Merge commit 'bc4620e5d61a4dd9a1f654fadd281a172aab04be'

* commit 'bc4620e5d61a4dd9a1f654fadd281a172aab04be':
  Remove libmpeg2 #define remnants
  De-doxygenize some top-level files

Conflicts:
	ffmpeg.c
	ffmpeg.h
	ffmpeg_filter.c
	ffplay.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
diff --git a/.gitignore b/.gitignore
index 19dbe88..b76493d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,12 +12,13 @@
 *.ver
 *-example
 *-test
+*_g
 /.config
 /.version
-/avconv
-/avplay
-/avprobe
-/avserver
+/ffmpeg
+/ffplay
+/ffprobe
+/ffserver
 /config.*
 /version.h
 /doc/*.1
@@ -25,6 +26,14 @@
 /doc/*.pod
 /doc/avoptions_codec.texi
 /doc/avoptions_format.texi
+/doc/examples/decoding_encoding
+/doc/examples/demuxing
+/doc/examples/filtering_audio
+/doc/examples/filtering_video
+/doc/examples/metadata
+/doc/examples/muxing
+/doc/examples/scaling_video
+/doc/fate.txt
 /doc/print_options
 /doxy/
 /libavcodec/*_tablegen
@@ -39,7 +48,10 @@
 /tests/videogen
 /tests/vsynth1/
 /tools/aviocat
+/tools/ffbisect
+/tools/bisect.need
 /tools/cws2fws
+/tools/ffeval
 /tools/graph2dot
 /tools/ismindex
 /tools/pktdumper
diff --git a/CREDITS b/CREDITS
index 4a53778..1d0666b 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1,5 +1,5 @@
 This file contains the names of some of the people who have contributed to
-Libav/FFmpeg. The names are sorted alphabetically by last name.  As this file is
+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.
 
diff --git a/Changelog b/Changelog
index b4b5294..2fd2239 100644
--- a/Changelog
+++ b/Changelog
@@ -1,33 +1,27 @@
 Entries are sorted chronologically from oldest to youngest within each release,
 releases are sorted from youngest to oldest.
 
-version <next>:
+version next:
+
+- stream disposition information printing in ffprobe
+- filter for loudness analysis following EBU R128
+- Opus encoder using libopus
+- ffprobe -select_streams option
+- Pinnacle TARGA CineWave YUV16 decoder
+- TAK demuxer, decoder and parser
+- DTS-HD demuxer
+- remove -same_quant, it hasn't worked for years
 
 
-version 9_beta1:
+version 1.0:
 
-- XWD encoder and decoder
-- Support for fragmentation in the mov/mp4 muxer
-- ISMV (Smooth Streaming) muxer
-- CDXL demuxer and decoder
-- Apple ProRes encoder
-- Sun Rasterfile Encoder
-- remove libpostproc
-- ID3v2 attached pictures reading and writing
-- WMA Lossless decoder
-- XBM encoder
-- RealAudio Lossless decoder
-- ZeroCodec decoder
-- drop support for avconv without libavfilter
-- add libavresample audio conversion library
-- audio filters support in libavfilter and avconv
-- add fps filter
-- audio split filter
-- audio mix filter
-- avprobe output is now standard INI or JSON. The old format can still
-  be used with -of old.
+- INI and flat output in ffprobe
+- Scene detection in libavfilter
 - Indeo Audio decoder
 - channelsplit audio filter
+- setnsamples audio filter
+- atempo filter
+- ffprobe -show_data option
 - RTMPT protocol support
 - iLBC encoding/decoding via libilbc
 - Microsoft Screen 1 decoder
@@ -40,43 +34,141 @@
 - Microsoft Expression Encoder Screen decoder
 - RTMPS protocol support
 - RTMPTS protocol support
-- JPEG 2000 encoding support through OpenJPEG
-- G.723.1 demuxer and decoder
 - RTMPE protocol support
 - RTMPTE protocol support
+- showwaves and showspectrum filter
+- LucasArts SMUSH playback support
+- SAMI, RealText and SubViewer demuxers and decoders
+- Heart Of Darkness PAF playback support
+- iec61883 device
+- asettb filter
+- new option: -progress
+- 3GPP Timed Text encoder/decoder
+- GeoTIFF decoder support
+- ffmpeg -(no)stdin option
+- Opus decoder using libopus
+- caca output device using libcaca
+- alphaextract and alphamerge filters
+- concat filter
+- flite filter
 - Canopus Lossless Codec decoder
-- avconv -shortest option is now per-output file,
+- bitmap subtitles in filters (experimental and temporary)
+- MP2 encoding via TwoLAME
+- bmp parser
+- smptebars source
+- asetpts filter
+- hue filter
+- ICO muxer
+- SubRip encoder and decoder without embedded timing
+- edge detection filter
+- framestep filter
+- ffmpeg -shortest option is now per-output file
   -pass and -passlogfile are now per-output stream
+- volume measurement filter
 - Ut Video encoder
 - Microsoft Screen 2 decoder
+- smartblur filter ported from MPlayer
+- CPiA decoder
+- decimate filter ported from MPlayer
 - RTP depacketization of JPEG
 - Smooth Streaming live segmenter muxer
+- F4V muxer
+- sendcmd and asendcmd filters
+- WebVTT demuxer and decoder (simple tags supported)
 - RTP packetization of JPEG
-- Opus decoder and encoder using libopus
-- remove -same_quant, it hasn't worked for years
+- faststart option in the MOV/MP4 muxer
 
 
-version 0.8:
+version 0.11:
 
+- Fixes: CVE-2012-2772, CVE-2012-2774, CVE-2012-2775, CVE-2012-2776, CVE-2012-2777,
+         CVE-2012-2779, CVE-2012-2782, CVE-2012-2783, CVE-2012-2784, CVE-2012-2785,
+         CVE-2012-2786, CVE-2012-2787, CVE-2012-2788, CVE-2012-2789, CVE-2012-2790,
+         CVE-2012-2791, CVE-2012-2792, CVE-2012-2793, CVE-2012-2794, CVE-2012-2795,
+         CVE-2012-2796, CVE-2012-2797, CVE-2012-2798, CVE-2012-2799, CVE-2012-2800,
+         CVE-2012-2801, CVE-2012-2802, CVE-2012-2803, CVE-2012-2804,
+- v408 Quicktime and Microsoft AYUV Uncompressed 4:4:4:4 encoder and decoder
+- setfield filter
+- CDXL demuxer and decoder
+- Apple ProRes encoder
+- ffprobe -count_packets and -count_frames options
+- Sun Rasterfile Encoder
+- ID3v2 attached pictures reading and writing
+- WMA Lossless decoder
+- bluray protocol
+- blackdetect filter
+- libutvideo encoder wrapper (--enable-libutvideo)
+- swapuv filter
+- bbox filter
+- XBM encoder and decoder
+- RealAudio Lossless decoder
+- ZeroCodec decoder
+- tile video filter
+- Metal Gear Solid: The Twin Snakes demuxer
+- OpenEXR image decoder
+- removelogo filter
+- drop support for ffmpeg without libavfilter
+- drawtext video filter: fontconfig support
+- ffmpeg -benchmark_all option
+- super2xsai filter ported from libmpcodecs
+- add libavresample audio conversion library for compatibility
+- MicroDVD decoder
+- Avid Meridien (AVUI) encoder and decoder
+- accept + prefix to -pix_fmt option to disable automatic conversions.
+- complete audio filtering in libavfilter and ffmpeg
+- add fps filter
+- vorbis parser
+- png parser
+- audio mix filter
+
+
+version 0.10:
+
+- Fixes: CVE-2011-3929, CVE-2011-3934, CVE-2011-3935, CVE-2011-3936,
+         CVE-2011-3937, CVE-2011-3940, CVE-2011-3941, CVE-2011-3944,
+         CVE-2011-3945, CVE-2011-3946, CVE-2011-3947, CVE-2011-3949,
+         CVE-2011-3950, CVE-2011-3951, CVE-2011-3952
+- v410 Quicktime Uncompressed 4:4:4 10-bit encoder and decoder
+- SBaGen (SBG) binaural beats script demuxer
+- OpenMG Audio muxer
+- Timecode extraction in DV and MOV
+- thumbnail video filter
+- XML output in ffprobe
+- asplit audio filter
+- tinterlace video filter
+- astreamsync audio filter
+- amerge audio filter
+- ISMV (Smooth Streaming) muxer
 - GSM audio parser
 - SMJPEG muxer
-
-
-version 0.8_beta2:
-
+- XWD encoder and decoder
 - Automatic thread count based on detection number of (available) CPU cores
-- Deprecate libpostproc. If desired, the switch --enable-postproc will
-  enable it but it may be removed in a later Libav release.
+- y41p Brooktree Uncompressed 4:1:1 12-bit encoder and decoder
+- ffprobe -show_error option
+- Avid 1:1 10-bit RGB Packer codec
+- v308 Quicktime Uncompressed 4:4:4 encoder and decoder
+- yuv4 libquicktime packed 4:2:0 encoder and decoder
+- ffprobe -show_frames option
+- silencedetect audio filter
+- ffprobe -show_program_version, -show_library_versions, -show_versions options
 - rv34: frame-level multi-threading
 - optimized iMDCT transform on x86 using SSE for for mpegaudiodec
+- Improved PGS subtitle decoder
+- dumpgraph option to lavfi device
+- r210 and r10k encoders
+- ffwavesynth decoder
+- aviocat tool
+- ffeval tool
 
 
-version 0.8_beta1:
+version 0.9:
 
+- openal input device added
+- boxblur filter added
 - BWF muxer
 - Flash Screen Video 2 decoder
-- ffplay/ffprobe/ffserver renamed to avplay/avprobe/avserver
-- ffmpeg deprecated, added avconv, which is almost the same for now, except
+- lavfi input device added
+- added avconv, which is almost the same for now, except
 for a few incompatible changes in the options, which will hopefully make them
 easier to use. The changes are:
     * The options placement is now strictly enforced! While in theory the
@@ -146,23 +238,40 @@
     * -vframes/-aframes/-dframes options are now aliases to the new -frames option.
     * -vtag/-atag/-stag options are now aliases to the new -tag option.
 - XMV demuxer
+- LOAS demuxer
+- ashowinfo filter added
 - Windows Media Image decoder
+- amovie source added
 - LATM muxer/demuxer
-- showinfo filter
-- split filter
+- Speex encoder via libspeex
+- JSON output in ffprobe
+- WTV muxer
+- Optional C++ Support (needed for libstagefright)
+- H.264 Decoding on Android via Stagefright
+- Prores decoder
+- BIN/XBIN/ADF/IDF text file decoder
+- aconvert audio filter added
+- audio support to lavfi input device added
 - libcdio-paranoia input device for audio CD grabbing
-- select filter
 - Apple ProRes decoder
 - CELT in Ogg demuxing
+- G.723.1 demuxer and decoder
+- libmodplug support (--enable-libmodplug)
 - VC-1 interlaced decoding
-- lut, lutrgb, and lutyuv filters
-- boxblur filter
+- libutvideo wrapper (--enable-libutvideo)
+- aevalsrc audio source added
 - Ut Video decoder
 - Speex encoding via libspeex
 - 4:2:2 H.264 decoding support
 - 4:2:2 and 4:4:4 H.264 encoding with libx264
 - Pulseaudio input device
+- Prores encoder
+- Video Decoder Acceleration (VDA) HWAccel module.
 - replacement Indeo 3 decoder
+- new ffmpeg option: -map_channel
+- volume audio filter added
+- earwax audio filter added
+- libv4l2 support (--enable-libv4l2)
 - TLS/SSL and HTTPS protocol support
 - AVOptions API rewritten and documented
 - most of CODEC_FLAG2_*, some CODEC_FLAG_* and many codec-specific fields in
@@ -172,44 +281,27 @@
 - Discworld II BMV decoding support
 - VBLE Decoder
 - OS X Video Decoder Acceleration (VDA) support
+- compact and csv output in ffprobe
+- pan audio filter
+- IFF Amiga Continuous Bitmap (ACBM) decoder
+- ass filter
 - CRI ADX audio format muxer and demuxer
 - Playstation Portable PMP format demuxer
+- Microsoft Windows ICO demuxer
+- life source
 - PCM format support in OMA demuxer
 - CLJR encoder
+- new option: -report
 - Dxtory capture format decoder
-- v410 QuickTime uncompressed 4:4:4 10-bit encoder and decoder
-- OpenMG Audio muxer
+- cellauto source
 - Simple segmenting muxer
 - Indeo 4 decoder
 - SMJPEG demuxer
 
 
-version 0.7:
+version 0.8:
 
-- E-AC-3 audio encoder
-- ac3enc: add channel coupling support
-- floating-point sample format support for (E-)AC-3, DCA, AAC, Vorbis decoders
-- H.264/MPEG frame-level multithreading
-- av_metadata_* functions renamed to av_dict_* and moved to libavutil
-- 4:4:4 H.264 decoding support
-- 10-bit H.264 optimizations for x86
-- bump libswscale for recently reported ABI break
-
-
-version 0.7_beta2:
-
-- VP8 frame-level multithreading
-- NEON optimizations for VP8
-- removed a lot of deprecated API cruft
-- FFT and IMDCT optimizations for AVX (Sandy Bridge) processors
-- DPX image encoder
-- SMPTE 302M AES3 audio decoder
-- ffmpeg no longer quits after the 'q' key is pressed; use 'ctrl+c' instead
-- 9bit and 10bit per sample support in the H.264 decoder
-
-
-version 0.7_beta1:
-
+- many many things we forgot because we rather write code than changelogs
 - WebM support in Matroska de/muxer
 - low overhead Ogg muxing
 - MMS-TCP support
@@ -217,6 +309,7 @@
 - Demuxer for On2's IVF format
 - Pictor/PC Paint decoder
 - HE-AAC v2 decoder
+- HE-AAC v2 encoding with libaacplus
 - libfaad2 wrapper removed
 - DTS-ES extension (XCh) decoding support
 - native VP8 decoder
@@ -228,6 +321,7 @@
 - RTP depacketization of QDM2
 - ANSI/ASCII art playback system
 - Lego Mindstorms RSO de/muxer
+- libavcore added (and subsequently removed)
 - SubRip subtitle file muxer and demuxer
 - Chinese AVS encoding via libxavs
 - ffprobe -show_packets option added
@@ -274,7 +368,7 @@
 - replace the ocv_smooth filter with a more generic ocv filter
 - Windows Televison (WTV) demuxer
 - FFmpeg metadata format muxer and demuxer
-- SubRip (srt) subtitle decoder
+- SubRip (srt) subtitle encoder and decoder
 - floating-point AC-3 encoder added
 - Lagarith decoder
 - ffmpeg -copytb option added
@@ -287,11 +381,46 @@
 - sndio support for playback and record
 - Linux framebuffer input device added
 - Chronomaster DFA decoder
-- Mobotix MxPEG decoder
+- DPX image encoder
+- MicroDVD subtitle file muxer and demuxer
+- Playstation Portable PMP format demuxer
+- fieldorder video filter added
 - AAC encoding via libvo-aacenc
 - AMR-WB encoding via libvo-amrwbenc
 - xWMA demuxer
-- fieldorder video filter added
+- Mobotix MxPEG decoder
+- VP8 frame-multithreading
+- NEON optimizations for VP8
+- Lots of deprecated API cruft removed
+- fft and imdct optimizations for AVX (Sandy Bridge) processors
+- showinfo filter added
+- SMPTE 302M AES3 audio decoder
+- Apple Core Audio Format muxer
+- 9bit and 10bit per sample support in the H.264 decoder
+- 9bit and 10bit FFV1 encoding / decoding
+- split filter added
+- select filter added
+- sdl output device added
+- libmpcodecs video filter support (3 times as many filters than before)
+- mpeg2 aspect ratio dection fixed
+- libxvid aspect pickiness fixed
+- Frame multithreaded decoding
+- E-AC-3 audio encoder
+- ac3enc: add channel coupling support
+- floating-point sample format support to the ac3, eac3, dca, aac, and vorbis decoders.
+- H264/MPEG frame-level multi-threading
+- All av_metadata_* functions renamed to av_dict_* and moved to libavutil
+- 4:4:4 H.264 decoding support
+- 10-bit H.264 optimizations for x86
+- lut, lutrgb, and lutyuv filters added
+- buffersink libavfilter sink added
+- Bump libswscale for recently reported ABI break
+- New J2K encoder (via OpenJPEG)
+
+
+version 0.7:
+
+- all the changes for 0.8, but keeping API/ABI compatibility with the 0.6 release
 
 
 version 0.6:
@@ -532,6 +661,7 @@
 - Gopher client support
 - MXF D-10 muxer
 - generic metadata API
+- flash ScreenVideo2 encoder
 
 
 version 0.4.9-pre1:
@@ -734,7 +864,7 @@
 - MPEG-4 vol header fixes (Jonathan Marsden <snmjbm at pacbell.net>)
 - ARM optimizations (Lionel Ulmer <lionel.ulmer at free.fr>).
 - Windows porting of file converter
-- added MJPEG raw format (input/ouput)
+- added MJPEG raw format (input/output)
 - added JPEG image format support (input/output)
 
 
diff --git a/Doxyfile b/Doxyfile
index 8e0dcf3..b91f351 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -25,7 +25,7 @@
 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded
 # by quotes) that should identify the project.
 
-PROJECT_NAME           = Libav
+PROJECT_NAME           = FFmpeg
 
 # The PROJECT_NUMBER tag can be used to enter a project or revision number.
 # This could be handy for archiving the generated documentation or
diff --git a/INSTALL b/INSTALL
index ac5dc5d..9549346 100644
--- a/INSTALL
+++ b/INSTALL
@@ -2,17 +2,14 @@
 1) Type './configure' to create the configuration. A list of configure
 options is printed by running 'configure --help'.
 
-'configure' can be launched from a directory different from the Libav
+'configure' can be launched from a directory different from the FFmpeg
 sources to build the objects out of tree. To do this, use an absolute
-path when launching 'configure', e.g. '/libavdir/libav/configure'.
+path when launching 'configure', e.g. '/ffmpegdir/ffmpeg/configure'.
 
-2) Then type 'make' to build Libav. GNU Make 3.81 or later is required.
+2) Then type 'make' to build FFmpeg. GNU Make 3.81 or later is required.
 
 3) Type 'make install' to install all binaries and libraries you built.
 
 NOTICE
 
  - Non system dependencies (e.g. libx264, libvpx) are disabled by default.
-
- - The default cflags include -g, if you want lean libraries you can either
-   pass --disable-debug or strip the debug symbols at a later time.
diff --git a/LICENSE b/LICENSE
index 1266627..b98b5d3 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,27 +1,39 @@
-Libav:
-======
+FFmpeg:
 
-Most files in Libav are under the GNU Lesser General Public License version 2.1
+Most files in FFmpeg are under the GNU Lesser General Public License version 2.1
 or later (LGPL v2.1+). Read the file COPYING.LGPLv2.1 for details. Some other
 files have MIT/X11/BSD-style licenses. In combination the LGPL v2.1+ applies to
-Libav.
+FFmpeg.
 
-Some optional parts of Libav are licensed under the GNU General Public License
+Some optional parts of FFmpeg are licensed under the GNU General Public License
 version 2 or later (GPL v2+). See the file COPYING.GPLv2 for details. None of
 these parts are used by default, you have to explicitly pass --enable-gpl to
-configure to activate them. In this case, Libav's license changes to GPL v2+.
+configure to activate them. In this case, FFmpeg's license changes to GPL v2+.
 
-Specifically, the GPL parts of Libav are
+Specifically, the GPL parts of FFmpeg are
 
+- libpostproc
+- libmpcodecs
+- optional x86 optimizations in the files
+  libavcodec/x86/idct_mmx.c
+- libutvideo encoding/decoding wrappers in
+  libavcodec/libutvideo*.cpp
 - the X11 grabber in libavdevice/x11grab.c
+- the swresample test app in
+  libswresample/swresample-test.c
 - the texi2pod.pl tool
 - the following filters in libavfilter:
     - vf_blackframe.c
     - vf_boxblur.c
+    - vf_colormatrix.c
     - vf_cropdetect.c
     - vf_delogo.c
     - vf_hqdn3d.c
+    - vf_mp.c
+    - vf_super2xsai.c
+    - vf_tinterlace.c
     - vf_yadif.c
+    - vsrc_mptestsrc.c
 
 There are a handful of files under other licensing terms, namely:
 
@@ -41,26 +53,29 @@
 external libraries
 ==================
 
-Libav can be combined with a number of external libraries, which sometimes
+FFmpeg can be combined with a number of external libraries, which sometimes
 affect the licensing of binaries resulting from the combination.
 
 compatible libraries
 --------------------
 
 The libcdio, libx264, libxavs and libxvid libraries are under GPL. When
-combining them with Libav, Libav needs to be licensed as GPL as well by
+combining them with FFmpeg, FFmpeg needs to be licensed as GPL as well by
 passing --enable-gpl to configure.
 
 The OpenCORE and VisualOn libraries are under the Apache License 2.0. That
 license is incompatible with the LGPL v2.1 and the GPL v2, but not with
-version 3 of those licenses. So to combine these libraries with Libav, the
+version 3 of those licenses. So to combine these libraries with FFmpeg, the
 license version needs to be upgraded by passing --enable-version3 to configure.
 
 incompatible libraries
 ----------------------
 
-The Fraunhofer AAC library, FAAC and OpenSSL are under licenses incompatible
-with all (L)GPL versions. Thus, unfortunately, since both licenses cannot be
-satisfied simultaneously, binaries resulting from the combination of Libav
-with these libraries are nonfree und unredistributable. If you wish to enable
-any of these libraries nonetheless, pass --enable-nonfree to configure.
+The Fraunhofer AAC library, FAAC and aacplus are under licenses which
+are incompatible with the GPLv2 and v3. We do not know for certain if their
+licenses are compatible with the LGPL.
+If you wish to enable these libraries, pass --enable-nonfree to configure.
+But note that if you enable any of these libraries the resulting binary will
+be under a complex license mix that is more restrictive than the LGPL and that
+may result in additional obligations. It is possible that these
+restrictions cause the resulting binary to be unredistributeable.
diff --git a/MAINTAINERS b/MAINTAINERS
new file mode 100644
index 0000000..bb5c4e4
--- /dev/null
+++ b/MAINTAINERS
@@ -0,0 +1,446 @@
+FFmpeg maintainers
+==================
+
+Below is a list of the people maintaining different parts of the
+FFmpeg code.
+
+Please try to keep entries where you are the maintainer up to date!
+
+Names in () mean that the maintainer currently has no time to maintain the code.
+A CC after the name means that the maintainer prefers to be CC-ed on patches
+and related discussions.
+
+
+Project Leader
+==============
+
+Michael Niedermayer
+  final design decisions
+
+
+Applications
+============
+
+ffmpeg:
+  ffmpeg.c                              Michael Niedermayer
+
+ffplay:
+  ffplay.c                              Marton Balint
+
+ffprobe:
+  ffprobe.c                             Stefano Sabatini
+
+ffserver:
+  ffserver.c, ffserver.h                Baptiste Coudurier
+
+Commandline utility code:
+  cmdutils.c, cmdutils.h                Michael Niedermayer
+
+QuickTime faststart:
+  tools/qt-faststart.c                  Baptiste Coudurier
+
+
+Miscellaneous Areas
+===================
+
+documentation                           Mike Melanson
+website                                 Robert Swain, Lou Logan
+build system (configure,Makefiles)      Diego Biurrun, Mans Rullgard
+project server                          Árpád Gereöffy, Michael Niedermayer, Reimar Döffinger
+mailinglists                            Michael Niedermayer, Baptiste Coudurier, Lou Logan
+presets                                 Robert Swain
+metadata subsystem                      Aurelien Jacobs
+release management                      Michael Niedermayer
+
+
+libavutil
+=========
+
+External Interfaces:
+  libavutil/avutil.h                    Michael Niedermayer
+Internal Interfaces:
+  libavutil/common.h                    Michael Niedermayer
+
+Other:
+  intfloat*                             Michael Niedermayer
+  rational.c, rational.h                Michael Niedermayer
+  mathematics.c, mathematics.h          Michael Niedermayer
+  integer.c, integer.h                  Michael Niedermayer
+  bswap.h
+
+
+libavcodec
+==========
+
+Generic Parts:
+  External Interfaces:
+    avcodec.h                           Michael Niedermayer
+  utility code:
+    utils.c                             Michael Niedermayer
+    mem.c                               Michael Niedermayer
+    opt.c, opt.h                        Michael Niedermayer
+  arithmetic expression evaluator:
+    eval.c                              Michael Niedermayer
+  audio and video frame extraction:
+    parser.c                            Michael Niedermayer
+  bitstream reading:
+    bitstream.c, bitstream.h            Michael Niedermayer
+  CABAC:
+    cabac.h, cabac.c                    Michael Niedermayer
+  codec names:
+    codec_names.sh                      Nicolas George
+  DSP utilities:
+    dsputils.c, dsputils.h              Michael Niedermayer
+  entropy coding:
+    rangecoder.c, rangecoder.h          Michael Niedermayer
+    lzw.*                               Michael Niedermayer
+  floating point AAN DCT:
+    faandct.c, faandct.h                Michael Niedermayer
+  Golomb coding:
+    golomb.c, golomb.h                  Michael Niedermayer
+  LPC:
+    lpc.c, lpc.h                        Justin Ruggles
+  motion estimation:
+    motion*                             Michael Niedermayer
+  rate control:
+    ratecontrol.c                       Michael Niedermayer
+    libxvid_rc.c                        Michael Niedermayer
+  simple IDCT:
+    simple_idct.c, simple_idct.h        Michael Niedermayer
+  postprocessing:
+    libpostproc/*                       Michael Niedermayer
+  table generation:
+    tableprint.c, tableprint.h          Reimar Doeffinger
+
+Codecs:
+  4xm.c                                 Michael Niedermayer
+  8bps.c                                Roberto Togni
+  8svx.c                                Jaikrishnan Menon
+  aasc.c                                Kostya Shishkov
+  ac3*                                  Justin Ruggles
+  alacenc.c                             Jaikrishnan Menon
+  alsdec.c                              Thilo Borgmann
+  apedec.c                              Kostya Shishkov
+  ass*                                  Aurelien Jacobs
+  asv*                                  Michael Niedermayer
+  atrac3*                               Benjamin Larsson
+  bgmc.c, bgmc.h                        Thilo Borgmann
+  bink.c                                Kostya Shishkov
+  binkaudio.c                           Peter Ross
+  bmp.c                                 Mans Rullgard, Kostya Shishkov
+  cavs*                                 Stefan Gehrer
+  celp_filters.*                        Vitor Sessak
+  cinepak.c                             Roberto Togni
+  cljr                                  Alex Beregszaszi
+  cllc.c                                Derek Buitenhuis
+  cook.c, cookdata.h                    Benjamin Larsson
+  cpia.c                                Stephan Hilb
+  crystalhd.c                           Philip Langdale
+  cscd.c                                Reimar Doeffinger
+  dca.c                                 Kostya Shishkov, Benjamin Larsson
+  dnxhd*                                Baptiste Coudurier
+  dpcm.c                                Mike Melanson
+  dxa.c                                 Kostya Shishkov
+  dv.c                                  Roman Shaposhnik
+  eacmv*, eaidct*, eat*                 Peter Ross
+  ffv1.c                                Michael Niedermayer
+  ffwavesynth.c                         Nicolas George
+  flac*                                 Justin Ruggles
+  flashsv*                              Benjamin Larsson
+  flicvideo.c                           Mike Melanson
+  g722.c                                Martin Storsjo
+  g726.c                                Roman Shaposhnik
+  gifdec.c                              Baptiste Coudurier
+  h264*                                 Loren Merritt, Michael Niedermayer
+  h261*                                 Michael Niedermayer
+  h263*                                 Michael Niedermayer
+  huffyuv.c                             Michael Niedermayer
+  idcinvideo.c                          Mike Melanson
+  imc*                                  Benjamin Larsson
+  indeo2*                               Kostya Shishkov
+  indeo5*                               Kostya Shishkov
+  interplayvideo.c                      Mike Melanson
+  ivi*                                  Kostya Shishkov
+  jacosub*                              Clément Bœsch
+  jpeg_ls.c                             Kostya Shishkov
+  jvdec.c                               Peter Ross
+  kmvc.c                                Kostya Shishkov
+  lcl*.c                                Roberto Togni, Reimar Doeffinger
+  libcelt_dec.c                         Nicolas George
+  libgsm.c                              Michel Bardiaux
+  libdirac*                             David Conrad
+  libopenjpeg.c                         Jaikrishnan Menon
+  libopenjpegenc.c                      Michael Bradshaw
+  libschroedinger*                      David Conrad
+  libspeexdec.c                         Justin Ruggles
+  libtheoraenc.c                        David Conrad
+  libutvideo*                           Derek Buitenhuis
+  libvorbis.c                           David Conrad
+  libxavs.c                             Stefan Gehrer
+  libx264.c                             Mans Rullgard, Jason Garrett-Glaser
+  loco.c                                Kostya Shishkov
+  lzo.h, lzo.c                          Reimar Doeffinger
+  mdec.c                                Michael Niedermayer
+  mimic.c                               Ramiro Polla
+  mjpeg.c                               Michael Niedermayer
+  mlp*                                  Ramiro Polla
+  mmvideo.c                             Peter Ross
+  mpc*                                  Kostya Shishkov
+  mpeg12.c, mpeg12data.h                Michael Niedermayer
+  mpegvideo.c, mpegvideo.h              Michael Niedermayer
+  msmpeg4.c, msmpeg4data.h              Michael Niedermayer
+  msrle.c                               Mike Melanson
+  msvideo1.c                            Mike Melanson
+  nellymoserdec.c                       Benjamin Larsson
+  nuv.c                                 Reimar Doeffinger
+  pcx.c                                 Ivo van Poorten
+  pgssubdec.c                           Reimar Doeffinger
+  ptx.c                                 Ivo van Poorten
+  qcelp*                                Reynaldo H. Verdejo Pinochet
+  qdm2.c, qdm2data.h                    Roberto Togni, Benjamin Larsson
+  qdrw.c                                Kostya Shishkov
+  qpeg.c                                Kostya Shishkov
+  qtrle.c                               Mike Melanson
+  ra144.c, ra144.h, ra288.c, ra288.h    Roberto Togni
+  resample2.c                           Michael Niedermayer
+  rl2.c                                 Sascha Sommer
+  rpza.c                                Roberto Togni
+  rtjpeg.c, rtjpeg.h                    Reimar Doeffinger
+  rv10.c                                Michael Niedermayer
+  rv3*                                  Kostya Shishkov
+  rv4*                                  Kostya Shishkov
+  s3tc*                                 Ivo van Poorten
+  smacker.c                             Kostya Shishkov
+  smc.c                                 Mike Melanson
+  snow.c                                Michael Niedermayer, Loren Merritt
+  sonic.c                               Alex Beregszaszi
+  srt*                                  Aurelien Jacobs
+  sunrast.c                             Ivo van Poorten
+  svq3.c                                Michael Niedermayer
+  targa.c                               Kostya Shishkov
+  tiff.c                                Kostya Shishkov
+  truemotion1*                          Mike Melanson
+  truemotion2*                          Kostya Shishkov
+  truespeech.c                          Kostya Shishkov
+  tscc.c                                Kostya Shishkov
+  tta.c                                 Alex Beregszaszi, Jaikrishnan Menon
+  txd.c                                 Ivo van Poorten
+  ulti*                                 Kostya Shishkov
+  v410*.c                               Derek Buitenhuis
+  vb.c                                  Kostya Shishkov
+  vble.c                                Derek Buitenhuis
+  vc1*                                  Kostya Shishkov
+  vcr1.c                                Michael Niedermayer
+  vda_h264_dec.c                        Xidorn Quan
+  vmnc.c                                Kostya Shishkov
+  vorbis_enc.c                          Oded Shimon
+  vorbis_dec.c                          Denes Balatoni, David Conrad
+  vp3*                                  Mike Melanson
+  vp5                                   Aurelien Jacobs
+  vp6                                   Aurelien Jacobs
+  vp8                                   David Conrad, Jason Garrett-Glaser, Ronald Bultje
+  vqavideo.c                            Mike Melanson
+  wavpack.c                             Kostya Shishkov
+  wmaprodec.c                           Sascha Sommer
+  wmavoice.c                            Ronald S. Bultje
+  wmv2.c                                Michael Niedermayer
+  wnv1.c                                Kostya Shishkov
+  xan.c                                 Mike Melanson
+  xl.c                                  Kostya Shishkov
+  xvmc.c                                Ivan Kalvachev
+  zerocodec.c                           Derek Buitenhuis
+  zmbv*                                 Kostya Shishkov
+
+Hardware acceleration:
+  crystalhd.c                           Philip Langdale
+  dxva2*                                Laurent Aimar
+  libstagefright.cpp                    Mohamed Naufal
+  vaapi*                                Gwenole Beauchesne
+  vda*                                  Sebastien Zwickert
+  vdpau*                                Carl Eugen Hoyos
+
+
+libavdevice
+===========
+  External Interface:
+    libavdevice/avdevice.h
+
+
+  iec61883.c                            Georg Lippitsch
+  libdc1394.c                           Roman Shaposhnik
+  v4l2.c                                Luca Abeni
+  vfwcap.c                              Ramiro Polla
+  dshow.c                               Roger Pack
+
+libavfilter
+===========
+
+Generic parts:
+  graphdump.c                           Nicolas George
+
+Filters:
+  af_amerge.c                           Nicolas George
+  af_astreamsync.c                      Nicolas George
+  af_atempo.c                           Pavel Koshevoy
+  af_pan.c                              Nicolas George
+  vf_yadif.c                            Michael Niedermayer
+
+Sources:
+  vsrc_mandelbrot.c                     Michael Niedermayer
+
+libavformat
+===========
+
+Generic parts:
+  External Interface:
+    libavformat/avformat.h              Michael Niedermayer
+  Utility Code:
+    libavformat/utils.c                 Michael Niedermayer
+
+
+Muxers/Demuxers:
+  4xm.c                                 Mike Melanson
+  adtsenc.c                             Robert Swain
+  aiff.c                                Baptiste Coudurier
+  ape.c                                 Kostya Shishkov
+  ass*                                  Aurelien Jacobs
+  avi*                                  Michael Niedermayer
+  bink.c                                Peter Ross
+  caf*                                  Peter Ross
+  crc.c                                 Michael Niedermayer
+  daud.c                                Reimar Doeffinger
+  dv.c                                  Roman Shaposhnik
+  dxa.c                                 Kostya Shishkov
+  electronicarts.c                      Peter Ross
+  ffm*                                  Baptiste Coudurier
+  flac*                                 Justin Ruggles
+  flic.c                                Mike Melanson
+  flvdec.c, flvenc.c                    Michael Niedermayer
+  gxf.c                                 Reimar Doeffinger
+  gxfenc.c                              Baptiste Coudurier
+  idcin.c                               Mike Melanson
+  idroqdec.c                            Mike Melanson
+  iff.c                                 Jaikrishnan Menon
+  ipmovie.c                             Mike Melanson
+  img2.c                                Michael Niedermayer
+  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
+  lxfdec.c                              Tomas Härdin
+  matroska.c                            Aurelien Jacobs
+  matroskadec.c                         Aurelien Jacobs
+  matroskaenc.c                         David Conrad
+  metadata*                             Aurelien Jacobs
+  microdvd*                             Aurelien Jacobs
+  mm.c                                  Peter Ross
+  mov.c                                 Michael Niedermayer, Baptiste Coudurier
+  movenc.c                              Michael Niedermayer, Baptiste Coudurier
+  mpc.c                                 Kostya Shishkov
+  mpeg.c                                Michael Niedermayer
+  mpegenc.c                             Michael Niedermayer
+  mpegts*                               Baptiste Coudurier
+  msnwc_tcp.c                           Ramiro Polla
+  mtv.c                                 Reynaldo H. Verdejo Pinochet
+  mxf*                                  Baptiste Coudurier
+  mxfdec.c                              Tomas Härdin
+  nsvdec.c                              Francois Revol
+  nut.c                                 Michael Niedermayer
+  nuv.c                                 Reimar Doeffinger
+  oggdec.c, oggdec.h                    David Conrad
+  oggenc.c                              Baptiste Coudurier
+  oggparse*.c                           David Conrad
+  oma.c                                 Maxim Poliakovski
+  psxstr.c                              Mike Melanson
+  pva.c                                 Ivo van Poorten
+  r3d.c                                 Baptiste Coudurier
+  raw.c                                 Michael Niedermayer
+  rdt.c                                 Ronald S. Bultje
+  rl2.c                                 Sascha Sommer
+  rmdec.c, rmenc.c                      Ronald S. Bultje, Kostya Shishkov
+  rtmp*                                 Kostya Shishkov
+  rtp.c, rtpenc.c                       Martin Storsjo
+  rtpdec_asf.*                          Ronald S. Bultje
+  rtpenc_mpv.*, rtpenc_aac.*            Martin Storsjo
+  rtsp.c                                Luca Barbato
+  sbgdec.c                              Nicolas George
+  sdp.c                                 Martin Storsjo
+  segafilm.c                            Mike Melanson
+  siff.c                                Kostya Shishkov
+  smacker.c                             Kostya Shishkov
+  srtdec.c                              Aurelien Jacobs
+  swf.c                                 Baptiste Coudurier
+  tta.c                                 Alex Beregszaszi
+  txd.c                                 Ivo van Poorten
+  voc.c                                 Aurelien Jacobs
+  wav.c                                 Michael Niedermayer
+  wc3movie.c                            Mike Melanson
+  westwood.c                            Mike Melanson
+  wtv.c                                 Peter Ross
+  wv.c                                  Kostya Shishkov
+
+Protocols:
+  bluray.c                              Petri Hintukainen
+  http.c                                Ronald S. Bultje
+  mms*.c                                Ronald S. Bultje
+  udp.c                                 Luca Abeni
+
+
+Operating systems / CPU architectures
+=====================================
+
+Alpha                                   Mans Rullgard, Falk Hueffner
+ARM                                     Mans Rullgard
+AVR32                                   Mans Rullgard
+MIPS                                    Mans Rullgard
+Mac OS X / PowerPC                      Romain Dolbeau, Guillaume Poirier
+Amiga / PowerPC                         Colin Ward
+Linux / PowerPC                         Luca Barbato
+Windows MinGW                           Alex Beregszaszi, Ramiro Polla
+Windows Cygwin                          Victor Paesa
+ADI/Blackfin DSP                        Marc Hoffman
+Sparc                                   Roman Shaposhnik
+x86                                     Michael Niedermayer
+
+
+Releases
+========
+
+1.0                                     Michael Niedermayer
+0.11                                    Michael Niedermayer
+0.10                                    Michael Niedermayer
+
+
+
+GnuPG Fingerprints of maintainers and contributors
+==================================================
+
+Anssi Hannula                 1A92 FF42 2DD9 8D2E 8AF7 65A9 4278 C520 513D F3CB
+Anton Khirnov                 6D0C 6625 56F8 65D1 E5F5 814B B50A 1241 C067 07AB
+Attila Kinali                 11F0 F9A6 A1D2 11F6 C745 D10C 6520 BCDD F2DF E765
+Baptiste Coudurier            8D77 134D 20CC 9220 201F C5DB 0AC9 325C 5C1A BAAA
+Ben Littler                   3EE3 3723 E560 3214 A8CD 4DEB 2CDB FCE7 768C 8D2C
+Benoit Fouet                  B22A 4F4F 43EF 636B BB66 FCDC 0023 AE1E 2985 49C8
+Bœsch Clément                 52D0 3A82 D445 F194 DB8B 2B16 87EE 2CB8 F4B8 FCF9
+Daniel Verkamp                78A6 07ED 782C 653E C628 B8B9 F0EB 8DD8 2F0E 21C7
+Diego Biurrun                 8227 1E31 B6D9 4994 7427 E220 9CAE D6CC 4757 FCC5
+Gwenole Beauchesne            2E63 B3A6 3E44 37E2 017D 2704 53C7 6266 B153 99C4
+Jaikrishnan Menon             61A1 F09F 01C9 2D45 78E1 C862 25DC 8831 AF70 D368
+Justin Ruggles                3136 ECC0 C10D 6C04 5F43 CA29 FCBE CD2A 3787 1EBF
+Loren Merritt                 ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE
+Lou Logan                     7D68 DC73 CBEF EABB 671A B6CF 621C 2E28 82F8 DC3A
+Luca Barbato                  6677 4209 213C 8843 5B67 29E7 E84C 78C2 84E9 0E34
+Michael Niedermayer           9FF2 128B 147E F673 0BAD F133 611E C787 040B 0FAB
+Nicolas George                24CE 01CE 9ACC 5CEB 74D8 8D9D B063 D997 36E5 4C93
+Panagiotis Issaris            6571 13A3 33D9 3726 F728 AA98 F643 B12E ECF3 E029
+Peter Ross                    A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B
+Reimar Döffinger              C61D 16E5 9E2C D10C 8958 38A4 0899 A2B9 06D4 D9C7
+Reinhard Tartler              9300 5DC2 7E87 6C37 ED7B CA9A 9808 3544 9453 48A4
+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
+Stephan Hilb                  4F38 0B3A 5F39 B99B F505 E562 8D5C 5554 4E17 8863
+Tomas Härdin                  D133 29CA 4EEC 9DB4 7076 F697 B04B 7403 3313 41FD
diff --git a/Makefile b/Makefile
index 77d51eb..53db626 100644
--- a/Makefile
+++ b/Makefile
@@ -1,73 +1,32 @@
+MAIN_MAKEFILE=1
 include config.mak
 
 vpath %.c    $(SRC_PATH)
+vpath %.cpp  $(SRC_PATH)
 vpath %.h    $(SRC_PATH)
 vpath %.S    $(SRC_PATH)
 vpath %.asm  $(SRC_PATH)
 vpath %.v    $(SRC_PATH)
 vpath %.texi $(SRC_PATH)
+vpath %/fate_config.sh.template $(SRC_PATH)
 
-ifndef V
-Q      = @
-ECHO   = printf "$(1)\t%s\n" $(2)
-BRIEF  = CC HOSTCC HOSTLD AS YASM AR LD
-SILENT = DEPCC DEPHOSTCC DEPAS DEPYASM RANLIB RM
-MSG    = $@
-M      = @$(call ECHO,$(TAG),$@);
-$(foreach VAR,$(BRIEF), \
-    $(eval override $(VAR) = @$$(call ECHO,$(VAR),$$(MSG)); $($(VAR))))
-$(foreach VAR,$(SILENT),$(eval override $(VAR) = @$($(VAR))))
-$(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_PATH)/%=%)); $(INSTALL))
-endif
+PROGS-$(CONFIG_FFMPEG)   += ffmpeg
+PROGS-$(CONFIG_FFPLAY)   += ffplay
+PROGS-$(CONFIG_FFPROBE)  += ffprobe
+PROGS-$(CONFIG_FFSERVER) += ffserver
 
-ALLFFLIBS = avcodec avdevice avfilter avformat avresample avutil swscale
-
-IFLAGS     := -I. -I$(SRC_PATH)
-CPPFLAGS   := $(IFLAGS) $(CPPFLAGS)
-CFLAGS     += $(ECFLAGS)
-CCFLAGS     = $(CPPFLAGS) $(CFLAGS)
-ASFLAGS    := $(CPPFLAGS) $(ASFLAGS)
-YASMFLAGS  += $(IFLAGS:%=%/) -I$(SRC_PATH)/libavutil/x86/ -Pconfig.asm
-HOSTCCFLAGS = $(IFLAGS) $(HOSTCFLAGS)
-LDFLAGS    := $(ALLFFLIBS:%=$(LD_PATH)lib%) $(LDFLAGS)
-
-define COMPILE
-	$(call $(1)DEP,$(1))
-	$($(1)) $($(1)FLAGS) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $<
-endef
-
-COMPILE_C = $(call COMPILE,CC)
-COMPILE_S = $(call COMPILE,AS)
-
-%.o: %.c
-	$(COMPILE_C)
-
-%.o: %.S
-	$(COMPILE_S)
-
-%.h.c:
-	$(Q)echo '#include "$*.h"' >$@
-
-%.ver: %.v
-	$(Q)sed 's/$$MAJOR/$($(basename $(@F))_VERSION_MAJOR)/' $^ > $@
-
-%.c %.h: TAG = GEN
-
-PROGS-$(CONFIG_AVCONV)   += avconv
-PROGS-$(CONFIG_AVPLAY)   += avplay
-PROGS-$(CONFIG_AVPROBE)  += avprobe
-PROGS-$(CONFIG_AVSERVER) += avserver
-
-PROGS      := $(PROGS-yes:%=%$(EXESUF))
+PROGS      := $(PROGS-yes:%=%$(PROGSSUF)$(EXESUF))
+INSTPROGS   = $(PROGS-yes:%=%$(PROGSSUF)$(EXESUF))
 OBJS        = cmdutils.o
-OBJS-avconv = avconv_opt.o avconv_filter.o
+OBJS-ffmpeg = ffmpeg_opt.o ffmpeg_filter.o
 TESTTOOLS   = audiogen videogen rotozoom tiny_psnr base64
 HOSTPROGS  := $(TESTTOOLS:%=tests/%) doc/print_options
 TOOLS       = qt-faststart trasher
 TOOLS-$(CONFIG_ZLIB) += cws2fws
 
-BASENAMES   = avconv avplay avprobe avserver
-ALLPROGS    = $(BASENAMES:%=%$(EXESUF))
+BASENAMES   = ffmpeg ffplay ffprobe ffserver
+ALLPROGS    = $(BASENAMES:%=%$(PROGSSUF)$(EXESUF))
+ALLPROGS_G  = $(BASENAMES:%=%$(PROGSSUF)_g$(EXESUF))
 ALLMANPAGES = $(BASENAMES:%=%.1)
 
 FFLIBS-$(CONFIG_AVDEVICE) += avdevice
@@ -75,11 +34,14 @@
 FFLIBS-$(CONFIG_AVFORMAT) += avformat
 FFLIBS-$(CONFIG_AVRESAMPLE) += avresample
 FFLIBS-$(CONFIG_AVCODEC)  += avcodec
+FFLIBS-$(CONFIG_POSTPROC) += postproc
+FFLIBS-$(CONFIG_SWRESAMPLE)+= swresample
 FFLIBS-$(CONFIG_SWSCALE)  += swscale
 
 FFLIBS := avutil
 
-DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.avpreset)
+DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.ffpreset) $(SRC_PATH)/doc/ffprobe.xsd
+EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examples/Makefile
 
 SKIPHEADERS = cmdutils_common_opts.h
 
@@ -90,6 +52,10 @@
 
 all: $(PROGS)
 
+$(PROGS): %$(EXESUF): %_g$(EXESUF)
+	$(CP) $< $@
+	$(STRIP) $@
+
 $(TOOLS): %$(EXESUF): %.o
 	$(LD) $(LDFLAGS) $(LD_O) $< $(ELIBS)
 
@@ -106,6 +72,7 @@
                ARMV5TE-OBJS ARMV6-OBJS ARMVFP-OBJS NEON-OBJS             \
                MMI-OBJS ALTIVEC-OBJS VIS-OBJS                            \
                MMX-OBJS YASM-OBJS                                        \
+               MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSPR1-OBJS MIPS32R2-OBJS  \
                OBJS HOSTOBJS TESTOBJS
 
 define RESET
@@ -125,16 +92,16 @@
 
 define DOPROG
 OBJS-$(1) += $(1).o
-$(1)$(EXESUF): $(OBJS-$(1))
+$(1)$(PROGSSUF)_g$(EXESUF): $(OBJS-$(1))
 $$(OBJS-$(1)): CFLAGS  += $(CFLAGS-$(1))
-$(1)$(EXESUF): LDFLAGS += $(LDFLAGS-$(1))
-$(1)$(EXESUF): FF_EXTRALIBS += $(LIBS-$(1))
+$(1)$(PROGSSUF)_g$(EXESUF): LDFLAGS += $(LDFLAGS-$(1))
+$(1)$(PROGSSUF)_g$(EXESUF): FF_EXTRALIBS += $(LIBS-$(1))
 -include $$(OBJS-$(1):.o=.d)
 endef
 
 $(foreach P,$(PROGS-yes),$(eval $(call DOPROG,$(P))))
 
-$(PROGS): %$(EXESUF): %.o cmdutils.o $(FF_DEP_LIBS)
+%$(PROGSSUF)_g$(EXESUF): %.o cmdutils.o $(FF_DEP_LIBS)
 	$(LD) $(LDFLAGS) $(LD_O) $(OBJS-$*) cmdutils.o $(FF_EXTRALIBS)
 
 OBJDIRS += tools
@@ -167,11 +134,12 @@
 
 install-progs: install-progs-yes $(PROGS)
 	$(Q)mkdir -p "$(BINDIR)"
-	$(INSTALL) -c -m 755 $(PROGS) "$(BINDIR)"
+	$(INSTALL) -c -m 755 $(INSTPROGS) "$(BINDIR)"
 
-install-data: $(DATA_FILES)
-	$(Q)mkdir -p "$(DATADIR)"
+install-data: $(DATA_FILES) $(EXAMPLES_FILES)
+	$(Q)mkdir -p "$(DATADIR)/examples"
 	$(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)"
+	$(INSTALL) -m 644 $(EXAMPLES_FILES) "$(DATADIR)/examples"
 
 uninstall: uninstall-libs uninstall-headers uninstall-progs uninstall-data
 
@@ -182,19 +150,30 @@
 	$(RM) -r "$(DATADIR)"
 
 clean::
-	$(RM) $(ALLPROGS)
+	$(RM) $(ALLPROGS) $(ALLPROGS_G)
 	$(RM) $(CLEANSUFFIXES)
 	$(RM) $(TOOLS)
 	$(RM) $(CLEANSUFFIXES:%=tools/%)
+	$(RM) coverage.info
+	$(RM) -r coverage-html
 
 distclean::
 	$(RM) $(DISTCLEANSUFFIXES)
-	$(RM) config.* .version version.h libavutil/avconfig.h
+	$(RM) config.* .version version.h libavutil/avconfig.h libavcodec/codec_names.h
 
 config:
-	$(SRC_PATH)/configure $(value LIBAV_CONFIGURATION)
+	$(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION)
 
-check: all alltools checkheaders examples testprogs fate
+# Without the sed genthml thinks "libavutil" and "./libavutil" are two different things
+coverage.info: $(wildcard *.gcda *.gcno */*.gcda */*.gcno */*/*.gcda */*/*.gcno)
+	$(Q)lcov -c -d . -b . | sed -e 's#/./#/#g' > $@
+
+coverage-html: coverage.info
+	$(Q)mkdir -p $@
+	$(Q)genhtml -o $@ $<
+	$(Q)touch $@
+
+check: all alltools examples testprogs fate
 
 include $(SRC_PATH)/doc/Makefile
 include $(SRC_PATH)/tests/Makefile
@@ -210,5 +189,5 @@
 # so this saves some time on slow systems.
 .SUFFIXES:
 
-.PHONY: all all-yes alltools check *clean config examples install*
+.PHONY: all all-yes alltools check *clean config install*
 .PHONY: testprogs uninstall*
diff --git a/README b/README
index afef671..ae007bc 100644
--- a/README
+++ b/README
@@ -1,12 +1,18 @@
-Libav README
-------------
+FFmpeg README
+-------------
 
 1) Documentation
 ----------------
 
-* Read the documentation in the doc/ directory.
+* Read the documentation in the doc/ directory in git.
+  You can also view it online at http://ffmpeg.org/documentation.html
 
 2) Licensing
 ------------
 
 * See the LICENSE file.
+
+3) Build and Install
+--------------------
+
+* See the INSTALL file.
diff --git a/RELEASE b/RELEASE
index 437fe58..4402ec2 100644
--- a/RELEASE
+++ b/RELEASE
@@ -1 +1 @@
-9_beta1
+1.0.git
diff --git a/arch.mak b/arch.mak
index 33018f3..6ccdfa0 100644
--- a/arch.mak
+++ b/arch.mak
@@ -4,6 +4,10 @@
 OBJS-$(HAVE_NEON)    += $(NEON-OBJS)    $(NEON-OBJS-yes)
 
 OBJS-$(HAVE_MMI)     += $(MMI-OBJS)     $(MMI-OBJS-yes)
+OBJS-$(HAVE_MIPSFPU)   += $(MIPSFPU-OBJS)    $(MIPSFPU-OBJS-yes)
+OBJS-$(HAVE_MIPS32R2)  += $(MIPS32R2-OBJS)   $(MIPS32R2-OBJS-yes)
+OBJS-$(HAVE_MIPSDSPR1) += $(MIPSDSPR1-OBJS)  $(MIPSDSPR1-OBJS-yes)
+OBJS-$(HAVE_MIPSDSPR2) += $(MIPSDSPR2-OBJS)  $(MIPSDSPR2-OBJS-yes)
 
 OBJS-$(HAVE_ALTIVEC) += $(ALTIVEC-OBJS) $(ALTIVEC-OBJS-yes)
 
diff --git a/avconv.c b/avconv.c
deleted file mode 100644
index 4d9c7c0..0000000
--- a/avconv.c
+++ /dev/null
@@ -1,2462 +0,0 @@
-/*
- * avconv main
- * Copyright (c) 2000-2011 The libav developers.
- *
- * 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
- */
-
-#include "config.h"
-#include <ctype.h>
-#include <string.h>
-#include <math.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <signal.h>
-#include <limits.h>
-#include "libavformat/avformat.h"
-#include "libavdevice/avdevice.h"
-#include "libswscale/swscale.h"
-#include "libavresample/avresample.h"
-#include "libavutil/opt.h"
-#include "libavutil/audioconvert.h"
-#include "libavutil/parseutils.h"
-#include "libavutil/samplefmt.h"
-#include "libavutil/colorspace.h"
-#include "libavutil/fifo.h"
-#include "libavutil/intreadwrite.h"
-#include "libavutil/dict.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/pixdesc.h"
-#include "libavutil/avstring.h"
-#include "libavutil/libm.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/time.h"
-#include "libavformat/os_support.h"
-
-# include "libavfilter/avfilter.h"
-# include "libavfilter/avfiltergraph.h"
-# include "libavfilter/buffersrc.h"
-# include "libavfilter/buffersink.h"
-
-#if HAVE_SYS_RESOURCE_H
-#include <sys/types.h>
-#include <sys/resource.h>
-#elif HAVE_GETPROCESSTIMES
-#include <windows.h>
-#endif
-#if HAVE_GETPROCESSMEMORYINFO
-#include <windows.h>
-#include <psapi.h>
-#endif
-
-#if HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#if HAVE_PTHREADS
-#include <pthread.h>
-#endif
-
-#include <time.h>
-
-#include "avconv.h"
-#include "cmdutils.h"
-
-#include "libavutil/avassert.h"
-
-const char program_name[] = "avconv";
-const int program_birth_year = 2000;
-
-static FILE *vstats_file;
-
-static int64_t video_size = 0;
-static int64_t audio_size = 0;
-static int64_t extra_size = 0;
-static int nb_frames_dup = 0;
-static int nb_frames_drop = 0;
-
-
-
-#if HAVE_PTHREADS
-/* signal to input threads that they should exit; set by the main thread */
-static int transcoding_finished;
-#endif
-
-#define DEFAULT_PASS_LOGFILENAME_PREFIX "av2pass"
-
-InputStream **input_streams = NULL;
-int        nb_input_streams = 0;
-InputFile   **input_files   = NULL;
-int        nb_input_files   = 0;
-
-OutputStream **output_streams = NULL;
-int         nb_output_streams = 0;
-OutputFile   **output_files   = NULL;
-int         nb_output_files   = 0;
-
-FilterGraph **filtergraphs;
-int        nb_filtergraphs;
-
-static void term_exit(void)
-{
-    av_log(NULL, AV_LOG_QUIET, "");
-}
-
-static volatile int received_sigterm = 0;
-static volatile int received_nb_signals = 0;
-
-static void
-sigterm_handler(int sig)
-{
-    received_sigterm = sig;
-    received_nb_signals++;
-    term_exit();
-}
-
-static void term_init(void)
-{
-    signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).    */
-    signal(SIGTERM, sigterm_handler); /* Termination (ANSI).  */
-#ifdef SIGXCPU
-    signal(SIGXCPU, sigterm_handler);
-#endif
-}
-
-static int decode_interrupt_cb(void *ctx)
-{
-    return received_nb_signals > 1;
-}
-
-const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
-
-static void exit_program(void)
-{
-    int i, j;
-
-    for (i = 0; i < nb_filtergraphs; i++) {
-        avfilter_graph_free(&filtergraphs[i]->graph);
-        for (j = 0; j < filtergraphs[i]->nb_inputs; j++) {
-            av_freep(&filtergraphs[i]->inputs[j]->name);
-            av_freep(&filtergraphs[i]->inputs[j]);
-        }
-        av_freep(&filtergraphs[i]->inputs);
-        for (j = 0; j < filtergraphs[i]->nb_outputs; j++) {
-            av_freep(&filtergraphs[i]->outputs[j]->name);
-            av_freep(&filtergraphs[i]->outputs[j]);
-        }
-        av_freep(&filtergraphs[i]->outputs);
-        av_freep(&filtergraphs[i]);
-    }
-    av_freep(&filtergraphs);
-
-    /* close files */
-    for (i = 0; i < nb_output_files; i++) {
-        AVFormatContext *s = output_files[i]->ctx;
-        if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
-            avio_close(s->pb);
-        avformat_free_context(s);
-        av_dict_free(&output_files[i]->opts);
-        av_freep(&output_files[i]);
-    }
-    for (i = 0; i < nb_output_streams; i++) {
-        AVBitStreamFilterContext *bsfc = output_streams[i]->bitstream_filters;
-        while (bsfc) {
-            AVBitStreamFilterContext *next = bsfc->next;
-            av_bitstream_filter_close(bsfc);
-            bsfc = next;
-        }
-        output_streams[i]->bitstream_filters = NULL;
-        avcodec_free_frame(&output_streams[i]->filtered_frame);
-
-        av_freep(&output_streams[i]->forced_keyframes);
-        av_freep(&output_streams[i]->avfilter);
-        av_freep(&output_streams[i]->logfile_prefix);
-        av_freep(&output_streams[i]);
-    }
-    for (i = 0; i < nb_input_files; i++) {
-        avformat_close_input(&input_files[i]->ctx);
-        av_freep(&input_files[i]);
-    }
-    for (i = 0; i < nb_input_streams; i++) {
-        avcodec_free_frame(&input_streams[i]->decoded_frame);
-        av_dict_free(&input_streams[i]->opts);
-        free_buffer_pool(&input_streams[i]->buffer_pool);
-        av_freep(&input_streams[i]->filters);
-        av_freep(&input_streams[i]);
-    }
-
-    if (vstats_file)
-        fclose(vstats_file);
-    av_free(vstats_filename);
-
-    av_freep(&input_streams);
-    av_freep(&input_files);
-    av_freep(&output_streams);
-    av_freep(&output_files);
-
-    uninit_opts();
-
-    avfilter_uninit();
-    avformat_network_deinit();
-
-    if (received_sigterm) {
-        av_log(NULL, AV_LOG_INFO, "Received signal %d: terminating.\n",
-               (int) received_sigterm);
-        exit (255);
-    }
-}
-
-void assert_avoptions(AVDictionary *m)
-{
-    AVDictionaryEntry *t;
-    if ((t = av_dict_get(m, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
-        av_log(NULL, AV_LOG_FATAL, "Option %s not found.\n", t->key);
-        exit(1);
-    }
-}
-
-static void assert_codec_experimental(AVCodecContext *c, int encoder)
-{
-    const char *codec_string = encoder ? "encoder" : "decoder";
-    AVCodec *codec;
-    if (c->codec->capabilities & CODEC_CAP_EXPERIMENTAL &&
-        c->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
-        av_log(NULL, AV_LOG_FATAL, "%s '%s' is experimental and might produce bad "
-                "results.\nAdd '-strict experimental' if you want to use it.\n",
-                codec_string, c->codec->name);
-        codec = encoder ? avcodec_find_encoder(c->codec->id) : avcodec_find_decoder(c->codec->id);
-        if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL))
-            av_log(NULL, AV_LOG_FATAL, "Or use the non experimental %s '%s'.\n",
-                   codec_string, codec->name);
-        exit(1);
-    }
-}
-
-/*
- * Update the requested input sample format based on the output sample format.
- * This is currently only used to request float output from decoders which
- * support multiple sample formats, one of which is AV_SAMPLE_FMT_FLT.
- * Ideally this will be removed in the future when decoders do not do format
- * conversion and only output in their native format.
- */
-static void update_sample_fmt(AVCodecContext *dec, AVCodec *dec_codec,
-                              AVCodecContext *enc)
-{
-    /* if sample formats match or a decoder sample format has already been
-       requested, just return */
-    if (enc->sample_fmt == dec->sample_fmt ||
-        dec->request_sample_fmt > AV_SAMPLE_FMT_NONE)
-        return;
-
-    /* if decoder supports more than one output format */
-    if (dec_codec && dec_codec->sample_fmts &&
-        dec_codec->sample_fmts[0] != AV_SAMPLE_FMT_NONE &&
-        dec_codec->sample_fmts[1] != AV_SAMPLE_FMT_NONE) {
-        const enum AVSampleFormat *p;
-        int min_dec = INT_MAX, min_inc = INT_MAX;
-        enum AVSampleFormat dec_fmt = AV_SAMPLE_FMT_NONE;
-        enum AVSampleFormat inc_fmt = AV_SAMPLE_FMT_NONE;
-
-        /* find a matching sample format in the encoder */
-        for (p = dec_codec->sample_fmts; *p != AV_SAMPLE_FMT_NONE; p++) {
-            if (*p == enc->sample_fmt) {
-                dec->request_sample_fmt = *p;
-                return;
-            } else {
-                enum AVSampleFormat dfmt = av_get_packed_sample_fmt(*p);
-                enum AVSampleFormat efmt = av_get_packed_sample_fmt(enc->sample_fmt);
-                int fmt_diff = 32 * abs(dfmt - efmt);
-                if (av_sample_fmt_is_planar(*p) !=
-                    av_sample_fmt_is_planar(enc->sample_fmt))
-                    fmt_diff++;
-                if (dfmt == efmt) {
-                    min_inc = fmt_diff;
-                    inc_fmt = *p;
-                } else if (dfmt > efmt) {
-                    if (fmt_diff < min_inc) {
-                        min_inc = fmt_diff;
-                        inc_fmt = *p;
-                    }
-                } else {
-                    if (fmt_diff < min_dec) {
-                        min_dec = fmt_diff;
-                        dec_fmt = *p;
-                    }
-                }
-            }
-        }
-
-        /* if none match, provide the one that matches quality closest */
-        dec->request_sample_fmt = min_inc != INT_MAX ? inc_fmt : dec_fmt;
-    }
-}
-
-static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
-{
-    AVBitStreamFilterContext *bsfc = ost->bitstream_filters;
-    AVCodecContext          *avctx = ost->st->codec;
-    int ret;
-
-    /*
-     * Audio encoders may split the packets --  #frames in != #packets out.
-     * But there is no reordering, so we can limit the number of output packets
-     * by simply dropping them here.
-     * Counting encoded video frames needs to be done separately because of
-     * reordering, see do_video_out()
-     */
-    if (!(avctx->codec_type == AVMEDIA_TYPE_VIDEO && avctx->codec)) {
-        if (ost->frame_number >= ost->max_frames) {
-            av_free_packet(pkt);
-            return;
-        }
-        ost->frame_number++;
-    }
-
-    while (bsfc) {
-        AVPacket new_pkt = *pkt;
-        int a = av_bitstream_filter_filter(bsfc, avctx, NULL,
-                                           &new_pkt.data, &new_pkt.size,
-                                           pkt->data, pkt->size,
-                                           pkt->flags & AV_PKT_FLAG_KEY);
-        if (a > 0) {
-            av_free_packet(pkt);
-            new_pkt.destruct = av_destruct_packet;
-        } else if (a < 0) {
-            av_log(NULL, AV_LOG_ERROR, "%s failed for stream %d, codec %s",
-                   bsfc->filter->name, pkt->stream_index,
-                   avctx->codec ? avctx->codec->name : "copy");
-            print_error("", a);
-            if (exit_on_error)
-                exit(1);
-        }
-        *pkt = new_pkt;
-
-        bsfc = bsfc->next;
-    }
-
-    pkt->stream_index = ost->index;
-    ret = av_interleaved_write_frame(s, pkt);
-    if (ret < 0) {
-        print_error("av_interleaved_write_frame()", ret);
-        exit(1);
-    }
-}
-
-static int check_recording_time(OutputStream *ost)
-{
-    OutputFile *of = output_files[ost->file_index];
-
-    if (of->recording_time != INT64_MAX &&
-        av_compare_ts(ost->sync_opts - ost->first_pts, ost->st->codec->time_base, of->recording_time,
-                      AV_TIME_BASE_Q) >= 0) {
-        ost->finished = 1;
-        return 0;
-    }
-    return 1;
-}
-
-static void do_audio_out(AVFormatContext *s, OutputStream *ost,
-                         AVFrame *frame)
-{
-    AVCodecContext *enc = ost->st->codec;
-    AVPacket pkt;
-    int got_packet = 0;
-
-    av_init_packet(&pkt);
-    pkt.data = NULL;
-    pkt.size = 0;
-
-    if (!check_recording_time(ost))
-        return;
-
-    if (frame->pts == AV_NOPTS_VALUE || audio_sync_method < 0)
-        frame->pts = ost->sync_opts;
-    ost->sync_opts = frame->pts + frame->nb_samples;
-
-    if (avcodec_encode_audio2(enc, &pkt, frame, &got_packet) < 0) {
-        av_log(NULL, AV_LOG_FATAL, "Audio encoding failed\n");
-        exit(1);
-    }
-
-    if (got_packet) {
-        if (pkt.pts != AV_NOPTS_VALUE)
-            pkt.pts      = av_rescale_q(pkt.pts,      enc->time_base, ost->st->time_base);
-        if (pkt.dts != AV_NOPTS_VALUE)
-            pkt.dts      = av_rescale_q(pkt.dts,      enc->time_base, ost->st->time_base);
-        if (pkt.duration > 0)
-            pkt.duration = av_rescale_q(pkt.duration, enc->time_base, ost->st->time_base);
-
-        write_frame(s, &pkt, ost);
-
-        audio_size += pkt.size;
-    }
-}
-
-static void pre_process_video_frame(InputStream *ist, AVPicture *picture, void **bufp)
-{
-    AVCodecContext *dec;
-    AVPicture *picture2;
-    AVPicture picture_tmp;
-    uint8_t *buf = 0;
-
-    dec = ist->st->codec;
-
-    /* deinterlace : must be done before any resize */
-    if (do_deinterlace) {
-        int size;
-
-        /* create temporary picture */
-        size = avpicture_get_size(dec->pix_fmt, dec->width, dec->height);
-        buf  = av_malloc(size);
-        if (!buf)
-            return;
-
-        picture2 = &picture_tmp;
-        avpicture_fill(picture2, buf, dec->pix_fmt, dec->width, dec->height);
-
-        if (avpicture_deinterlace(picture2, picture,
-                                 dec->pix_fmt, dec->width, dec->height) < 0) {
-            /* if error, do not deinterlace */
-            av_log(NULL, AV_LOG_WARNING, "Deinterlacing failed\n");
-            av_free(buf);
-            buf = NULL;
-            picture2 = picture;
-        }
-    } else {
-        picture2 = picture;
-    }
-
-    if (picture != picture2)
-        *picture = *picture2;
-    *bufp = buf;
-}
-
-static void do_subtitle_out(AVFormatContext *s,
-                            OutputStream *ost,
-                            InputStream *ist,
-                            AVSubtitle *sub,
-                            int64_t pts)
-{
-    static uint8_t *subtitle_out = NULL;
-    int subtitle_out_max_size = 1024 * 1024;
-    int subtitle_out_size, nb, i;
-    AVCodecContext *enc;
-    AVPacket pkt;
-
-    if (pts == AV_NOPTS_VALUE) {
-        av_log(NULL, AV_LOG_ERROR, "Subtitle packets must have a pts\n");
-        if (exit_on_error)
-            exit(1);
-        return;
-    }
-
-    enc = ost->st->codec;
-
-    if (!subtitle_out) {
-        subtitle_out = av_malloc(subtitle_out_max_size);
-    }
-
-    /* Note: DVB subtitle need one packet to draw them and one other
-       packet to clear them */
-    /* XXX: signal it in the codec context ? */
-    if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE)
-        nb = 2;
-    else
-        nb = 1;
-
-    for (i = 0; i < nb; i++) {
-        ost->sync_opts = av_rescale_q(pts, ist->st->time_base, enc->time_base);
-        if (!check_recording_time(ost))
-            return;
-
-        sub->pts = av_rescale_q(pts, ist->st->time_base, AV_TIME_BASE_Q);
-        // start_display_time is required to be 0
-        sub->pts               += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q);
-        sub->end_display_time  -= sub->start_display_time;
-        sub->start_display_time = 0;
-        subtitle_out_size = avcodec_encode_subtitle(enc, subtitle_out,
-                                                    subtitle_out_max_size, sub);
-        if (subtitle_out_size < 0) {
-            av_log(NULL, AV_LOG_FATAL, "Subtitle encoding failed\n");
-            exit(1);
-        }
-
-        av_init_packet(&pkt);
-        pkt.data = subtitle_out;
-        pkt.size = subtitle_out_size;
-        pkt.pts  = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->st->time_base);
-        if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
-            /* XXX: the pts correction is handled here. Maybe handling
-               it in the codec would be better */
-            if (i == 0)
-                pkt.pts += 90 * sub->start_display_time;
-            else
-                pkt.pts += 90 * sub->end_display_time;
-        }
-        write_frame(s, &pkt, ost);
-    }
-}
-
-static void do_video_out(AVFormatContext *s,
-                         OutputStream *ost,
-                         AVFrame *in_picture,
-                         int *frame_size)
-{
-    int ret, format_video_sync;
-    AVPacket pkt;
-    AVCodecContext *enc = ost->st->codec;
-
-    *frame_size = 0;
-
-    format_video_sync = video_sync_method;
-    if (format_video_sync == VSYNC_AUTO)
-        format_video_sync = (s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH :
-                            (s->oformat->flags & AVFMT_VARIABLE_FPS) ? VSYNC_VFR : VSYNC_CFR;
-    if (format_video_sync != VSYNC_PASSTHROUGH &&
-        ost->frame_number &&
-        in_picture->pts != AV_NOPTS_VALUE &&
-        in_picture->pts < ost->sync_opts) {
-        nb_frames_drop++;
-        av_log(NULL, AV_LOG_VERBOSE, "*** drop!\n");
-        return;
-    }
-
-    if (in_picture->pts == AV_NOPTS_VALUE)
-        in_picture->pts = ost->sync_opts;
-    ost->sync_opts = in_picture->pts;
-
-
-    if (!ost->frame_number)
-        ost->first_pts = in_picture->pts;
-
-    av_init_packet(&pkt);
-    pkt.data = NULL;
-    pkt.size = 0;
-
-    if (!check_recording_time(ost) ||
-        ost->frame_number >= ost->max_frames)
-        return;
-
-    if (s->oformat->flags & AVFMT_RAWPICTURE &&
-        enc->codec->id == AV_CODEC_ID_RAWVIDEO) {
-        /* raw pictures are written as AVPicture structure to
-           avoid any copies. We support temporarily the older
-           method. */
-        enc->coded_frame->interlaced_frame = in_picture->interlaced_frame;
-        enc->coded_frame->top_field_first  = in_picture->top_field_first;
-        pkt.data   = (uint8_t *)in_picture;
-        pkt.size   =  sizeof(AVPicture);
-        pkt.pts    = av_rescale_q(in_picture->pts, enc->time_base, ost->st->time_base);
-        pkt.flags |= AV_PKT_FLAG_KEY;
-
-        write_frame(s, &pkt, ost);
-    } else {
-        int got_packet;
-        AVFrame big_picture;
-
-        big_picture = *in_picture;
-        /* better than nothing: use input picture interlaced
-           settings */
-        big_picture.interlaced_frame = in_picture->interlaced_frame;
-        if (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)) {
-            if (ost->top_field_first == -1)
-                big_picture.top_field_first = in_picture->top_field_first;
-            else
-                big_picture.top_field_first = !!ost->top_field_first;
-        }
-
-        big_picture.quality = ost->st->codec->global_quality;
-        if (!enc->me_threshold)
-            big_picture.pict_type = 0;
-        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++;
-        }
-        ret = avcodec_encode_video2(enc, &pkt, &big_picture, &got_packet);
-        if (ret < 0) {
-            av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");
-            exit(1);
-        }
-
-        if (got_packet) {
-            if (pkt.pts != AV_NOPTS_VALUE)
-                pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base);
-            if (pkt.dts != AV_NOPTS_VALUE)
-                pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base);
-
-            write_frame(s, &pkt, ost);
-            *frame_size = pkt.size;
-            video_size += pkt.size;
-
-            /* if two pass, output log */
-            if (ost->logfile && enc->stats_out) {
-                fprintf(ost->logfile, "%s", enc->stats_out);
-            }
-        }
-    }
-    ost->sync_opts++;
-    /*
-     * For video, number of frames in == number of packets out.
-     * But there may be reordering, so we can't throw away frames on encoder
-     * flush, we need to limit them here, before they go into encoder.
-     */
-    ost->frame_number++;
-}
-
-static double psnr(double d)
-{
-    return -10.0 * log(d) / log(10.0);
-}
-
-static void do_video_stats(AVFormatContext *os, OutputStream *ost,
-                           int frame_size)
-{
-    AVCodecContext *enc;
-    int frame_number;
-    double ti1, bitrate, avg_bitrate;
-
-    /* this is executed just the first time do_video_stats is called */
-    if (!vstats_file) {
-        vstats_file = fopen(vstats_filename, "w");
-        if (!vstats_file) {
-            perror("fopen");
-            exit(1);
-        }
-    }
-
-    enc = ost->st->codec;
-    if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
-        frame_number = ost->frame_number;
-        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);
-        if (ti1 < 0.01)
-            ti1 = 0.01;
-
-        bitrate     = (frame_size * 8) / av_q2d(enc->time_base) / 1000.0;
-        avg_bitrate = (double)(video_size * 8) / ti1 / 1000.0;
-        fprintf(vstats_file, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ",
-               (double)video_size / 1024, ti1, bitrate, avg_bitrate);
-        fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(enc->coded_frame->pict_type));
-    }
-}
-
-/*
- * Read one frame for lavfi output for ost and encode it.
- */
-static int poll_filter(OutputStream *ost)
-{
-    OutputFile    *of = output_files[ost->file_index];
-    AVFilterBufferRef *picref;
-    AVFrame *filtered_frame = NULL;
-    int frame_size, ret;
-
-    if (!ost->filtered_frame && !(ost->filtered_frame = avcodec_alloc_frame())) {
-        return AVERROR(ENOMEM);
-    } else
-        avcodec_get_frame_defaults(ost->filtered_frame);
-    filtered_frame = ost->filtered_frame;
-
-    if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
-        !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE))
-        ret = av_buffersink_read_samples(ost->filter->filter, &picref,
-                                         ost->st->codec->frame_size);
-    else
-        ret = av_buffersink_read(ost->filter->filter, &picref);
-
-    if (ret < 0)
-        return ret;
-
-    avfilter_copy_buf_props(filtered_frame, picref);
-    if (picref->pts != AV_NOPTS_VALUE) {
-        filtered_frame->pts = av_rescale_q(picref->pts,
-                                           ost->filter->filter->inputs[0]->time_base,
-                                           ost->st->codec->time_base) -
-                              av_rescale_q(of->start_time,
-                                           AV_TIME_BASE_Q,
-                                           ost->st->codec->time_base);
-
-        if (of->start_time && filtered_frame->pts < 0) {
-            avfilter_unref_buffer(picref);
-            return 0;
-        }
-    }
-
-    switch (ost->filter->filter->inputs[0]->type) {
-    case AVMEDIA_TYPE_VIDEO:
-        if (!ost->frame_aspect_ratio)
-            ost->st->codec->sample_aspect_ratio = picref->video->pixel_aspect;
-
-        do_video_out(of->ctx, ost, filtered_frame, &frame_size);
-        if (vstats_filename && frame_size)
-            do_video_stats(of->ctx, ost, frame_size);
-        break;
-    case AVMEDIA_TYPE_AUDIO:
-        do_audio_out(of->ctx, ost, filtered_frame);
-        break;
-    default:
-        // TODO support subtitle filters
-        av_assert0(0);
-    }
-
-    avfilter_unref_buffer(picref);
-
-    return 0;
-}
-
-/*
- * Read as many frames from possible from lavfi and encode them.
- *
- * Always read from the active stream with the lowest timestamp. If no frames
- * are available for it then return EAGAIN and wait for more input. This way we
- * can use lavfi sources that generate unlimited amount of frames without memory
- * usage exploding.
- */
-static int poll_filters(void)
-{
-    int i, j, ret = 0;
-
-    while (ret >= 0 && !received_sigterm) {
-        OutputStream *ost = NULL;
-        int64_t min_pts = INT64_MAX;
-
-        /* choose output stream with the lowest timestamp */
-        for (i = 0; i < nb_output_streams; i++) {
-            int64_t pts = output_streams[i]->sync_opts;
-
-            if (!output_streams[i]->filter || output_streams[i]->finished)
-                continue;
-
-            pts = av_rescale_q(pts, output_streams[i]->st->codec->time_base,
-                               AV_TIME_BASE_Q);
-            if (pts < min_pts) {
-                min_pts = pts;
-                ost = output_streams[i];
-            }
-        }
-
-        if (!ost)
-            break;
-
-        ret = poll_filter(ost);
-
-        if (ret == AVERROR_EOF) {
-            OutputFile *of = output_files[ost->file_index];
-
-            ost->finished = 1;
-
-            if (of->shortest) {
-                for (j = 0; j < of->ctx->nb_streams; j++)
-                    output_streams[of->ost_index + j]->finished = 1;
-            }
-
-            ret = 0;
-        } else if (ret == AVERROR(EAGAIN))
-            return 0;
-    }
-
-    return ret;
-}
-
-static void print_report(int is_last_report, int64_t timer_start)
-{
-    char buf[1024];
-    OutputStream *ost;
-    AVFormatContext *oc;
-    int64_t total_size;
-    AVCodecContext *enc;
-    int frame_number, vid, i;
-    double bitrate, ti1, pts;
-    static int64_t last_time = -1;
-    static int qp_histogram[52];
-
-    if (!print_stats && !is_last_report)
-        return;
-
-    if (!is_last_report) {
-        int64_t cur_time;
-        /* display the report every 0.5 seconds */
-        cur_time = av_gettime();
-        if (last_time == -1) {
-            last_time = cur_time;
-            return;
-        }
-        if ((cur_time - last_time) < 500000)
-            return;
-        last_time = cur_time;
-    }
-
-
-    oc = output_files[0]->ctx;
-
-    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);
-
-    buf[0] = '\0';
-    ti1 = 1e10;
-    vid = 0;
-    for (i = 0; i < nb_output_streams; i++) {
-        float q = -1;
-        ost = output_streams[i];
-        enc = ost->st->codec;
-        if (!ost->stream_copy && enc->coded_frame)
-            q = enc->coded_frame->quality / (float)FF_QP2LAMBDA;
-        if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
-            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q);
-        }
-        if (!vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
-            float t = (av_gettime() - timer_start) / 1000000.0;
-
-            frame_number = ost->frame_number;
-            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3d q=%3.1f ",
-                     frame_number, (t > 1) ? (int)(frame_number / t + 0.5) : 0, q);
-            if (is_last_report)
-                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L");
-            if (qp_hist) {
-                int j;
-                int qp = lrintf(q);
-                if (qp >= 0 && qp < FF_ARRAY_ELEMS(qp_histogram))
-                    qp_histogram[qp]++;
-                for (j = 0; j < 32; j++)
-                    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%X", (int)lrintf(log2(qp_histogram[j] + 1)));
-            }
-            if (enc->flags&CODEC_FLAG_PSNR) {
-                int j;
-                double error, error_sum = 0;
-                double scale, scale_sum = 0;
-                char type[3] = { 'Y','U','V' };
-                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "PSNR=");
-                for (j = 0; j < 3; j++) {
-                    if (is_last_report) {
-                        error = enc->error[j];
-                        scale = enc->width * enc->height * 255.0 * 255.0 * frame_number;
-                    } else {
-                        error = enc->coded_frame->error[j];
-                        scale = enc->width * enc->height * 255.0 * 255.0;
-                    }
-                    if (j)
-                        scale /= 4;
-                    error_sum += error;
-                    scale_sum += scale;
-                    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c:%2.2f ", type[j], psnr(error / scale));
-                }
-                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "*:%2.2f ", psnr(error_sum / scale_sum));
-            }
-            vid = 1;
-        }
-        /* compute min output value */
-        pts = (double)ost->st->pts.val * av_q2d(ost->st->time_base);
-        if ((pts < ti1) && (pts > 0))
-            ti1 = pts;
-    }
-    if (ti1 < 0.01)
-        ti1 = 0.01;
-
-    bitrate = (double)(total_size * 8) / ti1 / 1000.0;
-
-    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
-            "size=%8.0fkB time=%0.2f bitrate=%6.1fkbits/s",
-            (double)total_size / 1024, ti1, bitrate);
-
-    if (nb_frames_dup || nb_frames_drop)
-        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d",
-                nb_frames_dup, nb_frames_drop);
-
-    av_log(NULL, AV_LOG_INFO, "%s    \r", buf);
-
-    fflush(stderr);
-
-    if (is_last_report) {
-        int64_t raw= audio_size + video_size + extra_size;
-        av_log(NULL, AV_LOG_INFO, "\n");
-        av_log(NULL, AV_LOG_INFO, "video:%1.0fkB audio:%1.0fkB global headers:%1.0fkB muxing overhead %f%%\n",
-               video_size / 1024.0,
-               audio_size / 1024.0,
-               extra_size / 1024.0,
-               100.0 * (total_size - raw) / raw
-        );
-    }
-}
-
-static void flush_encoders(void)
-{
-    int i, ret;
-
-    for (i = 0; i < nb_output_streams; i++) {
-        OutputStream   *ost = output_streams[i];
-        AVCodecContext *enc = ost->st->codec;
-        AVFormatContext *os = output_files[ost->file_index]->ctx;
-        int stop_encoding = 0;
-
-        if (!ost->encoding_needed)
-            continue;
-
-        if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <= 1)
-            continue;
-        if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE) && enc->codec->id == AV_CODEC_ID_RAWVIDEO)
-            continue;
-
-        for (;;) {
-            int (*encode)(AVCodecContext*, AVPacket*, const AVFrame*, int*) = NULL;
-            const char *desc;
-            int64_t *size;
-
-            switch (ost->st->codec->codec_type) {
-            case AVMEDIA_TYPE_AUDIO:
-                encode = avcodec_encode_audio2;
-                desc   = "Audio";
-                size   = &audio_size;
-                break;
-            case AVMEDIA_TYPE_VIDEO:
-                encode = avcodec_encode_video2;
-                desc   = "Video";
-                size   = &video_size;
-                break;
-            default:
-                stop_encoding = 1;
-            }
-
-            if (encode) {
-                AVPacket pkt;
-                int got_packet;
-                av_init_packet(&pkt);
-                pkt.data = NULL;
-                pkt.size = 0;
-
-                ret = encode(enc, &pkt, NULL, &got_packet);
-                if (ret < 0) {
-                    av_log(NULL, AV_LOG_FATAL, "%s encoding failed\n", desc);
-                    exit(1);
-                }
-                *size += ret;
-                if (ost->logfile && enc->stats_out) {
-                    fprintf(ost->logfile, "%s", enc->stats_out);
-                }
-                if (!got_packet) {
-                    stop_encoding = 1;
-                    break;
-                }
-                if (pkt.pts != AV_NOPTS_VALUE)
-                    pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base);
-                if (pkt.dts != AV_NOPTS_VALUE)
-                    pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base);
-                write_frame(os, &pkt, ost);
-            }
-
-            if (stop_encoding)
-                break;
-        }
-    }
-}
-
-/*
- * Check whether a packet from ist should be written into ost at this time
- */
-static int check_output_constraints(InputStream *ist, OutputStream *ost)
-{
-    OutputFile *of = output_files[ost->file_index];
-    int ist_index  = input_files[ist->file_index]->ist_index + ist->st->index;
-
-    if (ost->source_index != ist_index)
-        return 0;
-
-    if (of->start_time && ist->last_dts < of->start_time)
-        return 0;
-
-    return 1;
-}
-
-static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *pkt)
-{
-    OutputFile *of = output_files[ost->file_index];
-    int64_t ost_tb_start_time = av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base);
-    AVPacket opkt;
-
-    av_init_packet(&opkt);
-
-    if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) &&
-        !ost->copy_initial_nonkeyframes)
-        return;
-
-    if (of->recording_time != INT64_MAX &&
-        ist->last_dts >= of->recording_time + of->start_time) {
-        ost->finished = 1;
-        return;
-    }
-
-    /* force the input stream PTS */
-    if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
-        audio_size += pkt->size;
-    else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
-        video_size += pkt->size;
-        ost->sync_opts++;
-    }
-
-    if (pkt->pts != AV_NOPTS_VALUE)
-        opkt.pts = av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base) - ost_tb_start_time;
-    else
-        opkt.pts = AV_NOPTS_VALUE;
-
-    if (pkt->dts == AV_NOPTS_VALUE)
-        opkt.dts = av_rescale_q(ist->last_dts, AV_TIME_BASE_Q, ost->st->time_base);
-    else
-        opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base);
-    opkt.dts -= ost_tb_start_time;
-
-    opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base);
-    opkt.flags    = pkt->flags;
-
-    // FIXME remove the following 2 lines they shall be replaced by the bitstream filters
-    if (  ost->st->codec->codec_id != AV_CODEC_ID_H264
-       && ost->st->codec->codec_id != AV_CODEC_ID_MPEG1VIDEO
-       && ost->st->codec->codec_id != AV_CODEC_ID_MPEG2VIDEO
-       && ost->st->codec->codec_id != AV_CODEC_ID_VC1
-       ) {
-        if (av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY))
-            opkt.destruct = av_destruct_packet;
-    } else {
-        opkt.data = pkt->data;
-        opkt.size = pkt->size;
-    }
-
-    write_frame(of->ctx, &opkt, ost);
-    ost->st->codec->frame_number++;
-    av_free_packet(&opkt);
-}
-
-static void rate_emu_sleep(InputStream *ist)
-{
-    if (input_files[ist->file_index]->rate_emu) {
-        int64_t pts = av_rescale(ist->last_dts, 1000000, AV_TIME_BASE);
-        int64_t now = av_gettime() - ist->start;
-        if (pts > now)
-            av_usleep(pts - now);
-    }
-}
-
-int guess_input_channel_layout(InputStream *ist)
-{
-    AVCodecContext *dec = ist->st->codec;
-
-    if (!dec->channel_layout) {
-        char layout_name[256];
-
-        dec->channel_layout = av_get_default_channel_layout(dec->channels);
-        if (!dec->channel_layout)
-            return 0;
-        av_get_channel_layout_string(layout_name, sizeof(layout_name),
-                                     dec->channels, dec->channel_layout);
-        av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for  Input Stream "
-               "#%d.%d : %s\n", ist->file_index, ist->st->index, layout_name);
-    }
-    return 1;
-}
-
-static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
-{
-    AVFrame *decoded_frame;
-    AVCodecContext *avctx = ist->st->codec;
-    int bps = av_get_bytes_per_sample(ist->st->codec->sample_fmt);
-    int i, ret, resample_changed;
-
-    if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
-        return AVERROR(ENOMEM);
-    else
-        avcodec_get_frame_defaults(ist->decoded_frame);
-    decoded_frame = ist->decoded_frame;
-
-    ret = avcodec_decode_audio4(avctx, decoded_frame, got_output, pkt);
-    if (!*got_output || ret < 0) {
-        if (!pkt->size) {
-            for (i = 0; i < ist->nb_filters; i++)
-                av_buffersrc_buffer(ist->filters[i]->filter, NULL);
-        }
-        return ret;
-    }
-
-    /* if the decoder provides a pts, use it instead of the last packet pts.
-       the decoder could be delaying output by a packet or more. */
-    if (decoded_frame->pts != AV_NOPTS_VALUE)
-        ist->next_dts = decoded_frame->pts;
-    else if (pkt->pts != AV_NOPTS_VALUE) {
-        decoded_frame->pts = pkt->pts;
-        pkt->pts           = AV_NOPTS_VALUE;
-    }
-
-    // preprocess audio (volume)
-    if (audio_volume != 256) {
-        int decoded_data_size = decoded_frame->nb_samples * avctx->channels * bps;
-        void *samples = decoded_frame->data[0];
-        switch (avctx->sample_fmt) {
-        case AV_SAMPLE_FMT_U8:
-        {
-            uint8_t *volp = samples;
-            for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
-                int v = (((*volp - 128) * audio_volume + 128) >> 8) + 128;
-                *volp++ = av_clip_uint8(v);
-            }
-            break;
-        }
-        case AV_SAMPLE_FMT_S16:
-        {
-            int16_t *volp = samples;
-            for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
-                int v = ((*volp) * audio_volume + 128) >> 8;
-                *volp++ = av_clip_int16(v);
-            }
-            break;
-        }
-        case AV_SAMPLE_FMT_S32:
-        {
-            int32_t *volp = samples;
-            for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
-                int64_t v = (((int64_t)*volp * audio_volume + 128) >> 8);
-                *volp++ = av_clipl_int32(v);
-            }
-            break;
-        }
-        case AV_SAMPLE_FMT_FLT:
-        {
-            float *volp = samples;
-            float scale = audio_volume / 256.f;
-            for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
-                *volp++ *= scale;
-            }
-            break;
-        }
-        case AV_SAMPLE_FMT_DBL:
-        {
-            double *volp = samples;
-            double scale = audio_volume / 256.;
-            for (i = 0; i < (decoded_data_size / sizeof(*volp)); i++) {
-                *volp++ *= scale;
-            }
-            break;
-        }
-        default:
-            av_log(NULL, AV_LOG_FATAL,
-                   "Audio volume adjustment on sample format %s is not supported.\n",
-                   av_get_sample_fmt_name(ist->st->codec->sample_fmt));
-            exit(1);
-        }
-    }
-
-    rate_emu_sleep(ist);
-
-    resample_changed = ist->resample_sample_fmt     != decoded_frame->format         ||
-                       ist->resample_channels       != avctx->channels               ||
-                       ist->resample_channel_layout != decoded_frame->channel_layout ||
-                       ist->resample_sample_rate    != decoded_frame->sample_rate;
-    if (resample_changed) {
-        char layout1[64], layout2[64];
-
-        if (!guess_input_channel_layout(ist)) {
-            av_log(NULL, AV_LOG_FATAL, "Unable to find default channel "
-                   "layout for Input Stream #%d.%d\n", ist->file_index,
-                   ist->st->index);
-            exit(1);
-        }
-        decoded_frame->channel_layout = avctx->channel_layout;
-
-        av_get_channel_layout_string(layout1, sizeof(layout1), ist->resample_channels,
-                                     ist->resample_channel_layout);
-        av_get_channel_layout_string(layout2, sizeof(layout2), avctx->channels,
-                                     decoded_frame->channel_layout);
-
-        av_log(NULL, AV_LOG_INFO,
-               "Input stream #%d:%d frame changed from rate:%d fmt:%s ch:%d chl:%s to rate:%d fmt:%s ch:%d chl:%s\n",
-               ist->file_index, ist->st->index,
-               ist->resample_sample_rate,  av_get_sample_fmt_name(ist->resample_sample_fmt),
-               ist->resample_channels, layout1,
-               decoded_frame->sample_rate, av_get_sample_fmt_name(decoded_frame->format),
-               avctx->channels, layout2);
-
-        ist->resample_sample_fmt     = decoded_frame->format;
-        ist->resample_sample_rate    = decoded_frame->sample_rate;
-        ist->resample_channel_layout = decoded_frame->channel_layout;
-        ist->resample_channels       = avctx->channels;
-
-        for (i = 0; i < nb_filtergraphs; i++)
-            if (ist_in_filtergraph(filtergraphs[i], ist) &&
-                configure_filtergraph(filtergraphs[i]) < 0) {
-                av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n");
-                exit(1);
-            }
-    }
-
-    if (decoded_frame->pts != AV_NOPTS_VALUE)
-        decoded_frame->pts = av_rescale_q(decoded_frame->pts,
-                                          ist->st->time_base,
-                                          (AVRational){1, ist->st->codec->sample_rate});
-    for (i = 0; i < ist->nb_filters; i++)
-        av_buffersrc_write_frame(ist->filters[i]->filter, decoded_frame);
-
-    return ret;
-}
-
-static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
-{
-    AVFrame *decoded_frame;
-    void *buffer_to_free = NULL;
-    int i, ret = 0, resample_changed;
-
-    if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
-        return AVERROR(ENOMEM);
-    else
-        avcodec_get_frame_defaults(ist->decoded_frame);
-    decoded_frame = ist->decoded_frame;
-
-    ret = avcodec_decode_video2(ist->st->codec,
-                                decoded_frame, got_output, pkt);
-    if (!*got_output || ret < 0) {
-        if (!pkt->size) {
-            for (i = 0; i < ist->nb_filters; i++)
-                av_buffersrc_buffer(ist->filters[i]->filter, NULL);
-        }
-        return ret;
-    }
-
-    decoded_frame->pts = guess_correct_pts(&ist->pts_ctx, decoded_frame->pkt_pts,
-                                           decoded_frame->pkt_dts);
-    pkt->size = 0;
-    pre_process_video_frame(ist, (AVPicture *)decoded_frame, &buffer_to_free);
-
-    rate_emu_sleep(ist);
-
-    if (ist->st->sample_aspect_ratio.num)
-        decoded_frame->sample_aspect_ratio = ist->st->sample_aspect_ratio;
-
-    resample_changed = ist->resample_width   != decoded_frame->width  ||
-                       ist->resample_height  != decoded_frame->height ||
-                       ist->resample_pix_fmt != decoded_frame->format;
-    if (resample_changed) {
-        av_log(NULL, AV_LOG_INFO,
-               "Input stream #%d:%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n",
-               ist->file_index, ist->st->index,
-               ist->resample_width,  ist->resample_height,  av_get_pix_fmt_name(ist->resample_pix_fmt),
-               decoded_frame->width, decoded_frame->height, av_get_pix_fmt_name(decoded_frame->format));
-
-        ret = poll_filters();
-        if (ret < 0 && (ret != AVERROR_EOF && ret != AVERROR(EAGAIN)))
-            av_log(NULL, AV_LOG_ERROR, "Error while filtering.\n");
-
-        ist->resample_width   = decoded_frame->width;
-        ist->resample_height  = decoded_frame->height;
-        ist->resample_pix_fmt = decoded_frame->format;
-
-        for (i = 0; i < nb_filtergraphs; i++)
-            if (ist_in_filtergraph(filtergraphs[i], ist) &&
-                configure_filtergraph(filtergraphs[i]) < 0) {
-                av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n");
-                exit(1);
-            }
-    }
-
-    for (i = 0; i < ist->nb_filters; i++) {
-        if (ist->st->codec->codec->capabilities & CODEC_CAP_DR1) {
-            FrameBuffer      *buf = decoded_frame->opaque;
-            AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays(
-                                        decoded_frame->data, decoded_frame->linesize,
-                                        AV_PERM_READ | AV_PERM_PRESERVE,
-                                        ist->st->codec->width, ist->st->codec->height,
-                                        ist->st->codec->pix_fmt);
-
-            avfilter_copy_frame_props(fb, decoded_frame);
-            fb->buf->priv           = buf;
-            fb->buf->free           = filter_release_buffer;
-
-            buf->refcount++;
-            av_buffersrc_buffer(ist->filters[i]->filter, fb);
-        } else
-            av_buffersrc_write_frame(ist->filters[i]->filter, decoded_frame);
-    }
-
-    av_free(buffer_to_free);
-    return ret;
-}
-
-static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
-{
-    AVSubtitle subtitle;
-    int i, ret = avcodec_decode_subtitle2(ist->st->codec,
-                                          &subtitle, got_output, pkt);
-    if (ret < 0)
-        return ret;
-    if (!*got_output)
-        return ret;
-
-    rate_emu_sleep(ist);
-
-    for (i = 0; i < nb_output_streams; i++) {
-        OutputStream *ost = output_streams[i];
-
-        if (!check_output_constraints(ist, ost) || !ost->encoding_needed)
-            continue;
-
-        do_subtitle_out(output_files[ost->file_index]->ctx, ost, ist, &subtitle, pkt->pts);
-    }
-
-    avsubtitle_free(&subtitle);
-    return ret;
-}
-
-/* pkt = NULL means EOF (needed to flush decoder buffers) */
-static int output_packet(InputStream *ist, const AVPacket *pkt)
-{
-    int i;
-    int got_output;
-    AVPacket avpkt;
-
-    if (ist->next_dts == AV_NOPTS_VALUE)
-        ist->next_dts = ist->last_dts;
-
-    if (pkt == NULL) {
-        /* EOF handling */
-        av_init_packet(&avpkt);
-        avpkt.data = NULL;
-        avpkt.size = 0;
-        goto handle_eof;
-    } else {
-        avpkt = *pkt;
-    }
-
-    if (pkt->dts != AV_NOPTS_VALUE)
-        ist->next_dts = ist->last_dts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
-
-    // while we have more to decode or while the decoder did output something on EOF
-    while (ist->decoding_needed && (avpkt.size > 0 || (!pkt && got_output))) {
-        int ret = 0;
-    handle_eof:
-
-        ist->last_dts = ist->next_dts;
-
-        if (avpkt.size && avpkt.size != pkt->size) {
-            av_log(NULL, ist->showed_multi_packet_warning ? AV_LOG_VERBOSE : AV_LOG_WARNING,
-                   "Multiple frames in a packet from stream %d\n", pkt->stream_index);
-            ist->showed_multi_packet_warning = 1;
-        }
-
-        switch (ist->st->codec->codec_type) {
-        case AVMEDIA_TYPE_AUDIO:
-            ret = decode_audio    (ist, &avpkt, &got_output);
-            break;
-        case AVMEDIA_TYPE_VIDEO:
-            ret = decode_video    (ist, &avpkt, &got_output);
-            if (avpkt.duration)
-                ist->next_dts += av_rescale_q(avpkt.duration, ist->st->time_base, AV_TIME_BASE_Q);
-            else if (ist->st->avg_frame_rate.num)
-                ist->next_dts += av_rescale_q(1, av_inv_q(ist->st->avg_frame_rate),
-                                              AV_TIME_BASE_Q);
-            else if (ist->st->codec->time_base.num != 0) {
-                int ticks      = ist->st->parser ? ist->st->parser->repeat_pict + 1 :
-                                                   ist->st->codec->ticks_per_frame;
-                ist->next_dts += av_rescale_q(ticks, ist->st->codec->time_base, AV_TIME_BASE_Q);
-            }
-            break;
-        case AVMEDIA_TYPE_SUBTITLE:
-            ret = transcode_subtitles(ist, &avpkt, &got_output);
-            break;
-        default:
-            return -1;
-        }
-
-        if (ret < 0)
-            return ret;
-        // touch data and size only if not EOF
-        if (pkt) {
-            avpkt.data += ret;
-            avpkt.size -= ret;
-        }
-        if (!got_output) {
-            continue;
-        }
-    }
-
-    /* handle stream copy */
-    if (!ist->decoding_needed) {
-        rate_emu_sleep(ist);
-        ist->last_dts = ist->next_dts;
-        switch (ist->st->codec->codec_type) {
-        case AVMEDIA_TYPE_AUDIO:
-            ist->next_dts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) /
-                             ist->st->codec->sample_rate;
-            break;
-        case AVMEDIA_TYPE_VIDEO:
-            if (ist->st->codec->time_base.num != 0) {
-                int ticks = ist->st->parser ? ist->st->parser->repeat_pict + 1 : ist->st->codec->ticks_per_frame;
-                ist->next_dts += ((int64_t)AV_TIME_BASE *
-                                  ist->st->codec->time_base.num * ticks) /
-                                  ist->st->codec->time_base.den;
-            }
-            break;
-        }
-    }
-    for (i = 0; pkt && i < nb_output_streams; i++) {
-        OutputStream *ost = output_streams[i];
-
-        if (!check_output_constraints(ist, ost) || ost->encoding_needed)
-            continue;
-
-        do_streamcopy(ist, ost, pkt);
-    }
-
-    return 0;
-}
-
-static void print_sdp(void)
-{
-    char sdp[2048];
-    int i;
-    AVFormatContext **avc = av_malloc(sizeof(*avc) * nb_output_files);
-
-    if (!avc)
-        exit(1);
-    for (i = 0; i < nb_output_files; i++)
-        avc[i] = output_files[i]->ctx;
-
-    av_sdp_create(avc, nb_output_files, sdp, sizeof(sdp));
-    printf("SDP:\n%s\n", sdp);
-    fflush(stdout);
-    av_freep(&avc);
-}
-
-static int init_input_stream(int ist_index, char *error, int error_len)
-{
-    int i;
-    InputStream *ist = input_streams[ist_index];
-    if (ist->decoding_needed) {
-        AVCodec *codec = ist->dec;
-        if (!codec) {
-            snprintf(error, error_len, "Decoder (codec id %d) not found for input stream #%d:%d",
-                    ist->st->codec->codec_id, ist->file_index, ist->st->index);
-            return AVERROR(EINVAL);
-        }
-
-        /* update requested sample format for the decoder based on the
-           corresponding encoder sample format */
-        for (i = 0; i < nb_output_streams; i++) {
-            OutputStream *ost = output_streams[i];
-            if (ost->source_index == ist_index) {
-                update_sample_fmt(ist->st->codec, codec, ost->st->codec);
-                break;
-            }
-        }
-
-        if (codec->type == AVMEDIA_TYPE_VIDEO && codec->capabilities & CODEC_CAP_DR1) {
-            ist->st->codec->get_buffer     = codec_get_buffer;
-            ist->st->codec->release_buffer = codec_release_buffer;
-            ist->st->codec->opaque         = &ist->buffer_pool;
-        }
-
-        if (!av_dict_get(ist->opts, "threads", NULL, 0))
-            av_dict_set(&ist->opts, "threads", "auto", 0);
-        if (avcodec_open2(ist->st->codec, codec, &ist->opts) < 0) {
-            snprintf(error, error_len, "Error while opening decoder for input stream #%d:%d",
-                    ist->file_index, ist->st->index);
-            return AVERROR(EINVAL);
-        }
-        assert_codec_experimental(ist->st->codec, 0);
-        assert_avoptions(ist->opts);
-    }
-
-    ist->last_dts = ist->st->avg_frame_rate.num ? - ist->st->codec->has_b_frames * AV_TIME_BASE / av_q2d(ist->st->avg_frame_rate) : 0;
-    ist->next_dts = AV_NOPTS_VALUE;
-    init_pts_correction(&ist->pts_ctx);
-    ist->is_start = 1;
-
-    return 0;
-}
-
-static InputStream *get_input_stream(OutputStream *ost)
-{
-    if (ost->source_index >= 0)
-        return input_streams[ost->source_index];
-
-    if (ost->filter) {
-        FilterGraph *fg = ost->filter->graph;
-        int i;
-
-        for (i = 0; i < fg->nb_inputs; i++)
-            if (fg->inputs[i]->ist->st->codec->codec_type == ost->st->codec->codec_type)
-                return fg->inputs[i]->ist;
-    }
-
-    return NULL;
-}
-
-static void parse_forced_key_frames(char *kf, OutputStream *ost,
-                                    AVCodecContext *avctx)
-{
-    char *p;
-    int n = 1, i;
-    int64_t t;
-
-    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) {
-        av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");
-        exit(1);
-    }
-
-    p = kf;
-    for (i = 0; i < n; i++) {
-        char *next = strchr(p, ',');
-
-        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);
-
-        p = next;
-    }
-}
-
-static int transcode_init(void)
-{
-    int ret = 0, i, j, k;
-    AVFormatContext *oc;
-    AVCodecContext *codec;
-    OutputStream *ost;
-    InputStream *ist;
-    char error[1024];
-    int want_sdp = 1;
-
-    /* init framerate emulation */
-    for (i = 0; i < nb_input_files; i++) {
-        InputFile *ifile = input_files[i];
-        if (ifile->rate_emu)
-            for (j = 0; j < ifile->nb_streams; j++)
-                input_streams[j + ifile->ist_index]->start = av_gettime();
-    }
-
-    /* output stream init */
-    for (i = 0; i < nb_output_files; i++) {
-        oc = output_files[i]->ctx;
-        if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {
-            av_dump_format(oc, i, oc->filename, 1);
-            av_log(NULL, AV_LOG_ERROR, "Output file #%d does not contain any stream\n", i);
-            return AVERROR(EINVAL);
-        }
-    }
-
-    /* init complex filtergraphs */
-    for (i = 0; i < nb_filtergraphs; i++)
-        if ((ret = avfilter_graph_config(filtergraphs[i]->graph, NULL)) < 0)
-            return ret;
-
-    /* for each output stream, we compute the right encoding parameters */
-    for (i = 0; i < nb_output_streams; i++) {
-        AVCodecContext *icodec = NULL;
-        ost = output_streams[i];
-        oc  = output_files[ost->file_index]->ctx;
-        ist = get_input_stream(ost);
-
-        if (ost->attachment_filename)
-            continue;
-
-        codec  = ost->st->codec;
-
-        if (ist) {
-            icodec = ist->st->codec;
-
-            ost->st->disposition          = ist->st->disposition;
-            codec->bits_per_raw_sample    = icodec->bits_per_raw_sample;
-            codec->chroma_sample_location = icodec->chroma_sample_location;
-        }
-
-        if (ost->stream_copy) {
-            uint64_t extra_size;
-
-            av_assert0(ist && !ost->filter);
-
-            extra_size = (uint64_t)icodec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE;
-
-            if (extra_size > INT_MAX) {
-                return AVERROR(EINVAL);
-            }
-
-            /* if stream_copy is selected, no need to decode or encode */
-            codec->codec_id   = icodec->codec_id;
-            codec->codec_type = icodec->codec_type;
-
-            if (!codec->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)
-                    codec->codec_tag = icodec->codec_tag;
-            }
-
-            codec->bit_rate       = icodec->bit_rate;
-            codec->rc_max_rate    = icodec->rc_max_rate;
-            codec->rc_buffer_size = icodec->rc_buffer_size;
-            codec->field_order    = icodec->field_order;
-            codec->extradata      = av_mallocz(extra_size);
-            if (!codec->extradata) {
-                return AVERROR(ENOMEM);
-            }
-            memcpy(codec->extradata, icodec->extradata, icodec->extradata_size);
-            codec->extradata_size = icodec->extradata_size;
-            if (!copy_tb) {
-                codec->time_base      = icodec->time_base;
-                codec->time_base.num *= icodec->ticks_per_frame;
-                av_reduce(&codec->time_base.num, &codec->time_base.den,
-                          codec->time_base.num, codec->time_base.den, INT_MAX);
-            } else
-                codec->time_base = ist->st->time_base;
-
-            switch (codec->codec_type) {
-            case AVMEDIA_TYPE_AUDIO:
-                if (audio_volume != 256) {
-                    av_log(NULL, AV_LOG_FATAL, "-acodec copy and -vol are incompatible (frames are not decoded)\n");
-                    exit(1);
-                }
-                codec->channel_layout     = icodec->channel_layout;
-                codec->sample_rate        = icodec->sample_rate;
-                codec->channels           = icodec->channels;
-                codec->frame_size         = icodec->frame_size;
-                codec->audio_service_type = icodec->audio_service_type;
-                codec->block_align        = icodec->block_align;
-                break;
-            case AVMEDIA_TYPE_VIDEO:
-                codec->pix_fmt            = icodec->pix_fmt;
-                codec->width              = icodec->width;
-                codec->height             = icodec->height;
-                codec->has_b_frames       = icodec->has_b_frames;
-                if (!codec->sample_aspect_ratio.num) {
-                    codec->sample_aspect_ratio   =
-                    ost->st->sample_aspect_ratio =
-                        ist->st->sample_aspect_ratio.num ? ist->st->sample_aspect_ratio :
-                        ist->st->codec->sample_aspect_ratio.num ?
-                        ist->st->codec->sample_aspect_ratio : (AVRational){0, 1};
-                }
-                break;
-            case AVMEDIA_TYPE_SUBTITLE:
-                codec->width  = icodec->width;
-                codec->height = icodec->height;
-                break;
-            case AVMEDIA_TYPE_DATA:
-            case AVMEDIA_TYPE_ATTACHMENT:
-                break;
-            default:
-                abort();
-            }
-        } else {
-            if (!ost->enc) {
-                /* should only happen when a default codec is not present. */
-                snprintf(error, sizeof(error), "Automatic encoder selection "
-                         "failed for output stream #%d:%d. Default encoder for "
-                         "format %s is probably disabled. Please choose an "
-                         "encoder manually.\n", ost->file_index, ost->index,
-                         oc->oformat->name);
-                ret = AVERROR(EINVAL);
-                goto dump_format;
-            }
-
-            if (ist)
-                ist->decoding_needed = 1;
-            ost->encoding_needed = 1;
-
-            /*
-             * We want CFR output if and only if one of those is true:
-             * 1) user specified output framerate with -r
-             * 2) user specified -vsync cfr
-             * 3) output format is CFR and the user didn't force vsync to
-             *    something else than CFR
-             *
-             * in such a case, set ost->frame_rate
-             */
-            if (codec->codec_type == AVMEDIA_TYPE_VIDEO &&
-                !ost->frame_rate.num && ist &&
-                (video_sync_method ==  VSYNC_CFR ||
-                 (video_sync_method ==  VSYNC_AUTO &&
-                  !(oc->oformat->flags & (AVFMT_NOTIMESTAMPS | AVFMT_VARIABLE_FPS))))) {
-                ost->frame_rate = ist->framerate.num ? ist->framerate :
-                                  ist->st->avg_frame_rate.num ?
-                                  ist->st->avg_frame_rate :
-                                  (AVRational){25, 1};
-
-                if (ost->enc && ost->enc->supported_framerates && !ost->force_fps) {
-                    int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates);
-                    ost->frame_rate = ost->enc->supported_framerates[idx];
-                }
-            }
-
-            if (!ost->filter &&
-                (codec->codec_type == AVMEDIA_TYPE_VIDEO ||
-                 codec->codec_type == AVMEDIA_TYPE_AUDIO)) {
-                    FilterGraph *fg;
-                    fg = init_simple_filtergraph(ist, ost);
-                    if (configure_filtergraph(fg)) {
-                        av_log(NULL, AV_LOG_FATAL, "Error opening filters!\n");
-                        exit(1);
-                    }
-            }
-
-            switch (codec->codec_type) {
-            case AVMEDIA_TYPE_AUDIO:
-                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->time_base      = (AVRational){ 1, codec->sample_rate };
-                break;
-            case AVMEDIA_TYPE_VIDEO:
-                codec->time_base = ost->filter->filter->inputs[0]->time_base;
-
-                codec->width  = ost->filter->filter->inputs[0]->w;
-                codec->height = ost->filter->filter->inputs[0]->h;
-                codec->sample_aspect_ratio = ost->st->sample_aspect_ratio =
-                    ost->frame_aspect_ratio ? // overridden by the -aspect cli option
-                    av_d2q(ost->frame_aspect_ratio * codec->height/codec->width, 255) :
-                    ost->filter->filter->inputs[0]->sample_aspect_ratio;
-                codec->pix_fmt = ost->filter->filter->inputs[0]->format;
-
-                if (icodec &&
-                    (codec->width   != icodec->width  ||
-                     codec->height  != icodec->height ||
-                     codec->pix_fmt != icodec->pix_fmt)) {
-                    codec->bits_per_raw_sample = 0;
-                }
-
-                if (ost->forced_keyframes)
-                    parse_forced_key_frames(ost->forced_keyframes, ost,
-                                            ost->st->codec);
-                break;
-            case AVMEDIA_TYPE_SUBTITLE:
-                codec->time_base = (AVRational){1, 1000};
-                break;
-            default:
-                abort();
-                break;
-            }
-            /* two pass mode */
-            if ((codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) {
-                char logfilename[1024];
-                FILE *f;
-
-                snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
-                         ost->logfile_prefix ? ost->logfile_prefix :
-                                               DEFAULT_PASS_LOGFILENAME_PREFIX,
-                         i);
-                if (!strcmp(ost->enc->name, "libx264")) {
-                    av_dict_set(&ost->opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE);
-                } else {
-                    if (codec->flags & CODEC_FLAG_PASS1) {
-                        f = fopen(logfilename, "wb");
-                        if (!f) {
-                            av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n",
-                                   logfilename, strerror(errno));
-                            exit(1);
-                        }
-                        ost->logfile = f;
-                    } else {
-                        char  *logbuffer;
-                        size_t logbuffer_size;
-                        if (cmdutils_read_file(logfilename, &logbuffer, &logbuffer_size) < 0) {
-                            av_log(NULL, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
-                                   logfilename);
-                            exit(1);
-                        }
-                        codec->stats_in = logbuffer;
-                    }
-                }
-            }
-        }
-    }
-
-    /* open each encoder */
-    for (i = 0; i < nb_output_streams; i++) {
-        ost = output_streams[i];
-        if (ost->encoding_needed) {
-            AVCodec      *codec = ost->enc;
-            AVCodecContext *dec = NULL;
-
-            if ((ist = get_input_stream(ost)))
-                dec = ist->st->codec;
-            if (dec && dec->subtitle_header) {
-                ost->st->codec->subtitle_header = av_malloc(dec->subtitle_header_size);
-                if (!ost->st->codec->subtitle_header) {
-                    ret = AVERROR(ENOMEM);
-                    goto dump_format;
-                }
-                memcpy(ost->st->codec->subtitle_header, dec->subtitle_header, dec->subtitle_header_size);
-                ost->st->codec->subtitle_header_size = dec->subtitle_header_size;
-            }
-            if (!av_dict_get(ost->opts, "threads", NULL, 0))
-                av_dict_set(&ost->opts, "threads", "auto", 0);
-            if (avcodec_open2(ost->st->codec, codec, &ost->opts) < 0) {
-                snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d:%d - maybe incorrect parameters such as bit_rate, rate, width or height",
-                        ost->file_index, ost->index);
-                ret = AVERROR(EINVAL);
-                goto dump_format;
-            }
-            assert_codec_experimental(ost->st->codec, 1);
-            assert_avoptions(ost->opts);
-            if (ost->st->codec->bit_rate && ost->st->codec->bit_rate < 1000)
-                av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
-                                             "It takes bits/s as argument, not kbits/s\n");
-            extra_size += ost->st->codec->extradata_size;
-
-            if (ost->st->codec->me_threshold)
-                input_streams[ost->source_index]->st->codec->debug |= FF_DEBUG_MV;
-        }
-    }
-
-    /* init input streams */
-    for (i = 0; i < nb_input_streams; i++)
-        if ((ret = init_input_stream(i, error, sizeof(error))) < 0)
-            goto dump_format;
-
-    /* discard unused programs */
-    for (i = 0; i < nb_input_files; i++) {
-        InputFile *ifile = input_files[i];
-        for (j = 0; j < ifile->ctx->nb_programs; j++) {
-            AVProgram *p = ifile->ctx->programs[j];
-            int discard  = AVDISCARD_ALL;
-
-            for (k = 0; k < p->nb_stream_indexes; k++)
-                if (!input_streams[ifile->ist_index + p->stream_index[k]]->discard) {
-                    discard = AVDISCARD_DEFAULT;
-                    break;
-                }
-            p->discard = discard;
-        }
-    }
-
-    /* open files and write file headers */
-    for (i = 0; i < nb_output_files; i++) {
-        oc = output_files[i]->ctx;
-        oc->interrupt_callback = int_cb;
-        if ((ret = avformat_write_header(oc, &output_files[i]->opts)) < 0) {
-            char errbuf[128];
-            const char *errbuf_ptr = errbuf;
-            if (av_strerror(ret, errbuf, sizeof(errbuf)) < 0)
-                errbuf_ptr = strerror(AVUNERROR(ret));
-            snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?): %s", i, errbuf_ptr);
-            ret = AVERROR(EINVAL);
-            goto dump_format;
-        }
-        assert_avoptions(output_files[i]->opts);
-        if (strcmp(oc->oformat->name, "rtp")) {
-            want_sdp = 0;
-        }
-    }
-
- dump_format:
-    /* dump the file output parameters - cannot be done before in case
-       of stream copy */
-    for (i = 0; i < nb_output_files; i++) {
-        av_dump_format(output_files[i]->ctx, i, output_files[i]->ctx->filename, 1);
-    }
-
-    /* dump the stream mapping */
-    av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
-    for (i = 0; i < nb_input_streams; i++) {
-        ist = input_streams[i];
-
-        for (j = 0; j < ist->nb_filters; j++) {
-            if (ist->filters[j]->graph->graph_desc) {
-                av_log(NULL, AV_LOG_INFO, "  Stream #%d:%d (%s) -> %s",
-                       ist->file_index, ist->st->index, ist->dec ? ist->dec->name : "?",
-                       ist->filters[j]->name);
-                if (nb_filtergraphs > 1)
-                    av_log(NULL, AV_LOG_INFO, " (graph %d)", ist->filters[j]->graph->index);
-                av_log(NULL, AV_LOG_INFO, "\n");
-            }
-        }
-    }
-
-    for (i = 0; i < nb_output_streams; i++) {
-        ost = output_streams[i];
-
-        if (ost->attachment_filename) {
-            /* an attached file */
-            av_log(NULL, AV_LOG_INFO, "  File %s -> Stream #%d:%d\n",
-                   ost->attachment_filename, ost->file_index, ost->index);
-            continue;
-        }
-
-        if (ost->filter && ost->filter->graph->graph_desc) {
-            /* output from a complex graph */
-            av_log(NULL, AV_LOG_INFO, "  %s", ost->filter->name);
-            if (nb_filtergraphs > 1)
-                av_log(NULL, AV_LOG_INFO, " (graph %d)", ost->filter->graph->index);
-
-            av_log(NULL, AV_LOG_INFO, " -> Stream #%d:%d (%s)\n", ost->file_index,
-                   ost->index, ost->enc ? ost->enc->name : "?");
-            continue;
-        }
-
-        av_log(NULL, AV_LOG_INFO, "  Stream #%d:%d -> #%d:%d",
-               input_streams[ost->source_index]->file_index,
-               input_streams[ost->source_index]->st->index,
-               ost->file_index,
-               ost->index);
-        if (ost->sync_ist != input_streams[ost->source_index])
-            av_log(NULL, AV_LOG_INFO, " [sync #%d:%d]",
-                   ost->sync_ist->file_index,
-                   ost->sync_ist->st->index);
-        if (ost->stream_copy)
-            av_log(NULL, AV_LOG_INFO, " (copy)");
-        else
-            av_log(NULL, AV_LOG_INFO, " (%s -> %s)", input_streams[ost->source_index]->dec ?
-                   input_streams[ost->source_index]->dec->name : "?",
-                   ost->enc ? ost->enc->name : "?");
-        av_log(NULL, AV_LOG_INFO, "\n");
-    }
-
-    if (ret) {
-        av_log(NULL, AV_LOG_ERROR, "%s\n", error);
-        return ret;
-    }
-
-    if (want_sdp) {
-        print_sdp();
-    }
-
-    return 0;
-}
-
-/* Return 1 if there remain streams where more output is wanted, 0 otherwise. */
-static int need_output(void)
-{
-    int i;
-
-    for (i = 0; i < nb_output_streams; i++) {
-        OutputStream *ost    = output_streams[i];
-        OutputFile *of       = output_files[ost->file_index];
-        AVFormatContext *os  = output_files[ost->file_index]->ctx;
-
-        if (ost->finished ||
-            (os->pb && avio_tell(os->pb) >= of->limit_filesize))
-            continue;
-        if (ost->frame_number >= ost->max_frames) {
-            int j;
-            for (j = 0; j < of->ctx->nb_streams; j++)
-                output_streams[of->ost_index + j]->finished = 1;
-            continue;
-        }
-
-        return 1;
-    }
-
-    return 0;
-}
-
-static InputFile *select_input_file(void)
-{
-    InputFile *ifile = NULL;
-    int64_t ipts_min = INT64_MAX;
-    int i;
-
-    for (i = 0; i < nb_input_streams; i++) {
-        InputStream *ist = input_streams[i];
-        int64_t ipts     = ist->last_dts;
-
-        if (ist->discard || input_files[ist->file_index]->eagain)
-            continue;
-        if (!input_files[ist->file_index]->eof_reached) {
-            if (ipts < ipts_min) {
-                ipts_min = ipts;
-                ifile    = input_files[ist->file_index];
-            }
-        }
-    }
-
-    return ifile;
-}
-
-#if HAVE_PTHREADS
-static void *input_thread(void *arg)
-{
-    InputFile *f = arg;
-    int ret = 0;
-
-    while (!transcoding_finished && ret >= 0) {
-        AVPacket pkt;
-        ret = av_read_frame(f->ctx, &pkt);
-
-        if (ret == AVERROR(EAGAIN)) {
-            av_usleep(10000);
-            ret = 0;
-            continue;
-        } else if (ret < 0)
-            break;
-
-        pthread_mutex_lock(&f->fifo_lock);
-        while (!av_fifo_space(f->fifo))
-            pthread_cond_wait(&f->fifo_cond, &f->fifo_lock);
-
-        av_dup_packet(&pkt);
-        av_fifo_generic_write(f->fifo, &pkt, sizeof(pkt), NULL);
-
-        pthread_mutex_unlock(&f->fifo_lock);
-    }
-
-    f->finished = 1;
-    return NULL;
-}
-
-static void free_input_threads(void)
-{
-    int i;
-
-    if (nb_input_files == 1)
-        return;
-
-    transcoding_finished = 1;
-
-    for (i = 0; i < nb_input_files; i++) {
-        InputFile *f = input_files[i];
-        AVPacket pkt;
-
-        if (!f->fifo || f->joined)
-            continue;
-
-        pthread_mutex_lock(&f->fifo_lock);
-        while (av_fifo_size(f->fifo)) {
-            av_fifo_generic_read(f->fifo, &pkt, sizeof(pkt), NULL);
-            av_free_packet(&pkt);
-        }
-        pthread_cond_signal(&f->fifo_cond);
-        pthread_mutex_unlock(&f->fifo_lock);
-
-        pthread_join(f->thread, NULL);
-        f->joined = 1;
-
-        while (av_fifo_size(f->fifo)) {
-            av_fifo_generic_read(f->fifo, &pkt, sizeof(pkt), NULL);
-            av_free_packet(&pkt);
-        }
-        av_fifo_free(f->fifo);
-    }
-}
-
-static int init_input_threads(void)
-{
-    int i, ret;
-
-    if (nb_input_files == 1)
-        return 0;
-
-    for (i = 0; i < nb_input_files; i++) {
-        InputFile *f = input_files[i];
-
-        if (!(f->fifo = av_fifo_alloc(8*sizeof(AVPacket))))
-            return AVERROR(ENOMEM);
-
-        pthread_mutex_init(&f->fifo_lock, NULL);
-        pthread_cond_init (&f->fifo_cond, NULL);
-
-        if ((ret = pthread_create(&f->thread, NULL, input_thread, f)))
-            return AVERROR(ret);
-    }
-    return 0;
-}
-
-static int get_input_packet_mt(InputFile *f, AVPacket *pkt)
-{
-    int ret = 0;
-
-    pthread_mutex_lock(&f->fifo_lock);
-
-    if (av_fifo_size(f->fifo)) {
-        av_fifo_generic_read(f->fifo, pkt, sizeof(*pkt), NULL);
-        pthread_cond_signal(&f->fifo_cond);
-    } else {
-        if (f->finished)
-            ret = AVERROR_EOF;
-        else
-            ret = AVERROR(EAGAIN);
-    }
-
-    pthread_mutex_unlock(&f->fifo_lock);
-
-    return ret;
-}
-#endif
-
-static int get_input_packet(InputFile *f, AVPacket *pkt)
-{
-#if HAVE_PTHREADS
-    if (nb_input_files > 1)
-        return get_input_packet_mt(f, pkt);
-#endif
-    return av_read_frame(f->ctx, pkt);
-}
-
-static int got_eagain(void)
-{
-    int i;
-    for (i = 0; i < nb_input_files; i++)
-        if (input_files[i]->eagain)
-            return 1;
-    return 0;
-}
-
-static void reset_eagain(void)
-{
-    int i;
-    for (i = 0; i < nb_input_files; i++)
-        input_files[i]->eagain = 0;
-}
-
-/*
- * Read one packet from an input file and send it for
- * - decoding -> lavfi (audio/video)
- * - decoding -> encoding -> muxing (subtitles)
- * - muxing (streamcopy)
- *
- * Return
- * - 0 -- one packet was read and processed
- * - AVERROR(EAGAIN) -- no packets were available for selected file,
- *   this function should be called again
- * - AVERROR_EOF -- this function should not be called again
- */
-static int process_input(void)
-{
-    InputFile *ifile;
-    AVFormatContext *is;
-    InputStream *ist;
-    AVPacket pkt;
-    int ret, i, j;
-
-    /* select the stream that we must read now */
-    ifile = select_input_file();
-    /* if none, if is finished */
-    if (!ifile) {
-        if (got_eagain()) {
-            reset_eagain();
-            av_usleep(10000);
-            return AVERROR(EAGAIN);
-        }
-        av_log(NULL, AV_LOG_VERBOSE, "No more inputs to read from.\n");
-        return AVERROR_EOF;
-    }
-
-    is  = ifile->ctx;
-    ret = get_input_packet(ifile, &pkt);
-
-    if (ret == AVERROR(EAGAIN)) {
-        ifile->eagain = 1;
-        return ret;
-    }
-    if (ret < 0) {
-        if (ret != AVERROR_EOF) {
-            print_error(is->filename, ret);
-            if (exit_on_error)
-                exit(1);
-        }
-        ifile->eof_reached = 1;
-
-        for (i = 0; i < ifile->nb_streams; i++) {
-            ist = input_streams[ifile->ist_index + i];
-            if (ist->decoding_needed)
-                output_packet(ist, NULL);
-
-            /* mark all outputs that don't go through lavfi as finished */
-            for (j = 0; j < nb_output_streams; j++) {
-                OutputStream *ost = output_streams[j];
-
-                if (ost->source_index == ifile->ist_index + i &&
-                    (ost->stream_copy || ost->enc->type == AVMEDIA_TYPE_SUBTITLE))
-                    ost->finished= 1;
-            }
-        }
-
-        return AVERROR(EAGAIN);
-    }
-
-    reset_eagain();
-
-    if (do_pkt_dump) {
-        av_pkt_dump_log2(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump,
-                         is->streams[pkt.stream_index]);
-    }
-    /* the following test is needed in case new streams appear
-       dynamically in stream : we ignore them */
-    if (pkt.stream_index >= ifile->nb_streams)
-        goto discard_packet;
-
-    ist = input_streams[ifile->ist_index + pkt.stream_index];
-    if (ist->discard)
-        goto discard_packet;
-
-    if (pkt.dts != AV_NOPTS_VALUE)
-        pkt.dts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
-    if (pkt.pts != AV_NOPTS_VALUE)
-        pkt.pts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
-
-    if (pkt.pts != AV_NOPTS_VALUE)
-        pkt.pts *= ist->ts_scale;
-    if (pkt.dts != AV_NOPTS_VALUE)
-        pkt.dts *= ist->ts_scale;
-
-    if (pkt.dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE &&
-        (is->iformat->flags & AVFMT_TS_DISCONT)) {
-        int64_t pkt_dts = av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);
-        int64_t delta   = pkt_dts - ist->next_dts;
-
-        if ((FFABS(delta) > 1LL * dts_delta_threshold * AV_TIME_BASE || pkt_dts + 1 < ist->last_dts) && !copy_ts) {
-            ifile->ts_offset -= delta;
-            av_log(NULL, AV_LOG_DEBUG,
-                   "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",
-                   delta, ifile->ts_offset);
-            pkt.dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
-            if (pkt.pts != AV_NOPTS_VALUE)
-                pkt.pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
-        }
-    }
-
-    ret = output_packet(ist, &pkt);
-    if (ret < 0) {
-        av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n",
-               ist->file_index, ist->st->index);
-        if (exit_on_error)
-            exit(1);
-    }
-
-discard_packet:
-    av_free_packet(&pkt);
-
-    return 0;
-}
-
-/*
- * The following code is the main loop of the file converter
- */
-static int transcode(void)
-{
-    int ret, i, need_input = 1;
-    AVFormatContext *os;
-    OutputStream *ost;
-    InputStream *ist;
-    int64_t timer_start;
-
-    ret = transcode_init();
-    if (ret < 0)
-        goto fail;
-
-    av_log(NULL, AV_LOG_INFO, "Press ctrl-c to stop encoding\n");
-    term_init();
-
-    timer_start = av_gettime();
-
-#if HAVE_PTHREADS
-    if ((ret = init_input_threads()) < 0)
-        goto fail;
-#endif
-
-    while (!received_sigterm) {
-        /* check if there's any stream where output is still needed */
-        if (!need_output()) {
-            av_log(NULL, AV_LOG_VERBOSE, "No more output streams to write to, finishing.\n");
-            break;
-        }
-
-        /* read and process one input packet if needed */
-        if (need_input) {
-            ret = process_input();
-            if (ret == AVERROR_EOF)
-                need_input = 0;
-        }
-
-        ret = poll_filters();
-        if (ret < 0) {
-            if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
-                continue;
-
-            av_log(NULL, AV_LOG_ERROR, "Error while filtering.\n");
-            break;
-        }
-
-        /* dump report by using the output first video and audio streams */
-        print_report(0, timer_start);
-    }
-#if HAVE_PTHREADS
-    free_input_threads();
-#endif
-
-    /* at the end of stream, we must flush the decoder buffers */
-    for (i = 0; i < nb_input_streams; i++) {
-        ist = input_streams[i];
-        if (!input_files[ist->file_index]->eof_reached && ist->decoding_needed) {
-            output_packet(ist, NULL);
-        }
-    }
-    poll_filters();
-    flush_encoders();
-
-    term_exit();
-
-    /* write the trailer if needed and close file */
-    for (i = 0; i < nb_output_files; i++) {
-        os = output_files[i]->ctx;
-        av_write_trailer(os);
-    }
-
-    /* dump report by using the first video and audio streams */
-    print_report(1, timer_start);
-
-    /* close each encoder */
-    for (i = 0; i < nb_output_streams; i++) {
-        ost = output_streams[i];
-        if (ost->encoding_needed) {
-            av_freep(&ost->st->codec->stats_in);
-            avcodec_close(ost->st->codec);
-        }
-    }
-
-    /* close each decoder */
-    for (i = 0; i < nb_input_streams; i++) {
-        ist = input_streams[i];
-        if (ist->decoding_needed) {
-            avcodec_close(ist->st->codec);
-        }
-    }
-
-    /* finished ! */
-    ret = 0;
-
- fail:
-#if HAVE_PTHREADS
-    free_input_threads();
-#endif
-
-    if (output_streams) {
-        for (i = 0; i < nb_output_streams; i++) {
-            ost = output_streams[i];
-            if (ost) {
-                if (ost->stream_copy)
-                    av_freep(&ost->st->codec->extradata);
-                if (ost->logfile) {
-                    fclose(ost->logfile);
-                    ost->logfile = NULL;
-                }
-                av_freep(&ost->st->codec->subtitle_header);
-                av_free(ost->forced_kf_pts);
-                av_dict_free(&ost->opts);
-            }
-        }
-    }
-    return ret;
-}
-
-static int64_t getutime(void)
-{
-#if HAVE_GETRUSAGE
-    struct rusage rusage;
-
-    getrusage(RUSAGE_SELF, &rusage);
-    return (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
-#elif HAVE_GETPROCESSTIMES
-    HANDLE proc;
-    FILETIME c, e, k, u;
-    proc = GetCurrentProcess();
-    GetProcessTimes(proc, &c, &e, &k, &u);
-    return ((int64_t) u.dwHighDateTime << 32 | u.dwLowDateTime) / 10;
-#else
-    return av_gettime();
-#endif
-}
-
-static int64_t getmaxrss(void)
-{
-#if HAVE_GETRUSAGE && HAVE_STRUCT_RUSAGE_RU_MAXRSS
-    struct rusage rusage;
-    getrusage(RUSAGE_SELF, &rusage);
-    return (int64_t)rusage.ru_maxrss * 1024;
-#elif HAVE_GETPROCESSMEMORYINFO
-    HANDLE proc;
-    PROCESS_MEMORY_COUNTERS memcounters;
-    proc = GetCurrentProcess();
-    memcounters.cb = sizeof(memcounters);
-    GetProcessMemoryInfo(proc, &memcounters, sizeof(memcounters));
-    return memcounters.PeakPagefileUsage;
-#else
-    return 0;
-#endif
-}
-
-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 };
-    int64_t ti;
-
-    atexit(exit_program);
-
-    reset_options(&o);
-
-    av_log_set_flags(AV_LOG_SKIP_REPEATED);
-    parse_loglevel(argc, argv, options);
-
-    avcodec_register_all();
-#if CONFIG_AVDEVICE
-    avdevice_register_all();
-#endif
-    avfilter_register_all();
-    av_register_all();
-    avformat_network_init();
-
-    show_banner();
-
-    parse_cpuflags(argc, argv, options);
-
-    /* parse options */
-    parse_options(&o, argc, argv, options, opt_output_file);
-
-    if (nb_output_files <= 0 && nb_input_files == 0) {
-        show_usage();
-        av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
-        exit(1);
-    }
-
-    /* file converter / grab */
-    if (nb_output_files <= 0) {
-        fprintf(stderr, "At least one output file must be specified\n");
-        exit(1);
-    }
-
-    ti = getutime();
-    if (transcode() < 0)
-        exit(1);
-    ti = getutime() - ti;
-    if (do_benchmark) {
-        int maxrss = getmaxrss() / 1024;
-        printf("bench: utime=%0.3fs maxrss=%ikB\n", ti / 1000000.0, maxrss);
-    }
-
-    exit(0);
-    return 0;
-}
diff --git a/avconv.h b/avconv.h
deleted file mode 100644
index 11e8462..0000000
--- a/avconv.h
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * 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 AVCONV_H
-#define AVCONV_H
-
-#include "config.h"
-
-#include <stdint.h>
-#include <stdio.h>
-
-#if HAVE_PTHREADS
-#include <pthread.h>
-#endif
-
-#include "cmdutils.h"
-
-#include "libavformat/avformat.h"
-#include "libavformat/avio.h"
-
-#include "libavcodec/avcodec.h"
-
-#include "libavfilter/avfilter.h"
-#include "libavfilter/avfiltergraph.h"
-
-#include "libavutil/avutil.h"
-#include "libavutil/dict.h"
-#include "libavutil/fifo.h"
-#include "libavutil/pixfmt.h"
-#include "libavutil/rational.h"
-
-#define VSYNC_AUTO       -1
-#define VSYNC_PASSTHROUGH 0
-#define VSYNC_CFR         1
-#define VSYNC_VFR         2
-
-/* select an input stream for an output stream */
-typedef struct StreamMap {
-    int disabled;           /* 1 is this mapping is disabled by a negative map */
-    int file_index;
-    int stream_index;
-    int sync_file_index;
-    int sync_stream_index;
-    char *linklabel;       /* name of an output link, for mapping lavfi outputs */
-} StreamMap;
-
-/* select an input file for an output file */
-typedef struct MetadataMap {
-    int  file;      // file index
-    char type;      // type of metadata to copy -- (g)lobal, (s)tream, (c)hapter or (p)rogram
-    int  index;     // stream/chapter/program number
-} MetadataMap;
-
-typedef struct OptionsContext {
-    /* input/output options */
-    int64_t start_time;
-    const char *format;
-
-    SpecifierOpt *codec_names;
-    int        nb_codec_names;
-    SpecifierOpt *audio_channels;
-    int        nb_audio_channels;
-    SpecifierOpt *audio_sample_rate;
-    int        nb_audio_sample_rate;
-    SpecifierOpt *frame_rates;
-    int        nb_frame_rates;
-    SpecifierOpt *frame_sizes;
-    int        nb_frame_sizes;
-    SpecifierOpt *frame_pix_fmts;
-    int        nb_frame_pix_fmts;
-
-    /* input options */
-    int64_t input_ts_offset;
-    int rate_emu;
-
-    SpecifierOpt *ts_scale;
-    int        nb_ts_scale;
-    SpecifierOpt *dump_attachment;
-    int        nb_dump_attachment;
-
-    /* output options */
-    StreamMap *stream_maps;
-    int     nb_stream_maps;
-    /* first item specifies output metadata, second is input */
-    MetadataMap (*meta_data_maps)[2];
-    int nb_meta_data_maps;
-    int metadata_global_manual;
-    int metadata_streams_manual;
-    int metadata_chapters_manual;
-    const char **attachments;
-    int       nb_attachments;
-
-    int chapters_input_file;
-
-    int64_t recording_time;
-    uint64_t limit_filesize;
-    float mux_preload;
-    float mux_max_delay;
-    int shortest;
-
-    int video_disable;
-    int audio_disable;
-    int subtitle_disable;
-    int data_disable;
-
-    /* indexed by output file stream index */
-    int   *streamid_map;
-    int nb_streamid_map;
-
-    SpecifierOpt *metadata;
-    int        nb_metadata;
-    SpecifierOpt *max_frames;
-    int        nb_max_frames;
-    SpecifierOpt *bitstream_filters;
-    int        nb_bitstream_filters;
-    SpecifierOpt *codec_tags;
-    int        nb_codec_tags;
-    SpecifierOpt *sample_fmts;
-    int        nb_sample_fmts;
-    SpecifierOpt *qscale;
-    int        nb_qscale;
-    SpecifierOpt *forced_key_frames;
-    int        nb_forced_key_frames;
-    SpecifierOpt *force_fps;
-    int        nb_force_fps;
-    SpecifierOpt *frame_aspect_ratios;
-    int        nb_frame_aspect_ratios;
-    SpecifierOpt *rc_overrides;
-    int        nb_rc_overrides;
-    SpecifierOpt *intra_matrices;
-    int        nb_intra_matrices;
-    SpecifierOpt *inter_matrices;
-    int        nb_inter_matrices;
-    SpecifierOpt *top_field_first;
-    int        nb_top_field_first;
-    SpecifierOpt *metadata_map;
-    int        nb_metadata_map;
-    SpecifierOpt *presets;
-    int        nb_presets;
-    SpecifierOpt *copy_initial_nonkeyframes;
-    int        nb_copy_initial_nonkeyframes;
-    SpecifierOpt *filters;
-    int        nb_filters;
-    SpecifierOpt *pass;
-    int        nb_pass;
-    SpecifierOpt *passlogfiles;
-    int        nb_passlogfiles;
-} OptionsContext;
-
-typedef struct InputFilter {
-    AVFilterContext    *filter;
-    struct InputStream *ist;
-    struct FilterGraph *graph;
-    uint8_t            *name;
-} InputFilter;
-
-typedef struct OutputFilter {
-    AVFilterContext     *filter;
-    struct OutputStream *ost;
-    struct FilterGraph  *graph;
-    uint8_t             *name;
-
-    /* temporary storage until stream maps are processed */
-    AVFilterInOut       *out_tmp;
-} OutputFilter;
-
-typedef struct FilterGraph {
-    int            index;
-    const char    *graph_desc;
-
-    AVFilterGraph *graph;
-
-    InputFilter   **inputs;
-    int          nb_inputs;
-    OutputFilter **outputs;
-    int         nb_outputs;
-} FilterGraph;
-
-typedef struct InputStream {
-    int file_index;
-    AVStream *st;
-    int discard;             /* true if stream data should be discarded */
-    int decoding_needed;     /* true if the packets must be decoded in 'raw_fifo' */
-    AVCodec *dec;
-    AVFrame *decoded_frame;
-
-    int64_t       start;     /* time when read started */
-    /* predicted dts of the next packet read for this stream or (when there are
-     * several frames in a packet) of the next frame in current packet */
-    int64_t       next_dts;
-    /* dts of the last packet read for this stream */
-    int64_t       last_dts;
-    PtsCorrectionContext pts_ctx;
-    double ts_scale;
-    int is_start;            /* is 1 at the start and after a discontinuity */
-    int showed_multi_packet_warning;
-    AVDictionary *opts;
-    AVRational framerate;               /* framerate forced with -r */
-
-    int resample_height;
-    int resample_width;
-    int resample_pix_fmt;
-
-    int      resample_sample_fmt;
-    int      resample_sample_rate;
-    int      resample_channels;
-    uint64_t resample_channel_layout;
-
-    /* a pool of free buffers for decoded data */
-    FrameBuffer *buffer_pool;
-
-    /* decoded data from this stream goes into all those filters
-     * currently video and audio only */
-    InputFilter **filters;
-    int        nb_filters;
-} InputStream;
-
-typedef struct InputFile {
-    AVFormatContext *ctx;
-    int eof_reached;      /* true if eof reached */
-    int eagain;           /* true if last read attempt returned EAGAIN */
-    int ist_index;        /* index of first stream in ist_table */
-    int64_t ts_offset;
-    int nb_streams;       /* number of stream that avconv is aware of; may be different
-                             from ctx.nb_streams if new streams appear during av_read_frame() */
-    int rate_emu;
-
-#if HAVE_PTHREADS
-    pthread_t thread;           /* thread reading from this file */
-    int finished;               /* the thread has exited */
-    int joined;                 /* the thread has been joined */
-    pthread_mutex_t fifo_lock;  /* lock for access to fifo */
-    pthread_cond_t  fifo_cond;  /* the main thread will signal on this cond after reading from fifo */
-    AVFifoBuffer *fifo;         /* demuxed packets are stored here; freed by the main thread */
-#endif
-} InputFile;
-
-typedef struct OutputStream {
-    int file_index;          /* file index */
-    int index;               /* stream index in the output file */
-    int source_index;        /* InputStream index */
-    AVStream *st;            /* stream in the output file */
-    int encoding_needed;     /* true if encoding needed for this stream */
-    int frame_number;
-    /* input pts and corresponding output pts
-       for A/V sync */
-    // double sync_ipts;        /* dts from the AVPacket of the demuxer in second units */
-    struct InputStream *sync_ist; /* input stream to sync against */
-    int64_t sync_opts;       /* output frame counter, could be changed to some true timestamp */ // FIXME look at frame_number
-    /* pts of the first frame encoded for this stream, used for limiting
-     * recording time */
-    int64_t first_pts;
-    AVBitStreamFilterContext *bitstream_filters;
-    AVCodec *enc;
-    int64_t max_frames;
-    AVFrame *filtered_frame;
-
-    /* video only */
-    AVRational frame_rate;
-    int force_fps;
-    int top_field_first;
-
-    float frame_aspect_ratio;
-
-    /* forced key frames */
-    int64_t *forced_kf_pts;
-    int forced_kf_count;
-    int forced_kf_index;
-    char *forced_keyframes;
-
-    char *logfile_prefix;
-    FILE *logfile;
-
-    OutputFilter *filter;
-    char *avfilter;
-
-    int64_t sws_flags;
-    AVDictionary *opts;
-    int finished;        /* no more packets should be written for this stream */
-    int stream_copy;
-    const char *attachment_filename;
-    int copy_initial_nonkeyframes;
-
-    enum AVPixelFormat pix_fmts[2];
-} OutputStream;
-
-typedef struct OutputFile {
-    AVFormatContext *ctx;
-    AVDictionary *opts;
-    int ost_index;       /* index of the first stream in output_streams */
-    int64_t recording_time; /* desired length of the resulting file in microseconds */
-    int64_t start_time;     /* start time in microseconds */
-    uint64_t limit_filesize;
-
-    int shortest;
-} OutputFile;
-
-extern InputStream **input_streams;
-extern int        nb_input_streams;
-extern InputFile   **input_files;
-extern int        nb_input_files;
-
-extern OutputStream **output_streams;
-extern int         nb_output_streams;
-extern OutputFile   **output_files;
-extern int         nb_output_files;
-
-extern FilterGraph **filtergraphs;
-extern int        nb_filtergraphs;
-
-extern char *vstats_filename;
-
-extern float audio_drift_threshold;
-extern float dts_delta_threshold;
-
-extern int audio_volume;
-extern int audio_sync_method;
-extern int video_sync_method;
-extern int do_benchmark;
-extern int do_deinterlace;
-extern int do_hex_dump;
-extern int do_pkt_dump;
-extern int copy_ts;
-extern int copy_tb;
-extern int exit_on_error;
-extern int print_stats;
-extern int qp_hist;
-
-extern const AVIOInterruptCB int_cb;
-
-extern const OptionDef options[];
-
-void reset_options(OptionsContext *o);
-void show_usage(void);
-
-int opt_cpuflags(void *optctx, const char *opt, const char *arg);
-
-void opt_output_file(void *optctx, const char *filename);
-
-void assert_avoptions(AVDictionary *m);
-
-int guess_input_channel_layout(InputStream *ist);
-
-int configure_filtergraph(FilterGraph *fg);
-int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out);
-int ist_in_filtergraph(FilterGraph *fg, InputStream *ist);
-FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost);
-
-#endif /* AVCONV_H */
diff --git a/avconv_filter.c b/avconv_filter.c
deleted file mode 100644
index 8f3f912..0000000
--- a/avconv_filter.c
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * avconv filter configuration
- *
- * 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
- */
-
-#include "avconv.h"
-
-#include "libavfilter/avfilter.h"
-#include "libavfilter/avfiltergraph.h"
-
-#include "libavutil/audioconvert.h"
-#include "libavutil/avassert.h"
-#include "libavutil/pixdesc.h"
-#include "libavutil/pixfmt.h"
-#include "libavutil/samplefmt.h"
-
-/* Define a function for building a string containing a list of
- * allowed formats. */
-#define DEF_CHOOSE_FORMAT(type, var, supported_list, none, get_name, separator)\
-static char *choose_ ## var ## s(OutputStream *ost)                            \
-{                                                                              \
-    if (ost->st->codec->var != none) {                                         \
-        get_name(ost->st->codec->var);                                         \
-        return av_strdup(name);                                                \
-    } else if (ost->enc->supported_list) {                                     \
-        const type *p;                                                         \
-        AVIOContext *s = NULL;                                                 \
-        uint8_t *ret;                                                          \
-        int len;                                                               \
-                                                                               \
-        if (avio_open_dyn_buf(&s) < 0)                                         \
-            exit(1);                                                           \
-                                                                               \
-        for (p = ost->enc->supported_list; *p != none; p++) {                  \
-            get_name(*p);                                                      \
-            avio_printf(s, "%s" separator, name);                              \
-        }                                                                      \
-        len = avio_close_dyn_buf(s, &ret);                                     \
-        ret[len - 1] = 0;                                                      \
-        return ret;                                                            \
-    } else                                                                     \
-        return NULL;                                                           \
-}
-
-DEF_CHOOSE_FORMAT(enum AVPixelFormat, pix_fmt, pix_fmts, AV_PIX_FMT_NONE,
-                  GET_PIX_FMT_NAME, ":")
-
-DEF_CHOOSE_FORMAT(enum AVSampleFormat, sample_fmt, sample_fmts,
-                  AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME, ",")
-
-DEF_CHOOSE_FORMAT(int, sample_rate, supported_samplerates, 0,
-                  GET_SAMPLE_RATE_NAME, ",")
-
-DEF_CHOOSE_FORMAT(uint64_t, channel_layout, channel_layouts, 0,
-                  GET_CH_LAYOUT_NAME, ",")
-
-FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost)
-{
-    FilterGraph *fg = av_mallocz(sizeof(*fg));
-
-    if (!fg)
-        exit(1);
-    fg->index = nb_filtergraphs;
-
-    fg->outputs = grow_array(fg->outputs, sizeof(*fg->outputs), &fg->nb_outputs,
-                             fg->nb_outputs + 1);
-    if (!(fg->outputs[0] = av_mallocz(sizeof(*fg->outputs[0]))))
-        exit(1);
-    fg->outputs[0]->ost   = ost;
-    fg->outputs[0]->graph = fg;
-
-    ost->filter = fg->outputs[0];
-
-    fg->inputs = grow_array(fg->inputs, sizeof(*fg->inputs), &fg->nb_inputs,
-                            fg->nb_inputs + 1);
-    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);
-    ist->filters[ist->nb_filters - 1] = fg->inputs[0];
-
-    filtergraphs = grow_array(filtergraphs, sizeof(*filtergraphs),
-                              &nb_filtergraphs, nb_filtergraphs + 1);
-    filtergraphs[nb_filtergraphs - 1] = fg;
-
-    return fg;
-}
-
-static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
-{
-    InputStream *ist = NULL;
-    enum AVMediaType type = avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx);
-    int i;
-
-    // TODO: support other filter types
-    if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) {
-        av_log(NULL, AV_LOG_FATAL, "Only video and audio filters supported "
-               "currently.\n");
-        exit(1);
-    }
-
-    if (in->name) {
-        AVFormatContext *s;
-        AVStream       *st = NULL;
-        char *p;
-        int file_idx = strtol(in->name, &p, 0);
-
-        if (file_idx < 0 || file_idx >= nb_input_files) {
-            av_log(NULL, AV_LOG_FATAL, "Invalid file index %d in filtegraph description %s.\n",
-                   file_idx, fg->graph_desc);
-            exit(1);
-        }
-        s = input_files[file_idx]->ctx;
-
-        for (i = 0; i < s->nb_streams; i++) {
-            if (s->streams[i]->codec->codec_type != type)
-                continue;
-            if (check_stream_specifier(s, s->streams[i], *p == ':' ? p + 1 : p) == 1) {
-                st = s->streams[i];
-                break;
-            }
-        }
-        if (!st) {
-            av_log(NULL, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s "
-                   "matches no streams.\n", p, fg->graph_desc);
-            exit(1);
-        }
-        ist = input_streams[input_files[file_idx]->ist_index + st->index];
-    } else {
-        /* find the first unused stream of corresponding type */
-        for (i = 0; i < nb_input_streams; i++) {
-            ist = input_streams[i];
-            if (ist->st->codec->codec_type == type && ist->discard)
-                break;
-        }
-        if (i == nb_input_streams) {
-            av_log(NULL, AV_LOG_FATAL, "Cannot find a matching stream for "
-                   "unlabeled input pad %d on filter %s", in->pad_idx,
-                   in->filter_ctx->name);
-            exit(1);
-        }
-    }
-    av_assert0(ist);
-
-    ist->discard         = 0;
-    ist->decoding_needed = 1;
-    ist->st->discard = AVDISCARD_NONE;
-
-    fg->inputs = grow_array(fg->inputs, sizeof(*fg->inputs),
-                            &fg->nb_inputs, fg->nb_inputs + 1);
-    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);
-    ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
-}
-
-static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
-{
-    char *pix_fmts;
-    OutputStream *ost = ofilter->ost;
-    AVCodecContext *codec = ost->st->codec;
-    AVFilterContext *last_filter = out->filter_ctx;
-    int pad_idx = out->pad_idx;
-    int ret;
-    char name[255];
-
-    snprintf(name, sizeof(name), "output stream %d:%d", ost->file_index, ost->index);
-    ret = avfilter_graph_create_filter(&ofilter->filter,
-                                       avfilter_get_by_name("buffersink"),
-                                       name, NULL, NULL, fg->graph);
-    if (ret < 0)
-        return ret;
-
-    if (codec->width || codec->height) {
-        char args[255];
-        AVFilterContext *filter;
-
-        snprintf(args, sizeof(args), "%d:%d:flags=0x%X",
-                 codec->width,
-                 codec->height,
-                 (unsigned)ost->sws_flags);
-        snprintf(name, sizeof(name), "scaler for output stream %d:%d",
-                 ost->file_index, ost->index);
-        if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
-                                                name, args, NULL, fg->graph)) < 0)
-            return ret;
-        if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
-            return ret;
-
-        last_filter = filter;
-        pad_idx = 0;
-    }
-
-    if ((pix_fmts = choose_pix_fmts(ost))) {
-        AVFilterContext *filter;
-        snprintf(name, sizeof(name), "pixel format for output stream %d:%d",
-                 ost->file_index, ost->index);
-        if ((ret = avfilter_graph_create_filter(&filter,
-                                                avfilter_get_by_name("format"),
-                                                "format", pix_fmts, NULL,
-                                                fg->graph)) < 0)
-            return ret;
-        if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
-            return ret;
-
-        last_filter = filter;
-        pad_idx     = 0;
-        av_freep(&pix_fmts);
-    }
-
-    if (ost->frame_rate.num) {
-        AVFilterContext *fps;
-        char args[255];
-
-        snprintf(args, sizeof(args), "fps=%d/%d", ost->frame_rate.num,
-                 ost->frame_rate.den);
-        snprintf(name, sizeof(name), "fps for output stream %d:%d",
-                 ost->file_index, ost->index);
-        ret = avfilter_graph_create_filter(&fps, avfilter_get_by_name("fps"),
-                                           name, args, NULL, fg->graph);
-        if (ret < 0)
-            return ret;
-
-        ret = avfilter_link(last_filter, pad_idx, fps, 0);
-        if (ret < 0)
-            return ret;
-        last_filter = fps;
-        pad_idx = 0;
-    }
-
-    if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
-        return ret;
-
-    return 0;
-}
-
-static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
-{
-    OutputStream *ost = ofilter->ost;
-    AVCodecContext *codec  = ost->st->codec;
-    AVFilterContext *last_filter = out->filter_ctx;
-    int pad_idx = out->pad_idx;
-    char *sample_fmts, *sample_rates, *channel_layouts;
-    char name[255];
-    int ret;
-
-
-    snprintf(name, sizeof(name), "output stream %d:%d", ost->file_index, ost->index);
-    ret = avfilter_graph_create_filter(&ofilter->filter,
-                                       avfilter_get_by_name("abuffersink"),
-                                       name, NULL, NULL, fg->graph);
-    if (ret < 0)
-        return ret;
-
-    if (codec->channels && !codec->channel_layout)
-        codec->channel_layout = av_get_default_channel_layout(codec->channels);
-
-    sample_fmts     = choose_sample_fmts(ost);
-    sample_rates    = choose_sample_rates(ost);
-    channel_layouts = choose_channel_layouts(ost);
-    if (sample_fmts || sample_rates || channel_layouts) {
-        AVFilterContext *format;
-        char args[256];
-        int len = 0;
-
-        if (sample_fmts)
-            len += snprintf(args + len, sizeof(args) - len, "sample_fmts=%s:",
-                            sample_fmts);
-        if (sample_rates)
-            len += snprintf(args + len, sizeof(args) - len, "sample_rates=%s:",
-                            sample_rates);
-        if (channel_layouts)
-            len += snprintf(args + len, sizeof(args) - len, "channel_layouts=%s:",
-                            channel_layouts);
-        args[len - 1] = 0;
-
-        av_freep(&sample_fmts);
-        av_freep(&sample_rates);
-        av_freep(&channel_layouts);
-
-        snprintf(name, sizeof(name), "audio format for output stream %d:%d",
-                 ost->file_index, ost->index);
-        ret = avfilter_graph_create_filter(&format,
-                                           avfilter_get_by_name("aformat"),
-                                           name, args, NULL, fg->graph);
-        if (ret < 0)
-            return ret;
-
-        ret = avfilter_link(last_filter, pad_idx, format, 0);
-        if (ret < 0)
-            return ret;
-
-        last_filter = format;
-        pad_idx = 0;
-    }
-
-    if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
-        return ret;
-
-    return 0;
-}
-
-#define DESCRIBE_FILTER_LINK(f, inout, in)                         \
-{                                                                  \
-    AVFilterContext *ctx = inout->filter_ctx;                      \
-    AVFilterPad *pads = in ? ctx->input_pads  : ctx->output_pads;  \
-    int       nb_pads = in ? ctx->input_count : ctx->output_count; \
-    AVIOContext *pb;                                               \
-                                                                   \
-    if (avio_open_dyn_buf(&pb) < 0)                                \
-        exit(1);                                                   \
-                                                                   \
-    avio_printf(pb, "%s", ctx->filter->name);                      \
-    if (nb_pads > 1)                                               \
-        avio_printf(pb, ":%s", avfilter_pad_get_name(pads, inout->pad_idx));\
-    avio_w8(pb, 0);                                                \
-    avio_close_dyn_buf(pb, &f->name);                              \
-}
-
-int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
-{
-    av_freep(&ofilter->name);
-    DESCRIBE_FILTER_LINK(ofilter, out, 0);
-
-    switch (avfilter_pad_get_type(out->filter_ctx->output_pads, out->pad_idx)) {
-    case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fg, ofilter, out);
-    case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fg, ofilter, out);
-    default: av_assert0(0);
-    }
-}
-
-static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
-                                        AVFilterInOut *in)
-{
-    AVFilterContext *first_filter = in->filter_ctx;
-    AVFilter *filter = avfilter_get_by_name("buffer");
-    InputStream *ist = ifilter->ist;
-    AVRational tb = ist->framerate.num ? av_inv_q(ist->framerate) :
-                                         ist->st->time_base;
-    AVRational sar;
-    char args[255], name[255];
-    int pad_idx = in->pad_idx;
-    int ret;
-
-    sar = ist->st->sample_aspect_ratio.num ?
-          ist->st->sample_aspect_ratio :
-          ist->st->codec->sample_aspect_ratio;
-    snprintf(args, sizeof(args), "%d:%d:%d:%d:%d:%d:%d", ist->st->codec->width,
-             ist->st->codec->height, ist->st->codec->pix_fmt,
-             tb.num, tb.den, sar.num, sar.den);
-    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, fg->graph)) < 0)
-        return ret;
-
-    if (ist->framerate.num) {
-        AVFilterContext *setpts;
-
-        snprintf(name, sizeof(name), "force CFR for input from stream %d:%d",
-                 ist->file_index, ist->st->index);
-        if ((ret = avfilter_graph_create_filter(&setpts,
-                                                avfilter_get_by_name("setpts"),
-                                                name, "N", NULL,
-                                                fg->graph)) < 0)
-            return ret;
-
-        if ((ret = avfilter_link(setpts, 0, first_filter, pad_idx)) < 0)
-            return ret;
-
-        first_filter = setpts;
-        pad_idx = 0;
-    }
-
-    if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0)
-        return ret;
-    return 0;
-}
-
-static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
-                                        AVFilterInOut *in)
-{
-    AVFilterContext *first_filter = in->filter_ctx;
-    AVFilter *filter = avfilter_get_by_name("abuffer");
-    InputStream *ist = ifilter->ist;
-    int pad_idx = in->pad_idx;
-    char args[255], name[255];
-    int ret;
-
-    snprintf(args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s"
-             ":channel_layout=0x%"PRIx64,
-             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);
-    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,
-                                            fg->graph)) < 0)
-        return ret;
-
-    if (audio_sync_method > 0) {
-        AVFilterContext *async;
-        char args[256];
-        int  len = 0;
-
-        av_log(NULL, AV_LOG_WARNING, "-async has been deprecated. Used the "
-               "asyncts audio filter instead.\n");
-
-        if (audio_sync_method > 1)
-            len += snprintf(args + len, sizeof(args) - len, "compensate=1:"
-                            "max_comp=%d:", audio_sync_method);
-        snprintf(args + len, sizeof(args) - len, "min_delta=%f",
-                 audio_drift_threshold);
-
-        snprintf(name, sizeof(name), "graph %d audio sync for input stream %d:%d",
-                 fg->index, ist->file_index, ist->st->index);
-        ret = avfilter_graph_create_filter(&async,
-                                           avfilter_get_by_name("asyncts"),
-                                           name, args, NULL, fg->graph);
-        if (ret < 0)
-            return ret;
-
-        ret = avfilter_link(async, 0, first_filter, pad_idx);
-        if (ret < 0)
-            return ret;
-
-        first_filter = async;
-        pad_idx = 0;
-    }
-    if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0)
-        return ret;
-
-    return 0;
-}
-
-static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter,
-                                  AVFilterInOut *in)
-{
-    av_freep(&ifilter->name);
-    DESCRIBE_FILTER_LINK(ifilter, in, 1);
-
-    switch (avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx)) {
-    case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, ifilter, in);
-    case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, ifilter, in);
-    default: av_assert0(0);
-    }
-}
-
-int configure_filtergraph(FilterGraph *fg)
-{
-    AVFilterInOut *inputs, *outputs, *cur;
-    int ret, i, init = !fg->graph, simple = !fg->graph_desc;
-    const char *graph_desc = simple ? fg->outputs[0]->ost->avfilter :
-                                      fg->graph_desc;
-
-    avfilter_graph_free(&fg->graph);
-    if (!(fg->graph = avfilter_graph_alloc()))
-        return AVERROR(ENOMEM);
-
-    if (simple) {
-        OutputStream *ost = fg->outputs[0]->ost;
-        char args[255];
-        snprintf(args, sizeof(args), "flags=0x%X", (unsigned)ost->sws_flags);
-        fg->graph->scale_sws_opts = av_strdup(args);
-    }
-
-    if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
-        return ret;
-
-    if (simple && (!inputs || inputs->next || !outputs || outputs->next)) {
-        av_log(NULL, AV_LOG_ERROR, "Simple filtergraph '%s' does not have "
-               "exactly one input and output.\n", graph_desc);
-        return AVERROR(EINVAL);
-    }
-
-    for (cur = inputs; !simple && init && cur; cur = cur->next)
-        init_input_filter(fg, cur);
-
-    for (cur = inputs, i = 0; cur; cur = cur->next, i++)
-        if ((ret = configure_input_filter(fg, fg->inputs[i], cur)) < 0)
-            return ret;
-    avfilter_inout_free(&inputs);
-
-    if (!init || simple) {
-        /* we already know the mappings between lavfi outputs and output streams,
-         * so we can finish the setup */
-        for (cur = outputs, i = 0; cur; cur = cur->next, i++)
-            configure_output_filter(fg, fg->outputs[i], cur);
-        avfilter_inout_free(&outputs);
-
-        if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
-            return ret;
-    } 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);
-            if (!(fg->outputs[fg->nb_outputs - 1] = av_mallocz(sizeof(*fg->outputs[0]))))
-                exit(1);
-            fg->outputs[fg->nb_outputs - 1]->graph   = fg;
-            fg->outputs[fg->nb_outputs - 1]->out_tmp = cur;
-            cur = cur->next;
-            fg->outputs[fg->nb_outputs - 1]->out_tmp->next = NULL;
-        }
-    }
-
-    return 0;
-}
-
-int ist_in_filtergraph(FilterGraph *fg, InputStream *ist)
-{
-    int i;
-    for (i = 0; i < fg->nb_inputs; i++)
-        if (fg->inputs[i]->ist == ist)
-            return 1;
-    return 0;
-}
-
diff --git a/avconv_opt.c b/avconv_opt.c
deleted file mode 100644
index 058d5a3..0000000
--- a/avconv_opt.c
+++ /dev/null
@@ -1,2051 +0,0 @@
-/*
- * avconv option parsing
- *
- * 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
- */
-
-#include <stdint.h>
-
-#include "avconv.h"
-#include "cmdutils.h"
-
-#include "libavformat/avformat.h"
-
-#include "libavcodec/avcodec.h"
-
-#include "libavfilter/avfilter.h"
-#include "libavfilter/avfiltergraph.h"
-
-#include "libavutil/audioconvert.h"
-#include "libavutil/avassert.h"
-#include "libavutil/avstring.h"
-#include "libavutil/avutil.h"
-#include "libavutil/intreadwrite.h"
-#include "libavutil/fifo.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/opt.h"
-#include "libavutil/parseutils.h"
-#include "libavutil/pixdesc.h"
-#include "libavutil/pixfmt.h"
-
-#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
-{\
-    int i, ret;\
-    for (i = 0; i < o->nb_ ## name; i++) {\
-        char *spec = o->name[i].specifier;\
-        if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0)\
-            outvar = o->name[i].u.type;\
-        else if (ret < 0)\
-            exit(1);\
-    }\
-}
-
-char *vstats_filename;
-
-float audio_drift_threshold = 0.1;
-float dts_delta_threshold   = 10;
-
-int audio_volume      = 256;
-int audio_sync_method = 0;
-int video_sync_method = VSYNC_AUTO;
-int do_deinterlace    = 0;
-int do_benchmark      = 0;
-int do_hex_dump       = 0;
-int do_pkt_dump       = 0;
-int copy_ts           = 0;
-int copy_tb           = 1;
-int exit_on_error     = 0;
-int print_stats       = 1;
-int qp_hist           = 0;
-
-static int file_overwrite     = 0;
-static int video_discard      = 0;
-static int intra_dc_precision = 8;
-static int using_stdin        = 0;
-static int input_sync;
-
-void reset_options(OptionsContext *o)
-{
-    const OptionDef *po = options;
-    int i;
-
-    /* all OPT_SPEC and OPT_STRING can be freed in generic way */
-    while (po->name) {
-        void *dst = (uint8_t*)o + po->u.off;
-
-        if (po->flags & OPT_SPEC) {
-            SpecifierOpt **so = dst;
-            int i, *count = (int*)(so + 1);
-            for (i = 0; i < *count; i++) {
-                av_freep(&(*so)[i].specifier);
-                if (po->flags & OPT_STRING)
-                    av_freep(&(*so)[i].u.str);
-            }
-            av_freep(so);
-            *count = 0;
-        } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
-            av_freep(dst);
-        po++;
-    }
-
-    for (i = 0; i < o->nb_stream_maps; i++)
-        av_freep(&o->stream_maps[i].linklabel);
-    av_freep(&o->stream_maps);
-    av_freep(&o->meta_data_maps);
-    av_freep(&o->streamid_map);
-
-    memset(o, 0, sizeof(*o));
-
-    o->mux_max_delay  = 0.7;
-    o->recording_time = INT64_MAX;
-    o->limit_filesize = UINT64_MAX;
-    o->chapters_input_file = INT_MAX;
-
-    uninit_opts();
-    init_opts();
-}
-
-
-static double parse_frame_aspect_ratio(const char *arg)
-{
-    int x = 0, y = 0;
-    double ar = 0;
-    const char *p;
-    char *end;
-
-    p = strchr(arg, ':');
-    if (p) {
-        x = strtol(arg, &end, 10);
-        if (end == p)
-            y = strtol(end + 1, &end, 10);
-        if (x > 0 && y > 0)
-            ar = (double)x / (double)y;
-    } else
-        ar = strtod(arg, NULL);
-
-    if (!ar) {
-        av_log(NULL, AV_LOG_FATAL, "Incorrect aspect ratio specification.\n");
-        exit(1);
-    }
-    return ar;
-}
-
-static int opt_audio_codec(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    return parse_option(o, "codec:a", arg, options);
-}
-
-static int opt_video_codec(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    return parse_option(o, "codec:v", arg, options);
-}
-
-static int opt_subtitle_codec(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    return parse_option(o, "codec:s", arg, options);
-}
-
-static int opt_data_codec(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    return parse_option(o, "codec:d", arg, options);
-}
-
-static int opt_map(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    StreamMap *m = NULL;
-    int i, negative = 0, file_idx;
-    int sync_file_idx = -1, sync_stream_idx;
-    char *p, *sync;
-    char *map;
-
-    if (*arg == '-') {
-        negative = 1;
-        arg++;
-    }
-    map = av_strdup(arg);
-
-    /* parse sync stream first, just pick first matching stream */
-    if (sync = strchr(map, ',')) {
-        *sync = 0;
-        sync_file_idx = strtol(sync + 1, &sync, 0);
-        if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {
-            av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx);
-            exit(1);
-        }
-        if (*sync)
-            sync++;
-        for (i = 0; i < input_files[sync_file_idx]->nb_streams; i++)
-            if (check_stream_specifier(input_files[sync_file_idx]->ctx,
-                                       input_files[sync_file_idx]->ctx->streams[i], sync) == 1) {
-                sync_stream_idx = i;
-                break;
-            }
-        if (i == input_files[sync_file_idx]->nb_streams) {
-            av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not "
-                                       "match any streams.\n", arg);
-            exit(1);
-        }
-    }
-
-
-    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);
-        m = &o->stream_maps[o->nb_stream_maps - 1];
-        m->linklabel = av_get_token(&c, "]");
-        if (!m->linklabel) {
-            av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", map);
-            exit(1);
-        }
-    } else {
-        file_idx = strtol(map, &p, 0);
-        if (file_idx >= nb_input_files || file_idx < 0) {
-            av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
-            exit(1);
-        }
-        if (negative)
-            /* disable some already defined maps */
-            for (i = 0; i < o->nb_stream_maps; i++) {
-                m = &o->stream_maps[i];
-                if (file_idx == m->file_index &&
-                    check_stream_specifier(input_files[m->file_index]->ctx,
-                                           input_files[m->file_index]->ctx->streams[m->stream_index],
-                                           *p == ':' ? p + 1 : p) > 0)
-                    m->disabled = 1;
-            }
-        else
-            for (i = 0; i < input_files[file_idx]->nb_streams; i++) {
-                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);
-                m = &o->stream_maps[o->nb_stream_maps - 1];
-
-                m->file_index   = file_idx;
-                m->stream_index = i;
-
-                if (sync_file_idx >= 0) {
-                    m->sync_file_index   = sync_file_idx;
-                    m->sync_stream_index = sync_stream_idx;
-                } else {
-                    m->sync_file_index   = file_idx;
-                    m->sync_stream_index = i;
-                }
-            }
-    }
-
-    if (!m) {
-        av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n", arg);
-        exit(1);
-    }
-
-    av_freep(&map);
-    return 0;
-}
-
-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);
-    o->attachments[o->nb_attachments - 1] = arg;
-    return 0;
-}
-
-/**
- * Parse a metadata specifier passed as 'arg' parameter.
- * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram)
- * @param index for type c/p, chapter/program index is written here
- * @param stream_spec for type s, the stream specifier is written here
- */
-static void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec)
-{
-    if (*arg) {
-        *type = *arg;
-        switch (*arg) {
-        case 'g':
-            break;
-        case 's':
-            if (*(++arg) && *arg != ':') {
-                av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
-                exit(1);
-            }
-            *stream_spec = *arg == ':' ? arg + 1 : "";
-            break;
-        case 'c':
-        case 'p':
-            if (*(++arg) == ':')
-                *index = strtol(++arg, NULL, 0);
-            break;
-        default:
-            av_log(NULL, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
-            exit(1);
-        }
-    } else
-        *type = 'g';
-}
-
-static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o)
-{
-    AVDictionary **meta_in = NULL;
-    AVDictionary **meta_out;
-    int i, ret = 0;
-    char type_in, type_out;
-    const char *istream_spec = NULL, *ostream_spec = NULL;
-    int idx_in = 0, idx_out = 0;
-
-    parse_meta_type(inspec,  &type_in,  &idx_in,  &istream_spec);
-    parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec);
-
-    if (type_in == 'g' || type_out == 'g')
-        o->metadata_global_manual = 1;
-    if (type_in == 's' || type_out == 's')
-        o->metadata_streams_manual = 1;
-    if (type_in == 'c' || type_out == 'c')
-        o->metadata_chapters_manual = 1;
-
-#define METADATA_CHECK_INDEX(index, nb_elems, desc)\
-    if ((index) < 0 || (index) >= (nb_elems)) {\
-        av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
-                (desc), (index));\
-        exit(1);\
-    }
-
-#define SET_DICT(type, meta, context, index)\
-        switch (type) {\
-        case 'g':\
-            meta = &context->metadata;\
-            break;\
-        case 'c':\
-            METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
-            meta = &context->chapters[index]->metadata;\
-            break;\
-        case 'p':\
-            METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
-            meta = &context->programs[index]->metadata;\
-            break;\
-        default: av_assert0(0);\
-        }\
-
-    SET_DICT(type_in, meta_in, ic, idx_in);
-    SET_DICT(type_out, meta_out, oc, idx_out);
-
-    /* for input streams choose first matching stream */
-    if (type_in == 's') {
-        for (i = 0; i < ic->nb_streams; i++) {
-            if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
-                meta_in = &ic->streams[i]->metadata;
-                break;
-            } else if (ret < 0)
-                exit(1);
-        }
-        if (!meta_in) {
-            av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match  any streams.\n", istream_spec);
-            exit(1);
-        }
-    }
-
-    if (type_out == 's') {
-        for (i = 0; i < oc->nb_streams; i++) {
-            if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
-                meta_out = &oc->streams[i]->metadata;
-                av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
-            } else if (ret < 0)
-                exit(1);
-        }
-    } else
-        av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
-
-    return 0;
-}
-
-static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder)
-{
-    const AVCodecDescriptor *desc;
-    const char *codec_string = encoder ? "encoder" : "decoder";
-    AVCodec *codec;
-
-    codec = encoder ?
-        avcodec_find_encoder_by_name(name) :
-        avcodec_find_decoder_by_name(name);
-
-    if (!codec && (desc = avcodec_descriptor_get_by_name(name))) {
-        codec = encoder ? avcodec_find_encoder(desc->id) :
-                          avcodec_find_decoder(desc->id);
-        if (codec)
-            av_log(NULL, AV_LOG_VERBOSE, "Matched %s '%s' for codec '%s'.\n",
-                   codec_string, codec->name, desc->name);
-    }
-
-    if (!codec) {
-        av_log(NULL, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
-        exit(1);
-    }
-    if (codec->type != type) {
-        av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
-        exit(1);
-    }
-    return codec;
-}
-
-static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
-{
-    char *codec_name = NULL;
-
-    MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
-    if (codec_name) {
-        AVCodec *codec = find_codec_or_die(codec_name, st->codec->codec_type, 0);
-        st->codec->codec_id = codec->id;
-        return codec;
-    } else
-        return avcodec_find_decoder(st->codec->codec_id);
-}
-
-/* Add all the streams from the given input file to the global
- * list of input streams. */
-static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
-{
-    int i;
-
-    for (i = 0; i < ic->nb_streams; i++) {
-        AVStream *st = ic->streams[i];
-        AVCodecContext *dec = st->codec;
-        InputStream *ist = av_mallocz(sizeof(*ist));
-        char *framerate = NULL;
-
-        if (!ist)
-            exit(1);
-
-        input_streams = grow_array(input_streams, sizeof(*input_streams), &nb_input_streams, nb_input_streams + 1);
-        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, NULL);
-
-        ist->ts_scale = 1.0;
-        MATCH_PER_STREAM_OPT(ts_scale, dbl, ist->ts_scale, ic, st);
-
-        ist->dec = choose_decoder(o, ic, st);
-
-        switch (dec->codec_type) {
-        case AVMEDIA_TYPE_VIDEO:
-            ist->resample_height  = dec->height;
-            ist->resample_width   = dec->width;
-            ist->resample_pix_fmt = dec->pix_fmt;
-
-            MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
-            if (framerate && av_parse_video_rate(&ist->framerate,
-                                                 framerate) < 0) {
-                av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
-                       framerate);
-                exit(1);
-            }
-
-            break;
-        case AVMEDIA_TYPE_AUDIO:
-            guess_input_channel_layout(ist);
-
-            ist->resample_sample_fmt     = dec->sample_fmt;
-            ist->resample_sample_rate    = dec->sample_rate;
-            ist->resample_channels       = dec->channels;
-            ist->resample_channel_layout = dec->channel_layout;
-
-            break;
-        case AVMEDIA_TYPE_DATA:
-        case AVMEDIA_TYPE_SUBTITLE:
-        case AVMEDIA_TYPE_ATTACHMENT:
-        case AVMEDIA_TYPE_UNKNOWN:
-            break;
-        default:
-            abort();
-        }
-    }
-}
-
-static void assert_file_overwrite(const char *filename)
-{
-    if (!file_overwrite &&
-        (strchr(filename, ':') == NULL || filename[1] == ':' ||
-         av_strstart(filename, "file:", NULL))) {
-        if (avio_check(filename, 0) == 0) {
-            if (!using_stdin) {
-                fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
-                fflush(stderr);
-                if (!read_yesno()) {
-                    fprintf(stderr, "Not overwriting - exiting\n");
-                    exit(1);
-                }
-            }
-            else {
-                fprintf(stderr,"File '%s' already exists. Exiting.\n", filename);
-                exit(1);
-            }
-        }
-    }
-}
-
-static void dump_attachment(AVStream *st, const char *filename)
-{
-    int ret;
-    AVIOContext *out = NULL;
-    AVDictionaryEntry *e;
-
-    if (!st->codec->extradata_size) {
-        av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
-               nb_input_files - 1, st->index);
-        return;
-    }
-    if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
-        filename = e->value;
-    if (!*filename) {
-        av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
-               "in stream #%d:%d.\n", nb_input_files - 1, st->index);
-        exit(1);
-    }
-
-    assert_file_overwrite(filename);
-
-    if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
-        av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
-               filename);
-        exit(1);
-    }
-
-    avio_write(out, st->codec->extradata, st->codec->extradata_size);
-    avio_flush(out);
-    avio_close(out);
-}
-
-static int opt_input_file(void *optctx, const char *opt, const char *filename)
-{
-    OptionsContext *o = optctx;
-    AVFormatContext *ic;
-    AVInputFormat *file_iformat = NULL;
-    int err, i, ret;
-    int64_t timestamp;
-    uint8_t buf[128];
-    AVDictionary **opts;
-    int orig_nb_streams;                     // number of streams before avformat_find_stream_info
-
-    if (o->format) {
-        if (!(file_iformat = av_find_input_format(o->format))) {
-            av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
-            exit(1);
-        }
-    }
-
-    if (!strcmp(filename, "-"))
-        filename = "pipe:";
-
-    using_stdin |= !strncmp(filename, "pipe:", 5) ||
-                    !strcmp(filename, "/dev/stdin");
-
-    /* get default parameters from command line */
-    ic = avformat_alloc_context();
-    if (!ic) {
-        print_error(filename, AVERROR(ENOMEM));
-        exit(1);
-    }
-    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);
-    }
-    if (o->nb_audio_channels) {
-        /* because we set audio_channels based on both the "ac" and
-         * "channel_layout" options, we need to check that the specified
-         * demuxer actually has the "channels" option before setting it */
-        if (file_iformat && file_iformat->priv_class &&
-            av_opt_find(&file_iformat->priv_class, "channels", NULL, 0,
-                        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);
-        }
-    }
-    if (o->nb_frame_rates) {
-        /* set the format-level framerate option;
-         * this is important for video grabbers, e.g. x11 */
-        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",
-                        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);
-    }
-    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);
-
-    ic->flags |= AVFMT_FLAG_NONBLOCK;
-    ic->interrupt_callback = int_cb;
-
-    /* open the input file with generic libav function */
-    err = avformat_open_input(&ic, filename, file_iformat, &format_opts);
-    if (err < 0) {
-        print_error(filename, err);
-        exit(1);
-    }
-    assert_avoptions(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);
-    orig_nb_streams = ic->nb_streams;
-
-    /* If not enough info to get the stream parameters, we decode the
-       first frames to get it. (used in mpeg case for example) */
-    ret = avformat_find_stream_info(ic, opts);
-    if (ret < 0) {
-        av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
-        avformat_close_input(&ic);
-        exit(1);
-    }
-
-    timestamp = o->start_time;
-    /* add the stream start time */
-    if (ic->start_time != AV_NOPTS_VALUE)
-        timestamp += ic->start_time;
-
-    /* if seeking requested, we execute it */
-    if (o->start_time != 0) {
-        ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
-        if (ret < 0) {
-            av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
-                   filename, (double)timestamp / AV_TIME_BASE);
-        }
-    }
-
-    /* update the current parameters so that they match the one of the input stream */
-    add_input_streams(o, ic);
-
-    /* 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);
-    if (!(input_files[nb_input_files - 1] = av_mallocz(sizeof(*input_files[0]))))
-        exit(1);
-
-    input_files[nb_input_files - 1]->ctx        = ic;
-    input_files[nb_input_files - 1]->ist_index  = nb_input_streams - ic->nb_streams;
-    input_files[nb_input_files - 1]->ts_offset  = o->input_ts_offset - (copy_ts ? 0 : timestamp);
-    input_files[nb_input_files - 1]->nb_streams = ic->nb_streams;
-    input_files[nb_input_files - 1]->rate_emu   = o->rate_emu;
-
-    for (i = 0; i < o->nb_dump_attachment; i++) {
-        int j;
-
-        for (j = 0; j < ic->nb_streams; j++) {
-            AVStream *st = ic->streams[j];
-
-            if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1)
-                dump_attachment(st, o->dump_attachment[i].u.str);
-        }
-    }
-
-    for (i = 0; i < orig_nb_streams; i++)
-        av_dict_free(&opts[i]);
-    av_freep(&opts);
-
-    reset_options(o);
-    return 0;
-}
-
-static uint8_t *get_line(AVIOContext *s)
-{
-    AVIOContext *line;
-    uint8_t *buf;
-    char c;
-
-    if (avio_open_dyn_buf(&line) < 0) {
-        av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n");
-        exit(1);
-    }
-
-    while ((c = avio_r8(s)) && c != '\n')
-        avio_w8(line, c);
-    avio_w8(line, 0);
-    avio_close_dyn_buf(line, &buf);
-
-    return buf;
-}
-
-static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
-{
-    int i, ret = 1;
-    char filename[1000];
-    const char *base[3] = { getenv("AVCONV_DATADIR"),
-                            getenv("HOME"),
-                            AVCONV_DATADIR,
-                            };
-
-    for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) {
-        if (!base[i])
-            continue;
-        if (codec_name) {
-            snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
-                     i != 1 ? "" : "/.avconv", codec_name, preset_name);
-            ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
-        }
-        if (ret) {
-            snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
-                     i != 1 ? "" : "/.avconv", preset_name);
-            ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
-        }
-    }
-    return ret;
-}
-
-static void choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost)
-{
-    char *codec_name = NULL;
-
-    MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
-    if (!codec_name) {
-        ost->st->codec->codec_id = av_guess_codec(s->oformat, NULL, s->filename,
-                                                  NULL, ost->st->codec->codec_type);
-        ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
-    } else if (!strcmp(codec_name, "copy"))
-        ost->stream_copy = 1;
-    else {
-        ost->enc = find_codec_or_die(codec_name, ost->st->codec->codec_type, 1);
-        ost->st->codec->codec_id = ost->enc->id;
-    }
-}
-
-static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type)
-{
-    OutputStream *ost;
-    AVStream *st = avformat_new_stream(oc, NULL);
-    int idx      = oc->nb_streams - 1, ret = 0;
-    char *bsf = NULL, *next, *codec_tag = NULL;
-    AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
-    double qscale = -1;
-    char *buf = NULL, *arg = NULL, *preset = NULL;
-    AVIOContext *s = NULL;
-
-    if (!st) {
-        av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");
-        exit(1);
-    }
-
-    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);
-    if (!(ost = av_mallocz(sizeof(*ost))))
-        exit(1);
-    output_streams[nb_output_streams - 1] = ost;
-
-    ost->file_index = nb_output_files;
-    ost->index      = idx;
-    ost->st         = st;
-    st->codec->codec_type = type;
-    choose_encoder(o, oc, ost);
-    if (ost->enc) {
-        ost->opts  = filter_codec_opts(codec_opts, ost->enc->id, oc, st, ost->enc);
-    }
-
-    avcodec_get_context_defaults3(st->codec, ost->enc);
-    st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy
-
-    MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
-    if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
-        do  {
-            buf = get_line(s);
-            if (!buf[0] || buf[0] == '#') {
-                av_free(buf);
-                continue;
-            }
-            if (!(arg = strchr(buf, '='))) {
-                av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
-                exit(1);
-            }
-            *arg++ = 0;
-            av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE);
-            av_free(buf);
-        } while (!s->eof_reached);
-        avio_close(s);
-    }
-    if (ret) {
-        av_log(NULL, AV_LOG_FATAL,
-               "Preset %s specified for stream %d:%d, but could not be opened.\n",
-               preset, ost->file_index, ost->index);
-        exit(1);
-    }
-
-    ost->max_frames = INT64_MAX;
-    MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
-
-    MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);
-    while (bsf) {
-        if (next = strchr(bsf, ','))
-            *next++ = 0;
-        if (!(bsfc = av_bitstream_filter_init(bsf))) {
-            av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
-            exit(1);
-        }
-        if (bsfc_prev)
-            bsfc_prev->next = bsfc;
-        else
-            ost->bitstream_filters = bsfc;
-
-        bsfc_prev = bsfc;
-        bsf       = next;
-    }
-
-    MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
-    if (codec_tag) {
-        uint32_t tag = strtol(codec_tag, &next, 0);
-        if (*next)
-            tag = AV_RL32(codec_tag);
-        st->codec->codec_tag = tag;
-    }
-
-    MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
-    if (qscale >= 0) {
-        st->codec->flags |= CODEC_FLAG_QSCALE;
-        st->codec->global_quality = FF_QP2LAMBDA * qscale;
-    }
-
-    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);
-
-    ost->pix_fmts[0] = ost->pix_fmts[1] = AV_PIX_FMT_NONE;
-
-    return ost;
-}
-
-static void parse_matrix_coeffs(uint16_t *dest, const char *str)
-{
-    int i;
-    const char *p = str;
-    for (i = 0;; i++) {
-        dest[i] = atoi(p);
-        if (i == 63)
-            break;
-        p = strchr(p, ',');
-        if (!p) {
-            av_log(NULL, AV_LOG_FATAL, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
-            exit(1);
-        }
-        p++;
-    }
-}
-
-static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
-{
-    AVStream *st;
-    OutputStream *ost;
-    AVCodecContext *video_enc;
-
-    ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO);
-    st  = ost->st;
-    video_enc = st->codec;
-
-    if (!ost->stream_copy) {
-        const char *p = NULL;
-        char *frame_rate = NULL, *frame_size = NULL;
-        char *frame_aspect_ratio = NULL, *frame_pix_fmt = NULL;
-        char *intra_matrix = NULL, *inter_matrix = NULL;
-        const char *filters = "null";
-        int do_pass = 0;
-        int i;
-
-        MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
-        if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
-            av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
-            exit(1);
-        }
-
-        MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
-        if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
-            av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
-            exit(1);
-        }
-
-        MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
-        if (frame_aspect_ratio)
-            ost->frame_aspect_ratio = parse_frame_aspect_ratio(frame_aspect_ratio);
-
-        MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
-        if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == AV_PIX_FMT_NONE) {
-            av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
-            exit(1);
-        }
-        st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
-
-        MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
-        if (intra_matrix) {
-            if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {
-                av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
-                exit(1);
-            }
-            parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
-        }
-        MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
-        if (inter_matrix) {
-            if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
-                av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for inter matrix.\n");
-                exit(1);
-            }
-            parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
-        }
-
-        MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
-        for (i = 0; p; i++) {
-            int start, end, q;
-            int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
-            if (e != 3) {
-                av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");
-                exit(1);
-            }
-            video_enc->rc_override =
-                av_realloc(video_enc->rc_override,
-                           sizeof(RcOverride) * (i + 1));
-            video_enc->rc_override[i].start_frame = start;
-            video_enc->rc_override[i].end_frame   = end;
-            if (q > 0) {
-                video_enc->rc_override[i].qscale         = q;
-                video_enc->rc_override[i].quality_factor = 1.0;
-            }
-            else {
-                video_enc->rc_override[i].qscale         = 0;
-                video_enc->rc_override[i].quality_factor = -q/100.0;
-            }
-            p = strchr(p, '/');
-            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;
-
-        /* two pass mode */
-        MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
-        if (do_pass) {
-            if (do_pass == 1) {
-                video_enc->flags |= CODEC_FLAG_PASS1;
-            } else {
-                video_enc->flags |= CODEC_FLAG_PASS2;
-            }
-        }
-
-        MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
-        if (ost->logfile_prefix &&
-            !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
-            exit(1);
-
-        MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
-        if (ost->forced_keyframes)
-            ost->forced_keyframes = av_strdup(ost->forced_keyframes);
-
-        MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
-
-        ost->top_field_first = -1;
-        MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
-
-        MATCH_PER_STREAM_OPT(filters, str, filters, oc, st);
-        ost->avfilter = av_strdup(filters);
-    } else {
-        MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
-    }
-
-    return ost;
-}
-
-static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc)
-{
-    AVStream *st;
-    OutputStream *ost;
-    AVCodecContext *audio_enc;
-
-    ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO);
-    st  = ost->st;
-
-    audio_enc = st->codec;
-    audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
-
-    if (!ost->stream_copy) {
-        char *sample_fmt = NULL;
-        const char *filters = "anull";
-
-        MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
-
-        MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
-        if (sample_fmt &&
-            (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
-            av_log(NULL, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
-            exit(1);
-        }
-
-        MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
-
-        MATCH_PER_STREAM_OPT(filters, str, filters, oc, st);
-        ost->avfilter = av_strdup(filters);
-    }
-
-    return ost;
-}
-
-static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc)
-{
-    OutputStream *ost;
-
-    ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA);
-    if (!ost->stream_copy) {
-        av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
-        exit(1);
-    }
-
-    return ost;
-}
-
-static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc)
-{
-    OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT);
-    ost->stream_copy = 1;
-    return ost;
-}
-
-static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc)
-{
-    AVStream *st;
-    OutputStream *ost;
-    AVCodecContext *subtitle_enc;
-
-    ost = new_output_stream(o, oc, AVMEDIA_TYPE_SUBTITLE);
-    st  = ost->st;
-    subtitle_enc = st->codec;
-
-    subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
-
-    return ost;
-}
-
-/* arg format is "output-stream-index:streamid-value". */
-static int opt_streamid(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    int idx;
-    char *p;
-    char idx_str[16];
-
-    av_strlcpy(idx_str, arg, sizeof(idx_str));
-    p = strchr(idx_str, ':');
-    if (!p) {
-        av_log(NULL, AV_LOG_FATAL,
-               "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
-               arg, opt);
-        exit(1);
-    }
-    *p++ = '\0';
-    idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, INT_MAX);
-    o->streamid_map = grow_array(o->streamid_map, sizeof(*o->streamid_map), &o->nb_streamid_map, idx+1);
-    o->streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
-    return 0;
-}
-
-static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
-{
-    AVFormatContext *is = ifile->ctx;
-    AVFormatContext *os = ofile->ctx;
-    AVChapter **tmp;
-    int i;
-
-    tmp = av_realloc(os->chapters, sizeof(*os->chapters) * (is->nb_chapters + os->nb_chapters));
-    if (!tmp)
-        return AVERROR(ENOMEM);
-    os->chapters = tmp;
-
-    for (i = 0; i < is->nb_chapters; i++) {
-        AVChapter *in_ch = is->chapters[i], *out_ch;
-        int64_t ts_off   = av_rescale_q(ofile->start_time - ifile->ts_offset,
-                                       AV_TIME_BASE_Q, in_ch->time_base);
-        int64_t rt       = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
-                           av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
-
-
-        if (in_ch->end < ts_off)
-            continue;
-        if (rt != INT64_MAX && in_ch->start > rt + ts_off)
-            break;
-
-        out_ch = av_mallocz(sizeof(AVChapter));
-        if (!out_ch)
-            return AVERROR(ENOMEM);
-
-        out_ch->id        = in_ch->id;
-        out_ch->time_base = in_ch->time_base;
-        out_ch->start     = FFMAX(0,  in_ch->start - ts_off);
-        out_ch->end       = FFMIN(rt, in_ch->end   - ts_off);
-
-        if (copy_metadata)
-            av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
-
-        os->chapters[os->nb_chapters++] = out_ch;
-    }
-    return 0;
-}
-
-static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
-                               AVFormatContext *oc)
-{
-    OutputStream *ost;
-
-    switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
-                                  ofilter->out_tmp->pad_idx)) {
-    case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc); break;
-    case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc); break;
-    default:
-        av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported "
-               "currently.\n");
-        exit(1);
-    }
-
-    ost->source_index = -1;
-    ost->filter       = ofilter;
-
-    ofilter->ost      = ost;
-
-    if (ost->stream_copy) {
-        av_log(NULL, AV_LOG_ERROR, "Streamcopy requested for output stream %d:%d, "
-               "which is fed from a complex filtergraph. Filtering and streamcopy "
-               "cannot be used together.\n", ost->file_index, ost->index);
-        exit(1);
-    }
-
-    if (configure_output_filter(ofilter->graph, ofilter, ofilter->out_tmp) < 0) {
-        av_log(NULL, AV_LOG_FATAL, "Error configuring filter.\n");
-        exit(1);
-    }
-    avfilter_inout_free(&ofilter->out_tmp);
-}
-
-static int configure_complex_filters(void)
-{
-    int i, ret = 0;
-
-    for (i = 0; i < nb_filtergraphs; i++)
-        if (!filtergraphs[i]->graph &&
-            (ret = configure_filtergraph(filtergraphs[i])) < 0)
-            return ret;
-    return 0;
-}
-
-void opt_output_file(void *optctx, const char *filename)
-{
-    OptionsContext *o = optctx;
-    AVFormatContext *oc;
-    int i, j, err;
-    AVOutputFormat *file_oformat;
-    OutputStream *ost;
-    InputStream  *ist;
-
-    if (configure_complex_filters() < 0) {
-        av_log(NULL, AV_LOG_FATAL, "Error configuring filters.\n");
-        exit(1);
-    }
-
-    if (!strcmp(filename, "-"))
-        filename = "pipe:";
-
-    oc = avformat_alloc_context();
-    if (!oc) {
-        print_error(filename, AVERROR(ENOMEM));
-        exit(1);
-    }
-
-    if (o->format) {
-        file_oformat = av_guess_format(o->format, NULL, NULL);
-        if (!file_oformat) {
-            av_log(NULL, AV_LOG_FATAL, "Requested output format '%s' is not a suitable output format\n", o->format);
-            exit(1);
-        }
-    } else {
-        file_oformat = av_guess_format(NULL, filename, NULL);
-        if (!file_oformat) {
-            av_log(NULL, AV_LOG_FATAL, "Unable to find a suitable output format for '%s'\n",
-                   filename);
-            exit(1);
-        }
-    }
-
-    oc->oformat = file_oformat;
-    oc->interrupt_callback = int_cb;
-    av_strlcpy(oc->filename, filename, sizeof(oc->filename));
-
-    /* create streams for all unlabeled output pads */
-    for (i = 0; i < nb_filtergraphs; i++) {
-        FilterGraph *fg = filtergraphs[i];
-        for (j = 0; j < fg->nb_outputs; j++) {
-            OutputFilter *ofilter = fg->outputs[j];
-
-            if (!ofilter->out_tmp || ofilter->out_tmp->name)
-                continue;
-
-            switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
-                                          ofilter->out_tmp->pad_idx)) {
-            case AVMEDIA_TYPE_VIDEO:    o->video_disable    = 1; break;
-            case AVMEDIA_TYPE_AUDIO:    o->audio_disable    = 1; break;
-            case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break;
-            }
-            init_output_filter(ofilter, o, oc);
-        }
-    }
-
-    if (!o->nb_stream_maps) {
-        /* pick the "best" stream of each type */
-#define NEW_STREAM(type, index)\
-        if (index >= 0) {\
-            ost = new_ ## type ## _stream(o, oc);\
-            ost->source_index = index;\
-            ost->sync_ist     = input_streams[index];\
-            input_streams[index]->discard = 0;\
-            input_streams[index]->st->discard = AVDISCARD_NONE;\
-        }
-
-        /* video: highest resolution */
-        if (!o->video_disable && oc->oformat->video_codec != AV_CODEC_ID_NONE) {
-            int area = 0, idx = -1;
-            for (i = 0; i < nb_input_streams; i++) {
-                ist = input_streams[i];
-                if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
-                    ist->st->codec->width * ist->st->codec->height > area) {
-                    area = ist->st->codec->width * ist->st->codec->height;
-                    idx = i;
-                }
-            }
-            NEW_STREAM(video, idx);
-        }
-
-        /* audio: most channels */
-        if (!o->audio_disable && oc->oformat->audio_codec != AV_CODEC_ID_NONE) {
-            int channels = 0, idx = -1;
-            for (i = 0; i < nb_input_streams; i++) {
-                ist = input_streams[i];
-                if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
-                    ist->st->codec->channels > channels) {
-                    channels = ist->st->codec->channels;
-                    idx = i;
-                }
-            }
-            NEW_STREAM(audio, idx);
-        }
-
-        /* subtitles: pick first */
-        if (!o->subtitle_disable && oc->oformat->subtitle_codec != AV_CODEC_ID_NONE) {
-            for (i = 0; i < nb_input_streams; i++)
-                if (input_streams[i]->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
-                    NEW_STREAM(subtitle, i);
-                    break;
-                }
-        }
-        /* do something with data? */
-    } else {
-        for (i = 0; i < o->nb_stream_maps; i++) {
-            StreamMap *map = &o->stream_maps[i];
-
-            if (map->disabled)
-                continue;
-
-            if (map->linklabel) {
-                FilterGraph *fg;
-                OutputFilter *ofilter = NULL;
-                int j, k;
-
-                for (j = 0; j < nb_filtergraphs; j++) {
-                    fg = filtergraphs[j];
-                    for (k = 0; k < fg->nb_outputs; k++) {
-                        AVFilterInOut *out = fg->outputs[k]->out_tmp;
-                        if (out && !strcmp(out->name, map->linklabel)) {
-                            ofilter = fg->outputs[k];
-                            goto loop_end;
-                        }
-                    }
-                }
-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);
-                    exit(1);
-                }
-                init_output_filter(ofilter, o, oc);
-            } else {
-                ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];
-                switch (ist->st->codec->codec_type) {
-                case AVMEDIA_TYPE_VIDEO:    ost = new_video_stream(o, oc);    break;
-                case AVMEDIA_TYPE_AUDIO:    ost = new_audio_stream(o, oc);    break;
-                case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(o, oc); break;
-                case AVMEDIA_TYPE_DATA:     ost = new_data_stream(o, oc);     break;
-                case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc); break;
-                default:
-                    av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
-                           map->file_index, map->stream_index);
-                    exit(1);
-                }
-
-                ost->source_index = input_files[map->file_index]->ist_index + map->stream_index;
-                ost->sync_ist     = input_streams[input_files[map->sync_file_index]->ist_index +
-                                               map->sync_stream_index];
-                ist->discard = 0;
-                ist->st->discard = AVDISCARD_NONE;
-            }
-        }
-    }
-
-    /* handle attached files */
-    for (i = 0; i < o->nb_attachments; i++) {
-        AVIOContext *pb;
-        uint8_t *attachment;
-        const char *p;
-        int64_t len;
-
-        if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
-            av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
-                   o->attachments[i]);
-            exit(1);
-        }
-        if ((len = avio_size(pb)) <= 0) {
-            av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
-                   o->attachments[i]);
-            exit(1);
-        }
-        if (!(attachment = av_malloc(len))) {
-            av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n",
-                   o->attachments[i]);
-            exit(1);
-        }
-        avio_read(pb, attachment, len);
-
-        ost = new_attachment_stream(o, oc);
-        ost->stream_copy               = 0;
-        ost->source_index              = -1;
-        ost->attachment_filename       = o->attachments[i];
-        ost->st->codec->extradata      = attachment;
-        ost->st->codec->extradata_size = len;
-
-        p = strrchr(o->attachments[i], '/');
-        av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
-        avio_close(pb);
-    }
-
-    output_files = grow_array(output_files, sizeof(*output_files), &nb_output_files, nb_output_files + 1);
-    if (!(output_files[nb_output_files - 1] = av_mallocz(sizeof(*output_files[0]))))
-        exit(1);
-
-    output_files[nb_output_files - 1]->ctx            = oc;
-    output_files[nb_output_files - 1]->ost_index      = nb_output_streams - oc->nb_streams;
-    output_files[nb_output_files - 1]->recording_time = o->recording_time;
-    if (o->recording_time != INT64_MAX)
-        oc->duration = o->recording_time;
-    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);
-
-    /* check filename in case of an image number is expected */
-    if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
-        if (!av_filename_number_test(oc->filename)) {
-            print_error(oc->filename, AVERROR(EINVAL));
-            exit(1);
-        }
-    }
-
-    if (!(oc->oformat->flags & AVFMT_NOFILE)) {
-        /* test if it already exists to avoid losing precious files */
-        assert_file_overwrite(filename);
-
-        /* open the file */
-        if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
-                              &oc->interrupt_callback,
-                              &output_files[nb_output_files - 1]->opts)) < 0) {
-            print_error(filename, err);
-            exit(1);
-        }
-    }
-
-    if (o->mux_preload) {
-        uint8_t buf[64];
-        snprintf(buf, sizeof(buf), "%d", (int)(o->mux_preload*AV_TIME_BASE));
-        av_dict_set(&output_files[nb_output_files - 1]->opts, "preload", buf, 0);
-    }
-    oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
-    oc->flags |= AVFMT_FLAG_NONBLOCK;
-
-    /* copy metadata */
-    for (i = 0; i < o->nb_metadata_map; i++) {
-        char *p;
-        int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);
-
-        if (in_file_index < 0)
-            continue;
-        if (in_file_index >= nb_input_files) {
-            av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index);
-            exit(1);
-        }
-        copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc, input_files[in_file_index]->ctx, o);
-    }
-
-    /* copy chapters */
-    if (o->chapters_input_file >= nb_input_files) {
-        if (o->chapters_input_file == INT_MAX) {
-            /* copy chapters from the first input file that has them*/
-            o->chapters_input_file = -1;
-            for (i = 0; i < nb_input_files; i++)
-                if (input_files[i]->ctx->nb_chapters) {
-                    o->chapters_input_file = i;
-                    break;
-                }
-        } else {
-            av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
-                   o->chapters_input_file);
-            exit(1);
-        }
-    }
-    if (o->chapters_input_file >= 0)
-        copy_chapters(input_files[o->chapters_input_file], output_files[nb_output_files - 1],
-                      !o->metadata_chapters_manual);
-
-    /* copy global metadata by default */
-    if (!o->metadata_global_manual && nb_input_files)
-        av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,
-                     AV_DICT_DONT_OVERWRITE);
-    if (!o->metadata_streams_manual)
-        for (i = output_files[nb_output_files - 1]->ost_index; i < nb_output_streams; i++) {
-            InputStream *ist;
-            if (output_streams[i]->source_index < 0)         /* this is true e.g. for attached files */
-                continue;
-            ist = input_streams[output_streams[i]->source_index];
-            av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
-        }
-
-    /* process manually set metadata */
-    for (i = 0; i < o->nb_metadata; i++) {
-        AVDictionary **m;
-        char type, *val;
-        const char *stream_spec;
-        int index = 0, j, ret;
-
-        val = strchr(o->metadata[i].u.str, '=');
-        if (!val) {
-            av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
-                   o->metadata[i].u.str);
-            exit(1);
-        }
-        *val++ = 0;
-
-        parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec);
-        if (type == 's') {
-            for (j = 0; j < oc->nb_streams; j++) {
-                if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
-                    av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
-                } else if (ret < 0)
-                    exit(1);
-            }
-        }
-        else {
-            switch (type) {
-            case 'g':
-                m = &oc->metadata;
-                break;
-            case 'c':
-                if (index < 0 || index >= oc->nb_chapters) {
-                    av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
-                    exit(1);
-                }
-                m = &oc->chapters[index]->metadata;
-                break;
-            default:
-                av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
-                exit(1);
-            }
-            av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
-        }
-    }
-
-    reset_options(o);
-}
-
-static int opt_target(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
-    static const char *const frame_rates[] = { "25", "30000/1001", "24000/1001" };
-
-    if (!strncmp(arg, "pal-", 4)) {
-        norm = PAL;
-        arg += 4;
-    } else if (!strncmp(arg, "ntsc-", 5)) {
-        norm = NTSC;
-        arg += 5;
-    } else if (!strncmp(arg, "film-", 5)) {
-        norm = FILM;
-        arg += 5;
-    } else {
-        /* Try to determine PAL/NTSC by peeking in the input files */
-        if (nb_input_files) {
-            int i, j, fr;
-            for (j = 0; j < nb_input_files; j++) {
-                for (i = 0; i < input_files[j]->nb_streams; i++) {
-                    AVCodecContext *c = input_files[j]->ctx->streams[i]->codec;
-                    if (c->codec_type != AVMEDIA_TYPE_VIDEO)
-                        continue;
-                    fr = c->time_base.den * 1000 / c->time_base.num;
-                    if (fr == 25000) {
-                        norm = PAL;
-                        break;
-                    } else if ((fr == 29970) || (fr == 23976)) {
-                        norm = NTSC;
-                        break;
-                    }
-                }
-                if (norm != UNKNOWN)
-                    break;
-            }
-        }
-        if (norm != UNKNOWN)
-            av_log(NULL, AV_LOG_INFO, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
-    }
-
-    if (norm == UNKNOWN) {
-        av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
-        av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
-        av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n");
-        exit(1);
-    }
-
-    if (!strcmp(arg, "vcd")) {
-        opt_video_codec(o, "c:v", "mpeg1video");
-        opt_audio_codec(o, "c:a", "mp2");
-        parse_option(o, "f", "vcd", options);
-
-        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");
-
-        opt_default(NULL, "b", "1150000");
-        opt_default(NULL, "maxrate", "1150000");
-        opt_default(NULL, "minrate", "1150000");
-        opt_default(NULL, "bufsize", "327680"); // 40*1024*8;
-
-        opt_default(NULL, "b:a", "224000");
-        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;
-
-        /* 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
-           and the first pack from the other stream, respectively, may also have
-           been written before.
-           So the real data starts at SCR 36000+3*1200. */
-        o->mux_preload = (36000 + 3 * 1200) / 90000.0; // 0.44
-    } else if (!strcmp(arg, "svcd")) {
-
-        opt_video_codec(o, "c:v", "mpeg2video");
-        opt_audio_codec(o, "c:a", "mp2");
-        parse_option(o, "f", "svcd", options);
-
-        parse_option(o, "s", norm == PAL ? "480x576" : "480x480", options);
-        parse_option(o, "r", frame_rates[norm], options);
-        opt_default(NULL, "g", norm == PAL ? "15" : "18");
-
-        opt_default(NULL, "b", "2040000");
-        opt_default(NULL, "maxrate", "2516000");
-        opt_default(NULL, "minrate", "0"); // 1145000;
-        opt_default(NULL, "bufsize", "1835008"); // 224*1024*8;
-        opt_default(NULL, "flags", "+scan_offset");
-
-
-        opt_default(NULL, "b:a", "224000");
-        parse_option(o, "ar", "44100", options);
-
-        opt_default(NULL, "packetsize", "2324");
-
-    } else if (!strcmp(arg, "dvd")) {
-
-        opt_video_codec(o, "c:v", "mpeg2video");
-        opt_audio_codec(o, "c:a", "ac3");
-        parse_option(o, "f", "dvd", options);
-
-        parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
-        parse_option(o, "r", frame_rates[norm], options);
-        opt_default(NULL, "g", norm == PAL ? "15" : "18");
-
-        opt_default(NULL, "b", "6000000");
-        opt_default(NULL, "maxrate", "9000000");
-        opt_default(NULL, "minrate", "0"); // 1500000;
-        opt_default(NULL, "bufsize", "1835008"); // 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
-
-        opt_default(NULL, "b:a", "448000");
-        parse_option(o, "ar", "48000", options);
-
-    } else if (!strncmp(arg, "dv", 2)) {
-
-        parse_option(o, "f", "dv", options);
-
-        parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
-        parse_option(o, "pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
-                          norm == PAL ? "yuv420p" : "yuv411p", options);
-        parse_option(o, "r", frame_rates[norm], options);
-
-        parse_option(o, "ar", "48000", options);
-        parse_option(o, "ac", "2", options);
-
-    } else {
-        av_log(NULL, AV_LOG_ERROR, "Unknown target: %s\n", arg);
-        return AVERROR(EINVAL);
-    }
-    return 0;
-}
-
-static int opt_vstats_file(void *optctx, const char *opt, const char *arg)
-{
-    av_free (vstats_filename);
-    vstats_filename = av_strdup (arg);
-    return 0;
-}
-
-static int opt_vstats(void *optctx, const char *opt, const char *arg)
-{
-    char filename[40];
-    time_t today2 = time(NULL);
-    struct tm *today = localtime(&today2);
-
-    snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
-             today->tm_sec);
-    return opt_vstats_file(NULL, opt, filename);
-}
-
-static int opt_video_frames(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    return parse_option(o, "frames:v", arg, options);
-}
-
-static int opt_audio_frames(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    return parse_option(o, "frames:a", arg, options);
-}
-
-static int opt_data_frames(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    return parse_option(o, "frames:d", arg, options);
-}
-
-static int opt_video_tag(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    return parse_option(o, "tag:v", arg, options);
-}
-
-static int opt_audio_tag(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    return parse_option(o, "tag:a", arg, options);
-}
-
-static int opt_subtitle_tag(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    return parse_option(o, "tag:s", arg, options);
-}
-
-static int opt_video_filters(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    return parse_option(o, "filter:v", arg, options);
-}
-
-static int opt_audio_filters(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    return parse_option(o, "filter:a", arg, options);
-}
-
-static int opt_vsync(void *optctx, const char *opt, const char *arg)
-{
-    if      (!av_strcasecmp(arg, "cfr"))         video_sync_method = VSYNC_CFR;
-    else if (!av_strcasecmp(arg, "vfr"))         video_sync_method = VSYNC_VFR;
-    else if (!av_strcasecmp(arg, "passthrough")) video_sync_method = VSYNC_PASSTHROUGH;
-
-    if (video_sync_method == VSYNC_AUTO)
-        video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR);
-    return 0;
-}
-
-static int opt_deinterlace(void *optctx, const char *opt, const char *arg)
-{
-    av_log(NULL, AV_LOG_WARNING, "-%s is deprecated, use -filter:v yadif instead\n", opt);
-    do_deinterlace = 1;
-    return 0;
-}
-
-int opt_cpuflags(void *optctx, const char *opt, const char *arg)
-{
-    int flags = av_parse_cpu_flags(arg);
-
-    if (flags < 0)
-        return flags;
-
-    av_set_cpu_flags_mask(flags);
-    return 0;
-}
-
-static int opt_channel_layout(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    char layout_str[32];
-    char *stream_str;
-    char *ac_str;
-    int ret, channels, ac_str_size;
-    uint64_t layout;
-
-    layout = av_get_channel_layout(arg);
-    if (!layout) {
-        av_log(NULL, AV_LOG_ERROR, "Unknown channel layout: %s\n", arg);
-        return AVERROR(EINVAL);
-    }
-    snprintf(layout_str, sizeof(layout_str), "%"PRIu64, layout);
-    ret = opt_default(NULL, opt, layout_str);
-    if (ret < 0)
-        return ret;
-
-    /* set 'ac' option based on channel layout */
-    channels = av_get_channel_layout_nb_channels(layout);
-    snprintf(layout_str, sizeof(layout_str), "%d", channels);
-    stream_str = strchr(opt, ':');
-    ac_str_size = 3 + (stream_str ? strlen(stream_str) : 0);
-    ac_str = av_mallocz(ac_str_size);
-    if (!ac_str)
-        return AVERROR(ENOMEM);
-    av_strlcpy(ac_str, "ac", 3);
-    if (stream_str)
-        av_strlcat(ac_str, stream_str, ac_str_size);
-    ret = parse_option(o, ac_str, layout_str, options);
-    av_free(ac_str);
-
-    return ret;
-}
-
-static int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
-{
-    OptionsContext *o = optctx;
-    return parse_option(o, "q:a", arg, options);
-}
-
-static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
-{
-    filtergraphs = grow_array(filtergraphs, sizeof(*filtergraphs),
-                              &nb_filtergraphs, nb_filtergraphs + 1);
-    if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
-        return AVERROR(ENOMEM);
-    filtergraphs[nb_filtergraphs - 1]->index       = nb_filtergraphs - 1;
-    filtergraphs[nb_filtergraphs - 1]->graph_desc = arg;
-    return 0;
-}
-
-void show_help_default(const char *opt, const char *arg)
-{
-    /* per-file options have at least one of those set */
-    const int per_file = OPT_SPEC | OPT_OFFSET | OPT_PERFILE;
-    int show_advanced = 0, show_avoptions = 0;
-
-    if (opt && *opt) {
-        if (!strcmp(opt, "long"))
-            show_advanced = 1;
-        else if (!strcmp(opt, "full"))
-            show_advanced = show_avoptions = 1;
-        else
-            av_log(NULL, AV_LOG_ERROR, "Unknown help option '%s'.\n", opt);
-    }
-
-    show_usage();
-
-    printf("Getting help:\n"
-           "    -h      -- print basic options\n"
-           "    -h long -- print more options\n"
-           "    -h full -- print all options (including all format and codec specific options, very long)\n"
-           "    See man %s for detailed description of the options.\n"
-           "\n", program_name);
-
-    show_help_options(options, "Print help / information / capabilities:",
-                      OPT_EXIT, 0, 0);
-
-    show_help_options(options, "Global options (affect whole program "
-                      "instead of just one file:",
-                      0, per_file | OPT_EXIT | OPT_EXPERT, 0);
-    if (show_advanced)
-        show_help_options(options, "Advanced global options:", OPT_EXPERT,
-                          per_file | OPT_EXIT, 0);
-
-    show_help_options(options, "Per-file main options:", 0,
-                      OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE |
-                      OPT_EXIT, per_file);
-    if (show_advanced)
-        show_help_options(options, "Advanced per-file options:",
-                          OPT_EXPERT, OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE, per_file);
-
-    show_help_options(options, "Video options:",
-                      OPT_VIDEO, OPT_EXPERT | OPT_AUDIO, 0);
-    if (show_advanced)
-        show_help_options(options, "Advanced Video options:",
-                          OPT_EXPERT | OPT_VIDEO, OPT_AUDIO, 0);
-
-    show_help_options(options, "Audio options:",
-                      OPT_AUDIO, OPT_EXPERT | OPT_VIDEO, 0);
-    if (show_advanced)
-        show_help_options(options, "Advanced Audio options:",
-                          OPT_EXPERT | OPT_AUDIO, OPT_VIDEO, 0);
-    show_help_options(options, "Subtitle options:",
-                      OPT_SUBTITLE, 0, 0);
-    printf("\n");
-
-    if (show_avoptions) {
-        int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
-        show_help_children(avcodec_get_class(), flags);
-        show_help_children(avformat_get_class(), flags);
-        show_help_children(sws_get_class(), flags);
-    }
-}
-
-void show_usage(void)
-{
-    printf("Hyper fast Audio and Video encoder\n");
-    printf("usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name);
-    printf("\n");
-}
-
-
-#define OFFSET(x) offsetof(OptionsContext, x)
-const OptionDef options[] = {
-    /* main options */
-#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" },
-    { "c",              HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(codec_names) },
-        "codec name", "codec" },
-    { "codec",          HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(codec_names) },
-        "codec name", "codec" },
-    { "pre",            HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(presets) },
-        "preset name", "preset" },
-    { "map",            HAS_ARG | OPT_EXPERT | OPT_PERFILE,          { .func_arg = opt_map },
-        "set input stream mapping",
-        "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" },
-    { "map_metadata",   HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(metadata_map) },
-        "set metadata information of outfile from infile",
-        "outfile[,metadata]:infile[,metadata]" },
-    { "map_chapters",   HAS_ARG | OPT_INT | OPT_EXPERT | OPT_OFFSET, { .off = OFFSET(chapters_input_file) },
-        "set chapters mapping", "input_file_index" },
-    { "t",              HAS_ARG | OPT_TIME | OPT_OFFSET,             { .off = OFFSET(recording_time) },
-        "record or transcode \"duration\" seconds of audio/video",
-        "duration" },
-    { "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) },
-        "set the start time offset", "time_off" },
-    { "itsoffset",      HAS_ARG | OPT_TIME | OPT_OFFSET | OPT_EXPERT,{ .off = OFFSET(input_ts_offset) },
-        "set the input ts offset", "time_off" },
-    { "itsscale",       HAS_ARG | OPT_DOUBLE | OPT_SPEC | OPT_EXPERT,{ .off = OFFSET(ts_scale) },
-        "set the input ts scale", "scale" },
-    { "metadata",       HAS_ARG | OPT_STRING | OPT_SPEC,             { .off = OFFSET(metadata) },
-        "add metadata", "string=string" },
-    { "dframes",        HAS_ARG | OPT_PERFILE | OPT_EXPERT,          { .func_arg = opt_data_frames },
-        "set the number of data frames to record", "number" },
-    { "benchmark",      OPT_BOOL | OPT_EXPERT,                       { &do_benchmark },
-        "add timings for benchmarking" },
-    { "timelimit",      HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_timelimit },
-        "set max runtime in seconds", "limit" },
-    { "dump",           OPT_BOOL | OPT_EXPERT,                       { &do_pkt_dump },
-        "dump each input packet" },
-    { "hex",            OPT_BOOL | OPT_EXPERT,                       { &do_hex_dump },
-        "when dumping packets, also dump the payload" },
-    { "re",             OPT_BOOL | OPT_EXPERT | OPT_OFFSET,          { .off = OFFSET(rate_emu) },
-        "read input at native frame rate", "" },
-    { "target",         HAS_ARG | OPT_PERFILE,                       { .func_arg = opt_target },
-        "specify target file type (\"vcd\", \"svcd\", \"dvd\","
-        " \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
-    { "vsync",          HAS_ARG | OPT_EXPERT,                        { opt_vsync },
-        "video sync method", "" },
-    { "async",          HAS_ARG | OPT_INT | OPT_EXPERT,              { &audio_sync_method },
-        "audio sync method", "" },
-    { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,          { &audio_drift_threshold },
-        "audio drift threshold", "threshold" },
-    { "copyts",         OPT_BOOL | OPT_EXPERT,                       { &copy_ts },
-        "copy timestamps" },
-    { "copytb",         OPT_BOOL | OPT_EXPERT,                       { &copy_tb },
-        "copy input stream time base when stream copying" },
-    { "shortest",       OPT_BOOL | OPT_EXPERT | OPT_OFFSET,          { .off = OFFSET(shortest) },
-        "finish encoding within shortest input" },
-    { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,       { &dts_delta_threshold },
-        "timestamp discontinuity delta threshold", "threshold" },
-    { "xerror",         OPT_BOOL | OPT_EXPERT,                       { &exit_on_error },
-        "exit on error", "error" },
-    { "copyinkf",       OPT_BOOL | OPT_EXPERT | OPT_SPEC,            { .off = OFFSET(copy_initial_nonkeyframes) },
-        "copy initial non-keyframes" },
-    { "frames",         OPT_INT64 | HAS_ARG | OPT_SPEC,              { .off = OFFSET(max_frames) },
-        "set the number of frames to record", "number" },
-    { "tag",            OPT_STRING | HAS_ARG | OPT_SPEC | OPT_EXPERT,{ .off = OFFSET(codec_tags) },
-        "force codec tag/fourcc", "fourcc/tag" },
-    { "q",              HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC,{ .off = OFFSET(qscale) },
-        "use fixed quality scale (VBR)", "q" },
-    { "qscale",         HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC,{ .off = OFFSET(qscale) },
-        "use fixed quality scale (VBR)", "q" },
-    { "filter",         HAS_ARG | OPT_STRING | OPT_SPEC,             { .off = OFFSET(filters) },
-        "set stream filterchain", "filter_list" },
-    { "filter_complex", HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_filter_complex },
-        "create a complex filtergraph", "graph_description" },
-    { "stats",          OPT_BOOL,                                    { &print_stats },
-        "print progress report during encoding", },
-    { "attach",         HAS_ARG | OPT_PERFILE | OPT_EXPERT,          { .func_arg = opt_attach },
-        "add an attachment to the output file", "filename" },
-    { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC |OPT_EXPERT,{ .off = OFFSET(dump_attachment) },
-        "extract an attachment into a file", "filename" },
-    { "cpuflags",       HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_cpuflags },
-        "set CPU flags mask", "mask" },
-
-    /* video options */
-    { "vframes",      OPT_VIDEO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_video_frames },
-        "set the number of video frames to record", "number" },
-    { "r",            OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC,              { .off = OFFSET(frame_rates) },
-        "set frame rate (Hz value, fraction or abbreviation)", "rate" },
-    { "s",            OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC,              { .off = OFFSET(frame_sizes) },
-        "set frame size (WxH or abbreviation)", "size" },
-    { "aspect",       OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC,              { .off = OFFSET(frame_aspect_ratios) },
-        "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
-    { "pix_fmt",      OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC, { .off = OFFSET(frame_pix_fmts) },
-        "set pixel format", "format" },
-    { "vn",           OPT_VIDEO | OPT_BOOL  | OPT_OFFSET,                        { .off = OFFSET(video_disable) },
-        "disable video" },
-    { "vdt",          OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT ,               { &video_discard },
-        "discard threshold", "n" },
-    { "rc_override",  OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC, { .off = OFFSET(rc_overrides) },
-        "rate control override for specific intervals", "override" },
-    { "vcodec",       OPT_VIDEO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_video_codec },
-        "force video codec ('copy' to copy stream)", "codec" },
-    { "pass",         OPT_VIDEO | HAS_ARG | OPT_SPEC | OPT_INT,                  { .off = OFFSET(pass) },
-        "select the pass number (1 or 2)", "n" },
-    { "passlogfile",  OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC,  { .off = OFFSET(passlogfiles) },
-        "select two pass log file name prefix", "prefix" },
-    { "deinterlace",  OPT_VIDEO | OPT_EXPERT ,                                   { .func_arg = opt_deinterlace },
-        "this option is deprecated, use the yadif filter instead" },
-    { "vstats",       OPT_VIDEO | OPT_EXPERT ,                                   { &opt_vstats },
-        "dump video coding statistics to file" },
-    { "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" },
-    { "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) },
-        "specify inter matrix coeffs", "matrix" },
-    { "top",          OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_INT| OPT_SPEC,     { .off = OFFSET(top_field_first) },
-        "top=1/bottom=0/auto=-1 field first", "" },
-    { "dc",           OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT ,               { &intra_dc_precision },
-        "intra_dc_precision", "precision" },
-    { "vtag",         OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_PERFILE,           { .func_arg = opt_video_tag },
-        "force video tag/fourcc", "fourcc/tag" },
-    { "qphist",       OPT_VIDEO | OPT_BOOL | OPT_EXPERT ,                        { &qp_hist },
-        "show QP histogram" },
-    { "force_fps",    OPT_VIDEO | OPT_BOOL | OPT_EXPERT  | OPT_SPEC,             { .off = OFFSET(force_fps) },
-        "force the selected framerate, disable the best supported framerate selection" },
-    { "streamid",     OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE,            { .func_arg = opt_streamid },
-        "set the value of an outfile streamid", "streamIndex:value" },
-    { "force_key_frames", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT  | OPT_SPEC,
-        { .off = OFFSET(forced_key_frames) }, "force key frames at specified timestamps", "timestamps" },
-
-    /* audio options */
-    { "aframes",        OPT_AUDIO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_audio_frames },
-        "set the number of audio frames to record", "number" },
-    { "aq",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_audio_qscale },
-        "set audio quality (codec-specific)", "quality", },
-    { "ar",             OPT_AUDIO | HAS_ARG  | OPT_INT | OPT_SPEC,                 { .off = OFFSET(audio_sample_rate) },
-        "set audio sampling rate (in Hz)", "rate" },
-    { "ac",             OPT_AUDIO | HAS_ARG  | OPT_INT | OPT_SPEC,                 { .off = OFFSET(audio_channels) },
-        "set number of audio channels", "channels" },
-    { "an",             OPT_AUDIO | OPT_BOOL | OPT_OFFSET,                         { .off = OFFSET(audio_disable) },
-        "disable audio" },
-    { "acodec",         OPT_AUDIO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_audio_codec },
-        "force audio codec ('copy' to copy stream)", "codec" },
-    { "atag",           OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE,           { .func_arg = opt_audio_tag },
-        "force audio tag/fourcc", "fourcc/tag" },
-    { "vol",            OPT_AUDIO | HAS_ARG  | OPT_INT,                            { &audio_volume },
-        "change audio volume (256=normal)" , "volume" },
-    { "sample_fmt",     OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_SPEC | OPT_STRING, { .off = OFFSET(sample_fmts) },
-        "set sample format", "format" },
-    { "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" },
-
-    /* subtitle options */
-    { "sn",     OPT_SUBTITLE | OPT_BOOL | OPT_OFFSET, { .off = OFFSET(subtitle_disable) },
-        "disable subtitle" },
-    { "scodec", OPT_SUBTITLE | HAS_ARG  | OPT_PERFILE, { .func_arg = opt_subtitle_codec },
-        "force subtitle codec ('copy' to copy stream)", "codec" },
-    { "stag",   OPT_SUBTITLE | HAS_ARG  | OPT_EXPERT  | OPT_PERFILE, { .func_arg = opt_subtitle_tag }
-        , "force subtitle tag/fourcc", "fourcc/tag" },
-
-    /* grab options */
-    { "isync", OPT_BOOL | OPT_EXPERT, { &input_sync }, "this option is deprecated and does nothing", "" },
-
-    /* muxer options */
-    { "muxdelay",   OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET, { .off = OFFSET(mux_max_delay) },
-        "set the maximum demux-decode delay", "seconds" },
-    { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET, { .off = OFFSET(mux_preload) },
-        "set the initial demux-decode delay", "seconds" },
-
-    { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT, { .off = OFFSET(bitstream_filters) },
-        "A comma-separated list of bitstream filters", "bitstream_filters" },
-
-    /* data codec support */
-    { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT, { .func_arg = opt_data_codec },
-        "force data codec ('copy' to copy stream)", "codec" },
-
-    { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { .func_arg = opt_default },
-        "generic catch all option", "" },
-    { NULL, },
-};
diff --git a/avplay.c b/avplay.c
deleted file mode 100644
index 597b23c..0000000
--- a/avplay.c
+++ /dev/null
@@ -1,3019 +0,0 @@
-/*
- * avplay : Simple Media Player based on the Libav libraries
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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
- */
-
-#include "config.h"
-#include <inttypes.h>
-#include <math.h>
-#include <limits.h>
-#include "libavutil/avstring.h"
-#include "libavutil/colorspace.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/pixdesc.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/dict.h"
-#include "libavutil/parseutils.h"
-#include "libavutil/samplefmt.h"
-#include "libavutil/time.h"
-#include "libavformat/avformat.h"
-#include "libavdevice/avdevice.h"
-#include "libswscale/swscale.h"
-#include "libavresample/avresample.h"
-#include "libavutil/opt.h"
-#include "libavcodec/avfft.h"
-
-#if CONFIG_AVFILTER
-# include "libavfilter/avfilter.h"
-# include "libavfilter/avfiltergraph.h"
-# include "libavfilter/buffersink.h"
-# include "libavfilter/buffersrc.h"
-#endif
-
-#include "cmdutils.h"
-
-#include <SDL.h>
-#include <SDL_thread.h>
-
-#ifdef __MINGW32__
-#undef main /* We don't want SDL to override our main() */
-#endif
-
-#include <assert.h>
-
-const char program_name[] = "avplay";
-const int program_birth_year = 2003;
-
-#define MAX_QUEUE_SIZE (15 * 1024 * 1024)
-#define MIN_AUDIOQ_SIZE (20 * 16 * 1024)
-#define MIN_FRAMES 5
-
-/* SDL audio buffer size, in samples. Should be small to have precise
-   A/V sync as SDL does not have hardware buffer fullness info. */
-#define SDL_AUDIO_BUFFER_SIZE 1024
-
-/* no AV sync correction is done if below the AV sync threshold */
-#define AV_SYNC_THRESHOLD 0.01
-/* no AV correction is done if too big error */
-#define AV_NOSYNC_THRESHOLD 10.0
-
-#define FRAME_SKIP_FACTOR 0.05
-
-/* maximum audio speed change to get correct sync */
-#define SAMPLE_CORRECTION_PERCENT_MAX 10
-
-/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
-#define AUDIO_DIFF_AVG_NB   20
-
-/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
-#define SAMPLE_ARRAY_SIZE (2 * 65536)
-
-static int sws_flags = SWS_BICUBIC;
-
-typedef struct PacketQueue {
-    AVPacketList *first_pkt, *last_pkt;
-    int nb_packets;
-    int size;
-    int abort_request;
-    SDL_mutex *mutex;
-    SDL_cond *cond;
-} PacketQueue;
-
-#define VIDEO_PICTURE_QUEUE_SIZE 2
-#define SUBPICTURE_QUEUE_SIZE 4
-
-typedef struct VideoPicture {
-    double pts;             // presentation timestamp for this picture
-    double target_clock;    // av_gettime() time at which this should be displayed ideally
-    int64_t pos;            // byte position in file
-    SDL_Overlay *bmp;
-    int width, height; /* source height & width */
-    int allocated;
-    int reallocate;
-    enum AVPixelFormat pix_fmt;
-
-#if CONFIG_AVFILTER
-    AVFilterBufferRef *picref;
-#endif
-} VideoPicture;
-
-typedef struct SubPicture {
-    double pts; /* presentation time stamp for this picture */
-    AVSubtitle sub;
-} SubPicture;
-
-enum {
-    AV_SYNC_AUDIO_MASTER, /* default choice */
-    AV_SYNC_VIDEO_MASTER,
-    AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
-};
-
-typedef struct VideoState {
-    SDL_Thread *parse_tid;
-    SDL_Thread *video_tid;
-    SDL_Thread *refresh_tid;
-    AVInputFormat *iformat;
-    int no_background;
-    int abort_request;
-    int paused;
-    int last_paused;
-    int seek_req;
-    int seek_flags;
-    int64_t seek_pos;
-    int64_t seek_rel;
-    int read_pause_return;
-    AVFormatContext *ic;
-
-    int audio_stream;
-
-    int av_sync_type;
-    double external_clock; /* external clock base */
-    int64_t external_clock_time;
-
-    double audio_clock;
-    double audio_diff_cum; /* used for AV difference average computation */
-    double audio_diff_avg_coef;
-    double audio_diff_threshold;
-    int audio_diff_avg_count;
-    AVStream *audio_st;
-    PacketQueue audioq;
-    int audio_hw_buf_size;
-    uint8_t silence_buf[SDL_AUDIO_BUFFER_SIZE];
-    uint8_t *audio_buf;
-    uint8_t *audio_buf1;
-    unsigned int audio_buf_size; /* in bytes */
-    int audio_buf_index; /* in bytes */
-    AVPacket audio_pkt_temp;
-    AVPacket audio_pkt;
-    enum AVSampleFormat sdl_sample_fmt;
-    uint64_t sdl_channel_layout;
-    int sdl_channels;
-    enum AVSampleFormat resample_sample_fmt;
-    uint64_t resample_channel_layout;
-    AVAudioResampleContext *avr;
-    AVFrame *frame;
-
-    int show_audio; /* if true, display audio samples */
-    int16_t sample_array[SAMPLE_ARRAY_SIZE];
-    int sample_array_index;
-    int last_i_start;
-    RDFTContext *rdft;
-    int rdft_bits;
-    FFTSample *rdft_data;
-    int xpos;
-
-    SDL_Thread *subtitle_tid;
-    int subtitle_stream;
-    int subtitle_stream_changed;
-    AVStream *subtitle_st;
-    PacketQueue subtitleq;
-    SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
-    int subpq_size, subpq_rindex, subpq_windex;
-    SDL_mutex *subpq_mutex;
-    SDL_cond *subpq_cond;
-
-    double frame_timer;
-    double frame_last_pts;
-    double frame_last_delay;
-    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_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
-    VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
-    int pictq_size, pictq_rindex, pictq_windex;
-    SDL_mutex *pictq_mutex;
-    SDL_cond *pictq_cond;
-#if !CONFIG_AVFILTER
-    struct SwsContext *img_convert_ctx;
-#endif
-
-    //    QETimer *video_timer;
-    char filename[1024];
-    int width, height, xleft, ytop;
-
-    PtsCorrectionContext pts_ctx;
-
-#if CONFIG_AVFILTER
-    AVFilterContext *in_video_filter;   // the first filter in the video chain
-    AVFilterContext *out_video_filter;  // the last filter in the video chain
-    int use_dr1;
-    FrameBuffer *buffer_pool;
-#endif
-
-    float skip_frames;
-    float skip_frames_index;
-    int refresh;
-} VideoState;
-
-/* options specified by the user */
-static AVInputFormat *file_iformat;
-static const char *input_filename;
-static const char *window_title;
-static int fs_screen_width;
-static int fs_screen_height;
-static int screen_width  = 0;
-static int screen_height = 0;
-static int audio_disable;
-static int video_disable;
-static int wanted_stream[AVMEDIA_TYPE_NB] = {
-    [AVMEDIA_TYPE_AUDIO]    = -1,
-    [AVMEDIA_TYPE_VIDEO]    = -1,
-    [AVMEDIA_TYPE_SUBTITLE] = -1,
-};
-static int seek_by_bytes = -1;
-static int display_disable;
-static int show_status = 1;
-static int av_sync_type = AV_SYNC_AUDIO_MASTER;
-static int64_t start_time = AV_NOPTS_VALUE;
-static int64_t duration = AV_NOPTS_VALUE;
-static int debug = 0;
-static int debug_mv = 0;
-static int step = 0;
-static int workaround_bugs = 1;
-static int fast = 0;
-static int genpts = 0;
-static int idct = FF_IDCT_AUTO;
-static enum AVDiscard skip_frame       = AVDISCARD_DEFAULT;
-static enum AVDiscard skip_idct        = AVDISCARD_DEFAULT;
-static enum AVDiscard skip_loop_filter = AVDISCARD_DEFAULT;
-static int error_concealment = 3;
-static int decoder_reorder_pts = -1;
-static int autoexit;
-static int exit_on_keydown;
-static int exit_on_mousedown;
-static int loop = 1;
-static int framedrop = 1;
-static int infinite_buffer = 0;
-
-static int rdftspeed = 20;
-#if CONFIG_AVFILTER
-static char *vfilters = NULL;
-#endif
-
-/* current context */
-static int is_full_screen;
-static VideoState *cur_stream;
-static int64_t audio_callback_time;
-
-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;
-
-static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
-
-/* packet queue handling */
-static void packet_queue_init(PacketQueue *q)
-{
-    memset(q, 0, sizeof(PacketQueue));
-    q->mutex = SDL_CreateMutex();
-    q->cond = SDL_CreateCond();
-    packet_queue_put(q, &flush_pkt);
-}
-
-static void packet_queue_flush(PacketQueue *q)
-{
-    AVPacketList *pkt, *pkt1;
-
-    SDL_LockMutex(q->mutex);
-    for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
-        pkt1 = pkt->next;
-        av_free_packet(&pkt->pkt);
-        av_freep(&pkt);
-    }
-    q->last_pkt = NULL;
-    q->first_pkt = NULL;
-    q->nb_packets = 0;
-    q->size = 0;
-    SDL_UnlockMutex(q->mutex);
-}
-
-static void packet_queue_end(PacketQueue *q)
-{
-    packet_queue_flush(q);
-    SDL_DestroyMutex(q->mutex);
-    SDL_DestroyCond(q->cond);
-}
-
-static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
-{
-    AVPacketList *pkt1;
-
-    /* duplicate the packet */
-    if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
-        return -1;
-
-    pkt1 = av_malloc(sizeof(AVPacketList));
-    if (!pkt1)
-        return -1;
-    pkt1->pkt = *pkt;
-    pkt1->next = NULL;
-
-
-    SDL_LockMutex(q->mutex);
-
-    if (!q->last_pkt)
-
-        q->first_pkt = pkt1;
-    else
-        q->last_pkt->next = pkt1;
-    q->last_pkt = pkt1;
-    q->nb_packets++;
-    q->size += pkt1->pkt.size + sizeof(*pkt1);
-    /* XXX: should duplicate packet data in DV case */
-    SDL_CondSignal(q->cond);
-
-    SDL_UnlockMutex(q->mutex);
-    return 0;
-}
-
-static void packet_queue_abort(PacketQueue *q)
-{
-    SDL_LockMutex(q->mutex);
-
-    q->abort_request = 1;
-
-    SDL_CondSignal(q->cond);
-
-    SDL_UnlockMutex(q->mutex);
-}
-
-/* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
-static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
-{
-    AVPacketList *pkt1;
-    int ret;
-
-    SDL_LockMutex(q->mutex);
-
-    for (;;) {
-        if (q->abort_request) {
-            ret = -1;
-            break;
-        }
-
-        pkt1 = q->first_pkt;
-        if (pkt1) {
-            q->first_pkt = pkt1->next;
-            if (!q->first_pkt)
-                q->last_pkt = NULL;
-            q->nb_packets--;
-            q->size -= pkt1->pkt.size + sizeof(*pkt1);
-            *pkt = pkt1->pkt;
-            av_free(pkt1);
-            ret = 1;
-            break;
-        } else if (!block) {
-            ret = 0;
-            break;
-        } else {
-            SDL_CondWait(q->cond, q->mutex);
-        }
-    }
-    SDL_UnlockMutex(q->mutex);
-    return ret;
-}
-
-static inline void fill_rectangle(SDL_Surface *screen,
-                                  int x, int y, int w, int h, int color)
-{
-    SDL_Rect rect;
-    rect.x = x;
-    rect.y = y;
-    rect.w = w;
-    rect.h = h;
-    SDL_FillRect(screen, &rect, color);
-}
-
-#define ALPHA_BLEND(a, oldp, newp, s)\
-((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
-
-#define RGBA_IN(r, g, b, a, s)\
-{\
-    unsigned int v = ((const uint32_t *)(s))[0];\
-    a = (v >> 24) & 0xff;\
-    r = (v >> 16) & 0xff;\
-    g = (v >> 8) & 0xff;\
-    b = v & 0xff;\
-}
-
-#define YUVA_IN(y, u, v, a, s, pal)\
-{\
-    unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
-    a = (val >> 24) & 0xff;\
-    y = (val >> 16) & 0xff;\
-    u = (val >> 8) & 0xff;\
-    v = val & 0xff;\
-}
-
-#define YUVA_OUT(d, y, u, v, a)\
-{\
-    ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
-}
-
-
-#define BPP 1
-
-static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
-{
-    int wrap, wrap3, width2, skip2;
-    int y, u, v, a, u1, v1, a1, w, h;
-    uint8_t *lum, *cb, *cr;
-    const uint8_t *p;
-    const uint32_t *pal;
-    int dstx, dsty, dstw, dsth;
-
-    dstw = av_clip(rect->w, 0, imgw);
-    dsth = av_clip(rect->h, 0, imgh);
-    dstx = av_clip(rect->x, 0, imgw - dstw);
-    dsty = av_clip(rect->y, 0, imgh - dsth);
-    lum = dst->data[0] + dsty * dst->linesize[0];
-    cb  = dst->data[1] + (dsty >> 1) * dst->linesize[1];
-    cr  = dst->data[2] + (dsty >> 1) * dst->linesize[2];
-
-    width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
-    skip2 = dstx >> 1;
-    wrap = dst->linesize[0];
-    wrap3 = rect->pict.linesize[0];
-    p = rect->pict.data[0];
-    pal = (const uint32_t *)rect->pict.data[1];  /* Now in YCrCb! */
-
-    if (dsty & 1) {
-        lum += dstx;
-        cb += skip2;
-        cr += skip2;
-
-        if (dstx & 1) {
-            YUVA_IN(y, u, v, a, p, pal);
-            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
-            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
-            cb++;
-            cr++;
-            lum++;
-            p += BPP;
-        }
-        for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
-            YUVA_IN(y, u, v, a, p, pal);
-            u1 = u;
-            v1 = v;
-            a1 = a;
-            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-
-            YUVA_IN(y, u, v, a, p + BPP, pal);
-            u1 += u;
-            v1 += v;
-            a1 += a;
-            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
-            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
-            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
-            cb++;
-            cr++;
-            p += 2 * BPP;
-            lum += 2;
-        }
-        if (w) {
-            YUVA_IN(y, u, v, a, p, pal);
-            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
-            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
-            p++;
-            lum++;
-        }
-        p += wrap3 - dstw * BPP;
-        lum += wrap - dstw - dstx;
-        cb += dst->linesize[1] - width2 - skip2;
-        cr += dst->linesize[2] - width2 - skip2;
-    }
-    for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
-        lum += dstx;
-        cb += skip2;
-        cr += skip2;
-
-        if (dstx & 1) {
-            YUVA_IN(y, u, v, a, p, pal);
-            u1 = u;
-            v1 = v;
-            a1 = a;
-            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-            p += wrap3;
-            lum += wrap;
-            YUVA_IN(y, u, v, a, p, pal);
-            u1 += u;
-            v1 += v;
-            a1 += a;
-            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
-            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
-            cb++;
-            cr++;
-            p += -wrap3 + BPP;
-            lum += -wrap + 1;
-        }
-        for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
-            YUVA_IN(y, u, v, a, p, pal);
-            u1 = u;
-            v1 = v;
-            a1 = a;
-            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-
-            YUVA_IN(y, u, v, a, p + BPP, pal);
-            u1 += u;
-            v1 += v;
-            a1 += a;
-            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
-            p += wrap3;
-            lum += wrap;
-
-            YUVA_IN(y, u, v, a, p, pal);
-            u1 += u;
-            v1 += v;
-            a1 += a;
-            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-
-            YUVA_IN(y, u, v, a, p + BPP, pal);
-            u1 += u;
-            v1 += v;
-            a1 += a;
-            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
-
-            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
-            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
-
-            cb++;
-            cr++;
-            p += -wrap3 + 2 * BPP;
-            lum += -wrap + 2;
-        }
-        if (w) {
-            YUVA_IN(y, u, v, a, p, pal);
-            u1 = u;
-            v1 = v;
-            a1 = a;
-            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-            p += wrap3;
-            lum += wrap;
-            YUVA_IN(y, u, v, a, p, pal);
-            u1 += u;
-            v1 += v;
-            a1 += a;
-            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
-            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
-            cb++;
-            cr++;
-            p += -wrap3 + BPP;
-            lum += -wrap + 1;
-        }
-        p += wrap3 + (wrap3 - dstw * BPP);
-        lum += wrap + (wrap - dstw - dstx);
-        cb += dst->linesize[1] - width2 - skip2;
-        cr += dst->linesize[2] - width2 - skip2;
-    }
-    /* handle odd height */
-    if (h) {
-        lum += dstx;
-        cb += skip2;
-        cr += skip2;
-
-        if (dstx & 1) {
-            YUVA_IN(y, u, v, a, p, pal);
-            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
-            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
-            cb++;
-            cr++;
-            lum++;
-            p += BPP;
-        }
-        for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
-            YUVA_IN(y, u, v, a, p, pal);
-            u1 = u;
-            v1 = v;
-            a1 = a;
-            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-
-            YUVA_IN(y, u, v, a, p + BPP, pal);
-            u1 += u;
-            v1 += v;
-            a1 += a;
-            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
-            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
-            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
-            cb++;
-            cr++;
-            p += 2 * BPP;
-            lum += 2;
-        }
-        if (w) {
-            YUVA_IN(y, u, v, a, p, pal);
-            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
-            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
-            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
-        }
-    }
-}
-
-static void free_subpicture(SubPicture *sp)
-{
-    avsubtitle_free(&sp->sub);
-}
-
-static void video_image_display(VideoState *is)
-{
-    VideoPicture *vp;
-    SubPicture *sp;
-    AVPicture pict;
-    float aspect_ratio;
-    int width, height, x, y;
-    SDL_Rect rect;
-    int i;
-
-    vp = &is->pictq[is->pictq_rindex];
-    if (vp->bmp) {
-#if CONFIG_AVFILTER
-         if (vp->picref->video->pixel_aspect.num == 0)
-             aspect_ratio = 0;
-         else
-             aspect_ratio = av_q2d(vp->picref->video->pixel_aspect);
-#else
-
-        /* XXX: use variable in the frame */
-        if (is->video_st->sample_aspect_ratio.num)
-            aspect_ratio = av_q2d(is->video_st->sample_aspect_ratio);
-        else if (is->video_st->codec->sample_aspect_ratio.num)
-            aspect_ratio = av_q2d(is->video_st->codec->sample_aspect_ratio);
-        else
-            aspect_ratio = 0;
-#endif
-        if (aspect_ratio <= 0.0)
-            aspect_ratio = 1.0;
-        aspect_ratio *= (float)vp->width / (float)vp->height;
-
-        if (is->subtitle_st)
-        {
-            if (is->subpq_size > 0)
-            {
-                sp = &is->subpq[is->subpq_rindex];
-
-                if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000))
-                {
-                    SDL_LockYUVOverlay (vp->bmp);
-
-                    pict.data[0] = vp->bmp->pixels[0];
-                    pict.data[1] = vp->bmp->pixels[2];
-                    pict.data[2] = vp->bmp->pixels[1];
-
-                    pict.linesize[0] = vp->bmp->pitches[0];
-                    pict.linesize[1] = vp->bmp->pitches[2];
-                    pict.linesize[2] = vp->bmp->pitches[1];
-
-                    for (i = 0; i < sp->sub.num_rects; i++)
-                        blend_subrect(&pict, sp->sub.rects[i],
-                                      vp->bmp->w, vp->bmp->h);
-
-                    SDL_UnlockYUVOverlay (vp->bmp);
-                }
-            }
-        }
-
-
-        /* XXX: we suppose the screen has a 1.0 pixel ratio */
-        height = is->height;
-        width = ((int)rint(height * aspect_ratio)) & ~1;
-        if (width > is->width) {
-            width = is->width;
-            height = ((int)rint(width / aspect_ratio)) & ~1;
-        }
-        x = (is->width - width) / 2;
-        y = (is->height - height) / 2;
-        is->no_background = 0;
-        rect.x = is->xleft + x;
-        rect.y = is->ytop  + y;
-        rect.w = width;
-        rect.h = height;
-        SDL_DisplayYUVOverlay(vp->bmp, &rect);
-    }
-}
-
-/* get the current audio output buffer size, in samples. With SDL, we
-   cannot have a precise information */
-static int audio_write_get_buf_size(VideoState *is)
-{
-    return is->audio_buf_size - is->audio_buf_index;
-}
-
-static inline int compute_mod(int a, int b)
-{
-    a = a % b;
-    if (a >= 0)
-        return a;
-    else
-        return a + b;
-}
-
-static void video_audio_display(VideoState *s)
-{
-    int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
-    int ch, channels, h, h2, bgcolor, fgcolor;
-    int16_t time_diff;
-    int rdft_bits, nb_freq;
-
-    for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
-        ;
-    nb_freq = 1 << (rdft_bits - 1);
-
-    /* compute display index : center on currently output samples */
-    channels = s->sdl_channels;
-    nb_display_channels = channels;
-    if (!s->paused) {
-        int data_used = s->show_audio == 1 ? s->width : (2 * nb_freq);
-        n = 2 * channels;
-        delay = audio_write_get_buf_size(s);
-        delay /= n;
-
-        /* to be more precise, we take into account the time spent since
-           the last buffer computation */
-        if (audio_callback_time) {
-            time_diff = av_gettime() - audio_callback_time;
-            delay -= (time_diff * s->audio_st->codec->sample_rate) / 1000000;
-        }
-
-        delay += 2 * data_used;
-        if (delay < data_used)
-            delay = data_used;
-
-        i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
-        if (s->show_audio == 1) {
-            h = INT_MIN;
-            for (i = 0; i < 1000; i += channels) {
-                int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
-                int a = s->sample_array[idx];
-                int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
-                int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
-                int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
-                int score = a - d;
-                if (h < score && (b ^ c) < 0) {
-                    h = score;
-                    i_start = idx;
-                }
-            }
-        }
-
-        s->last_i_start = i_start;
-    } else {
-        i_start = s->last_i_start;
-    }
-
-    bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
-    if (s->show_audio == 1) {
-        fill_rectangle(screen,
-                       s->xleft, s->ytop, s->width, s->height,
-                       bgcolor);
-
-        fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
-
-        /* total height for one channel */
-        h = s->height / nb_display_channels;
-        /* graph height / 2 */
-        h2 = (h * 9) / 20;
-        for (ch = 0; ch < nb_display_channels; ch++) {
-            i = i_start + ch;
-            y1 = s->ytop + ch * h + (h / 2); /* position of center line */
-            for (x = 0; x < s->width; x++) {
-                y = (s->sample_array[i] * h2) >> 15;
-                if (y < 0) {
-                    y = -y;
-                    ys = y1 - y;
-                } else {
-                    ys = y1;
-                }
-                fill_rectangle(screen,
-                               s->xleft + x, ys, 1, y,
-                               fgcolor);
-                i += channels;
-                if (i >= SAMPLE_ARRAY_SIZE)
-                    i -= SAMPLE_ARRAY_SIZE;
-            }
-        }
-
-        fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
-
-        for (ch = 1; ch < nb_display_channels; ch++) {
-            y = s->ytop + ch * h;
-            fill_rectangle(screen,
-                           s->xleft, y, s->width, 1,
-                           fgcolor);
-        }
-        SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
-    } else {
-        nb_display_channels= FFMIN(nb_display_channels, 2);
-        if (rdft_bits != s->rdft_bits) {
-            av_rdft_end(s->rdft);
-            av_free(s->rdft_data);
-            s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
-            s->rdft_bits = rdft_bits;
-            s->rdft_data = av_malloc(4 * nb_freq * sizeof(*s->rdft_data));
-        }
-        {
-            FFTSample *data[2];
-            for (ch = 0; ch < nb_display_channels; ch++) {
-                data[ch] = s->rdft_data + 2 * nb_freq * ch;
-                i = i_start + ch;
-                for (x = 0; x < 2 * nb_freq; x++) {
-                    double w = (x-nb_freq) * (1.0 / nb_freq);
-                    data[ch][x] = s->sample_array[i] * (1.0 - w * w);
-                    i += channels;
-                    if (i >= SAMPLE_ARRAY_SIZE)
-                        i -= SAMPLE_ARRAY_SIZE;
-                }
-                av_rdft_calc(s->rdft, data[ch]);
-            }
-            // least efficient way to do this, we should of course directly access it but its more than fast enough
-            for (y = 0; y < s->height; y++) {
-                double w = 1 / sqrt(nb_freq);
-                int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
-                int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
-                       + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
-                a = FFMIN(a, 255);
-                b = FFMIN(b, 255);
-                fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
-
-                fill_rectangle(screen,
-                            s->xpos, s->height-y, 1, 1,
-                            fgcolor);
-            }
-        }
-        SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
-        s->xpos++;
-        if (s->xpos >= s->width)
-            s->xpos= s->xleft;
-    }
-}
-
-static int video_open(VideoState *is)
-{
-    int flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL;
-    int w,h;
-
-    if (is_full_screen) flags |= SDL_FULLSCREEN;
-    else                flags |= SDL_RESIZABLE;
-
-    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;
-#if CONFIG_AVFILTER
-    } else if (is->out_video_filter && is->out_video_filter->inputs[0]) {
-        w = is->out_video_filter->inputs[0]->w;
-        h = is->out_video_filter->inputs[0]->h;
-#else
-    } else if (is->video_st && is->video_st->codec->width) {
-        w = is->video_st->codec->width;
-        h = is->video_st->codec->height;
-#endif
-    } else {
-        w = 640;
-        h = 480;
-    }
-    if (screen && is->width == screen->w && screen->w == w
-       && is->height== screen->h && screen->h == h)
-        return 0;
-
-#if defined(__APPLE__) && !SDL_VERSION_ATLEAST(1, 2, 14)
-    /* setting bits_per_pixel = 0 or 32 causes blank video on OS X and older SDL */
-    screen = SDL_SetVideoMode(w, h, 24, flags);
-#else
-    screen = SDL_SetVideoMode(w, h, 0, flags);
-#endif
-    if (!screen) {
-        fprintf(stderr, "SDL: could not set video mode - exiting\n");
-        return -1;
-    }
-    if (!window_title)
-        window_title = input_filename;
-    SDL_WM_SetCaption(window_title, window_title);
-
-    is->width  = screen->w;
-    is->height = screen->h;
-
-    return 0;
-}
-
-/* display the current picture, if any */
-static void video_display(VideoState *is)
-{
-    if (!screen)
-        video_open(cur_stream);
-    if (is->audio_st && is->show_audio)
-        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->refresh = 1;
-            SDL_PushEvent(&event);
-        }
-        av_usleep(is->audio_st && is->show_audio ? rdftspeed * 1000 : 5000); // FIXME ideally we should wait the correct time but SDLs event passing is so slow it would be silly
-    }
-    return 0;
-}
-
-/* get the current audio clock value */
-static double get_audio_clock(VideoState *is)
-{
-    double pts;
-    int hw_buf_size, bytes_per_sec;
-    pts = is->audio_clock;
-    hw_buf_size = audio_write_get_buf_size(is);
-    bytes_per_sec = 0;
-    if (is->audio_st) {
-        bytes_per_sec = is->audio_st->codec->sample_rate * is->sdl_channels *
-                        av_get_bytes_per_sample(is->sdl_sample_fmt);
-    }
-    if (bytes_per_sec)
-        pts -= (double)hw_buf_size / bytes_per_sec;
-    return pts;
-}
-
-/* get the current video clock value */
-static double get_video_clock(VideoState *is)
-{
-    if (is->paused) {
-        return is->video_current_pts;
-    } else {
-        return is->video_current_pts_drift + av_gettime() / 1000000.0;
-    }
-}
-
-/* get the current external clock value */
-static double get_external_clock(VideoState *is)
-{
-    int64_t ti;
-    ti = av_gettime();
-    return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
-}
-
-/* get the current master clock value */
-static double get_master_clock(VideoState *is)
-{
-    double val;
-
-    if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
-        if (is->video_st)
-            val = get_video_clock(is);
-        else
-            val = get_audio_clock(is);
-    } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
-        if (is->audio_st)
-            val = get_audio_clock(is);
-        else
-            val = get_video_clock(is);
-    } else {
-        val = get_external_clock(is);
-    }
-    return val;
-}
-
-/* seek in the stream */
-static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
-{
-    if (!is->seek_req) {
-        is->seek_pos = pos;
-        is->seek_rel = rel;
-        is->seek_flags &= ~AVSEEK_FLAG_BYTE;
-        if (seek_by_bytes)
-            is->seek_flags |= AVSEEK_FLAG_BYTE;
-        is->seek_req = 1;
-    }
-}
-
-/* pause or resume the video */
-static void stream_pause(VideoState *is)
-{
-    if (is->paused) {
-        is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
-        if (is->read_pause_return != AVERROR(ENOSYS)) {
-            is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
-        }
-        is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
-    }
-    is->paused = !is->paused;
-}
-
-static double compute_target_time(double frame_current_pts, VideoState *is)
-{
-    double delay, sync_threshold, diff;
-
-    /* compute nominal delay */
-    delay = frame_current_pts - is->frame_last_pts;
-    if (delay <= 0 || delay >= 10.0) {
-        /* if incorrect delay, use previous one */
-        delay = is->frame_last_delay;
-    } else {
-        is->frame_last_delay = delay;
-    }
-    is->frame_last_pts = frame_current_pts;
-
-    /* update delay to follow master synchronisation source */
-    if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
-         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
-        /* if video is slave, we try to correct big delays by
-           duplicating or deleting a frame */
-        diff = get_video_clock(is) - get_master_clock(is);
-
-        /* skip or repeat frame. We take into account the
-           delay to compute the threshold. I still don't know
-           if it is the best guess */
-        sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
-        if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
-            if (diff <= -sync_threshold)
-                delay = 0;
-            else if (diff >= sync_threshold)
-                delay = 2 * delay;
-        }
-    }
-    is->frame_timer += delay;
-
-    av_dlog(NULL, "video: delay=%0.3f pts=%0.3f A-V=%f\n",
-            delay, frame_current_pts, -diff);
-
-    return is->frame_timer;
-}
-
-/* called to display each frame */
-static void video_refresh_timer(void *opaque)
-{
-    VideoState *is = opaque;
-    VideoPicture *vp;
-
-    SubPicture *sp, *sp2;
-
-    if (is->video_st) {
-retry:
-        if (is->pictq_size == 0) {
-            // nothing to do, no picture to display in the que
-        } else {
-            double time = av_gettime() / 1000000.0;
-            double next_target;
-            /* dequeue the picture */
-            vp = &is->pictq[is->pictq_rindex];
-
-            if (time < vp->target_clock)
-                return;
-            /* update current video pts */
-            is->video_current_pts = vp->pts;
-            is->video_current_pts_drift = is->video_current_pts - time;
-            is->video_current_pos = vp->pos;
-            if (is->pictq_size > 1) {
-                VideoPicture *nextvp = &is->pictq[(is->pictq_rindex + 1) % VIDEO_PICTURE_QUEUE_SIZE];
-                assert(nextvp->target_clock >= vp->target_clock);
-                next_target= nextvp->target_clock;
-            } else {
-                next_target = vp->target_clock + is->video_clock - vp->pts; // FIXME pass durations cleanly
-            }
-            if (framedrop && time > next_target) {
-                is->skip_frames *= 1.0 + FRAME_SKIP_FACTOR;
-                if (is->pictq_size > 1 || time > next_target + 0.5) {
-                    /* update queue size and signal for next picture */
-                    if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
-                        is->pictq_rindex = 0;
-
-                    SDL_LockMutex(is->pictq_mutex);
-                    is->pictq_size--;
-                    SDL_CondSignal(is->pictq_cond);
-                    SDL_UnlockMutex(is->pictq_mutex);
-                    goto retry;
-                }
-            }
-
-            if (is->subtitle_st) {
-                if (is->subtitle_stream_changed) {
-                    SDL_LockMutex(is->subpq_mutex);
-
-                    while (is->subpq_size) {
-                        free_subpicture(&is->subpq[is->subpq_rindex]);
-
-                        /* update queue size and signal for next picture */
-                        if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
-                            is->subpq_rindex = 0;
-
-                        is->subpq_size--;
-                    }
-                    is->subtitle_stream_changed = 0;
-
-                    SDL_CondSignal(is->subpq_cond);
-                    SDL_UnlockMutex(is->subpq_mutex);
-                } else {
-                    if (is->subpq_size > 0) {
-                        sp = &is->subpq[is->subpq_rindex];
-
-                        if (is->subpq_size > 1)
-                            sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
-                        else
-                            sp2 = NULL;
-
-                        if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
-                                || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
-                        {
-                            free_subpicture(sp);
-
-                            /* update queue size and signal for next picture */
-                            if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
-                                is->subpq_rindex = 0;
-
-                            SDL_LockMutex(is->subpq_mutex);
-                            is->subpq_size--;
-                            SDL_CondSignal(is->subpq_cond);
-                            SDL_UnlockMutex(is->subpq_mutex);
-                        }
-                    }
-                }
-            }
-
-            /* display picture */
-            if (!display_disable)
-                video_display(is);
-
-            /* update queue size and signal for next picture */
-            if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
-                is->pictq_rindex = 0;
-
-            SDL_LockMutex(is->pictq_mutex);
-            is->pictq_size--;
-            SDL_CondSignal(is->pictq_cond);
-            SDL_UnlockMutex(is->pictq_mutex);
-        }
-    } 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);
-    }
-    if (show_status) {
-        static int64_t last_time;
-        int64_t cur_time;
-        int aqsize, vqsize, sqsize;
-        double av_diff;
-
-        cur_time = av_gettime();
-        if (!last_time || (cur_time - last_time) >= 30000) {
-            aqsize = 0;
-            vqsize = 0;
-            sqsize = 0;
-            if (is->audio_st)
-                aqsize = is->audioq.size;
-            if (is->video_st)
-                vqsize = is->videoq.size;
-            if (is->subtitle_st)
-                sqsize = is->subtitleq.size;
-            av_diff = 0;
-            if (is->audio_st && is->video_st)
-                av_diff = get_audio_clock(is) - get_video_clock(is);
-            printf("%7.2f A-V:%7.3f s:%3.1f aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64"   \r",
-                   get_master_clock(is), av_diff, FFMAX(is->skip_frames - 1, 0), aqsize / 1024,
-                   vqsize / 1024, sqsize, is->pts_ctx.num_faulty_dts, is->pts_ctx.num_faulty_pts);
-            fflush(stdout);
-            last_time = cur_time;
-        }
-    }
-}
-
-static void stream_close(VideoState *is)
-{
-    VideoPicture *vp;
-    int i;
-    /* XXX: use a special url_shutdown call to abort parse cleanly */
-    is->abort_request = 1;
-    SDL_WaitThread(is->parse_tid, NULL);
-    SDL_WaitThread(is->refresh_tid, NULL);
-
-    /* free all pictures */
-    for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
-        vp = &is->pictq[i];
-#if CONFIG_AVFILTER
-        avfilter_unref_bufferp(&vp->picref);
-#endif
-        if (vp->bmp) {
-            SDL_FreeYUVOverlay(vp->bmp);
-            vp->bmp = NULL;
-        }
-    }
-    SDL_DestroyMutex(is->pictq_mutex);
-    SDL_DestroyCond(is->pictq_cond);
-    SDL_DestroyMutex(is->subpq_mutex);
-    SDL_DestroyCond(is->subpq_cond);
-#if !CONFIG_AVFILTER
-    if (is->img_convert_ctx)
-        sws_freeContext(is->img_convert_ctx);
-#endif
-    av_free(is);
-}
-
-static void do_exit(void)
-{
-    if (cur_stream) {
-        stream_close(cur_stream);
-        cur_stream = NULL;
-    }
-    uninit_opts();
-#if CONFIG_AVFILTER
-    avfilter_uninit();
-#endif
-    avformat_network_deinit();
-    if (show_status)
-        printf("\n");
-    SDL_Quit();
-    av_log(NULL, AV_LOG_QUIET, "");
-    exit(0);
-}
-
-/* allocate a picture (needs to do that in main thread to avoid
-   potential locking problems */
-static void alloc_picture(void *opaque)
-{
-    VideoState *is = opaque;
-    VideoPicture *vp;
-
-    vp = &is->pictq[is->pictq_windex];
-
-    if (vp->bmp)
-        SDL_FreeYUVOverlay(vp->bmp);
-
-#if CONFIG_AVFILTER
-    avfilter_unref_bufferp(&vp->picref);
-
-    vp->width   = is->out_video_filter->inputs[0]->w;
-    vp->height  = is->out_video_filter->inputs[0]->h;
-    vp->pix_fmt = is->out_video_filter->inputs[0]->format;
-#else
-    vp->width   = is->video_st->codec->width;
-    vp->height  = is->video_st->codec->height;
-    vp->pix_fmt = is->video_st->codec->pix_fmt;
-#endif
-
-    vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
-                                   SDL_YV12_OVERLAY,
-                                   screen);
-    if (!vp->bmp || vp->bmp->pitches[0] < vp->width) {
-        /* SDL allocates a buffer smaller than requested if the video
-         * overlay hardware is unable to support the requested size. */
-        fprintf(stderr, "Error: the video system does not support an image\n"
-                        "size of %dx%d pixels. Try using -vf \"scale=w:h\"\n"
-                        "to reduce the image size.\n", vp->width, vp->height );
-        do_exit();
-    }
-
-    SDL_LockMutex(is->pictq_mutex);
-    vp->allocated = 1;
-    SDL_CondSignal(is->pictq_cond);
-    SDL_UnlockMutex(is->pictq_mutex);
-}
-
-/* The 'pts' parameter is the dts of the packet / pts of the frame and
- * guessed if not known. */
-static int queue_picture(VideoState *is, AVFrame *src_frame, double pts, int64_t pos)
-{
-    VideoPicture *vp;
-#if CONFIG_AVFILTER
-    AVPicture pict_src;
-#else
-    int dst_pix_fmt = AV_PIX_FMT_YUV420P;
-#endif
-    /* wait until we have space to put a new picture */
-    SDL_LockMutex(is->pictq_mutex);
-
-    if (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE && !is->refresh)
-        is->skip_frames = FFMAX(1.0 - FRAME_SKIP_FACTOR, is->skip_frames * (1.0 - FRAME_SKIP_FACTOR));
-
-    while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
-           !is->videoq.abort_request) {
-        SDL_CondWait(is->pictq_cond, is->pictq_mutex);
-    }
-    SDL_UnlockMutex(is->pictq_mutex);
-
-    if (is->videoq.abort_request)
-        return -1;
-
-    vp = &is->pictq[is->pictq_windex];
-
-    /* alloc or resize hardware picture buffer */
-    if (!vp->bmp || vp->reallocate ||
-#if CONFIG_AVFILTER
-        vp->width  != is->out_video_filter->inputs[0]->w ||
-        vp->height != is->out_video_filter->inputs[0]->h) {
-#else
-        vp->width != is->video_st->codec->width ||
-        vp->height != is->video_st->codec->height) {
-#endif
-        SDL_Event event;
-
-        vp->allocated  = 0;
-        vp->reallocate = 0;
-
-        /* the allocation must be done in the main thread to avoid
-           locking problems */
-        event.type = FF_ALLOC_EVENT;
-        event.user.data1 = is;
-        SDL_PushEvent(&event);
-
-        /* wait until the picture is allocated */
-        SDL_LockMutex(is->pictq_mutex);
-        while (!vp->allocated && !is->videoq.abort_request) {
-            SDL_CondWait(is->pictq_cond, is->pictq_mutex);
-        }
-        SDL_UnlockMutex(is->pictq_mutex);
-
-        if (is->videoq.abort_request)
-            return -1;
-    }
-
-    /* if the frame is not skipped, then display it */
-    if (vp->bmp) {
-        AVPicture pict = { { 0 } };
-#if CONFIG_AVFILTER
-        avfilter_unref_bufferp(&vp->picref);
-        vp->picref = src_frame->opaque;
-#endif
-
-        /* get a pointer on the bitmap */
-        SDL_LockYUVOverlay (vp->bmp);
-
-        pict.data[0] = vp->bmp->pixels[0];
-        pict.data[1] = vp->bmp->pixels[2];
-        pict.data[2] = vp->bmp->pixels[1];
-
-        pict.linesize[0] = vp->bmp->pitches[0];
-        pict.linesize[1] = vp->bmp->pitches[2];
-        pict.linesize[2] = vp->bmp->pitches[1];
-
-#if CONFIG_AVFILTER
-        pict_src.data[0] = src_frame->data[0];
-        pict_src.data[1] = src_frame->data[1];
-        pict_src.data[2] = src_frame->data[2];
-
-        pict_src.linesize[0] = src_frame->linesize[0];
-        pict_src.linesize[1] = src_frame->linesize[1];
-        pict_src.linesize[2] = src_frame->linesize[2];
-
-        // FIXME use direct rendering
-        av_picture_copy(&pict, &pict_src,
-                        vp->pix_fmt, vp->width, vp->height);
-#else
-        sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
-        is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
-            vp->width, vp->height, vp->pix_fmt, vp->width, vp->height,
-            dst_pix_fmt, sws_flags, NULL, NULL, NULL);
-        if (is->img_convert_ctx == NULL) {
-            fprintf(stderr, "Cannot initialize the conversion context\n");
-            exit(1);
-        }
-        sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
-                  0, vp->height, pict.data, pict.linesize);
-#endif
-        /* update the bitmap content */
-        SDL_UnlockYUVOverlay(vp->bmp);
-
-        vp->pts = pts;
-        vp->pos = pos;
-
-        /* now we can update the picture count */
-        if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
-            is->pictq_windex = 0;
-        SDL_LockMutex(is->pictq_mutex);
-        vp->target_clock = compute_target_time(vp->pts, is);
-
-        is->pictq_size++;
-        SDL_UnlockMutex(is->pictq_mutex);
-    }
-    return 0;
-}
-
-/* Compute the exact PTS for the picture if it is omitted in the stream.
- * The 'pts1' parameter is the dts of the packet / pts of the frame. */
-static int output_picture2(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
-{
-    double frame_delay, pts;
-
-    pts = pts1;
-
-    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;
-
-    return queue_picture(is, src_frame, pts, pos);
-}
-
-static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)
-{
-    int got_picture, i;
-
-    if (packet_queue_get(&is->videoq, pkt, 1) < 0)
-        return -1;
-
-    if (pkt->data == flush_pkt.data) {
-        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].target_clock= 0;
-        }
-        while (is->pictq_size && !is->videoq.abort_request) {
-            SDL_CondWait(is->pictq_cond, is->pictq_mutex);
-        }
-        is->video_current_pos = -1;
-        SDL_UnlockMutex(is->pictq_mutex);
-
-        init_pts_correction(&is->pts_ctx);
-        is->frame_last_pts = AV_NOPTS_VALUE;
-        is->frame_last_delay = 0;
-        is->frame_timer = (double)av_gettime() / 1000000.0;
-        is->skip_frames = 1;
-        is->skip_frames_index = 0;
-        return 0;
-    }
-
-    avcodec_decode_video2(is->video_st->codec, frame, &got_picture, pkt);
-
-    if (got_picture) {
-        if (decoder_reorder_pts == -1) {
-            *pts = guess_correct_pts(&is->pts_ctx, frame->pkt_pts, frame->pkt_dts);
-        } else if (decoder_reorder_pts) {
-            *pts = frame->pkt_pts;
-        } else {
-            *pts = frame->pkt_dts;
-        }
-
-        if (*pts == AV_NOPTS_VALUE) {
-            *pts = 0;
-        }
-
-        is->skip_frames_index += 1;
-        if (is->skip_frames_index >= is->skip_frames) {
-            is->skip_frames_index -= FFMAX(is->skip_frames, 1.0);
-            return 1;
-        }
-
-    }
-    return 0;
-}
-
-#if CONFIG_AVFILTER
-static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters)
-{
-    char sws_flags_str[128];
-    char buffersrc_args[256];
-    int ret;
-    AVFilterContext *filt_src = NULL, *filt_out = NULL, *filt_format;
-    AVCodecContext *codec = is->video_st->codec;
-
-    snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags);
-    graph->scale_sws_opts = av_strdup(sws_flags_str);
-
-    snprintf(buffersrc_args, sizeof(buffersrc_args), "%d:%d:%d:%d:%d:%d:%d",
-             codec->width, codec->height, codec->pix_fmt,
-             is->video_st->time_base.num, is->video_st->time_base.den,
-             codec->sample_aspect_ratio.num, codec->sample_aspect_ratio.den);
-
-
-    if ((ret = avfilter_graph_create_filter(&filt_src,
-                                            avfilter_get_by_name("buffer"),
-                                            "src", buffersrc_args, NULL,
-                                            graph)) < 0)
-        return ret;
-    if ((ret = avfilter_graph_create_filter(&filt_out,
-                                            avfilter_get_by_name("buffersink"),
-                                            "out", NULL, NULL, graph)) < 0)
-        return ret;
-
-    if ((ret = avfilter_graph_create_filter(&filt_format,
-                                            avfilter_get_by_name("format"),
-                                            "format", "yuv420p", NULL, graph)) < 0)
-        return ret;
-    if ((ret = avfilter_link(filt_format, 0, filt_out, 0)) < 0)
-        return ret;
-
-
-    if (vfilters) {
-        AVFilterInOut *outputs = avfilter_inout_alloc();
-        AVFilterInOut *inputs  = avfilter_inout_alloc();
-
-        outputs->name    = av_strdup("in");
-        outputs->filter_ctx = filt_src;
-        outputs->pad_idx = 0;
-        outputs->next    = NULL;
-
-        inputs->name    = av_strdup("out");
-        inputs->filter_ctx = filt_format;
-        inputs->pad_idx = 0;
-        inputs->next    = NULL;
-
-        if ((ret = avfilter_graph_parse(graph, vfilters, inputs, outputs, NULL)) < 0)
-            return ret;
-    } else {
-        if ((ret = avfilter_link(filt_src, 0, filt_format, 0)) < 0)
-            return ret;
-    }
-
-    if ((ret = avfilter_graph_config(graph, NULL)) < 0)
-        return ret;
-
-    is->in_video_filter  = filt_src;
-    is->out_video_filter = filt_out;
-
-    if (codec->codec->capabilities & CODEC_CAP_DR1) {
-        is->use_dr1 = 1;
-        codec->get_buffer     = codec_get_buffer;
-        codec->release_buffer = codec_release_buffer;
-        codec->opaque         = &is->buffer_pool;
-    }
-
-    return ret;
-}
-
-#endif  /* CONFIG_AVFILTER */
-
-static int video_thread(void *arg)
-{
-    AVPacket pkt = { 0 };
-    VideoState *is = arg;
-    AVFrame *frame = avcodec_alloc_frame();
-    int64_t pts_int;
-    double pts;
-    int ret;
-
-#if CONFIG_AVFILTER
-    AVFilterGraph *graph = avfilter_graph_alloc();
-    AVFilterContext *filt_out = NULL, *filt_in = NULL;
-    int64_t pos;
-    int last_w = is->video_st->codec->width;
-    int last_h = is->video_st->codec->height;
-
-    if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
-        goto the_end;
-    filt_in  = is->in_video_filter;
-    filt_out = is->out_video_filter;
-#endif
-
-    for (;;) {
-#if CONFIG_AVFILTER
-        AVFilterBufferRef *picref;
-        AVRational tb;
-#endif
-        while (is->paused && !is->videoq.abort_request)
-            SDL_Delay(10);
-
-        av_free_packet(&pkt);
-
-        ret = get_video_frame(is, frame, &pts_int, &pkt);
-        if (ret < 0)
-            goto the_end;
-
-        if (!ret)
-            continue;
-
-#if CONFIG_AVFILTER
-        if (   last_w != is->video_st->codec->width
-            || last_h != is->video_st->codec->height) {
-            av_dlog(NULL, "Changing size %dx%d -> %dx%d\n", last_w, last_h,
-                    is->video_st->codec->width, is->video_st->codec->height);
-            avfilter_graph_free(&graph);
-            graph = avfilter_graph_alloc();
-            if ((ret = configure_video_filters(graph, is, vfilters)) < 0)
-                goto the_end;
-            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;
-        }
-
-        frame->pts = pts_int;
-        if (is->use_dr1) {
-            FrameBuffer      *buf = frame->opaque;
-            AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays(
-                                        frame->data, frame->linesize,
-                                        AV_PERM_READ | AV_PERM_PRESERVE,
-                                        frame->width, frame->height,
-                                        frame->format);
-
-            avfilter_copy_frame_props(fb, frame);
-            fb->buf->priv           = buf;
-            fb->buf->free           = filter_release_buffer;
-
-            buf->refcount++;
-            av_buffersrc_buffer(filt_in, fb);
-
-        } else
-            av_buffersrc_write_frame(filt_in, frame);
-
-        while (ret >= 0) {
-            ret = av_buffersink_read(filt_out, &picref);
-            if (ret < 0) {
-                ret = 0;
-                break;
-            }
-
-            avfilter_copy_buf_props(frame, picref);
-
-            pts_int = picref->pts;
-            tb      = filt_out->inputs[0]->time_base;
-            pos     = picref->pos;
-            frame->opaque = picref;
-
-            if (av_cmp_q(tb, is->video_st->time_base)) {
-                av_unused int64_t pts1 = pts_int;
-                pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);
-                av_dlog(NULL, "video_thread(): "
-                        "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
-                        tb.num, tb.den, pts1,
-                        is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
-            }
-            pts = pts_int * av_q2d(is->video_st->time_base);
-            ret = output_picture2(is, frame, pts, pos);
-        }
-#else
-        pts = pts_int * av_q2d(is->video_st->time_base);
-        ret = output_picture2(is, frame, pts,  pkt.pos);
-#endif
-
-        if (ret < 0)
-            goto the_end;
-
-        if (step)
-            if (cur_stream)
-                stream_pause(cur_stream);
-    }
- the_end:
-#if CONFIG_AVFILTER
-    av_freep(&vfilters);
-    avfilter_graph_free(&graph);
-#endif
-    av_free_packet(&pkt);
-    avcodec_free_frame(&frame);
-    return 0;
-}
-
-static int subtitle_thread(void *arg)
-{
-    VideoState *is = arg;
-    SubPicture *sp;
-    AVPacket pkt1, *pkt = &pkt1;
-    int got_subtitle;
-    double pts;
-    int i, j;
-    int r, g, b, y, u, v, a;
-
-    for (;;) {
-        while (is->paused && !is->subtitleq.abort_request) {
-            SDL_Delay(10);
-        }
-        if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
-            break;
-
-        if (pkt->data == flush_pkt.data) {
-            avcodec_flush_buffers(is->subtitle_st->codec);
-            continue;
-        }
-        SDL_LockMutex(is->subpq_mutex);
-        while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
-               !is->subtitleq.abort_request) {
-            SDL_CondWait(is->subpq_cond, is->subpq_mutex);
-        }
-        SDL_UnlockMutex(is->subpq_mutex);
-
-        if (is->subtitleq.abort_request)
-            return 0;
-
-        sp = &is->subpq[is->subpq_windex];
-
-       /* NOTE: ipts is the PTS of the _first_ picture beginning in
-           this packet, if any */
-        pts = 0;
-        if (pkt->pts != AV_NOPTS_VALUE)
-            pts = av_q2d(is->subtitle_st->time_base) * pkt->pts;
-
-        avcodec_decode_subtitle2(is->subtitle_st->codec, &sp->sub,
-                                 &got_subtitle, pkt);
-
-        if (got_subtitle && sp->sub.format == 0) {
-            sp->pts = pts;
-
-            for (i = 0; i < sp->sub.num_rects; i++)
-            {
-                for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
-                {
-                    RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
-                    y = RGB_TO_Y_CCIR(r, g, b);
-                    u = RGB_TO_U_CCIR(r, g, b, 0);
-                    v = RGB_TO_V_CCIR(r, g, b, 0);
-                    YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
-                }
-            }
-
-            /* now we can update the picture count */
-            if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
-                is->subpq_windex = 0;
-            SDL_LockMutex(is->subpq_mutex);
-            is->subpq_size++;
-            SDL_UnlockMutex(is->subpq_mutex);
-        }
-        av_free_packet(pkt);
-    }
-    return 0;
-}
-
-/* copy samples for viewing in editor window */
-static void update_sample_display(VideoState *is, short *samples, int samples_size)
-{
-    int size, len;
-
-    size = samples_size / sizeof(short);
-    while (size > 0) {
-        len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
-        if (len > size)
-            len = size;
-        memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
-        samples += len;
-        is->sample_array_index += len;
-        if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
-            is->sample_array_index = 0;
-        size -= len;
-    }
-}
-
-/* return the new audio buffer size (samples can be added or deleted
-   to get better sync if video or external master clock) */
-static int synchronize_audio(VideoState *is, short *samples,
-                             int samples_size1, double pts)
-{
-    int n, samples_size;
-    double ref_clock;
-
-    n = is->sdl_channels * av_get_bytes_per_sample(is->sdl_sample_fmt);
-    samples_size = samples_size1;
-
-    /* if not master, then we try to remove or add samples to correct the clock */
-    if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
-         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
-        double diff, avg_diff;
-        int wanted_size, min_size, max_size, nb_samples;
-
-        ref_clock = get_master_clock(is);
-        diff = get_audio_clock(is) - ref_clock;
-
-        if (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 */
-                is->audio_diff_avg_count++;
-            } else {
-                /* estimate the A-V difference */
-                avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
-
-                if (fabs(avg_diff) >= is->audio_diff_threshold) {
-                    wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
-                    nb_samples = samples_size / n;
-
-                    min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
-                    max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
-                    if (wanted_size < min_size)
-                        wanted_size = min_size;
-                    else if (wanted_size > max_size)
-                        wanted_size = max_size;
-
-                    /* add or remove samples to correction the synchro */
-                    if (wanted_size < samples_size) {
-                        /* remove samples */
-                        samples_size = wanted_size;
-                    } else if (wanted_size > samples_size) {
-                        uint8_t *samples_end, *q;
-                        int nb;
-
-                        /* add samples */
-                        nb = (samples_size - wanted_size);
-                        samples_end = (uint8_t *)samples + samples_size - n;
-                        q = samples_end + n;
-                        while (nb > 0) {
-                            memcpy(q, samples_end, n);
-                            q += n;
-                            nb -= n;
-                        }
-                        samples_size = wanted_size;
-                    }
-                }
-                av_dlog(NULL, "diff=%f adiff=%f sample_diff=%d apts=%0.3f vpts=%0.3f %f\n",
-                        diff, avg_diff, samples_size - samples_size1,
-                        is->audio_clock, is->video_clock, is->audio_diff_threshold);
-            }
-        } else {
-            /* too big difference : may be initial PTS errors, so
-               reset A-V filter */
-            is->audio_diff_avg_count = 0;
-            is->audio_diff_cum       = 0;
-        }
-    }
-
-    return samples_size;
-}
-
-/* decode one audio frame and returns its uncompressed size */
-static int audio_decode_frame(VideoState *is, double *pts_ptr)
-{
-    AVPacket *pkt_temp = &is->audio_pkt_temp;
-    AVPacket *pkt = &is->audio_pkt;
-    AVCodecContext *dec = is->audio_st->codec;
-    int n, len1, data_size, got_frame;
-    double pts;
-    int new_packet = 0;
-    int flush_complete = 0;
-
-    for (;;) {
-        /* NOTE: the audio packet can contain several frames */
-        while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) {
-            int resample_changed, audio_resample;
-
-            if (!is->frame) {
-                if (!(is->frame = avcodec_alloc_frame()))
-                    return AVERROR(ENOMEM);
-            } else
-                avcodec_get_frame_defaults(is->frame);
-
-            if (flush_complete)
-                break;
-            new_packet = 0;
-            len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
-            if (len1 < 0) {
-                /* if error, we skip the frame */
-                pkt_temp->size = 0;
-                break;
-            }
-
-            pkt_temp->data += len1;
-            pkt_temp->size -= len1;
-
-            if (!got_frame) {
-                /* stop sending empty packets if the decoder is finished */
-                if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY)
-                    flush_complete = 1;
-                continue;
-            }
-            data_size = av_samples_get_buffer_size(NULL, dec->channels,
-                                                   is->frame->nb_samples,
-                                                   dec->sample_fmt, 1);
-
-            audio_resample = dec->sample_fmt     != is->sdl_sample_fmt ||
-                             dec->channel_layout != is->sdl_channel_layout;
-
-            resample_changed = dec->sample_fmt     != is->resample_sample_fmt ||
-                               dec->channel_layout != is->resample_channel_layout;
-
-            if ((!is->avr && audio_resample) || resample_changed) {
-                int ret;
-                if (is->avr)
-                    avresample_close(is->avr);
-                else if (audio_resample) {
-                    is->avr = avresample_alloc_context();
-                    if (!is->avr) {
-                        fprintf(stderr, "error allocating AVAudioResampleContext\n");
-                        break;
-                    }
-                }
-                if (audio_resample) {
-                    av_opt_set_int(is->avr, "in_channel_layout",  dec->channel_layout,    0);
-                    av_opt_set_int(is->avr, "in_sample_fmt",      dec->sample_fmt,        0);
-                    av_opt_set_int(is->avr, "in_sample_rate",     dec->sample_rate,       0);
-                    av_opt_set_int(is->avr, "out_channel_layout", is->sdl_channel_layout, 0);
-                    av_opt_set_int(is->avr, "out_sample_fmt",     is->sdl_sample_fmt,     0);
-                    av_opt_set_int(is->avr, "out_sample_rate",    dec->sample_rate,       0);
-
-                    if ((ret = avresample_open(is->avr)) < 0) {
-                        fprintf(stderr, "error initializing libavresample\n");
-                        break;
-                    }
-                }
-                is->resample_sample_fmt     = dec->sample_fmt;
-                is->resample_channel_layout = dec->channel_layout;
-            }
-
-            if (audio_resample) {
-                void *tmp_out;
-                int out_samples, out_size, out_linesize;
-                int osize      = av_get_bytes_per_sample(is->sdl_sample_fmt);
-                int nb_samples = is->frame->nb_samples;
-
-                out_size = av_samples_get_buffer_size(&out_linesize,
-                                                      is->sdl_channels,
-                                                      nb_samples,
-                                                      is->sdl_sample_fmt, 0);
-                tmp_out = av_realloc(is->audio_buf1, out_size);
-                if (!tmp_out)
-                    return AVERROR(ENOMEM);
-                is->audio_buf1 = tmp_out;
-
-                out_samples = avresample_convert(is->avr,
-                                                 &is->audio_buf1,
-                                                 out_linesize, nb_samples,
-                                                 is->frame->data,
-                                                 is->frame->linesize[0],
-                                                 is->frame->nb_samples);
-                if (out_samples < 0) {
-                    fprintf(stderr, "avresample_convert() failed\n");
-                    break;
-                }
-                is->audio_buf = is->audio_buf1;
-                data_size = out_samples * osize * is->sdl_channels;
-            } else {
-                is->audio_buf = is->frame->data[0];
-            }
-
-            /* if no pts, then compute it */
-            pts = is->audio_clock;
-            *pts_ptr = pts;
-            n = is->sdl_channels * av_get_bytes_per_sample(is->sdl_sample_fmt);
-            is->audio_clock += (double)data_size /
-                (double)(n * dec->sample_rate);
-#ifdef DEBUG
-            {
-                static double last_clock;
-                printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
-                       is->audio_clock - last_clock,
-                       is->audio_clock, pts);
-                last_clock = is->audio_clock;
-            }
-#endif
-            return data_size;
-        }
-
-        /* free the current packet */
-        if (pkt->data)
-            av_free_packet(pkt);
-        memset(pkt_temp, 0, sizeof(*pkt_temp));
-
-        if (is->paused || is->audioq.abort_request) {
-            return -1;
-        }
-
-        /* read next packet */
-        if ((new_packet = packet_queue_get(&is->audioq, pkt, 1)) < 0)
-            return -1;
-
-        if (pkt->data == flush_pkt.data) {
-            avcodec_flush_buffers(dec);
-            flush_complete = 0;
-        }
-
-        *pkt_temp = *pkt;
-
-        /* 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;
-        }
-    }
-}
-
-/* prepare a new audio buffer */
-static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
-{
-    VideoState *is = opaque;
-    int audio_size, len1;
-    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);
-           if (audio_size < 0) {
-                /* if error, just output silence */
-               is->audio_buf      = is->silence_buf;
-               is->audio_buf_size = sizeof(is->silence_buf);
-           } else {
-               if (is->show_audio)
-                   update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
-               audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
-                                              pts);
-               is->audio_buf_size = audio_size;
-           }
-           is->audio_buf_index = 0;
-        }
-        len1 = is->audio_buf_size - is->audio_buf_index;
-        if (len1 > len)
-            len1 = len;
-        memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
-        len -= len1;
-        stream += len1;
-        is->audio_buf_index += len1;
-    }
-}
-
-/* open a given stream. Return 0 if OK */
-static int stream_component_open(VideoState *is, int stream_index)
-{
-    AVFormatContext *ic = is->ic;
-    AVCodecContext *avctx;
-    AVCodec *codec;
-    SDL_AudioSpec wanted_spec, spec;
-    AVDictionary *opts;
-    AVDictionaryEntry *t = NULL;
-
-    if (stream_index < 0 || stream_index >= ic->nb_streams)
-        return -1;
-    avctx = ic->streams[stream_index]->codec;
-
-    opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], NULL);
-
-    codec = avcodec_find_decoder(avctx->codec_id);
-    avctx->debug_mv          = debug_mv;
-    avctx->debug             = debug;
-    avctx->workaround_bugs   = workaround_bugs;
-    avctx->idct_algo         = idct;
-    avctx->skip_frame        = skip_frame;
-    avctx->skip_idct         = skip_idct;
-    avctx->skip_loop_filter  = skip_loop_filter;
-    avctx->error_concealment = error_concealment;
-
-    if (fast)   avctx->flags2 |= CODEC_FLAG2_FAST;
-
-    if (!av_dict_get(opts, "threads", NULL, 0))
-        av_dict_set(&opts, "threads", "auto", 0);
-    if (!codec ||
-        avcodec_open2(avctx, codec, &opts) < 0)
-        return -1;
-    if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
-        av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
-        return AVERROR_OPTION_NOT_FOUND;
-    }
-
-    /* prepare audio output */
-    if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
-        wanted_spec.freq = avctx->sample_rate;
-        wanted_spec.format = AUDIO_S16SYS;
-
-        if (!avctx->channel_layout)
-            avctx->channel_layout = av_get_default_channel_layout(avctx->channels);
-        if (!avctx->channel_layout) {
-            fprintf(stderr, "unable to guess channel layout\n");
-            return -1;
-        }
-        if (avctx->channels == 1)
-            is->sdl_channel_layout = AV_CH_LAYOUT_MONO;
-        else
-            is->sdl_channel_layout = AV_CH_LAYOUT_STEREO;
-        is->sdl_channels = av_get_channel_layout_nb_channels(is->sdl_channel_layout);
-
-        wanted_spec.channels = is->sdl_channels;
-        wanted_spec.silence = 0;
-        wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
-        wanted_spec.callback = sdl_audio_callback;
-        wanted_spec.userdata = is;
-        if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
-            fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
-            return -1;
-        }
-        is->audio_hw_buf_size = spec.size;
-        is->sdl_sample_fmt          = AV_SAMPLE_FMT_S16;
-        is->resample_sample_fmt     = is->sdl_sample_fmt;
-        is->resample_channel_layout = is->sdl_channel_layout;
-    }
-
-    ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
-    switch (avctx->codec_type) {
-    case AVMEDIA_TYPE_AUDIO:
-        is->audio_stream = stream_index;
-        is->audio_st = ic->streams[stream_index];
-        is->audio_buf_size  = 0;
-        is->audio_buf_index = 0;
-
-        /* init averaging filter */
-        is->audio_diff_avg_coef  = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
-        is->audio_diff_avg_count = 0;
-        /* since we do not have a precise anough audio fifo fullness,
-           we correct audio sync only if larger than this threshold */
-        is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / avctx->sample_rate;
-
-        memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
-        packet_queue_init(&is->audioq);
-        SDL_PauseAudio(0);
-        break;
-    case AVMEDIA_TYPE_VIDEO:
-        is->video_stream = stream_index;
-        is->video_st = ic->streams[stream_index];
-
-        packet_queue_init(&is->videoq);
-        is->video_tid = SDL_CreateThread(video_thread, is);
-        break;
-    case AVMEDIA_TYPE_SUBTITLE:
-        is->subtitle_stream = stream_index;
-        is->subtitle_st = ic->streams[stream_index];
-        packet_queue_init(&is->subtitleq);
-
-        is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
-        break;
-    default:
-        break;
-    }
-    return 0;
-}
-
-static void stream_component_close(VideoState *is, int stream_index)
-{
-    AVFormatContext *ic = is->ic;
-    AVCodecContext *avctx;
-
-    if (stream_index < 0 || stream_index >= ic->nb_streams)
-        return;
-    avctx = ic->streams[stream_index]->codec;
-
-    switch (avctx->codec_type) {
-    case AVMEDIA_TYPE_AUDIO:
-        packet_queue_abort(&is->audioq);
-
-        SDL_CloseAudio();
-
-        packet_queue_end(&is->audioq);
-        av_free_packet(&is->audio_pkt);
-        if (is->avr)
-            avresample_free(&is->avr);
-        av_freep(&is->audio_buf1);
-        is->audio_buf = NULL;
-        avcodec_free_frame(&is->frame);
-
-        if (is->rdft) {
-            av_rdft_end(is->rdft);
-            av_freep(&is->rdft_data);
-            is->rdft = NULL;
-            is->rdft_bits = 0;
-        }
-        break;
-    case AVMEDIA_TYPE_VIDEO:
-        packet_queue_abort(&is->videoq);
-
-        /* note: we also signal this mutex to make sure we deblock the
-           video thread in all cases */
-        SDL_LockMutex(is->pictq_mutex);
-        SDL_CondSignal(is->pictq_cond);
-        SDL_UnlockMutex(is->pictq_mutex);
-
-        SDL_WaitThread(is->video_tid, NULL);
-
-        packet_queue_end(&is->videoq);
-        break;
-    case AVMEDIA_TYPE_SUBTITLE:
-        packet_queue_abort(&is->subtitleq);
-
-        /* note: we also signal this mutex to make sure we deblock the
-           video thread in all cases */
-        SDL_LockMutex(is->subpq_mutex);
-        is->subtitle_stream_changed = 1;
-
-        SDL_CondSignal(is->subpq_cond);
-        SDL_UnlockMutex(is->subpq_mutex);
-
-        SDL_WaitThread(is->subtitle_tid, NULL);
-
-        packet_queue_end(&is->subtitleq);
-        break;
-    default:
-        break;
-    }
-
-    ic->streams[stream_index]->discard = AVDISCARD_ALL;
-    avcodec_close(avctx);
-#if CONFIG_AVFILTER
-    free_buffer_pool(&is->buffer_pool);
-#endif
-    switch (avctx->codec_type) {
-    case AVMEDIA_TYPE_AUDIO:
-        is->audio_st = NULL;
-        is->audio_stream = -1;
-        break;
-    case AVMEDIA_TYPE_VIDEO:
-        is->video_st = NULL;
-        is->video_stream = -1;
-        break;
-    case AVMEDIA_TYPE_SUBTITLE:
-        is->subtitle_st = NULL;
-        is->subtitle_stream = -1;
-        break;
-    default:
-        break;
-    }
-}
-
-/* since we have only one decoding thread, we can use a global
-   variable instead of a thread local variable */
-static VideoState *global_video_state;
-
-static int decode_interrupt_cb(void *ctx)
-{
-    return global_video_state && global_video_state->abort_request;
-}
-
-/* this thread gets the stream from the disk or the network */
-static int decode_thread(void *arg)
-{
-    VideoState *is = arg;
-    AVFormatContext *ic = NULL;
-    int err, i, ret;
-    int st_index[AVMEDIA_TYPE_NB];
-    AVPacket pkt1, *pkt = &pkt1;
-    int eof = 0;
-    int pkt_in_play_range = 0;
-    AVDictionaryEntry *t;
-    AVDictionary **opts;
-    int orig_nb_streams;
-
-    memset(st_index, -1, sizeof(st_index));
-    is->video_stream = -1;
-    is->audio_stream = -1;
-    is->subtitle_stream = -1;
-
-    global_video_state = is;
-
-    ic = avformat_alloc_context();
-    ic->interrupt_callback.callback = decode_interrupt_cb;
-    err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
-    if (err < 0) {
-        print_error(is->filename, err);
-        ret = -1;
-        goto fail;
-    }
-    if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
-        av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
-        ret = AVERROR_OPTION_NOT_FOUND;
-        goto fail;
-    }
-    is->ic = ic;
-
-    if (genpts)
-        ic->flags |= AVFMT_FLAG_GENPTS;
-
-    opts = setup_find_stream_info_opts(ic, codec_opts);
-    orig_nb_streams = ic->nb_streams;
-
-    err = avformat_find_stream_info(ic, opts);
-    if (err < 0) {
-        fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
-        ret = -1;
-        goto fail;
-    }
-    for (i = 0; i < orig_nb_streams; i++)
-        av_dict_free(&opts[i]);
-    av_freep(&opts);
-
-    if (ic->pb)
-        ic->pb->eof_reached = 0; // FIXME hack, avplay maybe should not use url_feof() to test for the end
-
-    if (seek_by_bytes < 0)
-        seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT);
-
-    /* if seeking requested, we execute it */
-    if (start_time != AV_NOPTS_VALUE) {
-        int64_t timestamp;
-
-        timestamp = start_time;
-        /* add the stream start time */
-        if (ic->start_time != AV_NOPTS_VALUE)
-            timestamp += ic->start_time;
-        ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
-        if (ret < 0) {
-            fprintf(stderr, "%s: could not seek to position %0.3f\n",
-                    is->filename, (double)timestamp / AV_TIME_BASE);
-        }
-    }
-
-    for (i = 0; i < ic->nb_streams; i++)
-        ic->streams[i]->discard = AVDISCARD_ALL;
-    if (!video_disable)
-        st_index[AVMEDIA_TYPE_VIDEO] =
-            av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
-                                wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
-    if (!audio_disable)
-        st_index[AVMEDIA_TYPE_AUDIO] =
-            av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
-                                wanted_stream[AVMEDIA_TYPE_AUDIO],
-                                st_index[AVMEDIA_TYPE_VIDEO],
-                                NULL, 0);
-    if (!video_disable)
-        st_index[AVMEDIA_TYPE_SUBTITLE] =
-            av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
-                                wanted_stream[AVMEDIA_TYPE_SUBTITLE],
-                                (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
-                                 st_index[AVMEDIA_TYPE_AUDIO] :
-                                 st_index[AVMEDIA_TYPE_VIDEO]),
-                                NULL, 0);
-    if (show_status) {
-        av_dump_format(ic, 0, is->filename, 0);
-    }
-
-    /* open the streams */
-    if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
-        stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
-    }
-
-    ret = -1;
-    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 (ret < 0) {
-        if (!display_disable)
-            is->show_audio = 2;
-    }
-
-    if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
-        stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
-    }
-
-    if (is->video_stream < 0 && is->audio_stream < 0) {
-        fprintf(stderr, "%s: could not open codecs\n", is->filename);
-        ret = -1;
-        goto fail;
-    }
-
-    for (;;) {
-        if (is->abort_request)
-            break;
-        if (is->paused != is->last_paused) {
-            is->last_paused = is->paused;
-            if (is->paused)
-                is->read_pause_return = av_read_pause(ic);
-            else
-                av_read_play(ic);
-        }
-#if CONFIG_RTSP_DEMUXER
-        if (is->paused && !strcmp(ic->iformat->name, "rtsp")) {
-            /* wait 10 ms to avoid trying to get another packet */
-            /* XXX: horrible */
-            SDL_Delay(10);
-            continue;
-        }
-#endif
-        if (is->seek_req) {
-            int64_t seek_target = is->seek_pos;
-            int64_t seek_min    = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
-            int64_t seek_max    = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
-// FIXME the +-2 is due to rounding being not done in the correct direction in generation
-//      of the seek_pos/seek_rel variables
-
-            ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
-            if (ret < 0) {
-                fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
-            } else {
-                if (is->audio_stream >= 0) {
-                    packet_queue_flush(&is->audioq);
-                    packet_queue_put(&is->audioq, &flush_pkt);
-                }
-                if (is->subtitle_stream >= 0) {
-                    packet_queue_flush(&is->subtitleq);
-                    packet_queue_put(&is->subtitleq, &flush_pkt);
-                }
-                if (is->video_stream >= 0) {
-                    packet_queue_flush(&is->videoq);
-                    packet_queue_put(&is->videoq, &flush_pkt);
-                }
-            }
-            is->seek_req = 0;
-            eof = 0;
-        }
-
-        /* if the queue are full, no need to read more */
-        if (!infinite_buffer &&
-              (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
-            || (   (is->audioq   .size  > MIN_AUDIOQ_SIZE || is->audio_stream < 0)
-                && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream < 0)
-                && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0)))) {
-            /* wait 10 ms */
-            SDL_Delay(10);
-            continue;
-        }
-        if (eof) {
-            if (is->video_stream >= 0) {
-                av_init_packet(pkt);
-                pkt->data = NULL;
-                pkt->size = 0;
-                pkt->stream_index = is->video_stream;
-                packet_queue_put(&is->videoq, pkt);
-            }
-            if (is->audio_stream >= 0 &&
-                is->audio_st->codec->codec->capabilities & CODEC_CAP_DELAY) {
-                av_init_packet(pkt);
-                pkt->data = NULL;
-                pkt->size = 0;
-                pkt->stream_index = is->audio_stream;
-                packet_queue_put(&is->audioq, pkt);
-            }
-            SDL_Delay(10);
-            if (is->audioq.size + is->videoq.size + is->subtitleq.size == 0) {
-                if (loop != 1 && (!loop || --loop)) {
-                    stream_seek(cur_stream, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
-                } else if (autoexit) {
-                    ret = AVERROR_EOF;
-                    goto fail;
-                }
-            }
-            continue;
-        }
-        ret = av_read_frame(ic, pkt);
-        if (ret < 0) {
-            if (ret == AVERROR_EOF || (ic->pb && ic->pb->eof_reached))
-                eof = 1;
-            if (ic->pb && ic->pb->error)
-                break;
-            SDL_Delay(100); /* wait for user event */
-            continue;
-        }
-        /* check if packet is in play range specified by user, then queue, otherwise discard */
-        pkt_in_play_range = duration == AV_NOPTS_VALUE ||
-                (pkt->pts - ic->streams[pkt->stream_index]->start_time) *
-                av_q2d(ic->streams[pkt->stream_index]->time_base) -
-                (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
-                <= ((double)duration / 1000000);
-        if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
-            packet_queue_put(&is->audioq, pkt);
-        } else if (pkt->stream_index == is->video_stream && pkt_in_play_range) {
-            packet_queue_put(&is->videoq, pkt);
-        } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
-            packet_queue_put(&is->subtitleq, pkt);
-        } else {
-            av_free_packet(pkt);
-        }
-    }
-    /* wait until the end */
-    while (!is->abort_request) {
-        SDL_Delay(100);
-    }
-
-    ret = 0;
- fail:
-    /* disable interrupting */
-    global_video_state = NULL;
-
-    /* close each stream */
-    if (is->audio_stream >= 0)
-        stream_component_close(is, is->audio_stream);
-    if (is->video_stream >= 0)
-        stream_component_close(is, is->video_stream);
-    if (is->subtitle_stream >= 0)
-        stream_component_close(is, is->subtitle_stream);
-    if (is->ic) {
-        avformat_close_input(&is->ic);
-    }
-
-    if (ret != 0) {
-        SDL_Event event;
-
-        event.type = FF_QUIT_EVENT;
-        event.user.data1 = is;
-        SDL_PushEvent(&event);
-    }
-    return 0;
-}
-
-static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
-{
-    VideoState *is;
-
-    is = av_mallocz(sizeof(VideoState));
-    if (!is)
-        return NULL;
-    av_strlcpy(is->filename, filename, sizeof(is->filename));
-    is->iformat = iformat;
-    is->ytop    = 0;
-    is->xleft   = 0;
-
-    /* start video display */
-    is->pictq_mutex = SDL_CreateMutex();
-    is->pictq_cond  = SDL_CreateCond();
-
-    is->subpq_mutex = SDL_CreateMutex();
-    is->subpq_cond  = SDL_CreateCond();
-
-    is->av_sync_type = av_sync_type;
-    is->parse_tid    = SDL_CreateThread(decode_thread, is);
-    if (!is->parse_tid) {
-        av_free(is);
-        return NULL;
-    }
-    return is;
-}
-
-static void stream_cycle_channel(VideoState *is, int codec_type)
-{
-    AVFormatContext *ic = is->ic;
-    int start_index, stream_index;
-    AVStream *st;
-
-    if (codec_type == AVMEDIA_TYPE_VIDEO)
-        start_index = is->video_stream;
-    else if (codec_type == AVMEDIA_TYPE_AUDIO)
-        start_index = is->audio_stream;
-    else
-        start_index = is->subtitle_stream;
-    if (start_index < (codec_type == AVMEDIA_TYPE_SUBTITLE ? -1 : 0))
-        return;
-    stream_index = start_index;
-    for (;;) {
-        if (++stream_index >= is->ic->nb_streams)
-        {
-            if (codec_type == AVMEDIA_TYPE_SUBTITLE)
-            {
-                stream_index = -1;
-                goto the_end;
-            } else
-                stream_index = 0;
-        }
-        if (stream_index == start_index)
-            return;
-        st = ic->streams[stream_index];
-        if (st->codec->codec_type == codec_type) {
-            /* check that parameters are OK */
-            switch (codec_type) {
-            case AVMEDIA_TYPE_AUDIO:
-                if (st->codec->sample_rate != 0 &&
-                    st->codec->channels != 0)
-                    goto the_end;
-                break;
-            case AVMEDIA_TYPE_VIDEO:
-            case AVMEDIA_TYPE_SUBTITLE:
-                goto the_end;
-            default:
-                break;
-            }
-        }
-    }
- the_end:
-    stream_component_close(is, start_index);
-    stream_component_open(is, stream_index);
-}
-
-
-static void toggle_full_screen(void)
-{
-#if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
-    /* OS X needs to empty the picture_queue */
-    int i;
-    for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
-        cur_stream->pictq[i].reallocate = 1;
-#endif
-    is_full_screen = !is_full_screen;
-    video_open(cur_stream);
-}
-
-static void toggle_pause(void)
-{
-    if (cur_stream)
-        stream_pause(cur_stream);
-    step = 0;
-}
-
-static void step_to_next_frame(void)
-{
-    if (cur_stream) {
-        /* if the stream is paused unpause it, then step */
-        if (cur_stream->paused)
-            stream_pause(cur_stream);
-    }
-    step = 1;
-}
-
-static void toggle_audio_display(void)
-{
-    if (cur_stream) {
-        int bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
-        cur_stream->show_audio = (cur_stream->show_audio + 1) % 3;
-        fill_rectangle(screen,
-                       cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height,
-                       bgcolor);
-        SDL_UpdateRect(screen, cur_stream->xleft, cur_stream->ytop, cur_stream->width, cur_stream->height);
-    }
-}
-
-/* handle an event sent by the GUI */
-static void event_loop(void)
-{
-    SDL_Event event;
-    double incr, pos, frac;
-
-    for (;;) {
-        double x;
-        SDL_WaitEvent(&event);
-        switch (event.type) {
-        case SDL_KEYDOWN:
-            if (exit_on_keydown) {
-                do_exit();
-                break;
-            }
-            switch (event.key.keysym.sym) {
-            case SDLK_ESCAPE:
-            case SDLK_q:
-                do_exit();
-                break;
-            case SDLK_f:
-                toggle_full_screen();
-                break;
-            case SDLK_p:
-            case SDLK_SPACE:
-                toggle_pause();
-                break;
-            case SDLK_s: // S: Step to next frame
-                step_to_next_frame();
-                break;
-            case SDLK_a:
-                if (cur_stream)
-                    stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
-                break;
-            case SDLK_v:
-                if (cur_stream)
-                    stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
-                break;
-            case SDLK_t:
-                if (cur_stream)
-                    stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
-                break;
-            case SDLK_w:
-                toggle_audio_display();
-                break;
-            case SDLK_LEFT:
-                incr = -10.0;
-                goto do_seek;
-            case SDLK_RIGHT:
-                incr = 10.0;
-                goto do_seek;
-            case SDLK_UP:
-                incr = 60.0;
-                goto do_seek;
-            case SDLK_DOWN:
-                incr = -60.0;
-            do_seek:
-                if (cur_stream) {
-                    if (seek_by_bytes) {
-                        if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos >= 0) {
-                            pos = cur_stream->video_current_pos;
-                        } else if (cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos >= 0) {
-                            pos = cur_stream->audio_pkt.pos;
-                        } else
-                            pos = avio_tell(cur_stream->ic->pb);
-                        if (cur_stream->ic->bit_rate)
-                            incr *= cur_stream->ic->bit_rate / 8.0;
-                        else
-                            incr *= 180000.0;
-                        pos += incr;
-                        stream_seek(cur_stream, pos, incr, 1);
-                    } else {
-                        pos = get_master_clock(cur_stream);
-                        pos += incr;
-                        stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
-                    }
-                }
-                break;
-            default:
-                break;
-            }
-            break;
-        case SDL_MOUSEBUTTONDOWN:
-            if (exit_on_mousedown) {
-                do_exit();
-                break;
-            }
-        case SDL_MOUSEMOTION:
-            if (event.type == SDL_MOUSEBUTTONDOWN) {
-                x = event.button.x;
-            } else {
-                if (event.motion.state != SDL_PRESSED)
-                    break;
-                x = event.motion.x;
-            }
-            if (cur_stream) {
-                if (seek_by_bytes || cur_stream->ic->duration <= 0) {
-                    uint64_t size =  avio_size(cur_stream->ic->pb);
-                    stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
-                } else {
-                    int64_t ts;
-                    int ns, hh, mm, ss;
-                    int tns, thh, tmm, tss;
-                    tns  = cur_stream->ic->duration / 1000000LL;
-                    thh  = tns / 3600;
-                    tmm  = (tns % 3600) / 60;
-                    tss  = (tns % 60);
-                    frac = x / cur_stream->width;
-                    ns   = frac * tns;
-                    hh   = ns / 3600;
-                    mm   = (ns % 3600) / 60;
-                    ss   = (ns % 60);
-                    fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
-                            hh, mm, ss, thh, tmm, tss);
-                    ts = frac * cur_stream->ic->duration;
-                    if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
-                        ts += cur_stream->ic->start_time;
-                    stream_seek(cur_stream, ts, 0, 0);
-                }
-            }
-            break;
-        case SDL_VIDEORESIZE:
-            if (cur_stream) {
-                screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
-                                          SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
-                screen_width  = cur_stream->width  = event.resize.w;
-                screen_height = cur_stream->height = event.resize.h;
-            }
-            break;
-        case SDL_QUIT:
-        case FF_QUIT_EVENT:
-            do_exit();
-            break;
-        case FF_ALLOC_EVENT:
-            video_open(event.user.data1);
-            alloc_picture(event.user.data1);
-            break;
-        case FF_REFRESH_EVENT:
-            video_refresh_timer(event.user.data1);
-            cur_stream->refresh = 0;
-            break;
-        default:
-            break;
-        }
-    }
-}
-
-static int opt_frame_size(void *optctx, const char *opt, const char *arg)
-{
-    av_log(NULL, AV_LOG_ERROR,
-           "Option '%s' has been removed, use private format options instead\n", opt);
-    return AVERROR(EINVAL);
-}
-
-static int opt_width(void *optctx, const char *opt, const char *arg)
-{
-    screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
-    return 0;
-}
-
-static int opt_height(void *optctx, const char *opt, const char *arg)
-{
-    screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
-    return 0;
-}
-
-static int opt_format(void *optctx, const char *opt, const char *arg)
-{
-    file_iformat = av_find_input_format(arg);
-    if (!file_iformat) {
-        fprintf(stderr, "Unknown input format: %s\n", arg);
-        return AVERROR(EINVAL);
-    }
-    return 0;
-}
-
-static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
-{
-    av_log(NULL, AV_LOG_ERROR,
-           "Option '%s' has been removed, use private format options instead\n", opt);
-    return AVERROR(EINVAL);
-}
-
-static int opt_sync(void *optctx, const char *opt, const char *arg)
-{
-    if (!strcmp(arg, "audio"))
-        av_sync_type = AV_SYNC_AUDIO_MASTER;
-    else if (!strcmp(arg, "video"))
-        av_sync_type = AV_SYNC_VIDEO_MASTER;
-    else if (!strcmp(arg, "ext"))
-        av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
-    else {
-        fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
-        exit(1);
-    }
-    return 0;
-}
-
-static int opt_seek(void *optctx, const char *opt, const char *arg)
-{
-    start_time = parse_time_or_die(opt, arg, 1);
-    return 0;
-}
-
-static int opt_duration(void *optctx, const char *opt, const char *arg)
-{
-    duration = parse_time_or_die(opt, arg, 1);
-    return 0;
-}
-
-static int opt_debug(void *optctx, const char *opt, const char *arg)
-{
-    av_log_set_level(99);
-    debug = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
-    return 0;
-}
-
-static int opt_vismv(void *optctx, const char *opt, const char *arg)
-{
-    debug_mv = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
-    return 0;
-}
-
-static const OptionDef options[] = {
-#include "cmdutils_common_opts.h"
-    { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
-    { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
-    { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
-    { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
-    { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
-    { "vn", OPT_BOOL, { &video_disable }, "disable video" },
-    { "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" },
-    { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
-    { "t", HAS_ARG, { .func_arg = opt_duration }, "play  \"duration\" seconds of audio/video", "duration" },
-    { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
-    { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
-    { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
-    { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
-    { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
-    { "debug", HAS_ARG | OPT_EXPERT, { .func_arg = opt_debug }, "print specific debug info", "" },
-    { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, { &workaround_bugs }, "workaround bugs", "" },
-    { "vismv", HAS_ARG | OPT_EXPERT, { .func_arg = opt_vismv }, "visualize motion vectors", "" },
-    { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
-    { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
-    { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
-    { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, { &skip_loop_filter }, "", "" },
-    { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, { &skip_frame }, "", "" },
-    { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, { &skip_idct }, "", "" },
-    { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, { &idct }, "set idct algo",  "algo" },
-    { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, { &error_concealment }, "set error concealment options",  "bit_mask" },
-    { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
-    { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
-    { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
-    { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
-    { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
-    { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
-    { "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" },
-#endif
-    { "rdftspeed", OPT_INT | HAS_ARG| OPT_AUDIO | OPT_EXPERT, { &rdftspeed }, "rdft speed", "msecs" },
-    { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, { opt_default }, "generic catch all option", "" },
-    { "i", 0, { NULL }, "avconv compatibility dummy option", ""},
-    { NULL, },
-};
-
-static void show_usage(void)
-{
-    printf("Simple media player\n");
-    printf("usage: %s [options] input_file\n", program_name);
-    printf("\n");
-}
-
-void show_help_default(const char *opt, const char *arg)
-{
-    av_log_set_callback(log_callback_help);
-    show_usage();
-    show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
-    show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
-    printf("\n");
-    show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
-    show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
-#if !CONFIG_AVFILTER
-    show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
-#endif
-    printf("\nWhile playing:\n"
-           "q, ESC              quit\n"
-           "f                   toggle full screen\n"
-           "p, SPC              pause\n"
-           "a                   cycle audio channel\n"
-           "v                   cycle video channel\n"
-           "t                   cycle subtitle channel\n"
-           "w                   show audio waves\n"
-           "s                   activate frame-step mode\n"
-           "left/right          seek backward/forward 10 seconds\n"
-           "down/up             seek backward/forward 1 minute\n"
-           "mouse click         seek to percentage in file corresponding to fraction of width\n"
-           );
-}
-
-static void opt_input_file(void *optctx, const char *filename)
-{
-    if (input_filename) {
-        fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
-                filename, input_filename);
-        exit(1);
-    }
-    if (!strcmp(filename, "-"))
-        filename = "pipe:";
-    input_filename = filename;
-}
-
-/* Called from the main */
-int main(int argc, char **argv)
-{
-    int flags;
-
-    av_log_set_flags(AV_LOG_SKIP_REPEATED);
-    parse_loglevel(argc, argv, options);
-
-    /* register all codecs, demux and protocols */
-    avcodec_register_all();
-#if CONFIG_AVDEVICE
-    avdevice_register_all();
-#endif
-#if CONFIG_AVFILTER
-    avfilter_register_all();
-#endif
-    av_register_all();
-    avformat_network_init();
-
-    init_opts();
-
-    show_banner();
-
-    parse_options(NULL, argc, argv, options, opt_input_file);
-
-    if (!input_filename) {
-        show_usage();
-        fprintf(stderr, "An input file must be specified\n");
-        fprintf(stderr, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
-        exit(1);
-    }
-
-    if (display_disable) {
-        video_disable = 1;
-    }
-    flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
-#if !defined(__MINGW32__) && !defined(__APPLE__)
-    flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
-#endif
-    if (SDL_Init (flags)) {
-        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
-        exit(1);
-    }
-
-    if (!display_disable) {
-#if HAVE_SDL_VIDEO_SIZE
-        const SDL_VideoInfo *vi = SDL_GetVideoInfo();
-        fs_screen_width = vi->current_w;
-        fs_screen_height = vi->current_h;
-#endif
-    }
-
-    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
-    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
-    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
-
-    av_init_packet(&flush_pkt);
-    flush_pkt.data = "FLUSH";
-
-    cur_stream = stream_open(input_filename, file_iformat);
-
-    event_loop();
-
-    /* never returns */
-
-    return 0;
-}
diff --git a/avprobe.c b/avprobe.c
deleted file mode 100644
index 3a3ae0f..0000000
--- a/avprobe.c
+++ /dev/null
@@ -1,975 +0,0 @@
-/*
- * avprobe : Simple Media Prober based on the Libav libraries
- * Copyright (c) 2007-2010 Stefano Sabatini
- *
- * 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
- */
-
-#include "config.h"
-
-#include "libavformat/avformat.h"
-#include "libavcodec/avcodec.h"
-#include "libavutil/opt.h"
-#include "libavutil/pixdesc.h"
-#include "libavutil/dict.h"
-#include "libavutil/libm.h"
-#include "libavdevice/avdevice.h"
-#include "cmdutils.h"
-
-const char program_name[] = "avprobe";
-const int program_birth_year = 2007;
-
-static int do_show_format  = 0;
-static AVDictionary *fmt_entries_to_show = NULL;
-static int nb_fmt_entries_to_show;
-static int do_show_packets = 0;
-static int do_show_streams = 0;
-
-static int show_value_unit              = 0;
-static int use_value_prefix             = 0;
-static int use_byte_value_binary_prefix = 0;
-static int use_value_sexagesimal_format = 0;
-
-/* globals */
-static const OptionDef *options;
-
-/* AVprobe context */
-static const char *input_filename;
-static AVInputFormat *iformat = NULL;
-
-static const char *const binary_unit_prefixes [] = { "", "Ki", "Mi", "Gi", "Ti", "Pi" };
-static const char *const decimal_unit_prefixes[] = { "", "K" , "M" , "G" , "T" , "P"  };
-
-static const char unit_second_str[]         = "s"    ;
-static const char unit_hertz_str[]          = "Hz"   ;
-static const char unit_byte_str[]           = "byte" ;
-static const char unit_bit_per_second_str[] = "bit/s";
-
-static void exit_program(void)
-{
-    av_dict_free(&fmt_entries_to_show);
-}
-
-/*
- * The output is structured in array and objects that might contain items
- * Array could require the objects within to not be named.
- * Object could require the items within to be named.
- *
- * For flat representation the name of each section is saved on prefix so it
- * can be rendered in order to represent nested structures (e.g. array of
- * objects for the packets list).
- *
- * Within an array each element can need an unique identifier or an index.
- *
- * Nesting level is accounted separately.
- */
-
-typedef enum {
-    ARRAY,
-    OBJECT
-} ProbeElementType;
-
-typedef struct {
-    const char *name;
-    ProbeElementType type;
-    int64_t index;
-    int64_t nb_elems;
-} ProbeElement;
-
-typedef struct {
-    ProbeElement *prefix;
-    int level;
-    void (*print_header)(void);
-    void (*print_footer)(void);
-
-    void (*print_array_header) (const char *name);
-    void (*print_array_footer) (const char *name);
-    void (*print_object_header)(const char *name);
-    void (*print_object_footer)(const char *name);
-
-    void (*print_integer) (const char *key, int64_t value);
-    void (*print_string)  (const char *key, const char *value);
-} OutputContext;
-
-static AVIOContext *probe_out = NULL;
-static OutputContext octx;
-#define AVP_INDENT() avio_printf(probe_out, "%*c", octx.level * 2, ' ')
-
-/*
- * Default format, INI
- *
- * - all key and values are utf8
- * - '.' is the subgroup separator
- * - newlines and the following characters are escaped
- * - '\' is the escape character
- * - '#' is the comment
- * - '=' is the key/value separators
- * - ':' is not used but usually parsed as key/value separator
- */
-
-static void ini_print_header(void)
-{
-    avio_printf(probe_out, "# avprobe output\n\n");
-}
-static void ini_print_footer(void)
-{
-    avio_w8(probe_out, '\n');
-}
-
-static void ini_escape_print(const char *s)
-{
-    int i = 0;
-    char c = 0;
-
-    while (c = s[i++]) {
-        switch (c) {
-        case '\r': avio_printf(probe_out, "%s", "\\r"); break;
-        case '\n': avio_printf(probe_out, "%s", "\\n"); break;
-        case '\f': avio_printf(probe_out, "%s", "\\f"); break;
-        case '\b': avio_printf(probe_out, "%s", "\\b"); break;
-        case '\t': avio_printf(probe_out, "%s", "\\t"); break;
-        case '\\':
-        case '#' :
-        case '=' :
-        case ':' : avio_w8(probe_out, '\\');
-        default:
-            if ((unsigned char)c < 32)
-                avio_printf(probe_out, "\\x00%02x", c & 0xff);
-            else
-                avio_w8(probe_out, c);
-        break;
-        }
-    }
-}
-
-static void ini_print_array_header(const char *name)
-{
-    if (octx.prefix[octx.level -1].nb_elems)
-        avio_printf(probe_out, "\n");
-}
-
-static void ini_print_object_header(const char *name)
-{
-    int i;
-    ProbeElement *el = octx.prefix + octx.level -1;
-
-    if (el->nb_elems)
-        avio_printf(probe_out, "\n");
-
-    avio_printf(probe_out, "[");
-
-    for (i = 1; i < octx.level; i++) {
-        el = octx.prefix + i;
-        avio_printf(probe_out, "%s.", el->name);
-        if (el->index >= 0)
-            avio_printf(probe_out, "%"PRId64".", el->index);
-    }
-
-    avio_printf(probe_out, "%s", name);
-    if (el && el->type == ARRAY)
-        avio_printf(probe_out, ".%"PRId64"", el->nb_elems);
-    avio_printf(probe_out, "]\n");
-}
-
-static void ini_print_integer(const char *key, int64_t value)
-{
-    ini_escape_print(key);
-    avio_printf(probe_out, "=%"PRId64"\n", value);
-}
-
-
-static void ini_print_string(const char *key, const char *value)
-{
-    ini_escape_print(key);
-    avio_printf(probe_out, "=");
-    ini_escape_print(value);
-    avio_w8(probe_out, '\n');
-}
-
-/*
- * Alternate format, JSON
- */
-
-static void json_print_header(void)
-{
-    avio_printf(probe_out, "{");
-}
-static void json_print_footer(void)
-{
-    avio_printf(probe_out, "}\n");
-}
-
-static void json_print_array_header(const char *name)
-{
-    if (octx.prefix[octx.level -1].nb_elems)
-        avio_printf(probe_out, ",\n");
-    AVP_INDENT();
-    avio_printf(probe_out, "\"%s\" : ", name);
-    avio_printf(probe_out, "[\n");
-}
-
-static void json_print_array_footer(const char *name)
-{
-    avio_printf(probe_out, "\n");
-    AVP_INDENT();
-    avio_printf(probe_out, "]");
-}
-
-static void json_print_object_header(const char *name)
-{
-    if (octx.prefix[octx.level -1].nb_elems)
-        avio_printf(probe_out, ",\n");
-    AVP_INDENT();
-    if (octx.prefix[octx.level -1].type == OBJECT)
-        avio_printf(probe_out, "\"%s\" : ", name);
-    avio_printf(probe_out, "{\n");
-}
-
-static void json_print_object_footer(const char *name)
-{
-    avio_printf(probe_out, "\n");
-    AVP_INDENT();
-    avio_printf(probe_out, "}");
-}
-
-static void json_print_integer(const char *key, int64_t value)
-{
-    if (octx.prefix[octx.level -1].nb_elems)
-        avio_printf(probe_out, ",\n");
-    AVP_INDENT();
-    avio_printf(probe_out, "\"%s\" : %"PRId64"", key, value);
-}
-
-static void json_escape_print(const char *s)
-{
-    int i = 0;
-    char c = 0;
-
-    while (c = s[i++]) {
-        switch (c) {
-        case '\r': avio_printf(probe_out, "%s", "\\r"); break;
-        case '\n': avio_printf(probe_out, "%s", "\\n"); break;
-        case '\f': avio_printf(probe_out, "%s", "\\f"); break;
-        case '\b': avio_printf(probe_out, "%s", "\\b"); break;
-        case '\t': avio_printf(probe_out, "%s", "\\t"); break;
-        case '\\':
-        case '"' : avio_w8(probe_out, '\\');
-        default:
-            if ((unsigned char)c < 32)
-                avio_printf(probe_out, "\\u00%02x", c & 0xff);
-            else
-                avio_w8(probe_out, c);
-        break;
-        }
-    }
-}
-
-static void json_print_string(const char *key, const char *value)
-{
-    if (octx.prefix[octx.level -1].nb_elems)
-        avio_printf(probe_out, ",\n");
-    AVP_INDENT();
-    avio_w8(probe_out, '\"');
-    json_escape_print(key);
-    avio_printf(probe_out, "\" : \"");
-    json_escape_print(value);
-    avio_w8(probe_out, '\"');
-}
-
-/*
- * old-style pseudo-INI
- */
-static void old_print_object_header(const char *name)
-{
-    char *str, *p;
-
-    if (!strcmp(name, "tags"))
-        return;
-
-    str = p = av_strdup(name);
-    while (*p) {
-        *p = toupper(*p);
-        p++;
-    }
-
-    avio_printf(probe_out, "[%s]\n", str);
-    av_freep(&str);
-}
-
-static void old_print_object_footer(const char *name)
-{
-    char *str, *p;
-
-    if (!strcmp(name, "tags"))
-        return;
-
-    str = p = av_strdup(name);
-    while (*p) {
-        *p = toupper(*p);
-        p++;
-    }
-
-    avio_printf(probe_out, "[/%s]\n", str);
-    av_freep(&str);
-}
-
-static void old_print_string(const char *key, const char *value)
-{
-    if (!strcmp(octx.prefix[octx.level - 1].name, "tags"))
-        avio_printf(probe_out, "TAG:");
-    ini_print_string(key, value);
-}
-
-/*
- * Simple Formatter for single entries.
- */
-
-static void show_format_entry_integer(const char *key, int64_t value)
-{
-    if (key && av_dict_get(fmt_entries_to_show, key, NULL, 0)) {
-        if (nb_fmt_entries_to_show > 1)
-            avio_printf(probe_out, "%s=", key);
-        avio_printf(probe_out, "%"PRId64"\n", value);
-    }
-}
-
-static void show_format_entry_string(const char *key, const char *value)
-{
-    if (key && av_dict_get(fmt_entries_to_show, key, NULL, 0)) {
-        if (nb_fmt_entries_to_show > 1)
-            avio_printf(probe_out, "%s=", key);
-        avio_printf(probe_out, "%s\n", value);
-    }
-}
-
-static void probe_group_enter(const char *name, int type)
-{
-    int64_t count = -1;
-
-    octx.prefix =
-        av_realloc(octx.prefix, sizeof(ProbeElement) * (octx.level + 1));
-
-    if (!octx.prefix || !name) {
-        fprintf(stderr, "Out of memory\n");
-        exit(1);
-    }
-
-    if (octx.level) {
-        ProbeElement *parent = octx.prefix + octx.level -1;
-        if (parent->type == ARRAY)
-            count = parent->nb_elems;
-        parent->nb_elems++;
-    }
-
-    octx.prefix[octx.level++] = (ProbeElement){name, type, count, 0};
-}
-
-static void probe_group_leave(void)
-{
-    --octx.level;
-}
-
-static void probe_header(void)
-{
-    if (octx.print_header)
-        octx.print_header();
-    probe_group_enter("root", OBJECT);
-}
-
-static void probe_footer(void)
-{
-    if (octx.print_footer)
-        octx.print_footer();
-    probe_group_leave();
-}
-
-
-static void probe_array_header(const char *name)
-{
-    if (octx.print_array_header)
-        octx.print_array_header(name);
-
-    probe_group_enter(name, ARRAY);
-}
-
-static void probe_array_footer(const char *name)
-{
-    probe_group_leave();
-    if (octx.print_array_footer)
-        octx.print_array_footer(name);
-}
-
-static void probe_object_header(const char *name)
-{
-    if (octx.print_object_header)
-        octx.print_object_header(name);
-
-    probe_group_enter(name, OBJECT);
-}
-
-static void probe_object_footer(const char *name)
-{
-    probe_group_leave();
-    if (octx.print_object_footer)
-        octx.print_object_footer(name);
-}
-
-static void probe_int(const char *key, int64_t value)
-{
-    octx.print_integer(key, value);
-    octx.prefix[octx.level -1].nb_elems++;
-}
-
-static void probe_str(const char *key, const char *value)
-{
-    octx.print_string(key, value);
-    octx.prefix[octx.level -1].nb_elems++;
-}
-
-static void probe_dict(AVDictionary *dict, const char *name)
-{
-    AVDictionaryEntry *entry = NULL;
-    if (!dict)
-        return;
-    probe_object_header(name);
-    while ((entry = av_dict_get(dict, "", entry, AV_DICT_IGNORE_SUFFIX))) {
-        probe_str(entry->key, entry->value);
-    }
-    probe_object_footer(name);
-}
-
-static char *value_string(char *buf, int buf_size, double val, const char *unit)
-{
-    if (unit == unit_second_str && use_value_sexagesimal_format) {
-        double secs;
-        int hours, mins;
-        secs  = val;
-        mins  = (int)secs / 60;
-        secs  = secs - mins * 60;
-        hours = mins / 60;
-        mins %= 60;
-        snprintf(buf, buf_size, "%d:%02d:%09.6f", hours, mins, secs);
-    } else if (use_value_prefix) {
-        const char *prefix_string;
-        int index;
-
-        if (unit == unit_byte_str && use_byte_value_binary_prefix) {
-            index = (int) log2(val) / 10;
-            index = av_clip(index, 0, FF_ARRAY_ELEMS(binary_unit_prefixes) - 1);
-            val  /= pow(2, index * 10);
-            prefix_string = binary_unit_prefixes[index];
-        } else {
-            index = (int) (log10(val)) / 3;
-            index = av_clip(index, 0, FF_ARRAY_ELEMS(decimal_unit_prefixes) - 1);
-            val  /= pow(10, index * 3);
-            prefix_string = decimal_unit_prefixes[index];
-        }
-        snprintf(buf, buf_size, "%.*f%s%s",
-                 index ? 3 : 0, val,
-                 prefix_string,
-                 show_value_unit ? unit : "");
-    } else {
-        snprintf(buf, buf_size, "%f%s", val, show_value_unit ? unit : "");
-    }
-
-    return buf;
-}
-
-static char *time_value_string(char *buf, int buf_size, int64_t val,
-                               const AVRational *time_base)
-{
-    if (val == AV_NOPTS_VALUE) {
-        snprintf(buf, buf_size, "N/A");
-    } else {
-        value_string(buf, buf_size, val * av_q2d(*time_base), unit_second_str);
-    }
-
-    return buf;
-}
-
-static char *ts_value_string(char *buf, int buf_size, int64_t ts)
-{
-    if (ts == AV_NOPTS_VALUE) {
-        snprintf(buf, buf_size, "N/A");
-    } else {
-        snprintf(buf, buf_size, "%"PRId64, ts);
-    }
-
-    return buf;
-}
-
-static char *rational_string(char *buf, int buf_size, const char *sep,
-                             const AVRational *rat)
-{
-    snprintf(buf, buf_size, "%d%s%d", rat->num, sep, rat->den);
-    return buf;
-}
-
-static char *tag_string(char *buf, int buf_size, int tag)
-{
-    snprintf(buf, buf_size, "0x%04x", tag);
-    return buf;
-}
-
-
-
-static const char *media_type_string(enum AVMediaType media_type)
-{
-    switch (media_type) {
-    case AVMEDIA_TYPE_VIDEO:      return "video";
-    case AVMEDIA_TYPE_AUDIO:      return "audio";
-    case AVMEDIA_TYPE_DATA:       return "data";
-    case AVMEDIA_TYPE_SUBTITLE:   return "subtitle";
-    case AVMEDIA_TYPE_ATTACHMENT: return "attachment";
-    default:                      return "unknown";
-    }
-}
-
-static void show_packet(AVFormatContext *fmt_ctx, AVPacket *pkt)
-{
-    char val_str[128];
-    AVStream *st = fmt_ctx->streams[pkt->stream_index];
-
-    probe_object_header("packet");
-    probe_str("codec_type", media_type_string(st->codec->codec_type));
-    probe_int("stream_index", pkt->stream_index);
-    probe_str("pts", ts_value_string(val_str, sizeof(val_str), pkt->pts));
-    probe_str("pts_time", time_value_string(val_str, sizeof(val_str),
-                                               pkt->pts, &st->time_base));
-    probe_str("dts", ts_value_string(val_str, sizeof(val_str), pkt->dts));
-    probe_str("dts_time", time_value_string(val_str, sizeof(val_str),
-                                               pkt->dts, &st->time_base));
-    probe_str("duration", ts_value_string(val_str, sizeof(val_str),
-                                             pkt->duration));
-    probe_str("duration_time", time_value_string(val_str, sizeof(val_str),
-                                                    pkt->duration,
-                                                    &st->time_base));
-    probe_str("size", value_string(val_str, sizeof(val_str),
-                                      pkt->size, unit_byte_str));
-    probe_int("pos", pkt->pos);
-    probe_str("flags", pkt->flags & AV_PKT_FLAG_KEY ? "K" : "_");
-    probe_object_footer("packet");
-}
-
-static void show_packets(AVFormatContext *fmt_ctx)
-{
-    AVPacket pkt;
-
-    av_init_packet(&pkt);
-    probe_array_header("packets");
-    while (!av_read_frame(fmt_ctx, &pkt))
-        show_packet(fmt_ctx, &pkt);
-    probe_array_footer("packets");
-}
-
-static void show_stream(AVFormatContext *fmt_ctx, int stream_idx)
-{
-    AVStream *stream = fmt_ctx->streams[stream_idx];
-    AVCodecContext *dec_ctx;
-    const AVCodec *dec;
-    const char *profile;
-    char val_str[128];
-    AVRational display_aspect_ratio;
-    const AVPixFmtDescriptor *desc;
-
-    probe_object_header("stream");
-
-    probe_int("index", stream->index);
-
-    if ((dec_ctx = stream->codec)) {
-        if ((dec = dec_ctx->codec)) {
-            probe_str("codec_name", dec->name);
-            probe_str("codec_long_name", dec->long_name);
-        } else {
-            probe_str("codec_name", "unknown");
-        }
-
-        probe_str("codec_type", media_type_string(dec_ctx->codec_type));
-        probe_str("codec_time_base",
-                  rational_string(val_str, sizeof(val_str),
-                                  "/", &dec_ctx->time_base));
-
-        /* print AVI/FourCC tag */
-        av_get_codec_tag_string(val_str, sizeof(val_str), dec_ctx->codec_tag);
-        probe_str("codec_tag_string", val_str);
-        probe_str("codec_tag", tag_string(val_str, sizeof(val_str),
-                                          dec_ctx->codec_tag));
-
-        /* print profile, if there is one */
-        if (dec && (profile = av_get_profile_name(dec, dec_ctx->profile)))
-            probe_str("profile", profile);
-
-        switch (dec_ctx->codec_type) {
-        case AVMEDIA_TYPE_VIDEO:
-            probe_int("width", dec_ctx->width);
-            probe_int("height", dec_ctx->height);
-            probe_int("has_b_frames", dec_ctx->has_b_frames);
-            if (dec_ctx->sample_aspect_ratio.num) {
-                probe_str("sample_aspect_ratio",
-                          rational_string(val_str, sizeof(val_str), ":",
-                          &dec_ctx->sample_aspect_ratio));
-                av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den,
-                          dec_ctx->width  * dec_ctx->sample_aspect_ratio.num,
-                          dec_ctx->height * dec_ctx->sample_aspect_ratio.den,
-                          1024*1024);
-                probe_str("display_aspect_ratio",
-                          rational_string(val_str, sizeof(val_str), ":",
-                          &display_aspect_ratio));
-            }
-            desc = av_pix_fmt_desc_get(dec_ctx->pix_fmt);
-            probe_str("pix_fmt", desc ? desc->name : "unknown");
-            probe_int("level", dec_ctx->level);
-            break;
-
-        case AVMEDIA_TYPE_AUDIO:
-            probe_str("sample_rate",
-                      value_string(val_str, sizeof(val_str),
-                                   dec_ctx->sample_rate,
-                                   unit_hertz_str));
-            probe_int("channels", dec_ctx->channels);
-            probe_int("bits_per_sample",
-                      av_get_bits_per_sample(dec_ctx->codec_id));
-            break;
-        }
-    } else {
-        probe_str("codec_type", "unknown");
-    }
-
-    if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS)
-        probe_int("id", stream->id);
-    probe_str("avg_frame_rate",
-              rational_string(val_str, sizeof(val_str), "/",
-              &stream->avg_frame_rate));
-    probe_str("time_base",
-              rational_string(val_str, sizeof(val_str), "/",
-              &stream->time_base));
-    probe_str("start_time",
-              time_value_string(val_str, sizeof(val_str),
-                                stream->start_time, &stream->time_base));
-    probe_str("duration",
-              time_value_string(val_str, sizeof(val_str),
-                                stream->duration, &stream->time_base));
-    if (stream->nb_frames)
-        probe_int("nb_frames", stream->nb_frames);
-
-    probe_dict(stream->metadata, "tags");
-
-    probe_object_footer("stream");
-}
-
-static void show_format(AVFormatContext *fmt_ctx)
-{
-    char val_str[128];
-    int64_t size = fmt_ctx->pb ? avio_size(fmt_ctx->pb) : -1;
-
-    probe_object_header("format");
-    probe_str("filename",         fmt_ctx->filename);
-    probe_int("nb_streams",       fmt_ctx->nb_streams);
-    probe_str("format_name",      fmt_ctx->iformat->name);
-    probe_str("format_long_name", fmt_ctx->iformat->long_name);
-    probe_str("start_time",
-                       time_value_string(val_str, sizeof(val_str),
-                                         fmt_ctx->start_time, &AV_TIME_BASE_Q));
-    probe_str("duration",
-                       time_value_string(val_str, sizeof(val_str),
-                                         fmt_ctx->duration, &AV_TIME_BASE_Q));
-    probe_str("size",
-                       size >= 0 ? value_string(val_str, sizeof(val_str),
-                                                size, unit_byte_str)
-                                  : "unknown");
-    probe_str("bit_rate",
-                       value_string(val_str, sizeof(val_str),
-                                    fmt_ctx->bit_rate, unit_bit_per_second_str));
-
-    probe_dict(fmt_ctx->metadata, "tags");
-
-    probe_object_footer("format");
-}
-
-static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename)
-{
-    int err, i;
-    AVFormatContext *fmt_ctx = NULL;
-    AVDictionaryEntry *t;
-
-    if ((err = avformat_open_input(&fmt_ctx, filename,
-                                   iformat, &format_opts)) < 0) {
-        print_error(filename, err);
-        return err;
-    }
-    if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
-        av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
-        return AVERROR_OPTION_NOT_FOUND;
-    }
-
-
-    /* fill the streams in the format context */
-    if ((err = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
-        print_error(filename, err);
-        return err;
-    }
-
-    av_dump_format(fmt_ctx, 0, filename, 0);
-
-    /* bind a decoder to each input stream */
-    for (i = 0; i < fmt_ctx->nb_streams; i++) {
-        AVStream *stream = fmt_ctx->streams[i];
-        AVCodec *codec;
-
-        if (stream->codec->codec_id == AV_CODEC_ID_PROBE) {
-            fprintf(stderr, "Failed to probe codec for input stream %d\n",
-                    stream->index);
-        } else if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) {
-            fprintf(stderr,
-                    "Unsupported codec with id %d for input stream %d\n",
-                    stream->codec->codec_id, stream->index);
-        } else if (avcodec_open2(stream->codec, codec, NULL) < 0) {
-            fprintf(stderr, "Error while opening codec for input stream %d\n",
-                    stream->index);
-        }
-    }
-
-    *fmt_ctx_ptr = fmt_ctx;
-    return 0;
-}
-
-static void close_input_file(AVFormatContext **ctx_ptr)
-{
-    int i;
-    AVFormatContext *fmt_ctx = *ctx_ptr;
-
-    /* close decoder for each stream */
-    for (i = 0; i < fmt_ctx->nb_streams; i++) {
-        AVStream *stream = fmt_ctx->streams[i];
-
-        avcodec_close(stream->codec);
-    }
-    avformat_close_input(ctx_ptr);
-}
-
-static int probe_file(const char *filename)
-{
-    AVFormatContext *fmt_ctx;
-    int ret, i;
-
-    if ((ret = open_input_file(&fmt_ctx, filename)))
-        return ret;
-
-    if (do_show_format)
-        show_format(fmt_ctx);
-
-    if (do_show_streams) {
-        probe_array_header("streams");
-        for (i = 0; i < fmt_ctx->nb_streams; i++)
-            show_stream(fmt_ctx, i);
-        probe_array_footer("streams");
-    }
-
-    if (do_show_packets)
-        show_packets(fmt_ctx);
-
-    close_input_file(&fmt_ctx);
-    return 0;
-}
-
-static void show_usage(void)
-{
-    printf("Simple multimedia streams analyzer\n");
-    printf("usage: %s [OPTIONS] [INPUT_FILE]\n", program_name);
-    printf("\n");
-}
-
-static int opt_format(void *optctx, const char *opt, const char *arg)
-{
-    iformat = av_find_input_format(arg);
-    if (!iformat) {
-        fprintf(stderr, "Unknown input format: %s\n", arg);
-        return AVERROR(EINVAL);
-    }
-    return 0;
-}
-
-static int opt_output_format(void *optctx, const char *opt, const char *arg)
-{
-
-    if (!strcmp(arg, "json")) {
-        octx.print_header        = json_print_header;
-        octx.print_footer        = json_print_footer;
-        octx.print_array_header  = json_print_array_header;
-        octx.print_array_footer  = json_print_array_footer;
-        octx.print_object_header = json_print_object_header;
-        octx.print_object_footer = json_print_object_footer;
-
-        octx.print_integer = json_print_integer;
-        octx.print_string  = json_print_string;
-    } else if (!strcmp(arg, "ini")) {
-        octx.print_header        = ini_print_header;
-        octx.print_footer        = ini_print_footer;
-        octx.print_array_header  = ini_print_array_header;
-        octx.print_object_header = ini_print_object_header;
-
-        octx.print_integer = ini_print_integer;
-        octx.print_string  = ini_print_string;
-    } else if (!strcmp(arg, "old")) {
-        octx.print_header        = NULL;
-        octx.print_object_header = old_print_object_header;
-        octx.print_object_footer = old_print_object_footer;
-
-        octx.print_string        = old_print_string;
-    } else {
-        av_log(NULL, AV_LOG_ERROR, "Unsupported formatter %s\n", arg);
-        return AVERROR(EINVAL);
-    }
-    return 0;
-}
-
-static int opt_show_format_entry(void *optctx, const char *opt, const char *arg)
-{
-    do_show_format = 1;
-    nb_fmt_entries_to_show++;
-    octx.print_header        = NULL;
-    octx.print_footer        = NULL;
-    octx.print_array_header  = NULL;
-    octx.print_array_footer  = NULL;
-    octx.print_object_header = NULL;
-    octx.print_object_footer = NULL;
-
-    octx.print_integer = show_format_entry_integer;
-    octx.print_string  = show_format_entry_string;
-    av_dict_set(&fmt_entries_to_show, arg, "", 0);
-    return 0;
-}
-
-static void opt_input_file(void *optctx, const char *arg)
-{
-    if (input_filename) {
-        fprintf(stderr,
-                "Argument '%s' provided as input filename, but '%s' was already specified.\n",
-                arg, input_filename);
-        exit(1);
-    }
-    if (!strcmp(arg, "-"))
-        arg = "pipe:";
-    input_filename = arg;
-}
-
-void show_help_default(const char *opt, const char *arg)
-{
-    av_log_set_callback(log_callback_help);
-    show_usage();
-    show_help_options(options, "Main options:", 0, 0, 0);
-    printf("\n");
-    show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
-}
-
-static int opt_pretty(void *optctx, const char *opt, const char *arg)
-{
-    show_value_unit              = 1;
-    use_value_prefix             = 1;
-    use_byte_value_binary_prefix = 1;
-    use_value_sexagesimal_format = 1;
-    return 0;
-}
-
-static const OptionDef real_options[] = {
-#include "cmdutils_common_opts.h"
-    { "f", HAS_ARG, {.func_arg = opt_format}, "force format", "format" },
-    { "of", HAS_ARG, {.func_arg = opt_output_format}, "output the document either as ini or json", "output_format" },
-    { "unit", OPT_BOOL, {&show_value_unit},
-      "show unit of the displayed values" },
-    { "prefix", OPT_BOOL, {&use_value_prefix},
-      "use SI prefixes for the displayed values" },
-    { "byte_binary_prefix", OPT_BOOL, {&use_byte_value_binary_prefix},
-      "use binary prefixes for byte units" },
-    { "sexagesimal", OPT_BOOL,  {&use_value_sexagesimal_format},
-      "use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" },
-    { "pretty", 0, {.func_arg = opt_pretty},
-      "prettify the format of displayed values, make it more human readable" },
-    { "show_format",  OPT_BOOL, {&do_show_format} , "show format/container info" },
-    { "show_format_entry", HAS_ARG, {.func_arg = opt_show_format_entry},
-      "show a particular entry from the format/container info", "entry" },
-    { "show_packets", OPT_BOOL, {&do_show_packets}, "show packets info" },
-    { "show_streams", OPT_BOOL, {&do_show_streams}, "show streams info" },
-    { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default},
-      "generic catch all option", "" },
-    { NULL, },
-};
-
-static int probe_buf_write(void *opaque, uint8_t *buf, int buf_size)
-{
-    printf("%.*s", buf_size, buf);
-    return 0;
-}
-
-#define AVP_BUFFSIZE 4096
-
-int main(int argc, char **argv)
-{
-    int ret;
-    uint8_t *buffer = av_malloc(AVP_BUFFSIZE);
-
-    if (!buffer)
-        exit(1);
-
-    atexit(exit_program);
-
-    options = real_options;
-    parse_loglevel(argc, argv, options);
-    av_register_all();
-    avformat_network_init();
-    init_opts();
-#if CONFIG_AVDEVICE
-    avdevice_register_all();
-#endif
-
-    show_banner();
-
-    octx.print_header = ini_print_header;
-    octx.print_footer = ini_print_footer;
-
-    octx.print_array_header = ini_print_array_header;
-    octx.print_object_header = ini_print_object_header;
-
-    octx.print_integer = ini_print_integer;
-    octx.print_string = ini_print_string;
-
-    parse_options(NULL, argc, argv, options, opt_input_file);
-
-    if (!input_filename) {
-        show_usage();
-        fprintf(stderr, "You have to specify one input file.\n");
-        fprintf(stderr,
-                "Use -h to get full help or, even better, run 'man %s'.\n",
-                program_name);
-        exit(1);
-    }
-
-    probe_out = avio_alloc_context(buffer, AVP_BUFFSIZE, 1, NULL, NULL,
-                                 probe_buf_write, NULL);
-    if (!probe_out)
-        exit(1);
-
-    probe_header();
-    ret = probe_file(input_filename);
-    probe_footer();
-    avio_flush(probe_out);
-    avio_close(probe_out);
-
-    avformat_network_deinit();
-
-    return ret;
-}
diff --git a/avserver.c b/avserver.c
deleted file mode 100644
index 6b01b15..0000000
--- a/avserver.c
+++ /dev/null
@@ -1,4724 +0,0 @@
-/*
- * Multiple format streaming server
- * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
- *
- * 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
- */
-
-#include "config.h"
-#if !HAVE_CLOSESOCKET
-#define closesocket close
-#endif
-#include <string.h>
-#include <stdlib.h>
-#include "libavformat/avformat.h"
-// FIXME those are internal headers, avserver _really_ shouldn't use them
-#include "libavformat/ffm.h"
-#include "libavformat/network.h"
-#include "libavformat/os_support.h"
-#include "libavformat/rtpdec.h"
-#include "libavformat/rtsp.h"
-#include "libavformat/avio_internal.h"
-#include "libavformat/internal.h"
-#include "libavformat/url.h"
-
-#include "libavutil/avstring.h"
-#include "libavutil/lfg.h"
-#include "libavutil/dict.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/random_seed.h"
-#include "libavutil/parseutils.h"
-#include "libavutil/opt.h"
-#include "libavutil/time.h"
-
-#include <stdarg.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#if HAVE_POLL_H
-#include <poll.h>
-#endif
-#include <errno.h>
-#include <time.h>
-#include <sys/wait.h>
-#include <signal.h>
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include "cmdutils.h"
-
-const char program_name[] = "avserver";
-const int program_birth_year = 2000;
-
-static const OptionDef options[];
-
-enum HTTPState {
-    HTTPSTATE_WAIT_REQUEST,
-    HTTPSTATE_SEND_HEADER,
-    HTTPSTATE_SEND_DATA_HEADER,
-    HTTPSTATE_SEND_DATA,          /* sending TCP or UDP data */
-    HTTPSTATE_SEND_DATA_TRAILER,
-    HTTPSTATE_RECEIVE_DATA,
-    HTTPSTATE_WAIT_FEED,          /* wait for data from the feed */
-    HTTPSTATE_READY,
-
-    RTSPSTATE_WAIT_REQUEST,
-    RTSPSTATE_SEND_REPLY,
-    RTSPSTATE_SEND_PACKET,
-};
-
-static const char *http_state[] = {
-    "HTTP_WAIT_REQUEST",
-    "HTTP_SEND_HEADER",
-
-    "SEND_DATA_HEADER",
-    "SEND_DATA",
-    "SEND_DATA_TRAILER",
-    "RECEIVE_DATA",
-    "WAIT_FEED",
-    "READY",
-
-    "RTSP_WAIT_REQUEST",
-    "RTSP_SEND_REPLY",
-    "RTSP_SEND_PACKET",
-};
-
-#define MAX_STREAMS 20
-
-#define IOBUFFER_INIT_SIZE 8192
-
-/* timeouts are in ms */
-#define HTTP_REQUEST_TIMEOUT (15 * 1000)
-#define RTSP_REQUEST_TIMEOUT (3600 * 24 * 1000)
-
-#define SYNC_TIMEOUT (10 * 1000)
-
-typedef struct RTSPActionServerSetup {
-    uint32_t ipaddr;
-    char transport_option[512];
-} RTSPActionServerSetup;
-
-typedef struct {
-    int64_t count1, count2;
-    int64_t time1, time2;
-} DataRateData;
-
-/* context associated with one connection */
-typedef struct HTTPContext {
-    enum HTTPState state;
-    int fd; /* socket file descriptor */
-    struct sockaddr_in from_addr; /* origin */
-    struct pollfd *poll_entry; /* used when polling */
-    int64_t timeout;
-    uint8_t *buffer_ptr, *buffer_end;
-    int http_error;
-    int post;
-    int chunked_encoding;
-    int chunk_size;               /* 0 if it needs to be read */
-    struct HTTPContext *next;
-    int got_key_frame; /* stream 0 => 1, stream 1 => 2, stream 2=> 4 */
-    int64_t data_count;
-    /* feed input */
-    int feed_fd;
-    /* input format handling */
-    AVFormatContext *fmt_in;
-    int64_t start_time;            /* In milliseconds - this wraps fairly often */
-    int64_t first_pts;            /* initial pts value */
-    int64_t cur_pts;             /* current pts value from the stream in us */
-    int64_t cur_frame_duration;  /* duration of the current frame in us */
-    int cur_frame_bytes;       /* output frame size, needed to compute
-                                  the time at which we send each
-                                  packet */
-    int pts_stream_index;        /* stream we choose as clock reference */
-    int64_t cur_clock;           /* current clock reference value in us */
-    /* output format handling */
-    struct FFStream *stream;
-    /* -1 is invalid stream */
-    int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
-    int switch_feed_streams[MAX_STREAMS]; /* index of streams in the feed */
-    int switch_pending;
-    AVFormatContext fmt_ctx; /* instance of FFStream for one user */
-    int last_packet_sent; /* true if last data packet was sent */
-    int suppress_log;
-    DataRateData datarate;
-    int wmp_client_id;
-    char protocol[16];
-    char method[16];
-    char url[128];
-    int buffer_size;
-    uint8_t *buffer;
-    int is_packetized; /* if true, the stream is packetized */
-    int packet_stream_index; /* current stream for output in state machine */
-
-    /* RTSP state specific */
-    uint8_t *pb_buffer; /* XXX: use that in all the code */
-    AVIOContext *pb;
-    int seq; /* RTSP sequence number */
-
-    /* RTP state specific */
-    enum RTSPLowerTransport rtp_protocol;
-    char session_id[32]; /* session id */
-    AVFormatContext *rtp_ctx[MAX_STREAMS];
-
-    /* RTP/UDP specific */
-    URLContext *rtp_handles[MAX_STREAMS];
-
-    /* RTP/TCP specific */
-    struct HTTPContext *rtsp_c;
-    uint8_t *packet_buffer, *packet_buffer_ptr, *packet_buffer_end;
-} HTTPContext;
-
-/* each generated stream is described here */
-enum StreamType {
-    STREAM_TYPE_LIVE,
-    STREAM_TYPE_STATUS,
-    STREAM_TYPE_REDIRECT,
-};
-
-enum IPAddressAction {
-    IP_ALLOW = 1,
-    IP_DENY,
-};
-
-typedef struct IPAddressACL {
-    struct IPAddressACL *next;
-    enum IPAddressAction action;
-    /* These are in host order */
-    struct in_addr first;
-    struct in_addr last;
-} IPAddressACL;
-
-/* description of each stream of the avserver.conf file */
-typedef struct FFStream {
-    enum StreamType stream_type;
-    char filename[1024];     /* stream filename */
-    struct FFStream *feed;   /* feed we are using (can be null if
-                                coming from file) */
-    AVDictionary *in_opts;   /* input parameters */
-    AVInputFormat *ifmt;       /* if non NULL, force input format */
-    AVOutputFormat *fmt;
-    IPAddressACL *acl;
-    char dynamic_acl[1024];
-    int nb_streams;
-    int prebuffer;      /* Number of millseconds early to start */
-    int64_t max_time;      /* Number of milliseconds to run */
-    int send_on_key;
-    AVStream *streams[MAX_STREAMS];
-    int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
-    char feed_filename[1024]; /* file name of the feed storage, or
-                                 input file name for a stream */
-    char author[512];
-    char title[512];
-    char copyright[512];
-    char comment[512];
-    pid_t pid;  /* of avconv process */
-    time_t pid_start;  /* of avconv process */
-    char **child_argv;
-    struct FFStream *next;
-    unsigned bandwidth; /* bandwidth, in kbits/s */
-    /* RTSP options */
-    char *rtsp_option;
-    /* multicast specific */
-    int is_multicast;
-    struct in_addr multicast_ip;
-    int multicast_port; /* first port used for multicast */
-    int multicast_ttl;
-    int loop; /* if true, send the stream in loops (only meaningful if file) */
-
-    /* feed specific */
-    int feed_opened;     /* true if someone is writing to the feed */
-    int is_feed;         /* true if it is a feed */
-    int readonly;        /* True if writing is prohibited to the file */
-    int truncate;        /* True if feeder connection truncate the feed file */
-    int conns_served;
-    int64_t bytes_served;
-    int64_t feed_max_size;      /* maximum storage size, zero means unlimited */
-    int64_t feed_write_index;   /* current write position in feed (it wraps around) */
-    int64_t feed_size;          /* current size of feed */
-    struct FFStream *next_feed;
-} FFStream;
-
-typedef struct FeedData {
-    long long data_count;
-    float avg_frame_size;   /* frame size averaged over last frames with exponential mean */
-} FeedData;
-
-static struct sockaddr_in my_http_addr;
-static struct sockaddr_in my_rtsp_addr;
-
-static char logfilename[1024];
-static HTTPContext *first_http_ctx;
-static FFStream *first_feed;   /* contains only feeds */
-static FFStream *first_stream; /* contains all streams, including feeds */
-
-static void new_connection(int server_fd, int is_rtsp);
-static void close_connection(HTTPContext *c);
-
-/* HTTP handling */
-static int handle_connection(HTTPContext *c);
-static int http_parse_request(HTTPContext *c);
-static int http_send_data(HTTPContext *c);
-static void compute_status(HTTPContext *c);
-static int open_input_stream(HTTPContext *c, const char *info);
-static int http_start_receive_data(HTTPContext *c);
-static int http_receive_data(HTTPContext *c);
-
-/* RTSP handling */
-static int rtsp_parse_request(HTTPContext *c);
-static void rtsp_cmd_describe(HTTPContext *c, const char *url);
-static void rtsp_cmd_options(HTTPContext *c, const char *url);
-static void rtsp_cmd_setup(HTTPContext *c, const char *url, RTSPMessageHeader *h);
-static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h);
-static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h);
-static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h);
-
-/* SDP handling */
-static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
-                                   struct in_addr my_ip);
-
-/* RTP handling */
-static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
-                                       FFStream *stream, const char *session_id,
-                                       enum RTSPLowerTransport rtp_protocol);
-static int rtp_new_av_stream(HTTPContext *c,
-                             int stream_index, struct sockaddr_in *dest_addr,
-                             HTTPContext *rtsp_c);
-
-static const char *my_program_name;
-static const char *my_program_dir;
-
-static const char *config_filename = "/etc/avserver.conf";
-
-static int avserver_debug;
-static int avserver_daemon;
-static int no_launch;
-static int need_to_start_children;
-
-/* maximum number of simultaneous HTTP connections */
-static unsigned int nb_max_http_connections = 2000;
-static unsigned int nb_max_connections = 5;
-static unsigned int nb_connections;
-
-static uint64_t max_bandwidth = 1000;
-static uint64_t current_bandwidth;
-
-static int64_t cur_time;           // Making this global saves on passing it around everywhere
-
-static AVLFG random_state;
-
-static FILE *logfile = NULL;
-
-/* FIXME: make avserver work with IPv6 */
-/* resolve host with also IP address parsing */
-static int resolve_host(struct in_addr *sin_addr, const char *hostname)
-{
-
-    if (!ff_inet_aton(hostname, sin_addr)) {
-#if HAVE_GETADDRINFO
-        struct addrinfo *ai, *cur;
-        struct addrinfo hints = { 0 };
-        hints.ai_family = AF_INET;
-        if (getaddrinfo(hostname, NULL, &hints, &ai))
-            return -1;
-        /* getaddrinfo returns a linked list of addrinfo structs.
-         * Even if we set ai_family = AF_INET above, make sure
-         * that the returned one actually is of the correct type. */
-        for (cur = ai; cur; cur = cur->ai_next) {
-            if (cur->ai_family == AF_INET) {
-                *sin_addr = ((struct sockaddr_in *)cur->ai_addr)->sin_addr;
-                freeaddrinfo(ai);
-                return 0;
-            }
-        }
-        freeaddrinfo(ai);
-        return -1;
-#else
-        struct hostent *hp;
-        hp = gethostbyname(hostname);
-        if (!hp)
-            return -1;
-        memcpy(sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
-#endif
-    }
-    return 0;
-}
-
-static char *ctime1(char *buf2)
-{
-    time_t ti;
-    char *p;
-
-    ti = time(NULL);
-    p = ctime(&ti);
-    strcpy(buf2, p);
-    p = buf2 + strlen(p) - 1;
-    if (*p == '\n')
-        *p = '\0';
-    return buf2;
-}
-
-static void http_vlog(const char *fmt, va_list vargs)
-{
-    static int print_prefix = 1;
-    if (logfile) {
-        if (print_prefix) {
-            char buf[32];
-            ctime1(buf);
-            fprintf(logfile, "%s ", buf);
-        }
-        print_prefix = strstr(fmt, "\n") != NULL;
-        vfprintf(logfile, fmt, vargs);
-        fflush(logfile);
-    }
-}
-
-#ifdef __GNUC__
-__attribute__ ((format (printf, 1, 2)))
-#endif
-static void http_log(const char *fmt, ...)
-{
-    va_list vargs;
-    va_start(vargs, fmt);
-    http_vlog(fmt, vargs);
-    va_end(vargs);
-}
-
-static void http_av_log(void *ptr, int level, const char *fmt, va_list vargs)
-{
-    static int print_prefix = 1;
-    AVClass *avc = ptr ? *(AVClass**)ptr : NULL;
-    if (level > av_log_get_level())
-        return;
-    if (print_prefix && avc)
-        http_log("[%s @ %p]", avc->item_name(ptr), ptr);
-    print_prefix = strstr(fmt, "\n") != NULL;
-    http_vlog(fmt, vargs);
-}
-
-static void log_connection(HTTPContext *c)
-{
-    if (c->suppress_log)
-        return;
-
-    http_log("%s - - [%s] \"%s %s\" %d %"PRId64"\n",
-             inet_ntoa(c->from_addr.sin_addr), c->method, c->url,
-             c->protocol, (c->http_error ? c->http_error : 200), c->data_count);
-}
-
-static void update_datarate(DataRateData *drd, int64_t count)
-{
-    if (!drd->time1 && !drd->count1) {
-        drd->time1 = drd->time2 = cur_time;
-        drd->count1 = drd->count2 = count;
-    } else if (cur_time - drd->time2 > 5000) {
-        drd->time1 = drd->time2;
-        drd->count1 = drd->count2;
-        drd->time2 = cur_time;
-        drd->count2 = count;
-    }
-}
-
-/* In bytes per second */
-static int compute_datarate(DataRateData *drd, int64_t count)
-{
-    if (cur_time == drd->time1)
-        return 0;
-
-    return ((count - drd->count1) * 1000) / (cur_time - drd->time1);
-}
-
-
-static void start_children(FFStream *feed)
-{
-    if (no_launch)
-        return;
-
-    for (; feed; feed = feed->next) {
-        if (feed->child_argv && !feed->pid) {
-            feed->pid_start = time(0);
-
-            feed->pid = fork();
-
-            if (feed->pid < 0) {
-                http_log("Unable to create children\n");
-                exit(1);
-            }
-            if (!feed->pid) {
-                /* In child */
-                char pathname[1024];
-                char *slash;
-                int i;
-
-                av_strlcpy(pathname, my_program_name, sizeof(pathname));
-
-                slash = strrchr(pathname, '/');
-                if (!slash)
-                    slash = pathname;
-                else
-                    slash++;
-                strcpy(slash, "avconv");
-
-                http_log("Launch command line: ");
-                http_log("%s ", pathname);
-                for (i = 1; feed->child_argv[i] && feed->child_argv[i][0]; i++)
-                    http_log("%s ", feed->child_argv[i]);
-                http_log("\n");
-
-                for (i = 3; i < 256; i++)
-                    close(i);
-
-                if (!avserver_debug) {
-                    i = open("/dev/null", O_RDWR);
-                    if (i != -1) {
-                        dup2(i, 0);
-                        dup2(i, 1);
-                        dup2(i, 2);
-                        close(i);
-                    }
-                }
-
-                /* This is needed to make relative pathnames work */
-                chdir(my_program_dir);
-
-                signal(SIGPIPE, SIG_DFL);
-
-                execvp(pathname, feed->child_argv);
-
-                _exit(1);
-            }
-        }
-    }
-}
-
-/* open a listening socket */
-static int socket_open_listen(struct sockaddr_in *my_addr)
-{
-    int server_fd, tmp;
-
-    server_fd = socket(AF_INET,SOCK_STREAM,0);
-    if (server_fd < 0) {
-        perror ("socket");
-        return -1;
-    }
-
-    tmp = 1;
-    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp));
-
-    my_addr->sin_family = AF_INET;
-    if (bind (server_fd, (struct sockaddr *) my_addr, sizeof (*my_addr)) < 0) {
-        char bindmsg[32];
-        snprintf(bindmsg, sizeof(bindmsg), "bind(port %d)", ntohs(my_addr->sin_port));
-        perror (bindmsg);
-        closesocket(server_fd);
-        return -1;
-    }
-
-    if (listen (server_fd, 5) < 0) {
-        perror ("listen");
-        closesocket(server_fd);
-        return -1;
-    }
-    ff_socket_nonblock(server_fd, 1);
-
-    return server_fd;
-}
-
-/* start all multicast streams */
-static void start_multicast(void)
-{
-    FFStream *stream;
-    char session_id[32];
-    HTTPContext *rtp_c;
-    struct sockaddr_in dest_addr;
-    int default_port, stream_index;
-
-    default_port = 6000;
-    for(stream = first_stream; stream != NULL; stream = stream->next) {
-        if (stream->is_multicast) {
-            /* open the RTP connection */
-            snprintf(session_id, sizeof(session_id), "%08x%08x",
-                     av_lfg_get(&random_state), av_lfg_get(&random_state));
-
-            /* choose a port if none given */
-            if (stream->multicast_port == 0) {
-                stream->multicast_port = default_port;
-                default_port += 100;
-            }
-
-            dest_addr.sin_family = AF_INET;
-            dest_addr.sin_addr = stream->multicast_ip;
-            dest_addr.sin_port = htons(stream->multicast_port);
-
-            rtp_c = rtp_new_connection(&dest_addr, stream, session_id,
-                                       RTSP_LOWER_TRANSPORT_UDP_MULTICAST);
-            if (!rtp_c)
-                continue;
-
-            if (open_input_stream(rtp_c, "") < 0) {
-                http_log("Could not open input stream for stream '%s'\n",
-                         stream->filename);
-                continue;
-            }
-
-            /* open each RTP stream */
-            for(stream_index = 0; stream_index < stream->nb_streams;
-                stream_index++) {
-                dest_addr.sin_port = htons(stream->multicast_port +
-                                           2 * stream_index);
-                if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, NULL) < 0) {
-                    http_log("Could not open output stream '%s/streamid=%d'\n",
-                             stream->filename, stream_index);
-                    exit(1);
-                }
-            }
-
-            /* change state to send data */
-            rtp_c->state = HTTPSTATE_SEND_DATA;
-        }
-    }
-}
-
-/* main loop of the http server */
-static int http_server(void)
-{
-    int server_fd = 0, rtsp_server_fd = 0;
-    int ret, delay, delay1;
-    struct pollfd *poll_table, *poll_entry;
-    HTTPContext *c, *c_next;
-
-    if(!(poll_table = av_mallocz((nb_max_http_connections + 2)*sizeof(*poll_table)))) {
-        http_log("Impossible to allocate a poll table handling %d connections.\n", nb_max_http_connections);
-        return -1;
-    }
-
-    if (my_http_addr.sin_port) {
-        server_fd = socket_open_listen(&my_http_addr);
-        if (server_fd < 0)
-            return -1;
-    }
-
-    if (my_rtsp_addr.sin_port) {
-        rtsp_server_fd = socket_open_listen(&my_rtsp_addr);
-        if (rtsp_server_fd < 0)
-            return -1;
-    }
-
-    if (!rtsp_server_fd && !server_fd) {
-        http_log("HTTP and RTSP disabled.\n");
-        return -1;
-    }
-
-    http_log("AVserver started.\n");
-
-    start_children(first_feed);
-
-    start_multicast();
-
-    for(;;) {
-        poll_entry = poll_table;
-        if (server_fd) {
-            poll_entry->fd = server_fd;
-            poll_entry->events = POLLIN;
-            poll_entry++;
-        }
-        if (rtsp_server_fd) {
-            poll_entry->fd = rtsp_server_fd;
-            poll_entry->events = POLLIN;
-            poll_entry++;
-        }
-
-        /* wait for events on each HTTP handle */
-        c = first_http_ctx;
-        delay = 1000;
-        while (c != NULL) {
-            int fd;
-            fd = c->fd;
-            switch(c->state) {
-            case HTTPSTATE_SEND_HEADER:
-            case RTSPSTATE_SEND_REPLY:
-            case RTSPSTATE_SEND_PACKET:
-                c->poll_entry = poll_entry;
-                poll_entry->fd = fd;
-                poll_entry->events = POLLOUT;
-                poll_entry++;
-                break;
-            case HTTPSTATE_SEND_DATA_HEADER:
-            case HTTPSTATE_SEND_DATA:
-            case HTTPSTATE_SEND_DATA_TRAILER:
-                if (!c->is_packetized) {
-                    /* for TCP, we output as much as we can (may need to put a limit) */
-                    c->poll_entry = poll_entry;
-                    poll_entry->fd = fd;
-                    poll_entry->events = POLLOUT;
-                    poll_entry++;
-                } else {
-                    /* when avserver is doing the timing, we work by
-                       looking at which packet need to be sent every
-                       10 ms */
-                    delay1 = 10; /* one tick wait XXX: 10 ms assumed */
-                    if (delay1 < delay)
-                        delay = delay1;
-                }
-                break;
-            case HTTPSTATE_WAIT_REQUEST:
-            case HTTPSTATE_RECEIVE_DATA:
-            case HTTPSTATE_WAIT_FEED:
-            case RTSPSTATE_WAIT_REQUEST:
-                /* need to catch errors */
-                c->poll_entry = poll_entry;
-                poll_entry->fd = fd;
-                poll_entry->events = POLLIN;/* Maybe this will work */
-                poll_entry++;
-                break;
-            default:
-                c->poll_entry = NULL;
-                break;
-            }
-            c = c->next;
-        }
-
-        /* wait for an event on one connection. We poll at least every
-           second to handle timeouts */
-        do {
-            ret = poll(poll_table, poll_entry - poll_table, delay);
-            if (ret < 0 && ff_neterrno() != AVERROR(EAGAIN) &&
-                ff_neterrno() != AVERROR(EINTR))
-                return -1;
-        } while (ret < 0);
-
-        cur_time = av_gettime() / 1000;
-
-        if (need_to_start_children) {
-            need_to_start_children = 0;
-            start_children(first_feed);
-        }
-
-        /* now handle the events */
-        for(c = first_http_ctx; c != NULL; c = c_next) {
-            c_next = c->next;
-            if (handle_connection(c) < 0) {
-                /* close and free the connection */
-                log_connection(c);
-                close_connection(c);
-            }
-        }
-
-        poll_entry = poll_table;
-        if (server_fd) {
-            /* new HTTP connection request ? */
-            if (poll_entry->revents & POLLIN)
-                new_connection(server_fd, 0);
-            poll_entry++;
-        }
-        if (rtsp_server_fd) {
-            /* new RTSP connection request ? */
-            if (poll_entry->revents & POLLIN)
-                new_connection(rtsp_server_fd, 1);
-        }
-    }
-}
-
-/* start waiting for a new HTTP/RTSP request */
-static void start_wait_request(HTTPContext *c, int is_rtsp)
-{
-    c->buffer_ptr = c->buffer;
-    c->buffer_end = c->buffer + c->buffer_size - 1; /* leave room for '\0' */
-
-    if (is_rtsp) {
-        c->timeout = cur_time + RTSP_REQUEST_TIMEOUT;
-        c->state = RTSPSTATE_WAIT_REQUEST;
-    } else {
-        c->timeout = cur_time + HTTP_REQUEST_TIMEOUT;
-        c->state = HTTPSTATE_WAIT_REQUEST;
-    }
-}
-
-static void http_send_too_busy_reply(int fd)
-{
-    char buffer[300];
-    int len = snprintf(buffer, sizeof(buffer),
-                       "HTTP/1.0 503 Server too busy\r\n"
-                       "Content-type: text/html\r\n"
-                       "\r\n"
-                       "<html><head><title>Too busy</title></head><body>\r\n"
-                       "<p>The server is too busy to serve your request at this time.</p>\r\n"
-                       "<p>The number of current connections is %d, and this exceeds the limit of %d.</p>\r\n"
-                       "</body></html>\r\n",
-                       nb_connections, nb_max_connections);
-    send(fd, buffer, len, 0);
-}
-
-
-static void new_connection(int server_fd, int is_rtsp)
-{
-    struct sockaddr_in from_addr;
-    int fd, len;
-    HTTPContext *c = NULL;
-
-    len = sizeof(from_addr);
-    fd = accept(server_fd, (struct sockaddr *)&from_addr,
-                &len);
-    if (fd < 0) {
-        http_log("error during accept %s\n", strerror(errno));
-        return;
-    }
-    ff_socket_nonblock(fd, 1);
-
-    if (nb_connections >= nb_max_connections) {
-        http_send_too_busy_reply(fd);
-        goto fail;
-    }
-
-    /* add a new connection */
-    c = av_mallocz(sizeof(HTTPContext));
-    if (!c)
-        goto fail;
-
-    c->fd = fd;
-    c->poll_entry = NULL;
-    c->from_addr = from_addr;
-    c->buffer_size = IOBUFFER_INIT_SIZE;
-    c->buffer = av_malloc(c->buffer_size);
-    if (!c->buffer)
-        goto fail;
-
-    c->next = first_http_ctx;
-    first_http_ctx = c;
-    nb_connections++;
-
-    start_wait_request(c, is_rtsp);
-
-    return;
-
- fail:
-    if (c) {
-        av_free(c->buffer);
-        av_free(c);
-    }
-    closesocket(fd);
-}
-
-static void close_connection(HTTPContext *c)
-{
-    HTTPContext **cp, *c1;
-    int i, nb_streams;
-    AVFormatContext *ctx;
-    URLContext *h;
-    AVStream *st;
-
-    /* remove connection from list */
-    cp = &first_http_ctx;
-    while ((*cp) != NULL) {
-        c1 = *cp;
-        if (c1 == c)
-            *cp = c->next;
-        else
-            cp = &c1->next;
-    }
-
-    /* remove references, if any (XXX: do it faster) */
-    for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
-        if (c1->rtsp_c == c)
-            c1->rtsp_c = NULL;
-    }
-
-    /* remove connection associated resources */
-    if (c->fd >= 0)
-        closesocket(c->fd);
-    if (c->fmt_in) {
-        /* close each frame parser */
-        for(i=0;i<c->fmt_in->nb_streams;i++) {
-            st = c->fmt_in->streams[i];
-            if (st->codec->codec)
-                avcodec_close(st->codec);
-        }
-        avformat_close_input(&c->fmt_in);
-    }
-
-    /* free RTP output streams if any */
-    nb_streams = 0;
-    if (c->stream)
-        nb_streams = c->stream->nb_streams;
-
-    for(i=0;i<nb_streams;i++) {
-        ctx = c->rtp_ctx[i];
-        if (ctx) {
-            av_write_trailer(ctx);
-            av_dict_free(&ctx->metadata);
-            av_free(ctx->streams[0]);
-            av_free(ctx);
-        }
-        h = c->rtp_handles[i];
-        if (h)
-            ffurl_close(h);
-    }
-
-    ctx = &c->fmt_ctx;
-
-    if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) {
-        if (ctx->oformat) {
-            /* prepare header */
-            if (avio_open_dyn_buf(&ctx->pb) >= 0) {
-                av_write_trailer(ctx);
-                av_freep(&c->pb_buffer);
-                avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
-            }
-        }
-    }
-
-    for(i=0; i<ctx->nb_streams; i++)
-        av_free(ctx->streams[i]);
-
-    if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE)
-        current_bandwidth -= c->stream->bandwidth;
-
-    /* signal that there is no feed if we are the feeder socket */
-    if (c->state == HTTPSTATE_RECEIVE_DATA && c->stream) {
-        c->stream->feed_opened = 0;
-        close(c->feed_fd);
-    }
-
-    av_freep(&c->pb_buffer);
-    av_freep(&c->packet_buffer);
-    av_free(c->buffer);
-    av_free(c);
-    nb_connections--;
-}
-
-static int handle_connection(HTTPContext *c)
-{
-    int len, ret;
-
-    switch(c->state) {
-    case HTTPSTATE_WAIT_REQUEST:
-    case RTSPSTATE_WAIT_REQUEST:
-        /* timeout ? */
-        if ((c->timeout - cur_time) < 0)
-            return -1;
-        if (c->poll_entry->revents & (POLLERR | POLLHUP))
-            return -1;
-
-        /* no need to read if no events */
-        if (!(c->poll_entry->revents & POLLIN))
-            return 0;
-        /* read the data */
-    read_loop:
-        len = recv(c->fd, c->buffer_ptr, 1, 0);
-        if (len < 0) {
-            if (ff_neterrno() != AVERROR(EAGAIN) &&
-                ff_neterrno() != AVERROR(EINTR))
-                return -1;
-        } else if (len == 0) {
-            return -1;
-        } else {
-            /* search for end of request. */
-            uint8_t *ptr;
-            c->buffer_ptr += len;
-            ptr = c->buffer_ptr;
-            if ((ptr >= c->buffer + 2 && !memcmp(ptr-2, "\n\n", 2)) ||
-                (ptr >= c->buffer + 4 && !memcmp(ptr-4, "\r\n\r\n", 4))) {
-                /* request found : parse it and reply */
-                if (c->state == HTTPSTATE_WAIT_REQUEST) {
-                    ret = http_parse_request(c);
-                } else {
-                    ret = rtsp_parse_request(c);
-                }
-                if (ret < 0)
-                    return -1;
-            } else if (ptr >= c->buffer_end) {
-                /* request too long: cannot do anything */
-                return -1;
-            } else goto read_loop;
-        }
-        break;
-
-    case HTTPSTATE_SEND_HEADER:
-        if (c->poll_entry->revents & (POLLERR | POLLHUP))
-            return -1;
-
-        /* no need to write if no events */
-        if (!(c->poll_entry->revents & POLLOUT))
-            return 0;
-        len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
-        if (len < 0) {
-            if (ff_neterrno() != AVERROR(EAGAIN) &&
-                ff_neterrno() != AVERROR(EINTR)) {
-                /* error : close connection */
-                av_freep(&c->pb_buffer);
-                return -1;
-            }
-        } else {
-            c->buffer_ptr += len;
-            if (c->stream)
-                c->stream->bytes_served += len;
-            c->data_count += len;
-            if (c->buffer_ptr >= c->buffer_end) {
-                av_freep(&c->pb_buffer);
-                /* if error, exit */
-                if (c->http_error)
-                    return -1;
-                /* all the buffer was sent : synchronize to the incoming stream */
-                c->state = HTTPSTATE_SEND_DATA_HEADER;
-                c->buffer_ptr = c->buffer_end = c->buffer;
-            }
-        }
-        break;
-
-    case HTTPSTATE_SEND_DATA:
-    case HTTPSTATE_SEND_DATA_HEADER:
-    case HTTPSTATE_SEND_DATA_TRAILER:
-        /* for packetized output, we consider we can always write (the
-           input streams sets the speed). It may be better to verify
-           that we do not rely too much on the kernel queues */
-        if (!c->is_packetized) {
-            if (c->poll_entry->revents & (POLLERR | POLLHUP))
-                return -1;
-
-            /* no need to read if no events */
-            if (!(c->poll_entry->revents & POLLOUT))
-                return 0;
-        }
-        if (http_send_data(c) < 0)
-            return -1;
-        /* close connection if trailer sent */
-        if (c->state == HTTPSTATE_SEND_DATA_TRAILER)
-            return -1;
-        break;
-    case HTTPSTATE_RECEIVE_DATA:
-        /* no need to read if no events */
-        if (c->poll_entry->revents & (POLLERR | POLLHUP))
-            return -1;
-        if (!(c->poll_entry->revents & POLLIN))
-            return 0;
-        if (http_receive_data(c) < 0)
-            return -1;
-        break;
-    case HTTPSTATE_WAIT_FEED:
-        /* no need to read if no events */
-        if (c->poll_entry->revents & (POLLIN | POLLERR | POLLHUP))
-            return -1;
-
-        /* nothing to do, we'll be waken up by incoming feed packets */
-        break;
-
-    case RTSPSTATE_SEND_REPLY:
-        if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
-            av_freep(&c->pb_buffer);
-            return -1;
-        }
-        /* no need to write if no events */
-        if (!(c->poll_entry->revents & POLLOUT))
-            return 0;
-        len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
-        if (len < 0) {
-            if (ff_neterrno() != AVERROR(EAGAIN) &&
-                ff_neterrno() != AVERROR(EINTR)) {
-                /* error : close connection */
-                av_freep(&c->pb_buffer);
-                return -1;
-            }
-        } else {
-            c->buffer_ptr += len;
-            c->data_count += len;
-            if (c->buffer_ptr >= c->buffer_end) {
-                /* all the buffer was sent : wait for a new request */
-                av_freep(&c->pb_buffer);
-                start_wait_request(c, 1);
-            }
-        }
-        break;
-    case RTSPSTATE_SEND_PACKET:
-        if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
-            av_freep(&c->packet_buffer);
-            return -1;
-        }
-        /* no need to write if no events */
-        if (!(c->poll_entry->revents & POLLOUT))
-            return 0;
-        len = send(c->fd, c->packet_buffer_ptr,
-                    c->packet_buffer_end - c->packet_buffer_ptr, 0);
-        if (len < 0) {
-            if (ff_neterrno() != AVERROR(EAGAIN) &&
-                ff_neterrno() != AVERROR(EINTR)) {
-                /* error : close connection */
-                av_freep(&c->packet_buffer);
-                return -1;
-            }
-        } else {
-            c->packet_buffer_ptr += len;
-            if (c->packet_buffer_ptr >= c->packet_buffer_end) {
-                /* all the buffer was sent : wait for a new request */
-                av_freep(&c->packet_buffer);
-                c->state = RTSPSTATE_WAIT_REQUEST;
-            }
-        }
-        break;
-    case HTTPSTATE_READY:
-        /* nothing to do */
-        break;
-    default:
-        return -1;
-    }
-    return 0;
-}
-
-static int extract_rates(char *rates, int ratelen, const char *request)
-{
-    const char *p;
-
-    for (p = request; *p && *p != '\r' && *p != '\n'; ) {
-        if (av_strncasecmp(p, "Pragma:", 7) == 0) {
-            const char *q = p + 7;
-
-            while (*q && *q != '\n' && isspace(*q))
-                q++;
-
-            if (av_strncasecmp(q, "stream-switch-entry=", 20) == 0) {
-                int stream_no;
-                int rate_no;
-
-                q += 20;
-
-                memset(rates, 0xff, ratelen);
-
-                while (1) {
-                    while (*q && *q != '\n' && *q != ':')
-                        q++;
-
-                    if (sscanf(q, ":%d:%d", &stream_no, &rate_no) != 2)
-                        break;
-
-                    stream_no--;
-                    if (stream_no < ratelen && stream_no >= 0)
-                        rates[stream_no] = rate_no;
-
-                    while (*q && *q != '\n' && !isspace(*q))
-                        q++;
-                }
-
-                return 1;
-            }
-        }
-        p = strchr(p, '\n');
-        if (!p)
-            break;
-
-        p++;
-    }
-
-    return 0;
-}
-
-static int find_stream_in_feed(FFStream *feed, AVCodecContext *codec, int bit_rate)
-{
-    int i;
-    int best_bitrate = 100000000;
-    int best = -1;
-
-    for (i = 0; i < feed->nb_streams; i++) {
-        AVCodecContext *feed_codec = feed->streams[i]->codec;
-
-        if (feed_codec->codec_id != codec->codec_id ||
-            feed_codec->sample_rate != codec->sample_rate ||
-            feed_codec->width != codec->width ||
-            feed_codec->height != codec->height)
-            continue;
-
-        /* Potential stream */
-
-        /* We want the fastest stream less than bit_rate, or the slowest
-         * faster than bit_rate
-         */
-
-        if (feed_codec->bit_rate <= bit_rate) {
-            if (best_bitrate > bit_rate || feed_codec->bit_rate > best_bitrate) {
-                best_bitrate = feed_codec->bit_rate;
-                best = i;
-            }
-        } else {
-            if (feed_codec->bit_rate < best_bitrate) {
-                best_bitrate = feed_codec->bit_rate;
-                best = i;
-            }
-        }
-    }
-
-    return best;
-}
-
-static int modify_current_stream(HTTPContext *c, char *rates)
-{
-    int i;
-    FFStream *req = c->stream;
-    int action_required = 0;
-
-    /* Not much we can do for a feed */
-    if (!req->feed)
-        return 0;
-
-    for (i = 0; i < req->nb_streams; i++) {
-        AVCodecContext *codec = req->streams[i]->codec;
-
-        switch(rates[i]) {
-            case 0:
-                c->switch_feed_streams[i] = req->feed_streams[i];
-                break;
-            case 1:
-                c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 2);
-                break;
-            case 2:
-                /* Wants off or slow */
-                c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 4);
-#ifdef WANTS_OFF
-                /* This doesn't work well when it turns off the only stream! */
-                c->switch_feed_streams[i] = -2;
-                c->feed_streams[i] = -2;
-#endif
-                break;
-        }
-
-        if (c->switch_feed_streams[i] >= 0 && c->switch_feed_streams[i] != c->feed_streams[i])
-            action_required = 1;
-    }
-
-    return action_required;
-}
-
-/* XXX: factorize in utils.c ? */
-/* XXX: take care with different space meaning */
-static void skip_spaces(const char **pp)
-{
-    const char *p;
-    p = *pp;
-    while (*p == ' ' || *p == '\t')
-        p++;
-    *pp = p;
-}
-
-static void get_word(char *buf, int buf_size, const char **pp)
-{
-    const char *p;
-    char *q;
-
-    p = *pp;
-    skip_spaces(&p);
-    q = buf;
-    while (!isspace(*p) && *p != '\0') {
-        if ((q - buf) < buf_size - 1)
-            *q++ = *p;
-        p++;
-    }
-    if (buf_size > 0)
-        *q = '\0';
-    *pp = p;
-}
-
-static void get_arg(char *buf, int buf_size, const char **pp)
-{
-    const char *p;
-    char *q;
-    int quote;
-
-    p = *pp;
-    while (isspace(*p)) p++;
-    q = buf;
-    quote = 0;
-    if (*p == '\"' || *p == '\'')
-        quote = *p++;
-    for(;;) {
-        if (quote) {
-            if (*p == quote)
-                break;
-        } else {
-            if (isspace(*p))
-                break;
-        }
-        if (*p == '\0')
-            break;
-        if ((q - buf) < buf_size - 1)
-            *q++ = *p;
-        p++;
-    }
-    *q = '\0';
-    if (quote && *p == quote)
-        p++;
-    *pp = p;
-}
-
-static void parse_acl_row(FFStream *stream, FFStream* feed, IPAddressACL *ext_acl,
-                         const char *p, const char *filename, int line_num)
-{
-    char arg[1024];
-    IPAddressACL acl;
-    int errors = 0;
-
-    get_arg(arg, sizeof(arg), &p);
-    if (av_strcasecmp(arg, "allow") == 0)
-        acl.action = IP_ALLOW;
-    else if (av_strcasecmp(arg, "deny") == 0)
-        acl.action = IP_DENY;
-    else {
-        fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n",
-                filename, line_num, arg);
-        errors++;
-    }
-
-    get_arg(arg, sizeof(arg), &p);
-
-    if (resolve_host(&acl.first, arg) != 0) {
-        fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
-                filename, line_num, arg);
-        errors++;
-    } else
-        acl.last = acl.first;
-
-    get_arg(arg, sizeof(arg), &p);
-
-    if (arg[0]) {
-        if (resolve_host(&acl.last, arg) != 0) {
-            fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
-                    filename, line_num, arg);
-            errors++;
-        }
-    }
-
-    if (!errors) {
-        IPAddressACL *nacl = av_mallocz(sizeof(*nacl));
-        IPAddressACL **naclp = 0;
-
-        acl.next = 0;
-        *nacl = acl;
-
-        if (stream)
-            naclp = &stream->acl;
-        else if (feed)
-            naclp = &feed->acl;
-        else if (ext_acl)
-            naclp = &ext_acl;
-        else {
-            fprintf(stderr, "%s:%d: ACL found not in <stream> or <feed>\n",
-                    filename, line_num);
-            errors++;
-        }
-
-        if (naclp) {
-            while (*naclp)
-                naclp = &(*naclp)->next;
-
-            *naclp = nacl;
-        }
-    }
-}
-
-
-static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c)
-{
-    FILE* f;
-    char line[1024];
-    char  cmd[1024];
-    IPAddressACL *acl = NULL;
-    int line_num = 0;
-    const char *p;
-
-    f = fopen(stream->dynamic_acl, "r");
-    if (!f) {
-        perror(stream->dynamic_acl);
-        return NULL;
-    }
-
-    acl = av_mallocz(sizeof(IPAddressACL));
-
-    /* Build ACL */
-    for(;;) {
-        if (fgets(line, sizeof(line), f) == NULL)
-            break;
-        line_num++;
-        p = line;
-        while (isspace(*p))
-            p++;
-        if (*p == '\0' || *p == '#')
-            continue;
-        get_arg(cmd, sizeof(cmd), &p);
-
-        if (!av_strcasecmp(cmd, "ACL"))
-            parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num);
-    }
-    fclose(f);
-    return acl;
-}
-
-
-static void free_acl_list(IPAddressACL *in_acl)
-{
-    IPAddressACL *pacl,*pacl2;
-
-    pacl = in_acl;
-    while(pacl) {
-        pacl2 = pacl;
-        pacl = pacl->next;
-        av_freep(pacl2);
-    }
-}
-
-static int validate_acl_list(IPAddressACL *in_acl, HTTPContext *c)
-{
-    enum IPAddressAction last_action = IP_DENY;
-    IPAddressACL *acl;
-    struct in_addr *src = &c->from_addr.sin_addr;
-    unsigned long src_addr = src->s_addr;
-
-    for (acl = in_acl; acl; acl = acl->next) {
-        if (src_addr >= acl->first.s_addr && src_addr <= acl->last.s_addr)
-            return (acl->action == IP_ALLOW) ? 1 : 0;
-        last_action = acl->action;
-    }
-
-    /* Nothing matched, so return not the last action */
-    return (last_action == IP_DENY) ? 1 : 0;
-}
-
-static int validate_acl(FFStream *stream, HTTPContext *c)
-{
-    int ret = 0;
-    IPAddressACL *acl;
-
-
-    /* if stream->acl is null validate_acl_list will return 1 */
-    ret = validate_acl_list(stream->acl, c);
-
-    if (stream->dynamic_acl[0]) {
-        acl = parse_dynamic_acl(stream, c);
-
-        ret = validate_acl_list(acl, c);
-
-        free_acl_list(acl);
-    }
-
-    return ret;
-}
-
-/* compute the real filename of a file by matching it without its
-   extensions to all the stream filenames */
-static void compute_real_filename(char *filename, int max_size)
-{
-    char file1[1024];
-    char file2[1024];
-    char *p;
-    FFStream *stream;
-
-    /* compute filename by matching without the file extensions */
-    av_strlcpy(file1, filename, sizeof(file1));
-    p = strrchr(file1, '.');
-    if (p)
-        *p = '\0';
-    for(stream = first_stream; stream != NULL; stream = stream->next) {
-        av_strlcpy(file2, stream->filename, sizeof(file2));
-        p = strrchr(file2, '.');
-        if (p)
-            *p = '\0';
-        if (!strcmp(file1, file2)) {
-            av_strlcpy(filename, stream->filename, max_size);
-            break;
-        }
-    }
-}
-
-enum RedirType {
-    REDIR_NONE,
-    REDIR_ASX,
-    REDIR_RAM,
-    REDIR_ASF,
-    REDIR_RTSP,
-    REDIR_SDP,
-};
-
-/* parse http request and prepare header */
-static int http_parse_request(HTTPContext *c)
-{
-    char *p;
-    enum RedirType redir_type;
-    char cmd[32];
-    char info[1024], filename[1024];
-    char url[1024], *q;
-    char protocol[32];
-    char msg[1024];
-    const char *mime_type;
-    FFStream *stream;
-    int i;
-    char ratebuf[32];
-    char *useragent = 0;
-
-    p = c->buffer;
-    get_word(cmd, sizeof(cmd), (const char **)&p);
-    av_strlcpy(c->method, cmd, sizeof(c->method));
-
-    if (!strcmp(cmd, "GET"))
-        c->post = 0;
-    else if (!strcmp(cmd, "POST"))
-        c->post = 1;
-    else
-        return -1;
-
-    get_word(url, sizeof(url), (const char **)&p);
-    av_strlcpy(c->url, url, sizeof(c->url));
-
-    get_word(protocol, sizeof(protocol), (const char **)&p);
-    if (strcmp(protocol, "HTTP/1.0") && strcmp(protocol, "HTTP/1.1"))
-        return -1;
-
-    av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
-
-    if (avserver_debug)
-        http_log("%s - - New connection: %s %s\n", inet_ntoa(c->from_addr.sin_addr), cmd, url);
-
-    /* find the filename and the optional info string in the request */
-    p = strchr(url, '?');
-    if (p) {
-        av_strlcpy(info, p, sizeof(info));
-        *p = '\0';
-    } else
-        info[0] = '\0';
-
-    av_strlcpy(filename, url + ((*url == '/') ? 1 : 0), sizeof(filename)-1);
-
-    for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
-        if (av_strncasecmp(p, "User-Agent:", 11) == 0) {
-            useragent = p + 11;
-            if (*useragent && *useragent != '\n' && isspace(*useragent))
-                useragent++;
-            break;
-        }
-        p = strchr(p, '\n');
-        if (!p)
-            break;
-
-        p++;
-    }
-
-    redir_type = REDIR_NONE;
-    if (av_match_ext(filename, "asx")) {
-        redir_type = REDIR_ASX;
-        filename[strlen(filename)-1] = 'f';
-    } else if (av_match_ext(filename, "asf") &&
-        (!useragent || av_strncasecmp(useragent, "NSPlayer", 8) != 0)) {
-        /* if this isn't WMP or lookalike, return the redirector file */
-        redir_type = REDIR_ASF;
-    } else if (av_match_ext(filename, "rpm,ram")) {
-        redir_type = REDIR_RAM;
-        strcpy(filename + strlen(filename)-2, "m");
-    } else if (av_match_ext(filename, "rtsp")) {
-        redir_type = REDIR_RTSP;
-        compute_real_filename(filename, sizeof(filename) - 1);
-    } else if (av_match_ext(filename, "sdp")) {
-        redir_type = REDIR_SDP;
-        compute_real_filename(filename, sizeof(filename) - 1);
-    }
-
-    // "redirect" / request to index.html
-    if (!strlen(filename))
-        av_strlcpy(filename, "index.html", sizeof(filename) - 1);
-
-    stream = first_stream;
-    while (stream != NULL) {
-        if (!strcmp(stream->filename, filename) && validate_acl(stream, c))
-            break;
-        stream = stream->next;
-    }
-    if (stream == NULL) {
-        snprintf(msg, sizeof(msg), "File '%s' not found", url);
-        http_log("File '%s' not found\n", url);
-        goto send_error;
-    }
-
-    c->stream = stream;
-    memcpy(c->feed_streams, stream->feed_streams, sizeof(c->feed_streams));
-    memset(c->switch_feed_streams, -1, sizeof(c->switch_feed_streams));
-
-    if (stream->stream_type == STREAM_TYPE_REDIRECT) {
-        c->http_error = 301;
-        q = c->buffer;
-        q += snprintf(q, c->buffer_size,
-                      "HTTP/1.0 301 Moved\r\n"
-                      "Location: %s\r\n"
-                      "Content-type: text/html\r\n"
-                      "\r\n"
-                      "<html><head><title>Moved</title></head><body>\r\n"
-                      "You should be <a href=\"%s\">redirected</a>.\r\n"
-                      "</body></html>\r\n", stream->feed_filename, stream->feed_filename);
-        /* prepare output buffer */
-        c->buffer_ptr = c->buffer;
-        c->buffer_end = q;
-        c->state = HTTPSTATE_SEND_HEADER;
-        return 0;
-    }
-
-    /* If this is WMP, get the rate information */
-    if (extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
-        if (modify_current_stream(c, ratebuf)) {
-            for (i = 0; i < FF_ARRAY_ELEMS(c->feed_streams); i++) {
-                if (c->switch_feed_streams[i] >= 0)
-                    c->switch_feed_streams[i] = -1;
-            }
-        }
-    }
-
-    if (c->post == 0 && stream->stream_type == STREAM_TYPE_LIVE)
-        current_bandwidth += stream->bandwidth;
-
-    /* If already streaming this feed, do not let start another feeder. */
-    if (stream->feed_opened) {
-        snprintf(msg, sizeof(msg), "This feed is already being received.");
-        http_log("Feed '%s' already being received\n", stream->feed_filename);
-        goto send_error;
-    }
-
-    if (c->post == 0 && max_bandwidth < current_bandwidth) {
-        c->http_error = 503;
-        q = c->buffer;
-        q += snprintf(q, c->buffer_size,
-                      "HTTP/1.0 503 Server too busy\r\n"
-                      "Content-type: text/html\r\n"
-                      "\r\n"
-                      "<html><head><title>Too busy</title></head><body>\r\n"
-                      "<p>The server is too busy to serve your request at this time.</p>\r\n"
-                      "<p>The bandwidth being served (including your stream) is %"PRIu64"kbit/sec, "
-                      "and this exceeds the limit of %"PRIu64"kbit/sec.</p>\r\n"
-                      "</body></html>\r\n", current_bandwidth, max_bandwidth);
-        /* prepare output buffer */
-        c->buffer_ptr = c->buffer;
-        c->buffer_end = q;
-        c->state = HTTPSTATE_SEND_HEADER;
-        return 0;
-    }
-
-    if (redir_type != REDIR_NONE) {
-        char *hostinfo = 0;
-
-        for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
-            if (av_strncasecmp(p, "Host:", 5) == 0) {
-                hostinfo = p + 5;
-                break;
-            }
-            p = strchr(p, '\n');
-            if (!p)
-                break;
-
-            p++;
-        }
-
-        if (hostinfo) {
-            char *eoh;
-            char hostbuf[260];
-
-            while (isspace(*hostinfo))
-                hostinfo++;
-
-            eoh = strchr(hostinfo, '\n');
-            if (eoh) {
-                if (eoh[-1] == '\r')
-                    eoh--;
-
-                if (eoh - hostinfo < sizeof(hostbuf) - 1) {
-                    memcpy(hostbuf, hostinfo, eoh - hostinfo);
-                    hostbuf[eoh - hostinfo] = 0;
-
-                    c->http_error = 200;
-                    q = c->buffer;
-                    switch(redir_type) {
-                    case REDIR_ASX:
-                        q += snprintf(q, c->buffer_size,
-                                      "HTTP/1.0 200 ASX Follows\r\n"
-                                      "Content-type: video/x-ms-asf\r\n"
-                                      "\r\n"
-                                      "<ASX Version=\"3\">\r\n"
-                                      //"<!-- Autogenerated by avserver -->\r\n"
-                                      "<ENTRY><REF HREF=\"http://%s/%s%s\"/></ENTRY>\r\n"
-                                      "</ASX>\r\n", hostbuf, filename, info);
-                        break;
-                    case REDIR_RAM:
-                        q += snprintf(q, c->buffer_size,
-                                      "HTTP/1.0 200 RAM Follows\r\n"
-                                      "Content-type: audio/x-pn-realaudio\r\n"
-                                      "\r\n"
-                                      "# Autogenerated by avserver\r\n"
-                                      "http://%s/%s%s\r\n", hostbuf, filename, info);
-                        break;
-                    case REDIR_ASF:
-                        q += snprintf(q, c->buffer_size,
-                                      "HTTP/1.0 200 ASF Redirect follows\r\n"
-                                      "Content-type: video/x-ms-asf\r\n"
-                                      "\r\n"
-                                      "[Reference]\r\n"
-                                      "Ref1=http://%s/%s%s\r\n", hostbuf, filename, info);
-                        break;
-                    case REDIR_RTSP:
-                        {
-                            char hostname[256], *p;
-                            /* extract only hostname */
-                            av_strlcpy(hostname, hostbuf, sizeof(hostname));
-                            p = strrchr(hostname, ':');
-                            if (p)
-                                *p = '\0';
-                            q += snprintf(q, c->buffer_size,
-                                          "HTTP/1.0 200 RTSP Redirect follows\r\n"
-                                          /* XXX: incorrect mime type ? */
-                                          "Content-type: application/x-rtsp\r\n"
-                                          "\r\n"
-                                          "rtsp://%s:%d/%s\r\n", hostname, ntohs(my_rtsp_addr.sin_port), filename);
-                        }
-                        break;
-                    case REDIR_SDP:
-                        {
-                            uint8_t *sdp_data;
-                            int sdp_data_size, len;
-                            struct sockaddr_in my_addr;
-
-                            q += snprintf(q, c->buffer_size,
-                                          "HTTP/1.0 200 OK\r\n"
-                                          "Content-type: application/sdp\r\n"
-                                          "\r\n");
-
-                            len = sizeof(my_addr);
-                            getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
-
-                            /* XXX: should use a dynamic buffer */
-                            sdp_data_size = prepare_sdp_description(stream,
-                                                                    &sdp_data,
-                                                                    my_addr.sin_addr);
-                            if (sdp_data_size > 0) {
-                                memcpy(q, sdp_data, sdp_data_size);
-                                q += sdp_data_size;
-                                *q = '\0';
-                                av_free(sdp_data);
-                            }
-                        }
-                        break;
-                    default:
-                        abort();
-                        break;
-                    }
-
-                    /* prepare output buffer */
-                    c->buffer_ptr = c->buffer;
-                    c->buffer_end = q;
-                    c->state = HTTPSTATE_SEND_HEADER;
-                    return 0;
-                }
-            }
-        }
-
-        snprintf(msg, sizeof(msg), "ASX/RAM file not handled");
-        goto send_error;
-    }
-
-    stream->conns_served++;
-
-    /* XXX: add there authenticate and IP match */
-
-    if (c->post) {
-        /* if post, it means a feed is being sent */
-        if (!stream->is_feed) {
-            /* However it might be a status report from WMP! Let us log the
-             * data as it might come in handy one day. */
-            char *logline = 0;
-            int client_id = 0;
-
-            for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
-                if (av_strncasecmp(p, "Pragma: log-line=", 17) == 0) {
-                    logline = p;
-                    break;
-                }
-                if (av_strncasecmp(p, "Pragma: client-id=", 18) == 0)
-                    client_id = strtol(p + 18, 0, 10);
-                p = strchr(p, '\n');
-                if (!p)
-                    break;
-
-                p++;
-            }
-
-            if (logline) {
-                char *eol = strchr(logline, '\n');
-
-                logline += 17;
-
-                if (eol) {
-                    if (eol[-1] == '\r')
-                        eol--;
-                    http_log("%.*s\n", (int) (eol - logline), logline);
-                    c->suppress_log = 1;
-                }
-            }
-
-#ifdef DEBUG
-            http_log("\nGot request:\n%s\n", c->buffer);
-#endif
-
-            if (client_id && extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
-                HTTPContext *wmpc;
-
-                /* Now we have to find the client_id */
-                for (wmpc = first_http_ctx; wmpc; wmpc = wmpc->next) {
-                    if (wmpc->wmp_client_id == client_id)
-                        break;
-                }
-
-                if (wmpc && modify_current_stream(wmpc, ratebuf))
-                    wmpc->switch_pending = 1;
-            }
-
-            snprintf(msg, sizeof(msg), "POST command not handled");
-            c->stream = 0;
-            goto send_error;
-        }
-        if (http_start_receive_data(c) < 0) {
-            snprintf(msg, sizeof(msg), "could not open feed");
-            goto send_error;
-        }
-        c->http_error = 0;
-        c->state = HTTPSTATE_RECEIVE_DATA;
-        return 0;
-    }
-
-#ifdef DEBUG
-    if (strcmp(stream->filename + strlen(stream->filename) - 4, ".asf") == 0)
-        http_log("\nGot request:\n%s\n", c->buffer);
-#endif
-
-    if (c->stream->stream_type == STREAM_TYPE_STATUS)
-        goto send_status;
-
-    /* open input stream */
-    if (open_input_stream(c, info) < 0) {
-        snprintf(msg, sizeof(msg), "Input stream corresponding to '%s' not found", url);
-        goto send_error;
-    }
-
-    /* prepare http header */
-    q = c->buffer;
-    q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 OK\r\n");
-    mime_type = c->stream->fmt->mime_type;
-    if (!mime_type)
-        mime_type = "application/x-octet-stream";
-    q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Pragma: no-cache\r\n");
-
-    /* for asf, we need extra headers */
-    if (!strcmp(c->stream->fmt->name,"asf_stream")) {
-        /* Need to allocate a client id */
-
-        c->wmp_client_id = av_lfg_get(&random_state);
-
-        q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Server: Cougar 4.1.0.3923\r\nCache-Control: no-cache\r\nPragma: client-id=%d\r\nPragma: features=\"broadcast\"\r\n", c->wmp_client_id);
-    }
-    q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-Type: %s\r\n", mime_type);
-    q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n");
-
-    /* prepare output buffer */
-    c->http_error = 0;
-    c->buffer_ptr = c->buffer;
-    c->buffer_end = q;
-    c->state = HTTPSTATE_SEND_HEADER;
-    return 0;
- send_error:
-    c->http_error = 404;
-    q = c->buffer;
-    q += snprintf(q, c->buffer_size,
-                  "HTTP/1.0 404 Not Found\r\n"
-                  "Content-type: text/html\r\n"
-                  "\r\n"
-                  "<html>\n"
-                  "<head><title>404 Not Found</title></head>\n"
-                  "<body>%s</body>\n"
-                  "</html>\n", msg);
-    /* prepare output buffer */
-    c->buffer_ptr = c->buffer;
-    c->buffer_end = q;
-    c->state = HTTPSTATE_SEND_HEADER;
-    return 0;
- send_status:
-    compute_status(c);
-    c->http_error = 200; /* horrible : we use this value to avoid
-                            going to the send data state */
-    c->state = HTTPSTATE_SEND_HEADER;
-    return 0;
-}
-
-static void fmt_bytecount(AVIOContext *pb, int64_t count)
-{
-    static const char suffix[] = " kMGTP";
-    const char *s;
-
-    for (s = suffix; count >= 100000 && s[1]; count /= 1000, s++);
-
-    avio_printf(pb, "%"PRId64"%c", count, *s);
-}
-
-static void compute_status(HTTPContext *c)
-{
-    HTTPContext *c1;
-    FFStream *stream;
-    char *p;
-    time_t ti;
-    int i, len;
-    AVIOContext *pb;
-
-    if (avio_open_dyn_buf(&pb) < 0) {
-        /* XXX: return an error ? */
-        c->buffer_ptr = c->buffer;
-        c->buffer_end = c->buffer;
-        return;
-    }
-
-    avio_printf(pb, "HTTP/1.0 200 OK\r\n");
-    avio_printf(pb, "Content-type: %s\r\n", "text/html");
-    avio_printf(pb, "Pragma: no-cache\r\n");
-    avio_printf(pb, "\r\n");
-
-    avio_printf(pb, "<html><head><title>%s Status</title>\n", program_name);
-    if (c->stream->feed_filename[0])
-        avio_printf(pb, "<link rel=\"shortcut icon\" href=\"%s\">\n", c->stream->feed_filename);
-    avio_printf(pb, "</head>\n<body>");
-    avio_printf(pb, "<h1>%s Status</h1>\n", program_name);
-    /* format status */
-    avio_printf(pb, "<h2>Available Streams</h2>\n");
-    avio_printf(pb, "<table cellspacing=0 cellpadding=4>\n");
-    avio_printf(pb, "<tr><th valign=top>Path<th align=left>Served<br>Conns<th><br>bytes<th valign=top>Format<th>Bit rate<br>kbits/s<th align=left>Video<br>kbits/s<th><br>Codec<th align=left>Audio<br>kbits/s<th><br>Codec<th align=left valign=top>Feed\n");
-    stream = first_stream;
-    while (stream != NULL) {
-        char sfilename[1024];
-        char *eosf;
-
-        if (stream->feed != stream) {
-            av_strlcpy(sfilename, stream->filename, sizeof(sfilename) - 10);
-            eosf = sfilename + strlen(sfilename);
-            if (eosf - sfilename >= 4) {
-                if (strcmp(eosf - 4, ".asf") == 0)
-                    strcpy(eosf - 4, ".asx");
-                else if (strcmp(eosf - 3, ".rm") == 0)
-                    strcpy(eosf - 3, ".ram");
-                else if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
-                    /* generate a sample RTSP director if
-                       unicast. Generate an SDP redirector if
-                       multicast */
-                    eosf = strrchr(sfilename, '.');
-                    if (!eosf)
-                        eosf = sfilename + strlen(sfilename);
-                    if (stream->is_multicast)
-                        strcpy(eosf, ".sdp");
-                    else
-                        strcpy(eosf, ".rtsp");
-                }
-            }
-
-            avio_printf(pb, "<tr><td><a href=\"/%s\">%s</a> ",
-                         sfilename, stream->filename);
-            avio_printf(pb, "<td align=right> %d <td align=right> ",
-                        stream->conns_served);
-            fmt_bytecount(pb, stream->bytes_served);
-            switch(stream->stream_type) {
-            case STREAM_TYPE_LIVE: {
-                    int audio_bit_rate = 0;
-                    int video_bit_rate = 0;
-                    const char *audio_codec_name = "";
-                    const char *video_codec_name = "";
-                    const char *audio_codec_name_extra = "";
-                    const char *video_codec_name_extra = "";
-
-                    for(i=0;i<stream->nb_streams;i++) {
-                        AVStream *st = stream->streams[i];
-                        AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
-                        switch(st->codec->codec_type) {
-                        case AVMEDIA_TYPE_AUDIO:
-                            audio_bit_rate += st->codec->bit_rate;
-                            if (codec) {
-                                if (*audio_codec_name)
-                                    audio_codec_name_extra = "...";
-                                audio_codec_name = codec->name;
-                            }
-                            break;
-                        case AVMEDIA_TYPE_VIDEO:
-                            video_bit_rate += st->codec->bit_rate;
-                            if (codec) {
-                                if (*video_codec_name)
-                                    video_codec_name_extra = "...";
-                                video_codec_name = codec->name;
-                            }
-                            break;
-                        case AVMEDIA_TYPE_DATA:
-                            video_bit_rate += st->codec->bit_rate;
-                            break;
-                        default:
-                            abort();
-                        }
-                    }
-                    avio_printf(pb, "<td align=center> %s <td align=right> %d <td align=right> %d <td> %s %s <td align=right> %d <td> %s %s",
-                                 stream->fmt->name,
-                                 stream->bandwidth,
-                                 video_bit_rate / 1000, video_codec_name, video_codec_name_extra,
-                                 audio_bit_rate / 1000, audio_codec_name, audio_codec_name_extra);
-                    if (stream->feed)
-                        avio_printf(pb, "<td>%s", stream->feed->filename);
-                    else
-                        avio_printf(pb, "<td>%s", stream->feed_filename);
-                    avio_printf(pb, "\n");
-                }
-                break;
-            default:
-                avio_printf(pb, "<td align=center> - <td align=right> - <td align=right> - <td><td align=right> - <td>\n");
-                break;
-            }
-        }
-        stream = stream->next;
-    }
-    avio_printf(pb, "</table>\n");
-
-    stream = first_stream;
-    while (stream != NULL) {
-        if (stream->feed == stream) {
-            avio_printf(pb, "<h2>Feed %s</h2>", stream->filename);
-            if (stream->pid) {
-                avio_printf(pb, "Running as pid %d.\n", stream->pid);
-
-#if defined(linux) && !defined(CONFIG_NOCUTILS)
-                {
-                    FILE *pid_stat;
-                    char ps_cmd[64];
-
-                    /* This is somewhat linux specific I guess */
-                    snprintf(ps_cmd, sizeof(ps_cmd),
-                             "ps -o \"%%cpu,cputime\" --no-headers %d",
-                             stream->pid);
-
-                    pid_stat = popen(ps_cmd, "r");
-                    if (pid_stat) {
-                        char cpuperc[10];
-                        char cpuused[64];
-
-                        if (fscanf(pid_stat, "%10s %64s", cpuperc,
-                                   cpuused) == 2) {
-                            avio_printf(pb, "Currently using %s%% of the cpu. Total time used %s.\n",
-                                         cpuperc, cpuused);
-                        }
-                        fclose(pid_stat);
-                    }
-                }
-#endif
-
-                avio_printf(pb, "<p>");
-            }
-            avio_printf(pb, "<table cellspacing=0 cellpadding=4><tr><th>Stream<th>type<th>kbits/s<th align=left>codec<th align=left>Parameters\n");
-
-            for (i = 0; i < stream->nb_streams; i++) {
-                AVStream *st = stream->streams[i];
-                AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
-                const char *type = "unknown";
-                char parameters[64];
-
-                parameters[0] = 0;
-
-                switch(st->codec->codec_type) {
-                case AVMEDIA_TYPE_AUDIO:
-                    type = "audio";
-                    snprintf(parameters, sizeof(parameters), "%d channel(s), %d Hz", st->codec->channels, st->codec->sample_rate);
-                    break;
-                case AVMEDIA_TYPE_VIDEO:
-                    type = "video";
-                    snprintf(parameters, sizeof(parameters), "%dx%d, q=%d-%d, fps=%d", st->codec->width, st->codec->height,
-                                st->codec->qmin, st->codec->qmax, st->codec->time_base.den / st->codec->time_base.num);
-                    break;
-                default:
-                    abort();
-                }
-                avio_printf(pb, "<tr><td align=right>%d<td>%s<td align=right>%d<td>%s<td>%s\n",
-                        i, type, st->codec->bit_rate/1000, codec ? codec->name : "", parameters);
-            }
-            avio_printf(pb, "</table>\n");
-
-        }
-        stream = stream->next;
-    }
-
-    /* connection status */
-    avio_printf(pb, "<h2>Connection Status</h2>\n");
-
-    avio_printf(pb, "Number of connections: %d / %d<br>\n",
-                 nb_connections, nb_max_connections);
-
-    avio_printf(pb, "Bandwidth in use: %"PRIu64"k / %"PRIu64"k<br>\n",
-                 current_bandwidth, max_bandwidth);
-
-    avio_printf(pb, "<table>\n");
-    avio_printf(pb, "<tr><th>#<th>File<th>IP<th>Proto<th>State<th>Target bits/sec<th>Actual bits/sec<th>Bytes transferred\n");
-    c1 = first_http_ctx;
-    i = 0;
-    while (c1 != NULL) {
-        int bitrate;
-        int j;
-
-        bitrate = 0;
-        if (c1->stream) {
-            for (j = 0; j < c1->stream->nb_streams; j++) {
-                if (!c1->stream->feed)
-                    bitrate += c1->stream->streams[j]->codec->bit_rate;
-                else if (c1->feed_streams[j] >= 0)
-                    bitrate += c1->stream->feed->streams[c1->feed_streams[j]]->codec->bit_rate;
-            }
-        }
-
-        i++;
-        p = inet_ntoa(c1->from_addr.sin_addr);
-        avio_printf(pb, "<tr><td><b>%d</b><td>%s%s<td>%s<td>%s<td>%s<td align=right>",
-                    i,
-                    c1->stream ? c1->stream->filename : "",
-                    c1->state == HTTPSTATE_RECEIVE_DATA ? "(input)" : "",
-                    p,
-                    c1->protocol,
-                    http_state[c1->state]);
-        fmt_bytecount(pb, bitrate);
-        avio_printf(pb, "<td align=right>");
-        fmt_bytecount(pb, compute_datarate(&c1->datarate, c1->data_count) * 8);
-        avio_printf(pb, "<td align=right>");
-        fmt_bytecount(pb, c1->data_count);
-        avio_printf(pb, "\n");
-        c1 = c1->next;
-    }
-    avio_printf(pb, "</table>\n");
-
-    /* date */
-    ti = time(NULL);
-    p = ctime(&ti);
-    avio_printf(pb, "<hr size=1 noshade>Generated at %s", p);
-    avio_printf(pb, "</body>\n</html>\n");
-
-    len = avio_close_dyn_buf(pb, &c->pb_buffer);
-    c->buffer_ptr = c->pb_buffer;
-    c->buffer_end = c->pb_buffer + len;
-}
-
-static int open_input_stream(HTTPContext *c, const char *info)
-{
-    char buf[128];
-    char input_filename[1024];
-    AVFormatContext *s = NULL;
-    int i, ret;
-    int64_t stream_pos;
-
-    /* find file name */
-    if (c->stream->feed) {
-        strcpy(input_filename, c->stream->feed->feed_filename);
-        /* compute position (absolute time) */
-        if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
-            if ((ret = av_parse_time(&stream_pos, buf, 0)) < 0)
-                return ret;
-        } else if (av_find_info_tag(buf, sizeof(buf), "buffer", info)) {
-            int prebuffer = strtol(buf, 0, 10);
-            stream_pos = av_gettime() - prebuffer * (int64_t)1000000;
-        } else
-            stream_pos = av_gettime() - c->stream->prebuffer * (int64_t)1000;
-    } else {
-        strcpy(input_filename, c->stream->feed_filename);
-        /* compute position (relative time) */
-        if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
-            if ((ret = av_parse_time(&stream_pos, buf, 1)) < 0)
-                return ret;
-        } else
-            stream_pos = 0;
-    }
-    if (input_filename[0] == '\0')
-        return -1;
-
-    /* open stream */
-    if ((ret = avformat_open_input(&s, input_filename, c->stream->ifmt, &c->stream->in_opts)) < 0) {
-        http_log("could not open %s: %d\n", input_filename, ret);
-        return -1;
-    }
-    s->flags |= AVFMT_FLAG_GENPTS;
-    c->fmt_in = s;
-    if (strcmp(s->iformat->name, "ffm") && avformat_find_stream_info(c->fmt_in, NULL) < 0) {
-        http_log("Could not find stream info '%s'\n", input_filename);
-        avformat_close_input(&s);
-        return -1;
-    }
-
-    /* choose stream as clock source (we favorize video stream if
-       present) for packet sending */
-    c->pts_stream_index = 0;
-    for(i=0;i<c->stream->nb_streams;i++) {
-        if (c->pts_stream_index == 0 &&
-            c->stream->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
-            c->pts_stream_index = i;
-        }
-    }
-
-    if (c->fmt_in->iformat->read_seek)
-        av_seek_frame(c->fmt_in, -1, stream_pos, 0);
-    /* set the start time (needed for maxtime and RTP packet timing) */
-    c->start_time = cur_time;
-    c->first_pts = AV_NOPTS_VALUE;
-    return 0;
-}
-
-/* return the server clock (in us) */
-static int64_t get_server_clock(HTTPContext *c)
-{
-    /* compute current pts value from system time */
-    return (cur_time - c->start_time) * 1000;
-}
-
-/* return the estimated time at which the current packet must be sent
-   (in us) */
-static int64_t get_packet_send_clock(HTTPContext *c)
-{
-    int bytes_left, bytes_sent, frame_bytes;
-
-    frame_bytes = c->cur_frame_bytes;
-    if (frame_bytes <= 0)
-        return c->cur_pts;
-    else {
-        bytes_left = c->buffer_end - c->buffer_ptr;
-        bytes_sent = frame_bytes - bytes_left;
-        return c->cur_pts + (c->cur_frame_duration * bytes_sent) / frame_bytes;
-    }
-}
-
-
-static int http_prepare_data(HTTPContext *c)
-{
-    int i, len, ret;
-    AVFormatContext *ctx;
-
-    av_freep(&c->pb_buffer);
-    switch(c->state) {
-    case HTTPSTATE_SEND_DATA_HEADER:
-        memset(&c->fmt_ctx, 0, sizeof(c->fmt_ctx));
-        av_dict_set(&c->fmt_ctx.metadata, "author"   , c->stream->author   , 0);
-        av_dict_set(&c->fmt_ctx.metadata, "comment"  , c->stream->comment  , 0);
-        av_dict_set(&c->fmt_ctx.metadata, "copyright", c->stream->copyright, 0);
-        av_dict_set(&c->fmt_ctx.metadata, "title"    , c->stream->title    , 0);
-
-        c->fmt_ctx.streams = av_mallocz(sizeof(AVStream *) * c->stream->nb_streams);
-
-        for(i=0;i<c->stream->nb_streams;i++) {
-            AVStream *src;
-            c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream));
-            /* if file or feed, then just take streams from FFStream struct */
-            if (!c->stream->feed ||
-                c->stream->feed == c->stream)
-                src = c->stream->streams[i];
-            else
-                src = c->stream->feed->streams[c->stream->feed_streams[i]];
-
-            *(c->fmt_ctx.streams[i]) = *src;
-            c->fmt_ctx.streams[i]->priv_data = 0;
-            c->fmt_ctx.streams[i]->codec->frame_number = 0; /* XXX: should be done in
-                                           AVStream, not in codec */
-        }
-        /* set output format parameters */
-        c->fmt_ctx.oformat = c->stream->fmt;
-        c->fmt_ctx.nb_streams = c->stream->nb_streams;
-
-        c->got_key_frame = 0;
-
-        /* prepare header and save header data in a stream */
-        if (avio_open_dyn_buf(&c->fmt_ctx.pb) < 0) {
-            /* XXX: potential leak */
-            return -1;
-        }
-        c->fmt_ctx.pb->seekable = 0;
-
-        /*
-         * HACK to avoid mpeg ps muxer to spit many underflow errors
-         * Default value from Libav
-         * Try to set it use configuration option
-         */
-        c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE);
-
-        if (avformat_write_header(&c->fmt_ctx, NULL) < 0) {
-            http_log("Error writing output header\n");
-            return -1;
-        }
-        av_dict_free(&c->fmt_ctx.metadata);
-
-        len = avio_close_dyn_buf(c->fmt_ctx.pb, &c->pb_buffer);
-        c->buffer_ptr = c->pb_buffer;
-        c->buffer_end = c->pb_buffer + len;
-
-        c->state = HTTPSTATE_SEND_DATA;
-        c->last_packet_sent = 0;
-        break;
-    case HTTPSTATE_SEND_DATA:
-        /* find a new packet */
-        /* read a packet from the input stream */
-        if (c->stream->feed)
-            ffm_set_write_index(c->fmt_in,
-                                c->stream->feed->feed_write_index,
-                                c->stream->feed->feed_size);
-
-        if (c->stream->max_time &&
-            c->stream->max_time + c->start_time - cur_time < 0)
-            /* We have timed out */
-            c->state = HTTPSTATE_SEND_DATA_TRAILER;
-        else {
-            AVPacket pkt;
-        redo:
-            ret = av_read_frame(c->fmt_in, &pkt);
-            if (ret < 0) {
-                if (c->stream->feed) {
-                    /* if coming from feed, it means we reached the end of the
-                       ffm file, so must wait for more data */
-                    c->state = HTTPSTATE_WAIT_FEED;
-                    return 1; /* state changed */
-                } else if (ret == AVERROR(EAGAIN)) {
-                    /* input not ready, come back later */
-                    return 0;
-                } else {
-                    if (c->stream->loop) {
-                        avformat_close_input(&c->fmt_in);
-                        if (open_input_stream(c, "") < 0)
-                            goto no_loop;
-                        goto redo;
-                    } else {
-                    no_loop:
-                        /* must send trailer now because eof or error */
-                        c->state = HTTPSTATE_SEND_DATA_TRAILER;
-                    }
-                }
-            } else {
-                int source_index = pkt.stream_index;
-                /* update first pts if needed */
-                if (c->first_pts == AV_NOPTS_VALUE) {
-                    c->first_pts = av_rescale_q(pkt.dts, c->fmt_in->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q);
-                    c->start_time = cur_time;
-                }
-                /* send it to the appropriate stream */
-                if (c->stream->feed) {
-                    /* if coming from a feed, select the right stream */
-                    if (c->switch_pending) {
-                        c->switch_pending = 0;
-                        for(i=0;i<c->stream->nb_streams;i++) {
-                            if (c->switch_feed_streams[i] == pkt.stream_index)
-                                if (pkt.flags & AV_PKT_FLAG_KEY)
-                                    c->switch_feed_streams[i] = -1;
-                            if (c->switch_feed_streams[i] >= 0)
-                                c->switch_pending = 1;
-                        }
-                    }
-                    for(i=0;i<c->stream->nb_streams;i++) {
-                        if (c->stream->feed_streams[i] == pkt.stream_index) {
-                            AVStream *st = c->fmt_in->streams[source_index];
-                            pkt.stream_index = i;
-                            if (pkt.flags & AV_PKT_FLAG_KEY &&
-                                (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
-                                 c->stream->nb_streams == 1))
-                                c->got_key_frame = 1;
-                            if (!c->stream->send_on_key || c->got_key_frame)
-                                goto send_it;
-                        }
-                    }
-                } else {
-                    AVCodecContext *codec;
-                    AVStream *ist, *ost;
-                send_it:
-                    ist = c->fmt_in->streams[source_index];
-                    /* specific handling for RTP: we use several
-                       output stream (one for each RTP
-                       connection). XXX: need more abstract handling */
-                    if (c->is_packetized) {
-                        /* compute send time and duration */
-                        c->cur_pts = av_rescale_q(pkt.dts, ist->time_base, AV_TIME_BASE_Q);
-                        c->cur_pts -= c->first_pts;
-                        c->cur_frame_duration = av_rescale_q(pkt.duration, ist->time_base, AV_TIME_BASE_Q);
-                        /* find RTP context */
-                        c->packet_stream_index = pkt.stream_index;
-                        ctx = c->rtp_ctx[c->packet_stream_index];
-                        if(!ctx) {
-                            av_free_packet(&pkt);
-                            break;
-                        }
-                        codec = ctx->streams[0]->codec;
-                        /* only one stream per RTP connection */
-                        pkt.stream_index = 0;
-                    } else {
-                        ctx = &c->fmt_ctx;
-                        /* Fudge here */
-                        codec = ctx->streams[pkt.stream_index]->codec;
-                    }
-
-                    if (c->is_packetized) {
-                        int max_packet_size;
-                        if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP)
-                            max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
-                        else
-                            max_packet_size = c->rtp_handles[c->packet_stream_index]->max_packet_size;
-                        ret = ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size);
-                    } else {
-                        ret = avio_open_dyn_buf(&ctx->pb);
-                    }
-                    if (ret < 0) {
-                        /* XXX: potential leak */
-                        return -1;
-                    }
-                    ost = ctx->streams[pkt.stream_index];
-
-                    ctx->pb->seekable = 0;
-                    if (pkt.dts != AV_NOPTS_VALUE)
-                        pkt.dts = av_rescale_q(pkt.dts, ist->time_base, ost->time_base);
-                    if (pkt.pts != AV_NOPTS_VALUE)
-                        pkt.pts = av_rescale_q(pkt.pts, ist->time_base, ost->time_base);
-                    pkt.duration = av_rescale_q(pkt.duration, ist->time_base, ost->time_base);
-                    if (av_write_frame(ctx, &pkt) < 0) {
-                        http_log("Error writing frame to output\n");
-                        c->state = HTTPSTATE_SEND_DATA_TRAILER;
-                    }
-
-                    len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
-                    c->cur_frame_bytes = len;
-                    c->buffer_ptr = c->pb_buffer;
-                    c->buffer_end = c->pb_buffer + len;
-
-                    codec->frame_number++;
-                    if (len == 0) {
-                        av_free_packet(&pkt);
-                        goto redo;
-                    }
-                }
-                av_free_packet(&pkt);
-            }
-        }
-        break;
-    default:
-    case HTTPSTATE_SEND_DATA_TRAILER:
-        /* last packet test ? */
-        if (c->last_packet_sent || c->is_packetized)
-            return -1;
-        ctx = &c->fmt_ctx;
-        /* prepare header */
-        if (avio_open_dyn_buf(&ctx->pb) < 0) {
-            /* XXX: potential leak */
-            return -1;
-        }
-        c->fmt_ctx.pb->seekable = 0;
-        av_write_trailer(ctx);
-        len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
-        c->buffer_ptr = c->pb_buffer;
-        c->buffer_end = c->pb_buffer + len;
-
-        c->last_packet_sent = 1;
-        break;
-    }
-    return 0;
-}
-
-/* should convert the format at the same time */
-/* send data starting at c->buffer_ptr to the output connection
-   (either UDP or TCP connection) */
-static int http_send_data(HTTPContext *c)
-{
-    int len, ret;
-
-    for(;;) {
-        if (c->buffer_ptr >= c->buffer_end) {
-            ret = http_prepare_data(c);
-            if (ret < 0)
-                return -1;
-            else if (ret != 0)
-                /* state change requested */
-                break;
-        } else {
-            if (c->is_packetized) {
-                /* RTP data output */
-                len = c->buffer_end - c->buffer_ptr;
-                if (len < 4) {
-                    /* fail safe - should never happen */
-                fail1:
-                    c->buffer_ptr = c->buffer_end;
-                    return 0;
-                }
-                len = (c->buffer_ptr[0] << 24) |
-                    (c->buffer_ptr[1] << 16) |
-                    (c->buffer_ptr[2] << 8) |
-                    (c->buffer_ptr[3]);
-                if (len > (c->buffer_end - c->buffer_ptr))
-                    goto fail1;
-                if ((get_packet_send_clock(c) - get_server_clock(c)) > 0) {
-                    /* nothing to send yet: we can wait */
-                    return 0;
-                }
-
-                c->data_count += len;
-                update_datarate(&c->datarate, c->data_count);
-                if (c->stream)
-                    c->stream->bytes_served += len;
-
-                if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP) {
-                    /* RTP packets are sent inside the RTSP TCP connection */
-                    AVIOContext *pb;
-                    int interleaved_index, size;
-                    uint8_t header[4];
-                    HTTPContext *rtsp_c;
-
-                    rtsp_c = c->rtsp_c;
-                    /* if no RTSP connection left, error */
-                    if (!rtsp_c)
-                        return -1;
-                    /* if already sending something, then wait. */
-                    if (rtsp_c->state != RTSPSTATE_WAIT_REQUEST)
-                        break;
-                    if (avio_open_dyn_buf(&pb) < 0)
-                        goto fail1;
-                    interleaved_index = c->packet_stream_index * 2;
-                    /* RTCP packets are sent at odd indexes */
-                    if (c->buffer_ptr[1] == 200)
-                        interleaved_index++;
-                    /* write RTSP TCP header */
-                    header[0] = '$';
-                    header[1] = interleaved_index;
-                    header[2] = len >> 8;
-                    header[3] = len;
-                    avio_write(pb, header, 4);
-                    /* write RTP packet data */
-                    c->buffer_ptr += 4;
-                    avio_write(pb, c->buffer_ptr, len);
-                    size = avio_close_dyn_buf(pb, &c->packet_buffer);
-                    /* prepare asynchronous TCP sending */
-                    rtsp_c->packet_buffer_ptr = c->packet_buffer;
-                    rtsp_c->packet_buffer_end = c->packet_buffer + size;
-                    c->buffer_ptr += len;
-
-                    /* send everything we can NOW */
-                    len = send(rtsp_c->fd, rtsp_c->packet_buffer_ptr,
-                                rtsp_c->packet_buffer_end - rtsp_c->packet_buffer_ptr, 0);
-                    if (len > 0)
-                        rtsp_c->packet_buffer_ptr += len;
-                    if (rtsp_c->packet_buffer_ptr < rtsp_c->packet_buffer_end) {
-                        /* if we could not send all the data, we will
-                           send it later, so a new state is needed to
-                           "lock" the RTSP TCP connection */
-                        rtsp_c->state = RTSPSTATE_SEND_PACKET;
-                        break;
-                    } else
-                        /* all data has been sent */
-                        av_freep(&c->packet_buffer);
-                } else {
-                    /* send RTP packet directly in UDP */
-                    c->buffer_ptr += 4;
-                    ffurl_write(c->rtp_handles[c->packet_stream_index],
-                                c->buffer_ptr, len);
-                    c->buffer_ptr += len;
-                    /* here we continue as we can send several packets per 10 ms slot */
-                }
-            } else {
-                /* TCP data output */
-                len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
-                if (len < 0) {
-                    if (ff_neterrno() != AVERROR(EAGAIN) &&
-                        ff_neterrno() != AVERROR(EINTR))
-                        /* error : close connection */
-                        return -1;
-                    else
-                        return 0;
-                } else
-                    c->buffer_ptr += len;
-
-                c->data_count += len;
-                update_datarate(&c->datarate, c->data_count);
-                if (c->stream)
-                    c->stream->bytes_served += len;
-                break;
-            }
-        }
-    } /* for(;;) */
-    return 0;
-}
-
-static int http_start_receive_data(HTTPContext *c)
-{
-    int fd;
-
-    if (c->stream->feed_opened)
-        return -1;
-
-    /* Don't permit writing to this one */
-    if (c->stream->readonly)
-        return -1;
-
-    /* open feed */
-    fd = open(c->stream->feed_filename, O_RDWR);
-    if (fd < 0) {
-        http_log("Error opening feeder file: %s\n", strerror(errno));
-        return -1;
-    }
-    c->feed_fd = fd;
-
-    if (c->stream->truncate) {
-        /* truncate feed file */
-        ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE);
-        http_log("Truncating feed file '%s'\n", c->stream->feed_filename);
-        if (ftruncate(c->feed_fd, FFM_PACKET_SIZE) < 0) {
-            http_log("Error truncating feed file: %s\n", strerror(errno));
-            return -1;
-        }
-    } else {
-        if ((c->stream->feed_write_index = ffm_read_write_index(fd)) < 0) {
-            http_log("Error reading write index from feed file: %s\n", strerror(errno));
-            return -1;
-        }
-    }
-
-    c->stream->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
-    c->stream->feed_size = lseek(fd, 0, SEEK_END);
-    lseek(fd, 0, SEEK_SET);
-
-    /* init buffer input */
-    c->buffer_ptr = c->buffer;
-    c->buffer_end = c->buffer + FFM_PACKET_SIZE;
-    c->stream->feed_opened = 1;
-    c->chunked_encoding = !!av_stristr(c->buffer, "Transfer-Encoding: chunked");
-    return 0;
-}
-
-static int http_receive_data(HTTPContext *c)
-{
-    HTTPContext *c1;
-    int len, loop_run = 0;
-
-    while (c->chunked_encoding && !c->chunk_size &&
-           c->buffer_end > c->buffer_ptr) {
-        /* read chunk header, if present */
-        len = recv(c->fd, c->buffer_ptr, 1, 0);
-
-        if (len < 0) {
-            if (ff_neterrno() != AVERROR(EAGAIN) &&
-                ff_neterrno() != AVERROR(EINTR))
-                /* error : close connection */
-                goto fail;
-            return 0;
-        } else if (len == 0) {
-            /* end of connection : close it */
-            goto fail;
-        } else if (c->buffer_ptr - c->buffer >= 2 &&
-                   !memcmp(c->buffer_ptr - 1, "\r\n", 2)) {
-            c->chunk_size = strtol(c->buffer, 0, 16);
-            if (c->chunk_size == 0) // end of stream
-                goto fail;
-            c->buffer_ptr = c->buffer;
-            break;
-        } else if (++loop_run > 10) {
-            /* no chunk header, abort */
-            goto fail;
-        } else {
-            c->buffer_ptr++;
-        }
-    }
-
-    if (c->buffer_end > c->buffer_ptr) {
-        len = recv(c->fd, c->buffer_ptr,
-                   FFMIN(c->chunk_size, c->buffer_end - c->buffer_ptr), 0);
-        if (len < 0) {
-            if (ff_neterrno() != AVERROR(EAGAIN) &&
-                ff_neterrno() != AVERROR(EINTR))
-                /* error : close connection */
-                goto fail;
-        } else if (len == 0)
-            /* end of connection : close it */
-            goto fail;
-        else {
-            c->chunk_size -= len;
-            c->buffer_ptr += len;
-            c->data_count += len;
-            update_datarate(&c->datarate, c->data_count);
-        }
-    }
-
-    if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) {
-        if (c->buffer[0] != 'f' ||
-            c->buffer[1] != 'm') {
-            http_log("Feed stream has become desynchronized -- disconnecting\n");
-            goto fail;
-        }
-    }
-
-    if (c->buffer_ptr >= c->buffer_end) {
-        FFStream *feed = c->stream;
-        /* a packet has been received : write it in the store, except
-           if header */
-        if (c->data_count > FFM_PACKET_SIZE) {
-            /* XXX: use llseek or url_seek */
-            lseek(c->feed_fd, feed->feed_write_index, SEEK_SET);
-            if (write(c->feed_fd, c->buffer, FFM_PACKET_SIZE) < 0) {
-                http_log("Error writing to feed file: %s\n", strerror(errno));
-                goto fail;
-            }
-
-            feed->feed_write_index += FFM_PACKET_SIZE;
-            /* update file size */
-            if (feed->feed_write_index > c->stream->feed_size)
-                feed->feed_size = feed->feed_write_index;
-
-            /* handle wrap around if max file size reached */
-            if (c->stream->feed_max_size && feed->feed_write_index >= c->stream->feed_max_size)
-                feed->feed_write_index = FFM_PACKET_SIZE;
-
-            /* write index */
-            if (ffm_write_write_index(c->feed_fd, feed->feed_write_index) < 0) {
-                http_log("Error writing index to feed file: %s\n", strerror(errno));
-                goto fail;
-            }
-
-            /* wake up any waiting connections */
-            for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
-                if (c1->state == HTTPSTATE_WAIT_FEED &&
-                    c1->stream->feed == c->stream->feed)
-                    c1->state = HTTPSTATE_SEND_DATA;
-            }
-        } else {
-            /* We have a header in our hands that contains useful data */
-            AVFormatContext *s = avformat_alloc_context();
-            AVIOContext *pb;
-            AVInputFormat *fmt_in;
-            int i;
-
-            if (!s)
-                goto fail;
-
-            /* use feed output format name to find corresponding input format */
-            fmt_in = av_find_input_format(feed->fmt->name);
-            if (!fmt_in)
-                goto fail;
-
-            pb = avio_alloc_context(c->buffer, c->buffer_end - c->buffer,
-                                    0, NULL, NULL, NULL, NULL);
-            pb->seekable = 0;
-
-            s->pb = pb;
-            if (avformat_open_input(&s, c->stream->feed_filename, fmt_in, NULL) < 0) {
-                av_free(pb);
-                goto fail;
-            }
-
-            /* Now we have the actual streams */
-            if (s->nb_streams != feed->nb_streams) {
-                avformat_close_input(&s);
-                av_free(pb);
-                http_log("Feed '%s' stream number does not match registered feed\n",
-                         c->stream->feed_filename);
-                goto fail;
-            }
-
-            for (i = 0; i < s->nb_streams; i++) {
-                AVStream *fst = feed->streams[i];
-                AVStream *st = s->streams[i];
-                avcodec_copy_context(fst->codec, st->codec);
-            }
-
-            avformat_close_input(&s);
-            av_free(pb);
-        }
-        c->buffer_ptr = c->buffer;
-    }
-
-    return 0;
- fail:
-    c->stream->feed_opened = 0;
-    close(c->feed_fd);
-    /* wake up any waiting connections to stop waiting for feed */
-    for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
-        if (c1->state == HTTPSTATE_WAIT_FEED &&
-            c1->stream->feed == c->stream->feed)
-            c1->state = HTTPSTATE_SEND_DATA_TRAILER;
-    }
-    return -1;
-}
-
-/********************************************************************/
-/* RTSP handling */
-
-static void rtsp_reply_header(HTTPContext *c, enum RTSPStatusCode error_number)
-{
-    const char *str;
-    time_t ti;
-    struct tm *tm;
-    char buf2[32];
-
-    switch(error_number) {
-    case RTSP_STATUS_OK:
-        str = "OK";
-        break;
-    case RTSP_STATUS_METHOD:
-        str = "Method Not Allowed";
-        break;
-    case RTSP_STATUS_BANDWIDTH:
-        str = "Not Enough Bandwidth";
-        break;
-    case RTSP_STATUS_SESSION:
-        str = "Session Not Found";
-        break;
-    case RTSP_STATUS_STATE:
-        str = "Method Not Valid in This State";
-        break;
-    case RTSP_STATUS_AGGREGATE:
-        str = "Aggregate operation not allowed";
-        break;
-    case RTSP_STATUS_ONLY_AGGREGATE:
-        str = "Only aggregate operation allowed";
-        break;
-    case RTSP_STATUS_TRANSPORT:
-        str = "Unsupported transport";
-        break;
-    case RTSP_STATUS_INTERNAL:
-        str = "Internal Server Error";
-        break;
-    case RTSP_STATUS_SERVICE:
-        str = "Service Unavailable";
-        break;
-    case RTSP_STATUS_VERSION:
-        str = "RTSP Version not supported";
-        break;
-    default:
-        str = "Unknown Error";
-        break;
-    }
-
-    avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", error_number, str);
-    avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
-
-    /* output GMT time */
-    ti = time(NULL);
-    tm = gmtime(&ti);
-    strftime(buf2, sizeof(buf2), "%a, %d %b %Y %H:%M:%S", tm);
-    avio_printf(c->pb, "Date: %s GMT\r\n", buf2);
-}
-
-static void rtsp_reply_error(HTTPContext *c, enum RTSPStatusCode error_number)
-{
-    rtsp_reply_header(c, error_number);
-    avio_printf(c->pb, "\r\n");
-}
-
-static int rtsp_parse_request(HTTPContext *c)
-{
-    const char *p, *p1, *p2;
-    char cmd[32];
-    char url[1024];
-    char protocol[32];
-    char line[1024];
-    int len;
-    RTSPMessageHeader header1 = { 0 }, *header = &header1;
-
-    c->buffer_ptr[0] = '\0';
-    p = c->buffer;
-
-    get_word(cmd, sizeof(cmd), &p);
-    get_word(url, sizeof(url), &p);
-    get_word(protocol, sizeof(protocol), &p);
-
-    av_strlcpy(c->method, cmd, sizeof(c->method));
-    av_strlcpy(c->url, url, sizeof(c->url));
-    av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
-
-    if (avio_open_dyn_buf(&c->pb) < 0) {
-        /* XXX: cannot do more */
-        c->pb = NULL; /* safety */
-        return -1;
-    }
-
-    /* check version name */
-    if (strcmp(protocol, "RTSP/1.0") != 0) {
-        rtsp_reply_error(c, RTSP_STATUS_VERSION);
-        goto the_end;
-    }
-
-    /* parse each header line */
-    /* skip to next line */
-    while (*p != '\n' && *p != '\0')
-        p++;
-    if (*p == '\n')
-        p++;
-    while (*p != '\0') {
-        p1 = memchr(p, '\n', (char *)c->buffer_ptr - p);
-        if (!p1)
-            break;
-        p2 = p1;
-        if (p2 > p && p2[-1] == '\r')
-            p2--;
-        /* skip empty line */
-        if (p2 == p)
-            break;
-        len = p2 - p;
-        if (len > sizeof(line) - 1)
-            len = sizeof(line) - 1;
-        memcpy(line, p, len);
-        line[len] = '\0';
-        ff_rtsp_parse_line(header, line, NULL, NULL);
-        p = p1 + 1;
-    }
-
-    /* handle sequence number */
-    c->seq = header->seq;
-
-    if (!strcmp(cmd, "DESCRIBE"))
-        rtsp_cmd_describe(c, url);
-    else if (!strcmp(cmd, "OPTIONS"))
-        rtsp_cmd_options(c, url);
-    else if (!strcmp(cmd, "SETUP"))
-        rtsp_cmd_setup(c, url, header);
-    else if (!strcmp(cmd, "PLAY"))
-        rtsp_cmd_play(c, url, header);
-    else if (!strcmp(cmd, "PAUSE"))
-        rtsp_cmd_pause(c, url, header);
-    else if (!strcmp(cmd, "TEARDOWN"))
-        rtsp_cmd_teardown(c, url, header);
-    else
-        rtsp_reply_error(c, RTSP_STATUS_METHOD);
-
- the_end:
-    len = avio_close_dyn_buf(c->pb, &c->pb_buffer);
-    c->pb = NULL; /* safety */
-    if (len < 0) {
-        /* XXX: cannot do more */
-        return -1;
-    }
-    c->buffer_ptr = c->pb_buffer;
-    c->buffer_end = c->pb_buffer + len;
-    c->state = RTSPSTATE_SEND_REPLY;
-    return 0;
-}
-
-static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
-                                   struct in_addr my_ip)
-{
-    AVFormatContext *avc;
-    AVStream *avs = NULL;
-    int i;
-
-    avc =  avformat_alloc_context();
-    if (avc == NULL) {
-        return -1;
-    }
-    av_dict_set(&avc->metadata, "title",
-               stream->title[0] ? stream->title : "No Title", 0);
-    avc->nb_streams = stream->nb_streams;
-    if (stream->is_multicast) {
-        snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
-                 inet_ntoa(stream->multicast_ip),
-                 stream->multicast_port, stream->multicast_ttl);
-    } else {
-        snprintf(avc->filename, 1024, "rtp://0.0.0.0");
-    }
-
-    if (avc->nb_streams >= INT_MAX/sizeof(*avc->streams) ||
-        !(avc->streams = av_malloc(avc->nb_streams * sizeof(*avc->streams))))
-        goto sdp_done;
-    if (avc->nb_streams >= INT_MAX/sizeof(*avs) ||
-        !(avs = av_malloc(avc->nb_streams * sizeof(*avs))))
-        goto sdp_done;
-
-    for(i = 0; i < stream->nb_streams; i++) {
-        avc->streams[i] = &avs[i];
-        avc->streams[i]->codec = stream->streams[i]->codec;
-    }
-    *pbuffer = av_mallocz(2048);
-    av_sdp_create(&avc, 1, *pbuffer, 2048);
-
- sdp_done:
-    av_free(avc->streams);
-    av_dict_free(&avc->metadata);
-    av_free(avc);
-    av_free(avs);
-
-    return strlen(*pbuffer);
-}
-
-static void rtsp_cmd_options(HTTPContext *c, const char *url)
-{
-//    rtsp_reply_header(c, RTSP_STATUS_OK);
-    avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", RTSP_STATUS_OK, "OK");
-    avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
-    avio_printf(c->pb, "Public: %s\r\n", "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE");
-    avio_printf(c->pb, "\r\n");
-}
-
-static void rtsp_cmd_describe(HTTPContext *c, const char *url)
-{
-    FFStream *stream;
-    char path1[1024];
-    const char *path;
-    uint8_t *content;
-    int content_length, len;
-    struct sockaddr_in my_addr;
-
-    /* find which url is asked */
-    av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
-    path = path1;
-    if (*path == '/')
-        path++;
-
-    for(stream = first_stream; stream != NULL; stream = stream->next) {
-        if (!stream->is_feed &&
-            stream->fmt && !strcmp(stream->fmt->name, "rtp") &&
-            !strcmp(path, stream->filename)) {
-            goto found;
-        }
-    }
-    /* no stream found */
-    rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
-    return;
-
- found:
-    /* prepare the media description in sdp format */
-
-    /* get the host IP */
-    len = sizeof(my_addr);
-    getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
-    content_length = prepare_sdp_description(stream, &content, my_addr.sin_addr);
-    if (content_length < 0) {
-        rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
-        return;
-    }
-    rtsp_reply_header(c, RTSP_STATUS_OK);
-    avio_printf(c->pb, "Content-Base: %s/\r\n", url);
-    avio_printf(c->pb, "Content-Type: application/sdp\r\n");
-    avio_printf(c->pb, "Content-Length: %d\r\n", content_length);
-    avio_printf(c->pb, "\r\n");
-    avio_write(c->pb, content, content_length);
-    av_free(content);
-}
-
-static HTTPContext *find_rtp_session(const char *session_id)
-{
-    HTTPContext *c;
-
-    if (session_id[0] == '\0')
-        return NULL;
-
-    for(c = first_http_ctx; c != NULL; c = c->next) {
-        if (!strcmp(c->session_id, session_id))
-            return c;
-    }
-    return NULL;
-}
-
-static RTSPTransportField *find_transport(RTSPMessageHeader *h, enum RTSPLowerTransport lower_transport)
-{
-    RTSPTransportField *th;
-    int i;
-
-    for(i=0;i<h->nb_transports;i++) {
-        th = &h->transports[i];
-        if (th->lower_transport == lower_transport)
-            return th;
-    }
-    return NULL;
-}
-
-static void rtsp_cmd_setup(HTTPContext *c, const char *url,
-                           RTSPMessageHeader *h)
-{
-    FFStream *stream;
-    int stream_index, rtp_port, rtcp_port;
-    char buf[1024];
-    char path1[1024];
-    const char *path;
-    HTTPContext *rtp_c;
-    RTSPTransportField *th;
-    struct sockaddr_in dest_addr;
-    RTSPActionServerSetup setup;
-
-    /* find which url is asked */
-    av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
-    path = path1;
-    if (*path == '/')
-        path++;
-
-    /* now check each stream */
-    for(stream = first_stream; stream != NULL; stream = stream->next) {
-        if (!stream->is_feed &&
-            stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
-            /* accept aggregate filenames only if single stream */
-            if (!strcmp(path, stream->filename)) {
-                if (stream->nb_streams != 1) {
-                    rtsp_reply_error(c, RTSP_STATUS_AGGREGATE);
-                    return;
-                }
-                stream_index = 0;
-                goto found;
-            }
-
-            for(stream_index = 0; stream_index < stream->nb_streams;
-                stream_index++) {
-                snprintf(buf, sizeof(buf), "%s/streamid=%d",
-                         stream->filename, stream_index);
-                if (!strcmp(path, buf))
-                    goto found;
-            }
-        }
-    }
-    /* no stream found */
-    rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
-    return;
- found:
-
-    /* generate session id if needed */
-    if (h->session_id[0] == '\0')
-        snprintf(h->session_id, sizeof(h->session_id), "%08x%08x",
-                 av_lfg_get(&random_state), av_lfg_get(&random_state));
-
-    /* find rtp session, and create it if none found */
-    rtp_c = find_rtp_session(h->session_id);
-    if (!rtp_c) {
-        /* always prefer UDP */
-        th = find_transport(h, RTSP_LOWER_TRANSPORT_UDP);
-        if (!th) {
-            th = find_transport(h, RTSP_LOWER_TRANSPORT_TCP);
-            if (!th) {
-                rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
-                return;
-            }
-        }
-
-        rtp_c = rtp_new_connection(&c->from_addr, stream, h->session_id,
-                                   th->lower_transport);
-        if (!rtp_c) {
-            rtsp_reply_error(c, RTSP_STATUS_BANDWIDTH);
-            return;
-        }
-
-        /* open input stream */
-        if (open_input_stream(rtp_c, "") < 0) {
-            rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
-            return;
-        }
-    }
-
-    /* test if stream is OK (test needed because several SETUP needs
-       to be done for a given file) */
-    if (rtp_c->stream != stream) {
-        rtsp_reply_error(c, RTSP_STATUS_SERVICE);
-        return;
-    }
-
-    /* test if stream is already set up */
-    if (rtp_c->rtp_ctx[stream_index]) {
-        rtsp_reply_error(c, RTSP_STATUS_STATE);
-        return;
-    }
-
-    /* check transport */
-    th = find_transport(h, rtp_c->rtp_protocol);
-    if (!th || (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
-                th->client_port_min <= 0)) {
-        rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
-        return;
-    }
-
-    /* setup default options */
-    setup.transport_option[0] = '\0';
-    dest_addr = rtp_c->from_addr;
-    dest_addr.sin_port = htons(th->client_port_min);
-
-    /* setup stream */
-    if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, c) < 0) {
-        rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
-        return;
-    }
-
-    /* now everything is OK, so we can send the connection parameters */
-    rtsp_reply_header(c, RTSP_STATUS_OK);
-    /* session ID */
-    avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
-
-    switch(rtp_c->rtp_protocol) {
-    case RTSP_LOWER_TRANSPORT_UDP:
-        rtp_port = ff_rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]);
-        rtcp_port = ff_rtp_get_local_rtcp_port(rtp_c->rtp_handles[stream_index]);
-        avio_printf(c->pb, "Transport: RTP/AVP/UDP;unicast;"
-                    "client_port=%d-%d;server_port=%d-%d",
-                    th->client_port_min, th->client_port_max,
-                    rtp_port, rtcp_port);
-        break;
-    case RTSP_LOWER_TRANSPORT_TCP:
-        avio_printf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",
-                    stream_index * 2, stream_index * 2 + 1);
-        break;
-    default:
-        break;
-    }
-    if (setup.transport_option[0] != '\0')
-        avio_printf(c->pb, ";%s", setup.transport_option);
-    avio_printf(c->pb, "\r\n");
-
-
-    avio_printf(c->pb, "\r\n");
-}
-
-
-/* find an rtp connection by using the session ID. Check consistency
-   with filename */
-static HTTPContext *find_rtp_session_with_url(const char *url,
-                                              const char *session_id)
-{
-    HTTPContext *rtp_c;
-    char path1[1024];
-    const char *path;
-    char buf[1024];
-    int s, len;
-
-    rtp_c = find_rtp_session(session_id);
-    if (!rtp_c)
-        return NULL;
-
-    /* find which url is asked */
-    av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
-    path = path1;
-    if (*path == '/')
-        path++;
-    if(!strcmp(path, rtp_c->stream->filename)) return rtp_c;
-    for(s=0; s<rtp_c->stream->nb_streams; ++s) {
-      snprintf(buf, sizeof(buf), "%s/streamid=%d",
-        rtp_c->stream->filename, s);
-      if(!strncmp(path, buf, sizeof(buf))) {
-    // XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE if nb_streams>1?
-        return rtp_c;
-      }
-    }
-    len = strlen(path);
-    if (len > 0 && path[len - 1] == '/' &&
-        !strncmp(path, rtp_c->stream->filename, len - 1))
-        return rtp_c;
-    return NULL;
-}
-
-static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h)
-{
-    HTTPContext *rtp_c;
-
-    rtp_c = find_rtp_session_with_url(url, h->session_id);
-    if (!rtp_c) {
-        rtsp_reply_error(c, RTSP_STATUS_SESSION);
-        return;
-    }
-
-    if (rtp_c->state != HTTPSTATE_SEND_DATA &&
-        rtp_c->state != HTTPSTATE_WAIT_FEED &&
-        rtp_c->state != HTTPSTATE_READY) {
-        rtsp_reply_error(c, RTSP_STATUS_STATE);
-        return;
-    }
-
-    rtp_c->state = HTTPSTATE_SEND_DATA;
-
-    /* now everything is OK, so we can send the connection parameters */
-    rtsp_reply_header(c, RTSP_STATUS_OK);
-    /* session ID */
-    avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
-    avio_printf(c->pb, "\r\n");
-}
-
-static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h)
-{
-    HTTPContext *rtp_c;
-
-    rtp_c = find_rtp_session_with_url(url, h->session_id);
-    if (!rtp_c) {
-        rtsp_reply_error(c, RTSP_STATUS_SESSION);
-        return;
-    }
-
-    if (rtp_c->state != HTTPSTATE_SEND_DATA &&
-        rtp_c->state != HTTPSTATE_WAIT_FEED) {
-        rtsp_reply_error(c, RTSP_STATUS_STATE);
-        return;
-    }
-
-    rtp_c->state = HTTPSTATE_READY;
-    rtp_c->first_pts = AV_NOPTS_VALUE;
-    /* now everything is OK, so we can send the connection parameters */
-    rtsp_reply_header(c, RTSP_STATUS_OK);
-    /* session ID */
-    avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
-    avio_printf(c->pb, "\r\n");
-}
-
-static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h)
-{
-    HTTPContext *rtp_c;
-
-    rtp_c = find_rtp_session_with_url(url, h->session_id);
-    if (!rtp_c) {
-        rtsp_reply_error(c, RTSP_STATUS_SESSION);
-        return;
-    }
-
-    /* now everything is OK, so we can send the connection parameters */
-    rtsp_reply_header(c, RTSP_STATUS_OK);
-    /* session ID */
-    avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
-    avio_printf(c->pb, "\r\n");
-
-    /* abort the session */
-    close_connection(rtp_c);
-}
-
-
-/********************************************************************/
-/* RTP handling */
-
-static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
-                                       FFStream *stream, const char *session_id,
-                                       enum RTSPLowerTransport rtp_protocol)
-{
-    HTTPContext *c = NULL;
-    const char *proto_str;
-
-    /* XXX: should output a warning page when coming
-       close to the connection limit */
-    if (nb_connections >= nb_max_connections)
-        goto fail;
-
-    /* add a new connection */
-    c = av_mallocz(sizeof(HTTPContext));
-    if (!c)
-        goto fail;
-
-    c->fd = -1;
-    c->poll_entry = NULL;
-    c->from_addr = *from_addr;
-    c->buffer_size = IOBUFFER_INIT_SIZE;
-    c->buffer = av_malloc(c->buffer_size);
-    if (!c->buffer)
-        goto fail;
-    nb_connections++;
-    c->stream = stream;
-    av_strlcpy(c->session_id, session_id, sizeof(c->session_id));
-    c->state = HTTPSTATE_READY;
-    c->is_packetized = 1;
-    c->rtp_protocol = rtp_protocol;
-
-    /* protocol is shown in statistics */
-    switch(c->rtp_protocol) {
-    case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
-        proto_str = "MCAST";
-        break;
-    case RTSP_LOWER_TRANSPORT_UDP:
-        proto_str = "UDP";
-        break;
-    case RTSP_LOWER_TRANSPORT_TCP:
-        proto_str = "TCP";
-        break;
-    default:
-        proto_str = "???";
-        break;
-    }
-    av_strlcpy(c->protocol, "RTP/", sizeof(c->protocol));
-    av_strlcat(c->protocol, proto_str, sizeof(c->protocol));
-
-    current_bandwidth += stream->bandwidth;
-
-    c->next = first_http_ctx;
-    first_http_ctx = c;
-    return c;
-
- fail:
-    if (c) {
-        av_free(c->buffer);
-        av_free(c);
-    }
-    return NULL;
-}
-
-/* add a new RTP stream in an RTP connection (used in RTSP SETUP
-   command). If RTP/TCP protocol is used, TCP connection 'rtsp_c' is
-   used. */
-static int rtp_new_av_stream(HTTPContext *c,
-                             int stream_index, struct sockaddr_in *dest_addr,
-                             HTTPContext *rtsp_c)
-{
-    AVFormatContext *ctx;
-    AVStream *st;
-    char *ipaddr;
-    URLContext *h = NULL;
-    uint8_t *dummy_buf;
-    int max_packet_size;
-
-    /* now we can open the relevant output stream */
-    ctx = avformat_alloc_context();
-    if (!ctx)
-        return -1;
-    ctx->oformat = av_guess_format("rtp", NULL, NULL);
-
-    st = av_mallocz(sizeof(AVStream));
-    if (!st)
-        goto fail;
-    ctx->nb_streams = 1;
-    ctx->streams = av_mallocz(sizeof(AVStream *) * ctx->nb_streams);
-    if (!ctx->streams)
-      goto fail;
-    ctx->streams[0] = st;
-
-    if (!c->stream->feed ||
-        c->stream->feed == c->stream)
-        memcpy(st, c->stream->streams[stream_index], sizeof(AVStream));
-    else
-        memcpy(st,
-               c->stream->feed->streams[c->stream->feed_streams[stream_index]],
-               sizeof(AVStream));
-    st->priv_data = NULL;
-
-    /* build destination RTP address */
-    ipaddr = inet_ntoa(dest_addr->sin_addr);
-
-    switch(c->rtp_protocol) {
-    case RTSP_LOWER_TRANSPORT_UDP:
-    case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
-        /* RTP/UDP case */
-
-        /* XXX: also pass as parameter to function ? */
-        if (c->stream->is_multicast) {
-            int ttl;
-            ttl = c->stream->multicast_ttl;
-            if (!ttl)
-                ttl = 16;
-            snprintf(ctx->filename, sizeof(ctx->filename),
-                     "rtp://%s:%d?multicast=1&ttl=%d",
-                     ipaddr, ntohs(dest_addr->sin_port), ttl);
-        } else {
-            snprintf(ctx->filename, sizeof(ctx->filename),
-                     "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port));
-        }
-
-        if (ffurl_open(&h, ctx->filename, AVIO_FLAG_WRITE, NULL, NULL) < 0)
-            goto fail;
-        c->rtp_handles[stream_index] = h;
-        max_packet_size = h->max_packet_size;
-        break;
-    case RTSP_LOWER_TRANSPORT_TCP:
-        /* RTP/TCP case */
-        c->rtsp_c = rtsp_c;
-        max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
-        break;
-    default:
-        goto fail;
-    }
-
-    http_log("%s:%d - - \"PLAY %s/streamid=%d %s\"\n",
-             ipaddr, ntohs(dest_addr->sin_port),
-             c->stream->filename, stream_index, c->protocol);
-
-    /* normally, no packets should be output here, but the packet size may be checked */
-    if (ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0) {
-        /* XXX: close stream */
-        goto fail;
-    }
-    if (avformat_write_header(ctx, NULL) < 0) {
-    fail:
-        if (h)
-            ffurl_close(h);
-        av_free(ctx);
-        return -1;
-    }
-    avio_close_dyn_buf(ctx->pb, &dummy_buf);
-    av_free(dummy_buf);
-
-    c->rtp_ctx[stream_index] = ctx;
-    return 0;
-}
-
-/********************************************************************/
-/* avserver initialization */
-
-static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int copy)
-{
-    AVStream *fst;
-
-    fst = av_mallocz(sizeof(AVStream));
-    if (!fst)
-        return NULL;
-    if (copy) {
-        fst->codec = avcodec_alloc_context3(NULL);
-        memcpy(fst->codec, codec, sizeof(AVCodecContext));
-        if (codec->extradata_size) {
-            fst->codec->extradata = av_malloc(codec->extradata_size);
-            memcpy(fst->codec->extradata, codec->extradata,
-                codec->extradata_size);
-        }
-    } else {
-        /* live streams must use the actual feed's codec since it may be
-         * updated later to carry extradata needed by the streams.
-         */
-        fst->codec = codec;
-    }
-    fst->priv_data = av_mallocz(sizeof(FeedData));
-    fst->index = stream->nb_streams;
-    avpriv_set_pts_info(fst, 33, 1, 90000);
-    fst->sample_aspect_ratio = codec->sample_aspect_ratio;
-    stream->streams[stream->nb_streams++] = fst;
-    return fst;
-}
-
-/* return the stream number in the feed */
-static int add_av_stream(FFStream *feed, AVStream *st)
-{
-    AVStream *fst;
-    AVCodecContext *av, *av1;
-    int i;
-
-    av = st->codec;
-    for(i=0;i<feed->nb_streams;i++) {
-        st = feed->streams[i];
-        av1 = st->codec;
-        if (av1->codec_id == av->codec_id &&
-            av1->codec_type == av->codec_type &&
-            av1->bit_rate == av->bit_rate) {
-
-            switch(av->codec_type) {
-            case AVMEDIA_TYPE_AUDIO:
-                if (av1->channels == av->channels &&
-                    av1->sample_rate == av->sample_rate)
-                    return i;
-                break;
-            case AVMEDIA_TYPE_VIDEO:
-                if (av1->width == av->width &&
-                    av1->height == av->height &&
-                    av1->time_base.den == av->time_base.den &&
-                    av1->time_base.num == av->time_base.num &&
-                    av1->gop_size == av->gop_size)
-                    return i;
-                break;
-            default:
-                abort();
-            }
-        }
-    }
-
-    fst = add_av_stream1(feed, av, 0);
-    if (!fst)
-        return -1;
-    return feed->nb_streams - 1;
-}
-
-static void remove_stream(FFStream *stream)
-{
-    FFStream **ps;
-    ps = &first_stream;
-    while (*ps != NULL) {
-        if (*ps == stream)
-            *ps = (*ps)->next;
-        else
-            ps = &(*ps)->next;
-    }
-}
-
-/* specific mpeg4 handling : we extract the raw parameters */
-static void extract_mpeg4_header(AVFormatContext *infile)
-{
-    int mpeg4_count, i, size;
-    AVPacket pkt;
-    AVStream *st;
-    const uint8_t *p;
-
-    mpeg4_count = 0;
-    for(i=0;i<infile->nb_streams;i++) {
-        st = infile->streams[i];
-        if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
-            st->codec->extradata_size == 0) {
-            mpeg4_count++;
-        }
-    }
-    if (!mpeg4_count)
-        return;
-
-    printf("MPEG4 without extra data: trying to find header in %s\n", infile->filename);
-    while (mpeg4_count > 0) {
-        if (av_read_packet(infile, &pkt) < 0)
-            break;
-        st = infile->streams[pkt.stream_index];
-        if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
-            st->codec->extradata_size == 0) {
-            av_freep(&st->codec->extradata);
-            /* fill extradata with the header */
-            /* XXX: we make hard suppositions here ! */
-            p = pkt.data;
-            while (p < pkt.data + pkt.size - 4) {
-                /* stop when vop header is found */
-                if (p[0] == 0x00 && p[1] == 0x00 &&
-                    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_size = size;
-                    memcpy(st->codec->extradata, pkt.data, size);
-                    break;
-                }
-                p++;
-            }
-            mpeg4_count--;
-        }
-        av_free_packet(&pkt);
-    }
-}
-
-/* compute the needed AVStream for each file */
-static void build_file_streams(void)
-{
-    FFStream *stream, *stream_next;
-    int i, ret;
-
-    /* gather all streams */
-    for(stream = first_stream; stream != NULL; stream = stream_next) {
-        AVFormatContext *infile = NULL;
-        stream_next = stream->next;
-        if (stream->stream_type == STREAM_TYPE_LIVE &&
-            !stream->feed) {
-            /* the stream comes from a file */
-            /* try to open the file */
-            /* open stream */
-            if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
-                /* specific case : if transport stream output to RTP,
-                   we use a raw transport stream reader */
-                av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0);
-            }
-
-            http_log("Opening file '%s'\n", stream->feed_filename);
-            if ((ret = avformat_open_input(&infile, stream->feed_filename, stream->ifmt, &stream->in_opts)) < 0) {
-                http_log("Could not open '%s': %d\n", stream->feed_filename, ret);
-                /* remove stream (no need to spend more time on it) */
-            fail:
-                remove_stream(stream);
-            } else {
-                /* find all the AVStreams inside and reference them in
-                   'stream' */
-                if (avformat_find_stream_info(infile, NULL) < 0) {
-                    http_log("Could not find codec parameters from '%s'\n",
-                             stream->feed_filename);
-                    avformat_close_input(&infile);
-                    goto fail;
-                }
-                extract_mpeg4_header(infile);
-
-                for(i=0;i<infile->nb_streams;i++)
-                    add_av_stream1(stream, infile->streams[i]->codec, 1);
-
-                avformat_close_input(&infile);
-            }
-        }
-    }
-}
-
-/* compute the needed AVStream for each feed */
-static void build_feed_streams(void)
-{
-    FFStream *stream, *feed;
-    int i;
-
-    /* gather all streams */
-    for(stream = first_stream; stream != NULL; stream = stream->next) {
-        feed = stream->feed;
-        if (feed) {
-            if (stream->is_feed) {
-                for(i=0;i<stream->nb_streams;i++)
-                    stream->feed_streams[i] = i;
-            } else {
-                /* we handle a stream coming from a feed */
-                for(i=0;i<stream->nb_streams;i++)
-                    stream->feed_streams[i] = add_av_stream(feed, stream->streams[i]);
-            }
-        }
-    }
-
-    /* create feed files if needed */
-    for(feed = first_feed; feed != NULL; feed = feed->next_feed) {
-        int fd;
-
-        if (avio_check(feed->feed_filename, AVIO_FLAG_READ) > 0) {
-            /* See if it matches */
-            AVFormatContext *s = NULL;
-            int matches = 0;
-
-            if (avformat_open_input(&s, feed->feed_filename, NULL, NULL) >= 0) {
-                /* Now see if it matches */
-                if (s->nb_streams == feed->nb_streams) {
-                    matches = 1;
-                    for(i=0;i<s->nb_streams;i++) {
-                        AVStream *sf, *ss;
-                        sf = feed->streams[i];
-                        ss = s->streams[i];
-
-                        if (sf->index != ss->index ||
-                            sf->id != ss->id) {
-                            http_log("Index & Id do not match for stream %d (%s)\n",
-                                   i, feed->feed_filename);
-                            matches = 0;
-                        } else {
-                            AVCodecContext *ccf, *ccs;
-
-                            ccf = sf->codec;
-                            ccs = ss->codec;
-#define CHECK_CODEC(x)  (ccf->x != ccs->x)
-
-                            if (CHECK_CODEC(codec_id) || CHECK_CODEC(codec_type)) {
-                                http_log("Codecs do not match for stream %d\n", i);
-                                matches = 0;
-                            } else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) {
-                                http_log("Codec bitrates do not match for stream %d\n", i);
-                                matches = 0;
-                            } else if (ccf->codec_type == AVMEDIA_TYPE_VIDEO) {
-                                if (CHECK_CODEC(time_base.den) ||
-                                    CHECK_CODEC(time_base.num) ||
-                                    CHECK_CODEC(width) ||
-                                    CHECK_CODEC(height)) {
-                                    http_log("Codec width, height and framerate do not match for stream %d\n", i);
-                                    matches = 0;
-                                }
-                            } else if (ccf->codec_type == AVMEDIA_TYPE_AUDIO) {
-                                if (CHECK_CODEC(sample_rate) ||
-                                    CHECK_CODEC(channels) ||
-                                    CHECK_CODEC(frame_size)) {
-                                    http_log("Codec sample_rate, channels, frame_size do not match for stream %d\n", i);
-                                    matches = 0;
-                                }
-                            } else {
-                                http_log("Unknown codec type\n");
-                                matches = 0;
-                            }
-                        }
-                        if (!matches)
-                            break;
-                    }
-                } else
-                    http_log("Deleting feed file '%s' as stream counts differ (%d != %d)\n",
-                        feed->feed_filename, s->nb_streams, feed->nb_streams);
-
-                avformat_close_input(&s);
-            } else
-                http_log("Deleting feed file '%s' as it appears to be corrupt\n",
-                        feed->feed_filename);
-
-            if (!matches) {
-                if (feed->readonly) {
-                    http_log("Unable to delete feed file '%s' as it is marked readonly\n",
-                        feed->feed_filename);
-                    exit(1);
-                }
-                unlink(feed->feed_filename);
-            }
-        }
-        if (avio_check(feed->feed_filename, AVIO_FLAG_WRITE) <= 0) {
-            AVFormatContext s1 = {0}, *s = &s1;
-
-            if (feed->readonly) {
-                http_log("Unable to create feed file '%s' as it is marked readonly\n",
-                    feed->feed_filename);
-                exit(1);
-            }
-
-            /* only write the header of the ffm file */
-            if (avio_open(&s->pb, feed->feed_filename, AVIO_FLAG_WRITE) < 0) {
-                http_log("Could not open output feed file '%s'\n",
-                         feed->feed_filename);
-                exit(1);
-            }
-            s->oformat = feed->fmt;
-            s->nb_streams = feed->nb_streams;
-            s->streams = feed->streams;
-            if (avformat_write_header(s, NULL) < 0) {
-                http_log("Container doesn't supports the required parameters\n");
-                exit(1);
-            }
-            /* XXX: need better api */
-            av_freep(&s->priv_data);
-            avio_close(s->pb);
-        }
-        /* get feed size and write index */
-        fd = open(feed->feed_filename, O_RDONLY);
-        if (fd < 0) {
-            http_log("Could not open output feed file '%s'\n",
-                    feed->feed_filename);
-            exit(1);
-        }
-
-        feed->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
-        feed->feed_size = lseek(fd, 0, SEEK_END);
-        /* ensure that we do not wrap before the end of file */
-        if (feed->feed_max_size && feed->feed_max_size < feed->feed_size)
-            feed->feed_max_size = feed->feed_size;
-
-        close(fd);
-    }
-}
-
-/* compute the bandwidth used by each stream */
-static void compute_bandwidth(void)
-{
-    unsigned bandwidth;
-    int i;
-    FFStream *stream;
-
-    for(stream = first_stream; stream != NULL; stream = stream->next) {
-        bandwidth = 0;
-        for(i=0;i<stream->nb_streams;i++) {
-            AVStream *st = stream->streams[i];
-            switch(st->codec->codec_type) {
-            case AVMEDIA_TYPE_AUDIO:
-            case AVMEDIA_TYPE_VIDEO:
-                bandwidth += st->codec->bit_rate;
-                break;
-            default:
-                break;
-            }
-        }
-        stream->bandwidth = (bandwidth + 999) / 1000;
-    }
-}
-
-/* add a codec and set the default parameters */
-static void add_codec(FFStream *stream, AVCodecContext *av)
-{
-    AVStream *st;
-
-    /* compute default parameters */
-    switch(av->codec_type) {
-    case AVMEDIA_TYPE_AUDIO:
-        if (av->bit_rate == 0)
-            av->bit_rate = 64000;
-        if (av->sample_rate == 0)
-            av->sample_rate = 22050;
-        if (av->channels == 0)
-            av->channels = 1;
-        break;
-    case AVMEDIA_TYPE_VIDEO:
-        if (av->bit_rate == 0)
-            av->bit_rate = 64000;
-        if (av->time_base.num == 0){
-            av->time_base.den = 5;
-            av->time_base.num = 1;
-        }
-        if (av->width == 0 || av->height == 0) {
-            av->width = 160;
-            av->height = 128;
-        }
-        /* Bitrate tolerance is less for streaming */
-        if (av->bit_rate_tolerance == 0)
-            av->bit_rate_tolerance = FFMAX(av->bit_rate / 4,
-                      (int64_t)av->bit_rate*av->time_base.num/av->time_base.den);
-        if (av->qmin == 0)
-            av->qmin = 3;
-        if (av->qmax == 0)
-            av->qmax = 31;
-        if (av->max_qdiff == 0)
-            av->max_qdiff = 3;
-        av->qcompress = 0.5;
-        av->qblur = 0.5;
-
-        if (!av->nsse_weight)
-            av->nsse_weight = 8;
-
-        av->frame_skip_cmp = FF_CMP_DCTMAX;
-        if (!av->me_method)
-            av->me_method = ME_EPZS;
-        av->rc_buffer_aggressivity = 1.0;
-
-        if (!av->rc_eq)
-            av->rc_eq = "tex^qComp";
-        if (!av->i_quant_factor)
-            av->i_quant_factor = -0.8;
-        if (!av->b_quant_factor)
-            av->b_quant_factor = 1.25;
-        if (!av->b_quant_offset)
-            av->b_quant_offset = 1.25;
-        if (!av->rc_max_rate)
-            av->rc_max_rate = av->bit_rate * 2;
-
-        if (av->rc_max_rate && !av->rc_buffer_size) {
-            av->rc_buffer_size = av->rc_max_rate;
-        }
-
-
-        break;
-    default:
-        abort();
-    }
-
-    st = av_mallocz(sizeof(AVStream));
-    if (!st)
-        return;
-    st->codec = avcodec_alloc_context3(NULL);
-    stream->streams[stream->nb_streams++] = st;
-    memcpy(st->codec, av, sizeof(AVCodecContext));
-}
-
-static enum AVCodecID opt_audio_codec(const char *arg)
-{
-    AVCodec *p= avcodec_find_encoder_by_name(arg);
-
-    if (p == NULL || p->type != AVMEDIA_TYPE_AUDIO)
-        return AV_CODEC_ID_NONE;
-
-    return p->id;
-}
-
-static enum AVCodecID opt_video_codec(const char *arg)
-{
-    AVCodec *p= avcodec_find_encoder_by_name(arg);
-
-    if (p == NULL || p->type != AVMEDIA_TYPE_VIDEO)
-        return AV_CODEC_ID_NONE;
-
-    return p->id;
-}
-
-/* simplistic plugin support */
-
-#if HAVE_DLOPEN
-static void load_module(const char *filename)
-{
-    void *dll;
-    void (*init_func)(void);
-    dll = dlopen(filename, RTLD_NOW);
-    if (!dll) {
-        fprintf(stderr, "Could not load module '%s' - %s\n",
-                filename, dlerror());
-        return;
-    }
-
-    init_func = dlsym(dll, "avserver_module_init");
-    if (!init_func) {
-        fprintf(stderr,
-                "%s: init function 'avserver_module_init()' not found\n",
-                filename);
-        dlclose(dll);
-    }
-
-    init_func();
-}
-#endif
-
-static int avserver_opt_default(const char *opt, const char *arg,
-                       AVCodecContext *avctx, int type)
-{
-    int ret = 0;
-    const AVOption *o = av_opt_find(avctx, opt, NULL, type, 0);
-    if(o)
-        ret = av_opt_set(avctx, opt, arg, 0);
-    return ret;
-}
-
-static int avserver_opt_preset(const char *arg,
-                       AVCodecContext *avctx, int type,
-                       enum AVCodecID *audio_id, enum AVCodecID *video_id)
-{
-    FILE *f=NULL;
-    char filename[1000], tmp[1000], tmp2[1000], line[1000];
-    int ret = 0;
-    AVCodec *codec = avcodec_find_encoder(avctx->codec_id);
-
-    if (!(f = get_preset_file(filename, sizeof(filename), arg, 0,
-                              codec ? codec->name : NULL))) {
-        fprintf(stderr, "File for preset '%s' not found\n", arg);
-        return 1;
-    }
-
-    while(!feof(f)){
-        int e= fscanf(f, "%999[^\n]\n", line) - 1;
-        if(line[0] == '#' && !e)
-            continue;
-        e|= sscanf(line, "%999[^=]=%999[^\n]\n", tmp, tmp2) - 2;
-        if(e){
-            fprintf(stderr, "%s: Invalid syntax: '%s'\n", filename, line);
-            ret = 1;
-            break;
-        }
-        if(!strcmp(tmp, "acodec")){
-            *audio_id = opt_audio_codec(tmp2);
-        }else if(!strcmp(tmp, "vcodec")){
-            *video_id = opt_video_codec(tmp2);
-        }else if(!strcmp(tmp, "scodec")){
-            /* opt_subtitle_codec(tmp2); */
-        }else if(avserver_opt_default(tmp, tmp2, avctx, type) < 0){
-            fprintf(stderr, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n", filename, line, tmp, tmp2);
-            ret = 1;
-            break;
-        }
-    }
-
-    fclose(f);
-
-    return ret;
-}
-
-static AVOutputFormat *avserver_guess_format(const char *short_name, const char *filename,
-                                             const char *mime_type)
-{
-    AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type);
-
-    if (fmt) {
-        AVOutputFormat *stream_fmt;
-        char stream_format_name[64];
-
-        snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
-        stream_fmt = av_guess_format(stream_format_name, NULL, NULL);
-
-        if (stream_fmt)
-            fmt = stream_fmt;
-    }
-
-    return fmt;
-}
-
-static void report_config_error(const char *filename, int line_num, int *errors, const char *fmt, ...)
-{
-    va_list vl;
-    va_start(vl, fmt);
-    fprintf(stderr, "%s:%d: ", filename, line_num);
-    vfprintf(stderr, fmt, vl);
-    va_end(vl);
-
-    (*errors)++;
-}
-
-static int parse_ffconfig(const char *filename)
-{
-    FILE *f;
-    char line[1024];
-    char cmd[64];
-    char arg[1024];
-    const char *p;
-    int val, errors, line_num;
-    FFStream **last_stream, *stream, *redirect;
-    FFStream **last_feed, *feed, *s;
-    AVCodecContext audio_enc, video_enc;
-    enum AVCodecID audio_id, video_id;
-
-    f = fopen(filename, "r");
-    if (!f) {
-        perror(filename);
-        return -1;
-    }
-
-    errors = 0;
-    line_num = 0;
-    first_stream = NULL;
-    last_stream = &first_stream;
-    first_feed = NULL;
-    last_feed = &first_feed;
-    stream = NULL;
-    feed = NULL;
-    redirect = NULL;
-    audio_id = AV_CODEC_ID_NONE;
-    video_id = AV_CODEC_ID_NONE;
-
-#define ERROR(...) report_config_error(filename, line_num, &errors, __VA_ARGS__)
-    for(;;) {
-        if (fgets(line, sizeof(line), f) == NULL)
-            break;
-        line_num++;
-        p = line;
-        while (isspace(*p))
-            p++;
-        if (*p == '\0' || *p == '#')
-            continue;
-
-        get_arg(cmd, sizeof(cmd), &p);
-
-        if (!av_strcasecmp(cmd, "Port")) {
-            get_arg(arg, sizeof(arg), &p);
-            val = atoi(arg);
-            if (val < 1 || val > 65536) {
-                ERROR("Invalid_port: %s\n", arg);
-            }
-            my_http_addr.sin_port = htons(val);
-        } else if (!av_strcasecmp(cmd, "BindAddress")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (resolve_host(&my_http_addr.sin_addr, arg) != 0) {
-                ERROR("%s:%d: Invalid host/IP address: %s\n", arg);
-            }
-        } else if (!av_strcasecmp(cmd, "NoDaemon")) {
-            avserver_daemon = 0;
-        } else if (!av_strcasecmp(cmd, "RTSPPort")) {
-            get_arg(arg, sizeof(arg), &p);
-            val = atoi(arg);
-            if (val < 1 || val > 65536) {
-                ERROR("%s:%d: Invalid port: %s\n", arg);
-            }
-            my_rtsp_addr.sin_port = htons(atoi(arg));
-        } else if (!av_strcasecmp(cmd, "RTSPBindAddress")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (resolve_host(&my_rtsp_addr.sin_addr, arg) != 0) {
-                ERROR("Invalid host/IP address: %s\n", arg);
-            }
-        } else if (!av_strcasecmp(cmd, "MaxHTTPConnections")) {
-            get_arg(arg, sizeof(arg), &p);
-            val = atoi(arg);
-            if (val < 1 || val > 65536) {
-                ERROR("Invalid MaxHTTPConnections: %s\n", arg);
-            }
-            nb_max_http_connections = val;
-        } else if (!av_strcasecmp(cmd, "MaxClients")) {
-            get_arg(arg, sizeof(arg), &p);
-            val = atoi(arg);
-            if (val < 1 || val > nb_max_http_connections) {
-                ERROR("Invalid MaxClients: %s\n", arg);
-            } else {
-                nb_max_connections = val;
-            }
-        } else if (!av_strcasecmp(cmd, "MaxBandwidth")) {
-            int64_t llval;
-            get_arg(arg, sizeof(arg), &p);
-            llval = atoll(arg);
-            if (llval < 10 || llval > 10000000) {
-                ERROR("Invalid MaxBandwidth: %s\n", arg);
-            } else
-                max_bandwidth = llval;
-        } else if (!av_strcasecmp(cmd, "CustomLog")) {
-            if (!avserver_debug)
-                get_arg(logfilename, sizeof(logfilename), &p);
-        } else if (!av_strcasecmp(cmd, "<Feed")) {
-            /*********************************************/
-            /* Feed related options */
-            char *q;
-            if (stream || feed) {
-                ERROR("Already in a tag\n");
-            } else {
-                feed = av_mallocz(sizeof(FFStream));
-                get_arg(feed->filename, sizeof(feed->filename), &p);
-                q = strrchr(feed->filename, '>');
-                if (*q)
-                    *q = '\0';
-
-                for (s = first_feed; s; s = s->next) {
-                    if (!strcmp(feed->filename, s->filename)) {
-                        ERROR("Feed '%s' already registered\n", s->filename);
-                    }
-                }
-
-                feed->fmt = av_guess_format("ffm", NULL, NULL);
-                /* defaut feed file */
-                snprintf(feed->feed_filename, sizeof(feed->feed_filename),
-                         "/tmp/%s.ffm", feed->filename);
-                feed->feed_max_size = 5 * 1024 * 1024;
-                feed->is_feed = 1;
-                feed->feed = feed; /* self feeding :-) */
-
-                /* add in stream list */
-                *last_stream = feed;
-                last_stream = &feed->next;
-                /* add in feed list */
-                *last_feed = feed;
-                last_feed = &feed->next_feed;
-            }
-        } else if (!av_strcasecmp(cmd, "Launch")) {
-            if (feed) {
-                int i;
-
-                feed->child_argv = av_mallocz(64 * sizeof(char *));
-
-                for (i = 0; i < 62; i++) {
-                    get_arg(arg, sizeof(arg), &p);
-                    if (!arg[0])
-                        break;
-
-                    feed->child_argv[i] = av_strdup(arg);
-                }
-
-                feed->child_argv[i] = av_malloc(30 + strlen(feed->filename));
-
-                snprintf(feed->child_argv[i], 30+strlen(feed->filename),
-                    "http://%s:%d/%s",
-                        (my_http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" :
-                    inet_ntoa(my_http_addr.sin_addr),
-                    ntohs(my_http_addr.sin_port), feed->filename);
-            }
-        } else if (!av_strcasecmp(cmd, "ReadOnlyFile")) {
-            if (feed) {
-                get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
-                feed->readonly = 1;
-            } else if (stream) {
-                get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
-            }
-        } else if (!av_strcasecmp(cmd, "File")) {
-            if (feed) {
-                get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
-            } else if (stream)
-                get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
-        } else if (!av_strcasecmp(cmd, "Truncate")) {
-            if (feed) {
-                get_arg(arg, sizeof(arg), &p);
-                feed->truncate = strtod(arg, NULL);
-            }
-        } else if (!av_strcasecmp(cmd, "FileMaxSize")) {
-            if (feed) {
-                char *p1;
-                double fsize;
-
-                get_arg(arg, sizeof(arg), &p);
-                p1 = arg;
-                fsize = strtod(p1, &p1);
-                switch(toupper(*p1)) {
-                case 'K':
-                    fsize *= 1024;
-                    break;
-                case 'M':
-                    fsize *= 1024 * 1024;
-                    break;
-                case 'G':
-                    fsize *= 1024 * 1024 * 1024;
-                    break;
-                }
-                feed->feed_max_size = (int64_t)fsize;
-                if (feed->feed_max_size < FFM_PACKET_SIZE*4) {
-                    ERROR("Feed max file size is too small, must be at least %d\n", FFM_PACKET_SIZE*4);
-                }
-            }
-        } else if (!av_strcasecmp(cmd, "</Feed>")) {
-            if (!feed) {
-                ERROR("No corresponding <Feed> for </Feed>\n");
-            }
-            feed = NULL;
-        } else if (!av_strcasecmp(cmd, "<Stream")) {
-            /*********************************************/
-            /* Stream related options */
-            char *q;
-            if (stream || feed) {
-                ERROR("Already in a tag\n");
-            } else {
-                FFStream *s;
-                stream = av_mallocz(sizeof(FFStream));
-                get_arg(stream->filename, sizeof(stream->filename), &p);
-                q = strrchr(stream->filename, '>');
-                if (*q)
-                    *q = '\0';
-
-                for (s = first_stream; s; s = s->next) {
-                    if (!strcmp(stream->filename, s->filename)) {
-                        ERROR("Stream '%s' already registered\n", s->filename);
-                    }
-                }
-
-                stream->fmt = avserver_guess_format(NULL, stream->filename, NULL);
-                avcodec_get_context_defaults3(&video_enc, NULL);
-                avcodec_get_context_defaults3(&audio_enc, NULL);
-                audio_id = AV_CODEC_ID_NONE;
-                video_id = AV_CODEC_ID_NONE;
-                if (stream->fmt) {
-                    audio_id = stream->fmt->audio_codec;
-                    video_id = stream->fmt->video_codec;
-                }
-
-                *last_stream = stream;
-                last_stream = &stream->next;
-            }
-        } else if (!av_strcasecmp(cmd, "Feed")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream) {
-                FFStream *sfeed;
-
-                sfeed = first_feed;
-                while (sfeed != NULL) {
-                    if (!strcmp(sfeed->filename, arg))
-                        break;
-                    sfeed = sfeed->next_feed;
-                }
-                if (!sfeed)
-                    ERROR("feed '%s' not defined\n", arg);
-                else
-                    stream->feed = sfeed;
-            }
-        } else if (!av_strcasecmp(cmd, "Format")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream) {
-                if (!strcmp(arg, "status")) {
-                    stream->stream_type = STREAM_TYPE_STATUS;
-                    stream->fmt = NULL;
-                } else {
-                    stream->stream_type = STREAM_TYPE_LIVE;
-                    /* jpeg cannot be used here, so use single frame jpeg */
-                    if (!strcmp(arg, "jpeg"))
-                        strcpy(arg, "mjpeg");
-                    stream->fmt = avserver_guess_format(arg, NULL, NULL);
-                    if (!stream->fmt) {
-                        ERROR("Unknown Format: %s\n", arg);
-                    }
-                }
-                if (stream->fmt) {
-                    audio_id = stream->fmt->audio_codec;
-                    video_id = stream->fmt->video_codec;
-                }
-            }
-        } else if (!av_strcasecmp(cmd, "InputFormat")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream) {
-                stream->ifmt = av_find_input_format(arg);
-                if (!stream->ifmt) {
-                    ERROR("Unknown input format: %s\n", arg);
-                }
-            }
-        } else if (!av_strcasecmp(cmd, "FaviconURL")) {
-            if (stream && stream->stream_type == STREAM_TYPE_STATUS) {
-                get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
-            } else {
-                ERROR("FaviconURL only permitted for status streams\n");
-            }
-        } else if (!av_strcasecmp(cmd, "Author")) {
-            if (stream)
-                get_arg(stream->author, sizeof(stream->author), &p);
-        } else if (!av_strcasecmp(cmd, "Comment")) {
-            if (stream)
-                get_arg(stream->comment, sizeof(stream->comment), &p);
-        } else if (!av_strcasecmp(cmd, "Copyright")) {
-            if (stream)
-                get_arg(stream->copyright, sizeof(stream->copyright), &p);
-        } else if (!av_strcasecmp(cmd, "Title")) {
-            if (stream)
-                get_arg(stream->title, sizeof(stream->title), &p);
-        } else if (!av_strcasecmp(cmd, "Preroll")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream)
-                stream->prebuffer = atof(arg) * 1000;
-        } else if (!av_strcasecmp(cmd, "StartSendOnKey")) {
-            if (stream)
-                stream->send_on_key = 1;
-        } else if (!av_strcasecmp(cmd, "AudioCodec")) {
-            get_arg(arg, sizeof(arg), &p);
-            audio_id = opt_audio_codec(arg);
-            if (audio_id == AV_CODEC_ID_NONE) {
-                ERROR("Unknown AudioCodec: %s\n", arg);
-            }
-        } else if (!av_strcasecmp(cmd, "VideoCodec")) {
-            get_arg(arg, sizeof(arg), &p);
-            video_id = opt_video_codec(arg);
-            if (video_id == AV_CODEC_ID_NONE) {
-                ERROR("Unknown VideoCodec: %s\n", arg);
-            }
-        } else if (!av_strcasecmp(cmd, "MaxTime")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream)
-                stream->max_time = atof(arg) * 1000;
-        } else if (!av_strcasecmp(cmd, "AudioBitRate")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream)
-                audio_enc.bit_rate = lrintf(atof(arg) * 1000);
-        } else if (!av_strcasecmp(cmd, "AudioChannels")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream)
-                audio_enc.channels = atoi(arg);
-        } else if (!av_strcasecmp(cmd, "AudioSampleRate")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream)
-                audio_enc.sample_rate = atoi(arg);
-        } else if (!av_strcasecmp(cmd, "AudioQuality")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream) {
-//                audio_enc.quality = atof(arg) * 1000;
-            }
-        } else if (!av_strcasecmp(cmd, "VideoBitRateRange")) {
-            if (stream) {
-                int minrate, maxrate;
-
-                get_arg(arg, sizeof(arg), &p);
-
-                if (sscanf(arg, "%d-%d", &minrate, &maxrate) == 2) {
-                    video_enc.rc_min_rate = minrate * 1000;
-                    video_enc.rc_max_rate = maxrate * 1000;
-                } else {
-                    ERROR("Incorrect format for VideoBitRateRange -- should be <min>-<max>: %s\n", arg);
-                }
-            }
-        } else if (!av_strcasecmp(cmd, "Debug")) {
-            if (stream) {
-                get_arg(arg, sizeof(arg), &p);
-                video_enc.debug = strtol(arg,0,0);
-            }
-        } else if (!av_strcasecmp(cmd, "Strict")) {
-            if (stream) {
-                get_arg(arg, sizeof(arg), &p);
-                video_enc.strict_std_compliance = atoi(arg);
-            }
-        } else if (!av_strcasecmp(cmd, "VideoBufferSize")) {
-            if (stream) {
-                get_arg(arg, sizeof(arg), &p);
-                video_enc.rc_buffer_size = atoi(arg) * 8*1024;
-            }
-        } else if (!av_strcasecmp(cmd, "VideoBitRateTolerance")) {
-            if (stream) {
-                get_arg(arg, sizeof(arg), &p);
-                video_enc.bit_rate_tolerance = atoi(arg) * 1000;
-            }
-        } else if (!av_strcasecmp(cmd, "VideoBitRate")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream) {
-                video_enc.bit_rate = atoi(arg) * 1000;
-            }
-        } else if (!av_strcasecmp(cmd, "VideoSize")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream) {
-                av_parse_video_size(&video_enc.width, &video_enc.height, arg);
-                if ((video_enc.width % 16) != 0 ||
-                    (video_enc.height % 16) != 0) {
-                    ERROR("Image size must be a multiple of 16\n");
-                }
-            }
-        } else if (!av_strcasecmp(cmd, "VideoFrameRate")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream) {
-                AVRational frame_rate;
-                if (av_parse_video_rate(&frame_rate, arg) < 0) {
-                    ERROR("Incorrect frame rate: %s\n", arg);
-                } else {
-                    video_enc.time_base.num = frame_rate.den;
-                    video_enc.time_base.den = frame_rate.num;
-                }
-            }
-        } else if (!av_strcasecmp(cmd, "VideoGopSize")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream)
-                video_enc.gop_size = atoi(arg);
-        } else if (!av_strcasecmp(cmd, "VideoIntraOnly")) {
-            if (stream)
-                video_enc.gop_size = 1;
-        } else if (!av_strcasecmp(cmd, "VideoHighQuality")) {
-            if (stream)
-                video_enc.mb_decision = FF_MB_DECISION_BITS;
-        } else if (!av_strcasecmp(cmd, "Video4MotionVector")) {
-            if (stream) {
-                video_enc.mb_decision = FF_MB_DECISION_BITS; //FIXME remove
-                video_enc.flags |= CODEC_FLAG_4MV;
-            }
-        } else if (!av_strcasecmp(cmd, "AVOptionVideo") ||
-                   !av_strcasecmp(cmd, "AVOptionAudio")) {
-            char arg2[1024];
-            AVCodecContext *avctx;
-            int type;
-            get_arg(arg, sizeof(arg), &p);
-            get_arg(arg2, sizeof(arg2), &p);
-            if (!av_strcasecmp(cmd, "AVOptionVideo")) {
-                avctx = &video_enc;
-                type = AV_OPT_FLAG_VIDEO_PARAM;
-            } else {
-                avctx = &audio_enc;
-                type = AV_OPT_FLAG_AUDIO_PARAM;
-            }
-            if (avserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) {
-                ERROR("AVOption error: %s %s\n", arg, arg2);
-            }
-        } else if (!av_strcasecmp(cmd, "AVPresetVideo") ||
-                   !av_strcasecmp(cmd, "AVPresetAudio")) {
-            AVCodecContext *avctx;
-            int type;
-            get_arg(arg, sizeof(arg), &p);
-            if (!av_strcasecmp(cmd, "AVPresetVideo")) {
-                avctx = &video_enc;
-                video_enc.codec_id = video_id;
-                type = AV_OPT_FLAG_VIDEO_PARAM;
-            } else {
-                avctx = &audio_enc;
-                audio_enc.codec_id = audio_id;
-                type = AV_OPT_FLAG_AUDIO_PARAM;
-            }
-            if (avserver_opt_preset(arg, avctx, type|AV_OPT_FLAG_ENCODING_PARAM, &audio_id, &video_id)) {
-                ERROR("AVPreset error: %s\n", arg);
-            }
-        } else if (!av_strcasecmp(cmd, "VideoTag")) {
-            get_arg(arg, sizeof(arg), &p);
-            if ((strlen(arg) == 4) && stream)
-                video_enc.codec_tag = MKTAG(arg[0], arg[1], arg[2], arg[3]);
-        } else if (!av_strcasecmp(cmd, "BitExact")) {
-            if (stream)
-                video_enc.flags |= CODEC_FLAG_BITEXACT;
-        } else if (!av_strcasecmp(cmd, "DctFastint")) {
-            if (stream)
-                video_enc.dct_algo  = FF_DCT_FASTINT;
-        } else if (!av_strcasecmp(cmd, "IdctSimple")) {
-            if (stream)
-                video_enc.idct_algo = FF_IDCT_SIMPLE;
-        } else if (!av_strcasecmp(cmd, "Qscale")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream) {
-                video_enc.flags |= CODEC_FLAG_QSCALE;
-                video_enc.global_quality = FF_QP2LAMBDA * atoi(arg);
-            }
-        } else if (!av_strcasecmp(cmd, "VideoQDiff")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream) {
-                video_enc.max_qdiff = atoi(arg);
-                if (video_enc.max_qdiff < 1 || video_enc.max_qdiff > 31) {
-                    ERROR("VideoQDiff out of range\n");
-                }
-            }
-        } else if (!av_strcasecmp(cmd, "VideoQMax")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream) {
-                video_enc.qmax = atoi(arg);
-                if (video_enc.qmax < 1 || video_enc.qmax > 31) {
-                    ERROR("VideoQMax out of range\n");
-                }
-            }
-        } else if (!av_strcasecmp(cmd, "VideoQMin")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream) {
-                video_enc.qmin = atoi(arg);
-                if (video_enc.qmin < 1 || video_enc.qmin > 31) {
-                    ERROR("VideoQMin out of range\n");
-                }
-            }
-        } else if (!av_strcasecmp(cmd, "LumaElim")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream)
-                video_enc.luma_elim_threshold = atoi(arg);
-        } else if (!av_strcasecmp(cmd, "ChromaElim")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream)
-                video_enc.chroma_elim_threshold = atoi(arg);
-        } else if (!av_strcasecmp(cmd, "LumiMask")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream)
-                video_enc.lumi_masking = atof(arg);
-        } else if (!av_strcasecmp(cmd, "DarkMask")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream)
-                video_enc.dark_masking = atof(arg);
-        } else if (!av_strcasecmp(cmd, "NoVideo")) {
-            video_id = AV_CODEC_ID_NONE;
-        } else if (!av_strcasecmp(cmd, "NoAudio")) {
-            audio_id = AV_CODEC_ID_NONE;
-        } else if (!av_strcasecmp(cmd, "ACL")) {
-            parse_acl_row(stream, feed, NULL, p, filename, line_num);
-        } else if (!av_strcasecmp(cmd, "DynamicACL")) {
-            if (stream) {
-                get_arg(stream->dynamic_acl, sizeof(stream->dynamic_acl), &p);
-            }
-        } else if (!av_strcasecmp(cmd, "RTSPOption")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream) {
-                av_freep(&stream->rtsp_option);
-                stream->rtsp_option = av_strdup(arg);
-            }
-        } else if (!av_strcasecmp(cmd, "MulticastAddress")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream) {
-                if (resolve_host(&stream->multicast_ip, arg) != 0) {
-                    ERROR("Invalid host/IP address: %s\n", arg);
-                }
-                stream->is_multicast = 1;
-                stream->loop = 1; /* default is looping */
-            }
-        } else if (!av_strcasecmp(cmd, "MulticastPort")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream)
-                stream->multicast_port = atoi(arg);
-        } else if (!av_strcasecmp(cmd, "MulticastTTL")) {
-            get_arg(arg, sizeof(arg), &p);
-            if (stream)
-                stream->multicast_ttl = atoi(arg);
-        } else if (!av_strcasecmp(cmd, "NoLoop")) {
-            if (stream)
-                stream->loop = 0;
-        } else if (!av_strcasecmp(cmd, "</Stream>")) {
-            if (!stream) {
-                ERROR("No corresponding <Stream> for </Stream>\n");
-            } else {
-                if (stream->feed && stream->fmt && strcmp(stream->fmt->name, "ffm") != 0) {
-                    if (audio_id != AV_CODEC_ID_NONE) {
-                        audio_enc.codec_type = AVMEDIA_TYPE_AUDIO;
-                        audio_enc.codec_id = audio_id;
-                        add_codec(stream, &audio_enc);
-                    }
-                    if (video_id != AV_CODEC_ID_NONE) {
-                        video_enc.codec_type = AVMEDIA_TYPE_VIDEO;
-                        video_enc.codec_id = video_id;
-                        add_codec(stream, &video_enc);
-                    }
-                }
-                stream = NULL;
-            }
-        } else if (!av_strcasecmp(cmd, "<Redirect")) {
-            /*********************************************/
-            char *q;
-            if (stream || feed || redirect) {
-                ERROR("Already in a tag\n");
-            } else {
-                redirect = av_mallocz(sizeof(FFStream));
-                *last_stream = redirect;
-                last_stream = &redirect->next;
-
-                get_arg(redirect->filename, sizeof(redirect->filename), &p);
-                q = strrchr(redirect->filename, '>');
-                if (*q)
-                    *q = '\0';
-                redirect->stream_type = STREAM_TYPE_REDIRECT;
-            }
-        } else if (!av_strcasecmp(cmd, "URL")) {
-            if (redirect)
-                get_arg(redirect->feed_filename, sizeof(redirect->feed_filename), &p);
-        } else if (!av_strcasecmp(cmd, "</Redirect>")) {
-            if (!redirect) {
-                ERROR("No corresponding <Redirect> for </Redirect>\n");
-            } else {
-                if (!redirect->feed_filename[0]) {
-                    ERROR("No URL found for <Redirect>\n");
-                }
-                redirect = NULL;
-            }
-        } else if (!av_strcasecmp(cmd, "LoadModule")) {
-            get_arg(arg, sizeof(arg), &p);
-#if HAVE_DLOPEN
-            load_module(arg);
-#else
-            ERROR("Module support not compiled into this version: '%s'\n", arg);
-#endif
-        } else {
-            ERROR("Incorrect keyword: '%s'\n", cmd);
-        }
-    }
-#undef ERROR
-
-    fclose(f);
-    if (errors)
-        return -1;
-    else
-        return 0;
-}
-
-static void handle_child_exit(int sig)
-{
-    pid_t pid;
-    int status;
-
-    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
-        FFStream *feed;
-
-        for (feed = first_feed; feed; feed = feed->next) {
-            if (feed->pid == pid) {
-                int uptime = time(0) - feed->pid_start;
-
-                feed->pid = 0;
-                fprintf(stderr, "%s: Pid %d exited with status %d after %d seconds\n", feed->filename, pid, status, uptime);
-
-                if (uptime < 30)
-                    /* Turn off any more restarts */
-                    feed->child_argv = 0;
-            }
-        }
-    }
-
-    need_to_start_children = 1;
-}
-
-static void opt_debug(void)
-{
-    avserver_debug = 1;
-    avserver_daemon = 0;
-    logfilename[0] = '-';
-}
-
-void show_help_default(const char *opt, const char *arg)
-{
-    printf("usage: avserver [options]\n"
-           "Hyper fast multi format Audio/Video streaming server\n");
-    printf("\n");
-    show_help_options(options, "Main options:", 0, 0, 0);
-}
-
-static const OptionDef options[] = {
-#include "cmdutils_common_opts.h"
-    { "n", OPT_BOOL, {(void *)&no_launch }, "enable no-launch mode" },
-    { "d", 0, {(void*)opt_debug}, "enable debug mode" },
-    { "f", HAS_ARG | OPT_STRING, {(void*)&config_filename }, "use configfile instead of /etc/avserver.conf", "configfile" },
-    { NULL },
-};
-
-int main(int argc, char **argv)
-{
-    struct sigaction sigact = { { 0 } };
-
-    parse_loglevel(argc, argv, options);
-    av_register_all();
-    avformat_network_init();
-
-    show_banner();
-
-    my_program_name = argv[0];
-    my_program_dir = getcwd(0, 0);
-    avserver_daemon = 1;
-
-    parse_options(NULL, argc, argv, options, NULL);
-
-    unsetenv("http_proxy");             /* Kill the http_proxy */
-
-    av_lfg_init(&random_state, av_get_random_seed());
-
-    sigact.sa_handler = handle_child_exit;
-    sigact.sa_flags = SA_NOCLDSTOP | SA_RESTART;
-    sigaction(SIGCHLD, &sigact, 0);
-
-    if (parse_ffconfig(config_filename) < 0) {
-        fprintf(stderr, "Incorrect config file - exiting.\n");
-        exit(1);
-    }
-
-    /* open log file if needed */
-    if (logfilename[0] != '\0') {
-        if (!strcmp(logfilename, "-"))
-            logfile = stdout;
-        else
-            logfile = fopen(logfilename, "a");
-        av_log_set_callback(http_av_log);
-    }
-
-    build_file_streams();
-
-    build_feed_streams();
-
-    compute_bandwidth();
-
-    /* put the process in background and detach it from its TTY */
-    if (avserver_daemon) {
-        int pid;
-
-        pid = fork();
-        if (pid < 0) {
-            perror("fork");
-            exit(1);
-        } else if (pid > 0) {
-            /* parent : exit */
-            exit(0);
-        } else {
-            /* child */
-            setsid();
-            close(0);
-            open("/dev/null", O_RDWR);
-            if (strcmp(logfilename, "-") != 0) {
-                close(1);
-                dup(0);
-            }
-            close(2);
-            dup(0);
-        }
-    }
-
-    /* signal init */
-    signal(SIGPIPE, SIG_IGN);
-
-    if (avserver_daemon)
-        chdir("/");
-
-    if (http_server() < 0) {
-        http_log("Could not start server\n");
-        exit(1);
-    }
-
-    return 0;
-}
diff --git a/cmdutils.c b/cmdutils.c
index 34c52ca..2312ca2 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -2,20 +2,20 @@
  * Various utilities for command line tools
  * Copyright (c) 2000-2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,11 +29,16 @@
    references to libraries that are not being built. */
 
 #include "config.h"
+#include "compat/va_copy.h"
 #include "libavformat/avformat.h"
 #include "libavfilter/avfilter.h"
 #include "libavdevice/avdevice.h"
 #include "libavresample/avresample.h"
 #include "libswscale/swscale.h"
+#include "libswresample/swresample.h"
+#if CONFIG_POSTPROC
+#include "libpostproc/postprocess.h"
+#endif
 #include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/mathematics.h"
@@ -53,16 +58,22 @@
 #endif
 
 struct SwsContext *sws_opts;
+SwrContext *swr_opts;
 AVDictionary *format_opts, *codec_opts;
 
-static const int this_year = 2012;
+const int this_year = 2012;
+
+static FILE *report_file;
 
 void init_opts(void)
 {
-#if CONFIG_SWSCALE
-    sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC,
+
+    if(CONFIG_SWSCALE)
+        sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC,
                               NULL, NULL, NULL);
-#endif
+
+    if(CONFIG_SWRESAMPLE)
+        swr_opts = swr_alloc();
 }
 
 void uninit_opts(void)
@@ -71,6 +82,10 @@
     sws_freeContext(sws_opts);
     sws_opts = NULL;
 #endif
+
+    if(CONFIG_SWRESAMPLE)
+        swr_free(&swr_opts);
+
     av_dict_free(&format_opts);
     av_dict_free(&codec_opts);
 }
@@ -80,6 +95,20 @@
     vfprintf(stdout, fmt, vl);
 }
 
+static void log_callback_report(void *ptr, int level, const char *fmt, va_list vl)
+{
+    va_list vl2;
+    char line[1024];
+    static int print_prefix = 1;
+
+    va_copy(vl2, vl);
+    av_log_default_callback(ptr, level, fmt, vl);
+    av_log_format_line(ptr, level, fmt, vl2, line, sizeof(line), &print_prefix);
+    va_end(vl2);
+    fputs(line, report_file);
+    fflush(report_file);
+}
+
 double parse_number_or_die(const char *context, const char *numstr, int type,
                            double min, double max)
 {
@@ -145,8 +174,10 @@
 void show_help_children(const AVClass *class, int flags)
 {
     const AVClass *child = NULL;
-    av_opt_show2(&class, NULL, flags, 0);
-    printf("\n");
+    if (class->option) {
+        av_opt_show2(&class, NULL, flags, 0);
+        printf("\n");
+    }
 
     while (child = av_opt_child_class_next(class, child))
         show_help_children(child, flags);
@@ -271,7 +302,7 @@
     if (po->flags & OPT_STRING) {
         char *str;
         str = av_strdup(arg);
-        av_freep(dst);
+//         av_freep(dst);
         *(char **)dst = str;
     } else if (po->flags & OPT_BOOL) {
         *(int *)dst = bool_val;
@@ -355,6 +386,30 @@
     return 0;
 }
 
+static void dump_argument(const char *a)
+{
+    const unsigned char *p;
+
+    for (p = a; *p; p++)
+        if (!((*p >= '+' && *p <= ':') || (*p >= '@' && *p <= 'Z') ||
+              *p == '_' || (*p >= 'a' && *p <= 'z')))
+            break;
+    if (!*p) {
+        fputs(a, report_file);
+        return;
+    }
+    fputc('"', report_file);
+    for (p = a; *p; p++) {
+        if (*p == '\\' || *p == '"' || *p == '$' || *p == '`')
+            fprintf(report_file, "\\%c", *p);
+        else if (*p < ' ' || *p > '~')
+            fprintf(report_file, "\\x%02x", *p);
+        else
+            fputc(*p, report_file);
+    }
+    fputc('"', report_file);
+}
+
 void parse_loglevel(int argc, char **argv, const OptionDef *options)
 {
     int idx = locate_option(argc, argv, options, "loglevel");
@@ -362,6 +417,19 @@
         idx = locate_option(argc, argv, options, "v");
     if (idx && argv[idx + 1])
         opt_loglevel(NULL, "loglevel", argv[idx + 1]);
+    idx = locate_option(argc, argv, options, "report");
+    if (idx || getenv("FFREPORT")) {
+        opt_report("report");
+        if (report_file) {
+            int i;
+            fprintf(report_file, "Command line:\n");
+            for (i = 0; i < argc; i++) {
+                dump_argument(argv[i]);
+                fputc(i < argc - 1 ? ' ' : '\n', report_file);
+            }
+            fflush(report_file);
+        }
+    }
 }
 
 #define FLAGS (o->type == AV_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
@@ -370,7 +438,7 @@
     const AVOption *o;
     char opt_stripped[128];
     const char *p;
-    const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc = sws_get_class();
+    const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc, *swr_class;
 
     if (!(p = strchr(opt, ':')))
         p = opt + strlen(opt);
@@ -384,8 +452,10 @@
     else if ((o = av_opt_find(&fc, opt, NULL, 0,
                               AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
         av_dict_set(&format_opts, opt, arg, FLAGS);
-    else if ((o = av_opt_find(&sc, opt, NULL, 0,
-                              AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
+#if CONFIG_SWSCALE
+    sc = sws_get_class();
+    if (!o && (o = av_opt_find(&sc, opt, NULL, 0,
+                         AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
         // XXX we only support sws_flags, not arbitrary sws options
         int ret = av_opt_set(sws_opts, opt, arg, 0);
         if (ret < 0) {
@@ -393,6 +463,18 @@
             return ret;
         }
     }
+#endif
+#if CONFIG_SWRESAMPLE
+    swr_class = swr_get_class();
+    if (!o && (o = 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 (ret < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
+            return ret;
+        }
+    }
+#endif
 
     if (o)
         return 0;
@@ -435,6 +517,70 @@
     return 0;
 }
 
+int opt_report(const char *opt)
+{
+    char filename[64];
+    time_t now;
+    struct tm *tm;
+
+    if (report_file) /* already opened */
+        return 0;
+    time(&now);
+    tm = localtime(&now);
+    snprintf(filename, sizeof(filename), "%s-%04d%02d%02d-%02d%02d%02d.log",
+             program_name,
+             tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+             tm->tm_hour, tm->tm_min, tm->tm_sec);
+    report_file = fopen(filename, "w");
+    if (!report_file) {
+        av_log(NULL, AV_LOG_ERROR, "Failed to open report \"%s\": %s\n",
+               filename, strerror(errno));
+        return AVERROR(errno);
+    }
+    av_log_set_callback(log_callback_report);
+    av_log(NULL, AV_LOG_INFO,
+           "%s started on %04d-%02d-%02d at %02d:%02d:%02d\n"
+           "Report written to \"%s\"\n",
+           program_name,
+           tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+           tm->tm_hour, tm->tm_min, tm->tm_sec,
+           filename);
+    av_log_set_level(FFMAX(av_log_get_level(), AV_LOG_VERBOSE));
+    return 0;
+}
+
+int opt_max_alloc(void *optctx, const char *opt, const char *arg)
+{
+    char *tail;
+    size_t max;
+
+    max = strtol(arg, &tail, 10);
+    if (*tail) {
+        av_log(NULL, AV_LOG_FATAL, "Invalid max_alloc \"%s\".\n", arg);
+        exit(1);
+    }
+    av_max_alloc(max);
+    return 0;
+}
+
+int opt_cpuflags(void *optctx, const char *opt, const char *arg)
+{
+    int ret;
+    unsigned flags = av_get_cpu_flags();
+
+    if ((ret = av_parse_cpu_caps(&flags, arg)) < 0)
+        return ret;
+
+    av_force_cpu_flags(flags);
+    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
@@ -463,6 +609,7 @@
 #define INDENT        1
 #define SHOW_VERSION  2
 #define SHOW_CONFIG   4
+#define SHOW_COPYRIGHT 8
 
 #define PRINT_LIB_INFO(libname, LIBNAME, flags, level)                  \
     if (CONFIG_##LIBNAME) {                                             \
@@ -470,7 +617,7 @@
         if (flags & SHOW_VERSION) {                                     \
             unsigned int version = libname##_version();                 \
             av_log(NULL, level,                                         \
-                   "%slib%-10s %2d.%3d.%2d / %2d.%3d.%2d\n",            \
+                   "%slib%-11s %2d.%3d.%3d / %2d.%3d.%3d\n",            \
                    indent, #libname,                                    \
                    LIB##LIBNAME##_VERSION_MAJOR,                        \
                    LIB##LIBNAME##_VERSION_MINOR,                        \
@@ -479,7 +626,7 @@
         }                                                               \
         if (flags & SHOW_CONFIG) {                                      \
             const char *cfg = libname##_configuration();                \
-            if (strcmp(LIBAV_CONFIGURATION, cfg)) {                     \
+            if (strcmp(FFMPEG_CONFIGURATION, cfg)) {                    \
                 if (!warned_cfg) {                                      \
                     av_log(NULL, level,                                 \
                             "%sWARNING: library configuration mismatch\n", \
@@ -499,26 +646,44 @@
     PRINT_LIB_INFO(avformat, AVFORMAT, flags, level);
     PRINT_LIB_INFO(avdevice, AVDEVICE, flags, level);
     PRINT_LIB_INFO(avfilter, AVFILTER, flags, level);
-    PRINT_LIB_INFO(avresample, AVRESAMPLE, flags, level);
+//    PRINT_LIB_INFO(avresample, AVRESAMPLE, flags, level);
     PRINT_LIB_INFO(swscale,  SWSCALE,  flags, level);
+    PRINT_LIB_INFO(swresample,SWRESAMPLE,  flags, level);
+#if CONFIG_POSTPROC
+    PRINT_LIB_INFO(postproc, POSTPROC, flags, level);
+#endif
 }
 
-void show_banner(void)
+static void print_program_info(int flags, int level)
 {
-    av_log(NULL, AV_LOG_INFO,
-           "%s version " LIBAV_VERSION ", Copyright (c) %d-%d the Libav developers\n",
-           program_name, program_birth_year, this_year);
-    av_log(NULL, AV_LOG_INFO, "  built on %s %s with %s\n",
-           __DATE__, __TIME__, CC_IDENT);
-    av_log(NULL, AV_LOG_VERBOSE, "  configuration: " LIBAV_CONFIGURATION "\n");
-    print_all_libs_info(INDENT|SHOW_CONFIG,  AV_LOG_VERBOSE);
-    print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_VERBOSE);
+    const char *indent = flags & INDENT? "  " : "";
+
+    av_log(NULL, level, "%s version " FFMPEG_VERSION, program_name);
+    if (flags & SHOW_COPYRIGHT)
+        av_log(NULL, level, " Copyright (c) %d-%d the FFmpeg developers",
+               program_birth_year, this_year);
+    av_log(NULL, level, "\n");
+    av_log(NULL, level, "%sbuilt on %s %s with %s\n",
+           indent, __DATE__, __TIME__, CC_IDENT);
+
+    av_log(NULL, level, "%sconfiguration: " FFMPEG_CONFIGURATION "\n", indent);
+}
+
+void show_banner(int argc, char **argv, const OptionDef *options)
+{
+    int idx = locate_option(argc, argv, options, "version");
+    if (idx)
+        return;
+
+    print_program_info (INDENT|SHOW_COPYRIGHT, AV_LOG_INFO);
+    print_all_libs_info(INDENT|SHOW_CONFIG,  AV_LOG_INFO);
+    print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_INFO);
 }
 
 int show_version(void *optctx, const char *opt, const char *arg)
 {
     av_log_set_callback(log_callback_help);
-    printf("%s " LIBAV_VERSION "\n", program_name);
+    print_program_info (0           , AV_LOG_INFO);
     print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
 
     return 0;
@@ -707,7 +872,9 @@
     switch (type) {
         case AVMEDIA_TYPE_VIDEO:    return 'V';
         case AVMEDIA_TYPE_AUDIO:    return 'A';
+        case AVMEDIA_TYPE_DATA:     return 'D';
         case AVMEDIA_TYPE_SUBTITLE: return 'S';
+        case AVMEDIA_TYPE_ATTACHMENT:return 'T';
         default:                    return '?';
     }
 }
@@ -723,6 +890,36 @@
     return NULL;
 }
 
+static int compare_codec_desc(const void *a, const void *b)
+{
+    const AVCodecDescriptor * const *da = a;
+    const AVCodecDescriptor * const *db = b;
+
+    return (*da)->type != (*db)->type ? (*da)->type - (*db)->type :
+           strcmp((*da)->name, (*db)->name);
+}
+
+static unsigned get_codecs_sorted(const AVCodecDescriptor ***rcodecs)
+{
+    const AVCodecDescriptor *desc = NULL;
+    const AVCodecDescriptor **codecs;
+    unsigned nb_codecs = 0, i = 0;
+
+    while ((desc = avcodec_descriptor_next(desc)))
+        nb_codecs++;
+    if (!(codecs = av_calloc(nb_codecs, sizeof(*codecs)))) {
+        av_log(0, AV_LOG_ERROR, "Out of memory\n");
+        exit(1);
+    }
+    desc = NULL;
+    while ((desc = avcodec_descriptor_next(desc)))
+        codecs[i++] = desc;
+    av_assert0(i == nb_codecs);
+    qsort(codecs, nb_codecs, sizeof(*codecs), compare_codec_desc);
+    *rcodecs = codecs;
+    return nb_codecs;
+}
+
 static void print_codecs_for_id(enum AVCodecID id, int encoder)
 {
     const AVCodec *codec = NULL;
@@ -737,7 +934,8 @@
 
 int show_codecs(void *optctx, const char *opt, const char *arg)
 {
-    const AVCodecDescriptor *desc = NULL;
+    const AVCodecDescriptor **codecs;
+    unsigned i, nb_codecs = get_codecs_sorted(&codecs);
 
     printf("Codecs:\n"
            " D..... = Decoding supported\n"
@@ -749,9 +947,11 @@
            " ....L. = Lossy compression\n"
            " .....S = Lossless compression\n"
            " -------\n");
-    while ((desc = avcodec_descriptor_next(desc))) {
+    for (i = 0; i < nb_codecs; i++) {
+        const AVCodecDescriptor *desc = codecs[i];
         const AVCodec *codec = NULL;
 
+        printf(" ");
         printf(avcodec_find_decoder(desc->id) ? "D" : ".");
         printf(avcodec_find_encoder(desc->id) ? "E" : ".");
 
@@ -780,30 +980,37 @@
 
         printf("\n");
     }
+    av_free(codecs);
     return 0;
 }
 
 static void print_codecs(int encoder)
 {
-    const AVCodecDescriptor *desc = NULL;
+    const AVCodecDescriptor **codecs;
+    unsigned i, nb_codecs = get_codecs_sorted(&codecs);
 
     printf("%s:\n"
-           " V... = Video\n"
-           " A... = Audio\n"
-           " S... = Subtitle\n"
-           " .F.. = Frame-level multithreading\n"
-           " ..S. = Slice-level multithreading\n"
-           " ...X = Codec is experimental\n"
-           " ---\n",
+           " V..... = Video\n"
+           " A..... = Audio\n"
+           " S..... = Subtitle\n"
+           " .F.... = Frame-level multithreading\n"
+           " ..S... = Slice-level multithreading\n"
+           " ...X.. = Codec is experimental\n"
+           " ....B. = Supports draw_horiz_band\n"
+           " .....D = Supports direct rendering method 1\n"
+           " ------\n",
            encoder ? "Encoders" : "Decoders");
-    while ((desc = avcodec_descriptor_next(desc))) {
+    for (i = 0; i < nb_codecs; i++) {
+        const AVCodecDescriptor *desc = codecs[i];
         const AVCodec *codec = NULL;
 
         while ((codec = next_codec_for_id(desc->id, codec, encoder))) {
-            printf("%c", get_media_type_char(desc->type));
+            printf(" %c", get_media_type_char(desc->type));
             printf((codec->capabilities & CODEC_CAP_FRAME_THREADS) ? "F" : ".");
             printf((codec->capabilities & CODEC_CAP_SLICE_THREADS) ? "S" : ".");
             printf((codec->capabilities & CODEC_CAP_EXPERIMENTAL)  ? "X" : ".");
+            printf((codec->capabilities & CODEC_CAP_DRAW_HORIZ_BAND)?"B" : ".");
+            printf((codec->capabilities & CODEC_CAP_DR1)           ? "D" : ".");
 
             printf(" %-20s %s", codec->name, codec->long_name ? codec->long_name : "");
             if (strcmp(codec->name, desc->name))
@@ -812,6 +1019,7 @@
             printf("\n");
         }
     }
+    av_free(codecs);
 }
 
 int show_decoders(void *optctx, const char *opt, const char *arg)
@@ -855,11 +1063,31 @@
 int show_filters(void *optctx, const char *opt, const char *arg)
 {
     AVFilter av_unused(**filter) = NULL;
+    char descr[64], *descr_cur;
+    int i, j;
+    const AVFilterPad *pad;
 
     printf("Filters:\n");
 #if CONFIG_AVFILTER
-    while ((filter = av_filter_next(filter)) && *filter)
-        printf("%-16s %s\n", (*filter)->name, (*filter)->description);
+    while ((filter = av_filter_next(filter)) && *filter) {
+        descr_cur = descr;
+        for (i = 0; i < 2; i++) {
+            if (i) {
+                *(descr_cur++) = '-';
+                *(descr_cur++) = '>';
+            }
+            pad = i ? (*filter)->outputs : (*filter)->inputs;
+            for (j = 0; pad && pad[j].name; j++) {
+                if (descr_cur >= descr + sizeof(descr) - 4)
+                    break;
+                *(descr_cur++) = get_media_type_char(pad[j].type);
+            }
+            if (!j)
+                *(descr_cur++) = '|';
+        }
+        *descr_cur = 0;
+        printf("%-16s %-10s %s\n", (*filter)->name, descr, (*filter)->description);
+    }
 #endif
     return 0;
 }
@@ -884,6 +1112,8 @@
 
     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' : '.',
@@ -897,6 +1127,35 @@
     return 0;
 }
 
+int show_layouts(void *optctx, const char *opt, const char *arg)
+{
+    int i = 0;
+    uint64_t layout, j;
+    const char *name, *descr;
+
+    printf("Individual channels:\n"
+           "NAME        DESCRIPTION\n");
+    for (i = 0; i < 63; i++) {
+        name = av_get_channel_name((uint64_t)1 << i);
+        if (!name)
+            continue;
+        descr = av_get_channel_description((uint64_t)1 << i);
+        printf("%-12s%s\n", name, descr);
+    }
+    printf("\nStandard channel layouts:\n"
+           "NAME        DECOMPOSITION\n");
+    for (i = 0; !av_get_standard_channel_layout(i, &layout, &name); i++) {
+        if (name) {
+            printf("%-12s", name);
+            for (j = 1; j; j <<= 1)
+                if ((layout & j))
+                    printf("%s%s", (layout & (j - 1)) ? "+" : "", av_get_channel_name(j));
+            printf("\n");
+        }
+    }
+    return 0;
+}
+
 int show_sample_fmts(void *optctx, const char *opt, const char *arg)
 {
     int i;
@@ -930,13 +1189,13 @@
         }
 
         if (!printed) {
-            av_log(NULL, AV_LOG_ERROR, "Codec '%s' is known to Libav, "
-                   "but no %s for it are available. Libav might need to be "
+            av_log(NULL, AV_LOG_ERROR, "Codec '%s' is known to FFmpeg, "
+                   "but no %s for it are available. FFmpeg might need to be "
                    "recompiled with additional external libraries.\n",
                    name, encoder ? "encoders" : "decoders");
         }
     } else {
-        av_log(NULL, AV_LOG_ERROR, "Codec '%s' is not recognized by Libav.\n",
+        av_log(NULL, AV_LOG_ERROR, "Codec '%s' is not recognized by FFmpeg.\n",
                name);
     }
 }
@@ -1068,58 +1327,47 @@
     return ret;
 }
 
-void init_pts_correction(PtsCorrectionContext *ctx)
-{
-    ctx->num_faulty_pts = ctx->num_faulty_dts = 0;
-    ctx->last_pts = ctx->last_dts = INT64_MIN;
-}
-
-int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t reordered_pts,
-                          int64_t dts)
-{
-    int64_t pts = AV_NOPTS_VALUE;
-
-    if (dts != AV_NOPTS_VALUE) {
-        ctx->num_faulty_dts += dts <= ctx->last_dts;
-        ctx->last_dts = dts;
-    }
-    if (reordered_pts != AV_NOPTS_VALUE) {
-        ctx->num_faulty_pts += reordered_pts <= ctx->last_pts;
-        ctx->last_pts = reordered_pts;
-    }
-    if ((ctx->num_faulty_pts<=ctx->num_faulty_dts || dts == AV_NOPTS_VALUE)
-        && reordered_pts != AV_NOPTS_VALUE)
-        pts = reordered_pts;
-    else
-        pts = dts;
-
-    return pts;
-}
-
 FILE *get_preset_file(char *filename, size_t filename_size,
                       const char *preset_name, int is_path,
                       const char *codec_name)
 {
     FILE *f = NULL;
     int i;
-    const char *base[3] = { getenv("AVCONV_DATADIR"),
+    const char *base[3] = { getenv("FFMPEG_DATADIR"),
                             getenv("HOME"),
-                            AVCONV_DATADIR, };
+                            FFMPEG_DATADIR, };
 
     if (is_path) {
         av_strlcpy(filename, preset_name, filename_size);
         f = fopen(filename, "r");
     } else {
+#ifdef _WIN32
+        char datadir[MAX_PATH], *ls;
+        base[2] = NULL;
+
+        if (GetModuleFileNameA(GetModuleHandleA(NULL), datadir, sizeof(datadir) - 1))
+        {
+            for (ls = datadir; ls < datadir + strlen(datadir); ls++)
+                if (*ls == '\\') *ls = '/';
+
+            if (ls = strrchr(datadir, '/'))
+            {
+                *ls = 0;
+                strncat(datadir, "/ffpresets",  sizeof(datadir) - 1 - strlen(datadir));
+                base[2] = datadir;
+            }
+        }
+#endif
         for (i = 0; i < 3 && !f; i++) {
             if (!base[i])
                 continue;
-            snprintf(filename, filename_size, "%s%s/%s.avpreset", base[i],
-                     i != 1 ? "" : "/.avconv", preset_name);
+            snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i],
+                     i != 1 ? "" : "/.ffmpeg", preset_name);
             f = fopen(filename, "r");
             if (!f && codec_name) {
                 snprintf(filename, filename_size,
-                         "%s%s/%s-%s.avpreset",
-                         base[i], i != 1 ? "" : "/.avconv", codec_name,
+                         "%s%s/%s-%s.ffpreset",
+                         base[i], i != 1 ? "" : "/.ffmpeg", codec_name,
                          preset_name);
                 f = fopen(filename, "r");
             }
@@ -1131,56 +1379,10 @@
 
 int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
 {
-    if (*spec <= '9' && *spec >= '0') /* opt:index */
-        return strtol(spec, NULL, 0) == st->index;
-    else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
-             *spec == 't') { /* opt:[vasdt] */
-        enum AVMediaType type;
-
-        switch (*spec++) {
-        case 'v': type = AVMEDIA_TYPE_VIDEO;      break;
-        case 'a': type = AVMEDIA_TYPE_AUDIO;      break;
-        case 's': type = AVMEDIA_TYPE_SUBTITLE;   break;
-        case 'd': type = AVMEDIA_TYPE_DATA;       break;
-        case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
-        default:  av_assert0(0);
-        }
-        if (type != st->codec->codec_type)
-            return 0;
-        if (*spec++ == ':') { /* possibly followed by :index */
-            int i, index = strtol(spec, NULL, 0);
-            for (i = 0; i < s->nb_streams; i++)
-                if (s->streams[i]->codec->codec_type == type && index-- == 0)
-                   return i == st->index;
-            return 0;
-        }
-        return 1;
-    } else if (*spec == 'p' && *(spec + 1) == ':') {
-        int prog_id, i, j;
-        char *endptr;
-        spec += 2;
-        prog_id = strtol(spec, &endptr, 0);
-        for (i = 0; i < s->nb_programs; i++) {
-            if (s->programs[i]->id != prog_id)
-                continue;
-
-            if (*endptr++ == ':') {
-                int stream_idx = strtol(endptr, NULL, 0);
-                return stream_idx >= 0 &&
-                    stream_idx < s->programs[i]->nb_stream_indexes &&
-                    st->index == s->programs[i]->stream_index[stream_idx];
-            }
-
-            for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
-                if (st->index == s->programs[i]->stream_index[j])
-                    return 1;
-        }
-        return 0;
-    } else if (!*spec) /* empty specifier, matches everything */
-        return 1;
-
-    av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
-    return AVERROR(EINVAL);
+    int ret = avformat_match_stream_specifier(s, st, spec);
+    if (ret < 0)
+        av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
+    return ret;
 }
 
 AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
@@ -1298,15 +1500,17 @@
     if (!buf)
         return AVERROR(ENOMEM);
 
+    avcodec_align_dimensions(s, &w, &h);
+
     if (!(s->flags & CODEC_FLAG_EMU_EDGE)) {
         w += 2*edge;
         h += 2*edge;
     }
 
-    avcodec_align_dimensions(s, &w, &h);
     if ((ret = av_image_alloc(buf->base, buf->linesize, w, h,
                               s->pix_fmt, 32)) < 0) {
         av_freep(&buf);
+        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
@@ -1320,9 +1524,9 @@
     for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
         const int h_shift = i==0 ? 0 : h_chroma_shift;
         const int v_shift = i==0 ? 0 : v_chroma_shift;
-        if (s->flags & CODEC_FLAG_EMU_EDGE)
+        if ((s->flags & CODEC_FLAG_EMU_EDGE) || !buf->linesize[i] || !buf->base[i])
             buf->data[i] = buf->base[i];
-        else if (buf->base[i])
+        else
             buf->data[i] = buf->base[i] +
                            FFALIGN((buf->linesize[i]*edge >> v_shift) +
                                    (pixel_size*edge >> h_shift), 32);
@@ -1342,6 +1546,11 @@
     FrameBuffer *buf;
     int ret, i;
 
+    if(av_image_check_size(s->width, s->height, 0, s) || s->pix_fmt<0) {
+        av_log(s, AV_LOG_ERROR, "codec_get_buffer: image parameters invalid\n");
+        return -1;
+    }
+
     if (!*pool && (ret = alloc_buffer(pool, s, pool)) < 0)
         return ret;
 
@@ -1354,6 +1563,7 @@
         if ((ret = alloc_buffer(pool, s, &buf)) < 0)
             return ret;
     }
+    av_assert0(!buf->refcount);
     buf->refcount++;
 
     frame->opaque        = buf;
@@ -1378,9 +1588,13 @@
 {
     FrameBuffer **pool = buf->pool;
 
-    av_assert0(buf->refcount);
+    av_assert0(buf->refcount > 0);
     buf->refcount--;
     if (!buf->refcount) {
+        FrameBuffer *tmp;
+        for(tmp= *pool; tmp; tmp= tmp->next)
+            av_assert1(tmp != buf);
+
         buf->next = *pool;
         *pool = buf;
     }
@@ -1391,6 +1605,11 @@
     FrameBuffer *buf = frame->opaque;
     int i;
 
+    if(frame->type!=FF_BUFFER_TYPE_USER) {
+        avcodec_default_release_buffer(s, frame);
+        return;
+    }
+
     for (i = 0; i < FF_ARRAY_ELEMS(frame->data); i++)
         frame->data[i] = NULL;
 
diff --git a/cmdutils.h b/cmdutils.h
index dd86235..3885d94 100644
--- a/cmdutils.h
+++ b/cmdutils.h
@@ -2,25 +2,25 @@
  * Various utilities for command line tools
  * copyright (c) 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#ifndef LIBAV_CMDUTILS_H
-#define LIBAV_CMDUTILS_H
+#ifndef FFMPEG_CMDUTILS_H
+#define FFMPEG_CMDUTILS_H
 
 #include <stdint.h>
 
@@ -29,6 +29,10 @@
 #include "libavformat/avformat.h"
 #include "libswscale/swscale.h"
 
+#ifdef __MINGW32__
+#undef main /* We don't want SDL to override our main() */
+#endif
+
 /**
  * program name, defined by the program for show_version().
  */
@@ -39,9 +43,15 @@
  */
 extern const int program_birth_year;
 
+/**
+ * this year, defined by the program for show_banner()
+ */
+extern const int this_year;
+
 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;
 
 /**
@@ -57,7 +67,7 @@
 
 /**
  * Trivial log callback.
- * Only suitable for show_help and similar since it lacks prefix handling.
+ * Only suitable for opt_help and similar since it lacks prefix handling.
  */
 void log_callback_help(void* ptr, int level, const char* fmt, va_list vl);
 
@@ -72,6 +82,14 @@
  */
 int opt_loglevel(void *optctx, const char *opt, const char *arg);
 
+int opt_report(const char *opt);
+
+int opt_max_alloc(void *optctx, const char *opt, const char *arg);
+
+int opt_cpuflags(void *optctx, const char *opt, const char *arg);
+
+int opt_codec_debug(void *optctx, const char *opt, const char *arg);
+
 /**
  * Limit the execution time.
  */
@@ -136,7 +154,7 @@
 #define OPT_INT64  0x0400
 #define OPT_EXIT   0x0800
 #define OPT_DATA   0x1000
-#define OPT_PERFILE  0x2000     /* the option is per-file (currently avconv-only).
+#define OPT_PERFILE  0x2000     /* the option is per-file (currently ffmpeg-only).
                                    implied by OPT_OFFSET or OPT_SPEC */
 #define OPT_OFFSET 0x4000       /* option is specified as an offset in a passed optctx */
 #define OPT_SPEC   0x8000       /* option is to be stored in an array of SpecifierOpt.
@@ -270,30 +288,34 @@
  * current version of the repository and of the libav* libraries used by
  * the program.
  */
-void show_banner(void);
+void show_banner(int argc, char **argv, const OptionDef *options);
 
 /**
  * Print the version of the program to stdout. The version message
  * depends on the current versions of the repository and of the libav*
  * libraries.
+ * This option processing function does not utilize the arguments.
  */
 int show_version(void *optctx, const char *opt, const char *arg);
 
 /**
  * Print the license of the program to stdout. The license depends on
  * the license of the libraries compiled into the program.
+ * This option processing function does not utilize the arguments.
  */
 int show_license(void *optctx, const char *opt, const char *arg);
 
 /**
  * Print a listing containing all the formats supported by the
  * program.
+ * This option processing function does not utilize the arguments.
  */
 int show_formats(void *optctx, const char *opt, const char *arg);
 
 /**
  * Print a listing containing all the codecs supported by the
  * program.
+ * This option processing function does not utilize the arguments.
  */
 int show_codecs(void *optctx, const char *opt, const char *arg);
 
@@ -312,28 +334,39 @@
 /**
  * Print a listing containing all the filters supported by the
  * program.
+ * This option processing function does not utilize the arguments.
  */
 int show_filters(void *optctx, const char *opt, const char *arg);
 
 /**
  * Print a listing containing all the bit stream filters supported by the
  * program.
+ * This option processing function does not utilize the arguments.
  */
 int show_bsfs(void *optctx, const char *opt, const char *arg);
 
 /**
  * Print a listing containing all the protocols supported by the
  * program.
+ * This option processing function does not utilize the arguments.
  */
 int show_protocols(void *optctx, const char *opt, const char *arg);
 
 /**
  * Print a listing containing all the pixel formats supported by the
  * program.
+ * This option processing function does not utilize the arguments.
  */
 int show_pix_fmts(void *optctx, const char *opt, const char *arg);
 
 /**
+ * Print a listing containing all the standard channel layouts supported by
+ * the program.
+ * This option processing function does not utilize the arguments.
+ */
+int show_layouts(void *optctx, const char *opt, const char *arg);
+
+/**
  * Print a listing containing all the sample formats supported by the
  * program.
  */
@@ -356,37 +389,14 @@
  */
 int cmdutils_read_file(const char *filename, char **bufptr, size_t *size);
 
-typedef struct PtsCorrectionContext {
-    int64_t num_faulty_pts; /// Number of incorrect PTS values so far
-    int64_t num_faulty_dts; /// Number of incorrect DTS values so far
-    int64_t last_pts;       /// PTS of the last frame
-    int64_t last_dts;       /// DTS of the last frame
-} PtsCorrectionContext;
-
-/**
- * Reset the state of the PtsCorrectionContext.
- */
-void init_pts_correction(PtsCorrectionContext *ctx);
-
-/**
- * Attempt to guess proper monotonic timestamps for decoded video frames
- * which might have incorrect times. Input timestamps may wrap around, in
- * which case the output will as well.
- *
- * @param pts the pts field of the decoded AVPacket, as passed through
- * AVCodecContext.reordered_opaque
- * @param dts the dts field of the decoded AVPacket
- * @return one of the input values, may be AV_NOPTS_VALUE
- */
-int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t pts, int64_t dts);
-
 /**
  * Get a file corresponding to a preset file.
  *
  * If is_path is non-zero, look for the file in the path preset_name.
- * Otherwise search for a file named arg.avpreset in the directories
- * $AVCONV_DATADIR (if set), $HOME/.avconv, and in the datadir defined
- * at configuration time, in that order. If no such file is found and
+ * Otherwise search for a file named arg.ffpreset in the directories
+ * $FFMPEG_DATADIR (if set), $HOME/.ffmpeg, and in the datadir defined
+ * at configuration time or in a "ffpresets" folder along the executable
+ * on win32, in that order. If no such file is found and
  * codec_name is defined, then search for a file named
  * codec_name-preset_name.avpreset in the above-mentioned directories.
  *
@@ -471,4 +481,4 @@
     char name[128];\
     av_get_channel_layout_string(name, sizeof(name), 0, ch_layout);
 
-#endif /* LIBAV_CMDUTILS_H */
+#endif /* CMDUTILS_H */
diff --git a/cmdutils_common_opts.h b/cmdutils_common_opts.h
index 619cd89..bfd71fe 100644
--- a/cmdutils_common_opts.h
+++ b/cmdutils_common_opts.h
@@ -12,6 +12,12 @@
     { "protocols"  , OPT_EXIT, {.func_arg = show_protocols},    "show available protocols" },
     { "filters"    , OPT_EXIT, {.func_arg = show_filters  },    "show available filters" },
     { "pix_fmts"   , OPT_EXIT, {.func_arg = show_pix_fmts },    "show available pixel formats" },
+    { "layouts"    , OPT_EXIT, {.func_arg = show_layouts  },    "show standard channel layouts" },
     { "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 dd9f4cb..dd5de7a 100644
--- a/common.mak
+++ b/common.mak
@@ -5,6 +5,77 @@
 # first so "all" becomes default target
 all: all-yes
 
+ifndef SUBDIR
+
+ifndef V
+Q      = @
+ECHO   = printf "$(1)\t%s\n" $(2)
+BRIEF  = CC CXX HOSTCC HOSTLD AS YASM AR LD STRIP CP
+SILENT = DEPCC DEPHOSTCC DEPAS DEPYASM RANLIB RM
+
+MSG    = $@
+M      = @$(call ECHO,$(TAG),$@);
+$(foreach VAR,$(BRIEF), \
+    $(eval override $(VAR) = @$$(call ECHO,$(VAR),$$(MSG)); $($(VAR))))
+$(foreach VAR,$(SILENT),$(eval override $(VAR) = @$($(VAR))))
+$(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL))
+endif
+
+ALLFFLIBS = avcodec avdevice avfilter avformat avresample avutil postproc swscale swresample
+
+# NASM requires -I path terminated with /
+IFLAGS     := -I. -I$(SRC_PATH)/
+CPPFLAGS   := $(IFLAGS) $(CPPFLAGS)
+CFLAGS     += $(ECFLAGS)
+CCFLAGS     = $(CPPFLAGS) $(CFLAGS)
+ASFLAGS    := $(CPPFLAGS) $(ASFLAGS)
+CXXFLAGS   += $(CPPFLAGS) $(CFLAGS)
+YASMFLAGS  += $(IFLAGS:%=%/) -I$(SRC_PATH)/libavutil/x86/ -Pconfig.asm
+
+HOSTCCFLAGS = $(IFLAGS) $(HOSTCFLAGS)
+LDFLAGS    := $(ALLFFLIBS:%=$(LD_PATH)lib%) $(LDFLAGS)
+
+define COMPILE
+       $(call $(1)DEP,$(1))
+       $($(1)) $($(1)FLAGS) $($(1)_DEPFLAGS) $($(1)_C) $($(1)_O) $<
+endef
+
+COMPILE_C = $(call COMPILE,CC)
+COMPILE_CXX = $(call COMPILE,CXX)
+COMPILE_S = $(call COMPILE,AS)
+
+%.o: %.c
+	$(COMPILE_C)
+
+%.o: %.cpp
+	$(COMPILE_CXX)
+
+%.s: %.c
+	$(CC) $(CPPFLAGS) $(CFLAGS) -S -o $@ $<
+
+%.o: %.S
+	$(COMPILE_S)
+
+%.h.c:
+	$(Q)echo '#include "$*.h"' >$@
+
+%.ver: %.v
+	$(Q)sed 's/$$MAJOR/$($(basename $(@F))_VERSION_MAJOR)/' $^ > $@
+
+%.c %.h: TAG = GEN
+
+# Dummy rule to stop make trying to rebuild removed or renamed headers
+%.h:
+	@:
+
+# Disable suffix rules.  Most of the builtin rules are suffix rules,
+# so this saves some time on slow systems.
+.SUFFIXES:
+
+# Do not delete intermediate files from chains of implicit rules
+$(OBJS):
+endif
+
 include $(SRC_PATH)/arch.mak
 
 OBJS      += $(OBJS-yes)
@@ -44,11 +115,12 @@
 $(OBJS):     | $(sort $(dir $(OBJS)))
 $(HOSTOBJS): | $(sort $(dir $(HOSTOBJS)))
 $(TESTOBJS): | $(sort $(dir $(TESTOBJS)))
+$(HOBJS):    | $(sort $(dir $(HOBJS)))
 $(TOOLOBJS): | tools
 
-OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOSTOBJS) $(TESTOBJS))
+OBJDIRS := $(OBJDIRS) $(dir $(OBJS) $(HOSTOBJS) $(TESTOBJS) $(HOBJS))
 
-CLEANSUFFIXES     = *.d *.o *~ *.h.c *.map *.ver
+CLEANSUFFIXES     = *.d *.o *~ *.h.c *.map *.ver *.ho *.gcno *.gcda
 DISTCLEANSUFFIXES = *.pc
 LIBSUFFIXES       = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a
 
diff --git a/compat/getopt.c b/compat/getopt.c
index 3e7d3e2..019049f 100644
--- a/compat/getopt.c
+++ b/compat/getopt.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/compat/msvcrt/snprintf.c b/compat/msvcrt/snprintf.c
index 0af7b54..c64653f 100644
--- a/compat/msvcrt/snprintf.c
+++ b/compat/msvcrt/snprintf.c
@@ -2,20 +2,20 @@
  * C99-compatible snprintf() and vsnprintf() implementations
  * Copyright (c) 2012 Ronald S. Bultje <rsbultje@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,10 +24,11 @@
 #include <limits.h>
 #include <string.h>
 
+#include "compat/va_copy.h"
 #include "libavutil/error.h"
 
-#if !defined(va_copy) && defined(_MSC_VER)
-#define va_copy(dst, src) ((dst) = (src))
+#if defined(__MINGW32__)
+#define EOVERFLOW EFBIG
 #endif
 
 int avpriv_snprintf(char *s, size_t n, const char *fmt, ...)
diff --git a/compat/msvcrt/snprintf.h b/compat/msvcrt/snprintf.h
new file mode 100644
index 0000000..f02113c
--- /dev/null
+++ b/compat/msvcrt/snprintf.h
@@ -0,0 +1,38 @@
+/*
+ * C99-compatible snprintf() and vsnprintf() implementations
+ * 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
+ */
+
+#ifndef COMPAT_SNPRINTF_H
+#define COMPAT_SNPRINTF_H
+
+#include <stdarg.h>
+#include <stdio.h>
+
+int avpriv_snprintf(char *s, size_t n, const char *fmt, ...);
+int avpriv_vsnprintf(char *s, size_t n, const char *fmt, va_list ap);
+
+#undef snprintf
+#undef _snprintf
+#undef vsnprintf
+#define snprintf avpriv_snprintf
+#define _snprintf avpriv_snprintf
+#define vsnprintf avpriv_vsnprintf
+
+#endif /* COMPAT_SNPRINTF_H */
diff --git a/compat/strtod.c b/compat/strtod.c
index 7e979e8..d0f9b3d 100644
--- a/compat/strtod.c
+++ b/compat/strtod.c
@@ -2,20 +2,20 @@
  * C99-compatible strtod() implementation
  * Copyright (c) 2012 Ronald S. Bultje <rsbultje@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/compat/va_copy.h b/compat/va_copy.h
new file mode 100644
index 0000000..f894771
--- /dev/null
+++ b/compat/va_copy.h
@@ -0,0 +1,26 @@
+/*
+ * MSVC Compatible va_copy macro
+ * Copyright (c) 2012 Derek Buitenhuis
+ *
+ * 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 <stdarg.h>
+
+#if !defined(va_copy) && defined(_MSC_VER)
+#define va_copy(dst, src) ((dst) = (src))
+#endif
diff --git a/configure b/configure
index bc3a218..cce6aad 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# Libav configure script
+# FFmpeg configure script
 #
 # Copyright (c) 2000-2002 Fabrice Bellard
 # Copyright (c) 2005-2008 Diego Biurrun
@@ -44,9 +44,9 @@
     echo "No compatible shell script interpreter found."
     echo "This configure script requires a POSIX-compatible shell"
     echo "such as bash or ksh."
-    echo "THIS IS NOT A BUG IN LIBAV, DO NOT REPORT IT AS SUCH."
+    echo "THIS IS NOT A BUG IN FFMPEG, DO NOT REPORT IT AS SUCH."
     echo "Instead, install a working POSIX-compatible shell."
-    echo "Disabling this configure test will create a broken Libav."
+    echo "Disabling this configure test will create a broken FFmpeg."
     if test "$BASH_VERSION" = '2.04.0(1)-release'; then
         echo "This bash version ($BASH_VERSION) is broken on your platform."
         echo "Upgrade to a later version if available."
@@ -78,7 +78,7 @@
   --disable-logging        do not log configure debug information
   --prefix=PREFIX          install in PREFIX [$prefix]
   --bindir=DIR             install binaries in DIR [PREFIX/bin]
-  --datadir=DIR            install data files in DIR [PREFIX/share/avconv]
+  --datadir=DIR            install data files in DIR [PREFIX/share/ffmpeg]
   --libdir=DIR             install libs in DIR [PREFIX/lib]
   --shlibdir=DIR           install shared libs in DIR [PREFIX/lib]
   --incdir=DIR             install includes in DIR [PREFIX/include]
@@ -95,24 +95,33 @@
   --disable-static         do not build static libraries [no]
   --enable-shared          build shared libraries [no]
   --enable-small           optimize for size instead of speed
-  --enable-runtime-cpudetect detect cpu capabilities at runtime (bigger binary)
+  --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
 
-Component options:
+Documentation options:
   --disable-doc            do not build documentation
-  --disable-avconv         disable avconv build
-  --disable-avplay         disable avplay build
-  --disable-avprobe        disable avprobe build
-  --disable-avserver       disable avserver build
+  --disable-htmlpages      do not build HTML documentation pages
+  --disable-manpages       do not build man documentation pages
+  --disable-podpages       do not build POD documentation pages
+  --disable-txtpages       do not build text documentation pages
+
+Component options:
+  --disable-ffmpeg         disable ffmpeg build
+  --disable-ffplay         disable ffplay build
+  --disable-ffprobe        disable ffprobe build
+  --disable-ffserver       disable ffserver build
   --disable-avdevice       disable libavdevice build
   --disable-avcodec        disable libavcodec build
   --disable-avformat       disable libavformat build
+  --disable-swresample     disable libswresample build
   --disable-swscale        disable libswscale build
-  --disable-avfilter       disable video filter support [no]
-  --disable-avresample     disable libavresample build [no]
+  --disable-postproc       disable libpostproc build
+  --disable-avfilter       disable libavfilter build
+  --enable-avresample      enable libavresample build [no]
   --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
@@ -122,9 +131,9 @@
   --disable-rdft           disable RDFT code
   --disable-fft            disable FFT code
   --enable-dxva2           enable DXVA2 code
-  --enable-vaapi           enable VAAPI code
-  --enable-vda             enable VDA code
-  --enable-vdpau           enable VDPAU code
+  --enable-vaapi           enable VAAPI code [autodetect]
+  --enable-vda             enable VDA code   [autodetect]
+  --enable-vdpau           enable VDPAU code [autodetect]
 
 Individual component options:
   --disable-everything     disable all components listed below
@@ -166,17 +175,28 @@
 External library support:
   --enable-avisynth        enable reading of AVISynth script files [no]
   --enable-bzlib           enable bzlib [autodetect]
+  --enable-fontconfig      enable fontconfig
   --enable-frei0r          enable frei0r video filtering
   --enable-gnutls          enable gnutls [no]
+  --enable-libaacplus      enable AAC+ encoding via libaacplus [no]
+  --enable-libass          enable libass subtitles rendering [no]
+  --enable-libbluray       enable BluRay reading using libbluray [no]
+  --enable-libcaca         enable textual display using libcaca
+  --enable-libcelt         enable CELT decoding via libcelt [no]
   --enable-libcdio         enable audio CD grabbing with libcdio
   --enable-libdc1394       enable IIDC-1394 grabbing using libdc1394
                            and libraw1394 [no]
   --enable-libfaac         enable AAC encoding via libfaac [no]
   --enable-libfdk-aac      enable AAC encoding via libfdk-aac [no]
+  --enable-libflite        enable flite (voice synthesis) support via libflite [no]
   --enable-libfreetype     enable libfreetype [no]
   --enable-libgsm          enable GSM de/encoding via libgsm [no]
+  --enable-libiec61883     enable iec61883 via libiec61883 [no]
   --enable-libilbc         enable iLBC de/encoding via libilbc [no]
+  --enable-libmodplug      enable ModPlug via libmodplug [no]
   --enable-libmp3lame      enable MP3 encoding via libmp3lame [no]
+  --enable-libnut          enable NUT (de)muxing via libnut,
+                           native (de)muxer exists [no]
   --enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore-amrnb [no]
   --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
   --enable-libopencv       enable video filtering via libopencv [no]
@@ -186,15 +206,21 @@
   --enable-librtmp         enable RTMP[E] support via librtmp [no]
   --enable-libschroedinger enable Dirac de/encoding via libschroedinger [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]
+  --enable-libtwolame      enable MP2 encoding via libtwolame [no]
+  --enable-libutvideo      enable Ut Video encoding and decoding via libutvideo [no]
+  --enable-libv4l2         enable libv4l2/v4l-utils [no]
   --enable-libvo-aacenc    enable AAC encoding via libvo-aacenc [no]
   --enable-libvo-amrwbenc  enable AMR-WB encoding via libvo-amrwbenc [no]
-  --enable-libvorbis       enable Vorbis encoding via libvorbis [no]
+  --enable-libvorbis       enable Vorbis en/decoding via libvorbis,
+                           native implementation exists [no]
   --enable-libvpx          enable VP8 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-zlib            enable zlib [autodetect]
 
@@ -207,12 +233,14 @@
   --target-exec=CMD        command to run executables on target
   --target-path=DIR        path to view of build directory on target
   --toolchain=NAME         set tool defaults according to NAME
-  --nm=NM                  use nm tool
+  --nm=NM                  use nm tool NM [$nm_default]
   --ar=AR                  use archive tool AR [$ar_default]
   --as=AS                  use assembler AS [$as_default]
+  --yasmexe=EXE            use yasm-compatible assembler EXE [$yasmexe_default]
   --cc=CC                  use C compiler CC [$cc_default]
+  --cxx=CXX                use C compiler CXX [$cxx_default]
   --dep-cc=DEPCC           use dependency generator DEPCC [$cc_default]
-  --ld=LD                  use linker LD
+  --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-ld=HOSTLD         use host linker HOSTLD
@@ -220,12 +248,14 @@
   --host-libs=HLIBS        use libs HLIBS when linking for host
   --host-os=OS             compiler host OS [$target_os]
   --extra-cflags=ECFLAGS   add ECFLAGS to CFLAGS [$CFLAGS]
+  --extra-cxxflags=ECFLAGS add ECFLAGS to CXXFLAGS [$CXXFLAGS]
   --extra-ldflags=ELDFLAGS add ELDFLAGS to LDFLAGS [$LDFLAGS]
   --extra-libs=ELIBS       add ELIBS [$ELIBS]
   --extra-version=STRING   version string suffix []
   --optflags=OPTFLAGS      override optimization-related compiler flags
   --build-suffix=SUFFIX    library name suffix []
   --malloc-prefix=PREFIX   prefix malloc and related names with PREFIX
+  --progs-suffix=SUFFIX    program name suffix []
   --arch=ARCH              select architecture [$arch]
   --cpu=CPU                select the minimum required CPU (affects
                            instruction selection, may crash on older CPUs)
@@ -264,14 +294,30 @@
   --disable-vis            disable VIS optimizations
   --disable-inline-asm     disable use of inline assembler
   --disable-yasm           disable use of yasm assembler
+  --disable-mips32r2       disable MIPS32R2 optimizations
+  --disable-mipsdspr1      disable MIPS DSP ASE R1 optimizations
+  --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 Libav itself):
+Developer options (useful when working on FFmpeg itself):
+  --enable-coverage        build with test coverage instrumentation
   --disable-debug          disable debugging symbols
   --enable-debug=LEVEL     set the debug level [$debuglevel]
   --disable-optimizations  disable compiler optimizations
   --enable-extra-warnings  enable more compiler warnings
+  --disable-stripping      disable stripping of executables and shared libraries
+  --assert-level=level     0(default), 1 or 2, amount of assertion testing,
+                           2 causes a slowdown at runtime.
+  --enable-memory-poisoning fill heap uninitialized allocated space with arbitrary data
+  --valgrind=VALGRIND      run "make fate" tests through valgrind to detect memory
+                           leaks and errors, using the specified valgrind binary.
+                           Cannot be combined with --target-exec
+  --enable-ftrapv          Trap arithmetic overflows
   --samples=PATH           location of test samples for FATE, if not set use
-                           \$LIBAV_SAMPLES at make invocation time.
+                           \$FATE_SAMPLES at make invocation time.
   --enable-xmm-clobber-test check XMM registers for clobbering (Win64-only;
                            should be used only for debugging purposes)
   --enable-random          randomly enable/disable components
@@ -316,7 +362,7 @@
 
 If you think configure made a mistake, make sure you are using the latest
 version from Git.  If the latest version fails, report the problem to the
-libav-user@libav.org mailing list or IRC #libav on irc.freenode.net.
+ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.freenode.net.
 EOF
     if disabled logging; then
         cat <<EOF
@@ -620,6 +666,10 @@
     append CFLAGS $($cflags_filter "$@")
 }
 
+add_cxxflags(){
+    append CXXFLAGS $($cflags_filter "$@")
+}
+
 add_asflags(){
     append ASFLAGS $($asflags_filter "$@")
 }
@@ -660,6 +710,13 @@
     check_cmd $cc $CPPFLAGS $CFLAGS "$@" $CC_C $(cc_o $TMPO) $TMPC
 }
 
+check_cxx(){
+    log check_cxx "$@"
+    cat > $TMPCPP
+    log_file $TMPCPP
+    check_cmd $cxx $CPPFLAGS $CFLAGS $CXXFLAGS "$@" $CXX_C -o $TMPO $TMPCPP
+}
+
 check_cpp(){
     log check_cpp "$@"
     cat > $TMPC
@@ -694,7 +751,7 @@
     echo "$1" > $TMPS
     log_file $TMPS
     shift 1
-    check_cmd $yasmexe $YASMFLAGS "$@" -o $TMPO $TMPS
+    check_cmd $yasmexe $YASMFLAGS -Werror "$@" -o $TMPO $TMPS
 }
 
 ld_o(){
@@ -703,12 +760,14 @@
 
 check_ld(){
     log check_ld "$@"
+    type=$1
+    shift 1
     flags=''
     libs=''
     for f; do
         test "${f}" = "${f#-l}" && flags="$flags $f" || libs="$libs $f"
     done
-    check_cc $($cflags_filter $flags) || return
+    check_$type $($cflags_filter $flags) || return
     flags=$($ldflags_filter $flags)
     libs=$($ldflags_filter $libs)
     check_cmd $ld $LDFLAGS $flags $(ld_o $TMPE) $TMPO $libs $extralibs
@@ -743,9 +802,17 @@
 EOF
 }
 
+check_cxxflags(){
+    log check_cxxflags "$@"
+    set -- $($cflags_filter "$@")
+    check_cxx "$@" <<EOF && append CXXFLAGS "$@"
+int x;
+EOF
+}
+
 test_ldflags(){
     log test_ldflags "$@"
-    check_ld "$@" <<EOF
+    check_ld "cc" "$@" <<EOF
 int main(void){ return 0; }
 EOF
 }
@@ -771,7 +838,7 @@
     func=$1
     shift
     disable $func
-    check_ld "$@" <<EOF && enable $func
+    check_ld "cc" "$@" <<EOF && enable $func
 extern int $func();
 int main(void){ $func(); }
 EOF
@@ -782,10 +849,10 @@
     func=$1
     shift
     disable $func
-    check_ld "$@" <<EOF && enable $func
+    check_ld "cc" "$@" <<EOF && enable $func
 #include <math.h>
 float foo(float f) { return $func(f); }
-int main(void){ return 0; }
+int main(void){ return (int) foo; }
 EOF
 }
 
@@ -802,7 +869,26 @@
             echo "long check_$func(void) { return (long) $func; }"
         done
         echo "int main(void) { return 0; }"
-    } | check_ld "$@" && enable $funcs && enable_safe $headers
+    } | check_ld "cc" "$@" && enable $funcs && enable_safe $headers
+}
+
+check_class_headers_cpp(){
+    log check_class_headers_cpp "$@"
+    headers=$1
+    classes=$2
+    shift 2
+    {
+        for hdr in $headers; do
+            echo "#include <$hdr>"
+        done
+        echo "int main(void) { "
+        i=1
+        for class in $classes; do
+            echo "$class obj$i;"
+            i=$(expr $i + 1)
+        done
+        echo "return 0; }"
+    } | check_ld "cxx" "$@" && enable $funcs && enable_safe $headers
 }
 
 check_cpp_condition(){
@@ -834,13 +920,21 @@
     check_func_headers "$headers" "$funcs" "$@" && add_extralibs "$@"
 }
 
+check_lib_cpp(){
+    log check_lib_cpp "$@"
+    headers="$1"
+    classes="$2"
+    shift 2
+    check_class_headers_cpp "$headers" "$classes" "$@" && add_extralibs "$@"
+}
+
 check_pkg_config(){
     log check_pkg_config "$@"
     pkg="$1"
     headers="$2"
     funcs="$3"
     shift 3
-    $pkg_config --exists $pkg || return
+    $pkg_config --exists $pkg 2>/dev/null || return
     pkg_cflags=$($pkg_config --cflags $pkg)
     pkg_libs=$($pkg_config --libs $pkg)
     check_func_headers "$headers" "$funcs" $pkg_cflags $pkg_libs "$@" &&
@@ -849,7 +943,7 @@
 }
 
 check_exec(){
-    check_ld "$@" && { enabled cross_compile || $TMPE >> $logfile 2>&1; }
+    check_ld "cc" "$@" && { enabled cross_compile || $TMPE >> $logfile 2>&1; }
 }
 
 check_exec_crash(){
@@ -866,9 +960,10 @@
 static void sighandler(int sig){
     raise(SIGTERM);
 }
-int foo(void){
+int func(void){
     $code
 }
+int (*func_ptr)(void) = func;
 int main(void){
     signal(SIGILL, sighandler);
     signal(SIGFPE, sighandler);
@@ -876,7 +971,7 @@
 #ifdef SIGBUS
     signal(SIGBUS, sighandler);
 #endif
-    foo();
+    return func_ptr();
 }
 EOF
 }
@@ -917,6 +1012,14 @@
     check_lib2 "$headers" $func "$@" || die "ERROR: $name not found"
 }
 
+require_cpp(){
+    name="$1"
+    headers="$2"
+    classes="$3"
+    shift 3
+    check_lib_cpp "$headers" "$classes" "$@" || die "ERROR: $name not found"
+}
+
 require_pkg_config(){
     pkg="$1"
     check_pkg_config "$@" || die "ERROR: $pkg not found"
@@ -972,15 +1075,24 @@
     protocols
 "
 
+DOCUMENT_LIST="
+    doc
+    htmlpages
+    manpages
+    podpages
+    txtpages
+"
+
 PROGRAM_LIST="
-    avconv
-    avplay
-    avprobe
-    avserver
+    ffplay
+    ffprobe
+    ffserver
+    ffmpeg
 "
 
 CONFIG_LIST="
     $COMPONENT_LIST
+    $DOCUMENT_LIST
     $PROGRAM_LIST
     avcodec
     avdevice
@@ -989,24 +1101,37 @@
     avresample
     avisynth
     bzlib
+    crystalhd
     dct
-    doc
     dwt
     dxva2
+    fast_unaligned
     fft
+    fontconfig
     frei0r
+    ftrapv
     gnutls
     gpl
     gray
     hardcoded_tables
+    incompatible_fork_abi
+    libaacplus
+    libass
+    libbluray
+    libcaca
     libcdio
+    libcelt
     libdc1394
     libfaac
     libfdk_aac
+    libflite
     libfreetype
     libgsm
+    libiec61883
     libilbc
+    libmodplug
     libmp3lame
+    libnut
     libopencore_amrnb
     libopencore_amrwb
     libopencv
@@ -1016,7 +1141,11 @@
     librtmp
     libschroedinger
     libspeex
+    libstagefright_h264
     libtheora
+    libtwolame
+    libutvideo
+    libv4l2
     libvo_aacenc
     libvo_amrwbenc
     libvorbis
@@ -1027,10 +1156,13 @@
     lsp
     mdct
     memalign_hack
+    memory_poisoning
     network
     nonfree
+    openal
     openssl
     pic
+    postproc
     rdft
     runtime_cpudetect
     safe_bitstream_reader
@@ -1038,6 +1170,7 @@
     small
     sram
     static
+    swresample
     swscale
     swscale_alpha
     thumb
@@ -1053,6 +1186,7 @@
 THREADS_LIST='
     pthreads
     w32threads
+    os2threads
 '
 
 ARCH_LIST='
@@ -1106,6 +1240,10 @@
     ppc4xx
     vfpv3
     vis
+    mipsfpu
+    mips32r2
+    mipsdspr1
+    mipsdspr2
 "
 
 HAVE_LIST_CMDLINE='
@@ -1117,6 +1255,7 @@
 HAVE_LIST_PUB='
     bigendian
     fast_unaligned
+    incompatible_fork_abi
 '
 
 HAVE_LIST="
@@ -1133,9 +1272,12 @@
     arpa_inet_h
     asm_mod_q
     asm_mod_y
+    asm_types_h
     attribute_may_alias
     attribute_packed
+    broken_snprintf
     cbrtf
+    clock_gettime
     closesocket
     cmov
     cpunop
@@ -1169,6 +1311,7 @@
     GetSystemTimeAsFileTime
     getrusage
     gettimeofday
+    glob
     gnu_as
     ibm_asm
     inet_aton
@@ -1177,6 +1320,7 @@
     isinf
     isnan
     jack_port_get_latency_range
+    kbhit
     ldbrx
     libdc1394_1
     libdc1394_2
@@ -1190,8 +1334,10 @@
     loongson
     lrint
     lrintf
+    lzo1x_999_compress
     machine_ioctl_bt848_h
     machine_ioctl_meteor_h
+    makeinfo
     malloc_h
     MapViewOfFile
     memalign
@@ -1200,8 +1346,12 @@
     mmap
     msvcrt
     nanosleep
+    PeekNamedPipe
+    perl
+    pod2man
     poll_h
     posix_memalign
+    pthread_cancel
     rdtsc
     rint
     round
@@ -1216,14 +1366,13 @@
     socklen_t
     soundcard_h
     strerror_r
-    strptime
-    strtok_r
     struct_addrinfo
     struct_group_source_req
     struct_ip_mreq_source
     struct_ipv6_mreq
     struct_pollfd
     struct_rusage_ru_maxrss
+    struct_sctp_event_subscribe
     struct_sockaddr_in6
     struct_sockaddr_sa_len
     struct_sockaddr_storage
@@ -1239,6 +1388,8 @@
     sys_soundcard_h
     sys_time_h
     sys_videoio_h
+    termios_h
+    texi2html
     threads
     trunc
     truncf
@@ -1285,12 +1436,14 @@
     $HAVE_LIST_CMDLINE
     $THREADS_LIST
     asm
+    coverage
     cross_compile
     debug
     extra_warnings
     logging
     lto
     optimizations
+    stripping
 "
 
 PATHS_LIST='
@@ -1308,10 +1461,12 @@
     ar
     arch
     as
+    assert_level
     build_suffix
     cc
     cpu
     cross_prefix
+    cxx
     dep_cc
     extra_version
     host_cc
@@ -1320,24 +1475,31 @@
     host_ldflags
     host_libs
     host_os
+    install
     ld
     logfile
     malloc_prefix
     nm
     optflags
     pkg_config
+    postproc_version
+    progs_suffix
     random_seed
     samples
+    strip
     sysinclude
     sysroot
     target_exec
     target_os
     target_path
     toolchain
+    valgrind
+    yasmexe
 "
 
 CMDLINE_APPEND="
     extra_cflags
+    extra_cxxflags
 "
 
 # code dependency declarations
@@ -1351,6 +1513,10 @@
 neon_deps="arm"
 vfpv3_deps="armvfp"
 
+mipsfpu_deps="mips"
+mips32r2_deps="mips"
+mipsdspr1_deps="mips"
+mipsdspr2_deps="mips"
 mmi_deps="mips"
 
 altivec_deps="ppc"
@@ -1414,6 +1580,7 @@
 alac_encoder_select="lpc"
 amrnb_decoder_select="lsp"
 amrwb_decoder_select="lsp"
+amv_encoder_select="aandcttables"
 atrac1_decoder_select="mdct sinewin"
 atrac3_decoder_select="mdct"
 binkaudio_dct_decoder_select="mdct rdft dct sinewin"
@@ -1422,6 +1589,7 @@
 cook_decoder_select="mdct sinewin"
 cscd_decoder_suggest="zlib"
 dca_decoder_select="mdct"
+dirac_decoder_select="dwt golomb"
 dnxhd_encoder_select="aandcttables mpegvideoenc"
 dxa_decoder_select="zlib"
 eac3_decoder_select="ac3_decoder"
@@ -1429,6 +1597,7 @@
 eamad_decoder_select="aandcttables error_resilience mpegvideo"
 eatgq_decoder_select="aandcttables"
 eatqi_decoder_select="aandcttables error_resilience mpegvideo"
+exr_decoder_select="zlib"
 ffv1_decoder_select="golomb rangecoder"
 ffv1_encoder_select="rangecoder"
 ffvhuff_encoder_select="huffman"
@@ -1436,6 +1605,7 @@
 flac_encoder_select="golomb lpc"
 flashsv_decoder_select="zlib"
 flashsv_encoder_select="zlib"
+flashsv2_encoder_select="zlib"
 flashsv2_decoder_select="zlib"
 flv_decoder_select="h263_decoder"
 flv_encoder_select="h263_encoder"
@@ -1447,10 +1617,13 @@
 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"
 huffyuv_encoder_select="huffman"
@@ -1479,17 +1652,22 @@
 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"
@@ -1515,6 +1693,9 @@
 sipr_decoder_select="lsp"
 snow_decoder_select="dwt rangecoder"
 snow_encoder_select="aandcttables dwt error_resilience mpegvideoenc rangecoder"
+sonic_decoder_select="golomb"
+sonic_encoder_select="golomb"
+sonic_ls_encoder_select="golomb"
 svq1_decoder_select="error_resilience mpegvideo"
 svq1_encoder_select="aandcttables error_resilience mpegvideoenc"
 svq3_decoder_select="error_resilience golomb h264chroma h264dsp h264pred h264qpel mpegvideo"
@@ -1522,10 +1703,11 @@
 theora_decoder_select="vp3_decoder"
 tiff_decoder_suggest="zlib"
 tiff_encoder_suggest="zlib"
-truehd_decoder_select="mlp_decoder"
+truehd_decoder_select="mlp_parser"
 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"
@@ -1551,6 +1733,7 @@
 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"
@@ -1561,6 +1744,7 @@
 zmbv_decoder_select="zlib"
 zmbv_encoder_select="zlib"
 
+crystalhd_deps="libcrystalhd_libcrystalhd_if_h"
 vaapi_deps="va_va_h"
 vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
 vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h"
@@ -1572,6 +1756,8 @@
 vc1_parser_select="error_resilience mpegvideo"
 
 # external libraries
+libaacplus_encoder_deps="libaacplus"
+libcelt_decoder_deps="libcelt"
 libfaac_encoder_deps="libfaac"
 libfdk_aac_encoder_deps="libfdk_aac"
 libgsm_decoder_deps="libgsm"
@@ -1580,6 +1766,7 @@
 libgsm_ms_encoder_deps="libgsm"
 libilbc_decoder_deps="libilbc"
 libilbc_encoder_deps="libilbc"
+libmodplug_demuxer_deps="libmodplug"
 libmp3lame_encoder_deps="libmp3lame"
 libopencore_amrnb_decoder_deps="libopencore_amrnb"
 libopencore_amrnb_encoder_deps="libopencore_amrnb"
@@ -1592,24 +1779,35 @@
 libschroedinger_encoder_deps="libschroedinger"
 libspeex_decoder_deps="libspeex"
 libspeex_encoder_deps="libspeex"
+libstagefright_h264_decoder_deps="libstagefright_h264"
 libtheora_encoder_deps="libtheora"
+libtwolame_encoder_deps="libtwolame"
 libvo_aacenc_encoder_deps="libvo_aacenc"
 libvo_amrwbenc_encoder_deps="libvo_amrwbenc"
+libvorbis_decoder_deps="libvorbis"
 libvorbis_encoder_deps="libvorbis"
 libvpx_decoder_deps="libvpx"
 libvpx_encoder_deps="libvpx"
 libx264_encoder_deps="libx264"
+libx264rgb_encoder_deps="libx264"
 libxavs_encoder_deps="libxavs"
 libxvid_encoder_deps="libxvid"
+libutvideo_decoder_deps="libutvideo"
+libutvideo_encoder_deps="libutvideo"
 
 # demuxers / muxers
 ac3_demuxer_select="ac3_parser"
 asf_stream_muxer_select="asf_muxer"
 avisynth_demuxer_deps="avisynth"
 dirac_demuxer_select="dirac_parser"
+dts_demuxer_select="dca_parser"
+dtshd_demuxer_select="dca_parser"
 eac3_demuxer_select="ac3_parser"
+f4v_muxer_select="mov_muxer"
 flac_demuxer_select="flac_parser"
 ipod_muxer_select="mov_muxer"
+libnut_demuxer_deps="libnut"
+libnut_muxer_deps="libnut"
 matroska_audio_muxer_select="matroska_muxer"
 matroska_demuxer_suggest="zlib bzlib"
 mov_demuxer_suggest="zlib"
@@ -1630,6 +1828,7 @@
 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"
 w64_demuxer_deps="wav_demuxer"
@@ -1638,22 +1837,32 @@
 alsa_indev_deps="alsa_asoundlib_h snd_pcm_htimestamp"
 alsa_outdev_deps="alsa_asoundlib_h"
 bktr_indev_deps_any="dev_bktr_ioctl_bt848_h machine_ioctl_bt848_h dev_video_bktr_ioctl_bt848_h dev_ic_bt8xx_h"
+caca_outdev_deps="libcaca"
+dshow_indev_deps="IBaseFilter"
+dshow_indev_extralibs="-lpsapi -lole32 -lstrmiids -luuid"
 dv1394_indev_deps="dv1394 dv_demuxer"
 fbdev_indev_deps="linux_fb_h"
-jack_indev_deps="jack_jack_h"
+iec61883_indev_deps="libiec61883"
+jack_indev_deps="jack_jack_h sem_timedwait"
+lavfi_indev_deps="avfilter"
 libcdio_indev_deps="libcdio"
 libdc1394_indev_deps="libdc1394"
+libv4l2_indev_deps="libv4l2"
+openal_indev_deps="openal"
 oss_indev_deps_any="soundcard_h sys_soundcard_h"
 oss_outdev_deps_any="soundcard_h sys_soundcard_h"
 pulse_indev_deps="libpulse"
+sdl_outdev_deps="sdl"
 sndio_indev_deps="sndio_h"
 sndio_outdev_deps="sndio_h"
+v4l_indev_deps="linux_videodev_h"
 v4l2_indev_deps_any="linux_videodev2_h sys_videoio_h"
 vfwcap_indev_deps="capCreateCaptureWindow vfwcap_defines"
 vfwcap_indev_extralibs="-lavicap32"
-x11grab_indev_deps="x11grab XShmCreateImage"
+x11grab_indev_deps="x11grab"
 
 # protocols
+bluray_protocol_deps="libbluray"
 ffrtmpcrypt_protocol_deps="!librtmp_protocol"
 ffrtmpcrypt_protocol_deps_any="gcrypt nettle openssl"
 ffrtmpcrypt_protocol_select="tcp_protocol"
@@ -1688,40 +1897,79 @@
 udp_protocol_deps="network"
 
 # filters
+aconvert_filter_deps="swresample"
+amovie_filter_deps="avcodec avformat"
+aresample_filter_deps="swresample"
+ass_filter_deps="libass"
+asyncts_filter_deps="avresample"
+atempo_filter_deps="avcodec rdft"
 blackframe_filter_deps="gpl"
 boxblur_filter_deps="gpl"
+colormatrix_filter_deps="gpl"
 cropdetect_filter_deps="gpl"
+decimate_filter_deps="gpl avcodec"
 delogo_filter_deps="gpl"
+deshake_filter_deps="avcodec"
 drawtext_filter_deps="libfreetype"
-frei0r_filter_deps="frei0r dlopen strtok_r"
+ebur128_filter_deps="gpl"
+flite_filter_deps="libflite"
+frei0r_filter_deps="frei0r dlopen"
 frei0r_filter_extralibs='$ldl'
-frei0r_src_filter_deps="frei0r dlopen strtok_r"
+frei0r_src_filter_deps="frei0r dlopen"
 frei0r_src_filter_extralibs='$ldl'
 hqdn3d_filter_deps="gpl"
+movie_filter_deps="avcodec avformat"
+mp_filter_deps="gpl avcodec swscale postproc inline_asm"
+mptestsrc_filter_deps="gpl"
+negate_filter_deps="lut_filter"
 resample_filter_deps="avresample"
 ocv_filter_deps="libopencv"
+pan_filter_deps="swresample"
+removelogo_filter_deps="avcodec avformat swscale"
 scale_filter_deps="swscale"
+smartblur_filter_deps="gpl swscale"
+showspectrum_filter_deps="avcodec rdft"
+super2xsai_filter_deps="gpl"
+tinterlace_filter_deps="gpl"
 yadif_filter_deps="gpl"
+pixfmts_super2xsai_test_deps="super2xsai_filter"
+tinterlace_merge_test_deps="tinterlace_filter"
+tinterlace_pad_test_deps="tinterlace_filter"
 
 # libraries
 avdevice_deps="avcodec avformat"
 avformat_deps="avcodec"
+postproc_deps="gpl"
 
 # programs
-avconv_deps="avcodec avfilter avformat avresample swscale
-             aformat_filter asyncts_filter
-             format_filter fps_filter scale_filter setpts_filter"
-avplay_deps="avcodec avformat swscale sdl"
-avplay_select="rdft"
-avprobe_deps="avcodec avformat"
-avserver_deps="avformat ffm_muxer fork rtp_protocol rtsp_demuxer !shared"
-avserver_extralibs='$ldl'
+ffmpeg_deps="avcodec avfilter avformat swscale swresample"
+ffmpeg_select="ffbuffersink_filter format_filter aformat_filter
+               setpts_filter null_filter anull_filter ffabuffersink_filter"
+ffplay_deps="avcodec avformat swscale swresample sdl"
+ffplay_select="ffbuffersink_filter rdft crop_filter"
+ffprobe_deps="avcodec avformat"
+ffserver_deps="avformat ffm_muxer fork rtp_protocol rtsp_demuxer"
+ffserver_extralibs='$ldl'
 
-doc_deps="texi2html"
+# documentation
+podpages_deps="perl"
+manpages_deps="perl pod2man"
+htmlpages_deps="texi2html"
+txtpages_deps="makeinfo"
+doc_deps_any="manpages htmlpages podpages txtpages"
 
 # tests
-
+colormatrix1_test_deps="colormatrix_filter"
+colormatrix2_test_deps="colormatrix_filter"
 mpg_test_deps="mpeg1system_muxer mpegps_demuxer"
+png_test_deps="zlib"
+pp_test_deps="mp_filter"
+pp2_test_deps="mp_filter"
+pp3_test_deps="mp_filter"
+pp4_test_deps="mp_filter"
+pp5_test_deps="mp_filter"
+pp6_test_deps="mp_filter"
+seek_flashsv_flv_test_deps="zlib"
 seek_lavf_mxf_d10_test_deps="mxf_d10_test"
 
 test_deps(){
@@ -1749,11 +1997,11 @@
     gxf                                                                 \
     matroska=mkv                                                        \
     mmf                                                                 \
-    mov                                                                 \
+    mov="mov ismv"                                                      \
     pcm_mulaw=mulaw                                                     \
     mxf="mxf mxf_d10"                                                   \
     nut                                                                 \
-    ogg                                                                 \
+    ogg="ogg ogg_vp3"                                                   \
     rawvideo=pixfmt                                                     \
     rm                                                                  \
     swf                                                                 \
@@ -1769,22 +2017,26 @@
 # installation paths
 prefix_default="/usr/local"
 bindir_default='${prefix}/bin'
-datadir_default='${prefix}/share/avconv'
+datadir_default='${prefix}/share/ffmpeg'
 incdir_default='${prefix}/include'
 libdir_default='${prefix}/lib'
 mandir_default='${prefix}/share/man'
 shlibdir_default="$libdir_default"
+postproc_version_default="current"
 
 # toolchain
 ar_default="ar"
 cc_default="gcc"
+cxx_default="g++"
 host_cc_default="gcc"
+install="install"
 ln_s="ln -sf"
 nm_default="nm -g"
 objformat="elf"
 pkg_config_default=pkg-config
 ranlib="ranlib"
-yasmexe="yasm"
+strip_default="strip"
+yasmexe_default="yasm"
 
 nogas=":"
 
@@ -1796,15 +2048,24 @@
 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 avcodec
 enable avdevice
 enable avfilter
 enable avformat
-enable avresample
 enable avutil
+enable postproc
+enable stripping
+enable swresample
 enable swscale
 
 enable asm
@@ -1812,13 +2073,14 @@
 enable doc
 enable network
 enable optimizations
+enable runtime_cpudetect
 enable safe_bitstream_reader
 enable static
 enable swscale_alpha
 
 # build settings
 SHFLAGS='-shared -Wl,-soname,$$(@F)'
-AVSERVERLDFLAGS=-Wl,-E
+FFSERVERLDFLAGS=-Wl,-E
 LIBPREF="lib"
 LIBSUF=".a"
 FULLNAME='$(NAME)$(BUILDSUF)'
@@ -1841,6 +2103,8 @@
 CC_C='-c'
 CC_E='-E -o $@'
 CC_O='-o $@'
+CXX_C='-c'
+CXX_O='-o $@'
 LD_O='-o $@'
 LD_LIB='-l%'
 LD_PATH='-L'
@@ -1875,7 +2139,7 @@
     r=${v#*=}
     l=${v%"$r"}
     r=$(sh_quote "$r")
-    LIBAV_CONFIGURATION="${LIBAV_CONFIGURATION# } ${l}${r}"
+    FFMPEG_CONFIGURATION="${FFMPEG_CONFIGURATION# } ${l}${r}"
 done
 
 find_things(){
@@ -1915,11 +2179,12 @@
     map "echo ${2}\${v}_test" $(ls "$source_path"/tests/ref/$1 | grep -v '[^-a-z0-9_]')
 }
 
+LAVF_FATE_TESTS=$(find_tests lavf-fate)
 LAVF_TESTS=$(find_tests lavf)
 LAVFI_TESTS=$(find_tests lavfi)
 SEEK_TESTS=$(find_tests seek seek_)
 
-ALL_TESTS="$LAVF_TESTS $LAVFI_TESTS $SEEK_TESTS"
+ALL_TESTS="$LAVF_FATE_TESTS $LAVF_TESTS $LAVFI_TESTS $SEEK_TESTS"
 
 for n in $COMPONENT_LIST; do
     v=$(toupper ${n%s})_LIST
@@ -2028,7 +2293,7 @@
 
 disabled logging && logfile=/dev/null
 
-echo "# $0 $LIBAV_CONFIGURATION" > $logfile
+echo "# $0 $FFMPEG_CONFIGURATION" > $logfile
 set >> $logfile
 
 test -n "$cross_prefix" && enable cross_compile
@@ -2038,13 +2303,25 @@
         die "Must specify target arch and OS when cross-compiling"
 fi
 
-set_default arch target_os
+set_default arch target_os 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}"
 nm_default="${cross_prefix}${nm_default}"
 pkg_config_default="${cross_prefix}${pkg_config_default}"
 ranlib="${cross_prefix}${ranlib}"
+strip_default="${cross_prefix}${strip_default}"
 
 sysinclude_default="${sysroot}/usr/include"
 
@@ -2060,7 +2337,7 @@
     ;;
 esac
 
-set_default cc pkg_config sysinclude
+set_default cc cxx pkg_config strip sysinclude yasmexe
 enabled cross_compile || host_cc_default=$cc
 set_default host_cc
 
@@ -2103,6 +2380,7 @@
 
 tmpfile TMPASM .asm
 tmpfile TMPC   .c
+tmpfile TMPCPP .cpp
 tmpfile TMPE   $EXESUF
 tmpfile TMPH   .h
 tmpfile TMPO   .o
@@ -2135,7 +2413,7 @@
             -Wall)                echo -W4 -wd4244 -wd4127 -wd4018 -wd4389 \
                                        -wd4146 -wd4057 -wd4204 -wd4706 -wd4305 \
                                        -wd4152 -wd4324 -we4013 -wd4100 -wd4214 \
-                                       -wd4996 ;;
+                                       -wd4996 -wd4554 ;;
             -std=c99)             ;;
             -fno-math-errno)      ;;
             -fno-common)          ;;
@@ -2359,6 +2637,7 @@
         if [ $pfx = hostcc ]; then
             append _cflags -Dsnprintf=_snprintf
         fi
+        disable stripping
     fi
 
     eval ${pfx}_type=\$_type
@@ -2439,6 +2718,7 @@
 fi
 
 add_cflags $extra_cflags
+add_cxxflags $extra_cxxflags
 add_asflags $extra_cflags
 
 if test -n "$sysroot"; then
@@ -2476,7 +2756,7 @@
 
 # Deal with common $arch aliases
 case "$arch" in
-    arm*)
+    arm*|iPad*)
         arch="arm"
     ;;
     mips|mipsel|IP*)
@@ -2493,13 +2773,9 @@
         arch="parisc"
         subarch="parisc64"
     ;;
-    "Power Macintosh"|ppc|powerpc)
+    "Power Macintosh"|ppc|powerpc|ppc64|powerpc64)
         arch="ppc"
     ;;
-    ppc64|powerpc64)
-        arch="ppc"
-        subarch="ppc64"
-    ;;
     s390|s390x)
         arch="s390"
     ;;
@@ -2510,7 +2786,7 @@
         arch="sparc"
         subarch="sparc64"
     ;;
-    i[3-6]86|i86pc|BePC|x86pc|x86_64|amd64)
+    i[3-6]86|i86pc|BePC|x86pc|x86_64|x86_32|amd64)
         arch="x86"
     ;;
 esac
@@ -2640,6 +2916,28 @@
 
     cpuflags="-march=$cpu"
 
+    case $cpu in
+        24kc)
+            disable mipsfpu
+            disable mipsdspr1
+            disable mipsdspr2
+        ;;
+        24kf*)
+            disable mipsdspr1
+            disable mipsdspr2
+        ;;
+        24kec|34kc|1004kc)
+            disable mipsfpu
+            disable mipsdspr2
+        ;;
+        24kef*|34kf*|1004kf*)
+            disable mipsdspr2
+        ;;
+        74kc)
+            disable mipsfpu
+        ;;
+    esac
+
 elif enabled avr32; then
 
     case $cpu in
@@ -2680,6 +2978,7 @@
 fi
 
 add_cppflags -D_ISOC99_SOURCE
+add_cxxflags -D__STDC_CONSTANT_MACROS
 check_cflags -std=c99
 check_cc -D_FILE_OFFSET_BITS=64 <<EOF && add_cppflags -D_FILE_OFFSET_BITS=64
 #include <stdlib.h>
@@ -2702,6 +3001,11 @@
             spic=$shared
         fi
     ;;
+    ppc)
+        check_cc <<EOF && subarch="ppc64"
+        int test[(int)sizeof(char*) - 7];
+EOF
+    ;;
 esac
 
 enable $subarch
@@ -2715,7 +3019,7 @@
         host_libs=
         ;;
     sunos)
-        AVSERVERLDFLAGS=""
+        FFSERVERLDFLAGS=""
         SHFLAGS='-shared -Wl,-h,$$(@F)'
         enabled x86 && SHFLAGS="-mimpure-text $SHFLAGS"
         network_extralibs="-lsocket -lnsl"
@@ -2732,10 +3036,11 @@
         disable symver
         oss_indev_extralibs="-lossaudio"
         oss_outdev_extralibs="-lossaudio"
+        enabled gcc || check_ldflags -Wl,-zmuldefs
         ;;
     openbsd|bitrig)
         # On OpenBSD 4.5. the compiler does not use PIC unless
-        # explicitly using -fPIC. Libav builds fine without PIC,
+        # 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.
@@ -2754,17 +3059,19 @@
         ;;
     bsd/os)
         add_extralibs -lpoll -lgnugetopt
+        strip="strip -d"
         ;;
     darwin)
         gas="gas-preprocessor.pl $cc"
         enabled ppc && add_asflags -force_cpusubtype_ALL
         SHFLAGS='-dynamiclib -Wl,-single_module -Wl,-install_name,$(SHLIBDIR)/$(SLIBNAME_WITH_MAJOR),-current_version,$(LIBVERSION),-compatibility_version,$(LIBMAJOR)'
         enabled x86_32 && append SHFLAGS -Wl,-read_only_relocs,suppress
+        strip="${strip} -x"
         add_ldflags -Wl,-dynamic,-search_paths_first
         SLIBSUF=".dylib"
         SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME).$(LIBVERSION)$(SLIBSUF)'
         SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME).$(LIBMAJOR)$(SLIBSUF)'
-        AVSERVERLDFLAGS=-Wl,-bind_at_load
+        FFSERVERLDFLAGS=-Wl,-bind_at_load
         objformat="macho"
         enabled x86_64 && objformat="macho64"
         enabled_any pic shared ||
@@ -2787,14 +3094,21 @@
         SLIBSUF=".dll"
         SLIBNAME_WITH_VERSION='$(SLIBPREF)$(FULLNAME)-$(LIBVERSION)$(SLIBSUF)'
         SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
-        SLIB_EXTRA_CMD=-'$(DLLTOOL) -m $(LIBTARGET) -d $$(@:$(SLIBSUF)=.def) -l $(SUBDIR)$(SLIBNAME:$(SLIBSUF)=.lib) -D $(SLIBNAME_WITH_MAJOR)'
+        dlltool="${cross_prefix}dlltool"
+        if check_cmd lib.exe -list; then
+            SLIB_EXTRA_CMD='-lib.exe /machine:$(LIBTARGET) /def:$$(@:$(SLIBSUF)=.def) /out:$(SUBDIR)$(SLIBNAME:$(SLIBSUF)=.lib)'
+            if enabled x86_64; then
+                LIBTARGET=x64
+            fi
+        elif check_cmd $dlltool --version; then
+            SLIB_EXTRA_CMD=-'$(DLLTOOL) -m $(LIBTARGET) -d $$(@:$(SLIBSUF)=.def) -l $(SUBDIR)$(SLIBNAME:$(SLIBSUF)=.lib) -D $(SLIBNAME_WITH_MAJOR)'
+        fi
         SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
         SLIB_INSTALL_LINKS=
         SLIB_INSTALL_EXTRA_SHLIB='$(SLIBNAME:$(SLIBSUF)=.lib)'
         SLIB_INSTALL_EXTRA_LIB='lib$(SLIBNAME:$(SLIBSUF)=.dll.a) $(SLIBNAME_WITH_MAJOR:$(SLIBSUF)=.def)'
         SHFLAGS='-shared -Wl,--output-def,$$(@:$(SLIBSUF)=.def) -Wl,--out-implib,$(SUBDIR)lib$(SLIBNAME:$(SLIBSUF)=.dll.a) -Wl,--enable-runtime-pseudo-reloc -Wl,--enable-auto-image-base'
         objformat="win32"
-        dlltool="${cross_prefix}dlltool"
         ranlib=:
         enable dos_paths
         add_cppflags -U__STRICT_ANSI__
@@ -2829,12 +3143,13 @@
         ranlib="echo ignoring ranlib"
         ;;
     os/2*)
+        strip="lxlite -CS"
         ln_s="cp -f"
         objformat="aout"
         add_cppflags -D_GNU_SOURCE
         add_ldflags -Zomf -Zbin-files -Zargs-wild -Zmap
         SHFLAGS='$(SUBDIR)$(NAME).def -Zdll -Zomf'
-        AVSERVERLDFLAGS=""
+        FFSERVERLDFLAGS=""
         LIBSUF="_s.a"
         SLIBPREF=""
         SLIBSUF=".dll"
@@ -2850,6 +3165,7 @@
             emximp -o $(SUBDIR)$(LIBPREF)$(NAME)_dll.lib $(SUBDIR)$(NAME).def;'
         SLIB_INSTALL_EXTRA_LIB='$(LIBPREF)$(NAME)_dll.a $(LIBPREF)$(NAME)_dll.lib'
         enable dos_paths
+        enable_weak os2threads
         ;;
     gnu/kfreebsd)
         add_cppflags -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_BSD_SOURCE
@@ -2875,7 +3191,7 @@
         ;;
     osf1)
         add_cppflags -D_OSF_SOURCE -D_POSIX_PII -D_REENTRANT
-        AVSERVERLDFLAGS=
+        FFSERVERLDFLAGS=
         ;;
     none)
         ;;
@@ -2896,10 +3212,16 @@
         "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."
+    if check_cpp_condition _mingw.h "defined(__MINGW64_VERSION_MAJOR) && \
+            __MINGW64_VERSION_MAJOR < 3"; then
+        enable broken_snprintf
+        add_cflags "-include $source_path/compat/msvcrt/snprintf.h"
+    fi
 elif check_cpp_condition newlib.h "defined _NEWLIB_VERSION"; then
     libc_type=newlib
 elif check_func_headers stdlib.h _get_doserrno; then
     libc_type=msvcrt
+    enable broken_snprintf
     add_cflags -Dstrtod=avpriv_strtod
     add_cflags -Dsnprintf=avpriv_snprintf   \
                -D_snprintf=avpriv_snprintf  \
@@ -2914,7 +3236,7 @@
     echo "$*" | sed 's/%/%25/g;s/:/%3a/g'
 }
 
-echo "config:$arch:$subarch:$cpu:$target_os:$(esc $cc_ident):$(esc $LIBAV_CONFIGURATION)" >config.fate
+echo "config:$arch:$subarch:$cpu:$target_os:$(esc $cc_ident):$(esc $FFMPEG_CONFIGURATION)" >config.fate
 
 check_cpp_condition stdlib.h "defined(__PIC__) || defined(__pic__) || defined(PIC)" && enable pic
 
@@ -2936,15 +3258,21 @@
     enabled $1 || { enabled $2 && die "$2 is $1 and --enable-$1 is not specified."; }
 }
 
+die_license_disabled_gpl() {
+    enabled $1 || { enabled $2 && die "$2 is incompatible with the gpl and --enable-$1 is not specified."; }
+}
+
 die_license_disabled gpl libcdio
+die_license_disabled gpl libutvideo
 die_license_disabled gpl libx264
 die_license_disabled gpl libxavs
 die_license_disabled gpl libxvid
 die_license_disabled gpl x11grab
 
+die_license_disabled nonfree libaacplus
 die_license_disabled nonfree libfaac
-die_license_disabled nonfree libfdk_aac
-die_license_disabled nonfree openssl
+enabled gpl && die_license_disabled_gpl nonfree libfdk_aac
+enabled gpl && die_license_disabled_gpl nonfree openssl
 
 die_license_disabled version3 libopencore_amrnb
 die_license_disabled version3 libopencore_amrwb
@@ -3008,7 +3336,7 @@
     elif ! check_cpp_condition stddef.h "defined __ARM_PCS || defined __SOFTFP__"; then
         case "${cross_prefix:-$cc}" in
             *hardfloat*)         enable vfp_args;   fpabi=vfp ;;
-            *) check_ld <<EOF && enable vfp_args && fpabi=vfp || fpabi=soft ;;
+            *) check_ld "cc" <<EOF && enable vfp_args && fpabi=vfp || fpabi=soft ;;
 __asm__ (".eabi_attribute 28, 1");
 int main(void) { return 0; }
 EOF
@@ -3032,6 +3360,14 @@
 
     check_inline_asm loongson '"dmult.g $1, $2, $3"'
     enabled mmi && check_inline_asm mmi '"lq $2, 0($2)"'
+    enabled mips32r2  && add_cflags "-mips32r2" && add_asflags "-mips32r2" &&
+     check_inline_asm mips32r2  '"rotr $t0, $t1, 1"'
+    enabled mipsdspr1 && add_cflags "-mdsp" && add_asflags "-mdsp" &&
+     check_inline_asm mipsdspr1 '"addu.qb $t0, $t1, $t2"'
+    enabled mipsdspr2 && add_cflags "-mdspr2" && add_asflags "-mdspr2" &&
+     check_inline_asm mipsdspr2 '"absq_s.qb $t0, $t1"'
+    enabled mipsfpu   && add_cflags "-mhard-float" && add_asflags "-mhard-float" &&
+     check_inline_asm mipsfpu   '"madd.d $f0, $f2, $f4, $f6"'
 
 elif enabled ppc; then
 
@@ -3071,9 +3407,9 @@
 
 elif enabled x86; then
 
-    check_code ld intrin.h "__rdtsc()" && enable rdtsc
+    check_code ld intrin.h "__rdtsc()" "cc" && enable rdtsc
 
-    check_code ld mmintrin.h "_mm_empty()" && enable mm_empty
+    check_code ld mmintrin.h "_mm_empty()" "cc" && enable mm_empty
 
     enable local_aligned_8 local_aligned_16
 
@@ -3182,6 +3518,7 @@
 # Solaris has nanosleep in -lrt, OpenSolaris no longer needs that
 check_func nanosleep || { check_func nanosleep -lrt && add_extralibs -lrt; }
 
+check_func  clock_gettime || { check_func clock_gettime -lrt && add_extralibs -lrt; }
 check_func  fcntl
 check_func  fork
 check_func  gethrtime
@@ -3199,13 +3536,14 @@
 check_func_headers malloc.h _aligned_malloc     && enable aligned_malloc
 check_func  setrlimit
 check_func  strerror_r
-check_func  strptime
-check_func  strtok_r
 check_func  sched_getaffinity
 check_func  sysconf
 check_func  sysctl
 check_func  usleep
+check_func_headers conio.h kbhit
+check_func_headers windows.h PeekNamedPipe
 check_func_headers io.h setmode
+check_func_headers lzo/lzo1x.h lzo1x_999_compress
 check_lib2 "windows.h shellapi.h" CommandLineToArgvW -lshell32
 check_lib2 "windows.h wincrypt.h" CryptGenRandom -ladvapi32
 check_lib2 "windows.h psapi.h" GetProcessMemoryInfo -lpsapi
@@ -3215,12 +3553,14 @@
 check_func_headers windows.h MapViewOfFile
 check_func_headers windows.h Sleep
 check_func_headers windows.h VirtualAlloc
+check_func_headers glob.h glob
 
 check_header direct.h
 check_header dlfcn.h
 check_header dxva.h
-check_header dxva2api.h
+check_header dxva2api.h -D_WIN32_WINNT=0x0600
 check_header io.h
+check_header libcrystalhd/libcrystalhd_if.h
 check_header malloc.h
 check_header poll.h
 check_header sys/mman.h
@@ -3228,22 +3568,32 @@
 check_header sys/resource.h
 check_header sys/select.h
 check_header sys/time.h
+check_header termios.h
 check_header unistd.h
 check_header vdpau/vdpau.h
 check_header vdpau/vdpau_x11.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
+
 if ! disabled w32threads && ! enabled pthreads; then
     check_func _beginthreadex && enable w32threads
 fi
 
 # check for some common methods of building with pthread support
 # do this before the optional library checks as some of them require pthreads
-if ! disabled pthreads && ! enabled w32threads; then
+if ! disabled pthreads && ! enabled w32threads && ! enabled os2threads; then
     enable pthreads
     if check_func pthread_create; then
         :
@@ -3268,7 +3618,12 @@
     fi
 done
 
+if enabled pthreads; then
+  check_func pthread_cancel
+fi
+
 check_lib math.h sin -lm && LIBM="-lm"
+disabled crystalhd || check_lib libcrystalhd/libcrystalhd_if.h DtsCrystalHDVersion -lcrystalhd || disable crystalhd
 enabled vaapi && require vaapi va/va.h vaInitialize -lva
 
 check_mathfunc cbrtf
@@ -3290,37 +3645,64 @@
 
 # these are off by default, so fail if requested and not available
 enabled avisynth   && require2 vfw32 "windows.h vfw.h" AVIFileInit -lavifil32
+enabled fontconfig && require_pkg_config fontconfig "fontconfig/fontconfig.h" FcInit
 enabled frei0r     && { check_header frei0r.h || die "ERROR: frei0r.h header not found"; }
 enabled gnutls     && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_init
+enabled libiec61883 && require libiec61883 libiec61883/iec61883.h iec61883_cmp_connect -lraw1394 -lavc1394 -lrom1394 -liec61883
+enabled libaacplus && require  "libaacplus >= 2.0.0" aacplus.h aacplusEncOpen -laacplus
+enabled libass     && require_pkg_config libass ass/ass.h ass_library_init
+enabled libbluray  && require libbluray libbluray/bluray.h bd_open -lbluray
+enabled 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."; }
+enabled libcaca    && require_pkg_config caca caca.h caca_create_canvas
 enabled libfaac    && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac
 enabled libfdk_aac && require  libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac
+flite_libs="-lflite_cmu_time_awb -lflite_cmu_us_awb -lflite_cmu_us_kal -lflite_cmu_us_kal16 -lflite_cmu_us_rms -lflite_cmu_us_slt -lflite_usenglish -lflite_cmulex -lflite"
+enabled libflite   && require2 libflite "flite/flite.h" flite_init $flite_libs
 enabled libfreetype && require_pkg_config freetype2 "ft2build.h freetype/freetype.h" FT_Init_FreeType
 enabled libgsm     && require  libgsm gsm/gsm.h gsm_create -lgsm
 enabled libilbc    && require  libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc
+enabled libmodplug && require  libmodplug libmodplug/modplug.h ModPlug_Load -lmodplug
 enabled libmp3lame && require  "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame
+enabled libnut     && require  libnut libnut.h nut_demuxer_init -lnut
 enabled libopencore_amrnb  && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb
 enabled libopencore_amrwb  && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb
-enabled libopencv  && require_pkg_config opencv opencv/cv.h cvCreateImageHeader
+enabled libopencv  && require_pkg_config opencv opencv/cxcore.h cvCreateImageHeader
 enabled libopenjpeg && require libopenjpeg openjpeg.h opj_version -lopenjpeg
 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 libspeex   && require  libspeex speex/speex.h speex_decoder_init -lspeex
+enabled libstagefright_h264  && require_cpp libstagefright_h264 "binder/ProcessState.h media/stagefright/MetaData.h
+    media/stagefright/MediaBufferGroup.h media/stagefright/MediaDebug.h media/stagefright/MediaDefs.h
+    media/stagefright/OMXClient.h media/stagefright/OMXCodec.h" android::OMXClient -lstagefright -lmedia -lutils -lbinder -lgnustl_static
 enabled libtheora  && require  libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
+enabled libtwolame && require  libtwolame twolame.h twolame_init -ltwolame &&
+                      { check_lib twolame.h twolame_encode_buffer_float32_interleaved -ltwolame ||
+                        die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; }
+enabled libutvideo    && require_cpp utvideo "stdint.h stdlib.h utvideo/utvideo.h utvideo/Codec.h" 'CCodec*' -lutvideo -lstdc++
+enabled libv4l2    && require_pkg_config libv4l2 libv4l2.h v4l2_ioctl
 enabled libvo_aacenc && require libvo_aacenc vo-aacenc/voAAC.h voGetAACEncAPI -lvo-aacenc
 enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
 enabled libvorbis  && require  libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg
 enabled libvpx     && {
     enabled libvpx_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_encoder && { check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_enc_init_ver -lvpx ||
-                                die "ERROR: libvpx encoder version must be >=0.9.1"; } }
+                                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 libx264    && require  libx264 x264.h x264_encoder_encode -lx264 &&
                       { check_cpp_condition x264.h "X264_BUILD >= 118" ||
-                        die "ERROR: libx264 version must be >= 0.118."; }
+                        die "ERROR: libx264 must be installed and version must be >= 0.118."; }
 enabled libxavs    && require  libxavs xavs.h xavs_encoder_encode -lxavs
 enabled libxvid    && require  libxvid xvid.h xvid_global -lxvidcore
+enabled openal     && { { for al_libs in "${OPENAL_LIBS}" "-lopenal" "-lOpenAL32"; do
+                        check_lib 'AL/al.h' alGetError "${al_libs}" && break; done } ||
+                        die "ERROR: openal not found"; } &&
+                      { check_cpp_condition "AL/al.h" "defined(AL_VERSION_1_1)" ||
+                        die "ERROR: openal must be installed and version must be 1.1 or compatible"; }
 enabled openssl    && { check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto ||
                         check_lib openssl/ssl.h SSL_library_init -lssl32 -leay32 ||
                         check_lib openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 ||
@@ -3340,15 +3722,30 @@
     die "ERROR: No version of libdc1394 found "
 fi
 
+SDL_CONFIG="${cross_prefix}sdl-config"
 if check_pkg_config sdl SDL_events.h SDL_PollEvent; then
     check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x010201" $sdl_cflags &&
     enable sdl &&
     check_struct SDL.h SDL_VideoInfo current_w $sdl_cflags && enable sdl_video_size
+else
+  if "${SDL_CONFIG}" --version > /dev/null 2>&1; then
+    sdl_cflags=$("${SDL_CONFIG}" --cflags)
+    sdl_libs=$("${SDL_CONFIG}" --libs)
+    check_func_headers SDL_version.h SDL_Linked_Version $sdl_cflags $sdl_libs &&
+    check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x010201" $sdl_cflags &&
+    enable sdl &&
+    check_struct SDL.h SDL_VideoInfo current_w $sdl_cflags && enable sdl_video_size
+  fi
 fi
+enabled sdl && add_cflags $sdl_cflags && add_extralibs $sdl_libs
 
-texi2html -version > /dev/null 2>&1 && enable texi2html || disable texi2html
+texi2html --help 2> /dev/null | grep -q 'init-file' && enable texi2html || disable texi2html
+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
 
 check_header linux/fb.h
+check_header linux/videodev.h
 check_header linux/videodev2.h
 check_struct linux/videodev2.h "struct v4l2_frmivalenum" discrete
 
@@ -3359,6 +3756,8 @@
 # w32api 3.12 had it defined wrong
 check_cpp_condition vfw.h "WM_CAP_DRIVER_CONNECT > WM_USER" && enable vfwcap_defines
 
+check_type "dshow.h" IBaseFilter
+
 # check for ioctl_meteor.h, ioctl_bt848.h and alternatives
 { check_header dev/bktr/ioctl_meteor.h &&
   check_header dev/bktr/ioctl_bt848.h; } ||
@@ -3369,27 +3768,33 @@
 check_header dev/ic/bt8xx.h
 
 check_header sndio.h
-check_header sys/soundcard.h
+if check_struct sys/soundcard.h audio_buf_info bytes; then
+    enable_safe sys/soundcard.h
+else
+    check_cc -D__BSD_VISIBLE -D__XSI_VISIBLE <<EOF && add_cppflags -D__BSD_VISIBLE -D__XSI_VISIBLE && enable_safe sys/soundcard.h
+    #include <sys/soundcard.h>
+    audio_buf_info abc;
+EOF
+fi
 check_header soundcard.h
 
 enabled_any alsa_indev alsa_outdev && check_lib2 alsa/asoundlib.h snd_pcm_htimestamp -lasound
 
-enabled jack_indev && check_lib2 jack/jack.h jack_client_open -ljack &&
+enabled jack_indev && check_lib2 jack/jack.h jack_client_open -ljack && check_func sem_timedwait &&
     check_func jack_port_get_latency_range -ljack
 
 enabled_any sndio_indev sndio_outdev && check_lib2 sndio.h sio_open -lsndio
 
-enabled libcdio &&
-    check_lib2 "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open "-lcdio_paranoia -lcdio_cdda -lcdio"
-
 enabled x11grab                                           &&
 require X11 X11/Xlib.h XOpenDisplay -lX11                 &&
 require Xext X11/extensions/XShm.h XShmCreateImage -lXext &&
 require Xfixes X11/extensions/Xfixes.h XFixesGetCursorImage -lXfixes
 
-# check for VDA header
-if ! disabled vda && check_header VideoDecodeAcceleration/VDADecoder.h; then
-    enable vda && add_extralibs -framework CoreFoundation -framework VideoDecodeAcceleration -framework QuartzCore
+if ! disabled vaapi; then
+    check_lib va/va.h vaInitialize -lva && {
+        check_cpp_condition va/va_version.h "VA_CHECK_VERSION(0,32,0)" ||
+        warn "Please upgrade to VA-API >= 0.32 if you would like full VA-API support.";
+    } || disable vaapi
 fi
 
 if ! disabled vdpau && enabled vdpau_vdpau_h; then
@@ -3398,6 +3803,8 @@
 fi
 
 enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel"
+enabled coverage && add_cflags "-fprofile-arcs -ftest-coverage" && add_ldflags "-fprofile-arcs -ftest-coverage"
+test -n "$valgrind" && target_exec="$valgrind --error-exitcode=1 --malloc-fill=0x2a --track-origins=yes --leak-check=full --gen-suppressions=all --suppressions=$source_path/tests/fate-valgrind.supp"
 
 # add some useful compiler flags if supported
 check_cflags -Wdeclaration-after-statement
@@ -3409,17 +3816,17 @@
 check_cflags -Wpointer-arith
 check_cflags -Wredundant-decls
 check_cflags -Wno-pointer-sign
-check_cflags -Wcast-qual
 check_cflags -Wwrite-strings
 check_cflags -Wtype-limits
 check_cflags -Wundef
 check_cflags -Wmissing-prototypes
+check_cflags -Wno-pointer-to-int-cast
 check_cflags -Wstrict-prototypes
 enabled extra_warnings && check_cflags -Winline
 
 # add some linker flags
 check_ldflags -Wl,--warn-common
-check_ldflags -Wl,-rpath-link=libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample
+check_ldflags -Wl,-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample
 test_ldflags -Wl,-Bsymbolic && append SHFLAGS -Wl,-Bsymbolic
 
 enabled xmm_clobber_test &&
@@ -3472,6 +3879,13 @@
 check_optflags -fno-math-errno
 check_optflags -fno-signed-zeros
 
+enabled ftrapv && check_cflags -ftrapv
+
+check_cc -mno-red-zone <<EOF && noredzone_flags="-mno-red-zone"
+int x;
+EOF
+
+
 if enabled icc; then
     # Just warnings, no remarks
     check_cflags -w1
@@ -3508,7 +3922,6 @@
     check_optflags -fno-tree-vectorize
     check_cflags -Werror=implicit-function-declaration
     check_cflags -Werror=missing-prototypes
-    check_cflags -Werror=declaration-after-statement
     check_cflags -Werror=vla
 elif enabled llvm_gcc; then
     check_cflags -mllvm -stack-alignment=16
@@ -3541,9 +3954,42 @@
            $ALL_COMPONENTS    \
            $ALL_TESTS         \
 
+
+if test $target_os = "haiku"; then
+    disable memalign
+    disable posix_memalign
+fi
+
 ! enabled_any memalign posix_memalign aligned_malloc &&
     enabled_any $need_memalign && enable memalign_hack
 
+# add_dep lib dep
+# -> enable ${lib}_deps_${dep}
+# -> add $dep to ${lib}_deps only once
+add_dep() {
+    lib=$1
+    dep=$2
+    enabled "${lib}_deps_${dep}" && return 0
+    enable  "${lib}_deps_${dep}"
+    prepend "${lib}_deps" $dep
+}
+
+# merge deps lib components
+# merge all ${component}_deps into ${lib}_deps and ${lib}_deps_*
+merge_deps() {
+    lib=$1
+    shift
+    for comp in $*; do
+        enabled $comp || continue
+        eval "dep=\"\$${comp}_deps\""
+        for d in $dep; do
+            add_dep $lib $d
+        done
+    done
+}
+
+merge_deps libavfilter $FILTER_LIST
+
 echo "install prefix            $prefix"
 echo "source path               $source_path"
 echo "C compiler                $cc"
@@ -3551,6 +3997,9 @@
 if test "$build_suffix" != ""; then
     echo "build suffix              $build_suffix"
 fi
+if test "$progs_suffix" != ""; then
+    echo "progs suffix              $progs_suffix"
+fi
 if test "$extra_version" != ""; then
     echo "version string suffix     $extra_version"
 fi
@@ -3580,6 +4029,10 @@
 fi
 if enabled mips; then
     echo "MMI enabled               ${mmi-no}"
+    echo "MIPS FPU enabled          ${mipsfpu-no}"
+    echo "MIPS32R2 enabled          ${mips32r2-no}"
+    echo "MIPS DSP R1 enabled       ${mipsdspr1-no}"
+    echo "MIPS DSP R2 enabled       ${mipsdspr2-no}"
 fi
 if enabled ppc; then
     echo "AltiVec enabled           ${altivec-no}"
@@ -3590,10 +4043,12 @@
     echo "VIS enabled               ${vis-no}"
 fi
 echo "debug symbols             ${debug-no}"
+echo "strip symbols             ${stripping-no}"
 echo "optimize for size         ${small-no}"
 echo "optimizations             ${optimizations-no}"
 echo "static                    ${static-no}"
 echo "shared                    ${shared-no}"
+echo "postprocessing support    ${postproc-no}"
 echo "new filter support        ${avfilter-no}"
 echo "network support           ${network-no}"
 echo "threading support         ${thread_type-no}"
@@ -3605,13 +4060,20 @@
 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}"
@@ -3621,7 +4083,11 @@
 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}"
@@ -3629,9 +4095,14 @@
 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}"
+echo "makeinfo enabled          ${makeinfo-no}"
 test -n "$random_seed" &&
     echo "random seed               ${random_seed}"
 echo
@@ -3660,11 +4131,15 @@
 
 test -e Makefile || $ln_s "$source_path/Makefile" .
 
+enabled stripping || strip="echo skipping strip"
+
 config_files="$TMPH config.mak"
 
 cat > config.mak <<EOF
 # Automatically generated by configure - do not modify!
-LIBAV_CONFIGURATION=$LIBAV_CONFIGURATION
+ifndef FFMPEG_CONFIG_MAK
+FFMPEG_CONFIG_MAK=1
+FFMPEG_CONFIGURATION=$FFMPEG_CONFIGURATION
 prefix=$prefix
 LIBDIR=\$(DESTDIR)$libdir
 SHLIBDIR=\$(DESTDIR)$shlibdir
@@ -3673,9 +4148,13 @@
 DATADIR=\$(DESTDIR)$datadir
 MANDIR=\$(DESTDIR)$mandir
 SRC_PATH=$source_path
+ifndef MAIN_MAKEFILE
+SRC_PATH:=\$(SRC_PATH:.%=..%)
+endif
 CC_IDENT=$cc_ident
 ARCH=$arch
 CC=$cc
+CXX=$cxx
 AS=$as
 LD=$ld
 DEPCC=$dep_cc
@@ -3688,23 +4167,29 @@
 ARFLAGS=$arflags
 AR_O=$ar_o
 RANLIB=$ranlib
+CP=cp -p
 LN_S=$ln_s
+STRIP=$strip
 CPPFLAGS=$CPPFLAGS
 CFLAGS=$CFLAGS
+CXXFLAGS=$CXXFLAGS
 ASFLAGS=$ASFLAGS
 AS_C=$AS_C
 AS_O=$AS_O
 CC_C=$CC_C
 CC_O=$CC_O
+CXX_C=$CXX_C
+CXX_O=$CXX_O
 LD_O=$LD_O
 LD_LIB=$LD_LIB
 LD_PATH=$LD_PATH
 DLLTOOL=$dlltool
 LDFLAGS=$LDFLAGS
-LDFLAGS-avserver=$AVSERVERLDFLAGS
+LDFLAGS-ffserver=$FFSERVERLDFLAGS
 SHFLAGS=$SHFLAGS
 YASMFLAGS=$YASMFLAGS
 BUILDSUF=$build_suffix
+PROGSSUF=$progs_suffix
 FULLNAME=$FULLNAME
 LIBPREF=$LIBPREF
 LIBSUF=$LIBSUF
@@ -3714,6 +4199,7 @@
 EXESUF=$EXESUF
 EXTRA_VERSION=$extra_version
 CCDEP=$CCDEP
+CXXDEP=$CXXDEP
 CCDEP_FLAGS=$CCDEP_FLAGS
 ASDEP=$ASDEP
 ASDEP_FLAGS=$ASDEP_FLAGS
@@ -3735,12 +4221,12 @@
 HOSTLD_O=$HOSTLD_O
 TARGET_EXEC=$target_exec
 TARGET_PATH=$target_path
-LIBS-avplay=$sdl_libs
-CFLAGS-avplay=$sdl_cflags
+LIBS-ffplay=$sdl_libs
+CFLAGS-ffplay=$sdl_cflags
 ZLIB=$($ldflags_filter -lz)
 LIB_INSTALL_EXTRA_CMD=$LIB_INSTALL_EXTRA_CMD
 EXTRALIBS=$extralibs
-INSTALL=install
+INSTALL=$install
 LIBTARGET=${LIBTARGET}
 SLIBNAME=${SLIBNAME}
 SLIBNAME_WITH_VERSION=${SLIBNAME_WITH_VERSION}
@@ -3751,7 +4237,8 @@
 SLIB_INSTALL_LINKS=${SLIB_INSTALL_LINKS}
 SLIB_INSTALL_EXTRA_LIB=${SLIB_INSTALL_EXTRA_LIB}
 SLIB_INSTALL_EXTRA_SHLIB=${SLIB_INSTALL_EXTRA_SHLIB}
-SAMPLES:=${samples:-\$(LIBAV_SAMPLES)}
+SAMPLES:=${samples:-\$(FATE_SAMPLES)}
+NOREDZONE_FLAGS=$noredzone_flags
 EOF
 
 get_version(){
@@ -3764,28 +4251,49 @@
     eval echo "${lcname}_VERSION_MAJOR=\$${name}_VERSION_MAJOR" >> 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
+
 get_version libavcodec
 get_version libavdevice
 get_version libavfilter
 get_version libavformat
 get_version libavresample
 get_version libavutil
+get_version libswresample
 get_version libswscale
 
 cat > $TMPH <<EOF
 /* Automatically generated by configure - do not modify! */
-#ifndef LIBAV_CONFIG_H
-#define LIBAV_CONFIG_H
-#define LIBAV_CONFIGURATION "$(c_escape $LIBAV_CONFIGURATION)"
-#define LIBAV_LICENSE "$(c_escape $license)"
+#ifndef FFMPEG_CONFIG_H
+#define FFMPEG_CONFIG_H
+#define FFMPEG_CONFIGURATION "$(c_escape $FFMPEG_CONFIGURATION)"
+#define FFMPEG_LICENSE "$(c_escape $license)"
+#define FFMPEG_DATADIR "$(eval c_escape $datadir)"
 #define AVCONV_DATADIR "$(eval c_escape $datadir)"
 #define CC_IDENT "$(c_escape ${cc_ident:-Unknown compiler})"
-#define restrict $_restrict
+#define av_restrict $_restrict
 #define EXTERN_PREFIX "${extern_prefix}"
 #define EXTERN_ASM ${extern_prefix}
 #define SLIBSUF "$SLIBSUF"
+#define HAVE_MMX2 HAVE_MMXEXT
 EOF
 
+test -n "$assert_level" &&
+    echo "#define ASSERT_LEVEL $assert_level" >>$TMPH
+
 test -n "$malloc_prefix" &&
     echo "#define MALLOC_PREFIX $malloc_prefix" >>$TMPH
 
@@ -3801,12 +4309,14 @@
                                      $ALL_COMPONENTS    \
 
 cat >>config.mak <<EOF
+LAVF_FATE_TESTS=$(print_enabled -n _test $LAVF_FATE_TESTS)
 LAVF_TESTS=$(print_enabled   -n _test $LAVF_TESTS)
 LAVFI_TESTS=$(print_enabled  -n _test $LAVFI_TESTS)
 SEEK_TESTS=$(print_enabled   -n _test $SEEK_TESTS)
 EOF
 
-echo "#endif /* LIBAV_CONFIG_H */" >> $TMPH
+echo "#endif /* FFMPEG_CONFIG_H */" >> $TMPH
+echo "endif # FFMPEG_CONFIG_MAK" >> config.mak
 
 # Do not overwrite an unchanged config.h to avoid superfluous rebuilds.
 cp_if_changed $TMPH config.h
@@ -3820,6 +4330,12 @@
 #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
@@ -3855,26 +4371,66 @@
 Libs.private: $(enabled shared && echo $libs)
 Cflags: -I\${includedir}
 EOF
-    cat <<EOF > $name/$name-uninstalled.pc
+
+mkdir -p doc/examples/pc-uninstalled
+includedir=${source_path}
+[ "$includedir" = . ] && includedir="\${pcfiledir}/../../.."
+    cat <<EOF > doc/examples/pc-uninstalled/$name.pc
 prefix=
 exec_prefix=
-libdir=\${pcfiledir}
-includedir=${source_path}
+libdir=\${pcfiledir}/../../../$name
+includedir=${includedir}
 
 Name: $name
 Description: $comment
 Version: $version
 Requires: $requires
 Conflicts:
-Libs: \${libdir}/${LIBPREF}${shortname}${LIBSUF} $libs
+Libs: -L\${libdir} -l${shortname} $(enabled shared || echo $libs)
 Cflags: -I\${includedir}
 EOF
 }
 
-pkgconfig_generate libavutil "Libav utility library" "$LIBAVUTIL_VERSION" "$LIBM"
-pkgconfig_generate libavcodec "Libav codec library" "$LIBAVCODEC_VERSION" "$extralibs" "libavutil = $LIBAVUTIL_VERSION"
-pkgconfig_generate libavformat "Libav container format library" "$LIBAVFORMAT_VERSION" "$extralibs" "libavcodec = $LIBAVCODEC_VERSION"
-pkgconfig_generate libavdevice "Libav device handling library" "$LIBAVDEVICE_VERSION" "$extralibs" "libavformat = $LIBAVFORMAT_VERSION"
-pkgconfig_generate libavfilter "Libav video filtering library" "$LIBAVFILTER_VERSION" "$extralibs"
+libavfilter_pc_deps=""
+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_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=${libavfilter_pc_deps%, }
+
+libavdevice_pc_deps="libavformat = $LIBAVFORMAT_VERSION"
+enabled lavfi_indev && prepend libavdevice_pc_deps "libavfilter = $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 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"
-pkgconfig_generate libswscale "Libav image rescaling library" "$LIBSWSCALE_VERSION" "$LIBM" "libavutil = $LIBAVUTIL_VERSION"
+pkgconfig_generate libswscale "FFmpeg image rescaling library" "$LIBSWSCALE_VERSION" "$LIBM" "libavutil = $LIBAVUTIL_VERSION"
+pkgconfig_generate libswresample "FFmpeg audio rescaling library" "$LIBSWRESAMPLE_VERSION" "$LIBM" "libavutil = $LIBAVUTIL_VERSION"
+
+fix_ffmpeg_remote(){
+    git_remote_from=$1
+    git_remote_to=$2
+    fixme_remote=$(git --git-dir=$source_path/.git --work-tree=$source_path remote -v | grep $git_remote_from | cut -f 1 | sort | uniq)
+    if [ "$fixme_remote" != "" ]; then
+        echolog "
+Outdated domain in git config, the official domain for ffmpeg git is since
+November 2011, source.ffmpeg.org, both the old and the new point to the same
+repository and server. To update it enter the following commands:
+"
+        for remote in $fixme_remote; do
+            echolog "git remote set-url $remote $git_remote_to"
+        done
+    fi
+}
+
+if test -f "$source_path/.git/config"; then
+    remote_from=git.videolan.org
+    remote_to=source.ffmpeg.org
+    fix_ffmpeg_remote git@$remote_from:ffmpeg   git@$remote_to:ffmpeg
+    fix_ffmpeg_remote git://$remote_from/ffmpeg git://$remote_to/ffmpeg
+fi
diff --git a/doc/APIchanges b/doc/APIchanges
index 0c9a455..1d6d34b 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -7,12 +7,96 @@
 libavfilter:   2012-06-22
 libavformat:   2012-01-27
 libavresample: 2012-04-24
+libpostproc:   2011-04-18
+libswresample: 2011-09-19
 libswscale:    2011-06-20
 libavutil:     2011-04-18
 
 
 API changes, most recent first:
 
+2012-09-27 - a70b493 - lavd 54.3.100 - version.h
+  Add LIBAVDEVICE_IDENT symbol.
+
+2012-09-27 - a70b493 - lavfi 3.18.100 - version.h
+  Add LIBAVFILTER_IDENT symbol.
+
+2012-09-27 - a70b493 - libswr 0.16.100 - version.h
+  Add LIBSWRESAMPLE_VERSION, LIBSWRESAMPLE_BUILD
+  and LIBSWRESAMPLE_IDENT symbols.
+
+2012-09-06 - 29e972f - lavu 51.72.100 - parseutils.h
+  Add av_small_strptime() time parsing function.
+
+  Can be used as a stripped-down replacement for strptime(), on
+  systems which do not support it.
+
+2012-08-25 - 2626cc4 - lavf 54.28.100
+  Matroska demuxer now identifies SRT subtitles as AV_CODEC_ID_SUBRIP instead
+  of AV_CODEC_ID_TEXT.
+
+2012-08-13 - 5c0d8bc - lavfi 3.8.100 - avfilter.h
+  Add avfilter_get_class() function, and priv_class field to AVFilter
+  struct.
+
+2012-08-12 - a25346e - lavu 51.69.100 - opt.h
+  Add AV_OPT_FLAG_FILTERING_PARAM symbol in opt.h.
+
+2012-07-31 - 23fc4dd - lavc 54.46.100
+  Add channels field to AVFrame.
+
+2012-07-30 - f893904 - lavu 51.66.100
+  Add av_get_channel_description()
+  and av_get_standard_channel_layout() functions.
+
+2012-07-21 - 016a472 - lavc 54.43.100
+  Add decode_error_flags field to AVFrame.
+
+2012-07-20 - b062936 - lavf 54.18.100
+  Add avformat_match_stream_specifier() function.
+
+2012-07-14 - f49ec1b - lavc 54.38.100 - avcodec.h
+  Add metadata to AVFrame, and the accessor functions
+  av_frame_get_metadata() and av_frame_set_metadata().
+
+2012-07-10 - 0e003d8 - lavc 54.33.100
+  Add av_fast_padded_mallocz().
+
+2012-07-10 - 21d5609 - lavfi 3.2.0 - avfilter.h
+  Add init_opaque() callback to AVFilter struct.
+
+2012-06-26 - e6674e4 - lavu 51.63.100 - imgutils.h
+  Add functions to libavutil/imgutils.h:
+  av_image_get_buffer_size()
+  av_image_fill_arrays()
+  av_image_copy_to_buffer()
+
+2012-06-24 - c41899a - lavu 51.62.100 - version.h
+  version moved from avutil.h to version.h
+
+2012-04-11 - 359abb1 - lavu 51.58.100 - error.h
+  Add av_make_error_string() and av_err2str() utilities to
+  libavutil/error.h.
+
+2012-06-05 - 62b39d4 - lavc 54.24.100
+  Add pkt_duration field to AVFrame.
+
+2012-05-24 - f2ee065 - lavu 51.54.100
+  Move AVPALETTE_SIZE and AVPALETTE_COUNT macros from
+  libavcodec/avcodec.h to libavutil/pixfmt.h.
+
+2012-05-14 - 94a9ac1 - lavf 54.5.100
+  Add av_guess_sample_aspect_ratio() function.
+
+2012-04-20 - 65fa7bc - lavfi 2.70.100
+  Add avfilter_unref_bufferp() to avfilter.h.
+
+2012-04-13 - 162e400 - lavfi 2.68.100
+  Install libavfilter/asrc_abuffer.h public header.
+
+2012-03-26 - a67d9cf - lavfi 2.66.100
+  Add avfilter_fill_frame_from_{audio_,}buffer_ref() functions.
+
 2012-10-12 - xxxxxxx - lavu 51.44.0 - pixdesc.h
   Add functions for accessing pixel format descriptors.
   Accessing the av_pix_fmt_descriptors array directly is now
@@ -62,10 +146,6 @@
   51efed1 - Add AVCodecDescriptor.props and AV_CODEC_PROP_INTRA_ONLY.
   91e59fe - Add avcodec_descriptor_get_by_name().
 
-
-2012-08-08 - 1d9c2dc - lavu 51.39 - avutil.h
-  Don't implicitly include libavutil/common.h in avutil.h
-
 2012-08-08 - 987170c - lavu 51.38 - dict.h
   Add av_dict_count().
 
@@ -84,9 +164,6 @@
 2012-07-29 - 681ed00 - lavf 54.13.0 - avformat.h
   Add AVFMT_FLAG_NOBUFFER for low latency use cases.
 
-2012-07-20 - b70d89a - lavfi 3.0.0 - avfilter.h
-  Add avfilter_unref_bufferp().
-
 2012-07-10 - 5fade8a - lavu 51.37.0
   Add av_malloc_array() and av_mallocz_array()
 
@@ -115,10 +192,6 @@
 2012-05-25 - 154486f - lavu 51.31.0 - opt.h
   Add av_opt_set_bin()
 
-2012-05-26 - e9cef89 - lavf 54.3.0
-  Add AVFMT_TS_NONSTRICT format flag to indicate that a muxer supports
-  non-increasing monotone timestamps.
-
 2012-05-15 - lavfi 2.17.0
   Add support for audio filters
   ac71230/a2cd9be - add video/audio buffer sink in a new installed
@@ -165,16 +238,34 @@
 
 2012-04-14 - lavfi 2.16.0 - avfiltergraph.h
   d7bcc71 Add avfilter_graph_parse2().
-  91d3cbe Add avfilter_inout_alloc() and avfilter_inout_free().
 
 2012-04-08 - 4d693b0 - lavu 51.27.0 - samplefmt.h
   Add av_get_packed_sample_fmt() and av_get_planar_sample_fmt()
 
-2012-04-05 - 5cc51a5 - lavu 51.26.0 - audioconvert.h
-  Add av_get_default_channel_layout()
+2012-03-21 - b75c67d - lavu 51.43.100
+  Add bprint.h for bprint API.
 
-2012-03-06 - 4d851f8 - lavu 51.25.0 - cpu.h
-  Add av_set_cpu_flags_mask().
+2012-02-21 - 9cbf17e - lavc 54.4.100
+  Add av_get_pcm_codec() function.
+
+2012-02-16 - 560b224 - libswr 0.7.100
+  Add swr_set_matrix() function.
+
+2012-02-09 - c28e7af - lavu 51.39.100
+  Add a new installed header libavutil/timestamp.h with timestamp
+  utilities.
+
+2012-02-06 - 70ffda3 - lavu 51.38.100
+  Add av_parse_ratio() function to parseutils.h.
+
+2012-02-06 - 70ffda3 - lavu 51.38.100
+  Add AV_LOG_MAX_OFFSET macro to log.h.
+
+2012-02-02 - 0eaa123 - lavu 51.37.100
+  Add public timecode helpers.
+
+2012-01-24 - 0c3577b - lavfi 2.60.100
+  Add avfilter_graph_dump.
 
 2012-03-05 - lavc 54.8.0
   6699d07 Add av_get_exact_bits_per_sample()
@@ -230,10 +321,6 @@
           muxers supporting it (av_write_frame makes sure it is called
           only for muxers with this flag).
 
-------------------------------8<-------------------------------------
-                   0.8 branch was cut here
------------------------------>8--------------------------------------
-
 2012-01-15 - lavc 53.34.0
   New audio encoding API:
   b2c75b6 Add CODEC_CAP_VARIABLE_FRAME_SIZE capability for use by audio
@@ -245,23 +332,27 @@
 2012-01-12 - 3167dc9 - lavfi 2.15.0
   Add a new installed header -- libavfilter/version.h -- with version macros.
 
+2011-12-08 - a502939 - lavfi 2.52.0
+  Add av_buffersink_poll_frame() to buffersink.h.
+
+2011-12-08 - 26c6fec - lavu 51.31.0
+  Add av_log_format_line.
+
+2011-12-03 - 976b095 - lavu 51.30.0
+  Add AVERROR_BUG.
+
+2011-11-24 - 573ffbb - lavu 51.28.1
+  Add av_get_alt_sample_fmt() to samplefmt.h.
+
+2011-11-03 - 96949da - lavu 51.23.0
+  Add av_strcasecmp() and av_strncasecmp() to avstring.h.
+
+2011-10-20 - b35e9e1 - lavu 51.22.0
+  Add av_strtok() to avstring.h.
+
 2011-01-03 - b73ec05 - lavu 51.21.0
   Add av_popcount64
 
-2011-12-25 - lavfi 2.14.0
-  e1d9dbf Add a new installed header - buffersrc.h
-  It contains a new function av_buffersrc_buffer() that allows passing
-  frames to the 'buffer' filter, but unlike av_vsrc_buffer_add_frame()
-  it allows for direct rendering.
-  1c9e340 Add avfilter_copy_frame_props() for copying properties from
-  AVFrame to AVFilterBufferRef.
-
-2011-12-25 - lavc 53.31.0
-  Add the following new fields to AVFrame:
-    b58dbb5 sample_aspect_ratio
-    3a2ddf7 width, height
-    8a4a5f6 format
-
 2011-12-18 - 8400b12 - lavc 53.28.1
   Deprecate AVFrame.age. The field is unused.
 
@@ -348,49 +439,134 @@
   - 641c7af new functions - av_opt_child_next, av_opt_child_class_next
     and av_opt_find2()
 
-2011-09-03 - fb4ca26 - lavc 53.10.0
-                       lavf 53.6.0
+2011-09-22 - a70e787 - lavu 51.17.0
+  Add av_x_if_null().
+
+2011-09-18 - 645cebb - lavc 53.16.0
+  Add showall flag2
+
+2011-09-16 - ea8de10 - lavfi 2.42.0
+  Add avfilter_all_channel_layouts.
+
+2011-09-16 - 9899037 - lavfi 2.41.0
+  Rename avfilter_all_* function names to avfilter_make_all_*.
+
+  In particular, apply the renames:
+  avfilter_all_formats         -> avfilter_make_all_formats
+  avfilter_all_channel_layouts -> avfilter_make_all_channel_layouts
+  avfilter_all_packing_formats -> avfilter_make_all_packing_formats
+
+2011-09-12 - 4381bdd - lavfi 2.40.0
+  Change AVFilterBufferRefAudioProps.sample_rate type from uint32_t to int.
+
+2011-09-12 - 2c03174 - lavfi 2.40.0
+  Simplify signature for avfilter_get_audio_buffer(), make it
+  consistent with avfilter_get_video_buffer().
+
+2011-09-06 - 4f7dfe1 - lavfi 2.39.0
+  Rename libavfilter/vsink_buffer.h to libavfilter/buffersink.h.
+
+2011-09-06 - c4415f6 - lavfi 2.38.0
+  Unify video and audio sink API.
+
+  In particular, add av_buffersink_get_buffer_ref(), deprecate
+  av_vsink_buffer_get_video_buffer_ref() and change the value for the
+  opaque field passed to the abuffersink init function.
+
+2011-09-04 - 61e2e29 - lavu 51.16.0
+  Add av_asprintf().
+
+2011-08-22 - dacd827 - lavf 53.10.0
+  Add av_find_program_from_stream().
+
+2011-08-20 - 69e2c1a - lavu 51.13.0
+  Add av_get_media_type_string().
+
+2011-09-03 - fb4ca26 - lavc 53.13.0
+                       lavf 53.11.0
                        lsws  2.1.0
   Add {avcodec,avformat,sws}_get_class().
 
-2011-09-03 - c11fb82 - lavu 51.10.0
+2011-08-03 - 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
-  - f2011ed Add av_fifo_peek2(), deprecate av_fifo_peek().
   - add41de..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.4.0
+2011-08-16 - 48f9e45 - lavf 53.8.0
   Add avformat_query_codec().
 
-2011-08-16 - bca06e7 - lavc 53.8.0
+2011-08-16 - bca06e7 - lavc 53.11.0
   Add avcodec_get_type().
 
-2011-08-06 - 2f63440 - lavf 53.4.0
+2011-08-06 - 2f63440 - lavf 53.7.0
   Add error_recognition to AVFormatContext.
 
-2011-08-02 - 9d39cbf - lavc 53.7.1
+2011-08-02 - 9d39cbf - lavc 53.9.1
   Add AV_PKT_FLAG_CORRUPT AVPacket flag.
 
-2011-07-10 - a67c061 - lavf 53.3.0
+2011-07-16 - b57df29 - lavfi 2.27.0
+  Add audio packing negotiation fields and helper functions.
+
+  In particular, add AVFilterPacking enum, planar, in_packings and
+  out_packings fields to AVFilterLink, and the functions:
+  avfilter_set_common_packing_formats()
+  avfilter_all_packing_formats()
+
+2011-07-10 - 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.6.0
+2011-07-10 - 0b950fe - lavc 53.8.0
   Add avcodec_open2(), deprecate avcodec_open().
   NOTE: this was backported to 0.7
 
   Add avcodec_alloc_context3. Deprecate avcodec_alloc_context() and
   avcodec_alloc_context2().
 
+2011-07-01 - b442ca6 - lavf 53.5.0 - avformat.h
+  Add function av_get_output_timestamp().
+
+2011-06-28 - 5129336 - lavu 51.11.0 - avutil.h
+  Define the AV_PICTURE_TYPE_NONE value in AVPictureType enum.
+
+2011-06-19 - fd2c0a5 - lavfi 2.23.0 - avfilter.h
+  Add layout negotiation fields and helper functions.
+
+  In particular, add in_chlayouts and out_chlayouts to AVFilterLink,
+  and the functions:
+  avfilter_set_common_sample_formats()
+  avfilter_set_common_channel_layouts()
+  avfilter_all_channel_layouts()
+
+2011-06-19 - 527ca39 - lavfi 2.22.0 - AVFilterFormats
+  Change type of AVFilterFormats.formats from int * to int64_t *,
+  and update formats handling API accordingly.
+
+  avfilter_make_format_list() still takes a int32_t array and converts
+  it to int64_t. A new function, avfilter_make_format64_list(), that
+  takes int64_t arrays has been added.
+
+2011-06-19 - 44f669e - lavfi 2.21.0 - vsink_buffer.h
+  Add video sink buffer and vsink_buffer.h public header.
+
+2011-06-12 - 9fdf772 - lavfi 2.18.0 - avcodec.h
+  Add avfilter_get_video_buffer_ref_from_frame() function in
+  libavfilter/avcodec.h.
+
+2011-06-12 - c535494 - lavfi 2.17.0 - avfiltergraph.h
+  Add avfilter_inout_alloc() and avfilter_inout_free() functions.
+
+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
   Add av_printf_format().
 
-------------------------------8<-------------------------------------
-                   0.7 branch was cut here
------------------------------>8--------------------------------------
-
 2011-06-16 - 05e84c9, 25de595 - lavf 53.2.0 - avformat.h
   Add avformat_open_input and avformat_write_header().
   Deprecate av_open_input_stream, av_open_input_file,
@@ -404,34 +580,97 @@
 2011-06-10 - cb7c11c - lavu 51.6.0 - opt.h
   Add av_opt_flag_is_set().
 
-2011-06-08 - d9f80ea - lavu 51.5.0 - AVMetadata
+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
   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.4.0 - av_get_bytes_per_sample()
+2011-06-07 - 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.3.0 - opt.h
+2011-06-05 - b39b062 - lavu 51.8.0 - opt.h
   Add av_opt_free convenience function.
 
-2011-05-28 - 0420bd7 - lavu 51.2.0 - pixdesc.h
+2011-06-06 - 95a0242 - lavfi 2.14.0 - AVFilterBufferRefAudioProps
+  Remove AVFilterBufferRefAudioProps.size, and use nb_samples in
+  avfilter_get_audio_buffer() and avfilter_default_get_audio_buffer() in
+  place of size.
+
+2011-06-06 - 0bc2cca - lavu 51.6.0 - av_samples_alloc()
+  Switch nb_channels and nb_samples parameters order in
+  av_samples_alloc().
+
+2011-06-06 - e1c7414 - lavu 51.5.0 - av_samples_*
+  Change the data layout created by av_samples_fill_arrays() and
+  av_samples_alloc().
+
+2011-06-06 - 27bcf55 - lavfi 2.13.0 - vsrc_buffer.h
+  Make av_vsrc_buffer_add_video_buffer_ref() accepts an additional
+  flags parameter in input.
+
+2011-06-03 - e977ca2 - lavfi 2.12.0 - avfilter_link_free()
+  Add avfilter_link_free() function.
+
+2011-06-02 - 5ad38d9 - lavu 51.4.0 - av_force_cpu_flags()
+  Add av_cpu_flags() in libavutil/cpu.h.
+
+2011-05-28 - e71f260 - lavu 51.3.0 - pixdesc.h
   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.1.0 - avformat.h
+2011-05-25 - 30315a8 - lavf 53.3.0 - avformat.h
   Add fps_probe_size to AVFormatContext.
 
-2011-05-18 - 64150ff - lavc 53.4.0 - AVCodecContext.request_sample_fmt
+2011-05-22 - 5ecdfd0 - lavf 53.2.0 - avformat.h
+  Introduce avformat_alloc_output_context2() and deprecate
+  avformat_alloc_output_context().
+
+2011-05-22 - 83db719 - lavfi 2.10.0 - vsrc_buffer.h
+  Make libavfilter/vsrc_buffer.h public.
+
+2011-05-19 - c000a9f - lavfi 2.8.0 - avcodec.h
+  Add av_vsrc_buffer_add_frame() to libavfilter/avcodec.h.
+
+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
   Add request_sample_fmt field to AVCodecContext.
 
-2011-05-10 - 188dea1 - lavc 53.3.0 - avcodec.h
+2011-05-10 - 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.
   Corresponding FLAC encoder options should be used instead.
 
+2011-05-07 - 9fdf772 - lavfi 2.5.0 - avcodec.h
+  Add libavfilter/avcodec.h header and avfilter_copy_frame_props()
+  function.
+
+2011-05-07 - 18ded93 - lavc 53.5.0 - AVFrame
+  Add format field to AVFrame.
+
+2011-05-07 - 22333a6 - lavc 53.4.0 - AVFrame
+  Add width and height fields to AVFrame.
+
+2011-05-01 - 35fe66a - lavfi 2.4.0 - avfilter.h
+  Rename AVFilterBufferRefVideoProps.pixel_aspect to
+  sample_aspect_ratio.
+
+2011-05-01 - 77e9dee - lavc 53.3.0 - AVFrame
+  Add a sample_aspect_ratio field to AVFrame.
+
+2011-05-01 - 1ba5727 - lavc 53.2.0 - AVFrame
+  Add a pkt_pos field to AVFrame.
+
+2011-04-29 - 35ceaa7 - lavu 51.2.0 - mem.h
+  Add av_dynarray_add function for adding
+  an element to a dynamic array.
+
 2011-04-26 - 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
@@ -483,9 +722,6 @@
     333e894 deprecate url_open_protocol
     e230705 deprecate url_poll and URLPollEntry
 
-2011-04-10 - lavu  50.40.0 - pixfmt.h
-  Add PIX_FMT_BGR48LE and PIX_FMT_BGR48BE pixel formats
-
 2011-04-08 - lavf 52.106.0 - avformat.h
   Minor avformat.h cleanup:
     a9bf9d8 deprecate av_guess_image2_codec
@@ -510,7 +746,6 @@
     d9d86e0 rename url_fprintf -> avio_printf
     59f65d9 deprecate url_setbufsize
     3e68b3b deprecate url_ferror
-    66e5b1d deprecate url_feof
     e8bb2e2 deprecate url_fget_max_packet_size
     76aa876 rename url_fsize -> avio_size
     e519753 deprecate url_fgetc
@@ -534,6 +769,9 @@
 2011-03-25 - 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
+  Add PIX_FMT_BGR48LE and PIX_FMT_BGR48BE pixel formats
+
 2011-03-02 - 863c471 - lavf  52.103.0 - av_pkt_dump2, av_pkt_dump_log2
   Add new functions av_pkt_dump2, av_pkt_dump_log2 that uses the
   source stream timebase for outputting timestamps. Deprecate
@@ -600,6 +838,12 @@
 2011-02-02 - dfd2a00 - lavu 50.37.0 - log.h
   Make av_dlog public.
 
+2011-01-31 - 7b3ea55 - lavfi 1.76.0 - vsrc_buffer
+  Add sample_aspect_ratio fields to vsrc_buffer arguments
+
+2011-01-31 - 910b5b8 - lavfi 1.75.0 - AVFilterLink sample_aspect_ratio
+  Add sample_aspect_ratio field to AVFilterLink.
+
 2011-01-15 - a242ac3 - lavfi 1.74.0 - AVFilterBufferRefAudioProps
   Rename AVFilterBufferRefAudioProps.samples_nb to nb_samples.
 
diff --git a/doc/Makefile b/doc/Makefile
index 6353034..41b0173 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -6,23 +6,37 @@
               doc/fate.html                                             \
               doc/general.html                                          \
               doc/git-howto.html                                        \
-              doc/libavfilter.html                                      \
               doc/nut.html                                              \
               doc/platform.html                                         \
+              doc/syntax.html                                           \
 
-DOCS = $(HTMLPAGES) $(MANPAGES) $(PODPAGES)
+TXTPAGES    = doc/fate.txt                                              \
 
-all-$(CONFIG_DOC): documentation
+
+DOCS-$(CONFIG_HTMLPAGES) += $(HTMLPAGES)
+DOCS-$(CONFIG_PODPAGES)  += $(PODPAGES)
+DOCS-$(CONFIG_MANPAGES)  += $(MANPAGES)
+DOCS-$(CONFIG_TXTPAGES)  += $(TXTPAGES)
+DOCS = $(DOCS-yes)
+
+all-$(CONFIG_DOC): doc
+
+doc: documentation
 
 documentation: $(DOCS)
 
-TEXIDEP = awk '/^@include/ { printf "$@: $(@D)/%s\n", $$2 }' <$< >$(@:%=%.d)
+TEXIDEP = awk '/^@(verbatim)?include/ { printf "$@: $(@D)/%s\n", $$2 }' <$< >$(@:%=%.d)
+
+doc/%.txt: TAG = TXT
+doc/%.txt: doc/%.texi
+	$(Q)$(TEXIDEP)
+	$(M)makeinfo --force --no-headers -o $@ $< 2>/dev/null
 
 GENTEXI  = format codec
 GENTEXI := $(GENTEXI:%=doc/avoptions_%.texi)
 
 $(GENTEXI): TAG = GENTEXI
-$(GENTEXI): doc/avoptions_%.texi: doc/print_options
+$(GENTEXI): doc/avoptions_%.texi: doc/print_options$(HOSTEXESUF)
 	$(M)doc/print_options $* > $@
 
 doc/%.html: TAG = HTML
@@ -33,7 +47,7 @@
 doc/%.pod: TAG = POD
 doc/%.pod: doc/%.texi $(GENTEXI)
 	$(Q)$(TEXIDEP)
-	$(M)$(SRC_PATH)/doc/texi2pod.pl -Idoc $< $@
+	$(M)perl $(SRC_PATH)/doc/texi2pod.pl -Idoc $< $@
 
 doc/%.1: TAG = MAN
 doc/%.1: doc/%.pod $(GENTEXI)
@@ -41,11 +55,15 @@
 
 $(DOCS): | doc/
 
+install-man:
+
+ifdef CONFIG_MANPAGES
 install-progs-$(CONFIG_DOC): install-man
 
 install-man: $(MANPAGES)
 	$(Q)mkdir -p "$(MANDIR)/man1"
 	$(INSTALL) -m 644 $(MANPAGES) "$(MANDIR)/man1"
+endif
 
 uninstall: uninstall-man
 
@@ -53,8 +71,8 @@
 	$(RM) $(addprefix "$(MANDIR)/man1/",$(ALLMANPAGES))
 
 clean::
-	$(RM) doc/*.html doc/*.pod doc/*.1 $(CLEANSUFFIXES:%=doc/%) doc/avoptions_*.texi
+	$(RM) $(TXTPAGES) doc/*.html doc/*.pod doc/*.1 $(CLEANSUFFIXES:%=doc/%) doc/avoptions_*.texi
 
 -include $(wildcard $(DOCS:%=%.d))
 
-.PHONY: documentation
+.PHONY: doc documentation
diff --git a/doc/RELEASE_NOTES b/doc/RELEASE_NOTES
index bb1aecb..135165a 100644
--- a/doc/RELEASE_NOTES
+++ b/doc/RELEASE_NOTES
@@ -1,95 +1,16 @@
 Release Notes
 =============
 
-* 9 "Plain Nine"
+* 0.10 "Freedom"  January, 2012
+
 
 General notes
 -------------
+See the Changelog file for a list of significant changes. Note, there
+are many more new features and bugfixes than whats listed there.
 
-From this release onwards, we have decided to drop the leading zero from our
-release numbers. There were no plans of ever changing it, so it carried no
-information. Thus this release is just a plain 9, the next will be 10 etc.
-
-A new library arrived in Libav during this development cycle -- its name is
-libavresample and it handles audio conversion and mixing. All users are
-encouraged to use it instead of the old, now deprecated, audio conversion
-API in libavcodec.
-
-The libpostproc library now resides in a separate tree. It was fully independent
-of the other Libav libraries, not used by any of the tools and saw very little
-development. For these reasons we decided that it has no place in Libav. A
-standalone Git tree is available at http://git.videolan.org/?p=libpostproc.git
-for people wishing to use libpostproc.
-
-The major versions of the libavcodec, libavformat and libavfilter libraries have
-been bumped, so they are not API or ABI compatible with the 0.8 release. The
-ffmpeg transcoding tool, kept for compatibility in 0.8, has also been dropped.
-
-This release brings a number of significant changes in the libavfilter library.
-Firstly, all the API dealing with filter internals is no longer public. The
-result is that creating user-side filters will not be supported until
-libavfilter is more mature.
-Secondly, full audio filtering support is now available along with a set of
-basic audio filters. We hope that their number will soon grow significantly.
-The avconv transcoding tool has of course been extended to handle audio
-filtering as well.
-There were a number of other API changes, most importantly the addition of
-the buffer sink public API.
-
-In the libavcodec library, one of the most notable changes is added support for
-planar audio (i.e. not interleaved). Many decoders and encoders, that previously
-did inefficient (de)interleaving internally, now only work with planar audio
-formats. Libavresample can be used for optimized conversion between interleaved
-and planar formats.
-
-As usual, this release also contains support for some new formats, many smaller
-new features and countless bug fixes. We can highlight Opus decoding / encoding
-through libopus, encoders for Apple ProRes and Ut Video, WMA Lossless and
-RealAudio Lossless decoders, fragmented MOV/MP4 and ISMV (Smooth Streaming)
-muxers, a large number of RTMP improvements and support for cover art in
-ID3v2, WMA, MP4 and FLAC.
-
-See the Changelog file for a list of significant changes.
-
-Please note that our policy on bug reports has not changed. We still only accept
-bug reports against HEAD of the Libav trunk repository. If you are experiencing
-issues with any formally released version of Libav, please try a current version
-of the development code to check if the issue still exists. If it does, make
-your report against the development code following the usual bug reporting
+Bugreports against FFmpeg git master or the most recent FFmpeg release are
+accepted. If you are experiencing issues with any formally released version of
+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.
-
-
-API changes
------------
-
-A number of additional APIs have been introduced and some existing functions
-have been deprecated and are scheduled for removal in the next release.
-Significant API changes include:
-
-[libavcodec]:
-* New video encoding API, similar to the previously introduced audio  encoding
-  API, which encodes from an AVFrame to an AVPacket, thus allowing it to
-  properly output timing information and side data.
-
-* All CODEC_ID_* symbols now carry AV_ prefixes. Non-prefixed codec IDs are
-  deprecated.
-
-* New codec descriptor API, which allows getting the properties of a given codec
-  (identified by its ID), without referring to a specific decoder or encoder.
-
-* An AVFrame must now be freed with a dedicated function, avcodec_free_frame().
-
-[libavutil]:
-* New audio FIFO API, which simplifies managing/merging/splitting audio buffers.
-
-* new int/float type punning API
-
-[libavfilter]:
-* All filter internals were hidden.
-
-* audio filtering.
-
-* new buffer sink API for getting frames out of libavfilter.
-
-Please see the file doc/APIchanges for details along with similar
-programmer-centric information.
diff --git a/doc/avconv.texi b/doc/avconv.texi
deleted file mode 100644
index 7341d2f..0000000
--- a/doc/avconv.texi
+++ /dev/null
@@ -1,1090 +0,0 @@
-\input texinfo @c -*- texinfo -*-
-
-@settitle avconv Documentation
-@titlepage
-@center @titlefont{avconv Documentation}
-@end titlepage
-
-@top
-
-@contents
-
-@chapter Synopsis
-
-The generic syntax is:
-
-@example
-@c man begin SYNOPSIS
-avconv [global options] [[infile options][@option{-i} @var{infile}]]... @{[outfile options] @var{outfile}@}...
-@c man end
-@end example
-
-@chapter Description
-@c man begin DESCRIPTION
-
-avconv is a very fast video and audio converter that can also grab from
-a live audio/video source. It can also convert between arbitrary sample
-rates and resize video on the fly with a high quality polyphase filter.
-
-avconv reads from an arbitrary number of input "files" (which can be regular
-files, pipes, network streams, grabbing devices, etc.), specified by the
-@code{-i} option, and writes to an arbitrary number of output "files", which are
-specified by a plain output filename. Anything found on the command line which
-cannot be interpreted as an option is considered to be an output filename.
-
-Each input or output file can in principle contain any number of streams of
-different types (video/audio/subtitle/attachment/data). Allowed number and/or
-types of streams can be limited by the container format. Selecting, which
-streams from which inputs go into output, is done either automatically or with
-the @code{-map} option (see the Stream selection chapter).
-
-To refer to input files in options, you must use their indices (0-based). E.g.
-the first input file is @code{0}, the second is @code{1} etc. Similarly, streams
-within a file are referred to by their indices. E.g. @code{2:3} refers to the
-fourth stream in the third input file. See also the Stream specifiers chapter.
-
-As a general rule, options are applied to the next specified
-file. Therefore, order is important, and you can have the same
-option on the command line multiple times. Each occurrence is
-then applied to the next input or output file.
-Exceptions from this rule are the global options (e.g. verbosity level),
-which should be specified first.
-
-Do not mix input and output files -- first specify all input files, then all
-output files. Also do not mix options which belong to different files. All
-options apply ONLY to the next input or output file and are reset between files.
-
-@itemize
-@item
-To set the video bitrate of the output file to 64kbit/s:
-@example
-avconv -i input.avi -b 64k output.avi
-@end example
-
-@item
-To force the frame rate of the output file to 24 fps:
-@example
-avconv -i input.avi -r 24 output.avi
-@end example
-
-@item
-To force the frame rate of the input file (valid for raw formats only)
-to 1 fps and the frame rate of the output file to 24 fps:
-@example
-avconv -r 1 -i input.m2v -r 24 output.avi
-@end example
-@end itemize
-
-The format option may be needed for raw input files.
-
-@c man end DESCRIPTION
-
-@chapter Detailed description
-@c man begin DETAILED DESCRIPTION
-
-The transcoding process in @command{avconv} for each output can be described by
-the following diagram:
-
-@example
- _______              ______________               _________              ______________            ________
-|       |            |              |             |         |            |              |          |        |
-| input |  demuxer   | encoded data |   decoder   | decoded |  encoder   | encoded data |  muxer   | output |
-| file  | ---------> | packets      |  ---------> | frames  | ---------> | packets      | -------> | file   |
-|_______|            |______________|             |_________|            |______________|          |________|
-
-@end example
-
-@command{avconv} calls the libavformat library (containing demuxers) to read
-input files and get packets containing encoded data from them. When there are
-multiple input files, @command{avconv} tries to keep them synchronized by
-tracking lowest timestamp on any active input stream.
-
-Encoded packets are then passed to the decoder (unless streamcopy is selected
-for the stream, see further for a description). The decoder produces
-uncompressed frames (raw video/PCM audio/...) which can be processed further by
-filtering (see next section). After filtering the frames are passed to the
-encoder, which encodes them and outputs encoded packets again. Finally those are
-passed to the muxer, which writes the encoded packets to the output file.
-
-@section Filtering
-Before encoding, @command{avconv} can process raw audio and video frames using
-filters from the libavfilter library. Several chained filters form a filter
-graph.  @command{avconv} distinguishes between two types of filtergraphs -
-simple and complex.
-
-@subsection Simple filtergraphs
-Simple filtergraphs are those that have exactly one input and output, both of
-the same type. In the above diagram they can be represented by simply inserting
-an additional step between decoding and encoding:
-
-@example
- _________                        __________              ______________
-|         |                      |          |            |              |
-| decoded |  simple filtergraph  | filtered |  encoder   | encoded data |
-| frames  | -------------------> | frames   | ---------> | packets      |
-|_________|                      |__________|            |______________|
-
-@end example
-
-Simple filtergraphs are configured with the per-stream @option{-filter} option
-(with @option{-vf} and @option{-af} aliases for video and audio respectively).
-A simple filtergraph for video can look for example like this:
-
-@example
- _______        _____________        _______        _____        ________
-|       |      |             |      |       |      |     |      |        |
-| input | ---> | deinterlace | ---> | scale | ---> | fps | ---> | output |
-|_______|      |_____________|      |_______|      |_____|      |________|
-
-@end example
-
-Note that some filters change frame properties but not frame contents. E.g. the
-@code{fps} filter in the example above changes number of frames, but does not
-touch the frame contents. Another example is the @code{setpts} filter, which
-only sets timestamps and otherwise passes the frames unchanged.
-
-@subsection Complex filtergraphs
-Complex filtergraphs are those which cannot be described as simply a linear
-processing chain applied to one stream. This is the case e.g. when the graph has
-more than one input and/or output, or when output stream type is different from
-input. They can be represented with the following diagram:
-
-@example
- _________
-|         |
-| input 0 |\                    __________
-|_________| \                  |          |
-             \   _________    /| output 0 |
-              \ |         |  / |__________|
- _________     \| complex | /
-|         |     |         |/
-| input 1 |---->| filter  |\
-|_________|     |         | \   __________
-               /| graph   |  \ |          |
-              / |         |   \| output 1 |
- _________   /  |_________|    |__________|
-|         | /
-| input 2 |/
-|_________|
-
-@end example
-
-Complex filtergraphs are configured with the @option{-filter_complex} option.
-Note that this option is global, since a complex filtergraph by its nature
-cannot be unambiguously associated with a single stream or file.
-
-A trivial example of a complex filtergraph is the @code{overlay} filter, which
-has two video inputs and one video output, containing one video overlaid on top
-of the other. Its audio counterpart is the @code{amix} filter.
-
-@section Stream copy
-Stream copy is a mode selected by supplying the @code{copy} parameter to the
-@option{-codec} option. It makes @command{avconv} omit the decoding and encoding
-step for the specified stream, so it does only demuxing and muxing. It is useful
-for changing the container format or modifying container-level metadata. The
-diagram above will in this case simplify to this:
-
-@example
- _______              ______________            ________
-|       |            |              |          |        |
-| input |  demuxer   | encoded data |  muxer   | output |
-| file  | ---------> | packets      | -------> | file   |
-|_______|            |______________|          |________|
-
-@end example
-
-Since there is no decoding or encoding, it is very fast and there is no quality
-loss. However it might not work in some cases because of many factors. Applying
-filters is obviously also impossible, since filters work on uncompressed data.
-
-@c man end DETAILED DESCRIPTION
-
-@chapter Stream selection
-@c man begin STREAM SELECTION
-
-By default avconv tries to pick the "best" stream of each type present in input
-files and add them to each output file. For video, this means the highest
-resolution, for audio the highest channel count. For subtitle it's simply the
-first subtitle stream.
-
-You can disable some of those defaults by using @code{-vn/-an/-sn} options. For
-full manual control, use the @code{-map} option, which disables the defaults just
-described.
-
-@c man end STREAM SELECTION
-
-@chapter Options
-@c man begin OPTIONS
-
-@include avtools-common-opts.texi
-
-@section Main options
-
-@table @option
-
-@item -f @var{fmt} (@emph{input/output})
-Force input or output file format. The format is normally autodetected for input
-files and guessed from file extension for output files, so this option is not
-needed in most cases.
-
-@item -i @var{filename} (@emph{input})
-input file name
-
-@item -y (@emph{global})
-Overwrite output files without asking.
-
-@item -c[:@var{stream_specifier}] @var{codec} (@emph{input/output,per-stream})
-@itemx -codec[:@var{stream_specifier}] @var{codec} (@emph{input/output,per-stream})
-Select an encoder (when used before an output file) or a decoder (when used
-before an input file) for one or more streams. @var{codec} is the name of a
-decoder/encoder or a special value @code{copy} (output only) to indicate that
-the stream is not to be reencoded.
-
-For example
-@example
-avconv -i INPUT -map 0 -c:v libx264 -c:a copy OUTPUT
-@end example
-encodes all video streams with libx264 and copies all audio streams.
-
-For each stream, the last matching @code{c} option is applied, so
-@example
-avconv -i INPUT -map 0 -c copy -c:v:1 libx264 -c:a:137 libvorbis OUTPUT
-@end example
-will copy all the streams except the second video, which will be encoded with
-libx264, and the 138th audio, which will be encoded with libvorbis.
-
-@item -t @var{duration} (@emph{output})
-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.
-
-@item -fs @var{limit_size} (@emph{output})
-Set the file size limit.
-
-@item -ss @var{position} (@emph{input/output})
-When used as an input option (before @code{-i}), seeks in this input file to
-@var{position}. When used as an output option (before an output filename),
-decodes but discards input until the timestamps reach @var{position}. This is
-slower, but more accurate.
-
-@var{position} may be either in seconds or in @code{hh:mm:ss[.xxx]} form.
-
-@item -itsoffset @var{offset} (@emph{input})
-Set the input time offset in seconds.
-@code{[-]hh:mm:ss[.xxx]} syntax is also supported.
-The offset is added to the timestamps of the input files.
-Specifying a positive offset means that the corresponding
-streams are delayed by @var{offset} seconds.
-
-@item -metadata[:metadata_specifier] @var{key}=@var{value} (@emph{output,per-metadata})
-Set a metadata key/value pair.
-
-An optional @var{metadata_specifier} may be given to set metadata
-on streams or chapters. See @code{-map_metadata} documentation for
-details.
-
-This option overrides metadata set with @code{-map_metadata}. It is
-also possible to delete metadata by using an empty value.
-
-For example, for setting the title in the output file:
-@example
-avconv -i in.avi -metadata title="my title" out.flv
-@end example
-
-To set the language of the first audio stream:
-@example
-avconv -i INPUT -metadata:s:a:0 language=eng OUTPUT
-@end example
-
-@item -target @var{type} (@emph{output})
-Specify target file type (@code{vcd}, @code{svcd}, @code{dvd}, @code{dv},
-@code{dv50}). @var{type} may be prefixed with @code{pal-}, @code{ntsc-} or
-@code{film-} to use the corresponding standard. All the format options
-(bitrate, codecs, buffer sizes) are then set automatically. You can just type:
-
-@example
-avconv -i myfile.avi -target vcd /tmp/vcd.mpg
-@end example
-
-Nevertheless you can specify additional options as long as you know
-they do not conflict with the standard, as in:
-
-@example
-avconv -i myfile.avi -target vcd -bf 2 /tmp/vcd.mpg
-@end example
-
-@item -dframes @var{number} (@emph{output})
-Set the number of data frames to record. This is an alias for @code{-frames:d}.
-
-@item -frames[:@var{stream_specifier}] @var{framecount} (@emph{output,per-stream})
-Stop writing to the stream after @var{framecount} frames.
-
-@item -q[:@var{stream_specifier}] @var{q} (@emph{output,per-stream})
-@itemx -qscale[:@var{stream_specifier}] @var{q} (@emph{output,per-stream})
-Use fixed quality scale (VBR). The meaning of @var{q} is
-codec-dependent.
-
-@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).
-
-See also the @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).
-
-@item -stats (@emph{global})
-Print encoding progress/statistics. On by default.
-
-@item -attach @var{filename} (@emph{output})
-Add an attachment to the output file. This is supported by a few formats
-like Matroska for e.g. fonts used in rendering subtitles. Attachments
-are implemented as a specific type of stream, so this option will add
-a new stream to the file. It is then possible to use per-stream options
-on this stream in the usual way. Attachment streams created with this
-option will be created after all the other streams (i.e. those created
-with @code{-map} or automatic mappings).
-
-Note that for Matroska you also have to set the mimetype metadata tag:
-@example
-avconv -i INPUT -attach DejaVuSans.ttf -metadata:s:2 mimetype=application/x-truetype-font out.mkv
-@end example
-(assuming that the attachment stream will be third in the output file).
-
-@item -dump_attachment[:@var{stream_specifier}] @var{filename} (@emph{input,per-stream})
-Extract the matching attachment stream into a file named @var{filename}. If
-@var{filename} is empty, then the value of the @code{filename} metadata tag
-will be used.
-
-E.g. to extract the first attachment to a file named 'out.ttf':
-@example
-avconv -dump_attachment:t:0 out.ttf INPUT
-@end example
-To extract all attachments to files determined by the @code{filename} tag:
-@example
-avconv -dump_attachment:t "" INPUT
-@end example
-
-Technical note -- attachments are implemented as codec extradata, so this
-option can actually be used to extract extradata from any stream, not just
-attachments.
-
-@end table
-
-@section Video Options
-
-@table @option
-@item -vframes @var{number} (@emph{output})
-Set the number of video frames to record. This is an alias for @code{-frames:v}.
-@item -r[:@var{stream_specifier}] @var{fps} (@emph{input/output,per-stream})
-Set frame rate (Hz value, fraction or abbreviation).
-
-As an input option, ignore any timestamps stored in the file and instead
-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).
-
-@item -s[:@var{stream_specifier}] @var{size} (@emph{input/output,per-stream})
-Set frame size.
-
-As an input option, this is a shortcut for the @option{video_size} private
-option, recognized by some demuxers for which the frame size is either not
-stored in the file or is configurable -- e.g. raw video or video grabbers.
-
-As an output option, this inserts the @code{scale} video filter to the
-@emph{end} of the corresponding filtergraph. Please use the @code{scale} filter
-directly to insert it at the beginning or some other place.
-
-The format is @samp{wxh} (default - same as source).  The following
-abbreviations are recognized:
-@table @samp
-@item sqcif
-128x96
-@item qcif
-176x144
-@item cif
-352x288
-@item 4cif
-704x576
-@item 16cif
-1408x1152
-@item qqvga
-160x120
-@item qvga
-320x240
-@item vga
-640x480
-@item svga
-800x600
-@item xga
-1024x768
-@item uxga
-1600x1200
-@item qxga
-2048x1536
-@item sxga
-1280x1024
-@item qsxga
-2560x2048
-@item hsxga
-5120x4096
-@item wvga
-852x480
-@item wxga
-1366x768
-@item wsxga
-1600x1024
-@item wuxga
-1920x1200
-@item woxga
-2560x1600
-@item wqsxga
-3200x2048
-@item wquxga
-3840x2400
-@item whsxga
-6400x4096
-@item whuxga
-7680x4800
-@item cga
-320x200
-@item ega
-640x350
-@item hd480
-852x480
-@item hd720
-1280x720
-@item hd1080
-1920x1080
-@end table
-
-@item -aspect[:@var{stream_specifier}] @var{aspect} (@emph{output,per-stream})
-Set the video display aspect ratio specified by @var{aspect}.
-
-@var{aspect} can be a floating point number string, or a string of the
-form @var{num}:@var{den}, where @var{num} and @var{den} are the
-numerator and denominator of the aspect ratio. For example "4:3",
-"16:9", "1.3333", and "1.7777" are valid argument values.
-
-@item -vn (@emph{output})
-Disable video recording.
-
-@item -vcodec @var{codec} (@emph{output})
-Set the video codec. This is an alias for @code{-codec:v}.
-
-@item -pass[:@var{stream_specifier}] @var{n} (@emph{output,per-stream})
-Select the pass number (1 or 2). It is used to do two-pass
-video encoding. The statistics of the video are recorded in the first
-pass into a log file (see also the option -passlogfile),
-and in the second pass that log file is used to generate the video
-at the exact requested bitrate.
-On pass 1, you may just deactivate audio and set output to null,
-examples for Windows and Unix:
-@example
-avconv -i foo.mov -c:v libxvid -pass 1 -an -f rawvideo -y NUL
-avconv -i foo.mov -c:v libxvid -pass 1 -an -f rawvideo -y /dev/null
-@end example
-
-@item -passlogfile[:@var{stream_specifier}] @var{prefix} (@emph{output,per-stream})
-Set two-pass log file name prefix to @var{prefix}, the default file name
-prefix is ``av2pass''. The complete file name will be
-@file{PREFIX-N.log}, where N is a number specific to the output
-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}.
-
-@end table
-
-@section Advanced Video Options
-
-@table @option
-@item -pix_fmt[:@var{stream_specifier}] @var{format} (@emph{input/output,per-stream})
-Set pixel format. Use @code{-pix_fmts} to show all the supported
-pixel formats.
-@item -sws_flags @var{flags} (@emph{input/output})
-Set SwScaler flags.
-@item -vdt @var{n}
-Discard threshold.
-
-@item -rc_override[:@var{stream_specifier}] @var{override} (@emph{output,per-stream})
-rate control override for specific intervals
-
-@item -deinterlace
-Deinterlace pictures.
-This option is deprecated since the deinterlacing is very low quality.
-Use the yadif filter with @code{-filter:v yadif}.
-@item -vstats
-Dump video coding statistics to @file{vstats_HHMMSS.log}.
-@item -vstats_file @var{file}
-Dump video coding statistics to @var{file}.
-@item -top[:@var{stream_specifier}] @var{n} (@emph{output,per-stream})
-top=1/bottom=0/auto=-1 field first
-@item -dc @var{precision}
-Intra_dc_precision.
-@item -vtag @var{fourcc/tag} (@emph{output})
-Force video tag/fourcc. This is an alias for @code{-tag:v}.
-@item -qphist (@emph{global})
-Show QP histogram.
-@item -force_key_frames[:@var{stream_specifier}] @var{time}[,@var{time}...] (@emph{output,per-stream})
-Force key frames at the specified timestamps, more precisely at the first
-frames after each specified time.
-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.
-
-@item -copyinkf[:@var{stream_specifier}] (@emph{output,per-stream})
-When doing stream copy, copy also non-key frames found at the
-beginning.
-@end table
-
-@section Audio Options
-
-@table @option
-@item -aframes @var{number} (@emph{output})
-Set the number of audio frames to record. This is an alias for @code{-frames:a}.
-@item -ar[:@var{stream_specifier}] @var{freq} (@emph{input/output,per-stream})
-Set the audio sampling frequency. For output streams it is set by
-default to the frequency of the corresponding input stream. For input
-streams this option only makes sense for audio grabbing devices and raw
-demuxers and is mapped to the corresponding demuxer options.
-@item -aq @var{q} (@emph{output})
-Set the audio quality (codec-specific, VBR). This is an alias for -q:a.
-@item -ac[:@var{stream_specifier}] @var{channels} (@emph{input/output,per-stream})
-Set the number of audio channels. For output streams it is set by
-default to the number of input audio channels. For input streams
-this option only makes sense for audio grabbing devices and raw demuxers
-and is mapped to the corresponding demuxer options.
-@item -an (@emph{output})
-Disable audio recording.
-@item -acodec @var{codec} (@emph{input/output})
-Set the audio codec. This is an alias for @code{-codec:a}.
-@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}.
-@end table
-
-@section Advanced Audio options:
-
-@table @option
-@item -atag @var{fourcc/tag} (@emph{output})
-Force audio tag/fourcc. This is an alias for @code{-tag:a}.
-@end table
-
-@section Subtitle options:
-
-@table @option
-@item -scodec @var{codec} (@emph{input/output})
-Set the subtitle codec. This is an alias for @code{-codec:s}.
-@item -sn (@emph{output})
-Disable subtitle recording.
-@end table
-
-@section Advanced options
-
-@table @option
-@item -map [-]@var{input_file_id}[:@var{stream_specifier}][,@var{sync_file_id}[:@var{stream_specifier}]] | @var{[linklabel]} (@emph{output})
-
-Designate one or more input streams as a source for the output file. Each input
-stream is identified by the input file index @var{input_file_id} and
-the input stream index @var{input_stream_id} within the input
-file. Both indices start at 0. If specified,
-@var{sync_file_id}:@var{stream_specifier} sets which input stream
-is used as a presentation sync reference.
-
-The first @code{-map} option on the command line specifies the
-source for output stream 0, the second @code{-map} option specifies
-the source for output stream 1, etc.
-
-A @code{-} character before the stream identifier creates a "negative" mapping.
-It disables matching streams from already created mappings.
-
-An alternative @var{[linklabel]} form will map outputs from complex filter
-graphs (see the @option{-filter_complex} option) to the output file.
-@var{linklabel} must correspond to a defined output link label in the graph.
-
-For example, to map ALL streams from the first input file to output
-@example
-avconv -i INPUT -map 0 output
-@end example
-
-For example, if you have two audio streams in the first input file,
-these streams are identified by "0:0" and "0:1". You can use
-@code{-map} to select which streams to place in an output file. For
-example:
-@example
-avconv -i INPUT -map 0:1 out.wav
-@end example
-will map the input stream in @file{INPUT} identified by "0:1" to
-the (single) output stream in @file{out.wav}.
-
-For example, to select the stream with index 2 from input file
-@file{a.mov} (specified by the identifier "0:2"), and stream with
-index 6 from input @file{b.mov} (specified by the identifier "1:6"),
-and copy them to the output file @file{out.mov}:
-@example
-avconv -i a.mov -i b.mov -c copy -map 0:2 -map 1:6 out.mov
-@end example
-
-To select all video and the third audio stream from an input file:
-@example
-avconv -i INPUT -map 0:v -map 0:a:2 OUTPUT
-@end example
-
-To map all the streams except the second audio, use negative mappings
-@example
-avconv -i INPUT -map 0 -map -0:a:1 OUTPUT
-@end example
-
-Note that using this option disables the default mappings for this output file.
-
-@item -map_metadata[:@var{metadata_spec_out}] @var{infile}[:@var{metadata_spec_in}] (@emph{output,per-metadata})
-Set metadata information of the next output file from @var{infile}. Note that
-those are file indices (zero-based), not filenames.
-Optional @var{metadata_spec_in/out} parameters specify, which metadata to copy.
-A metadata specifier can have the following forms:
-@table @option
-@item @var{g}
-global metadata, i.e. metadata that applies to the whole file
-
-@item @var{s}[:@var{stream_spec}]
-per-stream metadata. @var{stream_spec} is a stream specifier as described
-in the @ref{Stream specifiers} chapter. In an input metadata specifier, the first
-matching stream is copied from. In an output metadata specifier, all matching
-streams are copied to.
-
-@item @var{c}:@var{chapter_index}
-per-chapter metadata. @var{chapter_index} is the zero-based chapter index.
-
-@item @var{p}:@var{program_index}
-per-program metadata. @var{program_index} is the zero-based program index.
-@end table
-If metadata specifier is omitted, it defaults to global.
-
-By default, global metadata is copied from the first input file,
-per-stream and per-chapter metadata is copied along with streams/chapters. These
-default mappings are disabled by creating any mapping of the relevant type. A negative
-file index can be used to create a dummy mapping that just disables automatic copying.
-
-For example to copy metadata from the first stream of the input file to global metadata
-of the output file:
-@example
-avconv -i in.ogg -map_metadata 0:s:0 out.mp3
-@end example
-
-To do the reverse, i.e. copy global metadata to all audio streams:
-@example
-avconv -i in.mkv -map_metadata:s:a 0:g out.mkv
-@end example
-Note that simple @code{0} would work as well in this example, since global
-metadata is assumed by default.
-
-@item -map_chapters @var{input_file_index} (@emph{output})
-Copy chapters from input file with index @var{input_file_index} to the next
-output file. If no chapter mapping is specified, then chapters are copied from
-the first input file with at least one chapter. Use a negative file index to
-disable any chapter copying.
-@item -debug
-Print specific debug info.
-@item -benchmark (@emph{global})
-Show benchmarking information at the end of an encode.
-Shows CPU time used and maximum memory consumption.
-Maximum memory consumption is not supported on all systems,
-it will usually display as 0 if not supported.
-@item -timelimit @var{duration} (@emph{global})
-Exit after avconv has been running for @var{duration} seconds.
-@item -dump (@emph{global})
-Dump each input packet to stderr.
-@item -hex (@emph{global})
-When dumping packets, also dump the payload.
-@item -re (@emph{input})
-Read input at native frame rate. Mainly used to simulate a grab device.
-@item -vsync @var{parameter}
-Video sync method.
-
-@table @option
-@item passthrough
-Each frame is passed with its timestamp from the demuxer to the muxer.
-@item cfr
-Frames will be duplicated and dropped to achieve exactly the requested
-constant framerate.
-@item vfr
-Frames are passed through with their timestamp or dropped so as to
-prevent 2 frames from having the same timestamp.
-@item auto
-Chooses between 1 and 2 depending on muxer capabilities. This is the
-default method.
-@end table
-
-With -map you can select from which stream the timestamps should be
-taken. You can leave either video or audio unchanged and sync the
-remaining stream(s) to the unchanged one.
-
-@item -async @var{samples_per_second}
-Audio sync method. "Stretches/squeezes" the audio stream to match the timestamps,
-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.
-@item -copyts
-Copy timestamps from input to output.
-@item -copytb
-Copy input stream time base from input to output when stream copying.
-@item -shortest (@emph{output})
-Finish encoding when the shortest input stream ends.
-@item -dts_delta_threshold
-Timestamp discontinuity delta threshold.
-@item -muxdelay @var{seconds} (@emph{input})
-Set the maximum demux-decode delay.
-@item -muxpreload @var{seconds} (@emph{input})
-Set the initial demux-decode delay.
-@item -streamid @var{output-stream-index}:@var{new-value} (@emph{output})
-Assign a new stream-id value to an output stream. This option should be
-specified prior to the output filename to which it applies.
-For the situation where multiple output files exist, a streamid
-may be reassigned to a different value.
-
-For example, to set the stream 0 PID to 33 and the stream 1 PID to 36 for
-an output mpegts file:
-@example
-avconv -i infile -streamid 0:33 -streamid 1:36 out.ts
-@end example
-
-@item -bsf[:@var{stream_specifier}] @var{bitstream_filters} (@emph{output,per-stream})
-Set bitstream filters for matching streams. @var{bistream_filters} is
-a comma-separated list of bitstream filters. Use the @code{-bsfs} option
-to get the list of bitstream filters.
-@example
-avconv -i h264.mp4 -c:v copy -bsf:v h264_mp4toannexb -an out.h264
-@end example
-@example
-avconv -i file.mov -an -vn -bsf:s mov2textsub -c:s copy -f rawvideo sub.txt
-@end example
-
-@item -tag[:@var{stream_specifier}] @var{codec_tag} (@emph{output,per-stream})
-Force a tag/fourcc for matching streams.
-
-@item -cpuflags mask (@emph{global})
-Set a mask that's applied to autodetected CPU flags.  This option is intended
-for testing. Do not use it unless you know what you're doing.
-
-@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}.
-
-Input link labels must refer to input streams using the
-@code{[file_index:stream_specifier]} syntax (i.e. the same as @option{-map}
-uses). If @var{stream_specifier} matches multiple streams, the first one will be
-used. An unlabeled input will be connected to the first unused input stream of
-the matching type.
-
-Output link labels are referred to with @option{-map}. Unlabeled outputs are
-added to the first output file.
-
-Note that with this option it is possible to use only lavfi sources without
-normal input files.
-
-For example, to overlay an image over video
-@example
-avconv -i video.mkv -i image.png -filter_complex '[0:v][1:v]overlay[out]' -map
-'[out]' out.mkv
-@end example
-Here @code{[0:v]} refers to the first video stream in the first input file,
-which is linked to the first (main) input of the overlay filter. Similarly the
-first video stream in the second input is linked to the second (overlay) input
-of overlay.
-
-Assuming there is only one video stream in each input file, we can omit input
-labels, so the above is equivalent to
-@example
-avconv -i video.mkv -i image.png -filter_complex 'overlay[out]' -map
-'[out]' out.mkv
-@end example
-
-Furthermore we can omit the output label and the single output from the filter
-graph will be added to the output file automatically, so we can simply write
-@example
-avconv -i video.mkv -i image.png -filter_complex 'overlay' out.mkv
-@end example
-
-To generate 5 seconds of pure red video using lavfi @code{color} source:
-@example
-avconv -filter_complex 'color=red' -t 5 out.mkv
-@end example
-@end table
-@c man end OPTIONS
-
-@chapter Tips
-@c man begin TIPS
-
-@itemize
-@item
-For streaming at very low bitrate application, use a low frame rate
-and a small GOP size. This is especially true for RealVideo where
-the Linux player does not seem to be very fast, so it can miss
-frames. An example is:
-
-@example
-avconv -g 3 -r 3 -t 10 -b 50k -s qcif -f rv10 /tmp/b.rm
-@end example
-
-@item
-The parameter 'q' which is displayed while encoding is the current
-quantizer. The value 1 indicates that a very good quality could
-be achieved. The value 31 indicates the worst quality. If q=31 appears
-too often, it means that the encoder cannot compress enough to meet
-your bitrate. You must either increase the bitrate, decrease the
-frame rate or decrease the frame size.
-
-@item
-If your computer is not fast enough, you can speed up the
-compression at the expense of the compression ratio. You can use
-'-me zero' to speed up motion estimation, and '-g 0' to disable
-motion estimation completely (you have only I-frames, which means it
-is about as good as JPEG compression).
-
-@item
-To have very low audio bitrates, reduce the sampling frequency
-(down to 22050 Hz for MPEG audio, 22050 or 11025 for AC-3).
-
-@item
-To have a constant quality (but a variable bitrate), use the option
-'-qscale n' when 'n' is between 1 (excellent quality) and 31 (worst
-quality).
-
-@end itemize
-@c man end TIPS
-
-@chapter Examples
-@c man begin EXAMPLES
-
-@section Preset files
-
-A preset file contains a sequence of @var{option=value} pairs, one for
-each line, specifying a sequence of options which can be specified also on
-the command line. Lines starting with the hash ('#') character are ignored and
-are used to provide comments. Empty lines are also ignored. Check the
-@file{presets} directory in the Libav source tree for examples.
-
-Preset files are specified with the @code{pre} option, this option takes a
-preset name as input.  Avconv searches for a file named @var{preset_name}.avpreset in
-the directories @file{$AVCONV_DATADIR} (if set), and @file{$HOME/.avconv}, and in
-the data directory defined at configuration time (usually @file{$PREFIX/share/avconv})
-in that order.  For example, if the argument is @code{libx264-max}, it will
-search for the file @file{libx264-max.avpreset}.
-
-@section Video and Audio grabbing
-
-If you specify the input format and device then avconv can grab video
-and audio directly.
-
-@example
-avconv -f oss -i /dev/dsp -f video4linux2 -i /dev/video0 /tmp/out.mpg
-@end example
-
-Note that you must activate the right video source and channel before
-launching avconv with any TV viewer such as
-@uref{http://linux.bytesex.org/xawtv/, xawtv} by Gerd Knorr. You also
-have to set the audio recording levels correctly with a
-standard mixer.
-
-@section X11 grabbing
-
-Grab the X11 display with avconv via
-
-@example
-avconv -f x11grab -s cif -r 25 -i :0.0 /tmp/out.mpg
-@end example
-
-0.0 is display.screen number of your X11 server, same as
-the DISPLAY environment variable.
-
-@example
-avconv -f x11grab -s cif -r 25 -i :0.0+10,20 /tmp/out.mpg
-@end example
-
-0.0 is display.screen number of your X11 server, same as the DISPLAY environment
-variable. 10 is the x-offset and 20 the y-offset for the grabbing.
-
-@section Video and Audio file format conversion
-
-Any supported file format and protocol can serve as input to avconv:
-
-Examples:
-@itemize
-@item
-You can use YUV files as input:
-
-@example
-avconv -i /tmp/test%d.Y /tmp/out.mpg
-@end example
-
-It will use the files:
-@example
-/tmp/test0.Y, /tmp/test0.U, /tmp/test0.V,
-/tmp/test1.Y, /tmp/test1.U, /tmp/test1.V, etc...
-@end example
-
-The Y files use twice the resolution of the U and V files. They are
-raw files, without header. They can be generated by all decent video
-decoders. You must specify the size of the image with the @option{-s} option
-if avconv cannot guess it.
-
-@item
-You can input from a raw YUV420P file:
-
-@example
-avconv -i /tmp/test.yuv /tmp/out.avi
-@end example
-
-test.yuv is a file containing raw YUV planar data. Each frame is composed
-of the Y plane followed by the U and V planes at half vertical and
-horizontal resolution.
-
-@item
-You can output to a raw YUV420P file:
-
-@example
-avconv -i mydivx.avi hugefile.yuv
-@end example
-
-@item
-You can set several input files and output files:
-
-@example
-avconv -i /tmp/a.wav -s 640x480 -i /tmp/a.yuv /tmp/a.mpg
-@end example
-
-Converts the audio file a.wav and the raw YUV video file a.yuv
-to MPEG file a.mpg.
-
-@item
-You can also do audio and video conversions at the same time:
-
-@example
-avconv -i /tmp/a.wav -ar 22050 /tmp/a.mp2
-@end example
-
-Converts a.wav to MPEG audio at 22050 Hz sample rate.
-
-@item
-You can encode to several formats at the same time and define a
-mapping from input stream to output streams:
-
-@example
-avconv -i /tmp/a.wav -map 0:a -b 64k /tmp/a.mp2 -map 0:a -b 128k /tmp/b.mp2
-@end example
-
-Converts a.wav to a.mp2 at 64 kbits and to b.mp2 at 128 kbits. '-map
-file:index' specifies which input stream is used for each output
-stream, in the order of the definition of output streams.
-
-@item
-You can transcode decrypted VOBs:
-
-@example
-avconv -i snatch_1.vob -f avi -c:v mpeg4 -b:v 800k -g 300 -bf 2 -c:a libmp3lame -b:a 128k snatch.avi
-@end example
-
-This is a typical DVD ripping example; the input is a VOB file, the
-output an AVI file with MPEG-4 video and MP3 audio. Note that in this
-command we use B-frames so the MPEG-4 stream is DivX5 compatible, and
-GOP size is 300 which means one intra frame every 10 seconds for 29.97fps
-input video. Furthermore, the audio stream is MP3-encoded so you need
-to enable LAME support by passing @code{--enable-libmp3lame} to configure.
-The mapping is particularly useful for DVD transcoding
-to get the desired audio language.
-
-NOTE: To see the supported input formats, use @code{avconv -formats}.
-
-@item
-You can extract images from a video, or create a video from many images:
-
-For extracting images from a video:
-@example
-avconv -i foo.avi -r 1 -s WxH -f image2 foo-%03d.jpeg
-@end example
-
-This will extract one video frame per second from the video and will
-output them in files named @file{foo-001.jpeg}, @file{foo-002.jpeg},
-etc. Images will be rescaled to fit the new WxH values.
-
-If you want to extract just a limited number of frames, you can use the
-above command in combination with the -vframes or -t option, or in
-combination with -ss to start extracting from a certain point in time.
-
-For creating a video from many images:
-@example
-avconv -f image2 -i foo-%03d.jpeg -r 12 -s WxH foo.avi
-@end example
-
-The syntax @code{foo-%03d.jpeg} specifies to use a decimal number
-composed of three digits padded with zeroes to express the sequence
-number. It is the same syntax supported by the C printf function, but
-only formats accepting a normal integer are suitable.
-
-@item
-You can put many streams of the same type in the output:
-
-@example
-avconv -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
-the input file in reverse order.
-
-@item
-To force CBR video output:
-@example
-avconv -i myfile.avi -b 4000k -minrate 4000k -maxrate 4000k -bufsize 1835k out.m2v
-@end example
-
-@item
-The four options lmin, lmax, mblmin and mblmax use 'lambda' units,
-but you may use the QP2LAMBDA constant to easily convert from 'q' units:
-@example
-avconv -i src.ext -lmax 21*QP2LAMBDA dst.ext
-@end example
-
-@end itemize
-@c man end EXAMPLES
-
-@include eval.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
-
-@ignore
-
-@setfilename avconv
-@settitle avconv video converter
-
-@c man begin SEEALSO
-avplay(1), avprobe(1) and the Libav HTML documentation
-@c man end
-
-@c man begin AUTHORS
-The Libav developers
-@c man end
-
-@end ignore
-
-@bye
diff --git a/doc/avplay.texi b/doc/avplay.texi
deleted file mode 100644
index 8fc3308..0000000
--- a/doc/avplay.texi
+++ /dev/null
@@ -1,184 +0,0 @@
-\input texinfo @c -*- texinfo -*-
-
-@settitle avplay Documentation
-@titlepage
-@center @titlefont{avplay Documentation}
-@end titlepage
-
-@top
-
-@contents
-
-@chapter Synopsis
-
-@example
-@c man begin SYNOPSIS
-avplay [options] @file{input_file}
-@c man end
-@end example
-
-@chapter Description
-@c man begin DESCRIPTION
-
-AVplay is a very simple and portable media player using the Libav
-libraries and the SDL library. It is mostly used as a testbed for the
-various Libav APIs.
-@c man end
-
-@chapter Options
-@c man begin OPTIONS
-
-@include avtools-common-opts.texi
-
-@section Main options
-
-@table @option
-@item -x @var{width}
-Force displayed width.
-@item -y @var{height}
-Force displayed height.
-@item -s @var{size}
-This option has been removed. Use private format options for specifying the
-input video size.  For example with the rawvideo demuxer you need to specify the
-option @var{video_size}.
-@item -an
-Disable audio.
-@item -vn
-Disable video.
-@item -ss @var{pos}
-Seek to a given position in seconds.
-@item -t @var{duration}
-play <duration> seconds of audio/video
-@item -bytes
-Seek by bytes.
-@item -nodisp
-Disable graphical display.
-@item -f @var{fmt}
-Force format.
-@item -window_title @var{title}
-Set window title (default is the input filename).
-@item -loop @var{number}
-Loops movie playback <number> times. 0 means forever.
-@item -vf @var{filter_graph}
-@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).
-
-@end table
-
-@section Advanced options
-@table @option
-@item -pix_fmt @var{format}
-This option has been removed. Use private options for specifying the
-input pixel format. For example with the rawvideo demuxer you need to specify
-the option @var{pixel_format}.
-@item -stats
-Show the stream duration, the codec parameters, the current position in
-the stream and the audio/video synchronisation drift.
-@item -debug
-Print specific debug info.
-@item -bug
-Work around bugs.
-@item -vismv
-Visualize motion vectors.
-@item -fast
-Non-spec-compliant optimizations.
-@item -genpts
-Generate pts.
-@item -rtp_tcp
-Force RTP/TCP protocol usage instead of RTP/UDP. It is only meaningful
-if you are streaming with the RTSP protocol.
-@item -sync @var{type}
-Set the master clock to audio (@code{type=audio}), video
-(@code{type=video}) or external (@code{type=ext}). Default is audio. The
-master clock is used to control audio-video synchronization. Most media
-players use audio as master clock, but in some cases (streaming or high
-quality broadcast) it is necessary to change that. This option is mainly
-used for debugging purposes.
-@item -threads @var{count}
-Set the thread count.
-@item -ast @var{audio_stream_number}
-Select the desired audio stream number, counting from 0. The number
-refers to the list of all the input audio streams. If it is greater
-than the number of audio streams minus one, then the last one is
-selected, if it is negative the audio playback is disabled.
-@item -vst @var{video_stream_number}
-Select the desired video stream number, counting from 0. The number
-refers to the list of all the input video streams. If it is greater
-than the number of video streams minus one, then the last one is
-selected, if it is negative the video playback is disabled.
-@item -sst @var{subtitle_stream_number}
-Select the desired subtitle stream number, counting from 0. The number
-refers to the list of all the input subtitle streams. If it is greater
-than the number of subtitle streams minus one, then the last one is
-selected, if it is negative the subtitle rendering is disabled.
-@item -autoexit
-Exit when video is done playing.
-@item -exitonkeydown
-Exit if any key is pressed.
-@item -exitonmousedown
-Exit if any mouse button is pressed.
-@end table
-
-@section While playing
-
-@table @key
-@item q, ESC
-Quit.
-
-@item f
-Toggle full screen.
-
-@item p, SPC
-Pause.
-
-@item a
-Cycle audio channel.
-
-@item v
-Cycle video channel.
-
-@item t
-Cycle subtitle channel.
-
-@item w
-Show audio waves.
-
-@item left/right
-Seek backward/forward 10 seconds.
-
-@item down/up
-Seek backward/forward 1 minute.
-
-@item mouse click
-Seek to percentage in file corresponding to fraction of width.
-
-@end table
-
-@c man end
-
-@include eval.texi
-@include demuxers.texi
-@include muxers.texi
-@include indevs.texi
-@include outdevs.texi
-@include protocols.texi
-@include filters.texi
-
-@ignore
-
-@setfilename avplay
-@settitle AVplay media player
-
-@c man begin SEEALSO
-avconv(1), avprobe(1) and the Libav HTML documentation
-@c man end
-
-@c man begin AUTHORS
-The Libav developers
-@c man end
-
-@end ignore
-
-@bye
diff --git a/doc/avprobe.texi b/doc/avprobe.texi
deleted file mode 100644
index 7e6fedf..0000000
--- a/doc/avprobe.texi
+++ /dev/null
@@ -1,141 +0,0 @@
-\input texinfo @c -*- texinfo -*-
-
-@settitle avprobe Documentation
-@titlepage
-@center @titlefont{avprobe Documentation}
-@end titlepage
-
-@top
-
-@contents
-
-@chapter Synopsis
-
-The generic syntax is:
-
-@example
-@c man begin SYNOPSIS
-avprobe [options] [@file{input_file}]
-@c man end
-@end example
-
-@chapter Description
-@c man begin DESCRIPTION
-
-avprobe gathers information from multimedia streams and prints it in
-human- and machine-readable fashion.
-
-For example it can be used to check the format of the container used
-by a multimedia stream and the format and type of each media stream
-contained in it.
-
-If a filename is specified in input, avprobe will try to open and
-probe the file content. If the file cannot be opened or recognized as
-a multimedia file, a positive exit code is returned.
-
-avprobe may be employed both as a standalone application or in
-combination with a textual filter, which may perform more
-sophisticated processing, e.g. statistical processing or plotting.
-
-Options are used to list some of the formats supported by avprobe or
-for specifying which information to display, and for setting how
-avprobe will show it.
-
-avprobe output is designed to be easily parsable by any INI or JSON
-parsers.
-
-@c man end
-
-@chapter Options
-@c man begin OPTIONS
-
-@include avtools-common-opts.texi
-
-@section Main options
-
-@table @option
-
-@item -f @var{format}
-Force format to use.
-
-@item -of @var{formatter}
-Use a specific formatter to output the document. The following
-formatters are available
-@table @option
-@item ini
-
-@item json
-
-@item old
-Pseudo-INI format that used to be the only one available in old
-avprobe versions.
-@end table
-
-@item -unit
-Show the unit of the displayed values.
-
-@item -prefix
-Use SI prefixes for the displayed values.
-Unless the "-byte_binary_prefix" option is used all the prefixes
-are decimal.
-
-@item -byte_binary_prefix
-Force the use of binary prefixes for byte values.
-
-@item -sexagesimal
-Use sexagesimal format HH:MM:SS.MICROSECONDS for time values.
-
-@item -pretty
-Prettify the format of the displayed values, it corresponds to the
-options "-unit -prefix -byte_binary_prefix -sexagesimal".
-
-@item -show_format
-Show information about the container format of the input multimedia
-stream.
-
-All the container format information is printed within a section with
-name "FORMAT".
-
-@item -show_format_entry @var{name}
-Like @option{-show_format}, but only prints the specified entry of the
-container format information, rather than all. This option may be given more
-than once, then all specified entries will be shown.
-
-@item -show_packets
-Show information about each packet contained in the input multimedia
-stream.
-
-The information for each single packet is printed within a dedicated
-section with name "PACKET".
-
-@item -show_streams
-Show information about each media stream contained in the input
-multimedia stream.
-
-Each media stream information is printed within a dedicated section
-with name "STREAM".
-
-@end table
-@c man end
-
-@include demuxers.texi
-@include muxers.texi
-@include protocols.texi
-@include indevs.texi
-
-@ignore
-
-@setfilename avprobe
-@settitle avprobe media prober
-
-@c man begin SEEALSO
-avconv(1), avplay(1) and the Libav HTML documentation
-@c man end
-
-@c man begin AUTHORS
-The Libav developers
-@c man end
-
-@end ignore
-
-@bye
diff --git a/doc/avserver.conf b/doc/avserver.conf
deleted file mode 100644
index e9724bb..0000000
--- a/doc/avserver.conf
+++ /dev/null
@@ -1,375 +0,0 @@
-# Port on which the server is listening. You must select a different
-# port from your standard HTTP web server if it is running on the same
-# computer.
-Port 8090
-
-# Address on which the server is bound. Only useful if you have
-# several network interfaces.
-BindAddress 0.0.0.0
-
-# Number of simultaneous HTTP connections that can be handled. It has
-# to be defined *before* the MaxClients parameter, since it defines the
-# MaxClients maximum limit.
-MaxHTTPConnections 2000
-
-# Number of simultaneous requests that can be handled. Since AVServer
-# is very fast, it is more likely that you will want to leave this high
-# and use MaxBandwidth, below.
-MaxClients 1000
-
-# This the maximum amount of kbit/sec that you are prepared to
-# consume when streaming to clients.
-MaxBandwidth 1000
-
-# Access log file (uses standard Apache log file format)
-# '-' is the standard output.
-CustomLog -
-
-# Suppress that if you want to launch avserver as a daemon.
-NoDaemon
-
-
-##################################################################
-# Definition of the live feeds. Each live feed contains one video
-# and/or audio sequence coming from an avconv encoder or another
-# avserver. This sequence may be encoded simultaneously with several
-# codecs at several resolutions.
-
-<Feed feed1.ffm>
-
-# You must use 'avconv' to send a live feed to avserver. In this
-# example, you can type:
-#
-# avconv http://localhost:8090/feed1.ffm
-
-# avserver can also do time shifting. It means that it can stream any
-# previously recorded live stream. The request should contain:
-# "http://xxxx?date=[YYYY-MM-DDT][[HH:]MM:]SS[.m...]".You must specify
-# a path where the feed is stored on disk. You also specify the
-# maximum size of the feed, where zero means unlimited. Default:
-# File=/tmp/feed_name.ffm FileMaxSize=5M
-File /tmp/feed1.ffm
-FileMaxSize 200K
-
-# You could specify
-# ReadOnlyFile /saved/specialvideo.ffm
-# This marks the file as readonly and it will not be deleted or updated.
-
-# Specify launch in order to start avconv automatically.
-# First avconv must be defined with an appropriate path if needed,
-# after that options can follow, but avoid adding the http:// field
-#Launch avconv
-
-# Only allow connections from localhost to the feed.
-ACL allow 127.0.0.1
-
-</Feed>
-
-
-##################################################################
-# Now you can define each stream which will be generated from the
-# original audio and video stream. Each format has a filename (here
-# 'test1.mpg'). AVServer will send this stream when answering a
-# request containing this filename.
-
-<Stream test1.mpg>
-
-# coming from live feed 'feed1'
-Feed feed1.ffm
-
-# Format of the stream : you can choose among:
-# mpeg       : MPEG-1 multiplexed video and audio
-# mpegvideo  : only MPEG-1 video
-# mp2        : MPEG-2 audio (use AudioCodec to select layer 2 and 3 codec)
-# ogg        : Ogg format (Vorbis audio codec)
-# rm         : RealNetworks-compatible stream. Multiplexed audio and video.
-# ra         : RealNetworks-compatible stream. Audio only.
-# mpjpeg     : Multipart JPEG (works with Netscape without any plugin)
-# jpeg       : Generate a single JPEG image.
-# asf        : ASF compatible streaming (Windows Media Player format).
-# swf        : Macromedia Flash compatible stream
-# avi        : AVI format (MPEG-4 video, MPEG audio sound)
-Format mpeg
-
-# Bitrate for the audio stream. Codecs usually support only a few
-# different bitrates.
-AudioBitRate 32
-
-# Number of audio channels: 1 = mono, 2 = stereo
-AudioChannels 1
-
-# Sampling frequency for audio. When using low bitrates, you should
-# lower this frequency to 22050 or 11025. The supported frequencies
-# depend on the selected audio codec.
-AudioSampleRate 44100
-
-# Bitrate for the video stream
-VideoBitRate 64
-
-# Ratecontrol buffer size
-VideoBufferSize 40
-
-# Number of frames per second
-VideoFrameRate 3
-
-# Size of the video frame: WxH (default: 160x128)
-# The following abbreviations are defined: sqcif, qcif, cif, 4cif, qqvga,
-# qvga, vga, svga, xga, uxga, qxga, sxga, qsxga, hsxga, wvga, wxga, wsxga,
-# wuxga, woxga, wqsxga, wquxga, whsxga, whuxga, cga, ega, hd480, hd720,
-# hd1080
-VideoSize 160x128
-
-# Transmit only intra frames (useful for low bitrates, but kills frame rate).
-#VideoIntraOnly
-
-# If non-intra only, an intra frame is transmitted every VideoGopSize
-# frames. Video synchronization can only begin at an intra frame.
-VideoGopSize 12
-
-# More MPEG-4 parameters
-# VideoHighQuality
-# Video4MotionVector
-
-# Choose your codecs:
-#AudioCodec mp2
-#VideoCodec mpeg1video
-
-# Suppress audio
-#NoAudio
-
-# Suppress video
-#NoVideo
-
-#VideoQMin 3
-#VideoQMax 31
-
-# Set this to the number of seconds backwards in time to start. Note that
-# most players will buffer 5-10 seconds of video, and also you need to allow
-# for a keyframe to appear in the data stream.
-#Preroll 15
-
-# ACL:
-
-# You can allow ranges of addresses (or single addresses)
-#ACL ALLOW <first address> <last address>
-
-# You can deny ranges of addresses (or single addresses)
-#ACL DENY <first address> <last address>
-
-# You can repeat the ACL allow/deny as often as you like. It is on a per
-# stream basis. The first match defines the action. If there are no matches,
-# then the default is the inverse of the last ACL statement.
-#
-# Thus 'ACL allow localhost' only allows access from localhost.
-# 'ACL deny 1.0.0.0 1.255.255.255' would deny the whole of network 1 and
-# allow everybody else.
-
-</Stream>
-
-
-##################################################################
-# Example streams
-
-
-# Multipart JPEG
-
-#<Stream test.mjpg>
-#Feed feed1.ffm
-#Format mpjpeg
-#VideoFrameRate 2
-#VideoIntraOnly
-#NoAudio
-#Strict -1
-#</Stream>
-
-
-# Single JPEG
-
-#<Stream test.jpg>
-#Feed feed1.ffm
-#Format jpeg
-#VideoFrameRate 2
-#VideoIntraOnly
-##VideoSize 352x240
-#NoAudio
-#Strict -1
-#</Stream>
-
-
-# Flash
-
-#<Stream test.swf>
-#Feed feed1.ffm
-#Format swf
-#VideoFrameRate 2
-#VideoIntraOnly
-#NoAudio
-#</Stream>
-
-
-# ASF compatible
-
-<Stream test.asf>
-Feed feed1.ffm
-Format asf
-VideoFrameRate 15
-VideoSize 352x240
-VideoBitRate 256
-VideoBufferSize 40
-VideoGopSize 30
-AudioBitRate 64
-StartSendOnKey
-</Stream>
-
-
-# MP3 audio
-
-#<Stream test.mp3>
-#Feed feed1.ffm
-#Format mp2
-#AudioCodec mp3
-#AudioBitRate 64
-#AudioChannels 1
-#AudioSampleRate 44100
-#NoVideo
-#</Stream>
-
-
-# Ogg Vorbis audio
-
-#<Stream test.ogg>
-#Feed feed1.ffm
-#Title "Stream title"
-#AudioBitRate 64
-#AudioChannels 2
-#AudioSampleRate 44100
-#NoVideo
-#</Stream>
-
-
-# Real with audio only at 32 kbits
-
-#<Stream test.ra>
-#Feed feed1.ffm
-#Format rm
-#AudioBitRate 32
-#NoVideo
-#NoAudio
-#</Stream>
-
-
-# Real with audio and video at 64 kbits
-
-#<Stream test.rm>
-#Feed feed1.ffm
-#Format rm
-#AudioBitRate 32
-#VideoBitRate 128
-#VideoFrameRate 25
-#VideoGopSize 25
-#NoAudio
-#</Stream>
-
-
-##################################################################
-# A stream coming from a file: you only need to set the input
-# filename and optionally a new format. Supported conversions:
-#    AVI -> ASF
-
-#<Stream file.rm>
-#File "/usr/local/httpd/htdocs/tlive.rm"
-#NoAudio
-#</Stream>
-
-#<Stream file.asf>
-#File "/usr/local/httpd/htdocs/test.asf"
-#NoAudio
-#Author "Me"
-#Copyright "Super MegaCorp"
-#Title "Test stream from disk"
-#Comment "Test comment"
-#</Stream>
-
-
-##################################################################
-# RTSP examples
-#
-# You can access this stream with the RTSP URL:
-#   rtsp://localhost:5454/test1-rtsp.mpg
-#
-# A non-standard RTSP redirector is also created. Its URL is:
-#   http://localhost:8090/test1-rtsp.rtsp
-
-#<Stream test1-rtsp.mpg>
-#Format rtp
-#File "/usr/local/httpd/htdocs/test1.mpg"
-#</Stream>
-
-
-# Transcode an incoming live feed to another live feed,
-# using libx264 and video presets
-
-#<Stream live.h264>
-#Format rtp
-#Feed feed1.ffm
-#VideoCodec libx264
-#VideoFrameRate 24
-#VideoBitRate 100
-#VideoSize 480x272
-#AVPresetVideo default
-#AVPresetVideo baseline
-#AVOptionVideo flags +global_header
-#
-#AudioCodec libfaac
-#AudioBitRate 32
-#AudioChannels 2
-#AudioSampleRate 22050
-#AVOptionAudio flags +global_header
-#</Stream>
-
-##################################################################
-# SDP/multicast examples
-#
-# If you want to send your stream in multicast, you must set the
-# multicast address with MulticastAddress. The port and the TTL can
-# also be set.
-#
-# An SDP file is automatically generated by avserver by adding the
-# 'sdp' extension to the stream name (here
-# http://localhost:8090/test1-sdp.sdp). You should usually give this
-# file to your player to play the stream.
-#
-# The 'NoLoop' option can be used to avoid looping when the stream is
-# terminated.
-
-#<Stream test1-sdp.mpg>
-#Format rtp
-#File "/usr/local/httpd/htdocs/test1.mpg"
-#MulticastAddress 224.124.0.1
-#MulticastPort 5000
-#MulticastTTL 16
-#NoLoop
-#</Stream>
-
-
-##################################################################
-# Special streams
-
-# Server status
-
-<Stream stat.html>
-Format status
-
-# Only allow local people to get the status
-ACL allow localhost
-ACL allow 192.168.0.0 192.168.255.255
-
-#FaviconURL http://pond1.gladstonefamily.net:8080/favicon.ico
-</Stream>
-
-
-# Redirect index.html to the appropriate site
-
-<Redirect index.html>
-URL http://www.libav.org/
-</Redirect>
diff --git a/doc/avserver.texi b/doc/avserver.texi
deleted file mode 100644
index c023814..0000000
--- a/doc/avserver.texi
+++ /dev/null
@@ -1,282 +0,0 @@
-\input texinfo @c -*- texinfo -*-
-
-@settitle avserver Documentation
-@titlepage
-@center @titlefont{avserver Documentation}
-@end titlepage
-
-@top
-
-@contents
-
-@chapter Synopsys
-
-The generic syntax is:
-
-@example
-@c man begin SYNOPSIS
-avserver [options]
-@c man end
-@end example
-
-@chapter Description
-@c man begin DESCRIPTION
-
-WARNING: avserver is unmaintained, largely broken and in need of a
-complete rewrite. It probably won't work for you. Use at your own
-risk.
-
-avserver 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 avserver.conf).
-
-avserver runs in daemon mode by default; that is, it puts itself in
-the background and detaches from its TTY, unless it is launched in
-debug mode or a NoDaemon option is specified in the configuration
-file.
-
-This documentation covers only the streaming aspects of avserver /
-avconv. All questions about parameters for avconv, codec questions,
-etc. are not covered here. Read @file{avconv.html} for more
-information.
-
-@section How does it work?
-
-avserver receives prerecorded files or FFM streams from some avconv
-instance as input, then streams them over RTP/RTSP/HTTP.
-
-An avserver instance will listen on some port as specified in the
-configuration file. You can launch one or more instances of avconv and
-send one or more FFM streams to the port where avserver is expecting
-to receive them. Alternately, you can make avserver launch such avconv
-instances at startup.
-
-Input streams are called feeds, and each one is specified by a <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.
-
-@section Status stream
-
-avserver supports an HTTP interface which exposes the current status
-of the server.
-
-Simply point your browser to the address of the special status stream
-specified in the configuration file.
-
-For example if you have:
-@example
-<Stream status.html>
-Format status
-
-# Only allow local people to get the status
-ACL allow localhost
-ACL allow 192.168.0.0 192.168.255.255
-</Stream>
-@end example
-
-then the server will post a page with the status information when
-the special stream @file{status.html} is requested.
-
-@section What can this do?
-
-When properly configured and running, you can capture video and audio in real
-time from a suitable capture card, and stream it out over the Internet to
-either Windows Media Player or RealAudio player (with some restrictions).
-
-It can also stream from files, though that is currently broken. Very often, a
-web server can be used to serve up the files just as well.
-
-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
-you run the avserver ./configure, make sure that you have the
-@code{--enable-libmp3lame} flag turned on.
-
-LAME is important as it allows for streaming audio to Windows Media Player.
-Don't ask why the other audio types do not work.
-
-As a simple test, just run the following two command lines where INPUTFILE
-is some file which you can decode with avconv:
-
-@example
-./avserver -f doc/avserver.conf &
-./avconv -i INPUTFILE http://localhost:8090/feed1.ffm
-@end example
-
-At this point you should be able to go to your Windows machine and fire up
-Windows Media Player (WMP). Go to Open URL and enter
-
-@example
-    http://<linuxbox>:8090/test.asf
-@end example
-
-You should (after a short delay) see video and hear audio.
-
-WARNING: trying to stream test1.mpg doesn't work with WMP as it tries to
-transfer the entire file before starting to play.
-The same is true of AVI files.
-
-@section What happens next?
-
-You should edit the avserver.conf file to suit your needs (in terms of
-frame rates etc). Then install avserver and avconv, write a script to start
-them up, and off you go.
-
-@section Troubleshooting
-
-@subsection I don't hear any audio, but video is fine.
-
-Maybe you didn't install LAME, or got your ./configure statement wrong. Check
-the avconv output to see if a line referring to MP3 is present. If not, then
-your configuration was incorrect. If it is, then maybe your wiring is not
-set up correctly. Maybe the sound card is not getting data from the right
-input source. Maybe you have a really awful audio interface (like I do)
-that only captures in stereo and also requires that one channel be flipped.
-If you are one of these people, then export 'AUDIO_FLIP_LEFT=1' before
-starting avconv.
-
-@subsection The audio and video lose sync after a while.
-
-Yes, they do.
-
-@subsection After a long while, the video update rate goes way down in WMP.
-
-Yes, it does. Who knows why?
-
-@subsection WMP 6.4 behaves differently to WMP 7.
-
-Yes, it does. Any thoughts on this would be gratefully received. These
-differences extend to embedding WMP into a web page. [There are two
-object IDs that you can use: The old one, which does not play well, and
-the new one, which does (both tested on the same system). However,
-I suspect that the new one is not available unless you have installed WMP 7].
-
-@section What else can it do?
-
-You can replay video from .ffm files that was recorded earlier.
-However, there are a number of caveats, including the fact that the
-avserver parameters must match the original parameters used to record the
-file. If they do not, then avserver deletes the file before recording into it.
-(Now that I write this, it seems broken).
-
-You can fiddle with many of the codec choices and encoding parameters, and
-there are a bunch more parameters that you cannot control. Post a message
-to the mailing list if there are some 'must have' parameters. Look in
-avserver.conf for a list of the currently available controls.
-
-It will automatically generate the ASX or RAM files that are often used
-in browsers. These files are actually redirections to the underlying ASF
-or RM file. The reason for this is that the browser often fetches the
-entire file before starting up the external viewer. The redirection files
-are very small and can be transferred quickly. [The stream itself is
-often 'infinite' and thus the browser tries to download it and never
-finishes.]
-
-@section Tips
-
-* When you connect to a live stream, most players (WMP, RA, etc) want to
-buffer a certain number of seconds of material so that they can display the
-signal continuously. However, avserver (by default) starts sending data
-in realtime. This means that there is a pause of a few seconds while the
-buffering is being done by the player. The good news is that this can be
-cured by adding a '?buffer=5' to the end of the URL. This means that the
-stream should start 5 seconds in the past -- and so the first 5 seconds
-of the stream are sent as fast as the network will allow. It will then
-slow down to real time. This noticeably improves the startup experience.
-
-You can also add a 'Preroll 15' statement into the avserver.conf that will
-add the 15 second prebuffering on all requests that do not otherwise
-specify a time. In addition, avserver will skip frames until a key_frame
-is found. This further reduces the startup delay by not transferring data
-that will be discarded.
-
-* You may want to adjust the MaxBandwidth in the avserver.conf to limit
-the amount of bandwidth consumed by live streams.
-
-@section Why does the ?buffer / Preroll stop working after a time?
-
-It turns out that (on my machine at least) the number of frames successfully
-grabbed is marginally less than the number that ought to be grabbed. This
-means that the timestamp in the encoded data stream gets behind realtime.
-This means that if you say 'Preroll 10', then when the stream gets 10
-or more seconds behind, there is no Preroll left.
-
-Fixing this requires a change in the internals of how timestamps are
-handled.
-
-@section Does the @code{?date=} stuff work.
-
-Yes (subject to the limitation outlined above). Also note that whenever you
-start avserver, it deletes the ffm file (if any parameters have changed),
-thus wiping out what you had recorded before.
-
-The format of the @code{?date=xxxxxx} is fairly flexible. You should use one
-of the following formats (the 'T' is literal):
-
-@example
-* YYYY-MM-DDTHH:MM:SS     (localtime)
-* YYYY-MM-DDTHH:MM:SSZ    (UTC)
-@end example
-
-You can omit the YYYY-MM-DD, and then it refers to the current day. However
-note that @samp{?date=16:00:00} refers to 16:00 on the current day -- this
-may be in the future and so is unlikely to be useful.
-
-You use this by adding the ?date= to the end of the URL for the stream.
-For example:   @samp{http://localhost:8080/test.asf?date=2002-07-26T23:05:00}.
-@c man end
-
-@chapter Options
-@c man begin OPTIONS
-
-@include avtools-common-opts.texi
-
-@section Main options
-
-@table @option
-@item -f @var{configfile}
-Use @file{configfile} instead of @file{/etc/avserver.conf}.
-@item -n
-Enable no-launch mode. This option disables all the Launch directives
-within the various <Stream> sections. Since avserver will not launch
-any avconv instances, you will have to launch them manually.
-@item -d
-Enable debug mode. This option increases log verbosity, directs log
-messages to stdout and causes avserver to run in the foreground
-rather than as a daemon.
-@end table
-@c man end
-
-@ignore
-
-@setfilename avserver
-@settitle avserver video server
-
-@c man begin SEEALSO
-
-avconv(1), avplay(1), avprobe(1), the @file{avserver.conf}
-example and the Libav HTML documentation
-@c man end
-
-@c man begin AUTHORS
-The Libav developers
-@c man end
-
-@end ignore
-
-@bye
diff --git a/doc/avtools-common-opts.texi b/doc/avtools-common-opts.texi
index d07505d..1fc12aa 100644
--- a/doc/avtools-common-opts.texi
+++ b/doc/avtools-common-opts.texi
@@ -18,10 +18,10 @@
 
 A stream specifier is a string generally appended to the option name and
 separated from it by a colon. E.g. @code{-codec:a:1 ac3} option contains
-@code{a:1} stream specifer, which matches the second audio stream. Therefore it
+@code{a:1} stream specifier, which matches the second audio stream. Therefore it
 would select the ac3 codec for the second audio stream.
 
-A stream specifier can match several stream, the option is then applied to all
+A stream specifier can match several streams, the option is then applied to all
 of them. E.g. the stream specifier in @code{-b:a 128k} matches all audio
 streams.
 
@@ -41,7 +41,10 @@
 @item p:@var{program_id}[:@var{stream_index}]
 If @var{stream_index} is given, then matches stream number @var{stream_index} in
 program with id @var{program_id}. Otherwise matches all streams in this program.
+@item #@var{stream_id}
+Matches the stream by format-specific ID.
 @end table
+
 @section Generic options
 
 These options are shared amongst the av* tools.
@@ -116,6 +119,9 @@
 @item -sample_fmts
 Show available sample formats.
 
+@item -layouts
+Show channel names and standard channel layouts.
+
 @item -loglevel @var{loglevel} | -v @var{loglevel}
 Set the logging level used by the library.
 @var{loglevel} is a number or a string containing one of the following values:
@@ -136,7 +142,26 @@
 @env{AV_LOG_FORCE_NOCOLOR} or @env{NO_COLOR}, or can be forced setting
 the environment variable @env{AV_LOG_FORCE_COLOR}.
 The use of the environment variable @env{NO_COLOR} is deprecated and
-will be dropped in a following Libav version.
+will be dropped in a following FFmpeg version.
+
+@item -report
+Dump full command line and console output to a file named
+@code{@var{program}-@var{YYYYMMDD}-@var{HHMMSS}.log} in the current
+directory.
+This file can be useful for bug reports.
+It also implies @code{-loglevel verbose}.
+
+Note: setting the environment variable @code{FFREPORT} to any value has the
+same effect.
+
+@item -cpuflags flags (@emph{global})
+Allows setting and clearing cpu flags. This option is intended
+for testing. Do not use it unless you know what you're doing.
+@example
+ffmpeg -cpuflags -sse+mmx ...
+ffmpeg -cpuflags mmx ...
+ffmpeg -cpuflags 0 ...
+@end example
 
 @end table
 
@@ -159,7 +184,7 @@
 an MP3 file, use the @option{id3v2_version} private option of the MP3
 muxer:
 @example
-avconv -i input.flac -id3v2_version 3 out.mp3
+ffmpeg -i input.flac -id3v2_version 3 out.mp3
 @end example
 
 All codec AVOptions are obviously per-stream, so the chapter on stream
diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
index a6fe2f2..2ee00c1 100644
--- a/doc/bitstream_filters.texi
+++ b/doc/bitstream_filters.texi
@@ -1,7 +1,7 @@
 @chapter Bitstream Filters
 @c man begin BITSTREAM FILTERS
 
-When you configure your Libav build, all the supported bitstream
+When you configure your FFmpeg build, all the supported bitstream
 filters are enabled by default. You can list all available ones using
 the configure option @code{--list-bsfs}.
 
@@ -23,6 +23,20 @@
 
 @section h264_mp4toannexb
 
+Convert an H.264 bitstream from length prefixed mode to start code
+prefixed mode (as defined in the Annex B of the ITU-T H.264
+specification).
+
+This is required by some streaming formats, typically the MPEG-2
+transport stream format ("mpegts").
+
+For example to remux an MP4 file containing an H.264 stream to mpegts
+format with @command{ffmpeg}, you can use the command:
+
+@example
+ffmpeg -i INPUT.mp4 -codec copy -bsf:v h264_mp4toannexb OUTPUT.ts
+@end example
+
 @section imx_dump_header
 
 @section mjpeg2jpeg
@@ -34,7 +48,7 @@
 e.g. by
 
 @example
-avconv -i ../some_mjpeg.avi -c:v copy frames_%d.jpg
+ffmpeg -i ../some_mjpeg.avi -c:v copy frames_%d.jpg
 @end example
 
 Unfortunately, these chunks are incomplete JPEG images, because
@@ -57,9 +71,9 @@
 produce fully qualified JPEG images.
 
 @example
-avconv -i mjpeg-movie.avi -c:v copy -bsf:v mjpeg2jpeg frame_%d.jpg
+ffmpeg -i mjpeg-movie.avi -c:v copy -bsf:v mjpeg2jpeg frame_%d.jpg
 exiftran -i -9 frame*.jpg
-avconv -i frame_%d.jpg -c:v copy rotated.avi
+ffmpeg -i frame_%d.jpg -c:v copy rotated.avi
 @end example
 
 @section mjpega_dump_header
diff --git a/doc/build_system.txt b/doc/build_system.txt
index c3dede7..36c141e 100644
--- a/doc/build_system.txt
+++ b/doc/build_system.txt
@@ -1,4 +1,4 @@
-Libav currently uses a custom build system, this text attempts to document
+FFmpeg currently uses a custom build system, this text attempts to document
 some of its obscure features and options.
 
 Makefile variables:
@@ -9,13 +9,19 @@
 
 DESTDIR
     Destination directory for the install targets, useful to prepare packages
-    or install Libav in cross-environments.
+    or install FFmpeg in cross-environments.
 
 Makefile targets:
 
 all
     Default target, builds all the libraries and the executables.
 
+fate
+    Run the fate test suite, note you must have installed it
+
+fate-list
+    Will list all fate/regression test targets
+
 install
     Install headers, libraries and programs.
 
@@ -27,3 +33,18 @@
 
 libswscale/swscale-test
     Build the swscale self-test (useful also as example).
+
+
+Useful standard make commands:
+make -t <target>
+    Touch all files that otherwise would be build, this is useful to reduce
+    unneeded rebuilding when changing headers, but note you must force rebuilds
+    of files that actually need it by hand then.
+
+make -j<num>
+    rebuild with multiple jobs at the same time. Faster on multi processor systems
+
+make -k
+    continue build in case of errors, this is useful for the regression tests
+    sometimes but note it will still not run all reg tests.
+
diff --git a/doc/decoders.texi b/doc/decoders.texi
new file mode 100644
index 0000000..87ad4ee
--- /dev/null
+++ b/doc/decoders.texi
@@ -0,0 +1,63 @@
+@chapter Decoders
+@c man begin DECODERS
+
+Decoders are configured elements in FFmpeg which allow the decoding of
+multimedia streams.
+
+When you configure your FFmpeg build, all the supported native decoders
+are enabled by default. Decoders requiring an external library must be enabled
+manually via the corresponding @code{--enable-lib} option. You can list all
+available decoders using the configure option @code{--list-decoders}.
+
+You can disable all the decoders with the configure option
+@code{--disable-decoders} and selectively enable / disable single decoders
+with the options @code{--enable-decoder=@var{DECODER}} /
+@code{--disable-decoder=@var{DECODER}}.
+
+The option @code{-codecs} of the ff* tools will display the list of
+enabled decoders.
+
+@c man end DECODERS
+
+@chapter Video Decoders
+@c man begin VIDEO DECODERS
+
+A description of some of the currently available video decoders
+follows.
+
+@section rawvideo
+
+Raw video decoder.
+
+This decoder decodes rawvideo streams.
+
+@subsection Options
+
+@table @option
+@item top @var{top_field_first}
+Specify the assumed field type of the input video.
+@table @option
+@item -1
+the video is assumed to be progressive (default)
+@item 0
+bottom-field-first is assumed
+@item 1
+top-field-first is assumed
+@end table
+
+@end table
+
+@c man end VIDEO DECODERS
+
+@chapter Audio Decoders
+@c man begin AUDIO DECODERS
+
+@section ffwavesynth
+
+Internal wave synthetizer.
+
+This decoder generates wave patterns according to predefined sequences. Its
+use is purely internal and the format of the data it accepts is not publicly
+documented.
+
+@c man end AUDIO DECODERS
diff --git a/doc/demuxers.texi b/doc/demuxers.texi
index c3049dd..aea4c54 100644
--- a/doc/demuxers.texi
+++ b/doc/demuxers.texi
@@ -1,10 +1,10 @@
 @chapter Demuxers
 @c man begin DEMUXERS
 
-Demuxers are configured elements in Libav which allow to read the
+Demuxers are configured elements in FFmpeg which allow to read the
 multimedia streams from a particular type of file.
 
-When you configure your Libav build, all the supported demuxers
+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".
 
@@ -23,8 +23,31 @@
 Image file demuxer.
 
 This demuxer reads from a list of image files specified by a pattern.
+The syntax and meaning of the pattern is specified by the
+option @var{pattern_type}.
 
-The pattern may contain the string "%d" or "%0@var{N}d", which
+The pattern may contain a suffix which is used to automatically
+determine the format of the images contained in the files.
+
+The size, the pixel format, and the format of each image must be the
+same for all the files in the sequence.
+
+This demuxer accepts the following options:
+@table @option
+@item framerate
+Set the framerate for the video stream. It defaults to 25.
+@item loop
+If set to 1, loop over the input. Default value is 0.
+@item pattern_type
+Select the pattern type used to interpret the provided filename.
+
+@var{pattern_type} accepts one of the following values.
+@table @option
+@item sequence
+Select a sequence pattern type, used to specify a sequence of files
+indexed by sequential numbers.
+
+A sequence pattern may contain the string "%d" or "%0@var{N}d", which
 specifies the position of the characters representing a sequential
 number in each filename matched by the pattern. If the form
 "%d0@var{N}d" is used, the string representing the number in each
@@ -32,13 +55,11 @@
 digits representing the number. The literal character '%' can be
 specified in the pattern with the string "%%".
 
-If the pattern contains "%d" or "%0@var{N}d", the first filename of
+If the sequence pattern contains "%d" or "%0@var{N}d", the first filename of
 the file list specified by the pattern must contain a number
-inclusively contained between 0 and 4, all the following numbers must
-be sequential. This limitation may be hopefully fixed.
-
-The pattern may contain a suffix which is used to automatically
-determine the format of the images contained in the files.
+inclusively contained between @var{start_number} and
+@var{start_number}+@var{start_number_range}-1, and all the following
+numbers must be sequential.
 
 For example the pattern "img-%03d.bmp" will match a sequence of
 filenames of the form @file{img-001.bmp}, @file{img-002.bmp}, ...,
@@ -46,33 +67,121 @@
 sequence of filenames of the form @file{i%m%g-1.jpg},
 @file{i%m%g-2.jpg}, ..., @file{i%m%g-10.jpg}, etc.
 
-The size, the pixel format, and the format of each image must be the
-same for all the files in the sequence.
-
-The following example shows how to use @command{avconv} for creating a
-video from the images in the file sequence @file{img-001.jpeg},
-@file{img-002.jpeg}, ..., assuming an input framerate of 10 frames per
-second:
-@example
-avconv -i 'img-%03d.jpeg' -r 10 out.mkv
-@end example
-
 Note that the pattern must not necessarily contain "%d" or
 "%0@var{N}d", for example to convert a single image file
 @file{img.jpeg} you can employ the command:
 @example
-avconv -i img.jpeg img.png
+ffmpeg -i img.jpeg img.png
 @end example
 
+@item glob
+Select a glob wildcard pattern type.
+
+The pattern is interpreted like a @code{glob()} pattern. This is only
+selectable if libavformat was compiled with globbing support.
+
+@item glob_sequence @emph{(deprecated, will be removed)}
+Select a mixed glob wildcard/sequence pattern.
+
+If your version of libavformat was compiled with globbing support, and
+the provided pattern contains at least one glob meta character among
+@code{%*?[]@{@}} that is preceded by an unescaped "%", the pattern is
+interpreted like a @code{glob()} pattern, otherwise it is interpreted
+like a sequence pattern.
+
+All glob special characters @code{%*?[]@{@}} must be prefixed
+with "%". To escape a literal "%" you shall use "%%".
+
+For example the pattern @code{foo-%*.jpeg} will match all the
+filenames prefixed by "foo-" and terminating with ".jpeg", and
+@code{foo-%?%?%?.jpeg} will match all the filenames prefixed with
+"foo-", followed by a sequence of three characters, and terminating
+with ".jpeg".
+
+This pattern type is deprecated in favor of @var{glob} and
+@var{sequence}.
+@end table
+
+Default value is @var{glob_sequence}.
+@item pixel_format
+Set the pixel format of the images to read. If not specified the pixel
+format is guessed from the first image file in the sequence.
+@item start_number
+Set the index of the file matched by the image file pattern to start
+to read from. Default value is 0.
+@item start_number_range
+Set the index interval range to check when looking for the first image
+file in the sequence, starting from @var{start_number}. Default value
+is 5.
+@item video_size
+Set the video size of the images to read. If not specified the video
+size is guessed from the first image file in the sequence.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Use @command{ffmpeg} for creating a video from the images in the file
+sequence @file{img-001.jpeg}, @file{img-002.jpeg}, ..., assuming an
+input frame rate of 10 frames per second:
+@example
+ffmpeg -i 'img-%03d.jpeg' -r 10 out.mkv
+@end example
+
+@item
+As above, but start by reading from a file with index 100 in the sequence:
+@example
+ffmpeg -start_number 100 -i 'img-%03d.jpeg' -r 10 out.mkv
+@end example
+
+@item
+Read images matching the "*.png" glob pattern , that is all the files
+terminating with the ".png" suffix:
+@example
+ffmpeg -pattern_type glob -i "*.png" -r 10 out.mkv
+@end example
+@end itemize
+
 @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 avplay),
+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 sbg
+
+SBaGen script demuxer.
+
+This demuxer reads the script language used by SBaGen
+@url{http://uazu.net/sbagen/} to generate binaural beats sessions. A SBG
+script looks like that:
+@example
+-SE
+a: 300-2.5/3 440+4.5/0
+b: 300-2.5/0 440+4.5/3
+off: -
+NOW      == a
++0:07:00 == b
++0:14:00 == a
++0:21:00 == b
++0:30:00    off
+@end example
+
+A SBG script can mix absolute and relative timestamps. If the script uses
+either only absolute timestamps (including the script start time) or only
+relative ones, then its layout is fixed, and the conversion is
+straightforward. On the other hand, if the script mixes both kind of
+timestamps, then the @var{NOW} reference for relative timestamps will be
+taken from the current time of day at the time the script is read, and the
+script layout will be frozen according to that reference. That means that if
+the script is directly played, the actual times will match the absolute
+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
diff --git a/doc/developer.texi b/doc/developer.texi
index aff28b8..cd635a8 100644
--- a/doc/developer.texi
+++ b/doc/developer.texi
@@ -14,78 +14,47 @@
 @section API
 @itemize @bullet
 @item libavcodec is the library containing the codecs (both encoding and
-decoding). Look at @file{libavcodec/apiexample.c} to see how to use it.
+decoding). Look at @file{doc/examples/decoding_encoding.c} to see how to use
+it.
 
 @item libavformat is the library containing the file format handling (mux and
-demux code for several formats). Look at @file{avplay.c} to use it in a
-player. See @file{libavformat/output-example.c} to use it to generate
-audio or video streams.
+demux code for several formats). Look at @file{ffplay.c} to use it in a
+player. See @file{doc/examples/muxing.c} to use it to generate audio or video
+streams.
 
 @end itemize
 
-@section Integrating libav in your program
+@section Integrating libavcodec or libavformat in your program
 
-Shared libraries should be used whenever is possible in order to reduce
-the effort distributors have to pour to support programs and to ensure
-only the public api is used.
+You can integrate all the source code of the libraries to link them
+statically to avoid any version problem. All you need is to provide a
+'config.mak' and a 'config.h' in the parent directory. See the defines
+generated by ./configure to understand what is needed.
 
-You can use Libav in your commercial program, but you must abide to the
-license, LGPL or GPL depending on the specific features used, please refer
-to @uref{http://libav.org/legal.html, our legal page} for a quick checklist and to
-the following links for the exact text of each license:
-@uref{http://git.libav.org/?p=libav.git;a=blob;f=COPYING.GPLv2, GPL version 2},
-@uref{http://git.libav.org/?p=libav.git;a=blob;f=COPYING.GPLv3, GPL version 3},
-@uref{http://git.libav.org/?p=libav.git;a=blob;f=COPYING.LGPLv2.1, LGPL version 2.1},
-@uref{http://git.libav.org/?p=libav.git;a=blob;f=COPYING.LGPLv3, LGPL version 3}.
-Any modification to the source code can be suggested for inclusion.
-The best way to proceed is to send your patches to the
-@uref{https://lists.libav.org/mailman/listinfo/libav-devel, libav-devel}
-mailing list.
+You can use libavcodec or libavformat in your commercial program, but
+@emph{any patch you make must be published}. The best way to proceed is
+to send your patches to the FFmpeg mailing list.
+
+@section Contributing
+
+There are 3 ways by which code gets into ffmpeg.
+@itemize @bullet
+@item Submitting Patches to the main developer mailing list
+      see @ref{Submitting patches} for details.
+@item Directly committing changes to the main tree.
+@item Committing changes to a git clone, for example on github.com or
+      gitorious.org. And asking us to merge these changes.
+@end itemize
+
+Whichever way, changes should be reviewed by the maintainer of the code
+before they are committed. And they should follow the @ref{Coding Rules}.
+The developer making the commit and the author are responsible for their changes
+and should try to fix issues their commit causes.
 
 @anchor{Coding Rules}
 @section Coding Rules
 
 @subsection Code formatting conventions
-The code is written in K&R C style. That means the following:
-@itemize @bullet
-@item
-The control statements are formatted by putting space between the statement
-and parenthesis in the following way:
-@example
-for (i = 0; i < filter->input_count; i++) @{
-@end example
-@item
-The case statement is always located at the same level as the switch itself:
-@example
-switch (link->init_state) @{
-case AVLINK_INIT:
-    continue;
-case AVLINK_STARTINIT:
-    av_log(filter, AV_LOG_INFO, "circular filter chain detected");
-    return 0;
-@end example
-@item
-Braces in function declarations are written on the new line:
-@example
-const char *avfilter_configuration(void)
-@{
-    return LIBAV_CONFIGURATION;
-@}
-@end example
-@item
-Do not check for NULL values by comparison, @samp{if (p)} and
-@samp{if (!p)} are correct; @samp{if (p == NULL)} and @samp{if (p != NULL)}
-are not.
-@item
-In case of a single-statement if, no curly braces are required:
-@example
-if (!pic || !picref)
-    goto fail;
-@end example
-@item
-Do not put spaces immediately inside parentheses. @samp{if (ret)} is
-a valid style; @samp{if ( ret )} is not.
-@end itemize
 
 There are the following guidelines regarding the indentation in files:
 @itemize @bullet
@@ -101,7 +70,7 @@
 @end itemize
 The presentation is one inspired by 'indent -i4 -kr -nut'.
 
-The main priority in Libav is simplicity and small code size in order to
+The main priority in FFmpeg is simplicity and small code size in order to
 minimize the bug count.
 
 @subsection Comments
@@ -146,7 +115,7 @@
 
 @subsection C language features
 
-Libav is programmed in the ISO C90 language with a few additional
+FFmpeg is programmed in the ISO C90 language with a few additional
 features from ISO C99, namely:
 @itemize @bullet
 @item
@@ -178,10 +147,10 @@
 @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 only exception from this are structure
-names; they should always be in the CamelCase
+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
+for example structs and enums; they should always be in the CamelCase
+
 
 There are following conventions for naming variables and functions:
 @itemize @bullet
@@ -212,10 +181,10 @@
 @end itemize
 
 @subsection Editor configuration
-In order to configure Vim to follow Libav formatting conventions, paste
+In order to configure Vim to follow FFmpeg formatting conventions, paste
 the following snippet into your @file{.vimrc}:
 @example
-" indentation rules for libav: 4 spaces, no tabs
+" indentation rules for FFmpeg: 4 spaces, no tabs
 set expandtab
 set shiftwidth=4
 set softtabstop=4
@@ -232,7 +201,7 @@
 
 For Emacs, add these roughly equivalent lines to your @file{.emacs.d/init.el}:
 @example
-(c-add-style "libav"
+(c-add-style "ffmpeg"
              '("k&r"
                (c-basic-offset . 4)
                (indent-tabs-mode . nil)
@@ -241,7 +210,7 @@
                 (statement-cont . (c-lineup-assignments +)))
                )
              )
-(setq c-default-style "libav")
+(setq c-default-style "ffmpeg")
 @end example
 
 @section Development Policy
@@ -253,33 +222,17 @@
    an "or any later version" clause is also acceptable, but LGPL is
    preferred.
 @item
-   All the patches MUST be reviewed in the mailing list before they are
-   committed.
+   You must not commit code which breaks FFmpeg! (Meaning unfinished but
+   enabled code which breaks compilation or compiles but does not work or
+   breaks the regression tests)
+   You can commit unfinished stuff (for testing etc), but it must be disabled
+   (#ifdef etc) by default so it does not interfere with other developers'
+   work.
 @item
-   The Libav coding style should remain consistent. Changes to
-   conform will be suggested during the review or implemented on commit.
-@item
-   Patches should be generated using @code{git format-patch} or directly sent
-   using @code{git send-email}.
-   Please make sure you give the proper credit by setting the correct author
-   in the commit.
-@item
-   The commit message should have a short first line in the form of
-   @samp{topic: short description} as header, separated by a newline
-   from the body consting in few lines explaining the reason of the patch.
-   Referring to the issue on the bug tracker does not exempt to report an
-   excerpt of the bug.
-@item
-   Work in progress patches should be sent to the mailing list with the [WIP]
-   or the [RFC] tag.
-@item
-   Branches in public personal repos are advised as way to
-   work on issues collaboratively.
-@item
-   You do not have to over-test things. If it works for you and you think it
-   should work for others, send it to the mailing list for review.
-   If you have doubt about portability please state it in the submission so
-   people with specific hardware could test it.
+   You do not have to over-test things. If it works for you, and you think it
+   should work for others, then commit. If your code has problems
+   (portability, triggers compiler bugs, unusual environment etc) they will be
+   reported and eventually fixed.
 @item
    Do not commit unrelated changes together, split them into self-contained
    pieces. Also do not forget that if part B depends on part A, but A does not
@@ -287,37 +240,75 @@
    Keeping changes well split into self-contained parts makes reviewing and
    understanding them on the commit log mailing list easier. This also helps
    in case of debugging later on.
+   Also if you have doubts about splitting or not splitting, do not hesitate to
+   ask/discuss it on the developer mailing list.
 @item
-   Patches that change behavior of the programs (renaming options etc) or
-   public API or ABI should be discussed in depth and possible few days should
-   pass between discussion and commit.
-   Changes to the build system (Makefiles, configure script) which alter
-   the expected behavior should be considered in the same regard.
+   Do not change behavior of the programs (renaming options etc) or public
+   API or ABI without first discussing it on the ffmpeg-devel mailing list.
+   Do not remove functionality from the code. Just improve!
+
+   Note: Redundant code can be removed.
+@item
+   Do not commit changes to the build system (Makefiles, configure script)
+   which change behavior, defaults etc, without asking first. The same
+   applies to compiler warning fixes, trivial looking fixes and to code
+   maintained by other developers. We usually have a reason for doing things
+   the way we do. Send your changes as patches to the ffmpeg-devel mailing
+   list, and if the code maintainers say OK, you may commit. This does not
+   apply to files you wrote and/or maintain.
+@item
+   We refuse source indentation and other cosmetic changes if they are mixed
+   with functional changes, such commits will be rejected and removed. Every
+   developer has his own indentation style, you should not change it. Of course
+   if you (re)write something, you can use your own style, even though we would
+   prefer if the indentation throughout FFmpeg was consistent (Many projects
+   force a given indentation style - we do not.). If you really need to make
+   indentation changes (try to avoid this), separate them strictly from real
+   changes.
+
+   NOTE: If you had to put if()@{ .. @} over a large (> 5 lines) chunk of code,
+   then either do NOT change the indentation of the inner part within (do not
+   move it to the right)! or do so in a separate commit
+@item
+   Always fill out the commit log message. Describe in a few lines what you
+   changed and why. You can refer to mailing list postings if you fix a
+   particular bug. Comments such as "fixed!" or "Changed it." are unacceptable.
+   Recommended format:
+   area changed: Short 1 line description
+
+   details describing what and why and giving references.
+@item
+   Make sure the author of the commit is set correctly. (see git commit --author)
+   If you apply a patch, send an
+   answer to ffmpeg-devel (or wherever you got the patch from) saying that
+   you applied the patch.
 @item
    When applying patches that have been discussed (at length) on the mailing
    list, reference the thread in the log message.
 @item
-    Subscribe to the
-    @uref{https://lists.libav.org/mailman/listinfo/libav-devel, libav-devel} and
-    @uref{https://lists.libav.org/mailman/listinfo/libav-commits, libav-commits}
-    mailing lists.
-    Bugs and possible improvements or general questions regarding commits
-    are discussed on libav-devel. We expect you to react if problems with
-    your code are uncovered.
+    Do NOT commit to code actively maintained by others without permission.
+    Send a patch to ffmpeg-devel instead. If no one answers within a reasonable
+    timeframe (12h for build failures and security fixes, 3 days small changes,
+    1 week for big patches) then commit your patch if you think it is OK.
+    Also note, the maintainer can simply ask for more time to review!
+@item
+    Subscribe to the ffmpeg-cvslog mailing list. The diffs of all commits
+    are sent there and reviewed by all the other developers. Bugs and possible
+    improvements or general questions regarding commits are discussed there. We
+    expect you to react if problems with your code are uncovered.
 @item
     Update the documentation if you change behavior or add features. If you are
-    unsure how best to do this, send an [RFC] patch to libav-devel.
+    unsure how best to do this, send a patch to ffmpeg-devel, the documentation
+    maintainer(s) will review and commit your stuff.
 @item
-    All discussions and decisions should be reported on the public developer
-    mailing list, so that there is a reference to them.
-    Other media (e.g. IRC) should be used for coordination and immediate
-    collaboration.
+    Try to keep important discussions and requests (also) on the public
+    developer mailing list, so that all developers can benefit from them.
 @item
     Never write to unallocated memory, never write over the end of arrays,
     always check values read from some untrusted source before using them
-    as array index or other risky things. Always use valgrind to doublecheck.
+    as array index or other risky things.
 @item
-    Remember to check if you need to bump versions for the specific libav
+    Remember to check if you need to bump versions for the specific libav*
     parts (libavutil, libavcodec, libavformat) you are changing. You need
     to change the version integer.
     Incrementing the first component means no backward compatibility to
@@ -328,12 +319,13 @@
     Incrementing the third component means a noteworthy binary compatible
     change (e.g. encoder bug fix that matters for the decoder).
 @item
-    Compiler warnings indicate potential bugs or code with bad style.
+    Compiler warnings indicate potential bugs or code with bad style. If a type of
+    warning always points to correct and clean code, that warning should
+    be disabled, not the code changed.
+    Thus the remaining warnings can either be bugs or correct code.
     If it is a bug, the bug has to be fixed. If it is not, the code should
     be changed to not generate a warning unless that causes a slowdown
     or obfuscates the code.
-    If a type of warning leads to too many false positives, that warning
-    should be disabled, not the code changed.
 @item
     If you add a new file, give it a proper license header. Do not copy and
     paste it from a random place, use an existing file as template.
@@ -341,49 +333,47 @@
 
 We think our rules are not too hard. If you have comments, contact us.
 
-Note, some rules were borrowed from the MPlayer project.
+Note, these rules are mostly borrowed from the MPlayer project.
 
+@anchor{Submitting patches}
 @section Submitting patches
 
 First, read the @ref{Coding Rules} above if you did not yet, in particular
 the rules regarding patch submission.
 
-As stated already, please do not submit a patch which contains several
-unrelated changes.
+When you submit your patch, please use @code{git format-patch} or
+@code{git send-email}. We cannot read other diffs :-)
+
+Also please do not submit a patch which contains several unrelated changes.
 Split it into separate, self-contained pieces. This does not mean splitting
 file by file. Instead, make the patch as small as possible while still
 keeping it as a logical unit that contains an individual change, even
 if it spans multiple files. This makes reviewing your patches much easier
 for us and greatly increases your chances of getting your patch applied.
 
-Use the patcheck tool of Libav to check your patch.
+Use the patcheck tool of FFmpeg to check your patch.
 The tool is located in the tools directory.
 
-Run the @ref{Regression Tests} before submitting a patch in order to verify
+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
-@uref{https://lists.libav.org/mailman/listinfo/libav-devel, libav-devel}
-mailing list.
+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()'). This kind of explanation should be the body of the
-commit message.
+and has no lrint()')
 
 Also please if you send several patches, send each patch as a separate mail,
 do not attach several unrelated patches to the same mail.
 
-Use @code{git send-email} when possible since it will properly send patches
-without requiring extra care.
-
 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
-several iterations. Once your patch is deemed good enough, it will be
-committed to the official Libav tree.
+several iterations. Once your patch is deemed good enough, some developer
+will pick it up and commit it to the official FFmpeg tree.
 
 Give us a few days to react. But if some time passes without reaction,
 send a reminder by email. Your patch should eventually be dealt with.
@@ -407,12 +397,12 @@
     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?
-    Remember to do this even if you are just adding a format to a file that
-    is already being compiled by some other rule, like a raw demuxer.
+    Remember to do this even if you're just adding a format to a file that is
+    already being compiled by some other rule, like a raw demuxer.
 @item
     Did you add an entry to the table of supported formats or codecs in
     @file{doc/general.texi}?
@@ -434,13 +424,20 @@
 
 @enumerate
 @item
-    Does @code{make check} pass with the patch applied?
+    Does @code{make fate} pass with the patch applied?
 @item
-    Is the patch against latest Libav git master branch?
+    Was the patch generated with git format-patch or send-email?
 @item
-    Are you subscribed to the
-    @uref{https://lists.libav.org/mailman/listinfo/libav-devel, libav-devel}
-    mailing list? (Only list subscribers are allowed to post.)
+    Did you sign off your patch? (git commit -s)
+    See @url{http://kerneltrap.org/files/Jeremy/DCO.txt} for the meaning
+    of sign off.
+@item
+    Did you provide a clear git commit log message?
+@item
+    Is the patch against latest FFmpeg git master branch?
+@item
+    Are you subscribed to ffmpeg-devel?
+    (the list is subscribers only due to spam)
 @item
     Have you checked that the changes are minimal, so that the same cannot be
     achieved with a smaller patch and/or simpler final code?
@@ -470,7 +467,7 @@
     If the patch fixes a bug, did you provide enough information, including
     a sample, so the bug can be reproduced and the fix can be verified?
     Note please do not attach samples >100k to mails but rather provide a
-    URL, you can upload to ftp://upload.libav.org
+    URL, you can upload to ftp://upload.ffmpeg.org
 @item
     Did you provide a verbose summary about what the patch does change?
 @item
@@ -483,7 +480,7 @@
     patch easily?
 @item
     If you added a new file, did you insert a license header? It should be
-    taken from Libav, not randomly copied and pasted from somewhere else.
+    taken from FFmpeg, not randomly copied and pasted from somewhere else.
 @item
     You should maintain alphabetical order in alphabetically ordered lists as
     long as doing so does not break API/ABI compatibility.
@@ -491,16 +488,18 @@
     Lines with similar content should be aligned vertically when doing so
     improves readability.
 @item
+    Consider to add a regression test for your code.
+@item
+    If you added YASM code please check that things still work with --disable-yasm
+@item
     Make sure you check the return values of function and return appropriate
-    error codes. Especially memory allocation functions like @code{malloc()}
+    error codes. Especially memory allocation functions like @code{av_malloc()}
     are notoriously left unchecked, which is a serious problem.
 @end enumerate
 
 @section Patch review process
 
-All patches posted to the
-@uref{https://lists.libav.org/mailman/listinfo/libav-devel, libav-devel}
-mailing list will be reviewed, unless they contain a
+All patches posted to ffmpeg-devel will be reviewed, unless they contain a
 clear note that the patch is not for the git master branch.
 Reviews and comments will be posted as replies to the patch on the
 mailing list. The patch submitter then has to take care of every comment,
@@ -514,22 +513,38 @@
 We will review all submitted patches, but sometimes we are quite busy so
 especially for large patches this can take several weeks.
 
-When resubmitting patches, if their size grew or during the review different
-issues arisen please split the patch so each issue has a specific patch.
+If you feel that the review process is too slow and you are willing to try to
+take over maintainership of the area of code you change then just clone
+git master and maintain the area of code there. We will merge each area from
+where its best maintained.
 
-@anchor{Regression Tests}
-@section Regression Tests
+When resubmitting patches, please do not make any significant changes
+not related to the comments received during review. Such patches will
+be rejected. Instead, submit significant changes or new features as
+separate patches.
 
-Before submitting a patch (or committing to the repository), you should at
-least make sure that it does not break anything.
+@anchor{Regression tests}
+@section Regression tests
 
-If the code changed has already a test present in FATE you should run it,
-otherwise it is advised to add it.
+Before submitting a patch (or committing to the repository), you should at least
+test that you did not break anything.
 
-Improvements to codec or demuxer might change the FATE results. Make sure
-to commit the update reference with the change and to explain in the comment
-why the expected result changed.
+Running 'make fate' accomplishes this, please see @url{fate.html} for details.
 
-Please refer to @url{fate.html}.
+[Of course, some patches may change the results of the regression tests. In
+this case, the reference results of the regression tests shall be modified
+accordingly].
+
+@subsection Adding files to the fate-suite dataset
+
+When there is no muxer or encoder available to generate test media for a
+specific test then the media has to be inlcuded in the fate-suite.
+First please make sure that the sample file is as small as possible to test the
+respective decoder or demuxer sufficiently. Large files increase network
+bandwidth and disk space requirements.
+Once you have a working fate test and fate sample, provide in the commit
+message or introductionary message for the patch series that you post to
+the ffmpeg-devel mailing list, a direct link to download the sample media.
+
 
 @bye
diff --git a/doc/encoders.texi b/doc/encoders.texi
index 830981f..a7a2761 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -1,10 +1,10 @@
 @chapter Encoders
 @c man begin ENCODERS
 
-Encoders are configured elements in Libav which allow the encoding of
+Encoders are configured elements in FFmpeg which allow the encoding of
 multimedia streams.
 
-When you configure your Libav build, all the supported native encoders
+When you configure your FFmpeg build, all the supported native encoders
 are enabled by default. Encoders requiring an external library must be enabled
 manually via the corresponding @code{--enable-lib} option. You can list all
 available encoders using the configure option @code{--list-encoders}.
@@ -369,7 +369,7 @@
 
 @end table
 
-@subheading Floating-Point-Only AC-3 Encoding Options
+@subsection Floating-Point-Only AC-3 Encoding Options
 
 These options are only valid for the floating-point encoder and do not exist
 for the fixed-point encoder due to the corresponding features not being
@@ -413,3 +413,182 @@
 @end table
 
 @c man end AUDIO ENCODERS
+
+@chapter Video Encoders
+@c man begin VIDEO ENCODERS
+
+A description of some of the currently available video encoders
+follows.
+
+@section libvpx
+
+VP8 format supported through libvpx.
+
+Requires the presence of the libvpx headers and library during configuration.
+You need to explicitly configure the build with @code{--enable-libvpx}.
+
+@subsection Options
+
+Mapping from FFmpeg to libvpx options with conversion notes in parentheses.
+
+@table @option
+
+@item threads
+g_threads
+
+@item profile
+g_profile
+
+@item vb
+rc_target_bitrate
+
+@item g
+kf_max_dist
+
+@item keyint_min
+kf_min_dist
+
+@item qmin
+rc_min_quantizer
+
+@item qmax
+rc_max_quantizer
+
+@item bufsize, vb
+rc_buf_sz
+@code{(bufsize * 1000 / vb)}
+
+rc_buf_optimal_sz
+@code{(bufsize * 1000 / vb * 5 / 6)}
+
+@item rc_init_occupancy, vb
+rc_buf_initial_sz
+@code{(rc_init_occupancy * 1000 / vb)}
+
+@item rc_buffer_aggressivity
+rc_undershoot_pct
+
+@item skip_threshold
+rc_dropframe_thresh
+
+@item qcomp
+rc_2pass_vbr_bias_pct
+
+@item maxrate, vb
+rc_2pass_vbr_maxsection_pct
+@code{(maxrate * 100 / vb)}
+
+@item minrate, vb
+rc_2pass_vbr_minsection_pct
+@code{(minrate * 100 / vb)}
+
+@item minrate, maxrate, vb
+@code{VPX_CBR}
+@code{(minrate == maxrate == vb)}
+
+@item crf
+@code{VPX_CQ}, @code{VP8E_SET_CQ_LEVEL}
+
+@item quality
+@table @option
+@item @var{best}
+@code{VPX_DL_BEST_QUALITY}
+@item @var{good}
+@code{VPX_DL_GOOD_QUALITY}
+@item @var{realtime}
+@code{VPX_DL_REALTIME}
+@end table
+
+@item speed
+@code{VP8E_SET_CPUUSED}
+
+@item nr
+@code{VP8E_SET_NOISE_SENSITIVITY}
+
+@item mb_threshold
+@code{VP8E_SET_STATIC_THRESHOLD}
+
+@item slices
+@code{VP8E_SET_TOKEN_PARTITIONS}
+
+@item max-intra-rate
+@code{VP8E_SET_MAX_INTRA_BITRATE_PCT}
+
+@item force_key_frames
+@code{VPX_EFLAG_FORCE_KF}
+
+@item Alternate reference frame related
+@table @option
+@item vp8flags altref
+@code{VP8E_SET_ENABLEAUTOALTREF}
+@item @var{arnr_max_frames}
+@code{VP8E_SET_ARNR_MAXFRAMES}
+@item @var{arnr_type}
+@code{VP8E_SET_ARNR_TYPE}
+@item @var{arnr_strength}
+@code{VP8E_SET_ARNR_STRENGTH}
+@item @var{rc_lookahead}
+g_lag_in_frames
+@end table
+
+@item vp8flags error_resilient
+g_error_resilient
+
+@end table
+
+For more information about libvpx see:
+@url{http://www.webmproject.org/}
+
+@section libx264
+
+H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 format supported through
+libx264.
+
+Requires the presence of the libx264 headers and library during
+configuration. You need to explicitly configure the build with
+@code{--enable-libx264}.
+
+@subsection Options
+
+@table @option
+
+@item preset @var{preset_name}
+Set the encoding preset.
+
+@item tune @var{tune_name}
+Tune the encoding params.
+
+@item fastfirstpass @var{bool}
+Use fast settings when encoding first pass, default value is 1.
+
+@item profile @var{profile_name}
+Set profile restrictions.
+
+@item level @var{level}
+Specify level (as defined by Annex A).
+Deprecated in favor of @var{x264opts}.
+
+@item passlogfile @var{filename}
+Specify filename for 2 pass stats.
+Deprecated in favor of @var{x264opts} (see @var{stats} libx264 option).
+
+@item wpredp @var{wpred_type}
+Specify Weighted prediction for P-frames.
+Deprecated in favor of @var{x264opts} (see @var{weightp} libx264 option).
+
+@item x264opts @var{options}
+Allow to set any x264 option, see x264 --fullhelp for a list.
+
+@var{options} is a list of @var{key}=@var{value} couples separated by
+":".
+@end table
+
+For example to specify libx264 encoding options with @command{ffmpeg}:
+@example
+ffmpeg -i foo.mpg -vcodec libx264 -x264opts keyint=123:min-keyint=20 -an out.mkv
+@end example
+
+For more information about libx264 and the supported options see:
+@url{http://www.videolan.org/developers/x264.html}
+
+@c man end VIDEO ENCODERS
diff --git a/doc/errno.txt b/doc/errno.txt
new file mode 100644
index 0000000..31cab26
--- /dev/null
+++ b/doc/errno.txt
@@ -0,0 +1,174 @@
+The following table lists most error codes found in various operating
+systems supported by FFmpeg.
+
+                             OS
+Code             Std    F  LBMWwb Text (YMMV)
+
+E2BIG            POSIX     ++++++  Argument list too long
+EACCES           POSIX     ++++++  Permission denied
+EADDRINUSE       POSIX     +++..+  Address in use
+EADDRNOTAVAIL    POSIX     +++..+  Cannot assign requested address
+EADV                       +.....  Advertise error
+EAFNOSUPPORT     POSIX     +++..+  Address family not supported
+EAGAIN           POSIX  +  ++++++  Resource temporarily unavailable
+EALREADY         POSIX     +++..+  Operation already in progress
+EAUTH                      .++...  Authentication error
+EBADARCH                   ..+...  Bad CPU type in executable
+EBADE                      +.....  Invalid exchange
+EBADEXEC                   ..+...  Bad executable
+EBADF            POSIX     ++++++  Bad file descriptor
+EBADFD                     +.....  File descriptor in bad state
+EBADMACHO                  ..+...  Malformed Macho file
+EBADMSG          POSIX     ++4...  Bad message
+EBADR                      +.....  Invalid request descriptor
+EBADRPC                    .++...  RPC struct is bad
+EBADRQC                    +.....  Invalid request code
+EBADSLT                    +.....  Invalid slot
+EBFONT                     +.....  Bad font file format
+EBUSY            POSIX  -  ++++++  Device or resource busy
+ECANCELED        POSIX     +++...  Operation canceled
+ECHILD           POSIX     ++++++  No child processes
+ECHRNG                     +.....  Channel number out of range
+ECOMM                      +.....  Communication error on send
+ECONNABORTED     POSIX     +++..+  Software caused connection abort
+ECONNREFUSED     POSIX  -  +++ss+  Connection refused
+ECONNRESET       POSIX     +++..+  Connection reset
+EDEADLK          POSIX     ++++++  Resource deadlock avoided
+EDEADLOCK                  +..++.  File locking deadlock error
+EDESTADDRREQ     POSIX     +++...  Destination address required
+EDEVERR                    ..+...  Device error
+EDOM             C89    -  ++++++  Numerical argument out of domain
+EDOOFUS                    .F....  Programming error
+EDOTDOT                    +.....  RFS specific error
+EDQUOT           POSIX     +++...  Disc quota exceeded
+EEXIST           POSIX     ++++++  File exists
+EFAULT           POSIX  -  ++++++  Bad address
+EFBIG            POSIX  -  ++++++  File too large
+EFTYPE                     .++...  Inappropriate file type or format
+EHOSTDOWN                  +++...  Host is down
+EHOSTUNREACH     POSIX     +++..+  No route to host
+EHWPOISON                  +.....  Memory page has hardware error
+EIDRM            POSIX     +++...  Identifier removed
+EILSEQ           C99       ++++++  Illegal byte sequence
+EINPROGRESS      POSIX  -  +++ss+  Operation in progress
+EINTR            POSIX  -  ++++++  Interrupted system call
+EINVAL           POSIX  +  ++++++  Invalid argument
+EIO              POSIX  +  ++++++  I/O error
+EISCONN          POSIX     +++..+  Socket is already connected
+EISDIR           POSIX     ++++++  Is a directory
+EISNAM                     +.....  Is a named type file
+EKEYEXPIRED                +.....  Key has expired
+EKEYREJECTED               +.....  Key was rejected by service
+EKEYREVOKED                +.....  Key has been revoked
+EL2HLT                     +.....  Level 2 halted
+EL2NSYNC                   +.....  Level 2 not synchronized
+EL3HLT                     +.....  Level 3 halted
+EL3RST                     +.....  Level 3 reset
+ELIBACC                    +.....  Can not access a needed shared library
+ELIBBAD                    +.....  Accessing a corrupted shared library
+ELIBEXEC                   +.....  Cannot exec a shared library directly
+ELIBMAX                    +.....  Too many shared libraries
+ELIBSCN                    +.....  .lib section in a.out corrupted
+ELNRNG                     +.....  Link number out of range
+ELOOP            POSIX     +++..+  Too many levels of symbolic links
+EMEDIUMTYPE                +.....  Wrong medium type
+EMFILE           POSIX     ++++++  Too many open files
+EMLINK           POSIX     ++++++  Too many links
+EMSGSIZE         POSIX     +++..+  Message too long
+EMULTIHOP        POSIX     ++4...  Multihop attempted
+ENAMETOOLONG     POSIX  -  ++++++  Filen ame too long
+ENAVAIL                    +.....  No XENIX semaphores available
+ENEEDAUTH                  .++...  Need authenticator
+ENETDOWN         POSIX     +++..+  Network is down
+ENETRESET        SUSv3     +++..+  Network dropped connection on reset
+ENETUNREACH      POSIX     +++..+  Network unreachable
+ENFILE           POSIX     ++++++  Too many open files in system
+ENOANO                     +.....  No anode
+ENOATTR                    .++...  Attribute not found
+ENOBUFS          POSIX  -  +++..+  No buffer space available
+ENOCSI                     +.....  No CSI structure available
+ENODATA          XSR       +N4...  No message available
+ENODEV           POSIX  -  ++++++  No such device
+ENOENT           POSIX  -  ++++++  No such file or directory
+ENOEXEC          POSIX     ++++++  Exec format error
+ENOFILE                    ...++.  No such file or directory
+ENOKEY                     +.....  Required key not available
+ENOLCK           POSIX     ++++++  No locks available
+ENOLINK          POSIX     ++4...  Link has been severed
+ENOMEDIUM                  +.....  No medium found
+ENOMEM           POSIX     ++++++  Not enough space
+ENOMSG           POSIX     +++..+  No message of desired type
+ENONET                     +.....  Machine is not on the network
+ENOPKG                     +.....  Package not installed
+ENOPROTOOPT      POSIX     +++..+  Protocol not available
+ENOSPC           POSIX     ++++++  No space left on device
+ENOSR            XSR       +N4...  No STREAM resources
+ENOSTR           XSR       +N4...  Not a STREAM
+ENOSYS           POSIX  +  ++++++  Function not implemented
+ENOTBLK                    +++...  Block device required
+ENOTCONN         POSIX     +++..+  Socket is not connected
+ENOTDIR          POSIX     ++++++  Not a directory
+ENOTEMPTY        POSIX     ++++++  Directory not empty
+ENOTNAM                    +.....  Not a XENIX named type file
+ENOTRECOVERABLE  SUSv4  -  +.....  State not recoverable
+ENOTSOCK         POSIX     +++..+  Socket operation on non-socket
+ENOTSUP          POSIX     +++...  Operation not supported
+ENOTTY           POSIX     ++++++  Inappropriate I/O control operation
+ENOTUNIQ                   +.....  Name not unique on network
+ENXIO            POSIX     ++++++  No such device or address
+EOPNOTSUPP       POSIX     +++..+  Operation not supported (on socket)
+EOVERFLOW        POSIX     +++..+  Value too large to be stored in data type
+EOWNERDEAD       SUSv4     +.....  Owner died
+EPERM            POSIX  -  ++++++  Operation not permitted
+EPFNOSUPPORT               +++..+  Protocol family not supported
+EPIPE            POSIX  -  ++++++  Broken pipe
+EPROCLIM                   .++...  Too many processes
+EPROCUNAVAIL               .++...  Bad procedure for program
+EPROGMISMATCH              .++...  Program version wrong
+EPROGUNAVAIL               .++...  RPC prog. not avail
+EPROTO           POSIX     ++4...  Protocol error
+EPROTONOSUPPORT  POSIX  -  +++ss+  Protocol not supported
+EPROTOTYPE       POSIX     +++..+  Protocol wrong type for socket
+EPWROFF                    ..+...  Device power is off
+ERANGE           C89    -  ++++++  Result too large
+EREMCHG                    +.....  Remote address changed
+EREMOTE                    +++...  Object is remote
+EREMOTEIO                  +.....  Remote I/O error
+ERESTART                   +.....  Interrupted system call should be restarted
+ERFKILL                    +.....  Operation not possible due to RF-kill
+EROFS            POSIX     ++++++  Read-only file system
+ERPCMISMATCH               .++...  RPC version wrong
+ESHLIBVERS                 ..+...  Shared library version mismatch
+ESHUTDOWN                  +++..+  Cannot send after socket shutdown
+ESOCKTNOSUPPORT            +++...  Socket type not supported
+ESPIPE           POSIX     ++++++  Illegal seek
+ESRCH            POSIX     ++++++  No such process
+ESRMNT                     +.....  Srmount error
+ESTALE           POSIX     +++..+  Stale NFS file handle
+ESTRPIPE                   +.....  Streams pipe error
+ETIME            XSR       +N4...  Stream ioctl timeout
+ETIMEDOUT        POSIX  -  +++ss+  Connection timed out
+ETOOMANYREFS               +++...  Too many references: cannot splice
+ETXTBSY          POSIX     +++...  Text file busy
+EUCLEAN                    +.....  Structure needs cleaning
+EUNATCH                    +.....  Protocol driver not attached
+EUSERS                     +++...  Too many users
+EWOULDBLOCK      POSIX     +++..+  Operation would block
+EXDEV            POSIX     ++++++  Cross-device link
+EXFULL                     +.....  Exchange full
+
+Notations:
+
+F: used in FFmpeg (-: a few times, +: a lot)
+
+SUSv3: Single Unix Specification, version 3
+SUSv4: Single Unix Specification, version 4
+XSR: XSI STREAMS (obsolete)
+
+OS: availability on some supported operating systems
+L: GNU/Linux
+B: BSD (F: FreeBSD, N: NetBSD)
+M: MacOS X
+W: Microsoft Windows (s: emulated with winsock, see libavformat/network.h)
+w: Mingw32 (3.17) and Mingw64 (2.0.1)
+b: BeOS
diff --git a/doc/eval.texi b/doc/eval.texi
index e1fd7ee..1ea89d6 100644
--- a/doc/eval.texi
+++ b/doc/eval.texi
@@ -1,7 +1,7 @@
 @chapter Expression Evaluation
 @c man begin EXPRESSION EVALUATION
 
-When evaluating an arithmetic expression, Libav uses an internal
+When evaluating an arithmetic expression, FFmpeg uses an internal
 formula evaluator, implemented through the @file{libavutil/eval.h}
 interface.
 
@@ -21,37 +21,84 @@
 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 acos(x)
+Compute arccosine of @var{x}.
+
 @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 gauss(x)
+Compute Gauss function of @var{x}, corresponding to
+@code{exp(-x*x/2) / sqrt(2*PI)}.
+
 @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 max(x, y)
+Return the maximum between @var{x} and @var{y}.
+
 @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
@@ -81,21 +128,70 @@
 
 @item not(expr)
 Return 1.0 if @var{expr} is zero, 0.0 otherwise.
+
+@item pow(x, y)
+Compute the power of @var{x} elevated @var{y}, it is equivalent to
+"(@var{x})^(@var{y})".
+
+@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.
 @end table
 
-Note that:
+The following constants are available:
+@table @option
+@item PI
+area of the unit disc, approximately 3.14
+@item E
+exp(1) (Euler's number), approximately 2.718
+@item PHI
+golden ratio (1+sqrt(5))/2, approximately 1.618
+@end table
+
+Assuming that an expression is considered "true" if it has a non-zero
+value, note that:
 
 @code{*} works like AND
 
 @code{+} works like OR
 
-thus
+and the construct:
 @example
 if A then B else C
 @end example
 is equivalent to
 @example
-A*B + not(A)*C
+if(A,B) + ifnot(A,C)
 @end example
 
 In your C code, you can extend the list of unary and binary functions,
diff --git a/doc/examples/Makefile b/doc/examples/Makefile
new file mode 100644
index 0000000..36c949a
--- /dev/null
+++ b/doc/examples/Makefile
@@ -0,0 +1,36 @@
+# use pkg-config for getting CFLAGS and LDLIBS
+FFMPEG_LIBS=    libavdevice                        \
+                libavformat                        \
+                libavfilter                        \
+                libavcodec                         \
+                libswresample                      \
+                libswscale                         \
+                libavutil                          \
+
+CFLAGS += -Wall -O2 -g
+CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
+LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
+
+EXAMPLES=       decoding_encoding                  \
+                demuxing                           \
+                filtering_video                    \
+                filtering_audio                    \
+                metadata                           \
+                muxing                             \
+                scaling_video                      \
+
+OBJS=$(addsuffix .o,$(EXAMPLES))
+
+# the following examples make explicit use of the math library
+decoding_encoding: LDLIBS += -lm
+muxing:            LDLIBS += -lm
+
+.phony: all clean-test clean
+
+all: $(OBJS) $(EXAMPLES)
+
+clean-test:
+	$(RM) test*.pgm test.h264 test.mp2 test.sw test.mpg
+
+clean: clean-test
+	$(RM) $(EXAMPLES) $(OBJS)
diff --git a/doc/examples/decoding_encoding.c b/doc/examples/decoding_encoding.c
new file mode 100644
index 0000000..24b9b6b
--- /dev/null
+++ b/doc/examples/decoding_encoding.c
@@ -0,0 +1,635 @@
+/*
+ * Copyright (c) 2001 Fabrice Bellard
+ *
+ * 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.
+ */
+
+/**
+ * @file
+ * libavcodec API use example.
+ *
+ * Note that libavcodec only handles codecs (mpeg, mpeg4, etc...),
+ * not file formats (avi, vob, mp4, mov, mkv, mxf, flv, mpegts, mpegps, etc...). See library 'libavformat' for the
+ * format handling
+ */
+
+#include <math.h>
+
+#include <libavutil/opt.h>
+#include <libavcodec/avcodec.h>
+#include <libavutil/audioconvert.h>
+#include <libavutil/common.h>
+#include <libavutil/imgutils.h>
+#include <libavutil/mathematics.h>
+#include <libavutil/samplefmt.h>
+
+#define INBUF_SIZE 4096
+#define AUDIO_INBUF_SIZE 20480
+#define AUDIO_REFILL_THRESH 4096
+
+/* check that a given sample format is supported by the encoder */
+static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
+{
+    const enum AVSampleFormat *p = codec->sample_fmts;
+
+    while (*p != AV_SAMPLE_FMT_NONE) {
+        if (*p == sample_fmt)
+            return 1;
+        p++;
+    }
+    return 0;
+}
+
+/* just pick the highest supported samplerate */
+static int select_sample_rate(AVCodec *codec)
+{
+    const int *p;
+    int best_samplerate = 0;
+
+    if (!codec->supported_samplerates)
+        return 44100;
+
+    p = codec->supported_samplerates;
+    while (*p) {
+        best_samplerate = FFMAX(*p, best_samplerate);
+        p++;
+    }
+    return best_samplerate;
+}
+
+/* select layout with the highest channel count */
+static int select_channel_layout(AVCodec *codec)
+{
+    const uint64_t *p;
+    uint64_t best_ch_layout = 0;
+    int best_nb_channells   = 0;
+
+    if (!codec->channel_layouts)
+        return AV_CH_LAYOUT_STEREO;
+
+    p = codec->channel_layouts;
+    while (*p) {
+        int nb_channels = av_get_channel_layout_nb_channels(*p);
+
+        if (nb_channels > best_nb_channells) {
+            best_ch_layout    = *p;
+            best_nb_channells = nb_channels;
+        }
+        p++;
+    }
+    return best_ch_layout;
+}
+
+/*
+ * Audio encoding example
+ */
+static void audio_encode_example(const char *filename)
+{
+    AVCodec *codec;
+    AVCodecContext *c= NULL;
+    AVFrame *frame;
+    AVPacket pkt;
+    int i, j, k, ret, got_output;
+    int buffer_size;
+    FILE *f;
+    uint16_t *samples;
+    float t, tincr;
+
+    printf("Encode audio file %s\n", filename);
+
+    /* find the MP2 encoder */
+    codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
+    if (!codec) {
+        fprintf(stderr, "Codec not found\n");
+        exit(1);
+    }
+
+    c = avcodec_alloc_context3(codec);
+
+    /* put sample parameters */
+    c->bit_rate = 64000;
+
+    /* check that the encoder supports s16 pcm input */
+    c->sample_fmt = AV_SAMPLE_FMT_S16;
+    if (!check_sample_fmt(codec, c->sample_fmt)) {
+        fprintf(stderr, "Encoder does not support sample format %s",
+                av_get_sample_fmt_name(c->sample_fmt));
+        exit(1);
+    }
+
+    /* select other audio parameters supported by the encoder */
+    c->sample_rate    = select_sample_rate(codec);
+    c->channel_layout = select_channel_layout(codec);
+    c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);
+
+    /* open it */
+    if (avcodec_open2(c, codec, NULL) < 0) {
+        fprintf(stderr, "Could not open codec\n");
+        exit(1);
+    }
+
+    f = fopen(filename, "wb");
+    if (!f) {
+        fprintf(stderr, "Could not open %s\n", filename);
+        exit(1);
+    }
+
+    /* frame containing input raw audio */
+    frame = avcodec_alloc_frame();
+    if (!frame) {
+        fprintf(stderr, "Could not allocate audio frame\n");
+        exit(1);
+    }
+
+    frame->nb_samples     = c->frame_size;
+    frame->format         = c->sample_fmt;
+    frame->channel_layout = c->channel_layout;
+
+    /* the codec gives us the frame size, in samples,
+     * we calculate the size of the samples buffer in bytes */
+    buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
+                                             c->sample_fmt, 0);
+    samples = av_malloc(buffer_size);
+    if (!samples) {
+        fprintf(stderr, "Could not allocate %d bytes for samples buffer\n",
+                buffer_size);
+        exit(1);
+    }
+    /* setup the data pointers in the AVFrame */
+    ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
+                                   (const uint8_t*)samples, buffer_size, 0);
+    if (ret < 0) {
+        fprintf(stderr, "Could not setup audio frame\n");
+        exit(1);
+    }
+
+    /* encode a single tone sound */
+    t = 0;
+    tincr = 2 * M_PI * 440.0 / c->sample_rate;
+    for(i=0;i<200;i++) {
+        av_init_packet(&pkt);
+        pkt.data = NULL; // packet data will be allocated by the encoder
+        pkt.size = 0;
+
+        for (j = 0; j < c->frame_size; j++) {
+            samples[2*j] = (int)(sin(t) * 10000);
+
+            for (k = 1; k < c->channels; k++)
+                samples[2*j + k] = samples[2*j];
+            t += tincr;
+        }
+        /* encode the samples */
+        ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
+        if (ret < 0) {
+            fprintf(stderr, "Error encoding audio frame\n");
+            exit(1);
+        }
+        if (got_output) {
+            fwrite(pkt.data, 1, pkt.size, f);
+            av_free_packet(&pkt);
+        }
+    }
+
+    /* get the delayed frames */
+    for (got_output = 1; got_output; i++) {
+        ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output);
+        if (ret < 0) {
+            fprintf(stderr, "Error encoding frame\n");
+            exit(1);
+        }
+
+        if (got_output) {
+            fwrite(pkt.data, 1, pkt.size, f);
+            av_free_packet(&pkt);
+        }
+    }
+    fclose(f);
+
+    av_freep(&samples);
+    avcodec_free_frame(&frame);
+    avcodec_close(c);
+    av_free(c);
+}
+
+/*
+ * Audio decoding.
+ */
+static void audio_decode_example(const char *outfilename, const char *filename)
+{
+    AVCodec *codec;
+    AVCodecContext *c= NULL;
+    int len;
+    FILE *f, *outfile;
+    uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
+    AVPacket avpkt;
+    AVFrame *decoded_frame = NULL;
+
+    av_init_packet(&avpkt);
+
+    printf("Decode audio file %s to %s\n", filename, outfilename);
+
+    /* find the mpeg audio decoder */
+    codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
+    if (!codec) {
+        fprintf(stderr, "Codec not found\n");
+        exit(1);
+    }
+
+    c = avcodec_alloc_context3(codec);
+
+    /* open it */
+    if (avcodec_open2(c, codec, NULL) < 0) {
+        fprintf(stderr, "Could not open codec\n");
+        exit(1);
+    }
+
+    f = fopen(filename, "rb");
+    if (!f) {
+        fprintf(stderr, "Could not open %s\n", filename);
+        exit(1);
+    }
+    outfile = fopen(outfilename, "wb");
+    if (!outfile) {
+        av_free(c);
+        exit(1);
+    }
+
+    /* decode until eof */
+    avpkt.data = inbuf;
+    avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
+
+    while (avpkt.size > 0) {
+        int got_frame = 0;
+
+        if (!decoded_frame) {
+            if (!(decoded_frame = avcodec_alloc_frame())) {
+                fprintf(stderr, "Could not allocate audio frame\n");
+                exit(1);
+            }
+        } else
+            avcodec_get_frame_defaults(decoded_frame);
+
+        len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
+        if (len < 0) {
+            fprintf(stderr, "Error while decoding\n");
+            exit(1);
+        }
+        if (got_frame) {
+            /* if a frame has been decoded, output it */
+            int data_size = av_samples_get_buffer_size(NULL, c->channels,
+                                                       decoded_frame->nb_samples,
+                                                       c->sample_fmt, 1);
+            fwrite(decoded_frame->data[0], 1, data_size, outfile);
+        }
+        avpkt.size -= len;
+        avpkt.data += len;
+        avpkt.dts =
+        avpkt.pts = AV_NOPTS_VALUE;
+        if (avpkt.size < AUDIO_REFILL_THRESH) {
+            /* Refill the input buffer, to avoid trying to decode
+             * incomplete frames. Instead of this, one could also use
+             * a parser, or use a proper container format through
+             * libavformat. */
+            memmove(inbuf, avpkt.data, avpkt.size);
+            avpkt.data = inbuf;
+            len = fread(avpkt.data + avpkt.size, 1,
+                        AUDIO_INBUF_SIZE - avpkt.size, f);
+            if (len > 0)
+                avpkt.size += len;
+        }
+    }
+
+    fclose(outfile);
+    fclose(f);
+
+    avcodec_close(c);
+    av_free(c);
+    avcodec_free_frame(&decoded_frame);
+}
+
+/*
+ * Video encoding example
+ */
+static void video_encode_example(const char *filename, int codec_id)
+{
+    AVCodec *codec;
+    AVCodecContext *c= NULL;
+    int i, ret, x, y, got_output;
+    FILE *f;
+    AVFrame *frame;
+    AVPacket pkt;
+    uint8_t endcode[] = { 0, 0, 1, 0xb7 };
+
+    printf("Encode video file %s\n", filename);
+
+    /* find the mpeg1 video encoder */
+    codec = avcodec_find_encoder(codec_id);
+    if (!codec) {
+        fprintf(stderr, "Codec not found\n");
+        exit(1);
+    }
+
+    c = avcodec_alloc_context3(codec);
+
+    /* put sample parameters */
+    c->bit_rate = 400000;
+    /* resolution must be a multiple of two */
+    c->width = 352;
+    c->height = 288;
+    /* frames per second */
+    c->time_base= (AVRational){1,25};
+    c->gop_size = 10; /* emit one intra frame every ten frames */
+    c->max_b_frames=1;
+    c->pix_fmt = AV_PIX_FMT_YUV420P;
+
+    if(codec_id == AV_CODEC_ID_H264)
+        av_opt_set(c->priv_data, "preset", "slow", 0);
+
+    /* open it */
+    if (avcodec_open2(c, codec, NULL) < 0) {
+        fprintf(stderr, "Could not open codec\n");
+        exit(1);
+    }
+
+    f = fopen(filename, "wb");
+    if (!f) {
+        fprintf(stderr, "Could not open %s\n", filename);
+        exit(1);
+    }
+
+    frame = avcodec_alloc_frame();
+    if (!frame) {
+        fprintf(stderr, "Could not allocate video frame\n");
+        exit(1);
+    }
+    frame->format = c->pix_fmt;
+    frame->width  = c->width;
+    frame->height = c->height;
+
+    /* the image can be allocated by any means and av_image_alloc() is
+     * just the most convenient way if av_malloc() is to be used */
+    ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
+                         c->pix_fmt, 32);
+    if (ret < 0) {
+        fprintf(stderr, "Could not allocate raw picture buffer\n");
+        exit(1);
+    }
+
+    /* encode 1 second of video */
+    for(i=0;i<25;i++) {
+        av_init_packet(&pkt);
+        pkt.data = NULL;    // packet data will be allocated by the encoder
+        pkt.size = 0;
+
+        fflush(stdout);
+        /* prepare a dummy image */
+        /* Y */
+        for(y=0;y<c->height;y++) {
+            for(x=0;x<c->width;x++) {
+                frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
+            }
+        }
+
+        /* Cb and Cr */
+        for(y=0;y<c->height/2;y++) {
+            for(x=0;x<c->width/2;x++) {
+                frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
+                frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
+            }
+        }
+
+        frame->pts = i;
+
+        /* encode the image */
+        ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
+        if (ret < 0) {
+            fprintf(stderr, "Error encoding frame\n");
+            exit(1);
+        }
+
+        if (got_output) {
+            printf("Write frame %3d (size=%5d)\n", i, pkt.size);
+            fwrite(pkt.data, 1, pkt.size, f);
+            av_free_packet(&pkt);
+        }
+    }
+
+    /* get the delayed frames */
+    for (got_output = 1; got_output; i++) {
+        fflush(stdout);
+
+        ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
+        if (ret < 0) {
+            fprintf(stderr, "Error encoding frame\n");
+            exit(1);
+        }
+
+        if (got_output) {
+            printf("Write frame %3d (size=%5d)\n", i, pkt.size);
+            fwrite(pkt.data, 1, pkt.size, f);
+            av_free_packet(&pkt);
+        }
+    }
+
+    /* add sequence end code to have a real mpeg file */
+    fwrite(endcode, 1, sizeof(endcode), f);
+    fclose(f);
+
+    avcodec_close(c);
+    av_free(c);
+    av_freep(&frame->data[0]);
+    avcodec_free_frame(&frame);
+    printf("\n");
+}
+
+/*
+ * Video decoding example
+ */
+
+static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
+                     char *filename)
+{
+    FILE *f;
+    int i;
+
+    f=fopen(filename,"w");
+    fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
+    for(i=0;i<ysize;i++)
+        fwrite(buf + i * wrap,1,xsize,f);
+    fclose(f);
+}
+
+static void video_decode_example(const char *outfilename, const char *filename)
+{
+    AVCodec *codec;
+    AVCodecContext *c= NULL;
+    int frame, got_picture, len;
+    FILE *f;
+    AVFrame *picture;
+    uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
+    char buf[1024];
+    AVPacket avpkt;
+
+    av_init_packet(&avpkt);
+
+    /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
+    memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+
+    printf("Decode video file %s to %s\n", filename, outfilename);
+
+    /* find the mpeg1 video decoder */
+    codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
+    if (!codec) {
+        fprintf(stderr, "Codec not found\n");
+        exit(1);
+    }
+
+    c = avcodec_alloc_context3(codec);
+    if(codec->capabilities&CODEC_CAP_TRUNCATED)
+        c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
+
+    /* For some codecs, such as msmpeg4 and mpeg4, width and height
+       MUST be initialized there because this information is not
+       available in the bitstream. */
+
+    /* open it */
+    if (avcodec_open2(c, codec, NULL) < 0) {
+        fprintf(stderr, "Could not open codec\n");
+        exit(1);
+    }
+
+    /* the codec gives us the frame size, in samples */
+
+    f = fopen(filename, "rb");
+    if (!f) {
+        fprintf(stderr, "Could not open %s\n", filename);
+        exit(1);
+    }
+
+    picture = avcodec_alloc_frame();
+    if (!picture) {
+        fprintf(stderr, "Could not allocate video frame\n");
+        exit(1);
+    }
+
+    frame = 0;
+    for(;;) {
+        avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
+        if (avpkt.size == 0)
+            break;
+
+        /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
+           and this is the only method to use them because you cannot
+           know the compressed data size before analysing it.
+
+           BUT some other codecs (msmpeg4, mpeg4) are inherently frame
+           based, so you must call them with all the data for one
+           frame exactly. You must also initialize 'width' and
+           'height' before initializing them. */
+
+        /* NOTE2: some codecs allow the raw parameters (frame size,
+           sample rate) to be changed at any frame. We handle this, so
+           you should also take care of it */
+
+        /* here, we use a stream based decoder (mpeg1video), so we
+           feed decoder and see if it could decode a frame */
+        avpkt.data = inbuf;
+        while (avpkt.size > 0) {
+            len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
+            if (len < 0) {
+                fprintf(stderr, "Error while decoding frame %d\n", frame);
+                exit(1);
+            }
+            if (got_picture) {
+                printf("Saving frame %3d\n", frame);
+                fflush(stdout);
+
+                /* the picture is allocated by the decoder. no need to
+                   free it */
+                snprintf(buf, sizeof(buf), outfilename, frame);
+                pgm_save(picture->data[0], picture->linesize[0],
+                         c->width, c->height, buf);
+                frame++;
+            }
+            avpkt.size -= len;
+            avpkt.data += len;
+        }
+    }
+
+    /* some codecs, such as MPEG, transmit the I and P frame with a
+       latency of one frame. You must do the following to have a
+       chance to get the last frame of the video */
+    avpkt.data = NULL;
+    avpkt.size = 0;
+    len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
+    if (got_picture) {
+        printf("Saving last frame %3d\n", frame);
+        fflush(stdout);
+
+        /* the picture is allocated by the decoder. no need to
+           free it */
+        snprintf(buf, sizeof(buf), outfilename, frame);
+        pgm_save(picture->data[0], picture->linesize[0],
+                 c->width, c->height, buf);
+        frame++;
+    }
+
+    fclose(f);
+
+    avcodec_close(c);
+    av_free(c);
+    avcodec_free_frame(&picture);
+    printf("\n");
+}
+
+int main(int argc, char **argv)
+{
+    const char *output_type;
+
+    /* register all the codecs */
+    avcodec_register_all();
+
+    if (argc < 2) {
+        printf("usage: %s output_type\n"
+               "API example program to decode/encode a media stream with libavcodec.\n"
+               "This program generates a synthetic stream and encodes it to a file\n"
+               "named test.h264, test.mp2 or test.mpg depending on output_type.\n"
+               "The encoded stream is then decoded and written to a raw data output\n."
+               "output_type must be choosen between 'h264', 'mp2', 'mpg'\n",
+               argv[0]);
+        return 1;
+    }
+    output_type = argv[1];
+
+    if (!strcmp(output_type, "h264")) {
+        video_encode_example("test.h264", AV_CODEC_ID_H264);
+    } else if (!strcmp(output_type, "mp2")) {
+        audio_encode_example("test.mp2");
+        audio_decode_example("test.sw", "test.mp2");
+    } else if (!strcmp(output_type, "mpg")) {
+        video_encode_example("test.mpg", AV_CODEC_ID_MPEG1VIDEO);
+        video_decode_example("test%02d.pgm", "test.mpg");
+    } else {
+        fprintf(stderr, "Invalid output type '%s', choose between 'h264', 'mp2', or 'mpg'\n",
+                output_type);
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/doc/examples/demuxing.c b/doc/examples/demuxing.c
new file mode 100644
index 0000000..0e0015e
--- /dev/null
+++ b/doc/examples/demuxing.c
@@ -0,0 +1,339 @@
+/*
+ * 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.
+ */
+
+/**
+ * @file
+ * libavformat demuxing API use example.
+ *
+ * Show how to use the libavformat and libavcodec API to demux and
+ * decode audio and video data.
+ */
+
+#include <libavutil/imgutils.h>
+#include <libavutil/samplefmt.h>
+#include <libavutil/timestamp.h>
+#include <libavformat/avformat.h>
+
+static AVFormatContext *fmt_ctx = NULL;
+static AVCodecContext *video_dec_ctx = NULL, *audio_dec_ctx;
+static AVStream *video_stream = NULL, *audio_stream = NULL;
+static const char *src_filename = NULL;
+static const char *video_dst_filename = NULL;
+static const char *audio_dst_filename = NULL;
+static FILE *video_dst_file = NULL;
+static FILE *audio_dst_file = NULL;
+
+static uint8_t *video_dst_data[4] = {NULL};
+static int      video_dst_linesize[4];
+static int video_dst_bufsize;
+
+static uint8_t **audio_dst_data = NULL;
+static int       audio_dst_linesize;
+static int audio_dst_bufsize;
+
+static int video_stream_idx = -1, audio_stream_idx = -1;
+static AVFrame *frame = NULL;
+static AVPacket pkt;
+static int video_frame_count = 0;
+static int audio_frame_count = 0;
+
+static int decode_packet(int *got_frame, int cached)
+{
+    int ret = 0;
+
+    if (pkt.stream_index == video_stream_idx) {
+        /* decode video frame */
+        ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
+        if (ret < 0) {
+            fprintf(stderr, "Error decoding video frame\n");
+            return ret;
+        }
+
+        if (*got_frame) {
+            printf("video_frame%s n:%d coded_n:%d pts:%s\n",
+                   cached ? "(cached)" : "",
+                   video_frame_count++, frame->coded_picture_number,
+                   av_ts2timestr(frame->pts, &video_dec_ctx->time_base));
+
+            /* copy decoded frame to destination buffer:
+             * this is required since rawvideo expects non aligned data */
+            av_image_copy(video_dst_data, video_dst_linesize,
+                          (const uint8_t **)(frame->data), frame->linesize,
+                          video_dec_ctx->pix_fmt, video_dec_ctx->width, video_dec_ctx->height);
+
+            /* write to rawvideo file */
+            fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file);
+        }
+    } else if (pkt.stream_index == audio_stream_idx) {
+        /* decode audio frame */
+        ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt);
+        if (ret < 0) {
+            fprintf(stderr, "Error decoding audio frame\n");
+            return ret;
+        }
+
+        if (*got_frame) {
+            printf("audio_frame%s n:%d nb_samples:%d pts:%s\n",
+                   cached ? "(cached)" : "",
+                   audio_frame_count++, frame->nb_samples,
+                   av_ts2timestr(frame->pts, &audio_dec_ctx->time_base));
+
+            ret = av_samples_alloc(audio_dst_data, &audio_dst_linesize, frame->channels,
+                                   frame->nb_samples, frame->format, 1);
+            if (ret < 0) {
+                fprintf(stderr, "Could not allocate audio buffer\n");
+                return AVERROR(ENOMEM);
+            }
+
+            /* TODO: extend return code of the av_samples_* functions so that this call is not needed */
+            audio_dst_bufsize =
+                av_samples_get_buffer_size(NULL, frame->channels,
+                                           frame->nb_samples, frame->format, 1);
+
+            /* copy audio data to destination buffer:
+             * this is required since rawaudio expects non aligned data */
+            av_samples_copy(audio_dst_data, frame->data, 0, 0,
+                            frame->nb_samples, frame->channels, frame->format);
+
+            /* write to rawaudio file */
+            fwrite(audio_dst_data[0], 1, audio_dst_bufsize, audio_dst_file);
+            av_freep(&audio_dst_data[0]);
+        }
+    }
+
+    return ret;
+}
+
+static int open_codec_context(int *stream_idx,
+                              AVFormatContext *fmt_ctx, enum AVMediaType type)
+{
+    int ret;
+    AVStream *st;
+    AVCodecContext *dec_ctx = NULL;
+    AVCodec *dec = NULL;
+
+    ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
+    if (ret < 0) {
+        fprintf(stderr, "Could not find %s stream in input file '%s'\n",
+                av_get_media_type_string(type), src_filename);
+        return ret;
+    } else {
+        *stream_idx = ret;
+        st = fmt_ctx->streams[*stream_idx];
+
+        /* find decoder for the stream */
+        dec_ctx = st->codec;
+        dec = avcodec_find_decoder(dec_ctx->codec_id);
+        if (!dec) {
+            fprintf(stderr, "Failed to find %s codec\n",
+                    av_get_media_type_string(type));
+            return ret;
+        }
+
+        if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
+            fprintf(stderr, "Failed to open %s codec\n",
+                    av_get_media_type_string(type));
+            return ret;
+        }
+    }
+
+    return 0;
+}
+
+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 is not supported as output format\n",
+            av_get_sample_fmt_name(sample_fmt));
+    return -1;
+}
+
+int main (int argc, char **argv)
+{
+    int ret = 0, got_frame;
+
+    if (argc != 4) {
+        fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n"
+                "API example program to show how to read frames from an input file.\n"
+                "This program reads frames from a file, decodes them, and writes decoded\n"
+                "video frames to a rawvideo file named video_output_file, and decoded\n"
+                "audio frames to a rawaudio file named audio_output_file.\n"
+                "\n", argv[0]);
+        exit(1);
+    }
+    src_filename = argv[1];
+    video_dst_filename = argv[2];
+    audio_dst_filename = argv[3];
+
+    /* register all formats and codecs */
+    av_register_all();
+
+    /* open input file, and allocated format context */
+    if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
+        fprintf(stderr, "Could not open source file %s\n", src_filename);
+        exit(1);
+    }
+
+    /* retrieve stream information */
+    if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
+        fprintf(stderr, "Could not find stream information\n");
+        exit(1);
+    }
+
+    if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) {
+        video_stream = fmt_ctx->streams[video_stream_idx];
+        video_dec_ctx = video_stream->codec;
+
+        video_dst_file = fopen(video_dst_filename, "wb");
+        if (!video_dst_file) {
+            fprintf(stderr, "Could not open destination file %s\n", video_dst_filename);
+            ret = 1;
+            goto end;
+        }
+
+        /* allocate image where the decoded image will be put */
+        ret = av_image_alloc(video_dst_data, video_dst_linesize,
+                             video_dec_ctx->width, video_dec_ctx->height,
+                             video_dec_ctx->pix_fmt, 1);
+        if (ret < 0) {
+            fprintf(stderr, "Could not allocate raw video buffer\n");
+            goto end;
+        }
+        video_dst_bufsize = ret;
+    }
+
+    /* dump input information to stderr */
+    av_dump_format(fmt_ctx, 0, src_filename, 0);
+
+    if (open_codec_context(&audio_stream_idx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) {
+        int nb_planes;
+
+        audio_stream = fmt_ctx->streams[audio_stream_idx];
+        audio_dec_ctx = audio_stream->codec;
+        audio_dst_file = fopen(audio_dst_filename, "wb");
+        if (!audio_dst_file) {
+            fprintf(stderr, "Could not open destination file %s\n", video_dst_filename);
+            ret = 1;
+            goto end;
+        }
+
+        nb_planes = av_sample_fmt_is_planar(audio_dec_ctx->sample_fmt) ?
+            audio_dec_ctx->channels : 1;
+        audio_dst_data = av_mallocz(sizeof(uint8_t *) * nb_planes);
+        if (!audio_dst_data) {
+            fprintf(stderr, "Could not allocate audio data buffers\n");
+            ret = AVERROR(ENOMEM);
+            goto end;
+        }
+    }
+
+    if (!audio_stream && !video_stream) {
+        fprintf(stderr, "Could not find audio or video stream in the input, aborting\n");
+        ret = 1;
+        goto end;
+    }
+
+    frame = avcodec_alloc_frame();
+    if (!frame) {
+        fprintf(stderr, "Could not allocate frame\n");
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+
+    /* initialize packet, set data to NULL, let the demuxer fill it */
+    av_init_packet(&pkt);
+    pkt.data = NULL;
+    pkt.size = 0;
+
+    if (video_stream)
+        printf("Demuxing video from file '%s' into '%s'\n", src_filename, video_dst_filename);
+    if (audio_stream)
+        printf("Demuxing video from file '%s' into '%s'\n", src_filename, audio_dst_filename);
+
+    /* read frames from the file */
+    while (av_read_frame(fmt_ctx, &pkt) >= 0)
+        decode_packet(&got_frame, 0);
+
+    /* flush cached frames */
+    pkt.data = NULL;
+    pkt.size = 0;
+    do {
+        decode_packet(&got_frame, 1);
+    } while (got_frame);
+
+    printf("Demuxing succeeded.\n");
+
+    if (video_stream) {
+        printf("Play the output video file with the command:\n"
+               "ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",
+               av_get_pix_fmt_name(video_dec_ctx->pix_fmt), video_dec_ctx->width, video_dec_ctx->height,
+               video_dst_filename);
+    }
+
+    if (audio_stream) {
+        const char *fmt;
+
+        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",
+               fmt, audio_dec_ctx->channels, audio_dec_ctx->sample_rate,
+               audio_dst_filename);
+    }
+
+end:
+    if (video_dec_ctx)
+        avcodec_close(video_dec_ctx);
+    if (audio_dec_ctx)
+        avcodec_close(audio_dec_ctx);
+    avformat_close_input(&fmt_ctx);
+    if (video_dst_file)
+        fclose(video_dst_file);
+    if (audio_dst_file)
+        fclose(audio_dst_file);
+    av_free(frame);
+    av_free(video_dst_data[0]);
+    av_free(audio_dst_data);
+
+    return ret < 0;
+}
diff --git a/doc/examples/filtering_audio.c b/doc/examples/filtering_audio.c
new file mode 100644
index 0000000..39f4450
--- /dev/null
+++ b/doc/examples/filtering_audio.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2010 Nicolas George
+ * Copyright (c) 2011 Stefano Sabatini
+ * Copyright (c) 2012 Clément Bœsch
+ *
+ * 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.
+ */
+
+/**
+ * @file
+ * API example for audio decoding and filtering
+ */
+
+#include <unistd.h>
+
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+#include <libavfilter/avfiltergraph.h>
+#include <libavfilter/avcodec.h>
+#include <libavfilter/buffersink.h>
+#include <libavfilter/buffersrc.h>
+
+const char *filter_descr = "aresample=8000,aconvert=s16:mono";
+const char *player       = "ffplay -f s16le -ar 8000 -ac 1 -";
+
+static AVFormatContext *fmt_ctx;
+static AVCodecContext *dec_ctx;
+AVFilterContext *buffersink_ctx;
+AVFilterContext *buffersrc_ctx;
+AVFilterGraph *filter_graph;
+static int audio_stream_index = -1;
+
+static int open_input_file(const char *filename)
+{
+    int ret;
+    AVCodec *dec;
+
+    if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
+        return ret;
+    }
+
+    if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
+        return ret;
+    }
+
+    /* select the audio stream */
+    ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Cannot find a audio stream in the input file\n");
+        return ret;
+    }
+    audio_stream_index = ret;
+    dec_ctx = fmt_ctx->streams[audio_stream_index]->codec;
+
+    /* init the audio decoder */
+    if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Cannot open audio decoder\n");
+        return ret;
+    }
+
+    return 0;
+}
+
+static int init_filters(const char *filters_descr)
+{
+    char args[512];
+    int ret;
+    AVFilter *abuffersrc  = avfilter_get_by_name("abuffer");
+    AVFilter *abuffersink = avfilter_get_by_name("ffabuffersink");
+    AVFilterInOut *outputs = avfilter_inout_alloc();
+    AVFilterInOut *inputs  = avfilter_inout_alloc();
+    const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 };
+    AVABufferSinkParams *abuffersink_params;
+    const AVFilterLink *outlink;
+    AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base;
+
+    filter_graph = avfilter_graph_alloc();
+
+    /* buffer audio source: the decoded frames from the decoder will be inserted here. */
+    if (!dec_ctx->channel_layout)
+        dec_ctx->channel_layout = av_get_default_channel_layout(dec_ctx->channels);
+    snprintf(args, sizeof(args),
+            "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%"PRIx64,
+             time_base.num, time_base.den, dec_ctx->sample_rate,
+             av_get_sample_fmt_name(dec_ctx->sample_fmt), dec_ctx->channel_layout);
+    ret = avfilter_graph_create_filter(&buffersrc_ctx, abuffersrc, "in",
+                                       args, NULL, filter_graph);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
+        return ret;
+    }
+
+    /* buffer audio sink: to terminate the filter chain. */
+    abuffersink_params = av_abuffersink_params_alloc();
+    abuffersink_params->sample_fmts     = sample_fmts;
+    ret = avfilter_graph_create_filter(&buffersink_ctx, abuffersink, "out",
+                                       NULL, abuffersink_params, filter_graph);
+    av_free(abuffersink_params);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n");
+        return ret;
+    }
+
+    /* Endpoints for the filter graph. */
+    outputs->name       = av_strdup("in");
+    outputs->filter_ctx = buffersrc_ctx;
+    outputs->pad_idx    = 0;
+    outputs->next       = NULL;
+
+    inputs->name       = av_strdup("out");
+    inputs->filter_ctx = buffersink_ctx;
+    inputs->pad_idx    = 0;
+    inputs->next       = NULL;
+
+    if ((ret = avfilter_graph_parse(filter_graph, filters_descr,
+                                    &inputs, &outputs, NULL)) < 0)
+        return ret;
+
+    if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
+        return ret;
+
+    /* Print summary of the sink buffer
+     * Note: args buffer is reused to store channel layout string */
+    outlink = buffersink_ctx->inputs[0];
+    av_get_channel_layout_string(args, sizeof(args), -1, outlink->channel_layout);
+    av_log(NULL, AV_LOG_INFO, "Output: srate:%dHz fmt:%s chlayout:%s\n",
+           (int)outlink->sample_rate,
+           (char *)av_x_if_null(av_get_sample_fmt_name(outlink->format), "?"),
+           args);
+
+    return 0;
+}
+
+static void print_samplesref(AVFilterBufferRef *samplesref)
+{
+    const AVFilterBufferRefAudioProps *props = samplesref->audio;
+    const int n = props->nb_samples * av_get_channel_layout_nb_channels(props->channel_layout);
+    const uint16_t *p     = (uint16_t*)samplesref->data[0];
+    const uint16_t *p_end = p + n;
+
+    while (p < p_end) {
+        fputc(*p    & 0xff, stdout);
+        fputc(*p>>8 & 0xff, stdout);
+        p++;
+    }
+    fflush(stdout);
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+    AVPacket packet;
+    AVFrame frame;
+    int got_frame;
+
+    if (argc != 2) {
+        fprintf(stderr, "Usage: %s file | %s\n", argv[0], player);
+        exit(1);
+    }
+
+    avcodec_register_all();
+    av_register_all();
+    avfilter_register_all();
+
+    if ((ret = open_input_file(argv[1])) < 0)
+        goto end;
+    if ((ret = init_filters(filter_descr)) < 0)
+        goto end;
+
+    /* read all packets */
+    while (1) {
+        AVFilterBufferRef *samplesref;
+        if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
+            break;
+
+        if (packet.stream_index == audio_stream_index) {
+            avcodec_get_frame_defaults(&frame);
+            got_frame = 0;
+            ret = avcodec_decode_audio4(dec_ctx, &frame, &got_frame, &packet);
+            if (ret < 0) {
+                av_log(NULL, AV_LOG_ERROR, "Error decoding audio\n");
+                continue;
+            }
+
+            if (got_frame) {
+                /* push the audio data from decoded frame into the filtergraph */
+                if (av_buffersrc_add_frame(buffersrc_ctx, &frame, 0) < 0) {
+                    av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio filtergraph\n");
+                    break;
+                }
+
+                /* pull filtered audio from the filtergraph */
+                while (1) {
+                    ret = av_buffersink_get_buffer_ref(buffersink_ctx, &samplesref, 0);
+                    if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
+                        break;
+                    if(ret < 0)
+                        goto end;
+                    if (samplesref) {
+                        print_samplesref(samplesref);
+                        avfilter_unref_bufferp(&samplesref);
+                    }
+                }
+            }
+        }
+        av_free_packet(&packet);
+    }
+end:
+    avfilter_graph_free(&filter_graph);
+    if (dec_ctx)
+        avcodec_close(dec_ctx);
+    avformat_close_input(&fmt_ctx);
+
+    if (ret < 0 && ret != AVERROR_EOF) {
+        char buf[1024];
+        av_strerror(ret, buf, sizeof(buf));
+        fprintf(stderr, "Error occurred: %s\n", buf);
+        exit(1);
+    }
+
+    exit(0);
+}
diff --git a/doc/examples/filtering_video.c b/doc/examples/filtering_video.c
new file mode 100644
index 0000000..ca0266e
--- /dev/null
+++ b/doc/examples/filtering_video.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2010 Nicolas George
+ * Copyright (c) 2011 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.
+ */
+
+/**
+ * @file
+ * API example for decoding and filtering
+ */
+
+#define _XOPEN_SOURCE 600 /* for usleep */
+#include <unistd.h>
+
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+#include <libavfilter/avfiltergraph.h>
+#include <libavfilter/avcodec.h>
+#include <libavfilter/buffersink.h>
+#include <libavfilter/buffersrc.h>
+
+const char *filter_descr = "scale=78:24";
+
+static AVFormatContext *fmt_ctx;
+static AVCodecContext *dec_ctx;
+AVFilterContext *buffersink_ctx;
+AVFilterContext *buffersrc_ctx;
+AVFilterGraph *filter_graph;
+static int video_stream_index = -1;
+static int64_t last_pts = AV_NOPTS_VALUE;
+
+static int open_input_file(const char *filename)
+{
+    int ret;
+    AVCodec *dec;
+
+    if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
+        return ret;
+    }
+
+    if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
+        return ret;
+    }
+
+    /* select the video stream */
+    ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Cannot find a video stream in the input file\n");
+        return ret;
+    }
+    video_stream_index = ret;
+    dec_ctx = fmt_ctx->streams[video_stream_index]->codec;
+
+    /* init the video decoder */
+    if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Cannot open video decoder\n");
+        return ret;
+    }
+
+    return 0;
+}
+
+static int init_filters(const char *filters_descr)
+{
+    char args[512];
+    int ret;
+    AVFilter *buffersrc  = avfilter_get_by_name("buffer");
+    AVFilter *buffersink = avfilter_get_by_name("ffbuffersink");
+    AVFilterInOut *outputs = avfilter_inout_alloc();
+    AVFilterInOut *inputs  = avfilter_inout_alloc();
+    enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };
+    AVBufferSinkParams *buffersink_params;
+
+    filter_graph = avfilter_graph_alloc();
+
+    /* buffer video source: the decoded frames from the decoder will be inserted here. */
+    snprintf(args, sizeof(args),
+            "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
+            dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
+            dec_ctx->time_base.num, dec_ctx->time_base.den,
+            dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);
+
+    ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
+                                       args, NULL, filter_graph);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
+        return ret;
+    }
+
+    /* buffer video sink: to terminate the filter chain. */
+    buffersink_params = av_buffersink_params_alloc();
+    buffersink_params->pixel_fmts = pix_fmts;
+    ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
+                                       NULL, buffersink_params, filter_graph);
+    av_free(buffersink_params);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
+        return ret;
+    }
+
+    /* Endpoints for the filter graph. */
+    outputs->name       = av_strdup("in");
+    outputs->filter_ctx = buffersrc_ctx;
+    outputs->pad_idx    = 0;
+    outputs->next       = NULL;
+
+    inputs->name       = av_strdup("out");
+    inputs->filter_ctx = buffersink_ctx;
+    inputs->pad_idx    = 0;
+    inputs->next       = NULL;
+
+    if ((ret = avfilter_graph_parse(filter_graph, filters_descr,
+                                    &inputs, &outputs, NULL)) < 0)
+        return ret;
+
+    if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
+        return ret;
+    return 0;
+}
+
+static void display_picref(AVFilterBufferRef *picref, AVRational time_base)
+{
+    int x, y;
+    uint8_t *p0, *p;
+    int64_t delay;
+
+    if (picref->pts != AV_NOPTS_VALUE) {
+        if (last_pts != AV_NOPTS_VALUE) {
+            /* sleep roughly the right amount of time;
+             * usleep is in microseconds, just like AV_TIME_BASE. */
+            delay = av_rescale_q(picref->pts - last_pts,
+                                 time_base, AV_TIME_BASE_Q);
+            if (delay > 0 && delay < 1000000)
+                usleep(delay);
+        }
+        last_pts = picref->pts;
+    }
+
+    /* Trivial ASCII grayscale display. */
+    p0 = picref->data[0];
+    puts("\033c");
+    for (y = 0; y < picref->video->h; y++) {
+        p = p0;
+        for (x = 0; x < picref->video->w; x++)
+            putchar(" .-+#"[*(p++) / 52]);
+        putchar('\n');
+        p0 += picref->linesize[0];
+    }
+    fflush(stdout);
+}
+
+int main(int argc, char **argv)
+{
+    int ret;
+    AVPacket packet;
+    AVFrame frame;
+    int got_frame;
+
+    if (argc != 2) {
+        fprintf(stderr, "Usage: %s file\n", argv[0]);
+        exit(1);
+    }
+
+    avcodec_register_all();
+    av_register_all();
+    avfilter_register_all();
+
+    if ((ret = open_input_file(argv[1])) < 0)
+        goto end;
+    if ((ret = init_filters(filter_descr)) < 0)
+        goto end;
+
+    /* read all packets */
+    while (1) {
+        AVFilterBufferRef *picref;
+        if ((ret = av_read_frame(fmt_ctx, &packet)) < 0)
+            break;
+
+        if (packet.stream_index == video_stream_index) {
+            avcodec_get_frame_defaults(&frame);
+            got_frame = 0;
+            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);
+
+                /* push the decoded frame into the filtergraph */
+                if (av_buffersrc_add_frame(buffersrc_ctx, &frame, 0) < 0) {
+                    av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
+                    break;
+                }
+
+                /* pull filtered pictures from the filtergraph */
+                while (1) {
+                    ret = av_buffersink_get_buffer_ref(buffersink_ctx, &picref, 0);
+                    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
+                        break;
+                    if (ret < 0)
+                        goto end;
+
+                    if (picref) {
+                        display_picref(picref, buffersink_ctx->inputs[0]->time_base);
+                        avfilter_unref_bufferp(&picref);
+                    }
+                }
+            }
+        }
+        av_free_packet(&packet);
+    }
+end:
+    avfilter_graph_free(&filter_graph);
+    if (dec_ctx)
+        avcodec_close(dec_ctx);
+    avformat_close_input(&fmt_ctx);
+
+    if (ret < 0 && ret != AVERROR_EOF) {
+        char buf[1024];
+        av_strerror(ret, buf, sizeof(buf));
+        fprintf(stderr, "Error occurred: %s\n", buf);
+        exit(1);
+    }
+
+    exit(0);
+}
diff --git a/doc/examples/metadata.c b/doc/examples/metadata.c
new file mode 100644
index 0000000..9f35912
--- /dev/null
+++ b/doc/examples/metadata.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2011 Reinhard Tartler
+ *
+ * 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.
+ */
+
+/**
+ * @file
+ * Shows how the metadata API can be used in application programs.
+ */
+
+#include <stdio.h>
+
+#include <libavformat/avformat.h>
+#include <libavutil/dict.h>
+
+int main (int argc, char **argv)
+{
+    AVFormatContext *fmt_ctx = NULL;
+    AVDictionaryEntry *tag = NULL;
+    int ret;
+
+    if (argc != 2) {
+        printf("usage: %s <input_file>\n"
+               "example program to demonstrate the use of the libavformat metadata API.\n"
+               "\n", argv[0]);
+        return 1;
+    }
+
+    av_register_all();
+    if ((ret = avformat_open_input(&fmt_ctx, argv[1], NULL, NULL)))
+        return ret;
+
+    while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
+        printf("%s=%s\n", tag->key, tag->value);
+
+    avformat_close_input(&fmt_ctx);
+    return 0;
+}
diff --git a/doc/examples/muxing.c b/doc/examples/muxing.c
new file mode 100644
index 0000000..f46f0be
--- /dev/null
+++ b/doc/examples/muxing.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * 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.
+ */
+
+/**
+ * @file
+ * libavformat API example.
+ *
+ * Output a media file in any supported libavformat format.
+ * The default codecs are used.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include <libavutil/mathematics.h>
+#include <libavformat/avformat.h>
+#include <libswscale/swscale.h>
+
+/* 5 seconds stream duration */
+#define STREAM_DURATION   200.0
+#define STREAM_FRAME_RATE 25 /* 25 images/s */
+#define STREAM_NB_FRAMES  ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
+#define STREAM_PIX_FMT    AV_PIX_FMT_YUV420P /* default pix_fmt */
+
+static int sws_flags = SWS_BICUBIC;
+
+/**************************************************************/
+/* audio output */
+
+static float t, tincr, tincr2;
+static int16_t *samples;
+static int audio_input_frame_size;
+
+/*
+ * add an audio output stream
+ */
+static AVStream *add_audio_stream(AVFormatContext *oc, AVCodec **codec,
+                                  enum AVCodecID codec_id)
+{
+    AVCodecContext *c;
+    AVStream *st;
+
+    /* find the audio encoder */
+    *codec = avcodec_find_encoder(codec_id);
+    if (!(*codec)) {
+        fprintf(stderr, "Could not find codec\n");
+        exit(1);
+    }
+
+    st = avformat_new_stream(oc, *codec);
+    if (!st) {
+        fprintf(stderr, "Could not allocate stream\n");
+        exit(1);
+    }
+    st->id = 1;
+
+    c = st->codec;
+
+    /* put sample parameters */
+    c->sample_fmt  = AV_SAMPLE_FMT_S16;
+    c->bit_rate    = 64000;
+    c->sample_rate = 44100;
+    c->channels    = 2;
+
+    // some formats want stream headers to be separate
+    if (oc->oformat->flags & AVFMT_GLOBALHEADER)
+        c->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+    return st;
+}
+
+static void open_audio(AVFormatContext *oc, AVCodec *codec, AVStream *st)
+{
+    AVCodecContext *c;
+
+    c = st->codec;
+
+    /* open it */
+    if (avcodec_open2(c, codec, NULL) < 0) {
+        fprintf(stderr, "could not open codec\n");
+        exit(1);
+    }
+
+    /* init signal generator */
+    t     = 0;
+    tincr = 2 * M_PI * 110.0 / c->sample_rate;
+    /* increment frequency by 110 Hz per second */
+    tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
+
+    if (c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
+        audio_input_frame_size = 10000;
+    else
+        audio_input_frame_size = c->frame_size;
+    samples = av_malloc(audio_input_frame_size *
+                        av_get_bytes_per_sample(c->sample_fmt) *
+                        c->channels);
+}
+
+/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
+ * 'nb_channels' channels. */
+static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels)
+{
+    int j, i, v;
+    int16_t *q;
+
+    q = samples;
+    for (j = 0; j < frame_size; j++) {
+        v = (int)(sin(t) * 10000);
+        for (i = 0; i < nb_channels; i++)
+            *q++ = v;
+        t     += tincr;
+        tincr += tincr2;
+    }
+}
+
+static void write_audio_frame(AVFormatContext *oc, AVStream *st)
+{
+    AVCodecContext *c;
+    AVPacket pkt = { 0 }; // data and size must be 0;
+    AVFrame *frame = avcodec_alloc_frame();
+    int got_packet;
+
+    av_init_packet(&pkt);
+    c = st->codec;
+
+    get_audio_frame(samples, audio_input_frame_size, c->channels);
+    frame->nb_samples = audio_input_frame_size;
+    avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
+                             (uint8_t *)samples,
+                             audio_input_frame_size *
+                             av_get_bytes_per_sample(c->sample_fmt) *
+                             c->channels, 1);
+
+    avcodec_encode_audio2(c, &pkt, frame, &got_packet);
+    if (!got_packet)
+        return;
+
+    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");
+        exit(1);
+    }
+    avcodec_free_frame(&frame);
+}
+
+static void close_audio(AVFormatContext *oc, AVStream *st)
+{
+    avcodec_close(st->codec);
+
+    av_free(samples);
+}
+
+/**************************************************************/
+/* video output */
+
+static AVFrame *frame;
+static AVPicture src_picture, dst_picture;
+static uint8_t *video_outbuf;
+static int frame_count, video_outbuf_size;
+
+/* Add a video output stream. */
+static AVStream *add_video_stream(AVFormatContext *oc, AVCodec **codec,
+                                  enum AVCodecID codec_id)
+{
+    AVCodecContext *c;
+    AVStream *st;
+
+    /* find the video encoder */
+    *codec = avcodec_find_encoder(codec_id);
+    if (!(*codec)) {
+        fprintf(stderr, "codec not found\n");
+        exit(1);
+    }
+
+    st = avformat_new_stream(oc, *codec);
+    if (!st) {
+        fprintf(stderr, "Could not alloc stream\n");
+        exit(1);
+    }
+
+    c = st->codec;
+
+    avcodec_get_context_defaults3(c, *codec);
+
+    c->codec_id = codec_id;
+
+    /* Put sample parameters. */
+    c->bit_rate = 400000;
+    /* Resolution must be a multiple of two. */
+    c->width    = 352;
+    c->height   = 288;
+    /* timebase: This is the fundamental unit of time (in seconds) in terms
+     * of which frame timestamps are represented. For fixed-fps content,
+     * timebase should be 1/framerate and timestamp increments should be
+     * identical to 1. */
+    c->time_base.den = STREAM_FRAME_RATE;
+    c->time_base.num = 1;
+    c->gop_size      = 12; /* emit one intra frame every twelve frames at most */
+    c->pix_fmt       = STREAM_PIX_FMT;
+    if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+        /* just for testing, we also add B frames */
+        c->max_b_frames = 2;
+    }
+    if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
+        /* Needed to avoid using macroblocks in which some coeffs overflow.
+         * This does not happen with normal video, it just happens here as
+         * the motion of the chroma plane does not match the luma plane. */
+        c->mb_decision = 2;
+    }
+    /* Some formats want stream headers to be separate. */
+    if (oc->oformat->flags & AVFMT_GLOBALHEADER)
+        c->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+    return st;
+}
+
+static void open_video(AVFormatContext *oc, AVCodec *codec, AVStream *st)
+{
+    int ret;
+    AVCodecContext *c = st->codec;
+
+    /* open the codec */
+    if (avcodec_open2(c, codec, NULL) < 0) {
+        fprintf(stderr, "Could not open codec\n");
+        exit(1);
+    }
+
+    video_outbuf = NULL;
+    if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
+        /* Allocate output buffer. */
+        /* XXX: API change will be done. */
+        /* Buffers passed into lav* can be allocated any way you prefer,
+         * as long as they're aligned enough for the architecture, and
+         * they're freed appropriately (such as using av_free for buffers
+         * allocated with av_malloc). */
+        video_outbuf_size = 200000;
+        video_outbuf      = av_malloc(video_outbuf_size);
+    }
+
+    /* allocate and init a re-usable frame */
+    frame = avcodec_alloc_frame();
+    if (!frame) {
+        fprintf(stderr, "Could not allocate video frame\n");
+        exit(1);
+    }
+
+    /* 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");
+        exit(1);
+    }
+
+    /* If the output format is not YUV420P, then a temporary YUV420P
+     * picture is needed too. It is then converted to the required
+     * output format. */
+    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");
+            exit(1);
+        }
+    }
+
+    /* copy data and linesize picture pointers to frame */
+    *((AVPicture *)frame) = dst_picture;
+}
+
+/* Prepare a dummy image. */
+static void fill_yuv_image(AVPicture *pict, int frame_index,
+                           int width, int height)
+{
+    int x, y, i;
+
+    i = frame_index;
+
+    /* Y */
+    for (y = 0; y < height; y++)
+        for (x = 0; x < width; x++)
+            pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3;
+
+    /* Cb and Cr */
+    for (y = 0; y < height / 2; y++) {
+        for (x = 0; x < width / 2; x++) {
+            pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2;
+            pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5;
+        }
+    }
+}
+
+static void write_video_frame(AVFormatContext *oc, AVStream *st)
+{
+    int ret;
+    static struct SwsContext *sws_ctx;
+    AVCodecContext *c = st->codec;
+
+    if (frame_count >= STREAM_NB_FRAMES) {
+        /* No more frames to compress. The codec has a latency of a few
+         * frames if using B-frames, so we get the last frames by
+         * passing the same picture again. */
+    } else {
+        if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
+            /* as we only generate a YUV420P picture, we must convert it
+             * to the codec pixel format if needed */
+            if (!sws_ctx) {
+                sws_ctx = sws_getContext(c->width, c->height, AV_PIX_FMT_YUV420P,
+                                         c->width, c->height, c->pix_fmt,
+                                         sws_flags, NULL, NULL, NULL);
+                if (!sws_ctx) {
+                    fprintf(stderr,
+                            "Could not initialize the conversion context\n");
+                    exit(1);
+                }
+            }
+            fill_yuv_image(&src_picture, frame_count, c->width, c->height);
+            sws_scale(sws_ctx,
+                      (const uint8_t * const *)src_picture.data, src_picture.linesize,
+                      0, c->height, dst_picture.data, dst_picture.linesize);
+        } else {
+            fill_yuv_image(&dst_picture, frame_count, c->width, c->height);
+        }
+    }
+
+    if (oc->oformat->flags & AVFMT_RAWPICTURE) {
+        /* Raw video case - the API will change slightly in the near
+         * future for that. */
+        AVPacket pkt;
+        av_init_packet(&pkt);
+
+        pkt.flags        |= AV_PKT_FLAG_KEY;
+        pkt.stream_index  = st->index;
+        pkt.data          = dst_picture.data[0];
+        pkt.size          = sizeof(AVPicture);
+
+        ret = av_interleaved_write_frame(oc, &pkt);
+    } else {
+        /* encode the image */
+        AVPacket pkt;
+        int got_output;
+
+        av_init_packet(&pkt);
+        pkt.data = NULL;    // packet data will be allocated by the encoder
+        pkt.size = 0;
+
+        ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
+        if (ret < 0) {
+            fprintf(stderr, "Error encoding video frame\n");
+            exit(1);
+        }
+
+        /* If size is zero, it means the image was buffered. */
+        if (got_output) {
+            if (c->coded_frame->pts != AV_NOPTS_VALUE)
+                pkt.pts = av_rescale_q(c->coded_frame->pts,
+                                       c->time_base, st->time_base);
+            if (c->coded_frame->key_frame)
+                pkt.flags |= AV_PKT_FLAG_KEY;
+
+            pkt.stream_index = st->index;
+
+            /* Write the compressed frame to the media file. */
+            ret = av_interleaved_write_frame(oc, &pkt);
+        } else {
+            ret = 0;
+        }
+    }
+    if (ret != 0) {
+        fprintf(stderr, "Error while writing video frame\n");
+        exit(1);
+    }
+    frame_count++;
+}
+
+static void close_video(AVFormatContext *oc, AVStream *st)
+{
+    avcodec_close(st->codec);
+    av_free(src_picture.data[0]);
+    av_free(dst_picture.data[0]);
+    av_free(frame);
+    av_free(video_outbuf);
+}
+
+/**************************************************************/
+/* media file output */
+
+int main(int argc, char **argv)
+{
+    const char *filename;
+    AVOutputFormat *fmt;
+    AVFormatContext *oc;
+    AVStream *audio_st, *video_st;
+    AVCodec *audio_codec, *video_codec;
+    double audio_pts, video_pts;
+    int i;
+
+    /* Initialize libavcodec, and register all codecs and formats. */
+    av_register_all();
+
+    if (argc != 2) {
+        printf("usage: %s output_file\n"
+               "API example program to output a media file with libavformat.\n"
+               "The output format is automatically guessed according to the file extension.\n"
+               "Raw images can also be output by using '%%d' in the filename\n"
+               "\n", argv[0]);
+        return 1;
+    }
+
+    filename = argv[1];
+
+    /* allocate the output media context */
+    avformat_alloc_output_context2(&oc, NULL, NULL, filename);
+    if (!oc) {
+        printf("Could not deduce output format from file extension: using MPEG.\n");
+        avformat_alloc_output_context2(&oc, NULL, "mpeg", filename);
+    }
+    if (!oc) {
+        return 1;
+    }
+    fmt = oc->oformat;
+
+    /* Add the audio and video streams using the default format codecs
+     * and initialize the codecs. */
+    video_st = NULL;
+    audio_st = NULL;
+    if (fmt->video_codec != AV_CODEC_ID_NONE) {
+        video_st = add_video_stream(oc, &video_codec, fmt->video_codec);
+    }
+    if (fmt->audio_codec != AV_CODEC_ID_NONE) {
+        audio_st = add_audio_stream(oc, &audio_codec, fmt->audio_codec);
+    }
+
+    /* Now that all the parameters are set, we can open the audio and
+     * video codecs and allocate the necessary encode buffers. */
+    if (video_st)
+        open_video(oc, video_codec, video_st);
+    if (audio_st)
+        open_audio(oc, audio_codec, audio_st);
+
+    av_dump_format(oc, 0, filename, 1);
+
+    /* 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);
+            return 1;
+        }
+    }
+
+    /* Write the stream header, if any. */
+    if (avformat_write_header(oc, NULL) < 0) {
+        fprintf(stderr, "Error occurred when opening output file\n");
+        return 1;
+    }
+
+    frame->pts = 0;
+    for (;;) {
+        /* Compute current audio and video time. */
+        if (audio_st)
+            audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den;
+        else
+            audio_pts = 0.0;
+
+        if (video_st)
+            video_pts = (double)video_st->pts.val * video_st->time_base.num /
+                        video_st->time_base.den;
+        else
+            video_pts = 0.0;
+
+        if ((!audio_st || audio_pts >= STREAM_DURATION) &&
+            (!video_st || video_pts >= STREAM_DURATION))
+            break;
+
+        /* write interleaved audio and video frames */
+        if (!video_st || (video_st && audio_st && audio_pts < video_pts)) {
+            write_audio_frame(oc, audio_st);
+        } else {
+            write_video_frame(oc, video_st);
+            frame->pts++;
+        }
+    }
+
+    /* Write the trailer, if any. The trailer must be written before you
+     * close the CodecContexts open when you wrote the header; otherwise
+     * av_write_trailer() may try to use memory that was freed on
+     * av_codec_close(). */
+    av_write_trailer(oc);
+
+    /* Close each codec. */
+    if (video_st)
+        close_video(oc, video_st);
+    if (audio_st)
+        close_audio(oc, audio_st);
+
+    /* Free the streams. */
+    for (i = 0; i < oc->nb_streams; i++) {
+        av_freep(&oc->streams[i]->codec);
+        av_freep(&oc->streams[i]);
+    }
+
+    if (!(fmt->flags & AVFMT_NOFILE))
+        /* Close the output file. */
+        avio_close(oc->pb);
+
+    /* free the stream */
+    av_free(oc);
+
+    return 0;
+}
diff --git a/doc/examples/scaling_video.c b/doc/examples/scaling_video.c
new file mode 100644
index 0000000..e380131
--- /dev/null
+++ b/doc/examples/scaling_video.c
@@ -0,0 +1,142 @@
+/*
+ * 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.
+ */
+
+/**
+ * @file
+ * libswscale API use example.
+ */
+
+#include <libavutil/imgutils.h>
+#include <libavutil/parseutils.h>
+#include <libswscale/swscale.h>
+
+static void fill_yuv_image(uint8_t *data[4], int linesize[4],
+                           int width, int height, int frame_index)
+{
+    int x, y, i;
+
+    i = frame_index;
+
+    /* Y */
+    for (y = 0; y < height; y++)
+        for (x = 0; x < width; x++)
+            data[0][y * linesize[0] + x] = x + y + i * 3;
+
+    /* Cb and Cr */
+    for (y = 0; y < height / 2; y++) {
+        for (x = 0; x < width / 2; x++) {
+            data[1][y * linesize[1] + x] = 128 + y + i * 2;
+            data[2][y * linesize[2] + x] = 64 + x + i * 5;
+        }
+    }
+}
+
+int main(int argc, char **argv)
+{
+    uint8_t *src_data[4], *dst_data[4];
+    int src_linesize[4], dst_linesize[4];
+    int src_w = 320, src_h = 240, dst_w, dst_h;
+    enum AVPixelFormat src_pix_fmt = AV_PIX_FMT_YUV420P, dst_pix_fmt = AV_PIX_FMT_RGB24;
+    const char *dst_size = NULL;
+    const char *dst_filename = NULL;
+    FILE *dst_file;
+    int dst_bufsize;
+    struct SwsContext *sws_ctx;
+    int i, ret;
+
+    if (argc != 3) {
+        fprintf(stderr, "Usage: %s output_file output_size\n"
+                "API example program to show how to scale an image with libswscale.\n"
+                "This program generates a series of pictures, rescales them to the given "
+                "output_size and saves them to an output file named output_file\n."
+                "\n", argv[0]);
+        exit(1);
+    }
+    dst_filename = argv[1];
+    dst_size     = argv[2];
+
+    if (av_parse_video_size(&dst_w, &dst_h, dst_size) < 0) {
+        fprintf(stderr,
+                "Invalid size '%s', must be in the form WxH or a valid size abbreviation\n",
+                dst_size);
+        exit(1);
+    }
+
+    dst_file = fopen(dst_filename, "wb");
+    if (!dst_file) {
+        fprintf(stderr, "Could not open destination file %s\n", dst_filename);
+        exit(1);
+    }
+
+    /* create scaling context */
+    sws_ctx = sws_getContext(src_w, src_h, src_pix_fmt,
+                             dst_w, dst_h, dst_pix_fmt,
+                             SWS_BILINEAR, NULL, NULL, NULL);
+    if (!sws_ctx) {
+        fprintf(stderr,
+                "Impossible to create scale context for the conversion "
+                "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
+                av_get_pix_fmt_name(src_pix_fmt), src_w, src_h,
+                av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h);
+        ret = AVERROR(EINVAL);
+        goto end;
+    }
+
+    /* allocate source and destination image buffers */
+    if ((ret = av_image_alloc(src_data, src_linesize,
+                              src_w, src_h, src_pix_fmt, 16)) < 0) {
+        fprintf(stderr, "Could not allocate source image\n");
+        goto end;
+    }
+
+    /* buffer is going to be written to rawvideo file, no alignmnet */
+    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");
+        goto end;
+    }
+    dst_bufsize = ret;
+
+    for (i = 0; i < 100; i++) {
+        /* generate synthetic video */
+        fill_yuv_image(src_data, src_linesize, src_w, src_h, i);
+
+        /* convert to destination format */
+        sws_scale(sws_ctx, (const uint8_t * const*)src_data,
+                  src_linesize, 0, src_h, dst_data, dst_linesize);
+
+        /* write scaled image to file */
+        fwrite(dst_data[0], 1, dst_bufsize, dst_file);
+    }
+
+    fprintf(stderr, "Scaling succeeded. Play the output file with the command:\n"
+           "ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",
+           av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h, dst_filename);
+
+end:
+    if (dst_file)
+        fclose(dst_file);
+    av_freep(&src_data[0]);
+    av_freep(&dst_data[0]);
+    sws_freeContext(sws_ctx);
+    return ret < 0;
+}
diff --git a/doc/faq.texi b/doc/faq.texi
index 088ca03..1158091 100644
--- a/doc/faq.texi
+++ b/doc/faq.texi
@@ -1,8 +1,8 @@
 \input texinfo @c -*- texinfo -*-
 
-@settitle Libav FAQ
+@settitle FFmpeg FAQ
 @titlepage
-@center @titlefont{Libav FAQ}
+@center @titlefont{FFmpeg FAQ}
 @end titlepage
 
 @top
@@ -11,23 +11,23 @@
 
 @chapter General Questions
 
-@section Why doesn't Libav support feature [xyz]?
+@section Why doesn't FFmpeg support feature [xyz]?
 
-Because no one has taken on that task yet. Libav development is
+Because no one has taken on that task yet. FFmpeg development is
 driven by the tasks that are important to the individual developers.
 If there is a feature that is important to you, the best way to get
 it implemented is to undertake the task yourself or sponsor a developer.
 
-@section Libav does not support codec XXX. Can you include a Windows DLL loader to support it?
+@section FFmpeg does not support codec XXX. Can you include a Windows DLL loader to support it?
 
 No. Windows DLLs are not portable, bloated and often slow.
-Moreover Libav strives to support all codecs natively.
+Moreover FFmpeg strives to support all codecs natively.
 A DLL loader is not conducive to that goal.
 
-@section I cannot read this file although this format seems to be supported by avconv.
+@section I cannot read this file although this format seems to be supported by ffmpeg.
 
-Even if avconv can read the container format, it may not support all its
-codecs. Please consult the supported codec list in the avconv
+Even if ffmpeg can read the container format, it may not support all its
+codecs. Please consult the supported codec list in the ffmpeg
 documentation.
 
 @section Which codecs are supported by Windows?
@@ -81,6 +81,12 @@
 
 @chapter Usage
 
+@section ffmpeg does not work; what is wrong?
+
+Try a @code{make distclean} in the ffmpeg source directory before the build.
+If this does not help see
+(@url{http://ffmpeg.org/bugreports.html}).
+
 @section How do I encode single pictures into movies?
 
 First, rename your pictures to follow a numerical sequence.
@@ -88,7 +94,7 @@
 Then you may run:
 
 @example
-  avconv -f image2 -i img%d.jpg /tmp/a.mpg
+  ffmpeg -f image2 -i img%d.jpg /tmp/a.mpg
 @end example
 
 Notice that @samp{%d} is replaced by the image number.
@@ -111,17 +117,17 @@
 Then run:
 
 @example
-  avconv -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg
+  ffmpeg -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg
 @end example
 
-The same logic is used for any image format that avconv reads.
+The same logic is used for any image format that ffmpeg reads.
 
 @section How do I encode movie to single pictures?
 
 Use:
 
 @example
-  avconv -i movie.mpg movie%d.jpg
+  ffmpeg -i movie.mpg movie%d.jpg
 @end example
 
 The @file{movie.mpg} used as input will be converted to
@@ -137,7 +143,7 @@
 
 Applying that to the previous example:
 @example
-  avconv -i movie.mpg -f image2 -c:v mjpeg menu%d.jpg
+  ffmpeg -i movie.mpg -f image2 -c:v mjpeg menu%d.jpg
 @end example
 
 Beware that there is no "jpeg" codec. Use "mjpeg" instead.
@@ -156,12 +162,12 @@
 
 Try '-f image2 test%d.jpg'.
 
-@section Why can I not change the framerate?
+@section Why can I not change the frame rate?
 
-Some codecs, like MPEG-1/2, only allow a small number of fixed framerates.
+Some codecs, like MPEG-1/2, only allow a small number of fixed frame rates.
 Choose a different codec with the -c:v command line option.
 
-@section How do I encode Xvid or DivX video with avconv?
+@section How do I encode Xvid or DivX video with ffmpeg?
 
 Both Xvid and DivX (version 4+) are implementations of the ISO MPEG-4
 standard (note that there are many other coding formats that use this
@@ -182,14 +188,14 @@
 but beware the '-g 100' might cause problems with some decoders.
 Things to try: '-bf 2', '-flags qprd', '-flags mv0', '-flags skiprd.
 
-@section Interlaced video looks very bad when encoded with avconv, what is wrong?
+@section Interlaced video looks very bad when encoded with ffmpeg, what is wrong?
 
 You should use '-flags +ilme+ildct' and maybe '-flags +alt' for interlaced
 material, and try '-top 0/1' if the result looks really messed-up.
 
 @section How can I read DirectShow files?
 
-If you have built Libav with @code{./configure --enable-avisynth}
+If you have built FFmpeg with @code{./configure --enable-avisynth}
 (only possible on MinGW/Cygwin platforms),
 then you may use any file that DirectShow can read as input.
 
@@ -197,9 +203,9 @@
 @example
   DirectShowSource("C:\path to your file\yourfile.asf")
 @end example
-... and then feed that text file to avconv:
+... and then feed that text file to ffmpeg:
 @example
-  avconv -i input.avs
+  ffmpeg -i input.avs
 @end example
 
 For ANY other help on Avisynth, please visit the
@@ -207,8 +213,56 @@
 
 @section How can I join video files?
 
-A few multimedia containers (MPEG-1, MPEG-2 PS, DV) allow to join video files by
-merely concatenating them.
+To "join" video files is quite ambiguous. The following list explains the
+different kinds of "joining" and points out how those are addressed in
+FFmpeg. To join video files may mean:
+
+@itemize
+
+@item
+To put them one after the other: this is called to @emph{concatenate} them
+(in short: concat) and is addressed
+@ref{How can I concatenate video files, in this very faq}.
+
+@item
+To put them together in the same file, to let the user choose between the
+different versions (example: different audio languages): this is called to
+@emph{multiplex} them together (in short: mux), and is done by simply
+invoking ffmpeg with several @option{-i} options.
+
+@item
+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.
+
+@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
+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.
+
+@end itemize
+
+@anchor{How can I concatenate video files}
+@section How can I concatenate video files?
+
+There are several solutions, depending on the exact circumstances.
+
+@subsection Concatenating using filters
+
+FFmpeg has a @url{http://ffmpeg.org/ffmpeg.html#concat-1, @code{concat}}
+filter designed specifically for that, with examples in the documentation.
+
+@subsection Concatenating at the file level
+
+A few multimedia containers (MPEG-1, MPEG-2 PS, DV) allow to concatenate
+video by merely concatenating the files 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
@@ -216,27 +270,38 @@
 format of choice.
 
 @example
-avconv -i input1.avi intermediate1.mpg
-avconv -i input2.avi intermediate2.mpg
+ffmpeg -i input1.avi -qscale:v 1 intermediate1.mpg
+ffmpeg -i input2.avi -qscale:v 1 intermediate2.mpg
 cat intermediate1.mpg intermediate2.mpg > intermediate_all.mpg
-avconv -i intermediate_all.mpg output.avi
+ffmpeg -i intermediate_all.mpg -qscale:v 2 output.avi
 @end example
 
-Notice that you should set a reasonably high bitrate for your intermediate and
-output files, if you want to preserve video quality.
+Additionally, you can use the @code{concat} protocol instead of @code{cat} or
+@code{copy} which will avoid creation of a potentially huge intermediate file.
 
-Also notice that you may avoid the huge intermediate files by taking advantage
-of named pipes, should your platform support it:
+@example
+ffmpeg -i input1.avi -qscale:v 1 intermediate1.mpg
+ffmpeg -i input2.avi -qscale:v 1 intermediate2.mpg
+ffmpeg -i concat:"intermediate1.mpg|intermediate2.mpg" -c copy intermediate_all.mpg
+ffmpeg -i intermediate_all.mpg -qscale:v 2 output.avi
+@end example
+
+Note that you may need to escape the character "|" which is special for many
+shells.
+
+Another option is usage of named pipes, should your platform support it:
 
 @example
 mkfifo intermediate1.mpg
 mkfifo intermediate2.mpg
-avconv -i input1.avi -y intermediate1.mpg < /dev/null &
-avconv -i input2.avi -y intermediate2.mpg < /dev/null &
+ffmpeg -i input1.avi -qscale:v 1 -y intermediate1.mpg < /dev/null &
+ffmpeg -i input2.avi -qscale:v 1 -y intermediate2.mpg < /dev/null &
 cat intermediate1.mpg intermediate2.mpg |\
-avconv -f mpeg -i - -c:v mpeg4 -acodec libmp3lame output.avi
+ffmpeg -f mpeg -i - -c:v mpeg4 -acodec libmp3lame output.avi
 @end example
 
+@subsection Concatenating using raw audio and video
+
 Similarly, the yuv4mpegpipe format, and the raw video, raw audio codecs also
 allow concatenation, and the transcoding step is almost lossless.
 When using multiple yuv4mpegpipe(s), the first line needs to be discarded
@@ -244,7 +309,8 @@
 @code{tail} as seen below. Note that when piping through @code{tail} you
 must use command grouping, @code{@{  ;@}}, to background properly.
 
-For example, let's say we want to join two FLV files into an output.flv file:
+For example, let's say we want to concatenate two FLV files into an
+output.flv file:
 
 @example
 mkfifo temp1.a
@@ -253,13 +319,13 @@
 mkfifo temp2.v
 mkfifo all.a
 mkfifo all.v
-avconv -i input1.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null &
-avconv -i input2.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null &
-avconv -i input1.flv -an -f yuv4mpegpipe - > temp1.v < /dev/null &
-@{ avconv -i input2.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp2.v ; @} &
+ffmpeg -i input1.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp1.a < /dev/null &
+ffmpeg -i input2.flv -vn -f u16le -acodec pcm_s16le -ac 2 -ar 44100 - > temp2.a < /dev/null &
+ffmpeg -i input1.flv -an -f yuv4mpegpipe - > temp1.v < /dev/null &
+@{ ffmpeg -i input2.flv -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp2.v ; @} &
 cat temp1.a temp2.a > all.a &
 cat temp1.v temp2.v > all.v &
-avconv -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i all.a \
+ffmpeg -f u16le -acodec pcm_s16le -ac 2 -ar 44100 -i all.a \
        -f yuv4mpegpipe -i all.v \
        -y output.flv
 rm temp[12].[av] all.[av]
@@ -267,7 +333,7 @@
 
 @section -profile option fails when encoding H.264 video with AAC audio
 
-@command{avconv} prints an error like
+@command{ffmpeg} prints an error like
 
 @example
 Undefined constant or missing '(' in 'baseline'
@@ -282,16 +348,57 @@
 of which are named @var{baseline}.
 
 The solution is to apply the @option{-profile} option to the video stream only
-by using @url{http://libav.org/avconv.html#Stream-specifiers-1, Stream specifiers}.
+by using @url{http://ffmpeg.org/ffmpeg.html#Stream-specifiers-1, Stream specifiers}.
 Appending @code{:v} to it will do exactly that.
 
+@section Using @option{-f lavfi}, audio becomes mono for no apparent reason.
+
+Use @option{-dumpgraph -} to find out exactly where the channel layout is
+lost.
+
+Most likely, it is through @code{auto-inserted aconvert}. Try to understand
+why the converting filter was needed at that place.
+
+Just before the output is a likely place, as @option{-f lavfi} currently
+only support packed S16.
+
+Then insert the correct @code{aconvert} explicitly in the filter graph,
+specifying the exact format.
+
+@example
+aconvert=s16:stereo:packed
+@end example
+
+@section Why does FFmpeg not see the subtitles in my VOB file?
+
+VOB and a few other formats do not have a global header that describes
+everything present in the file. Instead, applications are supposed to scan
+the file to see what it contains. Since VOB files are frequently large, only
+the beginning is scanned. If the subtitles happen only later in the file,
+they will not be initally detected.
+
+Some applications, including the @code{ffmpeg} command-line tool, can only
+work with streams that were detected during the initial scan; streams that
+are detected later are ignored.
+
+The size of the initial scan is controlled by two options: @code{probesize}
+(default ~5 Mo) and @code{analyzeduration} (default 5,000,000 µs = 5 s). For
+the subtitle stream to be detected, both values must be large enough.
+
 @chapter Development
 
-@section Are there examples illustrating how to use the Libav libraries, particularly libavcodec and libavformat?
+@section Are there examples illustrating how to use the FFmpeg libraries, particularly libavcodec and libavformat?
 
-Yes. Read the Developers Guide of the Libav documentation. Alternatively,
+Yes. Check the @file{doc/examples} directory in the source
+repository, also available online at:
+@url{https://github.com/FFmpeg/FFmpeg/tree/master/doc/examples}.
+
+Examples are also installed by default, usually in
+@code{$PREFIX/share/ffmpeg/examples}.
+
+Also you may read the Developers Guide of the FFmpeg documentation. Alternatively,
 examine the source code for one of the many open source projects that
-already incorporate Libav at (@url{projects.html}).
+already incorporate FFmpeg at (@url{projects.html}).
 
 @section Can you support my C compiler XXX?
 
@@ -302,42 +409,88 @@
 @section Is Microsoft Visual C++ supported?
 
 Yes. Please see the @uref{platform.html, Microsoft Visual C++}
-section in the Libav documentation.
+section in the FFmpeg documentation.
 
 @section Can you add automake, libtool or autoconf support?
 
 No. These tools are too bloated and they complicate the build.
 
-@section Why not rewrite Libav in object-oriented C++?
+@section Why not rewrite FFmpeg in object-oriented C++?
 
-Libav is already organized in a highly modular manner and does not need to
+FFmpeg is already organized in a highly modular manner and does not need to
 be rewritten in a formal object language. Further, many of the developers
 favor straight C; it works for them. For more arguments on this matter,
 read @uref{http://www.tux.org/lkml/#s15, "Programming Religion"}.
 
+@section Why are the ffmpeg programs devoid of debugging symbols?
+
+The build process creates ffmpeg_g, ffplay_g, etc. which contain full debug
+information. Those binaries are stripped to create ffmpeg, ffplay, etc. If
+you need the debug information, use the *_g versions.
+
 @section I do not like the LGPL, can I contribute code under the GPL instead?
 
 Yes, as long as the code is optional and can easily and cleanly be placed
-under #if CONFIG_GPL without breaking anything. So for example a new codec
+under #if CONFIG_GPL without breaking anything. So, for example, a new codec
 or filter would be OK under GPL while a bug fix to LGPL code would not.
 
-@section I'm using Libav from within my C++ application but the linker complains about missing symbols which seem to be available.
+@section I'm using FFmpeg from within my C application but the linker complains about missing symbols from the libraries themselves.
 
-Libav is a pure C project, so to use the libraries within your C++ application
+FFmpeg builds static libraries by default. In static libraries, dependencies
+are not handled. That has two consequences. First, you must specify the
+libraries in dependency order: @code{-lavdevice} must come before
+@code{-lavformat}, @code{-lavutil} must come after everything else, etc.
+Second, external libraries that are used in FFmpeg have to be specified too.
+
+An easy way to get the full list of required libraries in dependency order
+is to use @code{pkg-config}.
+
+@example
+  c99 -o program program.c $(pkg-config --cflags --libs libavformat libavcodec)
+@end example
+
+See @file{doc/example/Makefile} and @file{doc/example/pc-uninstalled} for
+more details.
+
+@section I'm using FFmpeg from within my C++ application but the linker complains about missing symbols which seem to be available.
+
+FFmpeg is a pure C project, so to use the libraries within your C++ application
 you need to explicitly state that you are using a C library. You can do this by
-encompassing your Libav includes using @code{extern "C"}.
+encompassing your FFmpeg includes using @code{extern "C"}.
 
 See @url{http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.3}
 
 @section I'm using libavutil from within my C++ application but the compiler complains about 'UINT64_C' was not declared in this scope
 
-Libav is a pure C project using C99 math features, in order to enable C++
+FFmpeg is a pure C project using C99 math features, in order to enable C++
 to use them you have to append -D__STDC_CONSTANT_MACROS to your CXXFLAGS
 
 @section I have a file in memory / a API different from *open/*read/ libc how do I use it with libavformat?
 
 You have to create a custom AVIOContext using @code{avio_alloc_context},
-see @file{libavformat/aviobuf.c} in Libav and @file{libmpdemux/demux_lavf.c} in MPlayer2 sources.
+see @file{libavformat/aviobuf.c} in FFmpeg and @file{libmpdemux/demux_lavf.c} in MPlayer or MPlayer2 sources.
+
+@section Where can I find libav* headers for Pascal/Delphi?
+
+see @url{http://www.iversenit.dk/dev/ffmpeg-headers/}
+
+@section Where is the documentation about ffv1, msmpeg4, asv1, 4xm?
+
+see @url{http://www.ffmpeg.org/~michael/}
+
+@section How do I feed H.263-RTP (and other codecs in RTP) to libavcodec?
+
+Even if peculiar since it is network oriented, RTP is a container like any
+other. You have to @emph{demux} RTP before feeding the payload to libavcodec.
+In this specific case please look at RFC 4629 to see how it should be done.
+
+@section AVStream.r_frame_rate is wrong, it is much larger than the frame rate.
+
+r_frame_rate is NOT the average frame rate, it is the smallest frame rate
+that can accurately represent all timestamps. So no, it is not
+wrong if it is larger than the average!
+For example, if you have mixed 25 and 30 fps content, then r_frame_rate
+will be 150.
 
 @section Why is @code{make fate} not running all tests?
 
diff --git a/doc/fate.texi b/doc/fate.texi
index 975f40a..4c2ba4d 100644
--- a/doc/fate.texi
+++ b/doc/fate.texi
@@ -1,150 +1,194 @@
 \input texinfo @c -*- texinfo -*-
 
-@settitle FATE Automated Testing Environment
+@settitle FFmpeg Automated Testing Environment
 @titlepage
-@center @titlefont{FATE Automated Testing Environment}
+@center @titlefont{FFmpeg Automated Testing Environment}
 @end titlepage
 
+@node Top
 @top
 
 @contents
 
 @chapter Introduction
 
-FATE provides a regression testsuite embedded within the Libav build system.
-It can be run locally and optionally configured to send reports to a web
-aggregator and viewer @url{http://fate.libav.org}.
+  FATE is an extended regression suite on the client-side and a means
+for results aggregation and presentation on the server-side.
 
-It is advised to run FATE before submitting patches to the current codebase
-and provide new tests when submitting patches to add additional features.
+  The first part of this document explains how you can use FATE from
+your FFmpeg source directory to test your ffmpeg binary. The second
+part describes how you can run FATE to submit the results to FFmpeg's
+FATE server.
 
-@chapter Running FATE
+  In any way you can have a look at the publicly viewable FATE results
+by visiting this website:
 
-@section Samples and References
-In order to run, FATE needs a large amount of data (samples and references)
-that is provided separately from the actual source distribution.
+  @url{http://fate.ffmpeg.org/}
 
-To inform the build system about the testsuite location, pass
-@option{--samples=<path to the samples>} to @command{configure} or set the
-@var{SAMPLES} Make variable or the @var{LIBAV_SAMPLES} environment variable
-to a suitable value.
+  This is especially recommended for all people contributing source
+code to FFmpeg, as it can be seen if some test on some platform broke
+with there recent contribution. This usually happens on the platforms
+the developers could not test on.
+
+  The second part of this document describes how you can run FATE to
+submit your results to FFmpeg's FATE server. If you want to submit your
+results be sure to check that your combination of CPU, OS and compiler
+is not already listed on the above mentioned website.
+
+  In the third part you can find a comprehensive listing of FATE makefile
+targets and variables.
+
+
+@chapter Using FATE from your FFmpeg source directory
+
+  If you want to run FATE on your machine you need to have the samples
+in place. You can get the samples via the build target fate-rsync.
+Use this command from the top-level source directory:
+
+@example
+make fate-rsync SAMPLES=fate-suite/
+make fate       SAMPLES=fate-suite/
+@end example
+
+  The above commands set the samples location by passing a makefile
+variable via command line. It is also possible to set the samples
+location at source configuration time by invoking configure with
+`--samples=<path to the samples directory>'. Afterwards you can
+invoke the makefile targets without setting the SAMPLES makefile
+variable. This is illustrated by the following commands:
+
+@example
+./configure --samples=fate-suite/
+make fate-rsync
+make fate
+@end example
+
+  Yet another way to tell FATE about the location of the sample
+directory is by making sure the environment variable FATE_SAMPLES
+contains the path to your samples directory. This can be achieved
+by e.g. putting that variable in your shell profile or by setting
+it in your interactive session.
+
+@example
+FATE_SAMPLES=fate-suite/ make fate
+@end example
+
+@float NOTE
+Do not put a '~' character in the samples path to indicate a home
+directory. Because of shell nuances, this will cause FATE to fail.
+@end float
 
 To use a custom wrapper to run the test, pass @option{--target-exec} to
 @command{configure} or set the @var{TARGET_EXEC} Make variable.
 
-The dataset is available through @command{rsync}, is possible to fetch
-the current sample using the straight rsync command or through a specific
-@ref{Makefile target}.
+
+@chapter Submitting the results to the FFmpeg result aggregation server
+
+  To submit your results to the server you should run fate through the
+shell script @file{tests/fate.sh} from the FFmpeg sources. This script needs
+to be invoked with a configuration file as its first argument.
 
 @example
-# rsync -aL rsync://fate-suite.libav.org/fate-suite/ fate-suite
+tests/fate.sh /path/to/fate_config
 @end example
 
-@example
-# make fate-rsync SAMPLES=fate-suite
-@end example
+  A configuration file template with comments describing the individual
+configuration variables can be found at @file{doc/fate_config.sh.template}.
+
+@ifhtml
+  The mentioned configuration template is also available here:
+@verbatiminclude fate_config.sh.template
+@end ifhtml
+
+  Create a configuration that suits your needs, based on the configuration
+template. The `slot' configuration variable can be any string that is not
+yet used, but it is suggested that you name it adhering to the following
+pattern <arch>-<os>-<compiler>-<compiler version>. The configuration file
+itself will be sourced in a shell script, therefore all shell features may
+be used. This enables you to setup the environment as you need it for your
+build.
+
+  For your first test runs the `fate_recv' variable should be empty or
+commented out. This will run everything as normal except that it will omit
+the submission of the results to the server. The following files should be
+present in $workdir as specified in the configuration file:
+
+@itemize
+    @item configure.log
+    @item compile.log
+    @item test.log
+    @item report
+    @item version
+@end itemize
+
+  When you have everything working properly you can create an SSH key pair
+and send the public key to the FATE server administrator who can be contacted
+at the email address @email{fate-admin@@ffmpeg.org}.
+
+  Configure your SSH client to use public key authentication with that key
+when connecting to the FATE server. Also do not forget to check the identity
+of the server and to accept its host key. This can usually be achieved by
+running your SSH client manually and killing it after you accepted the key.
+The FATE server's fingerprint is:
+
+  b1:31:c8:79:3f:04:1d:f8:f2:23:26:5a:fd:55:fa:92
+
+  If you have problems connecting to the FATE server, it may help to try out
+the @command{ssh} command with one or more @option{-v} options. You should
+get detailed output concerning your SSH configuration and the authentication
+process.
+
+  The only thing left is to automate the execution of the fate.sh script and
+the synchronisation of the samples directory.
 
 
-@chapter Manual Run
-FATE regression test can be run through @command{make}.
-Specific Makefile targets and Makefile variables are available:
+@chapter FATE makefile targets and variables
 
-@anchor{Makefile target}
-@section FATE Makefile targets
+@section Makefile targets
+
 @table @option
-@item fate-list
-List all fate/regression test targets.
 @item fate-rsync
-Shortcut to download the fate test samples to the specified testsuite location.
+    Download/synchronize sample files to the configured samples directory.
+
+@item fate-list
+    Will list all fate/regression test targets.
+
 @item fate
-Run the FATE test suite (requires the fate-suite dataset).
+    Run the FATE test suite (requires the fate-suite dataset).
 @end table
 
-@section FATE Makefile variables
+@section Makefile variables
+
 @table @option
 @item V
-Verbosity level, can be set to 0, 1 or 2.
-@table @option
-    @item 0
-    show just the test arguments
-    @item 1
-    show just the command used in the test
-    @item 2
-    show everything
-@end table
+    Verbosity level, can be set to 0, 1 or 2.
+    @itemize
+        @item 0: show just the test arguments
+        @item 1: show just the command used in the test
+        @item 2: show everything
+    @end itemize
+
 @item SAMPLES
-Specify or override the path to the FATE samples at make time, it has a
-meaning only while running the regression tests.
+    Specify or override the path to the FATE samples at make time, it has a
+    meaning only while running the regression tests.
+
 @item THREADS
-Specify how many threads to use while running regression tests, it is
-quite useful to detect thread-related regressions.
+    Specify how many threads to use while running regression tests, it is
+    quite useful to detect thread-related regressions.
 @item THREAD_TYPE
-Specify which threading strategy test, either @var{slice} or @var{frame},
-by default @var{slice+frame}
+    Specify which threading strategy test, either @var{slice} or @var{frame},
+    by default @var{slice+frame}
 @item CPUFLAGS
-Specify a mask to be applied to autodetected CPU flags.
+    Specify CPU flags.
 @item TARGET_EXEC
-Specify or override the wrapper used to run the tests.
+    Specify or override the wrapper used to run the tests.
+    The @var{TARGET_EXEC} option provides a way to run FATE wrapped in
+    @command{valgrind}, @command{qemu-user} or @command{wine} or on remote targets
+    through @command{ssh}.
 @end table
 
-@example
-    make V=1 SAMPLES=/var/fate/samples THREADS=2 CPUFLAGS=mmx fate
-@end example
-
-@chapter Automated Tests
-In order to automatically testing specific configurations, e.g. multiple
-compilers, @command{tests/fate.sh} is provided.
-
-This shell script builds Libav, runs the regression tests and prepares
-a report that can be sent to @url{http://fate.libav.org/} or directly
-examined locally.
-
-@section Testing Profiles
-The configuration file passed to @command{fate.sh} is shell scripts as well.
-
-It must provide at least a @var{slot} identifier, the @var{repo} from
-which fetch the sources, the @var{samples} directory, a @var{workdir} with
-enough space to build and run all the tests.
-Optional submit command @var{fate_recv} and a @var{comment} to describe
-the testing profile are available.
-
-Additional optional parameter to tune the Libav building and reporting process
-can be passed.
+@section Examples
 
 @example
-slot=                                   # some unique identifier
-repo=git://git.libav.org/libav.git      # the source repository
-samples=/path/to/fate/samples
-workdir=                                # directory in which to do all the work
-fate_recv="ssh -T fate@@fate.libav.org"  # command to submit report
-comment=                                # optional description
-
-# the following are optional and map to configure options
-arch=
-cpu=
-cross_prefix=
-cc=
-target_os=
-sysroot=
-target_exec=
-target_path=
-extra_cflags=
-extra_ldflags=
-extra_libs=
-extra_conf=     # extra configure options not covered above
-
-#make=          # name of GNU make if not 'make'
-makeopts=       # extra options passed to 'make'
-#tar=           # command to create a tar archive from its arguments on
-                # stdout, defaults to 'tar c'
+make V=1 SAMPLES=/var/fate/samples THREADS=2 CPUFLAGS=mmx fate
 @end example
-
-@section Special Instances
-The @var{TARGET_EXEC} option provides a way to run FATE wrapped in
-@command{valgrind}, @command{qemu-user} or @command{wine} or on remote targets
-through @command{ssh}.
-
-@section Submitting Reports
-In order to send reports you need to create an @command{ssh} key and send it
-to @email{root@@libav.org}.
-The current server fingerprint is @var{a4:99:d7:d3:1c:92:0d:56:d6:d5:61:be:01:ae:7d:e6}
diff --git a/doc/fate_config.sh.template b/doc/fate_config.sh.template
new file mode 100644
index 0000000..f7bd625
--- /dev/null
+++ b/doc/fate_config.sh.template
@@ -0,0 +1,25 @@
+slot=                                    # some unique identifier
+repo=git://source.ffmpeg.org/ffmpeg.git  # the source repository
+samples=                                 # path to samples directory
+workdir=                                 # directory in which to do all the work
+#fate_recv="ssh -T fate@fate.ffmpeg.org" # command to submit report
+comment=                                 # optional description
+
+# the following are optional and map to configure options
+arch=
+cpu=
+cross_prefix=
+cc=
+target_os=
+sysroot=
+target_exec=
+target_path=
+extra_cflags=
+extra_ldflags=
+extra_libs=
+extra_conf=     # extra configure options not covered above
+
+#make=          # name of GNU make if not 'make'
+makeopts=       # extra options passed to 'make'
+#tar=           # command to create a tar archive from its arguments on stdout,
+                # defaults to 'tar c'
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
new file mode 100644
index 0000000..767ce59
--- /dev/null
+++ b/doc/ffmpeg.texi
@@ -0,0 +1,1337 @@
+\input texinfo @c -*- texinfo -*-
+
+@settitle ffmpeg Documentation
+@titlepage
+@center @titlefont{ffmpeg Documentation}
+@end titlepage
+
+@top
+
+@contents
+
+@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
+
+@chapter Description
+@c man begin DESCRIPTION
+
+ffmpeg is a very fast video and audio converter that can also grab from
+a live audio/video source. It can also convert between arbitrary sample
+rates and resize video on the fly with a high quality polyphase filter.
+
+ffmpeg reads from an arbitrary number of input "files" (which can be regular
+files, pipes, network streams, grabbing devices, etc.), specified by the
+@code{-i} option, and writes to an arbitrary number of output "files", which are
+specified by a plain output filename. Anything found on the command line which
+cannot be interpreted as an option is considered to be an output filename.
+
+Each input or output file can in principle contain any number of streams of
+different types (video/audio/subtitle/attachment/data). Allowed number and/or
+types of streams can be limited by the container format. Selecting, which
+streams from which inputs go into output, is done either automatically or with
+the @code{-map} option (see the Stream selection chapter).
+
+To refer to input files in options, you must use their indices (0-based). E.g.
+the first input file is @code{0}, the second is @code{1} etc. Similarly, streams
+within a file are referred to by their indices. E.g. @code{2:3} refers to the
+fourth stream in the third input file. See also the Stream specifiers chapter.
+
+As a general rule, options are applied to the next specified
+file. Therefore, order is important, and you can have the same
+option on the command line multiple times. Each occurrence is
+then applied to the next input or output file.
+Exceptions from this rule are the global options (e.g. verbosity level),
+which should be specified first.
+
+Do not mix input and output files -- first specify all input files, then all
+output files. Also do not mix options which belong to different files. All
+options apply ONLY to the next input or output file and are reset between files.
+
+@itemize
+@item
+To set the video bitrate of the output file to 64kbit/s:
+@example
+ffmpeg -i input.avi -b:v 64k output.avi
+@end example
+
+@item
+To force the frame rate of the output file to 24 fps:
+@example
+ffmpeg -i input.avi -r 24 output.avi
+@end example
+
+@item
+To force the frame rate of the input file (valid for raw formats only)
+to 1 fps and the frame rate of the output file to 24 fps:
+@example
+ffmpeg -r 1 -i input.m2v -r 24 output.avi
+@end example
+@end itemize
+
+The format option may be needed for raw input files.
+
+@c man end DESCRIPTION
+
+@chapter Detailed description
+@c man begin DETAILED DESCRIPTION
+
+The transcoding process in @command{ffmpeg} for each output can be described by
+the following diagram:
+
+@example
+ _______              ______________               _________              ______________            ________
+|       |            |              |             |         |            |              |          |        |
+| input |  demuxer   | encoded data |   decoder   | decoded |  encoder   | encoded data |  muxer   | output |
+| file  | ---------> | packets      |  ---------> | frames  | ---------> | packets      | -------> | file   |
+|_______|            |______________|             |_________|            |______________|          |________|
+
+@end example
+
+@command{ffmpeg} calls the libavformat library (containing demuxers) to read
+input files and get packets containing encoded data from them. When there are
+multiple input files, @command{ffmpeg} tries to keep them synchronized by
+tracking lowest timestamp on any active input stream.
+
+Encoded packets are then passed to the decoder (unless streamcopy is selected
+for the stream, see further for a description). The decoder produces
+uncompressed frames (raw video/PCM audio/...) which can be processed further by
+filtering (see next section). After filtering the frames are passed to the
+encoder, which encodes them and outputs encoded packets again. Finally those are
+passed to the muxer, which writes the encoded packets to the output file.
+
+@section Filtering
+Before encoding, @command{ffmpeg} can process raw audio and video frames using
+filters from the libavfilter library. Several chained filters form a filter
+graph.  @command{ffmpeg} distinguishes between two types of filtergraphs -
+simple and complex.
+
+@subsection Simple filtergraphs
+Simple filtergraphs are those that have exactly one input and output, both of
+the same type. In the above diagram they can be represented by simply inserting
+an additional step between decoding and encoding:
+
+@example
+ _________                        __________              ______________
+|         |                      |          |            |              |
+| decoded |  simple filtergraph  | filtered |  encoder   | encoded data |
+| frames  | -------------------> | frames   | ---------> | packets      |
+|_________|                      |__________|            |______________|
+
+@end example
+
+Simple filtergraphs are configured with the per-stream @option{-filter} option
+(with @option{-vf} and @option{-af} aliases for video and audio respectively).
+A simple filtergraph for video can look for example like this:
+
+@example
+ _______        _____________        _______        _____        ________
+|       |      |             |      |       |      |     |      |        |
+| input | ---> | deinterlace | ---> | scale | ---> | fps | ---> | output |
+|_______|      |_____________|      |_______|      |_____|      |________|
+
+@end example
+
+Note that some filters change frame properties but not frame contents. E.g. the
+@code{fps} filter in the example above changes number of frames, but does not
+touch the frame contents. Another example is the @code{setpts} filter, which
+only sets timestamps and otherwise passes the frames unchanged.
+
+@subsection Complex filtergraphs
+Complex filtergraphs are those which cannot be described as simply a linear
+processing chain applied to one stream. This is the case e.g. when the graph has
+more than one input and/or output, or when output stream type is different from
+input. They can be represented with the following diagram:
+
+@example
+ _________
+|         |
+| input 0 |\                    __________
+|_________| \                  |          |
+             \   _________    /| output 0 |
+              \ |         |  / |__________|
+ _________     \| complex | /
+|         |     |         |/
+| input 1 |---->| filter  |\
+|_________|     |         | \   __________
+               /| graph   |  \ |          |
+              / |         |   \| output 1 |
+ _________   /  |_________|    |__________|
+|         | /
+| input 2 |/
+|_________|
+
+@end example
+
+Complex filtergraphs are configured with the @option{-filter_complex} option.
+Note that this option is global, since a complex filtergraph by its nature
+cannot be unambiguously associated with a single stream or file.
+
+A trivial example of a complex filtergraph is the @code{overlay} filter, which
+has two video inputs and one video output, containing one video overlaid on top
+of the other. Its audio counterpart is the @code{amix} filter.
+
+@section Stream copy
+Stream copy is a mode selected by supplying the @code{copy} parameter to the
+@option{-codec} option. It makes @command{ffmpeg} omit the decoding and encoding
+step for the specified stream, so it does only demuxing and muxing. It is useful
+for changing the container format or modifying container-level metadata. The
+diagram above will in this case simplify to this:
+
+@example
+ _______              ______________            ________
+|       |            |              |          |        |
+| input |  demuxer   | encoded data |  muxer   | output |
+| file  | ---------> | packets      | -------> | file   |
+|_______|            |______________|          |________|
+
+@end example
+
+Since there is no decoding or encoding, it is very fast and there is no quality
+loss. However it might not work in some cases because of many factors. Applying
+filters is obviously also impossible, since filters work on uncompressed data.
+
+@c man end DETAILED DESCRIPTION
+
+@chapter Stream selection
+@c man begin STREAM SELECTION
+
+By default ffmpeg includes only one stream of each type (video, audio, subtitle)
+present in the input files and adds them to each output file.  It picks the
+"best" of each based upon the following criteria; for video it is the stream
+with the highest resolution, for audio the stream with the most channels, for
+subtitle it's the first subtitle stream. In the case where several streams of
+the same type rate equally, the lowest numbered stream is chosen.
+
+You can disable some of those defaults by using @code{-vn/-an/-sn} options. For
+full manual control, use the @code{-map} option, which disables the defaults just
+described.
+
+@c man end STREAM SELECTION
+
+@chapter Options
+@c man begin OPTIONS
+
+@include avtools-common-opts.texi
+
+@section Main options
+
+@table @option
+
+@item -f @var{fmt} (@emph{input/output})
+Force input or output file format. The format is normally auto detected for input
+files and guessed from file extension for output files, so this option is not
+needed in most cases.
+
+@item -i @var{filename} (@emph{input})
+input file name
+
+@item -y (@emph{global})
+Overwrite output files without asking.
+
+@item -n (@emph{global})
+Do not overwrite output files but exit if file exists.
+
+@item -c[:@var{stream_specifier}] @var{codec} (@emph{input/output,per-stream})
+@itemx -codec[:@var{stream_specifier}] @var{codec} (@emph{input/output,per-stream})
+Select an encoder (when used before an output file) or a decoder (when used
+before an input file) for one or more streams. @var{codec} is the name of a
+decoder/encoder or a special value @code{copy} (output only) to indicate that
+the stream is not to be re-encoded.
+
+For example
+@example
+ffmpeg -i INPUT -map 0 -c:v libx264 -c:a copy OUTPUT
+@end example
+encodes all video streams with libx264 and copies all audio streams.
+
+For each stream, the last matching @code{c} option is applied, so
+@example
+ffmpeg -i INPUT -map 0 -c copy -c:v:1 libx264 -c:a:137 libvorbis OUTPUT
+@end example
+will copy all the streams except the second video, which will be encoded with
+libx264, and the 138th audio, which will be encoded with libvorbis.
+
+@item -t @var{duration} (@emph{output})
+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.
+
+@item -fs @var{limit_size} (@emph{output})
+Set the file size limit, expressed in bytes.
+
+@item -ss @var{position} (@emph{input/output})
+When used as an input option (before @code{-i}), seeks in this input file to
+@var{position}. When used as an output option (before an output filename),
+decodes but discards input until the timestamps reach @var{position}. This is
+slower, but more accurate.
+
+@var{position} may be either in seconds or in @code{hh:mm:ss[.xxx]} form.
+
+@item -itsoffset @var{offset} (@emph{input})
+Set the input time offset in seconds.
+@code{[-]hh:mm:ss[.xxx]} syntax is also supported.
+The offset is added to the timestamps of the input files.
+Specifying a positive offset means that the corresponding
+streams are delayed by @var{offset} seconds.
+
+@item -timestamp @var{time} (@emph{output})
+Set the recording timestamp in the container.
+The syntax for @var{time} is:
+@example
+now|([(YYYY-MM-DD|YYYYMMDD)[T|t| ]]((HH:MM:SS[.m...])|(HHMMSS[.m...]))[Z|z])
+@end example
+If the value is "now" it takes the current time.
+Time is local time unless 'Z' or 'z' is appended, in which case it is
+interpreted as UTC.
+If the year-month-day part is not specified it takes the current
+year-month-day.
+
+@item -metadata[:metadata_specifier] @var{key}=@var{value} (@emph{output,per-metadata})
+Set a metadata key/value pair.
+
+An optional @var{metadata_specifier} may be given to set metadata
+on streams or chapters. See @code{-map_metadata} documentation for
+details.
+
+This option overrides metadata set with @code{-map_metadata}. It is
+also possible to delete metadata by using an empty value.
+
+For example, for setting the title in the output file:
+@example
+ffmpeg -i in.avi -metadata title="my title" out.flv
+@end example
+
+To set the language of the first audio stream:
+@example
+ffmpeg -i INPUT -metadata:s:a:1 language=eng OUTPUT
+@end example
+
+@item -target @var{type} (@emph{output})
+Specify target file type (@code{vcd}, @code{svcd}, @code{dvd}, @code{dv},
+@code{dv50}). @var{type} may be prefixed with @code{pal-}, @code{ntsc-} or
+@code{film-} to use the corresponding standard. All the format options
+(bitrate, codecs, buffer sizes) are then set automatically. You can just type:
+
+@example
+ffmpeg -i myfile.avi -target vcd /tmp/vcd.mpg
+@end example
+
+Nevertheless you can specify additional options as long as you know
+they do not conflict with the standard, as in:
+
+@example
+ffmpeg -i myfile.avi -target vcd -bf 2 /tmp/vcd.mpg
+@end example
+
+@item -dframes @var{number} (@emph{output})
+Set the number of data frames to record. This is an alias for @code{-frames:d}.
+
+@item -frames[:@var{stream_specifier}] @var{framecount} (@emph{output,per-stream})
+Stop writing to the stream after @var{framecount} frames.
+
+@item -q[:@var{stream_specifier}] @var{q} (@emph{output,per-stream})
+@itemx -qscale[:@var{stream_specifier}] @var{q} (@emph{output,per-stream})
+Use fixed quality scale (VBR). The meaning of @var{q} is
+codec-dependent.
+
+@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).
+
+See also the @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).
+
+@item -stats (@emph{global})
+Print encoding progress/statistics. On by default.
+
+@item -progress @var{url} (@emph{global})
+Send program-friendly progress information to @var{url}.
+
+Progress information is written approximately every second and at the end of
+the encoding process. It is made of "@var{key}=@var{value}" lines. @var{key}
+consists of only alphanumeric characters. The last key of a sequence of
+progress information is always "progress".
+
+@item -stdin
+Enable interaction on standard input. On by default unless standard input is
+used as an input. To explicitly disable interaction you need to specify
+@code{-nostdin}.
+
+Disabling interaction on standard input is useful, for example, if
+ffmpeg is in the background process group. Roughly the same result can
+be achieved with @code{ffmpeg ... < /dev/null} but it requires a
+shell.
+
+@item -debug_ts (@emph{global})
+Print timestamp information. It is off by default. This option is
+mostly useful for testing and debugging purposes, and the output
+format may change from one version to another, so it should not be
+employed by portable scripts.
+
+See also the option @code{-fdebug ts}.
+
+@item -attach @var{filename} (@emph{output})
+Add an attachment to the output file. This is supported by a few formats
+like Matroska for e.g. fonts used in rendering subtitles. Attachments
+are implemented as a specific type of stream, so this option will add
+a new stream to the file. It is then possible to use per-stream options
+on this stream in the usual way. Attachment streams created with this
+option will be created after all the other streams (i.e. those created
+with @code{-map} or automatic mappings).
+
+Note that for Matroska you also have to set the mimetype metadata tag:
+@example
+ffmpeg -i INPUT -attach DejaVuSans.ttf -metadata:s:2 mimetype=application/x-truetype-font out.mkv
+@end example
+(assuming that the attachment stream will be third in the output file).
+
+@item -dump_attachment[:@var{stream_specifier}] @var{filename} (@emph{input,per-stream})
+Extract the matching attachment stream into a file named @var{filename}. If
+@var{filename} is empty, then the value of the @code{filename} metadata tag
+will be used.
+
+E.g. to extract the first attachment to a file named 'out.ttf':
+@example
+ffmpeg -dump_attachment:t:0 out.ttf INPUT
+@end example
+To extract all attachments to files determined by the @code{filename} tag:
+@example
+ffmpeg -dump_attachment:t "" INPUT
+@end example
+
+Technical note -- attachments are implemented as codec extradata, so this
+option can actually be used to extract extradata from any stream, not just
+attachments.
+
+@end table
+
+@section Video Options
+
+@table @option
+@item -vframes @var{number} (@emph{output})
+Set the number of video frames to record. This is an alias for @code{-frames:v}.
+@item -r[:@var{stream_specifier}] @var{fps} (@emph{input/output,per-stream})
+Set frame rate (Hz value, fraction or abbreviation).
+
+As an input option, ignore any timestamps stored in the file and instead
+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).
+
+@item -s[:@var{stream_specifier}] @var{size} (@emph{input/output,per-stream})
+Set frame size.
+
+As an input option, this is a shortcut for the @option{video_size} private
+option, recognized by some demuxers for which the frame size is either not
+stored in the file or is configurable -- e.g. raw video or video grabbers.
+
+As an output option, this inserts the @code{scale} video filter to the
+@emph{end} of the corresponding filtergraph. Please use the @code{scale} filter
+directly to insert it at the beginning or some other place.
+
+The format is @samp{wxh} (default - same as source).
+
+@item -aspect[:@var{stream_specifier}] @var{aspect} (@emph{output,per-stream})
+Set the video display aspect ratio specified by @var{aspect}.
+
+@var{aspect} can be a floating point number string, or a string of the
+form @var{num}:@var{den}, where @var{num} and @var{den} are the
+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.
+
+@item -vcodec @var{codec} (@emph{output})
+Set the video codec. This is an alias for @code{-codec:v}.
+
+@item -pass[:@var{stream_specifier}] @var{n} (@emph{output,per-stream})
+Select the pass number (1 or 2). It is used to do two-pass
+video encoding. The statistics of the video are recorded in the first
+pass into a log file (see also the option -passlogfile),
+and in the second pass that log file is used to generate the video
+at the exact requested bitrate.
+On pass 1, you may just deactivate audio and set output to null,
+examples for Windows and Unix:
+@example
+ffmpeg -i foo.mov -c:v libxvid -pass 1 -an -f rawvideo -y NUL
+ffmpeg -i foo.mov -c:v libxvid -pass 1 -an -f rawvideo -y /dev/null
+@end example
+
+@item -passlogfile[:@var{stream_specifier}] @var{prefix} (@emph{output,per-stream})
+Set two-pass log file name prefix to @var{prefix}, the default file name
+prefix is ``ffmpeg2pass''. The complete file name will be
+@file{PREFIX-N.log}, where N is a number specific to the output
+stream
+
+@item -vlang @var{code}
+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}.
+
+@end table
+
+@section Advanced Video Options
+
+@table @option
+@item -pix_fmt[:@var{stream_specifier}] @var{format} (@emph{input/output,per-stream})
+Set pixel format. Use @code{-pix_fmts} to show all the supported
+pixel formats.
+If the selected pixel format can not be selected, ffmpeg will print a
+warning and select the best pixel format supported by the encoder.
+If @var{pix_fmt} is prefixed by a @code{+}, ffmpeg will exit with an error
+if the requested pixel format can not be selected, and automatic conversions
+inside filter graphs are disabled.
+If @var{pix_fmt} is a single @code{+}, ffmpeg selects the same pixel format
+as the input (or graph output) and automatic conversions are disabled.
+
+@item -sws_flags @var{flags} (@emph{input/output})
+Set SwScaler flags.
+@item -vdt @var{n}
+Discard threshold.
+
+@item -rc_override[:@var{stream_specifier}] @var{override} (@emph{output,per-stream})
+Rate control override for specific intervals, formatted as "int,int,int"
+list separated with slashes. Two first values are the beginning and
+end frame numbers, last one is quantizer to use if positive, or quality
+factor if negative.
+
+@item -deinterlace
+Deinterlace pictures.
+This option is deprecated since the deinterlacing is very low quality.
+Use the yadif filter with @code{-filter:v yadif}.
+@item -ilme
+Force interlacing support in encoder (MPEG-2 and MPEG-4 only).
+Use this option if your input file is interlaced and you want
+to keep the interlaced format for minimum losses.
+The alternative is to deinterlace the input stream with
+@option{-deinterlace}, but deinterlacing introduces losses.
+@item -psnr
+Calculate PSNR of compressed frames.
+@item -vstats
+Dump video coding statistics to @file{vstats_HHMMSS.log}.
+@item -vstats_file @var{file}
+Dump video coding statistics to @var{file}.
+@item -top[:@var{stream_specifier}] @var{n} (@emph{output,per-stream})
+top=1/bottom=0/auto=-1 field first
+@item -dc @var{precision}
+Intra_dc_precision.
+@item -vtag @var{fourcc/tag} (@emph{output})
+Force video tag/fourcc. This is an alias for @code{-tag:v}.
+@item -qphist (@emph{global})
+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})
+Force key frames at the specified timestamps, more precisely at the first
+frames after each specified time.
+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.
+
+@item -copyinkf[:@var{stream_specifier}] (@emph{output,per-stream})
+When doing stream copy, copy also non-key frames found at the
+beginning.
+@end table
+
+@section Audio Options
+
+@table @option
+@item -aframes @var{number} (@emph{output})
+Set the number of audio frames to record. This is an alias for @code{-frames:a}.
+@item -ar[:@var{stream_specifier}] @var{freq} (@emph{input/output,per-stream})
+Set the audio sampling frequency. For output streams it is set by
+default to the frequency of the corresponding input stream. For input
+streams this option only makes sense for audio grabbing devices and raw
+demuxers and is mapped to the corresponding demuxer options.
+@item -aq @var{q} (@emph{output})
+Set the audio quality (codec-specific, VBR). This is an alias for -q:a.
+@item -ac[:@var{stream_specifier}] @var{channels} (@emph{input/output,per-stream})
+Set the number of audio channels. For output streams it is set by
+default to the number of input audio channels. For input streams
+this option only makes sense for audio grabbing devices and raw demuxers
+and is mapped to the corresponding demuxer options.
+@item -an (@emph{output})
+Disable audio recording.
+@item -acodec @var{codec} (@emph{input/output})
+Set the audio codec. This is an alias for @code{-codec:a}.
+@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}.
+@end table
+
+@section Advanced Audio options:
+
+@table @option
+@item -atag @var{fourcc/tag} (@emph{output})
+Force audio tag/fourcc. This is an alias for @code{-tag:a}.
+@item -absf @var{bitstream_filter}
+Deprecated, see -bsf
+@end table
+
+@section Subtitle options:
+
+@table @option
+@item -slang @var{code}
+Set the ISO 639 language code (3 letters) of the current subtitle stream.
+@item -scodec @var{codec} (@emph{input/output})
+Set the subtitle codec. This is an alias for @code{-codec:s}.
+@item -sn (@emph{output})
+Disable subtitle recording.
+@item -sbsf @var{bitstream_filter}
+Deprecated, see -bsf
+@end table
+
+@section Advanced Subtitle options:
+
+@table @option
+
+@item -fix_sub_duration
+Fix subtitles durations. For each subtitle, wait for the next packet in the
+same stream and adjust the duration of the first to avoid overlap. This is
+necessary with some subtitles codecs, especially DVB subtitles, because the
+duration in the original packet is only a rough estimate and the end is
+actually marked by an empty subtitle frame. Failing to use this option when
+necessary can result in exaggerated durations or muxing failures due to
+non-monotonic timestamps.
+
+Note that this option will delay the output of all data until the next
+subtitle packet is decoded: it may increase memory consumption and latency a
+lot.
+
+@end table
+
+@section Advanced options
+
+@table @option
+@item -map [-]@var{input_file_id}[:@var{stream_specifier}][,@var{sync_file_id}[:@var{stream_specifier}]] | @var{[linklabel]} (@emph{output})
+
+Designate one or more input streams as a source for the output file. Each input
+stream is identified by the input file index @var{input_file_id} and
+the input stream index @var{input_stream_id} within the input
+file. Both indices start at 0. If specified,
+@var{sync_file_id}:@var{stream_specifier} sets which input stream
+is used as a presentation sync reference.
+
+The first @code{-map} option on the command line specifies the
+source for output stream 0, the second @code{-map} option specifies
+the source for output stream 1, etc.
+
+A @code{-} character before the stream identifier creates a "negative" mapping.
+It disables matching streams from already created mappings.
+
+An alternative @var{[linklabel]} form will map outputs from complex filter
+graphs (see the @option{-filter_complex} option) to the output file.
+@var{linklabel} must correspond to a defined output link label in the graph.
+
+For example, to map ALL streams from the first input file to output
+@example
+ffmpeg -i INPUT -map 0 output
+@end example
+
+For example, if you have two audio streams in the first input file,
+these streams are identified by "0:0" and "0:1". You can use
+@code{-map} to select which streams to place in an output file. For
+example:
+@example
+ffmpeg -i INPUT -map 0:1 out.wav
+@end example
+will map the input stream in @file{INPUT} identified by "0:1" to
+the (single) output stream in @file{out.wav}.
+
+For example, to select the stream with index 2 from input file
+@file{a.mov} (specified by the identifier "0:2"), and stream with
+index 6 from input @file{b.mov} (specified by the identifier "1:6"),
+and copy them to the output file @file{out.mov}:
+@example
+ffmpeg -i a.mov -i b.mov -c copy -map 0:2 -map 1:6 out.mov
+@end example
+
+To select all video and the third audio stream from an input file:
+@example
+ffmpeg -i INPUT -map 0:v -map 0:a:2 OUTPUT
+@end example
+
+To map all the streams except the second audio, use negative mappings
+@example
+ffmpeg -i INPUT -map 0 -map -0:a:1 OUTPUT
+@end example
+
+Note that using this option disables the default mappings for this output file.
+
+@item -map_channel [@var{input_file_id}.@var{stream_specifier}.@var{channel_id}|-1][:@var{output_file_id}.@var{stream_specifier}]
+Map an audio channel from a given input to an output. If
+@var{output_file_id}.@var{stream_specifier} is not set, the audio channel will
+be mapped on all the audio streams.
+
+Using "-1" instead of
+@var{input_file_id}.@var{stream_specifier}.@var{channel_id} will map a muted
+channel.
+
+For example, assuming @var{INPUT} is a stereo audio file, you can switch the
+two audio channels with the following command:
+@example
+ffmpeg -i INPUT -map_channel 0.0.1 -map_channel 0.0.0 OUTPUT
+@end example
+
+If you want to mute the first channel and keep the second:
+@example
+ffmpeg -i INPUT -map_channel -1 -map_channel 0.0.1 OUTPUT
+@end example
+
+The order of the "-map_channel" option specifies the order of the channels in
+the output stream. The output channel layout is guessed from the number of
+channels mapped (mono if one "-map_channel", stereo if two, etc.). Using "-ac"
+in combination of "-map_channel" makes the channel gain levels to be updated if
+input and output channel layouts don't match (for instance two "-map_channel"
+options and "-ac 6").
+
+You can also extract each channel of an input to specific outputs; the following
+command extracts two channels of the @var{INPUT} audio stream (file 0, stream 0)
+to the respective @var{OUTPUT_CH0} and @var{OUTPUT_CH1} outputs:
+@example
+ffmpeg -i INPUT -map_channel 0.0.0 OUTPUT_CH0 -map_channel 0.0.1 OUTPUT_CH1
+@end example
+
+The following example splits the channels of a stereo input into two separate
+streams, which are put into the same output file:
+@example
+ffmpeg -i stereo.wav -map 0:0 -map 0:0 -map_channel 0.0.0:0.0 -map_channel 0.0.1:0.1 -y out.ogg
+@end example
+
+Note that currently each output stream can only contain channels from a single
+input stream; you can't for example use "-map_channel" to pick multiple input
+audio channels contained in different streams (from the same or different files)
+and merge them into a single output stream. It is therefore not currently
+possible, for example, to turn two separate mono streams into a single stereo
+stream. However splitting a stereo stream into two single channel mono streams
+is possible.
+
+If you need this feature, a possible workaround is to use the @emph{amerge}
+filter. For example, if you need to merge a media (here @file{input.mkv}) with 2
+mono audio streams into one single stereo channel audio stream (and keep the
+video stream), you can use the following command:
+@example
+ffmpeg -i input.mkv -filter_complex "[0:1] [0:2] amerge" -c:a pcm_s16le -c:v copy output.mkv
+@end example
+
+@item -map_metadata[:@var{metadata_spec_out}] @var{infile}[:@var{metadata_spec_in}] (@emph{output,per-metadata})
+Set metadata information of the next output file from @var{infile}. Note that
+those are file indices (zero-based), not filenames.
+Optional @var{metadata_spec_in/out} parameters specify, which metadata to copy.
+A metadata specifier can have the following forms:
+@table @option
+@item @var{g}
+global metadata, i.e. metadata that applies to the whole file
+
+@item @var{s}[:@var{stream_spec}]
+per-stream metadata. @var{stream_spec} is a stream specifier as described
+in the @ref{Stream specifiers} chapter. In an input metadata specifier, the first
+matching stream is copied from. In an output metadata specifier, all matching
+streams are copied to.
+
+@item @var{c}:@var{chapter_index}
+per-chapter metadata. @var{chapter_index} is the zero-based chapter index.
+
+@item @var{p}:@var{program_index}
+per-program metadata. @var{program_index} is the zero-based program index.
+@end table
+If metadata specifier is omitted, it defaults to global.
+
+By default, global metadata is copied from the first input file,
+per-stream and per-chapter metadata is copied along with streams/chapters. These
+default mappings are disabled by creating any mapping of the relevant type. A negative
+file index can be used to create a dummy mapping that just disables automatic copying.
+
+For example to copy metadata from the first stream of the input file to global metadata
+of the output file:
+@example
+ffmpeg -i in.ogg -map_metadata 0:s:0 out.mp3
+@end example
+
+To do the reverse, i.e. copy global metadata to all audio streams:
+@example
+ffmpeg -i in.mkv -map_metadata:s:a 0:g out.mkv
+@end example
+Note that simple @code{0} would work as well in this example, since global
+metadata is assumed by default.
+
+@item -map_chapters @var{input_file_index} (@emph{output})
+Copy chapters from input file with index @var{input_file_index} to the next
+output file. If no chapter mapping is specified, then chapters are copied from
+the first input file with at least one chapter. Use a negative file index to
+disable any chapter copying.
+@item -debug @var{category}
+Print specific debug info.
+@var{category} is a number or a string containing one of the following values:
+@table @samp
+@item bitstream
+@item buffers
+picture buffer allocations
+@item bugs
+@item dct_coeff
+@item er
+error recognition
+@item mb_type
+macroblock (MB) type
+@item mmco
+memory management control operations (H.264)
+@item mv
+motion vector
+@item pict
+picture info
+@item pts
+@item qp
+per-block quantization parameter (QP)
+@item rc
+rate control
+@item skip
+@item startcode
+@item thread_ops
+threading operations
+@item vis_mb_type
+visualize block types
+@item vis_qp
+visualize quantization parameter (QP), lower QP are tinted greener
+@end table
+@item -benchmark (@emph{global})
+Show benchmarking information at the end of an encode.
+Shows CPU time used and maximum memory consumption.
+Maximum memory consumption is not supported on all systems,
+it will usually display as 0 if not supported.
+@item -benchmark_all (@emph{global})
+Show benchmarking information during the encode.
+Shows CPU time used in various steps (audio/video encode/decode).
+@item -timelimit @var{duration} (@emph{global})
+Exit after ffmpeg has been running for @var{duration} seconds.
+@item -dump (@emph{global})
+Dump each input packet to stderr.
+@item -hex (@emph{global})
+When dumping packets, also dump the payload.
+@item -re (@emph{input})
+Read input at native frame rate. Mainly used to simulate a grab device.
+By default @command{ffmpeg} attempts to read the input(s) as fast as possible.
+This option will slow down the reading of the input(s) to the native frame rate
+of the input(s). It is useful for real-time output (e.g. live streaming). If
+your input(s) is coming from some other live streaming source (through HTTP or
+UDP for example) the server might already be in real-time, thus the option will
+likely not be required. On the other hand, this is meaningful if your input(s)
+is a file you are trying to push in real-time.
+@item -loop_input
+Loop over the input stream. Currently it works only for image
+streams. This option is used for automatic FFserver testing.
+This option is deprecated, use -loop 1.
+@item -loop_output @var{number_of_times}
+Repeatedly loop output for formats that support looping such as animated GIF
+(0 will loop the output infinitely).
+This option is deprecated, use -loop.
+@item -vsync @var{parameter}
+Video sync method.
+For compatibility reasons old values can be specified as numbers.
+Newly added values will have to be specified as strings always.
+
+@table @option
+@item 0, passthrough
+Each frame is passed with its timestamp from the demuxer to the muxer.
+@item 1, cfr
+Frames will be duplicated and dropped to achieve exactly the requested
+constant framerate.
+@item 2, vfr
+Frames are passed through with their timestamp or dropped so as to
+prevent 2 frames from having the same timestamp.
+@item drop
+As passthrough but destroys all timestamps, making the muxer generate
+fresh timestamps based on frame-rate.
+@item -1, auto
+Chooses between 1 and 2 depending on muxer capabilities. This is the
+default method.
+@end table
+
+With -map you can select from which stream the timestamps should be
+taken. You can leave either video or audio unchanged and sync the
+remaining stream(s) to the unchanged one.
+
+@item -async @var{samples_per_second}
+Audio sync method. "Stretches/squeezes" the audio stream to match the timestamps,
+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.
+@item -copyts
+Copy timestamps from input to output.
+@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:
+
+@table @option
+@item 1
+Use the demuxer timebase.
+
+The time base is copied to the output encoder from the corresponding input
+demuxer. This is sometimes required to avoid non monotonically increasing
+timestamps when copying video streams with variable frame rate.
+
+@item 0
+Use the decoder timebase.
+
+The time base is copied to the output encoder from the corresponding input
+decoder.
+
+@item -1
+Try to make the choice automatically, in order to generate a sane output.
+@end table
+
+Default value is -1.
+
+@item -shortest (@emph{output})
+Finish encoding when the shortest input stream ends.
+@item -dts_delta_threshold
+Timestamp discontinuity delta threshold.
+@item -muxdelay @var{seconds} (@emph{input})
+Set the maximum demux-decode delay.
+@item -muxpreload @var{seconds} (@emph{input})
+Set the initial demux-decode delay.
+@item -streamid @var{output-stream-index}:@var{new-value} (@emph{output})
+Assign a new stream-id value to an output stream. This option should be
+specified prior to the output filename to which it applies.
+For the situation where multiple output files exist, a streamid
+may be reassigned to a different value.
+
+For example, to set the stream 0 PID to 33 and the stream 1 PID to 36 for
+an output mpegts file:
+@example
+ffmpeg -i infile -streamid 0:33 -streamid 1:36 out.ts
+@end example
+
+@item -bsf[:@var{stream_specifier}] @var{bitstream_filters} (@emph{output,per-stream})
+Set bitstream filters for matching streams. @var{bistream_filters} is
+a comma-separated list of bitstream filters. Use the @code{-bsfs} option
+to get the list of bitstream filters.
+@example
+ffmpeg -i h264.mp4 -c:v copy -bsf:v h264_mp4toannexb -an out.h264
+@end example
+@example
+ffmpeg -i file.mov -an -vn -bsf:s mov2textsub -c:s copy -f rawvideo sub.txt
+@end example
+
+@item -tag[:@var{stream_specifier}] @var{codec_tag} (@emph{per-stream})
+Force a tag/fourcc for matching streams.
+
+@item -timecode @var{hh}:@var{mm}:@var{ss}SEP@var{ff}
+Specify Timecode for writing. @var{SEP} is ':' for non drop timecode and ';'
+(or '.') for drop.
+@example
+ffmpeg -i input.mpg -timecode 01:02:03.04 -r 30000/1001 -s ntsc output.mpg
+@end example
+
+@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}.
+
+Input link labels must refer to input streams using the
+@code{[file_index:stream_specifier]} syntax (i.e. the same as @option{-map}
+uses). If @var{stream_specifier} matches multiple streams, the first one will be
+used. An unlabeled input will be connected to the first unused input stream of
+the matching type.
+
+Output link labels are referred to with @option{-map}. Unlabeled outputs are
+added to the first output file.
+
+Note that with this option it is possible to use only lavfi sources without
+normal input files.
+
+For example, to overlay an image over video
+@example
+ffmpeg -i video.mkv -i image.png -filter_complex '[0:v][1:v]overlay[out]' -map
+'[out]' out.mkv
+@end example
+Here @code{[0:v]} refers to the first video stream in the first input file,
+which is linked to the first (main) input of the overlay filter. Similarly the
+first video stream in the second input is linked to the second (overlay) input
+of overlay.
+
+Assuming there is only one video stream in each input file, we can omit input
+labels, so the above is equivalent to
+@example
+ffmpeg -i video.mkv -i image.png -filter_complex 'overlay[out]' -map
+'[out]' out.mkv
+@end example
+
+Furthermore we can omit the output label and the single output from the filter
+graph will be added to the output file automatically, so we can simply write
+@example
+ffmpeg -i video.mkv -i image.png -filter_complex 'overlay' out.mkv
+@end example
+
+To generate 5 seconds of pure red video using lavfi @code{color} source:
+@example
+ffmpeg -filter_complex 'color=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
+experimental and temporary solution. It will be removed once libavfilter has
+proper support for subtitles.
+
+For example, to hardcode subtitles on top of a DVB-T recording stored in
+MPEG-TS format, delaying the subtitles by 1 second:
+@example
+ffmpeg -i input.ts -filter_complex \
+  '[#0x2ef] setpts=PTS+1/TB [sub] ; [#0x2d0] [sub] overlay' \
+  -sn -map '#0x2dc' output.mkv
+@end example
+(0x2d0, 0x2dc and 0x2ef are the MPEG-TS PIDs of respectively the video,
+audio and subtitles streams; 0:0, 0:3 and 0:7 would have worked too)
+
+@section Preset files
+A preset file contains a sequence of @var{option}=@var{value} pairs,
+one for each line, specifying a sequence of options which would be
+awkward to specify on the command line. Lines starting with the hash
+('#') character are ignored and are used to provide comments. Check
+the @file{presets} directory in the FFmpeg source tree for examples.
+
+Preset files are specified with the @code{vpre}, @code{apre},
+@code{spre}, and @code{fpre} options. The @code{fpre} option takes the
+filename of the preset instead of a preset name as input and can be
+used for any kind of codec. For the @code{vpre}, @code{apre}, and
+@code{spre} options, the options specified in a preset file are
+applied to the currently selected codec of the same type as the preset
+option.
+
+The argument passed to the @code{vpre}, @code{apre}, and @code{spre}
+preset options identifies the preset file to use according to the
+following rules:
+
+First ffmpeg searches for a file named @var{arg}.ffpreset in the
+directories @file{$FFMPEG_DATADIR} (if set), and @file{$HOME/.ffmpeg}, and in
+the datadir defined at configuration time (usually @file{PREFIX/share/ffmpeg})
+or in a @file{ffpresets} folder along the executable on win32,
+in that order. For example, if the argument is @code{libvpx-1080p}, it will
+search for the file @file{libvpx-1080p.ffpreset}.
+
+If no such file is found, then ffmpeg will search for a file named
+@var{codec_name}-@var{arg}.ffpreset in the above-mentioned
+directories, where @var{codec_name} is the name of the codec to which
+the preset file options will be applied. For example, if you select
+the video codec with @code{-vcodec libvpx} and use @code{-vpre 1080p},
+then it will search for the file @file{libvpx-1080p.ffpreset}.
+@c man end OPTIONS
+
+@chapter Tips
+@c man begin TIPS
+
+@itemize
+@item
+For streaming at very low bitrate application, use a low frame rate
+and a small GOP size. This is especially true for RealVideo where
+the Linux player does not seem to be very fast, so it can miss
+frames. An example is:
+
+@example
+ffmpeg -g 3 -r 3 -t 10 -b:v 50k -s qcif -f rv10 /tmp/b.rm
+@end example
+
+@item
+The parameter 'q' which is displayed while encoding is the current
+quantizer. The value 1 indicates that a very good quality could
+be achieved. The value 31 indicates the worst quality. If q=31 appears
+too often, it means that the encoder cannot compress enough to meet
+your bitrate. You must either increase the bitrate, decrease the
+frame rate or decrease the frame size.
+
+@item
+If your computer is not fast enough, you can speed up the
+compression at the expense of the compression ratio. You can use
+'-me zero' to speed up motion estimation, and '-g 0' to disable
+motion estimation completely (you have only I-frames, which means it
+is about as good as JPEG compression).
+
+@item
+To have very low audio bitrates, reduce the sampling frequency
+(down to 22050 Hz for MPEG audio, 22050 or 11025 for AC-3).
+
+@item
+To have a constant quality (but a variable bitrate), use the option
+'-qscale n' when 'n' is between 1 (excellent quality) and 31 (worst
+quality).
+
+@end itemize
+@c man end TIPS
+
+@chapter Examples
+@c man begin EXAMPLES
+
+@section Preset files
+
+A preset file contains a sequence of @var{option=value} pairs, one for
+each line, specifying a sequence of options which can be specified also on
+the command line. Lines starting with the hash ('#') character are ignored and
+are used to provide comments. Empty lines are also ignored. Check the
+@file{presets} directory in the FFmpeg source tree for examples.
+
+Preset files are specified with the @code{pre} option, this option takes a
+preset name as input.  FFmpeg searches for a file named @var{preset_name}.avpreset in
+the directories @file{$AVCONV_DATADIR} (if set), and @file{$HOME/.ffmpeg}, and in
+the data directory defined at configuration time (usually @file{$PREFIX/share/ffmpeg})
+in that order.  For example, if the argument is @code{libx264-max}, it will
+search for the file @file{libx264-max.avpreset}.
+
+@section Video and Audio grabbing
+
+If you specify the input format and device then ffmpeg can grab video
+and audio directly.
+
+@example
+ffmpeg -f oss -i /dev/dsp -f video4linux2 -i /dev/video0 /tmp/out.mpg
+@end example
+
+Or with an ALSA audio source (mono input, card id 1) instead of OSS:
+@example
+ffmpeg -f alsa -ac 1 -i hw:1 -f video4linux2 -i /dev/video0 /tmp/out.mpg
+@end example
+
+Note that you must activate the right video source and channel before
+launching ffmpeg with any TV viewer such as
+@uref{http://linux.bytesex.org/xawtv/, xawtv} by Gerd Knorr. You also
+have to set the audio recording levels correctly with a
+standard mixer.
+
+@section X11 grabbing
+
+Grab the X11 display with ffmpeg via
+
+@example
+ffmpeg -f x11grab -s cif -r 25 -i :0.0 /tmp/out.mpg
+@end example
+
+0.0 is display.screen number of your X11 server, same as
+the DISPLAY environment variable.
+
+@example
+ffmpeg -f x11grab -s cif -r 25 -i :0.0+10,20 /tmp/out.mpg
+@end example
+
+0.0 is display.screen number of your X11 server, same as the DISPLAY environment
+variable. 10 is the x-offset and 20 the y-offset for the grabbing.
+
+@section Video and Audio file format conversion
+
+Any supported file format and protocol can serve as input to ffmpeg:
+
+Examples:
+@itemize
+@item
+You can use YUV files as input:
+
+@example
+ffmpeg -i /tmp/test%d.Y /tmp/out.mpg
+@end example
+
+It will use the files:
+@example
+/tmp/test0.Y, /tmp/test0.U, /tmp/test0.V,
+/tmp/test1.Y, /tmp/test1.U, /tmp/test1.V, etc...
+@end example
+
+The Y files use twice the resolution of the U and V files. They are
+raw files, without header. They can be generated by all decent video
+decoders. You must specify the size of the image with the @option{-s} option
+if ffmpeg cannot guess it.
+
+@item
+You can input from a raw YUV420P file:
+
+@example
+ffmpeg -i /tmp/test.yuv /tmp/out.avi
+@end example
+
+test.yuv is a file containing raw YUV planar data. Each frame is composed
+of the Y plane followed by the U and V planes at half vertical and
+horizontal resolution.
+
+@item
+You can output to a raw YUV420P file:
+
+@example
+ffmpeg -i mydivx.avi hugefile.yuv
+@end example
+
+@item
+You can set several input files and output files:
+
+@example
+ffmpeg -i /tmp/a.wav -s 640x480 -i /tmp/a.yuv /tmp/a.mpg
+@end example
+
+Converts the audio file a.wav and the raw YUV video file a.yuv
+to MPEG file a.mpg.
+
+@item
+You can also do audio and video conversions at the same time:
+
+@example
+ffmpeg -i /tmp/a.wav -ar 22050 /tmp/a.mp2
+@end example
+
+Converts a.wav to MPEG audio at 22050 Hz sample rate.
+
+@item
+You can encode to several formats at the same time and define a
+mapping from input stream to output streams:
+
+@example
+ffmpeg -i /tmp/a.wav -map 0:a -b:a 64k /tmp/a.mp2 -map 0:a -b:a 128k /tmp/b.mp2
+@end example
+
+Converts a.wav to a.mp2 at 64 kbits and to b.mp2 at 128 kbits. '-map
+file:index' specifies which input stream is used for each output
+stream, in the order of the definition of output streams.
+
+@item
+You can transcode decrypted VOBs:
+
+@example
+ffmpeg -i snatch_1.vob -f avi -c:v mpeg4 -b:v 800k -g 300 -bf 2 -c:a libmp3lame -b:a 128k snatch.avi
+@end example
+
+This is a typical DVD ripping example; the input is a VOB file, the
+output an AVI file with MPEG-4 video and MP3 audio. Note that in this
+command we use B-frames so the MPEG-4 stream is DivX5 compatible, and
+GOP size is 300 which means one intra frame every 10 seconds for 29.97fps
+input video. Furthermore, the audio stream is MP3-encoded so you need
+to enable LAME support by passing @code{--enable-libmp3lame} to configure.
+The mapping is particularly useful for DVD transcoding
+to get the desired audio language.
+
+NOTE: To see the supported input formats, use @code{ffmpeg -formats}.
+
+@item
+You can extract images from a video, or create a video from many images:
+
+For extracting images from a video:
+@example
+ffmpeg -i foo.avi -r 1 -s WxH -f image2 foo-%03d.jpeg
+@end example
+
+This will extract one video frame per second from the video and will
+output them in files named @file{foo-001.jpeg}, @file{foo-002.jpeg},
+etc. Images will be rescaled to fit the new WxH values.
+
+If you want to extract just a limited number of frames, you can use the
+above command in combination with the -vframes or -t option, or in
+combination with -ss to start extracting from a certain point in time.
+
+For creating a video from many images:
+@example
+ffmpeg -f image2 -i foo-%03d.jpeg -r 12 -s WxH foo.avi
+@end example
+
+The syntax @code{foo-%03d.jpeg} specifies to use a decimal number
+composed of three digits padded with zeroes to express the sequence
+number. It is the same syntax supported by the C printf function, but
+only formats accepting a normal integer are suitable.
+
+When importing an image sequence, -i also supports expanding
+shell-like wildcard patterns (globbing) internally, by selecting the
+image2-specific @code{-pattern_type glob} option.
+
+For example, for creating a video from filenames matching the glob pattern
+@code{foo-*.jpeg}:
+@example
+ffmpeg -f image2 -pattern_type glob -i 'foo-*.jpeg' -r 12 -s WxH foo.avi
+@end example
+
+@item
+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
+@end example
+
+The resulting output file @file{test12.avi} will contain first four streams from
+the input file in reverse order.
+
+@item
+To force CBR video output:
+@example
+ffmpeg -i myfile.avi -b 4000k -minrate 4000k -maxrate 4000k -bufsize 1835k out.m2v
+@end example
+
+@item
+The four options lmin, lmax, mblmin and mblmax use 'lambda' units,
+but you may use the QP2LAMBDA constant to easily convert from 'q' units:
+@example
+ffmpeg -i src.ext -lmax 21*QP2LAMBDA dst.ext
+@end example
+
+@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
+
+@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/ffmpeg.txt b/doc/ffmpeg.txt
new file mode 100644
index 0000000..a028ca2
--- /dev/null
+++ b/doc/ffmpeg.txt
@@ -0,0 +1,47 @@
+                                                                                                                                       :
+                                             ffmpeg.c                                                                                  :       libav*
+                                             ========                                                                                  :       ======
+                                                                                                                                       :
+                                                                                                                                       :
+                                                                                                       --------------------------------:---> AVStream...
+                                                                    InputStream input_streams[]      /                                 :
+                                                                                                    /                                  :
+                    InputFile input_files[]                         +==========================+   /   ^                               :
+                                                          ------> 0 |      : st ---:-----------:--/    :                               :
+                 ^  +------+-----------+-----+          /           +--------------------------+       :                               :
+                 :  |      :ist_index--:-----:---------/          1 |      : st    :           |       :                               :
+                 :  +------+-----------+-----+                      +==========================+       :                               :
+ nb_input_files  :  |      :ist_index--:-----:------------------> 2 |      : st    :           |       :                               :
+                 :  +------+-----------+-----+                      +--------------------------+       :  nb_input_streams             :
+                 :  |      :ist_index  :     |                    3 |            ...           |       :                               :
+                 v  +------+-----------+-----+                      +--------------------------+       :                               :
+                                                              --> 4 |                          |       :                               :
+                                                             |      +--------------------------+       :                               :
+                                                             |    5 |                          |       :                               :
+                                                             |      +==========================+       v                               :
+                                                             |                                                                         :
+                                                             |                                                                         :
+                                                             |                                                                         :
+                                                             |                                                                         :
+                                                              ---------                                --------------------------------:---> AVStream...
+                                                                        \                            /                                 :
+                                                                    OutputStream output_streams[]   /                                  :
+                                                                          \                        /                                   :
+                                                                    +======\======================/======+      ^                      :
+                                                          ------> 0 |   : source_index  : st-:---        |      :                      :
+                    OutputFile output_files[]           /           +------------------------------------+      :                      :
+                                                       /          1 |   :               :    :           |      :                      :
+                 ^  +------+------------+-----+       /             +------------------------------------+      :                      :
+                 :  |      : ost_index -:-----:------/            2 |   :               :    :           |      :                      :
+ nb_output_files :  +------+------------+-----+                     +====================================+      :                      :
+                 :  |      : ost_index -:-----|-----------------> 3 |   :               :    :           |      :                      :
+                 :  +------+------------+-----+                     +------------------------------------+      : nb_output_streams    :
+                 :  |      :            :     |                   4 |                                    |      :                      :
+                 :  +------+------------+-----+                     +------------------------------------+      :                      :
+                 :  |      :            :     |                   5 |                                    |      :                      :
+                 v  +------+------------+-----+                     +------------------------------------+      :                      :
+                                                                  6 |                                    |      :                      :
+                                                                    +------------------------------------+      :                      :
+                                                                  7 |                                    |      :                      :
+                                                                    +====================================+      v                      :
+                                                                                                                                       :
diff --git a/doc/ffplay.texi b/doc/ffplay.texi
new file mode 100644
index 0000000..e2bded7
--- /dev/null
+++ b/doc/ffplay.texi
@@ -0,0 +1,206 @@
+\input texinfo @c -*- texinfo -*-
+
+@settitle ffplay Documentation
+@titlepage
+@center @titlefont{ffplay Documentation}
+@end titlepage
+
+@top
+
+@contents
+
+@chapter Synopsis
+
+@example
+@c man begin SYNOPSIS
+ffplay [options] [@file{input_file}]
+@c man end
+@end example
+
+@chapter Description
+@c man begin DESCRIPTION
+
+FFplay is a very simple and portable media player using the FFmpeg
+libraries and the SDL library. It is mostly used as a testbed for the
+various FFmpeg APIs.
+@c man end
+
+@chapter Options
+@c man begin OPTIONS
+
+@include avtools-common-opts.texi
+
+@section Main options
+
+@table @option
+@item -x @var{width}
+Force displayed width.
+@item -y @var{height}
+Force displayed height.
+@item -s @var{size}
+Set frame size (WxH or abbreviation), needed for videos which do
+not contain a header with the frame size like raw YUV.  This option
+has been deprecated in favor of private options, try -video_size.
+@item -an
+Disable audio.
+@item -vn
+Disable video.
+@item -ss @var{pos}
+Seek to a given position in seconds.
+@item -t @var{duration}
+play <duration> seconds of audio/video
+@item -bytes
+Seek by bytes.
+@item -nodisp
+Disable graphical display.
+@item -f @var{fmt}
+Force format.
+@item -window_title @var{title}
+Set window title (default is the input filename).
+@item -loop @var{number}
+Loops movie playback <number> times. 0 means forever.
+@item -showmode @var{mode}
+Set the show mode to use.
+Available values for @var{mode} are:
+@table @samp
+@item 0, video
+show video
+@item 1, waves
+show audio waves
+@item 2, rdft
+show audio frequency band using RDFT ((Inverse) Real Discrete Fourier Transform)
+@end table
+
+Default value is "video", if video is not present or cannot be played
+"rdft" is automatically selected.
+
+You can interactively cycle through the available show modes by
+pressing the key @key{w}.
+
+@item -vf @var{filter_graph}
+@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).
+
+@item -i @var{input_file}
+Read @var{input_file}.
+@end table
+
+@section Advanced options
+@table @option
+@item -pix_fmt @var{format}
+Set pixel format.
+This option has been deprecated in favor of private options, try -pixel_format.
+@item -stats
+Show the stream duration, the codec parameters, the current position in
+the stream and the audio/video synchronisation drift.
+@item -bug
+Work around bugs.
+@item -fast
+Non-spec-compliant optimizations.
+@item -genpts
+Generate pts.
+@item -rtp_tcp
+Force RTP/TCP protocol usage instead of RTP/UDP. It is only meaningful
+if you are streaming with the RTSP protocol.
+@item -sync @var{type}
+Set the master clock to audio (@code{type=audio}), video
+(@code{type=video}) or external (@code{type=ext}). Default is audio. The
+master clock is used to control audio-video synchronization. Most media
+players use audio as master clock, but in some cases (streaming or high
+quality broadcast) it is necessary to change that. This option is mainly
+used for debugging purposes.
+@item -threads @var{count}
+Set the thread count.
+@item -ast @var{audio_stream_number}
+Select the desired audio stream number, counting from 0. The number
+refers to the list of all the input audio streams. If it is greater
+than the number of audio streams minus one, then the last one is
+selected, if it is negative the audio playback is disabled.
+@item -vst @var{video_stream_number}
+Select the desired video stream number, counting from 0. The number
+refers to the list of all the input video streams. If it is greater
+than the number of video streams minus one, then the last one is
+selected, if it is negative the video playback is disabled.
+@item -sst @var{subtitle_stream_number}
+Select the desired subtitle stream number, counting from 0. The number
+refers to the list of all the input subtitle streams. If it is greater
+than the number of subtitle streams minus one, then the last one is
+selected, if it is negative the subtitle rendering is disabled.
+@item -autoexit
+Exit when video is done playing.
+@item -exitonkeydown
+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
+@end table
+
+@section While playing
+
+@table @key
+@item q, ESC
+Quit.
+
+@item f
+Toggle full screen.
+
+@item p, SPC
+Pause.
+
+@item a
+Cycle audio channel.
+
+@item v
+Cycle video channel.
+
+@item t
+Cycle subtitle channel.
+
+@item w
+Show audio waves.
+
+@item left/right
+Seek backward/forward 10 seconds.
+
+@item down/up
+Seek backward/forward 1 minute.
+
+@item page down/page up
+Seek backward/forward 10 minutes.
+
+@item mouse click
+Seek to percentage in file corresponding to fraction of width.
+
+@end table
+
+@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
+
+@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
new file mode 100644
index 0000000..6295eb3
--- /dev/null
+++ b/doc/ffprobe.texi
@@ -0,0 +1,470 @@
+\input texinfo @c -*- texinfo -*-
+
+@settitle ffprobe Documentation
+@titlepage
+@center @titlefont{ffprobe Documentation}
+@end titlepage
+
+@top
+
+@contents
+
+@chapter Synopsis
+
+The generic syntax is:
+
+@example
+@c man begin SYNOPSIS
+ffprobe [options] [@file{input_file}]
+@c man end
+@end example
+
+@chapter Description
+@c man begin DESCRIPTION
+
+ffprobe gathers information from multimedia streams and prints it in
+human- and machine-readable fashion.
+
+For example it can be used to check the format of the container used
+by a multimedia stream and the format and type of each media stream
+contained in it.
+
+If a filename is specified in input, ffprobe will try to open and
+probe the file content. If the file cannot be opened or recognized as
+a multimedia file, a positive exit code is returned.
+
+ffprobe may be employed both as a standalone application or in
+combination with a textual filter, which may perform more
+sophisticated processing, e.g. statistical processing or plotting.
+
+Options are used to list some of the formats supported by ffprobe or
+for specifying which information to display, and for setting how
+ffprobe will show it.
+
+ffprobe output is designed to be easily parsable by a textual filter,
+and consists of one or more sections of a form defined by the selected
+writer, which is specified by the @option{print_format} option.
+
+Metadata tags stored in the container or in the streams are recognized
+and printed in the corresponding "FORMAT" or "STREAM" section.
+
+@c man end
+
+@chapter Options
+@c man begin OPTIONS
+
+@include avtools-common-opts.texi
+
+@section Main options
+
+@table @option
+
+@item -f @var{format}
+Force format to use.
+
+@item -unit
+Show the unit of the displayed values.
+
+@item -prefix
+Use SI prefixes for the displayed values.
+Unless the "-byte_binary_prefix" option is used all the prefixes
+are decimal.
+
+@item -byte_binary_prefix
+Force the use of binary prefixes for byte values.
+
+@item -sexagesimal
+Use sexagesimal format HH:MM:SS.MICROSECONDS for time values.
+
+@item -pretty
+Prettify the format of the displayed values, it corresponds to the
+options "-unit -prefix -byte_binary_prefix -sexagesimal".
+
+@item -of, -print_format @var{writer_name}[=@var{writer_options}]
+Set the output printing format.
+
+@var{writer_name} specifies the name of the writer, and
+@var{writer_options} specifies the options to be passed to the writer.
+
+For example for printing the output in JSON format, specify:
+@example
+-print_format json
+@end example
+
+For more details on the available output printing formats, see the
+Writers section below.
+
+@item -select_streams @var{stream_specifier}
+Select only the streams specified by @var{stream_specifier}. This
+option affects only the options related to streams
+(e.g. @code{show_streams}, @code{show_packets}, etc.).
+
+For example to show only audio streams, you can use the command:
+@example
+ffprobe -show_streams -select_streams a INPUT
+@end example
+
+To show only video packets belonging to the video stream with index 1:
+@example
+ffprobe -show_packets -select_streams v:1 INPUT
+@end example
+
+@item -show_data
+Show payload data, as an hexadecimal and ASCII dump. Coupled with
+@option{-show_packets}, it will dump the packets' data. Coupled with
+@option{-show_streams}, it will dump the codec extradata.
+
+The dump is printed as the "data" field. It may contain newlines.
+
+@item -show_error
+Show information about the error found when trying to probe the input.
+
+The error information is printed within a section with name "ERROR".
+
+@item -show_format
+Show information about the container format of the input multimedia
+stream.
+
+All the container format information is printed within a section with
+name "FORMAT".
+
+@item -show_format_entry @var{name}
+Like @option{-show_format}, but only prints the specified entry of the
+container format information, rather than all. This option may be given more
+than once, then all specified entries will be shown.
+
+@item -show_packets
+Show information about each packet contained in the input multimedia
+stream.
+
+The information for each single packet is printed within a dedicated
+section with name "PACKET".
+
+@item -show_frames
+Show information about each frame contained in the input multimedia
+stream.
+
+The information for each single frame is printed within a dedicated
+section with name "FRAME".
+
+@item -show_streams
+Show information about each media stream contained in the input
+multimedia stream.
+
+Each media stream information is printed within a dedicated section
+with name "STREAM".
+
+@item -count_frames
+Count the number of frames per stream and report it in the
+corresponding stream section.
+
+@item -count_packets
+Count the number of packets per stream and report it in the
+corresponding stream section.
+
+@item -show_private_data, -private
+Show private data, that is data depending on the format of the
+particular shown element.
+This option is enabled by default, but you may need to disable it
+for specific uses, for example when creating XSD-compliant XML output.
+
+@item -show_program_version
+Show information related to program version.
+
+Version information is printed within a section with name
+"PROGRAM_VERSION".
+
+@item -show_library_versions
+Show information related to library versions.
+
+Version information for each library is printed within a section with
+name "LIBRARY_VERSION".
+
+@item -show_versions
+Show information related to program and library versions. This is the
+equivalent of setting both @option{-show_program_version} and
+@option{-show_library_versions} options.
+
+@item -bitexact
+Force bitexact output, useful to produce output which is not dependent
+on the specific build.
+
+@item -i @var{input_file}
+Read @var{input_file}.
+
+@end table
+@c man end
+
+@chapter Writers
+@c man begin WRITERS
+
+A writer defines the output format adopted by @command{ffprobe}, and will be
+used for printing all the parts of the output.
+
+A writer may accept one or more arguments, which specify the options to
+adopt.
+
+A description of the currently available writers follows.
+
+@section default
+Default format.
+
+Print each section in the form:
+@example
+[SECTION]
+key1=val1
+...
+keyN=valN
+[/SECTION]
+@end example
+
+Metadata tags are printed as a line in the corresponding FORMAT or
+STREAM section, and are prefixed by the string "TAG:".
+
+This writer accepts options as a list of @var{key}=@var{value} pairs,
+separated by ":".
+
+A description of the accepted options follows.
+
+@table @option
+
+@item nokey, nk
+If set to 1 specify not to print the key of each field. Default value
+is 0.
+
+@item noprint_wrappers, nw
+If set to 1 specify not to print the section header and footer.
+Default value is 0.
+@end table
+
+@section compact, csv
+Compact and CSV format.
+
+The @code{csv} writer is equivalent to @code{compact}, but supports
+different defaults.
+
+Each section is printed on a single line.
+If no option is specifid, the output has the form:
+@example
+section|key1=val1| ... |keyN=valN
+@end example
+
+Metadata tags are printed in the corresponding "format" or "stream"
+section. A metadata tag key, if printed, is prefixed by the string
+"tag:".
+
+This writer accepts options as a list of @var{key}=@var{value} pairs,
+separated by ":".
+
+The description of the accepted options follows.
+
+@table @option
+
+@item item_sep, s
+Specify the character to use for separating fields in the output line.
+It must be a single printable character, it is "|" by default ("," for
+the @code{csv} writer).
+
+@item nokey, nk
+If set to 1 specify not to print the key of each field. Its default
+value is 0 (1 for the @code{csv} writer).
+
+@item escape, e
+Set the escape mode to use, default to "c" ("csv" for the @code{csv}
+writer).
+
+It can assume one of the following values:
+@table @option
+@item c
+Perform C-like escaping. Strings containing a newline ('\n'), carriage
+return ('\r'), a tab ('\t'), a form feed ('\f'), the escaping
+character ('\') or the item separator character @var{SEP} are escaped using C-like fashioned
+escaping, so that a newline is converted to the sequence "\n", a
+carriage return to "\r", '\' to "\\" and the separator @var{SEP} is
+converted to "\@var{SEP}".
+
+@item csv
+Perform CSV-like escaping, as described in RFC4180.  Strings
+containing a newline ('\n'), a carriage return ('\r'), a double quote
+('"'), or @var{SEP} are enclosed in double-quotes.
+
+@item none
+Perform no escaping.
+@end table
+
+@item print_section, p
+Print the section name at the begin of each line if the value is
+@code{1}, disable it with value set to @code{0}. Default value is
+@code{1}.
+
+@end table
+
+@section flat
+Flat format.
+
+A free-form output where each line contains an explicit key=value, such as
+"streams.stream.3.tags.foo=bar". The output is shell escaped, so it can be
+directly embedded in sh scripts as long as the separator character is an
+alphanumeric character or an underscore (see @var{sep_char} option).
+
+This writer accepts options as a list of @var{key}=@var{value} pairs,
+separated by ":".
+
+The description of the accepted options follows.
+
+@table @option
+@item sep_char, s
+Separator character used to separate the chapter, the section name, IDs and
+potential tags in the printed field key.
+
+Default value is '.'.
+
+@item hierarchical, h
+Specify if the section name specification should be hierarchical. If
+set to 1, and if there is more than one section in the current
+chapter, the section name will be prefixed by the name of the
+chapter. A value of 0 will disable this behavior.
+
+Default value is 1.
+@end table
+
+@section ini
+INI format output.
+
+Print output in an INI based format.
+
+The following conventions are adopted:
+
+@itemize
+@item
+all key and values are UTF-8
+@item
+'.' is the subgroup separator
+@item
+newline, '\t', '\f', '\b' and the following characters are escaped
+@item
+'\' is the escape character
+@item
+'#' is the comment indicator
+@item
+'=' is the key/value separator
+@item
+':' is not used but usually parsed as key/value separator
+@end itemize
+
+This writer accepts options as a list of @var{key}=@var{value} pairs,
+separated by ":".
+
+The description of the accepted options follows.
+
+@table @option
+@item hierarchical, h
+Specify if the section name specification should be hierarchical. If
+set to 1, and if there is more than one section in the current
+chapter, the section name will be prefixed by the name of the
+chapter. A value of 0 will disable this behavior.
+
+Default value is 1.
+@end table
+
+@section json
+JSON based format.
+
+Each section is printed using JSON notation.
+
+This writer accepts options as a list of @var{key}=@var{value} pairs,
+separated by ":".
+
+The description of the accepted options follows.
+
+@table @option
+
+@item compact, c
+If set to 1 enable compact output, that is each section will be
+printed on a single line. Default value is 0.
+@end table
+
+For more information about JSON, see @url{http://www.json.org/}.
+
+@section xml
+XML based format.
+
+The XML output is described in the XML schema description file
+@file{ffprobe.xsd} installed in the FFmpeg datadir.
+
+An updated version of the schema can be retrieved at the url
+@url{http://www.ffmpeg.org/schema/ffprobe.xsd}, which redirects to the
+latest schema committed into the FFmpeg development source code tree.
+
+Note that the output issued will be compliant to the
+@file{ffprobe.xsd} schema only when no special global output options
+(@option{unit}, @option{prefix}, @option{byte_binary_prefix},
+@option{sexagesimal} etc.) are specified.
+
+This writer accepts options as a list of @var{key}=@var{value} pairs,
+separated by ":".
+
+The description of the accepted options follows.
+
+@table @option
+
+@item fully_qualified, q
+If set to 1 specify if the output should be fully qualified. Default
+value is 0.
+This is required for generating an XML file which can be validated
+through an XSD file.
+
+@item xsd_compliant, x
+If set to 1 perform more checks for ensuring that the output is XSD
+compliant. Default value is 0.
+This option automatically sets @option{fully_qualified} to 1.
+@end table
+
+For more information about the XML format, see
+@url{http://www.w3.org/XML/}.
+@c man end WRITERS
+
+@chapter Timecode
+@c man begin TIMECODE
+
+@command{ffprobe} supports Timecode extraction:
+
+@itemize
+
+@item
+MPEG1/2 timecode is extracted from the GOP, and is available in the video
+stream details (@option{-show_streams}, see @var{timecode}).
+
+@item
+MOV timecode is extracted from tmcd track, so is available in the tmcd
+stream metadata (@option{-show_streams}, see @var{TAG:timecode}).
+
+@item
+DV, GXF and AVI timecodes are available in format metadata
+(@option{-show_format}, see @var{TAG:timecode}).
+
+@end itemize
+@c man end TIMECODE
+
+@include syntax.texi
+@include decoders.texi
+@include demuxers.texi
+@include protocols.texi
+@include indevs.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
new file mode 100644
index 0000000..d9c9392
--- /dev/null
+++ b/doc/ffprobe.xsd
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    targetNamespace="http://www.ffmpeg.org/schema/ffprobe"
+    xmlns:ffprobe="http://www.ffmpeg.org/schema/ffprobe">
+
+    <xsd:element name="ffprobe" type="ffprobe:ffprobeType"/>
+
+    <xsd:complexType name="ffprobeType">
+        <xsd:sequence>
+            <xsd:element name="packets"  type="ffprobe:packetsType" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="frames"   type="ffprobe:framesType"  minOccurs="0" maxOccurs="1" />
+            <xsd:element name="streams"  type="ffprobe:streamsType" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="format"   type="ffprobe:formatType"  minOccurs="0" maxOccurs="1" />
+            <xsd:element name="error"    type="ffprobe:errorType"   minOccurs="0" maxOccurs="1" />
+            <xsd:element name="program_version"  type="ffprobe:programVersionType"  minOccurs="0" maxOccurs="1" />
+            <xsd:element name="library_versions" type="ffprobe:libraryVersionsType" minOccurs="0" maxOccurs="1" />
+        </xsd:sequence>
+    </xsd:complexType>
+
+    <xsd:complexType name="packetsType">
+        <xsd:sequence>
+            <xsd:element name="packet" type="ffprobe:packetType" minOccurs="0" maxOccurs="unbounded"/>
+        </xsd:sequence>
+    </xsd:complexType>
+
+    <xsd:complexType name="framesType">
+        <xsd:sequence>
+            <xsd:element name="frame" type="ffprobe:frameType" minOccurs="0" maxOccurs="unbounded"/>
+        </xsd:sequence>
+    </xsd:complexType>
+
+    <xsd:complexType name="packetType">
+      <xsd:attribute name="codec_type"    type="xsd:string" use="required" />
+      <xsd:attribute name="stream_index"  type="xsd:int" use="required" />
+      <xsd:attribute name="pts"           type="xsd:long"  />
+      <xsd:attribute name="pts_time"      type="xsd:float" />
+      <xsd:attribute name="dts"           type="xsd:long"  />
+      <xsd:attribute name="dts_time"      type="xsd:float" />
+      <xsd:attribute name="duration"      type="xsd:long"  />
+      <xsd:attribute name="duration_time" type="xsd:float" />
+      <xsd:attribute name="convergence_duration"      type="xsd:long"  />
+      <xsd:attribute name="convergence_duration_time" type="xsd:float" />
+      <xsd:attribute name="size"          type="xsd:long" use="required" />
+      <xsd:attribute name="pos"           type="xsd:long"  />
+      <xsd:attribute name="flags"         type="xsd:string" use="required" />
+      <xsd:attribute name="data"          type="xsd:string" />
+    </xsd:complexType>
+
+    <xsd:complexType name="frameType">
+      <xsd:attribute name="media_type"    type="xsd:string" use="required"/>
+      <xsd:attribute name="key_frame"     type="xsd:int"    use="required"/>
+      <xsd:attribute name="pts"           type="xsd:long" />
+      <xsd:attribute name="pts_time"      type="xsd:float"/>
+      <xsd:attribute name="pkt_pts"       type="xsd:long" />
+      <xsd:attribute name="pkt_pts_time"  type="xsd:float"/>
+      <xsd:attribute name="pkt_dts"       type="xsd:long" />
+      <xsd:attribute name="pkt_dts_time"  type="xsd:float"/>
+      <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" />
+
+      <!-- audio attributes -->
+      <xsd:attribute name="sample_fmt"             type="xsd:string"/>
+      <xsd:attribute name="nb_samples"             type="xsd:long"  />
+      <xsd:attribute name="channels"               type="xsd:int"   />
+      <xsd:attribute name="channel_layout"         type="xsd:string"/>
+
+      <!-- video attributes -->
+      <xsd:attribute name="width"                  type="xsd:long"  />
+      <xsd:attribute name="height"                 type="xsd:long"  />
+      <xsd:attribute name="pix_fmt"                type="xsd:string"/>
+      <xsd:attribute name="sample_aspect_ratio"    type="xsd:string"/>
+      <xsd:attribute name="pict_type"              type="xsd:string"/>
+      <xsd:attribute name="coded_picture_number"   type="xsd:long"  />
+      <xsd:attribute name="display_picture_number" type="xsd:long"  />
+      <xsd:attribute name="interlaced_frame"       type="xsd:int"   />
+      <xsd:attribute name="top_field_first"        type="xsd:int"   />
+      <xsd:attribute name="repeat_pict"            type="xsd:int"   />
+      <xsd:attribute name="reference"              type="xsd:int"   />
+    </xsd:complexType>
+
+    <xsd:complexType name="streamsType">
+        <xsd:sequence>
+            <xsd:element name="stream" type="ffprobe:streamType" minOccurs="0" maxOccurs="unbounded"/>
+        </xsd:sequence>
+    </xsd:complexType>
+
+    <xsd:complexType name="streamDispositionType">
+      <xsd:attribute name="default"          type="xsd:int" use="required" />
+      <xsd:attribute name="dub"              type="xsd:int" use="required" />
+      <xsd:attribute name="original"         type="xsd:int" use="required" />
+      <xsd:attribute name="comment"          type="xsd:int" use="required" />
+      <xsd:attribute name="lyrics"           type="xsd:int" use="required" />
+      <xsd:attribute name="karaoke"          type="xsd:int" use="required" />
+      <xsd:attribute name="forced"           type="xsd:int" use="required" />
+      <xsd:attribute name="hearing_impaired" type="xsd:int" use="required" />
+      <xsd:attribute name="visual_impaired"  type="xsd:int" use="required" />
+      <xsd:attribute name="clean_effects"    type="xsd:int" use="required" />
+      <xsd:attribute name="attached_pic"     type="xsd:int" use="required" />
+    </xsd:complexType>
+
+    <xsd:complexType name="streamType">
+      <xsd:sequence>
+        <xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
+        <xsd:element name="disposition" type="ffprobe:streamDispositionType" minOccurs="0" maxOccurs="1"/>
+      </xsd:sequence>
+
+      <xsd:attribute name="index"            type="xsd:int" use="required"/>
+      <xsd:attribute name="codec_name"       type="xsd:string" />
+      <xsd:attribute name="codec_long_name"  type="xsd:string" />
+      <xsd:attribute name="profile"          type="xsd:string" />
+      <xsd:attribute name="codec_type"       type="xsd:string" />
+      <xsd:attribute name="codec_time_base"  type="xsd:string" use="required"/>
+      <xsd:attribute name="codec_tag"        type="xsd:string" use="required"/>
+      <xsd:attribute name="codec_tag_string" type="xsd:string" use="required"/>
+      <xsd:attribute name="extradata"        type="xsd:string" />
+
+      <!-- video attributes -->
+      <xsd:attribute name="width"                type="xsd:int"/>
+      <xsd:attribute name="height"               type="xsd:int"/>
+      <xsd:attribute name="has_b_frames"         type="xsd:int"/>
+      <xsd:attribute name="sample_aspect_ratio"  type="xsd:string"/>
+      <xsd:attribute name="display_aspect_ratio" type="xsd:string"/>
+      <xsd:attribute name="pix_fmt"              type="xsd:string"/>
+      <xsd:attribute name="level"                type="xsd:int"/>
+      <xsd:attribute name="timecode"             type="xsd:string"/>
+
+      <!-- audio attributes -->
+      <xsd:attribute name="sample_fmt"       type="xsd:string"/>
+      <xsd:attribute name="sample_rate"      type="xsd:int"/>
+      <xsd:attribute name="channels"         type="xsd:int"/>
+      <xsd:attribute name="bits_per_sample"  type="xsd:int"/>
+
+      <xsd:attribute name="id"               type="xsd:string"/>
+      <xsd:attribute name="r_frame_rate"     type="xsd:string" use="required"/>
+      <xsd:attribute name="avg_frame_rate"   type="xsd:string" use="required"/>
+      <xsd:attribute name="time_base"        type="xsd:string" use="required"/>
+      <xsd:attribute name="start_pts"        type="xsd:long"/>
+      <xsd:attribute name="start_time"       type="xsd:float"/>
+      <xsd:attribute name="duration_ts"      type="xsd:long"/>
+      <xsd:attribute name="duration"         type="xsd:float"/>
+      <xsd:attribute name="bit_rate"         type="xsd:int"/>
+      <xsd:attribute name="nb_frames"        type="xsd:int"/>
+      <xsd:attribute name="nb_read_frames"   type="xsd:int"/>
+      <xsd:attribute name="nb_read_packets"  type="xsd:int"/>
+    </xsd:complexType>
+
+    <xsd:complexType name="formatType">
+      <xsd:sequence>
+        <xsd:element name="tag" type="ffprobe:tagType" minOccurs="0" maxOccurs="unbounded"/>
+      </xsd:sequence>
+
+      <xsd:attribute name="filename"         type="xsd:string" use="required"/>
+      <xsd:attribute name="nb_streams"       type="xsd:int"    use="required"/>
+      <xsd:attribute name="format_name"      type="xsd:string" use="required"/>
+      <xsd:attribute name="format_long_name" type="xsd:string"/>
+      <xsd:attribute name="start_time"       type="xsd:float"/>
+      <xsd:attribute name="duration"         type="xsd:float"/>
+      <xsd:attribute name="size"             type="xsd:long"/>
+      <xsd:attribute name="bit_rate"         type="xsd:long"/>
+    </xsd:complexType>
+
+    <xsd:complexType name="tagType">
+      <xsd:attribute name="key"   type="xsd:string" use="required"/>
+      <xsd:attribute name="value" type="xsd:string" use="required"/>
+    </xsd:complexType>
+
+    <xsd:complexType name="errorType">
+      <xsd:attribute name="code"   type="xsd:int"    use="required"/>
+      <xsd:attribute name="string" type="xsd:string" use="required"/>
+    </xsd:complexType>
+
+    <xsd:complexType name="programVersionType">
+      <xsd:attribute name="version"          type="xsd:string" use="required"/>
+      <xsd:attribute name="copyright"        type="xsd:string" use="required"/>
+      <xsd:attribute name="build_date"       type="xsd:string" use="required"/>
+      <xsd:attribute name="build_time"       type="xsd:string" use="required"/>
+      <xsd:attribute name="compiler_type"    type="xsd:string" use="required"/>
+      <xsd:attribute name="compiler_version" type="xsd:string" use="required"/>
+      <xsd:attribute name="configuration"    type="xsd:string" use="required"/>
+    </xsd:complexType>
+
+    <xsd:complexType name="libraryVersionType">
+      <xsd:attribute name="name"        type="xsd:string" use="required"/>
+      <xsd:attribute name="major"       type="xsd:int"    use="required"/>
+      <xsd:attribute name="minor"       type="xsd:int"    use="required"/>
+      <xsd:attribute name="micro"       type="xsd:int"    use="required"/>
+      <xsd:attribute name="version"     type="xsd:int"    use="required"/>
+      <xsd:attribute name="ident"       type="xsd:string" use="required"/>
+    </xsd:complexType>
+
+    <xsd:complexType name="libraryVersionsType">
+        <xsd:sequence>
+          <xsd:element name="library_version" type="ffprobe:libraryVersionType" minOccurs="0" maxOccurs="unbounded"/>
+        </xsd:sequence>
+    </xsd:complexType>
+</xsd:schema>
diff --git a/doc/ffserver.conf b/doc/ffserver.conf
new file mode 100644
index 0000000..d10ac5b
--- /dev/null
+++ b/doc/ffserver.conf
@@ -0,0 +1,375 @@
+# Port on which the server is listening. You must select a different
+# port from your standard HTTP web server if it is running on the same
+# computer.
+Port 8090
+
+# Address on which the server is bound. Only useful if you have
+# several network interfaces.
+BindAddress 0.0.0.0
+
+# Number of simultaneous HTTP connections that can be handled. It has
+# to be defined *before* the MaxClients parameter, since it defines the
+# MaxClients maximum limit.
+MaxHTTPConnections 2000
+
+# Number of simultaneous requests that can be handled. Since FFServer
+# is very fast, it is more likely that you will want to leave this high
+# and use MaxBandwidth, below.
+MaxClients 1000
+
+# This the maximum amount of kbit/sec that you are prepared to
+# consume when streaming to clients.
+MaxBandwidth 1000
+
+# Access log file (uses standard Apache log file format)
+# '-' is the standard output.
+CustomLog -
+
+# Suppress that if you want to launch ffserver as a daemon.
+NoDaemon
+
+
+##################################################################
+# Definition of the live feeds. Each live feed contains one video
+# and/or audio sequence coming from an ffmpeg encoder or another
+# ffserver. This sequence may be encoded simultaneously with several
+# codecs at several resolutions.
+
+<Feed feed1.ffm>
+
+# You must use 'ffmpeg' to send a live feed to ffserver. In this
+# example, you can type:
+#
+# ffmpeg http://localhost:8090/feed1.ffm
+
+# ffserver can also do time shifting. It means that it can stream any
+# previously recorded live stream. The request should contain:
+# "http://xxxx?date=[YYYY-MM-DDT][[HH:]MM:]SS[.m...]".You must specify
+# a path where the feed is stored on disk. You also specify the
+# maximum size of the feed, where zero means unlimited. Default:
+# File=/tmp/feed_name.ffm FileMaxSize=5M
+File /tmp/feed1.ffm
+FileMaxSize 200K
+
+# You could specify
+# ReadOnlyFile /saved/specialvideo.ffm
+# This marks the file as readonly and it will not be deleted or updated.
+
+# Specify launch in order to start ffmpeg automatically.
+# First ffmpeg must be defined with an appropriate path if needed,
+# after that options can follow, but avoid adding the http:// field
+#Launch ffmpeg
+
+# Only allow connections from localhost to the feed.
+ACL allow 127.0.0.1
+
+</Feed>
+
+
+##################################################################
+# Now you can define each stream which will be generated from the
+# original audio and video stream. Each format has a filename (here
+# 'test1.mpg'). FFServer will send this stream when answering a
+# request containing this filename.
+
+<Stream test1.mpg>
+
+# coming from live feed 'feed1'
+Feed feed1.ffm
+
+# Format of the stream : you can choose among:
+# mpeg       : MPEG-1 multiplexed video and audio
+# mpegvideo  : only MPEG-1 video
+# mp2        : MPEG-2 audio (use AudioCodec to select layer 2 and 3 codec)
+# ogg        : Ogg format (Vorbis audio codec)
+# rm         : RealNetworks-compatible stream. Multiplexed audio and video.
+# ra         : RealNetworks-compatible stream. Audio only.
+# mpjpeg     : Multipart JPEG (works with Netscape without any plugin)
+# jpeg       : Generate a single JPEG image.
+# asf        : ASF compatible streaming (Windows Media Player format).
+# swf        : Macromedia Flash compatible stream
+# avi        : AVI format (MPEG-4 video, MPEG audio sound)
+Format mpeg
+
+# Bitrate for the audio stream. Codecs usually support only a few
+# different bitrates.
+AudioBitRate 32
+
+# Number of audio channels: 1 = mono, 2 = stereo
+AudioChannels 1
+
+# Sampling frequency for audio. When using low bitrates, you should
+# lower this frequency to 22050 or 11025. The supported frequencies
+# depend on the selected audio codec.
+AudioSampleRate 44100
+
+# Bitrate for the video stream
+VideoBitRate 64
+
+# Ratecontrol buffer size
+VideoBufferSize 40
+
+# Number of frames per second
+VideoFrameRate 3
+
+# Size of the video frame: WxH (default: 160x128)
+# The following abbreviations are defined: sqcif, qcif, cif, 4cif, qqvga,
+# qvga, vga, svga, xga, uxga, qxga, sxga, qsxga, hsxga, wvga, wxga, wsxga,
+# wuxga, woxga, wqsxga, wquxga, whsxga, whuxga, cga, ega, hd480, hd720,
+# hd1080
+VideoSize 160x128
+
+# Transmit only intra frames (useful for low bitrates, but kills frame rate).
+#VideoIntraOnly
+
+# If non-intra only, an intra frame is transmitted every VideoGopSize
+# frames. Video synchronization can only begin at an intra frame.
+VideoGopSize 12
+
+# More MPEG-4 parameters
+# VideoHighQuality
+# Video4MotionVector
+
+# Choose your codecs:
+#AudioCodec mp2
+#VideoCodec mpeg1video
+
+# Suppress audio
+#NoAudio
+
+# Suppress video
+#NoVideo
+
+#VideoQMin 3
+#VideoQMax 31
+
+# Set this to the number of seconds backwards in time to start. Note that
+# most players will buffer 5-10 seconds of video, and also you need to allow
+# for a keyframe to appear in the data stream.
+#Preroll 15
+
+# ACL:
+
+# You can allow ranges of addresses (or single addresses)
+#ACL ALLOW <first address> <last address>
+
+# You can deny ranges of addresses (or single addresses)
+#ACL DENY <first address> <last address>
+
+# You can repeat the ACL allow/deny as often as you like. It is on a per
+# stream basis. The first match defines the action. If there are no matches,
+# then the default is the inverse of the last ACL statement.
+#
+# Thus 'ACL allow localhost' only allows access from localhost.
+# 'ACL deny 1.0.0.0 1.255.255.255' would deny the whole of network 1 and
+# allow everybody else.
+
+</Stream>
+
+
+##################################################################
+# Example streams
+
+
+# Multipart JPEG
+
+#<Stream test.mjpg>
+#Feed feed1.ffm
+#Format mpjpeg
+#VideoFrameRate 2
+#VideoIntraOnly
+#NoAudio
+#Strict -1
+#</Stream>
+
+
+# Single JPEG
+
+#<Stream test.jpg>
+#Feed feed1.ffm
+#Format jpeg
+#VideoFrameRate 2
+#VideoIntraOnly
+##VideoSize 352x240
+#NoAudio
+#Strict -1
+#</Stream>
+
+
+# Flash
+
+#<Stream test.swf>
+#Feed feed1.ffm
+#Format swf
+#VideoFrameRate 2
+#VideoIntraOnly
+#NoAudio
+#</Stream>
+
+
+# ASF compatible
+
+<Stream test.asf>
+Feed feed1.ffm
+Format asf
+VideoFrameRate 15
+VideoSize 352x240
+VideoBitRate 256
+VideoBufferSize 40
+VideoGopSize 30
+AudioBitRate 64
+StartSendOnKey
+</Stream>
+
+
+# MP3 audio
+
+#<Stream test.mp3>
+#Feed feed1.ffm
+#Format mp2
+#AudioCodec mp3
+#AudioBitRate 64
+#AudioChannels 1
+#AudioSampleRate 44100
+#NoVideo
+#</Stream>
+
+
+# Ogg Vorbis audio
+
+#<Stream test.ogg>
+#Feed feed1.ffm
+#Title "Stream title"
+#AudioBitRate 64
+#AudioChannels 2
+#AudioSampleRate 44100
+#NoVideo
+#</Stream>
+
+
+# Real with audio only at 32 kbits
+
+#<Stream test.ra>
+#Feed feed1.ffm
+#Format rm
+#AudioBitRate 32
+#NoVideo
+#NoAudio
+#</Stream>
+
+
+# Real with audio and video at 64 kbits
+
+#<Stream test.rm>
+#Feed feed1.ffm
+#Format rm
+#AudioBitRate 32
+#VideoBitRate 128
+#VideoFrameRate 25
+#VideoGopSize 25
+#NoAudio
+#</Stream>
+
+
+##################################################################
+# A stream coming from a file: you only need to set the input
+# filename and optionally a new format. Supported conversions:
+#    AVI -> ASF
+
+#<Stream file.rm>
+#File "/usr/local/httpd/htdocs/tlive.rm"
+#NoAudio
+#</Stream>
+
+#<Stream file.asf>
+#File "/usr/local/httpd/htdocs/test.asf"
+#NoAudio
+#Author "Me"
+#Copyright "Super MegaCorp"
+#Title "Test stream from disk"
+#Comment "Test comment"
+#</Stream>
+
+
+##################################################################
+# RTSP examples
+#
+# You can access this stream with the RTSP URL:
+#   rtsp://localhost:5454/test1-rtsp.mpg
+#
+# A non-standard RTSP redirector is also created. Its URL is:
+#   http://localhost:8090/test1-rtsp.rtsp
+
+#<Stream test1-rtsp.mpg>
+#Format rtp
+#File "/usr/local/httpd/htdocs/test1.mpg"
+#</Stream>
+
+
+# Transcode an incoming live feed to another live feed,
+# using libx264 and video presets
+
+#<Stream live.h264>
+#Format rtp
+#Feed feed1.ffm
+#VideoCodec libx264
+#VideoFrameRate 24
+#VideoBitRate 100
+#VideoSize 480x272
+#AVPresetVideo default
+#AVPresetVideo baseline
+#AVOptionVideo flags +global_header
+#
+#AudioCodec libfaac
+#AudioBitRate 32
+#AudioChannels 2
+#AudioSampleRate 22050
+#AVOptionAudio flags +global_header
+#</Stream>
+
+##################################################################
+# SDP/multicast examples
+#
+# If you want to send your stream in multicast, you must set the
+# multicast address with MulticastAddress. The port and the TTL can
+# also be set.
+#
+# An SDP file is automatically generated by ffserver by adding the
+# 'sdp' extension to the stream name (here
+# http://localhost:8090/test1-sdp.sdp). You should usually give this
+# file to your player to play the stream.
+#
+# The 'NoLoop' option can be used to avoid looping when the stream is
+# terminated.
+
+#<Stream test1-sdp.mpg>
+#Format rtp
+#File "/usr/local/httpd/htdocs/test1.mpg"
+#MulticastAddress 224.124.0.1
+#MulticastPort 5000
+#MulticastTTL 16
+#NoLoop
+#</Stream>
+
+
+##################################################################
+# Special streams
+
+# Server status
+
+<Stream stat.html>
+Format status
+
+# Only allow local people to get the status
+ACL allow localhost
+ACL allow 192.168.0.0 192.168.255.255
+
+#FaviconURL http://pond1.gladstonefamily.net:8080/favicon.ico
+</Stream>
+
+
+# Redirect index.html to the appropriate site
+
+<Redirect index.html>
+URL http://www.ffmpeg.org/
+</Redirect>
diff --git a/doc/ffserver.texi b/doc/ffserver.texi
new file mode 100644
index 0000000..074c075
--- /dev/null
+++ b/doc/ffserver.texi
@@ -0,0 +1,279 @@
+\input texinfo @c -*- texinfo -*-
+
+@settitle ffserver Documentation
+@titlepage
+@center @titlefont{ffserver Documentation}
+@end titlepage
+
+@top
+
+@contents
+
+@chapter Synopsys
+
+The generic syntax is:
+
+@example
+@c man begin SYNOPSIS
+ffserver [options]
+@c man end
+@end example
+
+@chapter Description
+@c man begin DESCRIPTION
+
+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 ffserver.conf).
+
+ffserver runs in daemon mode by default; that is, it puts itself in
+the background and detaches from its TTY, unless it is launched in
+debug mode or a NoDaemon option is specified in the configuration
+file.
+
+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.
+
+@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.
+
+For each feed you can have different output streams in various
+formats, each one specified by a <Stream> section in the configuration
+file.
+
+@section Status stream
+
+ffserver supports an HTTP interface which exposes the current status
+of the server.
+
+Simply point your browser to the address of the special status stream
+specified in the configuration file.
+
+For example if you have:
+@example
+<Stream status.html>
+Format status
+
+# Only allow local people to get the status
+ACL allow localhost
+ACL allow 192.168.0.0 192.168.255.255
+</Stream>
+@end example
+
+then the server will post a page with the status information when
+the special stream @file{status.html} is requested.
+
+@section What can this do?
+
+When properly configured and running, you can capture video and audio in real
+time from a suitable capture card, and stream it out over the Internet to
+either Windows Media Player or RealAudio player (with some restrictions).
+
+It can also stream from files, though that is currently broken. Very often, a
+web server can be used to serve up the files just as well.
+
+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
+you run the ffserver ./configure, make sure that you have the
+@code{--enable-libmp3lame} flag turned on.
+
+LAME is important as it allows for streaming audio to Windows Media Player.
+Don't ask why the other audio types do not work.
+
+As a simple test, just run the following two command lines where INPUTFILE
+is some file which you can decode with ffmpeg:
+
+@example
+ffserver -f doc/ffserver.conf &
+ffmpeg -i INPUTFILE http://localhost:8090/feed1.ffm
+@end example
+
+At this point you should be able to go to your Windows machine and fire up
+Windows Media Player (WMP). Go to Open URL and enter
+
+@example
+    http://<linuxbox>:8090/test.asf
+@end example
+
+You should (after a short delay) see video and hear audio.
+
+WARNING: trying to stream test1.mpg doesn't work with WMP as it tries to
+transfer the entire file before starting to play.
+The same is true of AVI files.
+
+@section What happens next?
+
+You should edit the ffserver.conf file to suit your needs (in terms of
+frame rates etc). Then install ffserver and ffmpeg, write a script to start
+them up, and off you go.
+
+@section Troubleshooting
+
+@subsection I don't hear any audio, but video is fine.
+
+Maybe you didn't install LAME, or got your ./configure statement wrong. Check
+the ffmpeg output to see if a line referring to MP3 is present. If not, then
+your configuration was incorrect. If it is, then maybe your wiring is not
+set up correctly. Maybe the sound card is not getting data from the right
+input source. Maybe you have a really awful audio interface (like I do)
+that only captures in stereo and also requires that one channel be flipped.
+If you are one of these people, then export 'AUDIO_FLIP_LEFT=1' before
+starting ffmpeg.
+
+@subsection The audio and video lose sync after a while.
+
+Yes, they do.
+
+@subsection After a long while, the video update rate goes way down in WMP.
+
+Yes, it does. Who knows why?
+
+@subsection WMP 6.4 behaves differently to WMP 7.
+
+Yes, it does. Any thoughts on this would be gratefully received. These
+differences extend to embedding WMP into a web page. [There are two
+object IDs that you can use: The old one, which does not play well, and
+the new one, which does (both tested on the same system). However,
+I suspect that the new one is not available unless you have installed WMP 7].
+
+@section What else can it do?
+
+You can replay video from .ffm files that was recorded earlier.
+However, there are a number of caveats, including the fact that the
+ffserver parameters must match the original parameters used to record the
+file. If they do not, then ffserver deletes the file before recording into it.
+(Now that I write this, it seems broken).
+
+You can fiddle with many of the codec choices and encoding parameters, and
+there are a bunch more parameters that you cannot control. Post a message
+to the mailing list if there are some 'must have' parameters. Look in
+ffserver.conf for a list of the currently available controls.
+
+It will automatically generate the ASX or RAM files that are often used
+in browsers. These files are actually redirections to the underlying ASF
+or RM file. The reason for this is that the browser often fetches the
+entire file before starting up the external viewer. The redirection files
+are very small and can be transferred quickly. [The stream itself is
+often 'infinite' and thus the browser tries to download it and never
+finishes.]
+
+@section Tips
+
+* When you connect to a live stream, most players (WMP, RA, etc) want to
+buffer a certain number of seconds of material so that they can display the
+signal continuously. However, ffserver (by default) starts sending data
+in realtime. This means that there is a pause of a few seconds while the
+buffering is being done by the player. The good news is that this can be
+cured by adding a '?buffer=5' to the end of the URL. This means that the
+stream should start 5 seconds in the past -- and so the first 5 seconds
+of the stream are sent as fast as the network will allow. It will then
+slow down to real time. This noticeably improves the startup experience.
+
+You can also add a 'Preroll 15' statement into the ffserver.conf that will
+add the 15 second prebuffering on all requests that do not otherwise
+specify a time. In addition, ffserver will skip frames until a key_frame
+is found. This further reduces the startup delay by not transferring data
+that will be discarded.
+
+* You may want to adjust the MaxBandwidth in the ffserver.conf to limit
+the amount of bandwidth consumed by live streams.
+
+@section Why does the ?buffer / Preroll stop working after a time?
+
+It turns out that (on my machine at least) the number of frames successfully
+grabbed is marginally less than the number that ought to be grabbed. This
+means that the timestamp in the encoded data stream gets behind realtime.
+This means that if you say 'Preroll 10', then when the stream gets 10
+or more seconds behind, there is no Preroll left.
+
+Fixing this requires a change in the internals of how timestamps are
+handled.
+
+@section Does the @code{?date=} stuff work.
+
+Yes (subject to the limitation outlined above). Also note that whenever you
+start ffserver, it deletes the ffm file (if any parameters have changed),
+thus wiping out what you had recorded before.
+
+The format of the @code{?date=xxxxxx} is fairly flexible. You should use one
+of the following formats (the 'T' is literal):
+
+@example
+* YYYY-MM-DDTHH:MM:SS     (localtime)
+* YYYY-MM-DDTHH:MM:SSZ    (UTC)
+@end example
+
+You can omit the YYYY-MM-DD, and then it refers to the current day. However
+note that @samp{?date=16:00:00} refers to 16:00 on the current day -- this
+may be in the future and so is unlikely to be useful.
+
+You use this by adding the ?date= to the end of the URL for the stream.
+For example:   @samp{http://localhost:8080/test.asf?date=2002-07-26T23:05:00}.
+@c man end
+
+@chapter Options
+@c man begin OPTIONS
+
+@include avtools-common-opts.texi
+
+@section Main options
+
+@table @option
+@item -f @var{configfile}
+Use @file{configfile} instead of @file{/etc/ffserver.conf}.
+@item -n
+Enable no-launch mode. This option disables all the Launch directives
+within the various <Stream> sections. Since ffserver will not launch
+any ffmpeg instances, you will have to launch them manually.
+@item -d
+Enable debug mode. This option increases log verbosity, directs log
+messages to stdout and causes ffserver to run in the foreground
+rather than as a daemon.
+@end table
+@c man end
+
+@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
new file mode 100644
index 0000000..11bcc72
--- /dev/null
+++ b/doc/filter_design.txt
@@ -0,0 +1,269 @@
+Filter design
+=============
+
+This document explains guidelines that should be observed (or ignored with
+good reason) when writing filters for libavfilter.
+
+In this document, the word “frame” indicates either a video frame or a group
+of audio samples, as stored in an AVFilterBuffer structure.
+
+
+Format negotiation
+==================
+
+  The query_formats method should set, for each input and each output links,
+  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).
+
+  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
+  eventually chosen for a link amongst the remaining list, again, all
+  references to the list are updated.
+
+  That means that if a filter requires that its input and output have the
+  same format amongst a supported list, all it has to do is use a reference
+  to the same list of formats.
+
+
+Buffer references ownership and permissions
+===========================================
+
+  Principle
+  ---------
+
+    Audio and video data are voluminous; the buffer and buffer reference
+    mechanism is intended to avoid, as much as possible, expensive copies of
+    that data while still allowing the filters to produce correct results.
+
+    The data is stored in buffers represented by AVFilterBuffer structures.
+    They must not be accessed directly, but through references stored in
+    AVFilterBufferRef structures. Several references can point to the
+    same buffer; the buffer is automatically deallocated once all
+    corresponding references have been destroyed.
+
+    The characteristics of the data (resolution, sample rate, etc.) are
+    stored in the reference; different references for the same buffer can
+    show different characteristics. In particular, a video reference can
+    point to only a part of a video buffer.
+
+    A reference is usually obtained as input to the start_frame or
+    filter_samples method or requested using the ff_get_video_buffer or
+    ff_get_audio_buffer functions. A new reference on an existing buffer can
+    be created with the avfilter_ref_buffer. A reference is destroyed using
+    the avfilter_unref_bufferp function.
+
+  Reference ownership
+  -------------------
+
+    At any time, a reference “belongs” to a particular piece of code,
+    usually a filter. With a few caveats that will be explained below, only
+    that piece of code is allowed to access it. It is also responsible for
+    destroying it, although this is sometimes done automatically (see the
+    section on link reference fields).
+
+    Here are the (fairly obvious) rules for reference ownership:
+
+    * A reference received by the start_frame or filter_samples method
+      belong 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_samples is given
+      away and must no longer be used.
+
+    * A reference created with avfilter_ref_buffer belongs to the code that
+      created it.
+
+    * A reference obtained with ff_get_video_buffer or ff_get_audio_buffer
+      belongs to the code that requested it.
+
+    * A reference given as return value by the get_video_buffer or
+      get_audio_buffer method is given away and must no longer be used.
+
+  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_samples 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_samples, 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_samples, 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.
+
+  Reference permissions
+  ---------------------
+
+    The AVFilterBufferRef structure has a perms field that describes what
+    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.
+
+    The value is a binary OR of the following constants:
+
+    * AV_PERM_READ: the owner can read the buffer data; this is essentially
+      always true and is there for self-documentation.
+
+    * AV_PERM_WRITE: the owner can modify the buffer data.
+
+    * AV_PERM_PRESERVE: the owner can rely on the fact that the buffer data
+      will not be modified by previous filters.
+
+    * AV_PERM_REUSE: the owner can output the buffer several times, without
+      modifying the data in between.
+
+    * AV_PERM_REUSE2: the owner can output the buffer several times and
+      modify the data in between (useless without the WRITE permissions).
+
+    * AV_PERM_ALIGN: the owner can access the data using fast operations
+      that require data alignment.
+
+    The READ, WRITE and PRESERVE permissions are about sharing the same
+    buffer between several filters to avoid expensive copies without them
+    doing conflicting changes on the data.
+
+    The REUSE and REUSE2 permissions are about special memory for direct
+    rendering. For example a buffer directly allocated in video memory must
+    not modified once it is displayed on screen, or it will cause tearing;
+    it will therefore not have the REUSE2 permission.
+
+    The ALIGN permission is about extracting part of the buffer, for
+    copy-less padding or cropping for example.
+
+
+    References received on input pads are guaranteed to have all the
+    permissions stated in the min_perms field and none of the permissions
+    stated in the rej_perms.
+
+    References obtained by ff_get_video_buffer and ff_get_audio_buffer are
+    guaranteed to have at least all the permissions requested as argument.
+
+    References created by avfilter_ref_buffer have the same permissions as
+    the original reference minus the ones explicitly masked; the mask is
+    usually ~0 to keep the same permissions.
+
+    Filters should remove permissions on reference they give to output
+    whenever necessary. It can be automatically done by setting the
+    rej_perms field on the output pad.
+
+    Here are a few guidelines corresponding to common situations:
+
+    * Filters that modify and forward their frame (like drawtext) need the
+      WRITE permission.
+
+    * Filters that read their input to produce a new frame on output (like
+      scale) need the READ permission on input and and must request a buffer
+      with the WRITE permission.
+
+    * Filters that intend to keep a reference after the filtering process
+      is finished (after end_frame or filter_samples 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
+      the PRESERVE permission if they create a new reference to give it
+      away.
+
+
+Frame scheduling
+================
+
+  The purpose of these rules is to ensure that frames flow in the filter
+  graph without getting stuck and accumulating somewhere.
+
+  Simple filters that output one frame for each input frame should not have
+  to worry about it.
+
+  start_frame / filter_samples
+  ----------------------------
+
+    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.
+
+    If the input frame is enough to produce output, then the filter should
+    push the output frames on the output link immediately.
+
+    As an exception to the previous rule, if the input frame is enough to
+    produce several output frames, then the filter needs output only at
+    least one per link. The additional frames can be left buffered in the
+    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
+    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.)
+
+    If the input frame is not enough to produce output, the filter must not
+    call request_frame to get more. It must just process the frame or queue
+    it. The task of requesting more frames is left to the filter's
+    request_frame method or the application.
+
+    If a filter has several inputs, the filter must be ready for frames
+    arriving randomly on any input. Therefore, any filter with several inputs
+    will most likely require some kind of queuing mechanism. It is perfectly
+    acceptable to have a limited queue and to drop frames when the inputs
+    are too unbalanced.
+
+  request_frame
+  -------------
+
+    This method is called when a frame is wanted on an output.
+
+    For an input, it should directly call start_frame or filter_samples 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
+    one of its inputs, repeatedly until at least one frame has been pushed.
+
+    Return values:
+    if request_frame could produce a frame, it should return 0;
+    if it could not for temporary reasons, it should return AVERROR(EAGAIN);
+    if it could not because there are no more frames, it should return
+    AVERROR_EOF.
+
+    The typical implementation of request_frame for a filter with several
+    inputs will look like that:
+
+        if (frames_queued) {
+            push_one_frame();
+            return 0;
+        }
+        while (!frame_pushed) {
+            input = input_where_a_frame_is_most_needed();
+            ret = avfilter_request_frame(input);
+            if (ret == AVERROR_EOF) {
+                process_eof_on_input();
+            } else if (ret < 0) {
+                return ret;
+            }
+        }
+        return 0;
+
+    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_samples method will be called and do the work.
diff --git a/doc/filters.texi b/doc/filters.texi
index 8f90e84..725c7b5 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -1,3 +1,99 @@
+@chapter Filtering Introduction
+@c man begin FILTERING INTRODUCTION
+
+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 --------+
+@end example
+
+splits the stream in two streams, sends one stream through the crop filter
+and the vflip filter before merging it back with the other stream by
+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
+@end example
+
+The result will be that in output the top half of the video is mirrored
+onto the bottom half.
+
+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
+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
+where video is input and output.
+
+Some filters take in input a list of parameters: they are specified
+after the filter name and an equal sign, and are separated from each other
+by a colon.
+
+There exist so-called @var{source filters} that do not have an
+audio/video input, and @var{sink filters} that will not have audio/video
+output.
+
+@c man end FILTERING INTRODUCTION
+
+@chapter graph2dot
+@c man begin GRAPH2DOT
+
+The @file{graph2dot} program included in the FFmpeg @file{tools}
+directory can be used to parse a filter graph description and issue a
+corresponding textual representation in the dot language.
+
+Invoke the command:
+@example
+graph2dot -h
+@end example
+
+to see how to use @file{graph2dot}.
+
+You can then pass the dot description to the @file{dot} program (from
+the graphviz suite of programs) and obtain a graphical representation
+of the filter graph.
+
+For example the sequence of commands:
+@example
+echo @var{GRAPH_DESCRIPTION} | \
+tools/graph2dot -o graph.tmp && \
+dot -Tpng graph.tmp -o graph.png && \
+display graph.png
+@end example
+
+can be used to create and display an image representing the graph
+described by the @var{GRAPH_DESCRIPTION} string. Note that this string must be
+a complete self-contained graph, with its inputs and outputs explicitly defined.
+For example if your command line is of the form:
+@example
+ffmpeg -i infile -vf scale=640:360 outfile
+@end example
+your @var{GRAPH_DESCRIPTION} string will need to be of the form:
+@example
+nullsrc,scale=640:360,nullsink
+@end example
+you may also need to set the @var{nullsrc} parameters and add a @var{format}
+filter in order to simulate a specific input file.
+
+@c man end GRAPH2DOT
+
 @chapter Filtergraph description
 @c man begin FILTERGRAPH DESCRIPTION
 
@@ -19,7 +115,7 @@
 
 A filtergraph can be represented using a textual representation, which is
 recognized by the @option{-filter}/@option{-vf} and @option{-filter_complex}
-options in @command{avconv} and @option{-vf} in @command{avplay}, and by the
+options in @command{ffmpeg} and @option{-vf} in @command{ffplay}, and by the
 @code{avfilter_graph_parse()}/@code{avfilter_graph_parse2()} function defined in
 @file{libavfilter/avfiltergraph.h}.
 
@@ -100,13 +196,46 @@
 @chapter Audio Filters
 @c man begin AUDIO FILTERS
 
-When you configure your Libav build, you can disable any of the
-existing filters using --disable-filters.
+When you configure your FFmpeg build, you can disable any of the
+existing filters using @code{--disable-filters}.
 The configure output will show the audio filters included in your
 build.
 
 Below is a description of the currently available audio filters.
 
+@section aconvert
+
+Convert the input audio format to the specified formats.
+
+The filter accepts a string of the form:
+"@var{sample_format}:@var{channel_layout}".
+
+@var{sample_format} specifies the sample format, and can be a string or the
+corresponding numeric value defined in @file{libavutil/samplefmt.h}. Use 'p'
+suffix for a planar sample format.
+
+@var{channel_layout} specifies the channel layout, and can be a string
+or the corresponding number value defined in @file{libavutil/audioconvert.h}.
+
+The special parameter "auto", signifies that the filter will
+automatically select the output format depending on the output filter.
+
+Some examples follow.
+
+@itemize
+@item
+Convert input to float, planar, stereo:
+@example
+aconvert=fltp:stereo
+@end example
+
+@item
+Convert input to unsigned 8-bit, automatically select out channel layout:
+@example
+aconvert=u8:auto
+@end example
+@end itemize
+
 @section aformat
 
 Convert the input audio to one of the specified formats. The framework will
@@ -133,13 +262,65 @@
 aformat=sample_fmts\=u8\,s16:channel_layouts\=stereo
 @end example
 
+@section amerge
+
+Merge two or more audio streams into a single multi-channel stream.
+
+The filter accepts the following named options:
+
+@table @option
+
+@item inputs
+Set the number of inputs. Default is 2.
+
+@end table
+
+If the channel layouts of the inputs are disjoint, and therefore compatible,
+the channel layout of the output will be set accordingly and the channels
+will be reordered as necessary. If the channel layouts of the inputs are not
+disjoint, the output will have all the channels of the first input then all
+the channels of the second input, in that order, and the channel layout of
+the output will be the default value corresponding to the total number of
+channels.
+
+For example, if the first input is in 2.1 (FL+FR+LF) and the second input
+is FC+BL+BR, then the output will be in 5.1, with the channels in the
+following order: a1, a2, b1, a3, b2, b3 (a1 is the first channel of the
+first input, b1 is the first channel of the second input).
+
+On the other hand, if both input are in stereo, the output channels will be
+in the default order: a1, a2, b1, b2, and the channel layout will be
+arbitrarily set to 4.0, which may or may not be the expected value.
+
+All inputs must have the same sample rate, and format.
+
+If inputs do not have the same duration, the output will stop with the
+shortest.
+
+Example: merge two mono files into a stereo stream:
+@example
+amovie=left.wav [l] ; amovie=right.mp3 [r] ; [l] [r] amerge
+@end example
+
+Example: multiple merges:
+@example
+ffmpeg -f lavfi -i "
+amovie=input.mkv:si=0 [a0];
+amovie=input.mkv:si=1 [a1];
+amovie=input.mkv:si=2 [a2];
+amovie=input.mkv:si=3 [a3];
+amovie=input.mkv:si=4 [a4];
+amovie=input.mkv:si=5 [a5];
+[a0][a1][a2][a3][a4][a5] amerge=inputs=6" -c:a pcm_s16le output.mkv
+@end example
+
 @section amix
 
 Mixes multiple audio inputs into a single output.
 
 For example
 @example
-avconv -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex amix=inputs=3:duration=first:dropout_transition=3 OUTPUT
+ffmpeg -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex amix=inputs=3:duration=first:dropout_transition=3 OUTPUT
 @end example
 will mix 3 input audio streams to a single output with the same duration as the
 first input and a dropout transition time of 3 seconds.
@@ -175,6 +356,97 @@
 
 Pass the audio source unchanged to the output.
 
+@section aresample
+
+Resample the input audio to the specified sample rate.
+
+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.
+
+For example, to resample the input audio to 44100Hz:
+@example
+aresample=44100
+@end example
+
+@section asetnsamples
+
+Set the number of samples per each output audio frame.
+
+The last output packet may contain a different number of samples, as
+the filter will flush all the remaining samples when the input audio
+signal its end.
+
+The filter accepts parameters as a list of @var{key}=@var{value} pairs,
+separated by ":".
+
+@table @option
+
+@item nb_out_samples, n
+Set the number of frames per each output audio frame. The number is
+intended as the number of samples @emph{per each channel}.
+Default value is 1024.
+
+@item pad, p
+If set to 1, the filter will pad the last audio frame with zeroes, so
+that the last frame will contain the same number of samples as the
+previous ones. Default value is 1.
+@end table
+
+For example, to set the number of per-frame samples to 1234 and
+disable padding for the last frame, use:
+@example
+asetnsamples=n=1234:p=0
+@end example
+
+@section ashowinfo
+
+Show a line containing various information for each input audio frame.
+The input audio is not modified.
+
+The shown line contains a sequence of key/value pairs of the form
+@var{key}:@var{value}.
+
+A description of each shown parameter follows:
+
+@table @option
+@item n
+sequential number of the input frame, starting from 0
+
+@item pts
+presentation TimeStamp of the input frame, expressed as a number of
+time base units. The time base unit depends on the filter input pad, and
+is usually 1/@var{sample_rate}.
+
+@item pts_time
+presentation TimeStamp of the input frame, expressed as a number of
+seconds
+
+@item pos
+position of the frame in the input stream, -1 if this information in
+unavailable and/or meaningless (for example in case of synthetic audio)
+
+@item fmt
+sample format name
+
+@item chlayout
+channel layout description
+
+@item nb_samples
+number of samples (per each channel) contained in the filtered frame
+
+@item rate
+sample rate for the audio frame
+
+@item checksum
+Adler-32 checksum (printed in hexadecimal) of all the planes of the input frame
+
+@item plane_checksum
+Adler-32 checksum (printed in hexadecimal) for each input frame plane,
+expressed in the form "[@var{c0} @var{c1} @var{c2} @var{c3} @var{c4} @var{c5}
+@var{c6} @var{c7}]"
+@end table
+
 @section asplit
 
 Split input audio into several identical outputs.
@@ -182,12 +454,293 @@
 The filter accepts a single parameter which specifies the number of outputs. If
 unspecified, it defaults to 2.
 
-For example
+For example:
 @example
-avconv -i INPUT -filter_complex asplit=5 OUTPUT
+[in] asplit [out0][out1]
+@end example
+
+will create two separate outputs from the same input.
+
+To create 3 or more outputs, you need to specify the number of
+outputs, like in:
+@example
+[in] asplit=3 [out0][out1][out2]
+@end example
+
+@example
+ffmpeg -i INPUT -filter_complex asplit=5 OUTPUT
 @end example
 will create 5 copies of the input audio.
 
+
+@section astreamsync
+
+Forward two audio streams and control the order the buffers are forwarded.
+
+The argument to the filter is an expression deciding which stream should be
+forwarded next: if the result is negative, the first stream is forwarded; if
+the result is positive or zero, the second stream is forwarded. It can use
+the following variables:
+
+@table @var
+@item b1 b2
+number of buffers forwarded so far on each stream
+@item s1 s2
+number of samples forwarded so far on each stream
+@item t1 t2
+current timestamp of each stream
+@end table
+
+The default value is @code{t1-t2}, which means to always forward the stream
+that has a smaller timestamp.
+
+Example: stress-test @code{amerge} by randomly sending buffers on the wrong
+input, while avoiding too much of a desynchronization:
+@example
+amovie=file.ogg [a] ; amovie=file.mp3 [b] ;
+[a] [b] astreamsync=(2*random(1))-1+tanh(5*(t1-t2)) [a2] [b2] ;
+[a2] [b2] amerge
+@end example
+
+@section atempo
+
+Adjust audio tempo.
+
+The filter accepts exactly one parameter, the audio tempo. If not
+specified then the filter will assume nominal 1.0 tempo. Tempo must
+be in the [0.5, 2.0] range.
+
+For example, to slow down audio to 80% tempo:
+@example
+atempo=0.8
+@end example
+
+For example, to speed up audio to 125% tempo:
+@example
+atempo=1.25
+@end example
+
+@section earwax
+
+Make audio easier to listen to on headphones.
+
+This filter adds `cues' to 44.1kHz stereo (i.e. audio CD format) audio
+so that when listened to on headphones the stereo image is moved from
+inside your head (standard for headphones) to outside and in front of
+the listener (standard for speakers).
+
+Ported from SoX.
+
+@section pan
+
+Mix channels with specific gain levels. The filter accepts the output
+channel layout followed by a set of channels definitions.
+
+This filter is also designed to remap efficiently the channels of an audio
+stream.
+
+The filter accepts parameters of the form:
+"@var{l}:@var{outdef}:@var{outdef}:..."
+
+@table @option
+@item l
+output channel layout or number of channels
+
+@item outdef
+output channel specification, of the form:
+"@var{out_name}=[@var{gain}*]@var{in_name}[+[@var{gain}*]@var{in_name}...]"
+
+@item out_name
+output channel to define, either a channel name (FL, FR, etc.) or a channel
+number (c0, c1, etc.)
+
+@item gain
+multiplicative coefficient for the channel, 1 leaving the volume unchanged
+
+@item in_name
+input channel to use, see out_name for details; it is not possible to mix
+named and numbered input channels
+@end table
+
+If the `=' in a channel specification is replaced by `<', then the gains for
+that specification will be renormalized so that the total is 1, thus
+avoiding clipping noise.
+
+@subsection Mixing examples
+
+For example, if you want to down-mix from stereo to mono, but with a bigger
+factor for the left channel:
+@example
+pan=1:c0=0.9*c0+0.1*c1
+@end example
+
+A customized down-mix to stereo that works automatically for 3-, 4-, 5- and
+7-channels surround:
+@example
+pan=stereo: FL < FL + 0.5*FC + 0.6*BL + 0.6*SL : FR < FR + 0.5*FC + 0.6*BR + 0.6*SR
+@end example
+
+Note that @command{ffmpeg} integrates a default down-mix (and up-mix) system
+that should be preferred (see "-ac" option) unless you have very specific
+needs.
+
+@subsection Remapping examples
+
+The channel remapping will be effective if, and only if:
+
+@itemize
+@item gain coefficients are zeroes or ones,
+@item only one input per channel output,
+@end itemize
+
+If all these conditions are satisfied, the filter will notify the user ("Pure
+channel mapping detected"), and use an optimized and lossless method to do the
+remapping.
+
+For example, if you have a 5.1 source and want a stereo audio stream by
+dropping the extra channels:
+@example
+pan="stereo: c0=FL : c1=FR"
+@end example
+
+Given the same source, you can also switch front left and front right channels
+and keep the input channel layout:
+@example
+pan="5.1: c0=c1 : c1=c0 : c2=c2 : c3=c3 : c4=c4 : c5=c5"
+@end example
+
+If the input is a stereo audio stream, you can mute the front left channel (and
+still keep the stereo channel layout) with:
+@example
+pan="stereo:c1=c1"
+@end example
+
+Still with a stereo audio stream input, you can copy the right channel in both
+front left and right:
+@example
+pan="stereo: c0=FR : c1=FR"
+@end example
+
+@section silencedetect
+
+Detect silence in an audio stream.
+
+This filter logs a message when it detects that the input audio volume is less
+or equal to a noise tolerance value for a duration greater or equal to the
+minimum detected noise duration.
+
+The printed times and duration are expressed in seconds.
+
+@table @option
+@item duration, d
+Set silence duration until notification (default is 2 seconds).
+
+@item noise, n
+Set noise tolerance. Can be specified in dB (in case "dB" is appended to the
+specified value) or amplitude ratio. Default is -60dB, or 0.001.
+@end table
+
+Detect 5 seconds of silence with -50dB noise tolerance:
+@example
+silencedetect=n=-50dB:d=5
+@end example
+
+Complete example with @command{ffmpeg} to detect silence with 0.0001 noise
+tolerance in @file{silence.mp3}:
+@example
+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.
@@ -228,14 +781,14 @@
 
 For example, assuming a stereo input MP3 file
 @example
-avconv -i in.mp3 -filter_complex channelsplit out.mkv
+ffmpeg -i in.mp3 -filter_complex channelsplit out.mkv
 @end example
 will create an output Matroska file with two audio streams, one containing only
 the left channel and the other the right channel.
 
 To split a 5.1 WAV file into per-channel files
 @example
-avconv -i in.wav -filter_complex
+ffmpeg -i in.wav -filter_complex
 'channelsplit=channel_layout=5.1[FL][FR][FC][LFE][SL][SR]'
 -map '[FL]' front_left.wav -map '[FR]' front_right.wav -map '[FC]'
 front_center.wav -map '[LFE]' lfe.wav -map '[SL]' side_left.wav -map '[SR]'
@@ -265,14 +818,14 @@
 
 For example, assuming a 5.1+downmix input MOV file
 @example
-avconv -i in.mov -filter 'channelmap=map=DL-FL\,DR-FR' out.wav
+ffmpeg -i in.mov -filter 'channelmap=map=DL-FL\,DR-FR' out.wav
 @end example
 will create an output WAV file tagged as stereo from the downmix channels of
 the input.
 
 To fix a 5.1 WAV improperly encoded in AAC's native channel order
 @example
-avconv -i in.wav -filter 'channelmap=1\,2\,0\,5\,3\,4:channel_layout=5.1' out.wav
+ffmpeg -i in.wav -filter 'channelmap=1\,2\,0\,5\,3\,4:channel_layout=5.1' out.wav
 @end example
 
 @section join
@@ -302,21 +855,19 @@
 
 E.g. to join 3 inputs (with properly set channel layouts)
 @example
-avconv -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex join=inputs=3 OUTPUT
+ffmpeg -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex join=inputs=3 OUTPUT
 @end example
 
 To build a 5.1 output from 6 single-channel streams:
 @example
-avconv -i fl -i fr -i fc -i sl -i sr -i lfe -filter_complex
+ffmpeg -i fl -i fr -i fc -i sl -i sr -i lfe -filter_complex
 'join=inputs=6:channel_layout=5.1:map=0.0-FL\,1.0-FR\,2.0-FC\,3.0-SL\,4.0-SR\,5.0-LFE'
 out
 @end example
 
 @section resample
 Convert the audio sample format, sample rate and channel layout. This filter is
-not meant to be used directly, it is inserted automatically by libavfilter
-whenever conversion is needed. Use the @var{aformat} filter to force a specific
-conversion.
+not meant to be used directly.
 
 @c man end AUDIO FILTERS
 
@@ -325,31 +876,188 @@
 
 Below is a description of the currently available audio sources.
 
+@section abuffer
+
+Buffer audio frames, and make them available to the filter chain.
+
+This source is mainly intended for a programmatic use, in particular
+through the interface defined in @file{libavfilter/asrc_abuffer.h}.
+
+It accepts the following mandatory parameters:
+@var{sample_rate}:@var{sample_fmt}:@var{channel_layout}
+
+@table @option
+
+@item sample_rate
+The sample rate of the incoming audio buffers.
+
+@item sample_fmt
+The sample format of the incoming audio buffers.
+Either a sample format name or its corresponging integer representation from
+the enum AVSampleFormat in @file{libavutil/samplefmt.h}
+
+@item channel_layout
+The channel layout of the incoming audio buffers.
+Either a channel layout name from channel_layout_map in
+@file{libavutil/audioconvert.c} or its corresponding integer representation
+from the AV_CH_LAYOUT_* macros in @file{libavutil/audioconvert.h}
+
+@end table
+
+For example:
+@example
+abuffer=44100:s16p:stereo
+@end example
+
+will instruct the source to accept planar 16bit signed stereo at 44100Hz.
+Since the sample format with name "s16p" corresponds to the number
+6 and the "stereo" channel layout corresponds to the value 0x3, this is
+equivalent to:
+@example
+abuffer=44100:6:0x3
+@end example
+
+@section aevalsrc
+
+Generate an audio signal specified by an expression.
+
+This source accepts in input one or more expressions (one for each
+channel), which are evaluated and used to generate a corresponding
+audio signal.
+
+It accepts the syntax: @var{exprs}[::@var{options}].
+@var{exprs} is a list of expressions separated by ":", one for each
+separate channel. In case the @var{channel_layout} is not
+specified, the selected channel layout depends on the number of
+provided expressions.
+
+@var{options} is an optional sequence of @var{key}=@var{value} pairs,
+separated by ":".
+
+The description of the accepted options follows.
+
+@table @option
+
+@item channel_layout, c
+Set the channel layout. The number of channels in the specified layout
+must be equal to the number of specified expressions.
+
+@item duration, d
+Set the minimum duration of the sourced audio. See the function
+@code{av_parse_time()} for the accepted format.
+Note that the resulting duration may be greater than the specified
+duration, as the generated audio is always cut at the end of a
+complete frame.
+
+If not specified, or the expressed duration is negative, the audio is
+supposed to be generated forever.
+
+@item nb_samples, n
+Set the number of samples per channel per each output frame,
+default to 1024.
+
+@item sample_rate, s
+Specify the sample rate, default to 44100.
+@end table
+
+Each expression in @var{exprs} can contain the following constants:
+
+@table @option
+@item n
+number of the evaluated sample, starting from 0
+
+@item t
+time of the evaluated sample expressed in seconds, starting from 0
+
+@item s
+sample rate
+
+@end table
+
+@subsection Examples
+
+@itemize
+
+@item
+Generate silence:
+@example
+aevalsrc=0
+@end example
+
+@item
+
+Generate a sin signal with frequency of 440 Hz, set sample rate to
+8000 Hz:
+@example
+aevalsrc="sin(440*2*PI*t)::s=8000"
+@end example
+
+@item
+Generate a two channels signal, specify the channel layout (Front
+Center + Back Center) explicitly:
+@example
+aevalsrc="sin(420*2*PI*t):cos(430*2*PI*t)::c=FC|BC"
+@end example
+
+@item
+Generate white noise:
+@example
+aevalsrc="-2+random(0)"
+@end example
+
+@item
+Generate an amplitude modulated signal:
+@example
+aevalsrc="sin(10*2*PI*t)*sin(880*2*PI*t)"
+@end example
+
+@item
+Generate 2.5 Hz binaural beats on a 360 Hz carrier:
+@example
+aevalsrc="0.1*sin(2*PI*(360-2.5/2)*t) : 0.1*sin(2*PI*(360+2.5/2)*t)"
+@end example
+
+@end itemize
+
 @section anullsrc
 
-Null audio source, never return audio frames. It is mainly useful as a
-template and to be employed in analysis / debugging tools.
+Null audio source, return unprocessed audio frames. It is mainly useful
+as a template and to be employed in analysis / debugging tools, or as
+the source for filters which ignore the input data (for example the sox
+synth filter).
 
-It accepts as optional parameter a string of the form
-@var{sample_rate}:@var{channel_layout}.
+It accepts an optional sequence of @var{key}=@var{value} pairs,
+separated by ":".
 
-@var{sample_rate} specify the sample rate, and defaults to 44100.
+The description of the accepted options follows.
 
-@var{channel_layout} specify the channel layout, and can be either an
-integer or a string representing a channel layout. The default value
-of @var{channel_layout} is 3, which corresponds to CH_LAYOUT_STEREO.
+@table @option
+
+@item sample_rate, s
+Specify the sample rate, and defaults to 44100.
+
+@item channel_layout, cl
+
+Specify the channel layout, and can be either an integer or a string
+representing a channel layout. The default value of @var{channel_layout}
+is "stereo".
 
 Check the channel_layout_map definition in
 @file{libavcodec/audioconvert.c} for the mapping between strings and
 channel layout values.
 
+@item nb_samples, n
+Set the number of samples per requested frames.
+
+@end table
+
 Follow some examples:
 @example
-#  set the sample rate to 48000 Hz and the channel layout to CH_LAYOUT_MONO.
-anullsrc=48000:4
+#  set the sample rate to 48000 Hz and the channel layout to AV_CH_LAYOUT_MONO.
+anullsrc=r=48000:cl=4
 
 # same as
-anullsrc=48000:mono
+anullsrc=r=48000:cl=mono
 @end example
 
 @section abuffer
@@ -379,6 +1087,67 @@
 
 All the parameters need to be explicitly defined.
 
+@section flite
+
+Synthesize a voice utterance using the libflite library.
+
+To enable compilation of this filter you need to configure FFmpeg with
+@code{--enable-libflite}.
+
+Note that the flite library is not thread-safe.
+
+The source accepts parameters as a list of @var{key}=@var{value} pairs,
+separated by ":".
+
+The description of the accepted parameters follows.
+
+@table @option
+
+@item list_voices
+If set to 1, list the names of the available voices and exit
+immediately. Default value is 0.
+
+@item nb_samples, n
+Set the maximum number of samples per frame. Default value is 512.
+
+@item textfile
+Set the filename containing the text to speak.
+
+@item text
+Set the text to speak.
+
+@item voice, v
+Set the voice to use for the speech synthesis. Default value is
+@code{kal}. See also the @var{list_voices} option.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Read from file @file{speech.txt}, and synthetize the text using the
+standard flite voice:
+@example
+flite=textfile=speech.txt
+@end example
+
+@item
+Read the specified text selecting the @code{slt} voice:
+@example
+flite=text='So fare thee well, poor devil of a Sub-Sub, whose commentator I am':voice=slt
+@end example
+
+@item
+Make @file{ffplay} speech the specified text, using @code{flite} and
+the @code{lavfi} device:
+@example
+ffplay -f lavfi flite='No more be grieved for which that thou hast done.'
+@end example
+@end itemize
+
+For more information about libflite, check:
+@url{http://www.speech.cs.cmu.edu/flite/}
+
 @c man end AUDIO SOURCES
 
 @chapter Audio Sinks
@@ -386,6 +1155,17 @@
 
 Below is a description of the currently available audio sinks.
 
+@section abuffersink
+
+Buffer audio frames, and make them available to the end of filter chain.
+
+This sink is mainly intended for programmatic use, in particular
+through the interface defined in @file{libavfilter/buffersink.h}.
+
+It requires a pointer to an AVABufferSinkContext structure, which
+defines the incoming buffers' formats, to be passed as the opaque
+parameter to @code{avfilter_init_filter} for initialization.
+
 @section anullsink
 
 Null audio sink, do absolutely nothing with the input audio. It is
@@ -404,13 +1184,130 @@
 @chapter Video Filters
 @c man begin VIDEO FILTERS
 
-When you configure your Libav build, you can disable any of the
-existing filters using --disable-filters.
+When you configure your FFmpeg build, you can disable any of the
+existing filters using @code{--disable-filters}.
 The configure output will show the video filters included in your
 build.
 
 Below is a description of the currently available video filters.
 
+@section alphaextract
+
+Extract the alpha component from the input as a grayscale video. This
+is especially useful with the @var{alphamerge} filter.
+
+@section alphamerge
+
+Add or replace the alpha component of the primary input with the
+grayscale value of a second input. This is intended for use with
+@var{alphaextract} to allow the transmission or storage of frame
+sequences that have alpha in a format that doesn't support an alpha
+channel.
+
+For example, to reconstruct full frames from a normal YUV-encoded video
+and a separate video created with @var{alphaextract}, you might use:
+@example
+movie=in_alpha.mkv [alpha]; [in][alpha] alphamerge [out]
+@end example
+
+Since this filter is designed for reconstruction, it operates on frame
+sequences without considering timestamps, and terminates when either
+input reaches end of stream. This will cause problems if your encoding
+pipeline drops frames. If you're trying to apply an image as an
+overlay to a video stream, consider the @var{overlay} filter instead.
+
+@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 syntax: @var{ass_filename}[:@var{options}],
+where @var{ass_filename} is the filename of the ASS file to read, and
+@var{options} is an optional sequence of @var{key}=@var{value} pairs,
+separated by ":".
+
+A description of the accepted options follows.
+
+@table @option
+@item original_size
+Specifies 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
+
+For example, to render the file @file{sub.ass} on top of the input
+video, use the command:
+@example
+ass=sub.ass
+@end example
+
+@section bbox
+
+Compute the bounding box for the non-black pixels in the input frame
+luminance plane.
+
+This filter computes the bounding box containing all the pixels with a
+luminance value greater than the minimum allowed value.
+The parameters describing the bounding box are printed on the filter
+log.
+
+@section blackdetect
+
+Detect video intervals that are (almost) completely black. Can be
+useful to detect chapter transitions, commercials, or invalid
+recordings. Output lines contains the time for the start, end and
+duration of the detected black interval expressed in seconds.
+
+In order to display the output lines, you need to set the loglevel at
+least to the AV_LOG_INFO value.
+
+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 black_min_duration, d
+Set the minimum detected black duration expressed in seconds. It must
+be a non-negative floating point number.
+
+Default value is 2.0.
+
+@item picture_black_ratio_th, pic_th
+Set the threshold for considering a picture "black".
+Express the minimum value for the ratio:
+@example
+@var{nb_black_pixels} / @var{nb_pixels}
+@end example
+
+for which a picture is considered black.
+Default value is 0.98.
+
+@item pixel_black_th, pix_th
+Set the threshold for considering a pixel "black".
+
+The threshold expresses the maximum pixel luminance value for which a
+pixel is considered "black". The provided value is scaled according to
+the following equation:
+@example
+@var{absolute_threshold} = @var{luminance_minimum_value} + @var{pixel_black_th} * @var{luminance_range_size}
+@end example
+
+@var{luminance_range_size} and @var{luminance_minimum_value} depend on
+the input video format, the range is [0-255] for YUV full-range
+formats and [16-235] for YUV non full-range formats.
+
+Default value is 0.10.
+@end table
+
+The following example sets the maximum pixel threshold to the minimum
+value, and detects only black intervals of 2 or more seconds:
+@example
+blackdetect=d=2:pix_th=0.00
+@end example
+
 @section blackframe
 
 Detect frames that are (almost) completely black. Can be useful to
@@ -437,7 +1334,7 @@
 Apply boxblur algorithm to the input video.
 
 This filter accepts the parameters:
-@var{luma_power}:@var{luma_radius}:@var{chroma_radius}:@var{chroma_power}:@var{alpha_radius}:@var{alpha_power}
+@var{luma_radius}:@var{luma_power}:@var{chroma_radius}:@var{chroma_power}:@var{alpha_radius}:@var{alpha_power}
 
 Chroma and alpha parameters are optional, if not specified they default
 to the corresponding values set for @var{luma_radius} and
@@ -492,6 +1389,18 @@
 
 @end itemize
 
+@section colormatrix
+
+The colormatrix filter allows conversion between any of the following color
+space: BT.709 (@var{bt709}), BT.601 (@var{bt601}), SMPTE-240M (@var{smpte240m})
+and FCC (@var{fcc}).
+
+The syntax of the parameters is @var{source}:@var{destination}:
+
+@example
+colormatrix=bt601:smpte240m
+@end example
+
 @section copy
 
 Copy the input source unchanged to the output. Mainly useful for
@@ -499,15 +1408,16 @@
 
 @section crop
 
-Crop the input video to @var{out_w}:@var{out_h}:@var{x}:@var{y}.
+Crop the input video to @var{out_w}:@var{out_h}:@var{x}:@var{y}:@var{keep_aspect}
 
-The parameters are expressions containing the following constants:
+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.
+
+The @var{out_w}, @var{out_h}, @var{x}, @var{y} parameters are
+expressions containing the following constants:
 
 @table @option
-@item E, PI, PHI
-the corresponding mathematical approximated values for e
-(euler number), pi (greek PI), PHI (golden ratio)
-
 @item x, y
 the computed values for @var{x} and @var{y}. They are evaluated for
 each new frame.
@@ -524,6 +1434,19 @@
 @item ow, oh
 same as @var{out_w} and @var{out_h}
 
+@item a
+same as @var{iw} / @var{ih}
+
+@item sar
+input sample aspect ratio
+
+@item dar
+input display aspect ratio, it is the same as (@var{iw} / @var{ih}) * @var{sar}
+
+@item hsub, vsub
+horizontal and vertical chroma subsample values. For example for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
+
 @item n
 the number of input frame, starting from 0
 
@@ -630,6 +1553,43 @@
 playback.
 @end table
 
+@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.
+
+It accepts the following parameters:
+@var{max}:@var{hi}:@var{lo}:@var{frac}.
+
+@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
+negative). If the value is 0, the frame is dropped unregarding the
+number of previous sequentially dropped frames.
+
+Default value is 0.
+
+@item hi, lo, frac
+Set the dropping threshold values.
+
+Values for @var{hi} and @var{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}.
+
+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.
+@end table
+
 @section delogo
 
 Suppress a TV station logo by a simple interpolation of the surrounding
@@ -682,6 +1642,76 @@
 
 @end itemize
 
+@section deshake
+
+Attempt to fix small changes in horizontal and/or vertical shift. This
+filter helps remove camera shake from hand-holding a camera, bumping a
+tripod, moving on a vehicle, etc.
+
+The filter accepts parameters as a string of the form
+"@var{x}:@var{y}:@var{w}:@var{h}:@var{rx}:@var{ry}:@var{edge}:@var{blocksize}:@var{contrast}:@var{search}:@var{filename}"
+
+A description of the accepted parameters follows.
+
+@table @option
+
+@item x, y, w, h
+Specify a rectangular area where to limit the search for motion
+vectors.
+If desired the search for motion vectors can be limited to a
+rectangular area of the frame defined by its top left corner, width
+and height. These parameters have the same meaning as the drawbox
+filter which can be used to visualise the position of the bounding
+box.
+
+This is useful when simultaneous movement of subjects within the frame
+might be confused for camera motion by the motion vector search.
+
+If any or all of @var{x}, @var{y}, @var{w} and @var{h} are set to -1
+then the full frame is used. This allows later options to be set
+without specifying the bounding box for the motion vector search.
+
+Default - search the whole frame.
+
+@item rx, ry
+Specify the maximum extent of movement in x and y directions in the
+range 0-64 pixels. Default 16.
+
+@item edge
+Specify how to generate pixels to fill blanks at the edge of the
+frame. An integer from 0 to 3 as follows:
+@table @option
+@item 0
+Fill zeroes at blank locations
+@item 1
+Original image at blank locations
+@item 2
+Extruded edge value at blank locations
+@item 3
+Mirrored edge at blank locations
+@end table
+
+The default setting is mirror edge at blank locations.
+
+@item blocksize
+Specify the blocksize to use for motion search. Range 4-128 pixels,
+default 8.
+
+@item contrast
+Specify the contrast threshold for blocks. Only blocks with more than
+the specified contrast (difference between darkest and lightest
+pixels) will be considered. Range 1-255, default 125.
+
+@item search
+Specify the search strategy 0 = exhaustive search, 1 = less exhaustive
+search. Default - exhaustive search.
+
+@item filename
+If set then a detailed log of the motion search is written to the
+specified file.
+
+@end table
+
 @section drawbox
 
 Draw a colored box on the input image.
@@ -719,7 +1749,7 @@
 Draw text string or text from specified file on top of video using the
 libfreetype library.
 
-To enable compilation of this filter you need to configure Libav with
+To enable compilation of this filter you need to configure FFmpeg with
 @code{--enable-libfreetype}.
 
 The filter also recognizes strftime() sequences in the provided text
@@ -732,66 +1762,10 @@
 
 @table @option
 
-@item fontfile
-The font file to be used for drawing text. Path must be included.
-This parameter is mandatory.
-
-@item text
-The text string to be drawn. The text must be a sequence of UTF-8
-encoded characters.
-This parameter is mandatory if no file is specified with the parameter
-@var{textfile}.
-
-@item textfile
-A text file containing text to be drawn. The text must be a sequence
-of UTF-8 encoded characters.
-
-This parameter is mandatory if no text string is specified with the
-parameter @var{text}.
-
-If both text and textfile are specified, an error is thrown.
-
-@item x, y
-The offsets where text will be drawn within the video frame.
-Relative to the top/left border of the output image.
-They accept expressions similar to the @ref{overlay} filter:
-@table @option
-
-@item x, y
-the computed values for @var{x} and @var{y}. They are evaluated for
-each new frame.
-
-@item main_w, main_h
-main input width and height
-
-@item W, H
-same as @var{main_w} and @var{main_h}
-
-@item text_w, text_h
-rendered text width and height
-
-@item w, h
-same as @var{text_w} and @var{text_h}
-
-@item n
-the number of frames processed, starting from 0
-
-@item t
-timestamp expressed in seconds, NAN if the input timestamp is unknown
-
-@end table
-
-The default value of @var{x} and @var{y} is 0.
-
-@item fontsize
-The font size to be used for drawing text.
-The default value of @var{fontsize} is 16.
-
-@item fontcolor
-The color to be used for drawing fonts.
-Either a string (e.g. "red") or in 0xRRGGBB[AA] format
-(e.g. "0xff000033"), possibly followed by an alpha specifier.
-The default value of @var{fontcolor} is "black".
+@item box
+Used to draw a box around text using background color.
+Value should be either 1 (enable) or 0 (disable).
+The default value of @var{box} is 0.
 
 @item boxcolor
 The color to be used for drawing box around text.
@@ -799,21 +1773,32 @@
 (e.g. "0xff00ff"), possibly followed by an alpha specifier.
 The default value of @var{boxcolor} is "white".
 
-@item box
-Used to draw a box around text using background color.
-Value should be either 1 (enable) or 0 (disable).
-The default value of @var{box} is 0.
+@item draw
+Set an expression which specifies if the text should be drawn. If the
+expression evaluates to 0, the text is not drawn. This is useful for
+specifying that the text should be drawn only when specific conditions
+are met.
 
-@item shadowx, shadowy
-The x and y offsets for the text shadow position with respect to the
-position of the text. They can be either positive or negative
-values. Default value for both is "0".
+Default value is "1".
 
-@item shadowcolor
-The color to be used for drawing a shadow behind the drawn text.  It
-can be a color name (e.g. "yellow") or a string in the 0xRRGGBB[AA]
-form (e.g. "0xff00ff"), possibly followed by an alpha specifier.
-The default value of @var{shadowcolor} is "black".
+See below for the list of accepted constants and functions.
+
+@item fix_bounds
+If true, check and fix text coords to avoid clipping.
+
+@item fontcolor
+The color to be used for drawing fonts.
+Either a string (e.g. "red") or in 0xRRGGBB[AA] format
+(e.g. "0xff000033"), possibly followed by an alpha specifier.
+The default value of @var{fontcolor} is "black".
+
+@item fontfile
+The font file to be used for drawing text. Path must be included.
+This parameter is mandatory.
+
+@item fontsize
+The font size to be used for drawing text.
+The default value of @var{fontsize} is 16.
 
 @item ft_load_flags
 Flags to be used for loading the fonts.
@@ -844,45 +1829,230 @@
 For more information consult the documentation for the FT_LOAD_*
 libfreetype flags.
 
+@item shadowcolor
+The color to be used for drawing a shadow behind the drawn text.  It
+can be a color name (e.g. "yellow") or a string in the 0xRRGGBB[AA]
+form (e.g. "0xff00ff"), possibly followed by an alpha specifier.
+The default value of @var{shadowcolor} is "black".
+
+@item shadowx, shadowy
+The x and y offsets for the text shadow position with respect to the
+position of the text. They can be either positive or negative
+values. Default value for both is "0".
+
 @item tabsize
 The size in number of spaces to use for rendering the tab.
 Default value is 4.
 
-@item fix_bounds
-If true, check and fix text coords to avoid clipping.
+@item timecode
+Set the initial timecode representation in "hh:mm:ss[:;.]ff"
+format. It can be used with or without text parameter. @var{timecode_rate}
+option must be specified.
+
+@item timecode_rate, rate, r
+Set the timecode frame rate (timecode only).
+
+@item text
+The text string to be drawn. The text must be a sequence of UTF-8
+encoded characters.
+This parameter is mandatory if no file is specified with the parameter
+@var{textfile}.
+
+@item textfile
+A text file containing text to be drawn. The text must be a sequence
+of UTF-8 encoded characters.
+
+This parameter is mandatory if no text string is specified with the
+parameter @var{text}.
+
+If both @var{text} and @var{textfile} are specified, an error is thrown.
+
+@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
+output image.
+
+The default value of @var{x} and @var{y} is "0".
+
+See below for the list of accepted constants and functions.
 @end table
 
-For example the command:
+The parameters for @var{x} and @var{y} are expressions containing the
+following constants and functions:
+
+@table @option
+@item dar
+input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar}
+
+@item hsub, vsub
+horizontal and vertical chroma subsample values. For example for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
+
+@item line_h, lh
+the height of each text line
+
+@item main_h, h, H
+the input height
+
+@item main_w, w, W
+the input width
+
+@item max_glyph_a, ascent
+the maximum distance from the baseline to the highest/upper grid
+coordinate used to place a glyph outline point, for all the rendered
+glyphs.
+It is a positive value, due to the grid's orientation with the Y axis
+upwards.
+
+@item max_glyph_d, descent
+the maximum distance from the baseline to the lowest grid coordinate
+used to place a glyph outline point, for all the rendered glyphs.
+This is a negative value, due to the grid's orientation, with the Y axis
+upwards.
+
+@item max_glyph_h
+maximum glyph height, that is the maximum height for all the glyphs
+contained in the rendered text, it is equivalent to @var{ascent} -
+@var{descent}.
+
+@item max_glyph_w
+maximum glyph width, that is the maximum width for all the glyphs
+contained in the rendered text
+
+@item n
+the number of input frame, starting from 0
+
+@item rand(min, max)
+return a random number included between @var{min} and @var{max}
+
+@item sar
+input sample aspect ratio
+
+@item t
+timestamp expressed in seconds, NAN if the input timestamp is unknown
+
+@item text_h, th
+the height of the rendered text
+
+@item text_w, tw
+the width of the rendered text
+
+@item x, y
+the x and y offset coordinates where the text is drawn.
+
+These parameters allow the @var{x} and @var{y} expressions to refer
+each other, so you can for example specify @code{y=x/dar}.
+@end table
+
+If libavfilter was built with @code{--enable-fontconfig}, then
+@option{fontfile} can be a fontconfig pattern or omitted.
+
+Some examples follow.
+
+@itemize
+
+@item
+Draw "Test Text" with font FreeSerif, using the default values for the
+optional parameters.
+
 @example
 drawtext="fontfile=/usr/share/fonts/truetype/freefont/FreeSerif.ttf: text='Test Text'"
 @end example
 
-will draw "Test Text" with font FreeSerif, using the default values
-for the optional parameters.
+@item
+Draw 'Test Text' with font FreeSerif of size 24 at position x=100
+and y=50 (counting from the top-left corner of the screen), text is
+yellow with a red box around it. Both the text and the box have an
+opacity of 20%.
 
-The command:
 @example
 drawtext="fontfile=/usr/share/fonts/truetype/freefont/FreeSerif.ttf: text='Test Text':\
           x=100: y=50: fontsize=24: fontcolor=yellow@@0.2: box=1: boxcolor=red@@0.2"
 @end example
 
-will draw 'Test Text' with font FreeSerif of size 24 at position x=100
-and y=50 (counting from the top-left corner of the screen), text is
-yellow with a red box around it. Both the text and the box have an
-opacity of 20%.
-
 Note that the double quotes are not necessary if spaces are not used
 within the parameter list.
 
+@item
+Show the text at the center of the video frame:
+@example
+drawtext="fontsize=30:fontfile=FreeSerif.ttf:text='hello world':x=(w-text_w)/2:y=(h-text_h-line_h)/2"
+@end example
+
+@item
+Show a text line sliding from right to left in the last row of the video
+frame. The file @file{LONG_LINE} is assumed to contain a single line
+with no newlines.
+@example
+drawtext="fontsize=15:fontfile=FreeSerif.ttf:text=LONG_LINE:y=h-line_h:x=-50*t"
+@end example
+
+@item
+Show the content of file @file{CREDITS} off the bottom of the frame and scroll up.
+@example
+drawtext="fontsize=20:fontfile=FreeSerif.ttf:textfile=CREDITS:y=h-20*t"
+@end example
+
+@item
+Draw a single green letter "g", at the center of the input video.
+The glyph baseline is placed at half screen height.
+@example
+drawtext="fontsize=60:fontfile=FreeSerif.ttf:fontcolor=green:text=g:x=(w-max_glyph_w)/2:y=h/2-ascent"
+@end example
+
+@item
+Show text for 1 second every 3 seconds:
+@example
+drawtext="fontfile=FreeSerif.ttf:fontcolor=white:x=100:y=x/dar:draw=lt(mod(t\\,3)\\,1):text='blink'"
+@end example
+
+@item
+Use fontconfig to set the font. Note that the colons need to be escaped.
+@example
+drawtext='fontfile=Linux Libertine O-40\\:style=Semibold:text=FFmpeg'
+@end example
+
+@end itemize
+
 For more information about libfreetype, check:
 @url{http://www.freetype.org/}.
 
+For more information about fontconfig, check:
+@url{http://freedesktop.org/software/fontconfig/fontconfig-user.html}.
+
+@section edgedetect
+
+Detect and draw edges. The filter uses the Canny Edge Detection algorithm.
+
+This filter accepts the following optional named parameters:
+
+@table @option
+@item low, high
+Set low and high threshold values used by the Canny thresholding
+algorithm.
+
+The high threshold selects the "strong" edge pixels, which are then
+connected through 8-connectivity with the "weak" edge pixels selected
+by the low threshold.
+
+@var{low} and @var{high} threshold values must be choosen in the range
+[0,1], and @var{low} should be lesser or equal to @var{high}.
+
+Default value for @var{low} is @code{20/255}, and default value for @var{high}
+is @code{50/255}.
+@end table
+
+Example:
+@example
+edgedetect=low=0.1:high=0.4
+@end example
+
 @section fade
 
 Apply fade-in/out effect to input video.
 
 It accepts the parameters:
-@var{type}:@var{start_frame}:@var{nb_frames}
+@var{type}:@var{start_frame}:@var{nb_frames}[:@var{options}]
 
 @var{type} specifies if the effect type, can be either "in" for
 fade-in, or "out" for a fade-out effect.
@@ -895,6 +2065,25 @@
 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.
+
+@table @option
+
+@item type, t
+See @var{type}.
+
+@item start_frame, s
+See @var{start_frame}.
+
+@item nb_frames, n
+See @var{nb_frames}.
+
+@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.
 @example
 # fade in first 30 frames of video
@@ -908,6 +2097,9 @@
 
 # make first 5 frames black, then fade in from frame 5-24
 fade=in:5:20
+
+# fade in alpha over first 25 frames of video
+fade=in:0:25:alpha=1
 @end example
 
 @section fieldorder
@@ -940,7 +2132,7 @@
 
 For example:
 @example
-./avconv -i in.vob -vf "fieldorder=bff" out.dv
+ffmpeg -i in.vob -vf "fieldorder=bff" out.dv
 @end example
 
 @section fifo
@@ -983,13 +2175,20 @@
 
 @end table
 
+@section framestep
+
+Select one frame every N.
+
+This filter accepts in input a string representing a positive
+integer. Default argument is @code{1}.
+
 @anchor{frei0r}
 @section frei0r
 
 Apply a frei0r effect to the input video.
 
 To enable compilation of this filter you need to install the frei0r
-header and configure Libav with --enable-frei0r.
+header and configure FFmpeg with @code{--enable-frei0r}.
 
 The filter supports the syntax:
 @example
@@ -1017,27 +2216,37 @@
 effect parameter is not specified the default value is set.
 
 Some examples follow:
-@example
-# apply the distort0r effect, set the first two double parameters
-frei0r=distort0r:0.5:0.01
 
-# apply the colordistance effect, takes a color as first parameter
+@itemize
+@item
+Apply the distort0r effect, set the first two double parameters:
+@example
+frei0r=distort0r:0.5:0.01
+@end example
+
+@item
+Apply the colordistance effect, takes a color as first parameter:
+@example
 frei0r=colordistance:0.2/0.3/0.4
 frei0r=colordistance:violet
 frei0r=colordistance:0x112233
-
-# apply the perspective effect, specify the top left and top right
-# image positions
-frei0r=perspective:0.2/0.2:0.8/0.2
 @end example
 
+@item
+Apply the perspective effect, specify the top left and top right image
+positions:
+@example
+frei0r=perspective:0.2/0.2:0.8/0.2
+@end example
+@end itemize
+
 For more information see:
-@url{http://piksel.org/frei0r}
+@url{http://frei0r.dyne.org}
 
 @section gradfun
 
 Fix the banding artifacts that are sometimes introduced into nearly flat
-regions by truncation to 8bit colordepth.
+regions by truncation to 8bit color depth.
 Interpolate the gradients that should go where the bands are, and
 dither them.
 
@@ -1071,9 +2280,9 @@
 
 Flip the input video horizontally.
 
-For example to horizontally flip the input video with @command{avconv}:
+For example to horizontally flip the input video with @command{ffmpeg}:
 @example
-avconv -i in.avi -vf "hflip" out.avi
+ffmpeg -i in.avi -vf "hflip" out.avi
 @end example
 
 @section hqdn3d
@@ -1103,6 +2312,125 @@
 @var{luma_tmp}*@var{chroma_spatial}/@var{luma_spatial}
 @end table
 
+@section hue
+
+Modify the hue and/or the saturation of the input.
+
+This filter accepts the following optional named options:
+
+@table @option
+@item h
+Specify the hue angle as a number of degrees. It accepts a float
+number or an expression, and defaults to 0.0.
+
+@item H
+Specify the hue angle as a number of degrees. It accepts a float
+number or an expression, and defaults to 0.0.
+
+@item s
+Specify the saturation in the [-10,10] range. It accepts a float number and
+defaults to 1.0.
+@end table
+
+The @var{h}, @var{H} and @var{s} parameters are expressions containing the
+following constants:
+
+@table @option
+@item n
+frame count of the input frame starting from 0
+
+@item pts
+presentation timestamp of the input frame expressed in time base units
+
+@item r
+frame rate of the input video, NAN if the input frame rate is unknown
+
+@item t
+timestamp expressed in seconds, NAN if the input timestamp is unknown
+
+@item tb
+time base of the input video
+@end table
+
+The options can also be set using the syntax: @var{hue}:@var{saturation}
+
+In this case @var{hue} is expressed in degrees.
+
+Some examples follow:
+@itemize
+@item
+Set the hue to 90 degrees and the saturation to 1.0:
+@example
+hue=h=90:s=1
+@end example
+
+@item
+Same command but expressing the hue in radians:
+@example
+hue=H=PI/2:s=1
+@end example
+
+@item
+Same command without named options, hue must be expressed in degrees:
+@example
+hue=90:1
+@end example
+
+@item
+Note that "h:s" syntax does not support expressions for the values of
+h and s, so the following example will issue an error:
+@example
+hue=PI/2:1
+@end example
+
+@item
+Rotate hue and make the saturation swing between 0
+and 2 over a period of 1 second:
+@example
+hue="H=2*PI*t: s=sin(2*PI*t)+1"
+@end example
+
+@item
+Apply a 3 seconds saturation fade-in effect starting at 0:
+@example
+hue="s=min(t/3\,1)"
+@end example
+
+The general fade-in expression can be written as:
+@example
+hue="s=min(0\, max((t-START)/DURATION\, 1))"
+@end example
+
+@item
+Apply a 3 seconds saturation fade-out effect starting at 5 seconds:
+@example
+hue="s=max(0\, min(1\, (8-t)/3))"
+@end example
+
+The general fade-out expression can be written as:
+@example
+hue="s=max(0\, min(1\, (START+DURATION-t)/DURATION))"
+@end example
+
+@end itemize
+
+@subsection Commands
+
+This filter supports the following command:
+@table @option
+@item reinit
+Modify the hue and/or the saturation of the input video.
+The command accepts the same named options and syntax than when calling the
+filter from the command-line.
+
+If a parameter is omitted, it is kept at its current value.
+@end table
+
+@section idet
+
+Interlaceing detect filter. This filter tries to detect if the input is
+interlaced or progressive. Top or bottom field first.
+
 @section lut, lutrgb, lutyuv
 
 Compute a look-up table for binding each pixel component input value
@@ -1148,10 +2476,6 @@
 The expressions can contain the following constants and functions:
 
 @table @option
-@item E, PI, PHI
-the corresponding mathematical approximated values for e
-(euler number), pi (greek PI), PHI (golden ratio)
-
 @item w, h
 the input width and height
 
@@ -1197,7 +2521,7 @@
 lutyuv="y=negval:u=negval:v=negval"
 
 # negate luminance
-lutyuv=negval
+lutyuv=y=negval
 
 # remove chroma components, turns the video into a graytone image
 lutyuv="u=128:v=128"
@@ -1215,6 +2539,90 @@
 lutyuv=y=gammaval(0.5)
 @end example
 
+@section mp
+
+Apply an MPlayer filter to the input video.
+
+This filter provides a wrapper around most of the filters of
+MPlayer/MEncoder.
+
+This wrapper is considered experimental. Some of the wrapped filters
+may not work properly and we may drop support for them, as they will
+be implemented natively into FFmpeg. Thus you should avoid
+depending on them when writing portable scripts.
+
+The filters accepts the parameters:
+@var{filter_name}[:=]@var{filter_params}
+
+@var{filter_name} is the name of a supported MPlayer filter,
+@var{filter_params} is a string containing the parameters accepted by
+the named filter.
+
+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 field
+@item fil
+@item fixpts
+@item fspp
+@item geq
+@item harddup
+@item hqdn3d
+@item il
+@item ilpack
+@item ivtc
+@item kerndeint
+@item mcdeint
+@item noise
+@item ow
+@item palette
+@item perspective
+@item phase
+@item pp7
+@item pullup
+@item qp
+@item rectangle
+@item sab
+@item softpulldown
+@item softskip
+@item spp
+@item telecine
+@item tile
+@item tinterlace
+@item unsharp
+@item uspp
+@item yuvcsp
+@item yvu9
+@end table
+
+The parameter syntax and behavior for the listed filters are the same
+of the corresponding MPlayer filters. For detailed instructions check
+the "VIDEO FILTERS" section in the MPlayer manual.
+
+Some examples follow:
+@itemize
+@item
+Adjust gamma, brightness, contrast:
+@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/}.
+
 @section negate
 
 Negate input video.
@@ -1222,6 +2630,8 @@
 This filter accepts an integer in input, if non-zero it negates the
 alpha component (if available). The default value in input is 0.
 
+@section noformat
+
 Force libavfilter not to use any of the specified pixel formats for the
 input to the next filter.
 
@@ -1247,7 +2657,7 @@
 Apply video transform using libopencv.
 
 To enable this filter install libopencv library and headers and
-configure Libav with --enable-libopencv.
+configure FFmpeg with @code{--enable-libopencv}.
 
 The filter takes the parameters: @var{filter_name}@{:=@}@var{filter_params}.
 
@@ -1347,10 +2757,10 @@
 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}.
+It accepts the parameters: @var{x}:@var{y}[:@var{options}].
 
 @var{x} is the x coordinate of the overlayed video on the main video,
-@var{y} is the y coordinate. The parameters are expressions containing
+@var{y} is the y coordinate. @var{x} and @var{y} are expressions containing
 the following parameters:
 
 @table @option
@@ -1367,6 +2777,17 @@
 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 ":".
+
+The description of the accepted options follows.
+
+@table @option
+@item rgb
+If set to 1, force the filter to accept inputs in the RGB
+color space. Default value is 0.
+@end table
+
 Be aware that frames are taken from each input video in timestamp
 order, hence, if their initial timestamps differ, it is a a good idea
 to pass the two inputs through a @var{setpts=PTS-STARTPTS} filter to
@@ -1380,16 +2801,23 @@
 overlay=main_w-overlay_w-10:main_h-overlay_h-10
 
 # insert a transparent PNG logo in the bottom left corner of the input
-avconv -i input -i logo -filter_complex 'overlay=10:main_h-overlay_h-10' output
+ffmpeg -i input -i logo -filter_complex 'overlay=10:main_h-overlay_h-10' output
 
 # insert 2 different transparent PNG logos (second logo on bottom
 # right corner):
-avconv -i input -i logo1 -i logo2 -filter_complex
+ffmpeg -i input -i logo1 -i logo2 -filter_complex
 'overlay=10:H-h-10,overlay=W-w-10:H-h-10' output
 
 # add a transparent color layer on top of the main video,
 # WxH specifies the size of the main input to the overlay filter
 color=red@.3:WxH [over]; [in][over] overlay [out]
+
+# play an original video and a filtered version (here with the deshake filter)
+# side by side
+ffplay input.avi -vf 'split[a][b]; [a]pad=iw*2:ih[src]; [b]deshake[filt]; [src][filt]overlay=w'
+
+# the previous example is the same as:
+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
@@ -1407,10 +2835,6 @@
 expressions containing the following constants:
 
 @table @option
-@item E, PI, PHI
-the corresponding mathematical approximated values for e
-(euler number), pi (greek PI), phi (golden ratio)
-
 @item in_w, in_h
 the input video width and height
 
@@ -1429,7 +2853,13 @@
 expressions, or NAN if not yet specified
 
 @item a
-input display aspect ratio, same as @var{iw} / @var{ih}
+same as @var{iw} / @var{ih}
+
+@item sar
+input sample aspect ratio
+
+@item dar
+input display aspect ratio, it is the same as (@var{iw} / @var{ih}) * @var{sar}
 
 @item hsub, vsub
 horizontal and vertical chroma subsample values. For example for the
@@ -1469,30 +2899,59 @@
 
 @end table
 
-Some examples follow:
+@section Examples
 
+@itemize
+@item
+Add paddings with color "violet" to the input video. Output video
+size is 640x480, the top-left corner of the input video is placed at
+column 0, row 40:
 @example
-# Add paddings with color "violet" to the input video. Output video
-# size is 640x480, the top-left corner of the input video is placed at
-# column 0, row 40.
 pad=640:480:0:40:violet
+@end example
 
-# pad the input to get an output with dimensions increased bt 3/2,
-# and put the input video at the center of the padded area
+@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:
+@example
 pad="3/2*iw:3/2*ih:(ow-iw)/2:(oh-ih)/2"
+@end example
 
-# pad the input to get a squared output with size equal to the maximum
-# value between the input width and height, and put the input video at
-# the center of the padded area
+@item
+Pad the input to get a squared output with size equal to the maximum
+value between the input width and height, and put the input video at
+the center of the padded area:
+@example
 pad="max(iw\,ih):ow:(ow-iw)/2:(oh-ih)/2"
+@end example
 
-# pad the input to get a final w/h ratio of 16:9
+@item
+Pad the input to get a final w/h ratio of 16:9:
+@example
 pad="ih*16/9:ih:(ow-iw)/2:(oh-ih)/2"
+@end example
 
-# double output size and put the input video in the bottom-right
-# corner of the output padded area
+@item
+In case of anamorphic video, in order to set the output display aspect
+correctly, it is necessary to use @var{sar} in the expression,
+according to the relation:
+@example
+(ih * X / ih) * sar = output_dar
+X = output_dar / sar
+@end example
+
+Thus the previous example needs to be modified to:
+@example
+pad="ih*16/9/sar:ih:(ow-iw)/2:(oh-ih)/2"
+@end example
+
+@item
+Double output size and put the input video in the bottom-right
+corner of the output padded area:
+@example
 pad="2*iw:2*ih:ow-iw:oh-ih"
 @end example
+@end itemize
 
 @section pixdesctest
 
@@ -1506,18 +2965,43 @@
 
 can be used to test the monowhite pixel format descriptor definition.
 
+@section removelogo
+
+Suppress a TV station logo, using an image file to determine which
+pixels comprise the logo. It works by filling in the pixels that
+comprise the logo with neighboring pixels.
+
+This filter requires one argument which specifies the filter bitmap
+file, which can be any image format supported by libavformat. The
+width and height of the image file must match those of the video
+stream being processed.
+
+Pixels in the provided bitmap image with a value of zero are not
+considered part of the logo, non-zero pixels are considered part of
+the logo. If you use white (255) for the logo and black (0) for the
+rest, you will be safe. For making the filter bitmap, it is
+recommended to take a screen capture of a black frame with the logo
+visible, and then using a threshold filter followed by the erode
+filter once or twice.
+
+If needed, little splotches can be fixed manually. Remember that if
+logo pixels are not covered, the filter quality will be much
+reduced. Marking too many pixels as part of the logo does not hurt as
+much, but it will increase the amount of blurring needed to cover over
+the image and will destroy more information than necessary, and extra
+pixels will slow things down on a large logo.
+
 @section scale
 
-Scale the input video to @var{width}:@var{height} and/or convert the image format.
+Scale the input video to @var{width}:@var{height}[:@var{interl}=@{1|-1@}] and/or convert the image format.
+
+The scale filter forces the output display aspect ratio to be the same
+of the input, by changing the output sample aspect ratio.
 
 The parameters @var{width} and @var{height} are expressions containing
 the following constants:
 
 @table @option
-@item E, PI, PHI
-the corresponding mathematical approximated values for e
-(euler number), pi (greek PI), phi (golden ratio)
-
 @item in_w, in_h
 the input width and height
 
@@ -1530,12 +3014,15 @@
 @item ow, oh
 same as @var{out_w} and @var{out_h}
 
-@item dar, a
-input display aspect ratio, same as @var{iw} / @var{ih}
+@item a
+same as @var{iw} / @var{ih}
 
 @item sar
 input sample aspect ratio
 
+@item dar
+input display aspect ratio, it is the same as (@var{iw} / @var{ih}) * @var{sar}
+
 @item hsub, vsub
 horizontal and vertical chroma subsample values. For example for the
 pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
@@ -1554,6 +3041,19 @@
 
 The default value of @var{width} and @var{height} is 0.
 
+Valid values for the optional parameter @var{interl} are:
+
+@table @option
+@item 1
+force interlaced aware scaling
+
+@item -1
+select interlaced aware scaling depending on whether the source frames
+are flagged as interlaced or not
+@end table
+
+Unless @var{interl} is set to one of the above options, interlaced scaling will not be used.
+
 Some examples follow:
 @example
 # scale the input video to a size of 200x100.
@@ -1564,6 +3064,9 @@
 # the above is the same as
 scale=2*in_w:2*in_h
 
+# scale the input to 2x with forced interlaced scaling
+scale=2*iw:2*ih:interl=1
+
 # scale the input to half size
 scale=iw/2:ih/2
 
@@ -1594,15 +3097,6 @@
 The expression can contain the following constants:
 
 @table @option
-@item PI
-Greek PI
-
-@item PHI
-golden ratio
-
-@item E
-Euler number
-
 @item n
 the sequential number of the filtered frame, starting from 0
 
@@ -1668,6 +3162,12 @@
 @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".
@@ -1700,151 +3200,88 @@
 select='isnan(prev_selected_t)+gte(t-prev_selected_t\,10)'
 @end example
 
-@anchor{setdar}
-@section setdar
+Complete example to create a mosaic of the first scenes:
 
-Set the Display Aspect Ratio for the filter output video.
+@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
+output video.
 
 This is done by changing the specified Sample (aka Pixel) Aspect
 Ratio, according to the following equation:
-@math{DAR = HORIZONTAL_RESOLUTION / VERTICAL_RESOLUTION * SAR}
+@example
+@var{DAR} = @var{HORIZONTAL_RESOLUTION} / @var{VERTICAL_RESOLUTION} * @var{SAR}
+@end example
 
-Keep in mind that this filter does not modify the pixel dimensions of
-the video frame. Also the display aspect ratio set by this filter may
-be changed by later filters in the filterchain, e.g. in case of
-scaling or if another "setdar" or a "setsar" filter is applied.
+Keep in mind that the @code{setdar} filter does not modify the pixel
+dimensions of the video frame. Also the display aspect ratio set by
+this filter may be changed by later filters in the filterchain,
+e.g. in case of scaling or if another "setdar" or a "setsar" filter is
+applied.
 
-The filter accepts a parameter string which represents the wanted
-display aspect ratio.
-The parameter can be a floating point number string, or an expression
-of the form @var{num}:@var{den}, where @var{num} and @var{den} are the
-numerator and denominator of the aspect ratio.
-If the parameter is not specified, it is assumed the value "0:1".
+The @code{setsar} filter sets the Sample (aka Pixel) Aspect Ratio for
+the filter output video.
+
+Note that as a consequence of the application of this filter, the
+output display aspect ratio will change according to the equation
+above.
+
+Keep in mind that the sample aspect ratio set by the @code{setsar}
+filter may be changed by later filters in the filterchain, e.g. if
+another "setsar" or a "setdar" filter is applied.
+
+The @code{setdar} and @code{setsar} filters accept a parameter string
+which represents the wanted aspect ratio.  The parameter can
+be a floating point number string, an expression, or a string of the form
+@var{num}:@var{den}, where @var{num} and @var{den} are the numerator
+and denominator of the aspect ratio. If the parameter is not
+specified, it is assumed the value "0:1".
 
 For example to change the display aspect ratio to 16:9, specify:
 @example
 setdar=16:9
-# the above is equivalent to
+@end example
+
+The example above is equivalent to:
+@example
 setdar=1.77777
 @end example
 
-See also the @ref{setsar} filter documentation.
-
-@section setpts
-
-Change the PTS (presentation timestamp) of the input video frames.
-
-Accept in input an expression evaluated through the eval API, which
-can contain the following constants:
-
-@table @option
-@item PTS
-the presentation timestamp in input
-
-@item PI
-Greek PI
-
-@item PHI
-golden ratio
-
-@item E
-Euler number
-
-@item N
-the count of the input frame, starting from 0.
-
-@item STARTPTS
-the PTS of the first video frame
-
-@item INTERLACED
-tell if the current frame is interlaced
-
-@item POS
-original position in the file of the frame, or undefined if undefined
-for the current frame
-
-@item PREV_INPTS
-previous input PTS
-
-@item PREV_OUTPTS
-previous output PTS
-
-@end table
-
-Some examples follow:
-
-@example
-# start counting PTS from zero
-setpts=PTS-STARTPTS
-
-# fast motion
-setpts=0.5*PTS
-
-# slow motion
-setpts=2.0*PTS
-
-# fixed rate 25 fps
-setpts=N/(25*TB)
-
-# fixed rate 25 fps with some jitter
-setpts='1/(25*TB) * (N + 0.05 * sin(N*2*PI/25))'
-@end example
-
-@anchor{setsar}
-@section setsar
-
-Set the Sample (aka Pixel) Aspect Ratio for the filter output video.
-
-Note that as a consequence of the application of this filter, the
-output display aspect ratio will change according to the following
-equation:
-@math{DAR = HORIZONTAL_RESOLUTION / VERTICAL_RESOLUTION * SAR}
-
-Keep in mind that the sample aspect ratio set by this filter may be
-changed by later filters in the filterchain, e.g. if another "setsar"
-or a "setdar" filter is applied.
-
-The filter accepts a parameter string which represents the wanted
-sample aspect ratio.
-The parameter can be a floating point number string, or an expression
-of the form @var{num}:@var{den}, where @var{num} and @var{den} are the
-numerator and denominator of the aspect ratio.
-If the parameter is not specified, it is assumed the value "0:1".
-
-For example to change the sample aspect ratio to 10:11, specify:
+To change the sample aspect ratio to 10:11, specify:
 @example
 setsar=10:11
 @end example
 
-@section settb
+@section setfield
 
-Set the timebase to use for the output frames timestamps.
-It is mainly useful for testing timebase configuration.
+Force field for the output video frame.
 
-It accepts in input an arithmetic expression representing a rational.
-The expression can contain the constants "PI", "E", "PHI", "AVTB" (the
-default timebase), and "intb" (the input timebase).
+The @code{setfield} filter marks the interlace type field for the
+output frames. It does not change the input frame, but only sets the
+corresponding property, which affects how the frame is treated by
+following filters (e.g. @code{fieldorder} or @code{yadif}).
 
-The default value for the input is "intb".
+It accepts a string parameter, which can assume the following values:
+@table @samp
+@item auto
+Keep the same field property.
 
-Follow some examples.
+@item bff
+Mark the frame as bottom-field-first.
 
-@example
-# set the timebase to 1/25
-settb=1/25
+@item tff
+Mark the frame as top-field-first.
 
-# set the timebase to 1/10
-settb=0.1
-
-#set the timebase to 1001/1000
-settb=1+0.001
-
-#set the timebase to 2*intb
-settb=2*intb
-
-#set the default timebase value
-settb=AVTB
-@end example
+@item prog
+Mark the frame as progressive.
+@end table
 
 @section showinfo
 
@@ -1898,11 +3335,11 @@
 @file{libavutil/avutil.h}.
 
 @item checksum
-Adler-32 checksum of all the planes of the input frame
+Adler-32 checksum (printed in hexadecimal) of all the planes of the input frame
 
 @item plane_checksum
-Adler-32 checksum of each plane of the input frame, expressed in the form
-"[@var{c0} @var{c1} @var{c2} @var{c3}]"
+Adler-32 checksum (printed in hexadecimal) of each plane of the input frame,
+expressed in the form "[@var{c0} @var{c1} @var{c2} @var{c3}]"
 @end table
 
 @section slicify
@@ -1911,7 +3348,7 @@
 slices.
 
 @example
-./avconv -i in.avi -vf "slicify=32" out.avi
+ffmpeg -i in.avi -vf "slicify=32" out.avi
 @end example
 
 The filter accepts the slice height as parameter. If the parameter is
@@ -1920,6 +3357,35 @@
 Adding this in the beginning of filter chains should make filtering
 faster due to better use of the memory cache.
 
+@section smartblur
+
+Blur the input video without impacting the outlines.
+
+The filter accepts the following parameters:
+@var{luma_radius}:@var{luma_strength}:@var{luma_threshold}[:@var{chroma_radius}:@var{chroma_strength}:@var{chroma_threshold}]
+
+Parameters prefixed by @var{luma} indicate that they work on the
+luminance of the pixels whereas parameters prefixed by @var{chroma}
+refer to the chrominance of the pixels.
+
+If the chroma parameters are not set, the luma parameters are used for
+either the luminance and the chrominance of the pixels.
+
+@var{luma_radius} or @var{chroma_radius} must be a float number in the
+range [0.1,5.0] that specifies the variance of the gaussian filter
+used to blur the image (slower if larger).
+
+@var{luma_strength} or @var{chroma_strength} must be a float number in
+the range [-1.0,1.0] that configures the blurring. A value included in
+[0.0,1.0] will blur the image whereas a value included in [-1.0,0.0]
+will sharpen the image.
+
+@var{luma_threshold} or @var{chroma_threshold} must be an integer in
+the range [-30,30] that is used as a coefficient to determine whether
+a pixel should be blurred or not. A value of 0 will filter all the
+image, a value included in [0,30] will filter flat areas and a value
+included in [-30,0] will filter edges.
+
 @section split
 
 Split input video into several identical outputs.
@@ -1929,19 +3395,126 @@
 
 For example
 @example
-avconv -i INPUT -filter_complex split=5 OUTPUT
+ffmpeg -i INPUT -filter_complex split=5 OUTPUT
 @end example
 will create 5 copies of the input video.
 
+For example:
+@example
+[in] split [splitout1][splitout2];
+[splitout1] crop=100:100:0:0    [cropout];
+[splitout2] pad=200:200:100:100 [padout];
+@end example
+
+will create two separate outputs from the same input, one cropped and
+one padded.
+
+@section super2xsai
+
+Scale the input by 2x and smooth using the Super2xSaI (Scale and
+Interpolate) pixel art scaling algorithm.
+
+Useful for enlarging pixel art images without reducing sharpness.
+
+@section swapuv
+Swap U & V plane.
+
+@section thumbnail
+Select the most representative frame in a given sequence of consecutive frames.
+
+It accepts as argument the frames batch size to analyze (default @var{N}=100);
+in a set of @var{N} frames, the filter will pick one of them, and then handle
+the next batch of @var{N} frames until the end.
+
+Since the filter keeps track of the whole frames sequence, a bigger @var{N}
+value will result in a higher memory usage, so a high value is not recommended.
+
+The following example extract one picture each 50 frames:
+@example
+thumbnail=50
+@end example
+
+Complete example of a thumbnail creation with @command{ffmpeg}:
+@example
+ffmpeg -i in.avi -vf thumbnail,scale=300:200 -frames:v 1 out.png
+@end example
+
+@section tile
+
+Tile several successive frames together.
+
+It accepts as argument the tile size (i.e. the number of lines and columns)
+in the form "@var{w}x@var{h}".
+
+For example, produce 8×8 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
+@end example
+The @option{-vsync 0} is necessary to prevent @command{ffmpeg} from
+duplicating each output frame to accomodate the originally detected frame
+rate.
+
+@section tinterlace
+
+Perform various types of temporal field interlacing.
+
+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:
+
+@table @samp
+@item merge, 0
+Move odd frames into the upper field, even into the lower field,
+generating a double height frame at half framerate.
+
+@item drop_odd, 1
+Only output even frames, odd frames are dropped, generating a frame with
+unchanged height at half framerate.
+
+@item drop_even, 2
+Only output odd frames, even frames are dropped, generating a frame with
+unchanged height at half framerate.
+
+@item pad, 3
+Expand each frame to full height, but pad alternate lines with black,
+generating a frame with double height at the same input framerate.
+
+@item interleave_top, 4
+Interleave the upper field from odd frames with the lower field from
+even frames, generating a frame with unchanged height at half framerate.
+
+@item interleave_bottom, 5
+Interleave the lower field from odd frames with the upper field from
+even frames, generating a frame with unchanged height at half framerate.
+
+@item interlacex2, 6
+Double frame rate with unchanged height. Frames are inserted each
+containing the second temporal field from the previous input frame and
+the first temporal field from the next input frame. This mode relies on
+the top_field_first flag. Useful for interlaced video displays with no
+field synchronisation.
+@end table
+
+Numeric values are deprecated but are accepted for backward
+compatibility reasons.
+
+Default mode is @code{merge}.
+
 @section transpose
 
 Transpose rows with columns in the input video and optionally flip it.
 
-It accepts a parameter representing an integer, which can assume the
-values:
+This filter accepts the following named parameters:
+
+@table @option
+@item dir
+Specify the transposition direction. Can assume the following values:
 
 @table @samp
-@item 0
+@item 0, 4
 Rotate by 90 degrees counterclockwise and vertically flip (default), that is:
 @example
 L.R     L.l
@@ -1949,7 +3522,7 @@
 l.r     R.r
 @end example
 
-@item 1
+@item 1, 5
 Rotate by 90 degrees clockwise, that is:
 @example
 L.R     l.L
@@ -1957,7 +3530,7 @@
 l.r     r.R
 @end example
 
-@item 2
+@item 2, 6
 Rotate by 90 degrees counterclockwise, that is:
 @example
 L.R     R.r
@@ -1965,7 +3538,7 @@
 l.r     L.l
 @end example
 
-@item 3
+@item 3, 7
 Rotate by 90 degrees clockwise and vertically flip, that is:
 @example
 L.R     r.R
@@ -1974,6 +3547,25 @@
 @end example
 @end table
 
+For values between 4-7, the transposition is only done if the input
+video geometry is portrait and not landscape. These values are
+deprecated, the @code{passthrough} option should be used instead.
+
+@item passthrough
+Do not apply the transposition if the input geometry matches the one
+specified by the specified value. It accepts the following values:
+@table @samp
+@item none
+Always apply transposition.
+@item portrait
+Preserve portrait geometry (when @var{height} >= @var{width}).
+@item landscape
+Preserve landscape geometry (when @var{width} >= @var{height}).
+@end table
+
+Default value is @code{none}.
+@end table
+
 @section unsharp
 
 Sharpen or blur the input video.
@@ -2007,7 +3599,7 @@
 Set the chroma matrix vertical size. It can be an integer between 3
 and 13, default value is 5.
 
-@item luma_amount
+@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.
 
@@ -2020,8 +3612,8 @@
 # Strong blur of both luma and chroma parameters
 unsharp=7:7:-2:7:7:-2
 
-# Use the default values with @command{avconv}
-./avconv -i in.avi -vf "unsharp" out.mp4
+# Use the default values with @command{ffmpeg}
+ffmpeg -i in.avi -vf "unsharp" out.mp4
 @end example
 
 @section vflip
@@ -2029,7 +3621,7 @@
 Flip the input video vertically.
 
 @example
-./avconv -i in.avi -vf "vflip" out.avi
+ffmpeg -i in.avi -vf "vflip" out.avi
 @end example
 
 @section yadif
@@ -2097,35 +3689,37 @@
 This source is mainly intended for a programmatic use, in particular
 through the interface defined in @file{libavfilter/vsrc_buffer.h}.
 
-It accepts the following parameters:
-@var{width}:@var{height}:@var{pix_fmt_string}:@var{timebase_num}:@var{timebase_den}:@var{sample_aspect_ratio_num}:@var{sample_aspect_ratio.den}
-
-All the parameters need to be explicitly defined.
-
-Follows the list of the accepted parameters.
+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 width, height
-Specify the width and height of the buffered video frames.
+@item video_size
+Specify the size (width and height) of the buffered video frames.
 
-@item pix_fmt_string
+@item pix_fmt
 A string representing the pixel format of the buffered video frames.
 It may be a number corresponding to a pixel format, or a pixel format
 name.
 
-@item timebase_num, timebase_den
-Specify numerator and denomitor of the timebase assumed by the
-timestamps of the buffered frames.
+@item time_base
+Specify the timebase assumed by the timestamps of the buffered frames.
 
-@item sample_aspect_ratio.num, sample_aspect_ratio.den
-Specify numerator and denominator of the sample aspect ratio assumed
-by the video frames.
+@item time_base
+Specify the frame rate expected for the video stream.
+
+@item pixel_aspect
+Specify the sample aspect ratio assumed by the video frames.
+
+@item sws_param
+Specify the optional parameters to be used for the scale filter which
+is automatically inserted when an input change is detected in the
+input size or format.
 @end table
 
 For example:
 @example
-buffer=320:240:yuv410p:1:24:1:1
+buffer=size=320x240:pix_fmt=yuv410p:time_base=1/24:pixel_aspect=1/1
 @end example
 
 will instruct the source to accept video frames with size 320x240 and
@@ -2135,56 +3729,1000 @@
 (check the enum AVPixelFormat definition in @file{libavutil/pixfmt.h}),
 this example corresponds to:
 @example
-buffer=320:240:6:1:24
+buffer=size=320x240:pixfmt=6:time_base=1/24:pixel_aspect=1/1
 @end example
 
-@section color
+Alternatively, the options can be specified as a flat string, but this
+syntax is deprecated:
 
-Provide an uniformly colored input.
+@var{width}:@var{height}:@var{pix_fmt}:@var{time_base.num}:@var{time_base.den}:@var{pixel_aspect.num}:@var{pixel_aspect.den}[:@var{sws_param}]
 
-It accepts the following parameters:
-@var{color}:@var{frame_size}:@var{frame_rate}
+@section cellauto
 
-Follows the description of the accepted parameters.
+Create a pattern generated by an elementary cellular automaton.
+
+The initial state of the cellular automaton can be defined through the
+@option{filename}, and @option{pattern} options. If such options are
+not specified an initial state is created randomly.
+
+At each new frame a new row in the video is filled with the result of
+the cellular automaton next generation. The behavior when the whole
+frame is filled is defined by the @option{scroll} option.
+
+This source 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 filename, f
+Read the initial cellular automaton state, i.e. the starting row, from
+the specified file.
+In the file, each non-whitespace character is considered an alive
+cell, a newline will terminate the row, and further characters in the
+file will be ignored.
+
+@item pattern, p
+Read the initial cellular automaton state, i.e. the starting row, from
+the specified string.
+
+Each non-whitespace character in the string is considered an alive
+cell, a newline will terminate the row, and further characters in the
+string will be ignored.
+
+@item rate, r
+Set the video rate, that is the number of frames generated per second.
+Default is 25.
+
+@item random_fill_ratio, ratio
+Set the random fill ratio for the initial cellular automaton row. It
+is a floating point number value ranging from 0 to 1, defaults to
+1/PHI.
+
+This option is ignored when a file or a pattern is specified.
+
+@item random_seed, seed
+Set the seed for filling randomly the initial row, must be an integer
+included between 0 and UINT32_MAX. If not specified, or if explicitly
+set to -1, the filter will try to use a good random seed on a best
+effort basis.
+
+@item rule
+Set the cellular automaton rule, it is a number ranging from 0 to 255.
+Default value is 110.
+
+@item size, s
+Set the size of the output video.
+
+If @option{filename} or @option{pattern} is specified, the size is set
+by default to the width of the specified initial state row, and the
+height is set to @var{width} * PHI.
+
+If @option{size} is set, it must contain the width of the specified
+pattern string, and the specified pattern will be centered in the
+larger row.
+
+If a filename or a pattern string is not specified, the size value
+defaults to "320x518" (used for a randomly generated initial state).
+
+@item scroll
+If set to 1, scroll the output upward when all the rows in the output
+have been already filled. If set to 0, the new generated row will be
+written over the top row just after the bottom row is filled.
+Defaults to 1.
+
+@item start_full, full
+If set to 1, completely fill the output with generated rows before
+outputting the first frame.
+This is the default behavior, for disabling set the value to 0.
+
+@item stitch
+If set to 1, stitch the left and right row edges together.
+This is the default behavior, for disabling set the value to 0.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Read the initial state from @file{pattern}, and specify an output of
+size 200x400.
+@example
+cellauto=f=pattern:s=200x400
+@end example
+
+@item
+Generate a random initial row with a width of 200 cells, with a fill
+ratio of 2/3:
+@example
+cellauto=ratio=2/3:s=200x200
+@end example
+
+@item
+Create a pattern generated by rule 18 starting by a single alive cell
+centered on an initial row with width 100:
+@example
+cellauto=p=@@:s=100x400:full=0:rule=18
+@end example
+
+@item
+Specify a more elaborated initial pattern:
+@example
+cellauto=p='@@@@ @@ @@@@':s=100x400:full=0:rule=18
+@end example
+
+@end itemize
+
+@section mandelbrot
+
+Generate a Mandelbrot set fractal, and progressively zoom towards the
+point specified with @var{start_x} and @var{start_y}.
+
+This source 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 color
-Specify the color of the source. It can be the name of a color (case
-insensitive match) or a 0xRRGGBB[AA] sequence, possibly followed by an
-alpha specifier. The default value is "black".
+@item end_pts
+Set the terminal pts value. Default value is 400.
 
-@item frame_size
-Specify the size of the sourced video, it may be a string of the form
-@var{width}x@var{height}, or the name of a size abbreviation. The
-default value is "320x240".
+@item end_scale
+Set the terminal scale value.
+Must be a floating point value. Default value is 0.3.
 
-@item frame_rate
+@item inner
+Set the inner coloring mode, that is the algorithm used to draw the
+Mandelbrot fractal internal region.
+
+It shall assume one of the following values:
+@table @option
+@item black
+Set black mode.
+@item convergence
+Show time until convergence.
+@item mincol
+Set color based on point closest to the origin of the iterations.
+@item period
+Set period mode.
+@end table
+
+Default value is @var{mincol}.
+
+@item bailout
+Set the bailout value. Default value is 10.0.
+
+@item maxiter
+Set the maximum of iterations performed by the rendering
+algorithm. Default value is 7189.
+
+@item outer
+Set outer coloring mode.
+It shall assume one of following values:
+@table @option
+@item iteration_count
+Set iteration cound mode.
+@item normalized_iteration_count
+set normalized iteration count mode.
+@end table
+Default value is @var{normalized_iteration_count}.
+
+@item rate, r
+Set frame rate, expressed as number of frames per second. Default
+value is "25".
+
+@item size, s
+Set frame size. Default value is "640x480".
+
+@item start_scale
+Set the initial scale value. Default value is 3.0.
+
+@item start_x
+Set the initial x position. Must be a floating point value between
+-100 and 100. Default value is -0.743643887037158704752191506114774.
+
+@item start_y
+Set the initial y position. Must be a floating point value between
+-100 and 100. Default value is -0.131825904205311970493132056385139.
+@end table
+
+@section mptestsrc
+
+Generate various test patterns, as generated by the MPlayer test filter.
+
+The size of the generated video is fixed, and is 256x256.
+This source is useful in particular for testing encoding features.
+
+This source accepts an optional sequence of @var{key}=@var{value} pairs,
+separated by ":". The description of the accepted options follows.
+
+@table @option
+
+@item rate, r
 Specify the frame rate of the sourced video, as the number of frames
 generated per second. It has to be a string in the format
 @var{frame_rate_num}/@var{frame_rate_den}, an integer number, a float
 number or a valid video frame rate abbreviation. The default value is
 "25".
 
+@item duration, d
+Set the video duration of the sourced video. The accepted syntax is:
+@example
+[-]HH:MM:SS[.m...]
+[-]S+[.m...]
+@end example
+See also the function @code{av_parse_time()}.
+
+If not specified, or the expressed duration is negative, the video is
+supposed to be generated forever.
+
+@item test, t
+
+Set the number or the name of the test to perform. Supported tests are:
+@table @option
+@item dc_luma
+@item dc_chroma
+@item freq_luma
+@item freq_chroma
+@item amp_luma
+@item amp_chroma
+@item cbp
+@item mv
+@item ring1
+@item ring2
+@item all
 @end table
 
-For example the following graph description will generate a red source
-with an opacity of 0.2, with size "qcif" and a frame rate of 10
-frames per second, which will be overlayed over the source connected
-to the pad with identifier "in".
+Default value is "all", which will cycle through the list of all tests.
+@end table
 
+For example the following:
 @example
-"color=red@@0.2:qcif:10 [color]; [in][color] overlay [out]"
+testsrc=t=dc_luma
 @end example
 
+will generate a "dc_luma" test pattern.
+
+@section frei0r_src
+
+Provide a frei0r source.
+
+To enable compilation of this filter you need to install the frei0r
+header and configure FFmpeg with @code{--enable-frei0r}.
+
+The source supports the syntax:
+@example
+@var{size}:@var{rate}:@var{src_name}[@{=|:@}@var{param1}:@var{param2}:...:@var{paramN}]
+@end example
+
+@var{size} is the size of the video to generate, may be a string of the
+form @var{width}x@var{height} or a frame size abbreviation.
+@var{rate} is the rate of the video to generate, may be a string of
+the form @var{num}/@var{den} or a frame rate abbreviation.
+@var{src_name} is the name to the frei0r source to load. For more
+information regarding frei0r and how to set the parameters read the
+section @ref{frei0r} in the description of the video filters.
+
+For example, to generate a frei0r partik0l source with size 200x200
+and frame rate 10 which is overlayed on the overlay filter main input:
+@example
+frei0r_src=200x200:10:partik0l=1234 [overlay]; [in][overlay] overlay
+@end example
+
+@section life
+
+Generate a life pattern.
+
+This source is based on a generalization of John Conway's life game.
+
+The sourced input represents a life grid, each pixel represents a cell
+which can be in one of two possible states, alive or dead. Every cell
+interacts with its eight neighbours, which are the cells that are
+horizontally, vertically, or diagonally adjacent.
+
+At each interaction the grid evolves according to the adopted rule,
+which specifies the number of neighbor alive cells which will make a
+cell stay alive or born. The @option{rule} option allows to specify
+the rule to adopt.
+
+This source 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 filename, f
+Set the file from which to read the initial grid state. In the file,
+each non-whitespace character is considered an alive cell, and newline
+is used to delimit the end of each row.
+
+If this option is not specified, the initial grid is generated
+randomly.
+
+@item rate, r
+Set the video rate, that is the number of frames generated per second.
+Default is 25.
+
+@item random_fill_ratio, ratio
+Set the random fill ratio for the initial random grid. It is a
+floating point number value ranging from 0 to 1, defaults to 1/PHI.
+It is ignored when a file is specified.
+
+@item random_seed, seed
+Set the seed for filling the initial random grid, must be an integer
+included between 0 and UINT32_MAX. If not specified, or if explicitly
+set to -1, the filter will try to use a good random seed on a best
+effort basis.
+
+@item rule
+Set the life rule.
+
+A rule can be specified with a code of the kind "S@var{NS}/B@var{NB}",
+where @var{NS} and @var{NB} are sequences of numbers in the range 0-8,
+@var{NS} specifies the number of alive neighbor cells which make a
+live cell stay alive, and @var{NB} the number of alive neighbor cells
+which make a dead cell to become alive (i.e. to "born").
+"s" and "b" can be used in place of "S" and "B", respectively.
+
+Alternatively a rule can be specified by an 18-bits integer. The 9
+high order bits are used to encode the next cell state if it is alive
+for each number of neighbor alive cells, the low order bits specify
+the rule for "borning" new cells. Higher order bits encode for an
+higher number of neighbor cells.
+For example the number 6153 = @code{(12<<9)+9} specifies a stay alive
+rule of 12 and a born rule of 9, which corresponds to "S23/B03".
+
+Default value is "S23/B3", which is the original Conway's game of life
+rule, and will keep a cell alive if it has 2 or 3 neighbor alive
+cells, and will born a new cell if there are three alive cells around
+a dead cell.
+
+@item size, s
+Set the size of the output video.
+
+If @option{filename} is specified, the size is set by default to the
+same size of the input file. If @option{size} is set, it must contain
+the size specified in the input file, and the initial grid defined in
+that file is centered in the larger resulting area.
+
+If a filename is not specified, the size value defaults to "320x240"
+(used for a randomly generated initial grid).
+
+@item stitch
+If set to 1, stitch the left and right grid edges together, and the
+top and bottom edges also. Defaults to 1.
+
+@item mold
+Set cell mold speed. If set, a dead cell will go from @option{death_color} to
+@option{mold_color} with a step of @option{mold}. @option{mold} can have a
+value from 0 to 255.
+
+@item life_color
+Set the color of living (or new born) cells.
+
+@item death_color
+Set the color of dead cells. If @option{mold} is set, this is the first color
+used to represent a dead cell.
+
+@item mold_color
+Set mold color, for definitely dead and moldy cells.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Read a grid from @file{pattern}, and center it on a grid of size
+300x300 pixels:
+@example
+life=f=pattern:s=300x300
+@end example
+
+@item
+Generate a random grid of size 200x200, with a fill ratio of 2/3:
+@example
+life=ratio=2/3:s=200x200
+@end example
+
+@item
+Specify a custom rule for evolving a randomly generated grid:
+@example
+life=rule=S14/B34
+@end example
+
+@item
+Full example with slow death effect (mold) using @command{ffplay}:
+@example
+ffplay -f lavfi life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_color=#00ff00,scale=1200:800:flags=16
+@end example
+@end itemize
+
+@section color, nullsrc, rgbtestsrc, smptebars, testsrc
+
+The @code{color} source provides an uniformly colored input.
+
+The @code{nullsrc} source returns unprocessed video frames. It is
+mainly useful to be employed in analysis / debugging tools, or as the
+source for filters which ignore the input data.
+
+The @code{rgbtestsrc} source generates an RGB test pattern useful for
+detecting RGB vs BGR issues. You should see a red, green and blue
+stripe from top to bottom.
+
+The @code{smptebars} source generates a color bars pattern, based on
+the SMPTE Engineering Guideline EG 1-1990.
+
+The @code{testsrc} source generates a test video pattern, showing a
+color pattern, a scrolling gradient and a timestamp. This is mainly
+intended for testing purposes.
+
+These sources accept an optional sequence of @var{key}=@var{value} pairs,
+separated by ":". The description of the accepted options follows.
+
+@table @option
+
+@item color, c
+Specify the color of the source, only used in the @code{color}
+source. It can be the name of a color (case insensitive match) or a
+0xRRGGBB[AA] sequence, possibly followed by an alpha specifier. The
+default value is "black".
+
+@item size, s
+Specify the size of the sourced video, it may be a string of the form
+@var{width}x@var{height}, or the name of a size abbreviation. The
+default value is "320x240".
+
+@item rate, r
+Specify the frame rate of the sourced video, as the number of frames
+generated per second. It has to be a string in the format
+@var{frame_rate_num}/@var{frame_rate_den}, an integer number, a float
+number or a valid video frame rate abbreviation. The default value is
+"25".
+
+@item sar
+Set the sample aspect ratio of the sourced video.
+
+@item duration, d
+Set the video duration of the sourced video. The accepted syntax is:
+@example
+[-]HH[:MM[:SS[.m...]]]
+[-]S+[.m...]
+@end example
+See also the function @code{av_parse_time()}.
+
+If not specified, or the expressed duration is negative, the video is
+supposed to be generated forever.
+
+@item decimals, n
+Set the number of decimals to show in the timestamp, only used in the
+@code{testsrc} source.
+
+The displayed timestamp value will correspond to the original
+timestamp value multiplied by the power of 10 of the specified
+value. Default value is 0.
+@end table
+
+For example the following:
+@example
+testsrc=duration=5.3:size=qcif:rate=10
+@end example
+
+will generate a video with a duration of 5.3 seconds, with size
+176x144 and a frame rate of 10 frames per second.
+
+The following graph description will generate a red source
+with an opacity of 0.2, with size "qcif" and a frame rate of 10
+frames per second.
+@example
+color=c=red@@0.2:s=qcif:r=10
+@end example
+
+If the input content is to be ignored, @code{nullsrc} can be used. The
+following command generates noise in the luminance plane by employing
+the @code{mp=geq} filter:
+@example
+nullsrc=s=256x256, mp=geq=random(1)*255:128:128
+@end example
+
+@c man end VIDEO SOURCES
+
+@chapter Video Sinks
+@c man begin VIDEO SINKS
+
+Below is a description of the currently available video sinks.
+
+@section buffersink
+
+Buffer video frames, and make them available to the end of the filter
+graph.
+
+This sink is mainly intended for a programmatic use, in particular
+through the interface defined in @file{libavfilter/buffersink.h}.
+
+It does not require a string parameter in input, but you need to
+specify a pointer to a list of supported pixel formats terminated by
+-1 in the opaque parameter provided to @code{avfilter_init_filter}
+when initializing this sink.
+
+@section nullsink
+
+Null video sink, do absolutely nothing with the input video. It is
+mainly useful as a template and to be employed in analysis / debugging
+tools.
+
+@c man end VIDEO SINKS
+
+@chapter Multimedia Filters
+@c man begin MULTIMEDIA FILTERS
+
+Below is a description of the currently available multimedia filters.
+
+@section asendcmd, sendcmd
+
+Send commands to filters in the filtergraph.
+
+These filters read commands to be sent to other filters in the
+filtergraph.
+
+@code{asendcmd} must be inserted between two audio filters,
+@code{sendcmd} must be inserted between two video filters, but apart
+from that they act the same way.
+
+The specification of commands can be provided in the filter arguments
+with the @var{commands} option, or in a file specified by the
+@var{filename} option.
+
+These filters accept the following options:
+@table @option
+@item commands, c
+Set the commands to be read and sent to the other filters.
+@item filename, f
+Set the filename of the commands to be read and sent to the other
+filters.
+@end table
+
+@subsection Commands syntax
+
+A commands description consists of a sequence of interval
+specifications, comprising a list of commands to be executed when a
+particular event related to that interval occurs. The occurring event
+is typically the current frame time entering or leaving a given time
+interval.
+
+An interval is specified by the following syntax:
+@example
+@var{START}[-@var{END}] @var{COMMANDS};
+@end example
+
+The time interval is specified by the @var{START} and @var{END} times.
+@var{END} is optional and defaults to the maximum time.
+
+The current frame time is considered within the specified interval if
+it is included in the interval [@var{START}, @var{END}), that is when
+the time is greater or equal to @var{START} and is lesser than
+@var{END}.
+
+@var{COMMANDS} consists of a sequence of one or more command
+specifications, separated by ",", relating to that interval.  The
+syntax of a command specification is given by:
+@example
+[@var{FLAGS}] @var{TARGET} @var{COMMAND} @var{ARG}
+@end example
+
+@var{FLAGS} is optional and specifies the type of events relating to
+the time interval which enable sending the specified command, and must
+be a non-null sequence of identifier flags separated by "+" or "|" and
+enclosed between "[" and "]".
+
+The following flags are recognized:
+@table @option
+@item enter
+The command is sent when the current frame timestamp enters the
+specified interval. In other words, the command is sent when the
+previous frame timestamp was not in the given interval, and the
+current is.
+
+@item leave
+The command is sent when the current frame timestamp leaves the
+specified interval. In other words, the command is sent when the
+previous frame timestamp was in the given interval, and the
+current is not.
+@end table
+
+If @var{FLAGS} is not specified, a default value of @code{[enter]} is
+assumed.
+
+@var{TARGET} specifies the target of the command, usually the name of
+the filter class or a specific filter instance name.
+
+@var{COMMAND} specifies the name of the command for the target filter.
+
+@var{ARG} is optional and specifies the optional list of argument for
+the given @var{COMMAND}.
+
+Between one interval specification and another, whitespaces, or
+sequences of characters starting with @code{#} until the end of line,
+are ignored and can be used to annotate comments.
+
+A simplified BNF description of the commands specification syntax
+follows:
+@example
+@var{COMMAND_FLAG}  ::= "enter" | "leave"
+@var{COMMAND_FLAGS} ::= @var{COMMAND_FLAG} [(+|"|")@var{COMMAND_FLAG}]
+@var{COMMAND}       ::= ["[" @var{COMMAND_FLAGS} "]"] @var{TARGET} @var{COMMAND} [@var{ARG}]
+@var{COMMANDS}      ::= @var{COMMAND} [,@var{COMMANDS}]
+@var{INTERVAL}      ::= @var{START}[-@var{END}] @var{COMMANDS}
+@var{INTERVALS}     ::= @var{INTERVAL}[;@var{INTERVALS}]
+@end example
+
+@subsection Examples
+
+@itemize
+@item
+Specify audio tempo change at second 4:
+@example
+asendcmd=c='4.0 atempo tempo 1.5',atempo
+@end example
+
+@item
+Specify a list of drawtext and hue commands in a file.
+@example
+# show text in the interval 5-10
+5.0-10.0 [enter] drawtext reinit 'fontfile=FreeSerif.ttf:text=hello world',
+         [leave] drawtext reinit 'fontfile=FreeSerif.ttf:text=';
+
+# desaturate the image in the interval 15-20
+15.0-20.0 [enter] hue reinit s=0,
+          [enter] drawtext reinit 'fontfile=FreeSerif.ttf:text=nocolor',
+          [leave] hue reinit s=1,
+          [leave] drawtext reinit 'fontfile=FreeSerif.ttf:text=color';
+
+# apply an exponential saturation fade-out effect, starting from time 25
+25 [enter] hue s=exp(t-25)
+@end example
+
+A filtergraph allowing to read and process the above command list
+stored in a file @file{test.cmd}, can be specified with:
+@example
+sendcmd=f=test.cmd,drawtext=fontfile=FreeSerif.ttf:text='',hue
+@end example
+@end itemize
+
+@section asetpts, setpts
+
+Change the PTS (presentation timestamp) of the input frames.
+
+@code{asetpts} works on audio frames, @code{setpts} on video frames.
+
+Accept in input an expression evaluated through the eval API, which
+can contain the following constants:
+
+@table @option
+@item FRAME_RATE
+frame rate, only defined for constant frame-rate video
+
+@item PTS
+the presentation timestamp in input
+
+@item N
+the count of the input frame, starting from 0.
+
+@item NB_CONSUMED_SAMPLES
+the number of consumed samples, not including the current frame (only
+audio)
+
+@item NB_SAMPLES
+the number of samples in the current frame (only audio)
+
+@item SAMPLE_RATE
+audio sample rate
+
+@item STARTPTS
+the PTS of the first frame
+
+@item STARTT
+the time in seconds of the first frame
+
+@item INTERLACED
+tell if the current frame is interlaced
+
+@item T
+the time in seconds of the current frame
+
+@item TB
+the time base
+
+@item POS
+original position in the file of the frame, or undefined if undefined
+for the current frame
+
+@item PREV_INPTS
+previous input PTS
+
+@item PREV_INT
+previous input time in seconds
+
+@item PREV_OUTPTS
+previous output PTS
+
+@item PREV_OUTT
+previous output time in seconds
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Start counting PTS from zero
+@example
+setpts=PTS-STARTPTS
+@end example
+
+@item
+Apply fast motion effect:
+@example
+setpts=0.5*PTS
+@end example
+
+@item
+Apply slow motion effect:
+@example
+setpts=2.0*PTS
+@end example
+
+@item
+Set fixed rate of 25 frames per second:
+@example
+setpts=N/(25*TB)
+@end example
+
+@item
+Set fixed rate 25 fps with some jitter:
+@example
+setpts='1/(25*TB) * (N + 0.05 * sin(N*2*PI/25))'
+@end example
+
+@item
+Apply an offset of 10 seconds to the input PTS:
+@example
+setpts=PTS+10/TB
+@end example
+@end itemize
+
+@section ebur128
+
+EBU R128 scanner filter. This filter takes an audio stream as input and outputs
+it unchanged. By default, it logs a message at a frequency of 10Hz with the
+Momentary loudness (identified by @code{M}), Short-term loudness (@code{S}),
+Integrated loudness (@code{I}) and Loudness Range (@code{LRA}).
+
+The filter also has a video output (see the @var{video} option) with a real
+time graph to observe the loudness evolution. The graphic contains the logged
+message mentioned above, so it is not printed anymore when this option is set,
+unless the verbose logging is set. The main graphing area contains the
+short-term loudness (3 seconds of analysis), and the gauge on the right is for
+the momentary loudness (400 milliseconds).
+
+More information about the Loudness Recommendation EBU R128 on
+@url{http://tech.ebu.ch/loudness}.
+
+The filter accepts the following named parameters:
+
+@table @option
+
+@item video
+Activate the video output. The audio stream is passed unchanged whether this
+option is set or no. The video stream will be the first output stream if
+activated. Default is @code{0}.
+
+@item size
+Set the video size. This option is for video only. Default and minimum
+resolution is @code{640x480}.
+
+@item meter
+Set the EBU scale meter. Default is @code{9}. Common values are @code{9} and
+@code{18}, respectively for EBU scale meter +9 and EBU scale meter +18. Any
+other integer value between this range is allowed.
+
+@end table
+
+Example of real-time graph using @command{ffplay}, with a EBU scale meter +18:
+@example
+ffplay -f lavfi -i "amovie=input.mp3,ebur128=video=1:meter=18 [out0][out1]"
+@end example
+
+Run an analysis with @command{ffmpeg}:
+@example
+ffmpeg -nostats -i input.mp3 -filter_complex ebur128 -f null -
+@end example
+
+@section settb, asettb
+
+Set the timebase to use for the output frames timestamps.
+It is mainly useful for testing timebase configuration.
+
+It accepts in input an arithmetic expression representing a rational.
+The expression can contain the constants "AVTB" (the
+default timebase), "intb" (the input timebase) and "sr" (the sample rate,
+audio only).
+
+The default value for the input is "intb".
+
+@subsection Examples
+
+@itemize
+@item
+Set the timebase to 1/25:
+@example
+settb=1/25
+@end example
+
+@item
+Set the timebase to 1/10:
+@example
+settb=0.1
+@end example
+
+@item
+Set the timebase to 1001/1000:
+@example
+settb=1+0.001
+@end example
+
+@item
+Set the timebase to 2*intb:
+@example
+settb=2*intb
+@end example
+
+@item
+Set the default timebase value:
+@example
+settb=AVTB
+@end example
+@end itemize
+
+@section concat
+
+Concatenate audio and video streams, joining them together one after the
+other.
+
+The filter works on segments of synchronized video and audio streams. All
+segments must have the same number of streams of each type, and that will
+also be the number of streams at output.
+
+The filter accepts the following named parameters:
+@table @option
+
+@item n
+Set the number of segments. Default is 2.
+
+@item v
+Set the number of output video streams, that is also the number of video
+streams in each segment. Default is 1.
+
+@item a
+Set the number of output audio streams, that is also the number of video
+streams in each segment. Default is 0.
+
+@end table
+
+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
+segment, in the same order as the outputs, then the inputs for the second
+segment, etc.
+
+Related streams do not always have exactly the same duration, for various
+reasons including codec frame size or sloppy authoring. For that reason,
+related synchronized streams (e.g. a video and its audio track) should be
+concatenated at once. The concat filter will use the duration of the longest
+stream in each segment (except the last one), and if necessary pad shorter
+audio streams with silence.
+
+For this filter to work correctly, all segments must start at timestamp 0.
+
+All corresponding streams must have the same parameters in all segments; the
+filtering system will automatically select a common pixel format for video
+streams, and a common sample format, sample rate and channel layout for
+audio streams, but other settings, such as resolution, must be converted
+explicitly by the user.
+
+Different frame rates are acceptable but will result in variable frame rate
+at output; be sure to configure the output file to handle it.
+
+Examples:
+@itemize
+@item
+Concatenate an opening, an episode and an ending, all in bilingual version
+(video in stream 0, audio in streams 1 and 2):
+@example
+ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv -filter_complex \
+  '[0:0] [0:1] [0:2] [1:0] [1:1] [1:2] [2:0] [2:1] [2:2]
+   concat=n=3:v=1:a=2 [v] [a1] [a2]' \
+  -map '[v]' -map '[a1]' -map '[a2]' output.mkv
+@end example
+
+@item
+Concatenate two parts, handling audio and video separately, using the
+(a)movie sources, and adjusting the resolution:
+@example
+movie=part1.mp4, scale=512:288 [v1] ; amovie=part1.mp4 [a1] ;
+movie=part2.mp4, scale=512:288 [v2] ; amovie=part2.mp4 [a2] ;
+[v1] [v2] concat [outv] ; [a1] [a2] concat=v=0:a=1 [outa]
+@end example
+Note that a desync will happen at the stitch if the audio and video streams
+do not have exactly the same duration in the first file.
+
+@end itemize
+
+@section showspectrum
+
+Convert input audio to a video output, representing the audio frequency
+spectrum.
+
+The filter accepts the following named parameters:
+@table @option
+@item size, s
+Specify the video size for the output. Default value is @code{640x480}.
+@end table
+
+The usage is very similar to the showwaves filter; see the examples in that
+section.
+
+@section showwaves
+
+Convert input audio to a video output, representing the samples waves.
+
+The filter accepts the following named parameters:
+@table @option
+
+@item n
+Set the number of samples which are printed on the same column. A
+larger value will decrease the frame rate. Must be a positive
+integer. This option can be set only if the value for @var{rate}
+is not explicitly specified.
+
+@item rate, r
+Set the (approximate) output frame rate. This is done by setting the
+option @var{n}. Default value is "25".
+
+@item size, s
+Specify the video size for the output. Default value is "600x240".
+@end table
+
+Some examples follow.
+@itemize
+@item
+Output the input file audio and the corresponding video representation
+at the same time:
+@example
+amovie=a.mp3,asplit[out0],showwaves[out1]
+@end example
+
+@item
+Create a synthetic signal and show it with showwaves, forcing a
+framerate of 30 frames per second:
+@example
+aevalsrc=sin(1*2*PI*t)*sin(880*2*PI*t):cos(2*PI*200*t),asplit[out0],showwaves=r=30[out1]
+@end example
+@end itemize
+
+@c man end MULTIMEDIA FILTERS
+
+@chapter Multimedia Sources
+@c man begin MULTIMEDIA SOURCES
+
+Below is a description of the currently available multimedia sources.
+
+@section amovie
+
+This is the same as @ref{src_movie} source, except it selects an audio
+stream by default.
+
+@anchor{src_movie}
 @section movie
 
-Read a video stream from a movie container.
-
-Note that this source is a hack that bypasses the standard input path. It can be
-useful in applications that do not support arbitrary filter graphs, but its use
-is discouraged in those that do. Specifically in @command{avconv} this filter
-should never be used, the @option{-filter_complex} option fully replaces it.
+Read audio and/or video stream(s) from a movie container.
 
 It accepts the syntax: @var{movie_name}[:@var{options}] where
 @var{movie_name} is the name of the resource to read (not necessarily
@@ -2207,11 +4745,27 @@
 @code{av_strtod} so the numerical value may be suffixed by an IS
 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".
+
 @item stream_index, si
 Specifies the index of the video stream to read. If the value is -1,
 the best suited video stream will be automatically selected. Default
-value is "-1".
+value is "-1". Deprecated. If the filter is called "amovie", it will select
+audio instead of video.
 
+@item loop
+Specifies how many times to read the stream in sequence.
+If the value is less than 1, the stream will be read again and again.
+Default value is "1".
+
+Note that when the movie is looped the source timestamps are not
+changed, so it will generate non monotonically increasing timestamps.
 @end table
 
 This filter allows to overlay a second video on top of main input of
@@ -2223,132 +4777,32 @@
 movie --> scale--> deltapts1 -------+
 @end example
 
-Some examples follow:
+Some examples follow.
+
+@itemize
+@item
+Skip 3.2 seconds from the start of the avi file in.avi, and overlay it
+on top of the input labelled as "in":
 @example
-# skip 3.2 seconds from the start of the avi file in.avi, and overlay it
-# on top of the input labelled as "in".
 movie=in.avi:seek_point=3.2, scale=180:-1, setpts=PTS-STARTPTS [movie];
 [in] setpts=PTS-STARTPTS, [movie] overlay=16:16 [out]
+@end example
 
-# read from a video4linux2 device, and overlay it on top of the input
-# labelled as "in"
+@item
+Read from a video4linux2 device, and overlay it on top of the input
+labelled as "in":
+@example
 movie=/dev/video0:f=video4linux2, scale=180:-1, setpts=PTS-STARTPTS [movie];
 [in] setpts=PTS-STARTPTS, [movie] overlay=16:16 [out]
-
 @end example
 
-@section nullsrc
-
-Null video source, never return images. It is mainly useful as a
-template and to be employed in analysis / debugging tools.
-
-It accepts as optional parameter a string of the form
-@var{width}:@var{height}:@var{timebase}.
-
-@var{width} and @var{height} specify the size of the configured
-source. The default values of @var{width} and @var{height} are
-respectively 352 and 288 (corresponding to the CIF size format).
-
-@var{timebase} specifies an arithmetic expression representing a
-timebase. The expression can contain the constants "PI", "E", "PHI",
-"AVTB" (the default timebase), and defaults to the value "AVTB".
-
-@section frei0r_src
-
-Provide a frei0r source.
-
-To enable compilation of this filter you need to install the frei0r
-header and configure Libav with --enable-frei0r.
-
-The source supports the syntax:
+@item
+Read the first video stream and the audio stream with id 0x81 from
+dvd.vob; the video is connected to the pad named "video" and the audio is
+connected to the pad named "audio":
 @example
-@var{size}:@var{rate}:@var{src_name}[@{=|:@}@var{param1}:@var{param2}:...:@var{paramN}]
+movie=dvd.vob:s=v:0+#0x81 [video] [audio]
 @end example
+@end itemize
 
-@var{size} is the size of the video to generate, may be a string of the
-form @var{width}x@var{height} or a frame size abbreviation.
-@var{rate} is the rate of the video to generate, may be a string of
-the form @var{num}/@var{den} or a frame rate abbreviation.
-@var{src_name} is the name to the frei0r source to load. For more
-information regarding frei0r and how to set the parameters read the
-section @ref{frei0r} in the description of the video filters.
-
-Some examples follow:
-@example
-# generate a frei0r partik0l source with size 200x200 and framerate 10
-# which is overlayed on the overlay filter main input
-frei0r_src=200x200:10:partik0l=1234 [overlay]; [in][overlay] overlay
-@end example
-
-@section rgbtestsrc, testsrc
-
-The @code{rgbtestsrc} source generates an RGB test pattern useful for
-detecting RGB vs BGR issues. You should see a red, green and blue
-stripe from top to bottom.
-
-The @code{testsrc} source generates a test video pattern, showing a
-color pattern, a scrolling gradient and a timestamp. This is mainly
-intended for testing purposes.
-
-Both sources accept an optional sequence of @var{key}=@var{value} pairs,
-separated by ":". The description of the accepted options follows.
-
-@table @option
-
-@item size, s
-Specify the size of the sourced video, it may be a string of the form
-@var{width}x@var{height}, or the name of a size abbreviation. The
-default value is "320x240".
-
-@item rate, r
-Specify the frame rate of the sourced video, as the number of frames
-generated per second. It has to be a string in the format
-@var{frame_rate_num}/@var{frame_rate_den}, an integer number, a float
-number or a valid video frame rate abbreviation. The default value is
-"25".
-
-@item sar
-Set the sample aspect ratio of the sourced video.
-
-@item duration
-Set the video duration of the sourced video. The accepted syntax is:
-@example
-[-]HH[:MM[:SS[.m...]]]
-[-]S+[.m...]
-@end example
-See also the function @code{av_parse_time()}.
-
-If not specified, or the expressed duration is negative, the video is
-supposed to be generated forever.
-@end table
-
-For example the following:
-@example
-testsrc=duration=5.3:size=qcif:rate=10
-@end example
-
-will generate a video with a duration of 5.3 seconds, with size
-176x144 and a framerate of 10 frames per second.
-
-@c man end VIDEO SOURCES
-
-@chapter Video Sinks
-@c man begin VIDEO SINKS
-
-Below is a description of the currently available video sinks.
-
-@section buffersink
-
-Buffer video frames, and make them available to the end of the filter
-graph.
-
-This sink is intended for a programmatic use through the interface defined in
-@file{libavfilter/buffersink.h}.
-
-@section nullsink
-
-Null video sink, do absolutely nothing with the input video. It is
-mainly useful as a template and to be employed in analysis / debugging
-tools.
-
-@c man end VIDEO SINKS
+@c man end MULTIMEDIA SOURCES
diff --git a/doc/general.texi b/doc/general.texi
index 7b78308..7f50c11 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -11,11 +11,19 @@
 
 @chapter External libraries
 
-Libav can be hooked up with a number of external libraries to add support
+FFmpeg can be hooked up with a number of external libraries to add support
 for more formats. None of them are used by default, their use has to be
 explicitly requested by passing the appropriate flags to
 @command{./configure}.
 
+@section OpenJPEG
+
+FFmpeg can use the OpenJPEG libraries for encoding/decoding J2K videos.  Go to
+@url{http://www.openjpeg.org/} to get the libraries and follow the installation
+instructions.  To enable using OpenJPEG in FFmpeg, pass @code{--enable-libopenjpeg} to
+@file{./configure}.
+
+
 @section OpenCORE and VisualOn libraries
 
 Spun off Google Android sources, OpenCore, VisualOn and Fraunhofer
@@ -25,13 +33,13 @@
 OpenCORE and VisualOn libraries are under the Apache License 2.0
 (see @url{http://www.apache.org/licenses/LICENSE-2.0} for details), which is
 incompatible with the LGPL version 2.1 and GPL version 2. You have to
-upgrade Libav's license to LGPL version 3 (or if you have enabled
+upgrade FFmpeg's license to LGPL version 3 (or if you have enabled
 GPL components, GPL version 3) to use it.
 @end float
 
 @subsection OpenCORE AMR
 
-Libav can make use of the OpenCORE libraries for AMR-NB
+FFmpeg can make use of the OpenCORE libraries for AMR-NB
 decoding/encoding and AMR-WB decoding.
 
 Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the
@@ -41,7 +49,7 @@
 
 @subsection VisualOn AAC encoder library
 
-Libav can make use of the VisualOn AACenc library for AAC encoding.
+FFmpeg can make use of the VisualOn AACenc library for AAC encoding.
 
 Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the
 instructions for installing the library.
@@ -49,7 +57,7 @@
 
 @subsection VisualOn AMR-WB encoder library
 
-Libav can make use of the VisualOn AMR-WBenc library for AMR-WB encoding.
+FFmpeg can make use of the VisualOn AMR-WBenc library for AMR-WB encoding.
 
 Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the
 instructions for installing the library.
@@ -57,7 +65,7 @@
 
 @subsection Fraunhofer AAC library
 
-Libav can make use of the Fraunhofer AAC library for AAC encoding.
+FFmpeg can make use of the Fraunhofer AAC library for AAC encoding.
 
 Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the
 instructions for installing the library.
@@ -65,15 +73,23 @@
 
 @section LAME
 
-Libav can make use of the LAME library for MP3 encoding.
+FFmpeg can make use of the LAME library for MP3 encoding.
 
 Go to @url{http://lame.sourceforge.net/} and follow the
 instructions for installing the library.
 Then pass @code{--enable-libmp3lame} to configure to enable it.
 
+@section TwoLAME
+
+FFmpeg can make use of the TwoLAME library for MP2 encoding.
+
+Go to @url{http://www.twolame.org/} and follow the
+instructions for installing the library.
+Then pass @code{--enable-libtwolame} to configure to enable it.
+
 @section libvpx
 
-Libav can make use of the libvpx library for VP8 encoding.
+FFmpeg can make use of the libvpx library for VP8 encoding.
 
 Go to @url{http://www.webmproject.org/} and follow the instructions for
 installing the library. Then pass @code{--enable-libvpx} to configure to
@@ -81,7 +97,7 @@
 
 @section x264
 
-Libav can make use of the x264 library for H.264 encoding.
+FFmpeg can make use of the x264 library for H.264 encoding.
 
 Go to @url{http://www.videolan.org/developers/x264.html} and follow the
 instructions for installing the library. Then pass @code{--enable-libx264} to
@@ -90,14 +106,14 @@
 @float NOTE
 x264 is under the GNU Public License Version 2 or later
 (see @url{http://www.gnu.org/licenses/old-licenses/gpl-2.0.html} for
-details), you must upgrade Libav's license to GPL in order to use it.
+details), you must upgrade FFmpeg's license to GPL in order to use it.
 @end float
 
 @section libilbc
 
 iLBC is a narrowband speech codec that has been made freely available
 by Google as part of the WebRTC project. libilbc is a packaging friendly
-copy of the iLBC codec. Libav can make use of the libilbc library for
+copy of the iLBC codec. FFmpeg can make use of the libilbc library for
 iLBC encoding and decoding.
 
 Go to @url{https://github.com/dekkers/libilbc} and follow the instructions for
@@ -106,13 +122,13 @@
 
 
 
-@chapter Supported File Formats and Codecs
+@chapter Supported File Formats, Codecs or Features
 
 You can use the @code{-formats} and @code{-codecs} options to have an exhaustive list.
 
 @section File Formats
 
-Libav supports the following file formats through the @code{libavformat}
+FFmpeg supports the following file formats through the @code{libavformat}
 library:
 
 @multitable @columnfractions .4 .1 .1 .4
@@ -120,12 +136,17 @@
 @item 4xm                       @tab   @tab X
     @tab 4X Technologies format, used in some games.
 @item 8088flex TMV              @tab   @tab X
+@item ACT Voice                 @tab   @tab X
+    @tab contains G.729 audio
 @item Adobe Filmstrip           @tab X @tab X
 @item Audio IFF (AIFF)          @tab X @tab X
 @item American Laser Games MM   @tab   @tab X
     @tab Multimedia format used in games like Mad Dog McCree.
 @item 3GPP AMR                  @tab X @tab X
+@item Amazing Studio Packed Animation File        @tab   @tab X
+    @tab Multimedia format used in game Heart Of Darkness.
 @item Apple HTTP Live Streaming @tab   @tab X
+@item Artworx Data Format       @tab   @tab X
 @item ASF                       @tab X @tab X
 @item AVI                       @tab X @tab X
 @item AVISynth                  @tab   @tab X
@@ -135,6 +156,7 @@
     @tab Audio and video format used in some games by Beam Software.
 @item Bethesda Softworks VID    @tab   @tab X
     @tab Used in some games from Bethesda Softworks.
+@item Binary text               @tab   @tab X
 @item Bink                      @tab   @tab X
     @tab Multimedia format used by many games.
 @item Bitmap Brothers JV        @tab   @tab X
@@ -153,7 +175,7 @@
     @tab Video format used by CD+G karaoke disks
 @item Commodore CDXL            @tab   @tab X
     @tab Amiga CD video format
-@item Core Audio Format         @tab   @tab X
+@item Core Audio Format         @tab X @tab X
     @tab Apple Core Audio Format
 @item CRC testing format        @tab X @tab
 @item Creative Voice            @tab X @tab X
@@ -171,7 +193,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 FFM (AVserver live feed)  @tab X @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
     @tab Only embedded audio is decoded.
@@ -182,13 +204,19 @@
 @item framecrc testing format   @tab X @tab
 @item FunCom ISS                @tab   @tab X
     @tab Audio format used in various games from FunCom like The Longest Journey.
+@item G.723.1                   @tab X @tab X
+@item G.729 BIT                 @tab X @tab X
+@item G.729 raw                 @tab   @tab X
 @item GIF Animation             @tab X @tab
 @item GXF                       @tab X @tab X
     @tab General eXchange Format SMPTE 360M, used by Thomson Grass Valley
          playout servers.
+@item iCEDraw File              @tab   @tab X
+@item ICO                       @tab X @tab X
+    @tab Microsoft Windows ICO
 @item id Quake II CIN video     @tab   @tab X
 @item id RoQ                    @tab X @tab X
-    @tab Used in Quake III, Jedi Knight 2, other computer games.
+    @tab Used in Quake III, Jedi Knight 2 and other computer games.
 @item IEC61937 encapsulation @tab X @tab X
 @item IFF                       @tab   @tab X
     @tab Interchange File Format
@@ -202,6 +230,8 @@
 @item LATM                      @tab X @tab X
 @item LMLM4                     @tab   @tab X
     @tab Used by Linux Media Labs MPEG-4 PCI boards
+@item LOAS                      @tab   @tab X
+    @tab contains LATM multiplexed AAC audio
 @item LXF                       @tab   @tab X
     @tab VR native stream format, used by Leitch/Harris' video servers.
 @item Matroska                  @tab X @tab X
@@ -211,6 +241,7 @@
 @item MAXIS XA                  @tab   @tab X
     @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 Mobotix .mxg              @tab   @tab X
 @item Monkey's Audio            @tab   @tab X
 @item Motion Pixels MVI         @tab   @tab X
@@ -256,6 +287,7 @@
 @item raw Dirac                 @tab X @tab X
 @item raw DNxHD                 @tab X @tab X
 @item raw DTS                   @tab X @tab X
+@item raw DTS-HD                @tab   @tab X
 @item raw E-AC-3                @tab X @tab X
 @item raw FLAC                  @tab X @tab X
 @item raw GSM                   @tab   @tab X
@@ -273,6 +305,7 @@
 @item raw video                 @tab X @tab X
 @item raw id RoQ                @tab X @tab
 @item raw Shorten               @tab   @tab X
+@item raw TAK                   @tab   @tab X
 @item raw TrueHD                @tab X @tab X
 @item raw VC-1                  @tab   @tab X
 @item raw PCM A-law             @tab X @tab X
@@ -310,6 +343,7 @@
 @item RTP                       @tab X @tab X
 @item RTSP                      @tab X @tab X
 @item SAP                       @tab X @tab X
+@item SBG                       @tab   @tab X
 @item SDP                       @tab   @tab X
 @item Sega FILM/CPK             @tab   @tab X
     @tab Used in many Sega Saturn console games.
@@ -321,6 +355,8 @@
     @tab Multimedia format used by many games.
 @item SMJPEG                    @tab X @tab X
     @tab Used in certain Loki game ports.
+@item Smush                     @tab   @tab X
+    @tab Multimedia format used in some LucasArts games.
 @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
@@ -335,9 +371,9 @@
 @item True Audio                @tab   @tab X
 @item VC-1 test bitstream       @tab X @tab X
 @item WAV                       @tab X @tab X
-@item WavPack                   @tab   @tab X
+@item WavPack                   @tab X @tab X
 @item WebM                      @tab X @tab X
-@item Windows Televison (WTV)   @tab   @tab X
+@item Windows Televison (WTV)   @tab X @tab X
 @item Wing Commander III movie  @tab   @tab X
     @tab Multimedia format used in Origin's Wing Commander III computer game.
 @item Westwood Studios audio    @tab   @tab X
@@ -348,16 +384,16 @@
     @tab Microsoft video container used in Xbox games.
 @item xWMA                      @tab   @tab X
     @tab Microsoft audio container used by XAudio 2.
+@item eXtended BINary text (XBIN) @tab @tab X
 @item YUV4MPEG pipe             @tab X @tab X
 @item Psygnosis YOP             @tab   @tab X
-@item ZeroCodec Lossless Video  @tab   @tab X
 @end multitable
 
 @code{X} means that encoding (resp. decoding) is supported.
 
 @section Image Formats
 
-Libav can read and write images for each frame of a video sequence. The
+FFmpeg can read and write images for each frame of a video sequence. The
 following image formats are supported:
 
 @multitable @columnfractions .4 .1 .1 .4
@@ -370,10 +406,11 @@
     @tab Microsoft BMP image
 @item DPX          @tab X @tab X
     @tab Digital Picture Exchange
+@item EXR          @tab   @tab X
+    @tab OpenEXR
 @item JPEG         @tab X @tab X
     @tab Progressive JPEG is not supported.
-@item JPEG 2000    @tab E @tab E
-    @tab decoding supported through external library libopenjpeg
+@item JPEG 2000    @tab X @tab X
 @item JPEG-LS      @tab X @tab X
 @item LJPEG        @tab X @tab
     @tab Lossless JPEG
@@ -390,7 +427,6 @@
 @item PIC          @tab @tab X
     @tab Pictor/PC Paint
 @item PNG          @tab X @tab X
-    @tab 2/4 bpp not supported yet
 @item PPM          @tab X @tab X
     @tab Portable PixelMap image
 @item PTX          @tab   @tab X
@@ -403,7 +439,7 @@
     @tab YUV, JPEG and some extension is not supported yet.
 @item Truevision Targa  @tab X @tab X
     @tab Targa (.TGA) image format
-@item XBM  @tab X @tab
+@item XBM  @tab X @tab X
     @tab X BitMap image format
 @item XWD  @tab X @tab X
     @tab X Window Dump image format
@@ -424,9 +460,10 @@
 @item 8SVX fibonacci         @tab     @tab  X
 @item A64 multicolor         @tab  X  @tab
     @tab Creates video suitable to be played on a commodore 64 (multicolor mode).
+@item Amazing Studio PAF Video @tab     @tab  X
 @item American Laser Games MM  @tab    @tab X
     @tab Used in games like Mad Dog McCree.
-@item AMV Video              @tab     @tab  X
+@item AMV Video              @tab  X  @tab  X
     @tab Used in Chinese MP3 players.
 @item ANSI/ASCII art         @tab     @tab  X
 @item Apple MJPEG-B          @tab     @tab  X
@@ -446,13 +483,18 @@
 @item Autodesk Animator Flic video  @tab     @tab  X
 @item Autodesk RLE           @tab     @tab  X
     @tab fourcc: AASC
+@item Avid 1:1 10-bit RGB Packer  @tab  X  @tab  X
+    @tab fourcc: AVrp
 @item AVS (Audio Video Standard) video  @tab     @tab  X
     @tab Video encoding used by the Creature Shock game.
+@item AYUV                   @tab  X  @tab  X
+    @tab Microsoft uncompressed packed 4:4:4:4
 @item Beam Software VB       @tab     @tab  X
 @item Bethesda VID video     @tab     @tab  X
     @tab Used in some games from Bethesda Softworks.
 @item Bink Video             @tab     @tab  X
 @item Bitmap Brothers JV video  @tab   @tab X
+@item y41p Brooktree uncompressed 4:1:1 12-bit     @tab  X  @tab  X
 @item Brute Force & Ignorance   @tab   @tab X
     @tab Used in the game Flash Traffic: City of Angels.
 @item C93 video              @tab     @tab  X
@@ -472,10 +514,11 @@
 @item Cinepak                @tab     @tab  X
 @item Cirrus Logic AccuPak   @tab  X  @tab  X
     @tab fourcc: CLJR
+@item CPiA Video Format      @tab     @tab  X
 @item Creative YUV (CYUV)    @tab     @tab  X
 @item DFA                    @tab     @tab  X
     @tab Codec used in Chronomaster game.
-@item Dirac                  @tab  E  @tab  E
+@item Dirac                  @tab  E  @tab  X
     @tab supported through external library libschroedinger
 @item Deluxe Paint Animation @tab     @tab  X
 @item DNxHD                  @tab   X @tab  X
@@ -495,11 +538,12 @@
 @item Electronic Arts TGQ video  @tab     @tab  X
 @item Electronic Arts TQI video  @tab     @tab  X
 @item Escape 124             @tab     @tab  X
+@item Escape 130             @tab     @tab  X
 @item FFmpeg video codec #1  @tab  X  @tab  X
-    @tab experimental lossless codec (fourcc: FFV1)
+    @tab lossless codec (fourcc: FFV1)
 @item Flash Screen Video v1  @tab  X  @tab  X
     @tab fourcc: FSV1
-@item Flash Screen Video v2  @tab     @tab  X
+@item Flash Screen Video v2  @tab  X  @tab  X
 @item Flash Video (FLV)      @tab  X  @tab  X
     @tab Sorenson H.263 used in Flash
 @item Forward Uncompressed   @tab     @tab  X
@@ -531,6 +575,7 @@
     @tab Used in the game Cyberia from Interplay.
 @item Interplay MVE video    @tab     @tab  X
     @tab Used in Interplay .MVE files.
+@item J2K @tab  X  @tab  X
 @item Karl Morton's video codec  @tab     @tab  X
     @tab Codec used in Worms games.
 @item Kega Game Video (KGV1) @tab      @tab  X
@@ -539,6 +584,8 @@
 @item LCL (LossLess Codec Library) MSZH  @tab     @tab  X
 @item LCL (LossLess Codec Library) ZLIB  @tab  E  @tab  E
 @item LOCO                   @tab     @tab  X
+@item LucasArts Smush        @tab     @tab  X
+    @tab Used in LucasArts games.
 @item lossless MJPEG         @tab  X  @tab  X
 @item Microsoft ATC Screen   @tab     @tab  X
     @tab Also known as Microsoft Screen 3.
@@ -577,8 +624,10 @@
     @tab fourcc: VP60,VP61,VP62
 @item VP8                    @tab  E  @tab  X
     @tab fourcc: VP80, encoding supported through external library libvpx
-@item planar RGB             @tab     @tab  X
-    @tab fourcc: 8BPS
+@item Pinnacle TARGA CineWave YUV16 @tab     @tab  X
+    @tab fourcc: Y216
+@item Prores                 @tab     @tab  X
+    @tab fourcc: apch,apcn,apcs,apco
 @item Q-team QPEG            @tab     @tab  X
     @tab fourccs: QPEG, Q1.0, Q1.1
 @item QuickTime 8BPS video   @tab     @tab  X
@@ -588,8 +637,8 @@
     @tab fourcc: 'smc '
 @item QuickTime video (RPZA) @tab     @tab  X
     @tab fourcc: rpza
-@item R10K AJA Kona 10-bit RGB Codec     @tab     @tab  X
-@item R210 Quicktime Uncompressed RGB 10-bit     @tab     @tab  X
+@item R10K AJA Kona 10-bit RGB Codec     @tab  X  @tab  X
+@item R210 Quicktime Uncompressed RGB 10-bit     @tab  X  @tab  X
 @item Raw Video              @tab  X  @tab  X
 @item RealVideo 1.0          @tab  X  @tab  X
 @item RealVideo 2.0          @tab  X  @tab  X
@@ -624,6 +673,8 @@
     @tab Codec used in DOS CD-ROM FlashBack game.
 @item Ut Video               @tab  X  @tab  X
 @item v210 QuickTime uncompressed 4:2:2 10-bit     @tab  X  @tab  X
+@item v308 QuickTime uncompressed 4:4:4            @tab  X  @tab  X
+@item v408 QuickTime uncompressed 4:4:4:4          @tab  X  @tab  X
 @item v410 QuickTime uncompressed 4:4:4 10-bit     @tab  X  @tab  X
 @item VBLE Lossless Codec    @tab     @tab  X
 @item VMware Screen Codec / VMware Video  @tab     @tab  X
@@ -642,6 +693,9 @@
 @item WMV7                   @tab  X  @tab  X
 @item YAMAHA SMAF            @tab  X  @tab  X
 @item Psygnosis YOP Video    @tab     @tab  X
+@item yuv4                   @tab  X  @tab  X
+    @tab libquicktime uncompressed packed 4:2:0
+@item ZeroCodec Lossless Video @tab     @tab  X
 @item ZLIB                   @tab  X  @tab  X
     @tab part of LCL, encoder experimental
 @item Zip Motion Blocks Video  @tab   X @tab  X
@@ -657,6 +711,8 @@
 @multitable @columnfractions .4 .1 .1 .4
 @item Name @tab Encoding @tab Decoding @tab Comments
 @item 8SVX audio             @tab     @tab  X
+@item AAC+                   @tab  E  @tab  X
+    @tab encoding supported through external library libaacplus
 @item AAC                    @tab  E  @tab  X
     @tab encoding supported through external library libfaac and libvo-aacenc
 @item AC-3                   @tab IX  @tab  X
@@ -708,20 +764,23 @@
     @tab encoding supported through external library libopencore-amrnb
 @item AMR-WB                 @tab  E  @tab  X
     @tab encoding supported through external library libvo-amrwbenc
+@item Amazing Studio PAF Audio @tab     @tab  X
 @item Apple lossless audio   @tab  X  @tab  X
     @tab QuickTime fourcc 'alac'
 @item Atrac 1                @tab     @tab  X
 @item Atrac 3                @tab     @tab  X
 @item Bink Audio             @tab     @tab  X
     @tab Used in Bink and Smacker files in many games.
+@item CELT                   @tab     @tab  E
+    @tab decoding supported through external library libcelt
 @item Delphine Software International CIN audio  @tab     @tab  X
     @tab Codec used in Delphine Software International games.
 @item Discworld II BMV Audio @tab     @tab  X
 @item COOK                   @tab     @tab  X
     @tab All versions except 5.1 are supported.
-@item DCA (DTS Coherent Acoustics)  @tab     @tab  X
+@item DCA (DTS Coherent Acoustics)  @tab  X  @tab  X
 @item DPCM id RoQ            @tab  X  @tab  X
-    @tab Used in Quake III, Jedi Knight 2, other computer games.
+    @tab Used in Quake III, Jedi Knight 2 and other computer games.
 @item DPCM Interplay         @tab     @tab  X
     @tab Used in various Interplay computer games.
 @item DPCM Sierra Online     @tab     @tab  X
@@ -733,7 +792,8 @@
 @item DV audio               @tab     @tab  X
 @item Enhanced AC-3          @tab  X  @tab  X
 @item FLAC (Free Lossless Audio Codec)  @tab  X  @tab  IX
-@item G.723.1                @tab     @tab  X
+@item G.723.1                @tab X @tab X
+@item G.729                  @tab     @tab  X
 @item GSM                    @tab  E  @tab  X
     @tab encoding supported through external library libgsm
 @item GSM Microsoft variant  @tab  E  @tab  X
@@ -750,6 +810,7 @@
     @tab Only versions 3.97-3.99 are supported.
 @item MP1 (MPEG audio layer 1)  @tab     @tab IX
 @item MP2 (MPEG audio layer 2)  @tab IX  @tab IX
+    @tab libtwolame can be used alternatively for encoding.
 @item MP3 (MPEG audio layer 3)  @tab  E  @tab IX
     @tab encoding supported through external library LAME, ADU MP3 and MP3onMP4 also supported
 @item MPEG-4 Audio Lossless Coding (ALS)  @tab     @tab  X
@@ -798,12 +859,19 @@
     @tab Used in Sierra VMD files.
 @item Smacker audio          @tab     @tab  X
 @item SMPTE 302M AES3 audio  @tab     @tab  X
+@item Sonic                  @tab  X  @tab  X
+    @tab experimental codec
+@item Sonic lossless         @tab  X  @tab  X
+    @tab experimental codec
 @item Speex                  @tab  E  @tab  E
     @tab supported through external library libspeex
+@item TAK (Tom's lossless Audio Kompressor)  @tab     @tab  X
 @item True Audio (TTA)       @tab     @tab  X
 @item TrueHD                 @tab     @tab  X
     @tab Used in HD-DVD and Blu-Ray discs.
 @item TwinVQ (VQF flavor)    @tab     @tab  X
+@item VIMA                   @tab     @tab  X
+    @tab Used in LucasArts SMUSH animations.
 @item Vorbis                 @tab  E  @tab  X
     @tab A native but very primitive encoder exists.
 @item WavPack                @tab     @tab  X
@@ -826,12 +894,19 @@
 
 @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 DVB          @tab X @tab X @tab X @tab X
-@item DVD          @tab X @tab X @tab X @tab X
-@item PGS          @tab   @tab   @tab   @tab X
-@item SubRip (SRT) @tab X @tab X @tab   @tab X
-@item XSUB         @tab   @tab   @tab X @tab X
+@item SSA/ASS          @tab X @tab X @tab X @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 PGS              @tab   @tab   @tab   @tab X
+@item RealText         @tab   @tab X @tab   @tab X
+@item SAMI             @tab   @tab X @tab   @tab X
+@item SubRip (SRT)     @tab X @tab X @tab X @tab X
+@item SubViewer        @tab   @tab X @tab   @tab X
+@item 3GPP Timed Text  @tab   @tab   @tab X @tab X
+@item WebVTT           @tab   @tab X @tab   @tab X
+@item XSUB             @tab   @tab   @tab X @tab X
 @end multitable
 
 @code{X} means that the feature is supported.
@@ -872,13 +947,17 @@
 @item Name              @tab Input  @tab Output
 @item ALSA              @tab X      @tab X
 @item BKTR              @tab X      @tab
+@item caca              @tab        @tab X
 @item DV1394            @tab X      @tab
+@item Lavfi virtual device @tab X   @tab
 @item Linux framebuffer @tab X      @tab
 @item JACK              @tab X      @tab
 @item LIBCDIO           @tab X
 @item LIBDC1394         @tab X      @tab
+@item OpenAL            @tab X
 @item OSS               @tab X      @tab X
 @item Pulseaudio        @tab X      @tab
+@item SDL               @tab        @tab X
 @item Video4Linux2      @tab X      @tab
 @item VfW capture       @tab X      @tab
 @item X11 grabbing      @tab X      @tab
@@ -886,4 +965,16 @@
 
 @code{X} means that input/output is supported.
 
+@section Timecode
+
+@multitable @columnfractions .4 .1 .1
+@item Codec/format      @tab Read   @tab Write
+@item AVI               @tab X      @tab X
+@item DV                @tab X      @tab X
+@item GXF               @tab X      @tab X
+@item MOV               @tab X      @tab X
+@item MPEG1/2           @tab X      @tab X
+@item MXF               @tab X      @tab X
+@end multitable
+
 @bye
diff --git a/doc/git-howto.texi b/doc/git-howto.texi
index 5114115..44e1cc6 100644
--- a/doc/git-howto.texi
+++ b/doc/git-howto.texi
@@ -1,9 +1,9 @@
 \input texinfo @c -*- texinfo -*-
 
-@settitle Using git to develop Libav
+@settitle Using git to develop FFmpeg
 
 @titlepage
-@center @titlefont{Using git to develop Libav}
+@center @titlefont{Using git to develop FFmpeg}
 @end titlepage
 
 @top
@@ -39,7 +39,7 @@
 
 Consult these resources whenever you have problems, they are quite exhaustive.
 
-What follows now is a basic introduction to Git and some Libav-specific
+What follows now is a basic introduction to Git and some FFmpeg-specific
 guidelines to ease the contribution to the project
 
 @chapter Basics Usage
@@ -53,16 +53,16 @@
 @section Cloning the source tree
 
 @example
-git clone git://git.libav.org/libav.git <target>
+git clone git://source.ffmpeg.org/ffmpeg <target>
 @end example
 
-This will put the Libav sources into the directory @var{<target>}.
+This will put the FFmpeg sources into the directory @var{<target>}.
 
 @example
-git clone git@@git.libav.org:libav.git <target>
+git clone git@@source.ffmpeg.org:ffmpeg <target>
 @end example
 
-This will put the Libav sources into the directory @var{<target>} and let
+This will put the FFmpeg sources into the directory @var{<target>} and let
 you push back your changes to the remote repository.
 
 Make sure that you do not have Windows line endings in your checkouts,
@@ -85,7 +85,7 @@
 the remote origin.
 
 @float IMPORTANT
-Since merge commits are forbidden @command{--rebase} (see below) is recommended.
+@command{--rebase} (see below) is recommended.
 @end float
 
 @section Rebasing your local branches
@@ -96,7 +96,7 @@
 
 fetches the changes from the main repository and replays your local commits
 over it. This is required to keep all your local changes at the top of
-Libav's master tree. The master tree will reject pushes with merge commits.
+FFmpeg's master tree. The master tree will reject pushes with merge commits.
 
 
 @section Adding/removing files/directories
@@ -127,7 +127,7 @@
 @end example
 
 You may also use the graphical tools like gitview or gitk or the web
-interface available at http://git.libav.org/
+interface available at http://source.ffmpeg.org/
 
 @section Checking source tree status
 
@@ -261,7 +261,7 @@
 @chapter Git configuration
 
 In order to simplify a few workflows, it is advisable to configure both
-your personal Git installation and your local Libav repository.
+your personal Git installation and your local FFmpeg repository.
 
 @section Personal Git installation
 
@@ -276,15 +276,15 @@
 @section Repository configuration
 
 In order to have @command{git send-email} automatically send patches
-to the libav-devel mailing list, add the following stanza
-to @file{/path/to/libav/repository/.git/config}:
+to the ffmpeg-devel mailing list, add the following stanza
+to @file{/path/to/ffmpeg/repository/.git/config}:
 
 @example
 [sendemail]
-        to = libav-devel@@libav.org
+        to = ffmpeg-devel@@ffmpeg.org
 @end example
 
-@chapter Libav specific
+@chapter FFmpeg specific
 
 @section Reverting broken commits
 
@@ -381,53 +381,35 @@
 pushing a typo in a comment, some of the steps may be unnecessary.
 Apply your common sense, but if in doubt, err on the side of caution.
 
-First make sure your Git repository is on a branch that is a direct
-descendant of the Libav master branch, which is the only one from which
-pushing to Libav is possible. Then run the following command:
+First, make sure that the commits and branches you are going to push
+match what you want pushed and that nothing is missing, extraneous or
+wrong. You can see what will be pushed by running the git push command
+with --dry-run first. And then inspecting the commits listed with
+@command{git log -p 1234567..987654}. The @command{git status} command
+may help in finding local changes that have been forgotten to be added.
 
-@itemize
-@item @command{git log --patch --stat origin/master..}
-
-to make sure that only the commits you want to push are pending, that
-the log messages of the commits are correct and descriptive and contain
-no cruft from @command{git am} and to doublecheck that the commits you
-want to push really only contain the changes they are supposed to contain.
-
-@item @command{git status}
-
-to ensure no local changes still need to be committed and that no local
-changes may have thrown off the results of your testing.
-@end itemize
-
-Next let the code pass through a full run of our testsuite. Before you do,
-the command @command{make fate-rsync} will update the test samples. Changes
-to the samples set are not very common and commits depending on samples
-changes are delayed for at least 24 hours to allow the new samples to
-propagate, so updating it once per day is sufficient.  Now execute
+Next let the code pass through a full run of our testsuite.
 
 @itemize
 @item @command{make distclean}
-@item @command{/path/to/libav/configure}
+@item @command{/path/to/ffmpeg/configure}
 @item @command{make check}
+@item if fate fails due to missing samples run @command{make fate-rsync} and retry
 @end itemize
 
-While the test suite covers a wide range of possible problems, it is not
-a panacea. Do not hesitate to perform any other tests necessary to convince
-yourself that the changes you are about to push actually work as expected.
+Make sure all your changes have been checked before pushing them, the
+testsuite only checks against regressions and that only to some extend. It does
+obviously not check newly added features/code to be working unless you have
+added a test for that (which is recommended).
 
 Also note that every single commit should pass the test suite, not just
-the result of a series of patches. So if you have a series of related
-commits, run the test suite on every single commit.
+the result of a series of patches.
 
-Finally, after pushing, mark all patches as committed on
-@url{http://patches.libav.org/,patchwork}.
-Sometimes this is not automatically done when a patch has been
-slightly modified from the version on the mailing list.
-Also update previous incarnations of the patches you push so that
-patchwork is not cluttered with cruft.
-
+Once everything passed, push the changes to your public ffmpeg clone and post a
+merge request to ffmpeg-devel. You can also push them directly but this is not
+recommended.
 
 @chapter Server Issues
 
-Contact the project admins @email{git@@libav.org} if you have technical
+Contact the project admins @email{root@@ffmpeg.org} if you have technical
 problems with the GIT server.
diff --git a/doc/git-howto.txt b/doc/git-howto.txt
index 036b567..5ba72ee 100644
--- a/doc/git-howto.txt
+++ b/doc/git-howto.txt
@@ -28,9 +28,9 @@
 You do not need a special username or password.
 All you need is to provide a ssh public key to the Git server admin.
 
-What follows now is a basic introduction to Git and some Libav-specific
+What follows now is a basic introduction to Git and some FFmpeg-specific
 guidelines. Read it at least once, if you are granted commit privileges to the
-Libav project you are expected to be familiar with these rules.
+FFmpeg project you are expected to be familiar with these rules.
 
 
 
@@ -39,18 +39,19 @@
 
 0. Get GIT:
 
+  Most distributions have a git package, if not
   You can get git from http://git-scm.com/
 
 
 1. Cloning the source tree:
 
-    git clone git://git.libav.org/libav.git <target>
+    git clone git://source.ffmpeg.org/ffmpeg <target>
 
-  This will put the Libav sources into the directory <target>.
+  This will put the FFmpeg sources into the directory <target>.
 
-    git clone git@git.libav.org:libav.git <target>
+    git clone git@source.ffmpeg.org:ffmpeg <target>
 
-  This will put the Libav sources into the directory <target> and let
+  This will put the FFmpeg sources into the directory <target> and let
   you push back your changes to the remote repository.
 
 
@@ -72,7 +73,7 @@
 
   fetches the changes from the main repository and replays your local commits
   over it. This is required to keep all your local changes at the top of
-  Libav's master tree. The master tree will reject pushes with merge commits.
+  FFmpeg's master tree. The master tree will reject pushes with merge commits.
 
 
 3. Adding/removing files/directories:
@@ -97,7 +98,7 @@
     git log <filename(s)>
 
   You may also use the graphical tools like gitview or gitk or the web
-  interface available at http://git.libav.org/
+  interface available at http://source.ffmpeg.org
 
 6. Checking source tree status:
 
@@ -268,5 +269,5 @@
   where $SHA1 is the commit SHA1 from the 'git log' output.
 
 
-Contact the project admins <git at libav dot org> if you have technical
+Contact the project admins <root at ffmpeg dot org> if you have technical
 problems with the GIT server.
diff --git a/doc/indevs.texi b/doc/indevs.texi
index b0ba6ac..a5a91fa 100644
--- a/doc/indevs.texi
+++ b/doc/indevs.texi
@@ -1,10 +1,10 @@
 @chapter Input Devices
 @c man begin INPUT DEVICES
 
-Input devices are configured elements in Libav which allow to access
+Input devices are configured elements in FFmpeg which allow to access
 the data coming from a multimedia device attached to your system.
 
-When you configure your Libav build, all the supported input devices
+When you configure your FFmpeg build, all the supported input devices
 are enabled by default. You can list all available ones using the
 configure option "--list-indevs".
 
@@ -42,10 +42,10 @@
 To see the list of cards currently recognized by your system check the
 files @file{/proc/asound/cards} and @file{/proc/asound/devices}.
 
-For example to capture with @command{avconv} from an ALSA device with
+For example to capture with @command{ffmpeg} from an ALSA device with
 card id 0, you may run the command:
 @example
-avconv -f alsa -i hw:0 alsaout.wav
+ffmpeg -f alsa -i hw:0 alsaout.wav
 @end example
 
 For more information see:
@@ -55,6 +55,114 @@
 
 BSD video input device.
 
+@section dshow
+
+Windows DirectShow input device.
+
+DirectShow support is enabled when FFmpeg is built with the mingw-w64 project.
+Currently only audio and video devices are supported.
+
+Multiple devices may be opened as separate inputs, but they may also be
+opened on the same input, which should improve synchronism between them.
+
+The input name should be in the format:
+
+@example
+@var{TYPE}=@var{NAME}[:@var{TYPE}=@var{NAME}]
+@end example
+
+where @var{TYPE} can be either @var{audio} or @var{video},
+and @var{NAME} is the device's name.
+
+@subsection Options
+
+If no options are specified, the device's defaults are used.
+If the device does not support the requested options, it will
+fail to open.
+
+@table @option
+
+@item video_size
+Set the video size in the captured video.
+
+@item framerate
+Set the framerate in the captured video.
+
+@item sample_rate
+Set the sample rate (in Hz) of the captured audio.
+
+@item sample_size
+Set the sample size (in bits) of the captured audio.
+
+@item channels
+Set the number of channels in the captured audio.
+
+@item list_devices
+If set to @option{true}, print a list of devices and exit.
+
+@item list_options
+If set to @option{true}, print a list of selected device's options
+and exit.
+
+@item video_device_number
+Set video device number for devices with same name (starts at 0,
+defaults to 0).
+
+@item audio_device_number
+Set audio device number for devices with same name (starts at 0,
+defaults to 0).
+
+@item pixel_format
+Select pixel format to be used by DirectShow. This may only be set when
+the video codec is not set or set to rawvideo.
+
+@item audio_buffer_size
+Set audio device buffer size in milliseconds (which can directly
+impact latency, depending on the device).
+Defaults to using the audio device's
+default buffer size (typically some multiple of 500ms).
+Setting this value too low can degrade performance.
+See also
+@url{http://msdn.microsoft.com/en-us/library/windows/desktop/dd377582(v=vs.85).aspx}
+
+@end table
+
+@subsection Examples
+
+@itemize
+
+@item
+Print the list of DirectShow supported devices and exit:
+@example
+$ ffmpeg -list_devices true -f dshow -i dummy
+@end example
+
+@item
+Open video device @var{Camera}:
+@example
+$ ffmpeg -f dshow -i video="Camera"
+@end example
+
+@item
+Open second video device with name @var{Camera}:
+@example
+$ ffmpeg -f dshow -video_device_number 1 -i video="Camera"
+@end example
+
+@item
+Open video device @var{Camera} and audio device @var{Microphone}:
+@example
+$ ffmpeg -f dshow -i video="Camera":audio="Microphone"
+@end example
+
+@item
+Print the list of supported options in selected device and exit:
+@example
+$ ffmpeg -list_options true -f dshow -i video="Camera"
+@end example
+
+@end itemize
+
 @section dv1394
 
 Linux DV 1394 input device.
@@ -72,18 +180,71 @@
 Documentation/fb/framebuffer.txt included in the Linux source tree.
 
 To record from the framebuffer device @file{/dev/fb0} with
-@command{avconv}:
+@command{ffmpeg}:
 @example
-avconv -f fbdev -r 10 -i /dev/fb0 out.avi
+ffmpeg -f fbdev -r 10 -i /dev/fb0 out.avi
 @end example
 
 You can take a single screenshot image with the command:
 @example
-avconv -f fbdev -frames:v 1 -r 1 -i /dev/fb0 screenshot.jpeg
+ffmpeg -f fbdev -frames:v 1 -r 1 -i /dev/fb0 screenshot.jpeg
 @end example
 
 See also @url{http://linux-fbdev.sourceforge.net/}, and fbset(1).
 
+@section iec61883
+
+FireWire DV/HDV input device using libiec61883.
+
+To enable this input device, you need libiec61883, libraw1394 and
+libavc1394 installed on your system. Use the configure option
+@code{--enable-libiec61883} to compile with the device enabled.
+
+The iec61883 capture device supports capturing from a video device
+connected via IEEE1394 (FireWire), using libiec61883 and the new Linux
+FireWire stack (juju). This is the default DV/HDV input method in Linux
+Kernel 2.6.37 and later, since the old FireWire stack was removed.
+
+Specify the FireWire port to be used as input file, or "auto"
+to choose the first port connected.
+
+@subsection Options
+
+@table @option
+
+@item dvtype
+Override autodetection of DV/HDV. This should only be used if auto
+detection does not work, or if usage of a different device type
+should be prohibited. Treating a DV device as HDV (or vice versa) will
+not work and result in undefined behavior.
+The values @option{auto}, @option{dv} and @option{hdv} are supported.
+
+@item dvbuffer
+Set maxiumum size of buffer for incoming data, in frames. For DV, this
+is an exact value. For HDV, it is not frame exact, since HDV does
+not have a fixed frame size.
+
+@end table
+
+@subsection Examples
+
+@itemize
+
+@item
+Grab and show the input of a FireWire DV/HDV device.
+@example
+ffplay -f iec61883 -i auto
+@end example
+
+@item
+Grab and record the input of a FireWire DV/HDV device,
+using a packet buffer of 100000 packets if the source is HDV.
+@example
+ffmpeg -f iec61883 -i auto -hdvbuffer 100000 out.mpg
+@end example
+
+@end itemize
+
 @section jack
 
 JACK input device.
@@ -95,24 +256,24 @@
 each audio channel, with name @var{client_name}:input_@var{N}, where
 @var{client_name} is the name provided by the application, and @var{N}
 is a number which identifies the channel.
-Each writable client will send the acquired data to the Libav input
+Each writable client will send the acquired data to the FFmpeg input
 device.
 
 Once you have created one or more JACK readable clients, you need to
 connect them to one or more JACK writable clients.
 
-To connect or disconnect JACK clients you can use the
-@file{jack_connect} and @file{jack_disconnect} programs, or do it
-through a graphical interface, for example with @file{qjackctl}.
+To connect or disconnect JACK clients you can use the @command{jack_connect}
+and @command{jack_disconnect} programs, or do it through a graphical interface,
+for example with @command{qjackctl}.
 
 To list the JACK clients and their properties you can invoke the command
-@file{jack_lsp}.
+@command{jack_lsp}.
 
 Follows an example which shows how to capture a JACK readable client
-with @command{avconv}.
+with @command{ffmpeg}.
 @example
-# Create a JACK writable client with name "libav".
-$ avconv -f jack -i libav -y out.wav
+# Create a JACK writable client with name "ffmpeg".
+$ ffmpeg -f jack -i ffmpeg -y out.wav
 
 # Start the sample jack_metro readable client.
 $ jack_metro -b 120 -d 0.2 -f 4000
@@ -123,20 +284,175 @@
 system:capture_2
 system:playback_1
 system:playback_2
-libav:input_1
+ffmpeg:input_1
 metro:120_bpm
 
-# Connect metro to the avconv writable client.
-$ jack_connect metro:120_bpm libav:input_1
+# Connect metro to the ffmpeg writable client.
+$ jack_connect metro:120_bpm ffmpeg:input_1
 @end example
 
 For more information read:
 @url{http://jackaudio.org/}
 
+@section lavfi
+
+Libavfilter input virtual device.
+
+This input device reads data from the open output pads of a libavfilter
+filtergraph.
+
+For each filtergraph open output, the input device will create a
+corresponding stream which is mapped to the generated output. Currently
+only video data is supported. The filtergraph is specified through the
+option @option{graph}.
+
+@subsection Options
+
+@table @option
+
+@item graph
+Specify the filtergraph to use as input. Each video open output must be
+labelled by a unique string of the form "out@var{N}", where @var{N} is a
+number starting from 0 corresponding to the mapped input stream
+generated by the device.
+The first unlabelled output is automatically assigned to the "out0"
+label, but all the others need to be specified explicitly.
+
+If not specified defaults to the filename specified for the input
+device.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+Create a color video stream and play it back with @command{ffplay}:
+@example
+ffplay -f lavfi -graph "color=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
+@end example
+
+@item
+Create three different video test filtered sources and play them:
+@example
+ffplay -f lavfi -graph "testsrc [out0]; testsrc,hflip [out1]; testsrc,negate [out2]" test3
+@end example
+
+@item
+Read an audio stream from a file using the amovie source and play it
+back with @command{ffplay}:
+@example
+ffplay -f lavfi "amovie=test.wav"
+@end example
+
+@item
+Read an audio stream and a video stream and play it back with
+@command{ffplay}:
+@example
+ffplay -f lavfi "movie=test.avi[out0];amovie=test.wav[out1]"
+@end example
+
+@end itemize
+
 @section libdc1394
 
 IIDC1394 input device, based on libdc1394 and libraw1394.
 
+@section openal
+
+The OpenAL input device provides audio capture on all systems with a
+working OpenAL 1.1 implementation.
+
+To enable this input device during configuration, you need OpenAL
+headers and libraries installed on your system, and need to configure
+FFmpeg with @code{--enable-openal}.
+
+OpenAL headers and libraries should be provided as part of your OpenAL
+implementation, or as an additional download (an SDK). Depending on your
+installation you may need to specify additional flags via the
+@code{--extra-cflags} and @code{--extra-ldflags} for allowing the build
+system to locate the OpenAL headers and libraries.
+
+An incomplete list of OpenAL implementations follows:
+
+@table @strong
+@item Creative
+The official Windows implementation, providing hardware acceleration
+with supported devices and software fallback.
+See @url{http://openal.org/}.
+@item OpenAL Soft
+Portable, open source (LGPL) software implementation. Includes
+backends for the most common sound APIs on the Windows, Linux,
+Solaris, and BSD operating systems.
+See @url{http://kcat.strangesoft.net/openal.html}.
+@item Apple
+OpenAL is part of Core Audio, the official Mac OS X Audio interface.
+See @url{http://developer.apple.com/technologies/mac/audio-and-video.html}
+@end table
+
+This device allows to capture from an audio input device handled
+through OpenAL.
+
+You need to specify the name of the device to capture in the provided
+filename. If the empty string is provided, the device will
+automatically select the default device. You can get the list of the
+supported devices by using the option @var{list_devices}.
+
+@subsection Options
+
+@table @option
+
+@item channels
+Set the number of channels in the captured audio. Only the values
+@option{1} (monaural) and @option{2} (stereo) are currently supported.
+Defaults to @option{2}.
+
+@item sample_size
+Set the sample size (in bits) of the captured audio. Only the values
+@option{8} and @option{16} are currently supported. Defaults to
+@option{16}.
+
+@item sample_rate
+Set the sample rate (in Hz) of the captured audio.
+Defaults to @option{44.1k}.
+
+@item list_devices
+If set to @option{true}, print a list of devices and exit.
+Defaults to @option{false}.
+
+@end table
+
+@subsection Examples
+
+Print the list of OpenAL supported devices and exit:
+@example
+$ ffmpeg -list_devices true -f openal -i dummy out.ogg
+@end example
+
+Capture from the OpenAL device @file{DR-BT101 via PulseAudio}:
+@example
+$ ffmpeg -f openal -i 'DR-BT101 via PulseAudio' out.ogg
+@end example
+
+Capture from the default device (note the empty string '' as filename):
+@example
+$ ffmpeg -f openal -i '' out.ogg
+@end example
+
+Capture from two devices simultaneously, writing to two different files,
+within the same @command{ffmpeg} command:
+@example
+$ ffmpeg -f openal -i 'DR-BT101 via PulseAudio' out1.ogg -f openal -i 'ALSA Default' out2.ogg
+@end example
+Note: not all OpenAL implementations support multiple simultaneous capture -
+try the latest OpenAL Soft if the above does not work.
+
 @section oss
 
 Open Sound System input device.
@@ -145,10 +461,10 @@
 representing the OSS input device, and is usually set to
 @file{/dev/dsp}.
 
-For example to grab from @file{/dev/dsp} using @command{avconv} use the
+For example to grab from @file{/dev/dsp} using @command{ffmpeg} use the
 command:
 @example
-avconv -f oss -i /dev/dsp /tmp/oss.wav
+ffmpeg -f oss -i /dev/dsp /tmp/oss.wav
 @end example
 
 For more information about OSS see:
@@ -165,10 +481,10 @@
 string "default"
 
 To list the pulse source devices and their properties you can invoke
-the command @file{pactl list sources}.
+the command @command{pactl list sources}.
 
 @example
-avconv -f pulse -i default /tmp/pulse.wav
+ffmpeg -f pulse -i default /tmp/pulse.wav
 @end example
 
 @subsection @var{server} AVOption
@@ -188,7 +504,7 @@
 @end example
 
 Specify the application name pulse will use when showing active clients,
-by default it is "libav"
+by default it is the LIBAVFORMAT_IDENT string
 
 @subsection @var{stream_name} AVOption
 
@@ -248,10 +564,10 @@
 representing the sndio input device, and is usually set to
 @file{/dev/audio0}.
 
-For example to grab from @file{/dev/audio0} using @command{avconv} use the
+For example to grab from @file{/dev/audio0} using @command{ffmpeg} use the
 command:
 @example
-avconv -f sndio -i /dev/audio0 /tmp/oss.wav
+ffmpeg -f sndio -i /dev/audio0 /tmp/oss.wav
 @end example
 
 @section video4linux2
@@ -268,17 +584,29 @@
 @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 avconv and avplay:
+Some usage examples of the video4linux2 devices with ffmpeg and ffplay:
 
+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
+clock (origin at the Unix Epoch) or the monotonic clock (origin usually at
+boot time, unaffected by NTP or manual changes to the clock). The
+@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.
 @example
 # Grab and show the input of a video4linux2 device.
-avplay -f video4linux2 -framerate 30 -video_size hd720 /dev/video0
+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.
-avconv -f video4linux2 -input_format mjpeg -i /dev/video0 out.mpeg
+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".
+
 @section vfwcap
 
 VfW (Video for Windows) capture input device.
@@ -300,7 +628,7 @@
 
 @var{hostname}:@var{display_number}.@var{screen_number} specifies the
 X11 display name of the screen to grab from. @var{hostname} can be
-ommitted, and defaults to "localhost". The environment variable
+omitted, and defaults to "localhost". The environment variable
 @env{DISPLAY} contains the default display name.
 
 @var{x_offset} and @var{y_offset} specify the offsets of the grabbed
@@ -309,24 +637,30 @@
 
 Check the X11 documentation (e.g. man X) for more detailed information.
 
-Use the @file{dpyinfo} program for getting basic information about the
+Use the @command{dpyinfo} program for getting basic information about the
 properties of your X11 display (e.g. grep for "name" or "dimensions").
 
-For example to grab from @file{:0.0} using @command{avconv}:
+For example to grab from @file{:0.0} using @command{ffmpeg}:
 @example
-avconv -f x11grab -r 25 -s cif -i :0.0 out.mpg
-
-# Grab at position 10,20.
-avconv -f x11grab -r 25 -s cif -i :0.0+10,20 out.mpg
+ffmpeg -f x11grab -r 25 -s cif -i :0.0 out.mpg
 @end example
 
-@subsection @var{follow_mouse} AVOption
-
-The syntax is:
+Grab at position @code{10,20}:
 @example
--follow_mouse centered|@var{PIXELS}
+ffmpeg -f x11grab -r 25 -s cif -i :0.0+10,20 out.mpg
 @end example
 
+@subsection Options
+
+@table @option
+@item draw_mouse
+Specify whether to draw the mouse pointer. A value of @code{0} specify
+not to draw the pointer. Default value is @code{1}.
+
+@item follow_mouse
+Make the grabbed area follow the mouse. The argument can be
+@code{centered} or a number of pixels @var{PIXELS}.
+
 When it is specified with "centered", the grabbing region follows the mouse
 pointer and keeps the pointer at the center of region; otherwise, the region
 follows only when the mouse pointer reaches within @var{PIXELS} (greater than
@@ -334,29 +668,37 @@
 
 For example:
 @example
-avconv -f x11grab -follow_mouse centered -r 25 -s cif -i :0.0 out.mpg
-
-# Follows only when the mouse pointer reaches within 100 pixels to edge
-avconv -f x11grab -follow_mouse 100 -r 25 -s cif -i :0.0 out.mpg
+ffmpeg -f x11grab -follow_mouse centered -r 25 -s cif -i :0.0 out.mpg
 @end example
 
-@subsection @var{show_region} AVOption
-
-The syntax is:
+To follow only when the mouse pointer reaches within 100 pixels to edge:
 @example
--show_region 1
+ffmpeg -f x11grab -follow_mouse 100 -r 25 -s cif -i :0.0 out.mpg
 @end example
 
-If @var{show_region} AVOption is specified with @var{1}, then the grabbing
-region will be indicated on screen. With this option, it's easy to know what is
-being grabbed if only a portion of the screen is grabbed.
+@item framerate
+Set the grabbing frame rate. Default value is @code{ntsc},
+corresponding to a framerate of @code{30000/1001}.
+
+@item show_region
+Show grabbed region on screen.
+
+If @var{show_region} is specified with @code{1}, then the grabbing
+region will be indicated on screen. With this option, it is easy to
+know what is being grabbed if only a portion of the screen is grabbed.
 
 For example:
 @example
-avconv -f x11grab -show_region 1 -r 25 -s cif -i :0.0+10,20 out.mpg
-
-# With follow_mouse
-avconv -f x11grab -follow_mouse centered -show_region 1  -r 25 -s cif -i :0.0 out.mpg
+ffmpeg -f x11grab -show_region 1 -r 25 -s cif -i :0.0+10,20 out.mpg
 @end example
 
+With @var{follow_mouse}:
+@example
+ffmpeg -f x11grab -follow_mouse centered -show_region 1 -r 25 -s cif -i :0.0 out.mpg
+@end example
+
+@item video_size
+Set the video frame size. Default value is @code{vga}.
+@end table
+
 @c man end INPUT DEVICES
diff --git a/doc/issue_tracker.txt b/doc/issue_tracker.txt
new file mode 100644
index 0000000..d487f66
--- /dev/null
+++ b/doc/issue_tracker.txt
@@ -0,0 +1,213 @@
+FFmpeg's bug/patch/feature request tracker manual
+=================================================
+
+NOTE: This is a draft.
+
+Overview:
+---------
+
+FFmpeg uses Trac for tracking issues, new issues and changes to
+existing issues can be done through a web interface.
+
+Issues can be different kinds of things we want to keep track of
+but that do not belong into the source tree itself. This includes
+bug reports, patches, feature requests and license violations. We
+might add more items to this list in the future, so feel free to
+propose a new `type of issue' on the ffmpeg-devel mailing list if
+you feel it is worth tracking.
+
+It is possible to subscribe to individual issues by adding yourself to the
+Cc list or to subscribe to the ffmpeg-trac mailing list which receives
+a mail for every change to every issue.
+(the above does all work already after light testing)
+
+The subscription URL for the ffmpeg-trac list is:
+http(s)://ffmpeg.org/mailman/listinfo/ffmpeg-trac
+The URL of the webinterface of the tracker is:
+http(s)://ffmpeg.org/trac/ffmpeg
+
+Type:
+-----
+bug / defect
+    An error, flaw, mistake, failure, or fault in FFmpeg or libav* that
+    prevents it from behaving as intended.
+
+feature request / enhancement
+    Request of support for encoding or decoding of a new codec, container
+    or variant.
+    Request of support for more, less or plain different output or behavior
+    where the current implementation cannot be considered wrong.
+
+license violation
+    ticket to keep track of (L)GPL violations of ffmpeg by others
+
+patch
+    A patch as generated by diff which conforms to the patch submission and
+    development policy.
+
+
+Priority:
+---------
+critical
+    Bugs and patches which deal with data loss and security issues.
+    No feature request can be critical.
+
+important
+    Bugs which make FFmpeg unusable for a significant number of users, and
+    patches fixing them.
+    Examples here might be completely broken MPEG-4 decoding or a build issue
+    on Linux.
+    While broken 4xm decoding or a broken OS/2 build would not be important,
+    the separation to normal is somewhat fuzzy.
+    For feature requests this priority would be used for things many people
+    want.
+    Regressions also should be marked as important, regressions are bugs that
+    don't exist in a past revision or another branch.
+
+normal
+
+
+minor
+    Bugs and patches about things like spelling errors, "mp2" instead of
+    "mp3" being shown and such.
+    Feature requests about things few people want or which do not make a big
+    difference.
+
+wish
+    Something that is desirable to have but that there is no urgency at
+    all to implement, e.g. something completely cosmetic like a website
+    restyle or a personalized doxy template or the FFmpeg logo.
+    This priority is not valid for bugs.
+
+
+Status:
+-------
+new
+    initial state
+
+open
+    intermediate states
+
+closed
+    final state
+
+
+Analyzed flag:
+--------------
+Bugs which have been analyzed and where it is understood what causes them
+and which exact chain of events triggers them. This analysis should be
+available as a message in the bug report.
+Note, do not change the status to analyzed without also providing a clear
+and understandable analysis.
+This state implicates that the bug either has been reproduced or that
+reproduction is not needed as the bug is already understood.
+
+
+Type/Status/Substatus:
+----------
+*/new/new
+    Initial state of new bugs, patches and feature requests submitted by
+    users.
+
+*/open/open
+    Issues which have been briefly looked at and which did not look outright
+    invalid.
+    This implicates that no real more detailed state applies yet. Conversely,
+    the more detailed states below implicate that the issue has been briefly
+    looked at.
+
+*/closed/duplicate
+    Bugs, patches or feature requests which are duplicates.
+    Note that patches dealing with the same thing in a different way are not
+    duplicates.
+    Note, if you mark something as duplicate, do not forget setting the
+    superseder so bug reports are properly linked.
+
+*/closed/invalid
+    Bugs caused by user errors, random ineligible or otherwise nonsense stuff.
+
+*/closed/needs_more_info
+    Issues for which some information has been requested by the developers,
+    but which has not been provided by anyone within reasonable time.
+
+
+bug/closed/fixed
+    Bugs which have to the best of our knowledge been fixed.
+
+bug/closed/wont_fix
+    Bugs which we will not fix. Possible reasons include legality, high
+    complexity for the sake of supporting obscure corner cases, speed loss
+    for similarly esoteric purposes, et cetera.
+    This also means that we would reject a patch.
+    If we are just too lazy to fix a bug then the correct state is open
+    and unassigned. Closed means that the case is closed which is not
+    the case if we are just waiting for a patch.
+
+bug/closed/works_for_me
+    Bugs for which sufficient information was provided to reproduce but
+    reproduction failed - that is the code seems to work correctly to the
+    best of our knowledge.
+
+patch/open/approved
+    Patches which have been reviewed and approved by a developer.
+    Such patches can be applied anytime by any other developer after some
+    reasonable testing (compile + regression tests + does the patch do
+    what the author claimed).
+
+patch/open/needs_changes
+    Patches which have been reviewed and need changes to be accepted.
+
+patch/closed/applied
+    Patches which have been applied.
+
+patch/closed/rejected
+    Patches which have been rejected.
+
+feature_request/closed/implemented
+    Feature requests which have been implemented.
+
+feature_request/closed/wont_implement
+    Feature requests which will not be implemented. The reasons here could
+    be legal, philosophical or others.
+
+Note, please do not use type-status-substatus combinations other than the
+above without asking on ffmpeg-dev first!
+
+Note2, if you provide the requested info do not forget to remove the
+needs_more_info substatus.
+
+Component:
+----------
+
+avcodec
+    issues in libavcodec/*
+
+avformat
+    issues in libavformat/*
+
+avutil
+    issues in libavutil/*
+
+regression test
+    issues in tests/*
+
+ffmpeg
+    issues in or related to ffmpeg.c
+
+ffplay
+    issues in or related to ffplay.c
+
+ffprobe
+    issues in or related to ffprobe.c
+
+ffserver
+    issues in or related to ffserver.c
+
+build system
+    issues in or related to configure/Makefile
+
+regression
+    bugs which were not present in a past revision
+
+trac
+    issues related to our issue tracker
diff --git a/doc/libavfilter.texi b/doc/libavfilter.texi
deleted file mode 100644
index b452294..0000000
--- a/doc/libavfilter.texi
+++ /dev/null
@@ -1,92 +0,0 @@
-\input texinfo @c -*- texinfo -*-
-
-@settitle Libavfilter Documentation
-@titlepage
-@center @titlefont{Libavfilter Documentation}
-@end titlepage
-
-@top
-
-@contents
-
-@chapter Introduction
-
-Libavfilter is the filtering API of Libav. It is the substitute of the
-now deprecated 'vhooks' and started as a Google Summer of Code project.
-
-But note that there may still be serious bugs in the code and its API
-and ABI should not be considered stable yet!
-
-@chapter Tutorial
-
-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 --------+
-@end example
-
-splits the stream in two streams, sends one stream through the crop filter
-and the vflip filter before merging it back with the other stream by
-overlaying it on top. You can use the following command to achieve this:
-
-@example
-./avconv -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
-@end example
-
-The result will be that in output the top half of the video is mirrored
-onto the bottom half.
-
-Video filters are loaded using the @var{-vf} option passed to
-avconv or to avplay. 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 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 magic
-labels @var{[in]} and @var{[out]} are the points where video is input
-and output.
-
-Some filters take in input a list of parameters: they are specified
-after the filter name and an equal sign, and are separated each other
-by a semicolon.
-
-There exist so-called @var{source filters} that do not have a video
-input, and we expect in the future some @var{sink filters} that will
-not have video output.
-
-@chapter graph2dot
-
-The @file{graph2dot} program included in the Libav @file{tools}
-directory can be used to parse a filter graph description and issue a
-corresponding textual representation in the dot language.
-
-Invoke the command:
-@example
-graph2dot -h
-@end example
-
-to see how to use @file{graph2dot}.
-
-You can then pass the dot description to the @file{dot} program (from
-the graphviz suite of programs) and obtain a graphical representation
-of the filter graph.
-
-For example the sequence of commands:
-@example
-echo @var{GRAPH_DESCRIPTION} | \
-tools/graph2dot -o graph.tmp && \
-dot -Tpng graph.tmp -o graph.png && \
-display graph.png
-@end example
-
-can be used to create and display an image representing the graph
-described by the @var{GRAPH_DESCRIPTION} string.
-
-@include filters.texi
-
-@bye
diff --git a/doc/metadata.texi b/doc/metadata.texi
index cfaf491..2a28575 100644
--- a/doc/metadata.texi
+++ b/doc/metadata.texi
@@ -1,7 +1,7 @@
 @chapter Metadata
 @c man begin METADATA
 
-Libav is able to dump metadata from media files into a simple UTF-8-encoded
+FFmpeg is able to dump metadata from media files into a simple UTF-8-encoded
 INI-like text file and then load it back using the metadata muxer/demuxer.
 
 The file format is as follows:
@@ -53,7 +53,7 @@
 ;FFMETADATA1
 title=bike\\shed
 ;this is a comment
-artist=Libav troll team
+artist=FFmpeg troll team
 
 [CHAPTER]
 TIMEBASE=1/1000
diff --git a/doc/mips.txt b/doc/mips.txt
new file mode 100644
index 0000000..6fa6fb4
--- /dev/null
+++ b/doc/mips.txt
@@ -0,0 +1,65 @@
+MIPS optimizations info
+===============================================
+
+MIPS optimizations of codecs are targeting MIPS 74k family of
+CPUs. Some of these optimizations are relying more on properties of
+this architecture and some are relying less (and can be used on most
+MIPS architectures without degradation in performance).
+
+Along with FFMPEG copyright notice, there is MIPS copyright notice in
+all the files that are created by people from MIPS Technologies.
+
+Example of copyright notice:
+===============================================
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Author Name (author_name@@mips.com)
+ */
+
+Files that have MIPS copyright notice in them:
+===============================================
+* libavutil/mips/
+      libm_mips.h
+* libavcodec/mips/
+      acelp_filters_mips.c
+      acelp_vectors_mips.c
+      amrwbdec_mips.c
+      amrwbdec_mips.h
+      celp_filters_mips.c
+      celp_math_mips.c
+      compute_antialias_fixed.h
+      compute_antialias_float.h
+      lsp_mips.h
+      dsputil_mips.c
+      fft_mips.c
+      fft_table.h
+      fft_init_table.c
+      fmtconvert_mips.c
+      mpegaudiodsp_mips_fixed.c
+      mpegaudiodsp_mips_float.c
diff --git a/doc/multithreading.txt b/doc/multithreading.txt
index b72bc16..a106842 100644
--- a/doc/multithreading.txt
+++ b/doc/multithreading.txt
@@ -1,7 +1,7 @@
-Libav multithreading methods
+FFmpeg multithreading methods
 ==============================================
 
-Libav provides two methods for multithreading codecs.
+FFmpeg provides two methods for multithreading codecs.
 
 Slice threading decodes multiple parts of a frame at the same time, using
 AVCodecContext execute() and execute2().
diff --git a/doc/muxers.texi b/doc/muxers.texi
index 4bb6d56..83c21db 100644
--- a/doc/muxers.texi
+++ b/doc/muxers.texi
@@ -1,10 +1,10 @@
 @chapter Muxers
 @c man begin MUXERS
 
-Muxers are configured elements in Libav which allow writing
+Muxers are configured elements in FFmpeg which allow writing
 multimedia streams to a particular type of file.
 
-When you configure your Libav build, all the supported muxers
+When you configure your FFmpeg build, all the supported muxers
 are enabled by default. You can list all available muxers using the
 configure option @code{--list-muxers}.
 
@@ -35,20 +35,20 @@
 For example to compute the CRC of the input, and store it in the file
 @file{out.crc}:
 @example
-avconv -i INPUT -f crc out.crc
+ffmpeg -i INPUT -f crc out.crc
 @end example
 
 You can print the CRC to stdout with the command:
 @example
-avconv -i INPUT -f crc -
+ffmpeg -i INPUT -f crc -
 @end example
 
-You can select the output format of each frame with @command{avconv} by
+You can select the output format of each frame with @command{ffmpeg} by
 specifying the audio and video codec and format. For example to
 compute the CRC of the input audio converted to PCM unsigned 8-bit
 and the input video converted to MPEG-2 video, use the command:
 @example
-avconv -i INPUT -c:a pcm_u8 -c:v mpeg2video -f crc -
+ffmpeg -i INPUT -c:a pcm_u8 -c:v mpeg2video -f crc -
 @end example
 
 See also the @ref{framecrc} muxer.
@@ -56,40 +56,112 @@
 @anchor{framecrc}
 @section framecrc
 
-Per-frame CRC (Cyclic Redundancy Check) testing format.
+Per-packet CRC (Cyclic Redundancy Check) testing format.
 
-This muxer computes and prints the Adler-32 CRC for each decoded audio
-and video frame. By default audio frames are converted to signed
+This muxer computes and prints the Adler-32 CRC for each audio
+and video packet. By default audio frames are converted to signed
 16-bit raw audio and video frames to raw video before computing the
 CRC.
 
 The output of the muxer consists of a line for each audio and video
-frame of the form: @var{stream_index}, @var{frame_dts},
-@var{frame_size}, 0x@var{CRC}, where @var{CRC} is a hexadecimal
-number 0-padded to 8 digits containing the CRC of the decoded frame.
-
-For example to compute the CRC of each decoded frame in the input, and
-store it in the file @file{out.crc}:
+packet of the form:
 @example
-avconv -i INPUT -f framecrc out.crc
+@var{stream_index}, @var{packet_dts}, @var{packet_pts}, @var{packet_duration}, @var{packet_size}, 0x@var{CRC}
 @end example
 
-You can print the CRC of each decoded frame to stdout with the command:
+@var{CRC} is a hexadecimal number 0-padded to 8 digits containing the
+CRC of the packet.
+
+For example to compute the CRC of the audio and video frames in
+@file{INPUT}, converted to raw audio and video packets, and store it
+in the file @file{out.crc}:
 @example
-avconv -i INPUT -f framecrc -
+ffmpeg -i INPUT -f framecrc out.crc
 @end example
 
-You can select the output format of each frame with @command{avconv} by
-specifying the audio and video codec and format. For example, to
+To print the information to stdout, use the command:
+@example
+ffmpeg -i INPUT -f framecrc -
+@end example
+
+With @command{ffmpeg}, you can select the output format to which the
+audio and video frames are encoded before computing the CRC for each
+packet by specifying the audio and video codec. For example, to
 compute the CRC of each decoded input audio frame converted to PCM
 unsigned 8-bit and of each decoded input video frame converted to
 MPEG-2 video, use the command:
 @example
-avconv -i INPUT -c:a pcm_u8 -c:v mpeg2video -f framecrc -
+ffmpeg -i INPUT -c:a pcm_u8 -c:v mpeg2video -f framecrc -
 @end example
 
 See also the @ref{crc} muxer.
 
+@anchor{framemd5}
+@section framemd5
+
+Per-packet MD5 testing format.
+
+This muxer computes and prints the MD5 hash for each audio
+and video packet. By default audio frames are converted to signed
+16-bit raw audio and video frames to raw video before computing the
+hash.
+
+The output of the muxer consists of a line for each audio and video
+packet of the form:
+@example
+@var{stream_index}, @var{packet_dts}, @var{packet_pts}, @var{packet_duration}, @var{packet_size}, @var{MD5}
+@end example
+
+@var{MD5} is a hexadecimal number representing the computed MD5 hash
+for the packet.
+
+For example to compute the MD5 of the audio and video frames in
+@file{INPUT}, converted to raw audio and video packets, and store it
+in the file @file{out.md5}:
+@example
+ffmpeg -i INPUT -f framemd5 out.md5
+@end example
+
+To print the information to stdout, use the command:
+@example
+ffmpeg -i INPUT -f framemd5 -
+@end example
+
+See also the @ref{md5} muxer.
+
+@anchor{ico}
+@section ico
+
+ICO file muxer.
+
+Microsoft's icon file format (ICO) has some strict limitations that should be noted:
+
+@itemize
+@item
+Size cannot exceed 256 pixels in any dimension
+
+@item
+Only BMP and PNG images can be stored
+
+@item
+If a BMP image is used, it must be one of the following pixel formats:
+@example
+BMP Bit Depth      FFmpeg Pixel Format
+1bit               pal8
+4bit               pal8
+8bit               pal8
+16bit              rgb555le
+24bit              bgr24
+32bit              bgra
+@end example
+
+@item
+If a BMP image is used, it must use the BITMAPINFOHEADER DIB header
+
+@item
+If a PNG image is used, it must use the rgba pixel format
+@end itemize
+
 @anchor{image2}
 @section image2
 
@@ -120,28 +192,61 @@
 form @file{img%-1.jpg}, @file{img%-2.jpg}, ..., @file{img%-10.jpg},
 etc.
 
-The following example shows how to use @command{avconv} for creating a
+The following example shows how to use @command{ffmpeg} for creating a
 sequence of files @file{img-001.jpeg}, @file{img-002.jpeg}, ...,
 taking one image every second from the input video:
 @example
-avconv -i in.avi -vsync 1 -r 1 -f image2 'img-%03d.jpeg'
+ffmpeg -i in.avi -vsync 1 -r 1 -f image2 'img-%03d.jpeg'
 @end example
 
-Note that with @command{avconv}, if the format is not specified with the
+Note that with @command{ffmpeg}, if the format is not specified with the
 @code{-f} option and the output filename specifies an image file
 format, the image2 muxer is automatically selected, so the previous
 command can be written as:
 @example
-avconv -i in.avi -vsync 1 -r 1 'img-%03d.jpeg'
+ffmpeg -i in.avi -vsync 1 -r 1 'img-%03d.jpeg'
 @end example
 
 Note also that the pattern must not necessarily contain "%d" or
 "%0@var{N}d", for example to create a single image file
 @file{img.jpeg} from the input video you can employ the command:
 @example
-avconv -i in.avi -f image2 -frames:v 1 img.jpeg
+ffmpeg -i in.avi -f image2 -frames:v 1 img.jpeg
 @end example
 
+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,
+specify the name of the '.Y' file. The muxer will automatically open the
+'.U' and '.V' files as required.
+
+@anchor{md5}
+@section md5
+
+MD5 testing format.
+
+This muxer computes and prints the MD5 hash of all the input audio
+and video frames. By default audio frames are converted to signed
+16-bit raw audio and video frames to raw video before computing the
+hash.
+
+The output of the muxer consists of a single line of the form:
+MD5=@var{MD5}, where @var{MD5} is a hexadecimal number representing
+the computed MD5 hash.
+
+For example to compute the MD5 hash of the input converted to raw
+audio and video, and store it in the file @file{out.md5}:
+@example
+ffmpeg -i INPUT -f md5 out.md5
+@end example
+
+You can print the MD5 to stdout with the command:
+@example
+ffmpeg -i INPUT -f md5 -
+@end example
+
+See also the @ref{framemd5} muxer.
+
 @section MOV/MP4/ISMV
 
 The mov/mp4/ismv muxer supports fragmentation. Normally, a MOV/MP4
@@ -161,6 +266,9 @@
 how to cut the file into fragments:
 
 @table @option
+@item -moov_size @var{bytes}
+Reserves space for the moov atom at the beginning of the file instead of placing the
+moov atom at the end. If the space reserved is insufficient, muxing will fail.
 @item -movflags frag_keyframe
 Start a new fragment at each video keyframe.
 @item -frag_duration @var{duration}
@@ -171,7 +279,7 @@
 Allow the caller to manually choose when to cut fragments, by
 calling @code{av_write_frame(ctx, NULL)} to write a fragment with
 the packets written so far. (This is only useful with other
-applications integrating libavformat, not from @command{avconv}.)
+applications integrating libavformat, not from @command{ffmpeg}.)
 @item -min_frag_duration @var{duration}
 Don't create fragments that are shorter than @var{duration} microseconds long.
 @end table
@@ -207,7 +315,7 @@
 Smooth Streaming content can be pushed in real time to a publishing
 point on IIS with this muxer. Example:
 @example
-avconv -re @var{<normal input/transcoding options>} -movflags isml+frag_keyframe -f ismv http://server/publishingpoint.isml/Streams(Encoder1)
+ffmpeg -re @var{<normal input/transcoding options>} -movflags isml+frag_keyframe -f ismv http://server/publishingpoint.isml/Streams(Encoder1)
 @end example
 
 @section mpegts
@@ -236,11 +344,11 @@
 
 The recognized metadata settings in mpegts muxer are @code{service_provider}
 and @code{service_name}. If they are not set the default for
-@code{service_provider} is "Libav" and the default for
+@code{service_provider} is "FFmpeg" and the default for
 @code{service_name} is "Service01".
 
 @example
-avconv -i file.mpg -c copy \
+ffmpeg -i file.mpg -c copy \
      -mpegts_original_network_id 0x1122 \
      -mpegts_transport_stream_id 0x3344 \
      -mpegts_service_id 0x5566 \
@@ -258,19 +366,19 @@
 This muxer does not generate any output file, it is mainly useful for
 testing or benchmarking purposes.
 
-For example to benchmark decoding with @command{avconv} you can use the
+For example to benchmark decoding with @command{ffmpeg} you can use the
 command:
 @example
-avconv -benchmark -i INPUT -f null out.null
+ffmpeg -benchmark -i INPUT -f null out.null
 @end example
 
 Note that the above command does not read or write the @file{out.null}
-file, but specifying the output file is required by the @command{avconv}
+file, but specifying the output file is required by the @command{ffmpeg}
 syntax.
 
 Alternatively you can write the command as:
 @example
-avconv -benchmark -i INPUT -f null -
+ffmpeg -benchmark -i INPUT -f null -
 @end example
 
 @section matroska
@@ -295,7 +403,7 @@
 
 @table @option
 
-@item STEREO_MODE=@var{mode}
+@item stereo_mode=@var{mode}
 Stereo 3D video layout of two views in a single video track
 @table @option
 @item mono
@@ -333,10 +441,10 @@
 
 For example a 3D WebM clip can be created using the following command line:
 @example
-avconv -i sample_left_right_clip.mpg -an -c:v libvpx -metadata STEREO_MODE=left_right -y stereo_clip.webm
+ffmpeg -i sample_left_right_clip.mpg -an -c:v libvpx -metadata stereo_mode=left_right -y stereo_clip.webm
 @end example
 
-@section segment
+@section segment, stream_segment, ssegment
 
 Basic stream segmenter.
 
@@ -344,30 +452,166 @@
 fixed duration. Output filename pattern can be set in a fashion similar to
 @ref{image2}.
 
+@code{stream_segment} is a variant of the muxer used to write to
+streaming output formats, i.e. which do not require global headers,
+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.
+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
+segment with the key frame found next after the specified start
+time.
+
 The segment muxer works best with a single constant frame rate video.
 
-Optionally it can generate a flat list of the created segments, one segment
-per line.
+Optionally it can generate a list of the created segments, by setting
+the option @var{segment_list}. The list type is specified by the
+@var{segment_list_type} option.
+
+The segment muxer supports the following options:
 
 @table @option
 @item segment_format @var{format}
 Override the inner container format, by default it is guessed by the filename
 extension.
-@item segment_time @var{t}
-Set segment duration to @var{t} seconds.
 @item segment_list @var{name}
-Generate also a listfile named @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.
+
+It currently supports the following flags:
+@table @var
+@item cache
+Allow caching (only affects M3U8 list files).
+
+@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.
+Overwrite the listfile once it reaches @var{size} entries. If 0
+the listfile is never overwritten. Default value is 0.
+@item segment_list type @var{type}
+Specify the format for the segment list file.
+
+The following values are recognized:
+@table @option
+@item flat
+Generate a flat list for the created segments, one segment per line.
+
+@item csv, ext
+Generate a list for the created segments, one segment per line,
+each line matching the format (comma-separated values):
+@example
+@var{segment_filename},@var{segment_start_time},@var{segment_end_time}
+@end example
+
+@var{segment_filename} is the name of the output file generated by the
+muxer according to the provided pattern. CSV escaping (according to
+RFC4180) is applied if required.
+
+@var{segment_start_time} and @var{segment_end_time} specify
+the segment start and end time expressed in seconds.
+
+A list file with the suffix @code{".csv"} or @code{".ext"} will
+auto-select this format.
+
+@code{ext} is deprecated in favor or @code{csv}.
+
+@item m3u8
+Generate an extended M3U8 file, version 4, compliant with
+@url{http://tools.ietf.org/id/draft-pantos-http-live-streaming-08.txt}.
+
+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".
+@item segment_time_delta @var{delta}
+Specify the accuracy time when selecting the start time for a
+segment. Default value is "0".
+
+When delta is specified a key-frame will start a new segment if its
+PTS satisfies the relation:
+@example
+PTS >= start_time - time_delta
+@end example
+
+This option is useful when splitting video content, which is always
+split at GOP boundaries, in case a key frame is found just before the
+specified split time.
+
+In particular may be used in combination with the @file{ffmpeg} option
+@var{force_key_frames}. The key frame times specified by
+@var{force_key_frames} may not be set accurately because of rounding
+issues, with the consequence that a key frame time may result set just
+before the specified time. For constant frame rate videos a value of
+1/2*@var{frame_rate} should address the worst case mismatch between
+the specified time and the time set by @var{force_key_frames}.
+
+@item segment_times @var{times}
+Specify a list of split points. @var{times} contains a list of comma
+separated duration specifications, in increasing order.
 @item segment_wrap @var{limit}
 Wrap around segment index once it reaches @var{limit}.
 @end table
 
+Some examples follow.
+
+@itemize
+@item
+To remux the content of file @file{in.mkv} to a list of segments
+@file{out-000.nut}, @file{out-001.nut}, etc., and write the list of
+generated segments to @file{out.list}:
 @example
-avconv -i in.mkv -c copy -map 0 -f segment -list out.list out%03d.nut
+ffmpeg -i in.mkv -codec copy -map 0 -f segment -segment_list out.list out%03d.nut
 @end example
 
+@item
+As the example above, but segment the input file according to the split
+points specified by the @var{segment_times} option:
+@example
+ffmpeg -i in.mkv -codec copy -map 0 -f segment -segment_list out.csv -segment_times 1,2,3,5,8,13,21 out%03d.nut
+@end example
+
+@item
+As the example above, but use the @code{ffmpeg} @var{force_key_frames}
+option to force key frames in the input at the specified location, together
+with the segment option @var{segment_time_delta} to account for
+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 \
+-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
+To convert the @file{in.mkv} to TS segments using the @code{libx264}
+and @code{libfaac} encoders:
+@example
+ffmpeg -i in.mkv -map 0 -codec:v libx264 -codec:a libfaac -f ssegment -segment_list out.list out%03d.ts
+@end example
+
+@item
+Segment the input file, and create an M3U8 live playlist (can be used
+as live HLS source):
+@example
+ffmpeg -re -i in.mkv -codec copy -map 0 -f segment -segment_list playlist.m3u8 \
+-segment_list_flags +live -segment_time 10 out%03d.mkv
+@end example
+@end itemize
+
 @section mp3
 
 The MP3 muxer writes a raw MP3 stream with an ID3v2 header at the beginning and
@@ -394,12 +638,12 @@
 
 Write an mp3 with an ID3v2.3 header and an ID3v1 footer:
 @example
-avconv -i INPUT -id3v2_version 3 -write_id3v1 1 out.mp3
+ffmpeg -i INPUT -id3v2_version 3 -write_id3v1 1 out.mp3
 @end example
 
 Attach a picture to an mp3:
 @example
-avconv -i input.mp3 -i cover.png -c copy -metadata:s:v title="Album cover"
+ffmpeg -i input.mp3 -i cover.png -c copy -metadata:s:v title="Album cover"
 -metadata:s:v comment="Cover (Front)" out.mp3
 @end example
 
diff --git a/doc/optimization.txt b/doc/optimization.txt
index 78e0077..b027efe 100644
--- a/doc/optimization.txt
+++ b/doc/optimization.txt
@@ -17,15 +17,15 @@
 As many functions tend to be a bit difficult to understand because
 of optimizations, it can be hard to optimize them further, or write
 architecture-specific versions. It is recommended to look at older
-revisions of the interesting files (web frontends for the various Libav
-branches are listed at http://libav.org/download.html).
+revisions of the interesting files (web frontends for the various FFmpeg
+branches are listed at http://ffmpeg.org/download.html).
 Alternatively, look into the other architecture-specific versions in
 the x86/, ppc/, alpha/ subdirectories. Even if you don't exactly
 comprehend the instructions, it could help understanding the functions
 and how they can be optimized.
 
 NOTE: If you still don't understand some function, ask at our mailing list!!!
-(https://lists.libav.org/mailman/listinfo/libav-devel)
+(http://lists.ffmpeg.org/mailman/listinfo/ffmpeg-devel)
 
 
 When is an optimization justified?
@@ -201,7 +201,7 @@
 ---------------------------
 Both inline asm (__asm__("..") in a .c file, handled by a compiler such as gcc)
 and external asm (.s or .asm files, handled by an assembler such as yasm/nasm)
-are accepted in Libav. Which one to use differs per specific case.
+are accepted in FFmpeg. Which one to use differs per specific case.
 
 - if your code is intended to be inlined in a C function, inline asm is always
    better, because external asm cannot be inlined
diff --git a/doc/outdevs.texi b/doc/outdevs.texi
index 938909c..371d63a 100644
--- a/doc/outdevs.texi
+++ b/doc/outdevs.texi
@@ -1,10 +1,10 @@
 @chapter Output Devices
 @c man begin OUTPUT DEVICES
 
-Output devices are configured elements in Libav which allow to write
+Output devices are configured elements in FFmpeg which allow to write
 multimedia data to an output device attached to your system.
 
-When you configure your Libav build, all the supported output devices
+When you configure your FFmpeg build, all the supported output devices
 are enabled by default. You can list all available ones using the
 configure option "--list-outdevs".
 
@@ -22,10 +22,133 @@
 
 ALSA (Advanced Linux Sound Architecture) output device.
 
+@section caca
+
+CACA output device.
+
+This output devices allows to show a video stream in CACA window.
+Only one CACA window is allowed per application, so you can
+have only one instance of this output device in an application.
+
+To enable this output device you need to configure FFmpeg with
+@code{--enable-libcaca}.
+libcaca is a graphics library that outputs text instead of pixels.
+
+For more information about libcaca, check:
+@url{http://caca.zoy.org/wiki/libcaca}
+
+@subsection Options
+
+@table @option
+
+@item window_title
+Set the CACA window title, if not specified default to the filename
+specified for the output device.
+
+@item window_size
+Set the CACA window size, can be a string of the form
+@var{width}x@var{height} or a video size abbreviation.
+If not specified it defaults to the size of the input video.
+
+@item driver
+Set display driver.
+
+@item algorithm
+Set dithering algorithm. Dithering is necessary
+because the picture being rendered has usually far more colours than
+the available palette.
+The accepted values are listed with @code{-list_dither algorithms}.
+
+@item antialias
+Set antialias method. Antialiasing smoothens the rendered
+image and avoids the commonly seen staircase effect.
+The accepted values are listed with @code{-list_dither antialiases}.
+
+@item charset
+Set which characters are going to be used when rendering text.
+The accepted values are listed with @code{-list_dither charsets}.
+
+@item color
+Set color to be used when rendering text.
+The accepted values are listed with @code{-list_dither colors}.
+
+@item list_drivers
+If set to @option{true}, print a list of available drivers and exit.
+
+@item list_dither
+List available dither options related to the argument.
+The argument must be one of @code{algorithms}, @code{antialiases},
+@code{charsets}, @code{colors}.
+@end table
+
+@subsection Examples
+
+@itemize
+@item
+The following command shows the @command{ffmpeg} output is an
+CACA window, forcing its size to 80x25:
+@example
+ffmpeg -i INPUT -vcodec rawvideo -pix_fmt rgb24 -window_size 80x25 -f caca -
+@end example
+
+@item
+Show the list of available drivers and exit:
+@example
+ffmpeg -i INPUT -pix_fmt rgb24 -f caca -list_drivers true -
+@end example
+
+@item
+Show the list of available dither colors and exit:
+@example
+ffmpeg -i INPUT -pix_fmt rgb24 -f caca -list_dither colors -
+@end example
+@end itemize
+
 @section oss
 
 OSS (Open Sound System) output device.
 
+@section sdl
+
+SDL (Simple DirectMedia Layer) output device.
+
+This output devices allows to show a video stream in an SDL
+window. Only one SDL window is allowed per application, so you can
+have only one instance of this output device in an application.
+
+To enable this output device you need libsdl installed on your system
+when configuring your build.
+
+For more information about SDL, check:
+@url{http://www.libsdl.org/}
+
+@subsection Options
+
+@table @option
+
+@item window_title
+Set the SDL window title, if not specified default to the filename
+specified for the output device.
+
+@item icon_title
+Set the name of the iconified SDL window, if not specified it is set
+to the same value of @var{window_title}.
+
+@item window_size
+Set the SDL window size, can be a string of the form
+@var{width}x@var{height} or a video size abbreviation.
+If not specified it defaults to the size of the input video,
+downscaled according to the aspect ratio.
+@end table
+
+@subsection Examples
+
+The following command shows the @command{ffmpeg} output is an
+SDL window, forcing its size to the qcif format:
+@example
+ffmpeg -i INPUT -vcodec rawvideo -pix_fmt yuv420p -window_size qcif -f sdl "SDL output"
+@end example
+
 @section sndio
 
 sndio audio output device.
diff --git a/doc/platform.texi b/doc/platform.texi
index 3bb9f79..6047e71 100644
--- a/doc/platform.texi
+++ b/doc/platform.texi
@@ -11,7 +11,7 @@
 
 @chapter Unix-like
 
-Some parts of Libav cannot be built with version 2.15 of the GNU
+Some parts of FFmpeg cannot be built with version 2.15 of the GNU
 assembler which is still provided by a few AMD64 distributions. To
 make sure your compiler really uses the required version of gas
 after a binutils upgrade, run:
@@ -26,12 +26,12 @@
 
 @section BSD
 
-BSD make will not build Libav, you need to install and use GNU Make
+BSD make will not build FFmpeg, you need to install and use GNU Make
 (@command{gmake}).
 
 @section (Open)Solaris
 
-GNU Make is required to build Libav, so you have to invoke (@command{gmake}),
+GNU Make is required to build FFmpeg, so you have to invoke (@command{gmake}),
 standard Solaris Make will not work. When building with a non-c99 front-end
 (gcc, generic suncc) add either @code{--extra-libs=/usr/lib/values-xpg6.o}
 or @code{--extra-libs=/usr/lib/64/values-xpg6.o} to the configure options
@@ -45,20 +45,21 @@
 @end example
 
 @anchor{Darwin}
-@section Darwin (OS X, iPhone)
+@section Darwin (Mac OS X, iPhone)
 
 The toolchain provided with Xcode is sufficient to build the basic
 unacelerated code.
 
-OS X on PowerPC or ARM (iPhone) requires a preprocessor from
+Mac OS X on PowerPC or ARM (iPhone) requires a preprocessor from
 @url{http://github.com/yuvi/gas-preprocessor} to build the optimized
 assembler functions. Just download the Perl script and put it somewhere
-in your PATH, Libav's configure will pick it up automatically.
+in your PATH, FFmpeg's configure will pick it up automatically.
 
-OS X on AMD64 and x86 requires @command{yasm} to build most of the
-optimized assembler functions @url{http://mxcl.github.com/homebrew/, Homebrew},
-@url{http://www.gentoo.org/proj/en/gentoo-alt/prefix/bootstrap-macos.xml, Gentoo Prefix}
-or @url{http://www.macports.org, MacPorts} can easily provide it.
+Mac OS X on amd64 and x86 requires @command{yasm} to build most of the
+optimized assembler functions. @uref{http://www.finkproject.org/, Fink},
+@uref{http://www.gentoo.org/proj/en/gentoo-alt/prefix/bootstrap-macos.xml, Gentoo Prefix},
+@uref{http://mxcl.github.com/homebrew/, Homebrew}
+or @uref{http://www.macports.org, MacPorts} can easily provide it.
 
 
 @chapter DOS
@@ -69,15 +70,19 @@
 
 @chapter OS/2
 
-For information about compiling Libav on OS/2 see
+For information about compiling FFmpeg on OS/2 see
 @url{http://www.edm2.com/index.php/FFmpeg}.
 
 
 @chapter Windows
 
+To get help and instructions for building FFmpeg under Windows, check out
+the FFmpeg Windows Help Forum at
+@url{http://ffmpeg.arrozcru.org/}.
+
 @section Native Windows compilation using MinGW or MinGW-w64
 
-Libav can be built to run natively on Windows using the MinGW or MinGW-w64
+FFmpeg can be built to run natively on Windows using the MinGW or MinGW-w64
 toolchains. Install the latest versions of MSYS and MinGW or MinGW-w64 from
 @url{http://www.mingw.org/} or @url{http://mingw-w64.sourceforge.net/}.
 You can find detailed installation instructions in the download section and
@@ -93,17 +98,18 @@
 noticeable when running make for a second time (for example during
 @code{make install}).
 
-@item In order to compile AVplay, you must have the MinGW development library
+@item In order to compile FFplay, you must have the MinGW development library
 of @uref{http://www.libsdl.org/, SDL} and @code{pkg-config} installed.
 
-@item By using @code{./configure --enable-shared} when configuring Libav,
-you can build all libraries as DLLs.
+@item By using @code{./configure --enable-shared} when configuring FFmpeg,
+you can build the FFmpeg libraries (e.g. libavutil, libavcodec,
+libavformat) as DLLs.
 
 @end itemize
 
 @section Microsoft Visual C++
 
-Libav can be built with MSVC using a C99-to-C89 conversion utility and
+FFmpeg can be built with MSVC using a C99-to-C89 conversion utility and
 wrapper. At this time, only static builds are supported.
 
 You will need the following prerequisites:
@@ -154,26 +160,26 @@
 @enumerate
 @item Grab the @uref{http://zlib.net/, zlib sources}.
 @item Edit @code{win32/Makefile.msc} so that it uses -MT instead of -MD, since
-this is how Libav is built as well.
+this is how FFmpeg is built as well.
 @item Edit @code{zconf.h} and remove its inclusion of @code{unistd.h}. This gets
-erroneously included when building Libav.
+erroneously included when building FFmpeg.
 @item Run @code{nmake -f win32/Makefile.msc}.
 @item Move @code{zlib.lib}, @code{zconf.h}, and @code{zlib.h} to somewhere MSVC
 can see.
 @end enumerate
 
-@item Libav has been tested with Visual Studio 2010 and 2012, Pro and Express.
+@item FFmpeg has been tested with Visual Studio 2010 and 2012, Pro and Express.
 Anything else is not officially supported.
 
 @end itemize
 
-@subsection Linking to Libav with Microsoft Visual C++
+@subsection Linking to FFmpeg with Microsoft Visual C++
 
 If you plan to link with MSVC-built static libraries, you will need
 to make sure you have @code{Runtime Library} set to
 @code{Multi-threaded (/MT)} in your project's settings.
 
-Libav headers do not declare global data for Windows DLLs through the usual
+FFmpeg headers do not declare global data for Windows DLLs through the usual
 dllexport/dllimport interface. Such data will be exported properly while
 building, but to use them in your MSVC code you will have to edit the
 appropriate headers and mark the data as dllimport. For example, in
@@ -228,14 +234,14 @@
 You must use the MinGW cross compilation tools available at
 @url{http://www.mingw.org/}.
 
-Then configure Libav with the following options:
+Then configure FFmpeg with the following options:
 @example
 ./configure --target-os=mingw32 --cross-prefix=i386-mingw32msvc-
 @end example
 (you can change the cross-prefix according to the prefix chosen for the
 MinGW tools).
 
-Then you can easily test Libav with @uref{http://www.winehq.com/, Wine}.
+Then you can easily test FFmpeg with @uref{http://www.winehq.com/, Wine}.
 
 @section Compilation under Cygwin
 
@@ -253,7 +259,7 @@
 bc, diffutils
 @end example
 
-If you want to build Libav with additional libraries, download Cygwin
+If you want to build FFmpeg with additional libraries, download Cygwin
 "Devel" packages for Ogg and Vorbis from any Cygwin packages repository:
 @example
 libogg-devel, libvorbis-devel
@@ -263,7 +269,7 @@
 @uref{http://sourceware.org/cygwinports/, Cygwin Ports}:
 
 @example
-yasm, libSDL-devel, libfaac-devel, libgsm-devel, libmp3lame-devel,
+yasm, libSDL-devel, libfaac-devel, libaacplus-devel, libgsm-devel, libmp3lame-devel,
 libschroedinger1.0-devel, speex-devel, libtheora-devel, libxvidcore-devel
 @end example
 
diff --git a/doc/print_options.c b/doc/print_options.c
index 4283e6a..339b942 100644
--- a/doc/print_options.c
+++ b/doc/print_options.c
@@ -112,6 +112,8 @@
     if (argc < 2)
         print_usage();
 
+    printf("@c DO NOT EDIT THIS FILE!\n"
+           "@c It was generated by print_options.\n\n");
     if (!strcmp(argv[1], "format"))
         show_format_opts();
     else if (!strcmp(argv[1], "codec"))
diff --git a/doc/protocols.texi b/doc/protocols.texi
index 086a249..e790459 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -1,10 +1,10 @@
 @chapter Protocols
 @c man begin PROTOCOLS
 
-Protocols are configured elements in Libav which allow to access
+Protocols are configured elements in FFmpeg which allow to access
 resources which require the use of a particular protocol.
 
-When you configure your Libav build, all the supported protocols are
+When you configure your FFmpeg build, all the supported protocols are
 enabled by default. You can list all available ones using the
 configure option "--list-protocols".
 
@@ -19,6 +19,36 @@
 
 A description of the currently available protocols follows.
 
+@section bluray
+
+Read BluRay playlist.
+
+The accepted options are:
+@table @option
+
+@item angle
+BluRay angle
+
+@item chapter
+Start chapter (1...N)
+
+@item playlist
+Playlist to read (BDMV/PLAYLIST/?????.mpls)
+
+@end table
+
+Examples:
+
+Read longest playlist from BluRay mounted to /mnt/bluray:
+@example
+bluray:/mnt/bluray
+@end example
+
+Read angle 2 of playlist 4 from BluRay mounted to /mnt/bluray, start from chapter 2:
+@example
+-playlist 4 -angle 2 -chapter 2 bluray:/mnt/bluray
+@end example
+
 @section concat
 
 Physical concatenation protocol.
@@ -36,10 +66,10 @@
 protocol.
 
 For example to read a sequence of files @file{split1.mpeg},
-@file{split2.mpeg}, @file{split3.mpeg} with @command{avplay} use the
+@file{split2.mpeg}, @file{split3.mpeg} with @command{ffplay} use the
 command:
 @example
-avplay concat:split1.mpeg\|split2.mpeg\|split3.mpeg
+ffplay concat:split1.mpeg\|split2.mpeg\|split3.mpeg
 @end example
 
 Note that you may need to escape the character "|" which is special for
@@ -51,10 +81,10 @@
 
 Allow to read from or read to a file.
 
-For example to read from a file @file{input.mpeg} with @command{avconv}
+For example to read from a file @file{input.mpeg} with @command{ffmpeg}
 use the command:
 @example
-avconv -i file:input.mpeg output.mpeg
+ffmpeg -i file:input.mpeg output.mpeg
 @end example
 
 The ff* tools default to the file protocol, that is a resource
@@ -113,10 +143,10 @@
 Some examples follow.
 @example
 # Write the MD5 hash of the encoded AVI file to the file output.avi.md5.
-avconv -i input.flv -f avi -y md5:output.avi.md5
+ffmpeg -i input.flv -f avi -y md5:output.avi.md5
 
 # Write the MD5 hash of the encoded AVI file to stdout.
-avconv -i input.flv -f avi -y md5:
+ffmpeg -i input.flv -f avi -y md5:
 @end example
 
 Note that some formats (typically MOV) require the output protocol to
@@ -138,18 +168,18 @@
 is not specified, by default the stdout file descriptor will be used
 for writing, stdin for reading.
 
-For example to read from stdin with @command{avconv}:
+For example to read from stdin with @command{ffmpeg}:
 @example
-cat test.wav | avconv -i pipe:0
+cat test.wav | ffmpeg -i pipe:0
 # ...this is the same as...
-cat test.wav | avconv -i pipe:
+cat test.wav | ffmpeg -i pipe:
 @end example
 
-For writing to stdout with @command{avconv}:
+For writing to stdout with @command{ffmpeg}:
 @example
-avconv -i test.wav -f avi pipe:1 | cat > test.avi
+ffmpeg -i test.wav -f avi pipe:1 | cat > test.avi
 # ...this is the same as...
-avconv -i test.wav -f avi pipe: | cat > test.avi
+ffmpeg -i test.wav -f avi pipe: | cat > test.avi
 @end example
 
 Note that some formats (typically MOV), require the output protocol to
@@ -264,10 +294,10 @@
 
 @end table
 
-For example to read with @command{avplay} a multimedia resource named
+For example to read with @command{ffplay} a multimedia resource named
 "sample" from the application "vod" from an RTMP server "myserver":
 @example
-avplay rtmp://myserver/vod/sample
+ffplay rtmp://myserver/vod/sample
 @end example
 
 @section rtmpe
@@ -340,14 +370,14 @@
 See the librtmp manual page (man 3 librtmp) for more information.
 
 For example, to stream a file in real-time to an RTMP server using
-@command{avconv}:
+@command{ffmpeg}:
 @example
-avconv -re -i myfile -f flv rtmp://myserver/live/mystream
+ffmpeg -re -i myfile -f flv rtmp://myserver/live/mystream
 @end example
 
-To play the same stream using @command{avplay}:
+To play the same stream using @command{ffplay}:
 @example
-avplay "rtmp://myserver/live/mystream live=1"
+ffplay "rtmp://myserver/live/mystream live=1"
 @end example
 
 @section rtp
@@ -370,7 +400,7 @@
 rtsp://@var{hostname}[:@var{port}]/@var{path}
 @end example
 
-The following options (set on the @command{avconv}/@command{avplay} command
+The following options (set on the @command{ffmpeg}/@command{ffplay} command
 line, or set in code via @code{AVOption}s or in @code{avformat_open_input}),
 are supported:
 
@@ -411,7 +441,7 @@
 can be disabled by setting the maximum demuxing delay to zero (via
 the @code{max_delay} field of AVFormatContext).
 
-When watching multi-bitrate Real-RTSP streams with @command{avplay}, the
+When watching multi-bitrate Real-RTSP streams with @command{ffplay}, the
 streams to display can be chosen with @code{-vst} @var{n} and
 @code{-ast} @var{n} for video and audio respectively, and can be switched
 on the fly by pressing @code{v} and @code{a}.
@@ -421,25 +451,25 @@
 To watch a stream over UDP, with a max reordering delay of 0.5 seconds:
 
 @example
-avplay -max_delay 500000 -rtsp_transport udp rtsp://server/video.mp4
+ffplay -max_delay 500000 -rtsp_transport udp rtsp://server/video.mp4
 @end example
 
 To watch a stream tunneled over HTTP:
 
 @example
-avplay -rtsp_transport http rtsp://server/video.mp4
+ffplay -rtsp_transport http rtsp://server/video.mp4
 @end example
 
 To send a stream in realtime to a RTSP server, for others to watch:
 
 @example
-avconv -re -i @var{input} -f rtsp -muxdelay 0.1 rtsp://server/live.sdp
+ffmpeg -re -i @var{input} -f rtsp -muxdelay 0.1 rtsp://server/live.sdp
 @end example
 
 To receive a stream in realtime:
 
 @example
-avconv -rtsp_flags listen -i rtsp://ownaddress/live.sdp @var{output}
+ffmpeg -rtsp_flags listen -i rtsp://ownaddress/live.sdp @var{output}
 @end example
 
 @section sap
@@ -491,19 +521,19 @@
 To broadcast a stream on the local subnet, for watching in VLC:
 
 @example
-avconv -re -i @var{input} -f sap sap://224.0.0.255?same_port=1
+ffmpeg -re -i @var{input} -f sap sap://224.0.0.255?same_port=1
 @end example
 
-Similarly, for watching in avplay:
+Similarly, for watching in @command{ffplay}:
 
 @example
-avconv -re -i @var{input} -f sap sap://224.0.0.255
+ffmpeg -re -i @var{input} -f sap sap://224.0.0.255
 @end example
 
-And for watching in avplay, over IPv6:
+And for watching in @command{ffplay}, over IPv6:
 
 @example
-avconv -re -i @var{input} -f sap sap://[ff0e::1:2:3:4]
+ffmpeg -re -i @var{input} -f sap sap://[ff0e::1:2:3:4]
 @end example
 
 @subsection Demuxer
@@ -525,13 +555,13 @@
 To play back the first stream announced on the normal SAP multicast address:
 
 @example
-avplay sap://
+ffplay sap://
 @end example
 
 To play back the first stream announced on one the default IPv6 SAP multicast address:
 
 @example
-avplay sap://[ff0e::2:7ffe]
+ffplay sap://[ff0e::2:7ffe]
 @end example
 
 @section tcp
@@ -548,13 +578,60 @@
 @item listen
 Listen for an incoming connection
 
+@item timeout=@var{microseconds}
+In read mode: if no data arrived in more than this time interval, raise error.
+In write mode: if socket cannot be written in more than this time interval, raise error.
+This also sets timeout on TCP connection establishing.
+
 @example
-avconv -i @var{input} -f @var{format} tcp://@var{hostname}:@var{port}?listen
-avplay tcp://@var{hostname}:@var{port}
+ffmpeg -i @var{input} -f @var{format} tcp://@var{hostname}:@var{port}?listen
+ffplay tcp://@var{hostname}:@var{port}
 @end example
 
 @end table
 
+@section tls
+
+Transport Layer Security/Secure Sockets Layer
+
+The required syntax for a TLS/SSL url is:
+@example
+tls://@var{hostname}:@var{port}[?@var{options}]
+@end example
+
+@table @option
+
+@item listen
+Act as a server, listening for an incoming connection.
+
+@item cafile=@var{filename}
+Certificate authority file. The file must be in OpenSSL PEM format.
+
+@item cert=@var{filename}
+Certificate file. The file must be in OpenSSL PEM format.
+
+@item key=@var{filename}
+Private key file.
+
+@item verify=@var{0|1}
+Verify the peer's certificate.
+
+@end table
+
+Example command lines:
+
+To create a TLS/SSL server that serves an input stream.
+
+@example
+ffmpeg -i @var{input} -f @var{format} tls://@var{hostname}:@var{port}?listen&cert=@var{server.crt}&key=@var{server.key}
+@end example
+
+To play back a stream from the TLS/SSL server using @command{ffplay}:
+
+@example
+ffplay tls://@var{hostname}:@var{port}
+@end example
+
 @section udp
 
 User Datagram Protocol.
@@ -564,16 +641,23 @@
 udp://@var{hostname}:@var{port}[?@var{options}]
 @end example
 
-@var{options} contains a list of &-seperated options of the form @var{key}=@var{val}.
-Follow the list of supported options.
+@var{options} contains a list of &-separated options of the form @var{key}=@var{val}.
+
+In case threading is enabled on the system, a circular buffer is used
+to store the incoming data, which allows to reduce loss of data due to
+UDP socket buffer overruns. The @var{fifo_size} and
+@var{overrun_nonfatal} options are related to this buffer.
+
+The list of supported options follows.
 
 @table @option
 
 @item buffer_size=@var{size}
-set the UDP buffer size in bytes
+Set the UDP socket buffer size in bytes. This is used both for the
+receiving and the sending buffer size.
 
 @item localport=@var{port}
-override the local UDP port to bind with
+Override the local UDP port to bind with.
 
 @item localaddr=@var{addr}
 Choose the local IP address. This is useful e.g. if sending multicast
@@ -581,13 +665,13 @@
 which interface to send on by specifying the IP address of that interface.
 
 @item pkt_size=@var{size}
-set the size in bytes of UDP packets
+Set the size in bytes of UDP packets.
 
 @item reuse=@var{1|0}
-explicitly allow or disallow reusing UDP sockets
+Explicitly allow or disallow reusing UDP sockets.
 
 @item ttl=@var{ttl}
-set the time to live value (for multicast only)
+Set the time to live value (for multicast only).
 
 @item connect=@var{1|0}
 Initialize the UDP socket with @code{connect()}. In this case, the
@@ -607,23 +691,34 @@
 @item block=@var{address}[,@var{address}]
 Ignore packets sent to the multicast group from the specified
 sender IP addresses.
+
+@item fifo_size=@var{units}
+Set the UDP receiving circular buffer size, expressed as a number of
+packets with size of 188 bytes. If not specified defaults to 7*4096.
+
+@item overrun_nonfatal=@var{1|0}
+Survive in case of UDP receiving circular buffer overrun. Default
+value is 0.
+
+@item timeout=@var{microseconds}
+In read mode: if no data arrived in more than this time interval, raise error.
 @end table
 
-Some usage examples of the udp protocol with @command{avconv} follow.
+Some usage examples of the UDP protocol with @command{ffmpeg} follow.
 
 To stream over UDP to a remote endpoint:
 @example
-avconv -i @var{input} -f @var{format} udp://@var{hostname}:@var{port}
+ffmpeg -i @var{input} -f @var{format} udp://@var{hostname}:@var{port}
 @end example
 
 To stream in mpegts format over UDP using 188 sized UDP packets, using a large input buffer:
 @example
-avconv -i @var{input} -f mpegts udp://@var{hostname}:@var{port}?pkt_size=188&buffer_size=65535
+ffmpeg -i @var{input} -f mpegts udp://@var{hostname}:@var{port}?pkt_size=188&buffer_size=65535
 @end example
 
 To receive over UDP from a remote endpoint:
 @example
-avconv -i udp://[@var{multicast-address}]:@var{port}
+ffmpeg -i udp://[@var{multicast-address}]:@var{port}
 @end example
 
 @c man end PROTOCOLS
diff --git a/doc/soc.txt b/doc/soc.txt
index 89728b5..2504dba 100644
--- a/doc/soc.txt
+++ b/doc/soc.txt
@@ -8,9 +8,9 @@
 
 The Goal:
 Our goal in respect to soc is and must be of course exactly one thing and
-that is to improve Libav, to reach this goal, code must
+that is to improve FFmpeg, to reach this goal, code must
 * conform to the development policy and patch submission guidelines
-* must improve Libav somehow (faster, smaller, "better",
+* must improve FFmpeg somehow (faster, smaller, "better",
   more codecs supported, fewer bugs, cleaner, ...)
 
 for mentors and other developers to help students to reach that goal it is
@@ -20,5 +20,5 @@
 * separation of cosmetic from non-cosmetic changes (this is almost entirely
   ignored by mentors and students in soc 2006 which might lead to a surprise
   when the code will be reviewed at the end before a possible inclusion in
-  Libav, individual changes were generally not reviewable due to cosmetics).
+  FFmpeg, individual changes were generally not reviewable due to cosmetics).
 * frequent commits, so that comments can be provided early
diff --git a/doc/swresample.txt b/doc/swresample.txt
new file mode 100644
index 0000000..7904147
--- /dev/null
+++ b/doc/swresample.txt
@@ -0,0 +1,46 @@
+    The official guide to swresample for confused developers.
+   =========================================================
+
+Current (simplified) Architecture:
+---------------------------------
+                        Input
+                          v
+       __________________/|\___________
+      /                   |            \
+     /    input sample format convert   v
+    /                     | ___________/
+    |                     |/
+    |                     v
+    |         ___________/|\___________              _____________
+    |        /            |            \            |             |
+    |   Rematrix          |          resample <---->|   Buffers   |
+    |        \___________ | ___________/            |_____________|
+    v                    \|/
+Special Converter         v
+    v         ___________/|\___________              _____________
+    |        /            |            \            |             |
+    |   Rematrix          |          resample <---->|   Buffers   |
+    |        \___________ | ___________/            |_____________|
+    |                    \|/
+    |                     v
+    |                     |\___________
+    \                     |            \
+     \   output sample format convert   v
+      \_________________  | ___________/
+                         \|/
+                          v
+                        Output
+
+Planar/Packed conversion is done when needed during sample format conversion.
+Every step can be skipped without memcpy when its not needed.
+Either Resampling and Rematrixing can be performed first depending on which
+way its 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.
+Internally 32bit float and 16bit int is supported currently, other formats can
+easily be added.
+Externally all sample formats in packed and planar configuration are supported
+It's also trivial to add special converters for common cases.
+If only sample format and/or packed/planar conversion is needed, it
+is performed from input to output directly in a single pass with no intermediates.
diff --git a/doc/syntax.texi b/doc/syntax.texi
new file mode 100644
index 0000000..169fa78
--- /dev/null
+++ b/doc/syntax.texi
@@ -0,0 +1,158 @@
+@chapter Syntax
+@c man begin SYNTAX
+
+When evaluating specific formats, FFmpeg uses internal library parsing
+functions, shared by the tools. This section documents the syntax of
+some of these formats.
+
+@anchor{date syntax}
+@section Date
+
+The accepted syntax is:
+@example
+[(YYYY-MM-DD|YYYYMMDD)[T|t| ]]((HH:MM:SS[.m...]]])|(HHMMSS[.m...]]]))[Z]
+now
+@end example
+
+If the value is "now" it takes the current time.
+
+Time is local time unless Z is appended, in which case it is
+interpreted as UTC.
+If the year-month-day part is not specified it takes the current
+year-month-day.
+
+@anchor{time duration syntax}
+@section Time duration
+
+The accepted syntax is:
+@example
+[-]HH:MM:SS[.m...]
+[-]S+[.m...]
+@end example
+
+@var{HH} expresses the number of hours, @var{MM} the number a of minutes
+and @var{SS} the number of seconds.
+
+@anchor{video size syntax}
+@section Video size
+Specify the size of the sourced video, it may be a string of the form
+@var{width}x@var{height}, or the name of a size abbreviation.
+
+The following abbreviations are recognized:
+@table @samp
+@item sqcif
+128x96
+@item qcif
+176x144
+@item cif
+352x288
+@item 4cif
+704x576
+@item 16cif
+1408x1152
+@item qqvga
+160x120
+@item qvga
+320x240
+@item vga
+640x480
+@item svga
+800x600
+@item xga
+1024x768
+@item uxga
+1600x1200
+@item qxga
+2048x1536
+@item sxga
+1280x1024
+@item qsxga
+2560x2048
+@item hsxga
+5120x4096
+@item wvga
+852x480
+@item wxga
+1366x768
+@item wsxga
+1600x1024
+@item wuxga
+1920x1200
+@item woxga
+2560x1600
+@item wqsxga
+3200x2048
+@item wquxga
+3840x2400
+@item whsxga
+6400x4096
+@item whuxga
+7680x4800
+@item cga
+320x200
+@item ega
+640x350
+@item hd480
+852x480
+@item hd720
+1280x720
+@item hd1080
+1920x1080
+@end table
+
+@anchor{video rate syntax}
+@section Video rate
+
+Specify the frame rate of a video, expressed as the number of frames
+generated per second. It has to be a string in the format
+@var{frame_rate_num}/@var{frame_rate_den}, an integer number, a float
+number or a valid video frame rate abbreviation.
+
+The following abbreviations are recognized:
+@table @samp
+@item ntsc
+30000/1001
+@item pal
+25/1
+@item qntsc
+30000/1
+@item qpal
+25/1
+@item sntsc
+30000/1
+@item spal
+25/1
+@item film
+24/1
+@item ntsc-film
+24000/1
+@end table
+
+@anchor{ratio syntax}
+@section Ratio
+
+A ratio can be expressed as an expression, or in the form
+@var{numerator}:@var{denominator}.
+
+Note that a ratio with infinite (1/0) or negative value is
+considered valid, so you should check on the returned value if you
+want to exclude those values.
+
+The undefined value can be expressed using the "0:0" string.
+
+@anchor{color syntax}
+@section Color
+
+It can be the name of a color (case insensitive match) or a
+[0x|#]RRGGBB[AA] sequence, possibly followed by "@@" and a string
+representing the alpha component.
+
+The alpha component may be a string composed by "0x" followed by an
+hexadecimal number or a decimal number between 0.0 and 1.0, which
+represents the opacity value (0x00/0.0 means completely transparent,
+0xff/1.0 completely opaque).
+If the alpha component is not specified then 0xff is assumed.
+
+The string "random" will result in a random color.
+
+@c man end SYNTAX
diff --git a/doc/t2h.init b/doc/t2h.init
index 78c5177..ec7d2a0 100644
--- a/doc/t2h.init
+++ b/doc/t2h.init
@@ -1,6 +1,6 @@
 # no horiz rules between sections
-$end_section = \&Libav_end_section;
-sub Libav_end_section($$)
+$end_section = \&FFmpeg_end_section;
+sub FFmpeg_end_section($$)
 {
 }
 
@@ -8,7 +8,7 @@
 '<link rel="icon" href="favicon.png" type="image/png" />
 ';
 
-$CSS_LINES = $ENV{"LIBAV_CSS"} || <<EOT;
+$CSS_LINES = $ENV{"FFMPEG_CSS"} || <<EOT;
 <style type="text/css">
 <!--
 .container {
@@ -129,7 +129,7 @@
 </style>
 EOT
 
-my $TEMPLATE_HEADER = $ENV{"LIBAV_HEADER"} || <<EOT;
+my $TEMPLATE_HEADER = $ENV{"FFMPEG_HEADER"} || <<EOT;
 <link rel="icon" href="favicon.png" type="image/png" />
 </head>
 <body>
@@ -141,8 +141,8 @@
 $SMALL_RULE = '';
 $BODYTEXT = '';
 
-$print_page_foot = \&Libav_print_page_foot;
-sub Libav_print_page_foot($$)
+$print_page_foot = \&FFmpeg_print_page_foot;
+sub FFmpeg_print_page_foot($$)
 {
     my $fh = shift;
     my $program_string = defined &T2H_DEFAULT_program_string ?
@@ -152,9 +152,9 @@
     print $fh "</span></footer></div>\n";
 }
 
-$float = \&Libav_float;
+$float = \&FFmpeg_float;
 
-sub Libav_float($$$$)
+sub FFmpeg_float($$$$)
 {
     my $text = shift;
     my $float = shift;
@@ -181,8 +181,8 @@
     return '<div class="float ' . $class . '">' . "$label\n" . $text . '</div>';
 }
 
-$print_page_head = \&Libav_print_page_head;
-sub Libav_print_page_head($$)
+$print_page_head = \&FFmpeg_print_page_head;
+sub FFmpeg_print_page_head($$)
 {
     my $fh = shift;
     my $longtitle = "$Texi2HTML::THISDOC{'title_no_texi'}";
@@ -195,7 +195,7 @@
     my $encoding = '';
     $encoding = "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=$ENCODING\">" if (defined($ENCODING) and ($ENCODING ne ''));
     $longtitle =~ s/Documentation.*//g;
-    $longtitle = "Libav documentation : " . $longtitle;
+    $longtitle = "FFmpeg documentation : " . $longtitle;
 
     print $fh <<EOT;
 <!DOCTYPE html>
@@ -218,6 +218,9 @@
 EOT
 }
 
+# declare encoding in header
+$IN_ENCODING = $ENCODING = "utf-8";
+
 # no navigation elements
 $SECTION_NAVIGATION = 0;
 # the same for texi2html 5.0
diff --git a/doc/texi2pod.pl b/doc/texi2pod.pl
index 94323be..5e8814f 100755
--- a/doc/texi2pod.pl
+++ b/doc/texi2pod.pl
@@ -1,4 +1,4 @@
-#! /usr/bin/perl -w
+#! /usr/bin/perl
 
 #   Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
 
@@ -23,6 +23,8 @@
 # markup to Perl POD format.  It's intended to be used to extract
 # something suitable for a manpage from a Texinfo document.
 
+use warnings;
+
 $output = 0;
 $skipping = 0;
 %sects = ();
diff --git a/ffmpeg.c b/ffmpeg.c
new file mode 100644
index 0000000..97a1e4d
--- /dev/null
+++ b/ffmpeg.c
@@ -0,0 +1,3167 @@
+/*
+ * Copyright (c) 2000-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
+ */
+
+/**
+ * @file
+ * multimedia converter based on the FFmpeg libraries
+ */
+
+#include "config.h"
+#include <ctype.h>
+#include <string.h>
+#include <math.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <limits.h>
+#if HAVE_ISATTY
+#if HAVE_IO_H
+#include <io.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#endif
+#include "libavformat/avformat.h"
+#include "libavdevice/avdevice.h"
+#include "libswscale/swscale.h"
+#include "libswresample/swresample.h"
+#include "libavutil/opt.h"
+#include "libavutil/audioconvert.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/samplefmt.h"
+#include "libavutil/colorspace.h"
+#include "libavutil/fifo.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/dict.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/avstring.h"
+#include "libavutil/libm.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/timestamp.h"
+#include "libavutil/bprint.h"
+#include "libavutil/time.h"
+#include "libavformat/os_support.h"
+
+#include "libavformat/ffm.h" // not public API
+
+# include "libavfilter/avcodec.h"
+# include "libavfilter/avfilter.h"
+# include "libavfilter/avfiltergraph.h"
+# include "libavfilter/buffersrc.h"
+# include "libavfilter/buffersink.h"
+
+#if HAVE_SYS_RESOURCE_H
+#include <sys/types.h>
+#include <sys/resource.h>
+#elif HAVE_GETPROCESSTIMES
+#include <windows.h>
+#endif
+#if HAVE_GETPROCESSMEMORYINFO
+#include <windows.h>
+#include <psapi.h>
+#endif
+
+#if HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#if HAVE_TERMIOS_H
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <termios.h>
+#elif HAVE_KBHIT
+#include <conio.h>
+#endif
+
+#if HAVE_PTHREADS
+#include <pthread.h>
+#endif
+
+#include <time.h>
+
+#include "ffmpeg.h"
+#include "cmdutils.h"
+
+#include "libavutil/avassert.h"
+
+const char program_name[] = "ffmpeg";
+const int program_birth_year = 2000;
+
+static FILE *vstats_file;
+
+static void do_video_stats(AVFormatContext *os, OutputStream *ost, int frame_size);
+static int64_t getutime(void);
+
+static int run_as_daemon  = 0;
+static int64_t video_size = 0;
+static int64_t audio_size = 0;
+static int64_t subtitle_size = 0;
+static int64_t extra_size = 0;
+static int nb_frames_dup = 0;
+static int nb_frames_drop = 0;
+
+static int current_time;
+AVIOContext *progress_avio = NULL;
+
+static uint8_t *subtitle_out;
+
+#if HAVE_PTHREADS
+/* signal to input threads that they should exit; set by the main thread */
+static int transcoding_finished;
+#endif
+
+#define DEFAULT_PASS_LOGFILENAME_PREFIX "ffmpeg2pass"
+
+InputStream **input_streams = NULL;
+int        nb_input_streams = 0;
+InputFile   **input_files   = NULL;
+int        nb_input_files   = 0;
+
+OutputStream **output_streams = NULL;
+int         nb_output_streams = 0;
+OutputFile   **output_files   = NULL;
+int         nb_output_files   = 0;
+
+FilterGraph **filtergraphs;
+int        nb_filtergraphs;
+
+#if HAVE_TERMIOS_H
+
+/* init terminal so that we can grab keys */
+static struct termios oldtty;
+static int restore_tty;
+#endif
+
+
+/* sub2video hack:
+   Convert subtitles to video with alpha to insert them in filter graphs.
+   This is a temporary solution until libavfilter gets real subtitles support.
+ */
+
+
+
+static void sub2video_copy_rect(uint8_t *dst, int dst_linesize, int w, int h,
+                                AVSubtitleRect *r)
+{
+    uint32_t *pal, *dst2;
+    uint8_t *src, *src2;
+    int x, y;
+
+    if (r->type != SUBTITLE_BITMAP) {
+        av_log(NULL, AV_LOG_WARNING, "sub2video: non-bitmap subtitle\n");
+        return;
+    }
+    if (r->x < 0 || r->x + r->w > w || r->y < 0 || r->y + r->h > h) {
+        av_log(NULL, AV_LOG_WARNING, "sub2video: rectangle overflowing\n");
+        return;
+    }
+
+    dst += r->y * dst_linesize + r->x * 4;
+    src = r->pict.data[0];
+    pal = (uint32_t *)r->pict.data[1];
+    for (y = 0; y < r->h; y++) {
+        dst2 = (uint32_t *)dst;
+        src2 = src;
+        for (x = 0; x < r->w; x++)
+            *(dst2++) = pal[*(src2++)];
+        dst += dst_linesize;
+        src += r->pict.linesize[0];
+    }
+}
+
+static void sub2video_push_ref(InputStream *ist, int64_t pts)
+{
+    AVFilterBufferRef *ref = ist->sub2video.ref;
+    int i;
+
+    ist->sub2video.last_pts = ref->pts = pts;
+    for (i = 0; i < ist->nb_filters; i++)
+        av_buffersrc_add_ref(ist->filters[i]->filter,
+                             avfilter_ref_buffer(ref, ~0),
+                             AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT |
+                             AV_BUFFERSRC_FLAG_NO_COPY |
+                             AV_BUFFERSRC_FLAG_PUSH);
+}
+
+static void sub2video_update(InputStream *ist, AVSubtitle *sub)
+{
+    int w = ist->sub2video.w, h = ist->sub2video.h;
+    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);
+
+    if (!ref)
+        return;
+    dst          = ref->data    [0];
+    dst_linesize = ref->linesize[0];
+    memset(dst, 0, h * dst_linesize);
+    for (i = 0; i < sub->num_rects; i++)
+        sub2video_copy_rect(dst, dst_linesize, w, h, sub->rects[i]);
+    sub2video_push_ref(ist, pts);
+}
+
+static void sub2video_heartbeat(InputStream *ist, int64_t pts)
+{
+    InputFile *infile = input_files[ist->file_index];
+    int i, j, nb_reqs;
+    int64_t pts2;
+
+    /* When a frame is read from a file, examine all sub2video streams in
+       the same file and send the sub2video frame again. Otherwise, decoded
+       video frames could be accumulating in the filter graph while a filter
+       (possibly overlay) is desperately waiting for a subtitle frame. */
+    for (i = 0; i < infile->nb_streams; i++) {
+        InputStream *ist2 = input_streams[infile->ist_index + i];
+        if (!ist2->sub2video.ref)
+            continue;
+        /* subtitles seem to be usually muxed ahead of other streams;
+           if not, substracting a larger time here is necessary */
+        pts2 = av_rescale_q(pts, ist->st->time_base, ist2->st->time_base) - 1;
+        /* do not send the heartbeat frame if the subtitle is already ahead */
+        if (pts2 <= ist2->sub2video.last_pts)
+            continue;
+        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)
+            sub2video_push_ref(ist2, pts2);
+    }
+}
+
+static void sub2video_flush(InputStream *ist)
+{
+    int i;
+
+    for (i = 0; i < ist->nb_filters; i++)
+        av_buffersrc_add_ref(ist->filters[i]->filter, NULL, 0);
+}
+
+/* end of sub2video hack */
+
+void term_exit(void)
+{
+    av_log(NULL, AV_LOG_QUIET, "%s", "");
+#if HAVE_TERMIOS_H
+    if(restore_tty)
+        tcsetattr (0, TCSANOW, &oldtty);
+#endif
+}
+
+static volatile int received_sigterm = 0;
+static volatile int received_nb_signals = 0;
+
+static void
+sigterm_handler(int sig)
+{
+    received_sigterm = sig;
+    received_nb_signals++;
+    term_exit();
+    if(received_nb_signals > 3)
+        exit(123);
+}
+
+void term_init(void)
+{
+#if HAVE_TERMIOS_H
+    if(!run_as_daemon){
+        struct termios tty;
+        int istty = 1;
+#if HAVE_ISATTY
+        istty = isatty(0) && isatty(2);
+#endif
+        if (istty && tcgetattr (0, &tty) == 0) {
+            oldtty = tty;
+            restore_tty = 1;
+            atexit(term_exit);
+
+            tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
+                             |INLCR|IGNCR|ICRNL|IXON);
+            tty.c_oflag |= OPOST;
+            tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
+            tty.c_cflag &= ~(CSIZE|PARENB);
+            tty.c_cflag |= CS8;
+            tty.c_cc[VMIN] = 1;
+            tty.c_cc[VTIME] = 0;
+
+            tcsetattr (0, TCSANOW, &tty);
+        }
+        signal(SIGQUIT, sigterm_handler); /* Quit (POSIX).  */
+    }
+#endif
+    avformat_network_deinit();
+
+    signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).    */
+    signal(SIGTERM, sigterm_handler); /* Termination (ANSI).  */
+#ifdef SIGXCPU
+    signal(SIGXCPU, sigterm_handler);
+#endif
+}
+
+/* read a key without blocking */
+static int read_key(void)
+{
+    unsigned char ch;
+#if HAVE_TERMIOS_H
+    int n = 1;
+    struct timeval tv;
+    fd_set rfds;
+
+    FD_ZERO(&rfds);
+    FD_SET(0, &rfds);
+    tv.tv_sec = 0;
+    tv.tv_usec = 0;
+    n = select(1, &rfds, NULL, NULL, &tv);
+    if (n > 0) {
+        n = read(0, &ch, 1);
+        if (n == 1)
+            return ch;
+
+        return n;
+    }
+#elif HAVE_KBHIT
+#    if HAVE_PEEKNAMEDPIPE
+    static int is_pipe;
+    static HANDLE input_handle;
+    DWORD dw, nchars;
+    if(!input_handle){
+        input_handle = GetStdHandle(STD_INPUT_HANDLE);
+        is_pipe = !GetConsoleMode(input_handle, &dw);
+    }
+
+    if (stdin->_cnt > 0) {
+        read(0, &ch, 1);
+        return ch;
+    }
+    if (is_pipe) {
+        /* When running under a GUI, you will end here. */
+        if (!PeekNamedPipe(input_handle, NULL, 0, NULL, &nchars, NULL))
+            return -1;
+        //Read it
+        if(nchars != 0) {
+            read(0, &ch, 1);
+            return ch;
+        }else{
+            return -1;
+        }
+    }
+#    endif
+    if(kbhit())
+        return(getch());
+#endif
+    return -1;
+}
+
+static int decode_interrupt_cb(void *ctx)
+{
+    return received_nb_signals > 1;
+}
+
+const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
+
+static void exit_program(void)
+{
+    int i, j;
+
+    for (i = 0; i < nb_filtergraphs; i++) {
+        avfilter_graph_free(&filtergraphs[i]->graph);
+        for (j = 0; j < filtergraphs[i]->nb_inputs; j++) {
+            av_freep(&filtergraphs[i]->inputs[j]->name);
+            av_freep(&filtergraphs[i]->inputs[j]);
+        }
+        av_freep(&filtergraphs[i]->inputs);
+        for (j = 0; j < filtergraphs[i]->nb_outputs; j++) {
+            av_freep(&filtergraphs[i]->outputs[j]->name);
+            av_freep(&filtergraphs[i]->outputs[j]);
+        }
+        av_freep(&filtergraphs[i]->outputs);
+        av_freep(&filtergraphs[i]);
+    }
+    av_freep(&filtergraphs);
+
+    av_freep(&subtitle_out);
+
+    /* close files */
+    for (i = 0; i < nb_output_files; i++) {
+        AVFormatContext *s = output_files[i]->ctx;
+        if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
+            avio_close(s->pb);
+        avformat_free_context(s);
+        av_dict_free(&output_files[i]->opts);
+        av_freep(&output_files[i]);
+    }
+    for (i = 0; i < nb_output_streams; i++) {
+        AVBitStreamFilterContext *bsfc = output_streams[i]->bitstream_filters;
+        while (bsfc) {
+            AVBitStreamFilterContext *next = bsfc->next;
+            av_bitstream_filter_close(bsfc);
+            bsfc = next;
+        }
+        output_streams[i]->bitstream_filters = NULL;
+        avcodec_free_frame(&output_streams[i]->filtered_frame);
+
+        av_freep(&output_streams[i]->forced_keyframes);
+        av_freep(&output_streams[i]->avfilter);
+        av_freep(&output_streams[i]->logfile_prefix);
+        av_freep(&output_streams[i]);
+    }
+    for (i = 0; i < nb_input_files; i++) {
+        avformat_close_input(&input_files[i]->ctx);
+        av_freep(&input_files[i]);
+    }
+    for (i = 0; i < nb_input_streams; i++) {
+        avcodec_free_frame(&input_streams[i]->decoded_frame);
+        av_dict_free(&input_streams[i]->opts);
+        free_buffer_pool(&input_streams[i]->buffer_pool);
+        avfilter_unref_bufferp(&input_streams[i]->sub2video.ref);
+        av_freep(&input_streams[i]->filters);
+        av_freep(&input_streams[i]);
+    }
+
+    if (vstats_file)
+        fclose(vstats_file);
+    av_free(vstats_filename);
+
+    av_freep(&input_streams);
+    av_freep(&input_files);
+    av_freep(&output_streams);
+    av_freep(&output_files);
+
+    uninit_opts();
+
+    avfilter_uninit();
+    avformat_network_deinit();
+
+    if (received_sigterm) {
+        av_log(NULL, AV_LOG_INFO, "Received signal %d: terminating.\n",
+               (int) received_sigterm);
+        exit (255);
+    }
+}
+
+void assert_avoptions(AVDictionary *m)
+{
+    AVDictionaryEntry *t;
+    if ((t = av_dict_get(m, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
+        av_log(NULL, AV_LOG_FATAL, "Option %s not found.\n", t->key);
+        exit(1);
+    }
+}
+
+static void assert_codec_experimental(AVCodecContext *c, int encoder)
+{
+    const char *codec_string = encoder ? "encoder" : "decoder";
+    AVCodec *codec;
+    if (c->codec->capabilities & CODEC_CAP_EXPERIMENTAL &&
+        c->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+        av_log(NULL, AV_LOG_FATAL, "%s '%s' is experimental and might produce bad "
+                "results.\nAdd '-strict experimental' if you want to use it.\n",
+                codec_string, c->codec->name);
+        codec = encoder ? avcodec_find_encoder(c->codec->id) : avcodec_find_decoder(c->codec->id);
+        if (!(codec->capabilities & CODEC_CAP_EXPERIMENTAL))
+            av_log(NULL, AV_LOG_FATAL, "Or use the non experimental %s '%s'.\n",
+                   codec_string, codec->name);
+        exit(1);
+    }
+}
+
+static void update_benchmark(const char *fmt, ...)
+{
+    if (do_benchmark_all) {
+        int64_t t = getutime();
+        va_list va;
+        char buf[1024];
+
+        if (fmt) {
+            va_start(va, fmt);
+            vsnprintf(buf, sizeof(buf), fmt, va);
+            va_end(va);
+            printf("bench: %8"PRIu64" %s \n", t - current_time, buf);
+        }
+        current_time = t;
+    }
+}
+
+static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
+{
+    AVBitStreamFilterContext *bsfc = ost->bitstream_filters;
+    AVCodecContext          *avctx = ost->st->codec;
+    int ret;
+
+    if ((avctx->codec_type == AVMEDIA_TYPE_VIDEO && video_sync_method == VSYNC_DROP) ||
+        (avctx->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0))
+        pkt->pts = pkt->dts = AV_NOPTS_VALUE;
+
+    if ((avctx->codec_type == AVMEDIA_TYPE_AUDIO || avctx->codec_type == AVMEDIA_TYPE_VIDEO) && pkt->dts != AV_NOPTS_VALUE) {
+        int64_t max = ost->st->cur_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
+        if (ost->st->cur_dts && ost->st->cur_dts != AV_NOPTS_VALUE &&  max > pkt->dts) {
+            av_log(s, max - pkt->dts > 2 || avctx->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG,
+                   "st:%d PTS: %"PRId64" DTS: %"PRId64" < %"PRId64" invalid, clipping\n", pkt->stream_index, pkt->pts, pkt->dts, max);
+            if(pkt->pts >= pkt->dts)
+                pkt->pts = FFMAX(pkt->pts, max);
+            pkt->dts = max;
+        }
+    }
+
+    /*
+     * Audio encoders may split the packets --  #frames in != #packets out.
+     * But there is no reordering, so we can limit the number of output packets
+     * by simply dropping them here.
+     * Counting encoded video frames needs to be done separately because of
+     * reordering, see do_video_out()
+     */
+    if (!(avctx->codec_type == AVMEDIA_TYPE_VIDEO && avctx->codec)) {
+        if (ost->frame_number >= ost->max_frames) {
+            av_free_packet(pkt);
+            return;
+        }
+        ost->frame_number++;
+    }
+
+    while (bsfc) {
+        AVPacket new_pkt = *pkt;
+        int a = av_bitstream_filter_filter(bsfc, avctx, NULL,
+                                           &new_pkt.data, &new_pkt.size,
+                                           pkt->data, pkt->size,
+                                           pkt->flags & AV_PKT_FLAG_KEY);
+        if(a == 0 && new_pkt.data != pkt->data && new_pkt.destruct) {
+            uint8_t *t = av_malloc(new_pkt.size + FF_INPUT_BUFFER_PADDING_SIZE); //the new should be a subset of the old so cannot overflow
+            if(t) {
+                memcpy(t, new_pkt.data, new_pkt.size);
+                memset(t + new_pkt.size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+                new_pkt.data = t;
+                a = 1;
+            } else
+                a = AVERROR(ENOMEM);
+        }
+        if (a > 0) {
+            av_free_packet(pkt);
+            new_pkt.destruct = av_destruct_packet;
+        } else if (a < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Failed to open bitstream filter %s for stream %d with codec %s",
+                   bsfc->filter->name, pkt->stream_index,
+                   avctx->codec ? avctx->codec->name : "copy");
+            print_error("", a);
+            if (exit_on_error)
+                exit(1);
+        }
+        *pkt = new_pkt;
+
+        bsfc = bsfc->next;
+    }
+
+    pkt->stream_index = ost->index;
+
+    if (debug_ts) {
+        av_log(NULL, AV_LOG_INFO, "muxer <- type:%s "
+                "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s size:%d\n",
+                av_get_media_type_string(ost->st->codec->codec_type),
+                av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base),
+                av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base),
+                pkt->size
+              );
+    }
+
+    ret = av_interleaved_write_frame(s, pkt);
+    if (ret < 0) {
+        print_error("av_interleaved_write_frame()", ret);
+        exit(1);
+    }
+}
+
+static void close_output_stream(OutputStream *ost)
+{
+    OutputFile *of = output_files[ost->file_index];
+
+    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;
+    }
+}
+
+static int check_recording_time(OutputStream *ost)
+{
+    OutputFile *of = output_files[ost->file_index];
+
+    if (of->recording_time != INT64_MAX &&
+        av_compare_ts(ost->sync_opts - ost->first_pts, ost->st->codec->time_base, of->recording_time,
+                      AV_TIME_BASE_Q) >= 0) {
+        close_output_stream(ost);
+        return 0;
+    }
+    return 1;
+}
+
+static void do_audio_out(AVFormatContext *s, OutputStream *ost,
+                         AVFrame *frame)
+{
+    AVCodecContext *enc = ost->st->codec;
+    AVPacket pkt;
+    int got_packet = 0;
+
+    av_init_packet(&pkt);
+    pkt.data = NULL;
+    pkt.size = 0;
+
+    if (!check_recording_time(ost))
+        return;
+
+    if (frame->pts == AV_NOPTS_VALUE || audio_sync_method < 0)
+        frame->pts = ost->sync_opts;
+    ost->sync_opts = frame->pts + frame->nb_samples;
+
+    av_assert0(pkt.size || !pkt.data);
+    update_benchmark(NULL);
+    if (avcodec_encode_audio2(enc, &pkt, frame, &got_packet) < 0) {
+        av_log(NULL, AV_LOG_FATAL, "Audio encoding failed (avcodec_encode_audio2)\n");
+        exit(1);
+    }
+    update_benchmark("encode_audio %d.%d", ost->file_index, ost->index);
+
+    if (got_packet) {
+        if (pkt.pts != AV_NOPTS_VALUE)
+            pkt.pts      = av_rescale_q(pkt.pts,      enc->time_base, ost->st->time_base);
+        if (pkt.dts != AV_NOPTS_VALUE)
+            pkt.dts      = av_rescale_q(pkt.dts,      enc->time_base, ost->st->time_base);
+        if (pkt.duration > 0)
+            pkt.duration = av_rescale_q(pkt.duration, enc->time_base, ost->st->time_base);
+
+        if (debug_ts) {
+            av_log(NULL, AV_LOG_INFO, "encoder -> type:audio "
+                   "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n",
+                   av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ost->st->time_base),
+                   av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->st->time_base));
+        }
+
+        audio_size += pkt.size;
+        write_frame(s, &pkt, ost);
+
+        av_free_packet(&pkt);
+    }
+}
+
+static void pre_process_video_frame(InputStream *ist, AVPicture *picture, void **bufp)
+{
+    AVCodecContext *dec;
+    AVPicture *picture2;
+    AVPicture picture_tmp;
+    uint8_t *buf = 0;
+
+    dec = ist->st->codec;
+
+    /* deinterlace : must be done before any resize */
+    if (do_deinterlace) {
+        int size;
+
+        /* create temporary picture */
+        size = avpicture_get_size(dec->pix_fmt, dec->width, dec->height);
+        buf  = av_malloc(size);
+        if (!buf)
+            return;
+
+        picture2 = &picture_tmp;
+        avpicture_fill(picture2, buf, dec->pix_fmt, dec->width, dec->height);
+
+        if (avpicture_deinterlace(picture2, picture,
+                                 dec->pix_fmt, dec->width, dec->height) < 0) {
+            /* if error, do not deinterlace */
+            av_log(NULL, AV_LOG_WARNING, "Deinterlacing failed\n");
+            av_free(buf);
+            buf = NULL;
+            picture2 = picture;
+        }
+    } else {
+        picture2 = picture;
+    }
+
+    if (picture != picture2)
+        *picture = *picture2;
+    *bufp = buf;
+}
+
+static void do_subtitle_out(AVFormatContext *s,
+                            OutputStream *ost,
+                            InputStream *ist,
+                            AVSubtitle *sub)
+{
+    int subtitle_out_max_size = 1024 * 1024;
+    int subtitle_out_size, nb, i;
+    AVCodecContext *enc;
+    AVPacket pkt;
+    int64_t pts;
+
+    if (sub->pts == AV_NOPTS_VALUE) {
+        av_log(NULL, AV_LOG_ERROR, "Subtitle packets must have a pts\n");
+        if (exit_on_error)
+            exit(1);
+        return;
+    }
+
+    enc = ost->st->codec;
+
+    if (!subtitle_out) {
+        subtitle_out = av_malloc(subtitle_out_max_size);
+    }
+
+    /* Note: DVB subtitle need one packet to draw them and one other
+       packet to clear them */
+    /* XXX: signal it in the codec context ? */
+    if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE)
+        nb = 2;
+    else
+        nb = 1;
+
+    /* shift timestamp to honor -ss and make check_recording_time() work with -t */
+    pts = sub->pts - output_files[ost->file_index]->start_time;
+    for (i = 0; i < nb; i++) {
+        ost->sync_opts = av_rescale_q(pts, AV_TIME_BASE_Q, enc->time_base);
+        if (!check_recording_time(ost))
+            return;
+
+        sub->pts = pts;
+        // start_display_time is required to be 0
+        sub->pts               += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q);
+        sub->end_display_time  -= sub->start_display_time;
+        sub->start_display_time = 0;
+        if (i == 1)
+            sub->num_rects = 0;
+        subtitle_out_size = avcodec_encode_subtitle(enc, subtitle_out,
+                                                    subtitle_out_max_size, sub);
+        if (subtitle_out_size < 0) {
+            av_log(NULL, AV_LOG_FATAL, "Subtitle encoding failed\n");
+            exit(1);
+        }
+
+        av_init_packet(&pkt);
+        pkt.data = subtitle_out;
+        pkt.size = subtitle_out_size;
+        pkt.pts  = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->st->time_base);
+        pkt.duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->st->time_base);
+        if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
+            /* XXX: the pts correction is handled here. Maybe handling
+               it in the codec would be better */
+            if (i == 0)
+                pkt.pts += 90 * sub->start_display_time;
+            else
+                pkt.pts += 90 * sub->end_display_time;
+        }
+        subtitle_size += pkt.size;
+        write_frame(s, &pkt, ost);
+    }
+}
+
+static void do_video_out(AVFormatContext *s,
+                         OutputStream *ost,
+                         AVFrame *in_picture)
+{
+    int ret, format_video_sync;
+    AVPacket pkt;
+    AVCodecContext *enc = ost->st->codec;
+    int nb_frames, i;
+    double sync_ipts, delta;
+    double duration = 0;
+    int frame_size = 0;
+    InputStream *ist = NULL;
+
+    if (ost->source_index >= 0)
+        ist = input_streams[ost->source_index];
+
+    if(ist && ist->st->start_time != AV_NOPTS_VALUE && ist->st->first_dts != AV_NOPTS_VALUE && ost->frame_rate.num)
+        duration = 1/(av_q2d(ost->frame_rate) * av_q2d(enc->time_base));
+
+    sync_ipts = in_picture->pts;
+    delta = sync_ipts - ost->sync_opts + duration;
+
+    /* by default, we output a single frame */
+    nb_frames = 1;
+
+    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;
+
+    switch (format_video_sync) {
+    case VSYNC_CFR:
+        // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
+        if (delta < -1.1)
+            nb_frames = 0;
+        else if (delta > 1.1)
+            nb_frames = lrintf(delta);
+        break;
+    case VSYNC_VFR:
+        if (delta <= -0.6)
+            nb_frames = 0;
+        else if (delta > 0.6)
+            ost->sync_opts = lrint(sync_ipts);
+        break;
+    case VSYNC_DROP:
+    case VSYNC_PASSTHROUGH:
+        ost->sync_opts = lrint(sync_ipts);
+        break;
+    default:
+        av_assert0(0);
+    }
+
+    nb_frames = FFMIN(nb_frames, ost->max_frames - ost->frame_number);
+    if (nb_frames == 0) {
+        nb_frames_drop++;
+        av_log(NULL, AV_LOG_VERBOSE, "*** drop!\n");
+        return;
+    } else if (nb_frames > 1) {
+        if (nb_frames > dts_error_threshold * 30) {
+            av_log(NULL, AV_LOG_ERROR, "%d frame duplication too large, skipping\n", nb_frames - 1);
+            nb_frames_drop++;
+            return;
+        }
+        nb_frames_dup += nb_frames - 1;
+        av_log(NULL, AV_LOG_VERBOSE, "*** %d dup!\n", nb_frames - 1);
+    }
+
+  /* duplicates frame if needed */
+  for (i = 0; i < nb_frames; i++) {
+    av_init_packet(&pkt);
+    pkt.data = NULL;
+    pkt.size = 0;
+
+    in_picture->pts = ost->sync_opts;
+
+    if (!check_recording_time(ost))
+        return;
+
+    if (s->oformat->flags & AVFMT_RAWPICTURE &&
+        enc->codec->id == AV_CODEC_ID_RAWVIDEO) {
+        /* raw pictures are written as AVPicture structure to
+           avoid any copies. We support temporarily the older
+           method. */
+        enc->coded_frame->interlaced_frame = in_picture->interlaced_frame;
+        enc->coded_frame->top_field_first  = in_picture->top_field_first;
+        pkt.data   = (uint8_t *)in_picture;
+        pkt.size   =  sizeof(AVPicture);
+        pkt.pts    = av_rescale_q(in_picture->pts, enc->time_base, ost->st->time_base);
+        pkt.flags |= AV_PKT_FLAG_KEY;
+
+        video_size += pkt.size;
+        write_frame(s, &pkt, ost);
+    } else {
+        int got_packet;
+        AVFrame big_picture;
+
+        big_picture = *in_picture;
+        /* better than nothing: use input picture interlaced
+           settings */
+        big_picture.interlaced_frame = in_picture->interlaced_frame;
+        if (ost->st->codec->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME)) {
+            if (ost->top_field_first == -1)
+                big_picture.top_field_first = in_picture->top_field_first;
+            else
+                big_picture.top_field_first = !!ost->top_field_first;
+        }
+
+        big_picture.quality = ost->st->codec->global_quality;
+        if (!enc->me_threshold)
+            big_picture.pict_type = 0;
+        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++;
+        }
+        update_benchmark(NULL);
+        ret = avcodec_encode_video2(enc, &pkt, &big_picture, &got_packet);
+        update_benchmark("encode_video %d.%d", ost->file_index, ost->index);
+        if (ret < 0) {
+            av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");
+            exit(1);
+        }
+
+        if (got_packet) {
+            if (pkt.pts == AV_NOPTS_VALUE && !(enc->codec->capabilities & CODEC_CAP_DELAY))
+                pkt.pts = ost->sync_opts;
+
+            if (pkt.pts != AV_NOPTS_VALUE)
+                pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base);
+            if (pkt.dts != AV_NOPTS_VALUE)
+                pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base);
+
+            if (debug_ts) {
+                av_log(NULL, AV_LOG_INFO, "encoder -> type:video "
+                    "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n",
+                    av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ost->st->time_base),
+                    av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->st->time_base));
+            }
+
+            frame_size = pkt.size;
+            video_size += pkt.size;
+            write_frame(s, &pkt, ost);
+            av_free_packet(&pkt);
+
+            /* if two pass, output log */
+            if (ost->logfile && enc->stats_out) {
+                fprintf(ost->logfile, "%s", enc->stats_out);
+            }
+        }
+    }
+    ost->sync_opts++;
+    /*
+     * For video, number of frames in == number of packets out.
+     * But there may be reordering, so we can't throw away frames on encoder
+     * flush, we need to limit them here, before they go into encoder.
+     */
+    ost->frame_number++;
+  }
+
+    if (vstats_filename && frame_size)
+        do_video_stats(output_files[ost->file_index]->ctx, ost, frame_size);
+}
+
+static double psnr(double d)
+{
+    return -10.0 * log(d) / log(10.0);
+}
+
+static void do_video_stats(AVFormatContext *os, OutputStream *ost,
+                           int frame_size)
+{
+    AVCodecContext *enc;
+    int frame_number;
+    double ti1, bitrate, avg_bitrate;
+
+    /* this is executed just the first time do_video_stats is called */
+    if (!vstats_file) {
+        vstats_file = fopen(vstats_filename, "w");
+        if (!vstats_file) {
+            perror("fopen");
+            exit(1);
+        }
+    }
+
+    enc = ost->st->codec;
+    if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
+        frame_number = ost->frame_number;
+        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);
+        if (ti1 < 0.01)
+            ti1 = 0.01;
+
+        bitrate     = (frame_size * 8) / av_q2d(enc->time_base) / 1000.0;
+        avg_bitrate = (double)(video_size * 8) / ti1 / 1000.0;
+        fprintf(vstats_file, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ",
+               (double)video_size / 1024, ti1, bitrate, avg_bitrate);
+        fprintf(vstats_file, "type= %c\n", av_get_picture_type_char(enc->coded_frame->pict_type));
+    }
+}
+
+/*
+ * Get and encode new output from any of the filtergraphs, without causing
+ * activity.
+ *
+ * @return  0 for success, <0 for severe errors
+ */
+static int reap_filters(void)
+{
+    AVFilterBufferRef *picref;
+    AVFrame *filtered_frame = NULL;
+    int i;
+    int64_t frame_pts;
+
+    /* Reap all buffers present in the buffer sinks */
+    for (i = 0; i < nb_output_streams; i++) {
+        OutputStream *ost = output_streams[i];
+        OutputFile    *of = output_files[ost->file_index];
+        int ret = 0;
+
+        if (!ost->filter)
+            continue;
+
+        if (!ost->filtered_frame && !(ost->filtered_frame = avcodec_alloc_frame())) {
+            return AVERROR(ENOMEM);
+        } else
+            avcodec_get_frame_defaults(ost->filtered_frame);
+        filtered_frame = ost->filtered_frame;
+
+        while (1) {
+            ret = av_buffersink_get_buffer_ref(ost->filter->filter, &picref,
+                                               AV_BUFFERSINK_FLAG_NO_REQUEST);
+            if (ret < 0) {
+                if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
+                    char buf[256];
+                    av_strerror(ret, buf, sizeof(buf));
+                    av_log(NULL, AV_LOG_WARNING,
+                           "Error in av_buffersink_get_buffer_ref(): %s\n", buf);
+                }
+                break;
+            }
+            frame_pts = AV_NOPTS_VALUE;
+            if (picref->pts != AV_NOPTS_VALUE) {
+                filtered_frame->pts = frame_pts = av_rescale_q(picref->pts,
+                                                ost->filter->filter->inputs[0]->time_base,
+                                                ost->st->codec->time_base) -
+                                    av_rescale_q(of->start_time,
+                                                AV_TIME_BASE_Q,
+                                                ost->st->codec->time_base);
+
+                if (of->start_time && filtered_frame->pts < 0) {
+                    avfilter_unref_buffer(picref);
+                    continue;
+                }
+            }
+            //if (ost->source_index >= 0)
+            //    *filtered_frame= *input_streams[ost->source_index]->decoded_frame; //for me_threshold
+
+
+            switch (ost->filter->filter->inputs[0]->type) {
+            case AVMEDIA_TYPE_VIDEO:
+                avfilter_copy_buf_props(filtered_frame, picref);
+                filtered_frame->pts = frame_pts;
+                if (!ost->frame_aspect_ratio)
+                    ost->st->codec->sample_aspect_ratio = picref->video->sample_aspect_ratio;
+
+                do_video_out(of->ctx, ost, filtered_frame);
+                break;
+            case AVMEDIA_TYPE_AUDIO:
+                avfilter_copy_buf_props(filtered_frame, picref);
+                filtered_frame->pts = frame_pts;
+                do_audio_out(of->ctx, ost, filtered_frame);
+                break;
+            default:
+                // TODO support subtitle filters
+                av_assert0(0);
+            }
+
+            avfilter_unref_buffer(picref);
+        }
+    }
+
+    return 0;
+}
+
+static void print_report(int is_last_report, int64_t timer_start, int64_t cur_time)
+{
+    char buf[1024];
+    AVBPrint buf_script;
+    OutputStream *ost;
+    AVFormatContext *oc;
+    int64_t total_size;
+    AVCodecContext *enc;
+    int frame_number, vid, i;
+    double bitrate;
+    int64_t pts = INT64_MIN;
+    static int64_t last_time = -1;
+    static int qp_histogram[52];
+    int hours, mins, secs, us;
+
+    if (!print_stats && !is_last_report && !progress_avio)
+        return;
+
+    if (!is_last_report) {
+        if (last_time == -1) {
+            last_time = cur_time;
+            return;
+        }
+        if ((cur_time - last_time) < 500000)
+            return;
+        last_time = cur_time;
+    }
+
+
+    oc = output_files[0]->ctx;
+
+    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)
+            total_size = 0;
+    }
+
+    buf[0] = '\0';
+    vid = 0;
+    av_bprint_init(&buf_script, 0, 1);
+    for (i = 0; i < nb_output_streams; i++) {
+        float q = -1;
+        ost = output_streams[i];
+        enc = ost->st->codec;
+        if (!ost->stream_copy && enc->coded_frame)
+            q = enc->coded_frame->quality / (float)FF_QP2LAMBDA;
+        if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
+            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q);
+            av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
+                       ost->file_index, ost->index, q);
+        }
+        if (!vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {
+            float fps, t = (cur_time-timer_start) / 1000000.0;
+
+            frame_number = ost->frame_number;
+            fps = t > 1 ? frame_number / t : 0;
+            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3.*f q=%3.1f ",
+                     frame_number, fps < 9.95, fps, q);
+            av_bprintf(&buf_script, "frame=%d\n", frame_number);
+            av_bprintf(&buf_script, "fps=%.1f\n", fps);
+            av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
+                       ost->file_index, ost->index, q);
+            if (is_last_report)
+                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L");
+            if (qp_hist) {
+                int j;
+                int qp = lrintf(q);
+                if (qp >= 0 && qp < FF_ARRAY_ELEMS(qp_histogram))
+                    qp_histogram[qp]++;
+                for (j = 0; j < 32; j++)
+                    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%X", (int)lrintf(log2(qp_histogram[j] + 1)));
+            }
+            if (enc->flags&CODEC_FLAG_PSNR) {
+                int j;
+                double error, error_sum = 0;
+                double scale, scale_sum = 0;
+                double p;
+                char type[3] = { 'Y','U','V' };
+                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "PSNR=");
+                for (j = 0; j < 3; j++) {
+                    if (is_last_report) {
+                        error = enc->error[j];
+                        scale = enc->width * enc->height * 255.0 * 255.0 * frame_number;
+                    } else {
+                        error = enc->coded_frame->error[j];
+                        scale = enc->width * enc->height * 255.0 * 255.0;
+                    }
+                    if (j)
+                        scale /= 4;
+                    error_sum += error;
+                    scale_sum += scale;
+                    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);
+                }
+                p = psnr(error_sum / scale_sum);
+                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "*:%2.2f ", psnr(error_sum / scale_sum));
+                av_bprintf(&buf_script, "stream_%d_%d_psnr_all=%2.2f\n",
+                           ost->file_index, ost->index, p);
+            }
+            vid = 1;
+        }
+        /* compute min output value */
+        if ((is_last_report || !ost->finished) && ost->st->pts.val != AV_NOPTS_VALUE)
+            pts = FFMAX(pts, av_rescale_q(ost->st->pts.val,
+                                          ost->st->time_base, AV_TIME_BASE_Q));
+    }
+
+    secs = pts / AV_TIME_BASE;
+    us = pts % AV_TIME_BASE;
+    mins = secs / 60;
+    secs %= 60;
+    hours = mins / 60;
+    mins %= 60;
+
+    bitrate = pts ? total_size * 8 / (pts / 1000.0) : 0;
+
+    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);
+    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);
+
+    if (nb_frames_dup || nb_frames_drop)
+        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d",
+                nb_frames_dup, nb_frames_drop);
+    av_bprintf(&buf_script, "dup_frames=%d\n", nb_frames_dup);
+    av_bprintf(&buf_script, "drop_frames=%d\n", nb_frames_drop);
+
+    if (print_stats || is_last_report) {
+    av_log(NULL, AV_LOG_INFO, "%s    \r", buf);
+
+    fflush(stderr);
+    }
+
+    if (progress_avio) {
+        av_bprintf(&buf_script, "progress=%s\n",
+                   is_last_report ? "end" : "continue");
+        avio_write(progress_avio, buf_script.str,
+                   FFMIN(buf_script.len, buf_script.size - 1));
+        avio_flush(progress_avio);
+        av_bprint_finalize(&buf_script, NULL);
+        if (is_last_report) {
+            avio_close(progress_avio);
+            progress_avio = NULL;
+        }
+    }
+
+    if (is_last_report) {
+        int64_t raw= audio_size + video_size + subtitle_size + extra_size;
+        av_log(NULL, AV_LOG_INFO, "\n");
+        av_log(NULL, AV_LOG_INFO, "video:%1.0fkB audio:%1.0fkB subtitle:%1.0f global headers:%1.0fkB muxing overhead %f%%\n",
+               video_size / 1024.0,
+               audio_size / 1024.0,
+               subtitle_size / 1024.0,
+               extra_size / 1024.0,
+               100.0 * (total_size - raw) / raw
+        );
+        if(video_size + audio_size + subtitle_size + extra_size == 0){
+            av_log(NULL, AV_LOG_WARNING, "Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)\n");
+        }
+    }
+}
+
+static void flush_encoders(void)
+{
+    int i, ret;
+
+    for (i = 0; i < nb_output_streams; i++) {
+        OutputStream   *ost = output_streams[i];
+        AVCodecContext *enc = ost->st->codec;
+        AVFormatContext *os = output_files[ost->file_index]->ctx;
+        int stop_encoding = 0;
+
+        if (!ost->encoding_needed)
+            continue;
+
+        if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <= 1)
+            continue;
+        if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (os->oformat->flags & AVFMT_RAWPICTURE) && enc->codec->id == AV_CODEC_ID_RAWVIDEO)
+            continue;
+
+        for (;;) {
+            int (*encode)(AVCodecContext*, AVPacket*, const AVFrame*, int*) = NULL;
+            const char *desc;
+            int64_t *size;
+
+            switch (ost->st->codec->codec_type) {
+            case AVMEDIA_TYPE_AUDIO:
+                encode = avcodec_encode_audio2;
+                desc   = "Audio";
+                size   = &audio_size;
+                break;
+            case AVMEDIA_TYPE_VIDEO:
+                encode = avcodec_encode_video2;
+                desc   = "Video";
+                size   = &video_size;
+                break;
+            default:
+                stop_encoding = 1;
+            }
+
+            if (encode) {
+                AVPacket pkt;
+                int got_packet;
+                av_init_packet(&pkt);
+                pkt.data = NULL;
+                pkt.size = 0;
+
+                update_benchmark(NULL);
+                ret = encode(enc, &pkt, NULL, &got_packet);
+                update_benchmark("flush %s %d.%d", desc, ost->file_index, ost->index);
+                if (ret < 0) {
+                    av_log(NULL, AV_LOG_FATAL, "%s encoding failed\n", desc);
+                    exit(1);
+                }
+                *size += pkt.size;
+                if (ost->logfile && enc->stats_out) {
+                    fprintf(ost->logfile, "%s", enc->stats_out);
+                }
+                if (!got_packet) {
+                    stop_encoding = 1;
+                    break;
+                }
+                if (pkt.pts != AV_NOPTS_VALUE)
+                    pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base);
+                if (pkt.dts != AV_NOPTS_VALUE)
+                    pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base);
+                write_frame(os, &pkt, ost);
+            }
+
+            if (stop_encoding)
+                break;
+        }
+    }
+}
+
+/*
+ * Check whether a packet from ist should be written into ost at this time
+ */
+static int check_output_constraints(InputStream *ist, OutputStream *ost)
+{
+    OutputFile *of = output_files[ost->file_index];
+    int ist_index  = input_files[ist->file_index]->ist_index + ist->st->index;
+
+    if (ost->source_index != ist_index)
+        return 0;
+
+    if (of->start_time && ist->pts < of->start_time)
+        return 0;
+
+    return 1;
+}
+
+static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *pkt)
+{
+    OutputFile *of = output_files[ost->file_index];
+    int64_t ost_tb_start_time = av_rescale_q(of->start_time, AV_TIME_BASE_Q, ost->st->time_base);
+    AVPicture pict;
+    AVPacket opkt;
+
+    av_init_packet(&opkt);
+
+    if ((!ost->frame_number && !(pkt->flags & AV_PKT_FLAG_KEY)) &&
+        !ost->copy_initial_nonkeyframes)
+        return;
+
+    if (!ost->frame_number && ist->pts < of->start_time &&
+        !ost->copy_prior_start)
+        return;
+
+    if (of->recording_time != INT64_MAX &&
+        ist->pts >= of->recording_time + of->start_time) {
+        close_output_stream(ost);
+        return;
+    }
+
+    /* force the input stream PTS */
+    if (ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+        audio_size += pkt->size;
+    else if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+        video_size += pkt->size;
+        ost->sync_opts++;
+    } else if (ost->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+        subtitle_size += pkt->size;
+    }
+
+    if (pkt->pts != AV_NOPTS_VALUE)
+        opkt.pts = av_rescale_q(pkt->pts, ist->st->time_base, ost->st->time_base) - ost_tb_start_time;
+    else
+        opkt.pts = AV_NOPTS_VALUE;
+
+    if (pkt->dts == AV_NOPTS_VALUE)
+        opkt.dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ost->st->time_base);
+    else
+        opkt.dts = av_rescale_q(pkt->dts, ist->st->time_base, ost->st->time_base);
+    opkt.dts -= ost_tb_start_time;
+
+    opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base);
+    opkt.flags    = pkt->flags;
+
+    // FIXME remove the following 2 lines they shall be replaced by the bitstream filters
+    if (  ost->st->codec->codec_id != AV_CODEC_ID_H264
+       && ost->st->codec->codec_id != AV_CODEC_ID_MPEG1VIDEO
+       && ost->st->codec->codec_id != AV_CODEC_ID_MPEG2VIDEO
+       && ost->st->codec->codec_id != AV_CODEC_ID_VC1
+       ) {
+        if (av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY))
+            opkt.destruct = av_destruct_packet;
+    } else {
+        opkt.data = pkt->data;
+        opkt.size = pkt->size;
+    }
+
+    if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (of->ctx->oformat->flags & AVFMT_RAWPICTURE)) {
+        /* store AVPicture in AVPacket, as expected by the output format */
+        avpicture_fill(&pict, opkt.data, ost->st->codec->pix_fmt, ost->st->codec->width, ost->st->codec->height);
+        opkt.data = (uint8_t *)&pict;
+        opkt.size = sizeof(AVPicture);
+        opkt.flags |= AV_PKT_FLAG_KEY;
+    }
+
+    write_frame(of->ctx, &opkt, ost);
+    ost->st->codec->frame_number++;
+    av_free_packet(&opkt);
+}
+
+static void rate_emu_sleep(InputStream *ist)
+{
+    if (input_files[ist->file_index]->rate_emu) {
+        int64_t pts = av_rescale(ist->dts, 1000000, AV_TIME_BASE);
+        int64_t now = av_gettime() - ist->start;
+        if (pts > now)
+            av_usleep(pts - now);
+    }
+}
+
+int guess_input_channel_layout(InputStream *ist)
+{
+    AVCodecContext *dec = ist->st->codec;
+
+    if (!dec->channel_layout) {
+        char layout_name[256];
+
+        dec->channel_layout = av_get_default_channel_layout(dec->channels);
+        if (!dec->channel_layout)
+            return 0;
+        av_get_channel_layout_string(layout_name, sizeof(layout_name),
+                                     dec->channels, dec->channel_layout);
+        av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for  Input Stream "
+               "#%d.%d : %s\n", ist->file_index, ist->st->index, layout_name);
+    }
+    return 1;
+}
+
+static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output)
+{
+    AVFrame *decoded_frame;
+    AVCodecContext *avctx = ist->st->codec;
+    int i, ret, resample_changed;
+    AVRational decoded_frame_tb;
+
+    if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
+        return AVERROR(ENOMEM);
+    else
+        avcodec_get_frame_defaults(ist->decoded_frame);
+    decoded_frame = ist->decoded_frame;
+
+    update_benchmark(NULL);
+    ret = avcodec_decode_audio4(avctx, decoded_frame, got_output, pkt);
+    update_benchmark("decode_audio %d.%d", ist->file_index, ist->st->index);
+
+    if (ret >= 0 && avctx->sample_rate <= 0) {
+        av_log(avctx, AV_LOG_ERROR, "Sample rate %d invalid\n", avctx->sample_rate);
+        ret = AVERROR_INVALIDDATA;
+    }
+
+    if (!*got_output || ret < 0) {
+        if (!pkt->size) {
+            for (i = 0; i < ist->nb_filters; i++)
+                av_buffersrc_add_ref(ist->filters[i]->filter, NULL, 0);
+        }
+        return ret;
+    }
+
+#if 1
+    /* increment next_dts to use for the case where the input stream does not
+       have timestamps or there are multiple frames in the packet */
+    ist->next_pts += ((int64_t)AV_TIME_BASE * decoded_frame->nb_samples) /
+                     avctx->sample_rate;
+    ist->next_dts += ((int64_t)AV_TIME_BASE * decoded_frame->nb_samples) /
+                     avctx->sample_rate;
+#endif
+
+    rate_emu_sleep(ist);
+
+    resample_changed = ist->resample_sample_fmt     != decoded_frame->format         ||
+                       ist->resample_channels       != avctx->channels               ||
+                       ist->resample_channel_layout != decoded_frame->channel_layout ||
+                       ist->resample_sample_rate    != decoded_frame->sample_rate;
+    if (resample_changed) {
+        char layout1[64], layout2[64];
+
+        if (!guess_input_channel_layout(ist)) {
+            av_log(NULL, AV_LOG_FATAL, "Unable to find default channel "
+                   "layout for Input Stream #%d.%d\n", ist->file_index,
+                   ist->st->index);
+            exit(1);
+        }
+        decoded_frame->channel_layout = avctx->channel_layout;
+
+        av_get_channel_layout_string(layout1, sizeof(layout1), ist->resample_channels,
+                                     ist->resample_channel_layout);
+        av_get_channel_layout_string(layout2, sizeof(layout2), avctx->channels,
+                                     decoded_frame->channel_layout);
+
+        av_log(NULL, AV_LOG_INFO,
+               "Input stream #%d:%d frame changed from rate:%d fmt:%s ch:%d chl:%s to rate:%d fmt:%s ch:%d chl:%s\n",
+               ist->file_index, ist->st->index,
+               ist->resample_sample_rate,  av_get_sample_fmt_name(ist->resample_sample_fmt),
+               ist->resample_channels, layout1,
+               decoded_frame->sample_rate, av_get_sample_fmt_name(decoded_frame->format),
+               avctx->channels, layout2);
+
+        ist->resample_sample_fmt     = decoded_frame->format;
+        ist->resample_sample_rate    = decoded_frame->sample_rate;
+        ist->resample_channel_layout = decoded_frame->channel_layout;
+        ist->resample_channels       = avctx->channels;
+
+        for (i = 0; i < nb_filtergraphs; i++)
+            if (ist_in_filtergraph(filtergraphs[i], ist)) {
+                FilterGraph *fg = filtergraphs[i];
+                int j;
+                if (configure_filtergraph(fg) < 0) {
+                    av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n");
+                    exit(1);
+                }
+                for (j = 0; j < fg->nb_outputs; j++) {
+                    OutputStream *ost = fg->outputs[j]->ost;
+                    if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
+                        !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE))
+                        av_buffersink_set_frame_size(ost->filter->filter,
+                                                     ost->st->codec->frame_size);
+                }
+            }
+    }
+
+    /* if the decoder provides a pts, use it instead of the last packet pts.
+       the decoder could be delaying output by a packet or more. */
+    if (decoded_frame->pts != AV_NOPTS_VALUE) {
+        ist->dts = ist->next_dts = ist->pts = ist->next_pts = av_rescale_q(decoded_frame->pts, avctx->time_base, AV_TIME_BASE_Q);
+        decoded_frame_tb   = avctx->time_base;
+    } else if (decoded_frame->pkt_pts != AV_NOPTS_VALUE) {
+        decoded_frame->pts = decoded_frame->pkt_pts;
+        pkt->pts           = AV_NOPTS_VALUE;
+        decoded_frame_tb   = ist->st->time_base;
+    } else if (pkt->pts != AV_NOPTS_VALUE) {
+        decoded_frame->pts = pkt->pts;
+        pkt->pts           = AV_NOPTS_VALUE;
+        decoded_frame_tb   = ist->st->time_base;
+    }else {
+        decoded_frame->pts = ist->dts;
+        decoded_frame_tb   = AV_TIME_BASE_Q;
+    }
+    if (decoded_frame->pts != AV_NOPTS_VALUE)
+        decoded_frame->pts = av_rescale_q(decoded_frame->pts,
+                                          decoded_frame_tb,
+                                          (AVRational){1, ist->st->codec->sample_rate});
+    for (i = 0; i < ist->nb_filters; i++)
+        av_buffersrc_add_frame(ist->filters[i]->filter, decoded_frame,
+                               AV_BUFFERSRC_FLAG_PUSH);
+
+    decoded_frame->pts = AV_NOPTS_VALUE;
+
+    return ret;
+}
+
+static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output)
+{
+    AVFrame *decoded_frame;
+    void *buffer_to_free = NULL;
+    int i, ret = 0, resample_changed;
+    int64_t best_effort_timestamp;
+    AVRational *frame_sample_aspect;
+
+    if (!ist->decoded_frame && !(ist->decoded_frame = avcodec_alloc_frame()))
+        return AVERROR(ENOMEM);
+    else
+        avcodec_get_frame_defaults(ist->decoded_frame);
+    decoded_frame = ist->decoded_frame;
+    pkt->dts  = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ist->st->time_base);
+
+    update_benchmark(NULL);
+    ret = avcodec_decode_video2(ist->st->codec,
+                                decoded_frame, got_output, pkt);
+    update_benchmark("decode_video %d.%d", ist->file_index, ist->st->index);
+    if (!*got_output || ret < 0) {
+        if (!pkt->size) {
+            for (i = 0; i < ist->nb_filters; i++)
+                av_buffersrc_add_ref(ist->filters[i]->filter, NULL, 0);
+        }
+        return ret;
+    }
+
+    if(ist->top_field_first>=0)
+        decoded_frame->top_field_first = ist->top_field_first;
+
+    best_effort_timestamp= av_frame_get_best_effort_timestamp(decoded_frame);
+    if(best_effort_timestamp != AV_NOPTS_VALUE)
+        ist->next_pts = ist->pts = av_rescale_q(decoded_frame->pts = best_effort_timestamp, ist->st->time_base, AV_TIME_BASE_Q);
+
+    if (debug_ts) {
+        av_log(NULL, AV_LOG_INFO, "decoder -> ist_index:%d type:video "
+                "frame_pts:%s frame_pts_time:%s best_effort_ts:%"PRId64" best_effort_ts_time:%s keyframe:%d frame_type:%d \n",
+                ist->st->index, av_ts2str(decoded_frame->pts),
+                av_ts2timestr(decoded_frame->pts, &ist->st->time_base),
+                best_effort_timestamp,
+                av_ts2timestr(best_effort_timestamp, &ist->st->time_base),
+                decoded_frame->key_frame, decoded_frame->pict_type);
+    }
+
+    pkt->size = 0;
+    pre_process_video_frame(ist, (AVPicture *)decoded_frame, &buffer_to_free);
+
+    rate_emu_sleep(ist);
+
+    if (ist->st->sample_aspect_ratio.num)
+        decoded_frame->sample_aspect_ratio = ist->st->sample_aspect_ratio;
+
+    resample_changed = ist->resample_width   != decoded_frame->width  ||
+                       ist->resample_height  != decoded_frame->height ||
+                       ist->resample_pix_fmt != decoded_frame->format;
+    if (resample_changed) {
+        av_log(NULL, AV_LOG_INFO,
+               "Input stream #%d:%d frame changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s\n",
+               ist->file_index, ist->st->index,
+               ist->resample_width,  ist->resample_height,  av_get_pix_fmt_name(ist->resample_pix_fmt),
+               decoded_frame->width, decoded_frame->height, av_get_pix_fmt_name(decoded_frame->format));
+
+        ist->resample_width   = decoded_frame->width;
+        ist->resample_height  = decoded_frame->height;
+        ist->resample_pix_fmt = decoded_frame->format;
+
+        for (i = 0; i < nb_filtergraphs; i++)
+            if (ist_in_filtergraph(filtergraphs[i], ist) &&
+                configure_filtergraph(filtergraphs[i]) < 0) {
+                av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n");
+                exit(1);
+            }
+    }
+
+    frame_sample_aspect= av_opt_ptr(avcodec_get_frame_class(), decoded_frame, "sample_aspect_ratio");
+    for (i = 0; i < ist->nb_filters; i++) {
+        int changed =      ist->st->codec->width   != ist->filters[i]->filter->outputs[0]->w
+                        || ist->st->codec->height  != ist->filters[i]->filter->outputs[0]->h
+                        || ist->st->codec->pix_fmt != ist->filters[i]->filter->outputs[0]->format;
+
+        if (!frame_sample_aspect->num)
+            *frame_sample_aspect = ist->st->sample_aspect_ratio;
+        if (ist->dr1 && decoded_frame->type==FF_BUFFER_TYPE_USER && !changed) {
+            FrameBuffer      *buf = decoded_frame->opaque;
+            AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays(
+                                        decoded_frame->data, decoded_frame->linesize,
+                                        AV_PERM_READ | AV_PERM_PRESERVE,
+                                        ist->st->codec->width, ist->st->codec->height,
+                                        ist->st->codec->pix_fmt);
+
+            avfilter_copy_frame_props(fb, decoded_frame);
+            fb->buf->priv           = buf;
+            fb->buf->free           = filter_release_buffer;
+
+            av_assert0(buf->refcount>0);
+            buf->refcount++;
+            av_buffersrc_add_ref(ist->filters[i]->filter, fb,
+                                 AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT |
+                                 AV_BUFFERSRC_FLAG_NO_COPY |
+                                 AV_BUFFERSRC_FLAG_PUSH);
+        } else
+        if(av_buffersrc_add_frame(ist->filters[i]->filter, decoded_frame, AV_BUFFERSRC_FLAG_PUSH)<0) {
+            av_log(NULL, AV_LOG_FATAL, "Failed to inject frame into filter network\n");
+            exit(1);
+        }
+
+    }
+
+    av_free(buffer_to_free);
+    return ret;
+}
+
+static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)
+{
+    AVSubtitle subtitle;
+    int i, ret = avcodec_decode_subtitle2(ist->st->codec,
+                                          &subtitle, got_output, pkt);
+    if (ret < 0 || !*got_output) {
+        if (!pkt->size)
+            sub2video_flush(ist);
+        return ret;
+    }
+
+    if (ist->fix_sub_duration) {
+        if (ist->prev_sub.got_output) {
+            int end = av_rescale(subtitle.pts - ist->prev_sub.subtitle.pts,
+                                 1000, AV_TIME_BASE);
+            if (end < ist->prev_sub.subtitle.end_display_time) {
+                av_log(ist->st->codec, AV_LOG_DEBUG,
+                       "Subtitle duration reduced from %d to %d\n",
+                       ist->prev_sub.subtitle.end_display_time, end);
+                ist->prev_sub.subtitle.end_display_time = end;
+            }
+        }
+        FFSWAP(int,        *got_output, ist->prev_sub.got_output);
+        FFSWAP(int,        ret,         ist->prev_sub.ret);
+        FFSWAP(AVSubtitle, subtitle,    ist->prev_sub.subtitle);
+    }
+
+    sub2video_update(ist, &subtitle);
+
+    if (!*got_output || !subtitle.num_rects)
+        return ret;
+
+    rate_emu_sleep(ist);
+
+    for (i = 0; i < nb_output_streams; i++) {
+        OutputStream *ost = output_streams[i];
+
+        if (!check_output_constraints(ist, ost) || !ost->encoding_needed)
+            continue;
+
+        do_subtitle_out(output_files[ost->file_index]->ctx, ost, ist, &subtitle);
+    }
+
+    avsubtitle_free(&subtitle);
+    return ret;
+}
+
+/* pkt = NULL means EOF (needed to flush decoder buffers) */
+static int output_packet(InputStream *ist, const AVPacket *pkt)
+{
+    int ret = 0, i;
+    int got_output;
+
+    AVPacket avpkt;
+    if (!ist->saw_first_ts) {
+        ist->dts = ist->st->avg_frame_rate.num ? - ist->st->codec->has_b_frames * AV_TIME_BASE / av_q2d(ist->st->avg_frame_rate) : 0;
+        ist->pts = 0;
+        if (pkt != NULL && pkt->pts != AV_NOPTS_VALUE && !ist->decoding_needed) {
+            ist->dts += av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q);
+            ist->pts = ist->dts; //unused but better to set it to a value thats not totally wrong
+        }
+        ist->saw_first_ts = 1;
+    }
+
+    if (ist->next_dts == AV_NOPTS_VALUE)
+        ist->next_dts = ist->dts;
+    if (ist->next_pts == AV_NOPTS_VALUE)
+        ist->next_pts = ist->pts;
+
+    if (pkt == NULL) {
+        /* EOF handling */
+        av_init_packet(&avpkt);
+        avpkt.data = NULL;
+        avpkt.size = 0;
+        goto handle_eof;
+    } else {
+        avpkt = *pkt;
+    }
+
+    if (pkt->dts != AV_NOPTS_VALUE) {
+        ist->next_dts = ist->dts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
+        if (ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO || !ist->decoding_needed)
+            ist->next_pts = ist->pts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q);
+    }
+
+    // while we have more to decode or while the decoder did output something on EOF
+    while (ist->decoding_needed && (avpkt.size > 0 || (!pkt && got_output))) {
+        int duration;
+    handle_eof:
+
+        ist->pts = ist->next_pts;
+        ist->dts = ist->next_dts;
+
+        if (avpkt.size && avpkt.size != pkt->size) {
+            av_log(NULL, ist->showed_multi_packet_warning ? AV_LOG_VERBOSE : AV_LOG_WARNING,
+                   "Multiple frames in a packet from stream %d\n", pkt->stream_index);
+            ist->showed_multi_packet_warning = 1;
+        }
+
+        switch (ist->st->codec->codec_type) {
+        case AVMEDIA_TYPE_AUDIO:
+            ret = decode_audio    (ist, &avpkt, &got_output);
+            break;
+        case AVMEDIA_TYPE_VIDEO:
+            ret = decode_video    (ist, &avpkt, &got_output);
+            if (avpkt.duration) {
+                duration = av_rescale_q(avpkt.duration, ist->st->time_base, AV_TIME_BASE_Q);
+            } else if(ist->st->codec->time_base.num != 0 && ist->st->codec->time_base.den != 0) {
+                int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame;
+                duration = ((int64_t)AV_TIME_BASE *
+                                ist->st->codec->time_base.num * ticks) /
+                                ist->st->codec->time_base.den;
+            } else
+                duration = 0;
+
+            if(ist->dts != AV_NOPTS_VALUE && duration) {
+                ist->next_dts += duration;
+            }else
+                ist->next_dts = AV_NOPTS_VALUE;
+
+            if (got_output)
+                ist->next_pts += duration; //FIXME the duration is not correct in some cases
+            break;
+        case AVMEDIA_TYPE_SUBTITLE:
+            ret = transcode_subtitles(ist, &avpkt, &got_output);
+            break;
+        default:
+            return -1;
+        }
+
+        if (ret < 0)
+            return ret;
+
+        avpkt.dts=
+        avpkt.pts= AV_NOPTS_VALUE;
+
+        // touch data and size only if not EOF
+        if (pkt) {
+            if(ist->st->codec->codec_type != AVMEDIA_TYPE_AUDIO)
+                ret = avpkt.size;
+            avpkt.data += ret;
+            avpkt.size -= ret;
+        }
+        if (!got_output) {
+            continue;
+        }
+    }
+
+    /* handle stream copy */
+    if (!ist->decoding_needed) {
+        rate_emu_sleep(ist);
+        ist->dts = ist->next_dts;
+        switch (ist->st->codec->codec_type) {
+        case AVMEDIA_TYPE_AUDIO:
+            ist->next_dts += ((int64_t)AV_TIME_BASE * ist->st->codec->frame_size) /
+                             ist->st->codec->sample_rate;
+            break;
+        case AVMEDIA_TYPE_VIDEO:
+            if (pkt->duration) {
+                ist->next_dts += av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q);
+            } else if(ist->st->codec->time_base.num != 0) {
+                int ticks= ist->st->parser ? ist->st->parser->repeat_pict + 1 : ist->st->codec->ticks_per_frame;
+                ist->next_dts += ((int64_t)AV_TIME_BASE *
+                                  ist->st->codec->time_base.num * ticks) /
+                                  ist->st->codec->time_base.den;
+            }
+            break;
+        }
+        ist->pts = ist->dts;
+        ist->next_pts = ist->next_dts;
+    }
+    for (i = 0; pkt && i < nb_output_streams; i++) {
+        OutputStream *ost = output_streams[i];
+
+        if (!check_output_constraints(ist, ost) || ost->encoding_needed)
+            continue;
+
+        do_streamcopy(ist, ost, pkt);
+    }
+
+    return 0;
+}
+
+static void print_sdp(void)
+{
+    char sdp[2048];
+    int i;
+    AVFormatContext **avc = av_malloc(sizeof(*avc) * nb_output_files);
+
+    if (!avc)
+        exit(1);
+    for (i = 0; i < nb_output_files; i++)
+        avc[i] = output_files[i]->ctx;
+
+    av_sdp_create(avc, nb_output_files, sdp, sizeof(sdp));
+    printf("SDP:\n%s\n", sdp);
+    fflush(stdout);
+    av_freep(&avc);
+}
+
+static int init_input_stream(int ist_index, char *error, int error_len)
+{
+    InputStream *ist = input_streams[ist_index];
+
+    if (ist->decoding_needed) {
+        AVCodec *codec = ist->dec;
+        if (!codec) {
+            snprintf(error, error_len, "Decoder (codec %s) not found for input stream #%d:%d",
+                    avcodec_get_name(ist->st->codec->codec_id), ist->file_index, ist->st->index);
+            return AVERROR(EINVAL);
+        }
+
+        ist->dr1 = (codec->capabilities & CODEC_CAP_DR1) && !do_deinterlace;
+        if (codec->type == AVMEDIA_TYPE_VIDEO && ist->dr1) {
+            ist->st->codec->get_buffer     = codec_get_buffer;
+            ist->st->codec->release_buffer = codec_release_buffer;
+            ist->st->codec->opaque         = &ist->buffer_pool;
+        }
+
+        if (!av_dict_get(ist->opts, "threads", NULL, 0))
+            av_dict_set(&ist->opts, "threads", "auto", 0);
+        if (avcodec_open2(ist->st->codec, codec, &ist->opts) < 0) {
+            snprintf(error, error_len, "Error while opening decoder for input stream #%d:%d",
+                    ist->file_index, ist->st->index);
+            return AVERROR(EINVAL);
+        }
+        assert_codec_experimental(ist->st->codec, 0);
+        assert_avoptions(ist->opts);
+    }
+
+    ist->next_pts = AV_NOPTS_VALUE;
+    ist->next_dts = AV_NOPTS_VALUE;
+    ist->is_start = 1;
+
+    return 0;
+}
+
+static InputStream *get_input_stream(OutputStream *ost)
+{
+    if (ost->source_index >= 0)
+        return input_streams[ost->source_index];
+    return NULL;
+}
+
+static void parse_forced_key_frames(char *kf, OutputStream *ost,
+                                    AVCodecContext *avctx)
+{
+    char *p;
+    int n = 1, i;
+    int64_t t;
+
+    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) {
+        av_log(NULL, AV_LOG_FATAL, "Could not allocate forced key frames array.\n");
+        exit(1);
+    }
+
+    p = kf;
+    for (i = 0; i < n; i++) {
+        char *next = strchr(p, ',');
+
+        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);
+
+        p = next;
+    }
+}
+
+static void report_new_stream(int input_index, AVPacket *pkt)
+{
+    InputFile *file = input_files[input_index];
+    AVStream *st = file->ctx->streams[pkt->stream_index];
+
+    if (pkt->stream_index < file->nb_streams_warn)
+        return;
+    av_log(file->ctx, AV_LOG_WARNING,
+           "New %s stream %d:%d at pos:%"PRId64" and DTS:%ss\n",
+           av_get_media_type_string(st->codec->codec_type),
+           input_index, pkt->stream_index,
+           pkt->pos, av_ts2timestr(pkt->dts, &st->time_base));
+    file->nb_streams_warn = pkt->stream_index + 1;
+}
+
+static int transcode_init(void)
+{
+    int ret = 0, i, j, k;
+    AVFormatContext *oc;
+    AVCodecContext *codec;
+    OutputStream *ost;
+    InputStream *ist;
+    char error[1024];
+    int want_sdp = 1;
+
+    /* init framerate emulation */
+    for (i = 0; i < nb_input_files; i++) {
+        InputFile *ifile = input_files[i];
+        if (ifile->rate_emu)
+            for (j = 0; j < ifile->nb_streams; j++)
+                input_streams[j + ifile->ist_index]->start = av_gettime();
+    }
+
+    /* output stream init */
+    for (i = 0; i < nb_output_files; i++) {
+        oc = output_files[i]->ctx;
+        if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {
+            av_dump_format(oc, i, oc->filename, 1);
+            av_log(NULL, AV_LOG_ERROR, "Output file #%d does not contain any stream\n", i);
+            return AVERROR(EINVAL);
+        }
+    }
+
+    /* init complex filtergraphs */
+    for (i = 0; i < nb_filtergraphs; i++)
+        if ((ret = avfilter_graph_config(filtergraphs[i]->graph, NULL)) < 0)
+            return ret;
+
+    /* for each output stream, we compute the right encoding parameters */
+    for (i = 0; i < nb_output_streams; i++) {
+        AVCodecContext *icodec = NULL;
+        ost = output_streams[i];
+        oc  = output_files[ost->file_index]->ctx;
+        ist = get_input_stream(ost);
+
+        if (ost->attachment_filename)
+            continue;
+
+        codec  = ost->st->codec;
+
+        if (ist) {
+            icodec = ist->st->codec;
+
+            ost->st->disposition          = ist->st->disposition;
+            codec->bits_per_raw_sample    = icodec->bits_per_raw_sample;
+            codec->chroma_sample_location = icodec->chroma_sample_location;
+        }
+
+        if (ost->stream_copy) {
+            uint64_t extra_size;
+
+            av_assert0(ist && !ost->filter);
+
+            extra_size = (uint64_t)icodec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE;
+
+            if (extra_size > INT_MAX) {
+                return AVERROR(EINVAL);
+            }
+
+            /* if stream_copy is selected, no need to decode or encode */
+            codec->codec_id   = icodec->codec_id;
+            codec->codec_type = icodec->codec_type;
+
+            if (!codec->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)
+                    codec->codec_tag = icodec->codec_tag;
+            }
+
+            codec->bit_rate       = icodec->bit_rate;
+            codec->rc_max_rate    = icodec->rc_max_rate;
+            codec->rc_buffer_size = icodec->rc_buffer_size;
+            codec->field_order    = icodec->field_order;
+            codec->extradata      = av_mallocz(extra_size);
+            if (!codec->extradata) {
+                return AVERROR(ENOMEM);
+            }
+            memcpy(codec->extradata, icodec->extradata, icodec->extradata_size);
+            codec->extradata_size= icodec->extradata_size;
+            codec->bits_per_coded_sample  = icodec->bits_per_coded_sample;
+
+            codec->time_base = ist->st->time_base;
+            /*
+             * Avi is a special case here because it supports variable fps but
+             * having the fps and timebase differe significantly adds quite some
+             * overhead
+             */
+            if(!strcmp(oc->oformat->name, "avi")) {
+                if ( copy_tb<0 && av_q2d(ist->st->r_frame_rate) >= av_q2d(ist->st->avg_frame_rate)
+                               && 0.5/av_q2d(ist->st->r_frame_rate) > av_q2d(ist->st->time_base)
+                               && 0.5/av_q2d(ist->st->r_frame_rate) > av_q2d(icodec->time_base)
+                               && av_q2d(ist->st->time_base) < 1.0/500 && av_q2d(icodec->time_base) < 1.0/500
+                     || copy_tb==2){
+                    codec->time_base.num = ist->st->r_frame_rate.den;
+                    codec->time_base.den = 2*ist->st->r_frame_rate.num;
+                    codec->ticks_per_frame = 2;
+                } else if (   copy_tb<0 && av_q2d(icodec->time_base)*icodec->ticks_per_frame > 2*av_q2d(ist->st->time_base)
+                                 && av_q2d(ist->st->time_base) < 1.0/500
+                    || copy_tb==0){
+                    codec->time_base = icodec->time_base;
+                    codec->time_base.num *= icodec->ticks_per_frame;
+                    codec->time_base.den *= 2;
+                    codec->ticks_per_frame = 2;
+                }
+            } else if(!(oc->oformat->flags & AVFMT_VARIABLE_FPS)
+                      && strcmp(oc->oformat->name, "mov") && strcmp(oc->oformat->name, "mp4") && strcmp(oc->oformat->name, "3gp")
+                      && strcmp(oc->oformat->name, "3g2") && strcmp(oc->oformat->name, "psp") && strcmp(oc->oformat->name, "ipod")
+                      && strcmp(oc->oformat->name, "f4v")
+            ) {
+                if(   copy_tb<0 && icodec->time_base.den
+                                && av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base)
+                                && av_q2d(ist->st->time_base) < 1.0/500
+                   || copy_tb==0){
+                    codec->time_base = icodec->time_base;
+                    codec->time_base.num *= icodec->ticks_per_frame;
+                }
+            }
+
+            if(ost->frame_rate.num)
+                codec->time_base = av_inv_q(ost->frame_rate);
+
+            av_reduce(&codec->time_base.num, &codec->time_base.den,
+                        codec->time_base.num, codec->time_base.den, INT_MAX);
+
+            switch (codec->codec_type) {
+            case AVMEDIA_TYPE_AUDIO:
+                if (audio_volume != 256) {
+                    av_log(NULL, AV_LOG_FATAL, "-acodec copy and -vol are incompatible (frames are not decoded)\n");
+                    exit(1);
+                }
+                codec->channel_layout     = icodec->channel_layout;
+                codec->sample_rate        = icodec->sample_rate;
+                codec->channels           = icodec->channels;
+                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)
+                    codec->block_align= 0;
+                if(codec->codec_id == AV_CODEC_ID_AC3)
+                    codec->block_align= 0;
+                break;
+            case AVMEDIA_TYPE_VIDEO:
+                codec->pix_fmt            = icodec->pix_fmt;
+                codec->width              = icodec->width;
+                codec->height             = icodec->height;
+                codec->has_b_frames       = icodec->has_b_frames;
+                if (!codec->sample_aspect_ratio.num) {
+                    codec->sample_aspect_ratio   =
+                    ost->st->sample_aspect_ratio =
+                        ist->st->sample_aspect_ratio.num ? ist->st->sample_aspect_ratio :
+                        ist->st->codec->sample_aspect_ratio.num ?
+                        ist->st->codec->sample_aspect_ratio : (AVRational){0, 1};
+                }
+                ost->st->avg_frame_rate = ist->st->avg_frame_rate;
+                break;
+            case AVMEDIA_TYPE_SUBTITLE:
+                codec->width  = icodec->width;
+                codec->height = icodec->height;
+                break;
+            case AVMEDIA_TYPE_DATA:
+            case AVMEDIA_TYPE_ATTACHMENT:
+                break;
+            default:
+                abort();
+            }
+        } else {
+            if (!ost->enc)
+                ost->enc = avcodec_find_encoder(codec->codec_id);
+            if (!ost->enc) {
+                /* should only happen when a default codec is not present. */
+                snprintf(error, sizeof(error), "Encoder (codec %s) not found for output stream #%d:%d",
+                         avcodec_get_name(ost->st->codec->codec_id), ost->file_index, ost->index);
+                ret = AVERROR(EINVAL);
+                goto dump_format;
+            }
+
+            if (ist)
+                ist->decoding_needed++;
+            ost->encoding_needed = 1;
+
+            if (!ost->filter &&
+                (codec->codec_type == AVMEDIA_TYPE_VIDEO ||
+                 codec->codec_type == AVMEDIA_TYPE_AUDIO)) {
+                    FilterGraph *fg;
+                    fg = init_simple_filtergraph(ist, ost);
+                    if (configure_filtergraph(fg)) {
+                        av_log(NULL, AV_LOG_FATAL, "Error opening filters!\n");
+                        exit(1);
+                    }
+            }
+
+            if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+                if (ost->filter && !ost->frame_rate.num)
+                    ost->frame_rate = av_buffersink_get_frame_rate(ost->filter->filter);
+                if (ist && !ost->frame_rate.num)
+                    ost->frame_rate = ist->framerate;
+                if (ist && !ost->frame_rate.num)
+                    ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25, 1};
+//                    ost->frame_rate = ist->st->avg_frame_rate.num ? ist->st->avg_frame_rate : (AVRational){25, 1};
+                if (ost->enc && ost->enc->supported_framerates && !ost->force_fps) {
+                    int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates);
+                    ost->frame_rate = ost->enc->supported_framerates[idx];
+                }
+            }
+
+            switch (codec->codec_type) {
+            case AVMEDIA_TYPE_AUDIO:
+                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->time_base      = (AVRational){ 1, codec->sample_rate };
+                break;
+            case AVMEDIA_TYPE_VIDEO:
+                codec->time_base = av_inv_q(ost->frame_rate);
+                if (ost->filter && !(codec->time_base.num && codec->time_base.den))
+                    codec->time_base = ost->filter->filter->inputs[0]->time_base;
+                if (   av_q2d(codec->time_base) < 0.001 && video_sync_method != VSYNC_PASSTHROUGH
+                   && (video_sync_method == VSYNC_CFR || (video_sync_method == VSYNC_AUTO && !(oc->oformat->flags & AVFMT_VARIABLE_FPS)))){
+                    av_log(oc, AV_LOG_WARNING, "Frame rate very high for a muxer not efficiently supporting it.\n"
+                                               "Please consider specifying a lower framerate, a different muxer or -vsync 2\n");
+                }
+                for (j = 0; j < ost->forced_kf_count; j++)
+                    ost->forced_kf_pts[j] = av_rescale_q(ost->forced_kf_pts[j],
+                                                         AV_TIME_BASE_Q,
+                                                         codec->time_base);
+
+                codec->width  = ost->filter->filter->inputs[0]->w;
+                codec->height = ost->filter->filter->inputs[0]->h;
+                codec->sample_aspect_ratio = ost->st->sample_aspect_ratio =
+                    ost->frame_aspect_ratio ? // overridden by the -aspect cli option
+                    av_d2q(ost->frame_aspect_ratio * codec->height/codec->width, 255) :
+                    ost->filter->filter->inputs[0]->sample_aspect_ratio;
+                codec->pix_fmt = ost->filter->filter->inputs[0]->format;
+
+                if (!icodec ||
+                    codec->width   != icodec->width  ||
+                    codec->height  != icodec->height ||
+                    codec->pix_fmt != icodec->pix_fmt) {
+                    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);
+                break;
+            case AVMEDIA_TYPE_SUBTITLE:
+                codec->time_base = (AVRational){1, 1000};
+                if (!codec->width) {
+                    codec->width     = input_streams[ost->source_index]->st->codec->width;
+                    codec->height    = input_streams[ost->source_index]->st->codec->height;
+                }
+                break;
+            default:
+                abort();
+                break;
+            }
+            /* two pass mode */
+            if (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2)) {
+                char logfilename[1024];
+                FILE *f;
+
+                snprintf(logfilename, sizeof(logfilename), "%s-%d.log",
+                         ost->logfile_prefix ? ost->logfile_prefix :
+                                               DEFAULT_PASS_LOGFILENAME_PREFIX,
+                         i);
+                if (!strcmp(ost->enc->name, "libx264")) {
+                    av_dict_set(&ost->opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE);
+                } else {
+                    if (codec->flags & CODEC_FLAG_PASS2) {
+                        char  *logbuffer;
+                        size_t logbuffer_size;
+                        if (cmdutils_read_file(logfilename, &logbuffer, &logbuffer_size) < 0) {
+                            av_log(NULL, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n",
+                                   logfilename);
+                            exit(1);
+                        }
+                        codec->stats_in = logbuffer;
+                    }
+                    if (codec->flags & CODEC_FLAG_PASS1) {
+                        f = fopen(logfilename, "wb");
+                        if (!f) {
+                            av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n",
+                                logfilename, strerror(errno));
+                            exit(1);
+                        }
+                        ost->logfile = f;
+                    }
+                }
+            }
+        }
+    }
+
+    /* open each encoder */
+    for (i = 0; i < nb_output_streams; i++) {
+        ost = output_streams[i];
+        if (ost->encoding_needed) {
+            AVCodec      *codec = ost->enc;
+            AVCodecContext *dec = NULL;
+
+            if ((ist = get_input_stream(ost)))
+                dec = ist->st->codec;
+            if (dec && dec->subtitle_header) {
+                /* ASS code assumes this buffer is null terminated so add extra byte. */
+                ost->st->codec->subtitle_header = av_mallocz(dec->subtitle_header_size + 1);
+                if (!ost->st->codec->subtitle_header) {
+                    ret = AVERROR(ENOMEM);
+                    goto dump_format;
+                }
+                memcpy(ost->st->codec->subtitle_header, dec->subtitle_header, dec->subtitle_header_size);
+                ost->st->codec->subtitle_header_size = dec->subtitle_header_size;
+            }
+            if (!av_dict_get(ost->opts, "threads", NULL, 0))
+                av_dict_set(&ost->opts, "threads", "auto", 0);
+            if (avcodec_open2(ost->st->codec, codec, &ost->opts) < 0) {
+                snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d:%d - maybe incorrect parameters such as bit_rate, rate, width or height",
+                        ost->file_index, ost->index);
+                ret = AVERROR(EINVAL);
+                goto dump_format;
+            }
+            if (ost->enc->type == AVMEDIA_TYPE_AUDIO &&
+                !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE))
+                av_buffersink_set_frame_size(ost->filter->filter,
+                                             ost->st->codec->frame_size);
+            assert_codec_experimental(ost->st->codec, 1);
+            assert_avoptions(ost->opts);
+            if (ost->st->codec->bit_rate && ost->st->codec->bit_rate < 1000)
+                av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."
+                                             " It takes bits/s as argument, not kbits/s\n");
+            extra_size += ost->st->codec->extradata_size;
+
+            if (ost->st->codec->me_threshold)
+                input_streams[ost->source_index]->st->codec->debug |= FF_DEBUG_MV;
+        }
+    }
+
+    /* init input streams */
+    for (i = 0; i < nb_input_streams; i++)
+        if ((ret = init_input_stream(i, error, sizeof(error))) < 0)
+            goto dump_format;
+
+    /* discard unused programs */
+    for (i = 0; i < nb_input_files; i++) {
+        InputFile *ifile = input_files[i];
+        for (j = 0; j < ifile->ctx->nb_programs; j++) {
+            AVProgram *p = ifile->ctx->programs[j];
+            int discard  = AVDISCARD_ALL;
+
+            for (k = 0; k < p->nb_stream_indexes; k++)
+                if (!input_streams[ifile->ist_index + p->stream_index[k]]->discard) {
+                    discard = AVDISCARD_DEFAULT;
+                    break;
+                }
+            p->discard = discard;
+        }
+    }
+
+    /* open files and write file headers */
+    for (i = 0; i < nb_output_files; i++) {
+        oc = output_files[i]->ctx;
+        oc->interrupt_callback = int_cb;
+        if ((ret = avformat_write_header(oc, &output_files[i]->opts)) < 0) {
+            char errbuf[128];
+            const char *errbuf_ptr = errbuf;
+            if (av_strerror(ret, errbuf, sizeof(errbuf)) < 0)
+                errbuf_ptr = strerror(AVUNERROR(ret));
+            snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?): %s", i, errbuf_ptr);
+            ret = AVERROR(EINVAL);
+            goto dump_format;
+        }
+//         assert_avoptions(output_files[i]->opts);
+        if (strcmp(oc->oformat->name, "rtp")) {
+            want_sdp = 0;
+        }
+    }
+
+ dump_format:
+    /* dump the file output parameters - cannot be done before in case
+       of stream copy */
+    for (i = 0; i < nb_output_files; i++) {
+        av_dump_format(output_files[i]->ctx, i, output_files[i]->ctx->filename, 1);
+    }
+
+    /* dump the stream mapping */
+    av_log(NULL, AV_LOG_INFO, "Stream mapping:\n");
+    for (i = 0; i < nb_input_streams; i++) {
+        ist = input_streams[i];
+
+        for (j = 0; j < ist->nb_filters; j++) {
+            if (ist->filters[j]->graph->graph_desc) {
+                av_log(NULL, AV_LOG_INFO, "  Stream #%d:%d (%s) -> %s",
+                       ist->file_index, ist->st->index, ist->dec ? ist->dec->name : "?",
+                       ist->filters[j]->name);
+                if (nb_filtergraphs > 1)
+                    av_log(NULL, AV_LOG_INFO, " (graph %d)", ist->filters[j]->graph->index);
+                av_log(NULL, AV_LOG_INFO, "\n");
+            }
+        }
+    }
+
+    for (i = 0; i < nb_output_streams; i++) {
+        ost = output_streams[i];
+
+        if (ost->attachment_filename) {
+            /* an attached file */
+            av_log(NULL, AV_LOG_INFO, "  File %s -> Stream #%d:%d\n",
+                   ost->attachment_filename, ost->file_index, ost->index);
+            continue;
+        }
+
+        if (ost->filter && ost->filter->graph->graph_desc) {
+            /* output from a complex graph */
+            av_log(NULL, AV_LOG_INFO, "  %s", ost->filter->name);
+            if (nb_filtergraphs > 1)
+                av_log(NULL, AV_LOG_INFO, " (graph %d)", ost->filter->graph->index);
+
+            av_log(NULL, AV_LOG_INFO, " -> Stream #%d:%d (%s)\n", ost->file_index,
+                   ost->index, ost->enc ? ost->enc->name : "?");
+            continue;
+        }
+
+        av_log(NULL, AV_LOG_INFO, "  Stream #%d:%d -> #%d:%d",
+               input_streams[ost->source_index]->file_index,
+               input_streams[ost->source_index]->st->index,
+               ost->file_index,
+               ost->index);
+        if (ost->sync_ist != input_streams[ost->source_index])
+            av_log(NULL, AV_LOG_INFO, " [sync #%d:%d]",
+                   ost->sync_ist->file_index,
+                   ost->sync_ist->st->index);
+        if (ost->stream_copy)
+            av_log(NULL, AV_LOG_INFO, " (copy)");
+        else
+            av_log(NULL, AV_LOG_INFO, " (%s -> %s)", input_streams[ost->source_index]->dec ?
+                   input_streams[ost->source_index]->dec->name : "?",
+                   ost->enc ? ost->enc->name : "?");
+        av_log(NULL, AV_LOG_INFO, "\n");
+    }
+
+    if (ret) {
+        av_log(NULL, AV_LOG_ERROR, "%s\n", error);
+        return ret;
+    }
+
+    if (want_sdp) {
+        print_sdp();
+    }
+
+    return 0;
+}
+
+/* Return 1 if there remain streams where more output is wanted, 0 otherwise. */
+static int need_output(void)
+{
+    int i;
+
+    for (i = 0; i < nb_output_streams; i++) {
+        OutputStream *ost    = output_streams[i];
+        OutputFile *of       = output_files[ost->file_index];
+        AVFormatContext *os  = output_files[ost->file_index]->ctx;
+
+        if (ost->finished ||
+            (os->pb && avio_tell(os->pb) >= of->limit_filesize))
+            continue;
+        if (ost->frame_number >= ost->max_frames) {
+            int j;
+            for (j = 0; j < of->ctx->nb_streams; j++)
+                close_output_stream(output_streams[of->ost_index + j]);
+            continue;
+        }
+
+        return 1;
+    }
+
+    return 0;
+}
+
+/**
+ * Select the output stream to process.
+ *
+ * @return  selected output stream, or NULL if none available
+ */
+static OutputStream *choose_output(void)
+{
+    int i;
+    int64_t opts_min = INT64_MAX;
+    OutputStream *ost_min = NULL;
+
+    for (i = 0; i < nb_output_streams; i++) {
+        OutputStream *ost = output_streams[i];
+        int64_t opts = av_rescale_q(ost->st->cur_dts, ost->st->time_base,
+                                    AV_TIME_BASE_Q);
+        if (!ost->unavailable && !ost->finished && opts < opts_min) {
+            opts_min = opts;
+            ost_min  = ost;
+        }
+    }
+    return ost_min;
+}
+
+static int check_keyboard_interaction(int64_t cur_time)
+{
+    int i, ret, key;
+    static int64_t last_time;
+    if (received_nb_signals)
+        return AVERROR_EXIT;
+    /* read_key() returns 0 on EOF */
+    if(cur_time - last_time >= 100000 && !run_as_daemon){
+        key =  read_key();
+        last_time = cur_time;
+    }else
+        key = -1;
+    if (key == 'q')
+        return AVERROR_EXIT;
+    if (key == '+') av_log_set_level(av_log_get_level()+10);
+    if (key == '-') av_log_set_level(av_log_get_level()-10);
+    if (key == 's') qp_hist     ^= 1;
+    if (key == 'h'){
+        if (do_hex_dump){
+            do_hex_dump = do_pkt_dump = 0;
+        } else if(do_pkt_dump){
+            do_hex_dump = 1;
+        } else
+            do_pkt_dump = 1;
+        av_log_set_level(AV_LOG_DEBUG);
+    }
+    if (key == 'c' || key == 'C'){
+        char buf[4096], target[64], command[256], arg[256] = {0};
+        double time;
+        int k, n = 0;
+        fprintf(stderr, "\nEnter command: <target> <time> <command>[ <argument>]\n");
+        i = 0;
+        while ((k = read_key()) != '\n' && k != '\r' && i < sizeof(buf)-1)
+            if (k > 0)
+                buf[i++] = k;
+        buf[i] = 0;
+        if (k > 0 &&
+            (n = sscanf(buf, "%63[^ ] %lf %255[^ ] %255[^\n]", target, &time, command, arg)) >= 3) {
+            av_log(NULL, AV_LOG_DEBUG, "Processing command target:%s time:%f command:%s arg:%s",
+                   target, time, command, arg);
+            for (i = 0; i < nb_filtergraphs; i++) {
+                FilterGraph *fg = filtergraphs[i];
+                if (fg->graph) {
+                    if (time < 0) {
+                        ret = avfilter_graph_send_command(fg->graph, target, command, arg, buf, sizeof(buf),
+                                                          key == 'c' ? AVFILTER_CMD_FLAG_ONE : 0);
+                        fprintf(stderr, "Command reply for stream %d: ret:%d res:%s\n", i, ret, buf);
+                    } else {
+                        ret = avfilter_graph_queue_command(fg->graph, target, command, arg, 0, time);
+                    }
+                }
+            }
+        } else {
+            av_log(NULL, AV_LOG_ERROR,
+                   "Parse error, at least 3 arguments were expected, "
+                   "only %d given in string '%s'\n", n, buf);
+        }
+    }
+    if (key == 'd' || key == 'D'){
+        int debug=0;
+        if(key == 'D') {
+            debug = input_streams[0]->st->codec->debug<<1;
+            if(!debug) debug = 1;
+            while(debug & (FF_DEBUG_DCT_COEFF|FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) //unsupported, would just crash
+                debug += debug;
+        }else
+            if(scanf("%d", &debug)!=1)
+                fprintf(stderr,"error parsing debug value\n");
+        for(i=0;i<nb_input_streams;i++) {
+            input_streams[i]->st->codec->debug = debug;
+        }
+        for(i=0;i<nb_output_streams;i++) {
+            OutputStream *ost = output_streams[i];
+            ost->st->codec->debug = debug;
+        }
+        if(debug) av_log_set_level(AV_LOG_DEBUG);
+        fprintf(stderr,"debug=%d\n", debug);
+    }
+    if (key == '?'){
+        fprintf(stderr, "key    function\n"
+                        "?      show this help\n"
+                        "+      increase verbosity\n"
+                        "-      decrease verbosity\n"
+                        "c      Send command to filtergraph\n"
+                        "D      cycle through available debug modes\n"
+                        "h      dump packets/hex press to cycle through the 3 states\n"
+                        "q      quit\n"
+                        "s      Show QP histogram\n"
+        );
+    }
+    return 0;
+}
+
+#if HAVE_PTHREADS
+static void *input_thread(void *arg)
+{
+    InputFile *f = arg;
+    int ret = 0;
+
+    while (!transcoding_finished && ret >= 0) {
+        AVPacket pkt;
+        ret = av_read_frame(f->ctx, &pkt);
+
+        if (ret == AVERROR(EAGAIN)) {
+            av_usleep(10000);
+            ret = 0;
+            continue;
+        } else if (ret < 0)
+            break;
+
+        pthread_mutex_lock(&f->fifo_lock);
+        while (!av_fifo_space(f->fifo))
+            pthread_cond_wait(&f->fifo_cond, &f->fifo_lock);
+
+        av_dup_packet(&pkt);
+        av_fifo_generic_write(f->fifo, &pkt, sizeof(pkt), NULL);
+
+        pthread_mutex_unlock(&f->fifo_lock);
+    }
+
+    f->finished = 1;
+    return NULL;
+}
+
+static void free_input_threads(void)
+{
+    int i;
+
+    if (nb_input_files == 1)
+        return;
+
+    transcoding_finished = 1;
+
+    for (i = 0; i < nb_input_files; i++) {
+        InputFile *f = input_files[i];
+        AVPacket pkt;
+
+        if (!f->fifo || f->joined)
+            continue;
+
+        pthread_mutex_lock(&f->fifo_lock);
+        while (av_fifo_size(f->fifo)) {
+            av_fifo_generic_read(f->fifo, &pkt, sizeof(pkt), NULL);
+            av_free_packet(&pkt);
+        }
+        pthread_cond_signal(&f->fifo_cond);
+        pthread_mutex_unlock(&f->fifo_lock);
+
+        pthread_join(f->thread, NULL);
+        f->joined = 1;
+
+        while (av_fifo_size(f->fifo)) {
+            av_fifo_generic_read(f->fifo, &pkt, sizeof(pkt), NULL);
+            av_free_packet(&pkt);
+        }
+        av_fifo_free(f->fifo);
+    }
+}
+
+static int init_input_threads(void)
+{
+    int i, ret;
+
+    if (nb_input_files == 1)
+        return 0;
+
+    for (i = 0; i < nb_input_files; i++) {
+        InputFile *f = input_files[i];
+
+        if (!(f->fifo = av_fifo_alloc(8*sizeof(AVPacket))))
+            return AVERROR(ENOMEM);
+
+        pthread_mutex_init(&f->fifo_lock, NULL);
+        pthread_cond_init (&f->fifo_cond, NULL);
+
+        if ((ret = pthread_create(&f->thread, NULL, input_thread, f)))
+            return AVERROR(ret);
+    }
+    return 0;
+}
+
+static int get_input_packet_mt(InputFile *f, AVPacket *pkt)
+{
+    int ret = 0;
+
+    pthread_mutex_lock(&f->fifo_lock);
+
+    if (av_fifo_size(f->fifo)) {
+        av_fifo_generic_read(f->fifo, pkt, sizeof(*pkt), NULL);
+        pthread_cond_signal(&f->fifo_cond);
+    } else {
+        if (f->finished)
+            ret = AVERROR_EOF;
+        else
+            ret = AVERROR(EAGAIN);
+    }
+
+    pthread_mutex_unlock(&f->fifo_lock);
+
+    return ret;
+}
+#endif
+
+static int get_input_packet(InputFile *f, AVPacket *pkt)
+{
+#if HAVE_PTHREADS
+    if (nb_input_files > 1)
+        return get_input_packet_mt(f, pkt);
+#endif
+    return av_read_frame(f->ctx, pkt);
+}
+
+static int got_eagain(void)
+{
+    int i;
+    for (i = 0; i < nb_output_streams; i++)
+        if (output_streams[i]->unavailable)
+            return 1;
+    return 0;
+}
+
+static void reset_eagain(void)
+{
+    int i;
+    for (i = 0; i < nb_input_files; i++)
+        input_files[i]->eagain = 0;
+    for (i = 0; i < nb_output_streams; i++)
+        output_streams[i]->unavailable = 0;
+}
+
+/*
+ * Return
+ * - 0 -- one packet was read and processed
+ * - AVERROR(EAGAIN) -- no packets were available for selected file,
+ *   this function should be called again
+ * - AVERROR_EOF -- this function should not be called again
+ */
+static int process_input(int file_index)
+{
+    InputFile *ifile = input_files[file_index];
+    AVFormatContext *is;
+    InputStream *ist;
+    AVPacket pkt;
+    int ret, i, j;
+
+    is  = ifile->ctx;
+    ret = get_input_packet(ifile, &pkt);
+
+    if (ret == AVERROR(EAGAIN)) {
+        ifile->eagain = 1;
+        return ret;
+    }
+    if (ret < 0) {
+        if (ret != AVERROR_EOF) {
+            print_error(is->filename, ret);
+            if (exit_on_error)
+                exit(1);
+        }
+        ifile->eof_reached = 1;
+
+        for (i = 0; i < ifile->nb_streams; i++) {
+            ist = input_streams[ifile->ist_index + i];
+            if (ist->decoding_needed)
+                output_packet(ist, NULL);
+
+            /* mark all outputs that don't go through lavfi as finished */
+            for (j = 0; j < nb_output_streams; j++) {
+                OutputStream *ost = output_streams[j];
+
+                if (ost->source_index == ifile->ist_index + i &&
+                    (ost->stream_copy || ost->enc->type == AVMEDIA_TYPE_SUBTITLE))
+                    close_output_stream(ost);
+            }
+        }
+
+        return AVERROR(EAGAIN);
+    }
+
+    reset_eagain();
+
+    if (do_pkt_dump) {
+        av_pkt_dump_log2(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump,
+                         is->streams[pkt.stream_index]);
+    }
+    /* the following test is needed in case new streams appear
+       dynamically in stream : we ignore them */
+    if (pkt.stream_index >= ifile->nb_streams) {
+        report_new_stream(file_index, &pkt);
+        goto discard_packet;
+    }
+
+    ist = input_streams[ifile->ist_index + pkt.stream_index];
+    if (ist->discard)
+        goto discard_packet;
+
+    if(!ist->wrap_correction_done && input_files[file_index]->ctx->start_time != AV_NOPTS_VALUE && ist->st->pts_wrap_bits < 64){
+        int64_t stime = av_rescale_q(input_files[file_index]->ctx->start_time, AV_TIME_BASE_Q, ist->st->time_base);
+        int64_t stime2= stime + (1ULL<<ist->st->pts_wrap_bits);
+        ist->wrap_correction_done = 1;
+
+        if(stime2 > stime && pkt.dts != AV_NOPTS_VALUE && pkt.dts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) {
+            pkt.dts -= 1ULL<<ist->st->pts_wrap_bits;
+            ist->wrap_correction_done = 0;
+        }
+        if(stime2 > stime && pkt.pts != AV_NOPTS_VALUE && pkt.pts > stime + (1LL<<(ist->st->pts_wrap_bits-1))) {
+            pkt.pts -= 1ULL<<ist->st->pts_wrap_bits;
+            ist->wrap_correction_done = 0;
+        }
+    }
+
+    if (pkt.dts != AV_NOPTS_VALUE)
+        pkt.dts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
+    if (pkt.pts != AV_NOPTS_VALUE)
+        pkt.pts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base);
+
+    if (pkt.pts != AV_NOPTS_VALUE)
+        pkt.pts *= ist->ts_scale;
+    if (pkt.dts != AV_NOPTS_VALUE)
+        pkt.dts *= ist->ts_scale;
+
+    if (debug_ts) {
+        av_log(NULL, AV_LOG_INFO, "demuxer -> ist_index:%d type:%s "
+                "next_dts:%s next_dts_time:%s next_pts:%s next_pts_time:%s  pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s off:%"PRId64"\n",
+                ifile->ist_index + pkt.stream_index, av_get_media_type_string(ist->st->codec->codec_type),
+                av_ts2str(ist->next_dts), av_ts2timestr(ist->next_dts, &AV_TIME_BASE_Q),
+                av_ts2str(ist->next_pts), av_ts2timestr(ist->next_pts, &AV_TIME_BASE_Q),
+                av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ist->st->time_base),
+                av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ist->st->time_base),
+                input_files[ist->file_index]->ts_offset);
+    }
+
+    if (pkt.dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE &&
+        !copy_ts) {
+        int64_t pkt_dts = av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);
+        int64_t delta   = pkt_dts - ist->next_dts;
+        if (is->iformat->flags & AVFMT_TS_DISCONT) {
+        if(delta < -1LL*dts_delta_threshold*AV_TIME_BASE ||
+            (delta > 1LL*dts_delta_threshold*AV_TIME_BASE &&
+                ist->st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) ||
+            pkt_dts+1<ist->pts){
+            ifile->ts_offset -= delta;
+            av_log(NULL, AV_LOG_DEBUG,
+                   "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",
+                   delta, ifile->ts_offset);
+            pkt.dts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
+            if (pkt.pts != AV_NOPTS_VALUE)
+                pkt.pts -= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);
+        }
+        } else {
+            if ( delta < -1LL*dts_error_threshold*AV_TIME_BASE ||
+                (delta > 1LL*dts_error_threshold*AV_TIME_BASE && ist->st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE)
+               ) {
+                av_log(NULL, AV_LOG_WARNING, "DTS %"PRId64", next:%"PRId64" st:%d invalid dropping\n", pkt.dts, ist->next_dts, pkt.stream_index);
+                pkt.dts = AV_NOPTS_VALUE;
+            }
+            if (pkt.pts != AV_NOPTS_VALUE){
+                int64_t pkt_pts = av_rescale_q(pkt.pts, ist->st->time_base, AV_TIME_BASE_Q);
+                delta   = pkt_pts - ist->next_dts;
+                if ( delta < -1LL*dts_error_threshold*AV_TIME_BASE ||
+                    (delta > 1LL*dts_error_threshold*AV_TIME_BASE && ist->st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE)
+                   ) {
+                    av_log(NULL, AV_LOG_WARNING, "PTS %"PRId64", next:%"PRId64" invalid dropping st:%d\n", pkt.pts, ist->next_dts, pkt.stream_index);
+                    pkt.pts = AV_NOPTS_VALUE;
+                }
+            }
+        }
+    }
+
+    sub2video_heartbeat(ist, pkt.pts);
+
+    ret = output_packet(ist, &pkt);
+    if (ret < 0) {
+        char buf[128];
+        av_strerror(ret, buf, sizeof(buf));
+        av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d: %s\n",
+                ist->file_index, ist->st->index, buf);
+        if (exit_on_error)
+            exit(1);
+    }
+
+discard_packet:
+    av_free_packet(&pkt);
+
+    return 0;
+}
+
+/**
+ * Perform a step of transcoding for the specified filter graph.
+ *
+ * @param[in]  graph     filter graph to consider
+ * @param[out] best_ist  input stream where a frame would allow to continue
+ * @return  0 for success, <0 for error
+ */
+static int transcode_from_filter(FilterGraph *graph, InputStream **best_ist)
+{
+    int i, ret;
+    int nb_requests, nb_requests_max = 0;
+    InputFilter *ifilter;
+    InputStream *ist;
+
+    *best_ist = NULL;
+    ret = avfilter_graph_request_oldest(graph->graph);
+    if (ret >= 0)
+        return reap_filters();
+
+    if (ret == AVERROR_EOF) {
+        ret = reap_filters();
+        for (i = 0; i < graph->nb_outputs; i++)
+            close_output_stream(graph->outputs[i]->ost);
+        return ret;
+    }
+    if (ret != AVERROR(EAGAIN))
+        return ret;
+
+    for (i = 0; i < graph->nb_inputs; i++) {
+        ifilter = graph->inputs[i];
+        ist = ifilter->ist;
+        if (input_files[ist->file_index]->eagain ||
+            input_files[ist->file_index]->eof_reached)
+            continue;
+        nb_requests = av_buffersrc_get_nb_failed_requests(ifilter->filter);
+        if (nb_requests > nb_requests_max) {
+            nb_requests_max = nb_requests;
+            *best_ist = ist;
+        }
+    }
+
+    if (!*best_ist)
+        for (i = 0; i < graph->nb_outputs; i++)
+            graph->outputs[i]->ost->unavailable = 1;
+
+    return 0;
+}
+
+/**
+ * Run a single step of transcoding.
+ *
+ * @return  0 for success, <0 for error
+ */
+static int transcode_step(void)
+{
+    OutputStream *ost;
+    InputStream  *ist;
+    int ret;
+
+    ost = choose_output();
+    if (!ost) {
+        if (got_eagain()) {
+            reset_eagain();
+            av_usleep(10000);
+            return 0;
+        }
+        av_log(NULL, AV_LOG_VERBOSE, "No more inputs to read from, finishing.\n");
+        return AVERROR_EOF;
+    }
+
+    if (ost->filter) {
+        if ((ret = transcode_from_filter(ost->filter->graph, &ist)) < 0)
+            return ret;
+        if (!ist)
+            return 0;
+    } else {
+        av_assert0(ost->source_index >= 0);
+        ist = input_streams[ost->source_index];
+    }
+
+    ret = process_input(ist->file_index);
+    if (ret == AVERROR(EAGAIN)) {
+        if (input_files[ist->file_index]->eagain)
+            ost->unavailable = 1;
+        return 0;
+    }
+    if (ret < 0)
+        return ret == AVERROR_EOF ? 0 : ret;
+
+    return reap_filters();
+}
+
+/*
+ * The following code is the main loop of the file converter
+ */
+static int transcode(void)
+{
+    int ret, i;
+    AVFormatContext *os;
+    OutputStream *ost;
+    InputStream *ist;
+    int64_t timer_start;
+
+    ret = transcode_init();
+    if (ret < 0)
+        goto fail;
+
+    if (stdin_interaction) {
+        av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n");
+    }
+
+    timer_start = av_gettime();
+
+#if HAVE_PTHREADS
+    if ((ret = init_input_threads()) < 0)
+        goto fail;
+#endif
+
+    while (!received_sigterm) {
+        int64_t cur_time= av_gettime();
+
+        /* if 'q' pressed, exits */
+        if (stdin_interaction)
+            if (check_keyboard_interaction(cur_time) < 0)
+                break;
+
+        /* check if there's any stream where output is still needed */
+        if (!need_output()) {
+            av_log(NULL, AV_LOG_VERBOSE, "No more output streams to write to, finishing.\n");
+            break;
+        }
+
+        ret = transcode_step();
+        if (ret < 0) {
+            if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
+                continue;
+
+            av_log(NULL, AV_LOG_ERROR, "Error while filtering.\n");
+            break;
+        }
+
+        /* dump report by using the output first video and audio streams */
+        print_report(0, timer_start, cur_time);
+    }
+#if HAVE_PTHREADS
+    free_input_threads();
+#endif
+
+    /* at the end of stream, we must flush the decoder buffers */
+    for (i = 0; i < nb_input_streams; i++) {
+        ist = input_streams[i];
+        if (!input_files[ist->file_index]->eof_reached && ist->decoding_needed) {
+            output_packet(ist, NULL);
+        }
+    }
+    flush_encoders();
+
+    term_exit();
+
+    /* write the trailer if needed and close file */
+    for (i = 0; i < nb_output_files; i++) {
+        os = output_files[i]->ctx;
+        av_write_trailer(os);
+    }
+
+    /* dump report by using the first video and audio streams */
+    print_report(1, timer_start, av_gettime());
+
+    /* close each encoder */
+    for (i = 0; i < nb_output_streams; i++) {
+        ost = output_streams[i];
+        if (ost->encoding_needed) {
+            av_freep(&ost->st->codec->stats_in);
+            avcodec_close(ost->st->codec);
+        }
+    }
+
+    /* close each decoder */
+    for (i = 0; i < nb_input_streams; i++) {
+        ist = input_streams[i];
+        if (ist->decoding_needed) {
+            avcodec_close(ist->st->codec);
+        }
+    }
+
+    /* finished ! */
+    ret = 0;
+
+ fail:
+#if HAVE_PTHREADS
+    free_input_threads();
+#endif
+
+    if (output_streams) {
+        for (i = 0; i < nb_output_streams; i++) {
+            ost = output_streams[i];
+            if (ost) {
+                if (ost->stream_copy)
+                    av_freep(&ost->st->codec->extradata);
+                if (ost->logfile) {
+                    fclose(ost->logfile);
+                    ost->logfile = NULL;
+                }
+                av_freep(&ost->st->codec->subtitle_header);
+                av_free(ost->forced_kf_pts);
+                av_dict_free(&ost->opts);
+            }
+        }
+    }
+    return ret;
+}
+
+
+static int64_t getutime(void)
+{
+#if HAVE_GETRUSAGE
+    struct rusage rusage;
+
+    getrusage(RUSAGE_SELF, &rusage);
+    return (rusage.ru_utime.tv_sec * 1000000LL) + rusage.ru_utime.tv_usec;
+#elif HAVE_GETPROCESSTIMES
+    HANDLE proc;
+    FILETIME c, e, k, u;
+    proc = GetCurrentProcess();
+    GetProcessTimes(proc, &c, &e, &k, &u);
+    return ((int64_t) u.dwHighDateTime << 32 | u.dwLowDateTime) / 10;
+#else
+    return av_gettime();
+#endif
+}
+
+static int64_t getmaxrss(void)
+{
+#if HAVE_GETRUSAGE && HAVE_STRUCT_RUSAGE_RU_MAXRSS
+    struct rusage rusage;
+    getrusage(RUSAGE_SELF, &rusage);
+    return (int64_t)rusage.ru_maxrss * 1024;
+#elif HAVE_GETPROCESSMEMORYINFO
+    HANDLE proc;
+    PROCESS_MEMORY_COUNTERS memcounters;
+    proc = GetCurrentProcess();
+    memcounters.cb = sizeof(memcounters);
+    GetProcessMemoryInfo(proc, &memcounters, sizeof(memcounters));
+    return memcounters.PeakPagefileUsage;
+#else
+    return 0;
+#endif
+}
+
+static void log_callback_null(void *ptr, int level, const char *fmt, va_list vl)
+{
+}
+
+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 };
+    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);
+    parse_loglevel(argc, argv, options);
+
+    if(argc>1 && !strcmp(argv[1], "-d")){
+        run_as_daemon=1;
+        av_log_set_callback(log_callback_null);
+        argc--;
+        argv++;
+    }
+
+    avcodec_register_all();
+#if CONFIG_AVDEVICE
+    avdevice_register_all();
+#endif
+    avfilter_register_all();
+    av_register_all();
+    avformat_network_init();
+
+    show_banner(argc, argv, options);
+
+    term_init();
+
+    parse_cpuflags(argc, argv, options);
+
+    /* parse options */
+    parse_options(&o, argc, argv, options, opt_output_file);
+
+    if (nb_output_files <= 0 && nb_input_files == 0) {
+        show_usage();
+        av_log(NULL, AV_LOG_WARNING, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
+        exit(1);
+    }
+
+    /* file converter / grab */
+    if (nb_output_files <= 0) {
+        av_log(NULL, AV_LOG_FATAL, "At least one output file must be specified\n");
+        exit(1);
+    }
+
+//     if (nb_input_files == 0) {
+//         av_log(NULL, AV_LOG_FATAL, "At least one input file must be specified\n");
+//         exit(1);
+//     }
+
+    current_time = ti = getutime();
+    if (transcode() < 0)
+        exit(1);
+    ti = getutime() - ti;
+    if (do_benchmark) {
+        int maxrss = getmaxrss() / 1024;
+        printf("bench: utime=%0.3fs maxrss=%ikB\n", ti / 1000000.0, maxrss);
+    }
+
+    exit(0);
+    return 0;
+}
diff --git a/ffmpeg.h b/ffmpeg.h
new file mode 100644
index 0000000..e1b223f
--- /dev/null
+++ b/ffmpeg.h
@@ -0,0 +1,407 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef FFMPEG_H
+#define FFMPEG_H
+
+#include "config.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <signal.h>
+
+#if HAVE_PTHREADS
+#include <pthread.h>
+#endif
+
+#include "cmdutils.h"
+
+#include "libavformat/avformat.h"
+#include "libavformat/avio.h"
+
+#include "libavcodec/avcodec.h"
+
+#include "libavfilter/avfilter.h"
+#include "libavfilter/avfiltergraph.h"
+
+#include "libavutil/avutil.h"
+#include "libavutil/dict.h"
+#include "libavutil/fifo.h"
+#include "libavutil/pixfmt.h"
+#include "libavutil/rational.h"
+
+#include "libswresample/swresample.h"
+
+#define VSYNC_AUTO       -1
+#define VSYNC_PASSTHROUGH 0
+#define VSYNC_CFR         1
+#define VSYNC_VFR         2
+#define VSYNC_DROP        0xff
+
+#define MAX_STREAMS 1024    /* arbitrary sanity check value */
+
+/* select an input stream for an output stream */
+typedef struct StreamMap {
+    int disabled;           /* 1 is this mapping is disabled by a negative map */
+    int file_index;
+    int stream_index;
+    int sync_file_index;
+    int sync_stream_index;
+    char *linklabel;       /* name of an output link, for mapping lavfi outputs */
+} StreamMap;
+
+typedef struct {
+    int  file_idx,  stream_idx,  channel_idx; // input
+    int ofile_idx, ostream_idx;               // output
+} AudioChannelMap;
+
+typedef struct OptionsContext {
+    /* input/output options */
+    int64_t start_time;
+    const char *format;
+
+    SpecifierOpt *codec_names;
+    int        nb_codec_names;
+    SpecifierOpt *audio_channels;
+    int        nb_audio_channels;
+    SpecifierOpt *audio_sample_rate;
+    int        nb_audio_sample_rate;
+    SpecifierOpt *frame_rates;
+    int        nb_frame_rates;
+    SpecifierOpt *frame_sizes;
+    int        nb_frame_sizes;
+    SpecifierOpt *frame_pix_fmts;
+    int        nb_frame_pix_fmts;
+
+    /* input options */
+    int64_t input_ts_offset;
+    int rate_emu;
+
+    SpecifierOpt *ts_scale;
+    int        nb_ts_scale;
+    SpecifierOpt *dump_attachment;
+    int        nb_dump_attachment;
+
+    /* output options */
+    StreamMap *stream_maps;
+    int     nb_stream_maps;
+    AudioChannelMap *audio_channel_maps; /* one info entry per -map_channel */
+    int           nb_audio_channel_maps; /* number of (valid) -map_channel settings */
+    int metadata_global_manual;
+    int metadata_streams_manual;
+    int metadata_chapters_manual;
+    const char **attachments;
+    int       nb_attachments;
+
+    int chapters_input_file;
+
+    int64_t recording_time;
+    uint64_t limit_filesize;
+    float mux_preload;
+    float mux_max_delay;
+    int shortest;
+
+    int video_disable;
+    int audio_disable;
+    int subtitle_disable;
+    int data_disable;
+
+    /* indexed by output file stream index */
+    int   *streamid_map;
+    int nb_streamid_map;
+
+    SpecifierOpt *metadata;
+    int        nb_metadata;
+    SpecifierOpt *max_frames;
+    int        nb_max_frames;
+    SpecifierOpt *bitstream_filters;
+    int        nb_bitstream_filters;
+    SpecifierOpt *codec_tags;
+    int        nb_codec_tags;
+    SpecifierOpt *sample_fmts;
+    int        nb_sample_fmts;
+    SpecifierOpt *qscale;
+    int        nb_qscale;
+    SpecifierOpt *forced_key_frames;
+    int        nb_forced_key_frames;
+    SpecifierOpt *force_fps;
+    int        nb_force_fps;
+    SpecifierOpt *frame_aspect_ratios;
+    int        nb_frame_aspect_ratios;
+    SpecifierOpt *rc_overrides;
+    int        nb_rc_overrides;
+    SpecifierOpt *intra_matrices;
+    int        nb_intra_matrices;
+    SpecifierOpt *inter_matrices;
+    int        nb_inter_matrices;
+    SpecifierOpt *top_field_first;
+    int        nb_top_field_first;
+    SpecifierOpt *metadata_map;
+    int        nb_metadata_map;
+    SpecifierOpt *presets;
+    int        nb_presets;
+    SpecifierOpt *copy_initial_nonkeyframes;
+    int        nb_copy_initial_nonkeyframes;
+    SpecifierOpt *copy_prior_start;
+    int        nb_copy_prior_start;
+    SpecifierOpt *filters;
+    int        nb_filters;
+    SpecifierOpt *fix_sub_duration;
+    int        nb_fix_sub_duration;
+    SpecifierOpt *pass;
+    int        nb_pass;
+    SpecifierOpt *passlogfiles;
+    int        nb_passlogfiles;
+} OptionsContext;
+
+typedef struct InputFilter {
+    AVFilterContext    *filter;
+    struct InputStream *ist;
+    struct FilterGraph *graph;
+    uint8_t            *name;
+} InputFilter;
+
+typedef struct OutputFilter {
+    AVFilterContext     *filter;
+    struct OutputStream *ost;
+    struct FilterGraph  *graph;
+    uint8_t             *name;
+
+    /* temporary storage until stream maps are processed */
+    AVFilterInOut       *out_tmp;
+} OutputFilter;
+
+typedef struct FilterGraph {
+    int            index;
+    const char    *graph_desc;
+
+    AVFilterGraph *graph;
+
+    InputFilter   **inputs;
+    int          nb_inputs;
+    OutputFilter **outputs;
+    int         nb_outputs;
+} FilterGraph;
+
+typedef struct InputStream {
+    int file_index;
+    AVStream *st;
+    int discard;             /* true if stream data should be discarded */
+    int decoding_needed;     /* true if the packets must be decoded in 'raw_fifo' */
+    AVCodec *dec;
+    AVFrame *decoded_frame;
+
+    int64_t       start;     /* time when read started */
+    /* predicted dts of the next packet read for this stream or (when there are
+     * several frames in a packet) of the next frame in current packet (in AV_TIME_BASE units) */
+    int64_t       next_dts;
+    int64_t       dts;       ///< dts of the last packet read for this stream (in AV_TIME_BASE units)
+
+    int64_t       next_pts;  ///< synthetic pts for the next decode frame (in AV_TIME_BASE units)
+    int64_t       pts;       ///< current pts of the decoded frame  (in AV_TIME_BASE units)
+    int           wrap_correction_done;
+    double ts_scale;
+    int is_start;            /* is 1 at the start and after a discontinuity */
+    int saw_first_ts;
+    int showed_multi_packet_warning;
+    AVDictionary *opts;
+    AVRational framerate;               /* framerate forced with -r */
+    int top_field_first;
+
+    int resample_height;
+    int resample_width;
+    int resample_pix_fmt;
+
+    int      resample_sample_fmt;
+    int      resample_sample_rate;
+    int      resample_channels;
+    uint64_t resample_channel_layout;
+
+    int fix_sub_duration;
+    struct { /* previous decoded subtitle and related variables */
+        int got_output;
+        int ret;
+        AVSubtitle subtitle;
+    } prev_sub;
+
+    struct sub2video {
+        int64_t last_pts;
+        AVFilterBufferRef *ref;
+        int w, h;
+    } sub2video;
+
+    /* a pool of free buffers for decoded data */
+    FrameBuffer *buffer_pool;
+    int dr1;
+
+    /* decoded data from this stream goes into all those filters
+     * currently video and audio only */
+    InputFilter **filters;
+    int        nb_filters;
+} InputStream;
+
+typedef struct InputFile {
+    AVFormatContext *ctx;
+    int eof_reached;      /* true if eof reached */
+    int eagain;           /* true if last read attempt returned EAGAIN */
+    int ist_index;        /* index of first stream in input_streams */
+    int64_t ts_offset;
+    int nb_streams;       /* number of stream that ffmpeg is aware of; may be different
+                             from ctx.nb_streams if new streams appear during av_read_frame() */
+    int nb_streams_warn;  /* number of streams that the user was warned of */
+    int rate_emu;
+
+#if HAVE_PTHREADS
+    pthread_t thread;           /* thread reading from this file */
+    int finished;               /* the thread has exited */
+    int joined;                 /* the thread has been joined */
+    pthread_mutex_t fifo_lock;  /* lock for access to fifo */
+    pthread_cond_t  fifo_cond;  /* the main thread will signal on this cond after reading from fifo */
+    AVFifoBuffer *fifo;         /* demuxed packets are stored here; freed by the main thread */
+#endif
+} InputFile;
+
+typedef struct OutputStream {
+    int file_index;          /* file index */
+    int index;               /* stream index in the output file */
+    int source_index;        /* InputStream index */
+    AVStream *st;            /* stream in the output file */
+    int encoding_needed;     /* true if encoding needed for this stream */
+    int frame_number;
+    /* input pts and corresponding output pts
+       for A/V sync */
+    struct InputStream *sync_ist; /* input stream to sync against */
+    int64_t sync_opts;       /* output frame counter, could be changed to some true timestamp */ // FIXME look at frame_number
+    /* pts of the first frame encoded for this stream, used for limiting
+     * recording time */
+    int64_t first_pts;
+    AVBitStreamFilterContext *bitstream_filters;
+    AVCodec *enc;
+    int64_t max_frames;
+    AVFrame *filtered_frame;
+
+    /* video only */
+    AVRational frame_rate;
+    int force_fps;
+    int top_field_first;
+
+    float frame_aspect_ratio;
+
+    /* forced key frames */
+    int64_t *forced_kf_pts;
+    int forced_kf_count;
+    int forced_kf_index;
+    char *forced_keyframes;
+
+    /* audio only */
+    int audio_channels_map[SWR_CH_MAX];  /* list of the channels id to pick from the source stream */
+    int audio_channels_mapped;           /* number of channels in audio_channels_map */
+
+    char *logfile_prefix;
+    FILE *logfile;
+
+    OutputFilter *filter;
+    char *avfilter;
+
+    int64_t sws_flags;
+    int64_t swr_dither_method;
+    double swr_dither_scale;
+    AVDictionary *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;
+    const char *attachment_filename;
+    int copy_initial_nonkeyframes;
+    int copy_prior_start;
+
+    int keep_pix_fmt;
+} OutputStream;
+
+typedef struct OutputFile {
+    AVFormatContext *ctx;
+    AVDictionary *opts;
+    int ost_index;       /* index of the first stream in output_streams */
+    int64_t recording_time;  ///< desired length of the resulting file in microseconds == AV_TIME_BASE units
+    int64_t start_time;      ///< start time in microseconds == AV_TIME_BASE units
+    uint64_t limit_filesize; /* filesize limit expressed in bytes */
+
+    int shortest;
+} OutputFile;
+
+extern InputStream **input_streams;
+extern int        nb_input_streams;
+extern InputFile   **input_files;
+extern int        nb_input_files;
+
+extern OutputStream **output_streams;
+extern int         nb_output_streams;
+extern OutputFile   **output_files;
+extern int         nb_output_files;
+
+extern FilterGraph **filtergraphs;
+extern int        nb_filtergraphs;
+
+extern char *vstats_filename;
+
+extern float audio_drift_threshold;
+extern float dts_delta_threshold;
+extern float dts_error_threshold;
+
+extern int audio_volume;
+extern int audio_sync_method;
+extern int video_sync_method;
+extern int do_benchmark;
+extern int do_benchmark_all;
+extern int do_deinterlace;
+extern int do_hex_dump;
+extern int do_pkt_dump;
+extern int copy_ts;
+extern int copy_tb;
+extern int debug_ts;
+extern int exit_on_error;
+extern int print_stats;
+extern int qp_hist;
+extern int stdin_interaction;
+extern int frame_bits_per_raw_sample;
+extern AVIOContext *progress_avio;
+
+extern const AVIOInterruptCB int_cb;
+
+extern const OptionDef options[];
+
+void term_init(void);
+void term_exit(void);
+
+void reset_options(OptionsContext *o, int is_input);
+void show_usage(void);
+
+void opt_output_file(void *optctx, const char *filename);
+
+void assert_avoptions(AVDictionary *m);
+
+int guess_input_channel_layout(InputStream *ist);
+
+enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodec *codec, enum AVPixelFormat target);
+void choose_sample_fmt(AVStream *st, AVCodec *codec);
+
+int configure_filtergraph(FilterGraph *fg);
+int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out);
+int ist_in_filtergraph(FilterGraph *fg, InputStream *ist);
+FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost);
+
+#endif /* FFMPEG_H */
diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c
new file mode 100644
index 0000000..436cdf2
--- /dev/null
+++ b/ffmpeg_filter.c
@@ -0,0 +1,772 @@
+/*
+ * ffmpeg filter configuration
+ *
+ * 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 "ffmpeg.h"
+
+#include "libavfilter/avfilter.h"
+#include "libavfilter/avfiltergraph.h"
+#include "libavfilter/buffersink.h"
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/pixfmt.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/samplefmt.h"
+
+enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodec *codec, enum AVPixelFormat target)
+{
+    if (codec && codec->pix_fmts) {
+        const enum AVPixelFormat *p = codec->pix_fmts;
+        int has_alpha= av_pix_fmt_descriptors[target].nb_components % 2 == 0;
+        enum AVPixelFormat best= AV_PIX_FMT_NONE;
+        if (st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
+            if (st->codec->codec_id == AV_CODEC_ID_MJPEG) {
+                p = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE };
+            } else if (st->codec->codec_id == AV_CODEC_ID_LJPEG) {
+                p = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUV420P,
+                                                 AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
+            }
+        }
+        for (; *p != AV_PIX_FMT_NONE; p++) {
+            best= avcodec_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL);
+            if (*p == target)
+                break;
+        }
+        if (*p == AV_PIX_FMT_NONE) {
+            if (target != AV_PIX_FMT_NONE)
+                av_log(NULL, AV_LOG_WARNING,
+                       "Incompatible pixel format '%s' for codec '%s', auto-selecting format '%s'\n",
+                       av_pix_fmt_descriptors[target].name,
+                       codec->name,
+                       av_pix_fmt_descriptors[best].name);
+            return best;
+        }
+    }
+    return target;
+}
+
+void choose_sample_fmt(AVStream *st, AVCodec *codec)
+{
+    if (codec && codec->sample_fmts) {
+        const enum AVSampleFormat *p = codec->sample_fmts;
+        for (; *p != -1; p++) {
+            if (*p == st->codec->sample_fmt)
+                break;
+        }
+        if (*p == -1) {
+            if((codec->capabilities & CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codec->sample_fmt) > av_get_sample_fmt_name(codec->sample_fmts[0]))
+                av_log(NULL, AV_LOG_ERROR, "Conversion will not be lossless.\n");
+            if(av_get_sample_fmt_name(st->codec->sample_fmt))
+            av_log(NULL, AV_LOG_WARNING,
+                   "Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n",
+                   av_get_sample_fmt_name(st->codec->sample_fmt),
+                   codec->name,
+                   av_get_sample_fmt_name(codec->sample_fmts[0]));
+            st->codec->sample_fmt = codec->sample_fmts[0];
+        }
+    }
+}
+
+static char *choose_pix_fmts(OutputStream *ost)
+{
+     if (ost->keep_pix_fmt) {
+        if (ost->filter)
+            avfilter_graph_set_auto_convert(ost->filter->graph->graph,
+                                            AVFILTER_AUTO_CONVERT_NONE);
+        if (ost->st->codec->pix_fmt == AV_PIX_FMT_NONE)
+            return NULL;
+        return av_strdup(av_get_pix_fmt_name(ost->st->codec->pix_fmt));
+    }
+    if (ost->st->codec->pix_fmt != AV_PIX_FMT_NONE) {
+        return av_strdup(av_get_pix_fmt_name(choose_pixel_fmt(ost->st, ost->enc, ost->st->codec->pix_fmt)));
+    } else if (ost->enc && ost->enc->pix_fmts) {
+        const enum AVPixelFormat *p;
+        AVIOContext *s = NULL;
+        uint8_t *ret;
+        int len;
+
+        if (avio_open_dyn_buf(&s) < 0)
+            exit(1);
+
+        p = ost->enc->pix_fmts;
+        if (ost->st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
+            if (ost->st->codec->codec_id == AV_CODEC_ID_MJPEG) {
+                p = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE };
+            } else if (ost->st->codec->codec_id == AV_CODEC_ID_LJPEG) {
+                p = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUV420P,
+                                                    AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE };
+            }
+        }
+
+        for (; *p != AV_PIX_FMT_NONE; p++) {
+            const char *name = av_get_pix_fmt_name(*p);
+            avio_printf(s, "%s:", name);
+        }
+        len = avio_close_dyn_buf(s, &ret);
+        ret[len - 1] = 0;
+        return ret;
+    } else
+        return NULL;
+}
+
+/* Define a function for building a string containing a list of
+ * allowed formats. */
+#define DEF_CHOOSE_FORMAT(type, var, supported_list, none, get_name, separator)\
+static char *choose_ ## var ## s(OutputStream *ost)                            \
+{                                                                              \
+    if (ost->st->codec->var != none) {                                         \
+        get_name(ost->st->codec->var);                                         \
+        return av_strdup(name);                                                \
+    } else if (ost->enc->supported_list) {                                     \
+        const type *p;                                                         \
+        AVIOContext *s = NULL;                                                 \
+        uint8_t *ret;                                                          \
+        int len;                                                               \
+                                                                               \
+        if (avio_open_dyn_buf(&s) < 0)                                         \
+            exit(1);                                                           \
+                                                                               \
+        for (p = ost->enc->supported_list; *p != none; p++) {                  \
+            get_name(*p);                                                      \
+            avio_printf(s, "%s" separator, name);                              \
+        }                                                                      \
+        len = avio_close_dyn_buf(s, &ret);                                     \
+        ret[len - 1] = 0;                                                      \
+        return ret;                                                            \
+    } else                                                                     \
+        return NULL;                                                           \
+}
+
+// DEF_CHOOSE_FORMAT(enum AVPixelFormat, pix_fmt, pix_fmts, AV_PIX_FMT_NONE,
+//                   GET_PIX_FMT_NAME, ":")
+
+DEF_CHOOSE_FORMAT(enum AVSampleFormat, sample_fmt, sample_fmts,
+                  AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME, ",")
+
+DEF_CHOOSE_FORMAT(int, sample_rate, supported_samplerates, 0,
+                  GET_SAMPLE_RATE_NAME, ",")
+
+DEF_CHOOSE_FORMAT(uint64_t, channel_layout, channel_layouts, 0,
+                  GET_CH_LAYOUT_NAME, ",")
+
+FilterGraph *init_simple_filtergraph(InputStream *ist, OutputStream *ost)
+{
+    FilterGraph *fg = av_mallocz(sizeof(*fg));
+
+    if (!fg)
+        exit(1);
+    fg->index = nb_filtergraphs;
+
+    fg->outputs = grow_array(fg->outputs, sizeof(*fg->outputs), &fg->nb_outputs,
+                             fg->nb_outputs + 1);
+    if (!(fg->outputs[0] = av_mallocz(sizeof(*fg->outputs[0]))))
+        exit(1);
+    fg->outputs[0]->ost   = ost;
+    fg->outputs[0]->graph = fg;
+
+    ost->filter = fg->outputs[0];
+
+    fg->inputs = grow_array(fg->inputs, sizeof(*fg->inputs), &fg->nb_inputs,
+                            fg->nb_inputs + 1);
+    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);
+    ist->filters[ist->nb_filters - 1] = fg->inputs[0];
+
+    filtergraphs = grow_array(filtergraphs, sizeof(*filtergraphs),
+                              &nb_filtergraphs, nb_filtergraphs + 1);
+    filtergraphs[nb_filtergraphs - 1] = fg;
+
+    return fg;
+}
+
+static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
+{
+    InputStream *ist = NULL;
+    enum AVMediaType type = avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx);
+    int i;
+
+    // TODO: support other filter types
+    if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) {
+        av_log(NULL, AV_LOG_FATAL, "Only video and audio filters supported "
+               "currently.\n");
+        exit(1);
+    }
+
+    if (in->name) {
+        AVFormatContext *s;
+        AVStream       *st = NULL;
+        char *p;
+        int file_idx = strtol(in->name, &p, 0);
+
+        if (file_idx < 0 || file_idx >= nb_input_files) {
+            av_log(NULL, AV_LOG_FATAL, "Invalid file index %d in filtergraph description %s.\n",
+                   file_idx, fg->graph_desc);
+            exit(1);
+        }
+        s = input_files[file_idx]->ctx;
+
+        for (i = 0; i < s->nb_streams; i++) {
+            enum AVMediaType stream_type = s->streams[i]->codec->codec_type;
+            if (stream_type != type &&
+                !(stream_type == AVMEDIA_TYPE_SUBTITLE &&
+                  type == AVMEDIA_TYPE_VIDEO /* sub2video hack */))
+                continue;
+            if (check_stream_specifier(s, s->streams[i], *p == ':' ? p + 1 : p) == 1) {
+                st = s->streams[i];
+                break;
+            }
+        }
+        if (!st) {
+            av_log(NULL, AV_LOG_FATAL, "Stream specifier '%s' in filtergraph description %s "
+                   "matches no streams.\n", p, fg->graph_desc);
+            exit(1);
+        }
+        ist = input_streams[input_files[file_idx]->ist_index + st->index];
+    } else {
+        /* find the first unused stream of corresponding type */
+        for (i = 0; i < nb_input_streams; i++) {
+            ist = input_streams[i];
+            if (ist->st->codec->codec_type == type && ist->discard)
+                break;
+        }
+        if (i == nb_input_streams) {
+            av_log(NULL, AV_LOG_FATAL, "Cannot find a matching stream for "
+                   "unlabeled input pad %d on filter %s\n", in->pad_idx,
+                   in->filter_ctx->name);
+            exit(1);
+        }
+    }
+    av_assert0(ist);
+
+    ist->discard         = 0;
+    ist->decoding_needed++;
+    ist->st->discard = AVDISCARD_NONE;
+
+    fg->inputs = grow_array(fg->inputs, sizeof(*fg->inputs),
+                            &fg->nb_inputs, fg->nb_inputs + 1);
+    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);
+    ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
+}
+
+static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
+{
+    char *pix_fmts;
+    OutputStream *ost = ofilter->ost;
+    AVCodecContext *codec = ost->st->codec;
+    AVFilterContext *last_filter = out->filter_ctx;
+    int pad_idx = out->pad_idx;
+    int ret;
+    char name[255];
+    AVBufferSinkParams *buffersink_params = av_buffersink_params_alloc();
+
+    snprintf(name, sizeof(name), "output stream %d:%d", ost->file_index, ost->index);
+    ret = avfilter_graph_create_filter(&ofilter->filter,
+                                       avfilter_get_by_name("ffbuffersink"),
+                                       name, NULL, NULL, fg->graph);
+    av_freep(&buffersink_params);
+
+    if (ret < 0)
+        return ret;
+
+    if (codec->width || codec->height) {
+        char args[255];
+        AVFilterContext *filter;
+
+        snprintf(args, sizeof(args), "%d:%d:flags=0x%X",
+                 codec->width,
+                 codec->height,
+                 (unsigned)ost->sws_flags);
+        snprintf(name, sizeof(name), "scaler for output stream %d:%d",
+                 ost->file_index, ost->index);
+        if ((ret = avfilter_graph_create_filter(&filter, avfilter_get_by_name("scale"),
+                                                name, args, NULL, fg->graph)) < 0)
+            return ret;
+        if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
+            return ret;
+
+        last_filter = filter;
+        pad_idx = 0;
+    }
+
+    if ((pix_fmts = choose_pix_fmts(ost))) {
+        AVFilterContext *filter;
+        snprintf(name, sizeof(name), "pixel format for output stream %d:%d",
+                 ost->file_index, ost->index);
+        if ((ret = avfilter_graph_create_filter(&filter,
+                                                avfilter_get_by_name("format"),
+                                                "format", pix_fmts, NULL,
+                                                fg->graph)) < 0)
+            return ret;
+        if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
+            return ret;
+
+        last_filter = filter;
+        pad_idx     = 0;
+        av_freep(&pix_fmts);
+    }
+
+    if (ost->frame_rate.num && 0) {
+        AVFilterContext *fps;
+        char args[255];
+
+        snprintf(args, sizeof(args), "fps=%d/%d", ost->frame_rate.num,
+                 ost->frame_rate.den);
+        snprintf(name, sizeof(name), "fps for output stream %d:%d",
+                 ost->file_index, ost->index);
+        ret = avfilter_graph_create_filter(&fps, avfilter_get_by_name("fps"),
+                                           name, args, NULL, fg->graph);
+        if (ret < 0)
+            return ret;
+
+        ret = avfilter_link(last_filter, pad_idx, fps, 0);
+        if (ret < 0)
+            return ret;
+        last_filter = fps;
+        pad_idx = 0;
+    }
+
+    if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
+        return ret;
+
+    return 0;
+}
+
+static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
+{
+    OutputStream *ost = ofilter->ost;
+    AVCodecContext *codec  = ost->st->codec;
+    AVFilterContext *last_filter = out->filter_ctx;
+    int pad_idx = out->pad_idx;
+    char *sample_fmts, *sample_rates, *channel_layouts;
+    char name[255];
+    int ret;
+
+
+    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);
+    if (ret < 0)
+        return ret;
+
+#define AUTO_INSERT_FILTER(opt_name, filter_name, arg) do {                 \
+    AVFilterContext *filt_ctx;                                              \
+                                                                            \
+    av_log(NULL, AV_LOG_INFO, opt_name " is forwarded to lavfi "            \
+           "similarly to -af " filter_name "=%s.\n", arg);                  \
+                                                                            \
+    ret = avfilter_graph_create_filter(&filt_ctx,                           \
+                                       avfilter_get_by_name(filter_name),   \
+                                       filter_name, arg, NULL, fg->graph);  \
+    if (ret < 0)                                                            \
+        return ret;                                                         \
+                                                                            \
+    ret = avfilter_link(last_filter, pad_idx, filt_ctx, 0);                 \
+    if (ret < 0)                                                            \
+        return ret;                                                         \
+                                                                            \
+    last_filter = filt_ctx;                                                 \
+    pad_idx = 0;                                                            \
+} while (0)
+    if (ost->audio_channels_mapped) {
+        int i;
+        AVBPrint pan_buf;
+        av_bprint_init(&pan_buf, 256, 8192);
+        av_bprintf(&pan_buf, "0x%"PRIx64,
+                   av_get_default_channel_layout(ost->audio_channels_mapped));
+        for (i = 0; i < ost->audio_channels_mapped; i++)
+            if (ost->audio_channels_map[i] != -1)
+                av_bprintf(&pan_buf, ":c%d=c%d", i, ost->audio_channels_map[i]);
+
+        AUTO_INSERT_FILTER("-map_channel", "pan", pan_buf.str);
+        av_bprint_finalize(&pan_buf, NULL);
+    }
+
+    if (codec->channels && !codec->channel_layout)
+        codec->channel_layout = av_get_default_channel_layout(codec->channels);
+
+    sample_fmts     = choose_sample_fmts(ost);
+    sample_rates    = choose_sample_rates(ost);
+    channel_layouts = choose_channel_layouts(ost);
+    if (sample_fmts || sample_rates || channel_layouts) {
+        AVFilterContext *format;
+        char args[256];
+        args[0] = 0;
+
+        if (sample_fmts)
+            av_strlcatf(args, sizeof(args), "sample_fmts=%s:",
+                            sample_fmts);
+        if (sample_rates)
+            av_strlcatf(args, sizeof(args), "sample_rates=%s:",
+                            sample_rates);
+        if (channel_layouts)
+            av_strlcatf(args, sizeof(args), "channel_layouts=%s:",
+                            channel_layouts);
+
+        av_freep(&sample_fmts);
+        av_freep(&sample_rates);
+        av_freep(&channel_layouts);
+
+        snprintf(name, sizeof(name), "audio format for output stream %d:%d",
+                 ost->file_index, ost->index);
+        ret = avfilter_graph_create_filter(&format,
+                                           avfilter_get_by_name("aformat"),
+                                           name, args, NULL, fg->graph);
+        if (ret < 0)
+            return ret;
+
+        ret = avfilter_link(last_filter, pad_idx, format, 0);
+        if (ret < 0)
+            return ret;
+
+        last_filter = format;
+        pad_idx = 0;
+    }
+
+    if (audio_volume != 256 && 0) {
+        char args[256];
+
+        snprintf(args, sizeof(args), "%f", audio_volume / 256.);
+        AUTO_INSERT_FILTER("-vol", "volume", args);
+    }
+
+    if ((ret = avfilter_link(last_filter, pad_idx, ofilter->filter, 0)) < 0)
+        return ret;
+
+    return 0;
+}
+
+#define DESCRIBE_FILTER_LINK(f, inout, in)                         \
+{                                                                  \
+    AVFilterContext *ctx = inout->filter_ctx;                      \
+    AVFilterPad *pads = in ? ctx->input_pads  : ctx->output_pads;  \
+    int       nb_pads = in ? ctx->input_count : ctx->output_count; \
+    AVIOContext *pb;                                               \
+                                                                   \
+    if (avio_open_dyn_buf(&pb) < 0)                                \
+        exit(1);                                                   \
+                                                                   \
+    avio_printf(pb, "%s", ctx->filter->name);                      \
+    if (nb_pads > 1)                                               \
+        avio_printf(pb, ":%s", avfilter_pad_get_name(pads, inout->pad_idx));\
+    avio_w8(pb, 0);                                                \
+    avio_close_dyn_buf(pb, &f->name);                              \
+}
+
+int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
+{
+    av_freep(&ofilter->name);
+    DESCRIBE_FILTER_LINK(ofilter, out, 0);
+
+    switch (avfilter_pad_get_type(out->filter_ctx->output_pads, out->pad_idx)) {
+    case AVMEDIA_TYPE_VIDEO: return configure_output_video_filter(fg, ofilter, out);
+    case AVMEDIA_TYPE_AUDIO: return configure_output_audio_filter(fg, ofilter, out);
+    default: av_assert0(0);
+    }
+}
+
+static int sub2video_prepare(InputStream *ist)
+{
+    AVFormatContext *avf = input_files[ist->file_index]->ctx;
+    int i, ret, w, h;
+    uint8_t *image[4];
+    int linesize[4];
+
+    /* Compute the size of the canvas for the subtitles stream.
+       If the subtitles codec has set a size, use it. Otherwise use the
+       maximum dimensions of the video streams in the same file. */
+    w = ist->st->codec->width;
+    h = ist->st->codec->height;
+    if (!(w && h)) {
+        for (i = 0; i < avf->nb_streams; i++) {
+            if (avf->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+                w = FFMAX(w, avf->streams[i]->codec->width);
+                h = FFMAX(h, avf->streams[i]->codec->height);
+            }
+        }
+        if (!(w && h)) {
+            w = FFMAX(w, 720);
+            h = FFMAX(h, 576);
+        }
+        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;
+
+    /* 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;
+
+    ret = av_image_alloc(image, linesize, w, h, AV_PIX_FMT_RGB32, 32);
+    if (ret < 0)
+        return ret;
+    memset(image[0], 0, h * linesize[0]);
+    ist->sub2video.ref = avfilter_get_video_buffer_ref_from_arrays(
+            image, linesize, AV_PERM_READ | AV_PERM_PRESERVE,
+            w, h, AV_PIX_FMT_RGB32);
+    if (!ist->sub2video.ref) {
+        av_free(image[0]);
+        return AVERROR(ENOMEM);
+    }
+    return 0;
+}
+
+static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
+                                        AVFilterInOut *in)
+{
+    AVFilterContext *first_filter = in->filter_ctx;
+    AVFilter *filter = avfilter_get_by_name("buffer");
+    InputStream *ist = ifilter->ist;
+    AVRational tb = ist->framerate.num ? av_inv_q(ist->framerate) :
+                                         ist->st->time_base;
+    AVRational fr = ist->framerate.num ? ist->framerate :
+                                         ist->st->r_frame_rate;
+    AVRational sar;
+    AVBPrint args;
+    char name[255];
+    int pad_idx = in->pad_idx;
+    int ret;
+
+    if (ist->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+        ret = sub2video_prepare(ist);
+        if (ret < 0)
+            return ret;
+    }
+
+    sar = ist->st->sample_aspect_ratio.num ?
+          ist->st->sample_aspect_ratio :
+          ist->st->codec->sample_aspect_ratio;
+    if(!sar.den)
+        sar = (AVRational){0,1};
+    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,
+             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)
+        av_bprintf(&args, ":frame_rate=%d/%d", fr.num, fr.den);
+    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.str, NULL, fg->graph)) < 0)
+        return ret;
+
+    if (ist->framerate.num) {
+        AVFilterContext *setpts;
+
+        snprintf(name, sizeof(name), "force CFR for input from stream %d:%d",
+                 ist->file_index, ist->st->index);
+        if ((ret = avfilter_graph_create_filter(&setpts,
+                                                avfilter_get_by_name("setpts"),
+                                                name, "N", NULL,
+                                                fg->graph)) < 0)
+            return ret;
+
+        if ((ret = avfilter_link(setpts, 0, first_filter, pad_idx)) < 0)
+            return ret;
+
+        first_filter = setpts;
+        pad_idx = 0;
+    }
+
+    if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0)
+        return ret;
+    return 0;
+}
+
+static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
+                                        AVFilterInOut *in)
+{
+    AVFilterContext *first_filter = in->filter_ctx;
+    AVFilter *filter = avfilter_get_by_name("abuffer");
+    InputStream *ist = ifilter->ist;
+    int pad_idx = in->pad_idx;
+    char args[255], name[255];
+    int ret;
+
+    snprintf(args, sizeof(args), "time_base=%d/%d:sample_rate=%d:sample_fmt=%s"
+             ":channel_layout=0x%"PRIx64,
+             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);
+    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,
+                                            fg->graph)) < 0)
+        return ret;
+
+#define AUTO_INSERT_FILTER_INPUT(opt_name, filter_name, arg) do {                 \
+    AVFilterContext *filt_ctx;                                              \
+                                                                            \
+    av_log(NULL, AV_LOG_INFO, opt_name " is forwarded to lavfi "            \
+           "similarly to -af " filter_name "=%s.\n", arg);                  \
+                                                                            \
+    snprintf(name, sizeof(name), "graph %d %s for input stream %d:%d",      \
+                fg->index, filter_name, ist->file_index, ist->st->index);   \
+    ret = avfilter_graph_create_filter(&filt_ctx,                           \
+                                       avfilter_get_by_name(filter_name),   \
+                                       name, arg, NULL, fg->graph);         \
+    if (ret < 0)                                                            \
+        return ret;                                                         \
+                                                                            \
+    ret = avfilter_link(filt_ctx, 0, first_filter, pad_idx);                \
+    if (ret < 0)                                                            \
+        return ret;                                                         \
+                                                                            \
+    first_filter = filt_ctx;                                                  \
+} while (0)
+
+    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);
+        AUTO_INSERT_FILTER_INPUT("-async", "aresample", args);
+    }
+
+//     if (ost->audio_channels_mapped) {
+//         int i;
+//         AVBPrint pan_buf;
+//         av_bprint_init(&pan_buf, 256, 8192);
+//         av_bprintf(&pan_buf, "0x%"PRIx64,
+//                    av_get_default_channel_layout(ost->audio_channels_mapped));
+//         for (i = 0; i < ost->audio_channels_mapped; i++)
+//             if (ost->audio_channels_map[i] != -1)
+//                 av_bprintf(&pan_buf, ":c%d=c%d", i, ost->audio_channels_map[i]);
+//         AUTO_INSERT_FILTER_INPUT("-map_channel", "pan", pan_buf.str);
+//         av_bprint_finalize(&pan_buf, NULL);
+//     }
+
+    if (audio_volume != 256) {
+        char args[256];
+
+        snprintf(args, sizeof(args), "%f", audio_volume / 256.);
+        AUTO_INSERT_FILTER_INPUT("-vol", "volume", args);
+    }
+    if ((ret = avfilter_link(ifilter->filter, 0, first_filter, pad_idx)) < 0)
+        return ret;
+
+    return 0;
+}
+
+static int configure_input_filter(FilterGraph *fg, InputFilter *ifilter,
+                                  AVFilterInOut *in)
+{
+    av_freep(&ifilter->name);
+    DESCRIBE_FILTER_LINK(ifilter, in, 1);
+
+    switch (avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx)) {
+    case AVMEDIA_TYPE_VIDEO: return configure_input_video_filter(fg, ifilter, in);
+    case AVMEDIA_TYPE_AUDIO: return configure_input_audio_filter(fg, ifilter, in);
+    default: av_assert0(0);
+    }
+}
+
+int configure_filtergraph(FilterGraph *fg)
+{
+    AVFilterInOut *inputs, *outputs, *cur;
+    int ret, i, init = !fg->graph, simple = !fg->graph_desc;
+    const char *graph_desc = simple ? fg->outputs[0]->ost->avfilter :
+                                      fg->graph_desc;
+
+    avfilter_graph_free(&fg->graph);
+    if (!(fg->graph = avfilter_graph_alloc()))
+        return AVERROR(ENOMEM);
+
+    if (simple) {
+        OutputStream *ost = fg->outputs[0]->ost;
+        char args[255];
+        snprintf(args, sizeof(args), "flags=0x%X", (unsigned)ost->sws_flags);
+        fg->graph->scale_sws_opts = av_strdup(args);
+    }
+
+    if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0)
+        return ret;
+
+    if (simple && (!inputs || inputs->next || !outputs || outputs->next)) {
+        av_log(NULL, AV_LOG_ERROR, "Simple filtergraph '%s' does not have "
+               "exactly one input and output.\n", graph_desc);
+        return AVERROR(EINVAL);
+    }
+
+    for (cur = inputs; !simple && init && cur; cur = cur->next)
+        init_input_filter(fg, cur);
+
+    for (cur = inputs, i = 0; cur; cur = cur->next, i++)
+        if ((ret = configure_input_filter(fg, fg->inputs[i], cur)) < 0)
+            return ret;
+    avfilter_inout_free(&inputs);
+
+    if (!init || simple) {
+        /* we already know the mappings between lavfi outputs and output streams,
+         * so we can finish the setup */
+        for (cur = outputs, i = 0; cur; cur = cur->next, i++)
+            configure_output_filter(fg, fg->outputs[i], cur);
+        avfilter_inout_free(&outputs);
+
+        if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
+            return ret;
+    } 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);
+            if (!(fg->outputs[fg->nb_outputs - 1] = av_mallocz(sizeof(*fg->outputs[0]))))
+                exit(1);
+            fg->outputs[fg->nb_outputs - 1]->graph   = fg;
+            fg->outputs[fg->nb_outputs - 1]->out_tmp = cur;
+            cur = cur->next;
+            fg->outputs[fg->nb_outputs - 1]->out_tmp->next = NULL;
+        }
+    }
+
+    return 0;
+}
+
+int ist_in_filtergraph(FilterGraph *fg, InputStream *ist)
+{
+    int i;
+    for (i = 0; i < fg->nb_inputs; i++)
+        if (fg->inputs[i]->ist == ist)
+            return 1;
+    return 0;
+}
+
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c
new file mode 100644
index 0000000..fefb785
--- /dev/null
+++ b/ffmpeg_opt.c
@@ -0,0 +1,2509 @@
+/*
+ * ffmpeg option parsing
+ *
+ * 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 "ffmpeg.h"
+#include "cmdutils.h"
+
+#include "libavformat/avformat.h"
+
+#include "libavcodec/avcodec.h"
+
+#include "libavfilter/avfilter.h"
+#include "libavfilter/avfiltergraph.h"
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/avutil.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/fifo.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/pixfmt.h"
+
+#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
+{\
+    int i, ret;\
+    for (i = 0; i < o->nb_ ## name; i++) {\
+        char *spec = o->name[i].specifier;\
+        if ((ret = check_stream_specifier(fmtctx, st, spec)) > 0)\
+            outvar = o->name[i].u.type;\
+        else if (ret < 0)\
+            exit(1);\
+    }\
+}
+
+#define MATCH_PER_TYPE_OPT(name, type, outvar, fmtctx, mediatype)\
+{\
+    int i;\
+    for (i = 0; i < o->nb_ ## name; i++) {\
+        char *spec = o->name[i].specifier;\
+        if (!strcmp(spec, mediatype))\
+            outvar = o->name[i].u.type;\
+    }\
+}
+char *vstats_filename;
+
+float audio_drift_threshold = 0.1;
+float dts_delta_threshold   = 10;
+float dts_error_threshold   = 3600*30;
+
+int audio_volume      = 256;
+int audio_sync_method = 0;
+int video_sync_method = VSYNC_AUTO;
+int do_deinterlace    = 0;
+int do_benchmark      = 0;
+int do_benchmark_all  = 0;
+int do_hex_dump       = 0;
+int do_pkt_dump       = 0;
+int copy_ts           = 0;
+int copy_tb           = -1;
+int debug_ts          = 0;
+int exit_on_error     = 0;
+int print_stats       = 1;
+int qp_hist           = 0;
+int stdin_interaction = 1;
+int frame_bits_per_raw_sample = 0;
+
+
+static int intra_only         = 0;
+static int file_overwrite     = 0;
+static int no_file_overwrite  = 0;
+static int video_discard      = 0;
+static int intra_dc_precision = 8;
+static int do_psnr            = 0;
+static int input_sync;
+
+void reset_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 */
+    while (po->name) {
+        void *dst = (uint8_t*)o + po->u.off;
+
+        if (po->flags & OPT_SPEC) {
+            SpecifierOpt **so = dst;
+            int i, *count = (int*)(so + 1);
+            for (i = 0; i < *count; i++) {
+                av_freep(&(*so)[i].specifier);
+                if (po->flags & OPT_STRING)
+                    av_freep(&(*so)[i].u.str);
+            }
+            av_freep(so);
+            *count = 0;
+        } else if (po->flags & OPT_OFFSET && po->flags & OPT_STRING)
+            av_freep(dst);
+        po++;
+    }
+
+    for (i = 0; i < o->nb_stream_maps; i++)
+        av_freep(&o->stream_maps[i].linklabel);
+    av_freep(&o->stream_maps);
+    av_freep(&o->audio_channel_maps);
+    av_freep(&o->streamid_map);
+
+    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");
+    } else
+    o->recording_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)
+{
+    av_log(NULL, AV_LOG_WARNING, "Ignoring option '%s'\n", opt);
+    return 0;
+}
+
+static int opt_video_channel(void *optctx, const char *opt, const char *arg)
+{
+    av_log(NULL, AV_LOG_WARNING, "This option is deprecated, use -channel.\n");
+    return opt_default(optctx, "channel", arg);
+}
+
+static int opt_video_standard(void *optctx, const char *opt, const char *arg)
+{
+    av_log(NULL, AV_LOG_WARNING, "This option is deprecated, use -standard.\n");
+    return opt_default(optctx, "standard", arg);
+}
+
+static int opt_audio_codec(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    return parse_option(o, "codec:a", arg, options);
+}
+
+static int opt_video_codec(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    return parse_option(o, "codec:v", arg, options);
+}
+
+static int opt_subtitle_codec(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    return parse_option(o, "codec:s", arg, options);
+}
+
+static int opt_data_codec(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    return parse_option(o, "codec:d", arg, options);
+}
+
+static int opt_map(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    StreamMap *m = NULL;
+    int i, negative = 0, file_idx;
+    int sync_file_idx = -1, sync_stream_idx = 0;
+    char *p, *sync;
+    char *map;
+
+    if (*arg == '-') {
+        negative = 1;
+        arg++;
+    }
+    map = av_strdup(arg);
+
+    /* parse sync stream first, just pick first matching stream */
+    if (sync = strchr(map, ',')) {
+        *sync = 0;
+        sync_file_idx = strtol(sync + 1, &sync, 0);
+        if (sync_file_idx >= nb_input_files || sync_file_idx < 0) {
+            av_log(NULL, AV_LOG_FATAL, "Invalid sync file index: %d.\n", sync_file_idx);
+            exit(1);
+        }
+        if (*sync)
+            sync++;
+        for (i = 0; i < input_files[sync_file_idx]->nb_streams; i++)
+            if (check_stream_specifier(input_files[sync_file_idx]->ctx,
+                                       input_files[sync_file_idx]->ctx->streams[i], sync) == 1) {
+                sync_stream_idx = i;
+                break;
+            }
+        if (i == input_files[sync_file_idx]->nb_streams) {
+            av_log(NULL, AV_LOG_FATAL, "Sync stream specification in map %s does not "
+                                       "match any streams.\n", arg);
+            exit(1);
+        }
+    }
+
+
+    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);
+        m = &o->stream_maps[o->nb_stream_maps - 1];
+        m->linklabel = av_get_token(&c, "]");
+        if (!m->linklabel) {
+            av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", map);
+            exit(1);
+        }
+    } else {
+        file_idx = strtol(map, &p, 0);
+        if (file_idx >= nb_input_files || file_idx < 0) {
+            av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
+            exit(1);
+        }
+        if (negative)
+            /* disable some already defined maps */
+            for (i = 0; i < o->nb_stream_maps; i++) {
+                m = &o->stream_maps[i];
+                if (file_idx == m->file_index &&
+                    check_stream_specifier(input_files[m->file_index]->ctx,
+                                           input_files[m->file_index]->ctx->streams[m->stream_index],
+                                           *p == ':' ? p + 1 : p) > 0)
+                    m->disabled = 1;
+            }
+        else
+            for (i = 0; i < input_files[file_idx]->nb_streams; i++) {
+                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);
+                m = &o->stream_maps[o->nb_stream_maps - 1];
+
+                m->file_index   = file_idx;
+                m->stream_index = i;
+
+                if (sync_file_idx >= 0) {
+                    m->sync_file_index   = sync_file_idx;
+                    m->sync_stream_index = sync_stream_idx;
+                } else {
+                    m->sync_file_index   = file_idx;
+                    m->sync_stream_index = i;
+                }
+            }
+    }
+
+    if (!m) {
+        av_log(NULL, AV_LOG_FATAL, "Stream map '%s' matches no streams.\n", arg);
+        exit(1);
+    }
+
+    av_freep(&map);
+    return 0;
+}
+
+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);
+    o->attachments[o->nb_attachments - 1] = arg;
+    return 0;
+}
+
+static int opt_map_channel(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    int n;
+    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);
+    m = &o->audio_channel_maps[o->nb_audio_channel_maps - 1];
+
+    /* muted channel syntax */
+    n = sscanf(arg, "%d:%d.%d", &m->channel_idx, &m->ofile_idx, &m->ostream_idx);
+    if ((n == 1 || n == 3) && m->channel_idx == -1) {
+        m->file_idx = m->stream_idx = -1;
+        if (n == 1)
+            m->ofile_idx = m->ostream_idx = -1;
+        return 0;
+    }
+
+    /* normal syntax */
+    n = sscanf(arg, "%d.%d.%d:%d.%d",
+               &m->file_idx,  &m->stream_idx, &m->channel_idx,
+               &m->ofile_idx, &m->ostream_idx);
+
+    if (n != 3 && n != 5) {
+        av_log(NULL, AV_LOG_FATAL, "Syntax error, mapchan usage: "
+               "[file.stream.channel|-1][:syncfile:syncstream]\n");
+        exit(1);
+    }
+
+    if (n != 5) // only file.stream.channel specified
+        m->ofile_idx = m->ostream_idx = -1;
+
+    /* check input */
+    if (m->file_idx < 0 || m->file_idx >= nb_input_files) {
+        av_log(NULL, AV_LOG_FATAL, "mapchan: invalid input file index: %d\n",
+               m->file_idx);
+        exit(1);
+    }
+    if (m->stream_idx < 0 ||
+        m->stream_idx >= input_files[m->file_idx]->nb_streams) {
+        av_log(NULL, AV_LOG_FATAL, "mapchan: invalid input file stream index #%d.%d\n",
+               m->file_idx, m->stream_idx);
+        exit(1);
+    }
+    st = input_files[m->file_idx]->ctx->streams[m->stream_idx];
+    if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
+        av_log(NULL, AV_LOG_FATAL, "mapchan: stream #%d.%d is not an audio stream.\n",
+               m->file_idx, m->stream_idx);
+        exit(1);
+    }
+    if (m->channel_idx < 0 || m->channel_idx >= st->codec->channels) {
+        av_log(NULL, AV_LOG_FATAL, "mapchan: invalid audio channel #%d.%d.%d\n",
+               m->file_idx, m->stream_idx, m->channel_idx);
+        exit(1);
+    }
+    return 0;
+}
+
+/**
+ * Parse a metadata specifier passed as 'arg' parameter.
+ * @param type metadata type is written here -- g(lobal)/s(tream)/c(hapter)/p(rogram)
+ * @param index for type c/p, chapter/program index is written here
+ * @param stream_spec for type s, the stream specifier is written here
+ */
+static void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec)
+{
+    if (*arg) {
+        *type = *arg;
+        switch (*arg) {
+        case 'g':
+            break;
+        case 's':
+            if (*(++arg) && *arg != ':') {
+                av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", arg);
+                exit(1);
+            }
+            *stream_spec = *arg == ':' ? arg + 1 : "";
+            break;
+        case 'c':
+        case 'p':
+            if (*(++arg) == ':')
+                *index = strtol(++arg, NULL, 0);
+            break;
+        default:
+            av_log(NULL, AV_LOG_FATAL, "Invalid metadata type %c.\n", *arg);
+            exit(1);
+        }
+    } else
+        *type = 'g';
+}
+
+static int copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o)
+{
+    AVDictionary **meta_in = NULL;
+    AVDictionary **meta_out = NULL;
+    int i, ret = 0;
+    char type_in, type_out;
+    const char *istream_spec = NULL, *ostream_spec = NULL;
+    int idx_in = 0, idx_out = 0;
+
+    parse_meta_type(inspec,  &type_in,  &idx_in,  &istream_spec);
+    parse_meta_type(outspec, &type_out, &idx_out, &ostream_spec);
+
+    if (!ic) {
+        if (type_out == 'g' || !*outspec)
+            o->metadata_global_manual = 1;
+        if (type_out == 's' || !*outspec)
+            o->metadata_streams_manual = 1;
+        if (type_out == 'c' || !*outspec)
+            o->metadata_chapters_manual = 1;
+        return 0;
+    }
+
+    if (type_in == 'g' || type_out == 'g')
+        o->metadata_global_manual = 1;
+    if (type_in == 's' || type_out == 's')
+        o->metadata_streams_manual = 1;
+    if (type_in == 'c' || type_out == 'c')
+        o->metadata_chapters_manual = 1;
+
+#define METADATA_CHECK_INDEX(index, nb_elems, desc)\
+    if ((index) < 0 || (index) >= (nb_elems)) {\
+        av_log(NULL, AV_LOG_FATAL, "Invalid %s index %d while processing metadata maps.\n",\
+                (desc), (index));\
+        exit(1);\
+    }
+
+#define SET_DICT(type, meta, context, index)\
+        switch (type) {\
+        case 'g':\
+            meta = &context->metadata;\
+            break;\
+        case 'c':\
+            METADATA_CHECK_INDEX(index, context->nb_chapters, "chapter")\
+            meta = &context->chapters[index]->metadata;\
+            break;\
+        case 'p':\
+            METADATA_CHECK_INDEX(index, context->nb_programs, "program")\
+            meta = &context->programs[index]->metadata;\
+            break;\
+        default: av_assert0(0);\
+        case 's':\
+            break;\
+        }\
+
+    SET_DICT(type_in, meta_in, ic, idx_in);
+    SET_DICT(type_out, meta_out, oc, idx_out);
+
+    /* for input streams choose first matching stream */
+    if (type_in == 's') {
+        for (i = 0; i < ic->nb_streams; i++) {
+            if ((ret = check_stream_specifier(ic, ic->streams[i], istream_spec)) > 0) {
+                meta_in = &ic->streams[i]->metadata;
+                break;
+            } else if (ret < 0)
+                exit(1);
+        }
+        if (!meta_in) {
+            av_log(NULL, AV_LOG_FATAL, "Stream specifier %s does not match  any streams.\n", istream_spec);
+            exit(1);
+        }
+    }
+
+    if (type_out == 's') {
+        for (i = 0; i < oc->nb_streams; i++) {
+            if ((ret = check_stream_specifier(oc, oc->streams[i], ostream_spec)) > 0) {
+                meta_out = &oc->streams[i]->metadata;
+                av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
+            } else if (ret < 0)
+                exit(1);
+        }
+    } else
+        av_dict_copy(meta_out, *meta_in, AV_DICT_DONT_OVERWRITE);
+
+    return 0;
+}
+
+static int opt_recording_timestamp(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    char buf[128];
+    int64_t recording_timestamp = parse_time_or_die(opt, arg, 0) / 1E6;
+    struct tm time = *gmtime((time_t*)&recording_timestamp);
+    strftime(buf, sizeof(buf), "creation_time=%FT%T%z", &time);
+    parse_option(o, "metadata", buf, options);
+
+    av_log(NULL, AV_LOG_WARNING, "%s is deprecated, set the 'creation_time' metadata "
+                                 "tag instead.\n", opt);
+    return 0;
+}
+
+static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder)
+{
+    const AVCodecDescriptor *desc;
+    const char *codec_string = encoder ? "encoder" : "decoder";
+    AVCodec *codec;
+
+    codec = encoder ?
+        avcodec_find_encoder_by_name(name) :
+        avcodec_find_decoder_by_name(name);
+
+    if (!codec && (desc = avcodec_descriptor_get_by_name(name))) {
+        codec = encoder ? avcodec_find_encoder(desc->id) :
+                          avcodec_find_decoder(desc->id);
+        if (codec)
+            av_log(NULL, AV_LOG_VERBOSE, "Matched %s '%s' for codec '%s'.\n",
+                   codec_string, codec->name, desc->name);
+    }
+
+    if (!codec) {
+        av_log(NULL, AV_LOG_FATAL, "Unknown %s '%s'\n", codec_string, name);
+        exit(1);
+    }
+    if (codec->type != type) {
+        av_log(NULL, AV_LOG_FATAL, "Invalid %s type '%s'\n", codec_string, name);
+        exit(1);
+    }
+    return codec;
+}
+
+static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st)
+{
+    char *codec_name = NULL;
+
+    MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
+    if (codec_name) {
+        AVCodec *codec = find_codec_or_die(codec_name, st->codec->codec_type, 0);
+        st->codec->codec_id = codec->id;
+        return codec;
+    } else
+        return avcodec_find_decoder(st->codec->codec_id);
+}
+
+/* Add all the streams from the given input file to the global
+ * list of input streams. */
+static void add_input_streams(OptionsContext *o, AVFormatContext *ic)
+{
+    int i;
+    char *next, *codec_tag = NULL;
+
+    for (i = 0; i < ic->nb_streams; i++) {
+        AVStream *st = ic->streams[i];
+        AVCodecContext *dec = st->codec;
+        InputStream *ist = av_mallocz(sizeof(*ist));
+        char *framerate = NULL;
+
+        if (!ist)
+            exit(1);
+
+        input_streams = grow_array(input_streams, sizeof(*input_streams), &nb_input_streams, nb_input_streams + 1);
+        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);
+
+        MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
+        if (codec_tag) {
+            uint32_t tag = strtol(codec_tag, &next, 0);
+            if (*next)
+                tag = AV_RL32(codec_tag);
+            st->codec->codec_tag = tag;
+        }
+
+        ist->dec = choose_decoder(o, ic, st);
+
+        switch (dec->codec_type) {
+        case AVMEDIA_TYPE_VIDEO:
+            if(!ist->dec)
+                ist->dec = avcodec_find_decoder(dec->codec_id);
+            if (dec->lowres) {
+                dec->flags |= CODEC_FLAG_EMU_EDGE;
+            }
+
+            ist->resample_height  = dec->height;
+            ist->resample_width   = dec->width;
+            ist->resample_pix_fmt = dec->pix_fmt;
+
+            MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
+            if (framerate && av_parse_video_rate(&ist->framerate,
+                                                 framerate) < 0) {
+                av_log(NULL, AV_LOG_ERROR, "Error parsing framerate %s.\n",
+                       framerate);
+                exit(1);
+            }
+
+            ist->top_field_first = -1;
+            MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st);
+
+            break;
+        case AVMEDIA_TYPE_AUDIO:
+            guess_input_channel_layout(ist);
+
+            ist->resample_sample_fmt     = dec->sample_fmt;
+            ist->resample_sample_rate    = dec->sample_rate;
+            ist->resample_channels       = dec->channels;
+            ist->resample_channel_layout = dec->channel_layout;
+
+            break;
+        case AVMEDIA_TYPE_DATA:
+        case AVMEDIA_TYPE_SUBTITLE:
+            if(!ist->dec)
+                ist->dec = avcodec_find_decoder(dec->codec_id);
+            MATCH_PER_STREAM_OPT(fix_sub_duration, i, ist->fix_sub_duration, ic, st);
+            break;
+        case AVMEDIA_TYPE_ATTACHMENT:
+        case AVMEDIA_TYPE_UNKNOWN:
+            break;
+        default:
+            abort();
+        }
+    }
+}
+
+static void assert_file_overwrite(const char *filename)
+{
+    if ((!file_overwrite || no_file_overwrite) &&
+        (strchr(filename, ':') == NULL || filename[1] == ':' ||
+         av_strstart(filename, "file:", NULL))) {
+        if (avio_check(filename, 0) == 0) {
+            if (stdin_interaction && (!no_file_overwrite || file_overwrite)) {
+                fprintf(stderr,"File '%s' already exists. Overwrite ? [y/N] ", filename);
+                fflush(stderr);
+                term_exit();
+                signal(SIGINT, SIG_DFL);
+                if (!read_yesno()) {
+                    av_log(NULL, AV_LOG_FATAL, "Not overwriting - exiting\n");
+                    exit(1);
+                }
+                term_init();
+            }
+            else {
+                av_log(NULL, AV_LOG_FATAL, "File '%s' already exists. Exiting.\n", filename);
+                exit(1);
+            }
+        }
+    }
+}
+
+static void dump_attachment(AVStream *st, const char *filename)
+{
+    int ret;
+    AVIOContext *out = NULL;
+    AVDictionaryEntry *e;
+
+    if (!st->codec->extradata_size) {
+        av_log(NULL, AV_LOG_WARNING, "No extradata to dump in stream #%d:%d.\n",
+               nb_input_files - 1, st->index);
+        return;
+    }
+    if (!*filename && (e = av_dict_get(st->metadata, "filename", NULL, 0)))
+        filename = e->value;
+    if (!*filename) {
+        av_log(NULL, AV_LOG_FATAL, "No filename specified and no 'filename' tag"
+               "in stream #%d:%d.\n", nb_input_files - 1, st->index);
+        exit(1);
+    }
+
+    assert_file_overwrite(filename);
+
+    if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, &int_cb, NULL)) < 0) {
+        av_log(NULL, AV_LOG_FATAL, "Could not open file %s for writing.\n",
+               filename);
+        exit(1);
+    }
+
+    avio_write(out, st->codec->extradata, st->codec->extradata_size);
+    avio_flush(out);
+    avio_close(out);
+}
+
+static int opt_input_file(void *optctx, const char *opt, const char *filename)
+{
+    OptionsContext *o = optctx;
+    AVFormatContext *ic;
+    AVInputFormat *file_iformat = NULL;
+    int err, i, ret;
+    int64_t timestamp;
+    uint8_t buf[128];
+    AVDictionary **opts;
+    int orig_nb_streams;                     // number of streams before avformat_find_stream_info
+    char *   video_codec_name = NULL;
+    char *   audio_codec_name = NULL;
+    char *subtitle_codec_name = NULL;
+
+    if (o->format) {
+        if (!(file_iformat = av_find_input_format(o->format))) {
+            av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
+            exit(1);
+        }
+    }
+
+    if (!strcmp(filename, "-"))
+        filename = "pipe:";
+
+    stdin_interaction &= strncmp(filename, "pipe:", 5) &&
+                         strcmp(filename, "/dev/stdin");
+
+    /* get default parameters from command line */
+    ic = avformat_alloc_context();
+    if (!ic) {
+        print_error(filename, AVERROR(ENOMEM));
+        exit(1);
+    }
+    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);
+    }
+    if (o->nb_audio_channels) {
+        /* because we set audio_channels based on both the "ac" and
+         * "channel_layout" options, we need to check that the specified
+         * demuxer actually has the "channels" option before setting it */
+        if (file_iformat && file_iformat->priv_class &&
+            av_opt_find(&file_iformat->priv_class, "channels", NULL, 0,
+                        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);
+        }
+    }
+    if (o->nb_frame_rates) {
+        /* set the format-level framerate option;
+         * this is important for video grabbers, e.g. x11 */
+        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",
+                        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);
+    }
+    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);
+
+    MATCH_PER_TYPE_OPT(codec_names, str,    video_codec_name, ic, "v");
+    MATCH_PER_TYPE_OPT(codec_names, str,    audio_codec_name, ic, "a");
+    MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, ic, "s");
+
+    ic->video_codec_id   = video_codec_name ?
+        find_codec_or_die(video_codec_name   , AVMEDIA_TYPE_VIDEO   , 0)->id : AV_CODEC_ID_NONE;
+    ic->audio_codec_id   = audio_codec_name ?
+        find_codec_or_die(audio_codec_name   , AVMEDIA_TYPE_AUDIO   , 0)->id : AV_CODEC_ID_NONE;
+    ic->subtitle_codec_id= subtitle_codec_name ?
+        find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0)->id : AV_CODEC_ID_NONE;
+    ic->flags |= AVFMT_FLAG_NONBLOCK;
+    ic->interrupt_callback = int_cb;
+
+    /* open the input file with generic avformat function */
+    err = avformat_open_input(&ic, filename, file_iformat, &format_opts);
+    if (err < 0) {
+        print_error(filename, err);
+        exit(1);
+    }
+    assert_avoptions(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);
+    orig_nb_streams = ic->nb_streams;
+
+    /* If not enough info to get the stream parameters, we decode the
+       first frames to get it. (used in mpeg case for example) */
+    ret = avformat_find_stream_info(ic, opts);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_FATAL, "%s: could not find codec parameters\n", filename);
+        avformat_close_input(&ic);
+        exit(1);
+    }
+
+    timestamp = o->start_time;
+    /* add the stream start time */
+    if (ic->start_time != AV_NOPTS_VALUE)
+        timestamp += ic->start_time;
+
+    /* if seeking requested, we execute it */
+    if (o->start_time != 0) {
+        ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
+        if (ret < 0) {
+            av_log(NULL, AV_LOG_WARNING, "%s: could not seek to position %0.3f\n",
+                   filename, (double)timestamp / AV_TIME_BASE);
+        }
+    }
+
+    /* update the current parameters so that they match the one of the input stream */
+    add_input_streams(o, ic);
+
+    /* 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);
+    if (!(input_files[nb_input_files - 1] = av_mallocz(sizeof(*input_files[0]))))
+        exit(1);
+
+    input_files[nb_input_files - 1]->ctx        = ic;
+    input_files[nb_input_files - 1]->ist_index  = nb_input_streams - ic->nb_streams;
+    input_files[nb_input_files - 1]->ts_offset  = o->input_ts_offset - (copy_ts ? 0 : timestamp);
+    input_files[nb_input_files - 1]->nb_streams = ic->nb_streams;
+    input_files[nb_input_files - 1]->rate_emu   = o->rate_emu;
+
+    for (i = 0; i < o->nb_dump_attachment; i++) {
+        int j;
+
+        for (j = 0; j < ic->nb_streams; j++) {
+            AVStream *st = ic->streams[j];
+
+            if (check_stream_specifier(ic, st, o->dump_attachment[i].specifier) == 1)
+                dump_attachment(st, o->dump_attachment[i].u.str);
+        }
+    }
+
+    for (i = 0; i < orig_nb_streams; i++)
+        av_dict_free(&opts[i]);
+    av_freep(&opts);
+
+    reset_options(o, 1);
+    return 0;
+}
+
+static uint8_t *get_line(AVIOContext *s)
+{
+    AVIOContext *line;
+    uint8_t *buf;
+    char c;
+
+    if (avio_open_dyn_buf(&line) < 0) {
+        av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n");
+        exit(1);
+    }
+
+    while ((c = avio_r8(s)) && c != '\n')
+        avio_w8(line, c);
+    avio_w8(line, 0);
+    avio_close_dyn_buf(line, &buf);
+
+    return buf;
+}
+
+static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s)
+{
+    int i, ret = 1;
+    char filename[1000];
+    const char *base[3] = { getenv("AVCONV_DATADIR"),
+                            getenv("HOME"),
+                            AVCONV_DATADIR,
+                            };
+
+    for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) {
+        if (!base[i])
+            continue;
+        if (codec_name) {
+            snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i],
+                     i != 1 ? "" : "/.avconv", codec_name, preset_name);
+            ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
+        }
+        if (ret) {
+            snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i],
+                     i != 1 ? "" : "/.avconv", preset_name);
+            ret = avio_open2(s, filename, AVIO_FLAG_READ, &int_cb, NULL);
+        }
+    }
+    return ret;
+}
+
+static void choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost)
+{
+    char *codec_name = NULL;
+
+    MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st);
+    if (!codec_name) {
+        ost->st->codec->codec_id = av_guess_codec(s->oformat, NULL, s->filename,
+                                                  NULL, ost->st->codec->codec_type);
+        ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);
+    } else if (!strcmp(codec_name, "copy"))
+        ost->stream_copy = 1;
+    else {
+        ost->enc = find_codec_or_die(codec_name, ost->st->codec->codec_type, 1);
+        ost->st->codec->codec_id = ost->enc->id;
+    }
+}
+
+static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type, int source_index)
+{
+    OutputStream *ost;
+    AVStream *st = avformat_new_stream(oc, NULL);
+    int idx      = oc->nb_streams - 1, ret = 0;
+    char *bsf = NULL, *next, *codec_tag = NULL;
+    AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
+    double qscale = -1;
+    char *buf = NULL, *arg = NULL, *preset = NULL;
+    AVIOContext *s = NULL;
+
+    if (!st) {
+        av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");
+        exit(1);
+    }
+
+    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);
+    if (!(ost = av_mallocz(sizeof(*ost))))
+        exit(1);
+    output_streams[nb_output_streams - 1] = ost;
+
+    ost->file_index = nb_output_files;
+    ost->index      = idx;
+    ost->st         = st;
+    st->codec->codec_type = type;
+    choose_encoder(o, oc, ost);
+    if (ost->enc) {
+        ost->opts  = filter_codec_opts(codec_opts, ost->enc->id, oc, st, ost->enc);
+    }
+
+    avcodec_get_context_defaults3(st->codec, ost->enc);
+    st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy
+
+    MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
+    if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {
+        do  {
+            buf = get_line(s);
+            if (!buf[0] || buf[0] == '#') {
+                av_free(buf);
+                continue;
+            }
+            if (!(arg = strchr(buf, '='))) {
+                av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");
+                exit(1);
+            }
+            *arg++ = 0;
+            av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE);
+            av_free(buf);
+        } while (!s->eof_reached);
+        avio_close(s);
+    }
+    if (ret) {
+        av_log(NULL, AV_LOG_FATAL,
+               "Preset %s specified for stream %d:%d, but could not be opened.\n",
+               preset, ost->file_index, ost->index);
+        exit(1);
+    }
+
+    ost->max_frames = INT64_MAX;
+    MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);
+
+    ost->copy_prior_start = -1;
+    MATCH_PER_STREAM_OPT(copy_prior_start, i, ost->copy_prior_start, oc ,st);
+
+    MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);
+    while (bsf) {
+        if (next = strchr(bsf, ','))
+            *next++ = 0;
+        if (!(bsfc = av_bitstream_filter_init(bsf))) {
+            av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
+            exit(1);
+        }
+        if (bsfc_prev)
+            bsfc_prev->next = bsfc;
+        else
+            ost->bitstream_filters = bsfc;
+
+        bsfc_prev = bsfc;
+        bsf       = next;
+    }
+
+    MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
+    if (codec_tag) {
+        uint32_t tag = strtol(codec_tag, &next, 0);
+        if (*next)
+            tag = AV_RL32(codec_tag);
+        st->codec->codec_tag = tag;
+    }
+
+    MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);
+    if (qscale >= 0) {
+        st->codec->flags |= CODEC_FLAG_QSCALE;
+        st->codec->global_quality = FF_QP2LAMBDA * qscale;
+    }
+
+    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, "dither_method", 0, &ost->swr_dither_method);
+    av_opt_get_double(swr_opts, "dither_scale" , 0, &ost->swr_dither_scale);
+
+    ost->source_index = source_index;
+    if (source_index >= 0) {
+        ost->sync_ist = input_streams[source_index];
+        input_streams[source_index]->discard = 0;
+        input_streams[source_index]->st->discard = AVDISCARD_NONE;
+    }
+
+    return ost;
+}
+
+static void parse_matrix_coeffs(uint16_t *dest, const char *str)
+{
+    int i;
+    const char *p = str;
+    for (i = 0;; i++) {
+        dest[i] = atoi(p);
+        if (i == 63)
+            break;
+        p = strchr(p, ',');
+        if (!p) {
+            av_log(NULL, AV_LOG_FATAL, "Syntax error in matrix \"%s\" at coeff %d\n", str, i);
+            exit(1);
+        }
+        p++;
+    }
+}
+
+static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
+{
+    AVStream *st;
+    OutputStream *ost;
+    AVCodecContext *video_enc;
+    char *frame_rate = NULL;
+
+    ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO, source_index);
+    st  = ost->st;
+    video_enc = st->codec;
+
+    MATCH_PER_STREAM_OPT(frame_rates, str, frame_rate, oc, st);
+    if (frame_rate && av_parse_video_rate(&ost->frame_rate, frame_rate) < 0) {
+        av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", frame_rate);
+        exit(1);
+    }
+
+    if (!ost->stream_copy) {
+        const char *p = NULL;
+        char *frame_size = NULL;
+        char *frame_aspect_ratio = NULL, *frame_pix_fmt = NULL;
+        char *intra_matrix = NULL, *inter_matrix = NULL;
+        const char *filters = "null";
+        int do_pass = 0;
+        int i;
+
+        MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
+        if (frame_size && av_parse_video_size(&video_enc->width, &video_enc->height, frame_size) < 0) {
+            av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
+            exit(1);
+        }
+
+        MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
+        if (frame_aspect_ratio) {
+            AVRational q;
+            if (av_parse_ratio(&q, frame_aspect_ratio, 255, 0, NULL) < 0 ||
+                q.num <= 0 || q.den <= 0) {
+                av_log(NULL, AV_LOG_FATAL, "Invalid aspect ratio: %s\n", frame_aspect_ratio);
+                exit(1);
+            }
+            ost->frame_aspect_ratio = av_q2d(q);
+        }
+
+        video_enc->bits_per_raw_sample = frame_bits_per_raw_sample;
+        MATCH_PER_STREAM_OPT(frame_pix_fmts, str, frame_pix_fmt, oc, st);
+        if (frame_pix_fmt && *frame_pix_fmt == '+') {
+            ost->keep_pix_fmt = 1;
+            if (!*++frame_pix_fmt)
+                frame_pix_fmt = NULL;
+        }
+        if (frame_pix_fmt && (video_enc->pix_fmt = av_get_pix_fmt(frame_pix_fmt)) == AV_PIX_FMT_NONE) {
+            av_log(NULL, AV_LOG_FATAL, "Unknown pixel format requested: %s.\n", frame_pix_fmt);
+            exit(1);
+        }
+        st->sample_aspect_ratio = video_enc->sample_aspect_ratio;
+
+        if (intra_only)
+            video_enc->gop_size = 0;
+        MATCH_PER_STREAM_OPT(intra_matrices, str, intra_matrix, oc, st);
+        if (intra_matrix) {
+            if (!(video_enc->intra_matrix = av_mallocz(sizeof(*video_enc->intra_matrix) * 64))) {
+                av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for intra matrix.\n");
+                exit(1);
+            }
+            parse_matrix_coeffs(video_enc->intra_matrix, intra_matrix);
+        }
+        MATCH_PER_STREAM_OPT(inter_matrices, str, inter_matrix, oc, st);
+        if (inter_matrix) {
+            if (!(video_enc->inter_matrix = av_mallocz(sizeof(*video_enc->inter_matrix) * 64))) {
+                av_log(NULL, AV_LOG_FATAL, "Could not allocate memory for inter matrix.\n");
+                exit(1);
+            }
+            parse_matrix_coeffs(video_enc->inter_matrix, inter_matrix);
+        }
+
+        MATCH_PER_STREAM_OPT(rc_overrides, str, p, oc, st);
+        for (i = 0; p; i++) {
+            int start, end, q;
+            int e = sscanf(p, "%d,%d,%d", &start, &end, &q);
+            if (e != 3) {
+                av_log(NULL, AV_LOG_FATAL, "error parsing rc_override\n");
+                exit(1);
+            }
+            /* FIXME realloc failure */
+            video_enc->rc_override =
+                av_realloc(video_enc->rc_override,
+                           sizeof(RcOverride) * (i + 1));
+            video_enc->rc_override[i].start_frame = start;
+            video_enc->rc_override[i].end_frame   = end;
+            if (q > 0) {
+                video_enc->rc_override[i].qscale         = q;
+                video_enc->rc_override[i].quality_factor = 1.0;
+            }
+            else {
+                video_enc->rc_override[i].qscale         = 0;
+                video_enc->rc_override[i].quality_factor = -q/100.0;
+            }
+            p = strchr(p, '/');
+            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)
+            video_enc->flags|= CODEC_FLAG_PSNR;
+
+        /* two pass mode */
+        MATCH_PER_STREAM_OPT(pass, i, do_pass, oc, st);
+        if (do_pass) {
+            if (do_pass & 1) {
+                video_enc->flags |= CODEC_FLAG_PASS1;
+            }
+            if (do_pass & 2) {
+                video_enc->flags |= CODEC_FLAG_PASS2;
+            }
+        }
+
+        MATCH_PER_STREAM_OPT(passlogfiles, str, ost->logfile_prefix, oc, st);
+        if (ost->logfile_prefix &&
+            !(ost->logfile_prefix = av_strdup(ost->logfile_prefix)))
+            exit(1);
+
+        MATCH_PER_STREAM_OPT(forced_key_frames, str, ost->forced_keyframes, oc, st);
+        if (ost->forced_keyframes)
+            ost->forced_keyframes = av_strdup(ost->forced_keyframes);
+
+        MATCH_PER_STREAM_OPT(force_fps, i, ost->force_fps, oc, st);
+
+        ost->top_field_first = -1;
+        MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, st);
+
+        MATCH_PER_STREAM_OPT(filters, str, filters, oc, st);
+        ost->avfilter = av_strdup(filters);
+    } else {
+        MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc ,st);
+    }
+
+    return ost;
+}
+
+static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
+{
+    int n;
+    AVStream *st;
+    OutputStream *ost;
+    AVCodecContext *audio_enc;
+
+    ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO, source_index);
+    st  = ost->st;
+
+    audio_enc = st->codec;
+    audio_enc->codec_type = AVMEDIA_TYPE_AUDIO;
+
+    if (!ost->stream_copy) {
+        char *sample_fmt = NULL;
+        const char *filters = "anull";
+
+        MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
+
+        MATCH_PER_STREAM_OPT(sample_fmts, str, sample_fmt, oc, st);
+        if (sample_fmt &&
+            (audio_enc->sample_fmt = av_get_sample_fmt(sample_fmt)) == AV_SAMPLE_FMT_NONE) {
+            av_log(NULL, AV_LOG_FATAL, "Invalid sample format '%s'\n", sample_fmt);
+            exit(1);
+        }
+
+        MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, oc, st);
+
+        MATCH_PER_STREAM_OPT(filters, str, filters, oc, st);
+
+        av_assert1(filters);
+        ost->avfilter = av_strdup(filters);
+
+        /* check for channel mapping for this audio stream */
+        for (n = 0; n < o->nb_audio_channel_maps; n++) {
+            AudioChannelMap *map = &o->audio_channel_maps[n];
+            InputStream *ist = input_streams[ost->source_index];
+            if ((map->channel_idx == -1 || (ist->file_index == map->file_idx && ist->st->index == map->stream_idx)) &&
+                (map->ofile_idx   == -1 || ost->file_index == map->ofile_idx) &&
+                (map->ostream_idx == -1 || ost->st->index  == map->ostream_idx)) {
+                if (ost->audio_channels_mapped < FF_ARRAY_ELEMS(ost->audio_channels_map))
+                    ost->audio_channels_map[ost->audio_channels_mapped++] = map->channel_idx;
+                else
+                    av_log(NULL, AV_LOG_FATAL, "Max channel mapping for output %d.%d reached\n",
+                           ost->file_index, ost->st->index);
+            }
+        }
+    }
+
+    return ost;
+}
+
+static OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
+{
+    OutputStream *ost;
+
+    ost = new_output_stream(o, oc, AVMEDIA_TYPE_DATA, source_index);
+    if (!ost->stream_copy) {
+        av_log(NULL, AV_LOG_FATAL, "Data stream encoding not supported yet (only streamcopy)\n");
+        exit(1);
+    }
+
+    return ost;
+}
+
+static OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
+{
+    OutputStream *ost = new_output_stream(o, oc, AVMEDIA_TYPE_ATTACHMENT, source_index);
+    ost->stream_copy = 1;
+    return ost;
+}
+
+static OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc, int source_index)
+{
+    AVStream *st;
+    OutputStream *ost;
+    AVCodecContext *subtitle_enc;
+
+    ost = new_output_stream(o, oc, AVMEDIA_TYPE_SUBTITLE, source_index);
+    st  = ost->st;
+    subtitle_enc = st->codec;
+
+    subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
+
+    MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, ost->copy_initial_nonkeyframes, oc, st);
+
+    if (!ost->stream_copy) {
+        char *frame_size = NULL;
+
+        MATCH_PER_STREAM_OPT(frame_sizes, str, frame_size, oc, st);
+        if (frame_size && av_parse_video_size(&subtitle_enc->width, &subtitle_enc->height, frame_size) < 0) {
+            av_log(NULL, AV_LOG_FATAL, "Invalid frame size: %s.\n", frame_size);
+            exit(1);
+        }
+    }
+
+    return ost;
+}
+
+/* arg format is "output-stream-index:streamid-value". */
+static int opt_streamid(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    int idx;
+    char *p;
+    char idx_str[16];
+
+    av_strlcpy(idx_str, arg, sizeof(idx_str));
+    p = strchr(idx_str, ':');
+    if (!p) {
+        av_log(NULL, AV_LOG_FATAL,
+               "Invalid value '%s' for option '%s', required syntax is 'index:value'\n",
+               arg, opt);
+        exit(1);
+    }
+    *p++ = '\0';
+    idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, MAX_STREAMS-1);
+    o->streamid_map = grow_array(o->streamid_map, sizeof(*o->streamid_map), &o->nb_streamid_map, idx+1);
+    o->streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX);
+    return 0;
+}
+
+static int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata)
+{
+    AVFormatContext *is = ifile->ctx;
+    AVFormatContext *os = ofile->ctx;
+    AVChapter **tmp;
+    int i;
+
+    tmp = av_realloc_f(os->chapters, is->nb_chapters + os->nb_chapters, sizeof(*os->chapters));
+    if (!tmp)
+        return AVERROR(ENOMEM);
+    os->chapters = tmp;
+
+    for (i = 0; i < is->nb_chapters; i++) {
+        AVChapter *in_ch = is->chapters[i], *out_ch;
+        int64_t ts_off   = av_rescale_q(ofile->start_time - ifile->ts_offset,
+                                       AV_TIME_BASE_Q, in_ch->time_base);
+        int64_t rt       = (ofile->recording_time == INT64_MAX) ? INT64_MAX :
+                           av_rescale_q(ofile->recording_time, AV_TIME_BASE_Q, in_ch->time_base);
+
+
+        if (in_ch->end < ts_off)
+            continue;
+        if (rt != INT64_MAX && in_ch->start > rt + ts_off)
+            break;
+
+        out_ch = av_mallocz(sizeof(AVChapter));
+        if (!out_ch)
+            return AVERROR(ENOMEM);
+
+        out_ch->id        = in_ch->id;
+        out_ch->time_base = in_ch->time_base;
+        out_ch->start     = FFMAX(0,  in_ch->start - ts_off);
+        out_ch->end       = FFMIN(rt, in_ch->end   - ts_off);
+
+        if (copy_metadata)
+            av_dict_copy(&out_ch->metadata, in_ch->metadata, 0);
+
+        os->chapters[os->nb_chapters++] = out_ch;
+    }
+    return 0;
+}
+
+static int read_ffserver_streams(OptionsContext *o, AVFormatContext *s, const char *filename)
+{
+    int i, err;
+    AVFormatContext *ic = avformat_alloc_context();
+
+    ic->interrupt_callback = int_cb;
+    err = avformat_open_input(&ic, filename, NULL, NULL);
+    if (err < 0)
+        return err;
+    /* copy stream format */
+    for(i=0;i<ic->nb_streams;i++) {
+        AVStream *st;
+        OutputStream *ost;
+        AVCodec *codec;
+        AVCodecContext *avctx;
+
+        codec = avcodec_find_encoder(ic->streams[i]->codec->codec_id);
+        ost   = new_output_stream(o, s, codec->type, -1);
+        st    = ost->st;
+        avctx = st->codec;
+        ost->enc = codec;
+
+        // FIXME: a more elegant solution is needed
+        memcpy(st, ic->streams[i], sizeof(AVStream));
+        st->cur_dts = 0;
+        st->info = av_malloc(sizeof(*st->info));
+        memcpy(st->info, ic->streams[i]->info, sizeof(*st->info));
+        st->codec= avctx;
+        avcodec_copy_context(st->codec, ic->streams[i]->codec);
+
+        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && !ost->stream_copy)
+            choose_sample_fmt(st, codec);
+        else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !ost->stream_copy)
+            choose_pixel_fmt(st, codec, st->codec->pix_fmt);
+    }
+
+    /* ffserver seeking with date=... needs a date reference */
+    err = parse_option(o, "metadata", "creation_time=now", options);
+
+    avformat_close_input(&ic);
+    return err;
+}
+
+static void init_output_filter(OutputFilter *ofilter, OptionsContext *o,
+                               AVFormatContext *oc)
+{
+    OutputStream *ost;
+
+    switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
+                                  ofilter->out_tmp->pad_idx)) {
+    case AVMEDIA_TYPE_VIDEO: ost = new_video_stream(o, oc, -1); break;
+    case AVMEDIA_TYPE_AUDIO: ost = new_audio_stream(o, oc, -1); break;
+    default:
+        av_log(NULL, AV_LOG_FATAL, "Only video and audio filters are supported "
+               "currently.\n");
+        exit(1);
+    }
+
+    ost->source_index = -1;
+    ost->filter       = ofilter;
+
+    ofilter->ost      = ost;
+
+    if (ost->stream_copy) {
+        av_log(NULL, AV_LOG_ERROR, "Streamcopy requested for output stream %d:%d, "
+               "which is fed from a complex filtergraph. Filtering and streamcopy "
+               "cannot be used together.\n", ost->file_index, ost->index);
+        exit(1);
+    }
+
+    if (configure_output_filter(ofilter->graph, ofilter, ofilter->out_tmp) < 0) {
+        av_log(NULL, AV_LOG_FATAL, "Error configuring filter.\n");
+        exit(1);
+    }
+    avfilter_inout_free(&ofilter->out_tmp);
+}
+
+static int configure_complex_filters(void)
+{
+    int i, ret = 0;
+
+    for (i = 0; i < nb_filtergraphs; i++)
+        if (!filtergraphs[i]->graph &&
+            (ret = configure_filtergraph(filtergraphs[i])) < 0)
+            return ret;
+    return 0;
+}
+
+void opt_output_file(void *optctx, const char *filename)
+{
+    OptionsContext *o = optctx;
+    AVFormatContext *oc;
+    int i, j, err;
+    AVOutputFormat *file_oformat;
+    OutputStream *ost;
+    InputStream  *ist;
+
+    if (configure_complex_filters() < 0) {
+        av_log(NULL, AV_LOG_FATAL, "Error configuring filters.\n");
+        exit(1);
+    }
+
+    if (!strcmp(filename, "-"))
+        filename = "pipe:";
+
+    err = avformat_alloc_output_context2(&oc, NULL, o->format, filename);
+    if (!oc) {
+        print_error(filename, err);
+        exit(1);
+    }
+    file_oformat= oc->oformat;
+    oc->interrupt_callback = int_cb;
+
+    /* create streams for all unlabeled output pads */
+    for (i = 0; i < nb_filtergraphs; i++) {
+        FilterGraph *fg = filtergraphs[i];
+        for (j = 0; j < fg->nb_outputs; j++) {
+            OutputFilter *ofilter = fg->outputs[j];
+
+            if (!ofilter->out_tmp || ofilter->out_tmp->name)
+                continue;
+
+            switch (avfilter_pad_get_type(ofilter->out_tmp->filter_ctx->output_pads,
+                                          ofilter->out_tmp->pad_idx)) {
+            case AVMEDIA_TYPE_VIDEO:    o->video_disable    = 1; break;
+            case AVMEDIA_TYPE_AUDIO:    o->audio_disable    = 1; break;
+            case AVMEDIA_TYPE_SUBTITLE: o->subtitle_disable = 1; break;
+            }
+            init_output_filter(ofilter, o, oc);
+        }
+    }
+
+    if (!strcmp(file_oformat->name, "ffm") &&
+        av_strstart(filename, "http:", NULL)) {
+        int j;
+        /* special case for files sent to ffserver: we get the stream
+           parameters from ffserver */
+        int err = read_ffserver_streams(o, oc, filename);
+        if (err < 0) {
+            print_error(filename, err);
+            exit(1);
+        }
+        for(j = nb_output_streams - oc->nb_streams; j < nb_output_streams; j++) {
+            ost = output_streams[j];
+            for (i = 0; i < nb_input_streams; i++) {
+                ist = input_streams[i];
+                if(ist->st->codec->codec_type == ost->st->codec->codec_type){
+                    ost->sync_ist= ist;
+                    ost->source_index= i;
+                    if(ost->st->codec->codec_type == AVMEDIA_TYPE_AUDIO) ost->avfilter = av_strdup("anull");
+                    if(ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) ost->avfilter = av_strdup("null");
+                    ist->discard = 0;
+                    ist->st->discard = AVDISCARD_NONE;
+                    break;
+                }
+            }
+            if(!ost->sync_ist){
+                av_log(NULL, AV_LOG_FATAL, "Missing %s stream which is required by this ffm\n", av_get_media_type_string(ost->st->codec->codec_type));
+                exit(1);
+            }
+        }
+    } else if (!o->nb_stream_maps) {
+        char *subtitle_codec_name = NULL;
+        /* pick the "best" stream of each type */
+
+        /* video: highest resolution */
+        if (!o->video_disable && oc->oformat->video_codec != AV_CODEC_ID_NONE) {
+            int area = 0, idx = -1;
+            int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0);
+            for (i = 0; i < nb_input_streams; i++) {
+                int new_area;
+                ist = input_streams[i];
+                new_area = ist->st->codec->width * ist->st->codec->height;
+                if((qcr!=MKTAG('A', 'P', 'I', 'C')) && (ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+                    new_area = 1;
+                if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+                    new_area > area) {
+                    if((qcr==MKTAG('A', 'P', 'I', 'C')) && !(ist->st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+                        continue;
+                    area = new_area;
+                    idx = i;
+                }
+            }
+            if (idx >= 0)
+                new_video_stream(o, oc, idx);
+        }
+
+        /* audio: most channels */
+        if (!o->audio_disable && oc->oformat->audio_codec != AV_CODEC_ID_NONE) {
+            int channels = 0, idx = -1;
+            for (i = 0; i < nb_input_streams; i++) {
+                ist = input_streams[i];
+                if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
+                    ist->st->codec->channels > channels) {
+                    channels = ist->st->codec->channels;
+                    idx = i;
+                }
+            }
+            if (idx >= 0)
+                new_audio_stream(o, oc, idx);
+        }
+
+        /* subtitles: pick first */
+        MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, oc, "s");
+        if (!o->subtitle_disable && (oc->oformat->subtitle_codec != AV_CODEC_ID_NONE || subtitle_codec_name)) {
+            for (i = 0; i < nb_input_streams; i++)
+                if (input_streams[i]->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+                    new_subtitle_stream(o, oc, i);
+                    break;
+                }
+        }
+        /* do something with data? */
+    } else {
+        for (i = 0; i < o->nb_stream_maps; i++) {
+            StreamMap *map = &o->stream_maps[i];
+            int src_idx = input_files[map->file_index]->ist_index + map->stream_index;
+
+            if (map->disabled)
+                continue;
+
+            if (map->linklabel) {
+                FilterGraph *fg;
+                OutputFilter *ofilter = NULL;
+                int j, k;
+
+                for (j = 0; j < nb_filtergraphs; j++) {
+                    fg = filtergraphs[j];
+                    for (k = 0; k < fg->nb_outputs; k++) {
+                        AVFilterInOut *out = fg->outputs[k]->out_tmp;
+                        if (out && !strcmp(out->name, map->linklabel)) {
+                            ofilter = fg->outputs[k];
+                            goto loop_end;
+                        }
+                    }
+                }
+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);
+                    exit(1);
+                }
+                init_output_filter(ofilter, o, oc);
+            } else {
+                ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];
+                if(o->subtitle_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
+                    continue;
+                if(o->   audio_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+                    continue;
+                if(o->   video_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+                    continue;
+                if(o->    data_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_DATA)
+                    continue;
+
+                switch (ist->st->codec->codec_type) {
+                case AVMEDIA_TYPE_VIDEO:      ost = new_video_stream     (o, oc, src_idx); break;
+                case AVMEDIA_TYPE_AUDIO:      ost = new_audio_stream     (o, oc, src_idx); break;
+                case AVMEDIA_TYPE_SUBTITLE:   ost = new_subtitle_stream  (o, oc, src_idx); break;
+                case AVMEDIA_TYPE_DATA:       ost = new_data_stream      (o, oc, src_idx); break;
+                case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc, src_idx); break;
+                default:
+                    av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
+                           map->file_index, map->stream_index);
+                    exit(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
+            && (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;
+        uint8_t *attachment;
+        const char *p;
+        int64_t len;
+
+        if ((err = avio_open2(&pb, o->attachments[i], AVIO_FLAG_READ, &int_cb, NULL)) < 0) {
+            av_log(NULL, AV_LOG_FATAL, "Could not open attachment file %s.\n",
+                   o->attachments[i]);
+            exit(1);
+        }
+        if ((len = avio_size(pb)) <= 0) {
+            av_log(NULL, AV_LOG_FATAL, "Could not get size of the attachment %s.\n",
+                   o->attachments[i]);
+            exit(1);
+        }
+        if (!(attachment = av_malloc(len))) {
+            av_log(NULL, AV_LOG_FATAL, "Attachment %s too large to fit into memory.\n",
+                   o->attachments[i]);
+            exit(1);
+        }
+        avio_read(pb, attachment, len);
+
+        ost = new_attachment_stream(o, oc, -1);
+        ost->stream_copy               = 0;
+        ost->attachment_filename       = o->attachments[i];
+        ost->st->codec->extradata      = attachment;
+        ost->st->codec->extradata_size = len;
+
+        p = strrchr(o->attachments[i], '/');
+        av_dict_set(&ost->st->metadata, "filename", (p && *p) ? p + 1 : o->attachments[i], AV_DICT_DONT_OVERWRITE);
+        avio_close(pb);
+    }
+
+    output_files = grow_array(output_files, sizeof(*output_files), &nb_output_files, nb_output_files + 1);
+    if (!(output_files[nb_output_files - 1] = av_mallocz(sizeof(*output_files[0]))))
+        exit(1);
+
+    output_files[nb_output_files - 1]->ctx            = oc;
+    output_files[nb_output_files - 1]->ost_index      = nb_output_streams - oc->nb_streams;
+    output_files[nb_output_files - 1]->recording_time = o->recording_time;
+    if (o->recording_time != INT64_MAX)
+        oc->duration = o->recording_time;
+    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);
+
+    /* check filename in case of an image number is expected */
+    if (oc->oformat->flags & AVFMT_NEEDNUMBER) {
+        if (!av_filename_number_test(oc->filename)) {
+            print_error(oc->filename, AVERROR(EINVAL));
+            exit(1);
+        }
+    }
+
+    if (!(oc->oformat->flags & AVFMT_NOFILE)) {
+        /* test if it already exists to avoid losing precious files */
+        assert_file_overwrite(filename);
+
+        /* open the file */
+        if ((err = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,
+                              &oc->interrupt_callback,
+                              &output_files[nb_output_files - 1]->opts)) < 0) {
+            print_error(filename, err);
+            exit(1);
+        }
+    }
+
+    if (o->mux_preload) {
+        uint8_t buf[64];
+        snprintf(buf, sizeof(buf), "%d", (int)(o->mux_preload*AV_TIME_BASE));
+        av_dict_set(&output_files[nb_output_files - 1]->opts, "preload", buf, 0);
+    }
+    oc->max_delay = (int)(o->mux_max_delay * AV_TIME_BASE);
+
+    /* copy metadata */
+    for (i = 0; i < o->nb_metadata_map; i++) {
+        char *p;
+        int in_file_index = strtol(o->metadata_map[i].u.str, &p, 0);
+
+        if (in_file_index >= nb_input_files) {
+            av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d while processing metadata maps\n", in_file_index);
+            exit(1);
+        }
+        copy_metadata(o->metadata_map[i].specifier, *p ? p + 1 : p, oc, in_file_index >= 0 ? input_files[in_file_index]->ctx : NULL, o);
+    }
+
+    /* copy chapters */
+    if (o->chapters_input_file >= nb_input_files) {
+        if (o->chapters_input_file == INT_MAX) {
+            /* copy chapters from the first input file that has them*/
+            o->chapters_input_file = -1;
+            for (i = 0; i < nb_input_files; i++)
+                if (input_files[i]->ctx->nb_chapters) {
+                    o->chapters_input_file = i;
+                    break;
+                }
+        } else {
+            av_log(NULL, AV_LOG_FATAL, "Invalid input file index %d in chapter mapping.\n",
+                   o->chapters_input_file);
+            exit(1);
+        }
+    }
+    if (o->chapters_input_file >= 0)
+        copy_chapters(input_files[o->chapters_input_file], output_files[nb_output_files - 1],
+                      !o->metadata_chapters_manual);
+
+    /* copy global metadata by default */
+    if (!o->metadata_global_manual && nb_input_files){
+        av_dict_copy(&oc->metadata, input_files[0]->ctx->metadata,
+                     AV_DICT_DONT_OVERWRITE);
+        if(o->recording_time != INT64_MAX)
+            av_dict_set(&oc->metadata, "duration", NULL, 0);
+        av_dict_set(&oc->metadata, "creation_time", NULL, 0);
+    }
+    if (!o->metadata_streams_manual)
+        for (i = output_files[nb_output_files - 1]->ost_index; i < nb_output_streams; i++) {
+            InputStream *ist;
+            if (output_streams[i]->source_index < 0)         /* this is true e.g. for attached files */
+                continue;
+            ist = input_streams[output_streams[i]->source_index];
+            av_dict_copy(&output_streams[i]->st->metadata, ist->st->metadata, AV_DICT_DONT_OVERWRITE);
+        }
+
+    /* process manually set metadata */
+    for (i = 0; i < o->nb_metadata; i++) {
+        AVDictionary **m;
+        char type, *val;
+        const char *stream_spec;
+        int index = 0, j, ret = 0;
+
+        val = strchr(o->metadata[i].u.str, '=');
+        if (!val) {
+            av_log(NULL, AV_LOG_FATAL, "No '=' character in metadata string %s.\n",
+                   o->metadata[i].u.str);
+            exit(1);
+        }
+        *val++ = 0;
+
+        parse_meta_type(o->metadata[i].specifier, &type, &index, &stream_spec);
+        if (type == 's') {
+            for (j = 0; j < oc->nb_streams; j++) {
+                if ((ret = check_stream_specifier(oc, oc->streams[j], stream_spec)) > 0) {
+                    av_dict_set(&oc->streams[j]->metadata, o->metadata[i].u.str, *val ? val : NULL, 0);
+                } else if (ret < 0)
+                    exit(1);
+            }
+        }
+        else {
+            switch (type) {
+            case 'g':
+                m = &oc->metadata;
+                break;
+            case 'c':
+                if (index < 0 || index >= oc->nb_chapters) {
+                    av_log(NULL, AV_LOG_FATAL, "Invalid chapter index %d in metadata specifier.\n", index);
+                    exit(1);
+                }
+                m = &oc->chapters[index]->metadata;
+                break;
+            default:
+                av_log(NULL, AV_LOG_FATAL, "Invalid metadata specifier %s.\n", o->metadata[i].specifier);
+                exit(1);
+            }
+            av_dict_set(m, o->metadata[i].u.str, *val ? val : NULL, 0);
+        }
+    }
+
+    reset_options(o, 0);
+}
+
+static int opt_target(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    enum { PAL, NTSC, FILM, UNKNOWN } norm = UNKNOWN;
+    static const char *const frame_rates[] = { "25", "30000/1001", "24000/1001" };
+
+    if (!strncmp(arg, "pal-", 4)) {
+        norm = PAL;
+        arg += 4;
+    } else if (!strncmp(arg, "ntsc-", 5)) {
+        norm = NTSC;
+        arg += 5;
+    } else if (!strncmp(arg, "film-", 5)) {
+        norm = FILM;
+        arg += 5;
+    } else {
+        /* Try to determine PAL/NTSC by peeking in the input files */
+        if (nb_input_files) {
+            int i, j, fr;
+            for (j = 0; j < nb_input_files; j++) {
+                for (i = 0; i < input_files[j]->nb_streams; i++) {
+                    AVCodecContext *c = input_files[j]->ctx->streams[i]->codec;
+                    if (c->codec_type != AVMEDIA_TYPE_VIDEO)
+                        continue;
+                    fr = c->time_base.den * 1000 / c->time_base.num;
+                    if (fr == 25000) {
+                        norm = PAL;
+                        break;
+                    } else if ((fr == 29970) || (fr == 23976)) {
+                        norm = NTSC;
+                        break;
+                    }
+                }
+                if (norm != UNKNOWN)
+                    break;
+            }
+        }
+        if (norm != UNKNOWN)
+            av_log(NULL, AV_LOG_INFO, "Assuming %s for target.\n", norm == PAL ? "PAL" : "NTSC");
+    }
+
+    if (norm == UNKNOWN) {
+        av_log(NULL, AV_LOG_FATAL, "Could not determine norm (PAL/NTSC/NTSC-Film) for target.\n");
+        av_log(NULL, AV_LOG_FATAL, "Please prefix target with \"pal-\", \"ntsc-\" or \"film-\",\n");
+        av_log(NULL, AV_LOG_FATAL, "or set a framerate with \"-r xxx\".\n");
+        exit(1);
+    }
+
+    if (!strcmp(arg, "vcd")) {
+        opt_video_codec(o, "c:v", "mpeg1video");
+        opt_audio_codec(o, "c:a", "mp2");
+        parse_option(o, "f", "vcd", options);
+
+        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");
+
+        opt_default(NULL, "b:v", "1150000");
+        opt_default(NULL, "maxrate", "1150000");
+        opt_default(NULL, "minrate", "1150000");
+        opt_default(NULL, "bufsize", "327680"); // 40*1024*8;
+
+        opt_default(NULL, "b:a", "224000");
+        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;
+
+        /* 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
+           and the first pack from the other stream, respectively, may also have
+           been written before.
+           So the real data starts at SCR 36000+3*1200. */
+        o->mux_preload = (36000 + 3 * 1200) / 90000.0; // 0.44
+    } else if (!strcmp(arg, "svcd")) {
+
+        opt_video_codec(o, "c:v", "mpeg2video");
+        opt_audio_codec(o, "c:a", "mp2");
+        parse_option(o, "f", "svcd", options);
+
+        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");
+
+        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");
+
+        opt_default(NULL, "b:a", "224000");
+        parse_option(o, "ar", "44100", options);
+
+        opt_default(NULL, "packetsize", "2324");
+
+    } else if (!strcmp(arg, "dvd")) {
+
+        opt_video_codec(o, "c:v", "mpeg2video");
+        opt_audio_codec(o, "c:a", "ac3");
+        parse_option(o, "f", "dvd", options);
+
+        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");
+
+        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;
+
+        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
+
+        opt_default(NULL, "b:a", "448000");
+        parse_option(o, "ar", "48000", options);
+
+    } else if (!strncmp(arg, "dv", 2)) {
+
+        parse_option(o, "f", "dv", options);
+
+        parse_option(o, "s", norm == PAL ? "720x576" : "720x480", options);
+        parse_option(o, "pix_fmt", !strncmp(arg, "dv50", 4) ? "yuv422p" :
+                          norm == PAL ? "yuv420p" : "yuv411p", options);
+        parse_option(o, "r", frame_rates[norm], options);
+
+        parse_option(o, "ar", "48000", options);
+        parse_option(o, "ac", "2", options);
+
+    } else {
+        av_log(NULL, AV_LOG_ERROR, "Unknown target: %s\n", arg);
+        return AVERROR(EINVAL);
+    }
+    return 0;
+}
+
+static int opt_vstats_file(void *optctx, const char *opt, const char *arg)
+{
+    av_free (vstats_filename);
+    vstats_filename = av_strdup (arg);
+    return 0;
+}
+
+static int opt_vstats(void *optctx, const char *opt, const char *arg)
+{
+    char filename[40];
+    time_t today2 = time(NULL);
+    struct tm *today = localtime(&today2);
+
+    snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min,
+             today->tm_sec);
+    return opt_vstats_file(NULL, opt, filename);
+}
+
+static int opt_video_frames(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    return parse_option(o, "frames:v", arg, options);
+}
+
+static int opt_audio_frames(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    return parse_option(o, "frames:a", arg, options);
+}
+
+static int opt_data_frames(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    return parse_option(o, "frames:d", arg, options);
+}
+
+static int opt_preset(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    FILE *f=NULL;
+    char filename[1000], line[1000], tmp_line[1000];
+    const char *codec_name = NULL;
+
+    tmp_line[0] = *opt;
+    tmp_line[1] = 0;
+    MATCH_PER_TYPE_OPT(codec_names, str, codec_name, NULL, tmp_line);
+
+    if (!(f = get_preset_file(filename, sizeof(filename), arg, *opt == 'f', codec_name))) {
+        if(!strncmp(arg, "libx264-lossless", strlen("libx264-lossless"))){
+            av_log(NULL, AV_LOG_FATAL, "Please use -preset <speed> -qp 0\n");
+        }else
+            av_log(NULL, AV_LOG_FATAL, "File for preset '%s' not found\n", arg);
+        exit(1);
+}
+
+    while (fgets(line, sizeof(line), f)) {
+        char *key = tmp_line, *value, *endptr;
+
+        if (strcspn(line, "#\n\r") == 0)
+            continue;
+        strcpy(tmp_line, line);
+        if (!av_strtok(key,   "=",    &value) ||
+            !av_strtok(value, "\r\n", &endptr)) {
+            av_log(NULL, AV_LOG_FATAL, "%s: Invalid syntax: '%s'\n", filename, line);
+            exit(1);
+        }
+        av_log(NULL, AV_LOG_DEBUG, "ffpreset[%s]: set '%s' = '%s'\n", filename, key, value);
+
+        if      (!strcmp(key, "acodec")) opt_audio_codec   (o, key, value);
+        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) {
+            av_log(NULL, AV_LOG_FATAL, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n",
+                   filename, line, key, value);
+            exit(1);
+        }
+    }
+
+    fclose(f);
+
+    return 0;
+}
+
+static int opt_old2new(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    char *s = av_asprintf("%s:%c", opt + 1, *opt);
+    int ret = parse_option(o, s, arg, options);
+    av_free(s);
+    return ret;
+}
+
+static int opt_bitrate(void *optctx, const char *opt, const char *arg)
+{
+    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);
+    }
+    return opt_default(optctx, opt, arg);
+}
+
+static int opt_qscale(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    char *s;
+    int ret;
+    if(!strcmp(opt, "qscale")){
+        av_log(NULL, AV_LOG_WARNING, "Please use -q:a or -q:v, -qscale is ambiguous\n");
+        return parse_option(o, "q:v", arg, options);
+    }
+    s = av_asprintf("q%s", opt + 6);
+    ret = parse_option(o, s, arg, options);
+    av_free(s);
+    return ret;
+}
+
+static int opt_profile(void *optctx, const char *opt, const char *arg)
+{
+    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);
+    }
+    return opt_default(optctx, opt, arg);
+
+}
+
+static int opt_video_filters(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    return parse_option(o, "filter:v", arg, options);
+}
+
+static int opt_audio_filters(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    return parse_option(o, "filter:a", arg, options);
+}
+
+static int opt_vsync(void *optctx, const char *opt, const char *arg)
+{
+    if      (!av_strcasecmp(arg, "cfr"))         video_sync_method = VSYNC_CFR;
+    else if (!av_strcasecmp(arg, "vfr"))         video_sync_method = VSYNC_VFR;
+    else if (!av_strcasecmp(arg, "passthrough")) video_sync_method = VSYNC_PASSTHROUGH;
+    else if (!av_strcasecmp(arg, "drop"))        video_sync_method = VSYNC_DROP;
+
+    if (video_sync_method == VSYNC_AUTO)
+        video_sync_method = parse_number_or_die("vsync", arg, OPT_INT, VSYNC_AUTO, VSYNC_VFR);
+    return 0;
+}
+
+static int opt_deinterlace(void *optctx, const char *opt, const char *arg)
+{
+    av_log(NULL, AV_LOG_WARNING, "-%s is deprecated, use -filter:v yadif instead\n", opt);
+    do_deinterlace = 1;
+    return 0;
+}
+
+static int opt_timecode(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    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);
+    av_free(tcr);
+    return ret;
+}
+
+static int opt_channel_layout(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    char layout_str[32];
+    char *stream_str;
+    char *ac_str;
+    int ret, channels, ac_str_size;
+    uint64_t layout;
+
+    layout = av_get_channel_layout(arg);
+    if (!layout) {
+        av_log(NULL, AV_LOG_ERROR, "Unknown channel layout: %s\n", arg);
+        return AVERROR(EINVAL);
+    }
+    snprintf(layout_str, sizeof(layout_str), "%"PRIu64, layout);
+    ret = opt_default(NULL, opt, layout_str);
+    if (ret < 0)
+        return ret;
+
+    /* set 'ac' option based on channel layout */
+    channels = av_get_channel_layout_nb_channels(layout);
+    snprintf(layout_str, sizeof(layout_str), "%d", channels);
+    stream_str = strchr(opt, ':');
+    ac_str_size = 3 + (stream_str ? strlen(stream_str) : 0);
+    ac_str = av_mallocz(ac_str_size);
+    if (!ac_str)
+        return AVERROR(ENOMEM);
+    av_strlcpy(ac_str, "ac", 3);
+    if (stream_str)
+        av_strlcat(ac_str, stream_str, ac_str_size);
+    ret = parse_option(o, ac_str, layout_str, options);
+    av_free(ac_str);
+
+    return ret;
+}
+
+static int opt_audio_qscale(void *optctx, const char *opt, const char *arg)
+{
+    OptionsContext *o = optctx;
+    return parse_option(o, "q:a", arg, options);
+}
+
+static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
+{
+    filtergraphs = grow_array(filtergraphs, sizeof(*filtergraphs),
+                              &nb_filtergraphs, nb_filtergraphs + 1);
+    if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
+        return AVERROR(ENOMEM);
+    filtergraphs[nb_filtergraphs - 1]->index       = nb_filtergraphs - 1;
+    filtergraphs[nb_filtergraphs - 1]->graph_desc = arg;
+    return 0;
+}
+
+void show_help_default(const char *opt, const char *arg)
+{
+    /* per-file options have at least one of those set */
+    const int per_file = OPT_SPEC | OPT_OFFSET | OPT_PERFILE;
+    int show_advanced = 0, show_avoptions = 0;
+
+    if (opt && *opt) {
+        if (!strcmp(opt, "long"))
+            show_advanced = 1;
+        else if (!strcmp(opt, "full"))
+            show_advanced = show_avoptions = 1;
+        else
+            av_log(NULL, AV_LOG_ERROR, "Unknown help option '%s'.\n", opt);
+    }
+
+    show_usage();
+
+    printf("Getting help:\n"
+           "    -h      -- print basic options\n"
+           "    -h long -- print more options\n"
+           "    -h full -- print all options (including all format and codec specific options, very long)\n"
+           "    See man %s for detailed description of the options.\n"
+           "\n", program_name);
+
+    show_help_options(options, "Print help / information / capabilities:",
+                      OPT_EXIT, 0, 0);
+
+    show_help_options(options, "Global options (affect whole program "
+                      "instead of just one file:",
+                      0, per_file | OPT_EXIT | OPT_EXPERT, 0);
+    if (show_advanced)
+        show_help_options(options, "Advanced global options:", OPT_EXPERT,
+                          per_file | OPT_EXIT, 0);
+
+    show_help_options(options, "Per-file main options:", 0,
+                      OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE |
+                      OPT_EXIT, per_file);
+    if (show_advanced)
+        show_help_options(options, "Advanced per-file options:",
+                          OPT_EXPERT, OPT_AUDIO | OPT_VIDEO | OPT_SUBTITLE, per_file);
+
+    show_help_options(options, "Video options:",
+                      OPT_VIDEO, OPT_EXPERT | OPT_AUDIO, 0);
+    if (show_advanced)
+        show_help_options(options, "Advanced Video options:",
+                          OPT_EXPERT | OPT_VIDEO, OPT_AUDIO, 0);
+
+    show_help_options(options, "Audio options:",
+                      OPT_AUDIO, OPT_EXPERT | OPT_VIDEO, 0);
+    if (show_advanced)
+        show_help_options(options, "Advanced Audio options:",
+                          OPT_EXPERT | OPT_AUDIO, OPT_VIDEO, 0);
+    show_help_options(options, "Subtitle options:",
+                      OPT_SUBTITLE, 0, 0);
+    printf("\n");
+
+    if (show_avoptions) {
+        int flags = AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM;
+        show_help_children(avcodec_get_class(), flags);
+        show_help_children(avformat_get_class(), flags);
+        show_help_children(sws_get_class(), flags);
+        show_help_children(swr_get_class(), AV_OPT_FLAG_AUDIO_PARAM);
+        show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
+    }
+}
+
+void show_usage(void)
+{
+    av_log(NULL, AV_LOG_INFO, "Hyper fast Audio and Video encoder\n");
+    av_log(NULL, AV_LOG_INFO, "usage: %s [options] [[infile options] -i infile]... {[outfile options] outfile}...\n", program_name);
+    av_log(NULL, AV_LOG_INFO, "\n");
+}
+
+
+static int opt_progress(void *optctx, const char *opt, const char *arg)
+{
+    AVIOContext *avio = NULL;
+    int ret;
+
+    if (!strcmp(arg, "-"))
+        arg = "pipe:";
+    ret = avio_open2(&avio, arg, AVIO_FLAG_WRITE, &int_cb, NULL);
+    if (ret < 0) {
+        av_log(0, AV_LOG_ERROR, "Failed to open progress URL \"%s\": %s\n",
+               arg, av_err2str(ret));
+        return ret;
+    }
+    progress_avio = avio;
+    return 0;
+}
+
+#define OFFSET(x) offsetof(OptionsContext, x)
+const OptionDef options[] = {
+    /* main options */
+#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 },
+        "do not overwrite output files" },
+    { "c",              HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(codec_names) },
+        "codec name", "codec" },
+    { "codec",          HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(codec_names) },
+        "codec name", "codec" },
+    { "pre",            HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(presets) },
+        "preset name", "preset" },
+    { "map",            HAS_ARG | OPT_EXPERT | OPT_PERFILE,          { .func_arg = opt_map },
+        "set input stream mapping",
+        "[-]input_file_id[:stream_specifier][,sync_file_id[:stream_specifier]]" },
+    { "map_channel",    HAS_ARG | OPT_EXPERT | OPT_PERFILE,          { .func_arg = opt_map_channel },
+        "map an audio channel from one stream to another", "file.stream.channel[:syncfile.syncstream]" },
+    { "map_metadata",   HAS_ARG | OPT_STRING | OPT_SPEC,             { .off       = OFFSET(metadata_map) },
+        "set metadata information of outfile from infile",
+        "outfile[,metadata]:infile[,metadata]" },
+    { "map_chapters",   HAS_ARG | OPT_INT | OPT_EXPERT | OPT_OFFSET, { .off = OFFSET(chapters_input_file) },
+        "set chapters mapping", "input_file_index" },
+    { "t",              HAS_ARG | OPT_TIME | OPT_OFFSET,             { .off = OFFSET(recording_time) },
+        "record or transcode \"duration\" seconds of audio/video",
+        "duration" },
+    { "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) },
+        "set the start time offset", "time_off" },
+    { "itsoffset",      HAS_ARG | OPT_TIME | OPT_OFFSET | OPT_EXPERT,{ .off = OFFSET(input_ts_offset) },
+        "set the input ts offset", "time_off" },
+    { "itsscale",       HAS_ARG | OPT_DOUBLE | OPT_SPEC | OPT_EXPERT,{ .off = OFFSET(ts_scale) },
+        "set the input ts scale", "scale" },
+    { "timestamp",      HAS_ARG | OPT_PERFILE,                       { .func_arg = opt_recording_timestamp },
+        "set the recording timestamp ('now' to set the current time)", "time" },
+    { "metadata",       HAS_ARG | OPT_STRING | OPT_SPEC,             { .off = OFFSET(metadata) },
+        "add metadata", "string=string" },
+    { "dframes",        HAS_ARG | OPT_PERFILE | OPT_EXPERT,          { .func_arg = opt_data_frames },
+        "set the number of data frames to record", "number" },
+    { "benchmark",      OPT_BOOL | OPT_EXPERT,                       { &do_benchmark },
+        "add timings for benchmarking" },
+    { "benchmark_all",  OPT_BOOL | OPT_EXPERT,                       { &do_benchmark_all },
+      "add timings for each task" },
+    { "progress",       HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_progress },
+      "write program-readable progress information", "url" },
+    { "stdin",          OPT_BOOL | OPT_EXPERT,                       { &stdin_interaction },
+      "enable or disable interaction on standard input" },
+    { "timelimit",      HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_timelimit },
+        "set max runtime in seconds", "limit" },
+    { "dump",           OPT_BOOL | OPT_EXPERT,                       { &do_pkt_dump },
+        "dump each input packet" },
+    { "hex",            OPT_BOOL | OPT_EXPERT,                       { &do_hex_dump },
+        "when dumping packets, also dump the payload" },
+    { "re",             OPT_BOOL | OPT_EXPERT | OPT_OFFSET,          { .off = OFFSET(rate_emu) },
+        "read input at native frame rate", "" },
+    { "target",         HAS_ARG | OPT_PERFILE,                       { .func_arg = opt_target },
+        "specify target file type (\"vcd\", \"svcd\", \"dvd\","
+        " \"dv\", \"dv50\", \"pal-vcd\", \"ntsc-svcd\", ...)", "type" },
+    { "vsync",          HAS_ARG | OPT_EXPERT,                        { opt_vsync },
+        "video sync method", "" },
+    { "async",          HAS_ARG | OPT_INT | OPT_EXPERT,              { &audio_sync_method },
+        "audio sync method", "" },
+    { "adrift_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,          { &audio_drift_threshold },
+        "audio drift threshold", "threshold" },
+    { "copyts",         OPT_BOOL | OPT_EXPERT,                       { &copy_ts },
+        "copy timestamps" },
+    { "copytb",         HAS_ARG | OPT_INT | OPT_EXPERT,              { &copy_tb },
+        "copy input stream time base when stream copying", "mode" },
+    { "shortest",       OPT_BOOL | OPT_EXPERT | OPT_OFFSET,          { .off = OFFSET(shortest) },
+        "finish encoding within shortest input" },
+    { "dts_delta_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,       { &dts_delta_threshold },
+        "timestamp discontinuity delta threshold", "threshold" },
+    { "dts_error_threshold", HAS_ARG | OPT_FLOAT | OPT_EXPERT,       { &dts_error_threshold },
+        "timestamp error delta threshold", "threshold" },
+    { "xerror",         OPT_BOOL | OPT_EXPERT,                       { &exit_on_error },
+        "exit on error", "error" },
+    { "copyinkf",       OPT_BOOL | OPT_EXPERT | OPT_SPEC,            { .off = OFFSET(copy_initial_nonkeyframes) },
+        "copy initial non-keyframes" },
+    { "copypriorss",    OPT_INT | HAS_ARG | OPT_EXPERT | OPT_SPEC,   { .off = OFFSET(copy_prior_start) },
+        "copy or discard frames before start time" },
+    { "frames",         OPT_INT64 | HAS_ARG | OPT_SPEC,              { .off = OFFSET(max_frames) },
+        "set the number of frames to record", "number" },
+    { "tag",            OPT_STRING | HAS_ARG | OPT_SPEC | OPT_EXPERT,{ .off = OFFSET(codec_tags) },
+        "force codec tag/fourcc", "fourcc/tag" },
+    { "q",              HAS_ARG | OPT_EXPERT | OPT_DOUBLE | OPT_SPEC,{ .off = OFFSET(qscale) },
+        "use fixed quality scale (VBR)", "q" },
+    { "qscale",         HAS_ARG | OPT_EXPERT | OPT_PERFILE,          { .func_arg = opt_qscale },
+        "use fixed quality scale (VBR)", "q" },
+    { "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" },
+    { "filter_complex", HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_filter_complex },
+        "create a complex filtergraph", "graph_description" },
+    { "stats",          OPT_BOOL,                                    { &print_stats },
+        "print progress report during encoding", },
+    { "attach",         HAS_ARG | OPT_PERFILE | OPT_EXPERT,          { .func_arg = opt_attach },
+        "add an attachment to the output file", "filename" },
+    { "dump_attachment", HAS_ARG | OPT_STRING | OPT_SPEC |OPT_EXPERT,{ .off = OFFSET(dump_attachment) },
+        "extract an attachment into a file", "filename" },
+    { "debug_ts",       OPT_BOOL | OPT_EXPERT,                       { &debug_ts },
+        "print timestamp debugging info" },
+
+    /* video options */
+    { "vframes",      OPT_VIDEO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_video_frames },
+        "set the number of video frames to record", "number" },
+    { "r",            OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC,              { .off = OFFSET(frame_rates) },
+        "set frame rate (Hz value, fraction or abbreviation)", "rate" },
+    { "s",            OPT_VIDEO | HAS_ARG | OPT_SUBTITLE | OPT_STRING | OPT_SPEC,{ .off = OFFSET(frame_sizes) },
+        "set frame size (WxH or abbreviation)", "size" },
+    { "aspect",       OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC,              { .off = OFFSET(frame_aspect_ratios) },
+        "set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)", "aspect" },
+    { "pix_fmt",      OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC, { .off = OFFSET(frame_pix_fmts) },
+        "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) },
+        "disable video" },
+    { "vdt",          OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT ,               { &video_discard },
+        "discard threshold", "n" },
+    { "rc_override",  OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_STRING | OPT_SPEC, { .off = OFFSET(rc_overrides) },
+        "rate control override for specific intervals", "override" },
+    { "vcodec",       OPT_VIDEO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_video_codec },
+        "force video codec ('copy' to copy stream)", "codec" },
+    { "sameq",        OPT_VIDEO | OPT_EXPERT ,                                   { .func_arg = opt_sameq },
+        "Removed" },
+    { "same_quant",   OPT_VIDEO | OPT_EXPERT ,                                   { .func_arg = opt_sameq },
+        "Removed" },
+    { "timecode",     OPT_VIDEO | HAS_ARG | OPT_PERFILE,                         { .func_arg = opt_timecode },
+        "set initial TimeCode value.", "hh:mm:ss[:;.]ff" },
+    { "pass",         OPT_VIDEO | HAS_ARG | OPT_SPEC | OPT_INT,                  { .off = OFFSET(pass) },
+        "select the pass number (1 to 3)", "n" },
+    { "passlogfile",  OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_EXPERT | OPT_SPEC,  { .off = OFFSET(passlogfiles) },
+        "select two pass log file name prefix", "prefix" },
+    { "deinterlace",  OPT_VIDEO | OPT_EXPERT ,                                   { .func_arg = opt_deinterlace },
+        "this option is deprecated, use the yadif filter instead" },
+    { "psnr",         OPT_VIDEO | OPT_BOOL | OPT_EXPERT,                         { &do_psnr },
+        "calculate PSNR of compressed frames" },
+    { "vstats",       OPT_VIDEO | OPT_EXPERT ,                                   { &opt_vstats },
+        "dump video coding statistics to file" },
+    { "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" },
+    { "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) },
+        "specify inter matrix coeffs", "matrix" },
+    { "top",          OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_INT| OPT_SPEC,     { .off = OFFSET(top_field_first) },
+        "top=1/bottom=0/auto=-1 field first", "" },
+    { "dc",           OPT_VIDEO | OPT_INT | HAS_ARG | OPT_EXPERT ,               { &intra_dc_precision },
+        "intra_dc_precision", "precision" },
+    { "vtag",         OPT_VIDEO | HAS_ARG | OPT_EXPERT  | OPT_PERFILE,           { .func_arg = opt_old2new },
+        "force video tag/fourcc", "fourcc/tag" },
+    { "qphist",       OPT_VIDEO | OPT_BOOL | OPT_EXPERT ,                        { &qp_hist },
+        "show QP histogram" },
+    { "force_fps",    OPT_VIDEO | OPT_BOOL | OPT_EXPERT  | OPT_SPEC,             { .off = OFFSET(force_fps) },
+        "force the selected framerate, disable the best supported framerate selection" },
+    { "streamid",     OPT_VIDEO | HAS_ARG | OPT_EXPERT | OPT_PERFILE,            { .func_arg = opt_streamid },
+        "set the value of an outfile streamid", "streamIndex:value" },
+    { "force_key_frames", OPT_VIDEO | OPT_STRING | HAS_ARG | OPT_EXPERT  | OPT_SPEC,
+        { .off = OFFSET(forced_key_frames) },
+        "force key frames at specified timestamps", "timestamps" },
+    { "b",            OPT_VIDEO | HAS_ARG | OPT_PERFILE,                         { .func_arg = opt_bitrate },
+        "video bitrate (please use -b:v)", "bitrate" },
+
+    /* audio options */
+    { "aframes",        OPT_AUDIO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_audio_frames },
+        "set the number of audio frames to record", "number" },
+    { "aq",             OPT_AUDIO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_audio_qscale },
+        "set audio quality (codec-specific)", "quality", },
+    { "ar",             OPT_AUDIO | HAS_ARG  | OPT_INT | OPT_SPEC,                 { .off = OFFSET(audio_sample_rate) },
+        "set audio sampling rate (in Hz)", "rate" },
+    { "ac",             OPT_AUDIO | HAS_ARG  | OPT_INT | OPT_SPEC,                 { .off = OFFSET(audio_channels) },
+        "set number of audio channels", "channels" },
+    { "an",             OPT_AUDIO | OPT_BOOL | OPT_OFFSET,                         { .off = OFFSET(audio_disable) },
+        "disable audio" },
+    { "acodec",         OPT_AUDIO | HAS_ARG  | OPT_PERFILE,                        { .func_arg = opt_audio_codec },
+        "force audio codec ('copy' to copy stream)", "codec" },
+    { "atag",           OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_PERFILE,           { .func_arg = opt_old2new },
+        "force audio tag/fourcc", "fourcc/tag" },
+    { "vol",            OPT_AUDIO | HAS_ARG  | OPT_INT,                            { &audio_volume },
+        "change audio volume (256=normal)" , "volume" },
+    { "sample_fmt",     OPT_AUDIO | HAS_ARG  | OPT_EXPERT | OPT_SPEC | OPT_STRING, { .off = OFFSET(sample_fmts) },
+        "set sample format", "format" },
+    { "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" },
+
+    /* subtitle options */
+    { "sn",     OPT_SUBTITLE | OPT_BOOL | OPT_OFFSET, { .off = OFFSET(subtitle_disable) },
+        "disable subtitle" },
+    { "scodec", OPT_SUBTITLE | HAS_ARG  | OPT_PERFILE, { .func_arg = opt_subtitle_codec },
+        "force subtitle codec ('copy' to copy stream)", "codec" },
+    { "stag",   OPT_SUBTITLE | HAS_ARG  | OPT_EXPERT  | OPT_PERFILE, { .func_arg = opt_old2new }
+        , "force subtitle tag/fourcc", "fourcc/tag" },
+    { "fix_sub_duration", OPT_BOOL | OPT_EXPERT | OPT_SUBTITLE | OPT_SPEC, { .off = OFFSET(fix_sub_duration) },
+        "fix subtitles duration" },
+
+    /* grab options */
+    { "vc", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_video_channel },
+        "deprecated, use -channel", "channel" },
+    { "tvstd", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_video_standard },
+        "deprecated, use -standard", "standard" },
+    { "isync", OPT_BOOL | OPT_EXPERT, { &input_sync }, "this option is deprecated and does nothing", "" },
+
+    /* muxer options */
+    { "muxdelay",   OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET, { .off = OFFSET(mux_max_delay) },
+        "set the maximum demux-decode delay", "seconds" },
+    { "muxpreload", OPT_FLOAT | HAS_ARG | OPT_EXPERT | OPT_OFFSET, { .off = OFFSET(mux_preload) },
+        "set the initial demux-decode delay", "seconds" },
+
+    { "bsf", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_EXPERT, { .off = OFFSET(bitstream_filters) },
+        "A comma-separated list of bitstream filters", "bitstream_filters" },
+    { "absf", HAS_ARG | OPT_AUDIO | OPT_EXPERT| OPT_PERFILE, { .func_arg = opt_old2new },
+        "deprecated", "audio bitstream_filters" },
+    { "vbsf", OPT_VIDEO | HAS_ARG | OPT_EXPERT| OPT_PERFILE, { .func_arg = opt_old2new },
+        "deprecated", "video bitstream_filters" },
+
+    { "apre", HAS_ARG | OPT_AUDIO | OPT_EXPERT| OPT_PERFILE,    { .func_arg = opt_preset },
+        "set the audio options to the indicated preset", "preset" },
+    { "vpre", OPT_VIDEO | HAS_ARG | OPT_EXPERT| OPT_PERFILE,    { .func_arg = opt_preset },
+        "set the video options to the indicated preset", "preset" },
+    { "spre", HAS_ARG | OPT_SUBTITLE | OPT_EXPERT| OPT_PERFILE, { .func_arg = opt_preset },
+        "set the subtitle options to the indicated preset", "preset" },
+    { "fpre", HAS_ARG | OPT_EXPERT| OPT_PERFILE,                { .func_arg = opt_preset },
+        "set options from indicated preset file", "filename" },
+    /* data codec support */
+    { "dcodec", HAS_ARG | OPT_DATA | OPT_PERFILE | OPT_EXPERT, { .func_arg = opt_data_codec },
+        "force data codec ('copy' to copy stream)", "codec" },
+    { "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
new file mode 100644
index 0000000..438c11d
--- /dev/null
+++ b/ffplay.c
@@ -0,0 +1,3214 @@
+/*
+ * 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
+ */
+
+/**
+ * @file
+ * simple media player based on the FFmpeg libraries
+ */
+
+#include "config.h"
+#include <inttypes.h>
+#include <math.h>
+#include <limits.h>
+#include <signal.h>
+#include "libavutil/avstring.h"
+#include "libavutil/colorspace.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/dict.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/samplefmt.h"
+#include "libavutil/avassert.h"
+#include "libavutil/time.h"
+#include "libavformat/avformat.h"
+#include "libavdevice/avdevice.h"
+#include "libswscale/swscale.h"
+#include "libavutil/opt.h"
+#include "libavcodec/avfft.h"
+#include "libswresample/swresample.h"
+
+#if CONFIG_AVFILTER
+# include "libavfilter/avcodec.h"
+# include "libavfilter/avfilter.h"
+# include "libavfilter/avfiltergraph.h"
+# include "libavfilter/buffersink.h"
+# include "libavfilter/buffersrc.h"
+#endif
+
+#include <SDL.h>
+#include <SDL_thread.h>
+
+#include "cmdutils.h"
+
+#include <assert.h>
+
+const char program_name[] = "ffplay";
+const int program_birth_year = 2003;
+
+#define MAX_QUEUE_SIZE (15 * 1024 * 1024)
+#define MIN_FRAMES 5
+
+/* SDL audio buffer size, in samples. Should be small to have precise
+   A/V sync as SDL does not have hardware buffer fullness info. */
+#define SDL_AUDIO_BUFFER_SIZE 1024
+
+/* no AV sync correction is done if below the AV sync threshold */
+#define AV_SYNC_THRESHOLD 0.01
+/* no AV correction is done if too big error */
+#define AV_NOSYNC_THRESHOLD 10.0
+
+/* maximum audio speed change to get correct sync */
+#define SAMPLE_CORRECTION_PERCENT_MAX 10
+
+/* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
+#define AUDIO_DIFF_AVG_NB   20
+
+/* 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)
+
+static int sws_flags = SWS_BICUBIC;
+
+typedef struct PacketQueue {
+    AVPacketList *first_pkt, *last_pkt;
+    int nb_packets;
+    int size;
+    int abort_request;
+    SDL_mutex *mutex;
+    SDL_cond *cond;
+} PacketQueue;
+
+#define VIDEO_PICTURE_QUEUE_SIZE 4
+#define SUBPICTURE_QUEUE_SIZE 4
+
+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;
+    int allocated;
+    int reallocate;
+
+#if CONFIG_AVFILTER
+    AVFilterBufferRef *picref;
+#endif
+} VideoPicture;
+
+typedef struct SubPicture {
+    double pts; /* presentation time stamp for this picture */
+    AVSubtitle sub;
+} SubPicture;
+
+typedef struct AudioParams {
+    int freq;
+    int channels;
+    int channel_layout;
+    enum AVSampleFormat fmt;
+} AudioParams;
+
+enum {
+    AV_SYNC_AUDIO_MASTER, /* default choice */
+    AV_SYNC_VIDEO_MASTER,
+    AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
+};
+
+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 seek_req;
+    int seek_flags;
+    int64_t seek_pos;
+    int64_t seek_rel;
+    int read_pause_return;
+    AVFormatContext *ic;
+
+    int audio_stream;
+
+    int av_sync_type;
+    double external_clock; /* external clock base */
+    int64_t external_clock_time;
+
+    double audio_clock;
+    double audio_diff_cum; /* used for AV difference average computation */
+    double audio_diff_avg_coef;
+    double audio_diff_threshold;
+    int audio_diff_avg_count;
+    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 */
+    int audio_buf_index; /* in bytes */
+    int audio_write_buf_size;
+    AVPacket audio_pkt_temp;
+    AVPacket audio_pkt;
+    struct AudioParams audio_src;
+    struct AudioParams audio_tgt;
+    struct SwrContext *swr_ctx;
+    double audio_current_pts;
+    double audio_current_pts_drift;
+    int frame_drops_early;
+    int frame_drops_late;
+    AVFrame *frame;
+
+    enum ShowMode {
+        SHOW_MODE_NONE = -1, SHOW_MODE_VIDEO = 0, SHOW_MODE_WAVES, SHOW_MODE_RDFT, SHOW_MODE_NB
+    } show_mode;
+    int16_t sample_array[SAMPLE_ARRAY_SIZE];
+    int sample_array_index;
+    int last_i_start;
+    RDFTContext *rdft;
+    int rdft_bits;
+    FFTSample *rdft_data;
+    int xpos;
+
+    SDL_Thread *subtitle_tid;
+    int subtitle_stream;
+    int subtitle_stream_changed;
+    AVStream *subtitle_st;
+    PacketQueue subtitleq;
+    SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
+    int subpq_size, subpq_rindex, subpq_windex;
+    SDL_mutex *subpq_mutex;
+    SDL_cond *subpq_cond;
+
+    double frame_timer;
+    double frame_last_pts;
+    double frame_last_duration;
+    double frame_last_dropped_pts;
+    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_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
+    VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
+    int pictq_size, pictq_rindex, pictq_windex;
+    SDL_mutex *pictq_mutex;
+    SDL_cond *pictq_cond;
+#if !CONFIG_AVFILTER
+    struct SwsContext *img_convert_ctx;
+#endif
+
+    char filename[1024];
+    int width, height, xleft, ytop;
+    int step;
+
+#if CONFIG_AVFILTER
+    AVFilterContext *in_video_filter;   // the first filter in the video chain
+    AVFilterContext *out_video_filter;  // the last filter in the video chain
+    int use_dr1;
+    FrameBuffer *buffer_pool;
+#endif
+
+    int refresh;
+    int last_video_stream, last_audio_stream, last_subtitle_stream;
+
+    SDL_cond *continue_read_thread;
+} VideoState;
+
+/* options specified by the user */
+static AVInputFormat *file_iformat;
+static const char *input_filename;
+static const char *window_title;
+static int fs_screen_width;
+static int fs_screen_height;
+static int screen_width  = 0;
+static int screen_height = 0;
+static int audio_disable;
+static int video_disable;
+static int wanted_stream[AVMEDIA_TYPE_NB] = {
+    [AVMEDIA_TYPE_AUDIO]    = -1,
+    [AVMEDIA_TYPE_VIDEO]    = -1,
+    [AVMEDIA_TYPE_SUBTITLE] = -1,
+};
+static int seek_by_bytes = -1;
+static int display_disable;
+static int show_status = 1;
+static int av_sync_type = AV_SYNC_AUDIO_MASTER;
+static int64_t start_time = AV_NOPTS_VALUE;
+static int64_t duration = AV_NOPTS_VALUE;
+static int workaround_bugs = 1;
+static int fast = 0;
+static int genpts = 0;
+static int lowres = 0;
+static int idct = FF_IDCT_AUTO;
+static enum AVDiscard skip_frame       = AVDISCARD_DEFAULT;
+static enum AVDiscard skip_idct        = AVDISCARD_DEFAULT;
+static enum AVDiscard skip_loop_filter = AVDISCARD_DEFAULT;
+static int error_concealment = 3;
+static int decoder_reorder_pts = -1;
+static int autoexit;
+static int exit_on_keydown;
+static int exit_on_mousedown;
+static int loop = 1;
+static int framedrop = -1;
+static int infinite_buffer = -1;
+static enum ShowMode show_mode = SHOW_MODE_NONE;
+static const char *audio_codec_name;
+static const char *subtitle_codec_name;
+static const char *video_codec_name;
+static int rdftspeed = 20;
+#if CONFIG_AVFILTER
+static char *vfilters = NULL;
+#endif
+
+/* current context */
+static int is_full_screen;
+static int64_t audio_callback_time;
+
+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;
+
+static int packet_queue_put(PacketQueue *q, AVPacket *pkt);
+
+static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
+{
+    AVPacketList *pkt1;
+
+    if (q->abort_request)
+       return -1;
+
+    pkt1 = av_malloc(sizeof(AVPacketList));
+    if (!pkt1)
+        return -1;
+    pkt1->pkt = *pkt;
+    pkt1->next = NULL;
+
+    if (!q->last_pkt)
+        q->first_pkt = pkt1;
+    else
+        q->last_pkt->next = pkt1;
+    q->last_pkt = pkt1;
+    q->nb_packets++;
+    q->size += pkt1->pkt.size + sizeof(*pkt1);
+    /* XXX: should duplicate packet data in DV case */
+    SDL_CondSignal(q->cond);
+    return 0;
+}
+
+static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
+{
+    int ret;
+
+    /* duplicate the packet */
+    if (pkt != &flush_pkt && av_dup_packet(pkt) < 0)
+        return -1;
+
+    SDL_LockMutex(q->mutex);
+    ret = packet_queue_put_private(q, pkt);
+    SDL_UnlockMutex(q->mutex);
+
+    if (pkt != &flush_pkt && ret < 0)
+        av_free_packet(pkt);
+
+    return ret;
+}
+
+/* packet queue handling */
+static void packet_queue_init(PacketQueue *q)
+{
+    memset(q, 0, sizeof(PacketQueue));
+    q->mutex = SDL_CreateMutex();
+    q->cond = SDL_CreateCond();
+    q->abort_request = 1;
+}
+
+static void packet_queue_flush(PacketQueue *q)
+{
+    AVPacketList *pkt, *pkt1;
+
+    SDL_LockMutex(q->mutex);
+    for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
+        pkt1 = pkt->next;
+        av_free_packet(&pkt->pkt);
+        av_freep(&pkt);
+    }
+    q->last_pkt = NULL;
+    q->first_pkt = NULL;
+    q->nb_packets = 0;
+    q->size = 0;
+    SDL_UnlockMutex(q->mutex);
+}
+
+static void packet_queue_destroy(PacketQueue *q)
+{
+    packet_queue_flush(q);
+    SDL_DestroyMutex(q->mutex);
+    SDL_DestroyCond(q->cond);
+}
+
+static void packet_queue_abort(PacketQueue *q)
+{
+    SDL_LockMutex(q->mutex);
+
+    q->abort_request = 1;
+
+    SDL_CondSignal(q->cond);
+
+    SDL_UnlockMutex(q->mutex);
+}
+
+static void packet_queue_start(PacketQueue *q)
+{
+    SDL_LockMutex(q->mutex);
+    q->abort_request = 0;
+    packet_queue_put_private(q, &flush_pkt);
+    SDL_UnlockMutex(q->mutex);
+}
+
+/* return < 0 if aborted, 0 if no packet and > 0 if packet.  */
+static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
+{
+    AVPacketList *pkt1;
+    int ret;
+
+    SDL_LockMutex(q->mutex);
+
+    for (;;) {
+        if (q->abort_request) {
+            ret = -1;
+            break;
+        }
+
+        pkt1 = q->first_pkt;
+        if (pkt1) {
+            q->first_pkt = pkt1->next;
+            if (!q->first_pkt)
+                q->last_pkt = NULL;
+            q->nb_packets--;
+            q->size -= pkt1->pkt.size + sizeof(*pkt1);
+            *pkt = pkt1->pkt;
+            av_free(pkt1);
+            ret = 1;
+            break;
+        } else if (!block) {
+            ret = 0;
+            break;
+        } else {
+            SDL_CondWait(q->cond, q->mutex);
+        }
+    }
+    SDL_UnlockMutex(q->mutex);
+    return ret;
+}
+
+static inline void fill_rectangle(SDL_Surface *screen,
+                                  int x, int y, int w, int h, int color)
+{
+    SDL_Rect rect;
+    rect.x = x;
+    rect.y = y;
+    rect.w = w;
+    rect.h = h;
+    SDL_FillRect(screen, &rect, color);
+}
+
+#define ALPHA_BLEND(a, oldp, newp, s)\
+((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
+
+#define RGBA_IN(r, g, b, a, s)\
+{\
+    unsigned int v = ((const uint32_t *)(s))[0];\
+    a = (v >> 24) & 0xff;\
+    r = (v >> 16) & 0xff;\
+    g = (v >> 8) & 0xff;\
+    b = v & 0xff;\
+}
+
+#define YUVA_IN(y, u, v, a, s, pal)\
+{\
+    unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
+    a = (val >> 24) & 0xff;\
+    y = (val >> 16) & 0xff;\
+    u = (val >> 8) & 0xff;\
+    v = val & 0xff;\
+}
+
+#define YUVA_OUT(d, y, u, v, a)\
+{\
+    ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
+}
+
+
+#define BPP 1
+
+static void blend_subrect(AVPicture *dst, const AVSubtitleRect *rect, int imgw, int imgh)
+{
+    int wrap, wrap3, width2, skip2;
+    int y, u, v, a, u1, v1, a1, w, h;
+    uint8_t *lum, *cb, *cr;
+    const uint8_t *p;
+    const uint32_t *pal;
+    int dstx, dsty, dstw, dsth;
+
+    dstw = av_clip(rect->w, 0, imgw);
+    dsth = av_clip(rect->h, 0, imgh);
+    dstx = av_clip(rect->x, 0, imgw - dstw);
+    dsty = av_clip(rect->y, 0, imgh - dsth);
+    lum = dst->data[0] + dsty * dst->linesize[0];
+    cb  = dst->data[1] + (dsty >> 1) * dst->linesize[1];
+    cr  = dst->data[2] + (dsty >> 1) * dst->linesize[2];
+
+    width2 = ((dstw + 1) >> 1) + (dstx & ~dstw & 1);
+    skip2 = dstx >> 1;
+    wrap = dst->linesize[0];
+    wrap3 = rect->pict.linesize[0];
+    p = rect->pict.data[0];
+    pal = (const uint32_t *)rect->pict.data[1];  /* Now in YCrCb! */
+
+    if (dsty & 1) {
+        lum += dstx;
+        cb += skip2;
+        cr += skip2;
+
+        if (dstx & 1) {
+            YUVA_IN(y, u, v, a, p, pal);
+            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
+            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
+            cb++;
+            cr++;
+            lum++;
+            p += BPP;
+        }
+        for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
+            YUVA_IN(y, u, v, a, p, pal);
+            u1 = u;
+            v1 = v;
+            a1 = a;
+            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+
+            YUVA_IN(y, u, v, a, p + BPP, pal);
+            u1 += u;
+            v1 += v;
+            a1 += a;
+            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
+            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
+            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
+            cb++;
+            cr++;
+            p += 2 * BPP;
+            lum += 2;
+        }
+        if (w) {
+            YUVA_IN(y, u, v, a, p, pal);
+            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
+            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
+            p++;
+            lum++;
+        }
+        p += wrap3 - dstw * BPP;
+        lum += wrap - dstw - dstx;
+        cb += dst->linesize[1] - width2 - skip2;
+        cr += dst->linesize[2] - width2 - skip2;
+    }
+    for (h = dsth - (dsty & 1); h >= 2; h -= 2) {
+        lum += dstx;
+        cb += skip2;
+        cr += skip2;
+
+        if (dstx & 1) {
+            YUVA_IN(y, u, v, a, p, pal);
+            u1 = u;
+            v1 = v;
+            a1 = a;
+            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+            p += wrap3;
+            lum += wrap;
+            YUVA_IN(y, u, v, a, p, pal);
+            u1 += u;
+            v1 += v;
+            a1 += a;
+            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
+            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
+            cb++;
+            cr++;
+            p += -wrap3 + BPP;
+            lum += -wrap + 1;
+        }
+        for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
+            YUVA_IN(y, u, v, a, p, pal);
+            u1 = u;
+            v1 = v;
+            a1 = a;
+            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+
+            YUVA_IN(y, u, v, a, p + BPP, pal);
+            u1 += u;
+            v1 += v;
+            a1 += a;
+            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
+            p += wrap3;
+            lum += wrap;
+
+            YUVA_IN(y, u, v, a, p, pal);
+            u1 += u;
+            v1 += v;
+            a1 += a;
+            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+
+            YUVA_IN(y, u, v, a, p + BPP, pal);
+            u1 += u;
+            v1 += v;
+            a1 += a;
+            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
+
+            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 2);
+            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 2);
+
+            cb++;
+            cr++;
+            p += -wrap3 + 2 * BPP;
+            lum += -wrap + 2;
+        }
+        if (w) {
+            YUVA_IN(y, u, v, a, p, pal);
+            u1 = u;
+            v1 = v;
+            a1 = a;
+            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+            p += wrap3;
+            lum += wrap;
+            YUVA_IN(y, u, v, a, p, pal);
+            u1 += u;
+            v1 += v;
+            a1 += a;
+            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u1, 1);
+            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v1, 1);
+            cb++;
+            cr++;
+            p += -wrap3 + BPP;
+            lum += -wrap + 1;
+        }
+        p += wrap3 + (wrap3 - dstw * BPP);
+        lum += wrap + (wrap - dstw - dstx);
+        cb += dst->linesize[1] - width2 - skip2;
+        cr += dst->linesize[2] - width2 - skip2;
+    }
+    /* handle odd height */
+    if (h) {
+        lum += dstx;
+        cb += skip2;
+        cr += skip2;
+
+        if (dstx & 1) {
+            YUVA_IN(y, u, v, a, p, pal);
+            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
+            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
+            cb++;
+            cr++;
+            lum++;
+            p += BPP;
+        }
+        for (w = dstw - (dstx & 1); w >= 2; w -= 2) {
+            YUVA_IN(y, u, v, a, p, pal);
+            u1 = u;
+            v1 = v;
+            a1 = a;
+            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+
+            YUVA_IN(y, u, v, a, p + BPP, pal);
+            u1 += u;
+            v1 += v;
+            a1 += a;
+            lum[1] = ALPHA_BLEND(a, lum[1], y, 0);
+            cb[0] = ALPHA_BLEND(a1 >> 2, cb[0], u, 1);
+            cr[0] = ALPHA_BLEND(a1 >> 2, cr[0], v, 1);
+            cb++;
+            cr++;
+            p += 2 * BPP;
+            lum += 2;
+        }
+        if (w) {
+            YUVA_IN(y, u, v, a, p, pal);
+            lum[0] = ALPHA_BLEND(a, lum[0], y, 0);
+            cb[0] = ALPHA_BLEND(a >> 2, cb[0], u, 0);
+            cr[0] = ALPHA_BLEND(a >> 2, cr[0], v, 0);
+        }
+    }
+}
+
+static void free_subpicture(SubPicture *sp)
+{
+    avsubtitle_free(&sp->sub);
+}
+
+static void calculate_display_rect(SDL_Rect *rect, int scr_xleft, int scr_ytop, int scr_width, int scr_height, VideoPicture *vp)
+{
+    float aspect_ratio;
+    int width, height, x, y;
+
+    if (vp->sample_aspect_ratio.num == 0)
+        aspect_ratio = 0;
+    else
+        aspect_ratio = av_q2d(vp->sample_aspect_ratio);
+
+    if (aspect_ratio <= 0.0)
+        aspect_ratio = 1.0;
+    aspect_ratio *= (float)vp->width / (float)vp->height;
+
+    /* XXX: we suppose the screen has a 1.0 pixel ratio */
+    height = scr_height;
+    width = ((int)rint(height * aspect_ratio)) & ~1;
+    if (width > scr_width) {
+        width = scr_width;
+        height = ((int)rint(width / aspect_ratio)) & ~1;
+    }
+    x = (scr_width - width) / 2;
+    y = (scr_height - height) / 2;
+    rect->x = scr_xleft + x;
+    rect->y = scr_ytop  + y;
+    rect->w = FFMAX(width,  1);
+    rect->h = FFMAX(height, 1);
+}
+
+static void video_image_display(VideoState *is)
+{
+    VideoPicture *vp;
+    SubPicture *sp;
+    AVPicture pict;
+    SDL_Rect rect;
+    int i;
+
+    vp = &is->pictq[is->pictq_rindex];
+    if (vp->bmp) {
+        if (is->subtitle_st) {
+            if (is->subpq_size > 0) {
+                sp = &is->subpq[is->subpq_rindex];
+
+                if (vp->pts >= sp->pts + ((float) sp->sub.start_display_time / 1000)) {
+                    SDL_LockYUVOverlay (vp->bmp);
+
+                    pict.data[0] = vp->bmp->pixels[0];
+                    pict.data[1] = vp->bmp->pixels[2];
+                    pict.data[2] = vp->bmp->pixels[1];
+
+                    pict.linesize[0] = vp->bmp->pitches[0];
+                    pict.linesize[1] = vp->bmp->pitches[2];
+                    pict.linesize[2] = vp->bmp->pitches[1];
+
+                    for (i = 0; i < sp->sub.num_rects; i++)
+                        blend_subrect(&pict, sp->sub.rects[i],
+                                      vp->bmp->w, vp->bmp->h);
+
+                    SDL_UnlockYUVOverlay (vp->bmp);
+                }
+            }
+        }
+
+        calculate_display_rect(&rect, is->xleft, is->ytop, is->width, is->height, vp);
+
+        SDL_DisplayYUVOverlay(vp->bmp, &rect);
+    }
+}
+
+static inline int compute_mod(int a, int b)
+{
+    return a < 0 ? a%b + b : a%b;
+}
+
+static void video_audio_display(VideoState *s)
+{
+    int i, i_start, x, y1, y, ys, delay, n, nb_display_channels;
+    int ch, channels, h, h2, bgcolor, fgcolor;
+    int16_t time_diff;
+    int rdft_bits, nb_freq;
+
+    for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++)
+        ;
+    nb_freq = 1 << (rdft_bits - 1);
+
+    /* compute display index : center on currently output samples */
+    channels = s->audio_tgt.channels;
+    nb_display_channels = channels;
+    if (!s->paused) {
+        int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
+        n = 2 * channels;
+        delay = s->audio_write_buf_size;
+        delay /= n;
+
+        /* to be more precise, we take into account the time spent since
+           the last buffer computation */
+        if (audio_callback_time) {
+            time_diff = av_gettime() - audio_callback_time;
+            delay -= (time_diff * s->audio_tgt.freq) / 1000000;
+        }
+
+        delay += 2 * data_used;
+        if (delay < data_used)
+            delay = data_used;
+
+        i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE);
+        if (s->show_mode == SHOW_MODE_WAVES) {
+            h = INT_MIN;
+            for (i = 0; i < 1000; i += channels) {
+                int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE;
+                int a = s->sample_array[idx];
+                int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE];
+                int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE];
+                int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE];
+                int score = a - d;
+                if (h < score && (b ^ c) < 0) {
+                    h = score;
+                    i_start = idx;
+                }
+            }
+        }
+
+        s->last_i_start = i_start;
+    } else {
+        i_start = s->last_i_start;
+    }
+
+    bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
+    if (s->show_mode == SHOW_MODE_WAVES) {
+        fill_rectangle(screen,
+                       s->xleft, s->ytop, s->width, s->height,
+                       bgcolor);
+
+        fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
+
+        /* total height for one channel */
+        h = s->height / nb_display_channels;
+        /* graph height / 2 */
+        h2 = (h * 9) / 20;
+        for (ch = 0; ch < nb_display_channels; ch++) {
+            i = i_start + ch;
+            y1 = s->ytop + ch * h + (h / 2); /* position of center line */
+            for (x = 0; x < s->width; x++) {
+                y = (s->sample_array[i] * h2) >> 15;
+                if (y < 0) {
+                    y = -y;
+                    ys = y1 - y;
+                } else {
+                    ys = y1;
+                }
+                fill_rectangle(screen,
+                               s->xleft + x, ys, 1, y,
+                               fgcolor);
+                i += channels;
+                if (i >= SAMPLE_ARRAY_SIZE)
+                    i -= SAMPLE_ARRAY_SIZE;
+            }
+        }
+
+        fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
+
+        for (ch = 1; ch < nb_display_channels; ch++) {
+            y = s->ytop + ch * h;
+            fill_rectangle(screen,
+                           s->xleft, y, s->width, 1,
+                           fgcolor);
+        }
+        SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height);
+    } else {
+        nb_display_channels= FFMIN(nb_display_channels, 2);
+        if (rdft_bits != s->rdft_bits) {
+            av_rdft_end(s->rdft);
+            av_free(s->rdft_data);
+            s->rdft = av_rdft_init(rdft_bits, DFT_R2C);
+            s->rdft_bits = rdft_bits;
+            s->rdft_data = av_malloc(4 * nb_freq * sizeof(*s->rdft_data));
+        }
+        {
+            FFTSample *data[2];
+            for (ch = 0; ch < nb_display_channels; ch++) {
+                data[ch] = s->rdft_data + 2 * nb_freq * ch;
+                i = i_start + ch;
+                for (x = 0; x < 2 * nb_freq; x++) {
+                    double w = (x-nb_freq) * (1.0 / nb_freq);
+                    data[ch][x] = s->sample_array[i] * (1.0 - w * w);
+                    i += channels;
+                    if (i >= SAMPLE_ARRAY_SIZE)
+                        i -= SAMPLE_ARRAY_SIZE;
+                }
+                av_rdft_calc(s->rdft, data[ch]);
+            }
+            // least efficient way to do this, we should of course directly access it but its more than fast enough
+            for (y = 0; y < s->height; y++) {
+                double w = 1 / sqrt(nb_freq);
+                int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1]));
+                int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0]
+                       + data[1][2 * y + 1] * data[1][2 * y + 1])) : a;
+                a = FFMIN(a, 255);
+                b = FFMIN(b, 255);
+                fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2);
+
+                fill_rectangle(screen,
+                            s->xpos, s->height-y, 1, 1,
+                            fgcolor);
+            }
+        }
+        SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height);
+        if (!s->paused)
+            s->xpos++;
+        if (s->xpos >= s->width)
+            s->xpos= s->xleft;
+    }
+}
+
+static void stream_close(VideoState *is)
+{
+    VideoPicture *vp;
+    int i;
+    /* 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);
+
+    /* free all pictures */
+    for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++) {
+        vp = &is->pictq[i];
+#if CONFIG_AVFILTER
+        avfilter_unref_bufferp(&vp->picref);
+#endif
+        if (vp->bmp) {
+            SDL_FreeYUVOverlay(vp->bmp);
+            vp->bmp = NULL;
+        }
+    }
+    SDL_DestroyMutex(is->pictq_mutex);
+    SDL_DestroyCond(is->pictq_cond);
+    SDL_DestroyMutex(is->subpq_mutex);
+    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);
+#endif
+    av_free(is);
+}
+
+static void do_exit(VideoState *is)
+{
+    if (is) {
+        stream_close(is);
+    }
+    av_lockmgr_register(NULL);
+    uninit_opts();
+#if CONFIG_AVFILTER
+    avfilter_uninit();
+    av_freep(&vfilters);
+#endif
+    avformat_network_deinit();
+    if (show_status)
+        printf("\n");
+    SDL_Quit();
+    av_log(NULL, AV_LOG_QUIET, "%s", "");
+    exit(0);
+}
+
+static void sigterm_handler(int sig)
+{
+    exit(123);
+}
+
+static int video_open(VideoState *is, int force_set_video_mode)
+{
+    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 (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;
+    }
+    if (screen && is->width == screen->w && screen->w == w
+       && is->height== screen->h && screen->h == h && !force_set_video_mode)
+        return 0;
+    screen = SDL_SetVideoMode(w, h, 0, flags);
+    if (!screen) {
+        fprintf(stderr, "SDL: could not set video mode - exiting\n");
+        do_exit(is);
+    }
+    if (!window_title)
+        window_title = input_filename;
+    SDL_WM_SetCaption(window_title, window_title);
+
+    is->width  = screen->w;
+    is->height = screen->h;
+
+    return 0;
+}
+
+/* display the current picture, if any */
+static void video_display(VideoState *is)
+{
+    if (!screen)
+        video_open(is, 0);
+    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->paused) {
+        return is->audio_current_pts;
+    } else {
+        return is->audio_current_pts_drift + av_gettime() / 1000000.0;
+    }
+}
+
+/* get the current video clock value */
+static double get_video_clock(VideoState *is)
+{
+    if (is->paused) {
+        return is->video_current_pts;
+    } else {
+        return is->video_current_pts_drift + av_gettime() / 1000000.0;
+    }
+}
+
+/* get the current external clock value */
+static double get_external_clock(VideoState *is)
+{
+    int64_t ti;
+    ti = av_gettime();
+    return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
+}
+
+/* get the current master clock value */
+static double get_master_clock(VideoState *is)
+{
+    double val;
+
+    if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
+        if (is->video_st)
+            val = get_video_clock(is);
+        else
+            val = get_audio_clock(is);
+    } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
+        if (is->audio_st)
+            val = get_audio_clock(is);
+        else
+            val = get_video_clock(is);
+    } else {
+        val = get_external_clock(is);
+    }
+    return val;
+}
+
+/* seek in the stream */
+static void stream_seek(VideoState *is, int64_t pos, int64_t rel, int seek_by_bytes)
+{
+    if (!is->seek_req) {
+        is->seek_pos = pos;
+        is->seek_rel = rel;
+        is->seek_flags &= ~AVSEEK_FLAG_BYTE;
+        if (seek_by_bytes)
+            is->seek_flags |= AVSEEK_FLAG_BYTE;
+        is->seek_req = 1;
+    }
+}
+
+/* pause or resume the video */
+static void stream_toggle_pause(VideoState *is)
+{
+    if (is->paused) {
+        is->frame_timer += av_gettime() / 1000000.0 + is->video_current_pts_drift - is->video_current_pts;
+        if (is->read_pause_return != AVERROR(ENOSYS)) {
+            is->video_current_pts = is->video_current_pts_drift + av_gettime() / 1000000.0;
+        }
+        is->video_current_pts_drift = is->video_current_pts - av_gettime() / 1000000.0;
+    }
+    is->paused = !is->paused;
+}
+
+static double compute_target_delay(double delay, VideoState *is)
+{
+    double sync_threshold, diff;
+
+    /* update delay to follow master synchronisation source */
+    if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) ||
+         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
+        /* if video is slave, we try to correct big delays by
+           duplicating or deleting a frame */
+        diff = get_video_clock(is) - get_master_clock(is);
+
+        /* skip or repeat frame. We take into account the
+           delay to compute the threshold. I still don't know
+           if it is the best guess */
+        sync_threshold = FFMAX(AV_SYNC_THRESHOLD, delay);
+        if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
+            if (diff <= -sync_threshold)
+                delay = 0;
+            else if (diff >= sync_threshold)
+                delay = 2 * delay;
+        }
+    }
+
+    av_dlog(NULL, "video: delay=%0.3f A-V=%f\n",
+            delay, -diff);
+
+    return delay;
+}
+
+static void pictq_next_picture(VideoState *is) {
+    /* update queue size and signal for next picture */
+    if (++is->pictq_rindex == VIDEO_PICTURE_QUEUE_SIZE)
+        is->pictq_rindex = 0;
+
+    SDL_LockMutex(is->pictq_mutex);
+    is->pictq_size--;
+    SDL_CondSignal(is->pictq_cond);
+    SDL_UnlockMutex(is->pictq_mutex);
+}
+
+static void pictq_prev_picture(VideoState *is) {
+    VideoPicture *prevvp;
+    /* 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) {
+        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++;
+        }
+        SDL_CondSignal(is->pictq_cond);
+        SDL_UnlockMutex(is->pictq_mutex);
+    }
+}
+
+static void update_video_pts(VideoState *is, double pts, int64_t pos) {
+    double time = av_gettime() / 1000000.0;
+    /* update current video pts */
+    is->video_current_pts = pts;
+    is->video_current_pts_drift = is->video_current_pts - time;
+    is->video_current_pos = pos;
+    is->frame_last_pts = pts;
+}
+
+/* called to display each frame */
+static void video_refresh(void *opaque)
+{
+    VideoState *is = opaque;
+    VideoPicture *vp;
+    double time;
+
+    SubPicture *sp, *sp2;
+
+    if (is->video_st) {
+        if (is->force_refresh)
+            pictq_prev_picture(is);
+retry:
+        if (is->pictq_size == 0) {
+            SDL_LockMutex(is->pictq_mutex);
+            if (is->frame_last_dropped_pts != AV_NOPTS_VALUE && is->frame_last_dropped_pts > is->frame_last_pts) {
+                update_video_pts(is, is->frame_last_dropped_pts, is->frame_last_dropped_pos);
+                is->frame_last_dropped_pts = AV_NOPTS_VALUE;
+            }
+            SDL_UnlockMutex(is->pictq_mutex);
+            // nothing to do, no picture to display in the que
+        } else {
+            double last_duration, duration, delay;
+            /* dequeue the picture */
+            vp = &is->pictq[is->pictq_rindex];
+
+            if (vp->skip) {
+                pictq_next_picture(is);
+                goto retry;
+            }
+
+            if (is->paused)
+                goto display;
+
+            /* compute nominal last_duration */
+            last_duration = vp->pts - is->frame_last_pts;
+            if (last_duration > 0 && last_duration < 10.0) {
+                /* if duration of the last frame was sane, update last_duration in video state */
+                is->frame_last_duration = last_duration;
+            }
+            delay = compute_target_delay(is->frame_last_duration, is);
+
+            time= av_gettime()/1000000.0;
+            if (time < is->frame_timer + delay)
+                return;
+
+            if (delay > 0)
+                is->frame_timer += delay * FFMAX(1, floor((time-is->frame_timer) / delay));
+
+            SDL_LockMutex(is->pictq_mutex);
+            update_video_pts(is, vp->pts, vp->pos);
+            SDL_UnlockMutex(is->pictq_mutex);
+
+            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 && is->audio_st)) && time > is->frame_timer + duration){
+                    is->frame_drops_late++;
+                    pictq_next_picture(is);
+                    goto retry;
+                }
+            }
+
+            if (is->subtitle_st) {
+                if (is->subtitle_stream_changed) {
+                    SDL_LockMutex(is->subpq_mutex);
+
+                    while (is->subpq_size) {
+                        free_subpicture(&is->subpq[is->subpq_rindex]);
+
+                        /* update queue size and signal for next picture */
+                        if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
+                            is->subpq_rindex = 0;
+
+                        is->subpq_size--;
+                    }
+                    is->subtitle_stream_changed = 0;
+
+                    SDL_CondSignal(is->subpq_cond);
+                    SDL_UnlockMutex(is->subpq_mutex);
+                } else {
+                    if (is->subpq_size > 0) {
+                        sp = &is->subpq[is->subpq_rindex];
+
+                        if (is->subpq_size > 1)
+                            sp2 = &is->subpq[(is->subpq_rindex + 1) % SUBPICTURE_QUEUE_SIZE];
+                        else
+                            sp2 = NULL;
+
+                        if ((is->video_current_pts > (sp->pts + ((float) sp->sub.end_display_time / 1000)))
+                                || (sp2 && is->video_current_pts > (sp2->pts + ((float) sp2->sub.start_display_time / 1000))))
+                        {
+                            free_subpicture(sp);
+
+                            /* update queue size and signal for next picture */
+                            if (++is->subpq_rindex == SUBPICTURE_QUEUE_SIZE)
+                                is->subpq_rindex = 0;
+
+                            SDL_LockMutex(is->subpq_mutex);
+                            is->subpq_size--;
+                            SDL_CondSignal(is->subpq_cond);
+                            SDL_UnlockMutex(is->subpq_mutex);
+                        }
+                    }
+                }
+            }
+
+display:
+            /* display picture */
+            if (!display_disable)
+                video_display(is);
+
+            pictq_next_picture(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) {
+        static int64_t last_time;
+        int64_t cur_time;
+        int aqsize, vqsize, sqsize;
+        double av_diff;
+
+        cur_time = av_gettime();
+        if (!last_time || (cur_time - last_time) >= 30000) {
+            aqsize = 0;
+            vqsize = 0;
+            sqsize = 0;
+            if (is->audio_st)
+                aqsize = is->audioq.size;
+            if (is->video_st)
+                vqsize = is->videoq.size;
+            if (is->subtitle_st)
+                sqsize = is->subtitleq.size;
+            av_diff = 0;
+            if (is->audio_st && is->video_st)
+                av_diff = get_audio_clock(is) - get_video_clock(is);
+            printf("%7.2f A-V:%7.3f fd=%4d aq=%5dKB vq=%5dKB sq=%5dB f=%"PRId64"/%"PRId64"   \r",
+                   get_master_clock(is),
+                   av_diff,
+                   is->frame_drops_early + is->frame_drops_late,
+                   aqsize / 1024,
+                   vqsize / 1024,
+                   sqsize,
+                   is->video_st ? is->video_st->codec->pts_correction_num_faulty_dts : 0,
+                   is->video_st ? is->video_st->codec->pts_correction_num_faulty_pts : 0);
+            fflush(stdout);
+            last_time = cur_time;
+        }
+    }
+}
+
+/* allocate a picture (needs to do that in main thread to avoid
+   potential locking problems */
+static void alloc_picture(VideoState *is)
+{
+    VideoPicture *vp;
+
+    vp = &is->pictq[is->pictq_windex];
+
+    if (vp->bmp)
+        SDL_FreeYUVOverlay(vp->bmp);
+
+#if CONFIG_AVFILTER
+    avfilter_unref_bufferp(&vp->picref);
+#endif
+
+    video_open(is, 0);
+
+    vp->bmp = SDL_CreateYUVOverlay(vp->width, vp->height,
+                                   SDL_YV12_OVERLAY,
+                                   screen);
+    if (!vp->bmp || vp->bmp->pitches[0] < vp->width) {
+        /* SDL allocates a buffer smaller than requested if the video
+         * overlay hardware is unable to support the requested size. */
+        fprintf(stderr, "Error: the video system does not support an image\n"
+                        "size of %dx%d pixels. Try using -lowres or -vf \"scale=w:h\"\n"
+                        "to reduce the image size.\n", vp->width, vp->height );
+        do_exit(is);
+    }
+
+    SDL_LockMutex(is->pictq_mutex);
+    vp->allocated = 1;
+    SDL_CondSignal(is->pictq_cond);
+    SDL_UnlockMutex(is->pictq_mutex);
+}
+
+static int queue_picture(VideoState *is, AVFrame *src_frame, double pts1, int64_t pos)
+{
+    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);
+#endif
+
+    /* wait until we have space to put a new picture */
+    SDL_LockMutex(is->pictq_mutex);
+
+    /* keep the last already displayed picture in the queue */
+    while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE - 2 &&
+           !is->videoq.abort_request) {
+        SDL_CondWait(is->pictq_cond, is->pictq_mutex);
+    }
+    SDL_UnlockMutex(is->pictq_mutex);
+
+    if (is->videoq.abort_request)
+        return -1;
+
+    vp = &is->pictq[is->pictq_windex];
+
+#if CONFIG_AVFILTER
+    vp->sample_aspect_ratio = ((AVFilterBufferRef *)src_frame->opaque)->video->sample_aspect_ratio;
+#else
+    vp->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, src_frame);
+#endif
+
+    /* alloc or resize hardware picture buffer */
+    if (!vp->bmp || vp->reallocate || !vp->allocated ||
+        vp->width  != src_frame->width ||
+        vp->height != src_frame->height) {
+        SDL_Event event;
+
+        vp->allocated  = 0;
+        vp->reallocate = 0;
+        vp->width = src_frame->width;
+        vp->height = src_frame->height;
+
+        /* the allocation must be done in the main thread to avoid
+           locking problems. */
+        event.type = FF_ALLOC_EVENT;
+        event.user.data1 = is;
+        SDL_PushEvent(&event);
+
+        /* wait until the picture is allocated */
+        SDL_LockMutex(is->pictq_mutex);
+        while (!vp->allocated && !is->videoq.abort_request) {
+            SDL_CondWait(is->pictq_cond, is->pictq_mutex);
+        }
+        /* if the queue is aborted, we have to pop the pending ALLOC event or wait for the allocation to complete */
+        if (is->videoq.abort_request && SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_EVENTMASK(FF_ALLOC_EVENT)) != 1) {
+            while (!vp->allocated) {
+                SDL_CondWait(is->pictq_cond, is->pictq_mutex);
+            }
+        }
+        SDL_UnlockMutex(is->pictq_mutex);
+
+        if (is->videoq.abort_request)
+            return -1;
+    }
+
+    /* if the frame is not skipped, then display it */
+    if (vp->bmp) {
+        AVPicture pict = { { 0 } };
+#if CONFIG_AVFILTER
+        avfilter_unref_bufferp(&vp->picref);
+        vp->picref = src_frame->opaque;
+#endif
+
+        /* get a pointer on the bitmap */
+        SDL_LockYUVOverlay (vp->bmp);
+
+        pict.data[0] = vp->bmp->pixels[0];
+        pict.data[1] = vp->bmp->pixels[2];
+        pict.data[2] = vp->bmp->pixels[1];
+
+        pict.linesize[0] = vp->bmp->pitches[0];
+        pict.linesize[1] = vp->bmp->pitches[2];
+        pict.linesize[2] = vp->bmp->pitches[1];
+
+#if CONFIG_AVFILTER
+        // FIXME use direct rendering
+        av_picture_copy(&pict, (AVPicture *)src_frame,
+                        src_frame->format, vp->width, vp->height);
+#else
+        sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
+        is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
+            vp->width, vp->height, src_frame->format, vp->width, vp->height,
+            AV_PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL);
+        if (is->img_convert_ctx == NULL) {
+            fprintf(stderr, "Cannot initialize the conversion context\n");
+            exit(1);
+        }
+        sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
+                  0, vp->height, pict.data, pict.linesize);
+#endif
+        /* update the bitmap content */
+        SDL_UnlockYUVOverlay(vp->bmp);
+
+        vp->pts = pts;
+        vp->pos = pos;
+        vp->skip = 0;
+
+        /* now we can update the picture count */
+        if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
+            is->pictq_windex = 0;
+        SDL_LockMutex(is->pictq_mutex);
+        is->pictq_size++;
+        SDL_UnlockMutex(is->pictq_mutex);
+    }
+    return 0;
+}
+
+static int get_video_frame(VideoState *is, AVFrame *frame, int64_t *pts, AVPacket *pkt)
+{
+    int got_picture, i;
+
+    if (packet_queue_get(&is->videoq, pkt, 1) < 0)
+        return -1;
+
+    if (pkt->data == flush_pkt.data) {
+        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;
+        }
+        while (is->pictq_size && !is->videoq.abort_request) {
+            SDL_CondWait(is->pictq_cond, is->pictq_mutex);
+        }
+        is->video_current_pos = -1;
+        is->frame_last_pts = AV_NOPTS_VALUE;
+        is->frame_last_duration = 0;
+        is->frame_timer = (double)av_gettime() / 1000000.0;
+        is->frame_last_dropped_pts = AV_NOPTS_VALUE;
+        SDL_UnlockMutex(is->pictq_mutex);
+
+        return 0;
+    }
+
+    if(avcodec_decode_video2(is->video_st->codec, frame, &got_picture, pkt) < 0)
+        return 0;
+
+    if (got_picture) {
+        int ret = 1;
+
+        if (decoder_reorder_pts == -1) {
+            *pts = av_frame_get_best_effort_timestamp(frame);
+        } else if (decoder_reorder_pts) {
+            *pts = frame->pkt_pts;
+        } else {
+            *pts = frame->pkt_dts;
+        }
+
+        if (*pts == AV_NOPTS_VALUE) {
+            *pts = 0;
+        }
+
+        if (((is->av_sync_type == AV_SYNC_AUDIO_MASTER && is->audio_st) || is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK) &&
+             (framedrop>0 || (framedrop && is->audio_st))) {
+            SDL_LockMutex(is->pictq_mutex);
+            if (is->frame_last_pts != AV_NOPTS_VALUE && *pts) {
+                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 &&
+                     ptsdiff > 0 && ptsdiff < AV_NOSYNC_THRESHOLD &&
+                     clockdiff + ptsdiff - is->frame_last_filter_delay < 0) {
+                    is->frame_last_dropped_pos = pkt->pos;
+                    is->frame_last_dropped_pts = dpts;
+                    is->frame_drops_early++;
+                    ret = 0;
+                }
+            }
+            SDL_UnlockMutex(is->pictq_mutex);
+        }
+
+        return ret;
+    }
+    return 0;
+}
+
+#if CONFIG_AVFILTER
+static int configure_filtergraph(AVFilterGraph *graph, const char *filtergraph,
+                                 AVFilterContext *source_ctx, AVFilterContext *sink_ctx)
+{
+    int ret;
+    AVFilterInOut *outputs = NULL, *inputs = NULL;
+
+    if (filtergraph) {
+        outputs = avfilter_inout_alloc();
+        inputs  = avfilter_inout_alloc();
+        if (!outputs || !inputs) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+
+        outputs->name       = av_strdup("in");
+        outputs->filter_ctx = source_ctx;
+        outputs->pad_idx    = 0;
+        outputs->next       = NULL;
+
+        inputs->name        = av_strdup("out");
+        inputs->filter_ctx  = sink_ctx;
+        inputs->pad_idx     = 0;
+        inputs->next        = NULL;
+
+        if ((ret = avfilter_graph_parse(graph, filtergraph, &inputs, &outputs, NULL)) < 0)
+            goto fail;
+    } else {
+        if ((ret = avfilter_link(source_ctx, 0, sink_ctx, 0)) < 0)
+            goto fail;
+    }
+
+    return avfilter_graph_config(graph, NULL);
+fail:
+    avfilter_inout_free(&outputs);
+    avfilter_inout_free(&inputs);
+    return ret;
+}
+
+static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters)
+{
+    static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
+    char sws_flags_str[128];
+    char buffersrc_args[256];
+    int ret;
+    AVBufferSinkParams *buffersink_params = av_buffersink_params_alloc();
+    AVFilterContext *filt_src = NULL, *filt_out = NULL, *filt_format, *filt_crop;
+    AVCodecContext *codec = is->video_st->codec;
+
+    snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", 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,
+             is->video_st->time_base.num, is->video_st->time_base.den,
+             codec->sample_aspect_ratio.num, codec->sample_aspect_ratio.den);
+
+    if ((ret = avfilter_graph_create_filter(&filt_src,
+                                            avfilter_get_by_name("buffer"),
+                                            "ffplay_buffer", buffersrc_args, NULL,
+                                            graph)) < 0)
+        return ret;
+
+    buffersink_params->pixel_fmts = pix_fmts;
+    ret = avfilter_graph_create_filter(&filt_out,
+                                       avfilter_get_by_name("ffbuffersink"),
+                                       "ffplay_buffersink", NULL, buffersink_params, graph);
+    av_freep(&buffersink_params);
+    if (ret < 0)
+        return ret;
+
+    /* SDL YUV code is not handling odd width/height for some driver
+     * combinations, therefore we crop the picture to an even width/height. */
+    if ((ret = avfilter_graph_create_filter(&filt_crop,
+                                            avfilter_get_by_name("crop"),
+                                            "ffplay_crop", "floor(in_w/2)*2:floor(in_h/2)*2", NULL, graph)) < 0)
+        return ret;
+    if ((ret = avfilter_graph_create_filter(&filt_format,
+                                            avfilter_get_by_name("format"),
+                                            "format", "yuv420p", NULL, graph)) < 0)
+        return ret;
+    if ((ret = avfilter_link(filt_crop, 0, filt_format, 0)) < 0)
+        return ret;
+    if ((ret = avfilter_link(filt_format, 0, filt_out, 0)) < 0)
+        return ret;
+
+    if ((ret = configure_filtergraph(graph, vfilters, filt_src, filt_crop)) < 0)
+        return ret;
+
+    is->in_video_filter  = filt_src;
+    is->out_video_filter = filt_out;
+
+    return ret;
+}
+
+#endif  /* CONFIG_AVFILTER */
+
+static int video_thread(void *arg)
+{
+    AVPacket pkt = { 0 };
+    VideoState *is = arg;
+    AVFrame *frame = avcodec_alloc_frame();
+    int64_t pts_int = AV_NOPTS_VALUE, pos = -1;
+    double pts;
+    int ret;
+
+#if CONFIG_AVFILTER
+    AVCodecContext *codec = is->video_st->codec;
+    AVFilterGraph *graph = avfilter_graph_alloc();
+    AVFilterContext *filt_out = NULL, *filt_in = NULL;
+    int last_w = 0;
+    int last_h = 0;
+    enum AVPixelFormat last_format = -2;
+
+    if (codec->codec->capabilities & CODEC_CAP_DR1) {
+        is->use_dr1 = 1;
+        codec->get_buffer     = codec_get_buffer;
+        codec->release_buffer = codec_release_buffer;
+        codec->opaque         = &is->buffer_pool;
+    }
+#endif
+
+    for (;;) {
+#if CONFIG_AVFILTER
+        AVFilterBufferRef *picref;
+        AVRational tb;
+#endif
+        while (is->paused && !is->videoq.abort_request)
+            SDL_Delay(10);
+
+        avcodec_get_frame_defaults(frame);
+        av_free_packet(&pkt);
+
+        ret = get_video_frame(is, frame, &pts_int, &pkt);
+        if (ret < 0)
+            goto the_end;
+
+        if (!ret)
+            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);
+            avfilter_graph_free(&graph);
+            graph = avfilter_graph_alloc();
+            if ((ret = configure_video_filters(graph, is, vfilters)) < 0) {
+                SDL_Event event;
+                event.type = FF_QUIT_EVENT;
+                event.user.data1 = is;
+                SDL_PushEvent(&event);
+                av_free_packet(&pkt);
+                goto the_end;
+            }
+            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;
+        }
+
+        frame->pts = pts_int;
+        frame->sample_aspect_ratio = av_guess_sample_aspect_ratio(is->ic, is->video_st, frame);
+        if (is->use_dr1 && frame->opaque) {
+            FrameBuffer      *buf = frame->opaque;
+            AVFilterBufferRef *fb = avfilter_get_video_buffer_ref_from_arrays(
+                                        frame->data, frame->linesize,
+                                        AV_PERM_READ | AV_PERM_PRESERVE,
+                                        frame->width, frame->height,
+                                        frame->format);
+
+            avfilter_copy_frame_props(fb, frame);
+            fb->buf->priv           = buf;
+            fb->buf->free           = filter_release_buffer;
+
+            buf->refcount++;
+            av_buffersrc_add_ref(filt_in, fb, AV_BUFFERSRC_FLAG_NO_COPY);
+
+        } else
+            av_buffersrc_write_frame(filt_in, frame);
+
+        av_free_packet(&pkt);
+
+        while (ret >= 0) {
+            is->frame_last_returned_time = av_gettime() / 1000000.0;
+
+            ret = av_buffersink_get_buffer_ref(filt_out, &picref, 0);
+            if (ret < 0) {
+                ret = 0;
+                break;
+            }
+
+            is->frame_last_filter_delay = av_gettime() / 1000000.0 - is->frame_last_returned_time;
+            if (fabs(is->frame_last_filter_delay) > AV_NOSYNC_THRESHOLD / 10.0)
+                is->frame_last_filter_delay = 0;
+
+            avfilter_copy_buf_props(frame, picref);
+
+            pts_int = picref->pts;
+            tb      = filt_out->inputs[0]->time_base;
+            pos     = picref->pos;
+            frame->opaque = picref;
+
+            if (av_cmp_q(tb, is->video_st->time_base)) {
+                av_unused int64_t pts1 = pts_int;
+                pts_int = av_rescale_q(pts_int, tb, is->video_st->time_base);
+                av_dlog(NULL, "video_thread(): "
+                        "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
+                        tb.num, tb.den, pts1,
+                        is->video_st->time_base.num, is->video_st->time_base.den, pts_int);
+            }
+            pts = pts_int * av_q2d(is->video_st->time_base);
+            ret = queue_picture(is, frame, pts, pos);
+        }
+#else
+        pts = pts_int * av_q2d(is->video_st->time_base);
+        ret = queue_picture(is, frame, pts, pkt.pos);
+#endif
+
+        if (ret < 0)
+            goto the_end;
+
+        if (is->step)
+            stream_toggle_pause(is);
+    }
+ the_end:
+    avcodec_flush_buffers(is->video_st->codec);
+#if CONFIG_AVFILTER
+    avfilter_graph_free(&graph);
+#endif
+    av_free_packet(&pkt);
+    avcodec_free_frame(&frame);
+    return 0;
+}
+
+static int subtitle_thread(void *arg)
+{
+    VideoState *is = arg;
+    SubPicture *sp;
+    AVPacket pkt1, *pkt = &pkt1;
+    int got_subtitle;
+    double pts;
+    int i, j;
+    int r, g, b, y, u, v, a;
+
+    for (;;) {
+        while (is->paused && !is->subtitleq.abort_request) {
+            SDL_Delay(10);
+        }
+        if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
+            break;
+
+        if (pkt->data == flush_pkt.data) {
+            avcodec_flush_buffers(is->subtitle_st->codec);
+            continue;
+        }
+        SDL_LockMutex(is->subpq_mutex);
+        while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
+               !is->subtitleq.abort_request) {
+            SDL_CondWait(is->subpq_cond, is->subpq_mutex);
+        }
+        SDL_UnlockMutex(is->subpq_mutex);
+
+        if (is->subtitleq.abort_request)
+            return 0;
+
+        sp = &is->subpq[is->subpq_windex];
+
+       /* NOTE: ipts is the PTS of the _first_ picture beginning in
+           this packet, if any */
+        pts = 0;
+        if (pkt->pts != AV_NOPTS_VALUE)
+            pts = av_q2d(is->subtitle_st->time_base) * pkt->pts;
+
+        avcodec_decode_subtitle2(is->subtitle_st->codec, &sp->sub,
+                                 &got_subtitle, pkt);
+        if (got_subtitle && sp->sub.format == 0) {
+            if (sp->sub.pts != AV_NOPTS_VALUE)
+                pts = sp->sub.pts / (double)AV_TIME_BASE;
+            sp->pts = pts;
+
+            for (i = 0; i < sp->sub.num_rects; i++)
+            {
+                for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)
+                {
+                    RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);
+                    y = RGB_TO_Y_CCIR(r, g, b);
+                    u = RGB_TO_U_CCIR(r, g, b, 0);
+                    v = RGB_TO_V_CCIR(r, g, b, 0);
+                    YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);
+                }
+            }
+
+            /* now we can update the picture count */
+            if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
+                is->subpq_windex = 0;
+            SDL_LockMutex(is->subpq_mutex);
+            is->subpq_size++;
+            SDL_UnlockMutex(is->subpq_mutex);
+        }
+        av_free_packet(pkt);
+    }
+    return 0;
+}
+
+/* copy samples for viewing in editor window */
+static void update_sample_display(VideoState *is, short *samples, int samples_size)
+{
+    int size, len;
+
+    size = samples_size / sizeof(short);
+    while (size > 0) {
+        len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
+        if (len > size)
+            len = size;
+        memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
+        samples += len;
+        is->sample_array_index += len;
+        if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
+            is->sample_array_index = 0;
+        size -= len;
+    }
+}
+
+/* return the wanted number of samples to get better sync if sync_type is video
+ * or external master clock */
+static int synchronize_audio(VideoState *is, int nb_samples)
+{
+    int wanted_nb_samples = nb_samples;
+
+    /* if not master, then we try to remove or add samples to correct the clock */
+    if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
+         is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
+        double diff, avg_diff;
+        int min_nb_samples, max_nb_samples;
+
+        diff = get_audio_clock(is) - get_master_clock(is);
+
+        if (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 */
+                is->audio_diff_avg_count++;
+            } else {
+                /* estimate the A-V difference */
+                avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
+
+                if (fabs(avg_diff) >= is->audio_diff_threshold) {
+                    wanted_nb_samples = nb_samples + (int)(diff * is->audio_src.freq);
+                    min_nb_samples = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX) / 100));
+                    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",
+                        diff, avg_diff, wanted_nb_samples - nb_samples,
+                        is->audio_clock, is->video_clock, is->audio_diff_threshold);
+            }
+        } else {
+            /* too big difference : may be initial PTS errors, so
+               reset A-V filter */
+            is->audio_diff_avg_count = 0;
+            is->audio_diff_cum       = 0;
+        }
+    }
+
+    return wanted_nb_samples;
+}
+
+/* decode one audio frame and returns its uncompressed size */
+static int audio_decode_frame(VideoState *is, double *pts_ptr)
+{
+    AVPacket *pkt_temp = &is->audio_pkt_temp;
+    AVPacket *pkt = &is->audio_pkt;
+    AVCodecContext *dec = is->audio_st->codec;
+    int len1, len2, data_size, resampled_data_size;
+    int64_t dec_channel_layout;
+    int got_frame;
+    double pts;
+    int new_packet = 0;
+    int flush_complete = 0;
+    int wanted_nb_samples;
+
+    for (;;) {
+        /* NOTE: the audio packet can contain several frames */
+        while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) {
+            if (!is->frame) {
+                if (!(is->frame = avcodec_alloc_frame()))
+                    return AVERROR(ENOMEM);
+            } else
+                avcodec_get_frame_defaults(is->frame);
+
+            if (is->paused)
+                return -1;
+
+            if (flush_complete)
+                break;
+            new_packet = 0;
+            len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
+            if (len1 < 0) {
+                /* if error, we skip the frame */
+                pkt_temp->size = 0;
+                break;
+            }
+
+            pkt_temp->data += len1;
+            pkt_temp->size -= len1;
+
+            if (!got_frame) {
+                /* stop sending empty packets if the decoder is finished */
+                if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY)
+                    flush_complete = 1;
+                continue;
+            }
+            data_size = av_samples_get_buffer_size(NULL, dec->channels,
+                                                   is->frame->nb_samples,
+                                                   dec->sample_fmt, 1);
+
+            dec_channel_layout =
+                (dec->channel_layout && dec->channels == av_get_channel_layout_nb_channels(dec->channel_layout)) ?
+                dec->channel_layout : av_get_default_channel_layout(dec->channels);
+            wanted_nb_samples = synchronize_audio(is, is->frame->nb_samples);
+
+            if (dec->sample_fmt    != is->audio_src.fmt            ||
+                dec_channel_layout != is->audio_src.channel_layout ||
+                dec->sample_rate   != is->audio_src.freq           ||
+                (wanted_nb_samples != is->frame->nb_samples && !is->swr_ctx)) {
+                swr_free(&is->swr_ctx);
+                is->swr_ctx = swr_alloc_set_opts(NULL,
+                                                 is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
+                                                 dec_channel_layout,           dec->sample_fmt,   dec->sample_rate,
+                                                 0, NULL);
+                if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
+                    fprintf(stderr, "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
+                        dec->sample_rate,   av_get_sample_fmt_name(dec->sample_fmt),   dec->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;
+                is->audio_src.channels = dec->channels;
+                is->audio_src.freq = dec->sample_rate;
+                is->audio_src.fmt = dec->sample_fmt;
+            }
+
+            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);
+                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 / dec->sample_rate,
+                                                wanted_nb_samples * is->audio_tgt.freq / dec->sample_rate) < 0) {
+                        fprintf(stderr, "swr_set_compensation() failed\n");
+                        break;
+                    }
+                }
+                len2 = swr_convert(is->swr_ctx, out, out_count, in, is->frame->nb_samples);
+                if (len2 < 0) {
+                    fprintf(stderr, "swr_convert() failed\n");
+                    break;
+                }
+                if (len2 == out_count) {
+                    fprintf(stderr, "warning: audio buffer is probably too small\n");
+                    swr_init(is->swr_ctx);
+                }
+                is->audio_buf = is->audio_buf2;
+                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;
+            is->audio_clock += (double)data_size /
+                (dec->channels * dec->sample_rate * av_get_bytes_per_sample(dec->sample_fmt));
+#ifdef DEBUG
+            {
+                static double last_clock;
+                printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
+                       is->audio_clock - last_clock,
+                       is->audio_clock, pts);
+                last_clock = is->audio_clock;
+            }
+#endif
+            return resampled_data_size;
+        }
+
+        /* free the current packet */
+        if (pkt->data)
+            av_free_packet(pkt);
+        memset(pkt_temp, 0, sizeof(*pkt_temp));
+
+        if (is->paused || is->audioq.abort_request) {
+            return -1;
+        }
+
+        if (is->audioq.nb_packets == 0)
+            SDL_CondSignal(is->continue_read_thread);
+
+        /* read next packet */
+        if ((new_packet = packet_queue_get(&is->audioq, pkt, 1)) < 0)
+            return -1;
+
+        if (pkt->data == flush_pkt.data) {
+            avcodec_flush_buffers(dec);
+            flush_complete = 0;
+        }
+
+        *pkt_temp = *pkt;
+
+        /* 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;
+        }
+    }
+}
+
+/* prepare a new audio buffer */
+static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
+{
+    VideoState *is = opaque;
+    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);
+           if (audio_size < 0) {
+                /* if error, just output silence */
+               is->audio_buf      = is->silence_buf;
+               is->audio_buf_size = sizeof(is->silence_buf) / frame_size * frame_size;
+           } else {
+               if (is->show_mode != SHOW_MODE_VIDEO)
+                   update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
+               is->audio_buf_size = audio_size;
+           }
+           is->audio_buf_index = 0;
+        }
+        len1 = is->audio_buf_size - is->audio_buf_index;
+        if (len1 > len)
+            len1 = len;
+        memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
+        len -= len1;
+        stream += len1;
+        is->audio_buf_index += len1;
+    }
+    bytes_per_sec = is->audio_tgt.freq * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
+    is->audio_write_buf_size = is->audio_buf_size - is->audio_buf_index;
+    /* Let's assume the audio driver that is used by SDL has two periods. */
+    is->audio_current_pts = is->audio_clock - (double)(2 * is->audio_hw_buf_size + is->audio_write_buf_size) / bytes_per_sec;
+    is->audio_current_pts_drift = is->audio_current_pts - audio_callback_time / 1000000.0;
+}
+
+static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params)
+{
+    SDL_AudioSpec wanted_spec, spec;
+    const char *env;
+    const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
+
+    env = SDL_getenv("SDL_AUDIO_CHANNELS");
+    if (env) {
+        wanted_nb_channels = atoi(env);
+        wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
+    }
+    if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) {
+        wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels);
+        wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX;
+    }
+    wanted_spec.channels = av_get_channel_layout_nb_channels(wanted_channel_layout);
+    wanted_spec.freq = wanted_sample_rate;
+    if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
+        fprintf(stderr, "Invalid sample rate or channel count!\n");
+        return -1;
+    }
+    wanted_spec.format = AUDIO_S16SYS;
+    wanted_spec.silence = 0;
+    wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
+    wanted_spec.callback = sdl_audio_callback;
+    wanted_spec.userdata = opaque;
+    while (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
+        fprintf(stderr, "SDL_OpenAudio (%d channels): %s\n", wanted_spec.channels, SDL_GetError());
+        wanted_spec.channels = next_nb_channels[FFMIN(7, wanted_spec.channels)];
+        if (!wanted_spec.channels) {
+            fprintf(stderr, "No more channel combinations to try, audio open failed\n");
+            return -1;
+        }
+        wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels);
+    }
+    if (spec.format != AUDIO_S16SYS) {
+        fprintf(stderr, "SDL advised audio format %d is not supported!\n", spec.format);
+        return -1;
+    }
+    if (spec.channels != wanted_spec.channels) {
+        wanted_channel_layout = av_get_default_channel_layout(spec.channels);
+        if (!wanted_channel_layout) {
+            fprintf(stderr, "SDL advised channel count %d is not supported!\n", spec.channels);
+            return -1;
+        }
+    }
+
+    audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
+    audio_hw_params->freq = spec.freq;
+    audio_hw_params->channel_layout = wanted_channel_layout;
+    audio_hw_params->channels =  spec.channels;
+    return spec.size;
+}
+
+/* open a given stream. Return 0 if OK */
+static int stream_component_open(VideoState *is, int stream_index)
+{
+    AVFormatContext *ic = is->ic;
+    AVCodecContext *avctx;
+    AVCodec *codec;
+    AVDictionary *opts;
+    AVDictionaryEntry *t = NULL;
+
+    if (stream_index < 0 || stream_index >= ic->nb_streams)
+        return -1;
+    avctx = ic->streams[stream_index]->codec;
+
+    codec = avcodec_find_decoder(avctx->codec_id);
+    opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec);
+
+    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;
+    }
+    if (!codec)
+        return -1;
+
+    avctx->workaround_bugs   = workaround_bugs;
+    avctx->lowres            = lowres;
+    if(avctx->lowres > codec->max_lowres){
+        av_log(avctx, AV_LOG_WARNING, "The maximum value for lowres supported by the decoder is %d\n",
+                codec->max_lowres);
+        avctx->lowres= codec->max_lowres;
+    }
+    avctx->idct_algo         = idct;
+    avctx->skip_frame        = skip_frame;
+    avctx->skip_idct         = skip_idct;
+    avctx->skip_loop_filter  = skip_loop_filter;
+    avctx->error_concealment = error_concealment;
+
+    if(avctx->lowres) avctx->flags |= CODEC_FLAG_EMU_EDGE;
+    if (fast)   avctx->flags2 |= CODEC_FLAG2_FAST;
+    if(codec->capabilities & CODEC_CAP_DR1)
+        avctx->flags |= CODEC_FLAG_EMU_EDGE;
+
+    if (!av_dict_get(opts, "threads", NULL, 0))
+        av_dict_set(&opts, "threads", "auto", 0);
+    if (!codec ||
+        avcodec_open2(avctx, codec, &opts) < 0)
+        return -1;
+    if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
+        av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
+        return AVERROR_OPTION_NOT_FOUND;
+    }
+
+    /* prepare audio output */
+    if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
+        int audio_hw_buf_size = audio_open(is, avctx->channel_layout, avctx->channels, avctx->sample_rate, &is->audio_src);
+        if (audio_hw_buf_size < 0)
+            return -1;
+        is->audio_hw_buf_size = audio_hw_buf_size;
+        is->audio_tgt = is->audio_src;
+    }
+
+    ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
+    switch (avctx->codec_type) {
+    case AVMEDIA_TYPE_AUDIO:
+        is->audio_stream = stream_index;
+        is->audio_st = ic->streams[stream_index];
+        is->audio_buf_size  = 0;
+        is->audio_buf_index = 0;
+
+        /* init averaging filter */
+        is->audio_diff_avg_coef  = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
+        is->audio_diff_avg_count = 0;
+        /* since we do not have a precise anough audio fifo fullness,
+           we correct audio sync only if larger than this threshold */
+        is->audio_diff_threshold = 2.0 * is->audio_hw_buf_size / av_samples_get_buffer_size(NULL, is->audio_tgt.channels, is->audio_tgt.freq, is->audio_tgt.fmt, 1);
+
+        memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
+        memset(&is->audio_pkt_temp, 0, sizeof(is->audio_pkt_temp));
+        packet_queue_start(&is->audioq);
+        SDL_PauseAudio(0);
+        break;
+    case AVMEDIA_TYPE_VIDEO:
+        is->video_stream = stream_index;
+        is->video_st = ic->streams[stream_index];
+
+        packet_queue_start(&is->videoq);
+        is->video_tid = SDL_CreateThread(video_thread, is);
+        break;
+    case AVMEDIA_TYPE_SUBTITLE:
+        is->subtitle_stream = stream_index;
+        is->subtitle_st = ic->streams[stream_index];
+        packet_queue_start(&is->subtitleq);
+
+        is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
+        break;
+    default:
+        break;
+    }
+    return 0;
+}
+
+static void stream_component_close(VideoState *is, int stream_index)
+{
+    AVFormatContext *ic = is->ic;
+    AVCodecContext *avctx;
+
+    if (stream_index < 0 || stream_index >= ic->nb_streams)
+        return;
+    avctx = ic->streams[stream_index]->codec;
+
+    switch (avctx->codec_type) {
+    case AVMEDIA_TYPE_AUDIO:
+        packet_queue_abort(&is->audioq);
+
+        SDL_CloseAudio();
+
+        packet_queue_flush(&is->audioq);
+        av_free_packet(&is->audio_pkt);
+        swr_free(&is->swr_ctx);
+        av_freep(&is->audio_buf1);
+        is->audio_buf = NULL;
+        avcodec_free_frame(&is->frame);
+
+        if (is->rdft) {
+            av_rdft_end(is->rdft);
+            av_freep(&is->rdft_data);
+            is->rdft = NULL;
+            is->rdft_bits = 0;
+        }
+        break;
+    case AVMEDIA_TYPE_VIDEO:
+        packet_queue_abort(&is->videoq);
+
+        /* note: we also signal this mutex to make sure we deblock the
+           video thread in all cases */
+        SDL_LockMutex(is->pictq_mutex);
+        SDL_CondSignal(is->pictq_cond);
+        SDL_UnlockMutex(is->pictq_mutex);
+
+        SDL_WaitThread(is->video_tid, NULL);
+
+        packet_queue_flush(&is->videoq);
+        break;
+    case AVMEDIA_TYPE_SUBTITLE:
+        packet_queue_abort(&is->subtitleq);
+
+        /* note: we also signal this mutex to make sure we deblock the
+           video thread in all cases */
+        SDL_LockMutex(is->subpq_mutex);
+        is->subtitle_stream_changed = 1;
+
+        SDL_CondSignal(is->subpq_cond);
+        SDL_UnlockMutex(is->subpq_mutex);
+
+        SDL_WaitThread(is->subtitle_tid, NULL);
+
+        packet_queue_flush(&is->subtitleq);
+        break;
+    default:
+        break;
+    }
+
+    ic->streams[stream_index]->discard = AVDISCARD_ALL;
+    avcodec_close(avctx);
+#if CONFIG_AVFILTER
+    free_buffer_pool(&is->buffer_pool);
+#endif
+    switch (avctx->codec_type) {
+    case AVMEDIA_TYPE_AUDIO:
+        is->audio_st = NULL;
+        is->audio_stream = -1;
+        break;
+    case AVMEDIA_TYPE_VIDEO:
+        is->video_st = NULL;
+        is->video_stream = -1;
+        break;
+    case AVMEDIA_TYPE_SUBTITLE:
+        is->subtitle_st = NULL;
+        is->subtitle_stream = -1;
+        break;
+    default:
+        break;
+    }
+}
+
+static int decode_interrupt_cb(void *ctx)
+{
+    VideoState *is = ctx;
+    return is->abort_request;
+}
+
+static int is_realtime(AVFormatContext *s)
+{
+    if(   !strcmp(s->iformat->name, "rtp")
+       || !strcmp(s->iformat->name, "rtsp")
+       || !strcmp(s->iformat->name, "sdp")
+    )
+        return 1;
+
+    if(s->pb && (   !strncmp(s->filename, "rtp:", 4)
+                 || !strncmp(s->filename, "udp:", 4)
+                )
+    )
+        return 1;
+    return 0;
+}
+
+/* this thread gets the stream from the disk or the network */
+static int read_thread(void *arg)
+{
+    VideoState *is = arg;
+    AVFormatContext *ic = NULL;
+    int err, i, ret;
+    int st_index[AVMEDIA_TYPE_NB];
+    AVPacket pkt1, *pkt = &pkt1;
+    int eof = 0;
+    int pkt_in_play_range = 0;
+    AVDictionaryEntry *t;
+    AVDictionary **opts;
+    int orig_nb_streams;
+    SDL_mutex *wait_mutex = SDL_CreateMutex();
+
+    memset(st_index, -1, sizeof(st_index));
+    is->last_video_stream = is->video_stream = -1;
+    is->last_audio_stream = is->audio_stream = -1;
+    is->last_subtitle_stream = is->subtitle_stream = -1;
+
+    ic = avformat_alloc_context();
+    ic->interrupt_callback.callback = decode_interrupt_cb;
+    ic->interrupt_callback.opaque = is;
+    err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);
+    if (err < 0) {
+        print_error(is->filename, err);
+        ret = -1;
+        goto fail;
+    }
+    if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
+        av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
+        ret = AVERROR_OPTION_NOT_FOUND;
+        goto fail;
+    }
+    is->ic = ic;
+
+    if (genpts)
+        ic->flags |= AVFMT_FLAG_GENPTS;
+
+    opts = setup_find_stream_info_opts(ic, codec_opts);
+    orig_nb_streams = ic->nb_streams;
+
+    err = avformat_find_stream_info(ic, opts);
+    if (err < 0) {
+        fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
+        ret = -1;
+        goto fail;
+    }
+    for (i = 0; i < orig_nb_streams; i++)
+        av_dict_free(&opts[i]);
+    av_freep(&opts);
+
+    if (ic->pb)
+        ic->pb->eof_reached = 0; // FIXME hack, ffplay maybe should not use url_feof() to test for the end
+
+    if (seek_by_bytes < 0)
+        seek_by_bytes = !!(ic->iformat->flags & AVFMT_TS_DISCONT);
+
+    /* if seeking requested, we execute it */
+    if (start_time != AV_NOPTS_VALUE) {
+        int64_t timestamp;
+
+        timestamp = start_time;
+        /* add the stream start time */
+        if (ic->start_time != AV_NOPTS_VALUE)
+            timestamp += ic->start_time;
+        ret = avformat_seek_file(ic, -1, INT64_MIN, timestamp, INT64_MAX, 0);
+        if (ret < 0) {
+            fprintf(stderr, "%s: could not seek to position %0.3f\n",
+                    is->filename, (double)timestamp / AV_TIME_BASE);
+        }
+    }
+
+    for (i = 0; i < ic->nb_streams; i++)
+        ic->streams[i]->discard = AVDISCARD_ALL;
+    if (!video_disable)
+        st_index[AVMEDIA_TYPE_VIDEO] =
+            av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
+                                wanted_stream[AVMEDIA_TYPE_VIDEO], -1, NULL, 0);
+    if (!audio_disable)
+        st_index[AVMEDIA_TYPE_AUDIO] =
+            av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
+                                wanted_stream[AVMEDIA_TYPE_AUDIO],
+                                st_index[AVMEDIA_TYPE_VIDEO],
+                                NULL, 0);
+    if (!video_disable)
+        st_index[AVMEDIA_TYPE_SUBTITLE] =
+            av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
+                                wanted_stream[AVMEDIA_TYPE_SUBTITLE],
+                                (st_index[AVMEDIA_TYPE_AUDIO] >= 0 ?
+                                 st_index[AVMEDIA_TYPE_AUDIO] :
+                                 st_index[AVMEDIA_TYPE_VIDEO]),
+                                NULL, 0);
+    if (show_status) {
+        av_dump_format(ic, 0, is->filename, 0);
+    }
+
+    is->show_mode = show_mode;
+
+    /* open the streams */
+    if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
+        stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
+    }
+
+    ret = -1;
+    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;
+
+    if (st_index[AVMEDIA_TYPE_SUBTITLE] >= 0) {
+        stream_component_open(is, st_index[AVMEDIA_TYPE_SUBTITLE]);
+    }
+
+    if (is->video_stream < 0 && is->audio_stream < 0) {
+        fprintf(stderr, "%s: could not open codecs\n", is->filename);
+        ret = -1;
+        goto fail;
+    }
+
+    if (infinite_buffer < 0 && is_realtime(ic))
+        infinite_buffer = 1;
+
+    for (;;) {
+        if (is->abort_request)
+            break;
+        if (is->paused != is->last_paused) {
+            is->last_paused = is->paused;
+            if (is->paused)
+                is->read_pause_return = av_read_pause(ic);
+            else
+                av_read_play(ic);
+        }
+#if CONFIG_RTSP_DEMUXER || CONFIG_MMSH_PROTOCOL
+        if (is->paused &&
+                (!strcmp(ic->iformat->name, "rtsp") ||
+                 (ic->pb && !strncmp(input_filename, "mmsh:", 5)))) {
+            /* wait 10 ms to avoid trying to get another packet */
+            /* XXX: horrible */
+            SDL_Delay(10);
+            continue;
+        }
+#endif
+        if (is->seek_req) {
+            int64_t seek_target = is->seek_pos;
+            int64_t seek_min    = is->seek_rel > 0 ? seek_target - is->seek_rel + 2: INT64_MIN;
+            int64_t seek_max    = is->seek_rel < 0 ? seek_target - is->seek_rel - 2: INT64_MAX;
+// FIXME the +-2 is due to rounding being not done in the correct direction in generation
+//      of the seek_pos/seek_rel variables
+
+            ret = avformat_seek_file(is->ic, -1, seek_min, seek_target, seek_max, is->seek_flags);
+            if (ret < 0) {
+                fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
+            } else {
+                if (is->audio_stream >= 0) {
+                    packet_queue_flush(&is->audioq);
+                    packet_queue_put(&is->audioq, &flush_pkt);
+                }
+                if (is->subtitle_stream >= 0) {
+                    packet_queue_flush(&is->subtitleq);
+                    packet_queue_put(&is->subtitleq, &flush_pkt);
+                }
+                if (is->video_stream >= 0) {
+                    packet_queue_flush(&is->videoq);
+                    packet_queue_put(&is->videoq, &flush_pkt);
+                }
+            }
+            is->seek_req = 0;
+            eof = 0;
+        }
+        if (is->que_attachments_req) {
+            avformat_queue_attached_pictures(ic);
+            is->que_attachments_req = 0;
+        }
+
+        /* if the queue are full, no need to read more */
+        if (infinite_buffer<1 &&
+              (is->audioq.size + is->videoq.size + is->subtitleq.size > MAX_QUEUE_SIZE
+            || (   (is->audioq   .nb_packets > MIN_FRAMES || is->audio_stream < 0 || is->audioq.abort_request)
+                && (is->videoq   .nb_packets > MIN_FRAMES || is->video_stream < 0 || is->videoq.abort_request)
+                && (is->subtitleq.nb_packets > MIN_FRAMES || is->subtitle_stream < 0 || is->subtitleq.abort_request)))) {
+            /* wait 10 ms */
+            SDL_LockMutex(wait_mutex);
+            SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
+            SDL_UnlockMutex(wait_mutex);
+            continue;
+        }
+        if (eof) {
+            if (is->video_stream >= 0) {
+                av_init_packet(pkt);
+                pkt->data = NULL;
+                pkt->size = 0;
+                pkt->stream_index = is->video_stream;
+                packet_queue_put(&is->videoq, pkt);
+            }
+            if (is->audio_stream >= 0 &&
+                is->audio_st->codec->codec->capabilities & CODEC_CAP_DELAY) {
+                av_init_packet(pkt);
+                pkt->data = NULL;
+                pkt->size = 0;
+                pkt->stream_index = is->audio_stream;
+                packet_queue_put(&is->audioq, pkt);
+            }
+            SDL_Delay(10);
+            if (is->audioq.size + is->videoq.size + is->subtitleq.size == 0) {
+                if (loop != 1 && (!loop || --loop)) {
+                    stream_seek(is, start_time != AV_NOPTS_VALUE ? start_time : 0, 0, 0);
+                } else if (autoexit) {
+                    ret = AVERROR_EOF;
+                    goto fail;
+                }
+            }
+            eof=0;
+            continue;
+        }
+        ret = av_read_frame(ic, pkt);
+        if (ret < 0) {
+            if (ret == AVERROR_EOF || url_feof(ic->pb))
+                eof = 1;
+            if (ic->pb && ic->pb->error)
+                break;
+            SDL_LockMutex(wait_mutex);
+            SDL_CondWaitTimeout(is->continue_read_thread, wait_mutex, 10);
+            SDL_UnlockMutex(wait_mutex);
+            continue;
+        }
+        /* check if packet is in play range specified by user, then queue, otherwise discard */
+        pkt_in_play_range = duration == AV_NOPTS_VALUE ||
+                (pkt->pts - ic->streams[pkt->stream_index]->start_time) *
+                av_q2d(ic->streams[pkt->stream_index]->time_base) -
+                (double)(start_time != AV_NOPTS_VALUE ? start_time : 0) / 1000000
+                <= ((double)duration / 1000000);
+        if (pkt->stream_index == is->audio_stream && pkt_in_play_range) {
+            packet_queue_put(&is->audioq, pkt);
+        } else if (pkt->stream_index == is->video_stream && pkt_in_play_range) {
+            packet_queue_put(&is->videoq, pkt);
+        } else if (pkt->stream_index == is->subtitle_stream && pkt_in_play_range) {
+            packet_queue_put(&is->subtitleq, pkt);
+        } else {
+            av_free_packet(pkt);
+        }
+    }
+    /* wait until the end */
+    while (!is->abort_request) {
+        SDL_Delay(100);
+    }
+
+    ret = 0;
+ fail:
+    /* close each stream */
+    if (is->audio_stream >= 0)
+        stream_component_close(is, is->audio_stream);
+    if (is->video_stream >= 0)
+        stream_component_close(is, is->video_stream);
+    if (is->subtitle_stream >= 0)
+        stream_component_close(is, is->subtitle_stream);
+    if (is->ic) {
+        avformat_close_input(&is->ic);
+    }
+
+    if (ret != 0) {
+        SDL_Event event;
+
+        event.type = FF_QUIT_EVENT;
+        event.user.data1 = is;
+        SDL_PushEvent(&event);
+    }
+    SDL_DestroyMutex(wait_mutex);
+    return 0;
+}
+
+static VideoState *stream_open(const char *filename, AVInputFormat *iformat)
+{
+    VideoState *is;
+
+    is = av_mallocz(sizeof(VideoState));
+    if (!is)
+        return NULL;
+    av_strlcpy(is->filename, filename, sizeof(is->filename));
+    is->iformat = iformat;
+    is->ytop    = 0;
+    is->xleft   = 0;
+
+    /* start video display */
+    is->pictq_mutex = SDL_CreateMutex();
+    is->pictq_cond  = SDL_CreateCond();
+
+    is->subpq_mutex = SDL_CreateMutex();
+    is->subpq_cond  = SDL_CreateCond();
+
+    packet_queue_init(&is->videoq);
+    packet_queue_init(&is->audioq);
+    packet_queue_init(&is->subtitleq);
+
+    is->continue_read_thread = SDL_CreateCond();
+
+    is->av_sync_type = av_sync_type;
+    is->read_tid     = SDL_CreateThread(read_thread, is);
+    if (!is->read_tid) {
+        av_free(is);
+        return NULL;
+    }
+    return is;
+}
+
+static void stream_cycle_channel(VideoState *is, int codec_type)
+{
+    AVFormatContext *ic = is->ic;
+    int start_index, stream_index;
+    int old_index;
+    AVStream *st;
+
+    if (codec_type == AVMEDIA_TYPE_VIDEO) {
+        start_index = is->last_video_stream;
+        old_index = is->video_stream;
+    } else if (codec_type == AVMEDIA_TYPE_AUDIO) {
+        start_index = is->last_audio_stream;
+        old_index = is->audio_stream;
+    } else {
+        start_index = is->last_subtitle_stream;
+        old_index = is->subtitle_stream;
+    }
+    stream_index = start_index;
+    for (;;) {
+        if (++stream_index >= is->ic->nb_streams)
+        {
+            if (codec_type == AVMEDIA_TYPE_SUBTITLE)
+            {
+                stream_index = -1;
+                is->last_subtitle_stream = -1;
+                goto the_end;
+            }
+            if (start_index == -1)
+                return;
+            stream_index = 0;
+        }
+        if (stream_index == start_index)
+            return;
+        st = ic->streams[stream_index];
+        if (st->codec->codec_type == codec_type) {
+            /* check that parameters are OK */
+            switch (codec_type) {
+            case AVMEDIA_TYPE_AUDIO:
+                if (st->codec->sample_rate != 0 &&
+                    st->codec->channels != 0)
+                    goto the_end;
+                break;
+            case AVMEDIA_TYPE_VIDEO:
+            case AVMEDIA_TYPE_SUBTITLE:
+                goto the_end;
+            default:
+                break;
+            }
+        }
+    }
+ the_end:
+    stream_component_close(is, old_index);
+    stream_component_open(is, stream_index);
+    if (codec_type == AVMEDIA_TYPE_VIDEO)
+        is->que_attachments_req = 1;
+}
+
+
+static void toggle_full_screen(VideoState *is)
+{
+#if defined(__APPLE__) && SDL_VERSION_ATLEAST(1, 2, 14)
+    /* OS X needs to reallocate the SDL overlays */
+    int i;
+    for (i = 0; i < VIDEO_PICTURE_QUEUE_SIZE; i++)
+        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;
+}
+
+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);
+    SDL_UpdateRect(screen, is->xleft, is->ytop, is->width, is->height);
+}
+
+/* handle an event sent by the GUI */
+static void event_loop(VideoState *cur_stream)
+{
+    SDL_Event event;
+    double incr, pos, frac;
+
+    for (;;) {
+        double x;
+        SDL_WaitEvent(&event);
+        switch (event.type) {
+        case SDL_KEYDOWN:
+            if (exit_on_keydown) {
+                do_exit(cur_stream);
+                break;
+            }
+            switch (event.key.keysym.sym) {
+            case SDLK_ESCAPE:
+            case SDLK_q:
+                do_exit(cur_stream);
+                break;
+            case SDLK_f:
+                toggle_full_screen(cur_stream);
+                cur_stream->force_refresh = 1;
+                break;
+            case SDLK_p:
+            case SDLK_SPACE:
+                toggle_pause(cur_stream);
+                break;
+            case SDLK_s: // S: Step to next frame
+                step_to_next_frame(cur_stream);
+                break;
+            case SDLK_a:
+                stream_cycle_channel(cur_stream, AVMEDIA_TYPE_AUDIO);
+                break;
+            case SDLK_v:
+                stream_cycle_channel(cur_stream, AVMEDIA_TYPE_VIDEO);
+                break;
+            case SDLK_t:
+                stream_cycle_channel(cur_stream, AVMEDIA_TYPE_SUBTITLE);
+                break;
+            case SDLK_w:
+                toggle_audio_display(cur_stream);
+                cur_stream->force_refresh = 1;
+                break;
+            case SDLK_PAGEUP:
+                incr = 600.0;
+                goto do_seek;
+            case SDLK_PAGEDOWN:
+                incr = -600.0;
+                goto do_seek;
+            case SDLK_LEFT:
+                incr = -10.0;
+                goto do_seek;
+            case SDLK_RIGHT:
+                incr = 10.0;
+                goto do_seek;
+            case SDLK_UP:
+                incr = 60.0;
+                goto do_seek;
+            case SDLK_DOWN:
+                incr = -60.0;
+            do_seek:
+                    if (seek_by_bytes) {
+                        if (cur_stream->video_stream >= 0 && cur_stream->video_current_pos >= 0) {
+                            pos = cur_stream->video_current_pos;
+                        } else if (cur_stream->audio_stream >= 0 && cur_stream->audio_pkt.pos >= 0) {
+                            pos = cur_stream->audio_pkt.pos;
+                        } else
+                            pos = avio_tell(cur_stream->ic->pb);
+                        if (cur_stream->ic->bit_rate)
+                            incr *= cur_stream->ic->bit_rate / 8.0;
+                        else
+                            incr *= 180000.0;
+                        pos += incr;
+                        stream_seek(cur_stream, pos, incr, 1);
+                    } else {
+                        pos = get_master_clock(cur_stream);
+                        pos += incr;
+                        stream_seek(cur_stream, (int64_t)(pos * AV_TIME_BASE), (int64_t)(incr * AV_TIME_BASE), 0);
+                    }
+                break;
+            default:
+                break;
+            }
+            break;
+        case SDL_VIDEOEXPOSE:
+            cur_stream->force_refresh = 1;
+            break;
+        case SDL_MOUSEBUTTONDOWN:
+            if (exit_on_mousedown) {
+                do_exit(cur_stream);
+                break;
+            }
+        case SDL_MOUSEMOTION:
+            if (event.type == SDL_MOUSEBUTTONDOWN) {
+                x = event.button.x;
+            } else {
+                if (event.motion.state != SDL_PRESSED)
+                    break;
+                x = event.motion.x;
+            }
+                if (seek_by_bytes || cur_stream->ic->duration <= 0) {
+                    uint64_t size =  avio_size(cur_stream->ic->pb);
+                    stream_seek(cur_stream, size*x/cur_stream->width, 0, 1);
+                } else {
+                    int64_t ts;
+                    int ns, hh, mm, ss;
+                    int tns, thh, tmm, tss;
+                    tns  = cur_stream->ic->duration / 1000000LL;
+                    thh  = tns / 3600;
+                    tmm  = (tns % 3600) / 60;
+                    tss  = (tns % 60);
+                    frac = x / cur_stream->width;
+                    ns   = frac * tns;
+                    hh   = ns / 3600;
+                    mm   = (ns % 3600) / 60;
+                    ss   = (ns % 60);
+                    fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d)       \n", frac*100,
+                            hh, mm, ss, thh, tmm, tss);
+                    ts = frac * cur_stream->ic->duration;
+                    if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
+                        ts += cur_stream->ic->start_time;
+                    stream_seek(cur_stream, ts, 0, 0);
+                }
+            break;
+        case SDL_VIDEORESIZE:
+                screen = SDL_SetVideoMode(event.resize.w, event.resize.h, 0,
+                                          SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL);
+                screen_width  = cur_stream->width  = event.resize.w;
+                screen_height = cur_stream->height = event.resize.h;
+                cur_stream->force_refresh = 1;
+            break;
+        case SDL_QUIT:
+        case FF_QUIT_EVENT:
+            do_exit(cur_stream);
+            break;
+        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;
+        }
+    }
+}
+
+static int opt_frame_size(void *optctx, const char *opt, const char *arg)
+{
+    av_log(NULL, AV_LOG_WARNING, "Option -s is deprecated, use -video_size.\n");
+    return opt_default(NULL, "video_size", arg);
+}
+
+static int opt_width(void *optctx, const char *opt, const char *arg)
+{
+    screen_width = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
+    return 0;
+}
+
+static int opt_height(void *optctx, const char *opt, const char *arg)
+{
+    screen_height = parse_number_or_die(opt, arg, OPT_INT64, 1, INT_MAX);
+    return 0;
+}
+
+static int opt_format(void *optctx, const char *opt, const char *arg)
+{
+    file_iformat = av_find_input_format(arg);
+    if (!file_iformat) {
+        fprintf(stderr, "Unknown input format: %s\n", arg);
+        return AVERROR(EINVAL);
+    }
+    return 0;
+}
+
+static int opt_frame_pix_fmt(void *optctx, const char *opt, const char *arg)
+{
+    av_log(NULL, AV_LOG_WARNING, "Option -pix_fmt is deprecated, use -pixel_format.\n");
+    return opt_default(NULL, "pixel_format", arg);
+}
+
+static int opt_sync(void *optctx, const char *opt, const char *arg)
+{
+    if (!strcmp(arg, "audio"))
+        av_sync_type = AV_SYNC_AUDIO_MASTER;
+    else if (!strcmp(arg, "video"))
+        av_sync_type = AV_SYNC_VIDEO_MASTER;
+    else if (!strcmp(arg, "ext"))
+        av_sync_type = AV_SYNC_EXTERNAL_CLOCK;
+    else {
+        fprintf(stderr, "Unknown value for %s: %s\n", opt, arg);
+        exit(1);
+    }
+    return 0;
+}
+
+static int opt_seek(void *optctx, const char *opt, const char *arg)
+{
+    start_time = parse_time_or_die(opt, arg, 1);
+    return 0;
+}
+
+static int opt_duration(void *optctx, const char *opt, const char *arg)
+{
+    duration = parse_time_or_die(opt, arg, 1);
+    return 0;
+}
+
+static int opt_show_mode(void *optctx, const char *opt, const char *arg)
+{
+    show_mode = !strcmp(arg, "video") ? SHOW_MODE_VIDEO :
+                !strcmp(arg, "waves") ? SHOW_MODE_WAVES :
+                !strcmp(arg, "rdft" ) ? SHOW_MODE_RDFT  :
+                parse_number_or_die(opt, arg, OPT_INT, 0, SHOW_MODE_NB-1);
+    return 0;
+}
+
+static void opt_input_file(void *optctx, const char *filename)
+{
+    if (input_filename) {
+        fprintf(stderr, "Argument '%s' provided as input filename, but '%s' was already specified.\n",
+                filename, input_filename);
+        exit(1);
+    }
+    if (!strcmp(filename, "-"))
+        filename = "pipe:";
+    input_filename = filename;
+}
+
+static int opt_codec(void *o, 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;
+}
+
+static int dummy;
+
+static const OptionDef options[] = {
+#include "cmdutils_common_opts.h"
+    { "x", HAS_ARG, { .func_arg = opt_width }, "force displayed width", "width" },
+    { "y", HAS_ARG, { .func_arg = opt_height }, "force displayed height", "height" },
+    { "s", HAS_ARG | OPT_VIDEO, { .func_arg = opt_frame_size }, "set frame size (WxH or abbreviation)", "size" },
+    { "fs", OPT_BOOL, { &is_full_screen }, "force full screen" },
+    { "an", OPT_BOOL, { &audio_disable }, "disable audio" },
+    { "vn", OPT_BOOL, { &video_disable }, "disable video" },
+    { "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" },
+    { "ss", HAS_ARG, { .func_arg = opt_seek }, "seek to a given position in seconds", "pos" },
+    { "t", HAS_ARG, { .func_arg = opt_duration }, "play  \"duration\" seconds of audio/video", "duration" },
+    { "bytes", OPT_INT | HAS_ARG, { &seek_by_bytes }, "seek by bytes 0=off 1=on -1=auto", "val" },
+    { "nodisp", OPT_BOOL, { &display_disable }, "disable graphical display" },
+    { "f", HAS_ARG, { .func_arg = opt_format }, "force format", "fmt" },
+    { "pix_fmt", HAS_ARG | OPT_EXPERT | OPT_VIDEO, { .func_arg = opt_frame_pix_fmt }, "set pixel format", "format" },
+    { "stats", OPT_BOOL | OPT_EXPERT, { &show_status }, "show status", "" },
+    { "bug", OPT_INT | HAS_ARG | OPT_EXPERT, { &workaround_bugs }, "workaround bugs", "" },
+    { "fast", OPT_BOOL | OPT_EXPERT, { &fast }, "non spec compliant optimizations", "" },
+    { "genpts", OPT_BOOL | OPT_EXPERT, { &genpts }, "generate pts", "" },
+    { "drp", OPT_INT | HAS_ARG | OPT_EXPERT, { &decoder_reorder_pts }, "let decoder reorder pts 0=off 1=on -1=auto", ""},
+    { "lowres", OPT_INT | HAS_ARG | OPT_EXPERT, { &lowres }, "", "" },
+    { "skiploop", OPT_INT | HAS_ARG | OPT_EXPERT, { &skip_loop_filter }, "", "" },
+    { "skipframe", OPT_INT | HAS_ARG | OPT_EXPERT, { &skip_frame }, "", "" },
+    { "skipidct", OPT_INT | HAS_ARG | OPT_EXPERT, { &skip_idct }, "", "" },
+    { "idct", OPT_INT | HAS_ARG | OPT_EXPERT, { &idct }, "set idct algo",  "algo" },
+    { "ec", OPT_INT | HAS_ARG | OPT_EXPERT, { &error_concealment }, "set error concealment options",  "bit_mask" },
+    { "sync", HAS_ARG | OPT_EXPERT, { .func_arg = opt_sync }, "set audio-video sync. type (type=audio/video/ext)", "type" },
+    { "autoexit", OPT_BOOL | OPT_EXPERT, { &autoexit }, "exit at the end", "" },
+    { "exitonkeydown", OPT_BOOL | OPT_EXPERT, { &exit_on_keydown }, "exit on key down", "" },
+    { "exitonmousedown", OPT_BOOL | OPT_EXPERT, { &exit_on_mousedown }, "exit on mouse down", "" },
+    { "loop", OPT_INT | HAS_ARG | OPT_EXPERT, { &loop }, "set number of times the playback shall be looped", "loop count" },
+    { "framedrop", OPT_BOOL | OPT_EXPERT, { &framedrop }, "drop frames when cpu is too slow", "" },
+    { "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" },
+#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" },
+    { NULL, },
+};
+
+static void show_usage(void)
+{
+    av_log(NULL, AV_LOG_INFO, "Simple media player\n");
+    av_log(NULL, AV_LOG_INFO, "usage: %s [options] input_file\n", program_name);
+    av_log(NULL, AV_LOG_INFO, "\n");
+}
+
+void show_help_default(const char *opt, const char *arg)
+{
+    av_log_set_callback(log_callback_help);
+    show_usage();
+    show_help_options(options, "Main options:", 0, OPT_EXPERT, 0);
+    show_help_options(options, "Advanced options:", OPT_EXPERT, 0, 0);
+    printf("\n");
+    show_help_children(avcodec_get_class(), AV_OPT_FLAG_DECODING_PARAM);
+    show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
+#if !CONFIG_AVFILTER
+    show_help_children(sws_get_class(), AV_OPT_FLAG_ENCODING_PARAM);
+#else
+    show_help_children(avfilter_get_class(), AV_OPT_FLAG_FILTERING_PARAM);
+#endif
+    printf("\nWhile playing:\n"
+           "q, ESC              quit\n"
+           "f                   toggle full screen\n"
+           "p, SPC              pause\n"
+           "a                   cycle audio channel\n"
+           "v                   cycle video channel\n"
+           "t                   cycle subtitle channel\n"
+           "w                   show audio waves\n"
+           "s                   activate frame-step mode\n"
+           "left/right          seek backward/forward 10 seconds\n"
+           "down/up             seek backward/forward 1 minute\n"
+           "page down/page up   seek backward/forward 10 minutes\n"
+           "mouse click         seek to percentage in file corresponding to fraction of width\n"
+           );
+}
+
+static int lockmgr(void **mtx, enum AVLockOp op)
+{
+   switch(op) {
+      case AV_LOCK_CREATE:
+          *mtx = SDL_CreateMutex();
+          if(!*mtx)
+              return 1;
+          return 0;
+      case AV_LOCK_OBTAIN:
+          return !!SDL_LockMutex(*mtx);
+      case AV_LOCK_RELEASE:
+          return !!SDL_UnlockMutex(*mtx);
+      case AV_LOCK_DESTROY:
+          SDL_DestroyMutex(*mtx);
+          return 0;
+   }
+   return 1;
+}
+
+/* Called from the main */
+int main(int argc, char **argv)
+{
+    int flags;
+    VideoState *is;
+    char dummy_videodriver[] = "SDL_VIDEODRIVER=dummy";
+
+    av_log_set_flags(AV_LOG_SKIP_REPEATED);
+    parse_loglevel(argc, argv, options);
+
+    /* register all codecs, demux and protocols */
+    avcodec_register_all();
+#if CONFIG_AVDEVICE
+    avdevice_register_all();
+#endif
+#if CONFIG_AVFILTER
+    avfilter_register_all();
+#endif
+    av_register_all();
+    avformat_network_init();
+
+    init_opts();
+
+    signal(SIGINT , sigterm_handler); /* Interrupt (ANSI).    */
+    signal(SIGTERM, sigterm_handler); /* Termination (ANSI).  */
+
+    show_banner(argc, argv, options);
+
+    parse_options(NULL, argc, argv, options, opt_input_file);
+
+    if (!input_filename) {
+        show_usage();
+        fprintf(stderr, "An input file must be specified\n");
+        fprintf(stderr, "Use -h to get full help or, even better, run 'man %s'\n", program_name);
+        exit(1);
+    }
+
+    if (display_disable) {
+        video_disable = 1;
+    }
+    flags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
+    if (audio_disable)
+        flags &= ~SDL_INIT_AUDIO;
+    if (display_disable)
+        SDL_putenv(dummy_videodriver); /* For the event queue, we always need a video driver. */
+#if !defined(__MINGW32__) && !defined(__APPLE__)
+    flags |= SDL_INIT_EVENTTHREAD; /* Not supported on Windows or Mac OS X */
+#endif
+    if (SDL_Init (flags)) {
+        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
+        fprintf(stderr, "(Did you set the DISPLAY variable?)\n");
+        exit(1);
+    }
+
+    if (!display_disable) {
+#if HAVE_SDL_VIDEO_SIZE
+        const SDL_VideoInfo *vi = SDL_GetVideoInfo();
+        fs_screen_width = vi->current_w;
+        fs_screen_height = vi->current_h;
+#endif
+    }
+
+    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
+    SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
+    SDL_EventState(SDL_USEREVENT, SDL_IGNORE);
+
+    if (av_lockmgr_register(lockmgr)) {
+        fprintf(stderr, "Could not initialize lock manager!\n");
+        do_exit(NULL);
+    }
+
+    av_init_packet(&flush_pkt);
+    flush_pkt.data = (char *)(intptr_t)"FLUSH";
+
+    is = stream_open(input_filename, file_iformat);
+    if (!is) {
+        fprintf(stderr, "Failed to initialize VideoState!\n");
+        do_exit(NULL);
+    }
+
+    event_loop(is);
+
+    /* never returns */
+
+    return 0;
+}
diff --git a/ffprobe.c b/ffprobe.c
new file mode 100644
index 0000000..1cf6c42
--- /dev/null
+++ b/ffprobe.c
@@ -0,0 +1,2195 @@
+/*
+ * Copyright (c) 2007-2010 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
+ * simple media prober based on the FFmpeg libraries
+ */
+
+#include "config.h"
+#include "version.h"
+
+#include <string.h>
+
+#include "libavformat/avformat.h"
+#include "libavcodec/avcodec.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/dict.h"
+#include "libavutil/libm.h"
+#include "libavutil/timecode.h"
+#include "libavdevice/avdevice.h"
+#include "libswscale/swscale.h"
+#include "libswresample/swresample.h"
+#include "libpostproc/postprocess.h"
+#include "cmdutils.h"
+
+const char program_name[] = "ffprobe";
+const int program_birth_year = 2007;
+
+static int do_bitexact = 0;
+static int do_count_frames = 0;
+static int do_count_packets = 0;
+static int do_read_frames  = 0;
+static int do_read_packets = 0;
+static int do_show_error   = 0;
+static int do_show_format  = 0;
+static int do_show_frames  = 0;
+static AVDictionary *fmt_entries_to_show = NULL;
+static int do_show_packets = 0;
+static int do_show_streams = 0;
+static int do_show_data    = 0;
+static int do_show_program_version  = 0;
+static int do_show_library_versions = 0;
+
+static int show_value_unit              = 0;
+static int use_value_prefix             = 0;
+static int use_byte_value_binary_prefix = 0;
+static int use_value_sexagesimal_format = 0;
+static int show_private_data            = 1;
+
+static char *print_format;
+static char *stream_specifier;
+
+/* section structure definition */
+
+struct section {
+    int id;             ///< unique id indentifying a section
+    const char *name;
+
+#define SECTION_FLAG_IS_WRAPPER      1 ///< the section only contains other sections, but has no data at its own level
+#define SECTION_FLAG_IS_ARRAY        2 ///< the section contains an array of elements of the same type
+#define SECTION_FLAG_HAS_VARIABLE_FIELDS 4 ///< the section may contain a variable number of fields with variable keys.
+                                           ///  For these sections the element_name field is mandatory.
+    int flags;
+    const char *element_name; ///< name of the contained element, if provided
+};
+
+typedef enum {
+    SECTION_ID_NONE = -1,
+    SECTION_ID_ERROR,
+    SECTION_ID_FORMAT,
+    SECTION_ID_FORMAT_TAGS,
+    SECTION_ID_FRAME,
+    SECTION_ID_FRAMES,
+    SECTION_ID_FRAME_TAGS,
+    SECTION_ID_LIBRARY_VERSION,
+    SECTION_ID_LIBRARY_VERSIONS,
+    SECTION_ID_PACKET,
+    SECTION_ID_PACKETS,
+    SECTION_ID_PACKETS_AND_FRAMES,
+    SECTION_ID_PROGRAM_VERSION,
+    SECTION_ID_ROOT,
+    SECTION_ID_STREAM,
+    SECTION_ID_STREAM_DISPOSITION,
+    SECTION_ID_STREAMS,
+    SECTION_ID_STREAM_TAGS
+} SectionID;
+
+static const struct section sections[] = {
+    [SECTION_ID_ERROR] =              { SECTION_ID_ERROR,              "error" },
+    [SECTION_ID_FORMAT] =             { SECTION_ID_FORMAT,             "format" },
+    [SECTION_ID_FORMAT_TAGS] =        { SECTION_ID_FORMAT_TAGS,        "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, .element_name = "tag" },
+    [SECTION_ID_FRAME] =              { SECTION_ID_FRAME,              "frame" },
+    [SECTION_ID_FRAMES] =             { SECTION_ID_FRAMES,             "frames", SECTION_FLAG_IS_ARRAY },
+    [SECTION_ID_FRAME_TAGS] =         { SECTION_ID_FRAME_TAGS,         "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, .element_name = "tag" },
+    [SECTION_ID_LIBRARY_VERSION] =    { SECTION_ID_LIBRARY_VERSION,    "library_version" },
+    [SECTION_ID_LIBRARY_VERSIONS] =   { SECTION_ID_LIBRARY_VERSIONS,   "library_versions", SECTION_FLAG_IS_ARRAY },
+    [SECTION_ID_PACKET] =             { SECTION_ID_PACKET,             "packet" },
+    [SECTION_ID_PACKETS] =            { SECTION_ID_PACKETS,            "packets", SECTION_FLAG_IS_ARRAY },
+    [SECTION_ID_PACKETS_AND_FRAMES] = { SECTION_ID_PACKETS_AND_FRAMES, "packets_and_frames", SECTION_FLAG_IS_ARRAY },
+    [SECTION_ID_PROGRAM_VERSION] =    { SECTION_ID_PROGRAM_VERSION,    "program_version" },
+    [SECTION_ID_ROOT] =               { SECTION_ID_ROOT,               "root", SECTION_FLAG_IS_WRAPPER },
+    [SECTION_ID_STREAM] =             { SECTION_ID_STREAM,             "stream" },
+    [SECTION_ID_STREAM_DISPOSITION] = { SECTION_ID_STREAM_DISPOSITION, "disposition" },
+    [SECTION_ID_STREAMS] =            { SECTION_ID_STREAMS,            "streams", SECTION_FLAG_IS_ARRAY },
+    [SECTION_ID_STREAM_TAGS] =        { SECTION_ID_STREAM_TAGS,        "tags", SECTION_FLAG_HAS_VARIABLE_FIELDS, .element_name = "tag" },
+};
+
+static const OptionDef *options;
+
+/* FFprobe context */
+static const char *input_filename;
+static AVInputFormat *iformat = NULL;
+
+static const char *const binary_unit_prefixes [] = { "", "Ki", "Mi", "Gi", "Ti", "Pi" };
+static const char *const decimal_unit_prefixes[] = { "", "K" , "M" , "G" , "T" , "P"  };
+
+static const char unit_second_str[]         = "s"    ;
+static const char unit_hertz_str[]          = "Hz"   ;
+static const char unit_byte_str[]           = "byte" ;
+static const char unit_bit_per_second_str[] = "bit/s";
+
+static uint64_t *nb_streams_packets;
+static uint64_t *nb_streams_frames;
+static int *selected_streams;
+
+static void exit_program(void)
+{
+    av_dict_free(&fmt_entries_to_show);
+}
+
+struct unit_value {
+    union { double d; long long int i; } val;
+    const char *unit;
+};
+
+static char *value_string(char *buf, int buf_size, struct unit_value uv)
+{
+    double vald;
+    long long int vali;
+    int show_float = 0;
+
+    if (uv.unit == unit_second_str) {
+        vald = uv.val.d;
+        show_float = 1;
+    } else {
+        vald = vali = uv.val.i;
+    }
+
+    if (uv.unit == unit_second_str && use_value_sexagesimal_format) {
+        double secs;
+        int hours, mins;
+        secs  = vald;
+        mins  = (int)secs / 60;
+        secs  = secs - mins * 60;
+        hours = mins / 60;
+        mins %= 60;
+        snprintf(buf, buf_size, "%d:%02d:%09.6f", hours, mins, secs);
+    } else {
+        const char *prefix_string = "";
+
+        if (use_value_prefix && vald > 1) {
+            long long int index;
+
+            if (uv.unit == unit_byte_str && use_byte_value_binary_prefix) {
+                index = (long long int) (log2(vald)) / 10;
+                index = av_clip(index, 0, FF_ARRAY_ELEMS(binary_unit_prefixes) - 1);
+                vald /= exp2(index * 10);
+                prefix_string = binary_unit_prefixes[index];
+            } else {
+                index = (long long int) (log10(vald)) / 3;
+                index = av_clip(index, 0, FF_ARRAY_ELEMS(decimal_unit_prefixes) - 1);
+                vald /= pow(10, index * 3);
+                prefix_string = decimal_unit_prefixes[index];
+            }
+        }
+
+        if (show_float || (use_value_prefix && vald != (long long int)vald))
+            snprintf(buf, buf_size, "%f", vald);
+        else
+            snprintf(buf, buf_size, "%lld", vali);
+        av_strlcatf(buf, buf_size, "%s%s%s", *prefix_string || show_value_unit ? " " : "",
+                 prefix_string, show_value_unit ? uv.unit : "");
+    }
+
+    return buf;
+}
+
+/* WRITERS API */
+
+typedef struct WriterContext WriterContext;
+
+#define WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS 1
+#define WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER 2
+
+typedef struct Writer {
+    const AVClass *priv_class;      ///< private class of the writer, if any
+    int priv_size;                  ///< private size for the writer context
+    const char *name;
+
+    int  (*init)  (WriterContext *wctx);
+    void (*uninit)(WriterContext *wctx);
+
+    void (*print_section_header)(WriterContext *wctx);
+    void (*print_section_footer)(WriterContext *wctx);
+    void (*print_integer)       (WriterContext *wctx, const char *, long long int);
+    void (*print_rational)      (WriterContext *wctx, AVRational *q, char *sep);
+    void (*print_string)        (WriterContext *wctx, const char *, const char *);
+    int flags;                  ///< a combination or WRITER_FLAG_*
+} Writer;
+
+#define SECTION_MAX_NB_LEVELS 10
+
+struct WriterContext {
+    const AVClass *class;           ///< class of the writer
+    const Writer *writer;           ///< the Writer of which this is an instance
+    char *name;                     ///< name of this writer instance
+    void *priv;                     ///< private data for use by the filter
+
+    const struct section *sections; ///< array containing all sections
+    int nb_sections;                ///< number of sections
+
+    int level;                      ///< current level, starting from 0
+
+    /** number of the item printed in the given section, starting from 0 */
+    unsigned int nb_item[SECTION_MAX_NB_LEVELS];
+
+    /** section per each level */
+    const struct section *section[SECTION_MAX_NB_LEVELS];
+
+    unsigned int nb_section_packet; ///< number of the packet section in case we are in "packets_and_frames" section
+    unsigned int nb_section_frame;  ///< number of the frame  section in case we are in "packets_and_frames" section
+    unsigned int nb_section_packet_frame; ///< nb_section_packet or nb_section_frame according if is_packets_and_frames
+};
+
+static const char *writer_get_name(void *p)
+{
+    WriterContext *wctx = p;
+    return wctx->writer->name;
+}
+
+static const AVClass writer_class = {
+    "Writer",
+    writer_get_name,
+    NULL,
+    LIBAVUTIL_VERSION_INT,
+};
+
+static void writer_close(WriterContext **wctx)
+{
+    if (!*wctx)
+        return;
+
+    if ((*wctx)->writer->uninit)
+        (*wctx)->writer->uninit(*wctx);
+    if ((*wctx)->writer->priv_class)
+        av_opt_free((*wctx)->priv);
+    av_freep(&((*wctx)->priv));
+    av_freep(wctx);
+}
+
+static int writer_open(WriterContext **wctx, const Writer *writer, const char *args,
+                       const struct section *sections, int nb_sections)
+{
+    int ret = 0;
+
+    if (!(*wctx = av_malloc(sizeof(WriterContext)))) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    if (!((*wctx)->priv = av_mallocz(writer->priv_size))) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    (*wctx)->class = &writer_class;
+    (*wctx)->writer = writer;
+    (*wctx)->level = -1;
+    (*wctx)->sections = sections;
+    (*wctx)->nb_sections = nb_sections;
+
+    if (writer->priv_class) {
+        void *priv_ctx = (*wctx)->priv;
+        *((const AVClass **)priv_ctx) = writer->priv_class;
+        av_opt_set_defaults(priv_ctx);
+
+        if (args &&
+            (ret = av_set_options_string(priv_ctx, args, "=", ":")) < 0)
+            goto fail;
+    }
+    if ((*wctx)->writer->init)
+        ret = (*wctx)->writer->init(*wctx);
+    if (ret < 0)
+        goto fail;
+
+    return 0;
+
+fail:
+    writer_close(wctx);
+    return ret;
+}
+
+static inline void writer_print_section_header(WriterContext *wctx,
+                                               int section_id)
+{
+    int parent_section_id;
+    wctx->level++;
+    av_assert0(wctx->level < SECTION_MAX_NB_LEVELS);
+    parent_section_id = wctx->level ?
+        (wctx->section[wctx->level-1])->id : SECTION_ID_NONE;
+
+    wctx->nb_item[wctx->level] = 0;
+    wctx->section[wctx->level] = &wctx->sections[section_id];
+
+    if (section_id == SECTION_ID_PACKETS_AND_FRAMES) {
+        wctx->nb_section_packet = wctx->nb_section_frame =
+        wctx->nb_section_packet_frame = 0;
+    } else if (parent_section_id == SECTION_ID_PACKETS_AND_FRAMES) {
+        wctx->nb_section_packet_frame = section_id == SECTION_ID_PACKET ?
+            wctx->nb_section_packet : wctx->nb_section_frame;
+    }
+
+    if (wctx->writer->print_section_header)
+        wctx->writer->print_section_header(wctx);
+}
+
+static inline void writer_print_section_footer(WriterContext *wctx)
+{
+    int section_id = wctx->section[wctx->level]->id;
+    int parent_section_id = wctx->level ?
+        wctx->section[wctx->level-1]->id : SECTION_ID_NONE;
+
+    if (parent_section_id != SECTION_ID_NONE)
+        wctx->nb_item[wctx->level-1]++;
+    if (parent_section_id == SECTION_ID_PACKETS_AND_FRAMES) {
+        if (section_id == SECTION_ID_PACKET) wctx->nb_section_packet++;
+        else                                     wctx->nb_section_frame++;
+    }
+    if (wctx->writer->print_section_footer)
+        wctx->writer->print_section_footer(wctx);
+    wctx->level--;
+}
+
+static inline void writer_print_integer(WriterContext *wctx,
+                                        const char *key, long long int val)
+{
+    if ((wctx->section[wctx->level]->id != SECTION_ID_FORMAT
+         && wctx->section[wctx->level]->id != SECTION_ID_FORMAT_TAGS) ||
+        !fmt_entries_to_show || av_dict_get(fmt_entries_to_show, key, NULL, 0)) {
+        wctx->writer->print_integer(wctx, key, val);
+        wctx->nb_item[wctx->level]++;
+    }
+}
+
+static inline void writer_print_string(WriterContext *wctx,
+                                       const char *key, const char *val, int opt)
+{
+    if (opt && !(wctx->writer->flags & WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS))
+        return;
+    if ((wctx->section[wctx->level]->id != SECTION_ID_FORMAT
+         && wctx->section[wctx->level]->id != SECTION_ID_FORMAT_TAGS) ||
+        !fmt_entries_to_show || av_dict_get(fmt_entries_to_show, key, NULL, 0)) {
+        wctx->writer->print_string(wctx, key, val);
+        wctx->nb_item[wctx->level]++;
+    }
+}
+
+static inline void writer_print_rational(WriterContext *wctx,
+                                         const char *key, AVRational q, char sep)
+{
+    AVBPrint buf;
+    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
+    av_bprintf(&buf, "%d%c%d", q.num, sep, q.den);
+    writer_print_string(wctx, key, buf.str, 0);
+}
+
+static void writer_print_time(WriterContext *wctx, const char *key,
+                              int64_t ts, const AVRational *time_base, int is_duration)
+{
+    char buf[128];
+
+    if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) {
+        writer_print_string(wctx, key, "N/A", 1);
+    } else {
+        double d = ts * av_q2d(*time_base);
+        struct unit_value uv;
+        uv.val.d = d;
+        uv.unit = unit_second_str;
+        value_string(buf, sizeof(buf), uv);
+        writer_print_string(wctx, key, buf, 0);
+    }
+}
+
+static void writer_print_ts(WriterContext *wctx, const char *key, int64_t ts, int is_duration)
+{
+    if ((!is_duration && ts == AV_NOPTS_VALUE) || (is_duration && ts == 0)) {
+        writer_print_string(wctx, key, "N/A", 1);
+    } else {
+        writer_print_integer(wctx, key, ts);
+    }
+}
+
+static void writer_print_data(WriterContext *wctx, const char *name,
+                              uint8_t *data, int size)
+{
+    AVBPrint bp;
+    int offset = 0, l, i;
+
+    av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
+    av_bprintf(&bp, "\n");
+    while (size) {
+        av_bprintf(&bp, "%08x: ", offset);
+        l = FFMIN(size, 16);
+        for (i = 0; i < l; i++) {
+            av_bprintf(&bp, "%02x", data[i]);
+            if (i & 1)
+                av_bprintf(&bp, " ");
+        }
+        av_bprint_chars(&bp, ' ', 41 - 2 * i - i / 2);
+        for (i = 0; i < l; i++)
+            av_bprint_chars(&bp, data[i] - 32U < 95 ? data[i] : '.', 1);
+        av_bprintf(&bp, "\n");
+        offset += l;
+        data   += l;
+        size   -= l;
+    }
+    writer_print_string(wctx, name, bp.str, 0);
+    av_bprint_finalize(&bp, NULL);
+}
+
+#define MAX_REGISTERED_WRITERS_NB 64
+
+static const Writer *registered_writers[MAX_REGISTERED_WRITERS_NB + 1];
+
+static int writer_register(const Writer *writer)
+{
+    static int next_registered_writer_idx = 0;
+
+    if (next_registered_writer_idx == MAX_REGISTERED_WRITERS_NB)
+        return AVERROR(ENOMEM);
+
+    registered_writers[next_registered_writer_idx++] = writer;
+    return 0;
+}
+
+static const Writer *writer_get_by_name(const char *name)
+{
+    int i;
+
+    for (i = 0; registered_writers[i]; i++)
+        if (!strcmp(registered_writers[i]->name, name))
+            return registered_writers[i];
+
+    return NULL;
+}
+
+
+/* WRITERS */
+
+#define DEFINE_WRITER_CLASS(name)                   \
+static const char *name##_get_name(void *ctx)       \
+{                                                   \
+    return #name ;                                  \
+}                                                   \
+static const AVClass name##_class = {               \
+    #name,                                          \
+    name##_get_name,                                \
+    name##_options                                  \
+}
+
+/* Default output */
+
+typedef struct DefaultContext {
+    const AVClass *class;
+    int nokey;
+    int noprint_wrappers;
+    int nested_section[SECTION_MAX_NB_LEVELS];
+    AVBPrint prefix[SECTION_MAX_NB_LEVELS];
+} DefaultContext;
+
+#define OFFSET(x) offsetof(DefaultContext, x)
+
+static const AVOption default_options[] = {
+    { "noprint_wrappers", "do not print headers and footers", OFFSET(noprint_wrappers), AV_OPT_TYPE_INT, {.i64=0}, 0, 1 },
+    { "nw",               "do not print headers and footers", OFFSET(noprint_wrappers), AV_OPT_TYPE_INT, {.i64=0}, 0, 1 },
+    { "nokey",          "force no key printing",     OFFSET(nokey),          AV_OPT_TYPE_INT, {.i64=0}, 0, 1 },
+    { "nk",             "force no key printing",     OFFSET(nokey),          AV_OPT_TYPE_INT, {.i64=0}, 0, 1 },
+    {NULL},
+};
+
+DEFINE_WRITER_CLASS(default);
+
+/* lame uppercasing routine, assumes the string is lower case ASCII */
+static inline char *upcase_string(char *dst, size_t dst_size, const char *src)
+{
+    int i;
+    for (i = 0; src[i] && i < dst_size-1; i++)
+        dst[i] = av_toupper(src[i]);
+    dst[i] = 0;
+    return dst;
+}
+
+static int default_init(WriterContext *wctx)
+{
+    DefaultContext *def = wctx->priv;
+    int i;
+
+    for (i = 0; i < SECTION_MAX_NB_LEVELS; i++)
+        av_bprint_init(&def->prefix[i], 1, AV_BPRINT_SIZE_UNLIMITED);
+    return 0;
+}
+
+static void default_uninit(WriterContext *wctx)
+{
+    DefaultContext *def = wctx->priv;
+    int i;
+
+    for (i = 0; i < SECTION_MAX_NB_LEVELS; i++)
+        av_bprint_finalize(&def->prefix[i], NULL);
+}
+
+static void default_print_section_header(WriterContext *wctx)
+{
+    DefaultContext *def = wctx->priv;
+    char buf[32];
+    const struct section *section = wctx->section[wctx->level];
+    const struct section *parent_section = wctx->level ?
+        wctx->section[wctx->level-1] : NULL;
+
+    av_bprint_clear(&def->prefix[wctx->level]);
+    if (parent_section &&
+        !(parent_section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY))) {
+        def->nested_section[wctx->level] = 1;
+        av_bprintf(&def->prefix[wctx->level], "%s%s:", def->prefix[wctx->level-1].str,
+                   upcase_string(buf, sizeof(buf),
+                                 av_x_if_null(section->element_name, section->name)));
+    }
+
+    if (def->noprint_wrappers || def->nested_section[wctx->level])
+        return;
+
+    if (!(section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY)))
+        printf("[%s]\n", upcase_string(buf, sizeof(buf), section->name));
+}
+
+static void default_print_section_footer(WriterContext *wctx)
+{
+    DefaultContext *def = wctx->priv;
+    const struct section *section = wctx->section[wctx->level];
+    char buf[32];
+
+    if (def->noprint_wrappers || def->nested_section[wctx->level])
+        return;
+
+    if (!(section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY)))
+        printf("[/%s]\n", upcase_string(buf, sizeof(buf), section->name));
+}
+
+static void default_print_str(WriterContext *wctx, const char *key, const char *value)
+{
+    DefaultContext *def = wctx->priv;
+
+    if (!def->nokey)
+        printf("%s%s=", def->prefix[wctx->level].str, key);
+    printf("%s\n", value);
+}
+
+static void default_print_int(WriterContext *wctx, const char *key, long long int value)
+{
+    DefaultContext *def = wctx->priv;
+
+    if (!def->nokey)
+        printf("%s%s=", def->prefix[wctx->level].str, key);
+    printf("%lld\n", value);
+}
+
+static const Writer default_writer = {
+    .name                  = "default",
+    .priv_size             = sizeof(DefaultContext),
+    .init                  = default_init,
+    .uninit                = default_uninit,
+    .print_section_header  = default_print_section_header,
+    .print_section_footer  = default_print_section_footer,
+    .print_integer         = default_print_int,
+    .print_string          = default_print_str,
+    .flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS,
+    .priv_class            = &default_class,
+};
+
+/* Compact output */
+
+/**
+ * Apply C-language-like string escaping.
+ */
+static const char *c_escape_str(AVBPrint *dst, const char *src, const char sep, void *log_ctx)
+{
+    const char *p;
+
+    for (p = src; *p; p++) {
+        switch (*p) {
+        case '\b': av_bprintf(dst, "%s", "\\b");  break;
+        case '\f': av_bprintf(dst, "%s", "\\f");  break;
+        case '\n': av_bprintf(dst, "%s", "\\n");  break;
+        case '\r': av_bprintf(dst, "%s", "\\r");  break;
+        case '\\': av_bprintf(dst, "%s", "\\\\"); break;
+        default:
+            if (*p == sep)
+                av_bprint_chars(dst, '\\', 1);
+            av_bprint_chars(dst, *p, 1);
+        }
+    }
+    return dst->str;
+}
+
+/**
+ * Quote fields containing special characters, check RFC4180.
+ */
+static const char *csv_escape_str(AVBPrint *dst, const char *src, const char sep, void *log_ctx)
+{
+    char meta_chars[] = { sep, '"', '\n', '\r', '\0' };
+    int needs_quoting = !!src[strcspn(src, meta_chars)];
+
+    if (needs_quoting)
+        av_bprint_chars(dst, '\"', 1);
+
+    for (; *src; src++) {
+        if (*src == '"')
+            av_bprint_chars(dst, '\"', 1);
+        av_bprint_chars(dst, *src, 1);
+    }
+    if (needs_quoting)
+        av_bprint_chars(dst, '\"', 1);
+    return dst->str;
+}
+
+static const char *none_escape_str(AVBPrint *dst, const char *src, const char sep, void *log_ctx)
+{
+    return src;
+}
+
+typedef struct CompactContext {
+    const AVClass *class;
+    char *item_sep_str;
+    char item_sep;
+    int nokey;
+    int print_section;
+    char *escape_mode_str;
+    const char * (*escape_str)(AVBPrint *dst, const char *src, const char sep, void *log_ctx);
+    int nested_section[SECTION_MAX_NB_LEVELS];
+    AVBPrint prefix[SECTION_MAX_NB_LEVELS];
+} CompactContext;
+
+#undef OFFSET
+#define OFFSET(x) offsetof(CompactContext, x)
+
+static const AVOption compact_options[]= {
+    {"item_sep", "set item separator",    OFFSET(item_sep_str),    AV_OPT_TYPE_STRING, {.str="|"},  CHAR_MIN, CHAR_MAX },
+    {"s",        "set item separator",    OFFSET(item_sep_str),    AV_OPT_TYPE_STRING, {.str="|"},  CHAR_MIN, CHAR_MAX },
+    {"nokey",    "force no key printing", OFFSET(nokey),           AV_OPT_TYPE_INT,    {.i64=0},    0,        1        },
+    {"nk",       "force no key printing", OFFSET(nokey),           AV_OPT_TYPE_INT,    {.i64=0},    0,        1        },
+    {"escape",   "set escape mode",       OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="c"},  CHAR_MIN, CHAR_MAX },
+    {"e",        "set escape mode",       OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="c"},  CHAR_MIN, CHAR_MAX },
+    {"print_section", "print section name", OFFSET(print_section), AV_OPT_TYPE_INT,    {.i64=1},    0,        1        },
+    {"p",             "print section name", OFFSET(print_section), AV_OPT_TYPE_INT,    {.i64=1},    0,        1        },
+    {NULL},
+};
+
+DEFINE_WRITER_CLASS(compact);
+
+static av_cold int compact_init(WriterContext *wctx)
+{
+    CompactContext *compact = wctx->priv;
+    int i;
+
+    if (strlen(compact->item_sep_str) != 1) {
+        av_log(wctx, AV_LOG_ERROR, "Item separator '%s' specified, but must contain a single character\n",
+               compact->item_sep_str);
+        return AVERROR(EINVAL);
+    }
+    compact->item_sep = compact->item_sep_str[0];
+
+    if      (!strcmp(compact->escape_mode_str, "none")) compact->escape_str = none_escape_str;
+    else if (!strcmp(compact->escape_mode_str, "c"   )) compact->escape_str = c_escape_str;
+    else if (!strcmp(compact->escape_mode_str, "csv" )) compact->escape_str = csv_escape_str;
+    else {
+        av_log(wctx, AV_LOG_ERROR, "Unknown escape mode '%s'\n", compact->escape_mode_str);
+        return AVERROR(EINVAL);
+    }
+
+    for (i = 0; i < SECTION_MAX_NB_LEVELS; i++)
+        av_bprint_init(&compact->prefix[i], 1, AV_BPRINT_SIZE_UNLIMITED);
+    return 0;
+}
+
+static void compact_uninit(WriterContext *wctx)
+{
+    CompactContext *compact = wctx->priv;
+    int i;
+
+    for (i = 0; i < SECTION_MAX_NB_LEVELS; i++)
+        av_bprint_finalize(&compact->prefix[i], NULL);
+}
+
+static void compact_print_section_header(WriterContext *wctx)
+{
+    CompactContext *compact = wctx->priv;
+    const struct section *section = wctx->section[wctx->level];
+    const struct section *parent_section = wctx->level ?
+        wctx->section[wctx->level-1] : NULL;
+
+    av_bprint_clear(&compact->prefix[wctx->level]);
+    if (parent_section &&
+        !(parent_section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY))) {
+        compact->nested_section[wctx->level] = 1;
+        av_bprintf(&compact->prefix[wctx->level], "%s%s:",
+                   compact->prefix[wctx->level-1].str,
+                   (char *)av_x_if_null(section->element_name, section->name));
+        wctx->nb_item[wctx->level] = wctx->nb_item[wctx->level-1];
+    } else if (compact->print_section &&
+        !(section->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY)))
+       printf("%s%c", section->name, compact->item_sep);
+}
+
+static void compact_print_section_footer(WriterContext *wctx)
+{
+    CompactContext *compact = wctx->priv;
+
+    if (!compact->nested_section[wctx->level] &&
+        !(wctx->section[wctx->level]->flags & (SECTION_FLAG_IS_WRAPPER|SECTION_FLAG_IS_ARRAY)))
+        printf("\n");
+}
+
+static void compact_print_str(WriterContext *wctx, const char *key, const char *value)
+{
+    CompactContext *compact = wctx->priv;
+    AVBPrint buf;
+
+    if (wctx->nb_item[wctx->level]) printf("%c", compact->item_sep);
+    if (!compact->nokey)
+        printf("%s%s=", compact->prefix[wctx->level].str, key);
+    av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
+    printf("%s", compact->escape_str(&buf, value, compact->item_sep, wctx));
+    av_bprint_finalize(&buf, NULL);
+}
+
+static void compact_print_int(WriterContext *wctx, const char *key, long long int value)
+{
+    CompactContext *compact = wctx->priv;
+
+    if (wctx->nb_item[wctx->level]) printf("%c", compact->item_sep);
+    if (!compact->nokey)
+        printf("%s%s=", compact->prefix[wctx->level].str, key);
+    printf("%lld", value);
+}
+
+static const Writer compact_writer = {
+    .name                 = "compact",
+    .priv_size            = sizeof(CompactContext),
+    .init                 = compact_init,
+    .uninit               = compact_uninit,
+    .print_section_header = compact_print_section_header,
+    .print_section_footer = compact_print_section_footer,
+    .print_integer        = compact_print_int,
+    .print_string         = compact_print_str,
+    .flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS,
+    .priv_class           = &compact_class,
+};
+
+/* CSV output */
+
+#undef OFFSET
+#define OFFSET(x) offsetof(CompactContext, x)
+
+static const AVOption csv_options[] = {
+    {"item_sep", "set item separator",    OFFSET(item_sep_str),    AV_OPT_TYPE_STRING, {.str=","},  CHAR_MIN, CHAR_MAX },
+    {"s",        "set item separator",    OFFSET(item_sep_str),    AV_OPT_TYPE_STRING, {.str=","},  CHAR_MIN, CHAR_MAX },
+    {"nokey",    "force no key printing", OFFSET(nokey),           AV_OPT_TYPE_INT,    {.i64=1},    0,        1        },
+    {"nk",       "force no key printing", OFFSET(nokey),           AV_OPT_TYPE_INT,    {.i64=1},    0,        1        },
+    {"escape",   "set escape mode",       OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="csv"}, CHAR_MIN, CHAR_MAX },
+    {"e",        "set escape mode",       OFFSET(escape_mode_str), AV_OPT_TYPE_STRING, {.str="csv"}, CHAR_MIN, CHAR_MAX },
+    {"print_section", "print section name", OFFSET(print_section), AV_OPT_TYPE_INT,    {.i64=1},    0,        1        },
+    {"p",             "print section name", OFFSET(print_section), AV_OPT_TYPE_INT,    {.i64=1},    0,        1        },
+    {NULL},
+};
+
+DEFINE_WRITER_CLASS(csv);
+
+static const Writer csv_writer = {
+    .name                 = "csv",
+    .priv_size            = sizeof(CompactContext),
+    .init                 = compact_init,
+    .print_section_header = compact_print_section_header,
+    .print_section_footer = compact_print_section_footer,
+    .print_integer        = compact_print_int,
+    .print_string         = compact_print_str,
+    .flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS,
+    .priv_class           = &csv_class,
+};
+
+/* Flat output */
+
+typedef struct FlatContext {
+    const AVClass *class;
+    AVBPrint section_header[SECTION_MAX_NB_LEVELS];
+    const char *sep_str;
+    char sep;
+    int hierarchical;
+} FlatContext;
+
+#undef OFFSET
+#define OFFSET(x) offsetof(FlatContext, x)
+
+static const AVOption flat_options[]= {
+    {"sep_char", "set separator",    OFFSET(sep_str),    AV_OPT_TYPE_STRING, {.str="."},  CHAR_MIN, CHAR_MAX },
+    {"s",        "set separator",    OFFSET(sep_str),    AV_OPT_TYPE_STRING, {.str="."},  CHAR_MIN, CHAR_MAX },
+    {"hierarchical", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_INT, {.i64=1}, 0, 1 },
+    {"h",           "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_INT, {.i64=1}, 0, 1 },
+    {NULL},
+};
+
+DEFINE_WRITER_CLASS(flat);
+
+static av_cold int flat_init(WriterContext *wctx)
+{
+    FlatContext *flat = wctx->priv;
+    int i;
+
+    if (strlen(flat->sep_str) != 1) {
+        av_log(wctx, AV_LOG_ERROR, "Item separator '%s' specified, but must contain a single character\n",
+               flat->sep_str);
+        return AVERROR(EINVAL);
+    }
+    flat->sep = flat->sep_str[0];
+
+    for (i = 0; i < SECTION_MAX_NB_LEVELS; i++)
+        av_bprint_init(&flat->section_header[i], 1, AV_BPRINT_SIZE_UNLIMITED);
+    return 0;
+}
+
+static void flat_uninit(WriterContext *wctx)
+{
+    FlatContext *flat = wctx->priv;
+    int i;
+
+    for (i = 0; i < SECTION_MAX_NB_LEVELS; i++)
+        av_bprint_finalize(&flat->section_header[i], NULL);
+}
+
+static const char *flat_escape_key_str(AVBPrint *dst, const char *src, const char sep)
+{
+    const char *p;
+
+    for (p = src; *p; p++) {
+        if (!((*p >= '0' && *p <= '9') ||
+              (*p >= 'a' && *p <= 'z') ||
+              (*p >= 'A' && *p <= 'Z')))
+            av_bprint_chars(dst, '_', 1);
+        else
+            av_bprint_chars(dst, *p, 1);
+    }
+    return dst->str;
+}
+
+static const char *flat_escape_value_str(AVBPrint *dst, const char *src)
+{
+    const char *p;
+
+    for (p = src; *p; p++) {
+        switch (*p) {
+        case '\n': av_bprintf(dst, "%s", "\\n");  break;
+        case '\r': av_bprintf(dst, "%s", "\\r");  break;
+        case '\\': av_bprintf(dst, "%s", "\\\\"); break;
+        case '"':  av_bprintf(dst, "%s", "\\\""); break;
+        case '`':  av_bprintf(dst, "%s", "\\`");  break;
+        case '$':  av_bprintf(dst, "%s", "\\$");  break;
+        default:   av_bprint_chars(dst, *p, 1);   break;
+        }
+    }
+    return dst->str;
+}
+
+static void flat_print_section_header(WriterContext *wctx)
+{
+    FlatContext *flat = wctx->priv;
+    AVBPrint *buf = &flat->section_header[wctx->level];
+    const struct section *section = wctx->section[wctx->level];
+    const struct section *parent_section = wctx->level ?
+        wctx->section[wctx->level-1] : NULL;
+
+    /* build section header */
+    av_bprint_clear(buf);
+    if (!parent_section)
+        return;
+    av_bprintf(buf, "%s", flat->section_header[wctx->level-1].str);
+
+    if (flat->hierarchical ||
+        !(section->flags & (SECTION_FLAG_IS_ARRAY|SECTION_FLAG_IS_WRAPPER))) {
+        av_bprintf(buf, "%s%s", wctx->section[wctx->level]->name, flat->sep_str);
+
+        if (parent_section->flags & SECTION_FLAG_IS_ARRAY) {
+            int n = parent_section->id == SECTION_ID_PACKETS_AND_FRAMES ?
+                wctx->nb_section_packet_frame : wctx->nb_item[wctx->level-1];
+            av_bprintf(buf, "%d%s", n, flat->sep_str);
+        }
+    }
+}
+
+static void flat_print_int(WriterContext *wctx, const char *key, long long int value)
+{
+    FlatContext *flat = wctx->priv;
+    printf("%s%s=%lld\n", flat->section_header[wctx->level].str, key, value);
+}
+
+static void flat_print_str(WriterContext *wctx, const char *key, const char *value)
+{
+    FlatContext *flat = wctx->priv;
+    AVBPrint buf;
+
+    printf("%s", flat->section_header[wctx->level].str);
+    av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
+    printf("%s=", flat_escape_key_str(&buf, key, flat->sep));
+    av_bprint_clear(&buf);
+    printf("\"%s\"\n", flat_escape_value_str(&buf, value));
+    av_bprint_finalize(&buf, NULL);
+}
+
+static const Writer flat_writer = {
+    .name                  = "flat",
+    .priv_size             = sizeof(FlatContext),
+    .init                  = flat_init,
+    .uninit                = flat_uninit,
+    .print_section_header  = flat_print_section_header,
+    .print_integer         = flat_print_int,
+    .print_string          = flat_print_str,
+    .flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS|WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER,
+    .priv_class            = &flat_class,
+};
+
+/* INI format output */
+
+typedef struct {
+    const AVClass *class;
+    int hierarchical;
+    AVBPrint section_header[SECTION_MAX_NB_LEVELS];
+} INIContext;
+
+#undef OFFSET
+#define OFFSET(x) offsetof(INIContext, x)
+
+static const AVOption ini_options[] = {
+    {"hierarchical", "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_INT, {.i64=1}, 0, 1 },
+    {"h",           "specify if the section specification should be hierarchical", OFFSET(hierarchical), AV_OPT_TYPE_INT, {.i64=1}, 0, 1 },
+    {NULL},
+};
+
+DEFINE_WRITER_CLASS(ini);
+
+static int ini_init(WriterContext *wctx)
+{
+    INIContext *ini = wctx->priv;
+    int i;
+
+    for (i = 0; i < SECTION_MAX_NB_LEVELS; i++)
+        av_bprint_init(&ini->section_header[i], 1, AV_BPRINT_SIZE_UNLIMITED);
+    return 0;
+}
+
+static void ini_uninit(WriterContext *wctx)
+{
+    INIContext *ini = wctx->priv;
+    int i;
+
+    for (i = 0; i < SECTION_MAX_NB_LEVELS; i++)
+        av_bprint_finalize(&ini->section_header[i], NULL);
+}
+
+static char *ini_escape_str(AVBPrint *dst, const char *src)
+{
+    int i = 0;
+    char c = 0;
+
+    while (c = src[i++]) {
+        switch (c) {
+        case '\b': av_bprintf(dst, "%s", "\\b"); break;
+        case '\f': av_bprintf(dst, "%s", "\\f"); break;
+        case '\n': av_bprintf(dst, "%s", "\\n"); break;
+        case '\r': av_bprintf(dst, "%s", "\\r"); break;
+        case '\t': av_bprintf(dst, "%s", "\\t"); break;
+        case '\\':
+        case '#' :
+        case '=' :
+        case ':' : av_bprint_chars(dst, '\\', 1);
+        default:
+            if ((unsigned char)c < 32)
+                av_bprintf(dst, "\\x00%02x", c & 0xff);
+            else
+                av_bprint_chars(dst, c, 1);
+            break;
+        }
+    }
+    return dst->str;
+}
+
+static void ini_print_section_header(WriterContext *wctx)
+{
+    INIContext *ini = wctx->priv;
+    AVBPrint *buf = &ini->section_header[wctx->level];
+    const struct section *section = wctx->section[wctx->level];
+    const struct section *parent_section = wctx->level ?
+        wctx->section[wctx->level-1] : NULL;
+
+    av_bprint_clear(buf);
+    if (!parent_section) {
+        printf("# ffprobe output\n\n");
+        return;
+    }
+
+    if (wctx->nb_item[wctx->level-1])
+        printf("\n");
+
+    av_bprintf(buf, "%s", ini->section_header[wctx->level-1].str);
+    if (ini->hierarchical ||
+        !(section->flags & (SECTION_FLAG_IS_ARRAY|SECTION_FLAG_IS_WRAPPER))) {
+        av_bprintf(buf, "%s%s", buf->str[0] ? "." : "", wctx->section[wctx->level]->name);
+
+        if (parent_section->flags & SECTION_FLAG_IS_ARRAY) {
+            int n = parent_section->id == SECTION_ID_PACKETS_AND_FRAMES ?
+                wctx->nb_section_packet_frame : wctx->nb_item[wctx->level-1];
+            av_bprintf(buf, ".%d", n);
+        }
+    }
+
+    if (!(section->flags & (SECTION_FLAG_IS_ARRAY|SECTION_FLAG_IS_WRAPPER)))
+        printf("[%s]\n", buf->str);
+}
+
+static void ini_print_str(WriterContext *wctx, const char *key, const char *value)
+{
+    AVBPrint buf;
+
+    av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
+    printf("%s=", ini_escape_str(&buf, key));
+    av_bprint_clear(&buf);
+    printf("%s\n", ini_escape_str(&buf, value));
+    av_bprint_finalize(&buf, NULL);
+}
+
+static void ini_print_int(WriterContext *wctx, const char *key, long long int value)
+{
+    printf("%s=%lld\n", key, value);
+}
+
+static const Writer ini_writer = {
+    .name                  = "ini",
+    .priv_size             = sizeof(INIContext),
+    .init                  = ini_init,
+    .uninit                = ini_uninit,
+    .print_section_header  = ini_print_section_header,
+    .print_integer         = ini_print_int,
+    .print_string          = ini_print_str,
+    .flags = WRITER_FLAG_DISPLAY_OPTIONAL_FIELDS|WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER,
+    .priv_class            = &ini_class,
+};
+
+/* JSON output */
+
+typedef struct {
+    const AVClass *class;
+    int indent_level;
+    int compact;
+    const char *item_sep, *item_start_end;
+} JSONContext;
+
+#undef OFFSET
+#define OFFSET(x) offsetof(JSONContext, x)
+
+static const AVOption json_options[]= {
+    { "compact", "enable compact output", OFFSET(compact), AV_OPT_TYPE_INT, {.i64=0}, 0, 1 },
+    { "c",       "enable compact output", OFFSET(compact), AV_OPT_TYPE_INT, {.i64=0}, 0, 1 },
+    { NULL }
+};
+
+DEFINE_WRITER_CLASS(json);
+
+static av_cold int json_init(WriterContext *wctx)
+{
+    JSONContext *json = wctx->priv;
+
+    json->item_sep       = json->compact ? ", " : ",\n";
+    json->item_start_end = json->compact ? " "  : "\n";
+
+    return 0;
+}
+
+static const char *json_escape_str(AVBPrint *dst, const char *src, void *log_ctx)
+{
+    static const char json_escape[] = {'"', '\\', '\b', '\f', '\n', '\r', '\t', 0};
+    static const char json_subst[]  = {'"', '\\',  'b',  'f',  'n',  'r',  't', 0};
+    const char *p;
+
+    for (p = src; *p; p++) {
+        char *s = strchr(json_escape, *p);
+        if (s) {
+            av_bprint_chars(dst, '\\', 1);
+            av_bprint_chars(dst, json_subst[s - json_escape], 1);
+        } else if ((unsigned char)*p < 32) {
+            av_bprintf(dst, "\\u00%02x", *p & 0xff);
+        } else {
+            av_bprint_chars(dst, *p, 1);
+        }
+    }
+    return dst->str;
+}
+
+#define JSON_INDENT() printf("%*c", json->indent_level * 4, ' ')
+
+static void json_print_section_header(WriterContext *wctx)
+{
+    JSONContext *json = wctx->priv;
+    AVBPrint buf;
+    const struct section *section = wctx->section[wctx->level];
+    const struct section *parent_section = wctx->level ?
+        wctx->section[wctx->level-1] : NULL;
+
+    if (wctx->level && wctx->nb_item[wctx->level-1])
+        printf(",\n");
+
+    if (section->flags & SECTION_FLAG_IS_WRAPPER) {
+        printf("{\n");
+        json->indent_level++;
+    } else {
+        av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
+        json_escape_str(&buf, section->name, wctx);
+        JSON_INDENT();
+
+        json->indent_level++;
+        if (section->flags & SECTION_FLAG_IS_ARRAY) {
+            printf("\"%s\": [\n", buf.str);
+        } else if (!(parent_section->flags & SECTION_FLAG_IS_ARRAY)) {
+            printf("\"%s\": {%s", buf.str, json->item_start_end);
+        } else {
+            printf("{%s", json->item_start_end);
+
+            /* this is required so the parser can distinguish between packets and frames */
+            if (parent_section->id == SECTION_ID_PACKETS_AND_FRAMES) {
+                if (!json->compact)
+                    JSON_INDENT();
+                printf("\"type\": \"%s\"%s", section->name, json->item_sep);
+            }
+        }
+        av_bprint_finalize(&buf, NULL);
+    }
+}
+
+static void json_print_section_footer(WriterContext *wctx)
+{
+    JSONContext *json = wctx->priv;
+    const struct section *section = wctx->section[wctx->level];
+
+    if (wctx->level == 0) {
+        json->indent_level--;
+        printf("\n}\n");
+    } else if (section->flags & SECTION_FLAG_IS_ARRAY) {
+        printf("\n");
+        json->indent_level--;
+        JSON_INDENT();
+        printf("]");
+    } else {
+        printf("%s", json->item_start_end);
+        json->indent_level--;
+        if (!json->compact)
+            JSON_INDENT();
+        printf("}");
+    }
+}
+
+static inline void json_print_item_str(WriterContext *wctx,
+                                       const char *key, const char *value)
+{
+    AVBPrint buf;
+
+    av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
+    printf("\"%s\":", json_escape_str(&buf, key,   wctx));
+    av_bprint_clear(&buf);
+    printf(" \"%s\"", json_escape_str(&buf, value, wctx));
+    av_bprint_finalize(&buf, NULL);
+}
+
+static void json_print_str(WriterContext *wctx, const char *key, const char *value)
+{
+    JSONContext *json = wctx->priv;
+
+    if (wctx->nb_item[wctx->level])
+        printf("%s", json->item_sep);
+    if (!json->compact)
+        JSON_INDENT();
+    json_print_item_str(wctx, key, value);
+}
+
+static void json_print_int(WriterContext *wctx, const char *key, long long int value)
+{
+    JSONContext *json = wctx->priv;
+    AVBPrint buf;
+
+    if (wctx->nb_item[wctx->level])
+        printf("%s", json->item_sep);
+    if (!json->compact)
+        JSON_INDENT();
+
+    av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
+    printf("\"%s\": %lld", json_escape_str(&buf, key, wctx), value);
+    av_bprint_finalize(&buf, NULL);
+}
+
+static const Writer json_writer = {
+    .name                 = "json",
+    .priv_size            = sizeof(JSONContext),
+    .init                 = json_init,
+    .print_section_header = json_print_section_header,
+    .print_section_footer = json_print_section_footer,
+    .print_integer        = json_print_int,
+    .print_string         = json_print_str,
+    .flags = WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER,
+    .priv_class           = &json_class,
+};
+
+/* XML output */
+
+typedef struct {
+    const AVClass *class;
+    int within_tag;
+    int indent_level;
+    int fully_qualified;
+    int xsd_strict;
+} XMLContext;
+
+#undef OFFSET
+#define OFFSET(x) offsetof(XMLContext, x)
+
+static const AVOption xml_options[] = {
+    {"fully_qualified", "specify if the output should be fully qualified", OFFSET(fully_qualified), AV_OPT_TYPE_INT, {.i64=0},  0, 1 },
+    {"q",               "specify if the output should be fully qualified", OFFSET(fully_qualified), AV_OPT_TYPE_INT, {.i64=0},  0, 1 },
+    {"xsd_strict",      "ensure that the output is XSD compliant",         OFFSET(xsd_strict),      AV_OPT_TYPE_INT, {.i64=0},  0, 1 },
+    {"x",               "ensure that the output is XSD compliant",         OFFSET(xsd_strict),      AV_OPT_TYPE_INT, {.i64=0},  0, 1 },
+    {NULL},
+};
+
+DEFINE_WRITER_CLASS(xml);
+
+static av_cold int xml_init(WriterContext *wctx)
+{
+    XMLContext *xml = wctx->priv;
+
+    if (xml->xsd_strict) {
+        xml->fully_qualified = 1;
+#define CHECK_COMPLIANCE(opt, opt_name)                                 \
+        if (opt) {                                                      \
+            av_log(wctx, AV_LOG_ERROR,                                  \
+                   "XSD-compliant output selected but option '%s' was selected, XML output may be non-compliant.\n" \
+                   "You need to disable such option with '-no%s'\n", opt_name, opt_name); \
+            return AVERROR(EINVAL);                                     \
+        }
+        CHECK_COMPLIANCE(show_private_data, "private");
+        CHECK_COMPLIANCE(show_value_unit,   "unit");
+        CHECK_COMPLIANCE(use_value_prefix,  "prefix");
+
+        if (do_show_frames && do_show_packets) {
+            av_log(wctx, AV_LOG_ERROR,
+                   "Interleaved frames and packets are not allowed in XSD. "
+                   "Select only one between the -show_frames and the -show_packets options.\n");
+            return AVERROR(EINVAL);
+        }
+    }
+
+    return 0;
+}
+
+static const char *xml_escape_str(AVBPrint *dst, const char *src, void *log_ctx)
+{
+    const char *p;
+
+    for (p = src; *p; p++) {
+        switch (*p) {
+        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", "&apos;"); break;
+        default: av_bprint_chars(dst, *p, 1);
+        }
+    }
+
+    return dst->str;
+}
+
+#define XML_INDENT() printf("%*c", xml->indent_level * 4, ' ')
+
+static void xml_print_section_header(WriterContext *wctx)
+{
+    XMLContext *xml = wctx->priv;
+    const struct section *section = wctx->section[wctx->level];
+    const struct section *parent_section = wctx->level ?
+        wctx->section[wctx->level-1] : NULL;
+
+    if (wctx->level == 0) {
+        const char *qual = " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
+            "xmlns:ffprobe='http://www.ffmpeg.org/schema/ffprobe' "
+            "xsi:schemaLocation='http://www.ffmpeg.org/schema/ffprobe ffprobe.xsd'";
+
+        printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+        printf("<%sffprobe%s>\n",
+               xml->fully_qualified ? "ffprobe:" : "",
+               xml->fully_qualified ? qual : "");
+        return;
+    }
+
+    if (xml->within_tag) {
+        xml->within_tag = 0;
+        printf(">\n");
+    }
+    if (section->flags & SECTION_FLAG_HAS_VARIABLE_FIELDS) {
+        xml->indent_level++;
+    } else {
+        if (parent_section && (parent_section->flags & SECTION_FLAG_IS_WRAPPER) &&
+            wctx->level && wctx->nb_item[wctx->level-1])
+            printf("\n");
+        xml->indent_level++;
+
+        if (section->flags & SECTION_FLAG_IS_ARRAY) {
+            XML_INDENT(); printf("<%s>\n", section->name);
+        } else {
+            XML_INDENT(); printf("<%s ", section->name);
+            xml->within_tag = 1;
+        }
+    }
+}
+
+static void xml_print_section_footer(WriterContext *wctx)
+{
+    XMLContext *xml = wctx->priv;
+    const struct section *section = wctx->section[wctx->level];
+
+    if (wctx->level == 0) {
+        printf("</%sffprobe>\n", xml->fully_qualified ? "ffprobe:" : "");
+    } else if (xml->within_tag) {
+        xml->within_tag = 0;
+        printf("/>\n");
+        xml->indent_level--;
+    } else if (section->flags & SECTION_FLAG_HAS_VARIABLE_FIELDS) {
+        xml->indent_level--;
+    } else {
+        XML_INDENT(); printf("</%s>\n", section->name);
+        xml->indent_level--;
+    }
+}
+
+static void xml_print_str(WriterContext *wctx, const char *key, const char *value)
+{
+    AVBPrint buf;
+    XMLContext *xml = wctx->priv;
+    const struct section *section = wctx->section[wctx->level];
+
+    av_bprint_init(&buf, 1, AV_BPRINT_SIZE_UNLIMITED);
+
+    if (section->flags & SECTION_FLAG_HAS_VARIABLE_FIELDS) {
+        XML_INDENT();
+        printf("<%s key=\"%s\"",
+               section->element_name, xml_escape_str(&buf, key, wctx));
+        av_bprint_clear(&buf);
+        printf(" value=\"%s\"/>\n", xml_escape_str(&buf, value, wctx));
+    } else {
+        if (wctx->nb_item[wctx->level])
+            printf(" ");
+        printf("%s=\"%s\"", key, xml_escape_str(&buf, value, wctx));
+    }
+
+    av_bprint_finalize(&buf, NULL);
+}
+
+static void xml_print_int(WriterContext *wctx, const char *key, long long int value)
+{
+    if (wctx->nb_item[wctx->level])
+        printf(" ");
+    printf("%s=\"%lld\"", key, value);
+}
+
+static Writer xml_writer = {
+    .name                 = "xml",
+    .priv_size            = sizeof(XMLContext),
+    .init                 = xml_init,
+    .print_section_header = xml_print_section_header,
+    .print_section_footer = xml_print_section_footer,
+    .print_integer        = xml_print_int,
+    .print_string         = xml_print_str,
+    .flags = WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER,
+    .priv_class           = &xml_class,
+};
+
+static void writer_register_all(void)
+{
+    static int initialized;
+
+    if (initialized)
+        return;
+    initialized = 1;
+
+    writer_register(&default_writer);
+    writer_register(&compact_writer);
+    writer_register(&csv_writer);
+    writer_register(&flat_writer);
+    writer_register(&ini_writer);
+    writer_register(&json_writer);
+    writer_register(&xml_writer);
+}
+
+#define print_fmt(k, f, ...) do {              \
+    av_bprint_clear(&pbuf);                    \
+    av_bprintf(&pbuf, f, __VA_ARGS__);         \
+    writer_print_string(w, k, pbuf.str, 0);    \
+} while (0)
+
+#define print_int(k, v)         writer_print_integer(w, k, v)
+#define print_q(k, v, s)        writer_print_rational(w, k, v, s)
+#define print_str(k, v)         writer_print_string(w, k, v, 0)
+#define print_str_opt(k, v)     writer_print_string(w, k, v, 1)
+#define print_time(k, v, tb)    writer_print_time(w, k, v, tb, 0)
+#define print_ts(k, v)          writer_print_ts(w, k, v, 0)
+#define print_duration_time(k, v, tb) writer_print_time(w, k, v, tb, 1)
+#define print_duration_ts(k, v)       writer_print_ts(w, k, v, 1)
+#define print_val(k, v, u) do {                                     \
+    struct unit_value uv;                                           \
+    uv.val.i = v;                                                   \
+    uv.unit = u;                                                    \
+    writer_print_string(w, k, value_string(val_str, sizeof(val_str), uv), 0); \
+} while (0)
+
+#define print_section_header(s) writer_print_section_header(w, s)
+#define print_section_footer(s) writer_print_section_footer(w, s)
+
+static inline void show_tags(WriterContext *wctx, AVDictionary *tags, int section_id)
+{
+    AVDictionaryEntry *tag = NULL;
+
+    if (!tags)
+        return;
+    writer_print_section_header(wctx, section_id);
+    while ((tag = av_dict_get(tags, "", tag, AV_DICT_IGNORE_SUFFIX)))
+        writer_print_string(wctx, tag->key, tag->value, 0);
+    writer_print_section_footer(wctx);
+}
+
+static void show_packet(WriterContext *w, AVFormatContext *fmt_ctx, AVPacket *pkt, int packet_idx)
+{
+    char val_str[128];
+    AVStream *st = fmt_ctx->streams[pkt->stream_index];
+    AVBPrint pbuf;
+    const char *s;
+
+    av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
+
+    writer_print_section_header(w, SECTION_ID_PACKET);
+
+    s = av_get_media_type_string(st->codec->codec_type);
+    if (s) print_str    ("codec_type", s);
+    else   print_str_opt("codec_type", "unknown");
+    print_int("stream_index",     pkt->stream_index);
+    print_ts  ("pts",             pkt->pts);
+    print_time("pts_time",        pkt->pts, &st->time_base);
+    print_ts  ("dts",             pkt->dts);
+    print_time("dts_time",        pkt->dts, &st->time_base);
+    print_duration_ts("duration",        pkt->duration);
+    print_duration_time("duration_time", pkt->duration, &st->time_base);
+    print_duration_ts("convergence_duration", pkt->convergence_duration);
+    print_duration_time("convergence_duration_time", pkt->convergence_duration, &st->time_base);
+    print_val("size",             pkt->size, unit_byte_str);
+    if (pkt->pos != -1) print_fmt    ("pos", "%"PRId64, pkt->pos);
+    else                print_str_opt("pos", "N/A");
+    print_fmt("flags", "%c",      pkt->flags & AV_PKT_FLAG_KEY ? 'K' : '_');
+    if (do_show_data)
+        writer_print_data(w, "data", pkt->data, pkt->size);
+    writer_print_section_footer(w);
+
+    av_bprint_finalize(&pbuf, NULL);
+    fflush(stdout);
+}
+
+static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
+                       AVFormatContext *fmt_ctx)
+{
+    AVBPrint pbuf;
+    const char *s;
+
+    av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
+
+    writer_print_section_header(w, SECTION_ID_FRAME);
+
+    s = av_get_media_type_string(stream->codec->codec_type);
+    if (s) print_str    ("media_type", s);
+    else   print_str_opt("media_type", "unknown");
+    print_int("key_frame",              frame->key_frame);
+    print_ts  ("pkt_pts",               frame->pkt_pts);
+    print_time("pkt_pts_time",          frame->pkt_pts, &stream->time_base);
+    print_ts  ("pkt_dts",               frame->pkt_dts);
+    print_time("pkt_dts_time",          frame->pkt_dts, &stream->time_base);
+    print_duration_ts  ("pkt_duration",      frame->pkt_duration);
+    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");
+
+    switch (stream->codec->codec_type) {
+        AVRational sar;
+
+    case AVMEDIA_TYPE_VIDEO:
+        print_int("width",                  frame->width);
+        print_int("height",                 frame->height);
+        s = av_get_pix_fmt_name(frame->format);
+        if (s) print_str    ("pix_fmt", s);
+        else   print_str_opt("pix_fmt", "unknown");
+        sar = av_guess_sample_aspect_ratio(fmt_ctx, stream, frame);
+        if (sar.num) {
+            print_q("sample_aspect_ratio", sar, ':');
+        } else {
+            print_str_opt("sample_aspect_ratio", "N/A");
+        }
+        print_fmt("pict_type",              "%c", av_get_picture_type_char(frame->pict_type));
+        print_int("coded_picture_number",   frame->coded_picture_number);
+        print_int("display_picture_number", frame->display_picture_number);
+        print_int("interlaced_frame",       frame->interlaced_frame);
+        print_int("top_field_first",        frame->top_field_first);
+        print_int("repeat_pict",            frame->repeat_pict);
+        print_int("reference",              frame->reference);
+        break;
+
+    case AVMEDIA_TYPE_AUDIO:
+        s = av_get_sample_fmt_name(frame->format);
+        if (s) print_str    ("sample_fmt", s);
+        else   print_str_opt("sample_fmt", "unknown");
+        print_int("nb_samples",         frame->nb_samples);
+        print_int("channels", av_frame_get_channels(frame));
+        if (av_frame_get_channel_layout(frame)) {
+            av_bprint_clear(&pbuf);
+            av_bprint_channel_layout(&pbuf, av_frame_get_channels(frame),
+                                     av_frame_get_channel_layout(frame));
+            print_str    ("channel_layout", pbuf.str);
+        } else
+            print_str_opt("channel_layout", "unknown");
+        break;
+    }
+    show_tags(w, av_frame_get_metadata(frame), SECTION_ID_FRAME_TAGS);
+
+    writer_print_section_footer(w);
+
+    av_bprint_finalize(&pbuf, NULL);
+    fflush(stdout);
+}
+
+static av_always_inline int process_frame(WriterContext *w,
+                                          AVFormatContext *fmt_ctx,
+                                          AVFrame *frame, AVPacket *pkt)
+{
+    AVCodecContext *dec_ctx = fmt_ctx->streams[pkt->stream_index]->codec;
+    int ret = 0, got_frame = 0;
+
+    avcodec_get_frame_defaults(frame);
+    if (dec_ctx->codec) {
+        switch (dec_ctx->codec_type) {
+        case AVMEDIA_TYPE_VIDEO:
+            ret = avcodec_decode_video2(dec_ctx, frame, &got_frame, pkt);
+            break;
+
+        case AVMEDIA_TYPE_AUDIO:
+            ret = avcodec_decode_audio4(dec_ctx, frame, &got_frame, pkt);
+            break;
+        }
+    }
+
+    if (ret < 0)
+        return ret;
+    ret = FFMIN(ret, pkt->size); /* guard against bogus return values */
+    pkt->data += ret;
+    pkt->size -= ret;
+    if (got_frame) {
+        nb_streams_frames[pkt->stream_index]++;
+        if (do_show_frames)
+            show_frame(w, frame, fmt_ctx->streams[pkt->stream_index], fmt_ctx);
+    }
+    return got_frame;
+}
+
+static void read_packets(WriterContext *w, AVFormatContext *fmt_ctx)
+{
+    AVPacket pkt, pkt1;
+    AVFrame frame;
+    int i = 0;
+
+    av_init_packet(&pkt);
+
+    while (!av_read_frame(fmt_ctx, &pkt)) {
+        if (selected_streams[pkt.stream_index]) {
+            if (do_read_packets) {
+                if (do_show_packets)
+                    show_packet(w, fmt_ctx, &pkt, i++);
+                nb_streams_packets[pkt.stream_index]++;
+            }
+            if (do_read_frames) {
+                pkt1 = pkt;
+                while (pkt1.size && process_frame(w, fmt_ctx, &frame, &pkt1) > 0);
+            }
+        }
+        av_free_packet(&pkt);
+    }
+    av_init_packet(&pkt);
+    pkt.data = NULL;
+    pkt.size = 0;
+    //Flush remaining frames that are cached in the decoder
+    for (i = 0; i < fmt_ctx->nb_streams; i++) {
+        pkt.stream_index = i;
+        if (do_read_frames)
+            while (process_frame(w, fmt_ctx, &frame, &pkt) > 0);
+    }
+}
+
+static void show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx)
+{
+    AVStream *stream = fmt_ctx->streams[stream_idx];
+    AVCodecContext *dec_ctx;
+    const AVCodec *dec;
+    char val_str[128];
+    const char *s;
+    AVRational sar, dar;
+    AVBPrint pbuf;
+
+    av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
+
+    writer_print_section_header(w, SECTION_ID_STREAM);
+
+    print_int("index", stream->index);
+
+    if ((dec_ctx = stream->codec)) {
+        const char *profile = NULL;
+        dec = dec_ctx->codec;
+        if (dec) {
+            print_str("codec_name", dec->name);
+            if (!do_bitexact) {
+                if (dec->long_name) print_str    ("codec_long_name", dec->long_name);
+                else                print_str_opt("codec_long_name", "unknown");
+            }
+        } else {
+            print_str_opt("codec_name", "unknown");
+            if (!do_bitexact) {
+                print_str_opt("codec_long_name", "unknown");
+            }
+        }
+
+        if (dec && (profile = av_get_profile_name(dec, dec_ctx->profile)))
+            print_str("profile", profile);
+        else
+            print_str_opt("profile", "unknown");
+
+        s = av_get_media_type_string(dec_ctx->codec_type);
+        if (s) print_str    ("codec_type", s);
+        else   print_str_opt("codec_type", "unknown");
+        print_q("codec_time_base", dec_ctx->time_base, '/');
+
+        /* print AVI/FourCC tag */
+        av_get_codec_tag_string(val_str, sizeof(val_str), dec_ctx->codec_tag);
+        print_str("codec_tag_string",    val_str);
+        print_fmt("codec_tag", "0x%04x", dec_ctx->codec_tag);
+
+        switch (dec_ctx->codec_type) {
+        case AVMEDIA_TYPE_VIDEO:
+            print_int("width",        dec_ctx->width);
+            print_int("height",       dec_ctx->height);
+            print_int("has_b_frames", dec_ctx->has_b_frames);
+            sar = av_guess_sample_aspect_ratio(fmt_ctx, stream, NULL);
+            if (sar.den) {
+                print_q("sample_aspect_ratio", sar, ':');
+                av_reduce(&dar.num, &dar.den,
+                          dec_ctx->width  * sar.num,
+                          dec_ctx->height * sar.den,
+                          1024*1024);
+                print_q("display_aspect_ratio", dar, ':');
+            } else {
+                print_str_opt("sample_aspect_ratio", "N/A");
+                print_str_opt("display_aspect_ratio", "N/A");
+            }
+            s = av_get_pix_fmt_name(dec_ctx->pix_fmt);
+            if (s) print_str    ("pix_fmt", s);
+            else   print_str_opt("pix_fmt", "unknown");
+            print_int("level",   dec_ctx->level);
+            if (dec_ctx->timecode_frame_start >= 0) {
+                char tcbuf[AV_TIMECODE_STR_SIZE];
+                av_timecode_make_mpeg_tc_string(tcbuf, dec_ctx->timecode_frame_start);
+                print_str("timecode", tcbuf);
+            } else {
+                print_str_opt("timecode", "N/A");
+            }
+            break;
+
+        case AVMEDIA_TYPE_AUDIO:
+            s = av_get_sample_fmt_name(dec_ctx->sample_fmt);
+            if (s) print_str    ("sample_fmt", s);
+            else   print_str_opt("sample_fmt", "unknown");
+            print_val("sample_rate",     dec_ctx->sample_rate, unit_hertz_str);
+            print_int("channels",        dec_ctx->channels);
+            print_int("bits_per_sample", av_get_bits_per_sample(dec_ctx->codec_id));
+            break;
+        }
+    } else {
+        print_str_opt("codec_type", "unknown");
+    }
+    if (dec_ctx->codec && dec_ctx->codec->priv_class && show_private_data) {
+        const AVOption *opt = NULL;
+        while (opt = av_opt_next(dec_ctx->priv_data,opt)) {
+            uint8_t *str;
+            if (opt->flags) continue;
+            if (av_opt_get(dec_ctx->priv_data, opt->name, 0, &str) >= 0) {
+                print_str(opt->name, str);
+                av_free(str);
+            }
+        }
+    }
+
+    if (fmt_ctx->iformat->flags & AVFMT_SHOW_IDS) print_fmt    ("id", "0x%x", stream->id);
+    else                                          print_str_opt("id", "N/A");
+    print_q("r_frame_rate",   stream->r_frame_rate,   '/');
+    print_q("avg_frame_rate", stream->avg_frame_rate, '/');
+    print_q("time_base",      stream->time_base,      '/');
+    print_ts  ("start_pts",   stream->start_time);
+    print_time("start_time",  stream->start_time, &stream->time_base);
+    print_ts  ("duration_ts", stream->duration);
+    print_time("duration",    stream->duration, &stream->time_base);
+    if (dec_ctx->bit_rate > 0) print_val    ("bit_rate", dec_ctx->bit_rate, unit_bit_per_second_str);
+    else                       print_str_opt("bit_rate", "N/A");
+    if (stream->nb_frames) print_fmt    ("nb_frames", "%"PRId64, stream->nb_frames);
+    else                   print_str_opt("nb_frames", "N/A");
+    if (nb_streams_frames[stream_idx])  print_fmt    ("nb_read_frames", "%"PRIu64, nb_streams_frames[stream_idx]);
+    else                                print_str_opt("nb_read_frames", "N/A");
+    if (nb_streams_packets[stream_idx]) print_fmt    ("nb_read_packets", "%"PRIu64, nb_streams_packets[stream_idx]);
+    else                                print_str_opt("nb_read_packets", "N/A");
+    if (do_show_data)
+        writer_print_data(w, "extradata", dec_ctx->extradata,
+                                          dec_ctx->extradata_size);
+
+    /* Print disposition information */
+#define PRINT_DISPOSITION(flagname, name) do {                                \
+        print_int(name, !!(stream->disposition & AV_DISPOSITION_##flagname)); \
+    } while (0)
+
+    writer_print_section_header(w, SECTION_ID_STREAM_DISPOSITION);
+    PRINT_DISPOSITION(DEFAULT,          "default");
+    PRINT_DISPOSITION(DUB,              "dub");
+    PRINT_DISPOSITION(ORIGINAL,         "original");
+    PRINT_DISPOSITION(COMMENT,          "comment");
+    PRINT_DISPOSITION(LYRICS,           "lyrics");
+    PRINT_DISPOSITION(KARAOKE,          "karaoke");
+    PRINT_DISPOSITION(FORCED,           "forced");
+    PRINT_DISPOSITION(HEARING_IMPAIRED, "hearing_impaired");
+    PRINT_DISPOSITION(VISUAL_IMPAIRED,  "visual_impaired");
+    PRINT_DISPOSITION(CLEAN_EFFECTS,    "clean_effects");
+    PRINT_DISPOSITION(ATTACHED_PIC,     "attached_pic");
+    writer_print_section_footer(w);
+
+    show_tags(w, stream->metadata, SECTION_ID_STREAM_TAGS);
+
+    writer_print_section_footer(w);
+    av_bprint_finalize(&pbuf, NULL);
+    fflush(stdout);
+}
+
+static void show_streams(WriterContext *w, AVFormatContext *fmt_ctx)
+{
+    int i;
+    writer_print_section_header(w, SECTION_ID_STREAMS);
+    for (i = 0; i < fmt_ctx->nb_streams; i++)
+        if (selected_streams[i])
+            show_stream(w, fmt_ctx, i);
+    writer_print_section_footer(w);
+}
+
+static void show_format(WriterContext *w, AVFormatContext *fmt_ctx)
+{
+    char val_str[128];
+    int64_t size = fmt_ctx->pb ? avio_size(fmt_ctx->pb) : -1;
+
+    writer_print_section_header(w, SECTION_ID_FORMAT);
+    print_str("filename",         fmt_ctx->filename);
+    print_int("nb_streams",       fmt_ctx->nb_streams);
+    print_str("format_name",      fmt_ctx->iformat->name);
+    if (!do_bitexact) {
+        if (fmt_ctx->iformat->long_name) print_str    ("format_long_name", fmt_ctx->iformat->long_name);
+        else                             print_str_opt("format_long_name", "unknown");
+    }
+    print_time("start_time",      fmt_ctx->start_time, &AV_TIME_BASE_Q);
+    print_time("duration",        fmt_ctx->duration,   &AV_TIME_BASE_Q);
+    if (size >= 0) print_val    ("size", size, unit_byte_str);
+    else           print_str_opt("size", "N/A");
+    if (fmt_ctx->bit_rate > 0) print_val    ("bit_rate", fmt_ctx->bit_rate, unit_bit_per_second_str);
+    else                       print_str_opt("bit_rate", "N/A");
+    show_tags(w, fmt_ctx->metadata, SECTION_ID_FORMAT_TAGS);
+
+    writer_print_section_footer(w);
+    fflush(stdout);
+}
+
+static void show_error(WriterContext *w, int err)
+{
+    char errbuf[128];
+    const char *errbuf_ptr = errbuf;
+
+    if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
+        errbuf_ptr = strerror(AVUNERROR(err));
+
+    writer_print_section_header(w, SECTION_ID_ERROR);
+    print_int("code", err);
+    print_str("string", errbuf_ptr);
+    writer_print_section_footer(w);
+}
+
+static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename)
+{
+    int err, i;
+    AVFormatContext *fmt_ctx = NULL;
+    AVDictionaryEntry *t;
+
+    if ((err = avformat_open_input(&fmt_ctx, filename,
+                                   iformat, &format_opts)) < 0) {
+        print_error(filename, err);
+        return err;
+    }
+    if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
+        av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
+        return AVERROR_OPTION_NOT_FOUND;
+    }
+
+
+    /* fill the streams in the format context */
+    if ((err = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
+        print_error(filename, err);
+        return err;
+    }
+
+    av_dump_format(fmt_ctx, 0, filename, 0);
+
+    /* bind a decoder to each input stream */
+    for (i = 0; i < fmt_ctx->nb_streams; i++) {
+        AVStream *stream = fmt_ctx->streams[i];
+        AVCodec *codec;
+
+        if (stream->codec->codec_id == AV_CODEC_ID_PROBE) {
+            av_log(NULL, AV_LOG_ERROR,
+                   "Failed to probe codec for input stream %d\n",
+                    stream->index);
+        } else if (!(codec = avcodec_find_decoder(stream->codec->codec_id))) {
+            av_log(NULL, AV_LOG_ERROR,
+                    "Unsupported codec with id %d for input stream %d\n",
+                    stream->codec->codec_id, stream->index);
+        } else if (avcodec_open2(stream->codec, codec, NULL) < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Error while opening codec for input stream %d\n",
+                   stream->index);
+        }
+    }
+
+    *fmt_ctx_ptr = fmt_ctx;
+    return 0;
+}
+
+static void close_input_file(AVFormatContext **ctx_ptr)
+{
+    int i;
+    AVFormatContext *fmt_ctx = *ctx_ptr;
+
+    /* close decoder for each stream */
+    for (i = 0; i < fmt_ctx->nb_streams; i++)
+        if (fmt_ctx->streams[i]->codec->codec_id != AV_CODEC_ID_NONE)
+            avcodec_close(fmt_ctx->streams[i]->codec);
+
+    avformat_close_input(ctx_ptr);
+}
+
+static int probe_file(WriterContext *wctx, const char *filename)
+{
+    AVFormatContext *fmt_ctx;
+    int ret, i;
+    int section_id;
+
+    do_read_frames = do_show_frames || do_count_frames;
+    do_read_packets = do_show_packets || do_count_packets;
+
+    ret = open_input_file(&fmt_ctx, filename);
+    if (ret >= 0) {
+        nb_streams_frames  = av_calloc(fmt_ctx->nb_streams, sizeof(*nb_streams_frames));
+        nb_streams_packets = av_calloc(fmt_ctx->nb_streams, sizeof(*nb_streams_packets));
+        selected_streams   = av_calloc(fmt_ctx->nb_streams, sizeof(*selected_streams));
+
+        for (i = 0; i < fmt_ctx->nb_streams; i++) {
+            if (stream_specifier) {
+                ret = avformat_match_stream_specifier(fmt_ctx,
+                                                      fmt_ctx->streams[i],
+                                                      stream_specifier);
+                if (ret < 0)
+                    goto end;
+                else
+                    selected_streams[i] = ret;
+            } else {
+                selected_streams[i] = 1;
+            }
+        }
+
+        if (do_read_frames || do_read_packets) {
+            if (do_show_frames && do_show_packets &&
+                wctx->writer->flags & WRITER_FLAG_PUT_PACKETS_AND_FRAMES_IN_SAME_CHAPTER)
+                section_id = SECTION_ID_PACKETS_AND_FRAMES;
+            else if (do_show_packets && !do_show_frames)
+                section_id = SECTION_ID_PACKETS;
+            else // (!do_show_packets && do_show_frames)
+                section_id = SECTION_ID_FRAMES;
+            if (do_show_frames || do_show_packets)
+                writer_print_section_header(wctx, section_id);
+            read_packets(wctx, fmt_ctx);
+            if (do_show_frames || do_show_packets)
+                writer_print_section_footer(wctx);
+        }
+        if (do_show_streams)
+            show_streams(wctx, fmt_ctx);
+        if (do_show_format)
+            show_format(wctx, fmt_ctx);
+
+    end:
+        close_input_file(&fmt_ctx);
+        av_freep(&nb_streams_frames);
+        av_freep(&nb_streams_packets);
+        av_freep(&selected_streams);
+    }
+    return ret;
+}
+
+static void show_usage(void)
+{
+    av_log(NULL, AV_LOG_INFO, "Simple multimedia streams analyzer\n");
+    av_log(NULL, AV_LOG_INFO, "usage: %s [OPTIONS] [INPUT_FILE]\n", program_name);
+    av_log(NULL, AV_LOG_INFO, "\n");
+}
+
+static void ffprobe_show_program_version(WriterContext *w)
+{
+    AVBPrint pbuf;
+    av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
+
+    writer_print_section_header(w, SECTION_ID_PROGRAM_VERSION);
+    print_str("version", FFMPEG_VERSION);
+    print_fmt("copyright", "Copyright (c) %d-%d the FFmpeg developers",
+              program_birth_year, this_year);
+    print_str("build_date", __DATE__);
+    print_str("build_time", __TIME__);
+    print_str("compiler_ident", CC_IDENT);
+    print_str("configuration", FFMPEG_CONFIGURATION);
+    writer_print_section_footer(w);
+
+    av_bprint_finalize(&pbuf, NULL);
+}
+
+#define SHOW_LIB_VERSION(libname, LIBNAME)                              \
+    do {                                                                \
+        if (CONFIG_##LIBNAME) {                                         \
+            unsigned int version = libname##_version();                 \
+            writer_print_section_header(w, SECTION_ID_LIBRARY_VERSION); \
+            print_str("name",    "lib" #libname);                       \
+            print_int("major",   LIB##LIBNAME##_VERSION_MAJOR);         \
+            print_int("minor",   LIB##LIBNAME##_VERSION_MINOR);         \
+            print_int("micro",   LIB##LIBNAME##_VERSION_MICRO);         \
+            print_int("version", version);                              \
+            print_str("ident",   LIB##LIBNAME##_IDENT);                 \
+            writer_print_section_footer(w);                             \
+        }                                                               \
+    } while (0)
+
+static void ffprobe_show_library_versions(WriterContext *w)
+{
+    writer_print_section_header(w, SECTION_ID_LIBRARY_VERSIONS);
+    SHOW_LIB_VERSION(avutil,     AVUTIL);
+    SHOW_LIB_VERSION(avcodec,    AVCODEC);
+    SHOW_LIB_VERSION(avformat,   AVFORMAT);
+    SHOW_LIB_VERSION(avdevice,   AVDEVICE);
+    SHOW_LIB_VERSION(avfilter,   AVFILTER);
+    SHOW_LIB_VERSION(swscale,    SWSCALE);
+    SHOW_LIB_VERSION(swresample, SWRESAMPLE);
+    SHOW_LIB_VERSION(postproc,   POSTPROC);
+    writer_print_section_footer(w);
+}
+
+static int opt_format(void *optctx, const char *opt, const char *arg)
+{
+    iformat = av_find_input_format(arg);
+    if (!iformat) {
+        av_log(NULL, AV_LOG_ERROR, "Unknown input format: %s\n", arg);
+        return AVERROR(EINVAL);
+    }
+    return 0;
+}
+
+static int opt_show_format_entry(void *optctx, const char *opt, const char *arg)
+{
+    do_show_format = 1;
+    av_dict_set(&fmt_entries_to_show, arg, "", 0);
+    return 0;
+}
+
+static void opt_input_file(void *optctx, const char *arg)
+{
+    if (input_filename) {
+        av_log(NULL, AV_LOG_ERROR,
+                "Argument '%s' provided as input filename, but '%s' was already specified.\n",
+                arg, input_filename);
+        exit(1);
+    }
+    if (!strcmp(arg, "-"))
+        arg = "pipe:";
+    input_filename = arg;
+}
+
+static int opt_input_file_i(void *optctx, const char *opt, const char *arg)
+{
+    opt_input_file(optctx, arg);
+    return 0;
+}
+
+void show_help_default(const char *opt, const char *arg)
+{
+    av_log_set_callback(log_callback_help);
+    show_usage();
+    show_help_options(options, "Main options:", 0, 0, 0);
+    printf("\n");
+
+    show_help_children(avformat_get_class(), AV_OPT_FLAG_DECODING_PARAM);
+}
+
+static int opt_pretty(void *optctx, const char *opt, const char *arg)
+{
+    show_value_unit              = 1;
+    use_value_prefix             = 1;
+    use_byte_value_binary_prefix = 1;
+    use_value_sexagesimal_format = 1;
+    return 0;
+}
+
+static int opt_show_versions(const char *opt, const char *arg)
+{
+    do_show_program_version  = 1;
+    do_show_library_versions = 1;
+    return 0;
+}
+
+static const OptionDef real_options[] = {
+#include "cmdutils_common_opts.h"
+    { "f", HAS_ARG, {.func_arg = opt_format}, "force format", "format" },
+    { "unit", OPT_BOOL, {&show_value_unit}, "show unit of the displayed values" },
+    { "prefix", OPT_BOOL, {&use_value_prefix}, "use SI prefixes for the displayed values" },
+    { "byte_binary_prefix", OPT_BOOL, {&use_byte_value_binary_prefix},
+      "use binary prefixes for byte units" },
+    { "sexagesimal", OPT_BOOL,  {&use_value_sexagesimal_format},
+      "use sexagesimal format HOURS:MM:SS.MICROSECONDS for time units" },
+    { "pretty", 0, {.func_arg = opt_pretty},
+      "prettify the format of displayed values, make it more human readable" },
+    { "print_format", OPT_STRING | HAS_ARG, {(void*)&print_format},
+      "set the output printing format (available formats are: default, compact, csv, flat, ini, json, xml)", "format" },
+    { "of", OPT_STRING | HAS_ARG, {(void*)&print_format}, "alias for -print_format", "format" },
+    { "select_streams", OPT_STRING | HAS_ARG, {(void*)&stream_specifier}, "select the specified streams", "stream_specifier" },
+    { "show_data",    OPT_BOOL, {(void*)&do_show_data}, "show packets data" },
+    { "show_error",   OPT_BOOL, {(void*)&do_show_error} ,  "show probing error" },
+    { "show_format",  OPT_BOOL, {&do_show_format} , "show format/container info" },
+    { "show_frames",  OPT_BOOL, {(void*)&do_show_frames} , "show frames info" },
+    { "show_format_entry", HAS_ARG, {.func_arg = opt_show_format_entry},
+      "show a particular entry from the format/container info", "entry" },
+    { "show_packets", OPT_BOOL, {&do_show_packets}, "show packets info" },
+    { "show_streams", OPT_BOOL, {&do_show_streams}, "show streams info" },
+    { "count_frames", OPT_BOOL, {(void*)&do_count_frames}, "count the number of frames per stream" },
+    { "count_packets", OPT_BOOL, {(void*)&do_count_packets}, "count the number of packets per stream" },
+    { "show_program_version",  OPT_BOOL, {(void*)&do_show_program_version},  "show ffprobe version" },
+    { "show_library_versions", OPT_BOOL, {(void*)&do_show_library_versions}, "show library versions" },
+    { "show_versions",         0, {(void*)&opt_show_versions}, "show program and library versions" },
+    { "show_private_data", OPT_BOOL, {(void*)&show_private_data}, "show private data" },
+    { "private",           OPT_BOOL, {(void*)&show_private_data}, "same as show_private_data" },
+    { "bitexact", OPT_BOOL, {&do_bitexact}, "force bitexact output" },
+    { "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {.func_arg = opt_default}, "generic catch all option", "" },
+    { "i", HAS_ARG, {.func_arg = opt_input_file_i}, "read specified file", "input_file"},
+    { NULL, },
+};
+
+int main(int argc, char **argv)
+{
+    const Writer *w;
+    WriterContext *wctx;
+    char *buf;
+    char *w_name = NULL, *w_args = NULL;
+    int ret;
+
+    av_log_set_flags(AV_LOG_SKIP_REPEATED);
+    atexit(exit_program);
+
+    options = real_options;
+    parse_loglevel(argc, argv, options);
+    av_register_all();
+    avformat_network_init();
+    init_opts();
+#if CONFIG_AVDEVICE
+    avdevice_register_all();
+#endif
+
+    show_banner(argc, argv, options);
+    parse_options(NULL, argc, argv, options, opt_input_file);
+
+    if (do_bitexact && (do_show_program_version || do_show_library_versions)) {
+        av_log(NULL, AV_LOG_ERROR,
+               "-bitexact and -show_program_version or -show_library_versions "
+               "options are incompatible\n");
+        ret = AVERROR(EINVAL);
+        goto end;
+    }
+
+    writer_register_all();
+
+    if (!print_format)
+        print_format = av_strdup("default");
+    if (!print_format) {
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+    w_name = av_strtok(print_format, "=", &buf);
+    w_args = buf;
+
+    w = writer_get_by_name(w_name);
+    if (!w) {
+        av_log(NULL, AV_LOG_ERROR, "Unknown output format with name '%s'\n", w_name);
+        ret = AVERROR(EINVAL);
+        goto end;
+    }
+
+    if ((ret = writer_open(&wctx, w, w_args,
+                           sections, FF_ARRAY_ELEMS(sections))) >= 0) {
+        writer_print_section_header(wctx, SECTION_ID_ROOT);
+
+        if (do_show_program_version)
+            ffprobe_show_program_version(wctx);
+        if (do_show_library_versions)
+            ffprobe_show_library_versions(wctx);
+
+        if (!input_filename &&
+            ((do_show_format || do_show_streams || do_show_packets || do_show_error) ||
+             (!do_show_program_version && !do_show_library_versions))) {
+            show_usage();
+            av_log(NULL, AV_LOG_ERROR, "You have to specify one input file.\n");
+            av_log(NULL, AV_LOG_ERROR, "Use -h to get full help or, even better, run 'man %s'.\n", program_name);
+            ret = AVERROR(EINVAL);
+        } else if (input_filename) {
+            ret = probe_file(wctx, input_filename);
+            if (ret < 0 && do_show_error)
+                show_error(wctx, ret);
+        }
+
+        writer_print_section_footer(wctx);
+        writer_close(&wctx);
+    }
+
+end:
+    av_freep(&print_format);
+
+    uninit_opts();
+    av_dict_free(&fmt_entries_to_show);
+
+    avformat_network_deinit();
+
+    return ret;
+}
diff --git a/ffserver.c b/ffserver.c
new file mode 100644
index 0000000..4dd0ae2
--- /dev/null
+++ b/ffserver.c
@@ -0,0 +1,4762 @@
+/*
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * multiple format streaming server based on the FFmpeg libraries
+ */
+
+#include "config.h"
+#if !HAVE_CLOSESOCKET
+#define closesocket close
+#endif
+#include <string.h>
+#include <stdlib.h>
+#include "libavformat/avformat.h"
+// FIXME those are internal headers, ffserver _really_ shouldn't use them
+#include "libavformat/ffm.h"
+#include "libavformat/network.h"
+#include "libavformat/os_support.h"
+#include "libavformat/rtpdec.h"
+#include "libavformat/rtsp.h"
+#include "libavformat/avio_internal.h"
+#include "libavformat/internal.h"
+#include "libavformat/url.h"
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/lfg.h"
+#include "libavutil/dict.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/random_seed.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/time.h"
+
+#include <stdarg.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#if HAVE_POLL_H
+#include <poll.h>
+#endif
+#include <errno.h>
+#include <time.h>
+#include <sys/wait.h>
+#include <signal.h>
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include "cmdutils.h"
+
+const char program_name[] = "ffserver";
+const int program_birth_year = 2000;
+
+static const OptionDef options[];
+
+enum HTTPState {
+    HTTPSTATE_WAIT_REQUEST,
+    HTTPSTATE_SEND_HEADER,
+    HTTPSTATE_SEND_DATA_HEADER,
+    HTTPSTATE_SEND_DATA,          /* sending TCP or UDP data */
+    HTTPSTATE_SEND_DATA_TRAILER,
+    HTTPSTATE_RECEIVE_DATA,
+    HTTPSTATE_WAIT_FEED,          /* wait for data from the feed */
+    HTTPSTATE_READY,
+
+    RTSPSTATE_WAIT_REQUEST,
+    RTSPSTATE_SEND_REPLY,
+    RTSPSTATE_SEND_PACKET,
+};
+
+static const char *http_state[] = {
+    "HTTP_WAIT_REQUEST",
+    "HTTP_SEND_HEADER",
+
+    "SEND_DATA_HEADER",
+    "SEND_DATA",
+    "SEND_DATA_TRAILER",
+    "RECEIVE_DATA",
+    "WAIT_FEED",
+    "READY",
+
+    "RTSP_WAIT_REQUEST",
+    "RTSP_SEND_REPLY",
+    "RTSP_SEND_PACKET",
+};
+
+#define MAX_STREAMS 20
+
+#define IOBUFFER_INIT_SIZE 8192
+
+/* timeouts are in ms */
+#define HTTP_REQUEST_TIMEOUT (15 * 1000)
+#define RTSP_REQUEST_TIMEOUT (3600 * 24 * 1000)
+
+#define SYNC_TIMEOUT (10 * 1000)
+
+typedef struct RTSPActionServerSetup {
+    uint32_t ipaddr;
+    char transport_option[512];
+} RTSPActionServerSetup;
+
+typedef struct {
+    int64_t count1, count2;
+    int64_t time1, time2;
+} DataRateData;
+
+/* context associated with one connection */
+typedef struct HTTPContext {
+    enum HTTPState state;
+    int fd; /* socket file descriptor */
+    struct sockaddr_in from_addr; /* origin */
+    struct pollfd *poll_entry; /* used when polling */
+    int64_t timeout;
+    uint8_t *buffer_ptr, *buffer_end;
+    int http_error;
+    int post;
+    int chunked_encoding;
+    int chunk_size;               /* 0 if it needs to be read */
+    struct HTTPContext *next;
+    int got_key_frame; /* stream 0 => 1, stream 1 => 2, stream 2=> 4 */
+    int64_t data_count;
+    /* feed input */
+    int feed_fd;
+    /* input format handling */
+    AVFormatContext *fmt_in;
+    int64_t start_time;            /* In milliseconds - this wraps fairly often */
+    int64_t first_pts;            /* initial pts value */
+    int64_t cur_pts;             /* current pts value from the stream in us */
+    int64_t cur_frame_duration;  /* duration of the current frame in us */
+    int cur_frame_bytes;       /* output frame size, needed to compute
+                                  the time at which we send each
+                                  packet */
+    int pts_stream_index;        /* stream we choose as clock reference */
+    int64_t cur_clock;           /* current clock reference value in us */
+    /* output format handling */
+    struct FFStream *stream;
+    /* -1 is invalid stream */
+    int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
+    int switch_feed_streams[MAX_STREAMS]; /* index of streams in the feed */
+    int switch_pending;
+    AVFormatContext fmt_ctx; /* instance of FFStream for one user */
+    int last_packet_sent; /* true if last data packet was sent */
+    int suppress_log;
+    DataRateData datarate;
+    int wmp_client_id;
+    char protocol[16];
+    char method[16];
+    char url[128];
+    int buffer_size;
+    uint8_t *buffer;
+    int is_packetized; /* if true, the stream is packetized */
+    int packet_stream_index; /* current stream for output in state machine */
+
+    /* RTSP state specific */
+    uint8_t *pb_buffer; /* XXX: use that in all the code */
+    AVIOContext *pb;
+    int seq; /* RTSP sequence number */
+
+    /* RTP state specific */
+    enum RTSPLowerTransport rtp_protocol;
+    char session_id[32]; /* session id */
+    AVFormatContext *rtp_ctx[MAX_STREAMS];
+
+    /* RTP/UDP specific */
+    URLContext *rtp_handles[MAX_STREAMS];
+
+    /* RTP/TCP specific */
+    struct HTTPContext *rtsp_c;
+    uint8_t *packet_buffer, *packet_buffer_ptr, *packet_buffer_end;
+} HTTPContext;
+
+/* each generated stream is described here */
+enum StreamType {
+    STREAM_TYPE_LIVE,
+    STREAM_TYPE_STATUS,
+    STREAM_TYPE_REDIRECT,
+};
+
+enum IPAddressAction {
+    IP_ALLOW = 1,
+    IP_DENY,
+};
+
+typedef struct IPAddressACL {
+    struct IPAddressACL *next;
+    enum IPAddressAction action;
+    /* These are in host order */
+    struct in_addr first;
+    struct in_addr last;
+} IPAddressACL;
+
+/* description of each stream of the ffserver.conf file */
+typedef struct FFStream {
+    enum StreamType stream_type;
+    char filename[1024];     /* stream filename */
+    struct FFStream *feed;   /* feed we are using (can be null if
+                                coming from file) */
+    AVDictionary *in_opts;   /* input parameters */
+    AVInputFormat *ifmt;       /* if non NULL, force input format */
+    AVOutputFormat *fmt;
+    IPAddressACL *acl;
+    char dynamic_acl[1024];
+    int nb_streams;
+    int prebuffer;      /* Number of millseconds early to start */
+    int64_t max_time;      /* Number of milliseconds to run */
+    int send_on_key;
+    AVStream *streams[MAX_STREAMS];
+    int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
+    char feed_filename[1024]; /* file name of the feed storage, or
+                                 input file name for a stream */
+    char author[512];
+    char title[512];
+    char copyright[512];
+    char comment[512];
+    pid_t pid;  /* Of ffmpeg process */
+    time_t pid_start;  /* Of ffmpeg process */
+    char **child_argv;
+    struct FFStream *next;
+    unsigned bandwidth; /* bandwidth, in kbits/s */
+    /* RTSP options */
+    char *rtsp_option;
+    /* multicast specific */
+    int is_multicast;
+    struct in_addr multicast_ip;
+    int multicast_port; /* first port used for multicast */
+    int multicast_ttl;
+    int loop; /* if true, send the stream in loops (only meaningful if file) */
+
+    /* feed specific */
+    int feed_opened;     /* true if someone is writing to the feed */
+    int is_feed;         /* true if it is a feed */
+    int readonly;        /* True if writing is prohibited to the file */
+    int truncate;        /* True if feeder connection truncate the feed file */
+    int conns_served;
+    int64_t bytes_served;
+    int64_t feed_max_size;      /* maximum storage size, zero means unlimited */
+    int64_t feed_write_index;   /* current write position in feed (it wraps around) */
+    int64_t feed_size;          /* current size of feed */
+    struct FFStream *next_feed;
+} FFStream;
+
+typedef struct FeedData {
+    long long data_count;
+    float avg_frame_size;   /* frame size averaged over last frames with exponential mean */
+} FeedData;
+
+static struct sockaddr_in my_http_addr;
+static struct sockaddr_in my_rtsp_addr;
+
+static char logfilename[1024];
+static HTTPContext *first_http_ctx;
+static FFStream *first_feed;   /* contains only feeds */
+static FFStream *first_stream; /* contains all streams, including feeds */
+
+static void new_connection(int server_fd, int is_rtsp);
+static void close_connection(HTTPContext *c);
+
+/* HTTP handling */
+static int handle_connection(HTTPContext *c);
+static int http_parse_request(HTTPContext *c);
+static int http_send_data(HTTPContext *c);
+static void compute_status(HTTPContext *c);
+static int open_input_stream(HTTPContext *c, const char *info);
+static int http_start_receive_data(HTTPContext *c);
+static int http_receive_data(HTTPContext *c);
+
+/* RTSP handling */
+static int rtsp_parse_request(HTTPContext *c);
+static void rtsp_cmd_describe(HTTPContext *c, const char *url);
+static void rtsp_cmd_options(HTTPContext *c, const char *url);
+static void rtsp_cmd_setup(HTTPContext *c, const char *url, RTSPMessageHeader *h);
+static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h);
+static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h);
+static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h);
+
+/* SDP handling */
+static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
+                                   struct in_addr my_ip);
+
+/* RTP handling */
+static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
+                                       FFStream *stream, const char *session_id,
+                                       enum RTSPLowerTransport rtp_protocol);
+static int rtp_new_av_stream(HTTPContext *c,
+                             int stream_index, struct sockaddr_in *dest_addr,
+                             HTTPContext *rtsp_c);
+
+static const char *my_program_name;
+static const char *my_program_dir;
+
+static const char *config_filename = "/etc/ffserver.conf";
+
+static int ffserver_debug;
+static int ffserver_daemon;
+static int no_launch;
+static int need_to_start_children;
+
+/* maximum number of simultaneous HTTP connections */
+static unsigned int nb_max_http_connections = 2000;
+static unsigned int nb_max_connections = 5;
+static unsigned int nb_connections;
+
+static uint64_t max_bandwidth = 1000;
+static uint64_t current_bandwidth;
+
+static int64_t cur_time;           // Making this global saves on passing it around everywhere
+
+static AVLFG random_state;
+
+static FILE *logfile = NULL;
+
+/* FIXME: make ffserver work with IPv6 */
+/* resolve host with also IP address parsing */
+static int resolve_host(struct in_addr *sin_addr, const char *hostname)
+{
+
+    if (!ff_inet_aton(hostname, sin_addr)) {
+#if HAVE_GETADDRINFO
+        struct addrinfo *ai, *cur;
+        struct addrinfo hints = { 0 };
+        hints.ai_family = AF_INET;
+        if (getaddrinfo(hostname, NULL, &hints, &ai))
+            return -1;
+        /* getaddrinfo returns a linked list of addrinfo structs.
+         * Even if we set ai_family = AF_INET above, make sure
+         * that the returned one actually is of the correct type. */
+        for (cur = ai; cur; cur = cur->ai_next) {
+            if (cur->ai_family == AF_INET) {
+                *sin_addr = ((struct sockaddr_in *)cur->ai_addr)->sin_addr;
+                freeaddrinfo(ai);
+                return 0;
+            }
+        }
+        freeaddrinfo(ai);
+        return -1;
+#else
+        struct hostent *hp;
+        hp = gethostbyname(hostname);
+        if (!hp)
+            return -1;
+        memcpy(sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
+#endif
+    }
+    return 0;
+}
+
+static char *ctime1(char *buf2)
+{
+    time_t ti;
+    char *p;
+
+    ti = time(NULL);
+    p = ctime(&ti);
+    strcpy(buf2, p);
+    p = buf2 + strlen(p) - 1;
+    if (*p == '\n')
+        *p = '\0';
+    return buf2;
+}
+
+static void http_vlog(const char *fmt, va_list vargs)
+{
+    static int print_prefix = 1;
+    if (logfile) {
+        if (print_prefix) {
+            char buf[32];
+            ctime1(buf);
+            fprintf(logfile, "%s ", buf);
+        }
+        print_prefix = strstr(fmt, "\n") != NULL;
+        vfprintf(logfile, fmt, vargs);
+        fflush(logfile);
+    }
+}
+
+#ifdef __GNUC__
+__attribute__ ((format (printf, 1, 2)))
+#endif
+static void http_log(const char *fmt, ...)
+{
+    va_list vargs;
+    va_start(vargs, fmt);
+    http_vlog(fmt, vargs);
+    va_end(vargs);
+}
+
+static void http_av_log(void *ptr, int level, const char *fmt, va_list vargs)
+{
+    static int print_prefix = 1;
+    AVClass *avc = ptr ? *(AVClass**)ptr : NULL;
+    if (level > av_log_get_level())
+        return;
+    if (print_prefix && avc)
+        http_log("[%s @ %p]", avc->item_name(ptr), ptr);
+    print_prefix = strstr(fmt, "\n") != NULL;
+    http_vlog(fmt, vargs);
+}
+
+static void log_connection(HTTPContext *c)
+{
+    if (c->suppress_log)
+        return;
+
+    http_log("%s - - [%s] \"%s %s\" %d %"PRId64"\n",
+             inet_ntoa(c->from_addr.sin_addr), c->method, c->url,
+             c->protocol, (c->http_error ? c->http_error : 200), c->data_count);
+}
+
+static void update_datarate(DataRateData *drd, int64_t count)
+{
+    if (!drd->time1 && !drd->count1) {
+        drd->time1 = drd->time2 = cur_time;
+        drd->count1 = drd->count2 = count;
+    } else if (cur_time - drd->time2 > 5000) {
+        drd->time1 = drd->time2;
+        drd->count1 = drd->count2;
+        drd->time2 = cur_time;
+        drd->count2 = count;
+    }
+}
+
+/* In bytes per second */
+static int compute_datarate(DataRateData *drd, int64_t count)
+{
+    if (cur_time == drd->time1)
+        return 0;
+
+    return ((count - drd->count1) * 1000) / (cur_time - drd->time1);
+}
+
+
+static void start_children(FFStream *feed)
+{
+    if (no_launch)
+        return;
+
+    for (; feed; feed = feed->next) {
+        if (feed->child_argv && !feed->pid) {
+            feed->pid_start = time(0);
+
+            feed->pid = fork();
+
+            if (feed->pid < 0) {
+                http_log("Unable to create children\n");
+                exit(1);
+            }
+            if (!feed->pid) {
+                /* In child */
+                char pathname[1024];
+                char *slash;
+                int i;
+
+                av_strlcpy(pathname, my_program_name, sizeof(pathname));
+
+                slash = strrchr(pathname, '/');
+                if (!slash)
+                    slash = pathname;
+                else
+                    slash++;
+                strcpy(slash, "ffmpeg");
+
+                http_log("Launch command line: ");
+                http_log("%s ", pathname);
+                for (i = 1; feed->child_argv[i] && feed->child_argv[i][0]; i++)
+                    http_log("%s ", feed->child_argv[i]);
+                http_log("\n");
+
+                for (i = 3; i < 256; i++)
+                    close(i);
+
+                if (!ffserver_debug) {
+                    i = open("/dev/null", O_RDWR);
+                    if (i != -1) {
+                        dup2(i, 0);
+                        dup2(i, 1);
+                        dup2(i, 2);
+                        close(i);
+                    }
+                }
+
+                /* This is needed to make relative pathnames work */
+                if (chdir(my_program_dir) < 0) {
+                    http_log("chdir failed\n");
+                    exit(1);
+                }
+
+                signal(SIGPIPE, SIG_DFL);
+
+                execvp(pathname, feed->child_argv);
+
+                _exit(1);
+            }
+        }
+    }
+}
+
+/* open a listening socket */
+static int socket_open_listen(struct sockaddr_in *my_addr)
+{
+    int server_fd, tmp;
+
+    server_fd = socket(AF_INET,SOCK_STREAM,0);
+    if (server_fd < 0) {
+        perror ("socket");
+        return -1;
+    }
+
+    tmp = 1;
+    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp));
+
+    my_addr->sin_family = AF_INET;
+    if (bind (server_fd, (struct sockaddr *) my_addr, sizeof (*my_addr)) < 0) {
+        char bindmsg[32];
+        snprintf(bindmsg, sizeof(bindmsg), "bind(port %d)", ntohs(my_addr->sin_port));
+        perror (bindmsg);
+        closesocket(server_fd);
+        return -1;
+    }
+
+    if (listen (server_fd, 5) < 0) {
+        perror ("listen");
+        closesocket(server_fd);
+        return -1;
+    }
+    ff_socket_nonblock(server_fd, 1);
+
+    return server_fd;
+}
+
+/* start all multicast streams */
+static void start_multicast(void)
+{
+    FFStream *stream;
+    char session_id[32];
+    HTTPContext *rtp_c;
+    struct sockaddr_in dest_addr;
+    int default_port, stream_index;
+
+    default_port = 6000;
+    for(stream = first_stream; stream != NULL; stream = stream->next) {
+        if (stream->is_multicast) {
+            unsigned random0 = av_lfg_get(&random_state);
+            unsigned random1 = av_lfg_get(&random_state);
+            /* open the RTP connection */
+            snprintf(session_id, sizeof(session_id), "%08x%08x",
+                     random0, random1);
+
+            /* choose a port if none given */
+            if (stream->multicast_port == 0) {
+                stream->multicast_port = default_port;
+                default_port += 100;
+            }
+
+            dest_addr.sin_family = AF_INET;
+            dest_addr.sin_addr = stream->multicast_ip;
+            dest_addr.sin_port = htons(stream->multicast_port);
+
+            rtp_c = rtp_new_connection(&dest_addr, stream, session_id,
+                                       RTSP_LOWER_TRANSPORT_UDP_MULTICAST);
+            if (!rtp_c)
+                continue;
+
+            if (open_input_stream(rtp_c, "") < 0) {
+                http_log("Could not open input stream for stream '%s'\n",
+                         stream->filename);
+                continue;
+            }
+
+            /* open each RTP stream */
+            for(stream_index = 0; stream_index < stream->nb_streams;
+                stream_index++) {
+                dest_addr.sin_port = htons(stream->multicast_port +
+                                           2 * stream_index);
+                if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, NULL) < 0) {
+                    http_log("Could not open output stream '%s/streamid=%d'\n",
+                             stream->filename, stream_index);
+                    exit(1);
+                }
+            }
+
+            /* change state to send data */
+            rtp_c->state = HTTPSTATE_SEND_DATA;
+        }
+    }
+}
+
+/* main loop of the http server */
+static int http_server(void)
+{
+    int server_fd = 0, rtsp_server_fd = 0;
+    int ret, delay, delay1;
+    struct pollfd *poll_table, *poll_entry;
+    HTTPContext *c, *c_next;
+
+    if(!(poll_table = av_mallocz((nb_max_http_connections + 2)*sizeof(*poll_table)))) {
+        http_log("Impossible to allocate a poll table handling %d connections.\n", nb_max_http_connections);
+        return -1;
+    }
+
+    if (my_http_addr.sin_port) {
+        server_fd = socket_open_listen(&my_http_addr);
+        if (server_fd < 0)
+            return -1;
+    }
+
+    if (my_rtsp_addr.sin_port) {
+        rtsp_server_fd = socket_open_listen(&my_rtsp_addr);
+        if (rtsp_server_fd < 0)
+            return -1;
+    }
+
+    if (!rtsp_server_fd && !server_fd) {
+        http_log("HTTP and RTSP disabled.\n");
+        return -1;
+    }
+
+    http_log("FFserver started.\n");
+
+    start_children(first_feed);
+
+    start_multicast();
+
+    for(;;) {
+        poll_entry = poll_table;
+        if (server_fd) {
+            poll_entry->fd = server_fd;
+            poll_entry->events = POLLIN;
+            poll_entry++;
+        }
+        if (rtsp_server_fd) {
+            poll_entry->fd = rtsp_server_fd;
+            poll_entry->events = POLLIN;
+            poll_entry++;
+        }
+
+        /* wait for events on each HTTP handle */
+        c = first_http_ctx;
+        delay = 1000;
+        while (c != NULL) {
+            int fd;
+            fd = c->fd;
+            switch(c->state) {
+            case HTTPSTATE_SEND_HEADER:
+            case RTSPSTATE_SEND_REPLY:
+            case RTSPSTATE_SEND_PACKET:
+                c->poll_entry = poll_entry;
+                poll_entry->fd = fd;
+                poll_entry->events = POLLOUT;
+                poll_entry++;
+                break;
+            case HTTPSTATE_SEND_DATA_HEADER:
+            case HTTPSTATE_SEND_DATA:
+            case HTTPSTATE_SEND_DATA_TRAILER:
+                if (!c->is_packetized) {
+                    /* for TCP, we output as much as we can (may need to put a limit) */
+                    c->poll_entry = poll_entry;
+                    poll_entry->fd = fd;
+                    poll_entry->events = POLLOUT;
+                    poll_entry++;
+                } else {
+                    /* when ffserver is doing the timing, we work by
+                       looking at which packet need to be sent every
+                       10 ms */
+                    delay1 = 10; /* one tick wait XXX: 10 ms assumed */
+                    if (delay1 < delay)
+                        delay = delay1;
+                }
+                break;
+            case HTTPSTATE_WAIT_REQUEST:
+            case HTTPSTATE_RECEIVE_DATA:
+            case HTTPSTATE_WAIT_FEED:
+            case RTSPSTATE_WAIT_REQUEST:
+                /* need to catch errors */
+                c->poll_entry = poll_entry;
+                poll_entry->fd = fd;
+                poll_entry->events = POLLIN;/* Maybe this will work */
+                poll_entry++;
+                break;
+            default:
+                c->poll_entry = NULL;
+                break;
+            }
+            c = c->next;
+        }
+
+        /* wait for an event on one connection. We poll at least every
+           second to handle timeouts */
+        do {
+            ret = poll(poll_table, poll_entry - poll_table, delay);
+            if (ret < 0 && ff_neterrno() != AVERROR(EAGAIN) &&
+                ff_neterrno() != AVERROR(EINTR))
+                return -1;
+        } while (ret < 0);
+
+        cur_time = av_gettime() / 1000;
+
+        if (need_to_start_children) {
+            need_to_start_children = 0;
+            start_children(first_feed);
+        }
+
+        /* now handle the events */
+        for(c = first_http_ctx; c != NULL; c = c_next) {
+            c_next = c->next;
+            if (handle_connection(c) < 0) {
+                /* close and free the connection */
+                log_connection(c);
+                close_connection(c);
+            }
+        }
+
+        poll_entry = poll_table;
+        if (server_fd) {
+            /* new HTTP connection request ? */
+            if (poll_entry->revents & POLLIN)
+                new_connection(server_fd, 0);
+            poll_entry++;
+        }
+        if (rtsp_server_fd) {
+            /* new RTSP connection request ? */
+            if (poll_entry->revents & POLLIN)
+                new_connection(rtsp_server_fd, 1);
+        }
+    }
+}
+
+/* start waiting for a new HTTP/RTSP request */
+static void start_wait_request(HTTPContext *c, int is_rtsp)
+{
+    c->buffer_ptr = c->buffer;
+    c->buffer_end = c->buffer + c->buffer_size - 1; /* leave room for '\0' */
+
+    if (is_rtsp) {
+        c->timeout = cur_time + RTSP_REQUEST_TIMEOUT;
+        c->state = RTSPSTATE_WAIT_REQUEST;
+    } else {
+        c->timeout = cur_time + HTTP_REQUEST_TIMEOUT;
+        c->state = HTTPSTATE_WAIT_REQUEST;
+    }
+}
+
+static void http_send_too_busy_reply(int fd)
+{
+    char buffer[400];
+    int len = snprintf(buffer, sizeof(buffer),
+                       "HTTP/1.0 503 Server too busy\r\n"
+                       "Content-type: text/html\r\n"
+                       "\r\n"
+                       "<html><head><title>Too busy</title></head><body>\r\n"
+                       "<p>The server is too busy to serve your request at this time.</p>\r\n"
+                       "<p>The number of current connections is %d, and this exceeds the limit of %d.</p>\r\n"
+                       "</body></html>\r\n",
+                       nb_connections, nb_max_connections);
+    av_assert0(len < sizeof(buffer));
+    send(fd, buffer, len, 0);
+}
+
+
+static void new_connection(int server_fd, int is_rtsp)
+{
+    struct sockaddr_in from_addr;
+    int fd, len;
+    HTTPContext *c = NULL;
+
+    len = sizeof(from_addr);
+    fd = accept(server_fd, (struct sockaddr *)&from_addr,
+                &len);
+    if (fd < 0) {
+        http_log("error during accept %s\n", strerror(errno));
+        return;
+    }
+    ff_socket_nonblock(fd, 1);
+
+    if (nb_connections >= nb_max_connections) {
+        http_send_too_busy_reply(fd);
+        goto fail;
+    }
+
+    /* add a new connection */
+    c = av_mallocz(sizeof(HTTPContext));
+    if (!c)
+        goto fail;
+
+    c->fd = fd;
+    c->poll_entry = NULL;
+    c->from_addr = from_addr;
+    c->buffer_size = IOBUFFER_INIT_SIZE;
+    c->buffer = av_malloc(c->buffer_size);
+    if (!c->buffer)
+        goto fail;
+
+    c->next = first_http_ctx;
+    first_http_ctx = c;
+    nb_connections++;
+
+    start_wait_request(c, is_rtsp);
+
+    return;
+
+ fail:
+    if (c) {
+        av_free(c->buffer);
+        av_free(c);
+    }
+    closesocket(fd);
+}
+
+static void close_connection(HTTPContext *c)
+{
+    HTTPContext **cp, *c1;
+    int i, nb_streams;
+    AVFormatContext *ctx;
+    URLContext *h;
+    AVStream *st;
+
+    /* remove connection from list */
+    cp = &first_http_ctx;
+    while ((*cp) != NULL) {
+        c1 = *cp;
+        if (c1 == c)
+            *cp = c->next;
+        else
+            cp = &c1->next;
+    }
+
+    /* remove references, if any (XXX: do it faster) */
+    for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
+        if (c1->rtsp_c == c)
+            c1->rtsp_c = NULL;
+    }
+
+    /* remove connection associated resources */
+    if (c->fd >= 0)
+        closesocket(c->fd);
+    if (c->fmt_in) {
+        /* close each frame parser */
+        for(i=0;i<c->fmt_in->nb_streams;i++) {
+            st = c->fmt_in->streams[i];
+            if (st->codec->codec)
+                avcodec_close(st->codec);
+        }
+        avformat_close_input(&c->fmt_in);
+    }
+
+    /* free RTP output streams if any */
+    nb_streams = 0;
+    if (c->stream)
+        nb_streams = c->stream->nb_streams;
+
+    for(i=0;i<nb_streams;i++) {
+        ctx = c->rtp_ctx[i];
+        if (ctx) {
+            av_write_trailer(ctx);
+            av_dict_free(&ctx->metadata);
+            av_free(ctx->streams[0]);
+            av_free(ctx);
+        }
+        h = c->rtp_handles[i];
+        if (h)
+            ffurl_close(h);
+    }
+
+    ctx = &c->fmt_ctx;
+
+    if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) {
+        if (ctx->oformat) {
+            /* prepare header */
+            if (avio_open_dyn_buf(&ctx->pb) >= 0) {
+                av_write_trailer(ctx);
+                av_freep(&c->pb_buffer);
+                avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
+            }
+        }
+    }
+
+    for(i=0; i<ctx->nb_streams; i++)
+        av_free(ctx->streams[i]);
+
+    if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE)
+        current_bandwidth -= c->stream->bandwidth;
+
+    /* signal that there is no feed if we are the feeder socket */
+    if (c->state == HTTPSTATE_RECEIVE_DATA && c->stream) {
+        c->stream->feed_opened = 0;
+        close(c->feed_fd);
+    }
+
+    av_freep(&c->pb_buffer);
+    av_freep(&c->packet_buffer);
+    av_free(c->buffer);
+    av_free(c);
+    nb_connections--;
+}
+
+static int handle_connection(HTTPContext *c)
+{
+    int len, ret;
+
+    switch(c->state) {
+    case HTTPSTATE_WAIT_REQUEST:
+    case RTSPSTATE_WAIT_REQUEST:
+        /* timeout ? */
+        if ((c->timeout - cur_time) < 0)
+            return -1;
+        if (c->poll_entry->revents & (POLLERR | POLLHUP))
+            return -1;
+
+        /* no need to read if no events */
+        if (!(c->poll_entry->revents & POLLIN))
+            return 0;
+        /* read the data */
+    read_loop:
+        len = recv(c->fd, c->buffer_ptr, 1, 0);
+        if (len < 0) {
+            if (ff_neterrno() != AVERROR(EAGAIN) &&
+                ff_neterrno() != AVERROR(EINTR))
+                return -1;
+        } else if (len == 0) {
+            return -1;
+        } else {
+            /* search for end of request. */
+            uint8_t *ptr;
+            c->buffer_ptr += len;
+            ptr = c->buffer_ptr;
+            if ((ptr >= c->buffer + 2 && !memcmp(ptr-2, "\n\n", 2)) ||
+                (ptr >= c->buffer + 4 && !memcmp(ptr-4, "\r\n\r\n", 4))) {
+                /* request found : parse it and reply */
+                if (c->state == HTTPSTATE_WAIT_REQUEST) {
+                    ret = http_parse_request(c);
+                } else {
+                    ret = rtsp_parse_request(c);
+                }
+                if (ret < 0)
+                    return -1;
+            } else if (ptr >= c->buffer_end) {
+                /* request too long: cannot do anything */
+                return -1;
+            } else goto read_loop;
+        }
+        break;
+
+    case HTTPSTATE_SEND_HEADER:
+        if (c->poll_entry->revents & (POLLERR | POLLHUP))
+            return -1;
+
+        /* no need to write if no events */
+        if (!(c->poll_entry->revents & POLLOUT))
+            return 0;
+        len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
+        if (len < 0) {
+            if (ff_neterrno() != AVERROR(EAGAIN) &&
+                ff_neterrno() != AVERROR(EINTR)) {
+                /* error : close connection */
+                av_freep(&c->pb_buffer);
+                return -1;
+            }
+        } else {
+            c->buffer_ptr += len;
+            if (c->stream)
+                c->stream->bytes_served += len;
+            c->data_count += len;
+            if (c->buffer_ptr >= c->buffer_end) {
+                av_freep(&c->pb_buffer);
+                /* if error, exit */
+                if (c->http_error)
+                    return -1;
+                /* all the buffer was sent : synchronize to the incoming stream */
+                c->state = HTTPSTATE_SEND_DATA_HEADER;
+                c->buffer_ptr = c->buffer_end = c->buffer;
+            }
+        }
+        break;
+
+    case HTTPSTATE_SEND_DATA:
+    case HTTPSTATE_SEND_DATA_HEADER:
+    case HTTPSTATE_SEND_DATA_TRAILER:
+        /* for packetized output, we consider we can always write (the
+           input streams sets the speed). It may be better to verify
+           that we do not rely too much on the kernel queues */
+        if (!c->is_packetized) {
+            if (c->poll_entry->revents & (POLLERR | POLLHUP))
+                return -1;
+
+            /* no need to read if no events */
+            if (!(c->poll_entry->revents & POLLOUT))
+                return 0;
+        }
+        if (http_send_data(c) < 0)
+            return -1;
+        /* close connection if trailer sent */
+        if (c->state == HTTPSTATE_SEND_DATA_TRAILER)
+            return -1;
+        break;
+    case HTTPSTATE_RECEIVE_DATA:
+        /* no need to read if no events */
+        if (c->poll_entry->revents & (POLLERR | POLLHUP))
+            return -1;
+        if (!(c->poll_entry->revents & POLLIN))
+            return 0;
+        if (http_receive_data(c) < 0)
+            return -1;
+        break;
+    case HTTPSTATE_WAIT_FEED:
+        /* no need to read if no events */
+        if (c->poll_entry->revents & (POLLIN | POLLERR | POLLHUP))
+            return -1;
+
+        /* nothing to do, we'll be waken up by incoming feed packets */
+        break;
+
+    case RTSPSTATE_SEND_REPLY:
+        if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
+            av_freep(&c->pb_buffer);
+            return -1;
+        }
+        /* no need to write if no events */
+        if (!(c->poll_entry->revents & POLLOUT))
+            return 0;
+        len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
+        if (len < 0) {
+            if (ff_neterrno() != AVERROR(EAGAIN) &&
+                ff_neterrno() != AVERROR(EINTR)) {
+                /* error : close connection */
+                av_freep(&c->pb_buffer);
+                return -1;
+            }
+        } else {
+            c->buffer_ptr += len;
+            c->data_count += len;
+            if (c->buffer_ptr >= c->buffer_end) {
+                /* all the buffer was sent : wait for a new request */
+                av_freep(&c->pb_buffer);
+                start_wait_request(c, 1);
+            }
+        }
+        break;
+    case RTSPSTATE_SEND_PACKET:
+        if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
+            av_freep(&c->packet_buffer);
+            return -1;
+        }
+        /* no need to write if no events */
+        if (!(c->poll_entry->revents & POLLOUT))
+            return 0;
+        len = send(c->fd, c->packet_buffer_ptr,
+                    c->packet_buffer_end - c->packet_buffer_ptr, 0);
+        if (len < 0) {
+            if (ff_neterrno() != AVERROR(EAGAIN) &&
+                ff_neterrno() != AVERROR(EINTR)) {
+                /* error : close connection */
+                av_freep(&c->packet_buffer);
+                return -1;
+            }
+        } else {
+            c->packet_buffer_ptr += len;
+            if (c->packet_buffer_ptr >= c->packet_buffer_end) {
+                /* all the buffer was sent : wait for a new request */
+                av_freep(&c->packet_buffer);
+                c->state = RTSPSTATE_WAIT_REQUEST;
+            }
+        }
+        break;
+    case HTTPSTATE_READY:
+        /* nothing to do */
+        break;
+    default:
+        return -1;
+    }
+    return 0;
+}
+
+static int extract_rates(char *rates, int ratelen, const char *request)
+{
+    const char *p;
+
+    for (p = request; *p && *p != '\r' && *p != '\n'; ) {
+        if (av_strncasecmp(p, "Pragma:", 7) == 0) {
+            const char *q = p + 7;
+
+            while (*q && *q != '\n' && isspace(*q))
+                q++;
+
+            if (av_strncasecmp(q, "stream-switch-entry=", 20) == 0) {
+                int stream_no;
+                int rate_no;
+
+                q += 20;
+
+                memset(rates, 0xff, ratelen);
+
+                while (1) {
+                    while (*q && *q != '\n' && *q != ':')
+                        q++;
+
+                    if (sscanf(q, ":%d:%d", &stream_no, &rate_no) != 2)
+                        break;
+
+                    stream_no--;
+                    if (stream_no < ratelen && stream_no >= 0)
+                        rates[stream_no] = rate_no;
+
+                    while (*q && *q != '\n' && !isspace(*q))
+                        q++;
+                }
+
+                return 1;
+            }
+        }
+        p = strchr(p, '\n');
+        if (!p)
+            break;
+
+        p++;
+    }
+
+    return 0;
+}
+
+static int find_stream_in_feed(FFStream *feed, AVCodecContext *codec, int bit_rate)
+{
+    int i;
+    int best_bitrate = 100000000;
+    int best = -1;
+
+    for (i = 0; i < feed->nb_streams; i++) {
+        AVCodecContext *feed_codec = feed->streams[i]->codec;
+
+        if (feed_codec->codec_id != codec->codec_id ||
+            feed_codec->sample_rate != codec->sample_rate ||
+            feed_codec->width != codec->width ||
+            feed_codec->height != codec->height)
+            continue;
+
+        /* Potential stream */
+
+        /* We want the fastest stream less than bit_rate, or the slowest
+         * faster than bit_rate
+         */
+
+        if (feed_codec->bit_rate <= bit_rate) {
+            if (best_bitrate > bit_rate || feed_codec->bit_rate > best_bitrate) {
+                best_bitrate = feed_codec->bit_rate;
+                best = i;
+            }
+        } else {
+            if (feed_codec->bit_rate < best_bitrate) {
+                best_bitrate = feed_codec->bit_rate;
+                best = i;
+            }
+        }
+    }
+
+    return best;
+}
+
+static int modify_current_stream(HTTPContext *c, char *rates)
+{
+    int i;
+    FFStream *req = c->stream;
+    int action_required = 0;
+
+    /* Not much we can do for a feed */
+    if (!req->feed)
+        return 0;
+
+    for (i = 0; i < req->nb_streams; i++) {
+        AVCodecContext *codec = req->streams[i]->codec;
+
+        switch(rates[i]) {
+            case 0:
+                c->switch_feed_streams[i] = req->feed_streams[i];
+                break;
+            case 1:
+                c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 2);
+                break;
+            case 2:
+                /* Wants off or slow */
+                c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 4);
+#ifdef WANTS_OFF
+                /* This doesn't work well when it turns off the only stream! */
+                c->switch_feed_streams[i] = -2;
+                c->feed_streams[i] = -2;
+#endif
+                break;
+        }
+
+        if (c->switch_feed_streams[i] >= 0 && c->switch_feed_streams[i] != c->feed_streams[i])
+            action_required = 1;
+    }
+
+    return action_required;
+}
+
+/* XXX: factorize in utils.c ? */
+/* XXX: take care with different space meaning */
+static void skip_spaces(const char **pp)
+{
+    const char *p;
+    p = *pp;
+    while (*p == ' ' || *p == '\t')
+        p++;
+    *pp = p;
+}
+
+static void get_word(char *buf, int buf_size, const char **pp)
+{
+    const char *p;
+    char *q;
+
+    p = *pp;
+    skip_spaces(&p);
+    q = buf;
+    while (!isspace(*p) && *p != '\0') {
+        if ((q - buf) < buf_size - 1)
+            *q++ = *p;
+        p++;
+    }
+    if (buf_size > 0)
+        *q = '\0';
+    *pp = p;
+}
+
+static void get_arg(char *buf, int buf_size, const char **pp)
+{
+    const char *p;
+    char *q;
+    int quote;
+
+    p = *pp;
+    while (isspace(*p)) p++;
+    q = buf;
+    quote = 0;
+    if (*p == '\"' || *p == '\'')
+        quote = *p++;
+    for(;;) {
+        if (quote) {
+            if (*p == quote)
+                break;
+        } else {
+            if (isspace(*p))
+                break;
+        }
+        if (*p == '\0')
+            break;
+        if ((q - buf) < buf_size - 1)
+            *q++ = *p;
+        p++;
+    }
+    *q = '\0';
+    if (quote && *p == quote)
+        p++;
+    *pp = p;
+}
+
+static void parse_acl_row(FFStream *stream, FFStream* feed, IPAddressACL *ext_acl,
+                         const char *p, const char *filename, int line_num)
+{
+    char arg[1024];
+    IPAddressACL acl;
+    int errors = 0;
+
+    get_arg(arg, sizeof(arg), &p);
+    if (av_strcasecmp(arg, "allow") == 0)
+        acl.action = IP_ALLOW;
+    else if (av_strcasecmp(arg, "deny") == 0)
+        acl.action = IP_DENY;
+    else {
+        fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n",
+                filename, line_num, arg);
+        errors++;
+    }
+
+    get_arg(arg, sizeof(arg), &p);
+
+    if (resolve_host(&acl.first, arg) != 0) {
+        fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
+                filename, line_num, arg);
+        errors++;
+    } else
+        acl.last = acl.first;
+
+    get_arg(arg, sizeof(arg), &p);
+
+    if (arg[0]) {
+        if (resolve_host(&acl.last, arg) != 0) {
+            fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
+                    filename, line_num, arg);
+            errors++;
+        }
+    }
+
+    if (!errors) {
+        IPAddressACL *nacl = av_mallocz(sizeof(*nacl));
+        IPAddressACL **naclp = 0;
+
+        acl.next = 0;
+        *nacl = acl;
+
+        if (stream)
+            naclp = &stream->acl;
+        else if (feed)
+            naclp = &feed->acl;
+        else if (ext_acl)
+            naclp = &ext_acl;
+        else {
+            fprintf(stderr, "%s:%d: ACL found not in <stream> or <feed>\n",
+                    filename, line_num);
+            errors++;
+        }
+
+        if (naclp) {
+            while (*naclp)
+                naclp = &(*naclp)->next;
+
+            *naclp = nacl;
+        }
+    }
+}
+
+
+static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c)
+{
+    FILE* f;
+    char line[1024];
+    char  cmd[1024];
+    IPAddressACL *acl = NULL;
+    int line_num = 0;
+    const char *p;
+
+    f = fopen(stream->dynamic_acl, "r");
+    if (!f) {
+        perror(stream->dynamic_acl);
+        return NULL;
+    }
+
+    acl = av_mallocz(sizeof(IPAddressACL));
+
+    /* Build ACL */
+    for(;;) {
+        if (fgets(line, sizeof(line), f) == NULL)
+            break;
+        line_num++;
+        p = line;
+        while (isspace(*p))
+            p++;
+        if (*p == '\0' || *p == '#')
+            continue;
+        get_arg(cmd, sizeof(cmd), &p);
+
+        if (!av_strcasecmp(cmd, "ACL"))
+            parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num);
+    }
+    fclose(f);
+    return acl;
+}
+
+
+static void free_acl_list(IPAddressACL *in_acl)
+{
+    IPAddressACL *pacl,*pacl2;
+
+    pacl = in_acl;
+    while(pacl) {
+        pacl2 = pacl;
+        pacl = pacl->next;
+        av_freep(pacl2);
+    }
+}
+
+static int validate_acl_list(IPAddressACL *in_acl, HTTPContext *c)
+{
+    enum IPAddressAction last_action = IP_DENY;
+    IPAddressACL *acl;
+    struct in_addr *src = &c->from_addr.sin_addr;
+    unsigned long src_addr = src->s_addr;
+
+    for (acl = in_acl; acl; acl = acl->next) {
+        if (src_addr >= acl->first.s_addr && src_addr <= acl->last.s_addr)
+            return (acl->action == IP_ALLOW) ? 1 : 0;
+        last_action = acl->action;
+    }
+
+    /* Nothing matched, so return not the last action */
+    return (last_action == IP_DENY) ? 1 : 0;
+}
+
+static int validate_acl(FFStream *stream, HTTPContext *c)
+{
+    int ret = 0;
+    IPAddressACL *acl;
+
+
+    /* if stream->acl is null validate_acl_list will return 1 */
+    ret = validate_acl_list(stream->acl, c);
+
+    if (stream->dynamic_acl[0]) {
+        acl = parse_dynamic_acl(stream, c);
+
+        ret = validate_acl_list(acl, c);
+
+        free_acl_list(acl);
+    }
+
+    return ret;
+}
+
+/* compute the real filename of a file by matching it without its
+   extensions to all the stream filenames */
+static void compute_real_filename(char *filename, int max_size)
+{
+    char file1[1024];
+    char file2[1024];
+    char *p;
+    FFStream *stream;
+
+    /* compute filename by matching without the file extensions */
+    av_strlcpy(file1, filename, sizeof(file1));
+    p = strrchr(file1, '.');
+    if (p)
+        *p = '\0';
+    for(stream = first_stream; stream != NULL; stream = stream->next) {
+        av_strlcpy(file2, stream->filename, sizeof(file2));
+        p = strrchr(file2, '.');
+        if (p)
+            *p = '\0';
+        if (!strcmp(file1, file2)) {
+            av_strlcpy(filename, stream->filename, max_size);
+            break;
+        }
+    }
+}
+
+enum RedirType {
+    REDIR_NONE,
+    REDIR_ASX,
+    REDIR_RAM,
+    REDIR_ASF,
+    REDIR_RTSP,
+    REDIR_SDP,
+};
+
+/* parse http request and prepare header */
+static int http_parse_request(HTTPContext *c)
+{
+    char *p;
+    enum RedirType redir_type;
+    char cmd[32];
+    char info[1024], filename[1024];
+    char url[1024], *q;
+    char protocol[32];
+    char msg[1024];
+    const char *mime_type;
+    FFStream *stream;
+    int i;
+    char ratebuf[32];
+    char *useragent = 0;
+
+    p = c->buffer;
+    get_word(cmd, sizeof(cmd), (const char **)&p);
+    av_strlcpy(c->method, cmd, sizeof(c->method));
+
+    if (!strcmp(cmd, "GET"))
+        c->post = 0;
+    else if (!strcmp(cmd, "POST"))
+        c->post = 1;
+    else
+        return -1;
+
+    get_word(url, sizeof(url), (const char **)&p);
+    av_strlcpy(c->url, url, sizeof(c->url));
+
+    get_word(protocol, sizeof(protocol), (const char **)&p);
+    if (strcmp(protocol, "HTTP/1.0") && strcmp(protocol, "HTTP/1.1"))
+        return -1;
+
+    av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
+
+    if (ffserver_debug)
+        http_log("%s - - New connection: %s %s\n", inet_ntoa(c->from_addr.sin_addr), cmd, url);
+
+    /* find the filename and the optional info string in the request */
+    p = strchr(url, '?');
+    if (p) {
+        av_strlcpy(info, p, sizeof(info));
+        *p = '\0';
+    } else
+        info[0] = '\0';
+
+    av_strlcpy(filename, url + ((*url == '/') ? 1 : 0), sizeof(filename)-1);
+
+    for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
+        if (av_strncasecmp(p, "User-Agent:", 11) == 0) {
+            useragent = p + 11;
+            if (*useragent && *useragent != '\n' && isspace(*useragent))
+                useragent++;
+            break;
+        }
+        p = strchr(p, '\n');
+        if (!p)
+            break;
+
+        p++;
+    }
+
+    redir_type = REDIR_NONE;
+    if (av_match_ext(filename, "asx")) {
+        redir_type = REDIR_ASX;
+        filename[strlen(filename)-1] = 'f';
+    } else if (av_match_ext(filename, "asf") &&
+        (!useragent || av_strncasecmp(useragent, "NSPlayer", 8) != 0)) {
+        /* if this isn't WMP or lookalike, return the redirector file */
+        redir_type = REDIR_ASF;
+    } else if (av_match_ext(filename, "rpm,ram")) {
+        redir_type = REDIR_RAM;
+        strcpy(filename + strlen(filename)-2, "m");
+    } else if (av_match_ext(filename, "rtsp")) {
+        redir_type = REDIR_RTSP;
+        compute_real_filename(filename, sizeof(filename) - 1);
+    } else if (av_match_ext(filename, "sdp")) {
+        redir_type = REDIR_SDP;
+        compute_real_filename(filename, sizeof(filename) - 1);
+    }
+
+    // "redirect" / request to index.html
+    if (!strlen(filename))
+        av_strlcpy(filename, "index.html", sizeof(filename) - 1);
+
+    stream = first_stream;
+    while (stream != NULL) {
+        if (!strcmp(stream->filename, filename) && validate_acl(stream, c))
+            break;
+        stream = stream->next;
+    }
+    if (stream == NULL) {
+        snprintf(msg, sizeof(msg), "File '%s' not found", url);
+        http_log("File '%s' not found\n", url);
+        goto send_error;
+    }
+
+    c->stream = stream;
+    memcpy(c->feed_streams, stream->feed_streams, sizeof(c->feed_streams));
+    memset(c->switch_feed_streams, -1, sizeof(c->switch_feed_streams));
+
+    if (stream->stream_type == STREAM_TYPE_REDIRECT) {
+        c->http_error = 301;
+        q = c->buffer;
+        snprintf(q, c->buffer_size,
+                      "HTTP/1.0 301 Moved\r\n"
+                      "Location: %s\r\n"
+                      "Content-type: text/html\r\n"
+                      "\r\n"
+                      "<html><head><title>Moved</title></head><body>\r\n"
+                      "You should be <a href=\"%s\">redirected</a>.\r\n"
+                      "</body></html>\r\n", stream->feed_filename, stream->feed_filename);
+        q += strlen(q);
+        /* prepare output buffer */
+        c->buffer_ptr = c->buffer;
+        c->buffer_end = q;
+        c->state = HTTPSTATE_SEND_HEADER;
+        return 0;
+    }
+
+    /* If this is WMP, get the rate information */
+    if (extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
+        if (modify_current_stream(c, ratebuf)) {
+            for (i = 0; i < FF_ARRAY_ELEMS(c->feed_streams); i++) {
+                if (c->switch_feed_streams[i] >= 0)
+                    c->switch_feed_streams[i] = -1;
+            }
+        }
+    }
+
+    if (c->post == 0 && stream->stream_type == STREAM_TYPE_LIVE)
+        current_bandwidth += stream->bandwidth;
+
+    /* If already streaming this feed, do not let start another feeder. */
+    if (stream->feed_opened) {
+        snprintf(msg, sizeof(msg), "This feed is already being received.");
+        http_log("Feed '%s' already being received\n", stream->feed_filename);
+        goto send_error;
+    }
+
+    if (c->post == 0 && max_bandwidth < current_bandwidth) {
+        c->http_error = 503;
+        q = c->buffer;
+        snprintf(q, c->buffer_size,
+                      "HTTP/1.0 503 Server too busy\r\n"
+                      "Content-type: text/html\r\n"
+                      "\r\n"
+                      "<html><head><title>Too busy</title></head><body>\r\n"
+                      "<p>The server is too busy to serve your request at this time.</p>\r\n"
+                      "<p>The bandwidth being served (including your stream) is %"PRIu64"kbit/sec, "
+                      "and this exceeds the limit of %"PRIu64"kbit/sec.</p>\r\n"
+                      "</body></html>\r\n", current_bandwidth, max_bandwidth);
+        q += strlen(q);
+        /* prepare output buffer */
+        c->buffer_ptr = c->buffer;
+        c->buffer_end = q;
+        c->state = HTTPSTATE_SEND_HEADER;
+        return 0;
+    }
+
+    if (redir_type != REDIR_NONE) {
+        char *hostinfo = 0;
+
+        for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
+            if (av_strncasecmp(p, "Host:", 5) == 0) {
+                hostinfo = p + 5;
+                break;
+            }
+            p = strchr(p, '\n');
+            if (!p)
+                break;
+
+            p++;
+        }
+
+        if (hostinfo) {
+            char *eoh;
+            char hostbuf[260];
+
+            while (isspace(*hostinfo))
+                hostinfo++;
+
+            eoh = strchr(hostinfo, '\n');
+            if (eoh) {
+                if (eoh[-1] == '\r')
+                    eoh--;
+
+                if (eoh - hostinfo < sizeof(hostbuf) - 1) {
+                    memcpy(hostbuf, hostinfo, eoh - hostinfo);
+                    hostbuf[eoh - hostinfo] = 0;
+
+                    c->http_error = 200;
+                    q = c->buffer;
+                    switch(redir_type) {
+                    case REDIR_ASX:
+                        snprintf(q, c->buffer_size,
+                                      "HTTP/1.0 200 ASX Follows\r\n"
+                                      "Content-type: video/x-ms-asf\r\n"
+                                      "\r\n"
+                                      "<ASX Version=\"3\">\r\n"
+                                      //"<!-- Autogenerated by ffserver -->\r\n"
+                                      "<ENTRY><REF HREF=\"http://%s/%s%s\"/></ENTRY>\r\n"
+                                      "</ASX>\r\n", hostbuf, filename, info);
+                        q += strlen(q);
+                        break;
+                    case REDIR_RAM:
+                        snprintf(q, c->buffer_size,
+                                      "HTTP/1.0 200 RAM Follows\r\n"
+                                      "Content-type: audio/x-pn-realaudio\r\n"
+                                      "\r\n"
+                                      "# Autogenerated by ffserver\r\n"
+                                      "http://%s/%s%s\r\n", hostbuf, filename, info);
+                        q += strlen(q);
+                        break;
+                    case REDIR_ASF:
+                        snprintf(q, c->buffer_size,
+                                      "HTTP/1.0 200 ASF Redirect follows\r\n"
+                                      "Content-type: video/x-ms-asf\r\n"
+                                      "\r\n"
+                                      "[Reference]\r\n"
+                                      "Ref1=http://%s/%s%s\r\n", hostbuf, filename, info);
+                        q += strlen(q);
+                        break;
+                    case REDIR_RTSP:
+                        {
+                            char hostname[256], *p;
+                            /* extract only hostname */
+                            av_strlcpy(hostname, hostbuf, sizeof(hostname));
+                            p = strrchr(hostname, ':');
+                            if (p)
+                                *p = '\0';
+                            snprintf(q, c->buffer_size,
+                                          "HTTP/1.0 200 RTSP Redirect follows\r\n"
+                                          /* XXX: incorrect mime type ? */
+                                          "Content-type: application/x-rtsp\r\n"
+                                          "\r\n"
+                                          "rtsp://%s:%d/%s\r\n", hostname, ntohs(my_rtsp_addr.sin_port), filename);
+                            q += strlen(q);
+                        }
+                        break;
+                    case REDIR_SDP:
+                        {
+                            uint8_t *sdp_data;
+                            int sdp_data_size, len;
+                            struct sockaddr_in my_addr;
+
+                            snprintf(q, c->buffer_size,
+                                          "HTTP/1.0 200 OK\r\n"
+                                          "Content-type: application/sdp\r\n"
+                                          "\r\n");
+                            q += strlen(q);
+
+                            len = sizeof(my_addr);
+                            getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
+
+                            /* XXX: should use a dynamic buffer */
+                            sdp_data_size = prepare_sdp_description(stream,
+                                                                    &sdp_data,
+                                                                    my_addr.sin_addr);
+                            if (sdp_data_size > 0) {
+                                memcpy(q, sdp_data, sdp_data_size);
+                                q += sdp_data_size;
+                                *q = '\0';
+                                av_free(sdp_data);
+                            }
+                        }
+                        break;
+                    default:
+                        abort();
+                        break;
+                    }
+
+                    /* prepare output buffer */
+                    c->buffer_ptr = c->buffer;
+                    c->buffer_end = q;
+                    c->state = HTTPSTATE_SEND_HEADER;
+                    return 0;
+                }
+            }
+        }
+
+        snprintf(msg, sizeof(msg), "ASX/RAM file not handled");
+        goto send_error;
+    }
+
+    stream->conns_served++;
+
+    /* XXX: add there authenticate and IP match */
+
+    if (c->post) {
+        /* if post, it means a feed is being sent */
+        if (!stream->is_feed) {
+            /* However it might be a status report from WMP! Let us log the
+             * data as it might come in handy one day. */
+            char *logline = 0;
+            int client_id = 0;
+
+            for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
+                if (av_strncasecmp(p, "Pragma: log-line=", 17) == 0) {
+                    logline = p;
+                    break;
+                }
+                if (av_strncasecmp(p, "Pragma: client-id=", 18) == 0)
+                    client_id = strtol(p + 18, 0, 10);
+                p = strchr(p, '\n');
+                if (!p)
+                    break;
+
+                p++;
+            }
+
+            if (logline) {
+                char *eol = strchr(logline, '\n');
+
+                logline += 17;
+
+                if (eol) {
+                    if (eol[-1] == '\r')
+                        eol--;
+                    http_log("%.*s\n", (int) (eol - logline), logline);
+                    c->suppress_log = 1;
+                }
+            }
+
+#ifdef DEBUG
+            http_log("\nGot request:\n%s\n", c->buffer);
+#endif
+
+            if (client_id && extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
+                HTTPContext *wmpc;
+
+                /* Now we have to find the client_id */
+                for (wmpc = first_http_ctx; wmpc; wmpc = wmpc->next) {
+                    if (wmpc->wmp_client_id == client_id)
+                        break;
+                }
+
+                if (wmpc && modify_current_stream(wmpc, ratebuf))
+                    wmpc->switch_pending = 1;
+            }
+
+            snprintf(msg, sizeof(msg), "POST command not handled");
+            c->stream = 0;
+            goto send_error;
+        }
+        if (http_start_receive_data(c) < 0) {
+            snprintf(msg, sizeof(msg), "could not open feed");
+            goto send_error;
+        }
+        c->http_error = 0;
+        c->state = HTTPSTATE_RECEIVE_DATA;
+        return 0;
+    }
+
+#ifdef DEBUG
+    if (strcmp(stream->filename + strlen(stream->filename) - 4, ".asf") == 0)
+        http_log("\nGot request:\n%s\n", c->buffer);
+#endif
+
+    if (c->stream->stream_type == STREAM_TYPE_STATUS)
+        goto send_status;
+
+    /* open input stream */
+    if (open_input_stream(c, info) < 0) {
+        snprintf(msg, sizeof(msg), "Input stream corresponding to '%s' not found", url);
+        goto send_error;
+    }
+
+    /* prepare http header */
+    c->buffer[0] = 0;
+    av_strlcatf(c->buffer, c->buffer_size, "HTTP/1.0 200 OK\r\n");
+    mime_type = c->stream->fmt->mime_type;
+    if (!mime_type)
+        mime_type = "application/x-octet-stream";
+    av_strlcatf(c->buffer, c->buffer_size, "Pragma: no-cache\r\n");
+
+    /* for asf, we need extra headers */
+    if (!strcmp(c->stream->fmt->name,"asf_stream")) {
+        /* Need to allocate a client id */
+
+        c->wmp_client_id = av_lfg_get(&random_state);
+
+        av_strlcatf(c->buffer, c->buffer_size, "Server: Cougar 4.1.0.3923\r\nCache-Control: no-cache\r\nPragma: client-id=%d\r\nPragma: features=\"broadcast\"\r\n", c->wmp_client_id);
+    }
+    av_strlcatf(c->buffer, c->buffer_size, "Content-Type: %s\r\n", mime_type);
+    av_strlcatf(c->buffer, c->buffer_size, "\r\n");
+    q = c->buffer + strlen(c->buffer);
+
+    /* prepare output buffer */
+    c->http_error = 0;
+    c->buffer_ptr = c->buffer;
+    c->buffer_end = q;
+    c->state = HTTPSTATE_SEND_HEADER;
+    return 0;
+ send_error:
+    c->http_error = 404;
+    q = c->buffer;
+    snprintf(q, c->buffer_size,
+                  "HTTP/1.0 404 Not Found\r\n"
+                  "Content-type: text/html\r\n"
+                  "\r\n"
+                  "<html>\n"
+                  "<head><title>404 Not Found</title></head>\n"
+                  "<body>%s</body>\n"
+                  "</html>\n", msg);
+    q += strlen(q);
+    /* prepare output buffer */
+    c->buffer_ptr = c->buffer;
+    c->buffer_end = q;
+    c->state = HTTPSTATE_SEND_HEADER;
+    return 0;
+ send_status:
+    compute_status(c);
+    c->http_error = 200; /* horrible : we use this value to avoid
+                            going to the send data state */
+    c->state = HTTPSTATE_SEND_HEADER;
+    return 0;
+}
+
+static void fmt_bytecount(AVIOContext *pb, int64_t count)
+{
+    static const char suffix[] = " kMGTP";
+    const char *s;
+
+    for (s = suffix; count >= 100000 && s[1]; count /= 1000, s++);
+
+    avio_printf(pb, "%"PRId64"%c", count, *s);
+}
+
+static void compute_status(HTTPContext *c)
+{
+    HTTPContext *c1;
+    FFStream *stream;
+    char *p;
+    time_t ti;
+    int i, len;
+    AVIOContext *pb;
+
+    if (avio_open_dyn_buf(&pb) < 0) {
+        /* XXX: return an error ? */
+        c->buffer_ptr = c->buffer;
+        c->buffer_end = c->buffer;
+        return;
+    }
+
+    avio_printf(pb, "HTTP/1.0 200 OK\r\n");
+    avio_printf(pb, "Content-type: %s\r\n", "text/html");
+    avio_printf(pb, "Pragma: no-cache\r\n");
+    avio_printf(pb, "\r\n");
+
+    avio_printf(pb, "<html><head><title>%s Status</title>\n", program_name);
+    if (c->stream->feed_filename[0])
+        avio_printf(pb, "<link rel=\"shortcut icon\" href=\"%s\">\n", c->stream->feed_filename);
+    avio_printf(pb, "</head>\n<body>");
+    avio_printf(pb, "<h1>%s Status</h1>\n", program_name);
+    /* format status */
+    avio_printf(pb, "<h2>Available Streams</h2>\n");
+    avio_printf(pb, "<table cellspacing=0 cellpadding=4>\n");
+    avio_printf(pb, "<tr><th valign=top>Path<th align=left>Served<br>Conns<th><br>bytes<th valign=top>Format<th>Bit rate<br>kbits/s<th align=left>Video<br>kbits/s<th><br>Codec<th align=left>Audio<br>kbits/s<th><br>Codec<th align=left valign=top>Feed\n");
+    stream = first_stream;
+    while (stream != NULL) {
+        char sfilename[1024];
+        char *eosf;
+
+        if (stream->feed != stream) {
+            av_strlcpy(sfilename, stream->filename, sizeof(sfilename) - 10);
+            eosf = sfilename + strlen(sfilename);
+            if (eosf - sfilename >= 4) {
+                if (strcmp(eosf - 4, ".asf") == 0)
+                    strcpy(eosf - 4, ".asx");
+                else if (strcmp(eosf - 3, ".rm") == 0)
+                    strcpy(eosf - 3, ".ram");
+                else if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
+                    /* generate a sample RTSP director if
+                       unicast. Generate an SDP redirector if
+                       multicast */
+                    eosf = strrchr(sfilename, '.');
+                    if (!eosf)
+                        eosf = sfilename + strlen(sfilename);
+                    if (stream->is_multicast)
+                        strcpy(eosf, ".sdp");
+                    else
+                        strcpy(eosf, ".rtsp");
+                }
+            }
+
+            avio_printf(pb, "<tr><td><a href=\"/%s\">%s</a> ",
+                         sfilename, stream->filename);
+            avio_printf(pb, "<td align=right> %d <td align=right> ",
+                        stream->conns_served);
+            fmt_bytecount(pb, stream->bytes_served);
+            switch(stream->stream_type) {
+            case STREAM_TYPE_LIVE: {
+                    int audio_bit_rate = 0;
+                    int video_bit_rate = 0;
+                    const char *audio_codec_name = "";
+                    const char *video_codec_name = "";
+                    const char *audio_codec_name_extra = "";
+                    const char *video_codec_name_extra = "";
+
+                    for(i=0;i<stream->nb_streams;i++) {
+                        AVStream *st = stream->streams[i];
+                        AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
+                        switch(st->codec->codec_type) {
+                        case AVMEDIA_TYPE_AUDIO:
+                            audio_bit_rate += st->codec->bit_rate;
+                            if (codec) {
+                                if (*audio_codec_name)
+                                    audio_codec_name_extra = "...";
+                                audio_codec_name = codec->name;
+                            }
+                            break;
+                        case AVMEDIA_TYPE_VIDEO:
+                            video_bit_rate += st->codec->bit_rate;
+                            if (codec) {
+                                if (*video_codec_name)
+                                    video_codec_name_extra = "...";
+                                video_codec_name = codec->name;
+                            }
+                            break;
+                        case AVMEDIA_TYPE_DATA:
+                            video_bit_rate += st->codec->bit_rate;
+                            break;
+                        default:
+                            abort();
+                        }
+                    }
+                    avio_printf(pb, "<td align=center> %s <td align=right> %d <td align=right> %d <td> %s %s <td align=right> %d <td> %s %s",
+                                 stream->fmt->name,
+                                 stream->bandwidth,
+                                 video_bit_rate / 1000, video_codec_name, video_codec_name_extra,
+                                 audio_bit_rate / 1000, audio_codec_name, audio_codec_name_extra);
+                    if (stream->feed)
+                        avio_printf(pb, "<td>%s", stream->feed->filename);
+                    else
+                        avio_printf(pb, "<td>%s", stream->feed_filename);
+                    avio_printf(pb, "\n");
+                }
+                break;
+            default:
+                avio_printf(pb, "<td align=center> - <td align=right> - <td align=right> - <td><td align=right> - <td>\n");
+                break;
+            }
+        }
+        stream = stream->next;
+    }
+    avio_printf(pb, "</table>\n");
+
+    stream = first_stream;
+    while (stream != NULL) {
+        if (stream->feed == stream) {
+            avio_printf(pb, "<h2>Feed %s</h2>", stream->filename);
+            if (stream->pid) {
+                avio_printf(pb, "Running as pid %d.\n", stream->pid);
+
+#if defined(linux) && !defined(CONFIG_NOCUTILS)
+                {
+                    FILE *pid_stat;
+                    char ps_cmd[64];
+
+                    /* This is somewhat linux specific I guess */
+                    snprintf(ps_cmd, sizeof(ps_cmd),
+                             "ps -o \"%%cpu,cputime\" --no-headers %d",
+                             stream->pid);
+
+                    pid_stat = popen(ps_cmd, "r");
+                    if (pid_stat) {
+                        char cpuperc[10];
+                        char cpuused[64];
+
+                        if (fscanf(pid_stat, "%9s %63s", cpuperc,
+                                   cpuused) == 2) {
+                            avio_printf(pb, "Currently using %s%% of the cpu. Total time used %s.\n",
+                                         cpuperc, cpuused);
+                        }
+                        fclose(pid_stat);
+                    }
+                }
+#endif
+
+                avio_printf(pb, "<p>");
+            }
+            avio_printf(pb, "<table cellspacing=0 cellpadding=4><tr><th>Stream<th>type<th>kbits/s<th align=left>codec<th align=left>Parameters\n");
+
+            for (i = 0; i < stream->nb_streams; i++) {
+                AVStream *st = stream->streams[i];
+                AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
+                const char *type = "unknown";
+                char parameters[64];
+
+                parameters[0] = 0;
+
+                switch(st->codec->codec_type) {
+                case AVMEDIA_TYPE_AUDIO:
+                    type = "audio";
+                    snprintf(parameters, sizeof(parameters), "%d channel(s), %d Hz", st->codec->channels, st->codec->sample_rate);
+                    break;
+                case AVMEDIA_TYPE_VIDEO:
+                    type = "video";
+                    snprintf(parameters, sizeof(parameters), "%dx%d, q=%d-%d, fps=%d", st->codec->width, st->codec->height,
+                                st->codec->qmin, st->codec->qmax, st->codec->time_base.den / st->codec->time_base.num);
+                    break;
+                default:
+                    abort();
+                }
+                avio_printf(pb, "<tr><td align=right>%d<td>%s<td align=right>%d<td>%s<td>%s\n",
+                        i, type, st->codec->bit_rate/1000, codec ? codec->name : "", parameters);
+            }
+            avio_printf(pb, "</table>\n");
+
+        }
+        stream = stream->next;
+    }
+
+    /* connection status */
+    avio_printf(pb, "<h2>Connection Status</h2>\n");
+
+    avio_printf(pb, "Number of connections: %d / %d<br>\n",
+                 nb_connections, nb_max_connections);
+
+    avio_printf(pb, "Bandwidth in use: %"PRIu64"k / %"PRIu64"k<br>\n",
+                 current_bandwidth, max_bandwidth);
+
+    avio_printf(pb, "<table>\n");
+    avio_printf(pb, "<tr><th>#<th>File<th>IP<th>Proto<th>State<th>Target bits/sec<th>Actual bits/sec<th>Bytes transferred\n");
+    c1 = first_http_ctx;
+    i = 0;
+    while (c1 != NULL) {
+        int bitrate;
+        int j;
+
+        bitrate = 0;
+        if (c1->stream) {
+            for (j = 0; j < c1->stream->nb_streams; j++) {
+                if (!c1->stream->feed)
+                    bitrate += c1->stream->streams[j]->codec->bit_rate;
+                else if (c1->feed_streams[j] >= 0)
+                    bitrate += c1->stream->feed->streams[c1->feed_streams[j]]->codec->bit_rate;
+            }
+        }
+
+        i++;
+        p = inet_ntoa(c1->from_addr.sin_addr);
+        avio_printf(pb, "<tr><td><b>%d</b><td>%s%s<td>%s<td>%s<td>%s<td align=right>",
+                    i,
+                    c1->stream ? c1->stream->filename : "",
+                    c1->state == HTTPSTATE_RECEIVE_DATA ? "(input)" : "",
+                    p,
+                    c1->protocol,
+                    http_state[c1->state]);
+        fmt_bytecount(pb, bitrate);
+        avio_printf(pb, "<td align=right>");
+        fmt_bytecount(pb, compute_datarate(&c1->datarate, c1->data_count) * 8);
+        avio_printf(pb, "<td align=right>");
+        fmt_bytecount(pb, c1->data_count);
+        avio_printf(pb, "\n");
+        c1 = c1->next;
+    }
+    avio_printf(pb, "</table>\n");
+
+    /* date */
+    ti = time(NULL);
+    p = ctime(&ti);
+    avio_printf(pb, "<hr size=1 noshade>Generated at %s", p);
+    avio_printf(pb, "</body>\n</html>\n");
+
+    len = avio_close_dyn_buf(pb, &c->pb_buffer);
+    c->buffer_ptr = c->pb_buffer;
+    c->buffer_end = c->pb_buffer + len;
+}
+
+static int open_input_stream(HTTPContext *c, const char *info)
+{
+    char buf[128];
+    char input_filename[1024];
+    AVFormatContext *s = NULL;
+    int buf_size, i, ret;
+    int64_t stream_pos;
+
+    /* find file name */
+    if (c->stream->feed) {
+        strcpy(input_filename, c->stream->feed->feed_filename);
+        buf_size = FFM_PACKET_SIZE;
+        /* compute position (absolute time) */
+        if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
+            if ((ret = av_parse_time(&stream_pos, buf, 0)) < 0)
+                return ret;
+        } else if (av_find_info_tag(buf, sizeof(buf), "buffer", info)) {
+            int prebuffer = strtol(buf, 0, 10);
+            stream_pos = av_gettime() - prebuffer * (int64_t)1000000;
+        } else
+            stream_pos = av_gettime() - c->stream->prebuffer * (int64_t)1000;
+    } else {
+        strcpy(input_filename, c->stream->feed_filename);
+        buf_size = 0;
+        /* compute position (relative time) */
+        if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
+            if ((ret = av_parse_time(&stream_pos, buf, 1)) < 0)
+                return ret;
+        } else
+            stream_pos = 0;
+    }
+    if (input_filename[0] == '\0')
+        return -1;
+
+    /* open stream */
+    if ((ret = avformat_open_input(&s, input_filename, c->stream->ifmt, &c->stream->in_opts)) < 0) {
+        http_log("could not open %s: %d\n", input_filename, ret);
+        return -1;
+    }
+
+    /* set buffer size */
+    if (buf_size > 0) ffio_set_buf_size(s->pb, buf_size);
+
+    s->flags |= AVFMT_FLAG_GENPTS;
+    c->fmt_in = s;
+    if (strcmp(s->iformat->name, "ffm") && avformat_find_stream_info(c->fmt_in, NULL) < 0) {
+        http_log("Could not find stream info '%s'\n", input_filename);
+        avformat_close_input(&s);
+        return -1;
+    }
+
+    /* choose stream as clock source (we favorize video stream if
+       present) for packet sending */
+    c->pts_stream_index = 0;
+    for(i=0;i<c->stream->nb_streams;i++) {
+        if (c->pts_stream_index == 0 &&
+            c->stream->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+            c->pts_stream_index = i;
+        }
+    }
+
+    if (c->fmt_in->iformat->read_seek)
+        av_seek_frame(c->fmt_in, -1, stream_pos, 0);
+    /* set the start time (needed for maxtime and RTP packet timing) */
+    c->start_time = cur_time;
+    c->first_pts = AV_NOPTS_VALUE;
+    return 0;
+}
+
+/* return the server clock (in us) */
+static int64_t get_server_clock(HTTPContext *c)
+{
+    /* compute current pts value from system time */
+    return (cur_time - c->start_time) * 1000;
+}
+
+/* return the estimated time at which the current packet must be sent
+   (in us) */
+static int64_t get_packet_send_clock(HTTPContext *c)
+{
+    int bytes_left, bytes_sent, frame_bytes;
+
+    frame_bytes = c->cur_frame_bytes;
+    if (frame_bytes <= 0)
+        return c->cur_pts;
+    else {
+        bytes_left = c->buffer_end - c->buffer_ptr;
+        bytes_sent = frame_bytes - bytes_left;
+        return c->cur_pts + (c->cur_frame_duration * bytes_sent) / frame_bytes;
+    }
+}
+
+
+static int http_prepare_data(HTTPContext *c)
+{
+    int i, len, ret;
+    AVFormatContext *ctx;
+
+    av_freep(&c->pb_buffer);
+    switch(c->state) {
+    case HTTPSTATE_SEND_DATA_HEADER:
+        memset(&c->fmt_ctx, 0, sizeof(c->fmt_ctx));
+        av_dict_set(&c->fmt_ctx.metadata, "author"   , c->stream->author   , 0);
+        av_dict_set(&c->fmt_ctx.metadata, "comment"  , c->stream->comment  , 0);
+        av_dict_set(&c->fmt_ctx.metadata, "copyright", c->stream->copyright, 0);
+        av_dict_set(&c->fmt_ctx.metadata, "title"    , c->stream->title    , 0);
+
+        c->fmt_ctx.streams = av_mallocz(sizeof(AVStream *) * c->stream->nb_streams);
+
+        for(i=0;i<c->stream->nb_streams;i++) {
+            AVStream *src;
+            c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream));
+            /* if file or feed, then just take streams from FFStream struct */
+            if (!c->stream->feed ||
+                c->stream->feed == c->stream)
+                src = c->stream->streams[i];
+            else
+                src = c->stream->feed->streams[c->stream->feed_streams[i]];
+
+            *(c->fmt_ctx.streams[i]) = *src;
+            c->fmt_ctx.streams[i]->priv_data = 0;
+            c->fmt_ctx.streams[i]->codec->frame_number = 0; /* XXX: should be done in
+                                           AVStream, not in codec */
+        }
+        /* set output format parameters */
+        c->fmt_ctx.oformat = c->stream->fmt;
+        c->fmt_ctx.nb_streams = c->stream->nb_streams;
+
+        c->got_key_frame = 0;
+
+        /* prepare header and save header data in a stream */
+        if (avio_open_dyn_buf(&c->fmt_ctx.pb) < 0) {
+            /* XXX: potential leak */
+            return -1;
+        }
+        c->fmt_ctx.pb->seekable = 0;
+
+        /*
+         * HACK to avoid mpeg ps muxer to spit many underflow errors
+         * Default value from FFmpeg
+         * Try to set it use configuration option
+         */
+        c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE);
+
+        if (avformat_write_header(&c->fmt_ctx, NULL) < 0) {
+            http_log("Error writing output header\n");
+            return -1;
+        }
+        av_dict_free(&c->fmt_ctx.metadata);
+
+        len = avio_close_dyn_buf(c->fmt_ctx.pb, &c->pb_buffer);
+        c->buffer_ptr = c->pb_buffer;
+        c->buffer_end = c->pb_buffer + len;
+
+        c->state = HTTPSTATE_SEND_DATA;
+        c->last_packet_sent = 0;
+        break;
+    case HTTPSTATE_SEND_DATA:
+        /* find a new packet */
+        /* read a packet from the input stream */
+        if (c->stream->feed)
+            ffm_set_write_index(c->fmt_in,
+                                c->stream->feed->feed_write_index,
+                                c->stream->feed->feed_size);
+
+        if (c->stream->max_time &&
+            c->stream->max_time + c->start_time - cur_time < 0)
+            /* We have timed out */
+            c->state = HTTPSTATE_SEND_DATA_TRAILER;
+        else {
+            AVPacket pkt;
+        redo:
+            ret = av_read_frame(c->fmt_in, &pkt);
+            if (ret < 0) {
+                if (c->stream->feed) {
+                    /* if coming from feed, it means we reached the end of the
+                       ffm file, so must wait for more data */
+                    c->state = HTTPSTATE_WAIT_FEED;
+                    return 1; /* state changed */
+                } else if (ret == AVERROR(EAGAIN)) {
+                    /* input not ready, come back later */
+                    return 0;
+                } else {
+                    if (c->stream->loop) {
+                        avformat_close_input(&c->fmt_in);
+                        if (open_input_stream(c, "") < 0)
+                            goto no_loop;
+                        goto redo;
+                    } else {
+                    no_loop:
+                        /* must send trailer now because eof or error */
+                        c->state = HTTPSTATE_SEND_DATA_TRAILER;
+                    }
+                }
+            } else {
+                int source_index = pkt.stream_index;
+                /* update first pts if needed */
+                if (c->first_pts == AV_NOPTS_VALUE) {
+                    c->first_pts = av_rescale_q(pkt.dts, c->fmt_in->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q);
+                    c->start_time = cur_time;
+                }
+                /* send it to the appropriate stream */
+                if (c->stream->feed) {
+                    /* if coming from a feed, select the right stream */
+                    if (c->switch_pending) {
+                        c->switch_pending = 0;
+                        for(i=0;i<c->stream->nb_streams;i++) {
+                            if (c->switch_feed_streams[i] == pkt.stream_index)
+                                if (pkt.flags & AV_PKT_FLAG_KEY)
+                                    c->switch_feed_streams[i] = -1;
+                            if (c->switch_feed_streams[i] >= 0)
+                                c->switch_pending = 1;
+                        }
+                    }
+                    for(i=0;i<c->stream->nb_streams;i++) {
+                        if (c->stream->feed_streams[i] == pkt.stream_index) {
+                            AVStream *st = c->fmt_in->streams[source_index];
+                            pkt.stream_index = i;
+                            if (pkt.flags & AV_PKT_FLAG_KEY &&
+                                (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
+                                 c->stream->nb_streams == 1))
+                                c->got_key_frame = 1;
+                            if (!c->stream->send_on_key || c->got_key_frame)
+                                goto send_it;
+                        }
+                    }
+                } else {
+                    AVCodecContext *codec;
+                    AVStream *ist, *ost;
+                send_it:
+                    ist = c->fmt_in->streams[source_index];
+                    /* specific handling for RTP: we use several
+                       output stream (one for each RTP
+                       connection). XXX: need more abstract handling */
+                    if (c->is_packetized) {
+                        /* compute send time and duration */
+                        c->cur_pts = av_rescale_q(pkt.dts, ist->time_base, AV_TIME_BASE_Q);
+                        c->cur_pts -= c->first_pts;
+                        c->cur_frame_duration = av_rescale_q(pkt.duration, ist->time_base, AV_TIME_BASE_Q);
+                        /* find RTP context */
+                        c->packet_stream_index = pkt.stream_index;
+                        ctx = c->rtp_ctx[c->packet_stream_index];
+                        if(!ctx) {
+                            av_free_packet(&pkt);
+                            break;
+                        }
+                        codec = ctx->streams[0]->codec;
+                        /* only one stream per RTP connection */
+                        pkt.stream_index = 0;
+                    } else {
+                        ctx = &c->fmt_ctx;
+                        /* Fudge here */
+                        codec = ctx->streams[pkt.stream_index]->codec;
+                    }
+
+                    if (c->is_packetized) {
+                        int max_packet_size;
+                        if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP)
+                            max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
+                        else
+                            max_packet_size = c->rtp_handles[c->packet_stream_index]->max_packet_size;
+                        ret = ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size);
+                    } else {
+                        ret = avio_open_dyn_buf(&ctx->pb);
+                    }
+                    if (ret < 0) {
+                        /* XXX: potential leak */
+                        return -1;
+                    }
+                    ost = ctx->streams[pkt.stream_index];
+
+                    ctx->pb->seekable = 0;
+                    if (pkt.dts != AV_NOPTS_VALUE)
+                        pkt.dts = av_rescale_q(pkt.dts, ist->time_base, ost->time_base);
+                    if (pkt.pts != AV_NOPTS_VALUE)
+                        pkt.pts = av_rescale_q(pkt.pts, ist->time_base, ost->time_base);
+                    pkt.duration = av_rescale_q(pkt.duration, ist->time_base, ost->time_base);
+                    if (av_write_frame(ctx, &pkt) < 0) {
+                        http_log("Error writing frame to output\n");
+                        c->state = HTTPSTATE_SEND_DATA_TRAILER;
+                    }
+
+                    len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
+                    c->cur_frame_bytes = len;
+                    c->buffer_ptr = c->pb_buffer;
+                    c->buffer_end = c->pb_buffer + len;
+
+                    codec->frame_number++;
+                    if (len == 0) {
+                        av_free_packet(&pkt);
+                        goto redo;
+                    }
+                }
+                av_free_packet(&pkt);
+            }
+        }
+        break;
+    default:
+    case HTTPSTATE_SEND_DATA_TRAILER:
+        /* last packet test ? */
+        if (c->last_packet_sent || c->is_packetized)
+            return -1;
+        ctx = &c->fmt_ctx;
+        /* prepare header */
+        if (avio_open_dyn_buf(&ctx->pb) < 0) {
+            /* XXX: potential leak */
+            return -1;
+        }
+        c->fmt_ctx.pb->seekable = 0;
+        av_write_trailer(ctx);
+        len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
+        c->buffer_ptr = c->pb_buffer;
+        c->buffer_end = c->pb_buffer + len;
+
+        c->last_packet_sent = 1;
+        break;
+    }
+    return 0;
+}
+
+/* should convert the format at the same time */
+/* send data starting at c->buffer_ptr to the output connection
+   (either UDP or TCP connection) */
+static int http_send_data(HTTPContext *c)
+{
+    int len, ret;
+
+    for(;;) {
+        if (c->buffer_ptr >= c->buffer_end) {
+            ret = http_prepare_data(c);
+            if (ret < 0)
+                return -1;
+            else if (ret != 0)
+                /* state change requested */
+                break;
+        } else {
+            if (c->is_packetized) {
+                /* RTP data output */
+                len = c->buffer_end - c->buffer_ptr;
+                if (len < 4) {
+                    /* fail safe - should never happen */
+                fail1:
+                    c->buffer_ptr = c->buffer_end;
+                    return 0;
+                }
+                len = (c->buffer_ptr[0] << 24) |
+                    (c->buffer_ptr[1] << 16) |
+                    (c->buffer_ptr[2] << 8) |
+                    (c->buffer_ptr[3]);
+                if (len > (c->buffer_end - c->buffer_ptr))
+                    goto fail1;
+                if ((get_packet_send_clock(c) - get_server_clock(c)) > 0) {
+                    /* nothing to send yet: we can wait */
+                    return 0;
+                }
+
+                c->data_count += len;
+                update_datarate(&c->datarate, c->data_count);
+                if (c->stream)
+                    c->stream->bytes_served += len;
+
+                if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP) {
+                    /* RTP packets are sent inside the RTSP TCP connection */
+                    AVIOContext *pb;
+                    int interleaved_index, size;
+                    uint8_t header[4];
+                    HTTPContext *rtsp_c;
+
+                    rtsp_c = c->rtsp_c;
+                    /* if no RTSP connection left, error */
+                    if (!rtsp_c)
+                        return -1;
+                    /* if already sending something, then wait. */
+                    if (rtsp_c->state != RTSPSTATE_WAIT_REQUEST)
+                        break;
+                    if (avio_open_dyn_buf(&pb) < 0)
+                        goto fail1;
+                    interleaved_index = c->packet_stream_index * 2;
+                    /* RTCP packets are sent at odd indexes */
+                    if (c->buffer_ptr[1] == 200)
+                        interleaved_index++;
+                    /* write RTSP TCP header */
+                    header[0] = '$';
+                    header[1] = interleaved_index;
+                    header[2] = len >> 8;
+                    header[3] = len;
+                    avio_write(pb, header, 4);
+                    /* write RTP packet data */
+                    c->buffer_ptr += 4;
+                    avio_write(pb, c->buffer_ptr, len);
+                    size = avio_close_dyn_buf(pb, &c->packet_buffer);
+                    /* prepare asynchronous TCP sending */
+                    rtsp_c->packet_buffer_ptr = c->packet_buffer;
+                    rtsp_c->packet_buffer_end = c->packet_buffer + size;
+                    c->buffer_ptr += len;
+
+                    /* send everything we can NOW */
+                    len = send(rtsp_c->fd, rtsp_c->packet_buffer_ptr,
+                                rtsp_c->packet_buffer_end - rtsp_c->packet_buffer_ptr, 0);
+                    if (len > 0)
+                        rtsp_c->packet_buffer_ptr += len;
+                    if (rtsp_c->packet_buffer_ptr < rtsp_c->packet_buffer_end) {
+                        /* if we could not send all the data, we will
+                           send it later, so a new state is needed to
+                           "lock" the RTSP TCP connection */
+                        rtsp_c->state = RTSPSTATE_SEND_PACKET;
+                        break;
+                    } else
+                        /* all data has been sent */
+                        av_freep(&c->packet_buffer);
+                } else {
+                    /* send RTP packet directly in UDP */
+                    c->buffer_ptr += 4;
+                    ffurl_write(c->rtp_handles[c->packet_stream_index],
+                                c->buffer_ptr, len);
+                    c->buffer_ptr += len;
+                    /* here we continue as we can send several packets per 10 ms slot */
+                }
+            } else {
+                /* TCP data output */
+                len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
+                if (len < 0) {
+                    if (ff_neterrno() != AVERROR(EAGAIN) &&
+                        ff_neterrno() != AVERROR(EINTR))
+                        /* error : close connection */
+                        return -1;
+                    else
+                        return 0;
+                } else
+                    c->buffer_ptr += len;
+
+                c->data_count += len;
+                update_datarate(&c->datarate, c->data_count);
+                if (c->stream)
+                    c->stream->bytes_served += len;
+                break;
+            }
+        }
+    } /* for(;;) */
+    return 0;
+}
+
+static int http_start_receive_data(HTTPContext *c)
+{
+    int fd;
+
+    if (c->stream->feed_opened)
+        return -1;
+
+    /* Don't permit writing to this one */
+    if (c->stream->readonly)
+        return -1;
+
+    /* open feed */
+    fd = open(c->stream->feed_filename, O_RDWR);
+    if (fd < 0) {
+        http_log("Error opening feeder file: %s\n", strerror(errno));
+        return -1;
+    }
+    c->feed_fd = fd;
+
+    if (c->stream->truncate) {
+        /* truncate feed file */
+        ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE);
+        http_log("Truncating feed file '%s'\n", c->stream->feed_filename);
+        if (ftruncate(c->feed_fd, FFM_PACKET_SIZE) < 0) {
+            http_log("Error truncating feed file: %s\n", strerror(errno));
+            return -1;
+        }
+    } else {
+        if ((c->stream->feed_write_index = ffm_read_write_index(fd)) < 0) {
+            http_log("Error reading write index from feed file: %s\n", strerror(errno));
+            return -1;
+        }
+    }
+
+    c->stream->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
+    c->stream->feed_size = lseek(fd, 0, SEEK_END);
+    lseek(fd, 0, SEEK_SET);
+
+    /* init buffer input */
+    c->buffer_ptr = c->buffer;
+    c->buffer_end = c->buffer + FFM_PACKET_SIZE;
+    c->stream->feed_opened = 1;
+    c->chunked_encoding = !!av_stristr(c->buffer, "Transfer-Encoding: chunked");
+    return 0;
+}
+
+static int http_receive_data(HTTPContext *c)
+{
+    HTTPContext *c1;
+    int len, loop_run = 0;
+
+    while (c->chunked_encoding && !c->chunk_size &&
+           c->buffer_end > c->buffer_ptr) {
+        /* read chunk header, if present */
+        len = recv(c->fd, c->buffer_ptr, 1, 0);
+
+        if (len < 0) {
+            if (ff_neterrno() != AVERROR(EAGAIN) &&
+                ff_neterrno() != AVERROR(EINTR))
+                /* error : close connection */
+                goto fail;
+            return 0;
+        } else if (len == 0) {
+            /* end of connection : close it */
+            goto fail;
+        } else if (c->buffer_ptr - c->buffer >= 2 &&
+                   !memcmp(c->buffer_ptr - 1, "\r\n", 2)) {
+            c->chunk_size = strtol(c->buffer, 0, 16);
+            if (c->chunk_size == 0) // end of stream
+                goto fail;
+            c->buffer_ptr = c->buffer;
+            break;
+        } else if (++loop_run > 10) {
+            /* no chunk header, abort */
+            goto fail;
+        } else {
+            c->buffer_ptr++;
+        }
+    }
+
+    if (c->buffer_end > c->buffer_ptr) {
+        len = recv(c->fd, c->buffer_ptr,
+                   FFMIN(c->chunk_size, c->buffer_end - c->buffer_ptr), 0);
+        if (len < 0) {
+            if (ff_neterrno() != AVERROR(EAGAIN) &&
+                ff_neterrno() != AVERROR(EINTR))
+                /* error : close connection */
+                goto fail;
+        } else if (len == 0)
+            /* end of connection : close it */
+            goto fail;
+        else {
+            c->chunk_size -= len;
+            c->buffer_ptr += len;
+            c->data_count += len;
+            update_datarate(&c->datarate, c->data_count);
+        }
+    }
+
+    if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) {
+        if (c->buffer[0] != 'f' ||
+            c->buffer[1] != 'm') {
+            http_log("Feed stream has become desynchronized -- disconnecting\n");
+            goto fail;
+        }
+    }
+
+    if (c->buffer_ptr >= c->buffer_end) {
+        FFStream *feed = c->stream;
+        /* a packet has been received : write it in the store, except
+           if header */
+        if (c->data_count > FFM_PACKET_SIZE) {
+            /* XXX: use llseek or url_seek */
+            lseek(c->feed_fd, feed->feed_write_index, SEEK_SET);
+            if (write(c->feed_fd, c->buffer, FFM_PACKET_SIZE) < 0) {
+                http_log("Error writing to feed file: %s\n", strerror(errno));
+                goto fail;
+            }
+
+            feed->feed_write_index += FFM_PACKET_SIZE;
+            /* update file size */
+            if (feed->feed_write_index > c->stream->feed_size)
+                feed->feed_size = feed->feed_write_index;
+
+            /* handle wrap around if max file size reached */
+            if (c->stream->feed_max_size && feed->feed_write_index >= c->stream->feed_max_size)
+                feed->feed_write_index = FFM_PACKET_SIZE;
+
+            /* write index */
+            if (ffm_write_write_index(c->feed_fd, feed->feed_write_index) < 0) {
+                http_log("Error writing index to feed file: %s\n", strerror(errno));
+                goto fail;
+            }
+
+            /* wake up any waiting connections */
+            for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
+                if (c1->state == HTTPSTATE_WAIT_FEED &&
+                    c1->stream->feed == c->stream->feed)
+                    c1->state = HTTPSTATE_SEND_DATA;
+            }
+        } else {
+            /* We have a header in our hands that contains useful data */
+            AVFormatContext *s = avformat_alloc_context();
+            AVIOContext *pb;
+            AVInputFormat *fmt_in;
+            int i;
+
+            if (!s)
+                goto fail;
+
+            /* use feed output format name to find corresponding input format */
+            fmt_in = av_find_input_format(feed->fmt->name);
+            if (!fmt_in)
+                goto fail;
+
+            pb = avio_alloc_context(c->buffer, c->buffer_end - c->buffer,
+                                    0, NULL, NULL, NULL, NULL);
+            pb->seekable = 0;
+
+            s->pb = pb;
+            if (avformat_open_input(&s, c->stream->feed_filename, fmt_in, NULL) < 0) {
+                av_free(pb);
+                goto fail;
+            }
+
+            /* Now we have the actual streams */
+            if (s->nb_streams != feed->nb_streams) {
+                avformat_close_input(&s);
+                av_free(pb);
+                http_log("Feed '%s' stream number does not match registered feed\n",
+                         c->stream->feed_filename);
+                goto fail;
+            }
+
+            for (i = 0; i < s->nb_streams; i++) {
+                AVStream *fst = feed->streams[i];
+                AVStream *st = s->streams[i];
+                avcodec_copy_context(fst->codec, st->codec);
+            }
+
+            avformat_close_input(&s);
+            av_free(pb);
+        }
+        c->buffer_ptr = c->buffer;
+    }
+
+    return 0;
+ fail:
+    c->stream->feed_opened = 0;
+    close(c->feed_fd);
+    /* wake up any waiting connections to stop waiting for feed */
+    for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
+        if (c1->state == HTTPSTATE_WAIT_FEED &&
+            c1->stream->feed == c->stream->feed)
+            c1->state = HTTPSTATE_SEND_DATA_TRAILER;
+    }
+    return -1;
+}
+
+/********************************************************************/
+/* RTSP handling */
+
+static void rtsp_reply_header(HTTPContext *c, enum RTSPStatusCode error_number)
+{
+    const char *str;
+    time_t ti;
+    struct tm *tm;
+    char buf2[32];
+
+    switch(error_number) {
+    case RTSP_STATUS_OK:
+        str = "OK";
+        break;
+    case RTSP_STATUS_METHOD:
+        str = "Method Not Allowed";
+        break;
+    case RTSP_STATUS_BANDWIDTH:
+        str = "Not Enough Bandwidth";
+        break;
+    case RTSP_STATUS_SESSION:
+        str = "Session Not Found";
+        break;
+    case RTSP_STATUS_STATE:
+        str = "Method Not Valid in This State";
+        break;
+    case RTSP_STATUS_AGGREGATE:
+        str = "Aggregate operation not allowed";
+        break;
+    case RTSP_STATUS_ONLY_AGGREGATE:
+        str = "Only aggregate operation allowed";
+        break;
+    case RTSP_STATUS_TRANSPORT:
+        str = "Unsupported transport";
+        break;
+    case RTSP_STATUS_INTERNAL:
+        str = "Internal Server Error";
+        break;
+    case RTSP_STATUS_SERVICE:
+        str = "Service Unavailable";
+        break;
+    case RTSP_STATUS_VERSION:
+        str = "RTSP Version not supported";
+        break;
+    default:
+        str = "Unknown Error";
+        break;
+    }
+
+    avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", error_number, str);
+    avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
+
+    /* output GMT time */
+    ti = time(NULL);
+    tm = gmtime(&ti);
+    strftime(buf2, sizeof(buf2), "%a, %d %b %Y %H:%M:%S", tm);
+    avio_printf(c->pb, "Date: %s GMT\r\n", buf2);
+}
+
+static void rtsp_reply_error(HTTPContext *c, enum RTSPStatusCode error_number)
+{
+    rtsp_reply_header(c, error_number);
+    avio_printf(c->pb, "\r\n");
+}
+
+static int rtsp_parse_request(HTTPContext *c)
+{
+    const char *p, *p1, *p2;
+    char cmd[32];
+    char url[1024];
+    char protocol[32];
+    char line[1024];
+    int len;
+    RTSPMessageHeader header1 = { 0 }, *header = &header1;
+
+    c->buffer_ptr[0] = '\0';
+    p = c->buffer;
+
+    get_word(cmd, sizeof(cmd), &p);
+    get_word(url, sizeof(url), &p);
+    get_word(protocol, sizeof(protocol), &p);
+
+    av_strlcpy(c->method, cmd, sizeof(c->method));
+    av_strlcpy(c->url, url, sizeof(c->url));
+    av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
+
+    if (avio_open_dyn_buf(&c->pb) < 0) {
+        /* XXX: cannot do more */
+        c->pb = NULL; /* safety */
+        return -1;
+    }
+
+    /* check version name */
+    if (strcmp(protocol, "RTSP/1.0") != 0) {
+        rtsp_reply_error(c, RTSP_STATUS_VERSION);
+        goto the_end;
+    }
+
+    /* parse each header line */
+    /* skip to next line */
+    while (*p != '\n' && *p != '\0')
+        p++;
+    if (*p == '\n')
+        p++;
+    while (*p != '\0') {
+        p1 = memchr(p, '\n', (char *)c->buffer_ptr - p);
+        if (!p1)
+            break;
+        p2 = p1;
+        if (p2 > p && p2[-1] == '\r')
+            p2--;
+        /* skip empty line */
+        if (p2 == p)
+            break;
+        len = p2 - p;
+        if (len > sizeof(line) - 1)
+            len = sizeof(line) - 1;
+        memcpy(line, p, len);
+        line[len] = '\0';
+        ff_rtsp_parse_line(header, line, NULL, NULL);
+        p = p1 + 1;
+    }
+
+    /* handle sequence number */
+    c->seq = header->seq;
+
+    if (!strcmp(cmd, "DESCRIBE"))
+        rtsp_cmd_describe(c, url);
+    else if (!strcmp(cmd, "OPTIONS"))
+        rtsp_cmd_options(c, url);
+    else if (!strcmp(cmd, "SETUP"))
+        rtsp_cmd_setup(c, url, header);
+    else if (!strcmp(cmd, "PLAY"))
+        rtsp_cmd_play(c, url, header);
+    else if (!strcmp(cmd, "PAUSE"))
+        rtsp_cmd_pause(c, url, header);
+    else if (!strcmp(cmd, "TEARDOWN"))
+        rtsp_cmd_teardown(c, url, header);
+    else
+        rtsp_reply_error(c, RTSP_STATUS_METHOD);
+
+ the_end:
+    len = avio_close_dyn_buf(c->pb, &c->pb_buffer);
+    c->pb = NULL; /* safety */
+    if (len < 0) {
+        /* XXX: cannot do more */
+        return -1;
+    }
+    c->buffer_ptr = c->pb_buffer;
+    c->buffer_end = c->pb_buffer + len;
+    c->state = RTSPSTATE_SEND_REPLY;
+    return 0;
+}
+
+static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
+                                   struct in_addr my_ip)
+{
+    AVFormatContext *avc;
+    AVStream *avs = NULL;
+    int i;
+
+    avc =  avformat_alloc_context();
+    if (avc == NULL) {
+        return -1;
+    }
+    av_dict_set(&avc->metadata, "title",
+               stream->title[0] ? stream->title : "No Title", 0);
+    avc->nb_streams = stream->nb_streams;
+    if (stream->is_multicast) {
+        snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
+                 inet_ntoa(stream->multicast_ip),
+                 stream->multicast_port, stream->multicast_ttl);
+    } else {
+        snprintf(avc->filename, 1024, "rtp://0.0.0.0");
+    }
+
+    if (avc->nb_streams >= INT_MAX/sizeof(*avc->streams) ||
+        !(avc->streams = av_malloc(avc->nb_streams * sizeof(*avc->streams))))
+        goto sdp_done;
+    if (avc->nb_streams >= INT_MAX/sizeof(*avs) ||
+        !(avs = av_malloc(avc->nb_streams * sizeof(*avs))))
+        goto sdp_done;
+
+    for(i = 0; i < stream->nb_streams; i++) {
+        avc->streams[i] = &avs[i];
+        avc->streams[i]->codec = stream->streams[i]->codec;
+    }
+    *pbuffer = av_mallocz(2048);
+    av_sdp_create(&avc, 1, *pbuffer, 2048);
+
+ sdp_done:
+    av_free(avc->streams);
+    av_dict_free(&avc->metadata);
+    av_free(avc);
+    av_free(avs);
+
+    return strlen(*pbuffer);
+}
+
+static void rtsp_cmd_options(HTTPContext *c, const char *url)
+{
+//    rtsp_reply_header(c, RTSP_STATUS_OK);
+    avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", RTSP_STATUS_OK, "OK");
+    avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
+    avio_printf(c->pb, "Public: %s\r\n", "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE");
+    avio_printf(c->pb, "\r\n");
+}
+
+static void rtsp_cmd_describe(HTTPContext *c, const char *url)
+{
+    FFStream *stream;
+    char path1[1024];
+    const char *path;
+    uint8_t *content;
+    int content_length, len;
+    struct sockaddr_in my_addr;
+
+    /* find which url is asked */
+    av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
+    path = path1;
+    if (*path == '/')
+        path++;
+
+    for(stream = first_stream; stream != NULL; stream = stream->next) {
+        if (!stream->is_feed &&
+            stream->fmt && !strcmp(stream->fmt->name, "rtp") &&
+            !strcmp(path, stream->filename)) {
+            goto found;
+        }
+    }
+    /* no stream found */
+    rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
+    return;
+
+ found:
+    /* prepare the media description in sdp format */
+
+    /* get the host IP */
+    len = sizeof(my_addr);
+    getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
+    content_length = prepare_sdp_description(stream, &content, my_addr.sin_addr);
+    if (content_length < 0) {
+        rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
+        return;
+    }
+    rtsp_reply_header(c, RTSP_STATUS_OK);
+    avio_printf(c->pb, "Content-Base: %s/\r\n", url);
+    avio_printf(c->pb, "Content-Type: application/sdp\r\n");
+    avio_printf(c->pb, "Content-Length: %d\r\n", content_length);
+    avio_printf(c->pb, "\r\n");
+    avio_write(c->pb, content, content_length);
+    av_free(content);
+}
+
+static HTTPContext *find_rtp_session(const char *session_id)
+{
+    HTTPContext *c;
+
+    if (session_id[0] == '\0')
+        return NULL;
+
+    for(c = first_http_ctx; c != NULL; c = c->next) {
+        if (!strcmp(c->session_id, session_id))
+            return c;
+    }
+    return NULL;
+}
+
+static RTSPTransportField *find_transport(RTSPMessageHeader *h, enum RTSPLowerTransport lower_transport)
+{
+    RTSPTransportField *th;
+    int i;
+
+    for(i=0;i<h->nb_transports;i++) {
+        th = &h->transports[i];
+        if (th->lower_transport == lower_transport)
+            return th;
+    }
+    return NULL;
+}
+
+static void rtsp_cmd_setup(HTTPContext *c, const char *url,
+                           RTSPMessageHeader *h)
+{
+    FFStream *stream;
+    int stream_index, rtp_port, rtcp_port;
+    char buf[1024];
+    char path1[1024];
+    const char *path;
+    HTTPContext *rtp_c;
+    RTSPTransportField *th;
+    struct sockaddr_in dest_addr;
+    RTSPActionServerSetup setup;
+
+    /* find which url is asked */
+    av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
+    path = path1;
+    if (*path == '/')
+        path++;
+
+    /* now check each stream */
+    for(stream = first_stream; stream != NULL; stream = stream->next) {
+        if (!stream->is_feed &&
+            stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
+            /* accept aggregate filenames only if single stream */
+            if (!strcmp(path, stream->filename)) {
+                if (stream->nb_streams != 1) {
+                    rtsp_reply_error(c, RTSP_STATUS_AGGREGATE);
+                    return;
+                }
+                stream_index = 0;
+                goto found;
+            }
+
+            for(stream_index = 0; stream_index < stream->nb_streams;
+                stream_index++) {
+                snprintf(buf, sizeof(buf), "%s/streamid=%d",
+                         stream->filename, stream_index);
+                if (!strcmp(path, buf))
+                    goto found;
+            }
+        }
+    }
+    /* no stream found */
+    rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
+    return;
+ found:
+
+    /* generate session id if needed */
+    if (h->session_id[0] == '\0') {
+        unsigned random0 = av_lfg_get(&random_state);
+        unsigned random1 = av_lfg_get(&random_state);
+        snprintf(h->session_id, sizeof(h->session_id), "%08x%08x",
+                 random0, random1);
+    }
+
+    /* find rtp session, and create it if none found */
+    rtp_c = find_rtp_session(h->session_id);
+    if (!rtp_c) {
+        /* always prefer UDP */
+        th = find_transport(h, RTSP_LOWER_TRANSPORT_UDP);
+        if (!th) {
+            th = find_transport(h, RTSP_LOWER_TRANSPORT_TCP);
+            if (!th) {
+                rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
+                return;
+            }
+        }
+
+        rtp_c = rtp_new_connection(&c->from_addr, stream, h->session_id,
+                                   th->lower_transport);
+        if (!rtp_c) {
+            rtsp_reply_error(c, RTSP_STATUS_BANDWIDTH);
+            return;
+        }
+
+        /* open input stream */
+        if (open_input_stream(rtp_c, "") < 0) {
+            rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
+            return;
+        }
+    }
+
+    /* test if stream is OK (test needed because several SETUP needs
+       to be done for a given file) */
+    if (rtp_c->stream != stream) {
+        rtsp_reply_error(c, RTSP_STATUS_SERVICE);
+        return;
+    }
+
+    /* test if stream is already set up */
+    if (rtp_c->rtp_ctx[stream_index]) {
+        rtsp_reply_error(c, RTSP_STATUS_STATE);
+        return;
+    }
+
+    /* check transport */
+    th = find_transport(h, rtp_c->rtp_protocol);
+    if (!th || (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
+                th->client_port_min <= 0)) {
+        rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
+        return;
+    }
+
+    /* setup default options */
+    setup.transport_option[0] = '\0';
+    dest_addr = rtp_c->from_addr;
+    dest_addr.sin_port = htons(th->client_port_min);
+
+    /* setup stream */
+    if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, c) < 0) {
+        rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
+        return;
+    }
+
+    /* now everything is OK, so we can send the connection parameters */
+    rtsp_reply_header(c, RTSP_STATUS_OK);
+    /* session ID */
+    avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
+
+    switch(rtp_c->rtp_protocol) {
+    case RTSP_LOWER_TRANSPORT_UDP:
+        rtp_port = ff_rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]);
+        rtcp_port = ff_rtp_get_local_rtcp_port(rtp_c->rtp_handles[stream_index]);
+        avio_printf(c->pb, "Transport: RTP/AVP/UDP;unicast;"
+                    "client_port=%d-%d;server_port=%d-%d",
+                    th->client_port_min, th->client_port_max,
+                    rtp_port, rtcp_port);
+        break;
+    case RTSP_LOWER_TRANSPORT_TCP:
+        avio_printf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",
+                    stream_index * 2, stream_index * 2 + 1);
+        break;
+    default:
+        break;
+    }
+    if (setup.transport_option[0] != '\0')
+        avio_printf(c->pb, ";%s", setup.transport_option);
+    avio_printf(c->pb, "\r\n");
+
+
+    avio_printf(c->pb, "\r\n");
+}
+
+
+/* find an rtp connection by using the session ID. Check consistency
+   with filename */
+static HTTPContext *find_rtp_session_with_url(const char *url,
+                                              const char *session_id)
+{
+    HTTPContext *rtp_c;
+    char path1[1024];
+    const char *path;
+    char buf[1024];
+    int s, len;
+
+    rtp_c = find_rtp_session(session_id);
+    if (!rtp_c)
+        return NULL;
+
+    /* find which url is asked */
+    av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
+    path = path1;
+    if (*path == '/')
+        path++;
+    if(!strcmp(path, rtp_c->stream->filename)) return rtp_c;
+    for(s=0; s<rtp_c->stream->nb_streams; ++s) {
+      snprintf(buf, sizeof(buf), "%s/streamid=%d",
+        rtp_c->stream->filename, s);
+      if(!strncmp(path, buf, sizeof(buf))) {
+    // XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE if nb_streams>1?
+        return rtp_c;
+      }
+    }
+    len = strlen(path);
+    if (len > 0 && path[len - 1] == '/' &&
+        !strncmp(path, rtp_c->stream->filename, len - 1))
+        return rtp_c;
+    return NULL;
+}
+
+static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h)
+{
+    HTTPContext *rtp_c;
+
+    rtp_c = find_rtp_session_with_url(url, h->session_id);
+    if (!rtp_c) {
+        rtsp_reply_error(c, RTSP_STATUS_SESSION);
+        return;
+    }
+
+    if (rtp_c->state != HTTPSTATE_SEND_DATA &&
+        rtp_c->state != HTTPSTATE_WAIT_FEED &&
+        rtp_c->state != HTTPSTATE_READY) {
+        rtsp_reply_error(c, RTSP_STATUS_STATE);
+        return;
+    }
+
+    rtp_c->state = HTTPSTATE_SEND_DATA;
+
+    /* now everything is OK, so we can send the connection parameters */
+    rtsp_reply_header(c, RTSP_STATUS_OK);
+    /* session ID */
+    avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
+    avio_printf(c->pb, "\r\n");
+}
+
+static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h)
+{
+    HTTPContext *rtp_c;
+
+    rtp_c = find_rtp_session_with_url(url, h->session_id);
+    if (!rtp_c) {
+        rtsp_reply_error(c, RTSP_STATUS_SESSION);
+        return;
+    }
+
+    if (rtp_c->state != HTTPSTATE_SEND_DATA &&
+        rtp_c->state != HTTPSTATE_WAIT_FEED) {
+        rtsp_reply_error(c, RTSP_STATUS_STATE);
+        return;
+    }
+
+    rtp_c->state = HTTPSTATE_READY;
+    rtp_c->first_pts = AV_NOPTS_VALUE;
+    /* now everything is OK, so we can send the connection parameters */
+    rtsp_reply_header(c, RTSP_STATUS_OK);
+    /* session ID */
+    avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
+    avio_printf(c->pb, "\r\n");
+}
+
+static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h)
+{
+    HTTPContext *rtp_c;
+
+    rtp_c = find_rtp_session_with_url(url, h->session_id);
+    if (!rtp_c) {
+        rtsp_reply_error(c, RTSP_STATUS_SESSION);
+        return;
+    }
+
+    /* now everything is OK, so we can send the connection parameters */
+    rtsp_reply_header(c, RTSP_STATUS_OK);
+    /* session ID */
+    avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
+    avio_printf(c->pb, "\r\n");
+
+    /* abort the session */
+    close_connection(rtp_c);
+}
+
+
+/********************************************************************/
+/* RTP handling */
+
+static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
+                                       FFStream *stream, const char *session_id,
+                                       enum RTSPLowerTransport rtp_protocol)
+{
+    HTTPContext *c = NULL;
+    const char *proto_str;
+
+    /* XXX: should output a warning page when coming
+       close to the connection limit */
+    if (nb_connections >= nb_max_connections)
+        goto fail;
+
+    /* add a new connection */
+    c = av_mallocz(sizeof(HTTPContext));
+    if (!c)
+        goto fail;
+
+    c->fd = -1;
+    c->poll_entry = NULL;
+    c->from_addr = *from_addr;
+    c->buffer_size = IOBUFFER_INIT_SIZE;
+    c->buffer = av_malloc(c->buffer_size);
+    if (!c->buffer)
+        goto fail;
+    nb_connections++;
+    c->stream = stream;
+    av_strlcpy(c->session_id, session_id, sizeof(c->session_id));
+    c->state = HTTPSTATE_READY;
+    c->is_packetized = 1;
+    c->rtp_protocol = rtp_protocol;
+
+    /* protocol is shown in statistics */
+    switch(c->rtp_protocol) {
+    case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
+        proto_str = "MCAST";
+        break;
+    case RTSP_LOWER_TRANSPORT_UDP:
+        proto_str = "UDP";
+        break;
+    case RTSP_LOWER_TRANSPORT_TCP:
+        proto_str = "TCP";
+        break;
+    default:
+        proto_str = "???";
+        break;
+    }
+    av_strlcpy(c->protocol, "RTP/", sizeof(c->protocol));
+    av_strlcat(c->protocol, proto_str, sizeof(c->protocol));
+
+    current_bandwidth += stream->bandwidth;
+
+    c->next = first_http_ctx;
+    first_http_ctx = c;
+    return c;
+
+ fail:
+    if (c) {
+        av_free(c->buffer);
+        av_free(c);
+    }
+    return NULL;
+}
+
+/* add a new RTP stream in an RTP connection (used in RTSP SETUP
+   command). If RTP/TCP protocol is used, TCP connection 'rtsp_c' is
+   used. */
+static int rtp_new_av_stream(HTTPContext *c,
+                             int stream_index, struct sockaddr_in *dest_addr,
+                             HTTPContext *rtsp_c)
+{
+    AVFormatContext *ctx;
+    AVStream *st;
+    char *ipaddr;
+    URLContext *h = NULL;
+    uint8_t *dummy_buf;
+    int max_packet_size;
+
+    /* now we can open the relevant output stream */
+    ctx = avformat_alloc_context();
+    if (!ctx)
+        return -1;
+    ctx->oformat = av_guess_format("rtp", NULL, NULL);
+
+    st = av_mallocz(sizeof(AVStream));
+    if (!st)
+        goto fail;
+    ctx->nb_streams = 1;
+    ctx->streams = av_mallocz(sizeof(AVStream *) * ctx->nb_streams);
+    if (!ctx->streams)
+      goto fail;
+    ctx->streams[0] = st;
+
+    if (!c->stream->feed ||
+        c->stream->feed == c->stream)
+        memcpy(st, c->stream->streams[stream_index], sizeof(AVStream));
+    else
+        memcpy(st,
+               c->stream->feed->streams[c->stream->feed_streams[stream_index]],
+               sizeof(AVStream));
+    st->priv_data = NULL;
+
+    /* build destination RTP address */
+    ipaddr = inet_ntoa(dest_addr->sin_addr);
+
+    switch(c->rtp_protocol) {
+    case RTSP_LOWER_TRANSPORT_UDP:
+    case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
+        /* RTP/UDP case */
+
+        /* XXX: also pass as parameter to function ? */
+        if (c->stream->is_multicast) {
+            int ttl;
+            ttl = c->stream->multicast_ttl;
+            if (!ttl)
+                ttl = 16;
+            snprintf(ctx->filename, sizeof(ctx->filename),
+                     "rtp://%s:%d?multicast=1&ttl=%d",
+                     ipaddr, ntohs(dest_addr->sin_port), ttl);
+        } else {
+            snprintf(ctx->filename, sizeof(ctx->filename),
+                     "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port));
+        }
+
+        if (ffurl_open(&h, ctx->filename, AVIO_FLAG_WRITE, NULL, NULL) < 0)
+            goto fail;
+        c->rtp_handles[stream_index] = h;
+        max_packet_size = h->max_packet_size;
+        break;
+    case RTSP_LOWER_TRANSPORT_TCP:
+        /* RTP/TCP case */
+        c->rtsp_c = rtsp_c;
+        max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
+        break;
+    default:
+        goto fail;
+    }
+
+    http_log("%s:%d - - \"PLAY %s/streamid=%d %s\"\n",
+             ipaddr, ntohs(dest_addr->sin_port),
+             c->stream->filename, stream_index, c->protocol);
+
+    /* normally, no packets should be output here, but the packet size may be checked */
+    if (ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0) {
+        /* XXX: close stream */
+        goto fail;
+    }
+    if (avformat_write_header(ctx, NULL) < 0) {
+    fail:
+        if (h)
+            ffurl_close(h);
+        av_free(ctx);
+        return -1;
+    }
+    avio_close_dyn_buf(ctx->pb, &dummy_buf);
+    av_free(dummy_buf);
+
+    c->rtp_ctx[stream_index] = ctx;
+    return 0;
+}
+
+/********************************************************************/
+/* ffserver initialization */
+
+static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int copy)
+{
+    AVStream *fst;
+
+    if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams))
+        return NULL;
+
+    fst = av_mallocz(sizeof(AVStream));
+    if (!fst)
+        return NULL;
+    if (copy) {
+        fst->codec = avcodec_alloc_context3(NULL);
+        memcpy(fst->codec, codec, sizeof(AVCodecContext));
+        if (codec->extradata_size) {
+            fst->codec->extradata = av_malloc(codec->extradata_size);
+            memcpy(fst->codec->extradata, codec->extradata,
+                codec->extradata_size);
+        }
+    } else {
+        /* live streams must use the actual feed's codec since it may be
+         * updated later to carry extradata needed by the streams.
+         */
+        fst->codec = codec;
+    }
+    fst->priv_data = av_mallocz(sizeof(FeedData));
+    fst->index = stream->nb_streams;
+    avpriv_set_pts_info(fst, 33, 1, 90000);
+    fst->sample_aspect_ratio = codec->sample_aspect_ratio;
+    stream->streams[stream->nb_streams++] = fst;
+    return fst;
+}
+
+/* return the stream number in the feed */
+static int add_av_stream(FFStream *feed, AVStream *st)
+{
+    AVStream *fst;
+    AVCodecContext *av, *av1;
+    int i;
+
+    av = st->codec;
+    for(i=0;i<feed->nb_streams;i++) {
+        st = feed->streams[i];
+        av1 = st->codec;
+        if (av1->codec_id == av->codec_id &&
+            av1->codec_type == av->codec_type &&
+            av1->bit_rate == av->bit_rate) {
+
+            switch(av->codec_type) {
+            case AVMEDIA_TYPE_AUDIO:
+                if (av1->channels == av->channels &&
+                    av1->sample_rate == av->sample_rate)
+                    return i;
+                break;
+            case AVMEDIA_TYPE_VIDEO:
+                if (av1->width == av->width &&
+                    av1->height == av->height &&
+                    av1->time_base.den == av->time_base.den &&
+                    av1->time_base.num == av->time_base.num &&
+                    av1->gop_size == av->gop_size)
+                    return i;
+                break;
+            default:
+                abort();
+            }
+        }
+    }
+
+    fst = add_av_stream1(feed, av, 0);
+    if (!fst)
+        return -1;
+    return feed->nb_streams - 1;
+}
+
+static void remove_stream(FFStream *stream)
+{
+    FFStream **ps;
+    ps = &first_stream;
+    while (*ps != NULL) {
+        if (*ps == stream)
+            *ps = (*ps)->next;
+        else
+            ps = &(*ps)->next;
+    }
+}
+
+/* specific mpeg4 handling : we extract the raw parameters */
+static void extract_mpeg4_header(AVFormatContext *infile)
+{
+    int mpeg4_count, i, size;
+    AVPacket pkt;
+    AVStream *st;
+    const uint8_t *p;
+
+    mpeg4_count = 0;
+    for(i=0;i<infile->nb_streams;i++) {
+        st = infile->streams[i];
+        if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
+            st->codec->extradata_size == 0) {
+            mpeg4_count++;
+        }
+    }
+    if (!mpeg4_count)
+        return;
+
+    printf("MPEG4 without extra data: trying to find header in %s\n", infile->filename);
+    while (mpeg4_count > 0) {
+        if (av_read_packet(infile, &pkt) < 0)
+            break;
+        st = infile->streams[pkt.stream_index];
+        if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
+            st->codec->extradata_size == 0) {
+            av_freep(&st->codec->extradata);
+            /* fill extradata with the header */
+            /* XXX: we make hard suppositions here ! */
+            p = pkt.data;
+            while (p < pkt.data + pkt.size - 4) {
+                /* stop when vop header is found */
+                if (p[0] == 0x00 && p[1] == 0x00 &&
+                    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_size = size;
+                    memcpy(st->codec->extradata, pkt.data, size);
+                    break;
+                }
+                p++;
+            }
+            mpeg4_count--;
+        }
+        av_free_packet(&pkt);
+    }
+}
+
+/* compute the needed AVStream for each file */
+static void build_file_streams(void)
+{
+    FFStream *stream, *stream_next;
+    int i, ret;
+
+    /* gather all streams */
+    for(stream = first_stream; stream != NULL; stream = stream_next) {
+        AVFormatContext *infile = NULL;
+        stream_next = stream->next;
+        if (stream->stream_type == STREAM_TYPE_LIVE &&
+            !stream->feed) {
+            /* the stream comes from a file */
+            /* try to open the file */
+            /* open stream */
+            if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
+                /* specific case : if transport stream output to RTP,
+                   we use a raw transport stream reader */
+                av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0);
+            }
+
+            http_log("Opening file '%s'\n", stream->feed_filename);
+            if ((ret = avformat_open_input(&infile, stream->feed_filename, stream->ifmt, &stream->in_opts)) < 0) {
+                http_log("Could not open '%s': %d\n", stream->feed_filename, ret);
+                /* remove stream (no need to spend more time on it) */
+            fail:
+                remove_stream(stream);
+            } else {
+                /* find all the AVStreams inside and reference them in
+                   'stream' */
+                if (avformat_find_stream_info(infile, NULL) < 0) {
+                    http_log("Could not find codec parameters from '%s'\n",
+                             stream->feed_filename);
+                    avformat_close_input(&infile);
+                    goto fail;
+                }
+                extract_mpeg4_header(infile);
+
+                for(i=0;i<infile->nb_streams;i++)
+                    add_av_stream1(stream, infile->streams[i]->codec, 1);
+
+                avformat_close_input(&infile);
+            }
+        }
+    }
+}
+
+/* compute the needed AVStream for each feed */
+static void build_feed_streams(void)
+{
+    FFStream *stream, *feed;
+    int i;
+
+    /* gather all streams */
+    for(stream = first_stream; stream != NULL; stream = stream->next) {
+        feed = stream->feed;
+        if (feed) {
+            if (stream->is_feed) {
+                for(i=0;i<stream->nb_streams;i++)
+                    stream->feed_streams[i] = i;
+            } else {
+                /* we handle a stream coming from a feed */
+                for(i=0;i<stream->nb_streams;i++)
+                    stream->feed_streams[i] = add_av_stream(feed, stream->streams[i]);
+            }
+        }
+    }
+
+    /* create feed files if needed */
+    for(feed = first_feed; feed != NULL; feed = feed->next_feed) {
+        int fd;
+
+        if (avio_check(feed->feed_filename, AVIO_FLAG_READ) > 0) {
+            /* See if it matches */
+            AVFormatContext *s = NULL;
+            int matches = 0;
+
+            if (avformat_open_input(&s, feed->feed_filename, NULL, NULL) >= 0) {
+                /* set buffer size */
+                ffio_set_buf_size(s->pb, FFM_PACKET_SIZE);
+                /* Now see if it matches */
+                if (s->nb_streams == feed->nb_streams) {
+                    matches = 1;
+                    for(i=0;i<s->nb_streams;i++) {
+                        AVStream *sf, *ss;
+                        sf = feed->streams[i];
+                        ss = s->streams[i];
+
+                        if (sf->index != ss->index ||
+                            sf->id != ss->id) {
+                            http_log("Index & Id do not match for stream %d (%s)\n",
+                                   i, feed->feed_filename);
+                            matches = 0;
+                        } else {
+                            AVCodecContext *ccf, *ccs;
+
+                            ccf = sf->codec;
+                            ccs = ss->codec;
+#define CHECK_CODEC(x)  (ccf->x != ccs->x)
+
+                            if (CHECK_CODEC(codec_id) || CHECK_CODEC(codec_type)) {
+                                http_log("Codecs do not match for stream %d\n", i);
+                                matches = 0;
+                            } else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) {
+                                http_log("Codec bitrates do not match for stream %d\n", i);
+                                matches = 0;
+                            } else if (ccf->codec_type == AVMEDIA_TYPE_VIDEO) {
+                                if (CHECK_CODEC(time_base.den) ||
+                                    CHECK_CODEC(time_base.num) ||
+                                    CHECK_CODEC(width) ||
+                                    CHECK_CODEC(height)) {
+                                    http_log("Codec width, height and framerate do not match for stream %d\n", i);
+                                    matches = 0;
+                                }
+                            } else if (ccf->codec_type == AVMEDIA_TYPE_AUDIO) {
+                                if (CHECK_CODEC(sample_rate) ||
+                                    CHECK_CODEC(channels) ||
+                                    CHECK_CODEC(frame_size)) {
+                                    http_log("Codec sample_rate, channels, frame_size do not match for stream %d\n", i);
+                                    matches = 0;
+                                }
+                            } else {
+                                http_log("Unknown codec type\n");
+                                matches = 0;
+                            }
+                        }
+                        if (!matches)
+                            break;
+                    }
+                } else
+                    http_log("Deleting feed file '%s' as stream counts differ (%d != %d)\n",
+                        feed->feed_filename, s->nb_streams, feed->nb_streams);
+
+                avformat_close_input(&s);
+            } else
+                http_log("Deleting feed file '%s' as it appears to be corrupt\n",
+                        feed->feed_filename);
+
+            if (!matches) {
+                if (feed->readonly) {
+                    http_log("Unable to delete feed file '%s' as it is marked readonly\n",
+                        feed->feed_filename);
+                    exit(1);
+                }
+                unlink(feed->feed_filename);
+            }
+        }
+        if (avio_check(feed->feed_filename, AVIO_FLAG_WRITE) <= 0) {
+            AVFormatContext s1 = {0}, *s = &s1;
+
+            if (feed->readonly) {
+                http_log("Unable to create feed file '%s' as it is marked readonly\n",
+                    feed->feed_filename);
+                exit(1);
+            }
+
+            /* only write the header of the ffm file */
+            if (avio_open(&s->pb, feed->feed_filename, AVIO_FLAG_WRITE) < 0) {
+                http_log("Could not open output feed file '%s'\n",
+                         feed->feed_filename);
+                exit(1);
+            }
+            s->oformat = feed->fmt;
+            s->nb_streams = feed->nb_streams;
+            s->streams = feed->streams;
+            if (avformat_write_header(s, NULL) < 0) {
+                http_log("Container doesn't support the required parameters\n");
+                exit(1);
+            }
+            /* XXX: need better api */
+            av_freep(&s->priv_data);
+            avio_close(s->pb);
+        }
+        /* get feed size and write index */
+        fd = open(feed->feed_filename, O_RDONLY);
+        if (fd < 0) {
+            http_log("Could not open output feed file '%s'\n",
+                    feed->feed_filename);
+            exit(1);
+        }
+
+        feed->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
+        feed->feed_size = lseek(fd, 0, SEEK_END);
+        /* ensure that we do not wrap before the end of file */
+        if (feed->feed_max_size && feed->feed_max_size < feed->feed_size)
+            feed->feed_max_size = feed->feed_size;
+
+        close(fd);
+    }
+}
+
+/* compute the bandwidth used by each stream */
+static void compute_bandwidth(void)
+{
+    unsigned bandwidth;
+    int i;
+    FFStream *stream;
+
+    for(stream = first_stream; stream != NULL; stream = stream->next) {
+        bandwidth = 0;
+        for(i=0;i<stream->nb_streams;i++) {
+            AVStream *st = stream->streams[i];
+            switch(st->codec->codec_type) {
+            case AVMEDIA_TYPE_AUDIO:
+            case AVMEDIA_TYPE_VIDEO:
+                bandwidth += st->codec->bit_rate;
+                break;
+            default:
+                break;
+            }
+        }
+        stream->bandwidth = (bandwidth + 999) / 1000;
+    }
+}
+
+/* add a codec and set the default parameters */
+static void add_codec(FFStream *stream, AVCodecContext *av)
+{
+    AVStream *st;
+
+    if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams))
+        return;
+
+    /* compute default parameters */
+    switch(av->codec_type) {
+    case AVMEDIA_TYPE_AUDIO:
+        if (av->bit_rate == 0)
+            av->bit_rate = 64000;
+        if (av->sample_rate == 0)
+            av->sample_rate = 22050;
+        if (av->channels == 0)
+            av->channels = 1;
+        break;
+    case AVMEDIA_TYPE_VIDEO:
+        if (av->bit_rate == 0)
+            av->bit_rate = 64000;
+        if (av->time_base.num == 0){
+            av->time_base.den = 5;
+            av->time_base.num = 1;
+        }
+        if (av->width == 0 || av->height == 0) {
+            av->width = 160;
+            av->height = 128;
+        }
+        /* Bitrate tolerance is less for streaming */
+        if (av->bit_rate_tolerance == 0)
+            av->bit_rate_tolerance = FFMAX(av->bit_rate / 4,
+                      (int64_t)av->bit_rate*av->time_base.num/av->time_base.den);
+        if (av->qmin == 0)
+            av->qmin = 3;
+        if (av->qmax == 0)
+            av->qmax = 31;
+        if (av->max_qdiff == 0)
+            av->max_qdiff = 3;
+        av->qcompress = 0.5;
+        av->qblur = 0.5;
+
+        if (!av->nsse_weight)
+            av->nsse_weight = 8;
+
+        av->frame_skip_cmp = FF_CMP_DCTMAX;
+        if (!av->me_method)
+            av->me_method = ME_EPZS;
+        av->rc_buffer_aggressivity = 1.0;
+
+        if (!av->rc_eq)
+            av->rc_eq = "tex^qComp";
+        if (!av->i_quant_factor)
+            av->i_quant_factor = -0.8;
+        if (!av->b_quant_factor)
+            av->b_quant_factor = 1.25;
+        if (!av->b_quant_offset)
+            av->b_quant_offset = 1.25;
+        if (!av->rc_max_rate)
+            av->rc_max_rate = av->bit_rate * 2;
+
+        if (av->rc_max_rate && !av->rc_buffer_size) {
+            av->rc_buffer_size = av->rc_max_rate;
+        }
+
+
+        break;
+    default:
+        abort();
+    }
+
+    st = av_mallocz(sizeof(AVStream));
+    if (!st)
+        return;
+    st->codec = avcodec_alloc_context3(NULL);
+    stream->streams[stream->nb_streams++] = st;
+    memcpy(st->codec, av, sizeof(AVCodecContext));
+}
+
+static enum AVCodecID opt_audio_codec(const char *arg)
+{
+    AVCodec *p= avcodec_find_encoder_by_name(arg);
+
+    if (p == NULL || p->type != AVMEDIA_TYPE_AUDIO)
+        return AV_CODEC_ID_NONE;
+
+    return p->id;
+}
+
+static enum AVCodecID opt_video_codec(const char *arg)
+{
+    AVCodec *p= avcodec_find_encoder_by_name(arg);
+
+    if (p == NULL || p->type != AVMEDIA_TYPE_VIDEO)
+        return AV_CODEC_ID_NONE;
+
+    return p->id;
+}
+
+/* simplistic plugin support */
+
+#if HAVE_DLOPEN
+static void load_module(const char *filename)
+{
+    void *dll;
+    void (*init_func)(void);
+    dll = dlopen(filename, RTLD_NOW);
+    if (!dll) {
+        fprintf(stderr, "Could not load module '%s' - %s\n",
+                filename, dlerror());
+        return;
+    }
+
+    init_func = dlsym(dll, "ffserver_module_init");
+    if (!init_func) {
+        fprintf(stderr,
+                "%s: init function 'ffserver_module_init()' not found\n",
+                filename);
+        dlclose(dll);
+    }
+
+    init_func();
+}
+#endif
+
+static int ffserver_opt_default(const char *opt, const char *arg,
+                       AVCodecContext *avctx, int type)
+{
+    int ret = 0;
+    const AVOption *o = av_opt_find(avctx, opt, NULL, type, 0);
+    if(o)
+        ret = av_opt_set(avctx, opt, arg, 0);
+    return ret;
+}
+
+static int ffserver_opt_preset(const char *arg,
+                       AVCodecContext *avctx, int type,
+                       enum AVCodecID *audio_id, enum AVCodecID *video_id)
+{
+    FILE *f=NULL;
+    char filename[1000], tmp[1000], tmp2[1000], line[1000];
+    int ret = 0;
+    AVCodec *codec = avcodec_find_encoder(avctx->codec_id);
+
+    if (!(f = get_preset_file(filename, sizeof(filename), arg, 0,
+                              codec ? codec->name : NULL))) {
+        fprintf(stderr, "File for preset '%s' not found\n", arg);
+        return 1;
+    }
+
+    while(!feof(f)){
+        int e= fscanf(f, "%999[^\n]\n", line) - 1;
+        if(line[0] == '#' && !e)
+            continue;
+        e|= sscanf(line, "%999[^=]=%999[^\n]\n", tmp, tmp2) - 2;
+        if(e){
+            fprintf(stderr, "%s: Invalid syntax: '%s'\n", filename, line);
+            ret = 1;
+            break;
+        }
+        if(!strcmp(tmp, "acodec")){
+            *audio_id = opt_audio_codec(tmp2);
+        }else if(!strcmp(tmp, "vcodec")){
+            *video_id = opt_video_codec(tmp2);
+        }else if(!strcmp(tmp, "scodec")){
+            /* opt_subtitle_codec(tmp2); */
+        }else if(ffserver_opt_default(tmp, tmp2, avctx, type) < 0){
+            fprintf(stderr, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n", filename, line, tmp, tmp2);
+            ret = 1;
+            break;
+        }
+    }
+
+    fclose(f);
+
+    return ret;
+}
+
+static AVOutputFormat *ffserver_guess_format(const char *short_name, const char *filename,
+                                             const char *mime_type)
+{
+    AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type);
+
+    if (fmt) {
+        AVOutputFormat *stream_fmt;
+        char stream_format_name[64];
+
+        snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
+        stream_fmt = av_guess_format(stream_format_name, NULL, NULL);
+
+        if (stream_fmt)
+            fmt = stream_fmt;
+    }
+
+    return fmt;
+}
+
+static void report_config_error(const char *filename, int line_num, int *errors, const char *fmt, ...)
+{
+    va_list vl;
+    va_start(vl, fmt);
+    fprintf(stderr, "%s:%d: ", filename, line_num);
+    vfprintf(stderr, fmt, vl);
+    va_end(vl);
+
+    (*errors)++;
+}
+
+static int parse_ffconfig(const char *filename)
+{
+    FILE *f;
+    char line[1024];
+    char cmd[64];
+    char arg[1024];
+    const char *p;
+    int val, errors, line_num;
+    FFStream **last_stream, *stream, *redirect;
+    FFStream **last_feed, *feed, *s;
+    AVCodecContext audio_enc, video_enc;
+    enum AVCodecID audio_id, video_id;
+
+    f = fopen(filename, "r");
+    if (!f) {
+        perror(filename);
+        return -1;
+    }
+
+    errors = 0;
+    line_num = 0;
+    first_stream = NULL;
+    last_stream = &first_stream;
+    first_feed = NULL;
+    last_feed = &first_feed;
+    stream = NULL;
+    feed = NULL;
+    redirect = NULL;
+    audio_id = AV_CODEC_ID_NONE;
+    video_id = AV_CODEC_ID_NONE;
+
+#define ERROR(...) report_config_error(filename, line_num, &errors, __VA_ARGS__)
+    for(;;) {
+        if (fgets(line, sizeof(line), f) == NULL)
+            break;
+        line_num++;
+        p = line;
+        while (isspace(*p))
+            p++;
+        if (*p == '\0' || *p == '#')
+            continue;
+
+        get_arg(cmd, sizeof(cmd), &p);
+
+        if (!av_strcasecmp(cmd, "Port")) {
+            get_arg(arg, sizeof(arg), &p);
+            val = atoi(arg);
+            if (val < 1 || val > 65536) {
+                ERROR("Invalid_port: %s\n", arg);
+            }
+            my_http_addr.sin_port = htons(val);
+        } else if (!av_strcasecmp(cmd, "BindAddress")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (resolve_host(&my_http_addr.sin_addr, arg) != 0) {
+                ERROR("%s:%d: Invalid host/IP address: %s\n", arg);
+            }
+        } else if (!av_strcasecmp(cmd, "NoDaemon")) {
+            ffserver_daemon = 0;
+        } else if (!av_strcasecmp(cmd, "RTSPPort")) {
+            get_arg(arg, sizeof(arg), &p);
+            val = atoi(arg);
+            if (val < 1 || val > 65536) {
+                ERROR("%s:%d: Invalid port: %s\n", arg);
+            }
+            my_rtsp_addr.sin_port = htons(atoi(arg));
+        } else if (!av_strcasecmp(cmd, "RTSPBindAddress")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (resolve_host(&my_rtsp_addr.sin_addr, arg) != 0) {
+                ERROR("Invalid host/IP address: %s\n", arg);
+            }
+        } else if (!av_strcasecmp(cmd, "MaxHTTPConnections")) {
+            get_arg(arg, sizeof(arg), &p);
+            val = atoi(arg);
+            if (val < 1 || val > 65536) {
+                ERROR("Invalid MaxHTTPConnections: %s\n", arg);
+            }
+            nb_max_http_connections = val;
+        } else if (!av_strcasecmp(cmd, "MaxClients")) {
+            get_arg(arg, sizeof(arg), &p);
+            val = atoi(arg);
+            if (val < 1 || val > nb_max_http_connections) {
+                ERROR("Invalid MaxClients: %s\n", arg);
+            } else {
+                nb_max_connections = val;
+            }
+        } else if (!av_strcasecmp(cmd, "MaxBandwidth")) {
+            int64_t llval;
+            get_arg(arg, sizeof(arg), &p);
+            llval = atoll(arg);
+            if (llval < 10 || llval > 10000000) {
+                ERROR("Invalid MaxBandwidth: %s\n", arg);
+            } else
+                max_bandwidth = llval;
+        } else if (!av_strcasecmp(cmd, "CustomLog")) {
+            if (!ffserver_debug)
+                get_arg(logfilename, sizeof(logfilename), &p);
+        } else if (!av_strcasecmp(cmd, "<Feed")) {
+            /*********************************************/
+            /* Feed related options */
+            char *q;
+            if (stream || feed) {
+                ERROR("Already in a tag\n");
+            } else {
+                feed = av_mallocz(sizeof(FFStream));
+                get_arg(feed->filename, sizeof(feed->filename), &p);
+                q = strrchr(feed->filename, '>');
+                if (*q)
+                    *q = '\0';
+
+                for (s = first_feed; s; s = s->next) {
+                    if (!strcmp(feed->filename, s->filename)) {
+                        ERROR("Feed '%s' already registered\n", s->filename);
+                    }
+                }
+
+                feed->fmt = av_guess_format("ffm", NULL, NULL);
+                /* defaut feed file */
+                snprintf(feed->feed_filename, sizeof(feed->feed_filename),
+                         "/tmp/%s.ffm", feed->filename);
+                feed->feed_max_size = 5 * 1024 * 1024;
+                feed->is_feed = 1;
+                feed->feed = feed; /* self feeding :-) */
+
+                /* add in stream list */
+                *last_stream = feed;
+                last_stream = &feed->next;
+                /* add in feed list */
+                *last_feed = feed;
+                last_feed = &feed->next_feed;
+            }
+        } else if (!av_strcasecmp(cmd, "Launch")) {
+            if (feed) {
+                int i;
+
+                feed->child_argv = av_mallocz(64 * sizeof(char *));
+
+                for (i = 0; i < 62; i++) {
+                    get_arg(arg, sizeof(arg), &p);
+                    if (!arg[0])
+                        break;
+
+                    feed->child_argv[i] = av_strdup(arg);
+                }
+
+                feed->child_argv[i] = av_malloc(30 + strlen(feed->filename));
+
+                snprintf(feed->child_argv[i], 30+strlen(feed->filename),
+                    "http://%s:%d/%s",
+                        (my_http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" :
+                    inet_ntoa(my_http_addr.sin_addr),
+                    ntohs(my_http_addr.sin_port), feed->filename);
+            }
+        } else if (!av_strcasecmp(cmd, "ReadOnlyFile")) {
+            if (feed) {
+                get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
+                feed->readonly = 1;
+            } else if (stream) {
+                get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
+            }
+        } else if (!av_strcasecmp(cmd, "File")) {
+            if (feed) {
+                get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
+            } else if (stream)
+                get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
+        } else if (!av_strcasecmp(cmd, "Truncate")) {
+            if (feed) {
+                get_arg(arg, sizeof(arg), &p);
+                feed->truncate = strtod(arg, NULL);
+            }
+        } else if (!av_strcasecmp(cmd, "FileMaxSize")) {
+            if (feed) {
+                char *p1;
+                double fsize;
+
+                get_arg(arg, sizeof(arg), &p);
+                p1 = arg;
+                fsize = strtod(p1, &p1);
+                switch(toupper(*p1)) {
+                case 'K':
+                    fsize *= 1024;
+                    break;
+                case 'M':
+                    fsize *= 1024 * 1024;
+                    break;
+                case 'G':
+                    fsize *= 1024 * 1024 * 1024;
+                    break;
+                }
+                feed->feed_max_size = (int64_t)fsize;
+                if (feed->feed_max_size < FFM_PACKET_SIZE*4) {
+                    ERROR("Feed max file size is too small, must be at least %d\n", FFM_PACKET_SIZE*4);
+                }
+            }
+        } else if (!av_strcasecmp(cmd, "</Feed>")) {
+            if (!feed) {
+                ERROR("No corresponding <Feed> for </Feed>\n");
+            }
+            feed = NULL;
+        } else if (!av_strcasecmp(cmd, "<Stream")) {
+            /*********************************************/
+            /* Stream related options */
+            char *q;
+            if (stream || feed) {
+                ERROR("Already in a tag\n");
+            } else {
+                FFStream *s;
+                stream = av_mallocz(sizeof(FFStream));
+                get_arg(stream->filename, sizeof(stream->filename), &p);
+                q = strrchr(stream->filename, '>');
+                if (*q)
+                    *q = '\0';
+
+                for (s = first_stream; s; s = s->next) {
+                    if (!strcmp(stream->filename, s->filename)) {
+                        ERROR("Stream '%s' already registered\n", s->filename);
+                    }
+                }
+
+                stream->fmt = ffserver_guess_format(NULL, stream->filename, NULL);
+                avcodec_get_context_defaults3(&video_enc, NULL);
+                avcodec_get_context_defaults3(&audio_enc, NULL);
+
+                audio_id = AV_CODEC_ID_NONE;
+                video_id = AV_CODEC_ID_NONE;
+                if (stream->fmt) {
+                    audio_id = stream->fmt->audio_codec;
+                    video_id = stream->fmt->video_codec;
+                }
+
+                *last_stream = stream;
+                last_stream = &stream->next;
+            }
+        } else if (!av_strcasecmp(cmd, "Feed")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream) {
+                FFStream *sfeed;
+
+                sfeed = first_feed;
+                while (sfeed != NULL) {
+                    if (!strcmp(sfeed->filename, arg))
+                        break;
+                    sfeed = sfeed->next_feed;
+                }
+                if (!sfeed)
+                    ERROR("feed '%s' not defined\n", arg);
+                else
+                    stream->feed = sfeed;
+            }
+        } else if (!av_strcasecmp(cmd, "Format")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream) {
+                if (!strcmp(arg, "status")) {
+                    stream->stream_type = STREAM_TYPE_STATUS;
+                    stream->fmt = NULL;
+                } else {
+                    stream->stream_type = STREAM_TYPE_LIVE;
+                    /* jpeg cannot be used here, so use single frame jpeg */
+                    if (!strcmp(arg, "jpeg"))
+                        strcpy(arg, "mjpeg");
+                    stream->fmt = ffserver_guess_format(arg, NULL, NULL);
+                    if (!stream->fmt) {
+                        ERROR("Unknown Format: %s\n", arg);
+                    }
+                }
+                if (stream->fmt) {
+                    audio_id = stream->fmt->audio_codec;
+                    video_id = stream->fmt->video_codec;
+                }
+            }
+        } else if (!av_strcasecmp(cmd, "InputFormat")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream) {
+                stream->ifmt = av_find_input_format(arg);
+                if (!stream->ifmt) {
+                    ERROR("Unknown input format: %s\n", arg);
+                }
+            }
+        } else if (!av_strcasecmp(cmd, "FaviconURL")) {
+            if (stream && stream->stream_type == STREAM_TYPE_STATUS) {
+                get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
+            } else {
+                ERROR("FaviconURL only permitted for status streams\n");
+            }
+        } else if (!av_strcasecmp(cmd, "Author")) {
+            if (stream)
+                get_arg(stream->author, sizeof(stream->author), &p);
+        } else if (!av_strcasecmp(cmd, "Comment")) {
+            if (stream)
+                get_arg(stream->comment, sizeof(stream->comment), &p);
+        } else if (!av_strcasecmp(cmd, "Copyright")) {
+            if (stream)
+                get_arg(stream->copyright, sizeof(stream->copyright), &p);
+        } else if (!av_strcasecmp(cmd, "Title")) {
+            if (stream)
+                get_arg(stream->title, sizeof(stream->title), &p);
+        } else if (!av_strcasecmp(cmd, "Preroll")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream)
+                stream->prebuffer = atof(arg) * 1000;
+        } else if (!av_strcasecmp(cmd, "StartSendOnKey")) {
+            if (stream)
+                stream->send_on_key = 1;
+        } else if (!av_strcasecmp(cmd, "AudioCodec")) {
+            get_arg(arg, sizeof(arg), &p);
+            audio_id = opt_audio_codec(arg);
+            if (audio_id == AV_CODEC_ID_NONE) {
+                ERROR("Unknown AudioCodec: %s\n", arg);
+            }
+        } else if (!av_strcasecmp(cmd, "VideoCodec")) {
+            get_arg(arg, sizeof(arg), &p);
+            video_id = opt_video_codec(arg);
+            if (video_id == AV_CODEC_ID_NONE) {
+                ERROR("Unknown VideoCodec: %s\n", arg);
+            }
+        } else if (!av_strcasecmp(cmd, "MaxTime")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream)
+                stream->max_time = atof(arg) * 1000;
+        } else if (!av_strcasecmp(cmd, "AudioBitRate")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream)
+                audio_enc.bit_rate = lrintf(atof(arg) * 1000);
+        } else if (!av_strcasecmp(cmd, "AudioChannels")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream)
+                audio_enc.channels = atoi(arg);
+        } else if (!av_strcasecmp(cmd, "AudioSampleRate")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream)
+                audio_enc.sample_rate = atoi(arg);
+        } else if (!av_strcasecmp(cmd, "AudioQuality")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream) {
+//                audio_enc.quality = atof(arg) * 1000;
+            }
+        } else if (!av_strcasecmp(cmd, "VideoBitRateRange")) {
+            if (stream) {
+                int minrate, maxrate;
+
+                get_arg(arg, sizeof(arg), &p);
+
+                if (sscanf(arg, "%d-%d", &minrate, &maxrate) == 2) {
+                    video_enc.rc_min_rate = minrate * 1000;
+                    video_enc.rc_max_rate = maxrate * 1000;
+                } else {
+                    ERROR("Incorrect format for VideoBitRateRange -- should be <min>-<max>: %s\n", arg);
+                }
+            }
+        } else if (!av_strcasecmp(cmd, "Debug")) {
+            if (stream) {
+                get_arg(arg, sizeof(arg), &p);
+                video_enc.debug = strtol(arg,0,0);
+            }
+        } else if (!av_strcasecmp(cmd, "Strict")) {
+            if (stream) {
+                get_arg(arg, sizeof(arg), &p);
+                video_enc.strict_std_compliance = atoi(arg);
+            }
+        } else if (!av_strcasecmp(cmd, "VideoBufferSize")) {
+            if (stream) {
+                get_arg(arg, sizeof(arg), &p);
+                video_enc.rc_buffer_size = atoi(arg) * 8*1024;
+            }
+        } else if (!av_strcasecmp(cmd, "VideoBitRateTolerance")) {
+            if (stream) {
+                get_arg(arg, sizeof(arg), &p);
+                video_enc.bit_rate_tolerance = atoi(arg) * 1000;
+            }
+        } else if (!av_strcasecmp(cmd, "VideoBitRate")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream) {
+                video_enc.bit_rate = atoi(arg) * 1000;
+            }
+        } else if (!av_strcasecmp(cmd, "VideoSize")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream) {
+                av_parse_video_size(&video_enc.width, &video_enc.height, arg);
+                if ((video_enc.width % 16) != 0 ||
+                    (video_enc.height % 16) != 0) {
+                    ERROR("Image size must be a multiple of 16\n");
+                }
+            }
+        } else if (!av_strcasecmp(cmd, "VideoFrameRate")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream) {
+                AVRational frame_rate;
+                if (av_parse_video_rate(&frame_rate, arg) < 0) {
+                    ERROR("Incorrect frame rate: %s\n", arg);
+                } else {
+                    video_enc.time_base.num = frame_rate.den;
+                    video_enc.time_base.den = frame_rate.num;
+                }
+            }
+        } else if (!av_strcasecmp(cmd, "VideoGopSize")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream)
+                video_enc.gop_size = atoi(arg);
+        } else if (!av_strcasecmp(cmd, "VideoIntraOnly")) {
+            if (stream)
+                video_enc.gop_size = 1;
+        } else if (!av_strcasecmp(cmd, "VideoHighQuality")) {
+            if (stream)
+                video_enc.mb_decision = FF_MB_DECISION_BITS;
+        } else if (!av_strcasecmp(cmd, "Video4MotionVector")) {
+            if (stream) {
+                video_enc.mb_decision = FF_MB_DECISION_BITS; //FIXME remove
+                video_enc.flags |= CODEC_FLAG_4MV;
+            }
+        } else if (!av_strcasecmp(cmd, "AVOptionVideo") ||
+                   !av_strcasecmp(cmd, "AVOptionAudio")) {
+            char arg2[1024];
+            AVCodecContext *avctx;
+            int type;
+            get_arg(arg, sizeof(arg), &p);
+            get_arg(arg2, sizeof(arg2), &p);
+            if (!av_strcasecmp(cmd, "AVOptionVideo")) {
+                avctx = &video_enc;
+                type = AV_OPT_FLAG_VIDEO_PARAM;
+            } else {
+                avctx = &audio_enc;
+                type = AV_OPT_FLAG_AUDIO_PARAM;
+            }
+            if (ffserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) {
+                ERROR("AVOption error: %s %s\n", arg, arg2);
+            }
+        } else if (!av_strcasecmp(cmd, "AVPresetVideo") ||
+                   !av_strcasecmp(cmd, "AVPresetAudio")) {
+            AVCodecContext *avctx;
+            int type;
+            get_arg(arg, sizeof(arg), &p);
+            if (!av_strcasecmp(cmd, "AVPresetVideo")) {
+                avctx = &video_enc;
+                video_enc.codec_id = video_id;
+                type = AV_OPT_FLAG_VIDEO_PARAM;
+            } else {
+                avctx = &audio_enc;
+                audio_enc.codec_id = audio_id;
+                type = AV_OPT_FLAG_AUDIO_PARAM;
+            }
+            if (ffserver_opt_preset(arg, avctx, type|AV_OPT_FLAG_ENCODING_PARAM, &audio_id, &video_id)) {
+                ERROR("AVPreset error: %s\n", arg);
+            }
+        } else if (!av_strcasecmp(cmd, "VideoTag")) {
+            get_arg(arg, sizeof(arg), &p);
+            if ((strlen(arg) == 4) && stream)
+                video_enc.codec_tag = MKTAG(arg[0], arg[1], arg[2], arg[3]);
+        } else if (!av_strcasecmp(cmd, "BitExact")) {
+            if (stream)
+                video_enc.flags |= CODEC_FLAG_BITEXACT;
+        } else if (!av_strcasecmp(cmd, "DctFastint")) {
+            if (stream)
+                video_enc.dct_algo  = FF_DCT_FASTINT;
+        } else if (!av_strcasecmp(cmd, "IdctSimple")) {
+            if (stream)
+                video_enc.idct_algo = FF_IDCT_SIMPLE;
+        } else if (!av_strcasecmp(cmd, "Qscale")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream) {
+                video_enc.flags |= CODEC_FLAG_QSCALE;
+                video_enc.global_quality = FF_QP2LAMBDA * atoi(arg);
+            }
+        } else if (!av_strcasecmp(cmd, "VideoQDiff")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream) {
+                video_enc.max_qdiff = atoi(arg);
+                if (video_enc.max_qdiff < 1 || video_enc.max_qdiff > 31) {
+                    ERROR("VideoQDiff out of range\n");
+                }
+            }
+        } else if (!av_strcasecmp(cmd, "VideoQMax")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream) {
+                video_enc.qmax = atoi(arg);
+                if (video_enc.qmax < 1 || video_enc.qmax > 31) {
+                    ERROR("VideoQMax out of range\n");
+                }
+            }
+        } else if (!av_strcasecmp(cmd, "VideoQMin")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream) {
+                video_enc.qmin = atoi(arg);
+                if (video_enc.qmin < 1 || video_enc.qmin > 31) {
+                    ERROR("VideoQMin out of range\n");
+                }
+            }
+        } else if (!av_strcasecmp(cmd, "LumaElim")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream)
+                video_enc.luma_elim_threshold = atoi(arg);
+        } else if (!av_strcasecmp(cmd, "ChromaElim")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream)
+                video_enc.chroma_elim_threshold = atoi(arg);
+        } else if (!av_strcasecmp(cmd, "LumiMask")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream)
+                video_enc.lumi_masking = atof(arg);
+        } else if (!av_strcasecmp(cmd, "DarkMask")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream)
+                video_enc.dark_masking = atof(arg);
+        } else if (!av_strcasecmp(cmd, "NoVideo")) {
+            video_id = AV_CODEC_ID_NONE;
+        } else if (!av_strcasecmp(cmd, "NoAudio")) {
+            audio_id = AV_CODEC_ID_NONE;
+        } else if (!av_strcasecmp(cmd, "ACL")) {
+            parse_acl_row(stream, feed, NULL, p, filename, line_num);
+        } else if (!av_strcasecmp(cmd, "DynamicACL")) {
+            if (stream) {
+                get_arg(stream->dynamic_acl, sizeof(stream->dynamic_acl), &p);
+            }
+        } else if (!av_strcasecmp(cmd, "RTSPOption")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream) {
+                av_freep(&stream->rtsp_option);
+                stream->rtsp_option = av_strdup(arg);
+            }
+        } else if (!av_strcasecmp(cmd, "MulticastAddress")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream) {
+                if (resolve_host(&stream->multicast_ip, arg) != 0) {
+                    ERROR("Invalid host/IP address: %s\n", arg);
+                }
+                stream->is_multicast = 1;
+                stream->loop = 1; /* default is looping */
+            }
+        } else if (!av_strcasecmp(cmd, "MulticastPort")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream)
+                stream->multicast_port = atoi(arg);
+        } else if (!av_strcasecmp(cmd, "MulticastTTL")) {
+            get_arg(arg, sizeof(arg), &p);
+            if (stream)
+                stream->multicast_ttl = atoi(arg);
+        } else if (!av_strcasecmp(cmd, "NoLoop")) {
+            if (stream)
+                stream->loop = 0;
+        } else if (!av_strcasecmp(cmd, "</Stream>")) {
+            if (!stream) {
+                ERROR("No corresponding <Stream> for </Stream>\n");
+            } else {
+                if (stream->feed && stream->fmt && strcmp(stream->fmt->name, "ffm") != 0) {
+                    if (audio_id != AV_CODEC_ID_NONE) {
+                        audio_enc.codec_type = AVMEDIA_TYPE_AUDIO;
+                        audio_enc.codec_id = audio_id;
+                        add_codec(stream, &audio_enc);
+                    }
+                    if (video_id != AV_CODEC_ID_NONE) {
+                        video_enc.codec_type = AVMEDIA_TYPE_VIDEO;
+                        video_enc.codec_id = video_id;
+                        add_codec(stream, &video_enc);
+                    }
+                }
+                stream = NULL;
+            }
+        } else if (!av_strcasecmp(cmd, "<Redirect")) {
+            /*********************************************/
+            char *q;
+            if (stream || feed || redirect) {
+                ERROR("Already in a tag\n");
+            } else {
+                redirect = av_mallocz(sizeof(FFStream));
+                *last_stream = redirect;
+                last_stream = &redirect->next;
+
+                get_arg(redirect->filename, sizeof(redirect->filename), &p);
+                q = strrchr(redirect->filename, '>');
+                if (*q)
+                    *q = '\0';
+                redirect->stream_type = STREAM_TYPE_REDIRECT;
+            }
+        } else if (!av_strcasecmp(cmd, "URL")) {
+            if (redirect)
+                get_arg(redirect->feed_filename, sizeof(redirect->feed_filename), &p);
+        } else if (!av_strcasecmp(cmd, "</Redirect>")) {
+            if (!redirect) {
+                ERROR("No corresponding <Redirect> for </Redirect>\n");
+            } else {
+                if (!redirect->feed_filename[0]) {
+                    ERROR("No URL found for <Redirect>\n");
+                }
+                redirect = NULL;
+            }
+        } else if (!av_strcasecmp(cmd, "LoadModule")) {
+            get_arg(arg, sizeof(arg), &p);
+#if HAVE_DLOPEN
+            load_module(arg);
+#else
+            ERROR("Module support not compiled into this version: '%s'\n", arg);
+#endif
+        } else {
+            ERROR("Incorrect keyword: '%s'\n", cmd);
+        }
+    }
+#undef ERROR
+
+    fclose(f);
+    if (errors)
+        return -1;
+    else
+        return 0;
+}
+
+static void handle_child_exit(int sig)
+{
+    pid_t pid;
+    int status;
+
+    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
+        FFStream *feed;
+
+        for (feed = first_feed; feed; feed = feed->next) {
+            if (feed->pid == pid) {
+                int uptime = time(0) - feed->pid_start;
+
+                feed->pid = 0;
+                fprintf(stderr, "%s: Pid %d exited with status %d after %d seconds\n", feed->filename, pid, status, uptime);
+
+                if (uptime < 30)
+                    /* Turn off any more restarts */
+                    feed->child_argv = 0;
+            }
+        }
+    }
+
+    need_to_start_children = 1;
+}
+
+static void opt_debug(void)
+{
+    ffserver_debug = 1;
+    ffserver_daemon = 0;
+    logfilename[0] = '-';
+}
+
+void show_help_default(const char *opt, const char *arg)
+{
+    printf("usage: ffserver [options]\n"
+           "Hyper fast multi format Audio/Video streaming server\n");
+    printf("\n");
+    show_help_options(options, "Main options:", 0, 0, 0);
+}
+
+static const OptionDef options[] = {
+#include "cmdutils_common_opts.h"
+    { "n", OPT_BOOL, {(void *)&no_launch }, "enable no-launch mode" },
+    { "d", 0, {(void*)opt_debug}, "enable debug mode" },
+    { "f", HAS_ARG | OPT_STRING, {(void*)&config_filename }, "use configfile instead of /etc/ffserver.conf", "configfile" },
+    { NULL },
+};
+
+int main(int argc, char **argv)
+{
+    struct sigaction sigact = { { 0 } };
+
+    parse_loglevel(argc, argv, options);
+    av_register_all();
+    avformat_network_init();
+
+    show_banner(argc, argv, options);
+
+    my_program_name = argv[0];
+    my_program_dir = getcwd(0, 0);
+    ffserver_daemon = 1;
+
+    parse_options(NULL, argc, argv, options, NULL);
+
+    unsetenv("http_proxy");             /* Kill the http_proxy */
+
+    av_lfg_init(&random_state, av_get_random_seed());
+
+    sigact.sa_handler = handle_child_exit;
+    sigact.sa_flags = SA_NOCLDSTOP | SA_RESTART;
+    sigaction(SIGCHLD, &sigact, 0);
+
+    if (parse_ffconfig(config_filename) < 0) {
+        fprintf(stderr, "Incorrect config file - exiting.\n");
+        exit(1);
+    }
+
+    /* open log file if needed */
+    if (logfilename[0] != '\0') {
+        if (!strcmp(logfilename, "-"))
+            logfile = stdout;
+        else
+            logfile = fopen(logfilename, "a");
+        av_log_set_callback(http_av_log);
+    }
+
+    build_file_streams();
+
+    build_feed_streams();
+
+    compute_bandwidth();
+
+    /* put the process in background and detach it from its TTY */
+    if (ffserver_daemon) {
+        int pid;
+
+        pid = fork();
+        if (pid < 0) {
+            perror("fork");
+            exit(1);
+        } else if (pid > 0) {
+            /* parent : exit */
+            exit(0);
+        } else {
+            /* child */
+            setsid();
+            close(0);
+            open("/dev/null", O_RDWR);
+            if (strcmp(logfilename, "-") != 0) {
+                close(1);
+                dup(0);
+            }
+            close(2);
+            dup(0);
+        }
+    }
+
+    /* signal init */
+    signal(SIGPIPE, SIG_IGN);
+
+    if (ffserver_daemon)
+        chdir("/");
+
+    if (http_server() < 0) {
+        http_log("Could not start server\n");
+        exit(1);
+    }
+
+    return 0;
+}
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c
index 38fc2f2..bbf6d90 100644
--- a/libavcodec/4xm.c
+++ b/libavcodec/4xm.c
@@ -2,20 +2,20 @@
  * 4XM codec
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,8 +30,7 @@
 #include "dsputil.h"
 #include "get_bits.h"
 
-//#undef NDEBUG
-//#include <assert.h>
+#include "libavutil/avassert.h"
 
 #define BLOCK_TYPE_VLC_BITS 5
 #define ACDC_VLC_BITS 9
@@ -284,7 +283,7 @@
     }
 #endif
 
-static inline void mcdc(uint16_t *dst, uint16_t *src, int log2w,
+static inline void mcdc(uint16_t *dst, const uint16_t *src, int log2w,
                         int h, int stride, int scale, unsigned dc)
 {
     int i;
@@ -328,7 +327,7 @@
         }
         break;
     default:
-        assert(0);
+        av_assert2(0);
     }
 }
 
@@ -343,9 +342,13 @@
     uint16_t *start = (uint16_t *)f->last_picture.data[0];
     uint16_t *end   = start + stride * (f->avctx->height - h + 1) - (1 << log2w);
 
-    assert(code >= 0 && code <= 6);
+    av_assert2(code >= 0 && code <= 6);
 
     if (code == 0) {
+        if (f->g.buffer_end - f->g.buffer < 1) {
+            av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
+            return;
+        }
         src += f->mv[bytestream2_get_byte(&f->g)];
         if (start > src || src > end) {
             av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
@@ -365,15 +368,31 @@
     } 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) {
+            av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n");
+            return;
+        }
         src += f->mv[bytestream2_get_byte(&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){
+            av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
+            return;
+        }
         mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16(&f->g2));
     } else if (code == 5) {
+        if (f->g2.buffer_end - f->g2.buffer < 1) {
+            av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n");
+            return;
+        }
         mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16(&f->g2));
     } else if (code == 6) {
+        if (f->g2.buffer_end - f->g2.buffer < 2) {
+            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);
@@ -397,6 +416,8 @@
 
     if (f->version > 1) {
         extra           = 20;
+        if (length < extra)
+            return -1;
         bitstream_size  = AV_RL32(buf + 8);
         wordstream_size = AV_RL32(buf + 12);
         bytestream_size = AV_RL32(buf + 16);
@@ -407,13 +428,12 @@
         bytestream_size = FFMAX(length - bitstream_size - wordstream_size, 0);
     }
 
-    if (bitstream_size + bytestream_size + wordstream_size + extra != length
-        || bitstream_size  > (1 << 26)
-        || bytestream_size > (1 << 26)
-        || wordstream_size > (1 << 26)) {
-        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);
+    if (bitstream_size > length ||
+        bytestream_size > length - bitstream_size ||
+        wordstream_size > length - bytestream_size - bitstream_size ||
+        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;
     }
 
@@ -454,6 +474,11 @@
 {
     int code, i, j, level, val;
 
+    if (get_bits_left(&f->gb) < 2){
+        av_log(f->avctx, AV_LOG_ERROR, "%d bits left before decode_i_block()\n", get_bits_left(&f->gb));
+        return -1;
+    }
+
     /* DC coef */
     val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);
     if (val >> 4)
@@ -553,7 +578,7 @@
 }
 
 static const uint8_t *read_huffman_tables(FourXContext *f,
-                                          const uint8_t * const buf)
+                                          const uint8_t * const buf, int buf_size)
 {
     int frequency[512] = { 0 };
     uint8_t flag[512];
@@ -562,6 +587,7 @@
     int bits_tab[257];
     int start, end;
     const uint8_t *ptr = buf;
+    const uint8_t *ptr_end = buf + buf_size;
     int j;
 
     memset(up, -1, sizeof(up));
@@ -571,6 +597,8 @@
     for (;;) {
         int i;
 
+        if (start <= end && ptr_end - ptr < end - start + 1 + 1)
+            return NULL;
         for (i = start; i <= end; i++)
             frequency[i] = *ptr++;
         start = *ptr++;
@@ -653,6 +681,7 @@
     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;
+    const uint8_t *buf_end = buf + length;
     GetByteContext g3;
 
     if (length < mbs * 8) {
@@ -664,6 +693,8 @@
     for (y = 0; y < height; y += 16) {
         for (x = 0; x < width; x += 16) {
             unsigned int color[4] = { 0 }, bits;
+            if (buf_end - buf < 8)
+                return -1;
             // warning following is purely guessed ...
             color[0] = bytestream2_get_le16u(&g3);
             color[1] = bytestream2_get_le16u(&g3);
@@ -697,16 +728,14 @@
     const int width  = f->avctx->width;
     const int height = f->avctx->height;
     const unsigned int bitstream_size = AV_RL32(buf);
-    int token_count av_unused;
     unsigned int prestream_size;
     const uint8_t *prestream;
 
-    if (length < bitstream_size + 12) {
+    if (bitstream_size > (1<<26) || length < bitstream_size + 12) {
         av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n");
         return AVERROR_INVALIDDATA;
     }
 
-    token_count    =     AV_RL32(buf + bitstream_size + 8);
     prestream_size = 4 * AV_RL32(buf + bitstream_size + 4);
     prestream      =             buf + bitstream_size + 12;
 
@@ -718,7 +747,9 @@
         return -1;
     }
 
-    prestream = read_huffman_tables(f, prestream);
+    prestream = read_huffman_tables(f, prestream, buf + length - prestream);
+    if (!prestream)
+        return -1;
 
     init_get_bits(&f->gb, buf + 4, 8 * bitstream_size);
 
@@ -761,6 +792,8 @@
     AVFrame *p, temp;
     int i, frame_4cc, frame_size;
 
+    if (buf_size < 12)
+        return AVERROR_INVALIDDATA;
     frame_4cc = AV_RL32(buf);
     if (buf_size != AV_RL32(buf + 4) + 8 || buf_size < 20)
         av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n",
@@ -773,6 +806,11 @@
         const int whole_size = AV_RL32(buf + 16);
         CFrameBuffer *cfrm;
 
+        if (data_size < 0 || whole_size < 0) {
+            av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n");
+            return AVERROR_INVALIDDATA;
+        }
+
         for (i = 0; i < CFRAME_BUFFER_COUNT; i++)
             if (f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
                 av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n",
@@ -791,11 +829,14 @@
         }
         cfrm = &f->cfrm[i];
 
+        if (data_size > UINT_MAX -  cfrm->size - FF_INPUT_BUFFER_PADDING_SIZE)
+            return AVERROR_INVALIDDATA;
+
         cfrm->data = av_fast_realloc(cfrm->data, &cfrm->allocated_size,
                                      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");
+            av_log(f->avctx, AV_LOG_ERROR, "realloc falure\n");
             return -1;
         }
 
@@ -829,26 +870,27 @@
     // alternatively we would have to use our own buffer management
     avctx->flags |= CODEC_FLAG_EMU_EDGE;
 
-    if (p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 1;
-    if (avctx->get_buffer(avctx, p) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+    p->reference= 3;
+    if (avctx->reget_buffer(avctx, p) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return -1;
     }
 
     if (frame_4cc == AV_RL32("ifr2")) {
-        p->pict_type = AV_PICTURE_TYPE_I;
-        if (decode_i2_frame(f, buf - 4, frame_size + 4) < 0)
+        p->pict_type= AV_PICTURE_TYPE_I;
+        if (decode_i2_frame(f, buf - 4, frame_size + 4) < 0) {
+            av_log(f->avctx, AV_LOG_ERROR, "decode i2 frame failed\n");
             return -1;
+        }
     } else if (frame_4cc == AV_RL32("ifrm")) {
-        p->pict_type = AV_PICTURE_TYPE_I;
-        if (decode_i_frame(f, buf, frame_size) < 0)
+        p->pict_type= AV_PICTURE_TYPE_I;
+        if (decode_i_frame(f, buf, frame_size) < 0) {
+            av_log(f->avctx, AV_LOG_ERROR, "decode i frame failed\n");
             return -1;
+        }
     } else if (frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")) {
         if (!f->last_picture.data[0]) {
-            f->last_picture.reference = 1;
+            f->last_picture.reference = 3;
             if (avctx->get_buffer(avctx, &f->last_picture) < 0) {
                 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                 return -1;
@@ -856,8 +898,10 @@
         }
 
         p->pict_type = AV_PICTURE_TYPE_P;
-        if (decode_p_frame(f, buf, frame_size) < 0)
+        if (decode_p_frame(f, buf, frame_size) < 0) {
+            av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n");
             return -1;
+        }
     } else if (frame_4cc == AV_RL32("snd_")) {
         av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n",
                buf_size);
@@ -894,7 +938,13 @@
         av_log(avctx, AV_LOG_ERROR, "extradata wrong or missing\n");
         return 1;
     }
+    if((avctx->width % 16) || (avctx->height % 16)) {
+        av_log(avctx, AV_LOG_ERROR, "unsupported width/height\n");
+        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);
     init_vlcs(f);
diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c
index 95e811a..a6d0a1b 100644
--- a/libavcodec/8bps.c
+++ b/libavcodec/8bps.c
@@ -2,20 +2,20 @@
  * Quicktime Planar RGB (8BPS) Video Decoder
  * Copyright (C) 2003 Roberto Togni
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -27,7 +27,7 @@
  *
  * Supports: PAL8 (RGB 8bpp, paletted)
  *         : BGR24 (RGB 24bpp) (can also output it as RGB32)
- *         : RGB32 (RGB 32bpp, 4th plane is probably alpha and it's ignored)
+ *         : RGB32 (RGB 32bpp, 4th plane is alpha)
  *
  */
 
@@ -74,7 +74,6 @@
     unsigned int dlen, p, row;
     const unsigned char *lp, *dp;
     unsigned char count;
-    unsigned int px_inc;
     unsigned int planes     = c->planes;
     unsigned char *planemap = c->planemap;
 
@@ -91,12 +90,6 @@
     /* Set data pointer after line lengths */
     dp = encoded + planes * (height << 1);
 
-    /* Ignore alpha plane, don't know what to do with it */
-    if (planes == 4)
-        planes--;
-
-    px_inc = planes + (avctx->pix_fmt == AV_PIX_FMT_RGB32);
-
     for (p = 0; p < planes; p++) {
         /* Lines length pointer for this plane */
         lp = encoded + p * (height << 1);
@@ -113,21 +106,21 @@
                 if ((count = *dp++) <= 127) {
                     count++;
                     dlen -= count + 1;
-                    if (pixptr + count * px_inc > pixptr_end)
+                    if (pixptr + count * planes > pixptr_end)
                         break;
                     if (dp + count > buf + buf_size)
                         return -1;
                     while (count--) {
                         *pixptr = *dp++;
-                        pixptr += px_inc;
+                        pixptr += planes;
                     }
                 } else {
                     count = 257 - count;
-                    if (pixptr + count * px_inc > pixptr_end)
+                    if (pixptr + count * planes > pixptr_end)
                         break;
                     while (count--) {
                         *pixptr = *dp;
-                        pixptr += px_inc;
+                        pixptr += planes;
                     }
                     dp++;
                     dlen -= 2;
@@ -168,6 +161,7 @@
     c->avctx       = avctx;
     c->pic.data[0] = NULL;
 
+    avcodec_get_frame_defaults(&c->pic);
     switch (avctx->bits_per_coded_sample) {
     case 8:
         avctx->pix_fmt = AV_PIX_FMT_PAL8;
@@ -188,12 +182,12 @@
         c->planemap[0] = 1; // 1st plane is red
         c->planemap[1] = 2; // 2nd plane is green
         c->planemap[2] = 3; // 3rd plane is blue
-        c->planemap[3] = 0; // 4th plane is alpha???
+        c->planemap[3] = 0; // 4th plane is alpha
 #else
         c->planemap[0] = 2; // 1st plane is red
         c->planemap[1] = 1; // 2nd plane is green
         c->planemap[2] = 0; // 3rd plane is blue
-        c->planemap[3] = 3; // 4th plane is alpha???
+        c->planemap[3] = 3; // 4th plane is alpha
 #endif
         break;
     default:
diff --git a/libavcodec/8svx.c b/libavcodec/8svx.c
index 1839617..698ddd0 100644
--- a/libavcodec/8svx.c
+++ b/libavcodec/8svx.c
@@ -1,21 +1,21 @@
 /*
- * 8SVX audio decoder
  * Copyright (C) 2008 Jaikrishnan Menon
+ * Copyright (C) 2011 Stefano Sabatini
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,8 +26,18 @@
  *
  * supports: fibonacci delta encoding
  *         : exponential encoding
+ *
+ * For more information about the 8SVX format:
+ * http://netghost.narod.ru/gff/vendspec/iff/iff.txt
+ * http://sox.sourceforge.net/AudioFormats-11.html
+ * http://aminet.net/package/mus/misc/wavepak
+ * http://amigan.1emu.net/reg/8SVX.txt
+ *
+ * Samples can be found here:
+ * http://aminet.net/mods/smpl/
  */
 
+#include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "libavutil/common.h"
 
@@ -44,18 +54,17 @@
     int data_idx;
 } EightSvxContext;
 
-static const int8_t fibonacci[16]   = { -34, -21, -13,  -8, -5, -3, -2, -1,
-                                          0,   1,   2,   3,  5,  8, 13, 21 };
-static const int8_t exponential[16] = { -128, -64, -32, -16, -8, -4, -2, -1,
-                                           0,   1,   2,   4,  8, 16, 32, 64 };
+static const int8_t fibonacci[16]   = { -34,  -21, -13,  -8, -5, -3, -2, -1, 0, 1, 2, 3, 5, 8,  13, 21 };
+static const int8_t exponential[16] = { -128, -64, -32, -16, -8, -4, -2, -1, 0, 1, 2, 4, 8, 16, 32, 64 };
 
-#define MAX_FRAME_SIZE 32768
+#define MAX_FRAME_SIZE 2048
 
 /**
  * Delta decode the compressed values in src, and put the resulting
  * decoded samples in dst.
  *
  * @param[in,out] state starting value. it is saved for use in the next call.
+ * @param table delta sequence table
  */
 static void delta_decode(uint8_t *dst, const uint8_t *src, int src_size,
                          uint8_t *state, const int8_t *table)
@@ -87,25 +96,24 @@
     int buf_size;
     int ch, ret;
     int is_compr = (avctx->codec_id != AV_CODEC_ID_PCM_S8_PLANAR);
+    int hdr_size  = is_compr ? 2 : 0;
 
-    /* for the first packet, copy data to buffer */
-    if (avpkt->data) {
-        int hdr_size  = is_compr ? 2 : 0;
-        int chan_size = (avpkt->size - hdr_size * avctx->channels) / avctx->channels;
+    /* decode and interleave the first packet */
+    if (!esc->data[0] && avpkt) {
+        int chan_size = avpkt->size / avctx->channels - hdr_size;
 
-        if (avpkt->size < hdr_size * avctx->channels) {
-            av_log(avctx, AV_LOG_ERROR, "packet size is too small\n");
-            return AVERROR(EINVAL);
+        if (avpkt->size % avctx->channels) {
+            av_log(avctx, AV_LOG_WARNING, "Packet with odd size, ignoring last byte\n");
         }
-        if (esc->data[0]) {
-            av_log(avctx, AV_LOG_ERROR, "unexpected data after first packet\n");
+        if (avpkt->size < (hdr_size + 1) * avctx->channels) {
+            av_log(avctx, AV_LOG_ERROR, "packet size is too small\n");
             return AVERROR(EINVAL);
         }
 
         if (is_compr) {
-        esc->fib_acc[0] = avpkt->data[1] + 128;
-        if (avctx->channels == 2)
-            esc->fib_acc[1] = avpkt->data[2+chan_size+1] + 128;
+            esc->fib_acc[0] = avpkt->data[1] + 128;
+            if (avctx->channels == 2)
+                esc->fib_acc[1] = avpkt->data[2+chan_size+1] + 128;
         }
 
         esc->data_idx  = 0;
@@ -156,30 +164,26 @@
     *got_frame_ptr   = 1;
     *(AVFrame *)data = esc->frame;
 
-    return avpkt->size;
+    return ((avctx->frame_number == 0)*hdr_size + buf_size)*avctx->channels;
 }
 
-/** initialize 8svx decoder */
 static av_cold int eightsvx_decode_init(AVCodecContext *avctx)
 {
     EightSvxContext *esc = avctx->priv_data;
 
     if (avctx->channels < 1 || avctx->channels > 2) {
         av_log(avctx, AV_LOG_ERROR, "8SVX does not support more than 2 channels\n");
-        return AVERROR(EINVAL);
+        return AVERROR_INVALIDDATA;
     }
 
-    switch(avctx->codec->id) {
-        case AV_CODEC_ID_8SVX_FIB:
-          esc->table = fibonacci;
-          break;
-        case AV_CODEC_ID_8SVX_EXP:
-          esc->table = exponential;
-          break;
-        case AV_CODEC_ID_PCM_S8_PLANAR:
-            break;
-        default:
-          return -1;
+    switch (avctx->codec->id) {
+    case AV_CODEC_ID_8SVX_FIB: esc->table = fibonacci;    break;
+    case AV_CODEC_ID_8SVX_EXP: esc->table = exponential;  break;
+    case AV_CODEC_ID_PCM_S8_PLANAR:
+    case AV_CODEC_ID_8SVX_RAW: esc->table = NULL;         break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "Invalid codec id %d.\n", avctx->codec->id);
+        return AVERROR_INVALIDDATA;
     }
     avctx->sample_fmt = AV_SAMPLE_FMT_U8P;
 
@@ -195,38 +199,43 @@
 
     av_freep(&esc->data[0]);
     av_freep(&esc->data[1]);
+    esc->data_size = 0;
+    esc->data_idx = 0;
 
     return 0;
 }
 
+#if CONFIG_EIGHTSVX_FIB_DECODER
 AVCodec ff_eightsvx_fib_decoder = {
   .name           = "8svx_fib",
   .type           = AVMEDIA_TYPE_AUDIO,
   .id             = AV_CODEC_ID_8SVX_FIB,
   .priv_data_size = sizeof (EightSvxContext),
   .init           = eightsvx_decode_init,
-  .close          = eightsvx_decode_close,
   .decode         = eightsvx_decode_frame,
-  .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_DR1,
+  .close          = eightsvx_decode_close,
+  .capabilities   = CODEC_CAP_DR1,
   .long_name      = NULL_IF_CONFIG_SMALL("8SVX fibonacci"),
   .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
                                                     AV_SAMPLE_FMT_NONE },
 };
-
+#endif
+#if CONFIG_EIGHTSVX_EXP_DECODER
 AVCodec ff_eightsvx_exp_decoder = {
   .name           = "8svx_exp",
   .type           = AVMEDIA_TYPE_AUDIO,
   .id             = AV_CODEC_ID_8SVX_EXP,
   .priv_data_size = sizeof (EightSvxContext),
   .init           = eightsvx_decode_init,
-  .close          = eightsvx_decode_close,
   .decode         = eightsvx_decode_frame,
-  .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_DR1,
+  .close          = eightsvx_decode_close,
+  .capabilities   = CODEC_CAP_DR1,
   .long_name      = NULL_IF_CONFIG_SMALL("8SVX exponential"),
   .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
                                                     AV_SAMPLE_FMT_NONE },
 };
-
+#endif
+#if CONFIG_PCM_S8_PLANAR_DECODER
 AVCodec ff_pcm_s8_planar_decoder = {
     .name           = "pcm_s8_planar",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -235,8 +244,9 @@
     .init           = eightsvx_decode_init,
     .close          = eightsvx_decode_close,
     .decode         = eightsvx_decode_frame,
-    .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_DR1,
+    .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("PCM signed 8-bit planar"),
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
                                                       AV_SAMPLE_FMT_NONE },
 };
+#endif
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index a63e2ba..47a01db 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1,3 +1,5 @@
+include $(SUBDIR)../config.mak
+
 NAME = avcodec
 FFLIBS = avutil
 
@@ -27,6 +29,7 @@
        options.o                                                        \
        parser.o                                                         \
        raw.o                                                            \
+       rawdec.o                                                         \
        resample.o                                                       \
        resample2.o                                                      \
        simple_idct.o                                                    \
@@ -35,8 +38,9 @@
 # parts needed for many different codecs
 OBJS-$(CONFIG_AANDCTTABLES)            += aandcttab.o
 OBJS-$(CONFIG_AC3DSP)                  += ac3dsp.o
+OBJS-$(CONFIG_CRYSTALHD)               += crystalhd.o
 OBJS-$(CONFIG_DCT)                     += dct.o dct32_fixed.o dct32_float.o
-OBJS-$(CONFIG_DWT)                     += dwt.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
@@ -96,10 +100,14 @@
                                           acelp_vectors.o             \
                                           acelp_pitch_delay.o
 OBJS-$(CONFIG_AMV_DECODER)             += sp5xdec.o mjpegdec.o mjpeg.o
+OBJS-$(CONFIG_AMV_ENCODER)             += mjpegenc.o mjpeg.o           \
+                                          mpegvideo_enc.o motion_est.o \
+                                          ratecontrol.o mpeg12data.o   \
+                                          mpegvideo.o
 OBJS-$(CONFIG_ANM_DECODER)             += anm.o
 OBJS-$(CONFIG_ANSI_DECODER)            += ansi.o cga_data.o
 OBJS-$(CONFIG_APE_DECODER)             += apedec.o
-OBJS-$(CONFIG_ASS_DECODER)             += assdec.o ass.o
+OBJS-$(CONFIG_ASS_DECODER)             += assdec.o ass.o ass_split.o
 OBJS-$(CONFIG_ASS_ENCODER)             += assenc.o ass.o
 OBJS-$(CONFIG_ASV1_DECODER)            += asvdec.o asv.o mpeg12data.o
 OBJS-$(CONFIG_ASV1_ENCODER)            += asvenc.o asv.o mpeg12data.o
@@ -109,12 +117,20 @@
 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_AVRP_DECODER)            += r210dec.o
+OBJS-$(CONFIG_AVRP_ENCODER)            += r210enc.o
 OBJS-$(CONFIG_AVS_DECODER)             += avs.o
+OBJS-$(CONFIG_AVUI_DECODER)            += avuidec.o
+OBJS-$(CONFIG_AVUI_ENCODER)            += avuienc.o
+OBJS-$(CONFIG_AYUV_DECODER)            += v408dec.o
+OBJS-$(CONFIG_AYUV_ENCODER)            += v408enc.o
 OBJS-$(CONFIG_BETHSOFTVID_DECODER)     += bethsoftvideo.o
 OBJS-$(CONFIG_BFI_DECODER)             += bfi.o
 OBJS-$(CONFIG_BINK_DECODER)            += bink.o binkdsp.o
 OBJS-$(CONFIG_BINKAUDIO_DCT_DECODER)   += binkaudio.o wma.o wma_common.o
 OBJS-$(CONFIG_BINKAUDIO_RDFT_DECODER)  += binkaudio.o wma.o wma_common.o
+OBJS-$(CONFIG_BINTEXT_DECODER)         += bintext.o cga_data.o
 OBJS-$(CONFIG_BMP_DECODER)             += bmp.o msrledec.o
 OBJS-$(CONFIG_BMP_ENCODER)             += bmpenc.o
 OBJS-$(CONFIG_BMV_VIDEO_DECODER)       += bmv.o
@@ -129,10 +145,14 @@
 OBJS-$(CONFIG_CLJR_ENCODER)            += cljr.o
 OBJS-$(CONFIG_CLLC_DECODER)            += cllc.o
 OBJS-$(CONFIG_COOK_DECODER)            += cook.o
+OBJS-$(CONFIG_CPIA_DECODER)            += cpia.o
 OBJS-$(CONFIG_CSCD_DECODER)            += cscd.o
 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_DIRAC_DECODER)           += diracdec.o dirac.o diracdsp.o \
+                                          dirac_arith.o mpeg12data.o dwt.o
 OBJS-$(CONFIG_DFA_DECODER)             += dfa.o
 OBJS-$(CONFIG_DNXHD_DECODER)           += dnxhddec.o dnxhddata.o
 OBJS-$(CONFIG_DNXHD_ENCODER)           += dnxhdenc.o dnxhddata.o
@@ -161,14 +181,18 @@
 OBJS-$(CONFIG_EIGHTSVX_EXP_DECODER)    += 8svx.o
 OBJS-$(CONFIG_EIGHTSVX_FIB_DECODER)    += 8svx.o
 OBJS-$(CONFIG_ESCAPE124_DECODER)       += escape124.o
+OBJS-$(CONFIG_ESCAPE130_DECODER)       += escape130.o
+OBJS-$(CONFIG_EXR_DECODER)             += exr.o
 OBJS-$(CONFIG_FFV1_DECODER)            += ffv1.o
 OBJS-$(CONFIG_FFV1_ENCODER)            += ffv1.o
 OBJS-$(CONFIG_FFVHUFF_DECODER)         += huffyuv.o
 OBJS-$(CONFIG_FFVHUFF_ENCODER)         += huffyuv.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
+OBJS-$(CONFIG_FLAC_ENCODER)            += flacenc.o flacdata.o flac.o vorbis_data.o
 OBJS-$(CONFIG_FLASHSV_DECODER)         += flashsv.o
 OBJS-$(CONFIG_FLASHSV_ENCODER)         += flashsvenc.o
+OBJS-$(CONFIG_FLASHSV2_ENCODER)        += flashsv2enc.o
 OBJS-$(CONFIG_FLASHSV2_DECODER)        += flashsv.o
 OBJS-$(CONFIG_FLIC_DECODER)            += flicvideo.o
 OBJS-$(CONFIG_FOURXM_DECODER)          += 4xm.o
@@ -176,12 +200,14 @@
 OBJS-$(CONFIG_FRWU_DECODER)            += frwu.o
 OBJS-$(CONFIG_G723_1_DECODER)          += g723_1.o acelp_vectors.o \
                                           celp_filters.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
 OBJS-$(CONFIG_GIF_ENCODER)             += gif.o lzwenc.o
 OBJS-$(CONFIG_GSM_DECODER)             += gsmdec.o gsmdec_data.o msgsmdec.o
 OBJS-$(CONFIG_GSM_MS_DECODER)          += gsmdec.o gsmdec_data.o msgsmdec.o
-OBJS-$(CONFIG_H261_DECODER)            += h261dec.o h261.o
-OBJS-$(CONFIG_H261_ENCODER)            += h261enc.o h261.o
+OBJS-$(CONFIG_H261_DECODER)            += h261dec.o h261.o h261data.o
+OBJS-$(CONFIG_H261_ENCODER)            += h261enc.o h261.o h261data.o
 OBJS-$(CONFIG_H263_DECODER)            += h263dec.o h263.o ituh263dec.o        \
                                           mpeg4video.o mpeg4videodec.o flvdec.o\
                                           intelh263dec.o
@@ -195,10 +221,12 @@
 OBJS-$(CONFIG_H264_DXVA2_HWACCEL)      += dxva2_h264.o
 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_IAC_DECODER)             += imc.o
 OBJS-$(CONFIG_IDCIN_DECODER)           += idcinvideo.o
+OBJS-$(CONFIG_IDF_DECODER)             += bintext.o cga_data.o
 OBJS-$(CONFIG_IFF_BYTERUN1_DECODER)    += iff.o
 OBJS-$(CONFIG_IFF_ILBM_DECODER)        += iff.o
 OBJS-$(CONFIG_IMC_DECODER)             += imc.o
@@ -208,6 +236,9 @@
 OBJS-$(CONFIG_INDEO5_DECODER)          += indeo5.o ivi_common.o ivi_dsp.o
 OBJS-$(CONFIG_INTERPLAY_DPCM_DECODER)  += dpcm.o
 OBJS-$(CONFIG_INTERPLAY_VIDEO_DECODER) += interplayvideo.o
+OBJS-$(CONFIG_JACOSUB_DECODER)         += jacosubdec.o ass.o
+OBJS-$(CONFIG_JPEG2000_DECODER)        += j2kdec.o mqcdec.o mqc.o j2k.o j2k_dwt.o
+OBJS-$(CONFIG_JPEG2000_ENCODER)        += j2kenc.o mqcenc.o mqc.o j2k.o j2k_dwt.o
 OBJS-$(CONFIG_JPEGLS_DECODER)          += jpeglsdec.o jpegls.o \
                                           mjpegdec.o mjpeg.o
 OBJS-$(CONFIG_JPEGLS_ENCODER)          += jpeglsenc.o jpegls.o
@@ -220,6 +251,7 @@
 OBJS-$(CONFIG_MACE3_DECODER)           += mace.o
 OBJS-$(CONFIG_MACE6_DECODER)           += mace.o
 OBJS-$(CONFIG_MDEC_DECODER)            += mdec.o mpeg12.o mpeg12data.o
+OBJS-$(CONFIG_MICRODVD_DECODER)        += microdvddec.o ass.o
 OBJS-$(CONFIG_MIMIC_DECODER)           += mimic.o
 OBJS-$(CONFIG_MJPEG_DECODER)           += mjpegdec.o mjpeg.o
 OBJS-$(CONFIG_MJPEG_ENCODER)           += mjpegenc.o mjpeg.o
@@ -227,6 +259,8 @@
 OBJS-$(CONFIG_MLP_DECODER)             += mlpdec.o mlpdsp.o
 OBJS-$(CONFIG_MMVIDEO_DECODER)         += mmvideo.o
 OBJS-$(CONFIG_MOTIONPIXELS_DECODER)    += motionpixels.o
+OBJS-$(CONFIG_MOVTEXT_DECODER)         += movtextdec.o ass.o
+OBJS-$(CONFIG_MOVTEXT_ENCODER)         += movtextenc.o ass_split.o
 OBJS-$(CONFIG_MP1_DECODER)             += mpegaudiodec.o
 OBJS-$(CONFIG_MP1FLOAT_DECODER)        += mpegaudiodec_float.o
 OBJS-$(CONFIG_MP2_DECODER)             += mpegaudiodec.o
@@ -241,13 +275,17 @@
 OBJS-$(CONFIG_MP3ON4FLOAT_DECODER)     += mpegaudiodec_float.o mpeg4audio.o
 OBJS-$(CONFIG_MPC7_DECODER)            += mpc7.o mpc.o
 OBJS-$(CONFIG_MPC8_DECODER)            += mpc8.o mpc.o
+OBJS-$(CONFIG_MPEGVIDEO_DECODER)       += mpeg12.o mpeg12data.o \
+                                          mpegvideo.o error_resilience.o
 OBJS-$(CONFIG_MPEG_XVMC_DECODER)       += mpegvideo_xvmc.o
 OBJS-$(CONFIG_MPEG1VIDEO_DECODER)      += mpeg12.o mpeg12data.o
-OBJS-$(CONFIG_MPEG1VIDEO_ENCODER)      += mpeg12enc.o mpeg12.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_MPEG2VIDEO_DECODER)      += mpeg12.o mpeg12data.o
-OBJS-$(CONFIG_MPEG2VIDEO_ENCODER)      += mpeg12enc.o mpeg12.o
+OBJS-$(CONFIG_MPEG2VIDEO_ENCODER)      += mpeg12enc.o mpeg12.o          \
+                                          timecode.o
 OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL)     += vaapi_mpeg4.o
 OBJS-$(CONFIG_MSMPEG4V1_DECODER)       += msmpeg4.o msmpeg4data.o
 OBJS-$(CONFIG_MSMPEG4V2_DECODER)       += msmpeg4.o msmpeg4data.o h263dec.o \
@@ -265,6 +303,7 @@
 OBJS-$(CONFIG_MSS1_DECODER)            += mss1.o mss12.o
 OBJS-$(CONFIG_MSS2_DECODER)            += mss2.o mss12.o mss2dsp.o
 OBJS-$(CONFIG_MSVIDEO1_DECODER)        += msvideo1.o
+OBJS-$(CONFIG_MSVIDEO1_ENCODER)        += msvideo1enc.o elbg.o
 OBJS-$(CONFIG_MSZH_DECODER)            += lcldec.o
 OBJS-$(CONFIG_MTS2_DECODER)            += mss4.o mss34dsp.o
 OBJS-$(CONFIG_MXPEG_DECODER)           += mxpegdec.o mjpegdec.o mjpeg.o
@@ -272,6 +311,8 @@
 OBJS-$(CONFIG_NELLYMOSER_ENCODER)      += nellymoserenc.o nellymoser.o \
                                           audio_frame_queue.o
 OBJS-$(CONFIG_NUV_DECODER)             += nuv.o rtjpeg.o
+OBJS-$(CONFIG_PAF_VIDEO_DECODER)       += paf.o
+OBJS-$(CONFIG_PAF_AUDIO_DECODER)       += paf.o
 OBJS-$(CONFIG_PAM_DECODER)             += pnmdec.o pnm.o
 OBJS-$(CONFIG_PAM_ENCODER)             += pamenc.o pnm.o
 OBJS-$(CONFIG_PBM_DECODER)             += pnmdec.o pnm.o
@@ -288,8 +329,11 @@
 OBJS-$(CONFIG_PNG_ENCODER)             += png.o pngenc.o
 OBJS-$(CONFIG_PPM_DECODER)             += pnmdec.o pnm.o
 OBJS-$(CONFIG_PPM_ENCODER)             += pnmenc.o pnm.o
-OBJS-$(CONFIG_PRORES_DECODER)          += proresdec.o proresdata.o proresdsp.o
-OBJS-$(CONFIG_PRORES_ENCODER)          += proresenc.o proresdata.o proresdsp.o
+OBJS-$(CONFIG_PRORES_DECODER)          += proresdec2.o proresdsp.o
+OBJS-$(CONFIG_PRORES_LGPL_DECODER)     += proresdec_lgpl.o proresdsp.o proresdata.o
+OBJS-$(CONFIG_PRORES_ENCODER)          += proresenc_anatoliy.o
+OBJS-$(CONFIG_PRORES_ANATOLIY_ENCODER) += proresenc_anatoliy.o
+OBJS-$(CONFIG_PRORES_KOSTYA_ENCODER)   += proresenc_kostya.o proresdata.o proresdsp.o
 OBJS-$(CONFIG_PTX_DECODER)             += ptx.o
 OBJS-$(CONFIG_QCELP_DECODER)           += qcelpdec.o                     \
                                           celp_filters.o acelp_vectors.o \
@@ -300,7 +344,9 @@
 OBJS-$(CONFIG_QTRLE_DECODER)           += qtrle.o
 OBJS-$(CONFIG_QTRLE_ENCODER)           += qtrleenc.o
 OBJS-$(CONFIG_R10K_DECODER)            += r210dec.o
+OBJS-$(CONFIG_R10K_ENCODER)            += r210enc.o
 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
@@ -308,6 +354,7 @@
 OBJS-$(CONFIG_RALF_DECODER)            += ralf.o
 OBJS-$(CONFIG_RAWVIDEO_DECODER)        += rawdec.o
 OBJS-$(CONFIG_RAWVIDEO_ENCODER)        += rawenc.o
+OBJS-$(CONFIG_REALTEXT_DECODER)        += realtextdec.o ass.o
 OBJS-$(CONFIG_RL2_DECODER)             += rl2.o
 OBJS-$(CONFIG_ROQ_DECODER)             += roqvideodec.o roqvideo.o
 OBJS-$(CONFIG_ROQ_ENCODER)             += roqvideoenc.o roqvideo.o elbg.o
@@ -320,7 +367,9 @@
 OBJS-$(CONFIG_RV20_ENCODER)            += rv20enc.o
 OBJS-$(CONFIG_RV30_DECODER)            += rv30.o rv34.o rv30dsp.o rv34dsp.o
 OBJS-$(CONFIG_RV40_DECODER)            += rv40.o rv34.o rv34dsp.o rv40dsp.o
+OBJS-$(CONFIG_SAMI_DECODER)            += samidec.o ass.o
 OBJS-$(CONFIG_S302M_DECODER)           += s302m.o
+OBJS-$(CONFIG_SANM_DECODER)            += sanm.o
 OBJS-$(CONFIG_SGI_DECODER)             += sgidec.o
 OBJS-$(CONFIG_SGI_ENCODER)             += sgienc.o rle.o
 OBJS-$(CONFIG_SHORTEN_DECODER)         += shorten.o
@@ -335,8 +384,15 @@
 OBJS-$(CONFIG_SNOW_ENCODER)            += snowenc.o snow.o              \
                                           h263.o ituh263enc.o
 OBJS-$(CONFIG_SOL_DPCM_DECODER)        += dpcm.o
+OBJS-$(CONFIG_SONIC_DECODER)           += sonic.o
+OBJS-$(CONFIG_SONIC_ENCODER)           += sonic.o
+OBJS-$(CONFIG_SONIC_LS_ENCODER)        += sonic.o
 OBJS-$(CONFIG_SP5X_DECODER)            += sp5xdec.o mjpegdec.o mjpeg.o
 OBJS-$(CONFIG_SRT_DECODER)             += srtdec.o ass.o
+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_SUBVIEWER_DECODER)       += subviewerdec.o ass.o
 OBJS-$(CONFIG_SUNRAST_DECODER)         += sunrast.o
 OBJS-$(CONFIG_SUNRAST_ENCODER)         += sunrastenc.o
 OBJS-$(CONFIG_SVQ1_DECODER)            += svq1dec.o svq1.o svq13.o h263.o
@@ -346,14 +402,17 @@
                                           h264_loopfilter.o h264_direct.o     \
                                           h264_sei.o h264_ps.o h264_refs.o    \
                                           h264_cavlc.o h264_cabac.o cabac.o
+OBJS-$(CONFIG_TAK_DECODER)             += takdec.o tak.o
 OBJS-$(CONFIG_TARGA_DECODER)           += targa.o
 OBJS-$(CONFIG_TARGA_ENCODER)           += targaenc.o rle.o
+OBJS-$(CONFIG_TARGA_Y216_DECODER)      += targa_y216dec.o
 OBJS-$(CONFIG_THEORA_DECODER)          += xiph.o
 OBJS-$(CONFIG_THP_DECODER)             += mjpegdec.o mjpeg.o
 OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o
-OBJS-$(CONFIG_TIFF_DECODER)            += tiff.o lzw.o faxcompr.o
-OBJS-$(CONFIG_TIFF_ENCODER)            += tiffenc.o rle.o lzwenc.o
+OBJS-$(CONFIG_TIFF_DECODER)            += tiff.o lzw.o faxcompr.o tiff_data.o
+OBJS-$(CONFIG_TIFF_ENCODER)            += tiffenc.o rle.o lzwenc.o tiff_data.o
 OBJS-$(CONFIG_TMV_DECODER)             += tmv.o cga_data.o
+OBJS-$(CONFIG_TRUEHD_DECODER)          += mlpdec.o mlpdsp.o
 OBJS-$(CONFIG_TRUEMOTION1_DECODER)     += truemotion1.o
 OBJS-$(CONFIG_TRUEMOTION2_DECODER)     += truemotion2.o
 OBJS-$(CONFIG_TRUESPEECH_DECODER)      += truespeech.o
@@ -367,6 +426,10 @@
 OBJS-$(CONFIG_UTVIDEO_ENCODER)         += utvideoenc.o utvideo.o
 OBJS-$(CONFIG_V210_DECODER)            += v210dec.o
 OBJS-$(CONFIG_V210_ENCODER)            += v210enc.o
+OBJS-$(CONFIG_V308_DECODER)            += v308dec.o
+OBJS-$(CONFIG_V308_ENCODER)            += v308enc.o
+OBJS-$(CONFIG_V408_DECODER)            += v408dec.o
+OBJS-$(CONFIG_V408_ENCODER)            += v408enc.o
 OBJS-$(CONFIG_V410_DECODER)            += v410dec.o
 OBJS-$(CONFIG_V410_ENCODER)            += v410enc.o
 OBJS-$(CONFIG_V210X_DECODER)           += v210x.o
@@ -394,6 +457,7 @@
 OBJS-$(CONFIG_VP8_DECODER)             += vp8.o vp8dsp.o vp56rac.o
 OBJS-$(CONFIG_VQA_DECODER)             += vqavideo.o
 OBJS-$(CONFIG_WAVPACK_DECODER)         += wavpack.o
+OBJS-$(CONFIG_WEBVTT_DECODER)          += webvttdec.o
 OBJS-$(CONFIG_WMALOSSLESS_DECODER)     += wmalosslessdec.o wma_common.o
 OBJS-$(CONFIG_WMAPRO_DECODER)          += wmaprodec.o wma.o wma_common.o
 OBJS-$(CONFIG_WMAV1_DECODER)           += wmadec.o wma.o wma_common.o aactab.o
@@ -415,13 +479,19 @@
 OBJS-$(CONFIG_XAN_DPCM_DECODER)        += dpcm.o
 OBJS-$(CONFIG_XAN_WC3_DECODER)         += xan.o
 OBJS-$(CONFIG_XAN_WC4_DECODER)         += xxan.o
+OBJS-$(CONFIG_XBIN_DECODER)            += bintext.o cga_data.o
+OBJS-$(CONFIG_XBM_DECODER)             += xbmdec.o
 OBJS-$(CONFIG_XBM_ENCODER)             += xbmenc.o
 OBJS-$(CONFIG_XL_DECODER)              += xl.o
 OBJS-$(CONFIG_XSUB_DECODER)            += xsubdec.o
 OBJS-$(CONFIG_XSUB_ENCODER)            += xsubenc.o
 OBJS-$(CONFIG_XWD_DECODER)             += xwddec.o
 OBJS-$(CONFIG_XWD_ENCODER)             += xwdenc.o
+OBJS-$(CONFIG_Y41P_DECODER)            += y41pdec.o
+OBJS-$(CONFIG_Y41P_ENCODER)            += y41penc.o
 OBJS-$(CONFIG_YOP_DECODER)             += yop.o
+OBJS-$(CONFIG_YUV4_DECODER)            += yuv4dec.o
+OBJS-$(CONFIG_YUV4_ENCODER)            += yuv4enc.o
 OBJS-$(CONFIG_ZEROCODEC_DECODER)       += zerocodec.o
 OBJS-$(CONFIG_ZLIB_DECODER)            += lcldec.o
 OBJS-$(CONFIG_ZLIB_ENCODER)            += lclenc.o
@@ -517,6 +587,7 @@
 OBJS-$(CONFIG_ADPCM_XA_DECODER)           += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER)       += adpcm.o adpcm_data.o
 OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER)       += adpcmenc.o adpcm_data.o
+OBJS-$(CONFIG_VIMA_DECODER)               += vima.o adpcm_data.o
 
 # libavformat dependencies
 OBJS-$(CONFIG_ADTS_MUXER)              += mpeg4audio.o
@@ -524,40 +595,45 @@
 OBJS-$(CONFIG_CAF_DEMUXER)             += mpeg4audio.o mpegaudiodata.o  \
                                           ac3tab.o
 OBJS-$(CONFIG_DV_DEMUXER)              += dv_profile.o
-OBJS-$(CONFIG_DV_MUXER)                += dv_profile.o
-OBJS-$(CONFIG_FLAC_DEMUXER)            += flac.o flacdata.o             \
+OBJS-$(CONFIG_DV_MUXER)                += dv_profile.o timecode.o
+OBJS-$(CONFIG_FLAC_DEMUXER)            += flac.o flacdata.o vorbis_data.o \
                                           vorbis_parser.o xiph.o
-OBJS-$(CONFIG_FLAC_MUXER)              += flac.o flacdata.o
+OBJS-$(CONFIG_FLAC_MUXER)              += flac.o flacdata.o vorbis_data.o
 OBJS-$(CONFIG_FLV_DEMUXER)             += mpeg4audio.o
 OBJS-$(CONFIG_GXF_DEMUXER)             += mpeg12data.o
 OBJS-$(CONFIG_IFF_DEMUXER)             += iff.o
 OBJS-$(CONFIG_ISMV_MUXER)              += mpeg4audio.o mpegaudiodata.o
 OBJS-$(CONFIG_LATM_MUXER)              += mpeg4audio.o
-OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER)    += xiph.o mpeg4audio.o           \
+OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER)    += xiph.o mpeg4audio.o vorbis_data.o \
                                           flac.o flacdata.o
 OBJS-$(CONFIG_MATROSKA_DEMUXER)        += mpeg4audio.o mpegaudiodata.o
 OBJS-$(CONFIG_MATROSKA_MUXER)          += mpeg4audio.o mpegaudiodata.o  \
-                                          flac.o flacdata.o xiph.o
+                                          flac.o flacdata.o vorbis_data.o xiph.o
 OBJS-$(CONFIG_MP2_MUXER)               += mpegaudiodata.o mpegaudiodecheader.o
 OBJS-$(CONFIG_MP3_MUXER)               += mpegaudiodata.o mpegaudiodecheader.o
-OBJS-$(CONFIG_MOV_DEMUXER)             += mpeg4audio.o mpegaudiodata.o ac3tab.o
+OBJS-$(CONFIG_MOV_DEMUXER)             += mpeg4audio.o mpegaudiodata.o ac3tab.o timecode.o
 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_NUT_MUXER)               += mpegaudiodata.o
 OBJS-$(CONFIG_OGG_DEMUXER)             += xiph.o flac.o flacdata.o     \
                                           mpeg12data.o vorbis_parser.o \
-                                          dirac.o
-OBJS-$(CONFIG_OGG_MUXER)               += xiph.o flac.o flacdata.o
+                                          dirac.o vorbis_data.o
+OBJS-$(CONFIG_OGG_MUXER)               += xiph.o flac.o flacdata.o \
+                                          vorbis_data.o
 OBJS-$(CONFIG_RTP_MUXER)               += mpeg4audio.o xiph.o
 OBJS-$(CONFIG_RTPDEC)                  += mjpeg.o
 OBJS-$(CONFIG_SPDIF_DEMUXER)           += aacadtsdec.o mpeg4audio.o
 OBJS-$(CONFIG_SPDIF_MUXER)             += dca.o
 OBJS-$(CONFIG_WEBM_MUXER)              += mpeg4audio.o mpegaudiodata.o  \
-                                          xiph.o flac.o flacdata.o
+                                          xiph.o flac.o flacdata.o \
+                                          vorbis_data.o
 OBJS-$(CONFIG_WTV_DEMUXER)             += mpeg4audio.o mpegaudiodata.o
 
 # 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_LIBGSM_DECODER)             += libgsm.o
@@ -568,8 +644,10 @@
 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
-OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER)  += libopencore-amr.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_LIBOPENCORE_AMRWB_DECODER)  += libopencore-amr.o
 OBJS-$(CONFIG_LIBOPENJPEG_DECODER)        += libopenjpegdec.o
 OBJS-$(CONFIG_LIBOPENJPEG_ENCODER)        += libopenjpegenc.o
@@ -583,11 +661,17 @@
                                              libschroedinger.o
 OBJS-$(CONFIG_LIBSPEEX_DECODER)           += libspeexdec.o
 OBJS-$(CONFIG_LIBSPEEX_ENCODER)           += libspeexenc.o audio_frame_queue.o
+OBJS-$(CONFIG_LIBSTAGEFRIGHT_H264_DECODER)+= libstagefright.o
 OBJS-$(CONFIG_LIBTHEORA_ENCODER)          += libtheoraenc.o
-OBJS-$(CONFIG_LIBVO_AACENC_ENCODER)       += libvo-aacenc.o mpeg4audio.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_AMRWBENC_ENCODER)     += libvo-amrwbenc.o
-OBJS-$(CONFIG_LIBVORBIS_ENCODER)          += libvorbis.o audio_frame_queue.o \
-                                             vorbis_data.o vorbis_parser.o
+OBJS-$(CONFIG_LIBVORBIS_DECODER)          += libvorbisdec.o
+OBJS-$(CONFIG_LIBVORBIS_ENCODER)          += libvorbisenc.o audio_frame_queue.o \
+                                             vorbis_data.o vorbis_parser.o xiph.o
 OBJS-$(CONFIG_LIBVPX_DECODER)             += libvpxdec.o
 OBJS-$(CONFIG_LIBVPX_ENCODER)             += libvpxenc.o
 OBJS-$(CONFIG_LIBX264_ENCODER)            += libx264.o
@@ -601,6 +685,7 @@
 OBJS-$(CONFIG_AC3_PARSER)              += ac3_parser.o ac3tab.o \
                                           aac_ac3_parser.o
 OBJS-$(CONFIG_ADX_PARSER)              += adx_parser.o adx.o
+OBJS-$(CONFIG_BMP_PARSER)              += bmp_parser.o
 OBJS-$(CONFIG_CAVSVIDEO_PARSER)        += cavs_parser.o
 OBJS-$(CONFIG_COOK_PARSER)             += cook_parser.o
 OBJS-$(CONFIG_DCA_PARSER)              += dca_parser.o dca.o
@@ -608,7 +693,8 @@
 OBJS-$(CONFIG_DNXHD_PARSER)            += dnxhd_parser.o
 OBJS-$(CONFIG_DVBSUB_PARSER)           += dvbsub_parser.o
 OBJS-$(CONFIG_DVDSUB_PARSER)           += dvdsub_parser.o
-OBJS-$(CONFIG_FLAC_PARSER)             += flac_parser.o flacdata.o flac.o
+OBJS-$(CONFIG_FLAC_PARSER)             += flac_parser.o flacdata.o flac.o \
+                                          vorbis_data.o
 OBJS-$(CONFIG_GSM_PARSER)              += gsm_parser.o
 OBJS-$(CONFIG_H261_PARSER)             += h261_parser.o
 OBJS-$(CONFIG_H263_PARSER)             += h263_parser.o
@@ -622,6 +708,7 @@
 OBJS-$(CONFIG_MPEG4VIDEO_PARSER)       += mpeg4video_parser.o h263.o \
                                           mpeg4videodec.o mpeg4video.o \
                                           ituh263dec.o h263dec.o
+OBJS-$(CONFIG_PNG_PARSER)              += png_parser.o
 OBJS-$(CONFIG_MPEGAUDIO_PARSER)        += mpegaudio_parser.o \
                                           mpegaudiodecheader.o mpegaudiodata.o
 OBJS-$(CONFIG_MPEGVIDEO_PARSER)        += mpegvideo_parser.o    \
@@ -629,6 +716,7 @@
 OBJS-$(CONFIG_PNM_PARSER)              += pnm_parser.o pnm.o
 OBJS-$(CONFIG_RV30_PARSER)             += rv34_parser.o
 OBJS-$(CONFIG_RV40_PARSER)             += rv34_parser.o
+OBJS-$(CONFIG_TAK_PARSER)              += tak_parser.o tak.o
 OBJS-$(CONFIG_VC1_PARSER)              += vc1_parser.o vc1.o vc1data.o \
                                           msmpeg4.o msmpeg4data.o mpeg4video.o \
                                           h263.o
@@ -654,8 +742,9 @@
 OBJS-$(CONFIG_TEXT2MOVSUB_BSF)            += movsub_bsf.o
 
 # thread libraries
-OBJS-$(HAVE_PTHREADS)                  += pthread.o
-OBJS-$(HAVE_W32THREADS)                += pthread.o
+OBJS-$(HAVE_PTHREADS)                  += pthread.o frame_thread_encoder.o
+OBJS-$(HAVE_W32THREADS)                += pthread.o frame_thread_encoder.o
+OBJS-$(HAVE_OS2THREADS)                += pthread.o frame_thread_encoder.o
 
 SKIPHEADERS                            += %_tablegen.h                  \
                                           %_tables.h                    \
@@ -667,14 +756,14 @@
 
 SKIPHEADERS-$(CONFIG_DXVA2)            += dxva2.h dxva2_internal.h
 SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER)  += libschroedinger.h
+SKIPHEADERS-$(CONFIG_LIBUTVIDEO)       += libutvideo.h
 SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h
 SKIPHEADERS-$(CONFIG_VAAPI)            += vaapi_internal.h
 SKIPHEADERS-$(CONFIG_VDA)              += vda.h
 SKIPHEADERS-$(CONFIG_VDPAU)            += vdpau.h
+SKIPHEADERS-$(HAVE_OS2THREADS)         += os2threads.h
 SKIPHEADERS-$(HAVE_W32THREADS)         += w32pthreads.h
 
-EXAMPLES = api
-
 TESTPROGS = cabac                                                       \
             dct                                                         \
             fft                                                         \
@@ -682,9 +771,13 @@
             golomb                                                      \
             iirfilter                                                   \
             rangecoder                                                  \
+            snowenc                                                     \
 
+TESTPROGS-$(HAVE_MMX) += motion
 TESTOBJS = dctref.o
 
+TOOLS = fourcc2pixfmt
+
 HOSTPROGS = aac_tablegen                                                \
             aacps_tablegen                                              \
             cbrt_tablegen                                               \
diff --git a/libavcodec/a64colors.h b/libavcodec/a64colors.h
index d977426..a9cdb6f 100644
--- a/libavcodec/a64colors.h
+++ b/libavcodec/a64colors.h
@@ -2,20 +2,20 @@
  * a64 video encoder - c64 colors in rgb (Pepto)
  * Copyright (c) 2009 Tobias Bindhammer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/a64enc.h b/libavcodec/a64enc.h
index d5f8e9a..2895995 100644
--- a/libavcodec/a64enc.h
+++ b/libavcodec/a64enc.h
@@ -2,20 +2,20 @@
  * a64 video encoder - basic headers
  * Copyright (c) 2009 Tobias Bindhammer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/a64multienc.c b/libavcodec/a64multienc.c
index beddf9f..0f6cc76 100644
--- a/libavcodec/a64multienc.c
+++ b/libavcodec/a64multienc.c
@@ -2,20 +2,20 @@
  * a64 video encoder - multicolor modes
  * Copyright (c) 2009 Tobias Bindhammer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -255,7 +255,7 @@
     int b_width;
 
     int req_size, ret;
-    uint8_t *buf;
+    uint8_t *buf = NULL;
 
     int *charmap     = c->mc_charmap;
     uint8_t *colram  = c->mc_colram;
@@ -309,10 +309,8 @@
         /* any frames to encode? */
         if (c->mc_lifetime) {
             req_size = charset_size + c->mc_lifetime*(screen_size + colram_size);
-            if ((ret = ff_alloc_packet(pkt, req_size)) < 0) {
-                av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n", req_size);
+            if ((ret = ff_alloc_packet2(avctx, pkt, req_size)) < 0)
                 return ret;
-            }
             buf = pkt->data;
 
             /* calc optimal new charset + charmaps */
@@ -371,6 +369,7 @@
     return 0;
 }
 
+#if CONFIG_A64MULTI_ENCODER
 AVCodec ff_a64multi_encoder = {
     .name           = "a64multi",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -383,7 +382,8 @@
     .long_name      = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64"),
     .capabilities   = CODEC_CAP_DELAY,
 };
-
+#endif
+#if CONFIG_A64MULTI5_ENCODER
 AVCodec ff_a64multi5_encoder = {
     .name           = "a64multi5",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -396,3 +396,4 @@
     .long_name      = NULL_IF_CONFIG_SMALL("Multicolor charset for Commodore 64, extended with 5th color (colram)"),
     .capabilities   = CODEC_CAP_DELAY,
 };
+#endif
diff --git a/libavcodec/a64tables.h b/libavcodec/a64tables.h
index b95c5ce..a955ef4 100644
--- a/libavcodec/a64tables.h
+++ b/libavcodec/a64tables.h
@@ -2,20 +2,20 @@
  * a64 video encoder - tables used by a64 encoders
  * Copyright (c) 2009 Tobias Bindhammer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aac.h b/libavcodec/aac.h
index 32baf9d..1070e5f 100644
--- a/libavcodec/aac.h
+++ b/libavcodec/aac.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
  * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -304,9 +304,19 @@
     float *output_data[MAX_CHANNELS];                 ///< Points to each element's 'ret' buffer (PCM output).
     /** @} */
 
+
+    /**
+     * @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.
+    /** @} */
+
     DECLARE_ALIGNED(32, float, temp)[128];
 
     OutputConfiguration oc[2];
+    int warned_num_aac_frames;
 } AACContext;
 
 #endif /* AVCODEC_AAC_H */
diff --git a/libavcodec/aac_ac3_parser.c b/libavcodec/aac_ac3_parser.c
index b17cd4d..6f1e188 100644
--- a/libavcodec/aac_ac3_parser.c
+++ b/libavcodec/aac_ac3_parser.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aac_ac3_parser.h b/libavcodec/aac_ac3_parser.h
index 90b49c5..ca49d2f 100644
--- a/libavcodec/aac_ac3_parser.h
+++ b/libavcodec/aac_ac3_parser.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aac_adtstoasc_bsf.c b/libavcodec/aac_adtstoasc_bsf.c
index a659934..519641c 100644
--- a/libavcodec/aac_adtstoasc_bsf.c
+++ b/libavcodec/aac_adtstoasc_bsf.c
@@ -2,20 +2,20 @@
  * MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration bitstream filter
  * Copyright (c) 2009 Alex Converse <alex.converse@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aac_parser.c b/libavcodec/aac_parser.c
index fdaa5f8..ab6ca4e 100644
--- a/libavcodec/aac_parser.c
+++ b/libavcodec/aac_parser.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aac_tablegen.c b/libavcodec/aac_tablegen.c
index b2c6c95..33a179f 100644
--- a/libavcodec/aac_tablegen.c
+++ b/libavcodec/aac_tablegen.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aac_tablegen.h b/libavcodec/aac_tablegen.h
index 8773d9b..7afa466 100644
--- a/libavcodec/aac_tablegen.h
+++ b/libavcodec/aac_tablegen.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aac_tablegen_decl.h b/libavcodec/aac_tablegen_decl.h
index 496ca0c..0d86e80 100644
--- a/libavcodec/aac_tablegen_decl.h
+++ b/libavcodec/aac_tablegen_decl.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aacadtsdec.c b/libavcodec/aacadtsdec.c
index 30f92e0..c9718c4 100644
--- a/libavcodec/aacadtsdec.c
+++ b/libavcodec/aacadtsdec.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2003 Michael Niedermayer
  * Copyright (c) 2009 Alex Converse
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aacadtsdec.h b/libavcodec/aacadtsdec.h
index 6319efc..d0584ef 100644
--- a/libavcodec/aacadtsdec.h
+++ b/libavcodec/aacadtsdec.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c
index d65d8d9..994de28 100644
--- a/libavcodec/aaccoder.c
+++ b/libavcodec/aaccoder.c
@@ -2,20 +2,20 @@
  * AAC coefficients encoder
  * Copyright (C) 2008-2009 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -506,7 +506,7 @@
             idx = cb;
     ppos = max_sfb;
     while (ppos > 0) {
-        assert(idx >= 0);
+        av_assert1(idx >= 0);
         cb = idx;
         stackrun[stack_len] = path[ppos][cb].run;
         stackcb [stack_len] = cb;
@@ -875,7 +875,7 @@
     } else {
         for (w = 0; w < 8; w++) {
             const float *coeffs = sce->coeffs + w*128;
-            start = 0;
+            curband = start = 0;
             for (i = 0; i < 128; i++) {
                 if (i - start >= sce->ics.swb_sizes[curband]) {
                     start += sce->ics.swb_sizes[curband];
@@ -1112,7 +1112,7 @@
     }
 }
 
-AACCoefficientsEncoder ff_aac_coders[] = {
+AACCoefficientsEncoder ff_aac_coders[AAC_CODER_NB] = {
     {
         search_for_quantizers_faac,
         encode_window_bands_info,
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index 859414a..8ab6787 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -7,20 +7,20 @@
  * Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz>
  * Copyright (c) 2010      Janne Grunau <janne-libav@jannau.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -112,7 +112,7 @@
 static VLC vlc_scalefactors;
 static VLC vlc_spectral[11];
 
-static const char overread_err[] = "Input buffer exhausted before END element found\n";
+#define overread_err "Input buffer exhausted before END element found\n"
 
 static int count_channels(uint8_t (*layout)[3], int tags)
 {
@@ -129,7 +129,7 @@
 /**
  * Check for the channel element in the current channel position configuration.
  * If it exists, make sure the appropriate element is allocated and map the
- * channel order to match the internal Libav channel layout.
+ * channel order to match the internal FFmpeg channel layout.
  *
  * @param   che_pos current channel position configuration
  * @param   type channel element type
@@ -149,6 +149,10 @@
             ff_aac_sbr_ctx_init(ac, &ac->che[type][id]->sbr);
         }
         if (type != TYPE_CCE) {
+            if (*channels >= MAX_CHANNELS - (type == TYPE_CPE || (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1))) {
+                av_log(ac->avctx, AV_LOG_ERROR, "Too many channels\n");
+                return AVERROR_INVALIDDATA;
+            }
             ac->output_data[(*channels)++] = ac->che[type][id]->ch[0].ret;
             if (type == TYPE_CPE ||
                 (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1)) {
@@ -413,13 +417,31 @@
     }
 
     memcpy(ac->tag_che_map, ac->che, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0]));
-    avctx->channel_layout = ac->oc[1].channel_layout = layout;
+    if (layout) avctx->channel_layout = layout;
+    ac->oc[1].channel_layout = layout;
     avctx->channels = ac->oc[1].channels = channels;
     ac->oc[1].status = oc_type;
 
     return 0;
 }
 
+static void flush(AVCodecContext *avctx)
+{
+    AACContext *ac= avctx->priv_data;
+    int type, i, j;
+
+    for (type = 3; type >= 0; type--) {
+        for (i = 0; i < MAX_ELEM_ID; i++) {
+            ChannelElement *che = ac->che[type][i];
+            if (che) {
+                for (j = 0; j <= 1; j++) {
+                    memset(che->ch[j].saved, 0, sizeof(che->ch[j].saved));
+                }
+            }
+        }
+    }
+}
+
 /**
  * Set up channel positions based on a default channel configuration
  * as specified in table 1.17.
@@ -453,6 +475,8 @@
         int layout_map_tags;
         push_output_configuration(ac);
 
+        av_log(ac->avctx, AV_LOG_DEBUG, "mono with CPE\n");
+
         if (set_default_channel_config(ac->avctx, layout_map, &layout_map_tags,
                                        2) < 0)
             return NULL;
@@ -469,6 +493,8 @@
         int layout_map_tags;
         push_output_configuration(ac);
 
+        av_log(ac->avctx, AV_LOG_DEBUG, "stereo with SCE\n");
+
         if (set_default_channel_config(ac->avctx, layout_map, &layout_map_tags,
                                        1) < 0)
             return NULL;
@@ -547,6 +573,8 @@
         case AAC_CHANNEL_LFE:
             syn_ele = TYPE_LFE;
             break;
+        default:
+            av_assert0(0);
         }
         layout_map[0][0] = syn_ele;
         layout_map[0][1] = get_bits(gb, 4);
@@ -589,6 +617,10 @@
     if (get_bits1(gb))
         skip_bits(gb, 3); // mixdown_coeff_index and pseudo_surround
 
+    if (get_bits_left(gb) < 4 * (num_front + num_side + num_back + num_lfe + num_assoc_data + num_cc)) {
+        av_log(avctx, AV_LOG_ERROR, "decode_pce: " overread_err);
+        return -1;
+    }
     decode_channel_map(layout_map       , AAC_CHANNEL_FRONT, gb, num_front);
     tags = num_front;
     decode_channel_map(layout_map + tags, AAC_CHANNEL_SIDE,  gb, num_side);
@@ -608,7 +640,7 @@
     /* comment field, first byte is length */
     comment_len = get_bits(gb, 8) * 8;
     if (get_bits_left(gb) < comment_len) {
-        av_log(avctx, AV_LOG_ERROR, overread_err);
+        av_log(avctx, AV_LOG_ERROR, "decode_pce: " overread_err);
         return -1;
     }
     skip_bits_long(gb, comment_len);
@@ -706,9 +738,9 @@
     GetBitContext gb;
     int i;
 
-    av_dlog(avctx, "extradata size %d\n", avctx->extradata_size);
-    for (i = 0; i < avctx->extradata_size; i++)
-         av_dlog(avctx, "%02x ", avctx->extradata[i]);
+    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);
@@ -749,7 +781,7 @@
  *
  * @return  Returns a 32-bit pseudorandom integer
  */
-static av_always_inline int lcg_random(int previous_val)
+static av_always_inline int lcg_random(unsigned previous_val)
 {
     return previous_val * 1664525 + 1013904223;
 }
@@ -808,6 +840,14 @@
     ac->avctx = avctx;
     ac->oc[1].m4ac.sample_rate = avctx->sample_rate;
 
+    if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) {
+        avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+        output_scale_factor = 1.0 / 32768.0;
+    } else {
+        avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+        output_scale_factor = 1.0;
+    }
+
     if (avctx->extradata_size > 0) {
         if (decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,
                                          avctx->extradata,
@@ -843,14 +883,6 @@
         }
     }
 
-    if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) {
-        avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
-        output_scale_factor = 1.0 / 32768.0;
-    } else {
-        avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-        output_scale_factor = 1.0;
-    }
-
     AAC_INIT_VLC_STATIC( 0, 304);
     AAC_INIT_VLC_STATIC( 1, 270);
     AAC_INIT_VLC_STATIC( 2, 550);
@@ -908,7 +940,7 @@
         align_get_bits(gb);
 
     if (get_bits_left(gb) < 8 * count) {
-        av_log(ac->avctx, AV_LOG_ERROR, overread_err);
+        av_log(ac->avctx, AV_LOG_ERROR, "skip_data_stream_element: "overread_err);
         return -1;
     }
     skip_bits_long(gb, 8 * count);
@@ -989,11 +1021,11 @@
         if (ics->predictor_present) {
             if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN) {
                 if (decode_prediction(ac, ics, gb)) {
-                    return AVERROR_INVALIDDATA;
+                    goto fail;
                 }
             } else if (ac->oc[1].m4ac.object_type == AOT_AAC_LC) {
                 av_log(ac->avctx, AV_LOG_ERROR, "Prediction is not allowed in AAC-LC.\n");
-                return AVERROR_INVALIDDATA;
+                goto fail;
             } else {
                 if ((ics->ltp.present = get_bits(gb, 1)))
                     decode_ltp(ac, &ics->ltp, gb, ics->max_sfb);
@@ -1005,10 +1037,13 @@
         av_log(ac->avctx, AV_LOG_ERROR,
                "Number of scalefactor bands in group (%d) exceeds limit (%d).\n",
                ics->max_sfb, ics->num_swb);
-        return AVERROR_INVALIDDATA;
+        goto fail;
     }
 
     return 0;
+fail:
+    ics->max_sfb = 0;
+    return AVERROR_INVALIDDATA;
 }
 
 /**
@@ -1039,7 +1074,7 @@
                 sect_len_incr = get_bits(gb, bits);
                 sect_end += sect_len_incr;
                 if (get_bits_left(gb) < 0) {
-                    av_log(ac->avctx, AV_LOG_ERROR, overread_err);
+                    av_log(ac->avctx, AV_LOG_ERROR, "decode_band_types: "overread_err);
                     return -1;
                 }
                 if (sect_end > ics->max_sfb) {
@@ -1912,6 +1947,32 @@
     return n;
 }
 
+static int decode_fill(AACContext *ac, GetBitContext *gb, int len) {
+    uint8_t buf[256];
+    int i, major, minor;
+
+    if (len < 13+7*8)
+        goto unknown;
+
+    get_bits(gb, 13); len -= 13;
+
+    for(i=0; i+1<sizeof(buf) && len>=8; i++, len-=8)
+        buf[i] = get_bits(gb, 8);
+
+    buf[i] = 0;
+    if (ac->avctx->debug & FF_DEBUG_PICT_INFO)
+        av_log(ac->avctx, AV_LOG_DEBUG, "FILL:%s\n", buf);
+
+    if (sscanf(buf, "libfaac %d.%d", &major, &minor) == 2){
+        ac->avctx->internal->skip_samples = 1024;
+    }
+
+unknown:
+    skip_bits_long(gb, len);
+
+    return 0;
+}
+
 /**
  * Decode extension data (incomplete); reference: table 4.51.
  *
@@ -1953,6 +2014,8 @@
         res = decode_dynamic_range(&ac->che_drc, gb, cnt);
         break;
     case EXT_FILL:
+        decode_fill(ac, gb, 8 * cnt - 4);
+        break;
     case EXT_FILL_DATA:
     case EXT_DATA_ELEMENT:
     default:
@@ -2322,9 +2385,11 @@
 
     size = avpriv_aac_parse_header(gb, &hdr_info);
     if (size > 0) {
-        if (hdr_info.num_aac_frames != 1) {
+        if (!ac->warned_num_aac_frames && hdr_info.num_aac_frames != 1) {
+            // This is 2 for "VLB " audio in NSV files.
+            // See samples/nsv/vlb_audio.
             av_log_missing_feature(ac->avctx, "More than one AAC RDB per ADTS frame", 0);
-            return -1;
+            ac->warned_num_aac_frames = 1;
         }
         push_output_configuration(ac);
         if (hdr_info.chan_config) {
@@ -2338,6 +2403,21 @@
                 return -7;
         } else {
             ac->oc[1].m4ac.chan_config = 0;
+            /**
+             * dual mono frames in Japanese DTV can have chan_config 0
+             * WITHOUT specifying PCE.
+             *  thus, set dual mono as default.
+             */
+            if (ac->enable_jp_dmono && 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,
+                                     0, OC_TRIAL_FRAME))
+                    return -7;
+            }
         }
         ac->oc[1].m4ac.sample_rate     = hdr_info.sample_rate;
         ac->oc[1].m4ac.sampling_index  = hdr_info.sampling_index;
@@ -2355,13 +2435,15 @@
 }
 
 static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
-                                int *got_frame_ptr, GetBitContext *gb)
+                                int *got_frame_ptr, GetBitContext *gb, AVPacket *avpkt)
 {
     AACContext *ac = avctx->priv_data;
     ChannelElement *che = NULL, *che_prev = NULL;
     enum RawDataBlockType elem_type, elem_type_prev = TYPE_END;
     int err, elem_id;
     int samples = 0, multiplier, audio_found = 0, pce_found = 0;
+    int is_dmono, sce_count = 0;
+    float *tmp = NULL;
 
     if (show_bits(gb, 12) == 0xfff) {
         if (parse_adts_frame_header(ac, gb) < 0) {
@@ -2396,6 +2478,7 @@
         case TYPE_SCE:
             err = decode_ics(ac, &che->ch[0], gb, 0, 0);
             audio_found = 1;
+            sce_count++;
             break;
 
         case TYPE_CPE:
@@ -2431,6 +2514,8 @@
                 pop_output_configuration(ac);
             } else {
                 err = output_configure(ac, layout_map, tags, 0, OC_TRIAL_PCE);
+                if (!err)
+                    ac->oc[1].m4ac.chan_config = 0;
                 pce_found = 1;
             }
             break;
@@ -2440,7 +2525,7 @@
             if (elem_id == 15)
                 elem_id += get_bits(gb, 8) - 1;
             if (get_bits_left(gb) < 8 * elem_id) {
-                    av_log(avctx, AV_LOG_ERROR, overread_err);
+                    av_log(avctx, AV_LOG_ERROR, "TYPE_FIL: "overread_err);
                     err = -1;
                     goto fail;
             }
@@ -2472,6 +2557,20 @@
     multiplier = (ac->oc[1].m4ac.sbr == 1) ? ac->oc[1].m4ac.ext_sample_rate > ac->oc[1].m4ac.sample_rate : 0;
     samples <<= multiplier;
 
+    /* for dual-mono audio (SCE + SCE) */
+    is_dmono = ac->enable_jp_dmono && 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];
+        }
+    }
+
     if (samples) {
         /* get output buffer */
         ac->frame.nb_samples = samples;
@@ -2494,12 +2593,25 @@
     }
     *got_frame_ptr = !!samples;
 
+    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->oc[1].status && audio_found) {
         avctx->sample_rate = ac->oc[1].m4ac.sample_rate << multiplier;
         avctx->frame_size = samples;
         ac->oc[1].status = OC_LOCKED;
     }
 
+    if (multiplier) {
+        int side_size;
+        uint32_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));
+    }
     return 0;
 fail:
     pop_output_configuration(ac);
@@ -2520,8 +2632,12 @@
     const uint8_t *new_extradata = av_packet_get_side_data(avpkt,
                                        AV_PKT_DATA_NEW_EXTRADATA,
                                        &new_extradata_size);
+    int jp_dualmono_size;
+    const uint8_t *jp_dualmono   = av_packet_get_side_data(avpkt,
+                                       AV_PKT_DATA_JP_DUALMONO,
+                                       &jp_dualmono_size);
 
-    if (new_extradata) {
+    if (new_extradata && 0) {
         av_free(avctx->extradata);
         avctx->extradata = av_mallocz(new_extradata_size +
                                       FF_INPUT_BUFFER_PADDING_SIZE);
@@ -2538,9 +2654,14 @@
         }
     }
 
+    ac->enable_jp_dmono = !!jp_dualmono;
+    ac->dmono_mode = 0;
+    if (jp_dualmono && jp_dualmono_size > 0)
+        ac->dmono_mode = *jp_dualmono;
+
     init_get_bits(&gb, buf, buf_size * 8);
 
-    if ((err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb)) < 0)
+    if ((err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb, avpkt)) < 0)
         return err;
 
     buf_consumed = (get_bits_count(&gb) + 7) >> 3;
@@ -2575,7 +2696,7 @@
 
 struct LATMContext {
     AACContext      aac_ctx;             ///< containing AACContext
-    int             initialized;         ///< initilized after a valid extradata was seen
+    int             initialized;         ///< initialized after a valid extradata was seen
 
     // parser data
     int             audio_mux_version_A; ///< LATM syntax version
@@ -2620,10 +2741,15 @@
     if (bits_consumed < 0)
         return AVERROR_INVALIDDATA;
 
-    if (ac->oc[1].m4ac.sample_rate != m4ac.sample_rate ||
+    if (!latmctx->initialized ||
+        ac->oc[1].m4ac.sample_rate != m4ac.sample_rate ||
         ac->oc[1].m4ac.chan_config != m4ac.chan_config) {
 
-        av_log(avctx, AV_LOG_INFO, "audio config changed\n");
+        if(latmctx->initialized) {
+            av_log(avctx, AV_LOG_INFO, "audio config changed\n");
+        } else {
+            av_log(avctx, AV_LOG_INFO, "initializing latmctx\n");
+        }
         latmctx->initialized = 0;
 
         esize = (bits_consumed+7) / 8;
@@ -2667,9 +2793,9 @@
             return AVERROR_PATCHWELCOME;
         }
 
-        // for each program (which there is only on in DVB)
+        // for each program (which there is only one in DVB)
 
-        // for each layer (which there is only on in DVB)
+        // for each layer (which there is only one in DVB)
         if (get_bits(gb, 3)) {                   // numLayer
             av_log_missing_feature(latmctx->aac_ctx.avctx,
                                    "multiple layers", 1);
@@ -2790,7 +2916,7 @@
         return AVERROR_INVALIDDATA;
 
     muxlength = get_bits(&gb, 13) + 3;
-    // not enough data, the parser should have sorted this
+    // not enough data, the parser should have sorted this out
     if (muxlength > avpkt->size)
         return AVERROR_INVALIDDATA;
 
@@ -2820,7 +2946,7 @@
         return AVERROR_INVALIDDATA;
     }
 
-    if ((err = aac_decode_frame_int(avctx, out, got_frame_ptr, &gb)) < 0)
+    if ((err = aac_decode_frame_int(avctx, out, got_frame_ptr, &gb, avpkt)) < 0)
         return err;
 
     return muxlength;
@@ -2852,6 +2978,7 @@
     },
     .capabilities    = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1,
     .channel_layouts = aac_channel_layout,
+    .flush = flush,
 };
 
 /*
@@ -2873,4 +3000,5 @@
     },
     .capabilities    = CODEC_CAP_CHANNEL_CONF | CODEC_CAP_DR1,
     .channel_layouts = aac_channel_layout,
+    .flush = flush,
 };
diff --git a/libavcodec/aacdectab.h b/libavcodec/aacdectab.h
index 844579f..0083260 100644
--- a/libavcodec/aacdectab.h
+++ b/libavcodec/aacdectab.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
  * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index f5ab40f..9178bab 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -2,20 +2,20 @@
  * AAC encoder
  * Copyright (C) 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -146,7 +146,7 @@
 };
 
 /**
- * Table to remap channels from Libav's default order to AAC order.
+ * Table to remap channels from libavcodec's default order to AAC order.
  */
 static const uint8_t aac_chan_maps[AAC_MAX_CHANNELS][AAC_MAX_CHANNELS] = {
     { 0 },
@@ -480,7 +480,7 @@
 
 /*
  * Copy input samples.
- * Channels are reordered from Libav's default order to AAC order.
+ * Channels are reordered from libavcodec's default order to AAC order.
  */
 static void copy_input_samples(AACEncContext *s, const AVFrame *frame)
 {
@@ -573,11 +573,10 @@
         }
         start_ch += chans;
     }
-    if ((ret = ff_alloc_packet(avpkt, 768 * s->channels))) {
+    if ((ret = ff_alloc_packet2(avctx, avpkt, 8192 * s->channels))) {
         av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
         return ret;
     }
-
     do {
         int frame_bits;
 
@@ -779,7 +778,7 @@
     if (ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths, s->chan_map[0], grouping))
         goto fail;
     s->psypp = ff_psy_preprocess_init(avctx);
-    s->coder = &ff_aac_coders[2];
+    s->coder = &ff_aac_coders[s->options.aac_coder];
 
     s->lambda = avctx->global_quality ? avctx->global_quality : 120;
 
@@ -803,6 +802,7 @@
         {"auto",     "Selected by the Encoder", 0, AV_OPT_TYPE_CONST, {.i64 = -1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"},
         {"ms_off",   "Disable Mid/Side coding", 0, AV_OPT_TYPE_CONST, {.i64 =  0 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"},
         {"ms_force", "Force Mid/Side for the whole frame if possible", 0, AV_OPT_TYPE_CONST, {.i64 =  1 }, INT_MIN, INT_MAX, AACENC_FLAGS, "stereo_mode"},
+    {"aac_coder", "", offsetof(AACEncContext, options.aac_coder), AV_OPT_TYPE_INT, {.i64 = 2}, 0, AAC_CODER_NB-1, AACENC_FLAGS},
     {NULL}
 };
 
@@ -821,6 +821,7 @@
     .init           = aac_encode_init,
     .encode2        = aac_encode_frame,
     .close          = aac_encode_end,
+    .supported_samplerates = avpriv_mpeg4audio_sample_rates,
     .capabilities   = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY |
                       CODEC_CAP_EXPERIMENTAL,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
diff --git a/libavcodec/aacenc.h b/libavcodec/aacenc.h
index 81ffb97..fbc3da8 100644
--- a/libavcodec/aacenc.h
+++ b/libavcodec/aacenc.h
@@ -2,20 +2,20 @@
  * AAC encoder
  * Copyright (C) 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -31,8 +31,11 @@
 #include "audio_frame_queue.h"
 #include "psymodel.h"
 
+#define AAC_CODER_NB 4
+
 typedef struct AACEncOptions {
     int stereo_mode;
+    int aac_coder;
 } AACEncOptions;
 
 struct AACEncContext;
diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c
index fa7e9ac..569b44e 100644
--- a/libavcodec/aacps.c
+++ b/libavcodec/aacps.c
@@ -2,20 +2,20 @@
  * MPEG-4 Parametric Stereo decoding functions
  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aacps.h b/libavcodec/aacps.h
index e8a195a..29323ff 100644
--- a/libavcodec/aacps.h
+++ b/libavcodec/aacps.h
@@ -2,20 +2,20 @@
  * MPEG-4 Parametric Stereo definitions and declarations
  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aacps_tablegen.c b/libavcodec/aacps_tablegen.c
index 635737d..f56930b 100644
--- a/libavcodec/aacps_tablegen.c
+++ b/libavcodec/aacps_tablegen.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aacps_tablegen.h b/libavcodec/aacps_tablegen.h
index bd4e695..a8c4021 100644
--- a/libavcodec/aacps_tablegen.h
+++ b/libavcodec/aacps_tablegen.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aacpsdata.c b/libavcodec/aacpsdata.c
index 675bd8e..7431cae 100644
--- a/libavcodec/aacpsdata.c
+++ b/libavcodec/aacpsdata.c
@@ -2,20 +2,20 @@
  * MPEG-4 Parametric Stereo data tables
  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c
index 42db471..fa562b3 100644
--- a/libavcodec/aacpsy.c
+++ b/libavcodec/aacpsy.c
@@ -2,20 +2,20 @@
  * AAC encoder psychoacoustic model
  * Copyright (C) 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,6 +24,8 @@
  * AAC encoder psychoacoustic model
  */
 
+#include "libavutil/libm.h"
+
 #include "avcodec.h"
 #include "aactab.h"
 #include "psymodel.h"
@@ -292,7 +294,7 @@
     int i, j, g, start;
     float prev, minscale, minath, minsnr, pe_min;
     const int chan_bitrate = ctx->avctx->bit_rate / ctx->avctx->channels;
-    const int bandwidth    = ctx->avctx->cutoff ? ctx->avctx->cutoff : ctx->avctx->sample_rate / 2;
+    const int bandwidth    = ctx->avctx->cutoff ? ctx->avctx->cutoff : AAC_CUTOFF(ctx->avctx);
     const float num_bark   = calc_bark((float)bandwidth);
 
     ctx->model_priv_data = av_mallocz(sizeof(AacPsyContext));
@@ -333,7 +335,7 @@
             coeff->spread_low[1] = pow(10.0, -bark_width * en_spread_low);
             coeff->spread_hi [1] = pow(10.0, -bark_width * en_spread_hi);
             pe_min = bark_pe * bark_width;
-            minsnr = pow(2.0f, pe_min / band_sizes[g]) - 1.5f;
+            minsnr = exp2(pe_min / band_sizes[g]) - 1.5f;
             coeff->min_snr = av_clipf(1.0f / minsnr, PSY_SNR_25DB, PSY_SNR_1DB);
         }
         start = 0;
@@ -524,8 +526,11 @@
 {
     float thr_avg, reduction;
 
-    thr_avg   = powf(2.0f, (a - pe) / (4.0f * active_lines));
-    reduction = powf(2.0f, (a - desired_pe) / (4.0f * active_lines)) - thr_avg;
+    if(active_lines == 0.0)
+        return 0;
+
+    thr_avg   = exp2f((a - pe) / (4.0f * active_lines));
+    reduction = exp2f((a - desired_pe) / (4.0f * active_lines)) - thr_avg;
 
     return FFMAX(reduction, 0.0f);
 }
@@ -563,7 +568,7 @@
     AacPsyChannel *pch  = &pctx->ch[channel];
     int start = 0;
     int i, w, g;
-    float desired_bits, desired_pe, delta_pe, reduction, spread_en[128] = {0};
+    float desired_bits, desired_pe, delta_pe, reduction= NAN, spread_en[128] = {0};
     float a = 0.0f, active_lines = 0.0f, norm_fac = 0.0f;
     float pe = pctx->chan_bitrate > 32000 ? 0.0f : FFMAX(50.0f, 100.0f - pctx->chan_bitrate * 100.0f / 32000.0f);
     const int      num_bands   = ctx->num_bands[wi->num_windows == 8];
@@ -583,7 +588,7 @@
                 form_factor  += sqrtf(fabs(coefs[start+i]));
             }
             band->thr      = band->energy * 0.001258925f;
-            band->nz_lines = form_factor / powf(band->energy / band_sizes[g], 0.25f);
+            band->nz_lines = band->energy>0 ? form_factor / powf(band->energy / band_sizes[g], 0.25f) : 0;
 
             start += band_sizes[g];
         }
@@ -703,7 +708,7 @@
                         float delta_sfb_pe = band->norm_fac * norm_fac * delta_pe;
                         float thr = band->thr;
 
-                        thr *= powf(2.0f, delta_sfb_pe / band->active_lines);
+                        thr *= exp2f(delta_sfb_pe / band->active_lines);
                         if (thr > coeffs[g].min_snr * band->energy && band->avoid_holes == PSY_3GPP_AH_INACTIVE)
                             thr = FFMAX(band->thr, coeffs[g].min_snr * band->energy);
                         band->thr = thr;
diff --git a/libavcodec/aacpsy.h b/libavcodec/aacpsy.h
index 5d1e142..05c93cd 100644
--- a/libavcodec/aacpsy.h
+++ b/libavcodec/aacpsy.h
@@ -2,20 +2,20 @@
  * AAC encoder psychoacoustic model
  * Copyright (C) 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c
index 5eca115..db0954b 100644
--- a/libavcodec/aacsbr.c
+++ b/libavcodec/aacsbr.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
  * Copyright (c) 2009-2010 Alex Converse <alex.converse@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -34,9 +34,11 @@
 #include "aacps.h"
 #include "sbrdsp.h"
 #include "libavutil/libm.h"
+#include "libavutil/avassert.h"
 
 #include <stdint.h>
 #include <float.h>
+#include <math.h>
 
 #define ENVELOPE_ADJUSTMENT_OFFSET 2
 #define NOISE_FLOOR_OFFSET 6.0f
@@ -141,6 +143,8 @@
 av_cold void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr)
 {
     float mdct_scale;
+    if(sbr->mdct.mdct_bits)
+        return;
     sbr->kx[0] = sbr->kx[1];
     sbr_turnoff(sbr);
     sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128);
@@ -551,7 +555,7 @@
             k = sbr->n_master;
     } while (sb != sbr->kx[1] + sbr->m[1]);
 
-    if (sbr->patch_num_subbands[sbr->num_patches-1] < 3 && sbr->num_patches > 1)
+    if (sbr->num_patches > 1 && sbr->patch_num_subbands[sbr->num_patches-1] < 3)
         sbr->num_patches--;
 
     return 0;
@@ -929,7 +933,9 @@
         }
         break;
     default:
-        av_log_missing_feature(ac->avctx, "Reserved SBR extensions are", 1);
+        // some files contain 0-padding
+        if (bs_extension_id || *num_bits_left > 16 || show_bits(gb, *num_bits_left))
+            av_log_missing_feature(ac->avctx, "Reserved SBR extensions are", 1);
         skip_bits_long(gb, *num_bits_left); // bs_fill_bits
         *num_bits_left = 0;
         break;
@@ -1572,10 +1578,6 @@
         0.11516383427084,
         0.03183050093751,
     };
-    static const int8_t phi[2][4] = {
-        {  1,  0, -1,  0}, // real
-        {  0,  1,  0, -1}, // imaginary
-    };
     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;
@@ -1599,7 +1601,6 @@
 
     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++) {
-            int phi_sign = (1 - 2*(kx & 1));
             LOCAL_ALIGNED_16(float, g_filt_tab, [48]);
             LOCAL_ALIGNED_16(float, q_filt_tab, [48]);
             float *g_filt, *q_filt;
@@ -1629,13 +1630,17 @@
                                                    q_filt, indexnoise,
                                                    kx, m_max);
             } else {
-                for (m = 0; m < m_max; m++) {
-                    Y1[i][m + kx][0] +=
-                        sbr->s_m[e][m] * phi[0][indexsine];
-                    Y1[i][m + kx][1] +=
-                        sbr->s_m[e][m] * (phi[1][indexsine] * phi_sign);
-                    phi_sign = -phi_sign;
+                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];
+                for (m = 0; m+1 < m_max; m+=2) {
+                    out[2*m  ] += in[m  ] * A;
+                    out[2*m+2] += in[m+1] * B;
                 }
+                if(m_max&1)
+                    out[2*m  ] += in[m  ] * A;
             }
             indexnoise = (indexnoise + m_max) & 0x1ff;
             indexsine = (indexsine + 1) & 3;
diff --git a/libavcodec/aacsbr.h b/libavcodec/aacsbr.h
index 153070d..d028498 100644
--- a/libavcodec/aacsbr.h
+++ b/libavcodec/aacsbr.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
  * Copyright (c) 2010      Alex Converse <alex.converse@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aacsbrdata.h b/libavcodec/aacsbrdata.h
index f309059..dd7a827 100644
--- a/libavcodec/aacsbrdata.h
+++ b/libavcodec/aacsbrdata.h
@@ -2,20 +2,20 @@
  * AAC Spectral Band Replication decoding data
  * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aactab.c b/libavcodec/aactab.c
index 9176e37..6cbb8c4 100644
--- a/libavcodec/aactab.c
+++ b/libavcodec/aactab.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
  * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aactab.h b/libavcodec/aactab.h
index 56e5796..6ed3b4a 100644
--- a/libavcodec/aactab.h
+++ b/libavcodec/aactab.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
  * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aandcttab.c b/libavcodec/aandcttab.c
index 0c5b573..87c50b3 100644
--- a/libavcodec/aandcttab.c
+++ b/libavcodec/aandcttab.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aandcttab.h b/libavcodec/aandcttab.h
index daccb7b..d774828 100644
--- a/libavcodec/aandcttab.h
+++ b/libavcodec/aandcttab.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aasc.c b/libavcodec/aasc.c
index 60bf7c6..a759e0d 100644
--- a/libavcodec/aasc.c
+++ b/libavcodec/aasc.c
@@ -2,20 +2,20 @@
  * Autodesk RLE Decoder
  * Copyright (C) 2005 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,15 +36,40 @@
     AVCodecContext *avctx;
     GetByteContext gb;
     AVFrame frame;
+
+    uint32_t palette[AVPALETTE_COUNT];
+    int palette_size;
 } AascContext;
 
 static av_cold int aasc_decode_init(AVCodecContext *avctx)
 {
     AascContext *s = avctx->priv_data;
+    uint8_t *ptr;
+    int i;
 
     s->avctx = avctx;
+    switch (avctx->bits_per_coded_sample) {
+    case 8:
+        avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
-    avctx->pix_fmt = AV_PIX_FMT_BGR24;
+        ptr = avctx->extradata;
+        s->palette_size = FFMIN(avctx->extradata_size, AVPALETTE_SIZE);
+        for (i = 0; i < s->palette_size / 4; i++) {
+            s->palette[i] = 0xFFU << 24 | AV_RL32(ptr);
+            ptr += 4;
+        }
+        break;
+    case 16:
+        avctx->pix_fmt = AV_PIX_FMT_RGB555;
+        break;
+    case 24:
+        avctx->pix_fmt = AV_PIX_FMT_BGR24;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n", avctx->bits_per_coded_sample);
+        return -1;
+    }
+    avcodec_get_frame_defaults(&s->frame);
 
     return 0;
 }
@@ -56,9 +81,9 @@
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     AascContext *s = avctx->priv_data;
-    int compr, i, stride;
+    int compr, i, stride, psize;
 
-    s->frame.reference = 1;
+    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)) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
@@ -68,22 +93,42 @@
     compr = AV_RL32(buf);
     buf += 4;
     buf_size -= 4;
+    psize = avctx->bits_per_coded_sample / 8;
+    switch (avctx->codec_tag) {
+    case MKTAG('A', 'A', 'S', '4'):
+        bytestream2_init(&s->gb, buf - 4, buf_size + 4);
+        ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, &s->gb);
+        break;
+    case MKTAG('A', 'A', 'S', 'C'):
     switch(compr){
     case 0:
-        stride = (avctx->width * 3 + 3) & ~3;
+        stride = (avctx->width * psize + psize) & ~psize;
         for(i = avctx->height - 1; i >= 0; i--){
-            memcpy(s->frame.data[0] + i*s->frame.linesize[0], buf, avctx->width*3);
+            if(avctx->width * psize > buf_size){
+                av_log(avctx, AV_LOG_ERROR, "Next line is beyond buffer bounds\n");
+                break;
+            }
+            memcpy(s->frame.data[0] + i*s->frame.linesize[0], buf, avctx->width * psize);
             buf += stride;
+            buf_size -= stride;
         }
         break;
     case 1:
-        bytestream2_init(&s->gb, buf - 4, buf_size + 4);
+        bytestream2_init(&s->gb, buf, buf_size);
         ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, &s->gb);
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr);
         return -1;
     }
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "Unknown FourCC: %X\n", avctx->codec_tag);
+        return -1;
+    }
+
+    if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
+        memcpy(s->frame.data[1], s->palette, s->palette_size);
 
     *data_size = sizeof(AVFrame);
     *(AVFrame*)data = s->frame;
diff --git a/libavcodec/ac3.c b/libavcodec/ac3.c
index 99e5b50..29e132f 100644
--- a/libavcodec/ac3.c
+++ b/libavcodec/ac3.c
@@ -2,20 +2,20 @@
  * Common code between the AC-3 encoder and decoder
  * Copyright (c) 2000 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ac3.h b/libavcodec/ac3.h
index 647432f..e609bb5 100644
--- a/libavcodec/ac3.h
+++ b/libavcodec/ac3.h
@@ -2,20 +2,20 @@
  * Common code between the AC-3 encoder and decoder
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -39,6 +39,8 @@
 #define AC3_CRITICAL_BANDS 50
 #define AC3_MAX_CPL_BANDS  18
 
+#include "libavutil/opt.h"
+#include "avcodec.h"
 #include "ac3tab.h"
 
 /* exponent encoding strategy */
diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c
index 9786da3..8250a67 100644
--- a/libavcodec/ac3_parser.c
+++ b/libavcodec/ac3_parser.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ac3_parser.h b/libavcodec/ac3_parser.h
index 9322550..b5022de 100644
--- a/libavcodec/ac3_parser.h
+++ b/libavcodec/ac3_parser.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index 12770db..674de7a 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -7,20 +7,20 @@
  * Copyright (c) 2007-2008 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com>
  * Copyright (c) 2007 Justin Ruggles <justin.ruggles@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -1324,7 +1324,7 @@
         if (s->frame_size > buf_size) {
             av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");
             err = AAC_AC3_PARSE_ERROR_FRAME_SIZE;
-        } else if (avctx->err_recognition & AV_EF_CRCCHECK) {
+        } else if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL)) {
             /* check for crc mismatch */
             if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2],
                        s->frame_size - 2)) {
@@ -1353,6 +1353,10 @@
         avctx->channels       = s->out_channels;
         avctx->channel_layout = s->channel_layout;
 
+        s->loro_center_mix_level   = gain_levels[s->  center_mix_level];
+        s->loro_surround_mix_level = gain_levels[s->surround_mix_level];
+        s->ltrt_center_mix_level   = LEVEL_MINUS_3DB;
+        s->ltrt_surround_mix_level = LEVEL_MINUS_3DB;
         /* set downmixing coefficients if needed */
         if (s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) &&
                 s->fbw_channels == s->out_channels)) {
@@ -1363,6 +1367,10 @@
         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");
+        return AVERROR_INVALIDDATA;
+    }
     /* 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)
@@ -1398,6 +1406,8 @@
         }
     }
 
+    s->frame.decode_error_flags = err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0;
+
     *got_frame_ptr   = 1;
     *(AVFrame *)data = s->frame;
 
@@ -1420,6 +1430,13 @@
 #define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM)
 static const AVOption options[] = {
     { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 1.0, PAR },
+
+{"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 2, 0, "dmix_mode"},
+{"ltrt_cmixlev",   "Lt/Rt Center Mix Level",   OFFSET(ltrt_center_mix_level),    AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0},
+{"ltrt_surmixlev", "Lt/Rt Surround Mix Level", OFFSET(ltrt_surround_mix_level),  AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0},
+{"loro_cmixlev",   "Lo/Ro Center Mix Level",   OFFSET(loro_center_mix_level),    AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0},
+{"loro_surmixlev", "Lo/Ro Surround Mix Level", OFFSET(loro_surround_mix_level),  AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0},
+
     { NULL},
 };
 
diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h
index eabfd29..c3a43bf 100644
--- a/libavcodec/ac3dec.h
+++ b/libavcodec/ac3dec.h
@@ -2,20 +2,20 @@
  * Common code between the AC-3 and E-AC-3 decoders
  * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -89,6 +89,12 @@
     int eac3;                               ///< indicates if current frame is E-AC-3
 ///@}
 
+    int preferred_stereo_downmix;
+    float ltrt_center_mix_level;
+    float ltrt_surround_mix_level;
+    float loro_center_mix_level;
+    float loro_surround_mix_level;
+
 ///@name Frame syntax parameters
     int snr_offset_strategy;                ///< SNR offset strategy                    (snroffststr)
     int block_switch_syntax;                ///< block switch syntax enabled            (blkswe)
diff --git a/libavcodec/ac3dec_data.c b/libavcodec/ac3dec_data.c
index 272a963..d0a9b1e 100644
--- a/libavcodec/ac3dec_data.c
+++ b/libavcodec/ac3dec_data.c
@@ -2,20 +2,20 @@
  * AC-3 and E-AC-3 decoder tables
  * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ac3dec_data.h b/libavcodec/ac3dec_data.h
index c0a584e..975b52e 100644
--- a/libavcodec/ac3dec_data.h
+++ b/libavcodec/ac3dec_data.h
@@ -2,20 +2,20 @@
  * AC-3 and E-AC-3 decoder tables
  * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c
index 7e7a808..49866eb 100644
--- a/libavcodec/ac3dsp.c
+++ b/libavcodec/ac3dsp.c
@@ -2,20 +2,20 @@
  * AC-3 DSP utils
  * Copyright (c) 2011 Justin Ruggles
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -23,6 +23,7 @@
 #include "avcodec.h"
 #include "ac3.h"
 #include "ac3dsp.h"
+#include "mathops.h"
 
 static void ac3_exponent_min_c(uint8_t *exp, int num_reuse_blocks, int nb_coefs)
 {
@@ -171,6 +172,48 @@
     }
 }
 
+static void ac3_sum_square_butterfly_int32_c(int64_t sum[4],
+                                             const int32_t *coef0,
+                                             const int32_t *coef1,
+                                             int len)
+{
+    int i;
+
+    sum[0] = sum[1] = sum[2] = sum[3] = 0;
+
+    for (i = 0; i < len; i++) {
+        int lt = coef0[i];
+        int rt = coef1[i];
+        int md = lt + rt;
+        int sd = lt - rt;
+        MAC64(sum[0], lt, lt);
+        MAC64(sum[1], rt, rt);
+        MAC64(sum[2], md, md);
+        MAC64(sum[3], sd, sd);
+    }
+}
+
+static void ac3_sum_square_butterfly_float_c(float sum[4],
+                                             const float *coef0,
+                                             const float *coef1,
+                                             int len)
+{
+    int i;
+
+    sum[0] = sum[1] = sum[2] = sum[3] = 0;
+
+    for (i = 0; i < len; i++) {
+        float lt = coef0[i];
+        float rt = coef1[i];
+        float md = lt + rt;
+        float sd = lt - rt;
+        sum[0] += lt * lt;
+        sum[1] += rt * rt;
+        sum[2] += md * md;
+        sum[3] += sd * sd;
+    }
+}
+
 static void ac3_downmix_c(float (*samples)[256], float (*matrix)[2],
                           int out_ch, int in_ch, int len)
 {
@@ -207,6 +250,8 @@
     c->update_bap_counts = ac3_update_bap_counts_c;
     c->compute_mantissa_size = ac3_compute_mantissa_size_c;
     c->extract_exponents = ac3_extract_exponents_c;
+    c->sum_square_butterfly_int32 = ac3_sum_square_butterfly_int32_c;
+    c->sum_square_butterfly_float = ac3_sum_square_butterfly_float_c;
     c->downmix = ac3_downmix_c;
 
     if (ARCH_ARM)
diff --git a/libavcodec/ac3dsp.h b/libavcodec/ac3dsp.h
index 723d109..fbc63f6 100644
--- a/libavcodec/ac3dsp.h
+++ b/libavcodec/ac3dsp.h
@@ -2,20 +2,20 @@
  * AC-3 DSP utils
  * Copyright (c) 2011 Justin Ruggles
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -126,6 +126,12 @@
 
     void (*extract_exponents)(uint8_t *exp, int32_t *coef, int nb_coefs);
 
+    void (*sum_square_butterfly_int32)(int64_t sum[4], const int32_t *coef0,
+                                       const int32_t *coef1, int len);
+
+    void (*sum_square_butterfly_float)(float sum[4], const float *coef0,
+                                       const float *coef1, int len);
+
     void (*downmix)(float (*samples)[256], float (*matrix)[2], int out_ch,
                     int in_ch, int len);
 } AC3DSPContext;
diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c
index 5102e30..e5dea46 100644
--- a/libavcodec/ac3enc.c
+++ b/libavcodec/ac3enc.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2006-2010 Justin Ruggles <justin.ruggles@gmail.com>
  * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -1210,14 +1210,11 @@
     int i;
 
     for (i = start_freq; i < end_freq; i++) {
-        int v;
         int c = fixed_coef[i];
         int e = exp[i];
-        int b = bap[i];
-        switch (b) {
-        case 0:
-            v = 0;
-            break;
+        int v = bap[i];
+        if (v)
+        switch (v) {
         case 1:
             v = sym_quant(c, e, 3);
             switch (s->mant1_cnt) {
@@ -1286,7 +1283,7 @@
             v = asym_quant(c, e, 16);
             break;
         default:
-            v = asym_quant(c, e, b - 1);
+            v = asym_quant(c, e, v - 1);
             break;
         }
         qmant[i] = v;
diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c
index e471edf..5d8dd5c 100644
--- a/libavcodec/ac3enc_fixed.c
+++ b/libavcodec/ac3enc_fixed.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2006-2010 Justin Ruggles <justin.ruggles@gmail.com>
  * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -34,8 +34,13 @@
 
 #define AC3ENC_TYPE AC3ENC_TYPE_AC3_FIXED
 #include "ac3enc_opts_template.c"
-static const AVClass ac3enc_class = { "Fixed-Point AC-3 Encoder", av_default_item_name,
-                                      ac3_options, LIBAVUTIL_VERSION_INT };
+
+static const AVClass ac3enc_class = {
+    .class_name = "Fixed-Point AC-3 Encoder",
+    .item_name  = av_default_item_name,
+    .option     = ac3_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
 
 #include "ac3enc_template.c"
 
@@ -107,6 +112,12 @@
     }
 }
 
+static void sum_square_butterfly(AC3EncodeContext *s, int64_t sum[4],
+                                 const int32_t *coef0, const int32_t *coef1,
+                                 int len)
+{
+    s->ac3dsp.sum_square_butterfly_int32(sum, coef0, coef1, len);
+}
 
 /*
  * Clip MDCT coefficients to allowable range.
diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c
index a225d9b..7864f41 100644
--- a/libavcodec/ac3enc_float.c
+++ b/libavcodec/ac3enc_float.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2006-2010 Justin Ruggles <justin.ruggles@gmail.com>
  * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,8 +36,12 @@
 #if CONFIG_AC3_ENCODER
 #define AC3ENC_TYPE AC3ENC_TYPE_AC3
 #include "ac3enc_opts_template.c"
-static const AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name,
-                                      ac3_options, LIBAVUTIL_VERSION_INT };
+static const AVClass ac3enc_class = {
+    .class_name = "AC-3 Encoder",
+    .item_name  = av_default_item_name,
+    .option     = ac3_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
 #endif
 
 #include "ac3enc_template.c"
@@ -117,6 +121,12 @@
                                chan_size * (s->channels + cpl));
 }
 
+static void sum_square_butterfly(AC3EncodeContext *s, float sum[4],
+                                 const float *coef0, const float *coef1,
+                                 int len)
+{
+    s->ac3dsp.sum_square_butterfly_float(sum, coef0, coef1, len);
+}
 
 /*
  * Clip MDCT coefficients to allowable range.
diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c
index 388d753..904e0bb 100644
--- a/libavcodec/ac3enc_template.c
+++ b/libavcodec/ac3enc_template.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2006-2011 Justin Ruggles <justin.ruggles@gmail.com>
  * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -43,6 +43,9 @@
 
 static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl);
 
+static void sum_square_butterfly(AC3EncodeContext *s, CoefSumType sum[4],
+                                 const CoefType *coef0, const CoefType *coef1,
+                                 int len);
 
 int AC3_NAME(allocate_sample_buffers)(AC3EncodeContext *s)
 {
@@ -66,7 +69,7 @@
 
 /*
  * Copy input samples.
- * Channels are reordered from Libav's default order to AC-3 order.
+ * Channels are reordered from FFmpeg's default order to AC-3 order.
  */
 static void copy_input_samples(AC3EncodeContext *s, SampleType **samples)
 {
@@ -332,7 +335,7 @@
 static void compute_rematrixing_strategy(AC3EncodeContext *s)
 {
     int nb_coefs;
-    int blk, bnd, i;
+    int blk, bnd;
     AC3Block *block, *block0;
 
     if (s->channel_mode != AC3_CHMODE_STEREO)
@@ -360,17 +363,9 @@
             /* calculate calculate sum of squared coeffs for one band in one block */
             int start = ff_ac3_rematrix_band_tab[bnd];
             int end   = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]);
-            CoefSumType sum[4] = {0,};
-            for (i = start; i < end; i++) {
-                CoefType lt = block->mdct_coef[1][i];
-                CoefType rt = block->mdct_coef[2][i];
-                CoefType md = lt + rt;
-                CoefType sd = lt - rt;
-                MAC_COEF(sum[0], lt, lt);
-                MAC_COEF(sum[1], rt, rt);
-                MAC_COEF(sum[2], md, md);
-                MAC_COEF(sum[3], sd, sd);
-            }
+            CoefSumType sum[4];
+            sum_square_butterfly(s, sum, block->mdct_coef[1] + start,
+                                 block->mdct_coef[2] + start, end - start);
 
             /* compare sums to determine if rematrixing will be used for this band */
             if (FFMIN(sum[2], sum[3]) < FFMIN(sum[0], sum[1]))
@@ -439,10 +434,8 @@
 
     ff_ac3_quantize_mantissas(s);
 
-    if ((ret = ff_alloc_packet(avpkt, s->frame_size))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, s->frame_size)))
         return ret;
-    }
     ff_ac3_output_frame(s, avpkt->data);
 
     if (frame->pts != AV_NOPTS_VALUE)
diff --git a/libavcodec/ac3tab.c b/libavcodec/ac3tab.c
index 951a101..ccf04ec 100644
--- a/libavcodec/ac3tab.c
+++ b/libavcodec/ac3tab.c
@@ -2,20 +2,20 @@
  * AC-3 tables
  * copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ac3tab.h b/libavcodec/ac3tab.h
index 8ed5052..d6e0eed 100644
--- a/libavcodec/ac3tab.h
+++ b/libavcodec/ac3tab.h
@@ -2,20 +2,20 @@
  * AC-3 tables
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/acelp_filters.c b/libavcodec/acelp_filters.c
index 93bec65..9ab758b 100644
--- a/libavcodec/acelp_filters.c
+++ b/libavcodec/acelp_filters.c
@@ -3,25 +3,26 @@
  *
  * Copyright (c) 2008 Vladimir Voroshilov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <inttypes.h>
 
+#include "libavutil/avassert.h"
 #include "libavutil/common.h"
 #include "avcodec.h"
 #include "acelp_filters.h"
@@ -46,7 +47,7 @@
 {
     int n, i;
 
-    assert(frac_pos >= 0 && frac_pos < precision);
+    av_assert1(frac_pos >= 0 && frac_pos < precision);
 
     for (n = 0; n < length; n++) {
         int idx = 0;
@@ -143,3 +144,12 @@
     samples[0] -= tilt * *mem;
     *mem = new_tilt_mem;
 }
+
+void ff_acelp_filter_init(ACELPFContext *c)
+{
+    c->acelp_interpolatef                      = ff_acelp_interpolatef;
+    c->acelp_apply_order_2_transfer_function   = ff_acelp_apply_order_2_transfer_function;
+
+    if(HAVE_MIPSFPU)
+        ff_acelp_filter_init_mips(c);
+}
diff --git a/libavcodec/acelp_filters.h b/libavcodec/acelp_filters.h
index b8715d2..56197bc 100644
--- a/libavcodec/acelp_filters.h
+++ b/libavcodec/acelp_filters.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2008 Vladimir Voroshilov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,39 @@
 
 #include <stdint.h>
 
+typedef struct ACELPFContext {
+    /**
+    * Floating point version of ff_acelp_interpolate()
+    */
+    void (*acelp_interpolatef)(float *out, const float *in,
+                            const float *filter_coeffs, int precision,
+                            int frac_pos, int filter_length, int length);
+
+    /**
+     * Apply an order 2 rational transfer function in-place.
+     *
+     * @param out output buffer for filtered speech samples
+     * @param in input buffer containing speech data (may be the same as out)
+     * @param zero_coeffs z^-1 and z^-2 coefficients of the numerator
+     * @param pole_coeffs z^-1 and z^-2 coefficients of the denominator
+     * @param gain scale factor for final output
+     * @param mem intermediate values used by filter (should be 0 initially)
+     * @param n number of samples (should be a multiple of eight)
+     */
+    void (*acelp_apply_order_2_transfer_function)(float *out, const float *in,
+                                                  const float zero_coeffs[2],
+                                                  const float pole_coeffs[2],
+                                                  float gain,
+                                                  float mem[2], int n);
+
+}ACELPFContext;
+
+/**
+ * Initialize ACELPFContext.
+ */
+void ff_acelp_filter_init(ACELPFContext *c);
+void ff_acelp_filter_init_mips(ACELPFContext *c);
+
 /**
  * low-pass Finite Impulse Response filter coefficients.
  *
@@ -76,7 +109,7 @@
  *
  * The filter has a cut-off frequency of 1/80 of the sampling freq
  *
- * @note Two items before the top of the out buffer must contain two items from the
+ * @note Two items before the top of the in buffer must contain two items from the
  *       tail of the previous subframe.
  *
  * @remark It is safe to pass the same array in in and out parameters.
diff --git a/libavcodec/acelp_pitch_delay.c b/libavcodec/acelp_pitch_delay.c
index c091301..e488cc8 100644
--- a/libavcodec/acelp_pitch_delay.c
+++ b/libavcodec/acelp_pitch_delay.c
@@ -3,24 +3,25 @@
  *
  * Copyright (c) 2008 Vladimir Voroshilov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/common.h"
+#include "libavutil/libm.h"
 #include "libavutil/mathematics.h"
 #include "avcodec.h"
 #include "dsputil.h"
@@ -106,9 +107,20 @@
     for(i=0; i<ma_pred_order; i++)
         mr_energy += quant_energy[i] * ma_prediction_coeff[i];
 
+#ifdef G729_BITEXACT
+    mr_energy += (((-6165LL * ff_log2(dsp->scalarproduct_int16(fc_v, fc_v, subframe_size, 0))) >> 3) & ~0x3ff);
+
+    mr_energy = (5439 * (mr_energy >> 15)) >> 8;           // (0.15) = (0.15) * (7.23)
+
+    return bidir_sal(
+               ((ff_exp2(mr_energy & 0x7fff) + 16) >> 5) * (gain_corr_factor >> 1),
+               (mr_energy >> 15) - 25
+           );
+#else
     mr_energy = gain_corr_factor * exp(M_LN10 / (20 << 23) * mr_energy) /
                 sqrt(dsp->scalarproduct_int16(fc_v, fc_v, subframe_size));
     return mr_energy >> 12;
+#endif
 }
 
 float ff_amr_set_fixed_gain(float fixed_gain_factor, float fixed_mean_energy,
diff --git a/libavcodec/acelp_pitch_delay.h b/libavcodec/acelp_pitch_delay.h
index e5410bb..72977f1 100644
--- a/libavcodec/acelp_pitch_delay.h
+++ b/libavcodec/acelp_pitch_delay.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2008 Vladimir Voroshilov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/acelp_vectors.c b/libavcodec/acelp_vectors.c
index b50c5f3..aadacb4 100644
--- a/libavcodec/acelp_vectors.c
+++ b/libavcodec/acelp_vectors.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2008 Vladimir Voroshilov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -50,6 +50,26 @@
   28, 26,
 };
 
+const uint8_t ff_fc_2pulses_9bits_track2_gray[32] =
+{
+  0,  2,
+  5,  4,
+  12, 10,
+  7,  9,
+  25, 24,
+  20, 22,
+  14, 15,
+  19, 17,
+  36, 31,
+  21, 26,
+  1,  6,
+  16, 11,
+  27, 29,
+  32, 30,
+  39, 37,
+  34, 35,
+};
+
 const uint8_t ff_fc_4pulses_8bits_tracks_13[16] =
 {
   0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75,
@@ -219,11 +239,12 @@
         int x   = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
         float y = in->y[i] * scale;
 
-        do {
-            out[x] += y;
-            y *= in->pitch_fac;
-            x += in->pitch_lag;
-        } while (x < size && repeats);
+        if (in->pitch_lag > 0)
+            do {
+                out[x] += y;
+                y *= in->pitch_fac;
+                x += in->pitch_lag;
+            } while (x < size && repeats);
     }
 }
 
@@ -234,9 +255,18 @@
     for (i=0; i < in->n; i++) {
         int x  = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1);
 
-        do {
-            out[x] = 0.0;
-            x += in->pitch_lag;
-        } while (x < size && repeats);
+        if (in->pitch_lag > 0)
+            do {
+                out[x] = 0.0;
+                x += in->pitch_lag;
+            } while (x < size && repeats);
     }
 }
+
+void ff_acelp_vectors_init(ACELPVContext *c)
+{
+    c->weighted_vector_sumf   = ff_weighted_vector_sumf;
+
+    if(HAVE_MIPSFPU)
+        ff_acelp_vectors_init_mips(c);
+}
diff --git a/libavcodec/acelp_vectors.h b/libavcodec/acelp_vectors.h
index d6226bf..fae834d 100644
--- a/libavcodec/acelp_vectors.h
+++ b/libavcodec/acelp_vectors.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2008 Vladimir Voroshilov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,30 @@
 
 #include <stdint.h>
 
+typedef struct ACELPVContext {
+    /**
+     * float implementation of weighted sum of two vectors.
+     * @param[out] out result of addition
+     * @param in_a first vector
+     * @param in_b second vector
+     * @param weight_coeff_a first vector weight coefficient
+     * @param weight_coeff_a second vector weight coefficient
+     * @param length vectors length (should be a multiple of two)
+     *
+     * @note It is safe to pass the same buffer for out and in_a or in_b.
+     */
+    void (*weighted_vector_sumf)(float *out, const float *in_a, const float *in_b,
+                                 float weight_coeff_a, float weight_coeff_b,
+                                 int length);
+
+}ACELPVContext;
+
+/**
+ * Initialize ACELPVContext.
+ */
+void ff_acelp_vectors_init(ACELPVContext *c);
+void ff_acelp_vectors_init_mips(ACELPVContext *c);
+
 /** Sparse representation for the algebraic codebook (fixed) vector */
 typedef struct AMRFixed {
     int      n;
@@ -82,6 +106,37 @@
 extern const uint8_t ff_fc_2pulses_9bits_track1_gray[16];
 
 /**
+ * Track|Pulse|        Positions
+ * -----------------------------------------
+ *  2   | 1   | 0, 7, 14, 20, 27, 34,  1, 21
+ *      |     | 2, 9, 15, 22, 29, 35,  6, 26
+ *      |     | 4,10, 17, 24, 30, 37, 11, 31
+ *      |     | 5,12, 19, 25, 32, 39, 16, 36
+ * -----------------------------------------
+ *
+ * @remark Track in the table should be read top-to-bottom, left-to-right.
+ *
+ * @note (EE.1) This table (from the reference code) does not comply with
+ *              the specification.
+ *              The specification contains the following table:
+ *
+ * Track|Pulse|        Positions
+ * -----------------------------------------
+ *  2   | 1   | 0, 5, 10, 15, 20, 25, 30, 35
+ *      |     | 1, 6, 11, 16, 21, 26, 31, 36
+ *      |     | 2, 7, 12, 17, 22, 27, 32, 37
+ *      |     | 4, 9, 14, 19, 24, 29, 34, 39
+ *
+ * -----------------------------------------
+ *
+ * @note (EE.2) Reference G.729D code also uses gray decoding for each
+ *              pulse index before looking up the value in the table.
+ *
+ * Used in G.729 @@6.4k (with gray coding)
+ */
+extern const uint8_t ff_fc_2pulses_9bits_track2_gray[32];
+
+/**
  * b60 hamming windowed sinc function coefficients
  */
 extern const float ff_b60_sinc[61];
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index b6a20e2..2dc3e6b 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2001-2003 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avcodec.h"
@@ -301,11 +301,9 @@
     for(i=0;i<4;i++) {
         shift  = 12 - (in[4+i*2] & 15);
         filter = in[4+i*2] >> 4;
-        if (filter > 4) {
-            av_log(avctx, AV_LOG_ERROR,
-                   "Invalid XA-ADPCM filter %d (max. allowed is 4)\n",
-                   filter);
-            return AVERROR_INVALIDDATA;
+        if (filter >= FF_ARRAY_ELEMS(xa_adpcm_table)) {
+            av_log_ask_for_sample(avctx, "unknown XA-ADPCM filter %d\n", filter);
+            filter=0;
         }
         f0 = xa_adpcm_table[filter][0];
         f1 = xa_adpcm_table[filter][1];
@@ -332,12 +330,11 @@
 
         shift  = 12 - (in[5+i*2] & 15);
         filter = in[5+i*2] >> 4;
-        if (filter > 4) {
-            av_log(avctx, AV_LOG_ERROR,
-                   "Invalid XA-ADPCM filter %d (max. allowed is 4)\n",
-                   filter);
-            return AVERROR_INVALIDDATA;
+        if (filter >= FF_ARRAY_ELEMS(xa_adpcm_table)) {
+            av_log_ask_for_sample(avctx, "unknown XA-ADPCM filter %d\n", filter);
+            filter=0;
         }
+
         f0 = xa_adpcm_table[filter][0];
         f1 = xa_adpcm_table[filter][1];
 
@@ -443,6 +440,9 @@
 
     *coded_samples = 0;
 
+    if(ch <= 0)
+        return 0;
+
     switch (avctx->codec->id) {
     /* constant, only check buf_size */
     case AV_CODEC_ID_ADPCM_EA_XAS:
@@ -948,6 +948,9 @@
         /* Each EA ADPCM frame has a 12-byte header followed by 30-byte pieces,
            each coding 28 stereo samples. */
 
+        if(avctx->channels != 2)
+            return AVERROR_INVALIDDATA;
+
         current_left_sample   = sign_extend(bytestream2_get_le16u(&gb), 16);
         previous_left_sample  = sign_extend(bytestream2_get_le16u(&gb), 16);
         current_right_sample  = sign_extend(bytestream2_get_le16u(&gb), 16);
diff --git a/libavcodec/adpcm.h b/libavcodec/adpcm.h
index 16facb6..08fd23f 100644
--- a/libavcodec/adpcm.h
+++ b/libavcodec/adpcm.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2001-2003 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/adpcm_data.c b/libavcodec/adpcm_data.c
index 3bc5de2..f19d622 100644
--- a/libavcodec/adpcm_data.c
+++ b/libavcodec/adpcm_data.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2001-2003 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/adpcm_data.h b/libavcodec/adpcm_data.h
index a46cb5b..97ab66c 100644
--- a/libavcodec/adpcm_data.h
+++ b/libavcodec/adpcm_data.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2001-2003 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c
index f81d7fd..217d165 100644
--- a/libavcodec/adpcmenc.c
+++ b/libavcodec/adpcmenc.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2001-2003 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -59,6 +59,8 @@
 
 #define FREEZE_INTERVAL 128
 
+static av_cold int adpcm_encode_close(AVCodecContext *avctx);
+
 static av_cold int adpcm_encode_init(AVCodecContext *avctx)
 {
     ADPCMEncodeContext *s = avctx->priv_data;
@@ -100,6 +102,7 @@
         /* seems frame_size isn't taken into account...
            have to buffer the samples :-( */
         avctx->block_align = BLKSIZE;
+        avctx->bits_per_coded_sample = 4;
         break;
     case AV_CODEC_ID_ADPCM_IMA_QT:
         avctx->frame_size  = 64;
@@ -108,8 +111,8 @@
     case AV_CODEC_ID_ADPCM_MS:
         /* each 16 bits sample gives one nibble
            and we have 7 bytes per channel overhead */
-        avctx->frame_size = (BLKSIZE - 7 * avctx->channels) * 2 /
-                             avctx->channels + 2;
+        avctx->frame_size = (BLKSIZE - 7 * avctx->channels) * 2 / avctx->channels + 2;
+        avctx->bits_per_coded_sample = 4;
         avctx->block_align    = BLKSIZE;
         if (!(avctx->extradata = av_malloc(32 + FF_INPUT_BUFFER_PADDING_SIZE)))
             goto error;
@@ -149,10 +152,7 @@
 
     return 0;
 error:
-    av_freep(&s->paths);
-    av_freep(&s->node_buf);
-    av_freep(&s->nodep_buf);
-    av_freep(&s->trellis_hash);
+    adpcm_encode_close(avctx);
     return ret;
 }
 
@@ -188,24 +188,27 @@
                                                    int16_t sample)
 {
     int delta  = sample - c->prev_sample;
-    int mask, step = ff_adpcm_step_table[c->step_index];
-    int diff   = step >> 3;
-    int nibble = 0;
+    int diff, step = ff_adpcm_step_table[c->step_index];
+    int nibble = 8*(delta < 0);
 
-    if (delta < 0) {
-        nibble = 8;
-        delta  = -delta;
-    }
+    delta= abs(delta);
+    diff = delta + (step >> 3);
 
-    for (mask = 4; mask;) {
-        if (delta >= step) {
-            nibble |= mask;
-            delta  -= step;
-            diff   += step;
-        }
-        step >>= 1;
-        mask >>= 1;
+    if (delta >= step) {
+        nibble |= 4;
+        delta  -= step;
     }
+    step >>= 1;
+    if (delta >= step) {
+        nibble |= 2;
+        delta  -= step;
+    }
+    step >>= 1;
+    if (delta >= step) {
+        nibble |= 1;
+        delta  -= step;
+    }
+    diff -= delta;
 
     if (nibble & 8)
         c->prev_sample -= diff;
@@ -373,7 +376,7 @@
                     *h = generation;\
                     u  = nodes_next[pos];\
                     if (!u) {\
-                        assert(pathn < FREEZE_INTERVAL << avctx->trellis);\
+                        av_assert1(pathn < FREEZE_INTERVAL << avctx->trellis);\
                         u = t++;\
                         nodes_next[pos] = u;\
                         u->path = pathn++;\
@@ -492,10 +495,8 @@
         pkt_size = (2 + avctx->channels * (22 + 4 * (frame->nb_samples - 1)) + 7) / 8;
     else
         pkt_size = avctx->block_align;
-    if ((ret = ff_alloc_packet(avpkt, pkt_size))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, pkt_size)))
         return ret;
-    }
     dst = avpkt->data;
 
     switch(avctx->codec->id) {
diff --git a/libavcodec/adx.h b/libavcodec/adx.h
index 47d9f24..85b35d1 100644
--- a/libavcodec/adx.h
+++ b/libavcodec/adx.h
@@ -2,20 +2,20 @@
  * ADX ADPCM codecs
  * Copyright (c) 2001,2003 BERO
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c
index 4d2892b..901d717 100644
--- a/libavcodec/adxdec.c
+++ b/libavcodec/adxdec.c
@@ -2,20 +2,20 @@
  * ADX ADPCM codecs
  * Copyright (c) 2001,2003 BERO
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -102,6 +102,7 @@
     int16_t **samples;
     int samples_offset;
     const uint8_t *buf  = avpkt->data;
+    const uint8_t *buf_end = buf + avpkt->size;
     int num_blocks, ch, ret;
 
     if (c->eof) {
@@ -151,7 +152,7 @@
 
     while (num_blocks--) {
         for (ch = 0; ch < c->channels; ch++) {
-            if (adx_decode(c, samples[ch], samples_offset, buf, ch)) {
+            if (buf_end - buf < BLOCK_SIZE || adx_decode(c, samples[ch], samples_offset, buf, ch)) {
                 c->eof = 1;
                 buf = avpkt->data + avpkt->size;
                 break;
diff --git a/libavcodec/adxenc.c b/libavcodec/adxenc.c
index 8a50539..8514a0c 100644
--- a/libavcodec/adxenc.c
+++ b/libavcodec/adxenc.c
@@ -2,20 +2,20 @@
  * ADX ADPCM codecs
  * Copyright (c) 2001,2003 BERO
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -138,10 +138,8 @@
     int ch, out_size, ret;
 
     out_size = BLOCK_SIZE * avctx->channels + !c->header_parsed * HEADER_SIZE;
-    if ((ret = ff_alloc_packet(avpkt, out_size)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, out_size)) < 0)
         return ret;
-    }
     dst = avpkt->data;
 
     if (!c->header_parsed) {
diff --git a/libavcodec/alac.c b/libavcodec/alac.c
index 11f90fc..9cd1737 100644
--- a/libavcodec/alac.c
+++ b/libavcodec/alac.c
@@ -2,20 +2,20 @@
  * ALAC (Apple Lossless Audio Codec) decoder
  * Copyright (c) 2005 David Hammerton
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -73,6 +73,8 @@
 
     int extra_bits;     /**< number of extra bits beyond 16-bit */
     int nb_samples;     /**< number of samples in the current frame */
+
+    int direct_output;
 } ALACContext;
 
 enum RawDataBlockType {
@@ -131,7 +133,7 @@
     return x;
 }
 
-static void rice_decompress(ALACContext *alac, int32_t *output_buffer,
+static int rice_decompress(ALACContext *alac, int32_t *output_buffer,
                             int nb_samples, int bps, int rice_history_mult)
 {
     int i;
@@ -142,6 +144,9 @@
         int k;
         unsigned int x;
 
+        if(get_bits_left(&alac->gb) <= 0)
+            return -1;
+
         /* calculate rice param and decode next value */
         k = av_log2((history >> 9) + 3);
         k = FFMIN(k, alac->rice_limit);
@@ -182,6 +187,7 @@
             history = 0;
         }
     }
+    return 0;
 }
 
 static inline int sign_only(int v)
@@ -327,7 +333,7 @@
         return AVERROR_INVALIDDATA;
     }
     alac->nb_samples = output_samples;
-    if (alac->sample_size > 16) {
+    if (alac->direct_output) {
         for (ch = 0; ch < channels; ch++)
             alac->output_samples_buffer[ch] = (int32_t *)alac->frame.extended_data[ch_index + ch];
     }
@@ -355,14 +361,18 @@
 
         if (alac->extra_bits) {
             for (i = 0; i < alac->nb_samples; i++) {
+                if(get_bits_left(&alac->gb) <= 0)
+                    return -1;
                 for (ch = 0; ch < channels; ch++)
                     alac->extra_bits_buffer[ch][i] = get_bits(&alac->gb, alac->extra_bits);
             }
         }
         for (ch = 0; ch < channels; ch++) {
-            rice_decompress(alac, alac->predict_error_buffer[ch],
+            int ret=rice_decompress(alac, alac->predict_error_buffer[ch],
                             alac->nb_samples, bps,
                             rice_history_mult[ch] * alac->rice_history_mult / 4);
+            if(ret<0)
+                return ret;
 
             /* adaptive FIR filter */
             if (prediction_type[ch] == 15) {
@@ -387,6 +397,8 @@
     } else {
         /* not compressed, easy case */
         for (i = 0; i < alac->nb_samples; i++) {
+            if(get_bits_left(&alac->gb) <= 0)
+                return -1;
             for (ch = 0; ch < channels; ch++) {
                 alac->output_samples_buffer[ch][i] =
                          get_sbits_long(&alac->gb, alac->sample_size);
@@ -407,6 +419,7 @@
                           alac->extra_bits, channels, alac->nb_samples);
     }
 
+    if(av_sample_fmt_is_planar(avctx->sample_fmt)) {
     switch(alac->sample_size) {
     case 16: {
         for (ch = 0; ch < channels; ch++) {
@@ -422,6 +435,37 @@
         }}
         break;
     }
+    }else{
+        switch(alac->sample_size) {
+        case 16: {
+            int16_t *outbuffer = ((int16_t *)alac->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];
+                outbuffer += alac->channels - channels;
+            }
+            }
+            break;
+        case 24: {
+            int32_t *outbuffer = ((int32_t *)alac->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;
+                outbuffer += alac->channels - channels;
+            }
+            }
+            break;
+        case 32: {
+            int32_t *outbuffer = ((int32_t *)alac->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];
+                outbuffer += alac->channels - channels;
+            }
+            }
+            break;
+        }
+    }
 
     return 0;
 }
@@ -446,7 +490,7 @@
             break;
         }
         if (element > TYPE_CPE && element != TYPE_LFE) {
-            av_log(avctx, AV_LOG_ERROR, "syntax element unsupported: %d", element);
+            av_log(avctx, AV_LOG_ERROR, "syntax element unsupported: %d\n", element);
             return AVERROR_PATCHWELCOME;
         }
 
@@ -487,7 +531,7 @@
     int ch;
     for (ch = 0; ch < FFMIN(alac->channels, 2); ch++) {
         av_freep(&alac->predict_error_buffer[ch]);
-        if (alac->sample_size == 16)
+        if (!alac->direct_output)
             av_freep(&alac->output_samples_buffer[ch]);
         av_freep(&alac->extra_bits_buffer[ch]);
     }
@@ -504,7 +548,8 @@
         FF_ALLOC_OR_GOTO(alac->avctx, alac->predict_error_buffer[ch],
                          buf_size, buf_alloc_fail);
 
-        if (alac->sample_size == 16) {
+        alac->direct_output = alac->sample_size > 16 && av_sample_fmt_is_planar(alac->avctx->sample_fmt);
+        if (!alac->direct_output) {
             FF_ALLOC_OR_GOTO(alac->avctx, alac->output_samples_buffer[ch],
                              buf_size, buf_alloc_fail);
         }
@@ -550,25 +595,27 @@
 static av_cold int alac_decode_init(AVCodecContext * avctx)
 {
     int ret;
+    int req_packed;
     ALACContext *alac = avctx->priv_data;
     alac->avctx = avctx;
 
     /* initialize from the extradata */
     if (alac->avctx->extradata_size != ALAC_EXTRADATA_SIZE) {
-        av_log(avctx, AV_LOG_ERROR, "alac: expected %d extradata bytes\n",
+        av_log(avctx, AV_LOG_ERROR, "expected %d extradata bytes\n",
             ALAC_EXTRADATA_SIZE);
         return -1;
     }
     if (alac_set_info(alac)) {
-        av_log(avctx, AV_LOG_ERROR, "alac: set_info failed\n");
+        av_log(avctx, AV_LOG_ERROR, "set_info failed\n");
         return -1;
     }
 
+    req_packed = LIBAVCODEC_VERSION_MAJOR < 55 && !av_sample_fmt_is_planar(avctx->request_sample_fmt);
     switch (alac->sample_size) {
-    case 16: avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
+    case 16: avctx->sample_fmt = req_packed ? AV_SAMPLE_FMT_S16 : AV_SAMPLE_FMT_S16P;
              break;
     case 24:
-    case 32: avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
+    case 32: avctx->sample_fmt = req_packed ? AV_SAMPLE_FMT_S32 : AV_SAMPLE_FMT_S32P;
              break;
     default: av_log_ask_for_sample(avctx, "Sample depth %d is not supported.\n",
                                    alac->sample_size);
diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c
index 6b5c4f0..79b6ba8 100644
--- a/libavcodec/alacenc.c
+++ b/libavcodec/alacenc.c
@@ -2,20 +2,20 @@
  * ALAC audio encoder
  * Copyright (c) 2008  Jaikrishnan Menon <realityman@gmx.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -546,10 +546,8 @@
     else
         max_frame_size = s->max_coded_frame_size;
 
-    if ((ret = ff_alloc_packet(avpkt, 2 * max_frame_size))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, 2 * max_frame_size)))
         return ret;
-    }
 
     /* use verbatim mode for compression_level 0 */
     s->verbatim = !s->compression_level;
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index b175fbb..ae88fab 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -2,20 +2,20 @@
  * Provide registration of all codecs, parsers and bitstream filters for libavcodec.
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -59,8 +59,10 @@
     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);
@@ -71,14 +73,18 @@
     REGISTER_ENCODER (A64MULTI, a64multi);
     REGISTER_ENCODER (A64MULTI5, a64multi5);
     REGISTER_DECODER (AASC, aasc);
-    REGISTER_DECODER (AMV, amv);
+    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);
@@ -91,9 +97,11 @@
     REGISTER_DECODER (CINEPAK, cinepak);
     REGISTER_ENCDEC  (CLJR, cljr);
     REGISTER_DECODER (CLLC, cllc);
+    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);
@@ -109,10 +117,12 @@
     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_DECODER (FLASHSV2, flashsv2);
+    REGISTER_ENCDEC  (FLASHSV2, flashsv2);
     REGISTER_DECODER (FLIC, flic);
     REGISTER_ENCDEC  (FLV, flv);
     REGISTER_DECODER (FOURXM, fourxm);
@@ -122,8 +132,10 @@
     REGISTER_ENCDEC  (H261, h261);
     REGISTER_ENCDEC  (H263, h263);
     REGISTER_DECODER (H263I, h263i);
-    REGISTER_ENCODER (H263P, h263p);
+    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);
@@ -134,6 +146,7 @@
     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);
@@ -151,21 +164,26 @@
     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_DECODER (MSVIDEO1, msvideo1);
+    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);
@@ -175,12 +193,15 @@
     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_DECODER (R10K,  r10k);
-    REGISTER_DECODER (R210,  r210);
+    REGISTER_ENCDEC  (R10K,  r10k);
+    REGISTER_ENCDEC  (R210,  r210);
     REGISTER_ENCDEC  (RAWVIDEO, rawvideo);
     REGISTER_DECODER (RL2, rl2);
     REGISTER_ENCDEC  (ROQ, roq);
@@ -190,6 +211,7 @@
     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);
@@ -199,6 +221,7 @@
     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);
@@ -213,10 +236,13 @@
     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);
@@ -232,15 +258,18 @@
     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_ENCODER (XBM, xbm);
+    REGISTER_ENCDEC  (XBM, xbm);
     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);
@@ -261,11 +290,13 @@
     REGISTER_DECODER (BINKAUDIO_RDFT, binkaudio_rdft);
     REGISTER_DECODER (BMV_AUDIO, bmv_audio);
     REGISTER_DECODER (COOK, cook);
-    REGISTER_DECODER (DCA, dca);
+    REGISTER_ENCDEC  (DCA, dca);
     REGISTER_DECODER (DSICINAUDIO, dsicinaudio);
     REGISTER_ENCDEC  (EAC3, eac3);
+    REGISTER_DECODER (FFWAVESYNTH, ffwavesynth);
     REGISTER_ENCDEC  (FLAC, flac);
-    REGISTER_DECODER (G723_1, g723_1);
+    REGISTER_ENCDEC  (G723_1, g723_1);
+    REGISTER_DECODER (G729, g729);
     REGISTER_DECODER (GSM, gsm);
     REGISTER_DECODER (GSM_MS, gsm_ms);
     REGISTER_DECODER (IAC, iac);
@@ -286,6 +317,7 @@
     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);
@@ -294,6 +326,9 @@
     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);
@@ -374,16 +409,26 @@
     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 (SRT, srt);
+    REGISTER_DECODER (REALTEXT, realtext);
+    REGISTER_DECODER (SAMI, sami);
+    REGISTER_ENCDEC  (SRT, srt);
+    REGISTER_ENCDEC  (SUBRIP, subrip);
+    REGISTER_DECODER (SUBVIEWER, subviewer);
+    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);
@@ -396,20 +441,31 @@
     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_ENCODER (LIBVORBIS, libvorbis);
+    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);
+
+    /* text */
+    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);
@@ -427,9 +483,11 @@
     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);
diff --git a/libavcodec/alpha/asm.h b/libavcodec/alpha/asm.h
index ab4cfcc..827721e 100644
--- a/libavcodec/alpha/asm.h
+++ b/libavcodec/alpha/asm.h
@@ -2,20 +2,20 @@
  * Alpha optimized DSP utils
  * Copyright (c) 2002 Falk Hueffner <falk@debian.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/alpha/dsputil_alpha.c b/libavcodec/alpha/dsputil_alpha.c
index ce7cecb..38ac020 100644
--- a/libavcodec/alpha/dsputil_alpha.c
+++ b/libavcodec/alpha/dsputil_alpha.c
@@ -2,20 +2,20 @@
  * Alpha optimized DSP utils
  * Copyright (c) 2002 Falk Hueffner <falk@debian.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -211,7 +211,7 @@
 
 #define MAKE_OP(OPNAME, SUFF, OPKIND, STORE)                                \
 static void OPNAME ## _pixels ## SUFF ## _axp                               \
-        (uint8_t *restrict block, const uint8_t *restrict pixels,           \
+        (uint8_t *av_restrict block, const uint8_t *av_restrict pixels,           \
          int line_size, int h)                                              \
 {                                                                           \
     if ((size_t) pixels & 0x7) {                                            \
@@ -222,7 +222,7 @@
 }                                                                           \
                                                                             \
 static void OPNAME ## _pixels16 ## SUFF ## _axp                             \
-        (uint8_t *restrict block, const uint8_t *restrict pixels,           \
+        (uint8_t *av_restrict block, const uint8_t *av_restrict pixels,           \
          int line_size, int h)                                              \
 {                                                                           \
     OPNAME ## _pixels ## SUFF ## _axp(block,     pixels,     line_size, h); \
@@ -336,7 +336,7 @@
     put_pixels_clamped_axp_p = c->put_pixels_clamped;
     add_pixels_clamped_axp_p = c->add_pixels_clamped;
 
-    if (avctx->bits_per_raw_sample <= 8 &&
+    if (!avctx->lowres && avctx->bits_per_raw_sample <= 8 &&
         (avctx->idct_algo == FF_IDCT_AUTO ||
          avctx->idct_algo == FF_IDCT_SIMPLEALPHA)) {
         c->idct_put = ff_simple_idct_put_axp;
diff --git a/libavcodec/alpha/dsputil_alpha.h b/libavcodec/alpha/dsputil_alpha.h
index 0dcacab..4bc09a4 100644
--- a/libavcodec/alpha/dsputil_alpha.h
+++ b/libavcodec/alpha/dsputil_alpha.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,8 +36,8 @@
 extern void (*add_pixels_clamped_axp_p)(const DCTELEM *block, uint8_t *pixels,
                                         int line_size);
 
-void get_pixels_mvi(DCTELEM *restrict block,
-                    const uint8_t *restrict 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,
                      int stride);
 int pix_abs8x8_mvi(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 ca857ac..32a8bc9 100644
--- a/libavcodec/alpha/dsputil_alpha_asm.S
+++ b/libavcodec/alpha/dsputil_alpha_asm.S
@@ -2,20 +2,20 @@
  * Alpha optimized DSP utils
  * Copyright (c) 2002 Falk Hueffner <falk@debian.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/alpha/motion_est_alpha.c b/libavcodec/alpha/motion_est_alpha.c
index bb9ab13..927b25d 100644
--- a/libavcodec/alpha/motion_est_alpha.c
+++ b/libavcodec/alpha/motion_est_alpha.c
@@ -2,20 +2,20 @@
  * Alpha optimized DSP utils
  * Copyright (c) 2002 Falk Hueffner <falk@debian.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -23,8 +23,8 @@
 #include "dsputil_alpha.h"
 #include "asm.h"
 
-void get_pixels_mvi(DCTELEM *restrict block,
-                    const uint8_t *restrict pixels, int line_size)
+void get_pixels_mvi(DCTELEM *av_restrict block,
+                    const uint8_t *av_restrict pixels, int line_size)
 {
     int h = 8;
 
diff --git a/libavcodec/alpha/motion_est_mvi_asm.S b/libavcodec/alpha/motion_est_mvi_asm.S
index 7fe4e16..2399085 100644
--- a/libavcodec/alpha/motion_est_mvi_asm.S
+++ b/libavcodec/alpha/motion_est_mvi_asm.S
@@ -2,20 +2,20 @@
  * Alpha optimized DSP utils
  * Copyright (c) 2002 Falk Hueffner <falk@debian.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/alpha/mpegvideo_alpha.c b/libavcodec/alpha/mpegvideo_alpha.c
index a1a8a27..28eca07 100644
--- a/libavcodec/alpha/mpegvideo_alpha.c
+++ b/libavcodec/alpha/mpegvideo_alpha.c
@@ -2,20 +2,20 @@
  * Alpha optimized DSP utils
  * Copyright (c) 2002 Falk Hueffner <falk@debian.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/alpha/regdef.h b/libavcodec/alpha/regdef.h
index fa9ad98..aa1959f 100644
--- a/libavcodec/alpha/regdef.h
+++ b/libavcodec/alpha/regdef.h
@@ -2,20 +2,20 @@
  * Alpha optimized DSP utils
  * copyright (c) 2002 Falk Hueffner <falk@debian.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/alpha/simple_idct_alpha.c b/libavcodec/alpha/simple_idct_alpha.c
index 61bc5f2..522efd2 100644
--- a/libavcodec/alpha/simple_idct_alpha.c
+++ b/libavcodec/alpha/simple_idct_alpha.c
@@ -9,20 +9,20 @@
  * Alpha optimizations by Måns Rullgård <mans@mansr.com>
  *                     and Falk Hueffner <falk@debian.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c
index 1c3f0cb..46dd0b4 100644
--- a/libavcodec/alsdec.c
+++ b/libavcodec/alsdec.c
@@ -2,20 +2,20 @@
  * MPEG-4 ALS decoder
  * Copyright (c) 2009 Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -394,7 +394,7 @@
         if (get_bits_left(&gb) < 32)
             return -1;
 
-        if (avctx->err_recognition & AV_EF_CRCCHECK) {
+        if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL)) {
             ctx->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE);
             ctx->crc       = 0xFFFFFFFF;
             ctx->crc_org   = ~get_bits_long(&gb, 32);
@@ -1025,8 +1025,8 @@
 {
     unsigned int count = 0;
 
-    for (; b < b_max; b++)
-        count += div_blocks[b];
+    while (b < b_max)
+        count += div_blocks[b++];
 
     if (count)
         memset(buf, 0, sizeof(*buf) * count);
@@ -1132,7 +1132,7 @@
         // reconstruct joint-stereo blocks
         if (bd[0].js_blocks) {
             if (bd[1].js_blocks)
-                av_log(ctx->avctx, AV_LOG_WARNING, "Invalid channel pair!\n");
+                av_log(ctx->avctx, AV_LOG_WARNING, "Invalid channel pair.\n");
 
             for (s = 0; s < div_blocks[b]; s++)
                 bd[0].raw_samples[s] = bd[1].raw_samples[s] - bd[0].raw_samples[s];
@@ -1226,7 +1226,7 @@
     }
 
     if (dep == channels) {
-        av_log(ctx->avctx, AV_LOG_WARNING, "Invalid channel correlation!\n");
+        av_log(ctx->avctx, AV_LOG_WARNING, "Invalid channel correlation.\n");
         return -1;
     }
 
@@ -1403,6 +1403,7 @@
                 bd.lpc_cof     = ctx->lpc_cof[c];
                 bd.quant_cof   = ctx->quant_cof[c];
                 bd.raw_samples = ctx->raw_samples[c] + offset;
+
                 if ((ret = decode_block(ctx, &bd)) < 0)
                     return ret;
             }
@@ -1483,7 +1484,7 @@
     }
 
     // update CRC
-    if (sconf->crc_enabled && (avctx->err_recognition & AV_EF_CRCCHECK)) {
+    if (sconf->crc_enabled && (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL))) {
         int swap = HAVE_BIGENDIAN != sconf->msb_first;
 
         if (ctx->avctx->bits_per_raw_sample == 24) {
@@ -1533,7 +1534,7 @@
         // 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");
         }
     }
 
@@ -1595,12 +1596,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;
     }
@@ -1646,7 +1647,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);
     }
 
@@ -1671,7 +1672,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);
     }
@@ -1689,7 +1690,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);
         }
@@ -1710,7 +1711,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);
     }
@@ -1722,13 +1723,13 @@
 
     // allocate crc buffer
     if (HAVE_BIGENDIAN != sconf->msb_first && sconf->crc_enabled &&
-        (avctx->err_recognition & AV_EF_CRCCHECK)) {
+        (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL))) {
         ctx->crc_buffer = av_malloc(sizeof(*ctx->crc_buffer) *
                                     ctx->cur_frame_length *
                                     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);
         }
diff --git a/libavcodec/amr.h b/libavcodec/amr.h
index 676c963..1ac73ab 100644
--- a/libavcodec/amr.h
+++ b/libavcodec/amr.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010 Marcelo Galvao Povoa
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/amrnbdata.h b/libavcodec/amrnbdata.h
index b7d1b89..435fd99 100644
--- a/libavcodec/amrnbdata.h
+++ b/libavcodec/amrnbdata.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2006-2007 Robert Swain
  * Copyright (c) 2009 Colin McQuillan
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -1655,10 +1655,10 @@
  0.016998,  0.023804, -0.041779,  0.025696,  0.019989,
 };
 
-static const float *ir_filters_lookup[2]           = {
+static const float * const ir_filters_lookup[2]           = {
     ir_filter_strong,           ir_filter_medium
 };
-static const float *ir_filters_lookup_MODE_7k95[2] = {
+static const float * const ir_filters_lookup_MODE_7k95[2] = {
     ir_filter_strong_MODE_7k95, ir_filter_medium
 };
 
diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c
index d0ad76c..32b754f 100644
--- a/libavcodec/amrnbdec.c
+++ b/libavcodec/amrnbdec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2006-2007 Robert Swain
  * Copyright (c) 2009 Colin McQuillan
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -46,6 +46,8 @@
 #include "avcodec.h"
 #include "dsputil.h"
 #include "libavutil/common.h"
+#include "libavutil/avassert.h"
+#include "celp_math.h"
 #include "celp_filters.h"
 #include "acelp_filters.h"
 #include "acelp_vectors.h"
@@ -82,7 +84,7 @@
 /** Maximum sharpening factor
  *
  * The specification says 0.8, which should be 13107, but the reference C code
- * uses 13017 instead. (Amusingly the same applies to SHARP_MAX in bitexact G.729.)
+ * uses 13017 instead. (Amusingly the same applies to SHARP_MAX in g729dec.c.)
  */
 #define SHARP_MAX 0.79449462890625
 
@@ -135,6 +137,11 @@
 
     float samples_in[LP_FILTER_ORDER + AMR_SUBFRAME_SIZE]; ///< floating point samples
 
+    ACELPFContext                     acelpf_ctx; ///< context for filters for ACELP-based codecs
+    ACELPVContext                     acelpv_ctx; ///< context for vector operations for ACELP-based codecs
+    CELPFContext                       celpf_ctx; ///< context for filters for CELP-based codecs
+    CELPMContext                       celpm_ctx; ///< context for fixed point math operations
+
 } AMRContext;
 
 /** Double version of ff_weighted_vector_sumf() */
@@ -170,6 +177,11 @@
     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);
+    ff_celp_math_init(&p->celpm_ctx);
+
     return 0;
 }
 
@@ -213,15 +225,16 @@
  * Interpolate the LSF vector (used for fixed gain smoothing).
  * The interpolation is done over all four subframes even in MODE_12k2.
  *
+ * @param[in]     ctx       The Context
  * @param[in,out] lsf_q     LSFs in [0,1] for each subframe
  * @param[in]     lsf_new   New LSFs in [0,1] for subframe 4
  */
-static void interpolate_lsf(float lsf_q[4][LP_FILTER_ORDER], float *lsf_new)
+static void interpolate_lsf(ACELPVContext *ctx, float lsf_q[4][LP_FILTER_ORDER], float *lsf_new)
 {
     int i;
 
     for (i = 0; i < 4; i++)
-        ff_weighted_vector_sumf(lsf_q[i], lsf_q[3], lsf_new,
+        ctx->weighted_vector_sumf(lsf_q[i], lsf_q[3], lsf_new,
                                 0.25 * (3 - i), 0.25 * (i + 1),
                                 LP_FILTER_ORDER);
 }
@@ -265,7 +278,7 @@
     ff_set_min_dist_lsf(lsf_q, MIN_LSF_SPACING, LP_FILTER_ORDER);
 
     if (update)
-        interpolate_lsf(p->lsf_q, lsf_q);
+        interpolate_lsf(&p->acelpv_ctx, p->lsf_q, lsf_q);
 
     ff_acelp_lsf2lspd(lsp, lsf_q, LP_FILTER_ORDER);
 }
@@ -328,7 +341,7 @@
     ff_set_min_dist_lsf(lsf_q, MIN_LSF_SPACING, LP_FILTER_ORDER);
 
     // store data for computing the next frame's LSFs
-    interpolate_lsf(p->lsf_q, lsf_q);
+    interpolate_lsf(&p->acelpv_ctx, p->lsf_q, lsf_q);
     memcpy(p->prev_lsf_r, lsf_r, LP_FILTER_ORDER * sizeof(*lsf_r));
 
     ff_acelp_lsf2lspd(p->lsp[3], lsf_q, LP_FILTER_ORDER);
@@ -394,7 +407,8 @@
 
     /* Calculate the pitch vector by interpolating the past excitation at the
        pitch lag using a b60 hamming windowed sinc function.   */
-    ff_acelp_interpolatef(p->excitation, p->excitation + 1 - pitch_lag_int,
+    p->acelpf_ctx.acelp_interpolatef(p->excitation,
+                          p->excitation + 1 - pitch_lag_int,
                           ff_b60_sinc, 6,
                           pitch_lag_frac + 6 - 6*(pitch_lag_frac > 0),
                           10, AMR_SUBFRAME_SIZE);
@@ -478,7 +492,7 @@
 static void decode_fixed_sparse(AMRFixed *fixed_sparse, const uint16_t *pulses,
                                 const enum Mode mode, const int subframe)
 {
-    assert(MODE_4k75 <= mode && mode <= MODE_12k2);
+    av_assert1(MODE_4k75 <= (signed)mode && mode <= MODE_12k2);
 
     if (mode == MODE_12k2) {
         ff_decode_10_pulses_35bits(pulses, fixed_sparse, gray_decode, 5, 3);
@@ -779,12 +793,12 @@
         for (i = 0; i < AMR_SUBFRAME_SIZE; i++)
             p->pitch_vector[i] *= 0.25;
 
-    ff_weighted_vector_sumf(excitation, p->pitch_vector, fixed_vector,
+    p->acelpv_ctx.weighted_vector_sumf(excitation, p->pitch_vector, fixed_vector,
                             p->pitch_gain[4], fixed_gain, AMR_SUBFRAME_SIZE);
 
     // emphasize pitch vector contribution
     if (p->pitch_gain[4] > 0.5 && !overflow) {
-        float energy = ff_scalarproduct_float_c(excitation, excitation,
+        float energy = p->celpm_ctx.dot_productf(excitation, excitation,
                                                 AMR_SUBFRAME_SIZE);
         float pitch_factor =
             p->pitch_gain[4] *
@@ -799,7 +813,8 @@
                                                 AMR_SUBFRAME_SIZE);
     }
 
-    ff_celp_lp_synthesis_filterf(samples, lpc, excitation, AMR_SUBFRAME_SIZE,
+    p->celpf_ctx.celp_lp_synthesis_filterf(samples, lpc, excitation,
+                                 AMR_SUBFRAME_SIZE,
                                  LP_FILTER_ORDER);
 
     // detect overflow
@@ -845,10 +860,11 @@
 /**
  * Get the tilt factor of a formant filter from its transfer function
  *
+ * @param p     The Context
  * @param lpc_n LP_FILTER_ORDER coefficients of the numerator
  * @param lpc_d LP_FILTER_ORDER coefficients of the denominator
  */
-static float tilt_factor(float *lpc_n, float *lpc_d)
+static float tilt_factor(AMRContext *p, float *lpc_n, float *lpc_d)
 {
     float rh0, rh1; // autocorrelation at lag 0 and 1
 
@@ -858,11 +874,12 @@
 
     hf[0] = 1.0;
     memcpy(hf + 1, lpc_n, sizeof(float) * LP_FILTER_ORDER);
-    ff_celp_lp_synthesis_filterf(hf, lpc_d, hf, AMR_TILT_RESPONSE,
+    p->celpf_ctx.celp_lp_synthesis_filterf(hf, lpc_d, hf,
+                                 AMR_TILT_RESPONSE,
                                  LP_FILTER_ORDER);
 
-    rh0 = ff_scalarproduct_float_c(hf, hf,     AMR_TILT_RESPONSE);
-    rh1 = ff_scalarproduct_float_c(hf, hf + 1, AMR_TILT_RESPONSE - 1);
+    rh0 = p->celpm_ctx.dot_productf(hf, hf,     AMR_TILT_RESPONSE);
+    rh1 = p->celpm_ctx.dot_productf(hf, hf + 1, AMR_TILT_RESPONSE - 1);
 
     // The spec only specifies this check for 12.2 and 10.2 kbit/s
     // modes. But in the ref source the tilt is always non-negative.
@@ -882,7 +899,7 @@
     int i;
     float *samples          = p->samples_in + LP_FILTER_ORDER; // Start of input
 
-    float speech_gain       = ff_scalarproduct_float_c(samples, samples,
+    float speech_gain       = p->celpm_ctx.dot_productf(samples, samples,
                                                        AMR_SUBFRAME_SIZE);
 
     float pole_out[AMR_SUBFRAME_SIZE + LP_FILTER_ORDER];  // Output of pole filter
@@ -903,16 +920,16 @@
     }
 
     memcpy(pole_out, p->postfilter_mem, sizeof(float) * LP_FILTER_ORDER);
-    ff_celp_lp_synthesis_filterf(pole_out + LP_FILTER_ORDER, lpc_d, samples,
+    p->celpf_ctx.celp_lp_synthesis_filterf(pole_out + LP_FILTER_ORDER, lpc_d, samples,
                                  AMR_SUBFRAME_SIZE, LP_FILTER_ORDER);
     memcpy(p->postfilter_mem, pole_out + AMR_SUBFRAME_SIZE,
            sizeof(float) * LP_FILTER_ORDER);
 
-    ff_celp_lp_zero_synthesis_filterf(buf_out, lpc_n,
+    p->celpf_ctx.celp_lp_zero_synthesis_filterf(buf_out, lpc_n,
                                       pole_out + LP_FILTER_ORDER,
                                       AMR_SUBFRAME_SIZE, LP_FILTER_ORDER);
 
-    ff_tilt_compensation(&p->tilt_mem, tilt_factor(lpc_n, lpc_d), buf_out,
+    ff_tilt_compensation(&p->tilt_mem, tilt_factor(p, lpc_n, lpc_d), buf_out,
                          AMR_SUBFRAME_SIZE);
 
     ff_adaptive_gain_control(buf_out, buf_out, speech_gain, AMR_SUBFRAME_SIZE,
@@ -950,7 +967,8 @@
         return AVERROR_INVALIDDATA;
     }
     if (p->cur_frame_mode == MODE_DTX) {
-        av_log_missing_feature(avctx, "dtx mode", 1);
+        av_log_missing_feature(avctx, "dtx mode", 0);
+        av_log(avctx, AV_LOG_INFO, "Note: libopencore_amrnb supports dtx\n");
         return -1;
     }
 
@@ -988,7 +1006,7 @@
 
         p->fixed_gain[4] =
             ff_amr_set_fixed_gain(fixed_gain_factor,
-                                  ff_scalarproduct_float_c(p->fixed_vector,
+                       p->celpm_ctx.dot_productf(p->fixed_vector,
                                                            p->fixed_vector,
                                                            AMR_SUBFRAME_SIZE) /
                                   AMR_SUBFRAME_SIZE,
@@ -1034,7 +1052,8 @@
         update_state(p);
     }
 
-    ff_acelp_apply_order_2_transfer_function(buf_out, buf_out, highpass_zeros,
+    p->acelpf_ctx.acelp_apply_order_2_transfer_function(buf_out,
+                                             buf_out, highpass_zeros,
                                              highpass_poles,
                                              highpass_gain * AMR_SAMPLE_SCALE,
                                              p->high_pass_mem, AMR_BLOCK_SIZE);
@@ -1045,7 +1064,7 @@
      * for fixed_gain_smooth.
      * The specification has an incorrect formula: the reference decoder uses
      * qbar(n-1) rather than qbar(n) in section 6.1(4) equation 71. */
-    ff_weighted_vector_sumf(p->lsf_avg, p->lsf_avg, p->lsf_q[3],
+    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;
diff --git a/libavcodec/amrwbdata.h b/libavcodec/amrwbdata.h
index 81f8b47..8390582 100644
--- a/libavcodec/amrwbdata.h
+++ b/libavcodec/amrwbdata.h
@@ -2,20 +2,20 @@
  * AMR wideband data and definitions
  * Copyright (c) 2010 Marcelo Galvao Povoa
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -1805,7 +1805,7 @@
     -7.501221e-02,  2.920532e-02,  1.660156e-02,  7.751465e-02
 };
 
-static const float *ir_filters_lookup[2] = {
+static const float * const ir_filters_lookup[2] = {
     ir_filter_str, ir_filter_mid
 };
 
diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c
index 18b34cf..738dd98 100644
--- a/libavcodec/amrwbdec.c
+++ b/libavcodec/amrwbdec.c
@@ -2,20 +2,20 @@
  * AMR wideband decoder
  * Copyright (c) 2010 Marcelo Galvao Povoa
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A particular PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -31,6 +31,7 @@
 #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"
@@ -39,6 +40,7 @@
 #include "amr.h"
 
 #include "amrwbdata.h"
+#include "mips/amrwbdec_mips.h"
 
 typedef struct {
     AVFrame                              avframe; ///< AVFrame for decoded samples
@@ -83,6 +85,11 @@
 
     AVLFG                                   prng; ///< random number generator for white noise excitation
     uint8_t                          first_frame; ///< flag active during decoding of the first frame
+    ACELPFContext                     acelpf_ctx; ///< context for filters for ACELP-based codecs
+    ACELPVContext                     acelpv_ctx; ///< context for vector operations for ACELP-based codecs
+    CELPFContext                       celpf_ctx; ///< context for filters for CELP-based codecs
+    CELPMContext                       celpm_ctx; ///< context for fixed point math operations
+
 } AMRWBContext;
 
 static av_cold int amrwb_decode_init(AVCodecContext *avctx)
@@ -106,6 +113,11 @@
     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);
+    ff_celp_math_init(&ctx->celpm_ctx);
+
     return 0;
 }
 
@@ -320,7 +332,8 @@
 
     /* Calculate the pitch vector by interpolating the past excitation at the
        pitch lag using a hamming windowed sinc function */
-    ff_acelp_interpolatef(exc, exc + 1 - pitch_lag_int,
+    ctx->acelpf_ctx.acelp_interpolatef(exc,
+                          exc + 1 - pitch_lag_int,
                           ac_inter, 4,
                           pitch_lag_frac + (pitch_lag_frac > 0 ? 0 : 4),
                           LP_ORDER, AMRWB_SFR_SIZE + 1);
@@ -579,18 +592,20 @@
  *
  * @param[in] p_vector, f_vector   Pitch and fixed excitation vectors
  * @param[in] p_gain, f_gain       Pitch and fixed gains
+ * @param[in] ctx                  The context
  */
 // XXX: There is something wrong with the precision here! The magnitudes
 // of the energies are not correct. Please check the reference code carefully
 static float voice_factor(float *p_vector, float p_gain,
-                          float *f_vector, float f_gain)
+                          float *f_vector, float f_gain,
+                          CELPMContext *ctx)
 {
-    double p_ener = (double) ff_scalarproduct_float_c(p_vector, p_vector,
-                                                      AMRWB_SFR_SIZE) *
-                    p_gain * p_gain;
-    double f_ener = (double) ff_scalarproduct_float_c(f_vector, f_vector,
-                                                      AMRWB_SFR_SIZE) *
-                    f_gain * f_gain;
+    double p_ener = (double) ctx->dot_productf(p_vector, p_vector,
+                                             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;
 
     return (p_ener - f_ener) / (p_ener + f_ener);
 }
@@ -752,13 +767,13 @@
                       float fixed_gain, const float *fixed_vector,
                       float *samples)
 {
-    ff_weighted_vector_sumf(excitation, ctx->pitch_vector, fixed_vector,
+    ctx->acelpv_ctx.weighted_vector_sumf(excitation, ctx->pitch_vector, fixed_vector,
                             ctx->pitch_gain[0], fixed_gain, AMRWB_SFR_SIZE);
 
     /* emphasize pitch vector contribution in low bitrate modes */
     if (ctx->pitch_gain[0] > 0.5 && ctx->fr_cur_mode <= MODE_8k85) {
         int i;
-        float energy = ff_scalarproduct_float_c(excitation, excitation,
+        float energy = ctx->celpm_ctx.dot_productf(excitation, excitation,
                                                 AMRWB_SFR_SIZE);
 
         // XXX: Weird part in both ref code and spec. A unknown parameter
@@ -772,7 +787,7 @@
                                                 energy, AMRWB_SFR_SIZE);
     }
 
-    ff_celp_lp_synthesis_filterf(samples, lpc, excitation,
+    ctx->celpf_ctx.celp_lp_synthesis_filterf(samples, lpc, excitation,
                                  AMRWB_SFR_SIZE, LP_ORDER);
 }
 
@@ -804,8 +819,9 @@
  * @param[out] out                 Buffer for interpolated signal
  * @param[in]  in                  Current signal data (length 0.8*o_size)
  * @param[in]  o_size              Output signal length
+ * @param[in] ctx                  The context
  */
-static void upsample_5_4(float *out, const float *in, int o_size)
+static void upsample_5_4(float *out, const float *in, int o_size, CELPMContext *ctx)
 {
     const float *in0 = in - UPS_FIR_SIZE + 1;
     int i, j, k;
@@ -818,7 +834,7 @@
         i++;
 
         for (k = 1; k < 5; k++) {
-            out[i] = ff_scalarproduct_float_c(in0 + int_part,
+            out[i] = ctx->dot_productf(in0 + int_part,
                                               upsample_fir[4 - frac_part],
                                               UPS_MEM_SIZE);
             int_part++;
@@ -846,8 +862,8 @@
     if (ctx->fr_cur_mode == MODE_23k85)
         return qua_hb_gain[hb_idx] * (1.0f / (1 << 14));
 
-    tilt = ff_scalarproduct_float_c(synth, synth + 1, AMRWB_SFR_SIZE - 1) /
-           ff_scalarproduct_float_c(synth, synth, AMRWB_SFR_SIZE);
+    tilt = ctx->celpm_ctx.dot_productf(synth, synth + 1, AMRWB_SFR_SIZE - 1) /
+           ctx->celpm_ctx.dot_productf(synth, synth, AMRWB_SFR_SIZE);
 
     /* return gain bounded by [0.1, 1.0] */
     return av_clipf((1.0 - FFMAX(0.0, tilt)) * (1.25 - 0.25 * wsp), 0.1, 1.0);
@@ -866,7 +882,7 @@
                                  const float *synth_exc, float hb_gain)
 {
     int i;
-    float energy = ff_scalarproduct_float_c(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++)
@@ -997,7 +1013,7 @@
         float e_isf[LP_ORDER_16k]; // ISF vector for extrapolation
         double e_isp[LP_ORDER_16k];
 
-        ff_weighted_vector_sumf(e_isf, isf_past, isf, isfp_inter[subframe],
+        ctx->acelpv_ctx.weighted_vector_sumf(e_isf, isf_past, isf, isfp_inter[subframe],
                                 1.0 - isfp_inter[subframe], LP_ORDER);
 
         extrapolate_isf(e_isf);
@@ -1011,7 +1027,7 @@
         lpc_weighting(hb_lpc, ctx->lp_coef[subframe], 0.6, LP_ORDER);
     }
 
-    ff_celp_lp_synthesis_filterf(samples, hb_lpc, exc, AMRWB_SFR_SIZE_16k,
+    ctx->celpf_ctx.celp_lp_synthesis_filterf(samples, hb_lpc, exc, AMRWB_SFR_SIZE_16k,
                                  (mode == MODE_6k60) ? LP_ORDER_16k : LP_ORDER);
 }
 
@@ -1026,6 +1042,8 @@
  *
  * @remark It is safe to pass the same array in in and out parameters
  */
+
+#ifndef hb_fir_filter
 static void hb_fir_filter(float *out, const float fir_coef[HB_FIR_SIZE + 1],
                           float mem[HB_FIR_SIZE], const float *in)
 {
@@ -1043,6 +1061,7 @@
 
     memcpy(mem, data + AMRWB_SFR_SIZE_16k, HB_FIR_SIZE * sizeof(float));
 }
+#endif /* hb_fir_filter */
 
 /**
  * Update context state before the next subframe.
@@ -1159,7 +1178,7 @@
 
         ctx->fixed_gain[0] =
             ff_amr_set_fixed_gain(fixed_gain_factor,
-                                  ff_scalarproduct_float_c(ctx->fixed_vector,
+                                  ctx->celpm_ctx.dot_productf(ctx->fixed_vector,
                                                            ctx->fixed_vector,
                                                            AMRWB_SFR_SIZE) /
                                   AMRWB_SFR_SIZE,
@@ -1168,7 +1187,8 @@
 
         /* Calculate voice factor and store tilt for next subframe */
         voice_fac      = voice_factor(ctx->pitch_vector, ctx->pitch_gain[0],
-                                      ctx->fixed_vector, ctx->fixed_gain[0]);
+                                      ctx->fixed_vector, ctx->fixed_gain[0],
+                                      &ctx->celpm_ctx);
         ctx->tilt_coef = voice_fac * 0.25 + 0.25;
 
         /* Construct current excitation */
@@ -1194,15 +1214,15 @@
         de_emphasis(&ctx->samples_up[UPS_MEM_SIZE],
                     &ctx->samples_az[LP_ORDER], PREEMPH_FAC, ctx->demph_mem);
 
-        ff_acelp_apply_order_2_transfer_function(&ctx->samples_up[UPS_MEM_SIZE],
+        ctx->acelpf_ctx.acelp_apply_order_2_transfer_function(&ctx->samples_up[UPS_MEM_SIZE],
             &ctx->samples_up[UPS_MEM_SIZE], hpf_zeros, hpf_31_poles,
             hpf_31_gain, ctx->hpf_31_mem, AMRWB_SFR_SIZE);
 
         upsample_5_4(sub_buf, &ctx->samples_up[UPS_FIR_SIZE],
-                     AMRWB_SFR_SIZE_16k);
+                     AMRWB_SFR_SIZE_16k, &ctx->celpm_ctx);
 
         /* High frequency band (6.4 - 7.0 kHz) generation part */
-        ff_acelp_apply_order_2_transfer_function(hb_samples,
+        ctx->acelpf_ctx.acelp_apply_order_2_transfer_function(hb_samples,
             &ctx->samples_up[UPS_MEM_SIZE], hpf_zeros, hpf_400_poles,
             hpf_400_gain, ctx->hpf_400_mem, AMRWB_SFR_SIZE);
 
diff --git a/libavcodec/anm.c b/libavcodec/anm.c
index de563dd..22c274b 100644
--- a/libavcodec/anm.c
+++ b/libavcodec/anm.c
@@ -2,20 +2,20 @@
  * Deluxe Paint Animation decoder
  * Copyright (c) 2009 Peter Ross
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -41,7 +41,8 @@
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
-    s->frame.reference = 1;
+    avcodec_get_frame_defaults(&s->frame);
+    s->frame.reference = 3;
     bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size);
     if (bytestream2_get_bytes_left(&s->gb) < 16 * 8 + 4 * 256)
         return -1;
diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c
index 964abc6..6bfd08c 100644
--- a/libavcodec/ansi.c
+++ b/libavcodec/ansi.c
@@ -2,20 +2,20 @@
  * ASCII/ANSI art decoder
  * Copyright (c) 2010 Peter Ross <pross@xvid.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,6 +26,7 @@
 
 #include "libavutil/common.h"
 #include "libavutil/lfg.h"
+#include "libavutil/xga_font_data.h"
 #include "avcodec.h"
 #include "cga_data.h"
 
@@ -58,6 +59,7 @@
     int attributes;       /**< attribute flags */
     int fg;               /**< foreground color */
     int bg;               /**< background color */
+    int first_frame;
 
     /* ansi parser state machine */
     enum {
@@ -77,17 +79,33 @@
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
     /* defaults */
-    s->font        = ff_vga16_font;
+    s->font        = avpriv_vga16_font;
     s->font_height = 16;
     s->fg          = DEFAULT_FG_COLOR;
     s->bg          = DEFAULT_BG_COLOR;
 
+    avcodec_get_frame_defaults(&s->frame);
     if (!avctx->width || !avctx->height)
         avcodec_set_dimensions(avctx, 80<<3, 25<<4);
 
     return 0;
 }
 
+static void set_palette(uint32_t *pal)
+{
+    int r, g, b;
+    memcpy(pal, ff_cga_palette, 16 * 4);
+    pal += 16;
+#define COLOR(x) ((x) * 40 + 55)
+    for (r = 0; r < 6; r++)
+        for (g = 0; g < 6; g++)
+            for (b = 0; b < 6; b++)
+                *pal++ = 0xFF000000 | (COLOR(r) << 16) | (COLOR(g) << 8) | COLOR(b);
+#define GRAY(x) ((x) * 10 + 8)
+    for (g = 0; g < 24; g++)
+        *pal++ = 0xFF000000 | (GRAY(g) << 16) | (GRAY(g) << 8) | GRAY(g);
+}
+
 static void hscroll(AVCodecContext *avctx)
 {
     AnsiContext *s = avctx->priv_data;
@@ -182,21 +200,23 @@
     case 'l': //reset screen mode
         if (s->nb_args < 2)
             s->args[0] = DEFAULT_SCREEN_MODE;
+        width = avctx->width;
+        height = avctx->height;
         switch(s->args[0]) {
         case 0: case 1: case 4: case 5: case 13: case 19: //320x200 (25 rows)
-            s->font = ff_cga_font;
+            s->font = avpriv_cga_font;
             s->font_height = 8;
             width  = 40<<3;
             height = 25<<3;
             break;
         case 2: case 3: //640x400 (25 rows)
-            s->font = ff_vga16_font;
+            s->font = avpriv_vga16_font;
             s->font_height = 16;
             width  = 80<<3;
             height = 25<<4;
             break;
         case 6: case 14: //640x200 (25 rows)
-            s->font = ff_cga_font;
+            s->font = avpriv_cga_font;
             s->font_height = 8;
             width  = 80<<3;
             height = 25<<3;
@@ -204,13 +224,13 @@
         case 7: //set line wrapping
             break;
         case 15: case 16: //640x350 (43 rows)
-            s->font = ff_cga_font;
+            s->font = avpriv_cga_font;
             s->font_height = 8;
             width  = 80<<3;
             height = 43<<3;
             break;
         case 17: case 18: //640x480 (60 rows)
-            s->font = ff_cga_font;
+            s->font = avpriv_cga_font;
             s->font_height = 8;
             width  = 80<<3;
             height = 60<<4;
@@ -229,7 +249,7 @@
             }
             s->frame.pict_type           = AV_PICTURE_TYPE_I;
             s->frame.palette_has_changed = 1;
-            memcpy(s->frame.data[1], ff_cga_palette, 16 * 4);
+            set_palette((uint32_t *)s->frame.data[1]);
             erase_screen(avctx);
         } else if (c == 'l') {
             erase_screen(avctx);
@@ -277,12 +297,20 @@
                 s->bg = DEFAULT_BG_COLOR;
             } else if (m == 1 || m == 2 || m == 4 || m == 5 || m == 7 || m == 8) {
                 s->attributes |= 1 << (m - 1);
-            } else if (m >= 30 && m <= 38) {
+            } else if (m >= 30 && m <= 37) {
                 s->fg = ansi_to_cga[m - 30];
+            } else if (m == 38 && i + 2 < s->nb_args && s->args[i + 1] == 5 && s->args[i + 2] < 256) {
+                int index = s->args[i + 2];
+                s->fg = index < 16 ? ansi_to_cga[index] : index;
+                i += 2;
             } else if (m == 39) {
                 s->fg = ansi_to_cga[DEFAULT_FG_COLOR];
             } else if (m >= 40 && m <= 47) {
                 s->bg = ansi_to_cga[m - 40];
+            } else if (m == 48 && i + 2 < s->nb_args && s->args[i + 1] == 5 && s->args[i + 2] < 256) {
+                int index = s->args[i + 2];
+                s->bg = index < 16 ? ansi_to_cga[index] : index;
+                i += 2;
             } else if (m == 49) {
                 s->fg = ansi_to_cga[DEFAULT_BG_COLOR];
             } else {
@@ -326,7 +354,11 @@
     }
     s->frame.pict_type           = AV_PICTURE_TYPE_I;
     s->frame.palette_has_changed = 1;
-    memcpy(s->frame.data[1], ff_cga_palette, 16 * 4);
+    set_palette((uint32_t *)s->frame.data[1]);
+    if (!s->first_frame) {
+        erase_screen(avctx);
+        s->first_frame = 1;
+    }
 
     while(buf < buf_end) {
         switch(s->state) {
@@ -365,11 +397,10 @@
             if (buf[0] == '[') {
                 s->state   = STATE_CODE;
                 s->nb_args = 0;
-                s->args[0] = 0;
+                s->args[0] = -1;
             } else {
                 s->state = STATE_NORMAL;
                 draw_char(avctx, 0x1B);
-                    return -1;
                 continue;
             }
             break;
@@ -378,7 +409,7 @@
             case '0': case '1': case '2': case '3': case '4':
             case '5': case '6': case '7': case '8': case '9':
                 if (s->nb_args < MAX_NB_ARGS)
-                    s->args[s->nb_args] = s->args[s->nb_args] * 10 + buf[0] - '0';
+                    s->args[s->nb_args] = FFMAX(s->args[s->nb_args], 0) * 10 + buf[0] - '0';
                 break;
             case ';':
                 s->nb_args++;
@@ -394,7 +425,7 @@
             default:
                 if (s->nb_args > MAX_NB_ARGS)
                     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])
+                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;
diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c
index 9d2941c..cba3dc0 100644
--- a/libavcodec/apedec.c
+++ b/libavcodec/apedec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>
  *  based upon libdemac from Dave Chapman.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -217,7 +217,7 @@
 
     av_log(avctx, AV_LOG_DEBUG, "Compression Level: %d - Flags: %d\n",
            s->compression_level, s->flags);
-    if (s->compression_level % 1000 || s->compression_level > COMPRESSION_LEVEL_INSANE) {
+    if (s->compression_level % 1000 || s->compression_level > COMPRESSION_LEVEL_INSANE || !s->compression_level) {
         av_log(avctx, AV_LOG_ERROR, "Incorrect compression level %d\n",
                s->compression_level);
         return AVERROR_INVALIDDATA;
diff --git a/libavcodec/api-example.c b/libavcodec/api-example.c
deleted file mode 100644
index 198a59d..0000000
--- a/libavcodec/api-example.c
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
- * copyright (c) 2001 Fabrice Bellard
- *
- * 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
- * libavcodec API use example.
- *
- * @example libavcodec/api-example.c
- * Note that this library only handles codecs (mpeg, mpeg4, etc...),
- * not file formats (avi, vob, etc...). See library 'libavformat' for the
- * format handling
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef HAVE_AV_CONFIG_H
-#undef HAVE_AV_CONFIG_H
-#endif
-
-#include "libavcodec/avcodec.h"
-#include "libavutil/audioconvert.h"
-#include "libavutil/common.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/samplefmt.h"
-
-#define INBUF_SIZE 4096
-#define AUDIO_INBUF_SIZE 20480
-#define AUDIO_REFILL_THRESH 4096
-
-/* check that a given sample format is supported by the encoder */
-static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
-{
-    const enum AVSampleFormat *p = codec->sample_fmts;
-
-    while (*p != AV_SAMPLE_FMT_NONE) {
-        if (*p == sample_fmt)
-            return 1;
-        p++;
-    }
-    return 0;
-}
-
-/* just pick the highest supported samplerate */
-static int select_sample_rate(AVCodec *codec)
-{
-    const int *p;
-    int best_samplerate = 0;
-
-    if (!codec->supported_samplerates)
-        return 44100;
-
-    p = codec->supported_samplerates;
-    while (*p) {
-        best_samplerate = FFMAX(*p, best_samplerate);
-        p++;
-    }
-    return best_samplerate;
-}
-
-/* select layout with the highest channel count */
-static int select_channel_layout(AVCodec *codec)
-{
-    const uint64_t *p;
-    uint64_t best_ch_layout = 0;
-    int best_nb_channells   = 0;
-
-    if (!codec->channel_layouts)
-        return AV_CH_LAYOUT_STEREO;
-
-    p = codec->channel_layouts;
-    while (*p) {
-        int nb_channels = av_get_channel_layout_nb_channels(*p);
-
-        if (nb_channels > best_nb_channells) {
-            best_ch_layout    = *p;
-            best_nb_channells = nb_channels;
-        }
-        p++;
-    }
-    return best_ch_layout;
-}
-
-/*
- * Audio encoding example
- */
-static void audio_encode_example(const char *filename)
-{
-    AVCodec *codec;
-    AVCodecContext *c= NULL;
-    AVFrame *frame;
-    AVPacket pkt;
-    int i, j, k, ret, got_output;
-    int buffer_size;
-    FILE *f;
-    uint16_t *samples;
-    float t, tincr;
-
-    printf("Audio encoding\n");
-
-    /* find the MP2 encoder */
-    codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
-    if (!codec) {
-        fprintf(stderr, "codec not found\n");
-        exit(1);
-    }
-
-    c = avcodec_alloc_context3(codec);
-
-    /* put sample parameters */
-    c->bit_rate = 64000;
-
-    /* check that the encoder supports s16 pcm input */
-    c->sample_fmt = AV_SAMPLE_FMT_S16;
-    if (!check_sample_fmt(codec, c->sample_fmt)) {
-        fprintf(stderr, "encoder does not support %s",
-                av_get_sample_fmt_name(c->sample_fmt));
-        exit(1);
-    }
-
-    /* select other audio parameters supported by the encoder */
-    c->sample_rate    = select_sample_rate(codec);
-    c->channel_layout = select_channel_layout(codec);
-    c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);
-
-    /* open it */
-    if (avcodec_open2(c, codec, NULL) < 0) {
-        fprintf(stderr, "could not open codec\n");
-        exit(1);
-    }
-
-    f = fopen(filename, "wb");
-    if (!f) {
-        fprintf(stderr, "could not open %s\n", filename);
-        exit(1);
-    }
-
-    /* frame containing input raw audio */
-    frame = avcodec_alloc_frame();
-    if (!frame) {
-        fprintf(stderr, "could not allocate audio frame\n");
-        exit(1);
-    }
-
-    frame->nb_samples     = c->frame_size;
-    frame->format         = c->sample_fmt;
-    frame->channel_layout = c->channel_layout;
-
-    /* the codec gives us the frame size, in samples,
-     * we calculate the size of the samples buffer in bytes */
-    buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
-                                             c->sample_fmt, 0);
-    samples = av_malloc(buffer_size);
-    if (!samples) {
-        fprintf(stderr, "could not allocate %d bytes for samples buffer\n",
-                buffer_size);
-        exit(1);
-    }
-    /* setup the data pointers in the AVFrame */
-    ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
-                                   (const uint8_t*)samples, buffer_size, 0);
-    if (ret < 0) {
-        fprintf(stderr, "could not setup audio frame\n");
-        exit(1);
-    }
-
-    /* encode a single tone sound */
-    t = 0;
-    tincr = 2 * M_PI * 440.0 / c->sample_rate;
-    for(i=0;i<200;i++) {
-        av_init_packet(&pkt);
-        pkt.data = NULL; // packet data will be allocated by the encoder
-        pkt.size = 0;
-
-        for (j = 0; j < c->frame_size; j++) {
-            samples[2*j] = (int)(sin(t) * 10000);
-
-            for (k = 1; k < c->channels; k++)
-                samples[2*j + k] = samples[2*j];
-            t += tincr;
-        }
-        /* encode the samples */
-        ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
-        if (ret < 0) {
-            fprintf(stderr, "error encoding audio frame\n");
-            exit(1);
-        }
-        if (got_output) {
-            fwrite(pkt.data, 1, pkt.size, f);
-            av_free_packet(&pkt);
-        }
-    }
-    fclose(f);
-
-    av_freep(&samples);
-    avcodec_free_frame(&frame);
-    avcodec_close(c);
-    av_free(c);
-}
-
-/*
- * Audio decoding.
- */
-static void audio_decode_example(const char *outfilename, const char *filename)
-{
-    AVCodec *codec;
-    AVCodecContext *c= NULL;
-    int len;
-    FILE *f, *outfile;
-    uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
-    AVPacket avpkt;
-    AVFrame *decoded_frame = NULL;
-
-    av_init_packet(&avpkt);
-
-    printf("Audio decoding\n");
-
-    /* find the mpeg audio decoder */
-    codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
-    if (!codec) {
-        fprintf(stderr, "codec not found\n");
-        exit(1);
-    }
-
-    c = avcodec_alloc_context3(codec);
-
-    /* open it */
-    if (avcodec_open2(c, codec, NULL) < 0) {
-        fprintf(stderr, "could not open codec\n");
-        exit(1);
-    }
-
-    f = fopen(filename, "rb");
-    if (!f) {
-        fprintf(stderr, "could not open %s\n", filename);
-        exit(1);
-    }
-    outfile = fopen(outfilename, "wb");
-    if (!outfile) {
-        av_free(c);
-        exit(1);
-    }
-
-    /* decode until eof */
-    avpkt.data = inbuf;
-    avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
-
-    while (avpkt.size > 0) {
-        int got_frame = 0;
-
-        if (!decoded_frame) {
-            if (!(decoded_frame = avcodec_alloc_frame())) {
-                fprintf(stderr, "out of memory\n");
-                exit(1);
-            }
-        } else
-            avcodec_get_frame_defaults(decoded_frame);
-
-        len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
-        if (len < 0) {
-            fprintf(stderr, "Error while decoding\n");
-            exit(1);
-        }
-        if (got_frame) {
-            /* if a frame has been decoded, output it */
-            int data_size = av_samples_get_buffer_size(NULL, c->channels,
-                                                       decoded_frame->nb_samples,
-                                                       c->sample_fmt, 1);
-            fwrite(decoded_frame->data[0], 1, data_size, outfile);
-        }
-        avpkt.size -= len;
-        avpkt.data += len;
-        if (avpkt.size < AUDIO_REFILL_THRESH) {
-            /* Refill the input buffer, to avoid trying to decode
-             * incomplete frames. Instead of this, one could also use
-             * a parser, or use a proper container format through
-             * libavformat. */
-            memmove(inbuf, avpkt.data, avpkt.size);
-            avpkt.data = inbuf;
-            len = fread(avpkt.data + avpkt.size, 1,
-                        AUDIO_INBUF_SIZE - avpkt.size, f);
-            if (len > 0)
-                avpkt.size += len;
-        }
-    }
-
-    fclose(outfile);
-    fclose(f);
-
-    avcodec_close(c);
-    av_free(c);
-    avcodec_free_frame(&decoded_frame);
-}
-
-/*
- * Video encoding example
- */
-static void video_encode_example(const char *filename)
-{
-    AVCodec *codec;
-    AVCodecContext *c= NULL;
-    int i, ret, x, y, got_output;
-    FILE *f;
-    AVFrame *picture;
-    AVPacket pkt;
-    uint8_t endcode[] = { 0, 0, 1, 0xb7 };
-
-    printf("Video encoding\n");
-
-    /* find the mpeg1 video encoder */
-    codec = avcodec_find_encoder(AV_CODEC_ID_MPEG1VIDEO);
-    if (!codec) {
-        fprintf(stderr, "codec not found\n");
-        exit(1);
-    }
-
-    c = avcodec_alloc_context3(codec);
-    picture= avcodec_alloc_frame();
-
-    /* put sample parameters */
-    c->bit_rate = 400000;
-    /* resolution must be a multiple of two */
-    c->width = 352;
-    c->height = 288;
-    /* frames per second */
-    c->time_base= (AVRational){1,25};
-    c->gop_size = 10; /* emit one intra frame every ten frames */
-    c->max_b_frames=1;
-    c->pix_fmt = AV_PIX_FMT_YUV420P;
-
-    /* open it */
-    if (avcodec_open2(c, codec, NULL) < 0) {
-        fprintf(stderr, "could not open codec\n");
-        exit(1);
-    }
-
-    f = fopen(filename, "wb");
-    if (!f) {
-        fprintf(stderr, "could not open %s\n", filename);
-        exit(1);
-    }
-
-    ret = av_image_alloc(picture->data, picture->linesize, c->width, c->height,
-                         c->pix_fmt, 32);
-    if (ret < 0) {
-        fprintf(stderr, "could not alloc raw picture buffer\n");
-        exit(1);
-    }
-    picture->format = c->pix_fmt;
-    picture->width  = c->width;
-    picture->height = c->height;
-
-    /* encode 1 second of video */
-    for(i=0;i<25;i++) {
-        av_init_packet(&pkt);
-        pkt.data = NULL;    // packet data will be allocated by the encoder
-        pkt.size = 0;
-
-        fflush(stdout);
-        /* prepare a dummy image */
-        /* Y */
-        for(y=0;y<c->height;y++) {
-            for(x=0;x<c->width;x++) {
-                picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
-            }
-        }
-
-        /* Cb and Cr */
-        for(y=0;y<c->height/2;y++) {
-            for(x=0;x<c->width/2;x++) {
-                picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
-                picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
-            }
-        }
-
-        picture->pts = i;
-
-        /* encode the image */
-        ret = avcodec_encode_video2(c, &pkt, picture, &got_output);
-        if (ret < 0) {
-            fprintf(stderr, "error encoding frame\n");
-            exit(1);
-        }
-
-        if (got_output) {
-            printf("encoding frame %3d (size=%5d)\n", i, pkt.size);
-            fwrite(pkt.data, 1, pkt.size, f);
-            av_free_packet(&pkt);
-        }
-    }
-
-    /* get the delayed frames */
-    for (got_output = 1; got_output; i++) {
-        fflush(stdout);
-
-        ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
-        if (ret < 0) {
-            fprintf(stderr, "error encoding frame\n");
-            exit(1);
-        }
-
-        if (got_output) {
-            printf("encoding frame %3d (size=%5d)\n", i, pkt.size);
-            fwrite(pkt.data, 1, pkt.size, f);
-            av_free_packet(&pkt);
-        }
-    }
-
-    /* add sequence end code to have a real mpeg file */
-    fwrite(endcode, 1, sizeof(endcode), f);
-    fclose(f);
-
-    avcodec_close(c);
-    av_free(c);
-    av_freep(&picture->data[0]);
-    avcodec_free_frame(&picture);
-    printf("\n");
-}
-
-/*
- * Video decoding example
- */
-
-static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
-                     char *filename)
-{
-    FILE *f;
-    int i;
-
-    f=fopen(filename,"w");
-    fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
-    for(i=0;i<ysize;i++)
-        fwrite(buf + i * wrap,1,xsize,f);
-    fclose(f);
-}
-
-static void video_decode_example(const char *outfilename, const char *filename)
-{
-    AVCodec *codec;
-    AVCodecContext *c= NULL;
-    int frame, got_picture, len;
-    FILE *f;
-    AVFrame *picture;
-    uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
-    char buf[1024];
-    AVPacket avpkt;
-
-    av_init_packet(&avpkt);
-
-    /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
-    memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-
-    printf("Video decoding\n");
-
-    /* find the mpeg1 video decoder */
-    codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
-    if (!codec) {
-        fprintf(stderr, "codec not found\n");
-        exit(1);
-    }
-
-    c = avcodec_alloc_context3(codec);
-    picture= avcodec_alloc_frame();
-
-    if(codec->capabilities&CODEC_CAP_TRUNCATED)
-        c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
-
-    /* For some codecs, such as msmpeg4 and mpeg4, width and height
-       MUST be initialized there because this information is not
-       available in the bitstream. */
-
-    /* open it */
-    if (avcodec_open2(c, codec, NULL) < 0) {
-        fprintf(stderr, "could not open codec\n");
-        exit(1);
-    }
-
-    /* the codec gives us the frame size, in samples */
-
-    f = fopen(filename, "rb");
-    if (!f) {
-        fprintf(stderr, "could not open %s\n", filename);
-        exit(1);
-    }
-
-    frame = 0;
-    for(;;) {
-        avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
-        if (avpkt.size == 0)
-            break;
-
-        /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
-           and this is the only method to use them because you cannot
-           know the compressed data size before analysing it.
-
-           BUT some other codecs (msmpeg4, mpeg4) are inherently frame
-           based, so you must call them with all the data for one
-           frame exactly. You must also initialize 'width' and
-           'height' before initializing them. */
-
-        /* NOTE2: some codecs allow the raw parameters (frame size,
-           sample rate) to be changed at any frame. We handle this, so
-           you should also take care of it */
-
-        /* here, we use a stream based decoder (mpeg1video), so we
-           feed decoder and see if it could decode a frame */
-        avpkt.data = inbuf;
-        while (avpkt.size > 0) {
-            len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
-            if (len < 0) {
-                fprintf(stderr, "Error while decoding frame %d\n", frame);
-                exit(1);
-            }
-            if (got_picture) {
-                printf("saving frame %3d\n", frame);
-                fflush(stdout);
-
-                /* the picture is allocated by the decoder. no need to
-                   free it */
-                snprintf(buf, sizeof(buf), outfilename, frame);
-                pgm_save(picture->data[0], picture->linesize[0],
-                         c->width, c->height, buf);
-                frame++;
-            }
-            avpkt.size -= len;
-            avpkt.data += len;
-        }
-    }
-
-    /* some codecs, such as MPEG, transmit the I and P frame with a
-       latency of one frame. You must do the following to have a
-       chance to get the last frame of the video */
-    avpkt.data = NULL;
-    avpkt.size = 0;
-    len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
-    if (got_picture) {
-        printf("saving last frame %3d\n", frame);
-        fflush(stdout);
-
-        /* the picture is allocated by the decoder. no need to
-           free it */
-        snprintf(buf, sizeof(buf), outfilename, frame);
-        pgm_save(picture->data[0], picture->linesize[0],
-                 c->width, c->height, buf);
-        frame++;
-    }
-
-    fclose(f);
-
-    avcodec_close(c);
-    av_free(c);
-    avcodec_free_frame(&picture);
-    printf("\n");
-}
-
-int main(int argc, char **argv)
-{
-    const char *filename;
-
-    /* register all the codecs */
-    avcodec_register_all();
-
-    if (argc <= 1) {
-        audio_encode_example("/tmp/test.mp2");
-        audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");
-
-        video_encode_example("/tmp/test.mpg");
-        filename = "/tmp/test.mpg";
-    } else {
-        filename = argv[1];
-    }
-
-    //    audio_decode_example("/tmp/test.sw", filename);
-    video_decode_example("/tmp/test%d.pgm", filename);
-
-    return 0;
-}
diff --git a/libavcodec/arm/aac.h b/libavcodec/arm/aac.h
index 83b5aef..bd4d293 100644
--- a/libavcodec/arm/aac.h
+++ b/libavcodec/arm/aac.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/ac3dsp_init_arm.c b/libavcodec/arm/ac3dsp_init_arm.c
index d7cb95b..ffe0747 100644
--- a/libavcodec/arm/ac3dsp_init_arm.c
+++ b/libavcodec/arm/ac3dsp_init_arm.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2011 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -31,6 +31,14 @@
 void ff_ac3_rshift_int32_neon(int32_t *src, unsigned len, unsigned shift);
 void ff_float_to_fixed24_neon(int32_t *dst, const float *src, unsigned int len);
 void ff_ac3_extract_exponents_neon(uint8_t *exp, int32_t *coef, int nb_coefs);
+void ff_ac3_sum_square_butterfly_int32_neon(int64_t sum[4],
+                                            const int32_t *coef0,
+                                            const int32_t *coef1,
+                                            int len);
+void ff_ac3_sum_square_butterfly_float_neon(float sum[4],
+                                            const float *coef0,
+                                            const float *coef1,
+                                            int len);
 
 void ff_ac3_bit_alloc_calc_bap_armv6(int16_t *mask, int16_t *psd,
                                      int start, int end,
@@ -56,5 +64,7 @@
         c->ac3_rshift_int32      = ff_ac3_rshift_int32_neon;
         c->float_to_fixed24      = ff_float_to_fixed24_neon;
         c->extract_exponents     = ff_ac3_extract_exponents_neon;
+        c->sum_square_butterfly_int32 = ff_ac3_sum_square_butterfly_int32_neon;
+        c->sum_square_butterfly_float = ff_ac3_sum_square_butterfly_float_neon;
     }
 }
diff --git a/libavcodec/arm/ac3dsp_neon.S b/libavcodec/arm/ac3dsp_neon.S
index 82ff8af..42f35e3 100644
--- a/libavcodec/arm/ac3dsp_neon.S
+++ b/libavcodec/arm/ac3dsp_neon.S
@@ -108,3 +108,47 @@
         bgt             1b
         bx              lr
 endfunc
+
+function ff_ac3_sum_square_butterfly_int32_neon, export=1
+        vmov.i64        q0,  #0
+        vmov.i64        q1,  #0
+        vmov.i64        q2,  #0
+        vmov.i64        q3,  #0
+1:
+        vld1.32         {d16},    [r1]!
+        vld1.32         {d17},    [r2]!
+        vadd.s32        d18, d16, d17
+        vsub.s32        d19, d16, d17
+        vmlal.s32       q0,  d16, d16
+        vmlal.s32       q1,  d17, d17
+        vmlal.s32       q2,  d18, d18
+        vmlal.s32       q3,  d19, d19
+        subs            r3,  r3,  #2
+        bgt             1b
+        vadd.s64        d0,  d0,  d1
+        vadd.s64        d1,  d2,  d3
+        vadd.s64        d2,  d4,  d5
+        vadd.s64        d3,  d6,  d7
+        vst1.64         {q0-q1},  [r0]
+        bx              lr
+endfunc
+
+function ff_ac3_sum_square_butterfly_float_neon, export=1
+        vmov.f32        q0,  #0.0
+        vmov.f32        q1,  #0.0
+1:
+        vld1.32         {d16},    [r1]!
+        vld1.32         {d17},    [r2]!
+        vadd.f32        d18, d16, d17
+        vsub.f32        d19, d16, d17
+        vmla.f32        d0,  d16, d16
+        vmla.f32        d1,  d17, d17
+        vmla.f32        d2,  d18, d18
+        vmla.f32        d3,  d19, d19
+        subs            r3,  r3,  #2
+        bgt             1b
+        vpadd.f32       d0,  d0,  d1
+        vpadd.f32       d1,  d2,  d3
+        vst1.32         {q0},     [r0]
+        bx              lr
+endfunc
diff --git a/libavcodec/arm/asm-offsets.h b/libavcodec/arm/asm-offsets.h
index 8999456..5cfc5cb 100644
--- a/libavcodec/arm/asm-offsets.h
+++ b/libavcodec/arm/asm-offsets.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Mans Rullgard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/dca.h b/libavcodec/arm/dca.h
index 9b0efc0..05be789 100644
--- a/libavcodec/arm/dca.h
+++ b/libavcodec/arm/dca.h
@@ -25,7 +25,7 @@
 #include "config.h"
 #include "libavutil/intmath.h"
 
-#if HAVE_ARMV6 && HAVE_INLINE_ASM && AV_GCC_VERSION_AT_LEAST(4,4)
+#if HAVE_ARMV6 && HAVE_INLINE_ASM && 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,
diff --git a/libavcodec/arm/dcadsp_init_arm.c b/libavcodec/arm/dcadsp_init_arm.c
index f0375c9..56568e0 100644
--- a/libavcodec/arm/dcadsp_init_arm.c
+++ b/libavcodec/arm/dcadsp_init_arm.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/dcadsp_neon.S b/libavcodec/arm/dcadsp_neon.S
index fe3aae8..6a6c77a 100644
--- a/libavcodec/arm/dcadsp_neon.S
+++ b/libavcodec/arm/dcadsp_neon.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/dsputil_arm.S b/libavcodec/arm/dsputil_arm.S
index 78d7ad8..d665ab3 100644
--- a/libavcodec/arm/dsputil_arm.S
+++ b/libavcodec/arm/dsputil_arm.S
@@ -2,20 +2,20 @@
 @ ARMv4 optimized DSP utils
 @ Copyright (c) 2004 AGAWA Koji <i (AT) atty (DOT) jp>
 @
-@ This file is part of Libav.
+@ This file is part of FFmpeg.
 @
-@ Libav is free software; you can redistribute it and/or
+@ FFmpeg is free software; you can redistribute it and/or
 @ modify it under the terms of the GNU Lesser General Public
 @ License as published by the Free Software Foundation; either
 @ version 2.1 of the License, or (at your option) any later version.
 @
-@ Libav is distributed in the hope that it will be useful,
+@ FFmpeg is distributed in the hope that it will be useful,
 @ but WITHOUT ANY WARRANTY; without even the implied warranty of
 @ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 @ Lesser General Public License for more details.
 @
 @ You should have received a copy of the GNU Lesser General Public
-@ License along with Libav; if not, write to the Free Software
+@ License along with FFmpeg; if not, write to the Free Software
 @ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 @
 
diff --git a/libavcodec/arm/dsputil_arm.h b/libavcodec/arm/dsputil_arm.h
index 36d5d56..b7b5bdc 100644
--- a/libavcodec/arm/dsputil_arm.h
+++ b/libavcodec/arm/dsputil_arm.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/dsputil_armv6.S b/libavcodec/arm/dsputil_armv6.S
index 61535a1..0c54b52 100644
--- a/libavcodec/arm/dsputil_armv6.S
+++ b/libavcodec/arm/dsputil_armv6.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/dsputil_init_arm.c b/libavcodec/arm/dsputil_init_arm.c
index 0c1563d..03df6b2 100644
--- a/libavcodec/arm/dsputil_init_arm.c
+++ b/libavcodec/arm/dsputil_init_arm.c
@@ -2,20 +2,20 @@
  * ARM optimized DSP utils
  * Copyright (c) 2001 Lionel Ulmer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -82,7 +82,7 @@
     ff_put_pixels_clamped = c->put_pixels_clamped;
     ff_add_pixels_clamped = c->add_pixels_clamped;
 
-    if (avctx->bits_per_raw_sample <= 8) {
+    if (!avctx->lowres && avctx->bits_per_raw_sample <= 8) {
         if(avctx->idct_algo == FF_IDCT_AUTO ||
            avctx->idct_algo == FF_IDCT_ARM){
             c->idct_put              = j_rev_dct_arm_put;
diff --git a/libavcodec/arm/dsputil_init_armv5te.c b/libavcodec/arm/dsputil_init_armv5te.c
index f37ffc3..9fedb7a 100644
--- a/libavcodec/arm/dsputil_init_armv5te.c
+++ b/libavcodec/arm/dsputil_init_armv5te.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,7 +29,7 @@
 
 av_cold void ff_dsputil_init_armv5te(DSPContext *c, AVCodecContext *avctx)
 {
-    if (avctx->bits_per_raw_sample <= 8 &&
+    if (!avctx->lowres && avctx->bits_per_raw_sample <= 8 &&
         (avctx->idct_algo == FF_IDCT_AUTO ||
          avctx->idct_algo == FF_IDCT_SIMPLEARMV5TE)) {
         c->idct_put              = ff_simple_idct_put_armv5te;
diff --git a/libavcodec/arm/dsputil_init_armv6.c b/libavcodec/arm/dsputil_init_armv6.c
index fbe6014..1081135 100644
--- a/libavcodec/arm/dsputil_init_armv6.c
+++ b/libavcodec/arm/dsputil_init_armv6.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -47,7 +47,7 @@
 void ff_avg_pixels8_armv6(uint8_t *, const uint8_t *, int, int);
 
 void ff_add_pixels_clamped_armv6(const DCTELEM *block,
-                                 uint8_t *restrict pixels,
+                                 uint8_t *av_restrict pixels,
                                  int line_size);
 
 void ff_get_pixels_armv6(DCTELEM *block, const uint8_t *pixels, int stride);
@@ -74,7 +74,7 @@
 {
     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
-    if (avctx->bits_per_raw_sample <= 8 &&
+    if (!avctx->lowres && avctx->bits_per_raw_sample <= 8 &&
         (avctx->idct_algo == FF_IDCT_AUTO ||
          avctx->idct_algo == FF_IDCT_SIMPLEARMV6)) {
         c->idct_put              = ff_simple_idct_put_armv6;
diff --git a/libavcodec/arm/dsputil_init_neon.c b/libavcodec/arm/dsputil_init_neon.c
index a132f6f..5533a28 100644
--- a/libavcodec/arm/dsputil_init_neon.c
+++ b/libavcodec/arm/dsputil_init_neon.c
@@ -2,20 +2,20 @@
  * ARM NEON optimised DSP functions
  * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -171,7 +171,7 @@
 {
     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
 
-    if (avctx->bits_per_raw_sample <= 8) {
+    if (!avctx->lowres && avctx->bits_per_raw_sample <= 8) {
         if (avctx->idct_algo == FF_IDCT_AUTO ||
             avctx->idct_algo == FF_IDCT_SIMPLENEON) {
             c->idct_put              = ff_simple_idct_put_neon;
diff --git a/libavcodec/arm/dsputil_init_vfp.c b/libavcodec/arm/dsputil_init_vfp.c
index d77d686..5713c71 100644
--- a/libavcodec/arm/dsputil_init_vfp.c
+++ b/libavcodec/arm/dsputil_init_vfp.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/dsputil_neon.S b/libavcodec/arm/dsputil_neon.S
index ca1d2de..e4bd03e 100644
--- a/libavcodec/arm/dsputil_neon.S
+++ b/libavcodec/arm/dsputil_neon.S
@@ -2,20 +2,20 @@
  * ARM NEON optimised DSP functions
  * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/dsputil_vfp.S b/libavcodec/arm/dsputil_vfp.S
index 9df955d..63ba766 100644
--- a/libavcodec/arm/dsputil_vfp.S
+++ b/libavcodec/arm/dsputil_vfp.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/fft_fixed_init_arm.c b/libavcodec/arm/fft_fixed_init_arm.c
index 5601ba1..7cf8a6e 100644
--- a/libavcodec/arm/fft_fixed_init_arm.c
+++ b/libavcodec/arm/fft_fixed_init_arm.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/fft_fixed_neon.S b/libavcodec/arm/fft_fixed_neon.S
index faddc00..fa33eac 100644
--- a/libavcodec/arm/fft_fixed_neon.S
+++ b/libavcodec/arm/fft_fixed_neon.S
@@ -122,7 +122,7 @@
 
 function fft_pass_neon
         push            {r4,lr}
-        movrel          lr,  coefs + 24
+        movrel          lr,  coefs+24
         vld1.16         {d30},    [lr,:64]
         lsl             r12, r2,  #3
         vmov            d31, d30
diff --git a/libavcodec/arm/fft_init_arm.c b/libavcodec/arm/fft_init_arm.c
index 9ec620f..12d28a3 100644
--- a/libavcodec/arm/fft_init_arm.c
+++ b/libavcodec/arm/fft_init_arm.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/fft_neon.S b/libavcodec/arm/fft_neon.S
index c4d8918..8b9ae2a 100644
--- a/libavcodec/arm/fft_neon.S
+++ b/libavcodec/arm/fft_neon.S
@@ -7,20 +7,20 @@
  * This algorithm (though not any of the implementation details) is
  * based on libdjbfft by D. J. Bernstein.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/flacdsp_arm.S b/libavcodec/arm/flacdsp_arm.S
index d4441da..f8861c5 100644
--- a/libavcodec/arm/flacdsp_arm.S
+++ b/libavcodec/arm/flacdsp_arm.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2012 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/flacdsp_init_arm.c b/libavcodec/arm/flacdsp_init_arm.c
index 0530cf7..9b93942 100644
--- a/libavcodec/arm/flacdsp_init_arm.c
+++ b/libavcodec/arm/flacdsp_init_arm.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2012 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/fmtconvert_init_arm.c b/libavcodec/arm/fmtconvert_init_arm.c
index 9435263..5b3e3c1 100644
--- a/libavcodec/arm/fmtconvert_init_arm.c
+++ b/libavcodec/arm/fmtconvert_init_arm.c
@@ -1,20 +1,20 @@
 /*
  * ARM optimized Format Conversion Utils
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/fmtconvert_neon.S b/libavcodec/arm/fmtconvert_neon.S
index 41a095a..55d070e 100644
--- a/libavcodec/arm/fmtconvert_neon.S
+++ b/libavcodec/arm/fmtconvert_neon.S
@@ -2,20 +2,20 @@
  * ARM NEON optimised Format Conversion Utils
  * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/fmtconvert_vfp.S b/libavcodec/arm/fmtconvert_vfp.S
index 8aeec2a..4bdbe82 100644
--- a/libavcodec/arm/fmtconvert_vfp.S
+++ b/libavcodec/arm/fmtconvert_vfp.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/h264dsp_init_arm.c b/libavcodec/arm/h264dsp_init_arm.c
index b4277a5..f150a45 100644
--- a/libavcodec/arm/h264dsp_init_arm.c
+++ b/libavcodec/arm/h264dsp_init_arm.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -70,11 +70,14 @@
 
 static void ff_h264dsp_init_neon(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
 {
+#if HAVE_NEON
     if (bit_depth == 8) {
     c->h264_v_loop_filter_luma   = ff_h264_v_loop_filter_luma_neon;
     c->h264_h_loop_filter_luma   = ff_h264_h_loop_filter_luma_neon;
+    if(chroma_format_idc == 1){
     c->h264_v_loop_filter_chroma = ff_h264_v_loop_filter_chroma_neon;
     c->h264_h_loop_filter_chroma = ff_h264_h_loop_filter_chroma_neon;
+    }
 
     c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels_16_neon;
     c->weight_h264_pixels_tab[1] = ff_weight_h264_pixels_8_neon;
@@ -94,6 +97,7 @@
     c->h264_idct8_dc_add    = ff_h264_idct8_dc_add_neon;
     c->h264_idct8_add4      = ff_h264_idct8_add4_neon;
     }
+#endif // HAVE_NEON
 }
 
 void ff_h264dsp_init_arm(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
diff --git a/libavcodec/arm/h264dsp_neon.S b/libavcodec/arm/h264dsp_neon.S
index 9daabe0..be0d2ec 100644
--- a/libavcodec/arm/h264dsp_neon.S
+++ b/libavcodec/arm/h264dsp_neon.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/h264idct_neon.S b/libavcodec/arm/h264idct_neon.S
index b23ddb1..1b349ce 100644
--- a/libavcodec/arm/h264idct_neon.S
+++ b/libavcodec/arm/h264idct_neon.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/h264pred_init_arm.c b/libavcodec/arm/h264pred_init_arm.c
index 371b1a6..bd2ed0a 100644
--- a/libavcodec/arm/h264pred_init_arm.c
+++ b/libavcodec/arm/h264pred_init_arm.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -45,11 +45,12 @@
 
 static 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;
 
     if (high_depth)
         return;
-
+    if(chroma_format_idc == 1){
     h->pred8x8[VERT_PRED8x8     ] = ff_pred8x8_vert_neon;
     h->pred8x8[HOR_PRED8x8      ] = ff_pred8x8_hor_neon;
     if (codec_id != AV_CODEC_ID_VP8)
@@ -64,6 +65,7 @@
         h->pred8x8[ALZHEIMER_DC_L00_PRED8x8] = ff_pred8x8_l00_dc_neon;
         h->pred8x8[ALZHEIMER_DC_0L0_PRED8x8] = ff_pred8x8_0l0_dc_neon;
     }
+    }
 
     h->pred16x16[DC_PRED8x8     ] = ff_pred16x16_dc_neon;
     h->pred16x16[VERT_PRED8x8   ] = ff_pred16x16_vert_neon;
@@ -73,6 +75,7 @@
     h->pred16x16[DC_128_PRED8x8 ] = ff_pred16x16_128_dc_neon;
     if (codec_id != AV_CODEC_ID_SVQ3 && codec_id != AV_CODEC_ID_RV40 && codec_id != AV_CODEC_ID_VP8)
         h->pred16x16[PLANE_PRED8x8  ] = ff_pred16x16_plane_neon;
+#endif // HAVE_NEON
 }
 
 void ff_h264_pred_init_arm(H264PredContext *h, int codec_id, int bit_depth, const int chroma_format_idc)
diff --git a/libavcodec/arm/h264pred_neon.S b/libavcodec/arm/h264pred_neon.S
index 332f94b..4dc47ba 100644
--- a/libavcodec/arm/h264pred_neon.S
+++ b/libavcodec/arm/h264pred_neon.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/int_neon.S b/libavcodec/arm/int_neon.S
index 04208c2..6b28a97 100644
--- a/libavcodec/arm/int_neon.S
+++ b/libavcodec/arm/int_neon.S
@@ -2,20 +2,20 @@
  * ARM NEON optimised integer operations
  * Copyright (c) 2009 Kostya Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/mathops.h b/libavcodec/arm/mathops.h
index 17a687d..9313d6b 100644
--- a/libavcodec/arm/mathops.h
+++ b/libavcodec/arm/mathops.h
@@ -2,20 +2,20 @@
  * simple math operations
  * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/mdct_neon.S b/libavcodec/arm/mdct_neon.S
index 9f7cb46..e481cd1 100644
--- a/libavcodec/arm/mdct_neon.S
+++ b/libavcodec/arm/mdct_neon.S
@@ -2,20 +2,20 @@
  * ARM NEON optimised MDCT
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/mpegvideo_arm.c b/libavcodec/arm/mpegvideo_arm.c
index cce90c7..28838bb 100644
--- a/libavcodec/arm/mpegvideo_arm.c
+++ b/libavcodec/arm/mpegvideo_arm.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2002 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/mpegvideo_arm.h b/libavcodec/arm/mpegvideo_arm.h
index d69fa2f..4ff93b7 100644
--- a/libavcodec/arm/mpegvideo_arm.h
+++ b/libavcodec/arm/mpegvideo_arm.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/mpegvideo_armv5te.c b/libavcodec/arm/mpegvideo_armv5te.c
index f6839dd..842620b 100644
--- a/libavcodec/arm/mpegvideo_armv5te.c
+++ b/libavcodec/arm/mpegvideo_armv5te.c
@@ -2,23 +2,24 @@
  * Optimization of some functions from mpegvideo.c for armv5te
  * Copyright (c) 2007 Siarhei Siamashka <ssvb@users.sourceforge.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/avassert.h"
 #include "libavcodec/avcodec.h"
 #include "libavcodec/dsputil.h"
 #include "libavcodec/mpegvideo.h"
@@ -55,7 +56,7 @@
     int level, qmul, qadd;
     int nCoeffs;
 
-    assert(s->block_last_index[n]>=0);
+    av_assert2(s->block_last_index[n]>=0);
 
     qmul = qscale << 1;
 
@@ -84,7 +85,7 @@
     int qmul, qadd;
     int nCoeffs;
 
-    assert(s->block_last_index[n]>=0);
+    av_assert2(s->block_last_index[n]>=0);
 
     qadd = (qscale - 1) | 1;
     qmul = qscale << 1;
diff --git a/libavcodec/arm/mpegvideo_armv5te_s.S b/libavcodec/arm/mpegvideo_armv5te_s.S
index 4426e15..8687d6b 100644
--- a/libavcodec/arm/mpegvideo_armv5te_s.S
+++ b/libavcodec/arm/mpegvideo_armv5te_s.S
@@ -2,20 +2,20 @@
  * Optimization of some functions from mpegvideo.c for armv5te
  * Copyright (c) 2007 Siarhei Siamashka <ssvb@users.sourceforge.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/mpegvideo_neon.S b/libavcodec/arm/mpegvideo_neon.S
index 0c6c428..e05df8e 100644
--- a/libavcodec/arm/mpegvideo_neon.S
+++ b/libavcodec/arm/mpegvideo_neon.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Mans Rullgard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/rdft_neon.S b/libavcodec/arm/rdft_neon.S
index 7d01d53..781d976 100644
--- a/libavcodec/arm/rdft_neon.S
+++ b/libavcodec/arm/rdft_neon.S
@@ -2,20 +2,20 @@
  * ARM NEON optimised RDFT
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/rv34dsp_init_arm.c b/libavcodec/arm/rv34dsp_init_arm.c
index 07f5598..60ab82e 100644
--- a/libavcodec/arm/rv34dsp_init_arm.c
+++ b/libavcodec/arm/rv34dsp_init_arm.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2011 Janne Grunau <janne-libav@jannau.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/rv40dsp_init_arm.c b/libavcodec/arm/rv40dsp_init_arm.c
index 83f4355..1f9364a 100644
--- a/libavcodec/arm/rv40dsp_init_arm.c
+++ b/libavcodec/arm/rv40dsp_init_arm.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2011 Janne Grunau <janne-libav@jannau.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/simple_idct_arm.S b/libavcodec/arm/simple_idct_arm.S
index 8ba6c48..dd1c815 100644
--- a/libavcodec/arm/simple_idct_arm.S
+++ b/libavcodec/arm/simple_idct_arm.S
@@ -4,22 +4,22 @@
  * Author: Frederic Boulay <dilb@handhelds.org>
  *
  * The function defined in this file is derived from the simple_idct function
- * from the libavcodec library part of the Libav project.
+ * from the libavcodec library part of the FFmpeg project.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/simple_idct_armv5te.S b/libavcodec/arm/simple_idct_armv5te.S
index bf509ee..d1f10b7 100644
--- a/libavcodec/arm/simple_idct_armv5te.S
+++ b/libavcodec/arm/simple_idct_armv5te.S
@@ -4,20 +4,20 @@
  * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2006 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/simple_idct_armv6.S b/libavcodec/arm/simple_idct_armv6.S
index 0342b06..0c19d26 100644
--- a/libavcodec/arm/simple_idct_armv6.S
+++ b/libavcodec/arm/simple_idct_armv6.S
@@ -4,20 +4,20 @@
  * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2007 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/simple_idct_neon.S b/libavcodec/arm/simple_idct_neon.S
index b3e97d5..a8fc137 100644
--- a/libavcodec/arm/simple_idct_neon.S
+++ b/libavcodec/arm/simple_idct_neon.S
@@ -6,20 +6,20 @@
  * Based on Simple IDCT
  * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/synth_filter_neon.S b/libavcodec/arm/synth_filter_neon.S
index 62bb667..5417be7 100644
--- a/libavcodec/arm/synth_filter_neon.S
+++ b/libavcodec/arm/synth_filter_neon.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/vp3dsp_init_arm.c b/libavcodec/arm/vp3dsp_init_arm.c
index ea99bfd..90fc34b 100644
--- a/libavcodec/arm/vp3dsp_init_arm.c
+++ b/libavcodec/arm/vp3dsp_init_arm.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/vp3dsp_neon.S b/libavcodec/arm/vp3dsp_neon.S
index e09de57..0c88562 100644
--- a/libavcodec/arm/vp3dsp_neon.S
+++ b/libavcodec/arm/vp3dsp_neon.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 David Conrad
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/vp56_arith.h b/libavcodec/arm/vp56_arith.h
index d1a8837..29a2228 100644
--- a/libavcodec/arm/vp56_arith.h
+++ b/libavcodec/arm/vp56_arith.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2010 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/vp56dsp_init_arm.c b/libavcodec/arm/vp56dsp_init_arm.c
index afa5070..1304653 100644
--- a/libavcodec/arm/vp56dsp_init_arm.c
+++ b/libavcodec/arm/vp56dsp_init_arm.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/vp56dsp_neon.S b/libavcodec/arm/vp56dsp_neon.S
index 10b4d0f..03dd28d 100644
--- a/libavcodec/arm/vp56dsp_neon.S
+++ b/libavcodec/arm/vp56dsp_neon.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/vp8.h b/libavcodec/arm/vp8.h
index fc6523e..5a7b142 100644
--- a/libavcodec/arm/vp8.h
+++ b/libavcodec/arm/vp8.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/vp8_armv6.S b/libavcodec/arm/vp8_armv6.S
index 3863dc3..e7d25a4 100644
--- a/libavcodec/arm/vp8_armv6.S
+++ b/libavcodec/arm/vp8_armv6.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2010 Mans Rullgard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/vp8dsp_init_arm.c b/libavcodec/arm/vp8dsp_init_arm.c
index 603f68c..5c84ed3 100644
--- a/libavcodec/arm/vp8dsp_init_arm.c
+++ b/libavcodec/arm/vp8dsp_init_arm.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/arm/vp8dsp_neon.S b/libavcodec/arm/vp8dsp_neon.S
index 0cd2efa..04e7c5c 100644
--- a/libavcodec/arm/vp8dsp_neon.S
+++ b/libavcodec/arm/vp8dsp_neon.S
@@ -4,20 +4,20 @@
  * Copyright (c) 2010 Rob Clark <rob@ti.com>
  * Copyright (c) 2011 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ass.c b/libavcodec/ass.c
index 3585b93..db0fdd8 100644
--- a/libavcodec/ass.c
+++ b/libavcodec/ass.c
@@ -1,53 +1,37 @@
 /*
- * SSA/ASS common funtions
+ * SSA/ASS common functions
  * Copyright (c) 2010  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "avcodec.h"
 #include "ass.h"
+#include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/common.h"
 
-/**
- * Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS.
- *
- * @param avctx pointer to the AVCodecContext
- * @param font name of the default font face to use
- * @param font_size default font size to use
- * @param color default text color to use (ABGR)
- * @param back_color default background color to use (ABGR)
- * @param bold 1 for bold text, 0 for normal text
- * @param italic 1 for italic text, 0 for normal text
- * @param underline 1 for underline text, 0 for normal text
- * @param alignment position of the text (left, center, top...), defined after
- *                  the layout of the numpad (1-3 sub, 4-6 mid, 7-9 top)
- * @return >= 0 on success otherwise an error code <0
- */
-static int ff_ass_subtitle_header(AVCodecContext *avctx,
-                                  const char *font, int font_size,
-                                  int color, int back_color,
-                                  int bold, int italic, int underline,
-                                  int alignment)
+int ff_ass_subtitle_header(AVCodecContext *avctx,
+                           const char *font, int font_size,
+                           int color, int back_color,
+                           int bold, int italic, int underline,
+                           int alignment)
 {
-    char header[512];
-
-    snprintf(header, sizeof(header),
+    avctx->subtitle_header = av_asprintf(
              "[Script Info]\r\n"
              "ScriptType: v4.00+\r\n"
              "\r\n"
@@ -56,11 +40,10 @@
              "Style: Default,%s,%d,&H%x,&H%x,&H%x,&H%x,%d,%d,%d,1,1,0,%d,10,10,10,0,0\r\n"
              "\r\n"
              "[Events]\r\n"
-             "Format: Layer, Start, End, Text\r\n",
+             "Format: Layer, Start, End, Style, Text\r\n",
              font, font_size, color, color, back_color, back_color,
              -bold, -italic, -underline, alignment);
 
-    avctx->subtitle_header = av_strdup(header);
     if (!avctx->subtitle_header)
         return AVERROR(ENOMEM);
     avctx->subtitle_header_size = strlen(avctx->subtitle_header);
@@ -79,11 +62,6 @@
                                          ASS_DEFAULT_ALIGNMENT);
 }
 
-void ff_ass_init(AVSubtitle *sub)
-{
-    memset(sub, 0, sizeof(*sub));
-}
-
 static int ts_to_string(char *str, int strlen, int ts)
 {
     int h, m, s;
@@ -94,17 +72,21 @@
 }
 
 int ff_ass_add_rect(AVSubtitle *sub, const char *dialog,
-                    int ts_start, int ts_end, int raw)
+                    int ts_start, int duration, int raw)
 {
-    int len = 0, dlen, duration = ts_end - ts_start;
+    int len = 0, dlen;
     char s_start[16], s_end[16], header[48] = {0};
     AVSubtitleRect **rects;
 
     if (!raw) {
         ts_to_string(s_start, sizeof(s_start), ts_start);
-        ts_to_string(s_end,   sizeof(s_end),   ts_end  );
-        len = snprintf(header, sizeof(header), "Dialogue: 0,%s,%s,",
+        if (duration == -1)
+            snprintf(s_end, sizeof(s_end), "9:59:59.99");
+        else
+            ts_to_string(s_end, sizeof(s_end), ts_start + duration);
+        len = snprintf(header, sizeof(header), "Dialogue: 0,%s,%s,Default,",
                        s_start, s_end);
+        av_assert0(len < sizeof(header));
     }
 
     dlen = strcspn(dialog, "\n");
diff --git a/libavcodec/ass.h b/libavcodec/ass.h
index 594b5f3..e9339e4 100644
--- a/libavcodec/ass.h
+++ b/libavcodec/ass.h
@@ -1,21 +1,21 @@
 /*
- * SSA/ASS common funtions
+ * SSA/ASS common functions
  * Copyright (c) 2010  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -39,6 +39,27 @@
 /** @} */
 
 /**
+ * Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS.
+ *
+ * @param avctx pointer to the AVCodecContext
+ * @param font name of the default font face to use
+ * @param font_size default font size to use
+ * @param color default text color to use (ABGR)
+ * @param back_color default background color to use (ABGR)
+ * @param bold 1 for bold text, 0 for normal text
+ * @param italic 1 for italic text, 0 for normal text
+ * @param underline 1 for underline text, 0 for normal text
+ * @param alignment position of the text (left, center, top...), defined after
+ *                  the layout of the numpad (1-3 sub, 4-6 mid, 7-9 top)
+ * @return >= 0 on success otherwise an error code <0
+ */
+int ff_ass_subtitle_header(AVCodecContext *avctx,
+                           const char *font, int font_size,
+                           int color, int back_color,
+                           int bold, int italic, int underline,
+                           int alignment);
+
+/**
  * Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS
  * with default style.
  *
@@ -48,19 +69,13 @@
 int ff_ass_subtitle_header_default(AVCodecContext *avctx);
 
 /**
- * Initialize an AVSubtitle structure for use with ff_ass_add_rect().
- *
- * @param sub pointer to the AVSubtitle
- */
-void ff_ass_init(AVSubtitle *sub);
-
-/**
  * Add an ASS dialog line to an AVSubtitle as a new AVSubtitleRect.
  *
  * @param sub pointer to the AVSubtitle
  * @param dialog ASS dialog to add to sub
  * @param ts_start start timestamp for this dialog (in 1/100 second unit)
- * @param ts_end end timestamp for this dialog (in 1/100 second unit)
+ * @param duration duration for this dialog (in 1/100 second unit), can be -1
+ *                 to last until the end of the presentation
  * @param raw when set to 1, it indicates that dialog contains a whole ASS
  *                           dialog line which should be copied as is.
  *            when set to 0, it indicates that dialog contains only the Text
@@ -71,6 +86,6 @@
  *         A negative value indicates an error.
  */
 int ff_ass_add_rect(AVSubtitle *sub, const char *dialog,
-                    int ts_start, int ts_end, int raw);
+                    int ts_start, int duration, int raw);
 
 #endif /* AVCODEC_ASS_H */
diff --git a/libavcodec/ass_split.c b/libavcodec/ass_split.c
new file mode 100644
index 0000000..7ee48b4
--- /dev/null
+++ b/libavcodec/ass_split.c
@@ -0,0 +1,470 @@
+/*
+ * SSA/ASS spliting functions
+ * Copyright (c) 2010  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
+ */
+
+#include "avcodec.h"
+#include "ass_split.h"
+
+typedef enum {
+    ASS_STR,
+    ASS_INT,
+    ASS_FLT,
+    ASS_COLOR,
+    ASS_TIMESTAMP,
+    ASS_ALGN,
+} ASSFieldType;
+
+typedef struct {
+    const char *name;
+    int type;
+    int offset;
+} ASSFields;
+
+typedef struct {
+    const char *section;
+    const char *format_header;
+    const char *fields_header;
+    int         size;
+    int         offset;
+    int         offset_count;
+    ASSFields   fields[10];
+} ASSSection;
+
+static const ASSSection ass_sections[] = {
+    { .section       = "Script Info",
+      .offset        = offsetof(ASS, script_info),
+      .fields = {{"ScriptType", ASS_STR, offsetof(ASSScriptInfo, script_type)},
+                 {"Collisions", ASS_STR, offsetof(ASSScriptInfo, collisions) },
+                 {"PlayResX",   ASS_INT, offsetof(ASSScriptInfo, play_res_x) },
+                 {"PlayResY",   ASS_INT, offsetof(ASSScriptInfo, play_res_y) },
+                 {"Timer",      ASS_FLT, offsetof(ASSScriptInfo, timer)      },
+                 {0},
+        }
+    },
+    { .section       = "V4+ Styles",
+      .format_header = "Format",
+      .fields_header = "Style",
+      .size          = sizeof(ASSStyle),
+      .offset        = offsetof(ASS, styles),
+      .offset_count  = offsetof(ASS, styles_count),
+      .fields = {{"Name",         ASS_STR,  offsetof(ASSStyle, name)         },
+                 {"Fontname",     ASS_STR,  offsetof(ASSStyle, font_name)    },
+                 {"Fontsize",     ASS_INT,  offsetof(ASSStyle, font_size)    },
+                 {"PrimaryColour",ASS_COLOR,offsetof(ASSStyle, primary_color)},
+                 {"BackColour",   ASS_COLOR,offsetof(ASSStyle, back_color)   },
+                 {"Bold",         ASS_INT,  offsetof(ASSStyle, bold)         },
+                 {"Italic",       ASS_INT,  offsetof(ASSStyle, italic)       },
+                 {"Underline",    ASS_INT,  offsetof(ASSStyle, underline)    },
+                 {"Alignment",    ASS_INT,  offsetof(ASSStyle, alignment)    },
+                 {0},
+        }
+    },
+    { .section       = "V4 Styles",
+      .format_header = "Format",
+      .fields_header = "Style",
+      .size          = sizeof(ASSStyle),
+      .offset        = offsetof(ASS, styles),
+      .offset_count  = offsetof(ASS, styles_count),
+      .fields = {{"Name",         ASS_STR,  offsetof(ASSStyle, name)         },
+                 {"Fontname",     ASS_STR,  offsetof(ASSStyle, font_name)    },
+                 {"Fontsize",     ASS_INT,  offsetof(ASSStyle, font_size)    },
+                 {"PrimaryColour",ASS_COLOR,offsetof(ASSStyle, primary_color)},
+                 {"BackColour",   ASS_COLOR,offsetof(ASSStyle, back_color)   },
+                 {"Bold",         ASS_INT,  offsetof(ASSStyle, bold)         },
+                 {"Italic",       ASS_INT,  offsetof(ASSStyle, italic)       },
+                 {"Alignment",    ASS_ALGN, offsetof(ASSStyle, alignment)    },
+                 {0},
+        }
+    },
+    { .section       = "Events",
+      .format_header = "Format",
+      .fields_header = "Dialogue",
+      .size          = sizeof(ASSDialog),
+      .offset        = offsetof(ASS, dialogs),
+      .offset_count  = offsetof(ASS, dialogs_count),
+      .fields = {{"Layer",  ASS_INT,        offsetof(ASSDialog, layer)       },
+                 {"Start",  ASS_TIMESTAMP,  offsetof(ASSDialog, start)       },
+                 {"End",    ASS_TIMESTAMP,  offsetof(ASSDialog, end)         },
+                 {"Style",  ASS_STR,        offsetof(ASSDialog, style)       },
+                 {"Text",   ASS_STR,        offsetof(ASSDialog, text)        },
+                 {0},
+        }
+    },
+};
+
+
+typedef int (*ASSConvertFunc)(void *dest, const char *buf, int len);
+
+static int convert_str(void *dest, const char *buf, int len)
+{
+    char *str = av_malloc(len + 1);
+    if (str) {
+        memcpy(str, buf, len);
+        str[len] = 0;
+        if (*(void **)dest)
+            av_free(*(void **)dest);
+        *(char **)dest = str;
+    }
+    return !str;
+}
+static int convert_int(void *dest, const char *buf, int len)
+{
+    return sscanf(buf, "%d", (int *)dest) == 1;
+}
+static int convert_flt(void *dest, const char *buf, int len)
+{
+    return sscanf(buf, "%f", (float *)dest) == 1;
+}
+static int convert_color(void *dest, const char *buf, int len)
+{
+    return sscanf(buf, "&H%8x", (int *)dest) == 1 ||
+           sscanf(buf, "%d",    (int *)dest) == 1;
+}
+static int convert_timestamp(void *dest, const char *buf, int len)
+{
+    int c, h, m, s, cs;
+    if ((c = sscanf(buf, "%d:%02d:%02d.%02d", &h, &m, &s, &cs)) == 4)
+        *(int *)dest = 360000*h + 6000*m + 100*s + cs;
+    return c == 4;
+}
+static int convert_alignment(void *dest, const char *buf, int len)
+{
+    int a;
+    if (sscanf(buf, "%d", &a) == 1) {
+        /* convert V4 Style alignment to V4+ Style */
+        *(int *)dest = a + ((a&4) >> 1) - 5*!!(a&8);
+        return 1;
+    }
+    return 0;
+}
+
+static const ASSConvertFunc convert_func[] = {
+    [ASS_STR]       = convert_str,
+    [ASS_INT]       = convert_int,
+    [ASS_FLT]       = convert_flt,
+    [ASS_COLOR]     = convert_color,
+    [ASS_TIMESTAMP] = convert_timestamp,
+    [ASS_ALGN]      = convert_alignment,
+};
+
+
+struct ASSSplitContext {
+    ASS ass;
+    int current_section;
+    int field_number[FF_ARRAY_ELEMS(ass_sections)];
+    int *field_order[FF_ARRAY_ELEMS(ass_sections)];
+};
+
+
+static uint8_t *realloc_section_array(ASSSplitContext *ctx)
+{
+    const ASSSection *section = &ass_sections[ctx->current_section];
+    int *count = (int *)((uint8_t *)&ctx->ass + section->offset_count);
+    void **section_ptr = (void **)((uint8_t *)&ctx->ass + section->offset);
+    uint8_t *tmp = av_realloc(*section_ptr, (*count+1)*section->size);
+    if (!tmp)
+        return NULL;
+    *section_ptr = tmp;
+    tmp += *count * section->size;
+    memset(tmp, 0, section->size);
+    (*count)++;
+    return tmp;
+}
+
+static inline int is_eol(char buf)
+{
+    return buf == '\r' || buf == '\n' || buf == 0;
+}
+
+static inline const char *skip_space(const char *buf)
+{
+    while (*buf == ' ')
+        buf++;
+    return buf;
+}
+
+static const char *ass_split_section(ASSSplitContext *ctx, const char *buf)
+{
+    const ASSSection *section = &ass_sections[ctx->current_section];
+    int *number = &ctx->field_number[ctx->current_section];
+    int *order = ctx->field_order[ctx->current_section];
+    int *tmp, i, len;
+
+    while (buf && *buf) {
+        if (buf[0] == '[') {
+            ctx->current_section = -1;
+            break;
+        }
+        if (buf[0] == ';' || (buf[0] == '!' && buf[1] == ':')) {
+            /* skip comments */
+        } else if (section->format_header && !order) {
+            len = strlen(section->format_header);
+            if (strncmp(buf, section->format_header, len) || buf[len] != ':')
+                return NULL;
+            buf += len + 1;
+            while (!is_eol(*buf)) {
+                buf = skip_space(buf);
+                len = strcspn(buf, ", \r\n");
+                if (!(tmp = av_realloc(order, (*number + 1) * sizeof(*order))))
+                    return NULL;
+                order = tmp;
+                order[*number] = -1;
+                for (i=0; section->fields[i].name; i++)
+                    if (!strncmp(buf, section->fields[i].name, len)) {
+                        order[*number] = i;
+                        break;
+                    }
+                (*number)++;
+                buf = skip_space(buf + len + (buf[len] == ','));
+            }
+            ctx->field_order[ctx->current_section] = order;
+        } else if (section->fields_header) {
+            len = strlen(section->fields_header);
+            if (!strncmp(buf, section->fields_header, len) && buf[len] == ':') {
+                uint8_t *ptr, *struct_ptr = realloc_section_array(ctx);
+                if (!struct_ptr)  return NULL;
+                buf += len + 1;
+                for (i=0; !is_eol(*buf) && i < *number; i++) {
+                    int last = i == *number - 1;
+                    buf = skip_space(buf);
+                    len = strcspn(buf, last ? "\r\n" : ",\r\n");
+                    if (order[i] >= 0) {
+                        ASSFieldType type = section->fields[order[i]].type;
+                        ptr = struct_ptr + section->fields[order[i]].offset;
+                        convert_func[type](ptr, buf, len);
+                    }
+                    buf = skip_space(buf + len + !last);
+                }
+            }
+        } else {
+            len = strcspn(buf, ":\r\n");
+            if (buf[len] == ':') {
+                for (i=0; section->fields[i].name; i++)
+                    if (!strncmp(buf, section->fields[i].name, len)) {
+                        ASSFieldType type = section->fields[i].type;
+                        uint8_t *ptr = (uint8_t *)&ctx->ass + section->offset;
+                        ptr += section->fields[i].offset;
+                        buf = skip_space(buf + len + 1);
+                        convert_func[type](ptr, buf, strcspn(buf, "\r\n"));
+                        break;
+                    }
+            }
+        }
+        buf += strcspn(buf, "\n") + 1;
+    }
+    return buf;
+}
+
+static int ass_split(ASSSplitContext *ctx, const char *buf)
+{
+    char c, section[16];
+    int i;
+
+    if (ctx->current_section >= 0)
+        buf = ass_split_section(ctx, buf);
+
+    while (buf && *buf) {
+        if (sscanf(buf, "[%15[0-9A-Za-z+ ]]%c", section, &c) == 2) {
+            buf += strcspn(buf, "\n") + 1;
+            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;
+    }
+    return buf ? 0 : AVERROR_INVALIDDATA;
+}
+
+ASSSplitContext *ff_ass_split(const char *buf)
+{
+    ASSSplitContext *ctx = av_mallocz(sizeof(*ctx));
+    ctx->current_section = -1;
+    if (ass_split(ctx, buf) < 0) {
+        ff_ass_split_free(ctx);
+        return NULL;
+    }
+    return ctx;
+}
+
+static void free_section(ASSSplitContext *ctx, const ASSSection *section)
+{
+    uint8_t *ptr = (uint8_t *)&ctx->ass + section->offset;
+    int i, j, *count, c = 1;
+
+    if (section->format_header) {
+        ptr   = *(void **)ptr;
+        count = (int *)((uint8_t *)&ctx->ass + section->offset_count);
+    } else
+        count = &c;
+
+    if (ptr)
+        for (i=0; i<*count; i++, ptr += section->size)
+            for (j=0; section->fields[j].name; j++) {
+                const ASSFields *field = &section->fields[j];
+                if (field->type == ASS_STR)
+                    av_freep(ptr + field->offset);
+            }
+    *count = 0;
+
+    if (section->format_header)
+        av_freep((uint8_t *)&ctx->ass + section->offset);
+}
+
+ASSDialog *ff_ass_split_dialog(ASSSplitContext *ctx, const char *buf,
+                               int cache, int *number)
+{
+    ASSDialog *dialog = NULL;
+    int i, count;
+    if (!cache)
+        for (i=0; i<FF_ARRAY_ELEMS(ass_sections); i++)
+            if (!strcmp(ass_sections[i].section, "Events")) {
+                free_section(ctx, &ass_sections[i]);
+                break;
+            }
+    count = ctx->ass.dialogs_count;
+    if (ass_split(ctx, buf) == 0)
+        dialog = ctx->ass.dialogs + count;
+    if (number)
+        *number = ctx->ass.dialogs_count - count;
+    return dialog;
+}
+
+void ff_ass_split_free(ASSSplitContext *ctx)
+{
+    if (ctx) {
+        int i;
+        for (i=0; i<FF_ARRAY_ELEMS(ass_sections); i++) {
+            free_section(ctx, &ass_sections[i]);
+            av_freep(&(ctx->field_order[i]));
+        }
+        av_free(ctx);
+    }
+}
+
+
+int ff_ass_split_override_codes(const ASSCodesCallbacks *callbacks, void *priv,
+                                const char *buf)
+{
+    const char *text = NULL;
+    char new_line[2];
+    int text_len = 0;
+
+    while (*buf) {
+        if (text && callbacks->text &&
+            (sscanf(buf, "\\%1[nN]", new_line) == 1 ||
+             !strncmp(buf, "{\\", 2))) {
+            callbacks->text(priv, text, text_len);
+            text = NULL;
+        }
+        if (sscanf(buf, "\\%1[nN]", new_line) == 1) {
+            if (callbacks->new_line)
+                callbacks->new_line(priv, new_line[0] == 'N');
+            buf += 2;
+        } else if (!strncmp(buf, "{\\", 2)) {
+            buf++;
+            while (*buf == '\\') {
+                char style[2], c[2], sep[2], c_num[2] = "0", tmp[128] = {0};
+                unsigned int color = 0xFFFFFFFF;
+                int len, size = -1, an = -1, alpha = -1;
+                int x1, y1, x2, y2, t1 = -1, t2 = -1;
+                if (sscanf(buf, "\\%1[bisu]%1[01\\}]%n", style, c, &len) > 1) {
+                    int close = c[0] == '0' ? 1 : c[0] == '1' ? 0 : -1;
+                    len += close != -1;
+                    if (callbacks->style)
+                        callbacks->style(priv, style[0], close);
+                } else if (sscanf(buf, "\\c%1[\\}]%n", sep, &len) > 0 ||
+                           sscanf(buf, "\\c&H%X&%1[\\}]%n", &color, sep, &len) > 1 ||
+                           sscanf(buf, "\\%1[1234]c%1[\\}]%n", c_num, sep, &len) > 1 ||
+                           sscanf(buf, "\\%1[1234]c&H%X&%1[\\}]%n", c_num, &color, sep, &len) > 2) {
+                    if (callbacks->color)
+                        callbacks->color(priv, color, c_num[0] - '0');
+                } else if (sscanf(buf, "\\alpha%1[\\}]%n", sep, &len) > 0 ||
+                           sscanf(buf, "\\alpha&H%2X&%1[\\}]%n", &alpha, sep, &len) > 1 ||
+                           sscanf(buf, "\\%1[1234]a%1[\\}]%n", c_num, sep, &len) > 1 ||
+                           sscanf(buf, "\\%1[1234]a&H%2X&%1[\\}]%n", c_num, &alpha, sep, &len) > 2) {
+                    if (callbacks->alpha)
+                        callbacks->alpha(priv, alpha, c_num[0] - '0');
+                } else if (sscanf(buf, "\\fn%1[\\}]%n", sep, &len) > 0 ||
+                           sscanf(buf, "\\fn%127[^\\}]%1[\\}]%n", tmp, sep, &len) > 1) {
+                    if (callbacks->font_name)
+                        callbacks->font_name(priv, tmp[0] ? tmp : NULL);
+                } else if (sscanf(buf, "\\fs%1[\\}]%n", sep, &len) > 0 ||
+                           sscanf(buf, "\\fs%u%1[\\}]%n", &size, sep, &len) > 1) {
+                    if (callbacks->font_size)
+                        callbacks->font_size(priv, size);
+                } else if (sscanf(buf, "\\a%1[\\}]%n", sep, &len) > 0 ||
+                           sscanf(buf, "\\a%2u%1[\\}]%n", &an, sep, &len) > 1 ||
+                           sscanf(buf, "\\an%1[\\}]%n", sep, &len) > 0 ||
+                           sscanf(buf, "\\an%1u%1[\\}]%n", &an, sep, &len) > 1) {
+                    if (an != -1 && buf[2] != 'n')
+                        an = (an&3) + (an&4 ? 6 : an&8 ? 3 : 0);
+                    if (callbacks->alignment)
+                        callbacks->alignment(priv, an);
+                } else if (sscanf(buf, "\\r%1[\\}]%n", sep, &len) > 0 ||
+                           sscanf(buf, "\\r%127[^\\}]%1[\\}]%n", tmp, sep, &len) > 1) {
+                    if (callbacks->cancel_overrides)
+                        callbacks->cancel_overrides(priv, tmp);
+                } else if (sscanf(buf, "\\move(%d,%d,%d,%d)%1[\\}]%n", &x1, &y1, &x2, &y2, sep, &len) > 4 ||
+                           sscanf(buf, "\\move(%d,%d,%d,%d,%d,%d)%1[\\}]%n", &x1, &y1, &x2, &y2, &t1, &t2, sep, &len) > 6) {
+                    if (callbacks->move)
+                        callbacks->move(priv, x1, y1, x2, y2, t1, t2);
+                } else if (sscanf(buf, "\\pos(%d,%d)%1[\\}]%n", &x1, &y1, sep, &len) > 2) {
+                    if (callbacks->move)
+                        callbacks->move(priv, x1, y1, x1, y1, -1, -1);
+                } else if (sscanf(buf, "\\org(%d,%d)%1[\\}]%n", &x1, &y1, sep, &len) > 2) {
+                    if (callbacks->origin)
+                        callbacks->origin(priv, x1, y1);
+                } else {
+                    len = strcspn(buf+1, "\\}") + 2;  /* skip unknown code */
+                }
+                buf += len - 1;
+            }
+            if (*buf++ != '}')
+                return AVERROR_INVALIDDATA;
+        } else {
+            if (!text) {
+                text = buf;
+                text_len = 1;
+            } else
+                text_len++;
+            buf++;
+        }
+    }
+    if (text && callbacks->text)
+        callbacks->text(priv, text, text_len);
+    if (callbacks->end)
+        callbacks->end(priv);
+    return 0;
+}
+
+ASSStyle *ff_ass_style_get(ASSSplitContext *ctx, const char *style)
+{
+    ASS *ass = &ctx->ass;
+    int i;
+
+    if (!style || !*style)
+        style = "Default";
+    for (i=0; i<ass->styles_count; i++)
+        if (!strcmp(ass->styles[i].name, style))
+            return ass->styles + i;
+    return NULL;
+}
diff --git a/libavcodec/ass_split.h b/libavcodec/ass_split.h
new file mode 100644
index 0000000..7a6a75e
--- /dev/null
+++ b/libavcodec/ass_split.h
@@ -0,0 +1,172 @@
+/*
+ * SSA/ASS spliting functions
+ * Copyright (c) 2010  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 AVCODEC_ASS_SPLIT_H
+#define AVCODEC_ASS_SPLIT_H
+
+/**
+ * fields extracted from the [Script Info] section
+ */
+typedef struct {
+    char *script_type;    /**< SSA script format version (eg. v4.00) */
+    char *collisions;     /**< how subtitles are moved to prevent collisions */
+    int   play_res_x;     /**< video width that ASS coords are referring to */
+    int   play_res_y;     /**< video height that ASS coords are referring to */
+    float timer;          /**< time multiplier to apply to SSA clock (in %) */
+} ASSScriptInfo;
+
+/**
+ * fields extracted from the [V4(+) Styles] section
+ */
+typedef struct {
+    char *name;           /**< name of the tyle (case sensitive) */
+    char *font_name;      /**< font face (case sensitive) */
+    int   font_size;      /**< font height */
+    int   primary_color;  /**< color that a subtitle will normally appear in */
+    int   back_color;     /**< color of the subtitle outline or shadow */
+    int   bold;           /**< whether text is bold (1) or not (0) */
+    int   italic;         /**< whether text is italic (1) or not (0) */
+    int   underline;      /**< whether text is underlined (1) or not (0) */
+    int   alignment;      /**< position of the text (left, center, top...),
+                               defined after the layout of the numpad
+                               (1-3 sub, 4-6 mid, 7-9 top) */
+} ASSStyle;
+
+/**
+ * fields extracted from the [Events] section
+ */
+typedef struct {
+    int   layer;    /**< higher numbered layers are drawn over lower numbered */
+    int   start;    /**< start time of the dialog in centiseconds */
+    int   end;      /**< end time of the dialog in centiseconds */
+    char *style;    /**< name of the ASSStyle to use with this dialog */
+    char *text;     /**< actual text which will be displayed as a subtitle,
+                         can include style override control codes (see
+                         ff_ass_split_override_codes()) */
+} ASSDialog;
+
+/**
+ * structure containing the whole split ASS data
+ */
+typedef struct {
+    ASSScriptInfo script_info;   /**< general information about the SSA script*/
+    ASSStyle     *styles;        /**< array of split out styles */
+    int           styles_count;  /**< number of ASSStyle in the styles array */
+    ASSDialog    *dialogs;       /**< array of split out dialogs */
+    int           dialogs_count; /**< number of ASSDialog in the dialogs array*/
+} ASS;
+
+/**
+ * This struct can be casted to ASS to access to the split data.
+ */
+typedef struct ASSSplitContext ASSSplitContext;
+
+/**
+ * Split a full ASS file or a ASS header from a string buffer and store
+ * the split structure in a newly allocated context.
+ *
+ * @param buf String containing the ASS formated data.
+ * @return Newly allocated struct containing split data.
+ */
+ASSSplitContext *ff_ass_split(const char *buf);
+
+/**
+ * Split one or several ASS "Dialogue" lines from a string buffer and store
+ * them in a already initialized context.
+ *
+ * @param ctx Context previously initialized by ff_ass_split().
+ * @param buf String containing the ASS "Dialogue" lines.
+ * @param cache Set to 1 to keep all the previously split ASSDialog in
+ *              the context, or set to 0 to free all the previously split
+ *              ASSDialog.
+ * @param number If not NULL, the pointed integer will be set to the number
+ *               of split ASSDialog.
+ * @return Pointer to the first split ASSDialog.
+ */
+ASSDialog *ff_ass_split_dialog(ASSSplitContext *ctx, const char *buf,
+                               int cache, int *number);
+
+/**
+ * Free all the memory allocated for an ASSSplitContext.
+ *
+ * @param ctx Context previously initialized by ff_ass_split().
+ */
+void ff_ass_split_free(ASSSplitContext *ctx);
+
+
+/**
+ * Set of callback functions corresponding to each override codes that can
+ * be encountered in a "Dialogue" Text field.
+ */
+typedef struct {
+    /**
+     * @defgroup ass_styles    ASS styles
+     * @{
+     */
+    void (*text)(void *priv, const char *text, int len);
+    void (*new_line)(void *priv, int forced);
+    void (*style)(void *priv, char style, int close);
+    void (*color)(void *priv, unsigned int color, unsigned int color_id);
+    void (*alpha)(void *priv, int alpha, int alpha_id);
+    void (*font_name)(void *priv, const char *name);
+    void (*font_size)(void *priv, int size);
+    void (*alignment)(void *priv, int alignment);
+    void (*cancel_overrides)(void *priv, const char *style);
+    /** @} */
+
+    /**
+     * @defgroup ass_functions    ASS functions
+     * @{
+     */
+    void (*move)(void *priv, int x1, int y1, int x2, int y2, int t1, int t2);
+    void (*origin)(void *priv, int x, int y);
+    /** @} */
+
+    /**
+     * @defgroup ass_end    end of Dialogue Event
+     * @{
+     */
+    void (*end)(void *priv);
+    /** @} */
+} ASSCodesCallbacks;
+
+/**
+ * Split override codes out of a ASS "Dialogue" Text field.
+ *
+ * @param callbacks Set of callback functions called for each override code
+ *                  encountered.
+ * @param priv Opaque pointer passed to the callback functions.
+ * @param buf The ASS "Dialogue" Text field to split.
+ * @return >= 0 on success otherwise an error code <0
+ */
+int ff_ass_split_override_codes(const ASSCodesCallbacks *callbacks, void *priv,
+                                const char *buf);
+
+/**
+ * Find an ASSStyle structure by its name.
+ *
+ * @param ctx Context previously initialized by ff_ass_split().
+ * @param style name of the style to search for.
+ * @return the ASSStyle corresponding to style, or NULL if style can't be found
+ */
+ASSStyle *ff_ass_style_get(ASSSplitContext *ctx, const char *style);
+
+#endif /* AVCODEC_ASS_SPLIT_H */
diff --git a/libavcodec/assdec.c b/libavcodec/assdec.c
index 7a69582..5a51703 100644
--- a/libavcodec/assdec.c
+++ b/libavcodec/assdec.c
@@ -2,20 +2,20 @@
  * SSA/ASS decoder
  * Copyright (c) 2010  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -23,16 +23,20 @@
 
 #include "avcodec.h"
 #include "ass.h"
+#include "ass_split.h"
 #include "libavutil/internal.h"
 #include "libavutil/mem.h"
 
 static av_cold int ass_decode_init(AVCodecContext *avctx)
 {
     avctx->subtitle_header = av_malloc(avctx->extradata_size);
-    if (!avctx->extradata)
+    if (!avctx->subtitle_header)
         return AVERROR(ENOMEM);
     memcpy(avctx->subtitle_header, avctx->extradata, avctx->extradata_size);
     avctx->subtitle_header_size = avctx->extradata_size;
+    avctx->priv_data = ff_ass_split(avctx->extradata);
+    if(!avctx->priv_data)
+        return -1;
     return 0;
 }
 
@@ -42,10 +46,13 @@
     const char *ptr = avpkt->data;
     int len, size = avpkt->size;
 
-    ff_ass_init(data);
-
     while (size > 0) {
-        len = ff_ass_add_rect(data, ptr, 0, 0/* FIXME: duration */, 1);
+        int duration;
+        ASSDialog *dialog = ff_ass_split_dialog(avctx->priv_data, ptr, 0, NULL);
+        if (!dialog)
+            return AVERROR_INVALIDDATA;
+        duration = dialog->end - dialog->start;
+        len = ff_ass_add_rect(data, ptr, 0, duration, 1);
         if (len < 0)
             return len;
         ptr  += len;
@@ -56,6 +63,13 @@
     return avpkt->size;
 }
 
+static int ass_decode_close(AVCodecContext *avctx)
+{
+    ff_ass_split_free(avctx->priv_data);
+    avctx->priv_data = NULL;
+    return 0;
+}
+
 AVCodec ff_ass_decoder = {
     .name         = "ass",
     .long_name    = NULL_IF_CONFIG_SMALL("SSA (SubStation Alpha) subtitle"),
@@ -63,4 +77,5 @@
     .id           = AV_CODEC_ID_SSA,
     .init         = ass_decode_init,
     .decode       = ass_decode_frame,
+    .close        = ass_decode_close,
 };
diff --git a/libavcodec/assenc.c b/libavcodec/assenc.c
index caf266e..7ed21ee 100644
--- a/libavcodec/assenc.c
+++ b/libavcodec/assenc.c
@@ -2,20 +2,20 @@
  * SSA/ASS encoder
  * Copyright (c) 2010  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/asv.c b/libavcodec/asv.c
index b15182d..34622b4 100644
--- a/libavcodec/asv.c
+++ b/libavcodec/asv.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/asv.h b/libavcodec/asv.h
index 3440f93..4a6c799 100644
--- a/libavcodec/asv.h
+++ b/libavcodec/asv.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/asvdec.c b/libavcodec/asvdec.c
index a546d24..b9686a2 100644
--- a/libavcodec/asvdec.c
+++ b/libavcodec/asvdec.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -33,9 +33,6 @@
 #include "mathops.h"
 #include "mpeg12data.h"
 
-//#undef NDEBUG
-//#include <assert.h>
-
 #define VLC_BITS 6
 #define ASV2_LEVEL_VLC_BITS 10
 
@@ -264,8 +261,7 @@
     ff_init_scantable(a->dsp.idct_permutation, &a->scantable, ff_asv_scantab);
     avctx->pix_fmt= AV_PIX_FMT_YUV420P;
 
-    a->inv_qscale= avctx->extradata[0];
-    if(a->inv_qscale == 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;
@@ -300,6 +296,7 @@
     return 0;
 }
 
+#if CONFIG_ASV1_DECODER
 AVCodec ff_asv1_decoder = {
     .name           = "asv1",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -311,7 +308,9 @@
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("ASUS V1"),
 };
+#endif
 
+#if CONFIG_ASV2_DECODER
 AVCodec ff_asv2_decoder = {
     .name           = "asv2",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -323,4 +322,5 @@
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("ASUS V2"),
 };
+#endif
 
diff --git a/libavcodec/asvenc.c b/libavcodec/asvenc.c
index 4ab9ddb..259cd68 100644
--- a/libavcodec/asvenc.c
+++ b/libavcodec/asvenc.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -28,6 +28,7 @@
 
 #include "asv.h"
 #include "avcodec.h"
+#include "internal.h"
 #include "mathops.h"
 #include "mpeg12data.h"
 
@@ -114,7 +115,7 @@
         if( (block[index + 1] = (block[index + 1]*a->q_intra_matrix[index + 1] + (1<<15))>>16) ) ccp |= 2;
         if( (block[index + 9] = (block[index + 9]*a->q_intra_matrix[index + 9] + (1<<15))>>16) ) ccp |= 1;
 
-        assert(i || ccp<8);
+        av_assert2(i || ccp<8);
         if(i) put_bits(&a->pb, ff_asv_ac_ccp_tab[ccp][1], ff_asv_ac_ccp_tab[ccp][0]);
         else  put_bits(&a->pb, ff_asv_dc_ccp_tab[ccp][1], ff_asv_dc_ccp_tab[ccp][0]);
 
@@ -179,12 +180,9 @@
     int size, ret;
     int mb_x, mb_y;
 
-    if (!pkt->data &&
-        (ret = av_new_packet(pkt, a->mb_height*a->mb_width*MAX_MB_SIZE +
-                                  FF_MIN_BUFFER_SIZE)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, a->mb_height*a->mb_width*MAX_MB_SIZE +
+                                  FF_MIN_BUFFER_SIZE)) < 0)
         return ret;
-    }
 
     init_put_bits(&a->pb, pkt->data, pkt->size);
 
diff --git a/libavcodec/atrac.c b/libavcodec/atrac.c
index a772e7d..cb2f7ba 100644
--- a/libavcodec/atrac.c
+++ b/libavcodec/atrac.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2006-2008 Maxim Poliakovski
  * Copyright (c) 2006-2008 Benjamin Larsson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/atrac.h b/libavcodec/atrac.h
index 39fb331..8607b01 100644
--- a/libavcodec/atrac.h
+++ b/libavcodec/atrac.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2009 Maxim Poliakovski
  * Copyright (c) 2009 Benjamin Larsson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c
index 7e78c73..86d371e 100644
--- a/libavcodec/atrac1.c
+++ b/libavcodec/atrac1.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2009 Maxim Poliakovski
  * Copyright (c) 2009 Benjamin Larsson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -243,7 +243,7 @@
                      */
                     spec[pos+i] = get_sbits(gb, word_len) * scale_factor * max_quant;
                 }
-            } else { /* word_len = 0 -> empty BFU, zero all specs in the emty BFU */
+            } else { /* word_len = 0 -> empty BFU, zero all specs in the empty BFU */
                 memset(&spec[pos], 0, num_specs * sizeof(float));
             }
         }
diff --git a/libavcodec/atrac1data.h b/libavcodec/atrac1data.h
index 7d5dbeb..ebebe4b 100644
--- a/libavcodec/atrac1data.h
+++ b/libavcodec/atrac1data.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2009 Maxim Poliakovski
  * Copyright (c) 2009 Benjamin Larsson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c
index 94b355a..b900882 100644
--- a/libavcodec/atrac3.c
+++ b/libavcodec/atrac3.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2006-2008 Maxim Poliakovski
  * Copyright (c) 2006-2008 Benjamin Larsson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -37,6 +37,7 @@
 #include <stdio.h>
 
 #include "libavutil/float_dsp.h"
+#include "libavutil/libm.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "bytestream.h"
@@ -607,7 +608,7 @@
                 }
                 break;
             default:
-                assert(0);
+                av_assert1(0);
         }
     }
 }
@@ -997,10 +998,10 @@
 
     /* Generate gain tables. */
     for (i=0 ; i<16 ; i++)
-        gain_tab1[i] = powf (2.0, (4 - i));
+        gain_tab1[i] = exp2f (4 - i);
 
     for (i=-15 ; i<16 ; i++)
-        gain_tab2[i+15] = powf (2.0, i * -0.125);
+        gain_tab2[i+15] = exp2f (i * -0.125);
 
     /* init the joint-stereo decoding data */
     q->weighting_delay[0] = 0;
diff --git a/libavcodec/atrac3data.h b/libavcodec/atrac3data.h
index 9076d3a..b5aa71f 100644
--- a/libavcodec/atrac3data.h
+++ b/libavcodec/atrac3data.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2006-2007 Maxim Poliakovski
  * Copyright (c) 2006-2007 Benjamin Larsson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/audio_frame_queue.c b/libavcodec/audio_frame_queue.c
index 80f3100..7db0091 100644
--- a/libavcodec/audio_frame_queue.c
+++ b/libavcodec/audio_frame_queue.c
@@ -2,109 +2,71 @@
  * Audio Frame Queue
  * Copyright (c) 2012 Justin Ruggles
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/common.h"
-#include "libavutil/mathematics.h"
-#include "internal.h"
 #include "audio_frame_queue.h"
+#include "internal.h"
+#include "libavutil/avassert.h"
 
 void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
 {
-    afq->avctx             = avctx;
-    afq->next_pts          = AV_NOPTS_VALUE;
+    afq->avctx = avctx;
     afq->remaining_delay   = avctx->delay;
     afq->remaining_samples = avctx->delay;
-    afq->frame_queue       = NULL;
-}
-
-static void delete_next_frame(AudioFrameQueue *afq)
-{
-    AudioFrame *f = afq->frame_queue;
-    if (f) {
-        afq->frame_queue = f->next;
-        f->next = NULL;
-        av_freep(&f);
-    }
+    afq->frame_count       = 0;
 }
 
 void ff_af_queue_close(AudioFrameQueue *afq)
 {
-    /* remove/free any remaining frames */
-    while (afq->frame_queue)
-        delete_next_frame(afq);
+    if(afq->frame_count)
+        av_log(afq->avctx, AV_LOG_WARNING, "%d frames left in que on closing\n", afq->frame_count);
+    av_freep(&afq->frames);
     memset(afq, 0, sizeof(*afq));
 }
 
-#ifdef DEBUG
-static void af_queue_log_state(AudioFrameQueue *afq)
-{
-    AudioFrame *f;
-    av_dlog(afq->avctx, "remaining delay   = %d\n", afq->remaining_delay);
-    av_dlog(afq->avctx, "remaining samples = %d\n", afq->remaining_samples);
-    av_dlog(afq->avctx, "frames:\n");
-    f = afq->frame_queue;
-    while (f) {
-        av_dlog(afq->avctx, "  [ pts=%9"PRId64" duration=%d ]\n",
-                f->pts, f->duration);
-        f = f->next;
-    }
-}
-#endif /* DEBUG */
-
 int ff_af_queue_add(AudioFrameQueue *afq, const AVFrame *f)
 {
-    AudioFrame *new_frame;
-    AudioFrame *queue_end = afq->frame_queue;
-
-    /* find the end of the queue */
-    while (queue_end && queue_end->next)
-        queue_end = queue_end->next;
-
-    /* allocate new frame queue entry */
-    if (!(new_frame = av_malloc(sizeof(*new_frame))))
+    AudioFrame *new = av_fast_realloc(afq->frames, &afq->frame_alloc, sizeof(*afq->frames)*(afq->frame_count+1));
+    if(!new)
         return AVERROR(ENOMEM);
+    afq->frames = new;
+    new += afq->frame_count;
 
     /* get frame parameters */
-    new_frame->next = NULL;
-    new_frame->duration = f->nb_samples;
+    new->duration = f->nb_samples;
+    new->duration += afq->remaining_delay;
     if (f->pts != AV_NOPTS_VALUE) {
-        new_frame->pts = av_rescale_q(f->pts,
+        new->pts = av_rescale_q(f->pts,
                                       afq->avctx->time_base,
                                       (AVRational){ 1, afq->avctx->sample_rate });
-        afq->next_pts = new_frame->pts + new_frame->duration;
+        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");
     } else {
-        new_frame->pts = AV_NOPTS_VALUE;
-        afq->next_pts  = AV_NOPTS_VALUE;
+        new->pts = AV_NOPTS_VALUE;
     }
-
-    /* add new frame to the end of the queue */
-    if (!queue_end)
-        afq->frame_queue = new_frame;
-    else
-        queue_end->next = new_frame;
+    afq->remaining_delay = 0;
 
     /* add frame sample count */
     afq->remaining_samples += f->nb_samples;
 
-#ifdef DEBUG
-    af_queue_log_state(afq);
-#endif
+    afq->frame_count++;
 
     return 0;
 }
@@ -114,50 +76,37 @@
 {
     int64_t out_pts = AV_NOPTS_VALUE;
     int removed_samples = 0;
+    int i;
 
-#ifdef DEBUG
-    af_queue_log_state(afq);
-#endif
+    if (afq->frame_count || afq->frame_alloc) {
+        if (afq->frames->pts != AV_NOPTS_VALUE)
+            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);
+    if (pts)
+        *pts = ff_samples_to_time_base(afq->avctx, out_pts);
 
-    /* get output pts from the next frame or generated pts */
-    if (afq->frame_queue) {
-        if (afq->frame_queue->pts != AV_NOPTS_VALUE)
-            out_pts = afq->frame_queue->pts - afq->remaining_delay;
-    } else {
-        if (afq->next_pts != AV_NOPTS_VALUE)
-            out_pts = afq->next_pts - afq->remaining_delay;
-    }
-    if (pts) {
-        if (out_pts != AV_NOPTS_VALUE)
-            *pts = ff_samples_to_time_base(afq->avctx, out_pts);
-        else
-            *pts = AV_NOPTS_VALUE;
-    }
-
-    /* if the delay is larger than the packet duration, we use up delay samples
-       for the output packet and leave all frames in the queue */
-    if (afq->remaining_delay >= nb_samples) {
-        removed_samples      += nb_samples;
-        afq->remaining_delay -= nb_samples;
-    }
-    /* remove frames from the queue until we have enough to cover the
-       requested number of samples or until the queue is empty */
-    while (removed_samples < nb_samples && afq->frame_queue) {
-        removed_samples += afq->frame_queue->duration;
-        delete_next_frame(afq);
+    for(i=0; nb_samples && i<afq->frame_count; i++){
+        int n= FFMIN(afq->frames[i].duration, nb_samples);
+        afq->frames[i].duration -= n;
+        nb_samples              -= n;
+        removed_samples         += n;
+        if(afq->frames[i].pts != AV_NOPTS_VALUE)
+            afq->frames[i].pts      += n;
     }
     afq->remaining_samples -= removed_samples;
+    i -= i && afq->frames[i-1].duration;
+    memmove(afq->frames, afq->frames + i, sizeof(*afq->frames) * (afq->frame_count - i));
+    afq->frame_count -= i;
 
-    /* if there are no frames left and we have room for more samples, use
-       any remaining delay samples */
-    if (removed_samples < nb_samples && afq->remaining_samples > 0) {
-        int add_samples = FFMIN(afq->remaining_samples,
-                                nb_samples - removed_samples);
-        removed_samples        += add_samples;
-        afq->remaining_samples -= add_samples;
+    if(nb_samples){
+        av_assert0(!afq->frame_count);
+        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);
     }
-    if (removed_samples > nb_samples)
-        av_log(afq->avctx, AV_LOG_WARNING, "frame_size is too large\n");
     if (duration)
         *duration = ff_samples_to_time_base(afq->avctx, removed_samples);
 }
diff --git a/libavcodec/audio_frame_queue.h b/libavcodec/audio_frame_queue.h
index 4a29770..7e98afe 100644
--- a/libavcodec/audio_frame_queue.h
+++ b/libavcodec/audio_frame_queue.h
@@ -27,15 +27,15 @@
 typedef struct AudioFrame {
     int64_t pts;
     int duration;
-    struct AudioFrame *next;
 } AudioFrame;
 
 typedef struct AudioFrameQueue {
     AVCodecContext *avctx;
-    int64_t next_pts;
     int remaining_delay;
     int remaining_samples;
-    AudioFrame *frame_queue;
+    AudioFrame *frames;
+    unsigned frame_count;
+    unsigned frame_alloc;
 } AudioFrameQueue;
 
 /**
diff --git a/libavcodec/audioconvert.c b/libavcodec/audioconvert.c
index 3714de7..5d8a348 100644
--- a/libavcodec/audioconvert.c
+++ b/libavcodec/audioconvert.c
@@ -2,20 +2,20 @@
  * audio conversion
  * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/audioconvert.h b/libavcodec/audioconvert.h
index a7b0baa..03b196b 100644
--- a/libavcodec/audioconvert.h
+++ b/libavcodec/audioconvert.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2008 Peter Ross
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/aura.c b/libavcodec/aura.c
index 9f91021..669ef48 100644
--- a/libavcodec/aura.c
+++ b/libavcodec/aura.c
@@ -1,20 +1,20 @@
 /*
  * Aura 2 decoder
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -40,6 +40,7 @@
     if (avctx->width & 0x3)
         return -1;
     avctx->pix_fmt = AV_PIX_FMT_YUV422P;
+    avcodec_get_frame_defaults(&s->frame);
 
     return 0;
 }
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 32a7dcb..3c3dad3 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -34,6 +34,7 @@
 #include "libavutil/log.h"
 #include "libavutil/pixfmt.h"
 #include "libavutil/rational.h"
+#include "libavutil/audioconvert.h"
 
 #include "libavcodec/version.h"
 /**
@@ -87,7 +88,8 @@
  *
  * If you add a codec ID to this list, add it so that
  * 1. no value of a existing codec ID changes (that would break ABI),
- * 2. it is as close as possible to similar codecs.
+ * 2. Give it a value which when taken as ASCII is recognized uniquely by a human as this specific codec.
+ *    This ensures that 2 forks can independently add AVCodecIDs without producing conflicts.
  *
  * After adding new codec IDs, do not forget to add an entry to the codec
  * descriptor list and bump libavcodec minor version.
@@ -265,6 +267,22 @@
     AV_CODEC_ID_MTS2,
     AV_CODEC_ID_CLLC,
     AV_CODEC_ID_MSS2,
+    AV_CODEC_ID_Y41P       = MKBETAG('Y','4','1','P'),
+    AV_CODEC_ID_ESCAPE130  = MKBETAG('E','1','3','0'),
+    AV_CODEC_ID_EXR        = MKBETAG('0','E','X','R'),
+    AV_CODEC_ID_AVRP       = MKBETAG('A','V','R','P'),
+
+    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'),
+    AV_CODEC_ID_TARGA_Y216 = MKBETAG('T','2','1','6'),
+    AV_CODEC_ID_V308       = MKBETAG('V','3','0','8'),
+    AV_CODEC_ID_V408       = MKBETAG('V','4','0','8'),
+    AV_CODEC_ID_YUV4       = MKBETAG('Y','U','V','4'),
+    AV_CODEC_ID_SANM       = MKBETAG('S','A','N','M'),
+    AV_CODEC_ID_PAF_VIDEO  = MKBETAG('P','A','F','V'),
+    AV_CODEC_ID_AVRN       = MKBETAG('A','V','R','n'),
+    AV_CODEC_ID_CPIA       = MKBETAG('C','P','I','A'),
 
     /* various PCM "codecs" */
     AV_CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
@@ -328,6 +346,7 @@
     AV_CODEC_ID_ADPCM_IMA_ISS,
     AV_CODEC_ID_ADPCM_G722,
     AV_CODEC_ID_ADPCM_IMA_APC,
+    AV_CODEC_ID_VIMA       = MKBETAG('V','I','M','A'),
 
     /* AMR */
     AV_CODEC_ID_AMR_NB = 0x12000,
@@ -405,7 +424,14 @@
     AV_CODEC_ID_RALF,
     AV_CODEC_ID_IAC,
     AV_CODEC_ID_ILBC,
-    AV_CODEC_ID_OPUS,
+    AV_CODEC_ID_OPUS_DEPRECATED,
+    AV_CODEC_ID_FFWAVESYNTH = MKBETAG('F','F','W','S'),
+    AV_CODEC_ID_8SVX_RAW    = MKBETAG('8','S','V','X'),
+    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'),
 
     /* subtitle codecs */
     AV_CODEC_ID_FIRST_SUBTITLE = 0x17000,          ///< A dummy ID pointing at the start of subtitle codecs.
@@ -418,10 +444,22 @@
     AV_CODEC_ID_HDMV_PGS_SUBTITLE,
     AV_CODEC_ID_DVB_TELETEXT,
     AV_CODEC_ID_SRT,
+    AV_CODEC_ID_MICRODVD   = MKBETAG('m','D','V','D'),
+    AV_CODEC_ID_EIA_608    = MKBETAG('c','6','0','8'),
+    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_SUBVIEWER  = MKBETAG('S','u','b','V'),
+    AV_CODEC_ID_SUBRIP     = MKBETAG('S','R','i','p'),
+    AV_CODEC_ID_WEBVTT     = MKBETAG('W','V','T','T'),
 
     /* 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.
     AV_CODEC_ID_TTF = 0x18000,
+    AV_CODEC_ID_BINTEXT    = MKBETAG('B','T','X','T'),
+    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_PROBE = 0x19000, ///< codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it
 
@@ -493,7 +531,7 @@
  * Note: If the first 23 bits of the additional bytes are not 0, then damaged
  * MPEG bitstreams could cause overread and segfault.
  */
-#define FF_INPUT_BUFFER_PADDING_SIZE 8
+#define FF_INPUT_BUFFER_PADDING_SIZE 16
 
 /**
  * @ingroup lavc_encoding
@@ -565,6 +603,7 @@
     AVCOL_SPC_YCOCG       = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
     AVCOL_SPC_NB             , ///< Not part of ABI
 };
+#define AVCOL_SPC_YCGCO AVCOL_SPC_YCOCG
 
 enum AVColorRange{
     AVCOL_RANGE_UNSPECIFIED = 0,
@@ -650,6 +689,7 @@
 #define CODEC_FLAG2_FAST          0x00000001 ///< Allow non spec compliant speedup tricks.
 #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!!!!
 #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.
@@ -657,6 +697,7 @@
 #define CODEC_FLAG2_SKIP_RD       0x00004000 ///< RD optimal MB level residual skipping
 #endif
 #define CODEC_FLAG2_CHUNKS        0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries.
+#define CODEC_FLAG2_SHOW_ALL      0x00400000 ///< Show all frames before the first keyframe
 
 /* Unsupported options :
  *              Syntax Arithmetic coding (SAC)
@@ -729,10 +770,12 @@
  * Codec should fill in channel configuration and samplerate instead of container
  */
 #define CODEC_CAP_CHANNEL_CONF     0x0400
+
 /**
  * Codec is able to deal with negative linesizes
  */
 #define CODEC_CAP_NEG_LINESIZES    0x0800
+
 /**
  * Codec supports frame-level multithreading.
  */
@@ -753,6 +796,14 @@
  * Audio encoder supports receiving a different number of samples in each call.
  */
 #define CODEC_CAP_VARIABLE_FRAME_SIZE 0x10000
+/**
+ * Codec is intra only.
+ */
+#define CODEC_CAP_INTRA_ONLY       0x40000000
+/**
+ * Codec is lossless.
+ */
+#define CODEC_CAP_LOSSLESS         0x80000000
 
 //The following defines may change, don't expect compatibility if you use them.
 #define MB_TYPE_INTRA4x4   0x0001
@@ -869,6 +920,27 @@
      * @endcode
      */
     AV_PKT_DATA_H263_MB_INFO,
+
+    /**
+     * Recommmends skipping the specified number of samples
+     * @code
+     * u32le number of samples to skip from start of this packet
+     * u32le number of samples to skip from end of this packet
+     * u8    reason for start skip
+     * u8    reason for end   skip (0=padding silence, 1=convergence)
+     * @endcode
+     */
+    AV_PKT_DATA_SKIP_SAMPLES=70,
+
+    /**
+     * An AV_PKT_DATA_JP_DUALMONO side data packet indicates that
+     * the packet may contain "dual mono" audio specific to Japanese DTV
+     * and if it is true, recommends only the selected channel to be used.
+     * @code
+     * u8    selected channels (0=mail/left, 1=sub/right, 2=both)
+     * @endcode
+     */
+    AV_PKT_DATA_JP_DUALMONO,
 };
 
 typedef struct AVPacket {
@@ -950,9 +1022,12 @@
 /**
  * Audio Video Frame.
  * New fields can be added to the end of AVFRAME with minor version
- * bumps. Removal, reordering and changes to existing fields require
+ * bumps. 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 libav*.
+ * sizeof(AVFrame) must not be used outside libavcodec.
  */
 typedef struct AVFrame {
 #define AV_NUM_DATA_POINTERS 8
@@ -1241,7 +1316,7 @@
     int64_t reordered_opaque;
 
     /**
-     * hardware accelerator private data (Libav-allocated)
+     * hardware accelerator private data (FFmpeg-allocated)
      * - encoding: unused
      * - decoding: Set by libavcodec
      */
@@ -1273,7 +1348,7 @@
      * Sample rate of the audio data.
      *
      * - encoding: unused
-     * - decoding: set by get_buffer()
+     * - decoding: read by user
      */
     int sample_rate;
 
@@ -1281,11 +1356,92 @@
      * Channel layout of the audio data.
      *
      * - encoding: unused
-     * - decoding: set by get_buffer()
+     * - decoding: read by user.
      */
     uint64_t channel_layout;
+
+    /**
+     * frame timestamp estimated using various heuristics, in stream time base
+     * Code outside libavcodec should access this field using:
+     * av_frame_get_best_effort_timestamp(frame)
+     * - encoding: unused
+     * - decoding: set by libavcodec, read by user.
+     */
+    int64_t best_effort_timestamp;
+
+    /**
+     * reordered pos from the last AVPacket that has been input into the decoder
+     * Code outside libavcodec should access this field using:
+     * av_frame_get_pkt_pos(frame)
+     * - encoding: unused
+     * - decoding: Read by user.
+     */
+    int64_t pkt_pos;
+
+    /**
+     * duration of the corresponding packet, expressed in
+     * AVStream->time_base units, 0 if unknown.
+     * Code outside libavcodec should access this field using:
+     * av_frame_get_pkt_duration(frame)
+     * - encoding: unused
+     * - decoding: Read by user.
+     */
+    int64_t pkt_duration;
+
+    /**
+     * metadata.
+     * Code outside libavcodec should access this field using:
+     * av_frame_get_metadata(frame)
+     * - encoding: Set by user.
+     * - decoding: Set by libavcodec.
+     */
+    AVDictionary *metadata;
+
+    /**
+     * decode error flags of the frame, set to a combination of
+     * FF_DECODE_ERROR_xxx flags if the decoder produced a frame, but there
+     * were errors during the decoding.
+     * Code outside libavcodec should access this field using:
+     * av_frame_get_decode_error_flags(frame)
+     * - encoding: unused
+     * - decoding: set by libavcodec, read by user.
+     */
+    int decode_error_flags;
+#define FF_DECODE_ERROR_INVALID_BITSTREAM   1
+#define FF_DECODE_ERROR_MISSING_REFERENCE   2
+
+    /**
+     * number of audio channels, only used for audio.
+     * Code outside libavcodec should access this field using:
+     * av_frame_get_channels(frame)
+     * - encoding: unused
+     * - decoding: Read by user.
+     */
+    int64_t channels;
 } AVFrame;
 
+/**
+ * Accessors for some AVFrame fields.
+ * The position of these field in the structure is not part of the ABI,
+ * they should not be accessed directly outside libavcodec.
+ */
+int64_t av_frame_get_best_effort_timestamp(const AVFrame *frame);
+void    av_frame_set_best_effort_timestamp(AVFrame *frame, int64_t val);
+int64_t av_frame_get_pkt_duration         (const AVFrame *frame);
+void    av_frame_set_pkt_duration         (AVFrame *frame, int64_t val);
+int64_t av_frame_get_pkt_pos              (const AVFrame *frame);
+void    av_frame_set_pkt_pos              (AVFrame *frame, int64_t val);
+int64_t av_frame_get_channel_layout       (const AVFrame *frame);
+void    av_frame_set_channel_layout       (AVFrame *frame, int64_t val);
+int     av_frame_get_channels             (const AVFrame *frame);
+void    av_frame_set_channels             (AVFrame *frame, int     val);
+int     av_frame_get_sample_rate          (const AVFrame *frame);
+void    av_frame_set_sample_rate          (AVFrame *frame, int     val);
+AVDictionary *av_frame_get_metadata       (const AVFrame *frame);
+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);
+
 struct AVCodecInternal;
 
 enum AVFieldOrder {
@@ -1302,6 +1458,8 @@
  * New fields can be added to the end with minor version bumps.
  * Removal, reordering and changes to existing fields require a major
  * version bump.
+ * Please use AVOptions (av_opt* / av_set/get*()) to access these fields from user
+ * applications.
  * sizeof(AVCodecContext) must not be used outside libav*.
  */
 typedef struct AVCodecContext {
@@ -1442,7 +1600,10 @@
     int ticks_per_frame;
 
     /**
-     * Encoder delay.
+     * Encoding: Number of frames delay there will be from the encoder input to
+     *           the decoder output. (we assume the decoder matches the spec)
+     * Decoding: Number of frames delay in addition to what a standard decoder
+     *           as specified in the spec would produce.
      *
      * Video:
      *   Number of frames the decoded output will be delayed relative to the
@@ -1476,7 +1637,7 @@
     int width, height;
 
     /**
-     * Bitstream width / height, may be different from width/height.
+     * Bitstream width / height, may be different from width/height if lowres enabled.
      * - encoding: unused
      * - decoding: Set by user before init if known. Codec should override / dynamically change if needed.
      */
@@ -1494,7 +1655,7 @@
     /**
      * Pixel format, see AV_PIX_FMT_xxx.
      * May be set by the demuxer if known from headers.
-     * May be overriden by the decoder if it knows better.
+     * May be overridden by the decoder if it knows better.
      * - encoding: Set by user.
      * - decoding: Set by user if known, overridden by libavcodec if known
      */
@@ -2064,7 +2225,7 @@
 
     /** Field order
      * - encoding: set by libavcodec
-     * - decoding: Set by libavcodec
+     * - decoding: Set by user.
      */
     enum AVFieldOrder field_order;
 
@@ -2122,7 +2283,7 @@
     /**
      * Audio channel layout.
      * - encoding: set by user.
-     * - decoding: set by libavcodec.
+     * - decoding: set by user, may be overwritten by libavcodec.
      */
     uint64_t channel_layout;
 
@@ -2141,9 +2302,10 @@
     enum AVAudioServiceType audio_service_type;
 
     /**
-     * Used to request a sample format from the decoder.
-     * - encoding: unused.
+     * desired sample format
+     * - encoding: Not used.
      * - decoding: Set by user.
+     * Decoder will decode to this format if it can.
      */
     enum AVSampleFormat request_sample_fmt;
 
@@ -2257,7 +2419,7 @@
 
     /**
      * ratecontrol qmin qmax limiting method
-     * 0-> clipping, 1-> use a nice continous function to limit qscale wthin qmin/qmax.
+     * 0-> clipping, 1-> use a nice continuous function to limit qscale wthin qmin/qmax.
      * - encoding: Set by user.
      * - decoding: unused
      */
@@ -2413,9 +2575,9 @@
     int max_prediction_order;
 
     /**
-     * GOP timecode frame start number, in non drop frame format
-     * - encoding: Set by user.
-     * - decoding: unused
+     * GOP timecode frame start number
+     * - encoding: Set by user, in non drop frame format
+     * - decoding: Set by libavcodec (timecode in the 25 bits format, -1 if unset)
      */
     int64_t timecode_frame_start;
 
@@ -2562,6 +2724,11 @@
 #define AV_EF_BUFFER    (1<<2)
 #define AV_EF_EXPLODE   (1<<3)
 
+#define AV_EF_CAREFUL    (1<<16)
+#define AV_EF_COMPLIANT  (1<<17)
+#define AV_EF_AGGRESSIVE (1<<18)
+
+
     /**
      * opaque 64bit number (generally a PTS) that will be reordered and
      * output in AVFrame.reordered_opaque
@@ -2582,8 +2749,8 @@
      * Hardware accelerator context.
      * For some hardware accelerators, a global context needs to be
      * provided by the user. In that case, this holds display-dependent
-     * data Libav cannot instantiate itself. Please refer to the
-     * Libav HW accelerator documentation to know how to fill this
+     * data FFmpeg cannot instantiate itself. Please refer to the
+     * FFmpeg HW accelerator documentation to know how to fill this
      * is. e.g. for VA API, this is a struct vaapi_context.
      * - encoding: unused
      * - decoding: Set by user
@@ -2620,9 +2787,7 @@
 #define FF_IDCT_INT           1
 #define FF_IDCT_SIMPLE        2
 #define FF_IDCT_SIMPLEMMX     3
-#if FF_API_LIBMPEG2
 #define FF_IDCT_LIBMPEG2MMX   4
-#endif
 #define FF_IDCT_MMI           5
 #define FF_IDCT_ARM           7
 #define FF_IDCT_ALTIVEC       8
@@ -2670,7 +2835,7 @@
      * - encoding: unused
      * - decoding: Set by user.
      */
-    attribute_deprecated int lowres;
+     int lowres;
 
     /**
      * the picture in the bitstream
@@ -2895,8 +3060,42 @@
      * - decoding: unused.
      */
     uint64_t vbv_delay;
+
+    /**
+     * Timebase in which pkt_dts/pts and AVPacket.dts/pts are.
+     * Code outside libavcodec should access this field using:
+     * avcodec_set_pkt_timebase(avctx)
+     * - encoding unused.
+     * - decodimg set by user
+     */
+    AVRational pkt_timebase;
+
+    /**
+     * AVCodecDescriptor
+     * Code outside libavcodec should access this field using:
+     * avcodec_get_codec_descriptior(avctx)
+     * - encoding: unused.
+     * - decoding: set by libavcodec.
+     */
+    const AVCodecDescriptor *codec_descriptor;
+
+    /**
+     * Current statistics for PTS correction.
+     * - decoding: maintained and used by libavcodec, not intended to be used by user apps
+     * - encoding: unused
+     */
+    int64_t pts_correction_num_faulty_pts; /// Number of incorrect PTS values so far
+    int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far
+    int64_t pts_correction_last_pts;       /// PTS of the last frame
+    int64_t pts_correction_last_dts;       /// DTS of the last frame
 } AVCodecContext;
 
+AVRational av_codec_get_pkt_timebase         (const AVCodecContext *avctx);
+void       av_codec_set_pkt_timebase         (AVCodecContext *avctx, AVRational val);
+
+const AVCodecDescriptor *av_codec_get_codec_descriptor(const AVCodecContext *avctx);
+void                     av_codec_set_codec_descriptor(AVCodecContext *avctx, const AVCodecDescriptor *desc);
+
 /**
  * AVProfile.
  */
@@ -2937,7 +3136,7 @@
     const int *supported_samplerates;       ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0
     const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
     const uint64_t *channel_layouts;         ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
-    attribute_deprecated uint8_t max_lowres; ///< maximum value for lowres supported by the decoder
+    uint8_t max_lowres;                     ///< maximum value for lowres supported by the decoder
     const AVClass *priv_class;              ///< AVClass for the private context
     const AVProfile *profiles;              ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN}
 
@@ -3114,9 +3313,6 @@
  * @}
  */
 
-#define AVPALETTE_SIZE 1024
-#define AVPALETTE_COUNT 256
-
 enum AVSubtitleType {
     SUBTITLE_NONE,
 
@@ -3153,10 +3349,16 @@
 
     /**
      * 0 terminated ASS/SSA compatible event line.
-     * The pressentation of this is unaffected by the other values in this
+     * The presentation of this is unaffected by the other values in this
      * struct.
      */
     char *ass;
+
+    /**
+     * 1 indicates this subtitle is a forced subtitle.
+     * A forced subtitle should be displayed even when subtitles are hidden.
+     */
+    int forced;
 } AVSubtitleRect;
 
 typedef struct AVSubtitle {
@@ -3212,6 +3414,40 @@
  */
 void avcodec_register_all(void);
 
+
+#if FF_API_ALLOC_CONTEXT
+/**
+ * Allocate an AVCodecContext and set its fields to default values.  The
+ * resulting struct can be deallocated by simply calling av_free().
+ *
+ * @return An AVCodecContext filled with default values or NULL on failure.
+ * @see avcodec_get_context_defaults
+ *
+ * @deprecated use avcodec_alloc_context3()
+ */
+attribute_deprecated
+AVCodecContext *avcodec_alloc_context(void);
+
+/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API!
+ *  we WILL change its arguments and name a few times! */
+attribute_deprecated
+AVCodecContext *avcodec_alloc_context2(enum AVMediaType);
+
+/**
+ * Set the fields of the given AVCodecContext to default values.
+ *
+ * @param s The AVCodecContext of which the fields should be set to default values.
+ * @deprecated use avcodec_get_context_defaults3
+ */
+attribute_deprecated
+void avcodec_get_context_defaults(AVCodecContext *s);
+
+/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API!
+ *  we WILL change its arguments and name a few times! */
+attribute_deprecated
+void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType);
+#endif
+
 /**
  * Allocate an AVCodecContext and set its fields to default values.  The
  * resulting struct can be deallocated by calling avcodec_close() on it followed
@@ -3249,6 +3485,22 @@
 const AVClass *avcodec_get_class(void);
 
 /**
+ * Get the AVClass for AVFrame. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
+ *
+ * @see av_opt_find().
+ */
+const AVClass *avcodec_get_frame_class(void);
+
+/**
+ * Get the AVClass for AVSubtitleRect. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
+ *
+ * @see av_opt_find().
+ */
+const AVClass *avcodec_get_subtitle_rect_class(void);
+
+/**
  * Copy the settings of the source AVCodecContext into the destination
  * AVCodecContext. The resulting destination codec context will be
  * unopened, i.e. you are required to call avcodec_open2() before you
@@ -3289,6 +3541,40 @@
  */
 void avcodec_free_frame(AVFrame **frame);
 
+#if FF_API_AVCODEC_OPEN
+/**
+ * Initialize the AVCodecContext to use the given AVCodec. Prior to using this
+ * function the context has to be allocated.
+ *
+ * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(),
+ * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for
+ * retrieving a codec.
+ *
+ * @warning This function is not thread safe!
+ *
+ * @code
+ * avcodec_register_all();
+ * codec = avcodec_find_decoder(AV_CODEC_ID_H264);
+ * if (!codec)
+ *     exit(1);
+ *
+ * context = avcodec_alloc_context3(codec);
+ *
+ * if (avcodec_open(context, codec) < 0)
+ *     exit(1);
+ * @endcode
+ *
+ * @param avctx The context which will be set up to use the given codec.
+ * @param codec The codec to use within the context.
+ * @return zero on success, a negative value on error
+ * @see avcodec_alloc_context3, avcodec_find_decoder, avcodec_find_encoder, avcodec_close
+ *
+ * @deprecated use avcodec_open2
+ */
+attribute_deprecated
+int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
+#endif
+
 /**
  * Initialize the AVCodecContext to use the given AVCodec. Prior to using this
  * function the context has to be allocated with avcodec_alloc_context3().
@@ -3402,6 +3688,13 @@
 int av_dup_packet(AVPacket *pkt);
 
 /**
+ * Copy packet, including contents
+ *
+ * @return 0 on success, negative AVERROR on fail
+ */
+int av_copy_packet(AVPacket *dst, AVPacket *src);
+
+/**
  * Free a packet.
  *
  * @param pkt packet to free
@@ -3441,6 +3734,11 @@
 uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
                                  int *size);
 
+int av_packet_merge_side_data(AVPacket *pkt);
+
+int av_packet_split_side_data(AVPacket *pkt);
+
+
 /**
  * @}
  */
@@ -3596,7 +3894,7 @@
  *         AVPacket is returned.
  */
 int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame,
-                          int *got_frame_ptr, AVPacket *avpkt);
+                          int *got_frame_ptr, const AVPacket *avpkt);
 
 /**
  * Decode the video frame of size avpkt->size from avpkt->data into picture.
@@ -3641,7 +3939,7 @@
  */
 int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
                          int *got_picture_ptr,
-                         AVPacket *avpkt);
+                         const AVPacket *avpkt);
 
 /**
  * Decode a subtitle message.
@@ -3706,6 +4004,7 @@
 #define PARSER_FLAG_ONCE                      0x0002
 /// Set if the parser has a valid file offset
 #define PARSER_FLAG_FETCHED_OFFSET            0x0004
+#define PARSER_FLAG_USE_CODEC_TS              0x1000
 
     int64_t offset;      ///< byte offset from starting packet start
     int64_t cur_frame_end[AV_PARSER_PTS_NB];
@@ -3931,11 +4230,12 @@
  *                  The user can supply an output buffer by setting
  *                  avpkt->data and avpkt->size prior to calling the
  *                  function, but if the size of the user-provided data is not
- *                  large enough, encoding will fail. All other AVPacket fields
- *                  will be reset by the encoder using av_init_packet(). If
- *                  avpkt->data is NULL, the encoder will allocate it.
- *                  The encoder will set avpkt->size to the size of the
- *                  output packet.
+ *                  large enough, encoding will fail. If avpkt->data and
+ *                  avpkt->size are set, avpkt->destruct must also be set. All
+ *                  other AVPacket fields will be reset by the encoder using
+ *                  av_init_packet(). If avpkt->data is NULL, the encoder will
+ *                  allocate it. The encoder will set avpkt->size to the size
+ *                  of the output packet.
  *
  *                  If this function fails or produces no output, avpkt will be
  *                  freed using av_free_packet() (i.e. avpkt->destruct will be
@@ -4028,7 +4328,7 @@
 /**
  * @defgroup lavc_resample Audio resampling
  * @ingroup libavc
- * @deprecated use libavresample instead
+ * @deprecated use libswresample instead
  *
  * @{
  */
@@ -4149,42 +4449,19 @@
 void avpicture_free(AVPicture *picture);
 
 /**
- * Fill in the AVPicture fields.
- * The fields of the given AVPicture are filled in by using the 'ptr' address
- * which points to the image data buffer. Depending on the specified picture
- * format, one or multiple image data pointers and line sizes will be set.
- * If a planar format is specified, several pointers will be set pointing to
- * the different picture planes and the line sizes of the different planes
- * will be stored in the lines_sizes array.
- * Call with ptr == NULL to get the required size for the ptr buffer.
+ * Fill in the AVPicture fields, always assume a linesize alignment of
+ * 1.
  *
- * To allocate the buffer and fill in the AVPicture fields in one call,
- * use avpicture_alloc().
- *
- * @param picture AVPicture whose fields are to be filled in
- * @param ptr Buffer which will contain or contains the actual image data
- * @param pix_fmt The format in which the picture data is stored.
- * @param width the width of the image in pixels
- * @param height the height of the image in pixels
- * @return size of the image data in bytes
+ * @see av_image_fill_arrays()
  */
 int avpicture_fill(AVPicture *picture, uint8_t *ptr,
                    enum AVPixelFormat pix_fmt, int width, int height);
 
 /**
- * Copy pixel data from an AVPicture into a buffer.
- * The data is stored compactly, without any gaps for alignment or padding
- * which may be applied by avpicture_fill().
+ * Copy pixel data from an AVPicture into a buffer, always assume a
+ * linesize alignment of 1.
  *
- * @see avpicture_get_size()
- *
- * @param[in] src AVPicture containing image data
- * @param[in] pix_fmt The format in which the picture data is stored.
- * @param[in] width the width of the image in pixels.
- * @param[in] height the height of the image in pixels.
- * @param[out] dest A buffer into which picture data will be copied.
- * @param[in] dest_size The size of 'dest'.
- * @return The number of bytes written to dest, or a negative value (error code) on error.
+ * @see av_image_copy_to_buffer()
  */
 int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt,
                      int width, int height,
@@ -4193,14 +4470,9 @@
 /**
  * Calculate the size in bytes that a picture of the given width and height
  * would occupy if stored in the given picture format.
- * Note that this returns the size of a compact representation as generated
- * by avpicture_layout(), which can be smaller than the size required for e.g.
- * avpicture_fill().
+ * Always assume a linesize alignment of 1.
  *
- * @param pix_fmt the given picture format
- * @param width the width of the image
- * @param height the height of the image
- * @return Image data size in bytes or -1 on error (e.g. too large dimensions).
+ * @see av_image_get_buffer_size().
  */
 int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height);
 
@@ -4210,7 +4482,7 @@
 int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
                           enum AVPixelFormat pix_fmt, int width, int height);
 /**
- * Copy image src to dst. Wraps av_picture_data_copy() above.
+ * Copy image src to dst. Wraps av_image_copy().
  */
 void av_picture_copy(AVPicture *dst, const AVPicture *src,
                      enum AVPixelFormat pix_fmt, int width, int height);
@@ -4278,14 +4550,15 @@
  * @param[in] dst_pix_fmt destination pixel format
  * @param[in] src_pix_fmt source pixel format
  * @param[in] has_alpha Whether the source pixel format alpha channel is used.
- * @return Combination of flags informing you what kind of losses will occur.
+ * @return Combination of flags informing you what kind of losses will occur
+ * (maximum loss for an invalid dst_pix_fmt).
  */
 int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt,
                              int has_alpha);
 
 #if FF_API_FIND_BEST_PIX_FMT
 /**
- * @deprecated use avcodec_find_best_pix_fmt2() instead.
+ * @deprecated use avcodec_find_best_pix_fmt_of_2() instead.
  *
  * Find the best pixel format to convert to given a certain source pixel
  * format.  When converting from one pixel format to another, information loss
@@ -4296,9 +4569,11 @@
  * The pixel formats from which it chooses one, are determined by the
  * pix_fmt_mask parameter.
  *
+ * Note, only the first 64 pixel formats will fit in pix_fmt_mask.
+ *
  * @code
  * src_pix_fmt = AV_PIX_FMT_YUV420P;
- * pix_fmt_mask = (1 << AV_PIX_FMT_YUV422P) || (1 << AV_PIX_FMT_RGB24);
+ * pix_fmt_mask = (1 << AV_PIX_FMT_YUV422P) | (1 << AV_PIX_FMT_RGB24);
  * dst_pix_fmt = avcodec_find_best_pix_fmt(pix_fmt_mask, src_pix_fmt, alpha, &loss);
  * @endcode
  *
@@ -4318,7 +4593,7 @@
  * format.  When converting from one pixel format to another, information loss
  * may occur.  For example, when converting from RGB24 to GRAY, the color
  * information will be lost. Similarly, other losses occur when converting from
- * some formats to other formats. avcodec_find_best_pix_fmt2() searches which of
+ * some formats to other formats. avcodec_find_best_pix_fmt_of_2() searches which of
  * the given pixel formats should be used to suffer the least amount of loss.
  * The pixel formats from which it chooses one, are determined by the
  * pix_fmt_list parameter.
@@ -4330,9 +4605,53 @@
  * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur.
  * @return The best pixel format to convert to or -1 if none was found.
  */
+enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(enum AVPixelFormat *pix_fmt_list,
+                                            enum AVPixelFormat src_pix_fmt,
+                                            int has_alpha, int *loss_ptr);
+
+/**
+ * Find the best pixel format to convert to given a certain source pixel
+ * format and a selection of two destination pixel formats. When converting from
+ * one pixel format to another, information loss may occur.  For example, when converting
+ * from RGB24 to GRAY, the color information will be lost. Similarly, other losses occur when
+ * converting from some formats to other formats. avcodec_find_best_pix_fmt_of_2() selects which of
+ * the given pixel formats should be used to suffer the least amount of loss.
+ *
+ * If one of the destination formats is AV_PIX_FMT_NONE the other pixel format (if valid) will be
+ * returned.
+ *
+ * @code
+ * src_pix_fmt = AV_PIX_FMT_YUV420P;
+ * dst_pix_fmt1= AV_PIX_FMT_RGB24;
+ * dst_pix_fmt2= AV_PIX_FMT_GRAY8;
+ * dst_pix_fmt3= AV_PIX_FMT_RGB8;
+ * loss= FF_LOSS_CHROMA; // don't care about chroma loss, so chroma loss will be ignored.
+ * dst_pix_fmt = avcodec_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, alpha, &loss);
+ * dst_pix_fmt = avcodec_find_best_pix_fmt_of_2(dst_pix_fmt, dst_pix_fmt3, src_pix_fmt, alpha, &loss);
+ * @endcode
+ *
+ * @param[in] dst_pix_fmt1 One of the two destination pixel formats to choose from
+ * @param[in] dst_pix_fmt2 The other of the two destination pixel formats to choose from
+ * @param[in] src_pix_fmt Source pixel format
+ * @param[in] has_alpha Whether the source pixel format alpha channel is used.
+ * @param[in, out] loss_ptr Combination of loss flags. In: selects which of the losses to ignore, i.e.
+ *                               NULL or value of zero means we care about all losses. Out: the loss
+ *                               that occurs when converting from src to selected dst pixel format.
+ * @return The best pixel format to convert to or -1 if none was found.
+ */
+enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
+                                            enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr);
+
+attribute_deprecated
+#if AV_HAVE_INCOMPATIBLE_FORK_ABI
 enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat *pix_fmt_list,
                                               enum AVPixelFormat src_pix_fmt,
                                               int has_alpha, int *loss_ptr);
+#else
+enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
+                                            enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr);
+#endif
+
 
 enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum AVPixelFormat * fmt);
 
@@ -4402,6 +4721,14 @@
 int av_get_bits_per_sample(enum AVCodecID codec_id);
 
 /**
+ * Return the PCM codec associated with a sample format.
+ * @param be  endianness, 0 for little, 1 for big,
+ *            -1 (or anything else) for native
+ * @return  AV_CODEC_ID_PCM_* or AV_CODEC_ID_NONE
+ */
+enum AVCodecID av_get_pcm_codec(enum AVSampleFormat fmt, int be);
+
+/**
  * Return codec bits per sample.
  * Only return non-zero if the bits per sample is exactly correct, not an
  * approximation.
@@ -4475,15 +4802,21 @@
 void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size);
 
 /**
- * Allocate a buffer with padding, reusing the given one if large enough.
- *
  * Same behaviour av_fast_malloc but the buffer has additional
- * FF_INPUT_PADDING_SIZE at the end which will always memset to 0.
+ * FF_INPUT_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.
  */
 void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size);
 
 /**
+ * Same behaviour av_fast_padded_malloc except that buffer will always
+ * be 0-initialized after call.
+ */
+void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size);
+
+/**
  * Encode extradata length to a buffer. Used by xiph codecs.
  *
  * @param s buffer to write to; must be at least (v/255+1) bytes long
@@ -4494,7 +4827,7 @@
 
 /**
  * Log a generic warning message about a missing feature. This function is
- * intended to be used internally by Libav (libavcodec, libavformat, etc.)
+ * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.)
  * only, and would normally not be used by applications.
  * @param[in] avc a pointer to an arbitrary struct of which the first field is
  * a pointer to an AVClass struct
@@ -4508,7 +4841,7 @@
 
 /**
  * Log a generic warning message asking for a sample. This function is
- * intended to be used internally by Libav (libavcodec, libavformat, etc.)
+ * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.)
  * only, and would normally not be used by applications.
  * @param[in] avc a pointer to an arbitrary struct of which the first field is
  * a pointer to an AVClass struct
@@ -4545,7 +4878,7 @@
  * lockmgr should store/get a pointer to a user allocated mutex. It's
  * NULL upon AV_LOCK_CREATE and != NULL for all other ops.
  *
- * @param cb User defined callback. Note: Libav may invoke calls to this
+ * @param cb User defined callback. Note: FFmpeg may invoke calls to this
  *           callback during the call to av_lockmgr_register().
  *           Thus, the application must be prepared to handle that.
  *           If cb is set to NULL the lockmgr will be unregistered.
@@ -4560,6 +4893,12 @@
 enum AVMediaType avcodec_get_type(enum AVCodecID codec_id);
 
 /**
+ * Get the name of a codec.
+ * @return  a static string identifying the codec; never NULL
+ */
+const char *avcodec_get_name(enum AVCodecID id);
+
+/**
  * @return a positive value if s is open (i.e. avcodec_open2() was called on it
  * with no corresponding avcodec_close()), 0 otherwise.
  */
diff --git a/libavcodec/avfft.c b/libavcodec/avfft.c
index 9ed06fb..9e0ddaa 100644
--- a/libavcodec/avfft.c
+++ b/libavcodec/avfft.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/avfft.h b/libavcodec/avfft.h
index b896182..2d20a45 100644
--- a/libavcodec/avfft.h
+++ b/libavcodec/avfft.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index cb24948..516f1c9 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -2,20 +2,20 @@
  * AVPacket functions for libavcodec
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,21 +24,27 @@
 #include "libavutil/avassert.h"
 #include "libavutil/mem.h"
 #include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
 
-void av_destruct_packet(AVPacket *pkt)
+void ff_packet_free_side_data(AVPacket *pkt)
 {
     int i;
-
-    av_free(pkt->data);
-    pkt->data = NULL;
-    pkt->size = 0;
-
     for (i = 0; i < pkt->side_data_elems; i++)
         av_free(pkt->side_data[i].data);
     av_freep(&pkt->side_data);
     pkt->side_data_elems = 0;
 }
 
+void av_destruct_packet(AVPacket *pkt)
+{
+    av_free(pkt->data);
+    pkt->data = NULL;
+    pkt->size = 0;
+
+    ff_packet_free_side_data(pkt);
+}
+
 void av_init_packet(AVPacket *pkt)
 {
     pkt->pts                  = AV_NOPTS_VALUE;
@@ -119,35 +125,50 @@
         dst = data;                                                     \
     } while (0)
 
+/* Makes duplicates of data, side_data, but does not copy any other fields */
+static int copy_packet_data(AVPacket *dst, AVPacket *src)
+{
+    dst->data      = NULL;
+    dst->side_data = NULL;
+    DUP_DATA(dst->data, src->data, dst->size, 1);
+    dst->destruct = av_destruct_packet;
+
+    if (dst->side_data_elems) {
+        int i;
+
+        DUP_DATA(dst->side_data, src->side_data,
+                dst->side_data_elems * sizeof(*dst->side_data), 0);
+        memset(dst->side_data, 0,
+                dst->side_data_elems * sizeof(*dst->side_data));
+        for (i = 0; i < dst->side_data_elems; i++) {
+            DUP_DATA(dst->side_data[i].data, src->side_data[i].data,
+                    src->side_data[i].size, 1);
+            dst->side_data[i].size = src->side_data[i].size;
+            dst->side_data[i].type = src->side_data[i].type;
+        }
+    }
+    return 0;
+
+failed_alloc:
+    av_destruct_packet(dst);
+    return AVERROR(ENOMEM);
+}
+
 int av_dup_packet(AVPacket *pkt)
 {
     AVPacket tmp_pkt;
 
     if (pkt->destruct == NULL && pkt->data) {
         tmp_pkt = *pkt;
-
-        pkt->data      = NULL;
-        pkt->side_data = NULL;
-        DUP_DATA(pkt->data, tmp_pkt.data, pkt->size, 1);
-        pkt->destruct = av_destruct_packet;
-
-        if (pkt->side_data_elems) {
-            int i;
-
-            DUP_DATA(pkt->side_data, tmp_pkt.side_data,
-                     pkt->side_data_elems * sizeof(*pkt->side_data), 0);
-            memset(pkt->side_data, 0,
-                   pkt->side_data_elems * sizeof(*pkt->side_data));
-            for (i = 0; i < pkt->side_data_elems; i++)
-                DUP_DATA(pkt->side_data[i].data, tmp_pkt.side_data[i].data,
-                         tmp_pkt.side_data[i].size, 1);
-        }
+        return copy_packet_data(pkt, &tmp_pkt);
     }
     return 0;
+}
 
-failed_alloc:
-    av_destruct_packet(pkt);
-    return AVERROR(ENOMEM);
+int av_copy_packet(AVPacket *dst, AVPacket *src)
+{
+    *dst = *src;
+    return copy_packet_data(dst, src);
 }
 
 void av_free_packet(AVPacket *pkt)
@@ -202,6 +223,84 @@
     return NULL;
 }
 
+#define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL
+
+int av_packet_merge_side_data(AVPacket *pkt){
+    if(pkt->side_data_elems){
+        int i;
+        uint8_t *p;
+        uint64_t size= pkt->size + 8LL + FF_INPUT_BUFFER_PADDING_SIZE;
+        AVPacket old= *pkt;
+        for (i=0; i<old.side_data_elems; i++) {
+            size += old.side_data[i].size + 5LL;
+        }
+        if (size > INT_MAX)
+            return AVERROR(EINVAL);
+        p = av_malloc(size);
+        if (!p)
+            return AVERROR(ENOMEM);
+        pkt->data = p;
+        pkt->destruct = av_destruct_packet;
+        pkt->size = size - FF_INPUT_BUFFER_PADDING_SIZE;
+        bytestream_put_buffer(&p, old.data, old.size);
+        for (i=old.side_data_elems-1; i>=0; i--) {
+            bytestream_put_buffer(&p, old.side_data[i].data, old.side_data[i].size);
+            bytestream_put_be32(&p, old.side_data[i].size);
+            *p++ = old.side_data[i].type | ((i==old.side_data_elems-1)*128);
+        }
+        bytestream_put_be64(&p, FF_MERGE_MARKER);
+        av_assert0(p-pkt->data == pkt->size);
+        memset(p, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+        av_free_packet(&old);
+        pkt->side_data_elems = 0;
+        pkt->side_data = NULL;
+        return 1;
+    }
+    return 0;
+}
+
+int av_packet_split_side_data(AVPacket *pkt){
+    if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){
+        int i;
+        unsigned int size;
+        uint8_t *p;
+
+        p = pkt->data + pkt->size - 8 - 5;
+        for (i=1; ; i++){
+            size = AV_RB32(p);
+            if (size>INT_MAX || p - pkt->data < size)
+                return 0;
+            if (p[4]&128)
+                break;
+            p-= size+5;
+        }
+
+        pkt->side_data = av_malloc(i * sizeof(*pkt->side_data));
+        if (!pkt->side_data)
+            return AVERROR(ENOMEM);
+
+        p= pkt->data + pkt->size - 8 - 5;
+        for (i=0; ; i++){
+            size= AV_RB32(p);
+            av_assert0(size<=INT_MAX && p - pkt->data >= size);
+            pkt->side_data[i].data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
+            pkt->side_data[i].size = size;
+            pkt->side_data[i].type = p[4]&127;
+            if (!pkt->side_data[i].data)
+                return AVERROR(ENOMEM);
+            memcpy(pkt->side_data[i].data, p-size, size);
+            pkt->size -= size + 5;
+            if(p[4]&128)
+                break;
+            p-= size+5;
+        }
+        pkt->size -= 8;
+        pkt->side_data_elems = i+1;
+        return 1;
+    }
+    return 0;
+}
+
 int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
                                int size)
 {
diff --git a/libavcodec/avr32/mathops.h b/libavcodec/avr32/mathops.h
index 528b7ad..85f42b5 100644
--- a/libavcodec/avr32/mathops.h
+++ b/libavcodec/avr32/mathops.h
@@ -2,20 +2,20 @@
  * Simple math operations
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/avrndec.c b/libavcodec/avrndec.c
new file mode 100644
index 0000000..207b797
--- /dev/null
+++ b/libavcodec/avrndec.c
@@ -0,0 +1,133 @@
+/*
+ * AVRn decoder
+ * 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
+ */
+
+#include "avcodec.h"
+#include "mjpeg.h"
+#include "mjpegdec.h"
+
+typedef struct {
+    MJpegDecodeContext mjpeg_ctx;
+    AVFrame frame;
+    int is_mjpeg;
+    int interlace; //FIXME use frame.interlaced_frame
+    int tff;
+} AVRnContext;
+
+static av_cold int init(AVCodecContext *avctx)
+{
+    AVRnContext *a = avctx->priv_data;
+
+    // Support "Resolution 1:1" for Avid AVI Codec
+    a->is_mjpeg = avctx->extradata_size < 31 || memcmp(&avctx->extradata[28], "1:1", 3);
+
+    if(a->is_mjpeg)
+        return ff_mjpeg_decode_init(avctx);
+
+    if(avctx->width <= 0 || avctx->height <= 0)
+        return -1;
+
+    avcodec_get_frame_defaults(&a->frame);
+    avctx->pix_fmt = AV_PIX_FMT_UYVY422;
+
+    if(avctx->extradata_size >= 9 && avctx->extradata[4]+28 < avctx->extradata_size) {
+        int ndx = avctx->extradata[4] + 4;
+        a->interlace = !memcmp(avctx->extradata + ndx, "1:1(", 4);
+        if(a->interlace) {
+            a->tff = avctx->extradata[ndx + 24] == 1;
+        }
+    }
+
+    return 0;
+}
+
+static av_cold int end(AVCodecContext *avctx)
+{
+    AVRnContext *a = avctx->priv_data;
+    AVFrame *p = &a->frame;
+
+    if(p->data[0])
+        avctx->release_buffer(avctx, p);
+
+    if(a->is_mjpeg)
+        ff_mjpeg_decode_end(avctx);
+
+    return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+{
+    AVRnContext *a = avctx->priv_data;
+    AVFrame *p = &a->frame;
+    const uint8_t *buf = avpkt->data;
+    int buf_size       = avpkt->size;
+    int true_height    = buf_size / (2*avctx->width);
+    int y;
+
+    if(a->is_mjpeg)
+        return ff_mjpeg_decode_frame(avctx, data, data_size, avpkt);
+
+    if(p->data[0])
+        avctx->release_buffer(avctx, p);
+
+    if(buf_size < 2*avctx->width * avctx->height) {
+        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if(avctx->get_buffer(avctx, p) < 0){
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return -1;
+    }
+    p->pict_type= AV_PICTURE_TYPE_I;
+    p->key_frame= 1;
+
+    if(a->interlace) {
+        buf += (true_height - avctx->height)*avctx->width;
+        for(y = 0; y < avctx->height-1; y+=2) {
+            memcpy(p->data[0] + (y+ a->tff)*p->linesize[0], buf                             , 2*avctx->width);
+            memcpy(p->data[0] + (y+!a->tff)*p->linesize[0], buf + avctx->width*true_height+4, 2*avctx->width);
+            buf += 2*avctx->width;
+        }
+    } else {
+        buf += (true_height - avctx->height)*avctx->width*2;
+        for(y = 0; y < avctx->height; y++) {
+            memcpy(p->data[0] + y*p->linesize[0], buf, 2*avctx->width);
+            buf += 2*avctx->width;
+        }
+    }
+
+    *(AVFrame*)data = a->frame;
+    *data_size      = sizeof(AVFrame);
+    return buf_size;
+}
+
+AVCodec ff_avrn_decoder = {
+    .name           = "avrn",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_AVRN,
+    .priv_data_size = sizeof(AVRnContext),
+    .init           = init,
+    .close          = end,
+    .decode         = decode_frame,
+    .long_name      = NULL_IF_CONFIG_SMALL("Avid AVI Codec"),
+    .capabilities   = CODEC_CAP_DR1,
+};
+
diff --git a/libavcodec/avs.c b/libavcodec/avs.c
index f6535a2..a9ab029 100644
--- a/libavcodec/avs.c
+++ b/libavcodec/avs.c
@@ -2,20 +2,20 @@
  * AVS video decoder.
  * Copyright (c) 2006  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -63,7 +63,7 @@
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return -1;
     }
-    p->reference = 1;
+    p->reference = 3;
     p->pict_type = AV_PICTURE_TYPE_P;
     p->key_frame = 0;
 
@@ -85,8 +85,10 @@
         if (first >= 256 || last > 256 || buf_end - buf < 4 + 4 + 3 * (last - first))
             return AVERROR_INVALIDDATA;
         buf += 4;
-        for (i=first; i<last; i++, buf+=3)
+        for (i=first; i<last; i++, buf+=3) {
             pal[i] = (buf[0] << 18) | (buf[1] << 10) | (buf[2] << 2);
+            pal[i] |= 0xFF << 24 | (pal[i] >> 6) & 0x30303;
+        }
 
         sub_type = buf[0];
         type = buf[1];
@@ -157,7 +159,9 @@
 
 static av_cold int avs_decode_init(AVCodecContext * avctx)
 {
+    AvsContext *const avs = avctx->priv_data;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
+    avcodec_get_frame_defaults(&avs->picture);
     avcodec_set_dimensions(avctx, 318, 198);
     return 0;
 }
diff --git a/libavcodec/avuidec.c b/libavcodec/avuidec.c
new file mode 100644
index 0000000..27f0b4c
--- /dev/null
+++ b/libavcodec/avuidec.c
@@ -0,0 +1,155 @@
+/*
+ * AVID Meridien 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 "libavutil/intreadwrite.h"
+
+static av_cold int avui_decode_init(AVCodecContext *avctx)
+{
+    avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
+
+    avctx->coded_frame = avcodec_alloc_frame();
+
+    if (!avctx->coded_frame) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int avui_decode_frame(AVCodecContext *avctx, void *data,
+                             int *data_size, AVPacket *avpkt)
+{
+    AVFrame *pic = avctx->coded_frame;
+    const uint8_t *src = avpkt->data, *extradata = avctx->extradata;
+    const uint8_t *srca;
+    uint8_t *y, *u, *v, *a;
+    int transparent, interlaced = 1, skip, opaque_length, i, j, k;
+    uint32_t extradata_size = avctx->extradata_size;
+
+    if (pic->data[0])
+        avctx->release_buffer(avctx, pic);
+
+    while (extradata_size >= 24) {
+        uint32_t atom_size = AV_RB32(extradata);
+        if (!memcmp(&extradata[4], "APRGAPRG0001", 12)) {
+            interlaced = extradata[19] != 1;
+            break;
+        }
+        if (atom_size && atom_size <= extradata_size) {
+            extradata      += atom_size;
+            extradata_size -= atom_size;
+        } else {
+            break;
+        }
+    }
+    if (avctx->height == 486) {
+        skip = 10;
+    } else {
+        skip = 16;
+    }
+    opaque_length = 2 * avctx->width * (avctx->height + skip) + 4 * interlaced;
+    if (avpkt->size < opaque_length) {
+        av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
+        return AVERROR(EINVAL);
+    }
+    transparent = avctx->bits_per_coded_sample == 32 &&
+                  avpkt->size >= opaque_length * 2 + 4;
+    srca = src + opaque_length + 5;
+
+    pic->reference = 0;
+
+    if (avctx->get_buffer(avctx, pic) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    pic->key_frame = 1;
+    pic->pict_type = AV_PICTURE_TYPE_I;
+
+    if (!interlaced) {
+        src  += avctx->width * skip;
+        srca += avctx->width * skip;
+    }
+
+    for (i = 0; i < interlaced + 1; i++) {
+        src  += avctx->width * skip;
+        srca += avctx->width * skip;
+        if (interlaced && avctx->height == 486) {
+            y = pic->data[0] + (1 - i) * pic->linesize[0];
+            u = pic->data[1] + (1 - i) * pic->linesize[1];
+            v = pic->data[2] + (1 - i) * pic->linesize[2];
+            a = pic->data[3] + (1 - i) * pic->linesize[3];
+        } else {
+            y = pic->data[0] + i * pic->linesize[0];
+            u = pic->data[1] + i * pic->linesize[1];
+            v = pic->data[2] + i * pic->linesize[2];
+            a = pic->data[3] + i * pic->linesize[3];
+        }
+
+        for (j = 0; j < avctx->height >> interlaced; j++) {
+            for (k = 0; k < avctx->width >> 1; k++) {
+                u[    k    ] = *src++;
+                y[2 * k    ] = *src++;
+                a[2 * k    ] = 0xFF - (transparent ? *srca++ : 0);
+                srca++;
+                v[    k    ] = *src++;
+                y[2 * k + 1] = *src++;
+                a[2 * k + 1] = 0xFF - (transparent ? *srca++ : 0);
+                srca++;
+            }
+
+            y += (interlaced + 1) * pic->linesize[0];
+            u += (interlaced + 1) * pic->linesize[1];
+            v += (interlaced + 1) * pic->linesize[2];
+            a += (interlaced + 1) * pic->linesize[3];
+        }
+        src  += 4;
+        srca += 4;
+    }
+    *data_size = sizeof(AVFrame);
+    *(AVFrame *)data = *pic;
+
+    return avpkt->size;
+}
+
+static av_cold int avui_decode_close(AVCodecContext *avctx)
+{
+    if (avctx->coded_frame->data[0])
+        avctx->release_buffer(avctx, avctx->coded_frame);
+
+    av_freep(&avctx->coded_frame);
+
+    return 0;
+}
+
+AVCodec ff_avui_decoder = {
+    .name         = "avui",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_AVUI,
+    .init         = avui_decode_init,
+    .decode       = avui_decode_frame,
+    .close        = avui_decode_close,
+    .capabilities = CODEC_CAP_DR1,
+    .long_name    = NULL_IF_CONFIG_SMALL("AVID Meridien"),
+};
diff --git a/libavcodec/avuienc.c b/libavcodec/avuienc.c
new file mode 100644
index 0000000..4428232
--- /dev/null
+++ b/libavcodec/avuienc.c
@@ -0,0 +1,113 @@
+/*
+ * AVID Meridien encoder
+ *
+ * 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"
+
+static av_cold int avui_encode_init(AVCodecContext *avctx)
+{
+    avctx->coded_frame = avcodec_alloc_frame();
+
+    if (avctx->width != 720 || avctx->height != 486 && avctx->height != 576) {
+        av_log(avctx, AV_LOG_ERROR, "Only 720x486 and 720x576 are supported.\n");
+        return AVERROR(EINVAL);
+    }
+    if (!avctx->coded_frame) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+        return AVERROR(ENOMEM);
+    }
+    if (!(avctx->extradata = av_mallocz(24 + FF_INPUT_BUFFER_PADDING_SIZE)))
+        return AVERROR(ENOMEM);
+    avctx->extradata_size = 24;
+    memcpy(avctx->extradata, "\0\0\0\x18""APRGAPRG0001", 16);
+    if (avctx->field_order > AV_FIELD_PROGRESSIVE) {
+        avctx->extradata[19] = 2;
+    } else {
+        avctx->extradata[19] = 1;
+    }
+
+
+    return 0;
+}
+
+static int avui_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                             const AVFrame *pic, int *got_packet)
+{
+    uint8_t *dst, *src = pic->data[0];
+    int i, j, skip, ret, size, interlaced;
+
+    interlaced = avctx->field_order > AV_FIELD_PROGRESSIVE;
+
+    if (avctx->height == 486) {
+        skip = 10;
+    } else {
+        skip = 16;
+    }
+    size = 2 * avctx->width * (avctx->height + skip) + 8 * interlaced;
+    if ((ret = ff_alloc_packet2(avctx, pkt, size)) < 0)
+        return ret;
+    dst = pkt->data;
+    if (!interlaced) {
+        dst += avctx->width * skip;
+    }
+
+    avctx->coded_frame->reference = 0;
+    avctx->coded_frame->key_frame = 1;
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+
+    for (i = 0; i <= interlaced; i++) {
+        if (interlaced && avctx->height == 486) {
+            src = pic->data[0] + (1 - i) * pic->linesize[0];
+        } else {
+            src = pic->data[0] + i * pic->linesize[0];
+        }
+        dst += avctx->width * skip + 4 * i;
+        for (j = 0; j < avctx->height; j += interlaced + 1) {
+            memcpy(dst, src, avctx->width * 2);
+            src += (interlaced + 1) * pic->linesize[0];
+            dst += avctx->width * 2;
+        }
+    }
+
+    pkt->flags |= AV_PKT_FLAG_KEY;
+    *got_packet = 1;
+    return 0;
+}
+
+static av_cold int avui_encode_close(AVCodecContext *avctx)
+{
+    av_freep(&avctx->coded_frame);
+
+    return 0;
+}
+
+AVCodec ff_avui_encoder = {
+    .name         = "avui",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_AVUI,
+    .init         = avui_encode_init,
+    .encode2      = avui_encode_frame,
+    .close        = avui_encode_close,
+    .capabilities = CODEC_CAP_EXPERIMENTAL,
+    .pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_UYVY422, AV_PIX_FMT_NONE },
+    .long_name    = NULL_IF_CONFIG_SMALL("Avid Meridien Uncompressed"),
+};
diff --git a/libavcodec/bethsoftvideo.c b/libavcodec/bethsoftvideo.c
index c1f95ed..8eec5b7 100644
--- a/libavcodec/bethsoftvideo.c
+++ b/libavcodec/bethsoftvideo.c
@@ -2,20 +2,20 @@
  * Bethesda VID video decoder
  * Copyright (C) 2007 Nicholas Tung
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -40,7 +40,8 @@
 static av_cold int bethsoftvid_decode_init(AVCodecContext *avctx)
 {
     BethsoftvidContext *vid = avctx->priv_data;
-    vid->frame.reference = 1;
+    avcodec_get_frame_defaults(&vid->frame);
+    vid->frame.reference = 3;
     vid->frame.buffer_hints = FF_BUFFER_HINTS_VALID |
         FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
@@ -56,7 +57,8 @@
         return AVERROR_INVALIDDATA;
 
     for(a = 0; a < 256; a++){
-        palette[a] = bytestream2_get_be24u(&ctx->g) * 4;
+        palette[a] = 0xFFU << 24 | bytestream2_get_be24u(&ctx->g) * 4;
+        palette[a] |= palette[a] >> 6 & 0x30303;
     }
     ctx->frame.palette_has_changed = 1;
     return 0;
@@ -75,9 +77,9 @@
     int code, ret;
     int yoffset;
 
-    if (avctx->reget_buffer(avctx, &vid->frame)) {
+    if ((ret = avctx->reget_buffer(avctx, &vid->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return ret;
     }
     wrap_to_next_line = vid->frame.linesize[0] - avctx->width;
 
@@ -105,7 +107,7 @@
         case VIDEO_YOFF_P_FRAME:
             yoffset = bytestream2_get_le16(&vid->g);
             if(yoffset >= avctx->height)
-                return -1;
+                return AVERROR_INVALIDDATA;
             dst += vid->frame.linesize[0] * yoffset;
     }
 
diff --git a/libavcodec/bethsoftvideo.h b/libavcodec/bethsoftvideo.h
index 5cbbdfd..d5b5d0a 100644
--- a/libavcodec/bethsoftvideo.h
+++ b/libavcodec/bethsoftvideo.h
@@ -2,20 +2,20 @@
  * Bethesda VID video decoder
  * Copyright (C) 2007 Nicholas Tung
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/bfi.c b/libavcodec/bfi.c
index 34c5bd3..8d7aa13 100644
--- a/libavcodec/bfi.c
+++ b/libavcodec/bfi.c
@@ -2,20 +2,20 @@
  * Brute Force & Ignorance (BFI) video decoder
  * Copyright (c) 2008 Sisir Koppaka
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -34,12 +34,14 @@
     AVCodecContext *avctx;
     AVFrame frame;
     uint8_t *dst;
+    uint32_t pal[256];
 } BFIContext;
 
 static av_cold int bfi_decode_init(AVCodecContext *avctx)
 {
     BFIContext *bfi = avctx->priv_data;
     avctx->pix_fmt  = AV_PIX_FMT_PAL8;
+    avcodec_get_frame_defaults(&bfi->frame);
     bfi->dst        = av_mallocz(avctx->width * avctx->height);
     return 0;
 }
@@ -59,7 +61,7 @@
     if (bfi->frame.data[0])
         avctx->release_buffer(avctx, &bfi->frame);
 
-    bfi->frame.reference = 1;
+    bfi->frame.reference = 3;
 
     if (avctx->get_buffer(avctx, &bfi->frame) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
@@ -80,16 +82,19 @@
         pal = (uint32_t *)bfi->frame.data[1];
         for (i = 0; i < avctx->extradata_size / 3; i++) {
             int shift = 16;
-            *pal = 0;
+            *pal = 0xFF << 24;
             for (j = 0; j < 3; j++, shift -= 8)
                 *pal += ((avctx->extradata[i * 3 + j] << 2) |
                          (avctx->extradata[i * 3 + j] >> 4)) << shift;
             pal++;
         }
+        memcpy(bfi->pal, bfi->frame.data[1], sizeof(bfi->pal));
         bfi->frame.palette_has_changed = 1;
     } else {
         bfi->frame.pict_type = AV_PICTURE_TYPE_P;
         bfi->frame.key_frame = 0;
+        bfi->frame.palette_has_changed = 0;
+        memcpy(bfi->frame.data[1], bfi->pal, sizeof(bfi->pal));
     }
 
     bytestream2_skip(&g, 4); // Unpacked size, not required.
diff --git a/libavcodec/bfin/config_bfin.h b/libavcodec/bfin/config_bfin.h
index 0fee494..f3a2c6e 100644
--- a/libavcodec/bfin/config_bfin.h
+++ b/libavcodec/bfin/config_bfin.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 /*
diff --git a/libavcodec/bfin/dsputil_bfin.c b/libavcodec/bfin/dsputil_bfin.c
index 8597ec1..434d2a7 100644
--- a/libavcodec/bfin/dsputil_bfin.c
+++ b/libavcodec/bfin/dsputil_bfin.c
@@ -4,20 +4,20 @@
  * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com>
  * Copyright (c) 2006 Michael Benjamin <michael.benjamin@analog.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/bfin/dsputil_bfin.h b/libavcodec/bfin/dsputil_bfin.h
index f1a9b32..43ac39c 100644
--- a/libavcodec/bfin/dsputil_bfin.h
+++ b/libavcodec/bfin/dsputil_bfin.h
@@ -3,20 +3,20 @@
  *
  * Copyright (C) 2007 Marc Hoffman <mmh@pleasantst.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -43,7 +43,7 @@
 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 *restrict block, const uint8_t *pixels, int line_size) attribute_l1_text;
+void ff_bfin_get_pixels  (DCTELEM *av_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 8ca490d..e15acb6 100644
--- a/libavcodec/bfin/fdct_bfin.S
+++ b/libavcodec/bfin/fdct_bfin.S
@@ -3,20 +3,20 @@
  *
  * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 /*
@@ -104,14 +104,14 @@
   S3,C3,
 
 -----------------------------------------------------------
-Libav conformance testing results
+FFMPEG conformance testing results
 -----------------------------------------------------------
 dct-test: modified with the following
             dct_error("BFINfdct", 0, ff_bfin_fdct, fdct, test);
 produces the following output:
 
-libavcodec> ./dct-test
-Libav DCT/IDCT test
+root:/u/ffmpeg/bhead/libavcodec> ./dct-test
+ffmpeg DCT/IDCT test
 
     2  -131    -6   -48   -36    33   -83    24
    34    52   -24   -15     5    92    57   143
@@ -123,6 +123,8 @@
   -17   -63   -15    73    50   -91   159   -14
 DCT BFINfdct: err_inf=2 err2=0.16425938 syserr=0.00795000 maxout=2098 blockSumErr=27
 DCT BFINfdct: 92.1 kdct/s
+root:/u/ffmpeg/bhead/libavcodec>
+
 */
 
 #include "config.h"
diff --git a/libavcodec/bfin/idct_bfin.S b/libavcodec/bfin/idct_bfin.S
index b384840..6643009 100644
--- a/libavcodec/bfin/idct_bfin.S
+++ b/libavcodec/bfin/idct_bfin.S
@@ -3,20 +3,20 @@
  *
  * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 /*
@@ -32,15 +32,15 @@
 
 
 -----------------------------------------------------------
-Libav conformance testing results
+FFMPEG conformance testing results
 -----------------------------------------------------------
 
 dct-test: modified with the following
             dct_error("BFINidct", 1, ff_bfin_idct, idct, test);
 produces the following output
 
-libavcodec> ./dct-test -i
-Libav DCT/IDCT test
+root:/u/ffmpeg/bhead/libavcodec> ./dct-test -i
+ffmpeg DCT/IDCT test
 
     8    15    -2    21    24    17     0    10
     2   -10    -5    -5    -3     7   -14    -3
diff --git a/libavcodec/bfin/mathops.h b/libavcodec/bfin/mathops.h
index bbee493..50c0316 100644
--- a/libavcodec/bfin/mathops.h
+++ b/libavcodec/bfin/mathops.h
@@ -3,20 +3,20 @@
  *
  * Copyright (C) 2007 Marc Hoffman <mmhoffm@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #ifndef AVCODEC_BFIN_MATHOPS_H
diff --git a/libavcodec/bfin/mpegvideo_bfin.c b/libavcodec/bfin/mpegvideo_bfin.c
index 8e88d88..f7f3d72 100644
--- a/libavcodec/bfin/mpegvideo_bfin.c
+++ b/libavcodec/bfin/mpegvideo_bfin.c
@@ -3,20 +3,20 @@
  *
  * Copyright (C) 2007 Marc Hoffman <mmh@pleasantst.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -61,8 +61,13 @@
         dc = block[0] = (block[0] + (q >> 1)) / q;
         start_i = 1;
         last_non_zero = 0;
-        bias = s->q_intra_matrix16[qscale][1];
-        qmat = s->q_intra_matrix16[qscale][0];
+        if(n<4){
+            bias = s->q_intra_matrix16[qscale][1];
+            qmat = s->q_intra_matrix16[qscale][0];
+        }else{
+            bias = s->q_chroma_intra_matrix16[qscale][1];
+            qmat = s->q_chroma_intra_matrix16[qscale][0];
+        }
 
     } else {
         start_i = 0;
diff --git a/libavcodec/bfin/pixels_bfin.S b/libavcodec/bfin/pixels_bfin.S
index 45a3ab6..3b987ae 100644
--- a/libavcodec/bfin/pixels_bfin.S
+++ b/libavcodec/bfin/pixels_bfin.S
@@ -2,20 +2,20 @@
  * Blackfin Pixel Operations
  * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "config_bfin.h"
@@ -518,7 +518,7 @@
 
 
 DEFUN(get_pixels,mL1,
-        (DCTELEM *restrict block, const uint8_t *pixels, int line_size)):
+        (DCTELEM *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 bec25a0..6d6ac82 100644
--- a/libavcodec/bfin/vp3_bfin.c
+++ b/libavcodec/bfin/vp3_bfin.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/bfin/vp3_idct_bfin.S b/libavcodec/bfin/vp3_idct_bfin.S
index 2e18f91..83747f9 100644
--- a/libavcodec/bfin/vp3_idct_bfin.S
+++ b/libavcodec/bfin/vp3_idct_bfin.S
@@ -3,20 +3,20 @@
  *
  * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 /*
diff --git a/libavcodec/bgmc.c b/libavcodec/bgmc.c
index 08b1337..e4f937c 100644
--- a/libavcodec/bgmc.c
+++ b/libavcodec/bgmc.c
@@ -2,20 +2,20 @@
  * Block Gilbert-Moore decoder
  * Copyright (c) 2010 Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/bgmc.h b/libavcodec/bgmc.h
index 3d5b490..9e386fd 100644
--- a/libavcodec/bgmc.h
+++ b/libavcodec/bgmc.h
@@ -2,20 +2,20 @@
  * Block Gilbert-Moore decoder
  * Copyright (c) 2010 Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/bink.c b/libavcodec/bink.c
index b6c8c4b..31e4ac3 100644
--- a/libavcodec/bink.c
+++ b/libavcodec/bink.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2009 Konstantin Shishkov
  * Copyright (C) 2011 Peter Ross <pross@xvid.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -858,7 +858,7 @@
                 memset(dctblock, 0, sizeof(*dctblock) * 64);
                 dctblock[0] = binkb_get_value(c, BINKB_SRC_INTRA_DC);
                 qp = binkb_get_value(c, BINKB_SRC_INTRA_Q);
-                read_dct_coeffs(gb, dctblock, bink_scan, binkb_intra_quant, qp);
+                read_dct_coeffs(gb, dctblock, bink_scan, (const int32_t (*)[64])binkb_intra_quant, qp);
                 c->bdsp.idct_put(dst, stride, dctblock);
                 break;
             case 3:
@@ -891,7 +891,7 @@
                 memset(dctblock, 0, sizeof(*dctblock) * 64);
                 dctblock[0] = binkb_get_value(c, BINKB_SRC_INTER_DC);
                 qp = binkb_get_value(c, BINKB_SRC_INTER_Q);
-                read_dct_coeffs(gb, dctblock, bink_scan, binkb_inter_quant, qp);
+                read_dct_coeffs(gb, dctblock, bink_scan, (const int32_t (*)[64])binkb_inter_quant, qp);
                 c->bdsp.idct_add(dst, stride, dctblock);
                 break;
             case 5:
@@ -1128,6 +1128,11 @@
                 xoff = get_value(c, BINK_SRC_X_OFF);
                 yoff = get_value(c, BINK_SRC_Y_OFF);
                 ref = prev + xoff + yoff * stride;
+                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;
+                }
                 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8);
                 memset(dctblock, 0, sizeof(*dctblock) * 64);
                 dctblock[0] = get_value(c, BINK_SRC_INTER_DC);
@@ -1223,41 +1228,28 @@
 static av_cold void binkb_calc_quant(void)
 {
     uint8_t inv_bink_scan[64];
-    double s[64];
+    static const int s[64]={
+        1073741824,1489322693,1402911301,1262586814,1073741824, 843633538, 581104888, 296244703,
+        1489322693,2065749918,1945893874,1751258219,1489322693,1170153332, 806015634, 410903207,
+        1402911301,1945893874,1832991949,1649649171,1402911301,1102260336, 759250125, 387062357,
+        1262586814,1751258219,1649649171,1484645031,1262586814, 992008094, 683307060, 348346918,
+        1073741824,1489322693,1402911301,1262586814,1073741824, 843633538, 581104888, 296244703,
+         843633538,1170153332,1102260336, 992008094, 843633538, 662838617, 456571181, 232757969,
+         581104888, 806015634, 759250125, 683307060, 581104888, 456571181, 314491699, 160326478,
+         296244703, 410903207, 387062357, 348346918, 296244703, 232757969, 160326478,  81733730,
+    };
     int i, j;
-
-    for (j = 0; j < 8; j++) {
-        for (i = 0; i < 8; i++) {
-            if (j && j != 4)
-               if (i && i != 4)
-                   s[j*8 + i] = cos(j * M_PI/16.0) * cos(i * M_PI/16.0) * 2.0;
-               else
-                   s[j*8 + i] = cos(j * M_PI/16.0) * sqrt(2.0);
-            else
-               if (i && i != 4)
-                   s[j*8 + i] = cos(i * M_PI/16.0) * sqrt(2.0);
-               else
-                   s[j*8 + i] = 1.0;
-        }
-    }
-
+#define C (1LL<<30)
     for (i = 0; i < 64; i++)
         inv_bink_scan[bink_scan[i]] = i;
 
     for (j = 0; j < 16; j++) {
         for (i = 0; i < 64; i++) {
             int k = inv_bink_scan[i];
-            if (s[i] == 1.0) {
-                binkb_intra_quant[j][k] = (1L << 12) * binkb_intra_seed[i] *
-                                          binkb_num[j]/binkb_den[j];
-                binkb_inter_quant[j][k] = (1L << 12) * binkb_inter_seed[i] *
-                                          binkb_num[j]/binkb_den[j];
-            } else {
-                binkb_intra_quant[j][k] = (1L << 12) * binkb_intra_seed[i] * s[i] *
-                                          binkb_num[j]/(double)binkb_den[j];
-                binkb_inter_quant[j][k] = (1L << 12) * binkb_inter_seed[i] * s[i] *
-                                          binkb_num[j]/(double)binkb_den[j];
-            }
+            binkb_intra_quant[j][k] = binkb_intra_seed[i] * (int64_t)s[i] *
+                                        binkb_num[j]/(binkb_den[j] * (C>>12));
+            binkb_inter_quant[j][k] = binkb_inter_seed[i] * (int64_t)s[i] *
+                                        binkb_num[j]/(binkb_den[j] * (C>>12));
         }
     }
 }
diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c
index af56526..000895b 100644
--- a/libavcodec/binkaudio.c
+++ b/libavcodec/binkaudio.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2007-2011 Peter Ross (pross@xvid.org)
  * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -83,12 +83,12 @@
         frame_len_bits = 11;
     }
 
-    if (avctx->channels > MAX_CHANNELS) {
-        av_log(avctx, AV_LOG_ERROR, "too many channels: %d\n", avctx->channels);
-        return -1;
+    if (avctx->channels < 1 || avctx->channels > MAX_CHANNELS) {
+        av_log(avctx, AV_LOG_ERROR, "invalid number of channels: %d\n", avctx->channels);
+        return AVERROR_INVALIDDATA;
     }
 
-    s->version_b = avctx->extradata && avctx->extradata[3] == 'b';
+    s->version_b = avctx->extradata_size >= 4 && avctx->extradata[3] == 'b';
 
     if (avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) {
         // audio is already interleaved for the RDFT format variant
diff --git a/libavcodec/binkdata.h b/libavcodec/binkdata.h
index 60f0a59..b9dc1f2 100644
--- a/libavcodec/binkdata.h
+++ b/libavcodec/binkdata.h
@@ -2,20 +2,20 @@
  * Bink video decoder
  * Copyright (C) 2009 Kostya Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/binkdsp.c b/libavcodec/binkdsp.c
index 1f7855b..c751743 100644
--- a/libavcodec/binkdsp.c
+++ b/libavcodec/binkdsp.c
@@ -2,20 +2,20 @@
  * Bink DSP routines
  * Copyright (c) 2009 Kostya Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/bintext.c b/libavcodec/bintext.c
new file mode 100644
index 0000000..9c36b6b
--- /dev/null
+++ b/libavcodec/bintext.c
@@ -0,0 +1,257 @@
+/*
+ * Binary text decoder
+ * eXtended BINary text (XBIN) decoder
+ * iCEDraw File decoder
+ * 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
+ * Binary text decoder
+ * eXtended BINary text (XBIN) decoder
+ * iCEDraw File decoder
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "libavutil/xga_font_data.h"
+#include "avcodec.h"
+#include "cga_data.h"
+#include "bintext.h"
+
+typedef struct XbinContext {
+    AVFrame frame;
+    int palette[16];
+    int flags;
+    int font_height;
+    const uint8_t *font;
+    int x, y;
+} XbinContext;
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+    XbinContext *s = avctx->priv_data;
+    uint8_t *p;
+    int i;
+
+    avctx->pix_fmt = AV_PIX_FMT_PAL8;
+    p = avctx->extradata;
+    if (p) {
+        s->font_height = p[0];
+        s->flags = p[1];
+        p += 2;
+        if(avctx->extradata_size < 2 + (!!(s->flags & BINTEXT_PALETTE))*3*16
+                                     + (!!(s->flags & BINTEXT_FONT))*s->font_height*256) {
+            av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
+            return AVERROR_INVALIDDATA;
+        }
+    } else {
+        s->font_height = 8;
+        s->flags = 0;
+    }
+
+    if ((s->flags & BINTEXT_PALETTE)) {
+        for (i = 0; i < 16; i++) {
+            s->palette[i] = 0xFF000000 | (AV_RB24(p) << 2) | ((AV_RB24(p) >> 4) & 0x30303);
+            p += 3;
+        }
+    } else {
+        for (i = 0; i < 16; i++)
+            s->palette[i] = 0xFF000000 | ff_cga_palette[i];
+    }
+
+    if ((s->flags & BINTEXT_FONT)) {
+        s->font = p;
+    } else {
+        switch(s->font_height) {
+        default:
+            av_log(avctx, AV_LOG_WARNING, "font height %i not supported\n", s->font_height);
+            s->font_height = 8;
+        case 8:
+            s->font = avpriv_cga_font;
+            break;
+        case 16:
+            s->font = avpriv_vga16_font;
+            break;
+        }
+    }
+
+    return 0;
+}
+
+#define DEFAULT_BG_COLOR 0
+av_unused static void hscroll(AVCodecContext *avctx)
+{
+    XbinContext *s = avctx->priv_data;
+    if (s->y < avctx->height - s->font_height) {
+        s->y += s->font_height;
+    } else {
+        memmove(s->frame.data[0], s->frame.data[0] + s->font_height*s->frame.linesize[0],
+            (avctx->height - s->font_height)*s->frame.linesize[0]);
+        memset(s->frame.data[0] + (avctx->height - s->font_height)*s->frame.linesize[0],
+            DEFAULT_BG_COLOR, s->font_height * s->frame.linesize[0]);
+    }
+}
+
+#define FONT_WIDTH 8
+
+/**
+ * Draw character to screen
+ */
+static void draw_char(AVCodecContext *avctx, int c, int a)
+{
+    XbinContext *s = avctx->priv_data;
+    if (s->y > avctx->height - s->font_height)
+        return;
+    ff_draw_pc_font(s->frame.data[0] + s->y * s->frame.linesize[0] + s->x,
+                    s->frame.linesize[0], s->font, s->font_height, c,
+                    a & 0x0F, a >> 4);
+    s->x += FONT_WIDTH;
+    if (s->x > avctx->width - FONT_WIDTH) {
+        s->x = 0;
+        s->y += s->font_height;
+    }
+}
+
+static int decode_frame(AVCodecContext *avctx,
+                            void *data, int *data_size,
+                            AVPacket *avpkt)
+{
+    XbinContext *s = avctx->priv_data;
+    const uint8_t *buf = avpkt->data;
+    int buf_size = avpkt->size;
+    const uint8_t *buf_end = buf+buf_size;
+
+    s->x = s->y = 0;
+    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID |
+                            FF_BUFFER_HINTS_PRESERVE |
+                            FF_BUFFER_HINTS_REUSABLE;
+    if (avctx->reget_buffer(avctx, &s->frame)) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return -1;
+    }
+    s->frame.pict_type           = AV_PICTURE_TYPE_I;
+    s->frame.palette_has_changed = 1;
+    memcpy(s->frame.data[1], s->palette, 16 * 4);
+
+    if (avctx->codec_id == AV_CODEC_ID_XBIN) {
+        while (buf + 2 < buf_end) {
+            int i,c,a;
+            int type  = *buf >> 6;
+            int count = (*buf & 0x3F) + 1;
+            buf++;
+            switch (type) {
+            case 0: //no compression
+                for (i = 0; i < count && buf + 1 < buf_end; i++) {
+                    draw_char(avctx, buf[0], buf[1]);
+                    buf += 2;
+                }
+                break;
+            case 1: //character compression
+                c = *buf++;
+                for (i = 0; i < count && buf < buf_end; i++)
+                    draw_char(avctx, c, *buf++);
+                break;
+            case 2: //attribute compression
+                a = *buf++;
+                for (i = 0; i < count && buf < buf_end; i++)
+                    draw_char(avctx, *buf++, a);
+                break;
+            case 3: //character/attribute compression
+                c = *buf++;
+                a = *buf++;
+                for (i = 0; i < count && buf < buf_end; i++)
+                    draw_char(avctx, c, a);
+                break;
+            }
+        }
+    } else if (avctx->codec_id == AV_CODEC_ID_IDF) {
+        while (buf + 2 < buf_end) {
+            if (AV_RL16(buf) == 1) {
+               int i;
+               if (buf + 6 > buf_end)
+                   break;
+               for (i = 0; i < buf[2]; i++)
+                   draw_char(avctx, buf[4], buf[5]);
+               buf += 6;
+            } else {
+               draw_char(avctx, buf[0], buf[1]);
+               buf += 2;
+            }
+        }
+    } else {
+        while (buf + 1 < buf_end) {
+            draw_char(avctx, buf[0], buf[1]);
+            buf += 2;
+        }
+    }
+
+    *data_size = sizeof(AVFrame);
+    *(AVFrame*)data = s->frame;
+    return buf_size;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+    XbinContext *s = avctx->priv_data;
+
+    if (s->frame.data[0])
+        avctx->release_buffer(avctx, &s->frame);
+
+    return 0;
+}
+
+#if CONFIG_BINTEXT_DECODER
+AVCodec ff_bintext_decoder = {
+    .name           = "bintext",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_BINTEXT,
+    .priv_data_size = sizeof(XbinContext),
+    .init           = decode_init,
+    .close          = decode_end,
+    .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("Binary text"),
+};
+#endif
+#if CONFIG_XBIN_DECODER
+AVCodec ff_xbin_decoder = {
+    .name           = "xbin",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_XBIN,
+    .priv_data_size = sizeof(XbinContext),
+    .init           = decode_init,
+    .close          = decode_end,
+    .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("eXtended BINary text"),
+};
+#endif
+#if CONFIG_IDF_DECODER
+AVCodec ff_idf_decoder = {
+    .name           = "idf",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_IDF,
+    .priv_data_size = sizeof(XbinContext),
+    .init           = decode_init,
+    .close          = decode_end,
+    .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("iCEDraw text"),
+};
+#endif
diff --git a/libavcodec/bintext.h b/libavcodec/bintext.h
new file mode 100644
index 0000000..ea834a0
--- /dev/null
+++ b/libavcodec/bintext.h
@@ -0,0 +1,37 @@
+/*
+ * Binary text decoder
+ * 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
+ * Binary text decoder
+ */
+
+#ifndef AVCODEC_BINTEXT_H
+#define AVCODEC_BINTEXT_H
+
+/* flag values passed between avformat and avcodec;
+ * while these are identical to the XBIN flags, they are are also used
+ * for the BINTEXT and IDF decoders.
+ */
+#define BINTEXT_PALETTE  0x1
+#define BINTEXT_FONT     0x2
+
+#endif /* AVCODEC_BINTEXT_H */
diff --git a/libavcodec/bit_depth_template.c b/libavcodec/bit_depth_template.c
index 9071ec2..6b757fc 100644
--- a/libavcodec/bit_depth_template.c
+++ b/libavcodec/bit_depth_template.c
@@ -70,7 +70,7 @@
 #   define pixel4 uint32_t
 #   define dctcoef int16_t
 
-#   define INIT_CLIP uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+#   define INIT_CLIP
 #   define no_rnd_avg_pixel4 no_rnd_avg32
 #   define    rnd_avg_pixel4    rnd_avg32
 #   define AV_RN2P  AV_RN16
@@ -82,7 +82,7 @@
 #   define PIXEL_SPLAT_X4(x) ((x)*0x01010101U)
 
 #   define av_clip_pixel(a) av_clip_uint8(a)
-#   define CLIP(a) cm[a]
+#   define CLIP(a) av_clip_uint8(a)
 #endif
 
 #define FUNC3(a, b, c)  a ## _ ## b ## c
diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c
index eec2f6d..ce83ee0 100644
--- a/libavcodec/bitstream.c
+++ b/libavcodec/bitstream.c
@@ -6,20 +6,20 @@
  *
  * alternative bitstream reader & writer by Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -28,6 +28,7 @@
  * bitstream api.
  */
 
+#include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "mathops.h"
 #include "get_bits.h"
@@ -106,8 +107,8 @@
         if(use_static)
             abort(); // cannot do anything, init_vlc() is used with too little memory
         vlc->table_allocated += (1 << vlc->bits);
-        vlc->table = av_realloc(vlc->table,
-                                sizeof(VLC_TYPE) * 2 * vlc->table_allocated);
+        vlc->table = av_realloc_f(vlc->table,
+                                  vlc->table_allocated, sizeof(VLC_TYPE) * 2);
         if (!vlc->table)
             return -1;
     }
@@ -158,6 +159,8 @@
     VLC_TYPE (*table)[2];
 
     table_size = 1 << table_nb_bits;
+    if (table_nb_bits > 30)
+       return -1;
     table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC);
     av_dlog(NULL, "new table index=%d size=%d\n", table_index, table_size);
     if (table_index < 0)
@@ -282,7 +285,7 @@
 
     buf = av_malloc((nb_codes+1)*sizeof(VLCcode));
 
-    assert(symbols_size <= 2 || !symbols);
+    av_assert0(symbols_size <= 2 || !symbols);
     j = 0;
 #define COPY(condition)\
     for (i = 0; i < nb_codes; i++) {\
diff --git a/libavcodec/bitstream_filter.c b/libavcodec/bitstream_filter.c
index b2d61da..328a9f6 100644
--- a/libavcodec/bitstream_filter.c
+++ b/libavcodec/bitstream_filter.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/bmp.c b/libavcodec/bmp.c
index b38e056..e8e0072 100644
--- a/libavcodec/bmp.c
+++ b/libavcodec/bmp.c
@@ -2,20 +2,20 @@
  * BMP image format decoder
  * Copyright (c) 2005 Mans Rullgard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -49,6 +49,7 @@
     unsigned int ihsize;
     int i, j, n, linesize;
     uint32_t rgb[3];
+    uint32_t alpha = 0;
     uint8_t *ptr;
     int dsize;
     const uint8_t *buf0 = buf;
@@ -93,7 +94,8 @@
     }
 
     switch(ihsize){
-    case  40: // windib v3
+    case  40: // windib
+    case  56: // windib v3
     case  64: // OS/2 v2
     case 108: // windib v4
     case 124: // windib v5
@@ -116,7 +118,7 @@
 
     depth = bytestream_get_le16(&buf);
 
-    if(ihsize == 40)
+    if (ihsize >= 40)
         comp = bytestream_get_le32(&buf);
     else
         comp = BMP_RGB;
@@ -131,6 +133,7 @@
         rgb[0] = bytestream_get_le32(&buf);
         rgb[1] = bytestream_get_le32(&buf);
         rgb[2] = bytestream_get_le32(&buf);
+        alpha = bytestream_get_le32(&buf);
     }
 
     avctx->width = width;
@@ -141,21 +144,21 @@
     switch(depth){
     case 32:
         if(comp == BMP_BITFIELDS){
-            rgb[0] = (rgb[0] >> 15) & 3;
-            rgb[1] = (rgb[1] >> 15) & 3;
-            rgb[2] = (rgb[2] >> 15) & 3;
-
-            if(rgb[0] + rgb[1] + rgb[2] != 3 ||
-               rgb[0] == rgb[1] || rgb[0] == rgb[2] || rgb[1] == rgb[2]){
-                break;
+            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)
+                avctx->pix_fmt = alpha ? AV_PIX_FMT_BGRA : AV_PIX_FMT_BGR0;
+            else if (rgb[0] == 0x0000FF00 && rgb[1] == 0x00FF0000 && rgb[2] == 0xFF000000)
+                avctx->pix_fmt = alpha ? AV_PIX_FMT_ARGB : AV_PIX_FMT_0RGB;
+            else if (rgb[0] == 0x000000FF && rgb[1] == 0x0000FF00 && rgb[2] == 0x00FF0000)
+                avctx->pix_fmt = alpha ? AV_PIX_FMT_RGBA : AV_PIX_FMT_RGB0;
+            else {
+                av_log(avctx, AV_LOG_ERROR, "Unknown bitfields %0X %0X %0X\n", rgb[0], rgb[1], rgb[2]);
+                return AVERROR(EINVAL);
             }
         } else {
-            rgb[0] = 2;
-            rgb[1] = 1;
-            rgb[2] = 0;
+            avctx->pix_fmt = AV_PIX_FMT_BGRA;
         }
-
-        avctx->pix_fmt = AV_PIX_FMT_BGR24;
         break;
     case 24:
         avctx->pix_fmt = AV_PIX_FMT_BGR24;
@@ -216,7 +219,7 @@
     dsize = buf_size - hsize;
 
     /* Line size in file multiple of 4 */
-    n = ((avctx->width * depth) / 8 + 3) & ~3;
+    n = ((avctx->width * depth + 31) / 8) & ~3;
 
     if(n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8){
         av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
@@ -254,10 +257,10 @@
         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++)
-                ((uint32_t*)p->data[1])[i] = bytestream_get_le24(&buf);
+                ((uint32_t*)p->data[1])[i] = (0xff<<24) | bytestream_get_le24(&buf);
         }else{
             for(i = 0; i < colors; i++)
-                ((uint32_t*)p->data[1])[i] = bytestream_get_le32(&buf);
+                ((uint32_t*)p->data[1])[i] = 0xFFU << 24 | bytestream_get_le32(&buf);
         }
         buf = buf0 + hsize;
     }
@@ -293,6 +296,7 @@
             break;
         case 8:
         case 24:
+        case 32:
             for(i = 0; i < avctx->height; i++){
                 memcpy(ptr, buf, n);
                 buf += n;
@@ -322,23 +326,6 @@
                 ptr += linesize;
             }
             break;
-        case 32:
-            for(i = 0; i < avctx->height; i++){
-                const uint8_t *src = buf;
-                uint8_t *dst = ptr;
-
-                for(j = 0; j < avctx->width; j++){
-                    dst[0] = src[rgb[2]];
-                    dst[1] = src[rgb[1]];
-                    dst[2] = src[rgb[0]];
-                    dst += 3;
-                    src += 4;
-                }
-
-                buf += n;
-                ptr += linesize;
-            }
-            break;
         default:
             av_log(avctx, AV_LOG_ERROR, "BMP decoder is broken\n");
             return -1;
diff --git a/libavcodec/bmp.h b/libavcodec/bmp.h
index ab11523..b24a1fa 100644
--- a/libavcodec/bmp.h
+++ b/libavcodec/bmp.h
@@ -2,20 +2,20 @@
  * internals for BMP codecs
  * Copyright (c) 2005 Mans Rullgard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/bmp_parser.c b/libavcodec/bmp_parser.c
new file mode 100644
index 0000000..06ed367
--- /dev/null
+++ b/libavcodec/bmp_parser.c
@@ -0,0 +1,91 @@
+/*
+ * BMP parser
+ * 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
+ */
+
+/**
+ * @file
+ * BMP parser
+ */
+
+#include "libavutil/bswap.h"
+#include "parser.h"
+
+typedef struct BMPParseContext {
+    ParseContext pc;
+    uint32_t fsize;
+    uint32_t remaining_size;
+} BMPParseContext;
+
+static int bmp_parse(AVCodecParserContext *s, AVCodecContext *avctx,
+                     const uint8_t **poutbuf, int *poutbuf_size,
+                     const uint8_t *buf, int buf_size)
+{
+    BMPParseContext *bpc = s->priv_data;
+    uint64_t state = bpc->pc.state64;
+    int next = END_NOT_FOUND;
+    int i = 0;
+
+    s->pict_type = AV_PICTURE_TYPE_NONE;
+
+    *poutbuf_size = 0;
+    if (buf_size == 0)
+        return 0;
+
+    if (!bpc->pc.frame_start_found) {
+        for (; i < buf_size; i++) {
+            state = (state << 8) | buf[i];
+            if ((state >> 48) == (('B' << 8) | 'M')) {
+                bpc->fsize = av_bswap32(state >> 16);
+                bpc->pc.frame_start_found = 1;
+                if (bpc->fsize > buf_size - i + 7)
+                    bpc->remaining_size = bpc->fsize - buf_size + i - 7;
+                else
+                    next = bpc->fsize + i - 7;
+                break;
+            }
+        }
+        bpc->pc.state64 = state;
+    } else {
+        if (bpc->remaining_size) {
+            i = FFMIN(bpc->remaining_size, buf_size);
+            bpc->remaining_size -= i;
+            if (bpc->remaining_size)
+                goto flush;
+            next = i;
+        }
+    }
+
+flush:
+    if (ff_combine_frame(&bpc->pc, next, &buf, &buf_size) < 0)
+        return buf_size;
+
+    bpc->pc.frame_start_found = 0;
+
+    *poutbuf      = buf;
+    *poutbuf_size = buf_size;
+    return next;
+}
+
+AVCodecParser ff_bmp_parser = {
+    .codec_ids      = { AV_CODEC_ID_BMP },
+    .priv_data_size = sizeof(BMPParseContext),
+    .parser_parse   = bmp_parse,
+    .parser_close   = ff_parse_close,
+};
diff --git a/libavcodec/bmpenc.c b/libavcodec/bmpenc.c
index a798f34..fc36028 100644
--- a/libavcodec/bmpenc.c
+++ b/libavcodec/bmpenc.c
@@ -3,24 +3,25 @@
  * Copyright (c) 2006, 2007 Michel Bardiaux
  * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/imgutils.h"
+#include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "bytestream.h"
 #include "bmp.h"
@@ -37,6 +38,9 @@
     avctx->coded_frame = &s->picture;
 
     switch (avctx->pix_fmt) {
+    case AV_PIX_FMT_BGRA:
+        avctx->bits_per_coded_sample = 32;
+        break;
     case AV_PIX_FMT_BGR24:
         avctx->bits_per_coded_sample = 24;
         break;
@@ -71,6 +75,7 @@
     AVFrame * const p = &s->picture;
     int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize, ret;
     const uint32_t *pal = NULL;
+    uint32_t palette256[256];
     int pad_bytes_per_row, pal_entries = 0, compression = BMP_RGB;
     int bit_count = avctx->bits_per_coded_sample;
     uint8_t *ptr, *buf;
@@ -93,7 +98,10 @@
     case AV_PIX_FMT_RGB4_BYTE:
     case AV_PIX_FMT_BGR4_BYTE:
     case AV_PIX_FMT_GRAY8:
-        ff_set_systematic_pal2((uint32_t*)p->data[1], avctx->pix_fmt);
+        av_assert1(bit_count == 8);
+        ff_set_systematic_pal2(palette256, avctx->pix_fmt);
+        pal = palette256;
+        break;
     case AV_PIX_FMT_PAL8:
         pal = (uint32_t *)p->data[1];
         break;
@@ -112,10 +120,8 @@
 #define SIZE_BITMAPINFOHEADER 40
     hsize = SIZE_BITMAPFILEHEADER + SIZE_BITMAPINFOHEADER + (pal_entries << 2);
     n_bytes = n_bytes_image + hsize;
-    if ((ret = ff_alloc_packet(pkt, n_bytes)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, n_bytes)) < 0)
         return ret;
-    }
     buf = pkt->data;
     bytestream_put_byte(&buf, 'B');                   // BITMAPFILEHEADER.bfType
     bytestream_put_byte(&buf, 'M');                   // do.
@@ -167,8 +173,8 @@
     .init           = bmp_encode_init,
     .encode2        = bmp_encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){
-        AV_PIX_FMT_BGR24,
-        AV_PIX_FMT_RGB555, AV_PIX_FMT_RGB444, AV_PIX_FMT_RGB565,
+        AV_PIX_FMT_BGRA, AV_PIX_FMT_BGR24,
+        AV_PIX_FMT_RGB565, AV_PIX_FMT_RGB555, AV_PIX_FMT_RGB444,
         AV_PIX_FMT_RGB8, AV_PIX_FMT_BGR8, AV_PIX_FMT_RGB4_BYTE, AV_PIX_FMT_BGR4_BYTE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_PAL8,
         AV_PIX_FMT_MONOBLACK,
         AV_PIX_FMT_NONE
diff --git a/libavcodec/bmv.c b/libavcodec/bmv.c
index 876c13f..48e9508 100644
--- a/libavcodec/bmv.c
+++ b/libavcodec/bmv.c
@@ -21,6 +21,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "libavutil/avassert.h"
 
 enum BMVFlags{
     BMV_NOP = 0,
@@ -98,6 +99,8 @@
         }
         if (!(val & 0xC)) {
             for (;;) {
+                if(shift>22)
+                    return -1;
                 if (!read_two_nibbles) {
                     if (src < source || src >= source_end)
                         return -1;
@@ -131,6 +134,7 @@
         }
         advance_mode = val & 1;
         len = (val >> 1) - 1;
+        av_assert0(len>0);
         mode += 1 + advance_mode;
         if (mode >= 4)
             mode -= 3;
@@ -223,7 +227,7 @@
             return AVERROR_INVALIDDATA;
         }
         for (i = 0; i < 256; i++)
-            c->pal[i] = bytestream_get_be24(&c->stream);
+            c->pal[i] = 0xFF << 24 | bytestream_get_be24(&c->stream);
     }
     if (type & BMV_SCROLL) {
         if (c->stream - pkt->data > pkt->size - 2) {
@@ -268,6 +272,11 @@
     c->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
+    if (avctx->width != SCREEN_WIDE || avctx->height != SCREEN_HIGH) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid dimension %dx%d\n", avctx->width, avctx->height);
+        return AVERROR_INVALIDDATA;
+    }
+
     c->pic.reference = 1;
     if (avctx->get_buffer(avctx, &c->pic) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
@@ -365,6 +374,7 @@
     .init           = decode_init,
     .close          = decode_end,
     .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Discworld II BMV video"),
 };
 
diff --git a/libavcodec/bytestream.h b/libavcodec/bytestream.h
index 0f89558..af7f75b 100644
--- a/libavcodec/bytestream.h
+++ b/libavcodec/bytestream.h
@@ -3,20 +3,20 @@
  * copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@free.fr>
  * Copyright (c) 2012 Aneesh Dogra (lionaneesh) <lionaneesh@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -190,6 +190,16 @@
     return (int)(p->buffer - p->buffer_start);
 }
 
+static av_always_inline int bytestream2_size(GetByteContext *g)
+{
+    return (int)(g->buffer_end - g->buffer_start);
+}
+
+static av_always_inline int bytestream2_size_p(PutByteContext *p)
+{
+    return (int)(p->buffer_end - p->buffer_start);
+}
+
 static av_always_inline int bytestream2_seek(GetByteContext *g,
                                              int offset,
                                              int whence)
diff --git a/libavcodec/c93.c b/libavcodec/c93.c
index 07acb26..28135c0 100644
--- a/libavcodec/c93.c
+++ b/libavcodec/c93.c
@@ -2,20 +2,20 @@
  * Interplay C93 video decoder
  * Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -47,6 +47,10 @@
 
 static av_cold int decode_init(AVCodecContext *avctx)
 {
+    C93DecoderContext * const c93 = avctx->priv_data;
+
+    avcodec_get_frame_defaults(&c93->pictures[0]);
+    avcodec_get_frame_defaults(&c93->pictures[1]);
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
     return 0;
 }
@@ -127,7 +131,7 @@
 
     c93->currentpic ^= 1;
 
-    newpic->reference = 1;
+    newpic->reference = 3;
     newpic->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
                          FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
     if (avctx->reget_buffer(avctx, newpic)) {
@@ -231,7 +235,7 @@
     if (b & C93_HAS_PALETTE) {
         uint32_t *palette = (uint32_t *) newpic->data[1];
         for (i = 0; i < 256; i++) {
-            palette[i] = bytestream2_get_be24(&gb);
+            palette[i] = 0xFFU << 24 | bytestream2_get_be24(&gb);
         }
     } else {
         if (oldpic->data[1])
diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c
index bd7d949..385721f 100644
--- a/libavcodec/cabac.c
+++ b/libavcodec/cabac.c
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -73,7 +73,8 @@
 {  6,  8,  9, 11}, {  6,  7,  9, 10}, {  6,  7,  8,  9}, {  2,  2,  2,  2},
 };
 
-static uint8_t h264_mps_state[2 * 64];
+static uint8_t h264_lps_state[2*64];
+static uint8_t h264_mps_state[2*64];
 
 static const uint8_t mps_state[64]= {
   1, 2, 3, 4, 5, 6, 7, 8,
@@ -136,7 +137,7 @@
     c->range= 0x1FE;
 }
 
-void ff_init_cabac_states(CABACContext *c){
+void ff_init_cabac_states(){
     int i, j;
 
     for(i=0; i<64; i++){
@@ -151,10 +152,14 @@
         h264_mps_state[2 * i + 1] = 2 * mps_state[i] + 1;
 
         if( i ){
+            h264_lps_state[2*i+0]=
             ff_h264_mlps_state[128-2*i-1]= 2*lps_state[i]+0;
+            h264_lps_state[2*i+1]=
             ff_h264_mlps_state[128-2*i-2]= 2*lps_state[i]+1;
         }else{
+            h264_lps_state[2*i+0]=
             ff_h264_mlps_state[128-2*i-1]= 1;
+            h264_lps_state[2*i+1]=
             ff_h264_mlps_state[128-2*i-2]= 0;
         }
     }
@@ -204,6 +209,7 @@
     }else{
         c->low += c->range - RangeLPS;
         c->range = RangeLPS;
+        *state= h264_lps_state[*state];
     }
 
     renorm_cabac_encoder(c);
@@ -245,7 +251,7 @@
 
         renorm_cabac_encoder(c);
 
-        assert(c->low <= 0x1FF);
+        av_assert0(c->low <= 0x1FF);
         put_cabac_bit(c, c->low>>9);
         put_bits(&c->pb, 2, ((c->low>>7)&3)|1);
 
@@ -265,10 +271,11 @@
 
     av_lfg_init(&prng, 1);
     ff_init_cabac_encoder(&c, b, SIZE);
-    ff_init_cabac_states(&c);
+    ff_init_cabac_states();
 
     for(i=0; i<SIZE; i++){
-        r[i] = av_lfg_get(&prng) % 7;
+        if(2*i<SIZE) r[i] = av_lfg_get(&prng) % 7;
+        else         r[i] = (i>>8)&1;
     }
 
     for(i=0; i<SIZE; i++){
diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h
index 1f1c943..d4bafe0 100644
--- a/libavcodec/cabac.h
+++ b/libavcodec/cabac.h
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -51,6 +51,6 @@
 
 void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size);
 void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size);
-void ff_init_cabac_states(CABACContext *c);
+void ff_init_cabac_states(void);
 
 #endif /* AVCODEC_CABAC_H */
diff --git a/libavcodec/cabac_functions.h b/libavcodec/cabac_functions.h
index 484ba85..ee70fcf 100644
--- a/libavcodec/cabac_functions.h
+++ b/libavcodec/cabac_functions.h
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -49,8 +49,7 @@
         c->low+= c->bytestream[0]<<1;
 #endif
     c->low -= CABAC_MASK;
-    if (c->bytestream < c->bytestream_end)
-        c->bytestream += CABAC_BITS / 8;
+    c->bytestream += CABAC_BITS / 8;
 }
 
 static inline void renorm_cabac_decoder_once(CABACContext *c){
@@ -77,8 +76,7 @@
 #endif
 
     c->low += x<<i;
-    if (c->bytestream < c->bytestream_end)
-        c->bytestream += CABAC_BITS/8;
+    c->bytestream += CABAC_BITS/8;
 }
 
 static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){
diff --git a/libavcodec/cavs.c b/libavcodec/cavs.c
index a68a628..65e12dd 100644
--- a/libavcodec/cavs.c
+++ b/libavcodec/cavs.c
@@ -2,20 +2,20 @@
  * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
  * Copyright (c) 2006  Stefan Gehrer <stefan.gehrer@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -690,17 +690,17 @@
  */
 void ff_cavs_init_top_lines(AVSContext *h) {
     /* alloc top line of predictors */
-    h->top_qp       = av_malloc( h->mb_width);
-    h->top_mv[0]    = av_malloc((h->mb_width*2+1)*sizeof(cavs_vector));
-    h->top_mv[1]    = av_malloc((h->mb_width*2+1)*sizeof(cavs_vector));
-    h->top_pred_Y   = av_malloc( h->mb_width*2*sizeof(*h->top_pred_Y));
-    h->top_border_y = av_malloc((h->mb_width+1)*16);
-    h->top_border_u = av_malloc( h->mb_width * 10);
-    h->top_border_v = av_malloc( h->mb_width * 10);
+    h->top_qp       = av_mallocz( h->mb_width);
+    h->top_mv[0]    = av_mallocz((h->mb_width*2+1)*sizeof(cavs_vector));
+    h->top_mv[1]    = av_mallocz((h->mb_width*2+1)*sizeof(cavs_vector));
+    h->top_pred_Y   = av_mallocz( h->mb_width*2*sizeof(*h->top_pred_Y));
+    h->top_border_y = av_mallocz((h->mb_width+1)*16);
+    h->top_border_u = av_mallocz( h->mb_width * 10);
+    h->top_border_v = av_mallocz( h->mb_width * 10);
 
     /* alloc space for co-located MVs and types */
-    h->col_mv       = av_malloc( h->mb_width*h->mb_height*4*sizeof(cavs_vector));
-    h->col_type_base = av_malloc(h->mb_width*h->mb_height);
+    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));
 }
 
@@ -739,6 +739,8 @@
 av_cold int ff_cavs_end(AVCodecContext *avctx) {
     AVSContext *h = avctx->priv_data;
 
+    ff_MPV_common_end(&h->s);
+
     av_free(h->top_qp);
     av_free(h->top_mv[0]);
     av_free(h->top_mv[1]);
diff --git a/libavcodec/cavs.h b/libavcodec/cavs.h
index 2e43124..039053d 100644
--- a/libavcodec/cavs.h
+++ b/libavcodec/cavs.h
@@ -2,20 +2,20 @@
  * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
  * Copyright (c) 2006  Stefan Gehrer <stefan.gehrer@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/cavs_parser.c b/libavcodec/cavs_parser.c
index 84f647c..6067a39 100644
--- a/libavcodec/cavs_parser.c
+++ b/libavcodec/cavs_parser.c
@@ -2,20 +2,20 @@
  * Chinese AVS video (AVS1-P2, JiZhun profile) parser.
  * Copyright (c) 2006  Stefan Gehrer <stefan.gehrer@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/cavsdata.c b/libavcodec/cavsdata.c
index 4e4a131..905a306 100644
--- a/libavcodec/cavsdata.c
+++ b/libavcodec/cavsdata.c
@@ -2,20 +2,20 @@
  * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
  * Copyright (c) 2006  Stefan Gehrer <stefan.gehrer@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/cavsdata.h b/libavcodec/cavsdata.h
index b6117e3..67fae3c 100644
--- a/libavcodec/cavsdata.h
+++ b/libavcodec/cavsdata.h
@@ -2,20 +2,20 @@
  * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
  * Copyright (c) 2006  Stefan Gehrer <stefan.gehrer@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c
index b1dd3bd..a923ef5 100644
--- a/libavcodec/cavsdec.c
+++ b/libavcodec/cavsdec.c
@@ -2,20 +2,20 @@
  * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
  * Copyright (c) 2006  Stefan Gehrer <stefan.gehrer@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,7 @@
  * @author Stefan Gehrer <stefan.gehrer@gmx.de>
  */
 
+#include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "golomb.h"
@@ -543,7 +544,8 @@
 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 i, level_code, esc_code, level, run, mask;
+    int i, esc_code, level, mask;
+    unsigned int level_code, run;
     DCTELEM level_buf[65];
     uint8_t run_buf[65];
     DCTELEM *block = h->block;
@@ -552,20 +554,20 @@
         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)
                 r++;
             mask = -(level_code & 1);
             level = (level^mask) - mask;
-        } else if (level_code >= 0) {
+        } else {
             level = r->rltab[level_code][0];
             if(!level) //end of block signal
                 break;
             run   = r->rltab[level_code][1];
             r += r->rltab[level_code][2];
-        } else {
-            break;
         }
         level_buf[i] = level;
         run_buf[i] = run;
@@ -593,7 +595,7 @@
 
     /* get coded block pattern */
     int cbp= get_ue_golomb(&h->s.gb);
-    if(cbp > 63){
+    if(cbp > 63U){
         av_log(h->s.avctx, AV_LOG_ERROR, "illegal inter cbp\n");
         return -1;
     }
@@ -662,7 +664,7 @@
     /* get coded block pattern */
     if(h->pic_type == AV_PICTURE_TYPE_I)
         cbp_code = get_ue_golomb(gb);
-    if(cbp_code > 63){
+    if(cbp_code > 63U){
         av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra cbp\n");
         return -1;
     }
@@ -747,7 +749,7 @@
     h->col_type_base[h->mbidx] = mb_type;
 }
 
-static void 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;
@@ -818,7 +820,11 @@
         }
         break;
     default:
-        assert((mb_type > B_SYM_16X16) && (mb_type < B_8X8));
+        if (mb_type <= B_SYM_16X16) {
+            av_log(h->s.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)
@@ -853,6 +859,8 @@
     if(mb_type != B_SKIP)
         decode_residual_inter(h);
     ff_cavs_filter(h,mb_type);
+
+    return 0;
 }
 
 /*****************************************************************************
@@ -864,6 +872,10 @@
 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);
+
+    if (h->stc >= h->mb_height)
+        return -1;
+
     h->mby = h->stc;
     h->mbidx = h->mby*h->mb_width;
 
@@ -1068,6 +1080,10 @@
         av_log_missing_feature(s, "Width/height changing in CAVS", 0);
         return AVERROR_PATCHWELCOME;
     }
+    if (width <= 0 || height <= 0) {
+        av_log(s, AV_LOG_ERROR, "Dimensions invalid\n");
+        return AVERROR_INVALIDDATA;
+    }
     s->width  = width;
     s->height = height;
 
@@ -1142,6 +1158,8 @@
             *data_size = 0;
             if(!h->got_keyframe)
                 break;
+            if(!h->top_qp)
+                break;
             init_get_bits(&s->gb, buf_ptr, input_size);
             h->stc = stc;
             if(decode_pic(h))
diff --git a/libavcodec/cavsdsp.c b/libavcodec/cavsdsp.c
index 15020a8..a9b136e 100644
--- a/libavcodec/cavsdsp.c
+++ b/libavcodec/cavsdsp.c
@@ -5,20 +5,20 @@
  *
  * Copyright (c) 2006  Stefan Gehrer <stefan.gehrer@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/cavsdsp.h b/libavcodec/cavsdsp.h
index fff9c1c..f6e3e18 100644
--- a/libavcodec/cavsdsp.h
+++ b/libavcodec/cavsdsp.h
@@ -2,20 +2,20 @@
  * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
  * Copyright (c) 2006  Stefan Gehrer <stefan.gehrer@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/cbrt_tablegen.c b/libavcodec/cbrt_tablegen.c
index e92c0f1..e0a8e63 100644
--- a/libavcodec/cbrt_tablegen.c
+++ b/libavcodec/cbrt_tablegen.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/cbrt_tablegen.h b/libavcodec/cbrt_tablegen.h
index 01963a3..a9d34dc 100644
--- a/libavcodec/cbrt_tablegen.h
+++ b/libavcodec/cbrt_tablegen.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c
index 21de07e..91b2d90 100644
--- a/libavcodec/cdgraphics.c
+++ b/libavcodec/cdgraphics.c
@@ -2,20 +2,20 @@
  * CD Graphics Video Decoder
  * Copyright (c) 2009 Michael Tison
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -126,7 +126,7 @@
         r = ((color >> 8) & 0x000F) * 17;
         g = ((color >> 4) & 0x000F) * 17;
         b = ((color     ) & 0x000F) * 17;
-        palette[i + array_offset] = r << 16 | g << 8 | b;
+        palette[i + array_offset] = 0xFF << 24 | r << 16 | g << 8 | b;
     }
     cc->frame.palette_has_changed = 1;
 }
@@ -280,6 +280,10 @@
         av_log(avctx, AV_LOG_ERROR, "buffer too small for decoder\n");
         return AVERROR(EINVAL);
     }
+    if (buf_size > CDG_HEADER_SIZE + CDG_DATA_SIZE) {
+        av_log(avctx, AV_LOG_ERROR, "buffer too big for decoder\n");
+        return AVERROR(EINVAL);
+    }
 
     ret = avctx->reget_buffer(avctx, &cc->frame);
     if (ret) {
diff --git a/libavcodec/cdxl.c b/libavcodec/cdxl.c
index bc4dfe7..1708266 100644
--- a/libavcodec/cdxl.c
+++ b/libavcodec/cdxl.c
@@ -2,31 +2,33 @@
  * CDXL video decoder
  * Copyright (c) 2011-2012 Paul B Mahol
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#define UNCHECKED_BITSTREAM_READER 1
+
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
 #include "get_bits.h"
 
 #define BIT_PLANAR   0x00
-#define BYTE_PLANAR  0x20
-#define CHUNKY       0x40
+#define CHUNKY       0x20
+#define BYTE_PLANAR  0x40
 #define BIT_LINE     0x80
 #define BYTE_LINE    0xC0
 
@@ -64,7 +66,7 @@
         unsigned r   = ((rgb >> 8) & 0xF) * 0x11;
         unsigned g   = ((rgb >> 4) & 0xF) * 0x11;
         unsigned b   =  (rgb       & 0xF) * 0x11;
-        AV_WN32(&new_palette[i], (r << 16) | (g << 8) | b);
+        AV_WN32(&new_palette[i], (0xFFU << 24) | (r << 16) | (g << 8) | b);
     }
 }
 
diff --git a/libavcodec/celp_filters.c b/libavcodec/celp_filters.c
index 381ffa4..a81fd88 100644
--- a/libavcodec/celp_filters.c
+++ b/libavcodec/celp_filters.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2008 Vladimir Voroshilov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,6 +24,7 @@
 
 #include "avcodec.h"
 #include "celp_filters.h"
+#include "libavutil/avassert.h"
 #include "libavutil/common.h"
 
 void ff_celp_convolve_circ(int16_t* fc_out, const int16_t* fc_in,
@@ -104,6 +105,8 @@
     c -= filter_coeffs[1] * filter_coeffs[0];
     c -= filter_coeffs[0] * b;
 
+    av_assert2((filter_length&1)==0 && filter_length>=4);
+
     old_out0 = out[-4];
     old_out1 = out[-3];
     old_out2 = out[-2];
@@ -133,7 +136,7 @@
         out2 -= val * old_out2;
         out3 -= val * old_out3;
 
-        for (i = 5; i <= filter_length; i += 2) {
+        for (i = 5; i < filter_length; i += 2) {
             old_out3 = out[-i];
             val = filter_coeffs[i-1];
 
@@ -205,3 +208,12 @@
             out[n] += filter_coeffs[i-1] * in[n-i];
     }
 }
+
+void ff_celp_filter_init(CELPFContext *c)
+{
+    c->celp_lp_synthesis_filterf        = ff_celp_lp_synthesis_filterf;
+    c->celp_lp_zero_synthesis_filterf   = ff_celp_lp_zero_synthesis_filterf;
+
+    if(HAVE_MIPSFPU)
+        ff_celp_filter_init_mips(c);
+}
diff --git a/libavcodec/celp_filters.h b/libavcodec/celp_filters.h
index c328258..f644ec3 100644
--- a/libavcodec/celp_filters.h
+++ b/libavcodec/celp_filters.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2008 Vladimir Voroshilov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,55 @@
 
 #include <stdint.h>
 
+typedef struct CELPFContext {
+    /**
+     * LP synthesis filter.
+     * @param[out] out pointer to output buffer
+     *        - the array out[-filter_length, -1] must
+     *        contain the previous result of this filter
+     * @param filter_coeffs filter coefficients.
+     * @param in input signal
+     * @param buffer_length amount of data to process
+     * @param filter_length filter length (10 for 10th order LP filter). Must be
+     *                      greater than 4 and even.
+     *
+     * @note Output buffer must contain filter_length samples of past
+     *       speech data before pointer.
+     *
+     * Routine applies 1/A(z) filter to given speech data.
+     */
+    void (*celp_lp_synthesis_filterf)(float *out, const float *filter_coeffs,
+                                      const float *in, int buffer_length,
+                                      int filter_length);
+
+    /**
+     * LP zero synthesis filter.
+     * @param[out] out pointer to output buffer
+     * @param filter_coeffs filter coefficients.
+     * @param in input signal
+     *        - the array in[-filter_length, -1] must
+     *        contain the previous input of this filter
+     * @param buffer_length amount of data to process (should be a multiple of eight)
+     * @param filter_length filter length (10 for 10th order LP filter;
+     *                                      should be a multiple of two)
+     *
+     * @note Output buffer must contain filter_length samples of past
+     *       speech data before pointer.
+     *
+     * Routine applies A(z) filter to given speech data.
+     */
+    void (*celp_lp_zero_synthesis_filterf)(float *out, const float *filter_coeffs,
+                                           const float *in, int buffer_length,
+                                           int filter_length);
+
+}CELPFContext;
+
+/**
+ * Initialize CELPFContext.
+ */
+void ff_celp_filter_init(CELPFContext *c);
+void ff_celp_filter_init_mips(CELPFContext *c);
+
 /**
  * Circularly convolve fixed vector with a phase dispersion impulse
  *        response filter (D.6.2 of G.729 and 6.1.5 of AMR).
diff --git a/libavcodec/celp_math.c b/libavcodec/celp_math.c
index c3d12e9..56dc863 100644
--- a/libavcodec/celp_math.c
+++ b/libavcodec/celp_math.c
@@ -3,28 +3,29 @@
  *
  * Copyright (c) 2008 Vladimir Voroshilov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <inttypes.h>
 #include <limits.h>
-#include <assert.h>
 
+#include "libavutil/avassert.h"
 #include "avcodec.h"
+#include "mathops.h"
 #include "celp_math.h"
 #include "libavutil/common.h"
 
@@ -48,7 +49,7 @@
 {
     unsigned int result= exp2a[power>>10] + 0x10000;
 
-    assert(power <= 0x7fff);
+    av_assert2(power <= 0x7fff);
 
     result= (result<<3) + ((result*exp2b[(power>>5)&31])>>17);
     return result + ((result*(power&31)*89)>>22);
@@ -61,10 +62,17 @@
  */
 static const uint16_t tab_log2[33] =
 {
+#ifdef G729_BITEXACT
+      0,   1455,   2866,   4236,   5568,   6863,   8124,   9352,
+  10549,  11716,  12855,  13967,  15054,  16117,  17156,  18172,
+  19167,  20142,  21097,  22033,  22951,  23852,  24735,  25603,
+  26455,  27291,  28113,  28922,  29716,  30497,  31266,  32023,  32767,
+#else
       4,   1459,   2870,   4240,   5572,   6867,   8127,   9355,
   10552,  11719,  12858,  13971,  15057,  16120,  17158,  18175,
   19170,  20145,  21100,  22036,  22954,  23854,  24738,  25605,
   26457,  27294,  28116,  28924,  29719,  30500,  31269,  32025,  32769,
+#endif
 };
 
 int ff_log2(uint32_t value)
@@ -86,3 +94,33 @@
 
     return (power_int << 15) + value;
 }
+
+int64_t ff_dot_product(const int16_t *a, const int16_t *b, int length)
+{
+    int i;
+    int64_t sum = 0;
+
+    for (i = 0; i < length; i++)
+        sum += MUL16(a[i], b[i]);
+
+    return sum;
+}
+
+float ff_dot_productf(const float* a, const float* b, int length)
+{
+    float sum = 0;
+    int i;
+
+    for(i=0; i<length; i++)
+        sum += a[i] * b[i];
+
+    return sum;
+}
+
+void ff_celp_math_init(CELPMContext *c)
+{
+    c->dot_productf   = ff_dot_productf;
+
+    if(HAVE_MIPSFPU)
+        ff_celp_math_init_mips(c);
+}
diff --git a/libavcodec/celp_math.h b/libavcodec/celp_math.h
index 2fad312..f12f678 100644
--- a/libavcodec/celp_math.h
+++ b/libavcodec/celp_math.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2008 Vladimir Voroshilov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,25 @@
 
 #include <stdint.h>
 
+typedef struct CELPMContext {
+    /**
+     * Return the dot product.
+     * @param a input data array
+     * @param b input data array
+     * @param length number of elements
+     *
+     * @return dot product = sum of elementwise products
+     */
+    float (*dot_productf)(const float* a, const float* b, int length);
+
+}CELPMContext;
+
+/**
+ * Initialize CELPMContext.
+ */
+void ff_celp_math_init(CELPMContext *c);
+void ff_celp_math_init_mips(CELPMContext *c);
+
 /**
  * fixed-point implementation of exp2(x) in [0; 1] domain.
  * @param power argument to exp2, 0 <= power <= 0x7fff
@@ -55,4 +74,24 @@
     else           return value <<  offset;
 }
 
+/**
+ * returns the dot product of 2 int16_t vectors.
+ * @param a input data array
+ * @param b input data array
+ * @param length number of elements
+ *
+ * @return dot product = sum of elementwise products
+ */
+int64_t ff_dot_product(const int16_t *a, const int16_t *b, int length);
+
+/**
+ * Return the dot product.
+ * @param a input data array
+ * @param b input data array
+ * @param length number of elements
+ *
+ * @return dot product = sum of elementwise products
+ */
+float ff_dot_productf(const float* a, const float* b, int length);
+
 #endif /* AVCODEC_CELP_MATH_H */
diff --git a/libavcodec/cga_data.c b/libavcodec/cga_data.c
index 2c63ff2..023a86b 100644
--- a/libavcodec/cga_data.c
+++ b/libavcodec/cga_data.c
@@ -1,435 +1,46 @@
 /*
  * CGA/EGA/VGA ROM data
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
  * @file
  * CGA/EGA/VGA ROM data
+ * @note fonts are in libavutil/xga_font_data.[ch]
  */
 
 #include <stdint.h>
 #include "cga_data.h"
 
-const uint8_t ff_cga_font[2048] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e,
- 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00,
- 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c,
- 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00,
- 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
- 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78,
- 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0,
- 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99,
- 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00,
- 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
- 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78,
- 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff,
- 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
- 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00,
- 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00,
- 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00,
- 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00,
- 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
- 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00,
- 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00,
- 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00,
- 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00,
- 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00,
- 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00,
- 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60,
- 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
- 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00,
- 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00,
- 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00,
- 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00,
- 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00,
- 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
- 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00,
- 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00,
- 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00,
- 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00,
- 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00,
- 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00,
- 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00,
- 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00,
- 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
- 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
- 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
- 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00,
- 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
- 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
- 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
- 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00,
- 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00,
- 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00,
- 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e,
- 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00,
- 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
- 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00,
- 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
- 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00,
- 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00,
- 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00,
- 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
- 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00,
- 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00,
- 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38,
- 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
- 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
- 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
- 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00,
- 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00,
- 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00, 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
- 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
- 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
- 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00,
- 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18,
- 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00, 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30,
- 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7, 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70,
- 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
- 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
- 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00, 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00,
- 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00,
- 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f,
- 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00,
- 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00,
- 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
- 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
- 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36,
- 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
- 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36,
- 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00, 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0,
- 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00,
- 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00,
- 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00,
- 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00,
- 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00,
- 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0,
- 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00,
- 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00,
- 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00,
- 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70,
- 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00,
- 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c,
- 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-const uint8_t ff_vga16_font[4096] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00,
- 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
- 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,
- 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,
- 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
- 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
- 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00,
- 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
- 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00,
- 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
- 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
- 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
 const uint32_t ff_cga_palette[16] = {
-    0x000000, 0x0000AA, 0x00AA00, 0x00AAAA, 0xAA0000, 0xAA00AA, 0xAA5500, 0xAAAAAA,
-    0x555555, 0x5555FF, 0x55FF55, 0x55FFFF, 0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF,
+    0xFF000000, 0xFF0000AA, 0xFF00AA00, 0xFF00AAAA, 0xFFAA0000, 0xFFAA00AA, 0xFFAA5500, 0xFFAAAAAA,
+    0xFF555555, 0xFF5555FF, 0xFF55FF55, 0xFF55FFFF, 0xFFFF5555, 0xFFFF55FF, 0xFFFFFF55, 0xFFFFFFFF,
 };
 
 const uint32_t ff_ega_palette[64] = {
-    0x000000, 0x0000AA, 0x00AA00, 0x00AAAA, 0xAA0000, 0xAA00AA, 0xAAAA00, 0xAAAAAA,
-    0x000055, 0x0000FF, 0x00AA55, 0x00AAFF, 0xAA0055, 0xAA00FF, 0xAAAA55, 0xAAAAFF,
-    0x005500, 0x0055AA, 0x00FF00, 0x00FFAA, 0xAA5500, 0xAA55AA, 0xAAFF00, 0xAAFFAA,
-    0x005555, 0x0055FF, 0x00FF55, 0x00FFFF, 0xAA5555, 0xAA55FF, 0xAAFF55, 0xAAFFFF,
-    0x550000, 0x5500AA, 0x55AA00, 0x55AAAA, 0xFF0000, 0xFF00AA, 0xFFAA00, 0xFFAAAA,
-    0x550055, 0x5500FF, 0x55AA55, 0x55AAFF, 0xFF0055, 0xFF00FF, 0xFFAA55, 0xFFAAFF,
-    0x555500, 0x5555AA, 0x55FF00, 0x55FFAA, 0xFF5500, 0xFF55AA, 0xFFFF00, 0xFFFFAA,
-    0x555555, 0x5555FF, 0x55FF55, 0x55FFFF, 0xFF5555, 0xFF55FF, 0xFFFF55, 0xFFFFFF
+    0xFF000000, 0xFF0000AA, 0xFF00AA00, 0xFF00AAAA, 0xFFAA0000, 0xFFAA00AA, 0xFFAAAA00, 0xFFAAAAAA,
+    0xFF000055, 0xFF0000FF, 0xFF00AA55, 0xFF00AAFF, 0xFFAA0055, 0xFFAA00FF, 0xFFAAAA55, 0xFFAAAAFF,
+    0xFF005500, 0xFF0055AA, 0xFF00FF00, 0xFF00FFAA, 0xFFAA5500, 0xFFAA55AA, 0xFFAAFF00, 0xFFAAFFAA,
+    0xFF005555, 0xFF0055FF, 0xFF00FF55, 0xFF00FFFF, 0xFFAA5555, 0xFFAA55FF, 0xFFAAFF55, 0xFFAAFFFF,
+    0xFF550000, 0xFF5500AA, 0xFF55AA00, 0xFF55AAAA, 0xFFFF0000, 0xFFFF00AA, 0xFFFFAA00, 0xFFFFAAAA,
+    0xFF550055, 0xFF5500FF, 0xFF55AA55, 0xFF55AAFF, 0xFFFF0055, 0xFFFF00FF, 0xFFFFAA55, 0xFFFFAAFF,
+    0xFF555500, 0xFF5555AA, 0xFF55FF00, 0xFF55FFAA, 0xFFFF5500, 0xFFFF55AA, 0xFFFFFF00, 0xFFFFFFAA,
+    0xFF555555, 0xFF5555FF, 0xFF55FF55, 0xFF55FFFF, 0xFFFF5555, 0xFFFF55FF, 0xFFFFFF55, 0xFFFFFFFF
 };
 
 void ff_draw_pc_font(uint8_t *dst, int linesize, const uint8_t *font, int font_height, int ch, int fg, int bg)
diff --git a/libavcodec/cga_data.h b/libavcodec/cga_data.h
index 2149cfd..3f5281a 100644
--- a/libavcodec/cga_data.h
+++ b/libavcodec/cga_data.h
@@ -1,26 +1,27 @@
 /*
  * CGA/EGA/VGA ROM data
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
  * @file
  * CGA/EGA/VGA ROM data
+ * @note fonts are in libavutil/xga_font_data.[ch]
  */
 
 #ifndef AVCODEC_CGA_DATA_H
@@ -28,8 +29,6 @@
 
 #include <stdint.h>
 
-extern const uint8_t ff_cga_font[2048];
-extern const uint8_t ff_vga16_font[4096];
 extern const uint32_t ff_cga_palette[16];
 extern const uint32_t ff_ega_palette[64];
 
diff --git a/libavcodec/chomp_bsf.c b/libavcodec/chomp_bsf.c
index 9ed7496..eaefaaa 100644
--- a/libavcodec/chomp_bsf.c
+++ b/libavcodec/chomp_bsf.c
@@ -2,20 +2,20 @@
  * Chomp bitstream filter
  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c
index e6e2df2..9ae63b7 100644
--- a/libavcodec/cinepak.c
+++ b/libavcodec/cinepak.c
@@ -2,20 +2,20 @@
  * Cinepak Video Decoder
  * Copyright (C) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -361,6 +361,8 @@
 
     num_strips = FFMIN(num_strips, MAX_STRIPS);
 
+    s->frame.key_frame = 0;
+
     for (i=0; i < num_strips; i++) {
         if ((s->data + 12) > eod)
             return AVERROR_INVALIDDATA;
@@ -371,6 +373,9 @@
         s->strips[i].y2 = y0 + AV_RB16 (&s->data[8]);
         s->strips[i].x2 = s->avctx->width;
 
+        if (s->strips[i].id == 0x10)
+            s->frame.key_frame = 1;
+
         strip_size = AV_RB24 (&s->data[1]) - 12;
         if (strip_size < 0)
             return AVERROR_INVALIDDATA;
@@ -413,6 +418,7 @@
         avctx->pix_fmt = AV_PIX_FMT_PAL8;
     }
 
+    avcodec_get_frame_defaults(&s->frame);
     s->frame.data[0] = NULL;
 
     return 0;
@@ -429,7 +435,7 @@
     s->data = buf;
     s->size = buf_size;
 
-    s->frame.reference = 1;
+    s->frame.reference = 3;
     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
                             FF_BUFFER_HINTS_REUSABLE;
     if ((ret = avctx->reget_buffer(avctx, &s->frame))) {
diff --git a/libavcodec/cljr.c b/libavcodec/cljr.c
index 13b4547..2834ff6 100644
--- a/libavcodec/cljr.c
+++ b/libavcodec/cljr.c
@@ -2,20 +2,20 @@
  * Cirrus Logic AccuPak (CLJR) codec
  * Copyright (c) 2003 Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,18 +25,22 @@
  */
 
 #include "avcodec.h"
+#include "libavutil/opt.h"
 #include "get_bits.h"
 #include "internal.h"
 #include "put_bits.h"
 
 typedef struct CLJRContext {
+    AVClass        *avclass;
     AVFrame         picture;
+    int             dither_type;
 } CLJRContext;
 
 static av_cold int common_init(AVCodecContext *avctx)
 {
     CLJRContext * const a = avctx->priv_data;
 
+    avcodec_get_frame_defaults(&a->picture);
     avctx->coded_frame = &a->picture;
 
     return 0;
@@ -63,7 +67,7 @@
         return AVERROR_INVALIDDATA;
     }
 
-    if (buf_size < avctx->height * avctx->width) {
+    if (buf_size / avctx->height < avctx->width) {
         av_log(avctx, AV_LOG_ERROR,
                "Resolution larger than buffer size. Invalid header?\n");
         return AVERROR_INVALIDDATA;
@@ -84,10 +88,10 @@
         uint8_t *cb   = &a->picture.data[1][y * a->picture.linesize[1]];
         uint8_t *cr   = &a->picture.data[2][y * a->picture.linesize[2]];
         for (x = 0; x < avctx->width; x += 4) {
-            luma[3] = get_bits(&gb, 5) << 3;
-            luma[2] = get_bits(&gb, 5) << 3;
-            luma[1] = get_bits(&gb, 5) << 3;
-            luma[0] = get_bits(&gb, 5) << 3;
+            luma[3] = (get_bits(&gb, 5)*33) >> 2;
+            luma[2] = (get_bits(&gb, 5)*33) >> 2;
+            luma[1] = (get_bits(&gb, 5)*33) >> 2;
+            luma[0] = (get_bits(&gb, 5)*33) >> 2;
             luma += 4;
             *(cb++) = get_bits(&gb, 6) << 2;
             *(cr++) = get_bits(&gb, 6) << 2;
@@ -132,13 +136,18 @@
 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         const AVFrame *p, int *got_packet)
 {
+    CLJRContext *a = avctx->priv_data;
     PutBitContext pb;
     int x, y, ret;
+    uint32_t dither= avctx->frame_number;
+    static const uint32_t ordered_dither[2][2] =
+    {
+        { 0x10400000, 0x104F0000 },
+        { 0xCB2A0000, 0xCB250000 },
+    };
 
-    if ((ret = ff_alloc_packet(pkt, 32*avctx->height*avctx->width/4)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, 32*avctx->height*avctx->width/4)) < 0)
         return ret;
-    }
 
     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
     avctx->coded_frame->key_frame = 1;
@@ -150,13 +159,18 @@
         uint8_t *cb   = &p->data[1][y * p->linesize[1]];
         uint8_t *cr   = &p->data[2][y * p->linesize[2]];
         for (x = 0; x < avctx->width; x += 4) {
-            put_bits(&pb, 5, luma[3] >> 3);
-            put_bits(&pb, 5, luma[2] >> 3);
-            put_bits(&pb, 5, luma[1] >> 3);
-            put_bits(&pb, 5, luma[0] >> 3);
+            switch (a->dither_type) {
+            case 0: dither = 0x492A0000;                       break;
+            case 1: dither = dither * 1664525 + 1013904223;    break;
+            case 2: dither = ordered_dither[ y&1 ][ (x>>2)&1 ];break;
+            }
+            put_bits(&pb, 5, (249*(luma[3] +  (dither>>29)   )) >> 11);
+            put_bits(&pb, 5, (249*(luma[2] + ((dither>>26)&7))) >> 11);
+            put_bits(&pb, 5, (249*(luma[1] + ((dither>>23)&7))) >> 11);
+            put_bits(&pb, 5, (249*(luma[0] + ((dither>>20)&7))) >> 11);
             luma += 4;
-            put_bits(&pb, 6, *(cb++) >> 2);
-            put_bits(&pb, 6, *(cr++) >> 2);
+            put_bits(&pb, 6, (253*(*(cb++) + ((dither>>18)&3))) >> 10);
+            put_bits(&pb, 6, (253*(*(cr++) + ((dither>>16)&3))) >> 10);
         }
     }
 
@@ -168,6 +182,20 @@
     return 0;
 }
 
+#define OFFSET(x) offsetof(CLJRContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "dither_type",   "Dither type",   OFFSET(dither_type),        AV_OPT_TYPE_INT, { .i64=1 }, 0, 2, VE},
+    { NULL },
+};
+
+static const AVClass class = {
+    .class_name = "cljr encoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_cljr_encoder = {
     .name           = "cljr",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -178,5 +206,6 @@
     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P,
                                                    AV_PIX_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("Cirrus Logic AccuPak"),
+    .priv_class     = &class,
 };
 #endif
diff --git a/libavcodec/cllc.c b/libavcodec/cllc.c
index 467d819..b588331 100644
--- a/libavcodec/cllc.c
+++ b/libavcodec/cllc.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2012 Derek Buitenhuis
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 818a35e..d1b0b9e 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -1,18 +1,21 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * This table was generated from the long and short names of AVCodecs
+ * please see the respective codec sources for authorship
+ *
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -919,6 +922,7 @@
         .id        = AV_CODEC_ID_TMV,
         .type      = AVMEDIA_TYPE_VIDEO,
         .name      = "tmv",
+        .long_name = NULL_IF_CONFIG_SMALL("8088flex TMV"),
         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
     },
     {
@@ -1156,6 +1160,7 @@
         .id        = AV_CODEC_ID_XBM,
         .type      = AVMEDIA_TYPE_VIDEO,
         .name      = "xbm",
+        .long_name = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"),
         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS,
     },
     {
@@ -1207,6 +1212,105 @@
         .long_name = NULL_IF_CONFIG_SMALL("MS Windows Media Video V9 Screen"),
         .props     = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY,
     },
+    {
+        .id        = AV_CODEC_ID_Y41P,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "y41p",
+        .long_name = NULL_IF_CONFIG_SMALL("Uncompressed YUV 4:1:1 12-bit"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY,
+    },
+    {
+        .id        = AV_CODEC_ID_ESCAPE130,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "escape130",
+        .long_name = NULL_IF_CONFIG_SMALL("Escape 130"),
+    },
+    {
+        .id        = AV_CODEC_ID_EXR,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "exr",
+        .long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY,
+    },
+    {
+        .id        = AV_CODEC_ID_AVRP,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "avrp",
+        .long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY,
+    },
+    {
+        .id        = AV_CODEC_ID_G2M,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "g2m",
+        .long_name = NULL_IF_CONFIG_SMALL("GoToMeeting"),
+    },
+    {
+        .id        = AV_CODEC_ID_AVUI,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "avui",
+        .long_name = NULL_IF_CONFIG_SMALL("AVID Meridien"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY,
+    },
+    {
+        .id        = AV_CODEC_ID_AYUV,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "ayuv",
+        .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed MS 4:4:4:4"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY,
+    },
+    {
+        .id        = AV_CODEC_ID_TARGA_Y216,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "targa_y216",
+        .long_name = NULL_IF_CONFIG_SMALL("Pinnacle TARGA CineWave YUV16"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY,
+    },
+    {
+        .id        = AV_CODEC_ID_V308,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "v308",
+        .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:4:4"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY,
+    },
+    {
+        .id        = AV_CODEC_ID_V408,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "v408",
+        .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed QT 4:4:4:4"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY,
+    },
+    {
+        .id        = AV_CODEC_ID_YUV4,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "yuv4",
+        .long_name = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:2:0"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY,
+    },
+    {
+        .id        = AV_CODEC_ID_SANM,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "sanm",
+        .long_name = NULL_IF_CONFIG_SMALL("LucasArts SMUSH video"),
+    },
+    {
+        .id        = AV_CODEC_ID_PAF_VIDEO,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "paf_video",
+        .long_name = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File Video"),
+    },
+    {
+        .id        = AV_CODEC_ID_AVRN,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "avrn",
+        .long_name = NULL_IF_CONFIG_SMALL("Avid AVI Codec"),
+    },
+    {
+        .id        = AV_CODEC_ID_CPIA,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "cpia",
+        .long_name = NULL_IF_CONFIG_SMALL("CPiA video format"),
+    },
 
     /* various PCM "codecs" */
     {
@@ -2106,12 +2210,55 @@
         .props     = AV_CODEC_PROP_LOSSY,
     },
     {
+        .id        = AV_CODEC_ID_VIMA,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "vima",
+        .long_name = NULL_IF_CONFIG_SMALL("LucasArts VIMA audio"),
+    },
+    {
+        .id        = AV_CODEC_ID_FFWAVESYNTH,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "wavesynth",
+        .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",
+        .long_name = NULL_IF_CONFIG_SMALL("Sonic"),
+    },
+    {
+        .id        = AV_CODEC_ID_SONIC_LS,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "sonicls",
+        .long_name = NULL_IF_CONFIG_SMALL("Sonic lossless"),
+    },
+    {
+        .id        = AV_CODEC_ID_PAF_AUDIO,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "paf_audio",
+        .long_name = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File Audio"),
+    },
+    {
         .id        = AV_CODEC_ID_OPUS,
         .type      = AVMEDIA_TYPE_AUDIO,
         .name      = "opus",
         .long_name = NULL_IF_CONFIG_SMALL("Opus (Opus Interactive Audio Codec)"),
         .props     = AV_CODEC_PROP_LOSSY,
     },
+    {
+        .id        = AV_CODEC_ID_TAK,
+        .type      = AVMEDIA_TYPE_AUDIO,
+        .name      = "tak",
+        .long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"),
+        .props     = AV_CODEC_PROP_LOSSLESS,
+    },
 
     /* subtitle codecs */
     {
@@ -2166,8 +2313,78 @@
         .id        = AV_CODEC_ID_SRT,
         .type      = AVMEDIA_TYPE_SUBTITLE,
         .name      = "srt",
-        .long_name = NULL_IF_CONFIG_SMALL("SubRip Text"),
+        .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle with embedded timing"),
     },
+    {
+        .id        = AV_CODEC_ID_SUBRIP,
+        .type      = AVMEDIA_TYPE_SUBTITLE,
+        .name      = "subrip",
+        .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
+    },
+    {
+        .id        = AV_CODEC_ID_MICRODVD,
+        .type      = AVMEDIA_TYPE_SUBTITLE,
+        .name      = "microdvd",
+        .long_name = NULL_IF_CONFIG_SMALL("MicroDVD subtitle"),
+    },
+    {
+        .id        = AV_CODEC_ID_EIA_608,
+        .type      = AVMEDIA_TYPE_SUBTITLE,
+        .name      = "eia_608",
+        .long_name = NULL_IF_CONFIG_SMALL("EIA-608 closed captions"),
+    },
+    {
+        .id        = AV_CODEC_ID_JACOSUB,
+        .type      = AVMEDIA_TYPE_SUBTITLE,
+        .name      = "jacosub",
+        .long_name = NULL_IF_CONFIG_SMALL("JACOsub subtitle"),
+    },
+    {
+        .id        = AV_CODEC_ID_SAMI,
+        .type      = AVMEDIA_TYPE_SUBTITLE,
+        .name      = "sami",
+        .long_name = NULL_IF_CONFIG_SMALL("SAMI subtitle"),
+    },
+    {
+        .id        = AV_CODEC_ID_REALTEXT,
+        .type      = AVMEDIA_TYPE_SUBTITLE,
+        .name      = "realtext",
+        .long_name = NULL_IF_CONFIG_SMALL("RealText subtitle"),
+    },
+    {
+        .id        = AV_CODEC_ID_SUBVIEWER,
+        .type      = AVMEDIA_TYPE_SUBTITLE,
+        .name      = "subviewer",
+        .long_name = NULL_IF_CONFIG_SMALL("SubViewer subtitle"),
+    },
+    {
+        .id        = AV_CODEC_ID_WEBVTT,
+        .type      = AVMEDIA_TYPE_SUBTITLE,
+        .name      = "webvtt",
+        .long_name = NULL_IF_CONFIG_SMALL("WebVTT subtitle"),
+    },
+    {
+        .id        = AV_CODEC_ID_BINTEXT,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "bintext",
+        .long_name = NULL_IF_CONFIG_SMALL("Binary text"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY,
+    },
+    {
+        .id        = AV_CODEC_ID_XBIN,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "xbin",
+        .long_name = NULL_IF_CONFIG_SMALL("eXtended BINary text"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY,
+    },
+    {
+        .id        = AV_CODEC_ID_IDF,
+        .type      = AVMEDIA_TYPE_VIDEO,
+        .name      = "idf",
+        .long_name = NULL_IF_CONFIG_SMALL("iCEDraw text"),
+        .props     = AV_CODEC_PROP_INTRA_ONLY,
+    },
+
 };
 
 const AVCodecDescriptor *avcodec_descriptor_get(enum AVCodecID id)
diff --git a/libavcodec/cook.c b/libavcodec/cook.c
index c5b17f9..b4d1a37 100644
--- a/libavcodec/cook.c
+++ b/libavcodec/cook.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Sascha Sommer
  * Copyright (c) 2005 Benjamin Larsson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -408,7 +408,7 @@
  * @param category              pointer to the category array
  * @param category_index        pointer to the category_index array
  */
-static void categorize(COOKContext *q, COOKSubpacket *p, int *quant_index_table,
+static void categorize(COOKContext *q, COOKSubpacket *p, const int *quant_index_table,
                        int *category, int *category_index)
 {
     int exp_idx, bias, tmpbias1, tmpbias2, bits_left, num_bits, index, v, i, j;
@@ -647,13 +647,17 @@
     int category_index[128] = { 0 };
     int category[128]       = { 0 };
     int quant_index_table[102];
-    int res;
+    int res, i;
 
     if ((res = decode_envelope(q, p, quant_index_table)) < 0)
         return res;
     q->num_vectors = get_bits(&q->gb, p->log2_numvector_size);
     categorize(q, p, quant_index_table, category, category_index);
     expand_category(q, category, category_index);
+    for (i=0; i<p->total_subbands; i++) {
+        if (category[i] > 7)
+            return AVERROR_INVALIDDATA;
+    }
     decode_vectors(q, p, category, quant_index_table, mlt_buffer);
 
     return 0;
@@ -754,7 +758,7 @@
  * @param decouple_tab      decoupling array
  *
  */
-static void decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab)
+static int decouple_info(COOKContext *q, COOKSubpacket *p, int *decouple_tab)
 {
     int i;
     int vlc    = get_bits1(&q->gb);
@@ -763,14 +767,21 @@
     int length = end - start + 1;
 
     if (start > end)
-        return;
+        return 0;
 
     if (vlc)
         for (i = 0; i < length; i++)
             decouple_tab[start + i] = get_vlc2(&q->gb, p->ccpl.table, p->ccpl.bits, 2);
     else
-        for (i = 0; i < length; i++)
-            decouple_tab[start + i] = get_bits(&q->gb, p->js_vlc_bits);
+        for (i = 0; i < length; i++) {
+            int v = get_bits(&q->gb, p->js_vlc_bits);
+            if (v == (1<<p->js_vlc_bits)-1) {
+                av_log(q->avctx, AV_LOG_ERROR, "decouple value too large\n");
+                return AVERROR_INVALIDDATA;
+            }
+            decouple_tab[start + i] = v;
+        }
+    return 0;
 }
 
 /*
@@ -821,10 +832,10 @@
     /* Make sure the buffers are zeroed out. */
     memset(mlt_buffer1, 0, 1024 * sizeof(*mlt_buffer1));
     memset(mlt_buffer2, 0, 1024 * sizeof(*mlt_buffer2));
-    decouple_info(q, p, decouple_tab);
+    if ((res = decouple_info(q, p, decouple_tab)) < 0)
+        return res;
     if ((res = mono_decode(q, p, decode_buffer)) < 0)
         return res;
-
     /* The two channels are stored interleaved in decode_buffer. */
     for (i = 0; i < p->js_subband_start; i++) {
         for (j = 0; j < SUBBAND_SIZE; j++) {
@@ -1224,6 +1235,11 @@
         q->subpacket[s].gains2.now      = q->subpacket[s].gain_3;
         q->subpacket[s].gains2.previous = q->subpacket[s].gain_4;
 
+        if (q->num_subpackets + q->subpacket[s].num_channels > q->nb_channels) {
+            av_log(avctx, AV_LOG_ERROR, "Too many subpackets %d for channels %d\n", q->num_subpackets, q->nb_channels);
+            return AVERROR_INVALIDDATA;
+        }
+
         q->num_subpackets++;
         s++;
         if (s > MAX_SUBPACKETS) {
diff --git a/libavcodec/cookdata.h b/libavcodec/cookdata.h
index c4c26fa..7b9cba3 100644
--- a/libavcodec/cookdata.h
+++ b/libavcodec/cookdata.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Sascha Sommer
  * Copyright (c) 2005 Benjamin Larsson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/cos_tablegen.c b/libavcodec/cos_tablegen.c
index 8a90857..af9391d 100644
--- a/libavcodec/cos_tablegen.c
+++ b/libavcodec/cos_tablegen.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/cpia.c b/libavcodec/cpia.c
new file mode 100644
index 0000000..26e067a
--- /dev/null
+++ b/libavcodec/cpia.c
@@ -0,0 +1,218 @@
+/*
+ * CPiA video decoder.
+ * Copyright (c) 2010 Hans de Goede <hdegoede@redhat.com>
+ *
+ * This decoder is based on the LGPL code available at
+ * https://v4l4j.googlecode.com/svn/v4l4j/trunk/libvideo/libv4lconvert/cpia1.c
+ *
+ * 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 "get_bits.h"
+
+
+#define FRAME_HEADER_SIZE 64
+#define MAGIC_0         0x19    /**< First header byte */
+#define MAGIC_1         0x68    /**< Second header byte */
+#define SUBSAMPLE_420      0
+#define SUBSAMPLE_422      1
+#define YUVORDER_YUYV      0
+#define YUVORDER_UYVY      1
+#define NOT_COMPRESSED     0
+#define COMPRESSED         1
+#define NO_DECIMATION      0
+#define DECIMATION_ENAB    1
+#define EOL             0xfd    /**< End Of Line marker */
+#define EOI             0xff    /**< End Of Image marker */
+
+
+typedef struct {
+    AVFrame frame;
+} CpiaContext;
+
+
+static int cpia_decode_frame(AVCodecContext* avctx,
+        void* data, int* data_size, AVPacket* avpkt)
+{
+    CpiaContext* const cpia = avctx->priv_data;
+    int i,j,ret;
+
+    uint8_t* const header = avpkt->data;
+    uint8_t* src;
+    int src_size;
+    uint16_t linelength;
+    uint8_t skip;
+
+    AVFrame* const frame = &cpia->frame;
+    uint8_t *y, *u, *v, *y_end, *u_end, *v_end;
+
+    // Check header
+    if ( avpkt->size < FRAME_HEADER_SIZE
+      || header[0] != MAGIC_0 || header[1] != MAGIC_1
+      || (header[17] != SUBSAMPLE_420 && header[17] != SUBSAMPLE_422)
+      || (header[18] != YUVORDER_YUYV && header[18] != YUVORDER_UYVY)
+      || (header[28] != NOT_COMPRESSED && header[28] != COMPRESSED)
+      || (header[29] != NO_DECIMATION && header[29] != DECIMATION_ENAB)
+    ) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid header!\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    // currently unsupported properties
+    if (header[17] == SUBSAMPLE_422) {
+        av_log(avctx, AV_LOG_ERROR, "Unsupported subsample!\n");
+        return AVERROR_PATCHWELCOME;
+    }
+    if (header[18] == YUVORDER_UYVY) {
+        av_log(avctx, AV_LOG_ERROR, "Unsupported YUV byte order!\n");
+        return AVERROR_PATCHWELCOME;
+    }
+    if (header[29] == DECIMATION_ENAB) {
+        av_log(avctx, AV_LOG_ERROR, "Decimation unsupported!\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    src = header + FRAME_HEADER_SIZE;
+    src_size = avpkt->size - FRAME_HEADER_SIZE;
+
+    if (header[28] == NOT_COMPRESSED) {
+        frame->pict_type = AV_PICTURE_TYPE_I;
+        frame->key_frame = 1;
+    } else {
+        frame->pict_type = AV_PICTURE_TYPE_P;
+        frame->key_frame = 0;
+    }
+
+    // Get buffer filled with previous frame
+    if ((ret = avctx->reget_buffer(avctx, frame)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed!\n");
+        return ret;
+    }
+
+
+    for ( i = 0;
+          i < frame->height;
+          i++, src += linelength, src_size -= linelength
+    ) {
+        // Read line length, two byte little endian
+        linelength = AV_RL16(src);
+        src += 2;
+
+        if (src_size < linelength) {
+            frame->decode_error_flags = FF_DECODE_ERROR_INVALID_BITSTREAM;
+            av_log(avctx, AV_LOG_WARNING, "Frame ended enexpectedly!\n");
+            break;
+        }
+        if (src[linelength - 1] != EOL) {
+            frame->decode_error_flags = FF_DECODE_ERROR_INVALID_BITSTREAM;
+            av_log(avctx, AV_LOG_WARNING, "Wrong line length %d or line not terminated properly (found 0x%02x)!\n", linelength, src[linelength - 1]);
+            break;
+        }
+
+        /* Update the data pointers. Y data is on every line.
+         * U and V data on every second line
+         */
+        y = &frame->data[0][i * frame->linesize[0]];
+        u = &frame->data[1][(i >> 1) * frame->linesize[1]];
+        v = &frame->data[2][(i >> 1) * frame->linesize[2]];
+        y_end = y + frame->linesize[0] - 1;
+        u_end = u + frame->linesize[1] - 1;
+        v_end = v + frame->linesize[2] - 1;
+
+        if ((i & 1) && header[17] == SUBSAMPLE_420) {
+            /* We are on a odd line and 420 subsample is used.
+             * On this line only Y values are specified, one per pixel.
+             */
+            for (j = 0; j < linelength - 1; j++) {
+                if (y > y_end) {
+                    frame->decode_error_flags = FF_DECODE_ERROR_INVALID_BITSTREAM;
+                    av_log(avctx, AV_LOG_WARNING, "Decoded data exceeded linesize!\n");
+                    break;
+                }
+                if ((src[j] & 1) && header[28] == COMPRESSED) {
+                    /* It seems that odd lines are always uncompressed, but
+                     * we do it according to specification anyways.
+                     */
+                    skip = src[j] >> 1;
+                    y += skip;
+                } else {
+                    *(y++) = src[j];
+                }
+            }
+        } else if (header[17] == SUBSAMPLE_420) {
+            /* We are on an even line and 420 subsample is used.
+             * On this line each pair of pixels is described by four bytes.
+             */
+            for (j = 0; j < linelength - 4; ) {
+                if (y + 1 > y_end || u > u_end || v > v_end) {
+                    frame->decode_error_flags = FF_DECODE_ERROR_INVALID_BITSTREAM;
+                    av_log(avctx, AV_LOG_WARNING, "Decoded data exceeded linesize!\n");
+                    break;
+                }
+                if ((src[j] & 1) && header[28] == COMPRESSED) {
+                    // Skip amount of pixels and move forward one byte
+                    skip = src[j] >> 1;
+                    y += skip;
+                    u += skip >> 1;
+                    v += skip >> 1;
+                    j++;
+                } else {
+                    // Set image data as specified and move forward 4 bytes
+                    *(y++) = src[j];
+                    *(u++) = src[j+1];
+                    *(y++) = src[j+2];
+                    *(v++) = src[j+3];
+                    j += 4;
+                }
+            }
+        }
+    }
+
+    *data_size = sizeof(AVFrame);
+    *(AVFrame*) data = *frame;
+
+    return avpkt->size;
+}
+
+static av_cold int cpia_decode_init(AVCodecContext *avctx)
+{
+    // output pixel format
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+    /* The default timebase set by the v4l2 demuxer leads to probing which is buggy.
+     * Set some reasonable time_base to skip this.
+     */
+    if (avctx->time_base.num == 1 && avctx->time_base.den == 1000000) {
+        avctx->time_base.num = 1;
+        avctx->time_base.den = 60;
+    }
+
+    return 0;
+}
+
+
+AVCodec ff_cpia_decoder = {
+    .name           = "cpia",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_CPIA,
+    .priv_data_size = sizeof(CpiaContext),
+    .init           = cpia_decode_init,
+    .decode         = cpia_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("CPiA video format"),
+};
diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c
new file mode 100644
index 0000000..334337e
--- /dev/null
+++ b/libavcodec/crystalhd.c
@@ -0,0 +1,1225 @@
+/*
+ * - CrystalHD decoder module -
+ *
+ * Copyright(C) 2010,2011 Philip Langdale <ffmpeg.philipl@overt.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
+ */
+
+/*
+ * - Principles of Operation -
+ *
+ * The CrystalHD decoder operates at the bitstream level - which is an even
+ * higher level than the decoding hardware you typically see in modern GPUs.
+ * This means it has a very simple interface, in principle. You feed demuxed
+ * packets in one end and get decoded picture (fields/frames) out the other.
+ *
+ * Of course, nothing is ever that simple. Due, at the very least, to b-frame
+ * dependencies in the supported formats, the hardware has a delay between
+ * when a packet goes in, and when a picture comes out. Furthermore, this delay
+ * is not just a function of time, but also one of the dependency on additional
+ * frames being fed into the decoder to satisfy the b-frame dependencies.
+ *
+ * As such, a pipeline will build up that is roughly equivalent to the required
+ * DPB for the file being played. If that was all it took, things would still
+ * be simple - so, of course, it isn't.
+ *
+ * The hardware has a way of indicating that a picture is ready to be copied out,
+ * but this is unreliable - and sometimes the attempt will still fail so, based
+ * on testing, the code will wait until 3 pictures are ready before starting
+ * to copy out - and this has the effect of extending the pipeline.
+ *
+ * Finally, while it is tempting to say that once the decoder starts outputting
+ * frames, the software should never fail to return a frame from a decode(),
+ * this is a hard assertion to make, because the stream may switch between
+ * differently encoded content (number of b-frames, interlacing, etc) which
+ * might require a longer pipeline than before. If that happened, you could
+ * deadlock trying to retrieve a frame that can't be decoded without feeding
+ * in additional packets.
+ *
+ * As such, the code will return in the event that a picture cannot be copied
+ * out, leading to an increase in the length of the pipeline. This in turn,
+ * means we have to be sensitive to the time it takes to decode a picture;
+ * We do not want to give up just because the hardware needed a little more
+ * time to prepare the picture! For this reason, there are delays included
+ * in the decode() path that ensure that, under normal conditions, the hardware
+ * will only fail to return a frame if it really needs additional packets to
+ * complete the decoding.
+ *
+ * Finally, to be explicit, we do not want the pipeline to grow without bound
+ * for two reasons: 1) The hardware can only buffer a finite number of packets,
+ * and 2) The client application may not be able to cope with arbitrarily long
+ * delays in the video path relative to the audio path. For example. MPlayer
+ * can only handle a 20 picture delay (although this is arbitrary, and needs
+ * to be extended to fully support the CrystalHD where the delay could be up
+ * to 32 pictures - consider PAFF H.264 content with 16 b-frames).
+ */
+
+/*****************************************************************************
+ * Includes
+ ****************************************************************************/
+
+#define _XOPEN_SOURCE 600
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <libcrystalhd/bc_dts_types.h>
+#include <libcrystalhd/bc_dts_defs.h>
+#include <libcrystalhd/libcrystalhd_if.h>
+
+#include "avcodec.h"
+#include "h264.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
+
+/** Timeout parameter passed to DtsProcOutput() in us */
+#define OUTPUT_PROC_TIMEOUT 50
+/** Step between fake timestamps passed to hardware in units of 100ns */
+#define TIMESTAMP_UNIT 100000
+/** Initial value in us of the wait in decode() */
+#define BASE_WAIT 10000
+/** Increment in us to adjust wait in decode() */
+#define WAIT_UNIT 1000
+
+
+/*****************************************************************************
+ * Module private data
+ ****************************************************************************/
+
+typedef enum {
+    RET_ERROR           = -1,
+    RET_OK              = 0,
+    RET_COPY_AGAIN      = 1,
+    RET_SKIP_NEXT_COPY  = 2,
+    RET_COPY_NEXT_FIELD = 3,
+} CopyRet;
+
+typedef struct OpaqueList {
+    struct OpaqueList *next;
+    uint64_t fake_timestamp;
+    uint64_t reordered_opaque;
+    uint8_t pic_type;
+} OpaqueList;
+
+typedef struct {
+    AVClass *av_class;
+    AVCodecContext *avctx;
+    AVFrame pic;
+    HANDLE dev;
+
+    uint8_t *orig_extradata;
+    uint32_t orig_extradata_size;
+
+    AVBitStreamFilterContext *bsfc;
+    AVCodecParserContext *parser;
+
+    uint8_t is_70012;
+    uint8_t *sps_pps_buf;
+    uint32_t sps_pps_size;
+    uint8_t is_nal;
+    uint8_t output_ready;
+    uint8_t need_second_field;
+    uint8_t skip_next_output;
+    uint64_t decode_wait;
+
+    uint64_t last_picture;
+
+    OpaqueList *head;
+    OpaqueList *tail;
+
+    /* Options */
+    uint32_t sWidth;
+    uint8_t bframe_bug;
+} CHDContext;
+
+static const AVOption options[] = {
+    { "crystalhd_downscale_width",
+      "Turn on downscaling to the specified width",
+      offsetof(CHDContext, sWidth),
+      AV_OPT_TYPE_INT, 0, 0, UINT32_MAX,
+      AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, },
+    { NULL, },
+};
+
+
+/*****************************************************************************
+ * Helper functions
+ ****************************************************************************/
+
+static inline BC_MEDIA_SUBTYPE id2subtype(CHDContext *priv, enum AVCodecID id)
+{
+    switch (id) {
+    case AV_CODEC_ID_MPEG4:
+        return BC_MSUBTYPE_DIVX;
+    case AV_CODEC_ID_MSMPEG4V3:
+        return BC_MSUBTYPE_DIVX311;
+    case AV_CODEC_ID_MPEG2VIDEO:
+        return BC_MSUBTYPE_MPEG2VIDEO;
+    case AV_CODEC_ID_VC1:
+        return BC_MSUBTYPE_VC1;
+    case AV_CODEC_ID_WMV3:
+        return BC_MSUBTYPE_WMV3;
+    case AV_CODEC_ID_H264:
+        return priv->is_nal ? BC_MSUBTYPE_AVC1 : BC_MSUBTYPE_H264;
+    default:
+        return BC_MSUBTYPE_INVALID;
+    }
+}
+
+static inline void print_frame_info(CHDContext *priv, BC_DTS_PROC_OUT *output)
+{
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tYBuffSz: %u\n", output->YbuffSz);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tYBuffDoneSz: %u\n",
+           output->YBuffDoneSz);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tUVBuffDoneSz: %u\n",
+           output->UVBuffDoneSz);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tTimestamp: %"PRIu64"\n",
+           output->PicInfo.timeStamp);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tPicture Number: %u\n",
+           output->PicInfo.picture_number);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tWidth: %u\n",
+           output->PicInfo.width);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tHeight: %u\n",
+           output->PicInfo.height);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tChroma: 0x%03x\n",
+           output->PicInfo.chroma_format);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tPulldown: %u\n",
+           output->PicInfo.pulldown);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tFlags: 0x%08x\n",
+           output->PicInfo.flags);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tFrame Rate/Res: %u\n",
+           output->PicInfo.frame_rate);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tAspect Ratio: %u\n",
+           output->PicInfo.aspect_ratio);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tColor Primaries: %u\n",
+           output->PicInfo.colour_primaries);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tMetaData: %u\n",
+           output->PicInfo.picture_meta_payload);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tSession Number: %u\n",
+           output->PicInfo.sess_num);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tycom: %u\n",
+           output->PicInfo.ycom);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tCustom Aspect: %u\n",
+           output->PicInfo.custom_aspect_ratio_width_height);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tFrames to Drop: %u\n",
+           output->PicInfo.n_drop);
+    av_log(priv->avctx, AV_LOG_VERBOSE, "\tH264 Valid Fields: 0x%08x\n",
+           output->PicInfo.other.h264.valid);
+}
+
+
+/*****************************************************************************
+ * OpaqueList functions
+ ****************************************************************************/
+
+static uint64_t opaque_list_push(CHDContext *priv, uint64_t reordered_opaque,
+                                 uint8_t pic_type)
+{
+    OpaqueList *newNode = av_mallocz(sizeof (OpaqueList));
+    if (!newNode) {
+        av_log(priv->avctx, AV_LOG_ERROR,
+               "Unable to allocate new node in OpaqueList.\n");
+        return 0;
+    }
+    if (!priv->head) {
+        newNode->fake_timestamp = TIMESTAMP_UNIT;
+        priv->head              = newNode;
+    } else {
+        newNode->fake_timestamp = priv->tail->fake_timestamp + TIMESTAMP_UNIT;
+        priv->tail->next        = newNode;
+    }
+    priv->tail = newNode;
+    newNode->reordered_opaque = reordered_opaque;
+    newNode->pic_type = pic_type;
+
+    return newNode->fake_timestamp;
+}
+
+/*
+ * The OpaqueList is built in decode order, while elements will be removed
+ * in presentation order. If frames are reordered, this means we must be
+ * able to remove elements that are not the first element.
+ *
+ * Returned node must be freed by caller.
+ */
+static OpaqueList *opaque_list_pop(CHDContext *priv, uint64_t fake_timestamp)
+{
+    OpaqueList *node = priv->head;
+
+    if (!priv->head) {
+        av_log(priv->avctx, AV_LOG_ERROR,
+               "CrystalHD: Attempted to query non-existent timestamps.\n");
+        return NULL;
+    }
+
+    /*
+     * The first element is special-cased because we have to manipulate
+     * the head pointer rather than the previous element in the list.
+     */
+    if (priv->head->fake_timestamp == fake_timestamp) {
+        priv->head = node->next;
+
+        if (!priv->head->next)
+            priv->tail = priv->head;
+
+        node->next = NULL;
+        return node;
+    }
+
+    /*
+     * The list is processed at arm's length so that we have the
+     * previous element available to rewrite its next pointer.
+     */
+    while (node->next) {
+        OpaqueList *current = node->next;
+        if (current->fake_timestamp == fake_timestamp) {
+            node->next = current->next;
+
+            if (!node->next)
+               priv->tail = node;
+
+            current->next = NULL;
+            return current;
+        } else {
+            node = current;
+        }
+    }
+
+    av_log(priv->avctx, AV_LOG_VERBOSE,
+           "CrystalHD: Couldn't match fake_timestamp.\n");
+    return NULL;
+}
+
+
+/*****************************************************************************
+ * Video decoder API function definitions
+ ****************************************************************************/
+
+static void flush(AVCodecContext *avctx)
+{
+    CHDContext *priv = avctx->priv_data;
+
+    avctx->has_b_frames     = 0;
+    priv->last_picture      = -1;
+    priv->output_ready      = 0;
+    priv->need_second_field = 0;
+    priv->skip_next_output  = 0;
+    priv->decode_wait       = BASE_WAIT;
+
+    if (priv->pic.data[0])
+        avctx->release_buffer(avctx, &priv->pic);
+
+    /* Flush mode 4 flushes all software and hardware buffers. */
+    DtsFlushInput(priv->dev, 4);
+}
+
+
+static av_cold int uninit(AVCodecContext *avctx)
+{
+    CHDContext *priv = avctx->priv_data;
+    HANDLE device;
+
+    device = priv->dev;
+    DtsStopDecoder(device);
+    DtsCloseDecoder(device);
+    DtsDeviceClose(device);
+
+    /*
+     * Restore original extradata, so that if the decoder is
+     * reinitialised, the bitstream detection and filtering
+     * will work as expected.
+     */
+    if (priv->orig_extradata) {
+        av_free(avctx->extradata);
+        avctx->extradata = priv->orig_extradata;
+        avctx->extradata_size = priv->orig_extradata_size;
+        priv->orig_extradata = NULL;
+        priv->orig_extradata_size = 0;
+    }
+
+    av_parser_close(priv->parser);
+    if (priv->bsfc) {
+        av_bitstream_filter_close(priv->bsfc);
+    }
+
+    av_free(priv->sps_pps_buf);
+
+    if (priv->pic.data[0])
+        avctx->release_buffer(avctx, &priv->pic);
+
+    if (priv->head) {
+       OpaqueList *node = priv->head;
+       while (node) {
+          OpaqueList *next = node->next;
+          av_free(node);
+          node = next;
+       }
+    }
+
+    return 0;
+}
+
+
+static av_cold int init(AVCodecContext *avctx)
+{
+    CHDContext* priv;
+    BC_STATUS ret;
+    BC_INFO_CRYSTAL version;
+    BC_INPUT_FORMAT format = {
+        .FGTEnable   = FALSE,
+        .Progressive = TRUE,
+        .OptFlags    = 0x80000000 | vdecFrameRate59_94 | 0x40,
+        .width       = avctx->width,
+        .height      = avctx->height,
+    };
+
+    BC_MEDIA_SUBTYPE subtype;
+
+    uint32_t mode = DTS_PLAYBACK_MODE |
+                    DTS_LOAD_FILE_PLAY_FW |
+                    DTS_SKIP_TX_CHK_CPB |
+                    DTS_PLAYBACK_DROP_RPT_MODE |
+                    DTS_SINGLE_THREADED_MODE |
+                    DTS_DFLT_RESOLUTION(vdecRESOLUTION_1080p23_976);
+
+    av_log(avctx, AV_LOG_VERBOSE, "CrystalHD Init for %s\n",
+           avctx->codec->name);
+
+    avctx->pix_fmt = AV_PIX_FMT_YUYV422;
+
+    /* Initialize the library */
+    priv               = avctx->priv_data;
+    priv->avctx        = avctx;
+    priv->is_nal       = avctx->extradata_size > 0 && *(avctx->extradata) == 1;
+    priv->last_picture = -1;
+    priv->decode_wait  = BASE_WAIT;
+
+    subtype = id2subtype(priv, avctx->codec->id);
+    switch (subtype) {
+    case BC_MSUBTYPE_AVC1:
+        {
+            uint8_t *dummy_p;
+            int dummy_int;
+
+            /* Back up the extradata so it can be restored at close time. */
+            priv->orig_extradata = av_malloc(avctx->extradata_size);
+            if (!priv->orig_extradata) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Failed to allocate copy of extradata\n");
+                return AVERROR(ENOMEM);
+            }
+            priv->orig_extradata_size = avctx->extradata_size;
+            memcpy(priv->orig_extradata, avctx->extradata, avctx->extradata_size);
+
+            priv->bsfc = av_bitstream_filter_init("h264_mp4toannexb");
+            if (!priv->bsfc) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "Cannot open the h264_mp4toannexb BSF!\n");
+                return AVERROR_BSF_NOT_FOUND;
+            }
+            av_bitstream_filter_filter(priv->bsfc, avctx, NULL, &dummy_p,
+                                       &dummy_int, NULL, 0, 0);
+        }
+        subtype = BC_MSUBTYPE_H264;
+        // Fall-through
+    case BC_MSUBTYPE_H264:
+        format.startCodeSz = 4;
+        // Fall-through
+    case BC_MSUBTYPE_VC1:
+    case BC_MSUBTYPE_WVC1:
+    case BC_MSUBTYPE_WMV3:
+    case BC_MSUBTYPE_WMVA:
+    case BC_MSUBTYPE_MPEG2VIDEO:
+    case BC_MSUBTYPE_DIVX:
+    case BC_MSUBTYPE_DIVX311:
+        format.pMetaData  = avctx->extradata;
+        format.metaDataSz = avctx->extradata_size;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "CrystalHD: Unknown codec name\n");
+        return AVERROR(EINVAL);
+    }
+    format.mSubtype = subtype;
+
+    if (priv->sWidth) {
+        format.bEnableScaling = 1;
+        format.ScalingParams.sWidth = priv->sWidth;
+    }
+
+    /* Get a decoder instance */
+    av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: starting up\n");
+    // Initialize the Link and Decoder devices
+    ret = DtsDeviceOpen(&priv->dev, mode);
+    if (ret != BC_STS_SUCCESS) {
+        av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: DtsDeviceOpen failed\n");
+        goto fail;
+    }
+
+    ret = DtsCrystalHDVersion(priv->dev, &version);
+    if (ret != BC_STS_SUCCESS) {
+        av_log(avctx, AV_LOG_VERBOSE,
+               "CrystalHD: DtsCrystalHDVersion failed\n");
+        goto fail;
+    }
+    priv->is_70012 = version.device == 0;
+
+    if (priv->is_70012 &&
+        (subtype == BC_MSUBTYPE_DIVX || subtype == BC_MSUBTYPE_DIVX311)) {
+        av_log(avctx, AV_LOG_VERBOSE,
+               "CrystalHD: BCM70012 doesn't support MPEG4-ASP/DivX/Xvid\n");
+        goto fail;
+    }
+
+    ret = DtsSetInputFormat(priv->dev, &format);
+    if (ret != BC_STS_SUCCESS) {
+        av_log(avctx, AV_LOG_ERROR, "CrystalHD: SetInputFormat failed\n");
+        goto fail;
+    }
+
+    ret = DtsOpenDecoder(priv->dev, BC_STREAM_TYPE_ES);
+    if (ret != BC_STS_SUCCESS) {
+        av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsOpenDecoder failed\n");
+        goto fail;
+    }
+
+    ret = DtsSetColorSpace(priv->dev, OUTPUT_MODE422_YUY2);
+    if (ret != BC_STS_SUCCESS) {
+        av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsSetColorSpace failed\n");
+        goto fail;
+    }
+    ret = DtsStartDecoder(priv->dev);
+    if (ret != BC_STS_SUCCESS) {
+        av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsStartDecoder failed\n");
+        goto fail;
+    }
+    ret = DtsStartCapture(priv->dev);
+    if (ret != BC_STS_SUCCESS) {
+        av_log(avctx, AV_LOG_ERROR, "CrystalHD: DtsStartCapture failed\n");
+        goto fail;
+    }
+
+    if (avctx->codec->id == AV_CODEC_ID_H264) {
+        priv->parser = av_parser_init(avctx->codec->id);
+        if (!priv->parser)
+            av_log(avctx, AV_LOG_WARNING,
+                   "Cannot open the h.264 parser! Interlaced h.264 content "
+                   "will not be detected reliably.\n");
+        priv->parser->flags = PARSER_FLAG_COMPLETE_FRAMES;
+    }
+    av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Init complete.\n");
+
+    return 0;
+
+ fail:
+    uninit(avctx);
+    return -1;
+}
+
+
+static inline CopyRet copy_frame(AVCodecContext *avctx,
+                                 BC_DTS_PROC_OUT *output,
+                                 void *data, int *data_size)
+{
+    BC_STATUS ret;
+    BC_DTS_STATUS decoder_status = { 0, };
+    uint8_t trust_interlaced;
+    uint8_t interlaced;
+
+    CHDContext *priv = avctx->priv_data;
+    int64_t pkt_pts  = AV_NOPTS_VALUE;
+    uint8_t pic_type = 0;
+
+    uint8_t bottom_field = (output->PicInfo.flags & VDEC_FLAG_BOTTOMFIELD) ==
+                           VDEC_FLAG_BOTTOMFIELD;
+    uint8_t bottom_first = !!(output->PicInfo.flags & VDEC_FLAG_BOTTOM_FIRST);
+
+    int width    = output->PicInfo.width;
+    int height   = output->PicInfo.height;
+    int bwidth;
+    uint8_t *src = output->Ybuff;
+    int sStride;
+    uint8_t *dst;
+    int dStride;
+
+    if (output->PicInfo.timeStamp != 0) {
+        OpaqueList *node = opaque_list_pop(priv, output->PicInfo.timeStamp);
+        if (node) {
+            pkt_pts = node->reordered_opaque;
+            pic_type = node->pic_type;
+            av_free(node);
+        } else {
+            /*
+             * We will encounter a situation where a timestamp cannot be
+             * popped if a second field is being returned. In this case,
+             * each field has the same timestamp and the first one will
+             * cause it to be popped. To keep subsequent calculations
+             * simple, pic_type should be set a FIELD value - doesn't
+             * matter which, but I chose BOTTOM.
+             */
+            pic_type = PICT_BOTTOM_FIELD;
+        }
+        av_log(avctx, AV_LOG_VERBOSE, "output \"pts\": %"PRIu64"\n",
+               output->PicInfo.timeStamp);
+        av_log(avctx, AV_LOG_VERBOSE, "output picture type %d\n",
+               pic_type);
+    }
+
+    ret = DtsGetDriverStatus(priv->dev, &decoder_status);
+    if (ret != BC_STS_SUCCESS) {
+        av_log(avctx, AV_LOG_ERROR,
+               "CrystalHD: GetDriverStatus failed: %u\n", ret);
+       return RET_ERROR;
+    }
+
+    /*
+     * For most content, we can trust the interlaced flag returned
+     * by the hardware, but sometimes we can't. These are the
+     * conditions under which we can trust the flag:
+     *
+     * 1) It's not h.264 content
+     * 2) The UNKNOWN_SRC flag is not set
+     * 3) We know we're expecting a second field
+     * 4) The hardware reports this picture and the next picture
+     *    have the same picture number.
+     *
+     * Note that there can still be interlaced content that will
+     * fail this check, if the hardware hasn't decoded the next
+     * picture or if there is a corruption in the stream. (In either
+     * case a 0 will be returned for the next picture number)
+     */
+    trust_interlaced = avctx->codec->id != AV_CODEC_ID_H264 ||
+                       !(output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) ||
+                       priv->need_second_field ||
+                       (decoder_status.picNumFlags & ~0x40000000) ==
+                       output->PicInfo.picture_number;
+
+    /*
+     * If we got a false negative for trust_interlaced on the first field,
+     * we will realise our mistake here when we see that the picture number is that
+     * of the previous picture. We cannot recover the frame and should discard the
+     * second field to keep the correct number of output frames.
+     */
+    if (output->PicInfo.picture_number == priv->last_picture && !priv->need_second_field) {
+        av_log(avctx, AV_LOG_WARNING,
+               "Incorrectly guessed progressive frame. Discarding second field\n");
+        /* Returning without providing a picture. */
+        return RET_OK;
+    }
+
+    interlaced = (output->PicInfo.flags & VDEC_FLAG_INTERLACED_SRC) &&
+                 trust_interlaced;
+
+    if (!trust_interlaced && (decoder_status.picNumFlags & ~0x40000000) == 0) {
+        av_log(avctx, AV_LOG_VERBOSE,
+               "Next picture number unknown. Assuming progressive frame.\n");
+    }
+
+    av_log(avctx, AV_LOG_VERBOSE, "Interlaced state: %d | trust_interlaced %d\n",
+           interlaced, trust_interlaced);
+
+    if (priv->pic.data[0] && !priv->need_second_field)
+        avctx->release_buffer(avctx, &priv->pic);
+
+    priv->need_second_field = interlaced && !priv->need_second_field;
+
+    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) {
+            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+            return RET_ERROR;
+        }
+    }
+
+    bwidth = av_image_get_linesize(avctx->pix_fmt, width, 0);
+    if (priv->is_70012) {
+        int pStride;
+
+        if (width <= 720)
+            pStride = 720;
+        else if (width <= 1280)
+            pStride = 1280;
+        else pStride = 1920;
+        sStride = av_image_get_linesize(avctx->pix_fmt, pStride, 0);
+    } else {
+        sStride = bwidth;
+    }
+
+    dStride = priv->pic.linesize[0];
+    dst     = priv->pic.data[0];
+
+    av_log(priv->avctx, AV_LOG_VERBOSE, "CrystalHD: Copying out frame\n");
+
+    if (interlaced) {
+        int dY = 0;
+        int sY = 0;
+
+        height /= 2;
+        if (bottom_field) {
+            av_log(priv->avctx, AV_LOG_VERBOSE, "Interlaced: bottom field\n");
+            dY = 1;
+        } else {
+            av_log(priv->avctx, AV_LOG_VERBOSE, "Interlaced: top field\n");
+            dY = 0;
+        }
+
+        for (sY = 0; sY < height; dY++, sY++) {
+            memcpy(&(dst[dY * dStride]), &(src[sY * sStride]), bwidth);
+            dY++;
+        }
+    } else {
+        av_image_copy_plane(dst, dStride, src, sStride, bwidth, height);
+    }
+
+    priv->pic.interlaced_frame = interlaced;
+    if (interlaced)
+        priv->pic.top_field_first = !bottom_first;
+
+    priv->pic.pkt_pts = pkt_pts;
+
+    if (!priv->need_second_field) {
+        *data_size       = sizeof(AVFrame);
+        *(AVFrame *)data = priv->pic;
+    }
+
+    /*
+     * Two types of PAFF content have been observed. One form causes the
+     * hardware to return a field pair and the other individual fields,
+     * even though the input is always individual fields. We must skip
+     * copying on the next decode() call to maintain pipeline length in
+     * the first case.
+     */
+    if (!interlaced && (output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) &&
+        (pic_type == PICT_TOP_FIELD || pic_type == PICT_BOTTOM_FIELD)) {
+        av_log(priv->avctx, AV_LOG_VERBOSE, "Fieldpair from two packets.\n");
+        return RET_SKIP_NEXT_COPY;
+    }
+
+    /*
+     * The logic here is purely based on empirical testing with samples.
+     * If we need a second field, it could come from a second input packet,
+     * or it could come from the same field-pair input packet at the current
+     * field. In the first case, we should return and wait for the next time
+     * round to get the second field, while in the second case, we should
+     * ask the decoder for it immediately.
+     *
+     * Testing has shown that we are dealing with the fieldpair -> two fields
+     * case if the VDEC_FLAG_UNKNOWN_SRC is not set or if the input picture
+     * type was PICT_FRAME (in this second case, the flag might still be set)
+     */
+    return priv->need_second_field &&
+           (!(output->PicInfo.flags & VDEC_FLAG_UNKNOWN_SRC) ||
+            pic_type == PICT_FRAME) ?
+           RET_COPY_NEXT_FIELD : RET_OK;
+}
+
+
+static inline CopyRet receive_frame(AVCodecContext *avctx,
+                                    void *data, int *data_size)
+{
+    BC_STATUS ret;
+    BC_DTS_PROC_OUT output = {
+        .PicInfo.width  = avctx->width,
+        .PicInfo.height = avctx->height,
+    };
+    CHDContext *priv = avctx->priv_data;
+    HANDLE dev       = priv->dev;
+
+    *data_size = 0;
+
+    // Request decoded data from the driver
+    ret = DtsProcOutputNoCopy(dev, OUTPUT_PROC_TIMEOUT, &output);
+    if (ret == BC_STS_FMT_CHANGE) {
+        av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Initial format change\n");
+        avctx->width  = output.PicInfo.width;
+        avctx->height = output.PicInfo.height;
+        switch ( output.PicInfo.aspect_ratio ) {
+        case vdecAspectRatioSquare:
+            avctx->sample_aspect_ratio = (AVRational) {  1,  1};
+            break;
+        case vdecAspectRatio12_11:
+            avctx->sample_aspect_ratio = (AVRational) { 12, 11};
+            break;
+        case vdecAspectRatio10_11:
+            avctx->sample_aspect_ratio = (AVRational) { 10, 11};
+            break;
+        case vdecAspectRatio16_11:
+            avctx->sample_aspect_ratio = (AVRational) { 16, 11};
+            break;
+        case vdecAspectRatio40_33:
+            avctx->sample_aspect_ratio = (AVRational) { 40, 33};
+            break;
+        case vdecAspectRatio24_11:
+            avctx->sample_aspect_ratio = (AVRational) { 24, 11};
+            break;
+        case vdecAspectRatio20_11:
+            avctx->sample_aspect_ratio = (AVRational) { 20, 11};
+            break;
+        case vdecAspectRatio32_11:
+            avctx->sample_aspect_ratio = (AVRational) { 32, 11};
+            break;
+        case vdecAspectRatio80_33:
+            avctx->sample_aspect_ratio = (AVRational) { 80, 33};
+            break;
+        case vdecAspectRatio18_11:
+            avctx->sample_aspect_ratio = (AVRational) { 18, 11};
+            break;
+        case vdecAspectRatio15_11:
+            avctx->sample_aspect_ratio = (AVRational) { 15, 11};
+            break;
+        case vdecAspectRatio64_33:
+            avctx->sample_aspect_ratio = (AVRational) { 64, 33};
+            break;
+        case vdecAspectRatio160_99:
+            avctx->sample_aspect_ratio = (AVRational) {160, 99};
+            break;
+        case vdecAspectRatio4_3:
+            avctx->sample_aspect_ratio = (AVRational) {  4,  3};
+            break;
+        case vdecAspectRatio16_9:
+            avctx->sample_aspect_ratio = (AVRational) { 16,  9};
+            break;
+        case vdecAspectRatio221_1:
+            avctx->sample_aspect_ratio = (AVRational) {221,  1};
+            break;
+        }
+        return RET_COPY_AGAIN;
+    } else if (ret == BC_STS_SUCCESS) {
+        int copy_ret = -1;
+        if (output.PoutFlags & BC_POUT_FLAGS_PIB_VALID) {
+            if (priv->last_picture == -1) {
+                /*
+                 * Init to one less, so that the incrementing code doesn't
+                 * need to be special-cased.
+                 */
+                priv->last_picture = output.PicInfo.picture_number - 1;
+            }
+
+            if (avctx->codec->id == AV_CODEC_ID_MPEG4 &&
+                output.PicInfo.timeStamp == 0 && priv->bframe_bug) {
+                av_log(avctx, AV_LOG_VERBOSE,
+                       "CrystalHD: Not returning packed frame twice.\n");
+                priv->last_picture++;
+                DtsReleaseOutputBuffs(dev, NULL, FALSE);
+                return RET_COPY_AGAIN;
+            }
+
+            print_frame_info(priv, &output);
+
+            if (priv->last_picture + 1 < output.PicInfo.picture_number) {
+                av_log(avctx, AV_LOG_WARNING,
+                       "CrystalHD: Picture Number discontinuity\n");
+                /*
+                 * Have we lost frames? If so, we need to shrink the
+                 * pipeline length appropriately.
+                 *
+                 * XXX: I have no idea what the semantics of this situation
+                 * are so I don't even know if we've lost frames or which
+                 * ones.
+                 *
+                 * In any case, only warn the first time.
+                 */
+               priv->last_picture = output.PicInfo.picture_number - 1;
+            }
+
+            copy_ret = copy_frame(avctx, &output, data, data_size);
+            if (*data_size > 0) {
+                avctx->has_b_frames--;
+                priv->last_picture++;
+                av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Pipeline length: %u\n",
+                       avctx->has_b_frames);
+            }
+        } else {
+            /*
+             * An invalid frame has been consumed.
+             */
+            av_log(avctx, AV_LOG_ERROR, "CrystalHD: ProcOutput succeeded with "
+                                        "invalid PIB\n");
+            avctx->has_b_frames--;
+            copy_ret = RET_OK;
+        }
+        DtsReleaseOutputBuffs(dev, NULL, FALSE);
+
+        return copy_ret;
+    } else if (ret == BC_STS_BUSY) {
+        return RET_COPY_AGAIN;
+    } else {
+        av_log(avctx, AV_LOG_ERROR, "CrystalHD: ProcOutput failed %d\n", ret);
+        return RET_ERROR;
+    }
+}
+
+
+static int decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+{
+    BC_STATUS ret;
+    BC_DTS_STATUS decoder_status = { 0, };
+    CopyRet rec_ret;
+    CHDContext *priv   = avctx->priv_data;
+    HANDLE dev         = priv->dev;
+    uint8_t *in_data   = avpkt->data;
+    int len            = avpkt->size;
+    int free_data      = 0;
+    uint8_t pic_type   = 0;
+
+    av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: decode_frame\n");
+
+    if (avpkt->size == 7 && !priv->bframe_bug) {
+        /*
+         * The use of a drop frame triggers the bug
+         */
+        av_log(avctx, AV_LOG_INFO,
+               "CrystalHD: Enabling work-around for packed b-frame bug\n");
+        priv->bframe_bug = 1;
+    } else if (avpkt->size == 8 && priv->bframe_bug) {
+        /*
+         * Delay frames don't trigger the bug
+         */
+        av_log(avctx, AV_LOG_INFO,
+               "CrystalHD: Disabling work-around for packed b-frame bug\n");
+        priv->bframe_bug = 0;
+    }
+
+    if (len) {
+        int32_t tx_free = (int32_t)DtsTxFreeSize(dev);
+
+        if (priv->parser) {
+            int ret = 0;
+
+            if (priv->bsfc) {
+                ret = av_bitstream_filter_filter(priv->bsfc, avctx, NULL,
+                                                 &in_data, &len,
+                                                 avpkt->data, len, 0);
+            }
+            free_data = ret > 0;
+
+            if (ret >= 0) {
+                uint8_t *pout;
+                int psize;
+                int index;
+                H264Context *h = priv->parser->priv_data;
+
+                index = av_parser_parse2(priv->parser, avctx, &pout, &psize,
+                                         in_data, len, avctx->pkt->pts,
+                                         avctx->pkt->dts, 0);
+                if (index < 0) {
+                    av_log(avctx, AV_LOG_WARNING,
+                           "CrystalHD: Failed to parse h.264 packet to "
+                           "detect interlacing.\n");
+                } else if (index != len) {
+                    av_log(avctx, AV_LOG_WARNING,
+                           "CrystalHD: Failed to parse h.264 packet "
+                           "completely. Interlaced frames may be "
+                           "incorrectly detected.\n");
+                } else {
+                    av_log(avctx, AV_LOG_VERBOSE,
+                           "CrystalHD: parser picture type %d\n",
+                           h->s.picture_structure);
+                    pic_type = h->s.picture_structure;
+                }
+            } else {
+                av_log(avctx, AV_LOG_WARNING,
+                       "CrystalHD: mp4toannexb filter failed to filter "
+                       "packet. Interlaced frames may be incorrectly "
+                       "detected.\n");
+            }
+        }
+
+        if (len < tx_free - 1024) {
+            /*
+             * Despite being notionally opaque, either libcrystalhd or
+             * the hardware itself will mangle pts values that are too
+             * small or too large. The docs claim it should be in units
+             * of 100ns. Given that we're nominally dealing with a black
+             * box on both sides, any transform we do has no guarantee of
+             * avoiding mangling so we need to build a mapping to values
+             * we know will not be mangled.
+             */
+            uint64_t pts = opaque_list_push(priv, avctx->pkt->pts, pic_type);
+            if (!pts) {
+                if (free_data) {
+                    av_freep(&in_data);
+                }
+                return AVERROR(ENOMEM);
+            }
+            av_log(priv->avctx, AV_LOG_VERBOSE,
+                   "input \"pts\": %"PRIu64"\n", pts);
+            ret = DtsProcInput(dev, in_data, len, pts, 0);
+            if (free_data) {
+                av_freep(&in_data);
+            }
+            if (ret == BC_STS_BUSY) {
+                av_log(avctx, AV_LOG_WARNING,
+                       "CrystalHD: ProcInput returned busy\n");
+                usleep(BASE_WAIT);
+                return AVERROR(EBUSY);
+            } else if (ret != BC_STS_SUCCESS) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "CrystalHD: ProcInput failed: %u\n", ret);
+                return -1;
+            }
+            avctx->has_b_frames++;
+        } else {
+            av_log(avctx, AV_LOG_WARNING, "CrystalHD: Input buffer full\n");
+            len = 0; // We didn't consume any bytes.
+        }
+    } else {
+        av_log(avctx, AV_LOG_INFO, "CrystalHD: No more input data\n");
+    }
+
+    if (priv->skip_next_output) {
+        av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Skipping next output.\n");
+        priv->skip_next_output = 0;
+        avctx->has_b_frames--;
+        return len;
+    }
+
+    ret = DtsGetDriverStatus(dev, &decoder_status);
+    if (ret != BC_STS_SUCCESS) {
+        av_log(avctx, AV_LOG_ERROR, "CrystalHD: GetDriverStatus failed\n");
+        return -1;
+    }
+
+    /*
+     * No frames ready. Don't try to extract.
+     *
+     * Empirical testing shows that ReadyListCount can be a damn lie,
+     * and ProcOut still fails when count > 0. The same testing showed
+     * that two more iterations were needed before ProcOutput would
+     * succeed.
+     */
+    if (priv->output_ready < 2) {
+        if (decoder_status.ReadyListCount != 0)
+            priv->output_ready++;
+        usleep(BASE_WAIT);
+        av_log(avctx, AV_LOG_INFO, "CrystalHD: Filling pipeline.\n");
+        return len;
+    } else if (decoder_status.ReadyListCount == 0) {
+        /*
+         * After the pipeline is established, if we encounter a lack of frames
+         * that probably means we're not giving the hardware enough time to
+         * decode them, so start increasing the wait time at the end of a
+         * decode call.
+         */
+        usleep(BASE_WAIT);
+        priv->decode_wait += WAIT_UNIT;
+        av_log(avctx, AV_LOG_INFO, "CrystalHD: No frames ready. Returning\n");
+        return len;
+    }
+
+    do {
+        rec_ret = receive_frame(avctx, data, data_size);
+        if (rec_ret == RET_OK && *data_size == 0) {
+            /*
+             * This case is for when the encoded fields are stored
+             * separately and we get a separate avpkt for each one. To keep
+             * the pipeline stable, we should return nothing and wait for
+             * the next time round to grab the second field.
+             * H.264 PAFF is an example of this.
+             */
+            av_log(avctx, AV_LOG_VERBOSE, "Returning after first field.\n");
+            avctx->has_b_frames--;
+        } else if (rec_ret == RET_COPY_NEXT_FIELD) {
+            /*
+             * This case is for when the encoded fields are stored in a
+             * single avpkt but the hardware returns then separately. Unless
+             * we grab the second field before returning, we'll slip another
+             * frame in the pipeline and if that happens a lot, we're sunk.
+             * So we have to get that second field now.
+             * Interlaced mpeg2 and vc1 are examples of this.
+             */
+            av_log(avctx, AV_LOG_VERBOSE, "Trying to get second field.\n");
+            while (1) {
+                usleep(priv->decode_wait);
+                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 == RET_ERROR)
+                        break;
+                }
+            }
+            av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: Got second field.\n");
+        } else if (rec_ret == RET_SKIP_NEXT_COPY) {
+            /*
+             * Two input packets got turned into a field pair. Gawd.
+             */
+            av_log(avctx, AV_LOG_VERBOSE,
+                   "Don't output on next decode call.\n");
+            priv->skip_next_output = 1;
+        }
+        /*
+         * If rec_ret == RET_COPY_AGAIN, that means that either we just handled
+         * a FMT_CHANGE event and need to go around again for the actual frame,
+         * we got a busy status and need to try again, or we're dealing with
+         * packed b-frames, where the hardware strangely returns the packed
+         * p-frame twice. We choose to keep the second copy as it carries the
+         * valid pts.
+         */
+    } while (rec_ret == RET_COPY_AGAIN);
+    usleep(priv->decode_wait);
+    return len;
+}
+
+
+#if CONFIG_H264_CRYSTALHD_DECODER
+static AVClass h264_class = {
+    "h264_crystalhd",
+    av_default_item_name,
+    options,
+    LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_h264_crystalhd_decoder = {
+    .name           = "h264_crystalhd",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_H264,
+    .priv_data_size = sizeof(CHDContext),
+    .init           = init,
+    .close          = uninit,
+    .decode         = decode,
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+    .flush          = flush,
+    .long_name      = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (CrystalHD acceleration)"),
+    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
+    .priv_class     = &h264_class,
+};
+#endif
+
+#if CONFIG_MPEG2_CRYSTALHD_DECODER
+static AVClass mpeg2_class = {
+    "mpeg2_crystalhd",
+    av_default_item_name,
+    options,
+    LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_mpeg2_crystalhd_decoder = {
+    .name           = "mpeg2_crystalhd",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MPEG2VIDEO,
+    .priv_data_size = sizeof(CHDContext),
+    .init           = init,
+    .close          = uninit,
+    .decode         = decode,
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+    .flush          = flush,
+    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-2 Video (CrystalHD acceleration)"),
+    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
+    .priv_class     = &mpeg2_class,
+};
+#endif
+
+#if CONFIG_MPEG4_CRYSTALHD_DECODER
+static AVClass mpeg4_class = {
+    "mpeg4_crystalhd",
+    av_default_item_name,
+    options,
+    LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_mpeg4_crystalhd_decoder = {
+    .name           = "mpeg4_crystalhd",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MPEG4,
+    .priv_data_size = sizeof(CHDContext),
+    .init           = init,
+    .close          = uninit,
+    .decode         = decode,
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+    .flush          = flush,
+    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 (CrystalHD acceleration)"),
+    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
+    .priv_class     = &mpeg4_class,
+};
+#endif
+
+#if CONFIG_MSMPEG4_CRYSTALHD_DECODER
+static AVClass msmpeg4_class = {
+    "msmpeg4_crystalhd",
+    av_default_item_name,
+    options,
+    LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_msmpeg4_crystalhd_decoder = {
+    .name           = "msmpeg4_crystalhd",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MSMPEG4V3,
+    .priv_data_size = sizeof(CHDContext),
+    .init           = init,
+    .close          = uninit,
+    .decode         = decode,
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_EXPERIMENTAL,
+    .flush          = flush,
+    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 Microsoft variant version 3 (CrystalHD acceleration)"),
+    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
+    .priv_class     = &msmpeg4_class,
+};
+#endif
+
+#if CONFIG_VC1_CRYSTALHD_DECODER
+static AVClass vc1_class = {
+    "vc1_crystalhd",
+    av_default_item_name,
+    options,
+    LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_vc1_crystalhd_decoder = {
+    .name           = "vc1_crystalhd",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_VC1,
+    .priv_data_size = sizeof(CHDContext),
+    .init           = init,
+    .close          = uninit,
+    .decode         = decode,
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+    .flush          = flush,
+    .long_name      = NULL_IF_CONFIG_SMALL("SMPTE VC-1 (CrystalHD acceleration)"),
+    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
+    .priv_class     = &vc1_class,
+};
+#endif
+
+#if CONFIG_WMV3_CRYSTALHD_DECODER
+static AVClass wmv3_class = {
+    "wmv3_crystalhd",
+    av_default_item_name,
+    options,
+    LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_wmv3_crystalhd_decoder = {
+    .name           = "wmv3_crystalhd",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_WMV3,
+    .priv_data_size = sizeof(CHDContext),
+    .init           = init,
+    .close          = uninit,
+    .decode         = decode,
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
+    .flush          = flush,
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 9 (CrystalHD acceleration)"),
+    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE},
+    .priv_class     = &wmv3_class,
+};
+#endif
diff --git a/libavcodec/cscd.c b/libavcodec/cscd.c
index 8d0cbb6..8ba5de3 100644
--- a/libavcodec/cscd.c
+++ b/libavcodec/cscd.c
@@ -2,20 +2,20 @@
  * CamStudio decoder
  * Copyright (c) 2006 Reimar Doeffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include <stdio.h>
@@ -36,9 +36,9 @@
     unsigned char* decomp_buf;
 } CamStudioContext;
 
-static void copy_frame_default(AVFrame *f, const uint8_t *src, int src_stride,
+static void copy_frame_default(AVFrame *f, const uint8_t *src,
                                int linelen, int height) {
-    int i;
+    int i, src_stride = FFALIGN(linelen, 4);
     uint8_t *dst = f->data[0];
     dst += (height - 1) * f->linesize[0];
     for (i = height; i; i--) {
@@ -48,9 +48,9 @@
     }
 }
 
-static void add_frame_default(AVFrame *f, const uint8_t *src, int src_stride,
+static void add_frame_default(AVFrame *f, const uint8_t *src,
                               int linelen, int height) {
-    int i, j;
+    int i, j, src_stride = FFALIGN(linelen, 4);
     uint8_t *dst = f->data[0];
     dst += (height - 1) * f->linesize[0];
     for (i = height; i; i--) {
@@ -61,81 +61,6 @@
     }
 }
 
-#if !HAVE_BIGENDIAN
-#define copy_frame_16(f, s, l, h) copy_frame_default(f, s, l, l, h)
-#define copy_frame_32(f, s, l, h) copy_frame_default(f, s, l, l, h)
-#define add_frame_16(f, s, l, h) add_frame_default(f, s, l, l, h)
-#define add_frame_32(f, s, l, h) add_frame_default(f, s, l, l, h)
-#else
-static void copy_frame_16(AVFrame *f, const uint8_t *src,
-                          int linelen, int height) {
-    int i, j;
-    uint8_t *dst = f->data[0];
-    dst += (height - 1) * f->linesize[0];
-    for (i = height; i; i--) {
-        for (j = linelen / 2; j; j--) {
-          dst[0] = src[1];
-          dst[1] = src[0];
-          src += 2;
-          dst += 2;
-        }
-        dst -= f->linesize[0] + linelen;
-    }
-}
-
-static void copy_frame_32(AVFrame *f, const uint8_t *src,
-                          int linelen, int height) {
-    int i, j;
-    uint8_t *dst = f->data[0];
-    dst += (height - 1) * f->linesize[0];
-    for (i = height; i; i--) {
-        for (j = linelen / 4; j; j--) {
-          dst[0] = src[3];
-          dst[1] = src[2];
-          dst[2] = src[1];
-          dst[3] = src[0];
-          src += 4;
-          dst += 4;
-        }
-        dst -= f->linesize[0] + linelen;
-    }
-}
-
-static void add_frame_16(AVFrame *f, const uint8_t *src,
-                         int linelen, int height) {
-    int i, j;
-    uint8_t *dst = f->data[0];
-    dst += (height - 1) * f->linesize[0];
-    for (i = height; i; i--) {
-        for (j = linelen / 2; j; j--) {
-          dst[0] += src[1];
-          dst[1] += src[0];
-          src += 2;
-          dst += 2;
-        }
-        dst -= f->linesize[0] + linelen;
-    }
-}
-
-static void add_frame_32(AVFrame *f, const uint8_t *src,
-                         int linelen, int height) {
-    int i, j;
-    uint8_t *dst = f->data[0];
-    dst += (height - 1) * f->linesize[0];
-    for (i = height; i; i--) {
-        for (j = linelen / 4; j; j--) {
-          dst[0] += src[3];
-          dst[1] += src[2];
-          dst[2] += src[1];
-          dst[3] += src[0];
-          src += 4;
-          dst += 4;
-        }
-        dst -= f->linesize[0] + linelen;
-    }
-}
-#endif
-
 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
                         AVPacket *avpkt) {
     const uint8_t *buf = avpkt->data;
@@ -148,12 +73,10 @@
         return -1;
     }
 
-    if (c->pic.data[0])
-        avctx->release_buffer(avctx, &c->pic);
-    c->pic.reference = 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;
-    if (avctx->get_buffer(avctx, &c->pic) < 0) {
+    if (avctx->reget_buffer(avctx, &c->pic) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
@@ -186,31 +109,13 @@
     if (buf[0] & 1) { // keyframe
         c->pic.pict_type = AV_PICTURE_TYPE_I;
         c->pic.key_frame = 1;
-        switch (c->bpp) {
-          case 16:
-              copy_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height);
-              break;
-          case 32:
-              copy_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height);
-              break;
-          default:
-              copy_frame_default(&c->pic, c->decomp_buf, FFALIGN(c->linelen, 4),
+              copy_frame_default(&c->pic, c->decomp_buf,
                                  c->linelen, c->height);
-        }
     } else {
         c->pic.pict_type = AV_PICTURE_TYPE_P;
         c->pic.key_frame = 0;
-        switch (c->bpp) {
-          case 16:
-              add_frame_16(&c->pic, c->decomp_buf, c->linelen, c->height);
-              break;
-          case 32:
-              add_frame_32(&c->pic, c->decomp_buf, c->linelen, c->height);
-              break;
-          default:
-              add_frame_default(&c->pic, c->decomp_buf, FFALIGN(c->linelen, 4),
+              add_frame_default(&c->pic, c->decomp_buf,
                                 c->linelen, c->height);
-        }
     }
 
     *picture = c->pic;
@@ -222,9 +127,9 @@
     CamStudioContext *c = avctx->priv_data;
     int stride;
     switch (avctx->bits_per_coded_sample) {
-        case 16: avctx->pix_fmt = AV_PIX_FMT_RGB555; break;
+        case 16: avctx->pix_fmt = AV_PIX_FMT_RGB555LE; break;
         case 24: avctx->pix_fmt = AV_PIX_FMT_BGR24; break;
-        case 32: avctx->pix_fmt = AV_PIX_FMT_RGB32; break;
+        case 32: avctx->pix_fmt = AV_PIX_FMT_BGRA; break;
         default:
             av_log(avctx, AV_LOG_ERROR,
                    "CamStudio codec error: invalid depth %i bpp\n",
@@ -232,12 +137,11 @@
             return AVERROR_INVALIDDATA;
     }
     c->bpp = avctx->bits_per_coded_sample;
+    avcodec_get_frame_defaults(&c->pic);
     c->pic.data[0] = NULL;
     c->linelen = avctx->width * avctx->bits_per_coded_sample / 8;
     c->height = avctx->height;
-    stride = c->linelen;
-    if (avctx->bits_per_coded_sample == 24)
-        stride = FFALIGN(stride, 4);
+    stride = FFALIGN(c->linelen, 4);
     c->decomp_size = c->height * stride;
     c->decomp_buf = av_malloc(c->decomp_size + AV_LZO_OUTPUT_PADDING);
     if (!c->decomp_buf) {
diff --git a/libavcodec/cyuv.c b/libavcodec/cyuv.c
index 18767d7..74c1077 100644
--- a/libavcodec/cyuv.c
+++ b/libavcodec/cyuv.c
@@ -6,20 +6,20 @@
  *
  * Copyright (C) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -53,7 +53,7 @@
     if (s->width & 0x3)
         return -1;
     s->height = avctx->height;
-    avctx->pix_fmt = AV_PIX_FMT_YUV411P;
+    avcodec_get_frame_defaults(&s->frame);
 
     return 0;
 }
@@ -82,6 +82,7 @@
     int stream_ptr;
     unsigned char cur_byte;
     int pixel_groups;
+    int rawsize = s->height * FFALIGN(s->width,2) * 2;
 
     if (avctx->codec_id == AV_CODEC_ID_AURA) {
         y_table = u_table;
@@ -91,7 +92,11 @@
      * followed by (height) lines each with 3 bytes to represent groups
      * of 4 pixels. Thus, the total size of the buffer ought to be:
      *    (3 * 16) + height * (width * 3 / 4) */
-    if (buf_size != 48 + s->height * (s->width * 3 / 4)) {
+    if (buf_size == 48 + s->height * (s->width * 3 / 4)) {
+        avctx->pix_fmt = AV_PIX_FMT_YUV411P;
+    } else if(buf_size == rawsize ) {
+        avctx->pix_fmt = AV_PIX_FMT_UYVY422;
+    } 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;
@@ -114,6 +119,15 @@
     u_plane = s->frame.data[1];
     v_plane = s->frame.data[2];
 
+    if (buf_size == rawsize) {
+        int linesize = FFALIGN(s->width,2) * 2;
+        y_plane += s->frame.linesize[0] * s->height;
+        for (stream_ptr = 0; stream_ptr < rawsize; stream_ptr += linesize) {
+            y_plane -= s->frame.linesize[0];
+            memcpy(y_plane, buf+stream_ptr, linesize);
+        }
+    } else {
+
     /* iterate through each line in the height */
     for (y_ptr = 0, u_ptr = 0, v_ptr = 0;
          y_ptr < (s->height * s->frame.linesize[0]);
@@ -161,6 +175,7 @@
 
         }
     }
+    }
 
     *data_size=sizeof(AVFrame);
     *(AVFrame*)data= s->frame;
diff --git a/libavcodec/dca.c b/libavcodec/dca.c
index 0f1eeec..bbe1f10 100644
--- a/libavcodec/dca.c
+++ b/libavcodec/dca.c
@@ -1,20 +1,24 @@
 /*
  * DCA compatible decoder data
+ * Copyright (C) 2004 Gildas Bazin
+ * Copyright (C) 2004 Benjamin Zores
+ * Copyright (C) 2006 Benjamin Larsson
+ * Copyright (C) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dca.h b/libavcodec/dca.h
index 1515270..4d2a829 100644
--- a/libavcodec/dca.h
+++ b/libavcodec/dca.h
@@ -5,20 +5,20 @@
  * Copyright (C) 2006 Benjamin Larsson
  * Copyright (C) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dca_parser.c b/libavcodec/dca_parser.c
index 7e65d0b..5ccaacc 100644
--- a/libavcodec/dca_parser.c
+++ b/libavcodec/dca_parser.c
@@ -5,20 +5,20 @@
  * Copyright (C) 2006 Benjamin Larsson
  * Copyright (C) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -39,7 +39,7 @@
 #define IS_MARKER(state, i, buf, buf_size) \
  ((state == DCA_MARKER_14B_LE && (i < buf_size-2) && (buf[i+1] & 0xF0) == 0xF0 && buf[i+2] == 0x07) \
  || (state == DCA_MARKER_14B_BE && (i < buf_size-2) && buf[i+1] == 0x07 && (buf[i+2] & 0xF0) == 0xF0) \
- || state == DCA_MARKER_RAW_LE || state == DCA_MARKER_RAW_BE)
+ || state == DCA_MARKER_RAW_LE || state == DCA_MARKER_RAW_BE || state == DCA_HD_MARKER)
 
 /**
  * Find the end of the current frame in the bitstream.
@@ -60,10 +60,7 @@
         for (i = 0; i < buf_size; i++) {
             state = (state << 8) | buf[i];
             if (IS_MARKER(state, i, buf, buf_size)) {
-                if (pc1->lastmarker && state == pc1->lastmarker) {
-                    start_found = 1;
-                    break;
-                } else if (!pc1->lastmarker) {
+                if (!pc1->lastmarker || state == pc1->lastmarker || pc1->lastmarker == DCA_HD_MARKER) {
                     start_found = 1;
                     pc1->lastmarker = state;
                     break;
@@ -77,10 +74,11 @@
             state = (state << 8) | buf[i];
             if (state == DCA_HD_MARKER && !pc1->hd_pos)
                 pc1->hd_pos = pc1->size;
-            if (state == pc1->lastmarker && IS_MARKER(state, i, buf, buf_size)) {
+            if (IS_MARKER(state, i, buf, buf_size) && (state == pc1->lastmarker || pc1->lastmarker == DCA_HD_MARKER)) {
                 if(pc1->framesize > pc1->size)
                     continue;
-                if(!pc1->framesize){
+                // We have to check that we really read a full frame here, and that it isn't a pure HD frame, because their size is not constant.
+                if(!pc1->framesize && state == pc1->lastmarker && state != DCA_HD_MARKER){
                     pc1->framesize = pc1->hd_pos ? pc1->hd_pos : pc1->size;
                 }
                 pc->frame_start_found = 0;
diff --git a/libavcodec/dcadata.h b/libavcodec/dcadata.h
index 324e40f..15df49e 100644
--- a/libavcodec/dcadata.h
+++ b/libavcodec/dcadata.h
@@ -3,20 +3,20 @@
  * Copyright (C) 2004 Gildas Bazin
  * Copyright (c) 2006 Benjamin Larsson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -7522,6 +7522,40 @@
   0.001412537544623, 0.001000000000000, 0.000501187233627, 0.000251188643151, 0.000000000000000,
 };
 
+static const float dca_downmix_scale_factors[241] = {
+    0.001000, 0.001059, 0.001122, 0.001189, 0.001259, 0.001334, 0.001413, 0.001496,
+    0.001585, 0.001679, 0.001778, 0.001884, 0.001995, 0.002113, 0.002239, 0.002371,
+    0.002512, 0.002661, 0.002818, 0.002985, 0.003162, 0.003350, 0.003548, 0.003758,
+    0.003981, 0.004217, 0.004467, 0.004732, 0.005012, 0.005309, 0.005623, 0.005957,
+    0.006310, 0.006683, 0.007079, 0.007499, 0.007943, 0.008414, 0.008913, 0.009441,
+    0.010000, 0.010593, 0.011220, 0.011885, 0.012589, 0.013335, 0.014125, 0.014962,
+    0.015849, 0.016788, 0.017783, 0.018836, 0.019953, 0.021135, 0.022387, 0.023714,
+    0.025119, 0.026607, 0.028184, 0.029854, 0.031623, 0.032546, 0.033497, 0.034475,
+    0.035481, 0.036517, 0.037584, 0.038681, 0.039811, 0.040973, 0.042170, 0.043401,
+    0.044668, 0.045973, 0.047315, 0.048697, 0.050119, 0.051582, 0.053088, 0.054639,
+    0.056234, 0.057876, 0.059566, 0.061306, 0.063096, 0.064938, 0.066834, 0.068786,
+    0.070795, 0.072862, 0.074989, 0.077179, 0.079433, 0.081752, 0.084140, 0.086596,
+    0.089125, 0.091728, 0.094406, 0.097163, 0.100000, 0.102920, 0.105925, 0.109018,
+    0.112202, 0.115478, 0.118850, 0.122321, 0.125893, 0.129569, 0.133352, 0.137246,
+    0.141254, 0.145378, 0.149624, 0.153993, 0.158489, 0.163117, 0.167880, 0.172783,
+    0.177828, 0.180406, 0.183021, 0.185674, 0.188365, 0.191095, 0.193865, 0.196675,
+    0.199526, 0.202418, 0.205353, 0.208329, 0.211349, 0.214412, 0.217520, 0.220673,
+    0.223872, 0.227117, 0.230409, 0.233749, 0.237137, 0.240575, 0.244062, 0.247600,
+    0.251189, 0.254830, 0.258523, 0.262271, 0.266073, 0.269929, 0.273842, 0.277811,
+    0.281838, 0.285924, 0.290068, 0.294273, 0.298538, 0.302866, 0.307256, 0.311709,
+    0.316228, 0.320812, 0.325462, 0.330179, 0.334965, 0.339821, 0.344747, 0.349744,
+    0.354813, 0.359956, 0.365174, 0.370467, 0.375837, 0.381285, 0.386812, 0.392419,
+    0.398107, 0.403878, 0.409732, 0.415671, 0.421697, 0.427809, 0.434010, 0.440301,
+    0.446684, 0.453158, 0.459727, 0.466391, 0.473151, 0.480010, 0.486968, 0.494026,
+    0.501187, 0.508452, 0.515822, 0.523299, 0.530884, 0.538580, 0.546387, 0.554307,
+    0.562341, 0.570493, 0.578762, 0.587151, 0.595662, 0.604296, 0.613056, 0.621942,
+    0.630957, 0.640103, 0.649382, 0.658795, 0.668344, 0.678032, 0.687860, 0.697831,
+    0.707107, 0.718208, 0.728618, 0.739180, 0.749894, 0.760764, 0.771792, 0.782979,
+    0.794328, 0.805842, 0.817523, 0.829373, 0.841395, 0.853591, 0.865964, 0.878517,
+    0.891251, 0.904170, 0.917276, 0.930572, 0.944061, 0.957745, 0.971628, 0.985712,
+    1.000000
+};
+
 static const uint8_t dca_default_coeffs[10][5][2] = {
     { { 13, 13 },                                                 },
     { {  0, 64 }, { 64,  0 },                                     },
diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c
index d38dff81..4d5e115 100644
--- a/libavcodec/dcadec.c
+++ b/libavcodec/dcadec.c
@@ -5,20 +5,20 @@
  * Copyright (C) 2006 Benjamin Larsson
  * Copyright (C) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -52,12 +52,14 @@
 //#define TRACE
 
 #define DCA_PRIM_CHANNELS_MAX  (7)
-#define DCA_SUBBANDS          (32)
+#define DCA_SUBBANDS          (64)
 #define DCA_ABITS_MAX         (32)      /* Should be 28 */
 #define DCA_SUBSUBFRAMES_MAX   (4)
 #define DCA_SUBFRAMES_MAX     (16)
 #define DCA_BLOCKS_MAX        (16)
 #define DCA_LFE_MAX            (3)
+#define DCA_CHSETS_MAX         (4)
+#define DCA_CHSET_CHANS_MAX    (8)
 
 enum DCAMode {
     DCA_MONO = 0,
@@ -93,6 +95,68 @@
     DCA_EXSS_REAR_HIGH_LEFT_RIGHT  = 0x8000,
 };
 
+enum DCAXxchSpeakerMask {
+    DCA_XXCH_FRONT_CENTER          = 0x0000001,
+    DCA_XXCH_FRONT_LEFT            = 0x0000002,
+    DCA_XXCH_FRONT_RIGHT           = 0x0000004,
+    DCA_XXCH_SIDE_REAR_LEFT        = 0x0000008,
+    DCA_XXCH_SIDE_REAR_RIGHT       = 0x0000010,
+    DCA_XXCH_LFE1                  = 0x0000020,
+    DCA_XXCH_REAR_CENTER           = 0x0000040,
+    DCA_XXCH_SURROUND_REAR_LEFT    = 0x0000080,
+    DCA_XXCH_SURROUND_REAR_RIGHT   = 0x0000100,
+    DCA_XXCH_SIDE_SURROUND_LEFT    = 0x0000200,
+    DCA_XXCH_SIDE_SURROUND_RIGHT   = 0x0000400,
+    DCA_XXCH_FRONT_CENTER_LEFT     = 0x0000800,
+    DCA_XXCH_FRONT_CENTER_RIGHT    = 0x0001000,
+    DCA_XXCH_FRONT_HIGH_LEFT       = 0x0002000,
+    DCA_XXCH_FRONT_HIGH_CENTER     = 0x0004000,
+    DCA_XXCH_FRONT_HIGH_RIGHT      = 0x0008000,
+    DCA_XXCH_LFE2                  = 0x0010000,
+    DCA_XXCH_SIDE_FRONT_LEFT       = 0x0020000,
+    DCA_XXCH_SIDE_FRONT_RIGHT      = 0x0040000,
+    DCA_XXCH_OVERHEAD              = 0x0080000,
+    DCA_XXCH_SIDE_HIGH_LEFT        = 0x0100000,
+    DCA_XXCH_SIDE_HIGH_RIGHT       = 0x0200000,
+    DCA_XXCH_REAR_HIGH_CENTER      = 0x0400000,
+    DCA_XXCH_REAR_HIGH_LEFT        = 0x0800000,
+    DCA_XXCH_REAR_HIGH_RIGHT       = 0x1000000,
+    DCA_XXCH_REAR_LOW_CENTER       = 0x2000000,
+    DCA_XXCH_REAR_LOW_LEFT         = 0x4000000,
+    DCA_XXCH_REAR_LOW_RIGHT        = 0x8000000,
+};
+
+static const uint32_t map_xxch_to_native[28] = {
+    AV_CH_FRONT_CENTER,
+    AV_CH_FRONT_LEFT,
+    AV_CH_FRONT_RIGHT,
+    AV_CH_SIDE_LEFT,
+    AV_CH_SIDE_RIGHT,
+    AV_CH_LOW_FREQUENCY,
+    AV_CH_BACK_CENTER,
+    AV_CH_BACK_LEFT,
+    AV_CH_BACK_RIGHT,
+    AV_CH_SIDE_LEFT,           /* side surround left -- dup sur side L */
+    AV_CH_SIDE_RIGHT,          /* side surround right -- dup sur side R */
+    AV_CH_FRONT_LEFT_OF_CENTER,
+    AV_CH_FRONT_RIGHT_OF_CENTER,
+    AV_CH_TOP_FRONT_LEFT,
+    AV_CH_TOP_FRONT_CENTER,
+    AV_CH_TOP_FRONT_RIGHT,
+    AV_CH_LOW_FREQUENCY,        /* lfe2 -- duplicate lfe1 position */
+    AV_CH_FRONT_LEFT_OF_CENTER, /* side front left -- dup front cntr L */
+    AV_CH_FRONT_RIGHT_OF_CENTER,/* side front right -- dup front cntr R */
+    AV_CH_TOP_CENTER,           /* overhead */
+    AV_CH_TOP_FRONT_LEFT,       /* side high left -- dup */
+    AV_CH_TOP_FRONT_RIGHT,      /* side high right -- dup */
+    AV_CH_TOP_BACK_CENTER,
+    AV_CH_TOP_BACK_LEFT,
+    AV_CH_TOP_BACK_RIGHT,
+    AV_CH_BACK_CENTER,          /* rear low center -- dup */
+    AV_CH_BACK_LEFT,            /* rear low left -- dup */
+    AV_CH_BACK_RIGHT            /* read low right -- dup  */
+};
+
 enum DCAExtensionMask {
     DCA_EXT_CORE       = 0x001, ///< core in core substream
     DCA_EXT_XXCH       = 0x002, ///< XXCh channels extension in core substream
@@ -316,7 +380,6 @@
 
     /* Primary audio coding header */
     int subframes;              ///< number of subframes
-    int is_channels_set;        ///< check for if the channel number is already set
     int total_channels;         ///< number of channels including extensions
     int prim_channels;          ///< number of primary audio channels
     int subband_activity[DCA_PRIM_CHANNELS_MAX];    ///< subband activity count
@@ -373,6 +436,21 @@
     int xch_present;            ///< XCh extension present and valid
     int xch_base_channel;       ///< index of first (only) channel containing XCH data
 
+    /* XXCH extension information */
+    int xxch_chset;
+    int xxch_nbits_spk_mask;
+    uint32_t xxch_core_spkmask;
+    uint32_t xxch_spk_masks[4]; /* speaker masks, last element is core mask */
+    int xxch_chset_nch[4];
+    float xxch_dmix_sf[DCA_CHSETS_MAX];
+
+    uint32_t xxch_downmix;        /* downmix enabled per channel set */
+    uint32_t xxch_dmix_embedded;  /* lower layer has mix pre-embedded, per chset */
+    float xxch_dmix_coeff[DCA_PRIM_CHANNELS_MAX][32]; /* worst case sizing */
+
+    int8_t xxch_order_tab[32];
+    int8_t lfe_index;
+
     /* ExSS header parser */
     int static_fields;          ///< static fields present
     int mix_metadata;           ///< mixing metadata present
@@ -459,16 +537,88 @@
         *dst++ = get_bits(gb, bits);
 }
 
-static int dca_parse_audio_coding_header(DCAContext *s, int base_channel)
+static inline int dca_xxch2index(DCAContext *s, int xxch_ch)
+{
+    int i, base, mask;
+
+    /* locate channel set containing the channel */
+    for (i = -1, base = 0, mask = (s->xxch_core_spkmask & ~DCA_XXCH_LFE1);
+         i <= s->xxch_chset && !(mask & xxch_ch); mask = s->xxch_spk_masks[++i])
+        base += av_popcount(mask);
+
+    return base + av_popcount(mask & (xxch_ch - 1));
+}
+
+static int dca_parse_audio_coding_header(DCAContext *s, int base_channel,
+                                         int xxch)
 {
     int i, j;
     static const float adj_table[4] = { 1.0, 1.1250, 1.2500, 1.4375 };
     static const int bitlen[11] = { 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 };
     static const int thr[11]    = { 0, 1, 3, 3, 3, 3, 7, 7, 7, 7, 7 };
+    int hdr_pos = 0, hdr_size = 0;
+    float sign, mag, scale_factor;
+    int this_chans, acc_mask;
+    int embedded_downmix;
+    int nchans, mask[8];
+    int coeff, ichan;
 
-    s->total_channels = get_bits(&s->gb, 3) + 1 + base_channel;
+    /* xxch has arbitrary sized audio coding headers */
+    if (xxch) {
+        hdr_pos  = get_bits_count(&s->gb);
+        hdr_size = get_bits(&s->gb, 7) + 1;
+    }
+
+    nchans = get_bits(&s->gb, 3) + 1;
+    s->total_channels = nchans + base_channel;
     s->prim_channels  = s->total_channels;
 
+    /* obtain speaker layout mask & downmix coefficients for XXCH */
+    if (xxch) {
+        acc_mask = s->xxch_core_spkmask;
+
+        this_chans = get_bits(&s->gb, s->xxch_nbits_spk_mask - 6) << 6;
+        s->xxch_spk_masks[s->xxch_chset] = this_chans;
+        s->xxch_chset_nch[s->xxch_chset] = nchans;
+
+        for (i = 0; i <= s->xxch_chset; i++)
+            acc_mask |= s->xxch_spk_masks[i];
+
+        /* check for downmixing information */
+        if (get_bits1(&s->gb)) {
+            embedded_downmix = get_bits1(&s->gb);
+            scale_factor     =
+               1.0f / dca_downmix_scale_factors[(get_bits(&s->gb, 6) - 1) << 2];
+
+            s->xxch_dmix_sf[s->xxch_chset] = scale_factor;
+
+            for (i = base_channel; i < s->prim_channels; i++) {
+                s->xxch_downmix |= (1 << i);
+                mask[i] = get_bits(&s->gb, s->xxch_nbits_spk_mask);
+            }
+
+            for (j = base_channel; j < s->prim_channels; j++) {
+                memset(s->xxch_dmix_coeff[j], 0, sizeof(s->xxch_dmix_coeff[0]));
+                s->xxch_dmix_embedded |= (embedded_downmix << j);
+                for (i = 0; i < s->xxch_nbits_spk_mask; i++) {
+                    if (mask[j] & (1 << i)) {
+                        if ((1 << i) == DCA_XXCH_LFE1) {
+                            av_log(s->avctx, AV_LOG_WARNING,
+                                   "DCA-XXCH: dmix to LFE1 not supported.\n");
+                            continue;
+                        }
+
+                        coeff = get_bits(&s->gb, 7);
+                        sign  = (coeff & 64) ? 1.0 : -1.0;
+                        mag   = dca_downmix_scale_factors[((coeff & 63) - 1) << 2];
+                        ichan = dca_xxch2index(s, 1 << i);
+                        s->xxch_dmix_coeff[j][ichan] = sign * mag;
+                    }
+                }
+            }
+        }
+    }
+
     if (s->prim_channels > DCA_PRIM_CHANNELS_MAX)
         s->prim_channels = DCA_PRIM_CHANNELS_MAX;
 
@@ -505,9 +655,16 @@
             if (s->quant_index_huffman[i][j] < thr[j])
                 s->scalefactor_adj[i][j] = adj_table[get_bits(&s->gb, 2)];
 
-    if (s->crc_present) {
-        /* Audio header CRC check */
-        get_bits(&s->gb, 16);
+    if (!xxch) {
+        if (s->crc_present) {
+            /* Audio header CRC check */
+            get_bits(&s->gb, 16);
+        }
+    } else {
+        /* Skip to the end of the header, also ignore CRC if present  */
+        i = get_bits_count(&s->gb);
+        if (hdr_pos + 8 * hdr_size > i)
+            skip_bits_long(&s->gb, hdr_pos + 8 * hdr_size - i);
     }
 
     s->current_subframe    = 0;
@@ -567,7 +724,7 @@
     if (!s->bit_rate)
         return AVERROR_INVALIDDATA;
 
-    s->downmix           = get_bits(&s->gb, 1);
+    s->downmix           = get_bits(&s->gb, 1); /* note: this is FixedBit == 0 */
     s->dynrange          = get_bits(&s->gb, 1);
     s->timestamp         = get_bits(&s->gb, 1);
     s->aux_data          = get_bits(&s->gb, 1);
@@ -636,7 +793,7 @@
     /* Primary audio coding header */
     s->subframes         = get_bits(&s->gb, 4) + 1;
 
-    return dca_parse_audio_coding_header(s, 0);
+    return dca_parse_audio_coding_header(s, 0, 0);
 }
 
 
@@ -805,7 +962,7 @@
                        "Invalid channel mode %d\n", am);
                 return AVERROR_INVALIDDATA;
             }
-            for (j = base_channel; j < s->prim_channels; j++) {
+            for (j = base_channel; j < FFMIN(s->prim_channels, FF_ARRAY_ELEMS(dca_default_coeffs[am])); j++) {
                 s->downmix_coef[j][0] = dca_default_coeffs[am][j][0];
                 s->downmix_coef[j][1] = dca_default_coeffs[am][j][1];
             }
@@ -833,6 +990,7 @@
 
     /* Low frequency effect data */
     if (!base_channel && s->lfe) {
+        int quant7;
         /* LFE samples */
         int lfe_samples = 2 * s->lfe * (4 + block_index);
         int lfe_end_sample = 2 * s->lfe * (4 + block_index + s->subsubframes[s->current_subframe]);
@@ -844,8 +1002,12 @@
         }
 
         /* Scale factor index */
-        skip_bits(&s->gb, 1);
-        s->lfe_scale_factor = scale_factor_quant7[get_bits(&s->gb, 7)];
+        quant7 = get_bits(&s->gb, 8);
+        if (quant7 > 127) {
+            av_log_ask_for_sample(s->avctx, "LFEScaleIndex larger than 127\n");
+            return AVERROR_INVALIDDATA;
+        }
+        s->lfe_scale_factor = scale_factor_quant7[quant7];
 
         /* Quantization step size * scale factor */
         lfe_scale = 0.035 * s->lfe_scale_factor;
@@ -1290,7 +1452,7 @@
     if (s->output & DCA_LFE) {
         lfe_interpolation_fir(s, s->lfe, 2 * s->lfe,
                               s->lfe_data + 2 * s->lfe * (block_index + 4),
-                              s->samples_chanptr[dca_lfe_index[s->amode]],
+                              s->samples_chanptr[s->lfe_index],
                               1.0 / (256.0 * 32768.0));
         /* Outputs 20bits pcm samples */
     }
@@ -1415,11 +1577,11 @@
 {
     int header_pos = get_bits_count(&s->gb);
     int header_size;
-    int channels;
+    int channels = 0;
     int embedded_stereo = 0;
     int embedded_6ch    = 0;
     int drc_code_present;
-    int extensions_mask;
+    int av_uninit(extensions_mask);
     int i, j;
 
     if (get_bits_left(&s->gb) < 16)
@@ -1559,26 +1721,247 @@
     return 0;
 }
 
+static int dca_xbr_parse_frame(DCAContext *s)
+{
+    int scale_table_high[DCA_CHSET_CHANS_MAX][DCA_SUBBANDS][2];
+    int active_bands[DCA_CHSETS_MAX][DCA_CHSET_CHANS_MAX];
+    int abits_high[DCA_CHSET_CHANS_MAX][DCA_SUBBANDS];
+    int anctemp[DCA_CHSET_CHANS_MAX];
+    int chset_fsize[DCA_CHSETS_MAX];
+    int n_xbr_ch[DCA_CHSETS_MAX];
+    int hdr_size, num_chsets, xbr_tmode, hdr_pos;
+    int i, j, k, l, chset, chan_base;
+
+    av_log(s->avctx, AV_LOG_DEBUG, "DTS-XBR: decoding XBR extension\n");
+
+    /* get bit position of sync header */
+    hdr_pos = get_bits_count(&s->gb) - 32;
+
+    hdr_size = get_bits(&s->gb, 6) + 1;
+    num_chsets = get_bits(&s->gb, 2) + 1;
+
+    for(i = 0; i < num_chsets; i++)
+        chset_fsize[i] = get_bits(&s->gb, 14) + 1;
+
+    xbr_tmode = get_bits1(&s->gb);
+
+    for(i = 0; i < num_chsets; i++) {
+        n_xbr_ch[i] = get_bits(&s->gb, 3) + 1;
+        k = get_bits(&s->gb, 2) + 5;
+        for(j = 0; j < n_xbr_ch[i]; j++)
+            active_bands[i][j] = get_bits(&s->gb, k) + 1;
+    }
+
+    /* skip to the end of the header */
+    i = get_bits_count(&s->gb);
+    if(hdr_pos + hdr_size * 8 > i)
+        skip_bits_long(&s->gb, hdr_pos + hdr_size * 8 - i);
+
+    /* loop over the channel data sets */
+    /* only decode as many channels as we've decoded base data for */
+    for(chset = 0, chan_base = 0;
+        chset < num_chsets && chan_base + n_xbr_ch[chset] <= s->prim_channels;
+        chan_base += n_xbr_ch[chset++]) {
+        int start_posn = get_bits_count(&s->gb);
+        int subsubframe = 0;
+        int subframe = 0;
+
+        /* loop over subframes */
+        for (k = 0; k < (s->sample_blocks / 8); k++) {
+            /* parse header if we're on first subsubframe of a block */
+            if(subsubframe == 0) {
+                /* Parse subframe header */
+                for(i = 0; i < n_xbr_ch[chset]; i++) {
+                    anctemp[i] = get_bits(&s->gb, 2) + 2;
+                }
+
+                for(i = 0; i < n_xbr_ch[chset]; i++) {
+                    get_array(&s->gb, abits_high[i], active_bands[chset][i], anctemp[i]);
+                }
+
+                for(i = 0; i < n_xbr_ch[chset]; i++) {
+                    anctemp[i] = get_bits(&s->gb, 3);
+                    if(anctemp[i] < 1) {
+                        av_log(s->avctx, AV_LOG_ERROR, "DTS-XBR: SYNC ERROR\n");
+                        return AVERROR_INVALIDDATA;
+                    }
+                }
+
+                /* generate scale factors */
+                for(i = 0; i < n_xbr_ch[chset]; i++) {
+                    const uint32_t *scale_table;
+                    int nbits;
+
+                    if (s->scalefactor_huffman[chan_base+i] == 6) {
+                        scale_table = scale_factor_quant7;
+                    } else {
+                        scale_table = scale_factor_quant6;
+                    }
+
+                    nbits = anctemp[i];
+
+                    for(j = 0; j < active_bands[chset][i]; j++) {
+                        if(abits_high[i][j] > 0) {
+                            scale_table_high[i][j][0] =
+                                scale_table[get_bits(&s->gb, nbits)];
+
+                            if(xbr_tmode && s->transition_mode[i][j]) {
+                                scale_table_high[i][j][1] =
+                                    scale_table[get_bits(&s->gb, nbits)];
+                            }
+                        }
+                    }
+                }
+            }
+
+            /* decode audio array for this block */
+            for(i = 0; i < n_xbr_ch[chset]; i++) {
+                for(j = 0; j < active_bands[chset][i]; j++) {
+                    const int xbr_abits = abits_high[i][j];
+                    const float quant_step_size = lossless_quant_d[xbr_abits];
+                    const int sfi = xbr_tmode && s->transition_mode[i][j] && subsubframe >= s->transition_mode[i][j];
+                    const float rscale = quant_step_size * scale_table_high[i][j][sfi];
+                    float *subband_samples = s->subband_samples[k][chan_base+i][j];
+                    int block[8];
+
+                    if(xbr_abits <= 0)
+                        continue;
+
+                    if(xbr_abits > 7) {
+                        get_array(&s->gb, block, 8, xbr_abits - 3);
+                    } else {
+                        int block_code1, block_code2, size, levels, err;
+
+                        size   = abits_sizes[xbr_abits - 1];
+                        levels = abits_levels[xbr_abits - 1];
+
+                        block_code1 = get_bits(&s->gb, size);
+                        block_code2 = get_bits(&s->gb, size);
+                        err = decode_blockcodes(block_code1, block_code2,
+                                                levels, block);
+                        if (err) {
+                            av_log(s->avctx, AV_LOG_ERROR,
+                                   "ERROR: DTS-XBR: block code look-up failed\n");
+                            return AVERROR_INVALIDDATA;
+                        }
+                    }
+
+                    /* scale & sum into subband */
+                    for(l = 0; l < 8; l++)
+                        subband_samples[l] += (float)block[l] * rscale;
+                }
+            }
+
+            /* check DSYNC marker */
+            if(s->aspf || subsubframe == s->subsubframes[subframe] - 1) {
+                if(get_bits(&s->gb, 16) != 0xffff) {
+                    av_log(s->avctx, AV_LOG_ERROR, "DTS-XBR: Didn't get subframe DSYNC\n");
+                    return AVERROR_INVALIDDATA;
+                }
+            }
+
+            /* advance sub-sub-frame index */
+            if(++subsubframe >= s->subsubframes[subframe]) {
+                subsubframe = 0;
+                subframe++;
+            }
+        }
+
+        /* skip to next channel set */
+        i = get_bits_count(&s->gb);
+        if(start_posn + chset_fsize[chset] * 8 != i) {
+            j = start_posn + chset_fsize[chset] * 8 - i;
+            if(j < 0 || j >= 8)
+                av_log(s->avctx, AV_LOG_ERROR, "DTS-XBR: end of channel set,"
+                       " skipping further than expected (%d bits)\n", j);
+            skip_bits_long(&s->gb, j);
+        }
+    }
+
+    return 0;
+}
+
+/* parse initial header for XXCH and dump details */
+static int dca_xxch_decode_frame(DCAContext *s)
+{
+    int hdr_size, spkmsk_bits, num_chsets, core_spk, hdr_pos;
+    int i, chset, base_channel, chstart, fsize[8];
+
+    /* assume header word has already been parsed */
+    hdr_pos     = get_bits_count(&s->gb) - 32;
+    hdr_size    = get_bits(&s->gb, 6) + 1;
+  /*chhdr_crc   =*/ skip_bits1(&s->gb);
+    spkmsk_bits = get_bits(&s->gb, 5) + 1;
+    num_chsets  = get_bits(&s->gb, 2) + 1;
+
+    for (i = 0; i < num_chsets; i++)
+        fsize[i] = get_bits(&s->gb, 14) + 1;
+
+    core_spk               = get_bits(&s->gb, spkmsk_bits);
+    s->xxch_core_spkmask   = core_spk;
+    s->xxch_nbits_spk_mask = spkmsk_bits;
+    s->xxch_downmix        = 0;
+    s->xxch_dmix_embedded  = 0;
+
+    /* skip to the end of the header */
+    i = get_bits_count(&s->gb);
+    if (hdr_pos + hdr_size * 8 > i)
+        skip_bits_long(&s->gb, hdr_pos + hdr_size * 8 - i);
+
+    for (chset = 0; chset < num_chsets; chset++) {
+        chstart       = get_bits_count(&s->gb);
+        base_channel  = s->prim_channels;
+        s->xxch_chset = chset;
+
+        /* XXCH and Core headers differ, see 6.4.2 "XXCH Channel Set Header" vs.
+           5.3.2 "Primary Audio Coding Header", DTS Spec 1.3.1 */
+        dca_parse_audio_coding_header(s, base_channel, 1);
+
+        /* decode channel data */
+        for (i = 0; i < (s->sample_blocks / 8); i++) {
+            if (dca_decode_block(s, base_channel, i)) {
+                av_log(s->avctx, AV_LOG_ERROR,
+                       "Error decoding DTS-XXCH extension\n");
+                continue;
+            }
+        }
+
+        /* skip to end of this section */
+        i = get_bits_count(&s->gb);
+        if (chstart + fsize[chset] * 8 > i)
+            skip_bits_long(&s->gb, chstart + fsize[chset] * 8 - i);
+    }
+    s->xxch_chset = num_chsets;
+
+    return 0;
+}
+
 /**
  * Parse extension substream header (HD)
  */
 static void dca_exss_parse_header(DCAContext *s)
 {
+    int asset_size[8];
     int ss_index;
     int blownup;
     int num_audiop = 1;
     int num_assets = 1;
     int active_ss_mask[8];
     int i, j;
+    int start_posn;
+    int hdrsize;
+    uint32_t mkr;
 
     if (get_bits_left(&s->gb) < 52)
         return;
 
+    start_posn = get_bits_count(&s->gb) - 32;
+
     skip_bits(&s->gb, 8); // user data
     ss_index = get_bits(&s->gb, 2);
 
     blownup = get_bits1(&s->gb);
-    skip_bits(&s->gb,  8 + 4 * blownup); // header_size
+    hdrsize = get_bits(&s->gb,  8 + 4 * blownup) + 1; // header_size
     skip_bits(&s->gb, 16 + 4 * blownup); // hd_size
 
     s->static_fields = get_bits1(&s->gb);
@@ -1630,7 +2013,7 @@
     }
 
     for (i = 0; i < num_assets; i++)
-        skip_bits_long(&s->gb, 16 + 4 * blownup);  // asset size
+        asset_size[i] = get_bits_long(&s->gb, 16 + 4 * blownup);
 
     for (i = 0; i < num_assets; i++) {
         if (dca_exss_parse_asset_header(s))
@@ -1639,6 +2022,33 @@
 
     /* not parsed further, we were only interested in the extensions mask
      * from the asset header */
+
+    if (num_assets > 0) {
+        j = get_bits_count(&s->gb);
+        if (start_posn + hdrsize * 8 > j)
+            skip_bits_long(&s->gb, start_posn + hdrsize * 8 - j);
+
+        for (i = 0; i < num_assets; i++) {
+            start_posn = get_bits_count(&s->gb);
+            mkr        = get_bits_long(&s->gb, 32);
+
+            /* parse extensions that we know about */
+            if (mkr == 0x655e315e) {
+                dca_xbr_parse_frame(s);
+            } else if (mkr == 0x47004a03) {
+                dca_xxch_decode_frame(s);
+                s->core_ext_mask |= DCA_EXT_XXCH; /* xxx use for chan reordering */
+            } else {
+                av_log(s->avctx, AV_LOG_DEBUG,
+                       "DTS-ExSS: unknown marker = 0x%08x\n", mkr);
+            }
+
+            /* skip to end of block */
+            j = get_bits_count(&s->gb);
+            if (start_posn + asset_size[i] * 8 > j)
+                skip_bits_long(&s->gb, start_posn + asset_size[i] * 8 - j);
+        }
+    }
 }
 
 /**
@@ -1650,15 +2060,25 @@
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
-
+    int channel_mask;
+    int channel_layout;
     int lfe_samples;
     int num_core_channels = 0;
     int i, ret;
-    float  **samples_flt;
+    float **samples_flt;
+    float *src_chan;
+    float *dst_chan;
     DCAContext *s = avctx->priv_data;
-    int channels;
     int core_ss_end;
-
+    int channels;
+    float scale;
+    int achan;
+    int chset;
+    int mask;
+    int lavc;
+    int posn;
+    int j, k;
+    int endch;
 
     s->xch_present = 0;
 
@@ -1699,7 +2119,7 @@
 
     /* only scan for extensions if ext_descr was unknown or indicated a
      * supported XCh extension */
-    if (s->core_ext_mask < 0 || s->core_ext_mask & DCA_EXT_XCH) {
+    if (s->core_ext_mask < 0 || s->core_ext_mask & (DCA_EXT_XCH | DCA_EXT_XXCH)) {
 
         /* if ext_descr was unknown, clear s->core_ext_mask so that the
          * extensions scan can fill it up */
@@ -1737,7 +2157,7 @@
                 }
 
                 /* much like core primary audio coding header */
-                dca_parse_audio_coding_header(s, s->xch_base_channel);
+                dca_parse_audio_coding_header(s, s->xch_base_channel, 0);
 
                 for (i = 0; i < (s->sample_blocks / 8); i++)
                     if ((ret = dca_decode_block(s, s->xch_base_channel, i))) {
@@ -1753,6 +2173,7 @@
                 /* usually found either in core or HD part in DTS-HD HRA streams,
                  * but not in DTS-ES which contains XCh extensions instead */
                 s->core_ext_mask |= DCA_EXT_XXCH;
+                dca_xxch_decode_frame(s);
                 break;
 
             case 0x1d95f262: {
@@ -1792,56 +2213,123 @@
 
     channels = s->prim_channels + !!s->lfe;
 
-    if (s->amode < 16) {
-        avctx->channel_layout = dca_core_channel_layout[s->amode];
+    /* If we have XXCH then the channel layout is managed differently */
+    /* note that XLL will also have another way to do things */
+    if (!(s->core_ext_mask & DCA_EXT_XXCH)
+        || (s->core_ext_mask & DCA_EXT_XXCH && avctx->request_channels > 0
+            && avctx->request_channels
+            < num_core_channels + !!s->lfe + s->xxch_chset_nch[0]))
+    { /* xxx should also do MA extensions */
+        if (s->amode < 16) {
+            avctx->channel_layout = dca_core_channel_layout[s->amode];
 
-        if (s->xch_present && (!avctx->request_channels ||
-                               avctx->request_channels > num_core_channels + !!s->lfe)) {
-            avctx->channel_layout |= AV_CH_BACK_CENTER;
-            if (s->lfe) {
-                avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
-                s->channel_order_tab = dca_channel_reorder_lfe_xch[s->amode];
+            if (s->xch_present && (!avctx->request_channels ||
+                                   avctx->request_channels
+                                   > num_core_channels + !!s->lfe)) {
+                avctx->channel_layout |= AV_CH_BACK_CENTER;
+                if (s->lfe) {
+                    avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
+                    s->channel_order_tab = dca_channel_reorder_lfe_xch[s->amode];
+                } else {
+                    s->channel_order_tab = dca_channel_reorder_nolfe_xch[s->amode];
+                }
             } else {
-                s->channel_order_tab = dca_channel_reorder_nolfe_xch[s->amode];
+                channels = num_core_channels + !!s->lfe;
+                s->xch_present = 0; /* disable further xch processing */
+                if (s->lfe) {
+                    avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
+                    s->channel_order_tab = dca_channel_reorder_lfe[s->amode];
+                } else
+                    s->channel_order_tab = dca_channel_reorder_nolfe[s->amode];
+            }
+
+            if (channels > !!s->lfe &&
+                s->channel_order_tab[channels - 1 - !!s->lfe] < 0)
+                return AVERROR_INVALIDDATA;
+
+            if (avctx->request_channels == 2 && s->prim_channels > 2) {
+                channels = 2;
+                s->output = DCA_STEREO;
+                avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+            }
+            else if (avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE) {
+                static const int8_t dca_channel_order_native[9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
+                s->channel_order_tab = dca_channel_order_native;
+            }
+            s->lfe_index = dca_lfe_index[s->amode];
+        } else {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Non standard configuration %d !\n", s->amode);
+            return AVERROR_INVALIDDATA;
+        }
+
+        s->xxch_downmix = 0;
+    } else {
+        /* we only get here if an XXCH channel set can be added to the mix */
+        channel_mask = s->xxch_core_spkmask;
+
+        if (avctx->request_channels > 0
+            && avctx->request_channels < s->prim_channels) {
+            channels = num_core_channels + !!s->lfe;
+            for (i = 0; i < s->xxch_chset && channels + s->xxch_chset_nch[i]
+                                              <= avctx->request_channels; i++) {
+                channels += s->xxch_chset_nch[i];
+                channel_mask |= s->xxch_spk_masks[i];
             }
         } else {
-            channels = num_core_channels + !!s->lfe;
-            s->xch_present = 0; /* disable further xch processing */
-            if (s->lfe) {
-                avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
-                s->channel_order_tab = dca_channel_reorder_lfe[s->amode];
-            } else
-                s->channel_order_tab = dca_channel_reorder_nolfe[s->amode];
+            channels = s->prim_channels + !!s->lfe;
+            for (i = 0; i < s->xxch_chset; i++) {
+                channel_mask |= s->xxch_spk_masks[i];
+            }
         }
 
-        if (channels > !!s->lfe &&
-            s->channel_order_tab[channels - 1 - !!s->lfe] < 0)
+        /* Given the DTS spec'ed channel mask, generate an avcodec version */
+        channel_layout = 0;
+        for (i = 0; i < s->xxch_nbits_spk_mask; ++i) {
+            if (channel_mask & (1 << i)) {
+                channel_layout |= map_xxch_to_native[i];
+            }
+        }
+
+        /* make sure that we have managed to get equivelant dts/avcodec channel
+         * masks in some sense -- unfortunately some channels could overlap */
+        if (av_popcount(channel_mask) != av_popcount(channel_layout)) {
+            av_log(avctx, AV_LOG_DEBUG,
+                   "DTS-XXCH: Inconsistant avcodec/dts channel layouts\n");
             return AVERROR_INVALIDDATA;
-
-        if (avctx->request_channels == 2 && s->prim_channels > 2) {
-            channels = 2;
-            s->output = DCA_STEREO;
-            avctx->channel_layout = AV_CH_LAYOUT_STEREO;
         }
-    } else {
-        av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n", s->amode);
-        return AVERROR_INVALIDDATA;
+
+        avctx->channel_layout = channel_layout;
+
+        if (!(avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE)) {
+            /* Estimate DTS --> avcodec ordering table */
+            for (chset = -1, j = 0; chset < s->xxch_chset; ++chset) {
+                mask = chset >= 0 ? s->xxch_spk_masks[chset]
+                                  : s->xxch_core_spkmask;
+                for (i = 0; i < s->xxch_nbits_spk_mask; i++) {
+                    if (mask & ~(DCA_XXCH_LFE1 | DCA_XXCH_LFE2) & (1 << i)) {
+                        lavc = map_xxch_to_native[i];
+                        posn = av_popcount(channel_layout & (lavc - 1));
+                        s->xxch_order_tab[j++] = posn;
+                    }
+                }
+            }
+
+            s->lfe_index = av_popcount(channel_layout & (AV_CH_LOW_FREQUENCY-1));
+        } else { /* native ordering */
+            for (i = 0; i < channels; i++)
+                s->xxch_order_tab[i] = i;
+
+            s->lfe_index = channels - 1;
+        }
+
+        s->channel_order_tab = s->xxch_order_tab;
     }
 
-
-    /* There is nothing that prevents a dts frame to change channel configuration
-       but Libav doesn't support that so only set the channels if it is previously
-       unset. Ideally during the first probe for channels the crc should be checked
-       and only set avctx->channels when the crc is ok. Right now the decoder could
-       set the channels based on a broken first frame.*/
-    if (s->is_channels_set == 0) {
-        s->is_channels_set = 1;
-        avctx->channels = channels;
-    }
     if (avctx->channels != channels) {
-        av_log(avctx, AV_LOG_ERROR, "DCA decoder does not support number of "
-               "channels changing in stream. Skipping frame.\n");
-        return AVERROR_PATCHWELCOME;
+        if (avctx->channels)
+            av_log(avctx, AV_LOG_INFO, "Number of channels changed in DCA decoder (%d -> %d)\n", avctx->channels, channels);
+        avctx->channels = channels;
     }
 
     /* get output buffer */
@@ -1870,6 +2358,53 @@
             s->fdsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);
             s->fdsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256);
         }
+
+        /* If stream contains XXCH, we might need to undo an embedded downmix */
+        if (s->xxch_dmix_embedded) {
+            /* Loop over channel sets in turn */
+            ch = num_core_channels;
+            for (chset = 0; chset < s->xxch_chset; chset++) {
+                endch = ch + s->xxch_chset_nch[chset];
+                mask = s->xxch_dmix_embedded;
+
+                /* undo downmix */
+                for (j = ch; j < endch; j++) {
+                    if (mask & (1 << j)) { /* this channel has been mixed-out */
+                        src_chan = s->samples_chanptr[s->channel_order_tab[j]];
+                        for (k = 0; k < endch; k++) {
+                            achan = s->channel_order_tab[k];
+                            scale = s->xxch_dmix_coeff[j][k];
+                            if (scale != 0.0) {
+                                dst_chan = s->samples_chanptr[achan];
+                                s->fdsp.vector_fmac_scalar(dst_chan, src_chan,
+                                                           -scale, 256);
+                            }
+                        }
+                    }
+                }
+
+                /* if a downmix has been embedded then undo the pre-scaling */
+                if ((mask & (1 << ch)) && s->xxch_dmix_sf[chset] != 1.0f) {
+                    scale = s->xxch_dmix_sf[chset];
+
+                    for (j = 0; j < ch; j++) {
+                        src_chan = s->samples_chanptr[s->channel_order_tab[j]];
+                        for (k = 0; k < 256; k++)
+                            src_chan[k] *= scale;
+                    }
+
+                    /* LFE channel is always part of core, scale if it exists */
+                    if (s->lfe) {
+                        src_chan = s->samples_chanptr[s->lfe_index];
+                        for (k = 0; k < 256; k++)
+                            src_chan[k] *= scale;
+                    }
+                }
+
+                ch = endch;
+            }
+
+        }
     }
 
     /* update lfe history */
diff --git a/libavcodec/dcadsp.c b/libavcodec/dcadsp.c
index 14932e6..dd4994d 100644
--- a/libavcodec/dcadsp.c
+++ b/libavcodec/dcadsp.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2004 Gildas Bazin
  * Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dcadsp.h b/libavcodec/dcadsp.h
index 3c6f1f9..bb157f7 100644
--- a/libavcodec/dcadsp.h
+++ b/libavcodec/dcadsp.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c
new file mode 100644
index 0000000..104fd87
--- /dev/null
+++ b/libavcodec/dcaenc.c
@@ -0,0 +1,603 @@
+/*
+ * DCA encoder
+ * Copyright (C) 2008 Alexander E. Patrakov
+ *               2010 Benjamin Larsson
+ *               2011 Xiang Wang
+ *
+ * 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 "libavutil/avassert.h"
+#include "libavutil/audioconvert.h"
+#include "avcodec.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "put_bits.h"
+#include "dcaenc.h"
+#include "dcadata.h"
+#include "dca.h"
+
+#undef NDEBUG
+
+#define MAX_CHANNELS 6
+#define DCA_SUBBANDS_32 32
+#define DCA_MAX_FRAME_SIZE 16383
+#define DCA_HEADER_SIZE 13
+
+#define DCA_SUBBANDS 32 ///< Subband activity count
+#define QUANTIZER_BITS 16
+#define SUBFRAMES 1
+#define SUBSUBFRAMES 4
+#define PCM_SAMPLES (SUBFRAMES*SUBSUBFRAMES*8)
+#define LFE_BITS 8
+#define LFE_INTERPOLATION 64
+#define LFE_PRESENT 2
+#define LFE_MISSING 0
+
+static const int8_t dca_lfe_index[] = {
+    1,2,2,2,2,3,2,3,2,3,2,3,1,3,2,3
+};
+
+static const int8_t dca_channel_reorder_lfe[][9] = {
+    { 0, -1, -1, -1, -1, -1, -1, -1, -1 },
+    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
+    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
+    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
+    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
+    { 1,  2,  0, -1, -1, -1, -1, -1, -1 },
+    { 0,  1, -1,  2, -1, -1, -1, -1, -1 },
+    { 1,  2,  0, -1,  3, -1, -1, -1, -1 },
+    { 0,  1, -1,  2,  3, -1, -1, -1, -1 },
+    { 1,  2,  0, -1,  3,  4, -1, -1, -1 },
+    { 2,  3, -1,  0,  1,  4,  5, -1, -1 },
+    { 1,  2,  0, -1,  3,  4,  5, -1, -1 },
+    { 0, -1,  4,  5,  2,  3,  1, -1, -1 },
+    { 3,  4,  1, -1,  0,  2,  5,  6, -1 },
+    { 2,  3, -1,  5,  7,  0,  1,  4,  6 },
+    { 3,  4,  1, -1,  0,  2,  5,  7,  6 },
+};
+
+static const int8_t dca_channel_reorder_nolfe[][9] = {
+    { 0, -1, -1, -1, -1, -1, -1, -1, -1 },
+    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
+    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
+    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
+    { 0,  1, -1, -1, -1, -1, -1, -1, -1 },
+    { 1,  2,  0, -1, -1, -1, -1, -1, -1 },
+    { 0,  1,  2, -1, -1, -1, -1, -1, -1 },
+    { 1,  2,  0,  3, -1, -1, -1, -1, -1 },
+    { 0,  1,  2,  3, -1, -1, -1, -1, -1 },
+    { 1,  2,  0,  3,  4, -1, -1, -1, -1 },
+    { 2,  3,  0,  1,  4,  5, -1, -1, -1 },
+    { 1,  2,  0,  3,  4,  5, -1, -1, -1 },
+    { 0,  4,  5,  2,  3,  1, -1, -1, -1 },
+    { 3,  4,  1,  0,  2,  5,  6, -1, -1 },
+    { 2,  3,  5,  7,  0,  1,  4,  6, -1 },
+    { 3,  4,  1,  0,  2,  5,  7,  6, -1 },
+};
+
+typedef struct {
+    PutBitContext pb;
+    int32_t history[MAX_CHANNELS][512]; /* This is a circular buffer */
+    int start[MAX_CHANNELS];
+    int frame_size;
+    int prim_channels;
+    int lfe_channel;
+    int sample_rate_code;
+    int scale_factor[MAX_CHANNELS][DCA_SUBBANDS_32];
+    int lfe_scale_factor;
+    int lfe_data[SUBFRAMES*SUBSUBFRAMES*4];
+
+    int a_mode;                         ///< audio channels arrangement
+    int num_channel;
+    int lfe_state;
+    int lfe_offset;
+    const int8_t *channel_order_tab;    ///< channel reordering table, lfe and non lfe
+
+    int32_t pcm[FFMAX(LFE_INTERPOLATION, DCA_SUBBANDS_32)];
+    int32_t subband[PCM_SAMPLES][MAX_CHANNELS][DCA_SUBBANDS_32]; /* [sample][channel][subband] */
+} DCAContext;
+
+static int32_t cos_table[128];
+
+static inline int32_t mul32(int32_t a, int32_t b)
+{
+    int64_t r = (int64_t) a * b;
+    /* round the result before truncating - improves accuracy */
+    return (r + 0x80000000) >> 32;
+}
+
+/* Integer version of the cosine modulated Pseudo QMF */
+
+static void qmf_init(void)
+{
+    int i;
+    int32_t c[17], s[17];
+    s[0] = 0;           /* sin(index * PI / 64) * 0x7fffffff */
+    c[0] = 0x7fffffff;  /* cos(index * PI / 64) * 0x7fffffff */
+
+    for (i = 1; i <= 16; i++) {
+        s[i] = 2 * (mul32(c[i - 1], 105372028)  + mul32(s[i - 1], 2144896908));
+        c[i] = 2 * (mul32(c[i - 1], 2144896908) - mul32(s[i - 1], 105372028));
+    }
+
+    for (i = 0; i < 16; i++) {
+        cos_table[i      ]  =  c[i]      >> 3; /* avoid output overflow */
+        cos_table[i +  16]  =  s[16 - i] >> 3;
+        cos_table[i +  32]  = -s[i]      >> 3;
+        cos_table[i +  48]  = -c[16 - i] >> 3;
+        cos_table[i +  64]  = -c[i]      >> 3;
+        cos_table[i +  80]  = -s[16 - i] >> 3;
+        cos_table[i +  96]  =  s[i]      >> 3;
+        cos_table[i + 112]  =  c[16 - i] >> 3;
+    }
+}
+
+static int32_t band_delta_factor(int band, int sample_num)
+{
+    int index = band * (2 * sample_num + 1);
+    if (band == 0)
+        return 0x07ffffff;
+    else
+        return cos_table[index & 127];
+}
+
+static void add_new_samples(DCAContext *c, const int32_t *in,
+                            int count, int channel)
+{
+    int i;
+
+    /* Place new samples into the history buffer */
+    for (i = 0; i < count; i++) {
+        c->history[channel][c->start[channel] + i] = in[i];
+        av_assert0(c->start[channel] + i < 512);
+    }
+    c->start[channel] += count;
+    if (c->start[channel] == 512)
+        c->start[channel] = 0;
+    av_assert0(c->start[channel] < 512);
+}
+
+static void qmf_decompose(DCAContext *c, int32_t in[32], int32_t out[32],
+                          int channel)
+{
+    int band, i, j, k;
+    int32_t resp;
+    int32_t accum[DCA_SUBBANDS_32] = {0};
+
+    add_new_samples(c, in, DCA_SUBBANDS_32, channel);
+
+    /* Calculate the dot product of the signal with the (possibly inverted)
+       reference decoder's response to this vector:
+       (0.0, 0.0, ..., 0.0, -1.0, 1.0, 0.0, ..., 0.0)
+       so that -1.0 cancels 1.0 from the previous step */
+
+    for (k = 48, j = 0, i = c->start[channel]; i < 512; k++, j++, i++)
+        accum[(k & 32) ? (31 - (k & 31)) : (k & 31)] += mul32(c->history[channel][i], UnQMF[j]);
+    for (i = 0; i < c->start[channel]; k++, j++, i++)
+        accum[(k & 32) ? (31 - (k & 31)) : (k & 31)] += mul32(c->history[channel][i], UnQMF[j]);
+
+    resp = 0;
+    /* TODO: implement FFT instead of this naive calculation */
+    for (band = 0; band < DCA_SUBBANDS_32; band++) {
+        for (j = 0; j < 32; j++)
+            resp += mul32(accum[j], band_delta_factor(band, j));
+
+        out[band] = (band & 2) ? (-resp) : resp;
+    }
+}
+
+static int32_t lfe_fir_64i[512];
+static int lfe_downsample(DCAContext *c, int32_t in[LFE_INTERPOLATION])
+{
+    int i, j;
+    int channel = c->prim_channels;
+    int32_t accum = 0;
+
+    add_new_samples(c, in, LFE_INTERPOLATION, channel);
+    for (i = c->start[channel], j = 0; i < 512; i++, j++)
+        accum += mul32(c->history[channel][i], lfe_fir_64i[j]);
+    for (i = 0; i < c->start[channel]; i++, j++)
+        accum += mul32(c->history[channel][i], lfe_fir_64i[j]);
+    return accum;
+}
+
+static void init_lfe_fir(void)
+{
+    static int initialized = 0;
+    int i;
+    if (initialized)
+        return;
+
+    for (i = 0; i < 512; i++)
+        lfe_fir_64i[i] = lfe_fir_64[i] * (1 << 25); //float -> int32_t
+    initialized = 1;
+}
+
+static void put_frame_header(DCAContext *c)
+{
+    /* SYNC */
+    put_bits(&c->pb, 16, 0x7ffe);
+    put_bits(&c->pb, 16, 0x8001);
+
+    /* Frame type: normal */
+    put_bits(&c->pb, 1, 1);
+
+    /* Deficit sample count: none */
+    put_bits(&c->pb, 5, 31);
+
+    /* CRC is not present */
+    put_bits(&c->pb, 1, 0);
+
+    /* Number of PCM sample blocks */
+    put_bits(&c->pb, 7, PCM_SAMPLES-1);
+
+    /* Primary frame byte size */
+    put_bits(&c->pb, 14, c->frame_size-1);
+
+    /* Audio channel arrangement: L + R (stereo) */
+    put_bits(&c->pb, 6, c->num_channel);
+
+    /* Core audio sampling frequency */
+    put_bits(&c->pb, 4, c->sample_rate_code);
+
+    /* Transmission bit rate: 1411.2 kbps */
+    put_bits(&c->pb, 5, 0x16); /* FIXME: magic number */
+
+    /* Embedded down mix: disabled */
+    put_bits(&c->pb, 1, 0);
+
+    /* Embedded dynamic range flag: not present */
+    put_bits(&c->pb, 1, 0);
+
+    /* Embedded time stamp flag: not present */
+    put_bits(&c->pb, 1, 0);
+
+    /* Auxiliary data flag: not present */
+    put_bits(&c->pb, 1, 0);
+
+    /* HDCD source: no */
+    put_bits(&c->pb, 1, 0);
+
+    /* Extension audio ID: N/A */
+    put_bits(&c->pb, 3, 0);
+
+    /* Extended audio data: not present */
+    put_bits(&c->pb, 1, 0);
+
+    /* Audio sync word insertion flag: after each sub-frame */
+    put_bits(&c->pb, 1, 0);
+
+    /* Low frequency effects flag: not present or interpolation factor=64 */
+    put_bits(&c->pb, 2, c->lfe_state);
+
+    /* Predictor history switch flag: on */
+    put_bits(&c->pb, 1, 1);
+
+    /* No CRC */
+    /* Multirate interpolator switch: non-perfect reconstruction */
+    put_bits(&c->pb, 1, 0);
+
+    /* Encoder software revision: 7 */
+    put_bits(&c->pb, 4, 7);
+
+    /* Copy history: 0 */
+    put_bits(&c->pb, 2, 0);
+
+    /* Source PCM resolution: 16 bits, not DTS ES */
+    put_bits(&c->pb, 3, 0);
+
+    /* Front sum/difference coding: no */
+    put_bits(&c->pb, 1, 0);
+
+    /* Surrounds sum/difference coding: no */
+    put_bits(&c->pb, 1, 0);
+
+    /* Dialog normalization: 0 dB */
+    put_bits(&c->pb, 4, 0);
+}
+
+static void put_primary_audio_header(DCAContext *c)
+{
+    static const int bitlen[11] = { 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 };
+    static const int thr[11]    = { 0, 1, 3, 3, 3, 3, 7, 7, 7, 7, 7 };
+
+    int ch, i;
+    /* Number of subframes */
+    put_bits(&c->pb, 4, SUBFRAMES - 1);
+
+    /* Number of primary audio channels */
+    put_bits(&c->pb, 3, c->prim_channels - 1);
+
+    /* Subband activity count */
+    for (ch = 0; ch < c->prim_channels; ch++)
+        put_bits(&c->pb, 5, DCA_SUBBANDS - 2);
+
+    /* High frequency VQ start subband */
+    for (ch = 0; ch < c->prim_channels; ch++)
+        put_bits(&c->pb, 5, DCA_SUBBANDS - 1);
+
+    /* Joint intensity coding index: 0, 0 */
+    for (ch = 0; ch < c->prim_channels; ch++)
+        put_bits(&c->pb, 3, 0);
+
+    /* Transient mode codebook: A4, A4 (arbitrary) */
+    for (ch = 0; ch < c->prim_channels; ch++)
+        put_bits(&c->pb, 2, 0);
+
+    /* Scale factor code book: 7 bit linear, 7-bit sqrt table (for each channel) */
+    for (ch = 0; ch < c->prim_channels; ch++)
+        put_bits(&c->pb, 3, 6);
+
+    /* Bit allocation quantizer select: linear 5-bit */
+    for (ch = 0; ch < c->prim_channels; ch++)
+        put_bits(&c->pb, 3, 6);
+
+    /* Quantization index codebook select: dummy data
+       to avoid transmission of scale factor adjustment */
+
+    for (i = 1; i < 11; i++)
+        for (ch = 0; ch < c->prim_channels; ch++)
+            put_bits(&c->pb, bitlen[i], thr[i]);
+
+    /* Scale factor adjustment index: not transmitted */
+}
+
+/**
+ * 8-23 bits quantization
+ * @param sample
+ * @param bits
+ */
+static inline uint32_t quantize(int32_t sample, int bits)
+{
+    av_assert0(sample <    1 << (bits - 1));
+    av_assert0(sample >= -(1 << (bits - 1)));
+    return sample & ((1 << bits) - 1);
+}
+
+static inline int find_scale_factor7(int64_t max_value, int bits)
+{
+    int i = 0, j = 128, q;
+    max_value = ((max_value << 15) / lossy_quant[bits + 3]) >> (bits - 1);
+    while (i < j) {
+        q = (i + j) >> 1;
+        if (max_value < scale_factor_quant7[q])
+            j = q;
+        else
+            i = q + 1;
+    }
+    av_assert1(i < 128);
+    return i;
+}
+
+static inline void put_sample7(DCAContext *c, int64_t sample, int bits,
+                               int scale_factor)
+{
+    sample = (sample << 15) / ((int64_t) lossy_quant[bits + 3] * scale_factor_quant7[scale_factor]);
+    put_bits(&c->pb, bits, quantize((int) sample, bits));
+}
+
+static void put_subframe(DCAContext *c,
+                         int32_t subband_data[8 * SUBSUBFRAMES][MAX_CHANNELS][32],
+                         int subframe)
+{
+    int i, sub, ss, ch, max_value;
+    int32_t *lfe_data = c->lfe_data + 4 * SUBSUBFRAMES * subframe;
+
+    /* Subsubframes count */
+    put_bits(&c->pb, 2, SUBSUBFRAMES -1);
+
+    /* Partial subsubframe sample count: dummy */
+    put_bits(&c->pb, 3, 0);
+
+    /* Prediction mode: no ADPCM, in each channel and subband */
+    for (ch = 0; ch < c->prim_channels; ch++)
+        for (sub = 0; sub < DCA_SUBBANDS; sub++)
+            put_bits(&c->pb, 1, 0);
+
+    /* Prediction VQ addres: not transmitted */
+    /* Bit allocation index */
+    for (ch = 0; ch < c->prim_channels; ch++)
+        for (sub = 0; sub < DCA_SUBBANDS; sub++)
+            put_bits(&c->pb, 5, QUANTIZER_BITS+3);
+
+    if (SUBSUBFRAMES > 1) {
+        /* Transition mode: none for each channel and subband */
+        for (ch = 0; ch < c->prim_channels; ch++)
+            for (sub = 0; sub < DCA_SUBBANDS; sub++)
+                put_bits(&c->pb, 1, 0); /* codebook A4 */
+    }
+
+    /* Determine scale_factor */
+    for (ch = 0; ch < c->prim_channels; ch++)
+        for (sub = 0; sub < DCA_SUBBANDS; sub++) {
+            max_value = 0;
+            for (i = 0; i < 8 * SUBSUBFRAMES; i++)
+                max_value = FFMAX(max_value, FFABS(subband_data[i][ch][sub]));
+            c->scale_factor[ch][sub] = find_scale_factor7(max_value, QUANTIZER_BITS);
+        }
+
+    if (c->lfe_channel) {
+        max_value = 0;
+        for (i = 0; i < 4 * SUBSUBFRAMES; i++)
+            max_value = FFMAX(max_value, FFABS(lfe_data[i]));
+        c->lfe_scale_factor = find_scale_factor7(max_value, LFE_BITS);
+    }
+
+    /* Scale factors: the same for each channel and subband,
+       encoded according to Table D.1.2 */
+    for (ch = 0; ch < c->prim_channels; ch++)
+        for (sub = 0; sub < DCA_SUBBANDS; sub++)
+            put_bits(&c->pb, 7, c->scale_factor[ch][sub]);
+
+    /* Joint subband scale factor codebook select: not transmitted */
+    /* Scale factors for joint subband coding: not transmitted */
+    /* Stereo down-mix coefficients: not transmitted */
+    /* Dynamic range coefficient: not transmitted */
+    /* Stde information CRC check word: not transmitted */
+    /* VQ encoded high frequency subbands: not transmitted */
+
+    /* LFE data */
+    if (c->lfe_channel) {
+        for (i = 0; i < 4 * SUBSUBFRAMES; i++)
+            put_sample7(c, lfe_data[i], LFE_BITS, c->lfe_scale_factor);
+        put_bits(&c->pb, 8, c->lfe_scale_factor);
+    }
+
+    /* Audio data (subsubframes) */
+
+    for (ss = 0; ss < SUBSUBFRAMES ; ss++)
+        for (ch = 0; ch < c->prim_channels; ch++)
+            for (sub = 0; sub < DCA_SUBBANDS; sub++)
+                for (i = 0; i < 8; i++)
+                    put_sample7(c, subband_data[ss * 8 + i][ch][sub], QUANTIZER_BITS, c->scale_factor[ch][sub]);
+
+    /* DSYNC */
+    put_bits(&c->pb, 16, 0xffff);
+}
+
+static void put_frame(DCAContext *c,
+                      int32_t subband_data[PCM_SAMPLES][MAX_CHANNELS][32],
+                      uint8_t *frame)
+{
+    int i;
+    init_put_bits(&c->pb, frame + DCA_HEADER_SIZE, DCA_MAX_FRAME_SIZE-DCA_HEADER_SIZE);
+
+    put_primary_audio_header(c);
+    for (i = 0; i < SUBFRAMES; i++)
+        put_subframe(c, &subband_data[SUBSUBFRAMES * 8 * i], i);
+
+    flush_put_bits(&c->pb);
+    c->frame_size = (put_bits_count(&c->pb) >> 3) + DCA_HEADER_SIZE;
+
+    init_put_bits(&c->pb, frame, DCA_HEADER_SIZE);
+    put_frame_header(c);
+    flush_put_bits(&c->pb);
+}
+
+static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
+                        const AVFrame *frame, int *got_packet_ptr)
+{
+    int i, k, channel;
+    DCAContext *c = avctx->priv_data;
+    const int16_t *samples;
+    int ret, real_channel = 0;
+
+    if ((ret = ff_alloc_packet2(avctx, avpkt, DCA_MAX_FRAME_SIZE + DCA_HEADER_SIZE)))
+        return ret;
+
+    samples = (const int16_t *)frame->data[0];
+    for (i = 0; i < PCM_SAMPLES; i ++) { /* i is the decimated sample number */
+        for (channel = 0; channel < c->prim_channels + 1; channel++) {
+            real_channel = c->channel_order_tab[channel];
+            if (real_channel >= 0) {
+                /* Get 32 PCM samples */
+                for (k = 0; k < 32; k++) { /* k is the sample number in a 32-sample block */
+                    c->pcm[k] = samples[avctx->channels * (32 * i + k) + channel] << 16;
+                }
+                /* Put subband samples into the proper place */
+                qmf_decompose(c, c->pcm, &c->subband[i][real_channel][0], real_channel);
+            }
+        }
+    }
+
+    if (c->lfe_channel) {
+        for (i = 0; i < PCM_SAMPLES / 2; i++) {
+            for (k = 0; k < LFE_INTERPOLATION; k++) /* k is the sample number in a 32-sample block */
+                c->pcm[k] = samples[avctx->channels * (LFE_INTERPOLATION*i+k) + c->lfe_offset] << 16;
+            c->lfe_data[i] = lfe_downsample(c, c->pcm);
+        }
+    }
+
+    put_frame(c, c->subband, avpkt->data);
+
+    avpkt->size     = c->frame_size;
+    *got_packet_ptr = 1;
+    return 0;
+}
+
+static int encode_init(AVCodecContext *avctx)
+{
+    DCAContext *c = avctx->priv_data;
+    int i;
+    uint64_t layout = avctx->channel_layout;
+
+    c->prim_channels = avctx->channels;
+    c->lfe_channel   = (avctx->channels == 3 || avctx->channels == 6);
+
+    if (!layout) {
+        av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The "
+                                      "encoder will guess the layout, but it "
+                                      "might be incorrect.\n");
+        layout = av_get_default_channel_layout(avctx->channels);
+    }
+    switch (layout) {
+    case AV_CH_LAYOUT_STEREO:       c->a_mode = 2; c->num_channel = 2; break;
+    case AV_CH_LAYOUT_5POINT0:      c->a_mode = 9; c->num_channel = 9; break;
+    case AV_CH_LAYOUT_5POINT1:      c->a_mode = 9; c->num_channel = 9; break;
+    case AV_CH_LAYOUT_5POINT0_BACK: c->a_mode = 9; c->num_channel = 9; break;
+    case AV_CH_LAYOUT_5POINT1_BACK: c->a_mode = 9; c->num_channel = 9; break;
+    default:
+    av_log(avctx, AV_LOG_ERROR,
+           "Only stereo, 5.0, 5.1 channel layouts supported at the moment!\n");
+    return AVERROR_PATCHWELCOME;
+    }
+
+    if (c->lfe_channel) {
+        init_lfe_fir();
+        c->prim_channels--;
+        c->channel_order_tab = dca_channel_reorder_lfe[c->a_mode];
+        c->lfe_state         = LFE_PRESENT;
+        c->lfe_offset        = dca_lfe_index[c->a_mode];
+    } else {
+        c->channel_order_tab = dca_channel_reorder_nolfe[c->a_mode];
+        c->lfe_state         = LFE_MISSING;
+    }
+
+    for (i = 0; i < 16; i++) {
+        if (avpriv_dca_sample_rates[i] && (avpriv_dca_sample_rates[i] == avctx->sample_rate))
+            break;
+    }
+    if (i == 16) {
+        av_log(avctx, AV_LOG_ERROR, "Sample rate %iHz not supported, only ", avctx->sample_rate);
+        for (i = 0; i < 16; i++)
+            av_log(avctx, AV_LOG_ERROR, "%d, ", avpriv_dca_sample_rates[i]);
+        av_log(avctx, AV_LOG_ERROR, "supported.\n");
+        return -1;
+    }
+    c->sample_rate_code = i;
+
+    avctx->frame_size = 32 * PCM_SAMPLES;
+
+    if (!cos_table[127])
+        qmf_init();
+    return 0;
+}
+
+AVCodec ff_dca_encoder = {
+    .name           = "dca",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_DTS,
+    .priv_data_size = sizeof(DCAContext),
+    .init           = encode_init,
+    .encode2        = encode_frame,
+    .capabilities   = CODEC_CAP_EXPERIMENTAL,
+    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
+                                                     AV_SAMPLE_FMT_NONE },
+    .long_name      = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"),
+};
diff --git a/libavcodec/dcaenc.h b/libavcodec/dcaenc.h
new file mode 100644
index 0000000..121e5da
--- /dev/null
+++ b/libavcodec/dcaenc.h
@@ -0,0 +1,546 @@
+/*
+ * DCA encoder tables
+ * Copyright (C) 2008 Alexander E. Patrakov
+ *
+ * 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_DCAENC_H
+#define AVCODEC_DCAENC_H
+
+#include <stdint.h>
+
+/* This is a scaled version of the response of the reference decoder to
+   this vector of subband samples: ( 1.0 0.0 0.0 ... 0.0 )
+   */
+
+static const int32_t UnQMF[512] = {
+    7,
+    4,
+    -961,
+    -2844,
+    -8024,
+    -18978,
+    -32081,
+    -15635,
+    -16582,
+    -18359,
+    -17180,
+    -14868,
+    -11664,
+    -8051,
+    -4477,
+    -1327,
+    -1670,
+    -6019,
+    -11590,
+    -18030,
+    -24762,
+    -30965,
+    -35947,
+    -36145,
+    -37223,
+    -86311,
+    -57024,
+    -27215,
+    -11274,
+    -4684,
+    42,
+    108,
+    188,
+    250,
+    -1007,
+    -596,
+    -2289,
+    -12218,
+    -27191,
+    -124367,
+    -184256,
+    -250538,
+    -323499,
+    -397784,
+    -468855,
+    -532072,
+    -583000,
+    -618041,
+    -777916,
+    -783868,
+    -765968,
+    -724740,
+    -662468,
+    -583058,
+    -490548,
+    -401623,
+    -296090,
+    -73154,
+    -36711,
+    -7766,
+    -2363,
+    -4905,
+    2388,
+    2681,
+    5651,
+    4086,
+    71110,
+    139742,
+    188067,
+    151237,
+    101355,
+    309917,
+    343690,
+    358839,
+    357555,
+    334606,
+    289625,
+    224152,
+    142063,
+    48725,
+    74996,
+    238425,
+    411666,
+    584160,
+    744276,
+    880730,
+    983272,
+    1041933,
+    1054396,
+    789531,
+    851022,
+    864032,
+    675431,
+    418134,
+    35762,
+    66911,
+    103502,
+    136403,
+    -55147,
+    -245269,
+    -499595,
+    -808470,
+    -1136858,
+    -2010912,
+    -2581654,
+    -3151901,
+    -3696328,
+    -4196599,
+    -4633761,
+    -4993229,
+    -5262495,
+    -5436311,
+    -477650,
+    -901314,
+    -1308090,
+    -1677468,
+    -1985525,
+    -2212848,
+    -2341196,
+    -2373915,
+    -2269552,
+    -2620489,
+    -2173858,
+    -1629954,
+    -946595,
+    -193499,
+    1119459,
+    1138657,
+    1335311,
+    1126544,
+    2765033,
+    3139603,
+    3414913,
+    3599213,
+    3676363,
+    3448981,
+    3328726,
+    3111551,
+    2810887,
+    2428657,
+    1973684,
+    1457278,
+    893848,
+    300995,
+    -292521,
+    -867621,
+    -1404936,
+    -1871278,
+    -2229831,
+    -2440932,
+    -2462684,
+    -2255006,
+    -1768898,
+    -1079574,
+    82115,
+    1660302,
+    3660715,
+    6123610,
+    8329598,
+    11888744,
+    15722147,
+    19737089,
+    25647773,
+    31039399,
+    36868007,
+    43124253,
+    49737161,
+    56495958,
+    63668945,
+    71039511,
+    78540240,
+    86089058,
+    93600041,
+    100981151,
+    108136061,
+    114970055,
+    121718321,
+    127566038,
+    132774642,
+    137247294,
+    140894737,
+    143635018,
+    145395599,
+    146114032,
+    145742999,
+    144211606,
+    141594341,
+    137808404,
+    132914122,
+    126912246,
+    120243281,
+    112155281,
+    103338368,
+    93904953,
+    83439152,
+    72921548,
+    62192990,
+    51434918,
+    40894003,
+    30786726,
+    21384955,
+    12939112,
+    5718193,
+    -5790,
+    -3959261,
+    -5870978,
+    -5475538,
+    -2517061,
+    3247310,
+    12042937,
+    24076729,
+    39531397,
+    58562863,
+    81297002,
+    107826748,
+    138209187,
+    172464115,
+    210569037,
+    252468018,
+    298045453,
+    347168648,
+    399634888,
+    455137189,
+    513586535,
+    574537650,
+    637645129,
+    702597163,
+    768856566,
+    836022040,
+    903618096,
+    971159680,
+    1038137214,
+    1103987353,
+    1168195035,
+    1230223053,
+    1289539180,
+    1345620373,
+    1397957958,
+    1446063657,
+    1489474689,
+    1527740502,
+    1560502307,
+    1587383079,
+    1608071145,
+    1622301248,
+    1629859340,
+    1630584888,
+    1624373875,
+    1611178348,
+    1591018893,
+    1563948667,
+    1530105004,
+    1489673227,
+    1442904075,
+    1390107674,
+    1331590427,
+    1267779478,
+    1199115126,
+    1126053392,
+    1049146257,
+    968928307,
+    885965976,
+    800851610,
+    714186243,
+    626590147,
+    538672486,
+    451042824,
+    364299927,
+    279026812,
+    195785029,
+    115109565,
+    37503924,
+    -36564551,
+    -106668063,
+    -172421668,
+    -233487283,
+    -289575706,
+    -340448569,
+    -385919511,
+    -425854915,
+    -460174578,
+    -488840702,
+    -511893328,
+    -529405118,
+    -541489888,
+    -548312207,
+    -550036471,
+    -547005316,
+    -539436808,
+    -527630488,
+    -512084785,
+    -492941605,
+    -470665204,
+    -445668379,
+    -418328829,
+    -389072810,
+    -358293846,
+    -326396227,
+    -293769619,
+    -260792276,
+    -227825056,
+    -195208961,
+    -163262121,
+    -132280748,
+    -102533727,
+    -74230062,
+    -47600637,
+    -22817785,
+    -25786,
+    20662895,
+    39167253,
+    55438413,
+    69453741,
+    81242430,
+    90795329,
+    98213465,
+    103540643,
+    106917392,
+    108861938,
+    108539682,
+    106780704,
+    103722568,
+    99043289,
+    93608686,
+    87266209,
+    80212203,
+    72590022,
+    64603428,
+    56362402,
+    48032218,
+    39749162,
+    31638971,
+    23814664,
+    16376190,
+    9409836,
+    2988017,
+    -2822356,
+    -7976595,
+    -12454837,
+    -16241147,
+    -19331944,
+    -21735011,
+    -23468284,
+    -24559822,
+    -25042936,
+    -25035583,
+    -24429587,
+    -23346408,
+    -21860411,
+    -20015718,
+    -17025330,
+    -14968728,
+    -12487138,
+    -9656319,
+    -7846681,
+    -5197816,
+    -2621904,
+    -144953,
+    2144746,
+    3990570,
+    5845884,
+    7454650,
+    8820394,
+    9929891,
+    10784445,
+    11390921,
+    11762056,
+    11916017,
+    12261189,
+    12117604,
+    11815303,
+    11374622,
+    10815301,
+    10157241,
+    9418799,
+    8629399,
+    7780776,
+    7303680,
+    6353499,
+    5392738,
+    4457895,
+    3543062,
+    1305978,
+    1402521,
+    1084092,
+    965652,
+    -151008,
+    -666667,
+    -1032157,
+    -1231475,
+    -1319043,
+    -1006023,
+    -915720,
+    -773426,
+    -612377,
+    -445864,
+    -291068,
+    -161337,
+    -66484,
+    -11725,
+    133453,
+    388184,
+    615856,
+    804033,
+    942377,
+    1022911,
+    1041247,
+    995854,
+    891376,
+    572246,
+    457992,
+    316365,
+    172738,
+    43037,
+    -117662,
+    -98542,
+    -70279,
+    -41458,
+    -535790,
+    -959038,
+    -1364456,
+    -1502265,
+    -1568530,
+    -2378681,
+    -2701111,
+    -2976407,
+    -3182552,
+    -3314415,
+    -3366600,
+    -3337701,
+    -3232252,
+    -3054999,
+    1984841,
+    1925903,
+    1817377,
+    1669153,
+    1490069,
+    1292040,
+    1086223,
+    890983,
+    699163,
+    201358,
+    266971,
+    296990,
+    198419,
+    91119,
+    4737,
+    5936,
+    2553,
+    2060,
+    -3828,
+    -1664,
+    -4917,
+    -20796,
+    -36822,
+    -131247,
+    -154923,
+    -162055,
+    -161354,
+    -148762,
+    -125754,
+    -94473,
+    -57821,
+    -19096,
+    15172,
+    43004,
+    65624,
+    81354,
+    89325,
+    89524,
+    82766,
+    71075,
+    55128,
+    13686,
+    6921,
+    1449,
+    420,
+    785,
+    -215,
+    -179,
+    -113,
+    -49,
+    6002,
+    16007,
+    42978,
+    100662,
+    171472,
+    83975,
+    93702,
+    108813,
+    111893,
+    110272,
+    103914,
+    93973,
+    81606,
+    68041,
+    -54058,
+    -60695,
+    -65277,
+    -67224,
+    -66213,
+    -62082,
+    -55574,
+    -42988,
+    -35272,
+    -63735,
+    -33501,
+    -12671,
+    -4038,
+    -1232,
+    5,
+    7
+};
+
+#endif /* AVCODEC_DCAENC_H */
diff --git a/libavcodec/dcahuff.h b/libavcodec/dcahuff.h
index 254fc76..cbc8429 100644
--- a/libavcodec/dcahuff.h
+++ b/libavcodec/dcahuff.h
@@ -3,20 +3,20 @@
  * Copyright (C) 2004 Gildas Bazin
  * Copyright (C) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dct-test.c b/libavcodec/dct-test.c
index 848ba8a..6cefd9d 100644
--- a/libavcodec/dct-test.c
+++ b/libavcodec/dct-test.c
@@ -2,20 +2,20 @@
  * (c) 2001 Fabrice Bellard
  *     2007 Marc Hoffman <marc.hoffman@analog.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -48,6 +48,9 @@
 
 #undef printf
 
+void ff_mmx_idct(DCTELEM *data);
+void ff_mmxext_idct(DCTELEM *data);
+
 // BFIN
 void ff_bfin_idct(DCTELEM *block);
 void ff_bfin_fdct(DCTELEM *block);
@@ -68,7 +71,7 @@
     const char *name;
     void (*func)(DCTELEM *block);
     enum formattag { NO_PERM, MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM,
-                     SSE2_PERM, PARTTRANS_PERM } format;
+                     SSE2_PERM, PARTTRANS_PERM, TRANSPOSE_PERM } format;
     int mm_support;
     int nonspec;
 };
@@ -98,6 +101,23 @@
     { 0 }
 };
 
+#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);
+
+static void ff_prores_idct_put_10_sse2_wrap(DCTELEM *dst){
+    DECLARE_ALIGNED(16, static int16_t, qmat)[64];
+    DECLARE_ALIGNED(16, static int16_t, tmp)[64];
+    int i;
+
+    for(i=0; i<64; i++){
+        qmat[i]=4;
+        tmp[i]= dst[i];
+    }
+    ff_prores_idct_put_10_sse2(dst, 16, tmp, qmat);
+}
+#endif
+
 static const struct algo idct_tab[] = {
     { "FAANI",          ff_faanidct,           NO_PERM  },
     { "REF-DBL",        ff_ref_idct,           NO_PERM  },
@@ -105,10 +125,17 @@
     { "SIMPLE-C",       ff_simple_idct_8,      NO_PERM  },
 
 #if HAVE_MMX_INLINE
+#if CONFIG_GPL
+    { "LIBMPEG2-MMX",   ff_mmx_idct,           MMX_PERM,  AV_CPU_FLAG_MMX,  1 },
+    { "LIBMPEG2-MMX2",  ff_mmxext_idct,        MMX_PERM,  AV_CPU_FLAG_MMX2, 1 },
+#endif
     { "SIMPLE-MMX",     ff_simple_idct_mmx,  MMX_SIMPLE_PERM, AV_CPU_FLAG_MMX },
     { "XVID-MMX",       ff_idct_xvid_mmx,      NO_PERM,   AV_CPU_FLAG_MMX,  1 },
     { "XVID-MMXEXT",    ff_idct_xvid_mmx2,     NO_PERM,   AV_CPU_FLAG_MMXEXT, 1 },
     { "XVID-SSE2",      ff_idct_xvid_sse2,     SSE2_PERM, AV_CPU_FLAG_SSE2, 1 },
+#if ARCH_X86_64 && HAVE_YASM
+    { "PR-SSE2",        ff_prores_idct_put_10_sse2_wrap,     TRANSPOSE_PERM, AV_CPU_FLAG_SSE2, 1 },
+#endif
 #endif
 
 #if ARCH_BFIN
@@ -169,7 +196,7 @@
 DECLARE_ALIGNED(16, static DCTELEM, block)[64];
 DECLARE_ALIGNED(8,  static DCTELEM, block1)[64];
 
-static void init_block(DCTELEM block[64], int test, int is_idct, AVLFG *prng)
+static void init_block(DCTELEM block[64], int test, int is_idct, AVLFG *prng, int vals)
 {
     int i, j;
 
@@ -178,7 +205,7 @@
     switch (test) {
     case 0:
         for (i = 0; i < 64; i++)
-            block[i] = (av_lfg_get(prng) % 512) - 256;
+            block[i] = (av_lfg_get(prng) % (2*vals)) -vals;
         if (is_idct) {
             ff_ref_fdct(block);
             for (i = 0; i < 64; i++)
@@ -187,11 +214,13 @@
         break;
     case 1:
         j = av_lfg_get(prng) % 10 + 1;
-        for (i = 0; i < j; i++)
-            block[av_lfg_get(prng) % 64] = av_lfg_get(prng) % 512 - 256;
+        for (i = 0; i < j; i++) {
+            int idx = av_lfg_get(prng) % 64;
+            block[idx] = av_lfg_get(prng) % (2*vals) -vals;
+        }
         break;
     case 2:
-        block[ 0] = av_lfg_get(prng) % 4096 - 2048;
+        block[ 0] = av_lfg_get(prng) % (16*vals) - (8*vals);
         block[63] = (block[0] & 1) ^ 1;
         break;
     }
@@ -213,13 +242,16 @@
     } else if (perm == PARTTRANS_PERM) {
         for (i = 0; i < 64; i++)
             dst[(i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3)] = src[i];
+    } else if (perm == TRANSPOSE_PERM) {
+        for (i = 0; i < 64; i++)
+            dst[(i>>3) | ((i<<3)&0x38)] = src[i];
     } else {
         for (i = 0; i < 64; i++)
             dst[i] = src[i];
     }
 }
 
-static int dct_error(const struct algo *dct, int test, int is_idct, int speed)
+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;
     int it, i, scale;
@@ -229,6 +261,7 @@
     int maxout = 0;
     int blockSumErrMax = 0, blockSumErr;
     AVLFG prng;
+    const int vals=1<<bits;
     double omse, ome;
     int spec_err;
 
@@ -239,7 +272,7 @@
     for (i = 0; i < 64; i++)
         sysErr[i] = 0;
     for (it = 0; it < NB_ITS; it++) {
-        init_block(block1, test, is_idct, &prng);
+        init_block(block1, test, is_idct, &prng, vals);
         permute(block, block1, dct->format);
 
         dct->func(block);
@@ -285,7 +318,7 @@
 
     spec_err = is_idct && (err_inf > 1 || omse > 0.02 || fabs(ome) > 0.0015);
 
-    printf("%s %s: ppe=%d omse=%0.8f ome=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n",
+    printf("%s %s: max_err=%d omse=%0.8f ome=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n",
            is_idct ? "IDCT" : "DCT", dct->name, err_inf,
            omse, ome, (double) sysErrMax / NB_ITS,
            maxout, blockSumErrMax);
@@ -297,7 +330,8 @@
         return 0;
 
     /* speed test */
-    init_block(block, test, is_idct, &prng);
+
+    init_block(block, test, is_idct, &prng, vals);
     permute(block1, block, dct->format);
 
     ti = av_gettime();
@@ -307,10 +341,10 @@
             memcpy(block, block1, sizeof(block));
             dct->func(block);
         }
+        emms_c();
         it1 += NB_ITS_SPEED;
         ti1 = av_gettime() - ti;
     } while (ti1 < 1000000);
-    emms_c();
 
     printf("%s %s: %0.1f kdct/s\n", is_idct ? "IDCT" : "DCT", dct->name,
            (double) it1 * 1000.0 / (double) ti1);
@@ -435,6 +469,25 @@
             if (v > err_max)
                 err_max = v;
         }
+#if 0
+        printf("ref=\n");
+        for(i=0;i<8;i++) {
+            int j;
+            for(j=0;j<8;j++) {
+                printf(" %3d", img_dest1[i*8+j]);
+            }
+            printf("\n");
+        }
+
+        printf("out=\n");
+        for(i=0;i<8;i++) {
+            int j;
+            for(j=0;j<8;j++) {
+                printf(" %3d", img_dest[i*8+j]);
+            }
+            printf("\n");
+        }
+#endif
     }
     printf("%s %s: err_inf=%d\n", 1 ? "IDCT248" : "DCT248", name, err_max);
 
@@ -449,10 +502,10 @@
                 block[i] = block1[i];
             idct248_put(img_dest, 8, block);
         }
+        emms_c();
         it1 += NB_ITS_SPEED;
         ti1 = av_gettime() - ti;
     } while (ti1 < 1000000);
-    emms_c();
 
     printf("%s %s: %0.1f kdct/s\n", 1 ? "IDCT248" : "DCT248", name,
            (double) it1 * 1000.0 / (double) ti1);
@@ -460,10 +513,11 @@
 
 static void help(void)
 {
-    printf("dct-test [-i] [<test-number>]\n"
+    printf("dct-test [-i] [<test-number>] [<bits>]\n"
            "test-number 0 -> test with random matrixes\n"
            "            1 -> test with random sparse matrixes\n"
            "            2 -> do 3. test from mpeg4 std\n"
+           "bits        Number of time domain bits to use, 8 is default\n"
            "-i          test IDCT implementations\n"
            "-4          test IDCT248 implementations\n"
            "-t          speed test\n");
@@ -480,6 +534,7 @@
     int test = 1;
     int speed = 0;
     int err = 0;
+    int bits=8;
 
     cpu_flags = av_get_cpu_flags();
 
@@ -509,8 +564,9 @@
 
     if (optind < argc)
         test = atoi(argv[optind]);
+    if(optind+1 < argc) bits= atoi(argv[optind+1]);
 
-    printf("Libav DCT/IDCT test\n");
+    printf("ffmpeg DCT/IDCT test\n");
 
     if (test_248_dct) {
         idct248_error("SIMPLE-C", ff_simple_idct248_put, speed);
@@ -518,7 +574,7 @@
         const struct algo *algos = test_idct ? idct_tab : fdct_tab;
         for (i = 0; algos[i].name; i++)
             if (!(~cpu_flags & algos[i].mm_support)) {
-                err |= dct_error(&algos[i], test, test_idct, speed);
+                err |= dct_error(&algos[i], test, test_idct, speed, bits);
             }
     }
 
diff --git a/libavcodec/dct.c b/libavcodec/dct.c
index 0128c7d..e2ac0a8 100644
--- a/libavcodec/dct.c
+++ b/libavcodec/dct.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
  * Copyright (c) 2010 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
diff --git a/libavcodec/dct.h b/libavcodec/dct.h
index 905cc01..8995f10 100644
--- a/libavcodec/dct.h
+++ b/libavcodec/dct.h
@@ -4,20 +4,20 @@
  * Copyright (c) 2010 Alex Converse <alex.converse@gmail.com>
  * Copyright (c) 2010 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
diff --git a/libavcodec/dct32.c b/libavcodec/dct32.c
index 272e0db..fb53d53 100644
--- a/libavcodec/dct32.c
+++ b/libavcodec/dct32.c
@@ -2,20 +2,20 @@
  * Template for the Discrete Cosine Transform for 32 samples
  * Copyright (c) 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dctref.c b/libavcodec/dctref.c
index ae3dec5..851014b 100644
--- a/libavcodec/dctref.c
+++ b/libavcodec/dctref.c
@@ -2,20 +2,20 @@
  * reference discrete cosine transform (double precision)
  * Copyright (C) 2009 Dylan Yudaken
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dctref.h b/libavcodec/dctref.h
index a93b70d..f6fde88 100644
--- a/libavcodec/dctref.h
+++ b/libavcodec/dctref.h
@@ -2,20 +2,20 @@
  * reference discrete cosine transform (double precision)
  * Copyright (C) 2009 Dylan Yudaken
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c
index 39f0f64..8156c37 100644
--- a/libavcodec/dfa.c
+++ b/libavcodec/dfa.c
@@ -3,23 +3,24 @@
  * Copyright (c) 2011 Konstantin Shishkov
  * based on work by Vladimir "VAG" Gneushev
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "bytestream.h"
 
@@ -36,12 +37,13 @@
 static av_cold int dfa_decode_init(AVCodecContext *avctx)
 {
     DfaContext *s = avctx->priv_data;
-    int ret;
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
-    if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
-        return ret;
+    if (!avctx->width || !avctx->height)
+        return AVERROR_INVALIDDATA;
+
+    av_assert0(av_image_check_size(avctx->width, avctx->height, 0, avctx) >= 0);
 
     s->frame_buf = av_mallocz(avctx->width * avctx->height + AV_LZO_OUTPUT_PADDING);
     if (!s->frame_buf)
@@ -69,6 +71,8 @@
 
     segments = bytestream2_get_le32(gb);
     offset   = bytestream2_get_le32(gb);
+    if (segments == 0 && offset == frame_end - frame)
+        return 0; // skip frame
     if (frame_end - frame <= offset)
         return AVERROR_INVALIDDATA;
     frame += offset;
@@ -253,6 +257,8 @@
             y        += skip_lines;
             segments = bytestream2_get_le16(gb);
         }
+        if (frame_end <= frame)
+            return -1;
         if (segments & 0x8000) {
             frame[width - 1] = segments & 0xFF;
             segments = bytestream2_get_le16(gb);
@@ -339,7 +345,7 @@
             pal_elems = FFMIN(chunk_size / 3, 256);
             for (i = 0; i < pal_elems; i++) {
                 s->pal[i] = bytestream2_get_be24(&gb) << 2;
-                s->pal[i] |= (s->pal[i] >> 6) & 0x333;
+                s->pal[i] |= 0xFF << 24 | (s->pal[i] >> 6) & 0x30303;
             }
             s->pic.palette_has_changed = 1;
         } else if (chunk_type <= 9) {
diff --git a/libavcodec/dirac.c b/libavcodec/dirac.c
index 070ea0f..79638ac 100644
--- a/libavcodec/dirac.c
+++ b/libavcodec/dirac.c
@@ -1,28 +1,29 @@
 /*
  * Copyright (C) 2007 Marco Gerards <marco@gnu.org>
  * Copyright (C) 2009 David Conrad
+ * Copyright (C) 2011 Jordi Ortiz
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
  * @file
  * Dirac Decoder
- * @author Marco Gerards <marco@gnu.org>
+ * @author Marco Gerards <marco@gnu.org>, David Conrad, Jordi Ortiz <nenjordi@gmail.com>
  */
 
 #include "libavutil/imgutils.h"
@@ -31,7 +32,7 @@
 #include "golomb.h"
 #include "mpeg12data.h"
 
-// defaults for source parameters
+/* defaults for source parameters */
 static const dirac_source_params dirac_source_parameters_defaults[] = {
     { 640,  480,  2, 0, 0, 1,  1, 640,  480,  0, 0, 1, 0 },
     { 176,  120,  2, 0, 0, 9,  2, 176,  120,  0, 0, 1, 1 },
@@ -42,7 +43,6 @@
     { 704,  576,  2, 0, 1, 10, 3, 704,  576,  0, 0, 1, 2 },
     { 720,  480,  1, 1, 0, 4,  2, 704,  480,  8, 0, 3, 1 },
     { 720,  576,  1, 1, 1, 3,  3, 704,  576,  8, 0, 3, 2 },
-
     { 1280, 720,  1, 0, 1, 7,  1, 1280, 720,  0, 0, 3, 3 },
     { 1280, 720,  1, 0, 1, 6,  1, 1280, 720,  0, 0, 3, 3 },
     { 1920, 1080, 1, 1, 1, 4,  1, 1920, 1080, 0, 0, 3, 3 },
@@ -51,7 +51,6 @@
     { 1920, 1080, 1, 0, 1, 6,  1, 1920, 1080, 0, 0, 3, 3 },
     { 2048, 1080, 0, 0, 1, 2,  1, 2048, 1080, 0, 0, 4, 4 },
     { 4096, 2160, 0, 0, 1, 2,  1, 4096, 2160, 0, 0, 4, 4 },
-
     { 3840, 2160, 1, 0, 1, 7,  1, 3840, 2160, 0, 0, 3, 3 },
     { 3840, 2160, 1, 0, 1, 6,  1, 3840, 2160, 0, 0, 3, 3 },
     { 7680, 4320, 1, 0, 1, 7,  1, 3840, 2160, 0, 0, 3, 3 },
@@ -134,7 +133,7 @@
     if (get_bits1(gb))
         /* [DIRAC_STD] CHROMA_FORMAT_INDEX */
         source->chroma_format = svq3_get_ue_golomb(gb);
-    if (source->chroma_format > 2) {
+    if (source->chroma_format > 2U) {
         av_log(avctx, AV_LOG_ERROR, "Unknown chroma format %d\n",
                source->chroma_format);
         return AVERROR_INVALIDDATA;
@@ -145,14 +144,14 @@
     if (get_bits1(gb))
         /* [DIRAC_STD] SOURCE_SAMPLING */
         source->interlaced = svq3_get_ue_golomb(gb);
-    if (source->interlaced > 1)
+    if (source->interlaced > 1U)
         return AVERROR_INVALIDDATA;
 
     /* [DIRAC_STD] 10.3.5 Frame Rate. frame_rate(video_params) */
     if (get_bits1(gb)) { /* [DIRAC_STD] custom_frame_rate_flag */
         source->frame_rate_index = svq3_get_ue_golomb(gb);
 
-        if (source->frame_rate_index > 10)
+        if (source->frame_rate_index > 10U)
             return AVERROR_INVALIDDATA;
 
         if (!source->frame_rate_index) {
@@ -165,7 +164,7 @@
     /* [DIRAC_STD] preset_frame_rate(video_params, index) */
     if (source->frame_rate_index > 0) {
         if (source->frame_rate_index <= 8)
-            frame_rate = avpriv_frame_rate_tab[source->frame_rate_index];
+            frame_rate = avpriv_frame_rate_tab[source->frame_rate_index];  /* [DIRAC_STD] Table 10.3 values 1-8  */
         else
              /* [DIRAC_STD] Table 10.3 values 9-10 */
             frame_rate = dirac_frame_rate[source->frame_rate_index-9];
@@ -179,7 +178,7 @@
          /* [DIRAC_STD] index */
         source->aspect_ratio_index = svq3_get_ue_golomb(gb);
 
-        if (source->aspect_ratio_index > 6)
+        if (source->aspect_ratio_index > 6U)
             return AVERROR_INVALIDDATA;
 
         if (!source->aspect_ratio_index) {
@@ -191,7 +190,7 @@
      *  aspect ratio values */
     if (source->aspect_ratio_index > 0)
         avctx->sample_aspect_ratio =
-                dirac_preset_aspect_ratios[source->aspect_ratio_index-1];
+            dirac_preset_aspect_ratios[source->aspect_ratio_index-1];
 
     /* [DIRAC_STD] 10.3.7 Clean area. clean_area(video_params) */
     if (get_bits1(gb)) { /* [DIRAC_STD] custom_clean_area_flag */
@@ -212,10 +211,10 @@
         /* [DIRAC_STD] index */
         source->pixel_range_index = svq3_get_ue_golomb(gb);
 
-        if (source->pixel_range_index > 4)
+        if (source->pixel_range_index > 4U)
             return AVERROR_INVALIDDATA;
 
-        // This assumes either fullrange or MPEG levels only
+        /* This assumes either fullrange or MPEG levels only */
         if (!source->pixel_range_index) {
             luma_offset = svq3_get_ue_golomb(gb);
             luma_depth  = av_log2(svq3_get_ue_golomb(gb))+1;
@@ -233,7 +232,7 @@
     }
 
     if (luma_depth > 8)
-        av_log(avctx, AV_LOG_WARNING, "Bitdepth greater than 8");
+        av_log(avctx, AV_LOG_WARNING, "Bitdepth greater than 8\n");
 
     avctx->pix_fmt = dirac_pix_fmt[!luma_offset][source->chroma_format];
 
@@ -242,7 +241,7 @@
          /* [DIRAC_STD] index */
         idx = source->color_spec_index = svq3_get_ue_golomb(gb);
 
-        if (source->color_spec_index > 4)
+        if (source->color_spec_index > 4U)
             return AVERROR_INVALIDDATA;
 
         avctx->color_primaries = dirac_color_presets[idx].color_primaries;
@@ -253,7 +252,7 @@
             /* [DIRAC_STD] 10.3.9.1 Colour primaries */
             if (get_bits1(gb)) {
                 idx = svq3_get_ue_golomb(gb);
-                if (idx < 3)
+                if (idx < 3U)
                     avctx->color_primaries = dirac_primaries[idx];
             }
             /* [DIRAC_STD] 10.3.9.2 Colour matrix */
@@ -300,10 +299,10 @@
     else if (version_major > 2)
         av_log(avctx, AV_LOG_WARNING, "Stream may have unhandled features\n");
 
-    if (video_format > 20)
+    if (video_format > 20U)
         return AVERROR_INVALIDDATA;
 
-    // Fill in defaults for the source parameters.
+    /* Fill in defaults for the source parameters. */
     *source = dirac_source_parameters_defaults[video_format];
 
     /* [DIRAC_STD] 10.3 Source Parameters
@@ -320,7 +319,7 @@
      * currently only used to signal field coding */
     picture_coding_mode = svq3_get_ue_golomb(gb);
     if (picture_coding_mode != 0) {
-        av_log(avctx, AV_LOG_ERROR, "Unsupported picture coding mode %d",
+        av_log(avctx, AV_LOG_ERROR, "Unsupported picture coding mode %d\n",
                picture_coding_mode);
         return AVERROR_INVALIDDATA;
     }
diff --git a/libavcodec/dirac.h b/libavcodec/dirac.h
index e5b79b0..b0f955b 100644
--- a/libavcodec/dirac.h
+++ b/libavcodec/dirac.h
@@ -1,21 +1,22 @@
 /*
  * Copyright (C) 2007 Marco Gerards <marco@gnu.org>
  * Copyright (C) 2009 David Conrad
+ * Copyright (C) 2011 Jordi Ortiz
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,6 +27,8 @@
  * @file
  * Interface to Dirac Decoder/Encoder
  * @author Marco Gerards <marco@gnu.org>
+ * @author David Conrad
+ * @author Jordi Ortiz
  */
 
 #include "avcodec.h"
diff --git a/libavcodec/dirac_arith.c b/libavcodec/dirac_arith.c
new file mode 100644
index 0000000..bf91392
--- /dev/null
+++ b/libavcodec/dirac_arith.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2007 Marco Gerards <marco@gnu.org>
+ * Copyright (C) 2009 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
+ */
+
+/**
+ * @file
+ * Arithmetic decoder for Dirac
+ * @author Marco Gerards <marco@gnu.org>
+ */
+
+#include "dirac_arith.h"
+
+
+const uint16_t ff_dirac_prob[256] = {
+    0,    2,    5,    8,    11,   15,   20,   24,
+    29,   35,   41,   47,   53,   60,   67,   74,
+    82,   89,   97,   106,  114,  123,  132,  141,
+    150,  160,  170,  180,  190,  201,  211,  222,
+    233,  244,  256,  267,  279,  291,  303,  315,
+    327,  340,  353,  366,  379,  392,  405,  419,
+    433,  447,  461,  475,  489,  504,  518,  533,
+    548,  563,  578,  593,  609,  624,  640,  656,
+    672,  688,  705,  721,  738,  754,  771,  788,
+    805,  822,  840,  857,  875,  892,  910,  928,
+    946,  964,  983,  1001, 1020, 1038, 1057, 1076,
+    1095, 1114, 1133, 1153, 1172, 1192, 1211, 1231,
+    1251, 1271, 1291, 1311, 1332, 1352, 1373, 1393,
+    1414, 1435, 1456, 1477, 1498, 1520, 1541, 1562,
+    1584, 1606, 1628, 1649, 1671, 1694, 1716, 1738,
+    1760, 1783, 1806, 1828, 1851, 1874, 1897, 1920,
+    1935, 1942, 1949, 1955, 1961, 1968, 1974, 1980,
+    1985, 1991, 1996, 2001, 2006, 2011, 2016, 2021,
+    2025, 2029, 2033, 2037, 2040, 2044, 2047, 2050,
+    2053, 2056, 2058, 2061, 2063, 2065, 2066, 2068,
+    2069, 2070, 2071, 2072, 2072, 2072, 2072, 2072,
+    2072, 2071, 2070, 2069, 2068, 2066, 2065, 2063,
+    2060, 2058, 2055, 2052, 2049, 2045, 2042, 2038,
+    2033, 2029, 2024, 2019, 2013, 2008, 2002, 1996,
+    1989, 1982, 1975, 1968, 1960, 1952, 1943, 1934,
+    1925, 1916, 1906, 1896, 1885, 1874, 1863, 1851,
+    1839, 1827, 1814, 1800, 1786, 1772, 1757, 1742,
+    1727, 1710, 1694, 1676, 1659, 1640, 1622, 1602,
+    1582, 1561, 1540, 1518, 1495, 1471, 1447, 1422,
+    1396, 1369, 1341, 1312, 1282, 1251, 1219, 1186,
+    1151, 1114, 1077, 1037, 995,  952,  906,  857,
+    805,  750,  690,  625,  553,  471,  376,  255
+};
+
+const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT] = {
+    [CTX_ZPZN_F1]   = CTX_ZP_F2,
+    [CTX_ZPNN_F1]   = CTX_ZP_F2,
+    [CTX_ZP_F2]     = CTX_ZP_F3,
+    [CTX_ZP_F3]     = CTX_ZP_F4,
+    [CTX_ZP_F4]     = CTX_ZP_F5,
+    [CTX_ZP_F5]     = CTX_ZP_F6,
+    [CTX_ZP_F6]     = CTX_ZP_F6,
+    [CTX_NPZN_F1]   = CTX_NP_F2,
+    [CTX_NPNN_F1]   = CTX_NP_F2,
+    [CTX_NP_F2]     = CTX_NP_F3,
+    [CTX_NP_F3]     = CTX_NP_F4,
+    [CTX_NP_F4]     = CTX_NP_F5,
+    [CTX_NP_F5]     = CTX_NP_F6,
+    [CTX_NP_F6]     = CTX_NP_F6,
+    [CTX_DELTA_Q_F] = CTX_DELTA_Q_F,
+};
+
+int16_t ff_dirac_prob_branchless[256][2];
+
+void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length)
+{
+    int i;
+    align_get_bits(gb);
+
+    length = FFMIN(length, get_bits_left(gb)/8);
+
+    c->bytestream     = gb->buffer + get_bits_count(gb)/8;
+    c->bytestream_end = c->bytestream + length;
+    skip_bits_long(gb, length*8);
+
+    c->low = 0;
+    for (i = 0; i < 4; i++) {
+        c->low <<= 8;
+        if (c->bytestream < c->bytestream_end)
+            c->low |= *c->bytestream++;
+        else
+            c->low |= 0xff;
+    }
+
+    c->counter = -16;
+    c->range   = 0xffff;
+
+    for (i = 0; i < 256; i++) {
+        ff_dirac_prob_branchless[i][0] =  ff_dirac_prob[255-i];
+        ff_dirac_prob_branchless[i][1] = -ff_dirac_prob[i];
+    }
+
+    for (i = 0; i < DIRAC_CTX_COUNT; i++)
+        c->contexts[i] = 0x8000;
+}
diff --git a/libavcodec/dirac_arith.h b/libavcodec/dirac_arith.h
new file mode 100644
index 0000000..f9a8bba
--- /dev/null
+++ b/libavcodec/dirac_arith.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2007 Marco Gerards <marco@gnu.org>
+ * Copyright (C) 2009 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
+ */
+
+/**
+ * @file
+ * Arithmetic decoder for Dirac
+ * @author Marco Gerards <marco@gnu.org>
+ */
+
+#ifndef AVCODEC_DIRAC_ARITH_H
+#define AVCODEC_DIRAC_ARITH_H
+
+#include "bytestream.h"
+#include "get_bits.h"
+
+enum dirac_arith_contexts {
+    CTX_ZPZN_F1,
+    CTX_ZPNN_F1,
+    CTX_NPZN_F1,
+    CTX_NPNN_F1,
+    CTX_ZP_F2,
+    CTX_ZP_F3,
+    CTX_ZP_F4,
+    CTX_ZP_F5,
+    CTX_ZP_F6,
+    CTX_NP_F2,
+    CTX_NP_F3,
+    CTX_NP_F4,
+    CTX_NP_F5,
+    CTX_NP_F6,
+    CTX_COEFF_DATA,
+    CTX_SIGN_NEG,
+    CTX_SIGN_ZERO,
+    CTX_SIGN_POS,
+    CTX_ZERO_BLOCK,
+    CTX_DELTA_Q_F,
+    CTX_DELTA_Q_DATA,
+    CTX_DELTA_Q_SIGN,
+
+    DIRAC_CTX_COUNT
+};
+
+// Dirac resets the arith decoder between decoding various types of data,
+// so many contexts are never used simultaneously. Thus, we can reduce
+// the number of contexts needed by reusing them.
+#define CTX_SB_F1        CTX_ZP_F5
+#define CTX_SB_DATA      0
+#define CTX_PMODE_REF1   0
+#define CTX_PMODE_REF2   1
+#define CTX_GLOBAL_BLOCK 2
+#define CTX_MV_F1        CTX_ZP_F2
+#define CTX_MV_DATA      0
+#define CTX_DC_F1        CTX_ZP_F5
+#define CTX_DC_DATA      0
+
+typedef struct {
+    unsigned low;
+    uint16_t range;
+    int16_t  counter;
+
+    const uint8_t *bytestream;
+    const uint8_t *bytestream_end;
+
+    uint16_t contexts[DIRAC_CTX_COUNT];
+} DiracArith;
+
+extern const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT];
+extern const uint16_t ff_dirac_prob[256];
+extern int16_t ff_dirac_prob_branchless[256][2];
+
+static inline void renorm(DiracArith *c)
+{
+#if HAVE_FAST_CLZ
+    int shift = 14 - av_log2_16bit(c->range-1) + ((c->range-1)>>15);
+
+    c->low    <<= shift;
+    c->range  <<= shift;
+    c->counter += shift;
+#else
+    while (c->range <= 0x4000) {
+        c->low   <<= 1;
+        c->range <<= 1;
+        c->counter++;
+    }
+#endif
+}
+
+static inline void refill(DiracArith *c)
+{
+    int counter = c->counter;
+
+    if (counter >= 0) {
+        int new = bytestream_get_be16(&c->bytestream);
+
+        // the spec defines overread bits to be 1, and streams rely on this
+        if (c->bytestream > c->bytestream_end) {
+            new |= 0xff;
+            if (c->bytestream > c->bytestream_end+1)
+                new |= 0xff00;
+
+            c->bytestream = c->bytestream_end;
+        }
+
+        c->low += new << counter;
+        counter -= 16;
+    }
+    c->counter = counter;
+}
+
+static inline int dirac_get_arith_bit(DiracArith *c, int ctx)
+{
+    int prob_zero = c->contexts[ctx];
+    int range_times_prob, bit;
+    unsigned low = c->low;
+    int    range = c->range;
+
+    range_times_prob = (c->range * prob_zero) >> 16;
+
+#if HAVE_FAST_CMOV && HAVE_INLINE_ASM
+    low   -= range_times_prob << 16;
+    range -= range_times_prob;
+    bit = 0;
+    __asm__(
+        "cmpl   %5, %4 \n\t"
+        "setae  %b0    \n\t"
+        "cmovb  %3, %2 \n\t"
+        "cmovb  %5, %1 \n\t"
+        : "+q"(bit), "+r"(range), "+r"(low)
+        : "r"(c->low), "r"(c->low>>16),
+          "r"(range_times_prob)
+    );
+#else
+    bit = (low >> 16) >= range_times_prob;
+    if (bit) {
+        low   -= range_times_prob << 16;
+        range -= range_times_prob;
+    } else {
+        range  = range_times_prob;
+    }
+#endif
+
+    c->contexts[ctx] += ff_dirac_prob_branchless[prob_zero>>8][bit];
+    c->low   = low;
+    c->range = range;
+
+    renorm(c);
+    refill(c);
+    return bit;
+}
+
+static inline int dirac_get_arith_uint(DiracArith *c, int follow_ctx, int data_ctx)
+{
+    int ret = 1;
+    while (!dirac_get_arith_bit(c, follow_ctx)) {
+        ret <<= 1;
+        ret += dirac_get_arith_bit(c, data_ctx);
+        follow_ctx = ff_dirac_next_ctx[follow_ctx];
+    }
+    return ret-1;
+}
+
+static inline int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ctx)
+{
+    int ret = dirac_get_arith_uint(c, follow_ctx, data_ctx);
+    if (ret && dirac_get_arith_bit(c, data_ctx+1))
+        ret = -ret;
+    return ret;
+}
+
+void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length);
+
+#endif /* AVCODEC_DIRAC_ARITH_H */
diff --git a/libavcodec/dirac_parser.c b/libavcodec/dirac_parser.c
index 46f5430..a7c7c32 100644
--- a/libavcodec/dirac_parser.c
+++ b/libavcodec/dirac_parser.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2007-2008 Marco Gerards <marco@gnu.org>
  * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c
new file mode 100644
index 0000000..13d9e47
--- /dev/null
+++ b/libavcodec/diracdec.c
@@ -0,0 +1,1927 @@
+/*
+ * Copyright (C) 2007 Marco Gerards <marco@gnu.org>
+ * Copyright (C) 2009 David Conrad
+ * Copyright (C) 2011 Jordi Ortiz
+ *
+ * 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
+ * Dirac Decoder
+ * @author Marco Gerards <marco@gnu.org>, David Conrad, Jordi Ortiz <nenjordi@gmail.com>
+ */
+
+#include "avcodec.h"
+#include "dsputil.h"
+#include "get_bits.h"
+#include "bytestream.h"
+#include "golomb.h"
+#include "dirac_arith.h"
+#include "mpeg12data.h"
+#include "dwt.h"
+#include "dirac.h"
+#include "diracdsp.h"
+
+/**
+ * The spec limits the number of wavelet decompositions to 4 for both
+ * level 1 (VC-2) and 128 (long-gop default).
+ * 5 decompositions is the maximum before >16-bit buffers are needed.
+ * Schroedinger allows this for DD 9,7 and 13,7 wavelets only, limiting
+ * the others to 4 decompositions (or 3 for the fidelity filter).
+ *
+ * We use this instead of MAX_DECOMPOSITIONS to save some memory.
+ */
+#define MAX_DWT_LEVELS 5
+
+/**
+ * The spec limits this to 3 for frame coding, but in practice can be as high as 6
+ */
+#define MAX_REFERENCE_FRAMES 8
+#define MAX_DELAY 5         /* limit for main profile for frame coding (TODO: field coding) */
+#define MAX_FRAMES (MAX_REFERENCE_FRAMES + MAX_DELAY + 1)
+#define MAX_QUANT 68        /* max quant for VC-2 */
+#define MAX_BLOCKSIZE 32    /* maximum xblen/yblen we support */
+
+/**
+ * DiracBlock->ref flags, if set then the block does MC from the given ref
+ */
+#define DIRAC_REF_MASK_REF1   1
+#define DIRAC_REF_MASK_REF2   2
+#define DIRAC_REF_MASK_GLOBAL 4
+
+/**
+ * Value of Picture.reference when Picture is not a reference picture, but
+ * is held for delayed output.
+ */
+#define DELAYED_PIC_REF 4
+
+#define ff_emulated_edge_mc ff_emulated_edge_mc_8 /* Fix: change the calls to this function regarding bit depth */
+
+#define CALC_PADDING(size, depth)                       \
+    (((size + (1 << depth) - 1) >> depth) << depth)
+
+#define DIVRNDUP(a, b) (((a) + (b) - 1) / (b))
+
+typedef struct {
+    AVFrame avframe;
+    int interpolated[3];    /* 1 if hpel[] is valid */
+    uint8_t *hpel[3][4];
+    uint8_t *hpel_base[3][4];
+} DiracFrame;
+
+typedef struct {
+    union {
+        int16_t mv[2][2];
+        int16_t dc[3];
+    } u; /* anonymous unions aren't in C99 :( */
+    uint8_t ref;
+} DiracBlock;
+
+typedef struct SubBand {
+    int level;
+    int orientation;
+    int stride;
+    int width;
+    int height;
+    int quant;
+    IDWTELEM *ibuf;
+    struct SubBand *parent;
+
+    /* for low delay */
+    unsigned length;
+    const uint8_t *coeff_data;
+} SubBand;
+
+typedef struct Plane {
+    int width;
+    int height;
+    int stride;
+
+    int idwt_width;
+    int idwt_height;
+    int idwt_stride;
+    IDWTELEM *idwt_buf;
+    IDWTELEM *idwt_buf_base;
+    IDWTELEM *idwt_tmp;
+
+    /* block length */
+    uint8_t xblen;
+    uint8_t yblen;
+    /* block separation (block n+1 starts after this many pixels in block n) */
+    uint8_t xbsep;
+    uint8_t ybsep;
+    /* amount of overspill on each edge (half of the overlap between blocks) */
+    uint8_t xoffset;
+    uint8_t yoffset;
+
+    SubBand band[MAX_DWT_LEVELS][4];
+} Plane;
+
+typedef struct DiracContext {
+    AVCodecContext *avctx;
+    DSPContext dsp;
+    DiracDSPContext diracdsp;
+    GetBitContext gb;
+    dirac_source_params source;
+    int seen_sequence_header;
+    int frame_number;           /* number of the next frame to display       */
+    Plane plane[3];
+    int chroma_x_shift;
+    int chroma_y_shift;
+
+    int zero_res;               /* zero residue flag                         */
+    int is_arith;               /* whether coeffs use arith or golomb coding */
+    int low_delay;              /* use the low delay syntax                  */
+    int globalmc_flag;          /* use global motion compensation            */
+    int num_refs;               /* number of reference pictures              */
+
+    /* wavelet decoding */
+    unsigned wavelet_depth;     /* depth of the IDWT                         */
+    unsigned wavelet_idx;
+
+    /**
+     * schroedinger older than 1.0.8 doesn't store
+     * quant delta if only one codebook exists in a band
+     */
+    unsigned old_delta_quant;
+    unsigned codeblock_mode;
+
+    struct {
+        unsigned width;
+        unsigned height;
+    } codeblock[MAX_DWT_LEVELS+1];
+
+    struct {
+        unsigned num_x;         /* number of horizontal slices               */
+        unsigned num_y;         /* number of vertical slices                 */
+        AVRational bytes;       /* average bytes per slice                   */
+        uint8_t quant[MAX_DWT_LEVELS][4]; /* [DIRAC_STD] E.1 */
+    } lowdelay;
+
+    struct {
+        int pan_tilt[2];        /* pan/tilt vector                           */
+        int zrs[2][2];          /* zoom/rotate/shear matrix                  */
+        int perspective[2];     /* perspective vector                        */
+        unsigned zrs_exp;
+        unsigned perspective_exp;
+    } globalmc[2];
+
+    /* motion compensation */
+    uint8_t mv_precision;       /* [DIRAC_STD] REFS_WT_PRECISION             */
+    int16_t weight[2];          /* [DIRAC_STD] REF1_WT and REF2_WT           */
+    unsigned weight_log2denom;  /* [DIRAC_STD] REFS_WT_PRECISION             */
+
+    int blwidth;                /* number of blocks (horizontally)           */
+    int blheight;               /* number of blocks (vertically)             */
+    int sbwidth;                /* number of superblocks (horizontally)      */
+    int sbheight;               /* number of superblocks (vertically)        */
+
+    uint8_t *sbsplit;
+    DiracBlock *blmotion;
+
+    uint8_t *edge_emu_buffer[4];
+    uint8_t *edge_emu_buffer_base;
+
+    uint16_t *mctmp;            /* buffer holding the MC data multipled by OBMC weights */
+    uint8_t *mcscratch;
+
+    DECLARE_ALIGNED(16, uint8_t, obmc_weight)[3][MAX_BLOCKSIZE*MAX_BLOCKSIZE];
+
+    void (*put_pixels_tab[4])(uint8_t *dst, const uint8_t *src[5], int stride, int h);
+    void (*avg_pixels_tab[4])(uint8_t *dst, const uint8_t *src[5], int stride, int h);
+    void (*add_obmc)(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen);
+    dirac_weight_func weight_func;
+    dirac_biweight_func biweight_func;
+
+    DiracFrame *current_picture;
+    DiracFrame *ref_pics[2];
+
+    DiracFrame *ref_frames[MAX_REFERENCE_FRAMES+1];
+    DiracFrame *delay_frames[MAX_DELAY+1];
+    DiracFrame all_frames[MAX_FRAMES];
+} DiracContext;
+
+/**
+ * Dirac Specification ->
+ * Parse code values. 9.6.1 Table 9.1
+ */
+enum dirac_parse_code {
+    pc_seq_header         = 0x00,
+    pc_eos                = 0x10,
+    pc_aux_data           = 0x20,
+    pc_padding            = 0x30,
+};
+
+enum dirac_subband {
+    subband_ll = 0,
+    subband_hl = 1,
+    subband_lh = 2,
+    subband_hh = 3
+};
+
+static const uint8_t default_qmat[][4][4] = {
+    { { 5,  3,  3,  0}, { 0,  4,  4,  1}, { 0,  5,  5,  2}, { 0,  6,  6,  3} },
+    { { 4,  2,  2,  0}, { 0,  4,  4,  2}, { 0,  5,  5,  3}, { 0,  7,  7,  5} },
+    { { 5,  3,  3,  0}, { 0,  4,  4,  1}, { 0,  5,  5,  2}, { 0,  6,  6,  3} },
+    { { 8,  4,  4,  0}, { 0,  4,  4,  0}, { 0,  4,  4,  0}, { 0,  4,  4,  0} },
+    { { 8,  4,  4,  0}, { 0,  4,  4,  0}, { 0,  4,  4,  0}, { 0,  4,  4,  0} },
+    { { 0,  4,  4,  8}, { 0,  8,  8, 12}, { 0, 13, 13, 17}, { 0, 17, 17, 21} },
+    { { 3,  1,  1,  0}, { 0,  4,  4,  2}, { 0,  6,  6,  5}, { 0,  9,  9,  7} },
+};
+
+static const int qscale_tab[MAX_QUANT+1] = {
+    4,     5,     6,     7,     8,    10,    11,    13,
+    16,    19,    23,    27,    32,    38,    45,    54,
+    64,    76,    91,   108,   128,   152,   181,   215,
+    256,   304,   362,   431,   512,   609,   724,   861,
+    1024,  1218,  1448,  1722,  2048,  2435,  2896,  3444,
+    4096,  4871,  5793,  6889,  8192,  9742, 11585, 13777,
+    16384, 19484, 23170, 27554, 32768, 38968, 46341, 55109,
+    65536, 77936
+};
+
+static const int qoffset_intra_tab[MAX_QUANT+1] = {
+    1,     2,     3,     4,     4,     5,     6,     7,
+    8,    10,    12,    14,    16,    19,    23,    27,
+    32,    38,    46,    54,    64,    76,    91,   108,
+    128,   152,   181,   216,   256,   305,   362,   431,
+    512,   609,   724,   861,  1024,  1218,  1448,  1722,
+    2048,  2436,  2897,  3445,  4096,  4871,  5793,  6889,
+    8192,  9742, 11585, 13777, 16384, 19484, 23171, 27555,
+    32768, 38968
+};
+
+static const int qoffset_inter_tab[MAX_QUANT+1] = {
+    1,     2,     2,     3,     3,     4,     4,     5,
+    6,     7,     9,    10,    12,    14,    17,    20,
+    24,    29,    34,    41,    48,    57,    68,    81,
+    96,   114,   136,   162,   192,   228,   272,   323,
+    384,   457,   543,   646,   768,   913,  1086,  1292,
+    1536,  1827,  2172,  2583,  3072,  3653,  4344,  5166,
+    6144,  7307,  8689, 10333, 12288, 14613, 17378, 20666,
+    24576, 29226
+};
+
+/* magic number division by 3 from schroedinger */
+static inline int divide3(int x)
+{
+    return ((x+1)*21845 + 10922) >> 16;
+}
+
+static DiracFrame *remove_frame(DiracFrame *framelist[], int picnum)
+{
+    DiracFrame *remove_pic = NULL;
+    int i, remove_idx = -1;
+
+    for (i = 0; framelist[i]; i++)
+        if (framelist[i]->avframe.display_picture_number == picnum) {
+            remove_pic = framelist[i];
+            remove_idx = i;
+        }
+
+    if (remove_pic)
+        for (i = remove_idx; framelist[i]; i++)
+            framelist[i] = framelist[i+1];
+
+    return remove_pic;
+}
+
+static int add_frame(DiracFrame *framelist[], int maxframes, DiracFrame *frame)
+{
+    int i;
+    for (i = 0; i < maxframes; i++)
+        if (!framelist[i]) {
+            framelist[i] = frame;
+            return 0;
+        }
+    return -1;
+}
+
+static int alloc_sequence_buffers(DiracContext *s)
+{
+    int sbwidth  = DIVRNDUP(s->source.width,  4);
+    int sbheight = DIVRNDUP(s->source.height, 4);
+    int i, w, h, top_padding;
+
+    /* todo: think more about this / use or set Plane here */
+    for (i = 0; i < 3; i++) {
+        int max_xblen = MAX_BLOCKSIZE >> (i ? s->chroma_x_shift : 0);
+        int max_yblen = MAX_BLOCKSIZE >> (i ? s->chroma_y_shift : 0);
+        w = s->source.width  >> (i ? s->chroma_x_shift : 0);
+        h = s->source.height >> (i ? s->chroma_y_shift : 0);
+
+        /* we allocate the max we support here since num decompositions can
+         * change from frame to frame. Stride is aligned to 16 for SIMD, and
+         * 1<<MAX_DWT_LEVELS top padding to avoid if(y>0) in arith decoding
+         * MAX_BLOCKSIZE padding for MC: blocks can spill up to half of that
+         * on each side */
+        top_padding = FFMAX(1<<MAX_DWT_LEVELS, max_yblen/2);
+        w = FFALIGN(CALC_PADDING(w, MAX_DWT_LEVELS), 8); /* FIXME: Should this be 16 for SSE??? */
+        h = top_padding + CALC_PADDING(h, MAX_DWT_LEVELS) + max_yblen/2;
+
+        s->plane[i].idwt_buf_base = av_mallocz((w+max_xblen)*h * sizeof(IDWTELEM));
+        s->plane[i].idwt_tmp      = av_malloc((w+16) * sizeof(IDWTELEM));
+        s->plane[i].idwt_buf      = s->plane[i].idwt_buf_base + top_padding*w;
+        if (!s->plane[i].idwt_buf_base || !s->plane[i].idwt_tmp)
+            return AVERROR(ENOMEM);
+    }
+
+    w = s->source.width;
+    h = s->source.height;
+
+    /* fixme: allocate using real stride here */
+    s->sbsplit  = av_malloc(sbwidth * sbheight);
+    s->blmotion = av_malloc(sbwidth * sbheight * 4 * 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->mcscratch = av_malloc((w+64)*MAX_BLOCKSIZE);
+
+    if (!s->sbsplit || !s->blmotion)
+        return AVERROR(ENOMEM);
+    return 0;
+}
+
+static void free_sequence_buffers(DiracContext *s)
+{
+    int i, j, k;
+
+    for (i = 0; i < MAX_FRAMES; i++) {
+        if (s->all_frames[i].avframe.data[0]) {
+            s->avctx->release_buffer(s->avctx, &s->all_frames[i].avframe);
+            memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated));
+        }
+
+        for (j = 0; j < 3; j++)
+            for (k = 1; k < 4; k++)
+                av_freep(&s->all_frames[i].hpel_base[j][k]);
+    }
+
+    memset(s->ref_frames, 0, sizeof(s->ref_frames));
+    memset(s->delay_frames, 0, sizeof(s->delay_frames));
+
+    for (i = 0; i < 3; i++) {
+        av_freep(&s->plane[i].idwt_buf_base);
+        av_freep(&s->plane[i].idwt_tmp);
+    }
+
+    av_freep(&s->sbsplit);
+    av_freep(&s->blmotion);
+    av_freep(&s->edge_emu_buffer_base);
+
+    av_freep(&s->mctmp);
+    av_freep(&s->mcscratch);
+}
+
+static av_cold int dirac_decode_init(AVCodecContext *avctx)
+{
+    DiracContext *s = avctx->priv_data;
+    s->avctx = avctx;
+    s->frame_number = -1;
+
+    if (avctx->flags&CODEC_FLAG_EMU_EDGE) {
+        av_log(avctx, AV_LOG_ERROR, "Edge emulation not supported!\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    ff_dsputil_init(&s->dsp, avctx);
+    ff_diracdsp_init(&s->diracdsp);
+
+    return 0;
+}
+
+static void dirac_decode_flush(AVCodecContext *avctx)
+{
+    DiracContext *s = avctx->priv_data;
+    free_sequence_buffers(s);
+    s->seen_sequence_header = 0;
+    s->frame_number = -1;
+}
+
+static av_cold int dirac_decode_end(AVCodecContext *avctx)
+{
+    dirac_decode_flush(avctx);
+    return 0;
+}
+
+#define SIGN_CTX(x) (CTX_SIGN_ZERO + ((x) > 0) - ((x) < 0))
+
+static inline void coeff_unpack_arith(DiracArith *c, int qfactor, int qoffset,
+                                      SubBand *b, IDWTELEM *buf, int x, int y)
+{
+    int coeff, sign;
+    int sign_pred = 0;
+    int pred_ctx = CTX_ZPZN_F1;
+
+    /* Check if the parent subband has a 0 in the corresponding position */
+    if (b->parent)
+        pred_ctx += !!b->parent->ibuf[b->parent->stride * (y>>1) + (x>>1)] << 1;
+
+    if (b->orientation == subband_hl)
+        sign_pred = buf[-b->stride];
+
+    /* Determine if the pixel has only zeros in its neighbourhood */
+    if (x) {
+        pred_ctx += !(buf[-1] | buf[-b->stride] | buf[-1-b->stride]);
+        if (b->orientation == subband_lh)
+            sign_pred = buf[-1];
+    } else {
+        pred_ctx += !buf[-b->stride];
+    }
+
+    coeff = dirac_get_arith_uint(c, pred_ctx, CTX_COEFF_DATA);
+    if (coeff) {
+        coeff = (coeff * qfactor + qoffset + 2) >> 2;
+        sign  = dirac_get_arith_bit(c, SIGN_CTX(sign_pred));
+        coeff = (coeff ^ -sign) + sign;
+    }
+    *buf = coeff;
+}
+
+static inline int coeff_unpack_golomb(GetBitContext *gb, int qfactor, int qoffset)
+{
+    int sign, coeff;
+
+    coeff = svq3_get_ue_golomb(gb);
+    if (coeff) {
+        coeff = (coeff * qfactor + qoffset + 2) >> 2;
+        sign  = get_bits1(gb);
+        coeff = (coeff ^ -sign) + sign;
+    }
+    return coeff;
+}
+
+/**
+ * Decode the coeffs in the rectangle defined by left, right, top, bottom
+ * [DIRAC_STD] 13.4.3.2 Codeblock unpacking loop. codeblock()
+ */
+static inline void codeblock(DiracContext *s, SubBand *b,
+                             GetBitContext *gb, DiracArith *c,
+                             int left, int right, int top, int bottom,
+                             int blockcnt_one, int is_arith)
+{
+    int x, y, zero_block;
+    int qoffset, qfactor;
+    IDWTELEM *buf;
+
+    /* check for any coded coefficients in this codeblock */
+    if (!blockcnt_one) {
+        if (is_arith)
+            zero_block = dirac_get_arith_bit(c, CTX_ZERO_BLOCK);
+        else
+            zero_block = get_bits1(gb);
+
+        if (zero_block)
+            return;
+    }
+
+    if (s->codeblock_mode && !(s->old_delta_quant && blockcnt_one)) {
+        int quant = b->quant;
+        if (is_arith)
+            quant += dirac_get_arith_int(c, CTX_DELTA_Q_F, CTX_DELTA_Q_DATA);
+        else
+            quant += dirac_get_se_golomb(gb);
+        if (quant < 0) {
+            av_log(s->avctx, AV_LOG_ERROR, "Invalid quant\n");
+            return;
+        }
+        b->quant = quant;
+    }
+
+    b->quant = FFMIN(b->quant, MAX_QUANT);
+
+    qfactor = qscale_tab[b->quant];
+    /* TODO: context pointer? */
+    if (!s->num_refs)
+        qoffset = qoffset_intra_tab[b->quant];
+    else
+        qoffset = qoffset_inter_tab[b->quant];
+
+    buf = b->ibuf + top * b->stride;
+    for (y = top; y < bottom; y++) {
+        for (x = left; x < right; x++) {
+            /* [DIRAC_STD] 13.4.4 Subband coefficients. coeff_unpack() */
+            if (is_arith)
+                coeff_unpack_arith(c, qfactor, qoffset, b, buf+x, x, y);
+            else
+                buf[x] = coeff_unpack_golomb(gb, qfactor, qoffset);
+        }
+        buf += b->stride;
+    }
+}
+
+/**
+ * Dirac Specification ->
+ * 13.3 intra_dc_prediction(band)
+ */
+static inline void intra_dc_prediction(SubBand *b)
+{
+    IDWTELEM *buf = b->ibuf;
+    int x, y;
+
+    for (x = 1; x < b->width; x++)
+        buf[x] += buf[x-1];
+    buf += b->stride;
+
+    for (y = 1; y < b->height; y++) {
+        buf[0] += buf[-b->stride];
+
+        for (x = 1; x < b->width; x++) {
+            int pred = buf[x - 1] + buf[x - b->stride] + buf[x - b->stride-1];
+            buf[x]  += divide3(pred);
+        }
+        buf += b->stride;
+    }
+}
+
+/**
+ * Dirac Specification ->
+ * 13.4.2 Non-skipped subbands.  subband_coeffs()
+ */
+static av_always_inline void decode_subband_internal(DiracContext *s, SubBand *b, int is_arith)
+{
+    int cb_x, cb_y, left, right, top, bottom;
+    DiracArith c;
+    GetBitContext gb;
+    int cb_width  = s->codeblock[b->level + (b->orientation != subband_ll)].width;
+    int cb_height = s->codeblock[b->level + (b->orientation != subband_ll)].height;
+    int blockcnt_one = (cb_width + cb_height) == 2;
+
+    if (!b->length)
+        return;
+
+    init_get_bits(&gb, b->coeff_data, b->length*8);
+
+    if (is_arith)
+        ff_dirac_init_arith_decoder(&c, &gb, b->length);
+
+    top = 0;
+    for (cb_y = 0; cb_y < cb_height; cb_y++) {
+        bottom = (b->height * (cb_y+1)) / cb_height;
+        left = 0;
+        for (cb_x = 0; cb_x < cb_width; cb_x++) {
+            right = (b->width * (cb_x+1)) / cb_width;
+            codeblock(s, b, &gb, &c, left, right, top, bottom, blockcnt_one, is_arith);
+            left = right;
+        }
+        top = bottom;
+    }
+
+    if (b->orientation == subband_ll && s->num_refs == 0)
+        intra_dc_prediction(b);
+}
+
+static int decode_subband_arith(AVCodecContext *avctx, void *b)
+{
+    DiracContext *s = avctx->priv_data;
+    decode_subband_internal(s, b, 1);
+    return 0;
+}
+
+static int decode_subband_golomb(AVCodecContext *avctx, void *arg)
+{
+    DiracContext *s = avctx->priv_data;
+    SubBand **b     = arg;
+    decode_subband_internal(s, *b, 0);
+    return 0;
+}
+
+/**
+ * Dirac Specification ->
+ * [DIRAC_STD] 13.4.1 core_transform_data()
+ */
+static void decode_component(DiracContext *s, int comp)
+{
+    AVCodecContext *avctx = s->avctx;
+    SubBand *bands[3*MAX_DWT_LEVELS+1];
+    enum dirac_subband orientation;
+    int level, num_bands = 0;
+
+    /* Unpack all subbands at all levels. */
+    for (level = 0; level < s->wavelet_depth; level++) {
+        for (orientation = !!level; orientation < 4; orientation++) {
+            SubBand *b = &s->plane[comp].band[level][orientation];
+            bands[num_bands++] = b;
+
+            align_get_bits(&s->gb);
+            /* [DIRAC_STD] 13.4.2 subband() */
+            b->length = svq3_get_ue_golomb(&s->gb);
+            if (b->length) {
+                b->quant = svq3_get_ue_golomb(&s->gb);
+                align_get_bits(&s->gb);
+                b->coeff_data = s->gb.buffer + get_bits_count(&s->gb)/8;
+                b->length = FFMIN(b->length, FFMAX(get_bits_left(&s->gb)/8, 0));
+                skip_bits_long(&s->gb, b->length*8);
+            }
+        }
+        /* arithmetic coding has inter-level dependencies, so we can only execute one level at a time */
+        if (s->is_arith)
+            avctx->execute(avctx, decode_subband_arith, &s->plane[comp].band[level][!!level],
+                           NULL, 4-!!level, sizeof(SubBand));
+    }
+    /* golomb coding has no inter-level dependencies, so we can execute all subbands in parallel */
+    if (!s->is_arith)
+        avctx->execute(avctx, decode_subband_golomb, bands, NULL, num_bands, sizeof(SubBand*));
+}
+
+/* [DIRAC_STD] 13.5.5.2 Luma slice subband data. luma_slice_band(level,orient,sx,sy) --> if b2 == NULL */
+/* [DIRAC_STD] 13.5.5.3 Chroma slice subband data. chroma_slice_band(level,orient,sx,sy) --> if b2 != NULL */
+static void lowdelay_subband(DiracContext *s, GetBitContext *gb, int quant,
+                             int slice_x, int slice_y, int bits_end,
+                             SubBand *b1, SubBand *b2)
+{
+    int left   = b1->width  * slice_x    / s->lowdelay.num_x;
+    int right  = b1->width  *(slice_x+1) / s->lowdelay.num_x;
+    int top    = b1->height * slice_y    / s->lowdelay.num_y;
+    int bottom = b1->height *(slice_y+1) / s->lowdelay.num_y;
+
+    int qfactor = qscale_tab[FFMIN(quant, MAX_QUANT)];
+    int qoffset = qoffset_intra_tab[FFMIN(quant, MAX_QUANT)];
+
+    IDWTELEM *buf1 =      b1->ibuf + top * b1->stride;
+    IDWTELEM *buf2 = b2 ? b2->ibuf + top * b2->stride : NULL;
+    int x, y;
+    /* we have to constantly check for overread since the spec explictly
+       requires this, with the meaning that all remaining coeffs are set to 0 */
+    if (get_bits_count(gb) >= bits_end)
+        return;
+
+    for (y = top; y < bottom; y++) {
+        for (x = left; x < right; x++) {
+            buf1[x] = coeff_unpack_golomb(gb, qfactor, qoffset);
+            if (get_bits_count(gb) >= bits_end)
+                return;
+            if (buf2) {
+                buf2[x] = coeff_unpack_golomb(gb, qfactor, qoffset);
+                if (get_bits_count(gb) >= bits_end)
+                    return;
+            }
+        }
+        buf1 += b1->stride;
+        if (buf2)
+            buf2 += b2->stride;
+    }
+}
+
+struct lowdelay_slice {
+    GetBitContext gb;
+    int slice_x;
+    int slice_y;
+    int bytes;
+};
+
+
+/**
+ * Dirac Specification ->
+ * 13.5.2 Slices. slice(sx,sy)
+ */
+static int decode_lowdelay_slice(AVCodecContext *avctx, void *arg)
+{
+    DiracContext *s = avctx->priv_data;
+    struct lowdelay_slice *slice = arg;
+    GetBitContext *gb = &slice->gb;
+    enum dirac_subband orientation;
+    int level, quant, chroma_bits, chroma_end;
+
+    int quant_base  = get_bits(gb, 7); /*[DIRAC_STD] qindex */
+    int length_bits = av_log2(8 * slice->bytes)+1;
+    int luma_bits   = get_bits_long(gb, length_bits);
+    int luma_end    = get_bits_count(gb) + FFMIN(luma_bits, get_bits_left(gb));
+
+    /* [DIRAC_STD] 13.5.5.2 luma_slice_band */
+    for (level = 0; level < s->wavelet_depth; level++)
+        for (orientation = !!level; orientation < 4; orientation++) {
+            quant = FFMAX(quant_base - s->lowdelay.quant[level][orientation], 0);
+            lowdelay_subband(s, gb, quant, slice->slice_x, slice->slice_y, luma_end,
+                             &s->plane[0].band[level][orientation], NULL);
+        }
+
+    /* consume any unused bits from luma */
+    skip_bits_long(gb, get_bits_count(gb) - luma_end);
+
+    chroma_bits = 8*slice->bytes - 7 - length_bits - luma_bits;
+    chroma_end  = get_bits_count(gb) + FFMIN(chroma_bits, get_bits_left(gb));
+    /* [DIRAC_STD] 13.5.5.3 chroma_slice_band */
+    for (level = 0; level < s->wavelet_depth; level++)
+        for (orientation = !!level; orientation < 4; orientation++) {
+            quant = FFMAX(quant_base - s->lowdelay.quant[level][orientation], 0);
+            lowdelay_subband(s, gb, quant, slice->slice_x, slice->slice_y, chroma_end,
+                             &s->plane[1].band[level][orientation],
+                             &s->plane[2].band[level][orientation]);
+        }
+
+    return 0;
+}
+
+/**
+ * Dirac Specification ->
+ * 13.5.1 low_delay_transform_data()
+ */
+static void decode_lowdelay(DiracContext *s)
+{
+    AVCodecContext *avctx = s->avctx;
+    int slice_x, slice_y, bytes, bufsize;
+    const uint8_t *buf;
+    struct lowdelay_slice *slices;
+    int slice_num = 0;
+
+    slices = av_mallocz(s->lowdelay.num_x * s->lowdelay.num_y * sizeof(struct lowdelay_slice));
+
+    align_get_bits(&s->gb);
+    /*[DIRAC_STD] 13.5.2 Slices. slice(sx,sy) */
+    buf = s->gb.buffer + get_bits_count(&s->gb)/8;
+    bufsize = get_bits_left(&s->gb);
+
+    for (slice_y = 0; bufsize > 0 && slice_y < s->lowdelay.num_y; slice_y++)
+        for (slice_x = 0; bufsize > 0 && slice_x < s->lowdelay.num_x; slice_x++) {
+            bytes = (slice_num+1) * s->lowdelay.bytes.num / s->lowdelay.bytes.den
+                - slice_num    * s->lowdelay.bytes.num / s->lowdelay.bytes.den;
+
+            slices[slice_num].bytes   = bytes;
+            slices[slice_num].slice_x = slice_x;
+            slices[slice_num].slice_y = slice_y;
+            init_get_bits(&slices[slice_num].gb, buf, bufsize);
+            slice_num++;
+
+            buf     += bytes;
+            bufsize -= bytes*8;
+        }
+
+    avctx->execute(avctx, decode_lowdelay_slice, slices, NULL, slice_num,
+                   sizeof(struct lowdelay_slice)); /* [DIRAC_STD] 13.5.2 Slices */
+    intra_dc_prediction(&s->plane[0].band[0][0]);  /* [DIRAC_STD] 13.3 intra_dc_prediction() */
+    intra_dc_prediction(&s->plane[1].band[0][0]);  /* [DIRAC_STD] 13.3 intra_dc_prediction() */
+    intra_dc_prediction(&s->plane[2].band[0][0]);  /* [DIRAC_STD] 13.3 intra_dc_prediction() */
+    av_free(slices);
+}
+
+static void init_planes(DiracContext *s)
+{
+    int i, w, h, level, orientation;
+
+    for (i = 0; i < 3; i++) {
+        Plane *p = &s->plane[i];
+
+        p->width       = s->source.width  >> (i ? s->chroma_x_shift : 0);
+        p->height      = s->source.height >> (i ? s->chroma_y_shift : 0);
+        p->idwt_width  = w = CALC_PADDING(p->width , s->wavelet_depth);
+        p->idwt_height = h = CALC_PADDING(p->height, s->wavelet_depth);
+        p->idwt_stride = FFALIGN(p->idwt_width, 8);
+
+        for (level = s->wavelet_depth-1; level >= 0; level--) {
+            w = w>>1;
+            h = h>>1;
+            for (orientation = !!level; orientation < 4; orientation++) {
+                SubBand *b = &p->band[level][orientation];
+
+                b->ibuf   = p->idwt_buf;
+                b->level  = level;
+                b->stride = p->idwt_stride << (s->wavelet_depth - level);
+                b->width  = w;
+                b->height = h;
+                b->orientation = orientation;
+
+                if (orientation & 1)
+                    b->ibuf += w;
+                if (orientation > 1)
+                    b->ibuf += b->stride>>1;
+
+                if (level)
+                    b->parent = &p->band[level-1][orientation];
+            }
+        }
+
+        if (i > 0) {
+            p->xblen = s->plane[0].xblen >> s->chroma_x_shift;
+            p->yblen = s->plane[0].yblen >> s->chroma_y_shift;
+            p->xbsep = s->plane[0].xbsep >> s->chroma_x_shift;
+            p->ybsep = s->plane[0].ybsep >> s->chroma_y_shift;
+        }
+
+        p->xoffset = (p->xblen - p->xbsep)/2;
+        p->yoffset = (p->yblen - p->ybsep)/2;
+    }
+}
+
+/**
+ * Unpack the motion compensation parameters
+ * Dirac Specification ->
+ * 11.2 Picture prediction data. picture_prediction()
+ */
+static int dirac_unpack_prediction_parameters(DiracContext *s)
+{
+    static const uint8_t default_blen[] = { 4, 12, 16, 24 };
+    static const uint8_t default_bsep[] = { 4,  8, 12, 16 };
+
+    GetBitContext *gb = &s->gb;
+    unsigned idx, ref;
+
+    align_get_bits(gb);
+    /* [DIRAC_STD] 11.2.2 Block parameters. block_parameters() */
+    /* Luma and Chroma are equal. 11.2.3 */
+    idx = svq3_get_ue_golomb(gb); /* [DIRAC_STD] index */
+
+    if (idx > 4) {
+        av_log(s->avctx, AV_LOG_ERROR, "Block prediction index too high\n");
+        return -1;
+    }
+
+    if (idx == 0) {
+        s->plane[0].xblen = svq3_get_ue_golomb(gb);
+        s->plane[0].yblen = svq3_get_ue_golomb(gb);
+        s->plane[0].xbsep = svq3_get_ue_golomb(gb);
+        s->plane[0].ybsep = svq3_get_ue_golomb(gb);
+    } else {
+        /*[DIRAC_STD] preset_block_params(index). Table 11.1 */
+        s->plane[0].xblen = default_blen[idx-1];
+        s->plane[0].yblen = default_blen[idx-1];
+        s->plane[0].xbsep = default_bsep[idx-1];
+        s->plane[0].ybsep = default_bsep[idx-1];
+    }
+    /*[DIRAC_STD] 11.2.4 motion_data_dimensions()
+      Calculated in function dirac_unpack_block_motion_data */
+
+    if (!s->plane[0].xbsep || !s->plane[0].ybsep || s->plane[0].xbsep < s->plane[0].xblen/2 || s->plane[0].ybsep < s->plane[0].yblen/2) {
+        av_log(s->avctx, AV_LOG_ERROR, "Block separation too small\n");
+        return -1;
+    }
+    if (s->plane[0].xbsep > s->plane[0].xblen || s->plane[0].ybsep > s->plane[0].yblen) {
+        av_log(s->avctx, AV_LOG_ERROR, "Block separation greater than size\n");
+        return -1;
+    }
+    if (FFMAX(s->plane[0].xblen, s->plane[0].yblen) > MAX_BLOCKSIZE) {
+        av_log(s->avctx, AV_LOG_ERROR, "Unsupported large block size\n");
+        return -1;
+    }
+
+    /*[DIRAC_STD] 11.2.5 Motion vector precision. motion_vector_precision()
+      Read motion vector precision */
+    s->mv_precision = svq3_get_ue_golomb(gb);
+    if (s->mv_precision > 3) {
+        av_log(s->avctx, AV_LOG_ERROR, "MV precision finer than eighth-pel\n");
+        return -1;
+    }
+
+    /*[DIRAC_STD] 11.2.6 Global motion. global_motion()
+      Read the global motion compensation parameters */
+    s->globalmc_flag = get_bits1(gb);
+    if (s->globalmc_flag) {
+        memset(s->globalmc, 0, sizeof(s->globalmc));
+        /* [DIRAC_STD] pan_tilt(gparams) */
+        for (ref = 0; ref < s->num_refs; ref++) {
+            if (get_bits1(gb)) {
+                s->globalmc[ref].pan_tilt[0] = dirac_get_se_golomb(gb);
+                s->globalmc[ref].pan_tilt[1] = dirac_get_se_golomb(gb);
+            }
+            /* [DIRAC_STD] zoom_rotate_shear(gparams)
+               zoom/rotation/shear parameters */
+            if (get_bits1(gb)) {
+                s->globalmc[ref].zrs_exp   = svq3_get_ue_golomb(gb);
+                s->globalmc[ref].zrs[0][0] = dirac_get_se_golomb(gb);
+                s->globalmc[ref].zrs[0][1] = dirac_get_se_golomb(gb);
+                s->globalmc[ref].zrs[1][0] = dirac_get_se_golomb(gb);
+                s->globalmc[ref].zrs[1][1] = dirac_get_se_golomb(gb);
+            } else {
+                s->globalmc[ref].zrs[0][0] = 1;
+                s->globalmc[ref].zrs[1][1] = 1;
+            }
+            /* [DIRAC_STD] perspective(gparams) */
+            if (get_bits1(gb)) {
+                s->globalmc[ref].perspective_exp = svq3_get_ue_golomb(gb);
+                s->globalmc[ref].perspective[0]  = dirac_get_se_golomb(gb);
+                s->globalmc[ref].perspective[1]  = dirac_get_se_golomb(gb);
+            }
+        }
+    }
+
+    /*[DIRAC_STD] 11.2.7 Picture prediction mode. prediction_mode()
+      Picture prediction mode, not currently used. */
+    if (svq3_get_ue_golomb(gb)) {
+        av_log(s->avctx, AV_LOG_ERROR, "Unknown picture prediction mode\n");
+        return -1;
+    }
+
+    /* [DIRAC_STD] 11.2.8 Reference picture weight. reference_picture_weights()
+       just data read, weight calculation will be done later on. */
+    s->weight_log2denom = 1;
+    s->weight[0]        = 1;
+    s->weight[1]        = 1;
+
+    if (get_bits1(gb)) {
+        s->weight_log2denom = svq3_get_ue_golomb(gb);
+        s->weight[0] = dirac_get_se_golomb(gb);
+        if (s->num_refs == 2)
+            s->weight[1] = dirac_get_se_golomb(gb);
+    }
+    return 0;
+}
+
+/**
+ * Dirac Specification ->
+ * 11.3 Wavelet transform data. wavelet_transform()
+ */
+static int dirac_unpack_idwt_params(DiracContext *s)
+{
+    GetBitContext *gb = &s->gb;
+    int i, level;
+    unsigned tmp;
+
+#define CHECKEDREAD(dst, cond, errmsg) \
+    tmp = svq3_get_ue_golomb(gb); \
+    if (cond) { \
+        av_log(s->avctx, AV_LOG_ERROR, errmsg); \
+        return -1; \
+    }\
+    dst = tmp;
+
+    align_get_bits(gb);
+
+    s->zero_res = s->num_refs ? get_bits1(gb) : 0;
+    if (s->zero_res)
+        return 0;
+
+    /*[DIRAC_STD] 11.3.1 Transform parameters. transform_parameters() */
+    CHECKEDREAD(s->wavelet_idx, tmp > 6, "wavelet_idx is too big\n")
+
+    CHECKEDREAD(s->wavelet_depth, tmp > MAX_DWT_LEVELS || tmp < 1, "invalid number of DWT decompositions\n")
+
+    if (!s->low_delay) {
+        /* Codeblock parameters (core syntax only) */
+        if (get_bits1(gb)) {
+            for (i = 0; i <= s->wavelet_depth; i++) {
+                CHECKEDREAD(s->codeblock[i].width , tmp < 1, "codeblock width invalid\n")
+                CHECKEDREAD(s->codeblock[i].height, tmp < 1, "codeblock height invalid\n")
+            }
+
+            CHECKEDREAD(s->codeblock_mode, tmp > 1, "unknown codeblock mode\n")
+        } else
+            for (i = 0; i <= s->wavelet_depth; i++)
+                s->codeblock[i].width = s->codeblock[i].height = 1;
+    } else {
+        /* Slice parameters + quantization matrix*/
+        /*[DIRAC_STD] 11.3.4 Slice coding Parameters (low delay syntax only). slice_parameters() */
+        s->lowdelay.num_x     = svq3_get_ue_golomb(gb);
+        s->lowdelay.num_y     = svq3_get_ue_golomb(gb);
+        s->lowdelay.bytes.num = svq3_get_ue_golomb(gb);
+        s->lowdelay.bytes.den = svq3_get_ue_golomb(gb);
+
+        if (s->lowdelay.bytes.den <= 0) {
+            av_log(s->avctx,AV_LOG_ERROR,"Invalid lowdelay.bytes.den\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        /* [DIRAC_STD] 11.3.5 Quantisation matrices (low-delay syntax). quant_matrix() */
+        if (get_bits1(gb)) {
+            av_log(s->avctx,AV_LOG_DEBUG,"Low Delay: Has Custom Quantization Matrix!\n");
+            /* custom quantization matrix */
+            s->lowdelay.quant[0][0] = svq3_get_ue_golomb(gb);
+            for (level = 0; level < s->wavelet_depth; level++) {
+                s->lowdelay.quant[level][1] = svq3_get_ue_golomb(gb);
+                s->lowdelay.quant[level][2] = svq3_get_ue_golomb(gb);
+                s->lowdelay.quant[level][3] = svq3_get_ue_golomb(gb);
+            }
+        } else {
+            /* default quantization matrix */
+            for (level = 0; level < s->wavelet_depth; level++)
+                for (i = 0; i < 4; i++) {
+                    s->lowdelay.quant[level][i] = default_qmat[s->wavelet_idx][level][i];
+                    /* haar with no shift differs for different depths */
+                    if (s->wavelet_idx == 3)
+                        s->lowdelay.quant[level][i] += 4*(s->wavelet_depth-1 - level);
+                }
+        }
+    }
+    return 0;
+}
+
+static inline int pred_sbsplit(uint8_t *sbsplit, int stride, int x, int y)
+{
+    static const uint8_t avgsplit[7] = { 0, 0, 1, 1, 1, 2, 2 };
+
+    if (!(x|y))
+        return 0;
+    else if (!y)
+        return sbsplit[-1];
+    else if (!x)
+        return sbsplit[-stride];
+
+    return avgsplit[sbsplit[-1] + sbsplit[-stride] + sbsplit[-stride-1]];
+}
+
+static inline int pred_block_mode(DiracBlock *block, int stride, int x, int y, int refmask)
+{
+    int pred;
+
+    if (!(x|y))
+        return 0;
+    else if (!y)
+        return block[-1].ref & refmask;
+    else if (!x)
+        return block[-stride].ref & refmask;
+
+    /* return the majority */
+    pred = (block[-1].ref & refmask) + (block[-stride].ref & refmask) + (block[-stride-1].ref & refmask);
+    return (pred >> 1) & refmask;
+}
+
+static inline void pred_block_dc(DiracBlock *block, int stride, int x, int y)
+{
+    int i, n = 0;
+
+    memset(block->u.dc, 0, sizeof(block->u.dc));
+
+    if (x && !(block[-1].ref & 3)) {
+        for (i = 0; i < 3; i++)
+            block->u.dc[i] += block[-1].u.dc[i];
+        n++;
+    }
+
+    if (y && !(block[-stride].ref & 3)) {
+        for (i = 0; i < 3; i++)
+            block->u.dc[i] += block[-stride].u.dc[i];
+        n++;
+    }
+
+    if (x && y && !(block[-1-stride].ref & 3)) {
+        for (i = 0; i < 3; i++)
+            block->u.dc[i] += block[-1-stride].u.dc[i];
+        n++;
+    }
+
+    if (n == 2) {
+        for (i = 0; i < 3; i++)
+            block->u.dc[i] = (block->u.dc[i]+1)>>1;
+    } else if (n == 3) {
+        for (i = 0; i < 3; i++)
+            block->u.dc[i] = divide3(block->u.dc[i]);
+    }
+}
+
+static inline void pred_mv(DiracBlock *block, int stride, int x, int y, int ref)
+{
+    int16_t *pred[3];
+    int refmask = ref+1;
+    int mask = refmask | DIRAC_REF_MASK_GLOBAL; /*  exclude gmc blocks */
+    int n = 0;
+
+    if (x && (block[-1].ref & mask) == refmask)
+        pred[n++] = block[-1].u.mv[ref];
+
+    if (y && (block[-stride].ref & mask) == refmask)
+        pred[n++] = block[-stride].u.mv[ref];
+
+    if (x && y && (block[-stride-1].ref & mask) == refmask)
+        pred[n++] = block[-stride-1].u.mv[ref];
+
+    switch (n) {
+    case 0:
+        block->u.mv[ref][0] = 0;
+        block->u.mv[ref][1] = 0;
+        break;
+    case 1:
+        block->u.mv[ref][0] = pred[0][0];
+        block->u.mv[ref][1] = pred[0][1];
+        break;
+    case 2:
+        block->u.mv[ref][0] = (pred[0][0] + pred[1][0] + 1) >> 1;
+        block->u.mv[ref][1] = (pred[0][1] + pred[1][1] + 1) >> 1;
+        break;
+    case 3:
+        block->u.mv[ref][0] = mid_pred(pred[0][0], pred[1][0], pred[2][0]);
+        block->u.mv[ref][1] = mid_pred(pred[0][1], pred[1][1], pred[2][1]);
+        break;
+    }
+}
+
+static void global_mv(DiracContext *s, DiracBlock *block, int x, int y, int ref)
+{
+    int ez      = s->globalmc[ref].zrs_exp;
+    int ep      = s->globalmc[ref].perspective_exp;
+    int (*A)[2] = s->globalmc[ref].zrs;
+    int *b      = s->globalmc[ref].pan_tilt;
+    int *c      = s->globalmc[ref].perspective;
+
+    int m       = (1<<ep) - (c[0]*x + c[1]*y);
+    int mx      = m * ((A[0][0] * x + A[0][1]*y) + (1<<ez) * b[0]);
+    int my      = m * ((A[1][0] * x + A[1][1]*y) + (1<<ez) * b[1]);
+
+    block->u.mv[ref][0] = (mx + (1<<(ez+ep))) >> (ez+ep);
+    block->u.mv[ref][1] = (my + (1<<(ez+ep))) >> (ez+ep);
+}
+
+static void decode_block_params(DiracContext *s, DiracArith arith[8], DiracBlock *block,
+                                int stride, int x, int y)
+{
+    int i;
+
+    block->ref  = pred_block_mode(block, stride, x, y, DIRAC_REF_MASK_REF1);
+    block->ref ^= dirac_get_arith_bit(arith, CTX_PMODE_REF1);
+
+    if (s->num_refs == 2) {
+        block->ref |= pred_block_mode(block, stride, x, y, DIRAC_REF_MASK_REF2);
+        block->ref ^= dirac_get_arith_bit(arith, CTX_PMODE_REF2) << 1;
+    }
+
+    if (!block->ref) {
+        pred_block_dc(block, stride, x, y);
+        for (i = 0; i < 3; i++)
+            block->u.dc[i] += dirac_get_arith_int(arith+1+i, CTX_DC_F1, CTX_DC_DATA);
+        return;
+    }
+
+    if (s->globalmc_flag) {
+        block->ref |= pred_block_mode(block, stride, x, y, DIRAC_REF_MASK_GLOBAL);
+        block->ref ^= dirac_get_arith_bit(arith, CTX_GLOBAL_BLOCK) << 2;
+    }
+
+    for (i = 0; i < s->num_refs; i++)
+        if (block->ref & (i+1)) {
+            if (block->ref & DIRAC_REF_MASK_GLOBAL) {
+                global_mv(s, block, x, y, i);
+            } else {
+                pred_mv(block, stride, x, y, i);
+                block->u.mv[i][0] += dirac_get_arith_int(arith + 4 + 2 * i, CTX_MV_F1, CTX_MV_DATA);
+                block->u.mv[i][1] += dirac_get_arith_int(arith + 5 + 2 * i, CTX_MV_F1, CTX_MV_DATA);
+            }
+        }
+}
+
+/**
+ * Copies the current block to the other blocks covered by the current superblock split mode
+ */
+static void propagate_block_data(DiracBlock *block, int stride, int size)
+{
+    int x, y;
+    DiracBlock *dst = block;
+
+    for (x = 1; x < size; x++)
+        dst[x] = *block;
+
+    for (y = 1; y < size; y++) {
+        dst += stride;
+        for (x = 0; x < size; x++)
+            dst[x] = *block;
+    }
+}
+
+/**
+ * Dirac Specification ->
+ * 12. Block motion data syntax
+ */
+static int dirac_unpack_block_motion_data(DiracContext *s)
+{
+    GetBitContext *gb = &s->gb;
+    uint8_t *sbsplit = s->sbsplit;
+    int i, x, y, q, p;
+    DiracArith arith[8];
+
+    align_get_bits(gb);
+
+    /* [DIRAC_STD] 11.2.4 and 12.2.1 Number of blocks and superblocks */
+    s->sbwidth  = DIVRNDUP(s->source.width,  4*s->plane[0].xbsep);
+    s->sbheight = DIVRNDUP(s->source.height, 4*s->plane[0].ybsep);
+    s->blwidth  = 4 * s->sbwidth;
+    s->blheight = 4 * s->sbheight;
+
+    /* [DIRAC_STD] 12.3.1 Superblock splitting modes. superblock_split_modes()
+       decode superblock split modes */
+    ff_dirac_init_arith_decoder(arith, gb, svq3_get_ue_golomb(gb));     /* svq3_get_ue_golomb(gb) is the length */
+    for (y = 0; y < s->sbheight; y++) {
+        for (x = 0; x < s->sbwidth; x++) {
+            unsigned int split  = dirac_get_arith_uint(arith, CTX_SB_F1, CTX_SB_DATA);
+            if (split > 2)
+                return -1;
+            sbsplit[x] = (split + pred_sbsplit(sbsplit+x, s->sbwidth, x, y)) % 3;
+        }
+        sbsplit += s->sbwidth;
+    }
+
+    /* setup arith decoding */
+    ff_dirac_init_arith_decoder(arith, gb, svq3_get_ue_golomb(gb));
+    for (i = 0; i < s->num_refs; i++) {
+        ff_dirac_init_arith_decoder(arith + 4 + 2 * i, gb, svq3_get_ue_golomb(gb));
+        ff_dirac_init_arith_decoder(arith + 5 + 2 * i, gb, svq3_get_ue_golomb(gb));
+    }
+    for (i = 0; i < 3; i++)
+        ff_dirac_init_arith_decoder(arith+1+i, gb, svq3_get_ue_golomb(gb));
+
+    for (y = 0; y < s->sbheight; y++)
+        for (x = 0; x < s->sbwidth; x++) {
+            int blkcnt = 1 << s->sbsplit[y * s->sbwidth + x];
+            int step   = 4 >> s->sbsplit[y * s->sbwidth + x];
+
+            for (q = 0; q < blkcnt; q++)
+                for (p = 0; p < blkcnt; p++) {
+                    int bx = 4 * x + p*step;
+                    int by = 4 * y + q*step;
+                    DiracBlock *block = &s->blmotion[by*s->blwidth + bx];
+                    decode_block_params(s, arith, block, s->blwidth, bx, by);
+                    propagate_block_data(block, s->blwidth, step);
+                }
+        }
+
+    return 0;
+}
+
+static int weight(int i, int blen, int offset)
+{
+#define ROLLOFF(i) offset == 1 ? ((i) ? 5 : 3) :        \
+    (1 + (6*(i) + offset - 1) / (2*offset - 1))
+
+    if (i < 2*offset)
+        return ROLLOFF(i);
+    else if (i > blen-1 - 2*offset)
+        return ROLLOFF(blen-1 - i);
+    return 8;
+}
+
+static void init_obmc_weight_row(Plane *p, uint8_t *obmc_weight, int stride,
+                                 int left, int right, int wy)
+{
+    int x;
+    for (x = 0; left && x < p->xblen >> 1; x++)
+        obmc_weight[x] = wy*8;
+    for (; x < p->xblen >> right; x++)
+        obmc_weight[x] = wy*weight(x, p->xblen, p->xoffset);
+    for (; x < p->xblen; x++)
+        obmc_weight[x] = wy*8;
+    for (; x < stride; x++)
+        obmc_weight[x] = 0;
+}
+
+static void init_obmc_weight(Plane *p, uint8_t *obmc_weight, int stride,
+                             int left, int right, int top, int bottom)
+{
+    int y;
+    for (y = 0; top && y < p->yblen >> 1; y++) {
+        init_obmc_weight_row(p, obmc_weight, stride, left, right, 8);
+        obmc_weight += stride;
+    }
+    for (; y < p->yblen >> bottom; y++) {
+        int wy = weight(y, p->yblen, p->yoffset);
+        init_obmc_weight_row(p, obmc_weight, stride, left, right, wy);
+        obmc_weight += stride;
+    }
+    for (; y < p->yblen; y++) {
+        init_obmc_weight_row(p, obmc_weight, stride, left, right, 8);
+        obmc_weight += stride;
+    }
+}
+
+static void init_obmc_weights(DiracContext *s, Plane *p, int by)
+{
+    int top = !by;
+    int bottom = by == s->blheight-1;
+
+    /* don't bother re-initing for rows 2 to blheight-2, the weights don't change */
+    if (top || bottom || by == 1) {
+        init_obmc_weight(p, s->obmc_weight[0], MAX_BLOCKSIZE, 1, 0, top, bottom);
+        init_obmc_weight(p, s->obmc_weight[1], MAX_BLOCKSIZE, 0, 0, top, bottom);
+        init_obmc_weight(p, s->obmc_weight[2], MAX_BLOCKSIZE, 0, 1, top, bottom);
+    }
+}
+
+static const uint8_t epel_weights[4][4][4] = {
+    {{ 16,  0,  0,  0 },
+     { 12,  4,  0,  0 },
+     {  8,  8,  0,  0 },
+     {  4, 12,  0,  0 }},
+    {{ 12,  0,  4,  0 },
+     {  9,  3,  3,  1 },
+     {  6,  6,  2,  2 },
+     {  3,  9,  1,  3 }},
+    {{  8,  0,  8,  0 },
+     {  6,  2,  6,  2 },
+     {  4,  4,  4,  4 },
+     {  2,  6,  2,  6 }},
+    {{  4,  0, 12,  0 },
+     {  3,  1,  9,  3 },
+     {  2,  2,  6,  6 },
+     {  1,  3,  3,  9 }}
+};
+
+/**
+ * For block x,y, determine which of the hpel planes to do bilinear
+ * interpolation from and set src[] to the location in each hpel plane
+ * to MC from.
+ *
+ * @return the index of the put_dirac_pixels_tab function to use
+ *  0 for 1 plane (fpel,hpel), 1 for 2 planes (qpel), 2 for 4 planes (qpel), and 3 for epel
+ */
+static int mc_subpel(DiracContext *s, DiracBlock *block, const uint8_t *src[5],
+                     int x, int y, int ref, int plane)
+{
+    Plane *p = &s->plane[plane];
+    uint8_t **ref_hpel = s->ref_pics[ref]->hpel[plane];
+    int motion_x = block->u.mv[ref][0];
+    int motion_y = block->u.mv[ref][1];
+    int mx, my, i, epel, nplanes = 0;
+
+    if (plane) {
+        motion_x >>= s->chroma_x_shift;
+        motion_y >>= s->chroma_y_shift;
+    }
+
+    mx         = motion_x & ~(-1 << s->mv_precision);
+    my         = motion_y & ~(-1 << s->mv_precision);
+    motion_x >>= s->mv_precision;
+    motion_y >>= s->mv_precision;
+    /* normalize subpel coordinates to epel */
+    /* TODO: template this function? */
+    mx      <<= 3 - s->mv_precision;
+    my      <<= 3 - s->mv_precision;
+
+    x += motion_x;
+    y += motion_y;
+    epel = (mx|my)&1;
+
+    /* hpel position */
+    if (!((mx|my)&3)) {
+        nplanes = 1;
+        src[0] = ref_hpel[(my>>1)+(mx>>2)] + y*p->stride + x;
+    } else {
+        /* qpel or epel */
+        nplanes = 4;
+        for (i = 0; i < 4; i++)
+            src[i] = ref_hpel[i] + y*p->stride + x;
+
+        /* if we're interpolating in the right/bottom halves, adjust the planes as needed
+           we increment x/y because the edge changes for half of the pixels */
+        if (mx > 4) {
+            src[0] += 1;
+            src[2] += 1;
+            x++;
+        }
+        if (my > 4) {
+            src[0] += p->stride;
+            src[1] += p->stride;
+            y++;
+        }
+
+        /* hpel planes are:
+           [0]: F  [1]: H
+           [2]: V  [3]: C */
+        if (!epel) {
+            /* check if we really only need 2 planes since either mx or my is
+               a hpel position. (epel weights of 0 handle this there) */
+            if (!(mx&3)) {
+                /* mx == 0: average [0] and [2]
+                   mx == 4: average [1] and [3] */
+                src[!mx] = src[2 + !!mx];
+                nplanes = 2;
+            } else if (!(my&3)) {
+                src[0] = src[(my>>1)  ];
+                src[1] = src[(my>>1)+1];
+                nplanes = 2;
+            }
+        } else {
+            /* adjust the ordering if needed so the weights work */
+            if (mx > 4) {
+                FFSWAP(const uint8_t *, src[0], src[1]);
+                FFSWAP(const uint8_t *, src[2], src[3]);
+            }
+            if (my > 4) {
+                FFSWAP(const uint8_t *, src[0], src[2]);
+                FFSWAP(const uint8_t *, src[1], src[3]);
+            }
+            src[4] = epel_weights[my&3][mx&3];
+        }
+    }
+
+    /* fixme: v/h _edge_pos */
+    if ((unsigned)x > p->width +EDGE_WIDTH/2 - p->xblen ||
+        (unsigned)y > p->height+EDGE_WIDTH/2 - p->yblen) {
+        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,
+                                p->width+EDGE_WIDTH/2, p->height+EDGE_WIDTH/2);
+            src[i] = s->edge_emu_buffer[i];
+        }
+    }
+    return (nplanes>>1) + epel;
+}
+
+static void add_dc(uint16_t *dst, int dc, int stride,
+                   uint8_t *obmc_weight, int xblen, int yblen)
+{
+    int x, y;
+    dc += 128;
+
+    for (y = 0; y < yblen; y++) {
+        for (x = 0; x < xblen; x += 2) {
+            dst[x  ] += dc * obmc_weight[x  ];
+            dst[x+1] += dc * obmc_weight[x+1];
+        }
+        dst          += stride;
+        obmc_weight  += MAX_BLOCKSIZE;
+    }
+}
+
+static void block_mc(DiracContext *s, DiracBlock *block,
+                     uint16_t *mctmp, uint8_t *obmc_weight,
+                     int plane, int dstx, int dsty)
+{
+    Plane *p = &s->plane[plane];
+    const uint8_t *src[5];
+    int idx;
+
+    switch (block->ref&3) {
+    case 0: /* DC */
+        add_dc(mctmp, block->u.dc[plane], p->stride, obmc_weight, p->xblen, p->yblen);
+        return;
+    case 1:
+    case 2:
+        idx = mc_subpel(s, block, src, dstx, dsty, (block->ref&3)-1, plane);
+        s->put_pixels_tab[idx](s->mcscratch, src, p->stride, p->yblen);
+        if (s->weight_func)
+            s->weight_func(s->mcscratch, p->stride, s->weight_log2denom,
+                           s->weight[0] + s->weight[1], p->yblen);
+        break;
+    case 3:
+        idx = mc_subpel(s, block, src, dstx, dsty, 0, plane);
+        s->put_pixels_tab[idx](s->mcscratch, src, p->stride, p->yblen);
+        idx = mc_subpel(s, block, src, dstx, dsty, 1, plane);
+        if (s->biweight_func) {
+            /* fixme: +32 is a quick hack */
+            s->put_pixels_tab[idx](s->mcscratch + 32, src, p->stride, p->yblen);
+            s->biweight_func(s->mcscratch, s->mcscratch+32, p->stride, s->weight_log2denom,
+                             s->weight[0], s->weight[1], p->yblen);
+        } else
+            s->avg_pixels_tab[idx](s->mcscratch, src, p->stride, p->yblen);
+        break;
+    }
+    s->add_obmc(mctmp, s->mcscratch, p->stride, obmc_weight, p->yblen);
+}
+
+static void mc_row(DiracContext *s, DiracBlock *block, uint16_t *mctmp, int plane, int dsty)
+{
+    Plane *p = &s->plane[plane];
+    int x, dstx = p->xbsep - p->xoffset;
+
+    block_mc(s, block, mctmp, s->obmc_weight[0], plane, -p->xoffset, dsty);
+    mctmp += p->xbsep;
+
+    for (x = 1; x < s->blwidth-1; x++) {
+        block_mc(s, block+x, mctmp, s->obmc_weight[1], plane, dstx, dsty);
+        dstx  += p->xbsep;
+        mctmp += p->xbsep;
+    }
+    block_mc(s, block+x, mctmp, s->obmc_weight[2], plane, dstx, dsty);
+}
+
+static void select_dsp_funcs(DiracContext *s, int width, int height, int xblen, int yblen)
+{
+    int idx = 0;
+    if (xblen > 8)
+        idx = 1;
+    if (xblen > 16)
+        idx = 2;
+
+    memcpy(s->put_pixels_tab, s->diracdsp.put_dirac_pixels_tab[idx], sizeof(s->put_pixels_tab));
+    memcpy(s->avg_pixels_tab, s->diracdsp.avg_dirac_pixels_tab[idx], sizeof(s->avg_pixels_tab));
+    s->add_obmc = s->diracdsp.add_dirac_obmc[idx];
+    if (s->weight_log2denom > 1 || s->weight[0] != 1 || s->weight[1] != 1) {
+        s->weight_func   = s->diracdsp.weight_dirac_pixels_tab[idx];
+        s->biweight_func = s->diracdsp.biweight_dirac_pixels_tab[idx];
+    } else {
+        s->weight_func   = NULL;
+        s->biweight_func = NULL;
+    }
+}
+
+static void interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, int width, int height)
+{
+    /* chroma allocates an edge of 8 when subsampled
+       which for 4:2:2 means an h edge of 16 and v edge of 8
+       just use 8 for everything for the moment */
+    int i, edge = EDGE_WIDTH/2;
+
+    ref->hpel[plane][0] = ref->avframe.data[plane];
+    s->dsp.draw_edges(ref->hpel[plane][0], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */
+
+    /* no need for hpel if we only have fpel vectors */
+    if (!s->mv_precision)
+        return;
+
+    for (i = 1; i < 4; i++) {
+        if (!ref->hpel_base[plane][i])
+            ref->hpel_base[plane][i] = av_malloc((height+2*edge) * ref->avframe.linesize[plane] + 32);
+        /* we need to be 16-byte aligned even for chroma */
+        ref->hpel[plane][i] = ref->hpel_base[plane][i] + edge*ref->avframe.linesize[plane] + 16;
+    }
+
+    if (!ref->interpolated[plane]) {
+        s->diracdsp.dirac_hpel_filter(ref->hpel[plane][1], ref->hpel[plane][2],
+                                      ref->hpel[plane][3], ref->hpel[plane][0],
+                                      ref->avframe.linesize[plane], width, height);
+        s->dsp.draw_edges(ref->hpel[plane][1], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
+        s->dsp.draw_edges(ref->hpel[plane][2], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
+        s->dsp.draw_edges(ref->hpel[plane][3], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
+    }
+    ref->interpolated[plane] = 1;
+}
+
+/**
+ * Dirac Specification ->
+ * 13.0 Transform data syntax. transform_data()
+ */
+static int dirac_decode_frame_internal(DiracContext *s)
+{
+    DWTContext d;
+    int y, i, comp, dsty;
+
+    if (s->low_delay) {
+        /* [DIRAC_STD] 13.5.1 low_delay_transform_data() */
+        for (comp = 0; comp < 3; comp++) {
+            Plane *p = &s->plane[comp];
+            memset(p->idwt_buf, 0, p->idwt_stride * p->idwt_height * sizeof(IDWTELEM));
+        }
+        if (!s->zero_res)
+            decode_lowdelay(s);
+    }
+
+    for (comp = 0; comp < 3; comp++) {
+        Plane *p       = &s->plane[comp];
+        uint8_t *frame = s->current_picture->avframe.data[comp];
+
+        /* FIXME: small resolutions */
+        for (i = 0; i < 4; i++)
+            s->edge_emu_buffer[i] = s->edge_emu_buffer_base + i*FFALIGN(p->width, 16);
+
+        if (!s->zero_res && !s->low_delay)
+        {
+            memset(p->idwt_buf, 0, p->idwt_stride * p->idwt_height * sizeof(IDWTELEM));
+            decode_component(s, comp); /* [DIRAC_STD] 13.4.1 core_transform_data() */
+        }
+        if (ff_spatial_idwt_init2(&d, p->idwt_buf, p->idwt_width, p->idwt_height, p->idwt_stride,
+                                  s->wavelet_idx+2, s->wavelet_depth, p->idwt_tmp))
+            return -1;
+
+        if (!s->num_refs) { /* intra */
+            for (y = 0; y < p->height; y += 16) {
+                ff_spatial_idwt_slice2(&d, y+16); /* decode */
+                s->diracdsp.put_signed_rect_clamped(frame + y*p->stride, p->stride,
+                                                    p->idwt_buf + y*p->idwt_stride, p->idwt_stride, p->width, 16);
+            }
+        } else { /* inter */
+            int rowheight = p->ybsep*p->stride;
+
+            select_dsp_funcs(s, p->width, p->height, p->xblen, p->yblen);
+
+            for (i = 0; i < s->num_refs; i++)
+                interpolate_refplane(s, s->ref_pics[i], comp, p->width, p->height);
+
+            memset(s->mctmp, 0, 4*p->yoffset*p->stride);
+
+            dsty = -p->yoffset;
+            for (y = 0; y < s->blheight; y++) {
+                int h     = 0,
+                    start = FFMAX(dsty, 0);
+                uint16_t *mctmp    = s->mctmp + y*rowheight;
+                DiracBlock *blocks = s->blmotion + y*s->blwidth;
+
+                init_obmc_weights(s, p, y);
+
+                if (y == s->blheight-1 || start+p->ybsep > p->height)
+                    h = p->height - start;
+                else
+                    h = p->ybsep - (start - dsty);
+                if (h < 0)
+                    break;
+
+                memset(mctmp+2*p->yoffset*p->stride, 0, 2*rowheight);
+                mc_row(s, blocks, mctmp, comp, dsty);
+
+                mctmp += (start - dsty)*p->stride + p->xoffset;
+                ff_spatial_idwt_slice2(&d, start + h); /* decode */
+                s->diracdsp.add_rect_clamped(frame + start*p->stride, mctmp, p->stride,
+                                             p->idwt_buf + start*p->idwt_stride, p->idwt_stride, p->width, h);
+
+                dsty += p->ybsep;
+            }
+        }
+    }
+
+
+    return 0;
+}
+
+/**
+ * Dirac Specification ->
+ * 11.1.1 Picture Header. picture_header()
+ */
+static int dirac_decode_picture_header(DiracContext *s)
+{
+    int retire, picnum;
+    int i, j, refnum, refdist;
+    GetBitContext *gb = &s->gb;
+
+    /* [DIRAC_STD] 11.1.1 Picture Header. picture_header() PICTURE_NUM */
+    picnum = s->current_picture->avframe.display_picture_number = get_bits_long(gb, 32);
+
+
+    av_log(s->avctx,AV_LOG_DEBUG,"PICTURE_NUM: %d\n",picnum);
+
+    /* if this is the first keyframe after a sequence header, start our
+       reordering from here */
+    if (s->frame_number < 0)
+        s->frame_number = picnum;
+
+    s->ref_pics[0] = s->ref_pics[1] = NULL;
+    for (i = 0; i < s->num_refs; i++) {
+        refnum = picnum + dirac_get_se_golomb(gb);
+        refdist = INT_MAX;
+
+        /* find the closest reference to the one we want */
+        /* Jordi: this is needed if the referenced picture hasn't yet arrived */
+        for (j = 0; j < MAX_REFERENCE_FRAMES && refdist; j++)
+            if (s->ref_frames[j]
+                && FFABS(s->ref_frames[j]->avframe.display_picture_number - refnum) < refdist) {
+                s->ref_pics[i] = s->ref_frames[j];
+                refdist = FFABS(s->ref_frames[j]->avframe.display_picture_number - refnum);
+            }
+
+        if (!s->ref_pics[i] || refdist)
+            av_log(s->avctx, AV_LOG_DEBUG, "Reference not found\n");
+
+        /* if there were no references at all, allocate one */
+        if (!s->ref_pics[i])
+            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);
+                }
+    }
+
+    /* retire the reference frames that are not used anymore */
+    if (s->current_picture->avframe.reference) {
+        retire = picnum + dirac_get_se_golomb(gb);
+        if (retire != picnum) {
+            DiracFrame *retire_pic = remove_frame(s->ref_frames, retire);
+
+            if (retire_pic)
+                retire_pic->avframe.reference &= DELAYED_PIC_REF;
+            else
+                av_log(s->avctx, AV_LOG_DEBUG, "Frame to retire not found\n");
+        }
+
+        /* if reference array is full, remove the oldest as per the spec */
+        while (add_frame(s->ref_frames, MAX_REFERENCE_FRAMES, s->current_picture)) {
+            av_log(s->avctx, AV_LOG_ERROR, "Reference frame overflow\n");
+            remove_frame(s->ref_frames, s->ref_frames[0]->avframe.display_picture_number)->avframe.reference &= DELAYED_PIC_REF;
+        }
+    }
+
+    if (s->num_refs) {
+        if (dirac_unpack_prediction_parameters(s))  /* [DIRAC_STD] 11.2 Picture Prediction Data. picture_prediction() */
+            return -1;
+        if (dirac_unpack_block_motion_data(s))      /* [DIRAC_STD] 12. Block motion data syntax                       */
+            return -1;
+    }
+    if (dirac_unpack_idwt_params(s))                /* [DIRAC_STD] 11.3 Wavelet transform data                        */
+        return -1;
+
+    init_planes(s);
+    return 0;
+}
+
+static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *data_size)
+{
+    DiracFrame *out = s->delay_frames[0];
+    int i, out_idx  = 0;
+
+    /* find frame with lowest picture number */
+    for (i = 1; s->delay_frames[i]; i++)
+        if (s->delay_frames[i]->avframe.display_picture_number < out->avframe.display_picture_number) {
+            out     = s->delay_frames[i];
+            out_idx = i;
+        }
+
+    for (i = out_idx; s->delay_frames[i]; i++)
+        s->delay_frames[i] = s->delay_frames[i+1];
+
+    if (out) {
+        out->avframe.reference ^= DELAYED_PIC_REF;
+        *data_size = sizeof(AVFrame);
+        *(AVFrame *)picture = out->avframe;
+    }
+
+    return 0;
+}
+
+/**
+ * Dirac Specification ->
+ * 9.6 Parse Info Header Syntax. parse_info()
+ * 4 byte start code + byte parse code + 4 byte size + 4 byte previous size
+ */
+#define DATA_UNIT_HEADER_SIZE 13
+
+/* [DIRAC_STD] dirac_decode_data_unit makes reference to the while defined in 9.3
+   inside the function parse_sequence() */
+static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int size)
+{
+    DiracContext *s   = avctx->priv_data;
+    DiracFrame *pic   = NULL;
+    int i, parse_code = buf[4];
+    unsigned tmp;
+
+    if (size < DATA_UNIT_HEADER_SIZE)
+        return -1;
+
+    init_get_bits(&s->gb, &buf[13], 8*(size - DATA_UNIT_HEADER_SIZE));
+
+    if (parse_code == pc_seq_header) {
+        if (s->seen_sequence_header)
+            return 0;
+
+        /* [DIRAC_STD] 10. Sequence header */
+        if (avpriv_dirac_parse_sequence_header(avctx, &s->gb, &s->source))
+            return -1;
+
+        avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift);
+
+        if (alloc_sequence_buffers(s))
+            return -1;
+
+        s->seen_sequence_header = 1;
+    } else if (parse_code == pc_eos) { /* [DIRAC_STD] End of Sequence */
+        free_sequence_buffers(s);
+        s->seen_sequence_header = 0;
+    } else if (parse_code == pc_aux_data) {
+        if (buf[13] == 1) {     /* encoder implementation/version */
+            int ver[3];
+            /* versions older than 1.0.8 don't store quant delta for
+               subbands with only one codeblock */
+            if (sscanf(buf+14, "Schroedinger %d.%d.%d", ver, ver+1, ver+2) == 3)
+                if (ver[0] == 1 && ver[1] == 0 && ver[2] <= 7)
+                    s->old_delta_quant = 1;
+        }
+    } else if (parse_code & 0x8) {  /* picture data unit */
+        if (!s->seen_sequence_header) {
+            av_log(avctx, AV_LOG_DEBUG, "Dropping frame without sequence header\n");
+            return -1;
+        }
+
+        /* find an unused frame */
+        for (i = 0; i < MAX_FRAMES; i++)
+            if (s->all_frames[i].avframe.data[0] == NULL)
+                pic = &s->all_frames[i];
+        if (!pic) {
+            av_log(avctx, AV_LOG_ERROR, "framelist full\n");
+            return -1;
+        }
+
+        avcodec_get_frame_defaults(&pic->avframe);
+
+        /* [DIRAC_STD] Defined in 9.6.1 ... */
+        tmp            =  parse_code & 0x03;                   /* [DIRAC_STD] num_refs()      */
+        if (tmp > 2) {
+            av_log(avctx, AV_LOG_ERROR, "num_refs of 3\n");
+            return -1;
+        }
+        s->num_refs    = tmp;
+        s->is_arith    = (parse_code & 0x48) == 0x08;          /* [DIRAC_STD] using_ac()      */
+        s->low_delay   = (parse_code & 0x88) == 0x88;          /* [DIRAC_STD] is_low_delay()  */
+        pic->avframe.reference = (parse_code & 0x0C) == 0x0C;  /* [DIRAC_STD]  is_reference() */
+        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) {
+            av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+            return -1;
+        }
+        s->current_picture = pic;
+        s->plane[0].stride = pic->avframe.linesize[0];
+        s->plane[1].stride = pic->avframe.linesize[1];
+        s->plane[2].stride = pic->avframe.linesize[2];
+
+        /* [DIRAC_STD] 11.1 Picture parse. picture_parse() */
+        if (dirac_decode_picture_header(s))
+            return -1;
+
+        /* [DIRAC_STD] 13.0 Transform data syntax. transform_data() */
+        if (dirac_decode_frame_internal(s))
+            return -1;
+    }
+    return 0;
+}
+
+static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt)
+{
+    DiracContext *s     = avctx->priv_data;
+    DiracFrame *picture = data;
+    uint8_t *buf        = pkt->data;
+    int buf_size        = pkt->size;
+    int i, data_unit_size, buf_idx = 0;
+
+    /* release unused frames */
+    for (i = 0; i < MAX_FRAMES; i++)
+        if (s->all_frames[i].avframe.data[0] && !s->all_frames[i].avframe.reference) {
+            avctx->release_buffer(avctx, &s->all_frames[i].avframe);
+            memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated));
+        }
+
+    s->current_picture = NULL;
+    *data_size = 0;
+
+    /* end of stream, so flush delayed pics */
+    if (buf_size == 0)
+        return get_delayed_pic(s, (AVFrame *)data, data_size);
+
+    for (;;) {
+        /*[DIRAC_STD] Here starts the code from parse_info() defined in 9.6
+          [DIRAC_STD] PARSE_INFO_PREFIX = "BBCD" as defined in ISO/IEC 646
+          BBCD start code search */
+        for (; buf_idx + DATA_UNIT_HEADER_SIZE < buf_size; buf_idx++) {
+            if (buf[buf_idx  ] == 'B' && buf[buf_idx+1] == 'B' &&
+                buf[buf_idx+2] == 'C' && buf[buf_idx+3] == 'D')
+                break;
+        }
+        /* BBCD found or end of data */
+        if (buf_idx + DATA_UNIT_HEADER_SIZE >= buf_size)
+            break;
+
+        data_unit_size = AV_RB32(buf+buf_idx+5);
+        if (buf_idx + data_unit_size > buf_size || !data_unit_size) {
+            if(buf_idx + data_unit_size > buf_size)
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "Data unit with size %d is larger than input buffer, discarding\n",
+                   data_unit_size);
+            buf_idx += 4;
+            continue;
+        }
+        /* [DIRAC_STD] dirac_decode_data_unit makes reference to the while defined in 9.3 inside the function parse_sequence() */
+        if (dirac_decode_data_unit(avctx, buf+buf_idx, data_unit_size))
+        {
+            av_log(s->avctx, AV_LOG_ERROR,"Error in dirac_decode_data_unit\n");
+            return -1;
+        }
+        buf_idx += data_unit_size;
+    }
+
+    if (!s->current_picture)
+        return buf_size;
+
+    if (s->current_picture->avframe.display_picture_number > s->frame_number) {
+        DiracFrame *delayed_frame = remove_frame(s->delay_frames, s->frame_number);
+
+        s->current_picture->avframe.reference |= DELAYED_PIC_REF;
+
+        if (add_frame(s->delay_frames, MAX_DELAY, s->current_picture)) {
+            int min_num = s->delay_frames[0]->avframe.display_picture_number;
+            /* Too many delayed frames, so we display the frame with the lowest pts */
+            av_log(avctx, AV_LOG_ERROR, "Delay frame overflow\n");
+            delayed_frame = s->delay_frames[0];
+
+            for (i = 1; s->delay_frames[i]; i++)
+                if (s->delay_frames[i]->avframe.display_picture_number < min_num)
+                    min_num = s->delay_frames[i]->avframe.display_picture_number;
+
+            delayed_frame = remove_frame(s->delay_frames, min_num);
+            add_frame(s->delay_frames, MAX_DELAY, s->current_picture);
+        }
+
+        if (delayed_frame) {
+            delayed_frame->avframe.reference ^= DELAYED_PIC_REF;
+            *(AVFrame*)data = delayed_frame->avframe;
+            *data_size = sizeof(AVFrame);
+        }
+    } 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);
+    }
+
+    if (*data_size)
+        s->frame_number = picture->avframe.display_picture_number + 1;
+
+    return buf_idx;
+}
+
+AVCodec ff_dirac_decoder = {
+    .name           = "dirac",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_DIRAC,
+    .priv_data_size = sizeof(DiracContext),
+    .init           = dirac_decode_init,
+    .close          = dirac_decode_end,
+    .decode         = dirac_decode_frame,
+    .capabilities   = CODEC_CAP_DELAY,
+    .flush          = dirac_decode_flush,
+    .long_name      = NULL_IF_CONFIG_SMALL("BBC Dirac VC-2"),
+};
diff --git a/libavcodec/diracdsp.c b/libavcodec/diracdsp.c
new file mode 100644
index 0000000..429241d
--- /dev/null
+++ b/libavcodec/diracdsp.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2009 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 "dsputil.h"
+#include "diracdsp.h"
+#include "libavcodec/x86/diracdsp_mmx.h"
+
+#define FILTER(src, stride)                                     \
+    ((21*((src)[ 0*stride] + (src)[1*stride])                   \
+      -7*((src)[-1*stride] + (src)[2*stride])                   \
+      +3*((src)[-2*stride] + (src)[3*stride])                   \
+      -1*((src)[-3*stride] + (src)[4*stride]) + 16) >> 5)
+
+static void dirac_hpel_filter(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, const uint8_t *src,
+                              int stride, int width, int height)
+{
+    int x, y;
+
+    for (y = 0; y < height; y++) {
+        for (x = -3; x < width+5; x++)
+            dstv[x] = av_clip_uint8(FILTER(src+x, stride));
+
+        for (x = 0; x < width; x++)
+            dstc[x] = av_clip_uint8(FILTER(dstv+x, 1));
+
+        for (x = 0; x < width; x++)
+            dsth[x] = av_clip_uint8(FILTER(src+x, 1));
+
+        src  += stride;
+        dsth += stride;
+        dstv += stride;
+        dstc += stride;
+    }
+}
+
+#define PIXOP_BILINEAR(PFX, OP, WIDTH)                                  \
+    static void ff_ ## PFX ## _dirac_pixels ## WIDTH ## _bilinear_c(uint8_t *dst, const uint8_t *src[5], int stride, int h) \
+    {                                                                   \
+        int x;                                                          \
+        const uint8_t *s0 = src[0];                                     \
+        const uint8_t *s1 = src[1];                                     \
+        const uint8_t *s2 = src[2];                                     \
+        const uint8_t *s3 = src[3];                                     \
+        const uint8_t *w  = src[4];                                     \
+                                                                        \
+        while (h--) {                                                   \
+            for (x = 0; x < WIDTH; x++) {                               \
+                OP(dst[x], (s0[x]*w[0] + s1[x]*w[1] + s2[x]*w[2] + s3[x]*w[3] + 8) >> 4); \
+            }                                                           \
+                                                                        \
+            dst += stride;                                              \
+            s0 += stride;                                               \
+            s1 += stride;                                               \
+            s2 += stride;                                               \
+            s3 += stride;                                               \
+        }                                                               \
+    }
+
+#define OP_PUT(dst, val) (dst) = (val)
+#define OP_AVG(dst, val) (dst) = (((dst) + (val) + 1)>>1)
+
+PIXOP_BILINEAR(put, OP_PUT, 8)
+PIXOP_BILINEAR(put, OP_PUT, 16)
+PIXOP_BILINEAR(put, OP_PUT, 32)
+PIXOP_BILINEAR(avg, OP_AVG, 8)
+PIXOP_BILINEAR(avg, OP_AVG, 16)
+PIXOP_BILINEAR(avg, OP_AVG, 32)
+
+#define op_scale1(x)  block[x] = av_clip_uint8( (block[x]*weight + (1<<(log2_denom-1))) >> log2_denom)
+#define op_scale2(x)  dst[x] = av_clip_uint8( (src[x]*weights + dst[x]*weightd + (1<<(log2_denom-1))) >> log2_denom)
+
+#define DIRAC_WEIGHT(W)                                                 \
+    static void weight_dirac_pixels ## W ## _c(uint8_t *block, int stride, int log2_denom, \
+                                               int weight, int h) {     \
+        int x;                                                          \
+        while (h--) {                                                   \
+            for (x = 0; x < W; x++) {                                   \
+                op_scale1(x);                                           \
+                op_scale1(x+1);                                         \
+            }                                                           \
+            block += stride;                                            \
+        }                                                               \
+    }                                                                   \
+    static void biweight_dirac_pixels ## W ## _c(uint8_t *dst, const uint8_t *src, int stride, int log2_denom, \
+                                                 int weightd, int weights, int h) { \
+        int x;                                                          \
+        while (h--) {                                                   \
+            for (x = 0; x < W; x++) {                                   \
+                op_scale2(x);                                           \
+                op_scale2(x+1);                                         \
+            }                                                           \
+            dst += stride;                                              \
+            src += stride;                                              \
+        }                                                               \
+    }
+
+DIRAC_WEIGHT(8)
+DIRAC_WEIGHT(16)
+DIRAC_WEIGHT(32)
+
+#define ADD_OBMC(xblen)                                                 \
+    static void add_obmc ## xblen ## _c(uint16_t *dst, const uint8_t *src, int stride, \
+                                        const uint8_t *obmc_weight, int yblen) \
+    {                                                                   \
+        int x;                                                          \
+        while (yblen--) {                                               \
+            for (x = 0; x < xblen; x += 2) {                            \
+                dst[x  ] += src[x  ] * obmc_weight[x  ];                \
+                dst[x+1] += src[x+1] * obmc_weight[x+1];                \
+            }                                                           \
+            dst += stride;                                              \
+            src += stride;                                              \
+            obmc_weight += 32;                                          \
+        }                                                               \
+    }
+
+ADD_OBMC(8)
+ADD_OBMC(16)
+ADD_OBMC(32)
+
+static void put_signed_rect_clamped_c(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height)
+{
+    int x, y;
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x+=4) {
+            dst[x  ] = av_clip_uint8(src[x  ] + 128);
+            dst[x+1] = av_clip_uint8(src[x+1] + 128);
+            dst[x+2] = av_clip_uint8(src[x+2] + 128);
+            dst[x+3] = av_clip_uint8(src[x+3] + 128);
+        }
+        dst += dst_stride;
+        src += src_stride;
+    }
+}
+
+static void add_rect_clamped_c(uint8_t *dst, const uint16_t *src, int stride,
+                               const int16_t *idwt, int idwt_stride,
+                               int width, int height)
+{
+    int x, y;
+
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x+=2) {
+            dst[x  ] = av_clip_uint8(((src[x  ]+32)>>6) + idwt[x  ]);
+            dst[x+1] = av_clip_uint8(((src[x+1]+32)>>6) + idwt[x+1]);
+        }
+        dst += stride;
+        src += stride;
+        idwt += idwt_stride;
+    }
+}
+
+#define PIXFUNC(PFX, WIDTH)                                             \
+    c->PFX ## _dirac_pixels_tab[WIDTH>>4][0] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _c; \
+    c->PFX ## _dirac_pixels_tab[WIDTH>>4][1] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _l2_c; \
+    c->PFX ## _dirac_pixels_tab[WIDTH>>4][2] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _l4_c; \
+    c->PFX ## _dirac_pixels_tab[WIDTH>>4][3] = ff_ ## PFX ## _dirac_pixels ## WIDTH ## _bilinear_c
+
+void ff_diracdsp_init(DiracDSPContext *c)
+{
+    c->dirac_hpel_filter = dirac_hpel_filter;
+    c->add_rect_clamped = add_rect_clamped_c;
+    c->put_signed_rect_clamped = put_signed_rect_clamped_c;
+
+    c->add_dirac_obmc[0] = add_obmc8_c;
+    c->add_dirac_obmc[1] = add_obmc16_c;
+    c->add_dirac_obmc[2] = add_obmc32_c;
+
+    c->weight_dirac_pixels_tab[0] = weight_dirac_pixels8_c;
+    c->weight_dirac_pixels_tab[1] = weight_dirac_pixels16_c;
+    c->weight_dirac_pixels_tab[2] = weight_dirac_pixels32_c;
+    c->biweight_dirac_pixels_tab[0] = biweight_dirac_pixels8_c;
+    c->biweight_dirac_pixels_tab[1] = biweight_dirac_pixels16_c;
+    c->biweight_dirac_pixels_tab[2] = biweight_dirac_pixels32_c;
+
+    PIXFUNC(put, 8);
+    PIXFUNC(put, 16);
+    PIXFUNC(put, 32);
+    PIXFUNC(avg, 8);
+    PIXFUNC(avg, 16);
+    PIXFUNC(avg, 32);
+
+    if (HAVE_MMX && HAVE_YASM) ff_diracdsp_init_mmx(c);
+}
diff --git a/libavcodec/diracdsp.h b/libavcodec/diracdsp.h
new file mode 100644
index 0000000..613ca5b
--- /dev/null
+++ b/libavcodec/diracdsp.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2010 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
+ */
+
+#ifndef AVCODEC_DIRACDSP_H
+#define AVCODEC_DIRACDSP_H
+
+#include <stdint.h>
+
+typedef void (*dirac_weight_func)(uint8_t *block, int stride, int log2_denom, int weight, int h);
+typedef void (*dirac_biweight_func)(uint8_t *dst, const uint8_t *src, int stride, int log2_denom, int weightd, int weights, int h);
+
+typedef struct {
+    void (*dirac_hpel_filter)(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, const uint8_t *src, int stride, int width, int height);
+    /**
+     * dirac_pixels_tab[width][subpel]
+     * width is 2 for 32, 1 for 16, 0 for 8
+     * subpel is 0 for fpel and hpel (only need to copy from the first plane in src)
+     *           1 if an average of the first 2 planes is needed (TODO: worth it?)
+     *           2 for general qpel (avg of 4)
+     *           3 for general epel (biweight of 4 using the weights in src[4])
+     * src[0-3] is each of the hpel planes
+     * src[4] is the 1/8 pel weights if needed
+     */
+    void (*put_dirac_pixels_tab[3][4])(uint8_t *dst, const uint8_t *src[5], int stride, int h);
+    void (*avg_dirac_pixels_tab[3][4])(uint8_t *dst, const uint8_t *src[5], int stride, int h);
+
+    void (*put_signed_rect_clamped)(uint8_t *dst/*align 16*/, int dst_stride, const int16_t *src/*align 16*/, int src_stride, int width, int height/*mod 2*/);
+    void (*put_rect_clamped)(uint8_t *dst/*align 16*/, int dst_stride, const int16_t *src/*align 16*/, int src_stride, int width, int height/*mod 2*/);
+    void (*add_rect_clamped)(uint8_t *dst/*align 16*/, const uint16_t *src/*align 16*/, int stride, const int16_t *idwt/*align 16*/, int idwt_stride, int width, int height/*mod 2*/);
+    void (*add_dirac_obmc[3])(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen);
+
+    dirac_weight_func weight_dirac_pixels_tab[3];
+    dirac_biweight_func biweight_dirac_pixels_tab[3];
+} DiracDSPContext;
+
+#define DECL_DIRAC_PIXOP(PFX, EXT)                                      \
+    void ff_ ## PFX ## _dirac_pixels8_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h); \
+    void ff_ ## PFX ## _dirac_pixels16_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h); \
+    void ff_ ## PFX ## _dirac_pixels32_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)
+
+DECL_DIRAC_PIXOP(put, c);
+DECL_DIRAC_PIXOP(avg, c);
+DECL_DIRAC_PIXOP(put, l2_c);
+DECL_DIRAC_PIXOP(avg, l2_c);
+DECL_DIRAC_PIXOP(put, l4_c);
+DECL_DIRAC_PIXOP(avg, l4_c);
+
+void ff_diracdsp_init(DiracDSPContext *c);
+
+#endif /* AVCODEC_DIRACDSP_H */
diff --git a/libavcodec/dnxhd_parser.c b/libavcodec/dnxhd_parser.c
index d981079..6e030e4 100644
--- a/libavcodec/dnxhd_parser.c
+++ b/libavcodec/dnxhd_parser.c
@@ -2,20 +2,20 @@
  * DNxHD/VC-3 parser
  * Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@free.fr>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,21 +26,32 @@
 
 #include "parser.h"
 
-#define DNXHD_HEADER_PREFIX 0x0000028001
+#define DNXHD_HEADER_PREFIX 0x000002800100
 
-static int dnxhd_find_frame_end(ParseContext *pc,
+typedef struct {
+    ParseContext pc;
+    int interlaced;
+    int cur_field; /* first field is 0, second is 1 */
+} DNXHDParserContext;
+
+static int dnxhd_find_frame_end(DNXHDParserContext *dctx,
                                 const uint8_t *buf, int buf_size)
 {
+    ParseContext *pc = &dctx->pc;
     uint64_t state = pc->state64;
     int pic_found = pc->frame_start_found;
     int i = 0;
+    int interlaced = dctx->interlaced;
+    int cur_field = dctx->cur_field;
 
     if (!pic_found) {
         for (i = 0; i < buf_size; i++) {
             state = (state<<8) | buf[i];
-            if ((state & 0xffffffffffLL) == DNXHD_HEADER_PREFIX) {
+            if ((state & 0xffffffffff00LL) == DNXHD_HEADER_PREFIX) {
                 i++;
                 pic_found = 1;
+                interlaced = (state&2)>>1; /* byte following the 5-byte header prefix */
+                cur_field = state&1;
                 break;
             }
         }
@@ -51,15 +62,25 @@
             return 0;
         for (; i < buf_size; i++) {
             state = (state<<8) | buf[i];
-            if ((state & 0xffffffffffLL) == DNXHD_HEADER_PREFIX) {
-                pc->frame_start_found = 0;
-                pc->state64 = -1;
-                return i-4;
+            if ((state & 0xffffffffff00LL) == DNXHD_HEADER_PREFIX) {
+                if (!interlaced || dctx->cur_field) {
+                    pc->frame_start_found = 0;
+                    pc->state64 = -1;
+                    dctx->interlaced = interlaced;
+                    dctx->cur_field = 0;
+                    return i-5;
+                } else {
+                    /* continue, to get the second field */
+                    dctx->interlaced = interlaced = (state&2)>>1;
+                    dctx->cur_field = cur_field = state&1;
+                }
             }
         }
     }
     pc->frame_start_found = pic_found;
     pc->state64 = state;
+    dctx->interlaced = interlaced;
+    dctx->cur_field = cur_field;
     return END_NOT_FOUND;
 }
 
@@ -68,13 +89,14 @@
                        const uint8_t **poutbuf, int *poutbuf_size,
                        const uint8_t *buf, int buf_size)
 {
-    ParseContext *pc = s->priv_data;
+    DNXHDParserContext *dctx = s->priv_data;
+    ParseContext *pc = &dctx->pc;
     int next;
 
     if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
         next = buf_size;
     } else {
-        next = dnxhd_find_frame_end(pc, buf, buf_size);
+        next = dnxhd_find_frame_end(dctx, buf, buf_size);
         if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
             *poutbuf = NULL;
             *poutbuf_size = 0;
@@ -88,7 +110,7 @@
 
 AVCodecParser ff_dnxhd_parser = {
     .codec_ids      = { AV_CODEC_ID_DNXHD },
-    .priv_data_size = sizeof(ParseContext),
+    .priv_data_size = sizeof(DNXHDParserContext),
     .parser_parse   = dnxhd_parse,
     .parser_close   = ff_parse_close,
 };
diff --git a/libavcodec/dnxhddata.c b/libavcodec/dnxhddata.c
index 96895da..c3d2204 100644
--- a/libavcodec/dnxhddata.c
+++ b/libavcodec/dnxhddata.c
@@ -2,20 +2,20 @@
  * VC3/DNxHD data.
  * Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -23,26 +23,28 @@
 #include "dnxhddata.h"
 #include "libavutil/common.h"
 
+/* The quantization tables below are in zigzag order! */
+
 static const uint8_t dnxhd_1235_luma_weight[] = {
-     0, 32, 32, 32, 33, 35, 38, 39,
-    32, 33, 32, 33, 36, 36, 39, 42,
-    32, 32, 33, 36, 35, 37, 41, 43,
-    31, 33, 34, 36, 36, 40, 42, 48,
-    32, 34, 36, 37, 39, 42, 46, 51,
-    36, 37, 37, 39, 41, 46, 51, 55,
-    37, 39, 41, 41, 47, 50, 55, 56,
-    41, 42, 41, 44, 50, 53, 60, 60
+     0, 32, 32, 32, 33, 32, 32, 32,
+    32, 31, 32, 33, 33, 33, 33, 35,
+    36, 36, 34, 34, 36, 37, 37, 36,
+    36, 35, 36, 38, 39, 39, 37, 36,
+    37, 37, 39, 41, 42, 41, 39, 39,
+    40, 41, 42, 43, 42, 42, 41, 41,
+    41, 44, 47, 46, 46, 48, 51, 51,
+    50, 50, 53, 55, 55, 56, 60, 60,
 };
 
 static const uint8_t dnxhd_1235_chroma_weight[] = {
-     0, 32, 33, 34, 39, 41, 54, 59,
-    33, 34, 35, 38, 43, 49, 58, 84,
-    34, 37, 39, 44, 46, 55, 74, 87,
-    40, 42, 47, 48, 58, 70, 87, 86,
-    43, 50, 56, 63, 72, 94, 91, 82,
-    55, 63, 65, 75, 93, 89, 85, 73,
-    61, 67, 82, 81, 83, 90, 79, 73,
-    74, 84, 75, 78, 90, 85, 73, 73
+     0, 32, 33, 34, 34, 33, 34, 35,
+    37, 40, 43, 42, 39, 38, 39, 41,
+    43, 44, 47, 50, 55, 61, 63, 56,
+    48, 46, 49, 54, 59, 58, 55, 58,
+    63, 65, 67, 74, 84, 82, 75, 72,
+    70, 74, 84, 87, 87, 94, 93, 81,
+    75, 78, 83, 89, 91, 86, 82, 85,
+    90, 90, 85, 79, 73, 73, 73, 73,
 };
 
 static const uint8_t dnxhd_1237_luma_weight[] = {
@@ -156,25 +158,25 @@
 };
 
 static const uint8_t dnxhd_1250_luma_weight[] = {
-     0, 32, 35, 35, 36, 36, 41, 43,
-    32, 34, 35, 36, 37, 39, 43, 47,
-    33, 34, 36, 38, 38, 42, 42, 50,
-    34, 36, 38, 38, 41, 40, 47, 54,
-    35, 38, 39, 40, 39, 45, 49, 58,
-    38, 39, 40, 39, 46, 47, 54, 60,
-    38, 39, 41, 46, 46, 48, 57, 62,
-    40, 41, 44, 45, 49, 54, 63, 63
+     0, 32, 32, 33, 34, 35, 35, 35,
+    34, 34, 35, 36, 36, 36, 36, 36,
+    37, 38, 38, 38, 38, 38, 39, 39,
+    38, 38, 39, 41, 43, 43, 42, 41,
+    40, 40, 39, 40, 41, 41, 39, 39,
+    40, 42, 47, 50, 47, 45, 46, 46,
+    44, 45, 46, 47, 49, 54, 58, 54,
+    48, 49, 54, 57, 60, 62, 63, 63,
 };
 
 static const uint8_t dnxhd_1250_chroma_weight[] = {
-     0, 32, 35, 36, 40, 42, 51, 51,
-    35, 36, 39, 39, 43, 51, 52, 55,
-    36, 41, 41, 43, 51, 53, 54, 56,
-    43, 44, 45, 50, 54, 54, 55, 57,
-    45, 48, 50, 51, 55, 58, 59, 58,
-    49, 52, 49, 57, 58, 62, 58, 60,
-    51, 51, 56, 58, 62, 61, 59, 62,
-    52, 52, 60, 61, 59, 59, 63, 63
+     0, 32, 35, 36, 36, 35, 36, 39,
+    41, 43, 45, 44, 41, 39, 40, 42,
+    43, 43, 45, 48, 49, 51, 52, 50,
+    50, 51, 51, 51, 51, 52, 53, 54,
+    51, 49, 51, 52, 52, 56, 57, 55,
+    54, 54, 55, 56, 55, 58, 58, 58,
+    60, 61, 62, 62, 59, 57, 58, 58,
+    61, 59, 59, 59, 60, 62, 63, 63,
 };
 
 static const uint8_t dnxhd_1251_luma_weight[] = {
@@ -285,63 +287,43 @@
 };
 
 static const uint8_t dnxhd_1237_ac_level[257] = {
-     1,  1,  2,  0,  3,  4,  2,  5,  6,  7,  3,  8,  9, 10, 11, 12,
-     4,  5, 13, 14, 15, 16,  6, 17, 18, 19, 20, 21,  7, 22, 23, 24,
-    25, 26, 27,  8,  9, 28, 29, 30, 31, 32, 33, 34, 10, 11, 12, 35,
-    36, 37, 38, 39, 40, 41, 13, 14, 15, 16, 42, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 17, 18, 19, 20, 21, 53, 54, 55, 56, 57, 58,
-    59, 60, 61, 64,  1, 22, 23, 24, 25, 26, 27, 62, 63,  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, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
-    53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 28, 29, 30, 31,
-    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    64,  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, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    64,
+      3,  3,  5,  0,  7,  9,  5, 11, 13, 15,  7, 17, 19, 21, 23, 25,
+      9, 11, 27, 29, 31, 33, 13, 35, 37, 39, 41, 43, 15, 45, 47, 49,
+     51, 53, 55, 17, 19, 57, 59, 61, 63, 65, 67, 69, 21, 23, 25, 71,
+     73, 75, 77, 79, 81, 83, 27, 29, 31, 33, 85, 87, 89, 91, 93, 95,
+     97, 99,101,103,105, 35, 37, 39, 41, 43,107,109,111,113,115,117,
+    119,121,123,129,  3, 45, 47, 49, 51, 53, 55,125,127,  5,  7,  9,
+     11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41,
+     43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73,
+     75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99,101,103,105,
+    107,109,111,113,115,117,119,121,123,125,127,129, 57, 59, 61, 63,
+     65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95,
+     97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127,
+    129,  3,  5,  7,  9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31,
+     33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63,
+     65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95,
+     97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127,
+    129,
 };
 
-static const uint8_t dnxhd_1237_ac_run_flag[257] = {
-    0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-    1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0,
-    0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
-    0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+static const uint8_t dnxhd_1237_ac_flags[257] = {
+    0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0,
+    2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+    0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0,
+    0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 0, 0, 1, 1, 1,
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1,
-};
-
-static const uint8_t dnxhd_1237_ac_index_flag[257] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 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, 2, 2, 2,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3,
 };
 
 static const uint16_t dnxhd_1237_run_codes[62] = {
@@ -434,63 +416,43 @@
 };
 
 static const uint8_t dnxhd_1238_ac_level[257] = {
-     1,  1,  2,  3,  0,  4,  5,  2,  6,  7,  8,  3,  9, 10, 11,  4,
-    12, 13, 14, 15, 16,  5, 17, 18, 19, 20, 21, 22,  6,  7, 23, 24,
-    25, 26, 27, 28, 29,  8,  9, 30, 31, 32, 33, 34, 35, 36, 37, 10,
-    11, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 12, 13, 14, 49,
-    50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 15, 16, 17, 18,
-    62, 63, 64,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13,
-    14, 15, 16, 19, 20, 21, 22, 23, 24, 17, 18, 19, 20, 21, 22, 23,
-    24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 40, 25,
-    26, 27, 28, 29, 30, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49,
-    50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 31,
-    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    64,  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, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    64,
+      3,  3,  5,  7,  0,  9, 11,  5, 13, 15, 17,  7, 19, 21, 23,  9,
+     25, 27, 29, 31, 33, 11, 35, 37, 39, 41, 43, 45, 13, 15, 47, 49,
+     51, 53, 55, 57, 59, 17, 19, 61, 63, 65, 67, 69, 71, 73, 75, 21,
+     23, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 25, 27, 29, 99,
+    101,103,105,107,109,111,113,115,117,119,121,123, 31, 33, 35, 37,
+    125,127,129,  3,  5,  7,  9, 11, 13, 15, 17, 19, 21, 23, 25, 27,
+     29, 31, 33, 39, 41, 43, 45, 47, 49, 35, 37, 39, 41, 43, 45, 47,
+     49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 81, 51,
+     53, 55, 57, 59, 61, 77, 79, 83, 85, 87, 89, 91, 93, 95, 97, 99,
+    101,103,105,107,109,111,113,115,117,119,121,123,125,127,129, 63,
+     65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95,
+     97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127,
+    129,  3,  5,  7,  9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31,
+     33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63,
+     65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95,
+     97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127,
+    129,
 }; /* 0 is EOB */
 
-static const uint8_t dnxhd_1238_ac_run_flag[257] = {
-    0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
-    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,
-    0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
-    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
-    1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1,
-};
-
-static const uint8_t dnxhd_1238_ac_index_flag[257] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+static const uint8_t dnxhd_1238_ac_flags[257] = {
+    0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2,
+    0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0,
+    0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2,
+    2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2,
     0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
-    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+    2, 2, 2, 2, 2, 1, 1, 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,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3,
 };
 
 static const uint16_t dnxhd_1235_1238_1241_run_codes[62] = {
@@ -583,63 +545,43 @@
 };
 
 static const uint8_t dnxhd_1235_1241_ac_level[257] = {
-     1,  1,  2,  3,  0,  4,  5,  2,  6,  7,  8,  3,  9, 10, 11,  4,
-    12, 13, 14, 15, 16,  5, 17, 18, 19, 20, 21,  6,  7, 22, 23, 24,
-    25, 26, 27, 28, 29,  8,  9, 30, 31, 32, 33, 34, 35, 36, 37, 38,
-    10, 11, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 12, 13,
-    14, 15, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,  1,
-    16, 17, 18, 19, 64,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12,
-    13, 14, 15, 16, 17, 20, 21, 22, 23, 24, 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, 25, 26, 27, 28, 29, 30, 31, 32, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    64, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    64,  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, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    64,
+      3,  3,  5,  7,  0,  9, 11,  5, 13, 15, 17,  7, 19, 21, 23,  9,
+     25, 27, 29, 31, 33, 11, 35, 37, 39, 41, 43, 13, 15, 45, 47, 49,
+     51, 53, 55, 57, 59, 17, 19, 61, 63, 65, 67, 69, 71, 73, 75, 77,
+     21, 23, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99,101, 25, 27,
+     29, 31,103,105,107,109,111,113,115,117,119,121,123,125,127,  3,
+     33, 35, 37, 39,129,  5,  7,  9, 11, 13, 15, 17, 19, 21, 23, 25,
+     27, 29, 31, 33, 35, 41, 43, 45, 47, 49, 37, 39, 41, 43, 45, 47,
+     49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79,
+     81, 83, 85, 51, 53, 55, 57, 59, 61, 63, 65, 87, 89, 91, 93, 95,
+     97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127,
+    129, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95,
+     97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127,
+    129,  3,  5,  7,  9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31,
+     33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63,
+     65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95,
+     97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127,
+    129,
 };
 
-static const uint8_t dnxhd_1235_1241_ac_run_flag[257] = {
-    0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
-    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0,
-    0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
-    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+static const uint8_t dnxhd_1235_1241_ac_flags[257] = {
+    0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2,
+    0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0,
+    0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2,
+    2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+    2, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 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, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1,
-};
-
-static const uint8_t dnxhd_1235_1241_ac_index_flag[257] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
-    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 2, 2, 2, 2, 2, 2, 2, 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, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3,
 };
 
 static const uint8_t dnxhd_1235_1241_run[62] = {
@@ -710,61 +652,42 @@
     16
 };
 static const uint8_t dnxhd_1250_ac_level[257] = {
-     1,  1,  2,  3,  0,  4,  5,  2,  6,  7,  8,  3,  9, 10, 11,  4,
-    12, 13, 14, 15, 16,  5, 17, 18, 19, 20, 21, 22,  6, 23, 24, 25,
-    26, 27, 28, 29,  7,  8, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
-     9, 10, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 11,
-    12, 13, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,  1,  2,
-     3,  4,  5, 14, 15, 16, 17,  6,  7,  8,  9, 10, 11, 12, 13, 14,
-    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 18, 19, 20, 21,
-    27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
-    43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 55, 56, 22, 23, 24,
-    25, 26, 27, 54, 57, 58, 59, 60, 61, 62, 63, 64, 28, 29, 30, 31,
-    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    64,  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, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    64
+      3,  3,  5,  7,  0,  9, 11,  5, 13, 15, 17,  7, 19, 21, 23,  9,
+     25, 27, 29, 31, 33, 11, 35, 37, 39, 41, 43, 45, 13, 47, 49, 51,
+     53, 55, 57, 59, 15, 17, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79,
+     19, 21, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99,101,103,105, 23,
+     25, 27,107,109,111,113,115,117,119,121,123,125,127,129,  3,  5,
+      7,  9, 11, 29, 31, 33, 35, 13, 15, 17, 19, 21, 23, 25, 27, 29,
+     31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 37, 39, 41, 43,
+     55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85,
+     87, 89, 91, 93, 95, 97, 99,101,103,105,107,111,113, 45, 47, 49,
+     51, 53, 55,109,115,117,119,121,123,125,127,129, 57, 59, 61, 63,
+     65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95,
+     97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127,
+    129,  3,  5,  7,  9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31,
+     33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63,
+     65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95,
+     97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127,
+    129
 };
-static const uint8_t dnxhd_1250_ac_run_flag[257] = {
-    0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
-    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
-    0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
-    1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
-    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+static const uint8_t dnxhd_1250_ac_flags[257] = {
+    0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2,
+    0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
+    0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
+    2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+    1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1
-};
-static const uint8_t dnxhd_1250_ac_index_flag[257] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
-    1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
-    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 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, 2, 2,
+    2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3,
 };
 static const uint16_t dnxhd_1250_run_codes[62] = {
        0,    4,    5,   12,   26,   27,   28,   58,
@@ -854,63 +777,43 @@
 };
 
 static const uint8_t dnxhd_1251_ac_level[257] = {
-     1,  1,  2,  3,  0,  4,  5,  2,  6,  7,  8,  3,  9, 10, 11,  4,
-    12, 13, 14, 15, 16,  5, 17, 18, 19, 20, 21,  6, 22, 23, 24, 25,
-    26, 27, 28, 29,  7,  8, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
-    40,  9, 10, 11, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
-    12, 13, 14, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,  1,
-     2,  3,  4,  5,  6,  7,  8, 15, 16, 17,  9, 10, 11, 12, 13, 14,
-    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 18,
-    19, 20, 21, 22, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
-    42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
-    58, 23, 24, 25, 26, 27, 28, 59, 60, 61, 62, 63, 64, 29, 30, 31,
-    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    64,  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, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    64,
+      3,  3,  5,  7,  0,  9, 11,  5, 13, 15, 17,  7, 19, 21, 23,  9,
+     25, 27, 29, 31, 33, 11, 35, 37, 39, 41, 43, 13, 45, 47, 49, 51,
+     53, 55, 57, 59, 15, 17, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79,
+     81, 19, 21, 23, 83, 85, 87, 89, 91, 93, 95, 97, 99,101,103,105,
+     25, 27, 29,107,109,111,113,115,117,119,121,123,125,127,129,  3,
+      5,  7,  9, 11, 13, 15, 17, 31, 33, 35, 19, 21, 23, 25, 27, 29,
+     31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 37,
+     39, 41, 43, 45, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83,
+     85, 87, 89, 91, 93, 95, 97, 99,101,103,105,107,109,111,113,115,
+    117, 47, 49, 51, 53, 55, 57,119,121,123,125,127,129, 59, 61, 63,
+     65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95,
+     97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127,
+    129,  3,  5,  7,  9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31,
+     33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63,
+     65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95,
+     97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127,
+    129,
 };
 
-static const uint8_t dnxhd_1251_ac_run_flag[257] = {
-    0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
-    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
-    0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
-    1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1,
+static const uint8_t dnxhd_1251_ac_flags[257] = {
+    0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2,
+    0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0,
+    0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+    1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+    2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1,
-};
-
-static const uint8_t dnxhd_1251_ac_index_flag[257] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
-    1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
-    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3,
 };
 
 static const uint16_t dnxhd_1251_run_codes[62] = {
@@ -1003,134 +906,114 @@
 };
 
 static const uint8_t dnxhd_1252_ac_level[257] = {
-     1,  1,  2,  3,  2,  0,  4,  5,  6,  7,  3,  8,  9, 10, 11, 12,
-    13, 14,  4,  5, 15, 16, 17, 18,  6, 19, 20, 21, 22, 23, 24,  7,
-     8, 25, 26, 27, 28, 29, 30, 31, 32,  9, 10, 33, 34, 35, 36, 37,
-    38, 39, 40, 41, 11, 12, 13, 42, 43, 44, 45, 46, 47, 48, 49, 50,
-    51, 52, 53, 14, 15, 16, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    64,  1,  2,  3, 17, 18, 19, 20,  4,  5,  6,  7,  8,  9, 10, 11,
-    12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 25, 22,
-    23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
-    39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
-    55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 26, 27, 28, 29, 30, 31,
-    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    64,  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, 43, 44, 45, 46, 47,
-    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
-    64,
+      3,  3,  5,  7,  5,  0,  9, 11, 13, 15,  7, 17, 19, 21, 23, 25,
+     27, 29,  9, 11, 31, 33, 35, 37, 13, 39, 41, 43, 45, 47, 49, 15,
+     17, 51, 53, 55, 57, 59, 61, 63, 65, 19, 21, 67, 69, 71, 73, 75,
+     77, 79, 81, 83, 23, 25, 27, 85, 87, 89, 91, 93, 95, 97, 99,101,
+    103,105,107, 29, 31, 33,109,111,113,115,117,119,121,123,125,127,
+    129,  3,  5,  7, 35, 37, 39, 41,  9, 11, 13, 15, 17, 19, 21, 23,
+     25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 43, 45, 47, 49, 51, 45,
+     47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77,
+     79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99,101,103,105,107,109,
+    111,113,115,117,119,121,123,125,127,129, 53, 55, 57, 59, 61, 63,
+     65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95,
+     97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127,
+    129,  3,  5,  7,  9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31,
+     33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63,
+     65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95,
+     97, 99,101,103,105,107,109,111,113,115,117,119,121,123,125,127,
+    129,
 };
 
-static const uint8_t dnxhd_1252_ac_run_flag[257] = {
-    0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
-    0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,
-    1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
+static const uint8_t dnxhd_1252_ac_flags[257] = {
+    0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
+    0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2,
+    2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1,
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1,
-};
-
-static const uint8_t dnxhd_1252_ac_index_flag[257] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-    1, 1, 1, 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, 2, 2, 2, 2, 2,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3,
 };
 
 const CIDEntry ff_dnxhd_cid_table[] = {
-    { 1235, 1920, 1080, 0, 917504, 917504, 6, 10,
+    { 1235, 1920, 1080, 0, 917504, 917504, 6, 10, 4,
       dnxhd_1235_luma_weight, dnxhd_1235_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_run_flag, dnxhd_1235_1241_ac_index_flag,
+      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 } },
-    { 1237, 1920, 1080, 0, 606208, 606208, 4, 8,
+    { 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_run_flag, dnxhd_1237_ac_index_flag,
+      dnxhd_1237_ac_flags,
       dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run,
       { 115, 120, 145, 240, 290 } },
-    { 1238, 1920, 1080, 0, 917504, 917504, 4, 8,
+    { 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_run_flag, dnxhd_1238_ac_index_flag,
+      dnxhd_1238_ac_flags,
       dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1238_run,
       { 175, 185, 220, 365, 440 } },
-    { 1241, 1920, 1080, 1, 917504, 458752, 6, 10,
+    { 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_run_flag, dnxhd_1235_1241_ac_index_flag,
+      dnxhd_1235_1241_ac_flags,
       dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1235_1241_run,
       { 185, 220 } },
-    { 1242, 1920, 1080, 1, 606208, 303104, 4, 8,
+    { 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_run_flag, dnxhd_1237_ac_index_flag,
+      dnxhd_1237_ac_flags,
       dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run,
       { 120, 145 } },
-    { 1243, 1920, 1080, 1, 917504, 458752, 4, 8,
+    { 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_run_flag, dnxhd_1238_ac_index_flag,
+      dnxhd_1238_ac_flags,
       dnxhd_1235_1238_1241_run_codes, dnxhd_1235_1238_1241_run_bits, dnxhd_1238_run,
       { 185, 220 } },
-    { 1250, 1280,  720, 0, 458752, 458752, 6, 10,
+    { 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_run_flag, dnxhd_1250_ac_index_flag,
+      dnxhd_1250_ac_flags,
       dnxhd_1250_run_codes, dnxhd_1250_run_bits, dnxhd_1250_run,
       { 90, 180, 220 } },
-    { 1251, 1280,  720, 0, 458752, 458752, 4, 8,
+    { 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_run_flag, dnxhd_1251_ac_index_flag,
+      dnxhd_1251_ac_flags,
       dnxhd_1251_run_codes, dnxhd_1251_run_bits, dnxhd_1251_run,
       { 90, 110, 175, 220 } },
-    { 1252, 1280,  720, 0, 303104, 303104, 4, 8,
+    { 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_run_flag, dnxhd_1252_ac_index_flag,
+      dnxhd_1252_ac_flags,
       dnxhd_1251_run_codes, dnxhd_1251_run_bits, dnxhd_1251_run,
       { 60, 75, 115, 145 } },
-    { 1253, 1920, 1080, 0, 188416, 188416, 4, 8,
+    { 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_run_flag, dnxhd_1237_ac_index_flag,
+      dnxhd_1237_ac_flags,
       dnxhd_1237_run_codes, dnxhd_1237_run_bits, dnxhd_1237_run,
       { 36, 45, 75, 90 } },
 };
diff --git a/libavcodec/dnxhddata.h b/libavcodec/dnxhddata.h
index 66b0349..6ebee3d 100644
--- a/libavcodec/dnxhddata.h
+++ b/libavcodec/dnxhddata.h
@@ -2,20 +2,20 @@
  * VC3/DNxHD decoder.
  * Copyright (c) 2007 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -33,11 +33,12 @@
     unsigned int coding_unit_size;
     int index_bits;
     int bit_depth;
+    int eob_index;
     const uint8_t *luma_weight, *chroma_weight;
     const uint8_t *dc_codes, *dc_bits;
     const uint16_t *ac_codes;
     const uint8_t *ac_bits, *ac_level;
-    const uint8_t *ac_run_flag, *ac_index_flag;
+    const uint8_t *ac_flags;
     const uint16_t *run_codes;
     const uint8_t *run_bits, *run;
     int bit_rates[5]; ///< Helpher to choose variants, rounded to nearest 5Mb/s
diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c
index e71409b..4f3968a 100644
--- a/libavcodec/dnxhddec.c
+++ b/libavcodec/dnxhddec.c
@@ -5,20 +5,20 @@
  *
  * 10 bit support added by MirriAd Ltd, Joseph Artsimovich <joseph@mirriad.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,6 +30,7 @@
 #include "get_bits.h"
 #include "dnxhddata.h"
 #include "dsputil.h"
+#include "thread.h"
 
 typedef struct DNXHDContext {
     AVCodecContext *avctx;
@@ -49,6 +50,9 @@
     int bit_depth; // 8, 10 or 0 if not initialized at all.
     void (*decode_dct_block)(struct DNXHDContext *ctx, DCTELEM *block,
                              int n, int qscale);
+    int last_qscale;
+    int luma_scale[64];
+    int chroma_scale[64];
 } DNXHDContext;
 
 #define DNXHD_VLC_BITS 9
@@ -63,6 +67,7 @@
 
     ctx->avctx = avctx;
     avctx->coded_frame = &ctx->picture;
+    avcodec_get_frame_defaults(&ctx->picture);
     ctx->picture.type = AV_PICTURE_TYPE_I;
     ctx->picture.key_frame = 1;
     return 0;
@@ -77,6 +82,10 @@
             av_log(ctx->avctx, AV_LOG_ERROR, "unsupported cid %d\n", cid);
             return -1;
         }
+        if (ff_dnxhd_cid_table[index].bit_depth != ctx->bit_depth) {
+            av_log(ctx->avctx, AV_LOG_ERROR, "bit depth mismatches %d %d\n", ff_dnxhd_cid_table[index].bit_depth, ctx->bit_depth);
+            return AVERROR_INVALIDDATA;
+        }
         ctx->cid_table = &ff_dnxhd_cid_table[index];
 
         ff_free_vlc(&ctx->ac_vlc);
@@ -185,16 +194,22 @@
                                                     int level_bias,
                                                     int level_shift)
 {
-    int i, j, index1, index2, len;
+    int i, j, index1, index2, len, flags;
     int level, component, sign;
+    const int *scale;
     const uint8_t *weight_matrix;
+    const uint8_t *ac_level = ctx->cid_table->ac_level;
+    const uint8_t *ac_flags = ctx->cid_table->ac_flags;
+    const int eob_index     = ctx->cid_table->eob_index;
     OPEN_READER(bs, &ctx->gb);
 
     if (n&2) {
         component = 1 + (n&1);
+        scale = ctx->chroma_scale;
         weight_matrix = ctx->cid_table->chroma_weight;
     } else {
         component = 0;
+        scale = ctx->luma_scale;
         weight_matrix = ctx->cid_table->luma_weight;
     }
 
@@ -209,41 +224,47 @@
     }
     block[0] = ctx->last_dc[component];
 
-    for (i = 1; ; i++) {
-        UPDATE_CACHE(bs, &ctx->gb);
-        GET_VLC(index1, bs, &ctx->gb, ctx->ac_vlc.table,
-                DNXHD_VLC_BITS, 2);
-        level = ctx->cid_table->ac_level[index1];
-        if (!level) /* EOB */
-            break;
+    i = 0;
+
+    UPDATE_CACHE(bs, &ctx->gb);
+    GET_VLC(index1, bs, &ctx->gb, ctx->ac_vlc.table,
+            DNXHD_VLC_BITS, 2);
+
+    while (index1 != eob_index) {
+        level = ac_level[index1];
+        flags = ac_flags[index1];
 
         sign = SHOW_SBITS(bs, &ctx->gb, 1);
         SKIP_BITS(bs, &ctx->gb, 1);
 
-        if (ctx->cid_table->ac_index_flag[index1]) {
-            level += SHOW_UBITS(bs, &ctx->gb, index_bits) << 6;
+        if (flags & 1) {
+            level += SHOW_UBITS(bs, &ctx->gb, index_bits) << 7;
             SKIP_BITS(bs, &ctx->gb, index_bits);
         }
 
-        if (ctx->cid_table->ac_run_flag[index1]) {
+        if (flags & 2) {
             UPDATE_CACHE(bs, &ctx->gb);
             GET_VLC(index2, bs, &ctx->gb, ctx->run_vlc.table,
                     DNXHD_VLC_BITS, 2);
             i += ctx->cid_table->run[index2];
         }
 
-        if (i > 63) {
+        if (++i > 63) {
             av_log(ctx->avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", n, i);
             break;
         }
 
         j = ctx->scantable.permutated[i];
-        level = (2*level+1) * qscale * weight_matrix[i];
+        level *= scale[i];
         if (level_bias < 32 || weight_matrix[i] != level_bias)
             level += level_bias;
         level >>= level_shift;
 
         block[j] = (level^sign) - sign;
+
+        UPDATE_CACHE(bs, &ctx->gb);
+        GET_VLC(index1, bs, &ctx->gb, ctx->ac_vlc.table,
+                DNXHD_VLC_BITS, 2);
     }
 
     CLOSE_READER(bs, &ctx->gb);
@@ -273,6 +294,14 @@
     qscale = get_bits(&ctx->gb, 11);
     skip_bits1(&ctx->gb);
 
+    if (qscale != ctx->last_qscale) {
+        for (i = 0; i < 64; i++) {
+            ctx->luma_scale[i]   = qscale * ctx->cid_table->luma_weight[i];
+            ctx->chroma_scale[i] = qscale * ctx->cid_table->chroma_weight[i];
+        }
+        ctx->last_qscale = qscale;
+    }
+
     for (i = 0; i < 8; i++) {
         ctx->dsp.clear_block(ctx->blocks[i]);
         ctx->decode_dct_block(ctx, ctx->blocks[i], i, qscale);
@@ -336,6 +365,7 @@
     DNXHDContext *ctx = avctx->priv_data;
     AVFrame *picture = data;
     int first_field = 1;
+    int ret;
 
     av_dlog(avctx, "frame size %d\n", buf_size);
 
@@ -356,10 +386,10 @@
 
     if (first_field) {
         if (ctx->picture.data[0])
-            avctx->release_buffer(avctx, &ctx->picture);
-        if (avctx->get_buffer(avctx, &ctx->picture) < 0) {
+            ff_thread_release_buffer(avctx, &ctx->picture);
+        if ((ret = ff_thread_get_buffer(avctx, &ctx->picture)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-            return -1;
+            return ret;
         }
     }
 
@@ -382,7 +412,7 @@
     DNXHDContext *ctx = avctx->priv_data;
 
     if (ctx->picture.data[0])
-        avctx->release_buffer(avctx, &ctx->picture);
+        ff_thread_release_buffer(avctx, &ctx->picture);
     ff_free_vlc(&ctx->ac_vlc);
     ff_free_vlc(&ctx->dc_vlc);
     ff_free_vlc(&ctx->run_vlc);
@@ -397,6 +427,6 @@
     .init           = dnxhd_decode_init,
     .close          = dnxhd_decode_close,
     .decode         = dnxhd_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
     .long_name      = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
 };
diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c
index 8531fe0..b5d62bf 100644
--- a/libavcodec/dnxhdenc.c
+++ b/libavcodec/dnxhdenc.c
@@ -6,20 +6,20 @@
  * VC-3 encoder funded by the British Broadcasting Corporation
  * 10 bit support added by MirriAd Ltd, Joseph Artsimovich <joseph@mirriad.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -32,6 +32,7 @@
 #include "internal.h"
 #include "mpegvideo.h"
 #include "dnxhdenc.h"
+#include "internal.h"
 
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 #define DNX10BIT_QMAT_SHIFT 18 // The largest value that will not lead to overflow for 10bit samples.
@@ -40,11 +41,17 @@
     {"nitris_compat", "encode with Avid Nitris compatibility", offsetof(DNXHDEncContext, nitris_compat), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, VE},
 {NULL}
 };
-static const AVClass class = { "dnxhd", av_default_item_name, options, LIBAVUTIL_VERSION_INT };
+
+static const AVClass class = {
+    .class_name = "dnxhd",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
 
 #define LAMBDA_FRAC_BITS 10
 
-static void dnxhd_8bit_get_pixels_8x4_sym(DCTELEM *restrict block, const uint8_t *pixels, int line_size)
+static void dnxhd_8bit_get_pixels_8x4_sym(DCTELEM *av_restrict block, const uint8_t *pixels, int line_size)
 {
     int i;
     for (i = 0; i < 4; i++) {
@@ -61,23 +68,31 @@
     memcpy(block + 24, block - 32, sizeof(*block) * 8);
 }
 
-static av_always_inline void dnxhd_10bit_get_pixels_8x4_sym(DCTELEM *restrict block, const uint8_t *pixels, int line_size)
+static av_always_inline void dnxhd_10bit_get_pixels_8x4_sym(DCTELEM *av_restrict block, const uint8_t *pixels, int line_size)
 {
     int i;
-
-    block += 32;
+    const uint16_t* pixels16 = (const uint16_t*)pixels;
+    line_size >>= 1;
 
     for (i = 0; i < 4; i++) {
-        memcpy(block + i     * 8, pixels + i * line_size, 8 * sizeof(*block));
-        memcpy(block - (i+1) * 8, pixels + i * line_size, 8 * sizeof(*block));
+        block[0] = pixels16[0]; block[1] = pixels16[1];
+        block[2] = pixels16[2]; block[3] = pixels16[3];
+        block[4] = pixels16[4]; block[5] = pixels16[5];
+        block[6] = pixels16[6]; block[7] = pixels16[7];
+        pixels16 += line_size;
+        block += 8;
     }
+    memcpy(block,      block -  8, sizeof(*block) * 8);
+    memcpy(block +  8, block - 16, sizeof(*block) * 8);
+    memcpy(block + 16, block - 24, sizeof(*block) * 8);
+    memcpy(block + 24, block - 32, sizeof(*block) * 8);
 }
 
 static int dnxhd_10bit_dct_quantize(MpegEncContext *ctx, DCTELEM *block,
                                     int n, int qscale, int *overflow)
 {
     const uint8_t *scantable= ctx->intra_scantable.scantable;
-    const int *qmat = ctx->q_intra_matrix[qscale];
+    const int *qmat = n<4 ? ctx->q_intra_matrix[qscale] : ctx->q_chroma_intra_matrix[qscale];
     int last_non_zero = 0;
     int i;
 
@@ -122,10 +137,10 @@
                 alevel -= offset<<6;
             }
             for (j = 0; j < 257; j++) {
-                if (ctx->cid_table->ac_level[j] == alevel &&
-                    (!offset || (ctx->cid_table->ac_index_flag[j] && offset)) &&
-                    (!run    || (ctx->cid_table->ac_run_flag  [j] && run))) {
-                    assert(!ctx->vlc_codes[index]);
+                if (ctx->cid_table->ac_level[j] >> 1 == alevel &&
+                    (!offset || (ctx->cid_table->ac_flags[j] & 1) && offset) &&
+                    (!run    || (ctx->cid_table->ac_flags[j] & 2) && run)) {
+                    av_assert1(!ctx->vlc_codes[index]);
                     if (alevel) {
                         ctx->vlc_codes[index] = (ctx->cid_table->ac_codes[j]<<1)|(sign&1);
                         ctx->vlc_bits [index] = ctx->cid_table->ac_bits[j]+1;
@@ -136,7 +151,7 @@
                     break;
                 }
             }
-            assert(!alevel || j < 257);
+            av_assert0(!alevel || j < 257);
             if (offset) {
                 ctx->vlc_codes[index] = (ctx->vlc_codes[index]<<ctx->cid_table->index_bits)|offset;
                 ctx->vlc_bits [index]+= ctx->cid_table->index_bits;
@@ -145,7 +160,7 @@
     }
     for (i = 0; i < 62; i++) {
         int run = ctx->cid_table->run[i];
-        assert(run < 63);
+        av_assert0(run < 63);
         ctx->run_codes[run] = ctx->cid_table->run_codes[i];
         ctx->run_bits [run] = ctx->cid_table->run_bits[i];
     }
@@ -208,6 +223,11 @@
         }
     }
 
+    ctx->m.q_chroma_intra_matrix16 = ctx->qmatrix_c16;
+    ctx->m.q_chroma_intra_matrix   = ctx->qmatrix_c;
+    ctx->m.q_intra_matrix16        = ctx->qmatrix_l16;
+    ctx->m.q_intra_matrix          = ctx->qmatrix_l;
+
     return 0;
  fail:
     return -1;
@@ -260,8 +280,9 @@
 
     avctx->bits_per_raw_sample = ctx->cid_table->bit_depth;
 
-    ff_dsputil_init(&ctx->m.dsp, avctx);
     ff_dct_common_init(&ctx->m);
+    ff_dct_encode_init(&ctx->m);
+
     if (!ctx->m.dct_quantize)
         ctx->m.dct_quantize = ff_dct_quantize_c;
 
@@ -496,15 +517,8 @@
 
 static av_always_inline int dnxhd_switch_matrix(DNXHDEncContext *ctx, int i)
 {
-    if (i&2) {
-        ctx->m.q_intra_matrix16 = ctx->qmatrix_c16;
-        ctx->m.q_intra_matrix   = ctx->qmatrix_c;
-        return 1 + (i&1);
-    } else {
-        ctx->m.q_intra_matrix16 = ctx->qmatrix_l16;
-        ctx->m.q_intra_matrix   = ctx->qmatrix_l;
-        return 0;
-    }
+    const static uint8_t component[8]={0,0,1,2,0,0,1,2};
+    return component[i];
 }
 
 static int dnxhd_calc_bits_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr)
@@ -534,14 +548,14 @@
             int n = dnxhd_switch_matrix(ctx, i);
 
             memcpy(block, src_block, 64*sizeof(*block));
-            last_index = ctx->m.dct_quantize(&ctx->m, block, i, qscale, &overflow);
+            last_index = ctx->m.dct_quantize(&ctx->m, block, 4&(2*i), qscale, &overflow);
             ac_bits += dnxhd_calc_ac_bits(ctx, block, last_index);
 
             diff = block[0] - ctx->m.last_dc[n];
             if (diff < 0) nbits = av_log2_16bit(-2*diff);
             else          nbits = av_log2_16bit( 2*diff);
 
-            assert(nbits < ctx->cid_table->bit_depth + 4);
+            av_assert1(nbits < ctx->cid_table->bit_depth + 4);
             dc_bits += ctx->cid_table->dc_bits[nbits] + nbits;
 
             ctx->m.last_dc[n] = block[0];
@@ -580,8 +594,7 @@
         for (i = 0; i < 8; i++) {
             DCTELEM *block = ctx->blocks[i];
             int overflow, n = dnxhd_switch_matrix(ctx, i);
-            int last_index = ctx->m.dct_quantize(&ctx->m, block, i,
-                                                 qscale, &overflow);
+            int last_index = ctx->m.dct_quantize(&ctx->m, block, 4&(2*i), qscale, &overflow);
             //START_TIMER;
             dnxhd_encode_block(ctx, block, last_index, n);
             //STOP_TIMER("encode_block");
@@ -810,13 +823,13 @@
             buckets[j][get_bucket(v, 0)]++;
             v >>= BUCKET_BITS;
         }
-        assert(!v);
+        av_assert1(!v);
     }
     for (j = 0; j < RADIX_PASSES; j++) {
         int offset = size;
         for (i = NBUCKETS - 1; i >= 0; i--)
             buckets[j][i] = offset -= buckets[j][i];
-        assert(!buckets[j][0]);
+        av_assert1(!buckets[j][0]);
     }
 }
 
@@ -910,10 +923,8 @@
     int offset, i, ret;
     uint8_t *buf;
 
-    if ((ret = ff_alloc_packet(pkt, ctx->cid_table->frame_size)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "output buffer is too small to compress picture\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, ctx->cid_table->frame_size)) < 0)
         return ret;
-    }
     buf = pkt->data;
 
     dnxhd_load_picture(ctx, frame);
@@ -943,12 +954,12 @@
     for (i = 0; i < ctx->m.mb_height; i++) {
         AV_WB32(ctx->msip + i * 4, offset);
         offset += ctx->slice_size[i];
-        assert(!(ctx->slice_size[i] & 3));
+        av_assert1(!(ctx->slice_size[i] & 3));
     }
 
     avctx->execute2(avctx, dnxhd_encode_thread, buf, NULL, ctx->m.mb_height);
 
-    assert(640 + offset + 4 <= ctx->cid_table->coding_unit_size);
+    av_assert1(640 + offset + 4 <= ctx->cid_table->coding_unit_size);
     memset(buf + 640 + offset, 0, ctx->cid_table->coding_unit_size - 4 - offset - 640);
 
     AV_WB32(buf + ctx->cid_table->coding_unit_size - 4, 0x600DC0DE); // EOF
@@ -996,6 +1007,11 @@
     return 0;
 }
 
+static const AVCodecDefault dnxhd_defaults[] = {
+    { "qmax", "1024" }, /* Maximum quantization scale factor allowed for VC-3 */
+    { NULL },
+};
+
 AVCodec ff_dnxhd_encoder = {
     .name           = "dnxhd",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -1010,4 +1026,5 @@
                                                   AV_PIX_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("VC3/DNxHD"),
     .priv_class     = &class,
+    .defaults       = dnxhd_defaults,
 };
diff --git a/libavcodec/dnxhdenc.h b/libavcodec/dnxhdenc.h
index c74b9a7..36a42fb 100644
--- a/libavcodec/dnxhdenc.h
+++ b/libavcodec/dnxhdenc.h
@@ -4,20 +4,20 @@
  *
  * VC-3 encoder funded by the British Broadcasting Corporation
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -84,8 +84,6 @@
     unsigned qscale;
     unsigned lambda;
 
-    unsigned thread_size;
-
     uint16_t *mb_bits;
     uint8_t  *mb_qscale;
 
diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c
index f9aff98..a7c9bb1 100644
--- a/libavcodec/dpcm.c
+++ b/libavcodec/dpcm.c
@@ -2,20 +2,20 @@
  * Assorted DPCM codecs
  * Copyright (c) 2003 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -209,9 +209,12 @@
         av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
         return AVERROR(EINVAL);
     }
+    if (out % s->channels) {
+        av_log(avctx, AV_LOG_WARNING, "channels have differing number of samples\n");
+    }
 
     /* get output buffer */
-    s->frame.nb_samples = out / s->channels;
+    s->frame.nb_samples = (out + s->channels - 1) / s->channels;
     if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c
index f1a4e86..9b96ed8 100644
--- a/libavcodec/dpx.c
+++ b/libavcodec/dpx.c
@@ -2,20 +2,20 @@
  * DPX (.dpx) image decoder
  * Copyright (c) 2009 Jimmy Christensen
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -41,12 +41,19 @@
     return temp;
 }
 
-static inline unsigned make_16bit(unsigned value)
+static uint16_t read10in32(const uint8_t **ptr, uint32_t * lbuf,
+                                  int * n_datum, int is_big)
 {
-    // mask away invalid bits
-    value &= 0xFFC0;
-    // correctly expand to 16 bits
-    return value + (value >> 10);
+    if (*n_datum)
+        (*n_datum)--;
+    else {
+        *lbuf = read32(ptr, is_big);
+        *n_datum = 2;
+    }
+
+    *lbuf = (*lbuf << 10) | (*lbuf >> 22);
+
+    return *lbuf & 0x3FF;
 }
 
 static int decode_frame(AVCodecContext *avctx,
@@ -55,19 +62,19 @@
                         AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    const uint8_t *buf_end = avpkt->data + avpkt->size;
     int buf_size       = avpkt->size;
     DPXContext *const s = avctx->priv_data;
     AVFrame *picture  = data;
     AVFrame *const p = &s->picture;
-    uint8_t *ptr;
+    uint8_t *ptr[AV_NUM_DATA_POINTERS];
 
     unsigned int offset;
     int magic_num, endian;
-    int x, y;
-    int w, h, stride, bits_per_color, descriptor, elements, target_packet_size, source_packet_size;
+    int x, y, i;
+    int w, h, bits_per_color, descriptor, elements, packing, total_size;
 
-    unsigned int rgbBuffer;
+    unsigned int rgbBuffer = 0;
+    int n_datum = 0;
 
     if (avpkt->size <= 1634) {
         av_log(avctx, AV_LOG_ERROR, "Packet too small for DPX header\n");
@@ -106,10 +113,18 @@
     buf += 3;
     avctx->bits_per_raw_sample =
     bits_per_color = buf[0];
+    buf++;
+    packing = *((uint16_t*)buf);
 
-    buf += 825;
+    buf += 824;
     avctx->sample_aspect_ratio.num = read32(&buf, endian);
     avctx->sample_aspect_ratio.den = read32(&buf, endian);
+    if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0)
+        av_reduce(&avctx->sample_aspect_ratio.num, &avctx->sample_aspect_ratio.den,
+                   avctx->sample_aspect_ratio.num,  avctx->sample_aspect_ratio.den,
+                  0x10000);
+    else
+        avctx->sample_aspect_ratio = (AVRational){ 0, 1 };
 
     switch (descriptor) {
         case 51: // RGBA
@@ -130,23 +145,35 @@
             } else {
                 avctx->pix_fmt = AV_PIX_FMT_RGB24;
             }
-            source_packet_size = elements;
-            target_packet_size = elements;
+            total_size = avctx->width * avctx->height * elements;
             break;
         case 10:
-            avctx->pix_fmt = AV_PIX_FMT_RGB48;
-            target_packet_size = 6;
-            source_packet_size = 4;
+            if (!packing) {
+                av_log(avctx, AV_LOG_ERROR, "Packing to 32bit required\n");
+                return -1;
+            }
+            avctx->pix_fmt = AV_PIX_FMT_GBRP10;
+            total_size = (4 * avctx->width * avctx->height * elements) / 3;
             break;
         case 12:
+            if (!packing) {
+                av_log(avctx, AV_LOG_ERROR, "Packing to 16bit required\n");
+                return -1;
+            }
+            if (endian) {
+                avctx->pix_fmt = AV_PIX_FMT_GBRP12BE;
+            } else {
+                avctx->pix_fmt = AV_PIX_FMT_GBRP12LE;
+            }
+            total_size = 2 * avctx->width * avctx->height * elements;
+            break;
         case 16:
             if (endian) {
-                avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
+                avctx->pix_fmt = elements == 4 ? AV_PIX_FMT_RGBA64BE : AV_PIX_FMT_RGB48BE;
             } else {
-                avctx->pix_fmt = AV_PIX_FMT_RGB48LE;
+                avctx->pix_fmt = elements == 4 ? AV_PIX_FMT_RGBA64LE : AV_PIX_FMT_RGB48LE;
             }
-            target_packet_size = 6;
-            source_packet_size = elements * 2;
+            total_size = 2 * avctx->width * avctx->height * elements;
             break;
         default:
             av_log(avctx, AV_LOG_ERROR, "Unsupported color depth : %d\n", bits_per_color);
@@ -167,48 +194,70 @@
     // Move pointer to offset from start of file
     buf =  avpkt->data + offset;
 
-    ptr    = p->data[0];
-    stride = p->linesize[0];
+    for (i=0; i<AV_NUM_DATA_POINTERS; i++)
+        ptr[i] = p->data[i];
 
-    if (source_packet_size*avctx->width*avctx->height > buf_end - buf) {
+    if (total_size > avpkt->size) {
         av_log(avctx, AV_LOG_ERROR, "Overread buffer. Invalid header?\n");
         return -1;
     }
     switch (bits_per_color) {
-        case 10:
-            for (x = 0; x < avctx->height; x++) {
-               uint16_t *dst = (uint16_t*)ptr;
-               for (y = 0; y < avctx->width; y++) {
-                   rgbBuffer = read32(&buf, endian);
-                   // Read out the 10-bit colors and convert to 16-bit
-                   *dst++ = make_16bit(rgbBuffer >> 16);
-                   *dst++ = make_16bit(rgbBuffer >>  6);
-                   *dst++ = make_16bit(rgbBuffer <<  4);
-               }
-               ptr += stride;
+    case 10:
+        for (x = 0; x < avctx->height; x++) {
+            uint16_t *dst[3] = {(uint16_t*)ptr[0],
+                                (uint16_t*)ptr[1],
+                                (uint16_t*)ptr[2]};
+            for (y = 0; y < avctx->width; y++) {
+                *dst[2]++ = read10in32(&buf, &rgbBuffer,
+                                       &n_datum, endian);
+                *dst[0]++ = read10in32(&buf, &rgbBuffer,
+                                       &n_datum, endian);
+                *dst[1]++ = read10in32(&buf, &rgbBuffer,
+                                       &n_datum, endian);
+                // For 10 bit, ignore alpha
+                if (elements == 4)
+                    read10in32(&buf, &rgbBuffer,
+                               &n_datum, endian);
             }
-            break;
-        case 8:
-        case 12: // Treat 12-bit as 16-bit
-        case 16:
-            if (source_packet_size == target_packet_size) {
-                for (x = 0; x < avctx->height; x++) {
-                    memcpy(ptr, buf, target_packet_size*avctx->width);
-                    ptr += stride;
-                    buf += source_packet_size*avctx->width;
-                }
-            } else {
-                for (x = 0; x < avctx->height; x++) {
-                    uint8_t *dst = ptr;
-                    for (y = 0; y < avctx->width; y++) {
-                        memcpy(dst, buf, target_packet_size);
-                        dst += target_packet_size;
-                        buf += source_packet_size;
-                    }
-                    ptr += stride;
-                }
+            for (i = 0; i < 3; i++)
+                ptr[i] += p->linesize[i];
+        }
+        break;
+    case 12:
+        for (x = 0; x < avctx->height; x++) {
+            uint16_t *dst[3] = {(uint16_t*)ptr[0],
+                                (uint16_t*)ptr[1],
+                                (uint16_t*)ptr[2]};
+            for (y = 0; y < avctx->width; y++) {
+                *dst[2] = *((uint16_t*)buf);
+                *dst[2] = (*dst[2] >> 4) | (*dst[2] << 12);
+                dst[2]++;
+                buf += 2;
+                *dst[0] = *((uint16_t*)buf);
+                *dst[0] = (*dst[0] >> 4) | (*dst[0] << 12);
+                dst[0]++;
+                buf += 2;
+                *dst[1] = *((uint16_t*)buf);
+                *dst[1] = (*dst[1] >> 4) | (*dst[1] << 12);
+                dst[1]++;
+                buf += 2;
+                // For 12 bit, ignore alpha
+                if (elements == 4)
+                    buf += 2;
             }
-            break;
+            for (i = 0; i < 3; i++)
+                ptr[i] += p->linesize[i];
+        }
+        break;
+    case 16:
+        elements *= 2;
+    case 8:
+        for (x = 0; x < avctx->height; x++) {
+            memcpy(ptr[0], buf, elements*avctx->width);
+            ptr[0] += p->linesize[0];
+            buf += elements*avctx->width;
+        }
+        break;
     }
 
     *picture   = s->picture;
@@ -242,5 +291,6 @@
     .init           = decode_init,
     .close          = decode_end,
     .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("DPX image"),
 };
diff --git a/libavcodec/dpxenc.c b/libavcodec/dpxenc.c
index d263161..9b2cc6f 100644
--- a/libavcodec/dpxenc.c
+++ b/libavcodec/dpxenc.c
@@ -2,20 +2,20 @@
  * DPX (.dpx) image encoder
  * Copyright (c) 2011 Peter Ross <pross@xvid.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,6 +30,7 @@
     int big_endian;
     int bits_per_component;
     int descriptor;
+    int planar;
 } DPXContext;
 
 static av_cold int encode_init(AVCodecContext *avctx)
@@ -43,6 +44,7 @@
     s->big_endian         = 1;
     s->bits_per_component = 8;
     s->descriptor         = 50; /* RGB */
+    s->planar             = 0;
 
     switch (avctx->pix_fmt) {
     case AV_PIX_FMT_RGB24:
@@ -55,6 +57,24 @@
     case AV_PIX_FMT_RGB48BE:
         s->bits_per_component = avctx->bits_per_raw_sample ? avctx->bits_per_raw_sample : 16;
         break;
+    case AV_PIX_FMT_RGBA64LE:
+        s->big_endian = 0;
+    case AV_PIX_FMT_RGBA64BE:
+        s->descriptor = 51;
+        s->bits_per_component = 16;
+        break;
+    case AV_PIX_FMT_GBRP10LE:
+        s->big_endian = 0;
+    case AV_PIX_FMT_GBRP10BE:
+        s->bits_per_component = 10;
+        s->planar = 1;
+        break;
+    case AV_PIX_FMT_GBRP12LE:
+        s->big_endian = 0;
+    case AV_PIX_FMT_GBRP12BE:
+        s->bits_per_component = 12;
+        s->planar = 1;
+        break;
     default:
         av_log(avctx, AV_LOG_INFO, "unsupported pixel format\n");
         return -1;
@@ -75,8 +95,7 @@
     else               AV_WL32(p, value); \
 } while(0)
 
-static void encode_rgb48_10bit(AVCodecContext *avctx, const AVPicture *pic,
-                               uint8_t *dst)
+static void encode_rgb48_10bit(AVCodecContext *avctx, const AVPicture *pic, uint8_t *dst)
 {
     DPXContext *s = avctx->priv_data;
     const uint8_t *src = pic->data[0];
@@ -85,7 +104,7 @@
     for (y = 0; y < avctx->height; y++) {
         for (x = 0; x < avctx->width; x++) {
             int value;
-            if ((avctx->pix_fmt & 1)) {
+            if (s->big_endian) {
                 value = ((AV_RB16(src + 6*x + 4) & 0xFFC0) >> 4)
                       | ((AV_RB16(src + 6*x + 2) & 0xFFC0) << 6)
                       | ((AV_RB16(src + 6*x + 0) & 0xFFC0) << 16);
@@ -101,6 +120,59 @@
     }
 }
 
+static void encode_gbrp10(AVCodecContext *avctx, const AVPicture *pic, uint8_t *dst)
+{
+    DPXContext *s = avctx->priv_data;
+    const uint8_t *src[3] = {pic->data[0], pic->data[1], pic->data[2]};
+    int x, y, i;
+
+    for (y = 0; y < avctx->height; y++) {
+        for (x = 0; x < avctx->width; x++) {
+            int value;
+            if (s->big_endian) {
+                value = (AV_RB16(src[0] + 2*x) << 12)
+                      | (AV_RB16(src[1] + 2*x) << 2)
+                      | (AV_RB16(src[2] + 2*x) << 22);
+            } else {
+                value = (AV_RL16(src[0] + 2*x) << 12)
+                      | (AV_RL16(src[1] + 2*x) << 2)
+                      | (AV_RL16(src[2] + 2*x) << 22);
+            }
+            write32(dst, value);
+            dst += 4;
+        }
+        for (i = 0; i < 3; i++)
+            src[i] += pic->linesize[i];
+    }
+}
+
+static void encode_gbrp12(AVCodecContext *avctx, const AVPicture *pic, uint16_t *dst)
+{
+    DPXContext *s = avctx->priv_data;
+    const uint16_t *src[3] = {(uint16_t*)pic->data[0],
+                              (uint16_t*)pic->data[1],
+                              (uint16_t*)pic->data[2]};
+    int x, y, i;
+    for (y = 0; y < avctx->height; y++) {
+        for (x = 0; x < avctx->width; x++) {
+            uint16_t value[3];
+            if (s->big_endian) {
+                value[1] = AV_RB16(src[0] + x) << 4;
+                value[2] = AV_RB16(src[1] + x) << 4;
+                value[0] = AV_RB16(src[2] + x) << 4;
+            } else {
+                value[1] = AV_RL16(src[0] + x) << 4;
+                value[2] = AV_RL16(src[1] + x) << 4;
+                value[0] = AV_RL16(src[2] + x) << 4;
+            }
+            for (i = 0; i < 3; i++)
+                write16(dst++, value[i]);
+        }
+        for (i = 0; i < 3; i++)
+            src[i] += pic->linesize[i]/2;
+    }
+}
+
 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         const AVFrame *frame, int *got_packet)
 {
@@ -113,10 +185,8 @@
         size = avctx->height * avctx->width * 4;
     else
         size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
-    if ((ret = ff_alloc_packet(pkt, size + HEADER_SIZE)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, size + HEADER_SIZE)) < 0)
         return ret;
-    }
     buf = pkt->data;
 
     memset(buf, 0, HEADER_SIZE);
@@ -140,13 +210,14 @@
     buf[801] = 2; /* linear transfer */
     buf[802] = 2; /* linear colorimetric */
     buf[803] = s->bits_per_component;
-    write16(buf + 804, s->bits_per_component == 10 ? 1 : 0); /* packing method */
+    write16(buf + 804, (s->bits_per_component == 10 || s->bits_per_component == 12) ?
+                       1 : 0); /* packing method */
 
     /* Image source information header */
     write32(buf + 1628, avctx->sample_aspect_ratio.num);
     write32(buf + 1632, avctx->sample_aspect_ratio.den);
 
-    switch (s->bits_per_component) {
+    switch(s->bits_per_component) {
     case 8:
     case 16:
         size = avpicture_layout((const AVPicture*)frame, avctx->pix_fmt,
@@ -156,7 +227,13 @@
             return size;
         break;
     case 10:
-        encode_rgb48_10bit(avctx, (const AVPicture*)frame, buf + HEADER_SIZE);
+        if (s->planar)
+            encode_gbrp10(avctx, (const AVPicture*)frame, buf + HEADER_SIZE);
+        else
+            encode_rgb48_10bit(avctx, (const AVPicture*)frame, buf + HEADER_SIZE);
+        break;
+    case 12:
+        encode_gbrp12(avctx, (const AVPicture*)frame, (uint16_t*)(buf + HEADER_SIZE));
         break;
     default:
         av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n", s->bits_per_component);
@@ -185,6 +262,12 @@
         AV_PIX_FMT_RGBA,
         AV_PIX_FMT_RGB48LE,
         AV_PIX_FMT_RGB48BE,
+        AV_PIX_FMT_RGBA64LE,
+        AV_PIX_FMT_RGBA64BE,
+        AV_PIX_FMT_GBRP10LE,
+        AV_PIX_FMT_GBRP10BE,
+        AV_PIX_FMT_GBRP12LE,
+        AV_PIX_FMT_GBRP12BE,
         AV_PIX_FMT_NONE},
     .long_name = NULL_IF_CONFIG_SMALL("DPX image"),
 };
diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c
index 1492717..11afadf 100644
--- a/libavcodec/dsicinav.c
+++ b/libavcodec/dsicinav.c
@@ -2,20 +2,20 @@
  * Delphine Software International CIN Audio/Video Decoders
  * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -95,6 +95,7 @@
     cin->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
+    avcodec_get_frame_defaults(&cin->frame);
     cin->frame.data[0] = NULL;
 
     cin->bitmap_size = avctx->width * avctx->height;
@@ -178,24 +179,29 @@
     return 0;
 }
 
-static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
+static int cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
 {
     int len, code;
     unsigned char *dst_end = dst + dst_size;
     const unsigned char *src_end = src + src_size;
 
-    while (src < src_end && dst < dst_end) {
+    while (src + 1 < src_end && dst < dst_end) {
         code = *src++;
         if (code & 0x80) {
             len = code - 0x7F;
             memset(dst, *src++, FFMIN(len, dst_end - dst));
         } else {
             len = code + 1;
+            if (len > src_end-src) {
+                av_log(0, AV_LOG_ERROR, "RLE overread\n");
+                return AVERROR_INVALIDDATA;
+            }
             memcpy(dst, src, FFMIN(len, dst_end - dst));
             src += len;
         }
         dst += len;
     }
+    return 0;
 }
 
 static int cinvideo_decode_frame(AVCodecContext *avctx,
@@ -221,12 +227,12 @@
         if (palette_colors_count > 256)
             return AVERROR_INVALIDDATA;
         for (i = 0; i < palette_colors_count; ++i) {
-            cin->palette[i] = bytestream_get_le24(&buf);
+            cin->palette[i] = 0xFFU << 24 | bytestream_get_le24(&buf);
             bitmap_frame_size -= 3;
         }
     } else {
         for (i = 0; i < palette_colors_count; ++i) {
-            cin->palette[buf[0]] = AV_RL24(buf+1);
+            cin->palette[buf[0]] = 0xFFU << 24 | AV_RL24(buf+1);
             buf += 4;
             bitmap_frame_size -= 4;
         }
diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c
index cdd4b73..ec1f6dd 100644
--- a/libavcodec/dsputil.c
+++ b/libavcodec/dsputil.c
@@ -5,20 +5,20 @@
  *
  * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -37,10 +37,12 @@
 #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
@@ -49,8 +51,21 @@
 #include "dsputil_template.c"
 #undef BIT_DEPTH
 
+#undef pixeltmp
+#define pixeltmp int32_t
+#define BIT_DEPTH 12
+#include "dsputil_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 14
+#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)
@@ -337,7 +352,7 @@
     return s;
 }
 
-static void diff_pixels_c(DCTELEM *restrict block, const uint8_t *s1,
+static void diff_pixels_c(DCTELEM *av_restrict block, const uint8_t *s1,
                           const uint8_t *s2, int stride){
     int i;
 
@@ -358,7 +373,7 @@
 }
 
 
-static void put_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels,
+static void put_pixels_clamped_c(const DCTELEM *block, uint8_t *av_restrict pixels,
                                  int line_size)
 {
     int i;
@@ -379,8 +394,40 @@
     }
 }
 
+static void put_pixels_clamped4_c(const DCTELEM *block, uint8_t *av_restrict pixels,
+                                 int line_size)
+{
+    int i;
+
+    /* read the pixels */
+    for(i=0;i<4;i++) {
+        pixels[0] = av_clip_uint8(block[0]);
+        pixels[1] = av_clip_uint8(block[1]);
+        pixels[2] = av_clip_uint8(block[2]);
+        pixels[3] = av_clip_uint8(block[3]);
+
+        pixels += line_size;
+        block += 8;
+    }
+}
+
+static void put_pixels_clamped2_c(const DCTELEM *block, uint8_t *av_restrict pixels,
+                                 int line_size)
+{
+    int i;
+
+    /* read the pixels */
+    for(i=0;i<2;i++) {
+        pixels[0] = av_clip_uint8(block[0]);
+        pixels[1] = av_clip_uint8(block[1]);
+
+        pixels += line_size;
+        block += 8;
+    }
+}
+
 static void put_signed_pixels_clamped_c(const DCTELEM *block,
-                                        uint8_t *restrict pixels,
+                                        uint8_t *av_restrict pixels,
                                         int line_size)
 {
     int i, j;
@@ -400,7 +447,7 @@
     }
 }
 
-static void add_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels,
+static void add_pixels_clamped_c(const DCTELEM *block, uint8_t *av_restrict pixels,
                                  int line_size)
 {
     int i;
@@ -420,6 +467,36 @@
     }
 }
 
+static void add_pixels_clamped4_c(const DCTELEM *block, uint8_t *av_restrict pixels,
+                          int line_size)
+{
+    int i;
+
+    /* read the pixels */
+    for(i=0;i<4;i++) {
+        pixels[0] = av_clip_uint8(pixels[0] + block[0]);
+        pixels[1] = av_clip_uint8(pixels[1] + block[1]);
+        pixels[2] = av_clip_uint8(pixels[2] + block[2]);
+        pixels[3] = av_clip_uint8(pixels[3] + block[3]);
+        pixels += line_size;
+        block += 8;
+    }
+}
+
+static void add_pixels_clamped2_c(const DCTELEM *block, uint8_t *av_restrict pixels,
+                          int line_size)
+{
+    int i;
+
+    /* read the pixels */
+    for(i=0;i<2;i++) {
+        pixels[0] = av_clip_uint8(pixels[0] + block[0]);
+        pixels[1] = av_clip_uint8(pixels[1] + block[1]);
+        pixels += line_size;
+        block += 8;
+    }
+}
+
 static int sum_abs_dctelem_c(DCTELEM *block)
 {
     int sum=0, i;
@@ -1256,6 +1333,51 @@
 }
 #endif /* CONFIG_RV40_DECODER */
 
+#if CONFIG_DIRAC_DECODER
+#define DIRAC_MC(OPNAME)\
+void ff_ ## OPNAME ## _dirac_pixels8_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
+{\
+     OPNAME ## _pixels8_8_c(dst, src[0], stride, h);\
+}\
+void ff_ ## OPNAME ## _dirac_pixels16_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
+{\
+    OPNAME ## _pixels16_8_c(dst, src[0], stride, h);\
+}\
+void ff_ ## OPNAME ## _dirac_pixels32_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
+{\
+    OPNAME ## _pixels16_8_c(dst   , src[0]   , stride, h);\
+    OPNAME ## _pixels16_8_c(dst+16, src[0]+16, stride, h);\
+}\
+void ff_ ## OPNAME ## _dirac_pixels8_l2_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
+{\
+    OPNAME ## _pixels8_l2_8(dst, src[0], src[1], stride, stride, stride, h);\
+}\
+void ff_ ## OPNAME ## _dirac_pixels16_l2_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
+{\
+    OPNAME ## _pixels16_l2_8(dst, src[0], src[1], stride, stride, stride, h);\
+}\
+void ff_ ## OPNAME ## _dirac_pixels32_l2_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
+{\
+    OPNAME ## _pixels16_l2_8(dst   , src[0]   , src[1]   , stride, stride, stride, h);\
+    OPNAME ## _pixels16_l2_8(dst+16, src[0]+16, src[1]+16, stride, stride, stride, h);\
+}\
+void ff_ ## OPNAME ## _dirac_pixels8_l4_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
+{\
+    OPNAME ## _pixels8_l4_8(dst, src[0], src[1], src[2], src[3], stride, stride, stride, stride, stride, h);\
+}\
+void ff_ ## OPNAME ## _dirac_pixels16_l4_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
+{\
+    OPNAME ## _pixels16_l4_8(dst, src[0], src[1], src[2], src[3], stride, stride, stride, stride, stride, h);\
+}\
+void ff_ ## OPNAME ## _dirac_pixels32_l4_c(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
+{\
+    OPNAME ## _pixels16_l4_8(dst   , src[0]   , src[1]   , src[2]   , src[3]   , stride, stride, stride, stride, stride, h);\
+    OPNAME ## _pixels16_l4_8(dst+16, src[0]+16, src[1]+16, src[2]+16, src[3]+16, stride, stride, stride, stride, stride, h);\
+}
+DIRAC_MC(put)
+DIRAC_MC(avg)
+#endif
+
 static void wmv2_mspel8_v_lowpass(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int w){
     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
     int i;
@@ -1690,7 +1812,7 @@
         int b= rem[i] + ((basis[i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT));
         int w= weight[i];
         b>>= RECON_SHIFT;
-        assert(-512<b && b<512);
+        av_assert2(-512<b && b<512);
 
         sum += (w*b)*(w*b)>>4;
     }
@@ -1809,7 +1931,7 @@
         dst[i+0] += src[i+0];
 }
 
-static void diff_bytes_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){
+static void diff_bytes_c(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int w){
     long i;
 #if !HAVE_FAST_UNALIGNED
     if((long)src2 & (sizeof(long)-1)){
@@ -1949,7 +2071,7 @@
     int temp[64];
     int sum=0;
 
-    assert(h==8);
+    av_assert2(h==8);
 
     for(i=0; i<8; i++){
         //FIXME try pointer walks
@@ -1994,7 +2116,7 @@
     int temp[64];
     int sum=0;
 
-    assert(h==8);
+    av_assert2(h==8);
 
     for(i=0; i<8; i++){
         //FIXME try pointer walks
@@ -2041,7 +2163,7 @@
     MpegEncContext * const s= (MpegEncContext *)c;
     LOCAL_ALIGNED_16(DCTELEM, temp, [64]);
 
-    assert(h==8);
+    av_assert2(h==8);
 
     s->dsp.diff_pixels(temp, src1, src2, stride);
     s->dsp.fdct(temp);
@@ -2106,7 +2228,7 @@
     LOCAL_ALIGNED_16(DCTELEM, temp, [64]);
     int sum=0, i;
 
-    assert(h==8);
+    av_assert2(h==8);
 
     s->dsp.diff_pixels(temp, src1, src2, stride);
     s->dsp.fdct(temp);
@@ -2123,7 +2245,7 @@
     DCTELEM * const bak = temp+64;
     int sum=0, i;
 
-    assert(h==8);
+    av_assert2(h==8);
     s->mb_intra=0;
 
     s->dsp.diff_pixels(temp, src1, src2, stride);
@@ -2151,7 +2273,7 @@
     uint8_t * length;
     uint8_t * last_length;
 
-    assert(h==8);
+    av_assert2(h==8);
 
     copy_block8(lsrc1, src1, 8, stride, 8);
     copy_block8(lsrc2, src2, 8, stride, 8);
@@ -2193,7 +2315,7 @@
 
         level= temp[i] + 64;
 
-        assert(level - 64);
+        av_assert2(level - 64);
 
         if((level&(~127)) == 0){
             bits+= last_length[UNI_AC_ENC_INDEX(run, level)];
@@ -2225,7 +2347,7 @@
     uint8_t * length;
     uint8_t * last_length;
 
-    assert(h==8);
+    av_assert2(h==8);
 
     s->dsp.diff_pixels(temp, src1, src2, stride);
 
@@ -2264,7 +2386,7 @@
 
         level= temp[i] + 64;
 
-        assert(level - 64);
+        av_assert2(level - 64);
 
         if((level&(~127)) == 0){
             bits+= last_length[UNI_AC_ENC_INDEX(run, level)];
@@ -2400,7 +2522,7 @@
         dst[i] = src[i] * mul;
 }
 
-static void butterflies_float_c(float *restrict v1, float *restrict v2,
+static void butterflies_float_c(float *av_restrict v1, float *av_restrict v2,
                                 int len)
 {
     int i;
@@ -2623,6 +2745,37 @@
     add_pixels_clamped_c(block, dest, line_size);
 }
 
+static void ff_jref_idct4_put(uint8_t *dest, int line_size, DCTELEM *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)
+{
+    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)
+{
+    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)
+{
+    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)
+{
+    dest[0] = av_clip_uint8((block[0] + 4)>>3);
+}
+static void ff_jref_idct1_add(uint8_t *dest, int line_size, DCTELEM *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 */
@@ -2654,7 +2807,7 @@
                 "Compiler did not align stack variables. Libavcodec has been miscompiled\n"
                 "and may be very slow or crash. This is not a bug in libavcodec,\n"
                 "but in the compiler. You may try recompiling using gcc >= 4.2.\n"
-                "Do not report crashes to Libav developers.\n");
+                "Do not report crashes to FFmpeg developers.\n");
 #endif
             did_fail=1;
         }
@@ -2689,12 +2842,28 @@
     }
 #endif //CONFIG_ENCODERS
 
-    if (avctx->bits_per_raw_sample == 10) {
-        c->idct_put              = ff_simple_idct_put_10;
-        c->idct_add              = ff_simple_idct_add_10;
-        c->idct                  = ff_simple_idct_10;
-        c->idct_permutation_type = FF_NO_IDCT_PERM;
-    } else {
+    if(avctx->lowres==1){
+        c->idct_put= ff_jref_idct4_put;
+        c->idct_add= ff_jref_idct4_add;
+        c->idct    = ff_j_rev_dct4;
+        c->idct_permutation_type= FF_NO_IDCT_PERM;
+    }else if(avctx->lowres==2){
+        c->idct_put= ff_jref_idct2_put;
+        c->idct_add= ff_jref_idct2_add;
+        c->idct    = ff_j_rev_dct2;
+        c->idct_permutation_type= FF_NO_IDCT_PERM;
+    }else if(avctx->lowres==3){
+        c->idct_put= ff_jref_idct1_put;
+        c->idct_add= ff_jref_idct1_add;
+        c->idct    = ff_j_rev_dct1;
+        c->idct_permutation_type= FF_NO_IDCT_PERM;
+    }else{
+        if (avctx->bits_per_raw_sample == 10) {
+            c->idct_put              = ff_simple_idct_put_10;
+            c->idct_add              = ff_simple_idct_add_10;
+            c->idct                  = ff_simple_idct_10;
+            c->idct_permutation_type = FF_NO_IDCT_PERM;
+        } else {
         if(avctx->idct_algo==FF_IDCT_INT){
             c->idct_put= ff_jref_idct_put;
             c->idct_add= ff_jref_idct_add;
@@ -2716,6 +2885,7 @@
             c->idct     = ff_simple_idct_8;
             c->idct_permutation_type= FF_NO_IDCT_PERM;
         }
+        }
     }
 
     c->diff_pixels = diff_pixels_c;
@@ -2965,8 +3135,24 @@
             BIT_DEPTH_FUNCS(10, _16);
         }
         break;
+    case 12:
+        if (c->dct_bits == 32) {
+            BIT_DEPTH_FUNCS(12, _32);
+        } else {
+            BIT_DEPTH_FUNCS(12, _16);
+        }
+        break;
+    case 14:
+        if (c->dct_bits == 32) {
+            BIT_DEPTH_FUNCS(14, _32);
+        } else {
+            BIT_DEPTH_FUNCS(14, _16);
+        }
+        break;
     default:
-        BIT_DEPTH_FUNCS(8, _16);
+        if(avctx->bits_per_raw_sample<=8 || avctx->codec_type != AVMEDIA_TYPE_VIDEO) {
+            BIT_DEPTH_FUNCS(8, _16);
+        }
         break;
     }
 
@@ -2979,6 +3165,7 @@
     if (HAVE_MMI)        ff_dsputil_init_mmi   (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++) {
@@ -2994,3 +3181,8 @@
     ff_init_scantable_permutation(c->idct_permutation,
                                   c->idct_permutation_type);
 }
+
+av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx)
+{
+    ff_dsputil_init(c, avctx);
+}
diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h
index da3e758..a1b8861 100644
--- a/libavcodec/dsputil.h
+++ b/libavcodec/dsputil.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -46,6 +46,9 @@
 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);
@@ -69,6 +72,8 @@
 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);
@@ -95,6 +100,8 @@
 PUTAVG_PIXELS( 8)
 PUTAVG_PIXELS( 9)
 PUTAVG_PIXELS(10)
+PUTAVG_PIXELS(12)
+PUTAVG_PIXELS(14)
 
 #define ff_put_pixels8x8_c ff_put_pixels8x8_8_c
 #define ff_avg_pixels8x8_c ff_avg_pixels8x8_8_c
@@ -118,7 +125,7 @@
 /* minimum alignment rules ;)
 If you notice errors in the align stuff, need more alignment for some ASM code
 for some CPU or need to use a function with less aligned data then send a mail
-to the libav-devel mailing list, ...
+to the ffmpeg-devel mailing list, ...
 
 !warning These alignments might not match reality, (missing attribute((align))
 stuff somewhere possible).
@@ -196,6 +203,8 @@
 EMULATED_EDGE(8)
 EMULATED_EDGE(9)
 EMULATED_EDGE(10)
+EMULATED_EDGE(12)
+EMULATED_EDGE(14)
 
 /**
  * DSPContext.
@@ -355,7 +364,7 @@
 
     /* huffyuv specific */
     void (*add_bytes)(uint8_t *dst/*align 16*/, uint8_t *src/*align 16*/, int w);
-    void (*diff_bytes)(uint8_t *dst/*align 16*/, uint8_t *src1/*align 16*/, uint8_t *src2/*align 1*/,int w);
+    void (*diff_bytes)(uint8_t *dst/*align 16*/, const uint8_t *src1/*align 16*/, const uint8_t *src2/*align 1*/,int w);
     /**
      * subtract huffyuv's variant of median prediction
      * note, this might read from src1[-1], src2[-1]
@@ -364,6 +373,7 @@
     void (*add_hfyu_median_prediction)(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int w, int *left, int *left_top);
     int  (*add_hfyu_left_prediction)(uint8_t *dst, const uint8_t *src, int w, int left);
     void (*add_hfyu_left_prediction_bgr32)(uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue, int *alpha);
+    /* this might write to dst[w] */
     void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w);
     void (*bswap16_buf)(uint16_t *dst, const uint16_t *src, int len);
 
@@ -405,7 +415,7 @@
      * @param v2  second input vector, difference output, 16-byte aligned
      * @param len length of vectors, multiple of 4
      */
-    void (*butterflies_float)(float *restrict v1, float *restrict v2, int len);
+    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
@@ -527,6 +537,7 @@
 
 void ff_dsputil_static_init(void);
 void ff_dsputil_init(DSPContext* p, AVCodecContext *avctx);
+attribute_deprecated void dsputil_init(DSPContext* c, AVCodecContext *avctx);
 
 int ff_check_alignment(void);
 
@@ -604,6 +615,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);
 
diff --git a/libavcodec/dsputil_template.c b/libavcodec/dsputil_template.c
index 72ed6bf..0d6e8df 100644
--- a/libavcodec/dsputil_template.c
+++ b/libavcodec/dsputil_template.c
@@ -5,20 +5,20 @@
  *
  * gmc & q-pel & 32/64 bit based MC by Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -79,10 +79,10 @@
 
 /* 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 *_buf, int _wrap, int width, int height, int w, int h, int sides)
+static void FUNCC(draw_edges)(uint8_t *p_buf, int p_wrap, int width, int height, int w, int h, int sides)
 {
-    pixel *buf = (pixel*)_buf;
-    int wrap = _wrap / sizeof(pixel);
+    pixel *buf = (pixel*)p_buf;
+    int wrap = p_wrap / sizeof(pixel);
     pixel *ptr, *last_line;
     int i;
 
@@ -149,8 +149,8 @@
     start_x= FFMAX(0, -src_x);
     end_y= FFMIN(block_h, h-src_y);
     end_x= FFMIN(block_w, w-src_x);
-    assert(start_y < end_y && block_h);
-    assert(start_x < end_x && block_w);
+    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);
@@ -193,12 +193,12 @@
 }
 
 #define DCTELEM_FUNCS(dctcoef, suffix)                                  \
-static void FUNCC(get_pixels ## suffix)(DCTELEM *restrict _block,       \
+static void FUNCC(get_pixels ## suffix)(DCTELEM *av_restrict _block,    \
                                         const uint8_t *_pixels,         \
                                         int line_size)                  \
 {                                                                       \
     const pixel *pixels = (const pixel *) _pixels;                      \
-    dctcoef *restrict block = (dctcoef *) _block;                       \
+    dctcoef *av_restrict block = (dctcoef *) _block;                    \
     int i;                                                              \
                                                                         \
     /* read the pixels */                                               \
@@ -216,12 +216,12 @@
     }                                                                   \
 }                                                                       \
                                                                         \
-static void FUNCC(add_pixels8 ## suffix)(uint8_t *restrict _pixels,     \
+static void FUNCC(add_pixels8 ## suffix)(uint8_t *av_restrict _pixels,  \
                                          DCTELEM *_block,               \
                                          int line_size)                 \
 {                                                                       \
     int i;                                                              \
-    pixel *restrict pixels = (pixel *restrict)_pixels;                  \
+    pixel *av_restrict pixels = (pixel *av_restrict)_pixels;            \
     dctcoef *block = (dctcoef*)_block;                                  \
     line_size /= sizeof(pixel);                                         \
                                                                         \
@@ -239,12 +239,12 @@
     }                                                                   \
 }                                                                       \
                                                                         \
-static void FUNCC(add_pixels4 ## suffix)(uint8_t *restrict _pixels,     \
+static void FUNCC(add_pixels4 ## suffix)(uint8_t *av_restrict _pixels,  \
                                          DCTELEM *_block,               \
                                          int line_size)                 \
 {                                                                       \
     int i;                                                              \
-    pixel *restrict pixels = (pixel *restrict)_pixels;                  \
+    pixel *av_restrict pixels = (pixel *av_restrict)_pixels;            \
     dctcoef *block = (dctcoef*)_block;                                  \
     line_size /= sizeof(pixel);                                         \
                                                                         \
@@ -484,12 +484,12 @@
     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 *_block, const uint8_t *_pixels, int line_size, int h)\
+static inline void FUNCC(OPNAME ## _pixels2_xy2)(uint8_t *p_block, const uint8_t *p_pixels, int line_size, int h)\
 {\
         int i, a0, b0, a1, b1;\
-        pixel *block = (pixel*)_block;\
-        const pixel *pixels = (const pixel*)_pixels;\
-        line_size /= sizeof(pixel);\
+        pixel *block = (pixel*)p_block;\
+        const pixel *pixels = (const pixel*)p_pixels;\
+        line_size >>= sizeof(pixel)-1;\
         a0= pixels[0];\
         b0= pixels[1] + 2;\
         a0 += b0;\
@@ -670,17 +670,17 @@
 }
 
 #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;\
+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);\
+    stride >>= sizeof(pixel)-1;\
     \
-    assert(x<8 && y<8 && x>=0 && y>=0);\
+    av_assert2(x<8 && y<8 && x>=0 && y>=0);\
 \
     if(D){\
         for(i=0; i<h; i++){\
@@ -701,17 +701,17 @@
     }\
 }\
 \
-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;\
+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);\
+    stride >>= sizeof(pixel)-1;\
     \
-    assert(x<8 && y<8 && x>=0 && y>=0);\
+    av_assert2(x<8 && y<8 && x>=0 && y>=0);\
 \
     if(D){\
         for(i=0; i<h; i++){\
@@ -736,17 +736,17 @@
     }\
 }\
 \
-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;\
+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);\
+    stride >>= sizeof(pixel)-1;\
     \
-    assert(x<8 && y<8 && x>=0 && y>=0);\
+    av_assert2(x<8 && y<8 && x>=0 && y>=0);\
 \
     if(D){\
         for(i=0; i<h; i++){\
@@ -788,14 +788,14 @@
 #undef op_put
 
 #define H264_LOWPASS(OPNAME, OP, OP2) \
-static av_unused void FUNC(OPNAME ## h264_qpel2_h_lowpass)(uint8_t *_dst, uint8_t *_src, int dstStride, int srcStride){\
+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*)_dst;\
-    pixel *src = (pixel*)_src;\
-    dstStride /= sizeof(pixel);\
-    srcStride /= sizeof(pixel);\
+    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]));\
@@ -805,14 +805,14 @@
     }\
 }\
 \
-static av_unused void FUNC(OPNAME ## h264_qpel2_v_lowpass)(uint8_t *_dst, uint8_t *_src, int dstStride, int 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*)_dst;\
-    pixel *src = (pixel*)_src;\
-    dstStride /= sizeof(pixel);\
-    srcStride /= sizeof(pixel);\
+    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];\
@@ -829,16 +829,16 @@
     }\
 }\
 \
-static av_unused void FUNC(OPNAME ## h264_qpel2_hv_lowpass)(uint8_t *_dst, int16_t *tmp, uint8_t *_src, int dstStride, int tmpStride, int srcStride){\
+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 > 9) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\
+    const int pad = (BIT_DEPTH == 10) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\
     INIT_CLIP\
     int i;\
-    pixel *dst = (pixel*)_dst;\
-    pixel *src = (pixel*)_src;\
-    dstStride /= sizeof(pixel);\
-    srcStride /= sizeof(pixel);\
+    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++)\
     {\
@@ -863,14 +863,14 @@
         tmp++;\
     }\
 }\
-static void FUNC(OPNAME ## h264_qpel4_h_lowpass)(uint8_t *_dst, uint8_t *_src, int dstStride, int srcStride){\
+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*)_dst;\
-    pixel *src = (pixel*)_src;\
-    dstStride /= sizeof(pixel);\
-    srcStride /= sizeof(pixel);\
+    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]));\
@@ -882,14 +882,14 @@
     }\
 }\
 \
-static void FUNC(OPNAME ## h264_qpel4_v_lowpass)(uint8_t *_dst, uint8_t *_src, int dstStride, int 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*)_dst;\
-    pixel *src = (pixel*)_src;\
-    dstStride /= sizeof(pixel);\
-    srcStride /= sizeof(pixel);\
+    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];\
@@ -910,16 +910,16 @@
     }\
 }\
 \
-static void FUNC(OPNAME ## h264_qpel4_hv_lowpass)(uint8_t *_dst, int16_t *tmp, uint8_t *_src, int dstStride, int tmpStride, int srcStride){\
+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 > 9) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\
+    const int pad = (BIT_DEPTH == 10) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\
     INIT_CLIP\
     int i;\
-    pixel *dst = (pixel*)_dst;\
-    pixel *src = (pixel*)_src;\
-    dstStride /= sizeof(pixel);\
-    srcStride /= sizeof(pixel);\
+    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++)\
     {\
@@ -951,14 +951,14 @@
     }\
 }\
 \
-static void FUNC(OPNAME ## h264_qpel8_h_lowpass)(uint8_t *_dst, uint8_t *_src, int dstStride, int srcStride){\
+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*)_dst;\
-    pixel *src = (pixel*)_src;\
-    dstStride /= sizeof(pixel);\
-    srcStride /= sizeof(pixel);\
+    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 ]));\
@@ -974,14 +974,14 @@
     }\
 }\
 \
-static void FUNC(OPNAME ## h264_qpel8_v_lowpass)(uint8_t *_dst, uint8_t *_src, int dstStride, int 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*)_dst;\
-    pixel *src = (pixel*)_src;\
-    dstStride /= sizeof(pixel);\
-    srcStride /= sizeof(pixel);\
+    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];\
@@ -1010,16 +1010,16 @@
     }\
 }\
 \
-static void FUNC(OPNAME ## h264_qpel8_hv_lowpass)(uint8_t *_dst, int16_t *tmp, uint8_t *_src, int dstStride, int tmpStride, int srcStride){\
+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 > 9) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\
+    const int pad = (BIT_DEPTH == 10) ? (-10 * ((1<<BIT_DEPTH)-1)) : 0;\
     INIT_CLIP\
     int i;\
-    pixel *dst = (pixel*)_dst;\
-    pixel *src = (pixel*)_src;\
-    dstStride /= sizeof(pixel);\
-    srcStride /= sizeof(pixel);\
+    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++)\
     {\
@@ -1081,7 +1081,7 @@
     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, int16_t *tmp, uint8_t *src, int dstStride, int tmpStride, int 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;\
@@ -1181,12 +1181,12 @@
 }\
 \
 static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc22)(uint8_t *dst, uint8_t *src, int stride){\
-    int16_t tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
+    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){\
-    int16_t tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
+    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);\
@@ -1195,7 +1195,7 @@
 }\
 \
 static void FUNCC(OPNAME ## h264_qpel ## SIZE ## _mc23)(uint8_t *dst, uint8_t *src, int stride){\
-    int16_t tmp[SIZE*(SIZE+5)*sizeof(pixel)];\
+    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);\
@@ -1206,7 +1206,7 @@
 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);\
-    int16_t tmp[SIZE*(SIZE+5)*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);\
@@ -1218,7 +1218,7 @@
 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);\
-    int16_t tmp[SIZE*(SIZE+5)*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);\
@@ -1263,6 +1263,16 @@
 #   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
 
 void FUNCC(ff_put_pixels8x8)(uint8_t *dst, uint8_t *src, int stride) {
@@ -1277,3 +1287,4 @@
 void FUNCC(ff_avg_pixels16x16)(uint8_t *dst, uint8_t *src, int stride) {
     FUNCC(avg_pixels16)(dst, src, stride, 16);
 }
+
diff --git a/libavcodec/dump_extradata_bsf.c b/libavcodec/dump_extradata_bsf.c
index 17d9434..94b7b42 100644
--- a/libavcodec/dump_extradata_bsf.c
+++ b/libavcodec/dump_extradata_bsf.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dv.c b/libavcodec/dv.c
index 7067f0c..a7dfbdc 100644
--- a/libavcodec/dv.c
+++ b/libavcodec/dv.c
@@ -16,20 +16,20 @@
  * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth
  * of DV technical info.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -297,6 +297,7 @@
     }
 
     /* Generic DSP setup */
+    memset(&dsp,0, sizeof(dsp));
     ff_dsputil_init(&dsp, avctx);
     ff_set_cmp(&dsp, dsp.ildct_cmp, avctx->ildct_cmp);
     s->get_pixels = dsp.get_pixels;
@@ -311,7 +312,13 @@
     /* 248DCT setup */
     s->fdct[1]     = dsp.fdct248;
     s->idct_put[1] = ff_simple_idct248_put;  // FIXME: need to add it to DSP
-    memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64);
+    if (avctx->lowres){
+        for (i = 0; i < 64; i++){
+            int j = ff_zigzag248_direct[i];
+            s->dv_zigzag[1][i] = dsp.idct_permutation[(j & 7) + (j & 8) * 4 + (j & 48) / 2];
+        }
+    }else
+        memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64);
 
     avctx->coded_frame = &s->picture;
     s->avctx = avctx;
@@ -329,6 +336,10 @@
         ff_dv_print_profiles(avctx, AV_LOG_ERROR);
         return AVERROR(EINVAL);
     }
+    if (avctx->height > 576) {
+        av_log(avctx, AV_LOG_ERROR, "DVCPRO HD encoding is not supported.\n");
+        return AVERROR_PATCHWELCOME;
+    }
 
     dv_vlc_map_tableinit();
 
@@ -501,7 +512,7 @@
        method suggested in SMPTE 314M Table 22, and an improved
        method. The SMPTE method is very conservative; it assigns class
        3 (i.e. severe quantization) to any block where the largest AC
-       component is greater than 36. Libav's DV encoder tracks AC bit
+       component is greater than 36. FFmpeg's DV encoder tracks AC bit
        consumption precisely, so there is no need to bias most blocks
        towards strongly lossy compression. Instead, we assign class 2
        to most blocks, and use class 3 only when strictly necessary
@@ -509,7 +520,7 @@
 
 #if 0 /* SMPTE spec method */
     static const int classes[] = {12, 24, 36, 0xffff};
-#else /* improved Libav method */
+#else /* improved FFmpeg method */
     static const int classes[] = {-1, -1, 255, 0xffff};
 #endif
     int max  = classes[0];
@@ -952,10 +963,8 @@
     s->sys = avpriv_dv_codec_profile(c);
     if (!s->sys || ff_dv_init_dynamic_tables(s->sys))
         return -1;
-    if ((ret = ff_alloc_packet(pkt, s->sys->frame_size)) < 0) {
-        av_log(c, AV_LOG_ERROR, "Error getting output packet.\n");
+    if ((ret = ff_alloc_packet2(c, pkt, s->sys->frame_size)) < 0)
         return ret;
-    }
 
     c->pix_fmt           = s->sys->pix_fmt;
     s->picture           = *frame;
diff --git a/libavcodec/dv_profile.c b/libavcodec/dv_profile.c
index be392bb..05d4aba 100644
--- a/libavcodec/dv_profile.c
+++ b/libavcodec/dv_profile.c
@@ -19,6 +19,7 @@
 #include <stdint.h>
 
 #include "libavutil/common.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/log.h"
 #include "libavutil/pixdesc.h"
 #include "avcodec.h"
@@ -280,22 +281,26 @@
     }
 };
 
-const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys,
+const DVprofile* avpriv_dv_frame_profile2(AVCodecContext* codec, const DVprofile *sys,
                                   const uint8_t* frame, unsigned buf_size)
 {
     int i, dsf, stype;
 
-    if (buf_size < 80 * 5 + 48 + 4)
+    if(buf_size < DV_PROFILE_BYTES)
         return NULL;
 
     dsf = (frame[3] & 0x80) >> 7;
     stype = frame[80 * 5 + 48 + 3] & 0x1f;
 
     /* 576i50 25Mbps 4:1:1 is a special case */
-    if (dsf == 1 && stype == 0 && frame[4] & 0x07 /* the APT field */) {
+    if ((dsf == 1 && stype == 0 && frame[4] & 0x07 /* the APT field */) ||
+        (stype == 31 && codec && codec->codec_tag==AV_RL32("SL25") && codec->coded_width==720 && codec->coded_height==576)) {
         return &dv_profiles[2];
     }
 
+    if(stype == 0 && codec && codec->codec_tag==AV_RL32("dvsd") && codec->coded_width==720 && codec->coded_height==576)
+        return &dv_profiles[1];
+
     for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++)
         if (dsf == dv_profiles[i].dsf && stype == dv_profiles[i].video_stype)
             return &dv_profiles[i];
@@ -304,17 +309,36 @@
     if (sys && buf_size == sys->frame_size)
         return sys;
 
+    /* hack for trac issue #217, dv files created with QuickTime 3 */
+    if ((frame[3] & 0x7f) == 0x3f && frame[80 * 5 + 48 + 3] == 0xff)
+        return &dv_profiles[dsf];
+
     return NULL;
 }
 
+const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys,
+                                  const uint8_t* frame, unsigned buf_size)
+{
+    return avpriv_dv_frame_profile2(NULL, sys, frame, buf_size);
+}
+
 const DVprofile* avpriv_dv_codec_profile(AVCodecContext* codec)
 {
     int i;
+    int w, h;
+
+    if (codec->coded_width || codec->coded_height) {
+        w = codec->coded_width;
+        h = codec->coded_height;
+    } else {
+        w = codec->width;
+        h = codec->height;
+    }
 
     for (i=0; i<FF_ARRAY_ELEMS(dv_profiles); i++)
-       if (codec->height  == dv_profiles[i].height  &&
+       if (h == dv_profiles[i].height  &&
            codec->pix_fmt == dv_profiles[i].pix_fmt &&
-           codec->width   == dv_profiles[i].width)
+           w == dv_profiles[i].width)
                return &dv_profiles[i];
 
     return NULL;
diff --git a/libavcodec/dv_profile.h b/libavcodec/dv_profile.h
index c6d2278..97edce9 100644
--- a/libavcodec/dv_profile.h
+++ b/libavcodec/dv_profile.h
@@ -25,6 +25,10 @@
 #include "libavutil/rational.h"
 #include "avcodec.h"
 
+/* minimum number of bytes to read from a DV stream in order to
+   determine the profile */
+#define DV_PROFILE_BYTES (6*80) /* 6 DIF blocks */
+
 typedef struct DVwork_chunk {
     uint16_t  buf_offset;
     uint16_t  mb_coordinates[5];
@@ -62,6 +66,8 @@
 
 const DVprofile* avpriv_dv_frame_profile(const DVprofile *sys,
                                          const uint8_t* frame, unsigned buf_size);
+const DVprofile* avpriv_dv_frame_profile2(AVCodecContext* codec, const DVprofile *sys,
+                                  const uint8_t* frame, unsigned buf_size);
 const DVprofile* avpriv_dv_codec_profile(AVCodecContext* codec);
 
 /**
diff --git a/libavcodec/dv_tablegen.c b/libavcodec/dv_tablegen.c
index f463550..5d3793e 100644
--- a/libavcodec/dv_tablegen.c
+++ b/libavcodec/dv_tablegen.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dv_tablegen.h b/libavcodec/dv_tablegen.h
index 05831ea..e8cdc21 100644
--- a/libavcodec/dv_tablegen.h
+++ b/libavcodec/dv_tablegen.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dv_vlc_data.h b/libavcodec/dv_vlc_data.h
index d62fd6b..be768e6 100644
--- a/libavcodec/dv_vlc_data.h
+++ b/libavcodec/dv_vlc_data.h
@@ -2,20 +2,20 @@
  * VLC constants for DV codec
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dvbsub.c b/libavcodec/dvbsub.c
index 26d14bd..562db6a 100644
--- a/libavcodec/dvbsub.c
+++ b/libavcodec/dvbsub.c
@@ -2,20 +2,20 @@
  * DVB subtitle encoding
  * Copyright (c) 2005 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avcodec.h"
@@ -23,7 +23,6 @@
 #include "libavutil/colorspace.h"
 
 typedef struct DVBSubtitleContext {
-    int hide_state;
     int object_version;
 } DVBSubtitleContext;
 
@@ -194,6 +193,60 @@
     *pq = q;
 }
 
+static void dvb_encode_rle8(uint8_t **pq,
+                            const uint8_t *bitmap, int linesize,
+                            int w, int h)
+{
+    uint8_t *q;
+    int x, y, len, x1, color;
+
+    q = *pq;
+
+    for (y = 0; y < h; y++) {
+        *q++ = 0x12;
+
+        x = 0;
+        while (x < w) {
+            x1 = x;
+            color = bitmap[x1++];
+            while (x1 < w && bitmap[x1] == color)
+                x1++;
+            len = x1 - x;
+            if (len == 1 && color) {
+                // 00000001 to 11111111           1 pixel in colour x
+                *q++ = color;
+            } else {
+                if (color == 0x00) {
+                    // 00000000 0LLLLLLL          L pixels (1-127) in colour 0 (L > 0)
+                    len = FFMIN(len, 127);
+                    *q++ = 0x00;
+                    *q++ = len;
+                } else if (len > 2) {
+                    // 00000000 1LLLLLLL CCCCCCCC L pixels (3-127) in colour C (L > 2)
+                    len = FFMIN(len, 127);
+                    *q++ = 0x00;
+                    *q++ = 0x80+len;
+                    *q++ = color;
+                }
+                else if (len == 2) {
+                    *q++ = color;
+                    *q++ = color;
+                } else {
+                    *q++ = color;
+                    len = 1;
+                }
+            }
+            x += len;
+        }
+        /* end of line */
+        // 00000000 00000000 end of 8-bit/pixel_code_string
+        *q++ = 0x00;
+        *q++ = 0x00;
+        bitmap += linesize;
+    }
+    *pq = q;
+}
+
 static int encode_dvb_subtitles(DVBSubtitleContext *s,
                                 uint8_t *outbuf, const AVSubtitle *h)
 {
@@ -205,7 +258,7 @@
 
     page_id = 1;
 
-    if (h->num_rects == 0 || h->rects == NULL)
+    if (h->num_rects && h->rects == NULL)
         return -1;
 
     *q++ = 0x00; /* subtitle_stream_id */
@@ -218,10 +271,7 @@
     pseg_len = q;
     q += 2; /* segment length */
     *q++ = 30; /* page_timeout (seconds) */
-    if (s->hide_state)
-        page_state = 0; /* normal case */
-    else
-        page_state = 2; /* mode change */
+    page_state = 2; /* mode change */
     /* page_version = 0 + page_state */
     *q++ = (s->object_version << 4) | (page_state << 2) | 3;
 
@@ -234,7 +284,7 @@
 
     bytestream_put_be16(&pseg_len, q - pseg_len - 2);
 
-    if (!s->hide_state) {
+    if (h->num_rects) {
         for (clut_id = 0; clut_id < h->num_rects; clut_id++) {
 
             /* CLUT segment */
@@ -245,10 +295,15 @@
             } else if (h->rects[clut_id]->nb_colors <= 16) {
                 /* 4 bpp, standard encoding */
                 bpp_index = 1;
+            } else if (h->rects[clut_id]->nb_colors <= 256) {
+                /* 8 bpp, standard encoding */
+                bpp_index = 2;
             } else {
                 return -1;
             }
 
+
+            /* CLUT segment */
             *q++ = 0x0f; /* sync byte */
             *q++ = 0x12; /* CLUT definition segment */
             bytestream_put_be16(&q, page_id);
@@ -307,32 +362,37 @@
         *q++ = 0; /* 8 bit fill colors */
         *q++ = 0x03; /* 4 bit and 2 bit fill colors */
 
-        if (!s->hide_state) {
-            bytestream_put_be16(&q, region_id); /* object_id == region_id */
-            *q++ = (0 << 6) | (0 << 4);
-            *q++ = 0;
-            *q++ = 0xf0;
-            *q++ = 0;
-        }
+        bytestream_put_be16(&q, region_id); /* object_id == region_id */
+        *q++ = (0 << 6) | (0 << 4);
+        *q++ = 0;
+        *q++ = 0xf0;
+        *q++ = 0;
 
         bytestream_put_be16(&pseg_len, q - pseg_len - 2);
     }
 
-    if (!s->hide_state) {
+    if (h->num_rects) {
 
         for (object_id = 0; object_id < h->num_rects; object_id++) {
-            /* Object Data segment */
+            void (*dvb_encode_rle)(uint8_t **pq,
+                                    const uint8_t *bitmap, int linesize,
+                                    int w, int h);
 
+            /* bpp_index maths */
             if (h->rects[object_id]->nb_colors <= 4) {
                 /* 2 bpp, some decoders do not support it correctly */
-                bpp_index = 0;
+                dvb_encode_rle = dvb_encode_rle2;
             } else if (h->rects[object_id]->nb_colors <= 16) {
                 /* 4 bpp, standard encoding */
-                bpp_index = 1;
+                dvb_encode_rle = dvb_encode_rle4;
+            } else if (h->rects[object_id]->nb_colors <= 256) {
+                /* 8 bpp, standard encoding */
+                dvb_encode_rle = dvb_encode_rle8;
             } else {
                 return -1;
             }
 
+            /* Object Data segment */
             *q++ = 0x0f; /* sync byte */
             *q++ = 0x13;
             bytestream_put_be16(&q, page_id);
@@ -345,19 +405,12 @@
                                                                        non_modifying_color_flag */
             {
                 uint8_t *ptop_field_len, *pbottom_field_len, *top_ptr, *bottom_ptr;
-                void (*dvb_encode_rle)(uint8_t **pq,
-                                        const uint8_t *bitmap, int linesize,
-                                        int w, int h);
+
                 ptop_field_len = q;
                 q += 2;
                 pbottom_field_len = q;
                 q += 2;
 
-                if (bpp_index == 0)
-                    dvb_encode_rle = dvb_encode_rle2;
-                else
-                    dvb_encode_rle = dvb_encode_rle4;
-
                 top_ptr = q;
                 dvb_encode_rle(&q, h->rects[object_id]->pict.data[0], h->rects[object_id]->w * 2,
                                     h->rects[object_id]->w, h->rects[object_id]->h >> 1);
@@ -387,7 +440,6 @@
     *q++ = 0xff; /* end of PES data */
 
     s->object_version = (s->object_version + 1) & 0xf;
-    s->hide_state = !s->hide_state;
     return q - outbuf;
 }
 
diff --git a/libavcodec/dvbsub_parser.c b/libavcodec/dvbsub_parser.c
index c13aab6..5274fd6 100644
--- a/libavcodec/dvbsub_parser.c
+++ b/libavcodec/dvbsub_parser.c
@@ -1,21 +1,21 @@
 /*
- * DVB subtitle parser for Libav
+ * DVB subtitle parser for FFmpeg
  * Copyright (c) 2005 Ian Caulfield
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avcodec.h"
diff --git a/libavcodec/dvbsubdec.c b/libavcodec/dvbsubdec.c
index b4aba49..955925a 100644
--- a/libavcodec/dvbsubdec.c
+++ b/libavcodec/dvbsubdec.c
@@ -2,20 +2,20 @@
  * DVB subtitle decoding
  * Copyright (c) 2005 Ian Caulfield
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avcodec.h"
@@ -154,6 +154,7 @@
 
 typedef struct DVBSubCLUT {
     int id;
+    int version;
 
     uint32_t clut4[4];
     uint32_t clut16[16];
@@ -180,6 +181,7 @@
 
 typedef struct DVBSubObject {
     int id;
+    int version;
 
     int type;
 
@@ -199,6 +201,7 @@
 
 typedef struct DVBSubRegion {
     int id;
+    int version;
 
     int width;
     int height;
@@ -209,6 +212,7 @@
 
     uint8_t *pbuf;
     int buf_size;
+    int dirty;
 
     DVBSubObjectDisplay *display_list;
 
@@ -228,6 +232,7 @@
     int composition_id;
     int ancillary_id;
 
+    int version;
     int time_out;
     DVBSubRegion *region_list;
     DVBSubCLUT   *clut_list;
@@ -318,21 +323,10 @@
 
 }
 
-static void delete_state(DVBSubContext *ctx)
+static void delete_cluts(DVBSubContext *ctx)
 {
-    DVBSubRegion *region;
     DVBSubCLUT *clut;
 
-    while (ctx->region_list) {
-        region = ctx->region_list;
-
-        ctx->region_list = region->next;
-
-        delete_region_display_list(ctx, region);
-        av_free(region->pbuf);
-        av_free(region);
-    }
-
     while (ctx->clut_list) {
         clut = ctx->clut_list;
 
@@ -340,12 +334,35 @@
 
         av_free(clut);
     }
+}
 
-    av_freep(&ctx->display_definition);
+static void delete_objects(DVBSubContext *ctx)
+{
+    DVBSubObject *object;
 
-    /* Should already be null */
-    if (ctx->object_list)
-        av_log(0, AV_LOG_ERROR, "Memory deallocation error!\n");
+    while (ctx->object_list) {
+        object = ctx->object_list;
+
+        ctx->object_list = object->next;
+
+        av_free(object);
+    }
+}
+
+static void delete_regions(DVBSubContext *ctx)
+{
+    DVBSubRegion *region;
+
+    while (ctx->region_list) {
+        region = ctx->region_list;
+
+        ctx->region_list = region->next;
+
+        delete_region_display_list(ctx, region);
+
+        av_free(region->pbuf);
+        av_free(region);
+    }
 }
 
 static av_cold int dvbsub_init_decoder(AVCodecContext *avctx)
@@ -362,6 +379,8 @@
         ctx->ancillary_id   = AV_RB16(avctx->extradata + 2);
     }
 
+    ctx->version = -1;
+
     default_clut.id = -1;
     default_clut.next = NULL;
 
@@ -430,7 +449,13 @@
     DVBSubContext *ctx = avctx->priv_data;
     DVBSubRegionDisplay *display;
 
-    delete_state(ctx);
+    delete_regions(ctx);
+
+    delete_objects(ctx);
+
+    delete_cluts(ctx);
+
+    av_freep(&ctx->display_definition);
 
     while (ctx->display_list) {
         display = ctx->display_list;
@@ -444,16 +469,18 @@
 
 static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len,
                                    const uint8_t **srcbuf, int buf_size,
-                                   int non_mod, uint8_t *map_table)
+                                   int non_mod, uint8_t *map_table, int x_pos)
 {
     GetBitContext gb;
 
     int bits;
     int run_length;
-    int pixels_read = 0;
+    int pixels_read = x_pos;
 
     init_get_bits(&gb, *srcbuf, buf_size << 3);
 
+    destbuf += x_pos;
+
     while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
         bits = get_bits(&gb, 2);
 
@@ -514,14 +541,14 @@
                             }
                         }
                     } else if (bits == 1) {
-                        pixels_read += 2;
                         if (map_table)
                             bits = map_table[0];
                         else
                             bits = 0;
-                        if (pixels_read <= dbuf_len) {
+                        run_length = 2;
+                        while (run_length-- > 0 && pixels_read < dbuf_len) {
                             *destbuf++ = bits;
-                            *destbuf++ = bits;
+                            pixels_read++;
                         }
                     } else {
                         (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
@@ -549,16 +576,18 @@
 
 static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len,
                                    const uint8_t **srcbuf, int buf_size,
-                                   int non_mod, uint8_t *map_table)
+                                   int non_mod, uint8_t *map_table, int x_pos)
 {
     GetBitContext gb;
 
     int bits;
     int run_length;
-    int pixels_read = 0;
+    int pixels_read = x_pos;
 
     init_get_bits(&gb, *srcbuf, buf_size << 3);
 
+    destbuf += x_pos;
+
     while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
         bits = get_bits(&gb, 4);
 
@@ -638,14 +667,14 @@
                             }
                         }
                     } else if (bits == 1) {
-                        pixels_read += 2;
                         if (map_table)
                             bits = map_table[0];
                         else
                             bits = 0;
-                        if (pixels_read <= dbuf_len) {
+                        run_length = 2;
+                        while (run_length-- > 0 && pixels_read < dbuf_len) {
                             *destbuf++ = bits;
-                            *destbuf++ = bits;
+                            pixels_read++;
                         }
                     } else {
                         if (map_table)
@@ -670,12 +699,14 @@
 
 static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len,
                                     const uint8_t **srcbuf, int buf_size,
-                                    int non_mod, uint8_t *map_table)
+                                    int non_mod, uint8_t *map_table, int x_pos)
 {
     const uint8_t *sbuf_end = (*srcbuf) + buf_size;
     int bits;
     int run_length;
-    int pixels_read = 0;
+    int pixels_read = x_pos;
+
+    destbuf += x_pos;
 
     while (*srcbuf < sbuf_end && pixels_read < dbuf_len) {
         bits = *(*srcbuf)++;
@@ -744,6 +775,7 @@
                          0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
     uint8_t *map_table;
 
+#if 0
     av_dlog(avctx, "DVB pixel block size %d, %s field:\n", buf_size,
             top_bottom ? "bottom" : "top");
 
@@ -758,21 +790,22 @@
 
     if (i % 16)
         av_dlog(avctx, "\n");
+#endif
 
     if (region == 0)
         return;
 
     pbuf = region->pbuf;
+    region->dirty = 1;
 
     x_pos = display->x_pos;
     y_pos = display->y_pos;
 
-    if ((y_pos & 1) != top_bottom)
-        y_pos++;
+    y_pos += top_bottom;
 
     while (buf < buf_end) {
-        if (x_pos > region->width || y_pos > region->height) {
-            av_log(avctx, AV_LOG_ERROR, "Invalid object location!\n");
+        if ((*buf!=0xf0 && x_pos >= region->width) || y_pos >= region->height) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid object location! %d-%d %d-%d %02x\n", x_pos, region->width, y_pos, region->height, *buf);
             return;
         }
 
@@ -785,9 +818,9 @@
             else
                 map_table = NULL;
 
-            x_pos += dvbsub_read_2bit_string(pbuf + (y_pos * region->width) + x_pos,
-                                                region->width - x_pos, &buf, buf_end - buf,
-                                                non_mod, map_table);
+            x_pos = dvbsub_read_2bit_string(pbuf + (y_pos * region->width),
+                                            region->width, &buf, buf_end - buf,
+                                            non_mod, map_table, x_pos);
             break;
         case 0x11:
             if (region->depth < 4) {
@@ -800,9 +833,9 @@
             else
                 map_table = NULL;
 
-            x_pos += dvbsub_read_4bit_string(pbuf + (y_pos * region->width) + x_pos,
-                                                region->width - x_pos, &buf, buf_end - buf,
-                                                non_mod, map_table);
+            x_pos = dvbsub_read_4bit_string(pbuf + (y_pos * region->width),
+                                            region->width, &buf, buf_end - buf,
+                                            non_mod, map_table, x_pos);
             break;
         case 0x12:
             if (region->depth < 8) {
@@ -810,9 +843,9 @@
                 return;
             }
 
-            x_pos += dvbsub_read_8bit_string(pbuf + (y_pos * region->width) + x_pos,
-                                                region->width - x_pos, &buf, buf_end - buf,
-                                                non_mod, NULL);
+            x_pos = dvbsub_read_8bit_string(pbuf + (y_pos * region->width),
+                                            region->width, &buf, buf_end - buf,
+                                            non_mod, NULL, x_pos);
             break;
 
         case 0x20:
@@ -847,7 +880,6 @@
     DVBSubContext *ctx = avctx->priv_data;
 
     const uint8_t *buf_end = buf + buf_size;
-    const uint8_t *block;
     int object_id;
     DVBSubObject *object;
     DVBSubObjectDisplay *display;
@@ -878,7 +910,8 @@
         }
 
         for (display = object->display_list; display; display = display->object_list_next) {
-            block = buf;
+            const uint8_t *block = buf;
+            int bfl = bottom_field_len;
 
             dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0,
                                             non_modifying_color);
@@ -886,9 +919,9 @@
             if (bottom_field_len > 0)
                 block = buf + top_field_len;
             else
-                bottom_field_len = top_field_len;
+                bfl = top_field_len;
 
-            dvbsub_parse_pixel_data_block(avctx, display, block, bottom_field_len, 1,
+            dvbsub_parse_pixel_data_block(avctx, display, block, bfl, 1,
                                             non_modifying_color);
         }
 
@@ -907,6 +940,7 @@
 
     const uint8_t *buf_end = buf + buf_size;
     int i, clut_id;
+    int version;
     DVBSubCLUT *clut;
     int entry_id, depth , full_range;
     int y, cr, cb, alpha;
@@ -924,6 +958,7 @@
         av_dlog(avctx, "\n");
 
     clut_id = *buf++;
+    version = ((*buf)>>4)&15;
     buf += 1;
 
     clut = get_clut(ctx, clut_id);
@@ -934,11 +969,16 @@
         memcpy(clut, &default_clut, sizeof(DVBSubCLUT));
 
         clut->id = clut_id;
+        clut->version = -1;
 
         clut->next = ctx->clut_list;
         ctx->clut_list = clut;
     }
 
+    if (clut->version != version) {
+
+    clut->version = version;
+
     while (buf + 4 < buf_end) {
         entry_id = *buf++;
 
@@ -980,6 +1020,7 @@
         if (depth & 0x20)
             clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
     }
+    }
 }
 
 
@@ -990,6 +1031,7 @@
 
     const uint8_t *buf_end = buf + buf_size;
     int region_id, object_id;
+    int av_unused version;
     DVBSubRegion *region;
     DVBSubObject *object;
     DVBSubObjectDisplay *display;
@@ -1006,11 +1048,13 @@
         region = av_mallocz(sizeof(DVBSubRegion));
 
         region->id = region_id;
+        region->version = -1;
 
         region->next = ctx->region_list;
         ctx->region_list = region;
     }
 
+    version = ((*buf)>>4) & 15;
     fill = ((*buf++) >> 3) & 1;
 
     region->width = AV_RB16(buf);
@@ -1026,6 +1070,7 @@
         region->pbuf = av_malloc(region->buf_size);
 
         fill = 1;
+        region->dirty = 0;
     }
 
     region->depth = 1 << (((*buf++) >> 2) & 7);
@@ -1035,9 +1080,10 @@
     }
     region->clut = *buf++;
 
-    if (region->depth == 8)
+    if (region->depth == 8) {
         region->bgcolor = *buf++;
-    else {
+        buf += 1;
+    } else {
         buf += 1;
 
         if (region->depth == 4)
@@ -1104,17 +1150,27 @@
     const uint8_t *buf_end = buf + buf_size;
     int region_id;
     int page_state;
+    int timeout;
+    int version;
 
     if (buf_size < 1)
         return;
 
-    ctx->time_out = *buf++;
+    timeout = *buf++;
+    version = ((*buf)>>4) & 15;
     page_state = ((*buf++) >> 2) & 3;
 
+    if (ctx->version != version) {
+
+    ctx->time_out = timeout;
+    ctx->version = version;
+
     av_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state);
 
-    if (page_state == 2) {
-        delete_state(ctx);
+    if (page_state == 1 || page_state == 2) {
+        delete_regions(ctx);
+        delete_objects(ctx);
+        delete_cluts(ctx);
     }
 
     tmp_display_list = ctx->display_list;
@@ -1159,6 +1215,7 @@
 
         av_free(display);
     }
+    }
 
 }
 
@@ -1286,6 +1343,10 @@
     display_def->y       = 0;
     display_def->width   = bytestream_get_be16(&buf) + 1;
     display_def->height  = bytestream_get_be16(&buf) + 1;
+    if (!avctx->width || !avctx->height) {
+        avctx->width  = display_def->width;
+        avctx->height = display_def->height;
+    }
 
     if (buf_size < 13)
         return;
@@ -1312,10 +1373,7 @@
     int i;
     int offset_x=0, offset_y=0;
 
-    sub->rects = NULL;
-    sub->start_display_time = 0;
     sub->end_display_time = ctx->time_out * 1000;
-    sub->format = 0;
 
     if (display_def) {
         offset_x = display_def->x;
@@ -1328,22 +1386,24 @@
         sub->rects = av_mallocz(sizeof(*sub->rects) * sub->num_rects);
         for(i=0; i<sub->num_rects; i++)
             sub->rects[i] = av_mallocz(sizeof(*sub->rects[i]));
-    }
 
     i = 0;
 
     for (display = ctx->display_list; display; display = display->next) {
         region = get_region(ctx, display->region_id);
-        rect = sub->rects[i];
 
         if (!region)
             continue;
 
+        if (!region->dirty)
+            continue;
+
+        rect = sub->rects[i];
         rect->x = display->x_pos + offset_x;
         rect->y = display->y_pos + offset_y;
         rect->w = region->width;
         rect->h = region->height;
-        rect->nb_colors = 16;
+        rect->nb_colors = (1 << region->depth);
         rect->type      = SUBTITLE_BITMAP;
         rect->pict.linesize[0] = region->width;
 
@@ -1375,7 +1435,7 @@
     }
 
     sub->num_rects = i;
-
+    }
 #ifdef DEBUG
     save_display_set(ctx);
 #endif
@@ -1396,6 +1456,7 @@
     int page_id;
     int segment_length;
     int i;
+    int got_segment = 0;
 
     av_dlog(avctx, "DVB sub packet:\n");
 
@@ -1434,20 +1495,26 @@
             switch (segment_type) {
             case DVBSUB_PAGE_SEGMENT:
                 dvbsub_parse_page_segment(avctx, p, segment_length);
+                got_segment |= 1;
                 break;
             case DVBSUB_REGION_SEGMENT:
                 dvbsub_parse_region_segment(avctx, p, segment_length);
+                got_segment |= 2;
                 break;
             case DVBSUB_CLUT_SEGMENT:
                 dvbsub_parse_clut_segment(avctx, p, segment_length);
+                got_segment |= 4;
                 break;
             case DVBSUB_OBJECT_SEGMENT:
                 dvbsub_parse_object_segment(avctx, p, segment_length);
+                got_segment |= 8;
                 break;
             case DVBSUB_DISPLAYDEFINITION_SEGMENT:
                 dvbsub_parse_display_definition_segment(avctx, p, segment_length);
+                break;
             case DVBSUB_DISPLAY_SEGMENT:
                 *data_size = dvbsub_display_end_segment(avctx, p, segment_length, sub);
+                got_segment |= 16;
                 break;
             default:
                 av_dlog(avctx, "Subtitling segment type 0x%x, page id %d, length %d\n",
@@ -1458,6 +1525,10 @@
 
         p += segment_length;
     }
+    // Some streams do not send a display segment but if we have all the other
+    // segments then we need no further data.
+    if (got_segment == 15 && sub)
+        *data_size = dvbsub_display_end_segment(avctx, p, 0, sub);
 
     return p - buf;
 }
diff --git a/libavcodec/dvdata.c b/libavcodec/dvdata.c
index c779277..a7e3d59 100644
--- a/libavcodec/dvdata.c
+++ b/libavcodec/dvdata.c
@@ -2,20 +2,20 @@
  * Constants for DV codec
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dvdata.h b/libavcodec/dvdata.h
index c50fa5f..b1fa44a 100644
--- a/libavcodec/dvdata.h
+++ b/libavcodec/dvdata.h
@@ -2,20 +2,20 @@
  * Constants for DV codec
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -83,10 +83,6 @@
 #define DV_PROFILE_IS_1080i50(p) (((p)->video_stype == 0x14) && ((p)->dsf == 1))
 #define DV_PROFILE_IS_720p50(p)  (((p)->video_stype == 0x18) && ((p)->dsf == 1))
 
-/* minimum number of bytes to read from a DV stream in order to
-   determine the profile */
-#define DV_PROFILE_BYTES (6*80) /* 6 DIF blocks */
-
 /**
  * largest possible DV frame, in bytes (1080i50)
  */
diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c
index 2917de9..a38d409 100644
--- a/libavcodec/dvdec.c
+++ b/libavcodec/dvdec.c
@@ -13,20 +13,20 @@
  * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth
  * of DV technical info.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -35,6 +35,7 @@
  * DV decoder
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/pixdesc.h"
 #include "avcodec.h"
 #include "dsputil.h"
@@ -144,11 +145,11 @@
     LOCAL_ALIGNED_16(DCTELEM, 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;
+    const int log2_blocksize = 3-s->avctx->lowres;
     int is_field_mode[5];
 
-    assert((((int)mb_bit_buffer) & 7) == 0);
-    assert((((int)vs_bit_buffer) & 7) == 0);
+    av_assert1((((int)mb_bit_buffer) & 7) == 0);
+    av_assert1((((int)vs_bit_buffer) & 7) == 0);
 
     memset(sblock, 0, 5*DV_MAX_BPM*sizeof(*sblock));
 
@@ -319,7 +320,7 @@
     const uint8_t* vsc_pack;
     int apt, is16_9;
 
-    s->sys = avpriv_dv_frame_profile(s->sys, buf, buf_size);
+    s->sys = avpriv_dv_frame_profile2(avctx, s->sys, buf, buf_size);
     if (!s->sys || buf_size < s->sys->frame_size || ff_dv_init_dynamic_tables(s->sys)) {
         av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n");
         return -1; /* NOTE: we only accept several full frames */
@@ -328,6 +329,7 @@
     if (s->picture.data[0])
         avctx->release_buffer(avctx, &s->picture);
 
+    avcodec_get_frame_defaults(&s->picture);
     s->picture.reference = 0;
     s->picture.key_frame = 1;
     s->picture.pict_type = AV_PICTURE_TYPE_I;
@@ -355,7 +357,7 @@
     vsc_pack = buf + 80*5 + 48 + 5;
     if ( *vsc_pack == dv_video_control ) {
         apt = buf[4] & 0x07;
-        is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07)));
+        is16_9 = (vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07);
         avctx->sample_aspect_ratio = s->sys->sar[is16_9];
     }
 
@@ -381,5 +383,6 @@
     .close          = dvvideo_close,
     .decode         = dvvideo_decode_frame,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
+    .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
 };
diff --git a/libavcodec/dvdsub_parser.c b/libavcodec/dvdsub_parser.c
index 2ad3b33..e50c339 100644
--- a/libavcodec/dvdsub_parser.c
+++ b/libavcodec/dvdsub_parser.c
@@ -2,20 +2,20 @@
  * DVD subtitle decoding
  * Copyright (c) 2005 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c
index e52205d..90593d0 100644
--- a/libavcodec/dvdsubdec.c
+++ b/libavcodec/dvdsubdec.c
@@ -2,29 +2,38 @@
  * DVD subtitle decoding
  * Copyright (c) 2005 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avcodec.h"
 #include "get_bits.h"
 #include "dsputil.h"
 #include "libavutil/colorspace.h"
+#include "libavutil/imgutils.h"
 
 //#define DEBUG
 
+typedef struct DVDSubContext
+{
+  uint32_t palette[16];
+  int      has_palette;
+  uint8_t  colormap[4];
+  uint8_t  alpha[256];
+} DVDSubContext;
+
 static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values)
 {
     uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
@@ -116,12 +125,27 @@
 }
 
 static void guess_palette(uint32_t *rgba_palette,
-                          uint8_t *colormap,
-                          uint8_t *alpha,
+                          DVDSubContext* ctx,
                           uint32_t subtitle_color)
 {
+    static const uint8_t level_map[4][4] = {
+        // this configuration (full range, lowest to highest) in tests
+        // seemed most common, so assume this
+        {0xff},
+        {0x00, 0xff},
+        {0x00, 0x80, 0xff},
+        {0x00, 0x55, 0xaa, 0xff},
+    };
     uint8_t color_used[16] = { 0 };
     int nb_opaque_colors, i, level, j, r, g, b;
+    uint8_t *colormap = ctx->colormap, *alpha = ctx->alpha;
+
+    if(ctx->has_palette) {
+        for(i = 0; i < 4; i++)
+            rgba_palette[i] = (ctx->palette[colormap[i]] & 0x00ffffff)
+                              | ((alpha[i] * 17) << 24);
+        return;
+    }
 
     for(i = 0; i < 4; i++)
         rgba_palette[i] = 0;
@@ -137,18 +161,18 @@
     if (nb_opaque_colors == 0)
         return;
 
-    j = nb_opaque_colors;
+    j = 0;
     memset(color_used, 0, 16);
     for(i = 0; i < 4; i++) {
         if (alpha[i] != 0) {
             if (!color_used[colormap[i]])  {
-                level = (0xff * j) / nb_opaque_colors;
+                level = level_map[nb_opaque_colors][j];
                 r = (((subtitle_color >> 16) & 0xff) * level) >> 8;
                 g = (((subtitle_color >> 8) & 0xff) * level) >> 8;
                 b = (((subtitle_color >> 0) & 0xff) * level) >> 8;
                 rgba_palette[i] = b | (g << 8) | (r << 16) | ((alpha[i] * 17) << 24);
                 color_used[colormap[i]] = (i + 1);
-                j--;
+                j++;
             } else {
                 rgba_palette[i] = (rgba_palette[color_used[colormap[i]] - 1] & 0x00ffffff) |
                                     ((alpha[i] * 17) << 24);
@@ -159,20 +183,19 @@
 
 #define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a))
 
-static int decode_dvd_subtitles(AVSubtitle *sub_header,
+static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header,
                                 const uint8_t *buf, int buf_size)
 {
     int cmd_pos, pos, cmd, x1, y1, x2, y2, offset1, offset2, next_cmd_pos;
     int big_offsets, offset_size, is_8bit = 0;
     const uint8_t *yuv_palette = 0;
-    uint8_t colormap[4], alpha[256];
+    uint8_t *colormap = ctx->colormap, *alpha = ctx->alpha;
     int date;
     int i;
     int is_menu = 0;
 
     if (buf_size < 10)
         return -1;
-    memset(sub_header, 0, sizeof(*sub_header));
 
     if (AV_RB16(buf) == 0) {   /* HD subpicture with 4-byte offsets */
         big_offsets = 1;
@@ -325,8 +348,8 @@
                     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],
-                                  colormap, alpha, 0xffff00);
+                    guess_palette((uint32_t*)sub_header->rects[0]->pict.data[1], ctx,
+                                  0xffff00);
                 }
                 sub_header->rects[0]->x = x1;
                 sub_header->rects[0]->y = y1;
@@ -334,8 +357,13 @@
                 sub_header->rects[0]->h = h;
                 sub_header->rects[0]->type = SUBTITLE_BITMAP;
                 sub_header->rects[0]->pict.linesize[0] = w;
+                sub_header->rects[0]->forced = is_menu;
             }
         }
+        if (next_cmd_pos < cmd_pos) {
+            av_log(NULL, AV_LOG_ERROR, "Invalid command offset\n");
+            break;
+        }
         if (next_cmd_pos == cmd_pos)
             break;
         cmd_pos = next_cmd_pos;
@@ -456,12 +484,13 @@
                          void *data, int *data_size,
                          AVPacket *avpkt)
 {
+    DVDSubContext *ctx = (DVDSubContext*) avctx->priv_data;
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
     AVSubtitle *sub = data;
     int is_menu;
 
-    is_menu = decode_dvd_subtitles(sub, buf, buf_size);
+    is_menu = decode_dvd_subtitles(ctx, sub, buf, buf_size);
 
     if (is_menu < 0) {
     no_subtitle:
@@ -484,10 +513,63 @@
     return buf_size;
 }
 
+static int dvdsub_init(AVCodecContext *avctx)
+{
+    DVDSubContext *ctx = (DVDSubContext*) avctx->priv_data;
+    char *dataorig, *data;
+
+    if (!avctx->extradata || !avctx->extradata_size)
+        return 1;
+
+    dataorig = data = av_malloc(avctx->extradata_size+1);
+    if (!data)
+        return AVERROR(ENOMEM);
+    memcpy(data, avctx->extradata, avctx->extradata_size);
+    data[avctx->extradata_size] = '\0';
+
+    for(;;) {
+        int pos = strcspn(data, "\n\r");
+        if (pos==0 && *data==0)
+            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++;
+            }
+        } else if (strncmp("size:", data, 5) == 0) {
+            int w, h;
+            if (sscanf(data + 5, "%dx%d", &w, &h) == 2 &&
+                av_image_check_size(w, h, 0, avctx) >= 0)
+                avcodec_set_dimensions(avctx, w, h);
+        }
+
+        data += pos;
+        data += strspn(data, "\n\r");
+    }
+
+    if (ctx->has_palette) {
+        int i;
+        av_log(avctx, AV_LOG_DEBUG, "palette:");
+        for(i=0;i<16;i++)
+            av_log(avctx, AV_LOG_DEBUG, " 0x%06x", ctx->palette[i]);
+        av_log(avctx, AV_LOG_DEBUG, "\n");
+    }
+
+    av_free(dataorig);
+    return 1;
+}
+
 AVCodec ff_dvdsub_decoder = {
     .name           = "dvdsub",
     .type           = AVMEDIA_TYPE_SUBTITLE,
     .id             = AV_CODEC_ID_DVD_SUBTITLE,
+    .priv_data_size = sizeof(DVDSubContext),
+    .init           = dvdsub_init,
     .decode         = dvdsub_decode,
     .long_name      = NULL_IF_CONFIG_SMALL("DVD subtitles"),
 };
diff --git a/libavcodec/dvdsubenc.c b/libavcodec/dvdsubenc.c
index 5e362b7..2e0c37d 100644
--- a/libavcodec/dvdsubenc.c
+++ b/libavcodec/dvdsubenc.c
@@ -2,27 +2,31 @@
  * DVD subtitle encoding
  * Copyright (c) 2005 Wolfram Gloger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avcodec.h"
 #include "bytestream.h"
+#include "libavutil/avassert.h"
+#include "libavutil/bprint.h"
+#include "libavutil/imgutils.h"
 
-#undef NDEBUG
-#include <assert.h>
+typedef struct {
+    uint32_t global_palette[16];
+} DVDSubtitleContext;
 
 // ncnt is the nibble counter
 #define PUTNIBBLE(val)\
@@ -53,7 +57,7 @@
                 if (bitmap[x+len] != color)
                     break;
             color = cmap[color];
-            assert(color < 4);
+            av_assert0(color < 4);
             if (len < 0x04) {
                 PUTNIBBLE((len << 2)|color);
             } else if (len < 0x10) {
@@ -86,73 +90,247 @@
     *pq = q;
 }
 
-static int encode_dvd_subtitles(uint8_t *outbuf, int outbuf_size,
+static int color_distance(uint32_t a, uint32_t b)
+{
+    int r = 0, d, i;
+
+    for (i = 0; i < 32; i += 8) {
+        d = ((a >> i) & 0xFF) - ((b >> i) & 0xFF);
+        r += d * d;
+    }
+    return r;
+}
+
+/**
+ * Count colors used in a rectangle, quantizing alpha and grouping by
+ * nearest global palette entry.
+ */
+static void count_colors(AVCodecContext *avctx, unsigned hits[33],
+                         const AVSubtitleRect *r)
+{
+    DVDSubtitleContext *dvdc = avctx->priv_data;
+    unsigned count[256] = { 0 };
+    uint32_t *palette = (uint32_t *)r->pict.data[1];
+    uint32_t color;
+    int x, y, i, j, match, d, best_d, av_uninit(best_j);
+    uint8_t *p = r->pict.data[0];
+
+    for (y = 0; y < r->h; y++) {
+        for (x = 0; x < r->w; x++)
+            count[*(p++)]++;
+        p += r->pict.linesize[0] - r->w;
+    }
+    for (i = 0; i < 256; i++) {
+        if (!count[i]) /* avoid useless search */
+            continue;
+        color = palette[i];
+        /* 0: transparent, 1-16: semi-transparent, 17-33 opaque */
+        match = color < 0x33000000 ? 0 : color < 0xCC000000 ? 1 : 17;
+        if (match) {
+            best_d = INT_MAX;
+            for (j = 0; j < 16; j++) {
+                d = color_distance(color & 0xFFFFFF, dvdc->global_palette[j]);
+                if (d < best_d) {
+                    best_d = d;
+                    best_j = j;
+                }
+            }
+            match += best_j;
+        }
+        hits[match] += count[i];
+    }
+}
+
+static void select_palette(AVCodecContext *avctx, int out_palette[4],
+                           int out_alpha[4], unsigned hits[33])
+{
+    DVDSubtitleContext *dvdc = avctx->priv_data;
+    int i, j, bright, mult;
+    uint32_t color;
+    int selected[4] = { 0 };
+    uint32_t pseudopal[33] = { 0 };
+    uint32_t refcolor[3] = { 0x00000000, 0xFFFFFFFF, 0xFF000000 };
+
+    /* Bonus for transparent: if the rectangle fits tightly the text, the
+       background color can be quite rare, but it would be ugly without it */
+    hits[0] *= 16;
+    /* Bonus for bright colors */
+    for (i = 0; i < 16; i++) {
+        if (!(hits[1 + i] + hits[17 + i]))
+            continue; /* skip unused colors to gain time */
+        color = dvdc->global_palette[i];
+        bright = 0;
+        for (j = 0; j < 3; j++, color >>= 8)
+            bright += (color & 0xFF) < 0x40 || (color & 0xFF) >= 0xC0;
+        mult = 2 + FFMIN(bright, 2);
+        hits[ 1 + i] *= mult;
+        hits[17 + i] *= mult;
+    }
+
+    /* Select four most frequent colors */
+    for (i = 0; i < 4; i++) {
+        for (j = 0; j < 33; j++)
+            if (hits[j] > hits[selected[i]])
+                selected[i] = j;
+        hits[selected[i]] = 0;
+    }
+
+    /* Order the colors like in most DVDs:
+       0: background, 1: foreground, 2: outline */
+    for (i = 0; i < 16; i++) {
+        pseudopal[ 1 + i] = 0x80000000 | dvdc->global_palette[i];
+        pseudopal[17 + i] = 0xFF000000 | dvdc->global_palette[i];
+    }
+    for (i = 0; i < 3; i++) {
+        int best_d = color_distance(refcolor[i], pseudopal[selected[i]]);
+        for (j = i + 1; j < 4; j++) {
+            int d = color_distance(refcolor[i], pseudopal[selected[j]]);
+            if (d < best_d) {
+                FFSWAP(int, selected[i], selected[j]);
+                best_d = d;
+            }
+        }
+    }
+
+    /* Output */
+    for (i = 0; i < 4; i++) {
+        out_palette[i] = selected[i] ? (selected[i] - 1) & 0xF : 0;
+        out_alpha  [i] = !selected[i] ? 0 : selected[i] < 17 ? 0x80 : 0xFF;
+    }
+}
+
+static void build_color_map(AVCodecContext *avctx, int cmap[],
+                            const uint32_t palette[],
+                            const int out_palette[], int const out_alpha[])
+{
+    DVDSubtitleContext *dvdc = avctx->priv_data;
+    int i, j, d, best_d;
+    uint32_t pseudopal[4];
+
+    for (i = 0; i < 4; i++)
+        pseudopal[i] = (out_alpha[i] << 24) |
+                       dvdc->global_palette[out_palette[i]];
+    for (i = 0; i < 256; i++) {
+        best_d = INT_MAX;
+        for (j = 0; j < 4; j++) {
+            d = color_distance(pseudopal[j], palette[i]);
+            if (d < best_d) {
+                cmap[i] = j;
+                best_d = d;
+            }
+        }
+    }
+}
+
+static void copy_rectangle(AVSubtitleRect *dst, AVSubtitleRect *src, int cmap[])
+{
+    int x, y;
+    uint8_t *p, *q;
+
+    p = src->pict.data[0];
+    q = dst->pict.data[0] + (src->x - dst->x) +
+                            (src->y - dst->y) * dst->pict.linesize[0];
+    for (y = 0; y < src->h; y++) {
+        for (x = 0; x < src->w; x++)
+            *(q++) = cmap[*(p++)];
+        p += src->pict.linesize[0] - src->w;
+        q += dst->pict.linesize[0] - src->w;
+    }
+}
+
+static int encode_dvd_subtitles(AVCodecContext *avctx,
+                                uint8_t *outbuf, int outbuf_size,
                                 const AVSubtitle *h)
 {
+    DVDSubtitleContext *dvdc = avctx->priv_data;
     uint8_t *q, *qq;
-    int object_id;
-    int offset1[20], offset2[20];
-    int i, imax, color, alpha, rects = h->num_rects;
-    unsigned long hmax;
-    unsigned long hist[256];
-    int           cmap[256];
+    int offset1, offset2;
+    int i, rects = h->num_rects, ret;
+    unsigned global_palette_hits[33] = { 0 };
+    int cmap[256];
+    int out_palette[4];
+    int out_alpha[4];
+    AVSubtitleRect vrect;
+    uint8_t *vrect_data = NULL;
+    int x2, y2;
 
     if (rects == 0 || h->rects == NULL)
-        return -1;
-    if (rects > 20)
-        rects = 20;
-
-    // analyze bitmaps, compress to 4 colors
-    for (i=0; i<256; ++i) {
-        hist[i] = 0;
-        cmap[i] = 0;
-    }
-    for (object_id = 0; object_id < rects; object_id++)
-        for (i=0; i<h->rects[object_id]->w*h->rects[object_id]->h; ++i) {
-            color = h->rects[object_id]->pict.data[0][i];
-            // only count non-transparent pixels
-            alpha = ((uint32_t*)h->rects[object_id]->pict.data[1])[color] >> 24;
-            hist[color] += alpha;
+        return AVERROR(EINVAL);
+    for (i = 0; i < rects; i++)
+        if (h->rects[i]->type != SUBTITLE_BITMAP) {
+            av_log(avctx, AV_LOG_ERROR, "Bitmap subtitle required\n");
+            return AVERROR(EINVAL);
         }
-    for (color=3;; --color) {
-        hmax = 0;
-        imax = 0;
-        for (i=0; i<256; ++i)
-            if (hist[i] > hmax) {
-                imax = i;
-                hmax = hist[i];
-            }
-        if (hmax == 0)
-            break;
-        if (color == 0)
-            color = 3;
-        av_log(NULL, AV_LOG_DEBUG, "dvd_subtitle hist[%d]=%ld -> col %d\n",
-               imax, hist[imax], color);
-        cmap[imax] = color;
-        hist[imax] = 0;
+    vrect = *h->rects[0];
+
+    if (rects > 1) {
+        /* DVD subtitles can have only one rectangle: build a virtual
+           rectangle containing all actual rectangles.
+           The data of the rectangles will be copied later, when the palette
+           is decided, because the rectangles may have different palettes. */
+        int xmin = h->rects[0]->x, xmax = xmin + h->rects[0]->w;
+        int ymin = h->rects[0]->y, ymax = ymin + h->rects[0]->h;
+        for (i = 1; i < rects; i++) {
+            xmin = FFMIN(xmin, h->rects[i]->x);
+            ymin = FFMIN(ymin, h->rects[i]->y);
+            xmax = FFMAX(xmax, h->rects[i]->x + h->rects[i]->w);
+            ymax = FFMAX(ymax, h->rects[i]->y + h->rects[i]->h);
+        }
+        vrect.x = xmin;
+        vrect.y = ymin;
+        vrect.w = xmax - xmin;
+        vrect.h = ymax - ymin;
+        if ((ret = av_image_check_size(vrect.w, vrect.h, 0, avctx)) < 0)
+            return ret;
+
+        /* Count pixels outside the virtual rectangle as transparent */
+        global_palette_hits[0] = vrect.w * vrect.h;
+        for (i = 0; i < rects; i++)
+            global_palette_hits[0] -= h->rects[i]->w * h->rects[i]->h;
     }
 
+    for (i = 0; i < rects; i++)
+        count_colors(avctx, global_palette_hits, h->rects[i]);
+    select_palette(avctx, out_palette, out_alpha, global_palette_hits);
+
+    if (rects > 1) {
+        if (!(vrect_data = av_calloc(vrect.w, vrect.h)))
+            return AVERROR(ENOMEM);
+        vrect.pict.data    [0] = vrect_data;
+        vrect.pict.linesize[0] = vrect.w;
+        for (i = 0; i < rects; i++) {
+            build_color_map(avctx, cmap, (uint32_t *)h->rects[i]->pict.data[1],
+                            out_palette, out_alpha);
+            copy_rectangle(&vrect, h->rects[i], cmap);
+        }
+        for (i = 0; i < 4; i++)
+            cmap[i] = i;
+    } else {
+        build_color_map(avctx, cmap, (uint32_t *)h->rects[0]->pict.data[1],
+                        out_palette, out_alpha);
+    }
+
+    av_log(avctx, AV_LOG_DEBUG, "Selected palette:");
+    for (i = 0; i < 4; i++)
+        av_log(avctx, AV_LOG_DEBUG, " 0x%06x@@%02x (0x%x,0x%x)",
+               dvdc->global_palette[out_palette[i]], out_alpha[i],
+               out_palette[i], out_alpha[i] >> 4);
+    av_log(avctx, AV_LOG_DEBUG, "\n");
 
     // encode data block
     q = outbuf + 4;
-    for (object_id = 0; object_id < rects; object_id++) {
-        offset1[object_id] = q - outbuf;
-        // worst case memory requirement: 1 nibble per pixel..
-        if ((q - outbuf) + h->rects[object_id]->w*h->rects[object_id]->h/2
-            + 17*rects + 21 > outbuf_size) {
-            av_log(NULL, AV_LOG_ERROR, "dvd_subtitle too big\n");
-            return -1;
-        }
-        dvd_encode_rle(&q, h->rects[object_id]->pict.data[0],
-                       h->rects[object_id]->w*2,
-                       h->rects[object_id]->w, h->rects[object_id]->h >> 1,
-                       cmap);
-        offset2[object_id] = q - outbuf;
-        dvd_encode_rle(&q, h->rects[object_id]->pict.data[0] + h->rects[object_id]->w,
-                       h->rects[object_id]->w*2,
-                       h->rects[object_id]->w, h->rects[object_id]->h >> 1,
-                       cmap);
+    offset1 = q - outbuf;
+    // worst case memory requirement: 1 nibble per pixel..
+    if ((q - outbuf) + vrect.w * vrect.h / 2 + 17 + 21 > outbuf_size) {
+        av_log(NULL, AV_LOG_ERROR, "dvd_subtitle too big\n");
+        ret = AVERROR_BUFFER_TOO_SMALL;
+        goto fail;
     }
+    dvd_encode_rle(&q, vrect.pict.data[0], vrect.w * 2,
+                   vrect.w, (vrect.h + 1) >> 1, cmap);
+    offset2 = q - outbuf;
+    dvd_encode_rle(&q, vrect.pict.data[0] + vrect.w, vrect.w * 2,
+                   vrect.w, vrect.h >> 1, cmap);
 
     // set data packet size
     qq = outbuf + 2;
@@ -160,34 +338,33 @@
 
     // send start display command
     bytestream_put_be16(&q, (h->start_display_time*90) >> 10);
-    bytestream_put_be16(&q, (q - outbuf) /*- 2 */ + 8 + 12*rects + 2);
+    bytestream_put_be16(&q, (q - outbuf) /*- 2 */ + 8 + 12 + 2);
     *q++ = 0x03; // palette - 4 nibbles
-    *q++ = 0x03; *q++ = 0x7f;
+    *q++ = (out_palette[3] << 4) | out_palette[2];
+    *q++ = (out_palette[1] << 4) | out_palette[0];
     *q++ = 0x04; // alpha - 4 nibbles
-    *q++ = 0xf0; *q++ = 0x00;
-    //*q++ = 0x0f; *q++ = 0xff;
+    *q++ = (out_alpha[3] & 0xF0) | (out_alpha[2] >> 4);
+    *q++ = (out_alpha[1] & 0xF0) | (out_alpha[0] >> 4);
 
-    // XXX not sure if more than one rect can really be encoded..
     // 12 bytes per rect
-    for (object_id = 0; object_id < rects; object_id++) {
-        int x2 = h->rects[object_id]->x + h->rects[object_id]->w - 1;
-        int y2 = h->rects[object_id]->y + h->rects[object_id]->h - 1;
+    x2 = vrect.x + vrect.w - 1;
+    y2 = vrect.y + vrect.h - 1;
 
-        *q++ = 0x05;
-        // x1 x2 -> 6 nibbles
-        *q++ = h->rects[object_id]->x >> 4;
-        *q++ = (h->rects[object_id]->x << 4) | ((x2 >> 8) & 0xf);
-        *q++ = x2;
-        // y1 y2 -> 6 nibbles
-        *q++ = h->rects[object_id]->y >> 4;
-        *q++ = (h->rects[object_id]->y << 4) | ((y2 >> 8) & 0xf);
-        *q++ = y2;
+    *q++ = 0x05;
+    // x1 x2 -> 6 nibbles
+    *q++ = vrect.x >> 4;
+    *q++ = (vrect.x << 4) | ((x2 >> 8) & 0xf);
+    *q++ = x2;
+    // y1 y2 -> 6 nibbles
+    *q++ = vrect.y >> 4;
+    *q++ = (vrect.y << 4) | ((y2 >> 8) & 0xf);
+    *q++ = y2;
 
-        *q++ = 0x06;
-        // offset1, offset2
-        bytestream_put_be16(&q, offset1[object_id]);
-        bytestream_put_be16(&q, offset2[object_id]);
-    }
+    *q++ = 0x06;
+    // offset1, offset2
+    bytestream_put_be16(&q, offset1);
+    bytestream_put_be16(&q, offset2);
+
     *q++ = 0x01; // start command
     *q++ = 0xff; // terminating command
 
@@ -201,7 +378,41 @@
     bytestream_put_be16(&qq, q - outbuf);
 
     av_log(NULL, AV_LOG_DEBUG, "subtitle_packet size=%td\n", q - outbuf);
-    return q - outbuf;
+    ret = q - outbuf;
+
+fail:
+    av_free(vrect_data);
+    return ret;
+}
+
+static int dvdsub_init(AVCodecContext *avctx)
+{
+    DVDSubtitleContext *dvdc = avctx->priv_data;
+    static const uint32_t default_palette[16] = {
+        0x000000, 0x0000FF, 0x00FF00, 0xFF0000,
+        0xFFFF00, 0xFF00FF, 0x00FFFF, 0xFFFFFF,
+        0x808000, 0x8080FF, 0x800080, 0x80FF80,
+        0x008080, 0xFF8080, 0x555555, 0xAAAAAA,
+    };
+    AVBPrint extradata;
+    int i, ret;
+
+    av_assert0(sizeof(dvdc->global_palette) == sizeof(default_palette));
+    memcpy(dvdc->global_palette, default_palette, sizeof(dvdc->global_palette));
+
+    av_bprint_init(&extradata, 0, 1);
+    if (avctx->width && avctx->height)
+        av_bprintf(&extradata, "size: %dx%d\n", avctx->width, avctx->height);
+    av_bprintf(&extradata, "palette:");
+    for (i = 0; i < 16; i++)
+        av_bprintf(&extradata, " %06"PRIx32"%c",
+                   dvdc->global_palette[i] & 0xFFFFFF, i < 15 ? ',' : '\n');
+
+    if ((ret = av_bprint_finalize(&extradata, (char **)&avctx->extradata)) < 0)
+        return ret;
+    avctx->extradata_size = extradata.len;
+
+    return 0;
 }
 
 static int dvdsub_encode(AVCodecContext *avctx,
@@ -211,7 +422,7 @@
     //DVDSubtitleContext *s = avctx->priv_data;
     int ret;
 
-    ret = encode_dvd_subtitles(buf, buf_size, sub);
+    ret = encode_dvd_subtitles(avctx, buf, buf_size, sub);
     return ret;
 }
 
@@ -219,6 +430,8 @@
     .name           = "dvdsub",
     .type           = AVMEDIA_TYPE_SUBTITLE,
     .id             = AV_CODEC_ID_DVD_SUBTITLE,
+    .init           = dvdsub_init,
     .encode_sub     = dvdsub_encode,
     .long_name      = NULL_IF_CONFIG_SMALL("DVD subtitles"),
+    .priv_data_size = sizeof(DVDSubtitleContext),
 };
diff --git a/libavcodec/dwt.c b/libavcodec/dwt.c
index 93cf2c6..d36d25d 100644
--- a/libavcodec/dwt.c
+++ b/libavcodec/dwt.c
@@ -1,27 +1,30 @@
 /*
  * Copyright (C) 2004-2010 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2008 David Conrad
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/attributes.h"
+#include "libavutil/avassert.h"
 #include "libavutil/common.h"
 #include "dsputil.h"
 #include "dwt.h"
+#include "libavcodec/x86/dwt.h"
 
 int ff_slice_buffer_init(slice_buffer *buf, int line_count,
                          int max_allocated_lines, int line_width,
@@ -38,7 +41,7 @@
         return AVERROR(ENOMEM);
     buf->data_stack  = av_malloc(sizeof(IDWTELEM *) * max_allocated_lines);
     if (!buf->data_stack) {
-        av_free(buf->line);
+        av_freep(&buf->line);
         return AVERROR(ENOMEM);
     }
 
@@ -46,9 +49,9 @@
         buf->data_stack[i] = av_malloc(sizeof(IDWTELEM) * line_width);
         if (!buf->data_stack[i]) {
             for (i--; i >=0; i--)
-                av_free(buf->data_stack[i]);
-            av_free(buf->data_stack);
-            av_free(buf->line);
+                av_freep(&buf->data_stack[i]);
+            av_freep(&buf->data_stack);
+            av_freep(&buf->line);
             return AVERROR(ENOMEM);
         }
     }
@@ -61,8 +64,8 @@
 {
     IDWTELEM *buffer;
 
-    assert(buf->data_stack_top >= 0);
-//  assert(!buf->line[line]);
+    av_assert0(buf->data_stack_top >= 0);
+//  av_assert1(!buf->line[line]);
     if (buf->line[line])
         return buf->line[line];
 
@@ -77,8 +80,8 @@
 {
     IDWTELEM *buffer;
 
-    assert(line >= 0 && line < buf->line_count);
-    assert(buf->line[line]);
+    av_assert1(line >= 0 && line < buf->line_count);
+    av_assert1(buf->line[line]);
 
     buffer = buf->line[line];
     buf->data_stack_top++;
@@ -155,7 +158,7 @@
     const int w            = (width >> 1) - 1 + (highpass & width);
     int i;
 
-    assert(shift == 4);
+    av_assert1(shift == 4);
 #define LIFTS(src, ref, inv)                                            \
     ((inv) ? (src) + (((ref) + 4 * (src)) >> shift)                     \
            : -((-16 * (src) + (ref) + add /                             \
@@ -793,7 +796,7 @@
     ff_spatial_dwt(tmp, tmp2, w, h, 32, type, dec_count);
 
     s = 0;
-    assert(w == h);
+    av_assert1(w == h);
     for (level = 0; level < dec_count; level++)
         for (ori = level ? 1 : 0; ori < 4; ori++) {
             int size   = w >> (dec_count - level);
@@ -808,7 +811,7 @@
                     s += FFABS(v);
                 }
         }
-    assert(s >= 0);
+    av_assert1(s >= 0);
     return s >> 9;
 }
 
@@ -859,3 +862,541 @@
     if (HAVE_MMX)
         ff_dwt_init_x86(c);
 }
+
+
+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/dwt.h b/libavcodec/dwt.h
index e06f3f9..d82e510 100644
--- a/libavcodec/dwt.h
+++ b/libavcodec/dwt.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2004-2010 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,7 +26,12 @@
 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;
@@ -46,7 +51,31 @@
     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);
@@ -55,9 +84,71 @@
                              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;
 
-#define MAX_DECOMPOSITIONS 8
+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
diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c
index 84159a4..2155195 100644
--- a/libavcodec/dxa.c
+++ b/libavcodec/dxa.c
@@ -2,20 +2,20 @@
  * Feeble Files/ScummVM DXA decoder
  * Copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -209,7 +209,7 @@
             r = *buf++;
             g = *buf++;
             b = *buf++;
-            c->pal[i] = (r << 16) | (g << 8) | b;
+            c->pal[i] = 0xFF << 24 | r << 16 | g << 8 | b;
         }
         pc = 1;
         buf_size -= 768+4;
@@ -294,6 +294,9 @@
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
+    avcodec_get_frame_defaults(&c->pic);
+    avcodec_get_frame_defaults(&c->prev);
+
     c->dsize = avctx->width * avctx->height * 2;
     if((c->decomp_buf = av_malloc(c->dsize)) == NULL) {
         av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
index 71c8405..d866071 100644
--- a/libavcodec/dxva2.c
+++ b/libavcodec/dxva2.c
@@ -3,20 +3,20 @@
  *
  * copyright (c) 2010 Laurent Aimar
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dxva2.h b/libavcodec/dxva2.h
index c06f1f3..7d27ca5 100644
--- a/libavcodec/dxva2.h
+++ b/libavcodec/dxva2.h
@@ -3,20 +3,20 @@
  *
  * copyright (c) 2009 Laurent Aimar
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -45,7 +45,7 @@
 
 /**
  * This structure is used to provides the necessary configurations and data
- * to the DXVA2 Libav HWAccel implementation.
+ * to the DXVA2 FFmpeg HWAccel implementation.
  *
  * The application must make it available as AVCodecContext.hwaccel_context.
  */
@@ -76,7 +76,7 @@
     uint64_t workaround;
 
     /**
-     * Private to the Libav AVHWAccel implementation
+     * Private to the FFmpeg AVHWAccel implementation
      */
     unsigned report_id;
 };
diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c
index 2fd0767..f7d4e5d 100644
--- a/libavcodec/dxva2_h264.c
+++ b/libavcodec/dxva2_h264.c
@@ -3,20 +3,20 @@
  *
  * copyright (c) 2009 Laurent Aimar
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -96,7 +96,7 @@
                                         ((h->sps.mb_aff &&
                                         (s->picture_structure == PICT_FRAME)) <<  1) |
                                         (h->sps.residual_color_transform_flag <<  2) |
-                                        /* sp_for_switch_flag (not implemented by Libav) */
+                                        /* sp_for_switch_flag (not implemented by FFmpeg) */
                                         (0                                    <<  3) |
                                         (h->sps.chroma_format_idc             <<  4) |
                                         ((h->nal_ref_idc != 0)                <<  6) |
@@ -150,8 +150,8 @@
     pp->deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present;
     pp->redundant_pic_cnt_present_flag= h->pps.redundant_pic_cnt_present;
     pp->Reserved8BitsB                = 0;
-    pp->slice_group_change_rate_minus1= 0;  /* XXX not implemented by Libav */
-    //pp->SliceGroupMap[810];               /* XXX not implemented by Libav */
+    pp->slice_group_change_rate_minus1= 0;  /* XXX not implemented by FFmpeg */
+    //pp->SliceGroupMap[810];               /* XXX not implemented by FFmpeg */
 }
 
 static void fill_scaling_lists(struct dxva_context *ctx, const H264Context *h, DXVA_Qmatrix_H264 *qm)
@@ -259,7 +259,7 @@
             }
         }
     }
-    slice->slice_qs_delta    = 0; /* XXX not implemented by Libav */
+    slice->slice_qs_delta    = 0; /* XXX not implemented by FFmpeg */
     slice->slice_qp_delta    = s->qscale - h->pps.init_qp;
     slice->redundant_pic_cnt = h->redundant_pic_count;
     if (h->slice_type == AV_PICTURE_TYPE_B)
@@ -293,7 +293,7 @@
     /* Create an annex B bitstream buffer with only slice NAL and finalize slice */
     if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
                                                DXVA2_BitStreamDateBufferType,
-                                               &dxva_data, &dxva_size)))
+                                               (void **)&dxva_data, &dxva_size)))
         return -1;
     current = dxva_data;
     end = dxva_data + dxva_size;
diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h
index e2305b1..fcf45bc 100644
--- a/libavcodec/dxva2_internal.h
+++ b/libavcodec/dxva2_internal.h
@@ -3,20 +3,20 @@
  *
  * copyright (c) 2010 Laurent Aimar
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/dxva2_mpeg2.c b/libavcodec/dxva2_mpeg2.c
index fa6ae7b..f050ed9 100644
--- a/libavcodec/dxva2_mpeg2.c
+++ b/libavcodec/dxva2_mpeg2.c
@@ -3,20 +3,20 @@
  *
  * copyright (c) 2010 Laurent Aimar
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -109,10 +109,10 @@
         qm->bNewQmatrix[i] = 1;
     for (i = 0; i < 64; i++) {
         int n = s->dsp.idct_permutation[ff_zigzag_direct[i]];
-        qm->Qmatrix[0][i] = s->intra_matrix[n];;
-        qm->Qmatrix[1][i] = s->inter_matrix[n];;
-        qm->Qmatrix[2][i] = s->chroma_intra_matrix[n];;
-        qm->Qmatrix[3][i] = s->chroma_inter_matrix[n];;
+        qm->Qmatrix[0][i] = s->intra_matrix[n];
+        qm->Qmatrix[1][i] = s->inter_matrix[n];
+        qm->Qmatrix[2][i] = s->chroma_intra_matrix[n];
+        qm->Qmatrix[3][i] = s->chroma_inter_matrix[n];
     }
 }
 
@@ -160,7 +160,7 @@
 
     if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
                                               DXVA2_BitStreamDateBufferType,
-                                              &dxva_data, &dxva_size)))
+                                              (void **)&dxva_data, &dxva_size)))
         return -1;
     current = dxva_data;
     end = dxva_data + dxva_size;
diff --git a/libavcodec/dxva2_vc1.c b/libavcodec/dxva2_vc1.c
index 5aed2f3..e47db4d 100644
--- a/libavcodec/dxva2_vc1.c
+++ b/libavcodec/dxva2_vc1.c
@@ -3,20 +3,20 @@
  *
  * copyright (c) 2010 Laurent Aimar
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -178,7 +178,7 @@
 
     if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
                                               DXVA2_BitStreamDateBufferType,
-                                              &dxva_data, &dxva_size)))
+                                              (void **)&dxva_data, &dxva_size)))
         return -1;
 
     result = data_size <= dxva_size ? 0 : -1;
diff --git a/libavcodec/eac3_data.c b/libavcodec/eac3_data.c
index b0416f3..b159e16 100644
--- a/libavcodec/eac3_data.c
+++ b/libavcodec/eac3_data.c
@@ -2,20 +2,20 @@
  * E-AC-3 tables
  * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/eac3_data.h b/libavcodec/eac3_data.h
index 4d88ce0..10a67f1 100644
--- a/libavcodec/eac3_data.h
+++ b/libavcodec/eac3_data.h
@@ -2,20 +2,20 @@
  * E-AC-3 tables
  * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/eac3dec.c b/libavcodec/eac3dec.c
index 7072f78..91e35ad 100644
--- a/libavcodec/eac3dec.c
+++ b/libavcodec/eac3dec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com>
  * Copyright (c) 2008 Justin Ruggles
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -491,7 +491,7 @@
     s->skip_syntax       = get_bits1(gbc);
     parse_spx_atten_data = get_bits1(gbc);
 
-    /* coupling strategy occurance and coupling use per block */
+    /* coupling strategy occurrence and coupling use per block */
     num_cpl_blocks = 0;
     if (s->channel_mode > 1) {
         for (blk = 0; blk < s->num_blocks; blk++) {
diff --git a/libavcodec/eac3enc.c b/libavcodec/eac3enc.c
index 3c7a611..bb9ef4f 100644
--- a/libavcodec/eac3enc.c
+++ b/libavcodec/eac3enc.c
@@ -32,9 +32,13 @@
 
 #define AC3ENC_TYPE AC3ENC_TYPE_EAC3
 #include "ac3enc_opts_template.c"
-static const AVClass eac3enc_class = { "E-AC-3 Encoder", av_default_item_name,
-                                       ac3_options, LIBAVUTIL_VERSION_INT };
 
+static const AVClass eac3enc_class = {
+    .class_name = "E-AC-3 Encoder",
+    .item_name  = av_default_item_name,
+    .option     = ac3_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
 
 /**
  * LUT for finding a matching frame exponent strategy index from a set of
diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c
index 532bf94..4960011 100644
--- a/libavcodec/eacmv.c
+++ b/libavcodec/eacmv.c
@@ -2,20 +2,20 @@
  * Electronic Arts CMV Video Decoder
  * Copyright (c) 2007-2008 Peter Ross
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
@@ -44,6 +44,10 @@
 
 static av_cold int cmv_decode_init(AVCodecContext *avctx){
     CmvContext *s = avctx->priv_data;
+    avcodec_get_frame_defaults(&s->frame);
+    avcodec_get_frame_defaults(&s->last_frame);
+    avcodec_get_frame_defaults(&s->last2_frame);
+
     s->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
     return 0;
@@ -107,9 +111,10 @@
         }else{  /* inter using last frame as reference */
             int xoffset = (buf[i] & 0xF) - 7;
             int yoffset = ((buf[i] >> 4)) - 7;
-            cmv_motcomp(s->frame.data[0], s->frame.linesize[0],
-                      s->last_frame.data[0], s->last_frame.linesize[0],
-                      x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height);
+            if (s->last_frame.data[0])
+                cmv_motcomp(s->frame.data[0], s->frame.linesize[0],
+                          s->last_frame.data[0], s->last_frame.linesize[0],
+                          x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height);
         }
         i++;
     }
@@ -137,7 +142,7 @@
 
     buf += 16;
     for (i=pal_start; i<pal_start+pal_count && i<AVPALETTE_COUNT && buf_end - buf >= 3; i++) {
-        s->palette[i] = AV_RB24(buf);
+        s->palette[i] = 0xFF << 24 | AV_RB24(buf);
         buf += 3;
     }
 }
@@ -158,8 +163,11 @@
         return AVERROR_INVALIDDATA;
 
     if (AV_RL32(buf)==MVIh_TAG||AV_RB32(buf)==MVIh_TAG) {
+        unsigned size = AV_RL32(buf + 4);
         cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end);
-        return buf_size;
+        if (size > buf_end - buf - EA_PREAMBLE_SIZE)
+            return -1;
+        buf += size;
     }
 
     if (av_image_check_size(s->width, s->height, 0, s->avctx))
@@ -171,8 +179,10 @@
     FFSWAP(AVFrame, s->last_frame, s->last2_frame);
     FFSWAP(AVFrame, s->frame, s->last_frame);
 
-    s->frame.reference = 1;
-    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
+    s->frame.reference = 3;
+    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID |
+                            FF_BUFFER_HINTS_READABLE |
+                            FF_BUFFER_HINTS_PRESERVE;
     if (avctx->get_buffer(avctx, &s->frame)<0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
diff --git a/libavcodec/eaidct.c b/libavcodec/eaidct.c
index 9f2d5cc..175c1c4 100644
--- a/libavcodec/eaidct.c
+++ b/libavcodec/eaidct.c
@@ -2,20 +2,20 @@
  * Electronic Arts TGQ/TQI/MAD IDCT algorithm
  * Copyright (c) 2007-2008 Peter Ross <pross@xvid.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/eaidct.h b/libavcodec/eaidct.h
index 4c0b5ae..a436673 100644
--- a/libavcodec/eaidct.h
+++ b/libavcodec/eaidct.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c
index c45b588..2805195 100644
--- a/libavcodec/eamad.c
+++ b/libavcodec/eamad.c
@@ -2,20 +2,20 @@
  * Electronic Arts Madcow Video Decoder
  * Copyright (c) 2007-2009 Peter Ross
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
@@ -82,15 +82,21 @@
                               int j, int mv_x, int mv_y, int add)
 {
     if (j < 4) {
+        unsigned offset = (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x;
+        if (offset >= (t->avctx->height - 7) * t->last_frame.linesize[0] - 7)
+            return;
         comp(t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3),
              t->frame.linesize[0],
-             t->last_frame.data[0] + (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x,
+             t->last_frame.data[0] + offset,
              t->last_frame.linesize[0], add);
     } else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) {
         int index = j - 3;
+        unsigned offset = (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2);
+        if (offset >= (t->avctx->height/2 - 7) * t->last_frame.linesize[index] - 7)
+            return;
         comp(t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x * 8,
              t->frame.linesize[index],
-             t->last_frame.data[index] + (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2),
+             t->last_frame.data[index] + offset,
              t->last_frame.linesize[index], add);
     }
 }
@@ -109,7 +115,7 @@
     }
 }
 
-static inline void decode_block_intra(MadContext *s, DCTELEM * block)
+static inline int decode_block_intra(MadContext *s, DCTELEM * block)
 {
     int level, i, j, run;
     RLTable *rl = &ff_rl_mpeg1;
@@ -159,13 +165,14 @@
             }
             if (i > 63) {
                 av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
-                return;
+                return -1;
             }
 
             block[j] = level;
         }
         CLOSE_READER(re, &s->gb);
     }
+    return 0;
 }
 
 static int decode_motion(GetBitContext *gb)
@@ -179,7 +186,7 @@
     return value;
 }
 
-static void decode_mb(MadContext *s, int inter)
+static int decode_mb(MadContext *s, int inter)
 {
     int mv_map = 0;
     int mv_x, mv_y;
@@ -191,21 +198,22 @@
             mv_map = v ? get_bits(&s->gb, 6) : 63;
             mv_x = decode_motion(&s->gb);
             mv_y = decode_motion(&s->gb);
-        } else {
-            mv_map = 0;
         }
     }
 
     for (j=0; j<6; j++) {
         if (mv_map & (1<<j)) {  // mv_x and mv_y are guarded by mv_map
             int add = 2*decode_motion(&s->gb);
-            comp_block(s, s->mb_x, s->mb_y, j, mv_x, mv_y, add);
+            if (s->last_frame.data[0])
+                comp_block(s, s->mb_x, s->mb_y, j, mv_x, mv_y, add);
         } else {
             s->dsp.clear_block(s->block);
-            decode_block_intra(s, s->block);
+            if(decode_block_intra(s, s->block) < 0)
+                return -1;
             idct_put(s, s->block, s->mb_x, s->mb_y, j);
         }
     }
+    return 0;
 }
 
 static void calc_quant_matrix(MadContext *s, int qscale)
@@ -248,14 +256,18 @@
     buf += 16;
 
     if (avctx->width != width || avctx->height != height) {
+        if((width * height)/2048*7 > buf_end-buf)
+            return -1;
         if (av_image_check_size(width, height, 0, avctx) < 0)
             return -1;
         avcodec_set_dimensions(avctx, width, height);
         if (s->frame.data[0])
             avctx->release_buffer(avctx, &s->frame);
+        if (s->last_frame.data[0])
+            avctx->release_buffer(avctx, &s->last_frame);
     }
 
-    s->frame.reference = 1;
+    s->frame.reference = 3;
     if (!s->frame.data[0]) {
         if (avctx->get_buffer(avctx, &s->frame) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
@@ -267,11 +279,13 @@
     if (!s->bitstream_buf)
         return AVERROR(ENOMEM);
     s->dsp.bswap16_buf(s->bitstream_buf, (const uint16_t*)buf, (buf_end-buf)/2);
+    memset((uint8_t*)s->bitstream_buf + (buf_end-buf), 0, FF_INPUT_BUFFER_PADDING_SIZE);
     init_get_bits(&s->gb, s->bitstream_buf, 8*(buf_end-buf));
 
     for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++)
         for (s->mb_x=0; s->mb_x < (avctx->width +15)/16; s->mb_x++)
-            decode_mb(s, inter);
+            if(decode_mb(s, inter) < 0)
+                return -1;
 
     *data_size = sizeof(AVFrame);
     *(AVFrame*)data = s->frame;
diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c
index d6ee635..5114b20 100644
--- a/libavcodec/eatgq.c
+++ b/libavcodec/eatgq.c
@@ -2,20 +2,20 @@
  * Electronic Arts TGQ Video Decoder
  * Copyright (c) 2007-2008 Peter Ross <pross@xvid.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
@@ -149,7 +149,7 @@
     mode = bytestream2_get_byte(&s->gb);
     if (mode>12) {
         GetBitContext gb;
-        init_get_bits(&gb, s->gb.buffer, FFMIN(s->gb.buffer_end - s->gb.buffer, mode) * 8);
+        init_get_bits(&gb, s->gb.buffer, FFMIN(bytestream2_get_bytes_left(&s->gb), mode) * 8);
         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);
diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c
index b29c994..45f9fc7 100644
--- a/libavcodec/eatgv.c
+++ b/libavcodec/eatgv.c
@@ -2,20 +2,20 @@
  * Electronic Arts TGV Video Decoder
  * Copyright (c) 2007-2008 Peter Ross
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
@@ -55,6 +55,8 @@
     s->avctx = avctx;
     avctx->time_base = (AVRational){1, 15};
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
+    avcodec_get_frame_defaults(&s->frame);
+    avcodec_get_frame_defaults(&s->last_frame);
     return 0;
 }
 
@@ -72,7 +74,7 @@
     else
         src += 2;
 
-    if (src+3>src_end)
+    if (src_end - src < 3)
         return -1;
     size = AV_RB24(src);
     src += 3;
@@ -145,7 +147,7 @@
     int mvbits;
     const unsigned char *blocks_raw;
 
-    if(buf+12>buf_end)
+    if(buf_end - buf < 12)
         return -1;
 
     num_mvs           = AV_RL16(&buf[0]);
@@ -174,7 +176,7 @@
     /* read motion vectors */
     mvbits = (num_mvs*2*10+31) & ~31;
 
-    if (buf+(mvbits>>3)+16*num_blocks_raw+8*num_blocks_packed>buf_end)
+    if (buf_end - buf < (mvbits>>3)+16*num_blocks_raw+8*num_blocks_packed)
         return -1;
 
     init_get_bits(&gb, buf, mvbits);
@@ -214,8 +216,10 @@
             int my = y * 4 + s->mv_codebook[vector][1];
 
             if (   mx < 0 || mx + 4 > s->avctx->width
-                || my < 0 || my + 4 > s->avctx->height)
+                || 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];
@@ -258,12 +262,15 @@
     const uint8_t *buf_end = buf + buf_size;
     int chunk_type;
 
+    if (buf_end - buf < EA_PREAMBLE_SIZE)
+        return AVERROR_INVALIDDATA;
+
     chunk_type = AV_RL32(&buf[0]);
     buf += EA_PREAMBLE_SIZE;
 
     if (chunk_type==kVGT_TAG) {
         int pal_count, i;
-        if(buf+12>buf_end) {
+        if(buf_end - buf < 12) {
             av_log(avctx, AV_LOG_WARNING, "truncated header\n");
             return -1;
         }
@@ -278,8 +285,8 @@
 
         pal_count = AV_RL16(&buf[6]);
         buf += 12;
-        for(i=0; i<pal_count && i<AVPALETTE_COUNT && buf+2<buf_end; i++) {
-            s->palette[i] = AV_RB24(buf);
+        for(i=0; i<pal_count && i<AVPALETTE_COUNT && buf_end - buf >= 3; i++) {
+            s->palette[i] = 0xFF << 24 | AV_RB24(buf);
             buf += 3;
         }
     }
@@ -290,7 +297,7 @@
     /* shuffle */
     FFSWAP(AVFrame, s->frame, s->last_frame);
     if (!s->frame.data[0]) {
-        s->frame.reference = 1;
+        s->frame.reference = 3;
         s->frame.buffer_hints = FF_BUFFER_HINTS_VALID;
         s->frame.linesize[0] = s->width;
 
diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c
index 4c07327..62833d5 100644
--- a/libavcodec/eatqi.c
+++ b/libavcodec/eatqi.c
@@ -2,20 +2,20 @@
  * Electronic Arts TQI Video Decoder
  * Copyright (c) 2007-2009 Peter Ross <pross@xvid.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
@@ -133,9 +133,10 @@
     for (s->mb_x=0; s->mb_x<(avctx->width+15)/16; s->mb_x++)
     {
         if (tqi_decode_mb(s, t->block) < 0)
-            break;
+            goto end;
         tqi_idct_put(t, t->block);
     }
+    end:
 
     *data_size = sizeof(AVFrame);
     *(AVFrame*)data = t->frame;
diff --git a/libavcodec/elbg.c b/libavcodec/elbg.c
index 0aa8e16..2707599 100644
--- a/libavcodec/elbg.c
+++ b/libavcodec/elbg.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2007 Vitor Sessak <vitor1001@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,7 @@
 
 #include <string.h>
 
+#include "libavutil/avassert.h"
 #include "libavutil/common.h"
 #include "libavutil/lfg.h"
 #include "elbg.h"
@@ -111,7 +112,7 @@
     while (elbg->utility_inc[i] < r)
         i++;
 
-    assert(elbg->cells[i]);
+    av_assert2(elbg->cells[i]);
 
     return i;
 }
@@ -189,7 +190,7 @@
 
 /**
  * Add the points in the low utility cell to its closest cell. Split the high
- * utility cell, putting the separed points in the (now empty) low utility
+ * utility cell, putting the separate points in the (now empty) low utility
  * cell.
  *
  * @param elbg         Internal elbg data
diff --git a/libavcodec/elbg.h b/libavcodec/elbg.h
index b8ea489..e6f577e 100644
--- a/libavcodec/elbg.h
+++ b/libavcodec/elbg.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2007 Vitor Sessak <vitor1001@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
index ae9ef68..7ddc5ac 100644
--- a/libavcodec/error_resilience.c
+++ b/libavcodec/error_resilience.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -46,23 +46,33 @@
     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));
-        assert(ref >= 0);
+        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;
+        }
         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);
-        assert(!FRAME_MBAFF);
+        h->mb_mbaff =
+        h->mb_field_decoding_flag = 0;
         ff_h264_hl_decode_mb(h);
     } else {
         assert(ref == 0);
@@ -78,7 +88,7 @@
 {
     if (s->codec_id == AV_CODEC_ID_H264) {
         H264Context *h = (void*)s;
-        assert(s->quarter_sample);
+        av_assert0(s->quarter_sample);
         *mv_step = 4;
         *stride  = h->b_stride;
     } else {
@@ -170,11 +180,73 @@
                      int h, int stride, int is_luma)
 {
     int b_x, b_y;
+    int16_t  (*col )[4] = av_malloc(stride*h*sizeof( int16_t)*4);
+    uint32_t (*dist)[4] = av_malloc(stride*h*sizeof(uint32_t)*4);
+
+    if(!col || !dist) {
+        av_log(s->avctx, AV_LOG_ERROR, "guess_dc() is out of memory\n");
+        goto fail;
+    }
+
+    for(b_y=0; b_y<h; b_y++){
+        int color= 1024;
+        int distance= -1;
+        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]);
+            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
+                color= dc[b_x + b_y*stride];
+                distance= b_x;
+            }
+            col [b_x + b_y*stride][1]= color;
+            dist[b_x + b_y*stride][1]= distance >= 0 ? b_x-distance : 9999;
+        }
+        color= 1024;
+        distance= -1;
+        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]);
+            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
+                color= dc[b_x + b_y*stride];
+                distance= b_x;
+            }
+            col [b_x + b_y*stride][0]= color;
+            dist[b_x + b_y*stride][0]= distance >= 0 ? distance-b_x : 9999;
+        }
+    }
+    for(b_x=0; b_x<w; b_x++){
+        int color= 1024;
+        int distance= -1;
+        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]);
+            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
+                color= dc[b_x + b_y*stride];
+                distance= b_y;
+            }
+            col [b_x + b_y*stride][3]= color;
+            dist[b_x + b_y*stride][3]= distance >= 0 ? b_y-distance : 9999;
+        }
+        color= 1024;
+        distance= -1;
+        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]);
+            if(intra_j==0 || !(error_j&ER_DC_ERROR)){
+                color= dc[b_x + b_y*stride];
+                distance= b_y;
+            }
+            col [b_x + b_y*stride][2]= color;
+            dist[b_x + b_y*stride][2]= distance >= 0 ? distance-b_y : 9999;
+        }
+    }
 
     for (b_y = 0; b_y < h; b_y++) {
         for (b_x = 0; b_x < w; b_x++) {
-            int color[4]    = { 1024, 1024, 1024, 1024 };
-            int distance[4] = { 9999, 9999, 9999, 9999 };
             int mb_index, error, j;
             int64_t guess, weight_sum;
             mb_index = (b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride;
@@ -185,66 +257,21 @@
             if (!(error & ER_DC_ERROR))
                 continue; // dc-ok
 
-            /* right block */
-            for (j = b_x + 1; j < w; j++) {
-                int mb_index_j = (j >> 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]);
-                if (intra_j == 0 || !(error_j & ER_DC_ERROR)) {
-                    color[0]    = dc[j + b_y * stride];
-                    distance[0] = j - b_x;
-                    break;
-                }
-            }
-
-            /* left block */
-            for (j = b_x - 1; j >= 0; j--) {
-                int mb_index_j = (j >> 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]);
-                if (intra_j == 0 || !(error_j & ER_DC_ERROR)) {
-                    color[1]    = dc[j + b_y * stride];
-                    distance[1] = b_x - j;
-                    break;
-                }
-            }
-
-            /* bottom block */
-            for (j = b_y + 1; j < h; j++) {
-                int mb_index_j = (b_x >> is_luma) + (j >> 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]);
-
-                if (intra_j == 0 || !(error_j & ER_DC_ERROR)) {
-                    color[2]    = dc[b_x + j * stride];
-                    distance[2] = j - b_y;
-                    break;
-                }
-            }
-
-            /* top block */
-            for (j = b_y - 1; j >= 0; j--) {
-                int mb_index_j = (b_x >> is_luma) + (j >> 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]);
-                if (intra_j == 0 || !(error_j & ER_DC_ERROR)) {
-                    color[3]    = dc[b_x + j * stride];
-                    distance[3] = b_y - j;
-                    break;
-                }
-            }
-
             weight_sum = 0;
             guess      = 0;
             for (j = 0; j < 4; j++) {
-                int64_t weight  = 256 * 256 * 256 * 16 / distance[j];
-                guess          += weight * (int64_t) color[j];
+                int64_t weight  = 256 * 256 * 256 * 16 / FFMAX(dist[b_x + b_y*stride][j], 1);
+                guess          += weight*(int64_t)col[b_x + b_y*stride][j];
                 weight_sum     += weight;
             }
             guess = (guess + weight_sum / 2) / weight_sum;
             dc[b_x + b_y * stride] = guess;
         }
     }
+
+fail:
+    av_freep(&col);
+    av_freep(&dist);
 }
 
 /**
@@ -414,19 +441,22 @@
         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]){
+            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];
+        }
     }
 
     if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) ||
         num_avail <= mb_width / 2) {
         for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
-            s->mb_x = 0;
-            s->mb_y = mb_y;
-            ff_init_block_index(s);
             for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
                 const int mb_xy = mb_x + mb_y * s->mb_stride;
 
-                ff_update_block_index(s);
-
                 if (IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
                     continue;
                 if (!(s->error_status_table[mb_xy] & ER_MV_ERROR))
@@ -461,9 +491,6 @@
 
             changed = 0;
             for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
-                s->mb_x = 0;
-                s->mb_y = mb_y;
-                ff_init_block_index(s);
                 for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
                     const int mb_xy        = mb_x + mb_y * s->mb_stride;
                     int mv_predictor[8][2] = { { 0 } };
@@ -475,15 +502,13 @@
                     const int mot_index    = (mb_x + mb_y * mot_stride) * mot_step;
                     int prev_x, prev_y, prev_ref;
 
-                    ff_update_block_index(s);
-
                     if ((mb_x ^ mb_y ^ pass) & 1)
                         continue;
 
                     if (fixed[mb_xy] == MV_FROZEN)
                         continue;
-                    assert(!IS_INTRA(s->current_picture.f.mb_type[mb_xy]));
-                    assert(s->last_picture_ptr && s->last_picture_ptr->f.data[0]);
+                    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]);
 
                     j = 0;
                     if (mb_x > 0             && fixed[mb_xy - 1]         == MV_FROZEN)
@@ -598,7 +623,7 @@
                     /* zero MV */
                     pred_count++;
 
-                    if (!fixed[mb_xy]) {
+                    if (!fixed[mb_xy] && 0) {
                         if (s->avctx->codec_id == AV_CODEC_ID_H264) {
                             // FIXME
                         } else {
@@ -773,11 +798,9 @@
                     ff_thread_await_progress(&s->last_picture_ptr->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,
-                                                 last_mb_ptr + s->linesize * 16,
-                                                 s->linesize, 16);
+                is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr                    , s->linesize, 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);
             } else {
                 if (IS_INTRA(s->current_picture.f.mb_type[mb_xy]))
                    is_intra_likely++;
@@ -786,6 +809,7 @@
             }
         }
     }
+    // printf("is_intra_likely: %d type:%d\n", is_intra_likely, s->pict_type);
     return is_intra_likely > 0;
 }
 
@@ -887,7 +911,7 @@
 
     /* We do not support ER of field pictures yet,
      * though it should not crash if enabled. */
-    if (!s->err_recognition || s->error_count == 0                     ||
+    if (!s->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                             ||
@@ -919,6 +943,7 @@
         }
     }
 
+#if 1
     /* handle overlapping slices */
     for (error_type = 1; error_type <= 3; error_type++) {
         int end_ok = 0;
@@ -939,7 +964,8 @@
                 end_ok = 0;
         }
     }
-
+#endif
+#if 1
     /* handle slices with partitions of different length */
     if (s->partitioned_frame) {
         int end_ok = 0;
@@ -962,7 +988,7 @@
                 end_ok = 0;
         }
     }
-
+#endif
     /* handle missing slices */
     if (s->err_recognition & AV_EF_EXPLODE) {
         int end_ok = 1;
@@ -989,6 +1015,7 @@
         }
     }
 
+#if 1
     /* backward mark errors */
     distance = 9999999;
     for (error_type = 1; error_type <= 3; error_type++) {
@@ -1013,6 +1040,7 @@
                 distance = 9999999;
         }
     }
+#endif
 
     /* forward mark errors */
     error = 0;
@@ -1027,7 +1055,7 @@
             s->error_status_table[mb_xy] |= error;
         }
     }
-
+#if 1
     /* handle not partitioned case */
     if (!s->partitioned_frame) {
         for (i = 0; i < s->mb_num; i++) {
@@ -1038,6 +1066,7 @@
             s->error_status_table[mb_xy] = error;
         }
     }
+#endif
 
     dc_error = ac_error = mv_error = 0;
     for (i = 0; i < s->mb_num; i++) {
@@ -1050,8 +1079,8 @@
         if (error & ER_MV_ERROR)
             mv_error++;
     }
-    av_log(s->avctx, AV_LOG_INFO, "concealing %d DC, %d AC, %d MV errors\n",
-           dc_error, ac_error, 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));
 
     is_intra_likely = is_intra_more_likely(s);
 
@@ -1078,16 +1107,11 @@
 
     /* handle inter blocks with damaged AC */
     for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
-        s->mb_x = 0;
-        s->mb_y = mb_y;
-        ff_init_block_index(s);
         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];
 
-            ff_update_block_index(s);
-
             error = s->error_status_table[mb_xy];
 
             if (IS_INTRA(mb_type))
@@ -1125,16 +1149,11 @@
     /* guess MVs */
     if (s->pict_type == AV_PICTURE_TYPE_B) {
         for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
-            s->mb_x = 0;
-            s->mb_y = mb_y;
-            ff_init_block_index(s);
             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];
 
-                ff_update_block_index(s);
-
                 error = s->error_status_table[mb_xy];
 
                 if (IS_INTRA(mb_type))
@@ -1229,15 +1248,17 @@
             s->dc_val[2][mb_x + mb_y * s->mb_stride] = (dcv + 4) >> 3;
         }
     }
-
+#if 1
     /* guess DC for damaged blocks */
-    guess_dc(s, s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride, 1);
-    guess_dc(s, s->dc_val[1], s->mb_width, s->mb_height, s->mb_stride, 0);
-    guess_dc(s, s->dc_val[2], s->mb_width, s->mb_height, s->mb_stride, 0);
+    guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
+    guess_dc(s, s->dc_val[1], s->mb_width  , s->mb_height  , s->mb_stride, 0);
+    guess_dc(s, s->dc_val[2], s->mb_width  , s->mb_height  , s->mb_stride, 0);
+#endif
 
     /* filter luma DC */
     filter181(s->dc_val[0], s->mb_width * 2, s->mb_height * 2, s->b8_stride);
 
+#if 1
     /* render DC only intra */
     for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
@@ -1259,6 +1280,7 @@
             put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y);
         }
     }
+#endif
 
     if (s->avctx->error_concealment & FF_EC_DEBLOCK) {
         /* filter horizontal block boundaries */
diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c
index 40224fb..94eadce 100644
--- a/libavcodec/escape124.c
+++ b/libavcodec/escape124.c
@@ -2,20 +2,20 @@
  * Escape 124 Video Decoder
  * Copyright (C) 2008 Eli Friedman (eli.friedman@gmail.com)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -48,7 +48,7 @@
     CodeBook codebooks[3];
 } Escape124Context;
 
-static int can_safely_read(GetBitContext* gb, int bits) {
+static int can_safely_read(GetBitContext* gb, uint64_t bits) {
     return get_bits_left(gb) >= bits;
 }
 
@@ -61,6 +61,7 @@
 {
     Escape124Context *s = avctx->priv_data;
 
+    avcodec_get_frame_defaults(&s->frame);
     avctx->pix_fmt = AV_PIX_FMT_RGB555;
 
     s->num_superblocks = ((unsigned)avctx->width / 8) *
@@ -89,7 +90,7 @@
     unsigned i, j;
     CodeBook cb = { 0 };
 
-    if (!can_safely_read(gb, size * 34))
+    if (!can_safely_read(gb, (uint64_t)size * 34))
         return cb;
 
     if (size >= INT_MAX / sizeof(MacroBlock))
@@ -214,7 +215,8 @@
     uint16_t* old_frame_data, *new_frame_data;
     unsigned old_stride, new_stride;
 
-    AVFrame new_frame = { { 0 } };
+    AVFrame new_frame;
+    avcodec_get_frame_defaults(&new_frame);
 
     init_get_bits(&gb, buf, buf_size * 8);
 
diff --git a/libavcodec/escape130.c b/libavcodec/escape130.c
new file mode 100644
index 0000000..97547bb
--- /dev/null
+++ b/libavcodec/escape130.c
@@ -0,0 +1,319 @@
+/*
+ * Escape 130 Video Decoder
+ * Copyright (C) 2008 Eli Friedman (eli.friedman <at> gmail.com)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avcodec.h"
+
+#define BITSTREAM_READER_LE
+#include "get_bits.h"
+
+typedef struct Escape130Context {
+    AVFrame frame;
+    uint8_t *bases;
+} Escape130Context;
+
+/**
+ * Initialize the decoder
+ * @param avctx decoder context
+ * @return 0 success, negative on error
+ */
+static av_cold int escape130_decode_init(AVCodecContext *avctx)
+{
+    Escape130Context *s = avctx->priv_data;
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+    if((avctx->width&1) || (avctx->height&1)){
+        av_log(avctx, AV_LOG_ERROR, "Dimensions are not a multiple of the block size\n");
+        return AVERROR(EINVAL);
+    }
+
+    s->bases= av_malloc(avctx->width * avctx->height /4);
+
+    return 0;
+}
+
+static av_cold int escape130_decode_close(AVCodecContext *avctx)
+{
+    Escape130Context *s = avctx->priv_data;
+
+    if (s->frame.data[0])
+        avctx->release_buffer(avctx, &s->frame);
+
+    av_freep(&s->bases);
+
+    return 0;
+}
+
+static unsigned decode_skip_count(GetBitContext* gb) {
+    unsigned value;
+    // This function reads a maximum of 27 bits,
+    // which is within the padding space
+    if (get_bits_left(gb) < 1+3)
+        return -1;
+
+    value = get_bits1(gb);
+    if (value)
+        return 0;
+
+    value = get_bits(gb, 3);
+    if (value)
+        return value;
+
+    value = get_bits(gb, 8);
+    if (value)
+        return value + 7;
+
+    value = get_bits(gb, 15);
+    if (value)
+        return value + 262;
+
+    return -1;
+}
+
+/**
+ * Decode a single frame
+ * @param avctx decoder context
+ * @param data decoded frame
+ * @param data_size size of the 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,
+                                  AVPacket *avpkt)
+{
+    const uint8_t *buf = avpkt->data;
+    int buf_size = avpkt->size;
+    Escape130Context *s = avctx->priv_data;
+
+    GetBitContext gb;
+    unsigned i;
+
+    uint8_t *old_y, *old_cb, *old_cr,
+            *new_y, *new_cb, *new_cr;
+    unsigned old_y_stride, old_cb_stride, old_cr_stride,
+             new_y_stride, new_cb_stride, new_cr_stride;
+    unsigned total_blocks = avctx->width * avctx->height / 4,
+             block_index, row_index = 0;
+    unsigned y[4] = {0}, cb = 16, cr = 16;
+    unsigned skip = -1;
+    unsigned y_base = 0;
+    uint8_t *yb= s->bases;
+
+    AVFrame new_frame = { { 0 } };
+
+    init_get_bits(&gb, buf, buf_size * 8);
+
+    if (get_bits_left(&gb) < 128)
+        return -1;
+
+    // Header; no useful information in here
+    skip_bits_long(&gb, 128);
+
+    new_frame.reference = 3;
+    if (avctx->get_buffer(avctx, &new_frame)) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return -1;
+    }
+
+    new_y = new_frame.data[0];
+    new_cb = new_frame.data[1];
+    new_cr = new_frame.data[2];
+    new_y_stride = new_frame.linesize[0];
+    new_cb_stride = new_frame.linesize[1];
+    new_cr_stride = new_frame.linesize[2];
+    old_y = s->frame.data[0];
+    old_cb = s->frame.data[1];
+    old_cr = s->frame.data[2];
+    old_y_stride = s->frame.linesize[0];
+    old_cb_stride = s->frame.linesize[1];
+    old_cr_stride = s->frame.linesize[2];
+
+    av_log(avctx, AV_LOG_DEBUG,
+           "Strides: %i, %i\n",
+           new_y_stride, new_cb_stride);
+
+    for (block_index = 0; block_index < total_blocks; block_index++) {
+        // Note that this call will make us skip the rest of the blocks
+        // if the frame prematurely ends
+        if (skip == -1)
+            skip = decode_skip_count(&gb);
+
+        if (skip) {
+            if (old_y) {
+                y[0] = old_y[0] / 4;
+                y[1] = old_y[1] / 4;
+                y[2] = old_y[old_y_stride] / 4;
+                y[3] = old_y[old_y_stride+1] / 4;
+                y_base= yb[0];
+                cb = old_cb[0] / 8;
+                cr = old_cr[0] / 8;
+            } else {
+                y_base=y[0] = y[1] = y[2] = y[3] = 0;
+                cb = cr = 16;
+            }
+        } else {
+            if (get_bits1(&gb)) {
+                static const uint8_t offset_table[] = {2, 4, 10, 20};
+                static const int8_t sign_table[64][4] =
+                    { {0, 0, 0, 0},
+                      {-1, 1, 0, 0},
+                      {1, -1, 0, 0},
+                      {-1, 0, 1, 0},
+                      {-1, 1, 1, 0},
+                      {0, -1, 1, 0},
+                      {1, -1, 1, 0},
+                      {-1, -1, 1, 0},
+                      {1, 0, -1, 0},
+                      {0, 1, -1, 0},
+                      {1, 1, -1, 0},
+                      {-1, 1, -1, 0},
+                      {1, -1, -1, 0},
+                      {-1, 0, 0, 1},
+                      {-1, 1, 0, 1},
+                      {0, -1, 0, 1},
+
+                      {0, 0, 0, 0},
+                      {1, -1, 0, 1},
+                      {-1, -1, 0, 1},
+                      {-1, 0, 1, 1},
+                      {-1, 1, 1, 1},
+                      {0, -1, 1, 1},
+                      {1, -1, 1, 1},
+                      {-1, -1, 1, 1},
+                      {0, 0, -1, 1},
+                      {1, 0, -1, 1},
+                      {-1, 0, -1, 1},
+                      {0, 1, -1, 1},
+                      {1, 1, -1, 1},
+                      {-1, 1, -1, 1},
+                      {0, -1, -1, 1},
+                      {1, -1, -1, 1},
+
+                      {0, 0, 0, 0},
+                      {-1, -1, -1, 1},
+                      {1, 0, 0, -1},
+                      {0, 1, 0, -1},
+                      {1, 1, 0, -1},
+                      {-1, 1, 0, -1},
+                      {1, -1, 0, -1},
+                      {0, 0, 1, -1},
+                      {1, 0, 1, -1},
+                      {-1, 0, 1, -1},
+                      {0, 1, 1, -1},
+                      {1, 1, 1, -1},
+                      {-1, 1, 1, -1},
+                      {0, -1, 1, -1},
+                      {1, -1, 1, -1},
+                      {-1, -1, 1, -1},
+
+                      {0, 0, 0, 0},
+                      {1, 0, -1, -1},
+                      {0, 1, -1, -1},
+                      {1, 1, -1, -1},
+                      {-1, 1, -1, -1},
+                      {1, -1, -1, -1} };
+                unsigned sign_selector = get_bits(&gb, 6);
+                unsigned difference_selector = get_bits(&gb, 2);
+                y_base = 2 * get_bits(&gb, 5);
+                for (i = 0; i < 4; i++) {
+                    y[i] = av_clip((int)y_base + offset_table[difference_selector] *
+                                            sign_table[sign_selector][i], 0, 63);
+                }
+            } else if (get_bits1(&gb)) {
+                if (get_bits1(&gb)) {
+                    y_base = get_bits(&gb, 6);
+                } else {
+                    unsigned adjust_index = get_bits(&gb, 3);
+                    static const int8_t adjust[] = {-4, -3, -2, -1, 1, 2, 3, 4};
+                    y_base = (y_base + adjust[adjust_index]) & 63;
+                }
+                for (i = 0; i < 4; i++)
+                    y[i] = y_base;
+            }
+
+            if (get_bits1(&gb)) {
+                if (get_bits1(&gb)) {
+                    cb = get_bits(&gb, 5);
+                    cr = get_bits(&gb, 5);
+                } else {
+                    unsigned adjust_index = get_bits(&gb, 3);
+                    static const int8_t adjust[2][8] =
+                        {  { 1, 1, 0, -1, -1, -1,  0,  1 },
+                           { 0, 1, 1,  1,  0, -1, -1, -1 } };
+                    cb = (cb + adjust[0][adjust_index]) & 31;
+                    cr = (cr + adjust[1][adjust_index]) & 31;
+                }
+            }
+        }
+        *yb++= y_base;
+
+        new_y[0] = y[0] * 4;
+        new_y[1] = y[1] * 4;
+        new_y[new_y_stride] = y[2] * 4;
+        new_y[new_y_stride + 1] = y[3] * 4;
+        *new_cb = cb * 8;
+        *new_cr = cr * 8;
+
+        if (old_y)
+            old_y += 2, old_cb++, old_cr++;
+        new_y += 2, new_cb++, new_cr++;
+        row_index++;
+        if (avctx->width / 2 == row_index) {
+            row_index = 0;
+            if (old_y) {
+                old_y  += old_y_stride * 2  - avctx->width;
+                old_cb += old_cb_stride - avctx->width / 2;
+                old_cr += old_cr_stride - avctx->width / 2;
+            }
+            new_y  += new_y_stride * 2  - avctx->width;
+            new_cb += new_cb_stride - avctx->width / 2;
+            new_cr += new_cr_stride - avctx->width / 2;
+        }
+
+        skip--;
+    }
+
+    av_log(avctx, AV_LOG_DEBUG,
+           "Escape sizes: %i, %i\n",
+           buf_size, get_bits_count(&gb) / 8);
+
+    if (s->frame.data[0])
+        avctx->release_buffer(avctx, &s->frame);
+
+    *(AVFrame*)data = s->frame = new_frame;
+    *data_size = sizeof(AVFrame);
+
+    return buf_size;
+}
+
+
+AVCodec ff_escape130_decoder = {
+    .name           = "escape130",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_ESCAPE130,
+    .priv_data_size = sizeof(Escape130Context),
+    .init           = escape130_decode_init,
+    .close          = escape130_decode_close,
+    .decode         = escape130_decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("Escape 130"),
+};
diff --git a/libavcodec/exr.c b/libavcodec/exr.c
new file mode 100644
index 0000000..6773d88
--- /dev/null
+++ b/libavcodec/exr.c
@@ -0,0 +1,676 @@
+/*
+ * OpenEXR (.exr) image decoder
+ * Copyright (c) 2009 Jimmy Christensen
+ *
+ * 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
+ * OpenEXR decoder
+ * @author Jimmy Christensen
+ *
+ * For more information on the OpenEXR format, visit:
+ *  http://openexr.com/
+ *
+ * exr_flt2uint() and exr_halflt2uint() is credited to  Reimar Döffinger
+ */
+
+#include <zlib.h>
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "mathops.h"
+#include "thread.h"
+#include "libavutil/imgutils.h"
+
+enum ExrCompr {
+    EXR_RAW   = 0,
+    EXR_RLE   = 1,
+    EXR_ZIP1  = 2,
+    EXR_ZIP16 = 3,
+    EXR_PIZ   = 4,
+    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
+
+    uint8_t *uncompressed_data;
+    int uncompressed_size;
+
+    uint8_t *tmp;
+    int tmp_size;
+} EXRContext;
+
+/**
+ * Converts from 32-bit float as uint32_t to uint16_t
+ *
+ * @param v 32-bit float
+ * @return normalized 16-bit unsigned int
+ */
+static inline uint16_t exr_flt2uint(uint32_t v)
+{
+    unsigned int exp = v >> 23;
+    // "HACK": negative values result in exp<  0, so clipping them to 0
+    // is also handled by this condition, avoids explicit check for sign bit.
+    if (exp<= 127 + 7 - 24) // we would shift out all bits anyway
+        return 0;
+    if (exp >= 127)
+        return 0xffff;
+    v &= 0x007fffff;
+    return (v + (1 << 23)) >> (127 + 7 - exp);
+}
+
+/**
+ * Converts from 16-bit float as uint16_t to uint16_t
+ *
+ * @param v 16-bit float
+ * @return normalized 16-bit unsigned int
+ */
+static inline uint16_t exr_halflt2uint(uint16_t v)
+{
+    unsigned exp = 14 - (v >> 10);
+    if (exp >= 14) {
+        if (exp == 14) return (v >> 9) & 1;
+        else           return (v & 0x8000) ? 0 : 0xffff;
+    }
+    v <<= 6;
+    return (v + (1 << 16)) >> (exp + 1);
+}
+
+/**
+ * Gets the size of the header variable
+ *
+ * @param **buf the current pointer location in the header where
+ * the variable data starts
+ * @param *buf_end pointer location of the end of the buffer
+ * @return size of variable data
+ */
+static unsigned int get_header_variable_length(const uint8_t **buf,
+                                               const uint8_t *buf_end)
+{
+    unsigned int variable_buffer_data_size = bytestream_get_le32(buf);
+    if (variable_buffer_data_size >= buf_end - *buf)
+        return 0;
+    return variable_buffer_data_size;
+}
+
+/**
+ * Checks if the variable name corresponds with it's data type
+ *
+ * @param *avctx the AVCodecContext
+ * @param **buf the current pointer location in the header where
+ * the variable name starts
+ * @param *buf_end pointer location of the end of the buffer
+ * @param *value_name name of the varible to check
+ * @param *value_type type of the varible to check
+ * @param minimum_length minimum length of the variable data
+ * @param variable_buffer_data_size variable length read from the header
+ * after it's checked
+ * @return negative if variable is invalid
+ */
+static int check_header_variable(AVCodecContext *avctx,
+                                              const uint8_t **buf,
+                                              const uint8_t *buf_end,
+                                              const char *value_name,
+                                              const char *value_type,
+                                              unsigned int minimum_length,
+                                              unsigned int *variable_buffer_data_size)
+{
+    if (buf_end - *buf >= minimum_length && !strcmp(*buf, value_name)) {
+        *buf += strlen(value_name)+1;
+        if (!strcmp(*buf, value_type)) {
+            *buf += strlen(value_type)+1;
+            *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;
+        av_log(avctx, AV_LOG_WARNING, "Unknown data type for header variable %s\n", value_name);
+    }
+    return -1;
+}
+
+static void predictor(uint8_t *src, int size)
+{
+    uint8_t *t = src + 1;
+    uint8_t *stop = src + size;
+
+    while (t < stop) {
+        int d = (int)t[-1] + (int)t[0] - 128;
+        t[0] = d;
+        ++t;
+    }
+}
+
+static void reorder_pixels(uint8_t *src, uint8_t *dst, int size)
+{
+    const int8_t *t1 = src;
+    const int8_t *t2 = src + (size + 1) / 2;
+    int8_t *s = dst;
+    int8_t *stop = s + size;
+
+    while (1) {
+        if (s < stop)
+            *(s++) = *(t1++);
+        else
+            break;
+
+        if (s < stop)
+            *(s++) = *(t2++);
+        else
+            break;
+    }
+}
+
+static int rle_uncompress(const uint8_t *src, int ssize, uint8_t *dst, int dsize)
+{
+    int8_t *d = (int8_t *)dst;
+    int8_t *s = (int8_t *)src;
+    int8_t *dend = d + dsize;
+    int count;
+
+    while (ssize > 0) {
+        count = *s++;
+
+        if (count < 0) {
+            count = -count;
+
+            if ((dsize -= count    ) < 0 ||
+                (ssize -= count + 1) < 0)
+                return -1;
+
+            while (count--)
+                *d++ = *s++;
+        } else {
+            count++;
+
+            if ((dsize -= count) < 0 ||
+                (ssize -= 2    ) < 0)
+                return -1;
+
+            while (count--)
+                *d++ = *s;
+
+            s++;
+        }
+    }
+
+    return dend != d;
+}
+
+static int decode_frame(AVCodecContext *avctx,
+                        void *data,
+                        int *data_size,
+                        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 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;
+
+    unsigned int current_channel_offset = 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;
+
+    if (buf_size < 10) {
+        av_log(avctx, AV_LOG_ERROR, "Too short header to parse\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    magic_number = bytestream_get_le32(&buf);
+    if (magic_number != 20000630) { // As per documentation of OpenEXR it's supposed to be int 20000630 little-endian
+        av_log(avctx, AV_LOG_ERROR, "Wrong magic number %d\n", magic_number);
+        return AVERROR_INVALIDDATA;
+    }
+
+    version_flag = bytestream_get_le32(&buf);
+    if ((version_flag & 0x200) == 0x200) {
+        av_log(avctx, AV_LOG_ERROR, "Tile based images are not supported\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    // Parse the header
+    while (buf < buf_end && buf[0]) {
+        unsigned int variable_buffer_data_size;
+        // Process the channel list
+        if (check_header_variable(avctx, &buf, buf_end, "channels", "chlist", 38, &variable_buffer_data_size) >= 0) {
+            const uint8_t *channel_list_end;
+            if (!variable_buffer_data_size)
+                return AVERROR_INVALIDDATA;
+
+            channel_list_end = buf + variable_buffer_data_size;
+            while (channel_list_end - buf >= 19) {
+                int current_bits_per_color_id = -1;
+                int channel_index = -1;
+
+                if (!strcmp(buf, "R"))
+                    channel_index = 0;
+                else if (!strcmp(buf, "G"))
+                    channel_index = 1;
+                else if (!strcmp(buf, "B"))
+                    channel_index = 2;
+                else if (!strcmp(buf, "A"))
+                    channel_index = 3;
+                else
+                    av_log(avctx, AV_LOG_WARNING, "Unsupported channel %.256s\n", buf);
+
+                while (bytestream_get_byte(&buf) && buf < channel_list_end)
+                    continue; /* skip */
+
+                if (channel_list_end - * &buf < 4) {
+                    av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
+                    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");
+                    return AVERROR_INVALIDDATA;
+                }
+
+                if (channel_index >= 0) {
+                    if (s->bits_per_color_id != -1 && s->bits_per_color_id != current_bits_per_color_id) {
+                        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->channel_offsets[channel_index] = current_channel_offset;
+                }
+
+                current_channel_offset += 1 << current_bits_per_color_id;
+                buf += 12;
+            }
+
+            /* Check if all channels are set with an offset or if the channels
+             * are causing an overflow  */
+
+            if (FFMIN3(s->channel_offsets[0],
+                       s->channel_offsets[1],
+                       s->channel_offsets[2]) < 0) {
+                if (s->channel_offsets[0] < 0)
+                    av_log(avctx, AV_LOG_ERROR, "Missing red channel\n");
+                if (s->channel_offsets[1] < 0)
+                    av_log(avctx, AV_LOG_ERROR, "Missing green channel\n");
+                if (s->channel_offsets[2] < 0)
+                    av_log(avctx, AV_LOG_ERROR, "Missing blue channel\n");
+                return AVERROR_INVALIDDATA;
+            }
+
+            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) {
+            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;
+
+            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) {
+            if (!variable_buffer_data_size)
+                return AVERROR_INVALIDDATA;
+
+            w = AV_RL32(buf + 8) + 1;
+            h = AV_RL32(buf + 12) + 1;
+
+            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) {
+            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;
+            }
+
+            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) {
+            if (!variable_buffer_data_size)
+                return AVERROR_INVALIDDATA;
+
+            avctx->sample_aspect_ratio = av_d2q(av_int2float(AV_RL32(buf)), 255);
+
+            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) {
+            if (!variable_buffer_data_size)
+                return AVERROR_INVALIDDATA;
+
+            if (s->compr == -1)
+                s->compr = *buf;
+            else
+                av_log(avctx, AV_LOG_WARNING, "Found more than one compression attribute\n");
+
+            buf += variable_buffer_data_size;
+            continue;
+        }
+
+        // Check if there is enough bytes for a header
+        if (buf_end - buf <= 9) {
+            av_log(avctx, AV_LOG_ERROR, "Incomplete header\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        // Process unknown variables
+        for (i = 0; i < 2; i++) {
+            // Skip variable name/type
+            while (++buf < buf_end)
+                if (buf[0] == 0x0)
+                    break;
+        }
+        buf++;
+        // Skip variable length
+        if (buf_end - buf >= 5) {
+            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");
+                return AVERROR_INVALIDDATA;
+            }
+            buf += variable_buffer_data_size;
+        }
+    }
+
+    if (s->compr == -1) {
+        av_log(avctx, AV_LOG_ERROR, "Missing compression attribute\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (buf >= buf_end) {
+        av_log(avctx, AV_LOG_ERROR, "Incomplete frame\n");
+        return AVERROR_INVALIDDATA;
+    }
+    buf++;
+
+    switch (s->bits_per_color_id) {
+    case 2: // 32-bit
+    case 1: // 16-bit
+        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);
+        return AVERROR_PATCHWELCOME;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "Unknown color format : %d\n", s->bits_per_color_id);
+        return AVERROR_INVALIDDATA;
+    }
+
+    switch (s->compr) {
+    case EXR_RAW:
+    case EXR_RLE:
+    case EXR_ZIP1:
+        scan_lines_per_block = 1;
+        break;
+    case EXR_ZIP16:
+        scan_lines_per_block = 16;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "Compression type %d is not supported\n", s->compr);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    if (s->picture.data[0])
+        ff_thread_release_buffer(avctx, &s->picture);
+    if (av_image_check_size(w, h, 0, avctx))
+        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) {
+        av_log(avctx, AV_LOG_ERROR, "Wrong sizing or missing size information\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (w != avctx->width || h != avctx->height) {
+        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;
+
+    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)
+            return AVERROR(ENOMEM);
+    }
+
+    if ((ret = ff_thread_get_buffer(avctx, p)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
+    }
+
+    ptr    = p->data[0];
+    stride = p->linesize[0];
+
+    // Zero out the start if ymin is not 0
+    for (y = 0; y < ymin; y++) {
+        memset(ptr, 0, out_line_size);
+        ptr += stride;
+    }
+
+    // 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;
+                }
+            }
+        }
+    }
+
+    // Zero out the end if ymax+1 is not h
+    for (y = ymax + 1; y < avctx->height; y++) {
+        memset(ptr, 0, out_line_size);
+        ptr += stride;
+    }
+
+    *picture   = s->picture;
+    *data_size = sizeof(AVPicture);
+
+    return buf_size;
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+    EXRContext *s = avctx->priv_data;
+
+    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;
+
+    if (s->picture.data[0])
+        avctx->release_buffer(avctx, &s->picture);
+
+    av_freep(&s->uncompressed_data);
+    av_freep(&s->tmp);
+
+    return 0;
+}
+
+AVCodec ff_exr_decoder = {
+    .name               = "exr",
+    .type               = AVMEDIA_TYPE_VIDEO,
+    .id                 = AV_CODEC_ID_EXR,
+    .priv_data_size     = sizeof(EXRContext),
+    .init               = decode_init,
+    .close              = decode_end,
+    .decode             = decode_frame,
+    .capabilities       = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
+    .long_name          = NULL_IF_CONFIG_SMALL("OpenEXR image"),
+};
diff --git a/libavcodec/faandct.h b/libavcodec/faandct.h
index cd98236..a12dcaf 100644
--- a/libavcodec/faandct.h
+++ b/libavcodec/faandct.h
@@ -2,20 +2,20 @@
  * Floating point AAN DCT
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/faanidct.c b/libavcodec/faanidct.c
index cd8ca27..1e9bfaf 100644
--- a/libavcodec/faanidct.c
+++ b/libavcodec/faanidct.c
@@ -2,20 +2,20 @@
  * Floating point AAN IDCT
  * Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "faanidct.h"
diff --git a/libavcodec/faanidct.h b/libavcodec/faanidct.h
index f3896f7..4cf1189 100644
--- a/libavcodec/faanidct.h
+++ b/libavcodec/faanidct.h
@@ -2,20 +2,20 @@
  * Floating point AAN IDCT
  * Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/faxcompr.c b/libavcodec/faxcompr.c
index 077e740..e7f9d00 100644
--- a/libavcodec/faxcompr.c
+++ b/libavcodec/faxcompr.c
@@ -2,20 +2,20 @@
  * CCITT Fax Group 3 and 4 decompression
  * Copyright (c) 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -228,7 +228,7 @@
             mode = !mode;
         }
         //sync line pointers
-        while(run_off <= offs){
+        while(offs < width && run_off <= offs){
             run_off += *ref++;
             run_off += *ref++;
         }
@@ -279,6 +279,7 @@
     int ret;
     int runsize= avctx->width + 2;
     int err = 0;
+    int has_eol;
 
     runs = av_malloc(runsize * sizeof(runs[0]));
     ref  = av_malloc(runsize * sizeof(ref[0]));
@@ -290,6 +291,8 @@
     ref[1] = 0;
     ref[2] = 0;
     init_get_bits(&gb, src, srcsize*8);
+    has_eol = show_bits(&gb, 12) == 1 || show_bits(&gb, 16) == 1;
+
     for(j = 0; j < height; j++){
         runend = runs + runsize;
         if(compr == TIFF_G4){
@@ -300,7 +303,7 @@
             }
         }else{
             int g3d1 = (compr == TIFF_G3) && !(opts & 1);
-            if(compr!=TIFF_CCITT_RLE && find_group3_syncmarker(&gb, srcsize*8) < 0)
+            if(compr!=TIFF_CCITT_RLE && has_eol && find_group3_syncmarker(&gb, srcsize*8) < 0)
                 break;
             if(compr==TIFF_CCITT_RLE || g3d1 || get_bits1(&gb))
                 ret = decode_group3_1d_line(avctx, &gb, avctx->width, runs, runend);
diff --git a/libavcodec/faxcompr.h b/libavcodec/faxcompr.h
index 8157f1f..53d1168 100644
--- a/libavcodec/faxcompr.h
+++ b/libavcodec/faxcompr.h
@@ -2,20 +2,20 @@
  * CCITT Fax Group 3 and 4 decompression
  * Copyright (c) 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/fft-fixed-test.c b/libavcodec/fft-fixed-test.c
index 63cd194..a1a6160 100644
--- a/libavcodec/fft-fixed-test.c
+++ b/libavcodec/fft-fixed-test.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/fft-internal.h b/libavcodec/fft-internal.h
index d30571b..61066bb 100644
--- a/libavcodec/fft-internal.h
+++ b/libavcodec/fft-internal.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/fft-test.c b/libavcodec/fft-test.c
index 1e46750..66474ce 100644
--- a/libavcodec/fft-test.c
+++ b/libavcodec/fft-test.c
@@ -1,20 +1,20 @@
 /*
  * (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -148,7 +148,7 @@
 }
 
 #if CONFIG_FFT_FLOAT
-static void idct_ref(float *output, float *input, int nbits)
+static void idct_ref(FFTSample *output, FFTSample *input, int nbits)
 {
     int n = 1<<nbits;
     int k, i;
@@ -164,7 +164,7 @@
         output[i] = 2 * s / n;
     }
 }
-static void dct_ref(float *output, float *input, int nbits)
+static void dct_ref(FFTSample *output, FFTSample *input, int nbits)
 {
     int n = 1<<nbits;
     int k, i;
@@ -205,7 +205,7 @@
         error+= e*e;
         if(e>max) max= e;
     }
-    av_log(NULL, AV_LOG_INFO, "max:%f e:%g\n", max, sqrt(error)/n);
+    av_log(NULL, AV_LOG_INFO, "max:%f e:%g\n", max, sqrt(error/n));
     return err;
 }
 
@@ -288,10 +288,12 @@
             scale = atof(optarg);
             break;
         case 'c':
-            cpuflags = av_parse_cpu_flags(optarg);
-            if (cpuflags < 0)
+            cpuflags = av_get_cpu_flags();
+
+            if (av_parse_cpu_caps(&cpuflags, optarg) < 0)
                 return 1;
-            av_set_cpu_flags_mask(cpuflags);
+
+            av_force_cpu_flags(cpuflags);
             break;
         }
     }
@@ -408,11 +410,11 @@
         break;
     case TRANSFORM_DCT:
         memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
-        d->dct_calc(d, tab);
+        d->dct_calc(d, (FFTSample *)tab);
         if (do_inverse) {
-            idct_ref(tab_ref, tab1, fft_nbits);
+            idct_ref((FFTSample*)tab_ref, (FFTSample *)tab1, fft_nbits);
         } else {
-            dct_ref(tab_ref, tab1, fft_nbits);
+            dct_ref((FFTSample*)tab_ref, (FFTSample *)tab1, fft_nbits);
         }
         err = check_diff((float *)tab_ref, (float *)tab, fft_size, 1.0);
         break;
diff --git a/libavcodec/fft.c b/libavcodec/fft.c
index 0983e80..00c434a 100644
--- a/libavcodec/fft.c
+++ b/libavcodec/fft.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2002 Fabrice Bellard
  * Partly based on libdjbfft by D. J. Bernstein
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -162,6 +162,7 @@
     if (HAVE_ALTIVEC) ff_fft_init_altivec(s);
     if (ARCH_X86)     ff_fft_init_x86(s);
     if (CONFIG_MDCT)  s->mdct_calcw = s->mdct_calc;
+    if (HAVE_MIPSFPU) ff_fft_init_mips(s);
 #else
     if (CONFIG_MDCT)  s->mdct_calcw = ff_mdct_calcw_c;
     if (ARCH_ARM)     ff_fft_fixed_init_arm(s);
diff --git a/libavcodec/fft.h b/libavcodec/fft.h
index 7f10f72..9d92b2c 100644
--- a/libavcodec/fft.h
+++ b/libavcodec/fft.h
@@ -2,20 +2,20 @@
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -137,6 +137,7 @@
 void ff_fft_init_altivec(FFTContext *s);
 void ff_fft_init_x86(FFTContext *s);
 void ff_fft_init_arm(FFTContext *s);
+void ff_fft_init_mips(FFTContext *s);
 #else
 void ff_fft_fixed_init_arm(FFTContext *s);
 #endif
diff --git a/libavcodec/fft_fixed.c b/libavcodec/fft_fixed.c
index b28091d..3955efe 100644
--- a/libavcodec/fft_fixed.c
+++ b/libavcodec/fft_fixed.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/fft_float.c b/libavcodec/fft_float.c
index 24c9fdb..2149646 100644
--- a/libavcodec/fft_float.c
+++ b/libavcodec/fft_float.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c
index e6ee96d..7787070 100644
--- a/libavcodec/ffv1.c
+++ b/libavcodec/ffv1.c
@@ -1,22 +1,22 @@
 /*
  * FFV1 codec for libavcodec
  *
- * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2003-2012 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,13 +26,24 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 #include "get_bits.h"
 #include "put_bits.h"
 #include "dsputil.h"
 #include "rangecoder.h"
 #include "golomb.h"
 #include "mathops.h"
+#include "libavutil/pixdesc.h"
 #include "libavutil/avassert.h"
+#include "libavutil/crc.h"
+#include "libavutil/opt.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/timer.h"
+
+#ifdef __INTEL_COMPILER
+#undef av_flatten
+#define av_flatten
+#endif
 
 #define MAX_PLANES 4
 #define CONTEXT_SIZE 32
@@ -156,6 +167,7 @@
 #define MAX_SLICES 256
 
 typedef struct FFV1Context{
+    AVClass *class;
     AVCodecContext *avctx;
     RangeCoder c;
     GetBitContext gb;
@@ -163,13 +175,18 @@
     uint64_t rc_stat[256][2];
     uint64_t (*rc_stat2[MAX_QUANT_TABLES])[32][2];
     int version;
+    int minor_version;
     int width, height;
     int chroma_h_shift, chroma_v_shift;
+    int chroma_planes;
+    int transparency;
     int flags;
     int picture_number;
     AVFrame picture;
+    AVFrame last_picture;
     int plane_count;
     int ac;                              ///< 1=range coder <-> 0=golomb rice
+    int ac_byte_count;                   ///< number of bytes used for AC coding
     PlaneContext plane[MAX_PLANES];
     int16_t quant_table[MAX_CONTEXT_INPUTS][256];
     int16_t quant_tables[MAX_QUANT_TABLES][MAX_CONTEXT_INPUTS][256];
@@ -180,6 +197,10 @@
     int colorspace;
     int16_t *sample_buffer;
     int gob_count;
+    int packed_at_lsb;
+    int ec;
+    int slice_damaged;
+    int key_frame_ok;
 
     int quant_table_count;
 
@@ -193,6 +214,7 @@
     int slice_height;
     int slice_x;
     int slice_y;
+    int bits_per_raw_sample;
 }FFV1Context;
 
 static av_always_inline int fold(int diff, int bits){
@@ -253,7 +275,7 @@
             occ[j]=1.0;
             for(k=0; k<256; k++){
                 double newocc[256]={0};
-                for(m=0; m<256; m++){
+                for(m=1; m<256; m++){
                     if(occ[m]){
                         len -=occ[m]*(     p *l2tab[    m]
                                       + (1-p)*l2tab[256-m]);
@@ -392,7 +414,7 @@
         i += i;
     }
 
-    assert(k<=8);
+    av_assert2(k<=13);
 
 #if 0 // JPEG LS
     if(k==0 && 2*state->drift <= - state->count) code= v ^ (-1);
@@ -540,56 +562,75 @@
         sample[0][-1]= sample[1][0  ];
         sample[1][ w]= sample[1][w-1];
 //{START_TIMER
-        if(s->avctx->bits_per_raw_sample<=8){
+        if(s->bits_per_raw_sample<=8){
             for(x=0; x<w; x++){
                 sample[0][x]= src[x + stride*y];
             }
             encode_line(s, w, sample, plane_index, 8);
         }else{
-            for(x=0; x<w; x++){
-                sample[0][x]= ((uint16_t*)(src + stride*y))[x] >> (16 - s->avctx->bits_per_raw_sample);
+            if(s->packed_at_lsb){
+                for(x=0; x<w; x++){
+                    sample[0][x]= ((uint16_t*)(src + stride*y))[x];
+                }
+            }else{
+                for(x=0; x<w; x++){
+                    sample[0][x]= ((uint16_t*)(src + stride*y))[x] >> (16 - s->bits_per_raw_sample);
+                }
             }
-            encode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample);
+            encode_line(s, w, sample, plane_index, s->bits_per_raw_sample);
         }
 //STOP_TIMER("encode line")}
     }
 }
 
-static void encode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){
+static void encode_rgb_frame(FFV1Context *s, uint8_t *src[3], int w, int h, int stride[3]){
     int x, y, p, i;
     const int ring_size= s->avctx->context_model ? 3 : 2;
-    int16_t *sample[3][3];
+    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 offset= 1 << bits;
     s->run_index=0;
 
-    memset(s->sample_buffer, 0, ring_size*3*(w+6)*sizeof(*s->sample_buffer));
+    memset(s->sample_buffer, 0, ring_size*4*(w+6)*sizeof(*s->sample_buffer));
 
     for(y=0; y<h; y++){
         for(i=0; i<ring_size; i++)
-            for(p=0; p<3; p++)
+            for(p=0; p<4; p++)
                 sample[p][i]= s->sample_buffer + p*ring_size*(w+6) + ((h+i-y)%ring_size)*(w+6) + 3;
 
         for(x=0; x<w; x++){
-            int v= src[x + stride*y];
-            int b= v&0xFF;
-            int g= (v>>8)&0xFF;
-            int r= (v>>16)&0xFF;
+            int b,g,r,av_uninit(a);
+            if(lbd){
+                unsigned v= *((uint32_t*)(src[0] + x*4 + stride[0]*y));
+                b= v&0xFF;
+                g= (v>>8)&0xFF;
+                r= (v>>16)&0xFF;
+                a=  v>>24;
+            }else{
+                b= *((uint16_t*)(src[0] + x*2 + stride[0]*y));
+                g= *((uint16_t*)(src[1] + x*2 + stride[1]*y));
+                r= *((uint16_t*)(src[2] + x*2 + stride[2]*y));
+            }
 
             b -= g;
             r -= g;
             g += (b + r)>>2;
-            b += 0x100;
-            r += 0x100;
+            b += offset;
+            r += offset;
 
-//            assert(g>=0 && b>=0 && r>=0);
-//            assert(g<256 && b<512 && r<512);
             sample[0][0][x]= g;
             sample[1][0][x]= b;
             sample[2][0][x]= r;
+            sample[3][0][x]= a;
         }
-        for(p=0; p<3; p++){
+        for(p=0; p<3 + s->transparency; p++){
             sample[p][0][-1]= sample[p][1][0  ];
             sample[p][1][ w]= sample[p][1][w-1];
-            encode_line(s, w, sample[p], FFMIN(p, 1), 9);
+            if (lbd)
+                encode_line(s, w, sample[p], (p+1)/2, 9);
+            else
+                encode_line(s, w, sample[p], (p+1)/2, bits+1);
         }
     }
 }
@@ -632,14 +673,14 @@
         }
         put_symbol(c, state, f->colorspace, 0); //YUV cs type
         if(f->version>0)
-            put_symbol(c, state, f->avctx->bits_per_raw_sample, 0);
-        put_rac(c, state, 1); //chroma planes
-            put_symbol(c, state, f->chroma_h_shift, 0);
-            put_symbol(c, state, f->chroma_v_shift, 0);
-        put_rac(c, state, 0); //no transparency plane
+            put_symbol(c, state, f->bits_per_raw_sample, 0);
+        put_rac(c, state, f->chroma_planes);
+        put_symbol(c, state, f->chroma_h_shift, 0);
+        put_symbol(c, state, f->chroma_v_shift, 0);
+        put_rac(c, state, f->transparency);
 
         write_quant_tables(c, f->quant_table);
-    }else{
+    }else if(f->version < 3){
         put_symbol(c, state, f->slice_count, 0);
         for(i=0; i<f->slice_count; i++){
             FFV1Context *fs= f->slice_context[i];
@@ -659,15 +700,19 @@
 static av_cold int common_init(AVCodecContext *avctx){
     FFV1Context *s = avctx->priv_data;
 
+    if(!avctx->width || !avctx->height)
+        return AVERROR_INVALIDDATA;
+
     s->avctx= avctx;
     s->flags= avctx->flags;
 
+    avcodec_get_frame_defaults(&s->picture);
+
     ff_dsputil_init(&s->dsp, avctx);
 
     s->width = avctx->width;
     s->height= avctx->height;
 
-    assert(s->width && s->height);
     //defaults
     s->num_h_slices=1;
     s->num_v_slices=1;
@@ -676,11 +721,11 @@
     return 0;
 }
 
-static int init_slice_state(FFV1Context *f){
-    int i, j;
+static int init_slice_state(FFV1Context *f, FFV1Context *fs){
+    int j;
 
-    for(i=0; i<f->slice_count; i++){
-        FFV1Context *fs= f->slice_context[i];
+        fs->plane_count= f->plane_count;
+        fs->transparency= f->transparency;
         for(j=0; j<f->plane_count; j++){
             PlaneContext * const p= &fs->plane[j];
 
@@ -698,15 +743,24 @@
         if (fs->ac>1){
             //FIXME only redo if state_transition changed
             for(j=1; j<256; j++){
-                fs->c.one_state [    j]= fs->state_transition[j];
+                fs->c.one_state [    j]= f->state_transition[j];
                 fs->c.zero_state[256-j]= 256-fs->c.one_state [j];
             }
         }
-    }
 
     return 0;
 }
 
+static int init_slices_state(FFV1Context *f){
+    int i;
+    for(i=0; i<f->slice_count; i++){
+        FFV1Context *fs= f->slice_context[i];
+        if(init_slice_state(f, fs) < 0)
+            return -1;
+    }
+    return 0;
+}
+
 static av_cold int init_slice_contexts(FFV1Context *f){
     int i;
 
@@ -729,7 +783,7 @@
         fs->slice_x     = sxs;
         fs->slice_y     = sys;
 
-        fs->sample_buffer = av_malloc(9 * (fs->width+6) * sizeof(*fs->sample_buffer));
+        fs->sample_buffer = av_malloc(3*4 * (fs->width+6) * sizeof(*fs->sample_buffer));
         if (!fs->sample_buffer)
             return AVERROR(ENOMEM);
     }
@@ -754,6 +808,7 @@
     uint8_t state[CONTEXT_SIZE];
     int i, j, k;
     uint8_t state2[32][CONTEXT_SIZE];
+    unsigned v;
 
     memset(state2, 128, sizeof(state2));
     memset(state, 128, sizeof(state));
@@ -763,6 +818,11 @@
     ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
 
     put_symbol(c, state, f->version, 0);
+    if(f->version > 2) {
+        if(f->version == 3)
+            f->minor_version = 2;
+        put_symbol(c, state, f->minor_version, 0);
+    }
     put_symbol(c, state, f->ac, 0);
     if(f->ac>1){
         for(i=1; i<256; i++){
@@ -770,11 +830,11 @@
         }
     }
     put_symbol(c, state, f->colorspace, 0); //YUV cs type
-    put_symbol(c, state, f->avctx->bits_per_raw_sample, 0);
-    put_rac(c, state, 1); //chroma planes
-        put_symbol(c, state, f->chroma_h_shift, 0);
-        put_symbol(c, state, f->chroma_v_shift, 0);
-    put_rac(c, state, 0); //no transparency plane
+    put_symbol(c, state, f->bits_per_raw_sample, 0);
+    put_rac(c, state, f->chroma_planes);
+    put_symbol(c, state, f->chroma_h_shift, 0);
+    put_symbol(c, state, f->chroma_v_shift, 0);
+    put_rac(c, state, f->transparency);
     put_symbol(c, state, f->num_h_slices-1, 0);
     put_symbol(c, state, f->num_v_slices-1, 0);
 
@@ -799,7 +859,14 @@
         }
     }
 
+    if(f->version > 2){
+        put_symbol(c, state, f->ec, 0);
+    }
+
     f->avctx->extradata_size= ff_rac_terminate(c);
+    v = av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0, f->avctx->extradata, f->avctx->extradata_size);
+    AV_WL32(f->avctx->extradata + f->avctx->extradata_size, v);
+    f->avctx->extradata_size += 4;
 
     return 0;
 }
@@ -849,22 +916,128 @@
 
 static av_cold int encode_init(AVCodecContext *avctx)
 {
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
     FFV1Context *s = avctx->priv_data;
     int i, j, k, m;
 
     common_init(avctx);
 
     s->version=0;
-    s->ac= avctx->coder_type ? 2:0;
+
+    if((avctx->flags & (CODEC_FLAG_PASS1|CODEC_FLAG_PASS2)) || avctx->slices>1)
+        s->version = FFMAX(s->version, 2);
+
+    if(avctx->level == 3){
+        s->version = 3;
+    }
+
+    if(s->ec < 0){
+        s->ec = (s->version >= 3);
+    }
+
+    if(s->version >= 2 && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+        av_log(avctx, AV_LOG_ERROR, "Version 2 needed for requested features but version 2 is experimental and not enabled\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    s->ac= avctx->coder_type > 0 ? 2 : 0;
+
+    s->plane_count=3;
+    switch(avctx->pix_fmt){
+    case AV_PIX_FMT_YUV444P9:
+    case AV_PIX_FMT_YUV422P9:
+    case AV_PIX_FMT_YUV420P9:
+        if (!avctx->bits_per_raw_sample)
+            s->bits_per_raw_sample = 9;
+    case AV_PIX_FMT_YUV444P10:
+    case AV_PIX_FMT_YUV420P10:
+    case AV_PIX_FMT_YUV422P10:
+        s->packed_at_lsb = 1;
+        if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample)
+            s->bits_per_raw_sample = 10;
+    case AV_PIX_FMT_GRAY16:
+    case AV_PIX_FMT_YUV444P16:
+    case AV_PIX_FMT_YUV422P16:
+    case AV_PIX_FMT_YUV420P16:
+        if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample) {
+            s->bits_per_raw_sample = 16;
+        } else if (!s->bits_per_raw_sample){
+            s->bits_per_raw_sample = avctx->bits_per_raw_sample;
+        }
+        if(s->bits_per_raw_sample <=8){
+            av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample invalid\n");
+            return AVERROR_INVALIDDATA;
+        }
+        if(!s->ac && avctx->coder_type == -1) {
+            av_log(avctx, AV_LOG_INFO, "bits_per_raw_sample > 8, forcing coder 1\n");
+            s->ac = 2;
+        }
+        if(!s->ac){
+            av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample of more than 8 needs -coder 1 currently\n");
+            return AVERROR_INVALIDDATA;
+        }
+        s->version= FFMAX(s->version, 1);
+    case AV_PIX_FMT_GRAY8:
+    case AV_PIX_FMT_YUV444P:
+    case AV_PIX_FMT_YUV440P:
+    case AV_PIX_FMT_YUV422P:
+    case AV_PIX_FMT_YUV420P:
+    case AV_PIX_FMT_YUV411P:
+    case AV_PIX_FMT_YUV410P:
+        s->chroma_planes= desc->nb_components < 3 ? 0 : 1;
+        s->colorspace= 0;
+        break;
+    case AV_PIX_FMT_YUVA444P:
+    case AV_PIX_FMT_YUVA422P:
+    case AV_PIX_FMT_YUVA420P:
+        s->chroma_planes= 1;
+        s->colorspace= 0;
+        s->transparency= 1;
+        break;
+    case AV_PIX_FMT_RGB32:
+        s->colorspace= 1;
+        s->transparency= 1;
+        break;
+    case AV_PIX_FMT_0RGB32:
+        s->colorspace= 1;
+        break;
+    case AV_PIX_FMT_GBRP9:
+        if (!avctx->bits_per_raw_sample)
+            s->bits_per_raw_sample = 9;
+    case AV_PIX_FMT_GBRP10:
+        if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample)
+            s->bits_per_raw_sample = 10;
+    case AV_PIX_FMT_GBRP12:
+        if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample)
+            s->bits_per_raw_sample = 12;
+    case AV_PIX_FMT_GBRP14:
+        if (!avctx->bits_per_raw_sample && !s->bits_per_raw_sample)
+            s->bits_per_raw_sample = 14;
+        else if (!s->bits_per_raw_sample)
+            s->bits_per_raw_sample = avctx->bits_per_raw_sample;
+        s->colorspace= 1;
+        s->chroma_planes= 1;
+        s->version= FFMAX(s->version, 1);
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "format not supported\n");
+        return AVERROR_INVALIDDATA;
+    }
+    if (s->transparency) {
+        av_log(avctx, AV_LOG_WARNING, "Storing alpha plane, this will require a recent FFV1 decoder to playback!\n");
+    }
+    if (avctx->context_model > 1U) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid context model %d, valid values are 0 and 1\n", avctx->context_model);
+        return AVERROR(EINVAL);
+    }
 
     if(s->ac>1)
         for(i=1; i<256; i++)
             s->state_transition[i]=ver2_state[i];
 
-    s->plane_count=2;
     for(i=0; i<256; i++){
         s->quant_table_count=2;
-        if(avctx->bits_per_raw_sample <=8){
+        if(s->bits_per_raw_sample <=8){
             s->quant_tables[0][0][i]=           quant11[i];
             s->quant_tables[0][1][i]=        11*quant11[i];
             s->quant_tables[0][2][i]=     11*11*quant11[i];
@@ -900,33 +1073,8 @@
         return AVERROR(ENOMEM);
 
     avctx->coded_frame= &s->picture;
-    switch(avctx->pix_fmt){
-    case AV_PIX_FMT_YUV444P16:
-    case AV_PIX_FMT_YUV422P16:
-    case AV_PIX_FMT_YUV420P16:
-        if(avctx->bits_per_raw_sample <=8){
-            av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample invalid\n");
-            return -1;
-        }
-        if(!s->ac){
-            av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample of more than 8 needs -coder 1 currently\n");
-            return -1;
-        }
-        s->version= FFMAX(s->version, 1);
-    case AV_PIX_FMT_YUV444P:
-    case AV_PIX_FMT_YUV422P:
-    case AV_PIX_FMT_YUV420P:
-    case AV_PIX_FMT_YUV411P:
-    case AV_PIX_FMT_YUV410P:
-        s->colorspace= 0;
-        break;
-    case AV_PIX_FMT_RGB32:
-        s->colorspace= 1;
-        break;
-    default:
-        av_log(avctx, AV_LOG_ERROR, "format not supported\n");
-        return -1;
-    }
+    if(!s->transparency)
+        s->plane_count= 2;
     avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift);
 
     s->picture_number=0;
@@ -964,7 +1112,7 @@
                             s->rc_stat2[i][j][k][m]= strtol(p, &next, 0);
                             if(next==p){
                                 av_log(avctx, AV_LOG_ERROR, "2Pass file invalid at %d %d %d %d [%s]\n", i,j,k,m,p);
-                                return -1;
+                                return AVERROR_INVALIDDATA;
                             }
                             p=next;
                         }
@@ -974,7 +1122,7 @@
             gob_count= strtol(p, &next, 0);
             if(next==p || gob_count <0){
                 av_log(avctx, AV_LOG_ERROR, "2Pass file invalid\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             p=next;
             while(*p=='\n' || *p==' ') p++;
@@ -998,14 +1146,21 @@
     }
 
     if(s->version>1){
-        s->num_h_slices=2;
-        s->num_v_slices=2;
+        for(s->num_v_slices=2; 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;
+            }
+        }
+        av_log(avctx, AV_LOG_ERROR, "Unsupported number %d of slices requested, please specify a supported number with -slices (ex:4,6,9,12,16, ...)\n", avctx->slices);
+        return -1;
+        slices_ok:
         write_extra_header(s);
     }
 
     if(init_slice_contexts(s) < 0)
         return -1;
-    if(init_slice_state(s) < 0)
+    if(init_slices_state(s) < 0)
         return -1;
 
 #define STATS_OUT_SIZE 1024*1024*6
@@ -1027,11 +1182,9 @@
 #endif /* CONFIG_FFV1_ENCODER */
 
 
-static void clear_state(FFV1Context *f){
-    int i, si, j;
+static void clear_slice_state(FFV1Context *f, FFV1Context *fs){
+    int i, j;
 
-    for(si=0; si<f->slice_count; si++){
-        FFV1Context *fs= f->slice_context[si];
         for(i=0; i<f->plane_count; i++){
             PlaneContext *p= &fs->plane[i];
 
@@ -1044,18 +1197,38 @@
                 }else
                 memset(p->state, 128, CONTEXT_SIZE*p->context_count);
             }else{
-            for(j=0; j<p->context_count; j++){
+                for(j=0; j<p->context_count; j++){
                     p->vlc_state[j].drift= 0;
                     p->vlc_state[j].error_sum= 4; //FFMAX((RANGE + 32)/64, 2);
                     p->vlc_state[j].bias= 0;
                     p->vlc_state[j].count= 1;
-            }
+                }
             }
         }
-    }
 }
 
 #if CONFIG_FFV1_ENCODER
+
+static void encode_slice_header(FFV1Context *f, FFV1Context *fs){
+    RangeCoder *c = &fs->c;
+    uint8_t state[CONTEXT_SIZE];
+    int j;
+    memset(state, 128, sizeof(state));
+
+    put_symbol(c, state, (fs->slice_x     +1)*f->num_h_slices / f->width   , 0);
+    put_symbol(c, state, (fs->slice_y     +1)*f->num_v_slices / f->height  , 0);
+    put_symbol(c, state, (fs->slice_width +1)*f->num_h_slices / f->width -1, 0);
+    put_symbol(c, state, (fs->slice_height+1)*f->num_v_slices / f->height-1, 0);
+    for(j=0; j<f->plane_count; j++){
+        put_symbol(c, state, f->plane[j].quant_table_index, 0);
+        av_assert0(f->plane[j].quant_table_index == f->avctx->context_model);
+    }
+    if(!f->picture.interlaced_frame) put_symbol(c, state, 3, 0);
+    else                             put_symbol(c, state, 1 + !f->picture.top_field_first, 0);
+    put_symbol(c, state, f->picture.sample_aspect_ratio.num, 0);
+    put_symbol(c, state, f->picture.sample_aspect_ratio.den, 0);
+}
+
 static int encode_slice(AVCodecContext *c, void *arg){
     FFV1Context *fs= *(void**)arg;
     FFV1Context *f= fs->avctx->priv_data;
@@ -1064,6 +1237,19 @@
     int x= fs->slice_x;
     int y= fs->slice_y;
     AVFrame * const p= &f->picture;
+    const int ps= (f->bits_per_raw_sample>8)+1;
+
+    if(p->key_frame)
+        clear_slice_state(f, fs);
+    if(f->version > 2){
+        encode_slice_header(f, fs);
+    }
+    if(!fs->ac){
+        if(f->version > 2)
+            put_rac(&fs->c, (uint8_t[]){129}, 0);
+        fs->ac_byte_count = f->version > 2 || (!x&&!y) ? ff_rac_terminate(&fs->c) : 0;
+        init_put_bits(&fs->pb, fs->c.bytestream_start + fs->ac_byte_count, fs->c.bytestream_end - fs->c.bytestream_start - fs->ac_byte_count);
+    }
 
     if(f->colorspace==0){
         const int chroma_width = -((-width )>>f->chroma_h_shift);
@@ -1071,12 +1257,19 @@
         const int cx= x>>f->chroma_h_shift;
         const int cy= y>>f->chroma_v_shift;
 
-        encode_plane(fs, p->data[0] + x + y*p->linesize[0], width, height, p->linesize[0], 0);
+        encode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0);
 
-        encode_plane(fs, p->data[1] + cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1);
-        encode_plane(fs, p->data[2] + cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1);
+        if (f->chroma_planes){
+            encode_plane(fs, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1);
+            encode_plane(fs, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1);
+        }
+        if (fs->transparency)
+            encode_plane(fs, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 2);
     }else{
-        encode_rgb_frame(fs, (uint32_t*)(p->data[0]) + x + y*(p->linesize[0]/4), width, height, p->linesize[0]/4);
+        uint8_t *planes[3] = {p->data[0] + ps*x + y*p->linesize[0],
+                              p->data[1] + ps*x + y*p->linesize[1],
+                              p->data[2] + ps*x + y*p->linesize[2]};
+        encode_rgb_frame(fs, planes, width, height, p->linesize);
     }
     emms_c();
 
@@ -1094,12 +1287,9 @@
     uint8_t *buf_p;
     int i, ret;
 
-    if (!pkt->data &&
-        (ret = av_new_packet(pkt, avctx->width*avctx->height*((8*2+1+1)*4)/8
-                                  + FF_MIN_BUFFER_SIZE)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*((8*2+1+1)*4)/8
+                                  + FF_MIN_BUFFER_SIZE)) < 0)
         return ret;
-    }
 
     ff_init_range_encoder(c, pkt->data, pkt->size);
     ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
@@ -1112,16 +1302,12 @@
         p->key_frame= 1;
         f->gob_count++;
         write_header(f);
-        clear_state(f);
     }else{
         put_rac(c, &keystate, 0);
         p->key_frame= 0;
     }
 
-    if(!f->ac){
-        used_count += ff_rac_terminate(c);
-        init_put_bits(&f->slice_context[0]->pb, pkt->data + used_count, pkt->size - used_count);
-    }else if (f->ac>1){
+    if (f->ac>1){
         int i;
         for(i=1; i<256; i++){
             c->one_state[i]= f->state_transition[i];
@@ -1131,14 +1317,9 @@
 
     for(i=1; i<f->slice_count; i++){
         FFV1Context *fs= f->slice_context[i];
-        uint8_t *start = pkt->data + (pkt->size-used_count)*i/f->slice_count;
+        uint8_t *start = pkt->data + (pkt->size-used_count)*(int64_t)i/f->slice_count;
         int len = pkt->size/f->slice_count;
-
-        if(fs->ac){
-            ff_init_range_encoder(&fs->c, start, len);
-        }else{
-            init_put_bits(&fs->pb, start, len);
-        }
+        ff_init_range_encoder(&fs->c, start, len);
     }
     avctx->execute(avctx, encode_slice, &f->slice_context[0], NULL, f->slice_count, sizeof(void*));
 
@@ -1148,21 +1329,26 @@
         int bytes;
 
         if(fs->ac){
-            uint8_t state=128;
+            uint8_t state=129;
             put_rac(&fs->c, &state, 0);
             bytes= ff_rac_terminate(&fs->c);
         }else{
             flush_put_bits(&fs->pb); //nicer padding FIXME
-            bytes= used_count + (put_bits_count(&fs->pb)+7)/8;
-            used_count= 0;
+            bytes= fs->ac_byte_count + (put_bits_count(&fs->pb)+7)/8;
         }
-        if(i>0){
+        if(i>0 || f->version>2){
             av_assert0(bytes < pkt->size/f->slice_count);
-            memmove(buf_p, fs->ac ? fs->c.bytestream_start : fs->pb.buf, bytes);
+            memmove(buf_p, fs->c.bytestream_start, bytes);
             av_assert0(bytes < (1<<24));
             AV_WB24(buf_p+bytes, bytes);
             bytes+=3;
         }
+        if(f->ec){
+            unsigned v;
+            buf_p[bytes++] = 0;
+            v = av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0, buf_p, bytes);
+            AV_WL32(buf_p + bytes, v); bytes += 4;
+        }
         buf_p += bytes;
     }
 
@@ -1224,6 +1410,8 @@
 
     if (avctx->codec->decode && s->picture.data[0])
         avctx->release_buffer(avctx, &s->picture);
+    if (avctx->codec->decode && s->last_picture.data[0])
+        avctx->release_buffer(avctx, &s->last_picture);
 
     for(j=0; j<s->slice_count; j++){
         FFV1Context *fs= s->slice_context[j];
@@ -1342,28 +1530,37 @@
             }
         }else{
             decode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample);
-            for(x=0; x<w; x++){
-                ((uint16_t*)(src + stride*y))[x]= sample[1][x] << (16 - s->avctx->bits_per_raw_sample);
+            if(s->packed_at_lsb){
+                for(x=0; x<w; x++){
+                    ((uint16_t*)(src + stride*y))[x]= sample[1][x];
+                }
+            }else{
+                for(x=0; x<w; x++){
+                    ((uint16_t*)(src + stride*y))[x]= sample[1][x] << (16 - s->avctx->bits_per_raw_sample);
+                }
             }
         }
 //STOP_TIMER("decode-line")}
     }
 }
 
-static void decode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){
+static void decode_rgb_frame(FFV1Context *s, uint8_t *src[3], int w, int h, int stride[3]){
     int x, y, p;
-    int16_t *sample[3][2];
-    for(x=0; x<3; x++){
+    int16_t *sample[4][2];
+    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 offset= 1 << bits;
+    for(x=0; x<4; x++){
         sample[x][0] = s->sample_buffer +  x*2   *(w+6) + 3;
         sample[x][1] = s->sample_buffer + (x*2+1)*(w+6) + 3;
     }
 
     s->run_index=0;
 
-    memset(s->sample_buffer, 0, 6*(w+6)*sizeof(*s->sample_buffer));
+    memset(s->sample_buffer, 0, 8*(w+6)*sizeof(*s->sample_buffer));
 
     for(y=0; y<h; y++){
-        for(p=0; p<3; p++){
+        for(p=0; p<3 + s->transparency; p++){
             int16_t *temp = sample[p][0]; //FIXME try a normal buffer
 
             sample[p][0]= sample[p][1];
@@ -1371,48 +1568,152 @@
 
             sample[p][1][-1]= sample[p][0][0  ];
             sample[p][0][ w]= sample[p][0][w-1];
-            decode_line(s, w, sample[p], FFMIN(p, 1), 9);
+            if (lbd)
+                decode_line(s, w, sample[p], (p+1)/2, 9);
+            else
+                decode_line(s, w, sample[p], (p+1)/2, bits+1);
         }
         for(x=0; x<w; x++){
             int g= sample[0][1][x];
             int b= sample[1][1][x];
             int r= sample[2][1][x];
+            int a= sample[3][1][x];
 
-//            assert(g>=0 && b>=0 && r>=0);
-//            assert(g<256 && b<512 && r<512);
-
-            b -= 0x100;
-            r -= 0x100;
+            b -= offset;
+            r -= offset;
             g -= (b + r)>>2;
             b += g;
             r += g;
 
-            src[x + stride*y]= b + (g<<8) + (r<<16) + (0xFF<<24);
+            if(lbd)
+                *((uint32_t*)(src[0] + x*4 + stride[0]*y))= b + (g<<8) + (r<<16) + (a<<24);
+            else{
+                *((uint16_t*)(src[0] + x*2 + stride[0]*y)) = b;
+                *((uint16_t*)(src[1] + x*2 + stride[1]*y)) = g;
+                *((uint16_t*)(src[2] + x*2 + stride[2]*y)) = r;
+            }
         }
     }
 }
 
+static int decode_slice_header(FFV1Context *f, FFV1Context *fs){
+    RangeCoder *c = &fs->c;
+    uint8_t state[CONTEXT_SIZE];
+    unsigned ps, i, context_count;
+    memset(state, 128, sizeof(state));
+
+    av_assert0(f->version > 2);
+
+    fs->slice_x     = get_symbol(c, state, 0)   *f->width ;
+    fs->slice_y     = get_symbol(c, state, 0)   *f->height;
+    fs->slice_width =(get_symbol(c, state, 0)+1)*f->width  + fs->slice_x;
+    fs->slice_height=(get_symbol(c, state, 0)+1)*f->height + fs->slice_y;
+
+    fs->slice_x /= f->num_h_slices;
+    fs->slice_y /= f->num_v_slices;
+    fs->slice_width  = fs->slice_width /f->num_h_slices - fs->slice_x;
+    fs->slice_height = fs->slice_height/f->num_v_slices - fs->slice_y;
+    if((unsigned)fs->slice_width > f->width || (unsigned)fs->slice_height > f->height)
+        return -1;
+    if(    (unsigned)fs->slice_x + (uint64_t)fs->slice_width  > f->width
+        || (unsigned)fs->slice_y + (uint64_t)fs->slice_height > f->height)
+        return -1;
+
+    for(i=0; i<f->plane_count; i++){
+        PlaneContext * const p= &fs->plane[i];
+        int idx=get_symbol(c, state, 0);
+        if(idx > (unsigned)f->quant_table_count){
+            av_log(f->avctx, AV_LOG_ERROR, "quant_table_index out of range\n");
+            return -1;
+        }
+        p->quant_table_index= idx;
+        memcpy(p->quant_table, f->quant_tables[idx], sizeof(p->quant_table));
+        context_count= f->context_count[idx];
+
+        if(p->context_count < context_count){
+            av_freep(&p->state);
+            av_freep(&p->vlc_state);
+        }
+        p->context_count= context_count;
+    }
+
+    ps = get_symbol(c, state, 0);
+    if(ps==1){
+        f->picture.interlaced_frame = 1;
+        f->picture.top_field_first  = 1;
+    } else if(ps==2){
+        f->picture.interlaced_frame = 1;
+        f->picture.top_field_first  = 0;
+    } else if(ps==3){
+        f->picture.interlaced_frame = 0;
+    }
+    f->picture.sample_aspect_ratio.num = get_symbol(c, state, 0);
+    f->picture.sample_aspect_ratio.den = get_symbol(c, state, 0);
+
+    return 0;
+}
+
 static int decode_slice(AVCodecContext *c, void *arg){
     FFV1Context *fs= *(void**)arg;
     FFV1Context *f= fs->avctx->priv_data;
-    int width = fs->slice_width;
-    int height= fs->slice_height;
-    int x= fs->slice_x;
-    int y= fs->slice_y;
+    int width, height, x, y;
+    const int ps= (c->bits_per_raw_sample>8)+1;
     AVFrame * const p= &f->picture;
 
+    if(f->version > 2){
+        if(init_slice_state(f, fs) < 0)
+            return AVERROR(ENOMEM);
+        if(decode_slice_header(f, fs) < 0) {
+            fs->slice_damaged = 1;
+            return AVERROR_INVALIDDATA;
+        }
+    }
+    if(init_slice_state(f, fs) < 0)
+        return AVERROR(ENOMEM);
+    if(f->picture.key_frame)
+        clear_slice_state(f, fs);
+    width = fs->slice_width;
+    height= fs->slice_height;
+    x= fs->slice_x;
+    y= fs->slice_y;
+
+    if(!fs->ac){
+        if (f->version == 3 && f->minor_version > 1 || f->version > 3)
+            get_rac(&fs->c, (uint8_t[]){129});
+        fs->ac_byte_count = f->version > 2 || (!x&&!y) ? fs->c.bytestream - fs->c.bytestream_start - 1 : 0;
+        init_get_bits(&fs->gb,
+                      fs->c.bytestream_start + fs->ac_byte_count,
+                      (fs->c.bytestream_end - fs->c.bytestream_start - fs->ac_byte_count) * 8);
+    }
+
     av_assert1(width && height);
     if(f->colorspace==0){
         const int chroma_width = -((-width )>>f->chroma_h_shift);
         const int chroma_height= -((-height)>>f->chroma_v_shift);
         const int cx= x>>f->chroma_h_shift;
         const int cy= y>>f->chroma_v_shift;
-        decode_plane(fs, p->data[0] + x + y*p->linesize[0], width, height, p->linesize[0], 0);
+        decode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0);
 
-        decode_plane(fs, p->data[1] + cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1);
-        decode_plane(fs, p->data[2] + cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[2], 1);
+        if (f->chroma_planes){
+            decode_plane(fs, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1);
+            decode_plane(fs, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1);
+        }
+        if (fs->transparency)
+            decode_plane(fs, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 2);
     }else{
-        decode_rgb_frame(fs, (uint32_t*)p->data[0] + x + y*(p->linesize[0]/4), width, height, p->linesize[0]/4);
+        uint8_t *planes[3] = {p->data[0] + ps*x + y*p->linesize[0],
+                              p->data[1] + ps*x + y*p->linesize[1],
+                              p->data[2] + ps*x + y*p->linesize[2]};
+        decode_rgb_frame(fs, planes, width, height, p->linesize);
+    }
+    if(fs->ac && f->version > 2) {
+        int v;
+        get_rac(&fs->c, (uint8_t[]){129});
+        v = fs->c.bytestream_end - fs->c.bytestream - 2 - 5*f->ec;
+        if(v) {
+            av_log(f->avctx, AV_LOG_ERROR, "bytestream end mismatching by %d\n", v);
+            fs->slice_damaged = 1;
+        }
     }
 
     emms_c();
@@ -1428,9 +1729,9 @@
     memset(state, 128, sizeof(state));
 
     for(v=0; i<128 ; v++){
-        int len= get_symbol(c, state, 0) + 1;
+        unsigned len= get_symbol(c, state, 0) + 1;
 
-        if(len + i > 128) return -1;
+        if(len > 128 - i) return -1;
 
         while(len--){
             quant_table[i] = scale*v;
@@ -1472,6 +1773,10 @@
     ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
 
     f->version= get_symbol(c, state, 0);
+    if(f->version > 2) {
+        c->bytestream_end -= 4;
+        f->minor_version= get_symbol(c, state, 0);
+    }
     f->ac= f->avctx->coder_type= get_symbol(c, state, 0);
     if(f->ac>1){
         for(i=1; i<256; i++){
@@ -1480,11 +1785,11 @@
     }
     f->colorspace= get_symbol(c, state, 0); //YUV cs type
     f->avctx->bits_per_raw_sample= get_symbol(c, state, 0);
-    get_rac(c, state); //no chroma = false
+    f->chroma_planes= get_rac(c, state);
     f->chroma_h_shift= get_symbol(c, state, 0);
     f->chroma_v_shift= get_symbol(c, state, 0);
-    get_rac(c, state); //transparency plane
-    f->plane_count= 2;
+    f->transparency= get_rac(c, state);
+    f->plane_count= 2 + f->transparency;
     f->num_h_slices= 1 + get_symbol(c, state, 0);
     f->num_v_slices= 1 + get_symbol(c, state, 0);
     if(f->num_h_slices > (unsigned)f->width || f->num_v_slices > (unsigned)f->height){
@@ -1516,18 +1821,36 @@
         }
     }
 
+    if(f->version > 2){
+        f->ec = get_symbol(c, state, 0);
+    }
+
+    if(f->version > 2){
+        unsigned v;
+        v = av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0, f->avctx->extradata, f->avctx->extradata_size);
+        if(v){
+            av_log(f->avctx, AV_LOG_ERROR, "CRC mismatch %X!\n", v);
+            return AVERROR_INVALIDDATA;
+        }
+    }
+
     return 0;
 }
 
 static int read_header(FFV1Context *f){
     uint8_t state[CONTEXT_SIZE];
-    int i, j, context_count;
+    int i, j, context_count = -1; //-1 to avoid warning
     RangeCoder * const c= &f->slice_context[0]->c;
 
     memset(state, 128, sizeof(state));
 
     if(f->version < 2){
-        f->version= get_symbol(c, state, 0);
+        unsigned v= get_symbol(c, state, 0);
+        if(v >= 2){
+            av_log(f->avctx, AV_LOG_ERROR, "invalid version %d in ver01 header\n", v);
+            return AVERROR_INVALIDDATA;
+        }
+        f->version = v;
         f->ac= f->avctx->coder_type= get_symbol(c, state, 0);
         if(f->ac>1){
             for(i=1; i<256; i++){
@@ -1537,17 +1860,23 @@
         f->colorspace= get_symbol(c, state, 0); //YUV cs type
         if(f->version>0)
             f->avctx->bits_per_raw_sample= get_symbol(c, state, 0);
-        get_rac(c, state); //no chroma = false
+        f->chroma_planes= get_rac(c, state);
         f->chroma_h_shift= get_symbol(c, state, 0);
         f->chroma_v_shift= get_symbol(c, state, 0);
-        get_rac(c, state); //transparency plane
-        f->plane_count= 2;
+        f->transparency= get_rac(c, state);
+        f->plane_count= 2 + f->transparency;
     }
 
     if(f->colorspace==0){
-        if(f->avctx->bits_per_raw_sample<=8){
+        if(!f->transparency && !f->chroma_planes){
+            if (f->avctx->bits_per_raw_sample<=8)
+                f->avctx->pix_fmt= AV_PIX_FMT_GRAY8;
+            else
+                f->avctx->pix_fmt= AV_PIX_FMT_GRAY16;
+        }else if(f->avctx->bits_per_raw_sample<=8 && !f->transparency){
             switch(16*f->chroma_h_shift + f->chroma_v_shift){
             case 0x00: f->avctx->pix_fmt= AV_PIX_FMT_YUV444P; break;
+            case 0x01: f->avctx->pix_fmt= AV_PIX_FMT_YUV440P; break;
             case 0x10: f->avctx->pix_fmt= AV_PIX_FMT_YUV422P; break;
             case 0x11: f->avctx->pix_fmt= AV_PIX_FMT_YUV420P; break;
             case 0x20: f->avctx->pix_fmt= AV_PIX_FMT_YUV411P; break;
@@ -1556,7 +1885,36 @@
                 av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
                 return -1;
             }
-        }else{
+        }else if(f->avctx->bits_per_raw_sample<=8 && f->transparency){
+            switch(16*f->chroma_h_shift + f->chroma_v_shift){
+            case 0x00: f->avctx->pix_fmt= AV_PIX_FMT_YUVA444P; break;
+            case 0x10: f->avctx->pix_fmt= AV_PIX_FMT_YUVA422P; break;
+            case 0x11: f->avctx->pix_fmt= AV_PIX_FMT_YUVA420P; break;
+            default:
+                av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
+                return -1;
+            }
+        }else if(f->avctx->bits_per_raw_sample==9) {
+            f->packed_at_lsb=1;
+            switch(16*f->chroma_h_shift + f->chroma_v_shift){
+            case 0x00: f->avctx->pix_fmt= AV_PIX_FMT_YUV444P9; break;
+            case 0x10: f->avctx->pix_fmt= AV_PIX_FMT_YUV422P9; break;
+            case 0x11: f->avctx->pix_fmt= AV_PIX_FMT_YUV420P9; break;
+            default:
+                av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
+                return -1;
+            }
+        }else if(f->avctx->bits_per_raw_sample==10) {
+            f->packed_at_lsb=1;
+            switch(16*f->chroma_h_shift + f->chroma_v_shift){
+            case 0x00: f->avctx->pix_fmt= AV_PIX_FMT_YUV444P10; break;
+            case 0x10: f->avctx->pix_fmt= AV_PIX_FMT_YUV422P10; break;
+            case 0x11: f->avctx->pix_fmt= AV_PIX_FMT_YUV420P10; break;
+            default:
+                av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
+                return -1;
+            }
+        }else {
             switch(16*f->chroma_h_shift + f->chroma_v_shift){
             case 0x00: f->avctx->pix_fmt= AV_PIX_FMT_YUV444P16; break;
             case 0x10: f->avctx->pix_fmt= AV_PIX_FMT_YUV422P16; break;
@@ -1571,7 +1929,17 @@
             av_log(f->avctx, AV_LOG_ERROR, "chroma subsampling not supported in this colorspace\n");
             return -1;
         }
-        f->avctx->pix_fmt= AV_PIX_FMT_RGB32;
+        if(f->avctx->bits_per_raw_sample==9)
+            f->avctx->pix_fmt= AV_PIX_FMT_GBRP9;
+        else if(f->avctx->bits_per_raw_sample==10)
+            f->avctx->pix_fmt= AV_PIX_FMT_GBRP10;
+        else if(f->avctx->bits_per_raw_sample==12)
+            f->avctx->pix_fmt= AV_PIX_FMT_GBRP12;
+        else if(f->avctx->bits_per_raw_sample==14)
+            f->avctx->pix_fmt= AV_PIX_FMT_GBRP14;
+        else
+        if(f->transparency) f->avctx->pix_fmt= AV_PIX_FMT_RGB32;
+        else                f->avctx->pix_fmt= AV_PIX_FMT_0RGB32;
     }else{
         av_log(f->avctx, AV_LOG_ERROR, "colorspace not supported\n");
         return -1;
@@ -1585,17 +1953,31 @@
                 av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n");
                 return -1;
         }
-    }else{
+    }else if(f->version < 3){
         f->slice_count= get_symbol(c, state, 0);
-        if(f->slice_count > (unsigned)MAX_SLICES)
-            return -1;
+    }else{
+        const uint8_t *p= c->bytestream_end;
+        for(f->slice_count = 0; f->slice_count < MAX_SLICES && 3 < p - c->bytestream_start; f->slice_count++){
+            int trailer = 3 + 5*!!f->ec;
+            int size = AV_RB24(p-trailer);
+            if(size + trailer > p - c->bytestream_start)
+                break;
+            p -= size + trailer;
+        }
+    }
+    if(f->slice_count > (unsigned)MAX_SLICES || f->slice_count <= 0){
+        av_log(f->avctx, AV_LOG_ERROR, "slice count %d is invalid\n", f->slice_count);
+        return -1;
     }
 
     for(j=0; j<f->slice_count; j++){
         FFV1Context *fs= f->slice_context[j];
         fs->ac= f->ac;
+        fs->packed_at_lsb= f->packed_at_lsb;
 
-        if(f->version >= 2){
+        fs->slice_damaged = 0;
+
+        if(f->version == 2){
             fs->slice_x     = get_symbol(c, state, 0)   *f->width ;
             fs->slice_y     = get_symbol(c, state, 0)   *f->height;
             fs->slice_width =(get_symbol(c, state, 0)+1)*f->width  + fs->slice_x;
@@ -1615,7 +1997,7 @@
         for(i=0; i<f->plane_count; i++){
             PlaneContext * const p= &fs->plane[i];
 
-            if(f->version >= 2){
+            if(f->version == 2){
                 int idx=get_symbol(c, state, 0);
                 if(idx > (unsigned)f->quant_table_count){
                     av_log(f->avctx, AV_LOG_ERROR, "quant_table_index out of range\n");
@@ -1628,14 +2010,16 @@
                 memcpy(p->quant_table, f->quant_table, sizeof(p->quant_table));
             }
 
-            if(p->context_count < context_count){
-                av_freep(&p->state);
-                av_freep(&p->vlc_state);
+            if(f->version <= 2){
+                av_assert0(context_count>=0);
+                if(p->context_count < context_count){
+                    av_freep(&p->state);
+                    av_freep(&p->vlc_state);
+                }
+                p->context_count= context_count;
             }
-            p->context_count= context_count;
         }
     }
-
     return 0;
 }
 
@@ -1660,7 +2044,7 @@
     FFV1Context *f = avctx->priv_data;
     RangeCoder * const c= &f->slice_context[0]->c;
     AVFrame * const p= &f->picture;
-    int bytes_read, i;
+    int i;
     uint8_t keystate= 128;
     const uint8_t *buf_p;
 
@@ -1677,62 +2061,91 @@
     p->pict_type= AV_PICTURE_TYPE_I; //FIXME I vs. P
     if(get_rac(c, &keystate)){
         p->key_frame= 1;
+        f->key_frame_ok = 0;
         if(read_header(f) < 0)
             return -1;
-        if(init_slice_state(f) < 0)
-            return -1;
-
-        clear_state(f);
+        f->key_frame_ok = 1;
     }else{
+        if (!f->key_frame_ok) {
+            av_log(avctx, AV_LOG_ERROR, "Cant decode non keyframe without valid keyframe\n");
+            return AVERROR_INVALIDDATA;
+        }
         p->key_frame= 0;
     }
-    if(f->ac>1){
-        int i;
-        for(i=1; i<256; i++){
-            c->one_state[i]= f->state_transition[i];
-            c->zero_state[256-i]= 256-c->one_state[i];
-        }
-    }
 
-    p->reference= 0;
+    p->reference= 3; //for error concealment
     if(avctx->get_buffer(avctx, p) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
 
     if(avctx->debug&FF_DEBUG_PICT_INFO)
-        av_log(avctx, AV_LOG_ERROR, "keyframe:%d coder:%d\n", p->key_frame, f->ac);
-
-    if(!f->ac){
-        bytes_read = c->bytestream - c->bytestream_start - 1;
-        if(bytes_read ==0) av_log(avctx, AV_LOG_ERROR, "error at end of AC stream\n"); //FIXME
-        init_get_bits(&f->slice_context[0]->gb, buf + bytes_read, (buf_size - bytes_read) * 8);
-    } else {
-        bytes_read = 0; /* avoid warning */
-    }
+        av_log(avctx, AV_LOG_DEBUG, "ver:%d keyframe:%d coder:%d ec:%d slices:%d bps:%d\n",
+               f->version, p->key_frame, f->ac, f->ec, f->slice_count, f->avctx->bits_per_raw_sample);
 
     buf_p= buf + buf_size;
-    for(i=f->slice_count-1; i>0; i--){
+    for(i=f->slice_count-1; i>=0; i--){
         FFV1Context *fs= f->slice_context[i];
-        int v= AV_RB24(buf_p-3)+3;
-        if(buf_p - buf <= v){
+        int trailer = 3 + 5*!!f->ec;
+        int v;
+
+        if(i || f->version>2) v = AV_RB24(buf_p-trailer)+trailer;
+        else                  v = buf_p - c->bytestream_start;
+        if(buf_p - c->bytestream_start < v){
             av_log(avctx, AV_LOG_ERROR, "Slice pointer chain broken\n");
             return -1;
         }
         buf_p -= v;
-        if(fs->ac){
-            ff_init_range_decoder(&fs->c, buf_p, v);
-        }else{
-            init_get_bits(&fs->gb, buf_p, v * 8);
+
+        if(f->ec){
+            unsigned crc = av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0, buf_p, v);
+            if(crc){
+                int64_t ts = avpkt->pts != AV_NOPTS_VALUE ? avpkt->pts : avpkt->dts;
+                av_log(f->avctx, AV_LOG_ERROR, "CRC mismatch %X!", crc);
+                if(ts != AV_NOPTS_VALUE && avctx->pkt_timebase.num) {
+                    av_log(f->avctx, AV_LOG_ERROR, "at %f seconds\n",ts*av_q2d(avctx->pkt_timebase));
+                } else if(ts != AV_NOPTS_VALUE) {
+                    av_log(f->avctx, AV_LOG_ERROR, "at %"PRId64"\n", ts);
+                } else {
+                    av_log(f->avctx, AV_LOG_ERROR, "\n");
+                }
+                fs->slice_damaged = 1;
+            }
         }
+
+        if(i){
+            ff_init_range_decoder(&fs->c, buf_p, v);
+        }else
+            fs->c.bytestream_end = (uint8_t *)(buf_p + v);
     }
 
     avctx->execute(avctx, decode_slice, &f->slice_context[0], NULL, f->slice_count, sizeof(void*));
+
+    for(i=f->slice_count-1; i>=0; i--){
+        FFV1Context *fs= f->slice_context[i];
+        int j;
+        if(fs->slice_damaged && f->last_picture.data[0]){
+            uint8_t *dst[4], *src[4];
+            for(j=0; j<4; j++){
+                int sh = (j==1 || j==2) ? f->chroma_h_shift : 0;
+                int sv = (j==1 || j==2) ? f->chroma_v_shift : 0;
+                dst[j] = f->picture     .data[j] + f->picture     .linesize[j]*
+                         (fs->slice_y>>sv) + (fs->slice_x>>sh);
+                src[j] = f->last_picture.data[j] + f->last_picture.linesize[j]*
+                         (fs->slice_y>>sv) + (fs->slice_x>>sh);
+            }
+            av_image_copy(dst, f->picture.linesize, (const uint8_t **)src, f->last_picture.linesize,
+                          avctx->pix_fmt, fs->slice_width, fs->slice_height);
+        }
+    }
+
     f->picture_number++;
 
     *picture= *p;
     *data_size = sizeof(AVFrame);
 
+    FFSWAP(AVFrame, f->picture, f->last_picture);
+
     return buf_size;
 }
 
@@ -1750,6 +2163,26 @@
 };
 
 #if CONFIG_FFV1_ENCODER
+
+#define OFFSET(x) offsetof(FFV1Context, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "slicecrc",        "Protect slices with CRCs",               OFFSET(ec),              AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, VE},
+{NULL}
+};
+
+static const AVClass class = {
+    .class_name = "ffv1 encoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVCodecDefault ffv1_defaults[] = {
+    { "coder",                "-1" },
+    { NULL },
+};
+
 AVCodec ff_ffv1_encoder = {
     .name           = "ffv1",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -1759,11 +2192,18 @@
     .encode2        = encode_frame,
     .close          = common_end,
     .capabilities   = CODEC_CAP_SLICE_THREADS,
+    .defaults       = ffv1_defaults,
     .pix_fmts       = (const enum AVPixelFormat[]){
-        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P,
-        AV_PIX_FMT_YUV410P, AV_PIX_FMT_RGB32, AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16,
-        AV_PIX_FMT_YUV444P16, AV_PIX_FMT_NONE
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV444P,
+        AV_PIX_FMT_YUVA444P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_YUV410P, AV_PIX_FMT_0RGB32, AV_PIX_FMT_RGB32, AV_PIX_FMT_YUV420P16,
+        AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_YUV444P9, AV_PIX_FMT_YUV422P9,
+        AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
+        AV_PIX_FMT_GRAY16, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GBRP9, AV_PIX_FMT_GBRP10,
+        AV_PIX_FMT_GBRP12, AV_PIX_FMT_GBRP14,
+        AV_PIX_FMT_NONE
     },
     .long_name      = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
+    .priv_class     = &class,
 };
 #endif
diff --git a/libavcodec/ffwavesynth.c b/libavcodec/ffwavesynth.c
new file mode 100644
index 0000000..c63b90f
--- /dev/null
+++ b/libavcodec/ffwavesynth.c
@@ -0,0 +1,482 @@
+/*
+ * Wavesynth pseudo-codec
+ * Copyright (c) 2011 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/intreadwrite.h"
+#include "libavutil/log.h"
+#include "avcodec.h"
+
+#define SIN_BITS 14
+#define WS_MAX_CHANNELS 32
+#define INF_TS 0x7FFFFFFFFFFFFFFF
+
+#define PINK_UNIT 128
+
+/*
+   Format of the extradata and packets
+
+   THIS INFORMATION IS NOT PART OF THE PUBLIC API OR ABI.
+   IT CAN CHANGE WITHOUT NOTIFICATION.
+
+   All numbers are in little endian.
+
+   The codec extradata define a set of intervals with uniform content.
+   Overlapping intervals are added together.
+
+   extradata:
+       uint32      number of intervals
+       ...         intervals
+
+   interval:
+       int64       start timestamp; time_base must be 1/sample_rate;
+                   start timestamps must be in ascending order
+       int64       end timestamp
+       uint32      type
+       uint32      channels mask
+       ...         additional information, depends on type
+
+   sine interval (type fourcc "SINE"):
+       int32       start frequency, in 1/(1<<16) Hz
+       int32       end frequency
+       int32       start amplitude, 1<<16 is the full amplitude
+       int32       end amplitude
+       uint32      start phase, 0 is sin(0), 0x20000000 is sin(pi/2), etc.;
+                   n | (1<<31) means to match the phase of previous channel #n
+
+   pink noise interval (type fourcc "NOIS"):
+       int32       start amplitude
+       int32       end amplitude
+
+   The input packets encode the time and duration of the requested segment.
+
+   packet:
+       int64       start timestamp
+       int32       duration
+
+*/
+
+enum ws_interval_type {
+    WS_SINE  = MKTAG('S','I','N','E'),
+    WS_NOISE = MKTAG('N','O','I','S'),
+};
+
+struct ws_interval {
+    int64_t ts_start, ts_end;
+    uint64_t phi0, dphi0, ddphi;
+    uint64_t amp0, damp;
+    uint64_t phi, dphi, amp;
+    uint32_t channels;
+    enum ws_interval_type type;
+    int next;
+};
+
+struct wavesynth_context {
+    int64_t cur_ts;
+    int64_t next_ts;
+    int32_t *sin;
+    AVFrame frame;
+    struct ws_interval *inter;
+    uint32_t dither_state;
+    uint32_t pink_state;
+    int32_t pink_pool[PINK_UNIT];
+    unsigned pink_need, pink_pos;
+    int nb_inter;
+    int cur_inter;
+    int next_inter;
+};
+
+#define LCG_A 1284865837
+#define LCG_C 4150755663
+#define LCG_AI 849225893 /* A*AI = 1 [mod 1<<32] */
+
+static uint32_t lcg_next(uint32_t *s)
+{
+    *s = *s * LCG_A + LCG_C;
+    return *s;
+}
+
+static void lcg_seek(uint32_t *s, int64_t dt)
+{
+    uint32_t a, c, t = *s;
+
+    if (dt >= 0) {
+        a = LCG_A;
+        c = LCG_C;
+    } else { /* coefficients for a step backward */
+        a = LCG_AI;
+        c = (uint32_t)(LCG_AI * LCG_C);
+        dt = -dt;
+    }
+    while (dt) {
+        if (dt & 1)
+            t = a * t + c;
+        c *= a + 1; /* coefficients for a double step */
+        a *= a;
+        dt >>= 1;
+    }
+    *s = t;
+}
+
+/* Emulate pink noise by summing white noise at the sampling frequency,
+ * white noise at half the sampling frequency (each value taken twice),
+ * etc., with a total of 8 octaves.
+ * This is known as the Voss-McCartney algorithm. */
+
+static void pink_fill(struct wavesynth_context *ws)
+{
+    int32_t vt[7] = { 0 }, v = 0;
+    int i, j;
+
+    ws->pink_pos = 0;
+    if (!ws->pink_need)
+        return;
+    for (i = 0; i < PINK_UNIT; i++) {
+        for (j = 0; j < 7; j++) {
+            if ((i >> j) & 1)
+                break;
+            v -= vt[j];
+            vt[j] = (int32_t)lcg_next(&ws->pink_state) >> 3;
+            v += vt[j];
+        }
+        ws->pink_pool[i] = v + ((int32_t)lcg_next(&ws->pink_state) >> 3);
+    }
+    lcg_next(&ws->pink_state); /* so we use exactly 256 steps */
+}
+
+/**
+ * @return  (1<<64) * a / b, without overflow, if a < b
+ */
+static uint64_t frac64(uint64_t a, uint64_t b)
+{
+    uint64_t r = 0;
+    int i;
+
+    if (b < (uint64_t)1 << 32) { /* b small, use two 32-bits steps */
+        a <<= 32;
+        return ((a / b) << 32) | ((a % b) << 32) / b;
+    }
+    if (b < (uint64_t)1 << 48) { /* b medium, use four 16-bits steps */
+        for (i = 0; i < 4; i++) {
+            a <<= 16;
+            r = (r << 16) | (a / b);
+            a %= b;
+        }
+        return r;
+    }
+    for (i = 63; i >= 0; i--) {
+        if (a >= (uint64_t)1 << 63 || a << 1 >= b) {
+            r |= (uint64_t)1 << i;
+            a = (a << 1) - b;
+        } else {
+            a <<= 1;
+        }
+    }
+    return r;
+}
+
+static uint64_t phi_at(struct ws_interval *in, int64_t ts)
+{
+    uint64_t dt = ts - in->ts_start;
+    uint64_t dt2 = dt & 1 ? /* dt * (dt - 1) / 2 without overflow */
+                   dt * ((dt - 1) >> 1) : (dt >> 1) * (dt - 1);
+    return in->phi0 + dt * in->dphi0 + dt2 * in->ddphi;
+}
+
+static void wavesynth_seek(struct wavesynth_context *ws, int64_t ts)
+{
+    int *last, i;
+    struct ws_interval *in;
+
+    last = &ws->cur_inter;
+    for (i = 0; i < ws->nb_inter; i++) {
+        in = &ws->inter[i];
+        if (ts < in->ts_start)
+            break;
+        if (ts >= in->ts_end)
+            continue;
+        *last = i;
+        last = &in->next;
+        in->phi  = phi_at(in, ts);
+        in->dphi = in->dphi0 + (ts - in->ts_start) * in->ddphi;
+        in->amp  = in->amp0  + (ts - in->ts_start) * in->damp;
+    }
+    ws->next_inter = i;
+    ws->next_ts = i < ws->nb_inter ? ws->inter[i].ts_start : INF_TS;
+    *last = -1;
+    lcg_seek(&ws->dither_state, ts - ws->cur_ts);
+    if (ws->pink_need) {
+        int64_t pink_ts_cur  = (ws->cur_ts + PINK_UNIT - 1) & ~(PINK_UNIT - 1);
+        int64_t pink_ts_next = ts & ~(PINK_UNIT - 1);
+        int pos = ts & (PINK_UNIT - 1);
+        lcg_seek(&ws->pink_state, (pink_ts_next - pink_ts_cur) << 1);
+        if (pos) {
+            pink_fill(ws);
+            ws->pink_pos = pos;
+        } else {
+            ws->pink_pos = PINK_UNIT;
+        }
+    }
+    ws->cur_ts = ts;
+}
+
+static int wavesynth_parse_extradata(AVCodecContext *avc)
+{
+    struct wavesynth_context *ws = avc->priv_data;
+    struct ws_interval *in;
+    uint8_t *edata, *edata_end;
+    int32_t f1, f2, a1, a2;
+    uint32_t phi;
+    int64_t dphi1, dphi2, dt, cur_ts = -0x8000000000000000;
+    int i;
+
+    if (avc->extradata_size < 4)
+        return AVERROR(EINVAL);
+    edata = avc->extradata;
+    edata_end = edata + avc->extradata_size;
+    ws->nb_inter = AV_RL32(edata);
+    edata += 4;
+    if (ws->nb_inter < 0)
+        return AVERROR(EINVAL);
+    ws->inter = av_calloc(ws->nb_inter, sizeof(*ws->inter));
+    if (!ws->inter)
+        return AVERROR(ENOMEM);
+    for (i = 0; i < ws->nb_inter; i++) {
+        in = &ws->inter[i];
+        if (edata_end - edata < 24)
+            return AVERROR(EINVAL);
+        in->ts_start = AV_RL64(edata +  0);
+        in->ts_end   = AV_RL64(edata +  8);
+        in->type     = AV_RL32(edata + 16);
+        in->channels = AV_RL32(edata + 20);
+        edata += 24;
+        if (in->ts_start < cur_ts || in->ts_end <= in->ts_start)
+            return AVERROR(EINVAL);
+        cur_ts = in->ts_start;
+        dt = in->ts_end - in->ts_start;
+        switch (in->type) {
+            case WS_SINE:
+                if (edata_end - edata < 20)
+                    return AVERROR(EINVAL);
+                f1  = AV_RL32(edata +  0);
+                f2  = AV_RL32(edata +  4);
+                a1  = AV_RL32(edata +  8);
+                a2  = AV_RL32(edata + 12);
+                phi = AV_RL32(edata + 16);
+                edata += 20;
+                dphi1 = frac64(f1, (int64_t)avc->sample_rate << 16);
+                dphi2 = frac64(f2, (int64_t)avc->sample_rate << 16);
+                in->dphi0 = dphi1;
+                in->ddphi = (dphi2 - dphi1) / dt;
+                if (phi & 0x80000000) {
+                    phi &= ~0x80000000;
+                    if (phi >= i)
+                        return AVERROR(EINVAL);
+                    in->phi0 = phi_at(&ws->inter[phi], in->ts_start);
+                } else {
+                    in->phi0 = (uint64_t)phi << 33;
+                }
+                break;
+            case WS_NOISE:
+                if (edata_end - edata < 8)
+                    return AVERROR(EINVAL);
+                a1  = AV_RL32(edata +  0);
+                a2  = AV_RL32(edata +  4);
+                edata += 8;
+                break;
+            default:
+                return AVERROR(EINVAL);
+        }
+        in->amp0 = (int64_t)a1 << 32;
+        in->damp = (((int64_t)a2 << 32) - ((int64_t)a1 << 32)) / dt;
+    }
+    if (edata != edata_end)
+        return AVERROR(EINVAL);
+    return 0;
+}
+
+static av_cold int wavesynth_init(AVCodecContext *avc)
+{
+    struct wavesynth_context *ws = avc->priv_data;
+    int i, r;
+
+    if (avc->channels > WS_MAX_CHANNELS) {
+        av_log(avc, AV_LOG_ERROR,
+               "This implementation is limited to %d channels.\n",
+               WS_MAX_CHANNELS);
+        return AVERROR(EINVAL);
+    }
+    r = wavesynth_parse_extradata(avc);
+    if (r < 0) {
+        av_log(avc, AV_LOG_ERROR, "Invalid intervals definitions.\n");
+        goto fail;
+    }
+    ws->sin = av_malloc(sizeof(*ws->sin) << SIN_BITS);
+    if (!ws->sin) {
+        r = AVERROR(ENOMEM);
+        goto fail;
+    }
+    for (i = 0; i < 1 << SIN_BITS; i++)
+        ws->sin[i] = floor(32767 * sin(2 * M_PI * i / (1 << SIN_BITS)));
+    ws->dither_state = MKTAG('D','I','T','H');
+    for (i = 0; i < ws->nb_inter; i++)
+        ws->pink_need += ws->inter[i].type == WS_NOISE;
+    ws->pink_state = MKTAG('P','I','N','K');
+    ws->pink_pos = PINK_UNIT;
+    avcodec_get_frame_defaults(&ws->frame);
+    avc->coded_frame = &ws->frame;
+    wavesynth_seek(ws, 0);
+    avc->sample_fmt = AV_SAMPLE_FMT_S16;
+    return 0;
+
+fail:
+    av_free(ws->inter);
+    av_free(ws->sin);
+    return r;
+}
+
+static void wavesynth_synth_sample(struct wavesynth_context *ws, int64_t ts,
+                                   int32_t *channels)
+{
+    int32_t amp, val, *cv;
+    struct ws_interval *in;
+    int i, *last, pink;
+    uint32_t c, all_ch = 0;
+
+    i = ws->cur_inter;
+    last = &ws->cur_inter;
+    if (ws->pink_pos == PINK_UNIT)
+        pink_fill(ws);
+    pink = ws->pink_pool[ws->pink_pos++] >> 16;
+    while (i >= 0) {
+        in = &ws->inter[i];
+        i = in->next;
+        if (ts >= in->ts_end) {
+            *last = i;
+            continue;
+        }
+        last = &in->next;
+        amp = in->amp >> 32;
+        in->amp  += in->damp;
+        switch (in->type) {
+            case WS_SINE:
+                val = amp * ws->sin[in->phi >> (64 - SIN_BITS)];
+                in->phi  += in->dphi;
+                in->dphi += in->ddphi;
+                break;
+            case WS_NOISE:
+                val = amp * pink;
+                break;
+            default:
+                val = 0;
+        }
+        all_ch |= in->channels;
+        for (c = in->channels, cv = channels; c; c >>= 1, cv++)
+            if (c & 1)
+                *cv += val;
+    }
+    val = (int32_t)lcg_next(&ws->dither_state) >> 16;
+    for (c = all_ch, cv = channels; c; c >>= 1, cv++)
+        if (c & 1)
+            *cv += val;
+}
+
+static void wavesynth_enter_intervals(struct wavesynth_context *ws, int64_t ts)
+{
+    int *last, i;
+    struct ws_interval *in;
+
+    last = &ws->cur_inter;
+    for (i = ws->cur_inter; i >= 0; i = ws->inter[i].next)
+        last = &ws->inter[i].next;
+    for (i = ws->next_inter; i < ws->nb_inter; i++) {
+        in = &ws->inter[i];
+        if (ts < in->ts_start)
+            break;
+        if (ts >= in->ts_end)
+            continue;
+        *last = i;
+        last = &in->next;
+        in->phi = in->phi0;
+        in->dphi = in->dphi0;
+        in->amp = in->amp0;
+    }
+    ws->next_inter = i;
+    ws->next_ts = i < ws->nb_inter ? ws->inter[i].ts_start : INF_TS;
+    *last = -1;
+}
+
+static int wavesynth_decode(AVCodecContext *avc, void *rframe, int *rgot_frame,
+                            AVPacket *packet)
+{
+    struct wavesynth_context *ws = avc->priv_data;
+    int64_t ts;
+    int duration;
+    int s, c, r;
+    int16_t *pcm;
+    int32_t channels[WS_MAX_CHANNELS];
+
+    *rgot_frame = 0;
+    if (packet->size != 12)
+        return AVERROR_INVALIDDATA;
+    ts = AV_RL64(packet->data);
+    if (ts != ws->cur_ts)
+        wavesynth_seek(ws, ts);
+    duration = AV_RL32(packet->data + 8);
+    if (duration <= 0)
+        return AVERROR(EINVAL);
+    ws->frame.nb_samples = duration;
+    r = avc->get_buffer(avc, &ws->frame);
+    if (r < 0)
+        return r;
+    pcm = (int16_t *)ws->frame.data[0];
+    for (s = 0; s < duration; s++, ts++) {
+        memset(channels, 0, avc->channels * sizeof(*channels));
+        if (ts >= ws->next_ts)
+            wavesynth_enter_intervals(ws, ts);
+        wavesynth_synth_sample(ws, ts, channels);
+        for (c = 0; c < avc->channels; c++)
+            *(pcm++) = channels[c] >> 16;
+    }
+    ws->cur_ts += duration;
+    *rgot_frame = 1;
+    *(AVFrame *)rframe = ws->frame;
+    return packet->size;
+}
+
+static av_cold int wavesynth_close(AVCodecContext *avc)
+{
+    struct wavesynth_context *ws = avc->priv_data;
+
+    av_free(ws->sin);
+    av_free(ws->inter);
+    return 0;
+}
+
+AVCodec ff_ffwavesynth_decoder = {
+    .name           = "wavesynth",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_FFWAVESYNTH,
+    .priv_data_size = sizeof(struct wavesynth_context),
+    .init           = wavesynth_init,
+    .close          = wavesynth_close,
+    .decode         = wavesynth_decode,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("Wave synthesis pseudo-codec"),
+};
diff --git a/libavcodec/flac.c b/libavcodec/flac.c
index d624beb..b07e4f8 100644
--- a/libavcodec/flac.c
+++ b/libavcodec/flac.c
@@ -2,20 +2,20 @@
  * FLAC common code
  * Copyright (c) 2009 Justin Ruggles
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -206,8 +206,7 @@
     avctx->sample_rate = s->samplerate;
     avctx->bits_per_raw_sample = s->bps;
 
-    s->samples  = get_bits_long(&gb, 32) << 4;
-    s->samples |= get_bits(&gb, 4);
+    s->samples = get_bits_longlong(&gb, 36);
 
     skip_bits_long(&gb, 64); /* md5 sum */
     skip_bits_long(&gb, 64); /* md5 sum */
diff --git a/libavcodec/flac.h b/libavcodec/flac.h
index 55bacea..94444f8 100644
--- a/libavcodec/flac.h
+++ b/libavcodec/flac.h
@@ -2,20 +2,20 @@
  * FLAC (Free Lossless Audio Codec) decoder/demuxer common functions
  * Copyright (c) 2008 Justin Ruggles
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c
index 6c8c046..e37ca64 100644
--- a/libavcodec/flac_parser.c
+++ b/libavcodec/flac_parser.c
@@ -2,20 +2,20 @@
  * FLAC parser
  * Copyright (c) 2010 Michael Chinen
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -561,8 +561,8 @@
         }
 
         /* Fill the buffer. */
-        if (av_fifo_realloc2(fpc->fifo_buf,
-                             (read_end - read_start) + av_fifo_size(fpc->fifo_buf)) < 0) {
+        if (   av_fifo_space(fpc->fifo_buf) < read_end - read_start
+            && av_fifo_realloc2(fpc->fifo_buf, (read_end - read_start) + 2*av_fifo_size(fpc->fifo_buf)) < 0) {
             av_log(avctx, AV_LOG_ERROR,
                    "couldn't reallocate buffer of size %td\n",
                    (read_end - read_start) + av_fifo_size(fpc->fifo_buf));
@@ -606,10 +606,11 @@
 
         /* restore the state pre-padding */
         if (fpc->end_padded) {
+            int warp = fpc->fifo_buf->wptr - fpc->fifo_buf->buffer < MAX_FRAME_HEADER_SIZE;
             /* HACK: drain the tail of the fifo */
             fpc->fifo_buf->wptr -= MAX_FRAME_HEADER_SIZE;
             fpc->fifo_buf->wndx -= MAX_FRAME_HEADER_SIZE;
-            if (fpc->fifo_buf->wptr < 0) {
+            if (warp) {
                 fpc->fifo_buf->wptr += fpc->fifo_buf->end -
                     fpc->fifo_buf->buffer;
             }
diff --git a/libavcodec/flacdata.c b/libavcodec/flacdata.c
index 820c3aa..6fcbe39 100644
--- a/libavcodec/flacdata.c
+++ b/libavcodec/flacdata.c
@@ -2,20 +2,20 @@
  * FLAC data
  * Copyright (c) 2003 Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/flacdata.h b/libavcodec/flacdata.h
index f566377..96a50b9 100644
--- a/libavcodec/flacdata.h
+++ b/libavcodec/flacdata.h
@@ -2,20 +2,20 @@
  * FLAC data header
  * Copyright (c) 2003 Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
index f3f1b3a..61c30e8 100644
--- a/libavcodec/flacdec.c
+++ b/libavcodec/flacdec.c
@@ -2,20 +2,20 @@
  * FLAC (Free Lossless Audio Codec) decoder
  * Copyright (c) 2003 Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -34,6 +34,7 @@
 #include <limits.h>
 
 #include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
 #include "libavutil/crc.h"
 #include "avcodec.h"
 #include "internal.h"
@@ -44,9 +45,6 @@
 #include "flacdata.h"
 #include "flacdsp.h"
 
-#undef NDEBUG
-#include <assert.h>
-
 typedef struct FLACContext {
     FLACSTREAMINFO
 
@@ -141,7 +139,7 @@
 {
     int i;
 
-    assert(s->max_blocksize);
+    av_assert0(s->max_blocksize);
 
     for (i = 0; i < s->channels; i++) {
         s->decoded[i] = av_malloc(sizeof(int32_t)*s->max_blocksize);
diff --git a/libavcodec/flacdsp.c b/libavcodec/flacdsp.c
index 3f4f710..e51a91a 100644
--- a/libavcodec/flacdsp.c
+++ b/libavcodec/flacdsp.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2012 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/flacdsp.h b/libavcodec/flacdsp.h
index 429daab..00be265 100644
--- a/libavcodec/flacdsp.h
+++ b/libavcodec/flacdsp.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/flacdsp_template.c b/libavcodec/flacdsp_template.c
index 0affe22..62c0a15 100644
--- a/libavcodec/flacdsp_template.c
+++ b/libavcodec/flacdsp_template.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2012 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c
index b135e4a..ec6f2e0 100644
--- a/libavcodec/flacenc.c
+++ b/libavcodec/flacenc.c
@@ -2,23 +2,24 @@
  * FLAC audio encoder
  * Copyright (c) 2006  Justin Ruggles <justin.ruggles@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/crc.h"
 #include "libavutil/md5.h"
 #include "libavutil/opt.h"
@@ -139,7 +140,7 @@
     int target;
     int blocksize;
 
-    assert(samplerate > 0);
+    av_assert0(samplerate > 0);
     blocksize = ff_flac_blocksize_table[1];
     target    = (samplerate * block_time_ms) / 1000;
     for (i = 0; i < 16; i++) {
@@ -375,6 +376,28 @@
         return AVERROR(ENOMEM);
 #endif
 
+    if (channels == 3 &&
+            avctx->channel_layout != (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER) ||
+        channels == 4 &&
+            avctx->channel_layout != AV_CH_LAYOUT_2_2 &&
+            avctx->channel_layout != AV_CH_LAYOUT_QUAD ||
+        channels == 5 &&
+            avctx->channel_layout != AV_CH_LAYOUT_5POINT0 &&
+            avctx->channel_layout != AV_CH_LAYOUT_5POINT0_BACK ||
+        channels == 6 &&
+            avctx->channel_layout != AV_CH_LAYOUT_5POINT1 &&
+            avctx->channel_layout != AV_CH_LAYOUT_5POINT1_BACK) {
+        if (avctx->channel_layout) {
+            av_log(avctx, AV_LOG_ERROR, "Channel layout not supported by Flac, "
+                                             "output stream will have incorrect "
+                                             "channel layout.\n");
+        } else {
+            av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The encoder "
+                                               "will use Flac channel layout for "
+                                               "%d channels.\n", channels);
+        }
+    }
+
     ret = ff_lpc_init(&s->lpc_ctx, avctx->frame_size,
                       s->options.max_prediction_order, FF_LPC_TYPE_LEVINSON);
 
@@ -572,9 +595,9 @@
     uint32_t *udata;
     uint32_t sums[MAX_PARTITION_ORDER+1][MAX_PARTITIONS];
 
-    assert(pmin >= 0 && pmin <= MAX_PARTITION_ORDER);
-    assert(pmax >= 0 && pmax <= MAX_PARTITION_ORDER);
-    assert(pmin <= pmax);
+    av_assert1(pmin >= 0 && pmin <= MAX_PARTITION_ORDER);
+    av_assert1(pmax >= 0 && pmax <= MAX_PARTITION_ORDER);
+    av_assert1(pmin <= pmax);
 
     udata = av_malloc(n * sizeof(uint32_t));
     for (i = 0; i < n; i++)
@@ -1229,10 +1252,8 @@
         frame_bytes = encode_frame(s);
     }
 
-    if ((ret = ff_alloc_packet(avpkt, frame_bytes))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, frame_bytes)))
         return ret;
-    }
 
     out_bytes = write_frame(s, avpkt);
 
@@ -1309,7 +1330,7 @@
     .init           = flac_encode_init,
     .encode2        = flac_encode_frame,
     .close          = flac_encode_close,
-    .capabilities   = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
+    .capabilities   = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY | CODEC_CAP_LOSSLESS,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c
index 6052ecd..8d6f39d 100644
--- a/libavcodec/flashsv.c
+++ b/libavcodec/flashsv.c
@@ -3,20 +3,20 @@
  * Copyright (C) 2004 Alex Beregszaszi
  * Copyright (C) 2006 Benjamin Larsson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -115,6 +115,7 @@
         return 1;
     }
     avctx->pix_fmt = AV_PIX_FMT_BGR24;
+    avcodec_get_frame_defaults(&s->frame);
     s->frame.data[0] = NULL;
 
     return 0;
diff --git a/libavcodec/flashsv2enc.c b/libavcodec/flashsv2enc.c
new file mode 100644
index 0000000..1d0d196
--- /dev/null
+++ b/libavcodec/flashsv2enc.c
@@ -0,0 +1,931 @@
+/*
+ * Flash Screen Video Version 2 encoder
+ * Copyright (C) 2009 Joshua Warner
+ *
+ * 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
+ * Flash Screen Video Version 2 encoder
+ * @author Joshua Warner
+ */
+
+/* Differences from version 1 stream:
+ * NOTE: Currently, the only player that supports version 2 streams is Adobe Flash Player itself.
+ * * Supports sending only a range of scanlines in a block,
+ *   indicating a difference from the corresponding block in the last keyframe.
+ * * Supports initializing the zlib dictionary with data from the corresponding
+ *   block in the last keyframe, to improve compression.
+ * * Supports a hybrid 15-bit rgb / 7-bit palette color space.
+ */
+
+/* TODO:
+ * Don't keep Block structures for both current frame and keyframe.
+ * Make better heuristics for deciding stream parameters (optimum_* functions).  Currently these return constants.
+ * Figure out how to encode palette information in the stream, choose an optimum palette at each keyframe.
+ * Figure out how the zlibPrimeCompressCurrent flag works, implement support.
+ * Find other sample files (that weren't generated here), develop a decoder.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <zlib.h>
+
+#include "libavutil/imgutils.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "put_bits.h"
+#include "bytestream.h"
+
+#define HAS_IFRAME_IMAGE 0x02
+#define HAS_PALLET_INFO 0x01
+
+#define COLORSPACE_BGR 0x00
+#define COLORSPACE_15_7 0x10
+#define HAS_DIFF_BLOCKS 0x04
+#define ZLIB_PRIME_COMPRESS_CURRENT 0x02
+#define ZLIB_PRIME_COMPRESS_PREVIOUS 0x01
+
+// Disables experimental "smart" parameter-choosing code, as well as the statistics that it depends on.
+// At the moment, the "smart" code is a great example of how the parameters *shouldn't* be chosen.
+#define FLASHSV2_DUMB
+
+typedef struct Block {
+    uint8_t *enc;
+    uint8_t *sl_begin, *sl_end;
+    int enc_size;
+    uint8_t *data;
+    unsigned long data_size;
+
+    uint8_t start, len;
+    uint8_t dirty;
+    uint8_t col, row, width, height;
+    uint8_t flags;
+} Block;
+
+typedef struct Palette {
+    unsigned colors[128];
+    uint8_t index[1 << 15];
+} Palette;
+
+typedef struct FlashSV2Context {
+    AVCodecContext *avctx;
+    uint8_t *current_frame;
+    uint8_t *key_frame;
+    AVFrame frame;
+    uint8_t *encbuffer;
+    uint8_t *keybuffer;
+    uint8_t *databuffer;
+
+    uint8_t *blockbuffer;
+    int blockbuffer_size;
+
+    Block *frame_blocks;
+    Block *key_blocks;
+    int frame_size;
+    int blocks_size;
+
+    int use15_7, dist, comp;
+
+    int rows, cols;
+
+    int last_key_frame;
+
+    int image_width, image_height;
+    int block_width, block_height;
+    uint8_t flags;
+    uint8_t use_custom_palette;
+    uint8_t palette_type;       ///< 0=>default, 1=>custom - changed when palette regenerated.
+    Palette palette;
+#ifndef FLASHSV2_DUMB
+    double tot_blocks;          ///< blocks encoded since last keyframe
+    double diff_blocks;         ///< blocks that were different since last keyframe
+    double tot_lines;           ///< total scanlines in image since last keyframe
+    double diff_lines;          ///< scanlines that were different since last keyframe
+    double raw_size;            ///< size of raw frames since last keyframe
+    double comp_size;           ///< size of compressed data since last keyframe
+    double uncomp_size;         ///< size of uncompressed data since last keyframe
+
+    double total_bits;          ///< total bits written to stream so far
+#endif
+} FlashSV2Context;
+
+static av_cold void cleanup(FlashSV2Context * s)
+{
+    av_freep(&s->encbuffer);
+    av_freep(&s->keybuffer);
+    av_freep(&s->databuffer);
+    av_freep(&s->blockbuffer);
+    av_freep(&s->current_frame);
+    av_freep(&s->key_frame);
+
+    av_freep(&s->frame_blocks);
+    av_freep(&s->key_blocks);
+}
+
+static void init_blocks(FlashSV2Context * s, Block * blocks,
+                        uint8_t * encbuf, uint8_t * databuf)
+{
+    int row, col;
+    Block *b;
+    for (col = 0; col < s->cols; col++) {
+        for (row = 0; row < s->rows; row++) {
+            b = blocks + (col + row * s->cols);
+            b->width = (col < s->cols - 1) ?
+                s->block_width :
+                s->image_width - col * s->block_width;
+
+            b->height = (row < s->rows - 1) ?
+                s->block_height :
+                s->image_height - row * s->block_height;
+
+            b->row   = row;
+            b->col   = col;
+            b->enc   = encbuf;
+            b->data  = databuf;
+            encbuf  += b->width * b->height * 3;
+            databuf += !databuf ? 0 : b->width * b->height * 6;
+        }
+    }
+}
+
+static void reset_stats(FlashSV2Context * s)
+{
+#ifndef FLASHSV2_DUMB
+    s->diff_blocks = 0.1;
+    s->tot_blocks = 1;
+    s->diff_lines = 0.1;
+    s->tot_lines = 1;
+    s->raw_size = s->comp_size = s->uncomp_size = 10;
+#endif
+}
+
+static av_cold int flashsv2_encode_init(AVCodecContext * avctx)
+{
+    FlashSV2Context *s = avctx->priv_data;
+
+    s->avctx = avctx;
+
+    s->comp = avctx->compression_level;
+    if (s->comp == -1)
+        s->comp = 9;
+    if (s->comp < 0 || s->comp > 9) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Compression level should be 0-9, not %d\n", s->comp);
+        return -1;
+    }
+
+
+    if ((avctx->width > 4095) || (avctx->height > 4095)) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Input dimensions too large, input must be max 4096x4096 !\n");
+        return -1;
+    }
+    if ((avctx->width < 16) || (avctx->height < 16)) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Input dimensions too small, input must be at least 16x16 !\n");
+        return -1;
+    }
+
+    if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0)
+        return -1;
+
+
+    s->last_key_frame = 0;
+
+    s->image_width  = avctx->width;
+    s->image_height = avctx->height;
+
+    s->block_width  = (s->image_width /  12) & ~15;
+    s->block_height = (s->image_height / 12) & ~15;
+
+    if(!s->block_width)
+        s->block_width = 1;
+    if(!s->block_height)
+        s->block_height = 1;
+
+    s->rows = (s->image_height + s->block_height - 1) / s->block_height;
+    s->cols = (s->image_width +  s->block_width -  1) / s->block_width;
+
+    s->frame_size  = s->image_width * s->image_height * 3;
+    s->blocks_size = s->rows * s->cols * sizeof(Block);
+
+    s->encbuffer     = av_mallocz(s->frame_size);
+    s->keybuffer     = av_mallocz(s->frame_size);
+    s->databuffer    = av_mallocz(s->frame_size * 6);
+    s->current_frame = av_mallocz(s->frame_size);
+    s->key_frame     = av_mallocz(s->frame_size);
+    s->frame_blocks  = av_mallocz(s->blocks_size);
+    s->key_blocks    = av_mallocz(s->blocks_size);
+
+    s->blockbuffer      = NULL;
+    s->blockbuffer_size = 0;
+
+    init_blocks(s, s->frame_blocks, s->encbuffer, s->databuffer);
+    init_blocks(s, s->key_blocks,   s->keybuffer, 0);
+    reset_stats(s);
+#ifndef FLASHSV2_DUMB
+    s->total_bits = 1;
+#endif
+
+    s->use_custom_palette =  0;
+    s->palette_type       = -1;        // so that the palette will be generated in reconfigure_at_keyframe
+
+    if (!s->encbuffer || !s->keybuffer || !s->databuffer
+        || !s->current_frame || !s->key_frame || !s->key_blocks
+        || !s->frame_blocks) {
+        av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n");
+        cleanup(s);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int new_key_frame(FlashSV2Context * s)
+{
+    int i;
+    memcpy(s->key_blocks, s->frame_blocks, s->blocks_size);
+    memcpy(s->key_frame, s->current_frame, s->frame_size);
+
+    for (i = 0; i < s->rows * s->cols; i++) {
+        s->key_blocks[i].enc += (s->keybuffer - s->encbuffer);
+        s->key_blocks[i].sl_begin = 0;
+        s->key_blocks[i].sl_end   = 0;
+        s->key_blocks[i].data     = 0;
+    }
+    memcpy(s->keybuffer, s->encbuffer, s->frame_size);
+
+    return 0;
+}
+
+static int write_palette(FlashSV2Context * s, uint8_t * buf, int buf_size)
+{
+    //this isn't implemented yet!  Default palette only!
+    return -1;
+}
+
+static int write_header(FlashSV2Context * s, uint8_t * buf, int buf_size)
+{
+    PutBitContext pb;
+    int buf_pos, len;
+
+    if (buf_size < 5)
+        return -1;
+
+    init_put_bits(&pb, buf, buf_size * 8);
+
+    put_bits(&pb, 4, (s->block_width  >> 4) - 1);
+    put_bits(&pb, 12, s->image_width);
+    put_bits(&pb, 4, (s->block_height >> 4) - 1);
+    put_bits(&pb, 12, s->image_height);
+
+    flush_put_bits(&pb);
+    buf_pos = 4;
+
+    buf[buf_pos++] = s->flags;
+
+    if (s->flags & HAS_PALLET_INFO) {
+        len = write_palette(s, buf + buf_pos, buf_size - buf_pos);
+        if (len < 0)
+            return -1;
+        buf_pos += len;
+    }
+
+    return buf_pos;
+}
+
+static int write_block(Block * b, uint8_t * buf, int buf_size)
+{
+    int buf_pos = 0;
+    unsigned block_size = b->data_size;
+
+    if (b->flags & HAS_DIFF_BLOCKS)
+        block_size += 2;
+    if (b->flags & ZLIB_PRIME_COMPRESS_CURRENT)
+        block_size += 2;
+    if (block_size > 0)
+        block_size += 1;
+    if (buf_size < block_size + 2)
+        return -1;
+
+    buf[buf_pos++] = block_size >> 8;
+    buf[buf_pos++] = block_size;
+
+    if (block_size == 0)
+        return buf_pos;
+
+    buf[buf_pos++] = b->flags;
+
+    if (b->flags & HAS_DIFF_BLOCKS) {
+        buf[buf_pos++] = (b->start);
+        buf[buf_pos++] = (b->len);
+    }
+
+    if (b->flags & ZLIB_PRIME_COMPRESS_CURRENT) {
+        //This feature of the format is poorly understood, and as of now, unused.
+        buf[buf_pos++] = (b->col);
+        buf[buf_pos++] = (b->row);
+    }
+
+    memcpy(buf + buf_pos, b->data, b->data_size);
+
+    buf_pos += b->data_size;
+
+    return buf_pos;
+}
+
+static int encode_zlib(Block * b, uint8_t * buf, unsigned long *buf_size, int comp)
+{
+    int res = compress2(buf, buf_size, b->sl_begin, b->sl_end - b->sl_begin, comp);
+    return res == Z_OK ? 0 : -1;
+}
+
+static int encode_zlibprime(Block * b, Block * prime, uint8_t * buf,
+                            int *buf_size, int comp)
+{
+    z_stream s;
+    int res;
+    s.zalloc = NULL;
+    s.zfree  = NULL;
+    s.opaque = NULL;
+    res = deflateInit(&s, comp);
+    if (res < 0)
+        return -1;
+
+    s.next_in  = prime->enc;
+    s.avail_in = prime->enc_size;
+    while (s.avail_in > 0) {
+        s.next_out  = buf;
+        s.avail_out = *buf_size;
+        res = deflate(&s, Z_SYNC_FLUSH);
+        if (res < 0)
+            return -1;
+    }
+
+    s.next_in   = b->sl_begin;
+    s.avail_in  = b->sl_end - b->sl_begin;
+    s.next_out  = buf;
+    s.avail_out = *buf_size;
+    res = deflate(&s, Z_FINISH);
+    deflateEnd(&s);
+    *buf_size -= s.avail_out;
+    if (res != Z_STREAM_END)
+        return -1;
+    return 0;
+}
+
+static int encode_bgr(Block * b, const uint8_t * src, int stride)
+{
+    int i;
+    uint8_t *ptr = b->enc;
+    for (i = 0; i < b->start; i++)
+        memcpy(ptr + i * b->width * 3, src + i * stride, b->width * 3);
+    b->sl_begin = ptr + i * b->width * 3;
+    for (; i < b->start + b->len; i++)
+        memcpy(ptr + i * b->width * 3, src + i * stride, b->width * 3);
+    b->sl_end = ptr + i * b->width * 3;
+    for (; i < b->height; i++)
+        memcpy(ptr + i * b->width * 3, src + i * stride, b->width * 3);
+    b->enc_size = ptr + i * b->width * 3 - b->enc;
+    return b->enc_size;
+}
+
+static inline unsigned pixel_color15(const uint8_t * src)
+{
+    return (src[0] >> 3) | ((src[1] & 0xf8) << 2) | ((src[2] & 0xf8) << 7);
+}
+
+static inline unsigned int chroma_diff(unsigned int c1, unsigned int c2)
+{
+    unsigned int t1 = (c1 & 0x000000ff) + ((c1 & 0x0000ff00) >> 8) + ((c1 & 0x00ff0000) >> 16);
+    unsigned int t2 = (c2 & 0x000000ff) + ((c2 & 0x0000ff00) >> 8) + ((c2 & 0x00ff0000) >> 16);
+
+    return abs(t1 - t2) + abs((c1 & 0x000000ff) - (c2 & 0x000000ff)) +
+        abs(((c1 & 0x0000ff00) >> 8) - ((c2 & 0x0000ff00) >> 8)) +
+        abs(((c1 & 0x00ff0000) >> 16) - ((c2 & 0x00ff0000) >> 16));
+}
+
+static inline int pixel_color7_fast(Palette * palette, unsigned c15)
+{
+    return palette->index[c15];
+}
+
+static int pixel_color7_slow(Palette * palette, unsigned color)
+{
+    int i, min = 0x7fffffff;
+    int minc = -1;
+    for (i = 0; i < 128; i++) {
+        int c1 = palette->colors[i];
+        int diff = chroma_diff(c1, color);
+        if (diff < min) {
+            min = diff;
+            minc = i;
+        }
+    }
+    return minc;
+}
+
+static inline unsigned pixel_bgr(const uint8_t * src)
+{
+    return (src[0]) | (src[1] << 8) | (src[2] << 16);
+}
+
+static int write_pixel_15_7(Palette * palette, uint8_t * dest, const uint8_t * src,
+                            int dist)
+{
+    unsigned c15 = pixel_color15(src);
+    unsigned color = pixel_bgr(src);
+    int d15 = chroma_diff(color, color & 0x00f8f8f8);
+    int c7 = pixel_color7_fast(palette, c15);
+    int d7 = chroma_diff(color, palette->colors[c7]);
+    if (dist + d15 >= d7) {
+        dest[0] = c7;
+        return 1;
+    } else {
+        dest[0] = 0x80 | (c15 >> 8);
+        dest[1] = c15 & 0xff;
+        return 2;
+    }
+}
+
+static int update_palette_index(Palette * palette)
+{
+    int r, g, b;
+    unsigned int bgr, c15, index;
+    for (r = 4; r < 256; r += 8) {
+        for (g = 4; g < 256; g += 8) {
+            for (b = 4; b < 256; b += 8) {
+                bgr = b | (g << 8) | (r << 16);
+                c15 = (b >> 3) | ((g & 0xf8) << 2) | ((r & 0xf8) << 7);
+                index = pixel_color7_slow(palette, bgr);
+
+                palette->index[c15] = index;
+            }
+        }
+    }
+    return 0;
+}
+
+static const unsigned int default_screen_video_v2_palette[128] = {
+    0x00000000, 0x00333333, 0x00666666, 0x00999999, 0x00CCCCCC, 0x00FFFFFF,
+    0x00330000, 0x00660000, 0x00990000, 0x00CC0000, 0x00FF0000, 0x00003300,
+    0x00006600, 0x00009900, 0x0000CC00, 0x0000FF00, 0x00000033, 0x00000066,
+    0x00000099, 0x000000CC, 0x000000FF, 0x00333300, 0x00666600, 0x00999900,
+    0x00CCCC00, 0x00FFFF00, 0x00003333, 0x00006666, 0x00009999, 0x0000CCCC,
+    0x0000FFFF, 0x00330033, 0x00660066, 0x00990099, 0x00CC00CC, 0x00FF00FF,
+    0x00FFFF33, 0x00FFFF66, 0x00FFFF99, 0x00FFFFCC, 0x00FF33FF, 0x00FF66FF,
+    0x00FF99FF, 0x00FFCCFF, 0x0033FFFF, 0x0066FFFF, 0x0099FFFF, 0x00CCFFFF,
+    0x00CCCC33, 0x00CCCC66, 0x00CCCC99, 0x00CCCCFF, 0x00CC33CC, 0x00CC66CC,
+    0x00CC99CC, 0x00CCFFCC, 0x0033CCCC, 0x0066CCCC, 0x0099CCCC, 0x00FFCCCC,
+    0x00999933, 0x00999966, 0x009999CC, 0x009999FF, 0x00993399, 0x00996699,
+    0x0099CC99, 0x0099FF99, 0x00339999, 0x00669999, 0x00CC9999, 0x00FF9999,
+    0x00666633, 0x00666699, 0x006666CC, 0x006666FF, 0x00663366, 0x00669966,
+    0x0066CC66, 0x0066FF66, 0x00336666, 0x00996666, 0x00CC6666, 0x00FF6666,
+    0x00333366, 0x00333399, 0x003333CC, 0x003333FF, 0x00336633, 0x00339933,
+    0x0033CC33, 0x0033FF33, 0x00663333, 0x00993333, 0x00CC3333, 0x00FF3333,
+    0x00003366, 0x00336600, 0x00660033, 0x00006633, 0x00330066, 0x00663300,
+    0x00336699, 0x00669933, 0x00993366, 0x00339966, 0x00663399, 0x00996633,
+    0x006699CC, 0x0099CC66, 0x00CC6699, 0x0066CC99, 0x009966CC, 0x00CC9966,
+    0x0099CCFF, 0x00CCFF99, 0x00FF99CC, 0x0099FFCC, 0x00CC99FF, 0x00FFCC99,
+    0x00111111, 0x00222222, 0x00444444, 0x00555555, 0x00AAAAAA, 0x00BBBBBB,
+    0x00DDDDDD, 0x00EEEEEE
+};
+
+static int generate_default_palette(Palette * palette)
+{
+    memcpy(palette->colors, default_screen_video_v2_palette,
+           sizeof(default_screen_video_v2_palette));
+
+    return update_palette_index(palette);
+}
+
+static int generate_optimum_palette(Palette * palette, const uint8_t * image,
+                                   int width, int height, int stride)
+{
+    //this isn't implemented yet!  Default palette only!
+    return -1;
+}
+
+static inline int encode_15_7_sl(Palette * palette, uint8_t * dest,
+                                 const uint8_t * src, int width, int dist)
+{
+    int len = 0, x;
+    for (x = 0; x < width; x++) {
+        len += write_pixel_15_7(palette, dest + len, src + 3 * x, dist);
+    }
+    return len;
+}
+
+static int encode_15_7(Palette * palette, Block * b, const uint8_t * src,
+                       int stride, int dist)
+{
+    int i;
+    uint8_t *ptr = b->enc;
+    for (i = 0; i < b->start; i++)
+        ptr += encode_15_7_sl(palette, ptr, src + i * stride, b->width, dist);
+    b->sl_begin = ptr;
+    for (; i < b->start + b->len; i++)
+        ptr += encode_15_7_sl(palette, ptr, src + i * stride, b->width, dist);
+    b->sl_end = ptr;
+    for (; i < b->height; i++)
+        ptr += encode_15_7_sl(palette, ptr, src + i * stride, b->width, dist);
+    b->enc_size = ptr - b->enc;
+    return b->enc_size;
+}
+
+static int encode_block(FlashSV2Context *s, Palette * palette, Block * b,
+                        Block * prev, const uint8_t * src, int stride, int comp,
+                        int dist, int keyframe)
+{
+    unsigned buf_size = b->width * b->height * 6;
+    uint8_t *buf = s->blockbuffer;
+    int res;
+
+    if (b->flags & COLORSPACE_15_7) {
+        encode_15_7(palette, b, src, stride, dist);
+    } else {
+        encode_bgr(b, src, stride);
+    }
+
+    if (b->len > 0) {
+        b->data_size = buf_size;
+        res = encode_zlib(b, b->data, &b->data_size, comp);
+        if (res)
+            return res;
+
+        if (!keyframe) {
+            res = encode_zlibprime(b, prev, buf, &buf_size, comp);
+            if (res)
+                return res;
+
+            if (buf_size < b->data_size) {
+                b->data_size = buf_size;
+                memcpy(b->data, buf, buf_size);
+                b->flags |= ZLIB_PRIME_COMPRESS_PREVIOUS;
+            }
+        }
+    } else {
+        b->data_size = 0;
+    }
+    return 0;
+}
+
+static int compare_sl(FlashSV2Context * s, Block * b, const uint8_t * src,
+                      uint8_t * frame, uint8_t * key, int y, int keyframe)
+{
+    if (memcmp(src, frame, b->width * 3) != 0) {
+        b->dirty = 1;
+        memcpy(frame, src, b->width * 3);
+#ifndef FLASHSV2_DUMB
+        s->diff_lines++;
+#endif
+    }
+    if (memcmp(src, key, b->width * 3) != 0) {
+        if (b->len == 0)
+            b->start = y;
+        b->len = y + 1 - b->start;
+    }
+    return 0;
+}
+
+static int mark_all_blocks(FlashSV2Context * s, const uint8_t * src, int stride,
+                           int keyframe)
+{
+    int sl, rsl, col, pos, possl;
+    Block *b;
+    for (sl = s->image_height - 1; sl >= 0; sl--) {
+        for (col = 0; col < s->cols; col++) {
+            rsl = s->image_height - sl - 1;
+            b = s->frame_blocks + col + rsl / s->block_height * s->cols;
+            possl = stride * sl + col * s->block_width * 3;
+            pos = s->image_width * rsl * 3 + col * s->block_width * 3;
+            compare_sl(s, b, src + possl, s->current_frame + pos,
+                       s->key_frame + pos, rsl % s->block_height, keyframe);
+        }
+    }
+#ifndef FLASHSV2_DUMB
+    s->tot_lines += s->image_height * s->cols;
+#endif
+    return 0;
+}
+
+static int encode_all_blocks(FlashSV2Context * s, int keyframe)
+{
+    int row, col, res;
+    uint8_t *data;
+    Block *b, *prev;
+    for (row = 0; row < s->rows; row++) {
+        for (col = 0; col < s->cols; col++) {
+            b = s->frame_blocks + (row * s->cols + col);
+            prev = s->key_blocks + (row * s->cols + col);
+            b->flags = s->use15_7 ? COLORSPACE_15_7 : 0;
+            if (keyframe) {
+                b->start = 0;
+                b->len = b->height;
+            } else if (!b->dirty) {
+                b->start = 0;
+                b->len = 0;
+                b->data_size = 0;
+                continue;
+            } else if (b->start != 0 || b->len != b->height) {
+                b->flags |= HAS_DIFF_BLOCKS;
+            }
+            data = s->current_frame + s->image_width * 3 * s->block_height * row + s->block_width * col * 3;
+            res = encode_block(s, &s->palette, b, prev, data, s->image_width * 3, s->comp, s->dist, keyframe);
+#ifndef FLASHSV2_DUMB
+            if (b->dirty)
+                s->diff_blocks++;
+            s->comp_size += b->data_size;
+            s->uncomp_size += b->enc_size;
+#endif
+            if (res)
+                return res;
+        }
+    }
+#ifndef FLASHSV2_DUMB
+    s->raw_size += s->image_width * s->image_height * 3;
+    s->tot_blocks += s->rows * s->cols;
+#endif
+    return 0;
+}
+
+static int write_all_blocks(FlashSV2Context * s, uint8_t * buf,
+                            int buf_size)
+{
+    int row, col, buf_pos = 0, len;
+    Block *b;
+    for (row = 0; row < s->rows; row++) {
+        for (col = 0; col < s->cols; col++) {
+            b = s->frame_blocks + row * s->cols + col;
+            len = write_block(b, buf + buf_pos, buf_size - buf_pos);
+            b->start = b->len = b->dirty = 0;
+            if (len < 0)
+                return len;
+            buf_pos += len;
+        }
+    }
+    return buf_pos;
+}
+
+static int write_bitstream(FlashSV2Context * s, const uint8_t * src, int stride,
+                           uint8_t * buf, int buf_size, int keyframe)
+{
+    int buf_pos, res;
+
+    res = mark_all_blocks(s, src, stride, keyframe);
+    if (res)
+        return res;
+    res = encode_all_blocks(s, keyframe);
+    if (res)
+        return res;
+
+    res = write_header(s, buf, buf_size);
+    if (res < 0) {
+        return res;
+    } else {
+        buf_pos = res;
+    }
+    res = write_all_blocks(s, buf + buf_pos, buf_size - buf_pos);
+    if (res < 0)
+        return res;
+    buf_pos += res;
+#ifndef FLASHSV2_DUMB
+    s->total_bits += ((double) buf_pos) * 8.0;
+#endif
+
+    return buf_pos;
+}
+
+static void recommend_keyframe(FlashSV2Context * s, int *keyframe)
+{
+#ifndef FLASHSV2_DUMB
+    double block_ratio, line_ratio, enc_ratio, comp_ratio, data_ratio;
+    if (s->avctx->gop_size > 0) {
+        block_ratio = s->diff_blocks / s->tot_blocks;
+        line_ratio = s->diff_lines / s->tot_lines;
+        enc_ratio = s->uncomp_size / s->raw_size;
+        comp_ratio = s->comp_size / s->uncomp_size;
+        data_ratio = s->comp_size / s->raw_size;
+
+        if ((block_ratio >= 0.5 && line_ratio / block_ratio <= 0.5) || line_ratio >= 0.95) {
+            *keyframe = 1;
+            return;
+        }
+    }
+#else
+    return;
+#endif
+}
+
+static const double block_size_fraction = 1.0 / 300;
+static int optimum_block_width(FlashSV2Context * s)
+{
+#ifndef FLASHSV2_DUMB
+    double save = (1-pow(s->diff_lines/s->diff_blocks/s->block_height, 0.5)) * s->comp_size/s->tot_blocks;
+    double width = block_size_fraction * sqrt(0.5 * save * s->rows * s->cols) * s->image_width;
+    int pwidth = ((int) width);
+    return FFCLIP(pwidth & ~15, 256, 16);
+#else
+    return 64;
+#endif
+}
+
+static int optimum_block_height(FlashSV2Context * s)
+{
+#ifndef FLASHSV2_DUMB
+    double save = (1-pow(s->diff_lines/s->diff_blocks/s->block_height, 0.5)) * s->comp_size/s->tot_blocks;
+    double height = block_size_fraction * sqrt(0.5 * save * s->rows * s->cols) * s->image_height;
+    int pheight = ((int) height);
+    return FFCLIP(pheight & ~15, 256, 16);
+#else
+    return 64;
+#endif
+}
+
+static const double use15_7_threshold = 8192;
+
+static int optimum_use15_7(FlashSV2Context * s)
+{
+#ifndef FLASHSV2_DUMB
+    double ideal = ((double)(s->avctx->bit_rate * s->avctx->time_base.den * s->avctx->ticks_per_frame)) /
+        ((double) s->avctx->time_base.num) * s->avctx->frame_number;
+    if (ideal + use15_7_threshold < s->total_bits) {
+        return 1;
+    } else {
+        return 0;
+    }
+#else
+    return s->avctx->global_quality == 0;
+#endif
+}
+
+static const double color15_7_factor = 100;
+
+static int optimum_dist(FlashSV2Context * s)
+{
+#ifndef FLASHSV2_DUMB
+    double ideal =
+        s->avctx->bit_rate * s->avctx->time_base.den *
+        s->avctx->ticks_per_frame;
+    int dist = pow((s->total_bits / ideal) * color15_7_factor, 3);
+    av_log(s->avctx, AV_LOG_DEBUG, "dist: %d\n", dist);
+    return dist;
+#else
+    return 15;
+#endif
+}
+
+
+static int reconfigure_at_keyframe(FlashSV2Context * s, const uint8_t * image,
+                                   int stride)
+{
+    int update_palette = 0;
+    int res;
+    int block_width  = optimum_block_width (s);
+    int block_height = optimum_block_height(s);
+
+    s->rows = (s->image_height + block_height - 1) / block_height;
+    s->cols = (s->image_width  + block_width  - 1) / block_width;
+
+    if (block_width != s->block_width || block_height != s->block_height) {
+        s->block_width  = block_width;
+        s->block_height = block_height;
+        if (s->rows * s->cols > s->blocks_size / sizeof(Block)) {
+            s->frame_blocks = av_realloc(s->frame_blocks, s->rows * s->cols * sizeof(Block));
+            s->key_blocks = av_realloc(s->key_blocks, s->cols * s->rows * sizeof(Block));
+            if (!s->frame_blocks || !s->key_blocks) {
+                av_log(s->avctx, AV_LOG_ERROR, "Memory allocation failed.\n");
+                return -1;
+            }
+            s->blocks_size = s->rows * s->cols * sizeof(Block);
+        }
+        init_blocks(s, s->frame_blocks, s->encbuffer, s->databuffer);
+        init_blocks(s, s->key_blocks, s->keybuffer, 0);
+
+        av_fast_malloc(&s->blockbuffer, &s->blockbuffer_size, block_width * block_height * 6);
+        if (!s->blockbuffer) {
+            av_log(s->avctx, AV_LOG_ERROR, "Could not allocate block buffer.\n");
+            return AVERROR(ENOMEM);
+        }
+    }
+
+    s->use15_7 = optimum_use15_7(s);
+    if (s->use15_7) {
+        if ((s->use_custom_palette && s->palette_type != 1) || update_palette) {
+            res = generate_optimum_palette(&s->palette, image, s->image_width, s->image_height, stride);
+            if (res)
+                return res;
+            s->palette_type = 1;
+            av_log(s->avctx, AV_LOG_DEBUG, "Generated optimum palette\n");
+        } else if (!s->use_custom_palette && s->palette_type != 0) {
+            res = generate_default_palette(&s->palette);
+            if (res)
+                return res;
+            s->palette_type = 0;
+            av_log(s->avctx, AV_LOG_DEBUG, "Generated default palette\n");
+        }
+    }
+
+
+    reset_stats(s);
+
+    return 0;
+}
+
+static int flashsv2_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                                 const AVFrame *pict, int *got_packet)
+{
+    FlashSV2Context *const s = avctx->priv_data;
+    AVFrame *const p = &s->frame;
+    int res;
+    int keyframe = 0;
+
+    *p = *pict;
+
+    if ((res = ff_alloc_packet2(avctx, pkt, s->frame_size + FF_MIN_BUFFER_SIZE)) < 0)
+        return res;
+
+    /* First frame needs to be a keyframe */
+    if (avctx->frame_number == 0)
+        keyframe = 1;
+
+    /* Check the placement of keyframes */
+    if (avctx->gop_size > 0) {
+        if (avctx->frame_number >= s->last_key_frame + avctx->gop_size)
+            keyframe = 1;
+    }
+
+    if (!keyframe
+        && avctx->frame_number > s->last_key_frame + avctx->keyint_min) {
+        recommend_keyframe(s, &keyframe);
+        if (keyframe)
+            av_log(avctx, AV_LOG_DEBUG, "Recommending key frame at frame %d\n", avctx->frame_number);
+    }
+
+    if (keyframe) {
+        res = reconfigure_at_keyframe(s, p->data[0], p->linesize[0]);
+        if (res)
+            return res;
+    }
+
+    if (s->use15_7)
+        s->dist = optimum_dist(s);
+
+    res = write_bitstream(s, p->data[0], p->linesize[0], pkt->data, pkt->size, keyframe);
+
+    if (keyframe) {
+        new_key_frame(s);
+        p->pict_type = AV_PICTURE_TYPE_I;
+        p->key_frame = 1;
+        s->last_key_frame = avctx->frame_number;
+        pkt->flags |= AV_PKT_FLAG_KEY;
+        av_log(avctx, AV_LOG_DEBUG, "Inserting key frame at frame %d\n", avctx->frame_number);
+    } else {
+        p->pict_type = AV_PICTURE_TYPE_P;
+        p->key_frame = 0;
+    }
+
+    avctx->coded_frame = p;
+
+    pkt->size = res;
+    *got_packet = 1;
+
+    return 0;
+}
+
+static av_cold int flashsv2_encode_end(AVCodecContext * avctx)
+{
+    FlashSV2Context *s = avctx->priv_data;
+
+    cleanup(s);
+
+    return 0;
+}
+
+AVCodec ff_flashsv2_encoder = {
+    .name           = "flashsv2",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_FLASHSV2,
+    .priv_data_size = sizeof(FlashSV2Context),
+    .init           = flashsv2_encode_init,
+    .encode2        = flashsv2_encode_frame,
+    .close          = flashsv2_encode_end,
+    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
+    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video Version 2"),
+};
diff --git a/libavcodec/flashsvenc.c b/libavcodec/flashsvenc.c
index 0b78880..e6b181f 100644
--- a/libavcodec/flashsvenc.c
+++ b/libavcodec/flashsvenc.c
@@ -3,20 +3,20 @@
  * Copyright (C) 2004 Alex Beregszaszi
  * Copyright (C) 2006 Benjamin Larsson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -228,12 +228,8 @@
         I_frame = 1;
     }
 
-    if ((res = ff_alloc_packet(pkt, s->image_width * s->image_height * 3)) < 0) {
-        //Conservative upper bound check for compressed data
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n",
-               s->image_width * s->image_height * 3);
+    if ((res = ff_alloc_packet2(avctx, pkt, s->image_width * s->image_height * 3)) < 0)
         return res;
-    }
 
     pkt->size = encode_bitstream(s, p, pkt->data, pkt->size, opt_w * 16, opt_h * 16,
                                  pfptr, &I_frame);
diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c
index 2b9b290..79695da 100644
--- a/libavcodec/flicvideo.c
+++ b/libavcodec/flicvideo.c
@@ -2,20 +2,20 @@
  * FLI/FLC Animation Video Decoder
  * Copyright (C) 2003, 2004 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -63,9 +63,9 @@
 
 #define CHECK_PIXEL_PTR(n) \
     if (pixel_ptr + n > pixel_limit) { \
-        av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \
+        av_log (s->avctx, AV_LOG_ERROR, "Invalid pixel_ptr = %d > pixel_limit = %d\n", \
         pixel_ptr + n, pixel_limit); \
-        return -1; \
+        return AVERROR_INVALIDDATA; \
     } \
 
 typedef struct FlicDecodeContext {
@@ -83,22 +83,40 @@
     unsigned char *fli_header = (unsigned char *)avctx->extradata;
     int depth;
 
-    if (avctx->extradata_size != 12 &&
-        avctx->extradata_size != 128) {
-        av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n");
+    if (avctx->extradata_size != 0 &&
+        avctx->extradata_size != 12 &&
+        avctx->extradata_size != 128 &&
+        avctx->extradata_size != 256 &&
+        avctx->extradata_size != 904 &&
+        avctx->extradata_size != 1024) {
+        av_log(avctx, AV_LOG_ERROR, "Unexpected extradata size %d\n", avctx->extradata_size);
         return AVERROR_INVALIDDATA;
     }
 
     s->avctx = avctx;
 
-    s->fli_type = AV_RL16(&fli_header[4]); /* Might be overridden if a Magic Carpet FLC */
-
-    depth = 0;
     if (s->avctx->extradata_size == 12) {
         /* special case for magic carpet FLIs */
         s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE;
         depth = 8;
+    } else if (avctx->extradata_size == 1024) {
+        uint8_t *ptr = avctx->extradata;
+        int i;
+
+        for (i = 0; i < 256; i++) {
+            s->palette[i] = AV_RL32(ptr);
+            ptr += 4;
+        }
+        depth = 8;
+        /* FLI in MOV, see e.g. FFmpeg trac issue #626 */
+    } else if (avctx->extradata_size == 0 ||
+               avctx->extradata_size == 256 ||
+        /* see FFmpeg ticket #1234 */
+               avctx->extradata_size == 904) {
+        s->fli_type = FLI_TYPE_CODE;
+        depth = 8;
     } else {
+        s->fli_type = AV_RL16(&fli_header[4]);
         depth = AV_RL16(&fli_header[12]);
     }
 
@@ -122,6 +140,7 @@
                   return -1;
     }
 
+    avcodec_get_frame_defaults(&s->frame);
     s->frame.data[0] = NULL;
     s->new_palette = 0;
 
@@ -135,7 +154,6 @@
     FlicDecodeContext *s = avctx->priv_data;
 
     GetByteContext g2;
-    int stream_ptr_after_color_chunk;
     int pixel_ptr;
     int palette_ptr;
     unsigned char palette_idx1;
@@ -167,7 +185,7 @@
 
     bytestream2_init(&g2, buf, buf_size);
 
-    s->frame.reference = 1;
+    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) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
@@ -176,7 +194,11 @@
 
     pixels = s->frame.data[0];
     pixel_limit = s->avctx->height * s->frame.linesize[0];
+    if (buf_size < 16 || buf_size > INT_MAX - (3 * 256 + FF_INPUT_BUFFER_PADDING_SIZE))
+        return AVERROR_INVALIDDATA;
     frame_size = bytestream2_get_le32(&g2);
+    if (frame_size > buf_size)
+        frame_size = buf_size;
     bytestream2_skip(&g2, 2); /* skip the magic number */
     num_chunks = bytestream2_get_le16(&g2);
     bytestream2_skip(&g2, 8);  /* skip padding */
@@ -184,15 +206,21 @@
     frame_size -= 16;
 
     /* iterate through the chunks */
-    while ((frame_size > 0) && (num_chunks > 0)) {
+    while ((frame_size >= 6) && (num_chunks > 0)) {
+        int stream_ptr_after_chunk;
         chunk_size = bytestream2_get_le32(&g2);
+        if (chunk_size > frame_size) {
+            av_log(avctx, AV_LOG_WARNING,
+                   "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
+            chunk_size = frame_size;
+        }
+        stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
+
         chunk_type = bytestream2_get_le16(&g2);
 
         switch (chunk_type) {
         case FLI_256_COLOR:
         case FLI_COLOR:
-            stream_ptr_after_color_chunk = bytestream2_tell(&g2) + chunk_size - 6;
-
             /* check special case: If this file is from the Magic Carpet
              * game and uses 6-bit colors even though it reports 256-color
              * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
@@ -215,6 +243,9 @@
                 if (color_changes == 0)
                     color_changes = 256;
 
+                if (bytestream2_tell(&g2) + color_changes * 3 > stream_ptr_after_chunk)
+                    break;
+
                 for (j = 0; j < color_changes; j++) {
                     unsigned int entry;
 
@@ -225,26 +256,22 @@
                     r = bytestream2_get_byte(&g2) << color_shift;
                     g = bytestream2_get_byte(&g2) << color_shift;
                     b = bytestream2_get_byte(&g2) << color_shift;
-                    entry = (r << 16) | (g << 8) | b;
+                    entry = 0xFF << 24 | r << 16 | g << 8 | b;
+                    if (color_shift == 2)
+                        entry |= entry >> 6 & 0x30303;
                     if (s->palette[palette_ptr] != entry)
                         s->new_palette = 1;
                     s->palette[palette_ptr++] = entry;
                 }
             }
-
-            /* color chunks sometimes have weird 16-bit alignment issues;
-             * therefore, take the hardline approach and skip
-             * to the value calculated w.r.t. the size specified by the color
-             * chunk header */
-            if (stream_ptr_after_color_chunk - bytestream2_tell(&g2) > 0)
-                bytestream2_skip(&g2, stream_ptr_after_color_chunk - bytestream2_tell(&g2));
-
             break;
 
         case FLI_DELTA:
             y_ptr = 0;
             compressed_lines = bytestream2_get_le16(&g2);
             while (compressed_lines > 0) {
+                if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
+                    break;
                 line_packets = bytestream2_get_le16(&g2);
                 if ((line_packets & 0xC000) == 0xC000) {
                     // line skip opcode
@@ -263,6 +290,8 @@
                     CHECK_PIXEL_PTR(0);
                     pixel_countdown = s->avctx->width;
                     for (i = 0; i < line_packets; i++) {
+                        if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
+                            break;
                         /* account for the skip bytes */
                         pixel_skip = bytestream2_get_byte(&g2);
                         pixel_ptr += pixel_skip;
@@ -279,6 +308,8 @@
                             }
                         } else {
                             CHECK_PIXEL_PTR(byte_run * 2);
+                            if (bytestream2_tell(&g2) + byte_run * 2 > stream_ptr_after_chunk)
+                                break;
                             for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
                                 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
                             }
@@ -301,16 +332,22 @@
                 pixel_ptr = y_ptr;
                 CHECK_PIXEL_PTR(0);
                 pixel_countdown = s->avctx->width;
+                if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
+                    break;
                 line_packets = bytestream2_get_byte(&g2);
                 if (line_packets > 0) {
                     for (i = 0; i < line_packets; i++) {
                         /* account for the skip bytes */
+                        if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
+                            break;
                         pixel_skip = bytestream2_get_byte(&g2);
                         pixel_ptr += pixel_skip;
                         pixel_countdown -= pixel_skip;
                         byte_run = sign_extend(bytestream2_get_byte(&g2),8);
                         if (byte_run > 0) {
                             CHECK_PIXEL_PTR(byte_run);
+                            if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
+                                break;
                             for (j = 0; j < byte_run; j++, pixel_countdown--) {
                                 pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
                             }
@@ -347,6 +384,8 @@
                  bytestream2_skip(&g2, 1);
                 pixel_countdown = s->avctx->width;
                 while (pixel_countdown > 0) {
+                    if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
+                        break;
                     byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
                     if (byte_run > 0) {
                         palette_idx1 = bytestream2_get_byte(&g2);
@@ -361,6 +400,8 @@
                     } else {  /* copy bytes if byte_run < 0 */
                         byte_run = -byte_run;
                         CHECK_PIXEL_PTR(byte_run);
+                        if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
+                            break;
                         for (j = 0; j < byte_run; j++) {
                             pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
                             pixel_countdown--;
@@ -377,9 +418,9 @@
 
         case FLI_COPY:
             /* copy the chunk (uncompressed frame) */
-            if (chunk_size - 6 > s->avctx->width * s->avctx->height) {
+            if (chunk_size - 6 != s->avctx->width * s->avctx->height) {
                 av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
-                       "bigger than image, skipping chunk\n", chunk_size - 6);
+                       "has incorrect size, skipping chunk\n", chunk_size - 6);
                 bytestream2_skip(&g2, chunk_size - 6);
             } else {
                 for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
@@ -392,7 +433,6 @@
 
         case FLI_MINI:
             /* some sort of a thumbnail? disregard this chunk... */
-            bytestream2_skip(&g2, chunk_size - 6);
             break;
 
         default:
@@ -400,14 +440,16 @@
             break;
         }
 
+        if (stream_ptr_after_chunk - bytestream2_tell(&g2) > 0)
+            bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
+
         frame_size -= chunk_size;
         num_chunks--;
     }
 
     /* by the end of the chunk, the stream ptr should equal the frame
-     * size (minus 1, possibly); if it doesn't, issue a warning */
-    if ((bytestream2_get_bytes_left(&g2) != 0) &&
-        (bytestream2_get_bytes_left(&g2) != 1))
+     * size (minus 1 or 2, possibly); if it doesn't, issue a warning */
+    if (bytestream2_get_bytes_left(&g2) > 2)
         av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
                "and final chunk ptr = %d\n", buf_size,
                buf_size - bytestream2_get_bytes_left(&g2));
@@ -458,7 +500,7 @@
 
     bytestream2_init(&g2, buf, buf_size);
 
-    s->frame.reference = 1;
+    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) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
@@ -472,14 +514,25 @@
     bytestream2_skip(&g2, 2);  /* skip the magic number */
     num_chunks = bytestream2_get_le16(&g2);
     bytestream2_skip(&g2, 8);  /* skip padding */
+    if (frame_size > buf_size)
+        frame_size = buf_size;
 
     frame_size -= 16;
 
     /* iterate through the chunks */
     while ((frame_size > 0) && (num_chunks > 0)) {
+        int stream_ptr_after_chunk;
         chunk_size = bytestream2_get_le32(&g2);
+        if (chunk_size > frame_size) {
+            av_log(avctx, AV_LOG_WARNING,
+                   "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
+            chunk_size = frame_size;
+        }
+        stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
+
         chunk_type = bytestream2_get_le16(&g2);
 
+
         switch (chunk_type) {
         case FLI_256_COLOR:
         case FLI_COLOR:
@@ -497,6 +550,8 @@
             y_ptr = 0;
             compressed_lines = bytestream2_get_le16(&g2);
             while (compressed_lines > 0) {
+                if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
+                    break;
                 line_packets = bytestream2_get_le16(&g2);
                 if (line_packets < 0) {
                     line_packets = -line_packets;
@@ -508,6 +563,8 @@
                     pixel_countdown = s->avctx->width;
                     for (i = 0; i < line_packets; i++) {
                         /* account for the skip bytes */
+                        if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
+                            break;
                         pixel_skip = bytestream2_get_byte(&g2);
                         pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
                         pixel_countdown -= pixel_skip;
@@ -521,6 +578,8 @@
                                 pixel_ptr += 2;
                             }
                         } else {
+                            if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk)
+                                break;
                             CHECK_PIXEL_PTR(2 * byte_run);
                             for (j = 0; j < byte_run; j++, pixel_countdown--) {
                                 *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
@@ -555,6 +614,8 @@
                 pixel_countdown = (s->avctx->width * 2);
 
                 while (pixel_countdown > 0) {
+                    if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
+                        break;
                     byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
                     if (byte_run > 0) {
                         palette_idx1 = bytestream2_get_byte(&g2);
@@ -568,6 +629,8 @@
                         }
                     } else {  /* copy bytes if byte_run < 0 */
                         byte_run = -byte_run;
+                        if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
+                            break;
                         CHECK_PIXEL_PTR(byte_run);
                         for (j = 0; j < byte_run; j++) {
                             palette_idx1 = bytestream2_get_byte(&g2);
@@ -607,6 +670,8 @@
                 pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
 
                 while (pixel_countdown > 0) {
+                    if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
+                        break;
                     byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
                     if (byte_run > 0) {
                         pixel    = bytestream2_get_le16(&g2);
@@ -621,6 +686,8 @@
                         }
                     } else {  /* copy pixels if byte_run < 0 */
                         byte_run = -byte_run;
+                        if (bytestream2_tell(&g2) + 2 * byte_run > stream_ptr_after_chunk)
+                            break;
                         CHECK_PIXEL_PTR(2 * byte_run);
                         for (j = 0; j < byte_run; j++) {
                             *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
diff --git a/libavcodec/flv.h b/libavcodec/flv.h
index 3d9a2d5..16bc88b 100644
--- a/libavcodec/flv.h
+++ b/libavcodec/flv.h
@@ -1,19 +1,19 @@
 /*
  * FLV specific private header.
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/flvdec.c b/libavcodec/flvdec.c
index dfed95b..774fde7 100644
--- a/libavcodec/flvdec.c
+++ b/libavcodec/flvdec.c
@@ -1,19 +1,19 @@
 /*
  * FLV decoding.
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -40,12 +40,12 @@
     /* picture header */
     if (get_bits_long(&s->gb, 17) != 1) {
         av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     format = get_bits(&s->gb, 5);
     if (format != 0 && format != 1) {
         av_log(s->avctx, AV_LOG_ERROR, "Bad picture format\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     s->h263_flv = format+1;
     s->picture_number = get_bits(&s->gb, 8); /* picture timestamp */
@@ -84,7 +84,7 @@
         break;
     }
     if(av_image_check_size(width, height, 0, s->avctx))
-        return -1;
+        return AVERROR(EINVAL);
     s->width = width;
     s->height = height;
 
@@ -127,6 +127,7 @@
     .close          = ff_h263_decode_end,
     .decode         = ff_h263_decode_frame,
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+    .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("FLV / Sorenson Spark / Sorenson H.263 (Flash Video)"),
     .pix_fmts       = ff_pixfmt_list_420,
 };
diff --git a/libavcodec/flvenc.c b/libavcodec/flvenc.c
index 5427cbc..a68a6fa 100644
--- a/libavcodec/flvenc.c
+++ b/libavcodec/flvenc.c
@@ -1,19 +1,19 @@
 /*
  * FLV Encoding specific code.
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/fmtconvert.c b/libavcodec/fmtconvert.c
index 642e1d2..79e9645 100644
--- a/libavcodec/fmtconvert.c
+++ b/libavcodec/fmtconvert.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000, 2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -86,4 +86,36 @@
     if (ARCH_ARM) ff_fmt_convert_init_arm(c, avctx);
     if (HAVE_ALTIVEC) ff_fmt_convert_init_altivec(c, avctx);
     if (ARCH_X86) ff_fmt_convert_init_x86(c, avctx);
+    if (HAVE_MIPSFPU) ff_fmt_convert_init_mips(c);
+}
+
+/* ffdshow custom code */
+void float_interleave(float *dst, const float **src, long len, int channels)
+{
+    int i,j,c;
+    if(channels==2){
+        for(i=0; i<len; i++){
+            dst[2*i]   = src[0][i] / 32768.0f;
+            dst[2*i+1] = src[1][i] / 32768.0f;
+        }
+    }else{
+        for(c=0; c<channels; c++)
+            for(i=0, j=c; i<len; i++, j+=channels)
+                dst[j] = src[c][i] / 32768.0f;
+    }
+}
+
+void float_interleave_noscale(float *dst, const float **src, long len, int channels)
+{
+    int i,j,c;
+    if(channels==2){
+        for(i=0; i<len; i++){
+            dst[2*i]   = src[0][i];
+            dst[2*i+1] = src[1][i];
+        }
+    }else{
+        for(c=0; c<channels; c++)
+            for(i=0, j=c; i<len; i++, j+=channels)
+                dst[j] = src[c][i];
+    }
 }
diff --git a/libavcodec/fmtconvert.h b/libavcodec/fmtconvert.h
index b879ee6..ab2caa2 100644
--- a/libavcodec/fmtconvert.h
+++ b/libavcodec/fmtconvert.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2000, 2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -92,5 +92,10 @@
 void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx);
 void ff_fmt_convert_init_altivec(FmtConvertContext *c, AVCodecContext *avctx);
 void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx);
+void ff_fmt_convert_init_mips(FmtConvertContext *c);
+
+/* ffdshow custom code */
+void float_interleave(float *dst, const float **src, long len, int channels);
+void float_interleave_noscale(float *dst, const float **src, long len, int channels);
 
 #endif /* AVCODEC_FMTCONVERT_H */
diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c
new file mode 100644
index 0000000..26a41af
--- /dev/null
+++ b/libavcodec/frame_thread_encoder.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2012 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 "frame_thread_encoder.h"
+
+#include "libavutil/fifo.h"
+#include "libavutil/avassert.h"
+#include "libavutil/imgutils.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "thread.h"
+
+#if HAVE_PTHREADS
+#include <pthread.h>
+#elif HAVE_W32THREADS
+#include "w32pthreads.h"
+#elif HAVE_OS2THREADS
+#include "os2threads.h"
+#endif
+
+#define MAX_THREADS 64
+#define BUFFER_SIZE (2*MAX_THREADS)
+
+typedef struct{
+    void *indata;
+    void *outdata;
+    int64_t return_code;
+    unsigned index;
+} Task;
+
+typedef struct{
+    AVCodecContext *parent_avctx;
+    pthread_mutex_t buffer_mutex;
+
+    AVFifoBuffer *task_fifo;
+    pthread_mutex_t task_fifo_mutex;
+    pthread_cond_t task_fifo_cond;
+
+    Task finished_tasks[BUFFER_SIZE];
+    pthread_mutex_t finished_task_mutex;
+    pthread_cond_t finished_task_cond;
+
+    unsigned task_index;
+    unsigned finished_task_index;
+
+    pthread_t worker[MAX_THREADS];
+    int exit;
+} ThreadContext;
+
+static void * attribute_align_arg worker(void *v){
+    AVCodecContext *avctx = v;
+    ThreadContext *c = avctx->internal->frame_thread_encoder;
+    AVPacket *pkt = NULL;
+
+    while(!c->exit){
+        int got_packet, ret;
+        AVFrame *frame;
+        Task task;
+
+        if(!pkt) pkt= av_mallocz(sizeof(*pkt));
+        if(!pkt) continue;
+        av_init_packet(pkt);
+
+        pthread_mutex_lock(&c->task_fifo_mutex);
+        while (av_fifo_size(c->task_fifo) <= 0 || c->exit) {
+            if(c->exit){
+                pthread_mutex_unlock(&c->task_fifo_mutex);
+                goto end;
+            }
+            pthread_cond_wait(&c->task_fifo_cond, &c->task_fifo_mutex);
+        }
+        av_fifo_generic_read(c->task_fifo, &task, sizeof(task), NULL);
+        pthread_mutex_unlock(&c->task_fifo_mutex);
+        frame = task.indata;
+
+        ret = avcodec_encode_video2(avctx, pkt, frame, &got_packet);
+        pthread_mutex_lock(&c->buffer_mutex);
+        c->parent_avctx->release_buffer(c->parent_avctx, frame);
+        pthread_mutex_unlock(&c->buffer_mutex);
+        av_freep(&frame);
+        if(!got_packet)
+            continue;
+        av_dup_packet(pkt);
+        pthread_mutex_lock(&c->finished_task_mutex);
+        c->finished_tasks[task.index].outdata = pkt; pkt = NULL;
+        c->finished_tasks[task.index].return_code = ret;
+        pthread_cond_signal(&c->finished_task_cond);
+        pthread_mutex_unlock(&c->finished_task_mutex);
+    }
+end:
+    av_free(pkt);
+    pthread_mutex_lock(&c->buffer_mutex);
+    avcodec_close(avctx);
+    pthread_mutex_unlock(&c->buffer_mutex);
+    av_freep(&avctx);
+    return NULL;
+}
+
+int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){
+    int i=0;
+    ThreadContext *c;
+
+
+    if(   !(avctx->thread_type & FF_THREAD_FRAME)
+       || !(avctx->codec->capabilities & CODEC_CAP_INTRA_ONLY))
+        return 0;
+
+    if(!avctx->thread_count) {
+        avctx->thread_count = ff_get_logical_cpus(avctx);
+        avctx->thread_count = FFMIN(avctx->thread_count, MAX_THREADS);
+    }
+
+    if(avctx->thread_count <= 1)
+        return 0;
+
+    if(avctx->thread_count > MAX_THREADS)
+        return AVERROR(EINVAL);
+
+    av_assert0(!avctx->internal->frame_thread_encoder);
+    c = avctx->internal->frame_thread_encoder = av_mallocz(sizeof(ThreadContext));
+    if(!c)
+        return AVERROR(ENOMEM);
+
+    c->parent_avctx = avctx;
+
+    c->task_fifo = av_fifo_alloc(sizeof(Task) * BUFFER_SIZE);
+    if(!c->task_fifo)
+        goto fail;
+
+    pthread_mutex_init(&c->task_fifo_mutex, NULL);
+    pthread_mutex_init(&c->finished_task_mutex, NULL);
+    pthread_mutex_init(&c->buffer_mutex, NULL);
+    pthread_cond_init(&c->task_fifo_cond, NULL);
+    pthread_cond_init(&c->finished_task_cond, NULL);
+
+    for(i=0; i<avctx->thread_count ; i++){
+        AVDictionary *tmp = NULL;
+        AVCodecContext *thread_avctx = avcodec_alloc_context3(avctx->codec);
+        if(!thread_avctx)
+            goto fail;
+        *thread_avctx = *avctx;
+        thread_avctx->internal = NULL;
+        thread_avctx->priv_data = av_malloc(avctx->codec->priv_data_size);
+        if(!thread_avctx->priv_data) {
+            av_freep(&thread_avctx);
+            goto fail;
+        }
+        memcpy(thread_avctx->priv_data, avctx->priv_data, avctx->codec->priv_data_size);
+        thread_avctx->thread_count = 1;
+        thread_avctx->active_thread_type &= ~FF_THREAD_FRAME;
+
+        av_dict_copy(&tmp, options, 0);
+        av_dict_set(&tmp, "threads", "1", 0);
+        if(avcodec_open2(thread_avctx, avctx->codec, &tmp) < 0) {
+            av_dict_free(&tmp);
+            goto fail;
+        }
+        av_dict_free(&tmp);
+        av_assert0(!thread_avctx->internal->frame_thread_encoder);
+        thread_avctx->internal->frame_thread_encoder = c;
+        if(pthread_create(&c->worker[i], NULL, worker, thread_avctx)) {
+            goto fail;
+        }
+    }
+
+    avctx->active_thread_type = FF_THREAD_FRAME;
+
+    return 0;
+fail:
+    avctx->thread_count = i;
+    av_log(avctx, AV_LOG_ERROR, "ff_frame_thread_encoder_init failed\n");
+    ff_frame_thread_encoder_free(avctx);
+    return -1;
+}
+
+void ff_frame_thread_encoder_free(AVCodecContext *avctx){
+    int i;
+    ThreadContext *c= avctx->internal->frame_thread_encoder;
+
+    pthread_mutex_lock(&c->task_fifo_mutex);
+    c->exit = 1;
+    pthread_cond_broadcast(&c->task_fifo_cond);
+    pthread_mutex_unlock(&c->task_fifo_mutex);
+
+    for (i=0; i<avctx->thread_count; i++) {
+         pthread_join(c->worker[i], NULL);
+    }
+
+    pthread_mutex_destroy(&c->task_fifo_mutex);
+    pthread_mutex_destroy(&c->finished_task_mutex);
+    pthread_mutex_destroy(&c->buffer_mutex);
+    pthread_cond_destroy(&c->task_fifo_cond);
+    pthread_cond_destroy(&c->finished_task_cond);
+    av_fifo_free(c->task_fifo); c->task_fifo = NULL;
+    av_freep(&avctx->internal->frame_thread_encoder);
+}
+
+int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr){
+    ThreadContext *c = avctx->internal->frame_thread_encoder;
+    Task task;
+    int ret;
+
+    av_assert1(!*got_packet_ptr);
+
+    if(frame){
+        if(!(avctx->flags & CODEC_FLAG_INPUT_PRESERVED)){
+            AVFrame *new = avcodec_alloc_frame();
+            if(!new)
+                return AVERROR(ENOMEM);
+            pthread_mutex_lock(&c->buffer_mutex);
+            ret = c->parent_avctx->get_buffer(c->parent_avctx, new);
+            pthread_mutex_unlock(&c->buffer_mutex);
+            if(ret<0)
+                return ret;
+            new->pts = frame->pts;
+            new->quality = frame->quality;
+            new->pict_type = frame->pict_type;
+            av_image_copy(new->data, new->linesize, (const uint8_t **)frame->data, frame->linesize,
+                          avctx->pix_fmt, avctx->width, avctx->height);
+            frame = new;
+        }
+
+        task.index = c->task_index;
+        task.indata = (void*)frame;
+        pthread_mutex_lock(&c->task_fifo_mutex);
+        av_fifo_generic_write(c->task_fifo, &task, sizeof(task), NULL);
+        pthread_cond_signal(&c->task_fifo_cond);
+        pthread_mutex_unlock(&c->task_fifo_mutex);
+
+        c->task_index = (c->task_index+1) % BUFFER_SIZE;
+
+        if(!c->finished_tasks[c->finished_task_index].outdata && (c->task_index - c->finished_task_index) % BUFFER_SIZE <= avctx->thread_count)
+            return 0;
+    }
+
+    if(c->task_index == c->finished_task_index)
+        return 0;
+
+    pthread_mutex_lock(&c->finished_task_mutex);
+    while (!c->finished_tasks[c->finished_task_index].outdata) {
+        pthread_cond_wait(&c->finished_task_cond, &c->finished_task_mutex);
+    }
+    task = c->finished_tasks[c->finished_task_index];
+    *pkt = *(AVPacket*)(task.outdata);
+    c->finished_tasks[c->finished_task_index].outdata= NULL;
+    c->finished_task_index = (c->finished_task_index+1) % BUFFER_SIZE;
+    pthread_mutex_unlock(&c->finished_task_mutex);
+
+    *got_packet_ptr = 1;
+
+    return task.return_code;
+}
diff --git a/libavcodec/frame_thread_encoder.h b/libavcodec/frame_thread_encoder.h
new file mode 100644
index 0000000..1da0ce1
--- /dev/null
+++ b/libavcodec/frame_thread_encoder.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012 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 "avcodec.h"
+
+int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options);
+void ff_frame_thread_encoder_free(AVCodecContext *avctx);
+int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet_ptr);
+
diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c
index 3df1280..da8a50c 100644
--- a/libavcodec/fraps.c
+++ b/libavcodec/fraps.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2005 Roine Gustafsson
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,6 +36,7 @@
 #include "huffman.h"
 #include "bytestream.h"
 #include "dsputil.h"
+#include "thread.h"
 
 #define FPS_TAG MKTAG('F', 'P', 'S', 'x')
 
@@ -60,8 +61,8 @@
 {
     FrapsContext * const s = avctx->priv_data;
 
+    avcodec_get_frame_defaults(&s->frame);
     avctx->coded_frame = &s->frame;
-    avctx->pix_fmt= AV_PIX_FMT_NONE; /* set in decode_frame */
 
     s->avctx = avctx;
     s->tmpbuf = NULL;
@@ -138,7 +139,9 @@
     const uint32_t *buf32;
     uint32_t *luma1,*luma2,*cb,*cr;
     uint32_t offs[4];
-    int i, j, is_chroma, planes;
+    int i, j, is_chroma;
+    const int planes = 3;
+    uint8_t *out;
     enum AVPixelFormat pix_fmt;
 
     header = AV_RL32(buf);
@@ -152,9 +155,54 @@
         return -1;
     }
 
-    buf+=4;
-    if (header_size == 8)
-        buf+=4;
+    buf += header_size;
+
+    if (version < 2) {
+        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;
+            return buf_size;
+        }
+        if (buf_size != needed_size) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Invalid frame length %d (should be %d)\n",
+                   buf_size, needed_size);
+            return -1;
+        }
+    } else {
+        /* skip frame */
+        if (buf_size == 8) {
+            *data_size = 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 -1;
+        }
+        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)) {
+                av_log(avctx, AV_LOG_ERROR, "Fraps: plane %i offset is out of bounds\n", i);
+                return -1;
+            }
+        }
+        offs[planes] = buf_size - header_size;
+        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);
+        }
+    }
+
+    if (f->data[0])
+        ff_thread_release_buffer(avctx, f);
+    f->pict_type = AV_PICTURE_TYPE_I;
+    f->key_frame = 1;
+    f->reference = 0;
+    f->buffer_hints = FF_BUFFER_HINTS_VALID;
 
     pix_fmt = version & 1 ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_YUVJ420P;
     if (avctx->pix_fmt != pix_fmt && f->data[0]) {
@@ -162,83 +210,44 @@
     }
     avctx->pix_fmt = pix_fmt;
 
+    if (ff_thread_get_buffer(avctx, f)) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return -1;
+    }
+
     switch(version) {
     case 0:
     default:
         /* Fraps v0 is a reordered YUV420 */
-        if ( (buf_size != avctx->width*avctx->height*3/2+header_size) &&
-             (buf_size != header_size) ) {
-            av_log(avctx, AV_LOG_ERROR,
-                   "Invalid frame length %d (should be %d)\n",
-                   buf_size, avctx->width*avctx->height*3/2+header_size);
-            return -1;
-        }
-
-        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 -1;
         }
 
-        f->reference = 1;
-        f->buffer_hints = FF_BUFFER_HINTS_VALID |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-        if (avctx->reget_buffer(avctx, f)) {
-            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-            return -1;
-        }
-        /* bit 31 means same as previous pic */
-        f->pict_type = (header & (1U<<31))? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
-        f->key_frame = f->pict_type == AV_PICTURE_TYPE_I;
-
-        if (f->pict_type == AV_PICTURE_TYPE_I) {
-            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++);
-                    *(luma2++) = *(buf32++);
-                    *(cr++) = *(buf32++);
-                    *(cb++) = *(buf32++);
-                }
+        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++;
+                *luma2++ = *buf32++;
+                *cr++    = *buf32++;
+                *cb++    = *buf32++;
             }
         }
         break;
 
     case 1:
         /* Fraps v1 is an upside-down BGR24 */
-        if ( (buf_size != avctx->width*avctx->height*3+header_size) &&
-             (buf_size != header_size) ) {
-            av_log(avctx, AV_LOG_ERROR,
-                   "Invalid frame length %d (should be %d)\n",
-                   buf_size, avctx->width*avctx->height*3+header_size);
-            return -1;
-        }
-
-        f->reference = 1;
-        f->buffer_hints = FF_BUFFER_HINTS_VALID |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-        if (avctx->reget_buffer(avctx, f)) {
-            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-            return -1;
-        }
-        /* bit 31 means same as previous pic */
-        f->pict_type = (header & (1U<<31))? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
-        f->key_frame = f->pict_type == AV_PICTURE_TYPE_I;
-
-        if (f->pict_type == AV_PICTURE_TYPE_I) {
-            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)*f->linesize[0] ],
+                   &buf[y*avctx->width*3],
+                   3*avctx->width);
         break;
 
     case 2:
@@ -247,41 +256,8 @@
          * Fraps v2 is Huffman-coded YUV420 planes
          * Fraps v4 is virtually the same
          */
-        planes = 3;
-        f->reference = 1;
-        f->buffer_hints = FF_BUFFER_HINTS_VALID |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-        if (avctx->reget_buffer(avctx, f)) {
-            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-            return -1;
-        }
-        /* skip frame */
-        if(buf_size == 8) {
-            f->pict_type = AV_PICTURE_TYPE_P;
-            f->key_frame = 0;
-            break;
-        }
-        f->pict_type = AV_PICTURE_TYPE_I;
-        f->key_frame = 1;
-        if ((AV_RL32(buf) != FPS_TAG)||(buf_size < (planes*1024 + 24))) {
-            av_log(avctx, AV_LOG_ERROR, "Fraps: error in data stream\n");
-            return -1;
-        }
-        for(i = 0; i < planes; i++) {
-            offs[i] = AV_RL32(buf + 4 + i * 4);
-            if(offs[i] >= buf_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 -1;
-            }
-        }
-        offs[planes] = buf_size;
         for(i = 0; i < planes; i++){
             is_chroma = !!i;
-            av_fast_padded_malloc(&s->tmpbuf, &s->tmpbuf_size,
-                                  offs[i + 1] - offs[i] - 1024);
-            if (!s->tmpbuf)
-                return AVERROR(ENOMEM);
             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) {
                 av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i);
@@ -292,52 +268,23 @@
     case 3:
     case 5:
         /* Virtually the same as version 4, but is for RGB24 */
-        planes = 3;
-        f->reference = 1;
-        f->buffer_hints = FF_BUFFER_HINTS_VALID |
-                          FF_BUFFER_HINTS_PRESERVE |
-                          FF_BUFFER_HINTS_REUSABLE;
-        if (avctx->reget_buffer(avctx, f)) {
-            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-            return -1;
-        }
-        /* skip frame */
-        if(buf_size == 8) {
-            f->pict_type = AV_PICTURE_TYPE_P;
-            f->key_frame = 0;
-            break;
-        }
-        f->pict_type = AV_PICTURE_TYPE_I;
-        f->key_frame = 1;
-        if ((AV_RL32(buf) != FPS_TAG)||(buf_size < (planes*1024 + 24))) {
-            av_log(avctx, AV_LOG_ERROR, "Fraps: error in data stream\n");
-            return -1;
-        }
-        for(i = 0; i < planes; i++) {
-            offs[i] = AV_RL32(buf + 4 + i * 4);
-            if(offs[i] >= buf_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 -1;
-            }
-        }
-        offs[planes] = buf_size;
         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);
             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) {
                 av_log(avctx, AV_LOG_ERROR, "Error decoding plane %i\n", i);
                 return -1;
             }
         }
+        out = f->data[0];
         // convert pseudo-YUV into real RGB
         for(j = 0; j < avctx->height; j++){
-            for(i = 0; i < avctx->width; i++){
-                f->data[0][0 + i*3 + j*f->linesize[0]] += f->data[0][1 + i*3 + j*f->linesize[0]];
-                f->data[0][2 + i*3 + j*f->linesize[0]] += f->data[0][1 + i*3 + j*f->linesize[0]];
+            uint8_t *line_end = out + 3*avctx->width;
+            while (out < line_end) {
+                out[0]  += out[1];
+                out[2]  += out[1];
+                out += 3;
             }
+            out += f->linesize[0] - 3*avctx->width;
         }
         break;
     }
@@ -374,6 +321,6 @@
     .init           = decode_init,
     .close          = decode_end,
     .decode         = decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
     .long_name      = NULL_IF_CONFIG_SMALL("Fraps"),
 };
diff --git a/libavcodec/frwu.c b/libavcodec/frwu.c
index 63fc193..90ffc79 100644
--- a/libavcodec/frwu.c
+++ b/libavcodec/frwu.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/g722.c b/libavcodec/g722.c
index a911bc7..2c04c40 100644
--- a/libavcodec/g722.c
+++ b/libavcodec/g722.c
@@ -7,20 +7,20 @@
  * Copyright (c) 2009 Kenan Gillet
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/g722enc.c b/libavcodec/g722enc.c
index 11d3f20..39f83dc 100644
--- a/libavcodec/g722enc.c
+++ b/libavcodec/g722enc.c
@@ -27,6 +27,7 @@
  * G.722 ADPCM audio encoder
  */
 
+#include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "g722.h"
@@ -247,7 +248,7 @@
                     continue;\
                 if (heap_pos[index] < frontier) {\
                     pos = heap_pos[index]++;\
-                    assert(pathn[index] < FREEZE_INTERVAL * frontier);\
+                    av_assert2(pathn[index] < FREEZE_INTERVAL * frontier);\
                     node = nodes_next[index][pos] = next[index]++;\
                     node->path = pathn[index]++;\
                 } else {\
@@ -367,10 +368,8 @@
     int nb_samples, out_size, ret;
 
     out_size = (frame->nb_samples + 1) / 2;
-    if ((ret = ff_alloc_packet(avpkt, out_size))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, out_size)))
         return ret;
-    }
 
     nb_samples = frame->nb_samples - (frame->nb_samples & 1);
 
diff --git a/libavcodec/g723_1.c b/libavcodec/g723_1.c
index 3d4fa46..29eb4fa 100644
--- a/libavcodec/g723_1.c
+++ b/libavcodec/g723_1.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2006 Benjamin Larsson
  * Copyright (c) 2010 Mohamed Naufal Basheer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,49 +30,15 @@
 #include "libavutil/lzo.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
+#include "internal.h"
 #include "get_bits.h"
 #include "acelp_vectors.h"
 #include "celp_filters.h"
+#include "celp_math.h"
 #include "g723_1_data.h"
 
 #define CNG_RANDOM_SEED 12345
 
-/**
- * G723.1 frame types
- */
-enum FrameType {
-    ACTIVE_FRAME,        ///< Active speech
-    SID_FRAME,           ///< Silence Insertion Descriptor frame
-    UNTRANSMITTED_FRAME
-};
-
-enum Rate {
-    RATE_6300,
-    RATE_5300
-};
-
-/**
- * G723.1 unpacked data subframe
- */
-typedef struct {
-    int ad_cb_lag;     ///< adaptive codebook lag
-    int ad_cb_gain;
-    int dirac_train;
-    int pulse_sign;
-    int grid_index;
-    int amp_index;
-    int pulse_pos;
-} G723_1_Subframe;
-
-/**
- * Pitch postfilter parameters
- */
-typedef struct {
-    int     index;    ///< postfilter backward/forward lag
-    int16_t opt_gain; ///< optimal gain
-    int16_t sc_gain;  ///< scaling gain
-} PPFParam;
-
 typedef struct g723_1_context {
     AVClass *class;
     AVFrame frame;
@@ -100,10 +66,21 @@
     int sid_gain;
     int cur_gain;
     int reflection_coef;
-    int pf_gain;
+    int pf_gain;                 ///< formant postfilter
+                                 ///< gain scaling unit memory
     int postfilter;
 
     int16_t audio[FRAME_LEN + LPC_ORDER + PITCH_MAX + 4];
+    int16_t prev_data[HALF_FRAME_LEN];
+    int16_t prev_weight_sig[PITCH_MAX];
+
+
+    int16_t hpf_fir_mem;                   ///< highpass filter fir
+    int     hpf_iir_mem;                   ///< and iir memories
+    int16_t perf_fir_mem[LPC_ORDER];       ///< perceptual filter fir
+    int16_t perf_iir_mem[LPC_ORDER];       ///< and iir memories
+
+    int16_t harmonic_mem[PITCH_MAX];
 } G723_1_Context;
 
 static av_cold int g723_1_decode_init(AVCodecContext *avctx)
@@ -113,7 +90,6 @@
     avctx->channel_layout = AV_CH_LAYOUT_MONO;
     avctx->sample_fmt     = AV_SAMPLE_FMT_S16;
     avctx->channels       = 1;
-    avctx->sample_rate    = 8000;
     p->pf_gain            = 1 << 12;
 
     avcodec_get_frame_defaults(&p->frame);
@@ -200,13 +176,13 @@
         }
     }
 
-    p->subframe[0].grid_index = get_bits(&gb, 1);
-    p->subframe[1].grid_index = get_bits(&gb, 1);
-    p->subframe[2].grid_index = get_bits(&gb, 1);
-    p->subframe[3].grid_index = get_bits(&gb, 1);
+    p->subframe[0].grid_index = get_bits1(&gb);
+    p->subframe[1].grid_index = get_bits1(&gb);
+    p->subframe[2].grid_index = get_bits1(&gb);
+    p->subframe[3].grid_index = get_bits1(&gb);
 
     if (p->cur_rate == RATE_6300) {
-        skip_bits(&gb, 1);  /* skip reserved bit */
+        skip_bits1(&gb);  /* skip reserved bit */
 
         /* Compute pulse_pos index using the 13-bit combined position index */
         temp = get_bits(&gb, 13);
@@ -252,30 +228,23 @@
  */
 static int16_t square_root(int val)
 {
-    int16_t res = 0;
-    int16_t exp = 0x4000;
-    int i;
-
-    for (i = 0; i < 14; i ++) {
-        int res_exp = res + exp;
-        if (val >= res_exp * res_exp << 1)
-            res += exp;
-        exp >>= 1;
-    }
-    return res;
+    return (ff_sqrt(val << 1) >> 1) & (~1);
 }
 
 /**
  * Calculate the number of left-shifts required for normalizing the input.
  *
  * @param num   input number
- * @param width width of the input, 16 bits(0) / 32 bits(1)
+ * @param width width of the input, 15 or 31 bits
  */
 static int normalize_bits(int num, int width)
 {
     return width - av_log2(num) - 1;
 }
 
+#define normalize_bits_int16(num) normalize_bits(num, 15)
+#define normalize_bits_int32(num) normalize_bits(num, 31)
+
 /**
  * Scale vector contents based on the largest of their absolutes.
  */
@@ -284,12 +253,11 @@
     int bits, max = 0;
     int i;
 
-
     for (i = 0; i < length; i++)
         max |= FFABS(vector[i]);
 
-    max   = FFMIN(max, 0x7FFF);
-    bits  = normalize_bits(max, 15);
+    bits= 14 - av_log2_16bit(max);
+    bits= FFMAX(bits, 0);
 
     for (i = 0; i < length; i++)
         dst[i] = vector[i] << bits >> 3;
@@ -374,7 +342,7 @@
  * @param b 16 bit multiplier
  */
 #define MULL2(a, b) \
-        ((((a) >> 16) * (b) << 1) + (((a) & 0xffff) * (b) >> 15))
+        MULL(a,b,15)
 
 /**
  * Convert LSP frequencies to LPC coefficients.
@@ -570,13 +538,8 @@
 
 static int dot_product(const int16_t *a, const int16_t *b, int length)
 {
-    int i, sum = 0;
-
-    for (i = 0; i < length; i++) {
-        int prod = a[i] * b[i];
-        sum = av_sat_dadd32(sum, prod);
-    }
-    return sum;
+    int sum = ff_dot_product(a,b,length);
+    return av_sat_add32(sum, sum);
 }
 
 /**
@@ -596,16 +559,16 @@
     get_residual(residual, prev_excitation, lag);
 
     /* Select quantization table */
-    if (cur_rate == RATE_6300 && pitch_lag < SUBFRAME_LEN - 2)
+    if (cur_rate == RATE_6300 && pitch_lag < SUBFRAME_LEN - 2) {
         cb_ptr = adaptive_cb_gain85;
-    else
+    } else
         cb_ptr = adaptive_cb_gain170;
 
     /* Calculate adaptive vector */
     cb_ptr += subfrm->ad_cb_gain * 20;
     for (i = 0; i < SUBFRAME_LEN; i++) {
-        sum = dot_product(residual + i, cb_ptr, PITCH_ORDER);
-        vector[i] = av_sat_dadd32(1 << 15, sum) >> 16;
+        sum = ff_dot_product(residual + i, cb_ptr, PITCH_ORDER);
+        vector[i] = av_sat_dadd32(1 << 15, av_sat_add32(sum, sum)) >> 16;
     }
 }
 
@@ -748,7 +711,7 @@
 
     scale = normalize_bits(temp1, 31);
     for (i = 0; i < 5; i++)
-        energy[i] = (energy[i] << scale) >> 16;
+        energy[i] = av_clipl_int32(energy[i] << scale) >> 16;
 
     if (fwd_lag && !back_lag) {  /* Case 1 */
         comp_ppf_gains(fwd_lag,  ppf, cur_rate, energy[0], energy[1],
@@ -813,9 +776,9 @@
 
     temp = best_eng * *exc_eng >> 3;
 
-    if (temp < ccr * ccr)
+    if (temp < ccr * ccr) {
         return index;
-    else
+    } else
         return 0;
 }
 
@@ -855,21 +818,24 @@
  * @param iir_coef IIR coefficients
  * @param src      source vector
  * @param dest     destination vector
+ * @param width    width of the output, 16 bits(0) / 32 bits(1)
  */
-static inline void iir_filter(int16_t *fir_coef, int16_t *iir_coef,
-                              int16_t *src, int *dest)
-{
-    int m, n;
-
-    for (m = 0; m < SUBFRAME_LEN; m++) {
-        int64_t filter = 0;
-        for (n = 1; n <= LPC_ORDER; n++) {
-            filter -= fir_coef[n - 1] * src[m - n] -
-                      iir_coef[n - 1] * (dest[m - n] >> 16);
-        }
-
-        dest[m] = av_clipl_int32((src[m] << 16) + (filter << 3) + (1 << 15));
-    }
+#define iir_filter(fir_coef, iir_coef, src, dest, width)\
+{\
+    int m, n;\
+    int res_shift = 16 & ~-(width);\
+    int in_shift  = 16 - res_shift;\
+\
+    for (m = 0; m < SUBFRAME_LEN; m++) {\
+        int64_t filter = 0;\
+        for (n = 1; n <= LPC_ORDER; n++) {\
+            filter -= (fir_coef)[n - 1] * (src)[m - n] -\
+                      (iir_coef)[n - 1] * ((dest)[m - n] >> in_shift);\
+        }\
+\
+        (dest)[m] = av_clipl_int32(((src)[m] << 16) + (filter << 3) +\
+                                   (1 << 15)) >> res_shift;\
+    }\
 }
 
 /**
@@ -940,13 +906,12 @@
                                  (1 << 14)) >> 15;
         }
         iir_filter(filter_coef[0], filter_coef[1], buf + i,
-                   filter_signal + i);
+                   filter_signal + i, 1);
         lpc += LPC_ORDER;
     }
 
-    memcpy(p->fir_mem, buf + FRAME_LEN, LPC_ORDER * sizeof(*p->fir_mem));
-    memcpy(p->iir_mem, filter_signal + FRAME_LEN,
-           LPC_ORDER * sizeof(*p->iir_mem));
+    memcpy(p->fir_mem, buf + FRAME_LEN, LPC_ORDER * sizeof(int16_t));
+    memcpy(p->iir_mem, filter_signal + FRAME_LEN, LPC_ORDER * sizeof(int));
 
     buf += LPC_ORDER;
     signal_ptr = filter_signal + LPC_ORDER;
@@ -1221,8 +1186,8 @@
 
     p->frame.nb_samples = FRAME_LEN;
     if ((ret = avctx->get_buffer(avctx, &p->frame)) < 0) {
-         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-         return ret;
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
     }
 
     out = (int16_t *)p->frame.data[0];
@@ -1376,6 +1341,1141 @@
     .init           = g723_1_decode_init,
     .decode         = g723_1_decode_frame,
     .long_name      = NULL_IF_CONFIG_SMALL("G.723.1"),
-    .capabilities   = CODEC_CAP_SUBFRAMES,
+    .capabilities   = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
     .priv_class     = &g723_1dec_class,
 };
+
+#if CONFIG_G723_1_ENCODER
+#define BITSTREAM_WRITER_LE
+#include "put_bits.h"
+
+static av_cold int g723_1_encode_init(AVCodecContext *avctx)
+{
+    G723_1_Context *p = avctx->priv_data;
+
+    if (avctx->sample_rate != 8000) {
+        av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n");
+        return -1;
+    }
+
+    if (avctx->channels != 1) {
+        av_log(avctx, AV_LOG_ERROR, "Only mono supported\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (avctx->bit_rate == 6300) {
+        p->cur_rate = RATE_6300;
+    } else if (avctx->bit_rate == 5300) {
+        av_log(avctx, AV_LOG_ERROR, "Bitrate not supported yet, use 6.3k\n");
+        return AVERROR_PATCHWELCOME;
+    } else {
+        av_log(avctx, AV_LOG_ERROR,
+               "Bitrate not supported, use 6.3k\n");
+        return AVERROR(EINVAL);
+    }
+    avctx->frame_size = 240;
+    memcpy(p->prev_lsp, dc_lsp, LPC_ORDER * sizeof(int16_t));
+
+    return 0;
+}
+
+/**
+ * Remove DC component from the input signal.
+ *
+ * @param buf input signal
+ * @param fir zero memory
+ * @param iir pole memory
+ */
+static void highpass_filter(int16_t *buf, int16_t *fir, int *iir)
+{
+    int i;
+    for (i = 0; i < FRAME_LEN; i++) {
+        *iir   = (buf[i] << 15) + ((-*fir) << 15) + MULL2(*iir, 0x7f00);
+        *fir   = buf[i];
+        buf[i] = av_clipl_int32((int64_t)*iir + (1 << 15)) >> 16;
+    }
+}
+
+/**
+ * Estimate autocorrelation of the input vector.
+ *
+ * @param buf      input buffer
+ * @param autocorr autocorrelation coefficients vector
+ */
+static void comp_autocorr(int16_t *buf, int16_t *autocorr)
+{
+    int i, scale, temp;
+    int16_t vector[LPC_FRAME];
+
+    scale_vector(vector, buf, LPC_FRAME);
+
+    /* Apply the Hamming window */
+    for (i = 0; i < LPC_FRAME; i++)
+        vector[i] = (vector[i] * hamming_window[i] + (1 << 14)) >> 15;
+
+    /* Compute the first autocorrelation coefficient */
+    temp = ff_dot_product(vector, vector, LPC_FRAME);
+
+    /* Apply a white noise correlation factor of (1025/1024) */
+    temp += temp >> 10;
+
+    /* Normalize */
+    scale = normalize_bits_int32(temp);
+    autocorr[0] = av_clipl_int32((int64_t)(temp << scale) +
+                                 (1 << 15)) >> 16;
+
+    /* Compute the remaining coefficients */
+    if (!autocorr[0]) {
+        memset(autocorr + 1, 0, LPC_ORDER * sizeof(int16_t));
+    } else {
+        for (i = 1; i <= LPC_ORDER; i++) {
+           temp = ff_dot_product(vector, vector + i, LPC_FRAME - i);
+           temp = MULL2((temp << scale), binomial_window[i - 1]);
+           autocorr[i] = av_clipl_int32((int64_t)temp + (1 << 15)) >> 16;
+        }
+    }
+}
+
+/**
+ * Use Levinson-Durbin recursion to compute LPC coefficients from
+ * autocorrelation values.
+ *
+ * @param lpc      LPC coefficients vector
+ * @param autocorr autocorrelation coefficients vector
+ * @param error    prediction error
+ */
+static void levinson_durbin(int16_t *lpc, int16_t *autocorr, int16_t error)
+{
+    int16_t vector[LPC_ORDER];
+    int16_t partial_corr;
+    int i, j, temp;
+
+    memset(lpc, 0, LPC_ORDER * sizeof(int16_t));
+
+    for (i = 0; i < LPC_ORDER; i++) {
+        /* Compute the partial correlation coefficient */
+        temp = 0;
+        for (j = 0; j < i; j++)
+            temp -= lpc[j] * autocorr[i - j - 1];
+        temp = ((autocorr[i] << 13) + temp) << 3;
+
+        if (FFABS(temp) >= (error << 16))
+            break;
+
+        partial_corr = temp / (error << 1);
+
+        lpc[i] = av_clipl_int32((int64_t)(partial_corr << 14) +
+                                (1 << 15)) >> 16;
+
+        /* Update the prediction error */
+        temp  = MULL2(temp, partial_corr);
+        error = av_clipl_int32((int64_t)(error << 16) - temp +
+                                (1 << 15)) >> 16;
+
+        memcpy(vector, lpc, i * sizeof(int16_t));
+        for (j = 0; j < i; j++) {
+            temp = partial_corr * vector[i - j - 1] << 1;
+            lpc[j] = av_clipl_int32((int64_t)(lpc[j] << 16) - temp +
+                                    (1 << 15)) >> 16;
+        }
+    }
+}
+
+/**
+ * Calculate LPC coefficients for the current frame.
+ *
+ * @param buf       current frame
+ * @param prev_data 2 trailing subframes of the previous frame
+ * @param lpc       LPC coefficients vector
+ */
+static void comp_lpc_coeff(int16_t *buf, int16_t *lpc)
+{
+    int16_t autocorr[(LPC_ORDER + 1) * SUBFRAMES];
+    int16_t *autocorr_ptr = autocorr;
+    int16_t *lpc_ptr      = lpc;
+    int i, j;
+
+    for (i = 0, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) {
+        comp_autocorr(buf + i, autocorr_ptr);
+        levinson_durbin(lpc_ptr, autocorr_ptr + 1, autocorr_ptr[0]);
+
+        lpc_ptr += LPC_ORDER;
+        autocorr_ptr += LPC_ORDER + 1;
+    }
+}
+
+static void lpc2lsp(int16_t *lpc, int16_t *prev_lsp, int16_t *lsp)
+{
+    int f[LPC_ORDER + 2]; ///< coefficients of the sum and difference
+                          ///< polynomials (F1, F2) ordered as
+                          ///< f1[0], f2[0], ...., f1[5], f2[5]
+
+    int max, shift, cur_val, prev_val, count, p;
+    int i, j;
+    int64_t temp;
+
+    /* Initialize f1[0] and f2[0] to 1 in Q25 */
+    for (i = 0; i < LPC_ORDER; i++)
+        lsp[i] = (lpc[i] * bandwidth_expand[i] + (1 << 14)) >> 15;
+
+    /* Apply bandwidth expansion on the LPC coefficients */
+    f[0] = f[1] = 1 << 25;
+
+    /* Compute the remaining coefficients */
+    for (i = 0; i < LPC_ORDER / 2; i++) {
+        /* f1 */
+        f[2 * i + 2] = -f[2 * i] - ((lsp[i] + lsp[LPC_ORDER - 1 - i]) << 12);
+        /* f2 */
+        f[2 * i + 3] = f[2 * i + 1] - ((lsp[i] - lsp[LPC_ORDER - 1 - i]) << 12);
+    }
+
+    /* Divide f1[5] and f2[5] by 2 for use in polynomial evaluation */
+    f[LPC_ORDER] >>= 1;
+    f[LPC_ORDER + 1] >>= 1;
+
+    /* Normalize and shorten */
+    max = FFABS(f[0]);
+    for (i = 1; i < LPC_ORDER + 2; i++)
+        max = FFMAX(max, FFABS(f[i]));
+
+    shift = normalize_bits_int32(max);
+
+    for (i = 0; i < LPC_ORDER + 2; i++)
+        f[i] = av_clipl_int32((int64_t)(f[i] << shift) + (1 << 15)) >> 16;
+
+    /**
+     * Evaluate F1 and F2 at uniform intervals of pi/256 along the
+     * unit circle and check for zero crossings.
+     */
+    p    = 0;
+    temp = 0;
+    for (i = 0; i <= LPC_ORDER / 2; i++)
+        temp += f[2 * i] * cos_tab[0];
+    prev_val = av_clipl_int32(temp << 1);
+    count    = 0;
+    for ( i = 1; i < COS_TBL_SIZE / 2; i++) {
+        /* Evaluate */
+        temp = 0;
+        for (j = 0; j <= LPC_ORDER / 2; j++)
+            temp += f[LPC_ORDER - 2 * j + p] * cos_tab[i * j % COS_TBL_SIZE];
+        cur_val = av_clipl_int32(temp << 1);
+
+        /* Check for sign change, indicating a zero crossing */
+        if ((cur_val ^ prev_val) < 0) {
+            int abs_cur  = FFABS(cur_val);
+            int abs_prev = FFABS(prev_val);
+            int sum      = abs_cur + abs_prev;
+
+            shift        = normalize_bits_int32(sum);
+            sum          <<= shift;
+            abs_prev     = abs_prev << shift >> 8;
+            lsp[count++] = ((i - 1) << 7) + (abs_prev >> 1) / (sum >> 16);
+
+            if (count == LPC_ORDER)
+                break;
+
+            /* Switch between sum and difference polynomials */
+            p ^= 1;
+
+            /* Evaluate */
+            temp = 0;
+            for (j = 0; j <= LPC_ORDER / 2; j++){
+                temp += f[LPC_ORDER - 2 * j + p] *
+                        cos_tab[i * j % COS_TBL_SIZE];
+            }
+            cur_val = av_clipl_int32(temp<<1);
+        }
+        prev_val = cur_val;
+    }
+
+    if (count != LPC_ORDER)
+        memcpy(lsp, prev_lsp, LPC_ORDER * sizeof(int16_t));
+}
+
+/**
+ * Quantize the current LSP subvector.
+ *
+ * @param num    band number
+ * @param offset offset of the current subvector in an LPC_ORDER vector
+ * @param size   size of the current subvector
+ */
+#define get_index(num, offset, size) \
+{\
+    int error, max = -1;\
+    int16_t temp[4];\
+    int i, j;\
+    for (i = 0; i < LSP_CB_SIZE; i++) {\
+        for (j = 0; j < size; j++){\
+            temp[j] = (weight[j + (offset)] * lsp_band##num[i][j] +\
+                      (1 << 14)) >> 15;\
+        }\
+        error =  dot_product(lsp + (offset), temp, size) << 1;\
+        error -= dot_product(lsp_band##num[i], temp, size);\
+        if (error > max) {\
+            max = error;\
+            lsp_index[num] = i;\
+        }\
+    }\
+}
+
+/**
+ * Vector quantize the LSP frequencies.
+ *
+ * @param lsp      the current lsp vector
+ * @param prev_lsp the previous lsp vector
+ */
+static void lsp_quantize(uint8_t *lsp_index, int16_t *lsp, int16_t *prev_lsp)
+{
+    int16_t weight[LPC_ORDER];
+    int16_t min, max;
+    int shift, i;
+
+    /* Calculate the VQ weighting vector */
+    weight[0] = (1 << 20) / (lsp[1] - lsp[0]);
+    weight[LPC_ORDER - 1] = (1 << 20) /
+                            (lsp[LPC_ORDER - 1] - lsp[LPC_ORDER - 2]);
+
+    for (i = 1; i < LPC_ORDER - 1; i++) {
+        min  = FFMIN(lsp[i] - lsp[i - 1], lsp[i + 1] - lsp[i]);
+        if (min > 0x20)
+            weight[i] = (1 << 20) / min;
+        else
+            weight[i] = INT16_MAX;
+    }
+
+    /* Normalize */
+    max = 0;
+    for (i = 0; i < LPC_ORDER; i++)
+        max = FFMAX(weight[i], max);
+
+    shift = normalize_bits_int16(max);
+    for (i = 0; i < LPC_ORDER; i++) {
+        weight[i] <<= shift;
+    }
+
+    /* Compute the VQ target vector */
+    for (i = 0; i < LPC_ORDER; i++) {
+        lsp[i] -= dc_lsp[i] +
+                  (((prev_lsp[i] - dc_lsp[i]) * 12288 + (1 << 14)) >> 15);
+    }
+
+    get_index(0, 0, 3);
+    get_index(1, 3, 3);
+    get_index(2, 6, 4);
+}
+
+/**
+ * Apply the formant perceptual weighting filter.
+ *
+ * @param flt_coef filter coefficients
+ * @param unq_lpc  unquantized lpc vector
+ */
+static void perceptual_filter(G723_1_Context *p, int16_t *flt_coef,
+                              int16_t *unq_lpc, int16_t *buf)
+{
+    int16_t vector[FRAME_LEN + LPC_ORDER];
+    int i, j, k, l = 0;
+
+    memcpy(buf, p->iir_mem, sizeof(int16_t) * LPC_ORDER);
+    memcpy(vector, p->fir_mem, sizeof(int16_t) * LPC_ORDER);
+    memcpy(vector + LPC_ORDER, buf + LPC_ORDER, sizeof(int16_t) * FRAME_LEN);
+
+    for (i = LPC_ORDER, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) {
+        for (k = 0; k < LPC_ORDER; k++) {
+            flt_coef[k + 2 * l] = (unq_lpc[k + l] * percept_flt_tbl[0][k] +
+                                  (1 << 14)) >> 15;
+            flt_coef[k + 2 * l + LPC_ORDER] = (unq_lpc[k + l] *
+                                             percept_flt_tbl[1][k] +
+                                             (1 << 14)) >> 15;
+        }
+        iir_filter(flt_coef + 2 * l, flt_coef + 2 * l + LPC_ORDER, vector + i,
+                   buf + i, 0);
+        l += LPC_ORDER;
+    }
+    memcpy(p->iir_mem, buf + FRAME_LEN, sizeof(int16_t) * LPC_ORDER);
+    memcpy(p->fir_mem, vector + FRAME_LEN, sizeof(int16_t) * LPC_ORDER);
+}
+
+/**
+ * Estimate the open loop pitch period.
+ *
+ * @param buf   perceptually weighted speech
+ * @param start estimation is carried out from this position
+ */
+static int estimate_pitch(int16_t *buf, int start)
+{
+    int max_exp = 32;
+    int max_ccr = 0x4000;
+    int max_eng = 0x7fff;
+    int index   = PITCH_MIN;
+    int offset  = start - PITCH_MIN + 1;
+
+    int ccr, eng, orig_eng, ccr_eng, exp;
+    int diff, temp;
+
+    int i;
+
+    orig_eng = ff_dot_product(buf + offset, buf + offset, HALF_FRAME_LEN);
+
+    for (i = PITCH_MIN; i <= PITCH_MAX - 3; i++) {
+        offset--;
+
+        /* Update energy and compute correlation */
+        orig_eng += buf[offset] * buf[offset] -
+                    buf[offset + HALF_FRAME_LEN] * buf[offset + HALF_FRAME_LEN];
+        ccr      =  ff_dot_product(buf + start, buf + offset, HALF_FRAME_LEN);
+        if (ccr <= 0)
+            continue;
+
+        /* Split into mantissa and exponent to maintain precision */
+        exp  =   normalize_bits_int32(ccr);
+        ccr  =   av_clipl_int32((int64_t)(ccr << exp) + (1 << 15)) >> 16;
+        exp  <<= 1;
+        ccr  *=  ccr;
+        temp =   normalize_bits_int32(ccr);
+        ccr  =   ccr << temp >> 16;
+        exp  +=  temp;
+
+        temp =   normalize_bits_int32(orig_eng);
+        eng  =   av_clipl_int32((int64_t)(orig_eng << temp) + (1 << 15)) >> 16;
+        exp  -=  temp;
+
+        if (ccr >= eng) {
+            exp--;
+            ccr >>= 1;
+        }
+        if (exp > max_exp)
+            continue;
+
+        if (exp + 1 < max_exp)
+            goto update;
+
+        /* Equalize exponents before comparison */
+        if (exp + 1 == max_exp)
+            temp = max_ccr >> 1;
+        else
+            temp = max_ccr;
+        ccr_eng = ccr * max_eng;
+        diff    = ccr_eng - eng * temp;
+        if (diff > 0 && (i - index < PITCH_MIN || diff > ccr_eng >> 2)) {
+update:
+            index   = i;
+            max_exp = exp;
+            max_ccr = ccr;
+            max_eng = eng;
+        }
+    }
+    return index;
+}
+
+/**
+ * Compute harmonic noise filter parameters.
+ *
+ * @param buf       perceptually weighted speech
+ * @param pitch_lag open loop pitch period
+ * @param hf        harmonic filter parameters
+ */
+static void comp_harmonic_coeff(int16_t *buf, int16_t pitch_lag, HFParam *hf)
+{
+    int ccr, eng, max_ccr, max_eng;
+    int exp, max, diff;
+    int energy[15];
+    int i, j;
+
+    for (i = 0, j = pitch_lag - 3; j <= pitch_lag + 3; i++, j++) {
+        /* Compute residual energy */
+        energy[i << 1] = ff_dot_product(buf - j, buf - j, SUBFRAME_LEN);
+        /* Compute correlation */
+        energy[(i << 1) + 1] = ff_dot_product(buf, buf - j, SUBFRAME_LEN);
+    }
+
+    /* Compute target energy */
+    energy[14] = ff_dot_product(buf, buf, SUBFRAME_LEN);
+
+    /* Normalize */
+    max = 0;
+    for (i = 0; i < 15; i++)
+        max = FFMAX(max, FFABS(energy[i]));
+
+    exp = normalize_bits_int32(max);
+    for (i = 0; i < 15; i++) {
+        energy[i] = av_clipl_int32((int64_t)(energy[i] << exp) +
+                                   (1 << 15)) >> 16;
+    }
+
+    hf->index = -1;
+    hf->gain  =  0;
+    max_ccr   =  1;
+    max_eng   =  0x7fff;
+
+    for (i = 0; i <= 6; i++) {
+        eng = energy[i << 1];
+        ccr = energy[(i << 1) + 1];
+
+        if (ccr <= 0)
+            continue;
+
+        ccr  = (ccr * ccr + (1 << 14)) >> 15;
+        diff = ccr * max_eng - eng * max_ccr;
+        if (diff > 0) {
+            max_ccr   = ccr;
+            max_eng   = eng;
+            hf->index = i;
+        }
+    }
+
+    if (hf->index == -1) {
+        hf->index = pitch_lag;
+        return;
+    }
+
+    eng = energy[14] * max_eng;
+    eng = (eng >> 2) + (eng >> 3);
+    ccr = energy[(hf->index << 1) + 1] * energy[(hf->index << 1) + 1];
+    if (eng < ccr) {
+        eng = energy[(hf->index << 1) + 1];
+
+        if (eng >= max_eng)
+            hf->gain = 0x2800;
+        else
+            hf->gain = ((eng << 15) / max_eng * 0x2800 + (1 << 14)) >> 15;
+    }
+    hf->index += pitch_lag - 3;
+}
+
+/**
+ * Apply the harmonic noise shaping filter.
+ *
+ * @param hf filter parameters
+ */
+static void harmonic_filter(HFParam *hf, const int16_t *src, int16_t *dest)
+{
+    int i;
+
+    for (i = 0; i < SUBFRAME_LEN; i++) {
+        int64_t temp = hf->gain * src[i - hf->index] << 1;
+        dest[i] = av_clipl_int32((src[i] << 16) - temp + (1 << 15)) >> 16;
+    }
+}
+
+static void harmonic_noise_sub(HFParam *hf, const int16_t *src, int16_t *dest)
+{
+    int i;
+    for (i = 0; i < SUBFRAME_LEN; i++) {
+        int64_t temp = hf->gain * src[i - hf->index] << 1;
+        dest[i] = av_clipl_int32(((dest[i] - src[i]) << 16) + temp +
+                                 (1 << 15)) >> 16;
+
+    }
+}
+
+/**
+ * Combined synthesis and formant perceptual weighting filer.
+ *
+ * @param qnt_lpc  quantized lpc coefficients
+ * @param perf_lpc perceptual filter coefficients
+ * @param perf_fir perceptual filter fir memory
+ * @param perf_iir perceptual filter iir memory
+ * @param scale    the filter output will be scaled by 2^scale
+ */
+static void synth_percept_filter(int16_t *qnt_lpc, int16_t *perf_lpc,
+                                 int16_t *perf_fir, int16_t *perf_iir,
+                                 const int16_t *src, int16_t *dest, int scale)
+{
+    int i, j;
+    int16_t buf_16[SUBFRAME_LEN + LPC_ORDER];
+    int64_t buf[SUBFRAME_LEN];
+
+    int16_t *bptr_16 = buf_16 + LPC_ORDER;
+
+    memcpy(buf_16, perf_fir, sizeof(int16_t) * LPC_ORDER);
+    memcpy(dest - LPC_ORDER, perf_iir, sizeof(int16_t) * LPC_ORDER);
+
+    for (i = 0; i < SUBFRAME_LEN; i++) {
+        int64_t temp = 0;
+        for (j = 1; j <= LPC_ORDER; j++)
+            temp -= qnt_lpc[j - 1] * bptr_16[i - j];
+
+        buf[i]     = (src[i] << 15) + (temp << 3);
+        bptr_16[i] = av_clipl_int32(buf[i] + (1 << 15)) >> 16;
+    }
+
+    for (i = 0; i < SUBFRAME_LEN; i++) {
+        int64_t fir = 0, iir = 0;
+        for (j = 1; j <= LPC_ORDER; j++) {
+            fir -= perf_lpc[j - 1] * bptr_16[i - j];
+            iir += perf_lpc[j + LPC_ORDER - 1] * dest[i - j];
+        }
+        dest[i] = av_clipl_int32(((buf[i] + (fir << 3)) << scale) + (iir << 3) +
+                                 (1 << 15)) >> 16;
+    }
+    memcpy(perf_fir, buf_16 + SUBFRAME_LEN, sizeof(int16_t) * LPC_ORDER);
+    memcpy(perf_iir, dest + SUBFRAME_LEN - LPC_ORDER,
+           sizeof(int16_t) * LPC_ORDER);
+}
+
+/**
+ * Compute the adaptive codebook contribution.
+ *
+ * @param buf   input signal
+ * @param index the current subframe index
+ */
+static void acb_search(G723_1_Context *p, int16_t *residual,
+                       int16_t *impulse_resp, const int16_t *buf,
+                       int index)
+{
+
+    int16_t flt_buf[PITCH_ORDER][SUBFRAME_LEN];
+
+    const int16_t *cb_tbl = adaptive_cb_gain85;
+
+    int ccr_buf[PITCH_ORDER * SUBFRAMES << 2];
+
+    int pitch_lag = p->pitch_lag[index >> 1];
+    int acb_lag   = 1;
+    int acb_gain  = 0;
+    int odd_frame = index & 1;
+    int iter      = 3 + odd_frame;
+    int count     = 0;
+    int tbl_size  = 85;
+
+    int i, j, k, l, max;
+    int64_t temp;
+
+    if (!odd_frame) {
+        if (pitch_lag == PITCH_MIN)
+            pitch_lag++;
+        else
+            pitch_lag = FFMIN(pitch_lag, PITCH_MAX - 5);
+    }
+
+    for (i = 0; i < iter; i++) {
+        get_residual(residual, p->prev_excitation, pitch_lag + i - 1);
+
+        for (j = 0; j < SUBFRAME_LEN; j++) {
+            temp = 0;
+            for (k = 0; k <= j; k++)
+                temp += residual[PITCH_ORDER - 1 + k] * impulse_resp[j - k];
+            flt_buf[PITCH_ORDER - 1][j] = av_clipl_int32((temp << 1) +
+                                                         (1 << 15)) >> 16;
+        }
+
+        for (j = PITCH_ORDER - 2; j >= 0; j--) {
+            flt_buf[j][0] = ((residual[j] << 13) + (1 << 14)) >> 15;
+            for (k = 1; k < SUBFRAME_LEN; k++) {
+                temp = (flt_buf[j + 1][k - 1] << 15) +
+                       residual[j] * impulse_resp[k];
+                flt_buf[j][k] = av_clipl_int32((temp << 1) + (1 << 15)) >> 16;
+            }
+        }
+
+        /* Compute crosscorrelation with the signal */
+        for (j = 0; j < PITCH_ORDER; j++) {
+            temp = ff_dot_product(buf, flt_buf[j], SUBFRAME_LEN);
+            ccr_buf[count++] = av_clipl_int32(temp << 1);
+        }
+
+        /* Compute energies */
+        for (j = 0; j < PITCH_ORDER; j++) {
+            ccr_buf[count++] = dot_product(flt_buf[j], flt_buf[j],
+                                           SUBFRAME_LEN);
+        }
+
+        for (j = 1; j < PITCH_ORDER; j++) {
+            for (k = 0; k < j; k++) {
+                temp = ff_dot_product(flt_buf[j], flt_buf[k], SUBFRAME_LEN);
+                ccr_buf[count++] = av_clipl_int32(temp<<2);
+            }
+        }
+    }
+
+    /* Normalize and shorten */
+    max = 0;
+    for (i = 0; i < 20 * iter; i++)
+        max = FFMAX(max, FFABS(ccr_buf[i]));
+
+    temp = normalize_bits_int32(max);
+
+    for (i = 0; i < 20 * iter; i++){
+        ccr_buf[i] = av_clipl_int32((int64_t)(ccr_buf[i] << temp) +
+                                    (1 << 15)) >> 16;
+    }
+
+    max = 0;
+    for (i = 0; i < iter; i++) {
+        /* Select quantization table */
+        if (!odd_frame && pitch_lag + i - 1 >= SUBFRAME_LEN - 2 ||
+            odd_frame && pitch_lag >= SUBFRAME_LEN - 2) {
+            cb_tbl = adaptive_cb_gain170;
+            tbl_size = 170;
+        }
+
+        for (j = 0, k = 0; j < tbl_size; j++, k += 20) {
+            temp = 0;
+            for (l = 0; l < 20; l++)
+                temp += ccr_buf[20 * i + l] * cb_tbl[k + l];
+            temp =  av_clipl_int32(temp);
+
+            if (temp > max) {
+                max      = temp;
+                acb_gain = j;
+                acb_lag  = i;
+            }
+        }
+    }
+
+    if (!odd_frame) {
+        pitch_lag += acb_lag - 1;
+        acb_lag   =  1;
+    }
+
+    p->pitch_lag[index >> 1]      = pitch_lag;
+    p->subframe[index].ad_cb_lag  = acb_lag;
+    p->subframe[index].ad_cb_gain = acb_gain;
+}
+
+/**
+ * Subtract the adaptive codebook contribution from the input
+ * to obtain the residual.
+ *
+ * @param buf target vector
+ */
+static void sub_acb_contrib(const int16_t *residual, const int16_t *impulse_resp,
+                            int16_t *buf)
+{
+    int i, j;
+    /* Subtract adaptive CB contribution to obtain the residual */
+    for (i = 0; i < SUBFRAME_LEN; i++) {
+        int64_t temp = buf[i] << 14;
+        for (j = 0; j <= i; j++)
+            temp -= residual[j] * impulse_resp[i - j];
+
+        buf[i] = av_clipl_int32((temp << 2) + (1 << 15)) >> 16;
+    }
+}
+
+/**
+ * Quantize the residual signal using the fixed codebook (MP-MLQ).
+ *
+ * @param optim optimized fixed codebook parameters
+ * @param buf   excitation vector
+ */
+static void get_fcb_param(FCBParam *optim, int16_t *impulse_resp,
+                          int16_t *buf, int pulse_cnt, int pitch_lag)
+{
+    FCBParam param;
+    int16_t impulse_r[SUBFRAME_LEN];
+    int16_t temp_corr[SUBFRAME_LEN];
+    int16_t impulse_corr[SUBFRAME_LEN];
+
+    int ccr1[SUBFRAME_LEN];
+    int ccr2[SUBFRAME_LEN];
+    int amp, err, max, max_amp_index, min, scale, i, j, k, l;
+
+    int64_t temp;
+
+    /* Update impulse response */
+    memcpy(impulse_r, impulse_resp, sizeof(int16_t) * SUBFRAME_LEN);
+    param.dirac_train = 0;
+    if (pitch_lag < SUBFRAME_LEN - 2) {
+        param.dirac_train = 1;
+        gen_dirac_train(impulse_r, pitch_lag);
+    }
+
+    for (i = 0; i < SUBFRAME_LEN; i++)
+        temp_corr[i] = impulse_r[i] >> 1;
+
+    /* Compute impulse response autocorrelation */
+    temp = dot_product(temp_corr, temp_corr, SUBFRAME_LEN);
+
+    scale = normalize_bits_int32(temp);
+    impulse_corr[0] = av_clipl_int32((temp << scale) + (1 << 15)) >> 16;
+
+    for (i = 1; i < SUBFRAME_LEN; i++) {
+        temp = dot_product(temp_corr + i, temp_corr, SUBFRAME_LEN - i);
+        impulse_corr[i] = av_clipl_int32((temp << scale) + (1 << 15)) >> 16;
+    }
+
+    /* Compute crosscorrelation of impulse response with residual signal */
+    scale -= 4;
+    for (i = 0; i < SUBFRAME_LEN; i++){
+        temp = dot_product(buf + i, impulse_r, SUBFRAME_LEN - i);
+        if (scale < 0)
+            ccr1[i] = temp >> -scale;
+        else
+            ccr1[i] = av_clipl_int32(temp << scale);
+    }
+
+    /* Search loop */
+    for (i = 0; i < GRID_SIZE; i++) {
+        /* Maximize the crosscorrelation */
+        max = 0;
+        for (j = i; j < SUBFRAME_LEN; j += GRID_SIZE) {
+            temp = FFABS(ccr1[j]);
+            if (temp >= max) {
+                max = temp;
+                param.pulse_pos[0] = j;
+            }
+        }
+
+        /* Quantize the gain (max crosscorrelation/impulse_corr[0]) */
+        amp = max;
+        min = 1 << 30;
+        max_amp_index = GAIN_LEVELS - 2;
+        for (j = max_amp_index; j >= 2; j--) {
+            temp = av_clipl_int32((int64_t)fixed_cb_gain[j] *
+                                  impulse_corr[0] << 1);
+            temp = FFABS(temp - amp);
+            if (temp < min) {
+                min = temp;
+                max_amp_index = j;
+            }
+        }
+
+        max_amp_index--;
+        /* Select additional gain values */
+        for (j = 1; j < 5; j++) {
+            for (k = i; k < SUBFRAME_LEN; k += GRID_SIZE) {
+                temp_corr[k] = 0;
+                ccr2[k]      = ccr1[k];
+            }
+            param.amp_index = max_amp_index + j - 2;
+            amp = fixed_cb_gain[param.amp_index];
+
+            param.pulse_sign[0] = (ccr2[param.pulse_pos[0]] < 0) ? -amp : amp;
+            temp_corr[param.pulse_pos[0]] = 1;
+
+            for (k = 1; k < pulse_cnt; k++) {
+                max = -1 << 30;
+                for (l = i; l < SUBFRAME_LEN; l += GRID_SIZE) {
+                    if (temp_corr[l])
+                        continue;
+                    temp = impulse_corr[FFABS(l - param.pulse_pos[k - 1])];
+                    temp = av_clipl_int32((int64_t)temp *
+                                          param.pulse_sign[k - 1] << 1);
+                    ccr2[l] -= temp;
+                    temp = FFABS(ccr2[l]);
+                    if (temp > max) {
+                        max = temp;
+                        param.pulse_pos[k] = l;
+                    }
+                }
+
+                param.pulse_sign[k] = (ccr2[param.pulse_pos[k]] < 0) ?
+                                      -amp : amp;
+                temp_corr[param.pulse_pos[k]] = 1;
+            }
+
+            /* Create the error vector */
+            memset(temp_corr, 0, sizeof(int16_t) * SUBFRAME_LEN);
+
+            for (k = 0; k < pulse_cnt; k++)
+                temp_corr[param.pulse_pos[k]] = param.pulse_sign[k];
+
+            for (k = SUBFRAME_LEN - 1; k >= 0; k--) {
+                temp = 0;
+                for (l = 0; l <= k; l++) {
+                    int prod = av_clipl_int32((int64_t)temp_corr[l] *
+                                              impulse_r[k - l] << 1);
+                    temp     = av_clipl_int32(temp + prod);
+                }
+                temp_corr[k] = temp << 2 >> 16;
+            }
+
+            /* Compute square of error */
+            err = 0;
+            for (k = 0; k < SUBFRAME_LEN; k++) {
+                int64_t prod;
+                prod = av_clipl_int32((int64_t)buf[k] * temp_corr[k] << 1);
+                err  = av_clipl_int32(err - prod);
+                prod = av_clipl_int32((int64_t)temp_corr[k] * temp_corr[k]);
+                err  = av_clipl_int32(err + prod);
+            }
+
+            /* Minimize */
+            if (err < optim->min_err) {
+                optim->min_err     = err;
+                optim->grid_index  = i;
+                optim->amp_index   = param.amp_index;
+                optim->dirac_train = param.dirac_train;
+
+                for (k = 0; k < pulse_cnt; k++) {
+                    optim->pulse_sign[k] = param.pulse_sign[k];
+                    optim->pulse_pos[k]  = param.pulse_pos[k];
+                }
+            }
+        }
+    }
+}
+
+/**
+ * Encode the pulse position and gain of the current subframe.
+ *
+ * @param optim optimized fixed CB parameters
+ * @param buf   excitation vector
+ */
+static void pack_fcb_param(G723_1_Subframe *subfrm, FCBParam *optim,
+                           int16_t *buf, int pulse_cnt)
+{
+    int i, j;
+
+    j = PULSE_MAX - pulse_cnt;
+
+    subfrm->pulse_sign = 0;
+    subfrm->pulse_pos  = 0;
+
+    for (i = 0; i < SUBFRAME_LEN >> 1; i++) {
+        int val = buf[optim->grid_index + (i << 1)];
+        if (!val) {
+            subfrm->pulse_pos += combinatorial_table[j][i];
+        } else {
+            subfrm->pulse_sign <<= 1;
+            if (val < 0) subfrm->pulse_sign++;
+            j++;
+
+            if (j == PULSE_MAX) break;
+        }
+    }
+    subfrm->amp_index   = optim->amp_index;
+    subfrm->grid_index  = optim->grid_index;
+    subfrm->dirac_train = optim->dirac_train;
+}
+
+/**
+ * Compute the fixed codebook excitation.
+ *
+ * @param buf          target vector
+ * @param impulse_resp impulse response of the combined filter
+ */
+static void fcb_search(G723_1_Context *p, int16_t *impulse_resp,
+                       int16_t *buf, int index)
+{
+    FCBParam optim;
+    int pulse_cnt = pulses[index];
+    int i;
+
+    optim.min_err = 1 << 30;
+    get_fcb_param(&optim, impulse_resp, buf, pulse_cnt, SUBFRAME_LEN);
+
+    if (p->pitch_lag[index >> 1] < SUBFRAME_LEN - 2) {
+        get_fcb_param(&optim, impulse_resp, buf, pulse_cnt,
+                      p->pitch_lag[index >> 1]);
+    }
+
+    /* Reconstruct the excitation */
+    memset(buf, 0, sizeof(int16_t) * SUBFRAME_LEN);
+    for (i = 0; i < pulse_cnt; i++)
+        buf[optim.pulse_pos[i]] = optim.pulse_sign[i];
+
+    pack_fcb_param(&p->subframe[index], &optim, buf, pulse_cnt);
+
+    if (optim.dirac_train)
+        gen_dirac_train(buf, p->pitch_lag[index >> 1]);
+}
+
+/**
+ * Pack the frame parameters into output bitstream.
+ *
+ * @param frame output buffer
+ * @param size  size of the buffer
+ */
+static int pack_bitstream(G723_1_Context *p, unsigned char *frame, int size)
+{
+    PutBitContext pb;
+    int info_bits, i, temp;
+
+    init_put_bits(&pb, frame, size);
+
+    if (p->cur_rate == RATE_6300) {
+        info_bits = 0;
+        put_bits(&pb, 2, info_bits);
+    }
+
+    put_bits(&pb, 8, p->lsp_index[2]);
+    put_bits(&pb, 8, p->lsp_index[1]);
+    put_bits(&pb, 8, p->lsp_index[0]);
+
+    put_bits(&pb, 7, p->pitch_lag[0] - PITCH_MIN);
+    put_bits(&pb, 2, p->subframe[1].ad_cb_lag);
+    put_bits(&pb, 7, p->pitch_lag[1] - PITCH_MIN);
+    put_bits(&pb, 2, p->subframe[3].ad_cb_lag);
+
+    /* Write 12 bit combined gain */
+    for (i = 0; i < SUBFRAMES; i++) {
+        temp = p->subframe[i].ad_cb_gain * GAIN_LEVELS +
+               p->subframe[i].amp_index;
+        if (p->cur_rate ==  RATE_6300)
+            temp += p->subframe[i].dirac_train << 11;
+        put_bits(&pb, 12, temp);
+    }
+
+    put_bits(&pb, 1, p->subframe[0].grid_index);
+    put_bits(&pb, 1, p->subframe[1].grid_index);
+    put_bits(&pb, 1, p->subframe[2].grid_index);
+    put_bits(&pb, 1, p->subframe[3].grid_index);
+
+    if (p->cur_rate == RATE_6300) {
+        skip_put_bits(&pb, 1); /* reserved bit */
+
+        /* Write 13 bit combined position index */
+        temp = (p->subframe[0].pulse_pos >> 16) * 810 +
+               (p->subframe[1].pulse_pos >> 14) *  90 +
+               (p->subframe[2].pulse_pos >> 16) *   9 +
+               (p->subframe[3].pulse_pos >> 14);
+        put_bits(&pb, 13, temp);
+
+        put_bits(&pb, 16, p->subframe[0].pulse_pos & 0xffff);
+        put_bits(&pb, 14, p->subframe[1].pulse_pos & 0x3fff);
+        put_bits(&pb, 16, p->subframe[2].pulse_pos & 0xffff);
+        put_bits(&pb, 14, p->subframe[3].pulse_pos & 0x3fff);
+
+        put_bits(&pb, 6, p->subframe[0].pulse_sign);
+        put_bits(&pb, 5, p->subframe[1].pulse_sign);
+        put_bits(&pb, 6, p->subframe[2].pulse_sign);
+        put_bits(&pb, 5, p->subframe[3].pulse_sign);
+    }
+
+    flush_put_bits(&pb);
+    return frame_size[info_bits];
+}
+
+static int g723_1_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
+                            const AVFrame *frame, int *got_packet_ptr)
+{
+    G723_1_Context *p = avctx->priv_data;
+    int16_t unq_lpc[LPC_ORDER * SUBFRAMES];
+    int16_t qnt_lpc[LPC_ORDER * SUBFRAMES];
+    int16_t cur_lsp[LPC_ORDER];
+    int16_t weighted_lpc[LPC_ORDER * SUBFRAMES << 1];
+    int16_t vector[FRAME_LEN + PITCH_MAX];
+    int offset, ret;
+    int16_t *in = (const int16_t *)frame->data[0];
+
+    HFParam hf[4];
+    int i, j;
+
+    highpass_filter(in, &p->hpf_fir_mem, &p->hpf_iir_mem);
+
+    memcpy(vector, p->prev_data, HALF_FRAME_LEN * sizeof(int16_t));
+    memcpy(vector + HALF_FRAME_LEN, in, FRAME_LEN * sizeof(int16_t));
+
+    comp_lpc_coeff(vector, unq_lpc);
+    lpc2lsp(&unq_lpc[LPC_ORDER * 3], p->prev_lsp, cur_lsp);
+    lsp_quantize(p->lsp_index, cur_lsp, p->prev_lsp);
+
+    /* Update memory */
+    memcpy(vector + LPC_ORDER, p->prev_data + SUBFRAME_LEN,
+           sizeof(int16_t) * SUBFRAME_LEN);
+    memcpy(vector + LPC_ORDER + SUBFRAME_LEN, in,
+           sizeof(int16_t) * (HALF_FRAME_LEN + SUBFRAME_LEN));
+    memcpy(p->prev_data, in + HALF_FRAME_LEN,
+           sizeof(int16_t) * HALF_FRAME_LEN);
+    memcpy(in, vector + LPC_ORDER, sizeof(int16_t) * FRAME_LEN);
+
+    perceptual_filter(p, weighted_lpc, unq_lpc, vector);
+
+    memcpy(in, vector + LPC_ORDER, sizeof(int16_t) * FRAME_LEN);
+    memcpy(vector, p->prev_weight_sig, sizeof(int16_t) * PITCH_MAX);
+    memcpy(vector + PITCH_MAX, in, sizeof(int16_t) * FRAME_LEN);
+
+    scale_vector(vector, vector, FRAME_LEN + PITCH_MAX);
+
+    p->pitch_lag[0] = estimate_pitch(vector, PITCH_MAX);
+    p->pitch_lag[1] = estimate_pitch(vector, PITCH_MAX + HALF_FRAME_LEN);
+
+    for (i = PITCH_MAX, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++)
+        comp_harmonic_coeff(vector + i, p->pitch_lag[j >> 1], hf + j);
+
+    memcpy(vector, p->prev_weight_sig, sizeof(int16_t) * PITCH_MAX);
+    memcpy(vector + PITCH_MAX, in, sizeof(int16_t) * FRAME_LEN);
+    memcpy(p->prev_weight_sig, vector + FRAME_LEN, sizeof(int16_t) * PITCH_MAX);
+
+    for (i = 0, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++)
+        harmonic_filter(hf + j, vector + PITCH_MAX + i, in + i);
+
+    inverse_quant(cur_lsp, p->prev_lsp, p->lsp_index, 0);
+    lsp_interpolate(qnt_lpc, cur_lsp, p->prev_lsp);
+
+    memcpy(p->prev_lsp, cur_lsp, sizeof(int16_t) * LPC_ORDER);
+
+    offset = 0;
+    for (i = 0; i < SUBFRAMES; i++) {
+        int16_t impulse_resp[SUBFRAME_LEN];
+        int16_t residual[SUBFRAME_LEN + PITCH_ORDER - 1];
+        int16_t flt_in[SUBFRAME_LEN];
+        int16_t zero[LPC_ORDER], fir[LPC_ORDER], iir[LPC_ORDER];
+
+        /**
+         * Compute the combined impulse response of the synthesis filter,
+         * formant perceptual weighting filter and harmonic noise shaping filter
+         */
+        memset(zero, 0, sizeof(int16_t) * LPC_ORDER);
+        memset(vector, 0, sizeof(int16_t) * PITCH_MAX);
+        memset(flt_in, 0, sizeof(int16_t) * SUBFRAME_LEN);
+
+        flt_in[0] = 1 << 13; /* Unit impulse */
+        synth_percept_filter(qnt_lpc + offset, weighted_lpc + (offset << 1),
+                             zero, zero, flt_in, vector + PITCH_MAX, 1);
+        harmonic_filter(hf + i, vector + PITCH_MAX, impulse_resp);
+
+         /* Compute the combined zero input response */
+        flt_in[0] = 0;
+        memcpy(fir, p->perf_fir_mem, sizeof(int16_t) * LPC_ORDER);
+        memcpy(iir, p->perf_iir_mem, sizeof(int16_t) * LPC_ORDER);
+
+        synth_percept_filter(qnt_lpc + offset, weighted_lpc + (offset << 1),
+                             fir, iir, flt_in, vector + PITCH_MAX, 0);
+        memcpy(vector, p->harmonic_mem, sizeof(int16_t) * PITCH_MAX);
+        harmonic_noise_sub(hf + i, vector + PITCH_MAX, in);
+
+        acb_search(p, residual, impulse_resp, in, i);
+        gen_acb_excitation(residual, p->prev_excitation,p->pitch_lag[i >> 1],
+                           &p->subframe[i], p->cur_rate);
+        sub_acb_contrib(residual, impulse_resp, in);
+
+        fcb_search(p, impulse_resp, in, i);
+
+        /* Reconstruct the excitation */
+        gen_acb_excitation(impulse_resp, p->prev_excitation, p->pitch_lag[i >> 1],
+                           &p->subframe[i], RATE_6300);
+
+        memmove(p->prev_excitation, p->prev_excitation + SUBFRAME_LEN,
+               sizeof(int16_t) * (PITCH_MAX - SUBFRAME_LEN));
+        for (j = 0; j < SUBFRAME_LEN; j++)
+            in[j] = av_clip_int16((in[j] << 1) + impulse_resp[j]);
+        memcpy(p->prev_excitation + PITCH_MAX - SUBFRAME_LEN, in,
+               sizeof(int16_t) * SUBFRAME_LEN);
+
+        /* Update filter memories */
+        synth_percept_filter(qnt_lpc + offset, weighted_lpc + (offset << 1),
+                             p->perf_fir_mem, p->perf_iir_mem,
+                             in, vector + PITCH_MAX, 0);
+        memmove(p->harmonic_mem, p->harmonic_mem + SUBFRAME_LEN,
+                sizeof(int16_t) * (PITCH_MAX - SUBFRAME_LEN));
+        memcpy(p->harmonic_mem + PITCH_MAX - SUBFRAME_LEN, vector + PITCH_MAX,
+               sizeof(int16_t) * SUBFRAME_LEN);
+
+        in += SUBFRAME_LEN;
+        offset += LPC_ORDER;
+    }
+
+    if ((ret = ff_alloc_packet2(avctx, avpkt, 24)))
+        return ret;
+
+    *got_packet_ptr = 1;
+    avpkt->size = pack_bitstream(p, avpkt->data, avpkt->size);
+    return 0;
+}
+
+AVCodec ff_g723_1_encoder = {
+    .name           = "g723_1",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_G723_1,
+    .priv_data_size = sizeof(G723_1_Context),
+    .init           = g723_1_encode_init,
+    .encode2        = g723_1_encode_frame,
+    .long_name      = NULL_IF_CONFIG_SMALL("G.723.1"),
+    .sample_fmts    = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,
+                                                    AV_SAMPLE_FMT_NONE},
+};
+#endif
diff --git a/libavcodec/g723_1_data.h b/libavcodec/g723_1_data.h
index 04f8a06..8ee4a91 100644
--- a/libavcodec/g723_1_data.h
+++ b/libavcodec/g723_1_data.h
@@ -1,28 +1,28 @@
 /*
- * G.723.1 compatible decoder data tables.
+ * G723.1 compatible decoder data tables.
  * Copyright (c) 2006 Benjamin Larsson
  * Copyright (c) 2010 Mohamed Naufal Basheer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
  * @file
- * G.723.1 compatible decoder data tables
+ * G723.1 compatible decoder data tables
  */
 
 #ifndef AVCODEC_G723_1_DATA_H
@@ -33,6 +33,8 @@
 #define SUBFRAMES       4
 #define SUBFRAME_LEN    60
 #define FRAME_LEN       (SUBFRAME_LEN << 2)
+#define HALF_FRAME_LEN  (FRAME_LEN / 2)
+#define LPC_FRAME       (HALF_FRAME_LEN + SUBFRAME_LEN)
 #define LPC_ORDER       10
 #define LSP_BANDS       3
 #define LSP_CB_SIZE     256
@@ -44,18 +46,88 @@
 #define GAIN_LEVELS     24
 #define COS_TBL_SIZE    512
 
+/**
+ * G723.1 frame types
+ */
+typedef enum FrameType {
+    ACTIVE_FRAME,        ///< Active speech
+    SID_FRAME,           ///< Silence Insertion Descriptor frame
+    UNTRANSMITTED_FRAME
+} FrameType;
+
 static const uint8_t frame_size[4] = { 24, 20, 4, 1 };
 
-/* Postfilter gain weighting factors scaled by 2^15 */
-static const int16_t ppf_gain_weight[2] = { 0x1800, 0x2000 };
+typedef enum Rate {
+    RATE_6300,
+    RATE_5300
+} Rate;
 
-/* LSP DC component */
+/**
+ * G723.1 unpacked data subframe
+ */
+typedef struct G723_1_Subframe {
+    int ad_cb_lag;     ///< adaptive codebook lag
+    int ad_cb_gain;
+    int dirac_train;
+    int pulse_sign;
+    int grid_index;
+    int amp_index;
+    int pulse_pos;
+} G723_1_Subframe;
+
+/**
+ * Pitch postfilter parameters
+ */
+typedef struct {
+    int     index;    ///< postfilter backward/forward lag
+    int16_t opt_gain; ///< optimal gain
+    int16_t sc_gain;  ///< scaling gain
+} PPFParam;
+
+/**
+ * Harmonic filter parameters
+ */
+typedef struct {
+    int index;
+    int gain;
+} HFParam;
+
+/**
+ * Optimized fixed codebook excitation parameters
+ */
+typedef struct {
+    int min_err;
+    int amp_index;
+    int grid_index;
+    int dirac_train;
+    int pulse_pos[PULSE_MAX];
+    int pulse_sign[PULSE_MAX];
+} FCBParam;
+
+/**
+ * Postfilter gain weighting factors scaled by 2^15
+ */
+static const int16_t ppf_gain_weight[2] = {0x1800, 0x2000};
+
+/**
+ * LSP DC component
+ */
 static const int16_t dc_lsp[LPC_ORDER] = {
-    0x0c3b, 0x1271, 0x1e0a, 0x2a36, 0x3630,
-    0x406f, 0x4d28, 0x56f4, 0x638c, 0x6c46
+    0x0c3b,
+    0x1271,
+    0x1e0a,
+    0x2a36,
+    0x3630,
+    0x406f,
+    0x4d28,
+    0x56f4,
+    0x638c,
+    0x6c46
 };
 
-/* Cosine table scaled by 2^14 */
+/**
+ * Cosine table scaled by 2^14
+ */
 static const int16_t cos_tab[COS_TBL_SIZE] = {
     16384,  16383,  16379,  16373,  16364,  16353,  16340,  16324,
     16305,  16284,  16261,  16235,  16207,  16176,  16143,  16107,
@@ -123,7 +195,9 @@
     16305,  16324,  16340,  16353,  16364,  16373,  16379,  16383,
 };
 
-/* LSP VQ tables */
+/**
+ *  LSP VQ tables
+ */
 static const int16_t lsp_band0[LSP_CB_SIZE][3] = {
     {    0,      0,      0}, { -270,  -1372,  -1032}, { -541,  -1650,  -1382},
     { -723,  -2011,  -2213}, { -941,  -1122,  -1942}, { -780,  -1145,  -2454},
@@ -433,12 +507,12 @@
     { 3633,   2336,   2408,   1453}, { 2923,   3517,   2567,   1318},
 };
 
-/*
+/**
  * Used for the coding/decoding of the pulses positions
  * for the MP-MLQ codebook
  */
 static const int32_t combinatorial_table[PULSE_MAX][SUBFRAME_LEN/GRID_SIZE] = {
-    {118755, 98280, 80730, 65780L, 53130,
+    {118755, 98280, 80730,  65780, 53130,
       42504, 33649, 26334,  20349, 15504,
       11628,  8568,  6188,   4368,  3003,
        2002,  1287,   792,    462,   252,
@@ -527,10 +601,14 @@
     -2, 25144,  0, 17998
 };
 
-/* Number of non-zero pulses in the MP-MLQ excitation */
+/**
+ * Number of non-zero pulses in the MP-MLQ excitation
+ */
 static const int8_t pulses[4] = {6, 5, 6, 5};
 
-/* Size of the MP-MLQ fixed excitation codebooks */
+/**
+ * Size of the MP-MLQ fixed excitation codebooks
+ */
 static const int32_t max_pos[4] = {593775, 142506, 593775, 142506};
 
 static const int16_t fixed_cb_gain[GAIN_LEVELS] = {
@@ -1183,12 +1261,62 @@
     -4534,  -2487,  -3932,  -4166,  -2113,  -3341,  -3540,  -3070
 };
 
-/* 0.65^i (Zero part) and 0.75^i (Pole part) scaled by 2^15 */
+/**
+ * 0.65^i (Zero part) and 0.75^i (Pole part) scaled by 2^15
+ */
 static const int16_t postfilter_tbl[2][LPC_ORDER] = {
     /* Zero */
-    { 21299, 13844,  8999,  5849, 3802, 2471, 1606, 1044,  679,  441 },
+    {21299, 13844,  8999,  5849, 3802, 2471, 1606, 1044,  679,  441},
     /* Pole */
-    { 24576, 18432, 13824, 10368, 7776, 5832, 4374, 3281, 2460, 1845 }
+    {24576, 18432, 13824, 10368, 7776, 5832, 4374, 3281, 2460, 1845}
+};
+
+/**
+ * Hamming window coefficients scaled by 2^15
+ */
+static const int16_t hamming_window[LPC_FRAME] = {
+     2621,  2631,  2659,  2705,  2770,  2853,  2955,  3074,  3212,  3367,
+     3541,  3731,  3939,  4164,  4405,  4663,  4937,  5226,  5531,  5851,
+     6186,  6534,  6897,  7273,  7661,  8062,  8475,  8899,  9334,  9780,
+    10235, 10699, 11172, 11653, 12141, 12636, 13138, 13645, 14157, 14673,
+    15193, 15716, 16242, 16769, 17298, 17827, 18356, 18884, 19411, 19935,
+    20457, 20975, 21489, 21999, 22503, 23002, 23494, 23978, 24455, 24924,
+    25384, 25834, 26274, 26704, 27122, 27529, 27924, 28306, 28675, 29031,
+    29373, 29700, 30012, 30310, 30592, 30857, 31107, 31340, 31557, 31756,
+    31938, 32102, 32249, 32377, 32488, 32580, 32654, 32710, 32747, 32766,
+    32766, 32747, 32710, 32654, 32580, 32488, 32377, 32249, 32102, 31938,
+    31756, 31557, 31340, 31107, 30857, 30592, 30310, 30012, 29700, 29373,
+    29031, 28675, 28306, 27924, 27529, 27122, 26704, 26274, 25834, 25384,
+    24924, 24455, 23978, 23494, 23002, 22503, 21999, 21489, 20975, 20457,
+    19935, 19411, 18884, 18356, 17827, 17298, 16769, 16242, 15716, 15193,
+    14673, 14157, 13645, 13138, 12636, 12141, 11653, 11172, 10699, 10235,
+     9780, 9334,   8899,  8475,  8062,  7661,  7273,  6897,  6534,  6186,
+     5851, 5531,   5226,  4937,  4663,  4405,  4164,  3939,  3731,  3541,
+     3367, 3212,   3074,  2955,  2853,  2770,  2705,  2659,  2631,  2621
+};
+
+/**
+ * Binomial window coefficients scaled by 2^15
+ */
+static const int16_t binomial_window[LPC_ORDER] = {
+    32749, 32695, 32604, 32477, 32315, 32118, 31887, 31622, 31324, 30995
+};
+
+/**
+ * 0.994^i scaled by 2^15
+ */
+static const int16_t bandwidth_expand[LPC_ORDER] = {
+    32571, 32376, 32182, 31989, 31797, 31606, 31416, 31228, 31040, 30854
+};
+
+/**
+ * 0.5^i scaled by 2^15
+ */
+static const int16_t percept_flt_tbl[2][LPC_ORDER] = {
+    /* Zero part */
+    {29491, 26542, 23888, 21499, 19349, 17414, 15673, 14106, 12695, 11425},
+    /* Pole part */
+    {16384,  8192,  4096,  2048,  1024,   512,   256,   128,    64,    32}
 };
 
 static const int cng_adaptive_cb_lag[4] = { 1, 0, 1, 3 };
diff --git a/libavcodec/g726.c b/libavcodec/g726.c
index 7fa2be3..b2f21fd 100644
--- a/libavcodec/g726.c
+++ b/libavcodec/g726.c
@@ -5,20 +5,20 @@
  * This is a very straightforward rendition of the G.726
  * Section 4 "Computational Details".
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include <limits.h>
@@ -32,7 +32,7 @@
 /**
  * G.726 11bit float.
  * G.726 Standard uses rather odd 11bit floating point arithmentic for
- * numerous occasions. It's a mistery to me why they did it this way
+ * numerous occasions. It's a mystery to me why they did it this way
  * instead of simply using 32bit integer arithmetic.
  */
 typedef struct Float11 {
@@ -361,10 +361,8 @@
     int i, ret, out_size;
 
     out_size = (frame->nb_samples * c->code_size + 7) / 8;
-    if ((ret = ff_alloc_packet(avpkt, out_size))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, out_size)))
         return ret;
-    }
     init_put_bits(&pb, avpkt->data, avpkt->size);
 
     for (i = 0; i < frame->nb_samples; i++)
diff --git a/libavcodec/g729.h b/libavcodec/g729.h
new file mode 100644
index 0000000..6168313
--- /dev/null
+++ b/libavcodec/g729.h
@@ -0,0 +1,29 @@
+/*
+ * G.729, G729 Annex D decoders
+ * Copyright (c) 2008 Vladimir Voroshilov
+ *
+ * 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_G729_H
+#define AVCODEC_G729_H
+
+/**
+ * subframe size
+ */
+#define SUBFRAME_SIZE 40
+
+#endif // AVCODEC_G729_H
diff --git a/libavcodec/g729data.h b/libavcodec/g729data.h
new file mode 100644
index 0000000..365ca47
--- /dev/null
+++ b/libavcodec/g729data.h
@@ -0,0 +1,382 @@
+/*
+ * data for G.729, G729 Annex D decoders
+ * Copyright (c) 2007 Vladimir Voroshilov
+ *
+ * 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_G729DATA_H
+#define AVCODEC_G729DATA_H
+
+#include <stdint.h>
+
+#define MA_NP                4  ///< Moving Average (MA) prediction order
+
+#define VQ_1ST_BITS          7  ///< first stage vector of quantizer (size in bits)
+#define VQ_2ND_BITS          5  ///< second stage vector of quantizer (size in bits)
+
+#define GC_1ST_IDX_BITS_8K   3  ///< gain codebook (first stage) index, 8k mode (size in bits)
+#define GC_2ND_IDX_BITS_8K   4  ///< gain codebook (second stage) index, 8k mode (size in bits)
+
+#define GC_1ST_IDX_BITS_6K4  3  ///< gain codebook (first stage) index, 6.4k mode (size in bits)
+#define GC_2ND_IDX_BITS_6K4  3  ///< gain codebook (second stage) index, 6.4k mode (size in bits)
+
+/**
+ * first stage LSP codebook
+ * (10-dimensional, with 128 entries (3.24 of G.729)
+ */
+static const int16_t cb_lsp_1st[1<<VQ_1ST_BITS][10] = { /* (2.13) */
+  { 1486,  2168,  3751,  9074, 12134, 13944, 17983, 19173, 21190, 21820},
+  { 1730,  2640,  3450,  4870,  6126,  7876, 15644, 17817, 20294, 21902},
+  { 1568,  2256,  3088,  4874, 11063, 13393, 18307, 19293, 21109, 21741},
+  { 1733,  2512,  3357,  4708,  6977, 10296, 17024, 17956, 19145, 20350},
+  { 1744,  2436,  3308,  8731, 10432, 12007, 15614, 16639, 21359, 21913},
+  { 1786,  2369,  3372,  4521,  6795, 12963, 17674, 18988, 20855, 21640},
+  { 1631,  2433,  3361,  6328, 10709, 12013, 13277, 13904, 19441, 21088},
+  { 1489,  2364,  3291,  6250,  9227, 10403, 13843, 15278, 17721, 21451},
+  { 1869,  2533,  3475,  4365,  9152, 14513, 15908, 17022, 20611, 21411},
+  { 2070,  3025,  4333,  5854,  7805,  9231, 10597, 16047, 20109, 21834},
+  { 1910,  2673,  3419,  4261, 11168, 15111, 16577, 17591, 19310, 20265},
+  { 1141,  1815,  2624,  4623,  6495,  9588, 13968, 16428, 19351, 21286},
+  { 2192,  3171,  4707,  5808, 10904, 12500, 14162, 15664, 21124, 21789},
+  { 1286,  1907,  2548,  3453,  9574, 11964, 15978, 17344, 19691, 22495},
+  { 1921,  2720,  4604,  6684, 11503, 12992, 14350, 15262, 16997, 20791},
+  { 2052,  2759,  3897,  5246,  6638, 10267, 15834, 16814, 18149, 21675},
+  { 1798,  2497,  5617, 11449, 13189, 14711, 17050, 18195, 20307, 21182},
+  { 1009,  1647,  2889,  5709,  9541, 12354, 15231, 18494, 20966, 22033},
+  { 3016,  3794,  5406,  7469, 12488, 13984, 15328, 16334, 19952, 20791},
+  { 2203,  3040,  3796,  5442, 11987, 13512, 14931, 16370, 17856, 18803},
+  { 2912,  4292,  7988,  9572, 11562, 13244, 14556, 16529, 20004, 21073},
+  { 2861,  3607,  5923,  7034,  9234, 12054, 13729, 18056, 20262, 20974},
+  { 3069,  4311,  5967,  7367, 11482, 12699, 14309, 16233, 18333, 19172},
+  { 2434,  3661,  4866,  5798, 10383, 11722, 13049, 15668, 18862, 19831},
+  { 2020,  2605,  3860,  9241, 13275, 14644, 16010, 17099, 19268, 20251},
+  { 1877,  2809,  3590,  4707, 11056, 12441, 15622, 17168, 18761, 19907},
+  { 2107,  2873,  3673,  5799, 13579, 14687, 15938, 17077, 18890, 19831},
+  { 1612,  2284,  2944,  3572,  8219, 13959, 15924, 17239, 18592, 20117},
+  { 2420,  3156,  6542, 10215, 12061, 13534, 15305, 16452, 18717, 19880},
+  { 1667,  2612,  3534,  5237, 10513, 11696, 12940, 16798, 18058, 19378},
+  { 2388,  3017,  4839,  9333, 11413, 12730, 15024, 16248, 17449, 18677},
+  { 1875,  2786,  4231,  6320,  8694, 10149, 11785, 17013, 18608, 19960},
+  {  679,  1411,  4654,  8006, 11446, 13249, 15763, 18127, 20361, 21567},
+  { 1838,  2596,  3578,  4608,  5650, 11274, 14355, 15886, 20579, 21754},
+  { 1303,  1955,  2395,  3322, 12023, 13764, 15883, 18077, 20180, 21232},
+  { 1438,  2102,  2663,  3462,  8328, 10362, 13763, 17248, 19732, 22344},
+  {  860,  1904,  6098,  7775,  9815, 12007, 14821, 16709, 19787, 21132},
+  { 1673,  2723,  3704,  6125,  7668,  9447, 13683, 14443, 20538, 21731},
+  { 1246,  1849,  2902,  4508,  7221, 12710, 14835, 16314, 19335, 22720},
+  { 1525,  2260,  3862,  5659,  7342, 11748, 13370, 14442, 18044, 21334},
+  { 1196,  1846,  3104,  7063, 10972, 12905, 14814, 17037, 19922, 22636},
+  { 2147,  3106,  4475,  6511,  8227,  9765, 10984, 12161, 18971, 21300},
+  { 1585,  2405,  2994,  4036, 11481, 13177, 14519, 15431, 19967, 21275},
+  { 1778,  2688,  3614,  4680,  9465, 11064, 12473, 16320, 19742, 20800},
+  { 1862,  2586,  3492,  6719, 11708, 13012, 14364, 16128, 19610, 20425},
+  { 1395,  2156,  2669,  3386, 10607, 12125, 13614, 16705, 18976, 21367},
+  { 1444,  2117,  3286,  6233,  9423, 12981, 14998, 15853, 17188, 21857},
+  { 2004,  2895,  3783,  4897,  6168,  7297, 12609, 16445, 19297, 21465},
+  { 1495,  2863,  6360,  8100, 11399, 14271, 15902, 17711, 20479, 22061},
+  { 2484,  3114,  5718,  7097,  8400, 12616, 14073, 14847, 20535, 21396},
+  { 2424,  3277,  5296,  6284, 11290, 12903, 16022, 17508, 19333, 20283},
+  { 2565,  3778,  5360,  6989,  8782, 10428, 14390, 15742, 17770, 21734},
+  { 2727,  3384,  6613,  9254, 10542, 12236, 14651, 15687, 20074, 21102},
+  { 1916,  2953,  6274,  8088,  9710, 10925, 12392, 16434, 20010, 21183},
+  { 3384,  4366,  5349,  7667, 11180, 12605, 13921, 15324, 19901, 20754},
+  { 3075,  4283,  5951,  7619,  9604, 11010, 12384, 14006, 20658, 21497},
+  { 1751,  2455,  5147,  9966, 11621, 13176, 14739, 16470, 20788, 21756},
+  { 1442,  2188,  3330,  6813,  8929, 12135, 14476, 15306, 19635, 20544},
+  { 2294,  2895,  4070,  8035, 12233, 13416, 14762, 17367, 18952, 19688},
+  { 1937,  2659,  4602,  6697,  9071, 12863, 14197, 15230, 16047, 18877},
+  { 2071,  2663,  4216,  9445, 10887, 12292, 13949, 14909, 19236, 20341},
+  { 1740,  2491,  3488,  8138,  9656, 11153, 13206, 14688, 20896, 21907},
+  { 2199,  2881,  4675,  8527, 10051, 11408, 14435, 15463, 17190, 20597},
+  { 1943,  2988,  4177,  6039,  7478,  8536, 14181, 15551, 17622, 21579},
+  { 1825,  3175,  7062,  9818, 12824, 15450, 18330, 19856, 21830, 22412},
+  { 2464,  3046,  4822,  5977,  7696, 15398, 16730, 17646, 20588, 21320},
+  { 2550,  3393,  5305,  6920, 10235, 14083, 18143, 19195, 20681, 21336},
+  { 3003,  3799,  5321,  6437,  7919, 11643, 15810, 16846, 18119, 18980},
+  { 3455,  4157,  6838,  8199,  9877, 12314, 15905, 16826, 19949, 20892},
+  { 3052,  3769,  4891,  5810,  6977, 10126, 14788, 15990, 19773, 20904},
+  { 3671,  4356,  5827,  6997,  8460, 12084, 14154, 14939, 19247, 20423},
+  { 2716,  3684,  5246,  6686,  8463, 10001, 12394, 14131, 16150, 19776},
+  { 1945,  2638,  4130,  7995, 14338, 15576, 17057, 18206, 20225, 20997},
+  { 2304,  2928,  4122,  4824,  5640, 13139, 15825, 16938, 20108, 21054},
+  { 1800,  2516,  3350,  5219, 13406, 15948, 17618, 18540, 20531, 21252},
+  { 1436,  2224,  2753,  4546,  9657, 11245, 15177, 16317, 17489, 19135},
+  { 2319,  2899,  4980,  6936,  8404, 13489, 15554, 16281, 20270, 20911},
+  { 2187,  2919,  4610,  5875,  7390, 12556, 14033, 16794, 20998, 21769},
+  { 2235,  2923,  5121,  6259,  8099, 13589, 15340, 16340, 17927, 20159},
+  { 1765,  2638,  3751,  5730,  7883, 10108, 13633, 15419, 16808, 18574},
+  { 3460,  5741,  9596, 11742, 14413, 16080, 18173, 19090, 20845, 21601},
+  { 3735,  4426,  6199,  7363,  9250, 14489, 16035, 17026, 19873, 20876},
+  { 3521,  4778,  6887,  8680, 12717, 14322, 15950, 18050, 20166, 21145},
+  { 2141,  2968,  6865,  8051, 10010, 13159, 14813, 15861, 17528, 18655},
+  { 4148,  6128,  9028, 10871, 12686, 14005, 15976, 17208, 19587, 20595},
+  { 4403,  5367,  6634,  8371, 10163, 11599, 14963, 16331, 17982, 18768},
+  { 4091,  5386,  6852,  8770, 11563, 13290, 15728, 16930, 19056, 20102},
+  { 2746,  3625,  5299,  7504, 10262, 11432, 13172, 15490, 16875, 17514},
+  { 2248,  3556,  8539, 10590, 12665, 14696, 16515, 17824, 20268, 21247},
+  { 1279,  1960,  3920,  7793, 10153, 14753, 16646, 18139, 20679, 21466},
+  { 2440,  3475,  6737,  8654, 12190, 14588, 17119, 17925, 19110, 19979},
+  { 1879,  2514,  4497,  7572, 10017, 14948, 16141, 16897, 18397, 19376},
+  { 2804,  3688,  7490, 10086, 11218, 12711, 16307, 17470, 20077, 21126},
+  { 2023,  2682,  3873,  8268, 10255, 11645, 15187, 17102, 18965, 19788},
+  { 2823,  3605,  5815,  8595, 10085, 11469, 16568, 17462, 18754, 19876},
+  { 2851,  3681,  5280,  7648,  9173, 10338, 14961, 16148, 17559, 18474},
+  { 1348,  2645,  5826,  8785, 10620, 12831, 16255, 18319, 21133, 22586},
+  { 2141,  3036,  4293,  6082,  7593, 10629, 17158, 18033, 21466, 22084},
+  { 1608,  2375,  3384,  6878,  9970, 11227, 16928, 17650, 20185, 21120},
+  { 2774,  3616,  5014,  6557,  7788,  8959, 17068, 18302, 19537, 20542},
+  { 1934,  4813,  6204,  7212,  8979, 11665, 15989, 17811, 20426, 21703},
+  { 2288,  3507,  5037,  6841,  8278,  9638, 15066, 16481, 21653, 22214},
+  { 2951,  3771,  4878,  7578,  9016, 10298, 14490, 15242, 20223, 20990},
+  { 3256,  4791,  6601,  7521,  8644,  9707, 13398, 16078, 19102, 20249},
+  { 1827,  2614,  3486,  6039, 12149, 13823, 16191, 17282, 21423, 22041},
+  { 1000,  1704,  3002,  6335,  8471, 10500, 14878, 16979, 20026, 22427},
+  { 1646,  2286,  3109,  7245, 11493, 12791, 16824, 17667, 18981, 20222},
+  { 1708,  2501,  3315,  6737,  8729,  9924, 16089, 17097, 18374, 19917},
+  { 2623,  3510,  4478,  5645,  9862, 11115, 15219, 18067, 19583, 20382},
+  { 2518,  3434,  4728,  6388,  8082,  9285, 13162, 18383, 19819, 20552},
+  { 1726,  2383,  4090,  6303,  7805, 12845, 14612, 17608, 19269, 20181},
+  { 2860,  3735,  4838,  6044,  7254,  8402, 14031, 16381, 18037, 19410},
+  { 4247,  5993,  7952,  9792, 12342, 14653, 17527, 18774, 20831, 21699},
+  { 3502,  4051,  5680,  6805,  8146, 11945, 16649, 17444, 20390, 21564},
+  { 3151,  4893,  5899,  7198, 11418, 13073, 15124, 17673, 20520, 21861},
+  { 3960,  4848,  5926,  7259,  8811, 10529, 15661, 16560, 18196, 20183},
+  { 4499,  6604,  8036,  9251, 10804, 12627, 15880, 17512, 20020, 21046},
+  { 4251,  5541,  6654,  8318,  9900, 11686, 15100, 17093, 20572, 21687},
+  { 3769,  5327,  7865,  9360, 10684, 11818, 13660, 15366, 18733, 19882},
+  { 3083,  3969,  6248,  8121,  9798, 10994, 12393, 13686, 17888, 19105},
+  { 2731,  4670,  7063,  9201, 11346, 13735, 16875, 18797, 20787, 22360},
+  { 1187,  2227,  4737,  7214,  9622, 12633, 15404, 17968, 20262, 23533},
+  { 1911,  2477,  3915, 10098, 11616, 12955, 16223, 17138, 19270, 20729},
+  { 1764,  2519,  3887,  6944,  9150, 12590, 16258, 16984, 17924, 18435},
+  { 1400,  3674,  7131,  8718, 10688, 12508, 15708, 17711, 19720, 21068},
+  { 2322,  3073,  4287,  8108,  9407, 10628, 15862, 16693, 19714, 21474},
+  { 2630,  3339,  4758,  8360, 10274, 11333, 12880, 17374, 19221, 19936},
+  { 1721,  2577,  5553,  7195,  8651, 10686, 15069, 16953, 18703, 19929}
+};
+
+/**
+ * second stage LSP codebook, high and low parts
+   (both 5-dimensional, with 32 entries (3.2.4 of G.729)
+ */
+static const int16_t cb_lsp_2nd[1<<VQ_2ND_BITS][10] = { /* (2.13) */
+  { -435,  -815,  -742,  1033,  -518,   582, -1201,   829,    86,   385},
+  { -833,  -891,   463,    -8, -1251,  1450,    72,  -231,   864,   661},
+  {-1021,   231,  -306,   321,  -220,  -163,  -526,  -754, -1633,   267},
+  {   57,  -198,  -339,   -33, -1468,   573,   796,  -169,  -631,   816},
+  {  171,  -350,   294,  1660,   453,   519,   291,   159,  -640, -1296},
+  { -701,  -842,   -58,   950,   892,  1549,   715,   527,  -714,  -193},
+  {  584,    31,  -289,   356,  -333,  -457,   612,  -283, -1381,  -741},
+  { -109,  -808,   231,    77,   -87,  -344,  1341,  1087,  -654,  -569},
+  { -859,  1236,   550,   854,   714,  -543, -1752,  -195,   -98,  -276},
+  { -877,  -954, -1248,  -299,   212,  -235,  -728,   949,  1517,   895},
+  {  -77,   344,  -620,   763,   413,   502,  -362,  -960,  -483,  1386},
+  { -314,  -307,  -256, -1260,  -429,   450,  -466,  -108,  1010,  2223},
+  {  711,   693,   521,   650,  1305,   -28,  -378,   744, -1005,   240},
+  { -112,  -271,  -500,   946,  1733,   271,   -15,   909,  -259,  1688},
+  {  575,   -10,  -468,  -199,  1101, -1011,   581,   -53,  -747,   878},
+  {  145,  -285, -1280,  -398,    36,  -498, -1377,    18,  -444,  1483},
+  {-1133,  -835,  1350,  1284,   -95,  1015,  -222,   443,   372,  -354},
+  {-1459, -1237,   416,  -213,   466,   669,   659,  1640,   932,   534},
+  {  -15,    66,   468,  1019,  -748,  1385,  -182,  -907,  -721,  -262},
+  { -338,   148,  1445,    75,  -760,   569,  1247,   337,   416,  -121},
+  {  389,   239,  1568,   981,   113,   369, -1003,  -507,  -587,  -904},
+  { -312,   -98,   949,    31,  1104,    72,  -141,  1465,    63,  -785},
+  { 1127,   584,   835,   277, -1159,   208,   301,  -882,   117,  -404},
+  {  539,  -114,   856,  -493,   223,  -912,   623,   -76,   276,  -440},
+  { 2197,  2337,  1268,   670,   304,  -267,  -525,   140,   882,  -139},
+  {-1596,   550,   801,  -456,   -56,  -697,   865,  1060,   413,   446},
+  { 1154,   593,   -77,  1237,   -31,   581, -1037,  -895,   669,   297},
+  {  397,   558,   203,  -797,  -919,     3,   692,  -292,  1050,   782},
+  {  334,  1475,   632,   -80,    48, -1061,  -484,   362,  -597,  -852},
+  { -545,  -330,  -429,  -680,  1133, -1182,  -744,  1340,   262,    63},
+  { 1320,   827,  -398,  -576,   341,  -774,  -483, -1247,   -70,    98},
+  { -163,   674,   -11,  -886,   531, -1125,  -265,  -242,   724,   934}
+};
+
+/**
+ * gain codebook (first stage), 8k mode (3.9.2 of G.729)
+ */
+static const int16_t cb_gain_1st_8k[1<<GC_1ST_IDX_BITS_8K][2] = { /*(0.14) (2.13) */
+  { 3242 ,  9949 },
+  { 1551 ,  2425 },
+  { 2678 , 27162 },
+  { 1921 ,  9291 },
+  { 1831 ,  5022 },
+  {    1 ,  1516 },
+  {  356 , 14756 },
+  {   57 ,  5404 },
+};
+
+/**
+ * gain codebook (second stage), 8k mode (3.9.2 of G.729)
+ */
+static const int16_t cb_gain_2nd_8k[1<<GC_2ND_IDX_BITS_8K][2] = { /*(1.14) (1.13) */
+  {  5142 ,   592 },
+  { 17299 ,  1861 },
+  {  6160 ,  2395 },
+  { 16112 ,  3392 },
+  {   826 ,  2005 },
+  { 18973 ,  5935 },
+  {  1994 ,     0 },
+  { 15434 ,   237 },
+  { 10573 ,  2966 },
+  { 15132 ,  4914 },
+  { 11569 ,  1196 },
+  { 14194 ,  1630 },
+  {  8091 ,  4861 },
+  { 15161 , 14276 },
+  {  9120 ,   525 },
+  { 13260 ,  3256 },
+};
+
+/**
+ * gain codebook (first stage), 6.4k mode (D.3.9.2 of G.729)
+ */
+static const int16_t cb_gain_1st_6k4[1<<GC_1ST_IDX_BITS_6K4][2] =
+{ /*(0.14) (1.14)*/
+ { 5849,     0 },
+ { 3171,  9280 },
+ { 3617,  6747 },
+ { 4987, 22294 },
+ { 2929,  1078 },
+ { 6068,  6093 },
+ { 9425,  2731 },
+ { 3915, 12872 },
+};
+
+/**
+ * gain codebook (second stage), 6.4k mode (D.3.9.2 of G.729)
+ */
+static const int16_t cb_gain_2nd_6k4[1<<GC_2ND_IDX_BITS_6K4][2] =
+{ /*(1.14) (1.14)*/
+ {    0,  4175 },
+ {10828, 27602 },
+ {16423, 15724 },
+ { 4478,  7324 },
+ { 3988,     0 },
+ {10291, 11385 },
+ {11956, 10735 },
+ { 7876,  7821 },
+};
+
+/**
+ * 4th order Moving Average (MA) Predictor codebook (3.2.4 of G.729)
+ *
+ * float cb_ma_predictor_float[2][MA_NP][10] = {
+ *   {
+ *     {0.2570, 0.2780, 0.2800, 0.2736, 0.2757, 0.2764, 0.2675, 0.2678, 0.2779, 0.2647},
+ *     {0.2142, 0.2194, 0.2331, 0.2230, 0.2272, 0.2252, 0.2148, 0.2123, 0.2115, 0.2096},
+ *     {0.1670, 0.1523, 0.1567, 0.1580, 0.1601, 0.1569, 0.1589, 0.1555, 0.1474, 0.1571},
+ *     {0.1238, 0.0925, 0.0798, 0.0923, 0.0890, 0.0828, 0.1010, 0.0988, 0.0872, 0.1060},
+ *   },
+ *   {
+ *     {0.2360, 0.2405, 0.2499, 0.2495, 0.2517, 0.2591, 0.2636, 0.2625, 0.2551, 0.2310},
+ *     {0.1285, 0.0925, 0.0779, 0.1060, 0.1183, 0.1176, 0.1277, 0.1268, 0.1193, 0.1211},
+ *     {0.0981, 0.0589, 0.0401, 0.0654, 0.0761, 0.0728, 0.0841, 0.0826, 0.0776, 0.0891},
+ *     {0.0923, 0.0486, 0.0287, 0.0498, 0.0526, 0.0482, 0.0621, 0.0636, 0.0584, 0.0794},
+ *   },
+ * };
+ *                                    15
+ * cb_ma_predictor[j][k][i] = floor( 2 * cb_ma_predictor_float[j][k][i] )
+ *
+ * j=0..1, i=0..9, k=0..MA_NP-1
+ */
+static const int16_t cb_ma_predictor[2][MA_NP][10] = { /* (0.15) */
+  {
+    { 8421,  9109,  9175,  8965,  9034,  9057,  8765,  8775,  9106,  8673},
+    { 7018,  7189,  7638,  7307,  7444,  7379,  7038,  6956,  6930,  6868},
+    { 5472,  4990,  5134,  5177,  5246,  5141,  5206,  5095,  4830,  5147},
+    { 4056,  3031,  2614,  3024,  2916,  2713,  3309,  3237,  2857,  3473}
+  },
+  {
+    { 7733,  7880,  8188,  8175,  8247,  8490,  8637,  8601,  8359,  7569},
+    { 4210,  3031,  2552,  3473,  3876,  3853,  4184,  4154,  3909,  3968},
+    { 3214,  1930,  1313,  2143,  2493,  2385,  2755,  2706,  2542,  2919},
+    { 3024,  1592,   940,  1631,  1723,  1579,  2034,  2084,  1913,  2601}
+  }
+};
+
+/**
+ *                                     15         3
+ * cb_ma_predictor_sum[j][i] = floor( 2 * (1.0 - sum ( cb_ma_predictor_float[j][k][i] ) ) )
+ *                                               k=0
+ * j=0..1, i=0..9
+ */
+static const int16_t cb_ma_predictor_sum[2][10] = { /* (0.15) */
+  { 7798,  8447,  8205,  8293,  8126,  8477,  8447,  8703,  9043,  8604},
+  {14585, 18333, 19772, 17344, 16426, 16459, 15155, 15220, 16043, 15708}
+};
+
+/**
+ *                                                           12
+ *                                                          2
+ * cb_ma_predictor_sum_inv[j][i] = floor(---------------------------------------------)
+ *                                               3
+ *                                        1.0 - sum ( cb_ma_predictor_float[j][k][i] )
+ *                                              k=0
+ * j=0..1, i=0..9
+ */
+static const int16_t cb_ma_predictor_sum_inv[2][10] = { /* (3.12) */
+  {17210, 15888, 16357, 16183, 16516, 15833, 15888, 15421, 14840, 15597},
+  { 9202,  7320,  6788,  7738,  8170,  8154,  8856,  8818,  8366,  8544}
+};
+
+/**
+ * MA prediction coefficients (3.9.1 of G.729, near Equation 69)
+ */
+static const uint16_t ma_prediction_coeff[4] = { /* (0.13) */
+  5571, 4751, 2785, 1556
+};
+
+/**
+ * initial LSP coefficients belongs to virtual frame preceding  the
+ * first frame of the stream
+ */
+static const int16_t lsp_init[10]= { /* (0.15) */
+   30000, 26000, 21000, 15000, 8000, 0, -8000,-15000,-21000,-26000
+};
+
+/**
+ * additional "phase" post-processing filter impulse response (D.6.2 of G.729)
+ *
+ * Table contains three impulse responses, correspond to
+ * different amounts of spreading.
+ */
+static const int16_t phase_filter[3][40] =
+{
+  { // maximum spreading (for noise-like segments)
+    14690, 11518,  1268, -2762, -5672,  7514,  -36, -2808, -3041,  4823,
+     2952, -8425,  3785,  1455,  2179, -8638, 8051, -2104, -1455,   777,
+     1108, -2386,  2254,  -364,  -675, -2104, 6046, -5682,  1072,  3123,
+    -5059,  5312, -2330, -3729,  6924, -3890,  675, -1776,    29, 10145,
+  },
+  { // medium spreading
+    30274,  3831, -4037,  2972, -1049, -1003,  2477, -3044,  2815, -2232,
+     1753, -1612,  1714, -1776,  1543, -1009,   429,  -170,   472, -1265,
+     2176, -2707,  2523, -1622,   344,   826, -1530,  1724, -1658,  1701,
+    -2064,  2644, -3061,  2897, -1979,   557,   780, -1370,   842,   655,
+  },
+  { // no spreading (for voiced speech)
+    32767, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  }
+};
+#endif /* AVCODEC_G729DATA_H */
diff --git a/libavcodec/g729dec.c b/libavcodec/g729dec.c
new file mode 100644
index 0000000..7c12b0e
--- /dev/null
+++ b/libavcodec/g729dec.c
@@ -0,0 +1,726 @@
+/*
+ * G.729, G729 Annex D decoders
+ * Copyright (c) 2008 Vladimir Voroshilov
+ *
+ * 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 <inttypes.h>
+#include <string.h>
+
+#include "avcodec.h"
+#include "libavutil/avutil.h"
+#include "get_bits.h"
+#include "dsputil.h"
+
+#include "g729.h"
+#include "lsp.h"
+#include "celp_math.h"
+#include "celp_filters.h"
+#include "acelp_filters.h"
+#include "acelp_pitch_delay.h"
+#include "acelp_vectors.h"
+#include "g729data.h"
+#include "g729postfilter.h"
+
+/**
+ * minimum quantized LSF value (3.2.4)
+ * 0.005 in Q13
+ */
+#define LSFQ_MIN                   40
+
+/**
+ * maximum quantized LSF value (3.2.4)
+ * 3.135 in Q13
+ */
+#define LSFQ_MAX                   25681
+
+/**
+ * minimum LSF distance (3.2.4)
+ * 0.0391 in Q13
+ */
+#define LSFQ_DIFF_MIN              321
+
+/// interpolation filter length
+#define INTERPOL_LEN              11
+
+/**
+ * minimum gain pitch value (3.8, Equation 47)
+ * 0.2 in (1.14)
+ */
+#define SHARP_MIN                  3277
+
+/**
+ * maximum gain pitch value (3.8, Equation 47)
+ * (EE) This does not comply with the specification.
+ * Specification says about 0.8, which should be
+ * 13107 in (1.14), but reference C code uses
+ * 13017 (equals to 0.7945) instead of it.
+ */
+#define SHARP_MAX                  13017
+
+/**
+ * MR_ENERGY (mean removed energy) = mean_energy + 10 * log10(2^26  * subframe_size) in (7.13)
+ */
+#define MR_ENERGY 1018156
+
+#define DECISION_NOISE        0
+#define DECISION_INTERMEDIATE 1
+#define DECISION_VOICE        2
+
+typedef enum {
+    FORMAT_G729_8K = 0,
+    FORMAT_G729D_6K4,
+    FORMAT_COUNT,
+} G729Formats;
+
+typedef struct {
+    uint8_t ac_index_bits[2];   ///< adaptive codebook index for second subframe (size in bits)
+    uint8_t parity_bit;         ///< parity bit for pitch delay
+    uint8_t gc_1st_index_bits;  ///< gain codebook (first stage) index (size in bits)
+    uint8_t gc_2nd_index_bits;  ///< gain codebook (second stage) index (size in bits)
+    uint8_t fc_signs_bits;      ///< number of pulses in fixed-codebook vector
+    uint8_t fc_indexes_bits;    ///< size (in bits) of fixed-codebook index entry
+} G729FormatDescription;
+
+typedef struct {
+    DSPContext dsp;
+    AVFrame frame;
+
+    /// past excitation signal buffer
+    int16_t exc_base[2*SUBFRAME_SIZE+PITCH_DELAY_MAX+INTERPOL_LEN];
+
+    int16_t* exc;               ///< start of past excitation data in buffer
+    int pitch_delay_int_prev;   ///< integer part of previous subframe's pitch delay (4.1.3)
+
+    /// (2.13) LSP quantizer outputs
+    int16_t  past_quantizer_output_buf[MA_NP + 1][10];
+    int16_t* past_quantizer_outputs[MA_NP + 1];
+
+    int16_t lsfq[10];           ///< (2.13) quantized LSF coefficients from previous frame
+    int16_t lsp_buf[2][10];     ///< (0.15) LSP coefficients (previous and current frames) (3.2.5)
+    int16_t *lsp[2];            ///< pointers to lsp_buf
+
+    int16_t quant_energy[4];    ///< (5.10) past quantized energy
+
+    /// previous speech data for LP synthesis filter
+    int16_t syn_filter_data[10];
+
+
+    /// residual signal buffer (used in long-term postfilter)
+    int16_t residual[SUBFRAME_SIZE + RES_PREV_DATA_SIZE];
+
+    /// previous speech data for residual calculation filter
+    int16_t res_filter_data[SUBFRAME_SIZE+10];
+
+    /// previous speech data for short-term postfilter
+    int16_t pos_filter_data[SUBFRAME_SIZE+10];
+
+    /// (1.14) pitch gain of current and five previous subframes
+    int16_t past_gain_pitch[6];
+
+    /// (14.1) gain code from current and previous subframe
+    int16_t past_gain_code[2];
+
+    /// voice decision on previous subframe (0-noise, 1-intermediate, 2-voice), G.729D
+    int16_t voice_decision;
+
+    int16_t onset;              ///< detected onset level (0-2)
+    int16_t was_periodic;       ///< whether previous frame was declared as periodic or not (4.4)
+    int16_t ht_prev_data;       ///< previous data for 4.2.3, equation 86
+    int gain_coeff;             ///< (1.14) gain coefficient (4.2.4)
+    uint16_t rand_value;        ///< random number generator value (4.4.4)
+    int ma_predictor_prev;      ///< switched MA predictor of LSP quantizer from last good frame
+
+    /// (14.14) high-pass filter data (past input)
+    int hpf_f[2];
+
+    /// high-pass filter data (past output)
+    int16_t hpf_z[2];
+}  G729Context;
+
+static const G729FormatDescription format_g729_8k = {
+    .ac_index_bits     = {8,5},
+    .parity_bit        = 1,
+    .gc_1st_index_bits = GC_1ST_IDX_BITS_8K,
+    .gc_2nd_index_bits = GC_2ND_IDX_BITS_8K,
+    .fc_signs_bits     = 4,
+    .fc_indexes_bits   = 13,
+};
+
+static const G729FormatDescription format_g729d_6k4 = {
+    .ac_index_bits     = {8,4},
+    .parity_bit        = 0,
+    .gc_1st_index_bits = GC_1ST_IDX_BITS_6K4,
+    .gc_2nd_index_bits = GC_2ND_IDX_BITS_6K4,
+    .fc_signs_bits     = 2,
+    .fc_indexes_bits   = 9,
+};
+
+/**
+ * @brief pseudo random number generator
+ */
+static inline uint16_t g729_prng(uint16_t value)
+{
+    return 31821 * value + 13849;
+}
+
+/**
+ * Get parity bit of bit 2..7
+ */
+static inline int get_parity(uint8_t value)
+{
+   return (0x6996966996696996ULL >> (value >> 2)) & 1;
+}
+
+/*
+ * Decodes LSF (Line Spectral Frequencies) from L0-L3 (3.2.4).
+ * @param lsfq [out] (2.13) quantized LSF coefficients
+ * @param past_quantizer_outputs [in/out] (2.13) quantizer outputs from previous frames
+ * @param ma_predictor switched MA predictor of LSP quantizer
+ * @param vq_1st first stage vector of quantizer
+ * @param vq_2nd_low second stage lower vector of LSP quantizer
+ * @param vq_2nd_high second stage higher vector of LSP quantizer
+ */
+static void lsf_decode(int16_t* lsfq, int16_t* past_quantizer_outputs[MA_NP + 1],
+                       int16_t ma_predictor,
+                       int16_t vq_1st, int16_t vq_2nd_low, int16_t vq_2nd_high)
+{
+    int i,j;
+    static const uint8_t min_distance[2]={10, 5}; //(2.13)
+    int16_t* quantizer_output = past_quantizer_outputs[MA_NP];
+
+    for (i = 0; i < 5; i++) {
+        quantizer_output[i]     = cb_lsp_1st[vq_1st][i    ] + cb_lsp_2nd[vq_2nd_low ][i    ];
+        quantizer_output[i + 5] = cb_lsp_1st[vq_1st][i + 5] + cb_lsp_2nd[vq_2nd_high][i + 5];
+    }
+
+    for (j = 0; j < 2; j++) {
+        for (i = 1; i < 10; i++) {
+            int diff = (quantizer_output[i - 1] - quantizer_output[i] + min_distance[j]) >> 1;
+            if (diff > 0) {
+                quantizer_output[i - 1] -= diff;
+                quantizer_output[i    ] += diff;
+            }
+        }
+    }
+
+    for (i = 0; i < 10; i++) {
+        int sum = quantizer_output[i] * cb_ma_predictor_sum[ma_predictor][i];
+        for (j = 0; j < MA_NP; j++)
+            sum += past_quantizer_outputs[j][i] * cb_ma_predictor[ma_predictor][j][i];
+
+        lsfq[i] = sum >> 15;
+    }
+
+    ff_acelp_reorder_lsf(lsfq, LSFQ_DIFF_MIN, LSFQ_MIN, LSFQ_MAX, 10);
+}
+
+/**
+ * Restores past LSP quantizer output using LSF from previous frame
+ * @param lsfq [in/out] (2.13) quantized LSF coefficients
+ * @param past_quantizer_outputs [in/out] (2.13) quantizer outputs from previous frames
+ * @param ma_predictor_prev MA predictor from previous frame
+ * @param lsfq_prev (2.13) quantized LSF coefficients from previous frame
+ */
+static void lsf_restore_from_previous(int16_t* lsfq,
+                                      int16_t* past_quantizer_outputs[MA_NP + 1],
+                                      int ma_predictor_prev)
+{
+    int16_t* quantizer_output = past_quantizer_outputs[MA_NP];
+    int i,k;
+
+    for (i = 0; i < 10; i++) {
+        int tmp = lsfq[i] << 15;
+
+        for (k = 0; k < MA_NP; k++)
+            tmp -= past_quantizer_outputs[k][i] * cb_ma_predictor[ma_predictor_prev][k][i];
+
+        quantizer_output[i] = ((tmp >> 15) * cb_ma_predictor_sum_inv[ma_predictor_prev][i]) >> 12;
+    }
+}
+
+/**
+ * Constructs new excitation signal and applies phase filter to it
+ * @param out[out] constructed speech signal
+ * @param in original excitation signal
+ * @param fc_cur (2.13) original fixed-codebook vector
+ * @param gain_code (14.1) gain code
+ * @param subframe_size length of the subframe
+ */
+static void g729d_get_new_exc(
+        int16_t* out,
+        const int16_t* in,
+        const int16_t* fc_cur,
+        int dstate,
+        int gain_code,
+        int subframe_size)
+{
+    int i;
+    int16_t fc_new[SUBFRAME_SIZE];
+
+    ff_celp_convolve_circ(fc_new, fc_cur, phase_filter[dstate], subframe_size);
+
+    for(i=0; i<subframe_size; i++)
+    {
+        out[i]  = in[i];
+        out[i] -= (gain_code * fc_cur[i] + 0x2000) >> 14;
+        out[i] += (gain_code * fc_new[i] + 0x2000) >> 14;
+    }
+}
+
+/**
+ * Makes decision about onset in current subframe
+ * @param past_onset decision result of previous subframe
+ * @param past_gain_code gain code of current and previous subframe
+ *
+ * @return onset decision result for current subframe
+ */
+static int g729d_onset_decision(int past_onset, const int16_t* past_gain_code)
+{
+    if((past_gain_code[0] >> 1) > past_gain_code[1])
+        return 2;
+    else
+        return FFMAX(past_onset-1, 0);
+}
+
+/**
+ * Makes decision about voice presence in current subframe
+ * @param onset onset level
+ * @param prev_voice_decision voice decision result from previous subframe
+ * @param past_gain_pitch pitch gain of current and previous subframes
+ *
+ * @return voice decision result for current subframe
+ */
+static int16_t g729d_voice_decision(int onset, int prev_voice_decision, const int16_t* past_gain_pitch)
+{
+    int i, low_gain_pitch_cnt, voice_decision;
+
+    if(past_gain_pitch[0] >= 14745)      // 0.9
+        voice_decision = DECISION_VOICE;
+    else if (past_gain_pitch[0] <= 9830) // 0.6
+        voice_decision = DECISION_NOISE;
+    else
+        voice_decision = DECISION_INTERMEDIATE;
+
+    for(i=0, low_gain_pitch_cnt=0; i<6; i++)
+        if(past_gain_pitch[i] < 9830)
+            low_gain_pitch_cnt++;
+
+    if(low_gain_pitch_cnt > 2 && !onset)
+        voice_decision = DECISION_NOISE;
+
+    if(!onset && voice_decision > prev_voice_decision + 1)
+        voice_decision--;
+
+    if(onset && voice_decision < DECISION_VOICE)
+        voice_decision++;
+
+    return voice_decision;
+}
+
+static int32_t scalarproduct_int16_c(const int16_t * v1, const int16_t * v2, int order)
+{
+    int res = 0;
+
+    while (order--)
+        res += *v1++ * *v2++;
+
+    return res;
+}
+
+static av_cold int decoder_init(AVCodecContext * avctx)
+{
+    G729Context* ctx = avctx->priv_data;
+    int i,k;
+
+    if (avctx->channels != 1) {
+        av_log(avctx, AV_LOG_ERROR, "Only mono sound is supported (requested channels: %d).\n", avctx->channels);
+        return AVERROR(EINVAL);
+    }
+    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+    /* Both 8kbit/s and 6.4kbit/s modes uses two subframes per frame. */
+    avctx->frame_size = SUBFRAME_SIZE << 1;
+
+    ctx->gain_coeff = 16384; // 1.0 in (1.14)
+
+    for (k = 0; k < MA_NP + 1; k++) {
+        ctx->past_quantizer_outputs[k] = ctx->past_quantizer_output_buf[k];
+        for (i = 1; i < 11; i++)
+            ctx->past_quantizer_outputs[k][i - 1] = (18717 * i) >> 3;
+    }
+
+    ctx->lsp[0] = ctx->lsp_buf[0];
+    ctx->lsp[1] = ctx->lsp_buf[1];
+    memcpy(ctx->lsp[0], lsp_init, 10 * sizeof(int16_t));
+
+    ctx->exc = &ctx->exc_base[PITCH_DELAY_MAX+INTERPOL_LEN];
+
+    ctx->pitch_delay_int_prev = PITCH_DELAY_MIN;
+
+    /* random seed initialization */
+    ctx->rand_value = 21845;
+
+    /* quantized prediction error */
+    for(i=0; i<4; i++)
+        ctx->quant_energy[i] = -14336; // -14 in (5.10)
+
+    ff_dsputil_init(&ctx->dsp, avctx);
+    ctx->dsp.scalarproduct_int16 = scalarproduct_int16_c;
+
+    avcodec_get_frame_defaults(&ctx->frame);
+    avctx->coded_frame = &ctx->frame;
+
+    return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr,
+                        AVPacket *avpkt)
+{
+    const uint8_t *buf = avpkt->data;
+    int buf_size       = avpkt->size;
+    int16_t *out_frame;
+    GetBitContext gb;
+    const G729FormatDescription *format;
+    int frame_erasure = 0;    ///< frame erasure detected during decoding
+    int bad_pitch = 0;        ///< parity check failed
+    int i;
+    int16_t *tmp;
+    G729Formats packet_type;
+    G729Context *ctx = avctx->priv_data;
+    int16_t lp[2][11];           // (3.12)
+    uint8_t ma_predictor;     ///< switched MA predictor of LSP quantizer
+    uint8_t quantizer_1st;    ///< first stage vector of quantizer
+    uint8_t quantizer_2nd_lo; ///< second stage lower vector of quantizer (size in bits)
+    uint8_t quantizer_2nd_hi; ///< second stage higher vector of quantizer (size in bits)
+
+    int pitch_delay_int[2];      // pitch delay, integer part
+    int pitch_delay_3x;          // pitch delay, multiplied by 3
+    int16_t fc[SUBFRAME_SIZE];   // fixed-codebook vector
+    int16_t synth[SUBFRAME_SIZE+10]; // fixed-codebook vector
+    int j, ret;
+    int gain_before, gain_after;
+    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) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
+    }
+    out_frame = (int16_t*) ctx->frame.data[0];
+
+    if (buf_size == 10) {
+        packet_type = FORMAT_G729_8K;
+        format = &format_g729_8k;
+        //Reset voice decision
+        ctx->onset = 0;
+        ctx->voice_decision = DECISION_VOICE;
+        av_log(avctx, AV_LOG_DEBUG, "Packet type: %s\n", "G.729 @ 8kbit/s");
+    } else if (buf_size == 8) {
+        packet_type = FORMAT_G729D_6K4;
+        format = &format_g729d_6k4;
+        av_log(avctx, AV_LOG_DEBUG, "Packet type: %s\n", "G.729D @ 6.4kbit/s");
+    } else {
+        av_log(avctx, AV_LOG_ERROR, "Packet size %d is unknown.\n", buf_size);
+        return AVERROR_INVALIDDATA;
+    }
+
+    for (i=0; i < buf_size; i++)
+        frame_erasure |= buf[i];
+    frame_erasure = !frame_erasure;
+
+    init_get_bits(&gb, buf, 8*buf_size);
+
+    ma_predictor     = get_bits(&gb, 1);
+    quantizer_1st    = get_bits(&gb, VQ_1ST_BITS);
+    quantizer_2nd_lo = get_bits(&gb, VQ_2ND_BITS);
+    quantizer_2nd_hi = get_bits(&gb, VQ_2ND_BITS);
+
+    if(frame_erasure)
+        lsf_restore_from_previous(ctx->lsfq, ctx->past_quantizer_outputs,
+                                  ctx->ma_predictor_prev);
+    else {
+        lsf_decode(ctx->lsfq, ctx->past_quantizer_outputs,
+                   ma_predictor,
+                   quantizer_1st, quantizer_2nd_lo, quantizer_2nd_hi);
+        ctx->ma_predictor_prev = ma_predictor;
+    }
+
+    tmp = ctx->past_quantizer_outputs[MA_NP];
+    memmove(ctx->past_quantizer_outputs + 1, ctx->past_quantizer_outputs,
+            MA_NP * sizeof(int16_t*));
+    ctx->past_quantizer_outputs[0] = tmp;
+
+    ff_acelp_lsf2lsp(ctx->lsp[1], ctx->lsfq, 10);
+
+    ff_acelp_lp_decode(&lp[0][0], &lp[1][0], ctx->lsp[1], ctx->lsp[0], 10);
+
+    FFSWAP(int16_t*, ctx->lsp[1], ctx->lsp[0]);
+
+    for (i = 0; i < 2; i++) {
+        int gain_corr_factor;
+
+        uint8_t ac_index;      ///< adaptive codebook index
+        uint8_t pulses_signs;  ///< fixed-codebook vector pulse signs
+        int fc_indexes;        ///< fixed-codebook indexes
+        uint8_t gc_1st_index;  ///< gain codebook (first stage) index
+        uint8_t gc_2nd_index;  ///< gain codebook (second stage) index
+
+        ac_index      = get_bits(&gb, format->ac_index_bits[i]);
+        if(!i && format->parity_bit)
+            bad_pitch = get_parity(ac_index) == get_bits1(&gb);
+        fc_indexes    = get_bits(&gb, format->fc_indexes_bits);
+        pulses_signs  = get_bits(&gb, format->fc_signs_bits);
+        gc_1st_index  = get_bits(&gb, format->gc_1st_index_bits);
+        gc_2nd_index  = get_bits(&gb, format->gc_2nd_index_bits);
+
+        if (frame_erasure)
+            pitch_delay_3x   = 3 * ctx->pitch_delay_int_prev;
+        else if(!i) {
+            if (bad_pitch)
+                pitch_delay_3x   = 3 * ctx->pitch_delay_int_prev;
+            else
+                pitch_delay_3x = ff_acelp_decode_8bit_to_1st_delay3(ac_index);
+        } else {
+            int pitch_delay_min = av_clip(ctx->pitch_delay_int_prev - 5,
+                                          PITCH_DELAY_MIN, PITCH_DELAY_MAX - 9);
+
+            if(packet_type == FORMAT_G729D_6K4)
+                pitch_delay_3x = ff_acelp_decode_4bit_to_2nd_delay3(ac_index, pitch_delay_min);
+            else
+                pitch_delay_3x = ff_acelp_decode_5_6_bit_to_2nd_delay3(ac_index, pitch_delay_min);
+        }
+
+        /* Round pitch delay to nearest (used everywhere except ff_acelp_interpolate). */
+        pitch_delay_int[i]  = (pitch_delay_3x + 1) / 3;
+
+        if (frame_erasure) {
+            ctx->rand_value = g729_prng(ctx->rand_value);
+            fc_indexes   = ctx->rand_value & ((1 << format->fc_indexes_bits) - 1);
+
+            ctx->rand_value = g729_prng(ctx->rand_value);
+            pulses_signs = ctx->rand_value;
+        }
+
+
+        memset(fc, 0, sizeof(int16_t) * SUBFRAME_SIZE);
+        switch (packet_type) {
+            case FORMAT_G729_8K:
+                ff_acelp_fc_pulse_per_track(fc, ff_fc_4pulses_8bits_tracks_13,
+                                            ff_fc_4pulses_8bits_track_4,
+                                            fc_indexes, pulses_signs, 3, 3);
+                break;
+            case FORMAT_G729D_6K4:
+                ff_acelp_fc_pulse_per_track(fc, ff_fc_2pulses_9bits_track1_gray,
+                                            ff_fc_2pulses_9bits_track2_gray,
+                                            fc_indexes, pulses_signs, 1, 4);
+                break;
+        }
+
+        /*
+          This filter enhances harmonic components of the fixed-codebook vector to
+          improve the quality of the reconstructed speech.
+
+                     / fc_v[i],                                    i < pitch_delay
+          fc_v[i] = <
+                     \ fc_v[i] + gain_pitch * fc_v[i-pitch_delay], i >= pitch_delay
+        */
+        ff_acelp_weighted_vector_sum(fc + pitch_delay_int[i],
+                                     fc + pitch_delay_int[i],
+                                     fc, 1 << 14,
+                                     av_clip(ctx->past_gain_pitch[0], SHARP_MIN, SHARP_MAX),
+                                     0, 14,
+                                     SUBFRAME_SIZE - pitch_delay_int[i]);
+
+        memmove(ctx->past_gain_pitch+1, ctx->past_gain_pitch, 5 * sizeof(int16_t));
+        ctx->past_gain_code[1] = ctx->past_gain_code[0];
+
+        if (frame_erasure) {
+            ctx->past_gain_pitch[0] = (29491 * ctx->past_gain_pitch[0]) >> 15; // 0.90 (0.15)
+            ctx->past_gain_code[0]  = ( 2007 * ctx->past_gain_code[0] ) >> 11; // 0.98 (0.11)
+
+            gain_corr_factor = 0;
+        } else {
+            if (packet_type == FORMAT_G729D_6K4) {
+                ctx->past_gain_pitch[0]  = cb_gain_1st_6k4[gc_1st_index][0] +
+                                           cb_gain_2nd_6k4[gc_2nd_index][0];
+                gain_corr_factor = cb_gain_1st_6k4[gc_1st_index][1] +
+                                   cb_gain_2nd_6k4[gc_2nd_index][1];
+
+                /* Without check below overflow can occur in ff_acelp_update_past_gain.
+                   It is not issue for G.729, because gain_corr_factor in it's case is always
+                   greater than 1024, while in G.729D it can be even zero. */
+                gain_corr_factor = FFMAX(gain_corr_factor, 1024);
+#ifndef G729_BITEXACT
+                gain_corr_factor >>= 1;
+#endif
+            } else {
+                ctx->past_gain_pitch[0]  = cb_gain_1st_8k[gc_1st_index][0] +
+                                           cb_gain_2nd_8k[gc_2nd_index][0];
+                gain_corr_factor = cb_gain_1st_8k[gc_1st_index][1] +
+                                   cb_gain_2nd_8k[gc_2nd_index][1];
+            }
+
+            /* Decode the fixed-codebook gain. */
+            ctx->past_gain_code[0] = ff_acelp_decode_gain_code(&ctx->dsp, gain_corr_factor,
+                                                               fc, MR_ENERGY,
+                                                               ctx->quant_energy,
+                                                               ma_prediction_coeff,
+                                                               SUBFRAME_SIZE, 4);
+#ifdef G729_BITEXACT
+            /*
+              This correction required to get bit-exact result with
+              reference code, because gain_corr_factor in G.729D is
+              two times larger than in original G.729.
+
+              If bit-exact result is not issue then gain_corr_factor
+              can be simpler divided by 2 before call to g729_get_gain_code
+              instead of using correction below.
+            */
+            if (packet_type == FORMAT_G729D_6K4) {
+                gain_corr_factor >>= 1;
+                ctx->past_gain_code[0] >>= 1;
+            }
+#endif
+        }
+        ff_acelp_update_past_gain(ctx->quant_energy, gain_corr_factor, 2, frame_erasure);
+
+        /* Routine requires rounding to lowest. */
+        ff_acelp_interpolate(ctx->exc + i * SUBFRAME_SIZE,
+                             ctx->exc + i * SUBFRAME_SIZE - pitch_delay_3x / 3,
+                             ff_acelp_interp_filter, 6,
+                             (pitch_delay_3x % 3) << 1,
+                             10, SUBFRAME_SIZE);
+
+        ff_acelp_weighted_vector_sum(ctx->exc + i * SUBFRAME_SIZE,
+                                     ctx->exc + i * SUBFRAME_SIZE, fc,
+                                     (!ctx->was_periodic && frame_erasure) ? 0 : ctx->past_gain_pitch[0],
+                                     ( ctx->was_periodic && frame_erasure) ? 0 : ctx->past_gain_code[0],
+                                     1 << 13, 14, SUBFRAME_SIZE);
+
+        memcpy(synth, ctx->syn_filter_data, 10 * sizeof(int16_t));
+
+        if (ff_celp_lp_synthesis_filter(
+            synth+10,
+            &lp[i][1],
+            ctx->exc  + i * SUBFRAME_SIZE,
+            SUBFRAME_SIZE,
+            10,
+            1,
+            0,
+            0x800))
+            /* Overflow occurred, downscale excitation signal... */
+            for (j = 0; j < 2 * SUBFRAME_SIZE + PITCH_DELAY_MAX + INTERPOL_LEN; j++)
+                ctx->exc_base[j] >>= 2;
+
+        /* ... and make synthesis again. */
+        if (packet_type == FORMAT_G729D_6K4) {
+            int16_t exc_new[SUBFRAME_SIZE];
+
+            ctx->onset = g729d_onset_decision(ctx->onset, ctx->past_gain_code);
+            ctx->voice_decision = g729d_voice_decision(ctx->onset, ctx->voice_decision, ctx->past_gain_pitch);
+
+            g729d_get_new_exc(exc_new, ctx->exc  + i * SUBFRAME_SIZE, fc, ctx->voice_decision, ctx->past_gain_code[0], SUBFRAME_SIZE);
+
+            ff_celp_lp_synthesis_filter(
+                    synth+10,
+                    &lp[i][1],
+                    exc_new,
+                    SUBFRAME_SIZE,
+                    10,
+                    0,
+                    0,
+                    0x800);
+        } else {
+            ff_celp_lp_synthesis_filter(
+                    synth+10,
+                    &lp[i][1],
+                    ctx->exc  + i * SUBFRAME_SIZE,
+                    SUBFRAME_SIZE,
+                    10,
+                    0,
+                    0,
+                    0x800);
+        }
+        /* Save data (without postfilter) for use in next subframe. */
+        memcpy(ctx->syn_filter_data, synth+SUBFRAME_SIZE, 10 * sizeof(int16_t));
+
+        /* Calculate gain of unfiltered signal for use in AGC. */
+        gain_before = 0;
+        for (j = 0; j < SUBFRAME_SIZE; j++)
+            gain_before += FFABS(synth[j+10]);
+
+        /* Call postfilter and also update voicing decision for use in next frame. */
+        ff_g729_postfilter(
+                &ctx->dsp,
+                &ctx->ht_prev_data,
+                &is_periodic,
+                &lp[i][0],
+                pitch_delay_int[0],
+                ctx->residual,
+                ctx->res_filter_data,
+                ctx->pos_filter_data,
+                synth+10,
+                SUBFRAME_SIZE);
+
+        /* Calculate gain of filtered signal for use in AGC. */
+        gain_after = 0;
+        for(j=0; j<SUBFRAME_SIZE; j++)
+            gain_after += FFABS(synth[j+10]);
+
+        ctx->gain_coeff = ff_g729_adaptive_gain_control(
+                gain_before,
+                gain_after,
+                synth+10,
+                SUBFRAME_SIZE,
+                ctx->gain_coeff);
+
+        if (frame_erasure)
+            ctx->pitch_delay_int_prev = FFMIN(ctx->pitch_delay_int_prev + 1, PITCH_DELAY_MAX);
+        else
+            ctx->pitch_delay_int_prev = pitch_delay_int[i];
+
+        memcpy(synth+8, ctx->hpf_z, 2*sizeof(int16_t));
+        ff_acelp_high_pass_filter(
+                out_frame + i*SUBFRAME_SIZE,
+                ctx->hpf_f,
+                synth+10,
+                SUBFRAME_SIZE);
+        memcpy(ctx->hpf_z, synth+8+SUBFRAME_SIZE, 2*sizeof(int16_t));
+    }
+
+    ctx->was_periodic = is_periodic;
+
+    /* Save signal for use in next frame. */
+    memmove(ctx->exc_base, ctx->exc_base + 2 * SUBFRAME_SIZE, (PITCH_DELAY_MAX+INTERPOL_LEN)*sizeof(int16_t));
+
+    *got_frame_ptr = 1;
+    *(AVFrame*)data = ctx->frame;
+    return buf_size;
+}
+
+AVCodec ff_g729_decoder = {
+    .name           = "g729",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_G729,
+    .priv_data_size = sizeof(G729Context),
+    .init           = decoder_init,
+    .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("G.729"),
+};
diff --git a/libavcodec/g729postfilter.c b/libavcodec/g729postfilter.c
new file mode 100644
index 0000000..fc90374
--- /dev/null
+++ b/libavcodec/g729postfilter.c
@@ -0,0 +1,610 @@
+/*
+ * G.729, G729 Annex D postfilter
+ * Copyright (c) 2008 Vladimir Voroshilov
+ *
+ * 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 <inttypes.h>
+#include <limits.h>
+
+#include "avcodec.h"
+#include "g729.h"
+#include "acelp_pitch_delay.h"
+#include "g729postfilter.h"
+#include "celp_math.h"
+#include "acelp_filters.h"
+#include "acelp_vectors.h"
+#include "celp_filters.h"
+
+#define FRAC_BITS 15
+#include "mathops.h"
+
+/**
+ * short interpolation filter (of length 33, according to spec)
+ * for computing signal with non-integer delay
+ */
+static const int16_t ff_g729_interp_filt_short[(ANALYZED_FRAC_DELAYS+1)*SHORT_INT_FILT_LEN] = {
+      0, 31650, 28469, 23705, 18050, 12266,  7041,  2873,
+      0, -1597, -2147, -1992, -1492,  -933,  -484,  -188,
+};
+
+/**
+ * long interpolation filter (of length 129, according to spec)
+ * for computing signal with non-integer delay
+ */
+static const int16_t ff_g729_interp_filt_long[(ANALYZED_FRAC_DELAYS+1)*LONG_INT_FILT_LEN] = {
+   0, 31915, 29436, 25569, 20676, 15206,  9639,  4439,
+   0, -3390, -5579, -6549, -6414, -5392, -3773, -1874,
+   0,  1595,  2727,  3303,  3319,  2850,  2030,  1023,
+   0,  -887, -1527, -1860, -1876, -1614, -1150,  -579,
+   0,   501,   859,  1041,  1044,   892,   631,   315,
+   0,  -266,  -453,  -543,  -538,  -455,  -317,  -156,
+   0,   130,   218,   258,   253,   212,   147,    72,
+   0,   -59,  -101,  -122,  -123,  -106,   -77,   -40,
+};
+
+/**
+ * formant_pp_factor_num_pow[i] = FORMANT_PP_FACTOR_NUM^(i+1)
+ */
+static const int16_t formant_pp_factor_num_pow[10]= {
+  /* (0.15) */
+  18022, 9912, 5451, 2998, 1649, 907, 499, 274, 151, 83
+};
+
+/**
+ * formant_pp_factor_den_pow[i] = FORMANT_PP_FACTOR_DEN^(i+1)
+ */
+static const int16_t formant_pp_factor_den_pow[10] = {
+  /* (0.15) */
+  22938, 16057, 11240, 7868, 5508, 3856, 2699, 1889, 1322, 925
+};
+
+/**
+ * \brief Residual signal calculation (4.2.1 if G.729)
+ * \param out [out] output data filtered through A(z/FORMANT_PP_FACTOR_NUM)
+ * \param filter_coeffs (3.12) A(z/FORMANT_PP_FACTOR_NUM) filter coefficients
+ * \param in input speech data to process
+ * \param subframe_size size of one subframe
+ *
+ * \note in buffer must contain 10 items of previous speech data before top of the buffer
+ * \remark It is safe to pass the same buffer for input and output.
+ */
+static void residual_filter(int16_t* out, const int16_t* filter_coeffs, const int16_t* in,
+                            int subframe_size)
+{
+    int i, n;
+
+    for (n = subframe_size - 1; n >= 0; n--) {
+        int sum = 0x800;
+        for (i = 0; i < 10; i++)
+            sum += filter_coeffs[i] * in[n - i - 1];
+
+        out[n] = in[n] + (sum >> 12);
+    }
+}
+
+/**
+ * \brief long-term postfilter (4.2.1)
+ * \param dsp initialized DSP context
+ * \param pitch_delay_int integer part of the pitch delay in the first subframe
+ * \param residual filtering input data
+ * \param residual_filt [out] speech signal with applied A(z/FORMANT_PP_FACTOR_NUM) filter
+ * \param subframe_size size of subframe
+ *
+ * \return 0 if long-term prediction gain is less than 3dB, 1 -  otherwise
+ */
+static int16_t long_term_filter(DSPContext *dsp, int pitch_delay_int,
+                                const int16_t* residual, int16_t *residual_filt,
+                                int subframe_size)
+{
+    int i, k, tmp, tmp2;
+    int sum;
+    int L_temp0;
+    int L_temp1;
+    int64_t L64_temp0;
+    int64_t L64_temp1;
+    int16_t shift;
+    int corr_int_num, corr_int_den;
+
+    int ener;
+    int16_t sh_ener;
+
+    int16_t gain_num,gain_den; //selected signal's gain numerator and denominator
+    int16_t sh_gain_num, sh_gain_den;
+    int gain_num_square;
+
+    int16_t gain_long_num,gain_long_den; //filtered through long interpolation filter signal's gain numerator and denominator
+    int16_t sh_gain_long_num, sh_gain_long_den;
+
+    int16_t best_delay_int, best_delay_frac;
+
+    int16_t delayed_signal_offset;
+    int lt_filt_factor_a, lt_filt_factor_b;
+
+    int16_t * selected_signal;
+    const int16_t * selected_signal_const; //Necessary to avoid compiler warning
+
+    int16_t sig_scaled[SUBFRAME_SIZE + RES_PREV_DATA_SIZE];
+    int16_t delayed_signal[ANALYZED_FRAC_DELAYS][SUBFRAME_SIZE+1];
+    int corr_den[ANALYZED_FRAC_DELAYS][2];
+
+    tmp = 0;
+    for(i=0; i<subframe_size + RES_PREV_DATA_SIZE; i++)
+        tmp |= FFABS(residual[i]);
+
+    if(!tmp)
+        shift = 3;
+    else
+        shift = av_log2(tmp) - 11;
+
+    if (shift > 0)
+        for (i = 0; i < subframe_size + RES_PREV_DATA_SIZE; i++)
+            sig_scaled[i] = residual[i] >> shift;
+    else
+        for (i = 0; i < subframe_size + RES_PREV_DATA_SIZE; i++)
+            sig_scaled[i] = residual[i] << -shift;
+
+    /* Start of best delay searching code */
+    gain_num = 0;
+
+    ener = dsp->scalarproduct_int16(sig_scaled + RES_PREV_DATA_SIZE,
+                                    sig_scaled + RES_PREV_DATA_SIZE,
+                                    subframe_size);
+    if (ener) {
+        sh_ener = FFMAX(av_log2(ener) - 14, 0);
+        ener >>= sh_ener;
+        /* Search for best pitch delay.
+
+                       sum{ r(n) * r(k,n) ] }^2
+           R'(k)^2 := -------------------------
+                       sum{ r(k,n) * r(k,n) }
+
+
+           R(T)    :=  sum{ r(n) * r(n-T) ] }
+
+
+           where
+           r(n-T) is integer delayed signal with delay T
+           r(k,n) is non-integer delayed signal with integer delay best_delay
+           and fractional delay k */
+
+        /* Find integer delay best_delay which maximizes correlation R(T).
+
+           This is also equals to numerator of R'(0),
+           since the fine search (second step) is done with 1/8
+           precision around best_delay. */
+        corr_int_num = 0;
+        best_delay_int = pitch_delay_int - 1;
+        for (i = pitch_delay_int - 1; i <= pitch_delay_int + 1; i++) {
+            sum = dsp->scalarproduct_int16(sig_scaled + RES_PREV_DATA_SIZE,
+                                           sig_scaled + RES_PREV_DATA_SIZE - i,
+                                           subframe_size);
+            if (sum > corr_int_num) {
+                corr_int_num = sum;
+                best_delay_int = i;
+            }
+        }
+        if (corr_int_num) {
+            /* Compute denominator of pseudo-normalized correlation R'(0). */
+            corr_int_den = dsp->scalarproduct_int16(sig_scaled - best_delay_int + RES_PREV_DATA_SIZE,
+                                                    sig_scaled - best_delay_int + RES_PREV_DATA_SIZE,
+                                                    subframe_size);
+
+            /* Compute signals with non-integer delay k (with 1/8 precision),
+               where k is in [0;6] range.
+               Entire delay is qual to best_delay+(k+1)/8
+               This is archieved by applying an interpolation filter of
+               legth 33 to source signal. */
+            for (k = 0; k < ANALYZED_FRAC_DELAYS; k++) {
+                ff_acelp_interpolate(&delayed_signal[k][0],
+                                     &sig_scaled[RES_PREV_DATA_SIZE - best_delay_int],
+                                     ff_g729_interp_filt_short,
+                                     ANALYZED_FRAC_DELAYS+1,
+                                     8 - k - 1,
+                                     SHORT_INT_FILT_LEN,
+                                     subframe_size + 1);
+            }
+
+            /* Compute denominator of pseudo-normalized correlation R'(k).
+
+                 corr_den[k][0] is square root of R'(k) denominator, for int(T) == int(T0)
+                 corr_den[k][1] is square root of R'(k) denominator, for int(T) == int(T0)+1
+
+              Also compute maximum value of above denominators over all k. */
+            tmp = corr_int_den;
+            for (k = 0; k < ANALYZED_FRAC_DELAYS; k++) {
+                sum = dsp->scalarproduct_int16(&delayed_signal[k][1],
+                                               &delayed_signal[k][1],
+                                               subframe_size - 1);
+                corr_den[k][0] = sum + delayed_signal[k][0            ] * delayed_signal[k][0            ];
+                corr_den[k][1] = sum + delayed_signal[k][subframe_size] * delayed_signal[k][subframe_size];
+
+                tmp = FFMAX3(tmp, corr_den[k][0], corr_den[k][1]);
+            }
+
+            sh_gain_den = av_log2(tmp) - 14;
+            if (sh_gain_den >= 0) {
+
+                sh_gain_num =  FFMAX(sh_gain_den, sh_ener);
+                /* Loop through all k and find delay that maximizes
+                   R'(k) correlation.
+                   Search is done in [int(T0)-1; intT(0)+1] range
+                   with 1/8 precision. */
+                delayed_signal_offset = 1;
+                best_delay_frac = 0;
+                gain_den = corr_int_den >> sh_gain_den;
+                gain_num = corr_int_num >> sh_gain_num;
+                gain_num_square = gain_num * gain_num;
+                for (k = 0; k < ANALYZED_FRAC_DELAYS; k++) {
+                    for (i = 0; i < 2; i++) {
+                        int16_t gain_num_short, gain_den_short;
+                        int gain_num_short_square;
+                        /* Compute numerator of pseudo-normalized
+                           correlation R'(k). */
+                        sum = dsp->scalarproduct_int16(&delayed_signal[k][i],
+                                                       sig_scaled + RES_PREV_DATA_SIZE,
+                                                       subframe_size);
+                        gain_num_short = FFMAX(sum >> sh_gain_num, 0);
+
+                        /*
+                                      gain_num_short_square                gain_num_square
+                           R'(T)^2 = -----------------------, max R'(T)^2= --------------
+                                           den                                 gain_den
+                        */
+                        gain_num_short_square = gain_num_short * gain_num_short;
+                        gain_den_short = corr_den[k][i] >> sh_gain_den;
+
+                        tmp = MULL(gain_num_short_square, gain_den, FRAC_BITS);
+                        tmp2 = MULL(gain_num_square, gain_den_short, FRAC_BITS);
+
+                        // R'(T)^2 > max R'(T)^2
+                        if (tmp > tmp2) {
+                            gain_num = gain_num_short;
+                            gain_den = gain_den_short;
+                            gain_num_square = gain_num_short_square;
+                            delayed_signal_offset = i;
+                            best_delay_frac = k + 1;
+                        }
+                    }
+                }
+
+                /*
+                       R'(T)^2
+                  2 * --------- < 1
+                        R(0)
+                */
+                L64_temp0 =  (int64_t)gain_num_square  << ((sh_gain_num << 1) + 1);
+                L64_temp1 = ((int64_t)gain_den * ener) << (sh_gain_den + sh_ener);
+                if (L64_temp0 < L64_temp1)
+                    gain_num = 0;
+            } // if(sh_gain_den >= 0)
+        } // if(corr_int_num)
+    } // if(ener)
+    /* End of best delay searching code  */
+
+    if (!gain_num) {
+        memcpy(residual_filt, residual + RES_PREV_DATA_SIZE, subframe_size * sizeof(int16_t));
+
+        /* Long-term prediction gain is less than 3dB. Long-term postfilter is disabled. */
+        return 0;
+    }
+    if (best_delay_frac) {
+        /* Recompute delayed signal with an interpolation filter of length 129. */
+        ff_acelp_interpolate(residual_filt,
+                             &sig_scaled[RES_PREV_DATA_SIZE - best_delay_int + delayed_signal_offset],
+                             ff_g729_interp_filt_long,
+                             ANALYZED_FRAC_DELAYS + 1,
+                             8 - best_delay_frac,
+                             LONG_INT_FILT_LEN,
+                             subframe_size + 1);
+        /* Compute R'(k) correlation's numerator. */
+        sum = dsp->scalarproduct_int16(residual_filt,
+                                       sig_scaled + RES_PREV_DATA_SIZE,
+                                       subframe_size);
+
+        if (sum < 0) {
+            gain_long_num = 0;
+            sh_gain_long_num = 0;
+        } else {
+            tmp = FFMAX(av_log2(sum) - 14, 0);
+            sum >>= tmp;
+            gain_long_num = sum;
+            sh_gain_long_num = tmp;
+        }
+
+        /* Compute R'(k) correlation's denominator. */
+        sum = dsp->scalarproduct_int16(residual_filt, residual_filt, subframe_size);
+
+        tmp = FFMAX(av_log2(sum) - 14, 0);
+        sum >>= tmp;
+        gain_long_den = sum;
+        sh_gain_long_den = tmp;
+
+        /* Select between original and delayed signal.
+           Delayed signal will be selected if it increases R'(k)
+           correlation. */
+        L_temp0 = gain_num * gain_num;
+        L_temp0 = MULL(L_temp0, gain_long_den, FRAC_BITS);
+
+        L_temp1 = gain_long_num * gain_long_num;
+        L_temp1 = MULL(L_temp1, gain_den, FRAC_BITS);
+
+        tmp = ((sh_gain_long_num - sh_gain_num) << 1) - (sh_gain_long_den - sh_gain_den);
+        if (tmp > 0)
+            L_temp0 >>= tmp;
+        else
+            L_temp1 >>= -tmp;
+
+        /* Check if longer filter increases the values of R'(k). */
+        if (L_temp1 > L_temp0) {
+            /* Select long filter. */
+            selected_signal = residual_filt;
+            gain_num = gain_long_num;
+            gain_den = gain_long_den;
+            sh_gain_num = sh_gain_long_num;
+            sh_gain_den = sh_gain_long_den;
+        } else
+            /* Select short filter. */
+            selected_signal = &delayed_signal[best_delay_frac-1][delayed_signal_offset];
+
+        /* Rescale selected signal to original value. */
+        if (shift > 0)
+            for (i = 0; i < subframe_size; i++)
+                selected_signal[i] <<= shift;
+        else
+            for (i = 0; i < subframe_size; i++)
+                selected_signal[i] >>= -shift;
+
+        /* necessary to avoid compiler warning */
+        selected_signal_const = selected_signal;
+    } // if(best_delay_frac)
+    else
+        selected_signal_const = residual + RES_PREV_DATA_SIZE - (best_delay_int + 1 - delayed_signal_offset);
+#ifdef G729_BITEXACT
+    tmp = sh_gain_num - sh_gain_den;
+    if (tmp > 0)
+        gain_den >>= tmp;
+    else
+        gain_num >>= -tmp;
+
+    if (gain_num > gain_den)
+        lt_filt_factor_a = MIN_LT_FILT_FACTOR_A;
+    else {
+        gain_num >>= 2;
+        gain_den >>= 1;
+        lt_filt_factor_a = (gain_den << 15) / (gain_den + gain_num);
+    }
+#else
+    L64_temp0 = ((int64_t)gain_num) << (sh_gain_num - 1);
+    L64_temp1 = ((int64_t)gain_den) << sh_gain_den;
+    lt_filt_factor_a = FFMAX((L64_temp1 << 15) / (L64_temp1 + L64_temp0), MIN_LT_FILT_FACTOR_A);
+#endif
+
+    /* Filter through selected filter. */
+    lt_filt_factor_b = 32767 - lt_filt_factor_a + 1;
+
+    ff_acelp_weighted_vector_sum(residual_filt, residual + RES_PREV_DATA_SIZE,
+                                 selected_signal_const,
+                                 lt_filt_factor_a, lt_filt_factor_b,
+                                 1<<14, 15, subframe_size);
+
+    // Long-term prediction gain is larger than 3dB.
+    return 1;
+}
+
+/**
+ * \brief Calculate reflection coefficient for tilt compensation filter (4.2.3).
+ * \param dsp initialized DSP context
+ * \param lp_gn (3.12) coefficients of A(z/FORMANT_PP_FACTOR_NUM) filter
+ * \param lp_gd (3.12) coefficients of A(z/FORMANT_PP_FACTOR_DEN) filter
+ * \param speech speech to update
+ * \param subframe_size size of subframe
+ *
+ * \return (3.12) reflection coefficient
+ *
+ * \remark The routine also calculates the gain term for the short-term
+ *         filter (gf) and multiplies the speech data by 1/gf.
+ *
+ * \note All members of lp_gn, except 10-19 must be equal to zero.
+ */
+static int16_t get_tilt_comp(DSPContext *dsp, int16_t *lp_gn,
+                             const int16_t *lp_gd, int16_t* speech,
+                             int subframe_size)
+{
+    int rh1,rh0; // (3.12)
+    int temp;
+    int i;
+    int gain_term;
+
+    lp_gn[10] = 4096; //1.0 in (3.12)
+
+    /* Apply 1/A(z/FORMANT_PP_FACTOR_DEN) filter to hf. */
+    ff_celp_lp_synthesis_filter(lp_gn + 11, lp_gd + 1, lp_gn + 11, 22, 10, 0, 0, 0x800);
+    /* Now lp_gn (starting with 10) contains impulse response
+       of A(z/FORMANT_PP_FACTOR_NUM)/A(z/FORMANT_PP_FACTOR_DEN) filter. */
+
+    rh0 = dsp->scalarproduct_int16(lp_gn + 10, lp_gn + 10, 20);
+    rh1 = dsp->scalarproduct_int16(lp_gn + 10, lp_gn + 11, 20);
+
+    /* downscale to avoid overflow */
+    temp = av_log2(rh0) - 14;
+    if (temp > 0) {
+        rh0 >>= temp;
+        rh1 >>= temp;
+    }
+
+    if (FFABS(rh1) > rh0 || !rh0)
+        return 0;
+
+    gain_term = 0;
+    for (i = 0; i < 20; i++)
+        gain_term += FFABS(lp_gn[i + 10]);
+    gain_term >>= 2; // (3.12) -> (5.10)
+
+    if (gain_term > 0x400) { // 1.0 in (5.10)
+        temp = 0x2000000 / gain_term; // 1.0/gain_term in (0.15)
+        for (i = 0; i < subframe_size; i++)
+            speech[i] = (speech[i] * temp + 0x4000) >> 15;
+    }
+
+    return -(rh1 << 15) / rh0;
+}
+
+/**
+ * \brief Apply tilt compensation filter (4.2.3).
+ * \param res_pst [in/out] residual signal (partially filtered)
+ * \param k1 (3.12) reflection coefficient
+ * \param subframe_size size of subframe
+ * \param ht_prev_data previous data for 4.2.3, equation 86
+ *
+ * \return new value for ht_prev_data
+*/
+static int16_t apply_tilt_comp(int16_t* out, int16_t* res_pst, int refl_coeff,
+                               int subframe_size, int16_t ht_prev_data)
+{
+    int tmp, tmp2;
+    int i;
+    int gt, ga;
+    int fact, sh_fact;
+
+    if (refl_coeff > 0) {
+        gt = (refl_coeff * G729_TILT_FACTOR_PLUS + 0x4000) >> 15;
+        fact = 0x4000; // 0.5 in (0.15)
+        sh_fact = 15;
+    } else {
+        gt = (refl_coeff * G729_TILT_FACTOR_MINUS + 0x4000) >> 15;
+        fact = 0x800; // 0.5 in (3.12)
+        sh_fact = 12;
+    }
+    ga = (fact << 15) / av_clip_int16(32768 - FFABS(gt));
+    gt >>= 1;
+
+    /* Apply tilt compensation filter to signal. */
+    tmp = res_pst[subframe_size - 1];
+
+    for (i = subframe_size - 1; i >= 1; i--) {
+        tmp2 = (res_pst[i] << 15) + ((gt * res_pst[i-1]) << 1);
+        tmp2 = (tmp2 + 0x4000) >> 15;
+
+        tmp2 = (tmp2 * ga * 2 + fact) >> sh_fact;
+        out[i] = tmp2;
+    }
+    tmp2 = (res_pst[0] << 15) + ((gt * ht_prev_data) << 1);
+    tmp2 = (tmp2 + 0x4000) >> 15;
+    tmp2 = (tmp2 * ga * 2 + fact) >> sh_fact;
+    out[0] = tmp2;
+
+    return tmp;
+}
+
+void ff_g729_postfilter(DSPContext *dsp, int16_t* ht_prev_data, int* voicing,
+                     const int16_t *lp_filter_coeffs, int pitch_delay_int,
+                     int16_t* residual, int16_t* res_filter_data,
+                     int16_t* pos_filter_data, int16_t *speech, int subframe_size)
+{
+    int16_t residual_filt_buf[SUBFRAME_SIZE+11];
+    int16_t lp_gn[33]; // (3.12)
+    int16_t lp_gd[11]; // (3.12)
+    int tilt_comp_coeff;
+    int i;
+
+    /* Zero-filling is necessary for tilt-compensation filter. */
+    memset(lp_gn, 0, 33 * sizeof(int16_t));
+
+    /* Calculate A(z/FORMANT_PP_FACTOR_NUM) filter coefficients. */
+    for (i = 0; i < 10; i++)
+        lp_gn[i + 11] = (lp_filter_coeffs[i + 1] * formant_pp_factor_num_pow[i] + 0x4000) >> 15;
+
+    /* Calculate A(z/FORMANT_PP_FACTOR_DEN) filter coefficients. */
+    for (i = 0; i < 10; i++)
+        lp_gd[i + 1] = (lp_filter_coeffs[i + 1] * formant_pp_factor_den_pow[i] + 0x4000) >> 15;
+
+    /* residual signal calculation (one-half of short-term postfilter) */
+    memcpy(speech - 10, res_filter_data, 10 * sizeof(int16_t));
+    residual_filter(residual + RES_PREV_DATA_SIZE, lp_gn + 11, speech, subframe_size);
+    /* Save data to use it in the next subframe. */
+    memcpy(res_filter_data, speech + subframe_size - 10, 10 * sizeof(int16_t));
+
+    /* long-term filter. If long-term prediction gain is larger than 3dB (returned value is
+       nonzero) then declare current subframe as periodic. */
+    *voicing = FFMAX(*voicing, long_term_filter(dsp, pitch_delay_int,
+                                                residual, residual_filt_buf + 10,
+                                                subframe_size));
+
+    /* shift residual for using in next subframe */
+    memmove(residual, residual + subframe_size, RES_PREV_DATA_SIZE * sizeof(int16_t));
+
+    /* short-term filter tilt compensation */
+    tilt_comp_coeff = get_tilt_comp(dsp, lp_gn, lp_gd, residual_filt_buf + 10, subframe_size);
+
+    /* Apply second half of short-term postfilter: 1/A(z/FORMANT_PP_FACTOR_DEN) */
+    ff_celp_lp_synthesis_filter(pos_filter_data + 10, lp_gd + 1,
+                                residual_filt_buf + 10,
+                                subframe_size, 10, 0, 0, 0x800);
+    memcpy(pos_filter_data, pos_filter_data + subframe_size, 10 * sizeof(int16_t));
+
+    *ht_prev_data = apply_tilt_comp(speech, pos_filter_data + 10, tilt_comp_coeff,
+                                    subframe_size, *ht_prev_data);
+}
+
+/**
+ * \brief Adaptive gain control (4.2.4)
+ * \param gain_before gain of speech before applying postfilters
+ * \param gain_after  gain of speech after applying postfilters
+ * \param speech [in/out] signal buffer
+ * \param subframe_size length of subframe
+ * \param gain_prev (3.12) previous value of gain coefficient
+ *
+ * \return (3.12) last value of gain coefficient
+ */
+int16_t ff_g729_adaptive_gain_control(int gain_before, int gain_after, int16_t *speech,
+                                   int subframe_size, int16_t gain_prev)
+{
+    int gain; // (3.12)
+    int n;
+    int exp_before, exp_after;
+
+    if(!gain_after && gain_before)
+        return 0;
+
+    if (gain_before) {
+
+        exp_before  = 14 - av_log2(gain_before);
+        gain_before = bidir_sal(gain_before, exp_before);
+
+        exp_after  = 14 - av_log2(gain_after);
+        gain_after = bidir_sal(gain_after, exp_after);
+
+        if (gain_before < gain_after) {
+            gain = (gain_before << 15) / gain_after;
+            gain = bidir_sal(gain, exp_after - exp_before - 1);
+        } else {
+            gain = ((gain_before - gain_after) << 14) / gain_after + 0x4000;
+            gain = bidir_sal(gain, exp_after - exp_before);
+        }
+        gain = (gain * G729_AGC_FAC1 + 0x4000) >> 15; // gain * (1-0.9875)
+    } else
+        gain = 0;
+
+    for (n = 0; n < subframe_size; n++) {
+        // gain_prev = gain + 0.9875 * gain_prev
+        gain_prev = (G729_AGC_FACTOR * gain_prev + 0x4000) >> 15;
+        gain_prev = av_clip_int16(gain + gain_prev);
+        speech[n] = av_clip_int16((speech[n] * gain_prev + 0x2000) >> 14);
+    }
+    return gain_prev;
+}
diff --git a/libavcodec/g729postfilter.h b/libavcodec/g729postfilter.h
new file mode 100644
index 0000000..5239fc8
--- /dev/null
+++ b/libavcodec/g729postfilter.h
@@ -0,0 +1,116 @@
+/*
+ * G.729, G729 Annex D postfilter
+ * Copyright (c) 2008 Vladimir Voroshilov
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef FFMPEG_G729POSTFILTER_H
+#define FFMPEG_G729POSTFILTER_H
+
+#include <stdint.h>
+#include "dsputil.h"
+
+/**
+ * tilt compensation factor (G.729, k1>0)
+ * 0.2 in Q15
+ */
+#define G729_TILT_FACTOR_PLUS       6554
+
+/**
+ * tilt compensation factor (G.729, k1<0)
+ * 0.9 in Q15
+ */
+#define G729_TILT_FACTOR_MINUS     29491
+
+/* 4.2.2 */
+#define FORMANT_PP_FACTOR_NUM  18022             //0.55 in Q15
+#define FORMANT_PP_FACTOR_DEN  22938             //0.70 in Q15
+
+/**
+ * gain adjustment factor (G.729, 4.2.4)
+ * 0.9875 in Q15
+ */
+#define G729_AGC_FACTOR            32358
+#define G729_AGC_FAC1 (32768-G729_AGC_FACTOR)
+
+/**
+ * 1.0 / (1.0 + 0.5) in Q15
+ * where 0.5 is the minimum value of
+ * weight factor, controlling amount of long-term postfiltering
+ */
+#define MIN_LT_FILT_FACTOR_A       21845
+
+/**
+ * Short interpolation filter length
+ */
+#define SHORT_INT_FILT_LEN         2
+
+/**
+ * Long interpolation filter length
+ */
+#define LONG_INT_FILT_LEN          8
+
+/**
+ * Number of analyzed fractional pitch delays in second stage of long-term
+ * postfilter
+ */
+#define ANALYZED_FRAC_DELAYS       7
+
+/**
+ * Amount of past residual signal data stored in buffer
+ */
+#define RES_PREV_DATA_SIZE (PITCH_DELAY_MAX + LONG_INT_FILT_LEN + 1)
+
+/**
+ * \brief Signal postfiltering (4.2)
+ * \param dsp initialized DSP context
+ * \param ht_prev_data [in/out] (Q12) pointer to variable receiving tilt
+ *                     compensation filter data from previous subframe
+ * \param voicing [in/out] (Q0) pointer to variable receiving voicing decision
+ * \param lp_filter_coeffs (Q12) LP filter coefficients
+ * \param pitch_delay_int integer part of the pitch delay
+ * \param residual [in/out] (Q0) residual signal buffer (used in long-term postfilter)
+ * \param res_filter_data [in/out] (Q0) speech data of previous subframe
+ * \param pos_filter_data [in/out] (Q0) previous speech data for short-term postfilter
+ * \param speech [in/out] (Q0) signal buffer
+ * \param subframe_size size of subframe
+ *
+ * Filtering has the following  stages:
+ *   Long-term postfilter (4.2.1)
+ *   Short-term postfilter (4.2.2).
+ *   Tilt-compensation (4.2.3)
+ */
+void ff_g729_postfilter(DSPContext *dsp, int16_t* ht_prev_data, int* voicing,
+                     const int16_t *lp_filter_coeffs, int pitch_delay_int,
+                     int16_t* residual, int16_t* res_filter_data,
+                     int16_t* pos_filter_data, int16_t *speech,
+                     int subframe_size);
+
+/**
+ * \brief Adaptive gain control (4.2.4)
+ * \param gain_before (Q0) gain of speech before applying postfilters
+ * \param gain_after  (Q0) gain of speech after applying postfilters
+ * \param speech [in/out] (Q0) signal buffer
+ * \param subframe_size length of subframe
+ * \param gain_prev (Q12) previous value of gain coefficient
+ *
+ * \return (Q12) last value of gain coefficient
+ */
+int16_t ff_g729_adaptive_gain_control(int gain_before, int gain_after, int16_t *speech,
+                                   int subframe_size, int16_t gain_prev);
+
+#endif // FFMPEG_G729POSTFILTER_H
diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h
index f91441c..a1a48ab 100644
--- a/libavcodec/get_bits.h
+++ b/libavcodec/get_bits.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,6 +30,7 @@
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/log.h"
+#include "libavutil/avassert.h"
 #include "mathops.h"
 
 /*
@@ -53,9 +54,7 @@
     const uint8_t *buffer, *buffer_end;
     int index;
     int size_in_bits;
-#if !UNCHECKED_BITSTREAM_READER
     int size_in_bits_plus8;
-#endif
 } GetBitContext;
 
 #define VLC_TYPE int16_t
@@ -123,7 +122,7 @@
 #if UNCHECKED_BITSTREAM_READER
 #define OPEN_READER(name, gb)                   \
     unsigned int name##_index = (gb)->index;    \
-    unsigned int av_unused name##_cache = 0
+    av_unused unsigned int name##_cache
 
 #define HAVE_BITS_REMAINING(name, gb) 1
 #else
@@ -224,6 +223,7 @@
 {
     register int tmp;
     OPEN_READER(re, s);
+    av_assert2(n>0 && n<=25);
     UPDATE_CACHE(re, s);
     tmp = SHOW_SBITS(re, s, n);
     LAST_SKIP_BITS(re, s, n);
@@ -238,6 +238,7 @@
 {
     register int tmp;
     OPEN_READER(re, s);
+    av_assert2(n>0 && n<=25);
     UPDATE_CACHE(re, s);
     tmp = SHOW_UBITS(re, s, n);
     LAST_SKIP_BITS(re, s, n);
@@ -252,6 +253,7 @@
 {
     register int tmp;
     OPEN_READER(re, s);
+    av_assert2(n>0 && n<=25);
     UPDATE_CACHE(re, s);
     tmp = SHOW_UBITS(re, s, n);
     return tmp;
@@ -300,20 +302,40 @@
  */
 static inline unsigned int get_bits_long(GetBitContext *s, int n)
 {
-    if (n <= MIN_CACHE_BITS)
+    if (!n) {
+        return 0;
+    } else if (n <= MIN_CACHE_BITS)
         return get_bits(s, n);
     else {
 #ifdef BITSTREAM_READER_LE
-        int ret = get_bits(s, 16);
+        unsigned ret = get_bits(s, 16);
         return ret | (get_bits(s, n-16) << 16);
 #else
-        int ret = get_bits(s, 16) << (n-16);
+        unsigned ret = get_bits(s, 16) << (n-16);
         return ret | get_bits(s, n-16);
 #endif
     }
 }
 
 /**
+ * Read 0-64 bits.
+ */
+static inline uint64_t get_bits_longlong(GetBitContext *s, int n)
+{
+    if (n <= 32)
+        return get_bits_long(s, n);
+    else {
+#ifdef BITSTREAM_READER_LE
+        uint64_t ret = get_bits_long(s, 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);
+#endif
+    }
+}
+
+/**
  * Read 0-32 bits as a signed integer.
  */
 static inline int get_sbits_long(GetBitContext *s, int n)
@@ -360,9 +382,7 @@
 
     s->buffer       = buffer;
     s->size_in_bits = bit_size;
-#if !UNCHECKED_BITSTREAM_READER
     s->size_in_bits_plus8 = bit_size + 8;
-#endif
     s->buffer_end   = buffer + buffer_size;
     s->index        = 0;
 }
diff --git a/libavcodec/gif.c b/libavcodec/gif.c
index af57fff..1ae4661 100644
--- a/libavcodec/gif.c
+++ b/libavcodec/gif.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2002 Francois Revol
  * Copyright (c) 2006 Baptiste Coudurier
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -63,7 +63,7 @@
                                   uint8_t **bytestream, uint32_t *palette)
 {
     int i;
-    unsigned int v;
+    unsigned int v, smallest_alpha = 0xFF, alpha_component = 0;
 
     bytestream_put_buffer(bytestream, "GIF", 3);
     bytestream_put_buffer(bytestream, "89a", 3);
@@ -78,6 +78,20 @@
     for(i=0;i<256;i++) {
         v = palette[i];
         bytestream_put_be24(bytestream, v);
+        if (v >> 24 < smallest_alpha) {
+            smallest_alpha = v >> 24;
+            alpha_component = i;
+        }
+    }
+
+    if (smallest_alpha < 128) {
+        bytestream_put_byte(bytestream, 0x21); /* Extension Introducer */
+        bytestream_put_byte(bytestream, 0xf9); /* Graphic Control Label */
+        bytestream_put_byte(bytestream, 0x04); /* block length */
+        bytestream_put_byte(bytestream, 0x01); /* Transparent Color Flag */
+        bytestream_put_le16(bytestream, 0x00); /* no delay */
+        bytestream_put_byte(bytestream, alpha_component);
+        bytestream_put_byte(bytestream, 0x00);
     }
 
     return 0;
@@ -131,6 +145,11 @@
 {
     GIFContext *s = avctx->priv_data;
 
+    if (avctx->width > 65535 || avctx->height > 65535) {
+        av_log(avctx, AV_LOG_ERROR, "GIF does not support resolutions above 65535x65535\n");
+        return -1;
+    }
+
     avctx->coded_frame = &s->picture;
     s->lzw = av_mallocz(ff_lzw_encode_state_size);
     if (!s->lzw)
@@ -150,10 +169,8 @@
     uint8_t *outbuf_ptr, *end;
     int ret;
 
-    if ((ret = ff_alloc_packet(pkt, avctx->width*avctx->height*7/5 + FF_MIN_BUFFER_SIZE)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*7/5 + FF_MIN_BUFFER_SIZE)) < 0)
         return ret;
-    }
     outbuf_ptr = pkt->data;
     end        = pkt->data + pkt->size;
 
diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c
index 4bb7789..3e7799f 100644
--- a/libavcodec/gifdec.c
+++ b/libavcodec/gifdec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2006 Baptiste Coudurier
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -56,7 +56,7 @@
     uint8_t global_palette[256 * 3];
     uint8_t local_palette[256 * 3];
 
-  AVCodecContext* avctx;
+    AVCodecContext *avctx;
 } GifState;
 
 static const uint8_t gif87a_sig[6] = "GIF87a";
@@ -77,7 +77,7 @@
     has_local_palette = flags & 0x80;
     bits_per_pixel = (flags & 0x07) + 1;
 
-    av_dlog(s->avctx, "gif: image x=%d y=%d w=%d h=%d\n", left, top, width, height);
+    av_dlog(s->avctx, "image x=%d y=%d w=%d h=%d\n", left, top, width, height);
 
     if (has_local_palette) {
         bytestream_get_buffer(&s->bytestream, s->local_palette, 3 * (1 << bits_per_pixel));
@@ -163,7 +163,7 @@
     ext_code = bytestream_get_byte(&s->bytestream);
     ext_len = bytestream_get_byte(&s->bytestream);
 
-    av_dlog(s->avctx, "gif: ext_code=0x%x len=%d\n", ext_code, ext_len);
+    av_dlog(s->avctx, "ext_code=0x%x len=%d\n", ext_code, ext_len);
 
     switch(ext_code) {
     case 0xf9:
@@ -179,7 +179,7 @@
             s->transparent_color_index = -1;
         s->gce_disposal = (gce_flags >> 2) & 0x7;
 
-        av_dlog(s->avctx, "gif: gce_flags=%x delay=%d tcolor=%d disposal=%d\n",
+        av_dlog(s->avctx, "gce_flags=%x delay=%d tcolor=%d disposal=%d\n",
                gce_flags, s->gce_delay,
                s->transparent_color_index, s->gce_disposal);
 
@@ -194,7 +194,7 @@
             bytestream_get_byte(&s->bytestream);
         ext_len = bytestream_get_byte(&s->bytestream);
 
-        av_dlog(s->avctx, "gif: ext_len1=%d\n", ext_len);
+        av_dlog(s->avctx, "ext_len1=%d\n", ext_len);
     }
     return 0;
 }
@@ -206,13 +206,13 @@
     int has_global_palette;
 
     if (s->bytestream_end < s->bytestream + 13)
-        return -1;
+        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)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     /* read screen header */
     s->transparent_color_index = -1;
@@ -220,8 +220,8 @@
     s->screen_height = bytestream_get_le16(&s->bytestream);
     if(   (unsigned)s->screen_width  > 32767
        || (unsigned)s->screen_height > 32767){
-        av_log(NULL, AV_LOG_ERROR, "picture size too large\n");
-        return -1;
+        av_log(s->avctx, AV_LOG_ERROR, "picture size too large\n");
+        return AVERROR_INVALIDDATA;
     }
 
     v = bytestream_get_byte(&s->bytestream);
@@ -231,14 +231,14 @@
     s->background_color_index = bytestream_get_byte(&s->bytestream);
     bytestream_get_byte(&s->bytestream);                /* ignored */
 
-    av_dlog(s->avctx, "gif: screen_w=%d screen_h=%d bpp=%d global_palette=%d\n",
+    av_dlog(s->avctx, "screen_w=%d screen_h=%d bpp=%d global_palette=%d\n",
            s->screen_width, s->screen_height, s->bits_per_pixel,
            has_global_palette);
 
     if (has_global_palette) {
         n = 1 << s->bits_per_pixel;
         if (s->bytestream_end < s->bytestream + n * 3)
-            return -1;
+            return AVERROR_INVALIDDATA;
         bytestream_get_buffer(&s->bytestream, s->global_palette, n * 3);
     }
     return 0;
@@ -249,7 +249,7 @@
     while (s->bytestream < s->bytestream_end) {
         int code = bytestream_get_byte(&s->bytestream);
 
-        av_dlog(s->avctx, "gif: code=%02x '%c'\n", code, code);
+        av_dlog(s->avctx, "code=%02x '%c'\n", code, code);
 
         switch (code) {
         case ',':
@@ -291,8 +291,8 @@
 
     s->bytestream = buf;
     s->bytestream_end = buf + buf_size;
-    if (gif_read_header1(s) < 0)
-        return -1;
+    if ((ret = gif_read_header1(s)) < 0)
+        return ret;
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
     if (av_image_check_size(s->screen_width, s->screen_height, 0, avctx))
@@ -301,9 +301,9 @@
 
     if (s->picture.data[0])
         avctx->release_buffer(avctx, &s->picture);
-    if (avctx->get_buffer(avctx, &s->picture) < 0) {
+    if ((ret = avctx->get_buffer(avctx, &s->picture)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return -1;
+        return ret;
     }
     s->image_palette = (uint32_t *)s->picture.data[1];
     ret = gif_parse_next_image(s);
diff --git a/libavcodec/golomb-test.c b/libavcodec/golomb-test.c
index bc90f36..54644ad 100644
--- a/libavcodec/golomb-test.c
+++ b/libavcodec/golomb-test.c
@@ -1,18 +1,20 @@
 /*
- * This file is part of Libav.
+ * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/golomb.c b/libavcodec/golomb.c
index 550c41e..937ac22 100644
--- a/libavcodec/golomb.c
+++ b/libavcodec/golomb.c
@@ -2,20 +2,20 @@
  * exp golomb vlc stuff
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h
index 6f95a67..0ce1b34 100644
--- a/libavcodec/golomb.h
+++ b/libavcodec/golomb.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2004 Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -135,7 +135,7 @@
             ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf];
             UPDATE_CACHE(re, gb);
             buf = GET_CACHE(re, gb);
-        } while (HAVE_BITS_REMAINING(re, gb));
+        } while (ret<0x8000000U && HAVE_BITS_REMAINING(re, gb));
 
         CLOSE_READER(re, gb);
         return ret - 1;
@@ -146,7 +146,7 @@
  * read unsigned truncated exp golomb code.
  */
 static inline int get_te0_golomb(GetBitContext *gb, int range){
-    assert(range >= 1);
+    av_assert2(range >= 1);
 
     if(range==1)      return 0;
     else if(range==2) return get_bits1(gb)^1;
@@ -157,7 +157,7 @@
  * read unsigned truncated exp golomb code.
  */
 static inline int get_te_golomb(GetBitContext *gb, int range){
-    assert(range >= 1);
+    av_assert2(range >= 1);
 
     if(range==2) return get_bits1(gb)^1;
     else         return get_ue_golomb(gb);
@@ -301,7 +301,9 @@
         return buf;
     }else{
         int i;
-        for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0 && HAVE_BITS_REMAINING(re, gb); i++) {
+        for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0; i++) {
+            if (gb->size_in_bits <= re_index)
+                return -1;
             LAST_SKIP_BITS(re, gb, 1);
             UPDATE_CACHE(re, gb);
         }
@@ -431,7 +433,7 @@
 static inline void set_ue_golomb(PutBitContext *pb, int i){
     int e;
 
-    assert(i>=0);
+    av_assert2(i>=0);
 
 #if 0
     if(i=0){
@@ -452,8 +454,8 @@
  * write truncated unsigned exp golomb code.
  */
 static inline void set_te_golomb(PutBitContext *pb, int i, int range){
-    assert(range >= 1);
-    assert(i<=range);
+    av_assert2(range >= 1);
+    av_assert2(i<=range);
 
     if(range==2) put_bits(pb, 1, i^1);
     else         set_ue_golomb(pb, i);
@@ -482,7 +484,7 @@
 static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){
     int e;
 
-    assert(i>=0);
+    av_assert2(i>=0);
 
     e= i>>k;
     if(e<limit){
@@ -498,7 +500,7 @@
 static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k, int limit, int esc_len){
     int e;
 
-    assert(i>=0);
+    av_assert2(i>=0);
 
     e= (i>>k) + 1;
     if(e<limit){
diff --git a/libavcodec/gsm.h b/libavcodec/gsm.h
index c7c3e22..e56f4cd 100644
--- a/libavcodec/gsm.h
+++ b/libavcodec/gsm.h
@@ -1,20 +1,20 @@
 /*
  * GSM common header
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/gsmdec.c b/libavcodec/gsmdec.c
index a5e0d7d..fc042fb 100644
--- a/libavcodec/gsmdec.c
+++ b/libavcodec/gsmdec.c
@@ -2,20 +2,20 @@
  * gsm 06.10 decoder
  * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -105,6 +105,7 @@
     memset(s, 0, sizeof(*s));
 }
 
+#if CONFIG_GSM_DECODER
 AVCodec ff_gsm_decoder = {
     .name           = "gsm",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -116,7 +117,8 @@
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("GSM"),
 };
-
+#endif
+#if CONFIG_GSM_MS_DECODER
 AVCodec ff_gsm_ms_decoder = {
     .name           = "gsm_ms",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -128,3 +130,4 @@
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("GSM Microsoft variant"),
 };
+#endif
diff --git a/libavcodec/gsmdec_data.c b/libavcodec/gsmdec_data.c
index 8b75bb6..4324ea2 100644
--- a/libavcodec/gsmdec_data.c
+++ b/libavcodec/gsmdec_data.c
@@ -2,20 +2,20 @@
  * gsm 06.10 decoder data
  * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/gsmdec_data.h b/libavcodec/gsmdec_data.h
index 61715c8..6abe2b4 100644
--- a/libavcodec/gsmdec_data.h
+++ b/libavcodec/gsmdec_data.h
@@ -2,20 +2,20 @@
  * gsm 06.10 decoder data
  * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/gsmdec_template.c b/libavcodec/gsmdec_template.c
index b5222af..0f55953 100644
--- a/libavcodec/gsmdec_template.c
+++ b/libavcodec/gsmdec_template.c
@@ -2,20 +2,20 @@
  * gsm 06.10 decoder
  * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/h261.c b/libavcodec/h261.c
index 9555613..951997d 100644
--- a/libavcodec/h261.c
+++ b/libavcodec/h261.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2004 Maarten Daniels
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/h261.h b/libavcodec/h261.h
index 6461329..5b60dd6 100644
--- a/libavcodec/h261.h
+++ b/libavcodec/h261.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2004 Maarten Daniels
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/h261_parser.c b/libavcodec/h261_parser.c
index 8a507ee..753687a 100644
--- a/libavcodec/h261_parser.c
+++ b/libavcodec/h261_parser.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2004 Maarten Daniels
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -70,11 +70,15 @@
     ParseContext *pc = s->priv_data;
     int next;
 
-    next= h261_find_frame_end(pc,avctx, buf, buf_size);
-    if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
-        *poutbuf = NULL;
-        *poutbuf_size = 0;
-        return buf_size;
+    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
+        next = buf_size;
+    } else {
+        next= h261_find_frame_end(pc,avctx, buf, buf_size);
+        if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
+            *poutbuf = NULL;
+            *poutbuf_size = 0;
+            return buf_size;
+        }
     }
     *poutbuf = buf;
     *poutbuf_size = buf_size;
diff --git a/libavcodec/h261data.c b/libavcodec/h261data.c
new file mode 100644
index 0000000..a05161f
--- /dev/null
+++ b/libavcodec/h261data.c
@@ -0,0 +1,155 @@
+/*
+ * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
+ * copyright (c) 2004 Maarten Daniels
+ *
+ * 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.261 tables.
+ */
+
+#include <stdint.h>
+#include "h261.h"
+#include "h261data.h"
+
+// H.261 VLC table for macroblock addressing
+const uint8_t ff_h261_mba_code[35] = {
+     1,  3,  2,  3,
+     2,  3,  2,  7,
+     6, 11, 10,  9,
+     8,  7,  6, 23,
+    22, 21, 20, 19,
+    18, 35, 34, 33,
+    32, 31, 30, 29,
+    28, 27, 26, 25,
+    24,
+    15,           //(MBA stuffing)
+    1             //(start code)
+};
+
+const uint8_t ff_h261_mba_bits[35] = {
+     1,  3,  3,  4,
+     4,  5,  5,  7,
+     7,  8,  8,  8,
+     8,  8,  8, 10,
+    10, 10, 10, 10,
+    10, 11, 11, 11,
+    11, 11, 11, 11,
+    11, 11, 11, 11,
+    11,
+    11,           //(MBA stuffing)
+    16            //(start code)
+};
+
+//H.261 VLC table for macroblock type
+const uint8_t ff_h261_mtype_code[10] = {
+    1,  1,  1,  1,
+    1,  1,  1,  1,
+    1,  1
+};
+
+const uint8_t ff_h261_mtype_bits[10] = {
+    4,  7,  1,  5,
+    9,  8, 10,  3,
+    2,  6
+};
+
+const int ff_h261_mtype_map[10]= {
+        MB_TYPE_INTRA4x4,
+        MB_TYPE_INTRA4x4  |  MB_TYPE_QUANT,
+                                               MB_TYPE_CBP,
+                             MB_TYPE_QUANT  |  MB_TYPE_CBP,
+                                                               MB_TYPE_16x16,
+                                               MB_TYPE_CBP  |  MB_TYPE_16x16,
+                             MB_TYPE_QUANT  |  MB_TYPE_CBP  |  MB_TYPE_16x16,
+                                                               MB_TYPE_16x16  |  MB_TYPE_H261_FIL,
+                                               MB_TYPE_CBP  |  MB_TYPE_16x16  |  MB_TYPE_H261_FIL,
+                             MB_TYPE_QUANT  |  MB_TYPE_CBP  |  MB_TYPE_16x16  |  MB_TYPE_H261_FIL
+};
+
+//H.261 VLC table for motion vectors
+const uint8_t ff_h261_mv_tab[17][2] = {
+    {1,1}, {1,2}, {1,3}, {1,4}, {3,6}, {5,7}, {4,7}, {3,7},
+    {11,9}, {10,9}, {9,9}, {17,10}, {16,10}, {15,10}, {14,10}, {13,10}, {12,10}
+};
+
+//H.261 VLC table for coded block pattern
+const uint8_t ff_h261_cbp_tab[63][2] =
+{
+    {11,5}, {9,5}, {13,6}, {13,4}, {23,7}, {19,7}, {31,8}, {12,4},
+    {22,7}, {18,7}, {30,8}, {19,5}, {27,8}, {23,8}, {19,8}, {11,4},
+    {21,7}, {17,7}, {29,8}, {17,5}, {25,8}, {21,8}, {17,8}, {15,6},
+    {15,8}, {13,8}, {3,9}, {15,5}, {11,8}, {7,8}, {7,9}, {10,4},
+    {20,7}, {16,7}, {28,8}, {14,6}, {14,8}, {12,8}, {2,9}, {16,5},
+    {24,8}, {20,8}, {16,8}, {14,5}, {10,8}, {6,8}, {6,9}, {18,5},
+    {26,8}, {22,8}, {18,8}, {13,5}, {9,8}, {5,8}, {5,9}, {12,5},
+    {8,8}, {4,8}, {4,9}, {7,3}, {10,5}, {8,5}, {12,6}
+};
+
+//H.261 VLC table for transform coefficients
+static const uint16_t h261_tcoeff_vlc[65][2] = {
+{ 0x2, 2 }, { 0x3, 2 },{ 0x4, 4 },{ 0x5, 5 },
+{ 0x6, 7 },{ 0x26, 8 },{ 0x21, 8 },{ 0xa, 10 },
+{ 0x1d, 12 },{ 0x18, 12 },{ 0x13, 12 },{ 0x10 , 12 },
+{ 0x1a, 13},{ 0x19, 13 }, { 0x18, 13 }, { 0x17, 13 },
+{ 0x3, 3 }, { 0x6, 6 }, { 0x25 , 8 }, { 0xc, 10 },
+{ 0x1b, 12 }, { 0x16, 13 }, { 0x15, 13 }, { 0x5, 4},
+{ 0x4, 7}, { 0xb, 10 }, { 0x14, 12 }, { 0x14, 13 },
+{ 0x7, 5 }, { 0x24, 8 }, { 0x1c, 12 }, { 0x13, 13 },
+{ 0x6, 5 }, { 0xf, 10 }, { 0x12, 12}, { 0x7, 6},
+{ 0x9 , 10 }, { 0x12, 13 }, { 0x5, 6 }, { 0x1e, 12 },
+{ 0x4, 6 }, { 0x15, 12 }, { 0x7, 7 }, { 0x11, 12},
+{ 0x5, 7 }, { 0x11, 13 }, { 0x27, 8 }, { 0x10, 13 },
+{ 0x23, 8 }, { 0x22, 8 }, { 0x20, 8 }, { 0xe , 10 },
+{ 0xd, 10 }, { 0x8, 10 },{ 0x1f, 12 }, { 0x1a, 12 },
+{ 0x19, 12 }, { 0x17, 12 }, { 0x16, 12}, { 0x1f, 13},
+{ 0x1e, 13 }, { 0x1d, 13 }, { 0x1c, 13}, { 0x1b, 13},
+{ 0x1, 6 }                                             //escape
+};
+
+static const int8_t h261_tcoeff_level[64] = {
+    0,  1,  2,  3,  4,  5,  6,  7,
+    8,  9, 10, 11, 12, 13, 14, 15,
+    1,  2,  3,  4,  5,  6,  7,  1,
+    2,  3,  4,  5,  1,  2,  3,  4,
+    1,  2,  3,  1,  2,  3,  1,  2,
+    1,  2,  1,  2,  1,  2,  1,  2,
+    1,  1,  1,  1,  1,  1,  1,  1,
+    1,  1,  1,  1,  1,  1,  1,  1
+};
+
+static const int8_t h261_tcoeff_run[64] = {
+    0,
+    0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  1,
+    1,  1,  1,  1,  1,  1,  2,  2,
+    2,  2,  2,  3,  3,  3,  3,  4,
+    4,  4,  5,  5,  5,  6,  6,  7,
+    7,  8,  8,  9,  9, 10, 10, 11,
+   12, 13, 14, 15, 16, 17, 18, 19,
+   20, 21, 22, 23, 24, 25, 26
+};
+
+RLTable ff_h261_rl_tcoeff = {
+    64,
+    64,
+    h261_tcoeff_vlc,
+    h261_tcoeff_run,
+    h261_tcoeff_level,
+};
diff --git a/libavcodec/h261data.h b/libavcodec/h261data.h
index 2c61015..e9e5244 100644
--- a/libavcodec/h261data.h
+++ b/libavcodec/h261data.h
@@ -2,20 +2,20 @@
  * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  * copyright (c) 2004 Maarten Daniels
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,135 +30,13 @@
 #include <stdint.h>
 #include "h261.h"
 
-// H.261 VLC table for macroblock addressing
-static const uint8_t h261_mba_code[35] = {
-     1,  3,  2,  3,
-     2,  3,  2,  7,
-     6, 11, 10,  9,
-     8,  7,  6, 23,
-    22, 21, 20, 19,
-    18, 35, 34, 33,
-    32, 31, 30, 29,
-    28, 27, 26, 25,
-    24,
-    15,           //(MBA stuffing)
-    1             //(start code)
-};
-
-static const uint8_t h261_mba_bits[35] = {
-     1,  3,  3,  4,
-     4,  5,  5,  7,
-     7,  8,  8,  8,
-     8,  8,  8, 10,
-    10, 10, 10, 10,
-    10, 11, 11, 11,
-    11, 11, 11, 11,
-    11, 11, 11, 11,
-    11,
-    11,           //(MBA stuffing)
-    16            //(start code)
-};
-
-//H.261 VLC table for macroblock type
-static const uint8_t h261_mtype_code[10] = {
-    1,  1,  1,  1,
-    1,  1,  1,  1,
-    1,  1
-};
-
-static const uint8_t h261_mtype_bits[10] = {
-    4,  7,  1,  5,
-    9,  8, 10,  3,
-    2,  6
-};
-
-static const int h261_mtype_map[10]= {
-        MB_TYPE_INTRA4x4,
-        MB_TYPE_INTRA4x4  |  MB_TYPE_QUANT,
-                                               MB_TYPE_CBP,
-                             MB_TYPE_QUANT  |  MB_TYPE_CBP,
-                                                               MB_TYPE_16x16,
-                                               MB_TYPE_CBP  |  MB_TYPE_16x16,
-                             MB_TYPE_QUANT  |  MB_TYPE_CBP  |  MB_TYPE_16x16,
-                                                               MB_TYPE_16x16  |  MB_TYPE_H261_FIL,
-                                               MB_TYPE_CBP  |  MB_TYPE_16x16  |  MB_TYPE_H261_FIL,
-                             MB_TYPE_QUANT  |  MB_TYPE_CBP  |  MB_TYPE_16x16  |  MB_TYPE_H261_FIL
-};
-
-//H.261 VLC table for motion vectors
-static const uint8_t h261_mv_tab[17][2] = {
-    {1,1}, {1,2}, {1,3}, {1,4}, {3,6}, {5,7}, {4,7}, {3,7},
-    {11,9}, {10,9}, {9,9}, {17,10}, {16,10}, {15,10}, {14,10}, {13,10}, {12,10}
-};
-
-static const int mvmap[17] =
-{
-    0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16
-};
-
-//H.261 VLC table for coded block pattern
-static const uint8_t h261_cbp_tab[63][2] =
-{
-    {11,5}, {9,5}, {13,6}, {13,4}, {23,7}, {19,7}, {31,8}, {12,4},
-    {22,7}, {18,7}, {30,8}, {19,5}, {27,8}, {23,8}, {19,8}, {11,4},
-    {21,7}, {17,7}, {29,8}, {17,5}, {25,8}, {21,8}, {17,8}, {15,6},
-    {15,8}, {13,8}, {3,9}, {15,5}, {11,8}, {7,8}, {7,9}, {10,4},
-    {20,7}, {16,7}, {28,8}, {14,6}, {14,8}, {12,8}, {2,9}, {16,5},
-    {24,8}, {20,8}, {16,8}, {14,5}, {10,8}, {6,8}, {6,9}, {18,5},
-    {26,8}, {22,8}, {18,8}, {13,5}, {9,8}, {5,8}, {5,9}, {12,5},
-    {8,8}, {4,8}, {4,9}, {7,3}, {10,5}, {8,5}, {12,6}
-};
-
-//H.261 VLC table for transform coefficients
-static const uint16_t h261_tcoeff_vlc[65][2] = {
-{ 0x2, 2 }, { 0x3, 2 },{ 0x4, 4 },{ 0x5, 5 },
-{ 0x6, 7 },{ 0x26, 8 },{ 0x21, 8 },{ 0xa, 10 },
-{ 0x1d, 12 },{ 0x18, 12 },{ 0x13, 12 },{ 0x10 , 12 },
-{ 0x1a, 13},{ 0x19, 13 }, { 0x18, 13 }, { 0x17, 13 },
-{ 0x3, 3 }, { 0x6, 6 }, { 0x25 , 8 }, { 0xc, 10 },
-{ 0x1b, 12 }, { 0x16, 13 }, { 0x15, 13 }, { 0x5, 4},
-{ 0x4, 7}, { 0xb, 10 }, { 0x14, 12 }, { 0x14, 13 },
-{ 0x7, 5 }, { 0x24, 8 }, { 0x1c, 12 }, { 0x13, 13 },
-{ 0x6, 5 }, { 0xf, 10 }, { 0x12, 12}, { 0x7, 6},
-{ 0x9 , 10 }, { 0x12, 13 }, { 0x5, 6 }, { 0x1e, 12 },
-{ 0x4, 6 }, { 0x15, 12 }, { 0x7, 7 }, { 0x11, 12},
-{ 0x5, 7 }, { 0x11, 13 }, { 0x27, 8 }, { 0x10, 13 },
-{ 0x23, 8 }, { 0x22, 8 }, { 0x20, 8 }, { 0xe , 10 },
-{ 0xd, 10 }, { 0x8, 10 },{ 0x1f, 12 }, { 0x1a, 12 },
-{ 0x19, 12 }, { 0x17, 12 }, { 0x16, 12}, { 0x1f, 13},
-{ 0x1e, 13 }, { 0x1d, 13 }, { 0x1c, 13}, { 0x1b, 13},
-{ 0x1, 6 }                                             //escape
-};
-
-static const int8_t h261_tcoeff_level[64] = {
-    0,  1,  2,  3,  4,  5,  6,  7,
-    8,  9, 10, 11, 12, 13, 14, 15,
-    1,  2,  3,  4,  5,  6,  7,  1,
-    2,  3,  4,  5,  1,  2,  3,  4,
-    1,  2,  3,  1,  2,  3,  1,  2,
-    1,  2,  1,  2,  1,  2,  1,  2,
-    1,  1,  1,  1,  1,  1,  1,  1,
-    1,  1,  1,  1,  1,  1,  1,  1
-};
-
-static const int8_t h261_tcoeff_run[64] = {
-    0,
-    0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  1,
-    1,  1,  1,  1,  1,  1,  2,  2,
-    2,  2,  2,  3,  3,  3,  3,  4,
-    4,  4,  5,  5,  5,  6,  6,  7,
-    7,  8,  8,  9,  9, 10, 10, 11,
-   12, 13, 14, 15, 16, 17, 18, 19,
-   20, 21, 22, 23, 24, 25, 26
-};
-
-static RLTable h261_rl_tcoeff = {
-    64,
-    64,
-    h261_tcoeff_vlc,
-    h261_tcoeff_run,
-    h261_tcoeff_level,
-};
+extern const uint8_t ff_h261_mba_code[35];
+extern const uint8_t ff_h261_mba_bits[35];
+extern const uint8_t ff_h261_mtype_code[10];
+extern const uint8_t ff_h261_mtype_bits[10];
+extern const int ff_h261_mtype_map[10];
+extern const uint8_t ff_h261_mv_tab[17][2];
+extern const uint8_t ff_h261_cbp_tab[63][2];
+extern RLTable ff_h261_rl_tcoeff;
 
 #endif /* AVCODEC_H261DATA_H */
diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c
index 7780888..9bd6b20 100644
--- a/libavcodec/h261dec.c
+++ b/libavcodec/h261dec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2004 Maarten Daniels
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,7 @@
  * H.261 decoder.
  */
 
+#include "libavutil/avassert.h"
 #include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
@@ -55,19 +56,19 @@
     if(!done){
         done = 1;
         INIT_VLC_STATIC(&h261_mba_vlc, H261_MBA_VLC_BITS, 35,
-                 h261_mba_bits, 1, 1,
-                 h261_mba_code, 1, 1, 662);
+                 ff_h261_mba_bits, 1, 1,
+                 ff_h261_mba_code, 1, 1, 662);
         INIT_VLC_STATIC(&h261_mtype_vlc, H261_MTYPE_VLC_BITS, 10,
-                 h261_mtype_bits, 1, 1,
-                 h261_mtype_code, 1, 1, 80);
+                 ff_h261_mtype_bits, 1, 1,
+                 ff_h261_mtype_code, 1, 1, 80);
         INIT_VLC_STATIC(&h261_mv_vlc, H261_MV_VLC_BITS, 17,
-                 &h261_mv_tab[0][1], 2, 1,
-                 &h261_mv_tab[0][0], 2, 1, 144);
+                 &ff_h261_mv_tab[0][1], 2, 1,
+                 &ff_h261_mv_tab[0][0], 2, 1, 144);
         INIT_VLC_STATIC(&h261_cbp_vlc, H261_CBP_VLC_BITS, 63,
-                 &h261_cbp_tab[0][1], 2, 1,
-                 &h261_cbp_tab[0][0], 2, 1, 512);
-        ff_init_rl(&h261_rl_tcoeff, ff_h261_rl_table_store);
-        INIT_VLC_RL(h261_rl_tcoeff, 552);
+                 &ff_h261_cbp_tab[0][1], 2, 1,
+                 &ff_h261_cbp_tab[0][0], 2, 1, 512);
+        ff_init_rl(&ff_h261_rl_tcoeff, ff_h261_rl_table_store);
+        INIT_VLC_RL(ff_h261_rl_tcoeff, 552);
     }
 }
 
@@ -136,7 +137,7 @@
 
     if(s->qscale==0) {
         av_log(s->avctx, AV_LOG_ERROR, "qscale has forbidden 0 value\n");
-        if (s->avctx->err_recognition & AV_EF_BITSTREAM)
+        if (s->avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT))
             return -1;
     }
 
@@ -228,6 +229,9 @@
 }
 
 static int decode_mv_component(GetBitContext *gb, int v){
+    static const int mvmap[17] = {
+        0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16
+    };
     int mv_diff = get_vlc2(gb, h261_mv_vlc.table, H261_MV_VLC_BITS, 2);
 
     /* check if mv_diff is valid */
@@ -286,7 +290,11 @@
 
     // Read mtype
     h->mtype = get_vlc2(&s->gb, h261_mtype_vlc.table, H261_MTYPE_VLC_BITS, 2);
-    h->mtype = h261_mtype_map[h->mtype];
+    if (h->mtype < 0) {
+        av_log(s->avctx, AV_LOG_ERROR, "illegal mtype %d\n", h->mtype);
+        return SLICE_ERROR;
+    }
+    h->mtype = ff_h261_mtype_map[h->mtype];
 
     // Read mquant
     if ( IS_QUANT ( h->mtype ) ){
@@ -363,7 +371,7 @@
 {
     MpegEncContext * const s = &h->s;
     int code, level, i, j, run;
-    RLTable *rl = &h261_rl_tcoeff;
+    RLTable *rl = &ff_h261_rl_tcoeff;
     const uint8_t *scan_table;
 
     // For the variable length encoding there are two code tables, one being used for
@@ -622,8 +630,8 @@
     }
     ff_MPV_frame_end(s);
 
-assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type);
-assert(s->current_picture.f.pict_type == s->pict_type);
+    av_assert0(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type);
+    av_assert0(s->current_picture.f.pict_type == s->pict_type);
 
     *pict = s->current_picture_ptr->f;
     ff_print_debug_info(s, pict);
@@ -651,5 +659,6 @@
     .close          = h261_decode_end,
     .decode         = h261_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
+    .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("H.261"),
 };
diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c
index d6b4cfc..29bee5d 100644
--- a/libavcodec/h261enc.c
+++ b/libavcodec/h261enc.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2004 Maarten Daniels
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,7 @@
  * H.261 encoder.
  */
 
+#include "libavutil/avassert.h"
 #include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
@@ -128,7 +129,7 @@
     int sign, code;
     if(val==0){
         code = 0;
-        put_bits(&s->pb,h261_mv_tab[code][1],h261_mv_tab[code][0]);
+        put_bits(&s->pb,ff_h261_mv_tab[code][1],ff_h261_mv_tab[code][0]);
     }
     else{
         if(val > 15)
@@ -137,7 +138,7 @@
             val+=32;
         sign = val < 0;
         code = sign ? -val : val;
-        put_bits(&s->pb,h261_mv_tab[code][1],h261_mv_tab[code][0]);
+        put_bits(&s->pb,ff_h261_mv_tab[code][1],ff_h261_mv_tab[code][0]);
         put_bits(&s->pb,1,sign);
     }
 }
@@ -182,7 +183,7 @@
     }
 
     /* MB is not skipped, encode MBA */
-    put_bits(&s->pb, h261_mba_bits[(h->current_mba-h->previous_mba)-1], h261_mba_code[(h->current_mba-h->previous_mba)-1]);
+    put_bits(&s->pb, ff_h261_mba_bits[(h->current_mba-h->previous_mba)-1], ff_h261_mba_code[(h->current_mba-h->previous_mba)-1]);
 
     /* calculate MTYPE */
     if(!s->mb_intra){
@@ -194,15 +195,15 @@
             h->mtype+=3;
         if(cbp || s->dquant)
             h->mtype++;
-        assert(h->mtype > 1);
+        av_assert1(h->mtype > 1);
     }
 
     if(s->dquant)
         h->mtype++;
 
-    put_bits(&s->pb, h261_mtype_bits[h->mtype], h261_mtype_code[h->mtype]);
+    put_bits(&s->pb, ff_h261_mtype_bits[h->mtype], ff_h261_mtype_code[h->mtype]);
 
-    h->mtype = h261_mtype_map[h->mtype];
+    h->mtype = ff_h261_mtype_map[h->mtype];
 
     if(IS_QUANT(h->mtype)){
         ff_set_qscale(s,s->qscale+s->dquant);
@@ -221,8 +222,8 @@
     h->previous_mba = h->current_mba;
 
     if(HAS_CBP(h->mtype)){
-        assert(cbp>0);
-        put_bits(&s->pb,h261_cbp_tab[cbp-1][1],h261_cbp_tab[cbp-1][0]);
+        av_assert1(cbp>0);
+        put_bits(&s->pb,ff_h261_cbp_tab[cbp-1][1],ff_h261_cbp_tab[cbp-1][0]);
     }
     for(i=0; i<6; i++) {
         /* encode each block */
@@ -240,7 +241,7 @@
 
     if (!done) {
         done = 1;
-        ff_init_rl(&h261_rl_tcoeff, ff_h261_rl_table_store);
+        ff_init_rl(&ff_h261_rl_tcoeff, ff_h261_rl_table_store);
     }
 
     s->min_qcoeff= -127;
@@ -260,7 +261,7 @@
     int level, run, i, j, last_index, last_non_zero, sign, slevel, code;
     RLTable *rl;
 
-    rl = &h261_rl_tcoeff;
+    rl = &ff_h261_rl_tcoeff;
     if (s->mb_intra) {
         /* DC coef */
         level = block[0];
@@ -307,8 +308,8 @@
             put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
             if (code == rl->n) {
                 put_bits(&s->pb, 6, run);
-                assert(slevel != 0);
-                assert(level <= 127);
+                av_assert1(slevel != 0);
+                av_assert1(level <= 127);
                 put_sbits(&s->pb, 8, slevel);
             } else {
                 put_bits(&s->pb, 1, sign);
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index 7f1966f..5b77106 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -5,20 +5,20 @@
  * Copyright (c) 2001 Juan J. Sierralta P
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/h263.h b/libavcodec/h263.h
index 2a1ae48..a8d266d 100644
--- a/libavcodec/h263.h
+++ b/libavcodec/h263.h
@@ -1,20 +1,20 @@
 /*
  * H263 internal header
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #ifndef AVCODEC_H263_H
@@ -59,8 +59,8 @@
 
 extern const uint16_t ff_h263_format[8][2];
 extern const uint8_t ff_modified_quant_tab[2][32];
-extern uint16_t ff_mba_max[6];
-extern uint8_t ff_mba_length[7];
+extern const uint16_t ff_mba_max[6];
+extern const uint8_t ff_mba_length[7];
 
 extern uint8_t ff_h263_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
 
@@ -110,7 +110,7 @@
 
 void ff_clean_h263_qscales(MpegEncContext *s);
 int ff_h263_resync(MpegEncContext *s);
-const uint8_t *ff_h263_find_resync_marker(const uint8_t *p, const uint8_t *end);
+const uint8_t *ff_h263_find_resync_marker(MpegEncContext *s, const uint8_t *p, const uint8_t *end);
 int ff_h263_get_gob_height(MpegEncContext *s);
 void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code);
 
diff --git a/libavcodec/h263_parser.c b/libavcodec/h263_parser.c
index 71e047a..2e7d493 100644
--- a/libavcodec/h263_parser.c
+++ b/libavcodec/h263_parser.c
@@ -2,20 +2,20 @@
  * H.263 parser
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -70,12 +70,16 @@
     ParseContext *pc = s->priv_data;
     int next;
 
-    next= ff_h263_find_frame_end(pc, buf, buf_size);
+    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
+        next = buf_size;
+    } else {
+        next= ff_h263_find_frame_end(pc, buf, buf_size);
 
-    if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
-        *poutbuf = NULL;
-        *poutbuf_size = 0;
-        return buf_size;
+        if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
+            *poutbuf = NULL;
+            *poutbuf_size = 0;
+            return buf_size;
+        }
     }
 
     *poutbuf = buf;
diff --git a/libavcodec/h263_parser.h b/libavcodec/h263_parser.h
index 5bd715f..565a222 100644
--- a/libavcodec/h263_parser.h
+++ b/libavcodec/h263_parser.h
@@ -2,20 +2,20 @@
  * H.263 parser
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/h263data.h b/libavcodec/h263data.h
index e3b83ad..e245e2f 100644
--- a/libavcodec/h263data.h
+++ b/libavcodec/h263data.h
@@ -4,20 +4,20 @@
  * copyright (c) 2001 Juan J. Sierralta P
  * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -264,11 +264,11 @@
     0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 9,10,10,11,11,12,12,12,13,13,13,14,14,14,14,14,15,15,15,15,15
 };
 
-uint16_t ff_mba_max[6]={
+const uint16_t ff_mba_max[6]={
      47,  98, 395,1583,6335,9215
 };
 
-uint8_t ff_mba_length[7]={
+const uint8_t ff_mba_length[7]={
       6,   7,   9,  11,  13,  14,  14
 };
 
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 72bf052..7141d49 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,8 @@
  * H.263 decoder.
  */
 
+#define UNCHECKED_BITSTREAM_READER 1
+
 #include "libavutil/cpu.h"
 #include "internal.h"
 #include "avcodec.h"
@@ -45,6 +47,7 @@
 av_cold int ff_h263_decode_init(AVCodecContext *avctx)
 {
     MpegEncContext *s = avctx->priv_data;
+    int ret;
 
     s->avctx = avctx;
     s->out_format = FMT_H263;
@@ -67,6 +70,7 @@
     /* select sub codec */
     switch(avctx->codec->id) {
     case AV_CODEC_ID_H263:
+    case AV_CODEC_ID_H263P:
         s->unrestricted_mv= 0;
         avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
         break;
@@ -107,15 +111,15 @@
         s->h263_flv = 1;
         break;
     default:
-        return -1;
+        return AVERROR(EINVAL);
     }
     s->codec_id= avctx->codec->id;
     avctx->hwaccel= ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
 
     /* for h263, we allocate the images after having read the header */
-    if (avctx->codec->id != AV_CODEC_ID_H263 && avctx->codec->id != AV_CODEC_ID_MPEG4)
-        if (ff_MPV_common_init(s) < 0)
-            return -1;
+    if (avctx->codec->id != AV_CODEC_ID_H263 && avctx->codec->id != AV_CODEC_ID_H263P && avctx->codec->id != AV_CODEC_ID_MPEG4)
+        if ((ret = ff_MPV_common_init(s)) < 0)
+            return ret;
 
         ff_h263_decode_init_vlc(s);
 
@@ -153,7 +157,9 @@
 
 static int decode_slice(MpegEncContext *s){
     const int part_mask= s->partitioned_frame ? (ER_AC_END|ER_AC_ERROR) : 0x7F;
-    const int mb_size = 16;
+    const int mb_size= 16>>s->avctx->lowres;
+    int ret;
+
     s->last_resync_gb= s->gb;
     s->first_slice_line= 1;
 
@@ -164,7 +170,7 @@
 
     if (s->avctx->hwaccel) {
         const uint8_t *start= s->gb.buffer + get_bits_count(&s->gb)/8;
-        const uint8_t *end  = ff_h263_find_resync_marker(start + 1, s->gb.buffer_end);
+        const uint8_t *end  = ff_h263_find_resync_marker(s, start + 1, s->gb.buffer_end);
         skip_bits_long(&s->gb, 8*(end - start));
         return s->avctx->hwaccel->decode_slice(s->avctx, start, end - start);
     }
@@ -173,8 +179,8 @@
         const int qscale= s->qscale;
 
         if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4){
-            if(ff_mpeg4_decode_partitions(s) < 0)
-                return -1;
+            if ((ret = ff_mpeg4_decode_partitions(s)) < 0)
+                return ret;
         }
 
         /* restore variables which were modified */
@@ -243,12 +249,12 @@
                 }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);
-                    return -1;
+                    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);
 
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
 
             ff_MPV_decode_mb(s, s->block);
@@ -275,7 +281,7 @@
     if(      s->codec_id==AV_CODEC_ID_MPEG4
        &&   (s->workaround_bugs&FF_BUG_AUTODETECT)
        &&    get_bits_left(&s->gb) >=0
-       &&    get_bits_left(&s->gb) < 48
+       &&    get_bits_left(&s->gb) < 137
 //       &&   !s->resync_marker
        &&   !s->data_partitioning){
 
@@ -314,7 +320,7 @@
             max_extra+= 17;
 
         /* buggy padding but the frame should still end approximately at the bitstream end */
-        if((s->workaround_bugs&FF_BUG_NO_PADDING) && (s->err_recognition&AV_EF_BUFFER))
+        if((s->workaround_bugs&FF_BUG_NO_PADDING) && (s->err_recognition&(AV_EF_BUFFER|AV_EF_AGGRESSIVE)))
             max_extra+= 48;
         else if((s->workaround_bugs&FF_BUG_NO_PADDING))
             max_extra+= 256*256*256*64;
@@ -336,7 +342,7 @@
 
     ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);
 
-    return -1;
+    return AVERROR_INVALIDDATA;
 }
 
 int ff_h263_decode_frame(AVCodecContext *avctx,
@@ -375,9 +381,11 @@
             next= ff_mpeg4_find_frame_end(&s->parse_context, buf, buf_size);
         }else if(CONFIG_H263_DECODER && s->codec_id==AV_CODEC_ID_H263){
             next= ff_h263_find_frame_end(&s->parse_context, buf, buf_size);
+        }else if(CONFIG_H263P_DECODER && s->codec_id==AV_CODEC_ID_H263P){
+            next= ff_h263_find_frame_end(&s->parse_context, buf, buf_size);
         }else{
             av_log(s->avctx, AV_LOG_ERROR, "this codec does not support truncated bitstreams\n");
-            return -1;
+            return AVERROR(EINVAL);
         }
 
         if( ff_combine_frame(&s->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0 )
@@ -386,6 +394,18 @@
 
 
 retry:
+    if(s->divx_packed && s->bitstream_buffer_size){
+        int i;
+        for(i=0; i<buf_size-3; i++){
+            if(buf[i]==0 && buf[i+1]==0 && buf[i+2]==1){
+                if(buf[i+3]==0xB0){
+                    av_log(s->avctx, AV_LOG_WARNING, "Discarding excessive bitstream in packed xvid\n");
+                    s->bitstream_buffer_size=0;
+                }
+                break;
+            }
+        }
+    }
 
     if(s->bitstream_buffer_size && (s->divx_packed || buf_size<20)){ //divx 5.01+/xvid frame reorder
         init_get_bits(&s->gb, s->bitstream_buffer, s->bitstream_buffer_size*8);
@@ -394,8 +414,8 @@
     s->bitstream_buffer_size=0;
 
     if (!s->context_initialized) {
-        if (ff_MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix
-            return -1;
+        if ((ret = ff_MPV_common_init(s)) < 0) //we need the idct permutaton for reading a custom matrix
+            return ret;
     }
 
     /* We need to set current_picture_ptr before reading the header,
@@ -428,12 +448,20 @@
         ret = ff_h263_decode_picture_header(s);
     }
 
+    if (ret < 0 || ret==FRAME_SKIPPED) {
+        if (   s->width  != avctx->coded_width
+            || s->height != avctx->coded_height) {
+                av_log(s->avctx, AV_LOG_WARNING, "Reverting picture dimensions change due to header decoding failure\n");
+                s->width = avctx->coded_width;
+                s->height= avctx->coded_height;
+        }
+    }
     if(ret==FRAME_SKIPPED) return get_consumed_bytes(s, buf_size);
 
     /* skip if the header was thrashed */
     if (ret < 0){
         av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");
-        return -1;
+        return ret;
     }
 
     avctx->has_b_frames= !s->low_delay;
@@ -560,7 +588,7 @@
     if (s->codec_id == AV_CODEC_ID_MPEG4 && s->xvid_build>=0 && avctx->idct_algo == FF_IDCT_AUTO && (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) {
         avctx->idct_algo= FF_IDCT_XVIDMMX;
         ff_dct_common_init(s);
-        s->picture_number=0;
+        goto retry;
     }
 #endif
 
@@ -569,7 +597,7 @@
         /* FIXME: By the way H263 decoder is evolving it should have */
         /* an H263EncContext                                         */
 
-    if (!avctx->coded_width || !avctx->coded_height) {
+    if ((!avctx->coded_width || !avctx->coded_height) && 0) {
         ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat
 
         s->parse_context.buffer=0;
@@ -624,8 +652,8 @@
         s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab;
     }
 
-    if(ff_MPV_frame_start(s, avctx) < 0)
-        return -1;
+    if ((ret = ff_MPV_frame_start(s, avctx)) < 0)
+        return ret;
 
     if (!s->divx_packed) ff_thread_finish_setup(avctx);
 
@@ -635,8 +663,8 @@
     }
 
     if (avctx->hwaccel) {
-        if (avctx->hwaccel->start_frame(avctx, s->gb.buffer, s->gb.buffer_end - s->gb.buffer) < 0)
-            return -1;
+        if ((ret = avctx->hwaccel->start_frame(avctx, s->gb.buffer, s->gb.buffer_end - s->gb.buffer)) < 0)
+            return ret;
     }
 
     ff_er_frame_start(s);
@@ -681,22 +709,18 @@
 frame_end:
     /* divx 5.01+ bistream reorder stuff */
     if(s->codec_id==AV_CODEC_ID_MPEG4 && s->divx_packed){
-        int current_pos= get_bits_count(&s->gb)>>3;
+        int current_pos= s->gb.buffer == s->bitstream_buffer ? 0 : (get_bits_count(&s->gb)>>3);
         int startcode_found=0;
 
-        if(buf_size - current_pos > 5){
+        if(buf_size - current_pos > 7){
             int i;
-            for(i=current_pos; i<buf_size-3; i++){
+            for(i=current_pos; i<buf_size-4; i++){
                 if(buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 && buf[i+3]==0xB6){
-                    startcode_found=1;
+                    startcode_found=!(buf[i+4]&0x40);
                     break;
                 }
             }
         }
-        if(s->gb.buffer == s->bitstream_buffer && buf_size>7 && s->xvid_build>=0){ //xvid style
-            startcode_found=1;
-            current_pos=0;
-        }
 
         if(startcode_found){
             av_fast_malloc(
@@ -714,8 +738,8 @@
     ff_er_frame_end(s);
 
     if (avctx->hwaccel) {
-        if (avctx->hwaccel->end_frame(avctx) < 0)
-            return -1;
+        if ((ret = avctx->hwaccel->end_frame(avctx)) < 0)
+            return ret;
     }
 
     ff_MPV_frame_end(s);
@@ -751,6 +775,23 @@
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 |
                       CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
     .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,
+};
+
+AVCodec ff_h263p_decoder = {
+    .name           = "h263p",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_H263P,
+    .priv_data_size = sizeof(MpegEncContext),
+    .init           = ff_h263_decode_init,
+    .close          = ff_h263_decode_end,
+    .decode         = ff_h263_decode_frame,
+    .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 |
+                      CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
+    .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,
 };
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 8648a8d..55522aa 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... decoder
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,7 +25,10 @@
  * @author Michael Niedermayer <michaelni@gmx.at>
  */
 
+#define UNCHECKED_BITSTREAM_READER 1
+
 #include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
 #include "internal.h"
 #include "cabac.h"
 #include "cabac_functions.h"
@@ -50,13 +53,17 @@
 static const uint8_t rem6[QP_MAX_NUM + 1] = {
     0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2,
     3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
-    0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3,
+    0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2,
+    3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
+    0, 1, 2, 3,
 };
 
 static const uint8_t div6[QP_MAX_NUM + 1] = {
     0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3,  3,  3,
     3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6,  6,  6,
-    7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10,
+    7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10,
+   10,10,10,11,11,11,11,11,11,12,12,12,12,12,12,13,13,13, 13, 13, 13,
+   14,14,14,14,
 };
 
 static const enum AVPixelFormat hwaccel_pixfmt_list_h264_jpeg_420[] = {
@@ -67,6 +74,12 @@
     AV_PIX_FMT_NONE
 };
 
+int avpriv_h264_has_num_reorder_frames(AVCodecContext *avctx)
+{
+    H264Context *h = avctx->priv_data;
+    return h ? h->sps.num_reorder_frames : 0;
+}
+
 /**
  * Check if the top & left blocks are available if needed and
  * change the dc mode so it only uses the available blocks.
@@ -220,21 +233,27 @@
     }
 #endif
 
-    if (i >= length - 1) { // no escaped 0
-        *dst_length = length;
-        *consumed   = length + 1; // +1 for the header
-        return src;
-    }
-
     // use second escape buffer for inter data
     bufidx = h->nal_unit_type == NAL_DPC ? 1 : 0;
-    av_fast_malloc(&h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx],
-                   length + FF_INPUT_BUFFER_PADDING_SIZE);
+
+    si = h->rbsp_buffer_size[bufidx];
+    av_fast_padded_malloc(&h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx], length+MAX_MBPAIR_SIZE);
     dst = h->rbsp_buffer[bufidx];
 
     if (dst == NULL)
         return NULL;
 
+    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){
+            return src;
+        }else{
+            memcpy(dst, src, length);
+            return dst;
+        }
+    }
+
     memcpy(dst, src, i);
     si = di = i;
     while (si + 2 < length) {
@@ -369,7 +388,7 @@
     } else {
         int i;
 
-        assert(IS_8X8(mb_type));
+        av_assert2(IS_8X8(mb_type));
 
         for (i = 0; i < 4; i++) {
             const int sub_mb_type = h->sub_mb_type[i];
@@ -401,7 +420,7 @@
                                   nrefs);
             } else {
                 int j;
-                assert(IS_SUB_4X4(sub_mb_type));
+                av_assert2(IS_SUB_4X4(sub_mb_type));
                 for (j = 0; j < 4; j++) {
                     int sub_y_offset = y_offset + 2 * (j & 2);
                     get_lowest_part_y(h, refs, n + j, 4, sub_y_offset,
@@ -740,9 +759,7 @@
             s->dsp.prefetch(src[1] + off, s->linesize, 4);
             s->dsp.prefetch(src[2] + off, s->linesize, 4);
         } else {
-            off = ((mx >> 1) << pixel_shift) +
-                  ((my >> 1) + (s->mb_x & 7)) * s->uvlinesize +
-                  (64 << pixel_shift);
+            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);
         }
     }
@@ -859,7 +876,7 @@
 {
     MpegEncContext *const s = &h->s;
     const int big_mb_num    = s->mb_stride * (s->mb_height + 1);
-    const int row_mb_num    = s->mb_stride * 2 * s->avctx->thread_count;
+    const int row_mb_num    = 2*s->mb_stride*FFMAX(s->avctx->thread_count, 1);
     int x, y;
 
     FF_ALLOCZ_OR_GOTO(h->s.avctx, h->intra4x4_pred_mode,
@@ -966,12 +983,18 @@
     s->height   = s->avctx->height;
     s->codec_id = s->avctx->codec->id;
 
-    ff_h264dsp_init(&h->h264dsp, 8, 1);
-    ff_h264_pred_init(&h->hpc, s->codec_id, 8, 1);
+    s->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);
 
     h->dequant_coeff_pps = -1;
     s->unrestricted_mv   = 1;
 
+    s->dsp.dct_bits = 16;
     /* needed so that IDCT permutation is known early */
     ff_dsputil_init(&s->dsp, s->avctx);
 
@@ -979,17 +1002,20 @@
     memset(h->pps.scaling_matrix8, 16, 2 * 64 * sizeof(uint8_t));
 }
 
-int ff_h264_decode_extradata(H264Context *h)
+int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size)
 {
     AVCodecContext *avctx = h->s.avctx;
 
-    if (avctx->extradata[0] == 1) {
+    if (!buf || size <= 0)
+        return -1;
+
+    if (buf[0] == 1) {
         int i, cnt, nalsize;
-        unsigned char *p = avctx->extradata;
+        const unsigned char *p = buf;
 
         h->is_avc = 1;
 
-        if (avctx->extradata_size < 7) {
+        if (size < 7) {
             av_log(avctx, AV_LOG_ERROR, "avcC too short\n");
             return -1;
         }
@@ -1001,7 +1027,7 @@
         p  += 6;
         for (i = 0; i < cnt; i++) {
             nalsize = AV_RB16(p) + 2;
-            if (p - avctx->extradata + nalsize > avctx->extradata_size)
+            if(nalsize > size - (p-buf))
                 return -1;
             if (decode_nal_units(h, p, nalsize) < 0) {
                 av_log(avctx, AV_LOG_ERROR,
@@ -1014,7 +1040,7 @@
         cnt = *(p++); // Number of pps
         for (i = 0; i < cnt; i++) {
             nalsize = AV_RB16(p) + 2;
-            if (p - avctx->extradata + nalsize > avctx->extradata_size)
+            if(nalsize > size - (p-buf))
                 return -1;
             if (decode_nal_units(h, p, nalsize) < 0) {
                 av_log(avctx, AV_LOG_ERROR,
@@ -1024,13 +1050,13 @@
             p += nalsize;
         }
         // Now store right nal length size, that will be used to parse all other nals
-        h->nal_length_size = (avctx->extradata[4] & 0x03) + 1;
+        h->nal_length_size = (buf[4] & 0x03) + 1;
     } else {
         h->is_avc = 0;
-        if (decode_nal_units(h, avctx->extradata, avctx->extradata_size) < 0)
+        if (decode_nal_units(h, buf, size) < 0)
             return -1;
     }
-    return 0;
+    return size;
 }
 
 av_cold int ff_h264_decode_init(AVCodecContext *avctx)
@@ -1065,6 +1091,7 @@
     for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
         h->last_pocs[i] = INT_MIN;
     h->prev_poc_msb = 1 << 16;
+    h->prev_frame_num = -1;
     h->x264_build   = -1;
     ff_h264_reset_sei(h);
     if (avctx->codec_id == AV_CODEC_ID_H264) {
@@ -1074,8 +1101,10 @@
     }
 
     if (avctx->extradata_size > 0 && avctx->extradata &&
-        ff_h264_decode_extradata(h))
+        ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size) < 0) {
+        ff_h264_free_context(h);
         return -1;
+    }
 
     if (h->sps.bitstream_restriction_flag &&
         s->avctx->has_b_frames < h->sps.num_reorder_frames) {
@@ -1083,6 +1112,8 @@
         s->low_delay           = 0;
     }
 
+    ff_init_cabac_states();
+
     return 0;
 }
 
@@ -1142,7 +1173,7 @@
     int inited = s->context_initialized, err;
     int i;
 
-    if (dst == src || !s1->context_initialized)
+    if (dst == src)
         return 0;
 
     err = ff_mpeg_update_thread_context(dst, src);
@@ -1162,12 +1193,19 @@
                sizeof(H264Context) - sizeof(MpegEncContext));
         memset(h->sps_buffers, 0, sizeof(h->sps_buffers));
         memset(h->pps_buffers, 0, sizeof(h->pps_buffers));
+
+        if (s1->context_initialized) {
         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;
@@ -1175,10 +1213,6 @@
 
         h->thread_context[0] = 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);
-
         s->dsp.clear_blocks(h->mb);
         s->dsp.clear_blocks(h->mb + (24 * 16 << h->pixel_shift));
     }
@@ -1222,6 +1256,7 @@
                        MAX_DELAYED_PIC_COUNT + 2, s, s1);
 
     h->last_slice_type = h1->last_slice_type;
+    h->sync            = h1->sync;
 
     if (!s->current_picture_ptr)
         return 0;
@@ -1254,6 +1289,7 @@
      * 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;
 
     assert(s->linesize && s->uvlinesize);
@@ -1316,7 +1352,6 @@
     Picture *out = s->current_picture_ptr;
     Picture *cur = s->current_picture_ptr;
     int i, pics, out_of_order, out_idx;
-    int invalid = 0, cnt = 0;
 
     s->current_picture_ptr->f.qscale_type = FF_QSCALE_TYPE_H264;
     s->current_picture_ptr->f.pict_type   = s->pict_type;
@@ -1400,6 +1435,8 @@
         }
     }
 
+    cur->mmco_reset = h->mmco_reset;
+    h->mmco_reset = 0;
     // FIXME do something with unavailable reference frames
 
     /* Sort B-frames into display order */
@@ -1416,79 +1453,51 @@
         s->low_delay           = 0;
     }
 
+    for (i = 0; 1; i++) {
+        if(i == MAX_DELAYED_PIC_COUNT || cur->poc < h->last_pocs[i]){
+            if(i)
+                h->last_pocs[i-1] = cur->poc;
+            break;
+        } else if(i) {
+            h->last_pocs[i-1]= h->last_pocs[i];
+        }
+    }
+    out_of_order = MAX_DELAYED_PIC_COUNT - i;
+    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;
+    }
+
     pics = 0;
     while (h->delayed_pic[pics])
         pics++;
 
-    assert(pics <= MAX_DELAYED_PIC_COUNT);
+    av_assert0(pics <= MAX_DELAYED_PIC_COUNT);
 
     h->delayed_pic[pics++] = cur;
     if (cur->f.reference == 0)
         cur->f.reference = DELAYED_PIC_REF;
 
-    /* Frame reordering. This code takes pictures from coding order and sorts
-     * them by their incremental POC value into display order. It supports POC
-     * gaps, MMCO reset codes and random resets.
-     * A "display group" can start either with a IDR frame (f.key_frame = 1),
-     * and/or can be closed down with a MMCO reset code. In sequences where
-     * there is no delay, we can't detect that (since the frame was already
-     * output to the user), so we also set h->mmco_reset to detect the MMCO
-     * reset code.
-     * FIXME: if we detect insufficient delays (as per s->avctx->has_b_frames),
-     * we increase the delay between input and output. All frames affected by
-     * the lag (e.g. those that should have been output before another frame
-     * that we already returned to the user) will be dropped. This is a bug
-     * that we will fix later. */
-    for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++) {
-        cnt     += out->poc < h->last_pocs[i];
-        invalid += out->poc == INT_MIN;
-    }
-    if (!h->mmco_reset && !cur->f.key_frame &&
-        cnt + invalid == MAX_DELAYED_PIC_COUNT && cnt > 0) {
-        h->mmco_reset = 2;
-        if (pics > 1)
-            h->delayed_pic[pics - 2]->mmco_reset = 2;
-    }
-    if (h->mmco_reset || cur->f.key_frame) {
-        for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
-            h->last_pocs[i] = INT_MIN;
-        cnt     = 0;
-        invalid = MAX_DELAYED_PIC_COUNT;
-    }
-    out     = h->delayed_pic[0];
+    out = h->delayed_pic[0];
     out_idx = 0;
-    for (i = 1; i < MAX_DELAYED_PIC_COUNT &&
-                h->delayed_pic[i] &&
-                !h->delayed_pic[i - 1]->mmco_reset &&
-                !h->delayed_pic[i]->f.key_frame;
+    for (i = 1; h->delayed_pic[i] &&
+                !h->delayed_pic[i]->f.key_frame &&
+                !h->delayed_pic[i]->mmco_reset;
          i++)
         if (h->delayed_pic[i]->poc < out->poc) {
             out     = h->delayed_pic[i];
             out_idx = i;
         }
     if (s->avctx->has_b_frames == 0 &&
-        (h->delayed_pic[0]->f.key_frame || h->mmco_reset))
+        (h->delayed_pic[0]->f.key_frame || h->delayed_pic[0]->mmco_reset))
         h->next_outputed_poc = INT_MIN;
-    out_of_order = !out->f.key_frame && !h->mmco_reset &&
-                   (out->poc < h->next_outputed_poc);
+    out_of_order = out->poc < h->next_outputed_poc;
 
-    if (h->sps.bitstream_restriction_flag &&
-        s->avctx->has_b_frames >= h->sps.num_reorder_frames) {
-    } else if (out_of_order && pics - 1 == s->avctx->has_b_frames &&
-               s->avctx->has_b_frames < MAX_DELAYED_PIC_COUNT) {
-        if (invalid + cnt < MAX_DELAYED_PIC_COUNT) {
-            s->avctx->has_b_frames = FFMAX(s->avctx->has_b_frames, cnt);
-        }
-        s->low_delay = 0;
-    } else if (s->low_delay &&
-               ((h->next_outputed_poc != INT_MIN &&
-                 out->poc > h->next_outputed_poc + 2) ||
-                cur->f.pict_type == AV_PICTURE_TYPE_B)) {
-        s->low_delay = 0;
-        s->avctx->has_b_frames++;
-    }
-
-    if (pics > s->avctx->has_b_frames) {
+    if (out_of_order || pics > s->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
@@ -1496,28 +1505,18 @@
         for (i = out_idx; h->delayed_pic[i]; i++)
             h->delayed_pic[i] = h->delayed_pic[i + 1];
     }
-    memmove(h->last_pocs, &h->last_pocs[1],
-            sizeof(*h->last_pocs) * (MAX_DELAYED_PIC_COUNT - 1));
-    h->last_pocs[MAX_DELAYED_PIC_COUNT - 1] = cur->poc;
     if (!out_of_order && pics > s->avctx->has_b_frames) {
         h->next_output_pic = out;
-        if (out->mmco_reset) {
-            if (out_idx > 0) {
-                h->next_outputed_poc                    = out->poc;
-                h->delayed_pic[out_idx - 1]->mmco_reset = out->mmco_reset;
-            } else {
-                h->next_outputed_poc = INT_MIN;
-            }
-        } else {
-            if (out_idx == 0 && pics > 1 && h->delayed_pic[0]->f.key_frame) {
-                h->next_outputed_poc = INT_MIN;
-            } else {
-                h->next_outputed_poc = out->poc;
-            }
-        }
-        h->mmco_reset = 0;
+        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\n");
+        av_log(s->avctx, AV_LOG_DEBUG, "no picture %s\n", out_of_order ? "ooo" : "");
+    }
+
+    if (h->next_output_pic && h->next_output_pic->sync) {
+        h->sync |= 2;
     }
 
     if (setup_finished)
@@ -1790,7 +1789,7 @@
                         uint64_t tr_high;
                         if (dir == DIAG_DOWN_LEFT_PRED || dir == VERT_LEFT_PRED) {
                             const int topright_avail = (h->topright_samples_available << i) & 0x8000;
-                            assert(s->mb_y || linesize <= block_offset[i]);
+                            av_assert2(s->mb_y || linesize <= block_offset[i]);
                             if (!topright_avail) {
                                 if (pixel_shift) {
                                     tr_high  = ((uint16_t *)ptr)[3 - linesize / 2] * 0x0001000100010001ULL;
@@ -2084,11 +2083,14 @@
  */
 static void idr(H264Context *h)
 {
+    int i;
     ff_h264_remove_all_refs(h);
     h->prev_frame_num        = 0;
     h->prev_frame_num_offset = 0;
-    h->prev_poc_msb          =
+    h->prev_poc_msb          = 1<<16;
     h->prev_poc_lsb          = 0;
+    for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
+        h->last_pocs[i] = INT_MIN;
 }
 
 /* forget old pics after a seek */
@@ -2096,21 +2098,22 @@
 {
     H264Context *h = avctx->priv_data;
     int i;
-    for (i = 0; i < MAX_DELAYED_PIC_COUNT; 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;
     }
-    for (i = 0; i < MAX_DELAYED_PIC_COUNT; i++)
-        h->last_pocs[i] = INT_MIN;
     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;
     ff_h264_reset_sei(h);
     ff_mpeg_flush(avctx);
+    h->recovery_frame= -1;
+    h->sync= 0;
 }
 
 static int init_poc(H264Context *h)
@@ -2212,19 +2215,19 @@
 #undef T
     }
     if (h->sps.transform_bypass) { // FIXME same ugly
-        h->zigzag_scan_q0          = zigzag_scan;
-        h->zigzag_scan8x8_q0       = ff_zigzag_direct;
-        h->zigzag_scan8x8_cavlc_q0 = zigzag_scan8x8_cavlc;
-        h->field_scan_q0           = field_scan;
-        h->field_scan8x8_q0        = field_scan8x8;
-        h->field_scan8x8_cavlc_q0  = field_scan8x8_cavlc;
+        memcpy(h->zigzag_scan_q0          , zigzag_scan             , sizeof(h->zigzag_scan_q0         ));
+        memcpy(h->zigzag_scan8x8_q0       , ff_zigzag_direct        , sizeof(h->zigzag_scan8x8_q0      ));
+        memcpy(h->zigzag_scan8x8_cavlc_q0 , zigzag_scan8x8_cavlc    , sizeof(h->zigzag_scan8x8_cavlc_q0));
+        memcpy(h->field_scan_q0           , field_scan              , sizeof(h->field_scan_q0          ));
+        memcpy(h->field_scan8x8_q0        , field_scan8x8           , sizeof(h->field_scan8x8_q0       ));
+        memcpy(h->field_scan8x8_cavlc_q0  , field_scan8x8_cavlc     , sizeof(h->field_scan8x8_cavlc_q0 ));
     } else {
-        h->zigzag_scan_q0          = h->zigzag_scan;
-        h->zigzag_scan8x8_q0       = h->zigzag_scan8x8;
-        h->zigzag_scan8x8_cavlc_q0 = h->zigzag_scan8x8_cavlc;
-        h->field_scan_q0           = h->field_scan;
-        h->field_scan8x8_q0        = h->field_scan8x8;
-        h->field_scan8x8_cavlc_q0  = h->field_scan8x8_cavlc;
+        memcpy(h->zigzag_scan_q0          , h->zigzag_scan          , sizeof(h->zigzag_scan_q0         ));
+        memcpy(h->zigzag_scan8x8_q0       , h->zigzag_scan8x8       , sizeof(h->zigzag_scan8x8_q0      ));
+        memcpy(h->zigzag_scan8x8_cavlc_q0 , h->zigzag_scan8x8_cavlc , sizeof(h->zigzag_scan8x8_cavlc_q0));
+        memcpy(h->field_scan_q0           , h->field_scan           , sizeof(h->field_scan_q0          ));
+        memcpy(h->field_scan8x8_q0        , h->field_scan8x8        , sizeof(h->field_scan8x8_q0       ));
+        memcpy(h->field_scan8x8_cavlc_q0  , h->field_scan8x8_cavlc  , sizeof(h->field_scan8x8_cavlc_q0 ));
     }
 }
 
@@ -2360,6 +2363,7 @@
     unsigned int slice_type, tmp, i, j;
     int default_ref_list_done = 0;
     int last_pic_structure, last_pic_dropable;
+    int must_reinit;
 
     /* FIXME: 2tap qpel isn't implemented for high bit depth. */
     if ((s->avctx->flags2 & CODEC_FLAG2_FAST) &&
@@ -2371,7 +2375,7 @@
         s->me.qpel_avg = s->dsp.avg_h264_qpel_pixels_tab;
     }
 
-    first_mb_in_slice = get_ue_golomb(&s->gb);
+    first_mb_in_slice = get_ue_golomb_long(&s->gb);
 
     if (first_mb_in_slice == 0) { // FIXME better field boundary detection
         if (h0->current_slice && FIELD_PICTURE) {
@@ -2415,7 +2419,7 @@
 
     pps_id = get_ue_golomb(&s->gb);
     if (pps_id >= MAX_PPS_COUNT) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n");
+        av_log(h->s.avctx, AV_LOG_ERROR, "pps_id %d out of range\n", pps_id);
         return -1;
     }
     if (!h0->pps_buffers[pps_id]) {
@@ -2438,6 +2442,19 @@
     s->avctx->level   = h->sps.level_idc;
     s->avctx->refs    = h->sps.ref_frame_count;
 
+    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->cur_chroma_format_idc != h->sps.chroma_format_idc
+                     || av_cmp_q(h->sps.sar, s->avctx->sample_aspect_ratio)));
+
+    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
+    }
+
     s->mb_width  = h->sps.mb_width;
     s->mb_height = h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);
 
@@ -2445,29 +2462,15 @@
 
     s->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p
 
-    s->width = 16 * s->mb_width - (2 >> CHROMA444) * FFMIN(h->sps.crop_right, (8 << CHROMA444) - 1);
-    if (h->sps.frame_mbs_only_flag)
-        s->height = 16 * s->mb_height - (1 << s->chroma_y_shift) * FFMIN(h->sps.crop_bottom, (16 >> s->chroma_y_shift) - 1);
-    else
-        s->height = 16 * s->mb_height - (2 << s->chroma_y_shift) * FFMIN(h->sps.crop_bottom, (16 >> s->chroma_y_shift) - 1);
+    s->width  = 16 * s->mb_width;
+    s->height = 16 * s->mb_height;
 
-    if (FFALIGN(s->avctx->width,  16) == s->width &&
-        FFALIGN(s->avctx->height, 16) == s->height) {
-        s->width  = s->avctx->width;
-        s->height = s->avctx->height;
-    }
-
-    if (s->context_initialized &&
-        (s->width != s->avctx->width || s->height != s->avctx->height ||
-         av_cmp_q(h->sps.sar, s->avctx->sample_aspect_ratio))) {
-        if (h != h0 || (HAVE_THREADS && h->s.avctx->active_thread_type & FF_THREAD_FRAME)) {
-            av_log_missing_feature(s->avctx,
-                                   "Width/height changing with threads", 0);
-            return AVERROR_PATCHWELCOME;   // width / height changed during parallelized decoding
-        }
+    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) {
@@ -2475,13 +2478,52 @@
                    "Cannot (re-)initialize context during parallel decoding.\n");
             return -1;
         }
-
-        avcodec_set_dimensions(s->avctx, s->width, s->height);
+        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 ? AVCOL_RANGE_JPEG
+            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;
@@ -2521,13 +2563,38 @@
             else
                 s->avctx->pix_fmt = AV_PIX_FMT_YUV420P10;
             break;
-        case 8:
+        case 12:
             if (CHROMA444) {
                 if (s->avctx->colorspace == AVCOL_SPC_RGB) {
-                    s->avctx->pix_fmt = AV_PIX_FMT_GBRP;
+                    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;
@@ -2578,6 +2645,7 @@
                 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);
             }
@@ -2606,6 +2674,10 @@
     if (h->sps.frame_mbs_only_flag) {
         s->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");
+            return -1;
+        }
         if (get_bits1(&s->gb)) { // field_pic_flag
             s->picture_structure = PICT_TOP_FIELD + get_bits1(&s->gb); // bottom_field_flag
         } else {
@@ -2628,7 +2700,7 @@
     } else {
         /* Shorten frame num gaps so we don't have to allocate reference
          * frames just to throw them away */
-        if (h->frame_num != h->prev_frame_num) {
+        if (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0) {
             int unwrap_prev_frame_num = h->prev_frame_num;
             int max_frame_num         = 1 << h->sps.log2_max_frame_num;
 
@@ -2710,7 +2782,7 @@
             }
         }
 
-        while (h->frame_num != h->prev_frame_num &&
+        while (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0 &&
                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",
@@ -2759,6 +2831,8 @@
                 s0->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);
                     /* This and the previous field had different frame_nums.
                      * Consider this field first in pair. Throw away previous
                      * one except for reference purposes. */
@@ -2788,7 +2862,7 @@
 
     s->current_picture_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup
 
-    assert(s->mb_num == s->mb_width * s->mb_height);
+    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");
@@ -2798,7 +2872,7 @@
     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;
-    assert(s->mb_y < s->mb_height);
+    av_assert1(s->mb_y < s->mb_height);
 
     if (s->picture_structure == PICT_FRAME) {
         h->curr_pic_num = h->frame_num;
@@ -2835,7 +2909,8 @@
     h->ref_count[1] = h->pps.ref_count[1];
 
     if (h->slice_type_nos != AV_PICTURE_TYPE_I) {
-        int max_refs = s->picture_structure == PICT_FRAME ? 16 : 32;
+        unsigned max[2];
+        max[0] = max[1] = s->picture_structure == PICT_FRAME ? 15 : 31;
 
         if (h->slice_type_nos == AV_PICTURE_TYPE_B)
             h->direct_spatial_mv_pred = get_bits1(&s->gb);
@@ -2845,10 +2920,13 @@
             h->ref_count[0] = get_ue_golomb(&s->gb) + 1;
             if (h->slice_type_nos == AV_PICTURE_TYPE_B)
                 h->ref_count[1] = get_ue_golomb(&s->gb) + 1;
+            else
+                // full range is spec-ok in this case, even for frames
+                max[1] = 31;
         }
 
-        if (h->ref_count[0] > max_refs || h->ref_count[1] > max_refs) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n");
+        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]);
             h->ref_count[0] = h->ref_count[1] = 1;
             return AVERROR_INVALIDDATA;
         }
@@ -2858,7 +2936,7 @@
         else
             h->list_count = 1;
     } else
-        h->list_count = 0;
+        h->ref_count[1]= h->ref_count[0]= h->list_count= 0;
 
     if (!default_ref_list_done)
         ff_h264_fill_default_ref_list(h);
@@ -2999,9 +3077,14 @@
 
     h0->last_slice_type = slice_type;
     h->slice_num = ++h0->current_slice;
-    if (h->slice_num >= MAX_SLICES) {
-        av_log(s->avctx, AV_LOG_ERROR,
-               "Too many slices, increase MAX_SLICES and recompile\n");
+
+    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
+        && 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);
     }
 
     for (j = 0; j < 2; j++) {
@@ -3101,7 +3184,7 @@
         if (USES_LIST(top_type, list)) {
             const int b_xy  = h->mb2b_xy[top_xy] + 3 * b_stride;
             const int b8_xy = 4 * top_xy + 2;
-            int (*ref2frm)[64] = h->ref2frm[h->slice_table[top_xy] & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 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]);
             ref_cache[0 - 1 * 8] =
             ref_cache[1 - 1 * 8] = ref2frm[list][s->current_picture.f.ref_index[list][b8_xy + 0]];
@@ -3116,7 +3199,7 @@
             if (USES_LIST(left_type[LTOP], list)) {
                 const int b_xy  = h->mb2b_xy[left_xy[LTOP]] + 3;
                 const int b8_xy = 4 * left_xy[LTOP] + 1;
-                int (*ref2frm)[64] = h->ref2frm[h->slice_table[left_xy[LTOP]] & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2);
+                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]);
@@ -3149,7 +3232,7 @@
 
     {
         int8_t *ref = &s->current_picture.f.ref_index[list][4 * mb_xy];
-        int (*ref2frm)[64] = h->ref2frm[h->slice_num & (MAX_SLICES - 1)][0] + (MB_MBAFF ? 20 : 2);
+        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;
         AV_WN32A(&ref_cache[0 * 8], ref01);
@@ -3452,7 +3535,6 @@
         align_get_bits(&s->gb);
 
         /* init cabac */
-        ff_init_cabac_states(&h->cabac);
         ff_init_cabac_decoder(&h->cabac,
                               s->gb.buffer + get_bits_count(&s->gb) / 8,
                               (get_bits_left(&s->gb) + 7) / 8);
@@ -3488,7 +3570,9 @@
                     loop_filter(h, lf_x_start, s->mb_x + 1);
                 return 0;
             }
-            if (ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 2) {
+            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);
+            if (ret < 0 || h->cabac.bytestream > h->cabac.bytestream_end + 4) {
                 av_log(h->s.avctx, AV_LOG_ERROR,
                        "error while decoding MB %d %d, bytestream (%td)\n",
                        s->mb_x, s->mb_y,
@@ -3559,7 +3643,8 @@
                     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) {
+                    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);
@@ -3620,6 +3705,7 @@
             hx                    = h->thread_context[i];
             hx->s.err_recognition = avctx->err_recognition;
             hx->s.error_count     = 0;
+            hx->x264_build        = h->x264_build;
         }
 
         avctx->execute(avctx, decode_slice, h->thread_context,
@@ -3650,6 +3736,10 @@
     int nals_needed = 0; ///< number of NALs that need decoding before the next frame thread starts
     int nal_index;
 
+    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)) {
         h->current_slice = 0;
@@ -3717,16 +3807,14 @@
                 s->workaround_bugs |= FF_BUG_TRUNCATED;
 
             if (!(s->workaround_bugs & FF_BUG_TRUNCATED))
-                while (ptr[dst_length - 1] == 0 && dst_length > 0)
+                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 at %d/%d length %d\n",
-                       hx->nal_unit_type, buf_index, buf_size, dst_length);
+                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->is_avc && (nalsize != consumed) && nalsize)
                 av_log(h->s.avctx, AV_LOG_DEBUG,
@@ -3765,7 +3853,7 @@
             case NAL_IDR_SLICE:
                 if (h->nal_unit_type != NAL_IDR_SLICE) {
                     av_log(h->s.avctx, AV_LOG_ERROR,
-                           "Invalid mix of idr and non-idr slices");
+                           "Invalid mix of idr and non-idr slices\n");
                     buf_index = -1;
                     goto end;
                 }
@@ -3779,9 +3867,30 @@
                 if ((err = decode_slice_header(hx, h)))
                     break;
 
+                if (h->sei_recovery_frame_cnt >= 0 && (h->frame_num != h->sei_recovery_frame_cnt || hx->slice_type_nos != AV_PICTURE_TYPE_I))
+                    h->valid_recovery_point = 1;
+
+                if (   h->sei_recovery_frame_cnt >= 0
+                    && (   h->recovery_frame<0
+                        || ((h->recovery_frame - h->frame_num) & ((1 << h->sps.log2_max_frame_num)-1)) > h->sei_recovery_frame_cnt)) {
+                    h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) %
+                                        (1 << h->sps.log2_max_frame_num);
+
+                    if (!h->valid_recovery_point)
+                        h->recovery_frame = h->frame_num;
+                }
+
                 s->current_picture_ptr->f.key_frame |=
-                    (hx->nal_unit_type == NAL_IDR_SLICE) ||
-                    (h->sei_recovery_frame_cnt >= 0);
+                        (hx->nal_unit_type == NAL_IDR_SLICE);
+
+                if (h->recovery_frame == h->frame_num) {
+                    s->current_picture_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;
 
                 if (h->current_slice == 1) {
                     if (!(s->flags2 & CODEC_FLAG2_CHUNKS))
@@ -3838,6 +3947,9 @@
                 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");
+                return AVERROR_PATCHWELCOME;
+
                 if (hx->redundant_pic_count == 0 &&
                     hx->intra_gb_ptr &&
                     hx->s.data_partitioning &&
@@ -3856,12 +3968,13 @@
                 break;
             case NAL_SPS:
                 init_get_bits(&s->gb, ptr, bit_length);
-                if (ff_h264_decode_seq_parameter_set(h) < 0 &&
-                    h->is_avc && (nalsize != consumed) && nalsize) {
+                if (ff_h264_decode_seq_parameter_set(h) < 0 && (h->is_avc ? (nalsize != consumed) && nalsize : 1)) {
                     av_log(h->s.avctx, AV_LOG_DEBUG,
                            "SPS decoding failure, trying again with the complete NAL\n");
-                    init_get_bits(&s->gb, buf + buf_index + 1 - consumed,
-                                  8 * (nalsize - 1));
+                    if (h->is_avc)
+                        av_assert0(next_avc - buf_index + consumed == nalsize);
+                    init_get_bits(&s->gb, &buf[buf_index + 1 - consumed],
+                                  8*(next_avc - buf_index + consumed - 1));
                     ff_h264_decode_seq_parameter_set(h);
                 }
 
@@ -3869,42 +3982,8 @@
                     (h->sps.bitstream_restriction_flag &&
                      !h->sps.num_reorder_frames))
                     s->low_delay = 1;
-
                 if (avctx->has_b_frames < 2)
                     avctx->has_b_frames = !s->low_delay;
-
-                if (avctx->bits_per_raw_sample != h->sps.bit_depth_luma ||
-                    h->cur_chroma_format_idc   != h->sps.chroma_format_idc) {
-                    if (s->avctx->codec &&
-                        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU
-                        && (h->sps.bit_depth_luma != 8 ||
-                            h->sps.chroma_format_idc > 1)) {
-                        av_log(avctx, AV_LOG_ERROR,
-                               "VDPAU decoding does not support video "
-                               "colorspace\n");
-                        buf_index = -1;
-                        goto end;
-                    }
-                    if (h->sps.bit_depth_luma >= 8 && h->sps.bit_depth_luma <= 10) {
-                        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(avctx, AV_LOG_ERROR,
-                               "Unsupported bit depth: %d\n",
-                               h->sps.bit_depth_luma);
-                        buf_index = -1;
-                        goto end;
-                    }
-                }
                 break;
             case NAL_PPS:
                 init_get_bits(&s->gb, ptr, bit_length);
@@ -3977,15 +4056,15 @@
     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;
 
     /* end of stream, output what is still in the buffers */
-out:
     if (buf_size == 0) {
-        Picture *out;
-        int i, out_idx;
+ out:
 
         s->current_picture_ptr = NULL;
 
@@ -4012,19 +4091,42 @@
 
         return buf_index;
     }
+    if(h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC && (buf[5]&0x1F) && buf[8]==0x67){
+        int cnt= buf[5]&0x1f;
+        const uint8_t *p= buf+6;
+        while(cnt--){
+            int nalsize= AV_RB16(p) + 2;
+            if(nalsize > buf_size - (p-buf) || p[2]!=0x67)
+                goto not_extra;
+            p += nalsize;
+        }
+        cnt = *(p++);
+        if(!cnt)
+            goto not_extra;
+        while(cnt--){
+            int nalsize= AV_RB16(p) + 2;
+            if(nalsize > buf_size - (p-buf) || p[2]!=0x68)
+                goto not_extra;
+            p += nalsize;
+        }
+
+        return ff_h264_decode_extradata(h, buf, buf_size);
+    }
+not_extra:
 
     buf_index = decode_nal_units(h, buf, buf_size);
     if (buf_index < 0)
         return -1;
 
     if (!s->current_picture_ptr && h->nal_unit_type == NAL_END_SEQUENCE) {
-        buf_size = 0;
+        av_assert0(buf_index <= buf_size);
         goto out;
     }
 
     if (!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr) {
-        if (avctx->skip_frame >= AVDISCARD_NONREF)
-            return 0;
+        if (avctx->skip_frame >= AVDISCARD_NONREF ||
+            buf_size >= 4 && !memcmp("Q264", buf, 4))
+            return buf_size;
         av_log(avctx, AV_LOG_ERROR, "no frame!\n");
         return -1;
     }
@@ -4036,10 +4138,9 @@
 
         field_end(h, 0);
 
-        if (!h->next_output_pic) {
-            /* Wait for second field. */
-            *data_size = 0;
-        } else {
+        /* Wait for second field. */
+        *data_size = 0;
+        if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) {
             *data_size = sizeof(AVFrame);
             *pict      = h->next_output_pic->f;
         }
@@ -4069,6 +4170,7 @@
     H264Context *h    = avctx->priv_data;
     MpegEncContext *s = &h->s;
 
+    ff_h264_remove_all_refs(h);
     ff_h264_free_context(h);
 
     ff_MPV_common_end(s);
@@ -4095,6 +4197,26 @@
     { FF_PROFILE_UNKNOWN },
 };
 
+static const AVOption h264_options[] = {
+    {"is_avc", "is avc", offsetof(H264Context, is_avc), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 1, 0},
+    {"nal_length_size", "nal_length_size", offsetof(H264Context, nal_length_size), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 4, 0},
+    {NULL}
+};
+
+static const AVClass h264_class = {
+    "H264 Decoder",
+    av_default_item_name,
+    h264_options,
+    LIBAVUTIL_VERSION_INT,
+};
+
+static const AVClass h264_vdpau_class = {
+    "H264 VDPAU Decoder",
+    av_default_item_name,
+    h264_options,
+    LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_h264_decoder = {
     .name                  = "h264",
     .type                  = AVMEDIA_TYPE_VIDEO,
@@ -4111,6 +4233,7 @@
     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(decode_update_thread_context),
     .profiles              = NULL_IF_CONFIG_SMALL(profiles),
+    .priv_class            = &h264_class,
 };
 
 #if CONFIG_H264_VDPAU_DECODER
@@ -4128,5 +4251,6 @@
     .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_VDPAU_H264,
                                                    AV_PIX_FMT_NONE},
     .profiles       = NULL_IF_CONFIG_SMALL(profiles),
+    .priv_class     = &h264_vdpau_class,
 };
 #endif
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index 570ce2f..4d07a8a 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -46,6 +46,8 @@
 
 #define MAX_DELAYED_PIC_COUNT  16
 
+#define MAX_MBPAIR_SIZE (256*1024) // a tighter bound could be calculated if someone cares about a few bytes
+
 /* Compiling in interlaced support reduces the speed
  * of progressive decoding by about 2%. */
 #define ALLOW_INTERLACE
@@ -85,6 +87,7 @@
 #define CABAC h->pps.cabac
 #endif
 
+#define CHROMA    (h->sps.chroma_format_idc)
 #define CHROMA422 (h->sps.chroma_format_idc == 2)
 #define CHROMA444 (h->sps.chroma_format_idc == 3)
 
@@ -101,7 +104,7 @@
  */
 #define DELAYED_PIC_REF 4
 
-#define QP_MAX_NUM (51 + 2 * 6)           // The maximum supported qp
+#define QP_MAX_NUM (51 + 6*6)           // The maximum supported qp
 
 /* NAL unit types */
 enum {
@@ -226,7 +229,7 @@
     int transform_8x8_mode;         ///< transform_8x8_mode_flag
     uint8_t scaling_matrix4[6][16];
     uint8_t scaling_matrix8[6][64];
-    uint8_t chroma_qp_table[2][64]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table
+    uint8_t chroma_qp_table[2][QP_MAX_NUM+1];  ///< pre-scaled (with chroma_qp_index_offset) version of qp_table
     int chroma_qp_diff;
 } PPS;
 
@@ -418,12 +421,12 @@
     uint8_t field_scan[16];
     uint8_t field_scan8x8[64];
     uint8_t field_scan8x8_cavlc[64];
-    const uint8_t *zigzag_scan_q0;
-    const uint8_t *zigzag_scan8x8_q0;
-    const uint8_t *zigzag_scan8x8_cavlc_q0;
-    const uint8_t *field_scan_q0;
-    const uint8_t *field_scan8x8_q0;
-    const uint8_t *field_scan8x8_cavlc_q0;
+    uint8_t zigzag_scan_q0[16];
+    uint8_t zigzag_scan8x8_q0[64];
+    uint8_t zigzag_scan8x8_cavlc_q0[64];
+    uint8_t field_scan_q0[16];
+    uint8_t field_scan8x8_q0[64];
+    uint8_t field_scan8x8_cavlc_q0[64];
 
     int x264_build;
 
@@ -510,7 +513,7 @@
     struct H264Context *thread_context[MAX_THREADS];
 
     /**
-     * current slice number, used to initalize slice_num of each thread/context
+     * current slice number, used to initialize slice_num of each thread/context
      */
     int current_slice;
 
@@ -569,6 +572,18 @@
      * frames.
      */
     int sei_recovery_frame_cnt;
+    /**
+     * recovery_frame is the frame_num at which the next frame should
+     * be fully constructed.
+     *
+     * Set to -1 when not expecting a recovery point.
+     */
+    int recovery_frame;
+
+    /**
+     * Are the SEI recovery points looking valid.
+     */
+    int valid_recovery_point;
 
     int luma_weight_flag[2];    ///< 7.4.3.2 luma_weight_lX_flag
     int chroma_weight_flag[2];  ///< 7.4.3.2 chroma_weight_lX_flag
@@ -578,9 +593,17 @@
     int initial_cpb_removal_delay[32];  ///< Initial timestamps for CPBs
 
     int cur_chroma_format_idc;
+
+    int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low
+
+    int sync;                      ///< did we had a keyframe or recovery point
+
+    uint8_t parse_history[4];
+    int parse_history_count;
+    int parse_last_mb;
 } H264Context;
 
-extern const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM + 1]; ///< One chroma qp table for each supported bit depth (8, 9, 10).
+extern const uint8_t ff_h264_chroma_qp[7][QP_MAX_NUM + 1]; ///< One chroma qp table for each possible bit depth (8-14).
 extern const uint16_t ff_h264_mb_sizes[4];
 
 /**
@@ -663,7 +686,7 @@
 
 void ff_h264_hl_decode_mb(H264Context *h);
 int ff_h264_frame_start(H264Context *h);
-int ff_h264_decode_extradata(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);
 
diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c
index 92c1c03..a37094b 100644
--- a/libavcodec/h264_cabac.c
+++ b/libavcodec/h264_cabac.c
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... cabac decoding
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,6 +26,7 @@
  */
 
 #define CABAC 1
+#define UNCHECKED_BITSTREAM_READER 1
 
 #include "config.h"
 #include "cabac.h"
@@ -37,14 +38,12 @@
 #include "h264data.h"
 #include "h264_mvpred.h"
 #include "golomb.h"
+#include "libavutil/avassert.h"
 
 #if ARCH_X86
 #include "x86/h264_i386.h"
 #endif
 
-//#undef NDEBUG
-#include <assert.h>
-
 /* Cabac pre state table */
 
 static const int8_t cabac_context_init_I[1024][2] =
@@ -1623,7 +1622,6 @@
     cc.range     = h->cabac.range;
     cc.low       = h->cabac.low;
     cc.bytestream= h->cabac.bytestream;
-    cc.bytestream_end = h->cabac.bytestream_end;
 #else
 #define CC &h->cabac
 #endif
@@ -1672,7 +1670,7 @@
         }
 #endif
     }
-    assert(coeff_count > 0);
+    av_assert2(coeff_count > 0);
 
     if( is_dc ) {
         if( cat == 3 )
@@ -1684,11 +1682,12 @@
         if( max_coeff == 64 )
             fill_rectangle(&h->non_zero_count_cache[scan8[n]], 2, 2, 8, coeff_count, 1);
         else {
-            assert( cat == 1 || cat ==  2 || cat ==  4 || cat == 7 || cat == 8 || cat == 11 || cat == 12 );
+            av_assert2( cat == 1 || cat ==  2 || cat ==  4 || cat == 7 || cat == 8 || cat == 11 || cat == 12 );
             h->non_zero_count_cache[scan8[n]] = coeff_count;
         }
     }
 
+
 #define STORE_BLOCK(type) \
     do { \
         uint8_t *ctx = coeff_abs_level1_ctx[node_ctx] + abs_level_m1_ctx_base; \
@@ -1732,11 +1731,11 @@
         } \
     } while ( coeff_count );
 
-    if (h->pixel_shift) {
-        STORE_BLOCK(int32_t)
-    } else {
-        STORE_BLOCK(int16_t)
-    }
+        if (h->pixel_shift) {
+            STORE_BLOCK(int32_t)
+        } else {
+            STORE_BLOCK(int16_t)
+        }
 #ifdef CABAC_ON_STACK
             h->cabac.range     = cc.range     ;
             h->cabac.low       = cc.low       ;
@@ -1865,6 +1864,7 @@
     int dct8x8_allowed= h->pps.transform_8x8_mode;
     int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;
     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;
 
@@ -1907,7 +1907,7 @@
 
     if( h->slice_type_nos == AV_PICTURE_TYPE_B ) {
         int ctx = 0;
-        assert(h->slice_type_nos == AV_PICTURE_TYPE_B);
+        av_assert2(h->slice_type_nos == AV_PICTURE_TYPE_B);
 
         if( !IS_DIRECT( h->left_type[LTOP]-1 ) )
             ctx++;
@@ -1960,7 +1960,7 @@
         mb_type= decode_cabac_intra_mb_type(h, 3, 1);
         if(h->slice_type == AV_PICTURE_TYPE_SI && mb_type)
             mb_type--;
-        assert(h->slice_type_nos == AV_PICTURE_TYPE_I);
+        av_assert2(h->slice_type_nos == AV_PICTURE_TYPE_I);
 decode_intra_mb:
         partition_count = 0;
         cbp= i_mb_type_info[mb_type].cbp;
@@ -2005,6 +2005,9 @@
         return 0;
     }
 
+    local_ref_count[0] = h->ref_count[0] << MB_MBAFF;
+    local_ref_count[1] = h->ref_count[1] << MB_MBAFF;
+
     fill_decode_caches(h, mb_type);
 
     if( IS_INTRA( mb_type ) ) {
@@ -2073,11 +2076,10 @@
                 for( i = 0; i < 4; i++ ) {
                     if(IS_DIRECT(h->sub_mb_type[i])) continue;
                     if(IS_DIR(h->sub_mb_type[i], 0, list)){
-                        int rc = h->ref_count[list] << MB_MBAFF;
-                        if (rc > 1) {
+                        if (local_ref_count[list] > 1) {
                             ref[list][i] = decode_cabac_mb_ref( h, list, 4*i );
-                            if (ref[list][i] >= (unsigned) rc) {
-                                av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], rc);
+                            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]);
                                 return -1;
                             }
                         }else
@@ -2159,11 +2161,11 @@
         if(IS_16X16(mb_type)){
             for(list=0; list<h->list_count; list++){
                 if(IS_DIR(mb_type, 0, list)){
-                    int ref, rc = h->ref_count[list] << MB_MBAFF;
-                    if (rc > 1) {
+                    int ref;
+                    if (local_ref_count[list] > 1) {
                         ref= decode_cabac_mb_ref(h, list, 0);
-                        if (ref >= (unsigned) rc) {
-                            av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
+                        if (ref >= (unsigned)local_ref_count[list]) {
+                            av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
                             return -1;
                         }
                     }else
@@ -2187,11 +2189,11 @@
             for(list=0; list<h->list_count; list++){
                     for(i=0; i<2; i++){
                         if(IS_DIR(mb_type, i, list)){
-                            int ref, rc = h->ref_count[list] << MB_MBAFF;
-                            if (rc > 1) {
+                            int ref;
+                            if (local_ref_count[list] > 1) {
                                 ref= decode_cabac_mb_ref( h, list, 8*i );
-                                if (ref >= (unsigned) rc) {
-                                    av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
+                                if (ref >= (unsigned)local_ref_count[list]) {
+                                    av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
                                     return -1;
                                 }
                             }else
@@ -2218,15 +2220,15 @@
                 }
             }
         }else{
-            assert(IS_8X16(mb_type));
+            av_assert2(IS_8X16(mb_type));
             for(list=0; list<h->list_count; list++){
                     for(i=0; i<2; i++){
                         if(IS_DIR(mb_type, i, list)){ //FIXME optimize
-                            int ref, rc = h->ref_count[list] << MB_MBAFF;
-                            if (rc > 1) {
+                            int ref;
+                            if (local_ref_count[list] > 1) {
                                 ref= decode_cabac_mb_ref( h, list, 4*i );
-                                if (ref >= (unsigned) rc) {
-                                    av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
+                                if (ref >= (unsigned)local_ref_count[list]) {
+                                    av_log(s->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, local_ref_count[list]);
                                     return -1;
                                 }
                             }else
diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c
index 8996057..6dfe247 100644
--- a/libavcodec/h264_cavlc.c
+++ b/libavcodec/h264_cavlc.c
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... cavlc bitstream decoding
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,6 +26,7 @@
  */
 
 #define CABAC 0
+#define UNCHECKED_BITSTREAM_READER 1
 
 #include "internal.h"
 #include "avcodec.h"
@@ -34,9 +35,8 @@
 #include "h264data.h" // FIXME FIXME FIXME
 #include "h264_mvpred.h"
 #include "golomb.h"
+#include "libavutil/avassert.h"
 
-//#undef NDEBUG
-#include <assert.h>
 
 static const uint8_t golomb_to_inter_cbp_gray[16]={
  0, 1, 2, 4, 8, 3, 5,10,12,15, 7,11,13,14, 6, 9,
@@ -360,7 +360,7 @@
          * the packed static coeff_token_vlc table sizes
          * were initialized correctly.
          */
-        assert(offset == FF_ARRAY_ELEMS(coeff_token_vlc_tables));
+        av_assert0(offset == FF_ARRAY_ELEMS(coeff_token_vlc_tables));
 
         for(i=0; i<3; i++){
             chroma_dc_total_zeros_vlc[i].table = chroma_dc_total_zeros_vlc_tables[i];
@@ -480,7 +480,7 @@
 
     trailing_ones= coeff_token&3;
     tprintf(h->s.avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff);
-    assert(total_coeff<=16);
+    av_assert2(total_coeff<=16);
 
     i = show_bits(gb, 3);
     skip_bits(gb, trailing_ones);
@@ -512,7 +512,7 @@
                 else
                     level_code= prefix + get_bits(gb, 4); //part
             }else{
-                level_code= 30 + get_bits(gb, prefix-3); //part
+                level_code= 30;
                 if(prefix>=16){
                     if(prefix > 25+3){
                         av_log(h->s.avctx, AV_LOG_ERROR, "Invalid level prefix\n");
@@ -520,6 +520,7 @@
                     }
                     level_code += (1<<(prefix-3))-4096;
                 }
+                level_code += get_bits(gb, prefix-3); //part
             }
 
             if(trailing_ones < 3) level_code += 2;
@@ -637,7 +638,7 @@
             return -1; //FIXME continue if partitioned and other return -1 too
         }
 
-        assert((cbp&15) == 0 || (cbp&15) == 15);
+        av_assert2((cbp&15) == 0 || (cbp&15) == 15);
 
         if(cbp&15){
             for(i8x8=0; i8x8<4; i8x8++){
@@ -699,6 +700,7 @@
     int dct8x8_allowed= h->pps.transform_8x8_mode;
     int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;
     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;
 
@@ -743,7 +745,7 @@
             goto decode_intra_mb;
         }
     }else{
-       assert(h->slice_type_nos == AV_PICTURE_TYPE_I);
+       av_assert2(h->slice_type_nos == AV_PICTURE_TYPE_I);
         if(h->slice_type == AV_PICTURE_TYPE_SI && mb_type)
             mb_type--;
 decode_intra_mb:
@@ -784,6 +786,9 @@
         return 0;
     }
 
+    local_ref_count[0] = h->ref_count[0] << MB_MBAFF;
+    local_ref_count[1] = h->ref_count[1] << MB_MBAFF;
+
     fill_decode_neighbors(h, mb_type);
     fill_decode_caches(h, mb_type);
 
@@ -850,7 +855,7 @@
                 h->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;
             }
         }else{
-            assert(h->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ?
+            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);
                 if(h->sub_mb_type[i] >=4){
@@ -863,7 +868,7 @@
         }
 
         for(list=0; list<h->list_count; list++){
-            int ref_count = IS_REF0(mb_type) ? 1 : h->ref_count[list] << MB_MBAFF;
+            int ref_count= IS_REF0(mb_type) ? 1 : local_ref_count[list];
             for(i=0; i<4; i++){
                 if(IS_DIRECT(h->sub_mb_type[i])) continue;
                 if(IS_DIR(h->sub_mb_type[i], 0, list)){
@@ -943,14 +948,13 @@
             for(list=0; list<h->list_count; list++){
                     unsigned int val;
                     if(IS_DIR(mb_type, 0, list)){
-                        int rc = h->ref_count[list] << MB_MBAFF;
-                        if (rc == 1) {
+                        if(local_ref_count[list]==1){
                             val= 0;
-                        } else if (rc == 2) {
+                        }else if(local_ref_count[list]==2){
                             val= get_bits1(&s->gb)^1;
                         }else{
                             val= get_ue_golomb_31(&s->gb);
-                            if (val >= rc) {
+                            if(val >= local_ref_count[list]){
                                 av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                 return -1;
                             }
@@ -974,14 +978,13 @@
                     for(i=0; i<2; i++){
                         unsigned int val;
                         if(IS_DIR(mb_type, i, list)){
-                            int rc = h->ref_count[list] << MB_MBAFF;
-                            if (rc == 1) {
+                            if(local_ref_count[list] == 1){
                                 val= 0;
-                            } else if (rc == 2) {
+                            }else if(local_ref_count[list] == 2){
                                 val= get_bits1(&s->gb)^1;
                             }else{
                                 val= get_ue_golomb_31(&s->gb);
-                                if (val >= rc) {
+                                if(val >= local_ref_count[list]){
                                     av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                     return -1;
                                 }
@@ -1007,19 +1010,18 @@
                 }
             }
         }else{
-            assert(IS_8X16(mb_type));
+            av_assert2(IS_8X16(mb_type));
             for(list=0; list<h->list_count; list++){
                     for(i=0; i<2; i++){
                         unsigned int val;
                         if(IS_DIR(mb_type, i, list)){ //FIXME optimize
-                            int rc = h->ref_count[list] << MB_MBAFF;
-                            if (rc == 1) {
+                            if(local_ref_count[list]==1){
                                 val= 0;
-                            } else if (rc == 2) {
+                            }else if(local_ref_count[list]==2){
                                 val= get_bits1(&s->gb)^1;
                             }else{
                                 val= get_ue_golomb_31(&s->gb);
-                                if (val >= rc) {
+                                if(val >= local_ref_count[list]){
                                     av_log(h->s.avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
                                     return -1;
                                 }
@@ -1120,12 +1122,15 @@
             if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 2) < 0 ){
                 return -1;
             }
-        } else if (CHROMA422) {
+        } else {
+            const int num_c8x8 = h->sps.chroma_format_idc;
+
             if(cbp&0x30){
                 for(chroma_idx=0; chroma_idx<2; chroma_idx++)
                     if (decode_residual(h, gb, h->mb + ((256 + 16*16*chroma_idx) << pixel_shift),
-                                        CHROMA_DC_BLOCK_INDEX+chroma_idx, chroma422_dc_scan,
-                                        NULL, 8) < 0) {
+                                        CHROMA_DC_BLOCK_INDEX+chroma_idx,
+                                        CHROMA422 ? chroma422_dc_scan : chroma_dc_scan,
+                                        NULL, 4*num_c8x8) < 0) {
                         return -1;
                     }
             }
@@ -1134,34 +1139,12 @@
                 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);
-                    for (i8x8 = 0; i8x8 < 2; i8x8++) {
-                        for (i4x4 = 0; i4x4 < 4; i4x4++) {
-                            const int index = 16 + 16*chroma_idx + 8*i8x8 + i4x4;
+                    for (i8x8=0; i8x8<num_c8x8; i8x8++) {
+                        for (i4x4=0; i4x4<4; i4x4++) {
+                            const int index= 16 + 16*chroma_idx + 8*i8x8 + i4x4;
                             if (decode_residual(h, gb, mb, index, scan + 1, qmul, 15) < 0)
                                 return -1;
-                            mb += 16 << pixel_shift;
-                        }
-                    }
-                }
-            }else{
-                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);
-            }
-        } else /* yuv420 */ {
-            if(cbp&0x30){
-                for(chroma_idx=0; chroma_idx<2; chroma_idx++)
-                    if( decode_residual(h, gb, h->mb + ((256 + 16*16*chroma_idx) << pixel_shift), CHROMA_DC_BLOCK_INDEX+chroma_idx, chroma_dc_scan, NULL, 4) < 0){
-                        return -1;
-                    }
-            }
-
-            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]];
-                    for(i4x4=0; i4x4<4; i4x4++){
-                        const int index= 16 + 16*chroma_idx + i4x4;
-                        if( decode_residual(h, gb, h->mb + (16*index << pixel_shift), index, scan + 1, qmul, 15) < 0){
-                            return -1;
+                            mb += 16<<pixel_shift;
                         }
                     }
                 }
diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c
index cc6e018..ce395a3 100644
--- a/libavcodec/h264_direct.c
+++ b/libavcodec/h264_direct.c
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... direct mb/block decoding
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -89,7 +89,8 @@
             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;
-                    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;
diff --git a/libavcodec/h264_loopfilter.c b/libavcodec/h264_loopfilter.c
index b045d23..7cd9f69 100644
--- a/libavcodec/h264_loopfilter.c
+++ b/libavcodec/h264_loopfilter.c
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... loop filter
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -34,9 +34,6 @@
 #include "mathops.h"
 #include "rectangle.h"
 
-//#undef NDEBUG
-#include <assert.h>
-
 /* Deblocking filter (p153) */
 static const uint8_t alpha_table[52*3] = {
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
@@ -245,7 +242,7 @@
                                                           int pixel_shift)
 {
     MpegEncContext * const s = &h->s;
-    int chroma = !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
+    int chroma = CHROMA && !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
     int chroma444 = CHROMA444;
     int chroma422 = CHROMA422;
 
@@ -418,7 +415,7 @@
 }
 
 void ff_h264_filter_mb_fast( 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) {
-    assert(!FRAME_MBAFF);
+    av_assert2(!FRAME_MBAFF);
     if(!h->h264dsp.h264_loop_filter_strength || h->pps.chroma_qp_diff) {
         ff_h264_filter_mb(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize);
         return;
@@ -583,7 +580,9 @@
             // 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;
                 if( dir == 0 ) {
@@ -666,7 +665,9 @@
         // 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"); }
         if( dir == 0 ) {
             filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, a, b, h, 0 );
             if (chroma) {
@@ -709,7 +710,7 @@
     const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4;
     int first_vertical_edge_done = 0;
     av_unused int dir;
-    int chroma = !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));
+    int chroma = CHROMA && !(CONFIG_GRAY && (s->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;
diff --git a/libavcodec/h264_mb_template.c b/libavcodec/h264_mb_template.c
index 1e5b7f1..b02f566 100644
--- a/libavcodec/h264_mb_template.c
+++ b/libavcodec/h264_mb_template.c
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... decoder
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -99,8 +99,8 @@
     }
 
     if (!SIMPLE && IS_INTRA_PCM(mb_type)) {
+        const int bit_depth = h->sps.bit_depth_luma;
         if (PIXEL_SHIFT) {
-            const int bit_depth = h->sps.bit_depth_luma;
             int j;
             GetBitContext gb;
             init_get_bits(&gb, (uint8_t *)h->mb,
@@ -115,13 +115,10 @@
                 if (!h->sps.chroma_format_idc) {
                     for (i = 0; i < block_h; i++) {
                         uint16_t *tmp_cb = (uint16_t *)(dest_cb + i * uvlinesize);
-                        for (j = 0; j < 8; j++)
-                            tmp_cb[j] = 1 << (bit_depth - 1);
-                    }
-                    for (i = 0; i < block_h; i++) {
                         uint16_t *tmp_cr = (uint16_t *)(dest_cr + i * uvlinesize);
-                        for (j = 0; j < 8; j++)
-                            tmp_cr[j] = 1 << (bit_depth - 1);
+                        for (j = 0; j < 8; j++) {
+                            tmp_cb[j] = tmp_cr[j] = 1 << (bit_depth - 1);
+                        }
                     }
                 } else {
                     for (i = 0; i < block_h; i++) {
@@ -141,9 +138,9 @@
                 memcpy(dest_y + i * linesize, (uint8_t *)h->mb + i * 16, 16);
             if (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
                 if (!h->sps.chroma_format_idc) {
-                    for (i = 0; i < block_h; i++) {
-                        memset(dest_cb + i * uvlinesize, 128, 8);
-                        memset(dest_cr + i * uvlinesize, 128, 8);
+                    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;
@@ -162,8 +159,10 @@
                                uvlinesize, 1, 0, SIMPLE, PIXEL_SHIFT);
 
             if (SIMPLE || !CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+                if (CHROMA) {
                 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,
diff --git a/libavcodec/h264_mc_template.c b/libavcodec/h264_mc_template.c
index a3af39b..a59d6a2 100644
--- a/libavcodec/h264_mc_template.c
+++ b/libavcodec/h264_mc_template.c
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... decoder
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -71,7 +71,7 @@
     const int mb_xy   = h->mb_xy;
     const int mb_type = s->current_picture.f.mb_type[mb_xy];
 
-    assert(IS_INTER(mb_type));
+    av_assert2(IS_INTER(mb_type));
 
     if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
         await_references(h);
@@ -103,7 +103,7 @@
     } else {
         int i;
 
-        assert(IS_8X8(mb_type));
+        av_assert2(IS_8X8(mb_type));
 
         for (i = 0; i < 4; i++) {
             const int sub_mb_type = h->sub_mb_type[i];
@@ -141,7 +141,7 @@
                         IS_DIR(sub_mb_type, 0, 0), IS_DIR(sub_mb_type, 0, 1));
             } else {
                 int j;
-                assert(IS_SUB_4X4(sub_mb_type));
+                av_assert2(IS_SUB_4X4(sub_mb_type));
                 for (j = 0; j < 4; j++) {
                     int sub_x_offset = x_offset + 2 * (j & 1);
                     int sub_y_offset = y_offset + (j & 2);
diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c
index 276751e..2dea933 100644
--- a/libavcodec/h264_mp4toannexb_bsf.c
+++ b/libavcodec/h264_mp4toannexb_bsf.c
@@ -2,20 +2,20 @@
  * H.264 MP4 to Annex B byte stream format filter
  * Copyright (c) 2007 Benoit Fouet <benoit.fouet@free.fr>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -62,10 +62,12 @@
                                    const uint8_t *buf, int      buf_size,
                                    int keyframe) {
     H264BSFContext *ctx = bsfc->priv_data;
+    int i;
     uint8_t unit_type;
     int32_t nal_size;
     uint32_t cumul_size = 0;
     const uint8_t *buf_end = buf + buf_size;
+    int ret = AVERROR(EINVAL);
 
     /* nothing to filter */
     if (!avctx->extradata || avctx->extradata_size < 6) {
@@ -84,17 +86,11 @@
 
         /* retrieve length coded size */
         ctx->length_size = (*extradata++ & 0x3) + 1;
-        if (ctx->length_size == 3)
-            return AVERROR(EINVAL);
 
         /* retrieve sps and pps unit(s) */
         unit_nb = *extradata++ & 0x1f; /* number of sps unit(s) */
         if (!unit_nb) {
-            unit_nb = *extradata++; /* number of pps unit(s) */
-            sps_done++;
-
-            if (unit_nb)
-                pps_seen = 1;
+            goto pps;
         } else {
             sps_seen = 1;
         }
@@ -118,7 +114,7 @@
             memcpy(out+total_size-unit_size-4, nalu_header, 4);
             memcpy(out+total_size-unit_size,   extradata+2, unit_size);
             extradata += 2+unit_size;
-
+pps:
             if (!unit_nb && !sps_done++) {
                 unit_nb = *extradata++; /* number of pps unit(s) */
                 if (unit_nb)
@@ -144,15 +140,12 @@
     *poutbuf_size = 0;
     *poutbuf = NULL;
     do {
+        ret= AVERROR(EINVAL);
         if (buf + ctx->length_size > buf_end)
             goto fail;
 
-        if (ctx->length_size == 1) {
-            nal_size = buf[0];
-        } else if (ctx->length_size == 2) {
-            nal_size = AV_RB16(buf);
-        } else
-            nal_size = AV_RB32(buf);
+        for (nal_size = 0, i = 0; i<ctx->length_size; i++)
+            nal_size = (nal_size << 8) | buf[i];
 
         buf += ctx->length_size;
         unit_type = *buf & 0x1f;
@@ -162,15 +155,15 @@
 
         /* prepend only to the first type 5 NAL unit of an IDR picture */
         if (ctx->first_idr && unit_type == 5) {
-            if (alloc_and_copy(poutbuf, poutbuf_size,
+            if ((ret=alloc_and_copy(poutbuf, poutbuf_size,
                                avctx->extradata, avctx->extradata_size,
-                               buf, nal_size) < 0)
+                               buf, nal_size)) < 0)
                 goto fail;
             ctx->first_idr = 0;
         } else {
-            if (alloc_and_copy(poutbuf, poutbuf_size,
+            if ((ret=alloc_and_copy(poutbuf, poutbuf_size,
                                NULL, 0,
-                               buf, nal_size) < 0)
+                               buf, nal_size)) < 0)
                 goto fail;
             if (!ctx->first_idr && unit_type == 1)
                 ctx->first_idr = 1;
@@ -185,7 +178,7 @@
 fail:
     av_freep(poutbuf);
     *poutbuf_size = 0;
-    return AVERROR(EINVAL);
+    return ret;
 }
 
 AVBitStreamFilter ff_h264_mp4toannexb_bsf = {
diff --git a/libavcodec/h264_mvpred.h b/libavcodec/h264_mvpred.h
index 5244c29..0a405f7 100644
--- a/libavcodec/h264_mvpred.h
+++ b/libavcodec/h264_mvpred.h
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... motion vector predicion
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -31,9 +31,8 @@
 #include "internal.h"
 #include "avcodec.h"
 #include "h264.h"
+#include "libavutil/avassert.h"
 
-//#undef NDEBUG
-#include <assert.h>
 
 static av_always_inline int fetch_diagonal_mv(H264Context *h, const int16_t **C,
                                               int i, int list, int part_width)
@@ -104,7 +103,7 @@
     const int16_t *C;
     int diagonal_ref, match_count;
 
-    assert(part_width == 1 || part_width == 2 || part_width == 4);
+    av_assert2(part_width == 1 || part_width == 2 || part_width == 4);
 
 /* mv_cache
  * B . . A T T T T
@@ -486,7 +485,7 @@
                 } else {
                     int left_typei = s->current_picture.f.mb_type[left_xy[LTOP] + s->mb_stride];
 
-                    assert(left_xy[LTOP] == left_xy[LBOT]);
+                    av_assert2(left_xy[LTOP] == left_xy[LBOT]);
                     if (!((left_typei & type_mask) && (left_type[LTOP] & type_mask))) {
                         h->topleft_samples_available &= 0xDF5F;
                         h->left_samples_available    &= 0x5F5F;
@@ -611,7 +610,7 @@
             int16_t(*mv)[2]       = s->current_picture.f.motion_val[list];
             if (!USES_LIST(mb_type, list))
                 continue;
-            assert(!(IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred));
+            av_assert2(!(IS_DIRECT(mb_type) && !h->direct_spatial_mv_pred));
 
             if (USES_LIST(top_type, list)) {
                 const int b_xy = h->mb2b_xy[top_xy] + 3 * b_stride;
@@ -668,7 +667,7 @@
                 ref_cache[4 - 1 * 8] = topright_type ? LIST_NOT_USED
                                                      : PART_NOT_AVAILABLE;
             }
-            if (ref_cache[4 - 1 * 8] < 0) {
+            if(ref_cache[2 - 1*8] < 0 || ref_cache[4 - 1*8] < 0){
                 if (USES_LIST(topleft_type, list)) {
                     const int b_xy  = h->mb2b_xy[topleft_xy] + 3 + b_stride +
                                       (h->topleft_partition & 2 * b_stride);
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index 0464476..2628195 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... parser
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,38 +25,56 @@
  * @author Michael Niedermayer <michaelni@gmx.at>
  */
 
+#define UNCHECKED_BITSTREAM_READER 1
+
 #include "parser.h"
 #include "h264data.h"
 #include "golomb.h"
 
-#include <assert.h>
-
 
 static int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size)
 {
-    int i;
+    int i, j;
     uint32_t state;
     ParseContext *pc = &(h->s.parse_context);
+    int next_avc= h->is_avc ? 0 : buf_size;
+
 //    mb_addr= pc->mb_addr - 1;
     state= pc->state;
     if(state>13)
         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");
+
     for(i=0; i<buf_size; i++){
+        if(i >= next_avc) {
+            int nalsize = 0;
+            i = next_avc;
+            for(j = 0; j < h->nal_length_size; j++)
+                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);
+                return buf_size;
+            }
+            next_avc= i + nalsize;
+            state= 5;
+        }
+
         if(state==7){
 #if HAVE_FAST_UNALIGNED
         /* we check i<buf_size instead of i+3/7 because its simpler
          * and there should be FF_INPUT_BUFFER_PADDING_SIZE bytes at the end
          */
 #    if HAVE_FAST_64BIT
-            while(i<buf_size && !((~*(const uint64_t*)(buf+i) & (*(const uint64_t*)(buf+i) - 0x0101010101010101ULL)) & 0x8080808080808080ULL))
+            while(i<next_avc && !((~*(const uint64_t*)(buf+i) & (*(const uint64_t*)(buf+i) - 0x0101010101010101ULL)) & 0x8080808080808080ULL))
                 i+=8;
 #    else
-            while(i<buf_size && !((~*(const uint32_t*)(buf+i) & (*(const uint32_t*)(buf+i) - 0x01010101U)) & 0x80808080U))
+            while(i<next_avc && !((~*(const uint32_t*)(buf+i) & (*(const uint32_t*)(buf+i) - 0x01010101U)) & 0x80808080U))
                 i+=4;
 #    endif
 #endif
-            for(; i<buf_size; i++){
+            for(; i<next_avc; i++){
                 if(!buf[i]){
                     state=2;
                     break;
@@ -74,26 +92,41 @@
                     goto found;
                 }
             }else if(v==1 || v==2 || v==5){
-                if(pc->frame_start_found){
-                    state+=8;
-                    continue;
-                }else
-                    pc->frame_start_found = 1;
+                state+=8;
+                continue;
             }
             state= 7;
         }else{
-            if(buf[i] & 0x80)
-                goto found;
-            state= 7;
+            h->parse_history[h->parse_history_count++]= buf[i];
+            if(h->parse_history_count>3){
+                unsigned int mb, last_mb= h->parse_last_mb;
+                GetBitContext gb;
+
+                init_get_bits(&gb, h->parse_history, 8*h->parse_history_count);
+                h->parse_history_count=0;
+                mb= get_ue_golomb_long(&gb);
+                last_mb= h->parse_last_mb;
+                h->parse_last_mb= mb;
+                if(pc->frame_start_found){
+                    if(mb <= last_mb)
+                        goto found;
+                }else
+                    pc->frame_start_found = 1;
+                state= 7;
+            }
         }
     }
     pc->state= state;
+    if(h->is_avc)
+        return next_avc;
     return END_NOT_FOUND;
 
 found:
     pc->state=7;
     pc->frame_start_found= 0;
-    return i-(state&5);
+    if(h->is_avc)
+        return next_avc;
+    return i-(state&5) - 3*(state>7);
 }
 
 /**
@@ -114,6 +147,7 @@
     unsigned int slice_type;
     int state = -1;
     const uint8_t *ptr;
+    int q264 = buf_size >=4 && !memcmp("Q264", buf, 4);
 
     /* set some sane default values */
     s->pict_type = AV_PICTURE_TYPE_I;
@@ -129,12 +163,25 @@
         return 0;
 
     for(;;) {
-        int src_length, dst_length, consumed;
+        int src_length, dst_length, consumed, nalsize = 0;
+        if (h->is_avc) {
+            int i;
+            if (h->nal_length_size >= buf_end - buf) break;
+            nalsize = 0;
+            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);
+                break;
+            }
+            src_length = nalsize;
+        } else {
         buf = avpriv_mpv_find_start_code(buf, buf_end, &state);
         if(buf >= buf_end)
             break;
         --buf;
         src_length = buf_end - buf;
+        }
         switch (state & 0x1f) {
         case NAL_SLICE:
         case NAL_IDR_SLICE:
@@ -162,7 +209,7 @@
             s->key_frame = 1;
             /* fall through */
         case NAL_SLICE:
-            get_ue_golomb(&h->s.gb);  // skip first_mb_in_slice
+            get_ue_golomb_long(&h->s.gb);  // skip first_mb_in_slice
             slice_type = get_ue_golomb_31(&h->s.gb);
             s->pict_type = golomb_to_pict_type[slice_type % 5];
             if (h->sei_recovery_frame_cnt >= 0) {
@@ -230,10 +277,12 @@
 
             return 0; /* no need to evaluate the rest */
         }
-        buf += consumed;
+        buf += h->is_avc ? nalsize : consumed;
     }
+    if (q264)
+        return 0;
     /* didn't find a picture! */
-    av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit\n");
+    av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit with size %d\n", buf_size);
     return -1;
 }
 
@@ -250,14 +299,13 @@
         h->got_first = 1;
         if (avctx->extradata_size) {
             h->s.avctx = avctx;
-            // must be done like in the decoder.
-            // otherwise opening the parser, creating extradata,
-            // and then closing and opening again
+            // 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.
-            // NB: estimate_timings_from_pts behaves exactly like this.
+            // Note that estimate_timings_from_pts does exactly this.
             if (!avctx->has_b_frames)
                 h->s.low_delay = 1;
-            ff_h264_decode_extradata(h);
+            ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size);
         }
     }
 
@@ -273,7 +321,7 @@
         }
 
         if(next<0 && next != END_NOT_FOUND){
-            assert(pc->last_index + next >= 0 );
+            av_assert1(pc->last_index + next >= 0 );
             ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state
         }
     }
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index 7d9d596..cdc6b07 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... parameter set decoding
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -70,7 +70,7 @@
     QP(37,d), QP(37,d), QP(37,d), QP(38,d), QP(38,d), QP(38,d),\
     QP(39,d), QP(39,d), QP(39,d), QP(39,d)
 
-const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM+1] = {
+const uint8_t ff_h264_chroma_qp[7][QP_MAX_NUM+1] = {
     {
         CHROMA_QP_TABLE_END(8)
     },
@@ -83,6 +83,36 @@
         6, 7, 8, 9, 10, 11,
         CHROMA_QP_TABLE_END(10)
     },
+    {
+        0,  1, 2, 3,  4,  5,
+        6,  7, 8, 9, 10, 11,
+        12,13,14,15, 16, 17,
+        CHROMA_QP_TABLE_END(11)
+    },
+    {
+        0,  1, 2, 3,  4,  5,
+        6,  7, 8, 9, 10, 11,
+        12,13,14,15, 16, 17,
+        18,19,20,21, 22, 23,
+        CHROMA_QP_TABLE_END(12)
+    },
+    {
+        0,  1, 2, 3,  4,  5,
+        6,  7, 8, 9, 10, 11,
+        12,13,14,15, 16, 17,
+        18,19,20,21, 22, 23,
+        24,25,26,27, 28, 29,
+        CHROMA_QP_TABLE_END(13)
+    },
+    {
+        0,  1, 2, 3,  4,  5,
+        6,  7, 8, 9, 10, 11,
+        12,13,14,15, 16, 17,
+        18,19,20,21, 22, 23,
+        24,25,26,27, 28, 29,
+        30,31,32,33, 34, 35,
+        CHROMA_QP_TABLE_END(14)
+    },
 };
 
 static const uint8_t default_scaling4[2][16]={
@@ -216,7 +246,8 @@
     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))
+        return 0;
     sps->bitstream_restriction_flag = get_bits1(&s->gb);
     if(sps->bitstream_restriction_flag){
         get_bits1(&s->gb);     /* motion_vectors_over_pic_boundaries_flag */
@@ -237,6 +268,7 @@
             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));
         return AVERROR_INVALIDDATA;
@@ -284,13 +316,11 @@
         decode_scaling_list(h,scaling_matrix4[5],16,default_scaling4[1],scaling_matrix4[4]); // Inter, Cb
         if(is_sps || pps->transform_8x8_mode){
             decode_scaling_list(h,scaling_matrix8[0],64,default_scaling8[0],fallback[2]);  // Intra, Y
-            if(sps->chroma_format_idc == 3){
-                decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[0],scaling_matrix8[0]);  // Intra, Cr
-                decode_scaling_list(h,scaling_matrix8[2],64,default_scaling8[0],scaling_matrix8[1]);  // Intra, Cb
-            }
             decode_scaling_list(h,scaling_matrix8[3],64,default_scaling8[1],fallback[3]);  // Inter, Y
             if(sps->chroma_format_idc == 3){
+                decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[0],scaling_matrix8[0]);  // Intra, Cr
                 decode_scaling_list(h,scaling_matrix8[4],64,default_scaling8[1],scaling_matrix8[3]);  // Inter, Cr
+                decode_scaling_list(h,scaling_matrix8[2],64,default_scaling8[0],scaling_matrix8[1]);  // Intra, Cb
                 decode_scaling_list(h,scaling_matrix8[5],64,default_scaling8[1],scaling_matrix8[4]);  // Inter, Cb
             }
         }
@@ -309,7 +339,9 @@
     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
-    get_bits(&s->gb, 4); // reserved
+    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);
 
@@ -325,21 +357,35 @@
     sps->profile_idc= profile_idc;
     sps->constraint_set_flags = constraint_set_flags;
     sps->level_idc= level_idc;
+    sps->full_range = -1;
 
     memset(sps->scaling_matrix4, 16, sizeof(sps->scaling_matrix4));
     memset(sps->scaling_matrix8, 16, sizeof(sps->scaling_matrix8));
     sps->scaling_matrix_present = 0;
+    sps->colorspace = 2; //AVCOL_SPC_UNSPECIFIED
 
-    if(sps->profile_idc >= 100){ //high profile
+    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->chroma_format_idc= get_ue_golomb_31(&s->gb);
-        if(sps->chroma_format_idc > 3) {
-            av_log(h->s.avctx, AV_LOG_ERROR, "chroma_format_idc (%u) out of range\n", sps->chroma_format_idc);
+        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);
             goto fail;
         } else if(sps->chroma_format_idc == 3) {
             sps->residual_color_transform_flag = get_bits1(&s->gb);
+            if(sps->residual_color_transform_flag) {
+                av_log(h->s.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, sps->bit_depth_chroma);
+            goto fail;
+        }
         sps->transform_bypass = get_bits1(&s->gb);
         decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8);
     }else{
@@ -349,10 +395,21 @@
     }
 
     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);
+        goto fail;
+    }
+
     sps->poc_type= get_ue_golomb_31(&s->gb);
 
     if(sps->poc_type == 0){ //FIXME #define
-        sps->log2_max_poc_lsb= get_ue_golomb(&s->gb) + 4;
+        unsigned t = get_ue_golomb(&s->gb);
+        if(t>12){
+            av_log(h->s.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);
@@ -372,7 +429,7 @@
     }
 
     sps->ref_frame_count= get_ue_golomb_31(&s->gb);
-    if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count >= 32U){
+    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");
         goto fail;
     }
@@ -392,10 +449,6 @@
         sps->mb_aff= 0;
 
     sps->direct_8x8_inference_flag= get_bits1(&s->gb);
-    if(!sps->frame_mbs_only_flag && !sps->direct_8x8_inference_flag){
-        av_log(h->s.avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n");
-        goto fail;
-    }
 
 #ifndef ALLOW_INTERLACE
     if(sps->mb_aff)
@@ -410,10 +463,17 @@
         sps->crop_top   = get_ue_golomb(&s->gb);
         sps->crop_bottom= get_ue_golomb(&s->gb);
         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 ...\n");
+            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);
         }
         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, this could look slightly wrong ...\n");
+            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);
+        /* 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. */
+        sps->crop_left  =
+        sps->crop_right =
+        sps->crop_top   =
+        sps->crop_bottom= 0;
         }
     }else{
         sps->crop_left  =
@@ -432,7 +492,7 @@
 
     if(s->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\n",
+        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",
                sps_id, sps->profile_idc, sps->level_idc,
                sps->poc_type,
                sps->ref_frame_count,
@@ -444,7 +504,9 @@
                sps->vui_parameters_present_flag ? "VUI" : "",
                csp[sps->chroma_format_idc],
                sps->timing_info_present_flag ? sps->num_units_in_tick : 0,
-               sps->timing_info_present_flag ? sps->time_scale : 0
+               sps->timing_info_present_flag ? sps->time_scale : 0,
+               sps->bit_depth_luma,
+               h->sps.bitstream_restriction_flag ? sps->num_reorder_frames : -1
                );
     }
 
@@ -466,6 +528,21 @@
         pps->chroma_qp_table[t][i] = ff_h264_chroma_qp[depth-8][av_clip(i + index, 0, max_qp)];
 }
 
+static int more_rbsp_data_in_pps(H264Context *h, PPS *pps)
+{
+    const SPS *sps = h->sps_buffers[pps->sps_id];
+    int profile_idc = sps->profile_idc;
+
+    if ((profile_idc == 66 || profile_idc == 77 ||
+         profile_idc == 88) && (sps->constraint_set_flags & 7)) {
+        av_log(h->s.avctx, AV_LOG_VERBOSE,
+               "Current profile doesn't provide more RBSP data in PPS, skipping\n");
+        return 0;
+    }
+
+    return 1;
+}
+
 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);
@@ -476,8 +553,11 @@
     if(pps_id >= MAX_PPS_COUNT) {
         av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id);
         return -1;
-    } else if (h->sps.bit_depth_luma > 10) {
-        av_log(h->s.avctx, AV_LOG_ERROR, "Unimplemented luma bit depth=%d (max=10)\n", h->sps.bit_depth_luma);
+    } 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);
+        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);
         return AVERROR_PATCHWELCOME;
     }
 
@@ -552,8 +632,7 @@
     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);
-    if (bits_left && (bits_left > 8 ||
-                      show_bits(&s->gb, bits_left) != 1 << (bits_left - 1))) {
+    if(bits_left > 0 && more_rbsp_data_in_pps(h, pps)){
         pps->transform_8x8_mode= get_bits1(&s->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
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
index 2a71ac1..c15e928 100644
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... reference picture handling
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,7 @@
  * @author Michael Niedermayer <michaelni@gmx.at>
  */
 
+#include "libavutil/avassert.h"
 #include "internal.h"
 #include "dsputil.h"
 #include "avcodec.h"
@@ -300,7 +301,7 @@
 
 void ff_h264_fill_mbaff_ref_list(H264Context *h){
     int list, i, j;
-    for(list=0; list<2; list++){ //FIXME try list_count
+    for(list=0; list<h->list_count; list++){
         for(i=0; i<h->ref_count[list]; i++){
             Picture *frame = &h->ref_list[list][i];
             Picture *field = &h->ref_list[list][16+2*i];
@@ -442,6 +443,9 @@
         h->short_ref[i]= NULL;
     }
     h->short_ref_count=0;
+
+    memset(h->default_ref_list, 0, sizeof(h->default_ref_list));
+    memset(h->ref_list, 0, sizeof(h->ref_list));
 }
 
 /**
@@ -478,10 +482,9 @@
 
 void ff_generate_sliding_window_mmcos(H264Context *h) {
     MpegEncContext * const s = &h->s;
-    assert(h->long_ref_count + h->short_ref_count <= h->sps.ref_frame_count);
 
     h->mmco_index= 0;
-    if(h->short_ref_count && h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count &&
+    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;
@@ -586,6 +589,8 @@
             s->current_picture_ptr->frame_num= 0;
             h->mmco_reset = 1;
             s->current_picture_ptr->mmco_reset=1;
+            for (j = 0; j < MAX_DELAYED_PIC_COUNT; j++)
+                h->last_pocs[j] = INT_MIN;
             break;
         default: assert(0);
         }
@@ -623,8 +628,7 @@
         }
     }
 
-    if (h->long_ref_count + h->short_ref_count -
-            (h->short_ref[0] == s->current_picture_ptr) > h->sps.ref_frame_count){
+    if (h->long_ref_count + h->short_ref_count > FFMAX(h->sps.ref_frame_count, 1)){
 
         /* We have too many reference frames, probably due to corrupted
          * stream. Need to discard one frame. Prevents overrun of the
@@ -651,6 +655,13 @@
 
     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)
+            h->sync = 2;
+    }
+
     return (h->s.avctx->err_recognition & AV_EF_EXPLODE) ? err : 0;
 }
 
diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c
index 2e5fb65..81edeb2 100644
--- a/libavcodec/h264_sei.c
+++ b/libavcodec/h264_sei.c
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... sei decoding
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -47,8 +47,8 @@
 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(&s->gb, h->sps.cpb_removal_delay_length);
-        h->sei_dpb_output_delay = get_bits(&s->gb, h->sps.dpb_output_delay_length);
+        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);
     }
     if(h->sps.pic_struct_present_flag){
         unsigned int i, num_clock_ts;
@@ -111,6 +111,8 @@
     e= sscanf(user_data+16, "x264 - core %d"/*%s - H.264/MPEG-4 AVC codec - Copyleft 2005 - http://www.videolan.org/x264.html*/, &build);
     if(e==1 && build>0)
         h->x264_build= build;
+    if(e==1 && build==1 && !strncmp(user_data+16, "x264 - core 0000", 16))
+        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);
@@ -146,13 +148,13 @@
     // 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(&s->gb, sps->initial_cpb_removal_delay_length);
+            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
         }
     }
     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(&s->gb, sps->initial_cpb_removal_delay_length);
+            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
         }
     }
@@ -169,14 +171,21 @@
 
         type=0;
         do{
+            if (get_bits_left(&s->gb) < 8)
+                return -1;
             type+= show_bits(&s->gb, 8);
         }while(get_bits(&s->gb, 8) == 255);
 
         size=0;
         do{
+            if (get_bits_left(&s->gb) < 8)
+                return -1;
             size+= show_bits(&s->gb, 8);
         }while(get_bits(&s->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);
+
         switch(type){
         case SEI_TYPE_PIC_TIMING: // Picture timing SEI
             if(decode_picture_timing(h) < 0)
diff --git a/libavcodec/h264data.h b/libavcodec/h264data.h
index 5311c21..f3fc7f9 100644
--- a/libavcodec/h264data.h
+++ b/libavcodec/h264data.h
@@ -2,20 +2,20 @@
  * H26L/H264/AVC/JVT/14496-10/... encoder/decoder
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -52,14 +52,14 @@
     17, 18, 20, 24, 19, 21, 26, 28, 23, 27, 29, 30, 22, 25, 38, 41
 };
 
-static const uint8_t zigzag_scan[16] = {
+static const uint8_t zigzag_scan[16+1] = {
     0 + 0 * 4, 1 + 0 * 4, 0 + 1 * 4, 0 + 2 * 4,
     1 + 1 * 4, 2 + 0 * 4, 3 + 0 * 4, 2 + 1 * 4,
     1 + 2 * 4, 0 + 3 * 4, 1 + 3 * 4, 2 + 2 * 4,
     3 + 1 * 4, 3 + 2 * 4, 2 + 3 * 4, 3 + 3 * 4,
 };
 
-static const uint8_t field_scan[16] = {
+static const uint8_t field_scan[16+1] = {
     0 + 0 * 4, 0 + 1 * 4, 1 + 0 * 4, 0 + 2 * 4,
     0 + 3 * 4, 1 + 1 * 4, 1 + 2 * 4, 1 + 3 * 4,
     2 + 0 * 4, 2 + 1 * 4, 2 + 2 * 4, 2 + 3 * 4,
@@ -93,7 +93,7 @@
 };
 
 // zigzag_scan8x8_cavlc[i] = zigzag_scan8x8[(i/4) + 16*(i%4)]
-static const uint8_t zigzag_scan8x8_cavlc[64] = {
+static const uint8_t zigzag_scan8x8_cavlc[64+1] = {
     0 + 0 * 8, 1 + 1 * 8, 1 + 2 * 8, 2 + 2 * 8,
     4 + 1 * 8, 0 + 5 * 8, 3 + 3 * 8, 7 + 0 * 8,
     3 + 4 * 8, 1 + 7 * 8, 5 + 3 * 8, 6 + 3 * 8,
@@ -112,7 +112,7 @@
     5 + 5 * 8, 6 + 5 * 8, 6 + 6 * 8, 7 + 7 * 8,
 };
 
-static const uint8_t field_scan8x8[64] = {
+static const uint8_t field_scan8x8[64+1] = {
     0 + 0 * 8, 0 + 1 * 8, 0 + 2 * 8, 1 + 0 * 8,
     1 + 1 * 8, 0 + 3 * 8, 0 + 4 * 8, 1 + 2 * 8,
     2 + 0 * 8, 1 + 3 * 8, 0 + 5 * 8, 0 + 6 * 8,
@@ -131,7 +131,7 @@
     7 + 4 * 8, 7 + 5 * 8, 7 + 6 * 8, 7 + 7 * 8,
 };
 
-static const uint8_t field_scan8x8_cavlc[64] = {
+static const uint8_t field_scan8x8_cavlc[64+1] = {
     0 + 0 * 8, 1 + 1 * 8, 2 + 0 * 8, 0 + 7 * 8,
     2 + 2 * 8, 2 + 3 * 8, 2 + 4 * 8, 3 + 3 * 8,
     3 + 4 * 8, 4 + 3 * 8, 4 + 4 * 8, 5 + 3 * 8,
diff --git a/libavcodec/h264dsp.c b/libavcodec/h264dsp.c
index 1353c1a..69d0536 100644
--- a/libavcodec/h264dsp.c
+++ b/libavcodec/h264dsp.c
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
  * Copyright (c) 2003-2010 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,6 +26,7 @@
  */
 
 #include <stdint.h>
+#include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "h264dsp.h"
 #include "libavutil/common.h"
@@ -42,6 +43,14 @@
 #include "h264dsp_template.c"
 #undef BIT_DEPTH
 
+#define BIT_DEPTH 12
+#include "h264dsp_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 14
+#include "h264dsp_template.c"
+#undef BIT_DEPTH
+
 void ff_h264dsp_init(H264DSPContext *c, const int bit_depth, const int chroma_format_idc)
 {
 #undef FUNC
@@ -107,7 +116,14 @@
     case 10:
         H264_DSP(10);
         break;
+    case 12:
+        H264_DSP(12);
+        break;
+    case 14:
+        H264_DSP(14);
+        break;
     default:
+        av_assert0(bit_depth<=8);
         H264_DSP(8);
         break;
     }
diff --git a/libavcodec/h264dsp.h b/libavcodec/h264dsp.h
index 248c7d0..45f81a0 100644
--- a/libavcodec/h264dsp.h
+++ b/libavcodec/h264dsp.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2003-2010 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/h264dsp_template.c b/libavcodec/h264dsp_template.c
index 3d99cfc..4d5faf0 100644
--- a/libavcodec/h264dsp_template.c
+++ b/libavcodec/h264dsp_template.c
@@ -1,21 +1,21 @@
 /*
  * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
- * Copyright (c) 2003-2010 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2003-2011 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -35,7 +35,7 @@
 { \
     int y; \
     pixel *block = (pixel*)_block; \
-    stride /= sizeof(pixel); \
+    stride >>= sizeof(pixel)-1; \
     offset <<= (log2_denom + (BIT_DEPTH-8)); \
     if(log2_denom) offset += 1<<(log2_denom-1); \
     for (y = 0; y < height; y++, block += stride) { \
@@ -66,7 +66,7 @@
     int y; \
     pixel *dst = (pixel*)_dst; \
     pixel *src = (pixel*)_src; \
-    stride /= sizeof(pixel); \
+    stride >>= sizeof(pixel)-1; \
     offset <<= (BIT_DEPTH-8); \
     offset = ((offset + 1) | 1) << log2_denom; \
     for (y = 0; y < height; y++, dst += stride, src += stride) { \
@@ -101,12 +101,12 @@
 #undef op_scale2
 #undef H264_WEIGHT
 
-static av_always_inline av_flatten void FUNCC(h264_loop_filter_luma)(uint8_t *_pix, int xstride, int ystride, int inner_iters, int alpha, int beta, int8_t *tc0)
+static av_always_inline av_flatten void FUNCC(h264_loop_filter_luma)(uint8_t *p_pix, int xstride, int ystride, int inner_iters, int alpha, int beta, int8_t *tc0)
 {
-    pixel *pix = (pixel*)_pix;
+    pixel *pix = (pixel*)p_pix;
     int i, d;
-    xstride /= sizeof(pixel);
-    ystride /= sizeof(pixel);
+    xstride >>= sizeof(pixel)-1;
+    ystride >>= sizeof(pixel)-1;
     alpha <<= BIT_DEPTH - 8;
     beta  <<= BIT_DEPTH - 8;
     for( i = 0; i < 4; i++ ) {
@@ -162,12 +162,12 @@
     FUNCC(h264_loop_filter_luma)(pix, sizeof(pixel), stride, 2, alpha, beta, tc0);
 }
 
-static av_always_inline av_flatten void FUNCC(h264_loop_filter_luma_intra)(uint8_t *_pix, int xstride, int ystride, int inner_iters, int alpha, int beta)
+static av_always_inline av_flatten void FUNCC(h264_loop_filter_luma_intra)(uint8_t *p_pix, int xstride, int ystride, int inner_iters, int alpha, int beta)
 {
-    pixel *pix = (pixel*)_pix;
+    pixel *pix = (pixel*)p_pix;
     int d;
-    xstride /= sizeof(pixel);
-    ystride /= sizeof(pixel);
+    xstride >>= sizeof(pixel)-1;
+    ystride >>= sizeof(pixel)-1;
     alpha <<= BIT_DEPTH - 8;
     beta  <<= BIT_DEPTH - 8;
     for( d = 0; d < 4 * inner_iters; d++ ) {
@@ -228,14 +228,14 @@
     FUNCC(h264_loop_filter_luma_intra)(pix, sizeof(pixel), stride, 2, alpha, beta);
 }
 
-static av_always_inline av_flatten void FUNCC(h264_loop_filter_chroma)(uint8_t *_pix, int xstride, int ystride, int inner_iters, int alpha, int beta, int8_t *tc0)
+static av_always_inline av_flatten void FUNCC(h264_loop_filter_chroma)(uint8_t *p_pix, int xstride, int ystride, int inner_iters, int alpha, int beta, int8_t *tc0)
 {
-    pixel *pix = (pixel*)_pix;
+    pixel *pix = (pixel*)p_pix;
     int i, d;
-    xstride /= sizeof(pixel);
-    ystride /= sizeof(pixel);
     alpha <<= BIT_DEPTH - 8;
     beta  <<= BIT_DEPTH - 8;
+    xstride >>= sizeof(pixel)-1;
+    ystride >>= sizeof(pixel)-1;
     for( i = 0; i < 4; i++ ) {
         const int tc = ((tc0[i] - 1) << (BIT_DEPTH - 8)) + 1;
         if( tc <= 0 ) {
@@ -282,12 +282,12 @@
     FUNCC(h264_loop_filter_chroma)(pix, sizeof(pixel), stride, 2, alpha, beta, tc0);
 }
 
-static av_always_inline av_flatten void FUNCC(h264_loop_filter_chroma_intra)(uint8_t *_pix, int xstride, int ystride, int inner_iters, int alpha, int beta)
+static av_always_inline av_flatten void FUNCC(h264_loop_filter_chroma_intra)(uint8_t *p_pix, int xstride, int ystride, int inner_iters, int alpha, int beta)
 {
-    pixel *pix = (pixel*)_pix;
+    pixel *pix = (pixel*)p_pix;
     int d;
-    xstride /= sizeof(pixel);
-    ystride /= sizeof(pixel);
+    xstride >>= sizeof(pixel)-1;
+    ystride >>= sizeof(pixel)-1;
     alpha <<= BIT_DEPTH - 8;
     beta  <<= BIT_DEPTH - 8;
     for( d = 0; d < 4 * inner_iters; d++ ) {
diff --git a/libavcodec/h264idct.c b/libavcodec/h264idct.c
index 1634a00..d92025c 100644
--- a/libavcodec/h264idct.c
+++ b/libavcodec/h264idct.c
@@ -2,20 +2,20 @@
  * H.264 IDCT
  * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,3 +36,11 @@
 #define BIT_DEPTH 10
 #include "h264idct_template.c"
 #undef BIT_DEPTH
+
+#define BIT_DEPTH 12
+#include "h264idct_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 14
+#include "h264idct_template.c"
+#undef BIT_DEPTH
diff --git a/libavcodec/h264idct_template.c b/libavcodec/h264idct_template.c
index 554483c..313732b 100644
--- a/libavcodec/h264idct_template.c
+++ b/libavcodec/h264idct_template.c
@@ -2,20 +2,20 @@
  * H.264 IDCT
  * Copyright (c) 2004-2011 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -52,7 +52,7 @@
     int i;
     pixel *dst = (pixel*)_dst;
     dctcoef *block = (dctcoef*)_block;
-    stride /= sizeof(pixel);
+    stride >>= sizeof(pixel)-1;
 
     block[0] += 1 << 5;
 
@@ -85,7 +85,7 @@
     int i;
     pixel *dst = (pixel*)_dst;
     dctcoef *block = (dctcoef*)_block;
-    stride /= sizeof(pixel);
+    stride >>= sizeof(pixel)-1;
 
     block[0] += 32;
 
@@ -154,11 +154,11 @@
 }
 
 // assumes all AC coefs are 0
-void FUNCC(ff_h264_idct_dc_add)(uint8_t *_dst, DCTELEM *block, int stride){
+void FUNCC(ff_h264_idct_dc_add)(uint8_t *p_dst, DCTELEM *block, int stride){
     int i, j;
     int dc = (((dctcoef*)block)[0] + 32) >> 6;
-    pixel *dst = (pixel*)_dst;
-    stride /= sizeof(pixel);
+    pixel *dst = (pixel*)p_dst;
+    stride >>= sizeof(pixel)-1;
     for( j = 0; j < 4; j++ )
     {
         for( i = 0; i < 4; i++ )
@@ -167,11 +167,11 @@
     }
 }
 
-void FUNCC(ff_h264_idct8_dc_add)(uint8_t *_dst, DCTELEM *block, int stride){
+void FUNCC(ff_h264_idct8_dc_add)(uint8_t *p_dst, DCTELEM *block, int stride){
     int i, j;
     int dc = (((dctcoef*)block)[0] + 32) >> 6;
-    pixel *dst = (pixel*)_dst;
-    stride /= sizeof(pixel);
+    pixel *dst = (pixel*)p_dst;
+    stride >>= sizeof(pixel)-1;
     for( j = 0; j < 8; j++ )
     {
         for( i = 0; i < 8; i++ )
@@ -248,13 +248,13 @@
  * IDCT transforms the 16 dc values and dequantizes them.
  * @param qmul quantization parameter
  */
-void FUNCC(ff_h264_luma_dc_dequant_idct)(DCTELEM *_output, DCTELEM *_input, int qmul){
+void FUNCC(ff_h264_luma_dc_dequant_idct)(DCTELEM *p_output, DCTELEM *p_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*)_input;
-    dctcoef *output = (dctcoef*)_output;
+    dctcoef *input = (dctcoef*)p_input;
+    dctcoef *output = (dctcoef*)p_output;
 
     for(i=0; i<4; i++){
         const int z0= input[4*i+0] + input[4*i+1];
diff --git a/libavcodec/h264pred.c b/libavcodec/h264pred.c
index fb44046..5619efd 100644
--- a/libavcodec/h264pred.c
+++ b/libavcodec/h264pred.c
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,7 @@
  * @author Michael Niedermayer <michaelni@gmx.at>
  */
 
+#include "libavutil/avassert.h"
 #include "h264pred.h"
 
 #define BIT_DEPTH 8
@@ -39,6 +40,14 @@
 #include "h264pred_template.c"
 #undef BIT_DEPTH
 
+#define BIT_DEPTH 12
+#include "h264pred_template.c"
+#undef BIT_DEPTH
+
+#define BIT_DEPTH 14
+#include "h264pred_template.c"
+#undef BIT_DEPTH
+
 static void pred4x4_vertical_vp8_c(uint8_t *src, const uint8_t *topright, int stride){
     const unsigned lt = src[-1-1*stride];
     LOAD_TOP_EDGE
@@ -527,7 +536,14 @@
         case 10:
             H264_PRED(10)
             break;
+        case 12:
+            H264_PRED(12)
+            break;
+        case 14:
+            H264_PRED(14)
+            break;
         default:
+            av_assert0(bit_depth<=8);
             H264_PRED(8)
             break;
     }
diff --git a/libavcodec/h264pred.h b/libavcodec/h264pred.h
index a964ae3..d68f39b 100644
--- a/libavcodec/h264pred.h
+++ b/libavcodec/h264pred.h
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/h264pred_template.c b/libavcodec/h264pred_template.c
index 19100b6..3a1b1cf 100644
--- a/libavcodec/h264pred_template.c
+++ b/libavcodec/h264pred_template.c
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
  * Copyright (c) 2003-2011 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -31,7 +31,7 @@
 
 static void FUNCC(pred4x4_vertical)(uint8_t *_src, const uint8_t *topright, int _stride){
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     const pixel4 a= AV_RN4PA(src-stride);
 
     AV_WN4PA(src+0*stride, a);
@@ -42,7 +42,7 @@
 
 static void FUNCC(pred4x4_horizontal)(uint8_t *_src, const uint8_t *topright, int _stride){
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     AV_WN4PA(src+0*stride, PIXEL_SPLAT_X4(src[-1+0*stride]));
     AV_WN4PA(src+1*stride, PIXEL_SPLAT_X4(src[-1+1*stride]));
     AV_WN4PA(src+2*stride, PIXEL_SPLAT_X4(src[-1+2*stride]));
@@ -51,7 +51,7 @@
 
 static void FUNCC(pred4x4_dc)(uint8_t *_src, const uint8_t *topright, int _stride){
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     const int dc= (  src[-stride] + src[1-stride] + src[2-stride] + src[3-stride]
                    + src[-1+0*stride] + src[-1+1*stride] + src[-1+2*stride] + src[-1+3*stride] + 4) >>3;
     const pixel4 a = PIXEL_SPLAT_X4(dc);
@@ -64,7 +64,7 @@
 
 static void FUNCC(pred4x4_left_dc)(uint8_t *_src, const uint8_t *topright, int _stride){
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     const int dc= (  src[-1+0*stride] + src[-1+1*stride] + src[-1+2*stride] + src[-1+3*stride] + 2) >>2;
     const pixel4 a = PIXEL_SPLAT_X4(dc);
 
@@ -76,7 +76,7 @@
 
 static void FUNCC(pred4x4_top_dc)(uint8_t *_src, const uint8_t *topright, int _stride){
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     const int dc= (  src[-stride] + src[1-stride] + src[2-stride] + src[3-stride] + 2) >>2;
     const pixel4 a = PIXEL_SPLAT_X4(dc);
 
@@ -88,7 +88,7 @@
 
 static void FUNCC(pred4x4_128_dc)(uint8_t *_src, const uint8_t *topright, int _stride){
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     const pixel4 a = PIXEL_SPLAT_X4(1<<(BIT_DEPTH-1));
 
     AV_WN4PA(src+0*stride, a);
@@ -99,7 +99,7 @@
 
 static void FUNCC(pred4x4_127_dc)(uint8_t *_src, const uint8_t *topright, int _stride){
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     const pixel4 a = PIXEL_SPLAT_X4((1<<(BIT_DEPTH-1))-1);
 
     AV_WN4PA(src+0*stride, a);
@@ -110,7 +110,7 @@
 
 static void FUNCC(pred4x4_129_dc)(uint8_t *_src, const uint8_t *topright, int _stride){
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     const pixel4 a = PIXEL_SPLAT_X4((1<<(BIT_DEPTH-1))+1);
 
     AV_WN4PA(src+0*stride, a);
@@ -146,7 +146,7 @@
 
 static void FUNCC(pred4x4_down_right)(uint8_t *_src, const uint8_t *topright, int _stride){
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     const int lt= src[-1-1*stride];
     LOAD_TOP_EDGE
     LOAD_LEFT_EDGE
@@ -172,7 +172,7 @@
 static void FUNCC(pred4x4_down_left)(uint8_t *_src, const uint8_t *_topright, int _stride){
     pixel *src = (pixel*)_src;
     const pixel *topright = (const pixel*)_topright;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     LOAD_TOP_EDGE
     LOAD_TOP_RIGHT_EDGE
 //    LOAD_LEFT_EDGE
@@ -197,7 +197,7 @@
 
 static void FUNCC(pred4x4_vertical_right)(uint8_t *_src, const uint8_t *topright, int _stride){
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     const int lt= src[-1-1*stride];
     LOAD_TOP_EDGE
     LOAD_LEFT_EDGE
@@ -223,7 +223,7 @@
 static void FUNCC(pred4x4_vertical_left)(uint8_t *_src, const uint8_t *_topright, int _stride){
     pixel *src = (pixel*)_src;
     const pixel *topright = (const pixel*)_topright;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     LOAD_TOP_EDGE
     LOAD_TOP_RIGHT_EDGE
 
@@ -247,7 +247,7 @@
 
 static void FUNCC(pred4x4_horizontal_up)(uint8_t *_src, const uint8_t *topright, int _stride){
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     LOAD_LEFT_EDGE
 
     src[0+0*stride]=(l0 + l1 + 1)>>1;
@@ -270,7 +270,7 @@
 
 static void FUNCC(pred4x4_horizontal_down)(uint8_t *_src, const uint8_t *topright, int _stride){
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     const int lt= src[-1-1*stride];
     LOAD_TOP_EDGE
     LOAD_LEFT_EDGE
@@ -296,7 +296,7 @@
 static void FUNCC(pred16x16_vertical)(uint8_t *_src, int _stride){
     int i;
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     const pixel4 a = AV_RN4PA(((pixel4*)(src-stride))+0);
     const pixel4 b = AV_RN4PA(((pixel4*)(src-stride))+1);
     const pixel4 c = AV_RN4PA(((pixel4*)(src-stride))+2);
@@ -313,7 +313,7 @@
 static void FUNCC(pred16x16_horizontal)(uint8_t *_src, int stride){
     int i;
     pixel *src = (pixel*)_src;
-    stride /= sizeof(pixel);
+    stride >>= sizeof(pixel)-1;
 
     for(i=0; i<16; i++){
         const pixel4 a = PIXEL_SPLAT_X4(src[-1+i*stride]);
@@ -338,7 +338,7 @@
     int i, dc=0;
     pixel *src = (pixel*)_src;
     pixel4 dcsplat;
-    stride /= sizeof(pixel);
+    stride >>= sizeof(pixel)-1;
 
     for(i=0;i<16; i++){
         dc+= src[-1+i*stride];
@@ -356,7 +356,7 @@
     int i, dc=0;
     pixel *src = (pixel*)_src;
     pixel4 dcsplat;
-    stride /= sizeof(pixel);
+    stride >>= sizeof(pixel)-1;
 
     for(i=0;i<16; i++){
         dc+= src[-1+i*stride];
@@ -370,7 +370,7 @@
     int i, dc=0;
     pixel *src = (pixel*)_src;
     pixel4 dcsplat;
-    stride /= sizeof(pixel);
+    stride >>= sizeof(pixel)-1;
 
     for(i=0;i<16; i++){
         dc+= src[i-stride];
@@ -384,7 +384,7 @@
 static void FUNCC(pred16x16_##n##_dc)(uint8_t *_src, int stride){\
     int i;\
     pixel *src = (pixel*)_src;\
-    stride /= sizeof(pixel);\
+    stride >>= sizeof(pixel)-1;\
     PREDICT_16x16_DC(PIXEL_SPLAT_X4(v));\
 }
 
@@ -392,12 +392,12 @@
 PRED16x16_X(128, (1<<(BIT_DEPTH-1))+0)
 PRED16x16_X(129, (1<<(BIT_DEPTH-1))+1)
 
-static inline void FUNCC(pred16x16_plane_compat)(uint8_t *_src, int _stride, const int svq3, const int rv40){
+static inline void FUNCC(pred16x16_plane_compat)(uint8_t *p_src, int p_stride, const int svq3, const int rv40){
   int i, j, k;
   int a;
   INIT_CLIP
-  pixel *src = (pixel*)_src;
-  int stride = _stride/sizeof(pixel);
+  pixel *src = (pixel*)p_src;
+  int stride = p_stride>>(sizeof(pixel)-1);
   const pixel * const src0 = src +7-stride;
   const pixel *       src1 = src +8*stride-1;
   const pixel *       src2 = src1-2*stride;    // == src+6*stride-1;
@@ -444,7 +444,7 @@
 static void FUNCC(pred8x8_vertical)(uint8_t *_src, int _stride){
     int i;
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     const pixel4 a= AV_RN4PA(((pixel4*)(src-stride))+0);
     const pixel4 b= AV_RN4PA(((pixel4*)(src-stride))+1);
 
@@ -470,7 +470,7 @@
 static void FUNCC(pred8x8_horizontal)(uint8_t *_src, int stride){
     int i;
     pixel *src = (pixel*)_src;
-    stride /= sizeof(pixel);
+    stride >>= sizeof(pixel)-1;
 
     for(i=0; i<8; i++){
         const pixel4 a = PIXEL_SPLAT_X4(src[-1+i*stride]);
@@ -495,7 +495,7 @@
     int i;\
     const pixel4 a = PIXEL_SPLAT_X4(v);\
     pixel *src = (pixel*)_src;\
-    stride /= sizeof(pixel);\
+    stride >>= sizeof(pixel)-1;\
     for(i=0; i<8; i++){\
         AV_WN4PA(((pixel4*)(src+i*stride))+0, a);\
         AV_WN4PA(((pixel4*)(src+i*stride))+1, a);\
@@ -516,7 +516,7 @@
     int dc0, dc2;
     pixel4 dc0splat, dc2splat;
     pixel *src = (pixel*)_src;
-    stride /= sizeof(pixel);
+    stride >>= sizeof(pixel)-1;
 
     dc0=dc2=0;
     for(i=0;i<4; i++){
@@ -546,7 +546,7 @@
     int dc0, dc1;
     pixel4 dc0splat, dc1splat;
     pixel *src = (pixel*)_src;
-    stride /= sizeof(pixel);
+    stride >>= sizeof(pixel)-1;
 
     dc0=dc1=0;
     for(i=0;i<4; i++){
@@ -592,7 +592,7 @@
     int dc0, dc1, dc2;
     pixel4 dc0splat, dc1splat, dc2splat, dc3splat;
     pixel *src = (pixel*)_src;
-    stride /= sizeof(pixel);
+    stride >>= sizeof(pixel)-1;
 
     dc0=dc1=dc2=0;
     for(i=0;i<4; i++){
@@ -657,6 +657,7 @@
     }
 }
 
+//the following 4 function should not be optimized!
 static void FUNC(pred8x8_mad_cow_dc_l0t)(uint8_t *src, int stride){
     FUNCC(pred8x8_top_dc)(src, stride);
     FUNCC(pred4x4_dc)(src, NULL, stride);
@@ -706,7 +707,7 @@
   int a;
   INIT_CLIP
   pixel *src = (pixel*)_src;
-  int stride = _stride/sizeof(pixel);
+  int stride = _stride>>(sizeof(pixel)-1);
   const pixel * const src0 = src +3-stride;
   const pixel *       src1 = src +4*stride-1;
   const pixel *       src2 = src1-2*stride;    // == src+2*stride-1;
@@ -818,32 +819,32 @@
 static void FUNCC(pred8x8l_128_dc)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
 {
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
 
     PREDICT_8x8_DC(PIXEL_SPLAT_X4(1<<(BIT_DEPTH-1)));
 }
 static void FUNCC(pred8x8l_left_dc)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
 {
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
 
     PREDICT_8x8_LOAD_LEFT;
     const pixel4 dc = PIXEL_SPLAT_X4((l0+l1+l2+l3+l4+l5+l6+l7+4) >> 3);
     PREDICT_8x8_DC(dc);
 }
-static void FUNCC(pred8x8l_top_dc)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
+static void FUNCC(pred8x8l_top_dc)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride)
 {
-    pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    pixel *src = (pixel*)p_src;
+    int stride = p_stride>>(sizeof(pixel)-1);
 
     PREDICT_8x8_LOAD_TOP;
     const pixel4 dc = PIXEL_SPLAT_X4((t0+t1+t2+t3+t4+t5+t6+t7+4) >> 3);
     PREDICT_8x8_DC(dc);
 }
-static void FUNCC(pred8x8l_dc)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
+static void FUNCC(pred8x8l_dc)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride)
 {
-    pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    pixel *src = (pixel*)p_src;
+    int stride = p_stride>>(sizeof(pixel)-1);
 
     PREDICT_8x8_LOAD_LEFT;
     PREDICT_8x8_LOAD_TOP;
@@ -851,10 +852,10 @@
                                      +t0+t1+t2+t3+t4+t5+t6+t7+8) >> 4);
     PREDICT_8x8_DC(dc);
 }
-static void FUNCC(pred8x8l_horizontal)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
+static void FUNCC(pred8x8l_horizontal)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride)
 {
-    pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    pixel *src = (pixel*)p_src;
+    int stride = p_stride>>(sizeof(pixel)-1);
     pixel4 a;
 
     PREDICT_8x8_LOAD_LEFT;
@@ -868,7 +869,7 @@
 {
     int y;
     pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    int stride = _stride>>(sizeof(pixel)-1);
     pixel4 a, b;
 
     PREDICT_8x8_LOAD_TOP;
@@ -887,10 +888,10 @@
         AV_WN4PA(((pixel4*)(src+y*stride))+1, b);
     }
 }
-static void FUNCC(pred8x8l_down_left)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
+static void FUNCC(pred8x8l_down_left)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride)
 {
-    pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    pixel *src = (pixel*)p_src;
+    int stride = p_stride>>(sizeof(pixel)-1);
     PREDICT_8x8_LOAD_TOP;
     PREDICT_8x8_LOAD_TOPRIGHT;
     SRC(0,0)= (t0 + 2*t1 + t2 + 2) >> 2;
@@ -909,10 +910,10 @@
     SRC(6,7)=SRC(7,6)= (t13 + 2*t14 + t15 + 2) >> 2;
     SRC(7,7)= (t14 + 3*t15 + 2) >> 2;
 }
-static void FUNCC(pred8x8l_down_right)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
+static void FUNCC(pred8x8l_down_right)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride)
 {
-    pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    pixel *src = (pixel*)p_src;
+    int stride = p_stride>>(sizeof(pixel)-1);
     PREDICT_8x8_LOAD_TOP;
     PREDICT_8x8_LOAD_LEFT;
     PREDICT_8x8_LOAD_TOPLEFT;
@@ -932,10 +933,10 @@
     SRC(6,0)=SRC(7,1)= (t4 + 2*t5 + t6 + 2) >> 2;
     SRC(7,0)= (t5 + 2*t6 + t7 + 2) >> 2;
 }
-static void FUNCC(pred8x8l_vertical_right)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
+static void FUNCC(pred8x8l_vertical_right)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride)
 {
-    pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    pixel *src = (pixel*)p_src;
+    int stride = p_stride>>(sizeof(pixel)-1);
     PREDICT_8x8_LOAD_TOP;
     PREDICT_8x8_LOAD_LEFT;
     PREDICT_8x8_LOAD_TOPLEFT;
@@ -962,10 +963,10 @@
     SRC(7,1)= (t5 + 2*t6 + t7 + 2) >> 2;
     SRC(7,0)= (t6 + t7 + 1) >> 1;
 }
-static void FUNCC(pred8x8l_horizontal_down)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
+static void FUNCC(pred8x8l_horizontal_down)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride)
 {
-    pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    pixel *src = (pixel*)p_src;
+    int stride = p_stride>>(sizeof(pixel)-1);
     PREDICT_8x8_LOAD_TOP;
     PREDICT_8x8_LOAD_LEFT;
     PREDICT_8x8_LOAD_TOPLEFT;
@@ -992,10 +993,10 @@
     SRC(6,0)= (t5 + 2*t4 + t3 + 2) >> 2;
     SRC(7,0)= (t6 + 2*t5 + t4 + 2) >> 2;
 }
-static void FUNCC(pred8x8l_vertical_left)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
+static void FUNCC(pred8x8l_vertical_left)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride)
 {
-    pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    pixel *src = (pixel*)p_src;
+    int stride = p_stride>>(sizeof(pixel)-1);
     PREDICT_8x8_LOAD_TOP;
     PREDICT_8x8_LOAD_TOPRIGHT;
     SRC(0,0)= (t0 + t1 + 1) >> 1;
@@ -1021,10 +1022,10 @@
     SRC(7,6)= (t10 + t11 + 1) >> 1;
     SRC(7,7)= (t10 + 2*t11 + t12 + 2) >> 2;
 }
-static void FUNCC(pred8x8l_horizontal_up)(uint8_t *_src, int has_topleft, int has_topright, int _stride)
+static void FUNCC(pred8x8l_horizontal_up)(uint8_t *p_src, int has_topleft, int has_topright, int p_stride)
 {
-    pixel *src = (pixel*)_src;
-    int stride = _stride/sizeof(pixel);
+    pixel *src = (pixel*)p_src;
+    int stride = p_stride>>(sizeof(pixel)-1);
     PREDICT_8x8_LOAD_LEFT;
     SRC(0,0)= (l0 + l1 + 1) >> 1;
     SRC(1,0)= (l0 + 2*l1 + l2 + 2) >> 2;
@@ -1055,11 +1056,11 @@
 #undef PL
 #undef SRC
 
-static void FUNCC(pred4x4_vertical_add)(uint8_t *_pix, const DCTELEM *_block, int stride){
+static void FUNCC(pred4x4_vertical_add)(uint8_t *p_pix, const DCTELEM *p_block, int stride){
     int i;
-    pixel *pix = (pixel*)_pix;
-    const dctcoef *block = (const dctcoef*)_block;
-    stride /= sizeof(pixel);
+    pixel *pix = (pixel*)p_pix;
+    const dctcoef *block = (const dctcoef*)p_block;
+    stride >>= sizeof(pixel)-1;
     pix -= stride;
     for(i=0; i<4; i++){
         pixel v = pix[0];
@@ -1072,11 +1073,11 @@
     }
 }
 
-static void FUNCC(pred4x4_horizontal_add)(uint8_t *_pix, const DCTELEM *_block, int stride){
+static void FUNCC(pred4x4_horizontal_add)(uint8_t *p_pix, const DCTELEM *p_block, int stride){
     int i;
-    pixel *pix = (pixel*)_pix;
-    const dctcoef *block = (const dctcoef*)_block;
-    stride /= sizeof(pixel);
+    pixel *pix = (pixel*)p_pix;
+    const dctcoef *block = (const dctcoef*)p_block;
+    stride >>= sizeof(pixel)-1;
     for(i=0; i<4; i++){
         pixel v = pix[-1];
         pix[0]= v += block[0];
@@ -1088,11 +1089,11 @@
     }
 }
 
-static void FUNCC(pred8x8l_vertical_add)(uint8_t *_pix, const DCTELEM *_block, int stride){
+static void FUNCC(pred8x8l_vertical_add)(uint8_t *p_pix, const DCTELEM *p_block, int stride){
     int i;
-    pixel *pix = (pixel*)_pix;
-    const dctcoef *block = (const dctcoef*)_block;
-    stride /= sizeof(pixel);
+    pixel *pix = (pixel*)p_pix;
+    const dctcoef *block = (const dctcoef*)p_block;
+    stride >>= sizeof(pixel)-1;
     pix -= stride;
     for(i=0; i<8; i++){
         pixel v = pix[0];
@@ -1109,11 +1110,11 @@
     }
 }
 
-static void FUNCC(pred8x8l_horizontal_add)(uint8_t *_pix, const DCTELEM *_block, int stride){
+static void FUNCC(pred8x8l_horizontal_add)(uint8_t *p_pix, const DCTELEM *p_block, int stride){
     int i;
-    pixel *pix = (pixel*)_pix;
-    const dctcoef *block = (const dctcoef*)_block;
-    stride /= sizeof(pixel);
+    pixel *pix = (pixel*)p_pix;
+    const dctcoef *block = (const dctcoef*)p_block;
+    stride >>= sizeof(pixel)-1;
     for(i=0; i<8; i++){
         pixel v = pix[-1];
         pix[0]= v += block[0];
diff --git a/libavcodec/huffman.c b/libavcodec/huffman.c
index aef4929..27fed9f 100644
--- a/libavcodec/huffman.c
+++ b/libavcodec/huffman.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2006 Konstantin Shishkov
  * Copyright (c) 2007 Loren Merritt
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -153,18 +153,19 @@
     cur_node = nb_codes;
     nodes[nb_codes*2-1].count = 0;
     for (i = 0; i < nb_codes * 2 - 1; i += 2) {
-        nodes[cur_node].sym = HNODE;
-        nodes[cur_node].count = nodes[i].count + nodes[i + 1].count;
-        nodes[cur_node].n0 = i;
-        for (j = cur_node; j > 0; j--) {
-            if (nodes[j].count > nodes[j - 1].count ||
-                (nodes[j].count == nodes[j - 1].count &&
-                 (!(flags & FF_HUFFMAN_FLAG_HNODE_FIRST) ||
-                  nodes[j].n0 == j - 1 || nodes[j].n0 == j - 2 ||
-                  (nodes[j].sym!=HNODE && nodes[j-1].sym!=HNODE))))
+        uint32_t cur_count = nodes[i].count + nodes[i+1].count;
+        // find correct place to insert new node, and
+        // make space for the new node while at it
+        for(j = cur_node; j > i + 2; j--){
+            if(cur_count > nodes[j-1].count ||
+               (cur_count == nodes[j-1].count &&
+                !(flags & FF_HUFFMAN_FLAG_HNODE_FIRST)))
                 break;
-            FFSWAP(Node, nodes[j], nodes[j - 1]);
+            nodes[j] = nodes[j - 1];
         }
+        nodes[j].sym = HNODE;
+        nodes[j].count = cur_count;
+        nodes[j].n0 = i;
         cur_node++;
     }
     if (build_huff_tree(vlc, nodes, nb_codes * 2 - 2, flags) < 0) {
diff --git a/libavcodec/huffman.h b/libavcodec/huffman.h
index 043e6e3..4f9ccba 100644
--- a/libavcodec/huffman.h
+++ b/libavcodec/huffman.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2007  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c
index 3da1de8..6e88114 100644
--- a/libavcodec/huffyuv.c
+++ b/libavcodec/huffyuv.c
@@ -6,20 +6,20 @@
  * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of
  * the algorithm used
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,6 +29,7 @@
  */
 
 #include "avcodec.h"
+#include "internal.h"
 #include "get_bits.h"
 #include "put_bits.h"
 #include "dsputil.h"
@@ -87,14 +88,16 @@
 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
+  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
+  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] = {
@@ -136,7 +139,7 @@
 };
 
 static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst,
-                                      uint8_t *src, int w, int left)
+                                      const uint8_t *src, int w, int left)
 {
     int i;
     if (w < 32) {
@@ -158,25 +161,28 @@
 }
 
 static inline void sub_left_prediction_bgr32(HYuvContext *s, uint8_t *dst,
-                                             uint8_t *src, int w,
-                                             int *red, int *green, int *blue)
+                                             const uint8_t *src, int w,
+                                             int *red, int *green, int *blue, int *alpha)
 {
     int i;
-    int r,g,b;
+    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);
@@ -184,6 +190,32 @@
     *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)
@@ -378,7 +410,7 @@
 
     s->width = avctx->width;
     s->height = avctx->height;
-    assert(s->width>0 && s->height>0);
+    av_assert1(s->width > 0 && s->height > 0);
 
     return 0;
 }
@@ -392,6 +424,7 @@
     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;
@@ -477,6 +510,11 @@
         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;
+    }
+
     alloc_temp(s);
 
     return 0;
@@ -519,8 +557,8 @@
         for (; i < 256 && len[i] == val && repeat < 255; i++)
             repeat++;
 
-        assert(val < 32 && val >0 && repeat<256 && repeat>0);
-        if ( repeat > 7) {
+        av_assert0(val < 32 && val >0 && repeat<256 && repeat>0);
+        if (repeat > 7) {
             buf[index++] = val;
             buf[index++] = repeat;
         } else {
@@ -546,12 +584,17 @@
 
     switch (avctx->pix_fmt) {
     case AV_PIX_FMT_YUV420P:
-        s->bitstream_bpp = 12;
-        break;
     case AV_PIX_FMT_YUV422P:
-        s->bitstream_bpp = 16;
+        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:
@@ -855,27 +898,30 @@
     }
 }
 
-static int encode_bgr_bitstream(HYuvContext *s, int count)
+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) < 3 * 4 * count) {
+    if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < 4*planes*count) {
         av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
         return -1;
     }
 
 #define LOAD3\
-            int g =  s->temp[0][4 * i + G];\
-            int b = (s->temp[0][4 * i + B] - g) & 0xff;\
-            int r = (s->temp[0][4 * i + R] - g) & 0xff;
+            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]++;
+            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]);
+            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)) {
@@ -1231,11 +1277,8 @@
     AVFrame * const p = &s->picture;
     int i, j, size = 0, ret;
 
-    if (!pkt->data &&
-        (ret = av_new_packet(pkt, width * height * 3 * 4 + FF_MIN_BUFFER_SIZE)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error allocating output packet.\n");
+    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;
@@ -1366,25 +1409,50 @@
         const int stride = -p->linesize[0];
         const int fake_stride = -fake_ystride;
         int y;
-        int leftr, leftg, leftb;
+        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]);
-        put_bits(&s->pb, 8, 0);
 
-        sub_left_prediction_bgr32(s, s->temp[0], data + 4, width - 1, &leftr, &leftg, &leftb);
-        encode_bgr_bitstream(s, width - 1);
+        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);
+                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);
+                sub_left_prediction_bgr32(s, s->temp[0], dst, width, &leftr, &leftg, &leftb, &lefta);
             }
-            encode_bgr_bitstream(s, width);
+            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");
@@ -1480,7 +1548,7 @@
     .encode2        = encode_frame,
     .close          = encode_end,
     .pix_fmts       = (const enum AVPixelFormat[]){
-        AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE
+        AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE
     },
     .long_name      = NULL_IF_CONFIG_SMALL("Huffyuv / HuffYUV"),
 };
@@ -1496,7 +1564,7 @@
     .encode2        = encode_frame,
     .close          = encode_end,
     .pix_fmts       = (const enum AVPixelFormat[]){
-        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE
     },
     .long_name      = NULL_IF_CONFIG_SMALL("Huffyuv FFmpeg variant"),
 };
diff --git a/libavcodec/idcinvideo.c b/libavcodec/idcinvideo.c
index 476b628..f9fe925 100644
--- a/libavcodec/idcinvideo.c
+++ b/libavcodec/idcinvideo.c
@@ -2,20 +2,20 @@
  * id Quake II CIN Video Decoder
  * Copyright (C) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -167,6 +167,7 @@
         huff_build_tree(s, i);
     }
 
+    avcodec_get_frame_defaults(&s->frame);
     s->frame.data[0] = NULL;
 
     return 0;
diff --git a/libavcodec/iff.c b/libavcodec/iff.c
index 69efa2e..3940a0c 100644
--- a/libavcodec/iff.c
+++ b/libavcodec/iff.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2010 Peter Ross <pross@xvid.org>
  * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,10 +30,28 @@
 #include "avcodec.h"
 #include "get_bits.h"
 
+// TODO: masking bits
+typedef enum {
+    MASK_NONE,
+    MASK_HAS_MASK,
+    MASK_HAS_TRANSPARENT_COLOR,
+    MASK_LASSO
+} mask_type;
+
 typedef struct {
     AVFrame frame;
     int planesize;
     uint8_t * planebuf;
+    uint8_t * ham_buf;      ///< temporary buffer for planar to chunky conversation
+    uint32_t *ham_palbuf;   ///< HAM decode table
+    uint32_t *mask_buf;     ///< temporary buffer for palette indices
+    uint32_t *mask_palbuf;  ///< masking palette table
+    unsigned  compression;  ///< delta compression method used
+    unsigned  bpp;          ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
+    unsigned  ham;          ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
+    unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
+    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
 } IffContext;
 
@@ -121,19 +139,27 @@
  */
 static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
 {
+    IffContext *s = avctx->priv_data;
     int count, i;
+    const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
+    int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
 
     if (avctx->bits_per_coded_sample > 8) {
-        av_log(avctx, AV_LOG_ERROR, "bit_per_coded_sample > 8 not supported\n");
+        av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
         return AVERROR_INVALIDDATA;
     }
 
     count = 1 << avctx->bits_per_coded_sample;
     // If extradata is smaller than actually needed, fill the remaining with black.
-    count = FFMIN(avctx->extradata_size / 3, count);
+    count = FFMIN(palette_size / 3, count);
     if (count) {
         for (i=0; i < count; i++) {
-            pal[i] = 0xFF000000 | AV_RB24( avctx->extradata + i*3 );
+            pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
+        }
+        if (s->flags && count >= 32) { // EHB
+            for (i = 0; i < 32; i++)
+                pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
+            count = FFMAX(count, 64);
         }
     } else { // Create gray-scale color palette for bps < 8
         count = 1 << avctx->bits_per_coded_sample;
@@ -142,6 +168,150 @@
             pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
         }
     }
+    if (s->masking == MASK_HAS_MASK) {
+        memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
+        for (i = 0; i < count; i++)
+            pal[i] &= 0xFFFFFF;
+    } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
+        s->transparency < 1 << avctx->bits_per_coded_sample)
+        pal[s->transparency] &= 0xFFFFFF;
+    return 0;
+}
+
+/**
+ * Extracts the IFF extra context and updates internal
+ * decoder structures.
+ *
+ * @param avctx the AVCodecContext where to extract extra context to
+ * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
+ * @return 0 in case of success, a negative error code otherwise
+ */
+static int extract_header(AVCodecContext *const avctx,
+                          const AVPacket *const avpkt) {
+    const uint8_t *buf;
+    unsigned buf_size;
+    IffContext *s = avctx->priv_data;
+    int palette_size;
+
+    if (avctx->extradata_size < 2) {
+        av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
+        return AVERROR_INVALIDDATA;
+    }
+    palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
+
+    if (avpkt) {
+        int image_size;
+        if (avpkt->size < 2)
+            return AVERROR_INVALIDDATA;
+        image_size = avpkt->size - AV_RB16(avpkt->data);
+        buf = avpkt->data;
+        buf_size = bytestream_get_be16(&buf);
+        if (buf_size <= 1 || image_size <= 1) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Invalid image size received: %u -> image data offset: %d\n",
+                   buf_size, image_size);
+            return AVERROR_INVALIDDATA;
+        }
+    } else {
+        buf = avctx->extradata;
+        buf_size = bytestream_get_be16(&buf);
+        if (buf_size <= 1 || palette_size < 0) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Invalid palette size received: %u -> palette data offset: %d\n",
+                   buf_size, palette_size);
+            return AVERROR_INVALIDDATA;
+        }
+    }
+
+    if (buf_size > 8) {
+        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);
+        if (s->masking == MASK_HAS_MASK) {
+            if (s->bpp >= 8) {
+                avctx->pix_fmt = AV_PIX_FMT_RGB32;
+                av_freep(&s->mask_buf);
+                av_freep(&s->mask_palbuf);
+                s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE);
+                if (!s->mask_buf)
+                    return AVERROR(ENOMEM);
+                if (s->bpp > 16) {
+                    av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
+                    av_freep(&s->mask_buf);
+                    return AVERROR(ENOMEM);
+                }
+                s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
+                if (!s->mask_palbuf) {
+                    av_freep(&s->mask_buf);
+                    return AVERROR(ENOMEM);
+                }
+            }
+            s->bpp++;
+        } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
+            av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
+            return AVERROR_PATCHWELCOME;
+        }
+        if (!s->bpp || s->bpp > 32) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
+            return AVERROR_INVALIDDATA;
+        } else if (s->ham >= 8) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
+            return AVERROR_INVALIDDATA;
+        }
+
+        av_freep(&s->ham_buf);
+        av_freep(&s->ham_palbuf);
+
+        if (s->ham) {
+            int i, count = FFMIN(palette_size / 3, 1 << s->ham);
+            int ham_count;
+            const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
+
+            s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
+            if (!s->ham_buf)
+                return AVERROR(ENOMEM);
+
+            ham_count = 8 * (1 << s->ham);
+            s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
+            if (!s->ham_palbuf) {
+                av_freep(&s->ham_buf);
+                return AVERROR(ENOMEM);
+            }
+
+            if (count) { // HAM with color palette attached
+                // prefill with black and palette and set HAM take direct value mask to zero
+                memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
+                for (i=0; i < count; i++) {
+                    s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
+                }
+                count = 1 << s->ham;
+            } else { // HAM with grayscale color palette
+                count = 1 << s->ham;
+                for (i=0; i < count; i++) {
+                    s->ham_palbuf[i*2]   = 0xFF000000; // take direct color value from palette
+                    s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
+                }
+            }
+            for (i=0; i < count; i++) {
+                uint32_t tmp = i << (8 - s->ham);
+                tmp |= tmp >> s->ham;
+                s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF; // just modify blue color component
+                s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00; // just modify red color component
+                s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF; // just modify green color component
+                s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
+                s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
+                s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
+            }
+            if (s->masking == MASK_HAS_MASK) {
+                for (i = 0; i < ham_count; i++)
+                    s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
+            }
+        }
+    }
+
     return 0;
 }
 
@@ -151,11 +321,17 @@
     int err;
 
     if (avctx->bits_per_coded_sample <= 8) {
-        avctx->pix_fmt = (avctx->bits_per_coded_sample < 8 ||
-                          avctx->extradata_size) ? AV_PIX_FMT_PAL8
-                                                 : AV_PIX_FMT_GRAY8;
+        int palette_size;
+
+        if (avctx->extradata_size >= 2)
+            palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
+        else
+            palette_size = 0;
+        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) {
-        avctx->pix_fmt = AV_PIX_FMT_BGR32;
+        if (avctx->codec_tag != MKTAG('D','E','E','P'))
+            avctx->pix_fmt = AV_PIX_FMT_BGR32;
     } else {
         return AVERROR_INVALIDDATA;
     }
@@ -167,7 +343,12 @@
     if (!s->planebuf)
         return AVERROR(ENOMEM);
 
-    s->frame.reference = 1;
+    s->bpp = avctx->bits_per_coded_sample;
+    avcodec_get_frame_defaults(&s->frame);
+
+    if ((err = extract_header(avctx, NULL)) < 0)
+        return err;
+    s->frame.reference = 3;
 
     return 0;
 }
@@ -214,6 +395,47 @@
     } while (--buf_size);
 }
 
+#define DECODE_HAM_PLANE32(x)       \
+    first       = buf[x] << 1;      \
+    second      = buf[(x)+1] << 1;  \
+    delta      &= pal[first++];     \
+    delta      |= pal[first];       \
+    dst[x]      = delta;            \
+    delta      &= pal[second++];    \
+    delta      |= pal[second];      \
+    dst[(x)+1]  = delta
+
+/**
+ * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
+ *
+ * @param dst the destination 24bpp buffer
+ * @param buf the source 8bpp chunky buffer
+ * @param pal the HAM decode table
+ * @param buf_size the plane size in bytes
+ */
+static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
+                               const uint32_t *const pal, unsigned buf_size)
+{
+    uint32_t delta = 0;
+    do {
+        uint32_t first, second;
+        DECODE_HAM_PLANE32(0);
+        DECODE_HAM_PLANE32(2);
+        DECODE_HAM_PLANE32(4);
+        DECODE_HAM_PLANE32(6);
+        buf += 8;
+        dst += 8;
+    } while (--buf_size);
+}
+
+static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
+                         const uint32_t *const pal, unsigned width)
+{
+    do {
+        *dst++ = pal[*buf++];
+    } while (--width);
+}
+
 /**
  * Decode one complete byterun1 encoded line.
  *
@@ -250,11 +472,14 @@
                             AVPacket *avpkt)
 {
     IffContext *s = avctx->priv_data;
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
+    const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
+    const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
     const uint8_t *buf_end = buf+buf_size;
     int y, plane, res;
 
+    if ((res = extract_header(avctx, avpkt)) < 0)
+        return res;
+
     if (s->init) {
         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
@@ -263,37 +488,96 @@
     } else if ((res = avctx->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_GRAY8) {
+    } 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)
             return res;
     }
     s->init = 1;
 
-    if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
+    if (avctx->codec_tag == MKTAG('A','C','B','M')) {
+        if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
+            memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
+            for (plane = 0; plane < s->bpp; plane++) {
+                for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
+                    uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
+                    decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
+                    buf += s->planesize;
+                }
+            }
+        } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
+            memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
+            for(y = 0; y < avctx->height; y++) {
+                uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
+                memset(s->ham_buf, 0, s->planesize * 8);
+                for (plane = 0; plane < s->bpp; plane++) {
+                    const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
+                    if (start >= buf_end)
+                        break;
+                    decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
+                }
+                decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
+            }
+        }
+    } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
+        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+        int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
+        int x;
+        for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
+            uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
+            memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
+            buf += raw_width;
+            if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
+                for(x = 0; x < avctx->width; x++)
+                    row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
+            }
+        }
+    } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
         if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
             for(y = 0; y < avctx->height; y++ ) {
                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
                 memset(row, 0, avctx->width);
-                for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
+                for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
                     decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
                     buf += s->planesize;
                 }
             }
+        } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
+            for (y = 0; y < avctx->height; y++) {
+                uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
+                memset(s->ham_buf, 0, s->planesize * 8);
+                for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
+                    decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
+                    buf += s->planesize;
+                }
+                decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
+            }
         } else { // AV_PIX_FMT_BGR32
             for(y = 0; y < avctx->height; y++ ) {
                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
                 memset(row, 0, avctx->width << 2);
-                for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
+                for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
                     decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
                     buf += s->planesize;
                 }
             }
         }
-    } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) { // IFF-PBM
-        for(y = 0; y < avctx->height; y++ ) {
-            uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
-            memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
-            buf += avctx->width + (avctx->width % 2); // padding if odd
+    } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
+        if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
+            for(y = 0; y < avctx->height; y++ ) {
+                uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
+                memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
+                buf += avctx->width + (avctx->width % 2); // padding if odd
+            }
+        } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
+            for (y = 0; y < avctx->height; y++) {
+                uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
+                memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
+                buf += avctx->width + (avctx->width & 1); // padding if odd
+                decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
+            }
+        } else {
+            av_log_ask_for_sample(avctx, "unsupported bpp\n");
+            return AVERROR_INVALIDDATA;
         }
     }
 
@@ -307,11 +591,13 @@
                             AVPacket *avpkt)
 {
     IffContext *s = avctx->priv_data;
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
+    const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
+    const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
     const uint8_t *buf_end = buf+buf_size;
     int y, plane, res;
 
+    if ((res = extract_header(avctx, avpkt)) < 0)
+        return res;
     if (s->init) {
         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
@@ -320,9 +606,12 @@
     } else if ((res = avctx->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_GRAY8) {
+    } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
         if ((res = ff_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)
+            return res;
     }
     s->init = 1;
 
@@ -331,25 +620,56 @@
             for(y = 0; y < avctx->height ; y++ ) {
                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
                 memset(row, 0, avctx->width);
-                for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
+                for (plane = 0; plane < s->bpp; plane++) {
                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
                     decodeplane8(row, s->planebuf, s->planesize, plane);
                 }
             }
+        } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
+            for (y = 0; y < avctx->height ; y++ ) {
+                uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
+                memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
+                for (plane = 0; plane < s->bpp; plane++) {
+                    buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
+                    decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
+                }
+                lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
+            }
+        } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
+            for (y = 0; y < avctx->height ; y++) {
+                uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
+                memset(s->ham_buf, 0, s->planesize * 8);
+                for (plane = 0; plane < s->bpp; plane++) {
+                    buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
+                    decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
+                }
+                decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
+            }
         } else { //AV_PIX_FMT_BGR32
             for(y = 0; y < avctx->height ; y++ ) {
                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
                 memset(row, 0, avctx->width << 2);
-                for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
+                for (plane = 0; plane < s->bpp; plane++) {
                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
                     decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
                 }
             }
         }
-    } else {
-        for(y = 0; y < avctx->height ; y++ ) {
-            uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
-            buf += decode_byterun(row, avctx->width, buf, buf_end);
+    } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
+        if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
+            for(y = 0; y < avctx->height ; y++ ) {
+                uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
+                buf += decode_byterun(row, avctx->width, buf, buf_end);
+            }
+        } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
+            for (y = 0; y < avctx->height ; y++) {
+                uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
+                buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
+                decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
+            }
+        } else {
+            av_log_ask_for_sample(avctx, "unsupported bpp\n");
+            return AVERROR_INVALIDDATA;
         }
     }
 
@@ -364,9 +684,12 @@
     if (s->frame.data[0])
         avctx->release_buffer(avctx, &s->frame);
     av_freep(&s->planebuf);
+    av_freep(&s->ham_buf);
+    av_freep(&s->ham_palbuf);
     return 0;
 }
 
+#if CONFIG_IFF_ILBM_DECODER
 AVCodec ff_iff_ilbm_decoder = {
     .name           = "iff_ilbm",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -378,7 +701,8 @@
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("IFF ILBM"),
 };
-
+#endif
+#if CONFIG_IFF_BYTERUN1_DECODER
 AVCodec ff_iff_byterun1_decoder = {
     .name           = "iff_byterun1",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -390,3 +714,4 @@
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
 };
+#endif
diff --git a/libavcodec/iirfilter.c b/libavcodec/iirfilter.c
index f9b9ff6..3774d6e 100644
--- a/libavcodec/iirfilter.c
+++ b/libavcodec/iirfilter.c
@@ -2,20 +2,20 @@
  * IIR filter
  * Copyright (c) 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/iirfilter.h b/libavcodec/iirfilter.h
index bc65a96..b29e035 100644
--- a/libavcodec/iirfilter.h
+++ b/libavcodec/iirfilter.h
@@ -2,20 +2,20 @@
  * IIR filter
  * Copyright (c) 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/imc.c b/libavcodec/imc.c
index 1156e8a..9da769b 100644
--- a/libavcodec/imc.c
+++ b/libavcodec/imc.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2006 Benjamin Larsson
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -40,6 +40,7 @@
 #include "dsputil.h"
 #include "fft.h"
 #include "libavutil/audioconvert.h"
+#include "libavutil/libm.h"
 #include "sinewin.h"
 
 #include "imcdata.h"
@@ -341,7 +342,7 @@
     float tmp, tmp2;
     // maybe some frequency division thingy
 
-    flcoeffs1[0] = 20000.0 / pow (2, levlCoeffBuf[0] * 0.18945); // 0.18945 = log2(10) * 0.05703125
+    flcoeffs1[0] = 20000.0 / exp2 (levlCoeffBuf[0] * 0.18945); // 0.18945 = log2(10) * 0.05703125
     flcoeffs2[0] = log2f(flcoeffs1[0]);
     tmp  = flcoeffs1[0];
     tmp2 = flcoeffs2[0];
@@ -976,7 +977,7 @@
     return 0;
 }
 
-
+#if CONFIG_IMC_DECODER
 AVCodec ff_imc_decoder = {
     .name           = "imc",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -990,7 +991,8 @@
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
 };
-
+#endif
+#if CONFIG_IAC_DECODER
 AVCodec ff_iac_decoder = {
     .name           = "iac",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -1004,3 +1006,4 @@
     .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
                                                       AV_SAMPLE_FMT_NONE },
 };
+#endif
diff --git a/libavcodec/imcdata.h b/libavcodec/imcdata.h
index 8e99391..64e7c71 100644
--- a/libavcodec/imcdata.h
+++ b/libavcodec/imcdata.h
@@ -4,20 +4,20 @@
  * Copyright (c) 2006 Benjamin Larsson
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c
index fd30dc4..4846172 100644
--- a/libavcodec/imgconvert.c
+++ b/libavcodec/imgconvert.c
@@ -2,20 +2,20 @@
  * Misc image conversion routines
  * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -47,10 +47,6 @@
 #define FF_COLOR_YUV      2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
 #define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */
 
-#define FF_PIXEL_PLANAR   0 /**< each channel has one component in AVPicture */
-#define FF_PIXEL_PACKED   1 /**< only one components containing all the channels */
-#define FF_PIXEL_PALETTE  2  /**< one components containing indexes for a palette */
-
 #if HAVE_MMX_EXTERNAL
 #define deinterlace_line_inplace ff_deinterlace_line_inplace_mmx
 #define deinterlace_line         ff_deinterlace_line_mmx
@@ -59,352 +55,336 @@
 #define deinterlace_line         deinterlace_line_c
 #endif
 
+#define pixdesc_has_alpha(pixdesc) \
+    ((pixdesc)->nb_components == 2 || (pixdesc)->nb_components == 4 || (pixdesc)->flags & PIX_FMT_PAL)
+
 typedef struct PixFmtInfo {
-    uint8_t nb_channels;     /**< number of channels (including alpha) */
     uint8_t color_type;      /**< color type (see FF_COLOR_xxx constants) */
-    uint8_t pixel_type;      /**< pixel storage type (see FF_PIXEL_xxx constants) */
-    uint8_t is_alpha : 1;    /**< true if alpha can be specified */
-    uint8_t depth;           /**< bit depth of the color components */
+    uint8_t padded_size;     /**< padded size in bits if different from the non-padded size */
 } PixFmtInfo;
 
 /* this table gives more information about formats */
 static const PixFmtInfo pix_fmt_info[AV_PIX_FMT_NB] = {
     /* YUV formats */
     [AV_PIX_FMT_YUV420P] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 8,
     },
     [AV_PIX_FMT_YUV422P] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 8,
     },
     [AV_PIX_FMT_YUV444P] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 8,
     },
     [AV_PIX_FMT_YUYV422] = {
-        .nb_channels = 1,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 8,
     },
     [AV_PIX_FMT_UYVY422] = {
-        .nb_channels = 1,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 8,
     },
     [AV_PIX_FMT_YUV410P] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 8,
     },
     [AV_PIX_FMT_YUV411P] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 8,
     },
     [AV_PIX_FMT_YUV440P] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 8,
+    },
+    [AV_PIX_FMT_YUV420P9LE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV422P9LE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV444P9LE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV420P9BE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV422P9BE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV444P9BE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV420P10LE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV422P10LE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV444P10LE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV420P10BE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV422P10BE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV444P10BE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV420P12LE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV422P12LE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV444P12LE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV420P12BE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV422P12BE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV444P12BE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV420P14LE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV422P14LE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV444P14LE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV420P14BE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV422P14BE] = {
+        .color_type = FF_COLOR_YUV,
+    },
+    [AV_PIX_FMT_YUV444P14BE] = {
+        .color_type = FF_COLOR_YUV,
     },
     [AV_PIX_FMT_YUV420P16LE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 16,
     },
     [AV_PIX_FMT_YUV422P16LE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 16,
     },
     [AV_PIX_FMT_YUV444P16LE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 16,
     },
     [AV_PIX_FMT_YUV420P16BE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 16,
     },
     [AV_PIX_FMT_YUV422P16BE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 16,
     },
     [AV_PIX_FMT_YUV444P16BE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 16,
     },
 
-
     /* YUV formats with alpha plane */
     [AV_PIX_FMT_YUVA420P] = {
-        .nb_channels = 4,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 8,
+    },
+
+    [AV_PIX_FMT_YUVA422P] = {
+        .color_type = FF_COLOR_YUV,
+    },
+
+    [AV_PIX_FMT_YUVA444P] = {
+        .color_type = FF_COLOR_YUV,
     },
 
     /* JPEG YUV */
     [AV_PIX_FMT_YUVJ420P] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV_JPEG,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 8,
     },
     [AV_PIX_FMT_YUVJ422P] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV_JPEG,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 8,
     },
     [AV_PIX_FMT_YUVJ444P] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV_JPEG,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 8,
     },
     [AV_PIX_FMT_YUVJ440P] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_YUV_JPEG,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 8,
     },
 
     /* RGB formats */
     [AV_PIX_FMT_RGB24] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 8,
     },
     [AV_PIX_FMT_BGR24] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 8,
     },
     [AV_PIX_FMT_ARGB] = {
-        .nb_channels = 4, .is_alpha = 1,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 8,
     },
     [AV_PIX_FMT_RGB48BE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 16,
     },
     [AV_PIX_FMT_RGB48LE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 16,
+    },
+    [AV_PIX_FMT_RGBA64BE] = {
+        .color_type = FF_COLOR_RGB,
+    },
+    [AV_PIX_FMT_RGBA64LE] = {
+        .color_type = FF_COLOR_RGB,
     },
     [AV_PIX_FMT_RGB565BE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 5,
     },
     [AV_PIX_FMT_RGB565LE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 5,
     },
     [AV_PIX_FMT_RGB555BE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 5,
+        .padded_size = 16,
     },
     [AV_PIX_FMT_RGB555LE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 5,
+        .padded_size = 16,
     },
     [AV_PIX_FMT_RGB444BE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 4,
+        .padded_size = 16,
     },
     [AV_PIX_FMT_RGB444LE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 4,
+        .padded_size = 16,
     },
 
     /* gray / mono formats */
     [AV_PIX_FMT_GRAY16BE] = {
-        .nb_channels = 1,
         .color_type = FF_COLOR_GRAY,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 16,
     },
     [AV_PIX_FMT_GRAY16LE] = {
-        .nb_channels = 1,
         .color_type = FF_COLOR_GRAY,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 16,
     },
     [AV_PIX_FMT_GRAY8] = {
-        .nb_channels = 1,
         .color_type = FF_COLOR_GRAY,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 8,
+    },
+    [AV_PIX_FMT_GRAY8A] = {
+        .color_type = FF_COLOR_GRAY,
     },
     [AV_PIX_FMT_MONOWHITE] = {
-        .nb_channels = 1,
         .color_type = FF_COLOR_GRAY,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 1,
     },
     [AV_PIX_FMT_MONOBLACK] = {
-        .nb_channels = 1,
         .color_type = FF_COLOR_GRAY,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 1,
     },
 
     /* paletted formats */
     [AV_PIX_FMT_PAL8] = {
-        .nb_channels = 4, .is_alpha = 1,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PALETTE,
-        .depth = 8,
     },
     [AV_PIX_FMT_UYYVYY411] = {
-        .nb_channels = 1,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 8,
     },
     [AV_PIX_FMT_ABGR] = {
-        .nb_channels = 4, .is_alpha = 1,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 8,
+    },
+    [AV_PIX_FMT_BGR48BE] = {
+        .color_type = FF_COLOR_RGB,
+    },
+    [AV_PIX_FMT_BGR48LE] = {
+        .color_type = FF_COLOR_RGB,
+    },
+    [AV_PIX_FMT_BGRA64BE] = {
+        .color_type = FF_COLOR_RGB,
+    },
+    [AV_PIX_FMT_BGRA64LE] = {
+        .color_type = FF_COLOR_RGB,
     },
     [AV_PIX_FMT_BGR565BE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 5,
+        .padded_size = 16,
     },
     [AV_PIX_FMT_BGR565LE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 5,
+        .padded_size = 16,
     },
     [AV_PIX_FMT_BGR555BE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 5,
+        .padded_size = 16,
     },
     [AV_PIX_FMT_BGR555LE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 5,
+        .padded_size = 16,
     },
     [AV_PIX_FMT_BGR444BE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 4,
+        .padded_size = 16,
     },
     [AV_PIX_FMT_BGR444LE] = {
-        .nb_channels = 3,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 4,
+        .padded_size = 16,
     },
     [AV_PIX_FMT_RGB8] = {
-        .nb_channels = 1,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 8,
     },
     [AV_PIX_FMT_RGB4] = {
-        .nb_channels = 1,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 4,
     },
     [AV_PIX_FMT_RGB4_BYTE] = {
-        .nb_channels = 1,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 8,
+        .padded_size = 8,
     },
     [AV_PIX_FMT_BGR8] = {
-        .nb_channels = 1,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 8,
     },
     [AV_PIX_FMT_BGR4] = {
-        .nb_channels = 1,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 4,
     },
     [AV_PIX_FMT_BGR4_BYTE] = {
-        .nb_channels = 1,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 8,
+        .padded_size = 8,
     },
     [AV_PIX_FMT_NV12] = {
-        .nb_channels = 2,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 8,
     },
     [AV_PIX_FMT_NV21] = {
-        .nb_channels = 2,
         .color_type = FF_COLOR_YUV,
-        .pixel_type = FF_PIXEL_PLANAR,
-        .depth = 8,
     },
 
     [AV_PIX_FMT_BGRA] = {
-        .nb_channels = 4, .is_alpha = 1,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 8,
     },
     [AV_PIX_FMT_RGBA] = {
-        .nb_channels = 4, .is_alpha = 1,
         .color_type = FF_COLOR_RGB,
-        .pixel_type = FF_PIXEL_PACKED,
-        .depth = 8,
+    },
+
+    [AV_PIX_FMT_GBRP] = {
+        .color_type = FF_COLOR_RGB,
+    },
+    [AV_PIX_FMT_GBRP9BE] = {
+        .color_type = FF_COLOR_RGB,
+    },
+    [AV_PIX_FMT_GBRP9LE] = {
+        .color_type = FF_COLOR_RGB,
+    },
+    [AV_PIX_FMT_GBRP10BE] = {
+        .color_type = FF_COLOR_RGB,
+    },
+    [AV_PIX_FMT_GBRP10LE] = {
+        .color_type = FF_COLOR_RGB,
+    },
+    [AV_PIX_FMT_GBRP12BE] = {
+        .color_type = FF_COLOR_RGB,
+    },
+    [AV_PIX_FMT_GBRP12LE] = {
+        .color_type = FF_COLOR_RGB,
+    },
+    [AV_PIX_FMT_GBRP14BE] = {
+        .color_type = FF_COLOR_RGB,
+    },
+    [AV_PIX_FMT_GBRP14LE] = {
+        .color_type = FF_COLOR_RGB,
+    },
+    [AV_PIX_FMT_GBRP16BE] = {
+        .color_type = FF_COLOR_RGB,
+    },
+    [AV_PIX_FMT_GBRP16LE] = {
+        .color_type = FF_COLOR_RGB,
     },
 };
 
@@ -424,61 +404,39 @@
 int avpicture_fill(AVPicture *picture, uint8_t *ptr,
                    enum AVPixelFormat pix_fmt, int width, int height)
 {
-    int ret;
-
-    if ((ret = av_image_check_size(width, height, 0, NULL)) < 0)
-        return ret;
-
-    if ((ret = av_image_fill_linesizes(picture->linesize, pix_fmt, width)) < 0)
-        return ret;
-
-    return av_image_fill_pointers(picture->data, pix_fmt, height, ptr, picture->linesize);
+    return av_image_fill_arrays(picture->data, picture->linesize,
+                                ptr, pix_fmt, width, height, 1);
 }
 
 int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt, int width, int height,
                      unsigned char *dest, int dest_size)
 {
-    int i, j, nb_planes = 0, linesizes[4];
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
-    int size = avpicture_get_size(pix_fmt, width, height);
-
-    if (size > dest_size || size < 0)
-        return AVERROR(EINVAL);
-
-    for (i = 0; i < desc->nb_components; i++)
-        nb_planes = FFMAX(desc->comp[i].plane, nb_planes);
-    nb_planes++;
-
-    av_image_fill_linesizes(linesizes, pix_fmt, width);
-    for (i = 0; i < nb_planes; i++) {
-        int h, shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
-        const unsigned char *s = src->data[i];
-        h = (height + (1 << shift) - 1) >> shift;
-
-        for (j = 0; j < h; j++) {
-            memcpy(dest, s, linesizes[i]);
-            dest += linesizes[i];
-            s += src->linesize[i];
-        }
-    }
-
-    if (desc->flags & PIX_FMT_PAL)
-        memcpy((unsigned char *)(((size_t)dest + 3) & ~3), src->data[1], 256 * 4);
-
-    return size;
+    return av_image_copy_to_buffer(dest, dest_size,
+                                   (const uint8_t * const*)src->data, src->linesize,
+                                   pix_fmt, width, height, 1);
 }
 
 int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height)
 {
-    AVPicture dummy_pict;
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+    return av_image_get_buffer_size(pix_fmt, width, height, 1);
+}
 
-    if(av_image_check_size(width, height, 0, NULL))
-        return -1;
-    if (desc->flags & PIX_FMT_PSEUDOPAL)
-        // do not include palette for these pseudo-paletted formats
-        return width * height;
-    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
+static int get_pix_fmt_depth(int *min, int *max, enum AVPixelFormat pix_fmt)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+    int i;
+
+    if (!desc || !desc->nb_components) {
+        *min = *max = 0;
+        return AVERROR(EINVAL);
+    }
+
+    *min = INT_MAX, *max = -INT_MAX;
+    for (i = 0; i < desc->nb_components; i++) {
+        *min = FFMIN(desc->comp[i].depth_minus1+1, *min);
+        *max = FFMAX(desc->comp[i].depth_minus1+1, *max);
+    }
+    return 0;
 }
 
 int avcodec_get_pix_fmt_loss(enum AVPixelFormat dst_pix_fmt, enum AVPixelFormat src_pix_fmt,
@@ -487,22 +445,29 @@
     const PixFmtInfo *pf, *ps;
     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 loss;
+    int src_min_depth, src_max_depth, dst_min_depth, dst_max_depth;
+    int ret, loss;
+
+    if (dst_pix_fmt >= AV_PIX_FMT_NB || dst_pix_fmt <= AV_PIX_FMT_NONE)
+        return ~0;
 
     ps = &pix_fmt_info[src_pix_fmt];
 
     /* compute loss */
     loss = 0;
-    pf = &pix_fmt_info[dst_pix_fmt];
-    if (pf->depth < ps->depth ||
-        ((dst_pix_fmt == AV_PIX_FMT_RGB555BE || dst_pix_fmt == AV_PIX_FMT_RGB555LE ||
-          dst_pix_fmt == AV_PIX_FMT_BGR555BE || dst_pix_fmt == AV_PIX_FMT_BGR555LE) &&
-         (src_pix_fmt == AV_PIX_FMT_RGB565BE || src_pix_fmt == AV_PIX_FMT_RGB565LE ||
-          src_pix_fmt == AV_PIX_FMT_BGR565BE || src_pix_fmt == AV_PIX_FMT_BGR565LE)))
+
+    if ((ret = get_pix_fmt_depth(&src_min_depth, &src_max_depth, src_pix_fmt)) < 0)
+        return ret;
+    if ((ret = get_pix_fmt_depth(&dst_min_depth, &dst_max_depth, dst_pix_fmt)) < 0)
+        return ret;
+    if (dst_min_depth < src_min_depth ||
+        dst_max_depth < src_max_depth)
         loss |= FF_LOSS_DEPTH;
     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;
+
+    pf = &pix_fmt_info[dst_pix_fmt];
     switch(pf->color_type) {
     case FF_COLOR_RGB:
         if (ps->color_type != FF_COLOR_RGB &&
@@ -532,156 +497,116 @@
     if (pf->color_type == FF_COLOR_GRAY &&
         ps->color_type != FF_COLOR_GRAY)
         loss |= FF_LOSS_CHROMA;
-    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
+    if (!pixdesc_has_alpha(dst_desc) && (pixdesc_has_alpha(src_desc) && has_alpha))
         loss |= FF_LOSS_ALPHA;
-    if (pf->pixel_type == FF_PIXEL_PALETTE &&
-        (ps->pixel_type != FF_PIXEL_PALETTE && ps->color_type != FF_COLOR_GRAY))
+    if (dst_pix_fmt == AV_PIX_FMT_PAL8 &&
+        (src_pix_fmt != AV_PIX_FMT_PAL8 && (ps->color_type != FF_COLOR_GRAY || (pixdesc_has_alpha(src_desc) && has_alpha))))
         loss |= FF_LOSS_COLORQUANT;
+
     return loss;
 }
 
 static int avg_bits_per_pixel(enum AVPixelFormat pix_fmt)
 {
-    int bits;
-    const PixFmtInfo *pf;
+    const PixFmtInfo *info = &pix_fmt_info[pix_fmt];
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
 
-    pf = &pix_fmt_info[pix_fmt];
-    switch(pf->pixel_type) {
-    case FF_PIXEL_PACKED:
-        switch(pix_fmt) {
-        case AV_PIX_FMT_YUYV422:
-        case AV_PIX_FMT_UYVY422:
-        case AV_PIX_FMT_RGB565BE:
-        case AV_PIX_FMT_RGB565LE:
-        case AV_PIX_FMT_RGB555BE:
-        case AV_PIX_FMT_RGB555LE:
-        case AV_PIX_FMT_RGB444BE:
-        case AV_PIX_FMT_RGB444LE:
-        case AV_PIX_FMT_BGR565BE:
-        case AV_PIX_FMT_BGR565LE:
-        case AV_PIX_FMT_BGR555BE:
-        case AV_PIX_FMT_BGR555LE:
-        case AV_PIX_FMT_BGR444BE:
-        case AV_PIX_FMT_BGR444LE:
-            bits = 16;
-            break;
-        case AV_PIX_FMT_UYYVYY411:
-            bits = 12;
-            break;
-        default:
-            bits = pf->depth * pf->nb_channels;
-            break;
-        }
-        break;
-    case FF_PIXEL_PLANAR:
-        if (desc->log2_chroma_w == 0 && desc->log2_chroma_h == 0) {
-            bits = pf->depth * pf->nb_channels;
-        } else {
-            bits = pf->depth + ((2 * pf->depth) >>
-                                (desc->log2_chroma_w + desc->log2_chroma_h));
-        }
-        break;
-    case FF_PIXEL_PALETTE:
-        bits = 8;
-        break;
-    default:
-        bits = -1;
-        break;
-    }
-    return bits;
-}
-
-static enum AVPixelFormat avcodec_find_best_pix_fmt1(enum AVPixelFormat *pix_fmt_list,
-                                      enum AVPixelFormat src_pix_fmt,
-                                      int has_alpha,
-                                      int loss_mask)
-{
-    int dist, i, loss, min_dist;
-    enum AVPixelFormat dst_pix_fmt;
-
-    /* find exact color match with smallest size */
-    dst_pix_fmt = AV_PIX_FMT_NONE;
-    min_dist = 0x7fffffff;
-    i = 0;
-    while (pix_fmt_list[i] != AV_PIX_FMT_NONE) {
-        enum AVPixelFormat pix_fmt = pix_fmt_list[i];
-
-        if (i > AV_PIX_FMT_NB) {
-            av_log(NULL, AV_LOG_ERROR, "Pixel format list longer than expected, "
-                   "it is either not properly terminated or contains duplicates\n");
-            return AV_PIX_FMT_NONE;
-        }
-
-        loss = avcodec_get_pix_fmt_loss(pix_fmt, src_pix_fmt, has_alpha) & loss_mask;
-        if (loss == 0) {
-            dist = avg_bits_per_pixel(pix_fmt);
-            if (dist < min_dist) {
-                min_dist = dist;
-                dst_pix_fmt = pix_fmt;
-            }
-        }
-        i++;
-    }
-    return dst_pix_fmt;
+    return info->padded_size ?
+        info->padded_size : av_get_bits_per_pixel(desc);
 }
 
 #if FF_API_FIND_BEST_PIX_FMT
 enum AVPixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum AVPixelFormat src_pix_fmt,
-                              int has_alpha, int *loss_ptr)
-{
-    enum AVPixelFormat list[64];
-    int i, j = 0;
-
-    // test only the first 64 pixel formats to avoid undefined behaviour
-    for (i = 0; i < 64; i++) {
-        if (pix_fmt_mask & (1ULL << i))
-            list[j++] = i;
-    }
-    list[j] = AV_PIX_FMT_NONE;
-
-    return avcodec_find_best_pix_fmt2(list, src_pix_fmt, has_alpha, loss_ptr);
-}
-#endif /* FF_API_FIND_BEST_PIX_FMT */
-
-enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat *pix_fmt_list,
-                                            enum AVPixelFormat src_pix_fmt,
                                             int has_alpha, int *loss_ptr)
 {
     enum AVPixelFormat dst_pix_fmt;
-    int loss_mask, i;
+    int i;
+
+    if (loss_ptr) /* all losses count (for backward compatibility) */
+        *loss_ptr = 0;
+
+    dst_pix_fmt = AV_PIX_FMT_NONE; /* so first iteration doesn't have to be treated special */
+    for(i = 0; i< FFMIN(AV_PIX_FMT_NB, 64); i++){
+        if (pix_fmt_mask & (1ULL << i))
+            dst_pix_fmt = avcodec_find_best_pix_fmt_of_2(dst_pix_fmt, i, src_pix_fmt, has_alpha, loss_ptr);
+    }
+    return dst_pix_fmt;
+}
+#endif /* FF_API_FIND_BEST_PIX_FMT */
+
+enum AVPixelFormat avcodec_find_best_pix_fmt_of_2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
+                                            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;
     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,
     };
 
+    loss_mask= loss_ptr?~*loss_ptr:~0; /* use loss mask if provided */
+    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;
+
     /* try with successive loss */
-    i = 0;
-    for(;;) {
-        loss_mask = loss_mask_order[i++];
-        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_list, src_pix_fmt,
-                                                 has_alpha, loss_mask);
-        if (dst_pix_fmt >= 0)
-            goto found;
-        if (loss_mask == 0)
-            break;
+    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){ /* use format with smallest depth */
+            dst_pix_fmt = avg_bits_per_pixel(dst_pix_fmt2) < avg_bits_per_pixel(dst_pix_fmt1) ? 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;
+        }
     }
-    return AV_PIX_FMT_NONE;
- found:
+
     if (loss_ptr)
         *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
     return dst_pix_fmt;
 }
 
+#if AV_HAVE_INCOMPATIBLE_FORK_ABI
+enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat *pix_fmt_list,
+                                            enum AVPixelFormat src_pix_fmt,
+                                            int has_alpha, int *loss_ptr){
+    return avcodec_find_best_pix_fmt_of_list(pix_fmt_list, src_pix_fmt, has_alpha, loss_ptr);
+}
+#else
+enum AVPixelFormat avcodec_find_best_pix_fmt2(enum AVPixelFormat dst_pix_fmt1, enum AVPixelFormat dst_pix_fmt2,
+                                            enum AVPixelFormat src_pix_fmt, int has_alpha, int *loss_ptr)
+{
+    return avcodec_find_best_pix_fmt_of_2(dst_pix_fmt1, dst_pix_fmt2, src_pix_fmt, has_alpha, loss_ptr);
+}
+#endif
+
+enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(enum AVPixelFormat *pix_fmt_list,
+                                            enum AVPixelFormat src_pix_fmt,
+                                            int has_alpha, int *loss_ptr){
+    int i;
+
+    enum AVPixelFormat best = AV_PIX_FMT_NONE;
+
+    for(i=0; pix_fmt_list[i] != AV_PIX_FMT_NONE; i++)
+        best = avcodec_find_best_pix_fmt_of_2(best, pix_fmt_list[i], src_pix_fmt, has_alpha, loss_ptr);
+
+    return best;
+}
+
 void av_picture_copy(AVPicture *dst, const AVPicture *src,
                      enum AVPixelFormat pix_fmt, int width, int height)
 {
-    av_image_copy(dst->data, dst->linesize, src->data,
+    av_image_copy(dst->data, dst->linesize, (const uint8_t **)src->data,
                   src->linesize, pix_fmt, width, height);
 }
 
@@ -791,11 +716,26 @@
 }
 
 /* return true if yuv planar */
-static inline int is_yuv_planar(const PixFmtInfo *ps)
+static inline int is_yuv_planar(enum AVPixelFormat fmt)
 {
-    return (ps->color_type == FF_COLOR_YUV ||
-            ps->color_type == FF_COLOR_YUV_JPEG) &&
-        ps->pixel_type == FF_PIXEL_PLANAR;
+    const PixFmtInfo         *info = &pix_fmt_info[fmt];
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
+    int i;
+    int planes[4] = { 0 };
+
+    if (info->color_type != FF_COLOR_YUV &&
+        info->color_type != FF_COLOR_YUV_JPEG)
+        return 0;
+
+    /* set the used planes */
+    for (i = 0; i < desc->nb_components; i++)
+        planes[desc->comp[i].plane] = 1;
+
+    /* if there is an unused plane, the format is not planar */
+    for (i = 0; i < desc->nb_components; i++)
+        if (!planes[i])
+            return 0;
+    return 1;
 }
 
 int av_picture_crop(AVPicture *dst, const AVPicture *src,
@@ -805,15 +745,23 @@
     int y_shift;
     int x_shift;
 
-    if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB || !is_yuv_planar(&pix_fmt_info[pix_fmt]))
+    if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB)
         return -1;
 
     y_shift = desc->log2_chroma_h;
     x_shift = desc->log2_chroma_w;
 
+    if (is_yuv_planar(pix_fmt)) {
     dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
     dst->data[1] = src->data[1] + ((top_band >> y_shift) * src->linesize[1]) + (left_band >> x_shift);
     dst->data[2] = src->data[2] + ((top_band >> y_shift) * src->linesize[2]) + (left_band >> x_shift);
+    } else{
+        if(top_band % (1<<y_shift) || left_band % (1<<x_shift))
+            return -1;
+        if(left_band) //FIXME add support for this too
+            return -1;
+        dst->data[0] = src->data[0] + (top_band * src->linesize[0]) + left_band;
+    }
 
     dst->linesize[0] = src->linesize[0];
     dst->linesize[1] = src->linesize[1];
@@ -833,7 +781,7 @@
     int i, y;
 
     if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB ||
-        !is_yuv_planar(&pix_fmt_info[pix_fmt])) return -1;
+        !is_yuv_planar(pix_fmt)) return -1;
 
     for (i = 0; i < 3; i++) {
         x_shift = i ? desc->log2_chroma_w : 0;
diff --git a/libavcodec/imx_dump_header_bsf.c b/libavcodec/imx_dump_header_bsf.c
index 5f5493f..9f276bc 100644
--- a/libavcodec/imx_dump_header_bsf.c
+++ b/libavcodec/imx_dump_header_bsf.c
@@ -2,20 +2,20 @@
  * imx dump header bitstream filter
  * Copyright (c) 2007 Baptiste Coudurier
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c
index 76592d6..74a9800 100644
--- a/libavcodec/indeo2.c
+++ b/libavcodec/indeo2.c
@@ -2,20 +2,20 @@
  * Intel Indeo 2 codec
  * Copyright (c) 2005 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -148,10 +148,7 @@
     AVFrame * const p = &s->picture;
     int start;
 
-    if(p->data[0])
-        avctx->release_buffer(avctx, p);
-
-    p->reference = 1;
+    p->reference = 3;
     p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
     if (avctx->reget_buffer(avctx, p)) {
         av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
@@ -203,6 +200,7 @@
     Ir2Context * const ic = avctx->priv_data;
     static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2];
 
+    avcodec_get_frame_defaults(&ic->picture);
     ic->avctx = avctx;
 
     avctx->pix_fmt= AV_PIX_FMT_YUV410P;
diff --git a/libavcodec/indeo2data.h b/libavcodec/indeo2data.h
index ed8d83c..0d6d82f 100644
--- a/libavcodec/indeo2data.h
+++ b/libavcodec/indeo2data.h
@@ -2,20 +2,20 @@
  * Intel Indeo 2 codec
  * copyright (c) 2005 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index c99cee8..4cee28f 100644
--- a/libavcodec/indeo3.c
+++ b/libavcodec/indeo3.c
@@ -2,20 +2,20 @@
  * Indeo Video v3 compatible decoder
  * Copyright (c) 2009 - 2011 Maxim Poliakovski
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -148,14 +148,11 @@
 
 
 static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx,
-                                          AVCodecContext *avctx)
+                                          AVCodecContext *avctx, int luma_width, int luma_height)
 {
-    int p, luma_width, luma_height, chroma_width, chroma_height;
+    int p, chroma_width, chroma_height;
     int luma_pitch, chroma_pitch, luma_size, chroma_size;
 
-    luma_width  = ctx->width;
-    luma_height = ctx->height;
-
     if (luma_width  < 16 || luma_width  > 640 ||
         luma_height < 16 || luma_height > 480 ||
         luma_width  &  3 || luma_height &   3) {
@@ -164,6 +161,9 @@
         return AVERROR_INVALIDDATA;
     }
 
+    ctx->width  = luma_width ;
+    ctx->height = luma_height;
+
     chroma_width  = FFALIGN(luma_width  >> 2, 4);
     chroma_height = FFALIGN(luma_height >> 2, 4);
 
@@ -206,6 +206,9 @@
 {
     int p;
 
+    ctx->width=
+    ctx->height= 0;
+
     for (p = 0; p < 3; p++) {
         av_freep(&ctx->planes[p].buffers[0]);
         av_freep(&ctx->planes[p].buffers[1]);
@@ -230,8 +233,11 @@
     /* setup output and reference pointers */
     offset_dst  = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2);
     dst         = plane->pixels[ctx->buf_sel] + offset_dst;
+    if(cell->mv_ptr){
     mv_y        = cell->mv_ptr[0];
     mv_x        = cell->mv_ptr[1];
+    }else
+        mv_x= mv_y= 0;
     offset      = offset_dst + mv_y * plane->pitch + mv_x;
     src         = plane->pixels[ctx->buf_sel ^ 1] + offset;
 
@@ -578,6 +584,19 @@
     /* setup output and reference pointers */
     offset = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2);
     block  =  plane->pixels[ctx->buf_sel] + offset;
+
+    if (cell->mv_ptr) {
+        mv_y      = cell->mv_ptr[0];
+        mv_x      = cell->mv_ptr[1];
+        if (   mv_x + 4*cell->xpos < 0
+            || mv_y + 4*cell->ypos < 0
+            || mv_x + 4*cell->xpos + 4*cell->width  > plane->width
+            || mv_y + 4*cell->ypos + 4*cell->height > plane->height) {
+            av_log(avctx, AV_LOG_ERROR, "motion vector %d %d outside reference\n", mv_x + 4*cell->xpos, mv_y + 4*cell->ypos);
+            return AVERROR_INVALIDDATA;
+        }
+    }
+
     if (!cell->mv_ptr) {
         /* use previous line as reference for INTRA cells */
         ref_block = block - plane->pitch;
@@ -620,7 +639,7 @@
     /* of the predicted cell in order to avoid overflows. */
     if (vq_index >= 8 && ref_block) {
         for (x = 0; x < cell->width << 2; x++)
-            ref_block[x] = requant_tab[vq_index & 7][ref_block[x]];
+            ref_block[x] = requant_tab[vq_index & 7][ref_block[x] & 127];
     }
 
     error = IV3_NOERR;
@@ -721,6 +740,7 @@
 {
     Cell    curr_cell;
     int     bytes_used;
+    int mv_x, mv_y;
 
     if (depth <= 0) {
         av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n");
@@ -746,7 +766,7 @@
             return AVERROR_INVALIDDATA;
     }
 
-    while (1) { /* loop until return */
+    while (get_bits_left(&ctx->gb) >= 2) { /* loop until return */
         RESYNC_BITSTREAM;
         switch (code = get_bits(&ctx->gb, 2)) {
         case H_SPLIT:
@@ -771,6 +791,17 @@
                 CHECK_CELL
                 if (!curr_cell.mv_ptr)
                     return AVERROR_INVALIDDATA;
+
+                mv_y = curr_cell.mv_ptr[0];
+                mv_x = curr_cell.mv_ptr[1];
+                if (   mv_x + 4*curr_cell.xpos < 0
+                    || mv_y + 4*curr_cell.ypos < 0
+                    || mv_x + 4*curr_cell.xpos + 4*curr_cell.width  > plane->width
+                    || mv_y + 4*curr_cell.ypos + 4*curr_cell.height > plane->height) {
+                    av_log(avctx, AV_LOG_ERROR, "motion vector %d %d outside reference\n", mv_x + 4*curr_cell.xpos, mv_y + 4*curr_cell.ypos);
+                    return AVERROR_INVALIDDATA;
+                }
+
                 copy_cell(ctx, plane, &curr_cell);
                 return 0;
             }
@@ -781,6 +812,10 @@
                 /* get motion vector index and setup the pointer to the mv set */
                 if (!ctx->need_resync)
                     ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];
+                if (ctx->next_cell_data >= ctx->last_byte) {
+                    av_log(avctx, AV_LOG_ERROR, "motion vector out of array\n");
+                    return AVERROR_INVALIDDATA;
+                }
                 mv_idx = *(ctx->next_cell_data++);
                 if (mv_idx >= ctx->num_vectors) {
                     av_log(avctx, AV_LOG_ERROR, "motion vector index out of range\n");
@@ -807,7 +842,7 @@
         }
     }//while
 
-    return 0;
+    return AVERROR_INVALIDDATA;
 }
 
 
@@ -820,13 +855,13 @@
 
     /* each plane data starts with mc_vector_count field, */
     /* an optional array of motion vectors followed by the vq data */
-    num_vectors = bytestream_get_le32(&data);
+    num_vectors = bytestream_get_le32(&data); data_size -= 4;
     if (num_vectors > 256) {
         av_log(ctx->avctx, AV_LOG_ERROR,
                "Read invalid number of motion vectors %d\n", num_vectors);
         return AVERROR_INVALIDDATA;
     }
-    if (num_vectors * 2 >= data_size)
+    if (num_vectors * 2 > data_size)
         return AVERROR_INVALIDDATA;
 
     ctx->num_vectors = num_vectors;
@@ -837,7 +872,7 @@
     ctx->skip_bits   = 0;
     ctx->need_resync = 0;
 
-    ctx->last_byte = data + data_size - 1;
+    ctx->last_byte = data + data_size;
 
     /* initialize the 1st cell and set its dimensions to whole plane */
     curr_cell.xpos   = curr_cell.ypos = 0;
@@ -874,6 +909,7 @@
 
     /* parse the bitstream header */
     bs_hdr = buf_ptr;
+    buf_size -= 16;
 
     if (bytestream_get_le16(&buf_ptr) != 32) {
         av_log(avctx, AV_LOG_ERROR, "Unsupported codec version!\n");
@@ -910,12 +946,8 @@
                    "Invalid picture dimensions: %d x %d!\n", width, height);
             return AVERROR_INVALIDDATA;
         }
-
-        ctx->width  = width;
-        ctx->height = height;
-
         free_frame_buffers(ctx);
-        if ((res = allocate_frame_buffers(ctx, avctx)) < 0)
+        if ((res = allocate_frame_buffers(ctx, avctx, width, height)) < 0)
              return res;
         avcodec_set_dimensions(avctx, width, height);
     }
@@ -1007,17 +1039,14 @@
     Indeo3DecodeContext *ctx = avctx->priv_data;
 
     ctx->avctx     = avctx;
-    ctx->width     = avctx->width;
-    ctx->height    = avctx->height;
     avctx->pix_fmt = AV_PIX_FMT_YUV410P;
+    avcodec_get_frame_defaults(&ctx->frame);
 
     build_requant_tab();
 
     ff_dsputil_init(&ctx->dsp, avctx);
 
-    allocate_frame_buffers(ctx, avctx);
-
-    return 0;
+    return allocate_frame_buffers(ctx, avctx, avctx->width, avctx->height);
 }
 
 
diff --git a/libavcodec/indeo3data.h b/libavcodec/indeo3data.h
index 2ef8ea7..0b5648e 100644
--- a/libavcodec/indeo3data.h
+++ b/libavcodec/indeo3data.h
@@ -2,20 +2,20 @@
  * Indeo Video v3 compatible decoder
  * Copyright (c) 2009 - 2011 Maxim Poliakovski
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c
index b837ffb..bb5ec10 100644
--- a/libavcodec/indeo4.c
+++ b/libavcodec/indeo4.c
@@ -283,6 +283,7 @@
 {
     int plane, band_num, indx, transform_id, scan_indx;
     int i;
+    int quant_mat;
 
     plane    = get_bits(&ctx->gb, 2);
     band_num = get_bits(&ctx->gb, 4);
@@ -339,6 +340,10 @@
                 return AVERROR_PATCHWELCOME;
             }
 
+            if (transform_id < 10 && band->blk_size < 8) {
+                av_log(avctx, AV_LOG_ERROR, "wrong transform size!\n");
+                return AVERROR_INVALIDDATA;
+            }
 #if IVI4_STREAM_ANALYSER
             if ((transform_id >= 0 && transform_id <= 2) || transform_id == 10)
                 ctx->uses_haar = 1;
@@ -347,21 +352,35 @@
             band->inv_transform = transforms[transform_id].inv_trans;
             band->dc_transform  = transforms[transform_id].dc_trans;
             band->is_2d_trans   = transforms[transform_id].is_2d_trans;
+            band->transform_size= (transform_id < 10) ? 8 : 4;
 
             scan_indx = get_bits(&ctx->gb, 4);
+            if ((scan_indx>4 && scan_indx<10) != (band->blk_size==4)) {
+                av_log(avctx, AV_LOG_ERROR, "mismatching scan table!\n");
+                return AVERROR_INVALIDDATA;
+            }
             if (scan_indx == 15) {
                 av_log(avctx, AV_LOG_ERROR, "Custom scan pattern encountered!\n");
                 return AVERROR_INVALIDDATA;
             }
             band->scan = scan_index_to_tab[scan_indx];
 
-            band->quant_mat = get_bits(&ctx->gb, 5);
-            if (band->quant_mat == 31) {
+            quant_mat = get_bits(&ctx->gb, 5);
+            if (quant_mat == 31) {
                 av_log(avctx, AV_LOG_ERROR, "Custom quant matrix encountered!\n");
                 return AVERROR_INVALIDDATA;
             }
+            if (quant_mat > 21) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid quant matrix encountered!\n");
+                return AVERROR_INVALIDDATA;
+            }
+            band->quant_mat = quant_mat;
         }
-
+        if (quant_index_to_tab[band->quant_mat] > 4 && band->blk_size == 4) {
+            av_log(avctx, AV_LOG_ERROR, "Invalid quant matrix for 4x4 block encountered!\n");
+            band->quant_mat = 0;
+            return AVERROR_INVALIDDATA;
+        }
         /* decode block huffman codebook */
         if (ff_ivi_dec_huff_desc(&ctx->gb, get_bits1(&ctx->gb), IVI_BLK_HUFF,
                                  &band->blk_vlc, avctx))
@@ -400,6 +419,11 @@
 
     align_get_bits(&ctx->gb);
 
+    if (!band->scan) {
+        av_log(avctx, AV_LOG_ERROR, "band->scan not set\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     return 0;
 }
 
@@ -418,7 +442,7 @@
                           IVITile *tile, AVCodecContext *avctx)
 {
     int         x, y, mv_x, mv_y, mv_delta, offs, mb_offset, blks_per_mb,
-                mv_scale, mb_type_bits;
+                mv_scale, mb_type_bits, s;
     IVIMbInfo   *mb, *ref_mb;
     int         row_offset = band->mb_size * band->pitch;
 
@@ -433,6 +457,11 @@
     mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3);
     mv_x = mv_y = 0;
 
+    if (((tile->width + band->mb_size-1)/band->mb_size) * ((tile->height + band->mb_size-1)/band->mb_size) != tile->num_MBs) {
+        av_log(avctx, AV_LOG_ERROR, "num_MBs mismatch %d %d %d %d\n", tile->width, tile->height, band->mb_size, tile->num_MBs);
+        return -1;
+    }
+
     for (y = tile->ypos; y < tile->ypos + tile->height; y += band->mb_size) {
         mb_offset = offs;
 
@@ -457,7 +486,7 @@
                 }
 
                 mb->mv_x = mb->mv_y = 0; /* no motion vector coded */
-                if (band->inherit_mv) {
+                if (band->inherit_mv && ref_mb) {
                     /* motion vector inheritance */
                     if (mv_scale) {
                         mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
@@ -468,7 +497,7 @@
                     }
                 }
             } else {
-                if (band->inherit_mv) {
+                if (band->inherit_mv && ref_mb) {
                     mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */
                 } else if (ctx->frame_type == FRAMETYPE_INTRA ||
                            ctx->frame_type == FRAMETYPE_INTRA1) {
@@ -492,7 +521,7 @@
                 if (!mb->type) {
                     mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */
                 } else {
-                    if (band->inherit_mv) {
+                    if (band->inherit_mv && ref_mb) {
                         /* motion vector inheritance */
                         if (mv_scale) {
                             mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
@@ -515,6 +544,15 @@
                 }
             }
 
+            s= band->is_halfpel;
+            if (mb->type)
+            if ( x +  (mb->mv_x   >>s) +                 (y+               (mb->mv_y   >>s))*band->pitch < 0 ||
+                 x + ((mb->mv_x+s)>>s) + band->mb_size - 1
+                   + (y+band->mb_size - 1 +((mb->mv_y+s)>>s))*band->pitch > band->bufsize -1) {
+                av_log(avctx, AV_LOG_ERROR, "motion vector %d %d outside reference\n", x*s + mb->mv_x, y*s + mb->mv_y);
+                return AVERROR_INVALIDDATA;
+            }
+
             mb++;
             if (ref_mb)
                 ref_mb++;
diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c
index e9f7733..423d79b 100644
--- a/libavcodec/indeo5.c
+++ b/libavcodec/indeo5.c
@@ -2,20 +2,20 @@
  * Indeo Video Interactive v5 compatible decoder
  * Copyright (c) 2009 Maxim Poliakovski
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -59,7 +59,7 @@
  */
 static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx)
 {
-    int             result, i, p, tile_size, pic_size_indx, mb_size, blk_size;
+    int             result, i, p, tile_size, pic_size_indx, mb_size, blk_size, is_scalable;
     int             quant_mat, blk_size_changed = 0;
     IVIBandDesc     *band, *band1, *band2;
     IVIPicConfig    pic_conf;
@@ -81,8 +81,8 @@
     /* num_levels * 3 + 1 */
     pic_conf.luma_bands   = get_bits(&ctx->gb, 2) * 3 + 1;
     pic_conf.chroma_bands = get_bits1(&ctx->gb)   * 3 + 1;
-    ctx->is_scalable = pic_conf.luma_bands != 1 || pic_conf.chroma_bands != 1;
-    if (ctx->is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) {
+    is_scalable = pic_conf.luma_bands != 1 || pic_conf.chroma_bands != 1;
+    if (is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) {
         av_log(avctx, AV_LOG_ERROR, "Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d\n",
                pic_conf.luma_bands, pic_conf.chroma_bands);
         return -1;
@@ -120,6 +120,7 @@
             return -1;
         }
         ctx->pic_conf = pic_conf;
+        ctx->is_scalable = is_scalable;
         blk_size_changed = 1; /* force reallocation of the internal structures */
     }
 
@@ -133,6 +134,11 @@
             blk_size = 8 >> get_bits1(&ctx->gb);
             mb_size  = blk_size << !mb_size;
 
+            if (p==0 && blk_size==4) {
+                av_log(avctx, AV_LOG_ERROR, "4x4 luma blocks are unsupported!\n");
+                return AVERROR_PATCHWELCOME;
+            }
+
             blk_size_changed = mb_size != band->mb_size || blk_size != band->blk_size;
             if (blk_size_changed) {
                 band->mb_size  = mb_size;
@@ -150,30 +156,35 @@
                 band->inv_transform = ff_ivi_inverse_slant_8x8;
                 band->dc_transform  = ff_ivi_dc_slant_2d;
                 band->scan          = ff_zigzag_direct;
+                band->transform_size= 8;
                 break;
 
             case 1:
                 band->inv_transform = ff_ivi_row_slant8;
                 band->dc_transform  = ff_ivi_dc_row_slant;
                 band->scan          = ff_ivi_vertical_scan_8x8;
+                band->transform_size= 8;
                 break;
 
             case 2:
                 band->inv_transform = ff_ivi_col_slant8;
                 band->dc_transform  = ff_ivi_dc_col_slant;
                 band->scan          = ff_ivi_horizontal_scan_8x8;
+                band->transform_size= 8;
                 break;
 
             case 3:
                 band->inv_transform = ff_ivi_put_pixels_8x8;
                 band->dc_transform  = ff_ivi_put_dc_pixel_8x8;
                 band->scan          = ff_ivi_horizontal_scan_8x8;
+                band->transform_size= 8;
                 break;
 
             case 4:
                 band->inv_transform = ff_ivi_inverse_slant_4x4;
                 band->dc_transform  = ff_ivi_dc_slant_2d;
                 band->scan          = ff_ivi_direct_scan_4x4;
+                band->transform_size= 4;
                 break;
             }
 
@@ -188,6 +199,10 @@
             }
 
             if (band->blk_size == 8) {
+                if(quant_mat >= 5){
+                    av_log(avctx, AV_LOG_ERROR, "quant_mat %d too large!\n", quant_mat);
+                    return -1;
+                }
                 band->intra_base  = &ivi5_base_quant_8x8_intra[quant_mat][0];
                 band->inter_base  = &ivi5_base_quant_8x8_inter[quant_mat][0];
                 band->intra_scale = &ivi5_scale_quant_8x8_intra[quant_mat][0];
@@ -224,6 +239,7 @@
         band2->inv_transform = band1->inv_transform;
         band2->dc_transform  = band1->dc_transform;
         band2->is_2d_trans   = band1->is_2d_trans;
+        band2->transform_size= band1->transform_size;
     }
 
     /* reallocate internal structures if needed */
@@ -312,6 +328,12 @@
         ctx->gop_invalid = 0;
     }
 
+    if (ctx->frame_type == FRAMETYPE_INTER_SCAL && !ctx->is_scalable) {
+        av_log(avctx, AV_LOG_ERROR, "Scalable inter frame in non scaleable stream\n");
+        ctx->frame_type = FRAMETYPE_INTER;
+        return AVERROR_INVALIDDATA;
+    }
+
     if (ctx->frame_type != FRAMETYPE_NULL) {
         ctx->frame_flags = get_bits(&ctx->gb, 8);
 
@@ -418,7 +440,7 @@
                           IVITile *tile, AVCodecContext *avctx)
 {
     int         x, y, mv_x, mv_y, mv_delta, offs, mb_offset,
-                mv_scale, blks_per_mb;
+                mv_scale, blks_per_mb, s;
     IVIMbInfo   *mb, *ref_mb;
     int         row_offset = band->mb_size * band->pitch;
 
@@ -464,7 +486,7 @@
                 }
 
                 mb->mv_x = mb->mv_y = 0; /* no motion vector coded */
-                if (band->inherit_mv){
+                if (band->inherit_mv && ref_mb){
                     /* motion vector inheritance */
                     if (mv_scale) {
                         mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
@@ -475,7 +497,7 @@
                     }
                 }
             } else {
-                if (band->inherit_mv) {
+                if (band->inherit_mv && ref_mb) {
                     mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */
                 } else if (ctx->frame_type == FRAMETYPE_INTRA) {
                     mb->type = 0; /* mb_type is always INTRA for intra-frames */
@@ -501,7 +523,7 @@
                 if (!mb->type) {
                     mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */
                 } else {
-                    if (band->inherit_mv){
+                    if (band->inherit_mv && ref_mb){
                         /* motion vector inheritance */
                         if (mv_scale) {
                             mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
@@ -524,6 +546,15 @@
                 }
             }
 
+            s= band->is_halfpel;
+            if (mb->type)
+            if ( x +  (mb->mv_x   >>s) +                 (y+               (mb->mv_y   >>s))*band->pitch < 0 ||
+                 x + ((mb->mv_x+s)>>s) + band->mb_size - 1
+                   + (y+band->mb_size - 1 +((mb->mv_y+s)>>s))*band->pitch > band->bufsize - 1) {
+                av_log(avctx, AV_LOG_ERROR, "motion vector %d %d outside reference\n", x*s + mb->mv_x, y*s + mb->mv_y);
+                return AVERROR_INVALIDDATA;
+            }
+
             mb++;
             if (ref_mb)
                 ref_mb++;
@@ -612,6 +643,8 @@
     ctx->pic_conf.tile_height   = avctx->height;
     ctx->pic_conf.luma_bands    = ctx->pic_conf.chroma_bands = 1;
 
+    avcodec_get_frame_defaults(&ctx->frame);
+
     result = ff_ivi_init_planes(ctx->planes, &ctx->pic_conf);
     if (result) {
         av_log(avctx, AV_LOG_ERROR, "Couldn't allocate color planes!\n");
@@ -632,7 +665,6 @@
     return 0;
 }
 
-
 AVCodec ff_indeo5_decoder = {
     .name           = "indeo5",
     .type           = AVMEDIA_TYPE_VIDEO,
diff --git a/libavcodec/indeo5data.h b/libavcodec/indeo5data.h
index f4252b5..a6217d0 100644
--- a/libavcodec/indeo5data.h
+++ b/libavcodec/indeo5data.h
@@ -2,20 +2,20 @@
  * Indeo Video Interactive 5 compatible decoder
  * Copyright (c) 2009 Maxim Poliakovski
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/intelh263dec.c b/libavcodec/intelh263dec.c
index 0701cde..ac2695e 100644
--- a/libavcodec/intelh263dec.c
+++ b/libavcodec/intelh263dec.c
@@ -1,20 +1,20 @@
 /*
  * H.263i decoder
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -54,14 +54,14 @@
 
     s->pict_type = AV_PICTURE_TYPE_I + get_bits1(&s->gb);
 
-    s->unrestricted_mv = get_bits1(&s->gb);
-    s->h263_long_vectors = s->unrestricted_mv;
+    s->h263_long_vectors = get_bits1(&s->gb);
 
     if (get_bits1(&s->gb) != 0) {
         av_log(s->avctx, AV_LOG_ERROR, "SAC not supported\n");
         return -1;      /* SAC: off */
     }
     s->obmc= get_bits1(&s->gb);
+    s->unrestricted_mv = s->obmc || s->h263_long_vectors;
     s->pb_frame = get_bits1(&s->gb);
 
     if (format < 6) {
@@ -77,7 +77,7 @@
         }
         if(get_bits(&s->gb, 2))
             av_log(s->avctx, AV_LOG_ERROR, "Bad value for reserved field\n");
-        s->loop_filter = get_bits1(&s->gb);
+        s->loop_filter = get_bits1(&s->gb) * !s->avctx->lowres;
         if(get_bits1(&s->gb))
             av_log(s->avctx, AV_LOG_ERROR, "Bad value for reserved field\n");
         if(get_bits1(&s->gb))
diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index e5b1958..ed38c61 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -76,6 +76,19 @@
      * padded with silence. Reject all subsequent frames.
      */
     int last_audio_frame;
+
+    /**
+     * temporary buffer used for encoders to store their bitstream
+     */
+    uint8_t *byte_buffer;
+    unsigned int byte_buffer_size;
+
+    void *frame_thread_encoder;
+
+    /**
+     * Number of audio samples to skip at the start of the next decoded frame
+     */
+    int skip_samples;
 } AVCodecInternal;
 
 struct AVCodecDefault {
@@ -106,6 +119,16 @@
 
 unsigned int avpriv_toupper4(unsigned int x);
 
+/**
+ * does needed setup of pkt_pts/pos and such for (re)get_buffer();
+ */
+void ff_init_buffer_info(AVCodecContext *s, AVFrame *frame);
+
+/**
+ * Remove and free all side data from packet.
+ */
+void ff_packet_free_side_data(AVPacket *pkt);
+
 int avpriv_lock_avformat(void);
 int avpriv_unlock_avformat(void);
 
@@ -123,6 +146,7 @@
  * ensure the output packet data is large enough, whether provided by the user
  * or allocated in this function.
  *
+ * @param avctx   the AVCodecContext of the encoder
  * @param avpkt   the AVPacket
  *                If avpkt->data is already set, avpkt->size is checked
  *                to ensure it is large enough.
@@ -132,6 +156,8 @@
  * @param size    the minimum required packet size
  * @return        0 on success, negative error code on failure
  */
+int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int size);
+
 int ff_alloc_packet(AVPacket *avpkt, int size);
 
 /**
@@ -140,8 +166,16 @@
 static av_always_inline int64_t ff_samples_to_time_base(AVCodecContext *avctx,
                                                         int64_t samples)
 {
+    if(samples == AV_NOPTS_VALUE)
+        return AV_NOPTS_VALUE;
     return av_rescale_q(samples, (AVRational){ 1, avctx->sample_rate },
                         avctx->time_base);
 }
 
+int ff_thread_can_start_frame(AVCodecContext *avctx);
+
+int ff_get_logical_cpus(AVCodecContext *avctx);
+
+int avpriv_h264_has_num_reorder_frames(AVCodecContext *avctx);
+
 #endif /* AVCODEC_INTERNAL_H */
diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c
index 60ccf37..6892936 100644
--- a/libavcodec/interplayvideo.c
+++ b/libavcodec/interplayvideo.c
@@ -2,20 +2,20 @@
  * Interplay MVE Video Decoder
  * Copyright (C) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -72,10 +72,10 @@
     int motion_offset = current_offset + delta_y * s->current_frame.linesize[0]
                        + delta_x * (1 + s->is_16bpp);
     if (motion_offset < 0) {
-        av_log(s->avctx, AV_LOG_ERROR, " Interplay video: motion offset < 0 (%d)\n", motion_offset);
+        av_log(s->avctx, AV_LOG_ERROR, "motion offset < 0 (%d)\n", motion_offset);
         return -1;
     } else if (motion_offset > s->upper_motion_limit_offset) {
-        av_log(s->avctx, AV_LOG_ERROR, " Interplay video: motion offset above limit (%d >= %d)\n",
+        av_log(s->avctx, AV_LOG_ERROR, "motion offset above limit (%d >= %d)\n",
             motion_offset, s->upper_motion_limit_offset);
         return -1;
     }
@@ -118,7 +118,7 @@
         y =   8 + ((B - 56) / 29);
     }
 
-    av_dlog(NULL, "    motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
+    av_dlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
     return copy_from(s, &s->second_last_frame, x, y);
 }
 
@@ -144,7 +144,7 @@
         y = -(  8 + ((B - 56) / 29));
     }
 
-    av_dlog(NULL, "    motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
+    av_dlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
     return copy_from(s, &s->current_frame, x, y);
 }
 
@@ -165,7 +165,7 @@
     x = -8 + BL;
     y = -8 + BH;
 
-    av_dlog(NULL, "    motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
+    av_dlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
     return copy_from(s, &s->last_frame, x, y);
 }
 
@@ -178,14 +178,14 @@
     x = bytestream2_get_byte(&s->stream_ptr);
     y = bytestream2_get_byte(&s->stream_ptr);
 
-    av_dlog(NULL, "    motion bytes = %d, %d\n", x, y);
+    av_dlog(s->avctx, "motion bytes = %d, %d\n", x, y);
     return copy_from(s, &s->last_frame, x, y);
 }
 
 static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s)
 {
     /* mystery opcode? skip multiple blocks? */
-    av_log(s->avctx, AV_LOG_ERROR, "  Interplay video: Help! Mystery opcode 0x6 seen\n");
+    av_log(s->avctx, AV_LOG_ERROR, "Help! Mystery opcode 0x6 seen\n");
 
     /* report success */
     return 0;
@@ -528,7 +528,7 @@
     x = bytestream2_get_byte(&s->stream_ptr);
     y = bytestream2_get_byte(&s->stream_ptr);
 
-    av_dlog(NULL, "    motion bytes = %d, %d\n", x, y);
+    av_dlog(s->avctx, "motion bytes = %d, %d\n", x, y);
     return copy_from(s, &s->second_last_frame, x, y);
 }
 
@@ -884,7 +884,7 @@
     static int frame = 0;
     GetBitContext gb;
 
-    av_dlog(NULL, "------------------ frame %d\n", frame);
+    av_dlog(s->avctx, "frame %d\n", frame);
     frame++;
 
     bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */
@@ -921,7 +921,7 @@
                 ret = ipvideo_decode_block16[opcode](s);
             }
             if (ret != 0) {
-                av_log(s->avctx, AV_LOG_ERROR, " Interplay video: decode problem on frame %d, @ block (%d, %d)\n",
+                av_log(s->avctx, AV_LOG_ERROR, "decode problem on frame %d, @ block (%d, %d)\n",
                        frame, x, y);
                 return;
             }
@@ -929,7 +929,7 @@
     }
     if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
         av_log(s->avctx, AV_LOG_ERROR,
-               "Interplay video: decode finished with %d bytes left over\n",
+               "decode finished with %d bytes left over\n",
                bytestream2_get_bytes_left(&s->stream_ptr));
     }
 }
@@ -945,6 +945,10 @@
 
     ff_dsputil_init(&s->dsp, avctx);
 
+    avcodec_get_frame_defaults(&s->second_last_frame);
+    avcodec_get_frame_defaults(&s->last_frame);
+    avcodec_get_frame_defaults(&s->current_frame);
+
     s->current_frame.data[0] = s->last_frame.data[0] =
     s->second_last_frame.data[0] = NULL;
 
@@ -973,7 +977,7 @@
 
     s->current_frame.reference = 3;
     if (avctx->get_buffer(avctx, &s->current_frame)) {
-        av_log(avctx, AV_LOG_ERROR, "  Interplay Video: get_buffer() failed\n");
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
 
diff --git a/libavcodec/intrax8.c b/libavcodec/intrax8.c
index fad7ffe..fe1e770 100644
--- a/libavcodec/intrax8.c
+++ b/libavcodec/intrax8.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -21,6 +21,7 @@
  * @brief IntraX8 (J-Frame) subdecoder, used by WMV2 and VC-1
  */
 
+#include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "mpegvideo.h"
@@ -125,13 +126,13 @@
     MpegEncContext * const s= w->s;
     int table_index;
 
-    assert(mode<4);
+    av_assert2(mode<4);
 
     if( w->j_ac_vlc[mode] ) return;
 
     table_index = get_bits(&s->gb, 3);
     w->j_ac_vlc[mode] = &j_ac_vlc[w->quant<13][mode>>1][table_index];//2 modes use same tables
-    assert(w->j_ac_vlc[mode]);
+    av_assert2(w->j_ac_vlc[mode]);
 }
 
 static inline int x8_get_orient_vlc(IntraX8Context * w){
@@ -142,8 +143,6 @@
         table_index = get_bits(&s->gb, 1+(w->quant<13) );
         w->j_orient_vlc = &j_orient_vlc[w->quant<13][table_index];
     }
-    assert(w->j_orient_vlc);
-    assert(w->j_orient_vlc->table);
 
     return get_vlc2(&s->gb, w->j_orient_vlc->table, OR_VLC_BITS, OR_VLC_MTD);
 }
@@ -265,15 +264,13 @@
     MpegEncContext * const s= w->s;
     int i,e,c;
 
-    assert(mode<3);
+    av_assert2(mode<3);
     if( !w->j_dc_vlc[mode] ) {
         int table_index;
         table_index = get_bits(&s->gb, 3);
         //4 modes, same table
         w->j_dc_vlc[mode]= &j_dc_vlc[w->quant<13][table_index];
     }
-    assert(w->j_dc_vlc);
-    assert(w->j_dc_vlc[mode]->table);
 
     i=get_vlc2(&s->gb, w->j_dc_vlc[mode]->table, DC_VLC_BITS, DC_VLC_MTD);
 
@@ -326,7 +323,7 @@
     if(chroma)
         return 0;
 
-    assert(w->orient < 3);
+    av_assert2(w->orient < 3);
     if(range < 2*w->quant){
         if( (w->edges&3) == 0){
             if(w->orient==1) w->orient=11;
@@ -343,8 +340,8 @@
         };
         w->raw_orient=x8_get_orient_vlc(w);
         if(w->raw_orient<0) return -1;
-        assert(w->raw_orient < 12 );
-        assert(w->orient<3);
+        av_assert2(w->raw_orient < 12 );
+        av_assert2(w->orient<3);
         w->orient=prediction_table[w->orient][w->raw_orient];
     }
     return 0;
@@ -536,7 +533,7 @@
     int use_quant_matrix;
     int sign;
 
-    assert(w->orient<12);
+    av_assert2(w->orient<12);
     s->dsp.clear_block(s->block[0]);
 
     if(chroma){
@@ -694,7 +691,7 @@
 
     w->s=s;
     x8_vlc_init();
-    assert(s->mb_width>0);
+    av_assert0(s->mb_width>0);
     w->prediction_table=av_mallocz(s->mb_width*2*2);//two rows, 2 blocks per cannon mb
 
     ff_init_scantable(s->dsp.idct_permutation, &w->scantable[0], ff_wmv1_scantable[0]);
@@ -719,6 +716,7 @@
  * The parent codec must call MPV_frame_start(), ff_er_frame_start() before calling this function.
  * The parent codec must call ff_er_frame_end(), MPV_frame_end() after calling this function.
  * This function does not use MPV_decode_mb().
+ * lowres decoding is theoretically impossible.
  * @param w pointer to IntraX8Context
  * @param dquant doubled quantizer, it would be odd in case of VC-1 halfpq==1.
  * @param quant_offset offset away from zero
@@ -727,7 +725,6 @@
 int ff_intrax8_decode_picture(IntraX8Context * const w, int dquant, int quant_offset){
     MpegEncContext * const s= w->s;
     int mb_xy;
-    assert(s);
     w->use_quant_matrix = get_bits1(&s->gb);
 
     w->dquant = dquant;
diff --git a/libavcodec/intrax8.h b/libavcodec/intrax8.h
index 6967317..40d689a 100644
--- a/libavcodec/intrax8.h
+++ b/libavcodec/intrax8.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/intrax8dsp.c b/libavcodec/intrax8dsp.c
index ddceb2c..447ad21 100644
--- a/libavcodec/intrax8dsp.c
+++ b/libavcodec/intrax8dsp.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/intrax8dsp.h b/libavcodec/intrax8dsp.h
index 5c3cc4a..1e4a3af 100644
--- a/libavcodec/intrax8dsp.h
+++ b/libavcodec/intrax8dsp.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/intrax8huf.h b/libavcodec/intrax8huf.h
index 6bf01f3..375906b 100644
--- a/libavcodec/intrax8huf.h
+++ b/libavcodec/intrax8huf.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c
index cb26be2..6d43233 100644
--- a/libavcodec/ituh263dec.c
+++ b/libavcodec/ituh263dec.c
@@ -5,20 +5,20 @@
  * Copyright (c) 2001 Juan J. Sierralta P
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -27,6 +27,8 @@
  * h263 decoder.
  */
 
+#define UNCHECKED_BITSTREAM_READER 1
+
 //#define DEBUG
 #include <limits.h>
 
@@ -40,9 +42,6 @@
 #include "flv.h"
 #include "mpeg4video.h"
 
-//#undef NDEBUG
-//#include <assert.h>
-
 // The defines below define the number of bits that are read at once for
 // reading vlc values. Changing these may improve speed and data cache needs
 // be aware though that decreasing them may need the number of stages that is
@@ -208,16 +207,19 @@
  * @param end pointer to the end of the buffer
  * @return pointer to the next resync_marker, or end if none was found
  */
-const uint8_t *ff_h263_find_resync_marker(const uint8_t *restrict p, const uint8_t * restrict end)
+const uint8_t *ff_h263_find_resync_marker(MpegEncContext *s, const uint8_t *av_restrict p, const uint8_t *av_restrict end)
 {
-    assert(p < end);
+    av_assert2(p < end);
 
     end-=2;
     p++;
-    for(;p<end; p+=2){
-        if(!*p){
-            if     (!p[-1] && p[1]) return p - 1;
-            else if(!p[ 1] && p[2]) return p;
+    if(s->resync_marker){
+        int prefix_len = ff_mpeg4_get_video_packet_prefix_length(s);
+        for(;p<end; p+=2){
+            if(!*p){
+                if      (!p[-1] && ((p[1] >> (23-prefix_len)) == 1)) return p - 1;
+                else if (!p[ 1] && ((p[2] >> (23-prefix_len)) == 1)) return p;
+            }
         }
     }
     return end+2;
@@ -347,7 +349,7 @@
         s->block_index[i]+= 1;
     s->mb_x++;
 
-    assert(s->pict_type == AV_PICTURE_TYPE_P);
+    av_assert2(s->pict_type == AV_PICTURE_TYPE_P);
 
     do{
         if (get_bits1(&s->gb)) {
@@ -484,7 +486,7 @@
             level = get_bits(&s->gb, 8);
             if((level&0x7F) == 0){
                 av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", level, s->mb_x, s->mb_y);
-                if(s->err_recognition & AV_EF_BITSTREAM)
+                if(s->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))
                     return -1;
             }
             if (level == 255)
@@ -606,7 +608,7 @@
     const int xy= s->mb_x + s->mb_y * s->mb_stride;
     int cbpb = 0, pb_mv_count = 0;
 
-    assert(!s->h263_pred);
+    av_assert2(!s->h263_pred);
 
     if (s->pict_type == AV_PICTURE_TYPE_P) {
         do{
@@ -746,7 +748,7 @@
         }else
             cbp=0;
 
-        assert(!s->mb_intra);
+        av_assert2(!s->mb_intra);
 
         if(IS_QUANT(mb_type)){
             h263_decode_dquant(s);
@@ -961,6 +963,8 @@
             s->h263_aic = get_bits1(&s->gb); /* Advanced Intra Coding (AIC) */
             s->loop_filter= get_bits1(&s->gb);
             s->unrestricted_mv = s->umvplus || s->obmc || s->loop_filter;
+            if(s->avctx->lowres)
+                s->loop_filter = 0;
 
             s->h263_slice_structured= get_bits1(&s->gb);
             if (get_bits1(&s->gb) != 0) {
@@ -1128,7 +1132,7 @@
     }
 
         ff_h263_show_pict_info(s);
-    if (s->pict_type == AV_PICTURE_TYPE_I && s->codec_tag == AV_RL32("ZYGO")){
+    if (s->pict_type == AV_PICTURE_TYPE_I && s->codec_tag == AV_RL32("ZYGO") && get_bits_left(&s->gb) >= 85 + 13*3*16 + 50){
         int i,j;
         for(i=0; i<85; i++) av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&s->gb));
         av_log(s->avctx, AV_LOG_DEBUG, "\n");
diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c
index f95b1cd..3eb198f 100644
--- a/libavcodec/ituh263enc.c
+++ b/libavcodec/ituh263enc.c
@@ -5,20 +5,20 @@
  * Copyright (c) 2001 Juan J. Sierralta P
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -40,9 +40,6 @@
 #include "mpeg4video.h"
 #include "internal.h"
 
-//#undef NDEBUG
-//#include <assert.h>
-
 /**
  * Table of number of bits a motion vector component needs.
  */
@@ -229,7 +226,7 @@
     if(s->h263_slice_structured){
         put_bits(&s->pb, 1, 1);
 
-        assert(s->mb_x == 0 && s->mb_y == 0);
+        av_assert1(s->mb_x == 0 && s->mb_y == 0);
         ff_h263_encode_mba(s);
 
         put_bits(&s->pb, 1, 1);
@@ -271,7 +268,7 @@
 }
 
 /**
- * modify qscale so that encoding is acually possible in h263 (limit difference to -2..2)
+ * modify qscale so that encoding is actually possible in h263 (limit difference to -2..2)
  */
 void ff_clean_h263_qscales(MpegEncContext *s){
     int i;
@@ -396,7 +393,7 @@
                 put_bits(&s->pb, 1, last);
                 put_bits(&s->pb, 6, run);
 
-                assert(slevel != 0);
+                av_assert2(slevel != 0);
 
                 if(level < 128)
                     put_sbits(&s->pb, 8, slevel);
@@ -549,7 +546,7 @@
             s->mv_bits+= get_bits_diff(s);
         }
     } else {
-        assert(s->mb_intra);
+        av_assert2(s->mb_intra);
 
         cbp = 0;
         if (s->h263_aic) {
@@ -728,8 +725,8 @@
 static void init_uni_h263_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_tab){
     int slevel, run, last;
 
-    assert(MAX_LEVEL >= 64);
-    assert(MAX_RUN   >= 63);
+    av_assert0(MAX_LEVEL >= 64);
+    av_assert0(MAX_RUN   >= 63);
 
     for(slevel=-64; slevel<64; slevel++){
         if(slevel==0) continue;
diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c
index 149fffe..17d8af4 100644
--- a/libavcodec/ivi_common.c
+++ b/libavcodec/ivi_common.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Maxim Poliakovski
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -133,7 +133,7 @@
                 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)) {
+            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 (huff_tab->cust_tab.table)
@@ -216,6 +216,7 @@
             band->aheight  = height_aligned;
             band->bufs[0]  = av_mallocz(buf_size);
             band->bufs[1]  = av_mallocz(buf_size);
+            band->bufsize  = buf_size/2;
             if (!band->bufs[0] || !band->bufs[1])
                 return AVERROR(ENOMEM);
 
@@ -267,6 +268,8 @@
             t_width  >>= 1;
             t_height >>= 1;
         }
+        if(t_width<=0 || t_height<=0)
+            return AVERROR(EINVAL);
 
         for (b = 0; b < planes[p].num_bands; b++) {
             band = &planes[p].bands[b];
@@ -435,7 +438,7 @@
 
                     /* de-zigzag and dequantize */
                     scan_pos += run;
-                    if (scan_pos >= num_coeffs)
+                    if (scan_pos >= (unsigned)num_coeffs)
                         break;
                     pos = band->scan[scan_pos];
 
@@ -458,7 +461,10 @@
                     trvec[0]      = prev_dc;
                     col_flags[0] |= !!prev_dc;
                 }
-
+                if(band->transform_size > band->blk_size){
+                    av_log(0, AV_LOG_ERROR, "Too large transform\n");
+                    return AVERROR_INVALIDDATA;
+                }
                 /* apply inverse transform */
                 band->inv_transform(trvec, band->buf + buf_offs,
                                     band->pitch, col_flags);
@@ -543,7 +549,7 @@
             if (band->inherit_qdelta && ref_mb)
                 mb->q_delta = ref_mb->q_delta;
 
-            if (band->inherit_mv) {
+            if (band->inherit_mv && ref_mb) {
                 /* motion vector inheritance */
                 if (mv_scale) {
                     mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
@@ -678,6 +684,10 @@
         idx2 = band->corr[i * 2 + 1];
         FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
         FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
+        if (idx1 == band->rv_map->eob_sym || idx2 == band->rv_map->eob_sym)
+            band->rv_map->eob_sym ^= idx1 ^ idx2;
+        if (idx1 == band->rv_map->esc_sym || idx2 == band->rv_map->esc_sym)
+            band->rv_map->esc_sym ^= idx1 ^ idx2;
     }
 
     pos = get_bits_count(&ctx->gb);
@@ -701,7 +711,8 @@
             tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb);
             if (!tile->data_size) {
                 av_log(avctx, AV_LOG_ERROR, "Tile data size is zero!\n");
-                return AVERROR_INVALIDDATA;
+                result = AVERROR_INVALIDDATA;
+                break;
             }
 
             result = ctx->decode_mb_info(ctx, band, tile, avctx);
@@ -724,6 +735,10 @@
         idx2 = band->corr[i*2+1];
         FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]);
         FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]);
+        if (idx1 == band->rv_map->eob_sym || idx2 == band->rv_map->eob_sym)
+            band->rv_map->eob_sym ^= idx1 ^ idx2;
+        if (idx1 == band->rv_map->esc_sym || idx2 == band->rv_map->esc_sym)
+            band->rv_map->esc_sym ^= idx1 ^ idx2;
     }
 
 #ifdef DEBUG
@@ -773,6 +788,7 @@
     //{ START_TIMER;
 
     if (ctx->is_nonnull_frame(ctx)) {
+        ctx->buf_invalid[ctx->dst_buf] = 1;
         for (p = 0; p < 3; p++) {
             for (b = 0; b < ctx->planes[p].num_bands; b++) {
                 result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx);
@@ -783,7 +799,10 @@
                 }
             }
         }
+        ctx->buf_invalid[ctx->dst_buf] = 0;
     }
+    if (ctx->buf_invalid[ctx->dst_buf])
+        return -1;
 
     //STOP_TIMER("decode_planes"); }
 
@@ -797,6 +816,9 @@
             av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n");
     }
 
+    if (!ctx->is_nonnull_frame(ctx))
+        return buf_size;
+
     if (ctx->frame.data[0])
         avctx->release_buffer(avctx, &ctx->frame);
 
diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h
index 7c6d131..44b28cd 100644
--- a/libavcodec/ivi_common.h
+++ b/libavcodec/ivi_common.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Maxim Poliakovski
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -164,6 +164,7 @@
     InvTransformPtr *inv_transform;
     DCTransformPtr  *dc_transform;
     int             is_2d_trans;    ///< 1 indicates that the two-dimensional inverse transform is used
+    int             transform_size; ///< block size of the transform
     int32_t         checksum;       ///< for debug purposes
     int             checksum_present;
     int             bufsize;        ///< band buffer size in bytes
@@ -250,6 +251,7 @@
     int             (*is_nonnull_frame)(struct IVI45DecContext *ctx);
 
     int gop_invalid;
+    int buf_invalid[3];
 } IVI45DecContext;
 
 /** compare some properties of two pictures */
@@ -279,7 +281,7 @@
 
 /**
  *  Generate a huffman codebook from the given descriptor
- *  and convert it into the Libav VLC table.
+ *  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
diff --git a/libavcodec/ivi_dsp.c b/libavcodec/ivi_dsp.c
index 3ffe84a..52cd402 100644
--- a/libavcodec/ivi_dsp.c
+++ b/libavcodec/ivi_dsp.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009-2011 Maxim Poliakovski
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -56,6 +56,9 @@
     b3_ptr = plane->bands[3].buf;
 
     for (y = 0; y < plane->height; y += 2) {
+
+        if (y+2 >= plane->height)
+            pitch= 0;
         /* load storage variables with values */
         if (num_bands > 0) {
             b0_1 = b0_ptr[0];
@@ -85,6 +88,13 @@
         }
 
         for (x = 0, indx = 0; x < plane->width; x+=2, indx++) {
+            if (x+2 >= plane->width) {
+                b0_ptr --;
+                b1_ptr --;
+                b2_ptr --;
+                b3_ptr --;
+            }
+
             /* some values calculated in the previous iterations can */
             /* be reused in the next ones, so do appropriate copying */
             b2_1 = b2_2; // b2[x-1,y  ] = b2[x,  y  ]
@@ -172,10 +182,10 @@
 
         back_pitch = -pitch;
 
-        b0_ptr += pitch;
-        b1_ptr += pitch;
-        b2_ptr += pitch;
-        b3_ptr += pitch;
+        b0_ptr += pitch + 1;
+        b1_ptr += pitch + 1;
+        b2_ptr += pitch + 1;
+        b3_ptr += pitch + 1;
     }
 }
 
diff --git a/libavcodec/ivi_dsp.h b/libavcodec/ivi_dsp.h
index c46f8b2..e95bb11 100644
--- a/libavcodec/ivi_dsp.h
+++ b/libavcodec/ivi_dsp.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009-2011 Maxim Poliakovski
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/j2k.c b/libavcodec/j2k.c
new file mode 100644
index 0000000..606a3d8
--- /dev/null
+++ b/libavcodec/j2k.c
@@ -0,0 +1,391 @@
+/*
+ * JPEG2000 encoder and decoder common functions
+ * Copyright (c) 2007 Kamil Nowosad
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * JPEG2000 image encoder and decoder common functions
+ * @file
+ * @author Kamil Nowosad
+ */
+
+
+#include "avcodec.h"
+#include "j2k.h"
+
+#define SHL(a, n) ((n)>=0 ? (a) << (n) : (a) >> -(n))
+
+#if 0
+void ff_j2k_printv(int *tab, int l)
+{
+    int i;
+    for (i = 0; i < l; i++)
+        printf("%.3d ", tab[i]);
+    printf("\n");
+}
+
+void ff_j2k_printu(uint8_t *tab, int l)
+{
+    int i;
+    for (i = 0; i < l; i++)
+        printf("%.3hd ", tab[i]);
+    printf("\n");
+}
+#endif
+
+/* tag tree routines */
+
+/** allocate the memory for tag tree */
+
+static int tag_tree_size(int w, int h)
+{
+    int res = 0;
+    while (w > 1 || h > 1){
+        res += w * h;
+        w = (w+1) >> 1;
+        h = (h+1) >> 1;
+    }
+    return res + 1;
+}
+
+J2kTgtNode *ff_j2k_tag_tree_init(int w, int h)
+{
+    int pw = w, ph = h;
+    J2kTgtNode *res, *t, *t2;
+
+    t = res = av_mallocz(tag_tree_size(w, h)*sizeof(J2kTgtNode));
+
+    if (res == NULL)
+        return NULL;
+
+    while (w > 1 || h > 1){
+        int i, j;
+        pw = w;
+        ph = h;
+
+        w = (w+1) >> 1;
+        h = (h+1) >> 1;
+        t2 = t + pw*ph;
+
+        for (i = 0; i < ph; i++)
+            for (j = 0; j < pw; j++){
+                t[i*pw + j].parent = &t2[(i>>1)*w + (j>>1)];
+            }
+        t = t2;
+    }
+    t[0].parent = NULL;
+    return res;
+}
+
+static void tag_tree_zero(J2kTgtNode *t, int w, int h)
+{
+    int i, siz = tag_tree_size(w, h);
+
+    for (i = 0; i < siz; i++){
+        t[i].val = 0;
+        t[i].vis = 0;
+    }
+}
+
+uint8_t ff_j2k_nbctxno_lut[256][4];
+
+static int getnbctxno(int flag, int bandno, int vert_causal_ctx_csty_symbol)
+{
+    int h, v, d;
+
+    h = ((flag & J2K_T1_SIG_E) ? 1:0)+
+        ((flag & J2K_T1_SIG_W) ? 1:0);
+    v = ((flag & J2K_T1_SIG_N) ? 1:0);
+    if (!vert_causal_ctx_csty_symbol)
+         v = v + ((flag & J2K_T1_SIG_S) ? 1:0);
+    d = ((flag & J2K_T1_SIG_NE) ? 1:0)+
+        ((flag & J2K_T1_SIG_NW) ? 1:0);
+    if (!vert_causal_ctx_csty_symbol)
+        d = d + ((flag & J2K_T1_SIG_SE) ? 1:0)+
+                ((flag & J2K_T1_SIG_SW) ? 1:0);
+    if (bandno < 3){
+            if (bandno == 1)
+                FFSWAP(int, h, v);
+            if (h == 2) return 8;
+            if (h == 1){
+                if (v >= 1) return 7;
+                if (d >= 1) return 6;
+                return 5;
+            }
+            if (v == 2) return 4;
+            if (v == 1) return 3;
+            if (d >= 2) return 2;
+            if (d == 1) return 1;
+            return 0;
+    } else{
+            if (d >= 3) return 8;
+            if (d == 2){
+                if (h+v >= 1) return 7;
+                return 6;
+            }
+            if (d == 1){
+                if (h+v >= 2) return 5;
+                if (h+v == 1) return 4;
+                return 3;
+            }
+            if (h+v >= 2) return 2;
+            if (h+v == 1) return 1;
+            return 0;
+    }
+}
+
+uint8_t ff_j2k_sgnctxno_lut[16][16], ff_j2k_xorbit_lut[16][16];
+
+static int getsgnctxno(int flag, uint8_t *xorbit)
+{
+    int vcontrib, hcontrib;
+    static const int contribtab[3][3] = {{0, -1, 1}, {-1, -1, 0}, {1, 0, 1}};
+    static const int ctxlbltab[3][3] = {{13, 12, 11}, {10, 9, 10}, {11, 12, 13}};
+    static const int xorbittab[3][3] = {{1, 1, 1,}, {1, 0, 0}, {0, 0, 0}};
+
+    hcontrib = contribtab[flag & J2K_T1_SIG_E ? flag & J2K_T1_SGN_E ? 1:2:0]
+                         [flag & J2K_T1_SIG_W ? flag & J2K_T1_SGN_W ? 1:2:0]+1;
+    vcontrib = contribtab[flag & J2K_T1_SIG_S ? flag & J2K_T1_SGN_S ? 1:2:0]
+                         [flag & J2K_T1_SIG_N ? flag & J2K_T1_SGN_N ? 1:2:0]+1;
+    *xorbit = xorbittab[hcontrib][vcontrib];
+    return ctxlbltab[hcontrib][vcontrib];
+}
+
+void ff_j2k_init_tier1_luts(void)
+{
+    int i, j;
+    for (i = 0; i < 256; i++)
+        for (j = 0; j < 4; j++)
+            ff_j2k_nbctxno_lut[i][j] = getnbctxno(i, j, 0);
+    for (i = 0; i < 16; i++)
+        for (j = 0; j < 16; j++)
+            ff_j2k_sgnctxno_lut[i][j] = getsgnctxno(i + (j << 8), &ff_j2k_xorbit_lut[i][j]);
+}
+
+void ff_j2k_set_significant(J2kT1Context *t1, int x, int y, int negative)
+{
+    x++; y++;
+    t1->flags[y][x] |= J2K_T1_SIG;
+    if (negative){
+        t1->flags[y][x+1] |= J2K_T1_SIG_W | J2K_T1_SGN_W;
+        t1->flags[y][x-1] |= J2K_T1_SIG_E | J2K_T1_SGN_E;
+        t1->flags[y+1][x] |= J2K_T1_SIG_N | J2K_T1_SGN_N;
+        t1->flags[y-1][x] |= J2K_T1_SIG_S | J2K_T1_SGN_S;
+    } else{
+        t1->flags[y][x+1] |= J2K_T1_SIG_W;
+        t1->flags[y][x-1] |= J2K_T1_SIG_E;
+        t1->flags[y+1][x] |= J2K_T1_SIG_N;
+        t1->flags[y-1][x] |= J2K_T1_SIG_S;
+    }
+    t1->flags[y+1][x+1] |= J2K_T1_SIG_NW;
+    t1->flags[y+1][x-1] |= J2K_T1_SIG_NE;
+    t1->flags[y-1][x+1] |= J2K_T1_SIG_SW;
+    t1->flags[y-1][x-1] |= J2K_T1_SIG_SE;
+}
+
+int ff_j2k_init_component(J2kComponent *comp, J2kCodingStyle *codsty, J2kQuantStyle *qntsty, int cbps, int dx, int dy)
+{
+    int reslevelno, bandno, gbandno = 0, ret, i, j, csize = 1;
+
+    if (ret=ff_j2k_dwt_init(&comp->dwt, comp->coord, codsty->nreslevels-1, codsty->transform))
+        return ret;
+    for (i = 0; i < 2; i++)
+        csize *= comp->coord[i][1] - comp->coord[i][0];
+
+    comp->data = av_malloc(csize * sizeof(int));
+    if (!comp->data)
+        return AVERROR(ENOMEM);
+    comp->reslevel = av_malloc(codsty->nreslevels * sizeof(J2kResLevel));
+
+    if (!comp->reslevel)
+        return AVERROR(ENOMEM);
+    for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){
+        int declvl = codsty->nreslevels - reslevelno;
+        J2kResLevel *reslevel = comp->reslevel + reslevelno;
+
+        for (i = 0; i < 2; i++)
+            for (j = 0; j < 2; j++)
+                reslevel->coord[i][j] =
+                    ff_j2k_ceildivpow2(comp->coord[i][j], declvl - 1);
+
+        if (reslevelno == 0)
+            reslevel->nbands = 1;
+        else
+            reslevel->nbands = 3;
+
+        if (reslevel->coord[0][1] == reslevel->coord[0][0])
+            reslevel->num_precincts_x = 0;
+        else
+            reslevel->num_precincts_x = ff_j2k_ceildivpow2(reslevel->coord[0][1], codsty->log2_prec_width)
+                                        - (reslevel->coord[0][0] >> codsty->log2_prec_width);
+
+        if (reslevel->coord[1][1] == reslevel->coord[1][0])
+            reslevel->num_precincts_y = 0;
+        else
+            reslevel->num_precincts_y = ff_j2k_ceildivpow2(reslevel->coord[1][1], codsty->log2_prec_height)
+                                        - (reslevel->coord[1][0] >> codsty->log2_prec_height);
+
+        reslevel->band = av_malloc(reslevel->nbands * sizeof(J2kBand));
+        if (!reslevel->band)
+            return AVERROR(ENOMEM);
+        for (bandno = 0; bandno < reslevel->nbands; bandno++, gbandno++){
+            J2kBand *band = reslevel->band + bandno;
+            int cblkno, precx, precy, precno;
+            int x0, y0, x1, y1;
+            int xi0, yi0, xi1, yi1;
+            int cblkperprecw, cblkperprech;
+
+            if (qntsty->quantsty != J2K_QSTY_NONE){
+                static const uint8_t lut_gain[2][4] = {{0, 0, 0, 0}, {0, 1, 1, 2}};
+                int numbps;
+
+                numbps = cbps + lut_gain[codsty->transform][bandno + reslevelno>0];
+                band->stepsize = SHL(2048 + qntsty->mant[gbandno], 2 + numbps - qntsty->expn[gbandno]);
+            } else
+                band->stepsize = 1 << 13;
+
+            if (reslevelno == 0){  // the same everywhere
+                band->codeblock_width = 1 << FFMIN(codsty->log2_cblk_width, codsty->log2_prec_width-1);
+                band->codeblock_height = 1 << FFMIN(codsty->log2_cblk_height, codsty->log2_prec_height-1);
+                for (i = 0; i < 2; i++)
+                    for (j = 0; j < 2; j++)
+                        band->coord[i][j] = ff_j2k_ceildivpow2(comp->coord[i][j], declvl-1);
+            } else{
+                band->codeblock_width = 1 << FFMIN(codsty->log2_cblk_width, codsty->log2_prec_width);
+                band->codeblock_height = 1 << FFMIN(codsty->log2_cblk_height, codsty->log2_prec_height);
+
+                for (i = 0; i < 2; i++)
+                    for (j = 0; j < 2; j++)
+                        band->coord[i][j] = ff_j2k_ceildivpow2(comp->coord[i][j] - (((bandno+1>>i)&1) << declvl-1), declvl);
+            }
+            band->cblknx = ff_j2k_ceildiv(band->coord[0][1], band->codeblock_width)  - band->coord[0][0] / band->codeblock_width;
+            band->cblkny = ff_j2k_ceildiv(band->coord[1][1], band->codeblock_height) - band->coord[1][0] / band->codeblock_height;
+
+            for (j = 0; j < 2; j++)
+                band->coord[0][j] = ff_j2k_ceildiv(band->coord[0][j], dx);
+            for (j = 0; j < 2; j++)
+                band->coord[1][j] = ff_j2k_ceildiv(band->coord[1][j], dy);
+
+            band->cblknx = ff_j2k_ceildiv(band->cblknx, dx);
+            band->cblkny = ff_j2k_ceildiv(band->cblkny, dy);
+
+            band->cblk = av_malloc(band->cblknx * band->cblkny * sizeof(J2kCblk));
+            if (!band->cblk)
+                return AVERROR(ENOMEM);
+            band->prec = av_malloc(reslevel->num_precincts_x * reslevel->num_precincts_y * sizeof(J2kPrec));
+            if (!band->prec)
+                return AVERROR(ENOMEM);
+
+            for (cblkno = 0; cblkno < band->cblknx * band->cblkny; cblkno++){
+                J2kCblk *cblk = band->cblk + cblkno;
+                cblk->zero = 0;
+                cblk->lblock = 3;
+                cblk->length = 0;
+                cblk->lengthinc = 0;
+                cblk->npasses = 0;
+            }
+
+            y0 = band->coord[1][0];
+            y1 = ((band->coord[1][0] + (1<<codsty->log2_prec_height)) & ~((1<<codsty->log2_prec_height)-1)) - y0;
+            yi0 = 0;
+            yi1 = ff_j2k_ceildivpow2(y1 - y0, codsty->log2_cblk_height) << codsty->log2_cblk_height;
+            yi1 = FFMIN(yi1, band->cblkny);
+            cblkperprech = 1<<(codsty->log2_prec_height - codsty->log2_cblk_height);
+            for (precy = 0, precno = 0; precy < reslevel->num_precincts_y; precy++){
+                for (precx = 0; precx < reslevel->num_precincts_x; precx++, precno++){
+                    band->prec[precno].yi0 = yi0;
+                    band->prec[precno].yi1 = yi1;
+                }
+                yi1 += cblkperprech;
+                yi0 = yi1 - cblkperprech;
+                yi1 = FFMIN(yi1, band->cblkny);
+            }
+            x0 = band->coord[0][0];
+            x1 = ((band->coord[0][0] + (1<<codsty->log2_prec_width)) & ~((1<<codsty->log2_prec_width)-1)) - x0;
+            xi0 = 0;
+            xi1 = ff_j2k_ceildivpow2(x1 - x0, codsty->log2_cblk_width) << codsty->log2_cblk_width;
+            xi1 = FFMIN(xi1, band->cblknx);
+
+            cblkperprecw = 1<<(codsty->log2_prec_width - codsty->log2_cblk_width);
+            for (precx = 0, precno = 0; precx < reslevel->num_precincts_x; precx++){
+                for (precy = 0; precy < reslevel->num_precincts_y; precy++, precno = 0){
+                    J2kPrec *prec = band->prec + precno;
+                    prec->xi0 = xi0;
+                    prec->xi1 = xi1;
+                    prec->cblkincl = ff_j2k_tag_tree_init(prec->xi1 - prec->xi0,
+                                                          prec->yi1 - prec->yi0);
+                    prec->zerobits = ff_j2k_tag_tree_init(prec->xi1 - prec->xi0,
+                                                          prec->yi1 - prec->yi0);
+                    if (!prec->cblkincl || !prec->zerobits)
+                        return AVERROR(ENOMEM);
+
+                }
+                xi1 += cblkperprecw;
+                xi0 = xi1 - cblkperprecw;
+                xi1 = FFMIN(xi1, band->cblknx);
+            }
+        }
+    }
+    return 0;
+}
+
+void ff_j2k_reinit(J2kComponent *comp, J2kCodingStyle *codsty)
+{
+    int reslevelno, bandno, cblkno, precno;
+    for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){
+        J2kResLevel *rlevel = comp->reslevel + reslevelno;
+        for (bandno = 0; bandno < rlevel->nbands; bandno++){
+            J2kBand *band = rlevel->band + bandno;
+            for(precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++){
+                J2kPrec *prec = band->prec + precno;
+                tag_tree_zero(prec->zerobits, prec->xi1 - prec->xi0, prec->yi1 - prec->yi0);
+                tag_tree_zero(prec->cblkincl, prec->xi1 - prec->xi0, prec->yi1 - prec->yi0);
+            }
+            for (cblkno = 0; cblkno < band->cblknx * band->cblkny; cblkno++){
+                J2kCblk *cblk = band->cblk + cblkno;
+                cblk->length = 0;
+                cblk->lblock = 3;
+            }
+        }
+    }
+}
+
+void ff_j2k_cleanup(J2kComponent *comp, J2kCodingStyle *codsty)
+{
+    int reslevelno, bandno, precno;
+    for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){
+        J2kResLevel *reslevel = comp->reslevel + reslevelno;
+
+        for (bandno = 0; bandno < reslevel->nbands ; bandno++){
+            J2kBand *band = reslevel->band + bandno;
+                for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){
+                    J2kPrec *prec = band->prec + precno;
+                    av_freep(&prec->zerobits);
+                    av_freep(&prec->cblkincl);
+                }
+                av_freep(&band->cblk);
+                av_freep(&band->prec);
+            }
+        av_freep(&reslevel->band);
+    }
+
+    ff_j2k_dwt_destroy(&comp->dwt);
+    av_freep(&comp->reslevel);
+    av_freep(&comp->data);
+}
diff --git a/libavcodec/j2k.h b/libavcodec/j2k.h
new file mode 100644
index 0000000..85d5cd0
--- /dev/null
+++ b/libavcodec/j2k.h
@@ -0,0 +1,234 @@
+/*
+ * JPEG2000 tables
+ * Copyright (c) 2007 Kamil Nowosad
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_J2K_H
+#define AVCODEC_J2K_H
+
+/**
+ * JPEG2000 tables
+ * @file
+ * @author Kamil Nowosad
+ */
+
+#include "mqc.h"
+#include "j2k_dwt.h"
+
+enum J2kMarkers{
+    J2K_SOC = 0xff4f, ///< start of codestream
+    J2K_SIZ = 0xff51, ///< image and tile size
+    J2K_COD,          ///< coding style default
+    J2K_COC,          ///< coding style component
+    J2K_TLM = 0xff55, ///< packed packet headers, tile-part header
+    J2K_PLM = 0xff57, ///< tile-part lengths
+    J2K_PLT,          ///< packet length, main header
+    J2K_QCD = 0xff5c, ///< quantization default
+    J2K_QCC,          ///< quantization component
+    J2K_RGN,          ///< region of interest
+    J2K_POC,          ///< progression order change
+    J2K_PPM,          ///< packet length, tile-part header
+    J2K_PPT,          ///< packed packet headers, main header
+    J2K_CRG = 0xff63, ///< component registration
+    J2K_COM,          ///< comment
+    J2K_SOT = 0xff90, ///< start of tile-part
+    J2K_SOP,          ///< start of packet
+    J2K_EPH,          ///< end of packet header
+    J2K_SOD,          ///< start of data
+    J2K_EOC = 0xffd9, ///< end of codestream
+};
+
+enum J2kQuantsty{ ///< quantization style
+    J2K_QSTY_NONE, ///< no quantization
+    J2K_QSTY_SI,   ///< scalar derived
+    J2K_QSTY_SE    ///< scalar expoounded
+};
+
+#define J2K_MAX_CBLKW 64
+#define J2K_MAX_CBLKH 64
+
+// T1 flags
+// flags determining significance of neighbour coefficients
+#define J2K_T1_SIG_N  0x0001
+#define J2K_T1_SIG_E  0x0002
+#define J2K_T1_SIG_W  0x0004
+#define J2K_T1_SIG_S  0x0008
+#define J2K_T1_SIG_NE 0x0010
+#define J2K_T1_SIG_NW 0x0020
+#define J2K_T1_SIG_SE 0x0040
+#define J2K_T1_SIG_SW 0x0080
+#define J2K_T1_SIG_NB (J2K_T1_SIG_N | J2K_T1_SIG_E | J2K_T1_SIG_S | J2K_T1_SIG_W \
+                      |J2K_T1_SIG_NE | J2K_T1_SIG_NW | J2K_T1_SIG_SE | J2K_T1_SIG_SW)
+// flags determining sign bit of neighbour coefficients
+#define J2K_T1_SGN_N  0x0100
+#define J2K_T1_SGN_S  0x0200
+#define J2K_T1_SGN_W  0x0400
+#define J2K_T1_SGN_E  0x0800
+
+#define J2K_T1_VIS    0x1000
+#define J2K_T1_SIG    0x2000
+#define J2K_T1_REF    0x4000
+
+#define J2K_T1_SGN    0x8000
+
+// Codeblock coding styles
+#define J2K_CBLK_BYPASS    0x01 // Selective arithmetic coding bypass
+#define J2K_CBLK_RESET     0x02 // Reset context probabilities
+#define J2K_CBLK_TERMALL   0x04 // Terminate after each coding pass
+#define J2K_CBLK_VSC       0x08 // Vertical stripe causal context formation
+#define J2K_CBLK_PREDTERM  0x10 // Predictable termination
+#define J2K_CBLK_SEGSYM    0x20 // Segmentation symbols present
+
+// Coding styles
+#define J2K_CSTY_PREC      0x01 // Precincts defined in coding style
+#define J2K_CSTY_SOP       0x02 // SOP marker present
+#define J2K_CSTY_EPH       0x04 // EPH marker present
+
+typedef struct {
+    int data[J2K_MAX_CBLKW][J2K_MAX_CBLKH];
+    int flags[J2K_MAX_CBLKW+2][J2K_MAX_CBLKH+2];
+    MqcState mqc;
+} J2kT1Context;
+
+typedef struct J2kTgtNode {
+    uint8_t val;
+    uint8_t vis;
+    struct J2kTgtNode *parent;
+} J2kTgtNode;
+
+typedef struct {
+    uint8_t nreslevels;       ///< number of resolution levels
+    uint8_t log2_cblk_width,
+            log2_cblk_height; ///< exponent of codeblock size
+    uint8_t transform;        ///< DWT type
+    uint8_t csty;             ///< coding style
+    uint8_t log2_prec_width,
+            log2_prec_height; ///< precinct size
+    uint8_t nlayers;          ///< number of layers
+    uint8_t mct;              ///< multiple component transformation
+    uint8_t cblk_style;       ///< codeblock coding style
+} J2kCodingStyle;
+
+typedef struct {
+    uint8_t  expn[32 * 3]; ///< quantization exponent
+    uint16_t mant[32 * 3]; ///< quantization mantissa
+    uint8_t  quantsty;     ///< quantization style
+    uint8_t  nguardbits;   ///< number of guard bits
+} J2kQuantStyle;
+
+typedef struct {
+    uint16_t rate;
+    int64_t disto;
+} J2kPass;
+
+typedef struct {
+    uint8_t npasses;
+    uint8_t ninclpasses; ///< number coding of passes included in codestream
+    uint8_t nonzerobits;
+    uint16_t length;
+    uint16_t lengthinc;
+    uint8_t lblock;
+    uint8_t zero;
+    uint8_t data[8192];
+    J2kPass passes[100];
+} J2kCblk; ///< code block
+
+typedef struct {
+    uint16_t xi0, xi1, yi0, yi1; ///< codeblock indexes ([xi0, xi1))
+    J2kTgtNode *zerobits;
+    J2kTgtNode *cblkincl;
+} J2kPrec; ///< precinct
+
+typedef struct {
+    uint16_t coord[2][2]; ///< border coordinates {{x0, x1}, {y0, y1}}
+    uint16_t codeblock_width, codeblock_height;
+    uint16_t cblknx, cblkny;
+    uint32_t stepsize; ///< quantization stepsize (* 2^13)
+    J2kPrec *prec;
+    J2kCblk *cblk;
+} J2kBand; ///< subband
+
+typedef struct {
+    uint8_t nbands;
+    uint16_t coord[2][2]; ///< border coordinates {{x0, x1}, {y0, y1}}
+    uint16_t num_precincts_x, num_precincts_y; ///< number of precincts in x/y direction
+    uint8_t log2_prec_width, log2_prec_height; ///< exponent of precinct size
+    J2kBand *band;
+} J2kResLevel; ///< resolution level
+
+typedef struct {
+   J2kResLevel *reslevel;
+   DWTContext dwt;
+   int *data;
+   uint16_t coord[2][2]; ///< border coordinates {{x0, x1}, {y0, y1}}
+} J2kComponent;
+
+/* debug routines */
+#if 0
+#undef fprintf
+#undef printf
+void ff_j2k_printv(int *tab, int l);
+void ff_j2k_printu(uint8_t *tab, int l);
+#endif
+
+/* misc tools */
+static inline int ff_j2k_ceildivpow2(int a, int b)
+{
+    return (a + (1 << b) - 1)>> b;
+}
+
+static inline int ff_j2k_ceildiv(int a, int b)
+{
+    return (a + b - 1) / b;
+}
+
+/* tag tree routines */
+J2kTgtNode *ff_j2k_tag_tree_init(int w, int h);
+
+/* TIER-1 routines */
+void ff_j2k_init_tier1_luts(void);
+
+void ff_j2k_set_significant(J2kT1Context *t1, int x, int y, int negative);
+
+extern uint8_t ff_j2k_nbctxno_lut[256][4];
+
+static inline int ff_j2k_getnbctxno(int flag, int bandno, int vert_causal_ctx_csty_symbol)
+{
+    return ff_j2k_nbctxno_lut[flag&255][bandno];
+}
+
+static inline int ff_j2k_getrefctxno(int flag)
+{
+    static const uint8_t refctxno_lut[2][2] = {{14, 15}, {16, 16}};
+    return refctxno_lut[(flag>>14)&1][(flag & 255) != 0];
+}
+
+extern uint8_t ff_j2k_sgnctxno_lut[16][16], ff_j2k_xorbit_lut[16][16];
+
+static inline int ff_j2k_getsgnctxno(int flag, int *xorbit)
+{
+    *xorbit = ff_j2k_xorbit_lut[flag&15][(flag>>8)&15];
+    return  ff_j2k_sgnctxno_lut[flag&15][(flag>>8)&15];
+}
+
+int ff_j2k_init_component(J2kComponent *comp, J2kCodingStyle *codsty, J2kQuantStyle *qntsty, int cbps, int dx, int dy);
+void ff_j2k_reinit(J2kComponent *comp, J2kCodingStyle *codsty);
+void ff_j2k_cleanup(J2kComponent *comp, J2kCodingStyle *codsty);
+
+#endif /* AVCODEC_J2K_H */
diff --git a/libavcodec/j2k_dwt.c b/libavcodec/j2k_dwt.c
new file mode 100644
index 0000000..6f1457f
--- /dev/null
+++ b/libavcodec/j2k_dwt.c
@@ -0,0 +1,386 @@
+/*
+ * Discrete wavelet transform
+ * Copyright (c) 2007 Kamil Nowosad
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * Discrete wavelet transform
+ * @file
+ * @author Kamil Nowosad
+ */
+
+#include "j2k_dwt.h"
+
+static const float scale97[] = {1.625786, 1.230174};
+
+static inline void extend53(int *p, int i0, int i1)
+{
+    p[i0 - 1] = p[i0 + 1];
+    p[i1    ] = p[i1 - 2];
+    p[i0 - 2] = p[i0 + 2];
+    p[i1 + 1] = p[i1 - 3];
+}
+
+static inline void extend97(float *p, int i0, int i1)
+{
+    int i;
+
+    for (i = 1; i <= 4; i++){
+        p[i0 - i] = p[i0 + i];
+        p[i1 + i - 1] = p[i1 - i - 1];
+    }
+}
+
+static void sd_1d53(int *p, int i0, int i1)
+{
+    int i;
+
+    if (i1 == i0 + 1)
+        return;
+
+    extend53(p, i0, i1);
+
+    for (i = (i0+1)/2 - 1; i < (i1+1)/2; i++)
+        p[2*i+1] -= (p[2*i] + p[2*i+2]) >> 1;
+    for (i = (i0+1)/2; i < (i1+1)/2; i++)
+        p[2*i] += (p[2*i-1] + p[2*i+1] + 2) >> 2;
+}
+
+static void dwt_encode53(DWTContext *s, int *t)
+{
+    int lev,
+        w = s->linelen[s->ndeclevels-1][0];
+    int *line = s->linebuf;
+    line += 3;
+
+    for (lev = s->ndeclevels-1; lev >= 0; lev--){
+        int lh = s->linelen[lev][0],
+            lv = s->linelen[lev][1],
+            mh = s->mod[lev][0],
+            mv = s->mod[lev][1],
+            lp;
+        int *l;
+
+        // HOR_SD
+        l = line + mh;
+        for (lp = 0; lp < lv; lp++){
+            int i, j = 0;
+
+            for (i = 0; i < lh; i++)
+                l[i] = t[w*lp + i];
+
+            sd_1d53(line, mh, mh + lh);
+
+            // copy back and deinterleave
+            for (i =   mh; i < lh; i+=2, j++)
+                t[w*lp + j] = l[i];
+            for (i = 1-mh; i < lh; i+=2, j++)
+                t[w*lp + j] = l[i];
+        }
+
+        // VER_SD
+        l = line + mv;
+        for (lp = 0; lp < lh; lp++) {
+            int i, j = 0;
+
+            for (i = 0; i < lv; i++)
+                l[i] = t[w*i + lp];
+
+            sd_1d53(line, mv, mv + lv);
+
+            // copy back and deinterleave
+            for (i =   mv; i < lv; i+=2, j++)
+                t[w*j + lp] = l[i];
+            for (i = 1-mv; i < lv; i+=2, j++)
+                t[w*j + lp] = l[i];
+        }
+    }
+}
+
+static void sd_1d97(float *p, int i0, int i1)
+{
+    int i;
+
+    if (i1 == i0 + 1)
+        return;
+
+    extend97(p, i0, i1);
+    i0++; i1++;
+
+    for (i = i0/2 - 2; i < i1/2 + 1; i++)
+        p[2*i+1] -= 1.586134 * (p[2*i] + p[2*i+2]);
+    for (i = i0/2 - 1; i < i1/2 + 1; i++)
+        p[2*i] -= 0.052980 * (p[2*i-1] + p[2*i+1]);
+    for (i = i0/2 - 1; i < i1/2; i++)
+        p[2*i+1] += 0.882911 * (p[2*i] + p[2*i+2]);
+    for (i = i0/2; i < i1/2; i++)
+        p[2*i] += 0.443506 * (p[2*i-1] + p[2*i+1]);
+}
+
+static void dwt_encode97(DWTContext *s, int *t)
+{
+    int lev,
+        w = s->linelen[s->ndeclevels-1][0];
+    float *line = s->linebuf;
+    line += 5;
+
+    for (lev = s->ndeclevels-1; lev >= 0; lev--){
+        int lh = s->linelen[lev][0],
+            lv = s->linelen[lev][1],
+            mh = s->mod[lev][0],
+            mv = s->mod[lev][1],
+            lp;
+        float *l;
+
+        // HOR_SD
+        l = line + mh;
+        for (lp = 0; lp < lv; lp++){
+            int i, j = 0;
+
+            for (i = 0; i < lh; i++)
+                l[i] = t[w*lp + i];
+
+            sd_1d97(line, mh, mh + lh);
+
+            // copy back and deinterleave
+            for (i =   mh; i < lh; i+=2, j++)
+                t[w*lp + j] = scale97[mh] * l[i] / 2;
+            for (i = 1-mh; i < lh; i+=2, j++)
+                t[w*lp + j] = scale97[mh] * l[i] / 2;
+        }
+
+        // VER_SD
+        l = line + mv;
+        for (lp = 0; lp < lh; lp++) {
+            int i, j = 0;
+
+            for (i = 0; i < lv; i++)
+                l[i] = t[w*i + lp];
+
+            sd_1d97(line, mv, mv + lv);
+
+            // copy back and deinterleave
+            for (i =   mv; i < lv; i+=2, j++)
+                t[w*j + lp] = scale97[mv] * l[i] / 2;
+            for (i = 1-mv; i < lv; i+=2, j++)
+                t[w*j + lp] = scale97[mv] * l[i] / 2;
+        }
+    }
+}
+
+static void sr_1d53(int *p, int i0, int i1)
+{
+    int i;
+
+    if (i1 == i0 + 1)
+        return;
+
+    extend53(p, i0, i1);
+
+    for (i = i0/2; i < i1/2 + 1; i++)
+        p[2*i] -= (p[2*i-1] + p[2*i+1] + 2) >> 2;
+    for (i = i0/2; i < i1/2; i++)
+        p[2*i+1] += (p[2*i] + p[2*i+2]) >> 1;
+}
+
+static void dwt_decode53(DWTContext *s, int *t)
+{
+    int lev,
+        w = s->linelen[s->ndeclevels-1][0];
+    int *line = s->linebuf;
+    line += 3;
+
+    for (lev = 0; lev < s->ndeclevels; lev++){
+        int lh = s->linelen[lev][0],
+            lv = s->linelen[lev][1],
+            mh = s->mod[lev][0],
+            mv = s->mod[lev][1],
+            lp;
+        int *l;
+
+        // HOR_SD
+        l = line + mh;
+        for (lp = 0; lp < lv; lp++){
+            int i, j = 0;
+            // copy with interleaving
+            for (i =   mh; i < lh; i+=2, j++)
+                l[i] = t[w*lp + j];
+            for (i = 1-mh; i < lh; i+=2, j++)
+                l[i] = t[w*lp + j];
+
+            sr_1d53(line, mh, mh + lh);
+
+            for (i = 0; i < lh; i++)
+                t[w*lp + i] = l[i];
+        }
+
+        // VER_SD
+        l = line + mv;
+        for (lp = 0; lp < lh; lp++){
+            int i, j = 0;
+            // copy with interleaving
+            for (i =   mv; i < lv; i+=2, j++)
+                l[i] = t[w*j + lp];
+            for (i = 1-mv; i < lv; i+=2, j++)
+                l[i] = t[w*j + lp];
+
+            sr_1d53(line, mv, mv + lv);
+
+            for (i = 0; i < lv; i++)
+                t[w*i + lp] = l[i];
+        }
+    }
+}
+
+static void sr_1d97(float *p, int i0, int i1)
+{
+    int i;
+
+    if (i1 == i0 + 1)
+        return;
+
+    extend97(p, i0, i1);
+
+    for (i = i0/2 - 1; i < i1/2 + 2; i++)
+        p[2*i] -= 0.443506 * (p[2*i-1] + p[2*i+1]);
+    for (i = i0/2 - 1; i < i1/2 + 1; i++)
+        p[2*i+1] -= 0.882911 * (p[2*i] + p[2*i+2]);
+    for (i = i0/2; i < i1/2 + 1; i++)
+        p[2*i] += 0.052980 * (p[2*i-1] + p[2*i+1]);
+    for (i = i0/2; i < i1/2; i++)
+        p[2*i+1] += 1.586134 * (p[2*i] + p[2*i+2]);
+}
+
+static void dwt_decode97(DWTContext *s, int *t)
+{
+    int lev,
+        w = s->linelen[s->ndeclevels-1][0];
+    float *line = s->linebuf;
+    line += 5;
+
+    for (lev = 0; lev < s->ndeclevels; lev++){
+        int lh = s->linelen[lev][0],
+            lv = s->linelen[lev][1],
+            mh = s->mod[lev][0],
+            mv = s->mod[lev][1],
+            lp;
+        float *l;
+
+        // HOR_SD
+        l = line + mh;
+        for (lp = 0; lp < lv; lp++){
+            int i, j = 0;
+            // copy with interleaving
+            for (i =   mh; i < lh; i+=2, j++)
+                l[i] = scale97[1-mh] * t[w*lp + j];
+            for (i = 1-mh; i < lh; i+=2, j++)
+                l[i] = scale97[1-mh] * t[w*lp + j];
+
+            sr_1d97(line, mh, mh + lh);
+
+            for (i = 0; i < lh; i++)
+                t[w*lp + i] = l[i];
+        }
+
+        // VER_SD
+        l = line + mv;
+        for (lp = 0; lp < lh; lp++){
+            int i, j = 0;
+            // copy with interleaving
+            for (i =   mv; i < lv; i+=2, j++)
+                l[i] = scale97[1-mv] * t[w*j + lp];
+            for (i = 1-mv; i < lv; i+=2, j++)
+                l[i] = scale97[1-mv] * t[w*j + lp];
+
+            sr_1d97(line, mv, mv + lv);
+
+            for (i = 0; i < lv; i++)
+                t[w*i + lp] = l[i];
+        }
+    }
+}
+
+int ff_j2k_dwt_init(DWTContext *s, uint16_t border[2][2], int decomp_levels, int type)
+{
+    int i, j, lev = decomp_levels, maxlen,
+        b[2][2];
+
+    if ((unsigned)decomp_levels >= FF_DWT_MAX_DECLVLS)
+        return AVERROR_INVALIDDATA;
+    s->ndeclevels = decomp_levels;
+    s->type = type;
+
+    for (i = 0; i < 2; i++)
+        for(j = 0; j < 2; j++)
+            b[i][j] = border[i][j];
+
+    maxlen = FFMAX(b[0][1] - b[0][0],
+                   b[1][1] - b[1][0]);
+
+    while(--lev >= 0){
+        for (i = 0; i < 2; i++){
+            s->linelen[lev][i] = b[i][1] - b[i][0];
+            s->mod[lev][i] = b[i][0] & 1;
+            for (j = 0; j < 2; j++)
+                b[i][j] = (b[i][j] + 1) >> 1;
+        }
+    }
+    if (type == FF_DWT97)
+        s->linebuf = av_malloc((maxlen + 12) * sizeof(float));
+    else if (type == FF_DWT53)
+        s->linebuf = av_malloc((maxlen + 6) * sizeof(int));
+    else
+        return -1;
+
+    if (!s->linebuf)
+        return AVERROR(ENOMEM);
+
+    return 0;
+}
+
+int ff_j2k_dwt_encode(DWTContext *s, int *t)
+{
+    switch(s->type){
+        case FF_DWT97:
+            dwt_encode97(s, t); break;
+        case FF_DWT53:
+            dwt_encode53(s, t); break;
+        default:
+            return -1;
+    }
+    return 0;
+}
+
+int ff_j2k_dwt_decode(DWTContext *s, int *t)
+{
+    switch(s->type){
+        case FF_DWT97:
+            dwt_decode97(s, t); break;
+        case FF_DWT53:
+            dwt_decode53(s, t); break;
+        default:
+            return -1;
+    }
+    return 0;
+}
+
+void ff_j2k_dwt_destroy(DWTContext *s)
+{
+    av_freep(&s->linebuf);
+}
diff --git a/libavcodec/j2k_dwt.h b/libavcodec/j2k_dwt.h
new file mode 100644
index 0000000..a2a25a6
--- /dev/null
+++ b/libavcodec/j2k_dwt.h
@@ -0,0 +1,63 @@
+/*
+ * Discrete wavelet transform
+ * Copyright (c) 2007 Kamil Nowosad
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_DWT_H
+#define AVCODEC_DWT_H
+
+/**
+ * Discrete wavelet transform
+ * @file
+ * @author Kamil Nowosad
+ */
+
+#include "avcodec.h"
+
+#define FF_DWT_MAX_DECLVLS 32 ///< max number of decomposition levels
+
+enum DWTType{
+    FF_DWT97,
+    FF_DWT53
+};
+
+typedef struct {
+    ///line lengths {horizontal, vertical} in consecutive decomposition levels
+    uint16_t linelen[FF_DWT_MAX_DECLVLS][2];
+    uint8_t  mod[FF_DWT_MAX_DECLVLS][2]; ///< coordinates (x0, y0) of decomp. levels mod 2
+    uint8_t  ndeclevels;                 ///< number of decomposition levels
+    uint8_t  type;                       ///< 0 for 9/7; 1 for 5/3
+    void     *linebuf;                   ///< buffer used by transform (int or float)
+} DWTContext;
+
+/**
+ * initialize DWT
+ * @param s DWT context
+ * @param border coordinates of transformed region {{x0, x1}, {y0, y1}}
+ * @param decomp_levels number of decomposition levels
+ * @param type 0 for DWT 9/7; 1 for DWT 5/3
+ */
+int ff_j2k_dwt_init(DWTContext *s, uint16_t border[2][2], int decomp_levels, int type);
+
+int ff_j2k_dwt_encode(DWTContext *s, int *t);
+int ff_j2k_dwt_decode(DWTContext *s, int *t);
+
+void ff_j2k_dwt_destroy(DWTContext *s);
+
+#endif /* AVCODEC_DWT_H */
diff --git a/libavcodec/j2kdec.c b/libavcodec/j2kdec.c
new file mode 100644
index 0000000..b2624f9
--- /dev/null
+++ b/libavcodec/j2kdec.c
@@ -0,0 +1,1103 @@
+/*
+ * JPEG2000 image decoder
+ * Copyright (c) 2007 Kamil Nowosad
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * JPEG2000 image decoder
+ * @file
+ * @author Kamil Nowosad
+ */
+
+// #define DEBUG
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "j2k.h"
+#include "libavutil/common.h"
+
+#define JP2_SIG_TYPE    0x6A502020
+#define JP2_SIG_VALUE   0x0D0A870A
+#define JP2_CODESTREAM  0x6A703263
+
+#define HAD_COC 0x01
+#define HAD_QCC 0x02
+
+typedef struct {
+   J2kComponent *comp;
+   uint8_t properties[4];
+   J2kCodingStyle codsty[4];
+   J2kQuantStyle  qntsty[4];
+} J2kTile;
+
+typedef struct {
+    AVCodecContext *avctx;
+    AVFrame picture;
+    GetByteContext g;
+
+    int width, height; ///< image width and height
+    int image_offset_x, image_offset_y;
+    int tile_offset_x, tile_offset_y;
+    uint8_t cbps[4]; ///< bits per sample in particular components
+    uint8_t sgnd[4]; ///< if a component is signed
+    uint8_t properties[4];
+    int cdx[4], cdy[4];
+    int precision;
+    int ncomponents;
+    int tile_width, tile_height; ///< tile size
+    int numXtiles, numYtiles;
+    int maxtilelen;
+
+    J2kCodingStyle codsty[4];
+    J2kQuantStyle  qntsty[4];
+
+    int bit_index;
+
+    int16_t curtileno;
+
+    J2kTile *tile;
+} J2kDecoderContext;
+
+static int get_bits(J2kDecoderContext *s, int n)
+{
+    int res = 0;
+
+    while (--n >= 0){
+        res <<= 1;
+        if (s->bit_index == 0) {
+            s->bit_index = 7 + (bytestream2_get_byte(&s->g) != 0xFFu);
+        }
+        s->bit_index--;
+        res |= (bytestream2_peek_byte(&s->g) >> s->bit_index) & 1;
+    }
+    return res;
+}
+
+static void j2k_flush(J2kDecoderContext *s)
+{
+    if (bytestream2_get_byte(&s->g) == 0xff)
+        bytestream2_skip(&s->g, 1);
+    s->bit_index = 8;
+}
+#if 0
+void printcomp(J2kComponent *comp)
+{
+    int i;
+    for (i = 0; i < comp->y1 - comp->y0; i++)
+        ff_j2k_printv(comp->data + i * (comp->x1 - comp->x0), comp->x1 - comp->x0);
+}
+
+static void nspaces(FILE *fd, int n)
+{
+    while(n--) putc(' ', fd);
+}
+
+static void dump(J2kDecoderContext *s, FILE *fd)
+{
+    int tileno, compno, reslevelno, bandno, precno;
+    fprintf(fd, "XSiz = %d, YSiz = %d, tile_width = %d, tile_height = %d\n"
+                "numXtiles = %d, numYtiles = %d, ncomponents = %d\n"
+                "tiles:\n",
+            s->width, s->height, s->tile_width, s->tile_height,
+            s->numXtiles, s->numYtiles, s->ncomponents);
+    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){
+        J2kTile *tile = s->tile + tileno;
+        nspaces(fd, 2);
+        fprintf(fd, "tile %d:\n", tileno);
+        for(compno = 0; compno < s->ncomponents; compno++){
+            J2kComponent *comp = tile->comp + compno;
+            nspaces(fd, 4);
+            fprintf(fd, "component %d:\n", compno);
+            nspaces(fd, 4);
+            fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d\n",
+                        comp->x0, comp->x1, comp->y0, comp->y1);
+            for(reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){
+                J2kResLevel *reslevel = comp->reslevel + reslevelno;
+                nspaces(fd, 6);
+                fprintf(fd, "reslevel %d:\n", reslevelno);
+                nspaces(fd, 6);
+                fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d, nbands = %d\n",
+                        reslevel->x0, reslevel->x1, reslevel->y0,
+                        reslevel->y1, reslevel->nbands);
+                for(bandno = 0; bandno < reslevel->nbands; bandno++){
+                    J2kBand *band = reslevel->band + bandno;
+                    nspaces(fd, 8);
+                    fprintf(fd, "band %d:\n", bandno);
+                    nspaces(fd, 8);
+                    fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d,"
+                                "codeblock_width = %d, codeblock_height = %d cblknx = %d cblkny = %d\n",
+                                band->x0, band->x1,
+                                band->y0, band->y1,
+                                band->codeblock_width, band->codeblock_height,
+                                band->cblknx, band->cblkny);
+                    for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){
+                        J2kPrec *prec = band->prec + precno;
+                        nspaces(fd, 10);
+                        fprintf(fd, "prec %d:\n", precno);
+                        nspaces(fd, 10);
+                        fprintf(fd, "xi0 = %d, xi1 = %d, yi0 = %d, yi1 = %d\n",
+                                     prec->xi0, prec->xi1, prec->yi0, prec->yi1);
+                    }
+                }
+            }
+        }
+    }
+}
+#endif
+
+/** decode the value stored in node */
+static int tag_tree_decode(J2kDecoderContext *s, J2kTgtNode *node, int threshold)
+{
+    J2kTgtNode *stack[30];
+    int sp = -1, curval = 0;
+
+    while(node && !node->vis){
+        stack[++sp] = node;
+        node = node->parent;
+    }
+
+    if (node)
+        curval = node->val;
+    else
+        curval = stack[sp]->val;
+
+    while(curval < threshold && sp >= 0){
+        if (curval < stack[sp]->val)
+            curval = stack[sp]->val;
+        while (curval < threshold){
+            int ret;
+            if ((ret = get_bits(s, 1)) > 0){
+                stack[sp]->vis++;
+                break;
+            } else if (!ret)
+                curval++;
+            else
+                return ret;
+        }
+        stack[sp]->val = curval;
+        sp--;
+    }
+    return curval;
+}
+
+/* marker segments */
+/** get sizes and offsets of image, tiles; number of components */
+static int get_siz(J2kDecoderContext *s)
+{
+    int i, ret;
+
+    if (bytestream2_get_bytes_left(&s->g) < 36)
+        return AVERROR(EINVAL);
+
+                        bytestream2_get_be16u(&s->g); // Rsiz (skipped)
+             s->width = bytestream2_get_be32u(&s->g); // width
+            s->height = bytestream2_get_be32u(&s->g); // height
+    s->image_offset_x = bytestream2_get_be32u(&s->g); // X0Siz
+    s->image_offset_y = bytestream2_get_be32u(&s->g); // Y0Siz
+
+        s->tile_width = bytestream2_get_be32u(&s->g); // XTSiz
+       s->tile_height = bytestream2_get_be32u(&s->g); // YTSiz
+     s->tile_offset_x = bytestream2_get_be32u(&s->g); // XT0Siz
+     s->tile_offset_y = bytestream2_get_be32u(&s->g); // YT0Siz
+       s->ncomponents = bytestream2_get_be16u(&s->g); // CSiz
+
+    if(s->ncomponents <= 0 || s->ncomponents > 4) {
+        av_log(s->avctx, AV_LOG_ERROR, "unsupported/invalid ncomponents: %d\n", s->ncomponents);
+        return AVERROR(EINVAL);
+    }
+    if(s->tile_width<=0 || s->tile_height<=0)
+        return AVERROR(EINVAL);
+
+    if (bytestream2_get_bytes_left(&s->g) < 3 * s->ncomponents)
+        return AVERROR(EINVAL);
+
+    for (i = 0; i < s->ncomponents; i++){ // Ssiz_i XRsiz_i, YRsiz_i
+        uint8_t x = bytestream2_get_byteu(&s->g);
+        s->cbps[i] = (x & 0x7f) + 1;
+        s->precision = FFMAX(s->cbps[i], s->precision);
+        s->sgnd[i] = !!(x & 0x80);
+        s->cdx[i] = bytestream2_get_byteu(&s->g);
+        s->cdy[i] = bytestream2_get_byteu(&s->g);
+    }
+
+    s->numXtiles = ff_j2k_ceildiv(s->width - s->tile_offset_x, s->tile_width);
+    s->numYtiles = ff_j2k_ceildiv(s->height - s->tile_offset_y, s->tile_height);
+
+    if(s->numXtiles * (uint64_t)s->numYtiles > INT_MAX/sizeof(J2kTile))
+        return AVERROR(EINVAL);
+
+    s->tile = av_mallocz(s->numXtiles * s->numYtiles * sizeof(J2kTile));
+    if (!s->tile)
+        return AVERROR(ENOMEM);
+
+    for (i = 0; i < s->numXtiles * s->numYtiles; i++){
+        J2kTile *tile = s->tile + i;
+
+        tile->comp = av_mallocz(s->ncomponents * sizeof(J2kComponent));
+        if (!tile->comp)
+            return AVERROR(ENOMEM);
+    }
+
+    s->avctx->width  = s->width  - s->image_offset_x;
+    s->avctx->height = s->height - s->image_offset_y;
+
+    switch(s->ncomponents){
+    case 1:
+        if (s->precision > 8) {
+            s->avctx->pix_fmt = AV_PIX_FMT_GRAY16;
+        } else {
+            s->avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+        }
+        break;
+    case 3:
+        if (s->precision > 8) {
+            s->avctx->pix_fmt = AV_PIX_FMT_RGB48;
+        } else {
+            s->avctx->pix_fmt = AV_PIX_FMT_RGB24;
+        }
+        break;
+    case 4:
+        s->avctx->pix_fmt = AV_PIX_FMT_RGBA;
+        break;
+    }
+
+    if (s->picture.data[0])
+        s->avctx->release_buffer(s->avctx, &s->picture);
+
+    if ((ret = s->avctx->get_buffer(s->avctx, &s->picture)) < 0)
+        return ret;
+
+    s->picture.pict_type = AV_PICTURE_TYPE_I;
+    s->picture.key_frame = 1;
+
+    return 0;
+}
+
+/** get common part for COD and COC segments */
+static int get_cox(J2kDecoderContext *s, J2kCodingStyle *c)
+{
+    if (bytestream2_get_bytes_left(&s->g) < 5)
+        return AVERROR(EINVAL);
+          c->nreslevels = bytestream2_get_byteu(&s->g) + 1; // num of resolution levels - 1
+     c->log2_cblk_width = bytestream2_get_byteu(&s->g) + 2; // cblk width
+    c->log2_cblk_height = bytestream2_get_byteu(&s->g) + 2; // cblk height
+
+    c->cblk_style = bytestream2_get_byteu(&s->g);
+    if (c->cblk_style != 0){ // cblk style
+        av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style);
+    }
+    c->transform = bytestream2_get_byteu(&s->g); // transformation
+    if (c->csty & J2K_CSTY_PREC) {
+        int i;
+
+        for (i = 0; i < c->nreslevels; i++)
+            bytestream2_get_byte(&s->g);
+    }
+    return 0;
+}
+
+/** get coding parameters for a particular tile or whole image*/
+static int get_cod(J2kDecoderContext *s, J2kCodingStyle *c, uint8_t *properties)
+{
+    J2kCodingStyle tmp;
+    int compno;
+
+    if (bytestream2_get_bytes_left(&s->g) < 5)
+        return AVERROR(EINVAL);
+
+    tmp.log2_prec_width  =
+    tmp.log2_prec_height = 15;
+
+    tmp.csty = bytestream2_get_byteu(&s->g);
+
+    if (bytestream2_get_byteu(&s->g)){ // progression level
+        av_log(s->avctx, AV_LOG_ERROR, "only LRCP progression supported\n");
+        return -1;
+    }
+
+    tmp.nlayers = bytestream2_get_be16u(&s->g);
+        tmp.mct = bytestream2_get_byteu(&s->g); // multiple component transformation
+
+    get_cox(s, &tmp);
+    for (compno = 0; compno < s->ncomponents; compno++){
+        if (!(properties[compno] & HAD_COC))
+            memcpy(c + compno, &tmp, sizeof(J2kCodingStyle));
+    }
+    return 0;
+}
+
+/** get coding parameters for a component in the whole image on a particular tile */
+static int get_coc(J2kDecoderContext *s, J2kCodingStyle *c, uint8_t *properties)
+{
+    int compno;
+
+    if (bytestream2_get_bytes_left(&s->g) < 2)
+        return AVERROR(EINVAL);
+
+    compno = bytestream2_get_byteu(&s->g);
+
+    c += compno;
+    c->csty = bytestream2_get_byte(&s->g);
+    get_cox(s, c);
+
+    properties[compno] |= HAD_COC;
+    return 0;
+}
+
+/** get common part for QCD and QCC segments */
+static int get_qcx(J2kDecoderContext *s, int n, J2kQuantStyle *q)
+{
+    int i, x;
+
+    if (bytestream2_get_bytes_left(&s->g) < 1)
+        return AVERROR(EINVAL);
+
+    x = bytestream2_get_byteu(&s->g); // Sqcd
+
+    q->nguardbits = x >> 5;
+      q->quantsty = x & 0x1f;
+
+    if (q->quantsty == J2K_QSTY_NONE){
+        n -= 3;
+        if (bytestream2_get_bytes_left(&s->g) < n || 32*3 < n)
+            return AVERROR(EINVAL);
+        for (i = 0; i < n; i++)
+            q->expn[i] = bytestream2_get_byteu(&s->g) >> 3;
+    } else if (q->quantsty == J2K_QSTY_SI){
+        if (bytestream2_get_bytes_left(&s->g) < 2)
+            return AVERROR(EINVAL);
+        x = bytestream2_get_be16u(&s->g);
+        q->expn[0] = x >> 11;
+        q->mant[0] = x & 0x7ff;
+        for (i = 1; i < 32 * 3; i++){
+            int curexpn = FFMAX(0, q->expn[0] - (i-1)/3);
+            q->expn[i] = curexpn;
+            q->mant[i] = q->mant[0];
+        }
+    } else{
+        n = (n - 3) >> 1;
+        if (bytestream2_get_bytes_left(&s->g) < 2 * n || 32*3 < n)
+            return AVERROR(EINVAL);
+        for (i = 0; i < n; i++){
+            x = bytestream2_get_be16u(&s->g);
+            q->expn[i] = x >> 11;
+            q->mant[i] = x & 0x7ff;
+        }
+    }
+    return 0;
+}
+
+/** get quantization parameters for a particular tile or a whole image */
+static int get_qcd(J2kDecoderContext *s, int n, J2kQuantStyle *q, uint8_t *properties)
+{
+    J2kQuantStyle tmp;
+    int compno;
+
+    if (get_qcx(s, n, &tmp))
+        return -1;
+    for (compno = 0; compno < s->ncomponents; compno++)
+        if (!(properties[compno] & HAD_QCC))
+            memcpy(q + compno, &tmp, sizeof(J2kQuantStyle));
+    return 0;
+}
+
+/** get quantization parameters for a component in the whole image on in a particular tile */
+static int get_qcc(J2kDecoderContext *s, int n, J2kQuantStyle *q, uint8_t *properties)
+{
+    int compno;
+
+    if (bytestream2_get_bytes_left(&s->g) < 1)
+        return AVERROR(EINVAL);
+
+    compno = bytestream2_get_byteu(&s->g);
+    properties[compno] |= HAD_QCC;
+    return get_qcx(s, n-1, q+compno);
+}
+
+/** get start of tile segment */
+static uint8_t get_sot(J2kDecoderContext *s)
+{
+    if (bytestream2_get_bytes_left(&s->g) < 8)
+        return AVERROR(EINVAL);
+
+    s->curtileno = bytestream2_get_be16u(&s->g); ///< Isot
+    if((unsigned)s->curtileno >= s->numXtiles * s->numYtiles){
+        s->curtileno=0;
+        return AVERROR(EINVAL);
+    }
+
+    bytestream2_skipu(&s->g, 4); ///< Psot (ignored)
+
+    if (!bytestream2_get_byteu(&s->g)){ ///< TPsot
+        J2kTile *tile = s->tile + s->curtileno;
+
+        /* copy defaults */
+        memcpy(tile->codsty, s->codsty, s->ncomponents * sizeof(J2kCodingStyle));
+        memcpy(tile->qntsty, s->qntsty, s->ncomponents * sizeof(J2kQuantStyle));
+    }
+    bytestream2_get_byteu(&s->g); ///< TNsot
+
+    return 0;
+}
+
+static int init_tile(J2kDecoderContext *s, int tileno)
+{
+    int compno,
+        tilex = tileno % s->numXtiles,
+        tiley = tileno / s->numXtiles;
+    J2kTile *tile = s->tile + tileno;
+
+    if (!tile->comp)
+        return AVERROR(ENOMEM);
+    for (compno = 0; compno < s->ncomponents; compno++){
+        J2kComponent *comp = tile->comp + compno;
+        J2kCodingStyle *codsty = tile->codsty + compno;
+        J2kQuantStyle  *qntsty = tile->qntsty + compno;
+        int ret; // global bandno
+
+        comp->coord[0][0] = FFMAX(tilex * s->tile_width + s->tile_offset_x, s->image_offset_x);
+        comp->coord[0][1] = FFMIN((tilex+1)*s->tile_width + s->tile_offset_x, s->width);
+        comp->coord[1][0] = FFMAX(tiley * s->tile_height + s->tile_offset_y, s->image_offset_y);
+        comp->coord[1][1] = FFMIN((tiley+1)*s->tile_height + s->tile_offset_y, s->height);
+
+        if (ret = ff_j2k_init_component(comp, codsty, qntsty, s->cbps[compno], s->cdx[compno], s->cdy[compno]))
+            return ret;
+    }
+    return 0;
+}
+
+/** read the number of coding passes */
+static int getnpasses(J2kDecoderContext *s)
+{
+    int num;
+    if (!get_bits(s, 1))
+        return 1;
+    if (!get_bits(s, 1))
+        return 2;
+    if ((num = get_bits(s, 2)) != 3)
+        return num < 0 ? num : 3 + num;
+    if ((num = get_bits(s, 5)) != 31)
+        return num < 0 ? num : 6 + num;
+    num = get_bits(s, 7);
+    return num < 0 ? num : 37 + num;
+}
+
+static int getlblockinc(J2kDecoderContext *s)
+{
+    int res = 0, ret;
+    while (ret = get_bits(s, 1)){
+        if (ret < 0)
+            return ret;
+        res++;
+    }
+    return res;
+}
+
+static int decode_packet(J2kDecoderContext *s, J2kCodingStyle *codsty, J2kResLevel *rlevel, int precno,
+                         int layno, uint8_t *expn, int numgbits)
+{
+    int bandno, cblkny, cblknx, cblkno, ret;
+
+    if (!(ret = get_bits(s, 1))){
+        j2k_flush(s);
+        return 0;
+    } else if (ret < 0)
+        return ret;
+
+    for (bandno = 0; bandno < rlevel->nbands; bandno++){
+        J2kBand *band = rlevel->band + bandno;
+        J2kPrec *prec = band->prec + precno;
+        int pos = 0;
+
+        if (band->coord[0][0] == band->coord[0][1]
+        ||  band->coord[1][0] == band->coord[1][1])
+            continue;
+
+        for (cblkny = prec->yi0; cblkny < prec->yi1; cblkny++)
+            for(cblknx = prec->xi0, cblkno = cblkny * band->cblknx + cblknx; cblknx < prec->xi1; cblknx++, cblkno++, pos++){
+                J2kCblk *cblk = band->cblk + cblkno;
+                int incl, newpasses, llen;
+
+                if (cblk->npasses)
+                    incl = get_bits(s, 1);
+                else
+                    incl = tag_tree_decode(s, prec->cblkincl + pos, layno+1) == layno;
+                if (!incl)
+                    continue;
+                else if (incl < 0)
+                    return incl;
+
+                if (!cblk->npasses)
+                    cblk->nonzerobits = expn[bandno] + numgbits - 1 - tag_tree_decode(s, prec->zerobits + pos, 100);
+                if ((newpasses = getnpasses(s)) < 0)
+                    return newpasses;
+                if ((llen = getlblockinc(s)) < 0)
+                    return llen;
+                cblk->lblock += llen;
+                if ((ret = get_bits(s, av_log2(newpasses) + cblk->lblock)) < 0)
+                    return ret;
+                cblk->lengthinc = ret;
+                cblk->npasses += newpasses;
+            }
+    }
+    j2k_flush(s);
+
+    if (codsty->csty & J2K_CSTY_EPH) {
+        if (bytestream2_peek_be16(&s->g) == J2K_EPH) {
+            bytestream2_skip(&s->g, 2);
+        } else {
+            av_log(s->avctx, AV_LOG_ERROR, "EPH marker not found.\n");
+        }
+    }
+
+    for (bandno = 0; bandno < rlevel->nbands; bandno++){
+        J2kBand *band = rlevel->band + bandno;
+        int yi, cblknw = band->prec[precno].xi1 - band->prec[precno].xi0;
+        for (yi = band->prec[precno].yi0; yi < band->prec[precno].yi1; yi++){
+            int xi;
+            for (xi = band->prec[precno].xi0; xi < band->prec[precno].xi1; xi++){
+                J2kCblk *cblk = band->cblk + yi * cblknw + xi;
+                if (bytestream2_get_bytes_left(&s->g) < cblk->lengthinc)
+                    return AVERROR(EINVAL);
+                bytestream2_get_bufferu(&s->g, cblk->data, cblk->lengthinc);
+                cblk->length += cblk->lengthinc;
+                cblk->lengthinc = 0;
+            }
+        }
+    }
+    return 0;
+}
+
+static int decode_packets(J2kDecoderContext *s, J2kTile *tile)
+{
+    int layno, reslevelno, compno, precno, ok_reslevel;
+    s->bit_index = 8;
+    for (layno = 0; layno < tile->codsty[0].nlayers; layno++){
+        ok_reslevel = 1;
+        for (reslevelno = 0; ok_reslevel; reslevelno++){
+            ok_reslevel = 0;
+            for (compno = 0; compno < s->ncomponents; compno++){
+                J2kCodingStyle *codsty = tile->codsty + compno;
+                J2kQuantStyle  *qntsty = tile->qntsty + compno;
+                if (reslevelno < codsty->nreslevels){
+                    J2kResLevel *rlevel = tile->comp[compno].reslevel + reslevelno;
+                    ok_reslevel = 1;
+                    for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++){
+                        if (decode_packet(s, codsty, rlevel, precno, layno, qntsty->expn +
+                                          (reslevelno ? 3*(reslevelno-1)+1 : 0), qntsty->nguardbits))
+                            return -1;
+                    }
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+/* TIER-1 routines */
+static void decode_sigpass(J2kT1Context *t1, int width, int height, int bpno, int bandno, int bpass_csty_symbol,
+                           int vert_causal_ctx_csty_symbol)
+{
+    int mask = 3 << (bpno - 1), y0, x, y;
+
+    for (y0 = 0; y0 < height; y0 += 4)
+        for (x = 0; x < width; x++)
+            for (y = y0; y < height && y < y0+4; y++){
+                if ((t1->flags[y+1][x+1] & J2K_T1_SIG_NB)
+                && !(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS))){
+                    int vert_causal_ctx_csty_loc_symbol = vert_causal_ctx_csty_symbol && (x == 3 && y == 3);
+                    if (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno,
+                                      vert_causal_ctx_csty_loc_symbol))){
+                        int xorbit, ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
+                        if (bpass_csty_symbol)
+                             t1->data[y][x] = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? -mask : mask;
+                        else
+                             t1->data[y][x] = (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ^ xorbit) ?
+                                               -mask : mask;
+
+                        ff_j2k_set_significant(t1, x, y, t1->data[y][x] < 0);
+                    }
+                    t1->flags[y+1][x+1] |= J2K_T1_VIS;
+                }
+            }
+}
+
+static void decode_refpass(J2kT1Context *t1, int width, int height, int bpno)
+{
+    int phalf, nhalf;
+    int y0, x, y;
+
+    phalf = 1 << (bpno - 1);
+    nhalf = -phalf;
+
+    for (y0 = 0; y0 < height; y0 += 4)
+        for (x = 0; x < width; x++)
+            for (y = y0; y < height && y < y0+4; y++){
+                if ((t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS)) == J2K_T1_SIG){
+                    int ctxno = ff_j2k_getrefctxno(t1->flags[y+1][x+1]);
+                    int r = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? phalf : nhalf;
+                    t1->data[y][x] += t1->data[y][x] < 0 ? -r : r;
+                    t1->flags[y+1][x+1] |= J2K_T1_REF;
+                }
+            }
+}
+
+static void decode_clnpass(J2kDecoderContext *s, J2kT1Context *t1, int width, int height,
+                           int bpno, int bandno, int seg_symbols)
+{
+    int mask = 3 << (bpno - 1), y0, x, y, runlen, dec;
+
+    for (y0 = 0; y0 < height; y0 += 4) {
+        for (x = 0; x < width; x++){
+            if (y0 + 3 < height && !(
+            (t1->flags[y0+1][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) ||
+            (t1->flags[y0+2][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) ||
+            (t1->flags[y0+3][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) ||
+            (t1->flags[y0+4][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)))){
+                if (!ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_RL))
+                    continue;
+                runlen = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
+                runlen = (runlen << 1) | ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
+                dec = 1;
+            } else{
+                runlen = 0;
+                dec = 0;
+            }
+
+            for (y = y0 + runlen; y < y0 + 4 && y < height; y++){
+                if (!dec){
+                    if (!(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS)))
+                        dec = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_j2k_getnbctxno(t1->flags[y+1][x+1],
+                                                                                             bandno, 0));
+                }
+                if (dec){
+                    int xorbit, ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
+                    t1->data[y][x] = (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ^ xorbit) ? -mask : mask;
+                    ff_j2k_set_significant(t1, x, y, t1->data[y][x] < 0);
+                }
+                dec = 0;
+                t1->flags[y+1][x+1] &= ~J2K_T1_VIS;
+            }
+        }
+    }
+    if (seg_symbols) {
+        int val;
+        val = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
+        val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
+        val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
+        val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
+        if (val != 0xa) {
+            av_log(s->avctx, AV_LOG_ERROR,"Segmentation symbol value incorrect\n");
+        }
+    }
+}
+
+static int decode_cblk(J2kDecoderContext *s, J2kCodingStyle *codsty, J2kT1Context *t1, J2kCblk *cblk,
+                       int width, int height, int bandpos)
+{
+    int passno = cblk->npasses, pass_t = 2, bpno = cblk->nonzerobits - 1, y, clnpass_cnt = 0;
+    int bpass_csty_symbol = J2K_CBLK_BYPASS & codsty->cblk_style;
+    int vert_causal_ctx_csty_symbol = J2K_CBLK_VSC & codsty->cblk_style;
+
+    for (y = 0; y < height+2; y++)
+        memset(t1->flags[y], 0, (width+2)*sizeof(int));
+
+    for (y = 0; y < height; y++)
+        memset(t1->data[y], 0, width*sizeof(int));
+
+    cblk->data[cblk->length] = 0xff;
+    cblk->data[cblk->length+1] = 0xff;
+    ff_mqc_initdec(&t1->mqc, cblk->data);
+
+    while(passno--){
+        switch(pass_t){
+            case 0: decode_sigpass(t1, width, height, bpno+1, bandpos,
+                                  bpass_csty_symbol && (clnpass_cnt >= 4), vert_causal_ctx_csty_symbol);
+                    break;
+            case 1: decode_refpass(t1, width, height, bpno+1);
+                    if (bpass_csty_symbol && clnpass_cnt >= 4)
+                        ff_mqc_initdec(&t1->mqc, cblk->data);
+                    break;
+            case 2: decode_clnpass(s, t1, width, height, bpno+1, bandpos,
+                                   codsty->cblk_style & J2K_CBLK_SEGSYM);
+                    clnpass_cnt = clnpass_cnt + 1;
+                    if (bpass_csty_symbol && clnpass_cnt >= 4)
+                       ff_mqc_initdec(&t1->mqc, cblk->data);
+                    break;
+        }
+
+        pass_t++;
+        if (pass_t == 3){
+            bpno--;
+            pass_t = 0;
+        }
+    }
+    return 0;
+}
+
+static void mct_decode(J2kDecoderContext *s, J2kTile *tile)
+{
+    int i, *src[3], i0, i1, i2, csize = 1;
+
+    for (i = 0; i < 3; i++)
+        src[i] = tile->comp[i].data;
+
+    for (i = 0; i < 2; i++)
+        csize *= tile->comp[0].coord[i][1] - tile->comp[0].coord[i][0];
+
+    if (tile->codsty[0].transform == FF_DWT97){
+        for (i = 0; i < csize; i++){
+            i0 = *src[0] + (*src[2] * 46802 >> 16);
+            i1 = *src[0] - (*src[1] * 22553 + *src[2] * 46802 >> 16);
+            i2 = *src[0] + (116130 * *src[1] >> 16);
+            *src[0]++ = i0;
+            *src[1]++ = i1;
+            *src[2]++ = i2;
+        }
+    } else{
+        for (i = 0; i < csize; i++){
+            i1 = *src[0] - (*src[2] + *src[1] >> 2);
+            i0 = i1 + *src[2];
+            i2 = i1 + *src[1];
+            *src[0]++ = i0;
+            *src[1]++ = i1;
+            *src[2]++ = i2;
+        }
+    }
+}
+
+static int decode_tile(J2kDecoderContext *s, J2kTile *tile)
+{
+    int compno, reslevelno, bandno;
+    int x, y, *src[4];
+    uint8_t *line;
+    J2kT1Context t1;
+
+    for (compno = 0; compno < s->ncomponents; compno++){
+        J2kComponent *comp = tile->comp + compno;
+        J2kCodingStyle *codsty = tile->codsty + compno;
+
+        for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){
+            J2kResLevel *rlevel = comp->reslevel + reslevelno;
+            for (bandno = 0; bandno < rlevel->nbands; bandno++){
+                J2kBand *band = rlevel->band + bandno;
+                int cblkx, cblky, cblkno=0, xx0, x0, xx1, y0, yy0, yy1, bandpos;
+
+                bandpos = bandno + (reslevelno > 0);
+
+                yy0 = bandno == 0 ? 0 : comp->reslevel[reslevelno-1].coord[1][1] - comp->reslevel[reslevelno-1].coord[1][0];
+                y0 = yy0;
+                yy1 = FFMIN(ff_j2k_ceildiv(band->coord[1][0] + 1, band->codeblock_height) * band->codeblock_height,
+                            band->coord[1][1]) - band->coord[1][0] + yy0;
+
+                if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1])
+                    continue;
+
+                for (cblky = 0; cblky < band->cblkny; cblky++){
+                    if (reslevelno == 0 || bandno == 1)
+                        xx0 = 0;
+                    else
+                        xx0 = comp->reslevel[reslevelno-1].coord[0][1] - comp->reslevel[reslevelno-1].coord[0][0];
+                    x0 = xx0;
+                    xx1 = FFMIN(ff_j2k_ceildiv(band->coord[0][0] + 1, band->codeblock_width) * band->codeblock_width,
+                                band->coord[0][1]) - band->coord[0][0] + xx0;
+
+                    for (cblkx = 0; cblkx < band->cblknx; cblkx++, cblkno++){
+                        int y, x;
+                        decode_cblk(s, codsty, &t1, band->cblk + cblkno, xx1 - xx0, yy1 - yy0, bandpos);
+                        if (codsty->transform == FF_DWT53){
+                            for (y = yy0; y < yy1; y+=s->cdy[compno]){
+                                int *ptr = t1.data[y-yy0];
+                                for (x = xx0; x < xx1; x+=s->cdx[compno]){
+                                    comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x] = *ptr++ >> 1;
+                                }
+                            }
+                        } else{
+                            for (y = yy0; y < yy1; y+=s->cdy[compno]){
+                                int *ptr = t1.data[y-yy0];
+                                for (x = xx0; x < xx1; x+=s->cdx[compno]){
+                                    int tmp = ((int64_t)*ptr++) * ((int64_t)band->stepsize) >> 13, tmp2;
+                                    tmp2 = FFABS(tmp>>1) + FFABS(tmp&1);
+                                    comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x] = tmp < 0 ? -tmp2 : tmp2;
+                                }
+                            }
+                        }
+                        xx0 = xx1;
+                        xx1 = FFMIN(xx1 + band->codeblock_width, band->coord[0][1] - band->coord[0][0] + x0);
+                    }
+                    yy0 = yy1;
+                    yy1 = FFMIN(yy1 + band->codeblock_height, band->coord[1][1] - band->coord[1][0] + y0);
+                }
+            }
+        }
+        ff_j2k_dwt_decode(&comp->dwt, comp->data);
+        src[compno] = comp->data;
+    }
+    if (tile->codsty[0].mct)
+        mct_decode(s, tile);
+
+    if (s->precision <= 8) {
+        for (compno = 0; compno < s->ncomponents; compno++){
+            y = tile->comp[compno].coord[1][0] - s->image_offset_y;
+            line = s->picture.data[0] + y * s->picture.linesize[0];
+            for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]){
+                uint8_t *dst;
+
+                x = tile->comp[compno].coord[0][0] - s->image_offset_x;
+                dst = line + x * s->ncomponents + compno;
+
+                for (; x < tile->comp[compno].coord[0][1] - s->image_offset_x; x += s->cdx[compno]) {
+                    *src[compno] += 1 << (s->cbps[compno]-1);
+                    if (*src[compno] < 0)
+                        *src[compno] = 0;
+                    else if (*src[compno] >= (1 << s->cbps[compno]))
+                        *src[compno] = (1 << s->cbps[compno]) - 1;
+                    *dst = *src[compno]++;
+                    dst += s->ncomponents;
+                }
+                line += s->picture.linesize[0];
+            }
+        }
+    } else {
+        for (compno = 0; compno < s->ncomponents; compno++) {
+            y = tile->comp[compno].coord[1][0] - s->image_offset_y;
+            line = s->picture.data[0] + y * s->picture.linesize[0];
+            for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y += s->cdy[compno]) {
+                uint16_t *dst;
+
+                x = tile->comp[compno].coord[0][0] - s->image_offset_x;
+                dst = (uint16_t *)(line + (x * s->ncomponents + compno) * 2);
+                for (; x < tile->comp[compno].coord[0][1] - s->image_offset_x; x += s-> cdx[compno]) {
+                    int32_t val;
+
+                    val = *src[compno]++ << (16 - s->cbps[compno]);
+                    val += 1 << 15;
+                    val = av_clip(val, 0, (1 << 16) - 1);
+                    *dst = val;
+                    dst += s->ncomponents;
+                }
+                line += s->picture.linesize[0];
+            }
+        }
+    }
+    return 0;
+}
+
+static void cleanup(J2kDecoderContext *s)
+{
+    int tileno, compno;
+    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){
+        for (compno = 0; compno < s->ncomponents; compno++){
+            J2kComponent *comp = s->tile[tileno].comp + compno;
+            J2kCodingStyle *codsty = s->tile[tileno].codsty + compno;
+
+            ff_j2k_cleanup(comp, codsty);
+        }
+        av_freep(&s->tile[tileno].comp);
+    }
+    av_freep(&s->tile);
+}
+
+static int decode_codestream(J2kDecoderContext *s)
+{
+    J2kCodingStyle *codsty = s->codsty;
+    J2kQuantStyle  *qntsty = s->qntsty;
+    uint8_t *properties = s->properties;
+
+    for (;;){
+        int oldpos, marker, len, ret = 0;
+
+        if (bytestream2_get_bytes_left(&s->g) < 2){
+            av_log(s->avctx, AV_LOG_ERROR, "Missing EOC\n");
+            break;
+        }
+
+        marker = bytestream2_get_be16u(&s->g);
+        av_dlog(s->avctx, "marker 0x%.4X at pos 0x%x\n", marker, bytestream2_tell(&s->g) - 4);
+        oldpos = bytestream2_tell(&s->g);
+
+        if (marker == J2K_SOD){
+            J2kTile *tile = s->tile + s->curtileno;
+            if (ret = init_tile(s, s->curtileno)) {
+                av_log(s->avctx, AV_LOG_ERROR, "tile initialization failed\n");
+                return ret;
+            }
+            if (ret = decode_packets(s, tile)) {
+                av_log(s->avctx, AV_LOG_ERROR, "packets decoding failed\n");
+                return ret;
+            }
+            continue;
+        }
+        if (marker == J2K_EOC)
+            break;
+
+        if (bytestream2_get_bytes_left(&s->g) < 2)
+            return AVERROR(EINVAL);
+        len = bytestream2_get_be16u(&s->g);
+        switch (marker){
+        case J2K_SIZ:
+            ret = get_siz(s);
+            break;
+        case J2K_COC:
+            ret = get_coc(s, codsty, properties);
+            break;
+        case J2K_COD:
+            ret = get_cod(s, codsty, properties);
+            break;
+        case J2K_QCC:
+            ret = get_qcc(s, len, qntsty, properties);
+            break;
+        case J2K_QCD:
+            ret = get_qcd(s, len, qntsty, properties);
+            break;
+        case J2K_SOT:
+            if (!(ret = get_sot(s))){
+                codsty = s->tile[s->curtileno].codsty;
+                qntsty = s->tile[s->curtileno].qntsty;
+                properties = s->tile[s->curtileno].properties;
+            }
+            break;
+        case J2K_COM:
+            // the comment is ignored
+            bytestream2_skip(&s->g, len - 2);
+            break;
+        default:
+            av_log(s->avctx, AV_LOG_ERROR, "unsupported marker 0x%.4X at pos 0x%x\n", marker, bytestream2_tell(&s->g) - 4);
+            bytestream2_skip(&s->g, len - 2);
+            break;
+        }
+        if (bytestream2_tell(&s->g) - oldpos != len || ret){
+            av_log(s->avctx, AV_LOG_ERROR, "error during processing marker segment %.4x\n", marker);
+            return ret ? ret : -1;
+        }
+    }
+    return 0;
+}
+
+static int jp2_find_codestream(J2kDecoderContext *s)
+{
+    uint32_t atom_size, atom;
+    int found_codestream = 0, search_range = 10;
+
+    while(!found_codestream && search_range && bytestream2_get_bytes_left(&s->g) >= 8) {
+        atom_size = bytestream2_get_be32u(&s->g);
+        atom      = bytestream2_get_be32u(&s->g);
+        if (atom == JP2_CODESTREAM) {
+            found_codestream = 1;
+        } else {
+            if (bytestream2_get_bytes_left(&s->g) < atom_size - 8)
+                return 0;
+            bytestream2_skipu(&s->g, atom_size - 8);
+            search_range--;
+        }
+    }
+
+    if (found_codestream)
+        return 1;
+    return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx,
+                        void *data, int *data_size,
+                        AVPacket *avpkt)
+{
+    J2kDecoderContext *s = avctx->priv_data;
+    AVFrame *picture = data;
+    int tileno, ret;
+
+    bytestream2_init(&s->g, avpkt->data, avpkt->size);
+    s->curtileno = -1;
+
+    if (bytestream2_get_bytes_left(&s->g) < 2) {
+        ret = AVERROR(EINVAL);
+        goto err_out;
+    }
+
+    // check if the image is in jp2 format
+    if (bytestream2_get_bytes_left(&s->g) >= 12 &&
+       (bytestream2_get_be32u(&s->g) == 12) &&
+       (bytestream2_get_be32u(&s->g) == JP2_SIG_TYPE) &&
+       (bytestream2_get_be32u(&s->g) == JP2_SIG_VALUE)) {
+        if(!jp2_find_codestream(s)) {
+            av_log(avctx, AV_LOG_ERROR, "couldn't find jpeg2k codestream atom\n");
+            ret = -1;
+            goto err_out;
+        }
+    } else {
+        bytestream2_seek(&s->g, 0, SEEK_SET);
+    }
+
+    if (bytestream2_get_be16u(&s->g) != J2K_SOC){
+        av_log(avctx, AV_LOG_ERROR, "SOC marker not present\n");
+        ret = -1;
+        goto err_out;
+    }
+    if (ret = decode_codestream(s))
+        goto err_out;
+
+    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++)
+        if (ret = decode_tile(s, s->tile + tileno))
+            goto err_out;
+
+    cleanup(s);
+
+    *data_size = sizeof(AVPicture);
+    *picture = s->picture;
+
+    return bytestream2_tell(&s->g);
+
+err_out:
+    cleanup(s);
+    return ret;
+}
+
+static av_cold int j2kdec_init(AVCodecContext *avctx)
+{
+    J2kDecoderContext *s = avctx->priv_data;
+
+    s->avctx = avctx;
+    avcodec_get_frame_defaults((AVFrame*)&s->picture);
+    avctx->coded_frame = (AVFrame*)&s->picture;
+
+    ff_j2k_init_tier1_luts();
+
+    return 0;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+    J2kDecoderContext *s = avctx->priv_data;
+
+    if (s->picture.data[0])
+        avctx->release_buffer(avctx, &s->picture);
+
+    return 0;
+}
+
+AVCodec ff_jpeg2000_decoder = {
+    .name           = "j2k",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_JPEG2000,
+    .priv_data_size = sizeof(J2kDecoderContext),
+    .init           = j2kdec_init,
+    .close          = decode_end,
+    .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_EXPERIMENTAL,
+    .long_name      = NULL_IF_CONFIG_SMALL("JPEG 2000"),
+};
diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c
new file mode 100644
index 0000000..0c15fb0
--- /dev/null
+++ b/libavcodec/j2kenc.c
@@ -0,0 +1,1062 @@
+/*
+ * JPEG2000 image encoder
+ * Copyright (c) 2007 Kamil Nowosad
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * JPEG2000 image encoder
+ * @file
+ * @author Kamil Nowosad
+ */
+
+#include <float.h>
+#include "avcodec.h"
+#include "internal.h"
+#include "bytestream.h"
+#include "j2k.h"
+#include "libavutil/common.h"
+
+#define NMSEDEC_BITS 7
+#define NMSEDEC_FRACBITS (NMSEDEC_BITS-1)
+#define WMSEDEC_SHIFT 13 ///< must be >= 13
+#define LAMBDA_SCALE (100000000LL << (WMSEDEC_SHIFT - 13))
+
+static int lut_nmsedec_ref [1<<NMSEDEC_BITS],
+           lut_nmsedec_ref0[1<<NMSEDEC_BITS],
+           lut_nmsedec_sig [1<<NMSEDEC_BITS],
+           lut_nmsedec_sig0[1<<NMSEDEC_BITS];
+
+static const int dwt_norms[2][4][10] = { // [dwt_type][band][rlevel] (multiplied by 10000)
+    {{10000, 19650, 41770,  84030, 169000, 338400,  676900, 1353000, 2706000, 5409000},
+     {20220, 39890, 83550, 170400, 342700, 686300, 1373000, 2746000, 5490000},
+     {20220, 39890, 83550, 170400, 342700, 686300, 1373000, 2746000, 5490000},
+     {20800, 38650, 83070, 171800, 347100, 695900, 1393000, 2786000, 5572000}},
+
+    {{10000, 15000, 27500, 53750, 106800, 213400, 426700, 853300, 1707000, 3413000},
+     {10380, 15920, 29190, 57030, 113300, 226400, 452500, 904800, 1809000},
+     {10380, 15920, 29190, 57030, 113300, 226400, 452500, 904800, 1809000},
+     { 7186,  9218, 15860, 30430,  60190, 120100, 240000, 479700,  959300}}
+};
+
+typedef struct {
+   J2kComponent *comp;
+} J2kTile;
+
+typedef struct {
+    AVCodecContext *avctx;
+    AVFrame picture;
+
+    int width, height; ///< image width and height
+    uint8_t cbps[4]; ///< bits per sample in particular components
+    int chroma_shift[2];
+    uint8_t planar;
+    int ncomponents;
+    int tile_width, tile_height; ///< tile size
+    int numXtiles, numYtiles;
+
+    uint8_t *buf_start;
+    uint8_t *buf;
+    uint8_t *buf_end;
+    int bit_index;
+
+    int64_t lambda;
+
+    J2kCodingStyle codsty;
+    J2kQuantStyle  qntsty;
+
+    J2kTile *tile;
+} J2kEncoderContext;
+
+
+/* debug */
+#if 0
+#undef ifprintf
+#undef printf
+
+static void nspaces(FILE *fd, int n)
+{
+    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);
+}
+
+static void dump(J2kEncoderContext *s, FILE *fd)
+{
+    int tileno, compno, reslevelno, bandno, precno;
+    fprintf(fd, "XSiz = %d, YSiz = %d, tile_width = %d, tile_height = %d\n"
+                "numXtiles = %d, numYtiles = %d, ncomponents = %d\n"
+                "tiles:\n",
+            s->width, s->height, s->tile_width, s->tile_height,
+            s->numXtiles, s->numYtiles, s->ncomponents);
+    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){
+        J2kTile *tile = s->tile + tileno;
+        nspaces(fd, 2);
+        fprintf(fd, "tile %d:\n", tileno);
+        for(compno = 0; compno < s->ncomponents; compno++){
+            J2kComponent *comp = tile->comp + compno;
+            nspaces(fd, 4);
+            fprintf(fd, "component %d:\n", compno);
+            nspaces(fd, 4);
+            fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d\n",
+                        comp->x0, comp->x1, comp->y0, comp->y1);
+            for(reslevelno = 0; reslevelno < s->nreslevels; reslevelno++){
+                J2kResLevel *reslevel = comp->reslevel + reslevelno;
+                nspaces(fd, 6);
+                fprintf(fd, "reslevel %d:\n", reslevelno);
+                nspaces(fd, 6);
+                fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d, nbands = %d\n",
+                        reslevel->x0, reslevel->x1, reslevel->y0,
+                        reslevel->y1, reslevel->nbands);
+                for(bandno = 0; bandno < reslevel->nbands; bandno++){
+                    J2kBand *band = reslevel->band + bandno;
+                    nspaces(fd, 8);
+                    fprintf(fd, "band %d:\n", bandno);
+                    nspaces(fd, 8);
+                    fprintf(fd, "x0 = %d, x1 = %d, y0 = %d, y1 = %d,"
+                                "codeblock_width = %d, codeblock_height = %d cblknx = %d cblkny = %d\n",
+                                band->x0, band->x1,
+                                band->y0, band->y1,
+                                band->codeblock_width, band->codeblock_height,
+                                band->cblknx, band->cblkny);
+                    for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){
+                        J2kPrec *prec = band->prec + precno;
+                        nspaces(fd, 10);
+                        fprintf(fd, "prec %d:\n", precno);
+                        nspaces(fd, 10);
+                        fprintf(fd, "xi0 = %d, xi1 = %d, yi0 = %d, yi1 = %d\n",
+                                     prec->xi0, prec->xi1, prec->yi0, prec->yi1);
+                    }
+                }
+            }
+        }
+    }
+}
+#endif
+
+/* bitstream routines */
+
+/** put n times val bit */
+static void put_bits(J2kEncoderContext *s, int val, int n) // TODO: optimize
+{
+    while (n-- > 0){
+        if (s->bit_index == 8)
+        {
+            s->bit_index = *s->buf == 0xff;
+            *(++s->buf) = 0;
+        }
+        *s->buf |= val << (7 - s->bit_index++);
+    }
+}
+
+/** put n least significant bits of a number num */
+static void put_num(J2kEncoderContext *s, int num, int n)
+{
+    while(--n >= 0)
+        put_bits(s, (num >> n) & 1, 1);
+}
+
+/** flush the bitstream */
+static void j2k_flush(J2kEncoderContext *s)
+{
+    if (s->bit_index){
+        s->bit_index = 0;
+        s->buf++;
+    }
+}
+
+/* tag tree routines */
+
+/** code the value stored in node */
+static void tag_tree_code(J2kEncoderContext *s, J2kTgtNode *node, int threshold)
+{
+    J2kTgtNode *stack[30];
+    int sp = 1, curval = 0;
+    stack[0] = node;
+
+    node = node->parent;
+    while(node){
+        if (node->vis){
+            curval = node->val;
+            break;
+        }
+        node->vis++;
+        stack[sp++] = node;
+        node = node->parent;
+    }
+    while(--sp >= 0){
+        if (stack[sp]->val >= threshold){
+            put_bits(s, 0, threshold - curval);
+            break;
+        }
+        put_bits(s, 0, stack[sp]->val - curval);
+        put_bits(s, 1, 1);
+        curval = stack[sp]->val;
+    }
+}
+
+/** update the value in node */
+static void tag_tree_update(J2kTgtNode *node)
+{
+    int lev = 0;
+    while (node->parent){
+        if (node->parent->val <= node->val)
+            break;
+        node->parent->val = node->val;
+        node = node->parent;
+        lev++;
+    }
+}
+
+static int put_siz(J2kEncoderContext *s)
+{
+    int i;
+
+    if (s->buf_end - s->buf < 40 + 3 * s->ncomponents)
+        return -1;
+
+    bytestream_put_be16(&s->buf, J2K_SIZ);
+    bytestream_put_be16(&s->buf, 38 + 3 * s->ncomponents); // Lsiz
+    bytestream_put_be16(&s->buf, 0); // Rsiz
+    bytestream_put_be32(&s->buf, s->width); // width
+    bytestream_put_be32(&s->buf, s->height); // height
+    bytestream_put_be32(&s->buf, 0); // X0Siz
+    bytestream_put_be32(&s->buf, 0); // Y0Siz
+
+    bytestream_put_be32(&s->buf, s->tile_width); // XTSiz
+    bytestream_put_be32(&s->buf, s->tile_height); // YTSiz
+    bytestream_put_be32(&s->buf, 0); // XT0Siz
+    bytestream_put_be32(&s->buf, 0); // YT0Siz
+    bytestream_put_be16(&s->buf, s->ncomponents); // CSiz
+
+    for (i = 0; i < s->ncomponents; i++){ // Ssiz_i XRsiz_i, YRsiz_i
+        bytestream_put_byte(&s->buf, 7);
+        bytestream_put_byte(&s->buf, i?1<<s->chroma_shift[0]:1);
+        bytestream_put_byte(&s->buf, i?1<<s->chroma_shift[1]:1);
+    }
+    return 0;
+}
+
+static int put_cod(J2kEncoderContext *s)
+{
+    J2kCodingStyle *codsty = &s->codsty;
+
+    if (s->buf_end - s->buf < 14)
+        return -1;
+
+    bytestream_put_be16(&s->buf, J2K_COD);
+    bytestream_put_be16(&s->buf, 12); // Lcod
+    bytestream_put_byte(&s->buf, 0);  // Scod
+    // SGcod
+    bytestream_put_byte(&s->buf, 0); // progression level
+    bytestream_put_be16(&s->buf, 1); // num of layers
+    if(s->avctx->pix_fmt == AV_PIX_FMT_YUV444P){
+        bytestream_put_byte(&s->buf, 2); // ICT
+    }else{
+        bytestream_put_byte(&s->buf, 0); // unspecified
+    }
+    // SPcod
+    bytestream_put_byte(&s->buf, codsty->nreslevels - 1); // num of decomp. levels
+    bytestream_put_byte(&s->buf, codsty->log2_cblk_width-2); // cblk width
+    bytestream_put_byte(&s->buf, codsty->log2_cblk_height-2); // cblk height
+    bytestream_put_byte(&s->buf, 0); // cblk style
+    bytestream_put_byte(&s->buf, codsty->transform); // transformation
+    return 0;
+}
+
+static int put_qcd(J2kEncoderContext *s, int compno)
+{
+    int i, size;
+    J2kCodingStyle *codsty = &s->codsty;
+    J2kQuantStyle  *qntsty = &s->qntsty;
+
+    if (qntsty->quantsty == J2K_QSTY_NONE)
+        size = 4 + 3 * (codsty->nreslevels-1);
+    else // QSTY_SE
+        size = 5 + 6 * (codsty->nreslevels-1);
+
+    if (s->buf_end - s->buf < size + 2)
+        return -1;
+
+    bytestream_put_be16(&s->buf, J2K_QCD);
+    bytestream_put_be16(&s->buf, size);  // LQcd
+    bytestream_put_byte(&s->buf, (qntsty->nguardbits << 5) | qntsty->quantsty);  // Sqcd
+    if (qntsty->quantsty == J2K_QSTY_NONE)
+        for (i = 0; i < codsty->nreslevels * 3 - 2; i++)
+            bytestream_put_byte(&s->buf, qntsty->expn[i] << 3);
+    else // QSTY_SE
+        for (i = 0; i < codsty->nreslevels * 3 - 2; i++)
+            bytestream_put_be16(&s->buf, (qntsty->expn[i] << 11) | qntsty->mant[i]);
+    return 0;
+}
+
+static uint8_t *put_sot(J2kEncoderContext *s, int tileno)
+{
+    uint8_t *psotptr;
+
+    if (s->buf_end - s->buf < 12)
+        return NULL;
+
+    bytestream_put_be16(&s->buf, J2K_SOT);
+    bytestream_put_be16(&s->buf, 10); // Lsot
+    bytestream_put_be16(&s->buf, tileno); // Isot
+
+    psotptr = s->buf;
+    bytestream_put_be32(&s->buf, 0); // Psot (filled in later)
+
+    bytestream_put_byte(&s->buf, 0); // TPsot
+    bytestream_put_byte(&s->buf, 1); // TNsot
+    return psotptr;
+}
+
+/**
+ * compute the sizes of tiles, resolution levels, bands, etc.
+ * allocate memory for them
+ * divide the input image into tile-components
+ */
+static int init_tiles(J2kEncoderContext *s)
+{
+    int tileno, tilex, tiley, compno;
+    J2kCodingStyle *codsty = &s->codsty;
+    J2kQuantStyle  *qntsty = &s->qntsty;
+
+    s->numXtiles = ff_j2k_ceildiv(s->width, s->tile_width);
+    s->numYtiles = ff_j2k_ceildiv(s->height, s->tile_height);
+
+    s->tile = av_malloc(s->numXtiles * s->numYtiles * sizeof(J2kTile));
+    if (!s->tile)
+        return AVERROR(ENOMEM);
+    for (tileno = 0, tiley = 0; tiley < s->numYtiles; tiley++)
+        for (tilex = 0; tilex < s->numXtiles; tilex++, tileno++){
+            J2kTile *tile = s->tile + tileno;
+
+            tile->comp = av_malloc(s->ncomponents * sizeof(J2kComponent));
+            if (!tile->comp)
+                return AVERROR(ENOMEM);
+            for (compno = 0; compno < s->ncomponents; compno++){
+                J2kComponent *comp = tile->comp + compno;
+                int ret, i, j;
+
+                comp->coord[0][0] = tilex * s->tile_width;
+                comp->coord[0][1] = FFMIN((tilex+1)*s->tile_width, s->width);
+                comp->coord[1][0] = tiley * s->tile_height;
+                comp->coord[1][1] = FFMIN((tiley+1)*s->tile_height, s->height);
+                if (compno > 0)
+                    for (i = 0; i < 2; i++)
+                        for (j = 0; j < 2; j++)
+                            comp->coord[i][j] = ff_j2k_ceildivpow2(comp->coord[i][j], s->chroma_shift[i]);
+
+                if (ret = ff_j2k_init_component(comp, codsty, qntsty, s->cbps[compno], compno?1<<s->chroma_shift[0]:1, compno?1<<s->chroma_shift[1]:1))
+                    return ret;
+            }
+        }
+    return 0;
+}
+
+static void copy_frame(J2kEncoderContext *s)
+{
+    int tileno, compno, i, y, x;
+    uint8_t *line;
+    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){
+        J2kTile *tile = s->tile + tileno;
+        if (s->planar){
+            for (compno = 0; compno < s->ncomponents; compno++){
+                J2kComponent *comp = tile->comp + compno;
+                int *dst = comp->data;
+                line = s->picture.data[compno]
+                       + comp->coord[1][0] * s->picture.linesize[compno]
+                       + comp->coord[0][0];
+                for (y = comp->coord[1][0]; y < comp->coord[1][1]; y++){
+                    uint8_t *ptr = line;
+                    for (x = comp->coord[0][0]; x < comp->coord[0][1]; x++)
+                        *dst++ = *ptr++ - (1 << 7);
+                    line += s->picture.linesize[compno];
+                }
+            }
+        } else{
+            line = s->picture.data[0] + tile->comp[0].coord[1][0] * s->picture.linesize[0]
+                   + tile->comp[0].coord[0][0] * s->ncomponents;
+
+            i = 0;
+            for (y = tile->comp[0].coord[1][0]; y < tile->comp[0].coord[1][1]; y++){
+                uint8_t *ptr = line;
+                for (x = tile->comp[0].coord[0][0]; x < tile->comp[0].coord[0][1]; x++, i++){
+                    for (compno = 0; compno < s->ncomponents; compno++){
+                        tile->comp[compno].data[i] = *ptr++  - (1 << 7);
+                    }
+                }
+                line += s->picture.linesize[0];
+            }
+        }
+    }
+}
+
+static void init_quantization(J2kEncoderContext *s)
+{
+    int compno, reslevelno, bandno;
+    J2kQuantStyle  *qntsty = &s->qntsty;
+    J2kCodingStyle *codsty = &s->codsty;
+
+    for (compno = 0; compno < s->ncomponents; compno++){
+        int gbandno = 0;
+        for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){
+            int nbands, lev = codsty->nreslevels - reslevelno - 1;
+            nbands = reslevelno ? 3 : 1;
+            for (bandno = 0; bandno < nbands; bandno++, gbandno++){
+                int expn, mant;
+
+                if (codsty->transform == FF_DWT97){
+                    int bandpos = bandno + (reslevelno>0),
+                        ss = 81920000 / dwt_norms[0][bandpos][lev],
+                        log = av_log2(ss);
+                    mant = (11 - log < 0 ? ss >> log - 11 : ss << 11 - log) & 0x7ff;
+                    expn = s->cbps[compno] - log + 13;
+                } else
+                    expn = ((bandno&2)>>1) + (reslevelno>0) + s->cbps[compno];
+
+                qntsty->expn[gbandno] = expn;
+                qntsty->mant[gbandno] = mant;
+            }
+        }
+    }
+}
+
+static void init_luts(void)
+{
+    int i, a,
+        mask = ~((1<<NMSEDEC_FRACBITS)-1);
+
+    for (i = 0; i < (1 << NMSEDEC_BITS); i++){
+        lut_nmsedec_sig[i]  = FFMAX(6*i - (9<<NMSEDEC_FRACBITS-1) << 12-NMSEDEC_FRACBITS, 0);
+        lut_nmsedec_sig0[i] = FFMAX((i*i + (1<<NMSEDEC_FRACBITS-1) & mask) << 1, 0);
+
+        a = (i >> (NMSEDEC_BITS-2)&2) + 1;
+        lut_nmsedec_ref[i]  = FFMAX((-2*i + (1<<NMSEDEC_FRACBITS) + a*i - (a*a<<NMSEDEC_FRACBITS-2))
+                                    << 13-NMSEDEC_FRACBITS, 0);
+        lut_nmsedec_ref0[i] = FFMAX(((i*i + (1-4*i << NMSEDEC_FRACBITS-1) + (1<<2*NMSEDEC_FRACBITS)) & mask)
+                                    << 1, 0);
+    }
+}
+
+/* tier-1 routines */
+static int getnmsedec_sig(int x, int bpno)
+{
+    if (bpno > NMSEDEC_FRACBITS)
+        return lut_nmsedec_sig[(x >> (bpno - NMSEDEC_FRACBITS)) & ((1 << NMSEDEC_BITS) - 1)];
+    return lut_nmsedec_sig0[x & ((1 << NMSEDEC_BITS) - 1)];
+}
+
+static int getnmsedec_ref(int x, int bpno)
+{
+    if (bpno > NMSEDEC_FRACBITS)
+        return lut_nmsedec_ref[(x >> (bpno - NMSEDEC_FRACBITS)) & ((1 << NMSEDEC_BITS) - 1)];
+    return lut_nmsedec_ref0[x & ((1 << NMSEDEC_BITS) - 1)];
+}
+
+static void encode_sigpass(J2kT1Context *t1, int width, int height, int bandno, int *nmsedec, int bpno)
+{
+    int y0, x, y, mask = 1 << (bpno + NMSEDEC_FRACBITS);
+    int vert_causal_ctx_csty_loc_symbol;
+    for (y0 = 0; y0 < height; y0 += 4)
+        for (x = 0; x < width; x++)
+            for (y = y0; y < height && y < y0+4; y++){
+                if (!(t1->flags[y+1][x+1] & J2K_T1_SIG) && (t1->flags[y+1][x+1] & J2K_T1_SIG_NB)){
+                    int ctxno = ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno, vert_causal_ctx_csty_loc_symbol),
+                        bit = t1->data[y][x] & mask ? 1 : 0;
+                    ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, bit);
+                    if (bit){
+                        int xorbit;
+                        int ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
+                        ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, (t1->flags[y+1][x+1] >> 15) ^ xorbit);
+                        *nmsedec += getnmsedec_sig(t1->data[y][x], bpno + NMSEDEC_FRACBITS);
+                        ff_j2k_set_significant(t1, x, y, t1->flags[y+1][x+1] >> 15);
+                    }
+                    t1->flags[y+1][x+1] |= J2K_T1_VIS;
+                }
+            }
+}
+
+static void encode_refpass(J2kT1Context *t1, int width, int height, int *nmsedec, int bpno)
+{
+    int y0, x, y, mask = 1 << (bpno + NMSEDEC_FRACBITS);
+    for (y0 = 0; y0 < height; y0 += 4)
+        for (x = 0; x < width; x++)
+            for (y = y0; y < height && y < y0+4; y++)
+                if ((t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS)) == J2K_T1_SIG){
+                    int ctxno = ff_j2k_getrefctxno(t1->flags[y+1][x+1]);
+                    *nmsedec += getnmsedec_ref(t1->data[y][x], bpno + NMSEDEC_FRACBITS);
+                    ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, t1->data[y][x] & mask ? 1:0);
+                    t1->flags[y+1][x+1] |= J2K_T1_REF;
+                }
+}
+
+static void encode_clnpass(J2kT1Context *t1, int width, int height, int bandno, int *nmsedec, int bpno)
+{
+    int y0, x, y, mask = 1 << (bpno + NMSEDEC_FRACBITS);
+    int vert_causal_ctx_csty_loc_symbol;
+    for (y0 = 0; y0 < height; y0 += 4)
+        for (x = 0; x < width; x++){
+            if (y0 + 3 < height && !(
+            (t1->flags[y0+1][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) ||
+            (t1->flags[y0+2][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) ||
+            (t1->flags[y0+3][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG)) ||
+            (t1->flags[y0+4][x+1] & (J2K_T1_SIG_NB | J2K_T1_VIS | J2K_T1_SIG))))
+            {
+                // aggregation mode
+                int rlen;
+                for (rlen = 0; rlen < 4; rlen++)
+                    if (t1->data[y0+rlen][x] & mask)
+                        break;
+                ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + MQC_CX_RL, rlen != 4);
+                if (rlen == 4)
+                    continue;
+                ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI, rlen >> 1);
+                ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI, rlen & 1);
+                for (y = y0 + rlen; y < y0 + 4; y++){
+                    if (!(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS))){
+                        int ctxno = ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno, vert_causal_ctx_csty_loc_symbol);
+                        if (y > y0 + rlen)
+                            ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, t1->data[y][x] & mask ? 1:0);
+                        if (t1->data[y][x] & mask){ // newly significant
+                            int xorbit;
+                            int ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
+                            *nmsedec += getnmsedec_sig(t1->data[y][x], bpno + NMSEDEC_FRACBITS);
+                            ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, (t1->flags[y+1][x+1] >> 15) ^ xorbit);
+                            ff_j2k_set_significant(t1, x, y, t1->flags[y+1][x+1] >> 15);
+                        }
+                    }
+                    t1->flags[y+1][x+1] &= ~J2K_T1_VIS;
+                }
+            } else{
+                for (y = y0; y < y0 + 4 && y < height; y++){
+                    if (!(t1->flags[y+1][x+1] & (J2K_T1_SIG | J2K_T1_VIS))){
+                        int ctxno = ff_j2k_getnbctxno(t1->flags[y+1][x+1], bandno, vert_causal_ctx_csty_loc_symbol);
+                        ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, t1->data[y][x] & mask ? 1:0);
+                        if (t1->data[y][x] & mask){ // newly significant
+                            int xorbit;
+                            int ctxno = ff_j2k_getsgnctxno(t1->flags[y+1][x+1], &xorbit);
+                            *nmsedec += getnmsedec_sig(t1->data[y][x], bpno + NMSEDEC_FRACBITS);
+                            ff_mqc_encode(&t1->mqc, t1->mqc.cx_states + ctxno, (t1->flags[y+1][x+1] >> 15) ^ xorbit);
+                            ff_j2k_set_significant(t1, x, y, t1->flags[y+1][x+1] >> 15);
+                        }
+                    }
+                    t1->flags[y+1][x+1] &= ~J2K_T1_VIS;
+                }
+            }
+        }
+}
+
+static void encode_cblk(J2kEncoderContext *s, J2kT1Context *t1, J2kCblk *cblk, J2kTile *tile,
+                        int width, int height, int bandpos, int lev)
+{
+    int pass_t = 2, passno, x, y, max=0, nmsedec, bpno;
+    int64_t wmsedec = 0;
+
+    for (y = 0; y < height+2; y++)
+        memset(t1->flags[y], 0, (width+2)*sizeof(int));
+
+    for (y = 0; y < height; y++){
+        for (x = 0; x < width; x++){
+            if (t1->data[y][x] < 0){
+                t1->flags[y+1][x+1] |= J2K_T1_SGN;
+                t1->data[y][x] = -t1->data[y][x];
+            }
+            max = FFMAX(max, t1->data[y][x]);
+        }
+    }
+
+    if (max == 0){
+        cblk->nonzerobits = 0;
+        bpno = 0;
+    } else{
+        cblk->nonzerobits = av_log2(max) + 1 - NMSEDEC_FRACBITS;
+        bpno = cblk->nonzerobits - 1;
+    }
+
+    ff_mqc_initenc(&t1->mqc, cblk->data);
+
+    for (passno = 0; bpno >= 0; passno++){
+        nmsedec=0;
+
+        switch(pass_t){
+            case 0: encode_sigpass(t1, width, height, bandpos, &nmsedec, bpno);
+                    break;
+            case 1: encode_refpass(t1, width, height, &nmsedec, bpno);
+                    break;
+            case 2: encode_clnpass(t1, width, height, bandpos, &nmsedec, bpno);
+                    break;
+        }
+
+        cblk->passes[passno].rate = 3 + ff_mqc_length(&t1->mqc);
+        wmsedec += (int64_t)nmsedec << (2*bpno);
+        cblk->passes[passno].disto = wmsedec;
+
+        if (++pass_t == 3){
+            pass_t = 0;
+            bpno--;
+        }
+    }
+    cblk->npasses = passno;
+    cblk->ninclpasses = passno;
+
+    // TODO: optional flush on each pass
+    cblk->passes[passno-1].rate = ff_mqc_flush(&t1->mqc);
+}
+
+/* tier-2 routines: */
+
+static void putnumpasses(J2kEncoderContext *s, int n)
+{
+    if (n == 1)
+        put_num(s, 0, 1);
+    else if (n == 2)
+        put_num(s, 2, 2);
+    else if (n <= 5)
+        put_num(s, 0xc | (n-3), 4);
+    else if (n <= 36)
+        put_num(s, 0x1e0 | (n-6), 9);
+    else
+        put_num(s, 0xff80 | (n-37), 16);
+}
+
+
+static int encode_packet(J2kEncoderContext *s, J2kResLevel *rlevel, int precno,
+                          uint8_t *expn, int numgbits)
+{
+    int bandno, empty = 1;
+
+    // init bitstream
+    *s->buf = 0;
+    s->bit_index = 0;
+
+    // header
+
+    // is the packet empty?
+    for (bandno = 0; bandno < rlevel->nbands; bandno++){
+        if (rlevel->band[bandno].coord[0][0] < rlevel->band[bandno].coord[0][1]
+        &&  rlevel->band[bandno].coord[1][0] < rlevel->band[bandno].coord[1][1]){
+            empty = 0;
+            break;
+        }
+    }
+
+    put_bits(s, !empty, 1);
+    if (empty){
+        j2k_flush(s);
+        return 0;
+    }
+
+    for (bandno = 0; bandno < rlevel->nbands; bandno++){
+        J2kBand *band = rlevel->band + bandno;
+        J2kPrec *prec = band->prec + precno;
+        int yi, xi, pos;
+        int cblknw = prec->xi1 - prec->xi0;
+
+        if (band->coord[0][0] == band->coord[0][1]
+        ||  band->coord[1][0] == band->coord[1][1])
+            continue;
+
+        for (pos=0, yi = prec->yi0; yi < prec->yi1; yi++){
+            for (xi = prec->xi0; xi < prec->xi1; xi++, pos++){
+                prec->cblkincl[pos].val = band->cblk[yi * cblknw + xi].ninclpasses == 0;
+                tag_tree_update(prec->cblkincl + pos);
+                prec->zerobits[pos].val = expn[bandno] + numgbits - 1 - band->cblk[yi * cblknw + xi].nonzerobits;
+                tag_tree_update(prec->zerobits + pos);
+            }
+        }
+
+        for (pos=0, yi = prec->yi0; yi < prec->yi1; yi++){
+            for (xi = prec->xi0; xi < prec->xi1; xi++, pos++){
+                int pad = 0, llen, length;
+                J2kCblk *cblk = band->cblk + yi * cblknw + xi;
+
+                if (s->buf_end - s->buf < 20) // approximately
+                    return -1;
+
+                // inclusion information
+                tag_tree_code(s, prec->cblkincl + pos, 1);
+                if (!cblk->ninclpasses)
+                    continue;
+                // zerobits information
+                tag_tree_code(s, prec->zerobits + pos, 100);
+                // number of passes
+                putnumpasses(s, cblk->ninclpasses);
+
+                length = cblk->passes[cblk->ninclpasses-1].rate;
+                llen = av_log2(length) - av_log2(cblk->ninclpasses) - 2;
+                if (llen < 0){
+                    pad = -llen;
+                    llen = 0;
+                }
+                // length of code block
+                put_bits(s, 1, llen);
+                put_bits(s, 0, 1);
+                put_num(s, length, av_log2(length)+1+pad);
+            }
+        }
+    }
+    j2k_flush(s);
+    for (bandno = 0; bandno < rlevel->nbands; bandno++){
+        J2kBand *band = rlevel->band + bandno;
+        J2kPrec *prec = band->prec + precno;
+        int yi, cblknw = prec->xi1 - prec->xi0;
+        for (yi = prec->yi0; yi < prec->yi1; yi++){
+            int xi;
+            for (xi = prec->xi0; xi < prec->xi1; xi++){
+                J2kCblk *cblk = band->cblk + yi * cblknw + xi;
+                if (cblk->ninclpasses){
+                    if (s->buf_end - s->buf < cblk->passes[cblk->ninclpasses-1].rate)
+                        return -1;
+                    bytestream_put_buffer(&s->buf, cblk->data, cblk->passes[cblk->ninclpasses-1].rate);
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+static int encode_packets(J2kEncoderContext *s, J2kTile *tile, int tileno)
+{
+    int compno, reslevelno, ret;
+    J2kCodingStyle *codsty = &s->codsty;
+    J2kQuantStyle  *qntsty = &s->qntsty;
+
+    av_log(s->avctx, AV_LOG_DEBUG, "tier2\n");
+    // lay-rlevel-comp-pos progression
+    for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){
+        for (compno = 0; compno < s->ncomponents; compno++){
+            int precno;
+            J2kResLevel *reslevel = s->tile[tileno].comp[compno].reslevel + reslevelno;
+            for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++){
+                if (ret = encode_packet(s, reslevel, precno, qntsty->expn + (reslevelno ? 3*reslevelno-2 : 0),
+                              qntsty->nguardbits))
+                    return ret;
+            }
+        }
+    }
+    av_log(s->avctx, AV_LOG_DEBUG, "after tier2\n");
+    return 0;
+}
+
+static int getcut(J2kCblk *cblk, int64_t lambda, int dwt_norm)
+{
+    int passno, res = 0;
+    for (passno = 0; passno < cblk->npasses; passno++){
+        int dr;
+        int64_t dd;
+
+        dr = cblk->passes[passno].rate
+           - (res ? cblk->passes[res-1].rate:0);
+        dd = cblk->passes[passno].disto
+           - (res ? cblk->passes[res-1].disto:0);
+
+        if (((dd * dwt_norm) >> WMSEDEC_SHIFT) * dwt_norm >= dr * lambda)
+            res = passno+1;
+    }
+    return res;
+}
+
+static void truncpasses(J2kEncoderContext *s, J2kTile *tile)
+{
+    int compno, reslevelno, bandno, cblkno, lev;
+    J2kCodingStyle *codsty = &s->codsty;
+
+    for (compno = 0; compno < s->ncomponents; compno++){
+        J2kComponent *comp = tile->comp + compno;
+
+        for (reslevelno = 0, lev = codsty->nreslevels-1; reslevelno < codsty->nreslevels; reslevelno++, lev--){
+            J2kResLevel *reslevel = comp->reslevel + reslevelno;
+
+            for (bandno = 0; bandno < reslevel->nbands ; bandno++){
+                int bandpos = bandno + (reslevelno > 0);
+                J2kBand *band = reslevel->band + bandno;
+
+                for (cblkno = 0; cblkno < band->cblknx * band->cblkny; cblkno++){
+                    J2kCblk *cblk = band->cblk + cblkno;
+
+                    cblk->ninclpasses = getcut(cblk, s->lambda,
+                            (int64_t)dwt_norms[codsty->transform][bandpos][lev] * (int64_t)band->stepsize >> 13);
+                }
+            }
+        }
+    }
+}
+
+static int encode_tile(J2kEncoderContext *s, J2kTile *tile, int tileno)
+{
+    int compno, reslevelno, bandno, ret;
+    J2kT1Context t1;
+    J2kCodingStyle *codsty = &s->codsty;
+    for (compno = 0; compno < s->ncomponents; compno++){
+        J2kComponent *comp = s->tile[tileno].comp + compno;
+
+        av_log(s->avctx, AV_LOG_DEBUG,"dwt\n");
+        if (ret = ff_j2k_dwt_encode(&comp->dwt, comp->data))
+            return ret;
+        av_log(s->avctx, AV_LOG_DEBUG,"after dwt -> tier1\n");
+
+        for (reslevelno = 0; reslevelno < codsty->nreslevels; reslevelno++){
+            J2kResLevel *reslevel = comp->reslevel + reslevelno;
+
+            for (bandno = 0; bandno < reslevel->nbands ; bandno++){
+                J2kBand *band = reslevel->band + bandno;
+                int cblkx, cblky, cblkno=0, xx0, x0, xx1, y0, yy0, yy1, bandpos;
+                yy0 = bandno == 0 ? 0 : comp->reslevel[reslevelno-1].coord[1][1] - comp->reslevel[reslevelno-1].coord[1][0];
+                y0 = yy0;
+                yy1 = FFMIN(ff_j2k_ceildiv(band->coord[1][0] + 1, band->codeblock_height) * band->codeblock_height,
+                            band->coord[1][1]) - band->coord[1][0] + yy0;
+
+                if (band->coord[0][0] == band->coord[0][1] || band->coord[1][0] == band->coord[1][1])
+                    continue;
+
+                bandpos = bandno + (reslevelno > 0);
+
+                for (cblky = 0; cblky < band->cblkny; cblky++){
+                    if (reslevelno == 0 || bandno == 1)
+                        xx0 = 0;
+                    else
+                        xx0 = comp->reslevel[reslevelno-1].coord[0][1] - comp->reslevel[reslevelno-1].coord[0][0];
+                    x0 = xx0;
+                    xx1 = FFMIN(ff_j2k_ceildiv(band->coord[0][0] + 1, band->codeblock_width) * band->codeblock_width,
+                                band->coord[0][1]) - band->coord[0][0] + xx0;
+
+                    for (cblkx = 0; cblkx < band->cblknx; cblkx++, cblkno++){
+                        int y, x;
+                        if (codsty->transform == FF_DWT53){
+                            for (y = yy0; y < yy1; y++){
+                                int *ptr = t1.data[y-yy0];
+                                for (x = xx0; x < xx1; x++){
+                                    *ptr++ = comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x] << NMSEDEC_FRACBITS;
+                                }
+                            }
+                        } else{
+                            for (y = yy0; y < yy1; y++){
+                                int *ptr = t1.data[y-yy0];
+                                for (x = xx0; x < xx1; x++){
+                                    *ptr = (comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x]);
+                                    *ptr = (int64_t)*ptr * (int64_t)(8192 * 8192 / band->stepsize) >> 13 - NMSEDEC_FRACBITS;
+                                    *ptr++;
+                                }
+                            }
+                        }
+                        encode_cblk(s, &t1, band->cblk + cblkno, tile, xx1 - xx0, yy1 - yy0,
+                                    bandpos, codsty->nreslevels - reslevelno - 1);
+                        xx0 = xx1;
+                        xx1 = FFMIN(xx1 + band->codeblock_width, band->coord[0][1] - band->coord[0][0] + x0);
+                    }
+                    yy0 = yy1;
+                    yy1 = FFMIN(yy1 + band->codeblock_height, band->coord[1][1] - band->coord[1][0] + y0);
+                }
+            }
+        }
+        av_log(s->avctx, AV_LOG_DEBUG, "after tier1\n");
+    }
+
+    av_log(s->avctx, AV_LOG_DEBUG, "rate control\n");
+    truncpasses(s, tile);
+    if (ret = encode_packets(s, tile, tileno))
+        return ret;
+    av_log(s->avctx, AV_LOG_DEBUG, "after rate control\n");
+    return 0;
+}
+
+static void cleanup(J2kEncoderContext *s)
+{
+    int tileno, compno;
+    J2kCodingStyle *codsty = &s->codsty;
+
+    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){
+        for (compno = 0; compno < s->ncomponents; compno++){
+            J2kComponent *comp = s->tile[tileno].comp + compno;
+            ff_j2k_cleanup(comp, codsty);
+        }
+        av_freep(&s->tile[tileno].comp);
+    }
+    av_freep(&s->tile);
+}
+
+static void reinit(J2kEncoderContext *s)
+{
+    int tileno, compno;
+    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){
+        J2kTile *tile = s->tile + tileno;
+        for (compno = 0; compno < s->ncomponents; compno++)
+            ff_j2k_reinit(tile->comp + compno, &s->codsty);
+    }
+}
+
+static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                        const AVFrame *pict, int *got_packet)
+{
+    int tileno, ret;
+    J2kEncoderContext *s = avctx->priv_data;
+
+    if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*9 + FF_MIN_BUFFER_SIZE)) < 0)
+        return ret;
+
+    // init:
+    s->buf = s->buf_start = pkt->data;
+    s->buf_end = pkt->data + pkt->size;
+
+    s->picture = *pict;
+    avctx->coded_frame= &s->picture;
+
+    s->lambda = s->picture.quality * LAMBDA_SCALE;
+
+    copy_frame(s);
+    reinit(s);
+
+    if (s->buf_end - s->buf < 2)
+        return -1;
+    bytestream_put_be16(&s->buf, J2K_SOC);
+    if (ret = put_siz(s))
+        return ret;
+    if (ret = put_cod(s))
+        return ret;
+    if (ret = put_qcd(s, 0))
+        return ret;
+
+    for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){
+        uint8_t *psotptr;
+        if (!(psotptr = put_sot(s, tileno)))
+            return -1;
+        if (s->buf_end - s->buf < 2)
+            return -1;
+        bytestream_put_be16(&s->buf, J2K_SOD);
+        if (ret = encode_tile(s, s->tile + tileno, tileno))
+            return ret;
+        bytestream_put_be32(&psotptr, s->buf - psotptr + 6);
+    }
+    if (s->buf_end - s->buf < 2)
+        return -1;
+    bytestream_put_be16(&s->buf, J2K_EOC);
+
+    av_log(s->avctx, AV_LOG_DEBUG, "end\n");
+    pkt->size = s->buf - s->buf_start;
+    pkt->flags |= AV_PKT_FLAG_KEY;
+    *got_packet = 1;
+
+    return 0;
+}
+
+static av_cold int j2kenc_init(AVCodecContext *avctx)
+{
+    int i, ret;
+    J2kEncoderContext *s = avctx->priv_data;
+    J2kCodingStyle *codsty = &s->codsty;
+    J2kQuantStyle  *qntsty = &s->qntsty;
+
+    s->avctx = avctx;
+    av_log(s->avctx, AV_LOG_DEBUG, "init\n");
+
+    // defaults:
+    // TODO: implement setting non-standard precinct size
+    codsty->log2_prec_width  = 15;
+    codsty->log2_prec_height = 15;
+    codsty->nreslevels       = 7;
+    codsty->log2_cblk_width  = 4;
+    codsty->log2_cblk_height = 4;
+    codsty->transform        = 1;
+
+    qntsty->nguardbits       = 1;
+
+    s->tile_width            = 256;
+    s->tile_height           = 256;
+
+    if (codsty->transform == FF_DWT53)
+        qntsty->quantsty = J2K_QSTY_NONE;
+    else
+        qntsty->quantsty = J2K_QSTY_SE;
+
+    s->width = avctx->width;
+    s->height = avctx->height;
+
+    for (i = 0; i < 3; i++)
+        s->cbps[i] = 8;
+
+    if (avctx->pix_fmt == AV_PIX_FMT_RGB24){
+        s->ncomponents = 3;
+    } else if (avctx->pix_fmt == AV_PIX_FMT_GRAY8){
+        s->ncomponents = 1;
+    } else{ // planar YUV
+        s->planar = 1;
+        s->ncomponents = 3;
+        avcodec_get_chroma_sub_sample(avctx->pix_fmt,
+                s->chroma_shift, s->chroma_shift + 1);
+    }
+
+    ff_j2k_init_tier1_luts();
+
+    init_luts();
+
+    init_quantization(s);
+    if (ret=init_tiles(s))
+        return ret;
+
+    av_log(s->avctx, AV_LOG_DEBUG, "after init\n");
+
+    return 0;
+}
+
+static int j2kenc_destroy(AVCodecContext *avctx)
+{
+    J2kEncoderContext *s = avctx->priv_data;
+
+    cleanup(s);
+    return 0;
+}
+
+AVCodec ff_jpeg2000_encoder = {
+    .name           = "j2k",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_JPEG2000,
+    .priv_data_size = sizeof(J2kEncoderContext),
+    .init           = j2kenc_init,
+    .encode2        = encode_frame,
+    .close          = j2kenc_destroy,
+    .capabilities   = CODEC_CAP_EXPERIMENTAL,
+    .long_name      = NULL_IF_CONFIG_SMALL("JPEG 2000"),
+    .pix_fmts       = (const enum AVPixelFormat[]) {
+        AV_PIX_FMT_RGB24, AV_PIX_FMT_YUV444P, AV_PIX_FMT_GRAY8,
+/*      AV_PIX_FMT_YUV420P,
+        AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P,
+        AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P,*/
+        AV_PIX_FMT_NONE
+    }
+};
diff --git a/libavcodec/jacosub.h b/libavcodec/jacosub.h
new file mode 100644
index 0000000..c3665ae
--- /dev/null
+++ b/libavcodec/jacosub.h
@@ -0,0 +1,45 @@
+/*
+ * 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
+ * JACOsub shared utils
+ */
+
+#ifndef AVCODEC_JACOSUB_H
+#define AVCODEC_JACOSUB_H
+
+#include "libavutil/common.h"
+
+#define JSS_MAX_LINESIZE 512
+
+static av_always_inline int jss_whitespace(char c)
+{
+    return c == ' ' || (c >= '\t' && c <= '\r');
+}
+
+static av_always_inline const char *jss_skip_whitespace(const char *p)
+{
+    while (jss_whitespace(*p))
+        p++;
+    return p;
+}
+
+#endif /* AVCODEC_JACOSUB_H */
diff --git a/libavcodec/jacosubdec.c b/libavcodec/jacosubdec.c
new file mode 100644
index 0000000..b64fac8
--- /dev/null
+++ b/libavcodec/jacosubdec.c
@@ -0,0 +1,205 @@
+/*
+ * 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
+ * JACOsub subtitle decoder
+ * @see http://unicorn.us.com/jacosub/jscripts.html
+ */
+
+#include <time.h>
+#include "ass.h"
+#include "jacosub.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+
+#undef time
+
+static int insert_text(AVBPrint *dst, const char *in, const char *arg)
+{
+    av_bprintf(dst, "%s", arg);
+    return 0;
+}
+
+static int insert_datetime(AVBPrint *dst, const char *in, const char *arg)
+{
+    char buf[16] = {0};
+    time_t now = time(0);
+    struct tm ltime;
+
+#if HAVE_LOCALTIME_R
+    localtime_r(&now, &ltime);
+#else
+    ltime = *localtime(&now);
+#endif
+    strftime(buf, sizeof(buf), arg, &ltime);
+    av_bprintf(dst, "%s", buf);
+    return 0;
+}
+
+static int insert_color(AVBPrint *dst, const char *in, const char *arg)
+{
+    return 1; // skip id
+}
+
+static int insert_font(AVBPrint *dst, const char *in, const char *arg)
+{
+    return 1; // skip id
+}
+
+static const struct {
+    const char *from;
+    const char *arg;
+    int (*func)(AVBPrint *dst, const char *in, const char *arg);
+} ass_codes_map[] = {
+    {"\\~", "~",        insert_text},       // tilde doesn't need escaping
+    {"~",   "{\\h}",    insert_text},       // hard space
+    {"\\n", "\\N",      insert_text},       // newline
+    {"\\D", "%d %b %Y", insert_datetime},   // current date
+    {"\\T", "%H:%M",    insert_datetime},   // current time
+    {"\\N", "{\\r}",    insert_text},       // reset to default style
+    {"\\I", "{\\i1}",   insert_text},       // italic on
+    {"\\i", "{\\i0}",   insert_text},       // italic off
+    {"\\B", "{\\b1}",   insert_text},       // bold on
+    {"\\b", "{\\b0}",   insert_text},       // bold off
+    {"\\U", "{\\u1}",   insert_text},       // underline on
+    {"\\u", "{\\u0}",   insert_text},       // underline off
+    {"\\C", "",         insert_color},      // TODO: color
+    {"\\F", "",         insert_font},       // TODO: font
+};
+
+enum {
+    ALIGN_VB = 1<<0, // vertical bottom, default
+    ALIGN_VM = 1<<1, // vertical middle
+    ALIGN_VT = 1<<2, // vertical top
+    ALIGN_JC = 1<<3, // justify center, default
+    ALIGN_JL = 1<<4, // justify left
+    ALIGN_JR = 1<<5, // justify right
+};
+
+static void jacosub_to_ass(AVCodecContext *avctx, AVBPrint *dst, const char *src)
+{
+    int i, valign = 0, halign = 0;
+    char c = av_toupper(*src);
+    char directives[128] = {0};
+
+    /* extract the optional directives */
+    if ((c >= 'A' && c <= 'Z') || c == '[') {
+        char *p    = directives;
+        char *pend = directives + sizeof(directives) - 1;
+
+        do *p++ = av_toupper(*src++);
+        while (*src && !jss_whitespace(*src) && p < pend);
+        *p = 0;
+        src = jss_skip_whitespace(src);
+    }
+
+    /* handle directives (TODO: handle more of them, and more reliably) */
+    if      (strstr(directives, "VB")) valign = ALIGN_VB;
+    else if (strstr(directives, "VM")) valign = ALIGN_VM;
+    else if (strstr(directives, "VT")) valign = ALIGN_VT;
+    if      (strstr(directives, "JC")) halign = ALIGN_JC;
+    else if (strstr(directives, "JL")) halign = ALIGN_JL;
+    else if (strstr(directives, "JR")) halign = ALIGN_JR;
+    if (valign || halign) {
+        if (!valign) valign = ALIGN_VB;
+        if (!halign) halign = ALIGN_JC;
+        switch (valign | halign) {
+        case ALIGN_VB | ALIGN_JL: av_bprintf(dst, "{\\an1}"); break; // bottom left
+        case ALIGN_VB | ALIGN_JC: av_bprintf(dst, "{\\an2}"); break; // bottom center
+        case ALIGN_VB | ALIGN_JR: av_bprintf(dst, "{\\an3}"); break; // bottom right
+        case ALIGN_VM | ALIGN_JL: av_bprintf(dst, "{\\an4}"); break; // middle left
+        case ALIGN_VM | ALIGN_JC: av_bprintf(dst, "{\\an5}"); break; // middle center
+        case ALIGN_VM | ALIGN_JR: av_bprintf(dst, "{\\an6}"); break; // middle right
+        case ALIGN_VT | ALIGN_JL: av_bprintf(dst, "{\\an7}"); break; // top left
+        case ALIGN_VT | ALIGN_JC: av_bprintf(dst, "{\\an8}"); break; // top center
+        case ALIGN_VT | ALIGN_JR: av_bprintf(dst, "{\\an9}"); break; // top right
+        }
+    }
+
+    /* process timed line */
+    while (*src && *src != '\n') {
+
+        /* text continue on the next line */
+        if (src[0] == '\\' && src[1] == '\n') {
+            src += 2;
+            while (jss_whitespace(*src))
+                src++;
+            continue;
+        }
+
+        /* special character codes */
+        for (i = 0; i < FF_ARRAY_ELEMS(ass_codes_map); i++) {
+            const char *from = ass_codes_map[i].from;
+            const char *arg  = ass_codes_map[i].arg;
+            size_t codemap_len = strlen(from);
+
+            if (!strncmp(src, from, codemap_len)) {
+                src += codemap_len;
+                src += ass_codes_map[i].func(dst, src, arg);
+                break;
+            }
+        }
+
+        /* simple char copy */
+        if (i == FF_ARRAY_ELEMS(ass_codes_map))
+            av_bprintf(dst, "%c", *src++);
+    }
+    av_bprintf(dst, "\r\n");
+}
+
+static int jacosub_decode_frame(AVCodecContext *avctx,
+                                void *data, int *got_sub_ptr, AVPacket *avpkt)
+{
+    AVSubtitle *sub = data;
+    const char *ptr = avpkt->data;
+
+    if (avpkt->size <= 0)
+        goto end;
+
+    if (*ptr) {
+        AVBPrint buffer;
+        char *dec_sub;
+
+        // skip timers
+        ptr = jss_skip_whitespace(ptr);
+        ptr = strchr(ptr, ' '); if (!ptr) goto end; ptr++;
+        ptr = strchr(ptr, ' '); if (!ptr) goto end; ptr++;
+
+        av_bprint_init(&buffer, JSS_MAX_LINESIZE, JSS_MAX_LINESIZE);
+        jacosub_to_ass(avctx, &buffer, ptr);
+        av_bprint_finalize(&buffer, &dec_sub);
+        ff_ass_add_rect(sub, dec_sub, avpkt->pts, avpkt->duration, 0);
+        av_free(dec_sub);
+    }
+
+end:
+    *got_sub_ptr = sub->num_rects > 0;
+    return avpkt->size;
+}
+
+AVCodec ff_jacosub_decoder = {
+    .name           = "jacosub",
+    .long_name      = NULL_IF_CONFIG_SMALL("JACOsub subtitle"),
+    .type           = AVMEDIA_TYPE_SUBTITLE,
+    .id             = AV_CODEC_ID_JACOSUB,
+    .init           = ff_ass_subtitle_header_default,
+    .decode         = jacosub_decode_frame,
+};
diff --git a/libavcodec/jpegls.c b/libavcodec/jpegls.c
index 4740f11..dc5c9cf 100644
--- a/libavcodec/jpegls.c
+++ b/libavcodec/jpegls.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Michael Niedermayer
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,10 +36,8 @@
     // QBPP = ceil(log2(RANGE))
     for(state->qbpp = 0; (1 << state->qbpp) < state->range; state->qbpp++);
 
-    if(state->bpp < 8)
-        state->limit = 16 + 2 * state->bpp - state->qbpp;
-    else
-        state->limit = (4 * state->bpp) - state->qbpp;
+    state->bpp = FFMAX(av_log2(state->maxval)+1, 2);
+    state->limit = 2*(state->bpp + FFMAX(state->bpp, 8)) - state->qbpp;
 
     for(i = 0; i < 367; i++) {
         state->A[i] = FFMAX((state->range + 32) >> 6, 2);
diff --git a/libavcodec/jpegls.h b/libavcodec/jpegls.h
index 18c71a8..0a6ead3 100644
--- a/libavcodec/jpegls.h
+++ b/libavcodec/jpegls.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Michael Niedermayer
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -41,7 +41,7 @@
     int A[367], B[367], C[365], N[367];
     int limit, reset, bpp, qbpp, maxval, range;
     int near, twonear;
-    int run_index[3];
+    int run_index[4];
 }JLSState;
 
 extern const uint8_t ff_log2_run[32];
@@ -87,6 +87,8 @@
 }
 
 static inline int ff_jpegls_update_state_regular(JLSState *state, int Q, int err){
+    if(FFABS(err) > 0xFFFF)
+        return -0x10000;
     state->A[Q] += FFABS(err);
     err *= state->twonear;
     state->B[Q] += err;
diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c
index 8a55847..516a82f 100644
--- a/libavcodec/jpeglsdec.c
+++ b/libavcodec/jpeglsdec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Michael Niedermayer
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -40,7 +40,7 @@
 * (or test broken JPEG-LS decoder) and slow down ordinary decoding a bit.
 *
 * There is no Golomb code with length >= 32 bits possible, so check and
-* avoid situation of 32 zeros, Libav Golomb decoder is painfully slow
+* avoid situation of 32 zeros, FFmpeg Golomb decoder is painfully slow
 * on this errors.
 */
 //#define JLS_BROKEN
@@ -197,6 +197,9 @@
             r = ff_log2_run[state->run_index[comp]];
             if(r)
                 r = get_bits_long(&s->gb, r);
+            if(x + r * stride > w) {
+                r = (w - x) / stride;
+            }
             for(i = 0; i < r; i++) {
                 W(dst, x, Ra);
                 x += stride;
@@ -261,9 +264,9 @@
     JLSState *state;
     int off = 0, stride = 1, width, shift;
 
-    zero = av_mallocz(s->picture_ptr->linesize[0]);
+    zero = av_mallocz(s->picture.linesize[0]);
     last = zero;
-    cur = s->picture_ptr->data[0];
+    cur = s->picture.data[0];
 
     state = av_mallocz(sizeof(JLSState));
     /* initialize JPEG-LS state from JPEG parameters */
@@ -282,15 +285,17 @@
     else
         shift = point_transform + (16 - s->bits);
 
-    av_dlog(s->avctx, "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n",
-            s->width, s->height, state->near, state->maxval,
-            state->T1, state->T2, state->T3,
-            state->reset, state->limit, state->qbpp, state->range);
-    av_dlog(s->avctx, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n",
-            ilv, point_transform, s->bits, s->cur_scan);
+    if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
+        av_log(s->avctx, AV_LOG_DEBUG, "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n",
+                s->width, s->height, state->near, state->maxval,
+                state->T1, state->T2, state->T3,
+                state->reset, state->limit, state->qbpp, state->range);
+        av_log(s->avctx, AV_LOG_DEBUG, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n",
+                ilv, point_transform, s->bits, s->cur_scan);
+    }
     if(ilv == 0) { /* separate planes */
-        off = s->cur_scan - 1;
         stride = (s->nb_components > 1) ? 3 : 1;
+        off = av_clip(s->cur_scan - 1, 0, stride - 1);
         width = s->width * stride;
         cur += off;
         for(i = 0; i < s->height; i++) {
@@ -302,7 +307,7 @@
                 t = *((uint16_t*)last);
             }
             last = cur;
-            cur += s->picture_ptr->linesize[0];
+            cur += s->picture.linesize[0];
 
             if (s->restart_interval && !--s->restart_count) {
                 align_get_bits(&s->gb);
@@ -312,11 +317,12 @@
     } else if(ilv == 1) { /* line interleaving */
         int j;
         int Rc[3] = {0, 0, 0};
-        memset(cur, 0, s->picture_ptr->linesize[0]);
-        width = s->width * 3;
+        stride = (s->nb_components > 1) ? 3 : 1;
+        memset(cur, 0, s->picture.linesize[0]);
+        width = s->width * stride;
         for(i = 0; i < s->height; i++) {
-            for(j = 0; j < 3; j++) {
-                ls_decode_line(state, s, last + j, cur + j, Rc[j], width, 3, j, 8);
+            for(j = 0; j < stride; j++) {
+                ls_decode_line(state, s, last + j, cur + j, Rc[j], width, stride, j, 8);
                 Rc[j] = last[j];
 
                 if (s->restart_interval && !--s->restart_count) {
@@ -325,7 +331,7 @@
                 }
             }
             last = cur;
-            cur += s->picture_ptr->linesize[0];
+            cur += s->picture.linesize[0];
         }
     } else if(ilv == 2) { /* sample interleaving */
         av_log(s->avctx, AV_LOG_ERROR, "Sample interleaved images are not supported.\n");
@@ -340,22 +346,22 @@
         w = s->width * s->nb_components;
 
         if(s->bits <= 8){
-            uint8_t *src = s->picture_ptr->data[0];
+            uint8_t *src = s->picture.data[0];
 
             for(i = 0; i < s->height; i++){
                 for(x = off; x < w; x+= stride){
                     src[x] <<= shift;
                 }
-                src += s->picture_ptr->linesize[0];
+                src += s->picture.linesize[0];
             }
         }else{
-            uint16_t *src = (uint16_t*) s->picture_ptr->data[0];
+            uint16_t *src = (uint16_t*) s->picture.data[0];
 
             for(i = 0; i < s->height; i++){
                 for(x = 0; x < w; x++){
                     src[x] <<= shift;
                 }
-                src += s->picture_ptr->linesize[0]/2;
+                src += s->picture.linesize[0]/2;
             }
         }
     }
diff --git a/libavcodec/jpeglsdec.h b/libavcodec/jpeglsdec.h
index 4732822..5204ecb 100644
--- a/libavcodec/jpeglsdec.h
+++ b/libavcodec/jpeglsdec.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Michael Niedermayer
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/jpeglsenc.c b/libavcodec/jpeglsenc.c
index fea2a5b..e51e47a 100644
--- a/libavcodec/jpeglsenc.c
+++ b/libavcodec/jpeglsenc.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Michael Niedermayer
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -249,11 +249,9 @@
     else
         comps = 3;
 
-    if ((ret = ff_alloc_packet(pkt, avctx->width*avctx->height*comps*4 +
-                                    FF_MIN_BUFFER_SIZE)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*comps*4 +
+                                    FF_MIN_BUFFER_SIZE)) < 0)
         return ret;
-    }
 
     buf2 = av_malloc(pkt->size);
 
@@ -294,7 +292,11 @@
 
     ls_store_lse(state, &pb);
 
-    zero = av_mallocz(p->linesize[0]);
+    zero = av_mallocz(FFABS(p->linesize[0]));
+    if (!zero) {
+        av_free(state);
+        return AVERROR(ENOMEM);
+    }
     last = zero;
     cur = p->data[0];
     if(avctx->pix_fmt == AV_PIX_FMT_GRAY8){
@@ -343,8 +345,8 @@
         }
     }
 
-    av_free(zero);
-    av_free(state);
+    av_freep(&zero);
+    av_freep(&state);
 
     // the specification says that after doing 0xff escaping unused bits in the
     // last byte must be set to 0, so just append 7 "optional" zero-bits to
@@ -392,7 +394,7 @@
     return 0;
 }
 
-AVCodec ff_jpegls_encoder = { //FIXME avoid MPV_* lossless JPEG should not need them
+AVCodec ff_jpegls_encoder = {
     .name           = "jpegls",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_JPEGLS,
diff --git a/libavcodec/jrevdct.c b/libavcodec/jrevdct.c
index e33558f..395eb8c 100644
--- a/libavcodec/jrevdct.c
+++ b/libavcodec/jrevdct.c
@@ -940,3 +940,216 @@
     dataptr++;                  /* advance pointer to next column */
   }
 }
+
+#undef DCTSIZE
+#define DCTSIZE 4
+#define DCTSTRIDE 8
+
+void ff_j_rev_dct4(DCTBLOCK data)
+{
+  int32_t tmp0, tmp1, tmp2, tmp3;
+  int32_t tmp10, tmp11, tmp12, tmp13;
+  int32_t z1;
+  int32_t d0, d2, d4, d6;
+  register DCTELEM *dataptr;
+  int rowctr;
+
+  /* Pass 1: process rows. */
+  /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
+  /* furthermore, we scale the results by 2**PASS1_BITS. */
+
+  data[0] += 4;
+
+  dataptr = data;
+
+  for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) {
+    /* Due to quantization, we will usually find that many of the input
+     * coefficients are zero, especially the AC terms.  We can exploit this
+     * by short-circuiting the IDCT calculation for any row in which all
+     * the AC terms are zero.  In that case each output is equal to the
+     * DC coefficient (with scale factor as needed).
+     * With typical images and quantization tables, half or more of the
+     * row DCT calculations can be simplified this way.
+     */
+
+    register int *idataptr = (int*)dataptr;
+
+    d0 = dataptr[0];
+    d2 = dataptr[1];
+    d4 = dataptr[2];
+    d6 = dataptr[3];
+
+    if ((d2 | d4 | d6) == 0) {
+      /* AC terms all zero */
+      if (d0) {
+          /* Compute a 32 bit value to assign. */
+          DCTELEM dcval = (DCTELEM) (d0 << PASS1_BITS);
+          register int v = (dcval & 0xffff) | ((dcval << 16) & 0xffff0000);
+
+          idataptr[0] = v;
+          idataptr[1] = v;
+      }
+
+      dataptr += DCTSTRIDE;     /* advance pointer to next row */
+      continue;
+    }
+
+    /* Even part: reverse the even part of the forward DCT. */
+    /* The rotator is sqrt(2)*c(-6). */
+    if (d6) {
+            if (d2) {
+                    /* d0 != 0, d2 != 0, d4 != 0, d6 != 0 */
+                    z1 = MULTIPLY(d2 + d6, FIX_0_541196100);
+                    tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065);
+                    tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865);
+
+                    tmp0 = (d0 + d4) << CONST_BITS;
+                    tmp1 = (d0 - d4) << CONST_BITS;
+
+                    tmp10 = tmp0 + tmp3;
+                    tmp13 = tmp0 - tmp3;
+                    tmp11 = tmp1 + tmp2;
+                    tmp12 = tmp1 - tmp2;
+            } else {
+                    /* d0 != 0, d2 == 0, d4 != 0, d6 != 0 */
+                    tmp2 = MULTIPLY(-d6, FIX_1_306562965);
+                    tmp3 = MULTIPLY(d6, FIX_0_541196100);
+
+                    tmp0 = (d0 + d4) << CONST_BITS;
+                    tmp1 = (d0 - d4) << CONST_BITS;
+
+                    tmp10 = tmp0 + tmp3;
+                    tmp13 = tmp0 - tmp3;
+                    tmp11 = tmp1 + tmp2;
+                    tmp12 = tmp1 - tmp2;
+            }
+    } else {
+            if (d2) {
+                    /* d0 != 0, d2 != 0, d4 != 0, d6 == 0 */
+                    tmp2 = MULTIPLY(d2, FIX_0_541196100);
+                    tmp3 = MULTIPLY(d2, FIX_1_306562965);
+
+                    tmp0 = (d0 + d4) << CONST_BITS;
+                    tmp1 = (d0 - d4) << CONST_BITS;
+
+                    tmp10 = tmp0 + tmp3;
+                    tmp13 = tmp0 - tmp3;
+                    tmp11 = tmp1 + tmp2;
+                    tmp12 = tmp1 - tmp2;
+            } else {
+                    /* d0 != 0, d2 == 0, d4 != 0, d6 == 0 */
+                    tmp10 = tmp13 = (d0 + d4) << CONST_BITS;
+                    tmp11 = tmp12 = (d0 - d4) << CONST_BITS;
+            }
+      }
+
+    /* 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 += DCTSTRIDE;       /* advance pointer to next row */
+  }
+
+  /* Pass 2: process columns. */
+  /* Note that we must descale the results by a factor of 8 == 2**3, */
+  /* and also undo the PASS1_BITS scaling. */
+
+  dataptr = data;
+  for (rowctr = DCTSIZE-1; rowctr >= 0; rowctr--) {
+    /* Columns of zeroes can be exploited in the same way as we did with rows.
+     * However, the row calculation has created many nonzero AC terms, so the
+     * simplification applies less often (typically 5% to 10% of the time).
+     * On machines with very fast multiplication, it's possible that the
+     * test takes more time than it's worth.  In that case this section
+     * may be commented out.
+     */
+
+    d0 = dataptr[DCTSTRIDE*0];
+    d2 = dataptr[DCTSTRIDE*1];
+    d4 = dataptr[DCTSTRIDE*2];
+    d6 = dataptr[DCTSTRIDE*3];
+
+    /* Even part: reverse the even part of the forward DCT. */
+    /* The rotator is sqrt(2)*c(-6). */
+    if (d6) {
+            if (d2) {
+                    /* d0 != 0, d2 != 0, d4 != 0, d6 != 0 */
+                    z1 = MULTIPLY(d2 + d6, FIX_0_541196100);
+                    tmp2 = z1 + MULTIPLY(-d6, FIX_1_847759065);
+                    tmp3 = z1 + MULTIPLY(d2, FIX_0_765366865);
+
+                    tmp0 = (d0 + d4) << CONST_BITS;
+                    tmp1 = (d0 - d4) << CONST_BITS;
+
+                    tmp10 = tmp0 + tmp3;
+                    tmp13 = tmp0 - tmp3;
+                    tmp11 = tmp1 + tmp2;
+                    tmp12 = tmp1 - tmp2;
+            } else {
+                    /* d0 != 0, d2 == 0, d4 != 0, d6 != 0 */
+                    tmp2 = MULTIPLY(-d6, FIX_1_306562965);
+                    tmp3 = MULTIPLY(d6, FIX_0_541196100);
+
+                    tmp0 = (d0 + d4) << CONST_BITS;
+                    tmp1 = (d0 - d4) << CONST_BITS;
+
+                    tmp10 = tmp0 + tmp3;
+                    tmp13 = tmp0 - tmp3;
+                    tmp11 = tmp1 + tmp2;
+                    tmp12 = tmp1 - tmp2;
+            }
+    } else {
+            if (d2) {
+                    /* d0 != 0, d2 != 0, d4 != 0, d6 == 0 */
+                    tmp2 = MULTIPLY(d2, FIX_0_541196100);
+                    tmp3 = MULTIPLY(d2, FIX_1_306562965);
+
+                    tmp0 = (d0 + d4) << CONST_BITS;
+                    tmp1 = (d0 - d4) << CONST_BITS;
+
+                    tmp10 = tmp0 + tmp3;
+                    tmp13 = tmp0 - tmp3;
+                    tmp11 = tmp1 + tmp2;
+                    tmp12 = tmp1 - tmp2;
+            } else {
+                    /* d0 != 0, d2 == 0, d4 != 0, d6 == 0 */
+                    tmp10 = tmp13 = (d0 + d4) << CONST_BITS;
+                    tmp11 = tmp12 = (d0 - d4) << CONST_BITS;
+            }
+    }
+
+    /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
+
+    dataptr[DCTSTRIDE*0] = tmp10 >> (CONST_BITS+PASS1_BITS+3);
+    dataptr[DCTSTRIDE*1] = tmp11 >> (CONST_BITS+PASS1_BITS+3);
+    dataptr[DCTSTRIDE*2] = tmp12 >> (CONST_BITS+PASS1_BITS+3);
+    dataptr[DCTSTRIDE*3] = tmp13 >> (CONST_BITS+PASS1_BITS+3);
+
+    dataptr++;                  /* advance pointer to next column */
+  }
+}
+
+void ff_j_rev_dct2(DCTBLOCK data){
+  int d00, d01, d10, d11;
+
+  data[0] += 4;
+  d00 = data[0+0*DCTSTRIDE] + data[1+0*DCTSTRIDE];
+  d01 = data[0+0*DCTSTRIDE] - data[1+0*DCTSTRIDE];
+  d10 = data[0+1*DCTSTRIDE] + data[1+1*DCTSTRIDE];
+  d11 = data[0+1*DCTSTRIDE] - data[1+1*DCTSTRIDE];
+
+  data[0+0*DCTSTRIDE]= (d00 + d10)>>3;
+  data[1+0*DCTSTRIDE]= (d01 + d11)>>3;
+  data[0+1*DCTSTRIDE]= (d00 - d10)>>3;
+  data[1+1*DCTSTRIDE]= (d01 - d11)>>3;
+}
+
+void ff_j_rev_dct1(DCTBLOCK data){
+  data[0] = (data[0] + 4)>>3;
+}
+
+#undef FIX
+#undef CONST_BITS
diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c
index ed44e15..cec28cc 100644
--- a/libavcodec/jvdec.c
+++ b/libavcodec/jvdec.c
@@ -2,20 +2,20 @@
  * Bitmap Brothers JV video decoder
  * Copyright (c) 2011 Peter Ross <pross@xvid.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -133,16 +133,22 @@
                         AVPacket *avpkt)
 {
     JvContext *s           = avctx->priv_data;
-    int buf_size           = avpkt->size;
     const uint8_t *buf     = avpkt->data;
-    const uint8_t *buf_end = buf + buf_size;
+    const uint8_t *buf_end = buf + avpkt->size;
     int video_size, video_type, i, j;
 
+    if (avpkt->size < 6)
+        return AVERROR_INVALIDDATA;
+
     video_size = AV_RL32(buf);
     video_type = buf[4];
     buf += 5;
 
     if (video_size) {
+        if (video_size < 0 || video_size > avpkt->size - 5) {
+            av_log(avctx, AV_LOG_ERROR, "video size %d invalid\n", video_size);
+            return AVERROR_INVALIDDATA;
+        }
         if (avctx->reget_buffer(avctx, &s->frame) < 0) {
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return -1;
@@ -150,7 +156,7 @@
 
         if (video_type == 0 || video_type == 1) {
             GetBitContext gb;
-            init_get_bits(&gb, buf, 8 * FFMIN(video_size, buf_end - buf));
+            init_get_bits(&gb, buf, 8 * video_size);
 
             for (j = 0; j < avctx->height; j += 8)
                 for (i = 0; i < avctx->width; i += 8)
@@ -159,20 +165,19 @@
 
             buf += video_size;
         } else if (video_type == 2) {
-            if (buf + 1 <= buf_end) {
-                int v = *buf++;
-                for (j = 0; j < avctx->height; j++)
-                    memset(s->frame.data[0] + j*s->frame.linesize[0], v, avctx->width);
-            }
+            int v = *buf++;
+            for (j = 0; j < avctx->height; j++)
+                memset(s->frame.data[0] + j*s->frame.linesize[0], v, avctx->width);
         } else {
             av_log(avctx, AV_LOG_WARNING, "unsupported frame type %i\n", video_type);
             return AVERROR_INVALIDDATA;
         }
     }
 
-    if (buf < buf_end) {
-        for (i = 0; i < AVPALETTE_COUNT && buf + 3 <= buf_end; i++) {
-            s->palette[i] = AV_RB24(buf) << 2;
+    if (buf_end - buf >= AVPALETTE_COUNT * 3) {
+        for (i = 0; i < AVPALETTE_COUNT; i++) {
+            uint32_t pal = AV_RB24(buf);
+            s->palette[i] = 0xFF << 24 | pal << 2 | ((pal >> 4) & 0x30303);
             buf += 3;
         }
         s->palette_has_changed = 1;
@@ -189,7 +194,7 @@
         *(AVFrame*)data = s->frame;
     }
 
-    return buf_size;
+    return avpkt->size;
 }
 
 static av_cold int decode_close(AVCodecContext *avctx)
diff --git a/libavcodec/kbdwin.c b/libavcodec/kbdwin.c
index 3b590b3..2722312 100644
--- a/libavcodec/kbdwin.c
+++ b/libavcodec/kbdwin.c
@@ -1,22 +1,23 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <assert.h>
+
+#include <libavutil/avassert.h>
 #include <libavutil/mathematics.h>
 #include "libavutil/attributes.h"
 #include "kbdwin.h"
@@ -30,7 +31,7 @@
    double local_window[FF_KBD_WINDOW_MAX];
    double alpha2 = (alpha * M_PI / n) * (alpha * M_PI / n);
 
-   assert(n <= FF_KBD_WINDOW_MAX);
+   av_assert0(n <= FF_KBD_WINDOW_MAX);
 
    for (i = 0; i < n; i++) {
        tmp = i * (n - i) * alpha2;
diff --git a/libavcodec/kbdwin.h b/libavcodec/kbdwin.h
index 89b569a..4b93975 100644
--- a/libavcodec/kbdwin.h
+++ b/libavcodec/kbdwin.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c
index 8f32943..1cbd1c3 100644
--- a/libavcodec/kgv1dec.c
+++ b/libavcodec/kgv1dec.c
@@ -2,20 +2,20 @@
  * Kega Game Video (KGV1) decoder
  * Copyright (c) 2010 Daniel Verkamp
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c
index 2b67740..59ae9f2 100644
--- a/libavcodec/kmvc.c
+++ b/libavcodec/kmvc.c
@@ -2,20 +2,20 @@
  * KMVC decoder
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -106,6 +106,10 @@
                             val = bytestream2_get_byte(&ctx->g);
                             mx = val & 0xF;
                             my = val >> 4;
+                            if ((l0x-mx) + 320*(l0y-my) < 0 || (l0x-mx) + 320*(l0y-my) > 316*196) {
+                                av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
+                                return AVERROR_INVALIDDATA;
+                            }
                             for (j = 0; j < 16; j++)
                                 BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) =
                                     BLK(ctx->cur, l0x + (j & 3) - mx, l0y + (j >> 2) - my);
@@ -127,6 +131,10 @@
                                     val = bytestream2_get_byte(&ctx->g);
                                     mx = val & 0xF;
                                     my = val >> 4;
+                                    if ((l1x-mx) + 320*(l1y-my) < 0 || (l1x-mx) + 320*(l1y-my) > 318*198) {
+                                        av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
+                                        return AVERROR_INVALIDDATA;
+                                    }
                                     BLK(ctx->cur, l1x, l1y) = BLK(ctx->cur, l1x - mx, l1y - my);
                                     BLK(ctx->cur, l1x + 1, l1y) =
                                         BLK(ctx->cur, l1x + 1 - mx, l1y - my);
@@ -198,6 +206,10 @@
                             val = bytestream2_get_byte(&ctx->g);
                             mx = (val & 0xF) - 8;
                             my = (val >> 4) - 8;
+                            if ((l0x+mx) + 320*(l0y+my) < 0 || (l0x+mx) + 320*(l0y+my) > 318*198) {
+                                av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
+                                return AVERROR_INVALIDDATA;
+                            }
                             for (j = 0; j < 16; j++)
                                 BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) =
                                     BLK(ctx->prev, l0x + (j & 3) + mx, l0y + (j >> 2) + my);
@@ -219,6 +231,10 @@
                                     val = bytestream2_get_byte(&ctx->g);
                                     mx = (val & 0xF) - 8;
                                     my = (val >> 4) - 8;
+                                    if ((l1x+mx) + 320*(l1y+my) < 0 || (l1x+mx) + 320*(l1y+my) > 318*198) {
+                                        av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
+                                        return AVERROR_INVALIDDATA;
+                                    }
                                     BLK(ctx->cur, l1x, l1y) = BLK(ctx->prev, l1x + mx, l1y + my);
                                     BLK(ctx->cur, l1x + 1, l1y) =
                                         BLK(ctx->prev, l1x + 1 + mx, l1y + my);
@@ -255,7 +271,7 @@
     if (ctx->pic.data[0])
         avctx->release_buffer(avctx, &ctx->pic);
 
-    ctx->pic.reference = 1;
+    ctx->pic.reference = 3;
     ctx->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
     if (avctx->get_buffer(avctx, &ctx->pic) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
@@ -268,7 +284,7 @@
     if (bytestream2_peek_byte(&ctx->g) == 127) {
         bytestream2_skip(&ctx->g, 3);
         for (i = 0; i < 127; i++) {
-            ctx->pal[i + (header & 0x81)] = bytestream2_get_be24(&ctx->g);
+            ctx->pal[i + (header & 0x81)] = 0xFFU << 24 | bytestream2_get_be24(&ctx->g);
             bytestream2_skip(&ctx->g, 1);
         }
         bytestream2_seek(&ctx->g, -127 * 4 - 3, SEEK_CUR);
@@ -286,7 +302,7 @@
         ctx->pic.palette_has_changed = 1;
         // palette starts from index 1 and has 127 entries
         for (i = 1; i <= ctx->palsize; i++) {
-            ctx->pal[i] = bytestream2_get_be24(&ctx->g);
+            ctx->pal[i] = 0xFFU << 24 | bytestream2_get_be24(&ctx->g);
         }
     }
 
@@ -373,7 +389,7 @@
     c->prev = c->frm1;
 
     for (i = 0; i < 256; i++) {
-        c->pal[i] = i * 0x10101;
+        c->pal[i] = 0xFF << 24 | i * 0x10101;
     }
 
     if (avctx->extradata_size < 12) {
@@ -382,7 +398,8 @@
         c->palsize = 127;
     } else {
         c->palsize = AV_RL16(avctx->extradata + 10);
-        if (c->palsize >= MAX_PALSIZE) {
+        if (c->palsize >= (unsigned)MAX_PALSIZE) {
+            c->palsize = 127;
             av_log(avctx, AV_LOG_ERROR, "KMVC palette too large\n");
             return AVERROR_INVALIDDATA;
         }
@@ -397,6 +414,7 @@
         c->setpal = 1;
     }
 
+    avcodec_get_frame_defaults(&c->pic);
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
     return 0;
diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c
index f8db42e..6af0d09 100644
--- a/libavcodec/lagarith.c
+++ b/libavcodec/lagarith.c
@@ -2,20 +2,20 @@
  * Lagarith lossless decoder
  * Copyright (c) 2009 Nathan Caldwell <saintdev (at) gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -199,7 +199,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
-             *                          // breaks backwards compatibilty
+             *                          // breaks backwards compatibility
              *      b =- (signed int)b;
              *      b &= 0xFF;
              * } else {
@@ -250,8 +250,8 @@
 
     if (!line) {
         /* Left prediction only for first line */
-        L = l->dsp.add_hfyu_left_prediction(buf + 1, buf + 1,
-                                            width - 1, buf[0]);
+        L = l->dsp.add_hfyu_left_prediction(buf, buf,
+                                            width, 0);
     } else {
         /* Left pixel is actually prev_row[width] */
         L = buf[width - stride - 1];
@@ -277,11 +277,12 @@
     int L, TL;
 
     if (!line) {
-        if (is_luma) {
-            buf++;
-            width--;
-        }
-        l->dsp.add_hfyu_left_prediction(buf + 1, buf + 1, width - 1, buf[0]);
+        L= buf[0];
+        if (is_luma)
+            buf[0] = 0;
+        l->dsp.add_hfyu_left_prediction(buf, buf, width, 0);
+        if (is_luma)
+            buf[0] = L;
         return;
     }
     if (line == 1) {
@@ -294,14 +295,17 @@
             L += buf[i];
             buf[i] = L;
         }
-        buf   += HEAD;
-        width -= HEAD;
+        for (; i<width; i++) {
+            L     = mid_pred(L&0xFF, buf[i-stride], (L + buf[i-stride] - TL)&0xFF) + buf[i];
+            TL    = buf[i-stride];
+            buf[i]= L;
+        }
     } else {
         TL = buf[width - (2 * stride) - 1];
         L  = buf[width - stride - 1];
+        l->dsp.add_hfyu_median_prediction(buf, buf - stride, buf, width,
+                                        &L, &TL);
     }
-    l->dsp.add_hfyu_median_prediction(buf, buf - stride, buf, width,
-                                      &L, &TL);
 }
 
 static int lag_decode_line(LagarithContext *l, lag_rac *rac,
@@ -375,7 +379,7 @@
         i = 0;
         while (!zero_run && dst + i < end) {
             i++;
-            if (src + i >= src_end)
+            if (i+2 >= src_end - src)
                 return AVERROR_INVALIDDATA;
             zero_run =
                 !(src[i] | (src[i + 1] & mask1) | (src[i + 2] & mask2));
@@ -395,7 +399,7 @@
             dst += i;
         }
     }
-    return src_start - src;
+    return  src - src_start;
 }
 
 
@@ -408,7 +412,7 @@
     int read = 0;
     uint32_t length;
     uint32_t offset = 1;
-    int esc_count = src[0];
+    int esc_count;
     GetBitContext gb;
     lag_rac rac;
     const uint8_t *src_end = src + src_size;
@@ -416,8 +420,14 @@
     rac.avctx = l->avctx;
     l->zeros = 0;
 
+    if(src_size < 2)
+        return AVERROR_INVALIDDATA;
+
+    esc_count = src[0];
     if (esc_count < 4) {
         length = width * height;
+        if(src_size < 5)
+            return AVERROR_INVALIDDATA;
         if (esc_count && AV_RL32(src + 1) < length) {
             length = AV_RL32(src + 1);
             offset += 4;
@@ -500,7 +510,7 @@
                             void *data, int *data_size, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
+    unsigned int buf_size = avpkt->size;
     LagarithContext *l = avctx->priv_data;
     AVFrame *const p = &l->picture;
     uint8_t frametype = 0;
@@ -559,7 +569,7 @@
 
         if (!l->rgb_planes) {
             l->rgb_stride = FFALIGN(avctx->width, 16);
-            l->rgb_planes = av_malloc(l->rgb_stride * avctx->height * planes + 1);
+            l->rgb_planes = av_malloc(l->rgb_stride * avctx->height * planes + 16);
             if (!l->rgb_planes) {
                 av_log(avctx, AV_LOG_ERROR, "cannot allocate temporary buffer\n");
                 return AVERROR(ENOMEM);
@@ -567,14 +577,13 @@
         }
         for (i = 0; i < planes; i++)
             srcs[i] = l->rgb_planes + (i + 1) * l->rgb_stride * avctx->height - l->rgb_stride;
-        if (offset_ry >= buf_size ||
-            offset_gu >= buf_size ||
-            offset_bv >= buf_size ||
-            (planes == 4 && offs[3] >= buf_size)) {
-            av_log(avctx, AV_LOG_ERROR,
-                    "Invalid frame offsets\n");
-            return AVERROR_INVALIDDATA;
-        }
+        for (i = 0; i < planes; i++)
+            if (buf_size <= offs[i]) {
+                av_log(avctx, AV_LOG_ERROR,
+                        "Invalid frame offsets\n");
+                return AVERROR_INVALIDDATA;
+            }
+
         for (i = 0; i < planes; i++)
             lag_decode_arith_plane(l, srcs[i],
                                    avctx->width, avctx->height,
@@ -638,6 +647,9 @@
             av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
             return -1;
         }
+        if (buf_size <= offset_ry || buf_size <= offset_gu || buf_size <= offset_bv) {
+            return AVERROR_INVALIDDATA;
+        }
 
         if (offset_ry >= buf_size ||
             offset_gu >= buf_size ||
diff --git a/libavcodec/lagarithrac.c b/libavcodec/lagarithrac.c
index edfb18f..895acb0 100644
--- a/libavcodec/lagarithrac.c
+++ b/libavcodec/lagarithrac.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2009 Nathan Caldwell <saintdev (at) gmail.com>
  * Copyright (c) 2009 David Conrad
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -41,11 +41,11 @@
     left                = get_bits_left(gb) >> 3;
     l->bytestream_start =
     l->bytestream       = gb->buffer + get_bits_count(gb) / 8;
-    l->bytestream_end   = l->bytestream_start + FFMIN(length, left);
+    l->bytestream_end   = l->bytestream_start + left;
 
     l->range        = 0x80;
     l->low          = *l->bytestream >> 1;
-    l->hash_shift   = FFMAX(l->scale - 8, 0);
+    l->hash_shift   = FFMAX((int)l->scale - 8, 0);
 
     for (i = j = 0; i < 256; i++) {
         unsigned r = i << l->hash_shift;
diff --git a/libavcodec/lagarithrac.h b/libavcodec/lagarithrac.h
index aa36d38..d8d38f2 100644
--- a/libavcodec/lagarithrac.h
+++ b/libavcodec/lagarithrac.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2009 Nathan Caldwell <saintdev (at) gmail.com>
  * Copyright (c) 2009 David Conrad
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/latm_parser.c b/libavcodec/latm_parser.c
index 6fdb897..3820f58 100644
--- a/libavcodec/latm_parser.c
+++ b/libavcodec/latm_parser.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2008 Paul Kendall <paul@kcbbs.gen.nz>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -50,7 +50,6 @@
     pic_found = pc->frame_start_found;
     state     = pc->state;
 
-    i = 0;
     if (!pic_found) {
         for (i = 0; i < buf_size; i++) {
             state = (state<<8) | buf[i];
diff --git a/libavcodec/lcl.h b/libavcodec/lcl.h
index 4e7e170..b60c0e9 100644
--- a/libavcodec/lcl.h
+++ b/libavcodec/lcl.h
@@ -2,20 +2,20 @@
  * LCL (LossLess Codec Library) Codec
  * Copyright (c) 2002-2004 Roberto Togni
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c
index 0de7410..ab188e2 100644
--- a/libavcodec/lcldec.c
+++ b/libavcodec/lcldec.c
@@ -2,20 +2,20 @@
  * LCL (LossLess Codec Library) Codec
  * Copyright (c) 2002-2004 Roberto Togni
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -96,7 +96,13 @@
             ofs = FFMIN(ofs, destptr - destptr_bak);
             cnt *= 4;
             cnt = FFMIN(cnt, destptr_end - destptr);
-            av_memcpy_backptr(destptr, ofs, cnt);
+            if (ofs) {
+                av_memcpy_backptr(destptr, ofs, cnt);
+            } else {
+                // Not known what the correct behaviour is, but
+                // this at least avoids uninitialized data.
+                memset(destptr, 0, cnt);
+            }
             destptr += cnt;
         }
         maskbit >>= 1;
@@ -479,6 +485,7 @@
     unsigned int max_basesize = FFALIGN(avctx->width, 4) * FFALIGN(avctx->height, 4) + AV_LZO_OUTPUT_PADDING;
     unsigned int max_decomp_size;
 
+    avcodec_get_frame_defaults(&c->pic);
     if (avctx->extradata_size < 8) {
         av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n");
         return AVERROR_INVALIDDATA;
diff --git a/libavcodec/lclenc.c b/libavcodec/lclenc.c
index 0fb303c..1702136 100644
--- a/libavcodec/lclenc.c
+++ b/libavcodec/lclenc.c
@@ -2,20 +2,20 @@
  * LCL (LossLess Codec Library) Codec
  * Copyright (c) 2002-2004 Roberto Togni
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -41,7 +41,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include "libavutil/avassert.h"
 #include "avcodec.h"
+#include "internal.h"
 #include "lcl.h"
 #include "libavutil/internal.h"
 #include "libavutil/mem.h"
@@ -79,11 +81,8 @@
     int zret; // Zlib return code
     int max_size = deflateBound(&c->zstream, avctx->width * avctx->height * 3);
 
-    if (!pkt->data &&
-        (ret = av_new_packet(pkt, max_size)) < 0) {
-            av_log(avctx, AV_LOG_ERROR, "Error allocating packet of size %d.\n", max_size);
+    if ((ret = ff_alloc_packet2(avctx, pkt, max_size)) < 0)
             return ret;
-    }
 
     *p = *pict;
     p->pict_type= AV_PICTURE_TYPE_I;
@@ -136,7 +135,7 @@
 
     c->avctx= avctx;
 
-    assert(avctx->width && avctx->height);
+    av_assert0(avctx->width && avctx->height);
 
     avctx->extradata= av_mallocz(8);
     avctx->coded_frame= &c->pic;
diff --git a/libavcodec/libaacplus.c b/libavcodec/libaacplus.c
new file mode 100644
index 0000000..7872fec
--- /dev/null
+++ b/libavcodec/libaacplus.c
@@ -0,0 +1,143 @@
+/*
+ * Interface to libaacplus for aac+ (sbr+ps) encoding
+ * Copyright (c) 2010 tipok <piratfm@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
+ */
+
+/**
+ * @file
+ * Interface to libaacplus for aac+ (sbr+ps) encoding.
+ */
+
+#include <aacplus.h>
+
+#include "avcodec.h"
+#include "internal.h"
+
+typedef struct aacPlusAudioContext {
+    aacplusEncHandle aacplus_handle;
+    unsigned long max_output_bytes;
+    unsigned long samples_input;
+} aacPlusAudioContext;
+
+static av_cold int aacPlus_encode_init(AVCodecContext *avctx)
+{
+    aacPlusAudioContext *s = avctx->priv_data;
+    aacplusEncConfiguration *aacplus_cfg;
+
+    /* number of channels */
+    if (avctx->channels < 1 || avctx->channels > 2) {
+        av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels);
+        return -1;
+    }
+
+    s->aacplus_handle = aacplusEncOpen(avctx->sample_rate, avctx->channels,
+                                       &s->samples_input, &s->max_output_bytes);
+    if(!s->aacplus_handle) {
+            av_log(avctx, AV_LOG_ERROR, "can't open encoder\n");
+            return -1;
+    }
+
+    /* check aacplus version */
+    aacplus_cfg = aacplusEncGetCurrentConfiguration(s->aacplus_handle);
+
+    /* put the options in the configuration struct */
+    if(avctx->profile != FF_PROFILE_AAC_LOW && avctx->profile != FF_PROFILE_UNKNOWN) {
+            av_log(avctx, AV_LOG_ERROR, "invalid AAC profile: %d, only LC supported\n", avctx->profile);
+            aacplusEncClose(s->aacplus_handle);
+            return -1;
+    }
+
+    aacplus_cfg->bitRate = avctx->bit_rate;
+    aacplus_cfg->bandWidth = avctx->cutoff;
+    aacplus_cfg->outputFormat = !(avctx->flags & CODEC_FLAG_GLOBAL_HEADER);
+    aacplus_cfg->inputFormat = AACPLUS_INPUT_16BIT;
+    if (!aacplusEncSetConfiguration(s->aacplus_handle, aacplus_cfg)) {
+        av_log(avctx, AV_LOG_ERROR, "libaacplus doesn't support this output format!\n");
+        return -1;
+    }
+
+    avctx->frame_size = s->samples_input / avctx->channels;
+
+#if FF_API_OLD_ENCODE_AUDIO
+    avctx->coded_frame= avcodec_alloc_frame();
+    avctx->coded_frame->key_frame= 1;
+#endif
+
+    /* Set decoder specific info */
+    avctx->extradata_size = 0;
+    if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
+
+        unsigned char *buffer = NULL;
+        unsigned long decoder_specific_info_size;
+
+        if (aacplusEncGetDecoderSpecificInfo(s->aacplus_handle, &buffer,
+                                           &decoder_specific_info_size) == 1) {
+            avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE);
+            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;
+}
+
+static int aacPlus_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                                const AVFrame *frame, int *got_packet)
+{
+    aacPlusAudioContext *s = avctx->priv_data;
+    int32_t *input_buffer = (int32_t *)frame->data[0];
+    int ret;
+
+    if ((ret = ff_alloc_packet2(avctx, pkt, s->max_output_bytes)))
+        return ret;
+
+    pkt->size = aacplusEncEncode(s->aacplus_handle, input_buffer,
+                                 s->samples_input, pkt->data, pkt->size);
+    *got_packet   = 1;
+    pkt->pts      = frame->pts;
+    return 0;
+}
+
+static av_cold int aacPlus_encode_close(AVCodecContext *avctx)
+{
+    aacPlusAudioContext *s = avctx->priv_data;
+
+#if FF_API_OLD_ENCODE_AUDIO
+    av_freep(&avctx->coded_frame);
+#endif
+    av_freep(&avctx->extradata);
+
+    aacplusEncClose(s->aacplus_handle);
+    return 0;
+}
+
+AVCodec ff_libaacplus_encoder = {
+    .name           = "libaacplus",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_AAC,
+    .priv_data_size = sizeof(aacPlusAudioContext),
+    .init           = aacPlus_encode_init,
+    .encode2        = aacPlus_encode_frame,
+    .close          = aacPlus_encode_close,
+    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
+                                                     AV_SAMPLE_FMT_NONE },
+    .long_name      = NULL_IF_CONFIG_SMALL("libaacplus AAC+ (Advanced Audio Codec with SBR+PS)"),
+};
diff --git a/libavcodec/libavcodec.v b/libavcodec/libavcodec.v
index 0e1c2e1..314d305 100644
--- a/libavcodec/libavcodec.v
+++ b/libavcodec/libavcodec.v
@@ -2,5 +2,32 @@
         global: av*;
                 audio_resample;
                 audio_resample_close;
+                #deprecated, remove after next bump
+                img_get_alpha_info;
+                dsputil_init;
+                ff_find_pix_fmt;
+                ff_framenum_to_drop_timecode;
+                ff_framenum_to_smtpe_timecode;
+                ff_raw_pix_fmt_tags;
+                ff_init_smtpe_timecode;
+                ff_fft*;
+                ff_mdct*;
+                ff_dct*;
+                ff_rdft*;
+                ff_prores_idct_put_10_sse2;
+                ff_simple_idct*;
+                ff_aanscales;
+                ff_faan*;
+                ff_mmx_idct;
+                ff_fdct*;
+                fdct_ifast;
+                j_rev_dct;
+                ff_mmxext_idct;
+                ff_idct_xvid*;
+                ff_jpeg_fdct*;
+                #XBMC's configure checks for ff_vdpau_vc1_decode_picture()
+                ff_vdpau_vc1_decode_picture;
+                ff_dnxhd_get_cid_table;
+                ff_dnxhd_cid_table;
         local:  *;
 };
diff --git a/libavcodec/libcelt_dec.c b/libavcodec/libcelt_dec.c
new file mode 100644
index 0000000..18b7a5e
--- /dev/null
+++ b/libavcodec/libcelt_dec.c
@@ -0,0 +1,145 @@
+/*
+ * Xiph CELT decoder using libcelt
+ * Copyright (c) 2011 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 <celt/celt.h>
+#include <celt/celt_header.h>
+#include "avcodec.h"
+#include "libavutil/intreadwrite.h"
+
+struct libcelt_context {
+    CELTMode *mode;
+    CELTDecoder *dec;
+    AVFrame frame;
+    int discard;
+};
+
+static int ff_celt_error_to_averror(int err)
+{
+    switch (err) {
+        case CELT_BAD_ARG:          return AVERROR(EINVAL);
+#ifdef CELT_BUFFER_TOO_SMALL
+        case CELT_BUFFER_TOO_SMALL: return AVERROR(ENOBUFS);
+#endif
+        case CELT_INTERNAL_ERROR:   return AVERROR(EFAULT);
+        case CELT_CORRUPTED_DATA:   return AVERROR_INVALIDDATA;
+        case CELT_UNIMPLEMENTED:    return AVERROR(ENOSYS);
+#ifdef ENOTRECOVERABLE
+        case CELT_INVALID_STATE:    return AVERROR(ENOTRECOVERABLE);
+#endif
+        case CELT_ALLOC_FAIL:       return AVERROR(ENOMEM);
+        default:                    return AVERROR(EINVAL);
+    }
+}
+
+static int ff_celt_bitstream_version_hack(CELTMode *mode)
+{
+    CELTHeader header = { .version_id = 0 };
+    celt_header_init(&header, mode, 960, 2);
+    return header.version_id;
+}
+
+static av_cold int libcelt_dec_init(AVCodecContext *c)
+{
+    struct libcelt_context *celt = c->priv_data;
+    int err;
+
+    if (!c->channels || !c->frame_size ||
+        c->frame_size > INT_MAX / sizeof(int16_t) / c->channels)
+        return AVERROR(EINVAL);
+    celt->mode = celt_mode_create(c->sample_rate, c->frame_size, &err);
+    if (!celt->mode)
+        return ff_celt_error_to_averror(err);
+    celt->dec = celt_decoder_create_custom(celt->mode, c->channels, &err);
+    if (!celt->dec) {
+        celt_mode_destroy(celt->mode);
+        return ff_celt_error_to_averror(err);
+    }
+    if (c->extradata_size >= 4) {
+        celt->discard = AV_RL32(c->extradata);
+        if (celt->discard < 0 || celt->discard >= c->frame_size) {
+            av_log(c, AV_LOG_WARNING,
+                   "Invalid overlap (%d), ignored.\n", celt->discard);
+            celt->discard = 0;
+        }
+    }
+    if (c->extradata_size >= 8) {
+        unsigned version = AV_RL32(c->extradata + 4);
+        unsigned lib_version = ff_celt_bitstream_version_hack(celt->mode);
+        if (version != lib_version)
+            av_log(c, AV_LOG_WARNING,
+                   "CELT bitstream version 0x%x may be "
+                   "improperly decoded by libcelt for version 0x%x.\n",
+                   version, lib_version);
+    }
+    c->sample_fmt = AV_SAMPLE_FMT_S16;
+    avcodec_get_frame_defaults(&celt->frame);
+    c->coded_frame = &celt->frame;
+    return 0;
+}
+
+static av_cold int libcelt_dec_close(AVCodecContext *c)
+{
+    struct libcelt_context *celt = c->priv_data;
+
+    celt_decoder_destroy(celt->dec);
+    celt_mode_destroy(celt->mode);
+    return 0;
+}
+
+static int libcelt_dec_decode(AVCodecContext *c, void *frame,
+                              int *got_frame_ptr, AVPacket *pkt)
+{
+    struct libcelt_context *celt = c->priv_data;
+    int err;
+    int16_t *pcm;
+
+    celt->frame.nb_samples = c->frame_size;
+    err = c->get_buffer(c, &celt->frame);
+    if (err < 0) {
+        av_log(c, AV_LOG_ERROR, "get_buffer() failed\n");
+        return err;
+    }
+    pcm = (int16_t *)celt->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;
+        memmove(pcm, pcm + celt->discard * c->channels,
+                celt->frame.nb_samples * c->channels * sizeof(int16_t));
+        celt->discard = 0;
+    }
+    *got_frame_ptr = 1;
+    *(AVFrame *)frame = celt->frame;
+    return pkt->size;
+}
+
+AVCodec ff_libcelt_decoder = {
+    .name           = "libcelt",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_CELT,
+    .priv_data_size = sizeof(struct libcelt_context),
+    .init           = libcelt_dec_init,
+    .close          = libcelt_dec_close,
+    .decode         = libcelt_dec_decode,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("Xiph CELT decoder using libcelt"),
+};
diff --git a/libavcodec/libfaac.c b/libavcodec/libfaac.c
index 7297179..0bfed1e 100644
--- a/libavcodec/libfaac.c
+++ b/libavcodec/libfaac.c
@@ -2,20 +2,20 @@
  * Interface to libfaac for aac encoding
  * Copyright (c) 2002 Gildas Bazin <gbazin@netcourrier.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -41,7 +41,6 @@
     AudioFrameQueue afq;
 } FaacAudioContext;
 
-
 static av_cold int Faac_encode_close(AVCodecContext *avctx)
 {
     FaacAudioContext *s = avctx->priv_data;
@@ -187,7 +186,7 @@
     int num_samples  = frame ? frame->nb_samples : 0;
     void *samples    = frame ? frame->data[0]    : NULL;
 
-    if ((ret = ff_alloc_packet(avpkt, (7 + 768) * avctx->channels))) {
+    if ((ret = ff_alloc_packet2(avctx, avpkt, (7 + 768) * avctx->channels))) {
         av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
         return ret;
     }
diff --git a/libavcodec/libfdk-aacenc.c b/libavcodec/libfdk-aacenc.c
index fada1c2..2874e37 100644
--- a/libavcodec/libfdk-aacenc.c
+++ b/libavcodec/libfdk-aacenc.c
@@ -2,20 +2,20 @@
  * AAC encoder wrapper
  * Copyright (c) 2012 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -339,10 +339,8 @@
     }
 
     /* The maximum packet size is 6144 bits aka 768 bytes per channel. */
-    if ((ret = ff_alloc_packet(avpkt, FFMAX(8192, 768 * avctx->channels)))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, FFMAX(8192, 768 * avctx->channels))))
         return ret;
-    }
 
     out_ptr                   = avpkt->data;
     out_buffer_size           = avpkt->size;
diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c
index e6d435b..97f8abe 100644
--- a/libavcodec/libgsm.c
+++ b/libavcodec/libgsm.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2005 Alban Bedel <albeu@free.fr>
  * Copyright (c) 2006, 2007 Michel Bardiaux <mbardiaux@mediaxim.be>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -34,6 +34,15 @@
 #include "gsm.h"
 #include "libavutil/common.h"
 
+static av_cold int libgsm_encode_close(AVCodecContext *avctx) {
+#if FF_API_OLD_ENCODE_AUDIO
+    av_freep(&avctx->coded_frame);
+#endif
+    gsm_destroy(avctx->priv_data);
+    avctx->priv_data = NULL;
+    return 0;
+}
+
 static av_cold int libgsm_encode_init(AVCodecContext *avctx) {
     if (avctx->channels > 1) {
         av_log(avctx, AV_LOG_ERROR, "Mono required for GSM, got %d channels\n",
@@ -57,6 +66,8 @@
     }
 
     avctx->priv_data = gsm_create();
+    if (!avctx->priv_data)
+        goto error;
 
     switch(avctx->codec_id) {
     case AV_CODEC_ID_GSM:
@@ -73,22 +84,14 @@
 
 #if FF_API_OLD_ENCODE_AUDIO
     avctx->coded_frame= avcodec_alloc_frame();
-    if (!avctx->coded_frame) {
-        gsm_destroy(avctx->priv_data);
-        return AVERROR(ENOMEM);
-    }
+    if (!avctx->coded_frame)
+        goto error;
 #endif
 
     return 0;
-}
-
-static av_cold int libgsm_encode_close(AVCodecContext *avctx) {
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
-    gsm_destroy(avctx->priv_data);
-    avctx->priv_data = NULL;
-    return 0;
+error:
+    libgsm_encode_close(avctx);
+    return -1;
 }
 
 static int libgsm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
@@ -98,10 +101,8 @@
     gsm_signal *samples = (gsm_signal *)frame->data[0];
     struct gsm_state *state = avctx->priv_data;
 
-    if ((ret = ff_alloc_packet(avpkt, avctx->block_align))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, avctx->block_align)))
         return ret;
-    }
 
     switch(avctx->codec_id) {
     case AV_CODEC_ID_GSM:
@@ -117,6 +118,7 @@
 }
 
 
+#if CONFIG_LIBGSM_ENCODER
 AVCodec ff_libgsm_encoder = {
     .name           = "libgsm",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -128,7 +130,8 @@
                                                      AV_SAMPLE_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("libgsm GSM"),
 };
-
+#endif
+#if CONFIG_LIBGSM_MS_ENCODER
 AVCodec ff_libgsm_ms_encoder = {
     .name           = "libgsm_ms",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -140,6 +143,7 @@
                                                      AV_SAMPLE_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"),
 };
+#endif
 
 typedef struct LibGSMDecodeContext {
     AVFrame frame;
@@ -237,6 +241,7 @@
         gsm_option(s->state, GSM_OPT_WAV49, &one);
 }
 
+#if CONFIG_LIBGSM_DECODER
 AVCodec ff_libgsm_decoder = {
     .name           = "libgsm",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -249,7 +254,8 @@
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("libgsm GSM"),
 };
-
+#endif
+#if CONFIG_LIBGSM_MS_DECODER
 AVCodec ff_libgsm_ms_decoder = {
     .name           = "libgsm_ms",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -262,3 +268,4 @@
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"),
 };
+#endif
diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c
index a93285c..fe1fa39 100644
--- a/libavcodec/libilbc.c
+++ b/libavcodec/libilbc.c
@@ -2,20 +2,20 @@
  * iLBC decoder/encoder stub
  * Copyright (c) 2012 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -51,7 +51,10 @@
 };
 
 static const AVClass ilbc_dec_class = {
-    "libilbc", av_default_item_name, ilbc_dec_options, LIBAVUTIL_VERSION_INT
+    .class_name = "libilbc",
+    .item_name  = av_default_item_name,
+    .option     = ilbc_dec_options,
+    .version    = LIBAVUTIL_VERSION_INT,
 };
 
 static av_cold int ilbc_decode_init(AVCodecContext *avctx)
@@ -128,7 +131,10 @@
 };
 
 static const AVClass ilbc_enc_class = {
-    "libilbc", av_default_item_name, ilbc_enc_options, LIBAVUTIL_VERSION_INT
+    .class_name = "libilbc",
+    .item_name  = av_default_item_name,
+    .option     = ilbc_enc_options,
+    .version    = LIBAVUTIL_VERSION_INT,
 };
 
 static av_cold int ilbc_encode_init(AVCodecContext *avctx)
diff --git a/libavcodec/libmp3lame.c b/libavcodec/libmp3lame.c
index 871156f..ce17e06 100644
--- a/libavcodec/libmp3lame.c
+++ b/libavcodec/libmp3lame.c
@@ -2,20 +2,20 @@
  * Interface to libmp3lame for mp3 encoding
  * Copyright (c) 2002 Lennert Buytenhek <buytenh@gnu.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -38,7 +38,7 @@
 #include "mpegaudio.h"
 #include "mpegaudiodecheader.h"
 
-#define BUFFER_SIZE (7200 + 2 * MPA_FRAME_SIZE + MPA_FRAME_SIZE / 4)
+#define BUFFER_SIZE (7200 + 2 * MPA_FRAME_SIZE + MPA_FRAME_SIZE / 4+1000) // FIXME: Buffer size to small? Adding 1000 to make up for it.
 
 typedef struct LAMEContext {
     AVClass *class;
@@ -80,6 +80,7 @@
     if ((s->gfp = lame_init()) == NULL)
         return AVERROR(ENOMEM);
 
+
     lame_set_num_channels(s->gfp, avctx->channels);
     lame_set_mode(s->gfp, avctx->channels > 1 ? JOINT_STEREO : MONO);
 
@@ -222,10 +223,8 @@
     av_dlog(avctx, "in:%d packet-len:%d index:%d\n", avctx->frame_size, len,
             s->buffer_index);
     if (len <= s->buffer_index) {
-        if ((ret = ff_alloc_packet(avpkt, len))) {
-            av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+        if ((ret = ff_alloc_packet2(avctx, avpkt, len)))
             return ret;
-        }
         memcpy(avpkt->data, s->buffer, len);
         s->buffer_index -= len;
         memmove(s->buffer, s->buffer + len, s->buffer_index);
diff --git a/libavcodec/libopencore-amr.c b/libavcodec/libopencore-amr.c
index 9a543b4..aa6dfa6 100644
--- a/libavcodec/libopencore-amr.c
+++ b/libavcodec/libopencore-amr.c
@@ -2,20 +2,20 @@
  * AMR Audio decoder stub
  * Copyright (c) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -245,10 +245,8 @@
         s->enc_bitrate = avctx->bit_rate;
     }
 
-    if ((ret = ff_alloc_packet(avpkt, 32))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, 32)))
         return ret;
-    }
 
     if (frame) {
         if (frame->nb_samples < avctx->frame_size) {
diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c
index f9cf7e7..1fa3c5f 100644
--- a/libavcodec/libopenjpegdec.c
+++ b/libavcodec/libopenjpegdec.c
@@ -2,20 +2,20 @@
  * JPEG 2000 decoding support via OpenJPEG
  * Copyright (c) 2009 Jaikrishnan Menon <realityman@gmx.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -40,69 +40,51 @@
 
 // pix_fmts with lower bpp have to be listed before
 // similar pix_fmts with higher bpp.
-#define RGB_PIXEL_FORMATS  AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA,  \
-                           AV_PIX_FMT_RGB48
+#define RGB_PIXEL_FORMATS   AV_PIX_FMT_RGB24,AV_PIX_FMT_RGBA,AV_PIX_FMT_RGB48,AV_PIX_FMT_RGBA64
+#define GRAY_PIXEL_FORMATS  AV_PIX_FMT_GRAY8,AV_PIX_FMT_GRAY8A,AV_PIX_FMT_GRAY16
+#define YUV_PIXEL_FORMATS   AV_PIX_FMT_YUV410P,AV_PIX_FMT_YUV411P,AV_PIX_FMT_YUVA420P, \
+                            AV_PIX_FMT_YUV420P,AV_PIX_FMT_YUV422P,AV_PIX_FMT_YUVA422P, \
+                            AV_PIX_FMT_YUV440P,AV_PIX_FMT_YUV444P,AV_PIX_FMT_YUVA444P, \
+                            AV_PIX_FMT_YUV420P9,AV_PIX_FMT_YUV422P9,AV_PIX_FMT_YUV444P9, \
+                            AV_PIX_FMT_YUV420P10,AV_PIX_FMT_YUV422P10,AV_PIX_FMT_YUV444P10, \
+                            AV_PIX_FMT_YUV420P12,AV_PIX_FMT_YUV422P12,AV_PIX_FMT_YUV444P12, \
+                            AV_PIX_FMT_YUV420P14,AV_PIX_FMT_YUV422P14,AV_PIX_FMT_YUV444P14, \
+                            AV_PIX_FMT_YUV420P16,AV_PIX_FMT_YUV422P16,AV_PIX_FMT_YUV444P16
 
-#define GRAY_PIXEL_FORMATS AV_PIX_FMT_GRAY8, AV_PIX_FMT_Y400A, \
-                           AV_PIX_FMT_GRAY16
-
-#define YUV_PIXEL_FORMATS  AV_PIX_FMT_YUV410P,   AV_PIX_FMT_YUV411P,   \
-                           AV_PIX_FMT_YUVA420P, \
-                           AV_PIX_FMT_YUV420P,   AV_PIX_FMT_YUV422P,   \
-                           AV_PIX_FMT_YUV440P,   AV_PIX_FMT_YUV444P,   \
-                           AV_PIX_FMT_YUV420P9,  AV_PIX_FMT_YUV422P9,  \
-                           AV_PIX_FMT_YUV444P9, \
-                           AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, \
-                           AV_PIX_FMT_YUV444P10, \
-                           AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, \
-                           AV_PIX_FMT_YUV444P16
-
-static const enum AVPixelFormat rgb_pix_fmts[]  = {RGB_PIXEL_FORMATS};
-static const enum AVPixelFormat gray_pix_fmts[] = {GRAY_PIXEL_FORMATS};
-static const enum AVPixelFormat yuv_pix_fmts[]  = {YUV_PIXEL_FORMATS};
-static const enum AVPixelFormat any_pix_fmts[]  = {RGB_PIXEL_FORMATS,
-                                                 GRAY_PIXEL_FORMATS,
-                                                 YUV_PIXEL_FORMATS};
+static const enum AVPixelFormat libopenjpeg_rgb_pix_fmts[]  = {RGB_PIXEL_FORMATS};
+static const enum AVPixelFormat libopenjpeg_gray_pix_fmts[] = {GRAY_PIXEL_FORMATS};
+static const enum AVPixelFormat libopenjpeg_yuv_pix_fmts[]  = {YUV_PIXEL_FORMATS};
+static const enum AVPixelFormat libopenjpeg_all_pix_fmts[]  = {RGB_PIXEL_FORMATS,GRAY_PIXEL_FORMATS,YUV_PIXEL_FORMATS};
 
 typedef struct {
     AVClass *class;
     opj_dparameters_t dec_params;
     AVFrame image;
-    int lowres;
     int lowqual;
 } LibOpenJPEGContext;
 
-static int libopenjpeg_matches_pix_fmt(const opj_image_t *img,
-                                       enum AVPixelFormat pix_fmt)
+static inline int libopenjpeg_matches_pix_fmt(const opj_image_t *image, enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     int match = 1;
 
-    if (desc->nb_components != img->numcomps) {
+    if (desc->nb_components != image->numcomps) {
         return 0;
     }
 
     switch (desc->nb_components) {
-    case 4:
-        match = match &&
-            desc->comp[3].depth_minus1 + 1 >= img->comps[3].prec &&
-            1 == img->comps[3].dx &&
-            1 == img->comps[3].dy;
-    case 3:
-        match = match &&
-            desc->comp[2].depth_minus1 + 1 >= img->comps[2].prec &&
-            1 << desc->log2_chroma_w == img->comps[2].dx &&
-            1 << desc->log2_chroma_h == img->comps[2].dy;
-    case 2:
-        match = match &&
-            desc->comp[1].depth_minus1 + 1 >= img->comps[1].prec &&
-            1 << desc->log2_chroma_w == img->comps[1].dx &&
-            1 << desc->log2_chroma_h == img->comps[1].dy;
-    case 1:
-        match = match &&
-            desc->comp[0].depth_minus1 + 1 >= img->comps[0].prec &&
-            1 == img->comps[0].dx &&
-            1 == img->comps[0].dy;
+    case 4: match = match && desc->comp[3].depth_minus1 + 1 >= image->comps[3].prec &&
+                             1 == image->comps[3].dx &&
+                             1 == image->comps[3].dy;
+    case 3: match = match && desc->comp[2].depth_minus1 + 1 >= image->comps[2].prec &&
+                             1 << desc->log2_chroma_w == image->comps[2].dx &&
+                             1 << desc->log2_chroma_h == image->comps[2].dy;
+    case 2: match = match && desc->comp[1].depth_minus1 + 1 >= image->comps[1].prec &&
+                             1 << desc->log2_chroma_w == image->comps[1].dx &&
+                             1 << desc->log2_chroma_h == image->comps[1].dy;
+    case 1: match = match && desc->comp[0].depth_minus1 + 1 >= image->comps[0].prec &&
+                             1 == image->comps[0].dx &&
+                             1 == image->comps[0].dy;
     default:
         break;
     }
@@ -110,28 +92,27 @@
     return match;
 }
 
-static enum AVPixelFormat libopenjpeg_guess_pix_fmt(const opj_image_t *image)
-{
+static inline enum AVPixelFormat libopenjpeg_guess_pix_fmt(const opj_image_t *image) {
     int index;
     const enum AVPixelFormat *possible_fmts = NULL;
     int possible_fmts_nb = 0;
 
     switch (image->color_space) {
     case CLRSPC_SRGB:
-        possible_fmts = rgb_pix_fmts;
-        possible_fmts_nb = FF_ARRAY_ELEMS(rgb_pix_fmts);
+        possible_fmts = libopenjpeg_rgb_pix_fmts;
+        possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_rgb_pix_fmts);
         break;
     case CLRSPC_GRAY:
-        possible_fmts = gray_pix_fmts;
-        possible_fmts_nb = FF_ARRAY_ELEMS(gray_pix_fmts);
+        possible_fmts = libopenjpeg_gray_pix_fmts;
+        possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_gray_pix_fmts);
         break;
     case CLRSPC_SYCC:
-        possible_fmts = yuv_pix_fmts;
-        possible_fmts_nb = FF_ARRAY_ELEMS(yuv_pix_fmts);
+        possible_fmts = libopenjpeg_yuv_pix_fmts;
+        possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_yuv_pix_fmts);
         break;
     default:
-        possible_fmts = any_pix_fmts;
-        possible_fmts_nb = FF_ARRAY_ELEMS(any_pix_fmts);
+        possible_fmts = libopenjpeg_all_pix_fmts;
+        possible_fmts_nb = FF_ARRAY_ELEMS(libopenjpeg_all_pix_fmts);
         break;
     }
 
@@ -160,11 +141,9 @@
     return 1;
 }
 
-static void libopenjpeg_copy_to_packed8(AVFrame *picture, opj_image_t *image)
-{
+static inline void libopenjpeg_copy_to_packed8(AVFrame *picture, opj_image_t *image) {
     uint8_t *img_ptr;
     int index, x, y, c;
-
     for (y = 0; y < picture->height; y++) {
         index = y*picture->width;
         img_ptr = picture->data[0] + y*picture->linesize[0];
@@ -176,12 +155,10 @@
     }
 }
 
-static void libopenjpeg_copy_to_packed16(AVFrame *picture, opj_image_t *image)
-{
+static inline void libopenjpeg_copy_to_packed16(AVFrame *picture, opj_image_t *image) {
     uint16_t *img_ptr;
     int index, x, y, c;
     int adjust[4];
-
     for (x = 0; x < image->numcomps; x++)
         adjust[x] = FFMAX(FFMIN(16 - image->comps[x].prec, 8), 0);
 
@@ -196,8 +173,7 @@
     }
 }
 
-static void libopenjpeg_copyto8(AVFrame *picture, opj_image_t *image)
-{
+static inline void libopenjpeg_copyto8(AVFrame *picture, opj_image_t *image) {
     int *comp_data;
     uint8_t *img_ptr;
     int index, x, y;
@@ -215,16 +191,14 @@
     }
 }
 
-static void libopenjpeg_copyto16(AVFrame *p, opj_image_t *image)
-{
+static inline void libopenjpeg_copyto16(AVFrame *picture, opj_image_t *image) {
     int *comp_data;
     uint16_t *img_ptr;
     int index, x, y;
-
     for (index = 0; index < image->numcomps; index++) {
         comp_data = image->comps[index].data;
         for (y = 0; y < image->comps[index].h; y++) {
-            img_ptr = (uint16_t*) (p->data[index] + y * p->linesize[index]);
+            img_ptr = (uint16_t*) (picture->data[index] + y * picture->linesize[index]);
             for (x = 0; x < image->comps[index].w; x++) {
                 *img_ptr = *comp_data;
                 img_ptr++;
@@ -289,9 +263,7 @@
         return -1;
     }
     opj_set_event_mgr((opj_common_ptr)dec, NULL, NULL);
-
     ctx->dec_params.cp_limit_decoding = LIMIT_TO_MAIN_HEADER;
-    ctx->dec_params.cp_reduce         = ctx->lowres;
     ctx->dec_params.cp_layer          = ctx->lowqual;
     // Tie decoder with decoding parameters
     opj_setup_decoder(dec, &ctx->dec_params);
@@ -317,11 +289,6 @@
     width  = image->x1 - image->x0;
     height = image->y1 - image->y0;
 
-    if (ctx->lowres) {
-        width  = (width  + (1 << ctx->lowres) - 1) >> ctx->lowres;
-        height = (height + (1 << ctx->lowres) - 1) >> ctx->lowres;
-    }
-
     if (av_image_check_size(width, height, 0, avctx) < 0) {
         av_log(avctx, AV_LOG_ERROR,
                "%dx%d dimension invalid.\n", width, height);
@@ -339,10 +306,8 @@
 
     if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
         av_log(avctx, AV_LOG_ERROR, "Unable to determine pixel format\n");
-        ret = AVERROR_INVALIDDATA;
         goto done;
     }
-
     for (i = 0; i < image->numcomps; i++)
         if (image->comps[i].prec > avctx->bits_per_raw_sample)
             avctx->bits_per_raw_sample = image->comps[i].prec;
@@ -356,6 +321,7 @@
     }
 
     ctx->dec_params.cp_limit_decoding = NO_LIMITATION;
+    ctx->dec_params.cp_reduce = avctx->lowres;
     // Tie decoder with decoding parameters.
     opj_setup_decoder(dec, &ctx->dec_params);
     stream = opj_cio_open((opj_common_ptr)dec, buf, buf_size);
@@ -435,7 +401,6 @@
 
 static const AVOption options[] = {
     { "lowqual", "Limit the number of layers used for decoding",    OFFSET(lowqual), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VD },
-    { "lowres",  "Lower the decoding resolution by a power of two", OFFSET(lowres),  AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VD },
     { NULL },
 };
 
@@ -455,6 +420,7 @@
     .close            = libopenjpeg_decode_close,
     .decode           = libopenjpeg_decode_frame,
     .capabilities     = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
+    .max_lowres       = 31,
     .long_name        = NULL_IF_CONFIG_SMALL("OpenJPEG JPEG 2000"),
     .priv_class       = &class,
     .init_thread_copy = ONLY_IF_THREADS_ENABLED(libopenjpeg_decode_init_thread_copy),
diff --git a/libavcodec/libopenjpegenc.c b/libavcodec/libopenjpegenc.c
index 09b115b..a425731 100644
--- a/libavcodec/libopenjpegenc.c
+++ b/libavcodec/libopenjpegenc.c
@@ -2,20 +2,20 @@
  * JPEG 2000 encoding support via OpenJPEG
  * Copyright (c) 2011 Michael Bradshaw <mbradshaw@sorensonmedia.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -27,6 +27,7 @@
 #define  OPJ_STATIC
 #include <openjpeg.h>
 
+#include "libavutil/avassert.h"
 #include "libavutil/common.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/intreadwrite.h"
@@ -66,36 +67,34 @@
     av_log(data, AV_LOG_DEBUG, "%s\n", msg);
 }
 
-static opj_image_t *libopenjpeg_create_image(AVCodecContext *avctx,
-                                             opj_cparameters_t *parameters)
+static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *parameters)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
     opj_image_cmptparm_t *cmptparm;
-    OPJ_COLOR_SPACE color_space;
     opj_image_t *img;
     int i;
     int sub_dx[4];
     int sub_dy[4];
-    int numcomps = desc->nb_components;
+    int numcomps;
+    OPJ_COLOR_SPACE color_space = CLRSPC_UNKNOWN;
 
-    sub_dx[0] =
-    sub_dx[3] = 1;
-    sub_dy[0] =
-    sub_dy[3] = 1;
-    sub_dx[1] =
-    sub_dx[2] = 1 << desc->log2_chroma_w;
-    sub_dy[1] =
-    sub_dy[2] = 1 << desc->log2_chroma_h;
+    sub_dx[0] = sub_dx[3] = 1;
+    sub_dy[0] = sub_dy[3] = 1;
+    sub_dx[1] = sub_dx[2] = 1 << desc->log2_chroma_w;
+    sub_dy[1] = sub_dy[2] = 1 << desc->log2_chroma_h;
+
+    numcomps = desc->nb_components;
 
     switch (avctx->pix_fmt) {
     case AV_PIX_FMT_GRAY8:
+    case AV_PIX_FMT_GRAY8A:
     case AV_PIX_FMT_GRAY16:
-    case AV_PIX_FMT_Y400A:
         color_space = CLRSPC_GRAY;
         break;
     case AV_PIX_FMT_RGB24:
     case AV_PIX_FMT_RGBA:
     case AV_PIX_FMT_RGB48:
+    case AV_PIX_FMT_RGBA64:
         color_space = CLRSPC_SRGB;
         break;
     case AV_PIX_FMT_YUV410P:
@@ -105,12 +104,20 @@
     case AV_PIX_FMT_YUV440P:
     case AV_PIX_FMT_YUV444P:
     case AV_PIX_FMT_YUVA420P:
+    case AV_PIX_FMT_YUVA422P:
+    case AV_PIX_FMT_YUVA444P:
     case AV_PIX_FMT_YUV420P9:
     case AV_PIX_FMT_YUV422P9:
     case AV_PIX_FMT_YUV444P9:
     case AV_PIX_FMT_YUV420P10:
     case AV_PIX_FMT_YUV422P10:
     case AV_PIX_FMT_YUV444P10:
+    case AV_PIX_FMT_YUV420P12:
+    case AV_PIX_FMT_YUV422P12:
+    case AV_PIX_FMT_YUV444P12:
+    case AV_PIX_FMT_YUV420P14:
+    case AV_PIX_FMT_YUV422P14:
+    case AV_PIX_FMT_YUV444P14:
     case AV_PIX_FMT_YUV420P16:
     case AV_PIX_FMT_YUV422P16:
     case AV_PIX_FMT_YUV444P16:
@@ -125,18 +132,17 @@
 
     cmptparm = av_mallocz(numcomps * sizeof(*cmptparm));
     if (!cmptparm) {
-        av_log(avctx, AV_LOG_ERROR, "Not enough memory");
+        av_log(avctx, AV_LOG_ERROR, "Not enough memory\n");
         return NULL;
     }
-
     for (i = 0; i < numcomps; i++) {
         cmptparm[i].prec = desc->comp[i].depth_minus1 + 1;
         cmptparm[i].bpp  = desc->comp[i].depth_minus1 + 1;
         cmptparm[i].sgnd = 0;
-        cmptparm[i].dx   = sub_dx[i];
-        cmptparm[i].dy   = sub_dy[i];
-        cmptparm[i].w    = avctx->width / sub_dx[i];
-        cmptparm[i].h    = avctx->height / sub_dy[i];
+        cmptparm[i].dx = sub_dx[i];
+        cmptparm[i].dy = sub_dy[i];
+        cmptparm[i].w = avctx->width / sub_dx[i];
+        cmptparm[i].h = avctx->height / sub_dy[i];
     }
 
     img = opj_image_create(numcomps, cmptparm, color_space);
@@ -151,16 +157,16 @@
 
     opj_set_default_encoder_parameters(&ctx->enc_params);
 
-    ctx->enc_params.cp_rsiz          = ctx->profile;
-    ctx->enc_params.mode             = !!avctx->global_quality;
-    ctx->enc_params.cp_cinema        = ctx->cinema_mode;
-    ctx->enc_params.prog_order       = ctx->prog_order;
-    ctx->enc_params.numresolution    = ctx->numresolution;
-    ctx->enc_params.cp_disto_alloc   = ctx->disto_alloc;
-    ctx->enc_params.cp_fixed_alloc   = ctx->fixed_alloc;
+    ctx->enc_params.cp_rsiz = ctx->profile;
+    ctx->enc_params.mode = !!avctx->global_quality;
+    ctx->enc_params.cp_cinema = ctx->cinema_mode;
+    ctx->enc_params.prog_order = ctx->prog_order;
+    ctx->enc_params.numresolution = ctx->numresolution;
+    ctx->enc_params.cp_disto_alloc = ctx->disto_alloc;
+    ctx->enc_params.cp_fixed_alloc = ctx->fixed_alloc;
     ctx->enc_params.cp_fixed_quality = ctx->fixed_quality;
-    ctx->enc_params.tcp_numlayers    = ctx->numlayers;
-    ctx->enc_params.tcp_rates[0]     = FFMAX(avctx->compression_level, 0) * 2;
+    ctx->enc_params.tcp_numlayers = ctx->numlayers;
+    ctx->enc_params.tcp_rates[0] = FFMAX(avctx->compression_level, 0) * 2;
 
     ctx->compress = opj_create_compress(ctx->format);
     if (!ctx->compress) {
@@ -174,15 +180,16 @@
         goto fail;
     }
 
-    ctx->image = libopenjpeg_create_image(avctx, &ctx->enc_params);
+    ctx->image = mj2_create_image(avctx, &ctx->enc_params);
     if (!ctx->image) {
         av_log(avctx, AV_LOG_ERROR, "Error creating the mj2 image\n");
         err = AVERROR(EINVAL);
         goto fail;
     }
 
+    memset(&ctx->event_mgr, 0, sizeof(opj_event_mgr_t));
     ctx->event_mgr.info_handler    = info_callback;
-    ctx->event_mgr.error_handler   = error_callback;
+    ctx->event_mgr.error_handler = error_callback;
     ctx->event_mgr.warning_handler = warning_callback;
     opj_set_event_mgr((opj_common_ptr)ctx->compress, &ctx->event_mgr, avctx);
 
@@ -194,94 +201,131 @@
     return err;
 }
 
-static void libopenjpeg_copy_packed8(AVCodecContext *avctx,
-                                     const AVFrame *frame, opj_image_t *image)
+static int libopenjpeg_copy_packed8(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
 {
     int compno;
-    int x, y;
-    int image_index, frame_index;
+    int x;
+    int y;
+    int image_index;
+    int frame_index;
     const int numcomps = image->numcomps;
 
     for (compno = 0; compno < numcomps; ++compno) {
+        if (image->comps[compno].w > frame->linesize[0] / numcomps) {
+            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
+            return 0;
+        }
+    }
+
+    for (compno = 0; compno < numcomps; ++compno) {
         for (y = 0; y < avctx->height; ++y) {
             image_index = y * avctx->width;
             frame_index = y * frame->linesize[0] + compno;
             for (x = 0; x < avctx->width; ++x) {
-                image->comps[compno].data[image_index++] =
-                    frame->data[0][frame_index];
+                image->comps[compno].data[image_index++] = frame->data[0][frame_index];
                 frame_index += numcomps;
             }
         }
     }
+
+    return 1;
 }
 
-static void libopenjpeg_copy_packed16(AVCodecContext *avctx,
-                                      const AVFrame *frame, opj_image_t *image)
+static int libopenjpeg_copy_packed16(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
 {
     int compno;
-    int x, y;
-    int image_index, frame_index;
+    int x;
+    int y;
+    int image_index;
+    int frame_index;
     const int numcomps = image->numcomps;
     uint16_t *frame_ptr = (uint16_t*)frame->data[0];
 
     for (compno = 0; compno < numcomps; ++compno) {
+        if (image->comps[compno].w > frame->linesize[0] / numcomps) {
+            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
+            return 0;
+        }
+    }
+
+    for (compno = 0; compno < numcomps; ++compno) {
         for (y = 0; y < avctx->height; ++y) {
             image_index = y * avctx->width;
             frame_index = y * (frame->linesize[0] / 2) + compno;
             for (x = 0; x < avctx->width; ++x) {
-                image->comps[compno].data[image_index++] =
-                    frame_ptr[frame_index];
+                image->comps[compno].data[image_index++] = frame_ptr[frame_index];
                 frame_index += numcomps;
             }
         }
     }
+
+    return 1;
 }
 
-static void libopenjpeg_copy_unpacked8(AVCodecContext *avctx,
-                                       const AVFrame *frame, opj_image_t *image)
+static int libopenjpeg_copy_unpacked8(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
 {
     int compno;
-    int x, y;
-    int width, height;
-    int image_index, frame_index;
+    int x;
+    int y;
+    int width;
+    int height;
+    int image_index;
+    int frame_index;
     const int numcomps = image->numcomps;
 
     for (compno = 0; compno < numcomps; ++compno) {
-        width  = avctx->width  / image->comps[compno].dx;
+        if (image->comps[compno].w > frame->linesize[compno]) {
+            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
+            return 0;
+        }
+    }
+
+    for (compno = 0; compno < numcomps; ++compno) {
+        width = avctx->width / image->comps[compno].dx;
         height = avctx->height / image->comps[compno].dy;
         for (y = 0; y < height; ++y) {
             image_index = y * width;
             frame_index = y * frame->linesize[compno];
             for (x = 0; x < width; ++x)
-                image->comps[compno].data[image_index++] =
-                    frame->data[compno][frame_index++];
+                image->comps[compno].data[image_index++] = frame->data[compno][frame_index++];
         }
     }
+
+    return 1;
 }
 
-static void libopenjpeg_copy_unpacked16(AVCodecContext *avctx,
-                                        const AVFrame *frame,
-                                        opj_image_t *image)
+static int libopenjpeg_copy_unpacked16(AVCodecContext *avctx, const AVFrame *frame, opj_image_t *image)
 {
     int compno;
-    int x, y;
-    int width, height;
-    int image_index, frame_index;
+    int x;
+    int y;
+    int width;
+    int height;
+    int image_index;
+    int frame_index;
     const int numcomps = image->numcomps;
     uint16_t *frame_ptr;
 
     for (compno = 0; compno < numcomps; ++compno) {
-        width  = avctx->width  / image->comps[compno].dx;
+        if (image->comps[compno].w > frame->linesize[compno]) {
+            av_log(avctx, AV_LOG_ERROR, "Error: frame's linesize is too small for the image\n");
+            return 0;
+        }
+    }
+
+    for (compno = 0; compno < numcomps; ++compno) {
+        width = avctx->width / image->comps[compno].dx;
         height = avctx->height / image->comps[compno].dy;
         frame_ptr = (uint16_t*)frame->data[compno];
         for (y = 0; y < height; ++y) {
             image_index = y * width;
             frame_index = y * (frame->linesize[compno] / 2);
             for (x = 0; x < width; ++x)
-                image->comps[compno].data[image_index++] =
-                    frame_ptr[frame_index++];
+                image->comps[compno].data[image_index++] = frame_ptr[frame_index++];
         }
     }
+
+    return 1;
 }
 
 static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
@@ -291,6 +335,7 @@
     opj_cinfo_t *compress = ctx->compress;
     opj_image_t *image    = ctx->image;
     opj_cio_t *stream;
+    int cpyresult = 0;
     int ret, len;
 
     // x0, y0 is the top left corner of the image
@@ -303,11 +348,12 @@
     switch (avctx->pix_fmt) {
     case AV_PIX_FMT_RGB24:
     case AV_PIX_FMT_RGBA:
-    case AV_PIX_FMT_Y400A:
-        libopenjpeg_copy_packed8(avctx, frame, image);
+    case AV_PIX_FMT_GRAY8A:
+        cpyresult = libopenjpeg_copy_packed8(avctx, frame, image);
         break;
     case AV_PIX_FMT_RGB48:
-        libopenjpeg_copy_packed16(avctx, frame, image);
+    case AV_PIX_FMT_RGBA64:
+        cpyresult = libopenjpeg_copy_packed16(avctx, frame, image);
         break;
     case AV_PIX_FMT_GRAY8:
     case AV_PIX_FMT_YUV410P:
@@ -317,7 +363,9 @@
     case AV_PIX_FMT_YUV440P:
     case AV_PIX_FMT_YUV444P:
     case AV_PIX_FMT_YUVA420P:
-        libopenjpeg_copy_unpacked8(avctx, frame, image);
+    case AV_PIX_FMT_YUVA422P:
+    case AV_PIX_FMT_YUVA444P:
+        cpyresult = libopenjpeg_copy_unpacked8(avctx, frame, image);
         break;
     case AV_PIX_FMT_GRAY16:
     case AV_PIX_FMT_YUV420P9:
@@ -326,10 +374,16 @@
     case AV_PIX_FMT_YUV444P10:
     case AV_PIX_FMT_YUV422P10:
     case AV_PIX_FMT_YUV420P10:
+    case AV_PIX_FMT_YUV420P12:
+    case AV_PIX_FMT_YUV422P12:
+    case AV_PIX_FMT_YUV444P12:
+    case AV_PIX_FMT_YUV420P14:
+    case AV_PIX_FMT_YUV422P14:
+    case AV_PIX_FMT_YUV444P14:
     case AV_PIX_FMT_YUV444P16:
     case AV_PIX_FMT_YUV422P16:
     case AV_PIX_FMT_YUV420P16:
-        libopenjpeg_copy_unpacked16(avctx, frame, image);
+        cpyresult = libopenjpeg_copy_unpacked16(avctx, frame, image);
         break;
     default:
         av_log(avctx, AV_LOG_ERROR,
@@ -339,6 +393,12 @@
         break;
     }
 
+    if (!cpyresult) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Could not copy the frame data to the internal image buffer\n");
+        return -1;
+    }
+
     opj_setup_encoder(compress, &ctx->enc_params, image);
     stream = opj_cio_open((opj_common_ptr)compress, NULL, 0);
     if (!stream) {
@@ -353,7 +413,7 @@
     }
 
     len = cio_tell(stream);
-    if ((ret = ff_alloc_packet(pkt, len)) < 0) {
+    if ((ret = ff_alloc_packet2(avctx, pkt, len)) < 0) {
         opj_cio_close(stream);
         return ret;
     }
@@ -396,11 +456,11 @@
     { "rpcl",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = RPCL        }, 0,         0,           VE, "prog_order"  },
     { "pcrl",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = PCRL        }, 0,         0,           VE, "prog_order"  },
     { "cprl",          NULL,                0,                     AV_OPT_TYPE_CONST, { .i64 = CPRL        }, 0,         0,           VE, "prog_order"  },
-    { "numresolution", NULL,                OFFSET(numresolution), AV_OPT_TYPE_INT,   { .i64 = 6           }, 1,         10,          VE },
-    { "numlayers",     NULL,                OFFSET(numlayers),     AV_OPT_TYPE_INT,   { .i64 = 1           }, 1,         10,          VE },
-    { "disto_alloc",   NULL,                OFFSET(disto_alloc),   AV_OPT_TYPE_INT,   { .i64 = 1           }, 0,         1,           VE },
-    { "fixed_alloc",   NULL,                OFFSET(fixed_alloc),   AV_OPT_TYPE_INT,   { .i64 = 0           }, 0,         1,           VE },
-    { "fixed_quality", NULL,                OFFSET(fixed_quality), AV_OPT_TYPE_INT,   { .i64 = 0           }, 0,         1,           VE },
+    { "numresolution", NULL,                OFFSET(numresolution), AV_OPT_TYPE_INT,   { .i64 = 6           }, 1,         INT_MAX,     VE                },
+    { "numlayers",     NULL,                OFFSET(numlayers),     AV_OPT_TYPE_INT,   { .i64 = 1           }, 1,         10,          VE                },
+    { "disto_alloc",   NULL,                OFFSET(disto_alloc),   AV_OPT_TYPE_INT,   { .i64 = 1           }, 0,         1,           VE                },
+    { "fixed_alloc",   NULL,                OFFSET(fixed_alloc),   AV_OPT_TYPE_INT,   { .i64 = 0           }, 0,         1,           VE                },
+    { "fixed_quality", NULL,                OFFSET(fixed_quality), AV_OPT_TYPE_INT,   { .i64 = 0           }, 0,         1,           VE                },
     { NULL },
 };
 
@@ -421,13 +481,15 @@
     .close          = libopenjpeg_encode_close,
     .capabilities   = 0,
     .pix_fmts       = (const enum AVPixelFormat[]) {
-        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48,
-        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16, AV_PIX_FMT_Y400A,
+        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48, AV_PIX_FMT_RGBA64,
+        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_YUV411P, AV_PIX_FMT_YUV410P,
+        AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUVA422P,
+        AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUVA444P,
         AV_PIX_FMT_YUV420P9, AV_PIX_FMT_YUV422P9, AV_PIX_FMT_YUV444P9,
         AV_PIX_FMT_YUV420P10, AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
+        AV_PIX_FMT_YUV420P12, AV_PIX_FMT_YUV422P12, AV_PIX_FMT_YUV444P12,
+        AV_PIX_FMT_YUV420P14, AV_PIX_FMT_YUV422P14, AV_PIX_FMT_YUV444P14,
         AV_PIX_FMT_YUV420P16, AV_PIX_FMT_YUV422P16, AV_PIX_FMT_YUV444P16,
         AV_PIX_FMT_NONE
     },
diff --git a/libavcodec/libopus.c b/libavcodec/libopus.c
index b511415..16395c7 100644
--- a/libavcodec/libopus.c
+++ b/libavcodec/libopus.c
@@ -2,20 +2,20 @@
  * libopus encoder/decoder common code
  * Copyright (c) 2012 Nicolas George
  *
- * This file is part of libav.
+ * This file is part of FFmpeg.
  *
- * libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/libopus.h b/libavcodec/libopus.h
index b08257d..a8223d1 100644
--- a/libavcodec/libopus.h
+++ b/libavcodec/libopus.h
@@ -2,20 +2,20 @@
  * libopus encoder/decoder common code
  * Copyright (c) 2012 Nicolas George
  *
- * This file is part of libav.
+ * This file is part of FFmpeg.
  *
- * libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/libopusdec.c b/libavcodec/libopusdec.c
index 1b5b746..f3cad25 100644
--- a/libavcodec/libopusdec.c
+++ b/libavcodec/libopusdec.c
@@ -2,20 +2,20 @@
  * Opus decoder using libopus
  * Copyright (c) 2012 Nicolas George
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,7 @@
 #include "libavutil/avassert.h"
 #include "libavutil/intreadwrite.h"
 #include "avcodec.h"
+#include "internal.h"
 #include "vorbis.h"
 #include "mathops.h"
 #include "libopus.h"
@@ -32,6 +33,10 @@
 struct libopus_context {
     OpusMSDecoder *dec;
     AVFrame frame;
+    int pre_skip;
+#ifndef OPUS_SET_GAIN
+    union { int i; double d; } gain;
+#endif
 };
 
 #define OPUS_HEAD_SIZE 19
@@ -49,6 +54,7 @@
                           ff_vorbis_channel_layouts[avc->channels - 1];
 
     if (avc->extradata_size >= OPUS_HEAD_SIZE) {
+        opus->pre_skip = AV_RL16(avc->extradata + 10);
         gain_db     = sign_extend(AV_RL16(avc->extradata + 16), 16);
         channel_map = AV_RL8 (avc->extradata + 18);
     }
@@ -73,7 +79,7 @@
         const uint8_t *vorbis_offset = ff_vorbis_channel_layout_offsets[avc->channels - 1];
         int ch;
 
-        /* Remap channels from vorbis order to libav order */
+        /* Remap channels from vorbis order to ffmpeg order */
         for (ch = 0; ch < avc->channels; ch++)
             mapping_arr[ch] = mapping[vorbis_offset[ch]];
         mapping = mapping_arr;
@@ -88,11 +94,22 @@
         return ff_opus_error_to_averror(ret);
     }
 
+#ifdef OPUS_SET_GAIN
     ret = opus_multistream_decoder_ctl(opus->dec, OPUS_SET_GAIN(gain_db));
     if (ret != OPUS_OK)
         av_log(avc, AV_LOG_WARNING, "Failed to set gain: %s\n",
                opus_strerror(ret));
+#else
+    {
+        double gain_lin = pow(10, gain_db / (20.0 * 256));
+        if (avc->sample_fmt == AV_SAMPLE_FMT_FLT)
+            opus->gain.d = gain_lin;
+        else
+            opus->gain.i = FFMIN(gain_lin * 65536, INT_MAX);
+    }
+#endif
 
+    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;
@@ -137,6 +154,21 @@
         return ff_opus_error_to_averror(nb_samples);
     }
 
+#ifndef OPUS_SET_GAIN
+    {
+        int i = avc->channels * nb_samples;
+        if (avc->sample_fmt == AV_SAMPLE_FMT_FLT) {
+            float *pcm = (float *)opus->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];
+            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;
@@ -148,6 +180,9 @@
     struct libopus_context *opus = avc->priv_data;
 
     opus_multistream_decoder_ctl(opus->dec, OPUS_RESET_STATE);
+    /* The stream can have been extracted by a tool that is not Opus-aware.
+       Therefore, any packet can become the first of the stream. */
+    avc->internal->skip_samples = opus->pre_skip;
 }
 
 AVCodec ff_libopus_decoder = {
diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c
index f124e19..d198798 100644
--- a/libavcodec/libopusenc.c
+++ b/libavcodec/libopusenc.c
@@ -2,20 +2,20 @@
  * Opus encoder using libopus
  * Copyright (c) 2012 Nathan Caldwell
  *
- * This file is part of libav.
+ * This file is part of FFmpeg.
  *
- * libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -65,8 +65,8 @@
     { 0, 6, 1, 2, 3, 4, 5, 7 },
 };
 
-/* libav to libopus channel order mapping, passed to libopus */
-static const uint8_t libav_libopus_channel_map[8][8] = {
+/* libavcodec to libopus channel order mapping, passed to libopus */
+static const uint8_t libavcodec_libopus_channel_map[8][8] = {
     { 0 },
     { 0, 1 },
     { 0, 1, 2 },
@@ -159,7 +159,7 @@
 
     coupled_stream_count = opus_coupled_streams[avctx->channels - 1];
     opus->stream_count   = avctx->channels - coupled_stream_count;
-    channel_mapping      = libav_libopus_channel_map[avctx->channels - 1];
+    channel_mapping      = libavcodec_libopus_channel_map[avctx->channels - 1];
 
     /* FIXME: Opus can handle up to 255 channels. However, the mapping for
      * anything greater than 8 is undefined. */
diff --git a/libavcodec/libschroedinger.c b/libavcodec/libschroedinger.c
index 68e925c..c4963e1 100644
--- a/libavcodec/libschroedinger.c
+++ b/libavcodec/libschroedinger.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com >
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -190,7 +190,10 @@
     uv_height = y_height >> (SCHRO_FRAME_FORMAT_V_SHIFT(schro_frame_fmt));
 
     p_pic = av_mallocz(sizeof(AVPicture));
-    avpicture_alloc(p_pic, avccontext->pix_fmt, y_width, y_height);
+    if (!p_pic || avpicture_alloc(p_pic, avccontext->pix_fmt, y_width, y_height) < 0) {
+        av_free(p_pic);
+        return NULL;
+    }
 
     p_frame         = schro_frame_new();
     p_frame->format = schro_frame_fmt;
diff --git a/libavcodec/libschroedinger.h b/libavcodec/libschroedinger.h
index bf179d2..f2e513b 100644
--- a/libavcodec/libschroedinger.h
+++ b/libavcodec/libschroedinger.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com >
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/libschroedingerdec.c b/libavcodec/libschroedingerdec.c
index 3cd9f9a..4e523dc 100644
--- a/libavcodec/libschroedingerdec.c
+++ b/libavcodec/libschroedingerdec.c
@@ -2,20 +2,20 @@
  * Dirac decoder support via Schroedinger libraries
  * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com >
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,10 +36,6 @@
 #include "avcodec.h"
 #include "libschroedinger.h"
 
-#undef NDEBUG
-#include <assert.h>
-
-
 #include <schroedinger/schro.h>
 #include <schroedinger/schrodebug.h>
 #include <schroedinger/schrovideoformat.h>
@@ -136,7 +132,7 @@
 }
 
 /**
-* Returns Libav chroma format.
+* Returns FFmpeg chroma format.
 */
 static enum AVPixelFormat get_chroma_format(SchroChromaFormat schro_pix_fmt)
 {
@@ -181,7 +177,7 @@
 
     p_schro_params->format = schro_decoder_get_video_format(decoder);
 
-    /* Tell Libav about sequence details. */
+    /* 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",
diff --git a/libavcodec/libschroedingerenc.c b/libavcodec/libschroedingerenc.c
index 4002286..aed7818 100644
--- a/libavcodec/libschroedingerenc.c
+++ b/libavcodec/libschroedingerenc.c
@@ -2,20 +2,20 @@
  * Dirac encoder support via Schroedinger libraries
  * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com >
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -27,13 +27,11 @@
 * (http://dirac.sourceforge.net/specification.html).
 */
 
-#undef NDEBUG
-#include <assert.h>
-
 #include <schroedinger/schro.h>
 #include <schroedinger/schrodebug.h>
 #include <schroedinger/schrovideoformat.h>
 
+#include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "libschroedinger.h"
@@ -305,8 +303,7 @@
         case SCHRO_STATE_HAVE_BUFFER:
         case SCHRO_STATE_END_OF_STREAM:
             enc_buf = schro_encoder_pull(encoder, &presentation_frame);
-            assert(enc_buf->length > 0);
-            assert(enc_buf->length <= buf_size);
+            av_assert0(enc_buf->length > 0);
             parse_code = enc_buf->data[4];
 
             /* All non-frame data is prepended to actual frame data to
@@ -380,10 +377,8 @@
     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_packet(pkt, pkt_size)) < 0) {
-        av_log(avccontext, AV_LOG_ERROR, "Error getting output packet of size %d.\n", pkt_size);
+    if ((ret = ff_alloc_packet2(avccontext, 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;
diff --git a/libavcodec/libspeexdec.c b/libavcodec/libspeexdec.c
index 0c93f05..51ab7ea 100644
--- a/libavcodec/libspeexdec.c
+++ b/libavcodec/libspeexdec.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2008 David Conrad
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/libspeexenc.c b/libavcodec/libspeexenc.c
index cbfa5be..fb597ef 100644
--- a/libavcodec/libspeexenc.c
+++ b/libavcodec/libspeexenc.c
@@ -2,20 +2,20 @@
  * Copyright (C) 2009 Justin Ruggles
  * Copyright (c) 2009 Xuggle Incorporated
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -92,6 +92,7 @@
 #include "internal.h"
 #include "audio_frame_queue.h"
 
+/* TODO: Think about converting abr, vad, dtx and such flags to a bit field */
 typedef struct {
     AVClass *class;             ///< AVClass for private options
     SpeexBits bits;             ///< libspeex bitwriter context
@@ -303,10 +304,8 @@
     /* write output if all frames for the packet have been encoded */
     if (s->pkt_frame_count == s->frames_per_packet) {
         s->pkt_frame_count = 0;
-        if ((ret = ff_alloc_packet(avpkt, speex_bits_nbytes(&s->bits)))) {
-            av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+        if ((ret = ff_alloc_packet2(avctx, avpkt, speex_bits_nbytes(&s->bits))))
             return ret;
-        }
         ret = speex_bits_write(&s->bits, avpkt->data, avpkt->size);
         speex_bits_reset(&s->bits);
 
diff --git a/libavcodec/libstagefright.cpp b/libavcodec/libstagefright.cpp
new file mode 100644
index 0000000..3c18527
--- /dev/null
+++ b/libavcodec/libstagefright.cpp
@@ -0,0 +1,598 @@
+/*
+ * Interface to the Android Stagefright library for
+ * H/W accelerated H.264 decoding
+ *
+ * Copyright (C) 2011 Mohamed Naufal
+ * Copyright (C) 2011 Martin Storsjö
+ *
+ * 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 <binder/ProcessState.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MediaBufferGroup.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/OMXClient.h>
+#include <media/stagefright/OMXCodec.h>
+#include <utils/List.h>
+#include <new>
+#include <map>
+
+extern "C" {
+#include "avcodec.h"
+#include "libavutil/imgutils.h"
+}
+
+#define OMX_QCOM_COLOR_FormatYVU420SemiPlanar 0x7FA30C00
+
+using namespace android;
+
+struct Frame {
+    status_t status;
+    size_t size;
+    int64_t time;
+    int key;
+    uint8_t *buffer;
+    AVFrame *vframe;
+};
+
+struct TimeStamp {
+    int64_t pts;
+    int64_t reordered_opaque;
+};
+
+class CustomSource;
+
+struct StagefrightContext {
+    AVCodecContext *avctx;
+    AVBitStreamFilterContext *bsfc;
+    uint8_t* orig_extradata;
+    int orig_extradata_size;
+    sp<MediaSource> *source;
+    List<Frame*> *in_queue, *out_queue;
+    pthread_mutex_t in_mutex, out_mutex;
+    pthread_cond_t condition;
+    pthread_t decode_thread_id;
+
+    Frame *end_frame;
+    bool source_done;
+    volatile sig_atomic_t thread_started, thread_exited, stop_decode;
+
+    AVFrame *prev_frame;
+    std::map<int64_t, TimeStamp> *ts_map;
+    int64_t frame_index;
+
+    uint8_t *dummy_buf;
+    int dummy_bufsize;
+
+    OMXClient *client;
+    sp<MediaSource> *decoder;
+    const char *decoder_component;
+};
+
+class CustomSource : public MediaSource {
+public:
+    CustomSource(AVCodecContext *avctx, sp<MetaData> meta) {
+        s = (StagefrightContext*)avctx->priv_data;
+        source_meta = meta;
+        frame_size  = (avctx->width * avctx->height * 3) / 2;
+        buf_group.add_buffer(new MediaBuffer(frame_size));
+    }
+
+    virtual sp<MetaData> getFormat() {
+        return source_meta;
+    }
+
+    virtual status_t start(MetaData *params) {
+        return OK;
+    }
+
+    virtual status_t stop() {
+        return OK;
+    }
+
+    virtual status_t read(MediaBuffer **buffer,
+                          const MediaSource::ReadOptions *options) {
+        Frame *frame;
+        status_t ret;
+
+        if (s->thread_exited)
+            return ERROR_END_OF_STREAM;
+        pthread_mutex_lock(&s->in_mutex);
+
+        while (s->in_queue->empty())
+            pthread_cond_wait(&s->condition, &s->in_mutex);
+
+        frame = *s->in_queue->begin();
+        ret = frame->status;
+
+        if (ret == OK) {
+            ret = buf_group.acquire_buffer(buffer);
+            if (ret == OK) {
+                memcpy((*buffer)->data(), frame->buffer, frame->size);
+                (*buffer)->set_range(0, frame->size);
+                (*buffer)->meta_data()->clear();
+                (*buffer)->meta_data()->setInt32(kKeyIsSyncFrame,frame->key);
+                (*buffer)->meta_data()->setInt64(kKeyTime, frame->time);
+            } else {
+                av_log(s->avctx, AV_LOG_ERROR, "Failed to acquire MediaBuffer\n");
+            }
+            av_freep(&frame->buffer);
+        }
+
+        s->in_queue->erase(s->in_queue->begin());
+        pthread_mutex_unlock(&s->in_mutex);
+
+        av_freep(&frame);
+        return ret;
+    }
+
+private:
+    MediaBufferGroup buf_group;
+    sp<MetaData> source_meta;
+    StagefrightContext *s;
+    int frame_size;
+};
+
+void* decode_thread(void *arg)
+{
+    AVCodecContext *avctx = (AVCodecContext*)arg;
+    StagefrightContext *s = (StagefrightContext*)avctx->priv_data;
+    const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[avctx->pix_fmt];
+    Frame* frame;
+    MediaBuffer *buffer;
+    int32_t w, h;
+    int decode_done = 0;
+    int ret;
+    int src_linesize[3];
+    const uint8_t *src_data[3];
+    int64_t out_frame_index = 0;
+
+    do {
+        buffer = NULL;
+        frame = (Frame*)av_mallocz(sizeof(Frame));
+        if (!frame) {
+            frame         = s->end_frame;
+            frame->status = AVERROR(ENOMEM);
+            decode_done   = 1;
+            s->end_frame  = NULL;
+            goto push_frame;
+        }
+        frame->status = (*s->decoder)->read(&buffer);
+        if (frame->status == OK) {
+            sp<MetaData> outFormat = (*s->decoder)->getFormat();
+            outFormat->findInt32(kKeyWidth , &w);
+            outFormat->findInt32(kKeyHeight, &h);
+            frame->vframe = (AVFrame*)av_mallocz(sizeof(AVFrame));
+            if (!frame->vframe) {
+                frame->status = AVERROR(ENOMEM);
+                decode_done   = 1;
+                buffer->release();
+                goto push_frame;
+            }
+            ret = avctx->get_buffer(avctx, frame->vframe);
+            if (ret < 0) {
+                av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+                frame->status = ret;
+                decode_done   = 1;
+                buffer->release();
+                goto push_frame;
+            }
+
+            // The OMX.SEC decoder doesn't signal the modified width/height
+            if (s->decoder_component && !strncmp(s->decoder_component, "OMX.SEC", 7) &&
+                (w & 15 || h & 15)) {
+                if (((w + 15)&~15) * ((h + 15)&~15) * 3/2 == buffer->range_length()) {
+                    w = (w + 15)&~15;
+                    h = (h + 15)&~15;
+                }
+            }
+
+            if (!avctx->width || !avctx->height || avctx->width > w || avctx->height > h) {
+                avctx->width  = w;
+                avctx->height = h;
+            }
+
+            src_linesize[0] = av_image_get_linesize(avctx->pix_fmt, w, 0);
+            src_linesize[1] = av_image_get_linesize(avctx->pix_fmt, w, 1);
+            src_linesize[2] = av_image_get_linesize(avctx->pix_fmt, w, 2);
+
+            src_data[0] = (uint8_t*)buffer->data();
+            src_data[1] = src_data[0] + src_linesize[0] * h;
+            src_data[2] = src_data[1] + src_linesize[1] * -(-h>>pix_desc->log2_chroma_h);
+            av_image_copy(frame->vframe->data, frame->vframe->linesize,
+                          src_data, src_linesize,
+                          avctx->pix_fmt, avctx->width, avctx->height);
+
+            buffer->meta_data()->findInt64(kKeyTime, &out_frame_index);
+            if (out_frame_index && s->ts_map->count(out_frame_index) > 0) {
+                frame->vframe->pts = (*s->ts_map)[out_frame_index].pts;
+                frame->vframe->reordered_opaque = (*s->ts_map)[out_frame_index].reordered_opaque;
+                s->ts_map->erase(out_frame_index);
+            }
+            buffer->release();
+            } else if (frame->status == INFO_FORMAT_CHANGED) {
+                if (buffer)
+                    buffer->release();
+                av_free(frame);
+                continue;
+            } else {
+                decode_done = 1;
+            }
+push_frame:
+        while (true) {
+            pthread_mutex_lock(&s->out_mutex);
+            if (s->out_queue->size() >= 10) {
+                pthread_mutex_unlock(&s->out_mutex);
+                usleep(10000);
+                continue;
+            }
+            break;
+        }
+        s->out_queue->push_back(frame);
+        pthread_mutex_unlock(&s->out_mutex);
+    } while (!decode_done && !s->stop_decode);
+
+    s->thread_exited = true;
+
+    return 0;
+}
+
+static av_cold int Stagefright_init(AVCodecContext *avctx)
+{
+    StagefrightContext *s = (StagefrightContext*)avctx->priv_data;
+    sp<MetaData> meta, outFormat;
+    int32_t colorFormat = 0;
+    int ret;
+
+    if (!avctx->extradata || !avctx->extradata_size || avctx->extradata[0] != 1)
+        return -1;
+
+    s->avctx = avctx;
+    s->bsfc  = av_bitstream_filter_init("h264_mp4toannexb");
+    if (!s->bsfc) {
+        av_log(avctx, AV_LOG_ERROR, "Cannot open the h264_mp4toannexb BSF!\n");
+        return -1;
+    }
+
+    s->orig_extradata_size = avctx->extradata_size;
+    s->orig_extradata = (uint8_t*) av_mallocz(avctx->extradata_size +
+                                              FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!s->orig_extradata) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+    memcpy(s->orig_extradata, avctx->extradata, avctx->extradata_size);
+
+    meta = new MetaData;
+    if (meta == NULL) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
+    meta->setInt32(kKeyWidth, avctx->width);
+    meta->setInt32(kKeyHeight, avctx->height);
+    meta->setData(kKeyAVCC, kTypeAVCC, avctx->extradata, avctx->extradata_size);
+
+    android::ProcessState::self()->startThreadPool();
+
+    s->source    = new sp<MediaSource>();
+    *s->source   = new CustomSource(avctx, meta);
+    s->in_queue  = new List<Frame*>;
+    s->out_queue = new List<Frame*>;
+    s->ts_map    = new std::map<int64_t, TimeStamp>;
+    s->client    = new OMXClient;
+    s->end_frame = (Frame*)av_mallocz(sizeof(Frame));
+    if (s->source == NULL || !s->in_queue || !s->out_queue || !s->client ||
+        !s->ts_map || !s->end_frame) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    if (s->client->connect() !=  OK) {
+        av_log(avctx, AV_LOG_ERROR, "Cannot connect OMX client\n");
+        ret = -1;
+        goto fail;
+    }
+
+    s->decoder  = new sp<MediaSource>();
+    *s->decoder = OMXCodec::Create(s->client->interface(), meta,
+                                  false, *s->source, NULL,
+                                  OMXCodec::kClientNeedsFramebuffer);
+    if ((*s->decoder)->start() !=  OK) {
+        av_log(avctx, AV_LOG_ERROR, "Cannot start decoder\n");
+        ret = -1;
+        s->client->disconnect();
+        goto fail;
+    }
+
+    outFormat = (*s->decoder)->getFormat();
+    outFormat->findInt32(kKeyColorFormat, &colorFormat);
+    if (colorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar ||
+        colorFormat == OMX_COLOR_FormatYUV420SemiPlanar)
+        avctx->pix_fmt = AV_PIX_FMT_NV21;
+    else if (colorFormat == OMX_COLOR_FormatYCbYCr)
+        avctx->pix_fmt = AV_PIX_FMT_YUYV422;
+    else if (colorFormat == OMX_COLOR_FormatCbYCrY)
+        avctx->pix_fmt = AV_PIX_FMT_UYVY422;
+    else
+        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+    outFormat->findCString(kKeyDecoderComponent, &s->decoder_component);
+    if (s->decoder_component)
+        s->decoder_component = av_strdup(s->decoder_component);
+
+    pthread_mutex_init(&s->in_mutex, NULL);
+    pthread_mutex_init(&s->out_mutex, NULL);
+    pthread_cond_init(&s->condition, NULL);
+    return 0;
+
+fail:
+    av_bitstream_filter_close(s->bsfc);
+    av_freep(&s->orig_extradata);
+    av_freep(&s->end_frame);
+    delete s->in_queue;
+    delete s->out_queue;
+    delete s->ts_map;
+    delete s->client;
+    return ret;
+}
+
+static int Stagefright_decode_frame(AVCodecContext *avctx, void *data,
+                                    int *data_size, AVPacket *avpkt)
+{
+    StagefrightContext *s = (StagefrightContext*)avctx->priv_data;
+    Frame *frame;
+    status_t status;
+    int orig_size = avpkt->size;
+    AVPacket pkt = *avpkt;
+    AVFrame *ret_frame;
+
+    if (!s->thread_started) {
+        pthread_create(&s->decode_thread_id, NULL, &decode_thread, avctx);
+        s->thread_started = true;
+    }
+
+    if (avpkt && avpkt->data) {
+        av_bitstream_filter_filter(s->bsfc, avctx, NULL, &pkt.data, &pkt.size,
+                                   avpkt->data, avpkt->size, avpkt->flags & AV_PKT_FLAG_KEY);
+        avpkt = &pkt;
+    }
+
+    if (!s->source_done) {
+        if(!s->dummy_buf) {
+            s->dummy_buf = (uint8_t*)av_malloc(avpkt->size);
+            if (!s->dummy_buf)
+                return AVERROR(ENOMEM);
+            s->dummy_bufsize = avpkt->size;
+            memcpy(s->dummy_buf, avpkt->data, avpkt->size);
+        }
+
+        frame = (Frame*)av_mallocz(sizeof(Frame));
+        if (avpkt->data) {
+            frame->status  = OK;
+            frame->size    = avpkt->size;
+            frame->key     = avpkt->flags & AV_PKT_FLAG_KEY ? 1 : 0;
+            frame->buffer  = (uint8_t*)av_malloc(avpkt->size);
+            if (!frame->buffer) {
+                av_freep(&frame);
+                return AVERROR(ENOMEM);
+            }
+            uint8_t *ptr = avpkt->data;
+            // The OMX.SEC decoder fails without this.
+            if (avpkt->size == orig_size + avctx->extradata_size) {
+                ptr += avctx->extradata_size;
+                frame->size = orig_size;
+            }
+            memcpy(frame->buffer, ptr, orig_size);
+            if (avpkt == &pkt)
+                av_free(avpkt->data);
+
+            frame->time = ++s->frame_index;
+            (*s->ts_map)[s->frame_index].pts = avpkt->pts;
+            (*s->ts_map)[s->frame_index].reordered_opaque = avctx->reordered_opaque;
+        } else {
+            frame->status  = ERROR_END_OF_STREAM;
+            s->source_done = true;
+        }
+
+        while (true) {
+            if (s->thread_exited) {
+                s->source_done = true;
+                break;
+            }
+            pthread_mutex_lock(&s->in_mutex);
+            if (s->in_queue->size() >= 10) {
+                pthread_mutex_unlock(&s->in_mutex);
+                usleep(10000);
+                continue;
+            }
+            s->in_queue->push_back(frame);
+            pthread_cond_signal(&s->condition);
+            pthread_mutex_unlock(&s->in_mutex);
+            break;
+        }
+    }
+    while (true) {
+        pthread_mutex_lock(&s->out_mutex);
+        if (!s->out_queue->empty()) break;
+        pthread_mutex_unlock(&s->out_mutex);
+        if (s->source_done) {
+            usleep(10000);
+            continue;
+        } else {
+            return orig_size;
+        }
+    }
+
+    frame = *s->out_queue->begin();
+    s->out_queue->erase(s->out_queue->begin());
+    pthread_mutex_unlock(&s->out_mutex);
+
+    ret_frame = frame->vframe;
+    status  = frame->status;
+    av_freep(&frame);
+
+    if (status == ERROR_END_OF_STREAM)
+        return 0;
+    if (status != OK) {
+        if (status == AVERROR(ENOMEM))
+            return status;
+        av_log(avctx, AV_LOG_ERROR, "Decode failed: %x\n", status);
+        return -1;
+    }
+
+    if (s->prev_frame) {
+        avctx->release_buffer(avctx, s->prev_frame);
+        av_freep(&s->prev_frame);
+    }
+    s->prev_frame = ret_frame;
+
+    *data_size = sizeof(AVFrame);
+    *(AVFrame*)data = *ret_frame;
+    return orig_size;
+}
+
+static av_cold int Stagefright_close(AVCodecContext *avctx)
+{
+    StagefrightContext *s = (StagefrightContext*)avctx->priv_data;
+    Frame *frame;
+
+    if (s->thread_started) {
+        if (!s->thread_exited) {
+            s->stop_decode = 1;
+
+            // Make sure decode_thread() doesn't get stuck
+            pthread_mutex_lock(&s->out_mutex);
+            while (!s->out_queue->empty()) {
+                frame = *s->out_queue->begin();
+                s->out_queue->erase(s->out_queue->begin());
+                if (frame->vframe) {
+                    avctx->release_buffer(avctx, frame->vframe);
+                    av_freep(&frame->vframe);
+                }
+                av_freep(&frame);
+            }
+            pthread_mutex_unlock(&s->out_mutex);
+
+            // Feed a dummy frame prior to signalling EOF.
+            // This is required to terminate the decoder(OMX.SEC)
+            // when only one frame is read during stream info detection.
+            if (s->dummy_buf && (frame = (Frame*)av_mallocz(sizeof(Frame)))) {
+                frame->status = OK;
+                frame->size   = s->dummy_bufsize;
+                frame->key    = 1;
+                frame->buffer = s->dummy_buf;
+                pthread_mutex_lock(&s->in_mutex);
+                s->in_queue->push_back(frame);
+                pthread_cond_signal(&s->condition);
+                pthread_mutex_unlock(&s->in_mutex);
+                s->dummy_buf = NULL;
+            }
+
+            pthread_mutex_lock(&s->in_mutex);
+            s->end_frame->status = ERROR_END_OF_STREAM;
+            s->in_queue->push_back(s->end_frame);
+            pthread_cond_signal(&s->condition);
+            pthread_mutex_unlock(&s->in_mutex);
+            s->end_frame = NULL;
+        }
+
+        pthread_join(s->decode_thread_id, NULL);
+
+        if (s->prev_frame) {
+            avctx->release_buffer(avctx, s->prev_frame);
+            av_freep(&s->prev_frame);
+        }
+
+        s->thread_started = false;
+    }
+
+    while (!s->in_queue->empty()) {
+        frame = *s->in_queue->begin();
+        s->in_queue->erase(s->in_queue->begin());
+        if (frame->size)
+            av_freep(&frame->buffer);
+        av_freep(&frame);
+    }
+
+    while (!s->out_queue->empty()) {
+        frame = *s->out_queue->begin();
+        s->out_queue->erase(s->out_queue->begin());
+        if (frame->vframe) {
+            avctx->release_buffer(avctx, frame->vframe);
+            av_freep(&frame->vframe);
+        }
+        av_freep(&frame);
+    }
+
+    (*s->decoder)->stop();
+    s->client->disconnect();
+
+    if (s->decoder_component)
+        av_freep(&s->decoder_component);
+    av_freep(&s->dummy_buf);
+    av_freep(&s->end_frame);
+
+    // Reset the extradata back to the original mp4 format, so that
+    // the next invocation (both when decoding and when called from
+    // av_find_stream_info) get the original mp4 format extradata.
+    av_freep(&avctx->extradata);
+    avctx->extradata = s->orig_extradata;
+    avctx->extradata_size = s->orig_extradata_size;
+
+    delete s->in_queue;
+    delete s->out_queue;
+    delete s->ts_map;
+    delete s->client;
+    delete s->decoder;
+    delete s->source;
+
+    pthread_mutex_destroy(&s->in_mutex);
+    pthread_mutex_destroy(&s->out_mutex);
+    pthread_cond_destroy(&s->condition);
+    av_bitstream_filter_close(s->bsfc);
+    return 0;
+}
+
+AVCodec ff_libstagefright_h264_decoder = {
+    "libstagefright_h264",
+    NULL_IF_CONFIG_SMALL("libstagefright H.264"),
+    AVMEDIA_TYPE_VIDEO,
+    AV_CODEC_ID_H264,
+    CODEC_CAP_DELAY,
+    NULL, //supported_framerates
+    NULL, //pix_fmts
+    NULL, //supported_samplerates
+    NULL, //sample_fmts
+    NULL, //channel_layouts
+    0,    //max_lowres
+    NULL, //priv_class
+    NULL, //profiles
+    sizeof(StagefrightContext),
+    NULL, //next
+    NULL, //init_thread_copy
+    NULL, //update_thread_context
+    NULL, //defaults
+    NULL, //init_static_data
+    Stagefright_init,
+    NULL, //encode
+    NULL, //encode2
+    Stagefright_decode_frame,
+    Stagefright_close,
+};
diff --git a/libavcodec/libtheoraenc.c b/libavcodec/libtheoraenc.c
index 6c4eddf..431fa57 100644
--- a/libavcodec/libtheoraenc.c
+++ b/libavcodec/libtheoraenc.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2006 Paul Richards <paul.richards@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,7 +30,7 @@
  * and o_ prefixes on variables which are libogg types.
  */
 
-/* Libav includes */
+/* FFmpeg includes */
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/log.h"
@@ -329,10 +329,8 @@
     }
 
     /* Copy ogg_packet content out to buffer */
-    if ((ret = ff_alloc_packet(pkt, o_packet.bytes)) < 0) {
-        av_log(avc_context, AV_LOG_ERROR, "Error getting output packet of size %ld.\n", o_packet.bytes);
+    if ((ret = ff_alloc_packet2(avc_context, pkt, o_packet.bytes)) < 0)
         return ret;
-    }
     memcpy(pkt->data, o_packet.packet, o_packet.bytes);
 
     // HACK: assumes no encoder delay, this is true until libtheora becomes
diff --git a/libavcodec/libtwolame.c b/libavcodec/libtwolame.c
new file mode 100644
index 0000000..b57fbc9
--- /dev/null
+++ b/libavcodec/libtwolame.c
@@ -0,0 +1,196 @@
+/*
+ * Interface to libtwolame for mp2 encoding
+ * 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
+ */
+
+/**
+ * @file
+ * Interface to libtwolame for mp2 encoding.
+ */
+
+#include <twolame.h>
+
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "mpegaudio.h"
+
+typedef struct TWOLAMEContext {
+    AVClass  *class;
+    int      mode;
+    int      psymodel;
+    int      energy;
+    int      error_protection;
+    int      copyright;
+    int      original;
+
+    twolame_options *glopts;
+    int64_t  next_pts;
+} TWOLAMEContext;
+
+static av_cold int twolame_encode_close(AVCodecContext *avctx)
+{
+    TWOLAMEContext *s = avctx->priv_data;
+    twolame_close(&s->glopts);
+    return 0;
+}
+
+static av_cold int twolame_encode_init(AVCodecContext *avctx)
+{
+    TWOLAMEContext *s = avctx->priv_data;
+    int ret;
+
+    avctx->frame_size = TWOLAME_SAMPLES_PER_FRAME;
+
+    s->glopts = twolame_init();
+    if (!s->glopts)
+        return AVERROR(ENOMEM);
+
+    twolame_set_verbosity(s->glopts, 0);
+    twolame_set_mode(s->glopts, s->mode);
+    twolame_set_psymodel(s->glopts, s->psymodel);
+    twolame_set_energy_levels(s->glopts, s->energy);
+    twolame_set_error_protection(s->glopts, s->error_protection);
+
+    twolame_set_num_channels(s->glopts, avctx->channels);
+    twolame_set_in_samplerate(s->glopts, avctx->sample_rate);
+    twolame_set_out_samplerate(s->glopts, avctx->sample_rate);
+    if (avctx->flags & CODEC_FLAG_QSCALE || !avctx->bit_rate) {
+        twolame_set_VBR(s->glopts, TRUE);
+        twolame_set_VBR_level(s->glopts, avctx->global_quality);
+        av_log(avctx, AV_LOG_WARNING, "VBR mode is experimental!\n");
+    } else {
+        twolame_set_bitrate(s->glopts, avctx->bit_rate / 1000);
+    }
+
+    if ((ret = twolame_init_params(s->glopts)))
+        goto error;
+
+    return 0;
+error:
+    twolame_encode_close(avctx);
+    return ret;
+}
+
+static int twolame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
+                                const AVFrame *frame, int *got_packet_ptr)
+{
+    TWOLAMEContext *s = avctx->priv_data;
+    int ret;
+
+    if ((ret = ff_alloc_packet2(avctx, avpkt, MPA_MAX_CODED_FRAME_SIZE)))
+        return ret;
+
+    if (frame) {
+        switch (avctx->sample_fmt) {
+        case AV_SAMPLE_FMT_FLT:
+            ret = twolame_encode_buffer_float32_interleaved(s->glopts,
+                                        frame->data[0],
+                                        frame->nb_samples,
+                                        avpkt->data, avpkt->size);
+            break;
+        case AV_SAMPLE_FMT_FLTP:
+            ret = twolame_encode_buffer_float32(s->glopts,
+                                        frame->data[0], frame->data[1],
+                                        frame->nb_samples,
+                                        avpkt->data, avpkt->size);
+            break;
+        case AV_SAMPLE_FMT_S16:
+            ret = twolame_encode_buffer_interleaved(s->glopts,
+                                        frame->data[0],
+                                        frame->nb_samples,
+                                        avpkt->data, avpkt->size);
+            break;
+        case AV_SAMPLE_FMT_S16P:
+            ret = twolame_encode_buffer(s->glopts,
+                                        frame->data[0], frame->data[1],
+                                        frame->nb_samples,
+                                        avpkt->data, avpkt->size);
+            break;
+        default:
+            return AVERROR_BUG;
+        }
+    } else {
+        ret = twolame_encode_flush(s->glopts, avpkt->data, avpkt->size);
+    }
+
+    if (ret > 0) {
+        avpkt->duration = ff_samples_to_time_base(avctx, avctx->frame_size);
+        if (frame) {
+            if (frame->pts != AV_NOPTS_VALUE)
+                avpkt->pts  = frame->pts;
+        } else {
+            avpkt->pts = s->next_pts;
+        }
+        if (avpkt->pts != AV_NOPTS_VALUE)
+            s->next_pts = avpkt->pts + avpkt->duration;
+
+        avpkt->size     = ret;
+        *got_packet_ptr = 1;
+        return 0;
+    }
+
+    return ret;
+}
+
+#define OFFSET(x) offsetof(TWOLAMEContext, x)
+#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "mode",         "Mpeg Mode", OFFSET(mode), AV_OPT_TYPE_INT, { .i64 = TWOLAME_AUTO_MODE }, TWOLAME_AUTO_MODE, TWOLAME_MONO, AE, "mode"},
+    { "auto",         NULL,         0, AV_OPT_TYPE_CONST, { .i64 = TWOLAME_AUTO_MODE },          0, 0, AE, "mode" },
+    { "stereo",       NULL,         0, AV_OPT_TYPE_CONST, { .i64 = TWOLAME_STEREO },             0, 0, AE, "mode" },
+    { "joint_stereo", NULL,         0, AV_OPT_TYPE_CONST, { .i64 = TWOLAME_JOINT_STEREO },       0, 0, AE, "mode" },
+    { "dual_channel", NULL,         0, AV_OPT_TYPE_CONST, { .i64 = TWOLAME_DUAL_CHANNEL },       0, 0, AE, "mode" },
+    { "mono",         NULL,         0, AV_OPT_TYPE_CONST, { .i64 = TWOLAME_MONO },               0, 0, AE, "mode" },
+    { "psymodel",    "Psychoacoustic Model",  OFFSET(psymodel), AV_OPT_TYPE_INT, { .i64 = 3 }, -1, 4, AE},
+    { "energy_levels","enable energy levels", OFFSET(energy),   AV_OPT_TYPE_INT, { .i64 = 0 },  0, 1, AE},
+    { "error_protection","enable CRC error protection", OFFSET(error_protection), AV_OPT_TYPE_INT, { .i64 = 0 },  0, 1, AE},
+    { "copyright",    "set MPEG Audio Copyright flag",  OFFSET(copyright), AV_OPT_TYPE_INT, { .i64 = 0 },  0, 1, AE},
+    { "original",     "set MPEG Audio Original flag",   OFFSET(original),  AV_OPT_TYPE_INT, { .i64 = 0 },  0, 1, AE},
+    { NULL },
+};
+
+static const AVClass libtwolame_class = {
+    .class_name = "libtwolame encoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_libtwolame_encoder = {
+    .name                  = "libtwolame",
+    .type                  = AVMEDIA_TYPE_AUDIO,
+    .id                    = AV_CODEC_ID_MP2,
+    .priv_data_size        = sizeof(TWOLAMEContext),
+    .init                  = twolame_encode_init,
+    .encode2               = twolame_encode_frame,
+    .close                 = twolame_encode_close,
+    .capabilities          = CODEC_CAP_DELAY,
+    .sample_fmts           = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
+                                                             AV_SAMPLE_FMT_FLTP,
+                                                             AV_SAMPLE_FMT_S16,
+                                                             AV_SAMPLE_FMT_S16P,
+                                                             AV_SAMPLE_FMT_NONE },
+    .channel_layouts       = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
+                                                  AV_CH_LAYOUT_STEREO,
+                                                  0 },
+    .supported_samplerates = (const int[]){ 16000, 22050, 24000, 32000, 44100, 48000, 0 },
+    .long_name             = NULL_IF_CONFIG_SMALL("libtwolame MP2 (MPEG audio layer 2)"),
+    .priv_class            = &libtwolame_class,
+};
diff --git a/libavcodec/libutvideo.h b/libavcodec/libutvideo.h
new file mode 100644
index 0000000..a9387e1
--- /dev/null
+++ b/libavcodec/libutvideo.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2011-2012 Derek Buitenhuis
+ *
+ * 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;
+ * version 2 of the License.
+ *
+ * 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
+ * Known FOURCCs:
+ *     'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA)
+ */
+
+#ifndef AVCODEC_LIBUTVIDEO_H
+#define AVCODEC_LIBUTVIDEO_H
+
+#include <stdlib.h>
+#include <utvideo/utvideo.h>
+#include <utvideo/Codec.h>
+
+typedef struct {
+    uint32_t version;
+    uint32_t original_format;
+    uint32_t frameinfo_size;
+    uint32_t flags;
+} UtVideoExtra;
+
+typedef struct {
+    CCodec *codec;
+    unsigned int buf_size;
+    uint8_t *buffer;
+} UtVideoContext;
+
+#endif /* AVCODEC_LIBUTVIDEO_H */
diff --git a/libavcodec/libutvideodec.cpp b/libavcodec/libutvideodec.cpp
new file mode 100644
index 0000000..f4ba8b3
--- /dev/null
+++ b/libavcodec/libutvideodec.cpp
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2011 Derek Buitenhuis
+ *
+ * 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;
+ * version 2 of the License.
+ *
+ * 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
+ * Known FOURCCs:
+ *     'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA)
+ */
+
+extern "C" {
+#include "avcodec.h"
+}
+
+#include "libutvideo.h"
+#include "get_bits.h"
+
+static av_cold int utvideo_decode_init(AVCodecContext *avctx)
+{
+    UtVideoContext *utv = (UtVideoContext *)avctx->priv_data;
+    UtVideoExtra info;
+    int format;
+    int begin_ret;
+
+    if (avctx->extradata_size != 4*4) {
+        av_log(avctx, AV_LOG_ERROR, "Extradata size mismatch.\n");
+        return -1;
+    }
+
+    /* Read extradata */
+    info.version = AV_RL32(avctx->extradata);
+    info.original_format = AV_RL32(avctx->extradata + 4);
+    info.frameinfo_size = AV_RL32(avctx->extradata + 8);
+    info.flags = AV_RL32(avctx->extradata + 12);
+
+    /* Pick format based on FOURCC */
+    switch (avctx->codec_tag) {
+    case MKTAG('U', 'L', 'Y', '0'):
+        avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+        format = UTVF_YV12;
+        break;
+    case MKTAG('U', 'L', 'Y', '2'):
+        avctx->pix_fmt = AV_PIX_FMT_YUYV422;
+        format = UTVF_YUY2;
+        break;
+    case MKTAG('U', 'L', 'R', 'G'):
+        avctx->pix_fmt = AV_PIX_FMT_BGR24;
+        format = UTVF_RGB24_WIN;
+        break;
+    case MKTAG('U', 'L', 'R', 'A'):
+        avctx->pix_fmt = AV_PIX_FMT_RGB32;
+        format = UTVF_RGB32_WIN;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR,
+              "Not a Ut Video FOURCC: %X\n", avctx->codec_tag);
+        return -1;
+    }
+
+    /* Only allocate the buffer once */
+    utv->buf_size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
+    utv->buffer = (uint8_t *)av_malloc(utv->buf_size * sizeof(uint8_t));
+
+    if (utv->buffer == NULL) {
+        av_log(avctx, AV_LOG_ERROR, "Unable to allocate output buffer.\n");
+        return -1;
+    }
+
+    /* Allocate the output frame */
+    avctx->coded_frame = avcodec_alloc_frame();
+
+    /* Ut Video only supports 8-bit */
+    avctx->bits_per_raw_sample = 8;
+
+    /* Is it interlaced? */
+    avctx->coded_frame->interlaced_frame = info.flags & 0x800 ? 1 : 0;
+
+    /* Apparently Ut Video doesn't store this info... */
+    avctx->coded_frame->top_field_first = 1;
+
+    /*
+     * Create a Ut Video instance. Since the function wants
+     * an "interface name" string, pass it the name of the lib.
+     */
+    utv->codec = CCodec::CreateInstance(UNFCC(avctx->codec_tag), "libavcodec");
+
+    /* Initialize Decoding */
+    begin_ret = utv->codec->DecodeBegin(format, avctx->width, avctx->height,
+                            CBGROSSWIDTH_WINDOWS, &info, sizeof(UtVideoExtra));
+
+    /* Check to see if the decoder initlized properly */
+    if (begin_ret != 0) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Could not initialize decoder: %d\n", begin_ret);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int utvideo_decode_frame(AVCodecContext *avctx, void *data,
+                                int *data_size, AVPacket *avpkt)
+{
+    UtVideoContext *utv = (UtVideoContext *)avctx->priv_data;
+    AVFrame *pic = avctx->coded_frame;
+    int w = avctx->width, h = avctx->height;
+
+    /* Set flags */
+    pic->reference = 0;
+    pic->pict_type = AV_PICTURE_TYPE_I;
+    pic->key_frame = 1;
+
+    /* Decode the frame */
+    utv->codec->DecodeFrame(utv->buffer, avpkt->data, true);
+
+    /* Set the output data depending on the colorspace */
+    switch (avctx->pix_fmt) {
+    case AV_PIX_FMT_YUV420P:
+        pic->linesize[0] = w;
+        pic->linesize[1] = pic->linesize[2] = w / 2;
+        pic->data[0] = utv->buffer;
+        pic->data[2] = utv->buffer + (w * h);
+        pic->data[1] = pic->data[2] + (w * h / 4);
+        break;
+    case AV_PIX_FMT_YUYV422:
+        pic->linesize[0] = w * 2;
+        pic->data[0] = utv->buffer;
+        break;
+    case AV_PIX_FMT_BGR24:
+    case AV_PIX_FMT_RGB32:
+        /* Make the linesize negative, since Ut Video uses bottom-up BGR */
+        pic->linesize[0] = -1 * w * (avctx->pix_fmt == AV_PIX_FMT_BGR24 ? 3 : 4);
+        pic->data[0] = utv->buffer + utv->buf_size + pic->linesize[0];
+        break;
+    }
+
+    *data_size = sizeof(AVFrame);
+    *(AVFrame *)data = *pic;
+
+    return avpkt->size;
+}
+
+static av_cold int utvideo_decode_close(AVCodecContext *avctx)
+{
+    UtVideoContext *utv = (UtVideoContext *)avctx->priv_data;
+
+    /* Free output */
+    av_freep(&avctx->coded_frame);
+    av_freep(&utv->buffer);
+
+    /* Finish decoding and clean up the instance */
+    utv->codec->DecodeEnd();
+    CCodec::DeleteInstance(utv->codec);
+
+    return 0;
+}
+
+AVCodec ff_libutvideo_decoder = {
+    "libutvideo",
+    NULL_IF_CONFIG_SMALL("Ut Video"),
+    AVMEDIA_TYPE_VIDEO,
+    AV_CODEC_ID_UTVIDEO,
+    0,    //capabilities
+    NULL, //supported_framerates
+    NULL, //pix_fmts
+    NULL, //supported_samplerates
+    NULL, //sample_fmts
+    NULL, //channel_layouts
+    0,    //max_lowres
+    NULL, //priv_class
+    NULL, //profiles
+    sizeof(UtVideoContext),
+    NULL, //next
+    NULL, //init_thread_copy
+    NULL, //update_thread_context
+    NULL, //defaults
+    NULL, //init_static_data
+    utvideo_decode_init,
+    NULL, //encode
+    NULL, //encode2
+    utvideo_decode_frame,
+    utvideo_decode_close,
+};
diff --git a/libavcodec/libutvideoenc.cpp b/libavcodec/libutvideoenc.cpp
new file mode 100644
index 0000000..e9af7df
--- /dev/null
+++ b/libavcodec/libutvideoenc.cpp
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2012 Derek Buitenhuis
+ *
+ * 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;
+ * version 2 of the License.
+ *
+ * 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
+ * Known FOURCCs:
+ *     'ULY0' (YCbCr 4:2:0), 'ULY2' (YCbCr 4:2:2), 'ULRG' (RGB), 'ULRA' (RGBA)
+ */
+
+extern "C" {
+#include "libavutil/avassert.h"
+#include "avcodec.h"
+#include "internal.h"
+}
+
+#include "libutvideo.h"
+#include "put_bits.h"
+
+static av_cold int utvideo_encode_init(AVCodecContext *avctx)
+{
+    UtVideoContext *utv = (UtVideoContext *)avctx->priv_data;
+    UtVideoExtra *info;
+    uint32_t flags, in_format;
+
+    switch (avctx->pix_fmt) {
+    case AV_PIX_FMT_YUV420P:
+        in_format = UTVF_YV12;
+        avctx->bits_per_coded_sample = 12;
+        avctx->codec_tag = MKTAG('U', 'L', 'Y', '0');
+        break;
+    case AV_PIX_FMT_YUYV422:
+        in_format = UTVF_YUYV;
+        avctx->bits_per_coded_sample = 16;
+        avctx->codec_tag = MKTAG('U', 'L', 'Y', '2');
+        break;
+    case AV_PIX_FMT_BGR24:
+        in_format = UTVF_RGB24_WIN;
+        avctx->bits_per_coded_sample = 24;
+        avctx->codec_tag = MKTAG('U', 'L', 'R', 'G');
+        break;
+    case AV_PIX_FMT_RGB32:
+        in_format = UTVF_RGB32_WIN;
+        avctx->bits_per_coded_sample = 32;
+        avctx->codec_tag = MKTAG('U', 'L', 'R', 'A');
+        break;
+    default:
+        return AVERROR(EINVAL);
+    }
+
+    /* Check before we alloc anything */
+    if (avctx->prediction_method != 0 && avctx->prediction_method != 2) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid prediction method.\n");
+        return AVERROR(EINVAL);
+    }
+
+    flags = ((avctx->prediction_method + 1) << 8) | (avctx->thread_count - 1);
+
+    avctx->priv_data = utv;
+    avctx->coded_frame = avcodec_alloc_frame();
+
+    /* Alloc extradata buffer */
+    info = (UtVideoExtra *)av_malloc(sizeof(*info));
+
+    if (info == NULL) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate extradata buffer.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    /*
+     * We use this buffer to hold the data that Ut Video returns,
+     * since we cannot decode planes separately with it.
+     */
+    utv->buf_size = avpicture_get_size(avctx->pix_fmt,
+                                       avctx->width, avctx->height);
+    utv->buffer = (uint8_t *)av_malloc(utv->buf_size);
+
+    if (utv->buffer == NULL) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate output buffer.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    /*
+     * Create a Ut Video instance. Since the function wants
+     * an "interface name" string, pass it the name of the lib.
+     */
+    utv->codec = CCodec::CreateInstance(UNFCC(avctx->codec_tag), "libavcodec");
+
+    /* Initialize encoder */
+    utv->codec->EncodeBegin(in_format, avctx->width, avctx->height,
+                            CBGROSSWIDTH_WINDOWS);
+
+    /* Get extradata from encoder */
+    avctx->extradata_size = utv->codec->EncodeGetExtraDataSize();
+    utv->codec->EncodeGetExtraData(info, avctx->extradata_size, in_format,
+                                   avctx->width, avctx->height,
+                                   CBGROSSWIDTH_WINDOWS);
+    avctx->extradata = (uint8_t *)info;
+
+    /* Set flags */
+    utv->codec->SetState(&flags, sizeof(flags));
+
+    return 0;
+}
+
+static int utvideo_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                                const AVFrame *pic, int *got_packet)
+{
+    UtVideoContext *utv = (UtVideoContext *)avctx->priv_data;
+    int w = avctx->width, h = avctx->height;
+    int ret, rgb_size, i;
+    bool keyframe;
+    uint8_t *y, *u, *v;
+    uint8_t *dst;
+
+    /* Alloc buffer */
+    if ((ret = ff_alloc_packet2(avctx, pkt, utv->buf_size)) < 0)
+        return ret;
+
+    dst = pkt->data;
+
+    /* Move input if needed data into Ut Video friendly buffer */
+    switch (avctx->pix_fmt) {
+    case AV_PIX_FMT_YUV420P:
+        y = utv->buffer;
+        u = y + w * h;
+        v = u + w * h / 4;
+        for (i = 0; i < h; i++) {
+            memcpy(y, pic->data[0] + i * pic->linesize[0], w);
+            y += w;
+        }
+        for (i = 0; i < h / 2; i++) {
+            memcpy(u, pic->data[2] + i * pic->linesize[2], w >> 1);
+            memcpy(v, pic->data[1] + i * pic->linesize[1], w >> 1);
+            u += w >> 1;
+            v += w >> 1;
+        }
+        break;
+    case AV_PIX_FMT_YUYV422:
+        for (i = 0; i < h; i++)
+            memcpy(utv->buffer + i * (w << 1),
+                   pic->data[0] + i * pic->linesize[0], w << 1);
+        break;
+    case AV_PIX_FMT_BGR24:
+    case AV_PIX_FMT_RGB32:
+        /* Ut Video takes bottom-up BGR */
+        rgb_size = avctx->pix_fmt == AV_PIX_FMT_BGR24 ? 3 : 4;
+        for (i = 0; i < h; i++)
+            memcpy(utv->buffer + (h - i - 1) * w * rgb_size,
+                   pic->data[0] + i * pic->linesize[0],
+                   w * rgb_size);
+        break;
+    default:
+        return AVERROR(EINVAL);
+    }
+
+    /* Encode frame */
+    pkt->size = utv->codec->EncodeFrame(dst, &keyframe, utv->buffer);
+
+    if (!pkt->size) {
+        av_log(avctx, AV_LOG_ERROR, "EncodeFrame failed!\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    /*
+     * Ut Video is intra-only and every frame is a keyframe,
+     * and the API always returns true. In case something
+     * durastic changes in the future, such as inter support,
+     * assert that this is true.
+     */
+    av_assert2(keyframe == true);
+    avctx->coded_frame->key_frame = 1;
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+
+    pkt->flags |= AV_PKT_FLAG_KEY;
+    *got_packet = 1;
+    return 0;
+}
+
+static av_cold int utvideo_encode_close(AVCodecContext *avctx)
+{
+    UtVideoContext *utv = (UtVideoContext *)avctx->priv_data;
+
+    av_freep(&avctx->coded_frame);
+    av_freep(&avctx->extradata);
+    av_freep(&utv->buffer);
+
+    utv->codec->EncodeEnd();
+    CCodec::DeleteInstance(utv->codec);
+
+    return 0;
+}
+
+AVCodec ff_libutvideo_encoder = {
+    "libutvideo",
+    NULL_IF_CONFIG_SMALL("Ut Video"),
+    AVMEDIA_TYPE_VIDEO,
+    AV_CODEC_ID_UTVIDEO,
+    CODEC_CAP_AUTO_THREADS | CODEC_CAP_LOSSLESS,
+    NULL, /* supported_framerates */
+    (const enum AVPixelFormat[]) {
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUYV422, AV_PIX_FMT_BGR24,
+        AV_PIX_FMT_RGB32, AV_PIX_FMT_NONE
+    },
+    NULL, /* supported_samplerates */
+    NULL, /* sample_fmts */
+    NULL, /* channel_layouts */
+    0,    /* max_lowres */
+    NULL, /* priv_class */
+    NULL, /* profiles */
+    sizeof(UtVideoContext),
+    NULL, /* next */
+    NULL, /* init_thread_copy */
+    NULL, /* update_thread_context */
+    NULL, /* defaults */
+    NULL, /* init_static_data */
+    utvideo_encode_init,
+    NULL, /* encode */
+    utvideo_encode_frame,
+    NULL, /* decode */
+    utvideo_encode_close,
+    NULL, /* flush */
+};
diff --git a/libavcodec/libvo-aacenc.c b/libavcodec/libvo-aacenc.c
index d09f1ed..3b7aca7 100644
--- a/libavcodec/libvo-aacenc.c
+++ b/libavcodec/libvo-aacenc.c
@@ -2,20 +2,20 @@
  * AAC encoder wrapper
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -161,10 +161,8 @@
             return ret;
     }
 
-    if ((ret = ff_alloc_packet(avpkt, FFMAX(8192, 768 * avctx->channels)))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, FFMAX(8192, 768 * avctx->channels))))
         return ret;
-    }
 
     input.Buffer  = samples;
     input.Length  = 2 * avctx->channels * avctx->frame_size;
@@ -195,6 +193,7 @@
     .init           = aac_encode_init,
     .encode2        = aac_encode_frame,
     .close          = aac_encode_close,
+    .supported_samplerates = avpriv_mpeg4audio_sample_rates,
     .capabilities   = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_NONE },
diff --git a/libavcodec/libvo-amrwbenc.c b/libavcodec/libvo-amrwbenc.c
index 6502456..c463994 100644
--- a/libavcodec/libvo-amrwbenc.c
+++ b/libavcodec/libvo-amrwbenc.c
@@ -2,20 +2,20 @@
  * AMR Audio encoder stub
  * Copyright (c) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -121,10 +121,8 @@
     const int16_t *samples = (const int16_t *)frame->data[0];
     int size, ret;
 
-    if ((ret = ff_alloc_packet(avpkt, MAX_PACKET_SIZE))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, MAX_PACKET_SIZE)))
         return ret;
-    }
 
     if (s->last_bitrate != avctx->bit_rate) {
         s->mode         = get_wb_bitrate_mode(avctx->bit_rate, avctx);
diff --git a/libavcodec/libvorbis.c b/libavcodec/libvorbis.c
deleted file mode 100644
index a31d476..0000000
--- a/libavcodec/libvorbis.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * copyright (c) 2002 Mark Hills <mark@pogo.org.uk>
- *
- * 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
- * Vorbis encoding support via libvorbisenc.
- * @author Mark Hills <mark@pogo.org.uk>
- */
-
-#include <vorbis/vorbisenc.h>
-
-#include "libavutil/fifo.h"
-#include "libavutil/opt.h"
-#include "avcodec.h"
-#include "audio_frame_queue.h"
-#include "bytestream.h"
-#include "internal.h"
-#include "vorbis.h"
-#include "vorbis_parser.h"
-
-#undef NDEBUG
-#include <assert.h>
-
-/* Number of samples the user should send in each call.
- * This value is used because it is the LCD of all possible frame sizes, so
- * an output packet will always start at the same point as one of the input
- * packets.
- */
-#define OGGVORBIS_FRAME_SIZE 64
-
-#define BUFFER_SIZE (1024 * 64)
-
-typedef struct OggVorbisContext {
-    AVClass *av_class;                  /**< class for AVOptions            */
-    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 */
-    AVFifoBuffer *pkt_fifo;             /**< output packet buffer           */
-    int eof;                            /**< end-of-file flag               */
-    int dsp_initialized;                /**< vd has been initialized        */
-    vorbis_comment vc;                  /**< VorbisComment info             */
-    ogg_packet op;                      /**< ogg packet                     */
-    double iblock;                      /**< impulse block bias option      */
-    VorbisParseContext vp;              /**< parse context to get durations */
-    AudioFrameQueue afq;                /**< frame queue for timestamps     */
-} OggVorbisContext;
-
-static const AVOption options[] = {
-    { "iblock", "Sets the impulse block bias", offsetof(OggVorbisContext, iblock), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, -15, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
-    { NULL }
-};
-
-static const AVCodecDefault defaults[] = {
-    { "b",  "0" },
-    { NULL },
-};
-
-static const AVClass class = { "libvorbis", av_default_item_name, options, LIBAVUTIL_VERSION_INT };
-
-
-static int vorbis_error_to_averror(int ov_err)
-{
-    switch (ov_err) {
-    case OV_EFAULT: return AVERROR_BUG;
-    case OV_EINVAL: return AVERROR(EINVAL);
-    case OV_EIMPL:  return AVERROR(EINVAL);
-    default:        return AVERROR_UNKNOWN;
-    }
-}
-
-static av_cold int oggvorbis_init_encoder(vorbis_info *vi,
-                                          AVCodecContext *avctx)
-{
-    OggVorbisContext *s = avctx->priv_data;
-    double cfreq;
-    int ret;
-
-    if (avctx->flags & CODEC_FLAG_QSCALE || !avctx->bit_rate) {
-        /* variable bitrate
-         * NOTE: we use the oggenc range of -1 to 10 for global_quality for
-         *       user convenience, but libvorbis uses -0.1 to 1.0.
-         */
-        float q = avctx->global_quality / (float)FF_QP2LAMBDA;
-        /* default to 3 if the user did not set quality or bitrate */
-        if (!(avctx->flags & CODEC_FLAG_QSCALE))
-            q = 3.0;
-        if ((ret = vorbis_encode_setup_vbr(vi, avctx->channels,
-                                           avctx->sample_rate,
-                                           q / 10.0)))
-            goto error;
-    } else {
-        int minrate = avctx->rc_min_rate > 0 ? avctx->rc_min_rate : -1;
-        int maxrate = avctx->rc_max_rate > 0 ? avctx->rc_max_rate : -1;
-
-        /* average bitrate */
-        if ((ret = vorbis_encode_setup_managed(vi, avctx->channels,
-                                               avctx->sample_rate, maxrate,
-                                               avctx->bit_rate, minrate)))
-            goto error;
-
-        /* variable bitrate by estimate, disable slow rate management */
-        if (minrate == -1 && maxrate == -1)
-            if ((ret = vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE2_SET, NULL)))
-                goto error;
-    }
-
-    /* cutoff frequency */
-    if (avctx->cutoff > 0) {
-        cfreq = avctx->cutoff / 1000.0;
-        if ((ret = vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq)))
-            goto error;
-    }
-
-    /* impulse block bias */
-    if (s->iblock) {
-        if ((ret = vorbis_encode_ctl(vi, OV_ECTL_IBLOCK_SET, &s->iblock)))
-            goto error;
-    }
-
-    if ((ret = vorbis_encode_setup_init(vi)))
-        goto error;
-
-    return 0;
-error:
-    return vorbis_error_to_averror(ret);
-}
-
-/* How many bytes are needed for a buffer of length 'l' */
-static int xiph_len(int l)
-{
-    return 1 + l / 255 + l;
-}
-
-static av_cold int oggvorbis_encode_close(AVCodecContext *avctx)
-{
-    OggVorbisContext *s = avctx->priv_data;
-
-    /* notify vorbisenc this is EOF */
-    if (s->dsp_initialized)
-        vorbis_analysis_wrote(&s->vd, 0);
-
-    vorbis_block_clear(&s->vb);
-    vorbis_dsp_clear(&s->vd);
-    vorbis_info_clear(&s->vi);
-
-    av_fifo_free(s->pkt_fifo);
-    ff_af_queue_close(&s->afq);
-#if FF_API_OLD_ENCODE_AUDIO
-    av_freep(&avctx->coded_frame);
-#endif
-    av_freep(&avctx->extradata);
-
-    return 0;
-}
-
-static av_cold int oggvorbis_encode_init(AVCodecContext *avctx)
-{
-    OggVorbisContext *s = avctx->priv_data;
-    ogg_packet header, header_comm, header_code;
-    uint8_t *p;
-    unsigned int offset;
-    int ret;
-
-    vorbis_info_init(&s->vi);
-    if ((ret = oggvorbis_init_encoder(&s->vi, avctx))) {
-        av_log(avctx, AV_LOG_ERROR, "encoder setup failed\n");
-        goto error;
-    }
-    if ((ret = vorbis_analysis_init(&s->vd, &s->vi))) {
-        av_log(avctx, AV_LOG_ERROR, "analysis init failed\n");
-        ret = vorbis_error_to_averror(ret);
-        goto error;
-    }
-    s->dsp_initialized = 1;
-    if ((ret = vorbis_block_init(&s->vd, &s->vb))) {
-        av_log(avctx, AV_LOG_ERROR, "dsp init failed\n");
-        ret = vorbis_error_to_averror(ret);
-        goto error;
-    }
-
-    vorbis_comment_init(&s->vc);
-    vorbis_comment_add_tag(&s->vc, "encoder", LIBAVCODEC_IDENT);
-
-    if ((ret = vorbis_analysis_headerout(&s->vd, &s->vc, &header, &header_comm,
-                                         &header_code))) {
-        ret = vorbis_error_to_averror(ret);
-        goto error;
-    }
-
-    avctx->extradata_size = 1 + xiph_len(header.bytes)      +
-                                xiph_len(header_comm.bytes) +
-                                header_code.bytes;
-    p = avctx->extradata = av_malloc(avctx->extradata_size +
-                                     FF_INPUT_BUFFER_PADDING_SIZE);
-    if (!p) {
-        ret = AVERROR(ENOMEM);
-        goto error;
-    }
-    p[0]    = 2;
-    offset  = 1;
-    offset += av_xiphlacing(&p[offset], header.bytes);
-    offset += av_xiphlacing(&p[offset], header_comm.bytes);
-    memcpy(&p[offset], header.packet, header.bytes);
-    offset += header.bytes;
-    memcpy(&p[offset], header_comm.packet, header_comm.bytes);
-    offset += header_comm.bytes;
-    memcpy(&p[offset], header_code.packet, header_code.bytes);
-    offset += header_code.bytes;
-    assert(offset == avctx->extradata_size);
-
-    if ((ret = avpriv_vorbis_parse_extradata(avctx, &s->vp)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "invalid extradata\n");
-        return ret;
-    }
-
-    vorbis_comment_clear(&s->vc);
-
-    avctx->frame_size = OGGVORBIS_FRAME_SIZE;
-    ff_af_queue_init(avctx, &s->afq);
-
-    s->pkt_fifo = av_fifo_alloc(BUFFER_SIZE);
-    if (!s->pkt_fifo) {
-        ret = AVERROR(ENOMEM);
-        goto error;
-    }
-
-#if FF_API_OLD_ENCODE_AUDIO
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame) {
-        ret = AVERROR(ENOMEM);
-        goto error;
-    }
-#endif
-
-    return 0;
-error:
-    oggvorbis_encode_close(avctx);
-    return ret;
-}
-
-static int oggvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
-                                  const AVFrame *frame, int *got_packet_ptr)
-{
-    OggVorbisContext *s = avctx->priv_data;
-    ogg_packet op;
-    int ret, duration;
-
-    /* send samples to libvorbis */
-    if (frame) {
-        const int samples = frame->nb_samples;
-        float **buffer;
-        int c, channels = s->vi.channels;
-
-        buffer = vorbis_analysis_buffer(&s->vd, samples);
-        for (c = 0; c < channels; c++) {
-            int co = (channels > 8) ? c :
-                     ff_vorbis_encoding_channel_layout_offsets[channels - 1][c];
-            memcpy(buffer[c], frame->extended_data[co],
-                   samples * sizeof(*buffer[c]));
-        }
-        if ((ret = vorbis_analysis_wrote(&s->vd, samples)) < 0) {
-            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))
-            return ret;
-    } else {
-        if (!s->eof)
-            if ((ret = vorbis_analysis_wrote(&s->vd, 0)) < 0) {
-                av_log(avctx, AV_LOG_ERROR, "error in vorbis_analysis_wrote()\n");
-                return vorbis_error_to_averror(ret);
-            }
-        s->eof = 1;
-    }
-
-    /* retrieve available packets from libvorbis */
-    while ((ret = vorbis_analysis_blockout(&s->vd, &s->vb)) == 1) {
-        if ((ret = vorbis_analysis(&s->vb, NULL)) < 0)
-            break;
-        if ((ret = vorbis_bitrate_addblock(&s->vb)) < 0)
-            break;
-
-        /* add any available packets to the output packet buffer */
-        while ((ret = vorbis_bitrate_flushpacket(&s->vd, &op)) == 1) {
-            if (av_fifo_space(s->pkt_fifo) < sizeof(ogg_packet) + op.bytes) {
-                av_log(avctx, AV_LOG_ERROR, "packet buffer is too small");
-                return AVERROR_BUG;
-            }
-            av_fifo_generic_write(s->pkt_fifo, &op, sizeof(ogg_packet), NULL);
-            av_fifo_generic_write(s->pkt_fifo, op.packet, op.bytes, NULL);
-        }
-        if (ret < 0) {
-            av_log(avctx, AV_LOG_ERROR, "error getting available packets\n");
-            break;
-        }
-    }
-    if (ret < 0) {
-        av_log(avctx, AV_LOG_ERROR, "error getting available packets\n");
-        return vorbis_error_to_averror(ret);
-    }
-
-    /* check for available packets */
-    if (av_fifo_size(s->pkt_fifo) < sizeof(ogg_packet))
-        return 0;
-
-    av_fifo_generic_read(s->pkt_fifo, &op, sizeof(ogg_packet), NULL);
-
-    if ((ret = ff_alloc_packet(avpkt, op.bytes))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
-        return ret;
-    }
-    av_fifo_generic_read(s->pkt_fifo, avpkt->data, op.bytes, NULL);
-
-    avpkt->pts = ff_samples_to_time_base(avctx, op.granulepos);
-
-    duration = avpriv_vorbis_parse_frame(&s->vp, avpkt->data, avpkt->size);
-    if (duration > 0) {
-        /* we do not know encoder delay until we get the first packet from
-         * libvorbis, so we have to update the AudioFrameQueue counts */
-        if (!avctx->delay) {
-            avctx->delay              = duration;
-            s->afq.remaining_delay   += duration;
-            s->afq.remaining_samples += duration;
-        }
-        ff_af_queue_remove(&s->afq, duration, &avpkt->pts, &avpkt->duration);
-    }
-
-    *got_packet_ptr = 1;
-    return 0;
-}
-
-AVCodec ff_libvorbis_encoder = {
-    .name           = "libvorbis",
-    .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = AV_CODEC_ID_VORBIS,
-    .priv_data_size = sizeof(OggVorbisContext),
-    .init           = oggvorbis_encode_init,
-    .encode2        = oggvorbis_encode_frame,
-    .close          = oggvorbis_encode_close,
-    .capabilities   = CODEC_CAP_DELAY,
-    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
-                                                      AV_SAMPLE_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("libvorbis Vorbis"),
-    .priv_class     = &class,
-    .defaults       = defaults,
-};
diff --git a/libavcodec/libvorbisdec.c b/libavcodec/libvorbisdec.c
new file mode 100644
index 0000000..93c65b8
--- /dev/null
+++ b/libavcodec/libvorbisdec.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2002 Mark Hills <mark@pogo.org.uk>
+ *
+ * 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 <vorbis/vorbisenc.h>
+
+#include "avcodec.h"
+#include "bytestream.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 */
+    vorbis_comment vc;                  /**< VorbisComment info             */
+    ogg_packet op;                      /**< ogg packet                     */
+} OggVorbisDecContext;
+
+static int oggvorbis_decode_init(AVCodecContext *avccontext) {
+    OggVorbisDecContext *context = avccontext->priv_data ;
+    uint8_t *p= avccontext->extradata;
+    int i, hsizes[3];
+    unsigned char *headers[3], *extradata = avccontext->extradata;
+
+    vorbis_info_init(&context->vi) ;
+    vorbis_comment_init(&context->vc) ;
+
+    if(! avccontext->extradata_size || ! p) {
+        av_log(avccontext, AV_LOG_ERROR, "vorbis extradata absent\n");
+        return -1;
+    }
+
+    if(p[0] == 0 && p[1] == 30) {
+        for(i = 0; i < 3; i++){
+            hsizes[i] = bytestream_get_be16((const uint8_t **)&p);
+            headers[i] = p;
+            p += hsizes[i];
+        }
+    } else if(*p == 2) {
+        unsigned int offset = 1;
+        p++;
+        for(i=0; i<2; i++) {
+            hsizes[i] = 0;
+            while((*p == 0xFF) && (offset < avccontext->extradata_size)) {
+                hsizes[i] += 0xFF;
+                offset++;
+                p++;
+            }
+            if(offset >= avccontext->extradata_size - 1) {
+                av_log(avccontext, AV_LOG_ERROR,
+                       "vorbis header sizes damaged\n");
+                return -1;
+            }
+            hsizes[i] += *p;
+            offset++;
+            p++;
+        }
+        hsizes[2] = avccontext->extradata_size - hsizes[0]-hsizes[1]-offset;
+#if 0
+        av_log(avccontext, AV_LOG_DEBUG,
+               "vorbis header sizes: %d, %d, %d, / extradata_len is %d \n",
+               hsizes[0], hsizes[1], hsizes[2], avccontext->extradata_size);
+#endif
+        headers[0] = extradata + offset;
+        headers[1] = extradata + offset + hsizes[0];
+        headers[2] = extradata + offset + hsizes[0] + hsizes[1];
+    } else {
+        av_log(avccontext, AV_LOG_ERROR,
+               "vorbis initial header len is wrong: %d\n", *p);
+        return -1;
+    }
+
+    for(i=0; i<3; i++){
+        context->op.b_o_s= i==0;
+        context->op.bytes = hsizes[i];
+        context->op.packet = headers[i];
+        if(vorbis_synthesis_headerin(&context->vi, &context->vc, &context->op)<0){
+            av_log(avccontext, AV_LOG_ERROR, "%d. vorbis header damaged\n", i+1);
+            return -1;
+        }
+    }
+
+    avccontext->channels = context->vi.channels;
+    avccontext->sample_rate = context->vi.rate;
+    avccontext->time_base= (AVRational){1, avccontext->sample_rate};
+
+    vorbis_synthesis_init(&context->vd, &context->vi);
+    vorbis_block_init(&context->vd, &context->vb);
+
+    return 0 ;
+}
+
+
+static inline int conv(int samples, float **pcm, char *buf, int channels) {
+    int i, j;
+    ogg_int16_t *ptr, *data = (ogg_int16_t*)buf ;
+    float *mono ;
+
+    for(i = 0 ; i < channels ; i++){
+        ptr = &data[i];
+        mono = pcm[i] ;
+
+        for(j = 0 ; j < samples ; j++) {
+            *ptr = av_clip_int16(mono[j] * 32767.f);
+            ptr += channels;
+        }
+    }
+
+    return 0 ;
+}
+
+static int oggvorbis_decode_frame(AVCodecContext *avccontext, void *data,
+                        int *got_frame_ptr, AVPacket *avpkt)
+{
+    OggVorbisDecContext *context = avccontext->priv_data ;
+    float **pcm ;
+    ogg_packet *op= &context->op;
+    int samples, total_samples, total_bytes;
+    int ret;
+    int16_t *output;
+
+    if(!avpkt->size){
+    //FIXME flush
+        return 0;
+    }
+
+    context->frame.nb_samples = 8192*4;
+    if ((ret = avccontext->get_buffer(avccontext, &context->frame)) < 0) {
+        av_log(avccontext, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
+    }
+    output = (int16_t *)context->frame.data[0];
+
+
+    op->packet = avpkt->data;
+    op->bytes  = avpkt->size;
+
+//    av_log(avccontext, AV_LOG_DEBUG, "%d %d %d %"PRId64" %"PRId64" %d %d\n", op->bytes, op->b_o_s, op->e_o_s, op->granulepos, op->packetno, buf_size, context->vi.rate);
+
+/*    for(i=0; i<op->bytes; i++)
+      av_log(avccontext, AV_LOG_DEBUG, "%02X ", op->packet[i]);
+    av_log(avccontext, AV_LOG_DEBUG, "\n");*/
+
+    if(vorbis_synthesis(&context->vb, op) == 0)
+        vorbis_synthesis_blockin(&context->vd, &context->vb) ;
+
+    total_samples = 0 ;
+    total_bytes = 0 ;
+
+    while((samples = vorbis_synthesis_pcmout(&context->vd, &pcm)) > 0) {
+        conv(samples, pcm, (char*)output + total_bytes, context->vi.channels) ;
+        total_bytes += samples * 2 * context->vi.channels ;
+        total_samples += samples ;
+        vorbis_synthesis_read(&context->vd, samples) ;
+    }
+
+    context->frame.nb_samples = total_samples;
+    *got_frame_ptr   = 1;
+    *(AVFrame *)data = context->frame;
+    return avpkt->size;
+}
+
+
+static int oggvorbis_decode_close(AVCodecContext *avccontext) {
+    OggVorbisDecContext *context = avccontext->priv_data ;
+
+    vorbis_info_clear(&context->vi) ;
+    vorbis_comment_clear(&context->vc) ;
+
+    return 0 ;
+}
+
+
+AVCodec ff_libvorbis_decoder = {
+    .name           = "libvorbis",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_VORBIS,
+    .priv_data_size = sizeof(OggVorbisDecContext),
+    .init           = oggvorbis_decode_init,
+    .decode         = oggvorbis_decode_frame,
+    .close          = oggvorbis_decode_close,
+    .capabilities   = CODEC_CAP_DELAY,
+    .long_name      = NULL_IF_CONFIG_SMALL("libvorbis"),
+};
diff --git a/libavcodec/libvorbisenc.c b/libavcodec/libvorbisenc.c
new file mode 100644
index 0000000..6064dd5
--- /dev/null
+++ b/libavcodec/libvorbisenc.c
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2002 Mark Hills <mark@pogo.org.uk>
+ *
+ * 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 <vorbis/vorbisenc.h>
+
+#include "libavutil/avassert.h"
+#include "libavutil/fifo.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "audio_frame_queue.h"
+#include "internal.h"
+#include "vorbis.h"
+#include "vorbis_parser.h"
+
+
+/* Number of samples the user should send in each call.
+ * This value is used because it is the LCD of all possible frame sizes, so
+ * an output packet will always start at the same point as one of the input
+ * packets.
+ */
+#define OGGVORBIS_FRAME_SIZE 64
+
+#define BUFFER_SIZE (1024 * 64)
+
+typedef struct OggVorbisEncContext {
+    AVClass *av_class;                  /**< class for AVOptions            */
+    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 */
+    AVFifoBuffer *pkt_fifo;             /**< output packet buffer           */
+    int eof;                            /**< end-of-file flag               */
+    int dsp_initialized;                /**< vd has been initialized        */
+    vorbis_comment vc;                  /**< VorbisComment info             */
+    double iblock;                      /**< impulse block bias option      */
+    VorbisParseContext vp;              /**< parse context to get durations */
+    AudioFrameQueue afq;                /**< frame queue for timestamps     */
+} OggVorbisEncContext;
+
+static const AVOption options[] = {
+    { "iblock", "Sets the impulse block bias", offsetof(OggVorbisEncContext, iblock), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, -15, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
+    { NULL }
+};
+
+static const AVCodecDefault defaults[] = {
+    { "b",  "0" },
+    { NULL },
+};
+
+static const AVClass class = {
+    .class_name = "libvorbis",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+static int vorbis_error_to_averror(int ov_err)
+{
+    switch (ov_err) {
+    case OV_EFAULT: return AVERROR_BUG;
+    case OV_EINVAL: return AVERROR(EINVAL);
+    case OV_EIMPL:  return AVERROR(EINVAL);
+    default:        return AVERROR_UNKNOWN;
+    }
+}
+
+static av_cold int oggvorbis_init_encoder(vorbis_info *vi,
+                                          AVCodecContext *avctx)
+{
+    OggVorbisEncContext *s = avctx->priv_data;
+    double cfreq;
+    int ret;
+
+    if (avctx->flags & CODEC_FLAG_QSCALE || !avctx->bit_rate) {
+        /* variable bitrate
+         * NOTE: we use the oggenc range of -1 to 10 for global_quality for
+         *       user convenience, but libvorbis uses -0.1 to 1.0.
+         */
+        float q = avctx->global_quality / (float)FF_QP2LAMBDA;
+        /* default to 3 if the user did not set quality or bitrate */
+        if (!(avctx->flags & CODEC_FLAG_QSCALE))
+            q = 3.0;
+        if ((ret = vorbis_encode_setup_vbr(vi, avctx->channels,
+                                           avctx->sample_rate,
+                                           q / 10.0)))
+            goto error;
+    } else {
+        int minrate = avctx->rc_min_rate > 0 ? avctx->rc_min_rate : -1;
+        int maxrate = avctx->rc_max_rate > 0 ? avctx->rc_max_rate : -1;
+
+        /* average bitrate */
+        if ((ret = vorbis_encode_setup_managed(vi, avctx->channels,
+                                               avctx->sample_rate, maxrate,
+                                               avctx->bit_rate, minrate)))
+            goto error;
+
+        /* variable bitrate by estimate, disable slow rate management */
+        if (minrate == -1 && maxrate == -1)
+            if ((ret = vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE2_SET, NULL)))
+                goto error; /* should not happen */
+    }
+
+    /* cutoff frequency */
+    if (avctx->cutoff > 0) {
+        cfreq = avctx->cutoff / 1000.0;
+        if ((ret = vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq)))
+            goto error; /* should not happen */
+    }
+
+    /* impulse block bias */
+    if (s->iblock) {
+        if ((ret = vorbis_encode_ctl(vi, OV_ECTL_IBLOCK_SET, &s->iblock)))
+            goto error;
+    }
+
+    if (avctx->channels == 3 &&
+            avctx->channel_layout != (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER) ||
+        avctx->channels == 4 &&
+            avctx->channel_layout != AV_CH_LAYOUT_2_2 &&
+            avctx->channel_layout != AV_CH_LAYOUT_QUAD ||
+        avctx->channels == 5 &&
+            avctx->channel_layout != AV_CH_LAYOUT_5POINT0 &&
+            avctx->channel_layout != AV_CH_LAYOUT_5POINT0_BACK ||
+        avctx->channels == 6 &&
+            avctx->channel_layout != AV_CH_LAYOUT_5POINT1 &&
+            avctx->channel_layout != AV_CH_LAYOUT_5POINT1_BACK ||
+        avctx->channels == 7 &&
+            avctx->channel_layout != (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER) ||
+        avctx->channels == 8 &&
+            avctx->channel_layout != AV_CH_LAYOUT_7POINT1) {
+        if (avctx->channel_layout) {
+            char name[32];
+            av_get_channel_layout_string(name, sizeof(name), avctx->channels,
+                                         avctx->channel_layout);
+            av_log(avctx, AV_LOG_ERROR, "%s not supported by Vorbis: "
+                                             "output stream will have incorrect "
+                                             "channel layout.\n", name);
+        } else {
+            av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The encoder "
+                                               "will use Vorbis channel layout for "
+                                               "%d channels.\n", avctx->channels);
+        }
+    }
+
+    if ((ret = vorbis_encode_setup_init(vi)))
+        goto error;
+
+    return 0;
+error:
+    return vorbis_error_to_averror(ret);
+}
+
+/* How many bytes are needed for a buffer of length 'l' */
+static int xiph_len(int l)
+{
+    return 1 + l / 255 + l;
+}
+
+static av_cold int oggvorbis_encode_close(AVCodecContext *avctx)
+{
+    OggVorbisEncContext *s = avctx->priv_data;
+
+    /* notify vorbisenc this is EOF */
+    if (s->dsp_initialized)
+        vorbis_analysis_wrote(&s->vd, 0);
+
+    vorbis_block_clear(&s->vb);
+    vorbis_dsp_clear(&s->vd);
+    vorbis_info_clear(&s->vi);
+
+    av_fifo_free(s->pkt_fifo);
+    ff_af_queue_close(&s->afq);
+#if FF_API_OLD_ENCODE_AUDIO
+    av_freep(&avctx->coded_frame);
+#endif
+    av_freep(&avctx->extradata);
+
+    return 0;
+}
+
+static av_cold int oggvorbis_encode_init(AVCodecContext *avctx)
+{
+    OggVorbisEncContext *s = avctx->priv_data;
+    ogg_packet header, header_comm, header_code;
+    uint8_t *p;
+    unsigned int offset;
+    int ret;
+
+    vorbis_info_init(&s->vi);
+    if ((ret = oggvorbis_init_encoder(&s->vi, avctx))) {
+        av_log(avctx, AV_LOG_ERROR, "encoder setup failed\n");
+        goto error;
+    }
+    if ((ret = vorbis_analysis_init(&s->vd, &s->vi))) {
+        av_log(avctx, AV_LOG_ERROR, "analysis init failed\n");
+        ret = vorbis_error_to_averror(ret);
+        goto error;
+    }
+    s->dsp_initialized = 1;
+    if ((ret = vorbis_block_init(&s->vd, &s->vb))) {
+        av_log(avctx, AV_LOG_ERROR, "dsp init failed\n");
+        ret = vorbis_error_to_averror(ret);
+        goto error;
+    }
+
+    vorbis_comment_init(&s->vc);
+    if (!(avctx->flags & CODEC_FLAG_BITEXACT))
+        vorbis_comment_add_tag(&s->vc, "encoder", LIBAVCODEC_IDENT);
+
+    if ((ret = vorbis_analysis_headerout(&s->vd, &s->vc, &header, &header_comm,
+                                         &header_code))) {
+        ret = vorbis_error_to_averror(ret);
+        goto error;
+    }
+
+    avctx->extradata_size = 1 + xiph_len(header.bytes)      +
+                                xiph_len(header_comm.bytes) +
+                                header_code.bytes;
+    p = avctx->extradata = av_malloc(avctx->extradata_size +
+                                     FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!p) {
+        ret = AVERROR(ENOMEM);
+        goto error;
+    }
+    p[0]    = 2;
+    offset  = 1;
+    offset += av_xiphlacing(&p[offset], header.bytes);
+    offset += av_xiphlacing(&p[offset], header_comm.bytes);
+    memcpy(&p[offset], header.packet, header.bytes);
+    offset += header.bytes;
+    memcpy(&p[offset], header_comm.packet, header_comm.bytes);
+    offset += header_comm.bytes;
+    memcpy(&p[offset], header_code.packet, header_code.bytes);
+    offset += header_code.bytes;
+    av_assert0(offset == avctx->extradata_size);
+
+    if ((ret = avpriv_vorbis_parse_extradata(avctx, &s->vp)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "invalid extradata\n");
+        return ret;
+    }
+
+    vorbis_comment_clear(&s->vc);
+
+    avctx->frame_size = OGGVORBIS_FRAME_SIZE;
+    ff_af_queue_init(avctx, &s->afq);
+
+    s->pkt_fifo = av_fifo_alloc(BUFFER_SIZE);
+    if (!s->pkt_fifo) {
+        ret = AVERROR(ENOMEM);
+        goto error;
+    }
+
+#if FF_API_OLD_ENCODE_AUDIO
+    avctx->coded_frame = avcodec_alloc_frame();
+    if (!avctx->coded_frame) {
+        ret = AVERROR(ENOMEM);
+        goto error;
+    }
+#endif
+
+    return 0;
+error:
+    oggvorbis_encode_close(avctx);
+    return ret;
+}
+
+static int oggvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
+                                  const AVFrame *frame, int *got_packet_ptr)
+{
+    OggVorbisEncContext *s = avctx->priv_data;
+    ogg_packet op;
+    int ret, duration;
+
+    /* send samples to libvorbis */
+    if (frame) {
+        const int samples = frame->nb_samples;
+        float **buffer;
+        int c, channels = s->vi.channels;
+
+        buffer = vorbis_analysis_buffer(&s->vd, samples);
+        for (c = 0; c < channels; c++) {
+            int co = (channels > 8) ? c :
+                     ff_vorbis_encoding_channel_layout_offsets[channels - 1][c];
+            memcpy(buffer[c], frame->extended_data[co],
+                   samples * sizeof(*buffer[c]));
+        }
+        if ((ret = vorbis_analysis_wrote(&s->vd, samples)) < 0) {
+            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))
+            return ret;
+    } else {
+        if (!s->eof)
+            if ((ret = vorbis_analysis_wrote(&s->vd, 0)) < 0) {
+                av_log(avctx, AV_LOG_ERROR, "error in vorbis_analysis_wrote()\n");
+                return vorbis_error_to_averror(ret);
+            }
+        s->eof = 1;
+    }
+
+    /* retrieve available packets from libvorbis */
+    while ((ret = vorbis_analysis_blockout(&s->vd, &s->vb)) == 1) {
+        if ((ret = vorbis_analysis(&s->vb, NULL)) < 0)
+            break;
+        if ((ret = vorbis_bitrate_addblock(&s->vb)) < 0)
+            break;
+
+        /* add any available packets to the output packet buffer */
+        while ((ret = vorbis_bitrate_flushpacket(&s->vd, &op)) == 1) {
+            if (av_fifo_space(s->pkt_fifo) < sizeof(ogg_packet) + op.bytes) {
+                av_log(avctx, AV_LOG_ERROR, "packet buffer is too small\n");
+                return AVERROR_BUG;
+            }
+            av_fifo_generic_write(s->pkt_fifo, &op, sizeof(ogg_packet), NULL);
+            av_fifo_generic_write(s->pkt_fifo, op.packet, op.bytes, NULL);
+        }
+        if (ret < 0) {
+            av_log(avctx, AV_LOG_ERROR, "error getting available packets\n");
+            break;
+        }
+    }
+    if (ret < 0) {
+        av_log(avctx, AV_LOG_ERROR, "error getting available packets\n");
+        return vorbis_error_to_averror(ret);
+    }
+
+    /* check for available packets */
+    if (av_fifo_size(s->pkt_fifo) < sizeof(ogg_packet))
+        return 0;
+
+    av_fifo_generic_read(s->pkt_fifo, &op, sizeof(ogg_packet), NULL);
+
+    if ((ret = ff_alloc_packet2(avctx, avpkt, op.bytes)))
+        return ret;
+    av_fifo_generic_read(s->pkt_fifo, avpkt->data, op.bytes, NULL);
+
+    avpkt->pts = ff_samples_to_time_base(avctx, op.granulepos);
+
+    duration = avpriv_vorbis_parse_frame(&s->vp, avpkt->data, avpkt->size);
+    if (duration > 0) {
+        /* we do not know encoder delay until we get the first packet from
+         * libvorbis, so we have to update the AudioFrameQueue counts */
+        if (!avctx->delay) {
+            avctx->delay              = duration;
+            av_assert0(!s->afq.remaining_delay);
+            s->afq.frames->duration  += duration;
+            s->afq.frames->pts       -= duration;
+            s->afq.remaining_samples += duration;
+        }
+        ff_af_queue_remove(&s->afq, duration, &avpkt->pts, &avpkt->duration);
+    }
+
+    *got_packet_ptr = 1;
+    return 0;
+}
+
+AVCodec ff_libvorbis_encoder = {
+    .name           = "libvorbis",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_VORBIS,
+    .priv_data_size = sizeof(OggVorbisEncContext),
+    .init           = oggvorbis_encode_init,
+    .encode2        = oggvorbis_encode_frame,
+    .close          = oggvorbis_encode_close,
+    .capabilities   = CODEC_CAP_DELAY,
+    .sample_fmts    = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
+                                                      AV_SAMPLE_FMT_NONE },
+    .long_name      = NULL_IF_CONFIG_SMALL("libvorbis"),
+    .priv_class     = &class,
+    .defaults       = defaults,
+};
diff --git a/libavcodec/libvpxdec.c b/libavcodec/libvpxdec.c
index 56f706e..61dbaa7 100644
--- a/libavcodec/libvpxdec.c
+++ b/libavcodec/libvpxdec.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010, Google, Inc.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index f505d0e..aecff79 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010, Google, Inc.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,6 +30,7 @@
 
 #include "avcodec.h"
 #include "internal.h"
+#include "libavutil/avassert.h"
 #include "libavutil/base64.h"
 #include "libavutil/common.h"
 #include "libavutil/mathematics.h"
@@ -55,15 +56,27 @@
     struct vpx_codec_ctx encoder;
     struct vpx_image rawimg;
     struct vpx_fixed_buf twopass_stats;
-    unsigned long deadline; //i.e., RT/GOOD/BEST
+    int deadline; //i.e., RT/GOOD/BEST
     struct FrameListData *coded_frame_list;
+
     int cpu_used;
+    /**
+     * VP8 specific flags, see VP8F_* below.
+     */
+    int flags;
+#define VP8F_ERROR_RESILIENT 0x00000001 ///< Enable measures appropriate for streaming over lossy links
+#define VP8F_AUTO_ALT_REF    0x00000002 ///< Enable automatic alternate reference frame generation
+
     int auto_alt_ref;
+
     int arnr_max_frames;
     int arnr_strength;
     int arnr_type;
+
     int lag_in_frames;
     int error_resilient;
+    int crf;
+    int max_intra_rate;
 } VP8Context;
 
 /** String mappings for enum vp8e_enc_control_id */
@@ -84,6 +97,8 @@
     [VP8E_SET_ARNR_MAXFRAMES]    = "VP8E_SET_ARNR_MAXFRAMES",
     [VP8E_SET_ARNR_STRENGTH]     = "VP8E_SET_ARNR_STRENGTH",
     [VP8E_SET_ARNR_TYPE]         = "VP8E_SET_ARNR_TYPE",
+    [VP8E_SET_CQ_LEVEL]          = "VP8E_SET_CQ_LEVEL",
+    [VP8E_SET_MAX_INTRA_BITRATE_PCT] = "VP8E_SET_MAX_INTRA_BITRATE_PCT",
 };
 
 static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc)
@@ -227,6 +242,13 @@
                vpx_codec_err_to_string(res));
         return AVERROR(EINVAL);
     }
+
+    if(!avctx->bit_rate)
+        if(avctx->rc_max_rate || avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) {
+            av_log( avctx, AV_LOG_ERROR, "Rate control parameters set without a bitrate\n");
+            return AVERROR(EINVAL);
+        }
+
     dump_enc_cfg(avctx, &enccfg);
 
     enccfg.g_w            = avctx->width;
@@ -234,9 +256,7 @@
     enccfg.g_timebase.num = avctx->time_base.num;
     enccfg.g_timebase.den = avctx->time_base.den;
     enccfg.g_threads      = avctx->thread_count;
-
-    if (ctx->lag_in_frames >= 0)
-        enccfg.g_lag_in_frames = ctx->lag_in_frames;
+    enccfg.g_lag_in_frames= ctx->lag_in_frames;
 
     if (avctx->flags & CODEC_FLAG_PASS1)
         enccfg.g_pass = VPX_RC_FIRST_PASS;
@@ -245,15 +265,25 @@
     else
         enccfg.g_pass = VPX_RC_ONE_PASS;
 
-    if (!avctx->bit_rate)
-        avctx->bit_rate = enccfg.rc_target_bitrate * 1000;
-    else
-        enccfg.rc_target_bitrate = av_rescale_rnd(avctx->bit_rate, 1, 1000,
-                                              AV_ROUND_NEAR_INF);
-
     if (avctx->rc_min_rate == avctx->rc_max_rate &&
-        avctx->rc_min_rate == avctx->bit_rate)
+        avctx->rc_min_rate == avctx->bit_rate && avctx->bit_rate)
         enccfg.rc_end_usage = VPX_CBR;
+    else if (ctx->crf)
+        enccfg.rc_end_usage = VPX_CQ;
+
+    if (avctx->bit_rate) {
+        enccfg.rc_target_bitrate = av_rescale_rnd(avctx->bit_rate, 1, 1000,
+                                                AV_ROUND_NEAR_INF);
+    } else {
+        if (enccfg.rc_end_usage == VPX_CQ) {
+            enccfg.rc_target_bitrate = 1000000;
+        } else {
+            avctx->bit_rate = enccfg.rc_target_bitrate * 1000;
+            av_log(avctx, AV_LOG_WARNING,
+                   "Neither bitrate nor constrained quality specified, using default bitrate of %dkbit/sec\n",
+                   enccfg.rc_target_bitrate);
+        }
+    }
 
     if (avctx->qmin > 0)
         enccfg.rc_min_quantizer = avctx->qmin;
@@ -263,8 +293,9 @@
 
     //0-100 (0 => CBR, 100 => VBR)
     enccfg.rc_2pass_vbr_bias_pct           = round(avctx->qcompress * 100);
-    enccfg.rc_2pass_vbr_minsection_pct     =
-        avctx->rc_min_rate * 100LL / avctx->bit_rate;
+    if (avctx->bit_rate)
+        enccfg.rc_2pass_vbr_minsection_pct     =
+            avctx->rc_min_rate * 100LL / avctx->bit_rate;
     if (avctx->rc_max_rate)
         enccfg.rc_2pass_vbr_maxsection_pct =
             avctx->rc_max_rate * 100LL / avctx->bit_rate;
@@ -276,6 +307,7 @@
         enccfg.rc_buf_initial_sz =
             avctx->rc_initial_buffer_occupancy * 1000LL / avctx->bit_rate;
     enccfg.rc_buf_optimal_sz     = enccfg.rc_buf_sz * 5 / 6;
+    enccfg.rc_undershoot_pct     = round(avctx->rc_buffer_aggressivity * 100);
 
     //_enc_init() will balk if kf_min_dist differs from max w/VPX_KF_AUTO
     if (avctx->keyint_min >= 0 && avctx->keyint_min == avctx->gop_size)
@@ -318,7 +350,7 @@
    if (avctx->profile != FF_PROFILE_UNKNOWN)
        enccfg.g_profile = avctx->profile;
 
-    enccfg.g_error_resilient = ctx->error_resilient;
+    enccfg.g_error_resilient = ctx->error_resilient || ctx->flags & VP8F_ERROR_RESILIENT;
 
     dump_enc_cfg(avctx, &enccfg);
     /* Construct Encoder Context */
@@ -332,6 +364,8 @@
     av_log(avctx, AV_LOG_DEBUG, "vpx_codec_control\n");
     if (ctx->cpu_used != INT_MIN)
         codecctl_int(avctx, VP8E_SET_CPUUSED,          ctx->cpu_used);
+    if (ctx->flags & VP8F_AUTO_ALT_REF)
+        ctx->auto_alt_ref = 1;
     if (ctx->auto_alt_ref >= 0)
         codecctl_int(avctx, VP8E_SET_ENABLEAUTOALTREF, ctx->auto_alt_ref);
     if (ctx->arnr_max_frames >= 0)
@@ -343,6 +377,11 @@
     codecctl_int(avctx, VP8E_SET_NOISE_SENSITIVITY, avctx->noise_reduction);
     codecctl_int(avctx, VP8E_SET_TOKEN_PARTITIONS,  av_log2(avctx->slices));
     codecctl_int(avctx, VP8E_SET_STATIC_THRESHOLD,  avctx->mb_threshold);
+    codecctl_int(avctx, VP8E_SET_CQ_LEVEL,          ctx->crf);
+    if (ctx->max_intra_rate >= 0)
+        codecctl_int(avctx, VP8E_SET_MAX_INTRA_BITRATE_PCT, ctx->max_intra_rate);
+
+    av_log(avctx, AV_LOG_DEBUG, "Using deadline: %d\n", ctx->deadline);
 
     //provide dummy value to initialize wrapper, values will be updated each _encode()
     vpx_img_wrap(&ctx->rawimg, VPX_IMG_FMT_I420, avctx->width, avctx->height, 1,
@@ -377,7 +416,7 @@
 static int storeframe(AVCodecContext *avctx, struct FrameListData *cx_frame,
                       AVPacket *pkt, AVFrame *coded_frame)
 {
-    int ret = ff_alloc_packet(pkt, cx_frame->sz);
+    int ret = ff_alloc_packet2(avctx, pkt, cx_frame->sz);
     if (ret >= 0) {
         memcpy(pkt->data, cx_frame->buf, pkt->size);
         pkt->pts = pkt->dts    = cx_frame->pts;
@@ -390,8 +429,6 @@
         } else
             coded_frame->pict_type = AV_PICTURE_TYPE_P;
     } else {
-        av_log(avctx, AV_LOG_ERROR,
-               "Error getting output packet of size %zu.\n", cx_frame->sz);
         return ret;
     }
     return pkt->size;
@@ -433,7 +470,7 @@
 
                 /* avoid storing the frame when the list is empty and we haven't yet
                    provided a frame for output */
-                assert(!ctx->coded_frame_list);
+                av_assert0(!ctx->coded_frame_list);
                 cx_pktcpy(&cx_frame, pkt);
                 size = storeframe(avctx, &cx_frame, pkt_out, coded_frame);
                 if (size < 0)
@@ -454,6 +491,7 @@
                     av_log(avctx, AV_LOG_ERROR,
                            "Data buffer alloc (%zu bytes) failed\n",
                            cx_frame->sz);
+                    av_free(cx_frame);
                     return AVERROR(ENOMEM);
                 }
                 memcpy(cx_frame->buf, pkt->data.frame.buf, pkt->data.frame.sz);
@@ -462,8 +500,8 @@
             break;
         case VPX_CODEC_STATS_PKT: {
             struct vpx_fixed_buf *stats = &ctx->twopass_stats;
-            stats->buf = av_realloc(stats->buf,
-                                    stats->sz + pkt->data.twopass_stats.sz);
+            stats->buf = av_realloc_f(stats->buf, 1,
+                                      stats->sz + pkt->data.twopass_stats.sz);
             if (!stats->buf) {
                 av_log(avctx, AV_LOG_ERROR, "Stat buffer realloc failed\n");
                 return AVERROR(ENOMEM);
@@ -489,6 +527,7 @@
     VP8Context *ctx = avctx->priv_data;
     struct vpx_image *rawimg = NULL;
     int64_t timestamp = 0;
+    long flags = 0;
     int res, coded_size;
 
     if (frame) {
@@ -500,10 +539,11 @@
         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;
     }
 
     res = vpx_codec_encode(&ctx->encoder, rawimg, timestamp,
-                           avctx->ticks_per_frame, 0, ctx->deadline);
+                           avctx->ticks_per_frame, flags, ctx->deadline);
     if (res != VPX_CODEC_OK) {
         log_encoder_error(avctx, "Error encoding frame");
         return AVERROR_INVALIDDATA;
@@ -546,6 +586,7 @@
     { "good",            NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_GOOD_QUALITY}, 0, 0, VE, "quality"},
     { "realtime",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = VPX_DL_REALTIME},     0, 0, VE, "quality"},
     { "error-resilient", "Error resilience configuration", OFFSET(error_resilient), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, VE, "er"},
+    { "max-intra-rate",  "Maximum I-frame bitrate (pct) 0=unlimited",  OFFSET(max_intra_rate),  AV_OPT_TYPE_INT,  {.i64 = -1}, -1,      INT_MAX, VE},
 #ifdef VPX_ERROR_RESILIENT_DEFAULT
     { "default",         "Improve resiliency against losses of whole frames", 0, AV_OPT_TYPE_CONST, {.i64 = VPX_ERROR_RESILIENT_DEFAULT}, 0, 0, VE, "er"},
     { "partitions",      "The frame partitions are independently decodable "
@@ -553,7 +594,17 @@
                          "though earlier partitions have been lost. Note that intra predicition"
                          " is still done over the partition boundary.",       0, AV_OPT_TYPE_CONST, {.i64 = VPX_ERROR_RESILIENT_PARTITIONS}, 0, 0, VE, "er"},
 #endif
-    { NULL }
+{"speed", "", offsetof(VP8Context, cpu_used), AV_OPT_TYPE_INT, {.i64 = 3}, -16, 16, VE},
+{"quality", "", offsetof(VP8Context, deadline), AV_OPT_TYPE_INT, {.i64 = VPX_DL_GOOD_QUALITY}, INT_MIN, INT_MAX, VE, "quality"},
+{"vp8flags", "", offsetof(VP8Context, flags), FF_OPT_TYPE_FLAGS, {.i64 = 0}, 0, UINT_MAX, VE, "flags"},
+{"error_resilient", "enable error resilience", 0, FF_OPT_TYPE_CONST, {.dbl = VP8F_ERROR_RESILIENT}, INT_MIN, INT_MAX, VE, "flags"},
+{"altref", "enable use of alternate reference frames (VP8/2-pass only)", 0, FF_OPT_TYPE_CONST, {.dbl = VP8F_AUTO_ALT_REF}, INT_MIN, INT_MAX, VE, "flags"},
+{"arnr_max_frames", "altref noise reduction max frame count", offsetof(VP8Context, arnr_max_frames), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 15, VE},
+{"arnr_strength", "altref noise reduction filter strength", offsetof(VP8Context, arnr_strength), AV_OPT_TYPE_INT, {.i64 = 3}, 0, 6, VE},
+{"arnr_type", "altref noise reduction filter type", offsetof(VP8Context, arnr_type), AV_OPT_TYPE_INT, {.i64 = 3}, 1, 3, VE},
+{"rc_lookahead", "Number of frames to look ahead for alternate reference frame selection", offsetof(VP8Context, lag_in_frames), AV_OPT_TYPE_INT, {.i64 = 25}, 0, 25, VE},
+{"crf", "Select the quality for constant quality mode", offsetof(VP8Context, crf), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 63, VE},
+{NULL}
 };
 
 static const AVClass class = {
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index f536f7f..8765e56 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -2,20 +2,20 @@
  * H.264 encoding using the x264 library
  * Copyright (C) 2005  Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -43,7 +43,10 @@
     char *preset;
     char *tune;
     char *profile;
+    char *level;
     int fastfirstpass;
+    char *wpredp;
+    char *x264opts;
     float crf;
     float crf_max;
     int cqp;
@@ -101,16 +104,21 @@
     for (i = 0; i < nnal; i++)
         size += nals[i].i_payload;
 
-    if ((ret = ff_alloc_packet(pkt, size)) < 0)
+    if ((ret = ff_alloc_packet2(ctx, pkt, size)) < 0)
         return ret;
 
     p = pkt->data;
 
     /* Write the SEI as part of the first frame. */
     if (x4->sei_size > 0 && nnal > 0) {
+        if (x4->sei_size > size) {
+            av_log(ctx, AV_LOG_ERROR, "Error: nal buffer is too small\n");
+            return -1;
+        }
         memcpy(p, x4->sei, x4->sei_size);
         p += x4->sei_size;
         x4->sei_size = 0;
+        av_freep(&x4->sei);
     }
 
     for (i = 0; i < nnal; i++){
@@ -121,6 +129,25 @@
     return 1;
 }
 
+static int avfmt2_num_planes(int avfmt)
+{
+    switch (avfmt) {
+    case AV_PIX_FMT_YUV420P:
+    case AV_PIX_FMT_YUVJ420P:
+    case AV_PIX_FMT_YUV420P9:
+    case AV_PIX_FMT_YUV420P10:
+    case AV_PIX_FMT_YUV444P:
+        return 3;
+
+    case AV_PIX_FMT_BGR24:
+    case AV_PIX_FMT_RGB24:
+        return 1;
+
+    default:
+        return 3;
+    }
+}
+
 static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,
                       int *got_packet)
 {
@@ -133,10 +160,10 @@
     x4->pic.img.i_csp   = x4->params.i_csp;
     if (x264_bit_depth > 8)
         x4->pic.img.i_csp |= X264_CSP_HIGH_DEPTH;
-    x4->pic.img.i_plane = 3;
+    x4->pic.img.i_plane = avfmt2_num_planes(ctx->pix_fmt);
 
     if (frame) {
-        for (i = 0; i < 3; i++) {
+        for (i = 0; i < x4->pic.img.i_plane; i++) {
             x4->pic.img.plane[i]    = frame->data[i];
             x4->pic.img.i_stride[i] = frame->linesize[i];
         }
@@ -206,6 +233,20 @@
     return 0;
 }
 
+#define OPT_STR(opt, param)                                                   \
+    do {                                                                      \
+        int ret;                                                              \
+        if (param && (ret = x264_param_parse(&x4->params, opt, param)) < 0) { \
+            if(ret == X264_PARAM_BAD_NAME)                                    \
+                av_log(avctx, AV_LOG_ERROR,                                   \
+                        "bad option '%s': '%s'\n", opt, param);               \
+            else                                                              \
+                av_log(avctx, AV_LOG_ERROR,                                   \
+                        "bad value for '%s': '%s'\n", opt, param);            \
+            return -1;                                                        \
+        }                                                                     \
+    } while (0)
+
 static int convert_pix_fmt(enum AVPixelFormat pix_fmt)
 {
     switch (pix_fmt) {
@@ -218,6 +259,13 @@
     case AV_PIX_FMT_YUV444P:
     case AV_PIX_FMT_YUV444P9:
     case AV_PIX_FMT_YUV444P10: return X264_CSP_I444;
+#ifdef X264_CSP_BGR
+    case AV_PIX_FMT_BGR24:
+        return X264_CSP_BGR;
+
+    case AV_PIX_FMT_RGB24:
+        return X264_CSP_RGB;
+#endif
     };
     return 0;
 }
@@ -231,14 +279,27 @@
 static av_cold int X264_init(AVCodecContext *avctx)
 {
     X264Context *x4 = avctx->priv_data;
+    int sw,sh;
 
     x264_param_default(&x4->params);
 
     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)
         if (x264_param_default_preset(&x4->params, x4->preset, x4->tune) < 0) {
+            int i;
             av_log(avctx, AV_LOG_ERROR, "Error setting preset/tune %s/%s.\n", x4->preset, x4->tune);
+            av_log(avctx, AV_LOG_INFO, "Possible presets:");
+            for (i = 0; x264_preset_names[i]; i++)
+                av_log(avctx, AV_LOG_INFO, " %s", x264_preset_names[i]);
+            av_log(avctx, AV_LOG_INFO, "\n");
+            av_log(avctx, AV_LOG_INFO, "Possible tunes:");
+            for (i = 0; x264_tune_names[i]; i++)
+                av_log(avctx, AV_LOG_INFO, " %s", x264_tune_names[i]);
+            av_log(avctx, AV_LOG_INFO, "\n");
             return AVERROR(EINVAL);
         }
 
@@ -250,6 +311,8 @@
     x4->params.i_log_level          = X264_LOG_DEBUG;
     x4->params.i_csp                = convert_pix_fmt(avctx->pix_fmt);
 
+    OPT_STR("weightp", x4->wpredp);
+
     if (avctx->bit_rate) {
         x4->params.rc.i_bitrate   = avctx->bit_rate / 1000;
         x4->params.rc.i_rc_method = X264_RC_ABR;
@@ -278,9 +341,20 @@
             (float)avctx->rc_initial_buffer_occupancy / avctx->rc_buffer_size;
     }
 
-    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;
+    OPT_STR("level", x4->level);
+
+    if(x4->x264opts){
+        const char *p= x4->x264opts;
+        while(p){
+            char param[256]={0}, val[256]={0};
+            if(sscanf(p, "%255[^:=]=%255[^:]", param, val) == 1){
+                OPT_STR(param, "1");
+            }else
+                OPT_STR(param, val);
+            p= strchr(p, ':');
+            p+=!!p;
+        }
+    }
 
     if (avctx->me_method == ME_EPZS)
         x4->params.analyse.i_me_method = X264_ME_DIA;
@@ -370,23 +444,64 @@
 
     if (x4->slice_max_size >= 0)
         x4->params.i_slice_max_size =  x4->slice_max_size;
+    else {
+        /*
+         * Allow x264 to be instructed through AVCodecContext about the maximum
+         * size of the RTP payload. For example, this enables the production of
+         * payload suitable for the H.264 RTP packetization-mode 0 i.e. single
+         * NAL unit per RTP packet.
+         */
+        if (avctx->rtp_payload_size)
+            x4->params.i_slice_max_size = avctx->rtp_payload_size;
+    }
 
     if (x4->fastfirstpass)
         x264_param_apply_fastfirstpass(&x4->params);
 
+    /* Allow specifying the x264 profile through AVCodecContext. */
+    if (!x4->profile)
+        switch (avctx->profile) {
+        case FF_PROFILE_H264_BASELINE:
+            x4->profile = av_strdup("baseline");
+            break;
+        case FF_PROFILE_H264_HIGH:
+            x4->profile = av_strdup("high");
+            break;
+        case FF_PROFILE_H264_HIGH_10:
+            x4->profile = av_strdup("high10");
+            break;
+        case FF_PROFILE_H264_HIGH_422:
+            x4->profile = av_strdup("high422");
+            break;
+        case FF_PROFILE_H264_HIGH_444:
+            x4->profile = av_strdup("high444");
+            break;
+        case FF_PROFILE_H264_MAIN:
+            x4->profile = av_strdup("main");
+            break;
+        default:
+            break;
+        }
+
     if (x4->nal_hrd >= 0)
         x4->params.i_nal_hrd = x4->nal_hrd;
 
     if (x4->profile)
         if (x264_param_apply_profile(&x4->params, x4->profile) < 0) {
+            int i;
             av_log(avctx, AV_LOG_ERROR, "Error setting profile %s.\n", x4->profile);
+            av_log(avctx, AV_LOG_INFO, "Possible profiles:");
+            for (i = 0; x264_profile_names[i]; i++)
+                av_log(avctx, AV_LOG_INFO, " %s", x264_profile_names[i]);
+            av_log(avctx, AV_LOG_INFO, "\n");
             return AVERROR(EINVAL);
         }
 
     x4->params.i_width          = avctx->width;
     x4->params.i_height         = avctx->height;
-    x4->params.vui.i_sar_width  = avctx->sample_aspect_ratio.num;
-    x4->params.vui.i_sar_height = avctx->sample_aspect_ratio.den;
+    av_reduce(&sw, &sh, avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den, 4096);
+    x4->params.vui.i_sar_width  = sw;
+    x4->params.vui.i_sar_height = sh;
     x4->params.i_fps_num = x4->params.i_timebase_den = avctx->time_base.den;
     x4->params.i_fps_den = x4->params.i_timebase_num = avctx->time_base.num;
 
@@ -465,6 +580,13 @@
     AV_PIX_FMT_YUV444P10,
     AV_PIX_FMT_NONE
 };
+static const enum AVPixelFormat pix_fmts_8bit_rgb[] = {
+#ifdef X264_CSP_BGR
+    AV_PIX_FMT_BGR24,
+    AV_PIX_FMT_RGB24,
+#endif
+    AV_PIX_FMT_NONE
+};
 
 static av_cold void X264_init_static(AVCodec *codec)
 {
@@ -483,6 +605,10 @@
     { "tune",          "Tune the encoding params (cf. x264 --fullhelp)",  OFFSET(tune),          AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},
     { "profile",       "Set profile restrictions (cf. x264 --fullhelp) ", OFFSET(profile),       AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE},
     { "fastfirstpass", "Use fast settings when encoding first pass",      OFFSET(fastfirstpass), AV_OPT_TYPE_INT,    { .i64 = 1 }, 0, 1, VE},
+    {"level", "Specify level (as defined by Annex A)", OFFSET(level), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE},
+    {"passlogfile", "Filename for 2 pass stats", OFFSET(stats), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE},
+    {"wpredp", "Weighted prediction for P-frames", OFFSET(wpredp), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE},
+    {"x264opts", "x264 options", OFFSET(x264opts), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, VE},
     { "crf",           "Select the quality for constant quality mode",    OFFSET(crf),           AV_OPT_TYPE_FLOAT,  {.dbl = -1 }, -1, FLT_MAX, VE },
     { "crf_max",       "In CRF mode, prevents VBV from lowering quality beyond this point.",OFFSET(crf_max), AV_OPT_TYPE_FLOAT, {.dbl = -1 }, -1, FLT_MAX, VE },
     { "qp",            "Constant quantization parameter rate control method",OFFSET(cqp),        AV_OPT_TYPE_INT,    { .i64 = -1 }, -1, INT_MAX, VE },
@@ -537,15 +663,24 @@
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
+static const AVClass rgbclass = {
+    .class_name = "libx264rgb",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const AVCodecDefault x264_defaults[] = {
     { "b",                "0" },
     { "bf",               "-1" },
+    { "flags2",           "0" },
     { "g",                "-1" },
     { "qmin",             "-1" },
     { "qmax",             "-1" },
     { "qdiff",            "-1" },
     { "qblur",            "-1" },
     { "qcomp",            "-1" },
+//     { "rc_lookahead",     "-1" },
     { "refs",             "-1" },
     { "sc_threshold",     "-1" },
     { "trellis",          "-1" },
@@ -577,3 +712,18 @@
     .defaults         = x264_defaults,
     .init_static_data = X264_init_static,
 };
+
+AVCodec ff_libx264rgb_encoder = {
+    .name           = "libx264rgb",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_H264,
+    .priv_data_size = sizeof(X264Context),
+    .init           = X264_init,
+    .encode2        = X264_frame,
+    .close          = X264_close,
+    .capabilities   = CODEC_CAP_DELAY,
+    .long_name      = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 RGB"),
+    .priv_class     = &rgbclass,
+    .defaults       = x264_defaults,
+    .pix_fmts       = pix_fmts_8bit_rgb,
+};
diff --git a/libavcodec/libxavs.c b/libavcodec/libxavs.c
index 16026ac..442fc0ee 100644
--- a/libavcodec/libxavs.c
+++ b/libavcodec/libxavs.c
@@ -2,20 +2,20 @@
  * AVS encoding using the xavs library
  * Copyright (C) 2010 Amanda, Y.N. Wu <amanda11192003@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -89,10 +89,8 @@
     for (i = 0; i < nnal; i++)
         size += nals[i].i_payload;
 
-    if ((ret = ff_alloc_packet(pkt, size)) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n", size);
+    if ((ret = ff_alloc_packet2(ctx, pkt, size)) < 0)
         return ret;
-    }
     p = pkt->data;
 
     /* Write the SEI as part of the first frame. */
@@ -146,7 +144,7 @@
 
     if (!ret) {
         if (!frame && !(x4->end_of_stream)) {
-            if ((ret = ff_alloc_packet(pkt, 4)) < 0)
+            if ((ret = ff_alloc_packet2(ctx, pkt, 4)) < 0)
                 return ret;
 
             pkt->data[0] = 0x0;
@@ -390,10 +388,10 @@
 #define OFFSET(x) offsetof(XavsContext, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-    { "crf",           "Select the quality for constant quality mode",    OFFSET(crf),           AV_OPT_TYPE_FLOAT,  {-1 }, -1, FLT_MAX, VE },
+    { "crf",           "Select the quality for constant quality mode",    OFFSET(crf),           AV_OPT_TYPE_FLOAT,  {.dbl = -1 }, -1, FLT_MAX, VE },
     { "qp",            "Constant quantization parameter rate control method",OFFSET(cqp),        AV_OPT_TYPE_INT,    {.i64 = -1 }, -1, INT_MAX, VE },
     { "b-bias",        "Influences how often B-frames are used",          OFFSET(b_bias),        AV_OPT_TYPE_INT,    {.i64 = INT_MIN}, INT_MIN, INT_MAX, VE },
-    { "cplxblur",      "Reduce fluctuations in QP (before curve compression)", OFFSET(cplxblur), AV_OPT_TYPE_FLOAT,  {-1 }, -1, FLT_MAX, VE},
+    { "cplxblur",      "Reduce fluctuations in QP (before curve compression)", OFFSET(cplxblur), AV_OPT_TYPE_FLOAT,  {.dbl = -1 }, -1, FLT_MAX, VE},
     { "direct-pred",   "Direct MV prediction mode",                       OFFSET(direct_pred),   AV_OPT_TYPE_INT,    {.i64 = -1 }, -1, INT_MAX, VE, "direct-pred" },
     { "none",          NULL,      0,    AV_OPT_TYPE_CONST, { .i64 = XAVS_DIRECT_PRED_NONE },     0, 0, VE, "direct-pred" },
     { "spatial",       NULL,      0,    AV_OPT_TYPE_CONST, { .i64 = XAVS_DIRECT_PRED_SPATIAL },  0, 0, VE, "direct-pred" },
diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c
index 89021e7..fa3be7c 100644
--- a/libavcodec/libxvid.c
+++ b/libavcodec/libxvid.c
@@ -2,20 +2,20 @@
  * Interface to xvidcore for mpeg4 encoding
  * Copyright (c) 2004 Adam Thayer <krevnik@comcast.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -28,6 +28,8 @@
 #include <xvid.h>
 #include <unistd.h>
 #include "avcodec.h"
+#include "internal.h"
+#include "libavutil/file.h"
 #include "libavutil/cpu.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
@@ -100,7 +102,7 @@
     /* This is because we can safely prevent a buffer overflow */
     log[0] = 0;
     snprintf(log, BUFFER_REMAINING(log),
-        "# avconv 2-pass log file, using xvid codec\n");
+        "# ffmpeg 2-pass log file, using xvid codec\n");
     snprintf(BUFFER_CAT(log), BUFFER_REMAINING(log),
         "# Do not modify. libxvidcore version: %d.%d.%d\n\n",
         XVID_VERSION_MAJOR(XVID_VERSION),
@@ -362,7 +364,7 @@
     xvid_enc_create_t xvid_enc_create = { 0 };
     xvid_enc_plugin_t plugins[7];
 
-    /* Bring in VOP flags from avconv command-line */
+    /* Bring in VOP flags from ffmpeg command-line */
     x->vop_flags = XVID_VOP_HALFPEL; /* Bare minimum quality */
     if( xvid_flags & CODEC_FLAG_4MV )
         x->vop_flags |= XVID_VOP_INTER4V; /* Level 3 */
@@ -416,7 +418,7 @@
            break;
     }
 
-    /* Bring in VOL flags from avconv command-line */
+    /* Bring in VOL flags from ffmpeg command-line */
     x->vol_flags = 0;
     if( xvid_flags & CODEC_FLAG_GMC ) {
         x->vol_flags |= XVID_VOL_GMC;
@@ -491,7 +493,7 @@
         rc2pass2.version = XVID_VERSION;
         rc2pass2.bitrate = avctx->bit_rate;
 
-        fd = ff_tempfile("xvidff.", &x->twopassfile);
+        fd = av_tempfile("xvidff.", &x->twopassfile, 0, avctx);
         if( fd == -1 ) {
             av_log(avctx, AV_LOG_ERROR,
                 "Xvid: Cannot write 2-pass pipe\n");
@@ -641,11 +643,8 @@
     xvid_enc_frame_t xvid_enc_frame = { 0 };
     xvid_enc_stats_t xvid_enc_stats = { 0 };
 
-    if (!user_packet &&
-        (ret = av_new_packet(pkt, mb_width*mb_height*MAX_MB_BYTES + FF_MIN_BUFFER_SIZE)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, mb_width*mb_height*MAX_MB_BYTES + FF_MIN_BUFFER_SIZE)) < 0)
         return ret;
-    }
 
     /* Start setting up the frame */
     xvid_enc_frame.version = XVID_VERSION;
@@ -680,8 +679,8 @@
                                           XVID_TYPE_AUTO;
 
     /* Pixel aspect ratio setting */
-    if (avctx->sample_aspect_ratio.num < 1 || avctx->sample_aspect_ratio.num > 255 ||
-        avctx->sample_aspect_ratio.den < 1 || avctx->sample_aspect_ratio.den > 255) {
+    if (avctx->sample_aspect_ratio.num < 0 || avctx->sample_aspect_ratio.num > 255 ||
+        avctx->sample_aspect_ratio.den < 0 || avctx->sample_aspect_ratio.den > 255) {
         av_log(avctx, AV_LOG_ERROR, "Invalid pixel aspect ratio %i/%i\n",
                avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den);
         return -1;
@@ -764,6 +763,7 @@
     if( x->twopassbuffer != NULL ) {
         av_free(x->twopassbuffer);
         av_free(x->old_twopassbuffer);
+        avctx->stats_out = NULL;
     }
     av_free(x->twopassfile);
     av_free(x->intra_matrix);
diff --git a/libavcodec/libxvid.h b/libavcodec/libxvid.h
index 413d353..90ecd6f 100644
--- a/libavcodec/libxvid.h
+++ b/libavcodec/libxvid.h
@@ -1,20 +1,20 @@
 /*
  * copyright (C) 2006 Corey Hickey
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/libxvid_rc.c b/libavcodec/libxvid_rc.c
index bf9f6f0..93aeb71 100644
--- a/libavcodec/libxvid_rc.c
+++ b/libavcodec/libxvid_rc.c
@@ -3,30 +3,27 @@
  *
  * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "config.h"
 #include <xvid.h>
 #include <unistd.h>
-#if !HAVE_MKSTEMP
-#include <fcntl.h>
-#endif
-
+#include "libavutil/file.h"
 #include "avcodec.h"
 #include "libxvid.h"
 //#include "dsputil.h"
@@ -35,49 +32,13 @@
 #undef NDEBUG
 #include <assert.h>
 
-/* Wrapper to work around the lack of mkstemp() on mingw.
- * Also, tries to create file in /tmp first, if possible.
- * *prefix can be a character constant; *filename will be allocated internally.
- * @return file descriptor of opened file (or -1 on error)
- * and opened file name in **filename. */
-int ff_tempfile(const char *prefix, char **filename) {
-    int fd=-1;
-#if !HAVE_MKSTEMP
-    *filename = tempnam(".", prefix);
-#else
-    size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */
-    *filename = av_malloc(len);
-#endif
-    /* -----common section-----*/
-    if (*filename == NULL) {
-        av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n");
-        return -1;
-    }
-#if !HAVE_MKSTEMP
-    fd = open(*filename, O_RDWR | O_BINARY | O_CREAT, 0444);
-#else
-    snprintf(*filename, len, "/tmp/%sXXXXXX", prefix);
-    fd = mkstemp(*filename);
-    if (fd < 0) {
-        snprintf(*filename, len, "./%sXXXXXX", prefix);
-        fd = mkstemp(*filename);
-    }
-#endif
-    /* -----common section-----*/
-    if (fd < 0) {
-        av_log(NULL, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename);
-        return -1;
-    }
-    return fd; /* success */
-}
-
 int ff_xvid_rate_control_init(MpegEncContext *s){
     char *tmp_name;
     int fd, i;
     xvid_plg_create_t xvid_plg_create = { 0 };
     xvid_plugin_2pass2_t xvid_2pass2  = { 0 };
 
-    fd=ff_tempfile("xvidrc.", &tmp_name);
+    fd=av_tempfile("xvidrc.", &tmp_name, 0, s->avctx);
     if (fd == -1) {
         av_log(NULL, AV_LOG_ERROR, "Can't create temporary pass2 file.\n");
         return -1;
@@ -94,7 +55,12 @@
             frame_types[rce->pict_type], (int)lrintf(rce->qscale / FF_QP2LAMBDA), rce->i_count, s->mb_num - rce->i_count - rce->skip_count,
             rce->skip_count, (rce->i_tex_bits + rce->p_tex_bits + rce->misc_bits+7)/8, (rce->header_bits+rce->mv_bits+7)/8);
 
-        write(fd, tmp, strlen(tmp));
+        if (write(fd, tmp, strlen(tmp)) < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Error %s writing 2pass logfile\n", strerror(errno));
+            av_free(tmp_name);
+            close(fd);
+            return AVERROR(errno);
+        }
     }
 
     close(fd);
diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c
index 78ba2c9..d3c2921 100644
--- a/libavcodec/ljpegenc.c
+++ b/libavcodec/ljpegenc.c
@@ -8,20 +8,20 @@
  * aspecting, new decode_frame mechanism and apple mjpeg-b support
  *                                  by Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -57,10 +57,8 @@
         max_pkt_size += mb_width * mb_height * 3 * 4
                         * s->mjpeg_hsample[0] * s->mjpeg_vsample[0];
     }
-    if ((ret = ff_alloc_packet(pkt, max_pkt_size)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n", max_pkt_size);
+    if ((ret = ff_alloc_packet2(avctx, pkt, max_pkt_size)) < 0)
         return ret;
-    }
 
     init_put_bits(&s->pb, pkt->data, pkt->size);
 
@@ -72,7 +70,9 @@
 
     s->header_bits= put_bits_count(&s->pb);
 
-    if(avctx->pix_fmt == AV_PIX_FMT_BGRA){
+    if(avctx->pix_fmt == AV_PIX_FMT_BGR0
+        || avctx->pix_fmt == AV_PIX_FMT_BGRA
+        || avctx->pix_fmt == AV_PIX_FMT_BGR24){
         int x, y, i;
         const int linesize= p->linesize[0];
         uint16_t (*buffer)[4]= (void *) s->rd_scratchpad;
@@ -95,9 +95,15 @@
                 top[i]= left[i]= topleft[i]= buffer[0][i];
             }
             for(x = 0; x < width; x++) {
+                if(avctx->pix_fmt == AV_PIX_FMT_BGR24){
+                    buffer[x][1] = ptr[3*x+0] - ptr[3*x+1] + 0x100;
+                    buffer[x][2] = ptr[3*x+2] - ptr[3*x+1] + 0x100;
+                    buffer[x][0] = (ptr[3*x+0] + 2*ptr[3*x+1] + ptr[3*x+2])>>2;
+                }else{
                 buffer[x][1] = ptr[4*x+0] - ptr[4*x+1] + 0x100;
                 buffer[x][2] = ptr[4*x+2] - ptr[4*x+1] + 0x100;
                 buffer[x][0] = (ptr[4*x+0] + 2*ptr[4*x+1] + ptr[4*x+2])>>2;
+                }
 
                 for(i=0;i<3;i++) {
                     int pred, diff;
@@ -189,7 +195,8 @@
     }
 
     emms_c();
-
+    av_assert0(s->esc_pos == s->header_bits >> 3);
+    ff_mjpeg_encode_stuffing(s);
     ff_mjpeg_encode_picture_trailer(s);
     s->picture_number++;
 
@@ -211,5 +218,10 @@
     .init           = ff_MPV_encode_init,
     .encode2        = encode_picture_lossless,
     .close          = ff_MPV_encode_end,
+    .pix_fmts       = (const enum AVPixelFormat[]){
+        AV_PIX_FMT_BGR24, AV_PIX_FMT_BGRA, AV_PIX_FMT_BGR0,
+        AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P,
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P,
+        AV_PIX_FMT_NONE},
     .long_name      = NULL_IF_CONFIG_SMALL("Lossless JPEG"),
 };
diff --git a/libavcodec/loco.c b/libavcodec/loco.c
index 5d0ce05..53bdb58 100644
--- a/libavcodec/loco.c
+++ b/libavcodec/loco.c
@@ -2,20 +2,20 @@
  * LOCO codec
  * Copyright (c) 2005 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -123,6 +123,9 @@
     int val;
     int i, j;
 
+    if(buf_size<=0)
+        return -1;
+
     init_get_bits(&rc.gb, buf, buf_size*8);
     rc.save = 0;
     rc.run = 0;
@@ -176,56 +179,61 @@
     }
     p->key_frame = 1;
 
+#define ADVANCE_BY_DECODED do { \
+    if (decoded < 0) goto stop; \
+    buf += decoded; buf_size -= decoded; \
+} while(0)
     switch(l->mode) {
     case LOCO_CYUY2: case LOCO_YUY2: case LOCO_UYVY:
         decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height,
                                     p->linesize[0], buf, buf_size, 1);
-        buf += decoded; buf_size -= decoded;
+        ADVANCE_BY_DECODED;
         decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height,
                                     p->linesize[1], buf, buf_size, 1);
-        buf += decoded; buf_size -= decoded;
+        ADVANCE_BY_DECODED;
         decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height,
                                     p->linesize[2], buf, buf_size, 1);
         break;
     case LOCO_CYV12: case LOCO_YV12:
         decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height,
                                     p->linesize[0], buf, buf_size, 1);
-        buf += decoded; buf_size -= decoded;
+        ADVANCE_BY_DECODED;
         decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height / 2,
                                     p->linesize[2], buf, buf_size, 1);
-        buf += decoded; buf_size -= decoded;
+        ADVANCE_BY_DECODED;
         decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height / 2,
                                     p->linesize[1], buf, buf_size, 1);
         break;
     case LOCO_CRGB: case LOCO_RGB:
         decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height,
                                     -p->linesize[0], buf, buf_size, 3);
-        buf += decoded; buf_size -= decoded;
+        ADVANCE_BY_DECODED;
         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, 3);
-        buf += decoded; buf_size -= decoded;
+        ADVANCE_BY_DECODED;
         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_RGBA:
+    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);
-        buf += decoded; buf_size -= decoded;
+        ADVANCE_BY_DECODED;
         decoded = loco_decode_plane(l, p->data[0] + 1, avctx->width, avctx->height,
                                     p->linesize[0], buf, buf_size, 4);
-        buf += decoded; buf_size -= decoded;
+        ADVANCE_BY_DECODED;
         decoded = loco_decode_plane(l, p->data[0] + 2, avctx->width, avctx->height,
                                     p->linesize[0], buf, buf_size, 4);
-        buf += decoded; buf_size -= decoded;
+        ADVANCE_BY_DECODED;
         decoded = loco_decode_plane(l, p->data[0] + 3, avctx->width, avctx->height,
                                     p->linesize[0], buf, buf_size, 4);
         break;
     }
+stop:
 
     *data_size = sizeof(AVFrame);
     *(AVFrame*)data = l->pic;
 
-    return buf_size;
+    return buf_size < 0 ? -1 : avpkt->size - buf_size;
 }
 
 static av_cold int decode_init(AVCodecContext *avctx){
@@ -272,6 +280,8 @@
     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);
+
     return 0;
 }
 
diff --git a/libavcodec/lpc.c b/libavcodec/lpc.c
index 126dbc1..c8d24c0 100644
--- a/libavcodec/lpc.c
+++ b/libavcodec/lpc.c
@@ -2,20 +2,20 @@
  * LPC utility code
  * Copyright (c) 2006  Justin Ruggles <justin.ruggles@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,6 +24,7 @@
 
 #define LPC_USE_DOUBLE
 #include "lpc.h"
+#include "libavutil/avassert.h"
 
 
 /**
@@ -38,7 +39,7 @@
 
     /* The optimization in commit fa4ed8c does not support odd len.
      * If someone wants odd len extend that change. */
-    assert(!(len & 1));
+    av_assert2(!(len & 1));
 
     n2 = (len >> 1);
     c = 2.0 / (len - 1.0);
@@ -167,7 +168,7 @@
     int i, j, pass;
     int opt_order;
 
-    assert(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER &&
+    av_assert2(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER &&
            lpc_type > FF_LPC_TYPE_FIXED);
 
     /* reinit LPC context if parameters have changed */
@@ -190,6 +191,9 @@
         LLSModel m[2];
         double var[MAX_LPC_ORDER+1], av_uninit(weight);
 
+        if(lpc_passes <= 0)
+            lpc_passes = 2;
+
         for(pass=0; pass<lpc_passes; pass++){
             av_init_lls(&m[pass&1], max_order);
 
diff --git a/libavcodec/lpc.h b/libavcodec/lpc.h
index cbee46f..680e102 100644
--- a/libavcodec/lpc.h
+++ b/libavcodec/lpc.h
@@ -2,20 +2,20 @@
  * LPC utility code
  * Copyright (c) 2006  Justin Ruggles <justin.ruggles@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/lsp.c b/libavcodec/lsp.c
index 8a05aed..17f59ea 100644
--- a/libavcodec/lsp.c
+++ b/libavcodec/lsp.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2007 Reynaldo H. Verdejo Pinochet (QCELP decoder)
  * Copyright (c) 2008 Vladimir Voroshilov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -27,6 +27,8 @@
 #define FRAC_BITS 14
 #include "mathops.h"
 #include "lsp.h"
+#include "libavcodec/mips/lsp_mips.h"
+#include "libavutil/avassert.h"
 
 void ff_acelp_reorder_lsf(int16_t* lsfq, int lsfq_min_distance, int lsfq_min, int lsfq_max, int lp_order)
 {
@@ -73,7 +75,7 @@
     uint8_t offset= arg;
     uint8_t ind = arg >> 8;
 
-    assert(arg <= 0x3fff);
+    av_assert2(arg <= 0x3fff);
 
     return tab_cos[ind] + (offset * (tab_cos[ind+1] - tab_cos[ind]) >> 8);
 }
@@ -173,7 +175,11 @@
 
     /* LSP values for first subframe (3.2.5 of G.729, Equation 24)*/
     for(i=0; i<lp_order; i++)
+#ifdef G729_BITEXACT
+        lsp_1st[i] = (lsp_2nd[i] >> 1) + (lsp_prev[i] >> 1);
+#else
         lsp_1st[i] = (lsp_2nd[i] + lsp_prev[i]) >> 1;
+#endif
 
     ff_acelp_lsp2lpc(lp_1st, lsp_1st, lp_order >> 1);
 
@@ -181,6 +187,7 @@
     ff_acelp_lsp2lpc(lp_2nd, lsp_2nd, lp_order >> 1);
 }
 
+#ifndef ff_lsp2polyf
 void ff_lsp2polyf(const double *lsp, double *f, int lp_half_order)
 {
     int i, j;
@@ -197,13 +204,14 @@
         f[1] += val;
     }
 }
+#endif /* ff_lsp2polyf */
 
 void ff_acelp_lspd2lpc(const double *lsp, float *lpc, int lp_half_order)
 {
     double pa[MAX_LP_HALF_ORDER+1], qa[MAX_LP_HALF_ORDER+1];
     float *lpc2 = lpc + (lp_half_order << 1) - 1;
 
-    assert(lp_half_order <= MAX_LP_HALF_ORDER);
+    av_assert2(lp_half_order <= MAX_LP_HALF_ORDER);
 
     ff_lsp2polyf(lsp,     pa, lp_half_order);
     ff_lsp2polyf(lsp + 1, qa, lp_half_order);
diff --git a/libavcodec/lsp.h b/libavcodec/lsp.h
index 4b95567..46a2d47 100644
--- a/libavcodec/lsp.h
+++ b/libavcodec/lsp.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2008 Vladimir Voroshilov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/lzw.c b/libavcodec/lzw.c
index 2c99014..d06e3a0 100644
--- a/libavcodec/lzw.c
+++ b/libavcodec/lzw.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -191,6 +191,10 @@
             if ((--l) == 0)
                 goto the_end;
         }
+        if (s->ebuf < s->pbuf) {
+            av_log(0, AV_LOG_ERROR, "lzw overread\n");
+            goto the_end;
+        }
         c = lzw_get_code(s);
         if (c == s->end_code) {
             break;
diff --git a/libavcodec/lzw.h b/libavcodec/lzw.h
index ab782f5..115ca4e 100644
--- a/libavcodec/lzw.h
+++ b/libavcodec/lzw.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/lzwenc.c b/libavcodec/lzwenc.c
index cb064e7..0757d02 100644
--- a/libavcodec/lzwenc.c
+++ b/libavcodec/lzwenc.c
@@ -2,20 +2,20 @@
  * LZW encoder
  * Copyright (c) 2007 Bartlomiej Wolowiec
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mace.c b/libavcodec/mace.c
index 8fef839..c76f486 100644
--- a/libavcodec/mace.c
+++ b/libavcodec/mace.c
@@ -2,20 +2,20 @@
  * MACE decoder
  * Copyright (c) 2002 Laszlo Torok <torokl@alpha.dfmk.hu>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -228,7 +228,7 @@
 {
     MACEContext *ctx = avctx->priv_data;
 
-    if (avctx->channels > 2)
+    if (avctx->channels > 2 || avctx->channels <= 0)
         return -1;
     avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
 
diff --git a/libavcodec/mathops.h b/libavcodec/mathops.h
index 551017e..592f5a5 100644
--- a/libavcodec/mathops.h
+++ b/libavcodec/mathops.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2001, 2002 Fabrice Bellard
  * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #ifndef AVCODEC_MATHOPS_H
diff --git a/libavcodec/mathtables.c b/libavcodec/mathtables.c
index 141aa78..037b135 100644
--- a/libavcodec/mathtables.c
+++ b/libavcodec/mathtables.c
@@ -1,18 +1,20 @@
 /*
- * This file is part of Libav.
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mdct.c b/libavcodec/mdct.c
index 6f64534..2232024 100644
--- a/libavcodec/mdct.c
+++ b/libavcodec/mdct.c
@@ -2,20 +2,20 @@
  * MDCT/IMDCT transforms
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mdct_fixed.c b/libavcodec/mdct_fixed.c
index 94527f9..794a3e0 100644
--- a/libavcodec/mdct_fixed.c
+++ b/libavcodec/mdct_fixed.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mdct_float.c b/libavcodec/mdct_float.c
index e4f5549..ec4f486 100644
--- a/libavcodec/mdct_float.c
+++ b/libavcodec/mdct_float.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c
index a07d6e5..52b9040 100644
--- a/libavcodec/mdec.c
+++ b/libavcodec/mdec.c
@@ -4,20 +4,20 @@
  *
  * based upon code from Sebastian Jedruszkiewicz <elf@frogger.rules.pl>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -219,6 +219,7 @@
     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;
 }
@@ -244,14 +245,15 @@
     MDECContext * const a = avctx->priv_data;
     AVFrame *p = &a->picture;
 
-    avctx->coded_frame = p;
+    avctx->coded_frame= p;
     a->avctx= avctx;
 
-    p->qscale_table = av_mallocz( a->mb_width);
+    p->qscale_table= av_mallocz(a->mb_width);
 
     return 0;
 }
 
+
 static av_cold int decode_end(AVCodecContext *avctx){
     MDECContext * const a = avctx->priv_data;
 
diff --git a/libavcodec/microdvddec.c b/libavcodec/microdvddec.c
new file mode 100644
index 0000000..e08cc31
--- /dev/null
+++ b/libavcodec/microdvddec.c
@@ -0,0 +1,369 @@
+/*
+ * 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
+ * MicroDVD subtitle decoder
+ *
+ * Based on the specifications found here:
+ * https://trac.videolan.org/vlc/ticket/1825#comment:6
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/bprint.h"
+#include "avcodec.h"
+#include "ass.h"
+
+static int indexof(const char *s, int c)
+{
+    char *f = strchr(s, c);
+    return f ? (f - s) : -1;
+}
+
+struct microdvd_tag {
+    char key;
+    int persistent;
+    uint32_t data1;
+    uint32_t data2;
+    char *data_string;
+    int data_string_len;
+};
+
+#define MICRODVD_PERSISTENT_OFF     0
+#define MICRODVD_PERSISTENT_ON      1
+#define MICRODVD_PERSISTENT_OPENED  2
+
+// Color, Font, Size, cHarset, stYle, Position, cOordinate
+#define MICRODVD_TAGS "cfshyYpo"
+
+static void microdvd_set_tag(struct microdvd_tag *tags, struct microdvd_tag tag)
+{
+    int tag_index = indexof(MICRODVD_TAGS, tag.key);
+
+    if (tag_index < 0)
+        return;
+    memcpy(&tags[tag_index], &tag, sizeof(tag));
+}
+
+// italic, bold, underline, strike-through
+#define MICRODVD_STYLES "ibus"
+
+static char *microdvd_load_tags(struct microdvd_tag *tags, char *s)
+{
+    while (*s == '{') {
+        char *start = s;
+        char tag_char = *(s + 1);
+        struct microdvd_tag tag = {0};
+
+        if (!tag_char || *(s + 2) != ':')
+            break;
+        s += 3;
+
+        switch (tag_char) {
+
+        /* Style */
+        case 'Y':
+            tag.persistent = MICRODVD_PERSISTENT_ON;
+        case 'y':
+            while (*s && *s != '}') {
+                int style_index = indexof(MICRODVD_STYLES, *s);
+
+                if (style_index >= 0)
+                    tag.data1 |= (1 << style_index);
+                s++;
+            }
+            if (*s != '}')
+                break;
+            /* We must distinguish persistent and non-persistent styles
+             * to handle this kind of style tags: {y:ib}{Y:us} */
+            tag.key = tag_char;
+            break;
+
+        /* Color */
+        case 'C':
+            tag.persistent = MICRODVD_PERSISTENT_ON;
+        case 'c':
+            if (*s == '$')
+                s++;
+            tag.data1 = strtol(s, &s, 16) & 0x00ffffff;
+            if (*s != '}')
+                break;
+            tag.key = 'c';
+            break;
+
+        /* Font name */
+        case 'F':
+            tag.persistent = MICRODVD_PERSISTENT_ON;
+        case 'f': {
+            int len = indexof(s, '}');
+            if (len < 0)
+                break;
+            tag.data_string = s;
+            tag.data_string_len = len;
+            s += len;
+            tag.key = 'f';
+            break;
+        }
+
+        /* Font size */
+        case 'S':
+            tag.persistent = MICRODVD_PERSISTENT_ON;
+        case 's':
+            tag.data1 = strtol(s, &s, 10);
+            if (*s != '}')
+                break;
+            tag.key = 's';
+            break;
+
+        /* Charset */
+        case 'H': {
+            //TODO: not yet handled, just parsed.
+            int len = indexof(s, '}');
+            if (len < 0)
+                break;
+            tag.data_string = s;
+            tag.data_string_len = len;
+            s += len;
+            tag.key = 'h';
+            break;
+        }
+
+        /* Position */
+        case 'P':
+            tag.persistent = MICRODVD_PERSISTENT_ON;
+            tag.data1 = (*s++ == '1');
+            if (*s != '}')
+                break;
+            tag.key = 'p';
+            break;
+
+        /* Coordinates */
+        case 'o':
+            tag.persistent = MICRODVD_PERSISTENT_ON;
+            tag.data1 = strtol(s, &s, 10);
+            if (*s != ',')
+                break;
+            s++;
+            tag.data2 = strtol(s, &s, 10);
+            if (*s != '}')
+                break;
+            tag.key = 'o';
+            break;
+
+        default:    /* Unknown tag, we consider it's text */
+            break;
+        }
+
+        if (tag.key == 0)
+            return start;
+
+        microdvd_set_tag(tags, tag);
+        s++;
+    }
+    return s;
+}
+
+static void microdvd_open_tags(AVBPrint *new_line, struct microdvd_tag *tags)
+{
+    int i, sidx;
+    for (i = 0; i < sizeof(MICRODVD_TAGS) - 1; i++) {
+        if (tags[i].persistent == MICRODVD_PERSISTENT_OPENED)
+            continue;
+        switch (tags[i].key) {
+        case 'Y':
+        case 'y':
+            for (sidx = 0; sidx < sizeof(MICRODVD_STYLES) - 1; sidx++)
+                if (tags[i].data1 & (1 << sidx))
+                    av_bprintf(new_line, "{\\%c1}", MICRODVD_STYLES[sidx]);
+            break;
+
+        case 'c':
+            av_bprintf(new_line, "{\\c&H%06X&}", tags[i].data1);
+            break;
+
+        case 'f':
+            av_bprintf(new_line, "{\\fn%.*s}",
+                       tags[i].data_string_len, tags[i].data_string);
+            break;
+
+        case 's':
+            av_bprintf(new_line, "{\\fs%d}", tags[i].data1);
+            break;
+
+        case 'p':
+            if (tags[i].data1 == 0)
+                av_bprintf(new_line, "{\\an8}");
+            break;
+
+        case 'o':
+            av_bprintf(new_line, "{\\pos(%d,%d)}",
+                       tags[i].data1, tags[i].data2);
+            break;
+        }
+        if (tags[i].persistent == MICRODVD_PERSISTENT_ON)
+            tags[i].persistent = MICRODVD_PERSISTENT_OPENED;
+    }
+}
+
+static void microdvd_close_no_persistent_tags(AVBPrint *new_line,
+                                              struct microdvd_tag *tags)
+{
+    int i, sidx;
+
+    for (i = sizeof(MICRODVD_TAGS) - 2; i >= 0; i--) {
+        if (tags[i].persistent != MICRODVD_PERSISTENT_OFF)
+            continue;
+        switch (tags[i].key) {
+
+        case 'y':
+            for (sidx = sizeof(MICRODVD_STYLES) - 2; sidx >= 0; sidx--)
+                if (tags[i].data1 & (1 << sidx))
+                    av_bprintf(new_line, "{\\%c0}", MICRODVD_STYLES[sidx]);
+            break;
+
+        case 'c':
+            av_bprintf(new_line, "{\\c}");
+            break;
+
+        case 'f':
+            av_bprintf(new_line, "{\\fn}");
+            break;
+
+        case 's':
+            av_bprintf(new_line, "{\\fs}");
+            break;
+        }
+        tags[i].key = 0;
+    }
+}
+
+static int microdvd_decode_frame(AVCodecContext *avctx,
+                                 void *data, int *got_sub_ptr, AVPacket *avpkt)
+{
+    AVSubtitle *sub = data;
+    AVBPrint new_line;
+    char *decoded_sub;
+    char *line = avpkt->data;
+    char *end = avpkt->data + avpkt->size;
+    struct microdvd_tag tags[sizeof(MICRODVD_TAGS) - 1] = {{0}};
+
+    if (avpkt->size <= 0)
+        return avpkt->size;
+
+    av_bprint_init(&new_line, 0, 2048);
+
+    // skip {frame_start}{frame_end}
+    line = strchr(line, '}'); if (!line) goto end; line++;
+    line = strchr(line, '}'); if (!line) goto end; line++;
+
+    // subtitle content
+    while (line < end && *line) {
+
+        // parse MicroDVD tags, and open them in ASS
+        line = microdvd_load_tags(tags, line);
+        microdvd_open_tags(&new_line, tags);
+
+        // simple copy until EOL or forced carriage return
+        while (line < end && *line && *line != '|') {
+            av_bprint_chars(&new_line, *line, 1);
+            line++;
+        }
+
+        // line split
+        if (line < end && *line == '|') {
+            microdvd_close_no_persistent_tags(&new_line, tags);
+            av_bprintf(&new_line, "\\N");
+            line++;
+        }
+    }
+
+end:
+    av_bprint_finalize(&new_line, &decoded_sub);
+    if (*decoded_sub) {
+        int64_t start    = avpkt->pts;
+        int64_t duration = avpkt->duration;
+        int ts_start     = av_rescale_q(start,    avctx->time_base, (AVRational){1,100});
+        int ts_duration  = duration != -1 ?
+                           av_rescale_q(duration, avctx->time_base, (AVRational){1,100}) : -1;
+        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;
+}
+
+static int microdvd_init(AVCodecContext *avctx)
+{
+    int i, sidx;
+    AVBPrint font_buf;
+    int font_size    = ASS_DEFAULT_FONT_SIZE;
+    int color        = ASS_DEFAULT_COLOR;
+    int bold         = ASS_DEFAULT_BOLD;
+    int italic       = ASS_DEFAULT_ITALIC;
+    int underline    = ASS_DEFAULT_UNDERLINE;
+    int alignment    = ASS_DEFAULT_ALIGNMENT;
+    struct microdvd_tag tags[sizeof(MICRODVD_TAGS) - 1] = {{0}};
+
+    av_bprint_init(&font_buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
+    av_bprintf(&font_buf, "%s", ASS_DEFAULT_FONT);
+
+    if (avctx->extradata) {
+        microdvd_load_tags(tags, avctx->extradata);
+        for (i = 0; i < sizeof(MICRODVD_TAGS) - 1; i++) {
+            switch (av_tolower(tags[i].key)) {
+            case 'y':
+                for (sidx = 0; sidx < sizeof(MICRODVD_STYLES) - 1; sidx++) {
+                    if (tags[i].data1 & (1 << sidx)) {
+                        switch (MICRODVD_STYLES[sidx]) {
+                        case 'i': italic    = 1; break;
+                        case 'b': bold      = 1; break;
+                        case 'u': underline = 1; break;
+                        }
+                    }
+                }
+                break;
+
+            case 'c': color     = tags[i].data1; break;
+            case 's': font_size = tags[i].data1; break;
+            case 'p': alignment =             8; break;
+
+            case 'f':
+                av_bprint_clear(&font_buf);
+                av_bprintf(&font_buf, "%.*s",
+                           tags[i].data_string_len, tags[i].data_string);
+                break;
+            }
+        }
+    }
+    return ff_ass_subtitle_header(avctx, font_buf.str, font_size, color,
+                                  ASS_DEFAULT_BACK_COLOR, bold, italic,
+                                  underline, alignment);
+}
+
+AVCodec ff_microdvd_decoder = {
+    .name         = "microdvd",
+    .long_name    = NULL_IF_CONFIG_SMALL("MicroDVD subtitle"),
+    .type         = AVMEDIA_TYPE_SUBTITLE,
+    .id           = AV_CODEC_ID_MICRODVD,
+    .init         = microdvd_init,
+    .decode       = microdvd_decode_frame,
+};
diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c
index fd7efef..25db9ca 100644
--- a/libavcodec/mimic.c
+++ b/libavcodec/mimic.c
@@ -2,20 +2,20 @@
  * Copyright (C) 2005  Ole André Vadla Ravnås <oleavr@gmail.com>
  * Copyright (C) 2008  Ramiro Polla
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -210,7 +210,7 @@
 
         value = get_bits(&ctx->gb, num_bits);
 
-        /* Libav's IDCT behaves somewhat different from the original code, so
+        /* FFmpeg's IDCT behaves somewhat different from the original code, so
          * a factor of 4 was added to the input */
 
         coeff = vlcdec_lookup[num_bits][value];
@@ -355,7 +355,7 @@
         return -1;
     }
 
-    ctx->buf_ptrs[ctx->cur_index].reference = 1;
+    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])) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
@@ -370,8 +370,7 @@
 
     ff_thread_finish_setup(avctx);
 
-    av_fast_malloc(&ctx->swap_buf, &ctx->swap_buf_size,
-                                 swap_buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
+    av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
     if(!ctx->swap_buf)
         return AVERROR(ENOMEM);
 
diff --git a/libavcodec/mips/Makefile b/libavcodec/mips/Makefile
index 5f00d70..8f64f82 100644
--- a/libavcodec/mips/Makefile
+++ b/libavcodec/mips/Makefile
@@ -2,3 +2,19 @@
             mips/idct_mmi.o                                             \
 
 MMI-OBJS-$(CONFIG_MPEGVIDEO)            += mips/mpegvideo_mmi.o
+
+MIPSFPU-OBJS-$(CONFIG_AMRNB_DECODER)      += mips/acelp_filters_mips.o     \
+                                             mips/celp_filters_mips.o      \
+                                             mips/celp_math_mips.o         \
+                                             mips/acelp_vectors_mips.o
+MIPSFPU-OBJS-$(CONFIG_AMRWB_DECODER)      += mips/acelp_filters_mips.o     \
+                                             mips/celp_filters_mips.o      \
+                                             mips/amrwbdec_mips.o          \
+                                             mips/celp_math_mips.o         \
+                                             mips/acelp_vectors_mips.o
+MIPSFPU-OBJS-$(CONFIG_MPEGAUDIODSP)       += mips/mpegaudiodsp_mips_float.o
+MIPSDSPR1-OBJS-$(CONFIG_MPEGAUDIODSP)     += mips/mpegaudiodsp_mips_fixed.o
+OBJS-$(CONFIG_FFT)                        += mips/fft_init_table.o
+MIPSFPU-OBJS-$(CONFIG_FFT)                += mips/fft_mips.o
+MIPSFPU-OBJS-$(HAVE_INLINE_ASM)           += mips/fmtconvert_mips.o
+MIPSFPU-OBJS-$(HAVE_INLINE_ASM)           += mips/dsputil_mips.o
diff --git a/libavcodec/mips/acelp_filters_mips.c b/libavcodec/mips/acelp_filters_mips.c
new file mode 100644
index 0000000..498660b
--- /dev/null
+++ b/libavcodec/mips/acelp_filters_mips.c
@@ -0,0 +1,210 @@
+ /*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Nedeljko Babic (nbabic@mips.com)
+ *
+ * various filters for ACELP-based codecs 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/acelp_filters.c
+ */
+#include "libavutil/attributes.h"
+#include "libavcodec/acelp_filters.h"
+
+static void ff_acelp_interpolatef_mips(float *out, const float *in,
+                           const float *filter_coeffs, int precision,
+                           int frac_pos, int filter_length, int length)
+{
+    int n, i;
+    int prec = precision * 4;
+    int fc_offset = precision - frac_pos;
+    float in_val_p, in_val_m, fc_val_p, fc_val_m;
+
+    for (n = 0; n < length; n++) {
+        /**
+        * four pointers are defined in order to minimize number of
+        * computations done in inner loop
+        */
+        const float *p_in_p = &in[n];
+        const float *p_in_m = &in[n-1];
+        const float *p_filter_coeffs_p = &filter_coeffs[frac_pos];
+        const float *p_filter_coeffs_m = filter_coeffs + fc_offset;
+        float v = 0;
+
+        for (i = 0; i < filter_length;i++) {
+            __asm__ volatile (
+                "lwc1   %[in_val_p],           0(%[p_in_p])                    \n\t"
+                "lwc1   %[fc_val_p],           0(%[p_filter_coeffs_p])         \n\t"
+                "lwc1   %[in_val_m],           0(%[p_in_m])                    \n\t"
+                "lwc1   %[fc_val_m],           0(%[p_filter_coeffs_m])         \n\t"
+                "addiu  %[p_in_p],             %[p_in_p],              4       \n\t"
+                "madd.s %[v],%[v],             %[in_val_p],%[fc_val_p]         \n\t"
+                "addiu  %[p_in_m],             %[p_in_m],              -4      \n\t"
+                "addu   %[p_filter_coeffs_p],  %[p_filter_coeffs_p],   %[prec] \n\t"
+                "addu   %[p_filter_coeffs_m],  %[p_filter_coeffs_m],   %[prec] \n\t"
+                "madd.s %[v],%[v],%[in_val_m], %[fc_val_m]                     \n\t"
+
+                : [v] "=&f" (v),[p_in_p] "+r" (p_in_p), [p_in_m] "+r" (p_in_m),
+                  [p_filter_coeffs_p] "+r" (p_filter_coeffs_p),
+                  [in_val_p] "=&f" (in_val_p), [in_val_m] "=&f" (in_val_m),
+                  [fc_val_p] "=&f" (fc_val_p), [fc_val_m] "=&f" (fc_val_m),
+                  [p_filter_coeffs_m] "+r" (p_filter_coeffs_m)
+                : [prec] "r" (prec)
+            );
+        }
+        out[n] = v;
+    }
+}
+
+static void ff_acelp_apply_order_2_transfer_function_mips(float *out, const float *in,
+                                              const float zero_coeffs[2],
+                                              const float pole_coeffs[2],
+                                              float gain, float mem[2], int n)
+{
+    /**
+    * loop is unrolled eight times
+    */
+
+    __asm__ volatile (
+        "lwc1   $f0,    0(%[mem])                                              \n\t"
+        "blez   %[n],   ff_acelp_apply_order_2_transfer_function_end%=         \n\t"
+        "lwc1   $f1,    4(%[mem])                                              \n\t"
+        "lwc1   $f2,    0(%[pole_coeffs])                                      \n\t"
+        "lwc1   $f3,    4(%[pole_coeffs])                                      \n\t"
+        "lwc1   $f4,    0(%[zero_coeffs])                                      \n\t"
+        "lwc1   $f5,    4(%[zero_coeffs])                                      \n\t"
+
+        "ff_acelp_apply_order_2_transfer_function_madd%=:                      \n\t"
+
+        "lwc1   $f6,    0(%[in])                                               \n\t"
+        "mul.s  $f9,    $f3,      $f1                                          \n\t"
+        "mul.s  $f7,    $f2,      $f0                                          \n\t"
+        "msub.s $f7,    $f7,      %[gain], $f6                                 \n\t"
+        "sub.s  $f7,    $f7,      $f9                                          \n\t"
+        "madd.s $f8,    $f7,      $f4,     $f0                                 \n\t"
+        "madd.s $f8,    $f8,      $f5,     $f1                                 \n\t"
+        "lwc1   $f11,   4(%[in])                                               \n\t"
+        "mul.s  $f12,   $f3,      $f0                                          \n\t"
+        "mul.s  $f13,   $f2,      $f7                                          \n\t"
+        "msub.s $f13,   $f13,     %[gain], $f11                                \n\t"
+        "sub.s  $f13,   $f13,     $f12                                         \n\t"
+        "madd.s $f14,   $f13,     $f4,     $f7                                 \n\t"
+        "madd.s $f14,   $f14,     $f5,     $f0                                 \n\t"
+        "swc1   $f8,    0(%[out])                                              \n\t"
+        "lwc1   $f6,    8(%[in])                                               \n\t"
+        "mul.s  $f9,    $f3,      $f7                                          \n\t"
+        "mul.s  $f15,   $f2,      $f13                                         \n\t"
+        "msub.s $f15,   $f15,     %[gain], $f6                                 \n\t"
+        "sub.s  $f15,   $f15,     $f9                                          \n\t"
+        "madd.s $f8,    $f15,     $f4,     $f13                                \n\t"
+        "madd.s $f8,    $f8,      $f5,     $f7                                 \n\t"
+        "swc1   $f14,   4(%[out])                                              \n\t"
+        "lwc1   $f11,   12(%[in])                                              \n\t"
+        "mul.s  $f12,   $f3,      $f13                                         \n\t"
+        "mul.s  $f16,   $f2,      $f15                                         \n\t"
+        "msub.s $f16,   $f16,     %[gain], $f11                                \n\t"
+        "sub.s  $f16,   $f16,     $f12                                         \n\t"
+        "madd.s $f14,   $f16,     $f4,     $f15                                \n\t"
+        "madd.s $f14,   $f14,     $f5,     $f13                                \n\t"
+        "swc1   $f8,    8(%[out])                                              \n\t"
+        "lwc1   $f6,    16(%[in])                                              \n\t"
+        "mul.s  $f9,    $f3,      $f15                                         \n\t"
+        "mul.s  $f7,    $f2,      $f16                                         \n\t"
+        "msub.s $f7,    $f7,      %[gain], $f6                                 \n\t"
+        "sub.s  $f7,    $f7,      $f9                                          \n\t"
+        "madd.s $f8,    $f7,      $f4,     $f16                                \n\t"
+        "madd.s $f8,    $f8,      $f5,     $f15                                \n\t"
+        "swc1   $f14,   12(%[out])                                             \n\t"
+        "lwc1   $f11,   20(%[in])                                              \n\t"
+        "mul.s  $f12,   $f3,      $f16                                         \n\t"
+        "mul.s  $f13,   $f2,      $f7                                          \n\t"
+        "msub.s $f13,   $f13,     %[gain], $f11                                \n\t"
+        "sub.s  $f13,   $f13,     $f12                                         \n\t"
+        "madd.s $f14,   $f13,     $f4,     $f7                                 \n\t"
+        "madd.s $f14,   $f14,     $f5,     $f16                                \n\t"
+        "swc1   $f8,    16(%[out])                                             \n\t"
+        "lwc1   $f6,    24(%[in])                                              \n\t"
+        "mul.s  $f9,    $f3,      $f7                                          \n\t"
+        "mul.s  $f15,   $f2,      $f13                                         \n\t"
+        "msub.s $f15,   $f15,     %[gain], $f6                                 \n\t"
+        "sub.s  $f1,    $f15,     $f9                                          \n\t"
+        "madd.s $f8,    $f1,      $f4,     $f13                                \n\t"
+        "madd.s $f8,    $f8,      $f5,     $f7                                 \n\t"
+        "swc1   $f14,   20(%[out])                                             \n\t"
+        "lwc1   $f11,   28(%[in])                                              \n\t"
+        "mul.s  $f12,   $f3,      $f13                                         \n\t"
+        "mul.s  $f16,   $f2,      $f1                                          \n\t"
+        "msub.s $f16,   $f16,     %[gain], $f11                                \n\t"
+        "sub.s  $f0,    $f16,     $f12                                         \n\t"
+        "madd.s $f14,   $f0,      $f4,     $f1                                 \n\t"
+        "madd.s $f14,   $f14,     $f5,     $f13                                \n\t"
+        "swc1   $f8,    24(%[out])                                             \n\t"
+        "addiu  %[out], 32                                                     \n\t"
+        "addiu  %[in],  32                                                     \n\t"
+        "addiu  %[n],   -8                                                     \n\t"
+        "swc1   $f14,   -4(%[out])                                             \n\t"
+        "bnez   %[n],   ff_acelp_apply_order_2_transfer_function_madd%=        \n\t"
+        "swc1   $f1,    4(%[mem])                                              \n\t"
+        "swc1   $f0,    0(%[mem])                                              \n\t"
+
+        "ff_acelp_apply_order_2_transfer_function_end%=:                       \n\t"
+
+         : [out] "+r" (out),
+           [in] "+r" (in), [gain] "+f" (gain),
+           [n] "+r" (n), [mem] "+r" (mem)
+         : [zero_coeffs] "r" (zero_coeffs),
+           [pole_coeffs] "r" (pole_coeffs)
+         : "$f0", "$f1", "$f2", "$f3", "$f4", "$f5",
+           "$f6", "$f7",  "$f8", "$f9", "$f10", "$f11",
+           "$f12", "$f13", "$f14", "$f15", "$f16"
+    );
+}
+
+void ff_acelp_filter_init_mips(ACELPFContext *c)
+{
+    c->acelp_interpolatef                      = ff_acelp_interpolatef_mips;
+    c->acelp_apply_order_2_transfer_function   = ff_acelp_apply_order_2_transfer_function_mips;
+}
diff --git a/libavcodec/mips/acelp_vectors_mips.c b/libavcodec/mips/acelp_vectors_mips.c
new file mode 100644
index 0000000..6f9390f
--- /dev/null
+++ b/libavcodec/mips/acelp_vectors_mips.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Nedeljko Babic (nbabic@mips.com)
+ *
+ * adaptive and fixed codebook vector operations for ACELP-based codecs
+ * 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/acelp_vectors.c
+ */
+#include "libavcodec/acelp_vectors.h"
+
+static void ff_weighted_vector_sumf_mips(
+                  float *out, const float *in_a, const float *in_b,
+                  float weight_coeff_a, float weight_coeff_b, int length)
+{
+    const float *a_end = in_a + length;
+
+    /* loop unrolled two times */
+    __asm__ volatile (
+        "blez   %[length], ff_weighted_vector_sumf_end%=                     \n\t"
+
+        "ff_weighted_vector_sumf_madd%=:                                     \n\t"
+        "lwc1   $f0,       0(%[in_a])                                        \n\t"
+        "lwc1   $f3,       4(%[in_a])                                        \n\t"
+        "lwc1   $f1,       0(%[in_b])                                        \n\t"
+        "lwc1   $f4,       4(%[in_b])                                        \n\t"
+        "mul.s  $f2,       %[weight_coeff_a], $f0                            \n\t"
+        "mul.s  $f5,       %[weight_coeff_a], $f3                            \n\t"
+        "madd.s $f2,       $f2,               %[weight_coeff_b], $f1         \n\t"
+        "madd.s $f5,       $f5,               %[weight_coeff_b], $f4         \n\t"
+        "addiu  %[in_a],   8                                                 \n\t"
+        "addiu  %[in_b],   8                                                 \n\t"
+        "swc1   $f2,       0(%[out])                                         \n\t"
+        "swc1   $f5,       4(%[out])                                         \n\t"
+        "addiu  %[out],    8                                                 \n\t"
+        "bne   %[in_a],    %[a_end],          ff_weighted_vector_sumf_madd%= \n\t"
+
+        "ff_weighted_vector_sumf_end%=:                                      \n\t"
+
+        : [out] "+r" (out), [in_a] "+r" (in_a),   [in_b] "+r" (in_b)
+        : [weight_coeff_a] "f" (weight_coeff_a),
+          [weight_coeff_b] "f" (weight_coeff_b),
+          [length] "r" (length), [a_end]"r"(a_end)
+        : "$f0", "$f1", "$f2", "$f3", "$f4", "$f5"
+    );
+}
+
+void ff_acelp_vectors_init_mips(ACELPVContext *c)
+{
+    c->weighted_vector_sumf = ff_weighted_vector_sumf_mips;
+}
diff --git a/libavcodec/mips/amrwbdec_mips.c b/libavcodec/mips/amrwbdec_mips.c
new file mode 100644
index 0000000..4bfbb8c
--- /dev/null
+++ b/libavcodec/mips/amrwbdec_mips.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Nedeljko Babic (nbabic@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/amrwbdec.c
+ */
+#include "libavutil/avutil.h"
+#include "libavcodec/amrwbdata.h"
+#include "amrwbdec_mips.h"
+
+void hb_fir_filter_mips(float *out, const float fir_coef[HB_FIR_SIZE + 1],
+                          float mem[HB_FIR_SIZE], const float *in)
+{
+    int i;
+    float data[AMRWB_SFR_SIZE_16k + HB_FIR_SIZE]; // past and current samples
+
+    memcpy(data, mem, HB_FIR_SIZE * sizeof(float));
+    memcpy(data + HB_FIR_SIZE, in, AMRWB_SFR_SIZE_16k * sizeof(float));
+
+    for (i = 0; i < AMRWB_SFR_SIZE_16k; i++) {
+        float output;
+        float * p_data = (data+i);
+
+        /**
+        * inner loop is entirely unrolled and instructions are scheduled
+        * to minimize pipeline stall
+        */
+        __asm__ volatile(
+            "mtc1       $zero,     %[output]                      \n\t"
+            "lwc1       $f0,       0(%[p_data])                   \n\t"
+            "lwc1       $f1,       0(%[fir_coef])                 \n\t"
+            "lwc1       $f2,       4(%[p_data])                   \n\t"
+            "madd.s     %[output], %[output],       $f0, $f1      \n\t"
+            "lwc1       $f3,       4(%[fir_coef])                 \n\t"
+            "lwc1       $f4,       8(%[p_data])                   \n\t"
+            "madd.s     %[output], %[output],       $f2, $f3      \n\t"
+            "lwc1       $f5,       8(%[fir_coef])                 \n\t"
+
+            "lwc1       $f0,       12(%[p_data])                  \n\t"
+            "lwc1       $f1,       12(%[fir_coef])                \n\t"
+            "madd.s     %[output], %[output],       $f4, $f5      \n\t"
+            "lwc1       $f2,       16(%[p_data])                  \n\t"
+            "madd.s     %[output], %[output],       $f0, $f1      \n\t"
+            "lwc1       $f3,       16(%[fir_coef])                \n\t"
+            "lwc1       $f4,       20(%[p_data])                  \n\t"
+            "lwc1       $f5,       20(%[fir_coef])                \n\t"
+            "madd.s     %[output], %[output],       $f2, $f3      \n\t"
+
+            "lwc1       $f0,       24(%[p_data])                  \n\t"
+            "lwc1       $f1,       24(%[fir_coef])                \n\t"
+            "lwc1       $f2,       28(%[p_data])                  \n\t"
+            "madd.s     %[output], %[output],       $f4, $f5      \n\t"
+            "lwc1       $f3,       28(%[fir_coef])                \n\t"
+            "madd.s     %[output], %[output],       $f0, $f1      \n\t"
+            "lwc1       $f4,       32(%[p_data])                  \n\t"
+            "madd.s     %[output], %[output],       $f2, $f3      \n\t"
+            "lwc1       $f5,       32(%[fir_coef])                \n\t"
+            "madd.s     %[output], %[output],       $f4, $f5      \n\t"
+
+            "lwc1       $f0,       36(%[p_data])                  \n\t"
+            "lwc1       $f1,       36(%[fir_coef])                \n\t"
+            "lwc1       $f2,       40(%[p_data])                  \n\t"
+            "lwc1       $f3,       40(%[fir_coef])                \n\t"
+            "madd.s     %[output], %[output],       $f0, $f1      \n\t"
+            "lwc1       $f4,       44(%[p_data])                  \n\t"
+            "lwc1       $f5,       44(%[fir_coef])                \n\t"
+            "madd.s     %[output], %[output],       $f2, $f3      \n\t"
+
+            "lwc1       $f0,       48(%[p_data])                  \n\t"
+            "lwc1       $f1,       48(%[fir_coef])                \n\t"
+            "lwc1       $f2,       52(%[p_data])                  \n\t"
+            "madd.s     %[output], %[output],       $f4, $f5      \n\t"
+            "lwc1       $f3,       52(%[fir_coef])                \n\t"
+            "lwc1       $f4,       56(%[p_data])                  \n\t"
+            "madd.s     %[output], %[output],       $f0, $f1      \n\t"
+            "lwc1       $f5,       56(%[fir_coef])                \n\t"
+            "madd.s     %[output], %[output],       $f2, $f3      \n\t"
+
+            "lwc1       $f0,       60(%[p_data])                  \n\t"
+            "lwc1       $f1,       60(%[fir_coef])                \n\t"
+            "lwc1       $f2,       64(%[p_data])                  \n\t"
+            "madd.s     %[output], %[output],       $f4, $f5      \n\t"
+            "lwc1       $f3,       64(%[fir_coef])                \n\t"
+            "madd.s     %[output], %[output],       $f0, $f1      \n\t"
+            "lwc1       $f4,       68(%[p_data])                  \n\t"
+            "madd.s     %[output], %[output],       $f2, $f3      \n\t"
+            "lwc1       $f5,       68(%[fir_coef])                \n\t"
+            "madd.s     %[output], %[output],       $f4, $f5      \n\t"
+
+            "lwc1       $f0,       72(%[p_data])                  \n\t"
+            "lwc1       $f1,       72(%[fir_coef])                \n\t"
+            "lwc1       $f2,       76(%[p_data])                  \n\t"
+            "lwc1       $f3,       76(%[fir_coef])                \n\t"
+            "madd.s     %[output], %[output],       $f0, $f1      \n\t"
+            "lwc1       $f4,       80(%[p_data])                  \n\t"
+            "lwc1       $f5,       80(%[fir_coef])                \n\t"
+            "madd.s     %[output], %[output],       $f2, $f3      \n\t"
+
+            "lwc1       $f0,       84(%[p_data])                  \n\t"
+            "lwc1       $f1,       84(%[fir_coef])                \n\t"
+            "lwc1       $f2,       88(%[p_data])                  \n\t"
+            "madd.s     %[output], %[output],       $f4, $f5      \n\t"
+            "lwc1       $f3,       88(%[fir_coef])                \n\t"
+            "lwc1       $f4,       92(%[p_data])                  \n\t"
+            "madd.s     %[output], %[output],       $f0, $f1      \n\t"
+            "lwc1       $f5,       92(%[fir_coef])                \n\t"
+            "madd.s     %[output], %[output],       $f2, $f3      \n\t"
+
+            "lwc1       $f0,       96(%[p_data])                  \n\t"
+            "lwc1       $f1,       96(%[fir_coef])                \n\t"
+            "lwc1       $f2,       100(%[p_data])                 \n\t"
+            "madd.s     %[output], %[output],       $f4, $f5      \n\t"
+            "lwc1       $f3,       100(%[fir_coef])               \n\t"
+            "lwc1       $f4,       104(%[p_data])                 \n\t"
+            "madd.s     %[output], %[output],       $f0, $f1      \n\t"
+            "lwc1       $f5,       104(%[fir_coef])               \n\t"
+            "madd.s     %[output], %[output],       $f2, $f3      \n\t"
+
+            "lwc1       $f0,       108(%[p_data])                 \n\t"
+            "lwc1       $f1,       108(%[fir_coef])               \n\t"
+            "madd.s     %[output], %[output],       $f4, $f5      \n\t"
+            "lwc1       $f2,       112(%[p_data])                 \n\t"
+            "lwc1       $f3,       112(%[fir_coef])               \n\t"
+            "madd.s     %[output], %[output],       $f0, $f1      \n\t"
+            "lwc1       $f4,       116(%[p_data])                 \n\t"
+            "lwc1       $f5,       116(%[fir_coef])               \n\t"
+            "lwc1       $f0,       120(%[p_data])                 \n\t"
+            "madd.s     %[output], %[output],       $f2, $f3      \n\t"
+            "lwc1       $f1,       120(%[fir_coef])               \n\t"
+            "madd.s     %[output], %[output],       $f4, $f5      \n\t"
+            "madd.s     %[output], %[output],       $f0, $f1      \n\t"
+
+            : [output]"=&f"(output)
+            : [fir_coef]"r"(fir_coef), [p_data]"r"(p_data)
+            : "$f0", "$f1", "$f2", "$f3", "$f4", "$f5"
+        );
+        out[i] = output;
+    }
+    memcpy(mem, data + AMRWB_SFR_SIZE_16k, HB_FIR_SIZE * sizeof(float));
+}
diff --git a/libavcodec/mips/amrwbdec_mips.h b/libavcodec/mips/amrwbdec_mips.h
new file mode 100644
index 0000000..a469918
--- /dev/null
+++ b/libavcodec/mips/amrwbdec_mips.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Nedeljko Babic (nbabic@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/amrwbdec.c
+ */
+#ifndef AVCODEC_AMRWBDEC_MIPS_H
+#define AVCODEC_AMRWBDEC_MIPS_H
+#include "config.h"
+
+#if HAVE_MIPSFPU && HAVE_INLINE_ASM
+void hb_fir_filter_mips(float *out, const float fir_coef[],
+                          float mem[], const float *in);
+#define hb_fir_filter hb_fir_filter_mips
+#endif
+
+#endif /* AVCODEC_AMRWBDEC_MIPS_H  */
diff --git a/libavcodec/mips/celp_filters_mips.c b/libavcodec/mips/celp_filters_mips.c
new file mode 100644
index 0000000..06e0127
--- /dev/null
+++ b/libavcodec/mips/celp_filters_mips.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Nedeljko Babic (nbabic@mips.com)
+ *
+ * various filters for CELP-based codecs 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/celp_filters.c
+ */
+#include "libavutil/attributes.h"
+#include "libavutil/common.h"
+#include "libavcodec/celp_filters.h"
+
+static void ff_celp_lp_synthesis_filterf_mips(float *out,
+                                  const float *filter_coeffs,
+                                  const float* in, int buffer_length,
+                                  int filter_length)
+{
+    int i,n;
+
+    float out0, out1, out2, out3;
+    float old_out0, old_out1, old_out2, old_out3;
+    float a,b,c;
+    const float *p_filter_coeffs;
+    float *p_out;
+
+    a = filter_coeffs[0];
+    b = filter_coeffs[1];
+    c = filter_coeffs[2];
+    b -= filter_coeffs[0] * filter_coeffs[0];
+    c -= filter_coeffs[1] * filter_coeffs[0];
+    c -= filter_coeffs[0] * b;
+
+    old_out0 = out[-4];
+    old_out1 = out[-3];
+    old_out2 = out[-2];
+    old_out3 = out[-1];
+    for (n = 0; n <= buffer_length - 4; n+=4) {
+        p_filter_coeffs = filter_coeffs;
+        p_out = out;
+
+        out0 = in[0];
+        out1 = in[1];
+        out2 = in[2];
+        out3 = in[3];
+
+        __asm__ volatile(
+            "lwc1       $f2,     8(%[filter_coeffs])                        \n\t"
+            "lwc1       $f1,     4(%[filter_coeffs])                        \n\t"
+            "lwc1       $f0,     0(%[filter_coeffs])                        \n\t"
+            "nmsub.s    %[out0], %[out0],             $f2, %[old_out1]      \n\t"
+            "nmsub.s    %[out1], %[out1],             $f2, %[old_out2]      \n\t"
+            "nmsub.s    %[out2], %[out2],             $f2, %[old_out3]      \n\t"
+            "lwc1       $f3,     12(%[filter_coeffs])                       \n\t"
+            "nmsub.s    %[out0], %[out0],             $f1, %[old_out2]      \n\t"
+            "nmsub.s    %[out1], %[out1],             $f1, %[old_out3]      \n\t"
+            "nmsub.s    %[out2], %[out2],             $f3, %[old_out2]      \n\t"
+            "nmsub.s    %[out0], %[out0],             $f0, %[old_out3]      \n\t"
+            "nmsub.s    %[out3], %[out3],             $f3, %[old_out3]      \n\t"
+            "nmsub.s    %[out1], %[out1],             $f3, %[old_out1]      \n\t"
+            "nmsub.s    %[out0], %[out0],             $f3, %[old_out0]      \n\t"
+
+            : [out0]"+f"(out0), [out1]"+f"(out1),
+              [out2]"+f"(out2), [out3]"+f"(out3)
+            : [old_out0]"f"(old_out0), [old_out1]"f"(old_out1),
+              [old_out2]"f"(old_out2), [old_out3]"f"(old_out3),
+              [filter_coeffs]"r"(filter_coeffs)
+            : "$f0", "$f1", "$f2", "$f3", "$f4"
+        );
+
+        for (i = 5; i <= filter_length; i += 2) {
+            __asm__ volatile(
+                "lwc1    %[old_out3], -20(%[p_out])                         \n\t"
+                "lwc1    $f5,         16(%[p_filter_coeffs])                \n\t"
+                "addiu   %[p_out],    -8                                    \n\t"
+                "addiu   %[p_filter_coeffs], 8                              \n\t"
+                "nmsub.s %[out1],     %[out1],      $f5, %[old_out0]        \n\t"
+                "nmsub.s %[out3],     %[out3],      $f5, %[old_out2]        \n\t"
+                "lwc1    $f4,         12(%[p_filter_coeffs])                \n\t"
+                "lwc1    %[old_out2], -16(%[p_out])                         \n\t"
+                "nmsub.s %[out0],     %[out0],      $f5, %[old_out3]        \n\t"
+                "nmsub.s %[out2],     %[out2],      $f5, %[old_out1]        \n\t"
+                "nmsub.s %[out1],     %[out1],      $f4, %[old_out3]        \n\t"
+                "nmsub.s %[out3],     %[out3],      $f4, %[old_out1]        \n\t"
+                "mov.s   %[old_out1], %[old_out3]                           \n\t"
+                "nmsub.s %[out0],     %[out0],      $f4, %[old_out2]        \n\t"
+                "nmsub.s %[out2],     %[out2],      $f4, %[old_out0]        \n\t"
+
+                : [out0]"+f"(out0), [out1]"+f"(out1),
+                  [out2]"+f"(out2), [out3]"+f"(out3), [old_out0]"+f"(old_out0),
+                  [old_out1]"+f"(old_out1), [old_out2]"+f"(old_out2),
+                  [old_out3]"+f"(old_out3),[p_filter_coeffs]"+r"(p_filter_coeffs),
+                  [p_out]"+r"(p_out)
+                :
+                : "$f4", "$f5"
+            );
+            FFSWAP(float, old_out0, old_out2);
+        }
+
+        __asm__ volatile(
+            "nmsub.s    %[out3], %[out3], %[a], %[out2]                     \n\t"
+            "nmsub.s    %[out2], %[out2], %[a], %[out1]                     \n\t"
+            "nmsub.s    %[out3], %[out3], %[b], %[out1]                     \n\t"
+            "nmsub.s    %[out1], %[out1], %[a], %[out0]                     \n\t"
+            "nmsub.s    %[out2], %[out2], %[b], %[out0]                     \n\t"
+            "nmsub.s    %[out3], %[out3], %[c], %[out0]                     \n\t"
+
+            : [out0]"+f"(out0), [out1]"+f"(out1),
+              [out2]"+f"(out2), [out3]"+f"(out3)
+            : [a]"f"(a), [b]"f"(b), [c]"f"(c)
+        );
+
+        out[0] = out0;
+        out[1] = out1;
+        out[2] = out2;
+        out[3] = out3;
+
+        old_out0 = out0;
+        old_out1 = out1;
+        old_out2 = out2;
+        old_out3 = out3;
+
+        out += 4;
+        in  += 4;
+    }
+
+    out -= n;
+    in -= n;
+    for (; n < buffer_length; n++) {
+        float out_val, out_val_i, fc_val;
+        p_filter_coeffs = filter_coeffs;
+        p_out = &out[n];
+        out_val = in[n];
+        for (i = 1; i <= filter_length; i++) {
+            __asm__ volatile(
+                "lwc1    %[fc_val],          0(%[p_filter_coeffs])                        \n\t"
+                "lwc1    %[out_val_i],       -4(%[p_out])                                 \n\t"
+                "addiu   %[p_filter_coeffs], 4                                            \n\t"
+                "addiu   %[p_out],           -4                                           \n\t"
+                "nmsub.s %[out_val],         %[out_val],          %[fc_val], %[out_val_i] \n\t"
+
+                : [fc_val]"=&f"(fc_val), [out_val]"+f"(out_val),
+                  [out_val_i]"=&f"(out_val_i), [p_out]"+r"(p_out),
+                  [p_filter_coeffs]"+r"(p_filter_coeffs)
+            );
+        }
+        out[n] = out_val;
+    }
+}
+
+static void ff_celp_lp_zero_synthesis_filterf_mips(float *out,
+                                       const float *filter_coeffs,
+                                       const float *in, int buffer_length,
+                                       int filter_length)
+{
+    int i,n;
+    float sum_out8, sum_out7, sum_out6, sum_out5, sum_out4, fc_val;
+    float sum_out3, sum_out2, sum_out1;
+    const float *p_filter_coeffs, *p_in;
+
+    for (n = 0; n < buffer_length; n+=8) {
+        p_in = &in[n];
+        p_filter_coeffs = filter_coeffs;
+        sum_out8 = in[n+7];
+        sum_out7 = in[n+6];
+        sum_out6 = in[n+5];
+        sum_out5 = in[n+4];
+        sum_out4 = in[n+3];
+        sum_out3 = in[n+2];
+        sum_out2 = in[n+1];
+        sum_out1 = in[n];
+        i = filter_length;
+
+        /* i is always greater than 0
+        * outer loop is unrolled eight times so there is less memory access
+        * inner loop is unrolled two times
+        */
+        __asm__ volatile(
+            "filt_lp_inner%=:                                               \n\t"
+            "lwc1   %[fc_val],   0(%[p_filter_coeffs])                      \n\t"
+            "lwc1   $f7,         6*4(%[p_in])                               \n\t"
+            "lwc1   $f6,         5*4(%[p_in])                               \n\t"
+            "lwc1   $f5,         4*4(%[p_in])                               \n\t"
+            "lwc1   $f4,         3*4(%[p_in])                               \n\t"
+            "lwc1   $f3,         2*4(%[p_in])                               \n\t"
+            "lwc1   $f2,         4(%[p_in])                                 \n\t"
+            "lwc1   $f1,         0(%[p_in])                                 \n\t"
+            "lwc1   $f0,         -4(%[p_in])                                \n\t"
+            "addiu  %[i],        -2                                         \n\t"
+            "madd.s %[sum_out8], %[sum_out8],          %[fc_val], $f7       \n\t"
+            "madd.s %[sum_out7], %[sum_out7],          %[fc_val], $f6       \n\t"
+            "madd.s %[sum_out6], %[sum_out6],          %[fc_val], $f5       \n\t"
+            "madd.s %[sum_out5], %[sum_out5],          %[fc_val], $f4       \n\t"
+            "madd.s %[sum_out4], %[sum_out4],          %[fc_val], $f3       \n\t"
+            "madd.s %[sum_out3], %[sum_out3],          %[fc_val], $f2       \n\t"
+            "madd.s %[sum_out2], %[sum_out2],          %[fc_val], $f1       \n\t"
+            "madd.s %[sum_out1], %[sum_out1],          %[fc_val], $f0       \n\t"
+            "lwc1   %[fc_val],   4(%[p_filter_coeffs])                      \n\t"
+            "lwc1   $f7,         -8(%[p_in])                                \n\t"
+            "addiu  %[p_filter_coeffs], 8                                   \n\t"
+            "addiu  %[p_in],     -8                                         \n\t"
+            "madd.s %[sum_out8], %[sum_out8],          %[fc_val], $f6       \n\t"
+            "madd.s %[sum_out7], %[sum_out7],          %[fc_val], $f5       \n\t"
+            "madd.s %[sum_out6], %[sum_out6],          %[fc_val], $f4       \n\t"
+            "madd.s %[sum_out5], %[sum_out5],          %[fc_val], $f3       \n\t"
+            "madd.s %[sum_out4], %[sum_out4],          %[fc_val], $f2       \n\t"
+            "madd.s %[sum_out3], %[sum_out3],          %[fc_val], $f1       \n\t"
+            "madd.s %[sum_out2], %[sum_out2],          %[fc_val], $f0       \n\t"
+            "madd.s %[sum_out1], %[sum_out1],          %[fc_val], $f7       \n\t"
+            "bgtz   %[i],        filt_lp_inner%=                            \n\t"
+
+            : [sum_out8]"+f"(sum_out8), [sum_out7]"+f"(sum_out7),
+              [sum_out6]"+f"(sum_out6), [sum_out5]"+f"(sum_out5),
+              [sum_out4]"+f"(sum_out4), [sum_out3]"+f"(sum_out3),
+              [sum_out2]"+f"(sum_out2), [sum_out1]"+f"(sum_out1),
+              [fc_val]"=&f"(fc_val), [p_filter_coeffs]"+r"(p_filter_coeffs),
+              [p_in]"+r"(p_in), [i]"+r"(i)
+            :
+            : "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7"
+        );
+
+        out[n+7] = sum_out8;
+        out[n+6] = sum_out7;
+        out[n+5] = sum_out6;
+        out[n+4] = sum_out5;
+        out[n+3] = sum_out4;
+        out[n+2] = sum_out3;
+        out[n+1] = sum_out2;
+        out[n] = sum_out1;
+    }
+}
+
+void ff_celp_filter_init_mips(CELPFContext *c)
+{
+    c->celp_lp_synthesis_filterf        = ff_celp_lp_synthesis_filterf_mips;
+    c->celp_lp_zero_synthesis_filterf   = ff_celp_lp_zero_synthesis_filterf_mips;
+}
diff --git a/libavcodec/mips/celp_math_mips.c b/libavcodec/mips/celp_math_mips.c
new file mode 100644
index 0000000..6ab1823
--- /dev/null
+++ b/libavcodec/mips/celp_math_mips.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Nedeljko Babic (nbabic@mips.com)
+ *
+ * Math operations 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/celp_math.c
+ */
+#include "libavcodec/celp_math.h"
+
+static float ff_dot_productf_mips(const float* a, const float* b,
+                                              int length)
+{
+    float sum;
+    const float* a_end = a + length;
+
+    __asm__ volatile (
+        "mtc1   $zero,      %[sum]                              \n\t"
+        "blez   %[length],  ff_dot_productf_end%=               \n\t"
+        "ff_dot_productf_madd%=:                                \n\t"
+        "lwc1   $f2,        0(%[a])                             \n\t"
+        "lwc1   $f1,        0(%[b])                             \n\t"
+        "addiu  %[a],       %[a],      4                        \n\t"
+        "addiu  %[b],       %[b],      4                        \n\t"
+        "madd.s %[sum],     %[sum],    $f1, $f2                 \n\t"
+        "bne   %[a],        %[a_end],  ff_dot_productf_madd%=   \n\t"
+        "ff_dot_productf_end%=:                                 \n\t"
+
+        : [sum] "=&f" (sum), [a] "+r" (a), [b] "+r" (b)
+        : [a_end]"r"(a_end), [length] "r" (length)
+        : "$f1", "$f2"
+    );
+    return sum;
+}
+
+void ff_celp_math_init_mips(CELPMContext *c)
+{
+    c->dot_productf = ff_dot_productf_mips;
+}
diff --git a/libavcodec/mips/compute_antialias_fixed.h b/libavcodec/mips/compute_antialias_fixed.h
new file mode 100644
index 0000000..528411f
--- /dev/null
+++ b/libavcodec/mips/compute_antialias_fixed.h
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Bojan Zivkovic (bojan@mips.com)
+ *
+ * Compute antialias function optimised for MIPS fixed-point architecture
+ *
+ * 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/mpegaudiodec.c
+ */
+
+#ifndef AVCODEC_MIPS_COMPUTE_ANTIALIAS_FIXED_H
+#define AVCODEC_MIPS_COMPUTE_ANTIALIAS_FIXED_H
+
+static void compute_antialias_mips_fixed(MPADecodeContext *s,
+                                        GranuleDef *g)
+{
+    int32_t *ptr, *csa;
+    int n, i;
+    int MAX_lo = 0xffffffff;
+
+    /* we antialias only "long" bands */
+    if (g->block_type == 2) {
+        if (!g->switch_point)
+            return;
+        /* XXX: check this for 8000Hz case */
+        n = 1;
+    } else {
+        n = SBLIMIT - 1;
+    }
+
+
+    ptr = g->sb_hybrid + 18;
+
+    for(i = n;i > 0;i--) {
+        int tmp0, tmp1, tmp2, tmp00, tmp11;
+        int temp_reg1, temp_reg2, temp_reg3, temp_reg4, temp_reg5, temp_reg6;
+        csa = &csa_table[0][0];
+
+        /**
+         * instructions are scheduled to minimize pipeline stall.
+         */
+        __asm__ volatile (
+            "lw   %[tmp0],      -1*4(%[ptr])                            \n\t"
+            "lw   %[tmp1],      0*4(%[ptr])                             \n\t"
+            "lw   %[temp_reg1], 0*4(%[csa])                             \n\t"
+            "lw   %[temp_reg2], 2*4(%[csa])                             \n\t"
+            "add  %[tmp2],      %[tmp0],      %[tmp1]                   \n\t"
+            "lw   %[temp_reg3], 3*4(%[csa])                             \n\t"
+            "mult $ac0,         %[tmp2],      %[temp_reg1]              \n\t"
+            "mult $ac1,         %[tmp2],      %[temp_reg1]              \n\t"
+            "lw   %[tmp00],     -2*4(%[ptr])                            \n\t"
+            "lw   %[tmp11],     1*4(%[ptr])                             \n\t"
+            "lw   %[temp_reg4], 4*4(%[csa])                             \n\t"
+            "mtlo %[MAX_lo],    $ac0                                    \n\t"
+            "mtlo $zero,        $ac1                                    \n\t"
+            "msub $ac0,         %[tmp1],      %[temp_reg2]              \n\t"
+            "madd $ac1,         %[tmp0],      %[temp_reg3]              \n\t"
+            "add  %[tmp2],      %[tmp00],     %[tmp11]                  \n\t"
+            "lw   %[temp_reg5], 6*4(%[csa])                             \n\t"
+            "mult $ac2,         %[tmp2],      %[temp_reg4]              \n\t"
+            "mult $ac3,         %[tmp2],      %[temp_reg4]              \n\t"
+            "mfhi %[temp_reg1], $ac0                                    \n\t"
+            "mfhi %[temp_reg2], $ac1                                    \n\t"
+            "lw   %[temp_reg6], 7*4(%[csa])                             \n\t"
+            "mtlo %[MAX_lo],    $ac2                                    \n\t"
+            "msub $ac2,         %[tmp11],     %[temp_reg5]              \n\t"
+            "mtlo $zero,        $ac3                                    \n\t"
+            "madd $ac3,         %[tmp00],     %[temp_reg6]              \n\t"
+            "sll  %[temp_reg1], %[temp_reg1], 2                         \n\t"
+            "sw   %[temp_reg1], -1*4(%[ptr])                            \n\t"
+            "mfhi %[temp_reg4], $ac2                                    \n\t"
+            "sll  %[temp_reg2], %[temp_reg2], 2                         \n\t"
+            "mfhi %[temp_reg5], $ac3                                    \n\t"
+            "sw   %[temp_reg2], 0*4(%[ptr])                             \n\t"
+            "lw   %[tmp0],      -3*4(%[ptr])                            \n\t"
+            "lw   %[tmp1],      2*4(%[ptr])                             \n\t"
+            "lw   %[temp_reg1], 8*4(%[csa])                             \n\t"
+            "sll  %[temp_reg4], %[temp_reg4], 2                         \n\t"
+            "add  %[tmp2],      %[tmp0],      %[tmp1]                   \n\t"
+            "sll  %[temp_reg5], %[temp_reg5], 2                         \n\t"
+            "mult $ac0,         %[tmp2],      %[temp_reg1]              \n\t"
+            "mult $ac1,         %[tmp2],      %[temp_reg1]              \n\t"
+            "sw   %[temp_reg4], -2*4(%[ptr])                            \n\t"
+            "sw   %[temp_reg5], 1*4(%[ptr])                             \n\t"
+            "lw   %[temp_reg2], 10*4(%[csa])                            \n\t"
+            "mtlo %[MAX_lo],    $ac0                                    \n\t"
+            "lw   %[temp_reg3], 11*4(%[csa])                            \n\t"
+            "msub $ac0,         %[tmp1],      %[temp_reg2]              \n\t"
+            "mtlo $zero,        $ac1                                    \n\t"
+            "madd $ac1,         %[tmp0],      %[temp_reg3]              \n\t"
+            "lw   %[tmp00],     -4*4(%[ptr])                            \n\t"
+            "lw   %[tmp11],     3*4(%[ptr])                             \n\t"
+            "mfhi %[temp_reg1], $ac0                                    \n\t"
+            "lw   %[temp_reg4], 12*4(%[csa])                            \n\t"
+            "mfhi %[temp_reg2], $ac1                                    \n\t"
+            "add  %[tmp2],      %[tmp00],     %[tmp11]                  \n\t"
+            "mult $ac2,         %[tmp2],      %[temp_reg4]              \n\t"
+            "mult $ac3,         %[tmp2],      %[temp_reg4]              \n\t"
+            "lw   %[temp_reg5], 14*4(%[csa])                            \n\t"
+            "lw   %[temp_reg6], 15*4(%[csa])                            \n\t"
+            "sll  %[temp_reg1], %[temp_reg1], 2                         \n\t"
+            "mtlo %[MAX_lo],    $ac2                                    \n\t"
+            "msub $ac2,         %[tmp11],     %[temp_reg5]              \n\t"
+            "mtlo $zero,        $ac3                                    \n\t"
+            "madd $ac3,         %[tmp00],     %[temp_reg6]              \n\t"
+            "sll  %[temp_reg2], %[temp_reg2], 2                         \n\t"
+            "sw   %[temp_reg1], -3*4(%[ptr])                            \n\t"
+            "mfhi %[temp_reg4], $ac2                                    \n\t"
+            "sw   %[temp_reg2], 2*4(%[ptr])                             \n\t"
+            "mfhi %[temp_reg5], $ac3                                    \n\t"
+            "lw   %[tmp0],      -5*4(%[ptr])                            \n\t"
+            "lw   %[tmp1],      4*4(%[ptr])                             \n\t"
+            "lw   %[temp_reg1], 16*4(%[csa])                            \n\t"
+            "lw   %[temp_reg2], 18*4(%[csa])                            \n\t"
+            "add  %[tmp2],      %[tmp0],      %[tmp1]                   \n\t"
+            "lw   %[temp_reg3], 19*4(%[csa])                            \n\t"
+            "mult $ac0,         %[tmp2],      %[temp_reg1]              \n\t"
+            "mult $ac1,         %[tmp2],      %[temp_reg1]              \n\t"
+            "sll  %[temp_reg4], %[temp_reg4], 2                         \n\t"
+            "sll  %[temp_reg5], %[temp_reg5], 2                         \n\t"
+            "sw   %[temp_reg4], -4*4(%[ptr])                            \n\t"
+            "mtlo %[MAX_lo],    $ac0                                    \n\t"
+            "msub $ac0,         %[tmp1],      %[temp_reg2]              \n\t"
+            "mtlo $zero,        $ac1                                    \n\t"
+            "madd $ac1,         %[tmp0],      %[temp_reg3]              \n\t"
+            "sw   %[temp_reg5], 3*4(%[ptr])                             \n\t"
+            "lw   %[tmp00],     -6*4(%[ptr])                            \n\t"
+            "mfhi %[temp_reg1], $ac0                                    \n\t"
+            "lw   %[tmp11],     5*4(%[ptr])                             \n\t"
+            "mfhi %[temp_reg2], $ac1                                    \n\t"
+            "lw   %[temp_reg4], 20*4(%[csa])                            \n\t"
+            "add  %[tmp2],      %[tmp00],     %[tmp11]                  \n\t"
+            "lw   %[temp_reg5], 22*4(%[csa])                            \n\t"
+            "mult $ac2,         %[tmp2],      %[temp_reg4]              \n\t"
+            "mult $ac3,         %[tmp2],      %[temp_reg4]              \n\t"
+            "lw   %[temp_reg6], 23*4(%[csa])                            \n\t"
+            "sll  %[temp_reg1], %[temp_reg1], 2                         \n\t"
+            "sll  %[temp_reg2], %[temp_reg2], 2                         \n\t"
+            "mtlo %[MAX_lo],    $ac2                                    \n\t"
+            "msub $ac2,         %[tmp11],     %[temp_reg5]              \n\t"
+            "mtlo $zero,        $ac3                                    \n\t"
+            "madd $ac3,         %[tmp00],     %[temp_reg6]              \n\t"
+            "sw   %[temp_reg1], -5*4(%[ptr])                            \n\t"
+            "sw   %[temp_reg2], 4*4(%[ptr])                             \n\t"
+            "mfhi %[temp_reg4], $ac2                                    \n\t"
+            "lw   %[tmp0],      -7*4(%[ptr])                            \n\t"
+            "mfhi %[temp_reg5], $ac3                                    \n\t"
+            "lw   %[tmp1],      6*4(%[ptr])                             \n\t"
+            "lw   %[temp_reg1], 24*4(%[csa])                            \n\t"
+            "lw   %[temp_reg2], 26*4(%[csa])                            \n\t"
+            "add  %[tmp2],      %[tmp0],      %[tmp1]                   \n\t"
+            "lw   %[temp_reg3], 27*4(%[csa])                            \n\t"
+            "mult $ac0,         %[tmp2],      %[temp_reg1]              \n\t"
+            "mult $ac1,         %[tmp2],      %[temp_reg1]              \n\t"
+            "sll  %[temp_reg4], %[temp_reg4], 2                         \n\t"
+            "sll  %[temp_reg5], %[temp_reg5], 2                         \n\t"
+            "sw   %[temp_reg4], -6*4(%[ptr])                            \n\t"
+            "mtlo %[MAX_lo],    $ac0                                    \n\t"
+            "msub $ac0,         %[tmp1],      %[temp_reg2]              \n\t"
+            "mtlo $zero,        $ac1                                    \n\t"
+            "madd $ac1,         %[tmp0],      %[temp_reg3]              \n\t"
+            "sw   %[temp_reg5], 5*4(%[ptr])                             \n\t"
+            "lw   %[tmp00],     -8*4(%[ptr])                            \n\t"
+            "mfhi %[temp_reg1], $ac0                                    \n\t"
+            "lw   %[tmp11],     7*4(%[ptr])                             \n\t"
+            "mfhi %[temp_reg2], $ac1                                    \n\t"
+            "lw   %[temp_reg4], 28*4(%[csa])                            \n\t"
+            "add  %[tmp2],      %[tmp00],     %[tmp11]                  \n\t"
+            "lw   %[temp_reg5], 30*4(%[csa])                            \n\t"
+            "mult $ac2,         %[tmp2],      %[temp_reg4]              \n\t"
+            "mult $ac3,         %[tmp2],      %[temp_reg4]              \n\t"
+            "lw   %[temp_reg6], 31*4(%[csa])                            \n\t"
+            "sll  %[temp_reg1], %[temp_reg1], 2                         \n\t"
+            "sll  %[temp_reg2], %[temp_reg2], 2                         \n\t"
+            "mtlo %[MAX_lo],    $ac2                                    \n\t"
+            "msub $ac2,         %[tmp11],     %[temp_reg5]              \n\t"
+            "mtlo $zero,        $ac3                                    \n\t"
+            "madd $ac3,         %[tmp00],     %[temp_reg6]              \n\t"
+            "sw   %[temp_reg1], -7*4(%[ptr])                            \n\t"
+            "sw   %[temp_reg2], 6*4(%[ptr])                             \n\t"
+            "mfhi %[temp_reg4], $ac2                                    \n\t"
+            "mfhi %[temp_reg5], $ac3                                    \n\t"
+            "sll  %[temp_reg4], %[temp_reg4], 2                         \n\t"
+            "sll  %[temp_reg5], %[temp_reg5], 2                         \n\t"
+            "sw   %[temp_reg4], -8*4(%[ptr])                            \n\t"
+            "sw   %[temp_reg5], 7*4(%[ptr])                             \n\t"
+
+            : [tmp0] "=&r" (tmp0), [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2),
+              [tmp00] "=&r" (tmp00), [tmp11] "=&r" (tmp11),
+              [temp_reg1] "=&r" (temp_reg1), [temp_reg2] "=&r" (temp_reg2),
+              [temp_reg3] "=&r" (temp_reg3), [temp_reg4] "=&r" (temp_reg4),
+              [temp_reg5] "=&r" (temp_reg5), [temp_reg6] "=&r" (temp_reg6)
+            : [csa] "r" (csa), [ptr] "r" (ptr),
+              [MAX_lo] "r" (MAX_lo)
+         );
+
+        ptr += 18;
+    }
+}
+#define compute_antialias compute_antialias_mips_fixed
+
+#endif /* AVCODEC_MIPS_COMPUTE_ANTIALIAS_FIXED_H */
diff --git a/libavcodec/mips/compute_antialias_float.h b/libavcodec/mips/compute_antialias_float.h
new file mode 100644
index 0000000..3a3f5d6
--- /dev/null
+++ b/libavcodec/mips/compute_antialias_float.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Bojan Zivkovic (bojan@mips.com)
+ *
+ * Compute antialias function optimised for MIPS floating-point architecture
+ *
+ * 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/mpegaudiodec.c
+ */
+
+#ifndef AVCODEC_MIPS_COMPUTE_ANTIALIAS_FLOAT_H
+#define AVCODEC_MIPS_COMPUTE_ANTIALIAS_FLOAT_H
+
+static void compute_antialias_mips_float(MPADecodeContext *s,
+                                        GranuleDef *g)
+{
+    float *ptr, *ptr_end;
+    float *csa = &csa_table[0][0];
+    int n;
+    /* temporary variables */
+    float in1, in2, in3, in4, in5, in6, in7, in8;
+    float out1, out2, out3, out4;
+
+    ptr = g->sb_hybrid + 18;
+    /* we antialias only "long" bands */
+    if (g->block_type == 2) {
+        if (!g->switch_point)
+            return;
+        /* XXX: check this for 8000Hz case */
+        n = 1;
+        ptr_end = ptr + 18;
+    } else {
+        n = 31;
+        ptr_end = ptr + 558;
+    }
+
+    /**
+    * instructions are scheduled to minimize pipeline stall.
+    */
+
+    __asm__ volatile (
+        "compute_antialias_float_loop%=:                                \t\n"
+        "lwc1    %[in1],  -1*4(%[ptr])                                  \t\n"
+        "lwc1    %[in2],  0(%[csa])                                     \t\n"
+        "lwc1    %[in3],  1*4(%[csa])                                   \t\n"
+        "lwc1    %[in4],  0(%[ptr])                                     \t\n"
+        "lwc1    %[in5],  -2*4(%[ptr])                                  \t\n"
+        "lwc1    %[in6],  4*4(%[csa])                                   \t\n"
+        "mul.s   %[out1], %[in1],  %[in2]                               \t\n"
+        "mul.s   %[out2], %[in1],  %[in3]                               \t\n"
+        "lwc1    %[in7],  5*4(%[csa])                                   \t\n"
+        "lwc1    %[in8],  1*4(%[ptr])                                   \t\n"
+        "nmsub.s %[out1], %[out1], %[in3], %[in4]                       \t\n"
+        "madd.s  %[out2], %[out2], %[in2], %[in4]                       \t\n"
+        "mul.s   %[out3], %[in5],  %[in6]                               \t\n"
+        "mul.s   %[out4], %[in5],  %[in7]                               \t\n"
+        "lwc1    %[in1],  -3*4(%[ptr])                                  \t\n"
+        "swc1    %[out1], -1*4(%[ptr])                                  \t\n"
+        "swc1    %[out2], 0(%[ptr])                                     \t\n"
+        "nmsub.s %[out3], %[out3], %[in7], %[in8]                       \t\n"
+        "madd.s  %[out4], %[out4], %[in6], %[in8]                       \t\n"
+        "lwc1    %[in2],  8*4(%[csa])                                   \t\n"
+        "swc1    %[out3], -2*4(%[ptr])                                  \t\n"
+        "swc1    %[out4], 1*4(%[ptr])                                   \t\n"
+        "lwc1    %[in3],  9*4(%[csa])                                   \t\n"
+        "lwc1    %[in4],  2*4(%[ptr])                                   \t\n"
+        "mul.s   %[out1], %[in1],  %[in2]                               \t\n"
+        "lwc1    %[in5],  -4*4(%[ptr])                                  \t\n"
+        "lwc1    %[in6],  12*4(%[csa])                                  \t\n"
+        "mul.s   %[out2], %[in1],  %[in3]                               \t\n"
+        "lwc1    %[in7],  13*4(%[csa])                                  \t\n"
+        "nmsub.s %[out1], %[out1], %[in3], %[in4]                       \t\n"
+        "lwc1    %[in8],  3*4(%[ptr])                                   \t\n"
+        "mul.s   %[out3], %[in5],  %[in6]                               \t\n"
+        "madd.s  %[out2], %[out2], %[in2], %[in4]                       \t\n"
+        "mul.s   %[out4], %[in5],  %[in7]                               \t\n"
+        "swc1    %[out1], -3*4(%[ptr])                                  \t\n"
+        "lwc1    %[in1],  -5*4(%[ptr])                                  \t\n"
+        "nmsub.s %[out3], %[out3], %[in7], %[in8]                       \t\n"
+        "swc1    %[out2], 2*4(%[ptr])                                   \t\n"
+        "madd.s  %[out4], %[out4], %[in6], %[in8]                       \t\n"
+        "lwc1    %[in2],  16*4(%[csa])                                  \t\n"
+        "lwc1    %[in3],  17*4(%[csa])                                  \t\n"
+        "swc1    %[out3], -4*4(%[ptr])                                  \t\n"
+        "lwc1    %[in4],  4*4(%[ptr])                                   \t\n"
+        "swc1    %[out4], 3*4(%[ptr])                                   \t\n"
+        "mul.s   %[out1], %[in1],  %[in2]                               \t\n"
+        "mul.s   %[out2], %[in1],  %[in3]                               \t\n"
+        "lwc1    %[in5],  -6*4(%[ptr])                                  \t\n"
+        "lwc1    %[in6],  20*4(%[csa])                                  \t\n"
+        "lwc1    %[in7],  21*4(%[csa])                                  \t\n"
+        "nmsub.s %[out1], %[out1], %[in3], %[in4]                       \t\n"
+        "madd.s  %[out2], %[out2], %[in2], %[in4]                       \t\n"
+        "lwc1    %[in8],  5*4(%[ptr])                                   \t\n"
+        "mul.s   %[out3], %[in5],  %[in6]                               \t\n"
+        "mul.s   %[out4], %[in5],  %[in7]                               \t\n"
+        "swc1    %[out1], -5*4(%[ptr])                                  \t\n"
+        "swc1    %[out2], 4*4(%[ptr])                                   \t\n"
+        "lwc1    %[in1],  -7*4(%[ptr])                                  \t\n"
+        "nmsub.s %[out3], %[out3], %[in7], %[in8]                       \t\n"
+        "madd.s  %[out4], %[out4], %[in6], %[in8]                       \t\n"
+        "lwc1    %[in2],  24*4(%[csa])                                  \t\n"
+        "lwc1    %[in3],  25*4(%[csa])                                  \t\n"
+        "lwc1    %[in4],  6*4(%[ptr])                                   \t\n"
+        "swc1    %[out3], -6*4(%[ptr])                                  \t\n"
+        "swc1    %[out4], 5*4(%[ptr])                                   \t\n"
+        "mul.s   %[out1], %[in1],  %[in2]                               \t\n"
+        "lwc1    %[in5],  -8*4(%[ptr])                                  \t\n"
+        "mul.s   %[out2], %[in1],  %[in3]                               \t\n"
+        "lwc1    %[in6],  28*4(%[csa])                                  \t\n"
+        "lwc1    %[in7],  29*4(%[csa])                                  \t\n"
+        "nmsub.s %[out1], %[out1], %[in3], %[in4]                       \t\n"
+        "lwc1    %[in8],  7*4(%[ptr])                                   \t\n"
+        "madd.s  %[out2], %[out2], %[in2], %[in4]                       \t\n"
+        "mul.s   %[out3], %[in5],  %[in6]                               \t\n"
+        "mul.s   %[out4], %[in5],  %[in7]                               \t\n"
+        "swc1    %[out1], -7*4(%[ptr])                                  \t\n"
+        "swc1    %[out2], 6*4(%[ptr])                                   \t\n"
+        "addiu   %[ptr],  %[ptr],  72                                   \t\n"
+        "nmsub.s %[out3], %[out3], %[in7], %[in8]                       \t\n"
+        "madd.s  %[out4], %[out4], %[in6], %[in8]                       \t\n"
+        "swc1    %[out3], -26*4(%[ptr])                                 \t\n"
+        "swc1    %[out4], -11*4(%[ptr])                                 \t\n"
+        "bne     %[ptr],  %[ptr_end],  compute_antialias_float_loop%=   \t\n"
+
+        : [ptr] "+r" (ptr),
+          [in1] "=&f" (in1), [in2] "=&f" (in2),
+          [in3] "=&f" (in3), [in4] "=&f" (in4),
+          [in5] "=&f" (in5), [in6] "=&f" (in6),
+          [in7] "=&f" (in7), [in8] "=&f" (in8),
+          [out1] "=&f" (out1), [out2] "=&f" (out2),
+          [out3] "=&f" (out3), [out4] "=&f" (out4)
+        : [csa] "r" (csa), [ptr_end] "r" (ptr_end)
+    );
+}
+#define compute_antialias compute_antialias_mips_float
+
+#endif /* AVCODEC_MIPS_COMPUTE_ANTIALIAS_FLOAT_H */
diff --git a/libavcodec/mips/dsputil_mips.c b/libavcodec/mips/dsputil_mips.c
new file mode 100644
index 0000000..e46a0a9
--- /dev/null
+++ b/libavcodec/mips/dsputil_mips.c
@@ -0,0 +1,164 @@
+/*
+ * 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"
+
+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"
+        );
+    }
+}
+
+av_cold void ff_dsputil_init_mips( DSPContext* c, AVCodecContext *avctx )
+{
+    c->vector_fmul_window = vector_fmul_window_mips;
+}
diff --git a/libavcodec/mips/dsputil_mmi.c b/libavcodec/mips/dsputil_mmi.c
index ba044cf..a1e1f6b 100644
--- a/libavcodec/mips/dsputil_mmi.c
+++ b/libavcodec/mips/dsputil_mmi.c
@@ -5,20 +5,20 @@
  * MMI optimization by Leon van Stuivenberg
  * clear_blocks_mmi() by BroadQ
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mips/fft_init_table.c b/libavcodec/mips/fft_init_table.c
new file mode 100644
index 0000000..9c2e998
--- /dev/null
+++ b/libavcodec/mips/fft_init_table.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Stanislav Ocovaj (socovaj@mips.com)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * definitions and initialization of LUT table for MIPS FFT
+ */
+#include "fft_table.h"
+
+uint16_t fft_offsets_lut[0x2aab];
+
+void ff_fft_lut_init(uint16_t *table, int off, int size, int *index)
+{
+    if (size < 16) {
+        table[*index] = off >> 2;
+        (*index)++;
+    }
+    else {
+        ff_fft_lut_init(table, off, size>>1, index);
+        ff_fft_lut_init(table, off+(size>>1), size>>2, index);
+        ff_fft_lut_init(table, off+3*(size>>2), size>>2, index);
+    }
+}
diff --git a/libavcodec/mips/fft_mips.c b/libavcodec/mips/fft_mips.c
new file mode 100644
index 0000000..2b1c508
--- /dev/null
+++ b/libavcodec/mips/fft_mips.c
@@ -0,0 +1,530 @@
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Stanislav Ocovaj (socovaj@mips.com)
+ * Author:  Zoran Lukic (zoranl@mips.com)
+ *
+ * Optimized MDCT/IMDCT and FFT transforms
+ *
+ * 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/fft.h"
+#include "fft_table.h"
+
+/**
+ * FFT transform
+ */
+
+#if HAVE_INLINE_ASM
+static void ff_fft_calc_mips(FFTContext *s, FFTComplex *z)
+{
+    int nbits, i, n, num_transforms, offset, step;
+    int n4, n2, n34;
+    FFTSample tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
+    FFTComplex *tmpz;
+    float w_re, w_im;
+    float *w_re_ptr, *w_im_ptr;
+    const int fft_size = (1 << s->nbits);
+    int s_n = s->nbits;
+    int tem1, tem2;
+    float pom,  pom1,  pom2,  pom3;
+    float temp, temp1, temp3, temp4;
+    FFTComplex * tmpz_n2, * tmpz_n34, * tmpz_n4;
+    FFTComplex * tmpz_n2_i, * tmpz_n34_i, * tmpz_n4_i, * tmpz_i;
+
+    /**
+    *num_transforms = (0x2aab >> (16 - s->nbits)) | 1;
+    */
+    __asm__ volatile (
+        "li   %[tem1], 16                                      \n\t"
+        "sub  %[s_n],  %[tem1], %[s_n]                         \n\t"
+        "li   %[tem2], 10923                                   \n\t"
+        "srav %[tem2], %[tem2], %[s_n]                         \n\t"
+        "ori  %[num_t],%[tem2], 1                              \n\t"
+        : [num_t]"=r"(num_transforms), [s_n]"+r"(s_n),
+          [tem1]"=&r"(tem1), [tem2]"=&r"(tem2)
+    );
+
+
+    for (n=0; n<num_transforms; n++) {
+        offset = fft_offsets_lut[n] << 2;
+        tmpz = z + offset;
+
+        tmp1 = tmpz[0].re + tmpz[1].re;
+        tmp5 = tmpz[2].re + tmpz[3].re;
+        tmp2 = tmpz[0].im + tmpz[1].im;
+        tmp6 = tmpz[2].im + tmpz[3].im;
+        tmp3 = tmpz[0].re - tmpz[1].re;
+        tmp8 = tmpz[2].im - tmpz[3].im;
+        tmp4 = tmpz[0].im - tmpz[1].im;
+        tmp7 = tmpz[2].re - tmpz[3].re;
+
+        tmpz[0].re = tmp1 + tmp5;
+        tmpz[2].re = tmp1 - tmp5;
+        tmpz[0].im = tmp2 + tmp6;
+        tmpz[2].im = tmp2 - tmp6;
+        tmpz[1].re = tmp3 + tmp8;
+        tmpz[3].re = tmp3 - tmp8;
+        tmpz[1].im = tmp4 - tmp7;
+        tmpz[3].im = tmp4 + tmp7;
+
+    }
+
+    if (fft_size < 8)
+        return;
+
+    num_transforms = (num_transforms >> 1) | 1;
+
+    for (n=0; n<num_transforms; n++) {
+        offset = fft_offsets_lut[n] << 3;
+        tmpz = z + offset;
+
+        __asm__ volatile (
+            "lwc1  %[tmp1], 32(%[tmpz])                     \n\t"
+            "lwc1  %[pom],  40(%[tmpz])                     \n\t"
+            "lwc1  %[tmp3], 48(%[tmpz])                     \n\t"
+            "lwc1  %[pom1], 56(%[tmpz])                     \n\t"
+            "lwc1  %[tmp2], 36(%[tmpz])                     \n\t"
+            "lwc1  %[pom2], 44(%[tmpz])                     \n\t"
+            "lwc1  %[pom3], 60(%[tmpz])                     \n\t"
+            "lwc1  %[tmp4], 52(%[tmpz])                     \n\t"
+            "add.s %[tmp1], %[tmp1],    %[pom]              \n\t"  // tmp1 = tmpz[4].re + tmpz[5].re;
+            "add.s %[tmp3], %[tmp3],    %[pom1]             \n\t"  // tmp3 = tmpz[6].re + tmpz[7].re;
+            "add.s %[tmp2], %[tmp2],    %[pom2]             \n\t"  // tmp2 = tmpz[4].im + tmpz[5].im;
+            "lwc1  %[pom],  40(%[tmpz])                     \n\t"
+            "add.s %[tmp4], %[tmp4],    %[pom3]             \n\t"  // tmp4 = tmpz[6].im + tmpz[7].im;
+            "add.s %[tmp5], %[tmp1],    %[tmp3]             \n\t"  // tmp5 = tmp1 + tmp3;
+            "sub.s %[tmp7], %[tmp1],    %[tmp3]             \n\t"  // tmp7 = tmp1 - tmp3;
+            "lwc1  %[tmp1], 32(%[tmpz])                     \n\t"
+            "lwc1  %[pom1], 44(%[tmpz])                     \n\t"
+            "add.s %[tmp6], %[tmp2],    %[tmp4]             \n\t"  // tmp6 = tmp2 + tmp4;
+            "sub.s %[tmp8], %[tmp2],    %[tmp4]             \n\t"  // tmp8 = tmp2 - tmp4;
+            "lwc1  %[tmp2], 36(%[tmpz])                     \n\t"
+            "lwc1  %[pom2], 56(%[tmpz])                     \n\t"
+            "lwc1  %[pom3], 60(%[tmpz])                     \n\t"
+            "lwc1  %[tmp3], 48(%[tmpz])                     \n\t"
+            "lwc1  %[tmp4], 52(%[tmpz])                     \n\t"
+            "sub.s %[tmp1], %[tmp1],    %[pom]              \n\t"  // tmp1 = tmpz[4].re - tmpz[5].re;
+            "lwc1  %[pom],  0(%[tmpz])                      \n\t"
+            "sub.s %[tmp2], %[tmp2],    %[pom1]             \n\t"  // tmp2 = tmpz[4].im - tmpz[5].im;
+            "sub.s %[tmp3], %[tmp3],    %[pom2]             \n\t"  // tmp3 = tmpz[6].re - tmpz[7].re;
+            "lwc1  %[pom2], 4(%[tmpz])                      \n\t"
+            "sub.s %[pom1], %[pom],     %[tmp5]             \n\t"
+            "sub.s %[tmp4], %[tmp4],    %[pom3]             \n\t"  // tmp4 = tmpz[6].im - tmpz[7].im;
+            "add.s %[pom3], %[pom],     %[tmp5]             \n\t"
+            "sub.s %[pom],  %[pom2],    %[tmp6]             \n\t"
+            "add.s %[pom2], %[pom2],    %[tmp6]             \n\t"
+            "swc1  %[pom1], 32(%[tmpz])                     \n\t"  // tmpz[4].re = tmpz[0].re - tmp5;
+            "swc1  %[pom3], 0(%[tmpz])                      \n\t"  // tmpz[0].re = tmpz[0].re + tmp5;
+            "swc1  %[pom],  36(%[tmpz])                     \n\t"  // tmpz[4].im = tmpz[0].im - tmp6;
+            "swc1  %[pom2], 4(%[tmpz])                      \n\t"  // tmpz[0].im = tmpz[0].im + tmp6;
+            "lwc1  %[pom1], 16(%[tmpz])                     \n\t"
+            "lwc1  %[pom3], 20(%[tmpz])                     \n\t"
+            "li.s  %[pom],  0.7071067812                    \n\t"  // float pom = 0.7071067812f;
+            "add.s %[temp1],%[tmp1],    %[tmp2]             \n\t"
+            "sub.s %[temp], %[pom1],    %[tmp8]             \n\t"
+            "add.s %[pom2], %[pom3],    %[tmp7]             \n\t"
+            "sub.s %[temp3],%[tmp3],    %[tmp4]             \n\t"
+            "sub.s %[temp4],%[tmp2],    %[tmp1]             \n\t"
+            "swc1  %[temp], 48(%[tmpz])                     \n\t"  // tmpz[6].re = tmpz[2].re - tmp8;
+            "swc1  %[pom2], 52(%[tmpz])                     \n\t"  // tmpz[6].im = tmpz[2].im + tmp7;
+            "add.s %[pom1], %[pom1],    %[tmp8]             \n\t"
+            "sub.s %[pom3], %[pom3],    %[tmp7]             \n\t"
+            "add.s %[tmp3], %[tmp3],    %[tmp4]             \n\t"
+            "mul.s %[tmp5], %[pom],     %[temp1]            \n\t"  // tmp5 = pom * (tmp1 + tmp2);
+            "mul.s %[tmp7], %[pom],     %[temp3]            \n\t"  // tmp7 = pom * (tmp3 - tmp4);
+            "mul.s %[tmp6], %[pom],     %[temp4]            \n\t"  // tmp6 = pom * (tmp2 - tmp1);
+            "mul.s %[tmp8], %[pom],     %[tmp3]             \n\t"  // tmp8 = pom * (tmp3 + tmp4);
+            "swc1  %[pom1], 16(%[tmpz])                     \n\t"  // tmpz[2].re = tmpz[2].re + tmp8;
+            "swc1  %[pom3], 20(%[tmpz])                     \n\t"  // tmpz[2].im = tmpz[2].im - tmp7;
+            "add.s %[tmp1], %[tmp5],    %[tmp7]             \n\t"  // tmp1 = tmp5 + tmp7;
+            "sub.s %[tmp3], %[tmp5],    %[tmp7]             \n\t"  // tmp3 = tmp5 - tmp7;
+            "add.s %[tmp2], %[tmp6],    %[tmp8]             \n\t"  // tmp2 = tmp6 + tmp8;
+            "sub.s %[tmp4], %[tmp6],    %[tmp8]             \n\t"  // tmp4 = tmp6 - tmp8;
+            "lwc1  %[temp], 8(%[tmpz])                      \n\t"
+            "lwc1  %[temp1],12(%[tmpz])                     \n\t"
+            "lwc1  %[pom],  24(%[tmpz])                     \n\t"
+            "lwc1  %[pom2], 28(%[tmpz])                     \n\t"
+            "sub.s %[temp4],%[temp],    %[tmp1]             \n\t"
+            "sub.s %[temp3],%[temp1],   %[tmp2]             \n\t"
+            "add.s %[temp], %[temp],    %[tmp1]             \n\t"
+            "add.s %[temp1],%[temp1],   %[tmp2]             \n\t"
+            "sub.s %[pom1], %[pom],     %[tmp4]             \n\t"
+            "add.s %[pom3], %[pom2],    %[tmp3]             \n\t"
+            "add.s %[pom],  %[pom],     %[tmp4]             \n\t"
+            "sub.s %[pom2], %[pom2],    %[tmp3]             \n\t"
+            "swc1  %[temp4],40(%[tmpz])                     \n\t"  // tmpz[5].re = tmpz[1].re - tmp1;
+            "swc1  %[temp3],44(%[tmpz])                     \n\t"  // tmpz[5].im = tmpz[1].im - tmp2;
+            "swc1  %[temp], 8(%[tmpz])                      \n\t"  // tmpz[1].re = tmpz[1].re + tmp1;
+            "swc1  %[temp1],12(%[tmpz])                     \n\t"  // tmpz[1].im = tmpz[1].im + tmp2;
+            "swc1  %[pom1], 56(%[tmpz])                     \n\t"  // tmpz[7].re = tmpz[3].re - tmp4;
+            "swc1  %[pom3], 60(%[tmpz])                     \n\t"  // tmpz[7].im = tmpz[3].im + tmp3;
+            "swc1  %[pom],  24(%[tmpz])                     \n\t"  // tmpz[3].re = tmpz[3].re + tmp4;
+            "swc1  %[pom2], 28(%[tmpz])                     \n\t"  // tmpz[3].im = tmpz[3].im - tmp3;
+            : [tmp1]"=&f"(tmp1), [pom]"=&f"(pom),   [pom1]"=&f"(pom1), [pom2]"=&f"(pom2),
+              [tmp3]"=&f"(tmp3), [tmp2]"=&f"(tmp2), [tmp4]"=&f"(tmp4), [tmp5]"=&f"(tmp5),  [tmp7]"=&f"(tmp7),
+              [tmp6]"=&f"(tmp6), [tmp8]"=&f"(tmp8), [pom3]"=&f"(pom3),[temp]"=&f"(temp), [temp1]"=&f"(temp1),
+              [temp3]"=&f"(temp3), [temp4]"=&f"(temp4)
+            : [tmpz]"r"(tmpz)
+            : "memory"
+        );
+    }
+
+    step = 1 << (MAX_LOG2_NFFT - 4);
+    n4 = 4;
+
+    for (nbits=4; nbits<=s->nbits; nbits++) {
+        /*
+        * num_transforms = (num_transforms >> 1) | 1;
+        */
+        __asm__ volatile (
+            "sra %[num_t], %[num_t], 1               \n\t"
+            "ori %[num_t], %[num_t], 1               \n\t"
+
+            : [num_t] "+r" (num_transforms)
+        );
+        n2  = 2 * n4;
+        n34 = 3 * n4;
+
+        for (n=0; n<num_transforms; n++) {
+            offset = fft_offsets_lut[n] << nbits;
+            tmpz = z + offset;
+
+            tmpz_n2  = tmpz +  n2;
+            tmpz_n4  = tmpz +  n4;
+            tmpz_n34 = tmpz +  n34;
+
+            __asm__ volatile (
+                "lwc1  %[pom1], 0(%[tmpz_n2])            \n\t"
+                "lwc1  %[pom],  0(%[tmpz_n34])           \n\t"
+                "lwc1  %[pom2], 4(%[tmpz_n2])            \n\t"
+                "lwc1  %[pom3], 4(%[tmpz_n34])           \n\t"
+                "lwc1  %[temp1],0(%[tmpz])               \n\t"
+                "lwc1  %[temp3],4(%[tmpz])               \n\t"
+                "add.s %[tmp5], %[pom1],      %[pom]     \n\t"   //  tmp5 = tmpz[ n2].re + tmpz[n34].re;
+                "sub.s %[tmp1], %[pom1],      %[pom]     \n\t"   //  tmp1 = tmpz[ n2].re - tmpz[n34].re;
+                "add.s %[tmp6], %[pom2],      %[pom3]    \n\t"   //  tmp6 = tmpz[ n2].im + tmpz[n34].im;
+                "sub.s %[tmp2], %[pom2],      %[pom3]    \n\t"   //  tmp2 = tmpz[ n2].im - tmpz[n34].im;
+                "sub.s %[temp], %[temp1],     %[tmp5]    \n\t"
+                "add.s %[temp1],%[temp1],     %[tmp5]    \n\t"
+                "sub.s %[temp4],%[temp3],     %[tmp6]    \n\t"
+                "add.s %[temp3],%[temp3],     %[tmp6]    \n\t"
+                "swc1  %[temp], 0(%[tmpz_n2])            \n\t"   //  tmpz[ n2].re = tmpz[ 0].re - tmp5;
+                "swc1  %[temp1],0(%[tmpz])               \n\t"   //  tmpz[  0].re = tmpz[ 0].re + tmp5;
+                "lwc1  %[pom1], 0(%[tmpz_n4])            \n\t"
+                "swc1  %[temp4],4(%[tmpz_n2])            \n\t"   //  tmpz[ n2].im = tmpz[ 0].im - tmp6;
+                "lwc1  %[temp], 4(%[tmpz_n4])            \n\t"
+                "swc1  %[temp3],4(%[tmpz])               \n\t"   //  tmpz[  0].im = tmpz[ 0].im + tmp6;
+                "sub.s %[pom],  %[pom1],      %[tmp2]    \n\t"
+                "add.s %[pom1], %[pom1],      %[tmp2]    \n\t"
+                "add.s %[temp1],%[temp],      %[tmp1]    \n\t"
+                "sub.s %[temp], %[temp],      %[tmp1]    \n\t"
+                "swc1  %[pom],  0(%[tmpz_n34])           \n\t"   //  tmpz[n34].re = tmpz[n4].re - tmp2;
+                "swc1  %[pom1], 0(%[tmpz_n4])            \n\t"   //  tmpz[ n4].re = tmpz[n4].re + tmp2;
+                "swc1  %[temp1],4(%[tmpz_n34])           \n\t"   //  tmpz[n34].im = tmpz[n4].im + tmp1;
+                "swc1  %[temp], 4(%[tmpz_n4])            \n\t"   //  tmpz[ n4].im = tmpz[n4].im - tmp1;
+                : [tmp5]"=&f"(tmp5),
+                  [tmp1]"=&f"(tmp1), [pom]"=&f"(pom),        [pom1]"=&f"(pom1),        [pom2]"=&f"(pom2),
+                  [tmp2]"=&f"(tmp2), [tmp6]"=&f"(tmp6),          [pom3]"=&f"(pom3),
+                  [temp]"=&f"(temp), [temp1]"=&f"(temp1),     [temp3]"=&f"(temp3),       [temp4]"=&f"(temp4)
+                : [tmpz]"r"(tmpz), [tmpz_n2]"r"(tmpz_n2), [tmpz_n34]"r"(tmpz_n34), [tmpz_n4]"r"(tmpz_n4)
+                : "memory"
+            );
+
+            w_re_ptr = (float*)(ff_cos_65536 + step);
+            w_im_ptr = (float*)(ff_cos_65536 + MAX_FFT_SIZE/4 - step);
+
+            for (i=1; i<n4; i++) {
+                w_re = w_re_ptr[0];
+                w_im = w_im_ptr[0];
+                tmpz_n2_i = tmpz_n2  + i;
+                tmpz_n4_i = tmpz_n4  + i;
+                tmpz_n34_i= tmpz_n34 + i;
+                tmpz_i    = tmpz     + i;
+
+                __asm__ volatile (
+                    "lwc1     %[temp],  0(%[tmpz_n2_i])               \n\t"
+                    "lwc1     %[temp1], 4(%[tmpz_n2_i])               \n\t"
+                    "lwc1     %[pom],   0(%[tmpz_n34_i])              \n\t"
+                    "lwc1     %[pom1],  4(%[tmpz_n34_i])              \n\t"
+                    "mul.s    %[temp3], %[w_im],    %[temp]           \n\t"
+                    "mul.s    %[temp4], %[w_im],    %[temp1]          \n\t"
+                    "mul.s    %[pom2],  %[w_im],    %[pom1]           \n\t"
+                    "mul.s    %[pom3],  %[w_im],    %[pom]            \n\t"
+                    "msub.s   %[tmp2],  %[temp3],   %[w_re], %[temp1] \n\t"  // tmp2 = w_re * tmpz[ n2+i].im - w_im * tmpz[ n2+i].re;
+                    "madd.s   %[tmp1],  %[temp4],   %[w_re], %[temp]  \n\t"  // tmp1 = w_re * tmpz[ n2+i].re + w_im * tmpz[ n2+i].im;
+                    "msub.s   %[tmp3],  %[pom2],    %[w_re], %[pom]   \n\t"  // tmp3 = w_re * tmpz[n34+i].re - w_im * tmpz[n34+i].im;
+                    "madd.s   %[tmp4],  %[pom3],    %[w_re], %[pom1]  \n\t"  // tmp4 = w_re * tmpz[n34+i].im + w_im * tmpz[n34+i].re;
+                    "lwc1     %[temp],  0(%[tmpz_i])                  \n\t"
+                    "lwc1     %[pom],   4(%[tmpz_i])                  \n\t"
+                    "add.s    %[tmp5],  %[tmp1],    %[tmp3]           \n\t"  // tmp5 = tmp1 + tmp3;
+                    "sub.s    %[tmp1],  %[tmp1],    %[tmp3]           \n\t"  // tmp1 = tmp1 - tmp3;
+                    "add.s    %[tmp6],  %[tmp2],    %[tmp4]           \n\t"  // tmp6 = tmp2 + tmp4;
+                    "sub.s    %[tmp2],  %[tmp2],    %[tmp4]           \n\t"  // tmp2 = tmp2 - tmp4;
+                    "sub.s    %[temp1], %[temp],    %[tmp5]           \n\t"
+                    "add.s    %[temp],  %[temp],    %[tmp5]           \n\t"
+                    "sub.s    %[pom1],  %[pom],     %[tmp6]           \n\t"
+                    "add.s    %[pom],   %[pom],     %[tmp6]           \n\t"
+                    "lwc1     %[temp3], 0(%[tmpz_n4_i])               \n\t"
+                    "lwc1     %[pom2],  4(%[tmpz_n4_i])               \n\t"
+                    "swc1     %[temp1], 0(%[tmpz_n2_i])               \n\t"  // tmpz[ n2+i].re = tmpz[   i].re - tmp5;
+                    "swc1     %[temp],  0(%[tmpz_i])                  \n\t"  // tmpz[    i].re = tmpz[   i].re + tmp5;
+                    "swc1     %[pom1],  4(%[tmpz_n2_i])               \n\t"  // tmpz[ n2+i].im = tmpz[   i].im - tmp6;
+                    "swc1     %[pom] ,  4(%[tmpz_i])                  \n\t"  // tmpz[    i].im = tmpz[   i].im + tmp6;
+                    "sub.s    %[temp4], %[temp3],   %[tmp2]           \n\t"
+                    "add.s    %[pom3],  %[pom2],    %[tmp1]           \n\t"
+                    "add.s    %[temp3], %[temp3],   %[tmp2]           \n\t"
+                    "sub.s    %[pom2],  %[pom2],    %[tmp1]           \n\t"
+                    "swc1     %[temp4], 0(%[tmpz_n34_i])              \n\t"  // tmpz[n34+i].re = tmpz[n4+i].re - tmp2;
+                    "swc1     %[pom3],  4(%[tmpz_n34_i])              \n\t"  // tmpz[n34+i].im = tmpz[n4+i].im + tmp1;
+                    "swc1     %[temp3], 0(%[tmpz_n4_i])               \n\t"  // tmpz[ n4+i].re = tmpz[n4+i].re + tmp2;
+                    "swc1     %[pom2],  4(%[tmpz_n4_i])               \n\t"  // tmpz[ n4+i].im = tmpz[n4+i].im - tmp1;
+                    : [tmp1]"=&f"(tmp1), [tmp2]"=&f" (tmp2), [temp]"=&f"(temp), [tmp3]"=&f"(tmp3),
+                      [tmp4]"=&f"(tmp4), [tmp5]"=&f"(tmp5), [tmp6]"=&f"(tmp6),
+                      [temp1]"=&f"(temp1), [temp3]"=&f"(temp3), [temp4]"=&f"(temp4),
+                      [pom]"=&f"(pom), [pom1]"=&f"(pom1), [pom2]"=&f"(pom2), [pom3]"=&f"(pom3)
+                    : [w_re]"f"(w_re), [w_im]"f"(w_im),
+                      [tmpz_i]"r"(tmpz_i),[tmpz_n2_i]"r"(tmpz_n2_i),
+                      [tmpz_n34_i]"r"(tmpz_n34_i), [tmpz_n4_i]"r"(tmpz_n4_i)
+                    : "memory"
+                );
+                w_re_ptr += step;
+                w_im_ptr -= step;
+            }
+        }
+        step >>= 1;
+        n4   <<= 1;
+    }
+}
+
+/**
+ * MDCT/IMDCT transforms.
+ */
+
+static void ff_imdct_half_mips(FFTContext *s, FFTSample *output, const FFTSample *input)
+{
+    int k, n8, n4, n2, n, j;
+    const uint16_t *revtab = s->revtab;
+    const FFTSample *tcos = s->tcos;
+    const FFTSample *tsin = s->tsin;
+    const FFTSample *in1, *in2, *in3, *in4;
+    FFTComplex *z = (FFTComplex *)output;
+
+    int j1;
+    const float *tcos1, *tsin1, *tcos2, *tsin2;
+    float temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8,
+        temp9, temp10, temp11, temp12, temp13, temp14, temp15, temp16;
+    FFTComplex *z1, *z2;
+
+    n = 1 << s->mdct_bits;
+    n2 = n >> 1;
+    n4 = n >> 2;
+    n8 = n >> 3;
+
+    /* pre rotation */
+    in1 = input;
+    in2 = input + n2 - 1;
+    in3 = input + 2;
+    in4 = input + n2 - 3;
+
+    tcos1 = tcos;
+    tsin1 = tsin;
+
+    /* n4 = 64 or 128 */
+    for(k = 0; k < n4; k += 2) {
+        j  = revtab[k    ];
+        j1 = revtab[k + 1];
+
+        __asm__ volatile (
+            "lwc1           %[temp1],       0(%[in2])                           \t\n"
+            "lwc1           %[temp2],       0(%[tcos1])                         \t\n"
+            "lwc1           %[temp3],       0(%[tsin1])                         \t\n"
+            "lwc1           %[temp4],       0(%[in1])                           \t\n"
+            "lwc1           %[temp5],       0(%[in4])                           \t\n"
+            "mul.s          %[temp9],       %[temp1],   %[temp2]                \t\n"
+            "mul.s          %[temp10],      %[temp1],   %[temp3]                \t\n"
+            "lwc1           %[temp6],       4(%[tcos1])                         \t\n"
+            "lwc1           %[temp7],       4(%[tsin1])                         \t\n"
+            "nmsub.s        %[temp9],       %[temp9],   %[temp4],   %[temp3]    \t\n"
+            "madd.s         %[temp10],      %[temp10],  %[temp4],   %[temp2]    \t\n"
+            "mul.s          %[temp11],      %[temp5],   %[temp6]                \t\n"
+            "mul.s          %[temp12],      %[temp5],   %[temp7]                \t\n"
+            "lwc1           %[temp8],       0(%[in3])                           \t\n"
+            "addiu          %[tcos1],       %[tcos1],   8                       \t\n"
+            "addiu          %[tsin1],       %[tsin1],   8                       \t\n"
+            "addiu          %[in1],         %[in1],     16                      \t\n"
+            "nmsub.s        %[temp11],      %[temp11],  %[temp8],   %[temp7]    \t\n"
+            "madd.s         %[temp12],      %[temp12],  %[temp8],   %[temp6]    \t\n"
+            "addiu          %[in2],         %[in2],     -16                     \t\n"
+            "addiu          %[in3],         %[in3],     16                      \t\n"
+            "addiu          %[in4],         %[in4],     -16                     \t\n"
+
+            : [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),
+              [tsin1]"+r"(tsin1), [tcos1]"+r"(tcos1),
+              [in1]"+r"(in1), [in2]"+r"(in2),
+              [in3]"+r"(in3), [in4]"+r"(in4)
+        );
+
+        z[j ].re = temp9;
+        z[j ].im = temp10;
+        z[j1].re = temp11;
+        z[j1].im = temp12;
+    }
+
+    s->fft_calc(s, z);
+
+    /* post rotation + reordering */
+    /* n8 = 32 or 64 */
+    for(k = 0; k < n8; k += 2) {
+        tcos1 = &tcos[n8 - k - 2];
+        tsin1 = &tsin[n8 - k - 2];
+        tcos2 = &tcos[n8 + k];
+        tsin2 = &tsin[n8 + k];
+        z1 = &z[n8 - k - 2];
+        z2 = &z[n8 + k    ];
+
+        __asm__ volatile (
+            "lwc1       %[temp1],   12(%[z1])                           \t\n"
+            "lwc1       %[temp2],   4(%[tsin1])                         \t\n"
+            "lwc1       %[temp3],   4(%[tcos1])                         \t\n"
+            "lwc1       %[temp4],   8(%[z1])                            \t\n"
+            "lwc1       %[temp5],   4(%[z1])                            \t\n"
+            "mul.s      %[temp9],   %[temp1],   %[temp2]                \t\n"
+            "mul.s      %[temp10],  %[temp1],   %[temp3]                \t\n"
+            "lwc1       %[temp6],   0(%[tsin1])                         \t\n"
+            "lwc1       %[temp7],   0(%[tcos1])                         \t\n"
+            "nmsub.s    %[temp9],   %[temp9],   %[temp4],   %[temp3]    \t\n"
+            "madd.s     %[temp10],  %[temp10],  %[temp4],   %[temp2]    \t\n"
+            "mul.s      %[temp11],  %[temp5],   %[temp6]                \t\n"
+            "mul.s      %[temp12],  %[temp5],   %[temp7]                \t\n"
+            "lwc1       %[temp8],   0(%[z1])                            \t\n"
+            "lwc1       %[temp1],   4(%[z2])                            \t\n"
+            "lwc1       %[temp2],   0(%[tsin2])                         \t\n"
+            "lwc1       %[temp3],   0(%[tcos2])                         \t\n"
+            "nmsub.s    %[temp11],  %[temp11],  %[temp8],   %[temp7]    \t\n"
+            "madd.s     %[temp12],  %[temp12],  %[temp8],   %[temp6]    \t\n"
+            "mul.s      %[temp13],  %[temp1],   %[temp2]                \t\n"
+            "mul.s      %[temp14],  %[temp1],   %[temp3]                \t\n"
+            "lwc1       %[temp4],   0(%[z2])                            \t\n"
+            "lwc1       %[temp5],   12(%[z2])                           \t\n"
+            "lwc1       %[temp6],   4(%[tsin2])                         \t\n"
+            "lwc1       %[temp7],   4(%[tcos2])                         \t\n"
+            "nmsub.s    %[temp13],  %[temp13],  %[temp4],   %[temp3]    \t\n"
+            "madd.s     %[temp14],  %[temp14],  %[temp4],   %[temp2]    \t\n"
+            "mul.s      %[temp15],  %[temp5],   %[temp6]                \t\n"
+            "mul.s      %[temp16],  %[temp5],   %[temp7]                \t\n"
+            "lwc1       %[temp8],   8(%[z2])                            \t\n"
+            "nmsub.s    %[temp15],  %[temp15],  %[temp8],   %[temp7]    \t\n"
+            "madd.s     %[temp16],  %[temp16],  %[temp8],   %[temp6]    \t\n"
+            : [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)
+            : [z1]"r"(z1), [z2]"r"(z2),
+              [tsin1]"r"(tsin1), [tcos1]"r"(tcos1),
+              [tsin2]"r"(tsin2), [tcos2]"r"(tcos2)
+        );
+
+        z1[1].re = temp9;
+        z1[1].im = temp14;
+        z2[0].re = temp13;
+        z2[0].im = temp10;
+
+        z1[0].re = temp11;
+        z1[0].im = temp16;
+        z2[1].re = temp15;
+        z2[1].im = temp12;
+    }
+}
+#endif /* HAVE_INLINE_ASM */
+
+/**
+ * Compute inverse MDCT of size N = 2^nbits
+ * @param output N samples
+ * @param input N/2 samples
+ */
+static void ff_imdct_calc_mips(FFTContext *s, FFTSample *output, const FFTSample *input)
+{
+    int k;
+    int n = 1 << s->mdct_bits;
+    int n2 = n >> 1;
+    int n4 = n >> 2;
+
+    ff_imdct_half_mips(s, output+n4, input);
+
+    for(k = 0; k < n4; k+=4) {
+        output[k] = -output[n2-k-1];
+        output[k+1] = -output[n2-k-2];
+        output[k+2] = -output[n2-k-3];
+        output[k+3] = -output[n2-k-4];
+
+        output[n-k-1] = output[n2+k];
+        output[n-k-2] = output[n2+k+1];
+        output[n-k-3] = output[n2+k+2];
+        output[n-k-4] = output[n2+k+3];
+    }
+}
+
+av_cold void ff_fft_init_mips(FFTContext *s)
+{
+    int n=0;
+
+    ff_fft_lut_init(fft_offsets_lut, 0, 1 << 16, &n);
+
+#if HAVE_INLINE_ASM
+    s->fft_calc     = ff_fft_calc_mips;
+#endif
+#if CONFIG_MDCT
+    s->imdct_calc   = ff_imdct_calc_mips;
+    s->imdct_half   = ff_imdct_half_mips;
+#endif
+}
diff --git a/libavcodec/mips/fft_table.h b/libavcodec/mips/fft_table.h
new file mode 100644
index 0000000..dd52eaf
--- /dev/null
+++ b/libavcodec/mips/fft_table.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Stanislav Ocovaj (socovaj@mips.com)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * definitions and LUT table for MIPS FFT
+ */
+#ifndef AVCODEC_MIPS_FFT_TABLE_H
+#define AVCODEC_MIPS_FFT_TABLE_H
+
+#include "libavcodec/fft.h"
+
+#define MAX_LOG2_NFFT 16 //!< Specifies maxiumum allowed fft size
+#define MAX_FFT_SIZE (1 << MAX_LOG2_NFFT)
+
+extern uint16_t fft_offsets_lut[];
+void ff_fft_lut_init(uint16_t *table, int off, int size, int *index);
+
+#endif /* AVCODEC_MIPS_FFT_TABLE_H */
diff --git a/libavcodec/mips/fmtconvert_mips.c b/libavcodec/mips/fmtconvert_mips.c
new file mode 100644
index 0000000..f89d3b6
--- /dev/null
+++ b/libavcodec/mips/fmtconvert_mips.c
@@ -0,0 +1,338 @@
+/*
+ * Format Conversion Utils for MIPS
+ *
+ * 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)
+ * Author:  Nedeljko Babic (nbabic@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/avcodec.h"
+#include "libavcodec/fmtconvert.h"
+
+#if HAVE_MIPSDSPR1
+static void float_to_int16_mips(int16_t *dst, const float *src, long len)
+{
+    const float *src_end = src + len;
+    int ret0, ret1, ret2, ret3, ret4, ret5, ret6, ret7;
+    float src0, src1, src2, src3, src4, src5, src6, src7;
+
+    /*
+     * loop is 8 times unrolled in assembler in order to achieve better performance
+     */
+    __asm__ volatile(
+        "beq        %[len],  $zero,   fti16_end%=   \n\t"
+        "fti16_lp%=:                                \n\t"
+        "lwc1       %[src0], 0(%[src])              \n\t"
+        "lwc1       %[src1], 4(%[src])              \n\t"
+        "lwc1       %[src2], 8(%[src])              \n\t"
+        "lwc1       %[src3], 12(%[src])             \n\t"
+        "cvt.w.s    %[src0], %[src0]                \n\t"
+        "cvt.w.s    %[src1], %[src1]                \n\t"
+        "cvt.w.s    %[src2], %[src2]                \n\t"
+        "cvt.w.s    %[src3], %[src3]                \n\t"
+        "mfc1       %[ret0], %[src0]                \n\t"
+        "mfc1       %[ret1], %[src1]                \n\t"
+        "mfc1       %[ret2], %[src2]                \n\t"
+        "mfc1       %[ret3], %[src3]                \n\t"
+        "lwc1       %[src4], 16(%[src])             \n\t"
+        "lwc1       %[src5], 20(%[src])             \n\t"
+        "lwc1       %[src6], 24(%[src])             \n\t"
+        "lwc1       %[src7], 28(%[src])             \n\t"
+        "cvt.w.s    %[src4], %[src4]                \n\t"
+        "cvt.w.s    %[src5], %[src5]                \n\t"
+        "cvt.w.s    %[src6], %[src6]                \n\t"
+        "cvt.w.s    %[src7], %[src7]                \n\t"
+        "addiu      %[src],  32                     \n\t"
+        "shll_s.w   %[ret0], %[ret0], 16            \n\t"
+        "shll_s.w   %[ret1], %[ret1], 16            \n\t"
+        "shll_s.w   %[ret2], %[ret2], 16            \n\t"
+        "shll_s.w   %[ret3], %[ret3], 16            \n\t"
+        "srl        %[ret0], %[ret0], 16            \n\t"
+        "srl        %[ret1], %[ret1], 16            \n\t"
+        "srl        %[ret2], %[ret2], 16            \n\t"
+        "srl        %[ret3], %[ret3], 16            \n\t"
+        "sh         %[ret0], 0(%[dst])              \n\t"
+        "sh         %[ret1], 2(%[dst])              \n\t"
+        "sh         %[ret2], 4(%[dst])              \n\t"
+        "sh         %[ret3], 6(%[dst])              \n\t"
+        "mfc1       %[ret4], %[src4]                \n\t"
+        "mfc1       %[ret5], %[src5]                \n\t"
+        "mfc1       %[ret6], %[src6]                \n\t"
+        "mfc1       %[ret7], %[src7]                \n\t"
+        "shll_s.w   %[ret4], %[ret4], 16            \n\t"
+        "shll_s.w   %[ret5], %[ret5], 16            \n\t"
+        "shll_s.w   %[ret6], %[ret6], 16            \n\t"
+        "shll_s.w   %[ret7], %[ret7], 16            \n\t"
+        "srl        %[ret4], %[ret4], 16            \n\t"
+        "srl        %[ret5], %[ret5], 16            \n\t"
+        "srl        %[ret6], %[ret6], 16            \n\t"
+        "srl        %[ret7], %[ret7], 16            \n\t"
+        "sh         %[ret4], 8(%[dst])              \n\t"
+        "sh         %[ret5], 10(%[dst])             \n\t"
+        "sh         %[ret6], 12(%[dst])             \n\t"
+        "sh         %[ret7], 14(%[dst])             \n\t"
+        "addiu      %[dst],  16                     \n\t"
+        "bne        %[src],  %[src_end], fti16_lp%= \n\t"
+        "fti16_end%=:                               \n\t"
+        : [ret0]"=&r"(ret0), [ret1]"=&r"(ret1), [ret2]"=&r"(ret2), [ret3]"=&r"(ret3),
+          [ret4]"=&r"(ret4), [ret5]"=&r"(ret5), [ret6]"=&r"(ret6), [ret7]"=&r"(ret7),
+          [src0]"=&f"(src0), [src1]"=&f"(src1), [src2]"=&f"(src2), [src3]"=&f"(src3),
+          [src4]"=&f"(src4), [src5]"=&f"(src5), [src6]"=&f"(src6), [src7]"=&f"(src7),
+          [src]"+r"(src), [dst]"+r"(dst)
+        : [src_end]"r"(src_end), [len]"r"(len)
+        : "memory"
+    );
+}
+
+static void float_to_int16_interleave_mips(int16_t *dst, const float **src, long len,
+        int channels)
+{
+    int   c, ch2 = channels <<1;
+    int ret0, ret1, ret2, ret3, ret4, ret5, ret6, ret7;
+    float src0, src1, src2, src3, src4, src5, src6, src7;
+    int16_t *dst_ptr0, *dst_ptr1, *dst_ptr2, *dst_ptr3;
+    int16_t *dst_ptr4, *dst_ptr5, *dst_ptr6, *dst_ptr7;
+    const float *src_ptr, *src_ptr2, *src_end;
+
+    if (channels == 2) {
+        src_ptr = &src[0][0];
+        src_ptr2 = &src[1][0];
+        src_end = src_ptr + len;
+
+        __asm__ volatile (
+            "fti16i2_lp%=:                                   \n\t"
+            "lwc1       %[src0],    0(%[src_ptr])            \n\t"
+            "lwc1       %[src1],    0(%[src_ptr2])           \n\t"
+            "addiu      %[src_ptr], 4                        \n\t"
+            "cvt.w.s    $f9,        %[src0]                  \n\t"
+            "cvt.w.s    $f10,       %[src1]                  \n\t"
+            "mfc1       %[ret0],    $f9                      \n\t"
+            "mfc1       %[ret1],    $f10                     \n\t"
+            "shll_s.w   %[ret0],    %[ret0], 16              \n\t"
+            "shll_s.w   %[ret1],    %[ret1], 16              \n\t"
+            "addiu      %[src_ptr2], 4                       \n\t"
+            "srl        %[ret0],    %[ret0], 16              \n\t"
+            "srl        %[ret1],    %[ret1], 16              \n\t"
+            "sh         %[ret0],    0(%[dst])                \n\t"
+            "sh         %[ret1],    2(%[dst])                \n\t"
+            "addiu      %[dst],     4                        \n\t"
+            "bne        %[src_ptr], %[src_end], fti16i2_lp%= \n\t"
+            : [ret0]"=&r"(ret0), [ret1]"=&r"(ret1),
+              [src0]"=&f"(src0), [src1]"=&f"(src1),
+              [src_ptr]"+r"(src_ptr), [src_ptr2]"+r"(src_ptr2),
+              [dst]"+r"(dst)
+            : [src_end]"r"(src_end)
+            : "memory"
+        );
+    } else {
+        for (c = 0; c < channels; c++) {
+            src_ptr  = &src[c][0];
+            dst_ptr0 = &dst[c];
+            src_end = src_ptr + len;
+            /*
+             * loop is 8 times unrolled in assembler in order to achieve better performance
+             */
+            __asm__ volatile(
+                "fti16i_lp%=:                                     \n\t"
+                "lwc1       %[src0], 0(%[src_ptr])                \n\t"
+                "lwc1       %[src1], 4(%[src_ptr])                \n\t"
+                "lwc1       %[src2], 8(%[src_ptr])                \n\t"
+                "lwc1       %[src3], 12(%[src_ptr])               \n\t"
+                "cvt.w.s    %[src0], %[src0]                      \n\t"
+                "cvt.w.s    %[src1], %[src1]                      \n\t"
+                "cvt.w.s    %[src2], %[src2]                      \n\t"
+                "cvt.w.s    %[src3], %[src3]                      \n\t"
+                "mfc1       %[ret0], %[src0]                      \n\t"
+                "mfc1       %[ret1], %[src1]                      \n\t"
+                "mfc1       %[ret2], %[src2]                      \n\t"
+                "mfc1       %[ret3], %[src3]                      \n\t"
+                "lwc1       %[src4], 16(%[src_ptr])               \n\t"
+                "lwc1       %[src5], 20(%[src_ptr])               \n\t"
+                "lwc1       %[src6], 24(%[src_ptr])               \n\t"
+                "lwc1       %[src7], 28(%[src_ptr])               \n\t"
+                "addu       %[dst_ptr1], %[dst_ptr0], %[ch2]      \n\t"
+                "addu       %[dst_ptr2], %[dst_ptr1], %[ch2]      \n\t"
+                "addu       %[dst_ptr3], %[dst_ptr2], %[ch2]      \n\t"
+                "addu       %[dst_ptr4], %[dst_ptr3], %[ch2]      \n\t"
+                "addu       %[dst_ptr5], %[dst_ptr4], %[ch2]      \n\t"
+                "addu       %[dst_ptr6], %[dst_ptr5], %[ch2]      \n\t"
+                "addu       %[dst_ptr7], %[dst_ptr6], %[ch2]      \n\t"
+                "addiu      %[src_ptr],  32                       \n\t"
+                "cvt.w.s    %[src4], %[src4]                      \n\t"
+                "cvt.w.s    %[src5], %[src5]                      \n\t"
+                "cvt.w.s    %[src6], %[src6]                      \n\t"
+                "cvt.w.s    %[src7], %[src7]                      \n\t"
+                "shll_s.w   %[ret0], %[ret0], 16                  \n\t"
+                "shll_s.w   %[ret1], %[ret1], 16                  \n\t"
+                "shll_s.w   %[ret2], %[ret2], 16                  \n\t"
+                "shll_s.w   %[ret3], %[ret3], 16                  \n\t"
+                "srl        %[ret0], %[ret0], 16                  \n\t"
+                "srl        %[ret1], %[ret1], 16                  \n\t"
+                "srl        %[ret2], %[ret2], 16                  \n\t"
+                "srl        %[ret3], %[ret3], 16                  \n\t"
+                "sh         %[ret0], 0(%[dst_ptr0])               \n\t"
+                "sh         %[ret1], 0(%[dst_ptr1])               \n\t"
+                "sh         %[ret2], 0(%[dst_ptr2])               \n\t"
+                "sh         %[ret3], 0(%[dst_ptr3])               \n\t"
+                "mfc1       %[ret4], %[src4]                      \n\t"
+                "mfc1       %[ret5], %[src5]                      \n\t"
+                "mfc1       %[ret6], %[src6]                      \n\t"
+                "mfc1       %[ret7], %[src7]                      \n\t"
+                "shll_s.w   %[ret4], %[ret4], 16                  \n\t"
+                "shll_s.w   %[ret5], %[ret5], 16                  \n\t"
+                "shll_s.w   %[ret6], %[ret6], 16                  \n\t"
+                "shll_s.w   %[ret7], %[ret7], 16                  \n\t"
+                "srl        %[ret4], %[ret4], 16                  \n\t"
+                "srl        %[ret5], %[ret5], 16                  \n\t"
+                "srl        %[ret6], %[ret6], 16                  \n\t"
+                "srl        %[ret7], %[ret7], 16                  \n\t"
+                "sh         %[ret4], 0(%[dst_ptr4])               \n\t"
+                "sh         %[ret5], 0(%[dst_ptr5])               \n\t"
+                "sh         %[ret6], 0(%[dst_ptr6])               \n\t"
+                "sh         %[ret7], 0(%[dst_ptr7])               \n\t"
+                "addu       %[dst_ptr0], %[dst_ptr7], %[ch2]      \n\t"
+                "bne        %[src_ptr],  %[src_end],  fti16i_lp%= \n\t"
+                : [ret0]"=&r"(ret0), [ret1]"=&r"(ret1), [ret2]"=&r"(ret2), [ret3]"=&r"(ret3),
+                  [ret4]"=&r"(ret4), [ret5]"=&r"(ret5), [ret6]"=&r"(ret6), [ret7]"=&r"(ret7),
+                  [src0]"=&f"(src0), [src1]"=&f"(src1), [src2]"=&f"(src2), [src3]"=&f"(src3),
+                  [src4]"=&f"(src4), [src5]"=&f"(src5), [src6]"=&f"(src6), [src7]"=&f"(src7),
+                  [dst_ptr1]"=&r"(dst_ptr1), [dst_ptr2]"=&r"(dst_ptr2), [dst_ptr3]"=&r"(dst_ptr3),
+                  [dst_ptr4]"=&r"(dst_ptr4), [dst_ptr5]"=&r"(dst_ptr5), [dst_ptr6]"=&r"(dst_ptr6),
+                  [dst_ptr7]"=&r"(dst_ptr7), [dst_ptr0]"+r"(dst_ptr0), [src_ptr]"+r"(src_ptr)
+                : [ch2]"r"(ch2), [src_end]"r"(src_end)
+                : "memory"
+            );
+        }
+    }
+}
+#endif /* HAVE_MIPSDSPR1 */
+
+static void int32_to_float_fmul_scalar_mips(float *dst, const int *src,
+        float mul, int len)
+{
+    /*
+     * variables used in inline assembler
+     */
+    float temp1, temp3, temp5, temp7, temp9, temp11, temp13, temp15;
+
+    int rpom1, rpom2, rpom11, rpom21, rpom12, rpom22, rpom13, rpom23;
+    const int *src_end = src + len;
+    /*
+     * loop is 8 times unrolled in assembler in order to achieve better performance
+     */
+    __asm__ volatile (
+        "i32tf_lp%=:                                    \n\t"
+        "lw       %[rpom11],     0(%[src])              \n\t"
+        "lw       %[rpom21],     4(%[src])              \n\t"
+        "lw       %[rpom1],      8(%[src])              \n\t"
+        "lw       %[rpom2],      12(%[src])             \n\t"
+        "mtc1     %[rpom11],     %[temp1]               \n\t"
+        "mtc1     %[rpom21],     %[temp3]               \n\t"
+        "mtc1     %[rpom1],      %[temp5]               \n\t"
+        "mtc1     %[rpom2],      %[temp7]               \n\t"
+
+        "lw       %[rpom13],     16(%[src])             \n\t"
+        "lw       %[rpom23],     20(%[src])             \n\t"
+        "lw       %[rpom12],     24(%[src])             \n\t"
+        "lw       %[rpom22],     28(%[src])             \n\t"
+        "mtc1     %[rpom13],     %[temp9]               \n\t"
+        "mtc1     %[rpom23],     %[temp11]              \n\t"
+        "mtc1     %[rpom12],     %[temp13]              \n\t"
+        "mtc1     %[rpom22],     %[temp15]              \n\t"
+
+        "addiu    %[src],        32                     \n\t"
+        "cvt.s.w  %[temp1],      %[temp1]               \n\t"
+        "cvt.s.w  %[temp3],      %[temp3]               \n\t"
+        "cvt.s.w  %[temp5],      %[temp5]               \n\t"
+        "cvt.s.w  %[temp7],      %[temp7]               \n\t"
+
+        "cvt.s.w  %[temp9],      %[temp9]               \n\t"
+        "cvt.s.w  %[temp11],     %[temp11]              \n\t"
+        "cvt.s.w  %[temp13],     %[temp13]              \n\t"
+        "cvt.s.w  %[temp15],     %[temp15]              \n\t"
+
+        "mul.s   %[temp1],       %[temp1],    %[mul]    \n\t"
+        "mul.s   %[temp3],       %[temp3],    %[mul]    \n\t"
+        "mul.s   %[temp5],       %[temp5],    %[mul]    \n\t"
+        "mul.s   %[temp7],       %[temp7],    %[mul]    \n\t"
+
+        "mul.s   %[temp9],       %[temp9],    %[mul]    \n\t"
+        "mul.s   %[temp11],      %[temp11],   %[mul]    \n\t"
+        "mul.s   %[temp13],      %[temp13],   %[mul]    \n\t"
+        "mul.s   %[temp15],      %[temp15],   %[mul]    \n\t"
+
+        "swc1    %[temp1],       0(%[dst])              \n\t" /*dst[i] = src[i] * mul;    */
+        "swc1    %[temp3],       4(%[dst])              \n\t" /*dst[i+1] = src[i+1] * mul;*/
+        "swc1    %[temp5],       8(%[dst])              \n\t" /*dst[i+2] = src[i+2] * mul;*/
+        "swc1    %[temp7],       12(%[dst])             \n\t" /*dst[i+3] = src[i+3] * mul;*/
+
+        "swc1    %[temp9],       16(%[dst])             \n\t" /*dst[i+4] = src[i+4] * mul;*/
+        "swc1    %[temp11],      20(%[dst])             \n\t" /*dst[i+5] = src[i+5] * mul;*/
+        "swc1    %[temp13],      24(%[dst])             \n\t" /*dst[i+6] = src[i+6] * mul;*/
+        "swc1    %[temp15],      28(%[dst])             \n\t" /*dst[i+7] = src[i+7] * mul;*/
+        "addiu   %[dst],        32                      \n\t"
+        "bne     %[src],        %[src_end], i32tf_lp%=  \n\t"
+        : [temp1]"=&f"(temp1),   [temp11]"=&f"(temp11),
+          [temp13]"=&f"(temp13), [temp15]"=&f"(temp15),
+          [temp3]"=&f"(temp3),   [temp5]"=&f"(temp5),
+          [temp7]"=&f"(temp7),   [temp9]"=&f"(temp9),
+          [rpom1]"=&r"(rpom1),   [rpom2]"=&r"(rpom2),
+          [rpom11]"=&r"(rpom11), [rpom21]"=&r"(rpom21),
+          [rpom12]"=&r"(rpom12), [rpom22]"=&r"(rpom22),
+          [rpom13]"=&r"(rpom13), [rpom23]"=&r"(rpom23),
+          [dst]"+r"(dst),       [src]"+r"(src)
+        : [mul]"f"(mul),        [src_end]"r"(src_end)
+        : "memory"
+    );
+}
+
+av_cold void ff_fmt_convert_init_mips(FmtConvertContext *c)
+{
+#if HAVE_MIPSDSPR1
+    c->float_to_int16_interleave = float_to_int16_interleave_mips;
+    c->float_to_int16 = float_to_int16_mips;
+#endif
+    c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_mips;
+}
diff --git a/libavcodec/mips/idct_mmi.c b/libavcodec/mips/idct_mmi.c
index 9b9033a..5a3af17 100644
--- a/libavcodec/mips/idct_mmi.c
+++ b/libavcodec/mips/idct_mmi.c
@@ -8,20 +8,20 @@
  *
  * MMI port and (c) 2002 by Leon van Stuivenberg
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mips/lsp_mips.h b/libavcodec/mips/lsp_mips.h
new file mode 100644
index 0000000..7497706
--- /dev/null
+++ b/libavcodec/mips/lsp_mips.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Nedeljko Babic (nbabic@mips.com)
+ *
+ * LSP routines for ACELP-based codecs 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/lsp.c
+ */
+#ifndef AVCODEC_LSP_MIPS_H
+#define AVCODEC_LSP_MIPS_H
+
+#if HAVE_MIPSFPU && HAVE_INLINE_ASM
+static av_always_inline void ff_lsp2polyf_mips(const double *lsp, double *f, int lp_half_order)
+{
+    int i, j = 0;
+    double * p_fi = f;
+    double * p_f = 0;
+
+    f[0] = 1.0;
+    f[1] = -2 * lsp[0];
+    lsp -= 2;
+
+    for(i=2; i<=lp_half_order; i++)
+    {
+        double tmp, f_j_2, f_j_1, f_j;
+        double val = lsp[2*i];
+
+        __asm__ volatile(
+            "move   %[p_f],     %[p_fi]                         \n\t"
+            "add.d  %[val],     %[val],     %[val]              \n\t"
+            "addiu  %[p_fi],    8                               \n\t"
+            "ldc1   %[f_j_1],   0(%[p_f])                       \n\t"
+            "ldc1   %[f_j],     8(%[p_f])                       \n\t"
+            "neg.d  %[val],     %[val]                          \n\t"
+            "add.d  %[tmp],     %[f_j_1],   %[f_j_1]            \n\t"
+            "madd.d %[tmp],     %[tmp],     %[f_j], %[val]      \n\t"
+            "addiu  %[j],       %[i], -2                        \n\t"
+            "ldc1   %[f_j_2],   -8(%[p_f])                      \n\t"
+            "sdc1   %[tmp],     16(%[p_f])                      \n\t"
+            "beqz   %[j],       ff_lsp2polyf_lp_j_end%=         \n\t"
+            "ff_lsp2polyf_lp_j%=:                               \n\t"
+            "add.d  %[tmp],     %[f_j],     %[f_j_2]            \n\t"
+            "madd.d %[tmp],     %[tmp],     %[f_j_1], %[val]    \n\t"
+            "mov.d  %[f_j],     %[f_j_1]                        \n\t"
+            "addiu  %[j],       -1                              \n\t"
+            "mov.d  %[f_j_1],   %[f_j_2]                        \n\t"
+            "ldc1   %[f_j_2],   -16(%[p_f])                     \n\t"
+            "sdc1   %[tmp],     8(%[p_f])                       \n\t"
+            "addiu  %[p_f],     -8                              \n\t"
+            "bgtz   %[j],       ff_lsp2polyf_lp_j%=             \n\t"
+            "ff_lsp2polyf_lp_j_end%=:                           \n\t"
+
+            : [f_j_2]"=&f"(f_j_2), [f_j_1]"=&f"(f_j_1), [val]"+f"(val),
+              [tmp]"=&f"(tmp), [f_j]"=&f"(f_j), [p_f]"+r"(p_f),
+              [j]"+r"(j), [p_fi]"+r"(p_fi)
+            : [i]"r"(i)
+        );
+        f[1] += val;
+    }
+}
+#define ff_lsp2polyf ff_lsp2polyf_mips
+#endif /* HAVE_MIPSFPU && HAVE_INLINE_ASM */
+#endif /* AVCODEC_LSP_MIPS_H */
diff --git a/libavcodec/mips/mathops.h b/libavcodec/mips/mathops.h
index 573745b..b58361f 100644
--- a/libavcodec/mips/mathops.h
+++ b/libavcodec/mips/mathops.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mips/mmi.h b/libavcodec/mips/mmi.h
index 48f2778..5ff0033 100644
--- a/libavcodec/mips/mmi.h
+++ b/libavcodec/mips/mmi.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2002 Leon van Stuivenberg
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mips/mpegaudiodsp_mips_fixed.c b/libavcodec/mips/mpegaudiodsp_mips_fixed.c
new file mode 100644
index 0000000..d1b0277
--- /dev/null
+++ b/libavcodec/mips/mpegaudiodsp_mips_fixed.c
@@ -0,0 +1,903 @@
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Bojan Zivkovic (bojan@mips.com)
+ *
+ * MPEG Audio decoder optimized for MIPS fixed-point architecture
+ *
+ * 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/mpegaudiodsp_template.c
+ */
+
+#include <string.h>
+
+#include "libavcodec/mpegaudiodsp.h"
+
+static void ff_mpadsp_apply_window_mips_fixed(int32_t *synth_buf, int32_t *window,
+                               int *dither_state, int16_t *samples, int incr)
+{
+    register const int32_t *w, *w2, *p;
+    int j;
+    int16_t *samples2;
+    int w_asm, p_asm, w_asm1, p_asm1, w_asm2, p_asm2;
+    int w2_asm, w2_asm1, *p_temp1, *p_temp2;
+    int sum1 = 0;
+    int const min_asm = -32768, max_asm = 32767;
+    int temp1, temp2 = 0, temp3 = 0;
+    int64_t sum;
+
+    /* copy to avoid wrap */
+    memcpy(synth_buf + 512, synth_buf, 32 * sizeof(*synth_buf));
+    samples2 = samples + 31 * incr;
+    w = window;
+    w2 = window + 31;
+    sum = *dither_state;
+    p = synth_buf + 16;
+    p_temp1 = synth_buf + 16;
+    p_temp2 = synth_buf + 48;
+    temp1 = sum;
+
+    /**
+    * use of round_sample function from the original code is eliminated,
+    * changed with appropriate assembly instructions.
+    */
+    __asm__ volatile (
+         "mthi   $zero                                                    \n\t"
+         "mtlo   %[temp1]                                                 \n\t"
+         "lw     %[w_asm],  0(%[w])                                       \n\t"
+         "lw     %[p_asm],  0(%[p])                                       \n\t"
+         "lw     %[w_asm1], 64*4(%[w])                                    \n\t"
+         "lw     %[p_asm1], 64*4(%[p])                                    \n\t"
+         "lw     %[w_asm2], 128*4(%[w])                                   \n\t"
+         "lw     %[p_asm2], 128*4(%[p])                                   \n\t"
+         "madd   %[w_asm],  %[p_asm]                                      \n\t"
+         "madd   %[w_asm1], %[p_asm1]                                     \n\t"
+         "madd   %[w_asm2], %[p_asm2]                                     \n\t"
+         "lw     %[w_asm],  192*4(%[w])                                   \n\t"
+         "lw     %[p_asm],  192*4(%[p])                                   \n\t"
+         "lw     %[w_asm1], 256*4(%[w])                                   \n\t"
+         "lw     %[p_asm1], 256*4(%[p])                                   \n\t"
+         "lw     %[w_asm2], 320*4(%[w])                                   \n\t"
+         "lw     %[p_asm2], 320*4(%[p])                                   \n\t"
+         "madd   %[w_asm],  %[p_asm]                                      \n\t"
+         "madd   %[w_asm1], %[p_asm1]                                     \n\t"
+         "madd   %[w_asm2], %[p_asm2]                                     \n\t"
+         "lw     %[w_asm],  384*4(%[w])                                   \n\t"
+         "lw     %[p_asm],  384*4(%[p])                                   \n\t"
+         "lw     %[w_asm1], 448*4(%[w])                                   \n\t"
+         "lw     %[p_asm1], 448*4(%[p])                                   \n\t"
+         "lw     %[w_asm2], 32*4(%[w])                                    \n\t"
+         "lw     %[p_asm2], 32*4(%[p])                                    \n\t"
+         "madd   %[w_asm],  %[p_asm]                                      \n\t"
+         "madd   %[w_asm1], %[p_asm1]                                     \n\t"
+         "msub   %[w_asm2], %[p_asm2]                                     \n\t"
+         "lw     %[w_asm],  96*4(%[w])                                    \n\t"
+         "lw     %[p_asm],  96*4(%[p])                                    \n\t"
+         "lw     %[w_asm1], 160*4(%[w])                                   \n\t"
+         "lw     %[p_asm1], 160*4(%[p])                                   \n\t"
+         "lw     %[w_asm2], 224*4(%[w])                                   \n\t"
+         "lw     %[p_asm2], 224*4(%[p])                                   \n\t"
+         "msub   %[w_asm],  %[p_asm]                                      \n\t"
+         "msub   %[w_asm1], %[p_asm1]                                     \n\t"
+         "msub   %[w_asm2], %[p_asm2]                                     \n\t"
+         "lw     %[w_asm],  288*4(%[w])                                   \n\t"
+         "lw     %[p_asm],  288*4(%[p])                                   \n\t"
+         "lw     %[w_asm1], 352*4(%[w])                                   \n\t"
+         "lw     %[p_asm1], 352*4(%[p])                                   \n\t"
+         "msub   %[w_asm],  %[p_asm]                                      \n\t"
+         "lw     %[w_asm],  480*4(%[w])                                   \n\t"
+         "lw     %[p_asm],  480*4(%[p])                                   \n\t"
+         "lw     %[w_asm2], 416*4(%[w])                                   \n\t"
+         "lw     %[p_asm2], 416*4(%[p])                                   \n\t"
+         "msub   %[w_asm],  %[p_asm]                                      \n\t"
+         "msub   %[w_asm1], %[p_asm1]                                     \n\t"
+         "msub   %[w_asm2], %[p_asm2]                                     \n\t"
+
+         /*round_sample function from the original code is eliminated,
+          * changed with appropriate assembly instructions
+          * code example:
+
+         "extr.w  %[sum1],$ac0,24                                       \n\t"
+         "mflo %[temp3],  $ac0                                          \n\t"
+         "and  %[temp1],  %[temp3],  0x00ffffff                         \n\t"
+         "slt  %[temp2],  %[sum1],   %[min_asm]                         \n\t"
+         "movn %[sum1],   %[min_asm],%[temp2]                           \n\t"
+         "slt  %[temp2],  %[max_asm],%[sum1]                            \n\t"
+         "movn %[sum1],   %[max_asm],%[temp2]                           \n\t"
+         "sh   %[sum1],   0(%[samples])                                 \n\t"
+         */
+
+         "extr.w %[sum1],   $ac0,       24                                \n\t"
+         "mflo   %[temp3]                                                 \n\t"
+         "addi   %[w],      %[w],       4                                 \n\t"
+         "and    %[temp1],  %[temp3],   0x00ffffff                        \n\t"
+         "slt    %[temp2],  %[sum1],    %[min_asm]                        \n\t"
+         "movn   %[sum1],   %[min_asm], %[temp2]                          \n\t"
+         "slt    %[temp2],  %[max_asm], %[sum1]                           \n\t"
+         "movn   %[sum1],   %[max_asm], %[temp2]                          \n\t"
+         "sh     %[sum1],   0(%[samples])                                 \n\t"
+
+        : [w_asm] "=&r" (w_asm), [p_asm] "=&r" (p_asm), [w_asm1] "=&r" (w_asm1),
+          [p_asm1] "=&r" (p_asm1), [temp1] "+r" (temp1), [temp2] "+r" (temp2),
+          [w_asm2] "=&r" (w_asm2), [p_asm2] "=&r" (p_asm2),
+          [sum1] "+r" (sum1), [w] "+r" (w), [temp3] "+r" (temp3)
+        : [p] "r" (p), [samples] "r" (samples), [min_asm] "r" (min_asm),
+          [max_asm] "r" (max_asm)
+        : "hi","lo"
+     );
+
+     samples += incr;
+
+    /* we calculate two samples at the same time to avoid one memory
+       access per two sample */
+
+    for(j = 1; j < 16; j++) {
+        __asm__ volatile (
+             "mthi   $0,         $ac1                                      \n\t"
+             "mtlo   $0,         $ac1                                      \n\t"
+             "mthi   $0                                                    \n\t"
+             "mtlo   %[temp1]                                              \n\t"
+             "addi   %[p_temp1], %[p_temp1],       4                       \n\t"
+             "lw     %[w_asm],   0(%[w])                                   \n\t"
+             "lw     %[p_asm],   0(%[p_temp1])                             \n\t"
+             "lw     %[w2_asm],  0(%[w2])                                  \n\t"
+             "lw     %[w_asm1],  64*4(%[w])                                \n\t"
+             "lw     %[p_asm1],  64*4(%[p_temp1])                          \n\t"
+             "lw     %[w2_asm1], 64*4(%[w2])                               \n\t"
+             "madd   %[w_asm],   %[p_asm]                                  \n\t"
+             "msub   $ac1,       %[w2_asm],        %[p_asm]                \n\t"
+             "madd   %[w_asm1],  %[p_asm1]                                 \n\t"
+             "msub   $ac1,       %[w2_asm1],       %[p_asm1]               \n\t"
+             "lw     %[w_asm],   128*4(%[w])                               \n\t"
+             "lw     %[p_asm],   128*4(%[p_temp1])                         \n\t"
+             "lw     %[w2_asm],  128*4(%[w2])                              \n\t"
+             "lw     %[w_asm1],  192*4(%[w])                               \n\t"
+             "lw     %[p_asm1],  192*4(%[p_temp1])                         \n\t"
+             "lw     %[w2_asm1], 192*4(%[w2])                              \n\t"
+             "madd   %[w_asm],   %[p_asm]                                  \n\t"
+             "msub   $ac1,       %[w2_asm],        %[p_asm]                \n\t"
+             "madd   %[w_asm1],  %[p_asm1]                                 \n\t"
+             "msub   $ac1,       %[w2_asm1],       %[p_asm1]               \n\t"
+             "lw     %[w_asm],   256*4(%[w])                               \n\t"
+             "lw     %[p_asm],   256*4(%[p_temp1])                         \n\t"
+             "lw     %[w2_asm],  256*4(%[w2])                              \n\t"
+             "lw     %[w_asm1],  320*4(%[w])                               \n\t"
+             "lw     %[p_asm1],  320*4(%[p_temp1])                         \n\t"
+             "lw     %[w2_asm1], 320*4(%[w2])                              \n\t"
+             "madd   %[w_asm],   %[p_asm]                                  \n\t"
+             "msub   $ac1,       %[w2_asm],        %[p_asm]                \n\t"
+             "madd   %[w_asm1],  %[p_asm1]                                 \n\t"
+             "msub   $ac1,       %[w2_asm1],       %[p_asm1]               \n\t"
+             "lw     %[w_asm],   384*4(%[w])                               \n\t"
+             "lw     %[p_asm],   384*4(%[p_temp1])                         \n\t"
+             "lw     %[w2_asm],  384*4(%[w2])                              \n\t"
+             "lw     %[w_asm1],  448*4(%[w])                               \n\t"
+             "lw     %[p_asm1],  448*4(%[p_temp1])                         \n\t"
+             "lw     %[w2_asm1], 448*4(%[w2])                              \n\t"
+             "madd   %[w_asm],   %[p_asm]                                  \n\t"
+             "msub   $ac1,       %[w2_asm],        %[p_asm]                \n\t"
+             "madd   %[w_asm1],  %[p_asm1]                                 \n\t"
+             "msub   $ac1,       %[w2_asm1],       %[p_asm1]               \n\t"
+             "addi   %[p_temp2], %[p_temp2],       -4                      \n\t"
+             "lw     %[w_asm],   32*4(%[w])                                \n\t"
+             "lw     %[p_asm],   0(%[p_temp2])                             \n\t"
+             "lw     %[w2_asm],  32*4(%[w2])                               \n\t"
+             "lw     %[w_asm1],  96*4(%[w])                                \n\t"
+             "lw     %[p_asm1],  64*4(%[p_temp2])                          \n\t"
+             "lw     %[w2_asm1], 96*4(%[w2])                               \n\t"
+             "msub   %[w_asm],   %[p_asm]                                  \n\t"
+             "msub   $ac1,       %[w2_asm],        %[p_asm]                \n\t"
+             "msub   %[w_asm1],  %[p_asm1]                                 \n\t"
+             "msub   $ac1,       %[w2_asm1],       %[p_asm1]               \n\t"
+             "lw     %[w_asm],   160*4(%[w])                               \n\t"
+             "lw     %[p_asm],   128*4(%[p_temp2])                         \n\t"
+             "lw     %[w2_asm],  160*4(%[w2])                              \n\t"
+             "lw     %[w_asm1],  224*4(%[w])                               \n\t"
+             "lw     %[p_asm1],  192*4(%[p_temp2])                         \n\t"
+             "lw     %[w2_asm1], 224*4(%[w2])                              \n\t"
+             "msub   %[w_asm],   %[p_asm]                                  \n\t"
+             "msub   $ac1,       %[w2_asm],        %[p_asm]                \n\t"
+             "msub   %[w_asm1],  %[p_asm1]                                 \n\t"
+             "msub   $ac1,       %[w2_asm1],       %[p_asm1]               \n\t"
+             "lw     %[w_asm],   288*4(%[w])                               \n\t"
+             "lw     %[p_asm],   256*4(%[p_temp2])                         \n\t"
+             "lw     %[w2_asm],  288*4(%[w2])                              \n\t"
+             "lw     %[w_asm1],  352*4(%[w])                               \n\t"
+             "lw     %[p_asm1],  320*4(%[p_temp2])                         \n\t"
+             "lw     %[w2_asm1], 352*4(%[w2])                              \n\t"
+             "msub   %[w_asm],   %[p_asm]                                  \n\t"
+             "msub   $ac1,       %[w2_asm],        %[p_asm]                \n\t"
+             "msub   %[w_asm1],  %[p_asm1]                                 \n\t"
+             "msub   $ac1,       %[w2_asm1],       %[p_asm1]               \n\t"
+             "lw     %[w_asm],   416*4(%[w])                               \n\t"
+             "lw     %[p_asm],   384*4(%[p_temp2])                         \n\t"
+             "lw     %[w2_asm],  416*4(%[w2])                              \n\t"
+             "lw     %[w_asm1],  480*4(%[w])                               \n\t"
+             "lw     %[p_asm1],  448*4(%[p_temp2])                         \n\t"
+             "lw     %[w2_asm1], 480*4(%[w2])                              \n\t"
+             "msub   %[w_asm],   %[p_asm]                                  \n\t"
+             "msub   %[w_asm1],  %[p_asm1]                                 \n\t"
+             "msub   $ac1,       %[w2_asm],        %[p_asm]                \n\t"
+             "msub   $ac1,       %[w2_asm1],       %[p_asm1]               \n\t"
+             "addi   %[w],       %[w],             4                       \n\t"
+             "addi   %[w2],      %[w2],            -4                      \n\t"
+             "mflo   %[temp2]                                              \n\t"
+             "extr.w %[sum1],    $ac0,             24                      \n\t"
+             "li     %[temp3],   1                                         \n\t"
+             "and    %[temp1],   %[temp2],         0x00ffffff              \n\t"
+             "madd   $ac1,       %[temp1],         %[temp3]                \n\t"
+             "slt    %[temp2],   %[sum1],          %[min_asm]              \n\t"
+             "movn   %[sum1],    %[min_asm],       %[temp2]                \n\t"
+             "slt    %[temp2],   %[max_asm],       %[sum1]                 \n\t"
+             "movn   %[sum1],    %[max_asm],       %[temp2]                \n\t"
+             "sh     %[sum1],    0(%[samples])                             \n\t"
+             "mflo   %[temp3],   $ac1                                      \n\t"
+             "extr.w %[sum1],    $ac1,             24                      \n\t"
+             "and    %[temp1],   %[temp3],         0x00ffffff              \n\t"
+             "slt    %[temp2],   %[sum1],          %[min_asm]              \n\t"
+             "movn   %[sum1],    %[min_asm],       %[temp2]                \n\t"
+             "slt    %[temp2],   %[max_asm],       %[sum1]                 \n\t"
+             "movn   %[sum1],    %[max_asm],       %[temp2]                \n\t"
+             "sh     %[sum1],    0(%[samples2])                            \n\t"
+
+            : [w_asm] "=&r" (w_asm), [p_asm] "=&r" (p_asm), [w_asm1] "=&r" (w_asm1),
+              [p_asm1] "=&r" (p_asm1), [w2_asm1] "=&r" (w2_asm1),
+              [w2_asm] "=&r" (w2_asm), [temp1] "+r" (temp1), [temp2] "+r" (temp2),
+              [p_temp1] "+r" (p_temp1), [p_temp2] "+r" (p_temp2), [sum1] "+r" (sum1),
+              [w] "+r" (w), [w2] "+r" (w2), [samples] "+r" (samples),
+              [samples2] "+r" (samples2), [temp3] "+r" (temp3)
+            : [min_asm] "r" (min_asm), [max_asm] "r" (max_asm)
+            : "hi", "lo"
+        );
+
+        samples += incr;
+        samples2 -= incr;
+    }
+
+    p = synth_buf + 32;
+
+    __asm__ volatile (
+        "mthi   $0                                                        \n\t"
+        "mtlo   %[temp1]                                                  \n\t"
+        "lw     %[w_asm],  32*4(%[w])                                     \n\t"
+        "lw     %[p_asm],  0(%[p])                                        \n\t"
+        "lw     %[w_asm1], 96*4(%[w])                                     \n\t"
+        "lw     %[p_asm1], 64*4(%[p])                                     \n\t"
+        "lw     %[w_asm2], 160*4(%[w])                                    \n\t"
+        "lw     %[p_asm2], 128*4(%[p])                                    \n\t"
+        "msub   %[w_asm],  %[p_asm]                                       \n\t"
+        "msub   %[w_asm1], %[p_asm1]                                      \n\t"
+        "msub   %[w_asm2], %[p_asm2]                                      \n\t"
+        "lw     %[w_asm],  224*4(%[w])                                    \n\t"
+        "lw     %[p_asm],  192*4(%[p])                                    \n\t"
+        "lw     %[w_asm1], 288*4(%[w])                                    \n\t"
+        "lw     %[p_asm1], 256*4(%[p])                                    \n\t"
+        "lw     %[w_asm2], 352*4(%[w])                                    \n\t"
+        "lw     %[p_asm2], 320*4(%[p])                                    \n\t"
+        "msub   %[w_asm],  %[p_asm]                                       \n\t"
+        "msub   %[w_asm1], %[p_asm1]                                      \n\t"
+        "msub   %[w_asm2], %[p_asm2]                                      \n\t"
+        "lw     %[w_asm],  416*4(%[w])                                    \n\t"
+        "lw     %[p_asm],  384*4(%[p])                                    \n\t"
+        "lw     %[w_asm1], 480*4(%[w])                                    \n\t"
+        "lw     %[p_asm1], 448*4(%[p])                                    \n\t"
+        "msub   %[w_asm],  %[p_asm]                                       \n\t"
+        "msub   %[w_asm1], %[p_asm1]                                      \n\t"
+        "extr.w %[sum1],   $ac0,       24                                 \n\t"
+        "mflo   %[temp2]                                                  \n\t"
+        "and    %[temp1],  %[temp2],   0x00ffffff                         \n\t"
+        "slt    %[temp2],  %[sum1],    %[min_asm]                         \n\t"
+        "movn   %[sum1],   %[min_asm], %[temp2]                           \n\t"
+        "slt    %[temp2],  %[max_asm], %[sum1]                            \n\t"
+        "movn   %[sum1],   %[max_asm], %[temp2]                           \n\t"
+        "sh     %[sum1],   0(%[samples])                                  \n\t"
+
+        : [w_asm] "=&r" (w_asm), [p_asm] "=&r" (p_asm), [w_asm1] "=&r" (w_asm1),
+          [p_asm1] "=&r" (p_asm1), [temp1] "+r" (temp1), [temp2] "+r" (temp2),
+          [w_asm2] "=&r" (w_asm2), [p_asm2] "=&r" (p_asm2), [sum1] "+r" (sum1)
+        : [w] "r" (w), [p] "r" (p), [samples] "r" (samples), [min_asm] "r" (min_asm),
+          [max_asm] "r" (max_asm)
+        : "hi", "lo"
+     );
+
+    *dither_state= temp1;
+}
+
+static void imdct36_mips_fixed(int *out, int *buf, int *in, int *win)
+{
+    int j;
+    int t0, t1, t2, t3, s0, s1, s2, s3;
+    int tmp[18], *tmp1, *in1;
+    /* temporary variables */
+    int temp_reg1, temp_reg2, temp_reg3, temp_reg4, temp_reg5, temp_reg6;
+    int t4, t5, t6, t8, t7;
+
+   /* values defined in macros and tables are
+    * eliminated - they are directly loaded in appropriate variables
+    */
+    int const C_1  =  4229717092; /* cos(pi*1/18)*2  */
+    int const C_2  =  4035949074; /* cos(pi*2/18)*2  */
+    int const C_3  =  575416510;  /* -cos(pi*3/18)*2 */
+    int const C_3A =  3719550786; /* cos(pi*3/18)*2  */
+    int const C_4  =  1004831466; /* -cos(pi*4/18)*2 */
+    int const C_5  =  1534215534; /* -cos(pi*5/18)*2 */
+    int const C_7  = -1468965330; /* -cos(pi*7/18)*2 */
+    int const C_8  = -745813244;  /* -cos(pi*8/18)*2 */
+
+   /*
+    * instructions of the first two loops are reorganized and loops are unrolled,
+    * in order to eliminate unnecessary readings and writings in array
+    */
+
+    __asm__ volatile (
+        "lw   %[t1], 17*4(%[in])                                         \n\t"
+        "lw   %[t2], 16*4(%[in])                                         \n\t"
+        "lw   %[t3], 15*4(%[in])                                         \n\t"
+        "lw   %[t4], 14*4(%[in])                                         \n\t"
+        "addu %[t1], %[t1],      %[t2]                                   \n\t"
+        "addu %[t2], %[t2],      %[t3]                                   \n\t"
+        "addu %[t3], %[t3],      %[t4]                                   \n\t"
+        "lw   %[t5], 13*4(%[in])                                         \n\t"
+        "addu %[t1], %[t1],      %[t3]                                   \n\t"
+        "sw   %[t2], 16*4(%[in])                                         \n\t"
+        "lw   %[t6], 12*4(%[in])                                         \n\t"
+        "sw   %[t1], 17*4(%[in])                                         \n\t"
+        "addu %[t4], %[t4],      %[t5]                                   \n\t"
+        "addu %[t5], %[t5],      %[t6]                                   \n\t"
+        "lw   %[t7], 11*4(%[in])                                         \n\t"
+        "addu %[t3], %[t3],      %[t5]                                   \n\t"
+        "sw   %[t4], 14*4(%[in])                                         \n\t"
+        "lw   %[t8], 10*4(%[in])                                         \n\t"
+        "sw   %[t3], 15*4(%[in])                                         \n\t"
+        "addu %[t6], %[t6],      %[t7]                                   \n\t"
+        "addu %[t7], %[t7],      %[t8]                                   \n\t"
+        "sw   %[t6], 12*4(%[in])                                         \n\t"
+        "addu %[t5], %[t5],      %[t7]                                   \n\t"
+        "lw   %[t1], 9*4(%[in])                                          \n\t"
+        "lw   %[t2], 8*4(%[in])                                          \n\t"
+        "sw   %[t5], 13*4(%[in])                                         \n\t"
+        "addu %[t8], %[t8],      %[t1]                                   \n\t"
+        "addu %[t1], %[t1],      %[t2]                                   \n\t"
+        "sw   %[t8], 10*4(%[in])                                         \n\t"
+        "addu %[t7], %[t7],      %[t1]                                   \n\t"
+        "lw   %[t3], 7*4(%[in])                                          \n\t"
+        "lw   %[t4], 6*4(%[in])                                          \n\t"
+        "sw   %[t7], 11*4(%[in])                                         \n\t"
+        "addu %[t2], %[t2],      %[t3]                                   \n\t"
+        "addu %[t3], %[t3],      %[t4]                                   \n\t"
+        "sw   %[t2], 8*4(%[in])                                          \n\t"
+        "addu %[t1], %[t1],      %[t3]                                   \n\t"
+        "lw   %[t5], 5*4(%[in])                                          \n\t"
+        "lw   %[t6], 4*4(%[in])                                          \n\t"
+        "sw   %[t1], 9*4(%[in])                                          \n\t"
+        "addu %[t4], %[t4],      %[t5]                                   \n\t"
+        "addu %[t5], %[t5],      %[t6]                                   \n\t"
+        "sw   %[t4], 6*4(%[in])                                          \n\t"
+        "addu %[t3], %[t3],      %[t5]                                   \n\t"
+        "lw   %[t7], 3*4(%[in])                                          \n\t"
+        "lw   %[t8], 2*4(%[in])                                          \n\t"
+        "sw   %[t3], 7*4(%[in])                                          \n\t"
+        "addu %[t6], %[t6],      %[t7]                                   \n\t"
+        "addu %[t7], %[t7],      %[t8]                                   \n\t"
+        "sw   %[t6], 4*4(%[in])                                          \n\t"
+        "addu %[t5], %[t5],      %[t7]                                   \n\t"
+        "lw   %[t1], 1*4(%[in])                                          \n\t"
+        "lw   %[t2], 0*4(%[in])                                          \n\t"
+        "sw   %[t5], 5*4(%[in])                                          \n\t"
+        "addu %[t8], %[t8],      %[t1]                                   \n\t"
+        "addu %[t1], %[t1],      %[t2]                                   \n\t"
+        "sw   %[t8], 2*4(%[in])                                          \n\t"
+        "addu %[t7], %[t7],      %[t1]                                   \n\t"
+        "sw   %[t7], 3*4(%[in])                                          \n\t"
+        "sw   %[t1], 1*4(%[in])                                          \n\t"
+
+        : [in] "+r" (in), [t1] "=&r" (t1), [t2] "=&r" (t2), [t3] "=&r" (t3),
+          [t4] "=&r" (t4), [t5] "=&r" (t5), [t6] "=&r" (t6),
+          [t7] "=&r" (t7), [t8] "=&r" (t8)
+    );
+
+    for(j = 0; j < 2; j++) {
+
+        tmp1 = tmp + j;
+        in1 = in + j;
+
+         /**
+         *  Original constants are multiplied by two in advanced
+         *  for assembly optimization (e.g. C_2 = 2 * C2).
+         *  That can lead to overflow in operations where they are used.
+         *
+         *  Example of the solution:
+         *
+         *  in original code:
+         *  t0 = ((int64_t)(in1[2*2] + in1[2*4]) * (int64_t)(2*C2))>>32
+         *
+         *  in assembly:
+         *  C_2 = 2 * C2;
+         *   .
+         *   .
+         *  "lw   %[t7],       4*4(%[in1])                               \n\t"
+         *  "lw   %[t8],       8*4(%[in1])                               \n\t"
+         *  "addu %[temp_reg2],%[t7],       %[t8]                        \n\t"
+         *  "multu %[C_2],     %[temp_reg2]                              \n\t"
+         *  "mfhi %[temp_reg1]                                           \n\t"
+         *  "sra  %[temp_reg2],%[temp_reg2],31                           \n\t"
+         *  "move %[t0],       $0                                        \n\t"
+         *  "movn %[t0],       %[C_2],      %[temp_reg2]                 \n\t"
+         *  "sub  %[t0],       %[temp_reg1],%[t0]                        \n\t"
+         */
+
+        __asm__ volatile (
+            "lw    %[t7],        4*4(%[in1])                               \n\t"
+            "lw    %[t8],        8*4(%[in1])                               \n\t"
+            "lw    %[t6],        16*4(%[in1])                              \n\t"
+            "lw    %[t4],        0*4(%[in1])                               \n\t"
+            "addu  %[temp_reg2], %[t7],        %[t8]                       \n\t"
+            "addu  %[t2],        %[t6],        %[t8]                       \n\t"
+            "multu %[C_2],       %[temp_reg2]                              \n\t"
+            "lw    %[t5],        12*4(%[in1])                              \n\t"
+            "sub   %[t2],        %[t2],        %[t7]                       \n\t"
+            "sub   %[t1],        %[t4],        %[t5]                       \n\t"
+            "sra   %[t3],        %[t5],        1                           \n\t"
+            "sra   %[temp_reg1], %[t2],        1                           \n\t"
+            "addu  %[t3],        %[t3],        %[t4]                       \n\t"
+            "sub   %[temp_reg1], %[t1],        %[temp_reg1]                \n\t"
+            "sra   %[temp_reg2], %[temp_reg2], 31                          \n\t"
+            "sw    %[temp_reg1], 6*4(%[tmp1])                              \n\t"
+            "move  %[t0],        $0                                        \n\t"
+            "movn  %[t0],        %[C_2],       %[temp_reg2]                \n\t"
+            "mfhi  %[temp_reg1]                                            \n\t"
+            "addu  %[t1],        %[t1],        %[t2]                       \n\t"
+            "sw    %[t1],        16*4(%[tmp1])                             \n\t"
+            "sub   %[temp_reg4], %[t8],        %[t6]                       \n\t"
+            "add   %[temp_reg2], %[t7],        %[t6]                       \n\t"
+            "mult  $ac1,         %[C_8],       %[temp_reg4]                \n\t"
+            "multu $ac2,         %[C_4],       %[temp_reg2]                \n\t"
+            "sub   %[t0],        %[temp_reg1], %[t0]                       \n\t"
+            "sra   %[temp_reg1], %[temp_reg2], 31                          \n\t"
+            "move  %[t2],        $0                                        \n\t"
+            "movn  %[t2],        %[C_4],       %[temp_reg1]                \n\t"
+            "mfhi  %[t1],        $ac1                                      \n\t"
+            "mfhi  %[temp_reg1], $ac2                                      \n\t"
+            "lw    %[t6],        10*4(%[in1])                              \n\t"
+            "lw    %[t8],        14*4(%[in1])                              \n\t"
+            "lw    %[t7],        2*4(%[in1])                               \n\t"
+            "lw    %[t4],        6*4(%[in1])                               \n\t"
+            "sub   %[temp_reg3], %[t3],        %[t0]                       \n\t"
+            "add   %[temp_reg4], %[t3],        %[t0]                       \n\t"
+            "sub   %[temp_reg1], %[temp_reg1], %[temp_reg2]                \n\t"
+            "add   %[temp_reg4], %[temp_reg4], %[t1]                       \n\t"
+            "sub   %[t2],        %[temp_reg1], %[t2]                       \n\t"
+            "sw    %[temp_reg4], 2*4(%[tmp1])                              \n\t"
+            "sub   %[temp_reg3], %[temp_reg3], %[t2]                       \n\t"
+            "add   %[temp_reg1], %[t3],        %[t2]                       \n\t"
+            "sw    %[temp_reg3], 10*4(%[tmp1])                             \n\t"
+            "sub   %[temp_reg1], %[temp_reg1], %[t1]                       \n\t"
+            "addu  %[temp_reg2], %[t6],        %[t8]                       \n\t"
+            "sw    %[temp_reg1], 14*4(%[tmp1])                             \n\t"
+            "sub   %[temp_reg2], %[temp_reg2], %[t7]                       \n\t"
+            "addu  %[temp_reg3], %[t7],        %[t6]                       \n\t"
+            "multu $ac3,         %[C_3],       %[temp_reg2]                \n\t"
+            "multu %[C_1],       %[temp_reg3]                              \n\t"
+            "sra   %[temp_reg1], %[temp_reg2], 31                          \n\t"
+            "move  %[t1],        $0                                        \n\t"
+            "sra   %[temp_reg3], %[temp_reg3], 31                          \n\t"
+            "movn  %[t1],        %[C_3],       %[temp_reg1]                \n\t"
+            "mfhi  %[temp_reg1], $ac3                                      \n\t"
+            "mfhi  %[temp_reg4]                                            \n\t"
+            "move  %[t2],        $0                                        \n\t"
+            "movn  %[t2],        %[C_1],       %[temp_reg3]                \n\t"
+            "sub   %[temp_reg3], %[t6],        %[t8]                       \n\t"
+            "sub   %[t2],        %[temp_reg4], %[t2]                       \n\t"
+            "multu $ac1,         %[C_7],       %[temp_reg3]                \n\t"
+            "sub   %[temp_reg1], %[temp_reg1], %[temp_reg2]                \n\t"
+            "sra   %[temp_reg4], %[temp_reg3], 31                          \n\t"
+            "sub   %[t1],        %[temp_reg1], %[t1]                       \n\t"
+            "move  %[t3],        $0                                        \n\t"
+            "sw    %[t1],        4*4(%[tmp1])                              \n\t"
+            "movn  %[t3],        %[C_7],       %[temp_reg4]                \n\t"
+            "multu $ac2,         %[C_3A],      %[t4]                       \n\t"
+            "add   %[temp_reg2], %[t7],        %[t8]                       \n\t"
+            "move  %[t1],        $0                                        \n\t"
+            "mfhi  %[temp_reg4], $ac1                                      \n\t"
+            "multu $ac3,%[C_5],  %[temp_reg2]                              \n\t"
+            "move  %[t0],        $0                                        \n\t"
+            "sra   %[temp_reg1], %[temp_reg2], 31                          \n\t"
+            "movn  %[t1],%[C_5], %[temp_reg1]                              \n\t"
+            "sub   %[temp_reg4], %[temp_reg4], %[temp_reg3]                \n\t"
+            "mfhi  %[temp_reg1], $ac3                                      \n\t"
+            "sra   %[temp_reg3], %[t4],        31                          \n\t"
+            "movn  %[t0],        %[C_3A],      %[temp_reg3]                \n\t"
+            "mfhi  %[temp_reg3], $ac2                                      \n\t"
+            "sub   %[t3],        %[temp_reg4], %[t3]                       \n\t"
+            "add   %[temp_reg4], %[t3],        %[t2]                       \n\t"
+            "sub   %[temp_reg1], %[temp_reg1], %[temp_reg2]                \n\t"
+            "sub   %[t1],        %[temp_reg1], %[t1]                       \n\t"
+            "sub   %[t0],        %[temp_reg3], %[t0]                       \n\t"
+            "add   %[temp_reg1], %[t2],        %[t1]                       \n\t"
+            "add   %[temp_reg4], %[temp_reg4], %[t0]                       \n\t"
+            "sub   %[temp_reg2], %[t3],        %[t1]                       \n\t"
+            "sw    %[temp_reg4], 0*4(%[tmp1])                              \n\t"
+            "sub   %[temp_reg1], %[temp_reg1], %[t0]                       \n\t"
+            "sub   %[temp_reg2], %[temp_reg2], %[t0]                       \n\t"
+            "sw    %[temp_reg1], 12*4(%[tmp1])                             \n\t"
+            "sw    %[temp_reg2], 8*4(%[tmp1])                              \n\t"
+
+            : [t7] "=&r" (t7), [temp_reg1] "=&r" (temp_reg1),
+              [temp_reg2] "=&r" (temp_reg2), [temp_reg4] "=&r" (temp_reg4),
+              [temp_reg3] "=&r" (temp_reg3), [t8] "=&r" (t8), [t0] "=&r" (t0),
+              [t4] "=&r" (t4), [t5] "=&r" (t5), [t6] "=&r"(t6), [t2] "=&r" (t2),
+              [t3] "=&r" (t3), [t1] "=&r" (t1)
+            : [C_2] "r" (C_2), [in1] "r" (in1), [tmp1] "r" (tmp1), [C_8] "r" (C_8),
+              [C_4] "r" (C_4), [C_3] "r" (C_3), [C_1] "r" (C_1), [C_7] "r" (C_7),
+              [C_3A] "r" (C_3A), [C_5] "r" (C_5)
+            : "hi", "lo"
+         );
+    }
+
+    /**
+    * loop is unrolled four times
+    *
+    * values defined in tables(icos36[] and icos36h[]) are not loaded from
+    * these tables - they are directly loaded in appropriate registers
+    *
+    */
+
+    __asm__ volatile (
+        "lw     %[t2],        1*4(%[tmp])                                  \n\t"
+        "lw     %[t3],        3*4(%[tmp])                                  \n\t"
+        "lw     %[t0],        0*4(%[tmp])                                  \n\t"
+        "lw     %[t1],        2*4(%[tmp])                                  \n\t"
+        "addu   %[temp_reg1], %[t3],        %[t2]                          \n\t"
+        "li     %[temp_reg2], 0x807D2B1E                                   \n\t"
+        "move   %[s1],        $0                                           \n\t"
+        "multu  %[temp_reg2], %[temp_reg1]                                 \n\t"
+        "sra    %[temp_reg1], %[temp_reg1], 31                             \n\t"
+        "movn   %[s1],        %[temp_reg2], %[temp_reg1]                   \n\t"
+        "sub    %[temp_reg3], %[t3],        %[t2]                          \n\t"
+        "li     %[temp_reg4], 0x2de5151                                    \n\t"
+        "mfhi   %[temp_reg2]                                               \n\t"
+        "addu   %[s0],        %[t1],        %[t0]                          \n\t"
+        "lw     %[temp_reg5], 9*4(%[win])                                  \n\t"
+        "mult   $ac1,         %[temp_reg4], %[temp_reg3]                   \n\t"
+        "lw     %[temp_reg6], 4*9*4(%[buf])                                \n\t"
+        "sub    %[s2],        %[t1],        %[t0]                          \n\t"
+        "lw     %[temp_reg3], 29*4(%[win])                                 \n\t"
+        "subu   %[s1],        %[temp_reg2], %[s1]                          \n\t"
+        "lw     %[temp_reg4], 28*4(%[win])                                 \n\t"
+        "add    %[t0],        %[s0],        %[s1]                          \n\t"
+        "extr.w %[s3],        $ac1,23                                      \n\t"
+        "mult   $ac2,         %[t0],        %[temp_reg3]                   \n\t"
+        "sub    %[t1],        %[s0],        %[s1]                          \n\t"
+        "lw     %[temp_reg1], 4*8*4(%[buf])                                \n\t"
+        "mult   %[t1],        %[temp_reg5]                                 \n\t"
+        "lw     %[temp_reg2], 8*4(%[win])                                  \n\t"
+        "mfhi   %[temp_reg3], $ac2                                         \n\t"
+        "mult   $ac3,         %[t0],        %[temp_reg4]                   \n\t"
+        "add    %[t0],        %[s2],        %[s3]                          \n\t"
+        "mfhi   %[temp_reg5]                                               \n\t"
+        "mult   $ac1,         %[t1],        %[temp_reg2]                   \n\t"
+        "sub    %[t1],        %[s2],        %[s3]                          \n\t"
+        "sw     %[temp_reg3], 4*9*4(%[buf])                                \n\t"
+        "mfhi   %[temp_reg4], $ac3                                         \n\t"
+        "lw     %[temp_reg3], 37*4(%[win])                                 \n\t"
+        "mfhi   %[temp_reg2], $ac1                                         \n\t"
+        "add    %[temp_reg5], %[temp_reg5], %[temp_reg6]                   \n\t"
+        "lw     %[temp_reg6], 17*4(%[win])                                 \n\t"
+        "sw     %[temp_reg5], 32*9*4(%[out])                               \n\t"
+        "sw     %[temp_reg4], 4*8*4(%[buf])                                \n\t"
+        "mult   %[t1],        %[temp_reg6]                                 \n\t"
+        "add    %[temp_reg1], %[temp_reg1], %[temp_reg2]                   \n\t"
+        "lw     %[temp_reg2], 0*4(%[win])                                  \n\t"
+        "lw     %[temp_reg5], 4*17*4(%[buf])                               \n\t"
+        "sw     %[temp_reg1], 8*32*4(%[out])                               \n\t"
+        "mfhi   %[temp_reg6]                                               \n\t"
+        "mult   $ac1,         %[t1],        %[temp_reg2]                   \n\t"
+        "lw     %[temp_reg4], 20*4(%[win])                                 \n\t"
+        "lw     %[temp_reg1], 0(%[buf])                                    \n\t"
+        "mult   $ac2,         %[t0],        %[temp_reg3]                   \n\t"
+        "mult   %[t0],        %[temp_reg4]                                 \n\t"
+        "mfhi   %[temp_reg2], $ac1                                         \n\t"
+        "lw     %[t0],        4*4(%[tmp])                                  \n\t"
+        "add    %[temp_reg5], %[temp_reg5], %[temp_reg6]                   \n\t"
+        "mfhi   %[temp_reg3], $ac2                                         \n\t"
+        "mfhi   %[temp_reg4]                                               \n\t"
+        "sw     %[temp_reg5], 17*32*4(%[out])                              \n\t"
+        "lw     %[t1],        6*4(%[tmp])                                  \n\t"
+        "add    %[temp_reg1], %[temp_reg1], %[temp_reg2]                   \n\t"
+        "lw     %[t2],        5*4(%[tmp])                                  \n\t"
+        "sw     %[temp_reg1], 0*32*4(%[out])                               \n\t"
+        "addu   %[s0],        %[t1],        %[t0]                          \n\t"
+        "sw     %[temp_reg3], 4*17*4(%[buf])                               \n\t"
+        "lw     %[t3],        7*4(%[tmp])                                  \n\t"
+        "sub    %[s2],        %[t1],        %[t0]                          \n\t"
+        "sw     %[temp_reg4], 0(%[buf])                                    \n\t"
+        "addu   %[temp_reg5], %[t3],        %[t2]                          \n\t"
+        "li     %[temp_reg6], 0x8483EE0C                                   \n\t"
+        "move   %[s1],        $0                                           \n\t"
+        "multu  %[temp_reg6], %[temp_reg5]                                 \n\t"
+        "sub    %[temp_reg1], %[t3],        %[t2]                          \n\t"
+        "li     %[temp_reg2], 0xf746ea                                     \n\t"
+        "sra    %[temp_reg5], %[temp_reg5], 31                             \n\t"
+        "mult   $ac1,         %[temp_reg2], %[temp_reg1]                   \n\t"
+        "movn   %[s1],        %[temp_reg6], %[temp_reg5]                   \n\t"
+        "mfhi   %[temp_reg5]                                               \n\t"
+        "lw     %[temp_reg3], 10*4(%[win])                                 \n\t"
+        "lw     %[temp_reg4], 4*10*4(%[buf])                               \n\t"
+        "extr.w %[s3],        $ac1,         23                             \n\t"
+        "lw     %[temp_reg1], 4*7*4(%[buf])                                \n\t"
+        "lw     %[temp_reg2], 7*4(%[win])                                  \n\t"
+        "lw     %[temp_reg6], 30*4(%[win])                                 \n\t"
+        "subu   %[s1],        %[temp_reg5], %[s1]                          \n\t"
+        "sub    %[t1],        %[s0],        %[s1]                          \n\t"
+        "add    %[t0],        %[s0],        %[s1]                          \n\t"
+        "mult   $ac2,         %[t1],        %[temp_reg3]                   \n\t"
+        "mult   $ac3,         %[t1],        %[temp_reg2]                   \n\t"
+        "mult   %[t0],        %[temp_reg6]                                 \n\t"
+        "lw     %[temp_reg5], 27*4(%[win])                                 \n\t"
+        "mult   $ac1,         %[t0],        %[temp_reg5]                   \n\t"
+        "mfhi   %[temp_reg3], $ac2                                         \n\t"
+        "mfhi   %[temp_reg2], $ac3                                         \n\t"
+        "mfhi   %[temp_reg6]                                               \n\t"
+        "add    %[t0],        %[s2],        %[s3]                          \n\t"
+        "sub    %[t1],        %[s2],        %[s3]                          \n\t"
+        "add    %[temp_reg3], %[temp_reg3], %[temp_reg4]                   \n\t"
+        "lw     %[temp_reg4], 16*4(%[win])                                 \n\t"
+        "mfhi   %[temp_reg5], $ac1                                         \n\t"
+        "sw     %[temp_reg3], 32*10*4(%[out])                              \n\t"
+        "add    %[temp_reg1], %[temp_reg1], %[temp_reg2]                   \n\t"
+        "lw     %[temp_reg3], 4*16*4(%[buf])                               \n\t"
+        "sw     %[temp_reg6], 4*10*4(%[buf])                               \n\t"
+        "sw     %[temp_reg1], 7*32*4(%[out])                               \n\t"
+        "mult   $ac2,         %[t1],        %[temp_reg4]                   \n\t"
+        "sw     %[temp_reg5], 4*7*4(%[buf])                                \n\t"
+        "lw     %[temp_reg6], 1*4(%[win])                                  \n\t"
+        "lw     %[temp_reg5], 4*1*4(%[buf])                                \n\t"
+        "lw     %[temp_reg1], 36*4(%[win])                                 \n\t"
+        "mult   $ac3,         %[t1],        %[temp_reg6]                   \n\t"
+        "lw     %[temp_reg2], 21*4(%[win])                                 \n\t"
+        "mfhi   %[temp_reg4], $ac2                                         \n\t"
+        "mult   %[t0],        %[temp_reg1]                                 \n\t"
+        "mult   $ac1,         %[t0],%[temp_reg2]                           \n\t"
+        "lw     %[t0],        8*4(%[tmp])                                  \n\t"
+        "mfhi   %[temp_reg6], $ac3                                         \n\t"
+        "lw     %[t1],        10*4(%[tmp])                                 \n\t"
+        "lw     %[t3],        11*4(%[tmp])                                 \n\t"
+        "mfhi   %[temp_reg1]                                               \n\t"
+        "add    %[temp_reg3], %[temp_reg3], %[temp_reg4]                   \n\t"
+        "lw     %[t2],        9*4(%[tmp])                                  \n\t"
+        "mfhi   %[temp_reg2], $ac1                                         \n\t"
+        "add    %[temp_reg5], %[temp_reg5], %[temp_reg6]                   \n\t"
+        "sw     %[temp_reg3], 16*32*4(%[out])                              \n\t"
+        "sw     %[temp_reg5], 1*32*4(%[out])                               \n\t"
+        "sw     %[temp_reg1], 4*16*4(%[buf])                               \n\t"
+        "addu   %[temp_reg3], %[t3],        %[t2]                          \n\t"
+        "li     %[temp_reg4], 0x8D3B7CD6                                   \n\t"
+        "sw     %[temp_reg2], 4*1*4(%[buf])                                \n\t"
+        "multu  %[temp_reg4],%[temp_reg3]                                  \n\t"
+        "sra    %[temp_reg3], %[temp_reg3], 31                             \n\t"
+        "move   %[s1],        $0                                           \n\t"
+        "movn   %[s1],        %[temp_reg4], %[temp_reg3]                   \n\t"
+        "addu   %[s0],        %[t1],        %[t0]                          \n\t"
+        "mfhi   %[temp_reg3]                                               \n\t"
+        "sub    %[s2],        %[t1],        %[t0]                          \n\t"
+        "sub    %[temp_reg5], %[t3],        %[t2]                          \n\t"
+        "li     %[temp_reg6], 0x976fd9                                     \n\t"
+        "lw     %[temp_reg2], 11*4(%[win])                                 \n\t"
+        "lw     %[temp_reg1], 4*11*4(%[buf])                               \n\t"
+        "mult   $ac1,         %[temp_reg6], %[temp_reg5]                   \n\t"
+        "subu   %[s1],        %[temp_reg3], %[s1]                          \n\t"
+        "lw     %[temp_reg5], 31*4(%[win])                                 \n\t"
+        "sub    %[t1],        %[s0],        %[s1]                          \n\t"
+        "add    %[t0],        %[s0],        %[s1]                          \n\t"
+        "mult   $ac2,         %[t1],        %[temp_reg2]                   \n\t"
+        "mult   %[t0],        %[temp_reg5]                                 \n\t"
+        "lw     %[temp_reg4], 6*4(%[win])                                  \n\t"
+        "extr.w %[s3],        $ac1,         23                             \n\t"
+        "lw     %[temp_reg3], 4*6*4(%[buf])                                \n\t"
+        "mfhi   %[temp_reg2], $ac2                                         \n\t"
+        "lw     %[temp_reg6], 26*4(%[win])                                 \n\t"
+        "mfhi   %[temp_reg5]                                               \n\t"
+        "mult   $ac3,         %[t1],        %[temp_reg4]                   \n\t"
+        "mult   $ac1,         %[t0],        %[temp_reg6]                   \n\t"
+        "add    %[t0],        %[s2],        %[s3]                          \n\t"
+        "sub    %[t1],        %[s2],        %[s3]                          \n\t"
+        "add    %[temp_reg2], %[temp_reg2], %[temp_reg1]                   \n\t"
+        "mfhi   %[temp_reg4], $ac3                                         \n\t"
+        "mfhi   %[temp_reg6], $ac1                                         \n\t"
+        "sw     %[temp_reg5], 4*11*4(%[buf])                               \n\t"
+        "sw     %[temp_reg2], 32*11*4(%[out])                              \n\t"
+        "lw     %[temp_reg1], 4*15*4(%[buf])                               \n\t"
+        "add    %[temp_reg3], %[temp_reg3], %[temp_reg4]                   \n\t"
+        "lw     %[temp_reg2], 15*4(%[win])                                 \n\t"
+        "sw     %[temp_reg3], 6*32*4(%[out])                               \n\t"
+        "sw     %[temp_reg6], 4*6*4(%[buf])                                \n\t"
+        "mult   %[t1],        %[temp_reg2]                                 \n\t"
+        "lw     %[temp_reg3], 2*4(%[win])                                  \n\t"
+        "lw     %[temp_reg4], 4*2*4(%[buf])                                \n\t"
+        "lw     %[temp_reg5], 35*4(%[win])                                 \n\t"
+        "mult   $ac1,         %[t1],        %[temp_reg3]                   \n\t"
+        "mfhi   %[temp_reg2]                                               \n\t"
+        "lw     %[temp_reg6], 22*4(%[win])                                 \n\t"
+        "mult   $ac2,         %[t0],        %[temp_reg5]                   \n\t"
+        "lw     %[t1],        14*4(%[tmp])                                 \n\t"
+        "mult   $ac3,         %[t0],        %[temp_reg6]                   \n\t"
+        "lw     %[t0],        12*4(%[tmp])                                 \n\t"
+        "mfhi   %[temp_reg3], $ac1                                         \n\t"
+        "add    %[temp_reg1], %[temp_reg1], %[temp_reg2]                   \n\t"
+        "mfhi   %[temp_reg5], $ac2                                         \n\t"
+        "sw     %[temp_reg1], 15*32*4(%[out])                              \n\t"
+        "mfhi   %[temp_reg6], $ac3                                         \n\t"
+        "lw     %[t2],        13*4(%[tmp])                                 \n\t"
+        "lw     %[t3],        15*4(%[tmp])                                 \n\t"
+        "add    %[temp_reg4], %[temp_reg4], %[temp_reg3]                   \n\t"
+        "sw     %[temp_reg5], 4*15*4(%[buf])                               \n\t"
+        "addu   %[temp_reg1], %[t3],        %[t2]                          \n\t"
+        "li     %[temp_reg2], 0x9C42577C                                   \n\t"
+        "move   %[s1],        $0                                           \n\t"
+        "multu  %[temp_reg2], %[temp_reg1]                                 \n\t"
+        "sw     %[temp_reg4], 2*32*4(%[out])                               \n\t"
+        "sra    %[temp_reg1], %[temp_reg1], 31                             \n\t"
+        "movn   %[s1],        %[temp_reg2], %[temp_reg1]                   \n\t"
+        "sub    %[temp_reg3], %[t3],        %[t2]                          \n\t"
+        "li     %[temp_reg4], 0x6f94a2                                     \n\t"
+        "mfhi   %[temp_reg1]                                               \n\t"
+        "addu   %[s0],        %[t1],        %[t0]                          \n\t"
+        "sw     %[temp_reg6], 4*2*4(%[buf])                                \n\t"
+        "mult   $ac1,         %[temp_reg4], %[temp_reg3]                   \n\t"
+        "sub    %[s2],        %[t1],        %[t0]                          \n\t"
+        "lw     %[temp_reg5], 12*4(%[win])                                 \n\t"
+        "lw     %[temp_reg6], 4*12*4(%[buf])                               \n\t"
+        "subu   %[s1],        %[temp_reg1], %[s1]                          \n\t"
+        "sub    %[t1],        %[s0],        %[s1]                          \n\t"
+        "lw     %[temp_reg3], 32*4(%[win])                                 \n\t"
+        "mult   $ac2,         %[t1],        %[temp_reg5]                   \n\t"
+        "add    %[t0],        %[s0],        %[s1]                          \n\t"
+        "extr.w %[s3],        $ac1,         23                             \n\t"
+        "lw     %[temp_reg2], 5*4(%[win])                                  \n\t"
+        "mult   %[t0],        %[temp_reg3]                                 \n\t"
+        "mfhi   %[temp_reg5], $ac2                                         \n\t"
+        "lw     %[temp_reg4], 25*4(%[win])                                 \n\t"
+        "lw     %[temp_reg1], 4*5*4(%[buf])                                \n\t"
+        "mult   $ac3,         %[t1],        %[temp_reg2]                   \n\t"
+        "mult   $ac1,         %[t0],        %[temp_reg4]                   \n\t"
+        "mfhi   %[temp_reg3]                                               \n\t"
+        "add    %[t0],        %[s2],        %[s3]                          \n\t"
+        "add    %[temp_reg5], %[temp_reg5], %[temp_reg6]                   \n\t"
+        "mfhi   %[temp_reg2], $ac3                                         \n\t"
+        "mfhi   %[temp_reg4], $ac1                                         \n\t"
+        "sub    %[t1],        %[s2],        %[s3]                          \n\t"
+        "sw     %[temp_reg5], 32*12*4(%[out])                              \n\t"
+        "sw     %[temp_reg3], 4*12*4(%[buf])                               \n\t"
+        "lw     %[temp_reg6], 14*4(%[win])                                 \n\t"
+        "lw     %[temp_reg5], 4*14*4(%[buf])                               \n\t"
+        "add    %[temp_reg1], %[temp_reg1], %[temp_reg2]                   \n\t"
+        "sw     %[temp_reg4], 4*5*4(%[buf])                                \n\t"
+        "sw     %[temp_reg1], 5*32*4(%[out])                               \n\t"
+        "mult   %[t1],        %[temp_reg6]                                 \n\t"
+        "lw     %[temp_reg4], 34*4(%[win])                                 \n\t"
+        "lw     %[temp_reg2], 3*4(%[win])                                  \n\t"
+        "lw     %[temp_reg1], 4*3*4(%[buf])                                \n\t"
+        "mult   $ac2,         %[t0],        %[temp_reg4]                   \n\t"
+        "mfhi   %[temp_reg6]                                               \n\t"
+        "mult   $ac1,         %[t1],        %[temp_reg2]                   \n\t"
+        "lw     %[temp_reg3], 23*4(%[win])                                 \n\t"
+        "lw     %[s0],        16*4(%[tmp])                                 \n\t"
+        "mfhi   %[temp_reg4], $ac2                                         \n\t"
+        "lw     %[t1],        17*4(%[tmp])                                 \n\t"
+        "mult   $ac3,         %[t0],        %[temp_reg3]                   \n\t"
+        "move   %[s1],        $0                                           \n\t"
+        "add    %[temp_reg5], %[temp_reg5], %[temp_reg6]                   \n\t"
+        "mfhi   %[temp_reg2], $ac1                                         \n\t"
+        "sw     %[temp_reg5], 14*32*4(%[out])                              \n\t"
+        "sw     %[temp_reg4], 4*14*4(%[buf])                               \n\t"
+        "mfhi   %[temp_reg3], $ac3                                         \n\t"
+        "li     %[temp_reg5], 0xB504F334                                   \n\t"
+        "add    %[temp_reg1], %[temp_reg1], %[temp_reg2]                   \n\t"
+        "multu  %[temp_reg5], %[t1]                                        \n\t"
+        "lw     %[temp_reg2], 4*13*4(%[buf])                               \n\t"
+        "sw     %[temp_reg1], 3*32*4(%[out])                               \n\t"
+        "sra    %[t1],        %[t1],        31                             \n\t"
+        "mfhi   %[temp_reg6]                                               \n\t"
+        "movn   %[s1],        %[temp_reg5], %[t1]                          \n\t"
+        "sw     %[temp_reg3], 4*3*4(%[buf])                                \n\t"
+        "lw     %[temp_reg1], 13*4(%[win])                                 \n\t"
+        "lw     %[temp_reg4], 4*4*4(%[buf])                                \n\t"
+        "lw     %[temp_reg3], 4*4(%[win])                                  \n\t"
+        "lw     %[temp_reg5], 33*4(%[win])                                 \n\t"
+        "subu   %[s1],        %[temp_reg6], %[s1]                          \n\t"
+        "lw     %[temp_reg6], 24*4(%[win])                                 \n\t"
+        "sub    %[t1],        %[s0],        %[s1]                          \n\t"
+        "add    %[t0],        %[s0],        %[s1]                          \n\t"
+        "mult   $ac1,         %[t1],        %[temp_reg1]                   \n\t"
+        "mult   $ac2,         %[t1],        %[temp_reg3]                   \n\t"
+        "mult   $ac3,         %[t0],        %[temp_reg5]                   \n\t"
+        "mult   %[t0],        %[temp_reg6]                                 \n\t"
+        "mfhi   %[temp_reg1], $ac1                                         \n\t"
+        "mfhi   %[temp_reg3], $ac2                                         \n\t"
+        "mfhi   %[temp_reg5], $ac3                                         \n\t"
+        "mfhi   %[temp_reg6]                                               \n\t"
+        "add    %[temp_reg2], %[temp_reg2], %[temp_reg1]                   \n\t"
+        "add    %[temp_reg4], %[temp_reg4], %[temp_reg3]                   \n\t"
+        "sw     %[temp_reg2], 13*32*4(%[out])                              \n\t"
+        "sw     %[temp_reg4], 4*32*4(%[out])                               \n\t"
+        "sw     %[temp_reg5], 4*13*4(%[buf])                               \n\t"
+        "sw     %[temp_reg6], 4*4*4(%[buf])                                \n\t"
+
+        : [t0] "=&r" (t0), [t1] "=&r" (t1), [t2] "=&r" (t2), [t3] "=&r" (t3),
+          [s0] "=&r" (s0), [s2] "=&r" (s2), [temp_reg1] "=&r" (temp_reg1),
+          [temp_reg2] "=&r" (temp_reg2), [s1] "=&r" (s1), [s3] "=&r" (s3),
+          [temp_reg3] "=&r" (temp_reg3), [temp_reg4] "=&r" (temp_reg4),
+          [temp_reg5] "=&r" (temp_reg5), [temp_reg6] "=&r" (temp_reg6),
+          [out] "+r" (out)
+        : [tmp] "r" (tmp), [win] "r" (win), [buf] "r" (buf)
+        : "hi", "lo"
+    );
+}
+
+static void ff_imdct36_blocks_mips_fixed(int *out, int *buf, int *in,
+                               int count, int switch_point, int block_type)
+{
+    int j;
+    for (j=0 ; j < count; j++) {
+        /* apply window & overlap with previous buffer */
+
+        /* select window */
+        int win_idx = (switch_point && j < 2) ? 0 : block_type;
+        int *win = ff_mdct_win_fixed[win_idx + (4 & -(j & 1))];
+
+        imdct36_mips_fixed(out, buf, in, win);
+
+        in  += 18;
+        buf += ((j&3) != 3 ? 1 : (72-3));
+        out++;
+    }
+}
+
+void ff_mpadsp_init_mipsdspr1(MPADSPContext *s)
+{
+    s->apply_window_fixed   = ff_mpadsp_apply_window_mips_fixed;
+    s->imdct36_blocks_fixed = ff_imdct36_blocks_mips_fixed;
+}
diff --git a/libavcodec/mips/mpegaudiodsp_mips_float.c b/libavcodec/mips/mpegaudiodsp_mips_float.c
new file mode 100644
index 0000000..00a7f20
--- /dev/null
+++ b/libavcodec/mips/mpegaudiodsp_mips_float.c
@@ -0,0 +1,1242 @@
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Bojan Zivkovic (bojan@mips.com)
+ *
+ * MPEG Audio decoder optimized for MIPS floating-point architecture
+ *
+ * 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/mpegaudiodsp_template.c
+ *            libavcodec/dct32.c
+ */
+
+#include <string.h>
+
+#include "libavcodec/mpegaudiodsp.h"
+
+static void ff_mpadsp_apply_window_mips_float(float *synth_buf, float *window,
+                               int *dither_state, float *samples, int incr)
+{
+    register const float *w, *w2, *p;
+    int j;
+    float *samples2;
+    float sum, sum2;
+    /* temporary variables */
+    int incr1 = incr << 2;
+    int t_sample;
+    float in1, in2, in3, in4, in5, in6, in7, in8;
+    float *p2;
+
+    /* copy to avoid wrap */
+    memcpy(synth_buf + 512, synth_buf, 32 * sizeof(*synth_buf));
+
+    /**
+    * instructions are scheduled to minimize pipeline stall.
+    * use of round_sample function from the original code is
+    * changed with appropriate assembly instructions.
+    */
+
+    __asm__ volatile (
+        "lwc1    %[sum],      0(%[dither_state])                            \t\n"
+        "sll     %[t_sample], %[incr1],     5                               \t\n"
+        "sub     %[t_sample], %[t_sample],  %[incr1]                        \n\t"
+        "li      %[j],        4                                             \t\n"
+        "lwc1    %[in1],      0(%[window])                                  \t\n"
+        "lwc1    %[in2],      16*4(%[synth_buf])                            \t\n"
+        "sw      $zero,       0(%[dither_state])                            \t\n"
+        "lwc1    %[in3],      64*4(%[window])                               \t\n"
+        "lwc1    %[in4],      80*4(%[synth_buf])                            \t\n"
+        "addu    %[samples2], %[samples],   %[t_sample]                     \t\n"
+        "madd.s  %[sum],      %[sum],       %[in1], %[in2]                  \t\n"
+        "lwc1    %[in5],      128*4(%[window])                              \t\n"
+        "lwc1    %[in6],      144*4(%[synth_buf])                           \t\n"
+        "lwc1    %[in7],      192*4(%[window])                              \t\n"
+        "madd.s  %[sum],      %[sum],       %[in3], %[in4]                  \t\n"
+        "lwc1    %[in8],      208*4(%[synth_buf])                           \t\n"
+        "lwc1    %[in1],      256*4(%[window])                              \t\n"
+        "lwc1    %[in2],      272*4(%[synth_buf])                           \t\n"
+        "madd.s  %[sum],      %[sum],       %[in5], %[in6]                  \t\n"
+        "lwc1    %[in3],      320*4(%[window])                              \t\n"
+        "lwc1    %[in4],      336*4(%[synth_buf])                           \t\n"
+        "lwc1    %[in5],      384*4(%[window])                              \t\n"
+        "madd.s  %[sum],      %[sum],       %[in7], %[in8]                  \t\n"
+        "lwc1    %[in6],      400*4(%[synth_buf])                           \t\n"
+        "lwc1    %[in7],      448*4(%[window])                              \t\n"
+        "lwc1    %[in8],      464*4(%[synth_buf])                           \t\n"
+        "madd.s  %[sum],      %[sum],       %[in1], %[in2]                  \t\n"
+        "lwc1    %[in1],      32*4(%[window])                               \t\n"
+        "lwc1    %[in2],      48*4(%[synth_buf])                            \t\n"
+        "madd.s  %[sum],      %[sum],       %[in3], %[in4]                  \t\n"
+        "lwc1    %[in3],      96*4(%[window])                               \t\n"
+        "lwc1    %[in4],      112*4(%[synth_buf])                           \t\n"
+        "madd.s  %[sum],      %[sum],       %[in5], %[in6]                  \t\n"
+        "lwc1    %[in5],      160*4(%[window])                              \t\n"
+        "lwc1    %[in6],      176*4(%[synth_buf])                           \t\n"
+        "madd.s  %[sum],      %[sum],       %[in7], %[in8]                  \t\n"
+        "lwc1    %[in7],      224*4(%[window])                              \t\n"
+        "lwc1    %[in8],      240*4(%[synth_buf])                           \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in1], %[in2]                  \t\n"
+        "lwc1    %[in1],      288*4(%[window])                              \t\n"
+        "lwc1    %[in2],      304*4(%[synth_buf])                           \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in3], %[in4]                  \t\n"
+        "lwc1    %[in3],      352*4(%[window])                              \t\n"
+        "lwc1    %[in4],      368*4(%[synth_buf])                           \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in5], %[in6]                  \t\n"
+        "lwc1    %[in5],      416*4(%[window])                              \t\n"
+        "lwc1    %[in6],      432*4(%[synth_buf])                           \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in7], %[in8]                  \t\n"
+        "lwc1    %[in7],      480*4(%[window])                              \t\n"
+        "lwc1    %[in8],      496*4(%[synth_buf])                           \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in1], %[in2]                  \t\n"
+        "addu    %[w],        %[window],    4                               \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in3], %[in4]                  \t\n"
+        "addu    %[w2],       %[window],    124                             \t\n"
+        "addiu   %[p],        %[synth_buf], 68                              \t\n"
+        "addiu   %[p2],       %[synth_buf], 188                             \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in5], %[in6]                  \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in7], %[in8]                  \t\n"
+        "swc1    %[sum],      0(%[samples])                                 \t\n"
+        "addu    %[samples],  %[samples],   %[incr1]                        \t\n"
+
+        /* calculate two samples at the same time to avoid one memory
+           access per two sample */
+
+        "ff_mpadsp_apply_window_loop%=:                                     \t\n"
+        "lwc1    %[in1],      0(%[w])                                       \t\n"
+        "lwc1    %[in2],      0(%[p])                                       \t\n"
+        "lwc1    %[in3],      0(%[w2])                                      \t\n"
+        "lwc1    %[in4],      64*4(%[w])                                    \t\n"
+        "lwc1    %[in5],      64*4(%[p])                                    \t\n"
+        "lwc1    %[in6],      64*4(%[w2])                                   \t\n"
+        "mul.s   %[sum],      %[in1],       %[in2]                          \t\n"
+        "mul.s   %[sum2],     %[in2],       %[in3]                          \t\n"
+        "lwc1    %[in1],      128*4(%[w])                                   \t\n"
+        "lwc1    %[in2],      128*4(%[p])                                   \t\n"
+        "madd.s  %[sum],      %[sum],       %[in4], %[in5]                  \t\n"
+        "nmadd.s %[sum2],     %[sum2],      %[in5], %[in6]                  \t\n"
+        "lwc1    %[in3],      128*4(%[w2])                                  \t\n"
+        "lwc1    %[in4],      192*4(%[w])                                   \t\n"
+        "madd.s  %[sum],      %[sum],       %[in1], %[in2]                  \t\n"
+        "lwc1    %[in5],      192*4(%[p])                                   \t\n"
+        "lwc1    %[in6],      192*4(%[w2])                                  \t\n"
+        "nmsub.s %[sum2],     %[sum2],      %[in2], %[in3]                  \t\n"
+        "lwc1    %[in1],      256*4(%[w])                                   \t\n"
+        "lwc1    %[in2],      256*4(%[p])                                   \t\n"
+        "madd.s  %[sum],      %[sum],       %[in4], %[in5]                  \t\n"
+        "nmsub.s %[sum2],     %[sum2],      %[in5], %[in6]                  \t\n"
+        "lwc1    %[in3],      256*4(%[w2])                                  \t\n"
+        "lwc1    %[in4],      320*4(%[w])                                   \t\n"
+        "madd.s  %[sum],      %[sum],       %[in1], %[in2]                  \t\n"
+        "lwc1    %[in5],      320*4(%[p])                                   \t\n"
+        "lwc1    %[in6],      320*4(%[w2])                                  \t\n"
+        "nmsub.s %[sum2],     %[sum2],      %[in2], %[in3]                  \t\n"
+        "lwc1    %[in1],      384*4(%[w])                                   \t\n"
+        "lwc1    %[in2],      384*4(%[p])                                   \t\n"
+        "madd.s  %[sum],      %[sum],       %[in4], %[in5]                  \t\n"
+        "nmsub.s %[sum2],     %[sum2],      %[in5], %[in6]                  \t\n"
+        "lwc1    %[in3],      384*4(%[w2])                                  \t\n"
+        "lwc1    %[in4],      448*4(%[w])                                   \t\n"
+        "madd.s  %[sum],      %[sum],       %[in1], %[in2]                  \t\n"
+        "lwc1    %[in5],      448*4(%[p])                                   \t\n"
+        "lwc1    %[in6],      448*4(%[w2])                                  \t\n"
+        "nmsub.s %[sum2],     %[sum2],      %[in2], %[in3]                  \t\n"
+        "madd.s  %[sum],      %[sum],       %[in4], %[in5]                  \t\n"
+        "lwc1    %[in1],      32*4(%[w])                                    \t\n"
+        "lwc1    %[in2],      0(%[p2])                                      \t\n"
+        "nmsub.s %[sum2],     %[sum2],      %[in5], %[in6]                  \t\n"
+        "lwc1    %[in3],      32*4(%[w2])                                   \t\n"
+        "lwc1    %[in4],      96*4(%[w])                                    \t\n"
+        "lwc1    %[in5],      64*4(%[p2])                                   \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in1], %[in2]                  \t\n"
+        "lwc1    %[in6],      96*4(%[w2])                                   \t\n"
+        "nmsub.s %[sum2],     %[sum2],      %[in2], %[in3]                  \t\n"
+        "lwc1    %[in1],      160*4(%[w])                                   \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in4], %[in5]                  \t\n"
+        "lwc1    %[in2],      128*4(%[p2])                                  \t\n"
+        "nmsub.s %[sum2],     %[sum2],      %[in5], %[in6]                  \t\n"
+        "lwc1    %[in3],      160*4(%[w2])                                  \t\n"
+        "lwc1    %[in4],      224*4(%[w])                                   \t\n"
+        "lwc1    %[in5],      192*4(%[p2])                                  \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in1], %[in2]                  \t\n"
+        "lwc1    %[in6],      224*4(%[w2])                                  \t\n"
+        "nmsub.s %[sum2],     %[sum2],      %[in2], %[in3]                  \t\n"
+        "lwc1    %[in1],      288*4(%[w])                                   \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in4], %[in5]                  \t\n"
+        "lwc1    %[in2],      256*4(%[p2])                                  \t\n"
+        "nmsub.s %[sum2],     %[sum2],      %[in5], %[in6]                  \t\n"
+        "lwc1    %[in3],      288*4(%[w2])                                  \t\n"
+        "lwc1    %[in4],      352*4(%[w])                                   \t\n"
+        "lwc1    %[in5],      320*4(%[p2])                                  \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in1], %[in2]                  \t\n"
+        "lwc1    %[in6],      352*4(%[w2])                                  \t\n"
+        "nmsub.s %[sum2],     %[sum2],      %[in2], %[in3]                  \t\n"
+        "lwc1    %[in1],      416*4(%[w])                                   \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in4], %[in5]                  \t\n"
+        "lwc1    %[in2],      384*4(%[p2])                                  \t\n"
+        "nmsub.s %[sum2],     %[sum2],      %[in5], %[in6]                  \t\n"
+        "lwc1    %[in3],      416*4(%[w2])                                  \t\n"
+        "lwc1    %[in4],      480*4(%[w])                                   \t\n"
+        "lwc1    %[in5],      448*4(%[p2])                                  \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in1], %[in2]                  \t\n"
+        "lwc1    %[in6],      480*4(%[w2])                                  \t\n"
+        "nmsub.s %[sum2],     %[sum2],      %[in2], %[in3]                  \t\n"
+        "addiu   %[w],        %[w],         4                               \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in4], %[in5]                  \t\n"
+        "addiu   %[w2],       %[w2],        -4                              \t\n"
+        "nmsub.s %[sum2],     %[sum2],      %[in5], %[in6]                  \t\n"
+        "addu    %[j],        %[j],         4                               \t\n"
+        "addiu   %[p],        4                                             \t\n"
+        "swc1    %[sum],      0(%[samples])                                 \t\n"
+        "addiu   %[p2],       -4                                            \t\n"
+        "swc1    %[sum2],     0(%[samples2])                                \t\n"
+        "addu    %[samples],  %[samples],   %[incr1]                        \t\n"
+        "subu    %[samples2], %[samples2],  %[incr1]                        \t\n"
+        "bne     %[j],        64,           ff_mpadsp_apply_window_loop%=   \t\n"
+
+        "lwc1    %[in1],      48*4(%[window])                               \t\n"
+        "lwc1    %[in2],      32*4(%[synth_buf])                            \t\n"
+        "lwc1    %[in3],      112*4(%[window])                              \t\n"
+        "lwc1    %[in4],      96*4(%[synth_buf])                            \t\n"
+        "lwc1    %[in5],      176*4(%[window])                              \t\n"
+        "lwc1    %[in6],      160*4(%[synth_buf])                           \t\n"
+        "mul.s   %[sum],      %[in1],       %[in2]                          \t\n"
+        "lwc1    %[in7],      240*4(%[window])                              \t\n"
+        "lwc1    %[in8],      224*4(%[synth_buf])                           \t\n"
+        "lwc1    %[in1],      304*4(%[window])                              \t\n"
+        "nmadd.s %[sum],      %[sum],       %[in3], %[in4]                  \t\n"
+        "lwc1    %[in2],      288*4(%[synth_buf])                           \t\n"
+        "lwc1    %[in3],      368*4(%[window])                              \t\n"
+        "lwc1    %[in4],      352*4(%[synth_buf])                           \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in5], %[in6]                  \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in7], %[in8]                  \t\n"
+        "lwc1    %[in5],      432*4(%[window])                              \t\n"
+        "lwc1    %[in6],      416*4(%[synth_buf])                           \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in1], %[in2]                  \t\n"
+        "lwc1    %[in7],      496*4(%[window])                              \t\n"
+        "lwc1    %[in8],      480*4(%[synth_buf])                           \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in3], %[in4]                  \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in5], %[in6]                  \t\n"
+        "nmsub.s %[sum],      %[sum],       %[in7], %[in8]                  \t\n"
+        "swc1    %[sum],      0(%[samples])                                 \t\n"
+
+        : [sum] "=&f" (sum), [sum2] "=&f" (sum2),
+          [w2] "=&r" (w2),   [w] "=&r" (w),
+          [p] "=&r" (p), [p2] "=&r" (p2), [j] "=&r" (j),
+          [samples] "+r" (samples), [samples2] "=&r" (samples2),
+          [in1] "=&f" (in1), [in2] "=&f" (in2),
+          [in3] "=&f" (in3), [in4] "=&f" (in4),
+          [in5] "=&f" (in5), [in6] "=&f" (in6),
+          [in7] "=&f" (in7), [in8] "=&f" (in8),
+          [t_sample] "=&r" (t_sample)
+        : [synth_buf] "r" (synth_buf), [window] "r" (window),
+          [dither_state] "r" (dither_state), [incr1] "r" (incr1)
+    );
+}
+
+static void ff_dct32_mips_float(float *out, const float *tab)
+{
+    float val0 , val1 , val2 , val3 , val4 , val5 , val6 , val7,
+          val8 , val9 , val10, val11, val12, val13, val14, val15,
+          val16, val17, val18, val19, val20, val21, val22, val23,
+          val24, val25, val26, val27, val28, val29, val30, val31;
+    float fTmp1, fTmp2, fTmp3, fTmp4, fTmp5, fTmp6, fTmp7, fTmp8,
+          fTmp9, fTmp10, fTmp11;
+
+    /**
+    * instructions are scheduled to minimize pipeline stall.
+    */
+    __asm__ volatile (
+        "lwc1       %[fTmp1],       0*4(%[tab])                             \n\t"
+        "lwc1       %[fTmp2],       31*4(%[tab])                            \n\t"
+        "lwc1       %[fTmp3],       15*4(%[tab])                            \n\t"
+        "lwc1       %[fTmp4],       16*4(%[tab])                            \n\t"
+        "li.s       %[fTmp7],       0.50241928618815570551                  \n\t"
+        "add.s      %[fTmp5],       %[fTmp1],       %[fTmp2]                \n\t"
+        "sub.s      %[fTmp8],       %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[fTmp6],       %[fTmp3],       %[fTmp4]                \n\t"
+        "sub.s      %[fTmp9],       %[fTmp3],       %[fTmp4]                \n\t"
+        "li.s       %[fTmp10],      0.50060299823519630134                  \n\t"
+        "li.s       %[fTmp11],      10.19000812354805681150                 \n\t"
+        "mul.s      %[fTmp8],       %[fTmp8],       %[fTmp10]               \n\t"
+        "add.s      %[val0],        %[fTmp5],       %[fTmp6]                \n\t"
+        "sub.s      %[val15],       %[fTmp5],       %[fTmp6]                \n\t"
+        "lwc1       %[fTmp1],       7*4(%[tab])                             \n\t"
+        "lwc1       %[fTmp2],       24*4(%[tab])                            \n\t"
+        "madd.s     %[val16],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "nmsub.s    %[val31],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "mul.s      %[val15],       %[val15],       %[fTmp7]                \n\t"
+        "lwc1       %[fTmp3],       8*4(%[tab])                             \n\t"
+        "lwc1       %[fTmp4],       23*4(%[tab])                            \n\t"
+        "add.s      %[fTmp5],       %[fTmp1],       %[fTmp2]                \n\t"
+        "mul.s      %[val31],       %[val31],       %[fTmp7]                \n\t"
+        "sub.s      %[fTmp8],       %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[fTmp6],       %[fTmp3],       %[fTmp4]                \n\t"
+        "sub.s      %[fTmp9],       %[fTmp3],       %[fTmp4]                \n\t"
+        "li.s       %[fTmp7],       5.10114861868916385802                  \n\t"
+        "li.s       %[fTmp10],      0.67480834145500574602                  \n\t"
+        "li.s       %[fTmp11],      0.74453627100229844977                  \n\t"
+        "add.s      %[val7],        %[fTmp5],       %[fTmp6]                \n\t"
+        "sub.s      %[val8],        %[fTmp5],       %[fTmp6]                \n\t"
+        "mul.s      %[fTmp8],       %[fTmp8],       %[fTmp10]               \n\t"
+        "li.s       %[fTmp1],       0.50979557910415916894                  \n\t"
+        "sub.s      %[fTmp2],       %[val0],        %[val7]                 \n\t"
+        "mul.s      %[val8],        %[val8],        %[fTmp7]                \n\t"
+        "madd.s     %[val23],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "nmsub.s    %[val24],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "add.s      %[val0],        %[val0],        %[val7]                 \n\t"
+        "mul.s      %[val7],        %[fTmp1],       %[fTmp2]                \n\t"
+        "sub.s      %[fTmp2],       %[val15],       %[val8]                 \n\t"
+        "add.s      %[val8],        %[val15],       %[val8]                 \n\t"
+        "mul.s      %[val24],       %[val24],       %[fTmp7]                \n\t"
+        "sub.s      %[fTmp3],       %[val16],       %[val23]                \n\t"
+        "add.s      %[val16],       %[val16],       %[val23]                \n\t"
+        "mul.s      %[val15],       %[fTmp1],       %[fTmp2]                \n\t"
+        "sub.s      %[fTmp4],       %[val31],       %[val24]                \n\t"
+        "mul.s      %[val23],       %[fTmp1],       %[fTmp3]                \n\t"
+        "add.s      %[val24],       %[val31],       %[val24]                \n\t"
+        "mul.s      %[val31],       %[fTmp1],       %[fTmp4]                \n\t"
+
+        : [fTmp1]  "=&f" (fTmp1),  [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3),
+          [fTmp4]  "=&f" (fTmp4),  [fTmp5] "=&f" (fTmp5), [fTmp6] "=&f" (fTmp6),
+          [fTmp7]  "=&f" (fTmp7),  [fTmp8] "=&f" (fTmp8), [fTmp9] "=&f" (fTmp9),
+          [fTmp10] "=&f" (fTmp10), [fTmp11] "=&f" (fTmp11),
+          [val0]  "=f" (val0),  [val7]  "=f" (val7),
+          [val8]  "=f" (val8),  [val15] "=f" (val15),
+          [val16] "=f" (val16), [val23] "=f" (val23),
+          [val24] "=f" (val24), [val31] "=f" (val31)
+        : [tab] "r" (tab)
+    );
+
+    __asm__ volatile (
+        "lwc1       %[fTmp1],       3*4(%[tab])                             \n\t"
+        "lwc1       %[fTmp2],       28*4(%[tab])                            \n\t"
+        "lwc1       %[fTmp3],       12*4(%[tab])                            \n\t"
+        "lwc1       %[fTmp4],       19*4(%[tab])                            \n\t"
+        "li.s       %[fTmp7],       0.64682178335999012954                  \n\t"
+        "add.s      %[fTmp5],       %[fTmp1],       %[fTmp2]                \n\t"
+        "sub.s      %[fTmp8],       %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[fTmp6],       %[fTmp3],       %[fTmp4]                \n\t"
+        "sub.s      %[fTmp9],       %[fTmp3],       %[fTmp4]                \n\t"
+        "li.s       %[fTmp10],      0.53104259108978417447                  \n\t"
+        "li.s       %[fTmp11],      1.48416461631416627724                  \n\t"
+        "mul.s      %[fTmp8],       %[fTmp8],       %[fTmp10]               \n\t"
+        "add.s      %[val3],        %[fTmp5],       %[fTmp6]                \n\t"
+        "sub.s      %[val12],       %[fTmp5],       %[fTmp6]                \n\t"
+        "lwc1       %[fTmp1],       4*4(%[tab])                             \n\t"
+        "lwc1       %[fTmp2],       27*4(%[tab])                            \n\t"
+        "madd.s     %[val19],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "nmsub.s    %[val28],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "mul.s      %[val12],       %[val12],       %[fTmp7]                \n\t"
+        "lwc1       %[fTmp3],       11*4(%[tab])                            \n\t"
+        "lwc1       %[fTmp4],       20*4(%[tab])                            \n\t"
+        "add.s      %[fTmp5],       %[fTmp1],       %[fTmp2]                \n\t"
+        "mul.s      %[val28],       %[val28],       %[fTmp7]                \n\t"
+        "sub.s      %[fTmp8],       %[fTmp1],       %[fTmp2]                \n\t"
+        "li.s       %[fTmp7],       0.78815462345125022473                  \n\t"
+        "add.s      %[fTmp6],       %[fTmp3],       %[fTmp4]                \n\t"
+        "sub.s      %[fTmp9],       %[fTmp3],       %[fTmp4]                \n\t"
+        "li.s       %[fTmp10],      0.55310389603444452782                  \n\t"
+        "li.s       %[fTmp11],      1.16943993343288495515                  \n\t"
+        "mul.s      %[fTmp8],       %[fTmp8],       %[fTmp10]               \n\t"
+        "add.s      %[val4],        %[fTmp5],       %[fTmp6]                \n\t"
+        "sub.s      %[val11],       %[fTmp5],       %[fTmp6]                \n\t"
+        "li.s       %[fTmp1],       2.56291544774150617881                  \n\t"
+        "madd.s     %[val20],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "nmsub.s    %[val27],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "mul.s      %[val11],       %[val11],       %[fTmp7]                \n\t"
+        "sub.s      %[fTmp2],       %[val3],        %[val4]                 \n\t"
+        "add.s      %[val3],        %[val3],        %[val4]                 \n\t"
+        "sub.s      %[fTmp4],       %[val19],       %[val20]                \n\t"
+        "mul.s      %[val27],       %[val27],       %[fTmp7]                \n\t"
+        "sub.s      %[fTmp3],       %[val12],       %[val11]                \n\t"
+        "mul.s      %[val4],        %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[val11],       %[val12],       %[val11]                \n\t"
+        "add.s      %[val19],       %[val19],       %[val20]                \n\t"
+        "mul.s      %[val20],       %[fTmp1],       %[fTmp4]                \n\t"
+        "mul.s      %[val12],       %[fTmp1],       %[fTmp3]                \n\t"
+        "sub.s      %[fTmp2],       %[val28],       %[val27]                \n\t"
+        "add.s      %[val27],       %[val28],       %[val27]                \n\t"
+        "mul.s      %[val28],       %[fTmp1],       %[fTmp2]                \n\t"
+
+        : [fTmp1]  "=&f" (fTmp1),  [fTmp2]  "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3),
+          [fTmp4]  "=&f" (fTmp4),  [fTmp5]  "=&f" (fTmp5), [fTmp6] "=&f" (fTmp6),
+          [fTmp7]  "=&f" (fTmp7),  [fTmp8]  "=&f" (fTmp8), [fTmp9] "=&f" (fTmp9),
+          [fTmp10] "=&f" (fTmp10), [fTmp11] "=&f" (fTmp11),
+          [val3]  "=f" (val3),  [val4]  "=f" (val4),
+          [val11] "=f" (val11), [val12] "=f" (val12),
+          [val19] "=f" (val19), [val20] "=f" (val20),
+          [val27] "=f" (val27), [val28] "=f" (val28)
+        : [tab] "r" (tab)
+    );
+
+    __asm__ volatile (
+        "li.s       %[fTmp1],       0.54119610014619698439                  \n\t"
+        "sub.s      %[fTmp2],       %[val0],        %[val3]                 \n\t"
+        "add.s      %[val0],        %[val0],        %[val3]                 \n\t"
+        "sub.s      %[fTmp3],       %[val7],        %[val4]                 \n\t"
+        "add.s      %[val4],        %[val7],        %[val4]                 \n\t"
+        "sub.s      %[fTmp4],       %[val8],        %[val11]                \n\t"
+        "mul.s      %[val3],        %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[val8],        %[val8],        %[val11]                \n\t"
+        "mul.s      %[val7],        %[fTmp1],       %[fTmp3]                \n\t"
+        "sub.s      %[fTmp2],       %[val15],       %[val12]                \n\t"
+        "mul.s      %[val11],       %[fTmp1],       %[fTmp4]                \n\t"
+        "add.s      %[val12],       %[val15],       %[val12]                \n\t"
+        "mul.s      %[val15],       %[fTmp1],       %[fTmp2]                \n\t"
+
+        : [val0]  "+f" (val0),   [val3] "+f" (val3),
+          [val4]  "+f" (val4),   [val7] "+f" (val7),
+          [val8]  "+f" (val8),   [val11] "+f" (val11),
+          [val12] "+f" (val12),  [val15] "+f" (val15),
+          [fTmp1] "=f"  (fTmp1), [fTmp2] "=&f" (fTmp2),
+          [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4)
+        :
+    );
+
+    __asm__ volatile (
+        "sub.s      %[fTmp2],       %[val16],       %[val19]                \n\t"
+        "add.s      %[val16],       %[val16],       %[val19]                \n\t"
+        "sub.s      %[fTmp3],       %[val23],       %[val20]                \n\t"
+        "add.s      %[val20],       %[val23],       %[val20]                \n\t"
+        "sub.s      %[fTmp4],       %[val24],       %[val27]                \n\t"
+        "mul.s      %[val19],       %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[val24],       %[val24],       %[val27]                \n\t"
+        "mul.s      %[val23],       %[fTmp1],       %[fTmp3]                \n\t"
+        "sub.s      %[fTmp2],       %[val31],       %[val28]                \n\t"
+        "mul.s      %[val27],       %[fTmp1],       %[fTmp4]                \n\t"
+        "add.s      %[val28],       %[val31],       %[val28]                \n\t"
+        "mul.s      %[val31],       %[fTmp1],       %[fTmp2]                \n\t"
+
+        : [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4),
+          [val16] "+f" (val16), [val19] "+f" (val19), [val20] "+f" (val20),
+          [val23] "+f" (val23), [val24] "+f" (val24), [val27] "+f" (val27),
+          [val28] "+f" (val28), [val31] "+f" (val31)
+        : [fTmp1] "f" (fTmp1)
+    );
+
+    __asm__ volatile (
+        "lwc1       %[fTmp1],       1*4(%[tab])                             \n\t"
+        "lwc1       %[fTmp2],       30*4(%[tab])                            \n\t"
+        "lwc1       %[fTmp3],       14*4(%[tab])                            \n\t"
+        "lwc1       %[fTmp4],       17*4(%[tab])                            \n\t"
+        "li.s       %[fTmp7],       0.52249861493968888062                  \n\t"
+        "add.s      %[fTmp5],       %[fTmp1],       %[fTmp2]                \n\t"
+        "sub.s      %[fTmp8],       %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[fTmp6],       %[fTmp3],       %[fTmp4]                \n\t"
+        "sub.s      %[fTmp9],       %[fTmp3],       %[fTmp4]                \n\t"
+        "li.s       %[fTmp10],      0.50547095989754365998                  \n\t"
+        "li.s       %[fTmp11],      3.40760841846871878570                  \n\t"
+        "mul.s      %[fTmp8],       %[fTmp8],       %[fTmp10]               \n\t"
+        "add.s      %[val1],        %[fTmp5],       %[fTmp6]                \n\t"
+        "sub.s      %[val14],       %[fTmp5],       %[fTmp6]                \n\t"
+        "lwc1       %[fTmp1],       6*4(%[tab])                             \n\t"
+        "lwc1       %[fTmp2],       25*4(%[tab])                            \n\t"
+        "madd.s     %[val17],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "nmsub.s    %[val30],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "mul.s      %[val14],       %[val14],       %[fTmp7]                \n\t"
+        "lwc1       %[fTmp3],       9*4(%[tab])                             \n\t"
+        "lwc1       %[fTmp4],       22*4(%[tab])                            \n\t"
+        "add.s      %[fTmp5],       %[fTmp1],       %[fTmp2]                \n\t"
+        "mul.s      %[val30],       %[val30],       %[fTmp7]                \n\t"
+        "sub.s      %[fTmp8],       %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[fTmp6],       %[fTmp3],       %[fTmp4]                \n\t"
+        "sub.s      %[fTmp9],       %[fTmp3],       %[fTmp4]                \n\t"
+        "li.s       %[fTmp7],       1.72244709823833392782                  \n\t"
+        "li.s       %[fTmp10],      0.62250412303566481615                  \n\t"
+        "li.s       %[fTmp11],      0.83934964541552703873                  \n\t"
+        "add.s      %[val6],        %[fTmp5],       %[fTmp6]                \n\t"
+        "sub.s      %[val9],        %[fTmp5],       %[fTmp6]                \n\t"
+        "mul.s      %[fTmp8],       %[fTmp8],       %[fTmp10]               \n\t"
+        "li.s       %[fTmp1],       0.60134488693504528054                  \n\t"
+        "sub.s      %[fTmp2],       %[val1],        %[val6]                 \n\t"
+        "add.s      %[val1],        %[val1],        %[val6]                 \n\t"
+        "mul.s      %[val9],        %[val9],        %[fTmp7]                \n\t"
+        "madd.s     %[val22],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "nmsub.s    %[val25],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "mul.s      %[val6],        %[fTmp1],       %[fTmp2]                \n\t"
+        "sub.s      %[fTmp2],       %[val14],       %[val9]                 \n\t"
+        "add.s      %[val9],        %[val14],       %[val9]                 \n\t"
+        "mul.s      %[val25],       %[val25],       %[fTmp7]                \n\t"
+        "sub.s      %[fTmp3],       %[val17],       %[val22]                \n\t"
+        "add.s      %[val17],       %[val17],       %[val22]                \n\t"
+        "mul.s      %[val14],       %[fTmp1],       %[fTmp2]                \n\t"
+        "sub.s      %[fTmp2],       %[val30],       %[val25]                \n\t"
+        "mul.s      %[val22],       %[fTmp1],       %[fTmp3]                \n\t"
+        "add.s      %[val25],       %[val30],       %[val25]                \n\t"
+        "mul.s      %[val30],       %[fTmp1],       %[fTmp2]                \n\t"
+
+        : [fTmp1]  "=&f" (fTmp1),  [fTmp2]  "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3),
+          [fTmp4]  "=&f" (fTmp4),  [fTmp5]  "=&f" (fTmp5), [fTmp6] "=&f" (fTmp6),
+          [fTmp7]  "=&f" (fTmp7),  [fTmp8]  "=&f" (fTmp8), [fTmp9] "=&f" (fTmp9),
+          [fTmp10] "=&f" (fTmp10), [fTmp11] "=&f" (fTmp11),
+          [val1]  "=f" (val1),  [val6]  "=f" (val6),
+          [val9]  "=f" (val9),  [val14] "=f" (val14),
+          [val17] "=f" (val17), [val22] "=f" (val22),
+          [val25] "=f" (val25), [val30] "=f" (val30)
+        : [tab] "r" (tab)
+    );
+
+    __asm__ volatile (
+        "lwc1       %[fTmp1],       2*4(%[tab])                             \n\t"
+        "lwc1       %[fTmp2],       29*4(%[tab])                            \n\t"
+        "lwc1       %[fTmp3],       13*4(%[tab])                            \n\t"
+        "lwc1       %[fTmp4],       18*4(%[tab])                            \n\t"
+        "li.s       %[fTmp7],       0.56694403481635770368                  \n\t"
+        "add.s      %[fTmp5],       %[fTmp1],       %[fTmp2]                \n\t"
+        "sub.s      %[fTmp8],       %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[fTmp6],       %[fTmp3],       %[fTmp4]                \n\t"
+        "sub.s      %[fTmp9],       %[fTmp3],       %[fTmp4]                \n\t"
+        "li.s       %[fTmp10],      0.51544730992262454697                  \n\t"
+        "li.s       %[fTmp11],      2.05778100995341155085                  \n\t"
+        "mul.s      %[fTmp8],       %[fTmp8],       %[fTmp10]               \n\t"
+        "add.s      %[val2],        %[fTmp5],       %[fTmp6]                \n\t"
+        "sub.s      %[val13],       %[fTmp5],       %[fTmp6]                \n\t"
+        "lwc1       %[fTmp1],       5*4(%[tab])                             \n\t"
+        "lwc1       %[fTmp2],       26*4(%[tab])                            \n\t"
+        "madd.s     %[val18],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "nmsub.s    %[val29],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "mul.s      %[val13],       %[val13],       %[fTmp7]                \n\t"
+        "lwc1       %[fTmp3],       10*4(%[tab])                            \n\t"
+        "lwc1       %[fTmp4],       21*4(%[tab])                            \n\t"
+        "mul.s      %[val29],       %[val29],       %[fTmp7]                \n\t"
+        "add.s      %[fTmp5],       %[fTmp1],       %[fTmp2]                \n\t"
+        "sub.s      %[fTmp8],       %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[fTmp6],       %[fTmp3],       %[fTmp4]                \n\t"
+        "sub.s      %[fTmp9],       %[fTmp3],       %[fTmp4]                \n\t"
+        "li.s       %[fTmp7],       1.06067768599034747134                  \n\t"
+        "li.s       %[fTmp10],      0.58293496820613387367                  \n\t"
+        "li.s       %[fTmp11],      0.97256823786196069369                  \n\t"
+        "add.s      %[val5],        %[fTmp5],       %[fTmp6]                \n\t"
+        "sub.s      %[val10],       %[fTmp5],       %[fTmp6]                \n\t"
+        "mul.s      %[fTmp8],       %[fTmp8],       %[fTmp10]               \n\t"
+        "li.s       %[fTmp1],       0.89997622313641570463                  \n\t"
+        "sub.s      %[fTmp2],       %[val2],        %[val5]                 \n\t"
+        "mul.s      %[val10],       %[val10],       %[fTmp7]                \n\t"
+        "madd.s     %[val21],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "nmsub.s    %[val26],       %[fTmp8],       %[fTmp9],   %[fTmp11]   \n\t"
+        "add.s      %[val2],        %[val2],        %[val5]                 \n\t"
+        "mul.s      %[val5],        %[fTmp1],       %[fTmp2]                \n\t"
+        "sub.s      %[fTmp3],       %[val13],       %[val10]                \n\t"
+        "add.s      %[val10],       %[val13],       %[val10]                \n\t"
+        "mul.s      %[val26],       %[val26],       %[fTmp7]                \n\t"
+        "sub.s      %[fTmp4],       %[val18],       %[val21]                \n\t"
+        "add.s      %[val18],       %[val18],       %[val21]                \n\t"
+        "mul.s      %[val13],       %[fTmp1],       %[fTmp3]                \n\t"
+        "sub.s      %[fTmp2],       %[val29],       %[val26]                \n\t"
+        "add.s      %[val26],       %[val29],       %[val26]                \n\t"
+        "mul.s      %[val21],       %[fTmp1],       %[fTmp4]                \n\t"
+        "mul.s      %[val29],       %[fTmp1],       %[fTmp2]                \n\t"
+
+        : [fTmp1]  "=&f" (fTmp1),  [fTmp2]  "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3),
+          [fTmp4]  "=&f" (fTmp4),  [fTmp5]  "=&f" (fTmp5), [fTmp6] "=&f" (fTmp6),
+          [fTmp7]  "=&f" (fTmp7),  [fTmp8]  "=&f" (fTmp8), [fTmp9] "=&f" (fTmp9),
+          [fTmp10] "=&f" (fTmp10), [fTmp11] "=&f" (fTmp11),
+          [val2]  "=f" (val2),  [val5]  "=f" (val5),
+          [val10] "=f" (val10), [val13] "=f" (val13),
+          [val18] "=f" (val18), [val21] "=f" (val21),
+          [val26] "=f" (val26), [val29] "=f" (val29)
+        : [tab] "r" (tab)
+    );
+
+    __asm__ volatile (
+        "li.s       %[fTmp1],       1.30656296487637652785                  \n\t"
+        "sub.s      %[fTmp2],       %[val1],        %[val2]                 \n\t"
+        "add.s      %[val1],        %[val1],        %[val2]                 \n\t"
+        "sub.s      %[fTmp3],       %[val6],        %[val5]                 \n\t"
+        "add.s      %[val5],        %[val6],        %[val5]                 \n\t"
+        "sub.s      %[fTmp4],       %[val9],        %[val10]                \n\t"
+        "mul.s      %[val2],        %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[val9],        %[val9],        %[val10]                \n\t"
+        "mul.s      %[val6],        %[fTmp1],       %[fTmp3]                \n\t"
+        "sub.s      %[fTmp2],       %[val14],       %[val13]                \n\t"
+        "mul.s      %[val10],       %[fTmp1],       %[fTmp4]                \n\t"
+        "add.s      %[val13],       %[val14],       %[val13]                \n\t"
+        "mul.s      %[val14],       %[fTmp1],       %[fTmp2]                \n\t"
+
+        : [fTmp1] "=f"  (fTmp1), [fTmp2] "=&f" (fTmp2),
+          [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4),
+          [val1]  "+f" (val1),  [val2]  "+f" (val2),
+          [val5]  "+f" (val5),  [val6]  "+f" (val6),
+          [val9]  "+f" (val9),  [val10] "+f" (val10),
+          [val13] "+f" (val13), [val14] "+f" (val14)
+        :
+    );
+
+    __asm__ volatile (
+        "sub.s      %[fTmp2],       %[val17],       %[val18]                \n\t"
+        "add.s      %[val17],       %[val17],       %[val18]                \n\t"
+        "sub.s      %[fTmp3],       %[val22],       %[val21]                \n\t"
+        "add.s      %[val21],       %[val22],       %[val21]                \n\t"
+        "sub.s      %[fTmp4],       %[val25],       %[val26]                \n\t"
+        "mul.s      %[val18],       %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[val25],       %[val25],       %[val26]                \n\t"
+        "mul.s      %[val22],       %[fTmp1],       %[fTmp3]                \n\t"
+        "sub.s      %[fTmp2],       %[val30],       %[val29]                \n\t"
+        "mul.s      %[val26],       %[fTmp1],       %[fTmp4]                \n\t"
+        "add.s      %[val29],       %[val30],       %[val29]                \n\t"
+        "mul.s      %[val30],       %[fTmp1],       %[fTmp2]                \n\t"
+
+        : [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4),
+          [val17] "+f" (val17), [val18] "+f" (val18), [val21] "+f" (val21),
+          [val22] "+f" (val22), [val25] "+f" (val25), [val26] "+f" (val26),
+          [val29] "+f" (val29), [val30] "+f" (val30)
+        : [fTmp1] "f" (fTmp1)
+    );
+
+    __asm__ volatile (
+        "li.s       %[fTmp1],       0.70710678118654752439                  \n\t"
+        "sub.s      %[fTmp2],       %[val0],        %[val1]                 \n\t"
+        "add.s      %[val0],        %[val0],        %[val1]                 \n\t"
+        "sub.s      %[fTmp3],       %[val3],        %[val2]                 \n\t"
+        "add.s      %[val2],        %[val3],        %[val2]                 \n\t"
+        "sub.s      %[fTmp4],       %[val4],        %[val5]                 \n\t"
+        "mul.s      %[val1],        %[fTmp1],       %[fTmp2]                \n\t"
+        "swc1       %[val0],        0(%[out])                               \n\t"
+        "mul.s      %[val3],        %[fTmp3],       %[fTmp1]                \n\t"
+        "add.s      %[val4],        %[val4],        %[val5]                 \n\t"
+        "mul.s      %[val5],        %[fTmp1],       %[fTmp4]                \n\t"
+        "swc1       %[val1],        16*4(%[out])                            \n\t"
+        "sub.s      %[fTmp2],       %[val7],        %[val6]                 \n\t"
+        "add.s      %[val2],        %[val2],        %[val3]                 \n\t"
+        "swc1       %[val3],        24*4(%[out])                            \n\t"
+        "add.s      %[val6],        %[val7],        %[val6]                 \n\t"
+        "mul.s      %[val7],        %[fTmp1],       %[fTmp2]                \n\t"
+        "swc1       %[val2],        8*4(%[out])                             \n\t"
+        "add.s      %[val6],        %[val6],        %[val7]                 \n\t"
+        "swc1       %[val7],        28*4(%[out])                            \n\t"
+        "add.s      %[val4],        %[val4],        %[val6]                 \n\t"
+        "add.s      %[val6],        %[val6],        %[val5]                 \n\t"
+        "add.s      %[val5],        %[val5],        %[val7]                 \n\t"
+        "swc1       %[val4],        4*4(%[out])                             \n\t"
+        "swc1       %[val5],        20*4(%[out])                            \n\t"
+        "swc1       %[val6],        12*4(%[out])                            \n\t"
+
+        : [fTmp1] "=f"  (fTmp1), [fTmp2] "=&f" (fTmp2),
+          [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4),
+          [val0] "+f" (val0), [val1] "+f" (val1),
+          [val2] "+f" (val2), [val3] "+f" (val3),
+          [val4] "+f" (val4), [val5] "+f" (val5),
+          [val6] "+f" (val6), [val7] "+f" (val7)
+        : [out] "r" (out)
+    );
+
+    __asm__ volatile (
+        "sub.s      %[fTmp2],       %[val8],        %[val9]                 \n\t"
+        "add.s      %[val8],        %[val8],        %[val9]                 \n\t"
+        "sub.s      %[fTmp3],       %[val11],       %[val10]                \n\t"
+        "add.s      %[val10],       %[val11],       %[val10]                \n\t"
+        "sub.s      %[fTmp4],       %[val12],       %[val13]                \n\t"
+        "mul.s      %[val9],        %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[val12],       %[val12],       %[val13]                \n\t"
+        "mul.s      %[val11],       %[fTmp1],       %[fTmp3]                \n\t"
+        "sub.s      %[fTmp2],       %[val15],       %[val14]                \n\t"
+        "mul.s      %[val13],       %[fTmp1],       %[fTmp4]                \n\t"
+        "add.s      %[val14],       %[val15],       %[val14]                \n\t"
+        "add.s      %[val10],       %[val10],       %[val11]                \n\t"
+        "mul.s      %[val15],       %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[val14],       %[val14],       %[val15]                \n\t"
+        "add.s      %[val12],       %[val12],       %[val14]                \n\t"
+        "add.s      %[val14],       %[val14],       %[val13]                \n\t"
+        "add.s      %[val13],       %[val13],       %[val15]                \n\t"
+        "add.s      %[val8],        %[val8],        %[val12]                \n\t"
+        "add.s      %[val12],       %[val12],       %[val10]                \n\t"
+        "add.s      %[val10],       %[val10],       %[val14]                \n\t"
+        "add.s      %[val14],       %[val14],       %[val9]                 \n\t"
+        "add.s      %[val9],        %[val9],        %[val13]                \n\t"
+        "add.s      %[val13],       %[val13],       %[val11]                \n\t"
+        "add.s      %[val11],       %[val11],       %[val15]                \n\t"
+        "swc1       %[val8],         2*4(%[out])                            \n\t"
+        "swc1       %[val9],        18*4(%[out])                            \n\t"
+        "swc1       %[val10],       10*4(%[out])                            \n\t"
+        "swc1       %[val11],       26*4(%[out])                            \n\t"
+        "swc1       %[val12],        6*4(%[out])                            \n\t"
+        "swc1       %[val13],       22*4(%[out])                            \n\t"
+        "swc1       %[val14],       14*4(%[out])                            \n\t"
+        "swc1       %[val15],       30*4(%[out])                            \n\t"
+
+        : [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4),
+          [val8]  "+f" (val8),  [val9]  "+f" (val9),  [val10] "+f" (val10),
+          [val11] "+f" (val11), [val12] "+f" (val12), [val13] "+f" (val13),
+          [val14] "+f" (val14), [val15] "+f" (val15)
+        : [fTmp1] "f" (fTmp1), [out] "r" (out)
+    );
+
+    __asm__ volatile (
+        "sub.s      %[fTmp2],       %[val16],       %[val17]                \n\t"
+        "add.s      %[val16],       %[val16],       %[val17]                \n\t"
+        "sub.s      %[fTmp3],       %[val19],       %[val18]                \n\t"
+        "add.s      %[val18],       %[val19],       %[val18]                \n\t"
+        "sub.s      %[fTmp4],       %[val20],       %[val21]                \n\t"
+        "mul.s      %[val17],       %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[val20],       %[val20],       %[val21]                \n\t"
+        "mul.s      %[val19],       %[fTmp1],       %[fTmp3]                \n\t"
+        "sub.s      %[fTmp2],       %[val23],       %[val22]                \n\t"
+        "mul.s      %[val21],       %[fTmp1],       %[fTmp4]                \n\t"
+        "add.s      %[val22],       %[val23],       %[val22]                \n\t"
+        "add.s      %[val18],       %[val18],       %[val19]                \n\t"
+        "mul.s      %[val23],       %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[val22],       %[val22],       %[val23]                \n\t"
+        "add.s      %[val20],       %[val20],       %[val22]                \n\t"
+        "add.s      %[val22],       %[val22],       %[val21]                \n\t"
+        "add.s      %[val21],       %[val21],       %[val23]                \n\t"
+
+        : [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4),
+          [val16] "+f" (val16), [val17] "+f" (val17), [val18] "+f" (val18),
+          [val19] "+f" (val19), [val20] "+f" (val20), [val21] "+f" (val21),
+          [val22] "+f" (val22), [val23] "+f" (val23)
+        : [fTmp1] "f" (fTmp1)
+    );
+
+    __asm__ volatile (
+        "sub.s      %[fTmp2],       %[val24],       %[val25]                \n\t"
+        "add.s      %[val24],       %[val24],       %[val25]                \n\t"
+        "sub.s      %[fTmp3],       %[val27],       %[val26]                \n\t"
+        "add.s      %[val26],       %[val27],       %[val26]                \n\t"
+        "sub.s      %[fTmp4],       %[val28],       %[val29]                \n\t"
+        "mul.s      %[val25],       %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[val28],       %[val28],       %[val29]                \n\t"
+        "mul.s      %[val27],       %[fTmp1],       %[fTmp3]                \n\t"
+        "sub.s      %[fTmp2],       %[val31],       %[val30]                \n\t"
+        "mul.s      %[val29],       %[fTmp1],       %[fTmp4]                \n\t"
+        "add.s      %[val30],       %[val31],       %[val30]                \n\t"
+        "add.s      %[val26],       %[val26],       %[val27]                \n\t"
+        "mul.s      %[val31],       %[fTmp1],       %[fTmp2]                \n\t"
+        "add.s      %[val30],       %[val30],       %[val31]                \n\t"
+        "add.s      %[val28],       %[val28],       %[val30]                \n\t"
+        "add.s      %[val30],       %[val30],       %[val29]                \n\t"
+        "add.s      %[val29],       %[val29],       %[val31]                \n\t"
+        "add.s      %[val24],       %[val24],       %[val28]                \n\t"
+        "add.s      %[val28],       %[val28],       %[val26]                \n\t"
+        "add.s      %[val26],       %[val26],       %[val30]                \n\t"
+        "add.s      %[val30],       %[val30],       %[val25]                \n\t"
+        "add.s      %[val25],       %[val25],       %[val29]                \n\t"
+        "add.s      %[val29],       %[val29],       %[val27]                \n\t"
+        "add.s      %[val27],       %[val27],       %[val31]                \n\t"
+
+        : [fTmp2] "=&f" (fTmp2), [fTmp3] "=&f" (fTmp3), [fTmp4] "=&f" (fTmp4),
+          [val24] "+f" (val24), [val25] "+f" (val25), [val26] "+f" (val26),
+          [val27] "+f" (val27), [val28] "+f" (val28), [val29] "+f" (val29),
+          [val30] "+f" (val30), [val31] "+f" (val31)
+        : [fTmp1] "f" (fTmp1)
+    );
+
+    out[ 1] = val16 + val24;
+    out[17] = val17 + val25;
+    out[ 9] = val18 + val26;
+    out[25] = val19 + val27;
+    out[ 5] = val20 + val28;
+    out[21] = val21 + val29;
+    out[13] = val22 + val30;
+    out[29] = val23 + val31;
+    out[ 3] = val24 + val20;
+    out[19] = val25 + val21;
+    out[11] = val26 + val22;
+    out[27] = val27 + val23;
+    out[ 7] = val28 + val18;
+    out[23] = val29 + val19;
+    out[15] = val30 + val17;
+    out[31] = val31;
+}
+
+static void imdct36_mips_float(float *out, float *buf, float *in, float *win)
+{
+    float t0, t1, t2, t3, s0, s1, s2, s3;
+    float tmp[18];
+    /* temporary variables */
+    float in1, in2, in3, in4, in5, in6;
+    float out1, out2, out3, out4, out5;
+    float c1, c2, c3, c4, c5, c6, c7, c8, c9;
+
+    /**
+    * all loops are unrolled totally, and instructions are scheduled to
+    * minimize pipeline stall. instructions of the first two loops are
+    * reorganized, in order to eliminate unnecessary readings and
+    * writings into array. values defined in macros and tables are
+    * eliminated - they are directly loaded in appropriate variables
+    */
+
+    /* loop 1 and 2 */
+    __asm__ volatile (
+        "lwc1   %[in1],  17*4(%[in])                                    \t\n"
+        "lwc1   %[in2],  16*4(%[in])                                    \t\n"
+        "lwc1   %[in3],  15*4(%[in])                                    \t\n"
+        "lwc1   %[in4],  14*4(%[in])                                    \t\n"
+        "lwc1   %[in5],  13*4(%[in])                                    \t\n"
+        "lwc1   %[in6],  12*4(%[in])                                    \t\n"
+        "add.s  %[out1], %[in1],  %[in2]                                \t\n"
+        "add.s  %[out2], %[in2],  %[in3]                                \t\n"
+        "add.s  %[out3], %[in3],  %[in4]                                \t\n"
+        "add.s  %[out4], %[in4],  %[in5]                                \t\n"
+        "add.s  %[out5], %[in5],  %[in6]                                \t\n"
+        "lwc1   %[in1],  11*4(%[in])                                    \t\n"
+        "swc1   %[out2], 16*4(%[in])                                    \t\n"
+        "add.s  %[out1], %[out1], %[out3]                               \t\n"
+        "swc1   %[out4], 14*4(%[in])                                    \t\n"
+        "add.s  %[out3], %[out3], %[out5]                               \t\n"
+        "lwc1   %[in2],  10*4(%[in])                                    \t\n"
+        "lwc1   %[in3],  9*4(%[in])                                     \t\n"
+        "swc1   %[out1], 17*4(%[in])                                    \t\n"
+        "lwc1   %[in4],  8*4(%[in])                                     \t\n"
+        "swc1   %[out3], 15*4(%[in])                                    \t\n"
+        "add.s  %[out1], %[in6],  %[in1]                                \t\n"
+        "add.s  %[out2], %[in1],  %[in2]                                \t\n"
+        "add.s  %[out3], %[in2],  %[in3]                                \t\n"
+        "add.s  %[out4], %[in3],  %[in4]                                \t\n"
+        "lwc1   %[in5],  7*4(%[in])                                     \t\n"
+        "swc1   %[out1], 12*4(%[in])                                    \t\n"
+        "add.s  %[out5], %[out5], %[out2]                               \t\n"
+        "swc1   %[out3], 10*4(%[in])                                    \t\n"
+        "add.s  %[out2], %[out2], %[out4]                               \t\n"
+        "lwc1   %[in6],  6*4(%[in])                                     \t\n"
+        "lwc1   %[in1],  5*4(%[in])                                     \t\n"
+        "swc1   %[out5], 13*4(%[in])                                    \t\n"
+        "lwc1   %[in2],  4*4(%[in])                                     \t\n"
+        "swc1   %[out2], 11*4(%[in])                                    \t\n"
+        "add.s  %[out5], %[in4],  %[in5]                                \t\n"
+        "add.s  %[out1], %[in5],  %[in6]                                \t\n"
+        "add.s  %[out2], %[in6],  %[in1]                                \t\n"
+        "add.s  %[out3], %[in1],  %[in2]                                \t\n"
+        "lwc1   %[in3],  3*4(%[in])                                     \t\n"
+        "swc1   %[out5], 8*4(%[in])                                     \t\n"
+        "add.s  %[out4], %[out4], %[out1]                               \t\n"
+        "swc1   %[out2], 6*4(%[in])                                     \t\n"
+        "add.s  %[out1], %[out1], %[out3]                               \t\n"
+        "lwc1   %[in4],  2*4(%[in])                                     \t\n"
+        "lwc1   %[in5],  1*4(%[in])                                     \t\n"
+        "swc1   %[out4], 9*4(%[in])                                     \t\n"
+        "lwc1   %[in6],  0(%[in])                                       \t\n"
+        "swc1   %[out1], 7*4(%[in])                                     \t\n"
+        "add.s  %[out4], %[in2],  %[in3]                                \t\n"
+        "add.s  %[out5], %[in3],  %[in4]                                \t\n"
+        "add.s  %[out1], %[in4],  %[in5]                                \t\n"
+        "add.s  %[out2], %[in5],  %[in6]                                \t\n"
+        "swc1   %[out4], 4*4(%[in])                                     \t\n"
+        "add.s  %[out3], %[out3], %[out5]                               \t\n"
+        "swc1   %[out1], 2*4(%[in])                                     \t\n"
+        "add.s  %[out5], %[out5], %[out2]                               \t\n"
+        "swc1   %[out2], 1*4(%[in])                                     \t\n"
+        "swc1   %[out3], 5*4(%[in])                                     \t\n"
+        "swc1   %[out5], 3*4(%[in])                                     \t\n"
+
+        : [in1] "=&f" (in1), [in2] "=&f" (in2),
+          [in3] "=&f" (in3), [in4] "=&f" (in4),
+          [in5] "=&f" (in5), [in6] "=&f" (in6),
+          [out1] "=&f" (out1), [out2] "=&f" (out2),
+          [out3] "=&f" (out3), [out4] "=&f" (out4),
+          [out5] "=&f" (out5)
+        : [in] "r" (in)
+    );
+
+    /* loop 3 */
+    __asm__ volatile (
+        "li.s    %[c1],   0.5                                           \t\n"
+        "lwc1    %[in1],  8*4(%[in])                                    \t\n"
+        "lwc1    %[in2],  16*4(%[in])                                   \t\n"
+        "lwc1    %[in3],  4*4(%[in])                                    \t\n"
+        "lwc1    %[in4],  0(%[in])                                      \t\n"
+        "lwc1    %[in5],  12*4(%[in])                                   \t\n"
+        "li.s    %[c2],   0.93969262078590838405                        \t\n"
+        "add.s   %[t2],   %[in1],  %[in2]                               \t\n"
+        "add.s   %[t0],   %[in1],  %[in3]                               \t\n"
+        "li.s    %[c3],   -0.76604444311897803520                       \t\n"
+        "madd.s  %[t3],   %[in4],  %[in5], %[c1]                        \t\n"
+        "sub.s   %[t1],   %[in4],  %[in5]                               \t\n"
+        "sub.s   %[t2],   %[t2],   %[in3]                               \t\n"
+        "mul.s   %[t0],   %[t0],   %[c2]                                \t\n"
+        "li.s    %[c4],   -0.17364817766693034885                       \t\n"
+        "li.s    %[c5],   -0.86602540378443864676                       \t\n"
+        "li.s    %[c6],   0.98480775301220805936                        \t\n"
+        "nmsub.s %[out1], %[t1],   %[t2],  %[c1]                        \t\n"
+        "add.s   %[out2], %[t1],   %[t2]                                \t\n"
+        "add.s   %[t2],   %[in2],  %[in3]                               \t\n"
+        "sub.s   %[t1],   %[in1],  %[in2]                               \t\n"
+        "sub.s   %[out3], %[t3],   %[t0]                                \t\n"
+        "swc1    %[out1], 6*4(%[tmp])                                   \t\n"
+        "swc1    %[out2], 16*4(%[tmp])                                  \t\n"
+        "mul.s   %[t2],   %[t2],   %[c3]                                \t\n"
+        "mul.s   %[t1],   %[t1],   %[c4]                                \t\n"
+        "add.s   %[out1], %[t3],   %[t0]                                \t\n"
+        "lwc1    %[in1],  10*4(%[in])                                   \t\n"
+        "lwc1    %[in2],  14*4(%[in])                                   \t\n"
+        "sub.s   %[out3], %[out3], %[t2]                                \t\n"
+        "add.s   %[out2], %[t3],   %[t2]                                \t\n"
+        "add.s   %[out1], %[out1], %[t1]                                \t\n"
+        "lwc1    %[in3],  2*4(%[in])                                    \t\n"
+        "lwc1    %[in4],  6*4(%[in])                                    \t\n"
+        "swc1    %[out3], 10*4(%[tmp])                                  \t\n"
+        "sub.s   %[out2], %[out2], %[t1]                                \t\n"
+        "swc1    %[out1], 2*4(%[tmp])                                   \t\n"
+        "add.s   %[out1], %[in1],  %[in2]                               \t\n"
+        "add.s   %[t2],   %[in1],  %[in3]                               \t\n"
+        "sub.s   %[t3],   %[in1],  %[in2]                               \t\n"
+        "swc1    %[out2], 14*4(%[tmp])                                  \t\n"
+        "li.s    %[c7],   -0.34202014332566873304                       \t\n"
+        "sub.s   %[out1], %[out1], %[in3]                               \t\n"
+        "mul.s   %[t2],   %[t2],   %[c6]                                \t\n"
+        "mul.s   %[t3],   %[t3],   %[c7]                                \t\n"
+        "li.s    %[c8],   0.86602540378443864676                        \t\n"
+        "mul.s   %[t0],   %[in4],  %[c8]                                \t\n"
+        "mul.s   %[out1], %[out1], %[c5]                                \t\n"
+        "add.s   %[t1],   %[in2],  %[in3]                               \t\n"
+        "li.s    %[c9],   -0.64278760968653932632                       \t\n"
+        "add.s   %[out2], %[t2],   %[t3]                                \t\n"
+        "lwc1    %[in1],  9*4(%[in])                                    \t\n"
+        "swc1    %[out1], 4*4(%[tmp])                                   \t\n"
+        "mul.s   %[t1],   %[t1],   %[c9]                                \t\n"
+        "lwc1    %[in2],  17*4(%[in])                                   \t\n"
+        "add.s   %[out2], %[out2], %[t0]                                \t\n"
+        "lwc1    %[in3],  5*4(%[in])                                    \t\n"
+        "lwc1    %[in4],  1*4(%[in])                                    \t\n"
+        "add.s   %[out3], %[t2],   %[t1]                                \t\n"
+        "sub.s   %[out1], %[t3],   %[t1]                                \t\n"
+        "swc1    %[out2], 0(%[tmp])                                     \t\n"
+        "lwc1    %[in5],  13*4(%[in])                                   \t\n"
+        "add.s   %[t2],   %[in1],  %[in2]                               \t\n"
+        "sub.s   %[out3], %[out3], %[t0]                                \t\n"
+        "sub.s   %[out1], %[out1], %[t0]                                \t\n"
+        "add.s   %[t0],   %[in1],  %[in3]                               \t\n"
+        "madd.s  %[t3],   %[in4],  %[in5], %[c1]                        \t\n"
+        "sub.s   %[t2],   %[t2],   %[in3]                               \t\n"
+        "swc1    %[out3], 12*4(%[tmp])                                  \t\n"
+        "swc1    %[out1], 8*4(%[tmp])                                   \t\n"
+        "sub.s   %[t1],   %[in4],  %[in5]                               \t\n"
+        "mul.s   %[t0],   %[t0],   %[c2]                                \t\n"
+        "nmsub.s %[out1], %[t1],   %[t2],  %[c1]                        \t\n"
+        "add.s   %[out2], %[t1],   %[t2]                                \t\n"
+        "add.s   %[t2],   %[in2],  %[in3]                               \t\n"
+        "sub.s   %[t1],   %[in1],  %[in2]                               \t\n"
+        "sub.s   %[out3], %[t3],   %[t0]                                \t\n"
+        "swc1    %[out1], 7*4(%[tmp])                                   \t\n"
+        "swc1    %[out2], 17*4(%[tmp])                                  \t\n"
+        "mul.s   %[t2],   %[t2],   %[c3]                                \t\n"
+        "mul.s   %[t1],   %[t1],   %[c4]                                \t\n"
+        "add.s   %[out1], %[t3],   %[t0]                                \t\n"
+        "lwc1    %[in1],  11*4(%[in])                                   \t\n"
+        "lwc1    %[in2],  15*4(%[in])                                   \t\n"
+        "sub.s   %[out3], %[out3], %[t2]                                \t\n"
+        "add.s   %[out2], %[t3],   %[t2]                                \t\n"
+        "add.s   %[out1], %[out1], %[t1]                                \t\n"
+        "lwc1    %[in3],  3*4(%[in])                                    \t\n"
+        "lwc1    %[in4],  7*4(%[in])                                    \t\n"
+        "swc1    %[out3], 11*4(%[tmp])                                  \t\n"
+        "sub.s   %[out2], %[out2], %[t1]                                \t\n"
+        "swc1    %[out1], 3*4(%[tmp])                                   \t\n"
+        "add.s   %[out3], %[in1],  %[in2]                               \t\n"
+        "add.s   %[t2],   %[in1],  %[in3]                               \t\n"
+        "sub.s   %[t3],   %[in1],  %[in2]                               \t\n"
+        "swc1    %[out2], 15*4(%[tmp])                                  \t\n"
+        "mul.s   %[t0],   %[in4],  %[c8]                                \t\n"
+        "sub.s   %[out3], %[out3], %[in3]                               \t\n"
+        "mul.s   %[t2],   %[t2],   %[c6]                                \t\n"
+        "mul.s   %[t3],   %[t3],   %[c7]                                \t\n"
+        "add.s   %[t1],   %[in2],  %[in3]                               \t\n"
+        "mul.s   %[out3], %[out3], %[c5]                                \t\n"
+        "add.s   %[out1], %[t2],   %[t3]                                \t\n"
+        "mul.s   %[t1],   %[t1],   %[c9]                                \t\n"
+        "swc1    %[out3], 5*4(%[tmp])                                   \t\n"
+        "add.s   %[out1], %[out1], %[t0]                                \t\n"
+        "add.s   %[out2], %[t2],   %[t1]                                \t\n"
+        "sub.s   %[out3], %[t3],   %[t1]                                \t\n"
+        "swc1    %[out1], 1*4(%[tmp])                                   \t\n"
+        "sub.s   %[out2], %[out2], %[t0]                                \t\n"
+        "sub.s   %[out3], %[out3], %[t0]                                \t\n"
+        "swc1    %[out2], 13*4(%[tmp])                                  \t\n"
+        "swc1    %[out3], 9*4(%[tmp])                                   \t\n"
+
+        : [t0] "=&f" (t0), [t1] "=&f" (t1),
+          [t2] "=&f" (t2), [t3] "=&f" (t3),
+          [in1] "=&f" (in1), [in2] "=&f" (in2),
+          [in3] "=&f" (in3), [in4] "=&f" (in4),
+          [in5] "=&f" (in5),
+          [out1] "=&f" (out1), [out2] "=&f" (out2),
+          [out3] "=&f" (out3),
+          [c1] "=&f" (c1), [c2] "=&f" (c2),
+          [c3] "=&f" (c3), [c4] "=&f" (c4),
+          [c5] "=&f" (c5), [c6] "=&f" (c6),
+          [c7] "=&f" (c7), [c8] "=&f" (c8),
+          [c9] "=&f" (c9)
+        : [in] "r" (in), [tmp] "r" (tmp)
+    );
+
+    /* loop 4 */
+    __asm__ volatile (
+        "lwc1   %[in1],  2*4(%[tmp])                                    \t\n"
+        "lwc1   %[in2],  0(%[tmp])                                      \t\n"
+        "lwc1   %[in3],  3*4(%[tmp])                                    \t\n"
+        "lwc1   %[in4],  1*4(%[tmp])                                    \t\n"
+        "li.s   %[c1],   0.50190991877167369479                         \t\n"
+        "li.s   %[c2],   5.73685662283492756461                         \t\n"
+        "add.s  %[s0],   %[in1], %[in2]                                 \t\n"
+        "sub.s  %[s2],   %[in1], %[in2]                                 \t\n"
+        "add.s  %[s1],   %[in3], %[in4]                                 \t\n"
+        "sub.s  %[s3],   %[in3], %[in4]                                 \t\n"
+        "lwc1   %[in1],  9*4(%[win])                                    \t\n"
+        "lwc1   %[in2],  4*9*4(%[buf])                                  \t\n"
+        "lwc1   %[in3],  8*4(%[win])                                    \t\n"
+        "mul.s  %[s1],   %[s1],  %[c1]                                  \t\n"
+        "mul.s  %[s3],   %[s3],  %[c2]                                  \t\n"
+        "lwc1   %[in4],  4*8*4(%[buf])                                  \t\n"
+        "lwc1   %[in5],  29*4(%[win])                                   \t\n"
+        "lwc1   %[in6],  28*4(%[win])                                   \t\n"
+        "add.s  %[t0],   %[s0],  %[s1]                                  \t\n"
+        "sub.s  %[t1],   %[s0],  %[s1]                                  \t\n"
+        "li.s   %[c1],   0.51763809020504152469                         \t\n"
+        "li.s   %[c2],   1.93185165257813657349                         \t\n"
+        "mul.s  %[out3], %[in5], %[t0]                                  \t\n"
+        "madd.s %[out1], %[in2], %[in1], %[t1]                          \t\n"
+        "madd.s %[out2], %[in4], %[in3], %[t1]                          \t\n"
+        "mul.s  %[out4], %[in6], %[t0]                                  \t\n"
+        "add.s  %[t0],   %[s2],  %[s3]                                  \t\n"
+        "swc1   %[out3], 4*9*4(%[buf])                                  \t\n"
+        "swc1   %[out1], 288*4(%[out])                                  \t\n"
+        "swc1   %[out2], 256*4(%[out])                                  \t\n"
+        "swc1   %[out4], 4*8*4(%[buf])                                  \t\n"
+        "sub.s  %[t1],   %[s2],  %[s3]                                  \t\n"
+        "lwc1   %[in1],  17*4(%[win])                                   \t\n"
+        "lwc1   %[in2],  4*17*4(%[buf])                                 \t\n"
+        "lwc1   %[in3],  0(%[win])                                      \t\n"
+        "lwc1   %[in4],  0(%[buf])                                      \t\n"
+        "lwc1   %[in5],  37*4(%[win])                                   \t\n"
+        "lwc1   %[in6],  20*4(%[win])                                   \t\n"
+        "madd.s %[out1], %[in2], %[in1], %[t1]                          \t\n"
+        "lwc1   %[in1],  6*4(%[tmp])                                    \t\n"
+        "madd.s %[out2], %[in4], %[in3], %[t1]                          \t\n"
+        "mul.s  %[out3], %[t0],  %[in5]                                 \t\n"
+        "mul.s  %[out4], %[t0],  %[in6]                                 \t\n"
+        "swc1   %[out1], 544*4(%[out])                                  \t\n"
+        "lwc1   %[in2],  4*4(%[tmp])                                    \t\n"
+        "swc1   %[out2], 0(%[out])                                      \t\n"
+        "swc1   %[out3], 4*17*4(%[buf])                                 \t\n"
+        "swc1   %[out4], 0(%[buf])                                      \t\n"
+        "lwc1   %[in3],  7*4(%[tmp])                                    \t\n"
+        "add.s  %[s0],   %[in1], %[in2]                                 \t\n"
+        "sub.s  %[s2],   %[in1], %[in2]                                 \t\n"
+        "lwc1   %[in4],  5*4(%[tmp])                                    \t\n"
+        "add.s  %[s1],   %[in3], %[in4]                                 \t\n"
+        "sub.s  %[s3],   %[in3], %[in4]                                 \t\n"
+        "lwc1   %[in1],  10*4(%[win])                                   \t\n"
+        "lwc1   %[in2],  4*10*4(%[buf])                                 \t\n"
+        "lwc1   %[in3],  7*4(%[win])                                    \t\n"
+        "mul.s  %[s1],   %[s1],  %[c1]                                  \t\n"
+        "mul.s  %[s3],   %[s3],  %[c2]                                  \t\n"
+        "add.s  %[t0],   %[s0],  %[s1]                                  \t\n"
+        "sub.s  %[t1],   %[s0],  %[s1]                                  \t\n"
+        "lwc1   %[in4],  4*7*4(%[buf])                                  \t\n"
+        "lwc1   %[in5],  30*4(%[win])                                   \t\n"
+        "lwc1   %[in6],  27*4(%[win])                                   \t\n"
+        "li.s   %[c1],   0.55168895948124587824                         \t\n"
+        "madd.s %[out1], %[in2], %[in1], %[t1]                          \t\n"
+        "madd.s %[out2], %[in4], %[in3], %[t1]                          \t\n"
+        "mul.s  %[out3], %[t0],  %[in5]                                 \t\n"
+        "mul.s  %[out4], %[t0],  %[in6]                                 \t\n"
+        "add.s  %[t0],   %[s2],  %[s3]                                  \t\n"
+        "swc1   %[out1], 320*4(%[out])                                  \t\n"
+        "swc1   %[out2], 224*4(%[out])                                  \t\n"
+        "swc1   %[out3], 4*10*4(%[buf])                                 \t\n"
+        "swc1   %[out4], 4*7*4(%[buf])                                  \t\n"
+        "sub.s  %[t1],   %[s2],  %[s3]                                  \t\n"
+        "lwc1   %[in1],  16*4(%[win])                                   \t\n"
+        "lwc1   %[in2],  4*16*4(%[buf])                                 \t\n"
+        "lwc1   %[in3],  1*4(%[win])                                    \t\n"
+        "lwc1   %[in4],  4*1*4(%[buf])                                  \t\n"
+        "lwc1   %[in5],  36*4(%[win])                                   \t\n"
+        "lwc1   %[in6],  21*4(%[win])                                   \t\n"
+        "madd.s %[out1], %[in2], %[in1], %[t1]                          \t\n"
+        "lwc1   %[in1],  10*4(%[tmp])                                   \t\n"
+        "madd.s %[out2], %[in4], %[in3], %[t1]                          \t\n"
+        "mul.s  %[out3], %[in5], %[t0]                                  \t\n"
+        "mul.s  %[out4], %[in6], %[t0]                                  \t\n"
+        "swc1   %[out1], 512*4(%[out])                                  \t\n"
+        "lwc1   %[in2],  8*4(%[tmp])                                    \t\n"
+        "swc1   %[out2], 32*4(%[out])                                   \t\n"
+        "swc1   %[out3], 4*16*4(%[buf])                                 \t\n"
+        "swc1   %[out4], 4*1*4(%[buf])                                  \t\n"
+        "li.s   %[c2],   1.18310079157624925896                         \t\n"
+        "add.s  %[s0],   %[in1], %[in2]                                 \t\n"
+        "sub.s  %[s2],   %[in1], %[in2]                                 \t\n"
+        "lwc1   %[in3],  11*4(%[tmp])                                   \t\n"
+        "lwc1   %[in4],  9*4(%[tmp])                                    \t\n"
+        "add.s  %[s1],   %[in3], %[in4]                                 \t\n"
+        "sub.s  %[s3],   %[in3], %[in4]                                 \t\n"
+        "lwc1   %[in1],  11*4(%[win])                                   \t\n"
+        "lwc1   %[in2],  4*11*4(%[buf])                                 \t\n"
+        "lwc1   %[in3],  6*4(%[win])                                    \t\n"
+        "mul.s  %[s1],   %[s1],  %[c1]                                  \t\n"
+        "mul.s  %[s3],   %[s3],  %[c2]                                  \t\n"
+        "lwc1   %[in4],  4*6*4(%[buf])                                  \t\n"
+        "lwc1   %[in5],  31*4(%[win])                                   \t\n"
+        "lwc1   %[in6],  26*4(%[win])                                   \t\n"
+        "add.s  %[t0],   %[s0],  %[s1]                                  \t\n"
+        "sub.s  %[t1],   %[s0],  %[s1]                                  \t\n"
+        "mul.s  %[out3], %[t0],  %[in5]                                 \t\n"
+        "mul.s  %[out4], %[t0],  %[in6]                                 \t\n"
+        "add.s  %[t0],   %[s2],  %[s3]                                  \t\n"
+        "madd.s %[out1], %[in2], %[in1], %[t1]                          \t\n"
+        "madd.s %[out2], %[in4], %[in3], %[t1]                          \t\n"
+        "swc1   %[out3], 4*11*4(%[buf])                                 \t\n"
+        "swc1   %[out4], 4*6*4(%[buf])                                  \t\n"
+        "sub.s  %[t1],   %[s2],  %[s3]                                  \t\n"
+        "swc1   %[out1], 352*4(%[out])                                  \t\n"
+        "swc1   %[out2], 192*4(%[out])                                  \t\n"
+        "lwc1   %[in1],  15*4(%[win])                                   \t\n"
+        "lwc1   %[in2],  4*15*4(%[buf])                                 \t\n"
+        "lwc1   %[in3],  2*4(%[win])                                    \t\n"
+        "lwc1   %[in4],  4*2*4(%[buf])                                  \t\n"
+        "lwc1   %[in5],  35*4(%[win])                                   \t\n"
+        "lwc1   %[in6],  22*4(%[win])                                   \t\n"
+        "madd.s %[out1], %[in2], %[in1], %[t1]                          \t\n"
+        "lwc1   %[in1],  14*4(%[tmp])                                   \t\n"
+        "madd.s %[out2], %[in4], %[in3], %[t1]                          \t\n"
+        "mul.s  %[out3], %[t0],  %[in5]                                 \t\n"
+        "mul.s  %[out4], %[t0],  %[in6]                                 \t\n"
+        "swc1   %[out1], 480*4(%[out])                                  \t\n"
+        "lwc1   %[in2],  12*4(%[tmp])                                   \t\n"
+        "swc1   %[out2], 64*4(%[out])                                   \t\n"
+        "swc1   %[out3], 4*15*4(%[buf])                                 \t\n"
+        "swc1   %[out4], 4*2*4(%[buf])                                  \t\n"
+        "lwc1   %[in3],  15*4(%[tmp])                                   \t\n"
+        "add.s  %[s0],   %[in1], %[in2]                                 \t\n"
+        "sub.s  %[s2],   %[in1], %[in2]                                 \t\n"
+        "lwc1   %[in4],  13*4(%[tmp])                                   \t\n"
+        "li.s   %[c1],   0.61038729438072803416                         \t\n"
+        "li.s   %[c2],   0.87172339781054900991                         \t\n"
+        "add.s  %[s1],   %[in3], %[in4]                                 \t\n"
+        "sub.s  %[s3],   %[in3], %[in4]                                 \t\n"
+        "lwc1   %[in1],  12*4(%[win])                                   \t\n"
+        "lwc1   %[in2],  4*12*4(%[buf])                                 \t\n"
+        "lwc1   %[in3],  5*4(%[win])                                    \t\n"
+        "mul.s  %[s1],   %[s1],  %[c1]                                  \t\n"
+        "mul.s  %[s3],   %[s3],  %[c2]                                  \t\n"
+        "lwc1   %[in4],  4*5*4(%[buf])                                  \t\n"
+        "lwc1   %[in5],  32*4(%[win])                                   \t\n"
+        "lwc1   %[in6],  25*4(%[win])                                   \t\n"
+        "add.s  %[t0],   %[s0],  %[s1]                                  \t\n"
+        "sub.s  %[t1],   %[s0],  %[s1]                                  \t\n"
+        "lwc1   %[s0],   16*4(%[tmp])                                   \t\n"
+        "lwc1   %[s1],   17*4(%[tmp])                                   \t\n"
+        "li.s   %[c1],   0.70710678118654752439                         \t\n"
+        "mul.s  %[out3], %[t0],  %[in5]                                 \t\n"
+        "madd.s %[out1], %[in2], %[in1], %[t1]                          \t\n"
+        "madd.s %[out2], %[in4], %[in3], %[t1]                          \t\n"
+        "mul.s  %[out4], %[t0],  %[in6]                                 \t\n"
+        "add.s  %[t0],   %[s2],  %[s3]                                  \t\n"
+        "swc1   %[out3], 4*12*4(%[buf])                                 \t\n"
+        "swc1   %[out1], 384*4(%[out])                                  \t\n"
+        "swc1   %[out2], 160*4(%[out])                                  \t\n"
+        "swc1   %[out4], 4*5*4(%[buf])                                  \t\n"
+        "sub.s  %[t1],   %[s2],  %[s3]                                  \t\n"
+        "lwc1   %[in1],  14*4(%[win])                                   \t\n"
+        "lwc1   %[in2],  4*14*4(%[buf])                                 \t\n"
+        "lwc1   %[in3],  3*4(%[win])                                    \t\n"
+        "lwc1   %[in4],  4*3*4(%[buf])                                  \t\n"
+        "lwc1   %[in5],  34*4(%[win])                                   \t\n"
+        "lwc1   %[in6],  23*4(%[win])                                   \t\n"
+        "madd.s %[out1], %[in2], %[in1], %[t1]                          \t\n"
+        "mul.s  %[s1],   %[s1],  %[c1]                                  \t\n"
+        "madd.s %[out2], %[in4], %[in3], %[t1]                          \t\n"
+        "mul.s  %[out3], %[in5], %[t0]                                  \t\n"
+        "mul.s  %[out4], %[in6], %[t0]                                  \t\n"
+        "swc1   %[out1], 448*4(%[out])                                  \t\n"
+        "add.s  %[t0],   %[s0],  %[s1]                                  \t\n"
+        "swc1   %[out2], 96*4(%[out])                                   \t\n"
+        "swc1   %[out3], 4*14*4(%[buf])                                 \t\n"
+        "swc1   %[out4], 4*3*4(%[buf])                                  \t\n"
+        "sub.s  %[t1],   %[s0],  %[s1]                                  \t\n"
+        "lwc1   %[in1],  13*4(%[win])                                   \t\n"
+        "lwc1   %[in2],  4*13*4(%[buf])                                 \t\n"
+        "lwc1   %[in3],  4*4(%[win])                                    \t\n"
+        "lwc1   %[in4],  4*4*4(%[buf])                                  \t\n"
+        "lwc1   %[in5],  33*4(%[win])                                   \t\n"
+        "lwc1   %[in6],  24*4(%[win])                                   \t\n"
+        "madd.s %[out1], %[in2], %[in1], %[t1]                          \t\n"
+        "madd.s %[out2], %[in4], %[in3], %[t1]                          \t\n"
+        "mul.s  %[out3], %[t0],  %[in5]                                 \t\n"
+        "mul.s  %[out4], %[t0],  %[in6]                                 \t\n"
+        "swc1   %[out1], 416*4(%[out])                                  \t\n"
+        "swc1   %[out2], 128*4(%[out])                                  \t\n"
+        "swc1   %[out3], 4*13*4(%[buf])                                 \t\n"
+        "swc1   %[out4], 4*4*4(%[buf])                                  \t\n"
+
+        : [c1] "=&f" (c1), [c2] "=&f" (c2),
+          [in1] "=&f" (in1), [in2] "=&f" (in2),
+          [in3] "=&f" (in3), [in4] "=&f" (in4),
+          [in5] "=&f" (in5), [in6] "=&f" (in6),
+          [out1] "=&f" (out1), [out2] "=&f" (out2),
+          [out3] "=&f" (out3), [out4] "=&f" (out4),
+          [t0] "=&f" (t0), [t1] "=&f" (t1),
+          [t2] "=&f" (t2), [t3] "=&f" (t3),
+          [s0] "=&f" (s0), [s1] "=&f" (s1),
+          [s2] "=&f" (s2), [s3] "=&f" (s3)
+        : [tmp] "r" (tmp), [win] "r" (win),
+          [buf] "r" (buf), [out] "r" (out)
+    );
+}
+
+static void ff_imdct36_blocks_mips_float(float *out, float *buf, float *in,
+                               int count, int switch_point, int block_type)
+{
+    int j;
+    for (j=0 ; j < count; j++) {
+        /* apply window & overlap with previous buffer */
+
+        /* select window */
+        int win_idx = (switch_point && j < 2) ? 0 : block_type;
+        float *win = ff_mdct_win_float[win_idx + (4 & -(j & 1))];
+
+        imdct36_mips_float(out, buf, in, win);
+
+        in  += 18;
+        buf += ((j&3) != 3 ? 1 : (72-3));
+        out++;
+    }
+}
+
+void ff_mpadsp_init_mipsfpu(MPADSPContext *s)
+{
+    s->apply_window_float   = ff_mpadsp_apply_window_mips_float;
+    s->imdct36_blocks_float = ff_imdct36_blocks_mips_float;
+    s->dct32_float          = ff_dct32_mips_float;
+}
diff --git a/libavcodec/mips/mpegvideo_mmi.c b/libavcodec/mips/mpegvideo_mmi.c
index 46239f7..2870892 100644
--- a/libavcodec/mips/mpegvideo_mmi.c
+++ b/libavcodec/mips/mpegvideo_mmi.c
@@ -3,20 +3,20 @@
  *
  * MMI optimization by Leon van Stuivenberg
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mjpeg.c b/libavcodec/mjpeg.c
index a353851..a5b1a80 100644
--- a/libavcodec/mjpeg.c
+++ b/libavcodec/mjpeg.c
@@ -8,20 +8,20 @@
  * aspecting, new decode_frame mechanism and apple mjpeg-b support
  *                                  by Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mjpeg.h b/libavcodec/mjpeg.h
index 1374ab3..d826278 100644
--- a/libavcodec/mjpeg.h
+++ b/libavcodec/mjpeg.h
@@ -8,20 +8,20 @@
  * aspecting, new decode_frame mechanism and apple mjpeg-b support
  *                                  by Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -127,6 +127,7 @@
 
 #define PREDICT(ret, topleft, top, left, predictor)\
     switch(predictor){\
+        case 0: ret= 0; break;\
         case 1: ret= left; break;\
         case 2: ret= top; break;\
         case 3: ret= topleft; break;\
diff --git a/libavcodec/mjpeg2jpeg_bsf.c b/libavcodec/mjpeg2jpeg_bsf.c
index ec36589..f367288 100644
--- a/libavcodec/mjpeg2jpeg_bsf.c
+++ b/libavcodec/mjpeg2jpeg_bsf.c
@@ -2,20 +2,20 @@
  * MJPEG/AVI1 to JPEG/JFIF bitstream format filter
  * Copyright (c) 2010 Adrian Daerr and Nicolas George
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mjpeg_parser.c b/libavcodec/mjpeg_parser.c
index ab65461..e548b00 100644
--- a/libavcodec/mjpeg_parser.c
+++ b/libavcodec/mjpeg_parser.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2003 Alex Beregszaszi
  * Copyright (c) 2003-2004 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -28,27 +28,44 @@
 
 #include "parser.h"
 
+typedef struct MJPEGParserContext{
+    ParseContext pc;
+    int size;
+}MJPEGParserContext;
 
 /**
  * Find the end of the current frame in the bitstream.
  * @return the position of the first byte of the next frame, or -1
  */
-static int find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
+static int find_frame_end(MJPEGParserContext *m, const uint8_t *buf, int buf_size){
+    ParseContext *pc= &m->pc;
     int vop_found, i;
-    uint16_t state;
+    uint32_t state;
 
     vop_found= pc->frame_start_found;
     state= pc->state;
 
     i=0;
     if(!vop_found){
-        for(i=0; i<buf_size; i++){
+        for(i=0; i<buf_size;){
             state= (state<<8) | buf[i];
-            if(state == 0xFFD8){
-                i++;
-                vop_found=1;
-                break;
+            if(state>=0xFFC00000 && state<=0xFFFEFFFF){
+                if(state>=0xFFD80000 && state<=0xFFD8FFFF){
+                    i++;
+                    vop_found=1;
+                    break;
+                }else if(state<0xFFD00000 || state>0xFFD9FFFF){
+                    m->size= (state&0xFFFF)-1;
+                }
             }
+            if(m->size>0){
+                int size= FFMIN(buf_size-i, m->size);
+                i+=size;
+                m->size-=size;
+                state=0;
+                continue;
+            }else
+                i++;
         }
     }
 
@@ -56,13 +73,25 @@
         /* EOF considered as end of frame */
         if (buf_size == 0)
             return 0;
-        for(; i<buf_size; i++){
+        for(; i<buf_size;){
             state= (state<<8) | buf[i];
-            if(state == 0xFFD8){
-                pc->frame_start_found=0;
-                pc->state=0;
-                return i-1;
+            if(state>=0xFFC00000 && state<=0xFFFEFFFF){
+                if(state>=0xFFD80000 && state<=0xFFD8FFFF){
+                    pc->frame_start_found=0;
+                    pc->state=0;
+                    return i-3;
+                } else if(state<0xFFD00000 || state>0xFFD9FFFF){
+                    m->size= (state&0xFFFF)-1;
+                }
             }
+            if(m->size>0){
+                int size= FFMIN(buf_size-i, m->size);
+                i+=size;
+                m->size-=size;
+                state=0;
+                continue;
+            }else
+                i++;
         }
     }
     pc->frame_start_found= vop_found;
@@ -75,13 +104,14 @@
                       const uint8_t **poutbuf, int *poutbuf_size,
                       const uint8_t *buf, int buf_size)
 {
-    ParseContext *pc = s->priv_data;
+    MJPEGParserContext *m = s->priv_data;
+    ParseContext *pc = &m->pc;
     int next;
 
     if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
         next= buf_size;
     }else{
-        next= find_frame_end(pc, buf, buf_size);
+        next= find_frame_end(m, buf, buf_size);
 
         if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
             *poutbuf = NULL;
@@ -98,7 +128,7 @@
 
 AVCodecParser ff_mjpeg_parser = {
     .codec_ids      = { AV_CODEC_ID_MJPEG },
-    .priv_data_size = sizeof(ParseContext),
+    .priv_data_size = sizeof(MJPEGParserContext),
     .parser_parse   = jpeg_parse,
     .parser_close   = ff_parse_close,
 };
diff --git a/libavcodec/mjpega_dump_header_bsf.c b/libavcodec/mjpega_dump_header_bsf.c
index ed32d5a..9de6ac3 100644
--- a/libavcodec/mjpega_dump_header_bsf.c
+++ b/libavcodec/mjpega_dump_header_bsf.c
@@ -2,20 +2,20 @@
  * MJPEG A dump header bitstream filter
  * Copyright (c) 2006 Baptiste Coudurier
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c
index 8c8514f..77f23f2 100644
--- a/libavcodec/mjpegbdec.c
+++ b/libavcodec/mjpegbdec.c
@@ -2,20 +2,20 @@
  * Apple MJPEG-B decoder
  * Copyright (c) 2002 Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -52,6 +52,7 @@
 
     buf_ptr = buf;
     buf_end = buf + buf_size;
+    s->got_picture = 0;
 
 read_header:
     /* reset on every SOI */
@@ -129,7 +130,6 @@
         if (s->bottom_field != s->interlace_polarity && second_field_offs)
         {
             buf_ptr = buf + second_field_offs;
-            second_field_offs = 0;
             goto read_header;
             }
     }
@@ -161,5 +161,6 @@
     .close          = ff_mjpeg_decode_end,
     .decode         = mjpegb_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
+    .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("Apple MJPEG-B"),
 };
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index ecccd68..6b5266d 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -8,20 +8,20 @@
  * aspecting, new decode_frame mechanism and apple mjpeg-b support
  *                                  by Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,10 +30,8 @@
  * MJPEG decoder.
  */
 
-// #define DEBUG
-#include <assert.h>
-
 #include "libavutil/imgutils.h"
+#include "libavutil/avassert.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
 #include "dsputil.h"
@@ -51,7 +49,7 @@
     uint16_t huff_sym[256];
     int i;
 
-    assert(nb_codes <= 256);
+    av_assert0(nb_codes <= 256);
 
     ff_mjpeg_build_huffman_codes(huff_size, huff_code, bits_table, val_table);
 
@@ -87,6 +85,7 @@
 
     if (!s->picture_ptr)
         s->picture_ptr = &s->picture;
+    avcodec_get_frame_defaults(&s->picture);
 
     s->avctx = avctx;
     ff_dsputil_init(&s->dsp, avctx);
@@ -101,18 +100,17 @@
     build_basic_mjpeg_vlc(s);
 
     if (s->extern_huff) {
-        int ret;
-        av_log(avctx, AV_LOG_INFO, "mjpeg: using external huffman table\n");
+        av_log(avctx, AV_LOG_INFO, "using external huffman table\n");
         init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size * 8);
-        if ((ret = ff_mjpeg_decode_dht(s))) {
+        if (ff_mjpeg_decode_dht(s)) {
             av_log(avctx, AV_LOG_ERROR,
-                   "mjpeg: error using external huffman table\n");
-            return ret;
+                   "error using external huffman table, switching back to internal\n");
+            build_basic_mjpeg_vlc(s);
         }
     }
     if (avctx->field_order == AV_FIELD_BB) { /* quicktime icefloe 019 */
         s->interlace_polarity = 1;           /* bottom field first */
-        av_log(avctx, AV_LOG_DEBUG, "mjpeg bottom field first\n");
+        av_log(avctx, AV_LOG_DEBUG, "bottom field first\n");
     }
     if (avctx->codec->id == AV_CODEC_ID_AMV)
         s->flipped = 1;
@@ -213,6 +211,9 @@
 {
     int len, nb_components, i, width, height, pix_fmt_id;
 
+    s->cur_scan = 0;
+    s->upscale_h = s->upscale_v = 0;
+
     /* XXX: verify len field validity */
     len     = get_bits(&s->gb, 16);
     s->bits = get_bits(&s->gb, 8);
@@ -227,6 +228,11 @@
         return -1;
     }
 
+    if(s->lossless && s->avctx->lowres){
+        av_log(s->avctx, AV_LOG_ERROR, "lowres is not possible with lossless jpeg\n");
+        return -1;
+    }
+
     height = get_bits(&s->gb, 16);
     width  = get_bits(&s->gb, 16);
 
@@ -242,6 +248,12 @@
     if (nb_components <= 0 ||
         nb_components > MAX_COMPONENTS)
         return -1;
+    if (s->interlaced && (s->bottom_field == !s->interlace_polarity)) {
+        if (nb_components != s->nb_components) {
+            av_log(s->avctx, AV_LOG_ERROR, "nb_components changing in interlaced picture\n");
+            return AVERROR_INVALIDDATA;
+        }
+    }
     if (s->ls && !(s->bits <= 8 || nb_components == 1)) {
         av_log_missing_feature(s->avctx,
                                "For JPEG-LS anything except <= 8 bits/component"
@@ -261,6 +273,10 @@
             s->h_max = s->h_count[i];
         if (s->v_count[i] > s->v_max)
             s->v_max = s->v_count[i];
+        if (!s->h_count[i] || !s->v_count[i]) {
+            av_log(s->avctx, AV_LOG_ERROR, "h/v_count is 0\n");
+            return -1;
+        }
         s->quant_index[i] = get_bits(&s->gb, 8);
         if (s->quant_index[i] >= 4)
             return AVERROR_INVALIDDATA;
@@ -274,7 +290,7 @@
         return AVERROR_PATCHWELCOME;
     }
 
-    if (s->v_max == 1 && s->h_max == 1 && s->lossless == 1)
+    if (s->v_max == 1 && s->h_max == 1 && s->lossless==1 && nb_components==3)
         s->rgb = 1;
 
     /* if different size, realloc/alloc picture */
@@ -303,7 +319,12 @@
         s->first_picture = 0;
     }
 
-    if (!(s->interlaced && (s->bottom_field == !s->interlace_polarity))) {
+    if (s->interlaced && (s->bottom_field == !s->interlace_polarity)) {
+        if (s->progressive) {
+            av_log_ask_for_sample(s->avctx, "progressively coded interlaced pictures not supported\n");
+            return AVERROR_INVALIDDATA;
+        }
+    } else{
     /* 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) |
@@ -320,28 +341,78 @@
     switch (pix_fmt_id) {
     case 0x11111100:
         if (s->rgb)
-            s->avctx->pix_fmt = AV_PIX_FMT_BGRA;
-        else
+            s->avctx->pix_fmt = AV_PIX_FMT_BGR24;
+        else {
+            if (s->component_id[0] == 'Q' && s->component_id[1] == 'F' && s->component_id[2] == 'A') {
+                s->avctx->pix_fmt = AV_PIX_FMT_GBR24P;
+            } else {
             s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
-        assert(s->nb_components == 3);
+            s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+            }
+        }
+        av_assert0(s->nb_components == 3);
+        break;
+    case 0x12121100:
+    case 0x22122100:
+        s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
+        s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+        s->upscale_v = 2;
+        s->upscale_h = (pix_fmt_id == 0x22122100);
+        s->chroma_height = s->height;
+        break;
+    case 0x21211100:
+    case 0x22211200:
+        s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
+        s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+        s->upscale_v = (pix_fmt_id == 0x22211200);
+        s->upscale_h = 2;
+        s->chroma_height = s->height;
+        break;
+    case 0x22221100:
+        s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
+        s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+        s->upscale_v = 2;
+        s->upscale_h = 2;
+        s->chroma_height = s->height / 2;
         break;
     case 0x11000000:
-        s->avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+        if(s->bits <= 8)
+            s->avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+        else
+            s->avctx->pix_fmt = AV_PIX_FMT_GRAY16;
         break;
     case 0x12111100:
+    case 0x22211100:
+    case 0x22112100:
         s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV440P : AV_PIX_FMT_YUVJ440P;
+        s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+        s->upscale_h = (pix_fmt_id == 0x22211100) * 2 + (pix_fmt_id == 0x22112100);
+        s->chroma_height = s->height / 2;
         break;
     case 0x21111100:
         s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P;
+        s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+        break;
+    case 0x22121100:
+    case 0x22111200:
+        s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P;
+        s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+        s->upscale_v = (pix_fmt_id == 0x22121100) + 1;
         break;
     case 0x22111100:
         s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUVJ420P;
+        s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
         break;
     default:
         av_log(s->avctx, AV_LOG_ERROR, "Unhandled pixel format 0x%x\n", pix_fmt_id);
         return AVERROR_PATCHWELCOME;
     }
+    if ((s->upscale_h || s->upscale_v) && s->avctx->lowres) {
+        av_log(s->avctx, AV_LOG_ERROR, "lowres not supported for weird subsampling\n");
+        return AVERROR_PATCHWELCOME;
+    }
     if (s->ls) {
+        s->upscale_h = s->upscale_v = 0;
         if (s->nb_components > 1)
             s->avctx->pix_fmt = AV_PIX_FMT_RGB24;
         else if (s->bits <= 8)
@@ -636,25 +707,27 @@
 #undef REFINE_BIT
 #undef ZERO_RUN
 
-static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor,
-                                 int point_transform)
+static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int predictor, int point_transform)
 {
     int i, mb_x, mb_y;
     uint16_t (*buffer)[4];
     int left[3], top[3], topleft[3];
     const int linesize = s->linesize[0];
     const int mask     = (1 << s->bits) - 1;
+    int resync_mb_y = 0;
+    int resync_mb_x = 0;
+
+    s->restart_count = s->restart_interval;
 
     av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size,
                    (unsigned)s->mb_width * 4 * sizeof(s->ljpeg_buffer[0][0]));
     buffer = s->ljpeg_buffer;
 
     for (i = 0; i < 3; i++)
-        buffer[0][i] = 1 << (s->bits + point_transform - 1);
+        buffer[0][i] = 1 << (s->bits - 1);
 
     for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
-        const int modified_predictor = mb_y ? predictor : 1;
-        uint8_t *ptr = s->picture_ptr->data[0] + (linesize * mb_y);
+        uint8_t *ptr = s->picture.data[0] + (linesize * mb_y);
 
         if (s->interlaced && s->bottom_field)
             ptr += linesize >> 1;
@@ -663,19 +736,32 @@
             top[i] = left[i] = topleft[i] = buffer[0][i];
 
         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
-            if (s->restart_interval && !s->restart_count)
-                s->restart_count = s->restart_interval;
+            int modified_predictor = predictor;
 
-            for (i = 0; i < 3; i++) {
-                int pred;
+            if (s->restart_interval && !s->restart_count){
+                s->restart_count = s->restart_interval;
+                resync_mb_x = mb_x;
+                resync_mb_y = mb_y;
+                for(i=0; i<3; i++)
+                    top[i] = left[i]= topleft[i]= 1 << (s->bits - 1);
+            }
+            if (mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x || !mb_x)
+                modified_predictor = 1;
+
+            for (i=0;i<nb_components;i++) {
+                int pred, dc;
 
                 topleft[i] = top[i];
                 top[i]     = buffer[mb_x][i];
 
                 PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
 
+                dc = mjpeg_decode_dc(s, s->dc_index[i]);
+                if(dc == 0xFFFF)
+                    return -1;
+
                 left[i] = buffer[mb_x][i] =
-                    mask & (pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform));
+                    mask & (pred + (dc << point_transform));
             }
 
             if (s->restart_interval && !--s->restart_count) {
@@ -686,21 +772,22 @@
 
         if (s->rct) {
             for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
-                ptr[4 * mb_x + 1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2] - 0x200) >> 2);
-                ptr[4 * mb_x + 0] = buffer[mb_x][1] + ptr[4 * mb_x + 1];
-                ptr[4 * mb_x + 2] = buffer[mb_x][2] + ptr[4 * mb_x + 1];
+                ptr[3*mb_x + 1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2] - 0x200) >> 2);
+                ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1];
+                ptr[3*mb_x + 2] = buffer[mb_x][2] + ptr[3*mb_x + 1];
             }
         } else if (s->pegasus_rct) {
             for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
-                ptr[4 * mb_x + 1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2]) >> 2);
-                ptr[4 * mb_x + 0] = buffer[mb_x][1] + ptr[4 * mb_x + 1];
-                ptr[4 * mb_x + 2] = buffer[mb_x][2] + ptr[4 * mb_x + 1];
+                ptr[3*mb_x + 1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2]) >> 2);
+                ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1];
+                ptr[3*mb_x + 2] = buffer[mb_x][2] + ptr[3*mb_x + 1];
             }
         } else {
-            for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
-                ptr[4 * mb_x + 0] = buffer[mb_x][2];
-                ptr[4 * mb_x + 1] = buffer[mb_x][1];
-                ptr[4 * mb_x + 2] = buffer[mb_x][0];
+            for(i=0; i<nb_components; i++) {
+                int c= s->comp_index[i];
+                for(mb_x = 0; mb_x < s->mb_width; mb_x++) {
+                    ptr[3*mb_x+2-c] = buffer[mb_x][i];
+                }
             }
         }
     }
@@ -711,48 +798,87 @@
                                  int point_transform)
 {
     int i, mb_x, mb_y;
-    const int nb_components = 3;
+    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);
 
     for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
         for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
-            if (s->restart_interval && !s->restart_count)
+            if (s->restart_interval && !s->restart_count){
                 s->restart_count = s->restart_interval;
+                resync_mb_x = mb_x;
+                resync_mb_y = mb_y;
+            }
 
-            if (mb_x == 0 || mb_y == 0 || s->interlaced) {
+            if(!mb_x || mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x || s->interlaced){
+                int toprow  = mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x;
+                int leftcol = !mb_x || mb_y == resync_mb_y && mb_x == resync_mb_x;
                 for (i = 0; i < nb_components; i++) {
                     uint8_t *ptr;
+                    uint16_t *ptr16;
                     int n, h, v, x, y, c, j, linesize;
-                    n        = s->nb_blocks[i];
-                    c        = s->comp_index[i];
-                    h        = s->h_scount[i];
-                    v        = s->v_scount[i];
-                    x        = 0;
-                    y        = 0;
-                    linesize = s->linesize[c];
+                    n = s->nb_blocks[i];
+                    c = s->comp_index[i];
+                    h = s->h_scount[i];
+                    v = s->v_scount[i];
+                    x = 0;
+                    y = 0;
+                    linesize= s->linesize[c];
 
-                    for (j = 0; j < n; j++) {
-                        int pred;
-                        // FIXME optimize this crap
-                        ptr = s->picture_ptr->data[c] +
-                              (linesize * (v * mb_y + y)) +
-                              (h * mb_x + x);
-                        if (y == 0 && mb_y == 0) {
-                            if (x == 0 && mb_x == 0)
-                                pred = 128 << point_transform;
-                            else
-                                pred = ptr[-1];
-                        } else {
-                            if (x == 0 && mb_x == 0)
-                                pred = ptr[-linesize];
-                            else
-                                PREDICT(pred, ptr[-linesize - 1],
-                                        ptr[-linesize], ptr[-1], predictor);
-                       }
+                    if(bits>8) linesize /= 2;
+
+                    for(j=0; j<n; j++) {
+                        int pred, dc;
+
+                        dc = mjpeg_decode_dc(s, s->dc_index[i]);
+                        if(dc == 0xFFFF)
+                            return -1;
+                        if(bits<=8){
+                        ptr = s->picture.data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
+                        if(y==0 && toprow){
+                            if(x==0 && leftcol){
+                                pred= 1 << (bits - 1);
+                            }else{
+                                pred= ptr[-1];
+                            }
+                        }else{
+                            if(x==0 && leftcol){
+                                pred= ptr[-linesize];
+                            }else{
+                                PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
+                            }
+                        }
 
                         if (s->interlaced && s->bottom_field)
                             ptr += linesize >> 1;
-                        *ptr = pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform);
+                        pred &= (-1)<<(8-s->bits);
+                        *ptr= pred + (dc << point_transform);
+                        }else{
+                            ptr16 = (uint16_t*)(s->picture.data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap
+                            if(y==0 && toprow){
+                                if(x==0 && leftcol){
+                                    pred= 1 << (bits - 1);
+                                }else{
+                                    pred= ptr16[-1];
+                                }
+                            }else{
+                                if(x==0 && leftcol){
+                                    pred= ptr16[-linesize];
+                                }else{
+                                    PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor);
+                                }
+                            }
 
+                            if (s->interlaced && s->bottom_field)
+                                ptr16 += linesize >> 1;
+                            pred &= (-1)<<(16-s->bits);
+                            *ptr16= pred + (dc << point_transform);
+                        }
                         if (++x == h) {
                             x = 0;
                             y++;
@@ -762,7 +888,8 @@
             } else {
                 for (i = 0; i < nb_components; i++) {
                     uint8_t *ptr;
-                    int n, h, v, x, y, c, j, linesize;
+                    uint16_t *ptr16;
+                    int n, h, v, x, y, c, j, linesize, dc;
                     n        = s->nb_blocks[i];
                     c        = s->comp_index[i];
                     h        = s->h_scount[i];
@@ -771,16 +898,30 @@
                     y        = 0;
                     linesize = s->linesize[c];
 
+                    if(bits>8) linesize /= 2;
+
                     for (j = 0; j < n; j++) {
                         int pred;
 
-                        // FIXME optimize this crap
-                        ptr = s->picture_ptr->data[c] +
+                        dc = mjpeg_decode_dc(s, s->dc_index[i]);
+                        if(dc == 0xFFFF)
+                            return -1;
+                        if(bits<=8){
+                            ptr = s->picture.data[c] +
                               (linesize * (v * mb_y + y)) +
-                              (h * mb_x + x);
-                        PREDICT(pred, ptr[-linesize - 1],
-                                ptr[-linesize], ptr[-1], predictor);
-                        *ptr = pred + (mjpeg_decode_dc(s, s->dc_index[i]) << point_transform);
+                              (h * mb_x + x); //FIXME optimize this crap
+                            PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
+
+                            pred &= (-1)<<(8-s->bits);
+                            *ptr = pred + (dc << point_transform);
+                        }else{
+                            ptr16 = (uint16_t*)(s->picture.data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap
+                            PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor);
+
+                            pred &= (-1)<<(16-s->bits);
+                            *ptr16= pred + (dc << point_transform);
+                        }
+
                         if (++x == h) {
                             x = 0;
                             y++;
@@ -797,6 +938,21 @@
     return 0;
 }
 
+static av_always_inline void mjpeg_copy_block(uint8_t *dst, const uint8_t *src,
+                                              int linesize, int lowres)
+{
+    switch (lowres) {
+    case 0: copy_block8(dst, src, linesize, linesize, 8);
+        break;
+    case 1: copy_block4(dst, src, linesize, linesize, 4);
+        break;
+    case 2: copy_block2(dst, src, linesize, linesize, 2);
+        break;
+    case 3: *dst = *src;
+        break;
+    }
+}
+
 static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
                              int Al, const uint8_t *mb_bitmask,
                              const AVFrame *reference)
@@ -810,9 +966,8 @@
     if (mb_bitmask)
         init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height);
 
-    if (s->flipped && s->avctx->flags & CODEC_FLAG_EMU_EDGE) {
-        av_log(s->avctx, AV_LOG_ERROR,
-               "Can not flip image with CODEC_FLAG_EMU_EDGE set!\n");
+    if (s->flipped && s->avctx->lowres) {
+        av_log(s->avctx, AV_LOG_ERROR, "Can not flip image with lowres\n");
         s->flipped = 0;
     }
 
@@ -822,7 +977,7 @@
         reference_data[c] = reference ? reference->data[c] : NULL;
         linesize[c] = s->linesize[c];
         s->coefs_finished[c] |= 1;
-        if (s->flipped) {
+        if (s->flipped && !(s->avctx->flags & CODEC_FLAG_EMU_EDGE)) {
             // picture should be flipped upside-down for this codec
             int offset = (linesize[c] * (s->v_scount[i] *
                          (8 * s->mb_height - ((s->height / s->v_max) & 7)) - 1));
@@ -855,16 +1010,16 @@
                 x = 0;
                 y = 0;
                 for (j = 0; j < n; j++) {
-                    block_offset = ((linesize[c] * (v * mb_y + y) * 8) +
-                                    (h * mb_x + x) * 8);
+                    block_offset = (((linesize[c] * (v * mb_y + y) * 8) +
+                                     (h * mb_x + x) * 8) >> s->avctx->lowres);
 
                     if (s->interlaced && s->bottom_field)
                         block_offset += linesize[c] >> 1;
                     ptr = data[c] + block_offset;
                     if (!s->progressive) {
                         if (copy_mb)
-                            copy_block8(ptr, reference_data[c] + block_offset,
-                                        linesize[c], linesize[c], 8);
+                            mjpeg_copy_block(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,
@@ -904,6 +1059,12 @@
 
             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) {
@@ -911,7 +1072,7 @@
                     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(&s->gb, 8) & 0xF8) == 0xD0) {
+                    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
@@ -924,44 +1085,30 @@
 }
 
 static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss,
-                                            int se, int Ah, int Al,
-                                            const uint8_t *mb_bitmask,
-                                            const AVFrame *reference)
+                                            int se, int Ah, int Al)
 {
     int mb_x, mb_y;
     int EOBRUN = 0;
     int c = s->comp_index[0];
-    uint8_t *data = s->picture_ptr->data[c];
-    const uint8_t *reference_data = reference ? reference->data[c] : NULL;
+    uint8_t *data = s->picture.data[c];
     int linesize  = s->linesize[c];
     int last_scan = 0;
     int16_t *quant_matrix = s->quant_matrixes[s->quant_index[c]];
-    GetBitContext mb_bitmask_gb;
-
-    if (mb_bitmask)
-        init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height);
 
     if (!Al) {
         s->coefs_finished[c] |= (1LL << (se + 1)) - (1LL << ss);
         last_scan = !~s->coefs_finished[c];
     }
 
-    if (s->interlaced && s->bottom_field) {
-        int offset      = linesize >> 1;
-        data           += offset;
-        reference_data += offset;
-    }
+    if (s->interlaced && s->bottom_field)
+        data += linesize >> 1;
 
     for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
-        int block_offset = mb_y * linesize * 8;
-        uint8_t *ptr     = data + block_offset;
+        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];
         uint8_t *last_nnz    = &s->last_nnz[c][block_idx];
         for (mb_x = 0; mb_x < s->mb_width; mb_x++, block++, last_nnz++) {
-            const int copy_mb = mb_bitmask && !get_bits1(&mb_bitmask_gb);
-
-            if (!copy_mb) {
                 int ret;
                 if (Ah)
                     ret = decode_block_refinement(s, *block, last_nnz, s->ac_index[0],
@@ -974,16 +1121,10 @@
                            "error y=%d x=%d\n", mb_y, mb_x);
                     return AVERROR_INVALIDDATA;
                 }
-            }
 
             if (last_scan) {
-                if (copy_mb) {
-                    copy_block8(ptr, reference_data + block_offset,
-                                linesize, linesize, 8);
-                } else {
                     s->dsp.idct_put(ptr, linesize, *block);
-                    ptr += 8;
-                }
+                    ptr += 8 >> s->avctx->lowres;
             }
         }
     }
@@ -998,6 +1139,13 @@
     const int block_size = s->lossless ? 1 : 8;
     int ilv, prev_shift;
 
+    if (!s->got_picture) {
+        av_log(s->avctx, AV_LOG_WARNING,
+                "Can not process SOS before SOF, skipping\n");
+        return -1;
+    }
+
+    av_assert0(s->picture_ptr->data[0]);
     /* XXX: verify len field validity */
     len = get_bits(&s->gb, 16);
     nb_components = get_bits(&s->gb, 8);
@@ -1027,6 +1175,11 @@
             && nb_components == 3 && s->nb_components == 3 && i)
             index = 3 - i;
 
+        if(nb_components == 3 && s->nb_components == 3 && s->avctx->pix_fmt == AV_PIX_FMT_GBR24P)
+            index = (i+2)%3;
+        if(nb_components == 1 && s->nb_components == 3 && s->avctx->pix_fmt == AV_PIX_FMT_GBR24P)
+            index = (index+2)%3;
+
         s->comp_index[i] = index;
 
         s->nb_blocks[i] = s->h_count[index] * s->v_count[index];
@@ -1039,15 +1192,17 @@
         if (s->dc_index[i] <  0 || s->ac_index[i] < 0 ||
             s->dc_index[i] >= 4 || s->ac_index[i] >= 4)
             goto out_of_range;
-        if (!s->vlcs[0][s->dc_index[i]].table ||
-            !s->vlcs[1][s->ac_index[i]].table)
+        if (!s->vlcs[0][s->dc_index[i]].table || !(s->progressive ? s->vlcs[2][s->ac_index[0]].table : s->vlcs[1][s->ac_index[i]].table))
             goto out_of_range;
     }
 
     predictor = get_bits(&s->gb, 8);       /* JPEG Ss / lossless JPEG predictor /JPEG-LS NEAR */
     ilv = get_bits(&s->gb, 8);             /* JPEG Se / JPEG-LS ILV */
-    prev_shift      = get_bits(&s->gb, 4); /* Ah */
-    point_transform = get_bits(&s->gb, 4); /* Al */
+    if(s->avctx->codec_tag != AV_RL32("CJPG")){
+        prev_shift      = get_bits(&s->gb, 4); /* Ah */
+        point_transform = get_bits(&s->gb, 4); /* Al */
+    }else
+        prev_shift = point_transform = 0;
 
     if (nb_components > 1) {
         /* interleaved stream */
@@ -1064,10 +1219,10 @@
     }
 
     if (s->avctx->debug & FF_DEBUG_PICT_INFO)
-        av_log(s->avctx, AV_LOG_DEBUG, "%s %s p:%d >>:%d ilv:%d bits:%d %s\n",
+        av_log(s->avctx, AV_LOG_DEBUG, "%s %s p:%d >>:%d ilv:%d bits:%d skip:%d %s comp:%d\n",
                s->lossless ? "lossless" : "sequential DCT", s->rgb ? "RGB" : "",
-               predictor, point_transform, ilv, s->bits,
-               s->pegasus_rct ? "PRCT" : (s->rct ? "RCT" : ""));
+               predictor, point_transform, ilv, s->bits, s->mjpb_skiptosod,
+               s->pegasus_rct ? "PRCT" : (s->rct ? "RCT" : ""), nb_components);
 
 
     /* mjpeg-b can have padding bytes between sos and image data, skip them */
@@ -1079,6 +1234,7 @@
         s->last_dc[i] = 1024;
 
     if (s->lossless) {
+        av_assert0(s->picture_ptr == &s->picture);
         if (CONFIG_JPEGLS_DECODER && s->ls) {
 //            for () {
 //            reset_ls_coding_parameters(s, 0);
@@ -1088,22 +1244,19 @@
                 return ret;
         } else {
             if (s->rgb) {
-                if ((ret = ljpeg_decode_rgb_scan(s, predictor,
-                                                 point_transform)) < 0)
+                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, predictor, point_transform)) < 0)
                     return ret;
             }
         }
     } else {
         if (s->progressive && predictor) {
+            av_assert0(s->picture_ptr == &s->picture);
             if ((ret = mjpeg_decode_scan_progressive_ac(s, predictor,
                                                         ilv, prev_shift,
-                                                        point_transform,
-                                                        mb_bitmask,
-                                                        reference)) < 0)
+                                                        point_transform)) < 0)
                 return ret;
         } else {
             if ((ret = mjpeg_decode_scan(s, nb_components,
@@ -1119,7 +1272,7 @@
         GetBitContext bak = s->gb;
         align_get_bits(&bak);
         if (show_bits(&bak, 16) == 0xFFD1) {
-            av_dlog(s->avctx, "AVRn interlaced picture marker found\n");
+            av_log(s->avctx, AV_LOG_DEBUG, "AVRn interlaced picture marker found\n");
             s->gb = bak;
             skip_bits(&s->gb, 16);
             s->bottom_field ^= 1;
@@ -1175,12 +1328,9 @@
             4bytes      field_size
             4bytes      field_size_less_padding
         */
-        s->buggy_avid = 1;
-        i = get_bits(&s->gb, 8);
-        if (i == 2)
-            s->bottom_field = 1;
-        else if (i == 1)
-            s->bottom_field = 0;
+            s->buggy_avid = 1;
+        i = get_bits(&s->gb, 8); len--;
+        av_log(s->avctx, AV_LOG_DEBUG, "polarity %d\n", i);
 #if 0
         skip_bits(&s->gb, 8);
         skip_bits(&s->gb, 32);
@@ -1303,14 +1453,14 @@
                 cbuf[i] = 0;
 
             if (s->avctx->debug & FF_DEBUG_PICT_INFO)
-                av_log(s->avctx, AV_LOG_INFO, "mjpeg comment: '%s'\n", cbuf);
+                av_log(s->avctx, AV_LOG_INFO, "comment: '%s'\n", cbuf);
 
             /* buggy avid, it puts EOI only at every 10th frame */
             if (!strcmp(cbuf, "AVID")) {
                 s->buggy_avid = 1;
             } else if (!strcmp(cbuf, "CS=ITU601"))
                 s->cs_itu601 = 1;
-            else if ((len > 20 && !strncmp(cbuf, "Intel(R) JPEG Library", 21)) ||
+            else if ((len > 31 && !strncmp(cbuf, "Intel(R) JPEG Library, version 1", 32)) ||
                      (len > 19 && !strncmp(cbuf, "Metasoft MJPEG Codec", 20)))
                 s->flipped = 1;
 
@@ -1328,9 +1478,7 @@
     const uint8_t *buf_ptr;
     unsigned int v, v2;
     int val;
-#ifdef DEBUG
     int skipped = 0;
-#endif
 
     buf_ptr = *pbuf_ptr;
     while (buf_ptr < buf_end) {
@@ -1340,9 +1488,7 @@
             val = *buf_ptr++;
             goto found;
         }
-#ifdef DEBUG
         skipped++;
-#endif
     }
     val = -1;
 found:
@@ -1445,6 +1591,7 @@
     const uint8_t *unescaped_buf_ptr;
     int unescaped_buf_size;
     int start_code;
+    int i, index;
     int ret = 0;
     AVFrame *picture = data;
 
@@ -1534,21 +1681,19 @@
                     return ret;
                 break;
             case EOI:
-                s->cur_scan = 0;
-                if ((s->buggy_avid && !s->interlaced) || s->restart_interval)
-                    break;
 eoi_parser:
+                s->cur_scan = 0;
                 if (!s->got_picture) {
                     av_log(avctx, AV_LOG_WARNING,
                            "Found EOI before any SOF, ignoring\n");
                     break;
-                    }
+                }
                 if (s->interlaced) {
                     s->bottom_field ^= 1;
                     /* if not bottom field, do not output image yet */
                     if (s->bottom_field == !s->interlace_polarity)
-                        goto not_the_end;
-                    }
+                        break;
+                }
                     *picture   = *s->picture_ptr;
                     *data_size = sizeof(AVFrame);
 
@@ -1568,18 +1713,9 @@
 
                 goto the_end;
             case SOS:
-                if (!s->got_picture) {
-                    av_log(avctx, AV_LOG_WARNING,
-                           "Can not process SOS before SOF, skipping\n");
-                    break;
-                    }
                 if ((ret = ff_mjpeg_decode_sos(s, NULL, NULL)) < 0 &&
                     (avctx->err_recognition & AV_EF_EXPLODE))
                     return ret;
-                /* buggy avid puts EOI every 10-20th frame */
-                /* if restart period is over process EOI */
-                if ((s->buggy_avid && !s->interlaced) || s->restart_interval)
-                    goto eoi_parser;
                 break;
             case DRI:
                 mjpeg_decode_dri(s);
@@ -1599,7 +1735,6 @@
                 break;
             }
 
-not_the_end:
             /* eof process start code */
             buf_ptr += (get_bits_count(&s->gb) + 7) / 8;
             av_log(avctx, AV_LOG_DEBUG,
@@ -1614,7 +1749,60 @@
     av_log(avctx, AV_LOG_FATAL, "No JPEG data found in image\n");
     return AVERROR_INVALIDDATA;
 the_end:
-    av_log(avctx, AV_LOG_DEBUG, "mjpeg decode frame unused %td bytes\n",
+    if (s->upscale_h) {
+        uint8_t *line = s->picture_ptr->data[s->upscale_h];
+        av_assert0(avctx->pix_fmt == AV_PIX_FMT_YUVJ444P ||
+                   avctx->pix_fmt == AV_PIX_FMT_YUV444P  ||
+                   avctx->pix_fmt == AV_PIX_FMT_YUVJ440P ||
+                   avctx->pix_fmt == AV_PIX_FMT_YUV440P);
+        for (i = 0; i < s->chroma_height; i++) {
+            for (index = s->width - 1; index; index--)
+                line[index] = (line[index / 2] + line[(index + 1) / 2]) >> 1;
+            line += s->linesize[s->upscale_h];
+        }
+    }
+    if (s->upscale_v) {
+        uint8_t *dst = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[(s->height - 1) * s->linesize[s->upscale_v]];
+        av_assert0(avctx->pix_fmt == AV_PIX_FMT_YUVJ444P ||
+                   avctx->pix_fmt == AV_PIX_FMT_YUV444P  ||
+                   avctx->pix_fmt == AV_PIX_FMT_YUVJ422P ||
+                   avctx->pix_fmt == AV_PIX_FMT_YUV422P);
+        for (i = s->height - 1; i; i--) {
+            uint8_t *src1 = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[i / 2 * s->linesize[s->upscale_v]];
+            uint8_t *src2 = &((uint8_t *)s->picture_ptr->data[s->upscale_v])[(i + 1) / 2 * s->linesize[s->upscale_v]];
+            if (src1 == src2) {
+                memcpy(dst, src1, s->width);
+            } else {
+                for (index = 0; index < s->width; index++)
+                    dst[index] = (src1[index] + src2[index]) >> 1;
+            }
+            dst -= s->linesize[s->upscale_v];
+        }
+    }
+    if (s->flipped && (s->avctx->flags & CODEC_FLAG_EMU_EDGE)) {
+        int hshift, vshift, j;
+        avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift);
+        for (index=0; index<4; index++) {
+            uint8_t *dst = s->picture_ptr->data[index];
+            int w = s->width;
+            int h = s->height;
+            if(index && index<3){
+                w = -((-w) >> hshift);
+                h = -((-h) >> vshift);
+            }
+            if(dst){
+                uint8_t *dst2 = dst + s->linesize[index]*(h-1);
+                for (i=0; i<h/2; i++) {
+                    for (j=0; j<w; j++)
+                        FFSWAP(int, dst[j], dst2[j]);
+                    dst  += s->linesize[index];
+                    dst2 -= s->linesize[index];
+                }
+            }
+        }
+    }
+
+    av_log(avctx, AV_LOG_DEBUG, "decode frame unused %td bytes\n",
            buf_end - buf_ptr);
 //  return buf_end - buf_ptr;
     return buf_ptr - buf;
@@ -1644,6 +1832,7 @@
     return 0;
 }
 
+#if CONFIG_MJPEG_DECODER
 #define OFFSET(x) offsetof(MJpegDecodeContext, x)
 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
 static const AVOption options[] = {
@@ -1668,10 +1857,12 @@
     .close          = ff_mjpeg_decode_end,
     .decode         = ff_mjpeg_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
+    .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"),
     .priv_class     = &mjpegdec_class,
 };
-
+#endif
+#if CONFIG_THP_DECODER
 AVCodec ff_thp_decoder = {
     .name           = "thp",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -1681,5 +1872,7 @@
     .close          = ff_mjpeg_decode_end,
     .decode         = ff_mjpeg_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
+    .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("Nintendo Gamecube THP video"),
 };
+#endif
diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h
index bfa987d..f35f20a 100644
--- a/libavcodec/mjpegdec.h
+++ b/libavcodec/mjpegdec.h
@@ -4,20 +4,20 @@
  * Copyright (c) 2003 Alex Beregszaszi
  * Copyright (c) 2003-2004 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -58,6 +58,9 @@
     int ls;
     int progressive;
     int rgb;
+    int upscale_h;
+    int chroma_height;
+    int upscale_v;
     int rct;            /* standard rct */
     int pegasus_rct;    /* pegasus reversible colorspace transform */
     int bits;           /* bits per component */
@@ -65,7 +68,7 @@
     int maxval;
     int near;         ///< near lossless bound (si 0 for lossless)
     int t1,t2,t3;
-    int reset;        ///< context halfing intervall ?rename
+    int reset;        ///< context halfing interval ?rename
 
     int width, height;
     int mb_width, mb_height;
diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 64e6f25..1d7741b 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -8,20 +8,20 @@
  * aspecting, new decode_frame mechanism and apple mjpeg-b support
  *                                  by Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,9 +30,6 @@
  * MJPEG encoder.
  */
 
-//#define DEBUG
-#include <assert.h>
-
 #include "avcodec.h"
 #include "dsputil.h"
 #include "mpegvideo.h"
@@ -48,6 +45,11 @@
 {
     MJpegContext *m;
 
+    if (s->width > 65500 || s->height > 65500) {
+        av_log(s, AV_LOG_ERROR, "JPEG does not support resolutions above 65500x65500\n");
+        return -1;
+    }
+
     m = av_malloc(sizeof(MJpegContext));
     if (!m)
         return -1;
@@ -132,6 +134,12 @@
     }
 #endif
 
+    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);
+    }
+
     /* huffman table */
     put_marker(p, DHT);
     flush_put_bits(p);
@@ -156,13 +164,13 @@
     int size;
     uint8_t *ptr;
 
-    if (s->aspect_ratio_info /* && !lossless */)
+    if (s->avctx->sample_aspect_ratio.num /* && !lossless */)
     {
     /* JFIF header */
     put_marker(p, APP0);
     put_bits(p, 16, 16);
     avpriv_put_string(p, "JFIF", 1); /* this puts the trailing zero-byte too */
-    put_bits(p, 16, 0x0201); /* v 1.02 */
+    put_bits(p, 16, 0x0102); /* v 1.02 */
     put_bits(p, 8, 0); /* units type: 0 - aspect ratio */
     put_bits(p, 16, s->avctx->sample_aspect_ratio.num);
     put_bits(p, 16, s->avctx->sample_aspect_ratio.den);
@@ -197,9 +205,13 @@
 void ff_mjpeg_encode_picture_header(MpegEncContext *s)
 {
     const int lossless= s->avctx->codec_id != AV_CODEC_ID_MJPEG;
+    int i;
 
     put_marker(&s->pb, SOI);
 
+    // hack for AMV mjpeg format
+    if(s->avctx->codec_id == AV_CODEC_ID_AMV) goto end;
+
     jpeg_put_comments(s);
 
     jpeg_table_header(s);
@@ -207,11 +219,13 @@
     switch(s->avctx->codec_id){
     case AV_CODEC_ID_MJPEG:  put_marker(&s->pb, SOF0 ); break;
     case AV_CODEC_ID_LJPEG:  put_marker(&s->pb, SOF3 ); break;
-    default: assert(0);
+    default: av_assert0(0);
     }
 
     put_bits(&s->pb, 16, 17);
-    if(lossless && s->avctx->pix_fmt == AV_PIX_FMT_BGRA)
+    if(lossless && (s->avctx->pix_fmt == AV_PIX_FMT_BGR0
+                    || s->avctx->pix_fmt == AV_PIX_FMT_BGRA
+                    || s->avctx->pix_fmt == AV_PIX_FMT_BGR24))
         put_bits(&s->pb, 8, 9); /* 9 bits/component RCT */
     else
         put_bits(&s->pb, 8, 8); /* 8 bits/component */
@@ -270,10 +284,15 @@
     switch(s->avctx->codec_id){
     case AV_CODEC_ID_MJPEG:  put_bits(&s->pb, 8, 63); break; /* Se (not used) */
     case AV_CODEC_ID_LJPEG:  put_bits(&s->pb, 8,  0); break; /* not used */
-    default: assert(0);
+    default: av_assert0(0);
     }
 
     put_bits(&s->pb, 8, 0); /* Ah/Al (not used) */
+
+end:
+    s->esc_pos = put_bits_count(&s->pb) >> 3;
+    for(i=1; i<s->slice_context_count; i++)
+        s->thread_context[i]->esc_pos = 0;
 }
 
 static void escape_FF(MpegEncContext *s, int start)
@@ -283,7 +302,7 @@
     uint8_t *buf= s->pb.buf + start;
     int align= (-(size_t)(buf))&3;
 
-    assert((size&7) == 0);
+    av_assert1((size&7) == 0);
     size >>= 3;
 
     ff_count=0;
@@ -328,21 +347,30 @@
     }
 }
 
-void ff_mjpeg_encode_stuffing(PutBitContext * pbc)
+void ff_mjpeg_encode_stuffing(MpegEncContext *s)
 {
-    int length;
+    int length, i;
+    PutBitContext *pbc = &s->pb;
+    int mb_y = s->mb_y - !s->mb_x;
     length= (-put_bits_count(pbc))&7;
     if(length) put_bits(pbc, length, (1<<length)-1);
+
+    flush_put_bits(&s->pb);
+    escape_FF(s, s->esc_pos);
+
+    if((s->avctx->active_thread_type & FF_THREAD_SLICE) && mb_y < s->mb_height)
+        put_marker(pbc, RST0 + (mb_y&7));
+    s->esc_pos = put_bits_count(pbc) >> 3;
+
+    for(i=0; i<3; i++)
+        s->last_dc[i] = 128 << s->intra_dc_precision;
 }
 
 void ff_mjpeg_encode_picture_trailer(MpegEncContext *s)
 {
-    ff_mjpeg_encode_stuffing(&s->pb);
-    flush_put_bits(&s->pb);
 
-    assert((s->header_bits&7)==0);
+    av_assert1((s->header_bits&7)==0);
 
-    escape_FF(s, s->header_bits>>3);
 
     put_marker(&s->pb, EOI);
 }
@@ -444,6 +472,29 @@
     s->i_tex_bits += get_bits_diff(s);
 }
 
+// maximum over s->mjpeg_vsample[i]
+#define V_MAX 2
+static int amv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
+                              const AVFrame *pic_arg, int *got_packet)
+
+{
+    MpegEncContext *s = avctx->priv_data;
+    AVFrame pic = *pic_arg;
+    int i;
+
+    //CODEC_FLAG_EMU_EDGE have to be cleared
+    if(s->avctx->flags & CODEC_FLAG_EMU_EDGE)
+        return -1;
+
+    //picture should be flipped upside-down
+    for(i=0; i < 3; i++) {
+        pic.data[i] += (pic.linesize[i] * (s->mjpeg_vsample[i] * (8 * s->mb_height -((s->height/V_MAX)&7)) - 1 ));
+        pic.linesize[i] *= -1;
+    }
+    return ff_MPV_encode_picture(avctx, pkt, &pic, got_packet);
+}
+
+#if CONFIG_MJPEG_ENCODER
 AVCodec ff_mjpeg_encoder = {
     .name           = "mjpeg",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -452,8 +503,25 @@
     .init           = ff_MPV_encode_init,
     .encode2        = ff_MPV_encode_picture,
     .close          = ff_MPV_encode_end,
+    .capabilities   = CODEC_CAP_SLICE_THREADS | CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
     .pix_fmts       = (const enum AVPixelFormat[]){
         AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_NONE
     },
     .long_name      = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"),
 };
+#endif
+#if CONFIG_AMV_ENCODER
+AVCodec ff_amv_encoder = {
+    .name           = "amv",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_AMV,
+    .priv_data_size = sizeof(MpegEncContext),
+    .init           = ff_MPV_encode_init,
+    .encode2        = amv_encode_picture,
+    .close          = ff_MPV_encode_end,
+    .pix_fmts       = (const enum AVPixelFormat[]){
+        AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_NONE
+    },
+    .long_name      = NULL_IF_CONFIG_SMALL("AMV Video"),
+};
+#endif
diff --git a/libavcodec/mjpegenc.h b/libavcodec/mjpegenc.h
index 12ff540..06f77c6 100644
--- a/libavcodec/mjpegenc.h
+++ b/libavcodec/mjpegenc.h
@@ -8,20 +8,20 @@
  * aspecting, new decode_frame mechanism and apple mjpeg-b support
  *                                  by Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -52,7 +52,7 @@
 void ff_mjpeg_encode_close(MpegEncContext *s);
 void ff_mjpeg_encode_picture_header(MpegEncContext *s);
 void ff_mjpeg_encode_picture_trailer(MpegEncContext *s);
-void ff_mjpeg_encode_stuffing(PutBitContext *pbc);
+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]);
diff --git a/libavcodec/mlp.c b/libavcodec/mlp.c
index 9615b66..87f7c77 100644
--- a/libavcodec/mlp.c
+++ b/libavcodec/mlp.c
@@ -2,20 +2,20 @@
  * MLP codec common code
  * Copyright (c) 2007-2008 Ian Caulfield
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mlp.h b/libavcodec/mlp.h
index d771112..d8d1292 100644
--- a/libavcodec/mlp.h
+++ b/libavcodec/mlp.h
@@ -2,20 +2,20 @@
  * MLP codec common header file
  * Copyright (c) 2007-2008 Ian Caulfield
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mlp_parser.c b/libavcodec/mlp_parser.c
index 4c1cf9b..5fb1424 100644
--- a/libavcodec/mlp_parser.c
+++ b/libavcodec/mlp_parser.c
@@ -2,20 +2,20 @@
  * MLP parser
  * Copyright (c) 2007 Ian Caulfield
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -43,28 +43,28 @@
     5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 };
 
-static const uint64_t mlp_layout[32] = {
+const uint64_t ff_mlp_layout[32] = {
     AV_CH_LAYOUT_MONO,
     AV_CH_LAYOUT_STEREO,
     AV_CH_LAYOUT_2_1,
-    AV_CH_LAYOUT_2_2,
+    AV_CH_LAYOUT_QUAD,
     AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY,
     AV_CH_LAYOUT_2_1|AV_CH_LOW_FREQUENCY,
-    AV_CH_LAYOUT_2_2|AV_CH_LOW_FREQUENCY,
+    AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY,
     AV_CH_LAYOUT_SURROUND,
     AV_CH_LAYOUT_4POINT0,
-    AV_CH_LAYOUT_5POINT0,
+    AV_CH_LAYOUT_5POINT0_BACK,
     AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY,
     AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY,
-    AV_CH_LAYOUT_5POINT1,
+    AV_CH_LAYOUT_5POINT1_BACK,
     AV_CH_LAYOUT_4POINT0,
-    AV_CH_LAYOUT_5POINT0,
+    AV_CH_LAYOUT_5POINT0_BACK,
     AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY,
     AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY,
-    AV_CH_LAYOUT_5POINT1,
-    AV_CH_LAYOUT_2_2|AV_CH_LOW_FREQUENCY,
-    AV_CH_LAYOUT_5POINT0,
-    AV_CH_LAYOUT_5POINT1,
+    AV_CH_LAYOUT_5POINT1_BACK,
+    AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY,
+    AV_CH_LAYOUT_5POINT0_BACK,
+    AV_CH_LAYOUT_5POINT1_BACK,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
@@ -107,7 +107,7 @@
     return channels;
 }
 
-static uint64_t truehd_layout(int chanmap)
+uint64_t ff_truehd_layout(int chanmap)
 {
     int i;
     uint64_t layout = 0;
@@ -129,7 +129,7 @@
     int ratebits;
     uint16_t checksum;
 
-    assert(get_bits_count(gb) == 0);
+    av_assert1(get_bits_count(gb) == 0);
 
     if (gb->size_in_bits < 28 << 3) {
         av_log(log, AV_LOG_ERROR, "packet too short, unable to read major sync\n");
@@ -264,6 +264,9 @@
         mp->bytes_left = ((mp->pc.index > 0 ? mp->pc.buffer[0] : buf[0]) << 8)
                        |  (mp->pc.index > 1 ? mp->pc.buffer[1] : buf[1-mp->pc.index]);
         mp->bytes_left = (mp->bytes_left & 0xfff) * 2;
+        if (mp->bytes_left <= 0) { // prevent infinite loop
+            goto lost_sync;
+        }
         mp->bytes_left -= mp->pc.index;
     }
 
@@ -314,20 +317,22 @@
         avctx->sample_rate = mh.group1_samplerate;
         s->duration = mh.access_unit_size;
 
+        if(!avctx->channels || !avctx->channel_layout) {
         if (mh.stream_type == 0xbb) {
             /* MLP stream */
             avctx->channels = mlp_channels[mh.channels_mlp];
-            avctx->channel_layout = mlp_layout[mh.channels_mlp];
+            avctx->channel_layout = ff_mlp_layout[mh.channels_mlp];
         } else { /* mh.stream_type == 0xba */
             /* TrueHD stream */
             if (mh.channels_thd_stream2) {
                 avctx->channels = truehd_channels(mh.channels_thd_stream2);
-                avctx->channel_layout = truehd_layout(mh.channels_thd_stream2);
+                avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream2);
             } else {
                 avctx->channels = truehd_channels(mh.channels_thd_stream1);
-                avctx->channel_layout = truehd_layout(mh.channels_thd_stream1);
+                avctx->channel_layout = ff_truehd_layout(mh.channels_thd_stream1);
             }
         }
+        }
 
         if (!mh.is_vbr) /* Stream is CBR */
             avctx->bit_rate = mh.peak_bitrate;
diff --git a/libavcodec/mlp_parser.h b/libavcodec/mlp_parser.h
index 35bb312..6aafed5 100644
--- a/libavcodec/mlp_parser.h
+++ b/libavcodec/mlp_parser.h
@@ -2,20 +2,20 @@
  * MLP parser prototypes
  * Copyright (c) 2007 Ian Caulfield
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -54,5 +54,8 @@
 
 
 int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb);
+uint64_t ff_truehd_layout(int chanmap);
+
+extern const uint64_t ff_mlp_layout[32];
 
 #endif /* AVCODEC_MLP_PARSER_H */
diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c
index cae5136..d587982 100644
--- a/libavcodec/mlpdec.c
+++ b/libavcodec/mlpdec.c
@@ -2,20 +2,20 @@
  * MLP decoder
  * Copyright (c) 2007-2008 Ian Caulfield
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -128,6 +128,9 @@
     /// Index of the last substream to decode - further substreams are skipped.
     uint8_t     max_decoded_substream;
 
+    /// Stream needs channel reordering to comply with FFmpeg's channel order
+    uint8_t     needs_reordering;
+
     /// number of PCM samples contained in each frame
     int         access_unit_size;
     /// next power of two above the number of samples in each frame
@@ -324,6 +327,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) {
+            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;
+
     return 0;
 }
 
@@ -343,6 +372,7 @@
     const int max_matrix_channel = m->avctx->codec_id == AV_CODEC_ID_MLP
                                  ? MAX_MATRIX_CHANNEL_MLP
                                  : MAX_MATRIX_CHANNEL_TRUEHD;
+    int max_channel, min_channel, matrix_channel;
 
     sync_word = get_bits(gbp, 13);
 
@@ -361,18 +391,18 @@
 
     skip_bits(gbp, 16); /* Output timestamp */
 
-    s->min_channel        = get_bits(gbp, 4);
-    s->max_channel        = get_bits(gbp, 4);
-    s->max_matrix_channel = get_bits(gbp, 4);
+    min_channel    = get_bits(gbp, 4);
+    max_channel    = get_bits(gbp, 4);
+    matrix_channel = get_bits(gbp, 4);
 
-    if (s->max_matrix_channel > max_matrix_channel) {
+    if (matrix_channel > max_matrix_channel) {
         av_log(m->avctx, AV_LOG_ERROR,
                "Max matrix channel cannot be greater than %d.\n",
                max_matrix_channel);
         return AVERROR_INVALIDDATA;
     }
 
-    if (s->max_channel != s->max_matrix_channel) {
+    if (max_channel != matrix_channel) {
         av_log(m->avctx, AV_LOG_ERROR,
                "Max channel must be equal max matrix channel.\n");
         return AVERROR_INVALIDDATA;
@@ -380,19 +410,23 @@
 
     /* This should happen for TrueHD streams with >6 channels and MLP's noise
      * type. It is not yet known if this is allowed. */
-    if (s->max_channel > MAX_MATRIX_CHANNEL_MLP && !s->noise_type) {
+    if (max_channel > MAX_MATRIX_CHANNEL_MLP && !s->noise_type) {
         av_log_ask_for_sample(m->avctx,
                "Number of channels %d is larger than the maximum supported "
-               "by the decoder.\n", s->max_channel + 2);
+               "by the decoder.\n", max_channel + 2);
         return AVERROR_PATCHWELCOME;
     }
 
-    if (s->min_channel > s->max_channel) {
+    if (min_channel > max_channel) {
         av_log(m->avctx, AV_LOG_ERROR,
                "Substream min channel cannot be greater than max channel.\n");
         return AVERROR_INVALIDDATA;
     }
 
+    s->min_channel = min_channel;
+    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) {
@@ -434,6 +468,33 @@
         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))
@@ -481,7 +542,7 @@
     int i, order;
 
     // Filter is 0 for FIR, 1 for IIR.
-    assert(filter < 2);
+    av_assert0(filter < 2);
 
     if (m->filter_changed[channel][filter]++ > 1) {
         av_log(m->avctx, AV_LOG_ERROR, "Filters may change only once per access unit.\n");
@@ -681,7 +742,7 @@
         if (get_bits1(gbp)) {
             s->blocksize = get_bits(gbp, 9);
             if (s->blocksize < 8 || s->blocksize > m->access_unit_size) {
-                av_log(m->avctx, AV_LOG_ERROR, "Invalid blocksize.");
+                av_log(m->avctx, AV_LOG_ERROR, "Invalid blocksize.\n");
                 s->blocksize = 0;
                 return AVERROR_INVALIDDATA;
             }
@@ -1144,6 +1205,7 @@
     return AVERROR_INVALIDDATA;
 }
 
+#if CONFIG_MLP_DECODER
 AVCodec ff_mlp_decoder = {
     .name           = "mlp",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -1154,7 +1216,7 @@
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("MLP (Meridian Lossless Packing)"),
 };
-
+#endif
 #if CONFIG_TRUEHD_DECODER
 AVCodec ff_truehd_decoder = {
     .name           = "truehd",
diff --git a/libavcodec/mlpdsp.c b/libavcodec/mlpdsp.c
index 2944ce8..9a376e2 100644
--- a/libavcodec/mlpdsp.c
+++ b/libavcodec/mlpdsp.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2007-2008 Ian Caulfield
  *               2009 Ramiro Polla
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mlpdsp.h b/libavcodec/mlpdsp.h
index 995f72a..84a8aa3 100644
--- a/libavcodec/mlpdsp.h
+++ b/libavcodec/mlpdsp.h
@@ -2,20 +2,20 @@
  * MLP codec common header file
  * Copyright (c) 2007-2008 Ian Caulfield
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c
index 9959d5f..28975e8 100644
--- a/libavcodec/mmvideo.c
+++ b/libavcodec/mmvideo.c
@@ -2,20 +2,20 @@
  * American Laser Games MM Video Decoder
  * Copyright (c) 2006,2008 Peter Ross
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -60,7 +60,8 @@
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
-    s->frame.reference = 1;
+    avcodec_get_frame_defaults(&s->frame);
+    s->frame.reference = 3;
 
     return 0;
 }
@@ -71,7 +72,7 @@
 
     bytestream2_skip(&s->gb, 4);
     for (i = 0; i < 128; i++) {
-        s->palette[i] = bytestream2_get_be24(&s->gb);
+        s->palette[i] = 0xFF << 24 | bytestream2_get_be24(&s->gb);
         s->palette[i+128] = s->palette[i]<<2;
     }
 
@@ -125,7 +126,7 @@
  */
 static int mm_decode_inter(MmContext * s, int half_horiz, int half_vert)
 {
-    int data_off = bytestream2_get_le16(&s->gb), y;
+    int data_off = bytestream2_get_le16(&s->gb), y = 0;
     GetByteContext data_ptr;
 
     if (bytestream2_get_bytes_left(&s->gb) < data_off)
@@ -187,13 +188,13 @@
     buf_size -= MM_PREAMBLE_SIZE;
     bytestream2_init(&s->gb, buf, buf_size);
 
-    if (avctx->reget_buffer(avctx, &s->frame) < 0) {
+    if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
-        return -1;
+        return res;
     }
 
     switch(type) {
-    case MM_TYPE_PALETTE   : res = mm_decode_pal(s); return buf_size;
+    case MM_TYPE_PALETTE   : res = mm_decode_pal(s); return avpkt->size;
     case MM_TYPE_INTRA     : res = mm_decode_intra(s, 0, 0); break;
     case MM_TYPE_INTRA_HH  : res = mm_decode_intra(s, 1, 0); break;
     case MM_TYPE_INTRA_HHV : res = mm_decode_intra(s, 1, 1); break;
@@ -212,7 +213,7 @@
     *data_size = sizeof(AVFrame);
     *(AVFrame*)data = s->frame;
 
-    return buf_size;
+    return avpkt->size;
 }
 
 static av_cold int mm_decode_end(AVCodecContext *avctx)
diff --git a/libavcodec/motion-test.c b/libavcodec/motion-test.c
new file mode 100644
index 0000000..2cdb1c0
--- /dev/null
+++ b/libavcodec/motion-test.c
@@ -0,0 +1,151 @@
+/*
+ * (c) 2001 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * motion test.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "config.h"
+#include "dsputil.h"
+#include "libavutil/internal.h"
+#include "libavutil/lfg.h"
+#include "libavutil/mem.h"
+#include "libavutil/time.h"
+
+#undef printf
+
+#define WIDTH 64
+#define HEIGHT 64
+
+static uint8_t img1[WIDTH * HEIGHT];
+static uint8_t img2[WIDTH * HEIGHT];
+
+static void fill_random(uint8_t *tab, int size)
+{
+    int i;
+    AVLFG prng;
+
+    av_lfg_init(&prng, 1);
+    for(i=0;i<size;i++) {
+        tab[i] = av_lfg_get(&prng) % 256;
+    }
+}
+
+static void help(void)
+{
+    printf("motion-test [-h]\n"
+           "test motion implementations\n");
+}
+
+#define NB_ITS 500
+
+int dummy;
+
+static void test_motion(const char *name,
+                 me_cmp_func test_func, me_cmp_func ref_func)
+{
+    int x, y, d1, d2, it;
+    uint8_t *ptr;
+    int64_t ti;
+    printf("testing '%s'\n", name);
+
+    /* test correctness */
+    for(it=0;it<20;it++) {
+
+        fill_random(img1, WIDTH * HEIGHT);
+        fill_random(img2, WIDTH * HEIGHT);
+
+        for(y=0;y<HEIGHT-17;y++) {
+            for(x=0;x<WIDTH-17;x++) {
+                ptr = img2 + y * WIDTH + x;
+                d1 = test_func(NULL, img1, ptr, WIDTH, 8);
+                d2 = ref_func(NULL, img1, ptr, WIDTH, 8);
+                if (d1 != d2) {
+                    printf("error: mmx=%d c=%d\n", d1, d2);
+                }
+            }
+        }
+    }
+    emms_c();
+
+    /* speed test */
+    ti = av_gettime();
+    d1 = 0;
+    for(it=0;it<NB_ITS;it++) {
+        for(y=0;y<HEIGHT-17;y++) {
+            for(x=0;x<WIDTH-17;x++) {
+                ptr = img2 + y * WIDTH + x;
+                d1 += test_func(NULL, img1, ptr, WIDTH, 8);
+            }
+        }
+    }
+    emms_c();
+    dummy = d1; /* avoid optimization */
+    ti = av_gettime() - ti;
+
+    printf("  %0.0f kop/s\n",
+           (double)NB_ITS * (WIDTH - 16) * (HEIGHT - 16) /
+           (double)(ti / 1000.0));
+}
+
+
+int main(int argc, char **argv)
+{
+    AVCodecContext *ctx;
+    int c;
+    DSPContext cctx, mmxctx;
+    int flags[2] = { AV_CPU_FLAG_MMX, AV_CPU_FLAG_MMXEXT };
+    int flags_size = HAVE_MMXEXT ? 2 : 1;
+
+    if (argc > 1) {
+        help();
+        return 1;
+    }
+
+    printf("ffmpeg motion test\n");
+
+    ctx = avcodec_alloc_context3(NULL);
+    ctx->dsp_mask = AV_CPU_FLAG_FORCE;
+    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];
+        memset(&mmxctx, 0, sizeof(mmxctx));
+        ff_dsputil_init(&mmxctx, ctx);
+
+        for (x = 0; x < 2; x++) {
+            printf("%s for %dx%d pixels\n", c ? "mmx2" : "mmx",
+                   x ? 8 : 16, x ? 8 : 16);
+            test_motion("mmx",     mmxctx.pix_abs[x][0], cctx.pix_abs[x][0]);
+            test_motion("mmx_x2",  mmxctx.pix_abs[x][1], cctx.pix_abs[x][1]);
+            test_motion("mmx_y2",  mmxctx.pix_abs[x][2], cctx.pix_abs[x][2]);
+            test_motion("mmx_xy2", mmxctx.pix_abs[x][3], cctx.pix_abs[x][3]);
+        }
+    }
+    av_free(ctx);
+
+    return 0;
+}
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index 3577ada..4d08a14 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -5,20 +5,20 @@
  *
  * new motion estimation (X1/EPZS) by Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -155,14 +155,14 @@
                     c->qpel_avg[1][bxy](c->temp     + 8*stride, ref[8] + (bx>>2) + (by>>2)*stride     + 8*stride, stride);
                     c->qpel_avg[1][bxy](c->temp + 8 + 8*stride, ref[8] + (bx>>2) + (by>>2)*stride + 8 + 8*stride, stride);
                 }else{
-                    assert((fx>>1) + 16*s->mb_x >= -16);
-                    assert((fy>>1) + 16*s->mb_y >= -16);
-                    assert((fx>>1) + 16*s->mb_x <= s->width);
-                    assert((fy>>1) + 16*s->mb_y <= s->height);
-                    assert((bx>>1) + 16*s->mb_x >= -16);
-                    assert((by>>1) + 16*s->mb_y >= -16);
-                    assert((bx>>1) + 16*s->mb_x <= s->width);
-                    assert((by>>1) + 16*s->mb_y <= s->height);
+                    av_assert2((fx>>1) + 16*s->mb_x >= -16);
+                    av_assert2((fy>>1) + 16*s->mb_y >= -16);
+                    av_assert2((fx>>1) + 16*s->mb_x <= s->width);
+                    av_assert2((fy>>1) + 16*s->mb_y <= s->height);
+                    av_assert2((bx>>1) + 16*s->mb_x >= -16);
+                    av_assert2((by>>1) + 16*s->mb_y >= -16);
+                    av_assert2((bx>>1) + 16*s->mb_x <= s->width);
+                    av_assert2((by>>1) + 16*s->mb_y <= s->height);
 
                     c->hpel_put[0][fxy](c->temp, ref[0] + (fx>>1) + (fy>>1)*stride, stride, 16);
                     c->hpel_avg[0][bxy](c->temp, ref[8] + (bx>>1) + (by>>1)*stride, stride, 16);
@@ -298,7 +298,7 @@
     int cache_size= FFMIN(ME_MAP_SIZE>>ME_MAP_SHIFT, 1<<ME_MAP_SHIFT);
     int dia_size= FFMAX(FFABS(s->avctx->dia_size)&255, FFABS(s->avctx->pre_dia_size)&255);
 
-    if(FFMIN(s->avctx->dia_size, s->avctx->pre_dia_size) < -ME_MAP_SIZE){
+    if(FFMIN(s->avctx->dia_size, s->avctx->pre_dia_size) < -FFMIN(ME_MAP_SIZE, MAX_SAB_SIZE)){
         av_log(s->avctx, AV_LOG_ERROR, "ME_MAP size is too small for SAB diamond\n");
         return -1;
     }
@@ -523,8 +523,8 @@
     if (s->unrestricted_mv) {
         c->xmin = - x - 16;
         c->ymin = - y - 16;
-        c->xmax = - x + s->mb_width *16;
-        c->ymax = - y + s->mb_height*16;
+        c->xmax = - x + s->width;
+        c->ymax = - y + s->height;
     } else if (s->out_format == FMT_H261){
         // Search range of H261 is different from other codec standards
         c->xmin = (x > 15) ? - 15 : 0;
@@ -563,10 +563,11 @@
     const int h=8;
     int block;
     int P[10][2];
-    int dmin_sum=0, mx4_sum=0, my4_sum=0;
+    int dmin_sum=0, mx4_sum=0, my4_sum=0, i;
     int same=1;
     const int stride= c->stride;
     uint8_t *mv_penalty= c->current_mv_penalty;
+    int saftey_cliping= s->unrestricted_mv && (s->width&15) && (s->height&15);
 
     init_mv4_ref(c);
 
@@ -578,6 +579,11 @@
         const int mot_stride = s->b8_stride;
         const int mot_xy = s->block_index[block];
 
+        if(saftey_cliping){
+            c->xmax = - 16*s->mb_x + s->width  - 8*(block &1);
+            c->ymax = - 16*s->mb_y + s->height - 8*(block>>1);
+        }
+
         P_LEFT[0] = s->current_picture.f.motion_val[0][mot_xy - 1][0];
         P_LEFT[1] = s->current_picture.f.motion_val[0][mot_xy - 1][1];
 
@@ -605,6 +611,11 @@
         }
         P_MV1[0]= mx;
         P_MV1[1]= my;
+        if(saftey_cliping)
+            for(i=0; i<10; i++){
+                if(P[i][0] > (c->xmax<<shift)) P[i][0]= (c->xmax<<shift);
+                if(P[i][1] > (c->ymax<<shift)) P[i][1]= (c->ymax<<shift);
+            }
 
         dmin4 = epzs_motion_search4(s, &mx4, &my4, P, block, block, s->p_mv_table, (1<<16)>>shift);
 
@@ -736,8 +747,8 @@
             int16_t (*mv_table)[2]= mv_tables[block][field_select];
 
             if(user_field_select){
-                assert(field_select==0 || field_select==1);
-                assert(field_select_tables[block][xy]==0 || field_select_tables[block][xy]==1);
+                av_assert1(field_select==0 || field_select==1);
+                av_assert1(field_select_tables[block][xy]==0 || field_select_tables[block][xy]==1);
                 if(field_select_tables[block][xy] != field_select)
                     continue;
             }
@@ -855,7 +866,7 @@
         av_log(c->avctx, AV_LOG_ERROR, "backward motion vector in P frame\n");
         return INT_MAX/2;
     }
-    assert(IS_INTRA(mb_type) || USES_LIST(mb_type,0) || USES_LIST(mb_type,1));
+    av_assert0(IS_INTRA(mb_type) || USES_LIST(mb_type,0) || USES_LIST(mb_type,1));
 
     for(i=0; i<4; i++){
         int xy= s->block_index[i];
@@ -877,8 +888,8 @@
         if(USES_LIST(mb_type, 0)){
             int field_select0= p->f.ref_index[0][4*mb_xy  ];
             int field_select1= p->f.ref_index[0][4*mb_xy+2];
-            assert(field_select0==0 ||field_select0==1);
-            assert(field_select1==0 ||field_select1==1);
+            av_assert0(field_select0==0 ||field_select0==1);
+            av_assert0(field_select1==0 ||field_select1==1);
             init_interlaced_ref(s, 0);
 
             if(p_type){
@@ -905,8 +916,8 @@
         if(USES_LIST(mb_type, 1)){
             int field_select0 = p->f.ref_index[1][4 * mb_xy    ];
             int field_select1 = p->f.ref_index[1][4 * mb_xy + 2];
-            assert(field_select0==0 ||field_select0==1);
-            assert(field_select1==0 ||field_select1==1);
+            av_assert0(field_select0==0 ||field_select0==1);
+            av_assert0(field_select1==0 ||field_select1==1);
             init_interlaced_ref(s, 2);
 
             s->b_field_select_table[1][0][mb_xy]= field_select0;
@@ -988,9 +999,9 @@
 
     init_ref(c, s->new_picture.f.data, s->last_picture.f.data, NULL, 16*mb_x, 16*mb_y, 0);
 
-    assert(s->quarter_sample==0 || s->quarter_sample==1);
-    assert(s->linesize == c->stride);
-    assert(s->uvlinesize == c->uvstride);
+    av_assert0(s->quarter_sample==0 || s->quarter_sample==1);
+    av_assert0(s->linesize == c->stride);
+    av_assert0(s->uvlinesize == c->uvstride);
 
     c->penalty_factor    = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp);
     c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp);
@@ -1204,7 +1215,7 @@
     const int xy= mb_x + mb_y*s->mb_stride;
     init_ref(c, s->new_picture.f.data, s->last_picture.f.data, NULL, 16*mb_x, 16*mb_y, 0);
 
-    assert(s->quarter_sample==0 || s->quarter_sample==1);
+    av_assert0(s->quarter_sample==0 || s->quarter_sample==1);
 
     c->pre_penalty_factor    = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_pre_cmp);
     c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV;
@@ -1847,12 +1858,12 @@
     MotionEstContext * const c= &s->me;
     const int f_code= s->f_code;
     int y, range;
-    assert(s->pict_type==AV_PICTURE_TYPE_P);
+    av_assert0(s->pict_type==AV_PICTURE_TYPE_P);
 
     range = (((s->out_format == FMT_MPEG1 || s->msmpeg4_version) ? 8 : 16) << f_code);
 
-    assert(range <= 16 || !s->msmpeg4_version);
-    assert(range <=256 || !(s->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL));
+    av_assert0(range <= 16 || !s->msmpeg4_version);
+    av_assert0(range <=256 || !(s->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->avctx->strict_std_compliance >= FF_COMPLIANCE_NORMAL));
 
     if(c->avctx->me_range && range > c->avctx->me_range) range= c->avctx->me_range;
 
diff --git a/libavcodec/motion_est_template.c b/libavcodec/motion_est_template.c
index 7228744..07bfc00 100644
--- a/libavcodec/motion_est_template.c
+++ b/libavcodec/motion_est_template.c
@@ -2,20 +2,20 @@
  * Motion estimation
  * Copyright (c) 2002-2004 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -89,19 +89,18 @@
         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
         unsigned key;
         unsigned map_generation= c->map_generation;
-#ifndef NDEBUG
-        uint32_t *map= c->map;
-#endif
         key= ((my-1)<<ME_MAP_MV_BITS) + (mx) + map_generation;
-        assert(map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key);
+        av_assert2(c->map[(index-(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key);
         key= ((my+1)<<ME_MAP_MV_BITS) + (mx) + map_generation;
-        assert(map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key);
+        av_assert2(c->map[(index+(1<<ME_MAP_SHIFT))&(ME_MAP_SIZE-1)] == key);
         key= ((my)<<ME_MAP_MV_BITS) + (mx+1) + map_generation;
-        assert(map[(index+1)&(ME_MAP_SIZE-1)] == key);
+        av_assert2(c->map[(index+1)&(ME_MAP_SIZE-1)] == key);
         key= ((my)<<ME_MAP_MV_BITS) + (mx-1) + map_generation;
-        assert(map[(index-1)&(ME_MAP_SIZE-1)] == key);
+        av_assert2(c->map[(index-1)&(ME_MAP_SIZE-1)] == key);
+#endif
         if(t<=b){
             CHECK_HALF_MV(0, 1, mx  ,my-1)
             if(l<=r){
@@ -141,7 +140,7 @@
             }
             CHECK_HALF_MV(0, 1, mx  , my)
         }
-        assert(bx >= xmin*2 && bx <= xmax*2 && by >= ymin*2 && by <= ymax*2);
+        av_assert2(bx >= xmin*2 && bx <= xmax*2 && by >= ymin*2 && by <= ymax*2);
     }
 
     *mx_ptr = bx;
@@ -180,9 +179,6 @@
     cmp_sub= s->dsp.mb_cmp[size];
     chroma_cmp_sub= s->dsp.mb_cmp[size+1];
 
-//    assert(!c->skip);
-//    assert(c->avctx->me_sub_cmp != c->avctx->mb_cmp);
-
     d= cmp(s, mx>>(qpel+1), my>>(qpel+1), mx&mask, my&mask, size, h, ref_index, src_index, cmp_sub, chroma_cmp_sub, flags);
     //FIXME check cbp before adding penalty for (0,0) vector
     if(add_rate && (mx || my || size>0))
@@ -309,11 +305,11 @@
 
             cxy= 2*tl + (cx + cy)/4 - (cx2 + cy2) - 2*c;
 
-            assert(16*cx2 + 4*cx + 32*c == 32*r);
-            assert(16*cx2 - 4*cx + 32*c == 32*l);
-            assert(16*cy2 + 4*cy + 32*c == 32*b);
-            assert(16*cy2 - 4*cy + 32*c == 32*t);
-            assert(16*cxy + 16*cy2 + 16*cx2 - 4*cy - 4*cx + 32*c == 32*tl);
+            av_assert2(16*cx2 + 4*cx + 32*c == 32*r);
+            av_assert2(16*cx2 - 4*cx + 32*c == 32*l);
+            av_assert2(16*cy2 + 4*cy + 32*c == 32*b);
+            av_assert2(16*cy2 - 4*cy + 32*c == 32*t);
+            av_assert2(16*cxy + 16*cy2 + 16*cx2 - 4*cy - 4*cx + 32*c == 32*tl);
 
             for(ny= -3; ny <= 3; ny++){
                 for(nx= -3; nx <= 3; nx++){
@@ -346,7 +342,7 @@
             CHECK_QUARTER_MV(nx&3, ny&3, nx>>2, ny>>2)
         }
 
-        assert(bx >= xmin*4 && bx <= xmax*4 && by >= ymin*4 && by <= ymax*4);
+        av_assert2(bx >= xmin*4 && bx <= xmax*4 && by >= ymin*4 && by <= ymax*4);
 
         *mx_ptr = bx;
         *my_ptr = by;
@@ -363,10 +359,10 @@
 {\
     const unsigned key = ((y)<<ME_MAP_MV_BITS) + (x) + map_generation;\
     const int index= (((y)<<ME_MAP_SHIFT) + (x))&(ME_MAP_SIZE-1);\
-    assert((x) >= xmin);\
-    assert((x) <= xmax);\
-    assert((y) >= ymin);\
-    assert((y) <= ymax);\
+    av_assert2((x) >= xmin);\
+    av_assert2((x) <= xmax);\
+    av_assert2((y) >= ymin);\
+    av_assert2((y) <= ymax);\
     if(map[index]!=key){\
         d= cmp(s, x, y, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);\
         map[index]= key;\
@@ -888,7 +884,7 @@
 
     map_generation= update_map_generation(c);
 
-    assert(cmpf);
+    av_assert2(cmpf);
     dmin= cmp(s, 0, 0, 0, 0, size, h, ref_index, src_index, cmpf, chroma_cmpf, flags);
     map[0]= map_generation;
     score_map[0]= dmin;
diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c
index a33d8d3..471f63f 100644
--- a/libavcodec/motionpixels.c
+++ b/libavcodec/motionpixels.c
@@ -2,20 +2,20 @@
  * Motion Pixels Video Decoder
  * Copyright (c) 2008 Gregory Montoir (cyx@users.sourceforge.net)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -55,6 +55,11 @@
     int w4 = (avctx->width  + 3) & ~3;
     int h4 = (avctx->height + 3) & ~3;
 
+    if(avctx->extradata_size < 2){
+        av_log(avctx, AV_LOG_ERROR, "extradata too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     motionpixels_tableinit();
     mp->avctx = avctx;
     ff_dsputil_init(&mp->dsp, avctx);
@@ -63,6 +68,7 @@
     mp->vpt = av_mallocz(avctx->height * sizeof(YuvPixel));
     mp->hpt = av_mallocz(h4 * w4 / 16 * sizeof(YuvPixel));
     avctx->pix_fmt = AV_PIX_FMT_RGB555;
+    avcodec_get_frame_defaults(&mp->frame);
     return 0;
 }
 
@@ -246,7 +252,7 @@
     GetBitContext gb;
     int i, count1, count2, sz;
 
-    mp->frame.reference = 1;
+    mp->frame.reference = 3;
     mp->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
     if (avctx->reget_buffer(avctx, &mp->frame)) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
diff --git a/libavcodec/motionpixels_tablegen.c b/libavcodec/motionpixels_tablegen.c
index ad8e0d9..31e5cdf 100644
--- a/libavcodec/motionpixels_tablegen.c
+++ b/libavcodec/motionpixels_tablegen.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/motionpixels_tablegen.h b/libavcodec/motionpixels_tablegen.h
index cbf56c8..b9802e5 100644
--- a/libavcodec/motionpixels_tablegen.h
+++ b/libavcodec/motionpixels_tablegen.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,7 +30,7 @@
 } YuvPixel;
 
 static int mp_yuv_to_rgb(int y, int v, int u, int clip_rgb) {
-    static const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
+    const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
     int r, g, b;
 
     r = (1000 * y + 701 * v) / 1000;
diff --git a/libavcodec/movsub_bsf.c b/libavcodec/movsub_bsf.c
index 506750f..a745190 100644
--- a/libavcodec/movsub_bsf.c
+++ b/libavcodec/movsub_bsf.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Reimar Döffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c
new file mode 100644
index 0000000..a65bbb8
--- /dev/null
+++ b/libavcodec/movtextdec.c
@@ -0,0 +1,116 @@
+/*
+ * 3GPP TS 26.245 Timed Text decoder
+ * Copyright (c) 2012  Philip Langdale <philipl@overt.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 "avcodec.h"
+#include "ass.h"
+#include "libavutil/avstring.h"
+#include "libavutil/common.h"
+#include "libavutil/bprint.h"
+#include "libavutil/intreadwrite.h"
+
+static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end)
+{
+    while (text < text_end) {
+        switch (*text) {
+        case '\r':
+            break;
+        case '\n':
+            av_bprintf(buf, "\\N");
+            break;
+        default:
+            av_bprint_chars(buf, *text, 1);
+            break;
+        }
+        text++;
+    }
+
+    av_bprintf(buf, "\r\n");
+    return 0;
+}
+
+static int mov_text_init(AVCodecContext *avctx) {
+    /*
+     * TODO: Handle the default text style.
+     * NB: Most players ignore styles completely, with the result that
+     * it's very common to find files where the default style is broken
+     * and respecting it results in a worse experience than ignoring it.
+     */
+    return ff_ass_subtitle_header_default(avctx);
+}
+
+static int mov_text_decode_frame(AVCodecContext *avctx,
+                            void *data, int *got_sub_ptr, AVPacket *avpkt)
+{
+    AVSubtitle *sub = data;
+    int ts_start, ts_end;
+    AVBPrint buf;
+    const char *ptr = avpkt->data;
+    const char *end;
+
+    if (!ptr || avpkt->size < 2)
+        return AVERROR_INVALIDDATA;
+
+    /*
+     * A packet of size two with value zero is an empty subtitle
+     * used to mark the end of the previous non-empty subtitle.
+     * We can just drop them here as we have duration information
+     * already. If the value is non-zero, then it's technically a
+     * bad packet.
+     */
+    if (avpkt->size == 2)
+        return AV_RB16(ptr) == 0 ? 0 : AVERROR_INVALIDDATA;
+
+    /*
+     * The first two bytes of the packet are the length of the text string
+     * 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);
+    ptr += 2;
+
+    ts_start = av_rescale_q(avpkt->pts,
+                            avctx->time_base,
+                            (AVRational){1,100});
+    ts_end   = av_rescale_q(avpkt->pts + avpkt->duration,
+                            avctx->time_base,
+                            (AVRational){1,100});
+
+    // Note that the spec recommends lines be no longer than 2048 characters.
+    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
+    text_to_ass(&buf, ptr, end);
+
+    if (!av_bprint_is_complete(&buf))
+        return AVERROR(ENOMEM);
+
+    ff_ass_add_rect(sub, buf.str, ts_start, ts_end-ts_start, 0);
+    *got_sub_ptr = sub->num_rects > 0;
+    av_bprint_finalize(&buf, NULL);
+    return avpkt->size;
+}
+
+AVCodec ff_movtext_decoder = {
+    .name         = "mov_text",
+    .long_name    = NULL_IF_CONFIG_SMALL("3GPP Timed Text subtitle"),
+    .type         = AVMEDIA_TYPE_SUBTITLE,
+    .id           = AV_CODEC_ID_MOV_TEXT,
+    .init         = mov_text_init,
+    .decode       = mov_text_decode_frame,
+};
diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c
new file mode 100644
index 0000000..7f1b5b8
--- /dev/null
+++ b/libavcodec/movtextenc.c
@@ -0,0 +1,161 @@
+/*
+ * 3GPP TS 26.245 Timed Text encoder
+ * Copyright (c) 2012  Philip Langdale <philipl@overt.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 <stdarg.h>
+#include "avcodec.h"
+#include "libavutil/avstring.h"
+#include "libavutil/intreadwrite.h"
+#include "ass_split.h"
+#include "ass.h"
+
+typedef struct {
+    ASSSplitContext *ass_ctx;
+    char buffer[2048];
+    char *ptr;
+    char *end;
+} MovTextContext;
+
+
+static av_cold int mov_text_encode_init(AVCodecContext *avctx)
+{
+    /*
+     * For now, we'll use a fixed default style. When we add styling
+     * support, this will be generated from the ASS style.
+     */
+    static uint8_t text_sample_entry[] = {
+        0x00, 0x00, 0x00, 0x00, // uint32_t displayFlags
+        0x01,                   // int8_t horizontal-justification
+        0xFF,                   // int8_t vertical-justification
+        0x00, 0x00, 0x00, 0x00, // uint8_t background-color-rgba[4]
+        // BoxRecord {
+        0x00, 0x00,             // int16_t top
+        0x00, 0x00,             // int16_t left
+        0x00, 0x00,             // int16_t bottom
+        0x00, 0x00,             // int16_t right
+        // };
+        // StyleRecord {
+        0x00, 0x00,             // uint16_t startChar
+        0x00, 0x00,             // uint16_t endChar
+        0x00, 0x01,             // uint16_t font-ID
+        0x00,                   // uint8_t face-style-flags
+        0x12,                   // uint8_t font-size
+        0xFF, 0xFF, 0xFF, 0xFF, // uint8_t text-color-rgba[4]
+        // };
+        // FontTableBox {
+        0x00, 0x00, 0x00, 0x12, // uint32_t size
+        'f', 't', 'a', 'b',     // uint8_t name[4]
+        0x00, 0x01,             // uint16_t entry-count
+        // FontRecord {
+        0x00, 0x01,             // uint16_t font-ID
+        0x05,                   // uint8_t font-name-length
+        'S', 'e', 'r', 'i', 'f',// uint8_t font[font-name-length]
+        // };
+        // };
+    };
+
+    MovTextContext *s = avctx->priv_data;
+
+    avctx->extradata_size = sizeof text_sample_entry;
+    avctx->extradata = av_mallocz(avctx->extradata_size);
+    if (!avctx->extradata)
+        return AVERROR(ENOMEM);
+
+    memcpy(avctx->extradata, text_sample_entry, avctx->extradata_size);
+
+    s->ass_ctx = ff_ass_split(avctx->subtitle_header);
+    return s->ass_ctx ? 0 : AVERROR_INVALIDDATA;
+}
+
+static void mov_text_text_cb(void *priv, const char *text, int len)
+{
+    MovTextContext *s = priv;
+    av_strlcpy(s->ptr, text, FFMIN(s->end - s->ptr, len + 1));
+    s->ptr += len;
+}
+
+static void mov_text_new_line_cb(void *priv, int forced)
+{
+    MovTextContext *s = priv;
+    av_strlcpy(s->ptr, "\n", FFMIN(s->end - s->ptr, 2));
+    s->ptr++;
+}
+
+static const ASSCodesCallbacks mov_text_callbacks = {
+    .text     = mov_text_text_cb,
+    .new_line = mov_text_new_line_cb,
+};
+
+static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf,
+                                 int bufsize, const AVSubtitle *sub)
+{
+    MovTextContext *s = avctx->priv_data;
+    ASSDialog *dialog;
+    int i, len, num;
+
+    s->ptr = s->buffer;
+    s->end = s->ptr + sizeof(s->buffer);
+
+    for (i = 0; i < sub->num_rects; i++) {
+
+        if (sub->rects[i]->type != SUBTITLE_ASS) {
+            av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n");
+            return AVERROR(ENOSYS);
+        }
+
+        dialog = ff_ass_split_dialog(s->ass_ctx, sub->rects[i]->ass, 0, &num);
+        for (; dialog && num--; dialog++) {
+            ff_ass_split_override_codes(&mov_text_callbacks, s, dialog->text);
+        }
+    }
+
+    if (s->ptr == s->buffer)
+        return 0;
+
+    AV_WB16(buf, strlen(s->buffer));
+    buf += 2;
+
+    len = av_strlcpy(buf, s->buffer, bufsize - 2);
+
+    if (len > bufsize-3) {
+        av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n");
+        return AVERROR(EINVAL);
+    }
+
+    return len + 2;
+}
+
+static int mov_text_encode_close(AVCodecContext *avctx)
+{
+    MovTextContext *s = avctx->priv_data;
+    ff_ass_split_free(s->ass_ctx);
+    return 0;
+}
+
+AVCodec ff_movtext_encoder = {
+    .name           = "mov_text",
+    .long_name      = NULL_IF_CONFIG_SMALL("3GPP Timed Text subtitle"),
+    .type           = AVMEDIA_TYPE_SUBTITLE,
+    .id             = AV_CODEC_ID_MOV_TEXT,
+    .priv_data_size = sizeof(MovTextContext),
+    .init           = mov_text_encode_init,
+    .encode_sub     = mov_text_encode_frame,
+    .close          = mov_text_encode_close,
+};
diff --git a/libavcodec/mp3_header_compress_bsf.c b/libavcodec/mp3_header_compress_bsf.c
index 06a7ebe..3c5e2fb 100644
--- a/libavcodec/mp3_header_compress_bsf.c
+++ b/libavcodec/mp3_header_compress_bsf.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mp3_header_decompress_bsf.c b/libavcodec/mp3_header_decompress_bsf.c
index 8e086a1..adf5a7f 100644
--- a/libavcodec/mp3_header_decompress_bsf.c
+++ b/libavcodec/mp3_header_decompress_bsf.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpc.c b/libavcodec/mpc.c
index 5a54a9b..d064924 100644
--- a/libavcodec/mpc.c
+++ b/libavcodec/mpc.c
@@ -2,20 +2,20 @@
  * Musepack decoder core
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -74,13 +74,13 @@
         for(ch = 0; ch < 2; ch++){
             if(bands[i].res[ch]){
                 j = 0;
-                mul = mpc_CC[bands[i].res[ch] + 1] * mpc_SCF[bands[i].scf_idx[ch][0]+6];
+                mul = (mpc_CC+1)[bands[i].res[ch]] * mpc_SCF[bands[i].scf_idx[ch][0] & 0xFF];
                 for(; j < 12; j++)
                     c->sb_samples[ch][j][i] = mul * c->Q[ch][j + off];
-                mul = mpc_CC[bands[i].res[ch] + 1] * mpc_SCF[bands[i].scf_idx[ch][1]+6];
+                mul = (mpc_CC+1)[bands[i].res[ch]] * mpc_SCF[bands[i].scf_idx[ch][1] & 0xFF];
                 for(; j < 24; j++)
                     c->sb_samples[ch][j][i] = mul * c->Q[ch][j + off];
-                mul = mpc_CC[bands[i].res[ch] + 1] * mpc_SCF[bands[i].scf_idx[ch][2]+6];
+                mul = (mpc_CC+1)[bands[i].res[ch]] * mpc_SCF[bands[i].scf_idx[ch][2] & 0xFF];
                 for(; j < 36; j++)
                     c->sb_samples[ch][j][i] = mul * c->Q[ch][j + off];
             }
diff --git a/libavcodec/mpc.h b/libavcodec/mpc.h
index 86d4b6d..7ee402b 100644
--- a/libavcodec/mpc.h
+++ b/libavcodec/mpc.h
@@ -2,20 +2,20 @@
  * Musepack decoder
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c
index b013eeb..9f3cf6c 100644
--- a/libavcodec/mpc7.c
+++ b/libavcodec/mpc7.c
@@ -2,20 +2,20 @@
  * Musepack SV7 decoder
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -35,10 +35,6 @@
 #include "mpc.h"
 #include "mpc7data.h"
 
-#define BANDS            32
-#define SAMPLES_PER_BAND 36
-#define MPC_FRAME_SIZE   (BANDS * SAMPLES_PER_BAND)
-
 static VLC scfi_vlc, dscf_vlc, hdr_vlc, quant_vlc[MPC7_QUANT_VLC_TABLES][2];
 
 static const uint16_t quant_offsets[MPC7_QUANT_VLC_TABLES*2 + 1] =
@@ -97,6 +93,9 @@
     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;
@@ -137,9 +136,6 @@
     }
     vlc_initialized = 1;
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
@@ -193,7 +189,7 @@
     int t = get_vlc2(gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7;
     if (t == 8)
         return get_bits(gb, 6);
-    return av_clip_uintp2(ref + t, 7);
+    return ref + t;
 }
 
 static int mpc7_decode_frame(AVCodecContext * avctx, void *data,
@@ -228,7 +224,7 @@
     buf_size  -= 4;
 
     /* get output buffer */
-    c->frame.nb_samples = last_frame ? c->lastframelen : MPC_FRAME_SIZE;
+    c->frame.nb_samples = MPC_FRAME_SIZE;
     if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
@@ -247,7 +243,11 @@
             int t = 4;
             if(i) t = get_vlc2(&gb, hdr_vlc.table, MPC7_HDR_BITS, 1) - 5;
             if(t == 4) bands[i].res[ch] = get_bits(&gb, 4);
-            else bands[i].res[ch] = av_clip(bands[i-1].res[ch] + t, 0, 17);
+            else bands[i].res[ch] = bands[i-1].res[ch] + t;
+            if (bands[i].res[ch] < -1 || bands[i].res[ch] > 17) {
+                av_log(avctx, AV_LOG_ERROR, "subband index invalid\n");
+                return AVERROR_INVALIDDATA;
+            }
         }
 
         if(bands[i].res[0] || bands[i].res[1]){
@@ -294,6 +294,8 @@
             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);
+    if(last_frame)
+        c->frame.nb_samples = c->lastframelen;
 
     bits_used = get_bits_count(&gb);
     bits_avail = buf_size * 8;
diff --git a/libavcodec/mpc7data.h b/libavcodec/mpc7data.h
index f205ffe..5609e8f 100644
--- a/libavcodec/mpc7data.h
+++ b/libavcodec/mpc7data.h
@@ -2,20 +2,20 @@
  * Musepack decoder
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c
index 91e228b..64d1919 100644
--- a/libavcodec/mpc8.c
+++ b/libavcodec/mpc8.c
@@ -2,20 +2,20 @@
  * Musepack SV8 decoder
  * Copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -127,6 +127,10 @@
 
     skip_bits(&gb, 3);//sample rate
     c->maxbands = get_bits(&gb, 5) + 1;
+    if (c->maxbands >= BANDS) {
+        av_log(avctx,AV_LOG_ERROR, "maxbands %d too high\n", c->maxbands);
+        return AVERROR_INVALIDDATA;
+    }
     channels = get_bits(&gb, 4) + 1;
     if (channels > 2) {
         av_log_missing_feature(avctx, "Multichannel MPC SV8", 1);
@@ -136,7 +140,11 @@
     c->frames = 1 << (get_bits(&gb, 3) * 2);
 
     avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
-    avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
+    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");
@@ -229,9 +237,6 @@
     }
     vlc_initialized = 1;
 
-    avcodec_get_frame_defaults(&c->frame);
-    avctx->coded_frame = &c->frame;
-
     return 0;
 }
 
@@ -270,8 +275,11 @@
         maxband = c->last_max_band + get_vlc2(gb, band_vlc.table, MPC8_BANDS_BITS, 2);
         if(maxband > 32) maxband -= 33;
     }
-    if(maxband > c->maxbands + 1)
+
+    if(maxband > c->maxbands + 1) {
+        av_log(avctx, AV_LOG_ERROR, "maxband %d too large\n",maxband);
         return AVERROR_INVALIDDATA;
+    }
     c->last_max_band = maxband;
 
     /* read subband indexes */
diff --git a/libavcodec/mpc8data.h b/libavcodec/mpc8data.h
index 2940b30..22c2be4 100644
--- a/libavcodec/mpc8data.h
+++ b/libavcodec/mpc8data.h
@@ -2,20 +2,20 @@
  * Musepack SV8 decoder
  * Copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpc8huff.h b/libavcodec/mpc8huff.h
index 6005e21..8491037 100644
--- a/libavcodec/mpc8huff.h
+++ b/libavcodec/mpc8huff.h
@@ -2,20 +2,20 @@
  * Musepack SV8 decoder
  * Copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpcdata.h b/libavcodec/mpcdata.h
index 15724f3..64fb4ab 100644
--- a/libavcodec/mpcdata.h
+++ b/libavcodec/mpcdata.h
@@ -2,20 +2,20 @@
  * Musepack decoder
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,9 +30,7 @@
     4.0002, 2.0001, 1.0000
 };
 
-static const float mpc_SCF[128+6] = {
-    920.016296386718750000, 766.355773925781250000, 638.359558105468750000,
-    531.741149902343750000, 442.930114746093750000, 368.952209472656250000,
+static const float mpc_SCF[256] = {
     307.330047607421875000, 255.999984741210937500, 213.243041992187500000, 177.627334594726562500,
     147.960128784179687500, 123.247924804687500000, 102.663139343261718750, 85.516410827636718750,
     71.233520507812500000, 59.336143493652343750, 49.425861358642578125, 41.170787811279296875,
@@ -64,7 +62,39 @@
     0.000000396931966407, 0.000000330636652279, 0.000000275413924555, 0.000000229414467867,
     0.000000191097811353, 0.000000159180785886, 0.000000132594522029, 0.000000110448674207,
     0.000000092001613439, 0.000000076635565449, 0.000000063835940978, 0.000000053174105119,
-    0.000000044293003043, 0.000000036895215771, 0.000000030733001921, 0.000000025599996789
+    0.000000044293003043, 0.000000036895215771, 0.000000030733001921, 0.000000025599996789,
+    0.000000021324305018, 3689522167600.270019531250000000, 3073300627835.926757812500000000, 2560000000000.002929687500000000,
+    2132430501800.519042968750000000, 1776273376956.721923828125000000, 1479601378343.250244140625000000, 1232479339720.794189453125000000,
+    1026631459710.774291992187500000, 855164155779.391845703125000000, 712335206965.024780273437500000, 593361454233.829101562500000000,
+    494258618594.112609863281250000, 411707872682.763122558593750000, 342944697476.612365722656250000, 285666302081.983886718750000000,
+    237954506209.446411132812500000, 198211502766.368713378906250000, 165106349338.563323974609375000, 137530396629.095306396484375000,
+    114560161209.611633300781250000, 95426399240.062576293945312500, 79488345475.196502685546875000, 66212254855.064872741699218750,
+    55153528064.816276550292968750, 45941822471.611343383789062500, 38268649822.956413269042968750, 31877045369.216873168945312500,
+    26552962442.420688629150390625, 22118104306.789615631103515625, 18423953228.829509735107421875, 15346796808.164905548095703125,
+    12783585007.291271209716796875, 10648479137.463939666748046875, 8869977230.669750213623046875, 7388519530.061036109924316406,
+    6154493909.785535812377929688, 5126574428.270387649536132812, 4270337375.232155323028564453, 3557108465.595236301422119141,
+    2963002574.315670013427734375, 2468123854.056322574615478516, 2055899448.676229715347290039, 1712524489.450022459030151367,
+    1426499787.649837732315063477, 1188246741.404872417449951172, 989786560.561257958412170410, 824473067.192597866058349609,
+    686770123.591610312461853027, 572066234.090648531913757324, 476520111.962911486625671387, 396932039.637152194976806641,
+    330636714.243810534477233887, 275413990.026798009872436523, 229414528.498330980539321899, 191097866.455478429794311523,
+    159180827.835415601730346680, 132594551.788319095969200134, 110448697.892960876226425171, 92001629.793398514389991760,
+    76635578.744844585657119751, 63835955.327594503760337830, 53174116.504741288721561432, 44293010.914454914629459381,
+    36895221.676002673804759979, 30733006.278359245508909225, 25600000.000000011175870895, 21324305.018005173653364182,
+    17762733.769567202776670456, 14796013.783432489261031151, 12324793.397207930684089661, 10266314.597107734531164169,
+    8551641.557793911546468735, 7123352.069650243036448956, 5933614.542338287457823753, 4942586.185941123403608799,
+    4117078.726827629376202822, 3429446.974766122177243233, 2856663.020819837693125010, 2379545.062094463035464287,
+    1982115.027663686312735081, 1651063.493385632522404194, 1375303.966290952404960990, 1145601.612096115713939071,
+    954263.992400625254958868, 794883.454751964658498764, 662122.548550648498348892, 551535.280648162588477135,
+    459418.224716113239992410, 382686.498229563992936164, 318770.453692168579436839, 265529.624424206791445613,
+    221181.043067896069260314, 184239.532288295013131574, 153467.968081648985389620, 127835.850072912653558888,
+    106484.791374639346031472, 88699.772306697457679547, 73885.195300610314006917, 61544.939097855312866159,
+    51265.744282703839417081, 42703.373752321524079889, 35571.084655952341563534, 29630.025743156678800005,
+    24681.238540563208516687, 20558.994486762283486314, 17125.244894500214286381, 14264.997876498367986642,
+    11882.467414048716818797, 9897.865605612574654515, 8244.730671925974093028, 6867.701235916098994494,
+    5720.662340906482313585, 4765.201119629112326948, 3969.320396371519564127, 3306.367142438103201130,
+    2754.139900267978191550, 2294.145284983308101801, 1910.978664554782881169, 1591.808278354154936096,
+    1325.945517883190177599, 1104.486978929608085309, 920.016297933984674273, 766.355787448445425980,
+    638.359553275944676898, 531.741165047412550848, 442.930109144548907807, 368.952216760026544762,
 };
 
 #endif /* AVCODEC_MPCDATA_H */
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index a5dcccf..953cd5e 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000, 2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,11 +25,15 @@
  * MPEG-1/2 decoder
  */
 
+#define UNCHECKED_BITSTREAM_READER 1
+
 //#define DEBUG
 #include "internal.h"
 #include "avcodec.h"
 #include "dsputil.h"
 #include "mpegvideo.h"
+#include "libavutil/avassert.h"
+#include "libavutil/timecode.h"
 
 #include "mpeg12.h"
 #include "mpeg12data.h"
@@ -39,9 +43,6 @@
 #include "xvmc_internal.h"
 #include "thread.h"
 
-//#undef NDEBUG
-//#include <assert.h>
-
 
 #define MV_VLC_BITS 9
 #define MBINCR_VLC_BITS 9
@@ -231,6 +232,11 @@
     return 0;
 }
 
+/**
+ * Note: this function can read out of range and crash for corrupt streams.
+ * 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)
 {
     int level, i, j, run;
@@ -382,6 +388,11 @@
     return 0;
 }
 
+/**
+ * Note: this function can read out of range and crash for corrupt streams.
+ * 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_non_intra(MpegEncContext *s,
                                                     DCTELEM *block, int n)
 {
@@ -522,6 +533,11 @@
     return 0;
 }
 
+/**
+ * Note: this function can read out of range and crash for corrupt streams.
+ * 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)
 {
     int level, dc, diff, j, run;
@@ -741,7 +757,7 @@
 
     av_dlog(s->avctx, "decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y);
 
-    assert(s->mb_skipped == 0);
+    av_assert2(s->mb_skipped == 0);
 
     if (s->mb_skip_run-- != 0) {
         if (s->pict_type == AV_PICTURE_TYPE_P) {
@@ -758,7 +774,7 @@
                 return -1;
             s->current_picture.f.mb_type[s->mb_x + s->mb_y*s->mb_stride] =
                 mb_type | MB_TYPE_SKIP;
-//            assert(s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1] & (MB_TYPE_16x16 | MB_TYPE_16x8));
+//            av_assert2(s->current_picture.f.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1] & (MB_TYPE_16x16 | MB_TYPE_16x8));
 
             if ((s->mv[0][0][0] | s->mv[0][0][1] | s->mv[1][0][0] | s->mv[1][0][1]) == 0)
                 s->mb_skipped = 1;
@@ -856,7 +872,7 @@
         }
     } else {
         if (mb_type & MB_TYPE_ZERO_MV) {
-            assert(mb_type & MB_TYPE_CBP);
+            av_assert2(mb_type & MB_TYPE_CBP);
 
             s->mv_dir = MV_DIR_FORWARD;
             if (s->picture_structure == PICT_FRAME) {
@@ -879,7 +895,7 @@
             s->mv[0][0][0] = 0;
             s->mv[0][0][1] = 0;
         } else {
-            assert(mb_type & MB_TYPE_L0L1);
+            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)
@@ -956,6 +972,7 @@
                         }
                     }
                 } else {
+                    av_assert0(!s->progressive_sequence);
                     mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
                     for (i = 0; i < 2; i++) {
                         if (USES_LIST(mb_type, i)) {
@@ -972,6 +989,10 @@
                 }
                 break;
             case MT_DMV:
+                if(s->progressive_sequence){
+                    av_log(s->avctx, AV_LOG_ERROR, "MT_DMV in progressive_sequence\n");
+                    return -1;
+                }
                 s->mv_type = MV_TYPE_DMV;
                 for (i = 0; i < 2; i++) {
                     if (USES_LIST(mb_type, i)) {
@@ -1171,31 +1192,61 @@
     }
 }
 
-static const enum AVPixelFormat pixfmt_xvmc_mpg2_420[] = {
+static const enum AVPixelFormat mpeg1_hwaccel_pixfmt_list_420[] = {
+#if CONFIG_MPEG_XVMC_DECODER
     AV_PIX_FMT_XVMC_MPEG2_IDCT,
     AV_PIX_FMT_XVMC_MPEG2_MC,
-    AV_PIX_FMT_NONE };
+#endif
+#if CONFIG_MPEG1_VDPAU_HWACCEL
+    AV_PIX_FMT_VDPAU_MPEG1,
+#endif
+    AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_NONE
+};
+
+static const enum AVPixelFormat mpeg2_hwaccel_pixfmt_list_420[] = {
+#if CONFIG_MPEG_XVMC_DECODER
+    AV_PIX_FMT_XVMC_MPEG2_IDCT,
+    AV_PIX_FMT_XVMC_MPEG2_MC,
+#endif
+#if CONFIG_MPEG2_VDPAU_HWACCEL
+    AV_PIX_FMT_VDPAU_MPEG2,
+#endif
+#if CONFIG_MPEG2_DXVA2_HWACCEL
+    AV_PIX_FMT_DXVA2_VLD,
+#endif
+#if CONFIG_MPEG2_VAAPI_HWACCEL
+    AV_PIX_FMT_VAAPI_VLD,
+#endif
+    AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_NONE
+};
+
+static inline int uses_vdpau(AVCodecContext *avctx) {
+    return avctx->pix_fmt == AV_PIX_FMT_VDPAU_MPEG1 || avctx->pix_fmt == AV_PIX_FMT_VDPAU_MPEG2;
+}
 
 static enum AVPixelFormat mpeg_get_pixelformat(AVCodecContext *avctx)
 {
     Mpeg1Context *s1 = avctx->priv_data;
     MpegEncContext *s = &s1->mpeg_enc_ctx;
 
-    if (avctx->xvmc_acceleration)
-        return avctx->get_format(avctx, pixfmt_xvmc_mpg2_420);
-    else if (avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {
-        if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO)
-            return AV_PIX_FMT_VDPAU_MPEG1;
-        else
-            return AV_PIX_FMT_VDPAU_MPEG2;
-    } else {
-        if (s->chroma_format <  2)
-            return avctx->get_format(avctx, ff_hwaccel_pixfmt_list_420);
-        else if (s->chroma_format == 2)
-            return AV_PIX_FMT_YUV422P;
-        else
-            return AV_PIX_FMT_YUV444P;
-    }
+    if(s->chroma_format < 2) {
+        enum AVPixelFormat res;
+        res = avctx->get_format(avctx,
+                                avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO ?
+                                mpeg1_hwaccel_pixfmt_list_420 :
+                                mpeg2_hwaccel_pixfmt_list_420);
+        if (res != AV_PIX_FMT_XVMC_MPEG2_IDCT && res != AV_PIX_FMT_XVMC_MPEG2_MC) {
+            avctx->xvmc_acceleration = 0;
+        } else if (!avctx->xvmc_acceleration) {
+            avctx->xvmc_acceleration = 2;
+        }
+        return res;
+    } else if(s->chroma_format == 2)
+        return AV_PIX_FMT_YUV422P;
+    else
+        return AV_PIX_FMT_YUV444P;
 }
 
 /* Call this function when we know all parameters.
@@ -1290,8 +1341,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                            ||
-            s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
+            avctx->hwaccel )
             if (avctx->idct_algo == FF_IDCT_AUTO)
                 avctx->idct_algo = FF_IDCT_SIMPLE;
 
@@ -1330,16 +1380,18 @@
     if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type == AV_PICTURE_TYPE_B) {
         s->full_pel[0] = get_bits1(&s->gb);
         f_code = get_bits(&s->gb, 3);
-        if (f_code == 0 && (avctx->err_recognition & AV_EF_BITSTREAM))
+        if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)))
             return -1;
+        f_code += !f_code;
         s->mpeg_f_code[0][0] = f_code;
         s->mpeg_f_code[0][1] = f_code;
     }
     if (s->pict_type == AV_PICTURE_TYPE_B) {
         s->full_pel[1] = get_bits1(&s->gb);
         f_code = get_bits(&s->gb, 3);
-        if (f_code == 0 && (avctx->err_recognition & AV_EF_BITSTREAM))
+        if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)))
             return -1;
+        f_code += !f_code;
         s->mpeg_f_code[1][0] = f_code;
         s->mpeg_f_code[1][1] = f_code;
     }
@@ -1459,7 +1511,7 @@
             return -1;
         }
         if (intra && i == 0 && v != 8) {
-            av_log(s->avctx, AV_LOG_ERROR, "intra matrix invalid, ignoring\n");
+            av_log(s->avctx, AV_LOG_DEBUG, "intra matrix specifies invalid DC quantizer %d, ignoring\n", v);
             v = 8; // needed by pink.mpg / issue1046
         }
         matrix0[j] = v;
@@ -1500,6 +1552,11 @@
         s->current_picture.f.pict_type = s->pict_type;
         s->current_picture.f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;
     }
+    s->mpeg_f_code[0][0] += !s->mpeg_f_code[0][0];
+    s->mpeg_f_code[0][1] += !s->mpeg_f_code[0][1];
+    s->mpeg_f_code[1][0] += !s->mpeg_f_code[1][0];
+    s->mpeg_f_code[1][1] += !s->mpeg_f_code[1][1];
+
     s->intra_dc_precision         = get_bits(&s->gb, 2);
     s->picture_structure          = get_bits(&s->gb, 2);
     s->top_field_first            = get_bits1(&s->gb);
@@ -1512,28 +1569,6 @@
     s->chroma_420_type            = get_bits1(&s->gb);
     s->progressive_frame          = get_bits1(&s->gb);
 
-    if (s->progressive_sequence && !s->progressive_frame) {
-        s->progressive_frame = 1;
-        av_log(s->avctx, AV_LOG_ERROR, "interlaced frame in progressive sequence, ignoring\n");
-    }
-
-    if (s->picture_structure == 0 || (s->progressive_frame && s->picture_structure != PICT_FRAME)) {
-        av_log(s->avctx, AV_LOG_ERROR, "picture_structure %d invalid, ignoring\n", s->picture_structure);
-        s->picture_structure = PICT_FRAME;
-    }
-
-    if (s->progressive_sequence && !s->frame_pred_frame_dct) {
-        av_log(s->avctx, AV_LOG_WARNING, "invalid frame_pred_frame_dct\n");
-    }
-
-    if (s->picture_structure == PICT_FRAME) {
-        s->first_field = 0;
-        s->v_edge_pos  = 16 * s->mb_height;
-    } else {
-        s->first_field ^= 1;
-        s->v_edge_pos   = 8 * s->mb_height;
-        memset(s->mbskip_table, 0, s->mb_stride * s->mb_height);
-    }
 
     if (s->alternate_scan) {
         ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan);
@@ -1633,14 +1668,17 @@
                              const uint8_t **buf, int buf_size)
 {
     AVCodecContext *avctx = s->avctx;
+    const int lowres      = s->avctx->lowres;
     const int field_pic   = s->picture_structure != PICT_FRAME;
 
     s->resync_mb_x =
     s->resync_mb_y = -1;
 
-    assert(mb_y < s->mb_height);
+    av_assert0(mb_y < s->mb_height);
 
     init_get_bits(&s->gb, *buf, buf_size * 8);
+    if(s->codec_id != AV_CODEC_ID_MPEG1VIDEO && s->mb_height > 2800/16)
+        skip_bits(&s->gb, 3);
 
     ff_mpeg1_clean_buffers(s);
     s->interlaced_dct = 0;
@@ -1746,21 +1784,21 @@
                     s->current_picture.f.motion_val[dir][xy + 1][1] = motion_y;
                     s->current_picture.f.ref_index [dir][b8_xy    ] =
                     s->current_picture.f.ref_index [dir][b8_xy + 1] = s->field_select[dir][i];
-                    assert(s->field_select[dir][i] == 0 || s->field_select[dir][i] == 1);
+                    av_assert2(s->field_select[dir][i] == 0 || s->field_select[dir][i] == 1);
                 }
                 xy += wrap;
                 b8_xy +=2;
             }
         }
 
-        s->dest[0] += 16;
-        s->dest[1] += 16 >> s->chroma_x_shift;
-        s->dest[2] += 16 >> s->chroma_x_shift;
+        s->dest[0] += 16 >> lowres;
+        s->dest[1] +=(16 >> lowres) >> s->chroma_x_shift;
+        s->dest[2] +=(16 >> lowres) >> s->chroma_x_shift;
 
         ff_MPV_decode_mb(s, s->block);
 
         if (++s->mb_x >= s->mb_width) {
-            const int mb_size = 16;
+            const int mb_size = 16 >> s->avctx->lowres;
 
             ff_draw_horiz_band(s, mb_size*(s->mb_y >> field_pic), mb_size);
             ff_MPV_report_decode_progress(s);
@@ -1775,7 +1813,7 @@
                              && s->progressive_frame == 0 /* vbv_delay == 0xBBB || 0xE10*/;
 
                 if (left < 0 || (left && show_bits(&s->gb, FFMIN(left, 23)) && !is_d10)
-                    || ((avctx->err_recognition & AV_EF_BUFFER) && left > 8)) {
+                    || ((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)));
                     return -1;
                 } else
@@ -1881,7 +1919,10 @@
 
         start_code = -1;
         buf = avpriv_mpv_find_start_code(buf, s->gb.buffer_end, &start_code);
-        mb_y= (start_code - SLICE_MIN_START_CODE) << field_pic;
+        mb_y= start_code - SLICE_MIN_START_CODE;
+        if(s->codec_id != AV_CODEC_ID_MPEG1VIDEO && s->mb_height > 2800/16)
+            mb_y += (*buf&0xE0)<<2;
+        mb_y <<= field_pic;
         if (s->picture_structure == PICT_BOTTOM_FIELD)
             mb_y++;
         if (mb_y < 0 || mb_y >= s->end_mb_y)
@@ -1910,7 +1951,7 @@
         ff_xvmc_field_end(s);
 
     /* end of slice reached */
-    if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field) {
+    if (/*s->mb_y << field_pic == s->mb_height &&*/ !s->first_field && !s->first_slice) {
         /* end of image */
 
         s->current_picture_ptr->f.qscale_type = FF_QSCALE_TYPE_MPEG2;
@@ -1956,7 +1997,7 @@
     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");
-        if (avctx->err_recognition & AV_EF_BITSTREAM)
+        if (avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT))
             return -1;
     }
     s->frame_rate_index = get_bits(&s->gb, 4);
@@ -2002,6 +2043,7 @@
     s->progressive_sequence = 1;
     s->progressive_frame    = 1;
     s->picture_structure    = PICT_FRAME;
+    s->first_field          = 0;
     s->frame_pred_frame_dct = 1;
     s->chroma_format        = 1;
     s->codec_id             = s->avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO;
@@ -2036,15 +2078,12 @@
     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 ||
-        s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
+    if( avctx->pix_fmt == AV_PIX_FMT_XVMC_MPEG2_IDCT || avctx->hwaccel )
         if (avctx->idct_algo == FF_IDCT_AUTO)
             avctx->idct_algo = FF_IDCT_SIMPLE;
 
     if (ff_MPV_common_init(s) < 0)
         return -1;
-    exchange_uv(s); // common init reset pblocks, so we swap them here
-    s->swap_uv = 1; // in case of xvmc we need to swap uv for each MB
     s1->mpeg_enc_ctx_allocated = 1;
 
     for (i = 0; i < 64; i++) {
@@ -2061,9 +2100,16 @@
     s->progressive_sequence  = 1;
     s->progressive_frame     = 1;
     s->picture_structure     = PICT_FRAME;
+    s->first_field           = 0;
     s->frame_pred_frame_dct  = 1;
     s->chroma_format         = 1;
-    s->codec_id              = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
+    if (s->codec_tag == AV_RL32("BW10")) {
+        s->codec_id              = s->avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO;
+    } else {
+        exchange_uv(s); // common init reset pblocks, so we swap them here
+        s->swap_uv = 1; // in case of xvmc we need to swap uv for each MB
+        s->codec_id              = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
+    }
     s1->save_width           = s->width;
     s1->save_height          = s->height;
     s1->save_progressive_seq = s->progressive_sequence;
@@ -2074,8 +2120,22 @@
 static void mpeg_decode_user_data(AVCodecContext *avctx,
                                   const uint8_t *p, int buf_size)
 {
+    Mpeg1Context *s = avctx->priv_data;
     const uint8_t *buf_end = p + buf_size;
 
+    if(buf_size > 29){
+        int i;
+        for(i=0; i<20; i++)
+            if(!memcmp(p+i, "\0TMPGEXS\0", 9)){
+                s->tmpgexs= 1;
+            }
+
+/*        for(i=0; !(!p[i-2] && !p[i-1] && p[i]==1) && i<buf_size; i++){
+            av_log(0,0, "%c", p[i]);
+        }
+            av_log(0,0, "\n");*/
+    }
+
     /* we parse the DTG active format information */
     if (buf_end - p >= 5 &&
         p[0] == 'D' && p[1] == 'T' && p[2] == 'G' && p[3] == '1') {
@@ -2098,31 +2158,26 @@
 {
     Mpeg1Context *s1  = avctx->priv_data;
     MpegEncContext *s = &s1->mpeg_enc_ctx;
-
-    int time_code_hours, time_code_minutes;
-    int time_code_seconds, time_code_pictures;
     int broken_link;
+    int64_t tc;
 
     init_get_bits(&s->gb, buf, buf_size*8);
 
-    skip_bits1(&s->gb); /* drop_frame_flag */
+    tc = avctx->timecode_frame_start = get_bits(&s->gb, 25);
 
-    time_code_hours   = get_bits(&s->gb, 5);
-    time_code_minutes = get_bits(&s->gb, 6);
-    skip_bits1(&s->gb); // marker bit
-    time_code_seconds  = get_bits(&s->gb, 6);
-    time_code_pictures = get_bits(&s->gb, 6);
-
-    s1->closed_gop = get_bits1(&s->gb);
+    s->closed_gop = get_bits1(&s->gb);
     /*broken_link indicate that after editing the
       reference frames of the first B-Frames after GOP I-Frame
       are missing (open gop)*/
     broken_link = get_bits1(&s->gb);
 
-    if (s->avctx->debug & FF_DEBUG_PICT_INFO)
-        av_log(s->avctx, AV_LOG_DEBUG, "GOP (%2d:%02d:%02d.[%02d]) closed_gop=%d broken_link=%d\n",
-               time_code_hours, time_code_minutes, time_code_seconds,
-               time_code_pictures, s1->closed_gop, broken_link);
+    if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
+        char tcbuf[AV_TIMECODE_STR_SIZE];
+        av_timecode_make_mpeg_tc_string(tcbuf, tc);
+        av_log(s->avctx, AV_LOG_DEBUG,
+               "GOP (%s) closed_gop=%d broken_link=%d\n",
+               tcbuf, s->closed_gop, broken_link);
+    }
 }
 /**
  * Find the end of the current frame in the bitstream.
@@ -2146,7 +2201,7 @@
 */
 
     for (i = 0; i < buf_size; i++) {
-        assert(pc->frame_start_found >= 0 && pc->frame_start_found <= 4);
+        av_assert1(pc->frame_start_found >= 0 && pc->frame_start_found <= 4);
         if (pc->frame_start_found & 1) {
             if (state == EXT_START_CODE && (buf[i] & 0xF0) != 0x80)
                 pc->frame_start_found--;
@@ -2207,15 +2262,17 @@
             if (s2->pict_type != AV_PICTURE_TYPE_B || avctx->skip_frame <= AVDISCARD_DEFAULT) {
                 if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)) {
                     int i;
+                    av_assert0(avctx->thread_count > 1);
 
                     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;
                 }
 
-                if (CONFIG_MPEG_VDPAU_DECODER && avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)
+                if (CONFIG_VDPAU && uses_vdpau(avctx))
                     ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count);
 
+
                 if (slice_end(avctx, picture)) {
                     if (s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice
                         *got_output = 1;
@@ -2236,7 +2293,8 @@
         case SEQ_START_CODE:
             if (last_code == 0) {
                 mpeg1_decode_sequence(avctx, buf_ptr, input_size);
-                s->sync=1;
+                if(buf != avctx->extradata)
+                    s->sync=1;
             } else {
                 av_log(avctx, AV_LOG_ERROR, "ignoring SEQ_START_CODE after %X\n", last_code);
                 if (avctx->err_recognition & AV_EF_EXPLODE)
@@ -2245,6 +2303,10 @@
             break;
 
         case PICTURE_START_CODE:
+            if(s->tmpgexs){
+                s2->intra_dc_precision= 3;
+                s2->intra_matrix[0]= 1;
+            }
             if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) && s->slice_count) {
                 int i;
 
@@ -2322,11 +2384,40 @@
             break;
         default:
             if (start_code >= SLICE_MIN_START_CODE &&
+                start_code <= SLICE_MAX_START_CODE && last_code == PICTURE_START_CODE) {
+
+                if (s2->progressive_sequence && !s2->progressive_frame) {
+                    s2->progressive_frame = 1;
+                    av_log(s2->avctx, AV_LOG_ERROR, "interlaced frame in progressive sequence, ignoring\n");
+                }
+
+                if (s2->picture_structure == 0 || (s2->progressive_frame && s2->picture_structure != PICT_FRAME)) {
+                    av_log(s2->avctx, AV_LOG_ERROR, "picture_structure %d invalid, ignoring\n", s2->picture_structure);
+                    s2->picture_structure = PICT_FRAME;
+                }
+
+                if (s2->progressive_sequence && !s2->frame_pred_frame_dct) {
+                    av_log(s2->avctx, AV_LOG_WARNING, "invalid frame_pred_frame_dct\n");
+                }
+
+                if (s2->picture_structure == PICT_FRAME) {
+                    s2->first_field = 0;
+                    s2->v_edge_pos  = 16 * s2->mb_height;
+                } else {
+                    s2->first_field ^= 1;
+                    s2->v_edge_pos   = 8 * s2->mb_height;
+                    memset(s2->mbskip_table, 0, s2->mb_stride * s2->mb_height);
+                }
+            }
+            if (start_code >= SLICE_MIN_START_CODE &&
                 start_code <= SLICE_MAX_START_CODE && last_code != 0) {
                 const int field_pic = s2->picture_structure != PICT_FRAME;
-                int mb_y = (start_code - SLICE_MIN_START_CODE) << field_pic;
+                int mb_y = start_code - SLICE_MIN_START_CODE;
                 last_code = SLICE_MIN_START_CODE;
+                if(s2->codec_id != AV_CODEC_ID_MPEG1VIDEO && s2->mb_height > 2800/16)
+                    mb_y += (*buf_ptr&0xE0)<<2;
 
+                mb_y <<= field_pic;
                 if (s2->picture_structure == PICT_BOTTOM_FIELD)
                     mb_y++;
 
@@ -2338,11 +2429,11 @@
                 if (s2->last_picture_ptr == NULL) {
                 /* Skip B-frames if we do not have reference frames and gop is not closed */
                     if (s2->pict_type == AV_PICTURE_TYPE_B) {
-                        if (!s->closed_gop)
+                        if (!s2->closed_gop)
                             break;
                     }
                 }
-                if (s2->pict_type == AV_PICTURE_TYPE_I)
+                if (s2->pict_type == AV_PICTURE_TYPE_I || (s2->flags2 & CODEC_FLAG2_SHOW_ALL))
                     s->sync=1;
                 if (s2->next_picture_ptr == NULL) {
                 /* Skip P-frames if we do not have a reference frame or we have an invalid header. */
@@ -2378,7 +2469,7 @@
                     return AVERROR_INVALIDDATA;
                 }
 
-                if (avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) {
+                if (uses_vdpau(avctx)) {
                     s->slice_count++;
                     break;
                 }
@@ -2387,6 +2478,7 @@
                     int threshold = (s2->mb_height * s->slice_count +
                                      s2->slice_context_count / 2) /
                                     s2->slice_context_count;
+                    av_assert0(avctx->thread_count > 1);
                     if (threshold <= mb_y) {
                         MpegEncContext *thread_context = s2->thread_context[s->slice_count];
 
@@ -2448,13 +2540,21 @@
             return buf_size;
     }
 
-    if (s->mpeg_enc_ctx_allocated == 0 && avctx->codec_tag == AV_RL32("VCR2"))
+    s2->codec_tag = avpriv_toupper4(avctx->codec_tag);
+    if (s->mpeg_enc_ctx_allocated == 0 && (   s2->codec_tag == AV_RL32("VCR2")
+                                           || s2->codec_tag == AV_RL32("BW10")
+                                          ))
         vcr2_init_sequence(avctx);
 
     s->slice_count = 0;
 
-    if (avctx->extradata && !avctx->frame_number) {
+    if (avctx->extradata && !s->parsed_extra) {
         int 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))
             return ret;
     }
@@ -2468,7 +2568,6 @@
     Mpeg1Context *s = avctx->priv_data;
 
     s->sync=0;
-    s->closed_gop = 0;
 
     ff_mpeg_flush(avctx);
 }
@@ -2507,6 +2606,7 @@
                              CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY |
                              CODEC_CAP_SLICE_THREADS,
     .flush                 = flush,
+    .max_lowres            = 3,
     .long_name             = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
     .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context)
 };
@@ -2523,10 +2623,26 @@
                       CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY |
                       CODEC_CAP_SLICE_THREADS,
     .flush          = flush,
+    .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("MPEG-2 video"),
     .profiles       = NULL_IF_CONFIG_SMALL(mpeg2_video_profiles),
 };
 
+//legacy decoder
+AVCodec ff_mpegvideo_decoder = {
+    .name           = "mpegvideo",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MPEG2VIDEO,
+    .priv_data_size = sizeof(Mpeg1Context),
+    .init           = mpeg_decode_init,
+    .close          = mpeg_decode_end,
+    .decode         = mpeg_decode_frame,
+    .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS,
+    .flush          = flush,
+    .max_lowres     = 3,
+    .long_name      = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
+};
+
 #if CONFIG_MPEG_XVMC_DECODER
 static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx)
 {
diff --git a/libavcodec/mpeg12.h b/libavcodec/mpeg12.h
index ab0352f..c8cec48 100644
--- a/libavcodec/mpeg12.h
+++ b/libavcodec/mpeg12.h
@@ -2,20 +2,20 @@
  * MPEG1/2 common code
  * Copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -41,7 +41,8 @@
     int save_width, save_height, save_progressive_seq;
     AVRational frame_rate_ext;       ///< MPEG-2 specific framerate modificator
     int sync;                        ///< Did we reach a sync point like a GOP/SEQ/KEYFrame?
-    int closed_gop;                  ///< GOP is closed
+    int tmpgexs;
+    int parsed_extra;
 } Mpeg1Context;
 
 extern uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3];
diff --git a/libavcodec/mpeg12data.c b/libavcodec/mpeg12data.c
index a0dd6e5..f4644f3 100644
--- a/libavcodec/mpeg12data.c
+++ b/libavcodec/mpeg12data.c
@@ -3,20 +3,20 @@
  * copyright (c) 2000,2001 Fabrice Bellard
  * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -325,6 +325,72 @@
     {    0,    0},
 };
 
+const AVRational ff_mpeg2_frame_rate_tab[] = {
+    {      1,     1},
+    {      2,     1},
+    {      3,     1},
+    {      4,     1},
+    {      5,     1},
+    {      6,     1},
+    {      8,     1},
+    {      9,     1},
+    {     10,     1},
+    {     12,     1},
+    {     15,     1},
+    {     16,     1},
+    {     18,     1},
+    {     20,     1},
+    {     24,     1},
+    {     25,     1},
+    {     30,     1},
+    {     32,     1},
+    {     36,     1},
+    {     40,     1},
+    {     45,     1},
+    {     48,     1},
+    {     50,     1},
+    {     60,     1},
+    {     72,     1},
+    {     75,     1},
+    {     80,     1},
+    {     90,     1},
+    {     96,     1},
+    {    100,     1},
+    {    120,     1},
+    {    150,     1},
+    {    180,     1},
+    {    200,     1},
+    {    240,     1},
+    {    750,  1001},
+    {    800,  1001},
+    {    960,  1001},
+    {   1000,  1001},
+    {   1200,  1001},
+    {   1250,  1001},
+    {   1500,  1001},
+    {   1600,  1001},
+    {   1875,  1001},
+    {   2000,  1001},
+    {   2400,  1001},
+    {   2500,  1001},
+    {   3000,  1001},
+    {   3750,  1001},
+    {   4000,  1001},
+    {   4800,  1001},
+    {   5000,  1001},
+    {   6000,  1001},
+    {   7500,  1001},
+    {   8000,  1001},
+    {  10000,  1001},
+    {  12000,  1001},
+    {  15000,  1001},
+    {  20000,  1001},
+    {  24000,  1001},
+    {  30000,  1001},
+    {  60000,  1001},
+    {      0,     0},
+};
+
 const float ff_mpeg1_aspect[16]={
     0.0000,
     1.0000,
diff --git a/libavcodec/mpeg12data.h b/libavcodec/mpeg12data.h
index 86ba3ec..7eac33b 100644
--- a/libavcodec/mpeg12data.h
+++ b/libavcodec/mpeg12data.h
@@ -3,20 +3,20 @@
  * copyright (c) 2000,2001 Fabrice Bellard
  * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -49,6 +49,7 @@
 extern const uint8_t ff_mpeg12_mbMotionVectorTable[17][2];
 
 extern const AVRational avpriv_frame_rate_tab[];
+extern const AVRational ff_mpeg2_frame_rate_tab[];
 
 extern const float ff_mpeg1_aspect[16];
 extern const AVRational ff_mpeg2_aspect[16];
diff --git a/libavcodec/mpeg12decdata.h b/libavcodec/mpeg12decdata.h
index 323a902..66ca5c4 100644
--- a/libavcodec/mpeg12decdata.h
+++ b/libavcodec/mpeg12decdata.h
@@ -3,20 +3,20 @@
  * copyright (c) 2000,2001 Fabrice Bellard
  * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c
index 7048b5d..42731eb 100644
--- a/libavcodec/mpeg12enc.c
+++ b/libavcodec/mpeg12enc.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000,2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -33,9 +33,10 @@
 #include "mpeg12.h"
 #include "mpeg12data.h"
 #include "bytestream.h"
-
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
+#include "libavutil/avassert.h"
+#include "libavutil/timecode.h"
 
 static const uint8_t inv_non_linear_qscale[13] = {
     0, 2, 4, 6, 8,
@@ -107,21 +108,34 @@
 
 static int find_frame_rate_index(MpegEncContext *s){
     int i;
-    int64_t dmin= INT64_MAX;
-    int64_t d;
+    AVRational bestq= (AVRational){0, 0};
+    AVRational ext;
+    AVRational target = av_inv_q(s->avctx->time_base);
 
     for(i=1;i<14;i++) {
-        int64_t n0= 1001LL/avpriv_frame_rate_tab[i].den*avpriv_frame_rate_tab[i].num*s->avctx->time_base.num;
-        int64_t n1= 1001LL*s->avctx->time_base.den;
         if(s->avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL && i>=9) break;
 
-        d = FFABS(n0 - n1);
-        if(d < dmin){
-            dmin=d;
-            s->frame_rate_index= i;
+        for (ext.num=1; ext.num <= 4; ext.num++) {
+            for (ext.den=1; ext.den <= 32; ext.den++) {
+                AVRational q = av_mul_q(ext, avpriv_frame_rate_tab[i]);
+
+                if(s->codec_id != AV_CODEC_ID_MPEG2VIDEO && (ext.den!=1 || ext.num!=1))
+                    continue;
+                if(av_gcd(ext.den, ext.num) != 1)
+                    continue;
+
+                if(    bestq.num==0
+                    || av_nearer_q(target, bestq, q) < 0
+                    || ext.num==1 && ext.den==1 && av_nearer_q(target, bestq, q) == 0){
+                    bestq = q;
+                    s->frame_rate_index= i;
+                    s->mpeg2_frame_rate_ext.num = ext.num;
+                    s->mpeg2_frame_rate_ext.den = ext.den;
+                }
+            }
         }
     }
-    if(dmin)
+    if(av_cmp_q(target, bestq))
         return -1;
     else
         return 0;
@@ -166,11 +180,24 @@
         }
     }
 
+    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;
     if (s->drop_frame_timecode && s->frame_rate_index != 4) {
         av_log(avctx, AV_LOG_ERROR, "Drop frame time code only allowed with 1001/30000 fps\n");
         return -1;
     }
 
+    if (s->tc_opt_str) {
+        AVRational rate = avpriv_frame_rate_tab[s->frame_rate_index];
+        int ret = av_timecode_init_from_string(&s->tc, rate, s->tc_opt_str, s);
+        if (ret < 0)
+            return ret;
+        s->drop_frame_timecode = !!(s->tc.flags & AV_TIMECODE_FLAG_DROPFRAME);
+        s->avctx->timecode_frame_start = s->tc.start;
+    } else {
+        s->avctx->timecode_frame_start = 0; // default is -1
+    }
     return 0;
 }
 
@@ -272,8 +299,8 @@
                 put_bits(&s->pb, 1, 1); //marker
                 put_bits(&s->pb, 8, vbv_buffer_size >>10); //vbv buffer ext
                 put_bits(&s->pb, 1, s->low_delay);
-                put_bits(&s->pb, 2, 0); // frame_rate_ext_n
-                put_bits(&s->pb, 5, 0); // frame_rate_ext_d
+                put_bits(&s->pb, 2, s->mpeg2_frame_rate_ext.num-1); // frame_rate_ext_n
+                put_bits(&s->pb, 5, s->mpeg2_frame_rate_ext.den-1); // frame_rate_ext_d
             }
 
             put_header(s, GOP_START_CODE);
@@ -284,13 +311,9 @@
             time_code = s->current_picture_ptr->f.coded_picture_number + s->avctx->timecode_frame_start;
 
             s->gop_picture_number = s->current_picture_ptr->f.coded_picture_number;
-            if (s->drop_frame_timecode) {
-                /* only works for NTSC 29.97 */
-                int d = time_code / 17982;
-                int m = time_code % 17982;
-                //if (m < 2) m += 2; /* not needed since -2,-1 / 1798 in C returns 0 */
-                time_code += 18 * d + 2 * ((m - 2) / 1798);
-            }
+            av_assert0(s->drop_frame_timecode == !!(s->tc.flags & AV_TIMECODE_FLAG_DROPFRAME));
+            if (s->drop_frame_timecode)
+                time_code = av_timecode_adjust_ntsc_framenum2(time_code, fps);
             put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24));
             put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60));
             put_bits(&s->pb, 1, 1);
@@ -313,7 +336,7 @@
 static av_always_inline void put_qscale(MpegEncContext *s)
 {
     if(s->q_scale_type){
-        assert(s->qscale>=1 && s->qscale <=12);
+        av_assert2(s->qscale>=1 && s->qscale <=12);
         put_bits(&s->pb, 5, inv_non_linear_qscale[s->qscale]);
     }else{
         put_bits(&s->pb, 5, s->qscale);
@@ -321,7 +344,7 @@
 }
 
 void ff_mpeg1_encode_slice_header(MpegEncContext *s){
-    if (s->height > 2800) {
+    if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->height > 2800) {
         put_header(s, SLICE_MIN_START_CODE + (s->mb_y & 127));
         put_bits(&s->pb, 3, s->mb_y >> 7);  /* slice_vertical_position_extension */
     } else {
@@ -385,7 +408,7 @@
         }
         put_bits(&s->pb, 2, s->intra_dc_precision);
 
-        assert(s->picture_structure == PICT_FRAME);
+        av_assert0(s->picture_structure == PICT_FRAME);
         put_bits(&s->pb, 2, s->picture_structure);
         if (s->progressive_sequence) {
             put_bits(&s->pb, 1, 0); /* no repeat */
@@ -464,7 +487,7 @@
         }
     } else {
         if(first_mb){
-            assert(s->mb_skip_run == 0);
+            av_assert0(s->mb_skip_run == 0);
             encode_mb_skip_run(s, s->mb_x);
         }else{
             encode_mb_skip_run(s, s->mb_skip_run);
@@ -527,7 +550,7 @@
                 s->last_mv[0][1][0]= s->last_mv[0][0][0]= motion_x;
                 s->last_mv[0][1][1]= s->last_mv[0][0][1]= motion_y;
             }else{
-                assert(!s->frame_pred_frame_dct && s->mv_type == MV_TYPE_FIELD);
+                av_assert2(!s->frame_pred_frame_dct && s->mv_type == MV_TYPE_FIELD);
 
                 if (cbp) {
                     if(s->dquant){
@@ -594,8 +617,8 @@
                     s->b_count++;
                 }
             }else{
-                assert(s->mv_type == MV_TYPE_FIELD);
-                assert(!s->frame_pred_frame_dct);
+                av_assert2(s->mv_type == MV_TYPE_FIELD);
+                av_assert2(!s->frame_pred_frame_dct);
                 if (cbp){    // With coded bloc pattern
                     if (s->dquant) {
                         if(s->mv_dir == MV_DIR_FORWARD)
@@ -690,7 +713,7 @@
             sign = 1;
         }
 
-        assert(code > 0 && code <= 16);
+        av_assert2(code > 0 && code <= 16);
 
         put_bits(&s->pb,
                  ff_mpeg12_mbMotionVectorTable[code][1],
@@ -921,6 +944,7 @@
 #define OFFSET(x) offsetof(MpegEncContext, x)
 #define VE AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM
 #define COMMON_OPTS\
+    { "gop_timecode",        "MPEG GOP Timecode in hh:mm:ss[:;.]ff format", OFFSET(tc_opt_str), AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, VE },\
     { "intra_vlc",           "Use MPEG-2 intra VLC table.",       OFFSET(intra_vlc_format),    AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },\
     { "drop_frame_timecode", "Timecode is in drop frame format.", OFFSET(drop_frame_timecode), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE}, \
     { "scan_offset",         "Reserve space for SVCD scan offset user data.", OFFSET(scan_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
@@ -961,7 +985,7 @@
     .supported_framerates = avpriv_frame_rate_tab+1,
     .pix_fmts             = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P,
                                                         AV_PIX_FMT_NONE },
-    .capabilities         = CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS,
+    .capabilities         = CODEC_CAP_DELAY,
     .long_name            = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
     .priv_class           = &mpeg1_class,
 };
@@ -974,7 +998,7 @@
     .init                 = encode_init,
     .encode2              = ff_MPV_encode_picture,
     .close                = ff_MPV_encode_end,
-    .supported_framerates = avpriv_frame_rate_tab + 1,
+    .supported_framerates = ff_mpeg2_frame_rate_tab,
     .pix_fmts             = (const enum AVPixelFormat[]){
         AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE
     },
diff --git a/libavcodec/mpeg4audio.c b/libavcodec/mpeg4audio.c
index 0fb9b96..3066954 100644
--- a/libavcodec/mpeg4audio.c
+++ b/libavcodec/mpeg4audio.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@free.fr>
  * Copyright (c) 2009 Alex Converse <alex.converse@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -82,6 +82,9 @@
     GetBitContext gb;
     int specific_config_bitindex;
 
+    if(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);
@@ -123,8 +126,11 @@
             if (show_bits(&gb, 11) == 0x2b7) { // sync extension
                 get_bits(&gb, 11);
                 c->ext_object_type = get_object_type(&gb);
-                if (c->ext_object_type == AOT_SBR && (c->sbr = get_bits1(&gb)) == 1)
+                if (c->ext_object_type == AOT_SBR && (c->sbr = get_bits1(&gb)) == 1) {
                     c->ext_sample_rate = get_sample_rate(&gb, &c->ext_sampling_index);
+                    if (c->ext_sample_rate == c->sample_rate)
+                        c->sbr = -1;
+                }
                 if (get_bits_left(&gb) > 11 && get_bits(&gb, 11) == 0x548)
                     c->ps = get_bits1(&gb);
                 break;
diff --git a/libavcodec/mpeg4audio.h b/libavcodec/mpeg4audio.h
index 1ee2d7e..64839c6 100644
--- a/libavcodec/mpeg4audio.h
+++ b/libavcodec/mpeg4audio.h
@@ -2,20 +2,20 @@
  * MPEG-4 Audio common header
  * Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@free.fr>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpeg4data.h b/libavcodec/mpeg4data.h
index 87bb539..1ac5840 100644
--- a/libavcodec/mpeg4data.h
+++ b/libavcodec/mpeg4data.h
@@ -3,20 +3,20 @@
  * H263+ support
  * copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpeg4video.c b/libavcodec/mpeg4video.c
index d7c928d..7444f26 100644
--- a/libavcodec/mpeg4video.c
+++ b/libavcodec/mpeg4video.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000,2001 Fabrice Bellard
  * Copyright (c) 2002-2010 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpeg4video.h b/libavcodec/mpeg4video.h
index 64c0243..95e6e9e 100644
--- a/libavcodec/mpeg4video.h
+++ b/libavcodec/mpeg4video.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2000,2001 Fabrice Bellard
  * Copyright (c) 2002-2010 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -174,7 +174,7 @@
     }else{
         level += pred;
         ret= level;
-        if(s->err_recognition&AV_EF_BITSTREAM){
+        if(s->err_recognition&(AV_EF_BITSTREAM|AV_EF_AGGRESSIVE)){
             if(level<0){
                 av_log(s->avctx, AV_LOG_ERROR, "dc<0 at %dx%d\n", s->mb_x, s->mb_y);
                 return -1;
diff --git a/libavcodec/mpeg4video_parser.c b/libavcodec/mpeg4video_parser.c
index e291262..d609440 100644
--- a/libavcodec/mpeg4video_parser.c
+++ b/libavcodec/mpeg4video_parser.c
@@ -3,23 +3,25 @@
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#define UNCHECKED_BITSTREAM_READER 1
+
 #include "parser.h"
 #include "mpegvideo.h"
 #include "mpeg4video.h"
@@ -91,6 +93,13 @@
     if (s->width && (!avctx->width || !avctx->height || !avctx->coded_width || !avctx->coded_height)) {
         avcodec_set_dimensions(avctx, s->width, s->height);
     }
+    if((s1->flags & PARSER_FLAG_USE_CODEC_TS) && s->avctx->time_base.den>0 && ret>=0){
+        av_assert1(s1->pts == AV_NOPTS_VALUE);
+        av_assert1(s1->dts == AV_NOPTS_VALUE);
+
+        s1->pts = av_rescale_q(s->time, (AVRational){1, s->avctx->time_base.den}, (AVRational){1, 1200000});
+    }
+
     s1->pict_type= s->pict_type;
     pc->first_picture = 0;
     return ret;
@@ -101,6 +110,7 @@
     struct Mp4vParseContext *pc = s->priv_data;
 
     pc->first_picture = 1;
+    pc->enc.quant_precision=5;
     pc->enc.slice_context_count = 1;
     return 0;
 }
diff --git a/libavcodec/mpeg4video_parser.h b/libavcodec/mpeg4video_parser.h
index 0f56e7f..50f8b44 100644
--- a/libavcodec/mpeg4video_parser.h
+++ b/libavcodec/mpeg4video_parser.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c
index faa9866..122f5f5 100644
--- a/libavcodec/mpeg4videodec.c
+++ b/libavcodec/mpeg4videodec.c
@@ -3,23 +3,26 @@
  * Copyright (c) 2000,2001 Fabrice Bellard
  * Copyright (c) 2002-2010 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#define UNCHECKED_BITSTREAM_READER 1
+
+#include "libavutil/opt.h"
 #include "mpegvideo.h"
 #include "mpeg4video.h"
 #include "h263.h"
@@ -113,7 +116,7 @@
     int bits_count= get_bits_count(&s->gb);
     int v= show_bits(&s->gb, 16);
 
-    if(s->workaround_bugs&FF_BUG_NO_PADDING){
+    if(s->workaround_bugs&FF_BUG_NO_PADDING && !s->resync_marker){
         return 0;
     }
 
@@ -130,10 +133,11 @@
         v|= 0x7F >> (7-(bits_count&7));
 
         if(v==0x7F)
-            return 1;
+            return s->mb_num;
     }else{
         if(v == ff_mpeg4_resync_prefix[bits_count&7]){
-            int len;
+            int len, mb_num;
+            int mb_num_bits= av_log2(s->mb_num - 1) + 1;
             GetBitContext gb= s->gb;
 
             skip_bits(&s->gb, 1);
@@ -143,16 +147,20 @@
                 if(get_bits1(&s->gb)) break;
             }
 
+            mb_num= get_bits(&s->gb, mb_num_bits);
+            if(!mb_num || mb_num > s->mb_num || get_bits_count(&s->gb)+6 > s->gb.size_in_bits)
+                mb_num= -1;
+
             s->gb= gb;
 
             if(len>=ff_mpeg4_get_video_packet_prefix_length(s))
-                return 1;
+                return mb_num;
         }
     }
     return 0;
 }
 
-static void mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb)
+static int mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb)
 {
     int i;
     int a= 2<<s->sprite_warping_accuracy;
@@ -168,6 +176,9 @@
     int h= s->height;
     int min_ab;
 
+    if(w<=0 || h<=0)
+        return -1;
+
     for(i=0; i<s->num_sprite_warping_points; i++){
         int length;
         int x=0, y=0;
@@ -340,6 +351,7 @@
         }
         s->real_sprite_warping_points= s->num_sprite_warping_points;
     }
+    return 0;
 }
 
 /**
@@ -373,17 +385,6 @@
         av_log(s->avctx, AV_LOG_ERROR, "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num);
         return -1;
     }
-    if(s->pict_type == AV_PICTURE_TYPE_B){
-        int mb_x = 0, mb_y = 0;
-
-        while (s->next_picture.f.mbskip_table[s->mb_index2xy[mb_num]]) {
-            if (!mb_x)
-                ff_thread_await_progress(&s->next_picture_ptr->f, mb_y++, 0);
-            mb_num++;
-            if (++mb_x == s->mb_width) mb_x = 0;
-        }
-        if(mb_num >= s->mb_num) return -1; // slice contains just skipped MBs which where already decoded
-    }
 
     s->mb_x= mb_num % s->mb_width;
     s->mb_y= mb_num / s->mb_width;
@@ -414,7 +415,8 @@
             skip_bits(&s->gb, 3); /* intra dc vlc threshold */
 //FIXME don't just ignore everything
             if(s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){
-                mpeg4_decode_sprite_trajectory(s, &s->gb);
+                if(mpeg4_decode_sprite_trajectory(s, &s->gb) < 0)
+                    return -1;
                 av_log(s->avctx, AV_LOG_ERROR, "untested\n");
             }
 
@@ -521,7 +523,7 @@
 
         if (code > 8){
             if(get_bits1(&s->gb)==0){ /* marker */
-                if(s->err_recognition&AV_EF_BITSTREAM){
+                if(s->err_recognition&(AV_EF_BITSTREAM|AV_EF_COMPLIANT)){
                     av_log(s->avctx, AV_LOG_ERROR, "dc marker bit missing\n");
                     return -1;
                 }
@@ -845,7 +847,7 @@
                               int n, int coded, int intra, int rvlc)
 {
     int level, i, last, run;
-    int dc_pred_dir;
+    int av_uninit(dc_pred_dir);
     RLTable * rl;
     RL_VLC_ELEM * rl_vlc;
     const uint8_t * scan_table;
@@ -991,11 +993,33 @@
                         SKIP_COUNTER(re, &s->gb, 1+12+1);
                     }
 
+#if 0
+                    if(s->error_recognition >= FF_ER_COMPLIANT){
+                        const int abs_level= FFABS(level);
+                        if(abs_level<=MAX_LEVEL && run<=MAX_RUN){
+                            const int run1= run - rl->max_run[last][abs_level] - 1;
+                            if(abs_level <= rl->max_level[last][run]){
+                                av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n");
+                                return -1;
+                            }
+                            if(s->error_recognition > FF_ER_COMPLIANT){
+                                if(abs_level <= rl->max_level[last][run]*2){
+                                    av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 1 encoding possible\n");
+                                    return -1;
+                                }
+                                if(run1 >= 0 && abs_level <= rl->max_level[last][run1]){
+                                    av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 2 encoding possible\n");
+                                    return -1;
+                                }
+                            }
+                        }
+                    }
+#endif
                     if (level>0) level= level * qmul + qadd;
                     else         level= level * qmul - qadd;
 
                     if((unsigned)(level + 2048) > 4095){
-                        if(s->err_recognition & AV_EF_BITSTREAM){
+                        if(s->err_recognition & (AV_EF_BITSTREAM|AV_EF_AGGRESSIVE)){
                             if(level > 2560 || level<-2560){
                                 av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc, qp=%d\n", s->qscale);
                                 return -1;
@@ -1155,7 +1179,7 @@
     static int8_t quant_tab[4] = { -1, -2, 1, 2 };
     const int xy= s->mb_x + s->mb_y * s->mb_stride;
 
-    assert(s->h263_pred);
+    av_assert2(s->h263_pred);
 
     if (s->pict_type == AV_PICTURE_TYPE_P || s->pict_type==AV_PICTURE_TYPE_S) {
         do{
@@ -1467,16 +1491,21 @@
 
         /* per-MB end of slice check */
     if(s->codec_id==AV_CODEC_ID_MPEG4){
-        if(mpeg4_is_resync(s)){
-            const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1;
+        int next= mpeg4_is_resync(s);
+        if(next) {
+            if        (s->mb_x + s->mb_y*s->mb_width + 1 >  next && (s->avctx->err_recognition & AV_EF_AGGRESSIVE)) {
+                return -1;
+            } else if (s->mb_x + s->mb_y*s->mb_width + 1 >= next)
+                return SLICE_END;
 
-            if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta]) {
+            if(s->pict_type==AV_PICTURE_TYPE_B){
+                const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1;
                 ff_thread_await_progress(&s->next_picture_ptr->f,
                                         (s->mb_x + delta >= s->mb_width) ? FFMIN(s->mb_y+1, s->mb_height-1) : s->mb_y, 0);
+                if (s->next_picture.f.mbskip_table[xy + delta])
+                    return SLICE_OK;
             }
 
-            if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta])
-                return SLICE_OK;
             return SLICE_END;
         }
     }
@@ -1487,35 +1516,36 @@
 
 static int mpeg4_decode_gop_header(MpegEncContext * s, GetBitContext *gb){
     int hours, minutes, seconds;
-    unsigned time_code = show_bits(gb, 18);
 
-    if (time_code & 0x40) {     /* marker_bit */
-        hours   = time_code >> 13;
-        minutes = time_code >>  7 & 0x3f;
-        seconds = time_code       & 0x3f;
-        s->time_base = seconds + 60*(minutes + 60*hours);
-        skip_bits(gb, 20);      /* time_code, closed_gov, broken_link */
-    } else {
-        av_log(s->avctx, AV_LOG_WARNING, "GOP header missing marker_bit\n");
+    if(!show_bits(gb, 23)){
+        av_log(s->avctx, AV_LOG_WARNING, "GOP header invalid\n");
+        return -1;
     }
 
+    hours= get_bits(gb, 5);
+    minutes= get_bits(gb, 6);
+    skip_bits1(gb);
+    seconds= get_bits(gb, 6);
+
+    s->time_base= seconds + 60*(minutes + 60*hours);
+
+    skip_bits1(gb);
+    skip_bits1(gb);
+
     return 0;
 }
 
 static int mpeg4_decode_profile_level(MpegEncContext * s, GetBitContext *gb){
-  int profile_and_level_indication;
 
-  profile_and_level_indication = get_bits(gb, 8);
+    s->avctx->profile = get_bits(gb, 4);
+    s->avctx->level   = get_bits(gb, 4);
 
-  s->avctx->profile = (profile_and_level_indication & 0xf0) >> 4;
-  s->avctx->level   = (profile_and_level_indication & 0x0f);
+    // for Simple profile, level 0
+    if (s->avctx->profile == 0 && s->avctx->level == 8) {
+        s->avctx->level = 0;
+    }
 
-  // for Simple profile, level 0
-  if (s->avctx->profile == 0 && s->avctx->level == 8) {
-      s->avctx->level = 0;
-  }
-
-  return 0;
+    return 0;
 }
 
 static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){
@@ -1558,7 +1588,7 @@
             skip_bits1(gb);     /* marker */
         }
     }else{
-        // set low delay flag only once the smartest? low delay detection won't be overriden
+        // set low delay flag only once the smartest? low delay detection won't be overridden
         if(s->picture_number==0)
             s->low_delay=0;
     }
@@ -1647,6 +1677,9 @@
             s->quant_precision = get_bits(gb, 4); /* quant_precision */
             if(get_bits(gb, 4)!=8) av_log(s->avctx, AV_LOG_ERROR, "N-bit not supported\n"); /* bits_per_pixel */
             if(s->quant_precision!=5) av_log(s->avctx, AV_LOG_ERROR, "quant precision %d\n", s->quant_precision);
+            if(s->quant_precision<3 || s->quant_precision>9) {
+                s->quant_precision = 5;
+            }
         } else {
             s->quant_precision = 5;
         }
@@ -1824,6 +1857,18 @@
             // bin shape stuff FIXME
         }
     }
+
+    if(s->avctx->debug&FF_DEBUG_PICT_INFO) {
+        av_log(s->avctx, AV_LOG_DEBUG, "tb %d/%d, tincrbits:%d, qp_prec:%d, ps:%d,  %s%s%s%s\n",
+               s->avctx->time_base.num, s->avctx->time_base.den,
+               s->time_increment_bits,
+               s->quant_precision,
+               s->progressive_sequence,
+               s->scalability ? "scalability " :"" , s->quarter_sample ? "qpel " : "",
+               s->data_partitioning ? "partition " : "", s->rvlc ? "rvlc " : ""
+        );
+    }
+
     return 0;
 }
 
@@ -2008,6 +2053,10 @@
          if(s->pict_type == AV_PICTURE_TYPE_B)
             skip_bits_long(gb, s->cplx_estimation_trash_b);
 
+         if(get_bits_left(gb) < 3) {
+             av_log(s->avctx, AV_LOG_ERROR, "Header truncated\n");
+             return -1;
+         }
          s->intra_dc_threshold= ff_mpeg4_dc_threshold[ get_bits(gb, 3) ];
          if(!s->progressive_sequence){
              s->top_field_first= get_bits1(gb);
@@ -2029,7 +2078,8 @@
      }
 
      if(s->pict_type == AV_PICTURE_TYPE_S && (s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE)){
-         mpeg4_decode_sprite_trajectory(s, gb);
+         if(mpeg4_decode_sprite_trajectory(s, gb) < 0)
+             return -1;
          if(s->sprite_brightness_change) av_log(s->avctx, AV_LOG_ERROR, "sprite_brightness_change not supported\n");
          if(s->vol_sprite_usage==STATIC_SPRITE) av_log(s->avctx, AV_LOG_ERROR, "static sprite not supported\n");
      }
@@ -2045,6 +2095,7 @@
              s->f_code = get_bits(gb, 3);       /* fcode_for */
              if(s->f_code==0){
                  av_log(s->avctx, AV_LOG_ERROR, "Error, header damaged or not MPEG4 header (f_code=0)\n");
+                 s->f_code=1;
                  return -1; // makes no sense to continue, as the MV decoding will break very quickly
              }
          }else
@@ -2052,16 +2103,25 @@
 
          if (s->pict_type == AV_PICTURE_TYPE_B) {
              s->b_code = get_bits(gb, 3);
+             if(s->b_code==0){
+                 av_log(s->avctx, AV_LOG_ERROR, "Error, header damaged or not MPEG4 header (b_code=0)\n");
+                 s->b_code=1;
+                 return -1; // makes no sense to continue, as the MV decoding will break very quickly
+             }
          }else
              s->b_code=1;
 
          if(s->avctx->debug&FF_DEBUG_PICT_INFO){
-             av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d ce:%d/%d/%d\n",
+             av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d ce:%d/%d/%d time:%"PRId64" tincr:%d\n",
                  s->qscale, s->f_code, s->b_code,
                  s->pict_type == AV_PICTURE_TYPE_I ? "I" : (s->pict_type == AV_PICTURE_TYPE_P ? "P" : (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")),
                  gb->size_in_bits,s->progressive_sequence, s->alternate_scan, s->top_field_first,
                  s->quarter_sample ? "q" : "h", s->data_partitioning, s->resync_marker, s->num_sprite_warping_points,
-                 s->sprite_warping_accuracy, 1-s->no_rounding, s->vo_type, s->vol_control_parameters ? " VOLC" : " ", s->intra_dc_threshold, s->cplx_estimation_trash_i, s->cplx_estimation_trash_p, s->cplx_estimation_trash_b);
+                 s->sprite_warping_accuracy, 1-s->no_rounding, s->vo_type, s->vol_control_parameters ? " VOLC" : " ", s->intra_dc_threshold,
+                 s->cplx_estimation_trash_i, s->cplx_estimation_trash_p, s->cplx_estimation_trash_b,
+                 s->time,
+                 time_increment
+                   );
          }
 
          if(!s->scalability){
@@ -2119,8 +2179,8 @@
     startcode = 0xff;
     for(;;) {
         if(get_bits_count(gb) >= gb->size_in_bits){
-            if(gb->size_in_bits==8 && (s->divx_version>=0 || s->xvid_build>=0)){
-                av_log(s->avctx, AV_LOG_WARNING, "frame skip %d\n", gb->size_in_bits);
+            if(gb->size_in_bits==8 && (s->divx_version>=0 || s->xvid_build>=0) || s->codec_tag == AV_RL32("QMP4")){
+                av_log(s->avctx, AV_LOG_VERBOSE, "frame skip %d\n", gb->size_in_bits);
                 return FRAME_SKIPPED; //divx bug
             }else
                 return -1; //end of stream
@@ -2230,7 +2290,7 @@
     }
 
     s->h263_pred = 1;
-    s->low_delay = 0; //default, might be overriden in the vol header during header parsing
+    s->low_delay = 0; //default, might be overridden in the vol header during header parsing
     s->decode_mb= mpeg4_decode_mb;
     s->time_increment_bits = 4; /* default value for broken headers */
     avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
@@ -2255,6 +2315,27 @@
     { FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE, "Advanced Scalable Texture Profile" },
     { FF_PROFILE_MPEG4_SIMPLE_STUDIO,             "Simple Studio Profile" },
     { FF_PROFILE_MPEG4_ADVANCED_SIMPLE,           "Advanced Simple Profile" },
+    { FF_PROFILE_UNKNOWN },
+};
+
+static const AVOption mpeg4_options[] = {
+    {"quarter_sample", "1/4 subpel MC", offsetof(MpegEncContext, quarter_sample), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 1, 0},
+    {"divx_packed", "divx style packed b frames", offsetof(MpegEncContext, divx_packed), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 1, 0},
+    {NULL}
+};
+
+static const AVClass mpeg4_class = {
+    "MPEG4 Video Decoder",
+    av_default_item_name,
+    mpeg4_options,
+    LIBAVUTIL_VERSION_INT,
+};
+
+static const AVClass mpeg4_vdpau_class = {
+    "MPEG4 Video VDPAU Decoder",
+    av_default_item_name,
+    mpeg4_options,
+    LIBAVUTIL_VERSION_INT,
 };
 
 AVCodec ff_mpeg4_decoder = {
@@ -2269,10 +2350,12 @@
                              CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY |
                              CODEC_CAP_FRAME_THREADS,
     .flush                 = ff_mpeg_flush,
+    .max_lowres            = 3,
     .long_name             = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
     .pix_fmts              = ff_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,
 };
 
 
@@ -2290,5 +2373,6 @@
     .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 (VDPAU)"),
     .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_VDPAU_MPEG4,
                                                   AV_PIX_FMT_NONE },
+    .priv_class     = &mpeg4_vdpau_class,
 };
 #endif
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c
index b145eb2..3311506 100644
--- a/libavcodec/mpeg4videoenc.c
+++ b/libavcodec/mpeg4videoenc.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000,2001 Fabrice Bellard
  * Copyright (c) 2002-2010 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -89,7 +89,7 @@
  * @param[in,out] block MB coefficients, these will be restored
  * @param[in] dir ac prediction direction for each 8x8 block
  * @param[out] st scantable for each 8x8 block
- * @param[in] zigzag_last_index index refering to the last non zero coefficient in zigzag order
+ * @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])
 {
@@ -120,7 +120,7 @@
  * @param[in,out] block MB coefficients, these will be updated if 1 is returned
  * @param[in] dir ac prediction direction for each 8x8 block
  * @param[out] st scantable for each 8x8 block
- * @param[out] zigzag_last_index index refering to the last non zero coefficient in zigzag order
+ * @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])
 {
@@ -199,7 +199,7 @@
 }
 
 /**
- * modify mb_type & qscale so that encoding is acually possible in mpeg4
+ * modify mb_type & qscale so that encoding is actually possible in mpeg4
  */
 void ff_clean_mpeg4_qscales(MpegEncContext *s){
     int i;
@@ -494,9 +494,9 @@
                 }
             }
 
-            assert(s->dquant>=-2 && s->dquant<=2);
-            assert((s->dquant&1)==0);
-            assert(mb_type>=0);
+            av_assert2(s->dquant>=-2 && s->dquant<=2);
+            av_assert2((s->dquant&1)==0);
+            av_assert2(mb_type>=0);
 
             /* nothing to do if this MB was skipped in the next P Frame */
             if (s->next_picture.f.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]) { //FIXME avoid DCT & ...
@@ -516,7 +516,7 @@
 
             if ((cbp | motion_x | motion_y | mb_type) ==0) {
                 /* direct MB with MV={0,0} */
-                assert(s->dquant==0);
+                av_assert2(s->dquant==0);
 
                 put_bits(&s->pb, 1, 1); /* mb not coded modb1=1 */
 
@@ -553,12 +553,12 @@
             }
 
             if(mb_type == 0){
-                assert(s->mv_dir & MV_DIRECT);
+                av_assert2(s->mv_dir & MV_DIRECT);
                 ff_h263_encode_motion_vector(s, motion_x, motion_y, 1);
                 s->b_count++;
                 s->f_count++;
             }else{
-                assert(mb_type > 0 && mb_type < 4);
+                av_assert2(mb_type > 0 && mb_type < 4);
                 if(s->mv_type != MV_TYPE_FIELD){
                     if(s->mv_dir & MV_DIR_FORWARD){
                         ff_h263_encode_motion_vector(s, s->mv[0][0][0] - s->last_mv[0][0][0],
@@ -627,8 +627,6 @@
 
                     x= s->mb_x*16;
                     y= s->mb_y*16;
-                    if(x+16 > s->width)  x= s->width-16;
-                    if(y+16 > s->height) y= s->height-16;
 
                     offset= x + y*s->linesize;
                     p_pic = s->new_picture.f.data[0] + offset;
@@ -645,7 +643,21 @@
                         b_pic = pic->f.data[0] + offset;
                         if (pic->f.type != FF_BUFFER_TYPE_SHARED)
                             b_pic+= INPLACE_OFFSET;
-                        diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16);
+
+                        if(x+16 > s->width || y+16 > s->height){
+                            int x1,y1;
+                            int xe= FFMIN(16, s->width - x);
+                            int ye= FFMIN(16, s->height- y);
+                            diff=0;
+                            for(y1=0; y1<ye; y1++){
+                                for(x1=0; x1<xe; x1++){
+                                    diff+= FFABS(p_pic[x1+y1*s->linesize] - b_pic[x1+y1*s->linesize]);
+                                }
+                            }
+                            diff= diff*256/(xe*ye);
+                        }else{
+                            diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16);
+                        }
                         if(diff>s->qscale*70){ //FIXME check that 70 is optimal
                             s->mb_skipped=0;
                             break;
@@ -707,7 +719,7 @@
                 if(s->dquant)
                     put_bits(pb2, 2, dquant_code[s->dquant+2]);
 
-                assert(!s->progressive_sequence);
+                av_assert2(!s->progressive_sequence);
                 if(cbp)
                     put_bits(pb2, 1, s->interlaced_dct);
                 put_bits(pb2, 1, 1);
@@ -728,7 +740,7 @@
                 ff_h263_encode_motion_vector(s, s->mv[0][1][0] - pred_x,
                                                 s->mv[0][1][1] - pred_y, s->f_code);
             }else{
-                assert(s->mv_type==MV_TYPE_8X8);
+                av_assert2(s->mv_type==MV_TYPE_8X8);
                 put_bits(&s->pb,
                         ff_h263_inter_MCBPC_bits[cbpc+16],
                         ff_h263_inter_MCBPC_code[cbpc+16]);
@@ -846,7 +858,7 @@
         ff_mpeg4_init_direct_mv(s);
     }else{
         s->last_time_base= s->time_base;
-        s->time_base= s->time/s->avctx->time_base.den;
+        s->time_base= FFUDIV(s->time, s->avctx->time_base.den);
     }
 }
 
@@ -861,11 +873,12 @@
     if(s->reordered_input_picture[1])
         time = FFMIN(time, s->reordered_input_picture[1]->f.pts);
     time= time*s->avctx->time_base.num;
+    s->last_time_base= FFUDIV(time, s->avctx->time_base.den);
 
-    seconds= time/s->avctx->time_base.den;
-    minutes= seconds/60; seconds %= 60;
-    hours= minutes/60; minutes %= 60;
-    hours%=24;
+    seconds= FFUDIV(time, s->avctx->time_base.den);
+    minutes= FFUDIV(seconds, 60); seconds = FFUMOD(seconds, 60);
+    hours  = FFUDIV(minutes, 60); minutes = FFUMOD(minutes, 60);
+    hours  = FFUMOD(hours  , 24);
 
     put_bits(&s->pb, 5, hours);
     put_bits(&s->pb, 6, minutes);
@@ -875,8 +888,6 @@
     put_bits(&s->pb, 1, !!(s->flags&CODEC_FLAG_CLOSED_GOP));
     put_bits(&s->pb, 1, 0); //broken link == NO
 
-    s->last_time_base= time / s->avctx->time_base.den;
-
     ff_mpeg4_stuffing(&s->pb);
 }
 
@@ -958,6 +969,8 @@
 
     put_bits(&s->pb, 4, s->aspect_ratio_info);/* aspect ratio info */
     if (s->aspect_ratio_info == FF_ASPECT_EXTENDED){
+        av_reduce(&s->avctx->sample_aspect_ratio.num, &s->avctx->sample_aspect_ratio.den,
+                   s->avctx->sample_aspect_ratio.num,  s->avctx->sample_aspect_ratio.den, 255);
         put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.num);
         put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.den);
     }
@@ -1049,11 +1062,10 @@
     put_bits(&s->pb, 16, VOP_STARTCODE);    /* vop header */
     put_bits(&s->pb, 2, s->pict_type - 1);  /* pict type: I = 0 , P = 1 */
 
-    assert(s->time>=0);
-    time_div= s->time/s->avctx->time_base.den;
-    time_mod= s->time%s->avctx->time_base.den;
+    time_div= FFUDIV(s->time, s->avctx->time_base.den);
+    time_mod= FFUMOD(s->time, s->avctx->time_base.den);
     time_incr= time_div - s->last_time_base;
-    assert(time_incr >= 0);
+    av_assert0(time_incr >= 0);
     while(time_incr--)
         put_bits(&s->pb, 1, 1);
 
@@ -1138,8 +1150,8 @@
 static void init_uni_mpeg4_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_tab){
     int slevel, run, last;
 
-    assert(MAX_LEVEL >= 64);
-    assert(MAX_RUN   >= 63);
+    av_assert0(MAX_LEVEL >= 64);
+    av_assert0(MAX_RUN   >= 63);
 
     for(slevel=-64; slevel<64; slevel++){
         if(slevel==0) continue;
diff --git a/libavcodec/mpegaudio.c b/libavcodec/mpegaudio.c
index 1a83635..cba5299 100644
--- a/libavcodec/mpegaudio.c
+++ b/libavcodec/mpegaudio.c
@@ -2,20 +2,20 @@
  * MPEG Audio common code
  * Copyright (c) 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpegaudio.h b/libavcodec/mpegaudio.h
index b556801..b880b7a 100644
--- a/libavcodec/mpegaudio.h
+++ b/libavcodec/mpegaudio.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -52,6 +52,8 @@
 #define WFRAC_BITS  16   /* fractional bits for window */
 #endif
 
+#define IMDCT_SCALAR 1.759
+
 #define FRAC_ONE    (1 << FRAC_BITS)
 
 #define FIX(a)   ((int)((a) * FRAC_ONE))
diff --git a/libavcodec/mpegaudio_parser.c b/libavcodec/mpegaudio_parser.c
index c904873..5f97d71 100644
--- a/libavcodec/mpegaudio_parser.c
+++ b/libavcodec/mpegaudio_parser.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -54,6 +54,7 @@
             int inc= FFMIN(buf_size - i, s->frame_size);
             i += inc;
             s->frame_size -= inc;
+            state = 0;
 
             if(!s->frame_size){
                 next= i;
@@ -76,7 +77,7 @@
                     s->header_count++;
                     s->frame_size = ret-4;
 
-                    if (s->header_count > 0) {
+                    if (s->header_count > 1) {
                         avctx->sample_rate= sr;
                         avctx->channels   = channels;
                         s1->duration      = frame_size;
diff --git a/libavcodec/mpegaudio_tablegen.c b/libavcodec/mpegaudio_tablegen.c
index b4c240b..90c9de4 100644
--- a/libavcodec/mpegaudio_tablegen.c
+++ b/libavcodec/mpegaudio_tablegen.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpegaudio_tablegen.h b/libavcodec/mpegaudio_tablegen.h
index a222f2c..6c15d3c 100644
--- a/libavcodec/mpegaudio_tablegen.h
+++ b/libavcodec/mpegaudio_tablegen.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -39,6 +39,7 @@
 static float expval_table_float[512][16];
 
 #define FRAC_BITS 23
+#define IMDCT_SCALAR 1.759
 
 static void mpegaudio_tableinit(void)
 {
@@ -47,7 +48,7 @@
         double value = i / 4;
         double f, fm;
         int e, m;
-        f  = value * cbrtf(value) * pow(2, (i & 3) * 0.25);
+        f  = value / IMDCT_SCALAR * cbrtf(value) * pow(2, (i & 3) * 0.25);
         fm = frexp(f, &e);
         m  = (uint32_t)(fm * (1LL << 31) + 0.5);
         e += FRAC_BITS - 31 + 5 - 100;
@@ -58,7 +59,7 @@
     }
     for (exponent = 0; exponent < 512; exponent++) {
         for (value = 0; value < 16; value++) {
-            double f = (double)value * cbrtf(value) * pow(2, (exponent - 400) * 0.25 + FRAC_BITS + 5);
+            double f = (double)value * cbrtf(value) * pow(2, (exponent - 400) * 0.25 + FRAC_BITS + 5) / IMDCT_SCALAR;
             expval_table_fixed[exponent][value] = llrint(f);
             expval_table_float[exponent][value] = f;
         }
diff --git a/libavcodec/mpegaudiodata.c b/libavcodec/mpegaudiodata.c
index 009a02a..0569281 100644
--- a/libavcodec/mpegaudiodata.c
+++ b/libavcodec/mpegaudiodata.c
@@ -2,20 +2,20 @@
  * MPEG Audio common tables
  * copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,11 +29,11 @@
 
 const uint16_t avpriv_mpa_bitrate_tab[2][3][15] = {
     { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
-      {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
-      {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } },
-    { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256},
-      {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160},
-      {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
+      {0, 32, 48, 56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, 384 },
+      {0, 32, 40, 48,  56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320 } },
+    { {0, 32, 48, 56,  64,  80,  96, 112, 128, 144, 160, 176, 192, 224, 256},
+      {0,  8, 16, 24,  32,  40,  48,  56,  64,  80,  96, 112, 128, 144, 160},
+      {0,  8, 16, 24,  32,  40,  48,  56,  64,  80,  96, 112, 128, 144, 160}
     }
 };
 
diff --git a/libavcodec/mpegaudiodata.h b/libavcodec/mpegaudiodata.h
index d1a8841..c0d595e 100644
--- a/libavcodec/mpegaudiodata.h
+++ b/libavcodec/mpegaudiodata.h
@@ -2,20 +2,20 @@
  * MPEG Audio common tables
  * copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c
index 80acdad..6ef1f6b 100644
--- a/libavcodec/mpegaudiodec.c
+++ b/libavcodec/mpegaudiodec.c
@@ -2,20 +2,20 @@
  * MPEG Audio decoder
  * Copyright (c) 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,8 @@
  */
 
 #include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
+#include "libavutil/libm.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "mathops.h"
@@ -203,6 +205,8 @@
 {
     if (g->block_type == 2) {
         if (g->switch_point) {
+            if(s->sample_rate_index == 8)
+                av_log_ask_for_sample(s->avctx, "switch point in 8khz\n");
             /* if switched mode, we handle the 36 first samples as
                 long blocks.  For 8000Hz, we handle the 72 first
                 exponents as long blocks */
@@ -262,7 +266,10 @@
     e  = table_4_3_exp  [4 * value + (exponent & 3)];
     m  = table_4_3_value[4 * value + (exponent & 3)];
     e -= exponent >> 2;
-    assert(e >= 1);
+#ifdef DEBUG
+    if(e < 1)
+        av_log(0, AV_LOG_WARNING, "l3_unscale: e is %d\n", e);
+#endif
     if (e > 31)
         return 0;
     m = (m + (1 << (e - 1))) >> e;
@@ -326,7 +333,7 @@
                  INIT_VLC_USE_NEW_STATIC);
         offset += huff_vlc_tables_sizes[i];
     }
-    assert(offset == FF_ARRAY_ELEMS(huff_vlc_tables));
+    av_assert0(offset == FF_ARRAY_ELEMS(huff_vlc_tables));
 
     offset = 0;
     for (i = 0; i < 2; i++) {
@@ -337,7 +344,7 @@
                  INIT_VLC_USE_NEW_STATIC);
         offset += huff_quad_vlc_tables_sizes[i];
     }
-    assert(offset == FF_ARRAY_ELEMS(huff_quad_vlc_tables));
+    av_assert0(offset == FF_ARRAY_ELEMS(huff_quad_vlc_tables));
 
     for (i = 0; i < 9; i++) {
         k = 0;
@@ -390,7 +397,7 @@
 
         for (j = 0; j < 2; j++) {
             e = -(j + 1) * ((i + 1) >> 1);
-            f = pow(2.0, e / 4.0);
+            f = exp2(e / 4.0);
             k = i & 1;
             is_table_lsf[j][k ^ 1][i] = FIXR(f);
             is_table_lsf[j][k    ][i] = FIXR(1.0);
@@ -826,7 +833,7 @@
     if (s->in_gb.buffer && *pos >= s->gb.size_in_bits) {
         s->gb           = s->in_gb;
         s->in_gb.buffer = NULL;
-        assert((get_bits_count(&s->gb) & 7) == 0);
+        av_assert2((get_bits_count(&s->gb) & 7) == 0);
         skip_bits_long(&s->gb, *pos - *end_pos);
         *end_pos2 =
         *end_pos  = *end_pos2 + get_bits_count(&s->gb) - *pos;
@@ -955,7 +962,7 @@
                 s_index -= 4;
                 skip_bits_long(&s->gb, last_pos - pos);
                 av_log(s->avctx, AV_LOG_INFO, "overread, skip %d enddists: %d %d\n", last_pos - pos, end_pos-pos, end_pos2-pos);
-                if(s->err_recognition & AV_EF_BITSTREAM)
+                if(s->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))
                     s_index=0;
                 break;
             }
@@ -982,10 +989,10 @@
     }
     /* skip extension bits */
     bits_left = end_pos2 - get_bits_count(&s->gb);
-    if (bits_left < 0 && (s->err_recognition & AV_EF_BUFFER)) {
+    if (bits_left < 0 && (s->err_recognition & (AV_EF_BUFFER|AV_EF_COMPLIANT))) {
         av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
         s_index=0;
-    } else if (bits_left > 0 && (s->err_recognition & AV_EF_BUFFER)) {
+    } else if (bits_left > 0 && (s->err_recognition & (AV_EF_BUFFER|AV_EF_AGGRESSIVE))) {
         av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
         s_index = 0;
     }
@@ -1165,6 +1172,17 @@
 }
 
 #if CONFIG_FLOAT
+#if HAVE_MIPSFPU
+#   include "mips/compute_antialias_float.h"
+#endif /* HAVE_MIPSFPU */
+#else
+#if HAVE_MIPSDSPR1
+#   include "mips/compute_antialias_fixed.h"
+#endif /* HAVE_MIPSDSPR1 */
+#endif /* CONFIG_FLOAT */
+
+#ifndef compute_antialias
+#if CONFIG_FLOAT
 #define AA(j) do {                                                      \
         float tmp0 = ptr[-1-j];                                         \
         float tmp1 = ptr[   j];                                         \
@@ -1210,6 +1228,7 @@
         ptr += 18;
     }
 }
+#endif /* compute_antialias */
 
 static void compute_imdct(MPADecodeContext *s, GranuleDef *g,
                           INTFLOAT *sb_samples, INTFLOAT *mdct_buf)
@@ -1379,9 +1398,8 @@
     if (!s->adu_mode) {
         int skip;
         const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3);
-        int extrasize = av_clip(get_bits_left(&s->gb) >> 3, 0,
-                                FFMAX(0, LAST_BUF_SIZE - s->last_buf_size));
-        assert((get_bits_count(&s->gb) & 7) == 0);
+        int extrasize = av_clip(get_bits_left(&s->gb) >> 3, 0, EXTRABYTES);
+        av_assert1((get_bits_count(&s->gb) & 7) == 0);
         /* now we get bits from the main_data_begin offset */
         av_dlog(s->avctx, "seekback:%d, lastbuf:%d\n",
                 main_data_begin, s->last_buf_size);
@@ -1390,7 +1408,7 @@
         s->in_gb = s->gb;
         init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8);
 #if !UNCHECKED_BITSTREAM_READER
-        s->gb.size_in_bits_plus8 += extrasize * 8;
+        s->gb.size_in_bits_plus8 += FFMAX(extrasize, LAST_BUF_SIZE - s->last_buf_size) * 8;
 #endif
         s->last_buf_size <<= 3;
         for (gr = 0; gr < nb_granules && (s->last_buf_size >> 3) < main_data_begin; gr++) {
@@ -1585,7 +1603,7 @@
         }
 
         align_get_bits(&s->gb);
-        assert((get_bits_count(&s->gb) & 7) == 0);
+        av_assert1((get_bits_count(&s->gb) & 7) == 0);
         i = get_bits_left(&s->gb) >> 3;
 
         if (i < 0 || i > BACKSTEP_SIZE || nb_frames < 0) {
@@ -1593,7 +1611,7 @@
                 av_log(s->avctx, AV_LOG_ERROR, "invalid new backstep %d\n", i);
             i = FFMIN(BACKSTEP_SIZE, buf_size - HEADER_SIZE);
         }
-        assert(i <= buf_size - HEADER_SIZE && i >= 0);
+        av_assert1(i <= buf_size - HEADER_SIZE && i >= 0);
         memcpy(s->last_buf + s->last_buf_size, s->gb.buffer + buf_size - HEADER_SIZE - i, i);
         s->last_buf_size += i;
     }
@@ -1634,10 +1652,19 @@
     uint32_t header;
     int out_size;
 
+    while(buf_size && !*buf){
+        buf++;
+        buf_size--;
+    }
+
     if (buf_size < HEADER_SIZE)
         return AVERROR_INVALIDDATA;
 
     header = AV_RB32(buf);
+    if (header>>8 == AV_RB32("TAG")>>8) {
+        av_log(avctx, AV_LOG_DEBUG, "discarding ID3 tag\n");
+        return buf_size;
+    }
     if (ff_mpa_check_header(header) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Header missing\n");
         return AVERROR_INVALIDDATA;
@@ -1658,6 +1685,7 @@
         av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");
         return AVERROR_INVALIDDATA;
     } else if (s->frame_size < buf_size) {
+        av_log(avctx, AV_LOG_DEBUG, "incorrect frame size - multiple frames in buffer?\n");
         buf_size= s->frame_size;
     }
 
@@ -1696,7 +1724,8 @@
     int buf_size        = avpkt->size;
     MPADecodeContext *s = avctx->priv_data;
     uint32_t header;
-    int len, out_size;
+    int len;
+    int av_unused out_size;
 
     len = buf_size;
 
@@ -1897,7 +1926,7 @@
     int fr, j, n, ch, ret;
 
     /* get output buffer */
-    s->frame->nb_samples = MPA_FRAME_SIZE;
+    s->frame->nb_samples = s->frames * MPA_FRAME_SIZE;
     if ((ret = avctx->get_buffer(avctx, s->frame)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
@@ -1918,7 +1947,7 @@
         fsize = AV_RB16(buf) >> 4;
         fsize = FFMIN3(fsize, len, MPA_MAX_CODED_FRAME_SIZE);
         m     = s->mp3decctx[fr];
-        assert(m != NULL);
+        av_assert1(m);
 
         if (fsize < HEADER_SIZE) {
             av_log(avctx, AV_LOG_ERROR, "Frame size smaller than header size\n");
diff --git a/libavcodec/mpegaudiodec_float.c b/libavcodec/mpegaudiodec_float.c
index 93468f5..e26a0a9 100644
--- a/libavcodec/mpegaudiodec_float.c
+++ b/libavcodec/mpegaudiodec_float.c
@@ -2,20 +2,20 @@
  * Float MPEG Audio decoder
  * Copyright (c) 2010 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpegaudiodecheader.c b/libavcodec/mpegaudiodecheader.c
index f8fc833..7841b30 100644
--- a/libavcodec/mpegaudiodecheader.c
+++ b/libavcodec/mpegaudiodecheader.c
@@ -2,20 +2,20 @@
  * MPEG Audio header decoder
  * Copyright (c) 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpegaudiodecheader.h b/libavcodec/mpegaudiodecheader.h
index 764e8ab..c434d00 100644
--- a/libavcodec/mpegaudiodecheader.h
+++ b/libavcodec/mpegaudiodecheader.h
@@ -2,20 +2,20 @@
  * MPEG Audio header decoder
  * Copyright (c) 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpegaudiodectab.h b/libavcodec/mpegaudiodectab.h
index 1221657..accd12b 100644
--- a/libavcodec/mpegaudiodectab.h
+++ b/libavcodec/mpegaudiodectab.h
@@ -2,20 +2,20 @@
  * MPEG Audio decoder
  * copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpegaudiodsp.c b/libavcodec/mpegaudiodsp.c
index cd9371b..aadc747 100644
--- a/libavcodec/mpegaudiodsp.c
+++ b/libavcodec/mpegaudiodsp.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2011 Mans Rullgard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -43,4 +43,6 @@
     if (ARCH_ARM)     ff_mpadsp_init_arm(s);
     if (ARCH_X86)     ff_mpadsp_init_x86(s);
     if (HAVE_ALTIVEC) ff_mpadsp_init_altivec(s);
+    if (HAVE_MIPSFPU)   ff_mpadsp_init_mipsfpu(s);
+    if (HAVE_MIPSDSPR1) ff_mpadsp_init_mipsdspr1(s);
 }
diff --git a/libavcodec/mpegaudiodsp.h b/libavcodec/mpegaudiodsp.h
index 1f85a15..623d2df 100644
--- a/libavcodec/mpegaudiodsp.h
+++ b/libavcodec/mpegaudiodsp.h
@@ -29,6 +29,7 @@
                                int *dither_state, int16_t *samples, int incr);
     void (*dct32_float)(float *dst, const float *src);
     void (*dct32_fixed)(int *dst, const int *src);
+
     void (*imdct36_blocks_float)(float *out, float *buf, float *in,
                                  int count, int switch_point, int block_type);
     void (*imdct36_blocks_fixed)(int *out, int *buf, int *in,
@@ -57,6 +58,8 @@
 void ff_mpadsp_init_arm(MPADSPContext *s);
 void ff_mpadsp_init_x86(MPADSPContext *s);
 void ff_mpadsp_init_altivec(MPADSPContext *s);
+void ff_mpadsp_init_mipsfpu(MPADSPContext *s);
+void ff_mpadsp_init_mipsdspr1(MPADSPContext *s);
 
 void ff_mpa_synth_init_float(float *window);
 void ff_mpa_synth_init_fixed(int32_t *window);
diff --git a/libavcodec/mpegaudiodsp_data.c b/libavcodec/mpegaudiodsp_data.c
index 5cf86b8..4550de9 100644
--- a/libavcodec/mpegaudiodsp_data.c
+++ b/libavcodec/mpegaudiodsp_data.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpegaudiodsp_template.c b/libavcodec/mpegaudiodsp_template.c
index e7a7656..03a740a 100644
--- a/libavcodec/mpegaudiodsp_template.c
+++ b/libavcodec/mpegaudiodsp_template.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -242,7 +242,7 @@
                 else if (i <  18) d = 1;
             }
             //merge last stage of imdct into the window coefficients
-            d *= 0.5 / cos(M_PI * (2 * i + 19) / 72);
+            d *= 0.5 * IMDCT_SCALAR / cos(M_PI * (2 * i + 19) / 72);
 
             if (j == 2)
                 RENAME(ff_mdct_win)[j][i/3] = FIXHR((d / (1<<5)));
@@ -397,3 +397,4 @@
         out++;
     }
 }
+
diff --git a/libavcodec/mpegaudioenc.c b/libavcodec/mpegaudioenc.c
index ab9e0fa..806cb21 100644
--- a/libavcodec/mpegaudioenc.c
+++ b/libavcodec/mpegaudioenc.c
@@ -2,20 +2,20 @@
  * The simplest mpeg audio layer 2 encoder
  * Copyright (c) 2000, 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -148,16 +148,16 @@
     }
 
     for(i=0;i<64;i++) {
-        v = (int)(pow(2.0, (3 - i) / 3.0) * (1 << 20));
+        v = (int)(exp2((3 - i) / 3.0) * (1 << 20));
         if (v <= 0)
             v = 1;
         scale_factor_table[i] = v;
 #ifdef USE_FLOATS
-        scale_factor_inv_table[i] = pow(2.0, -(3 - i) / 3.0) / (float)(1 << 20);
+        scale_factor_inv_table[i] = exp2(-(3 - i) / 3.0) / (float)(1 << 20);
 #else
 #define P 15
         scale_factor_shift[i] = 21 - P - (i / 3);
-        scale_factor_mult[i] = (1 << P) * pow(2.0, (i % 3) / 3.0);
+        scale_factor_mult[i] = (1 << P) * exp2((i % 3) / 3.0);
 #endif
     }
     for(i=0;i<128;i++) {
@@ -407,7 +407,7 @@
             av_dlog(NULL, "%2d:%d in=%x %x %d\n",
                     j, i, vmax, scale_factor_table[index], index);
             /* store the scale factor */
-            assert(index >=0 && index <= 63);
+            av_assert2(index >=0 && index <= 63);
             sf[i] = index;
         }
 
@@ -469,7 +469,7 @@
             sf[1] = sf[2] = sf[0];
             break;
         default:
-            assert(0); //cannot happen
+            av_assert2(0); //cannot happen
             code = 0;           /* kill warning */
         }
 
@@ -589,7 +589,7 @@
         }
     }
     *padding = max_frame_size - current_frame_size;
-    assert(*padding >= 0);
+    av_assert0(*padding >= 0);
 }
 
 /*
@@ -704,7 +704,7 @@
 #endif
                             if (q[m] >= steps)
                                 q[m] = steps - 1;
-                            assert(q[m] >= 0 && q[m] < steps);
+                            av_assert2(q[m] >= 0 && q[m] < steps);
                         }
                         bits = ff_mpa_quant_bits[qindex];
                         if (bits < 0) {
@@ -754,10 +754,8 @@
     }
     compute_bit_allocation(s, smr, bit_alloc, &padding);
 
-    if ((ret = ff_alloc_packet(avpkt, MPA_MAX_CODED_FRAME_SIZE))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, MPA_MAX_CODED_FRAME_SIZE)))
         return ret;
-    }
 
     init_put_bits(&s->pb, avpkt->data, avpkt->size);
 
diff --git a/libavcodec/mpegaudiotab.h b/libavcodec/mpegaudiotab.h
index 45afe9b..35129e6 100644
--- a/libavcodec/mpegaudiotab.h
+++ b/libavcodec/mpegaudiotab.h
@@ -4,20 +4,20 @@
  *
  * Copyright (c) 2000, 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 2470d6d..2fe2c91 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -5,20 +5,20 @@
  *
  * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -138,9 +138,9 @@
     AV_PIX_FMT_NONE
 };
 
-const uint8_t *avpriv_mpv_find_start_code(const uint8_t *restrict p,
+const uint8_t *avpriv_mpv_find_start_code(const uint8_t *av_restrict p,
                                           const uint8_t *end,
-                                          uint32_t * restrict state)
+                                          uint32_t *av_restrict state)
 {
     int i;
 
@@ -424,12 +424,12 @@
     // 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 + 64) * 2 * 21 * 2, fail);    // (width + edge + align)*interlaced*MBsize*tolerance
+                      (s->width + 95) * 2 * 21 * 4, fail);    // (width + edge + align)*interlaced*MBsize*tolerance
 
     // 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 + 64) * 4 * 16 * 2 * sizeof(uint8_t), fail)
+                      (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;
@@ -534,7 +534,7 @@
     int i;
     MpegEncContext *s = dst->priv_data, *s1 = src->priv_data;
 
-    if (dst == src || !s1->context_initialized)
+    if (dst == src)
         return 0;
 
     // FIXME can parameters change on I-frames?
@@ -543,12 +543,14 @@
         memcpy(s, s1, sizeof(MpegEncContext));
 
         s->avctx                 = dst;
-        s->picture_range_start  += MAX_PICTURE_COUNT;
-        s->picture_range_end    += MAX_PICTURE_COUNT;
         s->bitstream_buffer      = NULL;
         s->bitstream_buffer_size = s->allocated_bitstream_buffer_size = 0;
 
-        ff_MPV_common_init(s);
+        if (s1->context_initialized){
+            s->picture_range_start  += MAX_PICTURE_COUNT;
+            s->picture_range_end    += MAX_PICTURE_COUNT;
+            ff_MPV_common_init(s);
+        }
     }
 
     if (s->height != s1->height || s->width != s1->width || s->context_reinit) {
@@ -584,6 +586,7 @@
     // Error/bug resilience
     s->next_p_frame_damaged = s1->next_p_frame_damaged;
     s->workaround_bugs      = s1->workaround_bugs;
+    s->padding_bug_score    = s1->padding_bug_score;
 
     // MPEG4 timing info
     memcpy(&s->time_increment_bits, &s1->time_increment_bits,
@@ -699,44 +702,32 @@
     c_size  = s->mb_stride * (s->mb_height + 1);
     yc_size = y_size + 2   * c_size;
 
-    FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_index2xy, (s->mb_num + 1) * sizeof(int),
-                      fail); // error ressilience code looks cleaner with this
+    FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_index2xy, (s->mb_num + 1) * sizeof(int), fail); // error ressilience code looks cleaner with this
     for (y = 0; y < s->mb_height; y++)
         for (x = 0; x < s->mb_width; x++)
             s->mb_index2xy[x + y * s->mb_width] = x + y * s->mb_stride;
 
-    s->mb_index2xy[s->mb_height * s->mb_width] =
-        (s->mb_height - 1) * s->mb_stride + s->mb_width; // FIXME really needed?
+    s->mb_index2xy[s->mb_height * s->mb_width] = (s->mb_height - 1) * s->mb_stride + s->mb_width; // FIXME really needed?
 
     if (s->encoding) {
         /* Allocate MV tables */
-        FF_ALLOCZ_OR_GOTO(s->avctx, s->p_mv_table_base,
-                          mv_table_size * 2 * sizeof(int16_t), fail);
-        FF_ALLOCZ_OR_GOTO(s->avctx, s->b_forw_mv_table_base,
-                          mv_table_size * 2 * sizeof(int16_t), fail);
-        FF_ALLOCZ_OR_GOTO(s->avctx, s->b_back_mv_table_base,
-                          mv_table_size * 2 * sizeof(int16_t), fail);
-        FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_forw_mv_table_base,
-                          mv_table_size * 2 * sizeof(int16_t), fail);
-        FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_back_mv_table_base,
-                          mv_table_size * 2 * sizeof(int16_t), fail);
-        FF_ALLOCZ_OR_GOTO(s->avctx, s->b_direct_mv_table_base,
-                          mv_table_size * 2 * sizeof(int16_t), fail);
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->p_mv_table_base,                 mv_table_size * 2 * sizeof(int16_t), fail)
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->b_forw_mv_table_base,            mv_table_size * 2 * sizeof(int16_t), fail)
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->b_back_mv_table_base,            mv_table_size * 2 * sizeof(int16_t), fail)
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_forw_mv_table_base,      mv_table_size * 2 * sizeof(int16_t), fail)
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->b_bidir_back_mv_table_base,      mv_table_size * 2 * sizeof(int16_t), fail)
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->b_direct_mv_table_base,          mv_table_size * 2 * sizeof(int16_t), fail)
         s->p_mv_table            = s->p_mv_table_base + s->mb_stride + 1;
         s->b_forw_mv_table       = s->b_forw_mv_table_base + s->mb_stride + 1;
         s->b_back_mv_table       = s->b_back_mv_table_base + s->mb_stride + 1;
-        s->b_bidir_forw_mv_table = s->b_bidir_forw_mv_table_base +
-                                   s->mb_stride + 1;
-        s->b_bidir_back_mv_table = s->b_bidir_back_mv_table_base +
-                                   s->mb_stride + 1;
+        s->b_bidir_forw_mv_table = s->b_bidir_forw_mv_table_base + s->mb_stride + 1;
+        s->b_bidir_back_mv_table = s->b_bidir_back_mv_table_base + s->mb_stride + 1;
         s->b_direct_mv_table     = s->b_direct_mv_table_base + s->mb_stride + 1;
 
         /* Allocate MB type table */
-        FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_type, mb_array_size *
-                          sizeof(uint16_t), fail); // needed for encoding
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_type, mb_array_size * sizeof(uint16_t), fail) // needed for encoding
 
-        FF_ALLOCZ_OR_GOTO(s->avctx, s->lambda_table, mb_array_size *
-                          sizeof(int), fail);
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->lambda_table, mb_array_size * sizeof(int), fail)
 
         FF_ALLOC_OR_GOTO(s->avctx, s->cplx_tab,
                          mb_array_size * sizeof(float), fail);
@@ -750,8 +741,7 @@
     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;
@@ -764,15 +754,11 @@
                     s->b_field_mv_table[i][j][k] = s->b_field_mv_table_base[i][j][k] +
                                                    s->mb_stride + 1;
                 }
-                FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_select_table [i][j],
-                                  mb_array_size * 2 * sizeof(uint8_t), fail);
-                FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_mv_table_base[i][j],
-                                  mv_table_size * 2 * sizeof(int16_t), fail);
-                s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j]
-                                            + s->mb_stride + 1;
+                FF_ALLOCZ_OR_GOTO(s->avctx, s->b_field_select_table [i][j], mb_array_size * 2 * sizeof(uint8_t), fail)
+                FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_mv_table_base[i][j], mv_table_size * 2 * sizeof(int16_t), fail)
+                s->p_field_mv_table[i][j] = s->p_field_mv_table_base[i][j] + s->mb_stride + 1;
             }
-            FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_select_table[i],
-                              mb_array_size * 2 * sizeof(uint8_t), fail);
+            FF_ALLOCZ_OR_GOTO(s->avctx, s->p_field_select_table[i], mb_array_size * 2 * sizeof(uint8_t), fail)
         }
     }
     if (s->out_format == FMT_H263) {
@@ -781,17 +767,14 @@
         s->coded_block = s->coded_block_base + s->b8_stride + 1;
 
         /* cbp, ac_pred, pred_dir */
-        FF_ALLOCZ_OR_GOTO(s->avctx, s->cbp_table,
-                          mb_array_size * sizeof(uint8_t), fail);
-        FF_ALLOCZ_OR_GOTO(s->avctx, s->pred_dir_table,
-                          mb_array_size * sizeof(uint8_t), fail);
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->cbp_table     , mb_array_size * sizeof(uint8_t), fail);
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->pred_dir_table, mb_array_size * sizeof(uint8_t), fail);
     }
 
     if (s->h263_pred || s->h263_plus || !s->encoding) {
         /* dc values */
         // MN: we need these for  error resilience of intra-frames
-        FF_ALLOCZ_OR_GOTO(s->avctx, s->dc_val_base,
-                          yc_size * sizeof(int16_t), fail);
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->dc_val_base, yc_size * sizeof(int16_t), fail);
         s->dc_val[0] = s->dc_val_base + s->b8_stride + 1;
         s->dc_val[1] = s->dc_val_base + y_size + s->mb_stride + 1;
         s->dc_val[2] = s->dc_val[1] + c_size;
@@ -807,16 +790,6 @@
     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
 
-    if ((s->avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) ||
-        s->avctx->debug_mv) {
-        s->visualization_buffer[0] = av_malloc((s->mb_width * 16 +
-                    2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
-        s->visualization_buffer[1] = av_malloc((s->mb_width * 16 +
-                    2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
-        s->visualization_buffer[2] = av_malloc((s->mb_width * 16 +
-                    2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
-    }
-
     return 0;
 fail:
     return AVERROR(ENOMEM);
@@ -867,43 +840,35 @@
     s->flags  = s->avctx->flags;
     s->flags2 = s->avctx->flags2;
 
-    if (s->width && s->height) {
         /* set chroma shifts */
         avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &s->chroma_x_shift,
                                       &s->chroma_y_shift);
 
-        /* convert fourcc to upper case */
-        s->codec_tag          = avpriv_toupper4(s->avctx->codec_tag);
+    /* convert fourcc to upper case */
+    s->codec_tag        = avpriv_toupper4(s->avctx->codec_tag);
+    s->stream_codec_tag = avpriv_toupper4(s->avctx->stream_codec_tag);
 
-        s->stream_codec_tag   = avpriv_toupper4(s->avctx->stream_codec_tag);
+    s->avctx->coded_frame = &s->current_picture.f;
 
-        s->avctx->coded_frame = &s->current_picture.f;
+    if (s->encoding) {
+        if (s->msmpeg4_version) {
+            FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_stats,
+                                2 * 2 * (MAX_LEVEL + 1) *
+                                (MAX_RUN + 1) * 2 * sizeof(int), fail);
+        }
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->avctx->stats_out, 256, fail);
 
-        if (s->encoding) {
-            if (s->msmpeg4_version) {
-                FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_stats,
-                                  2 * 2 * (MAX_LEVEL + 1) *
-                                  (MAX_RUN + 1) * 2 * sizeof(int), fail);
-            }
-            FF_ALLOCZ_OR_GOTO(s->avctx, s->avctx->stats_out, 256, fail);
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix,          64 * 32   * sizeof(int), fail)
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix,   64 * 32   * sizeof(int), fail)
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix,          64 * 32   * sizeof(int), fail)
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix16,        64 * 32 * 2 * sizeof(uint16_t), fail)
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->q_chroma_intra_matrix16, 64 * 32 * 2 * sizeof(uint16_t), fail)
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix16,        64 * 32 * 2 * sizeof(uint16_t), fail)
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->input_picture,           MAX_PICTURE_COUNT * sizeof(Picture *), fail)
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->reordered_input_picture, MAX_PICTURE_COUNT * sizeof(Picture *), fail)
 
-            FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix,
-                              64 * 32   * sizeof(int), fail);
-            FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix,
-                              64 * 32   * sizeof(int), fail);
-            FF_ALLOCZ_OR_GOTO(s->avctx, s->q_intra_matrix16,
-                              64 * 32 * 2 * sizeof(uint16_t), fail);
-            FF_ALLOCZ_OR_GOTO(s->avctx, s->q_inter_matrix16,
-                              64 * 32 * 2 * sizeof(uint16_t), fail);
-            FF_ALLOCZ_OR_GOTO(s->avctx, s->input_picture,
-                              MAX_PICTURE_COUNT * sizeof(Picture *), fail);
-            FF_ALLOCZ_OR_GOTO(s->avctx, s->reordered_input_picture,
-                              MAX_PICTURE_COUNT * sizeof(Picture *), fail);
-
-            if (s->avctx->noise_reduction) {
-                FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset,
-                                  2 * 64 * sizeof(uint16_t), fail);
-            }
+        if (s->avctx->noise_reduction) {
+            FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_offset, 2 * 64 * sizeof(uint16_t), fail);
         }
     }
 
@@ -914,17 +879,15 @@
         avcodec_get_frame_defaults(&s->picture[i].f);
     }
 
-    if (s->width && s->height) {
         if ((err = init_context_frame(s)))
             goto fail;
 
         s->parse_context.state = -1;
-    }
 
-    s->context_initialized = 1;
-    s->thread_context[0]   = s;
+        s->context_initialized = 1;
+        s->thread_context[0]   = s;
 
-    if (s->width && s->height) {
+//     if (s->width && s->height) {
         if (nb_slices > 1) {
             for (i = 1; i < nb_slices; i++) {
                 s->thread_context[i] = av_malloc(sizeof(MpegEncContext));
@@ -946,7 +909,7 @@
             s->end_mb_y   = s->mb_height;
         }
         s->slice_context_count = nb_slices;
-    }
+//     }
 
     return 0;
  fail:
@@ -1001,6 +964,7 @@
     av_freep(&s->er_temp_buffer);
     av_freep(&s->mb_index2xy);
     av_freep(&s->lambda_table);
+
     av_freep(&s->cplx_tab);
     av_freep(&s->bits_tab);
 
@@ -1110,6 +1074,10 @@
     av_freep(&s->avctx->stats_out);
     av_freep(&s->ac_stats);
 
+    if(s->q_chroma_intra_matrix   != s->q_intra_matrix  ) av_freep(&s->q_chroma_intra_matrix);
+    if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16);
+    s->q_chroma_intra_matrix=   NULL;
+    s->q_chroma_intra_matrix16= NULL;
     av_freep(&s->q_intra_matrix);
     av_freep(&s->q_inter_matrix);
     av_freep(&s->q_intra_matrix16);
@@ -1271,7 +1239,21 @@
         }
     }
 
-    return AVERROR_INVALIDDATA;
+    av_log(s->avctx, AV_LOG_FATAL,
+           "Internal error, picture buffer overflow\n");
+    /* We could return -1, but the codec would crash trying to draw into a
+     * non-existing frame anyway. This is safer than waiting for a random crash.
+     * Also the return of this is never useful, an encoder must only allocate
+     * as much as allowed in the specification. This has no relationship to how
+     * much libavcodec could allocate (and MAX_PICTURE_COUNT is always large
+     * enough for such valid streams).
+     * Plus, a decoder has to check stream validity and remove frames if too
+     * many reference frames are around. Waiting for "OOM" is not correct at
+     * all. Similarly, missing reference frames have to be replaced by
+     * interpolated/MC frames, anything else is a bug in the codec ...
+     */
+    abort();
+    return -1;
 }
 
 int ff_find_unused_picture(MpegEncContext *s, int shared)
@@ -1319,6 +1301,11 @@
     Picture *pic;
     s->mb_skipped = 0;
 
+    if (!ff_thread_can_start_frame(avctx)) {
+        av_log(avctx, AV_LOG_ERROR, "Attempt to start a frame outside SETUP state\n");
+        return -1;
+    }
+
     /* mark & release old frames */
     if (s->out_format != FMT_H264 || s->codec_id == AV_CODEC_ID_SVQ3) {
         if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr &&
@@ -1427,10 +1414,17 @@
                 return i;
             }
             s->last_picture_ptr = &s->picture[i];
+            s->last_picture_ptr->f.key_frame = 0;
             if (ff_alloc_picture(s, s->last_picture_ptr, 0) < 0) {
                 s->last_picture_ptr = NULL;
                 return -1;
             }
+
+            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);
+            }
+
             ff_thread_report_progress(&s->last_picture_ptr->f, INT_MAX, 0);
             ff_thread_report_progress(&s->last_picture_ptr->f, INT_MAX, 1);
             s->last_picture_ptr->f.reference = 3;
@@ -1445,6 +1439,7 @@
                 return i;
             }
             s->next_picture_ptr = &s->picture[i];
+            s->next_picture_ptr->f.key_frame = 0;
             if (ff_alloc_picture(s, s->next_picture_ptr, 0) < 0) {
                 s->next_picture_ptr = NULL;
                 return -1;
@@ -1520,28 +1515,30 @@
     // 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) &&
+   } else if((s->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 &&
               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);
-       int hshift = desc->log2_chroma_w;
-       int vshift = desc->log2_chroma_h;
-       s->dsp.draw_edges(s->current_picture.f.data[0], s->linesize,
-                         s->h_edge_pos, s->v_edge_pos,
-                         EDGE_WIDTH, EDGE_WIDTH,
-                         EDGE_TOP | EDGE_BOTTOM);
-       s->dsp.draw_edges(s->current_picture.f.data[1], s->uvlinesize,
-                         s->h_edge_pos >> hshift, s->v_edge_pos >> vshift,
-                         EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
-                         EDGE_TOP | EDGE_BOTTOM);
-       s->dsp.draw_edges(s->current_picture.f.data[2], s->uvlinesize,
-                         s->h_edge_pos >> hshift, s->v_edge_pos >> vshift,
-                         EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
-                         EDGE_TOP | EDGE_BOTTOM);
+              !(s->flags & CODEC_FLAG_EMU_EDGE) &&
+              !s->avctx->lowres
+            ) {
+        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
+        int hshift = desc->log2_chroma_w;
+        int vshift = desc->log2_chroma_h;
+        s->dsp.draw_edges(s->current_picture.f.data[0], s->current_picture.f.linesize[0],
+                          s->h_edge_pos, s->v_edge_pos,
+                          EDGE_WIDTH, EDGE_WIDTH,
+                          EDGE_TOP | EDGE_BOTTOM);
+        s->dsp.draw_edges(s->current_picture.f.data[1], s->current_picture.f.linesize[1],
+                          s->h_edge_pos >> hshift, s->v_edge_pos >> vshift,
+                          EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
+                          EDGE_TOP | EDGE_BOTTOM);
+        s->dsp.draw_edges(s->current_picture.f.data[2], s->current_picture.f.linesize[2],
+                          s->h_edge_pos >> hshift, s->v_edge_pos >> vshift,
+                          EDGE_WIDTH >> hshift, EDGE_WIDTH >> vshift,
+                          EDGE_TOP | EDGE_BOTTOM);
     }
 
     emms_c();
@@ -1611,11 +1608,11 @@
         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;
-            buf[(y + 1) * stride + x] += (color *            fr ) >> 16;
+            if(fr) buf[(y + 1) * stride + x] += (color *            fr ) >> 16;
         }
     } else {
         if (sy > ey) {
@@ -1625,14 +1622,14 @@
         buf += sx + sy * stride;
         ey  -= sy;
         if (ey)
-            f  = ((ex - sx) << 16) / ey;
+            f = ((ex - sx) << 16) / ey;
         else
             f = 0;
-        for (y = 0; y = ey; y++) {
-            x  = (y * f) >> 16;
-            fr = (y * f) & 0xFFFF;
+        for(y= 0; y <= ey; y++){
+            x  = (y*f) >> 16;
+            fr = (y*f) & 0xFFFF;
             buf[y * stride + x]     += (color * (0x10000 - fr)) >> 16;
-            buf[y * stride + x + 1] += (color *            fr ) >> 16;
+            if(fr) buf[y * stride + x + 1] += (color *            fr ) >> 16;
         }
     }
 }
@@ -1677,33 +1674,16 @@
  */
 void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
 {
-    if (s->avctx->hwaccel || !pict || !pict->mb_type)
+    if (   s->avctx->hwaccel || !pict || !pict->mb_type
+        || (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU))
         return;
 
+
     if (s->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: ");
-        switch (pict->pict_type) {
-        case AV_PICTURE_TYPE_I:
-            av_log(s->avctx,AV_LOG_DEBUG,"I\n");
-            break;
-        case AV_PICTURE_TYPE_P:
-            av_log(s->avctx,AV_LOG_DEBUG,"P\n");
-            break;
-        case AV_PICTURE_TYPE_B:
-            av_log(s->avctx,AV_LOG_DEBUG,"B\n");
-            break;
-        case AV_PICTURE_TYPE_S:
-            av_log(s->avctx,AV_LOG_DEBUG,"S\n");
-            break;
-        case AV_PICTURE_TYPE_SI:
-            av_log(s->avctx,AV_LOG_DEBUG,"SI\n");
-            break;
-        case AV_PICTURE_TYPE_SP:
-            av_log(s->avctx,AV_LOG_DEBUG,"SP\n");
-            break;
-        }
+        av_log(s->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) {
@@ -1742,7 +1722,7 @@
                     else if (!USES_LIST(mb_type, 0))
                         av_log(s->avctx, AV_LOG_DEBUG, "<");
                     else {
-                        assert(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1));
+                        av_assert2(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1));
                         av_log(s->avctx, AV_LOG_DEBUG, "X");
                     }
 
@@ -1786,12 +1766,14 @@
         avcodec_get_chroma_sub_sample(s->avctx->pix_fmt,
                                       &h_chroma_shift, &v_chroma_shift);
         for (i = 0; i < 3; i++) {
-            memcpy(s->visualization_buffer[i], pict->data[i],
-                   (i == 0) ? pict->linesize[i] * height:
-                              pict->linesize[i] * height >> v_chroma_shift);
+            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];
         }
         pict->type   = FF_BUFFER_TYPE_COPY;
+        pict->opaque= NULL;
         ptr          = pict->data[0];
         block_height = 16 >> v_chroma_shift;
 
@@ -1869,11 +1851,11 @@
                                            height, s->linesize, 100);
                             }
                         } else {
-                              int sx = mb_x * 16 + 8;
-                              int sy = mb_y * 16 + 8;
-                              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;
+                              int sx= mb_x * 16 + 8;
+                              int sy= mb_y * 16 + 8;
+                              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);
                         }
                     }
@@ -1924,7 +1906,7 @@
                     } else if (!USES_LIST(mb_type, 0)) {
                         COLOR(0, 48)
                     } else {
-                        assert(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1));
+                        av_assert2(USES_LIST(mb_type, 0) && USES_LIST(mb_type, 1));
                         COLOR(300,48)
                     }
 
@@ -1979,6 +1961,381 @@
     }
 }
 
+static inline int hpel_motion_lowres(MpegEncContext *s,
+                                     uint8_t *dest, uint8_t *src,
+                                     int field_based, int field_select,
+                                     int src_x, int src_y,
+                                     int width, int height, int stride,
+                                     int h_edge_pos, int v_edge_pos,
+                                     int w, int h, h264_chroma_mc_func *pix_op,
+                                     int motion_x, int motion_y)
+{
+    const int lowres   = s->avctx->lowres;
+    const int op_index = FFMIN(lowres, 2);
+    const int s_mask   = (2 << lowres) - 1;
+    int emu = 0;
+    int sx, sy;
+
+    if (s->quarter_sample) {
+        motion_x /= 2;
+        motion_y /= 2;
+    }
+
+    sx = motion_x & s_mask;
+    sy = motion_y & s_mask;
+    src_x += motion_x >> lowres + 1;
+    src_y += motion_y >> lowres + 1;
+
+    src   += src_y * stride + src_x;
+
+    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,
+                                (h + 1) << field_based, src_x,
+                                src_y   << field_based,
+                                h_edge_pos,
+                                v_edge_pos);
+        src = s->edge_emu_buffer;
+        emu = 1;
+    }
+
+    sx = (sx << 2) >> lowres;
+    sy = (sy << 2) >> lowres;
+    if (field_select)
+        src += s->linesize;
+    pix_op[op_index](dest, src, stride, h, sx, sy);
+    return emu;
+}
+
+/* apply one mpeg motion vector to the three components */
+static av_always_inline void mpeg_motion_lowres(MpegEncContext *s,
+                                                uint8_t *dest_y,
+                                                uint8_t *dest_cb,
+                                                uint8_t *dest_cr,
+                                                int field_based,
+                                                int bottom_field,
+                                                int field_select,
+                                                uint8_t **ref_picture,
+                                                h264_chroma_mc_func *pix_op,
+                                                int motion_x, int motion_y,
+                                                int h, int mb_y)
+{
+    uint8_t *ptr_y, *ptr_cb, *ptr_cr;
+    int mx, my, src_x, src_y, uvsrc_x, uvsrc_y, uvlinesize, linesize, sx, sy,
+        uvsx, uvsy;
+    const int lowres     = s->avctx->lowres;
+    const int op_index   = FFMIN(lowres-1+s->chroma_x_shift, 2);
+    const int block_s    = 8>>lowres;
+    const int s_mask     = (2 << lowres) - 1;
+    const int h_edge_pos = s->h_edge_pos >> lowres;
+    const int v_edge_pos = s->v_edge_pos >> lowres;
+    linesize   = s->current_picture.f.linesize[0] << field_based;
+    uvlinesize = s->current_picture.f.linesize[1] << field_based;
+
+    // FIXME obviously not perfect but qpel will not work in lowres anyway
+    if (s->quarter_sample) {
+        motion_x /= 2;
+        motion_y /= 2;
+    }
+
+    if(field_based){
+        motion_y += (bottom_field - field_select)*((1 << lowres)-1);
+    }
+
+    sx = motion_x & s_mask;
+    sy = motion_y & s_mask;
+    src_x = s->mb_x * 2 * block_s + (motion_x >> lowres + 1);
+    src_y = (mb_y * 2 * block_s >> field_based) + (motion_y >> lowres + 1);
+
+    if (s->out_format == FMT_H263) {
+        uvsx    = ((motion_x >> 1) & s_mask) | (sx & 1);
+        uvsy    = ((motion_y >> 1) & s_mask) | (sy & 1);
+        uvsrc_x = src_x >> 1;
+        uvsrc_y = src_y >> 1;
+    } else if (s->out_format == FMT_H261) {
+        // even chroma mv's are full pel in H261
+        mx      = motion_x / 4;
+        my      = motion_y / 4;
+        uvsx    = (2 * mx) & s_mask;
+        uvsy    = (2 * my) & s_mask;
+        uvsrc_x = s->mb_x * block_s + (mx >> lowres);
+        uvsrc_y =    mb_y * block_s + (my >> lowres);
+    } else {
+        if(s->chroma_y_shift){
+            mx      = motion_x / 2;
+            my      = motion_y / 2;
+            uvsx    = mx & s_mask;
+            uvsy    = my & s_mask;
+            uvsrc_x = s->mb_x * block_s                 + (mx >> lowres + 1);
+            uvsrc_y =   (mb_y * block_s >> field_based) + (my >> lowres + 1);
+        } else {
+            if(s->chroma_x_shift){
+            //Chroma422
+                mx = motion_x / 2;
+                uvsx = mx & s_mask;
+                uvsy = motion_y & s_mask;
+                uvsrc_y = src_y;
+                uvsrc_x = s->mb_x*block_s               + (mx >> (lowres+1));
+            } else {
+            //Chroma444
+                uvsx = motion_x & s_mask;
+                uvsy = motion_y & s_mask;
+                uvsrc_x = src_x;
+                uvsrc_y = src_y;
+            }
+        }
+    }
+
+    ptr_y  = ref_picture[0] + src_y   * linesize   + src_x;
+    ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
+    ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
+
+    if ((unsigned) src_x > FFMAX( h_edge_pos - (!!sx) - 2 * block_s,       0) ||
+        (unsigned) src_y > FFMAX((v_edge_pos >> field_based) - (!!sy) - h, 0)) {
+        s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y,
+                                s->linesize, 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, s->uvlinesize, 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, s->uvlinesize, 9,
+                                    9 + field_based,
+                                    uvsrc_x, uvsrc_y << field_based,
+                                    h_edge_pos >> 1, v_edge_pos >> 1);
+            ptr_cb = uvbuf;
+            ptr_cr = uvbuf + 16;
+        }
+    }
+
+    // FIXME use this for field pix too instead of the obnoxious hack which changes picture.f.data
+    if (bottom_field) {
+        dest_y  += s->linesize;
+        dest_cb += s->uvlinesize;
+        dest_cr += s->uvlinesize;
+    }
+
+    if (field_select) {
+        ptr_y   += s->linesize;
+        ptr_cb  += s->uvlinesize;
+        ptr_cr  += s->uvlinesize;
+    }
+
+    sx = (sx << 2) >> lowres;
+    sy = (sy << 2) >> lowres;
+    pix_op[lowres - 1](dest_y, ptr_y, linesize, h, sx, sy);
+
+    if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) {
+        uvsx = (uvsx << 2) >> lowres;
+        uvsy = (uvsy << 2) >> lowres;
+        if (h >> s->chroma_y_shift) {
+            pix_op[op_index](dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy);
+            pix_op[op_index](dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift, uvsx, uvsy);
+        }
+    }
+    // FIXME h261 lowres loop filter
+}
+
+static inline void chroma_4mv_motion_lowres(MpegEncContext *s,
+                                            uint8_t *dest_cb, uint8_t *dest_cr,
+                                            uint8_t **ref_picture,
+                                            h264_chroma_mc_func * pix_op,
+                                            int mx, int my)
+{
+    const int lowres     = s->avctx->lowres;
+    const int op_index   = FFMIN(lowres, 2);
+    const int block_s    = 8 >> lowres;
+    const int s_mask     = (2 << lowres) - 1;
+    const int h_edge_pos = s->h_edge_pos >> lowres + 1;
+    const int v_edge_pos = s->v_edge_pos >> lowres + 1;
+    int emu = 0, src_x, src_y, offset, sx, sy;
+    uint8_t *ptr;
+
+    if (s->quarter_sample) {
+        mx /= 2;
+        my /= 2;
+    }
+
+    /* In case of 8X8, we construct a single chroma motion vector
+       with a special rounding */
+    mx = ff_h263_round_chroma(mx);
+    my = ff_h263_round_chroma(my);
+
+    sx = mx & s_mask;
+    sy = my & s_mask;
+    src_x = s->mb_x * block_s + (mx >> lowres + 1);
+    src_y = s->mb_y * block_s + (my >> lowres + 1);
+
+    offset = src_y * s->uvlinesize + src_x;
+    ptr = ref_picture[1] + offset;
+    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,
+                                    9, 9, src_x, src_y, h_edge_pos, v_edge_pos);
+            ptr = s->edge_emu_buffer;
+            emu = 1;
+        }
+    }
+    sx = (sx << 2) >> lowres;
+    sy = (sy << 2) >> lowres;
+    pix_op[op_index](dest_cb, ptr, s->uvlinesize, block_s, sx, sy);
+
+    ptr = ref_picture[2] + offset;
+    if (emu) {
+        s->dsp.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;
+    }
+    pix_op[op_index](dest_cr, ptr, s->uvlinesize, block_s, sx, sy);
+}
+
+/**
+ * motion compensation of a single macroblock
+ * @param s context
+ * @param dest_y luma destination pointer
+ * @param dest_cb chroma cb/u destination pointer
+ * @param dest_cr chroma cr/v destination pointer
+ * @param dir direction (0->forward, 1->backward)
+ * @param ref_picture array[3] of pointers to the 3 planes of the reference picture
+ * @param pix_op halfpel motion compensation function (average or put normally)
+ * the motion vectors are taken from s->mv and the MV type from s->mv_type
+ */
+static inline void MPV_motion_lowres(MpegEncContext *s,
+                                     uint8_t *dest_y, uint8_t *dest_cb,
+                                     uint8_t *dest_cr,
+                                     int dir, uint8_t **ref_picture,
+                                     h264_chroma_mc_func *pix_op)
+{
+    int mx, my;
+    int mb_x, mb_y, i;
+    const int lowres  = s->avctx->lowres;
+    const int block_s = 8 >>lowres;
+
+    mb_x = s->mb_x;
+    mb_y = s->mb_y;
+
+    switch (s->mv_type) {
+    case MV_TYPE_16X16:
+        mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
+                           0, 0, 0,
+                           ref_picture, pix_op,
+                           s->mv[dir][0][0], s->mv[dir][0][1],
+                           2 * block_s, mb_y);
+        break;
+    case MV_TYPE_8X8:
+        mx = 0;
+        my = 0;
+        for (i = 0; i < 4; i++) {
+            hpel_motion_lowres(s, dest_y + ((i & 1) + (i >> 1) *
+                               s->linesize) * block_s,
+                               ref_picture[0], 0, 0,
+                               (2 * mb_x + (i & 1)) * block_s,
+                               (2 * mb_y + (i >> 1)) * block_s,
+                               s->width, s->height, s->linesize,
+                               s->h_edge_pos >> lowres, s->v_edge_pos >> lowres,
+                               block_s, block_s, pix_op,
+                               s->mv[dir][i][0], s->mv[dir][i][1]);
+
+            mx += s->mv[dir][i][0];
+            my += s->mv[dir][i][1];
+        }
+
+        if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY))
+            chroma_4mv_motion_lowres(s, dest_cb, dest_cr, ref_picture,
+                                     pix_op, mx, my);
+        break;
+    case MV_TYPE_FIELD:
+        if (s->picture_structure == PICT_FRAME) {
+            /* top field */
+            mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
+                               1, 0, s->field_select[dir][0],
+                               ref_picture, pix_op,
+                               s->mv[dir][0][0], s->mv[dir][0][1],
+                               block_s, mb_y);
+            /* bottom field */
+            mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
+                               1, 1, s->field_select[dir][1],
+                               ref_picture, pix_op,
+                               s->mv[dir][1][0], s->mv[dir][1][1],
+                               block_s, mb_y);
+        } else {
+            if (s->picture_structure != s->field_select[dir][0] + 1 &&
+                s->pict_type != AV_PICTURE_TYPE_B && !s->first_field) {
+                ref_picture = s->current_picture_ptr->f.data;
+
+            }
+            mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
+                               0, 0, s->field_select[dir][0],
+                               ref_picture, pix_op,
+                               s->mv[dir][0][0],
+                               s->mv[dir][0][1], 2 * block_s, mb_y >> 1);
+            }
+        break;
+    case MV_TYPE_16X8:
+        for (i = 0; i < 2; i++) {
+            uint8_t **ref2picture;
+
+            if (s->picture_structure == s->field_select[dir][i] + 1 ||
+                s->pict_type == AV_PICTURE_TYPE_B || s->first_field) {
+                ref2picture = ref_picture;
+            } else {
+                ref2picture = s->current_picture_ptr->f.data;
+            }
+
+            mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
+                               0, 0, s->field_select[dir][i],
+                               ref2picture, pix_op,
+                               s->mv[dir][i][0], s->mv[dir][i][1] +
+                               2 * block_s * i, block_s, mb_y >> 1);
+
+            dest_y  +=  2 * block_s *  s->linesize;
+            dest_cb += (2 * block_s >> s->chroma_y_shift) * s->uvlinesize;
+            dest_cr += (2 * block_s >> s->chroma_y_shift) * s->uvlinesize;
+        }
+        break;
+    case MV_TYPE_DMV:
+        if (s->picture_structure == PICT_FRAME) {
+            for (i = 0; i < 2; i++) {
+                int j;
+                for (j = 0; j < 2; j++) {
+                    mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
+                                       1, j, j ^ i,
+                                       ref_picture, pix_op,
+                                       s->mv[dir][2 * i + j][0],
+                                       s->mv[dir][2 * i + j][1],
+                                       block_s, mb_y);
+                }
+                pix_op = s->dsp.avg_h264_chroma_pixels_tab;
+            }
+        } else {
+            for (i = 0; i < 2; i++) {
+                mpeg_motion_lowres(s, dest_y, dest_cb, dest_cr,
+                                   0, 0, s->picture_structure != i + 1,
+                                   ref_picture, pix_op,
+                                   s->mv[dir][2 * i][0],s->mv[dir][2 * i][1],
+                                   2 * block_s, mb_y >> 1);
+
+                // after put we make avg of the same block
+                pix_op = s->dsp.avg_h264_chroma_pixels_tab;
+
+                // opposite parity is always in the same
+                // frame if this is second field
+                if (!s->first_field) {
+                    ref_picture = s->current_picture_ptr->f.data;
+                }
+            }
+        }
+        break;
+    default:
+        av_assert2(0);
+    }
+}
+
 /**
  * find the lowest MB row referenced in the MVs
  */
@@ -1987,7 +2344,7 @@
     int my_max = INT_MIN, my_min = INT_MAX, qpel_shift = !s->quarter_sample;
     int my, off, i, mvs;
 
-    if (s->picture_structure != PICT_FRAME) goto unhandled;
+    if (s->picture_structure != PICT_FRAME || s->mcsel) goto unhandled;
 
     switch (s->mv_type) {
         case MV_TYPE_16X16:
@@ -2088,7 +2445,7 @@
  */
 static av_always_inline
 void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64],
-                            int is_mpeg12)
+                            int lowres_flag, int is_mpeg12)
 {
     const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
     if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration){
@@ -2133,8 +2490,8 @@
         qpel_mc_func (*op_qpix)[16];
         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];
-        const int readable= s->pict_type != AV_PICTURE_TYPE_B || s->encoding || s->avctx->draw_horiz_band;
-        const int block_size = 8;
+        const int readable= s->pict_type != AV_PICTURE_TYPE_B || s->encoding || s->avctx->draw_horiz_band || lowres_flag;
+        const int block_size= lowres_flag ? 8>>s->avctx->lowres : 8;
 
         /* avoid copy if macroblock skipped in last frame too */
         /* skip only during decoding as we might trash the buffers during encoding a bit */
@@ -2143,7 +2500,7 @@
 
             if (s->mb_skipped) {
                 s->mb_skipped= 0;
-                assert(s->pict_type!=AV_PICTURE_TYPE_I);
+                av_assert2(s->pict_type!=AV_PICTURE_TYPE_I);
                 *mbskip_ptr = 1;
             } else if(!s->current_picture.f.reference) {
                 *mbskip_ptr = 1;
@@ -2183,19 +2540,31 @@
                     }
                 }
 
-                op_qpix= s->me.qpel_put;
-                if ((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){
-                    op_pix = s->dsp.put_pixels_tab;
+                if(lowres_flag){
+                    h264_chroma_mc_func *op_pix = s->dsp.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;
+                    }
+                    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);
+                    }
                 }else{
-                    op_pix = s->dsp.put_no_rnd_pixels_tab;
-                }
-                if (s->mv_dir & MV_DIR_FORWARD) {
-                    ff_MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.f.data, op_pix, op_qpix);
-                    op_pix = s->dsp.avg_pixels_tab;
-                    op_qpix= s->me.qpel_avg;
-                }
-                if (s->mv_dir & MV_DIR_BACKWARD) {
-                    ff_MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f.data, op_pix, op_qpix);
+                    op_qpix= s->me.qpel_put;
+                    if ((!s->no_rounding) || s->pict_type==AV_PICTURE_TYPE_B){
+                        op_pix = s->dsp.put_pixels_tab;
+                    }else{
+                        op_pix = s->dsp.put_no_rnd_pixels_tab;
+                    }
+                    if (s->mv_dir & MV_DIR_FORWARD) {
+                        ff_MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.f.data, op_pix, op_qpix);
+                        op_pix = s->dsp.avg_pixels_tab;
+                        op_qpix= s->me.qpel_avg;
+                    }
+                    if (s->mv_dir & MV_DIR_BACKWARD) {
+                        ff_MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.f.data, op_pix, op_qpix);
+                    }
                 }
             }
 
@@ -2241,17 +2610,17 @@
                     }else{
                         //chroma422
                         dct_linesize = uvlinesize << s->interlaced_dct;
-                        dct_offset   = s->interlaced_dct ? uvlinesize : uvlinesize * 8;
+                        dct_offset   = s->interlaced_dct ? uvlinesize : uvlinesize*block_size;
 
                         add_dct(s, block[4], 4, dest_cb, dct_linesize);
                         add_dct(s, block[5], 5, dest_cr, dct_linesize);
                         add_dct(s, block[6], 6, dest_cb+dct_offset, dct_linesize);
                         add_dct(s, block[7], 7, dest_cr+dct_offset, dct_linesize);
                         if(!s->chroma_x_shift){//Chroma444
-                            add_dct(s, block[8], 8, dest_cb+8, dct_linesize);
-                            add_dct(s, block[9], 9, dest_cr+8, dct_linesize);
-                            add_dct(s, block[10], 10, dest_cb+8+dct_offset, dct_linesize);
-                            add_dct(s, block[11], 11, dest_cr+8+dct_offset, dct_linesize);
+                            add_dct(s, block[8], 8, dest_cb+block_size, dct_linesize);
+                            add_dct(s, block[9], 9, dest_cr+block_size, dct_linesize);
+                            add_dct(s, block[10], 10, dest_cb+block_size+dct_offset, dct_linesize);
+                            add_dct(s, block[11], 11, dest_cr+block_size+dct_offset, dct_linesize);
                         }
                     }
                 }//fi gray
@@ -2293,17 +2662,17 @@
                     }else{
 
                         dct_linesize = uvlinesize << s->interlaced_dct;
-                        dct_offset   = s->interlaced_dct ? uvlinesize : uvlinesize * 8;
+                        dct_offset   = s->interlaced_dct? uvlinesize : uvlinesize*block_size;
 
                         s->dsp.idct_put(dest_cb,              dct_linesize, block[4]);
                         s->dsp.idct_put(dest_cr,              dct_linesize, block[5]);
                         s->dsp.idct_put(dest_cb + dct_offset, dct_linesize, block[6]);
                         s->dsp.idct_put(dest_cr + dct_offset, dct_linesize, block[7]);
                         if(!s->chroma_x_shift){//Chroma444
-                            s->dsp.idct_put(dest_cb + 8,              dct_linesize, block[8]);
-                            s->dsp.idct_put(dest_cr + 8,              dct_linesize, block[9]);
-                            s->dsp.idct_put(dest_cb + 8 + dct_offset, dct_linesize, block[10]);
-                            s->dsp.idct_put(dest_cr + 8 + dct_offset, dct_linesize, block[11]);
+                            s->dsp.idct_put(dest_cb + block_size,              dct_linesize, block[8]);
+                            s->dsp.idct_put(dest_cr + block_size,              dct_linesize, block[9]);
+                            s->dsp.idct_put(dest_cb + block_size + dct_offset, dct_linesize, block[10]);
+                            s->dsp.idct_put(dest_cr + block_size + dct_offset, dct_linesize, block[11]);
                         }
                     }
                 }//gray
@@ -2321,10 +2690,12 @@
 void ff_MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]){
 #if !CONFIG_SMALL
     if(s->out_format == FMT_MPEG1) {
-        MPV_decode_mb_internal(s, block, 1);
+        if(s->avctx->lowres) MPV_decode_mb_internal(s, block, 1, 1);
+        else                 MPV_decode_mb_internal(s, block, 0, 1);
     } else
 #endif
-        MPV_decode_mb_internal(s, block, 0);
+    if(s->avctx->lowres) MPV_decode_mb_internal(s, block, 1, 0);
+    else                  MPV_decode_mb_internal(s, block, 0, 0);
 }
 
 /**
@@ -2400,7 +2771,7 @@
 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];
-    const int mb_size= 4;
+    const int mb_size= 4 - s->avctx->lowres;
 
     s->block_index[0]= s->b8_stride*(s->mb_y*2    ) - 2 + s->mb_x*2;
     s->block_index[1]= s->b8_stride*(s->mb_y*2    ) - 1 + s->mb_x*2;
@@ -2424,7 +2795,7 @@
             s->dest[0] += (s->mb_y>>1) *   linesize << mb_size;
             s->dest[1] += (s->mb_y>>1) * uvlinesize << (mb_size - s->chroma_y_shift);
             s->dest[2] += (s->mb_y>>1) * uvlinesize << (mb_size - s->chroma_y_shift);
-            assert((s->mb_y&1) == (s->picture_structure == PICT_BOTTOM_FIELD));
+            av_assert1((s->mb_y&1) == (s->picture_structure == PICT_BOTTOM_FIELD));
         }
     }
 }
@@ -2445,6 +2816,7 @@
     s->current_picture_ptr = s->last_picture_ptr = s->next_picture_ptr = NULL;
 
     s->mb_x= s->mb_y= 0;
+    s->closed_gop= 0;
 
     s->parse_context.state= -1;
     s->parse_context.frame_start_found= 0;
@@ -2464,10 +2836,7 @@
 
     nCoeffs= s->block_last_index[n];
 
-    if (n < 4)
-        block[0] = block[0] * s->y_dc_scale;
-    else
-        block[0] = block[0] * s->c_dc_scale;
+    block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
     /* XXX: only mpeg1 */
     quant_matrix = s->intra_matrix;
     for(i=1;i<=nCoeffs;i++) {
@@ -2526,10 +2895,7 @@
     if(s->alternate_scan) nCoeffs= 63;
     else nCoeffs= s->block_last_index[n];
 
-    if (n < 4)
-        block[0] = block[0] * s->y_dc_scale;
-    else
-        block[0] = block[0] * s->c_dc_scale;
+    block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
     quant_matrix = s->intra_matrix;
     for(i=1;i<=nCoeffs;i++) {
         int j= s->intra_scantable.permutated[i];
@@ -2557,10 +2923,8 @@
     if(s->alternate_scan) nCoeffs= 63;
     else nCoeffs= s->block_last_index[n];
 
-    if (n < 4)
-        block[0] = block[0] * s->y_dc_scale;
-    else
-        block[0] = block[0] * s->c_dc_scale;
+    block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
+    sum += block[0];
     quant_matrix = s->intra_matrix;
     for(i=1;i<=nCoeffs;i++) {
         int j= s->intra_scantable.permutated[i];
@@ -2622,10 +2986,7 @@
     qmul = qscale << 1;
 
     if (!s->h263_aic) {
-        if (n < 4)
-            block[0] = block[0] * s->y_dc_scale;
-        else
-            block[0] = block[0] * s->c_dc_scale;
+        block[0] *= n < 4 ? s->y_dc_scale : s->c_dc_scale;
         qadd = (qscale - 1) | 1;
     }else{
         qadd = 0;
diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index 23637d0..f0fa652 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,6 +36,7 @@
 #include "parser.h"
 #include "mpeg12data.h"
 #include "rl.h"
+#include "libavutil/timecode.h"
 
 #include "libavutil/opt.h"
 
@@ -52,12 +53,12 @@
 #define MPEG_BUF_SIZE (16 * 1024)
 
 #define QMAT_SHIFT_MMX 16
-#define QMAT_SHIFT 22
+#define QMAT_SHIFT 21
 
 #define MAX_FCODE 7
 #define MAX_MV 2048
 
-#define MAX_THREADS 16
+#define MAX_THREADS 32
 
 #define MAX_PICTURE_COUNT 32
 
@@ -126,10 +127,11 @@
     int pic_id;                 /**< h264 pic_num (short -> no wrap version of pic_num,
                                      pic_num & max_pic_num; long -> long_pic_num) */
     int long_ref;               ///< 1->long term reference 0->short term reference
-    int ref_poc[2][2][32];      ///< h264 POCs of the frames used as reference (FIXME need per slice)
+    int ref_poc[2][2][32];      ///< h264 POCs of the frames/fields used as reference (FIXME need per slice)
     int ref_count[2][2];        ///< number of entries in ref_poc              (FIXME need per slice)
     int mbaff;                  ///< h264 1 -> MBAFF frame 0-> not MBAFF
     int field_picture;          ///< whether or not the picture was encoded in separate fields
+    int sync;                   ///< has been decoded after a keyframe
 
     int mb_var_sum;             ///< sum of MB variance for current frame
     int mc_mb_var_sum;          ///< motion compensated MB variance for current frame
@@ -339,11 +341,13 @@
     int *lambda_table;
     int adaptive_quant;         ///< use adaptive quantization
     int dquant;                 ///< qscale difference to prev qscale
+    int closed_gop;             ///< MPEG1/2 GOP is closed
     int pict_type;              ///< AV_PICTURE_TYPE_I, AV_PICTURE_TYPE_P, AV_PICTURE_TYPE_B, ...
     int last_pict_type; //FIXME removes
     int last_non_b_pict_type;   ///< used for mpeg4 gmc b-frames & ratecontrol
     int dropable;
     int frame_rate_index;
+    AVRational mpeg2_frame_rate_ext;
     int last_lambda_for[5];     ///< last lambda for a specific pict type
     int skipdct;                ///< skip dct and code zero residual
 
@@ -450,9 +454,11 @@
 
     /** precomputed matrix (combine qscale and DCT renorm) */
     int (*q_intra_matrix)[64];
+    int (*q_chroma_intra_matrix)[64];
     int (*q_inter_matrix)[64];
     /** identical to the above but for MMX & these are not permutated, second 64 entries are bias*/
     uint16_t (*q_intra_matrix16)[2][64];
+    uint16_t (*q_chroma_intra_matrix16)[2][64];
     uint16_t (*q_inter_matrix16)[2][64];
 
     /* noise reduction */
@@ -465,6 +471,7 @@
     /* bit rate control */
     int64_t total_bits;
     int frame_bits;                ///< bits used for the current frame
+    int stuffing_bits;             ///< bits used for stuffing
     int next_lambda;               ///< next lambda used for retrying to encode a frame
     RateControlContext rc_context; ///< contains stuff only accessed in ratecontrol.c
 
@@ -595,6 +602,7 @@
     struct MJpegContext *mjpeg_ctx;
     int mjpeg_vsample[3];       ///< vertical sampling factors, default = {2, 1, 1}
     int mjpeg_hsample[3];       ///< horizontal sampling factors, default = {2, 1, 1}
+    int esc_pos;
 
     /* MSMPEG4 specific */
     int mv_table_index;
@@ -659,6 +667,9 @@
     /* RTP specific */
     int rtp_mode;
 
+    char *tc_opt_str;        ///< timecode option string
+    AVTimecode tc;           ///< timecode context
+
     uint8_t *ptr_lastgob;
     int swap_uv;             //vcr2 codec is an MPEG-2 variant with U and V swapped
     DCTELEM (*pblocks[12])[64];
@@ -761,8 +772,8 @@
 int ff_MPV_encode_init(AVCodecContext *avctx);
 int ff_MPV_encode_end(AVCodecContext *avctx);
 int ff_MPV_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
-                          const AVFrame *frame, int *got_packet);
-void ff_MPV_encode_init_x86(MpegEncContext *s);
+                          AVFrame *frame, int *got_packet);
+void ff_dct_encode_init_x86(MpegEncContext *s);
 void ff_MPV_common_init_x86(MpegEncContext *s);
 void ff_MPV_common_init_axp(MpegEncContext *s);
 void ff_MPV_common_init_mmi(MpegEncContext *s);
@@ -789,6 +800,7 @@
 void ff_er_add_slice(MpegEncContext *s, int startx, int starty, int endx, int endy, int status);
 
 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);
@@ -813,7 +825,7 @@
 extern const enum AVPixelFormat ff_hwaccel_pixfmt_list_420[];
 
 static inline void ff_update_block_index(MpegEncContext *s){
-    const int block_size = 8;
+    const int block_size= 8 >> s->avctx->lowres;
 
     s->block_index[0]+=2;
     s->block_index[1]+=2;
diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c
index d2719fe..108db50 100644
--- a/libavcodec/mpegvideo_enc.c
+++ b/libavcodec/mpegvideo_enc.c
@@ -5,20 +5,20 @@
  *
  * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -45,6 +45,7 @@
 #include "internal.h"
 #include "bytestream.h"
 #include <limits.h>
+#include "sp5x.h"
 
 //#undef NDEBUG
 //#include <assert.h>
@@ -102,8 +103,7 @@
                  *           3444240 >= (1 << 36) / (x) >= 275 */
 
                 qmat[qscale][i] = (int)((UINT64_C(1) << (QMAT_SHIFT + 14)) /
-                                        (ff_aanscales[i] * qscale *
-                                         quant_matrix[j]));
+                                        (ff_aanscales[i] * qscale * quant_matrix[j]));
             }
         } else {
             for (i = 0; i < 64; i++) {
@@ -268,6 +268,21 @@
     s->fcode_tab     = default_fcode_tab;
 }
 
+av_cold int ff_dct_encode_init(MpegEncContext *s) {
+    if (ARCH_X86)
+        ff_dct_encode_init_x86(s);
+
+    if (!s->dct_quantize)
+        s->dct_quantize = ff_dct_quantize_c;
+    if (!s->denoise_dct)
+        s->denoise_dct  = denoise_dct_c;
+    s->fast_dct_quantize = s->dct_quantize;
+    if (s->avctx->trellis)
+        s->dct_quantize  = dct_quantize_trellis_c;
+
+    return 0;
+}
+
 /* init video encoder */
 av_cold int ff_MPV_encode_init(AVCodecContext *avctx)
 {
@@ -290,7 +305,9 @@
         if (avctx->pix_fmt != AV_PIX_FMT_YUVJ420P &&
             avctx->pix_fmt != AV_PIX_FMT_YUVJ422P &&
             avctx->pix_fmt != AV_PIX_FMT_YUVJ444P &&
+            avctx->pix_fmt != AV_PIX_FMT_BGR0     &&
             avctx->pix_fmt != AV_PIX_FMT_BGRA     &&
+            avctx->pix_fmt != AV_PIX_FMT_BGR24    &&
             ((avctx->pix_fmt != AV_PIX_FMT_YUV420P &&
               avctx->pix_fmt != AV_PIX_FMT_YUV422P &&
               avctx->pix_fmt != AV_PIX_FMT_YUV444P) ||
@@ -300,6 +317,7 @@
         }
         break;
     case AV_CODEC_ID_MJPEG:
+    case AV_CODEC_ID_AMV:
         if (avctx->pix_fmt != AV_PIX_FMT_YUVJ420P &&
             avctx->pix_fmt != AV_PIX_FMT_YUVJ422P &&
             ((avctx->pix_fmt != AV_PIX_FMT_YUV420P &&
@@ -333,8 +351,9 @@
     s->height   = avctx->height;
     if (avctx->gop_size > 600 &&
         avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Warning keyframe interval too large! reducing it ...\n");
+        av_log(avctx, AV_LOG_WARNING,
+               "keyframe interval too large!, reducing it from %d to %d\n",
+               avctx->gop_size, 600);
         avctx->gop_size = 600;
     }
     s->gop_size     = avctx->gop_size;
@@ -384,11 +403,10 @@
 
     s->loop_filter      = !!(s->flags & CODEC_FLAG_LOOP_FILTER);
 
-    if (avctx->rc_max_rate && !avctx->rc_buffer_size) {
-        av_log(avctx, AV_LOG_ERROR,
-               "a vbv buffer size is needed, "
-               "for encoding with a maximum bitrate\n");
-        return -1;
+    if ((!avctx->rc_max_rate) != (!avctx->rc_buffer_size)) {
+        av_log(avctx, AV_LOG_ERROR, "Either both buffer size and max rate or neither must be specified\n");
+        if (avctx->rc_max_rate && !avctx->rc_buffer_size)
+            return -1;
     }
 
     if (avctx->rc_min_rate && avctx->rc_max_rate != avctx->rc_min_rate) {
@@ -402,7 +420,7 @@
     }
 
     if (avctx->rc_max_rate && avctx->rc_max_rate < avctx->bit_rate) {
-        av_log(avctx, AV_LOG_INFO, "bitrate above max bitrate\n");
+        av_log(avctx, AV_LOG_ERROR, "bitrate above max bitrate\n");
         return -1;
     }
 
@@ -470,11 +488,48 @@
          s->codec_id == AV_CODEC_ID_H263P) &&
         (avctx->sample_aspect_ratio.num > 255 ||
          avctx->sample_aspect_ratio.den > 255)) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Invalid pixel aspect ratio %i/%i, limit is 255/255\n",
+        av_log(avctx, AV_LOG_WARNING,
+               "Invalid pixel aspect ratio %i/%i, limit is 255/255 reducing\n",
                avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den);
+        av_reduce(&avctx->sample_aspect_ratio.num, &avctx->sample_aspect_ratio.den,
+                   avctx->sample_aspect_ratio.num,  avctx->sample_aspect_ratio.den, 255);
+    }
+
+    if ((s->codec_id == AV_CODEC_ID_H263  ||
+         s->codec_id == AV_CODEC_ID_H263P) &&
+        (avctx->width  > 2048 ||
+         avctx->height > 1152 )) {
+        av_log(avctx, AV_LOG_ERROR, "H.263 does not support resolutions above 2048x1152\n");
         return -1;
     }
+    if ((s->codec_id == AV_CODEC_ID_H263  ||
+         s->codec_id == AV_CODEC_ID_H263P) &&
+        ((avctx->width &3) ||
+         (avctx->height&3) )) {
+        av_log(avctx, AV_LOG_ERROR, "w/h must be a multiple of 4\n");
+        return -1;
+    }
+
+    if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO &&
+        (avctx->width  > 4095 ||
+         avctx->height > 4095 )) {
+        av_log(avctx, AV_LOG_ERROR, "MPEG-1 does not support resolutions above 4095x4095\n");
+        return -1;
+    }
+
+    if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
+        (avctx->width  > 16383 ||
+         avctx->height > 16383 )) {
+        av_log(avctx, AV_LOG_ERROR, "MPEG-2 does not support resolutions above 16383x16383\n");
+        return -1;
+    }
+
+    if ((s->codec_id == AV_CODEC_ID_WMV1 ||
+         s->codec_id == AV_CODEC_ID_WMV2) &&
+         avctx->width & 1) {
+         av_log(avctx, AV_LOG_ERROR, "width must be multiple of 2\n");
+         return -1;
+    }
 
     if ((s->flags & (CODEC_FLAG_INTERLACED_DCT | CODEC_FLAG_INTERLACED_ME)) &&
         s->codec_id != AV_CODEC_ID_MPEG4 && s->codec_id != AV_CODEC_ID_MPEG2VIDEO) {
@@ -538,6 +593,7 @@
         s->codec_id != AV_CODEC_ID_MPEG4      &&
         s->codec_id != AV_CODEC_ID_MPEG1VIDEO &&
         s->codec_id != AV_CODEC_ID_MPEG2VIDEO &&
+        s->codec_id != AV_CODEC_ID_MJPEG      &&
         (s->codec_id != AV_CODEC_ID_H263P)) {
         av_log(avctx, AV_LOG_ERROR,
                "multi threaded encoding not supported by codec\n");
@@ -546,7 +602,7 @@
 
     if (s->avctx->thread_count < 1) {
         av_log(avctx, AV_LOG_ERROR,
-               "automatic thread number detection not supported by codec,"
+               "automatic thread number detection not supported by codec, "
                "patch welcome\n");
         return -1;
     }
@@ -554,6 +610,9 @@
     if (s->avctx->thread_count > 1)
         s->rtp_mode = 1;
 
+    if (s->avctx->thread_count > 1 && s->codec_id == AV_CODEC_ID_H263P)
+        s->h263_slice_structured = 1;
+
     if (!avctx->time_base.den || !avctx->time_base.num) {
         av_log(avctx, AV_LOG_ERROR, "framerate not set\n");
         return -1;
@@ -585,8 +644,7 @@
         //return -1;
     }
 
-    if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG1VIDEO ||
-        s->codec_id == AV_CODEC_ID_MPEG2VIDEO || s->codec_id == AV_CODEC_ID_MJPEG) {
+    if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG1VIDEO || s->codec_id == AV_CODEC_ID_MPEG2VIDEO || s->codec_id == AV_CODEC_ID_MJPEG || s->codec_id==AV_CODEC_ID_AMV) {
         // (a + x * 3 / 8) / x
         s->intra_quant_bias = 3 << (QUANT_BIAS_SHIFT - 3);
         s->inter_quant_bias = 0;
@@ -601,6 +659,8 @@
     if (avctx->inter_quant_bias != FF_DEFAULT_QUANT_BIAS)
         s->inter_quant_bias = avctx->inter_quant_bias;
 
+    av_log(avctx, AV_LOG_DEBUG, "intra_quant_bias = %d inter_quant_bias = %d\n",s->intra_quant_bias,s->inter_quant_bias);
+
     avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift,
                                   &chroma_v_shift);
 
@@ -638,10 +698,13 @@
         break;
     case AV_CODEC_ID_LJPEG:
     case AV_CODEC_ID_MJPEG:
+    case AV_CODEC_ID_AMV:
         s->out_format = FMT_MJPEG;
         s->intra_only = 1; /* force intra only for jpeg */
         if (avctx->codec->id == AV_CODEC_ID_LJPEG &&
-            avctx->pix_fmt   == AV_PIX_FMT_BGRA) {
+            (avctx->pix_fmt == AV_PIX_FMT_BGR0
+             || s->avctx->pix_fmt == AV_PIX_FMT_BGRA
+             || s->avctx->pix_fmt == AV_PIX_FMT_BGR24)) {
             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;
@@ -675,13 +738,13 @@
         break;
     case AV_CODEC_ID_H263:
         if (!CONFIG_H263_ENCODER)
-        return -1;
+            return -1;
         if (ff_match_2uint16(ff_h263_format, FF_ARRAY_ELEMS(ff_h263_format),
                              s->width, s->height) == 8) {
-            av_log(avctx, AV_LOG_INFO,
+            av_log(avctx, AV_LOG_ERROR,
                    "The specified picture size of %dx%d is not valid for "
                    "the H.263 codec.\nValid sizes are 128x96, 176x144, "
-                   "352x288, 704x576, and 1408x1152."
+                   "352x288, 704x576, and 1408x1152. "
                    "Try H.263+.\n", s->width, s->height);
             return -1;
         }
@@ -785,16 +848,7 @@
     if (ff_MPV_common_init(s) < 0)
         return -1;
 
-    if (ARCH_X86)
-        ff_MPV_encode_init_x86(s);
-
-    if (!s->dct_quantize)
-        s->dct_quantize = ff_dct_quantize_c;
-    if (!s->denoise_dct)
-        s->denoise_dct  = denoise_dct_c;
-    s->fast_dct_quantize = s->dct_quantize;
-    if (avctx->trellis)
-        s->dct_quantize  = dct_quantize_trellis_c;
+    ff_dct_encode_init(s);
 
     if ((CONFIG_H263P_ENCODER || CONFIG_RV20_ENCODER) && s->modified_quant)
         s->chroma_qscale_table = ff_h263_chroma_qscale_table;
@@ -1007,6 +1061,10 @@
                 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;
 
@@ -1097,7 +1155,7 @@
     int64_t best_rd  = INT64_MAX;
     int best_b_count = -1;
 
-    assert(scale >= 0 && scale <= 3);
+    av_assert0(scale >= 0 && scale <= 3);
 
     //emms_c();
     //s->next_picture_ptr->quality;
@@ -1405,7 +1463,7 @@
 }
 
 int ff_MPV_encode_picture(AVCodecContext *avctx, AVPacket *pkt,
-                          const AVFrame *pic_arg, int *got_packet)
+                          AVFrame *pic_arg, int *got_packet)
 {
     MpegEncContext *s = avctx->priv_data;
     int i, stuffing_count, ret;
@@ -1422,8 +1480,7 @@
 
     /* output? */
     if (s->new_picture.f.data[0]) {
-        if (!pkt->data &&
-            (ret = ff_alloc_packet(pkt, s->mb_width*s->mb_height*MAX_MB_BYTES)) < 0)
+        if ((ret = ff_alloc_packet2(avctx, pkt, s->mb_width*s->mb_height*(MAX_MB_BYTES+100)+10000)) < 0)
             return ret;
         if (s->mb_info) {
             s->mb_info_ptr = av_packet_new_side_data(pkt,
@@ -1518,6 +1575,7 @@
         s->frame_bits  = put_bits_count(&s->pb);
 
         stuffing_count = ff_vbv_update(s, s->frame_bits);
+        s->stuffing_bits = 8*stuffing_count;
         if (stuffing_count) {
             if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) <
                     stuffing_count + 50) {
@@ -1572,7 +1630,7 @@
 
             vbv_delay = FFMAX(vbv_delay, min_delay);
 
-            assert(vbv_delay < 0xFFFF);
+            av_assert0(vbv_delay < 0xFFFF);
 
             s->vbv_delay_ptr[0] &= 0xF8;
             s->vbv_delay_ptr[0] |= vbv_delay >> 13;
@@ -1585,12 +1643,12 @@
         avctx->frame_bits  = s->frame_bits;
 
         pkt->pts = s->current_picture.f.pts;
-        if (!s->low_delay) {
+        if (!s->low_delay && s->pict_type != AV_PICTURE_TYPE_B) {
             if (!s->current_picture.f.coded_picture_number)
                 pkt->dts = pkt->pts - s->dts_delta;
             else
                 pkt->dts = s->reordered_pts;
-            s->reordered_pts = s->input_picture[0]->f.pts;
+            s->reordered_pts = pkt->pts;
         } else
             pkt->dts = pkt->pts;
         if (s->current_picture.f.key_frame)
@@ -1778,18 +1836,18 @@
     ptr_cr = s->new_picture.f.data[2] +
              (mb_y * mb_block_height * wrap_c) + mb_x * 8;
 
-    if (mb_x * 16 + 16 > s->width || mb_y * 16 + 16 > s->height) {
+    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);
         ptr_y = ebuf;
         s->dsp.emulated_edge_mc(ebuf + 18 * wrap_y, ptr_cb, wrap_c, 8,
                                 mb_block_height, mb_x * 8, mb_y * 8,
-                                s->width >> 1, s->height >> 1);
+                                (s->width+1) >> 1, (s->height+1) >> 1);
         ptr_cb = ebuf + 18 * wrap_y;
         s->dsp.emulated_edge_mc(ebuf + 18 * wrap_y + 8, ptr_cr, wrap_c, 8,
                                 mb_block_height, mb_x * 8, mb_y * 8,
-                                s->width >> 1, s->height >> 1);
+                                (s->width+1) >> 1, (s->height+1) >> 1);
         ptr_cr = ebuf + 18 * wrap_y + 8;
     }
 
@@ -1981,7 +2039,7 @@
     }
 
     /* DCT & quantize */
-    assert(s->out_format != FMT_MJPEG || s->qscale == 8);
+    av_assert2(s->out_format != FMT_MJPEG || s->qscale == 8);
     {
         for (i = 0; i < mb_block_count; i++) {
             if (!skip_dct[i]) {
@@ -2077,11 +2135,12 @@
             ff_h263_encode_mb(s, s->block, motion_x, motion_y);
         break;
     case AV_CODEC_ID_MJPEG:
+    case AV_CODEC_ID_AMV:
         if (CONFIG_MJPEG_ENCODER)
             ff_mjpeg_encode_mb(s, s->block);
         break;
     default:
-        assert(0);
+        av_assert1(0);
     }
 }
 
@@ -2225,7 +2284,7 @@
         }
     }
 
-    assert(acc>=0);
+    av_assert2(acc>=0);
 
     return acc;
 }
@@ -2331,7 +2390,7 @@
 
         ff_mpeg4_stuffing(&s->pb);
     }else if(CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG){
-        ff_mjpeg_encode_stuffing(&s->pb);
+        ff_mjpeg_encode_stuffing(s);
     }
 
     avpriv_align_put_bits(&s->pb);
@@ -2420,6 +2479,11 @@
 
         s->current_picture.f.error[i] = 0;
     }
+    if(s->codec_id==AV_CODEC_ID_AMV){
+        s->last_dc[0] = 128*8/13;
+        s->last_dc[1] = 128*8/14;
+        s->last_dc[2] = 128*8/14;
+    }
     s->mb_skip_run = 0;
     memset(s->last_mv, 0, sizeof(s->last_mv));
 
@@ -2463,7 +2527,7 @@
             if(s->data_partitioning){
                 if(   s->pb2   .buf_end - s->pb2   .buf - (put_bits_count(&s->    pb2)>>3) < MAX_MB_BYTES
                    || s->tex_pb.buf_end - s->tex_pb.buf - (put_bits_count(&s->tex_pb )>>3) < MAX_MB_BYTES){
-                    av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n");
+                    av_log(s->avctx, AV_LOG_ERROR, "encoded partitioned frame too large\n");
                     return -1;
                 }
             }
@@ -2499,18 +2563,20 @@
                 case AV_CODEC_ID_MPEG1VIDEO:
                     if(s->mb_skip_run) is_gob_start=0;
                     break;
+                case AV_CODEC_ID_MJPEG:
+                    if(s->mb_x==0 && s->mb_y!=0) is_gob_start=1;
+                    break;
                 }
 
                 if(is_gob_start){
                     if(s->start_mb_y != mb_y || mb_x!=0){
                         write_slice_end(s);
-
                         if(CONFIG_MPEG4_ENCODER && s->codec_id==AV_CODEC_ID_MPEG4 && s->partitioned_frame){
                             ff_mpeg4_init_partitions(s);
                         }
                     }
 
-                    assert((put_bits_count(&s->pb)&7) == 0);
+                    av_assert2((put_bits_count(&s->pb)&7) == 0);
                     current_packet_size= put_bits_ptr(&s->pb) - s->ptr_lastgob;
 
                     if(s->avctx->error_rate && s->resync_mb_x + s->resync_mb_y > 0){
@@ -2718,7 +2784,7 @@
                         const int mvdir= (best_s.mv_dir&MV_DIR_BACKWARD) ? 1 : 0;
                         static const int dquant_tab[4]={-1,1,-2,2};
 
-                        assert(backup_s.dquant == 0);
+                        av_assert2(backup_s.dquant == 0);
 
                         //FIXME intra
                         s->mv_dir= best_s.mv_dir;
@@ -3146,6 +3212,13 @@
         update_qscale(s);
     }
 
+    if(s->codec_id != AV_CODEC_ID_AMV){
+        if(s->q_chroma_intra_matrix   != s->q_intra_matrix  ) av_freep(&s->q_chroma_intra_matrix);
+        if(s->q_chroma_intra_matrix16 != s->q_intra_matrix16) av_freep(&s->q_chroma_intra_matrix16);
+        s->q_chroma_intra_matrix   = s->q_intra_matrix;
+        s->q_chroma_intra_matrix16 = s->q_intra_matrix16;
+    }
+
     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);
@@ -3186,6 +3259,8 @@
         s->pict_type= AV_PICTURE_TYPE_I;
         for(i=0; i<s->mb_stride*s->mb_height; i++)
             s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA;
+        if(s->msmpeg4_version >= 3)
+            s->no_rounding=1;
         av_dlog(s, "Scene change detected, encoding as I Frame %d %d\n",
                 s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum);
     }
@@ -3264,6 +3339,25 @@
                        s->intra_matrix, s->intra_quant_bias, 8, 8, 1);
         s->qscale= 8;
     }
+    if(s->codec_id == AV_CODEC_ID_AMV){
+        static const uint8_t y[32]={13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13};
+        static const uint8_t c[32]={14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14};
+        for(i=1;i<64;i++){
+            int j= s->dsp.idct_permutation[ff_zigzag_direct[i]];
+
+            s->intra_matrix[j] = sp5x_quant_table[5*2+0][i];
+            s->chroma_intra_matrix[j] = sp5x_quant_table[5*2+1][i];
+        }
+        s->y_dc_scale_table= y;
+        s->c_dc_scale_table= c;
+        s->intra_matrix[0] = 13;
+        s->chroma_intra_matrix[0] = 14;
+        ff_convert_matrix(&s->dsp, s->q_intra_matrix, s->q_intra_matrix16,
+                       s->intra_matrix, s->intra_quant_bias, 8, 8, 1);
+        ff_convert_matrix(&s->dsp, s->q_chroma_intra_matrix, s->q_chroma_intra_matrix16,
+                       s->chroma_intra_matrix, s->intra_quant_bias, 8, 8, 1);
+        s->qscale= 8;
+    }
 
     //FIXME var duplication
     s->current_picture_ptr->f.key_frame =
@@ -3274,6 +3368,7 @@
     if (s->current_picture.f.key_frame)
         s->picture_in_gop_number=0;
 
+    s->mb_x = s->mb_y = 0;
     s->last_bits= put_bits_count(&s->pb);
     switch(s->out_format) {
     case FMT_MJPEG:
@@ -3307,7 +3402,7 @@
     case FMT_H264:
         break;
     default:
-        assert(0);
+        av_assert0(0);
     }
     bits= put_bits_count(&s->pb);
     s->header_bits= bits - s->last_bits;
@@ -3398,7 +3493,7 @@
         block[0] = (block[0] + (q >> 1)) / q;
         start_i = 1;
         last_non_zero = 0;
-        qmat = s->q_intra_matrix[qscale];
+        qmat = n < 4 ? s->q_intra_matrix[qscale] : s->q_chroma_intra_matrix[qscale];
         if(s->mpeg_quant || s->out_format == FMT_MPEG1)
             bias= 1<<(QMAT_SHIFT-1);
         length     = s->intra_ac_vlc_length;
@@ -3444,7 +3539,7 @@
 //                coeff[2][k]= -level+2;
             }
             coeff_count[i]= FFMIN(level, 2);
-            assert(coeff_count[i]);
+            av_assert2(coeff_count[i]);
             max |=level;
         }else{
             coeff[0][i]= (level>>31)|1;
@@ -3478,7 +3573,7 @@
             const int alevel= FFABS(level);
             int unquant_coeff;
 
-            assert(level);
+            av_assert2(level);
 
             if(s->out_format == FMT_H263){
                 unquant_coeff= alevel*qmul + qadd;
@@ -3627,7 +3722,7 @@
     }
 
     i= last_i;
-    assert(last_level);
+    av_assert2(last_level);
 
     block[ perm_scantable[last_non_zero] ]= last_level;
     i -= last_run + 1;
@@ -3743,8 +3838,8 @@
         weight[i] = w;
 //        w=weight[i] = (63*qns + (w/2)) / w;
 
-        assert(w>0);
-        assert(w<(1<<6));
+        av_assert2(w>0);
+        av_assert2(w<(1<<6));
         sum += w*w;
     }
     lambda= sum*(uint64_t)s->lambda2 >> (FF_LAMBDA_SHIFT - 6 + 6 + 6 + 6);
@@ -3810,7 +3905,7 @@
             const int level= block[0];
             int change, old_coeff;
 
-            assert(s->mb_intra);
+            av_assert2(s->mb_intra);
 
             old_coeff= q*level;
 
@@ -3853,7 +3948,7 @@
             }else{
                 old_coeff=0;
                 run2--;
-                assert(run2>=0 || i >= last_non_zero );
+                av_assert2(run2>=0 || i >= last_non_zero );
             }
 
             for(change=-1; change<=1; change+=2){
@@ -3881,7 +3976,7 @@
                                          - last_length[UNI_AC_ENC_INDEX(run, level+64)];
                         }
                     }else{
-                        assert(FFABS(new_level)==1);
+                        av_assert2(FFABS(new_level)==1);
 
                         if(analyze_gradient){
                             int g= d1[ scantable[i] ];
@@ -3914,7 +4009,7 @@
                     }
                 }else{
                     new_coeff=0;
-                    assert(FFABS(level)==1);
+                    av_assert2(FFABS(level)==1);
 
                     if(i < last_non_zero){
                         int next_i= i + run2 + 1;
@@ -3943,7 +4038,7 @@
                 score *= lambda;
 
                 unquant_change= new_coeff - old_coeff;
-                assert((score < 100*lambda && score > -100*lambda) || lambda==0);
+                av_assert2((score < 100*lambda && score > -100*lambda) || lambda==0);
 
                 score+= s->dsp.try_8x8basis(rem, weight, basis[j], unquant_change);
                 if(score<best_score){
@@ -3974,7 +4069,7 @@
 
             if(best_coeff > last_non_zero){
                 last_non_zero= best_coeff;
-                assert(block[j]);
+                av_assert2(block[j]);
 #ifdef REFINE_STATS
 after_last++;
 #endif
@@ -4065,7 +4160,7 @@
         block[0] = (block[0] + (q >> 1)) / q;
         start_i = 1;
         last_non_zero = 0;
-        qmat = s->q_intra_matrix[qscale];
+        qmat = n < 4 ? s->q_intra_matrix[qscale] : s->q_chroma_intra_matrix[qscale];
         bias= s->intra_quant_bias<<(QMAT_SHIFT - QUANT_BIAS_SHIFT);
     } else {
         start_i = 0;
diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c
index 22948e2..2e5f7e6 100644
--- a/libavcodec/mpegvideo_motion.c
+++ b/libavcodec/mpegvideo_motion.c
@@ -4,24 +4,25 @@
  *
  * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <string.h>
+#include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "dsputil.h"
 #include "mpegvideo.h"
@@ -434,7 +435,7 @@
     int i;
     uint8_t *ptr[5];
 
-    assert(s->quarter_sample==0);
+    av_assert2(s->quarter_sample==0);
 
     for(i=0; i<5; i++){
         if(i && mv[i][0]==mv[MID][0] && mv[i][1]==mv[MID][1]){
@@ -643,7 +644,7 @@
         const int mot_stride= s->b8_stride;
         const int mot_xy= mb_x*2 + mb_y*2*mot_stride;
 
-        assert(!s->mb_skipped);
+        av_assert2(!s->mb_skipped);
 
         memcpy(mv_cache[1][1], s->current_picture.f.motion_val[0][mot_xy             ], sizeof(int16_t) * 4);
         memcpy(mv_cache[2][1], s->current_picture.f.motion_val[0][mot_xy + mot_stride], sizeof(int16_t) * 4);
@@ -862,7 +863,7 @@
             }
         }
     break;
-    default: assert(0);
+    default: av_assert2(0);
     }
 }
 
diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c
index f1fc4a0..a9ed81b 100644
--- a/libavcodec/mpegvideo_parser.c
+++ b/libavcodec/mpegvideo_parser.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000,2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -170,18 +170,28 @@
 {
     int i;
     uint32_t state= -1;
+    int found=0;
 
     for(i=0; i<buf_size; i++){
         state= (state<<8) | buf[i];
-        if(state != 0x1B3 && state != 0x1B5 && state < 0x200 && state >= 0x100)
+        if(state == 0x1B3){
+            found=1;
+        }else if(found && state != 0x1B5 && state < 0x200 && state >= 0x100)
             return i-3;
     }
     return 0;
 }
 
+static int mpegvideo_parse_init(AVCodecParserContext *s)
+{
+    s->pict_type = AV_PICTURE_TYPE_NONE; // first frame might be partial
+    return 0;
+}
+
 AVCodecParser ff_mpegvideo_parser = {
     .codec_ids      = { AV_CODEC_ID_MPEG1VIDEO, AV_CODEC_ID_MPEG2VIDEO },
     .priv_data_size = sizeof(struct MpvParseContext),
+    .parser_init    = mpegvideo_parse_init,
     .parser_parse   = mpegvideo_parse,
     .parser_close   = ff_parse_close,
     .split          = mpegvideo_split,
diff --git a/libavcodec/mpegvideo_xvmc.c b/libavcodec/mpegvideo_xvmc.c
index 159fe21..6247e62 100644
--- a/libavcodec/mpegvideo_xvmc.c
+++ b/libavcodec/mpegvideo_xvmc.c
@@ -2,20 +2,20 @@
  * XVideo Motion Compensation
  * Copyright (c) 2003 Ivan Kalvachev
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mqc.c b/libavcodec/mqc.c
new file mode 100644
index 0000000..700b957
--- /dev/null
+++ b/libavcodec/mqc.c
@@ -0,0 +1,108 @@
+/*
+ * MQ-coder encoder and decoder common functions
+ * Copyright (c) 2007 Kamil Nowosad
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * MQ-coder ecoder and decoder common functions
+ * @file
+ * @author Kamil Nowosad
+ */
+
+#include "mqc.h"
+
+typedef struct {
+        uint16_t qe;
+        uint8_t  nmps;
+        uint8_t  nlps;
+        uint8_t  sw;
+} MqcCxState;
+
+const static MqcCxState cx_states[47] = {
+    {0x5601,  1,  1, 1},
+    {0x3401,  2,  6, 0},
+    {0x1801,  3,  9, 0},
+    {0x0AC1,  4, 12, 0},
+    {0x0521,  5, 29, 0},
+    {0x0221, 38, 33, 0},
+    {0x5601,  7,  6, 1},
+    {0x5401,  8, 14, 0},
+    {0x4801,  9, 14, 0},
+    {0x3801, 10, 14, 0},
+    {0x3001, 11, 17, 0},
+    {0x2401, 12, 18, 0},
+    {0x1C01, 13, 20, 0},
+    {0x1601, 29, 21, 0},
+    {0x5601, 15, 14, 1},
+    {0x5401, 16, 14, 0},
+    {0x5101, 17, 15, 0},
+    {0x4801, 18, 16, 0},
+    {0x3801, 19, 17, 0},
+    {0x3401, 20, 18, 0},
+    {0x3001, 21, 19, 0},
+    {0x2801, 22, 19, 0},
+    {0x2401, 23, 20, 0},
+    {0x2201, 24, 21, 0},
+    {0x1C01, 25, 22, 0},
+    {0x1801, 26, 23, 0},
+    {0x1601, 27, 24, 0},
+    {0x1401, 28, 25, 0},
+    {0x1201, 29, 26, 0},
+    {0x1101, 30, 27, 0},
+    {0x0AC1, 31, 28, 0},
+    {0x09C1, 32, 29, 0},
+    {0x08A1, 33, 30, 0},
+    {0x0521, 34, 31, 0},
+    {0x0441, 35, 32, 0},
+    {0x02A1, 36, 33, 0},
+    {0x0221, 37, 34, 0},
+    {0x0141, 38, 35, 0},
+    {0x0111, 39, 36, 0},
+    {0x0085, 40, 37, 0},
+    {0x0049, 41, 38, 0},
+    {0x0025, 42, 39, 0},
+    {0x0015, 43, 40, 0},
+    {0x0009, 44, 41, 0},
+    {0x0005, 45, 42, 0},
+    {0x0001, 45, 43, 0},
+    {0x5601, 46, 46, 0}
+};
+
+uint16_t ff_mqc_qe [2*47];
+uint8_t ff_mqc_nlps[2*47];
+uint8_t ff_mqc_nmps[2*47];
+
+void ff_mqc_init_contexts(MqcState *mqc)
+{
+    int i;
+    memset(mqc->cx_states, 0, sizeof(mqc->cx_states));
+    mqc->cx_states[MQC_CX_UNI] = 2 * 46;
+    mqc->cx_states[MQC_CX_RL] = 2 * 3;
+    mqc->cx_states[0] = 2 * 4;
+
+    for (i = 0; i < 47; i++){
+        ff_mqc_qe[2*i  ] =
+        ff_mqc_qe[2*i+1] = cx_states[i].qe;
+
+        ff_mqc_nlps[2*i  ] = 2*cx_states[i].nlps + cx_states[i].sw;
+        ff_mqc_nlps[2*i+1] = 2*cx_states[i].nlps + 1 - cx_states[i].sw;
+        ff_mqc_nmps[2*i  ] = 2*cx_states[i].nmps;
+        ff_mqc_nmps[2*i+1] = 2*cx_states[i].nmps + 1;
+    }
+}
diff --git a/libavcodec/mqc.h b/libavcodec/mqc.h
new file mode 100644
index 0000000..b28c13e
--- /dev/null
+++ b/libavcodec/mqc.h
@@ -0,0 +1,75 @@
+/*
+ * MQ-coder
+ * Copyright (c) 2007 Kamil Nowosad
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_MQC_H
+#define AVCODEC_MQC_H
+
+/**
+ * MQ-coder
+ * @file
+ * @author Kamil Nowosad
+ */
+
+#include "avcodec.h"
+
+#define MQC_CX_UNI 17
+#define MQC_CX_RL  18
+
+extern uint16_t  ff_mqc_qe[2*47];
+extern uint8_t ff_mqc_nlps[2*47];
+extern uint8_t ff_mqc_nmps[2*47];
+
+typedef struct {
+    uint8_t *bp, *bpstart;
+    unsigned int a;
+    unsigned int c;
+    unsigned int ct;
+    uint8_t cx_states[19];
+} MqcState;
+
+/* encoder */
+
+/** initialize the encoder */
+void ff_mqc_initenc(MqcState *mqc, uint8_t *bp);
+
+/** code bit d with context cx */
+void ff_mqc_encode(MqcState *mqc, uint8_t *cxstate, int d);
+
+/** number of encoded bytes */
+int ff_mqc_length(MqcState *mqc);
+
+/** flush the encoder [returns number of bytes encoded] */
+int ff_mqc_flush(MqcState *mqc);
+
+/* decoder */
+
+/** initialize the decoder */
+void ff_mqc_initdec(MqcState *mqc, uint8_t *bp);
+
+/** returns decoded bit with context cx */
+int ff_mqc_decode(MqcState *mqc, uint8_t *cxstate);
+
+/* common */
+
+/** initialize the contexts */
+void ff_mqc_init_contexts(MqcState *mqc);
+
+#endif /* AVCODEC_MQC_H */
diff --git a/libavcodec/mqcdec.c b/libavcodec/mqcdec.c
new file mode 100644
index 0000000..56e22f8
--- /dev/null
+++ b/libavcodec/mqcdec.c
@@ -0,0 +1,93 @@
+/*
+ * MQ-coder decoder
+ * Copyright (c) 2007 Kamil Nowosad
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * MQ-coder decoder
+ * @file
+ * @author Kamil Nowosad
+ */
+
+#include "mqc.h"
+
+static void bytein(MqcState *mqc)
+{
+    if (*mqc->bp == 0xff){
+        if (*(mqc->bp+1) > 0x8f)
+            mqc->c++;
+        else{
+            mqc->bp++;
+            mqc->c += 2 + 0xfe00 - (*mqc->bp << 9);
+        }
+    } else{
+        mqc->bp++;
+        mqc->c += 1 + 0xff00 - (*mqc->bp << 8);
+    }
+}
+
+static int exchange(MqcState *mqc, uint8_t *cxstate, int lps)
+{
+    int d;
+    if ((mqc->a < ff_mqc_qe[*cxstate]) ^ (!lps)){
+        if (lps)
+            mqc->a = ff_mqc_qe[*cxstate];
+        d = *cxstate & 1;
+        *cxstate = ff_mqc_nmps[*cxstate];
+    } else{
+        if (lps)
+            mqc->a = ff_mqc_qe[*cxstate];
+        d = 1 - (*cxstate & 1);
+        *cxstate = ff_mqc_nlps[*cxstate];
+    }
+    // renormd:
+    do{
+        if (!(mqc->c & 0xff)){
+            mqc->c -= 0x100;
+            bytein(mqc);
+        }
+        mqc->a += mqc->a;
+        mqc->c += mqc->c;
+    } while (!(mqc->a & 0x8000));
+    return d;
+}
+
+void ff_mqc_initdec(MqcState *mqc, uint8_t *bp)
+{
+    ff_mqc_init_contexts(mqc);
+    mqc->bp = bp;
+    mqc->c = (*mqc->bp ^ 0xff) << 16;
+    bytein(mqc);
+    mqc->c = mqc->c << 7;
+    mqc->a = 0x8000;
+}
+
+int ff_mqc_decode(MqcState *mqc, uint8_t *cxstate)
+{
+    mqc->a -= ff_mqc_qe[*cxstate];
+    if ((mqc->c >> 16) < mqc->a){
+        if (mqc->a & 0x8000)
+            return *cxstate & 1;
+        else
+            return exchange(mqc, cxstate, 0);
+    } else {
+        mqc->c -= mqc->a << 16;
+        return exchange(mqc, cxstate, 1);
+    }
+}
diff --git a/libavcodec/mqcenc.c b/libavcodec/mqcenc.c
new file mode 100644
index 0000000..97d352b
--- /dev/null
+++ b/libavcodec/mqcenc.c
@@ -0,0 +1,119 @@
+/*
+ * MQ-coder encoder
+ * Copyright (c) 2007 Kamil Nowosad
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * MQ-coder encoder
+ * @file
+ * @author Kamil Nowosad
+ */
+
+#include "mqc.h"
+
+static void byteout(MqcState *mqc)
+{
+retry:
+    if (*mqc->bp == 0xff){
+        mqc->bp++;
+        *mqc->bp = mqc->c >> 20;
+        mqc->c &= 0xfffff;
+        mqc->ct = 7;
+    } else if ((mqc->c & 0x8000000)){
+        (*mqc->bp)++;
+        mqc->c &= 0x7ffffff;
+        goto retry;
+    } else{
+        mqc->bp++;
+        *mqc->bp = mqc->c >> 19;
+        mqc->c &= 0x7ffff;
+        mqc->ct = 8;
+    }
+}
+
+static void renorme(MqcState *mqc)
+{
+    do{
+        mqc->a += mqc->a;
+        mqc->c += mqc->c;
+        if (!--mqc->ct)
+            byteout(mqc);
+    } while (!(mqc->a & 0x8000));
+}
+
+static void setbits(MqcState *mqc)
+{
+    int tmp = mqc->c + mqc->a;
+    mqc->c |= 0xffff;
+    if (mqc->c >= tmp)
+        mqc->c -= 0x8000;
+}
+
+void ff_mqc_initenc(MqcState *mqc, uint8_t *bp)
+{
+    ff_mqc_init_contexts(mqc);
+    mqc->a = 0x8000;
+    mqc->c = 0;
+    mqc->bp = bp-1;
+    mqc->bpstart = bp;
+    mqc->ct = 12 + (*mqc->bp == 0xff);
+}
+
+void ff_mqc_encode(MqcState *mqc, uint8_t *cxstate, int d)
+{
+    int qe;
+
+    qe = ff_mqc_qe[*cxstate];
+    mqc->a -= qe;
+    if ((*cxstate & 1) == d){
+        if (!(mqc->a & 0x8000)){
+            if (mqc->a < qe)
+                mqc->a = qe;
+            else
+                mqc->c += qe;
+            *cxstate = ff_mqc_nmps[*cxstate];
+            renorme(mqc);
+        } else
+            mqc->c += qe;
+    } else{
+        if (mqc->a < qe)
+            mqc->c += qe;
+        else
+            mqc->a = qe;
+        *cxstate = ff_mqc_nlps[*cxstate];
+        renorme(mqc);
+    }
+}
+
+int ff_mqc_length(MqcState *mqc)
+{
+    return mqc->bp - mqc->bpstart;
+}
+
+int ff_mqc_flush(MqcState *mqc)
+{
+    setbits(mqc);
+    mqc->c = mqc->c << mqc->ct;
+    byteout(mqc);
+    mqc->c = mqc->c << mqc->ct;
+    byteout(mqc);
+    if (*mqc->bp != 0xff)
+        mqc->bp++;
+    return mqc->bp - mqc->bpstart;
+}
diff --git a/libavcodec/msgsmdec.c b/libavcodec/msgsmdec.c
index 52b0f5d..90e83ae 100644
--- a/libavcodec/msgsmdec.c
+++ b/libavcodec/msgsmdec.c
@@ -2,20 +2,20 @@
  * gsm 06.10 decoder, Microsoft variant
  * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/msgsmdec.h b/libavcodec/msgsmdec.h
index 76c87f1..3bfd1fd 100644
--- a/libavcodec/msgsmdec.h
+++ b/libavcodec/msgsmdec.h
@@ -2,20 +2,20 @@
  * gsm 06.10 decoder, Microsoft variant
  * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c
index 5e562d8..0f8b57e 100644
--- a/libavcodec/msmpeg4.c
+++ b/libavcodec/msmpeg4.c
@@ -5,20 +5,20 @@
  *
  * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -409,6 +409,7 @@
 static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM 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];
 
     if (s->pict_type == AV_PICTURE_TYPE_P) {
         if (s->use_skip_mb_code) {
@@ -422,6 +423,7 @@
                 s->mv[0][0][0] = 0;
                 s->mv[0][0][1] = 0;
                 s->mb_skipped = 1;
+                *mb_type_ptr = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
                 return 0;
             }
         }
@@ -470,6 +472,7 @@
         s->mv_type = MV_TYPE_16X16;
         s->mv[0][0][0] = mx;
         s->mv[0][0][1] = my;
+        *mb_type_ptr = MB_TYPE_L0 | MB_TYPE_16x16;
     } else {
         if(s->msmpeg4_version==2){
             s->ac_pred = get_bits1(&s->gb);
@@ -479,6 +482,7 @@
             cbp|= get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors
             if(s->pict_type==AV_PICTURE_TYPE_P) cbp^=0x3C;
         }
+        *mb_type_ptr = MB_TYPE_INTRA;
     }
 
     s->dsp.clear_blocks(s->block[0]);
@@ -1139,7 +1143,7 @@
             i-= 192;
             if(i&(~63)){
                 const int left= get_bits_left(&s->gb);
-                if(((i+192 == 64 && level/qmul==-1) || !(s->err_recognition&AV_EF_BITSTREAM)) && left>=0){
+                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);
                     break;
                 }else{
@@ -1216,6 +1220,7 @@
     .close          = ff_h263_decode_end,
     .decode         = ff_h263_decode_frame,
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+    .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 1"),
     .pix_fmts       = ff_pixfmt_list_420,
 };
@@ -1229,6 +1234,7 @@
     .close          = ff_h263_decode_end,
     .decode         = ff_h263_decode_frame,
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+    .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"),
     .pix_fmts       = ff_pixfmt_list_420,
 };
@@ -1242,6 +1248,7 @@
     .close          = ff_h263_decode_end,
     .decode         = ff_h263_decode_frame,
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+    .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"),
     .pix_fmts       = ff_pixfmt_list_420,
 };
@@ -1255,6 +1262,7 @@
     .close          = ff_h263_decode_end,
     .decode         = ff_h263_decode_frame,
     .capabilities   = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
+    .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 7"),
     .pix_fmts       = ff_pixfmt_list_420,
 };
diff --git a/libavcodec/msmpeg4.h b/libavcodec/msmpeg4.h
index 8fe07f2..abc414c 100644
--- a/libavcodec/msmpeg4.h
+++ b/libavcodec/msmpeg4.h
@@ -2,20 +2,20 @@
  * MSMPEG4 backend for encoder and decoder
  * copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/msmpeg4data.c b/libavcodec/msmpeg4data.c
index 5721d8f..50ba18c 100644
--- a/libavcodec/msmpeg4data.c
+++ b/libavcodec/msmpeg4data.c
@@ -5,20 +5,20 @@
  *
  * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/msmpeg4data.h b/libavcodec/msmpeg4data.h
index ca2dac1..24a10d9 100644
--- a/libavcodec/msmpeg4data.h
+++ b/libavcodec/msmpeg4data.h
@@ -5,20 +5,20 @@
  *
  * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c
index 4a362c3..458ec09 100644
--- a/libavcodec/msmpeg4enc.c
+++ b/libavcodec/msmpeg4enc.c
@@ -5,20 +5,20 @@
  *
  * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -149,8 +149,8 @@
 static void find_best_tables(MpegEncContext * s)
 {
     int i;
-    int best       =-1, best_size       =9999999;
-    int chroma_best=-1, best_chroma_size=9999999;
+    int best        = 0, best_size        = INT_MAX;
+    int chroma_best = 0, best_chroma_size = INT_MAX;
 
     for(i=0; i<3; i++){
         int level;
@@ -273,14 +273,15 @@
 
 void ff_msmpeg4_encode_ext_header(MpegEncContext * s)
 {
-        put_bits(&s->pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); //yes 29.97 -> 29
+        unsigned fps = s->avctx->time_base.den / s->avctx->time_base.num / FFMAX(s->avctx->ticks_per_frame, 1);
+        put_bits(&s->pb, 5, FFMIN(fps, 31)); //yes 29.97 -> 29
 
         put_bits(&s->pb, 11, FFMIN(s->bit_rate/1024, 2047));
 
         if(s->msmpeg4_version>=3)
             put_bits(&s->pb, 1, s->flipflop_rounding);
         else
-            assert(s->flipflop_rounding==0);
+            av_assert0(s->flipflop_rounding==0);
 }
 
 void ff_msmpeg4_encode_motion(MpegEncContext * s,
diff --git a/libavcodec/msrle.c b/libavcodec/msrle.c
index 06305bf..0e8a0e5 100644
--- a/libavcodec/msrle.c
+++ b/libavcodec/msrle.c
@@ -2,20 +2,20 @@
  * Microsoft RLE video decoder
  * Copyright (C) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -50,10 +50,14 @@
 static av_cold int msrle_decode_init(AVCodecContext *avctx)
 {
     MsrleContext *s = avctx->priv_data;
+    int i;
 
     s->avctx = avctx;
 
     switch (avctx->bits_per_coded_sample) {
+    case 1:
+        avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
+        break;
     case 4:
     case 8:
         avctx->pix_fmt = AV_PIX_FMT_PAL8;
@@ -66,8 +70,13 @@
         return -1;
     }
 
+    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++)
+            s->pal[i] = 0xFF<<24 | AV_RL32(avctx->extradata+4*i);
+
     return 0;
 }
 
@@ -83,28 +92,27 @@
     s->buf = buf;
     s->size = buf_size;
 
-    s->frame.reference = 1;
+    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)) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return -1;
     }
 
-    if (avctx->bits_per_coded_sample <= 8) {
+    if (avctx->bits_per_coded_sample > 1 && avctx->bits_per_coded_sample <= 8) {
         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
 
         if (pal) {
             s->frame.palette_has_changed = 1;
             memcpy(s->pal, pal, AVPALETTE_SIZE);
         }
-
         /* make the palette available */
         memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);
     }
 
     /* FIXME how to correctly detect RLE ??? */
     if (avctx->height * istride == avpkt->size) { /* assume uncompressed */
-        int linesize = avctx->width * avctx->bits_per_coded_sample / 8;
+        int linesize = (avctx->width * avctx->bits_per_coded_sample + 7) / 8;
         uint8_t *ptr = s->frame.data[0];
         uint8_t *buf = avpkt->data + (avctx->height-1)*istride;
         int i, j;
diff --git a/libavcodec/msrledec.c b/libavcodec/msrledec.c
index fad9415..36a46b5 100644
--- a/libavcodec/msrledec.c
+++ b/libavcodec/msrledec.c
@@ -2,20 +2,20 @@
  * Microsoft RLE decoder
  * Copyright (C) 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/msrledec.h b/libavcodec/msrledec.h
index a594de3..3f66636 100644
--- a/libavcodec/msrledec.h
+++ b/libavcodec/msrledec.h
@@ -2,20 +2,20 @@
  * Microsoft RLE decoder
  * Copyright (C) 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mss1.c b/libavcodec/mss1.c
index f72385f..660dd89 100644
--- a/libavcodec/mss1.c
+++ b/libavcodec/mss1.c
@@ -2,20 +2,20 @@
  * Microsoft Screen 1 (aka Windows Media Video V7 Screen) decoder
  * Copyright (c) 2012 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -129,7 +129,7 @@
         r = arith_get_bits(acoder, 8);
         g = arith_get_bits(acoder, 8);
         b = arith_get_bits(acoder, 8);
-        *pal++ = (r << 16) | (g << 8) | b;
+        *pal++ = (0xFF << 24) | (r << 16) | (g << 8) | b;
     }
 
     return !!ncol;
diff --git a/libavcodec/mss12.c b/libavcodec/mss12.c
index 3601978..b8df225 100644
--- a/libavcodec/mss12.c
+++ b/libavcodec/mss12.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2012 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -448,7 +448,7 @@
         val = acoder->get_number(acoder, (base + 1) / 2 - 2) + 3;
     }
 
-    if (val >= base)
+    if ((unsigned)val >= base)
         return -1;
 
     return inv ? base - val : val;
@@ -645,7 +645,7 @@
     }
 
     for (i = 0; i < 256; i++)
-        c->pal[i] = AV_RB24(avctx->extradata + 52 +
+        c->pal[i] = 0xFF << 24 | AV_RB24(avctx->extradata + 52 +
                             (version ? 8 : 0) + i * 3);
 
     c->mask_stride = FFALIGN(avctx->width, 16);
diff --git a/libavcodec/mss12.h b/libavcodec/mss12.h
index f5d0366..42ceab5 100644
--- a/libavcodec/mss12.h
+++ b/libavcodec/mss12.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2012 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mss2.c b/libavcodec/mss2.c
index 597ebb6..10687f0 100644
--- a/libavcodec/mss2.c
+++ b/libavcodec/mss2.c
@@ -1,20 +1,20 @@
 /*
  * Microsoft Screen 2 (aka Windows Media Video V9 Screen) decoder
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mss2dsp.c b/libavcodec/mss2dsp.c
index aa13577..b18bf1f 100644
--- a/libavcodec/mss2dsp.c
+++ b/libavcodec/mss2dsp.c
@@ -1,20 +1,20 @@
 /*
  * Microsoft Screen 2 (aka Windows Media Video V9 Screen) decoder
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mss2dsp.h b/libavcodec/mss2dsp.h
index b3d67a1..e04aab0 100644
--- a/libavcodec/mss2dsp.h
+++ b/libavcodec/mss2dsp.h
@@ -1,20 +1,20 @@
 /*
  * Microsoft Screen 2 (aka Windows Media Video V9 Screen) decoder
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mss3.c b/libavcodec/mss3.c
index a41db22..91aceb2 100644
--- a/libavcodec/mss3.c
+++ b/libavcodec/mss3.c
@@ -2,20 +2,20 @@
  * Microsoft Screen 3 (aka Microsoft ATC Screen) decoder
  * Copyright (c) 2012 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mss34dsp.c b/libavcodec/mss34dsp.c
index 11abb2d..e4d4299 100644
--- a/libavcodec/mss34dsp.c
+++ b/libavcodec/mss34dsp.c
@@ -2,20 +2,20 @@
  * Common stuff for some Microsoft Screen codecs
  * Copyright (C) 2012 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mss34dsp.h b/libavcodec/mss34dsp.h
index b2cc550..2f9827d 100644
--- a/libavcodec/mss34dsp.h
+++ b/libavcodec/mss34dsp.h
@@ -2,20 +2,20 @@
  * Common stuff for some Microsoft Screen codecs
  * Copyright (C) 2012 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/mss4.c b/libavcodec/mss4.c
index 1c850bc..51db721 100644
--- a/libavcodec/mss4.c
+++ b/libavcodec/mss4.c
@@ -2,20 +2,20 @@
  * Microsoft Screen 4 (aka Microsoft Expression Encoder Screen) decoder
  * Copyright (c) 2012 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/msvideo1.c b/libavcodec/msvideo1.c
index 644fecf..8d1164b 100644
--- a/libavcodec/msvideo1.c
+++ b/libavcodec/msvideo1.c
@@ -2,20 +2,20 @@
  * Microsoft Video-1 Decoder
  * Copyright (C) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -71,6 +71,7 @@
         avctx->pix_fmt = AV_PIX_FMT_RGB555;
     }
 
+    avcodec_get_frame_defaults(&s->frame);
     s->frame.data[0] = NULL;
 
     return 0;
@@ -296,7 +297,7 @@
     s->buf = buf;
     s->size = buf_size;
 
-    s->frame.reference = 1;
+    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)) {
         av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
diff --git a/libavcodec/msvideo1enc.c b/libavcodec/msvideo1enc.c
new file mode 100644
index 0000000..50c0a06
--- /dev/null
+++ b/libavcodec/msvideo1enc.c
@@ -0,0 +1,311 @@
+/*
+ * Microsoft Video-1 Encoder
+ * Copyright (c) 2009 Konstantin Shishkov
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Microsoft Video-1 encoder
+ */
+
+#include "avcodec.h"
+#include "internal.h"
+#include "bytestream.h"
+#include "libavutil/lfg.h"
+#include "elbg.h"
+#include "libavutil/imgutils.h"
+/**
+ * Encoder context
+ */
+typedef struct Msvideo1EncContext {
+    AVCodecContext *avctx;
+    AVFrame pic;
+    AVLFG rnd;
+    uint8_t *prev;
+
+    int block[16*3];
+    int block2[16*3];
+    int codebook[8*3];
+    int codebook2[8*3];
+    int output[16*3];
+    int output2[16*3];
+    int avg[3];
+    int bestpos;
+    int keyint;
+} Msvideo1EncContext;
+
+enum MSV1Mode{
+    MODE_SKIP = 0,
+    MODE_FILL,
+    MODE_2COL,
+    MODE_8COL,
+};
+
+#define SKIP_PREFIX 0x8400
+#define SKIPS_MAX 0x0FFF
+#define MKRGB555(in, off) ((in[off] << 10) | (in[off + 1] << 5) | (in[off + 2]))
+
+static const int remap[16] = { 0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15 };
+
+static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                               const AVFrame *pict, int *got_packet)
+{
+    Msvideo1EncContext * const c = avctx->priv_data;
+    AVFrame * const p = &c->pic;
+    uint16_t *src;
+    uint8_t *prevptr;
+    uint8_t *dst, *buf;
+    int keyframe = 1;
+    int no_skips = 1;
+    int i, j, k, x, y, ret;
+    int skips = 0;
+
+    if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*9 + FF_MIN_BUFFER_SIZE)) < 0)
+        return ret;
+    dst= buf= pkt->data;
+
+    *p = *pict;
+    if(!c->prev)
+        c->prev = av_malloc(avctx->width * 3 * (avctx->height + 3));
+    prevptr = c->prev + avctx->width * 3 * (FFALIGN(avctx->height, 4) - 1);
+    src = (uint16_t*)(p->data[0] + p->linesize[0]*(FFALIGN(avctx->height, 4) - 1));
+    if(c->keyint >= avctx->keyint_min)
+        keyframe = 1;
+
+    p->quality = 24;
+
+    for(y = 0; y < avctx->height; y += 4){
+        for(x = 0; x < avctx->width; x += 4){
+            int bestmode = MODE_SKIP;
+            int bestscore = INT_MAX;
+            int flags = 0;
+            int score;
+
+            for(j = 0; j < 4; j++){
+                for(i = 0; i < 4; i++){
+                    uint16_t val = src[x + i - j*p->linesize[0]/2];
+                    for(k = 0; k < 3; k++){
+                        c->block[(i + j*4)*3 + k] =
+                        c->block2[remap[i + j*4]*3 + k] = (val >> (10-k*5)) & 0x1F;
+                    }
+                }
+            }
+            if(!keyframe){
+                bestscore = 0;
+                for(j = 0; j < 4; j++){
+                    for(i = 0; i < 4*3; i++){
+                        int t = prevptr[x*3 + i + j*p->linesize[0]] - c->block[i + j*4*3];
+                        bestscore += t*t;
+                    }
+                }
+                bestscore /= p->quality;
+            }
+            // try to find optimal value to fill whole 4x4 block
+            score = 0;
+            ff_init_elbg(c->block, 3, 16, c->avg, 1, 1, c->output, &c->rnd);
+            ff_do_elbg  (c->block, 3, 16, c->avg, 1, 1, c->output, &c->rnd);
+            if(c->avg[0] == 1) // red component = 1 will be written as skip code
+                c->avg[0] = 0;
+            for(j = 0; j < 4; j++){
+                for(i = 0; i < 4; i++){
+                    for(k = 0; k < 3; k++){
+                        int t = c->avg[k] - c->block[(i+j*4)*3+k];
+                        score += t*t;
+                    }
+                }
+            }
+            score /= p->quality;
+            score += 2;
+            if(score < bestscore){
+                bestscore = score;
+                bestmode = MODE_FILL;
+            }
+            // search for optimal filling of 2-color block
+            score = 0;
+            ff_init_elbg(c->block, 3, 16, c->codebook, 2, 1, c->output, &c->rnd);
+            ff_do_elbg  (c->block, 3, 16, c->codebook, 2, 1, c->output, &c->rnd);
+            // last output value should be always 1, swap codebooks if needed
+            if(!c->output[15]){
+                for(i = 0; i < 3; i++)
+                    FFSWAP(uint8_t, c->codebook[i], c->codebook[i+3]);
+                for(i = 0; i < 16; i++)
+                    c->output[i] ^= 1;
+            }
+            for(j = 0; j < 4; j++){
+                for(i = 0; i < 4; i++){
+                    for(k = 0; k < 3; k++){
+                        int t = c->codebook[c->output[i+j*4]*3 + k] - c->block[i*3+k+j*4*3];
+                        score += t*t;
+                    }
+                }
+            }
+            score /= p->quality;
+            score += 6;
+            if(score < bestscore){
+                bestscore = score;
+                bestmode = MODE_2COL;
+            }
+            // search for optimal filling of 2-color 2x2 subblocks
+            score = 0;
+            for(i = 0; i < 4; i++){
+                ff_init_elbg(c->block2 + i*4*3, 3, 4, c->codebook2 + i*2*3, 2, 1, c->output2 + i*4, &c->rnd);
+                ff_do_elbg  (c->block2 + i*4*3, 3, 4, c->codebook2 + i*2*3, 2, 1, c->output2 + i*4, &c->rnd);
+            }
+            // last value should be always 1, swap codebooks if needed
+            if(!c->output2[15]){
+                for(i = 0; i < 3; i++)
+                    FFSWAP(uint8_t, c->codebook2[i+18], c->codebook2[i+21]);
+                for(i = 12; i < 16; i++)
+                    c->output2[i] ^= 1;
+            }
+            for(j = 0; j < 4; j++){
+                for(i = 0; i < 4; i++){
+                    for(k = 0; k < 3; k++){
+                        int t = c->codebook2[(c->output2[remap[i+j*4]] + (i&2) + (j&2)*2)*3+k] - c->block[i*3+k + j*4*3];
+                        score += t*t;
+                    }
+                }
+            }
+            score /= p->quality;
+            score += 18;
+            if(score < bestscore){
+                bestscore = score;
+                bestmode = MODE_8COL;
+            }
+
+            if(bestmode == MODE_SKIP){
+                skips++;
+                no_skips = 0;
+            }
+            if((bestmode != MODE_SKIP && skips) || skips == SKIPS_MAX){
+                bytestream_put_le16(&dst, skips | SKIP_PREFIX);
+                skips = 0;
+            }
+
+            switch(bestmode){
+            case MODE_FILL:
+                bytestream_put_le16(&dst, MKRGB555(c->avg,0) | 0x8000);
+                for(j = 0; j < 4; j++)
+                    for(i = 0; i < 4; i++)
+                        for(k = 0; k < 3; k++)
+                            prevptr[i*3 + k - j*3*avctx->width] = c->avg[k];
+                break;
+            case MODE_2COL:
+                for(j = 0; j < 4; j++){
+                    for(i = 0; i < 4; i++){
+                        flags |= (c->output[i + j*4]^1) << (i + j*4);
+                        for(k = 0; k < 3; k++)
+                            prevptr[i*3 + k - j*3*avctx->width] = c->codebook[c->output[i + j*4]*3 + k];
+                    }
+                }
+                bytestream_put_le16(&dst, flags);
+                bytestream_put_le16(&dst, MKRGB555(c->codebook, 0));
+                bytestream_put_le16(&dst, MKRGB555(c->codebook, 3));
+                break;
+            case MODE_8COL:
+                for(j = 0; j < 4; j++){
+                    for(i = 0; i < 4; i++){
+                        flags |= (c->output2[remap[i + j*4]]^1) << (i + j*4);
+                        for(k = 0; k < 3; k++)
+                            prevptr[i*3 + k - j*3*avctx->width] = c->codebook2[(c->output2[remap[i+j*4]] + (i&2) + (j&2)*2)*3 + k];
+                    }
+                }
+                bytestream_put_le16(&dst, flags);
+                bytestream_put_le16(&dst, MKRGB555(c->codebook2, 0) | 0x8000);
+                for(i = 3; i < 24; i += 3)
+                    bytestream_put_le16(&dst, MKRGB555(c->codebook2, i));
+                break;
+            }
+        }
+        src     -= p->linesize[0] << 1;
+        prevptr -= avctx->width * 3 * 4;
+    }
+    if(skips)
+        bytestream_put_le16(&dst, skips | SKIP_PREFIX);
+    //EOF
+    bytestream_put_byte(&dst, 0);
+    bytestream_put_byte(&dst, 0);
+
+    if(no_skips)
+        keyframe = 1;
+    if(keyframe)
+        c->keyint = 0;
+    else
+        c->keyint++;
+    p->pict_type= keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+    p->key_frame= keyframe;
+    if (keyframe) pkt->flags |= AV_PKT_FLAG_KEY;
+    pkt->size = dst - buf;
+    *got_packet = 1;
+
+    return 0;
+}
+
+
+/**
+ * init encoder
+ */
+static av_cold int encode_init(AVCodecContext *avctx)
+{
+    Msvideo1EncContext * const c = avctx->priv_data;
+
+    c->avctx = avctx;
+    if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) {
+        return -1;
+    }
+    if((avctx->width&3) || (avctx->height&3)){
+        av_log(avctx, AV_LOG_ERROR, "width and height must be multiplies of 4\n");
+        return -1;
+    }
+
+    avcodec_get_frame_defaults(&c->pic);
+    avctx->coded_frame = (AVFrame*)&c->pic;
+    avctx->bits_per_coded_sample = 16;
+
+    c->keyint = avctx->keyint_min;
+    av_lfg_init(&c->rnd, 1);
+
+    return 0;
+}
+
+
+
+/**
+ * Uninit encoder
+ */
+static av_cold int encode_end(AVCodecContext *avctx)
+{
+    Msvideo1EncContext * const c = avctx->priv_data;
+
+    av_freep(&c->prev);
+
+    return 0;
+}
+
+AVCodec ff_msvideo1_encoder = {
+    .name           = "msvideo1",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_MSVIDEO1,
+    .priv_data_size = sizeof(Msvideo1EncContext),
+    .init           = encode_init,
+    .encode2        = encode_frame,
+    .close          = encode_end,
+    .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_RGB555, AV_PIX_FMT_NONE},
+    .long_name = NULL_IF_CONFIG_SMALL("Microsoft Video-1"),
+};
diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c
index 77357fd..c1e1512 100644
--- a/libavcodec/mxpegdec.c
+++ b/libavcodec/mxpegdec.c
@@ -2,20 +2,20 @@
  * MxPEG decoder
  * Copyright (c) 2011 Anatoly Nenashev
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -80,6 +80,7 @@
     }
 
     if (s->bitmask_size != bitmask_size) {
+        s->bitmask_size = 0;
         av_freep(&s->mxm_bitmask);
         s->mxm_bitmask = av_malloc(bitmask_size);
         if (!s->mxm_bitmask) {
@@ -338,4 +339,5 @@
     .close          = mxpeg_decode_end,
     .decode         = mxpeg_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
+    .max_lowres     = 3,
 };
diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c
index fce184a..ae98bf5 100644
--- a/libavcodec/nellymoserdec.c
+++ b/libavcodec/nellymoserdec.c
@@ -141,16 +141,19 @@
                       int *got_frame_ptr, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
+    const uint8_t *side=av_packet_get_side_data(avpkt, 'F', NULL);
     int buf_size = avpkt->size;
     NellyMoserDecodeContext *s = avctx->priv_data;
     int blocks, i, ret;
     float   *samples_flt;
 
     blocks     = buf_size / NELLY_BLOCK_LEN;
+
     if (blocks <= 0) {
         av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
         return AVERROR_INVALIDDATA;
     }
+
     if (buf_size % NELLY_BLOCK_LEN) {
         av_log(avctx, AV_LOG_WARNING, "Leftover bytes: %d.\n",
                buf_size % NELLY_BLOCK_LEN);
@@ -162,6 +165,8 @@
      * 22050 Hz - 4
      * 44100 Hz - 8
      */
+    if(side && blocks>1 && avctx->sample_rate%11025==0 && (1<<((side[0]>>2)&3)) == blocks)
+        avctx->sample_rate= 11025*(blocks/2);
 
     /* get output buffer */
     s->frame.nb_samples = NELLY_SAMPLES * blocks;
diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c
index 487cffd..4317e32 100644
--- a/libavcodec/nellymoserenc.c
+++ b/libavcodec/nellymoserenc.c
@@ -4,20 +4,20 @@
  *
  * Copyright (c) 2008 Bartlomiej Wolowiec
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -28,7 +28,7 @@
  *
  * Generic codec information: libavcodec/nellymoserdec.c
  *
- * Some information also from: http://samples.libav.org/A-codecs/Nelly_Moser/ASAO/ASAO.zip
+ * Some information also from: http://samples.mplayerhq.hu/A-codecs/Nelly_Moser/ASAO/ASAO.zip
  *                             (Copyright Joseph Artsimovich and UAB "DKD")
  *
  * for more information about nellymoser format, visit:
@@ -62,8 +62,8 @@
     DECLARE_ALIGNED(32, float, mdct_out)[NELLY_SAMPLES];
     DECLARE_ALIGNED(32, float, in_buff)[NELLY_SAMPLES];
     DECLARE_ALIGNED(32, float, buf)[3 * NELLY_BUF_LEN];     ///< sample buffer
-    float           (*opt )[NELLY_BANDS];
-    uint8_t         (*path)[NELLY_BANDS];
+    float           (*opt )[OPT_SIZE];
+    uint8_t         (*path)[OPT_SIZE];
 } NellyMoserEncodeContext;
 
 static float pow_table[POW_TABLE_SIZE];     ///< -pow(2, -i / 2048.0 - 3.0);
@@ -177,7 +177,7 @@
     avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT);
 
     /* Generate overlap window */
-    ff_sine_window_init(ff_sine_128, 128);
+    ff_init_ff_sine_windows(7);
     for (i = 0; i < POW_TABLE_SIZE; i++)
         pow_table[i] = -pow(2, -i / 2048.0 - 3.0 + POW_TABLE_OFFSET);
 
@@ -240,8 +240,8 @@
     int i, j, band, best_idx;
     float power_candidate, best_val;
 
-    float  (*opt )[NELLY_BANDS] = s->opt ;
-    uint8_t(*path)[NELLY_BANDS] = s->path;
+    float  (*opt )[OPT_SIZE] = s->opt ;
+    uint8_t(*path)[OPT_SIZE] = s->path;
 
     for (i = 0; i < NELLY_BANDS * OPT_SIZE; i++) {
         opt[0][i] = INFINITY;
@@ -404,10 +404,8 @@
         s->last_frame = 1;
     }
 
-    if ((ret = ff_alloc_packet(avpkt, NELLY_BLOCK_LEN))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, NELLY_BLOCK_LEN)))
         return ret;
-    }
     encode_block(s, avpkt->data, avpkt->size);
 
     /* Get the next frame pts/duration */
diff --git a/libavcodec/noise_bsf.c b/libavcodec/noise_bsf.c
index 3e552e2..1cab3e1 100644
--- a/libavcodec/noise_bsf.c
+++ b/libavcodec/noise_bsf.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c
index 4beed8f..09868e8 100644
--- a/libavcodec/nuv.c
+++ b/libavcodec/nuv.c
@@ -2,25 +2,26 @@
  * NuppelVideo decoder
  * Copyright (c) 2006 Reimar Doeffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <limits.h>
 
 #include "libavutil/bswap.h"
 #include "libavutil/common.h"
@@ -118,24 +119,28 @@
     if (quality >= 0)
         get_quant_quality(c, quality);
     if (width != c->width || height != c->height) {
-        if (av_image_check_size(height, width, 0, avctx) < 0)
-            return 0;
+        // 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)
+            return -1;
         avctx->width  = c->width  = width;
         avctx->height = c->height = height;
         av_fast_malloc(&c->decomp_buf, &c->decomp_size,
-                       c->height * c->width * 3 / 2);
+                       buf_size);
         if (!c->decomp_buf) {
             av_log(avctx, AV_LOG_ERROR,
                    "Can't allocate decompression buffer.\n");
-            return 0;
+            return AVERROR(ENOMEM);
         }
         ff_rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height,
                               c->lq, c->cq);
+        return 1;
     } else if (quality != c->quality)
         ff_rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height,
                               c->lq, c->cq);
 
-    return 1;
+    return 0;
 }
 
 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
@@ -147,6 +152,7 @@
     AVFrame *picture   = data;
     int orig_size      = buf_size;
     int keyframe;
+    int size_change = 0;
     int result;
     enum {
         NUV_UNCOMPRESSED  = '0',
@@ -176,7 +182,7 @@
         return orig_size;
     }
 
-    if (buf[0] != 'V' || buf_size < 12) {
+    if (buf_size < 12 || buf[0] != 'V') {
         av_log(avctx, AV_LOG_ERROR, "not a nuv video frame\n");
         return -1;
     }
@@ -193,33 +199,48 @@
         keyframe = 1;
         break;
     }
+retry:
     // skip rest of the frameheader.
     buf       = &buf[12];
     buf_size -= 12;
     if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) {
-        int outlen = c->decomp_size, inlen = buf_size;
+        int outlen = c->decomp_size - AV_LZO_OUTPUT_PADDING, inlen = buf_size;
         if (av_lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen))
             av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n");
         buf      = c->decomp_buf;
-        buf_size = c->decomp_size;
+        buf_size = c->decomp_size - AV_LZO_OUTPUT_PADDING - outlen;
     }
     if (c->codec_frameheader) {
         int w, h, q;
-        if (buf_size < RTJPEG_HEADER_SIZE || buf[4] != RTJPEG_HEADER_SIZE ||
-            buf[5] != RTJPEG_FILE_VERSION) {
-            av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n");
+        int res;
+        if (buf_size < RTJPEG_HEADER_SIZE) {
+            av_log(avctx, AV_LOG_ERROR, "Too small NUV video frame\n");
+            return AVERROR_INVALIDDATA;
+        }
+        // There seem to exist two variants of this header: one starts with 'V'
+        // and 5 bytes unknown, the other matches current MythTV and is 4 bytes size,
+        // 1 byte header size (== 12), 1 byte version (== 0)
+        if (buf[0] != 'V' && AV_RL16(&buf[4]) != 0x000c) {
+            av_log(avctx, AV_LOG_ERROR, "Unknown secondary frame header (wrong codec_tag?)\n");
             return AVERROR_INVALIDDATA;
         }
         w = AV_RL16(&buf[6]);
         h = AV_RL16(&buf[8]);
         q = buf[10];
-        if (!codec_reinit(avctx, w, h, q))
-            return -1;
-        buf       = &buf[RTJPEG_HEADER_SIZE];
+        res = codec_reinit(avctx, w, h, q);
+        if (res < 0)
+            return res;
+        if (res) {
+            buf = avpkt->data;
+            buf_size = avpkt->size;
+            size_change = 1;
+            goto retry;
+        }
+        buf = &buf[RTJPEG_HEADER_SIZE];
         buf_size -= RTJPEG_HEADER_SIZE;
     }
 
-    if (keyframe && c->pic.data[0])
+    if ((size_change || keyframe) && c->pic.data[0])
         avctx->release_buffer(avctx, &c->pic);
     c->pic.reference    = 3;
     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID    | FF_BUFFER_HINTS_READABLE |
@@ -283,7 +304,7 @@
 
     ff_dsputil_init(&c->dsp, avctx);
 
-    if (!codec_reinit(avctx, avctx->width, avctx->height, -1))
+    if (codec_reinit(avctx, avctx->width, avctx->height, -1) < 0)
         return 1;
 
     return 0;
diff --git a/libavcodec/old_codec_ids.h b/libavcodec/old_codec_ids.h
index 2b72e38..ded4cc7 100644
--- a/libavcodec/old_codec_ids.h
+++ b/libavcodec/old_codec_ids.h
@@ -1,24 +1,26 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #ifndef AVCODEC_OLD_CODEC_IDS_H
 #define AVCODEC_OLD_CODEC_IDS_H
 
+#include "libavutil/common.h"
+
 /*
  * This header exists to prevent new codec IDs from being accidentally added to
  * the deprecated list.
@@ -198,6 +200,19 @@
     CODEC_ID_TSCC2,
     CODEC_ID_MTS2,
     CODEC_ID_CLLC,
+    CODEC_ID_Y41P       = MKBETAG('Y','4','1','P'),
+    CODEC_ID_ESCAPE130  = MKBETAG('E','1','3','0'),
+    CODEC_ID_EXR        = MKBETAG('0','E','X','R'),
+    CODEC_ID_AVRP       = MKBETAG('A','V','R','P'),
+
+    CODEC_ID_G2M        = MKBETAG( 0 ,'G','2','M'),
+    CODEC_ID_AVUI       = MKBETAG('A','V','U','I'),
+    CODEC_ID_AYUV       = MKBETAG('A','Y','U','V'),
+    CODEC_ID_V308       = MKBETAG('V','3','0','8'),
+    CODEC_ID_V408       = MKBETAG('V','4','0','8'),
+    CODEC_ID_YUV4       = MKBETAG('Y','U','V','4'),
+    CODEC_ID_SANM       = MKBETAG('S','A','N','M'),
+    CODEC_ID_PAF_VIDEO  = MKBETAG('P','A','F','V'),
 
     /* various PCM "codecs" */
     CODEC_ID_FIRST_AUDIO = 0x10000,     ///< A dummy id pointing at the start of audio codecs
@@ -261,6 +276,7 @@
     CODEC_ID_ADPCM_IMA_ISS,
     CODEC_ID_ADPCM_G722,
     CODEC_ID_ADPCM_IMA_APC,
+    CODEC_ID_VIMA       = MKBETAG('V','I','M','A'),
 
     /* AMR */
     CODEC_ID_AMR_NB = 0x12000,
@@ -338,6 +354,12 @@
     CODEC_ID_RALF,
     CODEC_ID_IAC,
     CODEC_ID_ILBC,
+    CODEC_ID_FFWAVESYNTH = MKBETAG('F','F','W','S'),
+    CODEC_ID_8SVX_RAW    = MKBETAG('8','S','V','X'),
+    CODEC_ID_SONIC       = MKBETAG('S','O','N','C'),
+    CODEC_ID_SONIC_LS    = MKBETAG('S','O','N','L'),
+    CODEC_ID_PAF_AUDIO   = MKBETAG('P','A','F','A'),
+    CODEC_ID_OPUS        = MKBETAG('O','P','U','S'),
 
     /* subtitle codecs */
     CODEC_ID_FIRST_SUBTITLE = 0x17000,          ///< A dummy ID pointing at the start of subtitle codecs.
@@ -350,10 +372,20 @@
     CODEC_ID_HDMV_PGS_SUBTITLE,
     CODEC_ID_DVB_TELETEXT,
     CODEC_ID_SRT,
+    CODEC_ID_MICRODVD   = MKBETAG('m','D','V','D'),
+    CODEC_ID_EIA_608    = MKBETAG('c','6','0','8'),
+    CODEC_ID_JACOSUB    = MKBETAG('J','S','U','B'),
+    CODEC_ID_SAMI       = MKBETAG('S','A','M','I'),
+    CODEC_ID_REALTEXT   = MKBETAG('R','T','X','T'),
+    CODEC_ID_SUBVIEWER  = MKBETAG('S','u','b','V'),
 
     /* other specific kind of codecs (generally used for attachments) */
     CODEC_ID_FIRST_UNKNOWN = 0x18000,           ///< A dummy ID pointing at the start of various fake codecs.
     CODEC_ID_TTF = 0x18000,
+    CODEC_ID_BINTEXT    = MKBETAG('B','T','X','T'),
+    CODEC_ID_XBIN       = MKBETAG('X','B','I','N'),
+    CODEC_ID_IDF        = MKBETAG( 0 ,'I','D','F'),
+    CODEC_ID_OTF        = MKBETAG( 0 ,'O','T','F'),
 
     CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it
 
diff --git a/libavcodec/options.c b/libavcodec/options.c
index fc2a184..20e9495 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -67,6 +67,13 @@
     return NULL;
 }
 
+static AVClassCategory get_category(void *ptr)
+{
+    AVCodecContext* avctx = ptr;
+    if(avctx->codec && avctx->codec->decode) return AV_CLASS_CATEGORY_DECODER;
+    else                                     return AV_CLASS_CATEGORY_ENCODER;
+}
+
 static const AVClass av_codec_context_class = {
     .class_name              = "AVCodecContext",
     .item_name               = context_to_name,
@@ -75,17 +82,33 @@
     .log_level_offset_offset = offsetof(AVCodecContext, log_level_offset),
     .child_next              = codec_child_next,
     .child_class_next        = codec_child_class_next,
+    .category                = AV_CLASS_CATEGORY_ENCODER,
+    .get_category            = get_category,
 };
 
+#if FF_API_ALLOC_CONTEXT
+void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType codec_type){
+    AVCodec c= {0};
+    c.type= codec_type;
+    avcodec_get_context_defaults3(s, &c);
+}
+#endif
+
 int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec)
 {
+    int flags=0;
     memset(s, 0, sizeof(AVCodecContext));
 
     s->av_class = &av_codec_context_class;
 
     s->codec_type = codec ? codec->type : AVMEDIA_TYPE_UNKNOWN;
-    s->codec      = codec;
-    av_opt_set_defaults(s);
+    if(s->codec_type == AVMEDIA_TYPE_AUDIO)
+        flags= AV_OPT_FLAG_AUDIO_PARAM;
+    else if(s->codec_type == AVMEDIA_TYPE_VIDEO)
+        flags= AV_OPT_FLAG_VIDEO_PARAM;
+    else if(s->codec_type == AVMEDIA_TYPE_SUBTITLE)
+        flags= AV_OPT_FLAG_SUBTITLE_PARAM;
+    av_opt_set_defaults2(s, flags, flags);
 
     s->time_base           = (AVRational){0,1};
     s->get_buffer          = avcodec_default_get_buffer;
@@ -96,6 +119,7 @@
     s->sample_aspect_ratio = (AVRational){0,1};
     s->pix_fmt             = AV_PIX_FMT_NONE;
     s->sample_fmt          = AV_SAMPLE_FMT_NONE;
+    s->timecode_frame_start = -1;
 
     s->reget_buffer        = avcodec_default_reget_buffer;
     s->reordered_opaque    = AV_NOPTS_VALUE;
@@ -137,6 +161,26 @@
     return avctx;
 }
 
+#if FF_API_ALLOC_CONTEXT
+AVCodecContext *avcodec_alloc_context2(enum AVMediaType codec_type){
+    AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext));
+
+    if(avctx==NULL) return NULL;
+
+    avcodec_get_context_defaults2(avctx, codec_type);
+
+    return avctx;
+}
+
+void avcodec_get_context_defaults(AVCodecContext *s){
+    avcodec_get_context_defaults2(s, AVMEDIA_TYPE_UNKNOWN);
+}
+
+AVCodecContext *avcodec_alloc_context(void){
+    return avcodec_alloc_context2(AVMEDIA_TYPE_UNKNOWN);
+}
+#endif
+
 int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src)
 {
     if (avcodec_is_open(dest)) { // check that the dest context is uninitialized
@@ -198,3 +242,53 @@
 {
     return &av_codec_context_class;
 }
+
+#define FOFFSET(x) offsetof(AVFrame,x)
+
+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},
+{"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},
+{"format", "", FOFFSET(format), AV_OPT_TYPE_INT, {.i64 = -1 }, 0, INT_MAX, 0},
+{"channel_layout", "", FOFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, 0},
+{"sample_rate", "", FOFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{NULL},
+};
+
+static const AVClass av_frame_class = {
+    .class_name              = "AVFrame",
+    .item_name               = NULL,
+    .option                  = frame_options,
+    .version                 = LIBAVUTIL_VERSION_INT,
+};
+
+const AVClass *avcodec_get_frame_class(void)
+{
+    return &av_frame_class;
+}
+
+#define SROFFSET(x) offsetof(AVSubtitleRect,x)
+
+static const AVOption subtitle_rect_options[]={
+{"x", "", SROFFSET(x), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"y", "", SROFFSET(y), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"w", "", SROFFSET(w), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"h", "", SROFFSET(h), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"type", "", SROFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"forced", "", SROFFSET(forced), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, 0},
+{NULL},
+};
+
+static const AVClass av_subtitle_rect_class = {
+    .class_name             = "AVSubtitleRect",
+    .item_name              = NULL,
+    .option                 = subtitle_rect_options,
+    .version                = LIBAVUTIL_VERSION_INT,
+};
+
+const AVClass *avcodec_get_subtitle_rect_class(void)
+{
+    return &av_subtitle_rect_class;
+}
diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h
index 9e9de46..e4397d0 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -1,19 +1,21 @@
 /*
+ * Copyright (c) 2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -39,12 +41,13 @@
 #define AV_CODEC_DEFAULT_BITRATE 200*1000
 
 static const AVOption options[]={
-{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE }, INT_MIN, INT_MAX, V|A|E},
+{"b", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT, {.i64 = AV_CODEC_DEFAULT_BITRATE }, INT_MIN, INT_MAX, A|V|E},
+{"ab", "set bitrate (in bits/s)", OFFSET(bit_rate), AV_OPT_TYPE_INT, {.i64 = 128*1000 }, INT_MIN, 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.",
        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|E|D, "flags"},
+{"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"},
 {"loop", "use loop filter", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG_LOOP_FILTER }, INT_MIN, INT_MAX, V|E, "flags"},
@@ -76,6 +79,8 @@
 #endif
 {"noout", "skip bitstream encoding", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_NO_OUTPUT }, INT_MIN, INT_MAX, V|E, "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"},
 #if FF_API_SUB_ID
 {"sub_id", NULL, OFFSET(sub_id), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
 #endif
@@ -106,7 +111,7 @@
           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, 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},
 {"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},
@@ -152,10 +157,13 @@
 {"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, V|D, "err_detect"},
-{"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, V|D, "err_detect"},
-{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, V|D, "err_detect"},
-{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, 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"},
+{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
+{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
+{"careful",    "consider things that violate the spec and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
+{"compliant",  "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
+{"aggressive", "consider things that a sane encoder should not do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, A|V|D, "err_detect"},
 {"has_b_frames", NULL, OFFSET(has_b_frames), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
 {"block_align", NULL, OFFSET(block_align), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
 {"mpeg_quant", "use MPEG quantizers instead of H.263", OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
@@ -194,6 +202,7 @@
 {"int", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, "idct"},
 {"simple", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, "idct"},
 {"simplemmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
+{"libmpeg2mmx", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_LIBMPEG2MMX }, INT_MIN, INT_MAX, V|E|D, "idct"},
 {"mmi", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_MMI }, INT_MIN, INT_MAX, V|E|D, "idct"},
 {"arm", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, "idct"},
 {"altivec", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, "idct"},
@@ -327,6 +336,7 @@
 {"dts_hd_ma", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_DTS_HD_MA }, INT_MIN, INT_MAX, A|E, "profile"},
 {"level", NULL, OFFSET(level), AV_OPT_TYPE_INT, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"},
 {"unknown", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LEVEL_UNKNOWN }, INT_MIN, INT_MAX, V|A|E, "level"},
+{"lowres", "decode at 1= 1/2, 2=1/4, 3=1/8 resolutions", OFFSET(lowres), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, V|A|D},
 {"skip_threshold", "frame skip threshold", OFFSET(frame_skip_threshold), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|E},
 {"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},
@@ -346,7 +356,7 @@
 {"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},
-{"keyint_min", "minimum interval between IDR-frames (x264)", OFFSET(keyint_min), AV_OPT_TYPE_INT, {.i64 = 25 }, INT_MIN, INT_MAX, 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},
 {"trellis", "rate-distortion optimal quantization", OFFSET(trellis), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, V|A|E},
@@ -366,7 +376,7 @@
 {"bits_per_raw_sample", NULL, OFFSET(bits_per_raw_sample), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX},
 {"channel_layout", NULL, OFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT64_MAX, A|E|D, "channel_layout"},
 {"request_channel_layout", NULL, OFFSET(request_channel_layout), AV_OPT_TYPE_INT64, {.i64 = DEFAULT }, 0, INT64_MAX, A|D, "request_channel_layout"},
-{"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), AV_OPT_TYPE_FLOAT, {.dbl = 1.0/3 }, 0.0, FLT_MAX, V|E},
+{"rc_max_vbv_use", NULL, OFFSET(rc_max_available_vbv_use), AV_OPT_TYPE_FLOAT, {.dbl = 0 }, 0.0, FLT_MAX, V|E},
 {"rc_min_vbv_use", NULL, OFFSET(rc_min_vbv_overflow_use),  AV_OPT_TYPE_FLOAT, {.dbl = 3 },     0.0, FLT_MAX, V|E},
 {"ticks_per_frame", NULL, OFFSET(ticks_per_frame), AV_OPT_TYPE_INT, {.i64 = 1 }, 1, INT_MAX, A|V|E|D},
 {"color_primaries", NULL, OFFSET(color_primaries), AV_OPT_TYPE_INT, {.i64 = AVCOL_PRI_UNSPECIFIED }, 1, AVCOL_PRI_NB-1, V|E|D},
@@ -389,7 +399,7 @@
 {"em", "Emergency",          0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_EMERGENCY },         INT_MIN, INT_MAX, A|E, "audio_service_type"},
 {"vo", "Voice Over",         0, AV_OPT_TYPE_CONST, {.i64 = AV_AUDIO_SERVICE_TYPE_VOICE_OVER },        INT_MIN, INT_MAX, A|E, "audio_service_type"},
 {"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", NULL, OFFSET(request_sample_fmt), AV_OPT_TYPE_INT, {.i64 = AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NB-1, A|D, "request_sample_fmt"},
+{"request_sample_fmt", "sample format audio decoders should prefer", OFFSET(request_sample_fmt), AV_OPT_TYPE_INT, {.i64 = AV_SAMPLE_FMT_NONE }, AV_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NB-1, A|D, "request_sample_fmt"},
 {"u8" , "8-bit unsigned integer", 0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_U8  }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
 {"s16", "16-bit signed integer",  0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S16 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
 {"s32", "32-bit signed integer",  0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S32 }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
@@ -400,6 +410,7 @@
 {"s32p", "32-bit signed integer planar",  0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_S32P }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
 {"fltp", "32-bit float planar",           0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_FLTP }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
 {"dblp", "64-bit double planar",          0, AV_OPT_TYPE_CONST, {.i64 = AV_SAMPLE_FMT_DBLP }, INT_MIN, INT_MAX, A|D, "request_sample_fmt"},
+{"pkt_timebase", NULL, OFFSET(pkt_timebase), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0},
 {NULL},
 };
 
diff --git a/libavcodec/os2threads.h b/libavcodec/os2threads.h
new file mode 100644
index 0000000..b816bff
--- /dev/null
+++ b/libavcodec/os2threads.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2011 KO Myung-Hun <komh@chollian.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
+ * os2threads to pthreads wrapper
+ */
+
+#ifndef AVCODEC_OS2PTHREADS_H
+#define AVCODEC_OS2PTHREADS_H
+
+#define INCL_DOS
+#include <os2.h>
+
+#undef __STRICT_ANSI__          /* for _beginthread() */
+#include <stdlib.h>
+
+typedef TID  pthread_t;
+typedef void pthread_attr_t;
+
+typedef HMTX pthread_mutex_t;
+typedef void pthread_mutexattr_t;
+
+typedef struct {
+    HEV  event_sem;
+    int  wait_count;
+} pthread_cond_t;
+
+typedef void pthread_condattr_t;
+
+struct thread_arg {
+    void *(*start_routine)(void *);
+    void *arg;
+};
+
+static void thread_entry(void *arg)
+{
+    struct thread_arg *thread_arg = arg;
+
+    thread_arg->start_routine(thread_arg->arg);
+
+    av_free(thread_arg);
+}
+
+static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg)
+{
+    struct thread_arg *thread_arg;
+
+    thread_arg = av_mallocz(sizeof(struct thread_arg));
+
+    thread_arg->start_routine = start_routine;
+    thread_arg->arg = arg;
+
+    *thread = _beginthread(thread_entry, NULL, 256 * 1024, thread_arg);
+
+    return 0;
+}
+
+static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
+{
+    DosWaitThread((PTID)&thread, DCWW_WAIT);
+
+    return 0;
+}
+
+static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
+{
+    DosCreateMutexSem(NULL, (PHMTX)mutex, 0, FALSE);
+
+    return 0;
+}
+
+static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+    DosCloseMutexSem(*(PHMTX)mutex);
+
+    return 0;
+}
+
+static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
+{
+    DosRequestMutexSem(*(PHMTX)mutex, SEM_INDEFINITE_WAIT);
+
+    return 0;
+}
+
+static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
+{
+    DosReleaseMutexSem(*(PHMTX)mutex);
+
+    return 0;
+}
+
+static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
+{
+    DosCreateEventSem(NULL, &cond->event_sem, DCE_POSTONE, FALSE);
+
+    cond->wait_count = 0;
+
+    return 0;
+}
+
+static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
+{
+    DosCloseEventSem(cond->event_sem);
+
+    return 0;
+}
+
+static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
+{
+    if (cond->wait_count > 0) {
+        DosPostEventSem(cond->event_sem);
+
+        cond->wait_count--;
+    }
+
+    return 0;
+}
+
+static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond)
+{
+    while (cond->wait_count > 0) {
+        DosPostEventSem(cond->event_sem);
+
+        cond->wait_count--;
+    }
+
+    return 0;
+}
+
+static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+    cond->wait_count++;
+
+    pthread_mutex_unlock(mutex);
+
+    DosWaitEventSem(cond->event_sem, SEM_INDEFINITE_WAIT);
+
+    pthread_mutex_lock(mutex);
+
+    return 0;
+}
+
+#endif /* AVCODEC_OS2PTHREADS_H */
diff --git a/libavcodec/paf.c b/libavcodec/paf.c
new file mode 100644
index 0000000..877b170
--- /dev/null
+++ b/libavcodec/paf.c
@@ -0,0 +1,455 @@
+/*
+ * Packed Animation File video and audio decoder
+ * 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 "libavcodec/dsputil.h"
+#include "libavcodec/paf.h"
+#include "bytestream.h"
+#include "avcodec.h"
+
+static const uint8_t block_sequences[16][8] =
+{
+    { 0, 0, 0, 0, 0, 0, 0, 0 },
+    { 2, 0, 0, 0, 0, 0, 0, 0 },
+    { 5, 7, 0, 0, 0, 0, 0, 0 },
+    { 5, 0, 0, 0, 0, 0, 0, 0 },
+    { 6, 0, 0, 0, 0, 0, 0, 0 },
+    { 5, 7, 5, 7, 0, 0, 0, 0 },
+    { 5, 7, 5, 0, 0, 0, 0, 0 },
+    { 5, 7, 6, 0, 0, 0, 0, 0 },
+    { 5, 5, 0, 0, 0, 0, 0, 0 },
+    { 3, 0, 0, 0, 0, 0, 0, 0 },
+    { 6, 6, 0, 0, 0, 0, 0, 0 },
+    { 2, 4, 0, 0, 0, 0, 0, 0 },
+    { 2, 4, 5, 7, 0, 0, 0, 0 },
+    { 2, 4, 5, 0, 0, 0, 0, 0 },
+    { 2, 4, 6, 0, 0, 0, 0, 0 },
+    { 2, 4, 5, 7, 5, 7, 0, 0 }
+};
+
+typedef struct PAFVideoDecContext {
+    AVFrame  pic;
+    GetByteContext gb;
+
+    int     current_frame;
+    uint8_t *frame[4];
+    int     frame_size;
+    int     video_size;
+
+    uint8_t *opcodes;
+} PAFVideoDecContext;
+
+static av_cold int paf_vid_init(AVCodecContext *avctx)
+{
+    PAFVideoDecContext *c = avctx->priv_data;
+    int i;
+
+    if (avctx->height & 3 || avctx->width & 3) {
+        av_log(avctx, AV_LOG_ERROR, "width and height must be multiplies of 4\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    avctx->pix_fmt = AV_PIX_FMT_PAL8;
+
+    avcodec_get_frame_defaults(&c->pic);
+    c->frame_size = FFALIGN(avctx->height, 256) * avctx->width;
+    c->video_size = avctx->height * avctx->width;
+    for (i = 0; i < 4; i++) {
+        c->frame[i] = av_mallocz(c->frame_size);
+        if (!c->frame[i])
+            return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int get_video_page_offset(AVCodecContext *avctx, uint8_t a, uint8_t b)
+{
+    int x, y;
+
+    x = b & 0x7F;
+    y = ((a & 0x3F) << 1) | (b >> 7 & 1);
+
+    return y * 2 * avctx->width + x * 2;
+}
+
+static void copy4h(AVCodecContext *avctx, uint8_t *dst)
+{
+    PAFVideoDecContext *c = avctx->priv_data;
+    int i;
+
+    for (i = 0; i < 4; i++) {
+        bytestream2_get_buffer(&c->gb, dst, 4);
+        dst += avctx->width;
+    }
+}
+
+static void copy_color_mask(AVCodecContext *avctx, uint8_t mask, uint8_t *dst, uint8_t color)
+{
+    int i;
+
+    for (i = 0; i < 4; i++) {
+        if ((mask >> 4) & (1 << (3 - i)))
+            dst[i] = color;
+        if ((mask & 15) & (1 << (3 - i)))
+            dst[avctx->width + i] = color;
+    }
+}
+
+static void copy_src_mask(AVCodecContext *avctx, uint8_t mask, uint8_t *dst, const uint8_t *src)
+{
+    int i;
+
+    for (i = 0; i < 4; i++) {
+        if ((mask >> 4) & (1 << (3 - i)))
+            dst[i] = src[i];
+        if ((mask & 15) & (1 << (3 - i)))
+            dst[avctx->width + i] = src[avctx->width + i];
+    }
+}
+
+static int decode_0(AVCodecContext *avctx, uint8_t code, uint8_t *pkt)
+{
+    PAFVideoDecContext *c = avctx->priv_data;
+    uint32_t opcode_size, offset;
+    uint8_t *dst, *dend, mask = 0, color = 0, a, b, p;
+    const uint8_t *src, *send, *opcodes;
+    int  i, j, x = 0;
+
+    i = bytestream2_get_byte(&c->gb);
+    if (i) {
+        if (code & 0x10) {
+            int align;
+
+            align = bytestream2_tell(&c->gb) & 3;
+            if (align)
+                bytestream2_skip(&c->gb, 4 - align);
+        }
+        do {
+            a      = bytestream2_get_byte(&c->gb);
+            b      = bytestream2_get_byte(&c->gb);
+            p      = (a & 0xC0) >> 6;
+            dst    = c->frame[p] + get_video_page_offset(avctx, a, b);
+            dend   = c->frame[p] + c->frame_size;
+            offset = (b & 0x7F) * 2;
+            j      = bytestream2_get_le16(&c->gb) + offset;
+
+            do {
+                offset++;
+                if (dst + 3 * avctx->width + 4 > dend)
+                    return AVERROR_INVALIDDATA;
+                copy4h(avctx, dst);
+                if ((offset & 0x3F) == 0)
+                    dst += avctx->width * 3;
+                dst += 4;
+            } while (offset < j);
+        } while (--i);
+    }
+
+    dst  = c->frame[c->current_frame];
+    dend = c->frame[c->current_frame] + c->frame_size;
+    do {
+        a    = bytestream2_get_byte(&c->gb);
+        b    = bytestream2_get_byte(&c->gb);
+        p    = (a & 0xC0) >> 6;
+        src  = c->frame[p] + get_video_page_offset(avctx, a, b);
+        send = c->frame[p] + c->frame_size;
+        if ((src + 3 * avctx->width + 4 > send) ||
+            (dst + 3 * avctx->width + 4 > dend))
+            return AVERROR_INVALIDDATA;
+        copy_block4(dst, src, avctx->width, avctx->width, 4);
+        i++;
+        if ((i & 0x3F) == 0)
+            dst += avctx->width * 3;
+        dst += 4;
+    } while (i < c->video_size / 16);
+
+    opcode_size = bytestream2_get_le16(&c->gb);
+    bytestream2_skip(&c->gb, 2);
+
+    if (bytestream2_get_bytes_left(&c->gb) < opcode_size)
+        return AVERROR_INVALIDDATA;
+
+    opcodes = pkt + bytestream2_tell(&c->gb);
+    bytestream2_skipu(&c->gb, opcode_size);
+
+    dst = c->frame[c->current_frame];
+
+    for (i = 0; i < avctx->height; i += 4, dst += avctx->width * 3) {
+        for (j = 0; j < avctx->width; j += 4, dst += 4) {
+            int opcode, k = 0;
+
+            if (x > opcode_size)
+                return AVERROR_INVALIDDATA;
+            if (j & 4) {
+                opcode = opcodes[x] & 15;
+                x++;
+            } else {
+                opcode = opcodes[x] >> 4;
+            }
+
+            while (block_sequences[opcode][k]) {
+
+                offset = avctx->width * 2;
+                code   = block_sequences[opcode][k++];
+
+                switch (code) {
+                case 2:
+                    offset = 0;
+                case 3:
+                    color  = bytestream2_get_byte(&c->gb);
+                case 4:
+                    mask   = bytestream2_get_byte(&c->gb);
+                    copy_color_mask(avctx, mask, dst + offset, color);
+                    break;
+                case 5:
+                    offset = 0;
+                case 6:
+                    a    = bytestream2_get_byte(&c->gb);
+                    b    = bytestream2_get_byte(&c->gb);
+                    p    = (a & 0xC0) >> 6;
+                    src  = c->frame[p] + get_video_page_offset(avctx, a, b);
+                    send = c->frame[p] + c->frame_size;
+                case 7:
+                    if (src + offset + avctx->width + 4 > send)
+                        return AVERROR_INVALIDDATA;
+                    mask = bytestream2_get_byte(&c->gb);
+                    copy_src_mask(avctx, mask, dst + offset, src + offset);
+                    break;
+                }
+            }
+        }
+    }
+
+    return 0;
+}
+
+static int paf_vid_decode(AVCodecContext *avctx, void *data,
+                          int *data_size, AVPacket *pkt)
+{
+    PAFVideoDecContext *c = avctx->priv_data;
+    uint8_t code, *dst, *src, *end;
+    int i, frame, ret;
+
+    c->pic.reference = 3;
+    if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0)
+        return ret;
+
+    bytestream2_init(&c->gb, pkt->data, pkt->size);
+
+    code = bytestream2_get_byte(&c->gb);
+    if (code & 0x20) {
+        for (i = 0; i < 4; i++)
+            memset(c->frame[i], 0, c->frame_size);
+
+        memset(c->pic.data[1], 0, AVPALETTE_SIZE);
+        c->current_frame = 0;
+        c->pic.key_frame = 1;
+        c->pic.pict_type = AV_PICTURE_TYPE_I;
+    } else {
+        c->pic.key_frame = 0;
+        c->pic.pict_type = AV_PICTURE_TYPE_P;
+    }
+
+    if (code & 0x40) {
+        uint32_t *out = (uint32_t *)c->pic.data[1];
+        int index, count;
+
+        index = bytestream2_get_byte(&c->gb);
+        count = bytestream2_get_byte(&c->gb) + 1;
+
+        if (index + count > 256)
+            return AVERROR_INVALIDDATA;
+        if (bytestream2_get_bytes_left(&c->gb) < 3*count)
+            return AVERROR_INVALIDDATA;
+
+        out += index;
+        for (i = 0; i < count; i++) {
+            unsigned r, g, b;
+
+            r = bytestream2_get_byteu(&c->gb);
+            r = r << 2 | r >> 4;
+            g = bytestream2_get_byteu(&c->gb);
+            g = g << 2 | g >> 4;
+            b = bytestream2_get_byteu(&c->gb);
+            b = b << 2 | b >> 4;
+            *out++ = 0xFFU << 24 | r << 16 | g << 8 | b;
+        }
+        c->pic.palette_has_changed = 1;
+    }
+
+    switch (code & 0x0F) {
+    case 0:
+        if ((ret = decode_0(avctx, code, pkt->data)) < 0)
+            return ret;
+        break;
+    case 1:
+        dst = c->frame[c->current_frame];
+        bytestream2_skip(&c->gb, 2);
+        if (bytestream2_get_bytes_left(&c->gb) < c->video_size)
+            return AVERROR_INVALIDDATA;
+        bytestream2_get_bufferu(&c->gb, dst, c->video_size);
+        break;
+    case 2:
+        frame = bytestream2_get_byte(&c->gb);
+        if (frame > 3)
+            return AVERROR_INVALIDDATA;
+        if (frame != c->current_frame)
+            memcpy(c->frame[c->current_frame], c->frame[frame], c->frame_size);
+        break;
+    case 4:
+        dst = c->frame[c->current_frame];
+        end = dst + c->video_size;
+
+        bytestream2_skip(&c->gb, 2);
+
+        while (dst < end) {
+            int8_t code;
+            int count;
+
+            if (bytestream2_get_bytes_left(&c->gb) < 2)
+                return AVERROR_INVALIDDATA;
+
+            code  = bytestream2_get_byteu(&c->gb);
+            count = FFABS(code) + 1;
+
+            if (dst + count > end)
+                return AVERROR_INVALIDDATA;
+            if (code < 0)
+                memset(dst, bytestream2_get_byteu(&c->gb), count);
+            else
+                bytestream2_get_buffer(&c->gb, dst, count);
+            dst += count;
+        }
+        break;
+    default:
+        av_log_ask_for_sample(avctx, "unknown/invalid code\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    dst = c->pic.data[0];
+    src = c->frame[c->current_frame];
+    for (i = 0; i < avctx->height; i++) {
+        memcpy(dst, src, avctx->width);
+        dst += c->pic.linesize[0];
+        src += avctx->width;
+    }
+
+    c->current_frame = (c->current_frame + 1) & 3;
+
+    *data_size       = sizeof(AVFrame);
+    *(AVFrame *)data = c->pic;
+
+    return pkt->size;
+}
+
+static av_cold int paf_vid_close(AVCodecContext *avctx)
+{
+    PAFVideoDecContext *c = avctx->priv_data;
+    int i;
+
+    if (c->pic.data[0])
+        avctx->release_buffer(avctx, &c->pic);
+
+    for (i = 0; i < 4; i++)
+        av_freep(&c->frame[i]);
+
+    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;
+}
+
+static int paf_aud_decode(AVCodecContext *avctx, void *data,
+                          int *got_frame_ptr, AVPacket *pkt)
+{
+    PAFAudioDecContext *c = avctx->priv_data;
+    uint8_t *buf = pkt->data;
+    int16_t *output_samples;
+    const uint8_t *t;
+    int frames, ret, i, j, k;
+
+    frames = pkt->size / PAF_SOUND_FRAME_SIZE;
+    if (frames < 1)
+        return AVERROR_INVALIDDATA;
+
+    c->frame.nb_samples = PAF_SOUND_SAMPLES * frames;
+    if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0)
+        return ret;
+
+    output_samples = (int16_t *)c->frame.data[0];
+    for (i = 0; i < frames; i++) {
+        t = buf + 256 * sizeof(uint16_t);
+        for (j = 0; j < PAF_SOUND_SAMPLES; j++) {
+            for (k = 0; k < 2; k++) {
+                *output_samples++ = AV_RL16(buf + *t * 2);
+                t++;
+            }
+        }
+        buf += PAF_SOUND_FRAME_SIZE;
+    }
+
+    *got_frame_ptr   = 1;
+    *(AVFrame *)data = c->frame;
+
+    return pkt->size;
+}
+
+AVCodec ff_paf_video_decoder = {
+    .name           = "paf_video",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_PAF_VIDEO,
+    .priv_data_size = sizeof(PAFVideoDecContext),
+    .init           = paf_vid_init,
+    .close          = paf_vid_close,
+    .decode         = paf_vid_decode,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File Video"),
+};
+
+AVCodec ff_paf_audio_decoder = {
+    .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,
+    .long_name      = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File Audio"),
+};
diff --git a/libavcodec/paf.h b/libavcodec/paf.h
new file mode 100644
index 0000000..ce8245f
--- /dev/null
+++ b/libavcodec/paf.h
@@ -0,0 +1,28 @@
+/*
+ * Packed Animation File decoder/demuxer 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
+ */
+
+#ifndef AVCODEC_PAF_H
+#define AVCODEC_PAF_H
+
+#define PAF_SOUND_SAMPLES     2205
+#define PAF_SOUND_FRAME_SIZE  ((256 + PAF_SOUND_SAMPLES) * 2)
+
+#endif /* AVCODEC_PAF_H */
diff --git a/libavcodec/pamenc.c b/libavcodec/pamenc.c
index dba4771..3e47278 100644
--- a/libavcodec/pamenc.c
+++ b/libavcodec/pamenc.c
@@ -2,25 +2,24 @@
  * PAM image format
  * Copyright (c) 2002, 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "avcodec.h"
-#include "bytestream.h"
 #include "internal.h"
 #include "pnm.h"
 
@@ -34,26 +33,11 @@
     const char *tuple_type;
     uint8_t *ptr;
 
-    if ((ret = ff_alloc_packet(pkt, avpicture_get_size(avctx->pix_fmt,
-                                                       avctx->width,
-                                                       avctx->height) + 200)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
-        return ret;
-    }
-
-    *p           = *pict;
-    p->pict_type = AV_PICTURE_TYPE_I;
-    p->key_frame = 1;
-
-    s->bytestream_start =
-    s->bytestream       = pkt->data;
-    s->bytestream_end   = pkt->data + pkt->size;
-
     h = avctx->height;
     w = avctx->width;
     switch (avctx->pix_fmt) {
-    case AV_PIX_FMT_MONOWHITE:
-        n          = (w + 7) >> 3;
+    case AV_PIX_FMT_MONOBLACK:
+        n          = w;
         depth      = 1;
         maxval     = 1;
         tuple_type = "BLACKANDWHITE";
@@ -64,21 +48,57 @@
         maxval     = 255;
         tuple_type = "GRAYSCALE";
         break;
+    case AV_PIX_FMT_GRAY16BE:
+        n          = w * 2;
+        depth      = 1;
+        maxval     = 0xFFFF;
+        tuple_type = "GRAYSCALE";
+        break;
+    case AV_PIX_FMT_GRAY8A:
+        n          = w * 2;
+        depth      = 2;
+        maxval     = 255;
+        tuple_type = "GRAYSCALE_ALPHA";
+        break;
     case AV_PIX_FMT_RGB24:
         n          = w * 3;
         depth      = 3;
         maxval     = 255;
         tuple_type = "RGB";
         break;
-    case AV_PIX_FMT_RGB32:
+    case AV_PIX_FMT_RGBA:
         n          = w * 4;
         depth      = 4;
         maxval     = 255;
         tuple_type = "RGB_ALPHA";
         break;
+    case AV_PIX_FMT_RGB48BE:
+        n          = w * 6;
+        depth      = 3;
+        maxval     = 0xFFFF;
+        tuple_type = "RGB";
+        break;
+    case AV_PIX_FMT_RGBA64BE:
+        n          = w * 8;
+        depth      = 4;
+        maxval     = 0xFFFF;
+        tuple_type = "RGB_ALPHA";
+        break;
     default:
         return -1;
     }
+
+    if ((ret = ff_alloc_packet2(avctx, pkt, n*h + 200)) < 0)
+        return ret;
+
+    *p           = *pict;
+    p->pict_type = AV_PICTURE_TYPE_I;
+    p->key_frame = 1;
+
+    s->bytestream_start =
+    s->bytestream       = pkt->data;
+    s->bytestream_end   = pkt->data + pkt->size;
+
     snprintf(s->bytestream, s->bytestream_end - s->bytestream,
              "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
              w, h, depth, maxval, tuple_type);
@@ -87,16 +107,11 @@
     ptr      = p->data[0];
     linesize = p->linesize[0];
 
-    if (avctx->pix_fmt == AV_PIX_FMT_RGB32) {
+    if (avctx->pix_fmt == AV_PIX_FMT_MONOBLACK){
         int j;
-        unsigned int v;
-
         for (i = 0; i < h; i++) {
-            for (j = 0; j < w; j++) {
-                v = ((uint32_t *)ptr)[j];
-                bytestream_put_be24(&s->bytestream, v);
-                *s->bytestream++ = v >> 24;
-            }
+            for (j = 0; j < w; j++)
+                *s->bytestream++ = ptr[j >> 3] >> (7 - j & 7) & 1;
             ptr += linesize;
         }
     } else {
@@ -122,8 +137,7 @@
     .init           = ff_pnm_init,
     .encode2        = pam_encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){
-        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB32, AV_PIX_FMT_GRAY8, AV_PIX_FMT_MONOWHITE,
-        AV_PIX_FMT_NONE
+        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48BE, AV_PIX_FMT_RGBA64BE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_NONE
     },
     .long_name      = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
 };
diff --git a/libavcodec/parser.c b/libavcodec/parser.c
index 03f327e..127ba8b 100644
--- a/libavcodec/parser.c
+++ b/libavcodec/parser.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -61,13 +61,13 @@
     if (!s)
         return NULL;
     s->parser = parser;
-    if (parser->priv_data_size) {
-        s->priv_data = av_mallocz(parser->priv_data_size);
-        if (!s->priv_data) {
-            av_free(s);
-            return NULL;
-        }
+    s->priv_data = av_mallocz(parser->priv_data_size);
+    if (!s->priv_data) {
+        av_free(s);
+        return NULL;
     }
+    s->fetch_timestamp=1;
+    s->pict_type = AV_PICTURE_TYPE_I;
     if (parser->parser_init) {
         ret = parser->parser_init(s);
         if (ret != 0) {
@@ -76,8 +76,6 @@
             return NULL;
         }
     }
-    s->fetch_timestamp=1;
-    s->pict_type = AV_PICTURE_TYPE_I;
     s->key_frame = -1;
     s->convergence_duration = 0;
     s->dts_sync_point       = INT_MIN;
@@ -96,7 +94,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 doesnt send complete PES packets
+            //check is disabled because mpeg-ts doesn't 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];
@@ -263,6 +261,7 @@
         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 );
         pc->index = 0;
         *buf= pc->buffer;
diff --git a/libavcodec/parser.h b/libavcodec/parser.h
index 1d029e3..69f1064 100644
--- a/libavcodec/parser.h
+++ b/libavcodec/parser.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/pcm-mpeg.c b/libavcodec/pcm-mpeg.c
index 4a38648..032bdae 100644
--- a/libavcodec/pcm-mpeg.c
+++ b/libavcodec/pcm-mpeg.c
@@ -2,20 +2,20 @@
  * LPCM codecs for PCM formats found in MPEG streams
  * Copyright (c) 2009 Christian Schmidt
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -69,13 +69,14 @@
 
     /* get the sample depth and derive the sample format from it */
     avctx->bits_per_coded_sample = bits_per_samples[header[3] >> 6];
-    if (!avctx->bits_per_coded_sample) {
-        av_log(avctx, AV_LOG_ERROR, "reserved sample depth (0)\n");
+    if (!(avctx->bits_per_coded_sample == 16 || avctx->bits_per_coded_sample == 24)) {
+        av_log(avctx, AV_LOG_ERROR, "unsupported sample depth (%d)\n", avctx->bits_per_coded_sample);
         return -1;
     }
     avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? AV_SAMPLE_FMT_S16 :
                                                              AV_SAMPLE_FMT_S32;
-    avctx->bits_per_raw_sample = avctx->bits_per_coded_sample;
+    if (avctx->sample_fmt == AV_SAMPLE_FMT_S32)
+        avctx->bits_per_raw_sample = avctx->bits_per_coded_sample;
 
     /* get the sample rate. Not all values are used. */
     switch (header[2] & 0x0f) {
diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c
index c6c6bc0..e2ae9f9 100644
--- a/libavcodec/pcm.c
+++ b/libavcodec/pcm.c
@@ -2,20 +2,20 @@
  * PCM codecs
  * Copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -98,10 +98,8 @@
     n           = frame->nb_samples * avctx->channels;
     samples     = (const short *)frame->data[0];
 
-    if ((ret = ff_alloc_packet(avpkt, n * sample_size))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, n * sample_size)))
         return ret;
-    }
     dst = avpkt->data;
 
     switch (avctx->codec->id) {
@@ -273,7 +271,9 @@
     if (AV_CODEC_ID_PCM_DVD == avctx->codec_id) {
         if (avctx->bits_per_coded_sample != 20 &&
             avctx->bits_per_coded_sample != 24) {
-            av_log(avctx, AV_LOG_ERROR, "PCM DVD unsupported sample depth\n");
+            av_log(avctx, AV_LOG_ERROR,
+                   "PCM DVD unsupported sample depth %i\n",
+                   avctx->bits_per_coded_sample);
             return AVERROR(EINVAL);
         }
         /* 2 samples are interleaved per block in PCM_DVD */
@@ -294,8 +294,10 @@
 
     if (n && buf_size % n) {
         if (buf_size < n) {
-            av_log(avctx, AV_LOG_ERROR, "invalid PCM packet\n");
-            return -1;
+            av_log(avctx, AV_LOG_ERROR,
+                   "Invalid PCM packet, data has size %d but at least a size of %d was expected\n",
+                   buf_size, n);
+            return AVERROR_INVALIDDATA;
         } else
             buf_size -= buf_size % n;
     }
@@ -340,15 +342,15 @@
         break;
     case AV_CODEC_ID_PCM_S16LE_PLANAR:
     {
-        const uint8_t *src2[MAX_CHANNELS];
+        int i;
         n /= avctx->channels;
-        for (c = 0; c < avctx->channels; c++)
-            src2[c] = &src[c * n * 2];
-        for (; n > 0; n--)
-            for (c = 0; c < avctx->channels; c++) {
-                AV_WN16A(samples, bytestream_get_le16(&src2[c]));
+        for (c = 0; c < avctx->channels; c++) {
+            samples = s->frame.data[c];
+            for (i = n; i > 0; i--) {
+                AV_WN16A(samples, bytestream_get_le16(&src));
                 samples += 2;
             }
+        }
         break;
     }
     case AV_CODEC_ID_PCM_U16LE:
@@ -516,18 +518,18 @@
     PCM_DECODER(id, sample_fmt_, name, long_name_)
 
 /* Note: Do not forget to add new entries to the Makefile as well. */
-PCM_CODEC  (AV_CODEC_ID_PCM_ALAW,         AV_SAMPLE_FMT_S16, pcm_alaw,         "PCM A-law");
+PCM_CODEC  (AV_CODEC_ID_PCM_ALAW,         AV_SAMPLE_FMT_S16, pcm_alaw,         "PCM A-law / G.711 A-law");
 PCM_DECODER(AV_CODEC_ID_PCM_DVD,          AV_SAMPLE_FMT_S32, pcm_dvd,          "PCM signed 20|24-bit big-endian");
 PCM_CODEC  (AV_CODEC_ID_PCM_F32BE,        AV_SAMPLE_FMT_FLT, pcm_f32be,        "PCM 32-bit floating point big-endian");
 PCM_CODEC  (AV_CODEC_ID_PCM_F32LE,        AV_SAMPLE_FMT_FLT, pcm_f32le,        "PCM 32-bit floating point little-endian");
 PCM_CODEC  (AV_CODEC_ID_PCM_F64BE,        AV_SAMPLE_FMT_DBL, pcm_f64be,        "PCM 64-bit floating point big-endian");
 PCM_CODEC  (AV_CODEC_ID_PCM_F64LE,        AV_SAMPLE_FMT_DBL, pcm_f64le,        "PCM 64-bit floating point little-endian");
-PCM_DECODER(AV_CODEC_ID_PCM_LXF,          AV_SAMPLE_FMT_S32P, pcm_lxf,          "PCM signed 20-bit little-endian planar");
-PCM_CODEC  (AV_CODEC_ID_PCM_MULAW,        AV_SAMPLE_FMT_S16, pcm_mulaw,        "PCM mu-law");
+PCM_DECODER(AV_CODEC_ID_PCM_LXF,          AV_SAMPLE_FMT_S32P,pcm_lxf,          "PCM signed 20-bit little-endian planar");
+PCM_CODEC  (AV_CODEC_ID_PCM_MULAW,        AV_SAMPLE_FMT_S16, pcm_mulaw,        "PCM mu-law / G.711 mu-law");
 PCM_CODEC  (AV_CODEC_ID_PCM_S8,           AV_SAMPLE_FMT_U8,  pcm_s8,           "PCM signed 8-bit");
 PCM_CODEC  (AV_CODEC_ID_PCM_S16BE,        AV_SAMPLE_FMT_S16, pcm_s16be,        "PCM signed 16-bit big-endian");
 PCM_CODEC  (AV_CODEC_ID_PCM_S16LE,        AV_SAMPLE_FMT_S16, pcm_s16le,        "PCM signed 16-bit little-endian");
-PCM_DECODER(AV_CODEC_ID_PCM_S16LE_PLANAR, AV_SAMPLE_FMT_S16, pcm_s16le_planar, "PCM 16-bit little-endian planar");
+PCM_DECODER(AV_CODEC_ID_PCM_S16LE_PLANAR, AV_SAMPLE_FMT_S16P,pcm_s16le_planar, "PCM 16-bit little-endian planar");
 PCM_CODEC  (AV_CODEC_ID_PCM_S24BE,        AV_SAMPLE_FMT_S32, pcm_s24be,        "PCM signed 24-bit big-endian");
 PCM_CODEC  (AV_CODEC_ID_PCM_S24DAUD,      AV_SAMPLE_FMT_S16, pcm_s24daud,      "PCM D-Cinema audio signed 24-bit");
 PCM_CODEC  (AV_CODEC_ID_PCM_S24LE,        AV_SAMPLE_FMT_S32, pcm_s24le,        "PCM signed 24-bit little-endian");
@@ -541,3 +543,4 @@
 PCM_CODEC  (AV_CODEC_ID_PCM_U32BE,        AV_SAMPLE_FMT_S32, pcm_u32be,        "PCM unsigned 32-bit big-endian");
 PCM_CODEC  (AV_CODEC_ID_PCM_U32LE,        AV_SAMPLE_FMT_S32, pcm_u32le,        "PCM unsigned 32-bit little-endian");
 PCM_DECODER(AV_CODEC_ID_PCM_ZORK,         AV_SAMPLE_FMT_U8,  pcm_zork,         "PCM Zork");
+
diff --git a/libavcodec/pcm_tablegen.c b/libavcodec/pcm_tablegen.c
index 7b4bc8c..bf8e7fb 100644
--- a/libavcodec/pcm_tablegen.c
+++ b/libavcodec/pcm_tablegen.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/pcm_tablegen.h b/libavcodec/pcm_tablegen.h
index 79d6561..1387210 100644
--- a/libavcodec/pcm_tablegen.h
+++ b/libavcodec/pcm_tablegen.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c
index 45e751b..722e89f 100644
--- a/libavcodec/pcx.c
+++ b/libavcodec/pcx.c
@@ -5,20 +5,20 @@
  * This decoder does not support CGA palettes. I am unable to find samples
  * and Netpbm cannot generate them.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -31,7 +31,8 @@
     AVFrame picture;
 } PCXContext;
 
-static av_cold int pcx_init(AVCodecContext *avctx) {
+static av_cold int pcx_init(AVCodecContext *avctx)
+{
     PCXContext *s = avctx->priv_data;
 
     avcodec_get_frame_defaults(&s->picture);
@@ -40,84 +41,86 @@
     return 0;
 }
 
-/**
- * @return advanced src pointer
- */
-static const uint8_t *pcx_rle_decode(const uint8_t *src, uint8_t *dst,
-                            unsigned int bytes_per_scanline, int compressed) {
+static void pcx_rle_decode(GetByteContext *gb, uint8_t *dst,
+                           unsigned int bytes_per_scanline, int compressed)
+{
     unsigned int i = 0;
     unsigned char run, value;
 
     if (compressed) {
         while (i<bytes_per_scanline) {
             run = 1;
-            value = *src++;
+            value = bytestream2_get_byte(gb);
             if (value >= 0xc0) {
                 run = value & 0x3f;
-                value = *src++;
+                value = bytestream2_get_byte(gb);
             }
             while (i<bytes_per_scanline && run--)
                 dst[i++] = value;
         }
     } else {
-        memcpy(dst, src, bytes_per_scanline);
-        src += bytes_per_scanline;
+        bytestream2_get_buffer(gb, dst, bytes_per_scanline);
     }
-
-    return src;
 }
 
-static void pcx_palette(const uint8_t **src, uint32_t *dst, unsigned int pallen) {
-    unsigned int i;
+static void pcx_palette(GetByteContext *gb, uint32_t *dst, int pallen)
+{
+    int i;
 
+    pallen = FFMIN(pallen, bytestream2_get_bytes_left(gb) / 3);
     for (i=0; i<pallen; i++)
-        *dst++ = bytestream_get_be24(src);
+        *dst++ = 0xFF000000 | bytestream2_get_be24u(gb);
     if (pallen < 256)
         memset(dst, 0, (256 - pallen) * sizeof(*dst));
 }
 
 static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
-                            AVPacket *avpkt) {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
+                            AVPacket *avpkt)
+{
     PCXContext * const s = avctx->priv_data;
     AVFrame *picture = data;
     AVFrame * const p = &s->picture;
-    int compressed, xmin, ymin, xmax, ymax;
+    GetByteContext gb;
+    int compressed, xmin, ymin, xmax, ymax, ret;
     unsigned int w, h, bits_per_pixel, bytes_per_line, nplanes, stride, y, x,
                  bytes_per_scanline;
-    uint8_t *ptr;
-    uint8_t const *bufstart = buf;
-    uint8_t *scanline;
-    int ret = -1;
+    uint8_t *ptr, *scanline;
 
-    if (buf[0] != 0x0a || buf[1] > 5) {
+    if (avpkt->size < 128)
+        return AVERROR_INVALIDDATA;
+
+    bytestream2_init(&gb, avpkt->data, avpkt->size);
+
+    if (bytestream2_get_byteu(&gb) != 0x0a || bytestream2_get_byteu(&gb) > 5) {
         av_log(avctx, AV_LOG_ERROR, "this is not PCX encoded data\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
-    compressed = buf[2];
-    xmin = AV_RL16(buf+ 4);
-    ymin = AV_RL16(buf+ 6);
-    xmax = AV_RL16(buf+ 8);
-    ymax = AV_RL16(buf+10);
+    compressed = bytestream2_get_byteu(&gb);
+    bits_per_pixel = bytestream2_get_byteu(&gb);
+    xmin = bytestream2_get_le16u(&gb);
+    ymin = bytestream2_get_le16u(&gb);
+    xmax = bytestream2_get_le16u(&gb);
+    ymax = bytestream2_get_le16u(&gb);
+    avctx->sample_aspect_ratio.num = bytestream2_get_le16u(&gb);
+    avctx->sample_aspect_ratio.den = bytestream2_get_le16u(&gb);
 
     if (xmax < xmin || ymax < ymin) {
         av_log(avctx, AV_LOG_ERROR, "invalid image dimensions\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     w = xmax - xmin + 1;
     h = ymax - ymin + 1;
 
-    bits_per_pixel     = buf[3];
-    bytes_per_line     = AV_RL16(buf+66);
-    nplanes            = buf[65];
+    bytestream2_skipu(&gb, 49);
+    nplanes            = bytestream2_get_byteu(&gb);
+    bytes_per_line     = bytestream2_get_le16u(&gb);
     bytes_per_scanline = nplanes * bytes_per_line;
 
     if (bytes_per_scanline < w * bits_per_pixel * nplanes / 8) {
         av_log(avctx, AV_LOG_ERROR, "PCX data is corrupted\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     switch ((nplanes<<8) + bits_per_pixel) {
@@ -135,21 +138,21 @@
             break;
         default:
             av_log(avctx, AV_LOG_ERROR, "invalid PCX file\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
     }
 
-    buf += 128;
+    bytestream2_skipu(&gb, 60);
 
     if (p->data[0])
         avctx->release_buffer(avctx, p);
 
     if (av_image_check_size(w, h, 0, avctx))
-        return -1;
+        return AVERROR_INVALIDDATA;
     if (w != avctx->width || h != avctx->height)
         avcodec_set_dimensions(avctx, w, h);
-    if (avctx->get_buffer(avctx, p) < 0) {
+    if ((ret = avctx->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;
@@ -163,7 +166,7 @@
 
     if (nplanes == 3 && bits_per_pixel == 8) {
         for (y=0; y<h; y++) {
-            buf = pcx_rle_decode(buf, scanline, bytes_per_scanline, compressed);
+            pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed);
 
             for (x=0; x<w; x++) {
                 ptr[3*x  ] = scanline[x                    ];
@@ -175,19 +178,20 @@
         }
 
     } else if (nplanes == 1 && bits_per_pixel == 8) {
-        const uint8_t *palstart = bufstart + buf_size - 769;
+        int palstart = avpkt->size - 769;
 
         for (y=0; y<h; y++, ptr+=stride) {
-            buf = pcx_rle_decode(buf, scanline, bytes_per_scanline, compressed);
+            pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed);
             memcpy(ptr, scanline, w);
         }
 
-        if (buf != palstart) {
+        if (bytestream2_tell(&gb) != palstart) {
             av_log(avctx, AV_LOG_WARNING, "image data possibly corrupted\n");
-            buf = palstart;
+            bytestream2_seek(&gb, palstart, SEEK_SET);
         }
-        if (*buf++ != 12) {
+        if (bytestream2_get_byte(&gb) != 12) {
             av_log(avctx, AV_LOG_ERROR, "expected palette after image data\n");
+            ret = AVERROR_INVALIDDATA;
             goto end;
         }
 
@@ -197,7 +201,7 @@
         for (y=0; y<h; y++) {
             init_get_bits(&s, scanline, bytes_per_scanline<<3);
 
-            buf = pcx_rle_decode(buf, scanline, bytes_per_scanline, compressed);
+            pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed);
 
             for (x=0; x<w; x++)
                 ptr[x] = get_bits(&s, bits_per_pixel);
@@ -208,7 +212,7 @@
         int i;
 
         for (y=0; y<h; y++) {
-            buf = pcx_rle_decode(buf, scanline, bytes_per_scanline, compressed);
+            pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed);
 
             for (x=0; x<w; x++) {
                 int m = 0x80 >> (x&7), v = 0;
@@ -222,23 +226,28 @@
         }
     }
 
+    ret = bytestream2_tell(&gb);
     if (nplanes == 1 && bits_per_pixel == 8) {
-        pcx_palette(&buf, (uint32_t *) p->data[1], 256);
+        pcx_palette(&gb, (uint32_t *) p->data[1], 256);
+        ret += 256 * 3;
+    } else if (bits_per_pixel * nplanes == 1) {
+        AV_WN32A(p->data[1]  , 0xFF000000);
+        AV_WN32A(p->data[1]+4, 0xFFFFFFFF);
     } else if (bits_per_pixel < 8) {
-        const uint8_t *palette = bufstart+16;
-        pcx_palette(&palette, (uint32_t *) p->data[1], 16);
+        bytestream2_seek(&gb, 16, SEEK_SET);
+        pcx_palette(&gb, (uint32_t *) p->data[1], 16);
     }
 
     *picture = s->picture;
     *data_size = sizeof(AVFrame);
 
-    ret = buf - bufstart;
 end:
     av_free(scanline);
     return ret;
 }
 
-static av_cold int pcx_end(AVCodecContext *avctx) {
+static av_cold int pcx_end(AVCodecContext *avctx)
+{
     PCXContext *s = avctx->priv_data;
 
     if(s->picture.data[0])
diff --git a/libavcodec/pcxenc.c b/libavcodec/pcxenc.c
index e0ee20a..7f710a2 100644
--- a/libavcodec/pcxenc.c
+++ b/libavcodec/pcxenc.c
@@ -2,20 +2,20 @@
  * PC Paintbrush PCX (.pcx) image encoder
  * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -28,6 +28,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "libavutil/imgutils.h"
 #include "internal.h"
 
 typedef struct PCXContext {
@@ -104,8 +105,9 @@
     const uint8_t *buf_end;
     uint8_t *buf;
 
-    int bpp, nplanes, i, y, line_bytes, written, ret, max_pkt_size;
+    int bpp, nplanes, i, y, line_bytes, written, ret, max_pkt_size, sw, sh;
     const uint32_t *pal = NULL;
+    uint32_t palette256[256];
     const uint8_t *src;
 
     *pict = *frame;
@@ -127,6 +129,11 @@
     case AV_PIX_FMT_RGB4_BYTE:
     case AV_PIX_FMT_BGR4_BYTE:
     case AV_PIX_FMT_GRAY8:
+        bpp = 8;
+        nplanes = 1;
+        ff_set_systematic_pal2(palette256, avctx->pix_fmt);
+        pal = palette256;
+        break;
     case AV_PIX_FMT_PAL8:
         bpp = 8;
         nplanes = 1;
@@ -146,13 +153,16 @@
     line_bytes = (line_bytes + 1) & ~1;
 
     max_pkt_size = 128 + avctx->height * 2 * line_bytes * nplanes + (pal ? 256*3 + 1 : 0);
-    if ((ret = ff_alloc_packet(pkt, max_pkt_size)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n", max_pkt_size);
+    if ((ret = ff_alloc_packet2(avctx, pkt, max_pkt_size)) < 0)
         return ret;
-    }
     buf     = pkt->data;
     buf_end = pkt->data + pkt->size;
 
+    sw = avctx->sample_aspect_ratio.num;
+    sh = avctx->sample_aspect_ratio.den;
+    if (sw > 0xFFFFu || sh > 0xFFFFu)
+        av_reduce(&sw, &sh, sw, sh, 0xFFFFu);
+
     bytestream_put_byte(&buf, 10);                  // manufacturer
     bytestream_put_byte(&buf, 5);                   // version
     bytestream_put_byte(&buf, 1);                   // encoding
@@ -161,8 +171,8 @@
     bytestream_put_le16(&buf, 0);                   // y min
     bytestream_put_le16(&buf, avctx->width - 1);    // x max
     bytestream_put_le16(&buf, avctx->height - 1);   // y max
-    bytestream_put_le16(&buf, 0);                   // horizontal DPI
-    bytestream_put_le16(&buf, 0);                   // vertical DPI
+    bytestream_put_le16(&buf, sw);                  // horizontal DPI
+    bytestream_put_le16(&buf, sh);                  // vertical DPI
     for (i = 0; i < 16; i++)
         bytestream_put_be24(&buf, pal ? pal[i] : 0);// palette (<= 16 color only)
     bytestream_put_byte(&buf, 0);                   // reserved
diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c
index 9fd26d8..d0d4dd6a 100644
--- a/libavcodec/pgssubdec.c
+++ b/libavcodec/pgssubdec.c
@@ -2,20 +2,20 @@
  * PGS subtitle decoder
  * Copyright (c) 2009 Stephen Backway
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,6 +29,7 @@
 #include "bytestream.h"
 #include "libavutil/colorspace.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
 
 #define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
 
@@ -40,11 +41,17 @@
     DISPLAY_SEGMENT      = 0x80,
 };
 
-typedef struct PGSSubPresentation {
+typedef struct PGSSubPictureReference {
     int x;
     int y;
-    int id_number;
-    int object_number;
+    int picture_id;
+    int composition;
+} PGSSubPictureReference;
+
+typedef struct PGSSubPresentation {
+    int                    id_number;
+    int                    object_count;
+    PGSSubPictureReference *objects;
 } PGSSubPresentation;
 
 typedef struct PGSSubPicture {
@@ -56,24 +63,34 @@
 } PGSSubPicture;
 
 typedef struct PGSSubContext {
+    AVClass *class;
     PGSSubPresentation presentation;
     uint32_t           clut[256];
-    PGSSubPicture      picture;
+    PGSSubPicture      pictures[UINT16_MAX];
+    int64_t            pts;
+    int forced_subs_only;
 } PGSSubContext;
 
 static av_cold int init_decoder(AVCodecContext *avctx)
 {
-    avctx->pix_fmt = AV_PIX_FMT_PAL8;
+    avctx->pix_fmt     = AV_PIX_FMT_PAL8;
 
     return 0;
 }
 
 static av_cold int close_decoder(AVCodecContext *avctx)
 {
+    uint16_t picture;
+
     PGSSubContext *ctx = avctx->priv_data;
 
-    av_freep(&ctx->picture.rle);
-    ctx->picture.rle_buffer_size  = 0;
+    av_freep(&ctx->presentation.objects);
+    ctx->presentation.object_count = 0;
+
+    for (picture = 0; picture < UINT16_MAX; ++picture) {
+        av_freep(&ctx->pictures[picture].rle);
+        ctx->pictures[picture].rle_buffer_size = 0;
+    }
 
     return 0;
 }
@@ -88,7 +105,7 @@
  * @param buf pointer to the RLE data to process
  * @param buf_size size of the RLE data to process
  */
-static int decode_rle(AVCodecContext *avctx, AVSubtitle *sub,
+static int decode_rle(AVCodecContext *avctx, AVSubtitle *sub, int rect,
                       const uint8_t *buf, unsigned int buf_size)
 {
     const uint8_t *rle_bitmap_end;
@@ -96,15 +113,15 @@
 
     rle_bitmap_end = buf + buf_size;
 
-    sub->rects[0]->pict.data[0] = av_malloc(sub->rects[0]->w * sub->rects[0]->h);
+    sub->rects[rect]->pict.data[0] = av_malloc(sub->rects[rect]->w * sub->rects[rect]->h);
 
-    if (!sub->rects[0]->pict.data[0])
+    if (!sub->rects[rect]->pict.data[0])
         return -1;
 
     pixel_count = 0;
     line_count  = 0;
 
-    while (buf < rle_bitmap_end && line_count < sub->rects[0]->h) {
+    while (buf < rle_bitmap_end && line_count < sub->rects[rect]->h) {
         uint8_t flags, color;
         int run;
 
@@ -119,27 +136,27 @@
             color = flags & 0x80 ? bytestream_get_byte(&buf) : 0;
         }
 
-        if (run > 0 && pixel_count + run <= sub->rects[0]->w * sub->rects[0]->h) {
-            memset(sub->rects[0]->pict.data[0] + pixel_count, color, run);
+        if (run > 0 && pixel_count + run <= sub->rects[rect]->w * sub->rects[rect]->h) {
+            memset(sub->rects[rect]->pict.data[0] + pixel_count, color, run);
             pixel_count += run;
         } else if (!run) {
             /*
              * New Line. Check if correct pixels decoded, if not display warning
              * and adjust bitmap pointer to correct new line position.
              */
-            if (pixel_count % sub->rects[0]->w > 0)
+            if (pixel_count % sub->rects[rect]->w > 0)
                 av_log(avctx, AV_LOG_ERROR, "Decoded %d pixels, when line should be %d pixels\n",
-                       pixel_count % sub->rects[0]->w, sub->rects[0]->w);
+                       pixel_count % sub->rects[rect]->w, sub->rects[rect]->w);
             line_count++;
         }
     }
 
-    if (pixel_count < sub->rects[0]->w * sub->rects[0]->h) {
+    if (pixel_count < sub->rects[rect]->w * sub->rects[rect]->h) {
         av_log(avctx, AV_LOG_ERROR, "Insufficient RLE data for subtitle\n");
         return -1;
     }
 
-    av_dlog(avctx, "Pixel Count = %d, Area = %d\n", pixel_count, sub->rects[0]->w * sub->rects[0]->h);
+    av_dlog(avctx, "Pixel Count = %d, Area = %d\n", pixel_count, sub->rects[rect]->w * sub->rects[rect]->h);
 
     return 0;
 }
@@ -162,25 +179,28 @@
 
     uint8_t sequence_desc;
     unsigned int rle_bitmap_len, width, height;
+    uint16_t picture_id;
 
     if (buf_size <= 4)
         return -1;
     buf_size -= 4;
 
-    /* skip 3 unknown bytes: Object ID (2 bytes), Version Number */
-    buf += 3;
+    picture_id = bytestream_get_be16(&buf);
+
+    /* skip 1 unknown byte: Version Number */
+    buf++;
 
     /* Read the Sequence Description to determine if start of RLE data or appended to previous RLE */
     sequence_desc = bytestream_get_byte(&buf);
 
     if (!(sequence_desc & 0x80)) {
         /* Additional RLE data */
-        if (buf_size > ctx->picture.rle_remaining_len)
+        if (buf_size > ctx->pictures[picture_id].rle_remaining_len)
             return -1;
 
-        memcpy(ctx->picture.rle + ctx->picture.rle_data_len, buf, buf_size);
-        ctx->picture.rle_data_len += buf_size;
-        ctx->picture.rle_remaining_len -= buf_size;
+        memcpy(ctx->pictures[picture_id].rle + ctx->pictures[picture_id].rle_data_len, buf, buf_size);
+        ctx->pictures[picture_id].rle_data_len += buf_size;
+        ctx->pictures[picture_id].rle_remaining_len -= buf_size;
 
         return 0;
     }
@@ -202,17 +222,17 @@
         return -1;
     }
 
-    ctx->picture.w = width;
-    ctx->picture.h = height;
+    ctx->pictures[picture_id].w = width;
+    ctx->pictures[picture_id].h = height;
 
-    av_fast_malloc(&ctx->picture.rle, &ctx->picture.rle_buffer_size, rle_bitmap_len);
+    av_fast_malloc(&ctx->pictures[picture_id].rle, &ctx->pictures[picture_id].rle_buffer_size, rle_bitmap_len);
 
-    if (!ctx->picture.rle)
+    if (!ctx->pictures[picture_id].rle)
         return -1;
 
-    memcpy(ctx->picture.rle, buf, buf_size);
-    ctx->picture.rle_data_len = buf_size;
-    ctx->picture.rle_remaining_len = rle_bitmap_len - buf_size;
+    memcpy(ctx->pictures[picture_id].rle, buf, buf_size);
+    ctx->pictures[picture_id].rle_data_len      = buf_size;
+    ctx->pictures[picture_id].rle_remaining_len = rle_bitmap_len - buf_size;
 
     return 0;
 }
@@ -268,18 +288,17 @@
  * @param buf pointer to the packet to process
  * @param buf_size size of packet to process
  * @todo TODO: Implement cropping
- * @todo TODO: Implement forcing of subtitles
  */
 static void parse_presentation_segment(AVCodecContext *avctx,
                                        const uint8_t *buf, int buf_size)
 {
     PGSSubContext *ctx = avctx->priv_data;
 
-    int x, y;
-
     int w = bytestream_get_be16(&buf);
     int h = bytestream_get_be16(&buf);
 
+    uint16_t object_index;
+
     av_dlog(avctx, "Video Dimensions %dx%d\n",
             w, h);
     if (av_image_check_size(w, h, 0, avctx) >= 0)
@@ -298,34 +317,46 @@
      */
     buf += 3;
 
-    ctx->presentation.object_number = bytestream_get_byte(&buf);
-    if (!ctx->presentation.object_number)
+    ctx->presentation.object_count = bytestream_get_byte(&buf);
+    if (!ctx->presentation.object_count)
         return;
 
-    /*
-     * Skip 4 bytes of unknown:
-     *     object_id_ref (2 bytes),
-     *     window_id_ref,
-     *     composition_flag (0x80 - object cropped, 0x40 - object forced)
-     */
-    buf += 4;
-
-    x = bytestream_get_be16(&buf);
-    y = bytestream_get_be16(&buf);
-
-    /* TODO If cropping, cropping_x, cropping_y, cropping_width, cropping_height (all 2 bytes).*/
-
-    av_dlog(avctx, "Subtitle Placement x=%d, y=%d\n", x, y);
-
-    if (x > avctx->width || y > avctx->height) {
-        av_log(avctx, AV_LOG_ERROR, "Subtitle out of video bounds. x = %d, y = %d, video width = %d, video height = %d.\n",
-               x, y, avctx->width, avctx->height);
-        x = 0; y = 0;
+    /* Verify that enough bytes are remaining for all of the objects. */
+    buf_size -= 11;
+    if (buf_size < ctx->presentation.object_count * 8) {
+        ctx->presentation.object_count = 0;
+        return;
     }
 
-    /* Fill in dimensions */
-    ctx->presentation.x = x;
-    ctx->presentation.y = y;
+    av_freep(&ctx->presentation.objects);
+    ctx->presentation.objects = av_malloc(sizeof(PGSSubPictureReference) * ctx->presentation.object_count);
+    if (!ctx->presentation.objects) {
+        ctx->presentation.object_count = 0;
+        return;
+    }
+
+    for (object_index = 0; object_index < ctx->presentation.object_count; ++object_index) {
+        PGSSubPictureReference *reference = &ctx->presentation.objects[object_index];
+        reference->picture_id             = bytestream_get_be16(&buf);
+
+        /* Skip window_id_ref */
+        buf++;
+        /* composition_flag (0x80 - object cropped, 0x40 - object forced) */
+        reference->composition = bytestream_get_byte(&buf);
+
+        reference->x = bytestream_get_be16(&buf);
+        reference->y = bytestream_get_be16(&buf);
+
+        /* TODO If cropping, cropping_x, cropping_y, cropping_width, cropping_height (all 2 bytes).*/
+        av_dlog(avctx, "Subtitle Placement ID=%d, x=%d, y=%d\n", reference->picture_id, reference->x, reference->y);
+
+        if (reference->x > avctx->width || reference->y > avctx->height) {
+            av_log(avctx, AV_LOG_ERROR, "Subtitle out of video bounds. x = %d, y = %d, video width = %d, video height = %d.\n",
+                   reference->x, reference->y, avctx->width, avctx->height);
+            reference->x = 0;
+            reference->y = 0;
+        }
+    }
 }
 
 /**
@@ -348,47 +379,61 @@
 {
     AVSubtitle    *sub = data;
     PGSSubContext *ctx = avctx->priv_data;
+    int64_t pts;
+
+    uint16_t rect;
 
     /*
      *      The end display time is a timeout value and is only reached
-     *      if the next subtitle is later then timeout or subtitle has
+     *      if the next subtitle is later than timeout or subtitle has
      *      not been cleared by a subsequent empty display command.
      */
 
+    pts = ctx->pts != AV_NOPTS_VALUE ? ctx->pts : sub->pts;
     memset(sub, 0, sizeof(*sub));
-    // Blank if last object_number was 0.
-    // Note that this may be wrong for more complex subtitles.
-    if (!ctx->presentation.object_number)
+    sub->pts = pts;
+    ctx->pts = AV_NOPTS_VALUE;
+
+    // Blank if last object_count was 0.
+    if (!ctx->presentation.object_count)
         return 1;
+
     sub->start_display_time = 0;
     sub->end_display_time   = 20000;
     sub->format             = 0;
 
-    sub->rects     = av_mallocz(sizeof(*sub->rects));
-    sub->rects[0]  = av_mallocz(sizeof(*sub->rects[0]));
-    sub->num_rects = 1;
+    sub->num_rects = ctx->presentation.object_count;
+    sub->rects     = av_mallocz(sizeof(*sub->rects) * sub->num_rects);
 
-    sub->rects[0]->x    = ctx->presentation.x;
-    sub->rects[0]->y    = ctx->presentation.y;
-    sub->rects[0]->w    = ctx->picture.w;
-    sub->rects[0]->h    = ctx->picture.h;
-    sub->rects[0]->type = SUBTITLE_BITMAP;
+    for (rect = 0; rect < sub->num_rects; ++rect) {
+        uint16_t picture_id    = ctx->presentation.objects[rect].picture_id;
+        sub->rects[rect]       = av_mallocz(sizeof(*sub->rects[rect]));
+        sub->rects[rect]->x    = ctx->presentation.objects[rect].x;
+        sub->rects[rect]->y    = ctx->presentation.objects[rect].y;
+        sub->rects[rect]->w    = ctx->pictures[picture_id].w;
+        sub->rects[rect]->h    = ctx->pictures[picture_id].h;
+        sub->rects[rect]->type = SUBTITLE_BITMAP;
 
-    /* Process bitmap */
-    sub->rects[0]->pict.linesize[0] = ctx->picture.w;
+        /* Process bitmap */
+        sub->rects[rect]->pict.linesize[0] = ctx->pictures[picture_id].w;
+        if (ctx->pictures[picture_id].rle) {
+            if (ctx->pictures[picture_id].rle_remaining_len)
+                av_log(avctx, AV_LOG_ERROR, "RLE data length %u is %u bytes shorter than expected\n",
+                       ctx->pictures[picture_id].rle_data_len, ctx->pictures[picture_id].rle_remaining_len);
+            if (decode_rle(avctx, sub, rect, ctx->pictures[picture_id].rle, ctx->pictures[picture_id].rle_data_len) < 0)
+                return 0;
+        }
 
-    if (ctx->picture.rle) {
-        if (ctx->picture.rle_remaining_len)
-            av_log(avctx, AV_LOG_ERROR, "RLE data length %u is %u bytes shorter than expected\n",
-                   ctx->picture.rle_data_len, ctx->picture.rle_remaining_len);
-        if(decode_rle(avctx, sub, ctx->picture.rle, ctx->picture.rle_data_len) < 0)
-            return 0;
+        /* Allocate memory for colors */
+        sub->rects[rect]->nb_colors    = 256;
+        sub->rects[rect]->pict.data[1] = av_mallocz(AVPALETTE_SIZE);
+
+        /* Copy the forced flag */
+        sub->rects[rect]->forced = (ctx->presentation.objects[rect].composition & 0x40) != 0;
+
+        if (!ctx->forced_subs_only || ctx->presentation.objects[rect].composition & 0x40)
+        memcpy(sub->rects[rect]->pict.data[1], ctx->clut, sub->rects[rect]->nb_colors * sizeof(uint32_t));
     }
-    /* Allocate memory for colors */
-    sub->rects[0]->nb_colors    = 256;
-    sub->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE);
-
-    memcpy(sub->rects[0]->pict.data[1], ctx->clut, sub->rects[0]->nb_colors * sizeof(uint32_t));
 
     return 1;
 }
@@ -396,8 +441,10 @@
 static int decode(AVCodecContext *avctx, void *data, int *data_size,
                   AVPacket *avpkt)
 {
+    PGSSubContext *ctx = avctx->priv_data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
+    AVSubtitle *sub    = data;
 
     const uint8_t *buf_end;
     uint8_t       segment_type;
@@ -442,6 +489,7 @@
             break;
         case PRESENTATION_SEGMENT:
             parse_presentation_segment(avctx, buf, segment_length);
+            ctx->pts = sub->pts;
             break;
         case WINDOW_SEGMENT:
             /*
@@ -468,6 +516,20 @@
     return buf_size;
 }
 
+#define OFFSET(x) offsetof(PGSSubContext, x)
+#define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+    {"forced_subs_only", "Only show forced subtitles", OFFSET(forced_subs_only), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SD},
+    { NULL },
+};
+
+static const AVClass pgsdec_class = {
+    .class_name = "PGS subtitle decoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_pgssub_decoder = {
     .name           = "pgssub",
     .type           = AVMEDIA_TYPE_SUBTITLE,
@@ -477,4 +539,5 @@
     .close          = close_decoder,
     .decode         = decode,
     .long_name      = NULL_IF_CONFIG_SMALL("HDMV Presentation Graphic Stream subtitles"),
+    .priv_class     = &pgsdec_class,
 };
diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c
index a0affc9..ad8eae0 100644
--- a/libavcodec/pictordec.c
+++ b/libavcodec/pictordec.c
@@ -2,20 +2,20 @@
  * Pictor/PC Paint decoder
  * Copyright (c) 2010 Peter Ross <pross@xvid.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -96,6 +96,14 @@
     [5] = { 0, 11, 12, 15 }, // mode5, high intensity
 };
 
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+    PicContext *s = avctx->priv_data;
+
+    avcodec_get_frame_defaults(&s->frame);
+    return 0;
+}
+
 static int decode_frame(AVCodecContext *avctx,
                         void *data, int *data_size,
                         AVPacket *avpkt)
@@ -121,11 +129,11 @@
     s->nb_planes   = (tmp >> 4) + 1;
     bpp            = bits_per_plane * s->nb_planes;
     if (bits_per_plane > 8 || bpp < 1 || bpp > 32) {
-        av_log_ask_for_sample(s, "unsupported bit depth\n");
+        av_log_ask_for_sample(avctx, "unsupported bit depth\n");
         return AVERROR_INVALIDDATA;
     }
 
-    if (bytestream2_peek_byte(&s->g) == 0xFF) {
+    if (bytestream2_peek_byte(&s->g) == 0xFF || bpp == 8) {
         bytestream2_skip(&s->g, 2);
         etype = bytestream2_get_le16(&s->g);
         esize = bytestream2_get_le16(&s->g);
@@ -175,13 +183,15 @@
         }
     } else if (etype == 4 || etype == 5) {
         npal = FFMIN(esize / 3, 256);
-        for (i = 0; i < npal; i++)
+        for (i = 0; i < npal; i++) {
             palette[i] = bytestream2_get_be24(&s->g) << 2;
+            palette[i] |= 0xFFU << 24 | palette[i] >> 6 & 0x30303;
+        }
     } else {
         if (bpp == 1) {
             npal = 2;
-            palette[0] = 0x000000;
-            palette[1] = 0xFFFFFF;
+            palette[0] = 0xFF000000;
+            palette[1] = 0xFFFFFFFF;
         } else if (bpp == 2) {
             npal = 4;
             for (i = 0; i < npal; i++)
@@ -196,11 +206,11 @@
     // skip remaining palette bytes
     bytestream2_seek(&s->g, pos_after_pal, SEEK_SET);
 
-    x = 0;
     y = s->height - 1;
-    plane = 0;
     if (bytestream2_get_le16(&s->g)) {
-        while (bytestream2_get_bytes_left(&s->g) >= 6) {
+        x = 0;
+        plane = 0;
+        while (y >= 0 && bytestream2_get_bytes_left(&s->g) >= 6) {
             int stop_size, marker, t1, t2;
 
             t1        = bytestream2_get_bytes_left(&s->g);
@@ -210,7 +220,7 @@
             bytestream2_skip(&s->g, 2);
             marker    = bytestream2_get_byte(&s->g);
 
-            while (plane < s->nb_planes &&
+            while (plane < s->nb_planes && y >= 0 &&
                    bytestream2_get_bytes_left(&s->g) > stop_size) {
                 int run = 1;
                 int val = bytestream2_get_byte(&s->g);
@@ -225,16 +235,17 @@
 
                 if (bits_per_plane == 8) {
                     picmemset_8bpp(s, val, run, &x, &y);
-                    if (y < 0)
-                        break;
                 } else {
                     picmemset(s, val, run, &x, &y, &plane, bits_per_plane);
                 }
             }
         }
     } else {
-        av_log_ask_for_sample(s, "uncompressed image\n");
-        return avpkt->size;
+        while (y >= 0 && bytestream2_get_bytes_left(&s->g) > 0) {
+            memcpy(s->frame.data[0] + y * s->frame.linesize[0], s->g.buffer, FFMIN(avctx->width, bytestream2_get_bytes_left(&s->g)));
+            bytestream2_skip(&s->g, avctx->width);
+            y--;
+        }
     }
 
     *data_size = sizeof(AVFrame);
@@ -255,6 +266,7 @@
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_PICTOR,
     .priv_data_size = sizeof(PicContext),
+    .init           = decode_init,
     .close          = decode_end,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
diff --git a/libavcodec/png.c b/libavcodec/png.c
index 70a080e..a4287bd 100644
--- a/libavcodec/png.c
+++ b/libavcodec/png.c
@@ -2,29 +2,25 @@
  * PNG image format
  * Copyright (c) 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avcodec.h"
-#include "bytestream.h"
 #include "png.h"
 
-const uint8_t ff_pngsig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
-const uint8_t ff_mngsig[8] = {138, 77, 78, 71, 13, 10, 26, 10};
-
 /* Mask to determine which y pixels are valid in a pass */
 const uint8_t ff_png_pass_ymask[NB_PASSES] = {
     0x80, 0x80, 0x08, 0x88, 0x22, 0xaa, 0x55,
@@ -40,11 +36,6 @@
     3, 3, 2, 2, 1, 1, 0
 };
 
-/* Mask to determine which pixels are valid in a pass */
-const uint8_t ff_png_pass_mask[NB_PASSES] = {
-    0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff
-};
-
 void *ff_png_zalloc(void *opaque, unsigned int items, unsigned int size)
 {
     if(items >= UINT_MAX / size)
diff --git a/libavcodec/png.h b/libavcodec/png.h
index b8c72ee..948c2f7 100644
--- a/libavcodec/png.h
+++ b/libavcodec/png.h
@@ -2,20 +2,20 @@
  * PNG image format
  * Copyright (c) 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -49,15 +49,12 @@
 
 #define NB_PASSES 7
 
-extern const uint8_t ff_pngsig[8];
-extern const uint8_t ff_mngsig[8];
+#define PNGSIG 0x89504e470d0a1a0a
+#define MNGSIG 0x8a4d4e470d0a1a0a
 
 /* Mask to determine which y pixels are valid in a pass */
 extern const uint8_t ff_png_pass_ymask[NB_PASSES];
 
-/* Mask to determine which pixels are valid in a pass */
-extern const uint8_t ff_png_pass_mask[NB_PASSES];
-
 void *ff_png_zalloc(void *opaque, unsigned int items, unsigned int size);
 
 void ff_png_zfree(void *opaque, void *ptr);
diff --git a/libavcodec/png_parser.c b/libavcodec/png_parser.c
new file mode 100644
index 0000000..6f153d9
--- /dev/null
+++ b/libavcodec/png_parser.c
@@ -0,0 +1,120 @@
+/*
+ * PNG parser
+ * Copyright (c) 2009 Peter Holik
+ *
+ * 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
+ * PNG parser
+ */
+
+#include "parser.h"
+#include "png.h"
+
+typedef struct PNGParseContext
+{
+    ParseContext pc;
+    uint32_t index;
+    uint32_t chunk_length;
+    uint32_t remaining_size;
+} PNGParseContext;
+
+static int png_parse(AVCodecParserContext *s, AVCodecContext *avctx,
+                     const uint8_t **poutbuf, int *poutbuf_size,
+                     const uint8_t *buf, int buf_size)
+{
+    PNGParseContext *ppc = s->priv_data;
+    int next = END_NOT_FOUND;
+    int i = 0;
+
+    s->pict_type = AV_PICTURE_TYPE_NONE;
+
+    *poutbuf_size = 0;
+    if (buf_size == 0)
+        return 0;
+
+    if (!ppc->pc.frame_start_found) {
+        uint64_t state64 = ppc->pc.state64;
+        for (; i < buf_size; i++) {
+            state64 = (state64 << 8) | buf[i];
+            if (state64 == PNGSIG || state64 == MNGSIG) {
+                i++;
+                ppc->pc.frame_start_found = 1;
+                break;
+            }
+        }
+        ppc->pc.state64 = state64;
+    } else
+        if (ppc->remaining_size) {
+            i = FFMIN(ppc->remaining_size, buf_size);
+            ppc->remaining_size -= i;
+            if (ppc->remaining_size)
+                goto flush;
+            if (ppc->index == -1) {
+                next = i;
+                goto flush;
+            }
+        }
+
+    for (;ppc->pc.frame_start_found && i < buf_size; i++) {
+        ppc->pc.state = (ppc->pc.state<<8) | buf[i];
+        if (ppc->index == 3) {
+            ppc->chunk_length = ppc->pc.state;
+            if (ppc->chunk_length > 0x7fffffff) {
+                ppc->index = ppc->pc.frame_start_found = 0;
+                goto flush;
+            }
+            ppc->chunk_length += 4;
+        } else if (ppc->index == 7) {
+            if (ppc->chunk_length >= buf_size - i)
+                    ppc->remaining_size = ppc->chunk_length - buf_size + i + 1;
+            if (ppc->pc.state == MKBETAG('I', 'E', 'N', 'D')) {
+                if (ppc->remaining_size)
+                    ppc->index = -1;
+                else
+                    next = ppc->chunk_length + i + 1;
+                break;
+            } else {
+                ppc->index = 0;
+                if (ppc->remaining_size)
+                    break;
+                else
+                    i += ppc->chunk_length;
+                continue;
+            }
+        }
+        ppc->index++;
+    }
+flush:
+    if (ff_combine_frame(&ppc->pc, next, &buf, &buf_size) < 0)
+        return buf_size;
+
+    ppc->index = ppc->pc.frame_start_found = 0;
+
+    *poutbuf      = buf;
+    *poutbuf_size = buf_size;
+    return next;
+}
+
+AVCodecParser ff_png_parser = {
+    .codec_ids      = { AV_CODEC_ID_PNG },
+    .priv_data_size = sizeof(PNGParseContext),
+    .parser_parse   = png_parse,
+    .parser_close   = ff_parse_close,
+};
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index aaedeff..a3af924 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -2,22 +2,25 @@
  * PNG image format
  * Copyright (c) 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
+
+//#define DEBUG
+
 #include "libavutil/imgutils.h"
 #include "avcodec.h"
 #include "bytestream.h"
@@ -25,7 +28,7 @@
 #include "pngdsp.h"
 
 /* TODO:
- * - add 2, 4 and 16 bit depth support
+ * - add 16 bit depth support
  */
 
 #include <zlib.h>
@@ -34,6 +37,7 @@
 
 typedef struct PNGDecContext {
     PNGDSPContext dsp;
+    AVCodecContext *avctx;
 
     GetByteContext gb;
     AVFrame picture1, picture2;
@@ -64,9 +68,14 @@
     z_stream zstream;
 } PNGDecContext;
 
+/* Mask to determine which pixels are valid in a pass */
+static const uint8_t png_pass_mask[NB_PASSES] = {
+    0x01, 0x01, 0x11, 0x11, 0x55, 0x55, 0xff,
+};
+
 /* Mask to determine which y pixels can be written in a pass */
 static const uint8_t png_pass_dsp_ymask[NB_PASSES] = {
-    0xff, 0xff, 0x0f, 0xcc, 0x33, 0xff, 0x55,
+    0xff, 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
 };
 
 /* Mask to determine which pixels to overwrite while displaying */
@@ -85,39 +94,54 @@
     uint8_t *d;
     const uint8_t *s;
 
-    mask = ff_png_pass_mask[pass];
+    mask = png_pass_mask[pass];
     dsp_mask = png_pass_dsp_mask[pass];
     switch(bits_per_pixel) {
     case 1:
-        /* we must initialize the line to zero before writing to it */
-        if (pass == 0)
-            memset(dst, 0, (width + 7) >> 3);
         src_x = 0;
         for(x = 0; x < width; x++) {
             j = (x & 7);
             if ((dsp_mask << j) & 0x80) {
                 b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1;
+                dst[x >> 3] &= 0xFF7F>>j;
                 dst[x >> 3] |= b << (7 - j);
             }
             if ((mask << j) & 0x80)
                 src_x++;
         }
         break;
+    case 2:
+        src_x = 0;
+        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;
+                dst[x >> 2] &= 0xFF3F>>j2;
+                dst[x >> 2] |= b << (6 - j2);
+            }
+            if ((mask << j) & 0x80)
+                src_x++;
+        }
+        break;
+    case 4:
+        src_x = 0;
+        for(x = 0; x < width; x++) {
+            int j2 = 4*(x&1);
+            j = (x & 7);
+            if ((dsp_mask << j) & 0x80) {
+                b = (src[src_x >> 1] >> (4 - 4*(src_x & 1))) & 15;
+                dst[x >> 1] &= 0xFF0F>>j2;
+                dst[x >> 1] |= b << (4 - j2);
+            }
+            if ((mask << j) & 0x80)
+                src_x++;
+        }
+        break;
     default:
         bpp = bits_per_pixel >> 3;
         d = dst;
         s = src;
-        if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
-            for(x = 0; x < width; x++) {
-                j = x & 7;
-                if ((dsp_mask << j) & 0x80) {
-                    *(uint32_t *)d = (s[3] << 24) | (s[0] << 16) | (s[1] << 8) | s[2];
-                }
-                d += bpp;
-                if ((mask << j) & 0x80)
-                    s += bpp;
-            }
-        } else {
             for(x = 0; x < width; x++) {
                 j = x & 7;
                 if ((dsp_mask << j) & 0x80) {
@@ -127,7 +151,6 @@
                 if ((mask << j) & 0x80)
                     s += bpp;
             }
-        }
         break;
     }
 }
@@ -230,7 +253,7 @@
             p = last[i];
             dst[i] = p + src[i];
         }
-        if(bpp > 1 && 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);
@@ -241,43 +264,21 @@
     }
 }
 
-static av_always_inline void convert_to_rgb32_loco(uint8_t *dst, const uint8_t *src, int width, int loco)
-{
-    int j;
-    unsigned int r, g, b, a;
-
-    for(j = 0;j < width; j++) {
-        r = src[0];
-        g = src[1];
-        b = src[2];
-        a = src[3];
-        if(loco) {
-            r = (r+g)&0xff;
-            b = (b+g)&0xff;
-        }
-        *(uint32_t *)dst = (a << 24) | (r << 16) | (g << 8) | b;
-        dst += 4;
-        src += 4;
-    }
+/* This used to be called "deloco" in FFmpeg
+ * and is actually an inverse reversible colorspace transformation */
+#define YUV2RGB(NAME, TYPE) \
+static void deloco_ ## NAME(TYPE *dst, int size, int alpha) \
+{ \
+    int i; \
+    for (i = 0; i < size; i += 3 + alpha) { \
+        int g = dst [i+1]; \
+        dst[i+0] += g; \
+        dst[i+2] += g; \
+    } \
 }
 
-static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width, int loco)
-{
-    if(loco)
-        convert_to_rgb32_loco(dst, src, width, 1);
-    else
-        convert_to_rgb32_loco(dst, src, width, 0);
-}
-
-static void deloco_rgb24(uint8_t *dst, int size)
-{
-    int i;
-    for(i=0; i<size; i+=3) {
-        int g = dst[i+1];
-        dst[i+0] += g;
-        dst[i+2] += g;
-    }
-}
+YUV2RGB(rgb8, uint8_t)
+YUV2RGB(rgb16, uint16_t)
 
 /* process exactly one decompressed row */
 static void png_handle_row(PNGDecContext *s)
@@ -287,14 +288,6 @@
 
     if (!s->interlace_type) {
         ptr = s->image_buf + s->image_linesize * s->y;
-        /* need to swap bytes correctly for RGB_ALPHA */
-        if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
-            png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
-                           s->last_row, s->row_size, s->bpp);
-            convert_to_rgb32(ptr, s->tmp_row, s->width, s->filter_type == PNG_FILTER_TYPE_LOCO);
-            FFSWAP(uint8_t*, s->last_row, s->tmp_row);
-        } else {
-            /* in normal case, we avoid one copy */
             if (s->y == 0)
                 last_row = s->last_row;
             else
@@ -302,17 +295,28 @@
 
             png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1,
                            last_row, s->row_size, s->bpp);
-        }
         /* loco lags by 1 row so that it doesn't interfere with top prediction */
-        if (s->filter_type == PNG_FILTER_TYPE_LOCO &&
-            s->color_type == PNG_COLOR_TYPE_RGB && s->y > 0)
-            deloco_rgb24(ptr - s->image_linesize, s->row_size);
+        if (s->filter_type == PNG_FILTER_TYPE_LOCO && s->y > 0) {
+            if (s->bit_depth == 16) {
+                deloco_rgb16((uint16_t *)(ptr - s->image_linesize), s->row_size / 2,
+                             s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
+            } else {
+                deloco_rgb8(ptr - s->image_linesize, s->row_size,
+                            s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
+            }
+        }
         s->y++;
         if (s->y == s->height) {
             s->state |= PNG_ALLIMAGE;
-            if (s->filter_type == PNG_FILTER_TYPE_LOCO &&
-                s->color_type == PNG_COLOR_TYPE_RGB)
-                deloco_rgb24(ptr, s->row_size);
+            if (s->filter_type == PNG_FILTER_TYPE_LOCO) {
+                if (s->bit_depth == 16) {
+                    deloco_rgb16((uint16_t *)ptr, s->row_size / 2,
+                                 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
+                } else {
+                    deloco_rgb8(ptr, s->row_size,
+                                s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
+                }
+            }
         }
     } else {
         got_line = 0;
@@ -329,12 +333,12 @@
                 got_line = 1;
             }
             if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) {
-                /* NOTE: RGB32 is handled directly in png_put_interlaced_row */
                 png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass,
                                        s->color_type, s->last_row);
             }
             s->y++;
             if (s->y == s->height) {
+                memset(s->last_row, 0, s->row_size);
                 for(;;) {
                     if (s->pass == NB_PASSES - 1) {
                         s->state |= PNG_ALLIMAGE;
@@ -361,13 +365,14 @@
 {
     int ret;
     s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb));
-    s->zstream.next_in = s->gb.buffer;
+    s->zstream.next_in = (unsigned char *)s->gb.buffer;
     bytestream2_skip(&s->gb, length);
 
     /* decode one line if possible */
     while (s->zstream.avail_in > 0) {
         ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
         if (ret != Z_OK && ret != Z_STREAM_END) {
+            av_log(s->avctx, AV_LOG_ERROR, "inflate returned %d\n", ret);
             return -1;
         }
         if (s->zstream.avail_out == 0) {
@@ -392,19 +397,23 @@
     AVFrame *p;
     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;
     p = s->current_picture;
 
-    /* check signature */
-    if (buf_size < 8 ||
-        memcmp(buf, ff_pngsig, 8) != 0 &&
-        memcmp(buf, ff_mngsig, 8) != 0)
-        return -1;
+    bytestream2_init(&s->gb, buf, buf_size);
 
-    bytestream2_init(&s->gb, buf + 8, buf_size - 8);
+    /* check signature */
+    sig = bytestream2_get_be64(&s->gb);
+    if (sig != PNGSIG &&
+        sig != MNGSIG) {
+        av_log(avctx, AV_LOG_ERROR, "Missing png signature\n");
+        return -1;
+    }
+
     s->y=
     s->state=0;
 //    memset(s, 0, sizeof(PNGDecContext));
@@ -413,16 +422,24 @@
     s->zstream.zfree = ff_png_zfree;
     s->zstream.opaque = NULL;
     ret = inflateInit(&s->zstream);
-    if (ret != Z_OK)
+    if (ret != Z_OK) {
+        av_log(avctx, AV_LOG_ERROR, "inflateInit returned %d\n", ret);
         return -1;
+    }
     for(;;) {
-        if (bytestream2_get_bytes_left(&s->gb) <= 0)
+        if (bytestream2_get_bytes_left(&s->gb) <= 0) {
+            av_log(avctx, AV_LOG_ERROR, "No bytes left\n");
             goto fail;
+        }
+
         length = bytestream2_get_be32(&s->gb);
-        if (length > 0x7fffffff)
+        if (length > 0x7fffffff || length > bytestream2_get_bytes_left(&s->gb))  {
+            av_log(avctx, AV_LOG_ERROR, "chunk too big\n");
             goto fail;
+        }
         tag = bytestream2_get_le32(&s->gb);
-        av_dlog(avctx, "png: tag=%c%c%c%c length=%u\n",
+        if (avctx->debug & FF_DEBUG_STARTCODE)
+            av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n",
                 (tag & 0xff),
                 ((tag >> 8) & 0xff),
                 ((tag >> 16) & 0xff),
@@ -435,6 +452,7 @@
             s->height = bytestream2_get_be32(&s->gb);
             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;
             }
             s->bit_depth        = bytestream2_get_byte(&s->gb);
@@ -444,13 +462,16 @@
             s->interlace_type   = bytestream2_get_byte(&s->gb);
             bytestream2_skip(&s->gb, 4); /* crc */
             s->state |= PNG_IHDR;
-            av_dlog(avctx, "width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n",
+            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",
                     s->width, s->height, s->bit_depth, s->color_type,
                     s->compression_type, s->filter_type, s->interlace_type);
             break;
         case MKTAG('I', 'D', 'A', 'T'):
-            if (!(s->state & PNG_IHDR))
+            if (!(s->state & PNG_IHDR)) {
+                av_log(avctx, AV_LOG_ERROR, "IDAT without IHDR\n");
                 goto fail;
+            }
             if (!(s->state & PNG_IDAT)) {
                 /* init image info */
                 avctx->width = s->width;
@@ -461,13 +482,13 @@
                 s->bpp = (s->bits_per_pixel + 7) >> 3;
                 s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3;
 
-                if (s->bit_depth == 8 &&
+                if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
                     s->color_type == PNG_COLOR_TYPE_RGB) {
                     avctx->pix_fmt = AV_PIX_FMT_RGB24;
-                } else if (s->bit_depth == 8 &&
+                } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
                            s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
-                    avctx->pix_fmt = AV_PIX_FMT_RGB32;
-                } else if (s->bit_depth == 8 &&
+                    avctx->pix_fmt = AV_PIX_FMT_RGBA;
+                } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
                            s->color_type == PNG_COLOR_TYPE_GRAY) {
                     avctx->pix_fmt = AV_PIX_FMT_GRAY8;
                 } else if (s->bit_depth == 16 &&
@@ -476,22 +497,27 @@
                 } else if (s->bit_depth == 16 &&
                            s->color_type == PNG_COLOR_TYPE_RGB) {
                     avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
-                } else if (s->bit_depth == 1 &&
-                           s->color_type == PNG_COLOR_TYPE_GRAY) {
-                    avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
-                } else if (s->bit_depth == 8 &&
+                } else if (s->bit_depth == 16 &&
+                           s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
+                    avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
+                } else if ((s->bits_per_pixel == 1 || s->bits_per_pixel == 2 || s->bits_per_pixel == 4 || s->bits_per_pixel == 8) &&
                            s->color_type == PNG_COLOR_TYPE_PALETTE) {
                     avctx->pix_fmt = AV_PIX_FMT_PAL8;
+                } else if (s->bit_depth == 1) {
+                    avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
                 } else if (s->bit_depth == 8 &&
                            s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
                     avctx->pix_fmt = AV_PIX_FMT_Y400A;
                 } else {
+                    av_log(avctx, AV_LOG_ERROR, "unsupported bit depth %d "
+                                                "and color type %d\n",
+                                                 s->bit_depth, s->color_type);
                     goto fail;
                 }
                 if(p->data[0])
                     avctx->release_buffer(avctx, p);
 
-                p->reference= 0;
+                p->reference= 3;
                 if(avctx->get_buffer(avctx, p) < 0){
                     av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                     goto fail;
@@ -515,7 +541,7 @@
                 s->image_buf = p->data[0];
                 s->image_linesize = p->linesize[0];
                 /* copy the palette if needed */
-                if (s->color_type == PNG_COLOR_TYPE_PALETTE)
+                if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
                     memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t));
                 /* empty row is used if differencing to the first row */
                 s->last_row = av_mallocz(s->row_size);
@@ -581,7 +607,10 @@
             break;
         case MKTAG('I', 'E', 'N', 'D'):
             if (!(s->state & PNG_ALLIMAGE))
+                av_log(avctx, AV_LOG_ERROR, "IEND without all image\n");
+            if (!(s->state & (PNG_ALLIMAGE|PNG_IDAT))) {
                 goto fail;
+            }
             bytestream2_skip(&s->gb, 4); /* crc */
             goto exit_loop;
         default:
@@ -592,9 +621,71 @@
         }
     }
  exit_loop:
+
+    if(s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE){
+        int i, j;
+        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;
+            }
+            pd += s->image_linesize;
+        }
+    }
+    if(s->bits_per_pixel == 2){
+        int i, j;
+        uint8_t *pd = s->current_picture->data[0];
+        for(j=0; j < s->height; j++) {
+            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;
+            }
+            } 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;
+                }
+            }
+            pd += s->image_linesize;
+        }
+    }
+    if(s->bits_per_pixel == 4){
+        int i, j;
+        uint8_t *pd = s->current_picture->data[0];
+        for(j=0; j < s->height; j++) {
+            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;
+            }
+            } 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;
+                }
+            }
+            pd += s->image_linesize;
+        }
+    }
+
      /* 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(   !(avpkt->flags & AV_PKT_FLAG_KEY)
+            && s->last_picture->width == s->current_picture->width
+            && s->last_picture->height== s->current_picture->height
+         ) {
             int i, j;
             uint8_t *pd = s->current_picture->data[0];
             uint8_t *pd_last = s->last_picture->data[0];
@@ -625,15 +716,19 @@
     goto the_end;
 }
 
-static av_cold int png_dec_init(AVCodecContext *avctx){
+static av_cold int png_dec_init(AVCodecContext *avctx)
+{
     PNGDecContext *s = avctx->priv_data;
 
     s->current_picture = &s->picture1;
     s->last_picture = &s->picture2;
     avcodec_get_frame_defaults(&s->picture1);
     avcodec_get_frame_defaults(&s->picture2);
+
     ff_pngdsp_init(&s->dsp);
 
+    s->avctx = avctx;
+
     return 0;
 }
 
diff --git a/libavcodec/pngdsp.c b/libavcodec/pngdsp.c
index 00734d7..1ee8b57 100644
--- a/libavcodec/pngdsp.c
+++ b/libavcodec/pngdsp.c
@@ -2,20 +2,20 @@
  * PNG image format
  * Copyright (c) 2008 Loren Merrit <lorenm@u.washington.edu>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/pngdsp.h b/libavcodec/pngdsp.h
index 98d29a8..1475b0c 100644
--- a/libavcodec/pngdsp.h
+++ b/libavcodec/pngdsp.h
@@ -2,20 +2,20 @@
  * PNG image format
  * Copyright (c) 2008 Loren Merrit <lorenm@u.washington.edu>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c
index 00a800c..87d18d4 100644
--- a/libavcodec/pngenc.c
+++ b/libavcodec/pngenc.c
@@ -2,27 +2,30 @@
  * PNG image format
  * Copyright (c) 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avcodec.h"
+#include "internal.h"
 #include "bytestream.h"
 #include "dsputil.h"
 #include "png.h"
 
+#include "libavutil/avassert.h"
+
 /* TODO:
  * - add 2, 4 and 16 bit depth support
  */
@@ -55,7 +58,7 @@
     uint8_t *d;
     const uint8_t *s;
 
-    mask = ff_png_pass_mask[pass];
+    mask =  (int[]){0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}[pass];
     switch(bits_per_pixel) {
     case 1:
         memset(dst, 0, row_size);
@@ -146,7 +149,7 @@
                                   uint8_t *src, uint8_t *top, int size, int bpp)
 {
     int pred = s->filter_type;
-    assert(bpp || !pred);
+    av_assert0(bpp || !pred);
     if(!top && pred)
         pred = PNG_FILTER_VALUE_SUB;
     if(pred == PNG_FILTER_VALUE_MIXED) {
@@ -172,23 +175,6 @@
     }
 }
 
-static void convert_from_rgb32(uint8_t *dst, const uint8_t *src, int width)
-{
-    uint8_t *d;
-    int j;
-    unsigned int v;
-
-    d = dst;
-    for(j = 0; j < width; j++) {
-        v = ((const uint32_t *)src)[j];
-        d[0] = v >> 16;
-        d[1] = v >> 8;
-        d[2] = v;
-        d[3] = v >> 24;
-        d += 4;
-    }
-}
-
 static void png_write_chunk(uint8_t **f, uint32_t tag,
                             const uint8_t *buf, int length)
 {
@@ -235,12 +221,12 @@
     PNGEncContext *s = avctx->priv_data;
     AVFrame * const p= &s->picture;
     int bit_depth, color_type, y, len, row_size, ret, is_progressive;
-    int bits_per_pixel, pass_row_size, enc_row_size, max_packet_size;
+    int bits_per_pixel, pass_row_size, enc_row_size;
+    int64_t max_packet_size;
     int compression_level;
     uint8_t *ptr, *top;
     uint8_t *crow_base = NULL, *crow_buf, *crow;
     uint8_t *progressive_buf = NULL;
-    uint8_t *rgba_buf = NULL;
     uint8_t *top_buf = NULL;
 
     *p = *pict;
@@ -249,23 +235,44 @@
 
     is_progressive = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT);
     switch(avctx->pix_fmt) {
-    case AV_PIX_FMT_RGB32:
+    case AV_PIX_FMT_RGBA64BE:
+        bit_depth = 16;
+        color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+        break;
+    case AV_PIX_FMT_RGB48BE:
+        bit_depth = 16;
+        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;
+    case AV_PIX_FMT_GRAY16BE:
+        bit_depth = 16;
+        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;
+    case AV_PIX_FMT_GRAY8A:
+        bit_depth = 8;
+        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;
@@ -287,15 +294,13 @@
         return -1;
 
     enc_row_size    = deflateBound(&s->zstream, row_size);
-    max_packet_size = avctx->height * (enc_row_size +
+    max_packet_size = avctx->height * (int64_t)(enc_row_size +
                                        ((enc_row_size + IOBUF_SIZE - 1) / IOBUF_SIZE) * 12)
                       + FF_MIN_BUFFER_SIZE;
-    if (!pkt->data &&
-        (ret = av_new_packet(pkt, max_packet_size)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Could not allocate output packet of size %d.\n",
-               max_packet_size);
+    if (max_packet_size > INT_MAX)
+        return AVERROR(ENOMEM);
+    if ((ret = ff_alloc_packet2(avctx, pkt, max_packet_size)) < 0)
         return ret;
-    }
 
     s->bytestream_start =
     s->bytestream       = pkt->data;
@@ -310,19 +315,14 @@
         if (!progressive_buf)
             goto fail;
     }
-    if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
-        rgba_buf = av_malloc(row_size + 1);
-        if (!rgba_buf)
-            goto fail;
-    }
-    if (is_progressive || color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
+    if (is_progressive) {
         top_buf = av_malloc(row_size + 1);
         if (!top_buf)
             goto fail;
     }
 
     /* write png header */
-    memcpy(s->bytestream, ff_pngsig, 8);
+    AV_WB64(s->bytestream, PNGSIG);
     s->bytestream += 8;
 
     AV_WB32(s->buf, avctx->width);
@@ -349,7 +349,7 @@
         for(i = 0; i < 256; i++) {
             v = palette[i];
             alpha = v >> 24;
-            if (alpha && alpha != 0xff)
+            if (alpha != 0xff)
                 has_alpha = 1;
             *alpha_ptr++ = alpha;
             bytestream_put_be24(&ptr, v);
@@ -376,10 +376,6 @@
                     if ((ff_png_pass_ymask[pass] << (y & 7)) & 0x80) {
                         ptr = p->data[0] + y * p->linesize[0];
                         FFSWAP(uint8_t*, progressive_buf, top_buf);
-                        if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
-                            convert_from_rgb32(rgba_buf, ptr, avctx->width);
-                            ptr = rgba_buf;
-                        }
                         png_get_interlaced_row(progressive_buf, pass_row_size,
                                                bits_per_pixel, pass,
                                                ptr, avctx->width);
@@ -394,11 +390,6 @@
         top = NULL;
         for(y = 0; y < avctx->height; y++) {
             ptr = p->data[0] + y * p->linesize[0];
-            if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
-                FFSWAP(uint8_t*, rgba_buf, top_buf);
-                convert_from_rgb32(rgba_buf, ptr, avctx->width);
-                ptr = rgba_buf;
-            }
             crow = png_choose_filter(s, crow_buf, ptr, top, row_size, bits_per_pixel>>3);
             png_write_row(s, crow, row_size + 1);
             top = ptr;
@@ -430,7 +421,6 @@
  the_end:
     av_free(crow_base);
     av_free(progressive_buf);
-    av_free(rgba_buf);
     av_free(top_buf);
     deflateEnd(&s->zstream);
     return ret;
@@ -460,8 +450,13 @@
     .priv_data_size = sizeof(PNGEncContext),
     .init           = png_enc_init,
     .encode2        = encode_frame,
+    .capabilities   = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
     .pix_fmts       = (const enum AVPixelFormat[]){
-        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB32, AV_PIX_FMT_PAL8, AV_PIX_FMT_GRAY8,
+        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA,
+        AV_PIX_FMT_RGB48BE, AV_PIX_FMT_RGBA64BE,
+        AV_PIX_FMT_PAL8,
+        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A,
+        AV_PIX_FMT_GRAY16BE,
         AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_NONE
     },
     .long_name      = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"),
diff --git a/libavcodec/pnm.c b/libavcodec/pnm.c
index 2a89a72..c5c600b 100644
--- a/libavcodec/pnm.c
+++ b/libavcodec/pnm.c
@@ -2,20 +2,20 @@
  * PNM image format
  * Copyright (c) 2002, 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -37,12 +37,12 @@
     int c;
 
     /* skip spaces and comments */
-    for (;;) {
+    while (sc->bytestream < sc->bytestream_end) {
         c = *sc->bytestream++;
         if (c == '#')  {
-            do {
+            while (c != '\n' && sc->bytestream < sc->bytestream_end) {
                 c = *sc->bytestream++;
-            } while (c != '\n' && sc->bytestream < sc->bytestream_end);
+            }
         } else if (!pnm_space(c)) {
             break;
         }
@@ -107,26 +107,35 @@
             }
         }
         /* 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))
+        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;
 
         avctx->width  = w;
         avctx->height = h;
+        s->maxval     = maxval;
         if (depth == 1) {
-            if (maxval == 1)
-                avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
-            else
+            if (maxval == 1) {
+                avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
+            } else if (maxval == 255) {
                 avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+            } else {
+                avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
+            }
+        } else if (depth == 2) {
+            if (maxval == 255)
+                avctx->pix_fmt = AV_PIX_FMT_GRAY8A;
         } else if (depth == 3) {
             if (maxval < 256) {
             avctx->pix_fmt = AV_PIX_FMT_RGB24;
             } else {
-                av_log(avctx, AV_LOG_ERROR, "16-bit components are only supported for grayscale\n");
-                avctx->pix_fmt = AV_PIX_FMT_NONE;
-                return -1;
+                avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
             }
         } else if (depth == 4) {
-            avctx->pix_fmt = AV_PIX_FMT_RGB32;
+            if (maxval < 256) {
+                avctx->pix_fmt = AV_PIX_FMT_RGBA;
+            } else {
+                avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
+            }
         } else {
             return -1;
         }
@@ -135,14 +144,16 @@
         return -1;
     }
     pnm_get(s, buf1, sizeof(buf1));
-    avctx->width = atoi(buf1);
-    if (avctx->width <= 0)
-        return -1;
+    w = atoi(buf1);
     pnm_get(s, buf1, sizeof(buf1));
-    avctx->height = atoi(buf1);
-    if(av_image_check_size(avctx->width, avctx->height, 0, avctx))
+    h = atoi(buf1);
+    if(w <= 0 || h <= 0 || av_image_check_size(w, h, 0, avctx) || s->bytestream >= s->bytestream_end)
         return -1;
-    if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE) {
+
+    avctx->width  = w;
+    avctx->height = h;
+
+    if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE && avctx->pix_fmt != AV_PIX_FMT_MONOBLACK) {
         pnm_get(s, buf1, sizeof(buf1));
         s->maxval = atoi(buf1);
         if (s->maxval <= 0) {
diff --git a/libavcodec/pnm.h b/libavcodec/pnm.h
index 702921f..ac4b108 100644
--- a/libavcodec/pnm.h
+++ b/libavcodec/pnm.h
@@ -2,20 +2,20 @@
  * PNM image format
  * Copyright (c) 2002, 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/pnm_parser.c b/libavcodec/pnm_parser.c
index 2e00c0a..2a9e3e1 100644
--- a/libavcodec/pnm_parser.c
+++ b/libavcodec/pnm_parser.c
@@ -2,20 +2,20 @@
  * PNM image parser
  * Copyright (c) 2002, 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c
index 6fdd3f9..29efaca 100644
--- a/libavcodec/pnmdec.c
+++ b/libavcodec/pnmdec.c
@@ -2,25 +2,24 @@
  * PNM image format
  * Copyright (c) 2002, 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "avcodec.h"
-#include "bytestream.h"
 #include "put_bits.h"
 #include "pnm.h"
 
@@ -33,13 +32,13 @@
     PNMContext * const s = avctx->priv_data;
     AVFrame *picture     = data;
     AVFrame * const p    = &s->picture;
-    int i, j, n, linesize, h, upgrade = 0;
+    int i, j, n, linesize, h, upgrade = 0, is_mono = 0;
     unsigned char *ptr;
     int components, sample_len;
 
     s->bytestream_start =
-    s->bytestream       = buf;
-    s->bytestream_end   = buf + buf_size;
+    s->bytestream       = (uint8_t *)buf;
+    s->bytestream_end   = (uint8_t *)buf + buf_size;
 
     if (ff_pnm_decode_header(avctx, s) < 0)
         return -1;
@@ -58,11 +57,21 @@
     switch (avctx->pix_fmt) {
     default:
         return -1;
+    case AV_PIX_FMT_RGBA64BE:
+        n = avctx->width * 8;
+        components=4;
+        sample_len=16;
+        goto do_read;
     case AV_PIX_FMT_RGB48BE:
         n = avctx->width * 6;
         components=3;
         sample_len=16;
         goto do_read;
+    case AV_PIX_FMT_RGBA:
+        n = avctx->width * 4;
+        components=4;
+        sample_len=8;
+        goto do_read;
     case AV_PIX_FMT_RGB24:
         n = avctx->width * 3;
         components=3;
@@ -75,6 +84,11 @@
         if (s->maxval < 255)
             upgrade = 1;
         goto do_read;
+    case AV_PIX_FMT_GRAY8A:
+        n = avctx->width * 2;
+        components=2;
+        sample_len=8;
+        goto do_read;
     case AV_PIX_FMT_GRAY16BE:
     case AV_PIX_FMT_GRAY16LE:
         n = avctx->width * 2;
@@ -88,26 +102,34 @@
         n = (avctx->width + 7) >> 3;
         components=1;
         sample_len=1;
+        is_mono = 1;
     do_read:
         ptr      = p->data[0];
         linesize = p->linesize[0];
         if (s->bytestream + n * avctx->height > s->bytestream_end)
             return -1;
-        if(s->type < 4){
+        if(s->type < 4 || (is_mono && s->type==7)){
             for (i=0; i<avctx->height; i++) {
                 PutBitContext pb;
                 init_put_bits(&pb, ptr, linesize);
                 for(j=0; j<avctx->width * components; j++){
                     unsigned int c=0;
                     int v=0;
+                    if(s->type < 4)
                     while(s->bytestream < s->bytestream_end && (*s->bytestream < '0' || *s->bytestream > '9' ))
                         s->bytestream++;
                     if(s->bytestream >= s->bytestream_end)
                         return -1;
-                    do{
-                        v= 10*v + c;
-                        c= (*s->bytestream++) - '0';
-                    }while(c <= 9);
+                    if (is_mono) {
+                        /* read a single digit */
+                        v = (*s->bytestream++)&1;
+                    } else {
+                        /* read a sequence of digits */
+                        do {
+                            v = 10*v + c;
+                            c = (*s->bytestream++) - '0';
+                        } while (c <= 9);
+                    }
                     put_bits(&pb, sample_len, (((1<<sample_len)-1)*v + (s->maxval>>1))/s->maxval);
                 }
                 flush_put_bits(&pb);
@@ -161,24 +183,6 @@
             }
         }
         break;
-    case AV_PIX_FMT_RGB32:
-        ptr      = p->data[0];
-        linesize = p->linesize[0];
-        if (s->bytestream + avctx->width * avctx->height * 4 > s->bytestream_end)
-            return -1;
-        for (i = 0; i < avctx->height; i++) {
-            int j, r, g, b, a;
-
-            for (j = 0; j < avctx->width; j++) {
-                r = *s->bytestream++;
-                g = *s->bytestream++;
-                b = *s->bytestream++;
-                a = *s->bytestream++;
-                ((uint32_t *)ptr)[j] = (a << 24) | (r << 16) | (g << 8) | b;
-            }
-            ptr += linesize;
-        }
-        break;
     }
     *picture   = s->picture;
     *data_size = sizeof(AVPicture);
diff --git a/libavcodec/pnmenc.c b/libavcodec/pnmenc.c
index 2863db7..e311b2e 100644
--- a/libavcodec/pnmenc.c
+++ b/libavcodec/pnmenc.c
@@ -2,25 +2,24 @@
  * PNM image format
  * Copyright (c) 2002, 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "avcodec.h"
-#include "bytestream.h"
 #include "internal.h"
 #include "pnm.h"
 
@@ -33,12 +32,10 @@
     int i, h, h1, c, n, linesize, ret;
     uint8_t *ptr, *ptr1, *ptr2;
 
-    if ((ret = ff_alloc_packet(pkt, avpicture_get_size(avctx->pix_fmt,
+    if ((ret = ff_alloc_packet2(avctx, pkt, avpicture_get_size(avctx->pix_fmt,
                                                        avctx->width,
-                                                       avctx->height) + 200)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
+                                                       avctx->height) + 200)) < 0)
         return ret;
-    }
 
     *p           = *pict;
     p->pict_type = AV_PICTURE_TYPE_I;
@@ -72,6 +69,10 @@
         n  = avctx->width * 6;
         break;
     case AV_PIX_FMT_YUV420P:
+        if (avctx->width & 1) {
+            av_log(avctx, AV_LOG_ERROR, "pgmyuv needs even width\n");
+            return AVERROR(EINVAL);
+        }
         c  = '5';
         n  = avctx->width;
         h1 = (h * 3) / 2;
diff --git a/libavcodec/ppc/asm.S b/libavcodec/ppc/asm.S
index 4d4285b..bbbf8a4 100644
--- a/libavcodec/ppc/asm.S
+++ b/libavcodec/ppc/asm.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Loren Merritt
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ppc/dsputil_altivec.c b/libavcodec/ppc/dsputil_altivec.c
index 9ad73ef..5619c3f 100644
--- a/libavcodec/ppc/dsputil_altivec.c
+++ b/libavcodec/ppc/dsputil_altivec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2002 Dieter Shirley
  * Copyright (c) 2003-2004 Romain Dolbeau <romain@dolbeau.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -476,7 +476,7 @@
     return s;
 }
 
-static void get_pixels_altivec(DCTELEM *restrict block, const uint8_t *pixels, int line_size)
+static void get_pixels_altivec(DCTELEM *av_restrict block, const uint8_t *pixels, int line_size)
 {
     int i;
     vector unsigned char perm = vec_lvsl(0, pixels);
@@ -502,7 +502,7 @@
     }
 }
 
-static void diff_pixels_altivec(DCTELEM *restrict block, const uint8_t *s1,
+static void diff_pixels_altivec(DCTELEM *av_restrict block, const uint8_t *s1,
         const uint8_t *s2, int stride)
 {
     int i;
diff --git a/libavcodec/ppc/dsputil_altivec.h b/libavcodec/ppc/dsputil_altivec.h
index 7cbda36..0b5e404 100644
--- a/libavcodec/ppc/dsputil_altivec.h
+++ b/libavcodec/ppc/dsputil_altivec.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2002 Dieter Shirley
  * Copyright (c) 2003-2004 Romain Dolbeau <romain@dolbeau.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ppc/dsputil_ppc.c b/libavcodec/ppc/dsputil_ppc.c
index 6b894e0..f827a2a 100644
--- a/libavcodec/ppc/dsputil_ppc.c
+++ b/libavcodec/ppc/dsputil_ppc.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2002 Dieter Shirley
  * Copyright (c) 2003-2004 Romain Dolbeau <romain@dolbeau.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -149,6 +149,14 @@
 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();
+
+    if (avctx->dsp_mask) {
+        if (avctx->dsp_mask & AV_CPU_FLAG_FORCE)
+            mm_flags |= (avctx->dsp_mask & 0xffff);
+        else
+            mm_flags &= ~(avctx->dsp_mask & 0xffff);
+    }
 
     // Common optimizations whether AltiVec is available or not
     c->prefetch = prefetch_ppc;
@@ -168,7 +176,7 @@
 #if HAVE_ALTIVEC
     if(CONFIG_H264_DECODER) ff_dsputil_h264_init_ppc(c, avctx);
 
-    if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) {
+    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);
@@ -182,7 +190,7 @@
         }
 #endif //CONFIG_ENCODERS
 
-        if (avctx->bits_per_raw_sample <= 8) {
+        if (avctx->lowres == 0 && avctx->bits_per_raw_sample <= 8) {
             if ((avctx->idct_algo == FF_IDCT_AUTO) ||
                 (avctx->idct_algo == FF_IDCT_ALTIVEC)) {
                 c->idct_put = ff_idct_put_altivec;
diff --git a/libavcodec/ppc/fdct_altivec.c b/libavcodec/ppc/fdct_altivec.c
index 0e3658d..608dac4 100644
--- a/libavcodec/ppc/fdct_altivec.c
+++ b/libavcodec/ppc/fdct_altivec.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2003  James Klicman <james@klicman.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ppc/fft_altivec.c b/libavcodec/ppc/fft_altivec.c
index c85d04f..651ee26 100644
--- a/libavcodec/ppc/fft_altivec.c
+++ b/libavcodec/ppc/fft_altivec.c
@@ -3,20 +3,20 @@
  * AltiVec-enabled
  * Copyright (c) 2009 Loren Merritt
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ppc/fft_altivec_s.S b/libavcodec/ppc/fft_altivec_s.S
index 958d7df..16ce838 100644
--- a/libavcodec/ppc/fft_altivec_s.S
+++ b/libavcodec/ppc/fft_altivec_s.S
@@ -5,20 +5,20 @@
  * This algorithm (though not any of the implementation details) is
  * based on libdjbfft by D. J. Bernstein.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ppc/float_altivec.c b/libavcodec/ppc/float_altivec.c
index 5068fd4..e7b04ec 100644
--- a/libavcodec/ppc/float_altivec.c
+++ b/libavcodec/ppc/float_altivec.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2006 Luca Barbato <lu_zero@gentoo.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ppc/fmtconvert_altivec.c b/libavcodec/ppc/fmtconvert_altivec.c
index 68e5e00..d40ce07 100644
--- a/libavcodec/ppc/fmtconvert_altivec.c
+++ b/libavcodec/ppc/fmtconvert_altivec.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2006 Luca Barbato <lu_zero@gentoo.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -92,7 +92,7 @@
 static void float_to_int16_stride_altivec(int16_t *dst, const float *src,
                                           long len, int stride)
 {
-    int i, j;
+    int i;
     vector signed short d, s;
 
     for (i = 0; i < len - 7; i += 8) {
diff --git a/libavcodec/ppc/gmc_altivec.c b/libavcodec/ppc/gmc_altivec.c
index f86964b..4e36121 100644
--- a/libavcodec/ppc/gmc_altivec.c
+++ b/libavcodec/ppc/gmc_altivec.c
@@ -3,20 +3,20 @@
  * AltiVec-enabled
  * Copyright (c) 2003 Romain Dolbeau <romain@dolbeau.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ppc/h264_altivec.c b/libavcodec/ppc/h264_altivec.c
index 05a5c51..7c89b85 100644
--- a/libavcodec/ppc/h264_altivec.c
+++ b/libavcodec/ppc/h264_altivec.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2004 Romain Dolbeau <romain@dolbeau.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ppc/h264_altivec_template.c b/libavcodec/ppc/h264_altivec_template.c
index 0964bbe..6121ea1 100644
--- a/libavcodec/ppc/h264_altivec_template.c
+++ b/libavcodec/ppc/h264_altivec_template.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2004 Romain Dolbeau <romain@dolbeau.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ppc/idct_altivec.c b/libavcodec/ppc/idct_altivec.c
index e599491..9a8b917 100644
--- a/libavcodec/ppc/idct_altivec.c
+++ b/libavcodec/ppc/idct_altivec.c
@@ -1,31 +1,31 @@
 /*
  * Copyright (c) 2001 Michel Lespinasse
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /*
  * NOTE: This code is based on GPL code from the libmpeg2 project.  The
  * author, Michel Lespinasses, has given explicit permission to release
- * under LGPL as part of Libav.
+ * under LGPL as part of FFmpeg.
  */
 
 /*
- * Libav integration by Dieter Shirley
+ * FFmpeg integration by Dieter Shirley
  *
  * This file is a direct copy of the AltiVec IDCT module from the libmpeg2
  * project.  I've deleted all of the libmpeg2-specific code, renamed the
diff --git a/libavcodec/ppc/int_altivec.c b/libavcodec/ppc/int_altivec.c
index 4fcdf77..5a73876 100644
--- a/libavcodec/ppc/int_altivec.c
+++ b/libavcodec/ppc/int_altivec.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2007 Luca Barbato <lu_zero@gentoo.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ppc/mathops.h b/libavcodec/ppc/mathops.h
index 34ddb11..dbd714f 100644
--- a/libavcodec/ppc/mathops.h
+++ b/libavcodec/ppc/mathops.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2001, 2002 Fabrice Bellard
  * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ppc/mpegaudiodec_altivec.c b/libavcodec/ppc/mpegaudiodec_altivec.c
index fabde6a..7d829b8 100644
--- a/libavcodec/ppc/mpegaudiodec_altivec.c
+++ b/libavcodec/ppc/mpegaudiodec_altivec.c
@@ -2,20 +2,20 @@
  * Altivec optimized MP3 decoding functions
  * Copyright (c) 2010 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ppc/mpegvideo_altivec.c b/libavcodec/ppc/mpegvideo_altivec.c
index df111e9..bbc102b 100644
--- a/libavcodec/ppc/mpegvideo_altivec.c
+++ b/libavcodec/ppc/mpegvideo_altivec.c
@@ -4,20 +4,20 @@
  * dct_unquantize_h263_altivec:
  * Copyright (c) 2003 Romain Dolbeau <romain@dolbeau.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ppc/vc1dsp_altivec.c b/libavcodec/ppc/vc1dsp_altivec.c
index 6c110db..33e87af 100644
--- a/libavcodec/ppc/vc1dsp_altivec.c
+++ b/libavcodec/ppc/vc1dsp_altivec.c
@@ -2,20 +2,20 @@
  * VC-1 and WMV3 decoder - DSP functions AltiVec-optimized
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ppc/vp3dsp_altivec.c b/libavcodec/ppc/vp3dsp_altivec.c
index 75a3677..ac00c93 100644
--- a/libavcodec/ppc/vp3dsp_altivec.c
+++ b/libavcodec/ppc/vp3dsp_altivec.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2009 David Conrad
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ppc/vp8dsp_altivec.c b/libavcodec/ppc/vp8dsp_altivec.c
index 4336453..14d8784 100644
--- a/libavcodec/ppc/vp8dsp_altivec.c
+++ b/libavcodec/ppc/vp8dsp_altivec.c
@@ -3,20 +3,20 @@
  *
  * Copyright (C) 2010 David Conrad
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/proresdata.h b/libavcodec/proresdata.h
index 1e5d05e..ee8278d 100644
--- a/libavcodec/proresdata.h
+++ b/libavcodec/proresdata.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010-2011 Maxim Poliakovski
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/proresdec.c b/libavcodec/proresdec.c
deleted file mode 100644
index 47a5820..0000000
--- a/libavcodec/proresdec.c
+++ /dev/null
@@ -1,673 +0,0 @@
-/*
- * Apple ProRes compatible decoder
- *
- * Copyright (c) 2010-2011 Maxim Poliakovski
- *
- * 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
- * This is a decoder for Apple ProRes 422 SD/HQ/LT/Proxy and ProRes 4444.
- * It is used for storing and editing high definition video data in Apple's Final Cut Pro.
- *
- * @see http://wiki.multimedia.cx/index.php?title=Apple_ProRes
- */
-
-#define LONG_BITSTREAM_READER // some ProRes vlc codes require up to 28 bits to be read at once
-
-#include <stdint.h>
-
-#include "libavutil/intmath.h"
-#include "avcodec.h"
-#include "proresdata.h"
-#include "proresdsp.h"
-#include "get_bits.h"
-
-typedef struct {
-    const uint8_t *index;            ///< pointers to the data of this slice
-    int slice_num;
-    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, qmat_luma_scaled)[64];
-    DECLARE_ALIGNED(16, int16_t, qmat_chroma_scaled)[64];
-} ProresThreadData;
-
-typedef struct {
-    ProresDSPContext dsp;
-    AVFrame    picture;
-    ScanTable  scantable;
-    int        scantable_type;           ///< -1 = uninitialized, 0 = progressive, 1/2 = interlaced
-
-    int        frame_type;               ///< 0 = progressive, 1 = top-field first, 2 = bottom-field first
-    int        pic_format;               ///< 2 = 422, 3 = 444
-    uint8_t    qmat_luma[64];            ///< dequantization matrix for luma
-    uint8_t    qmat_chroma[64];          ///< dequantization matrix for chroma
-    int        qmat_changed;             ///< 1 - global quantization matrices changed
-    int        total_slices;            ///< total number of slices in a picture
-    ProresThreadData *slice_data;
-    int        pic_num;
-    int        chroma_factor;
-    int        mb_chroma_factor;
-    int        num_chroma_blocks;       ///< number of chrominance blocks in a macroblock
-    int        num_x_slices;
-    int        num_y_slices;
-    int        slice_width_factor;
-    int        slice_height_factor;
-    int        num_x_mbs;
-    int        num_y_mbs;
-    int        alpha_info;
-} ProresContext;
-
-
-static av_cold int decode_init(AVCodecContext *avctx)
-{
-    ProresContext *ctx = avctx->priv_data;
-
-    ctx->total_slices     = 0;
-    ctx->slice_data       = NULL;
-
-    avctx->bits_per_raw_sample = PRORES_BITS_PER_SAMPLE;
-    ff_proresdsp_init(&ctx->dsp);
-
-    avctx->coded_frame = &ctx->picture;
-    avcodec_get_frame_defaults(&ctx->picture);
-    ctx->picture.type      = AV_PICTURE_TYPE_I;
-    ctx->picture.key_frame = 1;
-
-    ctx->scantable_type = -1;   // set scantable type to uninitialized
-    memset(ctx->qmat_luma, 4, 64);
-    memset(ctx->qmat_chroma, 4, 64);
-
-    return 0;
-}
-
-
-static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
-                               const int data_size, AVCodecContext *avctx)
-{
-    int hdr_size, version, width, height, flags;
-    const uint8_t *ptr;
-
-    hdr_size = AV_RB16(buf);
-    if (hdr_size > data_size) {
-        av_log(avctx, AV_LOG_ERROR, "frame data too small\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    version = AV_RB16(buf + 2);
-    if (version >= 2) {
-        av_log(avctx, AV_LOG_ERROR,
-               "unsupported header version: %d\n", version);
-        return AVERROR_INVALIDDATA;
-    }
-
-    width  = AV_RB16(buf + 8);
-    height = AV_RB16(buf + 10);
-    if (width != avctx->width || height != avctx->height) {
-        av_log(avctx, AV_LOG_ERROR,
-               "picture dimension changed: old: %d x %d, new: %d x %d\n",
-               avctx->width, avctx->height, width, height);
-        return AVERROR_INVALIDDATA;
-    }
-
-    ctx->frame_type = (buf[12] >> 2) & 3;
-    if (ctx->frame_type > 2) {
-        av_log(avctx, AV_LOG_ERROR,
-               "unsupported frame type: %d\n", ctx->frame_type);
-        return AVERROR_INVALIDDATA;
-    }
-
-    ctx->chroma_factor     = (buf[12] >> 6) & 3;
-    ctx->mb_chroma_factor  = ctx->chroma_factor + 2;
-    ctx->num_chroma_blocks = (1 << ctx->chroma_factor) >> 1;
-    switch (ctx->chroma_factor) {
-    case 2:
-        avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
-        break;
-    case 3:
-        avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
-        break;
-    default:
-        av_log(avctx, AV_LOG_ERROR,
-               "unsupported picture format: %d\n", ctx->pic_format);
-        return AVERROR_INVALIDDATA;
-    }
-
-    if (ctx->scantable_type != ctx->frame_type) {
-        if (!ctx->frame_type)
-            ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable,
-                              ff_prores_progressive_scan);
-        else
-            ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable,
-                              ff_prores_interlaced_scan);
-        ctx->scantable_type = ctx->frame_type;
-    }
-
-    if (ctx->frame_type) {      /* if interlaced */
-        ctx->picture.interlaced_frame = 1;
-        ctx->picture.top_field_first  = ctx->frame_type & 1;
-    }
-
-    avctx->color_primaries = buf[14];
-    avctx->color_trc       = buf[15];
-    avctx->colorspace      = buf[16];
-
-    ctx->alpha_info = buf[17] & 0xf;
-    if (ctx->alpha_info)
-        av_log_missing_feature(avctx, "alpha channel", 0);
-
-    ctx->qmat_changed = 0;
-    ptr   = buf + 20;
-    flags = buf[19];
-    if (flags & 2) {
-        if (ptr - buf > hdr_size - 64) {
-            av_log(avctx, AV_LOG_ERROR, "header data too small\n");
-            return AVERROR_INVALIDDATA;
-        }
-        if (memcmp(ctx->qmat_luma, ptr, 64)) {
-            memcpy(ctx->qmat_luma, ptr, 64);
-            ctx->qmat_changed = 1;
-        }
-        ptr += 64;
-    } else {
-        memset(ctx->qmat_luma, 4, 64);
-        ctx->qmat_changed = 1;
-    }
-
-    if (flags & 1) {
-        if (ptr - buf > hdr_size - 64) {
-            av_log(avctx, AV_LOG_ERROR, "header data too small\n");
-            return -1;
-        }
-        if (memcmp(ctx->qmat_chroma, ptr, 64)) {
-            memcpy(ctx->qmat_chroma, ptr, 64);
-            ctx->qmat_changed = 1;
-        }
-    } else {
-        memset(ctx->qmat_chroma, 4, 64);
-        ctx->qmat_changed = 1;
-    }
-
-    return hdr_size;
-}
-
-
-static int decode_picture_header(ProresContext *ctx, const uint8_t *buf,
-                                 const int data_size, AVCodecContext *avctx)
-{
-    int   i, hdr_size, pic_data_size, num_slices;
-    int   slice_width_factor, slice_height_factor;
-    int   remainder, num_x_slices;
-    const uint8_t *data_ptr, *index_ptr;
-
-    hdr_size = data_size > 0 ? buf[0] >> 3 : 0;
-    if (hdr_size < 8 || hdr_size > data_size) {
-        av_log(avctx, AV_LOG_ERROR, "picture header too small\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    pic_data_size = AV_RB32(buf + 1);
-    if (pic_data_size > data_size) {
-        av_log(avctx, AV_LOG_ERROR, "picture data too small\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    slice_width_factor  = buf[7] >> 4;
-    slice_height_factor = buf[7] & 0xF;
-    if (slice_width_factor > 3 || slice_height_factor) {
-        av_log(avctx, AV_LOG_ERROR,
-               "unsupported slice dimension: %d x %d\n",
-               1 << slice_width_factor, 1 << slice_height_factor);
-        return AVERROR_INVALIDDATA;
-    }
-
-    ctx->slice_width_factor  = slice_width_factor;
-    ctx->slice_height_factor = slice_height_factor;
-
-    ctx->num_x_mbs = (avctx->width + 15) >> 4;
-    ctx->num_y_mbs = (avctx->height +
-                      (1 << (4 + ctx->picture.interlaced_frame)) - 1) >>
-                     (4 + ctx->picture.interlaced_frame);
-
-    remainder    = ctx->num_x_mbs & ((1 << slice_width_factor) - 1);
-    num_x_slices = (ctx->num_x_mbs >> slice_width_factor) + (remainder & 1) +
-                   ((remainder >> 1) & 1) + ((remainder >> 2) & 1);
-
-    num_slices = num_x_slices * ctx->num_y_mbs;
-    if (num_slices != AV_RB16(buf + 5)) {
-        av_log(avctx, AV_LOG_ERROR, "invalid number of slices\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    if (ctx->total_slices != num_slices) {
-        av_freep(&ctx->slice_data);
-        ctx->slice_data = av_malloc((num_slices + 1) * sizeof(ctx->slice_data[0]));
-        if (!ctx->slice_data)
-            return AVERROR(ENOMEM);
-        ctx->total_slices = num_slices;
-    }
-
-    if (hdr_size + num_slices * 2 > data_size) {
-        av_log(avctx, AV_LOG_ERROR, "slice table too small\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    /* parse slice table allowing quick access to the slice data */
-    index_ptr = buf + hdr_size;
-    data_ptr = index_ptr + num_slices * 2;
-
-    for (i = 0; i < num_slices; i++) {
-        ctx->slice_data[i].index = data_ptr;
-        ctx->slice_data[i].prev_slice_sf = 0;
-        data_ptr += AV_RB16(index_ptr + i * 2);
-    }
-    ctx->slice_data[i].index = data_ptr;
-    ctx->slice_data[i].prev_slice_sf = 0;
-
-    if (data_ptr > buf + data_size) {
-        av_log(avctx, AV_LOG_ERROR, "out of slice data\n");
-        return -1;
-    }
-
-    return pic_data_size;
-}
-
-
-/**
- * Read an unsigned rice/exp golomb codeword.
- */
-static inline int decode_vlc_codeword(GetBitContext *gb, unsigned codebook)
-{
-    unsigned int rice_order, exp_order, switch_bits;
-    unsigned int buf, code;
-    int log, prefix_len, len;
-
-    OPEN_READER(re, gb);
-    UPDATE_CACHE(re, gb);
-    buf = GET_CACHE(re, gb);
-
-    /* number of prefix bits to switch between Rice and expGolomb */
-    switch_bits = (codebook & 3) + 1;
-    rice_order  = codebook >> 5;        /* rice code order */
-    exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */
-
-    log = 31 - av_log2(buf); /* count prefix bits (zeroes) */
-
-    if (log < switch_bits) { /* ok, we got a rice code */
-        if (!rice_order) {
-            /* shortcut for faster decoding of rice codes without remainder */
-            code = log;
-            LAST_SKIP_BITS(re, gb, log + 1);
-        } else {
-            prefix_len = log + 1;
-            code = (log << rice_order) + NEG_USR32(buf << prefix_len, rice_order);
-            LAST_SKIP_BITS(re, gb, prefix_len + rice_order);
-        }
-    } else { /* otherwise we got a exp golomb code */
-        len  = (log << 1) - switch_bits + exp_order + 1;
-        code = NEG_USR32(buf, len) - (1 << exp_order) + (switch_bits << rice_order);
-        LAST_SKIP_BITS(re, gb, len);
-    }
-
-    CLOSE_READER(re, gb);
-
-    return code;
-}
-
-#define LSB2SIGN(x) (-((x) & 1))
-#define TOSIGNED(x) (((x) >> 1) ^ LSB2SIGN(x))
-
-/**
- * Decode DC coefficients for all blocks in a slice.
- */
-static inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out,
-                                    int nblocks)
-{
-    DCTELEM prev_dc;
-    int     i, sign;
-    int16_t delta;
-    unsigned int code;
-
-    code   = decode_vlc_codeword(gb, FIRST_DC_CB);
-    out[0] = prev_dc = TOSIGNED(code);
-
-    out   += 64; /* move to the DC coeff of the next block */
-    delta  = 3;
-
-    for (i = 1; i < nblocks; i++, out += 64) {
-        code = decode_vlc_codeword(gb, ff_prores_dc_codebook[FFMIN(FFABS(delta), 3)]);
-
-        sign     = -(((delta >> 15) & 1) ^ (code & 1));
-        delta    = (((code + 1) >> 1) ^ sign) - sign;
-        prev_dc += delta;
-        out[0]   = prev_dc;
-    }
-}
-
-
-/**
- * Decode AC coefficients for all blocks in a slice.
- */
-static inline void decode_ac_coeffs(GetBitContext *gb, DCTELEM *out,
-                                    int blocks_per_slice,
-                                    int plane_size_factor,
-                                    const uint8_t *scan)
-{
-    int pos, block_mask, run, level, sign, run_cb_index, lev_cb_index;
-    int max_coeffs, bits_left;
-
-    /* set initial prediction values */
-    run   = 4;
-    level = 2;
-
-    max_coeffs = blocks_per_slice << 6;
-    block_mask = blocks_per_slice - 1;
-
-    for (pos = blocks_per_slice - 1; pos < max_coeffs;) {
-        run_cb_index = ff_prores_run_to_cb_index[FFMIN(run, 15)];
-        lev_cb_index = ff_prores_lev_to_cb_index[FFMIN(level, 9)];
-
-        bits_left = get_bits_left(gb);
-        if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
-            return;
-
-        run = decode_vlc_codeword(gb, ff_prores_ac_codebook[run_cb_index]);
-
-        bits_left = get_bits_left(gb);
-        if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
-            return;
-
-        level = decode_vlc_codeword(gb, ff_prores_ac_codebook[lev_cb_index]) + 1;
-
-        pos += run + 1;
-        if (pos >= max_coeffs)
-            break;
-
-        sign = get_sbits(gb, 1);
-        out[((pos & block_mask) << 6) + scan[pos >> plane_size_factor]] =
-            (level ^ sign) - sign;
-    }
-}
-
-
-/**
- * Decode a slice plane (luma or chroma).
- */
-static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td,
-                               const uint8_t *buf,
-                               int data_size, uint16_t *out_ptr,
-                               int linesize, int mbs_per_slice,
-                               int blocks_per_mb, int plane_size_factor,
-                               const int16_t *qmat, int is_chroma)
-{
-    GetBitContext gb;
-    DCTELEM *block_ptr;
-    int mb_num, blocks_per_slice;
-
-    blocks_per_slice = mbs_per_slice * blocks_per_mb;
-
-    memset(td->blocks, 0, 8 * 4 * 64 * sizeof(*td->blocks));
-
-    init_get_bits(&gb, buf, data_size << 3);
-
-    decode_dc_coeffs(&gb, td->blocks, blocks_per_slice);
-
-    decode_ac_coeffs(&gb, td->blocks, blocks_per_slice,
-                     plane_size_factor, ctx->scantable.permutated);
-
-    /* inverse quantization, inverse transform and output */
-    block_ptr = td->blocks;
-
-    if (!is_chroma) {
-        for (mb_num = 0; mb_num < mbs_per_slice; mb_num++, out_ptr += blocks_per_mb * 4) {
-            ctx->dsp.idct_put(out_ptr,                    linesize, block_ptr, qmat);
-            block_ptr += 64;
-            if (blocks_per_mb > 2) {
-                ctx->dsp.idct_put(out_ptr + 8,            linesize, block_ptr, qmat);
-                block_ptr += 64;
-            }
-            ctx->dsp.idct_put(out_ptr + linesize * 4,     linesize, block_ptr, qmat);
-            block_ptr += 64;
-            if (blocks_per_mb > 2) {
-                ctx->dsp.idct_put(out_ptr + linesize * 4 + 8, linesize, block_ptr, qmat);
-                block_ptr += 64;
-            }
-        }
-    } else {
-        for (mb_num = 0; mb_num < mbs_per_slice; mb_num++, out_ptr += blocks_per_mb * 4) {
-            ctx->dsp.idct_put(out_ptr,                    linesize, block_ptr, qmat);
-            block_ptr += 64;
-            ctx->dsp.idct_put(out_ptr + linesize * 4,     linesize, block_ptr, qmat);
-            block_ptr += 64;
-            if (blocks_per_mb > 2) {
-                ctx->dsp.idct_put(out_ptr + 8,            linesize, block_ptr, qmat);
-                block_ptr += 64;
-                ctx->dsp.idct_put(out_ptr + linesize * 4 + 8, linesize, block_ptr, qmat);
-                block_ptr += 64;
-            }
-        }
-    }
-}
-
-
-static int decode_slice(AVCodecContext *avctx, void *tdata)
-{
-    ProresThreadData *td = tdata;
-    ProresContext *ctx = avctx->priv_data;
-    int mb_x_pos  = td->x_pos;
-    int mb_y_pos  = td->y_pos;
-    int pic_num   = ctx->pic_num;
-    int slice_num = td->slice_num;
-    int mbs_per_slice = td->slice_width;
-    const uint8_t *buf;
-    uint8_t *y_data, *u_data, *v_data;
-    AVFrame *pic = avctx->coded_frame;
-    int i, sf, slice_width_factor;
-    int slice_data_size, hdr_size, y_data_size, u_data_size, v_data_size;
-    int y_linesize, u_linesize, v_linesize;
-
-    buf             = ctx->slice_data[slice_num].index;
-    slice_data_size = ctx->slice_data[slice_num + 1].index - buf;
-
-    slice_width_factor = av_log2(mbs_per_slice);
-
-    y_data     = pic->data[0];
-    u_data     = pic->data[1];
-    v_data     = pic->data[2];
-    y_linesize = pic->linesize[0];
-    u_linesize = pic->linesize[1];
-    v_linesize = pic->linesize[2];
-
-    if (pic->interlaced_frame) {
-        if (!(pic_num ^ pic->top_field_first)) {
-            y_data += y_linesize;
-            u_data += u_linesize;
-            v_data += v_linesize;
-        }
-        y_linesize <<= 1;
-        u_linesize <<= 1;
-        v_linesize <<= 1;
-    }
-
-    if (slice_data_size < 6) {
-        av_log(avctx, AV_LOG_ERROR, "slice data too small\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    /* parse slice header */
-    hdr_size    = buf[0] >> 3;
-    y_data_size = AV_RB16(buf + 2);
-    u_data_size = AV_RB16(buf + 4);
-    v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) :
-        slice_data_size - y_data_size - u_data_size - hdr_size;
-
-    if (hdr_size + y_data_size + u_data_size + v_data_size > slice_data_size ||
-        v_data_size < 0 || hdr_size < 6) {
-        av_log(avctx, AV_LOG_ERROR, "invalid data size\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    sf = av_clip(buf[1], 1, 224);
-    sf = sf > 128 ? (sf - 96) << 2 : sf;
-
-    /* scale quantization matrixes according with slice's scale factor */
-    /* TODO: this can be SIMD-optimized a lot */
-    if (ctx->qmat_changed || sf != td->prev_slice_sf) {
-        td->prev_slice_sf = sf;
-        for (i = 0; i < 64; i++) {
-            td->qmat_luma_scaled[ctx->dsp.idct_permutation[i]]   = ctx->qmat_luma[i]   * sf;
-            td->qmat_chroma_scaled[ctx->dsp.idct_permutation[i]] = ctx->qmat_chroma[i] * sf;
-        }
-    }
-
-    /* decode luma plane */
-    decode_slice_plane(ctx, td, buf + hdr_size, y_data_size,
-                       (uint16_t*) (y_data + (mb_y_pos << 4) * y_linesize +
-                                    (mb_x_pos << 5)), y_linesize,
-                       mbs_per_slice, 4, slice_width_factor + 2,
-                       td->qmat_luma_scaled, 0);
-
-    /* decode U chroma plane */
-    decode_slice_plane(ctx, td, buf + hdr_size + y_data_size, u_data_size,
-                       (uint16_t*) (u_data + (mb_y_pos << 4) * u_linesize +
-                                    (mb_x_pos << ctx->mb_chroma_factor)),
-                       u_linesize, mbs_per_slice, ctx->num_chroma_blocks,
-                       slice_width_factor + ctx->chroma_factor - 1,
-                       td->qmat_chroma_scaled, 1);
-
-    /* decode V chroma plane */
-    decode_slice_plane(ctx, td, buf + hdr_size + y_data_size + u_data_size,
-                       v_data_size,
-                       (uint16_t*) (v_data + (mb_y_pos << 4) * v_linesize +
-                                    (mb_x_pos << ctx->mb_chroma_factor)),
-                       v_linesize, mbs_per_slice, ctx->num_chroma_blocks,
-                       slice_width_factor + ctx->chroma_factor - 1,
-                       td->qmat_chroma_scaled, 1);
-
-    return 0;
-}
-
-
-static int decode_picture(ProresContext *ctx, int pic_num,
-                          AVCodecContext *avctx)
-{
-    int slice_num, slice_width, x_pos, y_pos;
-
-    slice_num = 0;
-
-    ctx->pic_num = pic_num;
-    for (y_pos = 0; y_pos < ctx->num_y_mbs; y_pos++) {
-        slice_width = 1 << ctx->slice_width_factor;
-
-        for (x_pos = 0; x_pos < ctx->num_x_mbs && slice_width;
-             x_pos += slice_width) {
-            while (ctx->num_x_mbs - x_pos < slice_width)
-                slice_width >>= 1;
-
-            ctx->slice_data[slice_num].slice_num   = slice_num;
-            ctx->slice_data[slice_num].x_pos       = x_pos;
-            ctx->slice_data[slice_num].y_pos       = y_pos;
-            ctx->slice_data[slice_num].slice_width = slice_width;
-
-            slice_num++;
-        }
-    }
-
-    return avctx->execute(avctx, decode_slice,
-                          ctx->slice_data, NULL, slice_num,
-                          sizeof(ctx->slice_data[0]));
-}
-
-
-#define MOVE_DATA_PTR(nbytes) buf += (nbytes); buf_size -= (nbytes)
-
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
-                        AVPacket *avpkt)
-{
-    ProresContext *ctx = avctx->priv_data;
-    AVFrame *picture   = avctx->coded_frame;
-    const uint8_t *buf = avpkt->data;
-    int buf_size       = avpkt->size;
-    int frame_hdr_size, pic_num, pic_data_size;
-
-    /* check frame atom container */
-    if (buf_size < 28 || buf_size < AV_RB32(buf) ||
-        AV_RB32(buf + 4) != FRAME_ID) {
-        av_log(avctx, AV_LOG_ERROR, "invalid frame\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    MOVE_DATA_PTR(8);
-
-    frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx);
-    if (frame_hdr_size < 0)
-        return AVERROR_INVALIDDATA;
-
-    MOVE_DATA_PTR(frame_hdr_size);
-
-    if (picture->data[0])
-        avctx->release_buffer(avctx, picture);
-
-    picture->reference = 0;
-    if (avctx->get_buffer(avctx, picture) < 0)
-        return -1;
-
-    for (pic_num = 0; ctx->picture.interlaced_frame - pic_num + 1; pic_num++) {
-        pic_data_size = decode_picture_header(ctx, buf, buf_size, avctx);
-        if (pic_data_size < 0)
-            return AVERROR_INVALIDDATA;
-
-        if (decode_picture(ctx, pic_num, avctx))
-            return -1;
-
-        MOVE_DATA_PTR(pic_data_size);
-    }
-
-    *data_size       = sizeof(AVPicture);
-    *(AVFrame*) data = *avctx->coded_frame;
-
-    return avpkt->size;
-}
-
-
-static av_cold int decode_close(AVCodecContext *avctx)
-{
-    ProresContext *ctx = avctx->priv_data;
-
-    if (ctx->picture.data[0])
-        avctx->release_buffer(avctx, &ctx->picture);
-
-    av_freep(&ctx->slice_data);
-
-    return 0;
-}
-
-
-AVCodec ff_prores_decoder = {
-    .name           = "prores",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_PRORES,
-    .priv_data_size = sizeof(ProresContext),
-    .init           = decode_init,
-    .close          = decode_close,
-    .decode         = decode_frame,
-    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
-    .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)")
-};
diff --git a/libavcodec/proresdec.h b/libavcodec/proresdec.h
new file mode 100644
index 0000000..1c56227
--- /dev/null
+++ b/libavcodec/proresdec.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2010-2011 Maxim Poliakovski
+ * Copyright (c) 2010-2011 Elvis Presley
+ *
+ * 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;
+ * version 2 of the License.
+ *
+ * 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 AVCODEC_PRORESDEC_H
+#define AVCODEC_PRORESDEC_H
+
+#include "dsputil.h"
+#include "proresdsp.h"
+
+typedef struct {
+    const uint8_t *data;
+    unsigned mb_x;
+    unsigned mb_y;
+    unsigned mb_count;
+    unsigned data_size;
+    int ret;
+} SliceContext;
+
+typedef struct {
+    DSPContext dsp;
+    ProresDSPContext prodsp;
+    AVFrame frame;
+    int frame_type;              ///< 0 = progressive, 1 = tff, 2 = bff
+    uint8_t qmat_luma[64];
+    uint8_t qmat_chroma[64];
+    SliceContext *slices;
+    int slice_count;             ///< number of slices in the current picture
+    unsigned mb_width;           ///< width of the current picture in mb
+    unsigned mb_height;          ///< height of the current picture in mb
+    uint8_t progressive_scan[64];
+    uint8_t interlaced_scan[64];
+    const uint8_t *scan;
+    int first_field;
+} ProresContext;
+
+#endif /* AVCODEC_PRORESDEC_H */
diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c
new file mode 100644
index 0000000..d14b535
--- /dev/null
+++ b/libavcodec/proresdec2.c
@@ -0,0 +1,596 @@
+/*
+ * Copyright (c) 2010-2011 Maxim Poliakovski
+ * Copyright (c) 2010-2011 Elvis Presley
+ *
+ * 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
+ * Known FOURCCs: 'apch' (HQ), 'apcn' (SD), 'apcs' (LT), 'acpo' (Proxy), 'ap4h' (4444)
+ */
+
+//#define DEBUG
+
+#define LONG_BITSTREAM_READER
+
+#include "avcodec.h"
+#include "get_bits.h"
+#include "simple_idct.h"
+#include "proresdec.h"
+
+static void permute(uint8_t *dst, const uint8_t *src, const uint8_t permutation[64])
+{
+    int i;
+    for (i = 0; i < 64; i++)
+        dst[i] = permutation[src[i]];
+}
+
+static const uint8_t progressive_scan[64] = {
+     0,  1,  8,  9,  2,  3, 10, 11,
+    16, 17, 24, 25, 18, 19, 26, 27,
+     4,  5, 12, 20, 13,  6,  7, 14,
+    21, 28, 29, 22, 15, 23, 30, 31,
+    32, 33, 40, 48, 41, 34, 35, 42,
+    49, 56, 57, 50, 43, 36, 37, 44,
+    51, 58, 59, 52, 45, 38, 39, 46,
+    53, 60, 61, 54, 47, 55, 62, 63
+};
+
+static const uint8_t interlaced_scan[64] = {
+     0,  8,  1,  9, 16, 24, 17, 25,
+     2, 10,  3, 11, 18, 26, 19, 27,
+    32, 40, 33, 34, 41, 48, 56, 49,
+    42, 35, 43, 50, 57, 58, 51, 59,
+     4, 12,  5,  6, 13, 20, 28, 21,
+    14,  7, 15, 22, 29, 36, 44, 37,
+    30, 23, 31, 38, 45, 52, 60, 53,
+    46, 39, 47, 54, 61, 62, 55, 63,
+};
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+    ProresContext *ctx = avctx->priv_data;
+    uint8_t idct_permutation[64];
+
+    avctx->bits_per_raw_sample = 10;
+
+    ff_dsputil_init(&ctx->dsp, avctx);
+    ff_proresdsp_init(&ctx->prodsp, avctx);
+
+    avctx->coded_frame = &ctx->frame;
+    ctx->frame.type = AV_PICTURE_TYPE_I;
+    ctx->frame.key_frame = 1;
+
+    ff_init_scantable_permutation(idct_permutation,
+                                  ctx->prodsp.idct_permutation_type);
+
+    permute(ctx->progressive_scan, progressive_scan, idct_permutation);
+    permute(ctx->interlaced_scan, interlaced_scan, idct_permutation);
+
+    return 0;
+}
+
+static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
+                               const int data_size, AVCodecContext *avctx)
+{
+    int hdr_size, width, height, flags;
+    int version;
+    const uint8_t *ptr;
+
+    hdr_size = AV_RB16(buf);
+    av_dlog(avctx, "header size %d\n", hdr_size);
+    if (hdr_size > data_size) {
+        av_log(avctx, AV_LOG_ERROR, "error, wrong header size\n");
+        return -1;
+    }
+
+    version = AV_RB16(buf + 2);
+    av_dlog(avctx, "%.4s version %d\n", buf+4, version);
+    if (version > 1) {
+        av_log(avctx, AV_LOG_ERROR, "unsupported version: %d\n", version);
+        return -1;
+    }
+
+    width  = AV_RB16(buf + 8);
+    height = AV_RB16(buf + 10);
+    if (width != avctx->width || height != avctx->height) {
+        av_log(avctx, AV_LOG_ERROR, "picture resolution change: %dx%d -> %dx%d\n",
+               avctx->width, avctx->height, width, height);
+        return -1;
+    }
+
+    ctx->frame_type = (buf[12] >> 2) & 3;
+
+    av_dlog(avctx, "frame type %d\n", ctx->frame_type);
+
+    if (ctx->frame_type == 0) {
+        ctx->scan = ctx->progressive_scan; // permuted
+    } else {
+        ctx->scan = ctx->interlaced_scan; // permuted
+        ctx->frame.interlaced_frame = 1;
+        ctx->frame.top_field_first = ctx->frame_type == 1;
+    }
+
+    avctx->pix_fmt = (buf[12] & 0xC0) == 0xC0 ? AV_PIX_FMT_YUV444P10 : AV_PIX_FMT_YUV422P10;
+
+    ptr   = buf + 20;
+    flags = buf[19];
+    av_dlog(avctx, "flags %x\n", flags);
+
+    if (flags & 2) {
+        permute(ctx->qmat_luma, ctx->prodsp.idct_permutation, ptr);
+        ptr += 64;
+    } else {
+        memset(ctx->qmat_luma, 4, 64);
+    }
+
+    if (flags & 1) {
+        permute(ctx->qmat_chroma, ctx->prodsp.idct_permutation, ptr);
+    } else {
+        memset(ctx->qmat_chroma, 4, 64);
+    }
+
+    return hdr_size;
+}
+
+static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, const int buf_size)
+{
+    ProresContext *ctx = avctx->priv_data;
+    int i, hdr_size, slice_count;
+    unsigned pic_data_size;
+    int log2_slice_mb_width, log2_slice_mb_height;
+    int slice_mb_count, mb_x, mb_y;
+    const uint8_t *data_ptr, *index_ptr;
+
+    hdr_size = buf[0] >> 3;
+    if (hdr_size < 8 || hdr_size > buf_size) {
+        av_log(avctx, AV_LOG_ERROR, "error, wrong picture header size\n");
+        return -1;
+    }
+
+    pic_data_size = AV_RB32(buf + 1);
+    if (pic_data_size > buf_size) {
+        av_log(avctx, AV_LOG_ERROR, "error, wrong picture data size\n");
+        return -1;
+    }
+
+    log2_slice_mb_width  = buf[7] >> 4;
+    log2_slice_mb_height = buf[7] & 0xF;
+    if (log2_slice_mb_width > 3 || log2_slice_mb_height) {
+        av_log(avctx, AV_LOG_ERROR, "unsupported slice resolution: %dx%d\n",
+               1 << log2_slice_mb_width, 1 << log2_slice_mb_height);
+        return -1;
+    }
+
+    ctx->mb_width  = (avctx->width  + 15) >> 4;
+    if (ctx->frame_type)
+        ctx->mb_height = (avctx->height + 31) >> 5;
+    else
+        ctx->mb_height = (avctx->height + 15) >> 4;
+
+    slice_count = AV_RB16(buf + 5);
+
+    if (ctx->slice_count != slice_count || !ctx->slices) {
+        av_freep(&ctx->slices);
+        ctx->slices = av_mallocz(slice_count * sizeof(*ctx->slices));
+        if (!ctx->slices)
+            return AVERROR(ENOMEM);
+        ctx->slice_count = slice_count;
+    }
+
+    if (!slice_count)
+        return AVERROR(EINVAL);
+
+    if (hdr_size + slice_count*2 > buf_size) {
+        av_log(avctx, AV_LOG_ERROR, "error, wrong slice count\n");
+        return -1;
+    }
+
+    // parse slice information
+    index_ptr = buf + hdr_size;
+    data_ptr  = index_ptr + slice_count*2;
+
+    slice_mb_count = 1 << log2_slice_mb_width;
+    mb_x = 0;
+    mb_y = 0;
+
+    for (i = 0; i < slice_count; i++) {
+        SliceContext *slice = &ctx->slices[i];
+
+        slice->data = data_ptr;
+        data_ptr += AV_RB16(index_ptr + i*2);
+
+        while (ctx->mb_width - mb_x < slice_mb_count)
+            slice_mb_count >>= 1;
+
+        slice->mb_x = mb_x;
+        slice->mb_y = mb_y;
+        slice->mb_count = slice_mb_count;
+        slice->data_size = data_ptr - slice->data;
+
+        if (slice->data_size < 6) {
+            av_log(avctx, AV_LOG_ERROR, "error, wrong slice data size\n");
+            return -1;
+        }
+
+        mb_x += slice_mb_count;
+        if (mb_x == ctx->mb_width) {
+            slice_mb_count = 1 << log2_slice_mb_width;
+            mb_x = 0;
+            mb_y++;
+        }
+        if (data_ptr > buf + buf_size) {
+            av_log(avctx, AV_LOG_ERROR, "error, slice out of bounds\n");
+            return -1;
+        }
+    }
+
+    if (mb_x || mb_y != ctx->mb_height) {
+        av_log(avctx, AV_LOG_ERROR, "error wrong mb count y %d h %d\n",
+               mb_y, ctx->mb_height);
+        return -1;
+    }
+
+    return pic_data_size;
+}
+
+#define DECODE_CODEWORD(val, codebook)                                  \
+    do {                                                                \
+        unsigned int rice_order, exp_order, switch_bits;                \
+        unsigned int q, buf, bits;                                      \
+                                                                        \
+        UPDATE_CACHE(re, gb);                                           \
+        buf = GET_CACHE(re, gb);                                        \
+                                                                        \
+        /* number of bits to switch between rice and exp golomb */      \
+        switch_bits =  codebook & 3;                                    \
+        rice_order  =  codebook >> 5;                                   \
+        exp_order   = (codebook >> 2) & 7;                              \
+                                                                        \
+        q = 31 - av_log2(buf);                                          \
+                                                                        \
+        if (q > switch_bits) { /* exp golomb */                         \
+            bits = exp_order - switch_bits + (q<<1);                    \
+            val = SHOW_UBITS(re, gb, bits) - (1 << exp_order) +         \
+                ((switch_bits + 1) << rice_order);                      \
+            SKIP_BITS(re, gb, bits);                                    \
+        } else if (rice_order) {                                        \
+            SKIP_BITS(re, gb, q+1);                                     \
+            val = (q << rice_order) + SHOW_UBITS(re, gb, rice_order);   \
+            SKIP_BITS(re, gb, rice_order);                              \
+        } else {                                                        \
+            val = q;                                                    \
+            SKIP_BITS(re, gb, q+1);                                     \
+        }                                                               \
+    } while (0)
+
+#define TOSIGNED(x) (((x) >> 1) ^ (-((x) & 1)))
+
+#define FIRST_DC_CB 0xB8
+
+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,
+                                              int blocks_per_slice)
+{
+    DCTELEM prev_dc;
+    int code, i, sign;
+
+    OPEN_READER(re, gb);
+
+    DECODE_CODEWORD(code, FIRST_DC_CB);
+    prev_dc = TOSIGNED(code);
+    out[0] = prev_dc;
+
+    out += 64; // dc coeff for the next block
+
+    code = 5;
+    sign = 0;
+    for (i = 1; i < blocks_per_slice; i++, out += 64) {
+        DECODE_CODEWORD(code, dc_codebook[FFMIN(code, 6U)]);
+        if(code) sign ^= -(code & 1);
+        else     sign  = 0;
+        prev_dc += (((code + 1) >> 1) ^ sign) - sign;
+        out[0] = prev_dc;
+    }
+    CLOSE_READER(re, gb);
+}
+
+// adaptive codebook switching lut according to previous run/level values
+static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
+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)
+{
+    ProresContext *ctx = avctx->priv_data;
+    int block_mask, sign;
+    unsigned pos, run, level;
+    int max_coeffs, i, bits_left;
+    int log2_block_count = av_log2(blocks_per_slice);
+
+    OPEN_READER(re, gb);
+    UPDATE_CACHE(re, gb);                                           \
+    run   = 4;
+    level = 2;
+
+    max_coeffs = 64 << log2_block_count;
+    block_mask = blocks_per_slice - 1;
+
+    for (pos = block_mask;;) {
+        bits_left = gb->size_in_bits - re_index;
+        if (!bits_left || (bits_left < 32 && !SHOW_UBITS(re, gb, bits_left)))
+            break;
+
+        DECODE_CODEWORD(run, run_to_cb[FFMIN(run,  15)]);
+        pos += run + 1;
+        if (pos >= max_coeffs) {
+            av_log(avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", pos, max_coeffs);
+            return;
+        }
+
+        DECODE_CODEWORD(level, lev_to_cb[FFMIN(level, 9)]);
+        level += 1;
+
+        i = pos >> log2_block_count;
+
+        sign = SHOW_SBITS(re, gb, 1);
+        SKIP_BITS(re, gb, 1);
+        out[((pos & block_mask) << 6) + ctx->scan[i]] = ((level ^ sign) - sign);
+    }
+
+    CLOSE_READER(re, gb);
+}
+
+static void decode_slice_luma(AVCodecContext *avctx, SliceContext *slice,
+                              uint16_t *dst, int dst_stride,
+                              const uint8_t *buf, unsigned buf_size,
+                              const int16_t *qmat)
+{
+    ProresContext *ctx = avctx->priv_data;
+    LOCAL_ALIGNED_16(DCTELEM, blocks, [8*4*64]);
+    DCTELEM *block;
+    GetBitContext gb;
+    int i, blocks_per_slice = slice->mb_count<<2;
+
+    for (i = 0; i < blocks_per_slice; i++)
+        ctx->dsp.clear_block(blocks+(i<<6));
+
+    init_get_bits(&gb, buf, buf_size << 3);
+
+    decode_dc_coeffs(&gb, blocks, blocks_per_slice);
+    decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice);
+
+    block = blocks;
+    for (i = 0; i < slice->mb_count; i++) {
+        ctx->prodsp.idct_put(dst, dst_stride, block+(0<<6), qmat);
+        ctx->prodsp.idct_put(dst             +8, dst_stride, block+(1<<6), qmat);
+        ctx->prodsp.idct_put(dst+4*dst_stride  , dst_stride, block+(2<<6), qmat);
+        ctx->prodsp.idct_put(dst+4*dst_stride+8, dst_stride, block+(3<<6), qmat);
+        block += 4*64;
+        dst += 16;
+    }
+}
+
+static void decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice,
+                                uint16_t *dst, int dst_stride,
+                                const uint8_t *buf, unsigned buf_size,
+                                const int16_t *qmat, int log2_blocks_per_mb)
+{
+    ProresContext *ctx = avctx->priv_data;
+    LOCAL_ALIGNED_16(DCTELEM, blocks, [8*4*64]);
+    DCTELEM *block;
+    GetBitContext gb;
+    int i, j, blocks_per_slice = slice->mb_count << log2_blocks_per_mb;
+
+    for (i = 0; i < blocks_per_slice; i++)
+        ctx->dsp.clear_block(blocks+(i<<6));
+
+    init_get_bits(&gb, buf, buf_size << 3);
+
+    decode_dc_coeffs(&gb, blocks, blocks_per_slice);
+    decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice);
+
+    block = blocks;
+    for (i = 0; i < slice->mb_count; i++) {
+        for (j = 0; j < log2_blocks_per_mb; j++) {
+            ctx->prodsp.idct_put(dst,              dst_stride, block+(0<<6), qmat);
+            ctx->prodsp.idct_put(dst+4*dst_stride, dst_stride, block+(1<<6), qmat);
+            block += 2*64;
+            dst += 8;
+        }
+    }
+}
+
+static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr)
+{
+    ProresContext *ctx = avctx->priv_data;
+    SliceContext *slice = &ctx->slices[jobnr];
+    const uint8_t *buf = slice->data;
+    AVFrame *pic = avctx->coded_frame;
+    int i, hdr_size, qscale, log2_chroma_blocks_per_mb;
+    int luma_stride, chroma_stride;
+    int y_data_size, u_data_size, v_data_size;
+    uint8_t *dest_y, *dest_u, *dest_v;
+    int16_t qmat_luma_scaled[64];
+    int16_t qmat_chroma_scaled[64];
+    int mb_x_shift;
+
+    slice->ret = -1;
+    //av_log(avctx, AV_LOG_INFO, "slice %d mb width %d mb x %d y %d\n",
+    //       jobnr, slice->mb_count, slice->mb_x, slice->mb_y);
+
+    // slice header
+    hdr_size = buf[0] >> 3;
+    qscale = av_clip(buf[1], 1, 224);
+    qscale = qscale > 128 ? qscale - 96 << 2: qscale;
+    y_data_size = AV_RB16(buf + 2);
+    u_data_size = AV_RB16(buf + 4);
+    v_data_size = slice->data_size - y_data_size - u_data_size - hdr_size;
+    if (hdr_size > 7) v_data_size = AV_RB16(buf + 6);
+
+    if (y_data_size < 0 || u_data_size < 0 || v_data_size < 0
+        || hdr_size+y_data_size+u_data_size+v_data_size > slice->data_size){
+        av_log(avctx, AV_LOG_ERROR, "invalid plane data size\n");
+        return -1;
+    }
+
+    buf += hdr_size;
+
+    for (i = 0; i < 64; i++) {
+        qmat_luma_scaled  [i] = ctx->qmat_luma  [i] * qscale;
+        qmat_chroma_scaled[i] = ctx->qmat_chroma[i] * qscale;
+    }
+
+    if (ctx->frame_type == 0) {
+        luma_stride   = pic->linesize[0];
+        chroma_stride = pic->linesize[1];
+    } else {
+        luma_stride   = pic->linesize[0] << 1;
+        chroma_stride = pic->linesize[1] << 1;
+    }
+
+    if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
+        mb_x_shift = 5;
+        log2_chroma_blocks_per_mb = 2;
+    } else {
+        mb_x_shift = 4;
+        log2_chroma_blocks_per_mb = 1;
+    }
+
+    dest_y = pic->data[0] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5);
+    dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
+    dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift);
+
+    if (ctx->frame_type && ctx->first_field ^ ctx->frame.top_field_first) {
+        dest_y += pic->linesize[0];
+        dest_u += pic->linesize[1];
+        dest_v += pic->linesize[2];
+    }
+
+    decode_slice_luma(avctx, slice, (uint16_t*)dest_y, luma_stride,
+                      buf, y_data_size, qmat_luma_scaled);
+
+    if (!(avctx->flags & CODEC_FLAG_GRAY)) {
+        decode_slice_chroma(avctx, slice, (uint16_t*)dest_u, chroma_stride,
+                            buf + y_data_size, u_data_size,
+                            qmat_chroma_scaled, log2_chroma_blocks_per_mb);
+        decode_slice_chroma(avctx, slice, (uint16_t*)dest_v, chroma_stride,
+                            buf + y_data_size + u_data_size, v_data_size,
+                            qmat_chroma_scaled, log2_chroma_blocks_per_mb);
+    }
+
+    slice->ret = 0;
+    return 0;
+}
+
+static int decode_picture(AVCodecContext *avctx)
+{
+    ProresContext *ctx = avctx->priv_data;
+    int i;
+
+    avctx->execute2(avctx, decode_slice_thread, NULL, NULL, ctx->slice_count);
+
+    for (i = 0; i < ctx->slice_count; i++)
+        if (ctx->slices[i].ret < 0)
+            return ctx->slices[i].ret;
+
+    return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+                        AVPacket *avpkt)
+{
+    ProresContext *ctx = avctx->priv_data;
+    AVFrame *frame = avctx->coded_frame;
+    const uint8_t *buf = avpkt->data;
+    int buf_size = avpkt->size;
+    int frame_hdr_size, pic_size;
+
+    if (buf_size < 28 || AV_RL32(buf + 4) != AV_RL32("icpf")) {
+        av_log(avctx, AV_LOG_ERROR, "invalid frame header\n");
+        return -1;
+    }
+
+    ctx->first_field = 1;
+
+    buf += 8;
+    buf_size -= 8;
+
+    frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx);
+    if (frame_hdr_size < 0)
+        return -1;
+
+    buf += frame_hdr_size;
+    buf_size -= frame_hdr_size;
+
+    if (frame->data[0])
+        avctx->release_buffer(avctx, frame);
+
+    if (avctx->get_buffer(avctx, frame) < 0)
+        return -1;
+
+ decode_picture:
+    pic_size = decode_picture_header(avctx, buf, buf_size);
+    if (pic_size < 0) {
+        av_log(avctx, AV_LOG_ERROR, "error decoding picture header\n");
+        return -1;
+    }
+
+    if (decode_picture(avctx)) {
+        av_log(avctx, AV_LOG_ERROR, "error decoding picture\n");
+        return -1;
+    }
+
+    buf += pic_size;
+    buf_size -= pic_size;
+
+    if (ctx->frame_type && buf_size > 0 && ctx->first_field) {
+        ctx->first_field = 0;
+        goto decode_picture;
+    }
+
+    *data_size = sizeof(AVFrame);
+    *(AVFrame*)data = *frame;
+
+    return avpkt->size;
+}
+
+static av_cold int decode_close(AVCodecContext *avctx)
+{
+    ProresContext *ctx = avctx->priv_data;
+
+    AVFrame *frame = avctx->coded_frame;
+    if (frame->data[0])
+        avctx->release_buffer(avctx, frame);
+    av_freep(&ctx->slices);
+
+    return 0;
+}
+
+AVCodec ff_prores_decoder = {
+    .name           = "prores",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_PRORES,
+    .priv_data_size = sizeof(ProresContext),
+    .init           = decode_init,
+    .close          = decode_close,
+    .decode         = decode_frame,
+    .long_name      = NULL_IF_CONFIG_SMALL("ProRes"),
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
+};
diff --git a/libavcodec/proresdec_lgpl.c b/libavcodec/proresdec_lgpl.c
new file mode 100644
index 0000000..b5aaa61
--- /dev/null
+++ b/libavcodec/proresdec_lgpl.c
@@ -0,0 +1,673 @@
+/*
+ * Apple ProRes compatible decoder
+ *
+ * Copyright (c) 2010-2011 Maxim Poliakovski
+ *
+ * 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
+ * This is a decoder for Apple ProRes 422 SD/HQ/LT/Proxy and ProRes 4444.
+ * It is used for storing and editing high definition video data in Apple's Final Cut Pro.
+ *
+ * @see http://wiki.multimedia.cx/index.php?title=Apple_ProRes
+ */
+
+#define LONG_BITSTREAM_READER // some ProRes vlc codes require up to 28 bits to be read at once
+
+#include <stdint.h>
+
+#include "libavutil/intmath.h"
+#include "avcodec.h"
+#include "proresdata.h"
+#include "proresdsp.h"
+#include "get_bits.h"
+
+typedef struct {
+    const uint8_t *index;            ///< pointers to the data of this slice
+    int slice_num;
+    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, qmat_luma_scaled)[64];
+    DECLARE_ALIGNED(16, int16_t, qmat_chroma_scaled)[64];
+} ProresThreadData;
+
+typedef struct {
+    ProresDSPContext dsp;
+    AVFrame    picture;
+    ScanTable  scantable;
+    int        scantable_type;           ///< -1 = uninitialized, 0 = progressive, 1/2 = interlaced
+
+    int        frame_type;               ///< 0 = progressive, 1 = top-field first, 2 = bottom-field first
+    int        pic_format;               ///< 2 = 422, 3 = 444
+    uint8_t    qmat_luma[64];            ///< dequantization matrix for luma
+    uint8_t    qmat_chroma[64];          ///< dequantization matrix for chroma
+    int        qmat_changed;             ///< 1 - global quantization matrices changed
+    int        total_slices;            ///< total number of slices in a picture
+    ProresThreadData *slice_data;
+    int        pic_num;
+    int        chroma_factor;
+    int        mb_chroma_factor;
+    int        num_chroma_blocks;       ///< number of chrominance blocks in a macroblock
+    int        num_x_slices;
+    int        num_y_slices;
+    int        slice_width_factor;
+    int        slice_height_factor;
+    int        num_x_mbs;
+    int        num_y_mbs;
+    int        alpha_info;
+} ProresContext;
+
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+    ProresContext *ctx = avctx->priv_data;
+
+    ctx->total_slices     = 0;
+    ctx->slice_data       = NULL;
+
+    avctx->bits_per_raw_sample = PRORES_BITS_PER_SAMPLE;
+    ff_proresdsp_init(&ctx->dsp, avctx);
+
+    avctx->coded_frame = &ctx->picture;
+    avcodec_get_frame_defaults(&ctx->picture);
+    ctx->picture.type      = AV_PICTURE_TYPE_I;
+    ctx->picture.key_frame = 1;
+
+    ctx->scantable_type = -1;   // set scantable type to uninitialized
+    memset(ctx->qmat_luma, 4, 64);
+    memset(ctx->qmat_chroma, 4, 64);
+
+    return 0;
+}
+
+
+static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
+                               const int data_size, AVCodecContext *avctx)
+{
+    int hdr_size, version, width, height, flags;
+    const uint8_t *ptr;
+
+    hdr_size = AV_RB16(buf);
+    if (hdr_size > data_size) {
+        av_log(avctx, AV_LOG_ERROR, "frame data too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    version = AV_RB16(buf + 2);
+    if (version >= 2) {
+        av_log(avctx, AV_LOG_ERROR,
+               "unsupported header version: %d\n", version);
+        return AVERROR_INVALIDDATA;
+    }
+
+    width  = AV_RB16(buf + 8);
+    height = AV_RB16(buf + 10);
+    if (width != avctx->width || height != avctx->height) {
+        av_log(avctx, AV_LOG_ERROR,
+               "picture dimension changed: old: %d x %d, new: %d x %d\n",
+               avctx->width, avctx->height, width, height);
+        return AVERROR_INVALIDDATA;
+    }
+
+    ctx->frame_type = (buf[12] >> 2) & 3;
+    if (ctx->frame_type > 2) {
+        av_log(avctx, AV_LOG_ERROR,
+               "unsupported frame type: %d\n", ctx->frame_type);
+        return AVERROR_INVALIDDATA;
+    }
+
+    ctx->chroma_factor     = (buf[12] >> 6) & 3;
+    ctx->mb_chroma_factor  = ctx->chroma_factor + 2;
+    ctx->num_chroma_blocks = (1 << ctx->chroma_factor) >> 1;
+    switch (ctx->chroma_factor) {
+    case 2:
+        avctx->pix_fmt = AV_PIX_FMT_YUV422P10;
+        break;
+    case 3:
+        avctx->pix_fmt = AV_PIX_FMT_YUV444P10;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR,
+               "unsupported picture format: %d\n", ctx->pic_format);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (ctx->scantable_type != ctx->frame_type) {
+        if (!ctx->frame_type)
+            ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable,
+                              ff_prores_progressive_scan);
+        else
+            ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable,
+                              ff_prores_interlaced_scan);
+        ctx->scantable_type = ctx->frame_type;
+    }
+
+    if (ctx->frame_type) {      /* if interlaced */
+        ctx->picture.interlaced_frame = 1;
+        ctx->picture.top_field_first  = ctx->frame_type & 1;
+    }
+
+    avctx->color_primaries = buf[14];
+    avctx->color_trc       = buf[15];
+    avctx->colorspace      = buf[16];
+
+    ctx->alpha_info = buf[17] & 0xf;
+    if (ctx->alpha_info)
+        av_log_missing_feature(avctx, "alpha channel", 0);
+
+    ctx->qmat_changed = 0;
+    ptr   = buf + 20;
+    flags = buf[19];
+    if (flags & 2) {
+        if (ptr - buf > hdr_size - 64) {
+            av_log(avctx, AV_LOG_ERROR, "header data too small\n");
+            return AVERROR_INVALIDDATA;
+        }
+        if (memcmp(ctx->qmat_luma, ptr, 64)) {
+            memcpy(ctx->qmat_luma, ptr, 64);
+            ctx->qmat_changed = 1;
+        }
+        ptr += 64;
+    } else {
+        memset(ctx->qmat_luma, 4, 64);
+        ctx->qmat_changed = 1;
+    }
+
+    if (flags & 1) {
+        if (ptr - buf > hdr_size - 64) {
+            av_log(avctx, AV_LOG_ERROR, "header data too small\n");
+            return -1;
+        }
+        if (memcmp(ctx->qmat_chroma, ptr, 64)) {
+            memcpy(ctx->qmat_chroma, ptr, 64);
+            ctx->qmat_changed = 1;
+        }
+    } else {
+        memset(ctx->qmat_chroma, 4, 64);
+        ctx->qmat_changed = 1;
+    }
+
+    return hdr_size;
+}
+
+
+static int decode_picture_header(ProresContext *ctx, const uint8_t *buf,
+                                 const int data_size, AVCodecContext *avctx)
+{
+    int   i, hdr_size, pic_data_size, num_slices;
+    int   slice_width_factor, slice_height_factor;
+    int   remainder, num_x_slices;
+    const uint8_t *data_ptr, *index_ptr;
+
+    hdr_size = data_size > 0 ? buf[0] >> 3 : 0;
+    if (hdr_size < 8 || hdr_size > data_size) {
+        av_log(avctx, AV_LOG_ERROR, "picture header too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    pic_data_size = AV_RB32(buf + 1);
+    if (pic_data_size > data_size) {
+        av_log(avctx, AV_LOG_ERROR, "picture data too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    slice_width_factor  = buf[7] >> 4;
+    slice_height_factor = buf[7] & 0xF;
+    if (slice_width_factor > 3 || slice_height_factor) {
+        av_log(avctx, AV_LOG_ERROR,
+               "unsupported slice dimension: %d x %d\n",
+               1 << slice_width_factor, 1 << slice_height_factor);
+        return AVERROR_INVALIDDATA;
+    }
+
+    ctx->slice_width_factor  = slice_width_factor;
+    ctx->slice_height_factor = slice_height_factor;
+
+    ctx->num_x_mbs = (avctx->width + 15) >> 4;
+    ctx->num_y_mbs = (avctx->height +
+                      (1 << (4 + ctx->picture.interlaced_frame)) - 1) >>
+                     (4 + ctx->picture.interlaced_frame);
+
+    remainder    = ctx->num_x_mbs & ((1 << slice_width_factor) - 1);
+    num_x_slices = (ctx->num_x_mbs >> slice_width_factor) + (remainder & 1) +
+                   ((remainder >> 1) & 1) + ((remainder >> 2) & 1);
+
+    num_slices = num_x_slices * ctx->num_y_mbs;
+    if (num_slices != AV_RB16(buf + 5)) {
+        av_log(avctx, AV_LOG_ERROR, "invalid number of slices\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (ctx->total_slices != num_slices) {
+        av_freep(&ctx->slice_data);
+        ctx->slice_data = av_malloc((num_slices + 1) * sizeof(ctx->slice_data[0]));
+        if (!ctx->slice_data)
+            return AVERROR(ENOMEM);
+        ctx->total_slices = num_slices;
+    }
+
+    if (hdr_size + num_slices * 2 > data_size) {
+        av_log(avctx, AV_LOG_ERROR, "slice table too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    /* parse slice table allowing quick access to the slice data */
+    index_ptr = buf + hdr_size;
+    data_ptr = index_ptr + num_slices * 2;
+
+    for (i = 0; i < num_slices; i++) {
+        ctx->slice_data[i].index = data_ptr;
+        ctx->slice_data[i].prev_slice_sf = 0;
+        data_ptr += AV_RB16(index_ptr + i * 2);
+    }
+    ctx->slice_data[i].index = data_ptr;
+    ctx->slice_data[i].prev_slice_sf = 0;
+
+    if (data_ptr > buf + data_size) {
+        av_log(avctx, AV_LOG_ERROR, "out of slice data\n");
+        return -1;
+    }
+
+    return pic_data_size;
+}
+
+
+/**
+ * Read an unsigned rice/exp golomb codeword.
+ */
+static inline int decode_vlc_codeword(GetBitContext *gb, unsigned codebook)
+{
+    unsigned int rice_order, exp_order, switch_bits;
+    unsigned int buf, code;
+    int log, prefix_len, len;
+
+    OPEN_READER(re, gb);
+    UPDATE_CACHE(re, gb);
+    buf = GET_CACHE(re, gb);
+
+    /* number of prefix bits to switch between Rice and expGolomb */
+    switch_bits = (codebook & 3) + 1;
+    rice_order  = codebook >> 5;        /* rice code order */
+    exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */
+
+    log = 31 - av_log2(buf); /* count prefix bits (zeroes) */
+
+    if (log < switch_bits) { /* ok, we got a rice code */
+        if (!rice_order) {
+            /* shortcut for faster decoding of rice codes without remainder */
+            code = log;
+            LAST_SKIP_BITS(re, gb, log + 1);
+        } else {
+            prefix_len = log + 1;
+            code = (log << rice_order) + NEG_USR32(buf << prefix_len, rice_order);
+            LAST_SKIP_BITS(re, gb, prefix_len + rice_order);
+        }
+    } else { /* otherwise we got a exp golomb code */
+        len  = (log << 1) - switch_bits + exp_order + 1;
+        code = NEG_USR32(buf, len) - (1 << exp_order) + (switch_bits << rice_order);
+        LAST_SKIP_BITS(re, gb, len);
+    }
+
+    CLOSE_READER(re, gb);
+
+    return code;
+}
+
+#define LSB2SIGN(x) (-((x) & 1))
+#define TOSIGNED(x) (((x) >> 1) ^ LSB2SIGN(x))
+
+/**
+ * Decode DC coefficients for all blocks in a slice.
+ */
+static inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out,
+                                    int nblocks)
+{
+    DCTELEM prev_dc;
+    int     i, sign;
+    int16_t delta;
+    unsigned int code;
+
+    code   = decode_vlc_codeword(gb, FIRST_DC_CB);
+    out[0] = prev_dc = TOSIGNED(code);
+
+    out   += 64; /* move to the DC coeff of the next block */
+    delta  = 3;
+
+    for (i = 1; i < nblocks; i++, out += 64) {
+        code = decode_vlc_codeword(gb, ff_prores_dc_codebook[FFMIN(FFABS(delta), 3)]);
+
+        sign     = -(((delta >> 15) & 1) ^ (code & 1));
+        delta    = (((code + 1) >> 1) ^ sign) - sign;
+        prev_dc += delta;
+        out[0]   = prev_dc;
+    }
+}
+
+
+/**
+ * Decode AC coefficients for all blocks in a slice.
+ */
+static inline void decode_ac_coeffs(GetBitContext *gb, DCTELEM *out,
+                                    int blocks_per_slice,
+                                    int plane_size_factor,
+                                    const uint8_t *scan)
+{
+    int pos, block_mask, run, level, sign, run_cb_index, lev_cb_index;
+    int max_coeffs, bits_left;
+
+    /* set initial prediction values */
+    run   = 4;
+    level = 2;
+
+    max_coeffs = blocks_per_slice << 6;
+    block_mask = blocks_per_slice - 1;
+
+    for (pos = blocks_per_slice - 1; pos < max_coeffs;) {
+        run_cb_index = ff_prores_run_to_cb_index[FFMIN(run, 15)];
+        lev_cb_index = ff_prores_lev_to_cb_index[FFMIN(level, 9)];
+
+        bits_left = get_bits_left(gb);
+        if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
+            return;
+
+        run = decode_vlc_codeword(gb, ff_prores_ac_codebook[run_cb_index]);
+
+        bits_left = get_bits_left(gb);
+        if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
+            return;
+
+        level = decode_vlc_codeword(gb, ff_prores_ac_codebook[lev_cb_index]) + 1;
+
+        pos += run + 1;
+        if (pos >= max_coeffs)
+            break;
+
+        sign = get_sbits(gb, 1);
+        out[((pos & block_mask) << 6) + scan[pos >> plane_size_factor]] =
+            (level ^ sign) - sign;
+    }
+}
+
+
+/**
+ * Decode a slice plane (luma or chroma).
+ */
+static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td,
+                               const uint8_t *buf,
+                               int data_size, uint16_t *out_ptr,
+                               int linesize, int mbs_per_slice,
+                               int blocks_per_mb, int plane_size_factor,
+                               const int16_t *qmat, int is_chroma)
+{
+    GetBitContext gb;
+    DCTELEM *block_ptr;
+    int mb_num, blocks_per_slice;
+
+    blocks_per_slice = mbs_per_slice * blocks_per_mb;
+
+    memset(td->blocks, 0, 8 * 4 * 64 * sizeof(*td->blocks));
+
+    init_get_bits(&gb, buf, data_size << 3);
+
+    decode_dc_coeffs(&gb, td->blocks, blocks_per_slice);
+
+    decode_ac_coeffs(&gb, td->blocks, blocks_per_slice,
+                     plane_size_factor, ctx->scantable.permutated);
+
+    /* inverse quantization, inverse transform and output */
+    block_ptr = td->blocks;
+
+    if (!is_chroma) {
+        for (mb_num = 0; mb_num < mbs_per_slice; mb_num++, out_ptr += blocks_per_mb * 4) {
+            ctx->dsp.idct_put(out_ptr,                    linesize, block_ptr, qmat);
+            block_ptr += 64;
+            if (blocks_per_mb > 2) {
+                ctx->dsp.idct_put(out_ptr + 8,            linesize, block_ptr, qmat);
+                block_ptr += 64;
+            }
+            ctx->dsp.idct_put(out_ptr + linesize * 4,     linesize, block_ptr, qmat);
+            block_ptr += 64;
+            if (blocks_per_mb > 2) {
+                ctx->dsp.idct_put(out_ptr + linesize * 4 + 8, linesize, block_ptr, qmat);
+                block_ptr += 64;
+            }
+        }
+    } else {
+        for (mb_num = 0; mb_num < mbs_per_slice; mb_num++, out_ptr += blocks_per_mb * 4) {
+            ctx->dsp.idct_put(out_ptr,                    linesize, block_ptr, qmat);
+            block_ptr += 64;
+            ctx->dsp.idct_put(out_ptr + linesize * 4,     linesize, block_ptr, qmat);
+            block_ptr += 64;
+            if (blocks_per_mb > 2) {
+                ctx->dsp.idct_put(out_ptr + 8,            linesize, block_ptr, qmat);
+                block_ptr += 64;
+                ctx->dsp.idct_put(out_ptr + linesize * 4 + 8, linesize, block_ptr, qmat);
+                block_ptr += 64;
+            }
+        }
+    }
+}
+
+
+static int decode_slice(AVCodecContext *avctx, void *tdata)
+{
+    ProresThreadData *td = tdata;
+    ProresContext *ctx = avctx->priv_data;
+    int mb_x_pos  = td->x_pos;
+    int mb_y_pos  = td->y_pos;
+    int pic_num   = ctx->pic_num;
+    int slice_num = td->slice_num;
+    int mbs_per_slice = td->slice_width;
+    const uint8_t *buf;
+    uint8_t *y_data, *u_data, *v_data;
+    AVFrame *pic = avctx->coded_frame;
+    int i, sf, slice_width_factor;
+    int slice_data_size, hdr_size, y_data_size, u_data_size, v_data_size;
+    int y_linesize, u_linesize, v_linesize;
+
+    buf             = ctx->slice_data[slice_num].index;
+    slice_data_size = ctx->slice_data[slice_num + 1].index - buf;
+
+    slice_width_factor = av_log2(mbs_per_slice);
+
+    y_data     = pic->data[0];
+    u_data     = pic->data[1];
+    v_data     = pic->data[2];
+    y_linesize = pic->linesize[0];
+    u_linesize = pic->linesize[1];
+    v_linesize = pic->linesize[2];
+
+    if (pic->interlaced_frame) {
+        if (!(pic_num ^ pic->top_field_first)) {
+            y_data += y_linesize;
+            u_data += u_linesize;
+            v_data += v_linesize;
+        }
+        y_linesize <<= 1;
+        u_linesize <<= 1;
+        v_linesize <<= 1;
+    }
+
+    if (slice_data_size < 6) {
+        av_log(avctx, AV_LOG_ERROR, "slice data too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    /* parse slice header */
+    hdr_size    = buf[0] >> 3;
+    y_data_size = AV_RB16(buf + 2);
+    u_data_size = AV_RB16(buf + 4);
+    v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) :
+        slice_data_size - y_data_size - u_data_size - hdr_size;
+
+    if (hdr_size + y_data_size + u_data_size + v_data_size > slice_data_size ||
+        v_data_size < 0 || hdr_size < 6) {
+        av_log(avctx, AV_LOG_ERROR, "invalid data size\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    sf = av_clip(buf[1], 1, 224);
+    sf = sf > 128 ? (sf - 96) << 2 : sf;
+
+    /* scale quantization matrixes according with slice's scale factor */
+    /* TODO: this can be SIMD-optimized a lot */
+    if (ctx->qmat_changed || sf != td->prev_slice_sf) {
+        td->prev_slice_sf = sf;
+        for (i = 0; i < 64; i++) {
+            td->qmat_luma_scaled[ctx->dsp.idct_permutation[i]]   = ctx->qmat_luma[i]   * sf;
+            td->qmat_chroma_scaled[ctx->dsp.idct_permutation[i]] = ctx->qmat_chroma[i] * sf;
+        }
+    }
+
+    /* decode luma plane */
+    decode_slice_plane(ctx, td, buf + hdr_size, y_data_size,
+                       (uint16_t*) (y_data + (mb_y_pos << 4) * y_linesize +
+                                    (mb_x_pos << 5)), y_linesize,
+                       mbs_per_slice, 4, slice_width_factor + 2,
+                       td->qmat_luma_scaled, 0);
+
+    /* decode U chroma plane */
+    decode_slice_plane(ctx, td, buf + hdr_size + y_data_size, u_data_size,
+                       (uint16_t*) (u_data + (mb_y_pos << 4) * u_linesize +
+                                    (mb_x_pos << ctx->mb_chroma_factor)),
+                       u_linesize, mbs_per_slice, ctx->num_chroma_blocks,
+                       slice_width_factor + ctx->chroma_factor - 1,
+                       td->qmat_chroma_scaled, 1);
+
+    /* decode V chroma plane */
+    decode_slice_plane(ctx, td, buf + hdr_size + y_data_size + u_data_size,
+                       v_data_size,
+                       (uint16_t*) (v_data + (mb_y_pos << 4) * v_linesize +
+                                    (mb_x_pos << ctx->mb_chroma_factor)),
+                       v_linesize, mbs_per_slice, ctx->num_chroma_blocks,
+                       slice_width_factor + ctx->chroma_factor - 1,
+                       td->qmat_chroma_scaled, 1);
+
+    return 0;
+}
+
+
+static int decode_picture(ProresContext *ctx, int pic_num,
+                          AVCodecContext *avctx)
+{
+    int slice_num, slice_width, x_pos, y_pos;
+
+    slice_num = 0;
+
+    ctx->pic_num = pic_num;
+    for (y_pos = 0; y_pos < ctx->num_y_mbs; y_pos++) {
+        slice_width = 1 << ctx->slice_width_factor;
+
+        for (x_pos = 0; x_pos < ctx->num_x_mbs && slice_width;
+             x_pos += slice_width) {
+            while (ctx->num_x_mbs - x_pos < slice_width)
+                slice_width >>= 1;
+
+            ctx->slice_data[slice_num].slice_num   = slice_num;
+            ctx->slice_data[slice_num].x_pos       = x_pos;
+            ctx->slice_data[slice_num].y_pos       = y_pos;
+            ctx->slice_data[slice_num].slice_width = slice_width;
+
+            slice_num++;
+        }
+    }
+
+    return avctx->execute(avctx, decode_slice,
+                          ctx->slice_data, NULL, slice_num,
+                          sizeof(ctx->slice_data[0]));
+}
+
+
+#define MOVE_DATA_PTR(nbytes) buf += (nbytes); buf_size -= (nbytes)
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+                        AVPacket *avpkt)
+{
+    ProresContext *ctx = avctx->priv_data;
+    AVFrame *picture   = avctx->coded_frame;
+    const uint8_t *buf = avpkt->data;
+    int buf_size       = avpkt->size;
+    int frame_hdr_size, pic_num, pic_data_size;
+
+    /* check frame atom container */
+    if (buf_size < 28 || buf_size < AV_RB32(buf) ||
+        AV_RB32(buf + 4) != FRAME_ID) {
+        av_log(avctx, AV_LOG_ERROR, "invalid frame\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    MOVE_DATA_PTR(8);
+
+    frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx);
+    if (frame_hdr_size < 0)
+        return AVERROR_INVALIDDATA;
+
+    MOVE_DATA_PTR(frame_hdr_size);
+
+    if (picture->data[0])
+        avctx->release_buffer(avctx, picture);
+
+    picture->reference = 0;
+    if (avctx->get_buffer(avctx, picture) < 0)
+        return -1;
+
+    for (pic_num = 0; ctx->picture.interlaced_frame - pic_num + 1; pic_num++) {
+        pic_data_size = decode_picture_header(ctx, buf, buf_size, avctx);
+        if (pic_data_size < 0)
+            return AVERROR_INVALIDDATA;
+
+        if (decode_picture(ctx, pic_num, avctx))
+            return -1;
+
+        MOVE_DATA_PTR(pic_data_size);
+    }
+
+    *data_size       = sizeof(AVPicture);
+    *(AVFrame*) data = *avctx->coded_frame;
+
+    return avpkt->size;
+}
+
+
+static av_cold int decode_close(AVCodecContext *avctx)
+{
+    ProresContext *ctx = avctx->priv_data;
+
+    if (ctx->picture.data[0])
+        avctx->release_buffer(avctx, &ctx->picture);
+
+    av_freep(&ctx->slice_data);
+
+    return 0;
+}
+
+
+AVCodec ff_prores_lgpl_decoder = {
+    .name           = "prores_lgpl",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_PRORES,
+    .priv_data_size = sizeof(ProresContext),
+    .init           = decode_init,
+    .close          = decode_close,
+    .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
+    .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)")
+};
diff --git a/libavcodec/proresdsp.c b/libavcodec/proresdsp.c
index 5996904..9e063b0 100644
--- a/libavcodec/proresdsp.c
+++ b/libavcodec/proresdsp.c
@@ -30,7 +30,7 @@
 
 #define CLIP_AND_BIAS(x) (av_clip((x) + BIAS, CLIP_MIN, CLIP_MAX))
 
-#if CONFIG_PRORES_DECODER
+#if CONFIG_PRORES_DECODER | CONFIG_PRORES_LGPL_DECODER
 /**
  * Add bias value, clamp and output pixels of a slice
  */
@@ -54,7 +54,7 @@
 }
 #endif
 
-#if CONFIG_PRORES_ENCODER
+#if CONFIG_PRORES_KOSTYA_ENCODER
 static void prores_fdct_c(const uint16_t *src, int linesize, DCTELEM *block)
 {
     int x, y;
@@ -69,18 +69,18 @@
 }
 #endif
 
-void ff_proresdsp_init(ProresDSPContext *dsp)
+void ff_proresdsp_init(ProresDSPContext *dsp, AVCodecContext *avctx)
 {
-#if CONFIG_PRORES_DECODER
+#if CONFIG_PRORES_DECODER | CONFIG_PRORES_LGPL_DECODER
     dsp->idct_put = prores_idct_put_c;
     dsp->idct_permutation_type = FF_NO_IDCT_PERM;
 
-    if (ARCH_X86) ff_proresdsp_x86_init(dsp);
+    if (ARCH_X86) ff_proresdsp_x86_init(dsp, avctx);
 
     ff_init_scantable_permutation(dsp->idct_permutation,
                                   dsp->idct_permutation_type);
 #endif
-#if CONFIG_PRORES_ENCODER
+#if CONFIG_PRORES_KOSTYA_ENCODER
     dsp->fdct                 = prores_fdct_c;
     dsp->dct_permutation_type = FF_NO_IDCT_PERM;
     ff_init_scantable_permutation(dsp->dct_permutation,
diff --git a/libavcodec/proresdsp.h b/libavcodec/proresdsp.h
index ba22259..09541d9 100644
--- a/libavcodec/proresdsp.h
+++ b/libavcodec/proresdsp.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010-2011 Maxim Poliakovski
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,8 +36,8 @@
     void (* fdct) (const uint16_t *src, int linesize, DCTELEM *block);
 } ProresDSPContext;
 
-void ff_proresdsp_init(ProresDSPContext *dsp);
+void ff_proresdsp_init(ProresDSPContext *dsp, AVCodecContext *avctx);
 
-void ff_proresdsp_x86_init(ProresDSPContext *dsp);
+void ff_proresdsp_x86_init(ProresDSPContext *dsp, AVCodecContext *avctx);
 
 #endif /* AVCODEC_PRORESDSP_H */
diff --git a/libavcodec/proresenc.c b/libavcodec/proresenc.c
deleted file mode 100644
index c4716d6..0000000
--- a/libavcodec/proresenc.c
+++ /dev/null
@@ -1,1078 +0,0 @@
-/*
- * Apple ProRes encoder
- *
- * Copyright (c) 2012 Konstantin Shishkov
- *
- * 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
- */
-
-#include "libavutil/opt.h"
-#include "avcodec.h"
-#include "put_bits.h"
-#include "bytestream.h"
-#include "internal.h"
-#include "proresdsp.h"
-#include "proresdata.h"
-
-#define CFACTOR_Y422 2
-#define CFACTOR_Y444 3
-
-#define MAX_MBS_PER_SLICE 8
-
-#define MAX_PLANES 3 // should be increased to 4 when there's AV_PIX_FMT_YUV444AP10
-
-enum {
-    PRORES_PROFILE_PROXY = 0,
-    PRORES_PROFILE_LT,
-    PRORES_PROFILE_STANDARD,
-    PRORES_PROFILE_HQ,
-};
-
-enum {
-    QUANT_MAT_PROXY = 0,
-    QUANT_MAT_LT,
-    QUANT_MAT_STANDARD,
-    QUANT_MAT_HQ,
-    QUANT_MAT_DEFAULT,
-};
-
-static const uint8_t prores_quant_matrices[][64] = {
-    { // proxy
-         4,  7,  9, 11, 13, 14, 15, 63,
-         7,  7, 11, 12, 14, 15, 63, 63,
-         9, 11, 13, 14, 15, 63, 63, 63,
-        11, 11, 13, 14, 63, 63, 63, 63,
-        11, 13, 14, 63, 63, 63, 63, 63,
-        13, 14, 63, 63, 63, 63, 63, 63,
-        13, 63, 63, 63, 63, 63, 63, 63,
-        63, 63, 63, 63, 63, 63, 63, 63,
-    },
-    { // LT
-         4,  5,  6,  7,  9, 11, 13, 15,
-         5,  5,  7,  8, 11, 13, 15, 17,
-         6,  7,  9, 11, 13, 15, 15, 17,
-         7,  7,  9, 11, 13, 15, 17, 19,
-         7,  9, 11, 13, 14, 16, 19, 23,
-         9, 11, 13, 14, 16, 19, 23, 29,
-         9, 11, 13, 15, 17, 21, 28, 35,
-        11, 13, 16, 17, 21, 28, 35, 41,
-    },
-    { // standard
-         4,  4,  5,  5,  6,  7,  7,  9,
-         4,  4,  5,  6,  7,  7,  9,  9,
-         5,  5,  6,  7,  7,  9,  9, 10,
-         5,  5,  6,  7,  7,  9,  9, 10,
-         5,  6,  7,  7,  8,  9, 10, 12,
-         6,  7,  7,  8,  9, 10, 12, 15,
-         6,  7,  7,  9, 10, 11, 14, 17,
-         7,  7,  9, 10, 11, 14, 17, 21,
-    },
-    { // high quality
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  5,
-         4,  4,  4,  4,  4,  4,  5,  5,
-         4,  4,  4,  4,  4,  5,  5,  6,
-         4,  4,  4,  4,  5,  5,  6,  7,
-         4,  4,  4,  4,  5,  6,  7,  7,
-    },
-    { // codec default
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-         4,  4,  4,  4,  4,  4,  4,  4,
-    },
-};
-
-#define NUM_MB_LIMITS 4
-static const int prores_mb_limits[NUM_MB_LIMITS] = {
-    1620, // up to 720x576
-    2700, // up to 960x720
-    6075, // up to 1440x1080
-    9216, // up to 2048x1152
-};
-
-static const struct prores_profile {
-    const char *full_name;
-    uint32_t    tag;
-    int         min_quant;
-    int         max_quant;
-    int         br_tab[NUM_MB_LIMITS];
-    int         quant;
-} prores_profile_info[4] = {
-    {
-        .full_name = "proxy",
-        .tag       = MKTAG('a', 'p', 'c', 'o'),
-        .min_quant = 4,
-        .max_quant = 8,
-        .br_tab    = { 300, 242, 220, 194 },
-        .quant     = QUANT_MAT_PROXY,
-    },
-    {
-        .full_name = "LT",
-        .tag       = MKTAG('a', 'p', 'c', 's'),
-        .min_quant = 1,
-        .max_quant = 9,
-        .br_tab    = { 720, 560, 490, 440 },
-        .quant     = QUANT_MAT_LT,
-    },
-    {
-        .full_name = "standard",
-        .tag       = MKTAG('a', 'p', 'c', 'n'),
-        .min_quant = 1,
-        .max_quant = 6,
-        .br_tab    = { 1050, 808, 710, 632 },
-        .quant     = QUANT_MAT_STANDARD,
-    },
-    {
-        .full_name = "high quality",
-        .tag       = MKTAG('a', 'p', 'c', 'h'),
-        .min_quant = 1,
-        .max_quant = 6,
-        .br_tab    = { 1566, 1216, 1070, 950 },
-        .quant     = QUANT_MAT_HQ,
-    }
-// for 4444 profile bitrate numbers are { 2350, 1828, 1600, 1425 }
-};
-
-#define TRELLIS_WIDTH 16
-#define SCORE_LIMIT   INT_MAX / 2
-
-struct TrellisNode {
-    int prev_node;
-    int quant;
-    int bits;
-    int score;
-};
-
-#define MAX_STORED_Q 16
-
-typedef struct ProresThreadData {
-    DECLARE_ALIGNED(16, DCTELEM, 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;
-} ProresThreadData;
-
-typedef struct ProresContext {
-    AVClass *class;
-    DECLARE_ALIGNED(16, DCTELEM, 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];
-    const uint8_t *quant_mat;
-
-    ProresDSPContext dsp;
-    ScanTable  scantable;
-
-    int mb_width, mb_height;
-    int mbs_per_slice;
-    int num_chroma_blocks, chroma_factor;
-    int slices_width;
-    int slices_per_picture;
-    int pictures_per_frame; // 1 for progressive, 2 for interlaced
-    int cur_picture_idx;
-    int num_planes;
-    int bits_per_mb;
-    int force_quant;
-
-    char *vendor;
-    int quant_sel;
-
-    int frame_size_upper_bound;
-
-    int profile;
-    const struct prores_profile *profile_info;
-
-    int *slice_q;
-
-    ProresThreadData *tdata;
-} ProresContext;
-
-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,
-                           int mbs_per_slice, int blocks_per_mb, int is_chroma)
-{
-    const uint16_t *esrc;
-    const int mb_width = 4 * blocks_per_mb;
-    int elinesize;
-    int i, j, k;
-
-    for (i = 0; i < mbs_per_slice; i++, src += mb_width) {
-        if (x >= w) {
-            memset(blocks, 0, 64 * (mbs_per_slice - i) * blocks_per_mb
-                              * sizeof(*blocks));
-            return;
-        }
-        if (x + mb_width <= w && y + 16 <= h) {
-            esrc      = src;
-            elinesize = linesize;
-        } else {
-            int bw, bh, pix;
-
-            esrc      = emu_buf;
-            elinesize = 16 * sizeof(*emu_buf);
-
-            bw = FFMIN(w - x, mb_width);
-            bh = FFMIN(h - y, 16);
-
-            for (j = 0; j < bh; j++) {
-                memcpy(emu_buf + j * 16,
-                       (const uint8_t*)src + j * linesize,
-                       bw * sizeof(*src));
-                pix = emu_buf[j * 16 + bw - 1];
-                for (k = bw; k < mb_width; k++)
-                    emu_buf[j * 16 + k] = pix;
-            }
-            for (; j < 16; j++)
-                memcpy(emu_buf + j * 16,
-                       emu_buf + (bh - 1) * 16,
-                       mb_width * sizeof(*emu_buf));
-        }
-        if (!is_chroma) {
-            ctx->dsp.fdct(esrc, elinesize, blocks);
-            blocks += 64;
-            if (blocks_per_mb > 2) {
-                ctx->dsp.fdct(esrc + 8, elinesize, blocks);
-                blocks += 64;
-            }
-            ctx->dsp.fdct(esrc + elinesize * 4, elinesize, blocks);
-            blocks += 64;
-            if (blocks_per_mb > 2) {
-                ctx->dsp.fdct(esrc + elinesize * 4 + 8, elinesize, blocks);
-                blocks += 64;
-            }
-        } else {
-            ctx->dsp.fdct(esrc, elinesize, blocks);
-            blocks += 64;
-            ctx->dsp.fdct(esrc + elinesize * 4, elinesize, blocks);
-            blocks += 64;
-            if (blocks_per_mb > 2) {
-                ctx->dsp.fdct(esrc + 8, elinesize, blocks);
-                blocks += 64;
-                ctx->dsp.fdct(esrc + elinesize * 4 + 8, elinesize, blocks);
-                blocks += 64;
-            }
-        }
-
-        x += mb_width;
-    }
-}
-
-/**
- * Write an unsigned rice/exp golomb codeword.
- */
-static inline void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
-{
-    unsigned int rice_order, exp_order, switch_bits, switch_val;
-    int exponent;
-
-    /* number of prefix bits to switch between Rice and expGolomb */
-    switch_bits = (codebook & 3) + 1;
-    rice_order  =  codebook >> 5;       /* rice code order */
-    exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */
-
-    switch_val  = switch_bits << rice_order;
-
-    if (val >= switch_val) {
-        val -= switch_val - (1 << exp_order);
-        exponent = av_log2(val);
-
-        put_bits(pb, exponent - exp_order + switch_bits, 0);
-        put_bits(pb, exponent + 1, val);
-    } else {
-        exponent = val >> rice_order;
-
-        if (exponent)
-            put_bits(pb, exponent, 0);
-        put_bits(pb, 1, 1);
-        if (rice_order)
-            put_sbits(pb, rice_order, val);
-    }
-}
-
-#define GET_SIGN(x)  ((x) >> 31)
-#define MAKE_CODE(x) (((x) << 1) ^ GET_SIGN(x))
-
-static void encode_dcs(PutBitContext *pb, DCTELEM *blocks,
-                       int blocks_per_slice, int scale)
-{
-    int i;
-    int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
-
-    prev_dc = (blocks[0] - 0x4000) / scale;
-    encode_vlc_codeword(pb, FIRST_DC_CB, MAKE_CODE(prev_dc));
-    sign     = 0;
-    codebook = 3;
-    blocks  += 64;
-
-    for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
-        dc       = (blocks[0] - 0x4000) / scale;
-        delta    = dc - prev_dc;
-        new_sign = GET_SIGN(delta);
-        delta    = (delta ^ sign) - sign;
-        code     = MAKE_CODE(delta);
-        encode_vlc_codeword(pb, ff_prores_dc_codebook[codebook], code);
-        codebook = (code + (code & 1)) >> 1;
-        codebook = FFMIN(codebook, 3);
-        sign     = new_sign;
-        prev_dc  = dc;
-    }
-}
-
-static void encode_acs(PutBitContext *pb, DCTELEM *blocks,
-                       int blocks_per_slice,
-                       int plane_size_factor,
-                       const uint8_t *scan, const int16_t *qmat)
-{
-    int idx, i;
-    int run, level, run_cb, lev_cb;
-    int max_coeffs, abs_level;
-
-    max_coeffs = blocks_per_slice << 6;
-    run_cb     = ff_prores_run_to_cb_index[4];
-    lev_cb     = ff_prores_lev_to_cb_index[2];
-    run        = 0;
-
-    for (i = 1; i < 64; i++) {
-        for (idx = scan[i]; idx < max_coeffs; idx += 64) {
-            level = blocks[idx] / qmat[scan[i]];
-            if (level) {
-                abs_level = FFABS(level);
-                encode_vlc_codeword(pb, ff_prores_ac_codebook[run_cb], run);
-                encode_vlc_codeword(pb, ff_prores_ac_codebook[lev_cb],
-                                    abs_level - 1);
-                put_sbits(pb, 1, GET_SIGN(level));
-
-                run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
-                lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
-                run    = 0;
-            } else {
-                run++;
-            }
-        }
-    }
-}
-
-static int encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
-                              const uint16_t *src, int linesize,
-                              int mbs_per_slice, DCTELEM *blocks,
-                              int blocks_per_mb, int plane_size_factor,
-                              const int16_t *qmat)
-{
-    int blocks_per_slice, saved_pos;
-
-    saved_pos = put_bits_count(pb);
-    blocks_per_slice = mbs_per_slice * blocks_per_mb;
-
-    encode_dcs(pb, blocks, blocks_per_slice, qmat[0]);
-    encode_acs(pb, blocks, blocks_per_slice, plane_size_factor,
-               ctx->scantable.permutated, qmat);
-    flush_put_bits(pb);
-
-    return (put_bits_count(pb) - saved_pos) >> 3;
-}
-
-static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
-                        PutBitContext *pb,
-                        int sizes[4], int x, int y, int quant,
-                        int mbs_per_slice)
-{
-    ProresContext *ctx = avctx->priv_data;
-    int i, xp, yp;
-    int total_size = 0;
-    const uint16_t *src;
-    int slice_width_factor = av_log2(mbs_per_slice);
-    int num_cblocks, pwidth, linesize, line_add;
-    int plane_factor, is_chroma;
-    uint16_t *qmat;
-
-    if (ctx->pictures_per_frame == 1)
-        line_add = 0;
-    else
-        line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
-
-    if (ctx->force_quant) {
-        qmat = ctx->quants[0];
-    } else if (quant < MAX_STORED_Q) {
-        qmat = ctx->quants[quant];
-    } else {
-        qmat = ctx->custom_q;
-        for (i = 0; i < 64; i++)
-            qmat[i] = ctx->quant_mat[i] * quant;
-    }
-
-    for (i = 0; i < ctx->num_planes; i++) {
-        is_chroma    = (i == 1 || i == 2);
-        plane_factor = slice_width_factor + 2;
-        if (is_chroma)
-            plane_factor += ctx->chroma_factor - 3;
-        if (!is_chroma || ctx->chroma_factor == CFACTOR_Y444) {
-            xp          = x << 4;
-            yp          = y << 4;
-            num_cblocks = 4;
-            pwidth      = avctx->width;
-        } else {
-            xp          = x << 3;
-            yp          = y << 4;
-            num_cblocks = 2;
-            pwidth      = avctx->width >> 1;
-        }
-
-        linesize = pic->linesize[i] * ctx->pictures_per_frame;
-        src = (const uint16_t*)(pic->data[i] + yp * linesize +
-                                line_add * pic->linesize[i]) + xp;
-
-        get_slice_data(ctx, src, linesize, xp, yp,
-                       pwidth, avctx->height / ctx->pictures_per_frame,
-                       ctx->blocks[0], ctx->emu_buf,
-                       mbs_per_slice, num_cblocks, is_chroma);
-        sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
-                                      mbs_per_slice, ctx->blocks[0],
-                                      num_cblocks, plane_factor,
-                                      qmat);
-        total_size += sizes[i];
-    }
-    return total_size;
-}
-
-static inline int estimate_vlc(unsigned codebook, int val)
-{
-    unsigned int rice_order, exp_order, switch_bits, switch_val;
-    int exponent;
-
-    /* number of prefix bits to switch between Rice and expGolomb */
-    switch_bits = (codebook & 3) + 1;
-    rice_order  =  codebook >> 5;       /* rice code order */
-    exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */
-
-    switch_val  = switch_bits << rice_order;
-
-    if (val >= switch_val) {
-        val -= switch_val - (1 << exp_order);
-        exponent = av_log2(val);
-
-        return exponent * 2 - exp_order + switch_bits + 1;
-    } else {
-        return (val >> rice_order) + rice_order + 1;
-    }
-}
-
-static int estimate_dcs(int *error, DCTELEM *blocks, int blocks_per_slice,
-                        int scale)
-{
-    int i;
-    int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
-    int bits;
-
-    prev_dc  = (blocks[0] - 0x4000) / scale;
-    bits     = estimate_vlc(FIRST_DC_CB, MAKE_CODE(prev_dc));
-    sign     = 0;
-    codebook = 3;
-    blocks  += 64;
-    *error  += FFABS(blocks[0] - 0x4000) % scale;
-
-    for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
-        dc       = (blocks[0] - 0x4000) / scale;
-        *error  += FFABS(blocks[0] - 0x4000) % scale;
-        delta    = dc - prev_dc;
-        new_sign = GET_SIGN(delta);
-        delta    = (delta ^ sign) - sign;
-        code     = MAKE_CODE(delta);
-        bits    += estimate_vlc(ff_prores_dc_codebook[codebook], code);
-        codebook = (code + (code & 1)) >> 1;
-        codebook = FFMIN(codebook, 3);
-        sign     = new_sign;
-        prev_dc  = dc;
-    }
-
-    return bits;
-}
-
-static int estimate_acs(int *error, DCTELEM *blocks, int blocks_per_slice,
-                        int plane_size_factor,
-                        const uint8_t *scan, const int16_t *qmat)
-{
-    int idx, i;
-    int run, level, run_cb, lev_cb;
-    int max_coeffs, abs_level;
-    int bits = 0;
-
-    max_coeffs = blocks_per_slice << 6;
-    run_cb     = ff_prores_run_to_cb_index[4];
-    lev_cb     = ff_prores_lev_to_cb_index[2];
-    run        = 0;
-
-    for (i = 1; i < 64; i++) {
-        for (idx = scan[i]; idx < max_coeffs; idx += 64) {
-            level   = blocks[idx] / qmat[scan[i]];
-            *error += FFABS(blocks[idx]) % qmat[scan[i]];
-            if (level) {
-                abs_level = FFABS(level);
-                bits += estimate_vlc(ff_prores_ac_codebook[run_cb], run);
-                bits += estimate_vlc(ff_prores_ac_codebook[lev_cb],
-                                     abs_level - 1) + 1;
-
-                run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
-                lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
-                run    = 0;
-            } else {
-                run++;
-            }
-        }
-    }
-
-    return bits;
-}
-
-static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
-                                const uint16_t *src, int linesize,
-                                int mbs_per_slice,
-                                int blocks_per_mb, int plane_size_factor,
-                                const int16_t *qmat, ProresThreadData *td)
-{
-    int blocks_per_slice;
-    int bits;
-
-    blocks_per_slice = mbs_per_slice * blocks_per_mb;
-
-    bits  = estimate_dcs(error, td->blocks[plane], blocks_per_slice, qmat[0]);
-    bits += estimate_acs(error, td->blocks[plane], blocks_per_slice,
-                         plane_size_factor, ctx->scantable.permutated, qmat);
-
-    return FFALIGN(bits, 8);
-}
-
-static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
-                            int trellis_node, int x, int y, int mbs_per_slice,
-                            ProresThreadData *td)
-{
-    ProresContext *ctx = avctx->priv_data;
-    int i, q, pq, xp, yp;
-    const uint16_t *src;
-    int slice_width_factor = av_log2(mbs_per_slice);
-    int num_cblocks[MAX_PLANES], pwidth;
-    int plane_factor[MAX_PLANES], is_chroma[MAX_PLANES];
-    const int min_quant = ctx->profile_info->min_quant;
-    const int max_quant = ctx->profile_info->max_quant;
-    int error, bits, bits_limit;
-    int mbs, prev, cur, new_score;
-    int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
-    int overquant;
-    uint16_t *qmat;
-    int linesize[4], line_add;
-
-    if (ctx->pictures_per_frame == 1)
-        line_add = 0;
-    else
-        line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
-    mbs = x + mbs_per_slice;
-
-    for (i = 0; i < ctx->num_planes; i++) {
-        is_chroma[i]    = (i == 1 || i == 2);
-        plane_factor[i] = slice_width_factor + 2;
-        if (is_chroma[i])
-            plane_factor[i] += ctx->chroma_factor - 3;
-        if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
-            xp             = x << 4;
-            yp             = y << 4;
-            num_cblocks[i] = 4;
-            pwidth         = avctx->width;
-        } else {
-            xp             = x << 3;
-            yp             = y << 4;
-            num_cblocks[i] = 2;
-            pwidth         = avctx->width >> 1;
-        }
-
-        linesize[i] = pic->linesize[i] * ctx->pictures_per_frame;
-        src = (const uint16_t*)(pic->data[i] + yp * linesize[i] +
-                                line_add * pic->linesize[i]) + xp;
-
-        get_slice_data(ctx, src, linesize[i], xp, yp,
-                       pwidth, avctx->height / ctx->pictures_per_frame,
-                       td->blocks[i], td->emu_buf,
-                       mbs_per_slice, num_cblocks[i], is_chroma[i]);
-    }
-
-    for (q = min_quant; q < max_quant + 2; q++) {
-        td->nodes[trellis_node + q].prev_node = -1;
-        td->nodes[trellis_node + q].quant     = q;
-    }
-
-    // todo: maybe perform coarser quantising to fit into frame size when needed
-    for (q = min_quant; q <= max_quant; q++) {
-        bits  = 0;
-        error = 0;
-        for (i = 0; i < ctx->num_planes; i++) {
-            bits += estimate_slice_plane(ctx, &error, i,
-                                         src, linesize[i],
-                                         mbs_per_slice,
-                                         num_cblocks[i], plane_factor[i],
-                                         ctx->quants[q], td);
-        }
-        if (bits > 65000 * 8) {
-            error = SCORE_LIMIT;
-            break;
-        }
-        slice_bits[q]  = bits;
-        slice_score[q] = error;
-    }
-    if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
-        slice_bits[max_quant + 1]  = slice_bits[max_quant];
-        slice_score[max_quant + 1] = slice_score[max_quant] + 1;
-        overquant = max_quant;
-    } else {
-        for (q = max_quant + 1; q < 128; q++) {
-            bits  = 0;
-            error = 0;
-            if (q < MAX_STORED_Q) {
-                qmat = ctx->quants[q];
-            } else {
-                qmat = td->custom_q;
-                for (i = 0; i < 64; i++)
-                    qmat[i] = ctx->quant_mat[i] * q;
-            }
-            for (i = 0; i < ctx->num_planes; i++) {
-                bits += estimate_slice_plane(ctx, &error, i,
-                                             src, linesize[i],
-                                             mbs_per_slice,
-                                             num_cblocks[i], plane_factor[i],
-                                             qmat, td);
-            }
-            if (bits <= ctx->bits_per_mb * mbs_per_slice)
-                break;
-        }
-
-        slice_bits[max_quant + 1]  = bits;
-        slice_score[max_quant + 1] = error;
-        overquant = q;
-    }
-    td->nodes[trellis_node + max_quant + 1].quant = overquant;
-
-    bits_limit = mbs * ctx->bits_per_mb;
-    for (pq = min_quant; pq < max_quant + 2; pq++) {
-        prev = trellis_node - TRELLIS_WIDTH + pq;
-
-        for (q = min_quant; q < max_quant + 2; q++) {
-            cur = trellis_node + q;
-
-            bits  = td->nodes[prev].bits + slice_bits[q];
-            error = slice_score[q];
-            if (bits > bits_limit)
-                error = SCORE_LIMIT;
-
-            if (td->nodes[prev].score < SCORE_LIMIT && error < SCORE_LIMIT)
-                new_score = td->nodes[prev].score + error;
-            else
-                new_score = SCORE_LIMIT;
-            if (td->nodes[cur].prev_node == -1 ||
-                td->nodes[cur].score >= new_score) {
-
-                td->nodes[cur].bits      = bits;
-                td->nodes[cur].score     = new_score;
-                td->nodes[cur].prev_node = prev;
-            }
-        }
-    }
-
-    error = td->nodes[trellis_node + min_quant].score;
-    pq    = trellis_node + min_quant;
-    for (q = min_quant + 1; q < max_quant + 2; q++) {
-        if (td->nodes[trellis_node + q].score <= error) {
-            error = td->nodes[trellis_node + q].score;
-            pq    = trellis_node + q;
-        }
-    }
-
-    return pq;
-}
-
-static int find_quant_thread(AVCodecContext *avctx, void *arg,
-                             int jobnr, int threadnr)
-{
-    ProresContext *ctx = avctx->priv_data;
-    ProresThreadData *td = ctx->tdata + threadnr;
-    int mbs_per_slice = ctx->mbs_per_slice;
-    int x, y = jobnr, mb, q = 0;
-
-    for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
-        while (ctx->mb_width - x < mbs_per_slice)
-            mbs_per_slice >>= 1;
-        q = find_slice_quant(avctx, avctx->coded_frame,
-                             (mb + 1) * TRELLIS_WIDTH, x, y,
-                             mbs_per_slice, td);
-    }
-
-    for (x = ctx->slices_width - 1; x >= 0; x--) {
-        ctx->slice_q[x + y * ctx->slices_width] = td->nodes[q].quant;
-        q = td->nodes[q].prev_node;
-    }
-
-    return 0;
-}
-
-static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
-                        const AVFrame *pic, int *got_packet)
-{
-    ProresContext *ctx = avctx->priv_data;
-    uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
-    uint8_t *picture_size_pos;
-    PutBitContext pb;
-    int x, y, i, mb, q = 0;
-    int sizes[4] = { 0 };
-    int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1);
-    int frame_size, picture_size, slice_size;
-    int pkt_size, ret;
-    uint8_t frame_flags;
-
-    *avctx->coded_frame           = *pic;
-    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
-    avctx->coded_frame->key_frame = 1;
-
-    pkt_size = ctx->frame_size_upper_bound + FF_MIN_BUFFER_SIZE;
-
-    if ((ret = ff_alloc_packet(pkt, pkt_size)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
-        return ret;
-    }
-
-    orig_buf = pkt->data;
-
-    // frame atom
-    orig_buf += 4;                              // frame size
-    bytestream_put_be32  (&orig_buf, FRAME_ID); // frame container ID
-    buf = orig_buf;
-
-    // frame header
-    tmp = buf;
-    buf += 2;                                   // frame header size will be stored here
-    bytestream_put_be16  (&buf, 0);             // version 1
-    bytestream_put_buffer(&buf, ctx->vendor, 4);
-    bytestream_put_be16  (&buf, avctx->width);
-    bytestream_put_be16  (&buf, avctx->height);
-
-    frame_flags = ctx->chroma_factor << 6;
-    if (avctx->flags & CODEC_FLAG_INTERLACED_DCT)
-        frame_flags |= pic->top_field_first ? 0x04 : 0x08;
-    bytestream_put_byte  (&buf, frame_flags);
-
-    bytestream_put_byte  (&buf, 0);             // reserved
-    bytestream_put_byte  (&buf, avctx->color_primaries);
-    bytestream_put_byte  (&buf, avctx->color_trc);
-    bytestream_put_byte  (&buf, avctx->colorspace);
-    bytestream_put_byte  (&buf, 0x40);          // source format and alpha information
-    bytestream_put_byte  (&buf, 0);             // reserved
-    if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
-        bytestream_put_byte  (&buf, 0x03);      // matrix flags - both matrices are present
-        // luma quantisation matrix
-        for (i = 0; i < 64; i++)
-            bytestream_put_byte(&buf, ctx->quant_mat[i]);
-        // chroma quantisation matrix
-        for (i = 0; i < 64; i++)
-            bytestream_put_byte(&buf, ctx->quant_mat[i]);
-    } else {
-        bytestream_put_byte  (&buf, 0x00);      // matrix flags - default matrices are used
-    }
-    bytestream_put_be16  (&tmp, buf - orig_buf); // write back frame header size
-
-    for (ctx->cur_picture_idx = 0;
-         ctx->cur_picture_idx < ctx->pictures_per_frame;
-         ctx->cur_picture_idx++) {
-        // picture header
-        picture_size_pos = buf + 1;
-        bytestream_put_byte  (&buf, 0x40);          // picture header size (in bits)
-        buf += 4;                                   // picture data size will be stored here
-        bytestream_put_be16  (&buf, ctx->slices_per_picture);
-        bytestream_put_byte  (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
-
-        // seek table - will be filled during slice encoding
-        slice_sizes = buf;
-        buf += ctx->slices_per_picture * 2;
-
-        // slices
-        if (!ctx->force_quant) {
-            ret = avctx->execute2(avctx, find_quant_thread, NULL, NULL,
-                                  ctx->mb_height);
-            if (ret)
-                return ret;
-        }
-
-        for (y = 0; y < ctx->mb_height; y++) {
-            int mbs_per_slice = ctx->mbs_per_slice;
-            for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
-                q = ctx->force_quant ? ctx->force_quant
-                                     : ctx->slice_q[mb + y * ctx->slices_width];
-
-                while (ctx->mb_width - x < mbs_per_slice)
-                    mbs_per_slice >>= 1;
-
-                bytestream_put_byte(&buf, slice_hdr_size << 3);
-                slice_hdr = buf;
-                buf += slice_hdr_size - 1;
-                init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)) * 8);
-                encode_slice(avctx, pic, &pb, sizes, x, y, q, mbs_per_slice);
-
-                bytestream_put_byte(&slice_hdr, q);
-                slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];
-                for (i = 0; i < ctx->num_planes - 1; i++) {
-                    bytestream_put_be16(&slice_hdr, sizes[i]);
-                    slice_size += sizes[i];
-                }
-                bytestream_put_be16(&slice_sizes, slice_size);
-                buf += slice_size - slice_hdr_size;
-            }
-        }
-
-        if (ctx->pictures_per_frame == 1)
-            picture_size = buf - picture_size_pos - 6;
-        else
-            picture_size = buf - picture_size_pos + 1;
-        bytestream_put_be32(&picture_size_pos, picture_size);
-    }
-
-    orig_buf -= 8;
-    frame_size = buf - orig_buf;
-    bytestream_put_be32(&orig_buf, frame_size);
-
-    pkt->size   = frame_size;
-    pkt->flags |= AV_PKT_FLAG_KEY;
-    *got_packet = 1;
-
-    return 0;
-}
-
-static av_cold int encode_close(AVCodecContext *avctx)
-{
-    ProresContext *ctx = avctx->priv_data;
-    int i;
-
-    av_freep(&avctx->coded_frame);
-
-    if (ctx->tdata) {
-        for (i = 0; i < avctx->thread_count; i++)
-            av_free(ctx->tdata[i].nodes);
-    }
-    av_freep(&ctx->tdata);
-    av_freep(&ctx->slice_q);
-
-    return 0;
-}
-
-static av_cold int encode_init(AVCodecContext *avctx)
-{
-    ProresContext *ctx = avctx->priv_data;
-    int mps;
-    int i, j;
-    int min_quant, max_quant;
-    int interlaced = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT);
-
-    avctx->bits_per_raw_sample = 10;
-    avctx->coded_frame = avcodec_alloc_frame();
-    if (!avctx->coded_frame)
-        return AVERROR(ENOMEM);
-
-    ff_proresdsp_init(&ctx->dsp);
-    ff_init_scantable(ctx->dsp.dct_permutation, &ctx->scantable,
-                      interlaced ? ff_prores_interlaced_scan
-                                 : ff_prores_progressive_scan);
-
-    mps = ctx->mbs_per_slice;
-    if (mps & (mps - 1)) {
-        av_log(avctx, AV_LOG_ERROR,
-               "there should be an integer power of two MBs per slice\n");
-        return AVERROR(EINVAL);
-    }
-
-    ctx->chroma_factor = avctx->pix_fmt == AV_PIX_FMT_YUV422P10
-                         ? CFACTOR_Y422
-                         : CFACTOR_Y444;
-    ctx->profile_info  = prores_profile_info + ctx->profile;
-    ctx->num_planes    = 3;
-
-    ctx->mb_width      = FFALIGN(avctx->width,  16) >> 4;
-
-    if (interlaced)
-        ctx->mb_height = FFALIGN(avctx->height, 32) >> 5;
-    else
-        ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
-
-    ctx->slices_width  = ctx->mb_width / mps;
-    ctx->slices_width += av_popcount(ctx->mb_width - ctx->slices_width * mps);
-    ctx->slices_per_picture = ctx->mb_height * ctx->slices_width;
-    ctx->pictures_per_frame = 1 + interlaced;
-
-    if (ctx->quant_sel == -1)
-        ctx->quant_mat = prores_quant_matrices[ctx->profile_info->quant];
-    else
-        ctx->quant_mat = prores_quant_matrices[ctx->quant_sel];
-
-    if (strlen(ctx->vendor) != 4) {
-        av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    ctx->force_quant = avctx->global_quality / FF_QP2LAMBDA;
-    if (!ctx->force_quant) {
-        if (!ctx->bits_per_mb) {
-            for (i = 0; i < NUM_MB_LIMITS - 1; i++)
-                if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height *
-                                           ctx->pictures_per_frame)
-                    break;
-            ctx->bits_per_mb   = ctx->profile_info->br_tab[i];
-        } else if (ctx->bits_per_mb < 128) {
-            av_log(avctx, AV_LOG_ERROR, "too few bits per MB, please set at least 128\n");
-            return AVERROR_INVALIDDATA;
-        }
-
-        min_quant = ctx->profile_info->min_quant;
-        max_quant = ctx->profile_info->max_quant;
-        for (i = min_quant; i < MAX_STORED_Q; i++) {
-            for (j = 0; j < 64; j++)
-                ctx->quants[i][j] = ctx->quant_mat[j] * i;
-        }
-
-        ctx->slice_q = av_malloc(ctx->slices_per_picture * sizeof(*ctx->slice_q));
-        if (!ctx->slice_q) {
-            encode_close(avctx);
-            return AVERROR(ENOMEM);
-        }
-
-        ctx->tdata = av_mallocz(avctx->thread_count * sizeof(*ctx->tdata));
-        if (!ctx->tdata) {
-            encode_close(avctx);
-            return AVERROR(ENOMEM);
-        }
-
-        for (j = 0; j < avctx->thread_count; j++) {
-            ctx->tdata[j].nodes = av_malloc((ctx->slices_width + 1)
-                                            * TRELLIS_WIDTH
-                                            * sizeof(*ctx->tdata->nodes));
-            if (!ctx->tdata[j].nodes) {
-                encode_close(avctx);
-                return AVERROR(ENOMEM);
-            }
-            for (i = min_quant; i < max_quant + 2; i++) {
-                ctx->tdata[j].nodes[i].prev_node = -1;
-                ctx->tdata[j].nodes[i].bits      = 0;
-                ctx->tdata[j].nodes[i].score     = 0;
-            }
-        }
-    } else {
-        int ls = 0;
-
-        if (ctx->force_quant > 64) {
-            av_log(avctx, AV_LOG_ERROR, "too large quantiser, maximum is 64\n");
-            return AVERROR_INVALIDDATA;
-        }
-
-        for (j = 0; j < 64; j++) {
-            ctx->quants[0][j] = ctx->quant_mat[j] * ctx->force_quant;
-            ls += av_log2((1 << 11)  / ctx->quants[0][j]) * 2 + 1;
-        }
-
-        ctx->bits_per_mb = ls * 8;
-        if (ctx->chroma_factor == CFACTOR_Y444)
-            ctx->bits_per_mb += ls * 4;
-        if (ctx->num_planes == 4)
-            ctx->bits_per_mb += ls * 4;
-    }
-
-    ctx->frame_size_upper_bound = ctx->pictures_per_frame *
-                                  ctx->slices_per_picture *
-                                  (2 + 2 * ctx->num_planes +
-                                   (mps * ctx->bits_per_mb) / 8)
-                                  + 200;
-
-    avctx->codec_tag   = ctx->profile_info->tag;
-
-    av_log(avctx, AV_LOG_DEBUG,
-           "profile %d, %d slices, interlacing: %s, %d bits per MB\n",
-           ctx->profile, ctx->slices_per_picture * ctx->pictures_per_frame,
-           interlaced ? "yes" : "no", ctx->bits_per_mb);
-    av_log(avctx, AV_LOG_DEBUG, "frame size upper bound: %d\n",
-           ctx->frame_size_upper_bound);
-
-    return 0;
-}
-
-#define OFFSET(x) offsetof(ProresContext, x)
-#define VE     AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
-
-static const AVOption options[] = {
-    { "mbs_per_slice", "macroblocks per slice", OFFSET(mbs_per_slice),
-        AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
-    { "profile",       NULL, OFFSET(profile), AV_OPT_TYPE_INT,
-        { .i64 = PRORES_PROFILE_STANDARD },
-        PRORES_PROFILE_PROXY, PRORES_PROFILE_HQ, VE, "profile" },
-    { "proxy",         NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
-        0, 0, VE, "profile" },
-    { "lt",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
-        0, 0, VE, "profile" },
-    { "standard",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_STANDARD },
-        0, 0, VE, "profile" },
-    { "hq",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
-        0, 0, VE, "profile" },
-    { "vendor", "vendor ID", OFFSET(vendor),
-        AV_OPT_TYPE_STRING, { .str = "Lavc" }, CHAR_MIN, CHAR_MAX, VE },
-    { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
-        AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8192, VE },
-    { "quant_mat", "quantiser matrix", OFFSET(quant_sel), AV_OPT_TYPE_INT,
-        { .i64 = -1 }, -1, QUANT_MAT_DEFAULT, VE, "quant_mat" },
-    { "auto",          NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 },
-        0, 0, VE, "quant_mat" },
-    { "proxy",         NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_PROXY },
-        0, 0, VE, "quant_mat" },
-    { "lt",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_LT },
-        0, 0, VE, "quant_mat" },
-    { "standard",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_STANDARD },
-        0, 0, VE, "quant_mat" },
-    { "hq",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_HQ },
-        0, 0, VE, "quant_mat" },
-    { "default",       NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
-        0, 0, VE, "quant_mat" },
-    { NULL }
-};
-
-static const AVClass proresenc_class = {
-    .class_name = "ProRes encoder",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
-
-AVCodec ff_prores_encoder = {
-    .name           = "prores",
-    .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = AV_CODEC_ID_PRORES,
-    .priv_data_size = sizeof(ProresContext),
-    .init           = encode_init,
-    .close          = encode_close,
-    .encode2        = encode_frame,
-    .capabilities   = CODEC_CAP_SLICE_THREADS,
-    .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"),
-    .pix_fmts       = (const enum AVPixelFormat[]) {
-                          AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_NONE
-                      },
-    .priv_class     = &proresenc_class,
-};
diff --git a/libavcodec/proresenc_anatoliy.c b/libavcodec/proresenc_anatoliy.c
new file mode 100644
index 0000000..8c71ca5
--- /dev/null
+++ b/libavcodec/proresenc_anatoliy.c
@@ -0,0 +1,625 @@
+/*
+ * Apple ProRes encoder
+ *
+ * Copyright (c) 2011 Anatoliy Wasserman
+ *
+ * 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
+ * Apple ProRes encoder (Anatoliy Wasserman version)
+ * Known FOURCCs: 'apch' (HQ), 'apcn' (SD), 'apcs' (LT), 'acpo' (Proxy)
+ */
+
+#include "avcodec.h"
+#include "internal.h"
+#include "put_bits.h"
+#include "bytestream.h"
+#include "dsputil.h"
+
+#define DEFAULT_SLICE_MB_WIDTH 8
+
+#define FF_PROFILE_PRORES_PROXY     0
+#define FF_PROFILE_PRORES_LT        1
+#define FF_PROFILE_PRORES_STANDARD  2
+#define FF_PROFILE_PRORES_HQ        3
+
+static const AVProfile profiles[] = {
+    { FF_PROFILE_PRORES_PROXY,    "apco"},
+    { FF_PROFILE_PRORES_LT,       "apcs"},
+    { FF_PROFILE_PRORES_STANDARD, "apcn"},
+    { FF_PROFILE_PRORES_HQ,       "apch"},
+    { FF_PROFILE_UNKNOWN }
+};
+
+static const int qp_start_table[4] = { 4, 1, 1, 1 };
+static const int qp_end_table[4]   = { 8, 9, 6, 6 };
+static const int bitrate_table[5]  = { 1000, 2100, 3500, 5400 };
+
+static const uint8_t progressive_scan[64] = {
+     0,  1,  8,  9,  2,  3, 10, 11,
+    16, 17, 24, 25, 18, 19, 26, 27,
+     4,  5, 12, 20, 13,  6,  7, 14,
+    21, 28, 29, 22, 15, 23, 30, 31,
+    32, 33, 40, 48, 41, 34, 35, 42,
+    49, 56, 57, 50, 43, 36, 37, 44,
+    51, 58, 59, 52, 45, 38, 39, 46,
+    53, 60, 61, 54, 47, 55, 62, 63
+};
+
+static const uint8_t QMAT_LUMA[4][64] = {
+    {
+         4,  7,  9, 11, 13, 14, 15, 63,
+         7,  7, 11, 12, 14, 15, 63, 63,
+         9, 11, 13, 14, 15, 63, 63, 63,
+        11, 11, 13, 14, 63, 63, 63, 63,
+        11, 13, 14, 63, 63, 63, 63, 63,
+        13, 14, 63, 63, 63, 63, 63, 63,
+        13, 63, 63, 63, 63, 63, 63, 63,
+        63, 63, 63, 63, 63, 63, 63, 63
+    }, {
+         4,  5,  6,  7,  9, 11, 13, 15,
+         5,  5,  7,  8, 11, 13, 15, 17,
+         6,  7,  9, 11, 13, 15, 15, 17,
+         7,  7,  9, 11, 13, 15, 17, 19,
+         7,  9, 11, 13, 14, 16, 19, 23,
+         9, 11, 13, 14, 16, 19, 23, 29,
+         9, 11, 13, 15, 17, 21, 28, 35,
+        11, 13, 16, 17, 21, 28, 35, 41
+    }, {
+         4,  4,  5,  5,  6,  7,  7,  9,
+         4,  4,  5,  6,  7,  7,  9,  9,
+         5,  5,  6,  7,  7,  9,  9, 10,
+         5,  5,  6,  7,  7,  9,  9, 10,
+         5,  6,  7,  7,  8,  9, 10, 12,
+         6,  7,  7,  8,  9, 10, 12, 15,
+         6,  7,  7,  9, 10, 11, 14, 17,
+         7,  7,  9, 10, 11, 14, 17, 21
+    }, {
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  5,
+         4,  4,  4,  4,  4,  4,  5,  5,
+         4,  4,  4,  4,  4,  5,  5,  6,
+         4,  4,  4,  4,  5,  5,  6,  7,
+         4,  4,  4,  4,  5,  6,  7,  7
+    }
+};
+
+static const uint8_t QMAT_CHROMA[4][64] = {
+    {
+         4,  7,  9, 11, 13, 14, 63, 63,
+         7,  7, 11, 12, 14, 63, 63, 63,
+         9, 11, 13, 14, 63, 63, 63, 63,
+        11, 11, 13, 14, 63, 63, 63, 63,
+        11, 13, 14, 63, 63, 63, 63, 63,
+        13, 14, 63, 63, 63, 63, 63, 63,
+        13, 63, 63, 63, 63, 63, 63, 63,
+        63, 63, 63, 63, 63, 63, 63, 63
+    }, {
+         4,  5,  6,  7,  9, 11, 13, 15,
+         5,  5,  7,  8, 11, 13, 15, 17,
+         6,  7,  9, 11, 13, 15, 15, 17,
+         7,  7,  9, 11, 13, 15, 17, 19,
+         7,  9, 11, 13, 14, 16, 19, 23,
+         9, 11, 13, 14, 16, 19, 23, 29,
+         9, 11, 13, 15, 17, 21, 28, 35,
+        11, 13, 16, 17, 21, 28, 35, 41
+    }, {
+         4,  4,  5,  5,  6,  7,  7,  9,
+         4,  4,  5,  6,  7,  7,  9,  9,
+         5,  5,  6,  7,  7,  9,  9, 10,
+         5,  5,  6,  7,  7,  9,  9, 10,
+         5,  6,  7,  7,  8,  9, 10, 12,
+         6,  7,  7,  8,  9, 10, 12, 15,
+         6,  7,  7,  9, 10, 11, 14, 17,
+         7,  7,  9, 10, 11, 14, 17, 21
+    }, {
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  5,
+         4,  4,  4,  4,  4,  4,  5,  5,
+         4,  4,  4,  4,  4,  5,  5,  6,
+         4,  4,  4,  4,  5,  5,  6,  7,
+         4,  4,  4,  4,  5,  6,  7,  7
+    }
+};
+
+
+typedef struct {
+    uint8_t* fill_y;
+    uint8_t* fill_u;
+    uint8_t* fill_v;
+
+    int qmat_luma[16][64];
+    int qmat_chroma[16][64];
+} ProresContext;
+
+static void encode_codeword(PutBitContext *pb, int val, int codebook)
+{
+    unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros,
+            mask;
+
+    /* number of bits to switch between rice and exp golomb */
+    switch_bits = codebook & 3;
+    rice_order  = codebook >> 5;
+    exp_order   = (codebook >> 2) & 7;
+
+    first_exp = ((switch_bits + 1) << rice_order);
+
+    if (val >= first_exp) { /* exp golomb */
+        val -= first_exp;
+        val += (1 << exp_order);
+        exp = av_log2(val);
+        zeros = exp - exp_order + switch_bits + 1;
+        put_bits(pb, zeros, 0);
+        put_bits(pb, exp + 1, val);
+    } else if (rice_order) {
+        mask = (1 << rice_order) - 1;
+        put_bits(pb, (val >> rice_order), 0);
+        put_bits(pb, 1, 1);
+        put_bits(pb, rice_order, val & mask);
+    } else {
+        put_bits(pb, val, 0);
+        put_bits(pb, 1, 1);
+    }
+}
+
+#define QSCALE(qmat,ind,val) ((val) / (qmat[ind]))
+#define TO_GOLOMB(val) ((val << 1) ^ (val >> 31))
+#define DIFF_SIGN(val, sign) ((val >> 31) ^ sign)
+#define IS_NEGATIVE(val) (((val >> 31) ^ -1) + 1)
+#define TO_GOLOMB2(val,sign) (val==0 ? 0 : (val << 1) + sign)
+
+static av_always_inline int get_level(int val)
+{
+    int sign = (val >> 31);
+    return (val ^ sign) - sign;
+}
+
+#define FIRST_DC_CB 0xB8
+
+static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
+
+static void encode_dc_coeffs(PutBitContext *pb, DCTELEM *in,
+        int blocks_per_slice, int *qmat)
+{
+    int prev_dc, code;
+    int i, sign, idx;
+    int new_dc, delta, diff_sign, new_code;
+
+    prev_dc = QSCALE(qmat, 0, in[0] - 16384);
+    code = TO_GOLOMB(prev_dc);
+    encode_codeword(pb, code, FIRST_DC_CB);
+
+    code = 5; sign = 0; idx = 64;
+    for (i = 1; i < blocks_per_slice; i++, idx += 64) {
+        new_dc    = QSCALE(qmat, 0, in[idx] - 16384);
+        delta     = new_dc - prev_dc;
+        diff_sign = DIFF_SIGN(delta, sign);
+        new_code  = TO_GOLOMB2(get_level(delta), diff_sign);
+
+        encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
+
+        code      = new_code;
+        sign      = delta >> 31;
+        prev_dc   = new_dc;
+    }
+}
+
+static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
+        0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
+static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
+        0x28, 0x28, 0x28, 0x4C };
+
+static void encode_ac_coeffs(AVCodecContext *avctx, PutBitContext *pb,
+        DCTELEM *in, int blocks_per_slice, int *qmat)
+{
+    int prev_run = 4;
+    int prev_level = 2;
+
+    int run = 0, level, code, i, j;
+    for (i = 1; i < 64; i++) {
+        int indp = progressive_scan[i];
+        for (j = 0; j < blocks_per_slice; j++) {
+            int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
+            if (val) {
+                encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
+
+                prev_run   = run;
+                run        = 0;
+                level      = get_level(val);
+                code       = level - 1;
+
+                encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
+
+                prev_level = level;
+
+                put_bits(pb, 1, IS_NEGATIVE(val));
+            } else {
+                ++run;
+            }
+        }
+    }
+}
+
+static void get(uint8_t *pixels, int stride, DCTELEM* block)
+{
+    int16_t *p = (int16_t*)pixels;
+    int i, j;
+
+    stride >>= 1;
+    for (i = 0; i < 8; i++) {
+        for (j = 0; j < 8; j++) {
+            block[j] = p[j];
+        }
+        p += stride;
+        block += 8;
+    }
+}
+
+static void fdct_get(uint8_t *pixels, int stride, DCTELEM* block)
+{
+    get(pixels, stride, block);
+    ff_jpeg_fdct_islow_10(block);
+}
+
+static int encode_slice_plane(AVCodecContext *avctx, int mb_count,
+        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;
+    int i, blocks_per_slice;
+    PutBitContext pb;
+
+    block = blocks;
+    for (i = 0; i < mb_count; i++) {
+        fdct_get(src,                  src_stride, block + (0 << 6));
+        fdct_get(src + 8 * src_stride, src_stride, block + ((2 - chroma) << 6));
+        if (!chroma) {
+            fdct_get(src + 16,                  src_stride, block + (1 << 6));
+            fdct_get(src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
+        }
+
+        block += (256 >> chroma);
+        src   += (32  >> chroma);
+    }
+
+    blocks_per_slice = mb_count << (2 - chroma);
+    init_put_bits(&pb, buf, buf_size << 3);
+
+    encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
+    encode_ac_coeffs(avctx, &pb, blocks, blocks_per_slice, qmat);
+
+    flush_put_bits(&pb);
+    return put_bits_ptr(&pb) - pb.buf;
+}
+
+static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
+        uint8_t *dest_y, uint8_t *dest_u, uint8_t *dest_v, int luma_stride,
+        int chroma_stride, unsigned mb_count, uint8_t *buf, unsigned data_size,
+        unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
+        int qp)
+{
+    ProresContext* ctx = avctx->priv_data;
+
+    *y_data_size = encode_slice_plane(avctx, mb_count, dest_y, luma_stride,
+            buf, data_size, ctx->qmat_luma[qp - 1], 0);
+
+    if (!(avctx->flags & CODEC_FLAG_GRAY)) {
+        *u_data_size = encode_slice_plane(avctx, mb_count, dest_u,
+                chroma_stride, buf + *y_data_size, data_size - *y_data_size,
+                ctx->qmat_chroma[qp - 1], 1);
+
+        *v_data_size = encode_slice_plane(avctx, mb_count, dest_v,
+                chroma_stride, buf + *y_data_size + *u_data_size,
+                data_size - *y_data_size - *u_data_size,
+                ctx->qmat_chroma[qp - 1], 1);
+    }
+
+    return *y_data_size + *u_data_size + *v_data_size;
+}
+
+static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
+        unsigned stride, unsigned width, unsigned height, uint16_t *dst,
+        unsigned dst_width, unsigned dst_height)
+{
+
+    int box_width = FFMIN(width - x, dst_width);
+    int box_height = FFMIN(height - y, dst_height);
+    int i, j, src_stride = stride >> 1;
+    uint16_t last_pix, *last_line;
+
+    src += y * src_stride + x;
+    for (i = 0; i < box_height; ++i) {
+        for (j = 0; j < box_width; ++j) {
+            dst[j] = src[j];
+        }
+        last_pix = dst[j - 1];
+        for (; j < dst_width; j++)
+            dst[j] = last_pix;
+        src += src_stride;
+        dst += dst_width;
+    }
+    last_line = dst - dst_width;
+    for (; i < dst_height; i++) {
+        for (j = 0; j < dst_width; ++j) {
+            dst[j] = last_line[j];
+        }
+        dst += dst_width;
+    }
+}
+
+static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
+        int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
+        int unsafe, int *qp)
+{
+    int luma_stride, chroma_stride;
+    int hdr_size = 6, slice_size;
+    uint8_t *dest_y, *dest_u, *dest_v;
+    unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0;
+    ProresContext* ctx = avctx->priv_data;
+    int tgt_bits   = (mb_count * bitrate_table[avctx->profile]) >> 2;
+    int low_bytes  = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
+    int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
+
+    luma_stride   = pic->linesize[0];
+    chroma_stride = pic->linesize[1];
+
+    dest_y = pic->data[0] + (mb_y << 4) * luma_stride   + (mb_x << 5);
+    dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << 4);
+    dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << 4);
+
+    if (unsafe) {
+
+        subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
+                luma_stride, avctx->width, avctx->height,
+                (uint16_t *) ctx->fill_y, mb_count << 4, 16);
+        subimage_with_fill((uint16_t *) pic->data[1], mb_x << 3, mb_y << 4,
+                chroma_stride, avctx->width >> 1, avctx->height,
+                (uint16_t *) ctx->fill_u, mb_count << 3, 16);
+        subimage_with_fill((uint16_t *) pic->data[2], mb_x << 3, mb_y << 4,
+                chroma_stride, avctx->width >> 1, avctx->height,
+                (uint16_t *) ctx->fill_v, mb_count << 3, 16);
+
+        encode_slice_data(avctx, ctx->fill_y, ctx->fill_u, ctx->fill_v,
+                mb_count << 5, mb_count << 4, mb_count, buf + hdr_size,
+                data_size - hdr_size, &y_data_size, &u_data_size, &v_data_size,
+                *qp);
+    } else {
+        slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
+                luma_stride, chroma_stride, mb_count, buf + hdr_size,
+                data_size - hdr_size, &y_data_size, &u_data_size, &v_data_size,
+                *qp);
+
+        if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
+            do {
+                *qp += 1;
+                slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
+                        luma_stride, chroma_stride, mb_count, buf + hdr_size,
+                        data_size - hdr_size, &y_data_size, &u_data_size,
+                        &v_data_size, *qp);
+            } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
+        } else if (slice_size < low_bytes && *qp
+                > qp_start_table[avctx->profile]) {
+            do {
+                *qp -= 1;
+                slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
+                        luma_stride, chroma_stride, mb_count, buf + hdr_size,
+                        data_size - hdr_size, &y_data_size, &u_data_size,
+                        &v_data_size, *qp);
+            } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
+        }
+    }
+
+    buf[0] = hdr_size << 3;
+    buf[1] = *qp;
+    AV_WB16(buf + 2, y_data_size);
+    AV_WB16(buf + 4, u_data_size);
+
+    return hdr_size + y_data_size + u_data_size + v_data_size;
+}
+
+static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
+        uint8_t *buf, const int buf_size)
+{
+    int mb_width = (avctx->width + 15) >> 4;
+    int mb_height = (avctx->height + 15) >> 4;
+    int hdr_size, sl_size, i;
+    int mb_y, sl_data_size, qp;
+    int unsafe_bot, unsafe_right;
+    uint8_t *sl_data, *sl_data_sizes;
+    int slice_per_line = 0, rem = mb_width;
+
+    for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
+        slice_per_line += rem >> i;
+        rem &= (1 << i) - 1;
+    }
+
+    qp = qp_start_table[avctx->profile];
+    hdr_size = 8; sl_data_size = buf_size - hdr_size;
+    sl_data_sizes = buf + hdr_size;
+    sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
+    for (mb_y = 0; mb_y < mb_height; mb_y++) {
+        int mb_x = 0;
+        int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
+        while (mb_x < mb_width) {
+            while (mb_width - mb_x < slice_mb_count)
+                slice_mb_count >>= 1;
+
+            unsafe_bot = (avctx->height & 0xf) && (mb_y == mb_height - 1);
+            unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
+
+            sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
+                    sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp);
+
+            bytestream_put_be16(&sl_data_sizes, sl_size);
+            sl_data           += sl_size;
+            sl_data_size      -= sl_size;
+            mb_x              += slice_mb_count;
+        }
+    }
+
+    buf[0] = hdr_size << 3;
+    AV_WB32(buf + 1, sl_data - buf);
+    AV_WB16(buf + 5, slice_per_line * mb_height);
+    buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4;
+
+    return sl_data - buf;
+}
+
+static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                               const AVFrame *pict, int *got_packet)
+{
+    int header_size = 148;
+    uint8_t *buf;
+    int pic_size, ret;
+    int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + FF_MIN_BUFFER_SIZE; //FIXME choose tighter limit
+
+
+    if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + FF_MIN_BUFFER_SIZE)) < 0)
+        return ret;
+
+    buf = pkt->data;
+    pic_size = prores_encode_picture(avctx, pict, buf + header_size + 8,
+            pkt->size - header_size - 8);
+
+    bytestream_put_be32(&buf, pic_size + 8 + header_size);
+    bytestream_put_buffer(&buf, "icpf", 4);
+
+    bytestream_put_be16(&buf, header_size);
+    bytestream_put_be16(&buf, 0);
+    bytestream_put_buffer(&buf, "fmpg", 4);
+    bytestream_put_be16(&buf, avctx->width);
+    bytestream_put_be16(&buf, avctx->height);
+    *buf++ = 0x83; // {10}(422){00}{00}(frame){11}
+    *buf++ = 0;
+    *buf++ = 2;
+    *buf++ = 2;
+    *buf++ = 6;
+    *buf++ = 32;
+    *buf++ = 0;
+    *buf++ = 3;
+
+    bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile],   64);
+    bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
+
+    pkt->flags |= AV_PKT_FLAG_KEY;
+    pkt->size = pic_size + 8 + header_size;
+    *got_packet = 1;
+
+    return 0;
+}
+
+static void scale_mat(const uint8_t* src, int* dst, int scale)
+{
+    int i;
+    for (i = 0; i < 64; i++)
+        dst[i] = src[i] * scale;
+}
+
+static av_cold int prores_encode_init(AVCodecContext *avctx)
+{
+    int i;
+    ProresContext* ctx = avctx->priv_data;
+
+    if (avctx->pix_fmt != AV_PIX_FMT_YUV422P10) {
+        av_log(avctx, AV_LOG_ERROR, "need YUV422P10\n");
+        return -1;
+    }
+    if (avctx->width & 0x1) {
+        av_log(avctx, AV_LOG_ERROR,
+                "frame width needs to be multiple of 2\n");
+        return -1;
+    }
+
+    if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
+        ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
+        if (!ctx->fill_y)
+            return AVERROR(ENOMEM);
+        ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
+        ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
+    }
+
+    if (avctx->profile == FF_PROFILE_UNKNOWN) {
+        avctx->profile = FF_PROFILE_PRORES_STANDARD;
+        av_log(avctx, AV_LOG_INFO,
+                "encoding with ProRes standard (apcn) profile\n");
+
+    } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
+            || avctx->profile > FF_PROFILE_PRORES_HQ) {
+        av_log(
+                avctx,
+                AV_LOG_ERROR,
+                "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch]\n",
+                avctx->profile);
+        return -1;
+    }
+
+    avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
+
+    for (i = 1; i <= 16; i++) {
+        scale_mat(QMAT_LUMA[avctx->profile]  , ctx->qmat_luma[i - 1]  , i);
+        scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
+    }
+
+    avctx->coded_frame = avcodec_alloc_frame();
+    avctx->coded_frame->key_frame = 1;
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+
+    return 0;
+}
+
+static av_cold int prores_encode_close(AVCodecContext *avctx)
+{
+    ProresContext* ctx = avctx->priv_data;
+    av_freep(&avctx->coded_frame);
+    av_freep(&ctx->fill_y);
+
+    return 0;
+}
+
+AVCodec ff_prores_anatoliy_encoder = {
+    .name           = "prores_anatoliy",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_PRORES,
+    .priv_data_size = sizeof(ProresContext),
+    .init           = prores_encode_init,
+    .close          = prores_encode_close,
+    .encode2        = prores_encode_frame,
+    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
+    .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
+    .capabilities   = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
+    .profiles       = profiles
+};
+
+AVCodec ff_prores_encoder = {
+    .name           = "prores",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_PRORES,
+    .priv_data_size = sizeof(ProresContext),
+    .init           = prores_encode_init,
+    .close          = prores_encode_close,
+    .encode2        = prores_encode_frame,
+    .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
+    .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
+    .capabilities   = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
+    .profiles       = profiles
+};
diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c
new file mode 100644
index 0000000..0462c74
--- /dev/null
+++ b/libavcodec/proresenc_kostya.c
@@ -0,0 +1,1076 @@
+/*
+ * Apple ProRes encoder
+ *
+ * Copyright (c) 2012 Konstantin Shishkov
+ *
+ * This encoder appears to be based on Anatoliy Wassermans considering
+ * similarities in the bugs.
+ *
+ * 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
+ */
+
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "put_bits.h"
+#include "bytestream.h"
+#include "internal.h"
+#include "proresdsp.h"
+#include "proresdata.h"
+
+#define CFACTOR_Y422 2
+#define CFACTOR_Y444 3
+
+#define MAX_MBS_PER_SLICE 8
+
+#define MAX_PLANES 3 // should be increased to 4 when there's AV_PIX_FMT_YUV444AP10
+
+enum {
+    PRORES_PROFILE_PROXY = 0,
+    PRORES_PROFILE_LT,
+    PRORES_PROFILE_STANDARD,
+    PRORES_PROFILE_HQ,
+};
+
+enum {
+    QUANT_MAT_PROXY = 0,
+    QUANT_MAT_LT,
+    QUANT_MAT_STANDARD,
+    QUANT_MAT_HQ,
+    QUANT_MAT_DEFAULT,
+};
+
+static const uint8_t prores_quant_matrices[][64] = {
+    { // proxy
+         4,  7,  9, 11, 13, 14, 15, 63,
+         7,  7, 11, 12, 14, 15, 63, 63,
+         9, 11, 13, 14, 15, 63, 63, 63,
+        11, 11, 13, 14, 63, 63, 63, 63,
+        11, 13, 14, 63, 63, 63, 63, 63,
+        13, 14, 63, 63, 63, 63, 63, 63,
+        13, 63, 63, 63, 63, 63, 63, 63,
+        63, 63, 63, 63, 63, 63, 63, 63,
+    },
+    { // LT
+         4,  5,  6,  7,  9, 11, 13, 15,
+         5,  5,  7,  8, 11, 13, 15, 17,
+         6,  7,  9, 11, 13, 15, 15, 17,
+         7,  7,  9, 11, 13, 15, 17, 19,
+         7,  9, 11, 13, 14, 16, 19, 23,
+         9, 11, 13, 14, 16, 19, 23, 29,
+         9, 11, 13, 15, 17, 21, 28, 35,
+        11, 13, 16, 17, 21, 28, 35, 41,
+    },
+    { // standard
+         4,  4,  5,  5,  6,  7,  7,  9,
+         4,  4,  5,  6,  7,  7,  9,  9,
+         5,  5,  6,  7,  7,  9,  9, 10,
+         5,  5,  6,  7,  7,  9,  9, 10,
+         5,  6,  7,  7,  8,  9, 10, 12,
+         6,  7,  7,  8,  9, 10, 12, 15,
+         6,  7,  7,  9, 10, 11, 14, 17,
+         7,  7,  9, 10, 11, 14, 17, 21,
+    },
+    { // high quality
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  5,
+         4,  4,  4,  4,  4,  4,  5,  5,
+         4,  4,  4,  4,  4,  5,  5,  6,
+         4,  4,  4,  4,  5,  5,  6,  7,
+         4,  4,  4,  4,  5,  6,  7,  7,
+    },
+    { // codec default
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+         4,  4,  4,  4,  4,  4,  4,  4,
+    },
+};
+
+#define NUM_MB_LIMITS 4
+static const int prores_mb_limits[NUM_MB_LIMITS] = {
+    1620, // up to 720x576
+    2700, // up to 960x720
+    6075, // up to 1440x1080
+    9216, // up to 2048x1152
+};
+
+static const struct prores_profile {
+    const char *full_name;
+    uint32_t    tag;
+    int         min_quant;
+    int         max_quant;
+    int         br_tab[NUM_MB_LIMITS];
+    int         quant;
+} prores_profile_info[4] = {
+    {
+        .full_name = "proxy",
+        .tag       = MKTAG('a', 'p', 'c', 'o'),
+        .min_quant = 4,
+        .max_quant = 8,
+        .br_tab    = { 300, 242, 220, 194 },
+        .quant     = QUANT_MAT_PROXY,
+    },
+    {
+        .full_name = "LT",
+        .tag       = MKTAG('a', 'p', 'c', 's'),
+        .min_quant = 1,
+        .max_quant = 9,
+        .br_tab    = { 720, 560, 490, 440 },
+        .quant     = QUANT_MAT_LT,
+    },
+    {
+        .full_name = "standard",
+        .tag       = MKTAG('a', 'p', 'c', 'n'),
+        .min_quant = 1,
+        .max_quant = 6,
+        .br_tab    = { 1050, 808, 710, 632 },
+        .quant     = QUANT_MAT_STANDARD,
+    },
+    {
+        .full_name = "high quality",
+        .tag       = MKTAG('a', 'p', 'c', 'h'),
+        .min_quant = 1,
+        .max_quant = 6,
+        .br_tab    = { 1566, 1216, 1070, 950 },
+        .quant     = QUANT_MAT_HQ,
+    }
+// for 4444 profile bitrate numbers are { 2350, 1828, 1600, 1425 }
+};
+
+#define TRELLIS_WIDTH 16
+#define SCORE_LIMIT   INT_MAX / 2
+
+struct TrellisNode {
+    int prev_node;
+    int quant;
+    int bits;
+    int score;
+};
+
+#define MAX_STORED_Q 16
+
+typedef struct ProresThreadData {
+    DECLARE_ALIGNED(16, DCTELEM, 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;
+} ProresThreadData;
+
+typedef struct ProresContext {
+    AVClass *class;
+    DECLARE_ALIGNED(16, DCTELEM, 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];
+    const uint8_t *quant_mat;
+
+    ProresDSPContext dsp;
+    ScanTable  scantable;
+
+    int mb_width, mb_height;
+    int mbs_per_slice;
+    int num_chroma_blocks, chroma_factor;
+    int slices_width;
+    int slices_per_picture;
+    int pictures_per_frame; // 1 for progressive, 2 for interlaced
+    int cur_picture_idx;
+    int num_planes;
+    int bits_per_mb;
+    int force_quant;
+
+    char *vendor;
+    int quant_sel;
+
+    int frame_size_upper_bound;
+
+    int profile;
+    const struct prores_profile *profile_info;
+
+    int *slice_q;
+
+    ProresThreadData *tdata;
+} ProresContext;
+
+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,
+                           int mbs_per_slice, int blocks_per_mb, int is_chroma)
+{
+    const uint16_t *esrc;
+    const int mb_width = 4 * blocks_per_mb;
+    int elinesize;
+    int i, j, k;
+
+    for (i = 0; i < mbs_per_slice; i++, src += mb_width) {
+        if (x >= w) {
+            memset(blocks, 0, 64 * (mbs_per_slice - i) * blocks_per_mb
+                              * sizeof(*blocks));
+            return;
+        }
+        if (x + mb_width <= w && y + 16 <= h) {
+            esrc      = src;
+            elinesize = linesize;
+        } else {
+            int bw, bh, pix;
+
+            esrc      = emu_buf;
+            elinesize = 16 * sizeof(*emu_buf);
+
+            bw = FFMIN(w - x, mb_width);
+            bh = FFMIN(h - y, 16);
+
+            for (j = 0; j < bh; j++) {
+                memcpy(emu_buf + j * 16,
+                       (const uint8_t*)src + j * linesize,
+                       bw * sizeof(*src));
+                pix = emu_buf[j * 16 + bw - 1];
+                for (k = bw; k < mb_width; k++)
+                    emu_buf[j * 16 + k] = pix;
+            }
+            for (; j < 16; j++)
+                memcpy(emu_buf + j * 16,
+                       emu_buf + (bh - 1) * 16,
+                       mb_width * sizeof(*emu_buf));
+        }
+        if (!is_chroma) {
+            ctx->dsp.fdct(esrc, elinesize, blocks);
+            blocks += 64;
+            if (blocks_per_mb > 2) {
+                ctx->dsp.fdct(esrc + 8, elinesize, blocks);
+                blocks += 64;
+            }
+            ctx->dsp.fdct(esrc + elinesize * 4, elinesize, blocks);
+            blocks += 64;
+            if (blocks_per_mb > 2) {
+                ctx->dsp.fdct(esrc + elinesize * 4 + 8, elinesize, blocks);
+                blocks += 64;
+            }
+        } else {
+            ctx->dsp.fdct(esrc, elinesize, blocks);
+            blocks += 64;
+            ctx->dsp.fdct(esrc + elinesize * 4, elinesize, blocks);
+            blocks += 64;
+            if (blocks_per_mb > 2) {
+                ctx->dsp.fdct(esrc + 8, elinesize, blocks);
+                blocks += 64;
+                ctx->dsp.fdct(esrc + elinesize * 4 + 8, elinesize, blocks);
+                blocks += 64;
+            }
+        }
+
+        x += mb_width;
+    }
+}
+
+/**
+ * Write an unsigned rice/exp golomb codeword.
+ */
+static inline void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
+{
+    unsigned int rice_order, exp_order, switch_bits, switch_val;
+    int exponent;
+
+    /* number of prefix bits to switch between Rice and expGolomb */
+    switch_bits = (codebook & 3) + 1;
+    rice_order  =  codebook >> 5;       /* rice code order */
+    exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */
+
+    switch_val  = switch_bits << rice_order;
+
+    if (val >= switch_val) {
+        val -= switch_val - (1 << exp_order);
+        exponent = av_log2(val);
+
+        put_bits(pb, exponent - exp_order + switch_bits, 0);
+        put_bits(pb, exponent + 1, val);
+    } else {
+        exponent = val >> rice_order;
+
+        if (exponent)
+            put_bits(pb, exponent, 0);
+        put_bits(pb, 1, 1);
+        if (rice_order)
+            put_sbits(pb, rice_order, val);
+    }
+}
+
+#define GET_SIGN(x)  ((x) >> 31)
+#define MAKE_CODE(x) (((x) << 1) ^ GET_SIGN(x))
+
+static void encode_dcs(PutBitContext *pb, DCTELEM *blocks,
+                       int blocks_per_slice, int scale)
+{
+    int i;
+    int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
+
+    prev_dc = (blocks[0] - 0x4000) / scale;
+    encode_vlc_codeword(pb, FIRST_DC_CB, MAKE_CODE(prev_dc));
+    sign     = 0;
+    codebook = 3;
+    blocks  += 64;
+
+    for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
+        dc       = (blocks[0] - 0x4000) / scale;
+        delta    = dc - prev_dc;
+        new_sign = GET_SIGN(delta);
+        delta    = (delta ^ sign) - sign;
+        code     = MAKE_CODE(delta);
+        encode_vlc_codeword(pb, ff_prores_dc_codebook[codebook], code);
+        codebook = (code + (code & 1)) >> 1;
+        codebook = FFMIN(codebook, 3);
+        sign     = new_sign;
+        prev_dc  = dc;
+    }
+}
+
+static void encode_acs(PutBitContext *pb, DCTELEM *blocks,
+                       int blocks_per_slice,
+                       int plane_size_factor,
+                       const uint8_t *scan, const int16_t *qmat)
+{
+    int idx, i;
+    int run, level, run_cb, lev_cb;
+    int max_coeffs, abs_level;
+
+    max_coeffs = blocks_per_slice << 6;
+    run_cb     = ff_prores_run_to_cb_index[4];
+    lev_cb     = ff_prores_lev_to_cb_index[2];
+    run        = 0;
+
+    for (i = 1; i < 64; i++) {
+        for (idx = scan[i]; idx < max_coeffs; idx += 64) {
+            level = blocks[idx] / qmat[scan[i]];
+            if (level) {
+                abs_level = FFABS(level);
+                encode_vlc_codeword(pb, ff_prores_ac_codebook[run_cb], run);
+                encode_vlc_codeword(pb, ff_prores_ac_codebook[lev_cb],
+                                    abs_level - 1);
+                put_sbits(pb, 1, GET_SIGN(level));
+
+                run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
+                lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
+                run    = 0;
+            } else {
+                run++;
+            }
+        }
+    }
+}
+
+static int encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
+                              const uint16_t *src, int linesize,
+                              int mbs_per_slice, DCTELEM *blocks,
+                              int blocks_per_mb, int plane_size_factor,
+                              const int16_t *qmat)
+{
+    int blocks_per_slice, saved_pos;
+
+    saved_pos = put_bits_count(pb);
+    blocks_per_slice = mbs_per_slice * blocks_per_mb;
+
+    encode_dcs(pb, blocks, blocks_per_slice, qmat[0]);
+    encode_acs(pb, blocks, blocks_per_slice, plane_size_factor,
+               ctx->scantable.permutated, qmat);
+    flush_put_bits(pb);
+
+    return (put_bits_count(pb) - saved_pos) >> 3;
+}
+
+static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
+                        PutBitContext *pb,
+                        int sizes[4], int x, int y, int quant,
+                        int mbs_per_slice)
+{
+    ProresContext *ctx = avctx->priv_data;
+    int i, xp, yp;
+    int total_size = 0;
+    const uint16_t *src;
+    int slice_width_factor = av_log2(mbs_per_slice);
+    int num_cblocks, pwidth, linesize, line_add;
+    int plane_factor, is_chroma;
+    uint16_t *qmat;
+
+    if (ctx->pictures_per_frame == 1)
+        line_add = 0;
+    else
+        line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
+
+    if (ctx->force_quant) {
+        qmat = ctx->quants[0];
+    } else if (quant < MAX_STORED_Q) {
+        qmat = ctx->quants[quant];
+    } else {
+        qmat = ctx->custom_q;
+        for (i = 0; i < 64; i++)
+            qmat[i] = ctx->quant_mat[i] * quant;
+    }
+
+    for (i = 0; i < ctx->num_planes; i++) {
+        is_chroma    = (i == 1 || i == 2);
+        plane_factor = slice_width_factor + 2;
+        if (is_chroma)
+            plane_factor += ctx->chroma_factor - 3;
+        if (!is_chroma || ctx->chroma_factor == CFACTOR_Y444) {
+            xp          = x << 4;
+            yp          = y << 4;
+            num_cblocks = 4;
+            pwidth      = avctx->width;
+        } else {
+            xp          = x << 3;
+            yp          = y << 4;
+            num_cblocks = 2;
+            pwidth      = avctx->width >> 1;
+        }
+
+        linesize = pic->linesize[i] * ctx->pictures_per_frame;
+        src = (const uint16_t*)(pic->data[i] + yp * linesize +
+                                line_add * pic->linesize[i]) + xp;
+
+        get_slice_data(ctx, src, linesize, xp, yp,
+                       pwidth, avctx->height / ctx->pictures_per_frame,
+                       ctx->blocks[0], ctx->emu_buf,
+                       mbs_per_slice, num_cblocks, is_chroma);
+        sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
+                                      mbs_per_slice, ctx->blocks[0],
+                                      num_cblocks, plane_factor,
+                                      qmat);
+        total_size += sizes[i];
+    }
+    return total_size;
+}
+
+static inline int estimate_vlc(unsigned codebook, int val)
+{
+    unsigned int rice_order, exp_order, switch_bits, switch_val;
+    int exponent;
+
+    /* number of prefix bits to switch between Rice and expGolomb */
+    switch_bits = (codebook & 3) + 1;
+    rice_order  =  codebook >> 5;       /* rice code order */
+    exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */
+
+    switch_val  = switch_bits << rice_order;
+
+    if (val >= switch_val) {
+        val -= switch_val - (1 << exp_order);
+        exponent = av_log2(val);
+
+        return exponent * 2 - exp_order + switch_bits + 1;
+    } else {
+        return (val >> rice_order) + rice_order + 1;
+    }
+}
+
+static int estimate_dcs(int *error, DCTELEM *blocks, int blocks_per_slice,
+                        int scale)
+{
+    int i;
+    int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
+    int bits;
+
+    prev_dc  = (blocks[0] - 0x4000) / scale;
+    bits     = estimate_vlc(FIRST_DC_CB, MAKE_CODE(prev_dc));
+    sign     = 0;
+    codebook = 3;
+    blocks  += 64;
+    *error  += FFABS(blocks[0] - 0x4000) % scale;
+
+    for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
+        dc       = (blocks[0] - 0x4000) / scale;
+        *error  += FFABS(blocks[0] - 0x4000) % scale;
+        delta    = dc - prev_dc;
+        new_sign = GET_SIGN(delta);
+        delta    = (delta ^ sign) - sign;
+        code     = MAKE_CODE(delta);
+        bits    += estimate_vlc(ff_prores_dc_codebook[codebook], code);
+        codebook = (code + (code & 1)) >> 1;
+        codebook = FFMIN(codebook, 3);
+        sign     = new_sign;
+        prev_dc  = dc;
+    }
+
+    return bits;
+}
+
+static int estimate_acs(int *error, DCTELEM *blocks, int blocks_per_slice,
+                        int plane_size_factor,
+                        const uint8_t *scan, const int16_t *qmat)
+{
+    int idx, i;
+    int run, level, run_cb, lev_cb;
+    int max_coeffs, abs_level;
+    int bits = 0;
+
+    max_coeffs = blocks_per_slice << 6;
+    run_cb     = ff_prores_run_to_cb_index[4];
+    lev_cb     = ff_prores_lev_to_cb_index[2];
+    run        = 0;
+
+    for (i = 1; i < 64; i++) {
+        for (idx = scan[i]; idx < max_coeffs; idx += 64) {
+            level   = blocks[idx] / qmat[scan[i]];
+            *error += FFABS(blocks[idx]) % qmat[scan[i]];
+            if (level) {
+                abs_level = FFABS(level);
+                bits += estimate_vlc(ff_prores_ac_codebook[run_cb], run);
+                bits += estimate_vlc(ff_prores_ac_codebook[lev_cb],
+                                     abs_level - 1) + 1;
+
+                run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
+                lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
+                run    = 0;
+            } else {
+                run++;
+            }
+        }
+    }
+
+    return bits;
+}
+
+static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
+                                const uint16_t *src, int linesize,
+                                int mbs_per_slice,
+                                int blocks_per_mb, int plane_size_factor,
+                                const int16_t *qmat, ProresThreadData *td)
+{
+    int blocks_per_slice;
+    int bits;
+
+    blocks_per_slice = mbs_per_slice * blocks_per_mb;
+
+    bits  = estimate_dcs(error, td->blocks[plane], blocks_per_slice, qmat[0]);
+    bits += estimate_acs(error, td->blocks[plane], blocks_per_slice,
+                         plane_size_factor, ctx->scantable.permutated, qmat);
+
+    return FFALIGN(bits, 8);
+}
+
+static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
+                            int trellis_node, int x, int y, int mbs_per_slice,
+                            ProresThreadData *td)
+{
+    ProresContext *ctx = avctx->priv_data;
+    int i, q, pq, xp, yp;
+    const uint16_t *src;
+    int slice_width_factor = av_log2(mbs_per_slice);
+    int num_cblocks[MAX_PLANES], pwidth;
+    int plane_factor[MAX_PLANES], is_chroma[MAX_PLANES];
+    const int min_quant = ctx->profile_info->min_quant;
+    const int max_quant = ctx->profile_info->max_quant;
+    int error, bits, bits_limit;
+    int mbs, prev, cur, new_score;
+    int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
+    int overquant;
+    uint16_t *qmat;
+    int linesize[4], line_add;
+
+    if (ctx->pictures_per_frame == 1)
+        line_add = 0;
+    else
+        line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
+    mbs = x + mbs_per_slice;
+
+    for (i = 0; i < ctx->num_planes; i++) {
+        is_chroma[i]    = (i == 1 || i == 2);
+        plane_factor[i] = slice_width_factor + 2;
+        if (is_chroma[i])
+            plane_factor[i] += ctx->chroma_factor - 3;
+        if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
+            xp             = x << 4;
+            yp             = y << 4;
+            num_cblocks[i] = 4;
+            pwidth         = avctx->width;
+        } else {
+            xp             = x << 3;
+            yp             = y << 4;
+            num_cblocks[i] = 2;
+            pwidth         = avctx->width >> 1;
+        }
+
+        linesize[i] = pic->linesize[i] * ctx->pictures_per_frame;
+        src = (const uint16_t*)(pic->data[i] + yp * linesize[i] +
+                                line_add * pic->linesize[i]) + xp;
+
+        get_slice_data(ctx, src, linesize[i], xp, yp,
+                       pwidth, avctx->height / ctx->pictures_per_frame,
+                       td->blocks[i], td->emu_buf,
+                       mbs_per_slice, num_cblocks[i], is_chroma[i]);
+    }
+
+    for (q = min_quant; q < max_quant + 2; q++) {
+        td->nodes[trellis_node + q].prev_node = -1;
+        td->nodes[trellis_node + q].quant     = q;
+    }
+
+    // todo: maybe perform coarser quantising to fit into frame size when needed
+    for (q = min_quant; q <= max_quant; q++) {
+        bits  = 0;
+        error = 0;
+        for (i = 0; i < ctx->num_planes; i++) {
+            bits += estimate_slice_plane(ctx, &error, i,
+                                         src, linesize[i],
+                                         mbs_per_slice,
+                                         num_cblocks[i], plane_factor[i],
+                                         ctx->quants[q], td);
+        }
+        if (bits > 65000 * 8) {
+            error = SCORE_LIMIT;
+            break;
+        }
+        slice_bits[q]  = bits;
+        slice_score[q] = error;
+    }
+    if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
+        slice_bits[max_quant + 1]  = slice_bits[max_quant];
+        slice_score[max_quant + 1] = slice_score[max_quant] + 1;
+        overquant = max_quant;
+    } else {
+        for (q = max_quant + 1; q < 128; q++) {
+            bits  = 0;
+            error = 0;
+            if (q < MAX_STORED_Q) {
+                qmat = ctx->quants[q];
+            } else {
+                qmat = td->custom_q;
+                for (i = 0; i < 64; i++)
+                    qmat[i] = ctx->quant_mat[i] * q;
+            }
+            for (i = 0; i < ctx->num_planes; i++) {
+                bits += estimate_slice_plane(ctx, &error, i,
+                                             src, linesize[i],
+                                             mbs_per_slice,
+                                             num_cblocks[i], plane_factor[i],
+                                             qmat, td);
+            }
+            if (bits <= ctx->bits_per_mb * mbs_per_slice)
+                break;
+        }
+
+        slice_bits[max_quant + 1]  = bits;
+        slice_score[max_quant + 1] = error;
+        overquant = q;
+    }
+    td->nodes[trellis_node + max_quant + 1].quant = overquant;
+
+    bits_limit = mbs * ctx->bits_per_mb;
+    for (pq = min_quant; pq < max_quant + 2; pq++) {
+        prev = trellis_node - TRELLIS_WIDTH + pq;
+
+        for (q = min_quant; q < max_quant + 2; q++) {
+            cur = trellis_node + q;
+
+            bits  = td->nodes[prev].bits + slice_bits[q];
+            error = slice_score[q];
+            if (bits > bits_limit)
+                error = SCORE_LIMIT;
+
+            if (td->nodes[prev].score < SCORE_LIMIT && error < SCORE_LIMIT)
+                new_score = td->nodes[prev].score + error;
+            else
+                new_score = SCORE_LIMIT;
+            if (td->nodes[cur].prev_node == -1 ||
+                td->nodes[cur].score >= new_score) {
+
+                td->nodes[cur].bits      = bits;
+                td->nodes[cur].score     = new_score;
+                td->nodes[cur].prev_node = prev;
+            }
+        }
+    }
+
+    error = td->nodes[trellis_node + min_quant].score;
+    pq    = trellis_node + min_quant;
+    for (q = min_quant + 1; q < max_quant + 2; q++) {
+        if (td->nodes[trellis_node + q].score <= error) {
+            error = td->nodes[trellis_node + q].score;
+            pq    = trellis_node + q;
+        }
+    }
+
+    return pq;
+}
+
+static int find_quant_thread(AVCodecContext *avctx, void *arg,
+                             int jobnr, int threadnr)
+{
+    ProresContext *ctx = avctx->priv_data;
+    ProresThreadData *td = ctx->tdata + threadnr;
+    int mbs_per_slice = ctx->mbs_per_slice;
+    int x, y = jobnr, mb, q = 0;
+
+    for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
+        while (ctx->mb_width - x < mbs_per_slice)
+            mbs_per_slice >>= 1;
+        q = find_slice_quant(avctx, avctx->coded_frame,
+                             (mb + 1) * TRELLIS_WIDTH, x, y,
+                             mbs_per_slice, td);
+    }
+
+    for (x = ctx->slices_width - 1; x >= 0; x--) {
+        ctx->slice_q[x + y * ctx->slices_width] = td->nodes[q].quant;
+        q = td->nodes[q].prev_node;
+    }
+
+    return 0;
+}
+
+static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                        const AVFrame *pic, int *got_packet)
+{
+    ProresContext *ctx = avctx->priv_data;
+    uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
+    uint8_t *picture_size_pos;
+    PutBitContext pb;
+    int x, y, i, mb, q = 0;
+    int sizes[4] = { 0 };
+    int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1);
+    int frame_size, picture_size, slice_size;
+    int pkt_size, ret;
+    uint8_t frame_flags;
+
+    *avctx->coded_frame           = *pic;
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    avctx->coded_frame->key_frame = 1;
+
+    pkt_size = ctx->frame_size_upper_bound + FF_MIN_BUFFER_SIZE;
+
+    if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size)) < 0)
+        return ret;
+
+    orig_buf = pkt->data;
+
+    // frame atom
+    orig_buf += 4;                              // frame size
+    bytestream_put_be32  (&orig_buf, FRAME_ID); // frame container ID
+    buf = orig_buf;
+
+    // frame header
+    tmp = buf;
+    buf += 2;                                   // frame header size will be stored here
+    bytestream_put_be16  (&buf, 0);             // version 1
+    bytestream_put_buffer(&buf, ctx->vendor, 4);
+    bytestream_put_be16  (&buf, avctx->width);
+    bytestream_put_be16  (&buf, avctx->height);
+
+    frame_flags = ctx->chroma_factor << 6;
+    if (avctx->flags & CODEC_FLAG_INTERLACED_DCT)
+        frame_flags |= pic->top_field_first ? 0x04 : 0x08;
+    bytestream_put_byte  (&buf, frame_flags);
+
+    bytestream_put_byte  (&buf, 0);             // reserved
+    bytestream_put_byte  (&buf, avctx->color_primaries);
+    bytestream_put_byte  (&buf, avctx->color_trc);
+    bytestream_put_byte  (&buf, avctx->colorspace);
+    bytestream_put_byte  (&buf, 0x40);          // source format and alpha information
+    bytestream_put_byte  (&buf, 0);             // reserved
+    if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
+        bytestream_put_byte  (&buf, 0x03);      // matrix flags - both matrices are present
+        // luma quantisation matrix
+        for (i = 0; i < 64; i++)
+            bytestream_put_byte(&buf, ctx->quant_mat[i]);
+        // chroma quantisation matrix
+        for (i = 0; i < 64; i++)
+            bytestream_put_byte(&buf, ctx->quant_mat[i]);
+    } else {
+        bytestream_put_byte  (&buf, 0x00);      // matrix flags - default matrices are used
+    }
+    bytestream_put_be16  (&tmp, buf - orig_buf); // write back frame header size
+
+    for (ctx->cur_picture_idx = 0;
+         ctx->cur_picture_idx < ctx->pictures_per_frame;
+         ctx->cur_picture_idx++) {
+        // picture header
+        picture_size_pos = buf + 1;
+        bytestream_put_byte  (&buf, 0x40);          // picture header size (in bits)
+        buf += 4;                                   // picture data size will be stored here
+        bytestream_put_be16  (&buf, ctx->slices_per_picture);
+        bytestream_put_byte  (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
+
+        // seek table - will be filled during slice encoding
+        slice_sizes = buf;
+        buf += ctx->slices_per_picture * 2;
+
+        // slices
+        if (!ctx->force_quant) {
+            ret = avctx->execute2(avctx, find_quant_thread, NULL, NULL,
+                                  ctx->mb_height);
+            if (ret)
+                return ret;
+        }
+
+        for (y = 0; y < ctx->mb_height; y++) {
+            int mbs_per_slice = ctx->mbs_per_slice;
+            for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
+                q = ctx->force_quant ? ctx->force_quant
+                                     : ctx->slice_q[mb + y * ctx->slices_width];
+
+                while (ctx->mb_width - x < mbs_per_slice)
+                    mbs_per_slice >>= 1;
+
+                bytestream_put_byte(&buf, slice_hdr_size << 3);
+                slice_hdr = buf;
+                buf += slice_hdr_size - 1;
+                init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)) * 8);
+                encode_slice(avctx, pic, &pb, sizes, x, y, q, mbs_per_slice);
+
+                bytestream_put_byte(&slice_hdr, q);
+                slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];
+                for (i = 0; i < ctx->num_planes - 1; i++) {
+                    bytestream_put_be16(&slice_hdr, sizes[i]);
+                    slice_size += sizes[i];
+                }
+                bytestream_put_be16(&slice_sizes, slice_size);
+                buf += slice_size - slice_hdr_size;
+            }
+        }
+
+        picture_size = buf - (picture_size_pos - 1);
+        bytestream_put_be32(&picture_size_pos, picture_size);
+    }
+
+    orig_buf -= 8;
+    frame_size = buf - orig_buf;
+    bytestream_put_be32(&orig_buf, frame_size);
+
+    pkt->size   = frame_size;
+    pkt->flags |= AV_PKT_FLAG_KEY;
+    *got_packet = 1;
+
+    return 0;
+}
+
+static av_cold int encode_close(AVCodecContext *avctx)
+{
+    ProresContext *ctx = avctx->priv_data;
+    int i;
+
+    av_freep(&avctx->coded_frame);
+
+    if (ctx->tdata) {
+        for (i = 0; i < avctx->thread_count; i++)
+            av_free(ctx->tdata[i].nodes);
+    }
+    av_freep(&ctx->tdata);
+    av_freep(&ctx->slice_q);
+
+    return 0;
+}
+
+static av_cold int encode_init(AVCodecContext *avctx)
+{
+    ProresContext *ctx = avctx->priv_data;
+    int mps;
+    int i, j;
+    int min_quant, max_quant;
+    int interlaced = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT);
+
+    avctx->bits_per_raw_sample = 10;
+    avctx->coded_frame = avcodec_alloc_frame();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    ff_proresdsp_init(&ctx->dsp, avctx);
+    ff_init_scantable(ctx->dsp.dct_permutation, &ctx->scantable,
+                      interlaced ? ff_prores_interlaced_scan
+                                 : ff_prores_progressive_scan);
+
+    mps = ctx->mbs_per_slice;
+    if (mps & (mps - 1)) {
+        av_log(avctx, AV_LOG_ERROR,
+               "there should be an integer power of two MBs per slice\n");
+        return AVERROR(EINVAL);
+    }
+
+    ctx->chroma_factor = avctx->pix_fmt == AV_PIX_FMT_YUV422P10
+                         ? CFACTOR_Y422
+                         : CFACTOR_Y444;
+    ctx->profile_info  = prores_profile_info + ctx->profile;
+    ctx->num_planes    = 3;
+
+    ctx->mb_width      = FFALIGN(avctx->width,  16) >> 4;
+
+    if (interlaced)
+        ctx->mb_height = FFALIGN(avctx->height, 32) >> 5;
+    else
+        ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
+
+    ctx->slices_width  = ctx->mb_width / mps;
+    ctx->slices_width += av_popcount(ctx->mb_width - ctx->slices_width * mps);
+    ctx->slices_per_picture = ctx->mb_height * ctx->slices_width;
+    ctx->pictures_per_frame = 1 + interlaced;
+
+    if (ctx->quant_sel == -1)
+        ctx->quant_mat = prores_quant_matrices[ctx->profile_info->quant];
+    else
+        ctx->quant_mat = prores_quant_matrices[ctx->quant_sel];
+
+    if (strlen(ctx->vendor) != 4) {
+        av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    ctx->force_quant = avctx->global_quality / FF_QP2LAMBDA;
+    if (!ctx->force_quant) {
+        if (!ctx->bits_per_mb) {
+            for (i = 0; i < NUM_MB_LIMITS - 1; i++)
+                if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height *
+                                           ctx->pictures_per_frame)
+                    break;
+            ctx->bits_per_mb   = ctx->profile_info->br_tab[i];
+        } else if (ctx->bits_per_mb < 128) {
+            av_log(avctx, AV_LOG_ERROR, "too few bits per MB, please set at least 128\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        min_quant = ctx->profile_info->min_quant;
+        max_quant = ctx->profile_info->max_quant;
+        for (i = min_quant; i < MAX_STORED_Q; i++) {
+            for (j = 0; j < 64; j++)
+                ctx->quants[i][j] = ctx->quant_mat[j] * i;
+        }
+
+        ctx->slice_q = av_malloc(ctx->slices_per_picture * sizeof(*ctx->slice_q));
+        if (!ctx->slice_q) {
+            encode_close(avctx);
+            return AVERROR(ENOMEM);
+        }
+
+        ctx->tdata = av_mallocz(avctx->thread_count * sizeof(*ctx->tdata));
+        if (!ctx->tdata) {
+            encode_close(avctx);
+            return AVERROR(ENOMEM);
+        }
+
+        for (j = 0; j < avctx->thread_count; j++) {
+            ctx->tdata[j].nodes = av_malloc((ctx->slices_width + 1)
+                                            * TRELLIS_WIDTH
+                                            * sizeof(*ctx->tdata->nodes));
+            if (!ctx->tdata[j].nodes) {
+                encode_close(avctx);
+                return AVERROR(ENOMEM);
+            }
+            for (i = min_quant; i < max_quant + 2; i++) {
+                ctx->tdata[j].nodes[i].prev_node = -1;
+                ctx->tdata[j].nodes[i].bits      = 0;
+                ctx->tdata[j].nodes[i].score     = 0;
+            }
+        }
+    } else {
+        int ls = 0;
+
+        if (ctx->force_quant > 64) {
+            av_log(avctx, AV_LOG_ERROR, "too large quantiser, maximum is 64\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        for (j = 0; j < 64; j++) {
+            ctx->quants[0][j] = ctx->quant_mat[j] * ctx->force_quant;
+            ls += av_log2((1 << 11)  / ctx->quants[0][j]) * 2 + 1;
+        }
+
+        ctx->bits_per_mb = ls * 8;
+        if (ctx->chroma_factor == CFACTOR_Y444)
+            ctx->bits_per_mb += ls * 4;
+        if (ctx->num_planes == 4)
+            ctx->bits_per_mb += ls * 4;
+    }
+
+    ctx->frame_size_upper_bound = ctx->pictures_per_frame *
+                                  ctx->slices_per_picture *
+                                  (2 + 2 * ctx->num_planes +
+                                   (mps * ctx->bits_per_mb) / 8)
+                                  + 200;
+
+    avctx->codec_tag   = ctx->profile_info->tag;
+
+    av_log(avctx, AV_LOG_DEBUG,
+           "profile %d, %d slices, interlacing: %s, %d bits per MB\n",
+           ctx->profile, ctx->slices_per_picture * ctx->pictures_per_frame,
+           interlaced ? "yes" : "no", ctx->bits_per_mb);
+    av_log(avctx, AV_LOG_DEBUG, "frame size upper bound: %d\n",
+           ctx->frame_size_upper_bound);
+
+    return 0;
+}
+
+#define OFFSET(x) offsetof(ProresContext, x)
+#define VE     AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+
+static const AVOption options[] = {
+    { "mbs_per_slice", "macroblocks per slice", OFFSET(mbs_per_slice),
+        AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
+    { "profile",       NULL, OFFSET(profile), AV_OPT_TYPE_INT,
+        { .i64 = PRORES_PROFILE_STANDARD },
+        PRORES_PROFILE_PROXY, PRORES_PROFILE_HQ, VE, "profile" },
+    { "proxy",         NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
+        0, 0, VE, "profile" },
+    { "lt",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
+        0, 0, VE, "profile" },
+    { "standard",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_STANDARD },
+        0, 0, VE, "profile" },
+    { "hq",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
+        0, 0, VE, "profile" },
+    { "vendor", "vendor ID", OFFSET(vendor),
+        AV_OPT_TYPE_STRING, { .str = "Lavc" }, CHAR_MIN, CHAR_MAX, VE },
+    { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
+        AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8192, VE },
+    { "quant_mat", "quantiser matrix", OFFSET(quant_sel), AV_OPT_TYPE_INT,
+        { .i64 = -1 }, -1, QUANT_MAT_DEFAULT, VE, "quant_mat" },
+    { "auto",          NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 },
+        0, 0, VE, "quant_mat" },
+    { "proxy",         NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_PROXY },
+        0, 0, VE, "quant_mat" },
+    { "lt",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_LT },
+        0, 0, VE, "quant_mat" },
+    { "standard",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_STANDARD },
+        0, 0, VE, "quant_mat" },
+    { "hq",            NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_HQ },
+        0, 0, VE, "quant_mat" },
+    { "default",       NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
+        0, 0, VE, "quant_mat" },
+    { NULL }
+};
+
+static const AVClass proresenc_class = {
+    .class_name = "ProRes encoder",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_prores_kostya_encoder = {
+    .name           = "prores_kostya",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_PRORES,
+    .priv_data_size = sizeof(ProresContext),
+    .init           = encode_init,
+    .close          = encode_close,
+    .encode2        = encode_frame,
+    .capabilities   = CODEC_CAP_SLICE_THREADS,
+    .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"),
+    .pix_fmts       = (const enum AVPixelFormat[]) {
+                          AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_NONE
+                      },
+    .priv_class     = &proresenc_class,
+};
diff --git a/libavcodec/psymodel.c b/libavcodec/psymodel.c
index a2af611..a4a7cbb 100644
--- a/libavcodec/psymodel.c
+++ b/libavcodec/psymodel.c
@@ -2,20 +2,20 @@
  * audio encoder psychoacoustic model
  * Copyright (C) 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -103,6 +103,9 @@
     if (avctx->cutoff > 0)
         cutoff_coeff = 2.0 * avctx->cutoff / avctx->sample_rate;
 
+    if (!cutoff_coeff && avctx->codec_id == AV_CODEC_ID_AAC)
+        cutoff_coeff = 2.0 * AAC_CUTOFF(avctx) / avctx->sample_rate;
+
     if (cutoff_coeff)
     ctx->fcoeffs = ff_iir_filter_init_coeffs(avctx, FF_FILTER_TYPE_BUTTERWORTH,
                                              FF_FILTER_MODE_LOWPASS, FILT_ORDER,
diff --git a/libavcodec/psymodel.h b/libavcodec/psymodel.h
index 34b20d7..37c8191 100644
--- a/libavcodec/psymodel.h
+++ b/libavcodec/psymodel.h
@@ -2,20 +2,20 @@
  * audio encoder psychoacoustic model
  * Copyright (C) 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,6 +29,8 @@
 /** maximum number of channels */
 #define PSY_MAX_CHANS 20
 
+#define AAC_CUTOFF(s) (s->bit_rate ? FFMIN3(4000 + s->bit_rate/8, 12000 + s->bit_rate/32, s->sample_rate / 2) : (s->sample_rate / 2))
+
 /**
  * single band psychoacoustic information
  */
diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c
index 0496257..c0a872e 100644
--- a/libavcodec/pthread.c
+++ b/libavcodec/pthread.c
@@ -6,20 +6,20 @@
  * to Michael Niedermayer <michaelni@gmx.at> for writing initial
  * implementation.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -43,6 +43,7 @@
 #include <sys/param.h>
 #endif
 #include <sys/types.h>
+#include <sys/param.h>
 #include <sys/sysctl.h>
 #endif
 #if HAVE_SYSCONF
@@ -58,6 +59,8 @@
 #include <pthread.h>
 #elif HAVE_W32THREADS
 #include "w32pthreads.h"
+#elif HAVE_OS2THREADS
+#include "os2threads.h"
 #endif
 
 typedef int (action_func)(AVCodecContext *c, void *arg);
@@ -77,6 +80,7 @@
     pthread_cond_t current_job_cond;
     pthread_mutex_t current_job_lock;
     int current_job;
+    unsigned int current_execute;
     int done;
 } ThreadContext;
 
@@ -127,8 +131,8 @@
     /**
      * Array of progress values used by ff_thread_get_buffer().
      */
-    int     progress[MAX_BUFFERS][2];
-    uint8_t progress_used[MAX_BUFFERS];
+    volatile int     progress[MAX_BUFFERS][2];
+    volatile uint8_t progress_used[MAX_BUFFERS];
 
     AVFrame *requested_frame;       ///< AVFrame the codec passed to get_buffer()
 } PerThreadContext;
@@ -158,7 +162,7 @@
  * limit the number of threads to 16 for automatic detection */
 #define MAX_AUTO_THREADS 16
 
-static int get_logical_cpus(AVCodecContext *avctx)
+int ff_get_logical_cpus(AVCodecContext *avctx)
 {
     int ret, nb_cpus = 1;
 #if HAVE_SCHED_GETAFFINITY && defined(CPU_COUNT)
@@ -188,6 +192,10 @@
     nb_cpus = sysconf(_SC_NPROCESSORS_ONLN);
 #endif
     av_log(avctx, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus);
+
+    if  (avctx->height)
+        nb_cpus = FFMIN(nb_cpus, (avctx->height+15)/16);
+
     return nb_cpus;
 }
 
@@ -197,6 +205,7 @@
     AVCodecContext *avctx = v;
     ThreadContext *c = avctx->thread_opaque;
     int our_job = c->job_count;
+    int last_execute = 0;
     int thread_count = avctx->thread_count;
     int self_id;
 
@@ -207,7 +216,9 @@
             if (c->current_job == thread_count + c->job_count)
                 pthread_cond_signal(&c->last_job_cond);
 
-            pthread_cond_wait(&c->current_job_cond, &c->current_job_lock);
+            while (last_execute == c->current_execute && !c->done)
+                pthread_cond_wait(&c->current_job_cond, &c->current_job_lock);
+            last_execute = c->current_execute;
             our_job = self_id;
 
             if (c->done) {
@@ -227,7 +238,8 @@
 
 static av_always_inline void avcodec_thread_park_workers(ThreadContext *c, int thread_count)
 {
-    pthread_cond_wait(&c->last_job_cond, &c->current_job_lock);
+    while (c->current_job != thread_count + c->job_count)
+        pthread_cond_wait(&c->last_job_cond, &c->current_job_lock);
     pthread_mutex_unlock(&c->current_job_lock);
 }
 
@@ -276,6 +288,7 @@
         c->rets = &dummy_ret;
         c->rets_count = 1;
     }
+    c->current_execute++;
     pthread_cond_broadcast(&c->current_job_cond);
 
     avcodec_thread_park_workers(c, avctx->thread_count);
@@ -297,7 +310,7 @@
     int thread_count = avctx->thread_count;
 
     if (!thread_count) {
-        int nb_cpus = get_logical_cpus(avctx);
+        int nb_cpus = ff_get_logical_cpus(avctx);
         // use number of cores + 1 as thread count if there is more than one
         if (nb_cpus > 1)
             thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
@@ -359,20 +372,17 @@
     AVCodecContext *avctx = p->avctx;
     const AVCodec *codec = avctx->codec;
 
+    pthread_mutex_lock(&p->mutex);
     while (1) {
-        if (p->state == STATE_INPUT_READY && !fctx->die) {
-            pthread_mutex_lock(&p->mutex);
+        int i;
             while (p->state == STATE_INPUT_READY && !fctx->die)
                 pthread_cond_wait(&p->input_cond, &p->mutex);
-            pthread_mutex_unlock(&p->mutex);
-        }
 
         if (fctx->die) break;
 
-        if (!codec->update_thread_context && avctx->thread_safe_callbacks)
+        if (!codec->update_thread_context && (avctx->thread_safe_callbacks || avctx->get_buffer == avcodec_default_get_buffer))
             ff_thread_finish_setup(avctx);
 
-        pthread_mutex_lock(&p->mutex);
         avcodec_get_frame_defaults(&p->frame);
         p->got_frame = 0;
         p->result = codec->decode(avctx, &p->frame, &p->got_frame, &p->avpkt);
@@ -383,14 +393,19 @@
 
         if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx);
 
+        pthread_mutex_lock(&p->progress_mutex);
+        for (i = 0; i < MAX_BUFFERS; i++)
+            if (p->progress_used[i] && (p->got_frame || p->result<0 || avctx->codec_id != AV_CODEC_ID_H264)) {
+                p->progress[i][0] = INT_MAX;
+                p->progress[i][1] = INT_MAX;
+            }
         p->state = STATE_INPUT_READY;
 
-        pthread_mutex_lock(&p->progress_mutex);
+        pthread_cond_broadcast(&p->progress_cond);
         pthread_cond_signal(&p->output_cond);
         pthread_mutex_unlock(&p->progress_mutex);
-
-        pthread_mutex_unlock(&p->mutex);
     }
+    pthread_mutex_unlock(&p->mutex);
 
     return NULL;
 }
@@ -436,6 +451,7 @@
     }
 
     if (for_user) {
+        dst->delay       = src->thread_count - 1;
         dst->coded_frame = src->coded_frame;
     } else {
         if (dst->codec->update_thread_context)
@@ -472,6 +488,7 @@
 
     dst->frame_number     = src->frame_number;
     dst->reordered_opaque = src->reordered_opaque;
+    dst->thread_safe_callbacks = src->thread_safe_callbacks;
 
     if (src->slice_count && src->slice_offset) {
         if (dst->slice_count < src->slice_count) {
@@ -494,7 +511,7 @@
 static void free_progress(AVFrame *f)
 {
     PerThreadContext *p = f->owner->thread_opaque;
-    int *progress = f->thread_opaque;
+    volatile int *progress = f->thread_opaque;
 
     p->progress_used[(progress - p->progress[0]) / 2] = 0;
 }
@@ -660,7 +677,7 @@
 void ff_thread_report_progress(AVFrame *f, int n, int field)
 {
     PerThreadContext *p;
-    int *progress = f->thread_opaque;
+    volatile int *progress = f->thread_opaque;
 
     if (!progress || progress[field] >= n) return;
 
@@ -678,7 +695,7 @@
 void ff_thread_await_progress(AVFrame *f, int n, int field)
 {
     PerThreadContext *p;
-    int *progress = f->thread_opaque;
+    volatile int *progress = f->thread_opaque;
 
     if (!progress || progress[field] >= n) return;
 
@@ -698,6 +715,10 @@
 
     if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return;
 
+    if(p->state == STATE_SETUP_FINISHED){
+        av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n");
+    }
+
     pthread_mutex_lock(&p->progress_mutex);
     p->state = STATE_SETUP_FINISHED;
     pthread_cond_broadcast(&p->progress_cond);
@@ -718,6 +739,7 @@
                 pthread_cond_wait(&p->output_cond, &p->progress_mutex);
             pthread_mutex_unlock(&p->progress_mutex);
         }
+        p->got_frame = 0;
     }
 }
 
@@ -743,6 +765,7 @@
 
         if (p->thread_init)
             pthread_join(p->thread, NULL);
+        p->thread_init=0;
 
         if (codec->close)
             codec->close(p->avctx);
@@ -787,7 +810,9 @@
     int i, err = 0;
 
     if (!thread_count) {
-        int nb_cpus = get_logical_cpus(avctx);
+        int nb_cpus = ff_get_logical_cpus(avctx);
+        if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv)
+            nb_cpus = 1;
         // use number of cores + 1 as thread count if there is more than one
         if (nb_cpus > 1)
             thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
@@ -856,8 +881,10 @@
 
         if (err) goto error;
 
-        if (!pthread_create(&p->thread, NULL, frame_worker_thread, p))
-            p->thread_init = 1;
+        err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p));
+        p->thread_init= !err;
+        if(!p->thread_init)
+            goto error;
     }
 
     return 0;
@@ -895,7 +922,7 @@
     }
 }
 
-static int *allocate_progress(PerThreadContext *p)
+static volatile int *allocate_progress(PerThreadContext *p)
 {
     int i;
 
@@ -912,26 +939,41 @@
     return p->progress[i];
 }
 
+int ff_thread_can_start_frame(AVCodecContext *avctx)
+{
+    PerThreadContext *p = avctx->thread_opaque;
+    if ((avctx->active_thread_type&FF_THREAD_FRAME) && p->state != STATE_SETTING_UP &&
+        (avctx->codec->update_thread_context || (!avctx->thread_safe_callbacks &&
+                avctx->get_buffer != avcodec_default_get_buffer))) {
+        return 0;
+    }
+    return 1;
+}
+
 int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f)
 {
     PerThreadContext *p = avctx->thread_opaque;
-    int *progress, err;
+    int err;
+    volatile int *progress;
 
     f->owner = avctx;
 
+    ff_init_buffer_info(avctx, f);
+
     if (!(avctx->active_thread_type&FF_THREAD_FRAME)) {
         f->thread_opaque = NULL;
         return avctx->get_buffer(avctx, f);
     }
 
     if (p->state != STATE_SETTING_UP &&
-        (avctx->codec->update_thread_context || !avctx->thread_safe_callbacks)) {
+        (avctx->codec->update_thread_context || (!avctx->thread_safe_callbacks &&
+                avctx->get_buffer != avcodec_default_get_buffer))) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n");
         return -1;
     }
 
     pthread_mutex_lock(&p->parent->buffer_mutex);
-    f->thread_opaque = progress = allocate_progress(p);
+    f->thread_opaque = (int*)(progress = allocate_progress(p));
 
     if (!progress) {
         pthread_mutex_unlock(&p->parent->buffer_mutex);
@@ -945,10 +987,10 @@
         avctx->get_buffer == avcodec_default_get_buffer) {
         err = avctx->get_buffer(avctx, f);
     } else {
+        pthread_mutex_lock(&p->progress_mutex);
         p->requested_frame = f;
         p->state = STATE_GET_BUFFER;
-        pthread_mutex_lock(&p->progress_mutex);
-        pthread_cond_signal(&p->progress_cond);
+        pthread_cond_broadcast(&p->progress_cond);
 
         while (p->state != STATE_SETTING_UP)
             pthread_cond_wait(&p->progress_cond, &p->progress_mutex);
diff --git a/libavcodec/ptx.c b/libavcodec/ptx.c
index e6835e6..c9adb6d 100644
--- a/libavcodec/ptx.c
+++ b/libavcodec/ptx.c
@@ -2,20 +2,20 @@
  * V.Flash PTX (.ptx) image decoder
  * Copyright (c) 2007 Ivo van Poorten
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -59,7 +59,7 @@
         return -1;
     }
 
-    avctx->pix_fmt = AV_PIX_FMT_RGB555;
+    avctx->pix_fmt = AV_PIX_FMT_BGR555LE;
 
     if (buf_end - buf < offset)
         return AVERROR_INVALIDDATA;
@@ -86,13 +86,7 @@
     stride = p->linesize[0];
 
     for (y = 0; y < h && buf_end - buf >= w * bytes_per_pixel; y++) {
-#if HAVE_BIGENDIAN
-        unsigned int x;
-        for (x=0; x<w*bytes_per_pixel; x+=bytes_per_pixel)
-            AV_WN16(ptr+x, AV_RL16(buf+x));
-#else
         memcpy(ptr, buf, w*bytes_per_pixel);
-#endif
         ptr += stride;
         buf += w*bytes_per_pixel;
     }
diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h
index f32b7fd..f02965e 100644
--- a/libavcodec/put_bits.h
+++ b/libavcodec/put_bits.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -33,6 +33,7 @@
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/log.h"
+#include "libavutil/avassert.h"
 #include "mathops.h"
 #include "config.h"
 
@@ -130,7 +131,7 @@
     unsigned int bit_buf;
     int bit_left;
 
-    assert(n <= 31 && value < (1U << n));
+    av_assert2(n <= 31 && value < (1U << n));
 
     bit_buf = s->bit_buf;
     bit_left = s->bit_left;
@@ -139,6 +140,7 @@
 #ifdef BITSTREAM_WRITER_LE
     bit_buf |= value << (32 - bit_left);
     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;
@@ -152,6 +154,7 @@
     } else {
         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;
@@ -165,7 +168,7 @@
 
 static inline void put_sbits(PutBitContext *pb, int n, int32_t value)
 {
-    assert(n >= 0 && n <= 31);
+    av_assert2(n >= 0 && n <= 31);
 
     put_bits(pb, n, value & ((1<<n)-1));
 }
@@ -201,8 +204,8 @@
  */
 static inline void skip_put_bytes(PutBitContext *s, int n)
 {
-        assert((put_bits_count(s)&7)==0);
-        assert(s->bit_left==32);
+        av_assert2((put_bits_count(s)&7)==0);
+        av_assert2(s->bit_left==32);
         s->buf_ptr += n;
 }
 
diff --git a/libavcodec/qcelpdata.h b/libavcodec/qcelpdata.h
index 319833e..d58e9f8 100644
--- a/libavcodec/qcelpdata.h
+++ b/libavcodec/qcelpdata.h
@@ -2,20 +2,20 @@
  * QCELP decoder
  * Copyright (c) 2007 Reynaldo H. Verdejo Pinochet
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,7 +26,7 @@
  * @file
  * Data tables for the QCELP decoder
  * @author Reynaldo H. Verdejo Pinochet
- * @remark Libav merging spearheaded by Kenan Gillet
+ * @remark FFmpeg merging spearheaded by Kenan Gillet
  * @remark Development mentored by Benjamin Larson
  */
 
diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c
index edb1d24..7f27081 100644
--- a/libavcodec/qcelpdec.c
+++ b/libavcodec/qcelpdec.c
@@ -2,20 +2,20 @@
  * QCELP decoder
  * Copyright (c) 2007 Reynaldo H. Verdejo Pinochet
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -23,7 +23,7 @@
  * @file
  * QCELP decoder
  * @author Reynaldo H. Verdejo Pinochet
- * @remark Libav merging spearheaded by Kenan Gillet
+ * @remark FFmpeg merging spearheaded by Kenan Gillet
  * @remark Development mentored by Benjamin Larson
  */
 
diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c
index 4d3b391..3a77e7f 100644
--- a/libavcodec/qdm2.c
+++ b/libavcodec/qdm2.c
@@ -5,20 +5,20 @@
  * Copyright (c) 2005 Alex Beregszaszi
  * Copyright (c) 2005 Roberto Togni
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -169,7 +169,7 @@
     /// I/O data
     const uint8_t *compressed_data;
     int compressed_size;
-    float output_buffer[QDM2_MAX_FRAME_SIZE * 2];
+    float output_buffer[QDM2_MAX_FRAME_SIZE * MPA_MAX_CHANNELS * 2];
 
     /// Synthesis filter
     MPADSPContext mpadsp;
@@ -343,7 +343,14 @@
 
     /* stage-3, optional */
     if (flag) {
-        int tmp = vlc_stage3_values[value];
+        int tmp;
+
+        if (value >= 60) {
+            av_log(0, AV_LOG_ERROR, "value %d in qdm2_get_vlc too large\n", value);
+            return 0;
+        }
+
+        tmp= vlc_stage3_values[value];
 
         if ((value & ~3) > 0)
             tmp += get_bits (gb, (value >> 2));
@@ -761,7 +768,7 @@
  * @param sb_min    lower subband processed (sb_min included)
  * @param sb_max    higher subband processed (sb_max excluded)
  */
-static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int length, int sb_min, int sb_max)
+static int synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int length, int sb_min, int sb_max)
 {
     int sb, j, k, n, ch, run, channels;
     int joined_stereo, zero_encoding, chs;
@@ -775,7 +782,7 @@
         for (sb=sb_min; sb < sb_max; sb++)
             build_sb_samples_from_noise (q, sb);
 
-        return;
+        return 0;
     }
 
     for (sb = sb_min; sb < sb_max; sb++) {
@@ -881,10 +888,11 @@
                     case 30:
                         if (get_bits_left(gb) >= 4) {
                             unsigned index = qdm2_get_vlc(gb, &vlc_tab_type30, 0, 1);
-                            if (index < FF_ARRAY_ELEMS(type30_dequant)) {
-                                samples[0] = type30_dequant[index];
-                            } else
-                                samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx);
+                            if (index >= FF_ARRAY_ELEMS(type30_dequant)) {
+                                av_log(NULL, AV_LOG_ERROR, "index %d out of type30_dequant array\n", index);
+                                return AVERROR_INVALIDDATA;
+                            }
+                            samples[0] = type30_dequant[index];
                         } else
                             samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx);
 
@@ -900,11 +908,12 @@
                                 type34_first = 0;
                             } else {
                                 unsigned index = qdm2_get_vlc(gb, &vlc_tab_type34, 0, 1);
-                                if (index < FF_ARRAY_ELEMS(type34_delta)) {
-                                    samples[0] = type34_delta[index] / type34_div + type34_predictor;
-                                    type34_predictor = samples[0];
-                                } else
-                                    samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx);
+                                if (index >= FF_ARRAY_ELEMS(type34_delta)) {
+                                    av_log(NULL, AV_LOG_ERROR, "index %d out of type34_delta array\n", index);
+                                    return AVERROR_INVALIDDATA;
+                                }
+                                samples[0] = type34_delta[index] / type34_div + type34_predictor;
+                                type34_predictor = samples[0];
                             }
                         } else {
                             samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx);
@@ -939,6 +948,7 @@
             } // j loop
         } // channel loop
     } // subband loop
+    return 0;
 }
 
 
@@ -950,23 +960,26 @@
  * @param quantized_coeffs    pointer to quantized_coeffs[ch][0]
  * @param gb        bitreader context
  */
-static void init_quantized_coeffs_elem0 (int8_t *quantized_coeffs, GetBitContext *gb)
+static int init_quantized_coeffs_elem0 (int8_t *quantized_coeffs, GetBitContext *gb)
 {
     int i, k, run, level, diff;
 
     if (get_bits_left(gb) < 16)
-        return;
+        return -1;
     level = qdm2_get_vlc(gb, &vlc_tab_level, 0, 2);
 
     quantized_coeffs[0] = level;
 
     for (i = 0; i < 7; ) {
         if (get_bits_left(gb) < 16)
-            break;
+            return -1;
         run = qdm2_get_vlc(gb, &vlc_tab_run, 0, 1) + 1;
 
+        if (i + run >= 8)
+            return -1;
+
         if (get_bits_left(gb) < 16)
-            break;
+            return -1;
         diff = qdm2_get_se_vlc(&vlc_tab_diff, gb, 2);
 
         for (k = 1; k <= run; k++)
@@ -975,6 +988,7 @@
         level += diff;
         i += run;
     }
+    return 0;
 }
 
 
@@ -1049,7 +1063,7 @@
  * @param q       context
  * @param node    pointer to node with packet
  */
-static void process_subpacket_9 (QDM2Context *q, QDM2SubPNode *node)
+static int process_subpacket_9 (QDM2Context *q, QDM2SubPNode *node)
 {
     GetBitContext gb;
     int i, j, k, n, ch, run, level, diff;
@@ -1067,6 +1081,9 @@
                 run = qdm2_get_vlc(&gb, &vlc_tab_run, 0, 1) + 1;
                 diff = qdm2_get_se_vlc(&vlc_tab_diff, &gb, 2);
 
+                if (j + run >= 8)
+                    return -1;
+
                 for (k = 1; k <= run; k++)
                     q->quantized_coeffs[ch][i][j + k] = (level + ((k*diff) / run));
 
@@ -1078,6 +1095,8 @@
     for (ch = 0; ch < q->nb_channels; ch++)
         for (i = 0; i < 8; i++)
             q->quantized_coeffs[ch][0][i] = 0;
+
+    return 0;
 }
 
 
@@ -1338,9 +1357,14 @@
     local_int_10 = 1 << (q->group_order - duration - 1);
     offset = 1;
 
-    while (1) {
+    while (get_bits_left(gb)>0) {
         if (q->superblocktype_2_3) {
             while ((n = qdm2_get_vlc(gb, &vlc_tab_fft_tone_offset[local_int_8], 1, 2)) < 2) {
+                if (get_bits_left(gb)<0) {
+                    if(local_int_4 < q->group_size)
+                        av_log(0, AV_LOG_ERROR, "overread in qdm2_fft_decode_tones()\n");
+                    return;
+                }
                 offset = 1;
                 if (n == 0) {
                     local_int_4 += local_int_10;
@@ -1768,8 +1792,10 @@
 
     avctx->channels = s->nb_channels = s->channels = AV_RB32(extradata);
     extradata += 4;
-    if (s->channels > MPA_MAX_CHANNELS)
+    if (s->channels > MPA_MAX_CHANNELS) {
+        av_log(avctx, AV_LOG_ERROR, "Too many channels\n");
         return AVERROR_INVALIDDATA;
+    }
 
     avctx->sample_rate = AV_RB32(extradata);
     extradata += 4;
@@ -1794,6 +1820,7 @@
     // something like max decodable tones
     s->group_order = av_log2(s->group_size) + 1;
     s->frame_size = s->group_size / 16; // 16 iterations per super block
+
     if (s->frame_size > QDM2_MAX_FRAME_SIZE)
         return AVERROR_INVALIDDATA;
 
@@ -1867,6 +1894,9 @@
     int ch, i;
     const int frame_size = (q->frame_size * q->channels);
 
+    if((unsigned)frame_size > FF_ARRAY_ELEMS(q->output_buffer)/2)
+        return -1;
+
     /* select input buffer */
     q->compressed_data = in;
     q->compressed_size = q->checksum_size;
diff --git a/libavcodec/qdm2_tablegen.c b/libavcodec/qdm2_tablegen.c
index 59d82df..a7a9fb6 100644
--- a/libavcodec/qdm2_tablegen.c
+++ b/libavcodec/qdm2_tablegen.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/qdm2_tablegen.h b/libavcodec/qdm2_tablegen.h
index bb73d92..585edfd 100644
--- a/libavcodec/qdm2_tablegen.h
+++ b/libavcodec/qdm2_tablegen.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/qdm2data.h b/libavcodec/qdm2data.h
index ad6ea88..355d613 100644
--- a/libavcodec/qdm2data.h
+++ b/libavcodec/qdm2data.h
@@ -5,20 +5,20 @@
  * Copyright (c) 2005 Alex Beregszaszi
  * Copyright (c) 2005 Roberto Togni
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/qdrw.c b/libavcodec/qdrw.c
index 934a1fc..55fc930 100644
--- a/libavcodec/qdrw.c
+++ b/libavcodec/qdrw.c
@@ -2,20 +2,20 @@
  * QuickDraw (qdrw) codec
  * Copyright (c) 2004 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -91,7 +91,7 @@
         buf++;
         b = *buf++;
         buf++;
-        pal[idx] = (r << 16) | (g << 8) | b;
+        pal[idx] = 0xFF << 24 | r << 16 | g << 8 | b;
     }
     p->palette_has_changed = 1;
 
@@ -146,8 +146,9 @@
 }
 
 static av_cold int decode_init(AVCodecContext *avctx){
-//    QdrawContext * const a = avctx->priv_data;
+    QdrawContext * const a = avctx->priv_data;
 
+    avcodec_get_frame_defaults(&a->pic);
     avctx->pix_fmt= AV_PIX_FMT_PAL8;
 
     return 0;
diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c
index 1ee764b..4d8781e 100644
--- a/libavcodec/qpeg.c
+++ b/libavcodec/qpeg.c
@@ -2,20 +2,20 @@
  * QPEG codec
  * Copyright (c) 2004 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,8 +29,7 @@
 
 typedef struct QpegContext{
     AVCodecContext *avctx;
-    AVFrame pic;
-    uint8_t *refdata;
+    AVFrame pic, ref;
     uint32_t pal[256];
     GetByteContext buffer;
 } QpegContext;
@@ -120,9 +119,12 @@
     int filled = 0;
     int orig_height;
 
+    if(!refdata)
+        refdata= dst;
+
     /* copy prev frame */
     for(i = 0; i < height; i++)
-        memcpy(refdata + (i * width), dst + (i * stride), width);
+        memcpy(dst + (i * stride), refdata + (i * stride), width);
 
     orig_height = height;
     height--;
@@ -133,7 +135,7 @@
 
         if(delta) {
             /* motion compensation */
-            while((code & 0xF0) == 0xF0) {
+            while(bytestream2_get_bytes_left(&qctx->buffer) > 0 && (code & 0xF0) == 0xF0) {
                 if(delta == 1) {
                     int me_idx;
                     int me_w, me_h, me_x, me_y;
@@ -166,10 +168,10 @@
                                me_x, me_y, me_w, me_h, filled, height);
                     else {
                         /* do motion compensation */
-                        me_plane = refdata + (filled + me_x) + (height - me_y) * width;
+                        me_plane = refdata + (filled + me_x) + (height - me_y) * stride;
                         for(j = 0; j < me_h; j++) {
                             for(i = 0; i < me_w; i++)
-                                dst[filled + i - (j * stride)] = me_plane[i - (j * width)];
+                                dst[filled + i - (j * stride)] = me_plane[i - (j * stride)];
                         }
                     }
                 }
@@ -190,17 +192,24 @@
                     filled = 0;
                     dst -= stride;
                     height--;
+                    if(height < 0)
+                        break;
                 }
             }
         } else if(code >= 0xC0) { /* copy code: 0xC0..0xDF */
             code &= 0x1F;
 
+            if(code + 1 > bytestream2_get_bytes_left(&qctx->buffer))
+                break;
+
             for(i = 0; i <= code; i++) {
                 dst[filled++] = bytestream2_get_byte(&qctx->buffer);
                 if(filled >= width) {
                     filled = 0;
                     dst -= stride;
                     height--;
+                    if(height < 0)
+                        break;
                 }
             }
         } else if(code >= 0x80) { /* skip code: 0x80..0xBF */
@@ -245,7 +254,8 @@
 {
     uint8_t ctable[128];
     QpegContext * const a = avctx->priv_data;
-    AVFrame * const p = &a->pic;
+    AVFrame *  p = &a->pic;
+    AVFrame * ref= &a->ref;
     uint8_t* outdata;
     int delta;
     const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
@@ -256,9 +266,14 @@
     }
 
     bytestream2_init(&a->buffer, avpkt->data, avpkt->size);
-    p->reference = 3;
-    if (avctx->reget_buffer(avctx, p) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
+
+    if(ref->data[0])
+        avctx->release_buffer(avctx, ref);
+    FFSWAP(AVFrame, *ref, *p);
+
+    p->reference= 3;
+    if(avctx->get_buffer(avctx, p) < 0){
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
     outdata = a->pic.data[0];
@@ -270,7 +285,7 @@
     if(delta == 0x10) {
         qpeg_decode_intra(a, outdata, a->pic.linesize[0], avctx->width, avctx->height);
     } else {
-        qpeg_decode_inter(a, outdata, a->pic.linesize[0], avctx->width, avctx->height, delta, ctable, a->refdata);
+        qpeg_decode_inter(a, outdata, a->pic.linesize[0], avctx->width, avctx->height, delta, ctable, a->ref.data[0]);
     }
 
     /* make the palette available on the way out */
@@ -289,9 +304,10 @@
 static av_cold int decode_init(AVCodecContext *avctx){
     QpegContext * const a = avctx->priv_data;
 
+    avcodec_get_frame_defaults(&a->pic);
+    avcodec_get_frame_defaults(&a->ref);
     a->avctx = avctx;
     avctx->pix_fmt= AV_PIX_FMT_PAL8;
-    a->refdata = av_malloc(avctx->width * avctx->height);
 
     return 0;
 }
@@ -299,11 +315,13 @@
 static av_cold int decode_end(AVCodecContext *avctx){
     QpegContext * const a = avctx->priv_data;
     AVFrame * const p = &a->pic;
+    AVFrame * const ref= &a->ref;
 
     if(p->data[0])
         avctx->release_buffer(avctx, p);
+    if(ref->data[0])
+        avctx->release_buffer(avctx, ref);
 
-    av_free(a->refdata);
     return 0;
 }
 
diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c
index 3f173a5..d02dffa 100644
--- a/libavcodec/qtrle.c
+++ b/libavcodec/qtrle.c
@@ -2,20 +2,20 @@
  * Quicktime Animation (RLE) Video Decoder
  * Copyright (C) 2004 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -62,6 +62,15 @@
     unsigned char *rgb = s->frame.data[0];
     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
     int skip;
+    /* skip & 0x80 appears to mean 'start a new line', which can be interpreted
+     * as 'go to next line' during the decoding of a frame but is 'go to first
+     * line' at the beginning. Since we always interpret it as 'go to next line'
+     * in the decoding loop (which makes code simpler/faster), the first line
+     * would not be counted, so we count one more.
+     * See: https://ffmpeg.org/trac/ffmpeg/ticket/226
+     * In the following decoding loop, row_ptr will be the position of the
+     * _next_ row. */
+    lines_to_change++;
 
     while (lines_to_change) {
         skip     =              bytestream2_get_byte(&s->g);
@@ -70,12 +79,15 @@
             break;
         if(skip & 0x80) {
             lines_to_change--;
-            row_ptr += row_inc;
             pixel_ptr = row_ptr + 2 * (skip & 0x7f);
+            row_ptr += row_inc;
         } else
             pixel_ptr += 2 * skip;
         CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
 
+        if(rle_code == -1)
+            continue;
+
         if (rle_code < 0) {
             /* decode the run length code */
             rle_code = -rle_code;
@@ -114,6 +126,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 */
 
         while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
             if (rle_code == 0) {
@@ -168,6 +181,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 */
 
         while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
             if (rle_code == 0) {
@@ -217,6 +231,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 */
 
         while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
             if (rle_code == 0) {
@@ -260,6 +275,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 */
 
         while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
             if (rle_code == 0) {
@@ -306,6 +322,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 */
 
         while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
             if (rle_code == 0) {
@@ -376,6 +393,7 @@
         return AVERROR_INVALIDDATA;
     }
 
+    avcodec_get_frame_defaults(&s->frame);
     s->frame.data[0] = NULL;
 
     return 0;
@@ -391,7 +409,7 @@
     int has_palette = 0;
 
     bytestream2_init(&s->g, avpkt->data, avpkt->size);
-    s->frame.reference = 1;
+    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)) {
@@ -417,6 +435,8 @@
         bytestream2_skip(&s->g, 2);
         height     = bytestream2_get_be16(&s->g);
         bytestream2_skip(&s->g, 2);
+        if (height > s->avctx->height - start_line)
+            goto done;
     } else {
         start_line = 0;
         height     = s->avctx->height;
diff --git a/libavcodec/qtrleenc.c b/libavcodec/qtrleenc.c
index bb686f5..e151c9e 100644
--- a/libavcodec/qtrleenc.c
+++ b/libavcodec/qtrleenc.c
@@ -5,20 +5,20 @@
  *
  * This file is based on flashsvenc.c.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -40,6 +40,7 @@
     int pixel_size;
     AVPicture previous_frame;
     unsigned int max_buf_size;
+    int logical_width;
     /**
      * This array will contain at ith position the value of the best RLE code
      * if the line started at pixel i
@@ -63,13 +64,19 @@
 static av_cold int qtrle_encode_init(AVCodecContext *avctx)
 {
     QtrleEncContext *s = avctx->priv_data;
+    int ret;
 
     if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) {
-        return -1;
+        return AVERROR(EINVAL);
     }
     s->avctx=avctx;
+    s->logical_width=avctx->width;
 
     switch (avctx->pix_fmt) {
+    case AV_PIX_FMT_GRAY8:
+        s->logical_width = avctx->width / 4;
+        s->pixel_size = 4;
+        break;
     case AV_PIX_FMT_RGB555BE:
         s->pixel_size = 2;
         break;
@@ -83,24 +90,24 @@
         av_log(avctx, AV_LOG_ERROR, "Unsupported colorspace.\n");
         break;
     }
-    avctx->bits_per_coded_sample = s->pixel_size*8;
+    avctx->bits_per_coded_sample = avctx->pix_fmt == AV_PIX_FMT_GRAY8 ? 40 : s->pixel_size*8;
 
-    s->rlecode_table = av_mallocz(s->avctx->width);
-    s->skip_table    = av_mallocz(s->avctx->width);
-    s->length_table  = av_mallocz((s->avctx->width + 1)*sizeof(int));
+    s->rlecode_table = av_mallocz(s->logical_width);
+    s->skip_table    = av_mallocz(s->logical_width);
+    s->length_table  = av_mallocz((s->logical_width + 1)*sizeof(int));
     if (!s->skip_table || !s->length_table || !s->rlecode_table) {
         av_log(avctx, AV_LOG_ERROR, "Error allocating memory.\n");
-        return -1;
+        return AVERROR(ENOMEM);
     }
-    if (avpicture_alloc(&s->previous_frame, avctx->pix_fmt, avctx->width, avctx->height) < 0) {
+    if ((ret = avpicture_alloc(&s->previous_frame, avctx->pix_fmt, avctx->width, avctx->height)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "Error allocating picture\n");
-        return -1;
+        return ret;
     }
 
-    s->max_buf_size = s->avctx->width*s->avctx->height*s->pixel_size*2 /* image base material */
-                      + 15                                           /* header + footer */
-                      + s->avctx->height*2                           /* skip code+rle end */
-                      + s->avctx->width/MAX_RLE_BULK + 1             /* rle codes */;
+    s->max_buf_size = s->logical_width*s->avctx->height*s->pixel_size*2 /* image base material */
+                      + 15                                            /* header + footer */
+                      + s->avctx->height*2                            /* skip code+rle end */
+                      + s->logical_width/MAX_RLE_BULK + 1             /* rle codes */;
     avctx->coded_frame = &s->frame;
     return 0;
 }
@@ -110,18 +117,18 @@
  */
 static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, uint8_t **buf)
 {
-    int width=s->avctx->width;
+    int width=s->logical_width;
     int i;
     signed char rlecode;
 
     /* We will use it to compute the best bulk copy sequence */
-    unsigned int bulkcount;
+    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;
     /* This will be the number of consecutive equal pixels in the current
      * frame, starting from the ith one also */
-    unsigned int repeatcount;
+    unsigned int av_uninit(repeatcount);
 
     /* The cost of the three different possibilities */
     int total_bulk_cost;
@@ -200,7 +207,7 @@
         prev_line -= s->pixel_size;
     }
 
-    /* Good ! Now we have the best sequence for this line, let's ouput it */
+    /* Good ! Now we have the best sequence for this line, let's output it */
 
     /* We do a special case for the first pixel so that we avoid testing it in
      * the whole loop */
@@ -225,12 +232,28 @@
         }
         else if (rlecode > 0) {
             /* bulk copy */
-            bytestream_put_buffer(buf, this_line + i*s->pixel_size, rlecode*s->pixel_size);
+            if (s->avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
+                int j;
+                // QT grayscale colorspace has 0=white and 255=black, we will
+                // ignore the palette that is included in the AVFrame because
+                // AV_PIX_FMT_GRAY8 has defined color mapping
+                for (j = 0; j < rlecode*s->pixel_size; ++j)
+                    bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff);
+            } else {
+                bytestream_put_buffer(buf, this_line + i*s->pixel_size, rlecode*s->pixel_size);
+            }
             i += rlecode;
         }
         else {
             /* repeat the bits */
-            bytestream_put_buffer(buf, this_line + i*s->pixel_size, s->pixel_size);
+            if (s->avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
+                int j;
+                // QT grayscale colorspace has 0=white and 255=black, ...
+                for (j = 0; j < s->pixel_size; ++j)
+                    bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff);
+            } else {
+                bytestream_put_buffer(buf, this_line + i*s->pixel_size, s->pixel_size);
+            }
             i -= rlecode;
         }
     }
@@ -246,7 +269,7 @@
     uint8_t *orig_buf = buf;
 
     if (!s->frame.key_frame) {
-        unsigned line_size = s->avctx->width * s->pixel_size;
+        unsigned line_size = s->logical_width * s->pixel_size;
         for (start_line = 0; start_line < s->avctx->height; start_line++)
             if (memcmp(p->data[0] + start_line*p->linesize[0],
                        s->previous_frame.data[0] + start_line*s->previous_frame.linesize[0],
@@ -288,11 +311,8 @@
 
     *p = *pict;
 
-    if ((ret = ff_alloc_packet(pkt, s->max_buf_size)) < 0) {
-        /* Upper bound check for compressed data */
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n", s->max_buf_size);
+    if ((ret = ff_alloc_packet2(avctx, pkt, s->max_buf_size)) < 0)
         return ret;
-    }
 
     if (avctx->gop_size == 0 || (s->avctx->frame_number % avctx->gop_size) == 0) {
         /* I-Frame */
@@ -336,7 +356,7 @@
     .encode2        = qtrle_encode_frame,
     .close          = qtrle_encode_end,
     .pix_fmts       = (const enum AVPixelFormat[]){
-        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB555BE, AV_PIX_FMT_ARGB, AV_PIX_FMT_NONE
+        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB555BE, AV_PIX_FMT_ARGB, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
     },
     .long_name      = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"),
 };
diff --git a/libavcodec/r210dec.c b/libavcodec/r210dec.c
index 05f94b7..4c78b53 100644
--- a/libavcodec/r210dec.c
+++ b/libavcodec/r210dec.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Reimar Doeffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,6 +30,8 @@
     avctx->bits_per_raw_sample = 10;
 
     avctx->coded_frame         = avcodec_alloc_frame();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
@@ -40,7 +42,8 @@
     int h, w;
     AVFrame *pic = avctx->coded_frame;
     const uint32_t *src = (const uint32_t *)avpkt->data;
-    int aligned_width = FFALIGN(avctx->width, 64);
+    int aligned_width = FFALIGN(avctx->width,
+                                avctx->codec_id == AV_CODEC_ID_R10K ? 1 : 64);
     uint8_t *dst_line;
 
     if (pic->data[0])
@@ -62,8 +65,13 @@
     for (h = 0; h < avctx->height; h++) {
         uint16_t *dst = (uint16_t *)dst_line;
         for (w = 0; w < avctx->width; w++) {
-            uint32_t pixel = av_be2ne32(*src++);
+            uint32_t pixel;
             uint16_t r, g, b;
+            if (avctx->codec_id==AV_CODEC_ID_AVRP) {
+                pixel = av_le2ne32(*src++);
+            } else {
+                pixel = av_be2ne32(*src++);
+            }
             if (avctx->codec_id==AV_CODEC_ID_R210) {
                 b =  pixel <<  6;
                 g = (pixel >>  4) & 0xffc0;
@@ -121,3 +129,15 @@
     .long_name      = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"),
 };
 #endif
+#if CONFIG_AVRP_DECODER
+AVCodec ff_avrp_decoder = {
+    .name           = "avrp",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_AVRP,
+    .init           = decode_init,
+    .close          = decode_close,
+    .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"),
+};
+#endif
diff --git a/libavcodec/r210enc.c b/libavcodec/r210enc.c
new file mode 100644
index 0000000..39069ab
--- /dev/null
+++ b/libavcodec/r210enc.c
@@ -0,0 +1,124 @@
+/*
+ * R210 encoder
+ *
+ * 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 "avcodec.h"
+#include "internal.h"
+#include "bytestream.h"
+
+static av_cold int encode_init(AVCodecContext *avctx)
+{
+    avctx->coded_frame = avcodec_alloc_frame();
+
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    return 0;
+}
+
+static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                        const AVFrame *pic, int *got_packet)
+{
+    int i, j, ret;
+    int aligned_width = FFALIGN(avctx->width,
+                                avctx->codec_id == AV_CODEC_ID_R10K ? 1 : 64);
+    int pad = (aligned_width - avctx->width) * 4;
+    uint8_t *src_line;
+    uint8_t *dst;
+
+    if ((ret = ff_alloc_packet2(avctx, pkt, 4 * aligned_width * avctx->height)) < 0)
+        return ret;
+
+    avctx->coded_frame->reference = 0;
+    avctx->coded_frame->key_frame = 1;
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    src_line = pic->data[0];
+    dst = pkt->data;
+
+    for (i = 0; i < avctx->height; i++) {
+        uint16_t *src = (uint16_t *)src_line;
+        for (j = 0; j < avctx->width; j++) {
+            uint32_t pixel;
+            uint16_t r = *src++ >> 6;
+            uint16_t g = *src++ >> 6;
+            uint16_t b = *src++ >> 4;
+            if (avctx->codec_id == AV_CODEC_ID_R210)
+                pixel = (r << 20) | (g << 10) | b >> 2;
+            else
+                pixel = (r << 22) | (g << 12) | b;
+            if (avctx->codec_id == AV_CODEC_ID_AVRP)
+                bytestream_put_le32(&dst, pixel);
+            else
+                bytestream_put_be32(&dst, pixel);
+        }
+        memset(dst, 0, pad);
+        dst += pad;
+        src_line += pic->linesize[0];
+    }
+
+    pkt->flags |= AV_PKT_FLAG_KEY;
+    *got_packet = 1;
+    return 0;
+}
+
+static av_cold int encode_close(AVCodecContext *avctx)
+{
+    av_freep(&avctx->coded_frame);
+
+    return 0;
+}
+
+#if CONFIG_R210_ENCODER
+AVCodec ff_r210_encoder = {
+    .name           = "r210",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_R210,
+    .init           = encode_init,
+    .encode2        = encode_frame,
+    .close          = encode_close,
+    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE },
+    .long_name      = NULL_IF_CONFIG_SMALL("Uncompressed RGB 10-bit"),
+};
+#endif
+#if CONFIG_R10K_ENCODER
+AVCodec ff_r10k_encoder = {
+    .name           = "r10k",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_R10K,
+    .init           = encode_init,
+    .encode2        = encode_frame,
+    .close          = encode_close,
+    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE },
+    .long_name      = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"),
+};
+#endif
+#if CONFIG_AVRP_ENCODER
+AVCodec ff_avrp_encoder = {
+    .name           = "avrp",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_AVRP,
+    .init           = encode_init,
+    .encode2        = encode_frame,
+    .close          = encode_close,
+    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB48, AV_PIX_FMT_NONE },
+    .long_name      = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"),
+};
+#endif
diff --git a/libavcodec/ra144.c b/libavcodec/ra144.c
index 3705610..1ec1e10 100644
--- a/libavcodec/ra144.c
+++ b/libavcodec/ra144.c
@@ -2,20 +2,20 @@
  * Real Audio 1.0 (14.4K)
  * Copyright (c) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -1566,8 +1566,15 @@
         if (!b)
             b = -2;
 
-        for (j=0; j <= i; j++)
-            bp1[j] = ((bp2[j] - ((refl[i+1] * bp2[i-j]) >> 12)) * (0x1000000 / b)) >> 12;
+        b = 0x1000000 / b;
+        for (j=0; j <= i; j++) {
+#if CONFIG_FTRAPV
+            int a = bp2[j] - ((refl[i+1] * bp2[i-j]) >> 12);
+            if((int)(a*(unsigned)b) != a*(int64_t)b)
+                return 1;
+#endif
+            bp1[j] = ((bp2[j] - ((refl[i+1] * bp2[i-j]) >> 12)) * b) >> 12;
+        }
 
         if ((unsigned) bp1[i] + 0x1000 > 0x1fff)
             return 1;
diff --git a/libavcodec/ra144.h b/libavcodec/ra144.h
index 73f83f0..331dc35 100644
--- a/libavcodec/ra144.h
+++ b/libavcodec/ra144.h
@@ -2,20 +2,20 @@
  * Real Audio 1.0 (14.4K)
  * Copyright (c) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c
index 0cb4f86..9d44776 100644
--- a/libavcodec/ra144dec.c
+++ b/libavcodec/ra144dec.c
@@ -5,20 +5,20 @@
  * Copyright (c) 2003 Nick Kurshev
  *     Based on public domain decoder at http://www.honeypot.net/audio
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/ra144enc.c b/libavcodec/ra144enc.c
index 5b5de76..e0fb827 100644
--- a/libavcodec/ra144enc.c
+++ b/libavcodec/ra144enc.c
@@ -2,20 +2,20 @@
  * Real Audio 1.0 (14.4K) encoder
  * Copyright (c) 2010 Francesco Lavra <francescolavra@interfree.it>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -347,7 +347,8 @@
     float zero[BLOCKSIZE], cba[BLOCKSIZE], cb1[BLOCKSIZE], cb2[BLOCKSIZE];
     int16_t cba_vect[BLOCKSIZE];
     int cba_idx, cb1_idx, cb2_idx, gain;
-    int i, n, m[3];
+    int i, n;
+    unsigned m[3];
     float g[3];
     float error, best_error;
 
@@ -457,10 +458,8 @@
     if (ractx->last_frame)
         return 0;
 
-    if ((ret = ff_alloc_packet(avpkt, FRAMESIZE))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, FRAMESIZE)))
         return ret;
-    }
 
     /**
      * Since the LPC coefficients are calculated on a frame centered over the
diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c
index 1d02c7b..a8e9eab 100644
--- a/libavcodec/ra288.c
+++ b/libavcodec/ra288.c
@@ -2,20 +2,20 @@
  * RealAudio 2.0 (28.8K)
  * Copyright (c) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -102,14 +102,14 @@
     for (i=0; i < 5; i++)
         buffer[i] = codetable[cb_coef][i] * sumsum;
 
-    sum = ff_scalarproduct_float_c(buffer, buffer, 5) * ((1 << 24) / 5.);
+    sum = ff_scalarproduct_float_c(buffer, buffer, 5);
 
-    sum = FFMAX(sum, 1);
+    sum = FFMAX(sum, 5. / (1<<24));
 
     /* shift and store */
     memmove(gain_block, gain_block + 1, 9 * sizeof(*gain_block));
 
-    gain_block[9] = 10 * log10(sum) - 32;
+    gain_block[9] = 10 * log10(sum) + (10*log10(((1<<24)/5.)) - 32);
 
     ff_celp_lp_synthesis_filterf(block, ractx->sp_lpc, buffer, 5, 36);
 }
diff --git a/libavcodec/ra288.h b/libavcodec/ra288.h
index 8083580..0432bed 100644
--- a/libavcodec/ra288.h
+++ b/libavcodec/ra288.h
@@ -2,20 +2,20 @@
  * RealAudio 2.0 (28.8K)
  * Copyright (c) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/rangecoder.c b/libavcodec/rangecoder.c
index b0c9f21..509d968 100644
--- a/libavcodec/rangecoder.c
+++ b/libavcodec/rangecoder.c
@@ -2,20 +2,20 @@
  * Range coder
  * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -33,6 +33,7 @@
 
 #include <string.h>
 
+#include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "rangecoder.h"
 #include "bytestream.h"
@@ -53,7 +54,7 @@
     /* cast to avoid compiler warning */
     ff_init_range_encoder(c, (uint8_t *) buf, buf_size);
 
-    c->low = bytestream_get_be16(&c->bytestream);
+    c->low = bytestream_get_be16((const uint8_t **)&c->bytestream);
 }
 
 void ff_build_rac_states(RangeCoder *c, int factor, int max_p){
@@ -103,8 +104,8 @@
     c->range=0xFF;
     renorm_encoder(c);
 
-    assert(c->low   == 0);
-    assert(c->range >= 0x100);
+    av_assert1(c->low   == 0);
+    av_assert1(c->range >= 0x100);
 
     return c->bytestream - c->bytestream_start;
 }
@@ -148,7 +149,7 @@
     for(i=0; i<SIZE; i++){
 START_TIMER
         if( (r[i]&1) != get_rac(&c, state) )
-            av_log(NULL, AV_LOG_DEBUG, "rac failure at %d\n", i);
+            av_log(NULL, AV_LOG_ERROR, "rac failure at %d\n", i);
 STOP_TIMER("get_rac")
     }
 
diff --git a/libavcodec/rangecoder.h b/libavcodec/rangecoder.h
index 7ad1bd2..f0c86d0 100644
--- a/libavcodec/rangecoder.h
+++ b/libavcodec/rangecoder.h
@@ -2,20 +2,20 @@
  * Range coder
  * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -28,8 +28,8 @@
 #define AVCODEC_RANGECODER_H
 
 #include <stdint.h>
-#include <assert.h>
 #include "libavutil/common.h"
+#include "libavutil/avassert.h"
 
 typedef struct RangeCoder{
     int low;
@@ -82,9 +82,9 @@
 static inline void put_rac(RangeCoder *c, uint8_t * const state, int bit){
     int range1= (c->range * (*state)) >> 8;
 
-    assert(*state);
-    assert(range1 < c->range);
-    assert(range1 > 0);
+    av_assert2(*state);
+    av_assert2(range1 < c->range);
+    av_assert2(range1 > 0);
     if(!bit){
         c->range -= range1;
         *state= c->zero_state[*state];
diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c
index 2cb5eea..8f8647c 100644
--- a/libavcodec/ratecontrol.c
+++ b/libavcodec/ratecontrol.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -49,6 +49,10 @@
              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){
+    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){
         av_log(NULL, AV_LOG_ERROR, "qp<=0.0\n");
@@ -106,6 +110,13 @@
     };
     emms_c();
 
+    if (!s->avctx->rc_max_available_vbv_use && s->avctx->rc_buffer_size) {
+        if (s->avctx->rc_max_rate) {
+            s->avctx->rc_max_available_vbv_use = av_clipf(s->avctx->rc_max_rate/(s->avctx->rc_buffer_size*get_fps(s->avctx)), 1.0/0.3, 1.0);
+        } else
+            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);
     if (res < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->avctx->rc_eq);
@@ -125,6 +136,8 @@
         rcc->last_qscale_for[i]=FF_QP2LAMBDA * 5;
     }
     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){
         int i;
@@ -240,7 +253,7 @@
                 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/(1/av_q2d(s->avctx->time_base)); //FIXME misbehaves a little for variable fps
+                rcc->pass1_wanted_bits+= s->bit_rate/get_fps(s->avctx); //FIXME misbehaves a little for variable fps
             }
         }
 
@@ -265,7 +278,7 @@
 
 int ff_vbv_update(MpegEncContext *s, int frame_size){
     RateControlContext *rcc= &s->rc_context;
-    const double fps= 1/av_q2d(s->avctx->time_base);
+    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;
@@ -435,7 +448,7 @@
     int qmin, qmax;
     const int pict_type= rce->new_pict_type;
     const double buffer_size= s->avctx->rc_buffer_size;
-    const double fps= 1/av_q2d(s->avctx->time_base);
+    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;
 
@@ -668,11 +681,12 @@
 
     get_qminmax(&qmin, &qmax, s, pict_type);
 
-    fps= 1/av_q2d(s->avctx->time_base);
+    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;
-        update_predictor(&rcc->pred[s->last_pict_type], rcc->last_qscale, sqrt(last_var), s->frame_bits);
+        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);
     }
 
     if(s->flags&CODEC_FLAG_PASS2){
@@ -798,7 +812,7 @@
     RateControlContext *rcc= &s->rc_context;
     AVCodecContext *a= s->avctx;
     int i, toobig;
-    double fps= 1/av_q2d(s->avctx->time_base);
+    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
     uint64_t all_const_bits;
@@ -849,6 +863,12 @@
         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];
+
+            qscale[i]= get_diff_limited_q(s, rce, qscale[i]);
+        }
+
         for(i=rcc->num_entries-1; i>=0; i--){
             RateControlEntry *rce= &rcc->entry[i];
 
diff --git a/libavcodec/ratecontrol.h b/libavcodec/ratecontrol.h
index c0e05cc..b4132bf 100644
--- a/libavcodec/ratecontrol.h
+++ b/libavcodec/ratecontrol.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/raw.c b/libavcodec/raw.c
index 6f0c923..5f8bf33 100644
--- a/libavcodec/raw.c
+++ b/libavcodec/raw.c
@@ -2,20 +2,20 @@
  * Raw Video Codec
  * Copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -64,6 +64,7 @@
     { AV_PIX_FMT_UYVY422, MKTAG('A', 'V', 'u', 'p') },
     { AV_PIX_FMT_UYVY422, MKTAG('V', 'D', 'T', 'Z') }, /* SoftLab-NSK VideoTizer */
     { AV_PIX_FMT_UYVY422, MKTAG('a', 'u', 'v', '2') },
+    { AV_PIX_FMT_UYVY422, MKTAG('c', 'y', 'u', 'v') }, /* CYUV is also Creative YUV */
     { AV_PIX_FMT_UYYVYY411, MKTAG('Y', '4', '1', '1') },
     { AV_PIX_FMT_GRAY8,   MKTAG('G', 'R', 'E', 'Y') },
     { AV_PIX_FMT_NV12,    MKTAG('N', 'V', '1', '2') },
@@ -82,10 +83,18 @@
     { AV_PIX_FMT_BGR444LE, MKTAG('B', 'G', 'R', 12) },
     { AV_PIX_FMT_RGB444BE, MKTAG(12 , 'B', 'G', 'R') },
     { AV_PIX_FMT_BGR444BE, MKTAG(12 , 'R', 'G', 'B') },
+    { AV_PIX_FMT_RGBA64LE, MKTAG('R', 'B', 'A', 64 ) },
+    { AV_PIX_FMT_BGRA64LE, MKTAG('B', 'R', 'A', 64 ) },
+    { AV_PIX_FMT_RGBA64BE, MKTAG(64 , 'R', 'B', 'A') },
+    { AV_PIX_FMT_BGRA64BE, MKTAG(64 , 'B', 'R', 'A') },
     { AV_PIX_FMT_RGBA,     MKTAG('R', 'G', 'B', 'A') },
+    { AV_PIX_FMT_RGB0,     MKTAG('R', 'G', 'B',  0 ) },
     { AV_PIX_FMT_BGRA,     MKTAG('B', 'G', 'R', 'A') },
+    { AV_PIX_FMT_BGR0,     MKTAG('B', 'G', 'R',  0 ) },
     { AV_PIX_FMT_ABGR,     MKTAG('A', 'B', 'G', 'R') },
+    { AV_PIX_FMT_0BGR,     MKTAG( 0 , 'B', 'G', 'R') },
     { AV_PIX_FMT_ARGB,     MKTAG('A', 'R', 'G', 'B') },
+    { AV_PIX_FMT_0RGB,     MKTAG( 0 , 'R', 'G', 'B') },
     { AV_PIX_FMT_RGB24,    MKTAG('R', 'G', 'B', 24 ) },
     { AV_PIX_FMT_BGR24,    MKTAG('B', 'G', 'R', 24 ) },
     { AV_PIX_FMT_YUV411P,  MKTAG('4', '1', '1', 'P') },
@@ -115,6 +124,18 @@
     { AV_PIX_FMT_YUV422P10BE, MKTAG(10 , 10 , '3', 'Y') },
     { AV_PIX_FMT_YUV444P10LE, MKTAG('Y', '3',  0 , 10 ) },
     { AV_PIX_FMT_YUV444P10BE, MKTAG(10 ,  0 , '3', 'Y') },
+    { AV_PIX_FMT_YUV420P12LE, MKTAG('Y', '3', 11 , 12 ) },
+    { AV_PIX_FMT_YUV420P12BE, MKTAG(12 , 11 , '3', 'Y') },
+    { AV_PIX_FMT_YUV422P12LE, MKTAG('Y', '3', 10 , 12 ) },
+    { AV_PIX_FMT_YUV422P12BE, MKTAG(12 , 10 , '3', 'Y') },
+    { AV_PIX_FMT_YUV444P12LE, MKTAG('Y', '3',  0 , 12 ) },
+    { AV_PIX_FMT_YUV444P12BE, MKTAG(12 ,  0 , '3', 'Y') },
+    { AV_PIX_FMT_YUV420P14LE, MKTAG('Y', '3', 11 , 14 ) },
+    { AV_PIX_FMT_YUV420P14BE, MKTAG(14 , 11 , '3', 'Y') },
+    { AV_PIX_FMT_YUV422P14LE, MKTAG('Y', '3', 10 , 14 ) },
+    { AV_PIX_FMT_YUV422P14BE, MKTAG(14 , 10 , '3', 'Y') },
+    { AV_PIX_FMT_YUV444P14LE, MKTAG('Y', '3',  0 , 14 ) },
+    { AV_PIX_FMT_YUV444P14BE, MKTAG(14 ,  0 , '3', 'Y') },
     { AV_PIX_FMT_YUV420P16LE, MKTAG('Y', '3', 11 , 16 ) },
     { AV_PIX_FMT_YUV420P16BE, MKTAG(16 , 11 , '3', 'Y') },
     { AV_PIX_FMT_YUV422P16LE, MKTAG('Y', '3', 10 , 16 ) },
@@ -122,12 +143,17 @@
     { AV_PIX_FMT_YUV444P16LE, MKTAG('Y', '3',  0 , 16 ) },
     { AV_PIX_FMT_YUV444P16BE, MKTAG(16 ,  0 , '3', 'Y') },
     { AV_PIX_FMT_YUVA420P,    MKTAG('Y', '4', 11 ,  8 ) },
-    { AV_PIX_FMT_Y400A,       MKTAG('Y', '2',  0 ,  8 ) },
+    { AV_PIX_FMT_YUVA422P,    MKTAG('Y', '4', 10 ,  8 ) },
+    { AV_PIX_FMT_YUVA444P,    MKTAG('Y', '4',  0 ,  8 ) },
+    { AV_PIX_FMT_GRAY8A,      MKTAG('Y', '2',  0 ,  8 ) },
 
     /* quicktime */
+    { AV_PIX_FMT_YUV420P, MKTAG('R', '4', '2', '0') }, /* Radius DV YUV PAL */
+    { AV_PIX_FMT_YUV411P, MKTAG('R', '4', '1', '1') }, /* Radius DV YUV NTSC */
     { AV_PIX_FMT_UYVY422, MKTAG('2', 'v', 'u', 'y') },
     { AV_PIX_FMT_UYVY422, MKTAG('2', 'V', 'u', 'y') },
     { AV_PIX_FMT_UYVY422, MKTAG('A', 'V', 'U', 'I') }, /* FIXME merge both fields */
+    { AV_PIX_FMT_UYVY422, MKTAG('b', 'x', 'y', 'v') },
     { AV_PIX_FMT_YUYV422, MKTAG('y', 'u', 'v', '2') },
     { AV_PIX_FMT_YUYV422, MKTAG('y', 'u', 'v', 's') },
     { AV_PIX_FMT_YUYV422, MKTAG('D', 'V', 'O', 'O') }, /* Digital Voodoo SD 8 Bit */
@@ -135,8 +161,10 @@
     { AV_PIX_FMT_RGB565LE,MKTAG('L', '5', '6', '5') },
     { AV_PIX_FMT_RGB565BE,MKTAG('B', '5', '6', '5') },
     { AV_PIX_FMT_BGR24,   MKTAG('2', '4', 'B', 'G') },
+    { AV_PIX_FMT_BGR24,   MKTAG('b', 'x', 'b', 'g') },
     { AV_PIX_FMT_BGRA,    MKTAG('B', 'G', 'R', 'A') },
     { AV_PIX_FMT_RGBA,    MKTAG('R', 'G', 'B', 'A') },
+    { AV_PIX_FMT_RGB24,   MKTAG('b', 'x', 'r', 'g') },
     { AV_PIX_FMT_ABGR,    MKTAG('A', 'B', 'G', 'R') },
     { AV_PIX_FMT_GRAY16BE,MKTAG('b', '1', '6', 'g') },
     { AV_PIX_FMT_RGB48BE, MKTAG('b', '4', '8', 'r') },
@@ -144,6 +172,7 @@
     /* special */
     { AV_PIX_FMT_RGB565LE,MKTAG( 3 ,  0 ,  0 ,  0 ) }, /* flipped RGB565LE */
     { AV_PIX_FMT_YUV444P, MKTAG('Y', 'V', '2', '4') }, /* YUV444P, swapped UV */
+    { AV_PIX_FMT_YUYV422, MKTAG('Y', 'V', 'Y', 'U') }, /* YUYV, swapped UV */
 
     { AV_PIX_FMT_NONE, 0 },
 };
diff --git a/libavcodec/raw.h b/libavcodec/raw.h
index bf66671..b704b9c 100644
--- a/libavcodec/raw.h
+++ b/libavcodec/raw.h
@@ -2,20 +2,20 @@
  * Raw Video Codec
  * Copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -35,5 +35,6 @@
 } PixelFormatTag;
 
 extern const PixelFormatTag ff_raw_pix_fmt_tags[];
+enum AVPixelFormat ff_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc);
 
 #endif /* AVCODEC_RAW_H */
diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c
index 0f47e3f..d426f43 100644
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@ -2,20 +2,20 @@
  * Raw Video Decoder
  * Copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,26 +26,43 @@
 
 #include "avcodec.h"
 #include "raw.h"
+#include "libavutil/avassert.h"
 #include "libavutil/common.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
 
 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 */
     int flip;
     AVFrame pic;             ///< AVCodecContext.coded_frame
+    int tff;
 } RawVideoContext;
 
+static const AVOption options[]={
+{"top", "top field first", offsetof(RawVideoContext, tff), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM|AV_OPT_FLAG_VIDEO_PARAM},
+{NULL}
+};
+
+static const AVClass class = {
+    .class_name = "rawdec",
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 static const PixelFormatTag pix_fmt_bps_avi[] = {
+    { AV_PIX_FMT_MONOWHITE, 1 },
+    { 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_BGR24,  24 },
-    { AV_PIX_FMT_RGB32,  32 },
+    { AV_PIX_FMT_BGRA,   32 },
     { AV_PIX_FMT_NONE, 0 },
 };
 
@@ -63,7 +80,7 @@
     { AV_PIX_FMT_NONE, 0 },
 };
 
-static enum AVPixelFormat find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc)
+enum AVPixelFormat ff_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc)
 {
     while (tags->pix_fmt >= 0) {
         if (tags->fourcc == fourcc)
@@ -77,23 +94,30 @@
 {
     RawVideoContext *context = avctx->priv_data;
 
-    if (avctx->codec_tag == MKTAG('r','a','w',' '))
-        avctx->pix_fmt = find_pix_fmt(pix_fmt_bps_mov, avctx->bits_per_coded_sample);
+    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 = find_pix_fmt(pix_fmt_bps_avi, avctx->bits_per_coded_sample);
+        avctx->pix_fmt = ff_find_pix_fmt(pix_fmt_bps_avi, avctx->bits_per_coded_sample);
     else if (avctx->codec_tag)
-        avctx->pix_fmt = find_pix_fmt(ff_raw_pix_fmt_tags, avctx->codec_tag);
+        avctx->pix_fmt = ff_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 = find_pix_fmt(pix_fmt_bps_avi, avctx->bits_per_coded_sample);
+        avctx->pix_fmt = ff_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");
+        return AVERROR(EINVAL);
+    }
 
     ff_set_systematic_pal2(context->palette, avctx->pix_fmt);
-    context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
     if((avctx->bits_per_coded_sample == 4 || avctx->bits_per_coded_sample == 2) &&
        avctx->pix_fmt==AV_PIX_FMT_PAL8 &&
        (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' '))){
+        context->length = avpicture_get_size(avctx->pix_fmt, FFALIGN(avctx->width, 16), avctx->height);
         context->buffer = av_malloc(context->length);
         if (!context->buffer)
-            return -1;
+            return AVERROR(ENOMEM);
+    } else {
+        context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
     }
     context->pic.pict_type = AV_PICTURE_TYPE_I;
     context->pic.key_frame = 1;
@@ -101,6 +125,7 @@
     avctx->coded_frame= &context->pic;
 
     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;
 
@@ -118,9 +143,10 @@
 {
     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);
-    int res;
+    int res, len;
 
     AVFrame   *frame   = data;
     AVPicture *picture = data;
@@ -130,27 +156,40 @@
     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(buf_size < context->length - (avctx->pix_fmt==AV_PIX_FMT_PAL8 ? 256*4 : 0))
-        return -1;
+    if(context->tff>=0){
+        frame->interlaced_frame = 1;
+        frame->top_field_first  = context->tff;
+    }
+
+    if (avctx->width <= 0 || avctx->height <= 0) {
+        av_log(avctx, AV_LOG_ERROR, "w/h is invalid\n");
+        return AVERROR(EINVAL);
+    }
 
     //2bpp and 4bpp raw in avi and mov (yes this is ugly ...)
     if (context->buffer) {
         int i;
         uint8_t *dst = context->buffer;
-        buf_size = context->length - 256*4;
+        buf_size = context->length - AVPALETTE_SIZE;
         if (avctx->bits_per_coded_sample == 4){
-            for(i=0; 2*i+1 < buf_size; i++){
+            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;
             }
-        } else
-            for(i=0; 4*i+3 < buf_size; i++){
+            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;
             }
+            linesize_align = 16;
+        }
         buf= dst;
     }
 
@@ -158,12 +197,18 @@
        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);
+    if (buf_size < len) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid buffer size, packet size %d < expected length %d\n", buf_size, len);
+        return AVERROR(EINVAL);
+    }
+
     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]= context->palette;
+        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);
@@ -173,8 +218,15 @@
             frame->palette_has_changed = 1;
         }
     }
-    if(avctx->pix_fmt==AV_PIX_FMT_BGR24 && ((frame->linesize[0]+3)&~3)*avctx->height <= buf_size)
-        frame->linesize[0] = (frame->linesize[0]+3)&~3;
+    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)
+        frame->linesize[0] = FFALIGN(frame->linesize[0], linesize_align);
 
     if(context->flip)
         flip(avctx, picture);
@@ -195,6 +247,16 @@
             line += picture->linesize[0];
         }
     }
+    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++) {
+            for(x = 0; x < avctx->width - 1; x += 2)
+                FFSWAP(uint8_t, line[2*x + 1], line[2*x + 3]);
+            line += picture->linesize[0];
+        }
+    }
 
     *data_size = sizeof(AVPicture);
     return buf_size;
@@ -217,4 +279,5 @@
     .close          = raw_close_decoder,
     .decode         = raw_decode,
     .long_name      = NULL_IF_CONFIG_SMALL("raw video"),
+    .priv_class     = &class,
 };
diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c
index 3e607af..c6da6b8 100644
--- a/libavcodec/rawenc.c
+++ b/libavcodec/rawenc.c
@@ -2,20 +2,20 @@
  * Raw Video Encoder
  * Copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,8 +36,8 @@
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
 
     avctx->coded_frame            = avctx->priv_data;
+    avcodec_get_frame_defaults(avctx->coded_frame);
     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
-    avctx->coded_frame->key_frame = 1;
     avctx->bits_per_coded_sample = av_get_bits_per_pixel(desc);
     if(!avctx->codec_tag)
         avctx->codec_tag = avcodec_pix_fmt_to_codec_tag(avctx->pix_fmt);
@@ -52,7 +52,7 @@
     if (ret < 0)
         return ret;
 
-    if ((ret = ff_alloc_packet(pkt, ret)) < 0)
+    if ((ret = ff_alloc_packet2(avctx, pkt, ret)) < 0)
         return ret;
     if ((ret = avpicture_layout((const AVPicture *)frame, avctx->pix_fmt, avctx->width,
                                 avctx->height, pkt->data, pkt->size)) < 0)
diff --git a/libavcodec/rdft.c b/libavcodec/rdft.c
index 116cfa4..ebddd8b 100644
--- a/libavcodec/rdft.c
+++ b/libavcodec/rdft.c
@@ -2,20 +2,20 @@
  * (I)RDFT transforms
  * Copyright (c) 2009 Alex Converse <alex dot converse at gmail dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include <stdlib.h>
diff --git a/libavcodec/rdft.h b/libavcodec/rdft.h
index 8ff620f..5fb0323 100644
--- a/libavcodec/rdft.h
+++ b/libavcodec/rdft.h
@@ -2,20 +2,20 @@
  * (I)RDFT transforms
  * Copyright (c) 2009 Alex Converse <alex dot converse at gmail dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/realtextdec.c b/libavcodec/realtextdec.c
new file mode 100644
index 0000000..102e0d9
--- /dev/null
+++ b/libavcodec/realtextdec.c
@@ -0,0 +1,83 @@
+/*
+ * 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
+ * RealText subtitle decoder
+ * @see http://service.real.com/help/library/guides/ProductionGuide/prodguide/htmfiles/realtext.htm
+ */
+
+#include "avcodec.h"
+#include "ass.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+
+static int rt_event_to_ass(AVBPrint *buf, const char *p)
+{
+    int prev_chr_is_space = 1;
+
+    while (*p) {
+        if (*p != '<') {
+            if (!isspace(*p))
+                av_bprint_chars(buf, *p, 1);
+            else if (!prev_chr_is_space)
+                av_bprint_chars(buf, ' ', 1);
+            prev_chr_is_space = isspace(*p);
+        } else {
+            const char *end = strchr(p, '>');
+            if (!end)
+                break;
+            if (!av_strncasecmp(p, "<br/>", 5) ||
+                !av_strncasecmp(p, "<br>",  4)) {
+                av_bprintf(buf, "\\N");
+            }
+            p = end;
+        }
+        p++;
+    }
+    av_bprintf(buf, "\r\n");
+    return 0;
+}
+
+static int realtext_decode_frame(AVCodecContext *avctx,
+                                 void *data, int *got_sub_ptr, AVPacket *avpkt)
+{
+    AVSubtitle *sub = data;
+    const char *ptr = avpkt->data;
+    AVBPrint buf;
+
+    av_bprint_init(&buf, 0, 4096);
+    // note: no need to rescale pts & duration since they are in the same
+    // timebase as ASS (1/100)
+    if (ptr && avpkt->size > 0 && !rt_event_to_ass(&buf, ptr))
+        ff_ass_add_rect(sub, buf.str, avpkt->pts, avpkt->duration, 0);
+    *got_sub_ptr = sub->num_rects > 0;
+    av_bprint_finalize(&buf, NULL);
+    return avpkt->size;
+}
+
+AVCodec ff_realtext_decoder = {
+    .name           = "realtext",
+    .long_name      = NULL_IF_CONFIG_SMALL("RealText subtitle"),
+    .type           = AVMEDIA_TYPE_SUBTITLE,
+    .id             = AV_CODEC_ID_REALTEXT,
+    .decode         = realtext_decode_frame,
+    .init           = ff_ass_subtitle_header_default,
+};
diff --git a/libavcodec/rectangle.h b/libavcodec/rectangle.h
index 5cc81fe..43f89c9 100644
--- a/libavcodec/rectangle.h
+++ b/libavcodec/rectangle.h
@@ -2,20 +2,20 @@
  * rectangle filling function
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -28,9 +28,9 @@
 #ifndef AVCODEC_RECTANGLE_H
 #define AVCODEC_RECTANGLE_H
 
-#include <assert.h>
 #include "config.h"
 #include "libavutil/common.h"
+#include "libavutil/avassert.h"
 #include "dsputil.h"
 
 /**
@@ -41,14 +41,14 @@
  */
 static av_always_inline void fill_rectangle(void *vp, int w, int h, int stride, uint32_t val, int size){
     uint8_t *p= (uint8_t*)vp;
-    assert(size==1 || size==2 || size==4);
-    assert(w<=4);
+    av_assert2(size==1 || size==2 || size==4);
+    av_assert2(w<=4);
 
     w      *= size;
     stride *= size;
 
-    assert((((long)vp)&(FFMIN(w, STRIDE_ALIGN)-1)) == 0);
-    assert((stride&(w-1))==0);
+    av_assert2((((long)vp)&(FFMIN(w, STRIDE_ALIGN)-1)) == 0);
+    av_assert2((stride&(w-1))==0);
     if(w==2){
         const uint16_t v= size==4 ? val : val*0x0101;
         *(uint16_t*)(p + 0*stride)= v;
@@ -118,8 +118,8 @@
         *(uint32_t*)(p +12+3*stride)= val;
 #endif
     }else
-        assert(0);
-    assert(h==4);
+        av_assert2(0);
+    av_assert2(h==4);
 }
 
 #endif /* AVCODEC_RECTANGLE_H */
diff --git a/libavcodec/remove_extradata_bsf.c b/libavcodec/remove_extradata_bsf.c
index 460482a..f0d9b45 100644
--- a/libavcodec/remove_extradata_bsf.c
+++ b/libavcodec/remove_extradata_bsf.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/resample.c b/libavcodec/resample.c
index 20d7078..dfaad66 100644
--- a/libavcodec/resample.c
+++ b/libavcodec/resample.c
@@ -2,20 +2,20 @@
  * samplerate conversion for both audio and video
  * Copyright (c) 2000 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -113,6 +113,39 @@
     }
 }
 
+/*
+5.1 to stereo input: [fl, fr, c, lfe, rl, rr]
+- Left = front_left + rear_gain * rear_left + center_gain * center
+- Right = front_right + rear_gain * rear_right + center_gain * center
+Where rear_gain is usually around 0.5-1.0 and
+      center_gain is almost always 0.7 (-3 dB)
+*/
+static void surround_to_stereo(short **output, short *input, int channels, int samples)
+{
+    int i;
+    short l, r;
+
+    for (i = 0; i < samples; i++) {
+        int fl,fr,c,rl,rr;
+        fl = input[0];
+        fr = input[1];
+        c = input[2];
+        // lfe = input[3];
+        rl = input[4];
+        rr = input[5];
+
+        l = av_clip_int16(fl + (0.5 * rl) + (0.7 * c));
+        r = av_clip_int16(fr + (0.5 * rr) + (0.7 * c));
+
+        /* output l & r. */
+        *output[0]++ = l;
+        *output[1]++ = r;
+
+        /* increment input. */
+        input += channels;
+    }
+}
+
 static void deinterleave(short **output, short *input, int channels, int samples)
 {
     int i, j;
@@ -152,6 +185,21 @@
     }
 }
 
+#define SUPPORT_RESAMPLE(ch1, ch2, ch3, ch4, ch5, ch6, ch7, ch8) \
+    ch8<<7 | ch7<<6 | ch6<<5 | ch5<<4 | ch4<<3 | ch3<<2 | ch2<<1 | ch1<<0
+
+static const uint8_t supported_resampling[MAX_CHANNELS] = {
+    // output ch:    1  2  3  4  5  6  7  8
+    SUPPORT_RESAMPLE(1, 1, 0, 0, 0, 0, 0, 0), // 1 input channel
+    SUPPORT_RESAMPLE(1, 1, 0, 0, 0, 1, 0, 0), // 2 input channels
+    SUPPORT_RESAMPLE(0, 0, 1, 0, 0, 0, 0, 0), // 3 input channels
+    SUPPORT_RESAMPLE(0, 0, 0, 1, 0, 0, 0, 0), // 4 input channels
+    SUPPORT_RESAMPLE(0, 0, 0, 0, 1, 0, 0, 0), // 5 input channels
+    SUPPORT_RESAMPLE(0, 1, 0, 0, 0, 1, 0, 0), // 6 input channels
+    SUPPORT_RESAMPLE(0, 0, 0, 0, 0, 0, 1, 0), // 7 input channels
+    SUPPORT_RESAMPLE(0, 0, 0, 0, 0, 0, 0, 1), // 8 input channels
+};
+
 ReSampleContext *av_audio_resample_init(int output_channels, int input_channels,
                                         int output_rate, int input_rate,
                                         enum AVSampleFormat sample_fmt_out,
@@ -167,12 +215,15 @@
                MAX_CHANNELS);
         return NULL;
     }
-    if (output_channels != input_channels &&
-        (input_channels  > 2 ||
-         output_channels > 2 &&
-         !(output_channels == 6 && input_channels == 2))) {
-        av_log(NULL, AV_LOG_ERROR,
-               "Resampling output channel count must be 1 or 2 for mono input; 1, 2 or 6 for stereo input; or N for N channel input.\n");
+    if (!(supported_resampling[input_channels-1] & (1<<(output_channels-1)))) {
+        int i;
+        av_log(NULL, AV_LOG_ERROR, "Unsupported audio resampling. Allowed "
+               "output channels for %d input channel%s", input_channels,
+               input_channels > 1 ? "s:" : ":");
+        for (i = 0; i < MAX_CHANNELS; i++)
+            if (supported_resampling[input_channels-1] & (1<<i))
+                av_log(NULL, AV_LOG_ERROR, " %d", i + 1);
+        av_log(NULL, AV_LOG_ERROR, "\n");
         return NULL;
     }
 
@@ -274,7 +325,7 @@
         input = s->buffer[0];
     }
 
-    lenout = 4 * nb_samples * s->ratio + 16;
+    lenout= 2*s->output_channels*nb_samples * s->ratio + 16;
 
     if (s->sample_fmt[1] != AV_SAMPLE_FMT_S16) {
         int out_size = lenout * av_get_bytes_per_sample(s->sample_fmt[1]) *
@@ -308,6 +359,10 @@
     } else if (s->output_channels >= 2 && s->input_channels == 1) {
         buftmp3[0] = bufout[0];
         memcpy(buftmp2[0], input, nb_samples * sizeof(short));
+    } else if (s->input_channels == 6 && s->output_channels ==2) {
+        buftmp3[0] = bufout[0];
+        buftmp3[1] = bufout[1];
+        surround_to_stereo(buftmp2, input, s->input_channels, nb_samples);
     } else if (s->output_channels >= s->input_channels && s->input_channels >= 2) {
         for (i = 0; i < s->input_channels; i++) {
             buftmp3[i] = bufout[i];
@@ -337,7 +392,8 @@
         mono_to_stereo(output, buftmp3[0], nb_samples1);
     } else if (s->output_channels == 6 && s->input_channels == 2) {
         ac3_5p1_mux(output, buftmp3[0], buftmp3[1], nb_samples1);
-    } else if (s->output_channels == s->input_channels && s->input_channels >= 2) {
+    } else if ((s->output_channels == s->input_channels && s->input_channels >= 2) ||
+               (s->output_channels == 2 && s->input_channels == 6)) {
         interleave(output, buftmp3, s->output_channels, nb_samples1);
     }
 
diff --git a/libavcodec/resample2.c b/libavcodec/resample2.c
index c6e5c48..3a3cd13 100644
--- a/libavcodec/resample2.c
+++ b/libavcodec/resample2.c
@@ -2,20 +2,20 @@
  * audio resampling
  * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,7 @@
  * @author Michael Niedermayer <michaelni@gmx.at>
  */
 
+#include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "dsputil.h"
 #include "libavutil/common.h"
@@ -210,8 +211,10 @@
     memcpy(&c->filter_bank[c->filter_length*phase_count+1], c->filter_bank, (c->filter_length-1)*sizeof(FELEM));
     c->filter_bank[c->filter_length*phase_count]= c->filter_bank[c->filter_length - 1];
 
-    c->src_incr= out_rate;
-    c->ideal_dst_incr= c->dst_incr= in_rate * phase_count;
+    if(!av_reduce(&c->src_incr, &c->dst_incr, out_rate, in_rate * (int64_t)phase_count, INT32_MAX/2))
+        goto error;
+    c->ideal_dst_incr= c->dst_incr;
+
     c->index= -phase_count*((c->filter_length-1)/2);
 
     return c;
@@ -249,10 +252,9 @@
             dst[dst_index] = src[index2>>32];
             index2 += incr;
         }
-        frac += dst_index * dst_incr_frac;
         index += dst_index * dst_incr;
-        index += frac / c->src_incr;
-        frac %= c->src_incr;
+        index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr;
+        frac   = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr;
   }else{
     for(dst_index=0; dst_index < dst_size; dst_index++){
         FELEM *filter= c->filter_bank + c->filter_length*(index & c->phase_mask);
@@ -303,7 +305,7 @@
 
     if(compensation_distance){
         compensation_distance -= dst_index;
-        assert(compensation_distance > 0);
+        av_assert2(compensation_distance > 0);
     }
     if(update_ctx){
         c->frac= frac;
diff --git a/libavcodec/rl.h b/libavcodec/rl.h
index 367cc98..c80283d 100644
--- a/libavcodec/rl.h
+++ b/libavcodec/rl.h
@@ -2,20 +2,20 @@
  * Copyright (c) 2000-2002 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/rl2.c b/libavcodec/rl2.c
index 84434a2..96041a6 100644
--- a/libavcodec/rl2.c
+++ b/libavcodec/rl2.c
@@ -2,20 +2,20 @@
  * RL2 Video Decoder
  * Copyright (C) 2008 Sascha Sommer (saschasommer@freenet.de)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -53,7 +53,7 @@
  * @param s rl2 context
  * @param in input buffer
  * @param size input buffer size
- * @param out ouput buffer
+ * @param out output buffer
  * @param stride stride of the output buffer
  * @param video_base offset of the rle data inside the frame
  */
@@ -135,6 +135,7 @@
     int i;
     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){
@@ -153,7 +154,7 @@
 
     /** initialize palette */
     for(i=0;i<AVPALETTE_COUNT;i++)
-        s->palette[i] = AV_RB24(&avctx->extradata[6 + i * 3]);
+        s->palette[i] = 0xFF << 24 | AV_RB24(&avctx->extradata[6 + i * 3]);
 
     /** decode background frame if present */
     back_size = avctx->extradata_size - EXTRADATA1_SIZE;
diff --git a/libavcodec/rle.c b/libavcodec/rle.c
index cbbde93..d2ec68c 100644
--- a/libavcodec/rle.c
+++ b/libavcodec/rle.c
@@ -2,20 +2,20 @@
  * RLE encoder
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avcodec.h"
diff --git a/libavcodec/rle.h b/libavcodec/rle.h
index 00261d3..2485132 100644
--- a/libavcodec/rle.h
+++ b/libavcodec/rle.h
@@ -1,20 +1,20 @@
 /*
  * RLE encoder
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/roqaudioenc.c b/libavcodec/roqaudioenc.c
index 3cc9931..d69ccbf 100644
--- a/libavcodec/roqaudioenc.c
+++ b/libavcodec/roqaudioenc.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2005 Eric Lasota
  *    Based on RoQ specs (c)2001 Tim Ferguson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -171,10 +171,8 @@
     else
         data_size = avctx->channels * avctx->frame_size;
 
-    if ((ret = ff_alloc_packet(avpkt, ROQ_HEADER_SIZE + data_size))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, ROQ_HEADER_SIZE + data_size)))
         return ret;
-    }
     out = avpkt->data;
 
     bytestream_put_byte(&out, stereo ? 0x21 : 0x20);
diff --git a/libavcodec/roqvideo.c b/libavcodec/roqvideo.c
index 77df079..eb8fc25 100644
--- a/libavcodec/roqvideo.c
+++ b/libavcodec/roqvideo.c
@@ -2,20 +2,20 @@
  * Copyright (C) 2003 Mike Melanson
  * Copyright (C) 2003 Dr. Tim Ferguson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/roqvideo.h b/libavcodec/roqvideo.h
index 33d77ed..2f9493d 100644
--- a/libavcodec/roqvideo.h
+++ b/libavcodec/roqvideo.h
@@ -2,20 +2,20 @@
  * Copyright (C) 2003 Mike Melanson
  * Copyright (C) 2003 Dr. Tim Ferguson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/roqvideodec.c b/libavcodec/roqvideodec.c
index bf5664b..a6f213c 100644
--- a/libavcodec/roqvideodec.c
+++ b/libavcodec/roqvideodec.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,10 +25,6 @@
  *   http://www.csse.monash.edu.au/~timf/
  */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
 #include "avcodec.h"
 #include "bytestream.h"
 #include "roqvideo.h"
@@ -43,7 +39,7 @@
     roq_qcell *qcell;
     int64_t chunk_start;
 
-    while (bytestream2_get_bytes_left(&ri->gb) > 0) {
+    while (bytestream2_get_bytes_left(&ri->gb) >= 8) {
         chunk_id   = bytestream2_get_le16(&ri->gb);
         chunk_size = bytestream2_get_le32(&ri->gb);
         chunk_arg  = bytestream2_get_le16(&ri->gb);
@@ -71,9 +67,19 @@
 
     chunk_start = bytestream2_tell(&ri->gb);
     xpos = ypos = 0;
+
+    if (chunk_size > bytestream2_get_bytes_left(&ri->gb)) {
+        av_log(ri->avctx, AV_LOG_ERROR, "Chunk does not fit in input buffer\n");
+        chunk_size = bytestream2_get_bytes_left(&ri->gb);
+    }
+
     while (bytestream2_tell(&ri->gb) < chunk_start + chunk_size) {
         for (yp = ypos; yp < ypos + 16; yp += 8)
             for (xp = xpos; xp < xpos + 16; xp += 8) {
+                if (bytestream2_tell(&ri->gb) >= chunk_start + chunk_size) {
+                    av_log(ri->avctx, AV_LOG_ERROR, "Input buffer too small\n");
+                    return;
+                }
                 if (vqflg_pos < 0) {
                     vqflg = bytestream2_get_le16(&ri->gb);
                     vqflg_pos = 7;
@@ -105,6 +111,10 @@
                         if(k & 0x01) x += 4;
                         if(k & 0x02) y += 4;
 
+                        if (bytestream2_tell(&ri->gb) >= chunk_start + chunk_size) {
+                            av_log(ri->avctx, AV_LOG_ERROR, "Input buffer too small\n");
+                            return;
+                        }
                         if (vqflg_pos < 0) {
                             vqflg = bytestream2_get_le16(&ri->gb);
                             vqflg_pos = 7;
@@ -161,6 +171,8 @@
     s->avctx = avctx;
     s->width = avctx->width;
     s->height = avctx->height;
+    avcodec_get_frame_defaults(&s->frames[0]);
+    avcodec_get_frame_defaults(&s->frames[1]);
     s->last_frame    = &s->frames[0];
     s->current_frame = &s->frames[1];
     avctx->pix_fmt = AV_PIX_FMT_YUV444P;
@@ -176,11 +188,12 @@
     int buf_size = avpkt->size;
     RoqContext *s = avctx->priv_data;
     int copy= !s->current_frame->data[0];
+    int ret;
 
     s->current_frame->reference = 3;
-    if (avctx->reget_buffer(avctx, s->current_frame)) {
-        av_log(avctx, AV_LOG_ERROR, "  RoQ: get_buffer() failed\n");
-        return -1;
+    if ((ret = avctx->reget_buffer(avctx, s->current_frame)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
+        return ret;
     }
 
     if(copy)
diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c
index a5e0720..b38ecab 100644
--- a/libavcodec/roqvideoenc.c
+++ b/libavcodec/roqvideoenc.c
@@ -5,27 +5,27 @@
  * Copyright (C) 2004-2007 Eric Lasota
  *    Based on RoQ specs (C) 2001 Tim Ferguson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
  * @file
  * id RoQ encoder by Vitor. Based on the Switchblade3 library and the
- * Switchblade3 Libav glue by Eric Lasota.
+ * Switchblade3 FFmpeg glue by Eric Lasota.
  */
 
 /*
@@ -1020,10 +1020,8 @@
     /* 138 bits max per 8x8 block +
      *     256 codebooks*(6 bytes 2x2 + 4 bytes 4x4) + 8 bytes frame header */
     size = ((enc->width * enc->height / 64) * 138 + 7) / 8 + 256 * (6 + 4) + 8;
-    if ((ret = ff_alloc_packet(pkt, size)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet with size %d.\n", size);
+    if ((ret = ff_alloc_packet2(avctx, pkt, size)) < 0)
         return ret;
-    }
     enc->out_buf = pkt->data;
 
     /* Check for I frame */
diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c
index 876c9b7..498c36e 100644
--- a/libavcodec/rpza.c
+++ b/libavcodec/rpza.c
@@ -2,20 +2,20 @@
  * Quicktime Video (RPZA) Video Decoder
  * Copyright (C) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -238,6 +238,7 @@
     s->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_RGB555;
 
+    avcodec_get_frame_defaults(&s->frame);
     s->frame.data[0] = NULL;
 
     return 0;
@@ -254,7 +255,7 @@
     s->buf = buf;
     s->size = buf_size;
 
-    s->frame.reference = 1;
+    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)) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
diff --git a/libavcodec/rtjpeg.c b/libavcodec/rtjpeg.c
index 3604585..7797a65 100644
--- a/libavcodec/rtjpeg.c
+++ b/libavcodec/rtjpeg.c
@@ -2,20 +2,20 @@
  * RTJpeg decoding functions
  * Copyright (c) 2006 Reimar Doeffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "libavutil/common.h"
diff --git a/libavcodec/rtjpeg.h b/libavcodec/rtjpeg.h
index 9fbfb34..0fd24a3 100644
--- a/libavcodec/rtjpeg.h
+++ b/libavcodec/rtjpeg.h
@@ -2,20 +2,20 @@
  * RTJpeg decoding functions
  * copyright (c) 2006 Reimar Doeffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c
index 8769eae..21dec46 100644
--- a/libavcodec/rv10.c
+++ b/libavcodec/rv10.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000,2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -304,6 +304,23 @@
     int seq, mb_pos, i;
     int rpr_bits;
 
+#if 0
+    GetBitContext gb= s->gb;
+    for(i=0; i<64; i++){
+        av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&gb));
+        if(i%4==3) av_log(s->avctx, AV_LOG_DEBUG, " ");
+    }
+    av_log(s->avctx, AV_LOG_DEBUG, "\n");
+#endif
+#if 0
+    av_log(s->avctx, AV_LOG_DEBUG, "%3dx%03d/%02Xx%02X ", s->width, s->height, s->width/4, s->height/4);
+    for(i=0; i<s->avctx->extradata_size; i++){
+        av_log(s->avctx, AV_LOG_DEBUG, "%02X ", ((uint8_t*)s->avctx->extradata)[i]);
+        if(i%4==3) av_log(s->avctx, AV_LOG_DEBUG, " ");
+    }
+    av_log(s->avctx, AV_LOG_DEBUG, "\n");
+#endif
+
     i= get_bits(&s->gb, 2);
     switch(i){
     case 0: s->pict_type= AV_PICTURE_TYPE_I; break;
@@ -332,7 +349,7 @@
     }
 
     if(RV_GET_MINOR_VER(rv->sub_id) >= 2)
-        s->loop_filter = get_bits1(&s->gb);
+        s->loop_filter = get_bits1(&s->gb) && !s->avctx->lowres;
 
     if(RV_GET_MINOR_VER(rv->sub_id) <= 1)
         seq = get_bits(&s->gb, 8) << 7;
@@ -354,10 +371,19 @@
             new_h= s->orig_height;
         }
         if(new_w != s->width || new_h != s->height){
+            AVRational old_aspect = s->avctx->sample_aspect_ratio;
             av_log(s->avctx, AV_LOG_DEBUG, "attempting to change resolution to %dx%d\n", new_w, new_h);
             if (av_image_check_size(new_w, new_h, 0, s->avctx) < 0)
                 return -1;
             ff_MPV_common_end(s);
+
+            // attempt to keep aspect during typical resolution switches
+            if (!old_aspect.num)
+                old_aspect = (AVRational){1, 1};
+            if (2 * new_w * s->height == new_h * s->width)
+                s->avctx->sample_aspect_ratio = av_mul_q(old_aspect, (AVRational){2, 1});
+            if (new_w * s->height == 2 * new_h * s->width)
+                s->avctx->sample_aspect_ratio = av_mul_q(old_aspect, (AVRational){1, 2});
             avcodec_set_dimensions(s->avctx, new_w, new_h);
             s->width  = new_w;
             s->height = new_h;
@@ -404,14 +430,15 @@
 //    s->obmc=1;
 //    s->umvplus=1;
     s->modified_quant=1;
-    s->loop_filter=1;
+    if(!s->avctx->lowres)
+        s->loop_filter=1;
 
     if(s->avctx->debug & FF_DEBUG_PICT_INFO){
             av_log(s->avctx, AV_LOG_INFO, "num:%5d x:%2d y:%2d type:%d qscale:%2d rnd:%d\n",
                    seq, s->mb_x, s->mb_y, s->pict_type, s->qscale, s->no_rounding);
     }
 
-    assert(s->pict_type != AV_PICTURE_TYPE_B || !s->low_delay);
+    av_assert0(s->pict_type != AV_PICTURE_TYPE_B || !s->low_delay);
 
     return s->mb_width*s->mb_height - mb_pos;
 }
@@ -433,7 +460,6 @@
     s->avctx= avctx;
     s->out_format = FMT_H263;
     s->codec_id= avctx->codec_id;
-    avctx->flags |= CODEC_FLAG_EMU_EDGE;
 
     s->orig_width = s->width  = avctx->coded_width;
     s->orig_height= s->height = avctx->coded_height;
@@ -542,6 +568,7 @@
         }
     }
 
+
     av_dlog(avctx, "qscale=%d\n", s->qscale);
 
     /* default quantization values */
@@ -650,6 +677,8 @@
     const uint8_t *slices_hdr = NULL;
 
     av_dlog(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size);
+    s->flags  = avctx->flags;
+    s->flags2 = avctx->flags2;
 
     /* no supplementary picture */
     if (buf_size == 0) {
@@ -721,6 +750,7 @@
     .close          = rv10_decode_end,
     .decode         = rv10_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
+    .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("RealVideo 1.0"),
     .pix_fmts       = ff_pixfmt_list_420,
 };
@@ -735,6 +765,7 @@
     .decode         = rv10_decode_frame,
     .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_DELAY,
     .flush          = ff_mpeg_flush,
+    .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("RealVideo 2.0"),
     .pix_fmts       = ff_pixfmt_list_420,
 };
diff --git a/libavcodec/rv10enc.c b/libavcodec/rv10enc.c
index d3cd12c..c4c5c53 100644
--- a/libavcodec/rv10enc.c
+++ b/libavcodec/rv10enc.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000,2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/rv20enc.c b/libavcodec/rv20enc.c
index c392b53..295699a 100644
--- a/libavcodec/rv20enc.c
+++ b/libavcodec/rv20enc.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000,2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -40,12 +40,12 @@
 
     put_bits(&s->pb, 1, s->no_rounding);
 
-    assert(s->f_code == 1);
-    assert(s->unrestricted_mv == 0);
-    assert(s->alt_inter_vlc == 0);
-    assert(s->umvplus == 0);
-    assert(s->modified_quant==1);
-    assert(s->loop_filter==1);
+    av_assert0(s->f_code == 1);
+    av_assert0(s->unrestricted_mv == 0);
+    av_assert0(s->alt_inter_vlc == 0);
+    av_assert0(s->umvplus == 0);
+    av_assert0(s->modified_quant==1);
+    av_assert0(s->loop_filter==1);
 
     s->h263_aic= s->pict_type == AV_PICTURE_TYPE_I;
     if(s->h263_aic){
diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c
index 8016ad3..df2160a 100644
--- a/libavcodec/rv30.c
+++ b/libavcodec/rv30.c
@@ -2,20 +2,20 @@
  * RV30 decoder
  * Copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -51,6 +51,11 @@
     skip_bits1(gb);
     si->pts = get_bits(gb, 13);
     rpr = get_bits(gb, r->rpr);
+    if (r->s.avctx->extradata_size < 8 + rpr*2) {
+        av_log(r->s.avctx, AV_LOG_WARNING,
+               "Extradata does not contain selected resolution\n");
+        rpr = 0;
+    }
     if(rpr){
         w = r->s.avctx->extradata[6 + rpr*2] << 2;
         h = r->s.avctx->extradata[7 + rpr*2] << 2;
@@ -74,7 +79,7 @@
     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 >= 81*2){
+            if(code > 80U*2U){
                 av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction code\n");
                 return -1;
             }
@@ -103,7 +108,7 @@
     GetBitContext *gb = &s->gb;
     int code = svq3_get_ue_golomb(gb);
 
-    if (code < 0 || code > 11) {
+    if(code > 11U){
         av_log(s->avctx, AV_LOG_ERROR, "Incorrect MB type code\n");
         return -1;
     }
@@ -256,7 +261,6 @@
     if(avctx->extradata_size - 8 < (r->rpr - 1) * 2){
         av_log(avctx, AV_LOG_ERROR, "Insufficient extradata - need at least %d bytes, got %d\n",
                6 + r->rpr * 2, avctx->extradata_size);
-        return AVERROR(EINVAL);
     }
     r->parse_slice_header = rv30_parse_slice_header;
     r->decode_intra_types = rv30_decode_intra_types;
diff --git a/libavcodec/rv30data.h b/libavcodec/rv30data.h
index 5ee3048..9cc48a6 100644
--- a/libavcodec/rv30data.h
+++ b/libavcodec/rv30data.h
@@ -2,20 +2,20 @@
  * RealVideo 3 decoder
  * copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/rv30dsp.c b/libavcodec/rv30dsp.c
index bcd1a46..8343960 100644
--- a/libavcodec/rv30dsp.c
+++ b/libavcodec/rv30dsp.c
@@ -2,20 +2,20 @@
  * RV30 decoder motion compensation functions
  * Copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
index ffc8649..4226ecb 100644
--- a/libavcodec/rv34.c
+++ b/libavcodec/rv34.c
@@ -2,20 +2,20 @@
  * RV30/40 decoder common data
  * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -1332,7 +1332,7 @@
     if(r->s.mb_skip_run > 1)
         return 0;
     bits = get_bits_left(&s->gb);
-    if(bits < 0 || (bits < 8 && !show_bits(&s->gb, bits)))
+    if(bits <= 0 || (bits < 8 && !show_bits(&s->gb, bits)))
         return 1;
     return 0;
 }
@@ -1403,6 +1403,10 @@
         av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");
         return AVERROR_INVALIDDATA;
     }
+    if (s->width != r->si.width || s->height != r->si.height) {
+        av_log(s->avctx, AV_LOG_ERROR, "Size mismatch\n");
+        return AVERROR_INVALIDDATA;
+    }
 
     r->si.end = end;
     s->qscale = r->si.quant;
@@ -1645,7 +1649,7 @@
     /* first slice */
     if (si.start == 0) {
         if (s->mb_num_left > 0) {
-            av_log(avctx, AV_LOG_ERROR, "New frame but still %d MB left.",
+            av_log(avctx, AV_LOG_ERROR, "New frame but still %d MB left.\n",
                    s->mb_num_left);
             ff_er_frame_end(s);
             ff_MPV_frame_end(s);
diff --git a/libavcodec/rv34.h b/libavcodec/rv34.h
index e7a59c4..6b8d365 100644
--- a/libavcodec/rv34.h
+++ b/libavcodec/rv34.h
@@ -2,20 +2,20 @@
  * RV30/40 decoder common data declarations
  * Copyright (c) 2007 Mike Melanson, Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/rv34_parser.c b/libavcodec/rv34_parser.c
index ccb4314..8af7443 100644
--- a/libavcodec/rv34_parser.c
+++ b/libavcodec/rv34_parser.c
@@ -76,7 +76,7 @@
     return buf_size;
 }
 
-#ifdef CONFIG_RV30_PARSER
+#if CONFIG_RV30_PARSER
 AVCodecParser ff_rv30_parser = {
     .codec_ids      = { AV_CODEC_ID_RV30 },
     .priv_data_size = sizeof(RV34ParseContext),
@@ -84,7 +84,7 @@
 };
 #endif
 
-#ifdef CONFIG_RV40_PARSER
+#if CONFIG_RV40_PARSER
 AVCodecParser ff_rv40_parser = {
     .codec_ids      = { AV_CODEC_ID_RV40 },
     .priv_data_size = sizeof(RV34ParseContext),
diff --git a/libavcodec/rv34data.h b/libavcodec/rv34data.h
index 3064124..4b2701f 100644
--- a/libavcodec/rv34data.h
+++ b/libavcodec/rv34data.h
@@ -2,20 +2,20 @@
  * RealVideo 4 decoder
  * copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/rv34vlc.h b/libavcodec/rv34vlc.h
index f4670c1..aa29357 100644
--- a/libavcodec/rv34vlc.h
+++ b/libavcodec/rv34vlc.h
@@ -2,20 +2,20 @@
  * RealVideo 3/4 decoder
  * Copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c
index f95622a..ff0ef91 100644
--- a/libavcodec/rv40.c
+++ b/libavcodec/rv40.c
@@ -2,20 +2,20 @@
  * RV40 decoder
  * Copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -229,8 +229,11 @@
     int prev_type = 0;
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
 
-    if(!r->s.mb_skip_run)
+    if(!r->s.mb_skip_run) {
         r->s.mb_skip_run = svq3_get_ue_golomb(gb) + 1;
+        if(r->s.mb_skip_run > (unsigned)s->mb_num)
+            return -1;
+    }
 
     if(--r->s.mb_skip_run)
          return RV34_MB_SKIP;
diff --git a/libavcodec/rv40data.h b/libavcodec/rv40data.h
index 42328af..36f9f91 100644
--- a/libavcodec/rv40data.h
+++ b/libavcodec/rv40data.h
@@ -2,20 +2,20 @@
  * RealVideo 4 decoder
  * copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/rv40dsp.c b/libavcodec/rv40dsp.c
index c6968d9..944a628 100644
--- a/libavcodec/rv40dsp.c
+++ b/libavcodec/rv40dsp.c
@@ -2,20 +2,20 @@
  * RV40 decoder motion compensation functions
  * Copyright (c) 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -27,6 +27,7 @@
 #include "avcodec.h"
 #include "dsputil.h"
 #include "rv34dsp.h"
+#include "libavutil/avassert.h"
 #include "libavutil/common.h"
 
 #define RV40_LOWPASS(OPNAME, OP) \
@@ -206,7 +207,7 @@
     int i;\
     int bias = rv40_bias[y>>1][x>>1];\
     \
-    assert(x<8 && y<8 && x>=0 && y>=0);\
+    av_assert2(x<8 && y<8 && x>=0 && y>=0);\
 \
     if(D){\
         for(i = 0; i < h; i++){\
@@ -239,7 +240,7 @@
     int i;\
     int bias = rv40_bias[y>>1][x>>1];\
     \
-    assert(x<8 && y<8 && x>=0 && y>=0);\
+    av_assert2(x<8 && y<8 && x>=0 && y>=0);\
 \
     if(D){\
         for(i = 0; i < h; i++){\
diff --git a/libavcodec/rv40vlc2.h b/libavcodec/rv40vlc2.h
index 2f63fc2..15119a1 100644
--- a/libavcodec/rv40vlc2.h
+++ b/libavcodec/rv40vlc2.h
@@ -2,20 +2,20 @@
  * RealVideo 4 decoder
  * copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/s302m.c b/libavcodec/s302m.c
index 132c094..5058ba0 100644
--- a/libavcodec/s302m.c
+++ b/libavcodec/s302m.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2008 Laurent Aimar <fenrir@videolan.org>
  * Copyright (c) 2009 Baptiste Coudurier <baptiste.coudurier@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -69,6 +69,19 @@
         avctx->sample_fmt = AV_SAMPLE_FMT_S16;
 
     avctx->channels    = channels;
+    switch(channels) {
+        case 2:
+            avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+            break;
+        case 4:
+            avctx->channel_layout = AV_CH_LAYOUT_QUAD;
+            break;
+        case 6:
+            avctx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK;
+            break;
+        case 8:
+            avctx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX;
+    }
     avctx->sample_rate = 48000;
     avctx->bit_rate    = 48000 * avctx->channels * (avctx->bits_per_coded_sample + 4) +
                          32 * (48000 / (buf_size * 8 /
diff --git a/libavcodec/s3tc.c b/libavcodec/s3tc.c
index 62dc356..4e791c8 100644
--- a/libavcodec/s3tc.c
+++ b/libavcodec/s3tc.c
@@ -4,20 +4,20 @@
  *
  * see also: http://wiki.multimedia.cx/index.php?title=S3TC
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/s3tc.h b/libavcodec/s3tc.h
index 25237b9..2d77b3a 100644
--- a/libavcodec/s3tc.h
+++ b/libavcodec/s3tc.h
@@ -2,20 +2,20 @@
  * S3 Texture Compression (S3TC) decoding functions
  * Copyright (c) 2007 by Ivo van Poorten
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/samidec.c b/libavcodec/samidec.c
new file mode 100644
index 0000000..c04b8a3
--- /dev/null
+++ b/libavcodec/samidec.c
@@ -0,0 +1,158 @@
+/*
+ * 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
+ * SAMI subtitle decoder
+ * @see http://msdn.microsoft.com/en-us/library/ms971327.aspx
+ */
+
+#include "ass.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+
+typedef struct {
+    AVBPrint source;
+    AVBPrint content;
+    AVBPrint full;
+} SAMIContext;
+
+static int sami_paragraph_to_ass(AVCodecContext *avctx, const char *src)
+{
+    SAMIContext *sami = avctx->priv_data;
+    int ret = 0;
+    char *tag = NULL;
+    char *dupsrc = av_strdup(src);
+    char *p = dupsrc;
+
+    av_bprint_clear(&sami->content);
+    for (;;) {
+        char *saveptr = NULL;
+        int prev_chr_is_space = 0;
+        AVBPrint *dst = &sami->content;
+
+        /* parse & extract paragraph tag */
+        p = av_stristr(p, "<P");
+        if (!p)
+            break;
+        if (p[2] != '>' && !isspace(p[2])) { // avoid confusion with tags such as <PRE>
+            p++;
+            continue;
+        }
+        if (dst->len) // add a separator with the previous paragraph if there was one
+            av_bprintf(dst, "\\N");
+        tag = av_strtok(p, ">", &saveptr);
+        if (!tag || !saveptr)
+            break;
+        p = saveptr;
+
+        /* check if the current paragraph is the "source" (speaker name) */
+        if (av_stristr(tag, "ID=Source") || av_stristr(tag, "ID=\"Source\"")) {
+            dst = &sami->source;
+            av_bprint_clear(dst);
+        }
+
+        /* if empty event -> skip subtitle */
+        while (isspace(*p))
+            p++;
+        if (!strncmp(p, "&nbsp;", 6)) {
+            ret = -1;
+            goto end;
+        }
+
+        /* extract the text, stripping most of the tags */
+        while (*p) {
+            if (*p == '<') {
+                if (!av_strncasecmp(p, "<P", 2) && (p[2] == '>' || isspace(p[2])))
+                    break;
+                if (!av_strncasecmp(p, "<BR", 3))
+                    av_bprintf(dst, "\\N");
+                p++;
+                while (*p && *p != '>')
+                    p++;
+                if (!*p)
+                    break;
+                if (*p == '>')
+                    p++;
+            }
+            if (!isspace(*p))
+                av_bprint_chars(dst, *p, 1);
+            else if (!prev_chr_is_space)
+                av_bprint_chars(dst, ' ', 1);
+            prev_chr_is_space = isspace(*p);
+            p++;
+        }
+    }
+
+    av_bprint_clear(&sami->full);
+    if (sami->source.len)
+        av_bprintf(&sami->full, "{\\i1}%s{\\i0}\\N", sami->source.str);
+    av_bprintf(&sami->full, "%s\r\n", sami->content.str);
+
+end:
+    av_free(dupsrc);
+    return ret;
+}
+
+static int sami_decode_frame(AVCodecContext *avctx,
+                             void *data, int *got_sub_ptr, AVPacket *avpkt)
+{
+    AVSubtitle *sub = data;
+    const char *ptr = avpkt->data;
+    SAMIContext *sami = avctx->priv_data;
+
+    if (ptr && avpkt->size > 0 && !sami_paragraph_to_ass(avctx, ptr)) {
+        int ts_start     = av_rescale_q(avpkt->pts, avctx->time_base, (AVRational){1,100});
+        int ts_duration  = avpkt->duration != -1 ?
+                           av_rescale_q(avpkt->duration, avctx->time_base, (AVRational){1,100}) : -1;
+        ff_ass_add_rect(sub, sami->full.str, ts_start, ts_duration, 0);
+    }
+    *got_sub_ptr = sub->num_rects > 0;
+    return avpkt->size;
+}
+
+static av_cold int sami_init(AVCodecContext *avctx)
+{
+    SAMIContext *sami = avctx->priv_data;
+    av_bprint_init(&sami->source,  0, 2048);
+    av_bprint_init(&sami->content, 0, 2048);
+    av_bprint_init(&sami->full,    0, 2048);
+    return ff_ass_subtitle_header_default(avctx);
+}
+
+static av_cold int sami_close(AVCodecContext *avctx)
+{
+    SAMIContext *sami = avctx->priv_data;
+    av_bprint_finalize(&sami->source,  NULL);
+    av_bprint_finalize(&sami->content, NULL);
+    av_bprint_finalize(&sami->full,    NULL);
+    return 0;
+}
+
+AVCodec ff_sami_decoder = {
+    .name           = "sami",
+    .long_name      = NULL_IF_CONFIG_SMALL("SAMI subtitle"),
+    .type           = AVMEDIA_TYPE_SUBTITLE,
+    .id             = AV_CODEC_ID_SAMI,
+    .priv_data_size = sizeof(SAMIContext),
+    .init           = sami_init,
+    .close          = sami_close,
+    .decode         = sami_decode_frame,
+};
diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c
new file mode 100644
index 0000000..c39d269
--- /dev/null
+++ b/libavcodec/sanm.c
@@ -0,0 +1,1282 @@
+/*
+ * LucasArts Smush video decoder
+ * Copyright (c) 2006 Cyril Zorin
+ * Copyright (c) 2011 Konstantin Shishkov
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+// #define DEBUG 1
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "libavutil/bswap.h"
+#include "libavcodec/dsputil.h"
+#include "sanm_data.h"
+
+#define NGLYPHS 256
+
+typedef struct {
+    AVCodecContext *avctx;
+    GetByteContext gb;
+
+    int version, subversion;
+    uint32_t pal[256];
+    int16_t delta_pal[768];
+
+    int pitch;
+    int width, height;
+    int aligned_width, aligned_height;
+    int prev_seq;
+
+    AVFrame frame, *output;
+    uint16_t *frm0, *frm1, *frm2;
+    uint8_t *stored_frame;
+    uint32_t frm0_size, frm1_size, frm2_size;
+    uint32_t stored_frame_size;
+
+    uint8_t *rle_buf;
+    unsigned int rle_buf_size;
+
+    int rotate_code;
+
+    long npixels, buf_size;
+
+    uint16_t codebook[256];
+    uint16_t small_codebook[4];
+
+    int8_t p4x4glyphs[NGLYPHS][16];
+    int8_t p8x8glyphs[NGLYPHS][64];
+} SANMVideoContext;
+
+typedef struct {
+    int seq_num, codec, rotate_code, rle_output_size;
+
+    uint16_t bg_color;
+    uint32_t width, height;
+} SANMFrameHeader;
+
+enum GlyphEdge {
+    LEFT_EDGE,
+    TOP_EDGE,
+    RIGHT_EDGE,
+    BOTTOM_EDGE,
+    NO_EDGE
+};
+
+enum GlyphDir {
+    DIR_LEFT,
+    DIR_UP,
+    DIR_RIGHT,
+    DIR_DOWN,
+    NO_DIR
+};
+
+/**
+ * Return enum GlyphEdge of box where point (x, y) lies.
+ *
+ * @param x x point coordinate
+ * @param y y point coordinate
+ * @param edge_size box width/height.
+ */
+static enum GlyphEdge which_edge(int x, int y, int edge_size)
+{
+    const int edge_max = edge_size - 1;
+
+    if (!y) {
+        return BOTTOM_EDGE;
+    } else if (y == edge_max) {
+        return TOP_EDGE;
+    } else if (!x) {
+        return LEFT_EDGE;
+    } else if (x == edge_max) {
+        return RIGHT_EDGE;
+    } else {
+        return NO_EDGE;
+    }
+}
+
+static enum GlyphDir which_direction(enum GlyphEdge edge0, enum GlyphEdge edge1)
+{
+    if ((edge0 == LEFT_EDGE && edge1 == RIGHT_EDGE) ||
+        (edge1 == LEFT_EDGE && edge0 == RIGHT_EDGE) ||
+        (edge0 == BOTTOM_EDGE && edge1 != TOP_EDGE) ||
+        (edge1 == BOTTOM_EDGE && edge0 != TOP_EDGE)) {
+        return DIR_UP;
+    } else if ((edge0 == TOP_EDGE && edge1 != BOTTOM_EDGE) ||
+               (edge1 == TOP_EDGE && edge0 != BOTTOM_EDGE)) {
+        return DIR_DOWN;
+    } else if ((edge0 == LEFT_EDGE && edge1 != RIGHT_EDGE) ||
+               (edge1 == LEFT_EDGE && edge0 != RIGHT_EDGE)) {
+        return DIR_LEFT;
+    } else if ((edge0 == TOP_EDGE && edge1 == BOTTOM_EDGE) ||
+               (edge1 == TOP_EDGE && edge0 == BOTTOM_EDGE) ||
+               (edge0 == RIGHT_EDGE && edge1 != LEFT_EDGE) ||
+               (edge1 == RIGHT_EDGE && edge0 != LEFT_EDGE)) {
+        return DIR_RIGHT;
+    }
+
+    return NO_DIR;
+}
+
+/**
+ * Interpolate two points.
+ */
+static void interp_point(int8_t *points, int x0, int y0, int x1, int y1,
+                         int pos, int npoints)
+{
+    if (npoints) {
+        points[0] = (x0 * pos + x1 * (npoints - pos) + (npoints >> 1)) / npoints;
+        points[1] = (y0 * pos + y1 * (npoints - pos) + (npoints >> 1)) / npoints;
+    } else {
+        points[0] = x0;
+        points[1] = y0;
+    }
+}
+
+/**
+ * Construct glyphs by iterating through vectors coordinates.
+ *
+ * @param pglyphs pointer to table where glyphs are stored
+ * @param xvec pointer to x component of vectors coordinates
+ * @param yvec pointer to y component of vectors coordinates
+ * @param side_length glyph width/height.
+ */
+static void make_glyphs(int8_t *pglyphs, const int8_t *xvec, const int8_t *yvec,
+                        const int side_length)
+{
+    const int glyph_size = side_length * side_length;
+    int8_t *pglyph = pglyphs;
+
+    int i, j;
+    for (i = 0; i < GLYPH_COORD_VECT_SIZE; i++) {
+        int x0    = xvec[i];
+        int y0    = yvec[i];
+        enum GlyphEdge edge0 = which_edge(x0, y0, side_length);
+
+        for (j = 0; j < GLYPH_COORD_VECT_SIZE; j++, pglyph += glyph_size) {
+            int x1      = xvec[j];
+            int y1      = yvec[j];
+            enum GlyphEdge edge1   = which_edge(x1, y1, side_length);
+            enum GlyphDir  dir     = which_direction(edge0, edge1);
+            int npoints = FFMAX(FFABS(x1 - x0), FFABS(y1 - y0));
+            int ipoint;
+
+            for (ipoint = 0; ipoint <= npoints; ipoint++) {
+                int8_t point[2];
+                int irow, icol;
+
+                interp_point(point, x0, y0, x1, y1, ipoint, npoints);
+
+                switch (dir) {
+                case DIR_UP:
+                    for (irow = point[1]; irow >= 0; irow--)
+                        pglyph[point[0] + irow * side_length] = 1;
+                    break;
+
+                case DIR_DOWN:
+                    for (irow = point[1]; irow < side_length; irow++)
+                        pglyph[point[0] + irow * side_length] = 1;
+                    break;
+
+                case DIR_LEFT:
+                    for (icol = point[0]; icol >= 0; icol--)
+                        pglyph[icol + point[1] * side_length] = 1;
+                    break;
+
+                case DIR_RIGHT:
+                    for (icol = point[0]; icol < side_length; icol++)
+                        pglyph[icol + point[1] * side_length] = 1;
+                    break;
+                }
+            }
+        }
+    }
+}
+
+static void init_sizes(SANMVideoContext *ctx, int width, int height)
+{
+    ctx->width   = width;
+    ctx->height  = height;
+    ctx->npixels = width * height;
+
+    ctx->aligned_width  = FFALIGN(width,  8);
+    ctx->aligned_height = FFALIGN(height, 8);
+
+    ctx->buf_size = ctx->aligned_width * ctx->aligned_height * sizeof(ctx->frm0[0]);
+    ctx->pitch    = width;
+}
+
+static void destroy_buffers(SANMVideoContext *ctx)
+{
+    av_freep(&ctx->frm0);
+    av_freep(&ctx->frm1);
+    av_freep(&ctx->frm2);
+    av_freep(&ctx->stored_frame);
+    av_freep(&ctx->rle_buf);
+}
+
+static av_cold int init_buffers(SANMVideoContext *ctx)
+{
+    av_fast_padded_malloc(&ctx->frm0, &ctx->frm0_size, ctx->buf_size);
+    av_fast_padded_malloc(&ctx->frm1, &ctx->frm1_size, ctx->buf_size);
+    av_fast_padded_malloc(&ctx->frm2, &ctx->frm2_size, ctx->buf_size);
+    if (!ctx->version)
+        av_fast_padded_malloc(&ctx->stored_frame, &ctx->stored_frame_size, ctx->buf_size);
+
+    if (!ctx->frm0 || !ctx->frm1 || !ctx->frm2 || (!ctx->stored_frame && !ctx->version)) {
+        destroy_buffers(ctx);
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static void rotate_bufs(SANMVideoContext *ctx, int rotate_code)
+{
+    av_dlog(ctx->avctx, "rotate %d\n", rotate_code);
+    if (rotate_code == 2)
+        FFSWAP(uint16_t*, ctx->frm1, ctx->frm2);
+    FFSWAP(uint16_t*, ctx->frm2, ctx->frm0);
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+    SANMVideoContext *ctx = avctx->priv_data;
+
+    ctx->avctx     = avctx;
+    ctx->version   = !avctx->extradata_size;
+
+    avctx->pix_fmt = ctx->version ? AV_PIX_FMT_RGB565 : AV_PIX_FMT_PAL8;
+
+    init_sizes(ctx, avctx->width, avctx->height);
+    if (init_buffers(ctx)) {
+        av_log(avctx, AV_LOG_ERROR, "error allocating buffers\n");
+        return AVERROR(ENOMEM);
+    }
+    ctx->output          = &ctx->frame;
+    ctx->output->data[0] = 0;
+
+    make_glyphs(ctx->p4x4glyphs[0], glyph4_x, glyph4_y, 4);
+    make_glyphs(ctx->p8x8glyphs[0], glyph8_x, glyph8_y, 8);
+
+    if (!ctx->version) {
+        int i;
+
+        if (avctx->extradata_size < 1026) {
+            av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        ctx->subversion = AV_RL16(avctx->extradata);
+        for (i = 0; i < 256; i++)
+            ctx->pal[i] = 0xFF << 24 | AV_RL32(avctx->extradata + 2 + i * 4);
+    }
+
+    return 0;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+    SANMVideoContext *ctx = avctx->priv_data;
+
+    destroy_buffers(ctx);
+
+    if (ctx->frame.data[0]) {
+        avctx->release_buffer(avctx, &ctx->frame);
+        ctx->frame.data[0] = 0;
+    }
+
+    return 0;
+}
+
+static int rle_decode(SANMVideoContext *ctx, uint8_t *dst, const int out_size)
+{
+    int opcode, color, run_len, left = out_size;
+
+    while (left > 0) {
+        opcode = bytestream2_get_byte(&ctx->gb);
+        run_len = (opcode >> 1) + 1;
+        if (run_len > left || bytestream2_get_bytes_left(&ctx->gb) <= 0)
+            return AVERROR_INVALIDDATA;
+
+        if (opcode & 1) {
+            color = bytestream2_get_byte(&ctx->gb);
+            memset(dst, color, run_len);
+        } else {
+            if (bytestream2_get_bytes_left(&ctx->gb) < run_len)
+                return AVERROR_INVALIDDATA;
+            bytestream2_get_bufferu(&ctx->gb, dst, run_len);
+        }
+
+        dst  += run_len;
+        left -= run_len;
+    }
+
+    return 0;
+}
+
+static int old_codec1(SANMVideoContext *ctx, int top,
+                      int left, int width, int height)
+{
+    uint8_t *dst = ((uint8_t*)ctx->frm0) + left + top * ctx->pitch;
+    int i, j, len, flag, code, val, pos, end;
+
+    for (i = 0; i < height; i++) {
+        pos = 0;
+
+        if (bytestream2_get_bytes_left(&ctx->gb) < 2)
+            return AVERROR_INVALIDDATA;
+
+        len = bytestream2_get_le16u(&ctx->gb);
+        end = bytestream2_tell(&ctx->gb) + len;
+
+        while (bytestream2_tell(&ctx->gb) < end) {
+            if (bytestream2_get_bytes_left(&ctx->gb) < 2)
+                return AVERROR_INVALIDDATA;
+
+            code = bytestream2_get_byteu(&ctx->gb);
+            flag = code & 1;
+            code = (code >> 1) + 1;
+            if (pos + code > width)
+                return AVERROR_INVALIDDATA;
+            if (flag) {
+                val = bytestream2_get_byteu(&ctx->gb);
+                if (val)
+                    memset(dst + pos, val, code);
+                pos += code;
+            } else {
+                if (bytestream2_get_bytes_left(&ctx->gb) < code)
+                    return AVERROR_INVALIDDATA;
+                for (j = 0; j < code; j++) {
+                    val = bytestream2_get_byteu(&ctx->gb);
+                    if (val)
+                        dst[pos] = val;
+                    pos++;
+                }
+            }
+        }
+        dst += ctx->pitch;
+    }
+    ctx->rotate_code = 0;
+
+    return 0;
+}
+
+static inline void codec37_mv(uint8_t *dst, const uint8_t *src,
+                              int height, int stride, int x, int y)
+{
+    int pos, i, j;
+
+    pos = x + y * stride;
+    for (j = 0; j < 4; j++) {
+        for (i = 0; i < 4; i++) {
+            if ((pos + i) < 0 || (pos + i) >= height * stride)
+                dst[i] = 0;
+            else
+                dst[i] = src[i];
+        }
+        dst += stride;
+        src += stride;
+        pos += stride;
+    }
+}
+
+static int old_codec37(SANMVideoContext *ctx, int top,
+                       int left, int width, int height)
+{
+    int stride = ctx->pitch;
+    int i, j, k, t;
+    int skip_run = 0;
+    int compr, mvoff, seq, flags;
+    uint32_t decoded_size;
+    uint8_t *dst, *prev;
+
+    compr        = bytestream2_get_byte(&ctx->gb);
+    mvoff        = bytestream2_get_byte(&ctx->gb);
+    seq          = bytestream2_get_le16(&ctx->gb);
+    decoded_size = bytestream2_get_le32(&ctx->gb);
+    bytestream2_skip(&ctx->gb, 4);
+    flags        = bytestream2_get_byte(&ctx->gb);
+    bytestream2_skip(&ctx->gb, 3);
+
+    ctx->rotate_code = 0;
+
+    if (((seq & 1) || !(flags & 1)) && (compr && compr != 2))
+        rotate_bufs(ctx, 1);
+
+    dst  = ((uint8_t*)ctx->frm0) + left + top * stride;
+    prev = ((uint8_t*)ctx->frm2) + left + top * stride;
+
+    if (mvoff > 2) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "invalid motion base value %d\n", mvoff);
+        return AVERROR_INVALIDDATA;
+    }
+    av_dlog(ctx->avctx, "compression %d\n", compr);
+    switch (compr) {
+    case 0:
+        for (i = 0; i < height; i++) {
+            bytestream2_get_buffer(&ctx->gb, dst, width);
+            dst += stride;
+        }
+        memset(ctx->frm1, 0, ctx->height * stride);
+        memset(ctx->frm2, 0, ctx->height * stride);
+        break;
+    case 2:
+        if (rle_decode(ctx, dst, decoded_size))
+            return AVERROR_INVALIDDATA;
+        memset(ctx->frm1, 0, ctx->frm1_size);
+        memset(ctx->frm2, 0, ctx->frm2_size);
+        break;
+    case 3:
+    case 4:
+        if (flags & 4) {
+            for (j = 0; j < height; j += 4) {
+                for (i = 0; i < width; i += 4) {
+                    int code;
+                    if (skip_run) {
+                        skip_run--;
+                        copy_block4(dst + i, prev + i, stride, stride, 4);
+                        continue;
+                    }
+                    if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+                        return AVERROR_INVALIDDATA;
+                    code = bytestream2_get_byteu(&ctx->gb);
+                    switch (code) {
+                    case 0xFF:
+                        if (bytestream2_get_bytes_left(&ctx->gb) < 16)
+                            return AVERROR_INVALIDDATA;
+                        for (k = 0; k < 4; k++)
+                            bytestream2_get_bufferu(&ctx->gb, dst + i + k * stride, 4);
+                        break;
+                    case 0xFE:
+                        if (bytestream2_get_bytes_left(&ctx->gb) < 4)
+                            return AVERROR_INVALIDDATA;
+                        for (k = 0; k < 4; k++)
+                            memset(dst + i + k * stride, bytestream2_get_byteu(&ctx->gb), 4);
+                        break;
+                    case 0xFD:
+                        if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+                            return AVERROR_INVALIDDATA;
+                        t = bytestream2_get_byteu(&ctx->gb);
+                        for (k = 0; k < 4; k++)
+                            memset(dst + i + k * stride, t, 4);
+                        break;
+                    default:
+                        if (compr == 4 && !code) {
+                            if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+                                return AVERROR_INVALIDDATA;
+                            skip_run = bytestream2_get_byteu(&ctx->gb) + 1;
+                            i -= 4;
+                        } else {
+                            int mx, my;
+
+                            mx = c37_mv[(mvoff * 255 + code) * 2    ];
+                            my = c37_mv[(mvoff * 255 + code) * 2 + 1];
+                            codec37_mv(dst + i, prev + i + mx + my * stride,
+                                       ctx->height, stride, i + mx, j + my);
+                        }
+                    }
+                }
+                dst  += stride * 4;
+                prev += stride * 4;
+            }
+        } else {
+            for (j = 0; j < height; j += 4) {
+                for (i = 0; i < width; i += 4) {
+                    int code;
+                    if (skip_run) {
+                        skip_run--;
+                        copy_block4(dst + i, prev + i, stride, stride, 4);
+                        continue;
+                    }
+                    code = bytestream2_get_byte(&ctx->gb);
+                    if (code == 0xFF) {
+                        if (bytestream2_get_bytes_left(&ctx->gb) < 16)
+                            return AVERROR_INVALIDDATA;
+                        for (k = 0; k < 4; k++)
+                            bytestream2_get_bufferu(&ctx->gb, dst + i + k * stride, 4);
+                    } else if (compr == 4 && !code) {
+                        if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+                            return AVERROR_INVALIDDATA;
+                        skip_run = bytestream2_get_byteu(&ctx->gb) + 1;
+                        i -= 4;
+                    } else {
+                        int mx, my;
+
+                        mx = c37_mv[(mvoff * 255 + code) * 2];
+                        my = c37_mv[(mvoff * 255 + code) * 2 + 1];
+                        codec37_mv(dst + i, prev + i + mx + my * stride,
+                                   ctx->height, stride, i + mx, j + my);
+                    }
+                }
+                dst  += stride * 4;
+                prev += stride * 4;
+            }
+        }
+        break;
+    default:
+        av_log(ctx->avctx, AV_LOG_ERROR,
+               "subcodec 37 compression %d not implemented\n", compr);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    return 0;
+}
+
+static int process_block(SANMVideoContext *ctx, uint8_t *dst, uint8_t *prev1,
+                         uint8_t *prev2, int stride, int tbl, int size)
+{
+    int code, k, t;
+    uint8_t colors[2];
+    int8_t *pglyph;
+
+    if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+        return AVERROR_INVALIDDATA;
+
+    code = bytestream2_get_byteu(&ctx->gb);
+    if (code >= 0xF8) {
+        switch (code) {
+        case 0xFF:
+            if (size == 2) {
+                if (bytestream2_get_bytes_left(&ctx->gb) < 4)
+                    return AVERROR_INVALIDDATA;
+                dst[0]        = bytestream2_get_byteu(&ctx->gb);
+                dst[1]        = bytestream2_get_byteu(&ctx->gb);
+                dst[0+stride] = bytestream2_get_byteu(&ctx->gb);
+                dst[1+stride] = bytestream2_get_byteu(&ctx->gb);
+            } else {
+                size >>= 1;
+                if (process_block(ctx, dst, prev1, prev2, stride, tbl, size))
+                    return AVERROR_INVALIDDATA;
+                if (process_block(ctx, dst + size, prev1 + size, prev2 + size,
+                                  stride, tbl, size))
+                    return AVERROR_INVALIDDATA;
+                dst   += size * stride;
+                prev1 += size * stride;
+                prev2 += size * stride;
+                if (process_block(ctx, dst, prev1, prev2, stride, tbl, size))
+                    return AVERROR_INVALIDDATA;
+                if (process_block(ctx, dst + size, prev1 + size, prev2 + size,
+                                  stride, tbl, size))
+                    return AVERROR_INVALIDDATA;
+            }
+            break;
+        case 0xFE:
+            if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+                return AVERROR_INVALIDDATA;
+
+            t = bytestream2_get_byteu(&ctx->gb);
+            for (k = 0; k < size; k++)
+                memset(dst + k * stride, t, size);
+            break;
+        case 0xFD:
+            if (bytestream2_get_bytes_left(&ctx->gb) < 3)
+                return AVERROR_INVALIDDATA;
+
+            code = bytestream2_get_byteu(&ctx->gb);
+            pglyph = (size == 8) ? ctx->p8x8glyphs[code] : ctx->p4x4glyphs[code];
+            bytestream2_get_bufferu(&ctx->gb, colors, 2);
+
+            for (k = 0; k < size; k++)
+                for (t = 0; t < size; t++)
+                    dst[t + k * stride] = colors[!*pglyph++];
+            break;
+        case 0xFC:
+            for (k = 0; k < size; k++)
+                memcpy(dst + k * stride, prev1 + k * stride, size);
+            break;
+        default:
+            k = bytestream2_tell(&ctx->gb);
+            bytestream2_seek(&ctx->gb, tbl + (code & 7), SEEK_SET);
+            t = bytestream2_get_byte(&ctx->gb);
+            bytestream2_seek(&ctx->gb, k, SEEK_SET);
+            for (k = 0; k < size; k++)
+                memset(dst + k * stride, t, size);
+        }
+    } else {
+        int mx = motion_vectors[code][0];
+        int my = motion_vectors[code][1];
+        for (k = 0; k < size; k++)
+            memcpy(dst + k * stride, prev2 + mx + (my + k) * stride, size);
+    }
+
+    return 0;
+}
+
+static int old_codec47(SANMVideoContext *ctx, int top,
+                       int left, int width, int height)
+{
+    int i, j, seq, compr, new_rot, tbl_pos, skip;
+    int stride     = ctx->pitch;
+    uint8_t *dst   = ((uint8_t*)ctx->frm0) + left + top * stride;
+    uint8_t *prev1 = (uint8_t*)ctx->frm1;
+    uint8_t *prev2 = (uint8_t*)ctx->frm2;
+    uint32_t decoded_size;
+
+    tbl_pos = bytestream2_tell(&ctx->gb);
+    seq     = bytestream2_get_le16(&ctx->gb);
+    compr   = bytestream2_get_byte(&ctx->gb);
+    new_rot = bytestream2_get_byte(&ctx->gb);
+    skip    = bytestream2_get_byte(&ctx->gb);
+    bytestream2_skip(&ctx->gb, 9);
+    decoded_size = bytestream2_get_le32(&ctx->gb);
+    bytestream2_skip(&ctx->gb, 8);
+
+    if (skip & 1)
+        bytestream2_skip(&ctx->gb, 0x8080);
+    if (!seq) {
+        ctx->prev_seq = -1;
+        memset(prev1, 0, ctx->height * stride);
+        memset(prev2, 0, ctx->height * stride);
+    }
+    av_dlog(ctx->avctx, "compression %d\n", compr);
+    switch (compr) {
+    case 0:
+        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);
+            dst += stride;
+        }
+        break;
+    case 1:
+        if (bytestream2_get_bytes_left(&ctx->gb) < ((width + 1) >> 1) * ((height + 1) >> 1))
+            return AVERROR_INVALIDDATA;
+        for (j = 0; j < height; j += 2) {
+            for (i = 0; i < width; i += 2) {
+                dst[i] = dst[i + 1] =
+                dst[stride + i] = dst[stride + i + 1] = bytestream2_get_byteu(&ctx->gb);
+            }
+            dst += stride * 2;
+        }
+        break;
+    case 2:
+        if (seq == ctx->prev_seq + 1) {
+            for (j = 0; j < height; j += 8) {
+                for (i = 0; i < width; i += 8) {
+                    if (process_block(ctx, dst + i, prev1 + i, prev2 + i, stride,
+                                      tbl_pos + 8, 8))
+                        return AVERROR_INVALIDDATA;
+                }
+                dst   += stride * 8;
+                prev1 += stride * 8;
+                prev2 += stride * 8;
+            }
+        }
+        break;
+    case 3:
+        memcpy(ctx->frm0, ctx->frm2, ctx->pitch * ctx->height);
+        break;
+    case 4:
+        memcpy(ctx->frm0, ctx->frm1, ctx->pitch * ctx->height);
+        break;
+    case 5:
+        if (rle_decode(ctx, dst, decoded_size))
+            return AVERROR_INVALIDDATA;
+        break;
+    default:
+        av_log(ctx->avctx, AV_LOG_ERROR,
+               "subcodec 47 compression %d not implemented\n", compr);
+        return AVERROR_PATCHWELCOME;
+    }
+    if (seq == ctx->prev_seq + 1)
+        ctx->rotate_code = new_rot;
+    else
+        ctx->rotate_code = 0;
+    ctx->prev_seq = seq;
+
+    return 0;
+}
+
+static int process_frame_obj(SANMVideoContext *ctx)
+{
+    uint16_t codec, top, left, w, h;
+
+    codec = bytestream2_get_le16u(&ctx->gb);
+    left  = bytestream2_get_le16u(&ctx->gb);
+    top   = bytestream2_get_le16u(&ctx->gb);
+    w     = bytestream2_get_le16u(&ctx->gb);
+    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 (init_buffers(ctx)) {
+            av_log(ctx->avctx, AV_LOG_ERROR, "error resizing buffers\n");
+            return AVERROR(ENOMEM);
+        }
+    }
+    bytestream2_skip(&ctx->gb, 4);
+
+    av_dlog(ctx->avctx, "subcodec %d\n", codec);
+    switch (codec) {
+    case 1:
+    case 3:
+        return old_codec1(ctx, top, left, w, h);
+        break;
+    case 37:
+        return old_codec37(ctx, top, left, w, h);
+        break;
+    case 47:
+        return old_codec47(ctx, top, left, w, h);
+        break;
+    default:
+        av_log_ask_for_sample(ctx->avctx, "unknown subcodec %d\n", codec);
+        return AVERROR_PATCHWELCOME;
+    }
+}
+
+static int decode_0(SANMVideoContext *ctx)
+{
+    uint16_t *frm = ctx->frm0;
+    int x, y;
+
+    if (bytestream2_get_bytes_left(&ctx->gb) < ctx->width * ctx->height * 2) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "insufficient data for raw frame\n");
+        return AVERROR_INVALIDDATA;
+    }
+    for (y = 0; y < ctx->height; y++) {
+        for (x = 0; x < ctx->width; x++)
+            frm[x] = bytestream2_get_le16u(&ctx->gb);
+        frm += ctx->pitch;
+    }
+    return 0;
+}
+
+static int decode_nop(SANMVideoContext *ctx)
+{
+    av_log_ask_for_sample(ctx->avctx, "unknown/unsupported compression type\n");
+    return AVERROR_PATCHWELCOME;
+}
+
+static void copy_block(uint16_t *pdest, uint16_t *psrc, int block_size, int pitch)
+{
+    uint8_t *dst = (uint8_t *)pdest;
+    uint8_t *src = (uint8_t *)psrc;
+    int stride = pitch * 2;
+
+    switch (block_size) {
+    case 2:
+        copy_block4(dst, src, stride, stride, 2);
+        break;
+    case 4:
+        copy_block8(dst, src, stride, stride, 4);
+        break;
+    case 8:
+        copy_block16(dst, src, stride, stride, 8);
+        break;
+    }
+}
+
+static void fill_block(uint16_t *pdest, uint16_t color, int block_size, int pitch)
+{
+    int x, y;
+
+    pitch -= block_size;
+    for (y = 0; y < block_size; y++, pdest += pitch)
+        for (x = 0; x < block_size; x++)
+            *pdest++ = color;
+}
+
+static int draw_glyph(SANMVideoContext *ctx, uint16_t *dst, int index, uint16_t fg_color,
+                      uint16_t bg_color, int block_size, int pitch)
+{
+    int8_t *pglyph;
+    uint16_t colors[2] = { fg_color, bg_color };
+    int x, y;
+
+    if (index >= NGLYPHS) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "ignoring nonexistent glyph #%u\n", index);
+        return AVERROR_INVALIDDATA;
+    }
+
+    pglyph = block_size == 8 ? ctx->p8x8glyphs[index] : ctx->p4x4glyphs[index];
+    pitch -= block_size;
+
+    for (y = 0; y < block_size; y++, dst += pitch)
+        for (x = 0; x < block_size; x++)
+            *dst++ = colors[*pglyph++];
+    return 0;
+}
+
+static int opcode_0xf7(SANMVideoContext *ctx, int cx, int cy, int block_size, int pitch)
+{
+    uint16_t *dst = ctx->frm0 + cx + cy * ctx->pitch;
+
+    if (block_size == 2) {
+        uint32_t indices;
+
+        if (bytestream2_get_bytes_left(&ctx->gb) < 4)
+            return AVERROR_INVALIDDATA;
+
+        indices        = bytestream2_get_le32u(&ctx->gb);
+        dst[0]         = ctx->codebook[indices & 0xFF]; indices >>= 8;
+        dst[1]         = ctx->codebook[indices & 0xFF]; indices >>= 8;
+        dst[pitch]     = ctx->codebook[indices & 0xFF]; indices >>= 8;
+        dst[pitch + 1] = ctx->codebook[indices & 0xFF];
+    } else {
+        uint16_t fgcolor, bgcolor;
+        int glyph;
+
+        if (bytestream2_get_bytes_left(&ctx->gb) < 3)
+            return AVERROR_INVALIDDATA;
+
+        glyph   = bytestream2_get_byteu(&ctx->gb);
+        bgcolor = ctx->codebook[bytestream2_get_byteu(&ctx->gb)];
+        fgcolor = ctx->codebook[bytestream2_get_byteu(&ctx->gb)];
+
+        draw_glyph(ctx, dst, glyph, fgcolor, bgcolor, block_size, pitch);
+    }
+    return 0;
+}
+
+static int opcode_0xf8(SANMVideoContext *ctx, int cx, int cy, int block_size, int pitch)
+{
+    uint16_t *dst = ctx->frm0 + cx + cy * ctx->pitch;
+
+    if (block_size == 2) {
+        if (bytestream2_get_bytes_left(&ctx->gb) < 8)
+            return AVERROR_INVALIDDATA;
+
+        dst[0]         = bytestream2_get_le16u(&ctx->gb);
+        dst[1]         = bytestream2_get_le16u(&ctx->gb);
+        dst[pitch]     = bytestream2_get_le16u(&ctx->gb);
+        dst[pitch + 1] = bytestream2_get_le16u(&ctx->gb);
+    } else {
+        uint16_t fgcolor, bgcolor;
+        int glyph;
+
+        if (bytestream2_get_bytes_left(&ctx->gb) < 5)
+            return AVERROR_INVALIDDATA;
+
+        glyph   = bytestream2_get_byteu(&ctx->gb);
+        bgcolor = bytestream2_get_le16u(&ctx->gb);
+        fgcolor = bytestream2_get_le16u(&ctx->gb);
+
+        draw_glyph(ctx, dst, glyph, fgcolor, bgcolor, block_size, pitch);
+    }
+    return 0;
+}
+
+static int good_mvec(SANMVideoContext *ctx, int cx, int cy, int mx, int my,
+                     int block_size)
+{
+    int start_pos = cx + mx + (cy + my) * ctx->pitch;
+    int end_pos = start_pos + (block_size - 1) * (ctx->pitch + 1);
+
+    int good = start_pos >= 0 && end_pos < (ctx->buf_size >> 1);
+
+    if (!good) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "ignoring invalid motion vector (%i, %i)->(%u, %u), block size = %u\n",
+               cx + mx, cy + my, cx, cy, block_size);
+    }
+
+    return good;
+}
+
+static int codec2subblock(SANMVideoContext *ctx, int cx, int cy, int blk_size)
+{
+    int16_t mx, my, index;
+    int opcode;
+
+    if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+        return AVERROR_INVALIDDATA;
+
+    opcode = bytestream2_get_byteu(&ctx->gb);
+
+    av_dlog(ctx->avctx, "opcode 0x%0X cx %d cy %d blk %d\n", opcode, cx, cy, blk_size);
+    switch (opcode) {
+    default:
+        mx = motion_vectors[opcode][0];
+        my = motion_vectors[opcode][1];
+
+        if (good_mvec(ctx, cx, cy, mx, my, blk_size)) {
+            copy_block(ctx->frm0 + cx      + ctx->pitch *  cy,
+                       ctx->frm2 + cx + mx + ctx->pitch * (cy + my),
+                       blk_size, ctx->pitch);
+        }
+        break;
+    case 0xF5:
+        if (bytestream2_get_bytes_left(&ctx->gb) < 2)
+            return AVERROR_INVALIDDATA;
+        index = bytestream2_get_le16u(&ctx->gb);
+
+        mx = index % ctx->width;
+        my = index / ctx->width;
+
+        if (good_mvec(ctx, cx, cy, mx, my, blk_size)) {
+            copy_block(ctx->frm0 + cx      + ctx->pitch *  cy,
+                       ctx->frm2 + cx + mx + ctx->pitch * (cy + my),
+                       blk_size, ctx->pitch);
+        }
+        break;
+    case 0xF6:
+        copy_block(ctx->frm0 + cx + ctx->pitch * cy,
+                   ctx->frm1 + cx + ctx->pitch * cy,
+                   blk_size, ctx->pitch);
+        break;
+    case 0xF7:
+        opcode_0xf7(ctx, cx, cy, blk_size, ctx->pitch);
+        break;
+
+    case 0xF8:
+        opcode_0xf8(ctx, cx, cy, blk_size, ctx->pitch);
+        break;
+    case 0xF9:
+    case 0xFA:
+    case 0xFB:
+    case 0xFC:
+        fill_block(ctx->frm0 + cx + cy * ctx->pitch,
+                   ctx->small_codebook[opcode - 0xf9], blk_size, ctx->pitch);
+        break;
+    case 0xFD:
+        if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+            return AVERROR_INVALIDDATA;
+        fill_block(ctx->frm0 + cx + cy * ctx->pitch,
+                   ctx->codebook[bytestream2_get_byteu(&ctx->gb)], blk_size, ctx->pitch);
+        break;
+    case 0xFE:
+        if (bytestream2_get_bytes_left(&ctx->gb) < 2)
+            return AVERROR_INVALIDDATA;
+        fill_block(ctx->frm0 + cx + cy * ctx->pitch,
+                   bytestream2_get_le16u(&ctx->gb), blk_size, ctx->pitch);
+        break;
+    case 0xFF:
+        if (blk_size == 2) {
+            opcode_0xf8(ctx, cx, cy, blk_size, ctx->pitch);
+        } else {
+            blk_size >>= 1;
+            if (codec2subblock(ctx, cx           , cy           , blk_size))
+                return AVERROR_INVALIDDATA;
+            if (codec2subblock(ctx, cx + blk_size, cy           , blk_size))
+                return AVERROR_INVALIDDATA;
+            if (codec2subblock(ctx, cx           , cy + blk_size, blk_size))
+                return AVERROR_INVALIDDATA;
+            if (codec2subblock(ctx, cx + blk_size, cy + blk_size, blk_size))
+                return AVERROR_INVALIDDATA;
+        }
+        break;
+    }
+    return 0;
+}
+
+static int decode_2(SANMVideoContext *ctx)
+{
+    int cx, cy, ret;
+
+    for (cy = 0; cy < ctx->aligned_height; cy += 8) {
+        for (cx = 0; cx < ctx->aligned_width; cx += 8) {
+            if (ret = codec2subblock(ctx, cx, cy, 8))
+                return ret;
+        }
+    }
+
+    return 0;
+}
+
+static int decode_3(SANMVideoContext *ctx)
+{
+    memcpy(ctx->frm0, ctx->frm2, ctx->frm2_size);
+    return 0;
+}
+
+static int decode_4(SANMVideoContext *ctx)
+{
+    memcpy(ctx->frm0, ctx->frm1, ctx->frm1_size);
+    return 0;
+}
+
+static int decode_5(SANMVideoContext *ctx)
+{
+#if HAVE_BIGENDIAN
+    uint16_t *frm;
+    int npixels;
+#endif
+    uint8_t *dst = (uint8_t*)ctx->frm0;
+
+    if (rle_decode(ctx, dst, ctx->buf_size))
+        return AVERROR_INVALIDDATA;
+
+#if HAVE_BIGENDIAN
+    npixels = ctx->npixels;
+    frm = ctx->frm0;
+    while (npixels--)
+        *frm++ = av_bswap16(*frm);
+#endif
+
+    return 0;
+}
+
+static int decode_6(SANMVideoContext *ctx)
+{
+    int npixels = ctx->npixels;
+    uint16_t *frm = ctx->frm0;
+
+    if (bytestream2_get_bytes_left(&ctx->gb) < npixels) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "insufficient data for frame\n");
+        return AVERROR_INVALIDDATA;
+    }
+    while (npixels--)
+        *frm++ = ctx->codebook[bytestream2_get_byteu(&ctx->gb)];
+
+    return 0;
+}
+
+static int decode_8(SANMVideoContext *ctx)
+{
+    uint16_t *pdest = ctx->frm0;
+    uint8_t *rsrc;
+    long npixels = ctx->npixels;
+
+    av_fast_malloc(&ctx->rle_buf, &ctx->rle_buf_size, npixels);
+    if (!ctx->rle_buf) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "RLE buffer allocation failed\n");
+        return AVERROR(ENOMEM);
+    }
+    rsrc = ctx->rle_buf;
+
+    if (rle_decode(ctx, rsrc, npixels))
+        return AVERROR_INVALIDDATA;
+
+    while (npixels--)
+        *pdest++ = ctx->codebook[*rsrc++];
+
+    return 0;
+}
+
+typedef int (*frm_decoder)(SANMVideoContext *ctx);
+
+static const frm_decoder v1_decoders[] = {
+    decode_0, decode_nop, decode_2, decode_3, decode_4, decode_5,
+    decode_6, decode_nop, decode_8
+};
+
+static int read_frame_header(SANMVideoContext *ctx, SANMFrameHeader *hdr)
+{
+    int i, ret;
+
+    if ((ret = bytestream2_get_bytes_left(&ctx->gb)) < 560) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "too short input frame (%d bytes)\n",
+               ret);
+        return AVERROR_INVALIDDATA;
+    }
+    bytestream2_skip(&ctx->gb, 8); // skip pad
+
+    hdr->width  = bytestream2_get_le32u(&ctx->gb);
+    hdr->height = bytestream2_get_le32u(&ctx->gb);
+
+    if (hdr->width != ctx->width || hdr->height != ctx->height) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "variable size frames are not implemented\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    hdr->seq_num     = bytestream2_get_le16u(&ctx->gb);
+    hdr->codec       = bytestream2_get_byteu(&ctx->gb);
+    hdr->rotate_code = bytestream2_get_byteu(&ctx->gb);
+
+    bytestream2_skip(&ctx->gb, 4); // skip pad
+
+    for (i = 0; i < 4; i++)
+        ctx->small_codebook[i] = bytestream2_get_le16u(&ctx->gb);
+    hdr->bg_color = bytestream2_get_le16u(&ctx->gb);
+
+    bytestream2_skip(&ctx->gb, 2); // skip pad
+
+    hdr->rle_output_size = bytestream2_get_le32u(&ctx->gb);
+    for (i = 0; i < 256; i++)
+        ctx->codebook[i] = bytestream2_get_le16u(&ctx->gb);
+
+    bytestream2_skip(&ctx->gb, 8); // skip pad
+
+    av_dlog(ctx->avctx, "subcodec %d\n", hdr->codec);
+    return 0;
+}
+
+static void fill_frame(uint16_t *pbuf, int buf_size, uint16_t color)
+{
+    while (buf_size--)
+        *pbuf++ = color;
+}
+
+static int copy_output(SANMVideoContext *ctx, SANMFrameHeader *hdr)
+{
+    uint8_t *dst;
+    const uint8_t *src = (uint8_t*) ctx->frm0;
+    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) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
+    }
+
+    dst      = ctx->output->data[0];
+    dstpitch = ctx->output->linesize[0];
+
+    while (height--) {
+        memcpy(dst, src, srcpitch);
+        src += srcpitch;
+        dst += dstpitch;
+    }
+
+    return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data,
+                        int *got_frame_ptr, AVPacket *pkt)
+{
+    SANMVideoContext *ctx = avctx->priv_data;
+    int i, ret;
+
+    bytestream2_init(&ctx->gb, pkt->data, pkt->size);
+    if (ctx->output->data[0])
+        avctx->release_buffer(avctx, ctx->output);
+
+    if (!ctx->version) {
+        int to_store = 0;
+
+        while (bytestream2_get_bytes_left(&ctx->gb) >= 8) {
+            uint32_t sig, size;
+            int pos;
+
+            sig  = bytestream2_get_be32u(&ctx->gb);
+            size = bytestream2_get_be32u(&ctx->gb);
+            pos  = bytestream2_tell(&ctx->gb);
+
+            if (bytestream2_get_bytes_left(&ctx->gb) < size) {
+                av_log(avctx, AV_LOG_ERROR, "incorrect chunk size %d\n", size);
+                break;
+            }
+            switch (sig) {
+            case MKBETAG('N', 'P', 'A', 'L'):
+                if (size != 256 * 3) {
+                    av_log(avctx, AV_LOG_ERROR, "incorrect palette block size %d\n",
+                           size);
+                    return AVERROR_INVALIDDATA;
+                }
+                for (i = 0; i < 256; i++)
+                    ctx->pal[i] = 0xFF << 24 | bytestream2_get_be24u(&ctx->gb);
+                break;
+            case MKBETAG('F', 'O', 'B', 'J'):
+                if (size < 16)
+                    return AVERROR_INVALIDDATA;
+                if (ret = process_frame_obj(ctx))
+                    return ret;
+                break;
+            case MKBETAG('X', 'P', 'A', 'L'):
+                if (size == 6 || size == 4) {
+                    uint8_t tmp[3];
+                    int j;
+
+                    for (i = 0; i < 256; i++) {
+                        for (j = 0; j < 3; j++) {
+                            int t = (ctx->pal[i] >> (16 - j * 8)) & 0xFF;
+                            tmp[j] = av_clip_uint8((t * 129 + ctx->delta_pal[i * 3 + j]) >> 7);
+                        }
+                        ctx->pal[i] = 0xFF << 24 | AV_RB24(tmp);
+                    }
+                } else {
+                    if (size < 768 * 2 + 4) {
+                        av_log(avctx, AV_LOG_ERROR, "incorrect palette change block size %d\n",
+                               size);
+                        return AVERROR_INVALIDDATA;
+                    }
+                    bytestream2_skipu(&ctx->gb, 4);
+                    for (i = 0; i < 768; i++)
+                        ctx->delta_pal[i] = bytestream2_get_le16u(&ctx->gb);
+                    if (size >= 768 * 5 + 4) {
+                        for (i = 0; i < 256; i++)
+                            ctx->pal[i] = 0xFF << 24 | bytestream2_get_be24u(&ctx->gb);
+                    } else {
+                        memset(ctx->pal, 0, sizeof(ctx->pal));
+                    }
+                }
+                break;
+            case MKBETAG('S', 'T', 'O', 'R'):
+                to_store = 1;
+                break;
+            case MKBETAG('F', 'T', 'C', 'H'):
+                memcpy(ctx->frm0, ctx->stored_frame, ctx->buf_size);
+                break;
+            default:
+                bytestream2_skip(&ctx->gb, size);
+                av_log(avctx, AV_LOG_DEBUG, "unknown/unsupported chunk %x\n", sig);
+                break;
+            }
+
+            bytestream2_seek(&ctx->gb, pos + size, SEEK_SET);
+            if (size & 1)
+                bytestream2_skip(&ctx->gb, 1);
+        }
+        if (to_store)
+            memcpy(ctx->stored_frame, ctx->frm0, ctx->buf_size);
+        if ((ret = copy_output(ctx, NULL)))
+            return ret;
+        memcpy(ctx->output->data[1], ctx->pal, 1024);
+    } else {
+        SANMFrameHeader header;
+
+        if ((ret = read_frame_header(ctx, &header)))
+            return ret;
+
+        ctx->rotate_code = header.rotate_code;
+        if ((ctx->output->key_frame = !header.seq_num)) {
+            ctx->output->pict_type = AV_PICTURE_TYPE_I;
+            fill_frame(ctx->frm1, ctx->npixels, header.bg_color);
+            fill_frame(ctx->frm2, ctx->npixels, header.bg_color);
+        } else {
+            ctx->output->pict_type = AV_PICTURE_TYPE_P;
+        }
+
+        if (header.codec < FF_ARRAY_ELEMS(v1_decoders)) {
+            if ((ret = v1_decoders[header.codec](ctx))) {
+                av_log(avctx, AV_LOG_ERROR,
+                       "subcodec %d: error decoding frame\n", header.codec);
+                return ret;
+            }
+        } else {
+            av_log_ask_for_sample(avctx, "subcodec %d is not implemented\n",
+                   header.codec);
+            return AVERROR_PATCHWELCOME;
+        }
+
+        if ((ret = copy_output(ctx, &header)))
+            return ret;
+    }
+    if (ctx->rotate_code)
+        rotate_bufs(ctx, ctx->rotate_code);
+
+    *got_frame_ptr  = 1;
+    *(AVFrame*)data = *ctx->output;
+
+    return pkt->size;
+}
+
+AVCodec ff_sanm_decoder = {
+    .name           = "sanm",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_SANM,
+    .priv_data_size = sizeof(SANMVideoContext),
+    .init           = decode_init,
+    .close          = decode_end,
+    .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("LucasArts SMUSH video"),
+};
diff --git a/libavcodec/sanm_data.h b/libavcodec/sanm_data.h
new file mode 100644
index 0000000..8fccf38
--- /dev/null
+++ b/libavcodec/sanm_data.h
@@ -0,0 +1,248 @@
+/*
+ * LucasArts Smush video decoder
+ * Copyright (c) 2006 Cyril Zorin
+ *
+ * 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_SANM_DATA_H
+#define AVCODEC_SANM_DATA_H
+
+#include <stdint.h>
+
+#define GLYPH_COORD_VECT_SIZE 16
+
+static const int8_t glyph4_x[GLYPH_COORD_VECT_SIZE] =
+    { 0, 1, 2, 3, 3, 3, 3, 2, 1, 0, 0, 0, 1, 2, 2, 1 };
+static const int8_t glyph4_y[GLYPH_COORD_VECT_SIZE] =
+    { 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 2, 1, 1, 1, 2, 2 };
+static const int8_t glyph8_x[GLYPH_COORD_VECT_SIZE] =
+    { 0, 2, 5, 7, 7, 7, 7, 7, 7, 5, 2, 0, 0, 0, 0, 0 };
+static const int8_t glyph8_y[GLYPH_COORD_VECT_SIZE] =
+    { 0, 0, 0, 0, 1, 3, 4, 6, 7, 7, 7, 7, 6, 4, 3, 1 };
+
+static const int8_t motion_vectors[256][2] =
+{
+    {  0,   0}, { -1, -43}, {  6, -43}, { -9, -42}, { 13, -41},
+    {-16, -40}, { 19, -39}, {-23, -36}, { 26, -34}, { -2, -33},
+    {  4, -33}, {-29, -32}, { -9, -32}, { 11, -31}, {-16, -29},
+    { 32, -29}, { 18, -28}, {-34, -26}, {-22, -25}, { -1, -25},
+    {  3, -25}, { -7, -24}, {  8, -24}, { 24, -23}, { 36, -23},
+    {-12, -22}, { 13, -21}, {-38, -20}, {  0, -20}, {-27, -19},
+    { -4, -19}, {  4, -19}, {-17, -18}, { -8, -17}, {  8, -17},
+    { 18, -17}, { 28, -17}, { 39, -17}, {-12, -15}, { 12, -15},
+    {-21, -14}, { -1, -14}, {  1, -14}, {-41, -13}, { -5, -13},
+    {  5, -13}, { 21, -13}, {-31, -12}, {-15, -11}, { -8, -11},
+    {  8, -11}, { 15, -11}, { -2, -10}, {  1, -10}, { 31, -10},
+    {-23,  -9}, {-11,  -9}, { -5,  -9}, {  4,  -9}, { 11,  -9},
+    { 42,  -9}, {  6,  -8}, { 24,  -8}, {-18,  -7}, { -7,  -7},
+    { -3,  -7}, { -1,  -7}, {  2,  -7}, { 18,  -7}, {-43,  -6},
+    {-13,  -6}, { -4,  -6}, {  4,  -6}, {  8,  -6}, {-33,  -5},
+    { -9,  -5}, { -2,  -5}, {  0,  -5}, {  2,  -5}, {  5,  -5},
+    { 13,  -5}, {-25,  -4}, { -6,  -4}, { -3,  -4}, {  3,  -4},
+    {  9,  -4}, {-19,  -3}, { -7,  -3}, { -4,  -3}, { -2,  -3},
+    { -1,  -3}, {  0,  -3}, {  1,  -3}, {  2,  -3}, {  4,  -3},
+    {  6,  -3}, { 33,  -3}, {-14,  -2}, {-10,  -2}, { -5,  -2},
+    { -3,  -2}, { -2,  -2}, { -1,  -2}, {  0,  -2}, {  1,  -2},
+    {  2,  -2}, {  3,  -2}, {  5,  -2}, {  7,  -2}, { 14,  -2},
+    { 19,  -2}, { 25,  -2}, { 43,  -2}, { -7,  -1}, { -3,  -1},
+    { -2,  -1}, { -1,  -1}, {  0,  -1}, {  1,  -1}, {  2,  -1},
+    {  3,  -1}, { 10,  -1}, { -5,   0}, { -3,   0}, { -2,   0},
+    { -1,   0}, {  1,   0}, {  2,   0}, {  3,   0}, {  5,   0},
+    {  7,   0}, {-10,   1}, { -7,   1}, { -3,   1}, { -2,   1},
+    { -1,   1}, {  0,   1}, {  1,   1}, {  2,   1}, {  3,   1},
+    {-43,   2}, {-25,   2}, {-19,   2}, {-14,   2}, { -5,   2},
+    { -3,   2}, { -2,   2}, { -1,   2}, {  0,   2}, {  1,   2},
+    {  2,   2}, {  3,   2}, {  5,   2}, {  7,   2}, { 10,   2},
+    { 14,   2}, {-33,   3}, { -6,   3}, { -4,   3}, { -2,   3},
+    { -1,   3}, {  0,   3}, {  1,   3}, {  2,   3}, {  4,   3},
+    { 19,   3}, { -9,   4}, { -3,   4}, {  3,   4}, {  7,   4},
+    { 25,   4}, {-13,   5}, { -5,   5}, { -2,   5}, {  0,   5},
+    {  2,   5}, {  5,   5}, {  9,   5}, { 33,   5}, { -8,   6},
+    { -4,   6}, {  4,   6}, { 13,   6}, { 43,   6}, {-18,   7},
+    { -2,   7}, {  0,   7}, {  2,   7}, {  7,   7}, { 18,   7},
+    {-24,   8}, { -6,   8}, {-42,   9}, {-11,   9}, { -4,   9},
+    {  5,   9}, { 11,   9}, { 23,   9}, {-31,  10}, { -1,  10},
+    {  2,  10}, {-15,  11}, { -8,  11}, {  8,  11}, { 15,  11},
+    { 31,  12}, {-21,  13}, { -5,  13}, {  5,  13}, { 41,  13},
+    { -1,  14}, {  1,  14}, { 21,  14}, {-12,  15}, { 12,  15},
+    {-39,  17}, {-28,  17}, {-18,  17}, { -8,  17}, {  8,  17},
+    { 17,  18}, { -4,  19}, {  0,  19}, {  4,  19}, { 27,  19},
+    { 38,  20}, {-13,  21}, { 12,  22}, {-36,  23}, {-24,  23},
+    { -8,  24}, {  7,  24}, { -3,  25}, {  1,  25}, { 22,  25},
+    { 34,  26}, {-18,  28}, {-32,  29}, { 16,  29}, {-11,  31},
+    {  9,  32}, { 29,  32}, { -4,  33}, {  2,  33}, {-26,  34},
+    { 23,  36}, {-19,  39}, { 16,  40}, {-13,  41}, {  9,  42},
+    { -6,  43}, {  1,  43}, {  0,   0}, {  0,   0}, {  0,   0},
+};
+
+static const int8_t c37_mv[] = {
+    0,   0,   1,   0,   2,   0,   3,   0,   5,   0,
+    8,   0,  13,   0,  21,   0,  -1,   0,  -2,   0,
+   -3,   0,  -5,   0,  -8,   0, -13,   0, -17,   0,
+  -21,   0,   0,   1,   1,   1,   2,   1,   3,   1,
+    5,   1,   8,   1,  13,   1,  21,   1,  -1,   1,
+   -2,   1,  -3,   1,  -5,   1,  -8,   1, -13,   1,
+  -17,   1, -21,   1,   0,   2,   1,   2,   2,   2,
+    3,   2,   5,   2,   8,   2,  13,   2,  21,   2,
+   -1,   2,  -2,   2,  -3,   2,  -5,   2,  -8,   2,
+  -13,   2, -17,   2, -21,   2,   0,   3,   1,   3,
+    2,   3,   3,   3,   5,   3,   8,   3,  13,   3,
+   21,   3,  -1,   3,  -2,   3,  -3,   3,  -5,   3,
+   -8,   3, -13,   3, -17,   3, -21,   3,   0,   5,
+    1,   5,   2,   5,   3,   5,   5,   5,   8,   5,
+   13,   5,  21,   5,  -1,   5,  -2,   5,  -3,   5,
+   -5,   5,  -8,   5, -13,   5, -17,   5, -21,   5,
+    0,   8,   1,   8,   2,   8,   3,   8,   5,   8,
+    8,   8,  13,   8,  21,   8,  -1,   8,  -2,   8,
+   -3,   8,  -5,   8,  -8,   8, -13,   8, -17,   8,
+  -21,   8,   0,  13,   1,  13,   2,  13,   3,  13,
+    5,  13,   8,  13,  13,  13,  21,  13,  -1,  13,
+   -2,  13,  -3,  13,  -5,  13,  -8,  13, -13,  13,
+  -17,  13, -21,  13,   0,  21,   1,  21,   2,  21,
+    3,  21,   5,  21,   8,  21,  13,  21,  21,  21,
+   -1,  21,  -2,  21,  -3,  21,  -5,  21,  -8,  21,
+  -13,  21, -17,  21, -21,  21,   0,  -1,   1,  -1,
+    2,  -1,   3,  -1,   5,  -1,   8,  -1,  13,  -1,
+   21,  -1,  -1,  -1,  -2,  -1,  -3,  -1,  -5,  -1,
+   -8,  -1, -13,  -1, -17,  -1, -21,  -1,   0,  -2,
+    1,  -2,   2,  -2,   3,  -2,   5,  -2,   8,  -2,
+   13,  -2,  21,  -2,  -1,  -2,  -2,  -2,  -3,  -2,
+   -5,  -2,  -8,  -2, -13,  -2, -17,  -2, -21,  -2,
+    0,  -3,   1,  -3,   2,  -3,   3,  -3,   5,  -3,
+    8,  -3,  13,  -3,  21,  -3,  -1,  -3,  -2,  -3,
+   -3,  -3,  -5,  -3,  -8,  -3, -13,  -3, -17,  -3,
+  -21,  -3,   0,  -5,   1,  -5,   2,  -5,   3,  -5,
+    5,  -5,   8,  -5,  13,  -5,  21,  -5,  -1,  -5,
+   -2,  -5,  -3,  -5,  -5,  -5,  -8,  -5, -13,  -5,
+  -17,  -5, -21,  -5,   0,  -8,   1,  -8,   2,  -8,
+    3,  -8,   5,  -8,   8,  -8,  13,  -8,  21,  -8,
+   -1,  -8,  -2,  -8,  -3,  -8,  -5,  -8,  -8,  -8,
+  -13,  -8, -17,  -8, -21,  -8,   0, -13,   1, -13,
+    2, -13,   3, -13,   5, -13,   8, -13,  13, -13,
+   21, -13,  -1, -13,  -2, -13,  -3, -13,  -5, -13,
+   -8, -13, -13, -13, -17, -13, -21, -13,   0, -17,
+    1, -17,   2, -17,   3, -17,   5, -17,   8, -17,
+   13, -17,  21, -17,  -1, -17,  -2, -17,  -3, -17,
+   -5, -17,  -8, -17, -13, -17, -17, -17, -21, -17,
+    0, -21,   1, -21,   2, -21,   3, -21,   5, -21,
+    8, -21,  13, -21,  21, -21,  -1, -21,  -2, -21,
+   -3, -21,  -5, -21,  -8, -21, -13, -21, -17, -21,
+    0,   0,  -8, -29,   8, -29, -18, -25,  17, -25,
+    0, -23,  -6, -22,   6, -22, -13, -19,  12, -19,
+    0, -18,  25, -18, -25, -17,  -5, -17,   5, -17,
+  -10, -15,  10, -15,   0, -14,  -4, -13,   4, -13,
+   19, -13, -19, -12,  -8, -11,  -2, -11,   0, -11,
+    2, -11,   8, -11, -15, -10,  -4, -10,   4, -10,
+   15, -10,  -6,  -9,  -1,  -9,   1,  -9,   6,  -9,
+  -29,  -8, -11,  -8,  -8,  -8,  -3,  -8,   3,  -8,
+    8,  -8,  11,  -8,  29,  -8,  -5,  -7,  -2,  -7,
+    0,  -7,   2,  -7,   5,  -7, -22,  -6,  -9,  -6,
+   -6,  -6,  -3,  -6,  -1,  -6,   1,  -6,   3,  -6,
+    6,  -6,   9,  -6,  22,  -6, -17,  -5,  -7,  -5,
+   -4,  -5,  -2,  -5,   0,  -5,   2,  -5,   4,  -5,
+    7,  -5,  17,  -5, -13,  -4, -10,  -4,  -5,  -4,
+   -3,  -4,  -1,  -4,   0,  -4,   1,  -4,   3,  -4,
+    5,  -4,  10,  -4,  13,  -4,  -8,  -3,  -6,  -3,
+   -4,  -3,  -3,  -3,  -2,  -3,  -1,  -3,   0,  -3,
+    1,  -3,   2,  -3,   4,  -3,   6,  -3,   8,  -3,
+  -11,  -2,  -7,  -2,  -5,  -2,  -3,  -2,  -2,  -2,
+   -1,  -2,   0,  -2,   1,  -2,   2,  -2,   3,  -2,
+    5,  -2,   7,  -2,  11,  -2,  -9,  -1,  -6,  -1,
+   -4,  -1,  -3,  -1,  -2,  -1,  -1,  -1,   0,  -1,
+    1,  -1,   2,  -1,   3,  -1,   4,  -1,   6,  -1,
+    9,  -1, -31,   0, -23,   0, -18,   0, -14,   0,
+  -11,   0,  -7,   0,  -5,   0,  -4,   0,  -3,   0,
+   -2,   0,  -1,   0,   0, -31,   1,   0,   2,   0,
+    3,   0,   4,   0,   5,   0,   7,   0,  11,   0,
+   14,   0,  18,   0,  23,   0,  31,   0,  -9,   1,
+   -6,   1,  -4,   1,  -3,   1,  -2,   1,  -1,   1,
+    0,   1,   1,   1,   2,   1,   3,   1,   4,   1,
+    6,   1,   9,   1, -11,   2,  -7,   2,  -5,   2,
+   -3,   2,  -2,   2,  -1,   2,   0,   2,   1,   2,
+    2,   2,   3,   2,   5,   2,   7,   2,  11,   2,
+   -8,   3,  -6,   3,  -4,   3,  -2,   3,  -1,   3,
+    0,   3,   1,   3,   2,   3,   3,   3,   4,   3,
+    6,   3,   8,   3, -13,   4, -10,   4,  -5,   4,
+   -3,   4,  -1,   4,   0,   4,   1,   4,   3,   4,
+    5,   4,  10,   4,  13,   4, -17,   5,  -7,   5,
+   -4,   5,  -2,   5,   0,   5,   2,   5,   4,   5,
+    7,   5,  17,   5, -22,   6,  -9,   6,  -6,   6,
+   -3,   6,  -1,   6,   1,   6,   3,   6,   6,   6,
+    9,   6,  22,   6,  -5,   7,  -2,   7,   0,   7,
+    2,   7,   5,   7, -29,   8, -11,   8,  -8,   8,
+   -3,   8,   3,   8,   8,   8,  11,   8,  29,   8,
+   -6,   9,  -1,   9,   1,   9,   6,   9, -15,  10,
+   -4,  10,   4,  10,  15,  10,  -8,  11,  -2,  11,
+    0,  11,   2,  11,   8,  11,  19,  12, -19,  13,
+   -4,  13,   4,  13,   0,  14, -10,  15,  10,  15,
+   -5,  17,   5,  17,  25,  17, -25,  18,   0,  18,
+  -12,  19,  13,  19,  -6,  22,   6,  22,   0,  23,
+  -17,  25,  18,  25,  -8,  29,   8,  29,   0,  31,
+    0,   0,  -6, -22,   6, -22, -13, -19,  12, -19,
+    0, -18,  -5, -17,   5, -17, -10, -15,  10, -15,
+    0, -14,  -4, -13,   4, -13,  19, -13, -19, -12,
+   -8, -11,  -2, -11,   0, -11,   2, -11,   8, -11,
+  -15, -10,  -4, -10,   4, -10,  15, -10,  -6,  -9,
+   -1,  -9,   1,  -9,   6,  -9, -11,  -8,  -8,  -8,
+   -3,  -8,   0,  -8,   3,  -8,   8,  -8,  11,  -8,
+   -5,  -7,  -2,  -7,   0,  -7,   2,  -7,   5,  -7,
+  -22,  -6,  -9,  -6,  -6,  -6,  -3,  -6,  -1,  -6,
+    1,  -6,   3,  -6,   6,  -6,   9,  -6,  22,  -6,
+  -17,  -5,  -7,  -5,  -4,  -5,  -2,  -5,  -1,  -5,
+    0,  -5,   1,  -5,   2,  -5,   4,  -5,   7,  -5,
+   17,  -5, -13,  -4, -10,  -4,  -5,  -4,  -3,  -4,
+   -2,  -4,  -1,  -4,   0,  -4,   1,  -4,   2,  -4,
+    3,  -4,   5,  -4,  10,  -4,  13,  -4,  -8,  -3,
+   -6,  -3,  -4,  -3,  -3,  -3,  -2,  -3,  -1,  -3,
+    0,  -3,   1,  -3,   2,  -3,   3,  -3,   4,  -3,
+    6,  -3,   8,  -3, -11,  -2,  -7,  -2,  -5,  -2,
+   -4,  -2,  -3,  -2,  -2,  -2,  -1,  -2,   0,  -2,
+    1,  -2,   2,  -2,   3,  -2,   4,  -2,   5,  -2,
+    7,  -2,  11,  -2,  -9,  -1,  -6,  -1,  -5,  -1,
+   -4,  -1,  -3,  -1,  -2,  -1,  -1,  -1,   0,  -1,
+    1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,
+    6,  -1,   9,  -1, -23,   0, -18,   0, -14,   0,
+  -11,   0,  -7,   0,  -5,   0,  -4,   0,  -3,   0,
+   -2,   0,  -1,   0,   0, -23,   1,   0,   2,   0,
+    3,   0,   4,   0,   5,   0,   7,   0,  11,   0,
+   14,   0,  18,   0,  23,   0,  -9,   1,  -6,   1,
+   -5,   1,  -4,   1,  -3,   1,  -2,   1,  -1,   1,
+    0,   1,   1,   1,   2,   1,   3,   1,   4,   1,
+    5,   1,   6,   1,   9,   1, -11,   2,  -7,   2,
+   -5,   2,  -4,   2,  -3,   2,  -2,   2,  -1,   2,
+    0,   2,   1,   2,   2,   2,   3,   2,   4,   2,
+    5,   2,   7,   2,  11,   2,  -8,   3,  -6,   3,
+   -4,   3,  -3,   3,  -2,   3,  -1,   3,   0,   3,
+    1,   3,   2,   3,   3,   3,   4,   3,   6,   3,
+    8,   3, -13,   4, -10,   4,  -5,   4,  -3,   4,
+   -2,   4,  -1,   4,   0,   4,   1,   4,   2,   4,
+    3,   4,   5,   4,  10,   4,  13,   4, -17,   5,
+   -7,   5,  -4,   5,  -2,   5,  -1,   5,   0,   5,
+    1,   5,   2,   5,   4,   5,   7,   5,  17,   5,
+  -22,   6,  -9,   6,  -6,   6,  -3,   6,  -1,   6,
+    1,   6,   3,   6,   6,   6,   9,   6,  22,   6,
+   -5,   7,  -2,   7,   0,   7,   2,   7,   5,   7,
+  -11,   8,  -8,   8,  -3,   8,   0,   8,   3,   8,
+    8,   8,  11,   8,  -6,   9,  -1,   9,   1,   9,
+    6,   9, -15,  10,  -4,  10,   4,  10,  15,  10,
+   -8,  11,  -2,  11,   0,  11,   2,  11,   8,  11,
+   19,  12, -19,  13,  -4,  13,   4,  13,   0,  14,
+  -10,  15,  10,  15,  -5,  17,   5,  17,   0,  18,
+  -12,  19,  13,  19,  -6,  22,   6,  22,   0,  23,
+};
+#endif /* AVCODEC_SANM_DATA_H */
diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
index a47ad6e..7c0afdc 100644
--- a/libavcodec/sbr.h
+++ b/libavcodec/sbr.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
  * Copyright (c) 2010      Alex Converse <alex.converse@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sgi.h b/libavcodec/sgi.h
index ca531f0..be17f2e 100644
--- a/libavcodec/sgi.h
+++ b/libavcodec/sgi.h
@@ -2,20 +2,20 @@
  * SGI image encoder
  * Xiaohui Sun <tjnksxh@hotmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sgidec.c b/libavcodec/sgidec.c
index c220452..e9ada69 100644
--- a/libavcodec/sgidec.c
+++ b/libavcodec/sgidec.c
@@ -2,24 +2,25 @@
  * SGI image decoder
  * Todd Kirby <doubleshot@pacbell.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/imgutils.h"
+#include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "bytestream.h"
 #include "sgi.h"
@@ -48,16 +49,16 @@
     unsigned char pixel, count;
     unsigned char *orig = out_buf;
 
-    while (1) {
+    while (out_buf < out_end) {
         if (bytestream2_get_bytes_left(&s->g) < 1)
             return AVERROR_INVALIDDATA;
         pixel = bytestream2_get_byteu(&s->g);
         if (!(count = (pixel & 0x7f))) {
-            return (out_buf - orig) / pixelstride;
+            break;
         }
 
         /* Check for buffer overflow. */
-        if(out_buf + pixelstride * count >= out_end) return -1;
+        if(out_buf + pixelstride * (count-1) >= out_end) return -1;
 
         if (pixel & 0x80) {
             while (count--) {
@@ -73,6 +74,7 @@
             }
         }
     }
+    return (out_buf - orig) / pixelstride;
 }
 
 /**
@@ -100,7 +102,7 @@
             dest_row -= s->linesize;
             start_offset = bytestream2_get_be32(&g_table);
             bytestream2_seek(&s->g, start_offset, SEEK_SET);
-            if (expand_rle_row(s, dest_row + z, dest_row + FFABS(s->linesize),
+            if (expand_rle_row(s, dest_row + z, dest_row + s->width*s->depth,
                                s->depth) != s->width) {
                 return AVERROR_INVALIDDATA;
             }
@@ -112,16 +114,15 @@
 /**
  * Read an uncompressed SGI image.
  * @param out_buf output buffer
- * @param out_end end ofoutput buffer
  * @param s the current image state
  * @return 0 if read success, otherwise return -1.
  */
-static int read_uncompressed_sgi(unsigned char* out_buf, uint8_t* out_end,
-                                 SgiState *s)
+static int read_uncompressed_sgi(unsigned char* out_buf, SgiState *s)
 {
     int x, y, z;
     unsigned int offset = s->height * s->width * s->bytes_per_channel;
     GetByteContext gp[4];
+    uint8_t *out_end;
 
     /* Test buffer size. */
     if (offset * s->depth > bytestream2_get_bytes_left(&s->g))
@@ -194,8 +195,8 @@
         avctx->pix_fmt = s->bytes_per_channel == 2 ? AV_PIX_FMT_GRAY16BE : AV_PIX_FMT_GRAY8;
     } else if (s->depth == SGI_RGB) {
         avctx->pix_fmt = s->bytes_per_channel == 2 ? AV_PIX_FMT_RGB48BE : AV_PIX_FMT_RGB24;
-    } else if (s->depth == SGI_RGBA && s->bytes_per_channel == 1) {
-        avctx->pix_fmt = AV_PIX_FMT_RGBA;
+    } else if (s->depth == SGI_RGBA) {
+        avctx->pix_fmt = s->bytes_per_channel == 2 ? AV_PIX_FMT_RGBA64BE : AV_PIX_FMT_RGBA;
     } else {
         av_log(avctx, AV_LOG_ERROR, "wrong picture format\n");
         return -1;
@@ -227,7 +228,7 @@
     if (rle) {
         ret = read_rle_sgi(out_end, s);
     } else {
-        ret = read_uncompressed_sgi(out_buf, out_end, s);
+        ret = read_uncompressed_sgi(out_buf, s);
     }
 
     if (ret == 0) {
@@ -266,5 +267,6 @@
     .init           = sgi_init,
     .close          = sgi_end,
     .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("SGI image"),
 };
diff --git a/libavcodec/sgienc.c b/libavcodec/sgienc.c
index 2aecc59..d03ef52 100644
--- a/libavcodec/sgienc.c
+++ b/libavcodec/sgienc.c
@@ -2,20 +2,20 @@
  * SGI image encoder
  * Todd Kirby <doubleshot@pacbell.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,6 +36,11 @@
 {
     SgiContext *s = avctx->priv_data;
 
+    if (avctx->width > 65535 || avctx->height > 65535) {
+        av_log(avctx, AV_LOG_ERROR, "SGI does not support resolutions above 65535x65535\n");
+        return -1;
+    }
+
     avcodec_get_frame_defaults(&s->picture);
     avctx->coded_frame = &s->picture;
 
@@ -49,7 +54,7 @@
     AVFrame * const p = &s->picture;
     uint8_t *offsettab, *lengthtab, *in_buf, *encode_buf, *buf;
     int x, y, z, length, tablesize, ret;
-    unsigned int width, height, depth, dimension;
+    unsigned int width, height, depth, dimension, bytes_per_channel, pixmax, put_be;
     unsigned char *end_buf;
 
     *p = *frame;
@@ -58,6 +63,9 @@
 
     width  = avctx->width;
     height = avctx->height;
+    bytes_per_channel = 1;
+    pixmax = 0xFF;
+    put_be = HAVE_BIGENDIAN;
 
     switch (avctx->pix_fmt) {
     case AV_PIX_FMT_GRAY8:
@@ -72,6 +80,33 @@
         dimension = SGI_MULTI_CHAN;
         depth     = SGI_RGBA;
         break;
+    case AV_PIX_FMT_GRAY16LE:
+        put_be = !HAVE_BIGENDIAN;
+    case AV_PIX_FMT_GRAY16BE:
+        avctx->coder_type = FF_CODER_TYPE_RAW;
+        bytes_per_channel = 2;
+        pixmax = 0xFFFF;
+        dimension = SGI_SINGLE_CHAN;
+        depth     = SGI_GRAYSCALE;
+        break;
+    case AV_PIX_FMT_RGB48LE:
+        put_be = !HAVE_BIGENDIAN;
+    case AV_PIX_FMT_RGB48BE:
+        avctx->coder_type = FF_CODER_TYPE_RAW;
+        bytes_per_channel = 2;
+        pixmax = 0xFFFF;
+        dimension = SGI_MULTI_CHAN;
+        depth     = SGI_RGB;
+        break;
+    case AV_PIX_FMT_RGBA64LE:
+        put_be = !HAVE_BIGENDIAN;
+    case AV_PIX_FMT_RGBA64BE:
+        avctx->coder_type = FF_CODER_TYPE_RAW;
+        bytes_per_channel = 2;
+        pixmax = 0xFFFF;
+        dimension = SGI_MULTI_CHAN;
+        depth     = SGI_RGBA;
+        break;
     default:
         return AVERROR_INVALIDDATA;
     }
@@ -83,25 +118,22 @@
     else // assume ff_rl_encode() produces at most 2x size of input
         length += tablesize * 2 + depth * height * (2 * width + 1);
 
-    if ((ret = ff_alloc_packet(pkt, length)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n", length);
+    if ((ret = ff_alloc_packet2(avctx, pkt, bytes_per_channel * length)) < 0)
         return ret;
-    }
     buf     = pkt->data;
     end_buf = pkt->data + pkt->size;
 
     /* Encode header. */
     bytestream_put_be16(&buf, SGI_MAGIC);
     bytestream_put_byte(&buf, avctx->coder_type != FF_CODER_TYPE_RAW); /* RLE 1 - VERBATIM 0*/
-    bytestream_put_byte(&buf, 1); /* bytes_per_channel */
+    bytestream_put_byte(&buf, bytes_per_channel);
     bytestream_put_be16(&buf, dimension);
     bytestream_put_be16(&buf, width);
     bytestream_put_be16(&buf, height);
     bytestream_put_be16(&buf, depth);
 
-    /* The rest are constant in this implementation. */
     bytestream_put_be32(&buf, 0L); /* pixmin */
-    bytestream_put_be32(&buf, 255L); /* pixmax */
+    bytestream_put_be32(&buf, pixmax);
     bytestream_put_be32(&buf, 0L); /* dummy */
 
     /* name */
@@ -151,11 +183,19 @@
         av_free(encode_buf);
     } else {
         for (z = 0; z < depth; z++) {
-            in_buf = p->data[0] + p->linesize[0] * (height - 1) + z;
+            in_buf = p->data[0] + p->linesize[0] * (height - 1) + z * bytes_per_channel;
 
             for (y = 0; y < height; y++) {
                 for (x = 0; x < width * depth; x += depth)
+                    if (bytes_per_channel == 1) {
                     bytestream_put_byte(&buf, in_buf[x]);
+                    } else {
+                        if (put_be) {
+                            bytestream_put_be16(&buf, ((uint16_t *)in_buf)[x]);
+                        } else {
+                            bytestream_put_le16(&buf, ((uint16_t *)in_buf)[x]);
+                        }
+                    }
 
                 in_buf -= p->linesize[0];
             }
@@ -178,7 +218,11 @@
     .init           = encode_init,
     .encode2        = encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){
-        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
+        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA,
+        AV_PIX_FMT_RGB48LE, AV_PIX_FMT_RGB48BE,
+        AV_PIX_FMT_RGBA64LE, AV_PIX_FMT_RGBA64BE,
+        AV_PIX_FMT_GRAY16LE, AV_PIX_FMT_GRAY16BE,
+        AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE
     },
     .long_name      = NULL_IF_CONFIG_SMALL("SGI image"),
 };
diff --git a/libavcodec/sh4/dsputil_align.c b/libavcodec/sh4/dsputil_align.c
index b9b0121..a545e55 100644
--- a/libavcodec/sh4/dsputil_align.c
+++ b/libavcodec/sh4/dsputil_align.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2001-2003 BERO <bero@geocities.co.jp>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sh4/dsputil_sh4.c b/libavcodec/sh4/dsputil_sh4.c
index 74c8670..7deab41 100644
--- a/libavcodec/sh4/dsputil_sh4.c
+++ b/libavcodec/sh4/dsputil_sh4.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2003 BERO <bero@geocities.co.jp>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sh4/dsputil_sh4.h b/libavcodec/sh4/dsputil_sh4.h
index 7e8ebbc..f2cb11e 100644
--- a/libavcodec/sh4/dsputil_sh4.h
+++ b/libavcodec/sh4/dsputil_sh4.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sh4/idct_sh4.c b/libavcodec/sh4/idct_sh4.c
index 9da6ffc..e54c330 100644
--- a/libavcodec/sh4/idct_sh4.c
+++ b/libavcodec/sh4/idct_sh4.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2001-2003 BERO <bero@geocities.co.jp>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sh4/qpel.c b/libavcodec/sh4/qpel.c
index cb6cdf0..5ad0290 100644
--- a/libavcodec/sh4/qpel.c
+++ b/libavcodec/sh4/qpel.c
@@ -4,20 +4,20 @@
  *
  * copyright (c) 2001-2003 BERO <bero@geocities.co.jp>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sh4/sh4.h b/libavcodec/sh4/sh4.h
index acd12e6..5d46540 100644
--- a/libavcodec/sh4/sh4.h
+++ b/libavcodec/sh4/sh4.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c
index fb48070..d04011e 100644
--- a/libavcodec/shorten.c
+++ b/libavcodec/shorten.c
@@ -2,20 +2,20 @@
  * Shorten decoder
  * Copyright (c) 2005 Jeff Muizelaar
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -49,8 +49,12 @@
 #define ENERGYSIZE 3
 #define BITSHIFTSIZE 2
 
+#define TYPE_S8    1
+#define TYPE_U8    2
 #define TYPE_S16HL 3
+#define TYPE_U16HL 4
 #define TYPE_S16LH 5
+#define TYPE_U16LH 6
 
 #define NWRAP 3
 #define NSKIPSIZE 1
@@ -112,7 +116,6 @@
 {
     ShortenContext *s = avctx->priv_data;
     s->avctx = avctx;
-    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
 
     avcodec_get_frame_defaults(&s->frame);
     avctx->coded_frame = &s->frame;
@@ -186,12 +189,16 @@
     /* initialise offset */
     switch (s->internal_ftype)
     {
+        case TYPE_U8:
+            s->avctx->sample_fmt = AV_SAMPLE_FMT_U8;
+            mean = 0x80;
+            break;
         case TYPE_S16HL:
         case TYPE_S16LH:
-            mean = 0;
+            s->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
             break;
         default:
-            av_log(s->avctx, AV_LOG_ERROR, "unknown audio type");
+            av_log(s->avctx, AV_LOG_ERROR, "unknown audio type\n");
             return AVERROR_INVALIDDATA;
     }
 
@@ -204,9 +211,9 @@
 static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header,
                               int header_size)
 {
-    int len;
+    int len, bps;
     short wave_format;
-
+    const uint8_t *end= header + header_size;
 
     if (bytestream_get_le32(&header) != MKTAG('R','I','F','F')) {
         av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n");
@@ -222,6 +229,8 @@
 
     while (bytestream_get_le32(&header) != MKTAG('f','m','t',' ')) {
         len = bytestream_get_le32(&header);
+        if(len<0 || end - header - 8 < len)
+            return AVERROR_INVALIDDATA;
         header += len;
     }
     len = bytestream_get_le32(&header);
@@ -245,10 +254,11 @@
     avctx->sample_rate = bytestream_get_le32(&header);
     header += 4;        // skip bit rate    (represents original uncompressed bit rate)
     header += 2;        // skip block align (not needed)
-    avctx->bits_per_coded_sample = bytestream_get_le16(&header);
+    bps     = bytestream_get_le16(&header);
+    avctx->bits_per_coded_sample = bps;
 
-    if (avctx->bits_per_coded_sample != 16) {
-        av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample\n");
+    if (bps != 16 && bps != 8) {
+        av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample: %d\n", bps);
         return -1;
     }
 
@@ -259,15 +269,6 @@
     return 0;
 }
 
-static void interleave_buffer(int16_t *samples, int nchan, int blocksize,
-                              int32_t **buffer)
-{
-    int i, chan;
-    for (i=0; i<blocksize; i++)
-        for (chan=0; chan < nchan; chan++)
-            *samples++ = av_clip_int16(buffer[chan][i]);
-}
-
 static const int fixed_coeffs[3][3] = {
     { 1,  0,  0 },
     { 2, -1,  0 },
@@ -413,7 +414,7 @@
     /* allocate internal bitstream buffer */
     if(s->max_framesize == 0){
         void *tmp_ptr;
-        s->max_framesize= 1024; // should hopefully be enough for the first header
+        s->max_framesize= 8192; // should hopefully be enough for the first header
         tmp_ptr = av_fast_realloc(s->bitstream, &s->allocated_bitstream_size,
                                   s->max_framesize);
         if (!tmp_ptr) {
@@ -465,7 +466,7 @@
 
     s->cur_chan = 0;
     while (s->cur_chan < s->channels) {
-        int cmd;
+        unsigned int cmd;
         int len;
 
         if (get_bits_left(&s->gb) < 3+FNSIZE) {
@@ -524,7 +525,7 @@
             /* 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 defintion of get_sr_golomb_shorten */
+                /* this is a hack as version 0 differed in definition of get_sr_golomb_shorten */
                 if (s->version == 0)
                     residual_size--;
             }
@@ -538,7 +539,7 @@
                     sum += s->offset[channel][i];
                 coffset = sum / s->nmean;
                 if (s->version >= 2)
-                    coffset >>= FFMIN(1, s->bitshift);
+                    coffset = s->bitshift == 0 ? coffset : coffset >> s->bitshift - 1 >> 1;
             }
 
             /* decode samples for this channel */
@@ -576,15 +577,32 @@
             /* if this is the last channel in the block, output the samples */
             s->cur_chan++;
             if (s->cur_chan == s->channels) {
+                uint8_t *samples_u8;
+                int16_t *samples_s16;
+                int chan;
+
                 /* get output buffer */
                 s->frame.nb_samples = s->blocksize;
                 if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
                     av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                     return ret;
                 }
+                samples_u8  = (uint8_t *)s->frame.data[0];
+                samples_s16 = (int16_t *)s->frame.data[0];
                 /* interleave output */
-                interleave_buffer((int16_t *)s->frame.data[0], s->channels,
-                                  s->blocksize, s->decoded);
+                for (i = 0; i < s->blocksize; i++) {
+                    for (chan = 0; chan < s->channels; chan++) {
+                        switch (s->internal_ftype) {
+                        case TYPE_U8:
+                            *samples_u8++ = av_clip_uint8(s->decoded[chan][i]);
+                            break;
+                        case TYPE_S16HL:
+                        case TYPE_S16LH:
+                            *samples_s16++ = av_clip_int16(s->decoded[chan][i]);
+                            break;
+                        }
+                    }
+                }
 
                 *got_frame_ptr   = 1;
                 *(AVFrame *)data = s->frame;
diff --git a/libavcodec/simple_idct.c b/libavcodec/simple_idct.c
index 5812a87..2931850 100644
--- a/libavcodec/simple_idct.c
+++ b/libavcodec/simple_idct.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/simple_idct.h b/libavcodec/simple_idct.h
index 6e22158..64d3c2a 100644
--- a/libavcodec/simple_idct.h
+++ b/libavcodec/simple_idct.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/simple_idct_template.c b/libavcodec/simple_idct_template.c
index 3c855e3..b67893c 100644
--- a/libavcodec/simple_idct_template.c
+++ b/libavcodec/simple_idct_template.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2001 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sinewin.c b/libavcodec/sinewin.c
index be38dbc..1fa0e95 100644
--- a/libavcodec/sinewin.c
+++ b/libavcodec/sinewin.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sinewin.h b/libavcodec/sinewin.h
index 478036d..2268fd5 100644
--- a/libavcodec/sinewin.h
+++ b/libavcodec/sinewin.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Robert Swain
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sinewin_tablegen.c b/libavcodec/sinewin_tablegen.c
index 90a75c2..561ae3e 100644
--- a/libavcodec/sinewin_tablegen.c
+++ b/libavcodec/sinewin_tablegen.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sinewin_tablegen.h b/libavcodec/sinewin_tablegen.h
index 1ee225b..2b9c4f2 100644
--- a/libavcodec/sinewin_tablegen.h
+++ b/libavcodec/sinewin_tablegen.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c
index 1e9168a..fc03259 100644
--- a/libavcodec/sipr.c
+++ b/libavcodec/sipr.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2008 Vladimir Voroshilov
  * Copyright (c) 2009 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sipr.h b/libavcodec/sipr.h
index 5007c75..8872fa3 100644
--- a/libavcodec/sipr.h
+++ b/libavcodec/sipr.h
@@ -4,20 +4,20 @@
  * Copyright (c) 2008 Vladimir Voroshilov
  * Copyright (c) 2009 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sipr16k.c b/libavcodec/sipr16k.c
index bff739e..c2e090b 100644
--- a/libavcodec/sipr16k.c
+++ b/libavcodec/sipr16k.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2008 Vladimir Voroshilov
  * Copyright (c) 2009 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sipr16kdata.h b/libavcodec/sipr16kdata.h
index ec60c29..96bf0e9 100644
--- a/libavcodec/sipr16kdata.h
+++ b/libavcodec/sipr16kdata.h
@@ -4,20 +4,20 @@
  * Copyright (c) 2008 Vladimir Voroshilov
  * Copyright (c) 2009 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/siprdata.h b/libavcodec/siprdata.h
index 92037a4..ed804ee 100644
--- a/libavcodec/siprdata.h
+++ b/libavcodec/siprdata.h
@@ -4,20 +4,20 @@
  * Copyright (c) 2008 Vladimir Voroshilov
  * Copyright (c) 2009 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c
index df2d4c4..fa4812c 100644
--- a/libavcodec/smacker.c
+++ b/libavcodec/smacker.c
@@ -2,20 +2,20 @@
  * Smacker decoder
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -96,6 +96,10 @@
  */
 static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t prefix, int length)
 {
+    if(length > 32) {
+        av_log(NULL, AV_LOG_ERROR, "length too long\n");
+        return -1;
+    }
     if(!get_bits1(gb)){ //Leaf
         if(hc->current >= 256){
             av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n");
@@ -169,7 +173,7 @@
 }
 
 /**
- * Store large tree as Libav's vlc codes
+ * Store large tree as FFmpeg's vlc codes
  */
 static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int **recodes, int *last, int size)
 {
@@ -227,12 +231,9 @@
         av_log(smk->avctx, AV_LOG_ERROR, "Skipping high bytes tree\n");
     }
 
-    escapes[0]  = get_bits(gb, 8);
-    escapes[0] |= get_bits(gb, 8) << 8;
-    escapes[1]  = get_bits(gb, 8);
-    escapes[1] |= get_bits(gb, 8) << 8;
-    escapes[2]  = get_bits(gb, 8);
-    escapes[2] |= get_bits(gb, 8) << 8;
+    escapes[0]  = get_bits(gb, 16);
+    escapes[1]  = get_bits(gb, 16);
+    escapes[2]  = get_bits(gb, 16);
 
     last[0] = last[1] = last[2] = -1;
 
@@ -256,6 +257,11 @@
     if(ctx.last[0] == -1) ctx.last[0] = huff.current++;
     if(ctx.last[1] == -1) ctx.last[1] = huff.current++;
     if(ctx.last[2] == -1) ctx.last[2] = huff.current++;
+    if(huff.current > huff.length){
+        ctx.last[0] = ctx.last[1] = ctx.last[2] = 1;
+        av_log(smk->avctx, AV_LOG_ERROR, "bigtree damaged\n");
+        return -1;
+    }
 
     *recodes = huff.values;
 
@@ -363,7 +369,7 @@
     if (avpkt->size <= 769)
         return 0;
 
-    smk->pic.reference = 1;
+    smk->pic.reference = 3;
     smk->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
     if(avctx->reget_buffer(avctx, &smk->pic) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
@@ -382,7 +388,7 @@
         smk->pic.pict_type = AV_PICTURE_TYPE_P;
 
     for(i = 0; i < 256; i++)
-        *pal++ = bytestream2_get_be24u(&gb2);
+        *pal++ = 0xFF << 24 | bytestream2_get_be24u(&gb2);
 
     last_reset(smk->mmap_tbl, smk->mmap_last);
     last_reset(smk->mclr_tbl, smk->mclr_last);
@@ -517,6 +523,7 @@
 
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
+    avcodec_get_frame_defaults(&c->pic);
 
     /* decode huffman trees from extradata */
     if(avctx->extradata_size < 16){
@@ -655,16 +662,26 @@
         for(i = 0; i <= stereo; i++)
             *samples++ = pred[i];
         for(; i < unp_size / 2; i++) {
+            if(get_bits_left(&gb)<0)
+                return -1;
             if(i & stereo) {
                 if(vlc[2].table)
                     res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3);
                 else
                     res = 0;
+                if (res < 0) {
+                    av_log(avctx, AV_LOG_ERROR, "invalid vlc\n");
+                    return AVERROR_INVALIDDATA;
+                }
                 val  = h[2].values[res];
                 if(vlc[3].table)
                     res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3);
                 else
                     res = 0;
+                if (res < 0) {
+                    av_log(avctx, AV_LOG_ERROR, "invalid vlc\n");
+                    return AVERROR_INVALIDDATA;
+                }
                 val |= h[3].values[res] << 8;
                 pred[1] += sign_extend(val, 16);
                 *samples++ = av_clip_int16(pred[1]);
@@ -673,11 +690,19 @@
                     res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3);
                 else
                     res = 0;
+                if (res < 0) {
+                    av_log(avctx, AV_LOG_ERROR, "invalid vlc\n");
+                    return AVERROR_INVALIDDATA;
+                }
                 val  = h[0].values[res];
                 if(vlc[1].table)
                     res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3);
                 else
                     res = 0;
+                if (res < 0) {
+                    av_log(avctx, AV_LOG_ERROR, "invalid vlc\n");
+                    return AVERROR_INVALIDDATA;
+                }
                 val |= h[1].values[res] << 8;
                 pred[0] += sign_extend(val, 16);
                 *samples++ = av_clip_int16(pred[0]);
@@ -689,11 +714,17 @@
         for(i = 0; i <= stereo; i++)
             *samples8++ = pred[i];
         for(; i < unp_size; i++) {
+            if(get_bits_left(&gb)<0)
+                return -1;
             if(i & stereo){
                 if(vlc[1].table)
                     res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3);
                 else
                     res = 0;
+                if (res < 0) {
+                    av_log(avctx, AV_LOG_ERROR, "invalid vlc\n");
+                    return AVERROR_INVALIDDATA;
+                }
                 pred[1] += sign_extend(h[1].values[res], 8);
                 *samples8++ = av_clip_uint8(pred[1]);
             } else {
@@ -701,6 +732,10 @@
                     res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3);
                 else
                     res = 0;
+                if (res < 0) {
+                    av_log(avctx, AV_LOG_ERROR, "invalid vlc\n");
+                    return AVERROR_INVALIDDATA;
+                }
                 pred[0] += sign_extend(h[0].values[res], 8);
                 *samples8++ = av_clip_uint8(pred[0]);
             }
diff --git a/libavcodec/smc.c b/libavcodec/smc.c
index 38bf804..402c804 100644
--- a/libavcodec/smc.c
+++ b/libavcodec/smc.c
@@ -2,20 +2,20 @@
  * Quicktime Graphics (SMC) Video Decoder
  * Copyright (C) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -83,7 +83,7 @@
     int stride = s->frame.linesize[0];
     int i;
     int chunk_size;
-    int buf_size = (int) (s->gb.buffer_end - s->gb.buffer_start);
+    int buf_size = bytestream2_size(&s->gb);
     unsigned char opcode;
     int n_blocks;
     unsigned int color_flags;
@@ -416,6 +416,7 @@
     s->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
+    avcodec_get_frame_defaults(&s->frame);
     s->frame.data[0] = NULL;
 
     return 0;
@@ -432,7 +433,7 @@
 
     bytestream2_init(&s->gb, buf, buf_size);
 
-    s->frame.reference = 1;
+    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)) {
diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index d69f452..a4fe8b6 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -31,9 +31,6 @@
 #include "mathops.h"
 #include "h263.h"
 
-#undef NDEBUG
-#include <assert.h>
-
 
 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){
@@ -147,7 +144,7 @@
     int16_t *tmpI= tmpIt;
     uint8_t *tmp2= tmp2t[0];
     const uint8_t *hpel[11];
-    assert(dx<16 && dy<16);
+    av_assert2(dx<16 && dy<16);
     r= brane[dx + 16*dy]&15;
     l= brane[dx + 16*dy]>>4;
 
@@ -337,7 +334,7 @@
         }
     }else{
         uint8_t *src= s->last_picture[block->ref].data[plane_index];
-        const int scale= plane_index ?  s->mv_scale : 2*s->mv_scale;
+        const int scale= plane_index ?  (2*s->mv_scale)>>s->chroma_h_shift : 2*s->mv_scale;
         int mx= block->mx*scale;
         int my= block->my*scale;
         const int dx= mx&15;
@@ -351,10 +348,13 @@
             s->dsp.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;
         }
+
+        av_assert2(s->chroma_h_shift == s->chroma_v_shift); // only one mv_scale
+
 //        assert(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h);
 //        assert(!(b_w&(b_w-1)));
-        assert(b_w>1 && b_h>1);
-        assert((tab_index>=0 && tab_index<4) || b_w==32);
+        av_assert2(b_w>1 && b_h>1);
+        av_assert2((tab_index>=0 && tab_index<4) || b_w==32);
         if((dx&3) || (dy&3) || !(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h) || (b_w&(b_w-1)) || !s->plane[plane_index].fast_mc )
             mc_block(&s->plane[plane_index], dst, src, stride, b_w, b_h, dx, dy);
         else if(b_w==32){
@@ -369,7 +369,7 @@
             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);
         }else{
-            assert(2*b_w==b_h);
+            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);
         }
@@ -378,7 +378,7 @@
 
 #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){\
-    assert(h==b_w);\
+    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);\
 }
 
@@ -394,8 +394,7 @@
 av_cold int ff_snow_common_init(AVCodecContext *avctx){
     SnowContext *s = avctx->priv_data;
     int width, height;
-    int i, j, ret;
-    int emu_buf_size;
+    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
@@ -458,14 +457,6 @@
         for(j=0; j<MAX_REF_FRAMES; j++)
             ff_scale_mv_ref[i][j] = 256*(i+1)/(j+1);
 
-    if ((ret = s->avctx->get_buffer(s->avctx, &s->mconly_picture)) < 0) {
-        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        return ret;
-    }
-    FF_ALLOC_OR_GOTO(avctx, s->scratchbuf, s->mconly_picture.linesize[0]*7*MB_SIZE, fail);
-    emu_buf_size = s->mconly_picture.linesize[0] * (2 * MB_SIZE + HTAPS_MAX - 1);
-    FF_ALLOC_OR_GOTO(avctx, s->emu_edge_buffer, emu_buf_size, fail);
-
     return 0;
 fail:
     return AVERROR(ENOMEM);
@@ -474,6 +465,22 @@
 int ff_snow_common_init_after_header(AVCodecContext *avctx) {
     SnowContext *s = avctx->priv_data;
     int plane_index, level, orientation;
+    int ret, emu_buf_size;
+
+    if(!s->scratchbuf) {
+        if ((ret = s->avctx->get_buffer(s->avctx, &s->mconly_picture)) < 0) {
+            av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+            return ret;
+        }
+        FF_ALLOCZ_OR_GOTO(avctx, s->scratchbuf, FFMAX(s->mconly_picture.linesize[0], 2*avctx->width+256)*7*MB_SIZE, fail);
+        emu_buf_size = FFMAX(s->mconly_picture.linesize[0], 2*avctx->width+256) * (2 * MB_SIZE + HTAPS_MAX - 1);
+        FF_ALLOC_OR_GOTO(avctx, s->emu_edge_buffer, emu_buf_size, fail);
+    }
+
+    if(s->mconly_picture.format != avctx->pix_fmt) {
+        av_log(avctx, AV_LOG_ERROR, "pixel format changed\n");
+        return AVERROR_INVALIDDATA;
+    }
 
     for(plane_index=0; plane_index<3; plane_index++){
         int w= s->avctx->width;
@@ -522,6 +529,8 @@
     }
 
     return 0;
+fail:
+    return AVERROR(ENOMEM);
 }
 
 #define USE_HALFPEL_PLANE 0
@@ -531,8 +540,8 @@
 
     for(p=0; p<3; p++){
         int is_chroma= !!p;
-        int w= s->avctx->width  >>is_chroma;
-        int h= s->avctx->height >>is_chroma;
+        int w= is_chroma ? s->avctx->width >>s->chroma_h_shift : s->avctx->width;
+        int h= is_chroma ? s->avctx->height>>s->chroma_v_shift : s->avctx->height;
         int ls= frame->linesize[p];
         uint8_t *src= frame->data[p];
 
@@ -591,11 +600,11 @@
                           s->current_picture.linesize[0], w   , h   ,
                           EDGE_WIDTH  , EDGE_WIDTH  , EDGE_TOP | EDGE_BOTTOM);
         s->dsp.draw_edges(s->current_picture.data[1],
-                          s->current_picture.linesize[1], w>>1, h>>1,
-                          EDGE_WIDTH/2, EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM);
+                          s->current_picture.linesize[1], w>>s->chroma_h_shift, h>>s->chroma_v_shift,
+                          EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM);
         s->dsp.draw_edges(s->current_picture.data[2],
-                          s->current_picture.linesize[2], w>>1, h>>1,
-                          EDGE_WIDTH/2, EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM);
+                          s->current_picture.linesize[2], w>>s->chroma_h_shift, h>>s->chroma_v_shift,
+                          EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM);
     }
 
     ff_snow_release_buffer(s->avctx);
@@ -622,7 +631,7 @@
         }
     }
 
-    s->current_picture.reference= 1;
+    s->current_picture.reference= 3;
     if(s->avctx->get_buffer(s->avctx, &s->current_picture) < 0){
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
@@ -656,8 +665,10 @@
     for(i=0; i<MAX_REF_FRAMES; i++){
         av_freep(&s->ref_mvs[i]);
         av_freep(&s->ref_scores[i]);
-        if(s->last_picture[i].data[0])
+        if(s->last_picture[i].data[0]) {
+            av_assert0(s->last_picture[i].data[0] != s->current_picture.data[0]);
             s->avctx->release_buffer(s->avctx, &s->last_picture[i]);
+        }
     }
 
     for(plane_index=0; plane_index<3; plane_index++){
diff --git a/libavcodec/snow.h b/libavcodec/snow.h
index abf3309..6d6b086 100644
--- a/libavcodec/snow.h
+++ b/libavcodec/snow.h
@@ -2,20 +2,20 @@
  * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (C) 2006 Robert Edele <yartrebo@earthlink.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -161,6 +161,7 @@
     unsigned me_cache_generation;
     slice_buffer sb;
     int memc_only;
+    int no_bitstream;
 
     MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX)
 
@@ -326,7 +327,7 @@
 
     if(b_w<=0 || b_h<=0) return;
 
-    assert(src_stride > 2*MB_SIZE + 5);
+    av_assert2(src_stride > 2*MB_SIZE + 5);
 
     if(!sliced && offset_dst)
         dst += src_x + src_y*dst_stride;
@@ -404,20 +405,21 @@
     const int mb_h= s->b_height << s->block_max_depth;
     int x, y, mb_x;
     int block_size = MB_SIZE >> s->block_max_depth;
-    int block_w    = plane_index ? block_size/2 : block_size;
-    const uint8_t *obmc  = plane_index ? ff_obmc_tab[s->block_max_depth+1] : ff_obmc_tab[s->block_max_depth];
-    const int obmc_stride= plane_index ? block_size : 2*block_size;
+    int block_w    = plane_index ? block_size>>s->chroma_h_shift : block_size;
+    int block_h    = plane_index ? block_size>>s->chroma_v_shift : block_size;
+    const uint8_t *obmc  = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth];
+    const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
     int ref_stride= s->current_picture.linesize[plane_index];
     uint8_t *dst8= s->current_picture.data[plane_index];
     int w= p->width;
     int h= p->height;
-
+    av_assert2(s->chroma_h_shift == s->chroma_v_shift); // obmc params assume squares
     if(s->keyframe || (s->avctx->debug&512)){
         if(mb_y==mb_h)
             return;
 
         if(add){
-            for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
+            for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
                 for(x=0; x<w; x++){
                     int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
                     v >>= FRAC_BITS;
@@ -426,7 +428,7 @@
                 }
             }
         }else{
-            for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
+            for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
                 for(x=0; x<w; x++){
                     buf[x + y*w]-= 128<<FRAC_BITS;
                 }
@@ -439,8 +441,8 @@
     for(mb_x=0; mb_x<=mb_w; mb_x++){
         add_yblock(s, 0, NULL, buf, dst8, obmc,
                    block_w*mb_x - block_w/2,
-                   block_w*mb_y - block_w/2,
-                   block_w, block_w,
+                   block_h*mb_y - block_h/2,
+                   block_w, block_h,
                    w, h,
                    w, ref_stride, obmc_stride,
                    mb_x - 1, mb_y - 1,
@@ -460,6 +462,7 @@
     const int rem_depth= s->block_max_depth - level;
     const int index= (x + y*w) << rem_depth;
     const int block_w= 1<<rem_depth;
+    const int block_h= 1<<rem_depth; //FIXME "w!=h"
     BlockNode block;
     int i,j;
 
@@ -472,7 +475,7 @@
     block.type= type;
     block.level= level;
 
-    for(j=0; j<block_w; j++){
+    for(j=0; j<block_h; j++){
         for(i=0; i<block_w; i++){
             s->block[index + i + j*w]= block;
         }
@@ -480,17 +483,18 @@
 }
 
 static inline void init_ref(MotionEstContext *c, uint8_t *src[3], uint8_t *ref[3], uint8_t *ref2[3], int x, int y, int ref_index){
+    SnowContext *s = c->avctx->priv_data;
     const int offset[3]= {
           y*c->  stride + x,
-        ((y*c->uvstride + x)>>1),
-        ((y*c->uvstride + x)>>1),
+        ((y*c->uvstride + x)>>s->chroma_h_shift),
+        ((y*c->uvstride + x)>>s->chroma_h_shift),
     };
     int i;
     for(i=0; i<3; i++){
         c->src[0][i]= src [i];
         c->ref[0][i]= ref [i] + offset[i];
     }
-    assert(!ref_index);
+    av_assert2(!ref_index);
 }
 
 
@@ -555,8 +559,8 @@
     int i;
     int r= log2>=0 ? 1<<log2 : 1;
 
-    assert(v>=0);
-    assert(log2>=-4);
+    av_assert2(v>=0);
+    av_assert2(log2>=-4);
 
     while(v >= r){
         put_rac(c, state+4+log2, 1);
@@ -576,9 +580,9 @@
     int r= log2>=0 ? 1<<log2 : 1;
     int v=0;
 
-    assert(log2>=-4);
+    av_assert2(log2>=-4);
 
-    while(get_rac(c, state+4+log2)){
+    while(log2<28 && get_rac(c, state+4+log2)){
         v+= r;
         log2++;
         if(log2>0) r+=r;
@@ -660,11 +664,13 @@
                     int max_run;
                     run--;
                     v=0;
-
+                    av_assert2(run >= 0);
                     if(y) max_run= FFMIN(run, prev_xc->x - x - 2);
                     else  max_run= FFMIN(run, w-x-1);
                     if(parent_xc)
                         max_run= FFMIN(max_run, 2*parent_xc->x - x - 1);
+                    av_assert2(max_run >= 0 && max_run <= run);
+
                     x+= max_run;
                     run-= max_run;
                 }
diff --git a/libavcodec/snowdata.h b/libavcodec/snowdata.h
index 4a91858..490fdf8 100644
--- a/libavcodec/snowdata.h
+++ b/libavcodec/snowdata.h
@@ -2,20 +2,20 @@
  * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (C) 2006 Robert Edele <yartrebo@earthlink.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c
index c4d2904..f377409 100644
--- a/libavcodec/snowdec.c
+++ b/libavcodec/snowdec.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -41,9 +41,10 @@
     const int mb_h= s->b_height << s->block_max_depth;
     int x, y, mb_x;
     int block_size = MB_SIZE >> s->block_max_depth;
-    int block_w    = plane_index ? block_size/2 : block_size;
-    const uint8_t *obmc  = plane_index ? ff_obmc_tab[s->block_max_depth+1] : ff_obmc_tab[s->block_max_depth];
-    int obmc_stride= plane_index ? block_size : 2*block_size;
+    int block_w    = plane_index ? block_size>>s->chroma_h_shift : block_size;
+    int block_h    = plane_index ? block_size>>s->chroma_v_shift : block_size;
+    const uint8_t *obmc  = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth];
+    int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
     int ref_stride= s->current_picture.linesize[plane_index];
     uint8_t *dst8= s->current_picture.data[plane_index];
     int w= p->width;
@@ -54,7 +55,7 @@
             return;
 
         if(add){
-            for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
+            for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
 //                DWTELEM * line = slice_buffer_get_line(sb, y);
                 IDWTELEM * line = sb->line[y];
                 for(x=0; x<w; x++){
@@ -66,7 +67,7 @@
                 }
             }
         }else{
-            for(y=block_w*mb_y; y<FFMIN(h,block_w*(mb_y+1)); y++){
+            for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
 //                DWTELEM * line = slice_buffer_get_line(sb, y);
                 IDWTELEM * line = sb->line[y];
                 for(x=0; x<w; x++){
@@ -82,8 +83,8 @@
     for(mb_x=0; mb_x<=mb_w; mb_x++){
         add_yblock(s, 1, sb, old_buffer, dst8, obmc,
                    block_w*mb_x - block_w/2,
-                   block_w*mb_y - block_w/2,
-                   block_w, block_w,
+                   block_h*mb_y - block_h/2,
+                   block_w, block_h,
                    w, h,
                    w, ref_stride, obmc_stride,
                    mb_x - 1, mb_y - 1,
@@ -289,6 +290,20 @@
         s->colorspace_type= get_symbol(&s->c, s->header_state, 0);
         s->chroma_h_shift= get_symbol(&s->c, s->header_state, 0);
         s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0);
+
+        if(s->chroma_h_shift == 1 && s->chroma_v_shift==1){
+            s->avctx->pix_fmt= AV_PIX_FMT_YUV420P;
+        }else if(s->chroma_h_shift == 0 && s->chroma_v_shift==0){
+            s->avctx->pix_fmt= AV_PIX_FMT_YUV444P;
+        }else if(s->chroma_h_shift == 2 && s->chroma_v_shift==2){
+            s->avctx->pix_fmt= AV_PIX_FMT_YUV410P;
+        } else {
+            av_log(s, AV_LOG_ERROR, "unsupported color subsample mode %d %d\n", s->chroma_h_shift, s->chroma_v_shift);
+            s->chroma_h_shift = s->chroma_v_shift = 1;
+            s->avctx->pix_fmt= AV_PIX_FMT_YUV420P;
+            return AVERROR_INVALIDDATA;
+        }
+
         s->spatial_scalability= get_rac(&s->c, s->header_state);
 //        s->rate_scalability= get_rac(&s->c, s->header_state);
         GET_S(s->max_ref_frames, tmp < (unsigned)MAX_REF_FRAMES)
@@ -325,26 +340,22 @@
 
     s->spatial_decomposition_type+= get_symbol(&s->c, s->header_state, 1);
     if(s->spatial_decomposition_type > 1U){
-        av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_type %d not supported", s->spatial_decomposition_type);
+        av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_type %d not supported\n", s->spatial_decomposition_type);
         return -1;
     }
     if(FFMIN(s->avctx-> width>>s->chroma_h_shift,
              s->avctx->height>>s->chroma_v_shift) >> (s->spatial_decomposition_count-1) <= 0){
-        av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_count %d too large for size", s->spatial_decomposition_count);
+        av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_count %d too large for size\n", s->spatial_decomposition_count);
         return -1;
     }
 
-    if (s->chroma_h_shift != 1 || s->chroma_v_shift != 1) {
-        av_log(s->avctx, AV_LOG_ERROR, "Invalid chroma shift\n");
-        return AVERROR_PATCHWELCOME;
-    }
 
     s->qlog           += get_symbol(&s->c, s->header_state, 1);
     s->mv_scale       += get_symbol(&s->c, s->header_state, 1);
     s->qbias          += get_symbol(&s->c, s->header_state, 1);
     s->block_max_depth+= get_symbol(&s->c, s->header_state, 1);
     if(s->block_max_depth > 1 || s->block_max_depth < 0){
-        av_log(s->avctx, AV_LOG_ERROR, "block_max_depth= %d is too large", s->block_max_depth);
+        av_log(s->avctx, AV_LOG_ERROR, "block_max_depth= %d is too large\n", s->block_max_depth);
         s->block_max_depth= 0;
         return -1;
     }
@@ -356,8 +367,6 @@
 {
     int ret;
 
-    avctx->pix_fmt= AV_PIX_FMT_YUV420P;
-
     if ((ret = ff_snow_common_init(avctx)) < 0) {
         ff_snow_common_end(avctx->priv_data);
         return ret;
@@ -397,13 +406,14 @@
     s->current_picture.pict_type= AV_PICTURE_TYPE_I; //FIXME I vs. P
     if(decode_header(s)<0)
         return -1;
-    ff_snow_common_init_after_header(avctx);
+    if ((res=ff_snow_common_init_after_header(avctx)) < 0)
+        return res;
 
     // realloc slice buffer for the case that spatial_decomposition_count changed
     ff_slice_buffer_destroy(&s->sb);
     if ((res = ff_slice_buffer_init(&s->sb, s->plane[0].height,
                                     (MB_SIZE >> s->block_max_depth) +
-                                    s->spatial_decomposition_count * 8 + 1,
+                                    s->spatial_decomposition_count * 11 + 1,
                                     s->plane[0].width,
                                     s->spatial_idwt_buffer)) < 0)
         return res;
@@ -457,7 +467,7 @@
         {
         const int mb_h= s->b_height << s->block_max_depth;
         const int block_size = MB_SIZE >> s->block_max_depth;
-        const int block_w    = plane_index ? block_size/2 : block_size;
+        const int block_h    = plane_index ? block_size>>s->chroma_v_shift : block_size;
         int mb_y;
         DWTCompose cs[MAX_DECOMPOSITIONS];
         int yd=0, yq=0;
@@ -467,11 +477,12 @@
         ff_spatial_idwt_buffered_init(cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count);
         for(mb_y=0; mb_y<=mb_h; mb_y++){
 
-            int slice_starty = block_w*mb_y;
-            int slice_h = block_w*(mb_y+1);
+            int slice_starty = block_h*mb_y;
+            int slice_h = block_h*(mb_y+1);
+
             if (!(s->keyframe || s->avctx->debug&512)){
-                slice_starty = FFMAX(0, slice_starty - (block_w >> 1));
-                slice_h -= (block_w >> 1);
+                slice_starty = FFMAX(0, slice_starty - (block_h >> 1));
+                slice_h -= (block_h >> 1);
             }
 
             for(level=0; level<s->spatial_decomposition_count; level++){
@@ -482,11 +493,11 @@
                     int our_mb_start = mb_y;
                     int our_mb_end = (mb_y + 1);
                     const int extra= 3;
-                    start_y = (mb_y ? ((block_w * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra: 0);
-                    end_y = (((block_w * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra);
+                    start_y = (mb_y ? ((block_h * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra: 0);
+                    end_y = (((block_h * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra);
                     if (!(s->keyframe || s->avctx->debug&512)){
-                        start_y = FFMAX(0, start_y - (block_w >> (1+s->spatial_decomposition_count - level)));
-                        end_y = FFMAX(0, end_y - (block_w >> (1+s->spatial_decomposition_count - level)));
+                        start_y = FFMAX(0, start_y - (block_h >> (1+s->spatial_decomposition_count - level)));
+                        end_y = FFMAX(0, end_y - (block_h >> (1+s->spatial_decomposition_count - level)));
                     }
                     start_y = FFMIN(b->height, start_y);
                     end_y = FFMIN(b->height, end_y);
diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c
index 29f5330..cbdf978 100644
--- a/libavcodec/snowenc.c
+++ b/libavcodec/snowenc.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -22,6 +22,7 @@
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "avcodec.h"
+#include "internal.h"
 #include "dsputil.h"
 #include "dwt.h"
 #include "snow.h"
@@ -217,12 +218,12 @@
 
     avctx->coded_frame= &s->current_picture;
     switch(avctx->pix_fmt){
-//    case AV_PIX_FMT_YUV444P:
+    case AV_PIX_FMT_YUV444P:
 //    case AV_PIX_FMT_YUV422P:
     case AV_PIX_FMT_YUV420P:
-    case AV_PIX_FMT_GRAY8:
+//     case AV_PIX_FMT_GRAY8:
 //    case AV_PIX_FMT_YUV411P:
-//    case AV_PIX_FMT_YUV410P:
+    case AV_PIX_FMT_YUV410P:
         s->colorspace_type= 0;
         break;
 /*    case AV_PIX_FMT_RGB32:
@@ -232,9 +233,7 @@
         av_log(avctx, AV_LOG_ERROR, "pixel format not supported\n");
         return -1;
     }
-//    avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift);
-    s->chroma_h_shift= 1;
-    s->chroma_v_shift= 1;
+    avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_h_shift, &s->chroma_v_shift);
 
     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);
@@ -254,12 +253,12 @@
 }
 
 //near copy & paste from dsputil, FIXME
-static int pix_sum(uint8_t * pix, int line_size, int w)
+static int pix_sum(uint8_t * pix, int line_size, int w, int h)
 {
     int s, i, j;
 
     s = 0;
-    for (i = 0; i < w; i++) {
+    for (i = 0; i < h; i++) {
         for (j = 0; j < w; j++) {
             s += pix[0];
             pix ++;
@@ -325,8 +324,8 @@
     const int stride= s->current_picture.linesize[0];
     const int uvstride= s->current_picture.linesize[1];
     uint8_t *current_data[3]= { s->input_picture.data[0] + (x + y*  stride)*block_w,
-                                s->input_picture.data[1] + (x + y*uvstride)*block_w/2,
-                                s->input_picture.data[2] + (x + y*uvstride)*block_w/2};
+                                s->input_picture.data[1] + ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift),
+                                s->input_picture.data[2] + ((x*block_w)>>s->chroma_h_shift) + ((y*uvstride*block_w)>>s->chroma_v_shift)};
     int P[10][2];
     int16_t last_mv[3][2];
     int qpel= !!(s->avctx->flags & CODEC_FLAG_QPEL); //unused
@@ -446,15 +445,15 @@
     score += (s->lambda2*(get_rac_count(&pc)-base_bits))>>FF_LAMBDA_SHIFT;
 
     block_s= block_w*block_w;
-    sum = pix_sum(current_data[0], stride, block_w);
+    sum = pix_sum(current_data[0], stride, block_w, block_w);
     l= (sum + block_s/2)/block_s;
     iscore = pix_norm1(current_data[0], stride, block_w) - 2*l*sum + l*l*block_s;
 
-    block_s= block_w*block_w>>2;
-    sum = pix_sum(current_data[1], uvstride, block_w>>1);
+    block_s= block_w*block_w>>(s->chroma_h_shift + s->chroma_v_shift);
+    sum = pix_sum(current_data[1], uvstride, block_w>>s->chroma_h_shift, block_w>>s->chroma_v_shift);
     cb= (sum + block_s/2)/block_s;
 //    iscore += pix_norm1(&current_mb[1][0], uvstride, block_w>>1) - 2*cb*sum + cb*cb*block_s;
-    sum = pix_sum(current_data[2], uvstride, block_w>>1);
+    sum = pix_sum(current_data[2], uvstride, block_w>>s->chroma_h_shift, block_w>>s->chroma_v_shift);
     cr= (sum + block_s/2)/block_s;
 //    iscore += pix_norm1(&current_mb[2][0], uvstride, block_w>>1) - 2*cr*sum + cr*cr*block_s;
 
@@ -576,9 +575,10 @@
     int i, x2, y2;
     Plane *p= &s->plane[plane_index];
     const int block_size = MB_SIZE >> s->block_max_depth;
-    const int block_w    = plane_index ? block_size/2 : block_size;
-    const uint8_t *obmc  = plane_index ? ff_obmc_tab[s->block_max_depth+1] : ff_obmc_tab[s->block_max_depth];
-    const int obmc_stride= plane_index ? block_size : 2*block_size;
+    const int block_w    = plane_index ? block_size>>s->chroma_h_shift : block_size;
+    const int block_h    = plane_index ? block_size>>s->chroma_v_shift : block_size;
+    const uint8_t *obmc  = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth];
+    const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
     const int ref_stride= s->current_picture.linesize[plane_index];
     uint8_t *src= s-> input_picture.data[plane_index];
     IDWTELEM *dst= (IDWTELEM*)s->m.obmc_scratchpad + plane_index*block_size*block_size*4; //FIXME change to unsigned
@@ -591,6 +591,8 @@
     int ab=0;
     int aa=0;
 
+    av_assert2(s->chroma_h_shift == s->chroma_v_shift); //obmc stuff above
+
     b->type|= BLOCK_INTRA;
     b->color[plane_index]= 0;
     memset(dst, 0, obmc_stride*obmc_stride*sizeof(IDWTELEM));
@@ -599,19 +601,19 @@
         int mb_x2= mb_x + (i &1) - 1;
         int mb_y2= mb_y + (i>>1) - 1;
         int x= block_w*mb_x2 + block_w/2;
-        int y= block_w*mb_y2 + block_w/2;
+        int y= block_h*mb_y2 + block_h/2;
 
-        add_yblock(s, 0, NULL, dst + ((i&1)+(i>>1)*obmc_stride)*block_w, NULL, obmc,
-                    x, y, block_w, block_w, w, h, obmc_stride, ref_stride, obmc_stride, mb_x2, mb_y2, 0, 0, plane_index);
+        add_yblock(s, 0, NULL, dst + (i&1)*block_w + (i>>1)*obmc_stride*block_h, NULL, obmc,
+                    x, y, block_w, block_h, w, h, obmc_stride, ref_stride, obmc_stride, mb_x2, mb_y2, 0, 0, plane_index);
 
-        for(y2= FFMAX(y, 0); y2<FFMIN(h, y+block_w); y2++){
+        for(y2= FFMAX(y, 0); y2<FFMIN(h, y+block_h); y2++){
             for(x2= FFMAX(x, 0); x2<FFMIN(w, x+block_w); x2++){
-                int index= x2-(block_w*mb_x - block_w/2) + (y2-(block_w*mb_y - block_w/2))*obmc_stride;
+                int index= x2-(block_w*mb_x - block_w/2) + (y2-(block_h*mb_y - block_h/2))*obmc_stride;
                 int obmc_v= obmc[index];
                 int d;
-                if(y<0) obmc_v += obmc[index + block_w*obmc_stride];
+                if(y<0) obmc_v += obmc[index + block_h*obmc_stride];
                 if(x<0) obmc_v += obmc[index + block_w];
-                if(y+block_w>h) obmc_v += obmc[index - block_w*obmc_stride];
+                if(y+block_h>h) obmc_v += obmc[index - block_h*obmc_stride];
                 if(x+block_w>w) obmc_v += obmc[index - block_w];
                 //FIXME precalculate this or simplify it somehow else
 
@@ -668,8 +670,9 @@
 static int get_block_rd(SnowContext *s, int mb_x, int mb_y, int plane_index, uint8_t (*obmc_edged)[MB_SIZE * 2]){
     Plane *p= &s->plane[plane_index];
     const int block_size = MB_SIZE >> s->block_max_depth;
-    const int block_w    = plane_index ? block_size/2 : block_size;
-    const int obmc_stride= plane_index ? block_size : 2*block_size;
+    const int block_w    = plane_index ? block_size>>s->chroma_h_shift : block_size;
+    const int block_h    = plane_index ? block_size>>s->chroma_v_shift : block_size;
+    const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
     const int ref_stride= s->current_picture.linesize[plane_index];
     uint8_t *dst= s->current_picture.data[plane_index];
     uint8_t *src= s->  input_picture.data[plane_index];
@@ -684,14 +687,16 @@
     int rate= 0;
     const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp);
     int sx= block_w*mb_x - block_w/2;
-    int sy= block_w*mb_y - block_w/2;
+    int sy= block_h*mb_y - block_h/2;
     int x0= FFMAX(0,-sx);
     int y0= FFMAX(0,-sy);
     int x1= FFMIN(block_w*2, w-sx);
-    int y1= FFMIN(block_w*2, h-sy);
+    int y1= FFMIN(block_h*2, h-sy);
     int i,x,y;
 
-    ff_snow_pred_block(s, cur, tmp, ref_stride, sx, sy, block_w*2, block_w*2, &s->block[mb_x + mb_y*b_stride], plane_index, w, h);
+    av_assert2(s->chroma_h_shift == s->chroma_v_shift); //obmc and square assumtions below chckinhg only block_w
+
+    ff_snow_pred_block(s, cur, tmp, ref_stride, sx, sy, block_w*2, block_h*2, &s->block[mb_x + mb_y*b_stride], plane_index, w, h);
 
     for(y=y0; y<y1; y++){
         const uint8_t *obmc1= obmc_edged[y];
@@ -719,9 +724,9 @@
         else
             x0 = block_w;
         if(mb_y == 0)
-            y1 = block_w;
+            y1 = block_h;
         else
-            y0 = block_w;
+            y0 = block_h;
         for(y=y0; y<y1; y++)
             memcpy(dst + sx+x0 + (sy+y)*ref_stride, cur + x0 + y*ref_stride, x1-x0);
     }
@@ -767,9 +772,10 @@
     int i, y2;
     Plane *p= &s->plane[plane_index];
     const int block_size = MB_SIZE >> s->block_max_depth;
-    const int block_w    = plane_index ? block_size/2 : block_size;
-    const uint8_t *obmc  = plane_index ? ff_obmc_tab[s->block_max_depth+1] : ff_obmc_tab[s->block_max_depth];
-    const int obmc_stride= plane_index ? block_size : 2*block_size;
+    const int block_w    = plane_index ? block_size>>s->chroma_h_shift : block_size;
+    const int block_h    = plane_index ? block_size>>s->chroma_v_shift : block_size;
+    const uint8_t *obmc  = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth];
+    const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
     const int ref_stride= s->current_picture.linesize[plane_index];
     uint8_t *dst= s->current_picture.data[plane_index];
     uint8_t *src= s-> input_picture.data[plane_index];
@@ -783,31 +789,33 @@
     int rate= 0;
     const int penalty_factor= get_penalty_factor(s->lambda, s->lambda2, s->avctx->me_cmp);
 
+    av_assert2(s->chroma_h_shift == s->chroma_v_shift); //obmc and square assumtions below
+
     for(i=0; i<9; i++){
         int mb_x2= mb_x + (i%3) - 1;
         int mb_y2= mb_y + (i/3) - 1;
         int x= block_w*mb_x2 + block_w/2;
-        int y= block_w*mb_y2 + block_w/2;
+        int y= block_h*mb_y2 + block_h/2;
 
         add_yblock(s, 0, NULL, zero_dst, dst, obmc,
-                   x, y, block_w, block_w, w, h, /*dst_stride*/0, ref_stride, obmc_stride, mb_x2, mb_y2, 1, 1, plane_index);
+                   x, y, block_w, block_h, w, h, /*dst_stride*/0, ref_stride, obmc_stride, mb_x2, mb_y2, 1, 1, plane_index);
 
         //FIXME find a cleaner/simpler way to skip the outside stuff
         for(y2= y; y2<0; y2++)
             memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w);
-        for(y2= h; y2<y+block_w; y2++)
+        for(y2= h; y2<y+block_h; y2++)
             memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, block_w);
         if(x<0){
-            for(y2= y; y2<y+block_w; y2++)
+            for(y2= y; y2<y+block_h; y2++)
                 memcpy(dst + x + y2*ref_stride, src + x + y2*ref_stride, -x);
         }
         if(x+block_w > w){
-            for(y2= y; y2<y+block_w; y2++)
+            for(y2= y; y2<y+block_h; y2++)
                 memcpy(dst + w + y2*ref_stride, src + w + y2*ref_stride, x+block_w - w);
         }
 
         assert(block_w== 8 || block_w==16);
-        distortion += s->dsp.me_cmp[block_w==8](&s->m, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_w);
+        distortion += s->dsp.me_cmp[block_w==8](&s->m, src + x + y*ref_stride, dst + x + y*ref_stride, ref_stride, block_h);
     }
 
     if(plane_index==0){
@@ -829,7 +837,7 @@
     return distortion + rate*penalty_factor;
 }
 
-static int encode_subband_c0run(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){
+static int encode_subband_c0run(SnowContext *s, SubBand *b, const IDWTELEM *src, const IDWTELEM *parent, int stride, int orientation){
     const int w= b->width;
     const int h= b->height;
     int x, y;
@@ -949,7 +957,7 @@
     return 0;
 }
 
-static int encode_subband(SnowContext *s, SubBand *b, IDWTELEM *src, IDWTELEM *parent, int stride, int orientation){
+static int encode_subband(SnowContext *s, SubBand *b, const IDWTELEM *src, const IDWTELEM *parent, int stride, int orientation){
 //    encode_subband_qtree(s, b, src, parent, stride, orientation);
 //    encode_subband_z0run(s, b, src, parent, stride, orientation);
     return encode_subband_c0run(s, b, src, parent, stride, orientation);
@@ -1128,22 +1136,23 @@
                     uint8_t *dst= s->current_picture.data[0];
                     const int stride= s->current_picture.linesize[0];
                     const int block_w= MB_SIZE >> s->block_max_depth;
+                    const int block_h= MB_SIZE >> s->block_max_depth;
                     const int sx= block_w*mb_x - block_w/2;
-                    const int sy= block_w*mb_y - block_w/2;
+                    const int sy= block_h*mb_y - block_h/2;
                     const int w= s->plane[0].width;
                     const int h= s->plane[0].height;
                     int y;
 
                     for(y=sy; y<0; y++)
                         memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2);
-                    for(y=h; y<sy+block_w*2; y++)
+                    for(y=h; y<sy+block_h*2; y++)
                         memcpy(dst + sx + y*stride, src + sx + y*stride, block_w*2);
                     if(sx<0){
-                        for(y=sy; y<sy+block_w*2; y++)
+                        for(y=sy; y<sy+block_h*2; y++)
                             memcpy(dst + sx + y*stride, src + sx + y*stride, -sx);
                     }
                     if(sx+block_w*2 > w){
-                        for(y=sy; y<sy+block_w*2; y++)
+                        for(y=sy; y<sy+block_h*2; y++)
                             memcpy(dst + w + y*stride, src + w + y*stride, sx+block_w*2 - w);
                     }
                 }
@@ -1623,21 +1632,19 @@
     uint8_t rc_header_bak[sizeof(s->header_state)];
     uint8_t rc_block_bak[sizeof(s->block_state)];
 
-    if (!pkt->data &&
-        (ret = av_new_packet(pkt, s->b_width*s->b_height*MB_SIZE*MB_SIZE*3 + FF_MIN_BUFFER_SIZE)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, s->b_width*s->b_height*MB_SIZE*MB_SIZE*3 + FF_MIN_BUFFER_SIZE)) < 0)
         return ret;
-    }
 
     ff_init_range_encoder(c, pkt->data, pkt->size);
     ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
 
     for(i=0; i<3; i++){
-        int shift= !!i;
-        for(y=0; y<(height>>shift); y++)
+        int hshift= i ? s->chroma_h_shift : 0;
+        int vshift= i ? s->chroma_v_shift : 0;
+        for(y=0; y<(height>>vshift); y++)
             memcpy(&s->input_picture.data[i][y * s->input_picture.linesize[i]],
                    &pict->data[i][y * pict->linesize[i]],
-                   width>>shift);
+                   width>>hshift);
     }
     s->new_picture = *pict;
 
@@ -1725,6 +1732,10 @@
     else
         s->spatial_decomposition_count= 5;
 
+    while(   !(width >>(s->chroma_h_shift + s->spatial_decomposition_count))
+          || !(height>>(s->chroma_v_shift + s->spatial_decomposition_count)))
+        s->spatial_decomposition_count--;
+
     s->m.pict_type = pic->pict_type;
     s->qbias = pic->pict_type == AV_PICTURE_TYPE_P ? 2 : 0;
 
@@ -1811,6 +1822,7 @@
                         quantize(s, b, b->ibuf, b->buf, b->stride, s->qbias);
                     if(orientation==0)
                         decorrelate(s, b, b->ibuf, b->stride, pic->pict_type == AV_PICTURE_TYPE_P, 0);
+                    if (!s->no_bitstream)
                     encode_subband(s, b, b->ibuf, b->parent ? b->parent->ibuf : NULL, b->stride, orientation);
                     assert(b->parent==NULL || b->parent->stride == b->stride*2);
                     if(orientation==0)
@@ -1915,6 +1927,7 @@
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
     { "memc_only",      "Only do ME/MC (I frames -> ref, P frame -> ME+MC).",   OFFSET(memc_only), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
+    { "no_bitstream",   "Skip final bitstream writeout.",                    OFFSET(no_bitstream), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
     { NULL },
 };
 
@@ -1933,6 +1946,134 @@
     .init           = encode_init,
     .encode2        = encode_frame,
     .close          = encode_end,
+    .pix_fmts       = (const enum AVPixelFormat[]){
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV444P,
+        AV_PIX_FMT_NONE
+    },
     .long_name      = NULL_IF_CONFIG_SMALL("Snow"),
     .priv_class     = &snowenc_class,
 };
+
+
+#ifdef TEST
+#undef malloc
+#undef free
+#undef printf
+
+#include "libavutil/lfg.h"
+#include "libavutil/mathematics.h"
+
+int main(void){
+#define width  256
+#define height 256
+    int buffer[2][width*height];
+    SnowContext s;
+    int i;
+    AVLFG prng;
+    s.spatial_decomposition_count=6;
+    s.spatial_decomposition_type=1;
+
+    s.temp_dwt_buffer  = av_mallocz(width * sizeof(DWTELEM));
+    s.temp_idwt_buffer = av_mallocz(width * sizeof(IDWTELEM));
+
+    av_lfg_init(&prng, 1);
+
+    printf("testing 5/3 DWT\n");
+    for(i=0; i<width*height; i++)
+        buffer[0][i] = buffer[1][i] = av_lfg_get(&prng) % 54321 - 12345;
+
+    ff_spatial_dwt(buffer[0], s.temp_dwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
+    ff_spatial_idwt((IDWTELEM*)buffer[0], s.temp_idwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
+
+    for(i=0; i<width*height; i++)
+        if(buffer[0][i]!= buffer[1][i]) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]);
+
+    printf("testing 9/7 DWT\n");
+    s.spatial_decomposition_type=0;
+    for(i=0; i<width*height; i++)
+        buffer[0][i] = buffer[1][i] = av_lfg_get(&prng) % 54321 - 12345;
+
+    ff_spatial_dwt(buffer[0], s.temp_dwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
+    ff_spatial_idwt((IDWTELEM*)buffer[0], s.temp_idwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
+
+    for(i=0; i<width*height; i++)
+        if(FFABS(buffer[0][i] - buffer[1][i])>20) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]);
+
+    {
+    int level, orientation, x, y;
+    int64_t errors[8][4];
+    int64_t g=0;
+
+        memset(errors, 0, sizeof(errors));
+        s.spatial_decomposition_count=3;
+        s.spatial_decomposition_type=0;
+        for(level=0; level<s.spatial_decomposition_count; level++){
+            for(orientation=level ? 1 : 0; orientation<4; orientation++){
+                int w= width  >> (s.spatial_decomposition_count-level);
+                int h= height >> (s.spatial_decomposition_count-level);
+                int stride= width  << (s.spatial_decomposition_count-level);
+                DWTELEM *buf= buffer[0];
+                int64_t error=0;
+
+                if(orientation&1) buf+=w;
+                if(orientation>1) buf+=stride>>1;
+
+                memset(buffer[0], 0, sizeof(int)*width*height);
+                buf[w/2 + h/2*stride]= 256*256;
+                ff_spatial_idwt((IDWTELEM*)buffer[0], s.temp_idwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
+                for(y=0; y<height; y++){
+                    for(x=0; x<width; x++){
+                        int64_t d= buffer[0][x + y*width];
+                        error += d*d;
+                        if(FFABS(width/2-x)<9 && FFABS(height/2-y)<9 && level==2) printf("%8"PRId64" ", d);
+                    }
+                    if(FFABS(height/2-y)<9 && level==2) printf("\n");
+                }
+                error= (int)(sqrt(error)+0.5);
+                errors[level][orientation]= error;
+                if(g) g=av_gcd(g, error);
+                else g= error;
+            }
+        }
+        printf("static int const visual_weight[][4]={\n");
+        for(level=0; level<s.spatial_decomposition_count; level++){
+            printf("  {");
+            for(orientation=0; orientation<4; orientation++){
+                printf("%8"PRId64",", errors[level][orientation]/g);
+            }
+            printf("},\n");
+        }
+        printf("};\n");
+        {
+            int level=2;
+            int w= width  >> (s.spatial_decomposition_count-level);
+            //int h= height >> (s.spatial_decomposition_count-level);
+            int stride= width  << (s.spatial_decomposition_count-level);
+            DWTELEM *buf= buffer[0];
+            int64_t error=0;
+
+            buf+=w;
+            buf+=stride>>1;
+
+            memset(buffer[0], 0, sizeof(int)*width*height);
+            for(y=0; y<height; y++){
+                for(x=0; x<width; x++){
+                    int tab[4]={0,2,3,1};
+                    buffer[0][x+width*y]= 256*256*tab[(x&1) + 2*(y&1)];
+                }
+            }
+            ff_spatial_dwt(buffer[0], s.temp_dwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count);
+            for(y=0; y<height; y++){
+                for(x=0; x<width; x++){
+                    int64_t d= buffer[0][x + y*width];
+                    error += d*d;
+                    if(FFABS(width/2-x)<9 && FFABS(height/2-y)<9) printf("%8"PRId64" ", d);
+                }
+                if(FFABS(height/2-y)<9) printf("\n");
+            }
+        }
+
+    }
+    return 0;
+}
+#endif /* TEST */
diff --git a/libavcodec/sonic.c b/libavcodec/sonic.c
new file mode 100644
index 0000000..b7caf48
--- /dev/null
+++ b/libavcodec/sonic.c
@@ -0,0 +1,1001 @@
+/*
+ * Simple free lossless/lossy audio codec
+ * Copyright (c) 2004 Alex Beregszaszi
+ *
+ * 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 "get_bits.h"
+#include "golomb.h"
+#include "internal.h"
+
+/**
+ * @file
+ * Simple free lossless/lossy audio codec
+ * Based on Paul Francis Harrison's Bonk (http://www.logarithmic.net/pfh/bonk)
+ * Written and designed by Alex Beregszaszi
+ *
+ * TODO:
+ *  - CABAC put/get_symbol
+ *  - independent quantizer for channels
+ *  - >2 channels support
+ *  - more decorrelation types
+ *  - more tap_quant tests
+ *  - selectable intlist writers/readers (bonk-style, golomb, cabac)
+ */
+
+#define MAX_CHANNELS 2
+
+#define MID_SIDE 0
+#define LEFT_SIDE 1
+#define RIGHT_SIDE 2
+
+typedef struct SonicContext {
+    AVFrame frame;
+    int lossless, decorrelation;
+
+    int num_taps, downsampling;
+    double quantization;
+
+    int channels, samplerate, block_align, frame_size;
+
+    int *tap_quant;
+    int *int_samples;
+    int *coded_samples[MAX_CHANNELS];
+
+    // for encoding
+    int *tail;
+    int tail_size;
+    int *window;
+    int window_size;
+
+    // for decoding
+    int *predictor_k;
+    int *predictor_state[MAX_CHANNELS];
+} SonicContext;
+
+#define LATTICE_SHIFT   10
+#define SAMPLE_SHIFT    4
+#define LATTICE_FACTOR  (1 << LATTICE_SHIFT)
+#define SAMPLE_FACTOR   (1 << SAMPLE_SHIFT)
+
+#define BASE_QUANT      0.6
+#define RATE_VARIATION  3.0
+
+static inline int divide(int a, int b)
+{
+    if (a < 0)
+        return -( (-a + b/2)/b );
+    else
+        return (a + b/2)/b;
+}
+
+static inline int shift(int a,int b)
+{
+    return (a+(1<<(b-1))) >> b;
+}
+
+static inline int shift_down(int a,int b)
+{
+    return (a>>b)+((a<0)?1:0);
+}
+
+#if 1
+static inline int intlist_write(PutBitContext *pb, int *buf, int entries, int base_2_part)
+{
+    int i;
+
+    for (i = 0; i < entries; i++)
+        set_se_golomb(pb, buf[i]);
+
+    return 1;
+}
+
+static inline int intlist_read(GetBitContext *gb, int *buf, int entries, int base_2_part)
+{
+    int i;
+
+    for (i = 0; i < entries; i++)
+        buf[i] = get_se_golomb(gb);
+
+    return 1;
+}
+
+#else
+
+#define ADAPT_LEVEL 8
+
+static int bits_to_store(uint64_t x)
+{
+    int res = 0;
+
+    while(x)
+    {
+        res++;
+        x >>= 1;
+    }
+    return res;
+}
+
+static void write_uint_max(PutBitContext *pb, unsigned int value, unsigned int max)
+{
+    int i, bits;
+
+    if (!max)
+        return;
+
+    bits = bits_to_store(max);
+
+    for (i = 0; i < bits-1; i++)
+        put_bits(pb, 1, value & (1 << i));
+
+    if ( (value | (1 << (bits-1))) <= max)
+        put_bits(pb, 1, value & (1 << (bits-1)));
+}
+
+static unsigned int read_uint_max(GetBitContext *gb, int max)
+{
+    int i, bits, value = 0;
+
+    if (!max)
+        return 0;
+
+    bits = bits_to_store(max);
+
+    for (i = 0; i < bits-1; i++)
+        if (get_bits1(gb))
+            value += 1 << i;
+
+    if ( (value | (1<<(bits-1))) <= max)
+        if (get_bits1(gb))
+            value += 1 << (bits-1);
+
+    return value;
+}
+
+static int intlist_write(PutBitContext *pb, int *buf, int entries, int base_2_part)
+{
+    int i, j, x = 0, low_bits = 0, max = 0;
+    int step = 256, pos = 0, dominant = 0, any = 0;
+    int *copy, *bits;
+
+    copy = av_mallocz(4* entries);
+    if (!copy)
+        return -1;
+
+    if (base_2_part)
+    {
+        int energy = 0;
+
+        for (i = 0; i < entries; i++)
+            energy += abs(buf[i]);
+
+        low_bits = bits_to_store(energy / (entries * 2));
+        if (low_bits > 15)
+            low_bits = 15;
+
+        put_bits(pb, 4, low_bits);
+    }
+
+    for (i = 0; i < entries; i++)
+    {
+        put_bits(pb, low_bits, abs(buf[i]));
+        copy[i] = abs(buf[i]) >> low_bits;
+        if (copy[i] > max)
+            max = abs(copy[i]);
+    }
+
+    bits = av_mallocz(4* entries*max);
+    if (!bits)
+    {
+//        av_free(copy);
+        return -1;
+    }
+
+    for (i = 0; i <= max; i++)
+    {
+        for (j = 0; j < entries; j++)
+            if (copy[j] >= i)
+                bits[x++] = copy[j] > i;
+    }
+
+    // store bitstream
+    while (pos < x)
+    {
+        int steplet = step >> 8;
+
+        if (pos + steplet > x)
+            steplet = x - pos;
+
+        for (i = 0; i < steplet; i++)
+            if (bits[i+pos] != dominant)
+                any = 1;
+
+        put_bits(pb, 1, any);
+
+        if (!any)
+        {
+            pos += steplet;
+            step += step / ADAPT_LEVEL;
+        }
+        else
+        {
+            int interloper = 0;
+
+            while (((pos + interloper) < x) && (bits[pos + interloper] == dominant))
+                interloper++;
+
+            // note change
+            write_uint_max(pb, interloper, (step >> 8) - 1);
+
+            pos += interloper + 1;
+            step -= step / ADAPT_LEVEL;
+        }
+
+        if (step < 256)
+        {
+            step = 65536 / step;
+            dominant = !dominant;
+        }
+    }
+
+    // store signs
+    for (i = 0; i < entries; i++)
+        if (buf[i])
+            put_bits(pb, 1, buf[i] < 0);
+
+//    av_free(bits);
+//    av_free(copy);
+
+    return 0;
+}
+
+static int intlist_read(GetBitContext *gb, int *buf, int entries, int base_2_part)
+{
+    int i, low_bits = 0, x = 0;
+    int n_zeros = 0, step = 256, dominant = 0;
+    int pos = 0, level = 0;
+    int *bits = av_mallocz(4* entries);
+
+    if (!bits)
+        return -1;
+
+    if (base_2_part)
+    {
+        low_bits = get_bits(gb, 4);
+
+        if (low_bits)
+            for (i = 0; i < entries; i++)
+                buf[i] = get_bits(gb, low_bits);
+    }
+
+//    av_log(NULL, AV_LOG_INFO, "entries: %d, low bits: %d\n", entries, low_bits);
+
+    while (n_zeros < entries)
+    {
+        int steplet = step >> 8;
+
+        if (!get_bits1(gb))
+        {
+            for (i = 0; i < steplet; i++)
+                bits[x++] = dominant;
+
+            if (!dominant)
+                n_zeros += steplet;
+
+            step += step / ADAPT_LEVEL;
+        }
+        else
+        {
+            int actual_run = read_uint_max(gb, steplet-1);
+
+//            av_log(NULL, AV_LOG_INFO, "actual run: %d\n", actual_run);
+
+            for (i = 0; i < actual_run; i++)
+                bits[x++] = dominant;
+
+            bits[x++] = !dominant;
+
+            if (!dominant)
+                n_zeros += actual_run;
+            else
+                n_zeros++;
+
+            step -= step / ADAPT_LEVEL;
+        }
+
+        if (step < 256)
+        {
+            step = 65536 / step;
+            dominant = !dominant;
+        }
+    }
+
+    // reconstruct unsigned values
+    n_zeros = 0;
+    for (i = 0; n_zeros < entries; i++)
+    {
+        while(1)
+        {
+            if (pos >= entries)
+            {
+                pos = 0;
+                level += 1 << low_bits;
+            }
+
+            if (buf[pos] >= level)
+                break;
+
+            pos++;
+        }
+
+        if (bits[i])
+            buf[pos] += 1 << low_bits;
+        else
+            n_zeros++;
+
+        pos++;
+    }
+//    av_free(bits);
+
+    // read signs
+    for (i = 0; i < entries; i++)
+        if (buf[i] && get_bits1(gb))
+            buf[i] = -buf[i];
+
+//    av_log(NULL, AV_LOG_INFO, "zeros: %d pos: %d\n", n_zeros, pos);
+
+    return 0;
+}
+#endif
+
+static void predictor_init_state(int *k, int *state, int order)
+{
+    int i;
+
+    for (i = order-2; i >= 0; i--)
+    {
+        int j, p, x = state[i];
+
+        for (j = 0, p = i+1; p < order; j++,p++)
+            {
+            int tmp = x + shift_down(k[j] * state[p], LATTICE_SHIFT);
+            state[p] += shift_down(k[j]*x, LATTICE_SHIFT);
+            x = tmp;
+        }
+    }
+}
+
+static int predictor_calc_error(int *k, int *state, int order, int error)
+{
+    int i, x = error - shift_down(k[order-1] * state[order-1], LATTICE_SHIFT);
+
+#if 1
+    int *k_ptr = &(k[order-2]),
+        *state_ptr = &(state[order-2]);
+    for (i = order-2; i >= 0; i--, k_ptr--, state_ptr--)
+    {
+        int k_value = *k_ptr, state_value = *state_ptr;
+        x -= shift_down(k_value * state_value, LATTICE_SHIFT);
+        state_ptr[1] = state_value + shift_down(k_value * x, LATTICE_SHIFT);
+    }
+#else
+    for (i = order-2; i >= 0; i--)
+    {
+        x -= shift_down(k[i] * state[i], LATTICE_SHIFT);
+        state[i+1] = state[i] + shift_down(k[i] * x, LATTICE_SHIFT);
+    }
+#endif
+
+    // don't drift too far, to avoid overflows
+    if (x >  (SAMPLE_FACTOR<<16)) x =  (SAMPLE_FACTOR<<16);
+    if (x < -(SAMPLE_FACTOR<<16)) x = -(SAMPLE_FACTOR<<16);
+
+    state[0] = x;
+
+    return x;
+}
+
+#if CONFIG_SONIC_ENCODER || CONFIG_SONIC_LS_ENCODER
+// Heavily modified Levinson-Durbin algorithm which
+// copes better with quantization, and calculates the
+// actual whitened result as it goes.
+
+static void modified_levinson_durbin(int *window, int window_entries,
+        int *out, int out_entries, int channels, int *tap_quant)
+{
+    int i;
+    int *state = av_mallocz(4* window_entries);
+
+    memcpy(state, window, 4* window_entries);
+
+    for (i = 0; i < out_entries; i++)
+    {
+        int step = (i+1)*channels, k, j;
+        double xx = 0.0, xy = 0.0;
+#if 1
+        int *x_ptr = &(window[step]), *state_ptr = &(state[0]);
+        j = window_entries - step;
+        for (;j>=0;j--,x_ptr++,state_ptr++)
+        {
+            double x_value = *x_ptr, state_value = *state_ptr;
+            xx += state_value*state_value;
+            xy += x_value*state_value;
+        }
+#else
+        for (j = 0; j <= (window_entries - step); j++);
+        {
+            double stepval = window[step+j], stateval = window[j];
+//            xx += (double)window[j]*(double)window[j];
+//            xy += (double)window[step+j]*(double)window[j];
+            xx += stateval*stateval;
+            xy += stepval*stateval;
+        }
+#endif
+        if (xx == 0.0)
+            k = 0;
+        else
+            k = (int)(floor(-xy/xx * (double)LATTICE_FACTOR / (double)(tap_quant[i]) + 0.5));
+
+        if (k > (LATTICE_FACTOR/tap_quant[i]))
+            k = LATTICE_FACTOR/tap_quant[i];
+        if (-k > (LATTICE_FACTOR/tap_quant[i]))
+            k = -(LATTICE_FACTOR/tap_quant[i]);
+
+        out[i] = k;
+        k *= tap_quant[i];
+
+#if 1
+        x_ptr = &(window[step]);
+        state_ptr = &(state[0]);
+        j = window_entries - step;
+        for (;j>=0;j--,x_ptr++,state_ptr++)
+        {
+            int x_value = *x_ptr, state_value = *state_ptr;
+            *x_ptr = x_value + shift_down(k*state_value,LATTICE_SHIFT);
+            *state_ptr = state_value + shift_down(k*x_value, LATTICE_SHIFT);
+        }
+#else
+        for (j=0; j <= (window_entries - step); j++)
+        {
+            int stepval = window[step+j], stateval=state[j];
+            window[step+j] += shift_down(k * stateval, LATTICE_SHIFT);
+            state[j] += shift_down(k * stepval, LATTICE_SHIFT);
+        }
+#endif
+    }
+
+    av_free(state);
+}
+
+static inline int code_samplerate(int samplerate)
+{
+    switch (samplerate)
+    {
+        case 44100: return 0;
+        case 22050: return 1;
+        case 11025: return 2;
+        case 96000: return 3;
+        case 48000: return 4;
+        case 32000: return 5;
+        case 24000: return 6;
+        case 16000: return 7;
+        case 8000: return 8;
+    }
+    return -1;
+}
+
+static av_cold int sonic_encode_init(AVCodecContext *avctx)
+{
+    SonicContext *s = avctx->priv_data;
+    PutBitContext pb;
+    int i, version = 0;
+
+    if (avctx->channels > MAX_CHANNELS)
+    {
+        av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n");
+        return -1; /* only stereo or mono for now */
+    }
+
+    if (avctx->channels == 2)
+        s->decorrelation = MID_SIDE;
+
+    if (avctx->codec->id == AV_CODEC_ID_SONIC_LS)
+    {
+        s->lossless = 1;
+        s->num_taps = 32;
+        s->downsampling = 1;
+        s->quantization = 0.0;
+    }
+    else
+    {
+        s->num_taps = 128;
+        s->downsampling = 2;
+        s->quantization = 1.0;
+    }
+
+    // max tap 2048
+    if ((s->num_taps < 32) || (s->num_taps > 1024) ||
+        ((s->num_taps>>5)<<5 != s->num_taps))
+    {
+        av_log(avctx, AV_LOG_ERROR, "Invalid number of taps\n");
+        return -1;
+    }
+
+    // generate taps
+    s->tap_quant = av_mallocz(4* s->num_taps);
+    for (i = 0; i < s->num_taps; i++)
+        s->tap_quant[i] = (int)(sqrt(i+1));
+
+    s->channels = avctx->channels;
+    s->samplerate = avctx->sample_rate;
+
+    s->block_align = (int)(2048.0*s->samplerate/44100)/s->downsampling;
+    s->frame_size = s->channels*s->block_align*s->downsampling;
+
+    s->tail_size = s->num_taps*s->channels;
+    s->tail = av_mallocz(4 * s->tail_size);
+    if (!s->tail)
+        return -1;
+
+    s->predictor_k = av_mallocz(4 * s->num_taps);
+    if (!s->predictor_k)
+        return -1;
+
+    for (i = 0; i < s->channels; i++)
+    {
+        s->coded_samples[i] = av_mallocz(4* s->block_align);
+        if (!s->coded_samples[i])
+            return -1;
+    }
+
+    s->int_samples = av_mallocz(4* s->frame_size);
+
+    s->window_size = ((2*s->tail_size)+s->frame_size);
+    s->window = av_mallocz(4* s->window_size);
+    if (!s->window)
+        return -1;
+
+    avctx->extradata = av_mallocz(16);
+    if (!avctx->extradata)
+        return -1;
+    init_put_bits(&pb, avctx->extradata, 16*8);
+
+    put_bits(&pb, 2, version); // version
+    if (version == 1)
+    {
+        put_bits(&pb, 2, s->channels);
+        put_bits(&pb, 4, code_samplerate(s->samplerate));
+    }
+    put_bits(&pb, 1, s->lossless);
+    if (!s->lossless)
+        put_bits(&pb, 3, SAMPLE_SHIFT); // XXX FIXME: sample precision
+    put_bits(&pb, 2, s->decorrelation);
+    put_bits(&pb, 2, s->downsampling);
+    put_bits(&pb, 5, (s->num_taps >> 5)-1); // 32..1024
+    put_bits(&pb, 1, 0); // XXX FIXME: no custom tap quant table
+
+    flush_put_bits(&pb);
+    avctx->extradata_size = put_bits_count(&pb)/8;
+
+    av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n",
+        version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling);
+
+    avctx->coded_frame = avcodec_alloc_frame();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+    avctx->coded_frame->key_frame = 1;
+    avctx->frame_size = s->block_align*s->downsampling;
+
+    return 0;
+}
+
+static av_cold int sonic_encode_close(AVCodecContext *avctx)
+{
+    SonicContext *s = avctx->priv_data;
+    int i;
+
+    av_freep(&avctx->coded_frame);
+
+    for (i = 0; i < s->channels; i++)
+        av_free(s->coded_samples[i]);
+
+    av_free(s->predictor_k);
+    av_free(s->tail);
+    av_free(s->tap_quant);
+    av_free(s->window);
+    av_free(s->int_samples);
+
+    return 0;
+}
+
+static int sonic_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
+                              const AVFrame *frame, int *got_packet_ptr)
+{
+    SonicContext *s = avctx->priv_data;
+    PutBitContext pb;
+    int i, j, ch, quant = 0, x = 0;
+    int ret;
+    const short *samples = (const int16_t*)frame->data[0];
+
+    if ((ret = ff_alloc_packet2(avctx, avpkt, s->frame_size * 5 + 1000)))
+        return ret;
+
+    init_put_bits(&pb, avpkt->data, avpkt->size);
+
+    // short -> internal
+    for (i = 0; i < s->frame_size; i++)
+        s->int_samples[i] = samples[i];
+
+    if (!s->lossless)
+        for (i = 0; i < s->frame_size; i++)
+            s->int_samples[i] = s->int_samples[i] << SAMPLE_SHIFT;
+
+    switch(s->decorrelation)
+    {
+        case MID_SIDE:
+            for (i = 0; i < s->frame_size; i += s->channels)
+            {
+                s->int_samples[i] += s->int_samples[i+1];
+                s->int_samples[i+1] -= shift(s->int_samples[i], 1);
+            }
+            break;
+        case LEFT_SIDE:
+            for (i = 0; i < s->frame_size; i += s->channels)
+                s->int_samples[i+1] -= s->int_samples[i];
+            break;
+        case RIGHT_SIDE:
+            for (i = 0; i < s->frame_size; i += s->channels)
+                s->int_samples[i] -= s->int_samples[i+1];
+            break;
+    }
+
+    memset(s->window, 0, 4* s->window_size);
+
+    for (i = 0; i < s->tail_size; i++)
+        s->window[x++] = s->tail[i];
+
+    for (i = 0; i < s->frame_size; i++)
+        s->window[x++] = s->int_samples[i];
+
+    for (i = 0; i < s->tail_size; i++)
+        s->window[x++] = 0;
+
+    for (i = 0; i < s->tail_size; i++)
+        s->tail[i] = s->int_samples[s->frame_size - s->tail_size + i];
+
+    // generate taps
+    modified_levinson_durbin(s->window, s->window_size,
+                s->predictor_k, s->num_taps, s->channels, s->tap_quant);
+    if (intlist_write(&pb, s->predictor_k, s->num_taps, 0) < 0)
+        return -1;
+
+    for (ch = 0; ch < s->channels; ch++)
+    {
+        x = s->tail_size+ch;
+        for (i = 0; i < s->block_align; i++)
+        {
+            int sum = 0;
+            for (j = 0; j < s->downsampling; j++, x += s->channels)
+                sum += s->window[x];
+            s->coded_samples[ch][i] = sum;
+        }
+    }
+
+    // simple rate control code
+    if (!s->lossless)
+    {
+        double energy1 = 0.0, energy2 = 0.0;
+        for (ch = 0; ch < s->channels; ch++)
+        {
+            for (i = 0; i < s->block_align; i++)
+            {
+                double sample = s->coded_samples[ch][i];
+                energy2 += sample*sample;
+                energy1 += fabs(sample);
+            }
+        }
+
+        energy2 = sqrt(energy2/(s->channels*s->block_align));
+        energy1 = sqrt(2.0)*energy1/(s->channels*s->block_align);
+
+        // increase bitrate when samples are like a gaussian distribution
+        // reduce bitrate when samples are like a two-tailed exponential distribution
+
+        if (energy2 > energy1)
+            energy2 += (energy2-energy1)*RATE_VARIATION;
+
+        quant = (int)(BASE_QUANT*s->quantization*energy2/SAMPLE_FACTOR);
+//        av_log(avctx, AV_LOG_DEBUG, "quant: %d energy: %f / %f\n", quant, energy1, energy2);
+
+        if (quant < 1)
+            quant = 1;
+        if (quant > 65534)
+            quant = 65534;
+
+        set_ue_golomb(&pb, quant);
+
+        quant *= SAMPLE_FACTOR;
+    }
+
+    // write out coded samples
+    for (ch = 0; ch < s->channels; ch++)
+    {
+        if (!s->lossless)
+            for (i = 0; i < s->block_align; i++)
+                s->coded_samples[ch][i] = divide(s->coded_samples[ch][i], quant);
+
+        if (intlist_write(&pb, s->coded_samples[ch], s->block_align, 1) < 0)
+            return -1;
+    }
+
+//    av_log(avctx, AV_LOG_DEBUG, "used bytes: %d\n", (put_bits_count(&pb)+7)/8);
+
+    flush_put_bits(&pb);
+    avpkt->size = (put_bits_count(&pb)+7)/8;
+    *got_packet_ptr = 1;
+    return 0;
+}
+#endif /* CONFIG_SONIC_ENCODER || CONFIG_SONIC_LS_ENCODER */
+
+#if CONFIG_SONIC_DECODER
+static const int samplerate_table[] =
+    { 44100, 22050, 11025, 96000, 48000, 32000, 24000, 16000, 8000 };
+
+static av_cold int sonic_decode_init(AVCodecContext *avctx)
+{
+    SonicContext *s = avctx->priv_data;
+    GetBitContext gb;
+    int i, version;
+
+    s->channels = avctx->channels;
+    s->samplerate = avctx->sample_rate;
+
+    avcodec_get_frame_defaults(&s->frame);
+    avctx->coded_frame = &s->frame;
+
+    if (!avctx->extradata)
+    {
+        av_log(avctx, AV_LOG_ERROR, "No mandatory headers present\n");
+        return -1;
+    }
+
+    init_get_bits(&gb, avctx->extradata, avctx->extradata_size);
+
+    version = get_bits(&gb, 2);
+    if (version > 1)
+    {
+        av_log(avctx, AV_LOG_ERROR, "Unsupported Sonic version, please report\n");
+        return -1;
+    }
+
+    if (version == 1)
+    {
+        s->channels = get_bits(&gb, 2);
+        s->samplerate = samplerate_table[get_bits(&gb, 4)];
+        av_log(avctx, AV_LOG_INFO, "Sonicv2 chans: %d samprate: %d\n",
+            s->channels, s->samplerate);
+    }
+
+    if (s->channels > MAX_CHANNELS)
+    {
+        av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n");
+        return -1;
+    }
+
+    s->lossless = get_bits1(&gb);
+    if (!s->lossless)
+        skip_bits(&gb, 3); // XXX FIXME
+    s->decorrelation = get_bits(&gb, 2);
+
+    s->downsampling = get_bits(&gb, 2);
+    if (!s->downsampling) {
+        av_log(avctx, AV_LOG_ERROR, "invalid downsampling value\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    s->num_taps = (get_bits(&gb, 5)+1)<<5;
+    if (get_bits1(&gb)) // XXX FIXME
+        av_log(avctx, AV_LOG_INFO, "Custom quant table\n");
+
+    s->block_align = (int)(2048.0*s->samplerate/44100)/s->downsampling;
+    s->frame_size = s->channels*s->block_align*s->downsampling;
+//    avctx->frame_size = s->block_align;
+
+    av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n",
+        version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling);
+
+    // generate taps
+    s->tap_quant = av_mallocz(4* s->num_taps);
+    for (i = 0; i < s->num_taps; i++)
+        s->tap_quant[i] = (int)(sqrt(i+1));
+
+    s->predictor_k = av_mallocz(4* s->num_taps);
+
+    for (i = 0; i < s->channels; i++)
+    {
+        s->predictor_state[i] = av_mallocz(4* s->num_taps);
+        if (!s->predictor_state[i])
+            return -1;
+    }
+
+    for (i = 0; i < s->channels; i++)
+    {
+        s->coded_samples[i] = av_mallocz(4* s->block_align);
+        if (!s->coded_samples[i])
+            return -1;
+    }
+    s->int_samples = av_mallocz(4* s->frame_size);
+
+    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+    return 0;
+}
+
+static av_cold int sonic_decode_close(AVCodecContext *avctx)
+{
+    SonicContext *s = avctx->priv_data;
+    int i;
+
+    av_free(s->int_samples);
+    av_free(s->tap_quant);
+    av_free(s->predictor_k);
+
+    for (i = 0; i < s->channels; i++)
+    {
+        av_free(s->predictor_state[i]);
+        av_free(s->coded_samples[i]);
+    }
+
+    return 0;
+}
+
+static int sonic_decode_frame(AVCodecContext *avctx,
+                            void *data, int *got_frame_ptr,
+                            AVPacket *avpkt)
+{
+    const uint8_t *buf = avpkt->data;
+    int buf_size = avpkt->size;
+    SonicContext *s = avctx->priv_data;
+    GetBitContext gb;
+    int i, quant, ch, j, ret;
+    int16_t *samples;
+
+    if (buf_size == 0) return 0;
+
+    s->frame.nb_samples = s->frame_size;
+    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
+    }
+    samples = (int16_t *)s->frame.data[0];
+
+//    av_log(NULL, AV_LOG_INFO, "buf_size: %d\n", buf_size);
+
+    init_get_bits(&gb, buf, buf_size*8);
+
+    intlist_read(&gb, s->predictor_k, s->num_taps, 0);
+
+    // dequantize
+    for (i = 0; i < s->num_taps; i++)
+        s->predictor_k[i] *= s->tap_quant[i];
+
+    if (s->lossless)
+        quant = 1;
+    else
+        quant = get_ue_golomb(&gb) * SAMPLE_FACTOR;
+
+//    av_log(NULL, AV_LOG_INFO, "quant: %d\n", quant);
+
+    for (ch = 0; ch < s->channels; ch++)
+    {
+        int x = ch;
+
+        predictor_init_state(s->predictor_k, s->predictor_state[ch], s->num_taps);
+
+        intlist_read(&gb, s->coded_samples[ch], s->block_align, 1);
+
+        for (i = 0; i < s->block_align; i++)
+        {
+            for (j = 0; j < s->downsampling - 1; j++)
+            {
+                s->int_samples[x] = predictor_calc_error(s->predictor_k, s->predictor_state[ch], s->num_taps, 0);
+                x += s->channels;
+            }
+
+            s->int_samples[x] = predictor_calc_error(s->predictor_k, s->predictor_state[ch], s->num_taps, s->coded_samples[ch][i] * quant);
+            x += s->channels;
+        }
+
+        for (i = 0; i < s->num_taps; i++)
+            s->predictor_state[ch][i] = s->int_samples[s->frame_size - s->channels + ch - i*s->channels];
+    }
+
+    switch(s->decorrelation)
+    {
+        case MID_SIDE:
+            for (i = 0; i < s->frame_size; i += s->channels)
+            {
+                s->int_samples[i+1] += shift(s->int_samples[i], 1);
+                s->int_samples[i] -= s->int_samples[i+1];
+            }
+            break;
+        case LEFT_SIDE:
+            for (i = 0; i < s->frame_size; i += s->channels)
+                s->int_samples[i+1] += s->int_samples[i];
+            break;
+        case RIGHT_SIDE:
+            for (i = 0; i < s->frame_size; i += s->channels)
+                s->int_samples[i] += s->int_samples[i+1];
+            break;
+    }
+
+    if (!s->lossless)
+        for (i = 0; i < s->frame_size; i++)
+            s->int_samples[i] = shift(s->int_samples[i], SAMPLE_SHIFT);
+
+    // internal -> short
+    for (i = 0; i < s->frame_size; i++)
+        samples[i] = av_clip_int16(s->int_samples[i]);
+
+    align_get_bits(&gb);
+
+    *got_frame_ptr = 1;
+    *(AVFrame*)data = s->frame;
+
+    return (get_bits_count(&gb)+7)/8;
+}
+
+AVCodec ff_sonic_decoder = {
+    .name           = "sonic",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_SONIC,
+    .priv_data_size = sizeof(SonicContext),
+    .init           = sonic_decode_init,
+    .close          = sonic_decode_close,
+    .decode         = sonic_decode_frame,
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_EXPERIMENTAL,
+    .long_name = NULL_IF_CONFIG_SMALL("Sonic"),
+};
+#endif /* CONFIG_SONIC_DECODER */
+
+#if CONFIG_SONIC_ENCODER
+AVCodec ff_sonic_encoder = {
+    .name           = "sonic",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_SONIC,
+    .priv_data_size = sizeof(SonicContext),
+    .init           = sonic_encode_init,
+    .encode2        = sonic_encode_frame,
+    .capabilities   = CODEC_CAP_EXPERIMENTAL,
+    .close          = sonic_encode_close,
+    .long_name = NULL_IF_CONFIG_SMALL("Sonic"),
+};
+#endif
+
+#if CONFIG_SONIC_LS_ENCODER
+AVCodec ff_sonic_ls_encoder = {
+    .name           = "sonicls",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_SONIC_LS,
+    .priv_data_size = sizeof(SonicContext),
+    .init           = sonic_encode_init,
+    .encode2        = sonic_encode_frame,
+    .capabilities   = CODEC_CAP_EXPERIMENTAL,
+    .close          = sonic_encode_close,
+    .long_name = NULL_IF_CONFIG_SMALL("Sonic lossless"),
+};
+#endif
diff --git a/libavcodec/sp5x.h b/libavcodec/sp5x.h
index 1577302..004fcbb 100644
--- a/libavcodec/sp5x.h
+++ b/libavcodec/sp5x.h
@@ -2,20 +2,20 @@
  * Sunplus JPEG tables
  * Copyright (c) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sp5xdec.c b/libavcodec/sp5xdec.c
index 29b0059..7216088 100644
--- a/libavcodec/sp5xdec.c
+++ b/libavcodec/sp5xdec.c
@@ -2,20 +2,20 @@
  * Sunplus JPEG decoder (SP5X)
  * Copyright (c) 2003 Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -72,7 +72,7 @@
         for (i = 2; i < buf_size-2 && j < buf_size+1024-2; i++)
             recoded[j++] = buf[i];
     else
-    for (i = 14; i < buf_size && j < buf_size+1024-2; i++)
+    for (i = 14; i < buf_size && j < buf_size+1024-3; i++)
     {
         recoded[j++] = buf[i];
         if (buf[i] == 0xff)
@@ -90,9 +90,10 @@
 
     av_free(recoded);
 
-    return i;
+    return i < 0 ? i : avpkt->size;
 }
 
+#if CONFIG_SP5X_DECODER
 AVCodec ff_sp5x_decoder = {
     .name           = "sp5x",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -102,9 +103,11 @@
     .close          = ff_mjpeg_decode_end,
     .decode         = sp5x_decode_frame,
     .capabilities   = CODEC_CAP_DR1,
+    .max_lowres     = 3,
     .long_name      = NULL_IF_CONFIG_SMALL("Sunplus JPEG (SP5X)"),
 };
-
+#endif
+#if CONFIG_AMV_DECODER
 AVCodec ff_amv_decoder = {
     .name           = "amv",
     .type           = AVMEDIA_TYPE_VIDEO,
@@ -115,3 +118,4 @@
     .decode         = sp5x_decode_frame,
     .long_name      = NULL_IF_CONFIG_SMALL("AMV Video"),
 };
+#endif
diff --git a/libavcodec/sparc/dsputil_vis.c b/libavcodec/sparc/dsputil_vis.c
index 5bac83e..5b5b96e 100644
--- a/libavcodec/sparc/dsputil_vis.c
+++ b/libavcodec/sparc/dsputil_vis.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2003 David S. Miller <davem@redhat.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sparc/dsputil_vis.h b/libavcodec/sparc/dsputil_vis.h
index 4be86e2..e1cbcb4 100644
--- a/libavcodec/sparc/dsputil_vis.h
+++ b/libavcodec/sparc/dsputil_vis.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sparc/simple_idct_vis.c b/libavcodec/sparc/simple_idct_vis.c
index 43a898a..45ca010 100644
--- a/libavcodec/sparc/simple_idct_vis.c
+++ b/libavcodec/sparc/simple_idct_vis.c
@@ -5,20 +5,20 @@
  * I did consult the following fine web page about dct
  * http://www.geocities.com/ssavekar/dct.htm
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/sparc/vis.h b/libavcodec/sparc/vis.h
index 505c735..adee91b 100644
--- a/libavcodec/sparc/vis.h
+++ b/libavcodec/sparc/vis.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2003 David S. Miller <davem@redhat.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/srtdec.c b/libavcodec/srtdec.c
index bbc8061..5824091 100644
--- a/libavcodec/srtdec.c
+++ b/libavcodec/srtdec.c
@@ -2,20 +2,20 @@
  * SubRip subtitle decoder
  * Copyright (c) 2010  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -60,10 +60,11 @@
 
     if (x1 >= 0 && y1 >= 0) {
         if (x2 >= 0 && y2 >= 0 && (x2 != x1 || y2 != y1))
-            out += snprintf(out, out_end-out,
+            snprintf(out, out_end-out,
                             "{\\an1}{\\move(%d,%d,%d,%d)}", x1, y1, x2, y2);
         else
-            out += snprintf(out, out_end-out, "{\\an1}{\\pos(%d,%d)}", x1, y1);
+            snprintf(out, out_end-out, "{\\an1}{\\pos(%d,%d)}", x1, y1);
+        out += strlen(out);
     }
 
     for (; out < out_end && !end && *in; in++) {
@@ -77,7 +78,8 @@
             }
             while (out[-1] == ' ')
                 out--;
-            out += snprintf(out, out_end-out, "\\N");
+            snprintf(out, out_end-out, "\\N");
+            if(out<out_end) out += strlen(out);
             line_start = 1;
             break;
         case ' ':
@@ -110,8 +112,9 @@
                                 if (stack[sptr-1].param[i][0])
                                     for (j=sptr-2; j>=0; j--)
                                         if (stack[j].param[i][0]) {
-                                            out += snprintf(out, out_end-out,
+                                            snprintf(out, out_end-out,
                                                             "%s", stack[j].param[i]);
+                                            if(out<out_end) out += strlen(out);
                                             break;
                                         }
                         } else {
@@ -145,13 +148,16 @@
                                     param++;
                             }
                             for (i=0; i<PARAM_NUMBER; i++)
-                                if (stack[sptr].param[i][0])
-                                    out += snprintf(out, out_end-out,
+                                if (stack[sptr].param[i][0]) {
+                                    snprintf(out, out_end-out,
                                                     "%s", stack[sptr].param[i]);
+                                    if(out<out_end) out += strlen(out);
+                                }
                         }
                     } else if (!buffer[1] && strspn(buffer, "bisu") == 1) {
-                        out += snprintf(out, out_end-out,
+                        snprintf(out, out_end-out,
                                         "{\\%c%d}", buffer[0], !tag_close);
+                        if(out<out_end) out += strlen(out);
                     } else {
                         unknown = 1;
                         snprintf(tmp, sizeof(tmp), "</%s>", buffer);
@@ -180,7 +186,7 @@
         out -= 2;
     while (out[-1] == ' ')
         out--;
-    out += snprintf(out, out_end-out, "\r\n");
+    snprintf(out, out_end-out, "\r\n");
     return in;
 }
 
@@ -217,26 +223,47 @@
     if (avpkt->size <= 0)
         return avpkt->size;
 
-    ff_ass_init(sub);
-
     while (ptr < end && *ptr) {
-        ptr = read_ts(ptr, &ts_start, &ts_end, &x1, &y1, &x2, &y2);
-        if (!ptr)
-            break;
+        if (avctx->codec->id == CODEC_ID_SRT) {
+            ptr = read_ts(ptr, &ts_start, &ts_end, &x1, &y1, &x2, &y2);
+            if (!ptr)
+                break;
+        } else {
+            // Do final divide-by-10 outside rescale to force rounding down.
+            ts_start = av_rescale_q(avpkt->pts,
+                                    avctx->time_base,
+                                    (AVRational){1,100});
+            ts_end   = av_rescale_q(avpkt->pts + avpkt->duration,
+                                    avctx->time_base,
+                                    (AVRational){1,100});
+        }
         ptr = srt_to_ass(avctx, buffer, buffer+sizeof(buffer), ptr,
                          x1, y1, x2, y2);
-        ff_ass_add_rect(sub, buffer, ts_start, ts_end, 0);
+        ff_ass_add_rect(sub, buffer, ts_start, ts_end-ts_start, 0);
     }
 
     *got_sub_ptr = sub->num_rects > 0;
     return avpkt->size;
 }
 
+#if CONFIG_SRT_DECODER
 AVCodec ff_srt_decoder = {
     .name         = "srt",
-    .long_name    = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
+    .long_name    = NULL_IF_CONFIG_SMALL("SubRip subtitle with embedded timing"),
     .type         = AVMEDIA_TYPE_SUBTITLE,
     .id           = AV_CODEC_ID_SRT,
     .init         = ff_ass_subtitle_header_default,
     .decode       = srt_decode_frame,
 };
+#endif
+
+#if CONFIG_SUBRIP_DECODER
+AVCodec ff_subrip_decoder = {
+    .name         = "subrip",
+    .long_name    = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
+    .type         = AVMEDIA_TYPE_SUBTITLE,
+    .id           = AV_CODEC_ID_SUBRIP,
+    .init         = ff_ass_subtitle_header_default,
+    .decode       = srt_decode_frame,
+};
+#endif
diff --git a/libavcodec/srtenc.c b/libavcodec/srtenc.c
new file mode 100644
index 0000000..473c88f
--- /dev/null
+++ b/libavcodec/srtenc.c
@@ -0,0 +1,317 @@
+/*
+ * SubRip subtitle encoder
+ * Copyright (c) 2010  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
+ */
+
+#include <stdarg.h>
+#include "avcodec.h"
+#include "libavutil/avstring.h"
+#include "ass_split.h"
+#include "ass.h"
+
+
+#define SRT_STACK_SIZE 64
+
+typedef struct {
+    AVCodecContext *avctx;
+    ASSSplitContext *ass_ctx;
+    char buffer[2048];
+    char *ptr;
+    char *end;
+    char *dialog_start;
+    int count;
+    char stack[SRT_STACK_SIZE];
+    int stack_ptr;
+    int alignment_applied;
+} SRTContext;
+
+
+#ifdef __GNUC__
+__attribute__ ((__format__ (__printf__, 2, 3)))
+#endif
+static void srt_print(SRTContext *s, const char *str, ...)
+{
+    va_list vargs;
+    va_start(vargs, str);
+    s->ptr += vsnprintf(s->ptr, s->end - s->ptr, str, vargs);
+    va_end(vargs);
+}
+
+static int srt_stack_push(SRTContext *s, const char c)
+{
+    if (s->stack_ptr >= SRT_STACK_SIZE)
+        return -1;
+    s->stack[s->stack_ptr++] = c;
+    return 0;
+}
+
+static char srt_stack_pop(SRTContext *s)
+{
+    if (s->stack_ptr <= 0)
+        return 0;
+    return s->stack[--s->stack_ptr];
+}
+
+static int srt_stack_find(SRTContext *s, const char c)
+{
+    int i;
+    for (i = s->stack_ptr-1; i >= 0; i--)
+        if (s->stack[i] == c)
+            break;
+    return i;
+}
+
+static void srt_close_tag(SRTContext *s, char tag)
+{
+    srt_print(s, "</%c%s>", tag, tag == 'f' ? "ont" : "");
+}
+
+static void srt_stack_push_pop(SRTContext *s, const char c, int close)
+{
+    if (close) {
+        int i = c ? srt_stack_find(s, c) : 0;
+        if (i < 0)
+            return;
+        while (s->stack_ptr != i)
+            srt_close_tag(s, srt_stack_pop(s));
+    } else if (srt_stack_push(s, c) < 0)
+        av_log(s->avctx, AV_LOG_ERROR, "tag stack overflow\n");
+}
+
+static void srt_style_apply(SRTContext *s, const char *style)
+{
+    ASSStyle *st = ff_ass_style_get(s->ass_ctx, style);
+    if (st) {
+        int c = st->primary_color & 0xFFFFFF;
+        if (st->font_name && strcmp(st->font_name, ASS_DEFAULT_FONT) ||
+            st->font_size != ASS_DEFAULT_FONT_SIZE ||
+            c != ASS_DEFAULT_COLOR) {
+            srt_print(s, "<font");
+            if (st->font_name && strcmp(st->font_name, ASS_DEFAULT_FONT))
+                srt_print(s, " face=\"%s\"", st->font_name);
+            if (st->font_size != ASS_DEFAULT_FONT_SIZE)
+                srt_print(s, " size=\"%d\"", st->font_size);
+            if (c != ASS_DEFAULT_COLOR)
+                srt_print(s, " color=\"#%06x\"",
+                          (c & 0xFF0000) >> 16 | c & 0xFF00 | (c & 0xFF) << 16);
+            srt_print(s, ">");
+            srt_stack_push(s, 'f');
+        }
+        if (st->bold != ASS_DEFAULT_BOLD) {
+            srt_print(s, "<b>");
+            srt_stack_push(s, 'b');
+        }
+        if (st->italic != ASS_DEFAULT_ITALIC) {
+            srt_print(s, "<i>");
+            srt_stack_push(s, 'i');
+        }
+        if (st->underline != ASS_DEFAULT_UNDERLINE) {
+            srt_print(s, "<u>");
+            srt_stack_push(s, 'u');
+        }
+        if (st->alignment != ASS_DEFAULT_ALIGNMENT) {
+            srt_print(s, "{\\an%d}", st->alignment);
+            s->alignment_applied = 1;
+        }
+    }
+}
+
+
+static av_cold int srt_encode_init(AVCodecContext *avctx)
+{
+    SRTContext *s = avctx->priv_data;
+    s->avctx = avctx;
+    s->ass_ctx = ff_ass_split(avctx->subtitle_header);
+    return s->ass_ctx ? 0 : AVERROR_INVALIDDATA;
+}
+
+static void srt_text_cb(void *priv, const char *text, int len)
+{
+    SRTContext *s = priv;
+    av_strlcpy(s->ptr, text, FFMIN(s->end-s->ptr, len+1));
+    s->ptr += len;
+}
+
+static void srt_new_line_cb(void *priv, int forced)
+{
+    srt_print(priv, "\r\n");
+}
+
+static void srt_style_cb(void *priv, char style, int close)
+{
+    srt_stack_push_pop(priv, style, close);
+    if (!close)
+        srt_print(priv, "<%c>", style);
+}
+
+static void srt_color_cb(void *priv, unsigned int color, unsigned int color_id)
+{
+    if (color_id > 1)
+        return;
+    srt_stack_push_pop(priv, 'f', color == 0xFFFFFFFF);
+    if (color != 0xFFFFFFFF)
+        srt_print(priv, "<font color=\"#%06x\">",
+              (color & 0xFF0000) >> 16 | color & 0xFF00 | (color & 0xFF) << 16);
+}
+
+static void srt_font_name_cb(void *priv, const char *name)
+{
+    srt_stack_push_pop(priv, 'f', !name);
+    if (name)
+        srt_print(priv, "<font face=\"%s\">", name);
+}
+
+static void srt_font_size_cb(void *priv, int size)
+{
+    srt_stack_push_pop(priv, 'f', size < 0);
+    if (size >= 0)
+        srt_print(priv, "<font size=\"%d\">", size);
+}
+
+static void srt_alignment_cb(void *priv, int alignment)
+{
+    SRTContext *s = priv;
+    if (!s->alignment_applied && alignment >= 0) {
+        srt_print(s, "{\\an%d}", alignment);
+        s->alignment_applied = 1;
+    }
+}
+
+static void srt_cancel_overrides_cb(void *priv, const char *style)
+{
+    srt_stack_push_pop(priv, 0, 1);
+    srt_style_apply(priv, style);
+}
+
+static void srt_move_cb(void *priv, int x1, int y1, int x2, int y2,
+                        int t1, int t2)
+{
+    SRTContext *s = priv;
+    char buffer[32];
+    int len = snprintf(buffer, sizeof(buffer),
+                       "  X1:%03u X2:%03u Y1:%03u Y2:%03u", x1, x2, y1, y2);
+    if (s->end - s->ptr > len) {
+        memmove(s->dialog_start+len, s->dialog_start, s->ptr-s->dialog_start+1);
+        memcpy(s->dialog_start, buffer, len);
+        s->ptr += len;
+    }
+}
+
+static void srt_end_cb(void *priv)
+{
+    srt_stack_push_pop(priv, 0, 1);
+    srt_print(priv, "\r\n\r\n");
+}
+
+static const ASSCodesCallbacks srt_callbacks = {
+    .text             = srt_text_cb,
+    .new_line         = srt_new_line_cb,
+    .style            = srt_style_cb,
+    .color            = srt_color_cb,
+    .font_name        = srt_font_name_cb,
+    .font_size        = srt_font_size_cb,
+    .alignment        = srt_alignment_cb,
+    .cancel_overrides = srt_cancel_overrides_cb,
+    .move             = srt_move_cb,
+    .end              = srt_end_cb,
+};
+
+static int srt_encode_frame(AVCodecContext *avctx,
+                            unsigned char *buf, int bufsize, const AVSubtitle *sub)
+{
+    SRTContext *s = avctx->priv_data;
+    ASSDialog *dialog;
+    int i, len, num;
+
+    s->ptr = s->buffer;
+    s->end = s->ptr + sizeof(s->buffer);
+
+    for (i=0; i<sub->num_rects; i++) {
+
+        if (sub->rects[i]->type != SUBTITLE_ASS) {
+            av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n");
+            return AVERROR(ENOSYS);
+        }
+
+        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) {
+                int sh, sm, ss, sc = 10 * dialog->start;
+                int eh, em, es, ec = 10 * dialog->end;
+                sh = sc/3600000;  sc -= 3600000*sh;
+                sm = sc/  60000;  sc -=   60000*sm;
+                ss = sc/   1000;  sc -=    1000*ss;
+                eh = ec/3600000;  ec -= 3600000*eh;
+                em = ec/  60000;  ec -=   60000*em;
+                es = ec/   1000;  ec -=    1000*es;
+                srt_print(s,"%d\r\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\r\n",
+                          ++s->count, sh, sm, ss, sc, eh, em, es, ec);
+            }
+            s->alignment_applied = 0;
+            s->dialog_start = s->ptr - 2;
+            srt_style_apply(s, dialog->style);
+            ff_ass_split_override_codes(&srt_callbacks, s, dialog->text);
+        }
+    }
+
+    if (s->ptr == s->buffer)
+        return 0;
+
+    len = av_strlcpy(buf, s->buffer, bufsize);
+
+    if (len > bufsize-1) {
+        av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n");
+        return -1;
+    }
+
+    return len;
+}
+
+static int srt_encode_close(AVCodecContext *avctx)
+{
+    SRTContext *s = avctx->priv_data;
+    ff_ass_split_free(s->ass_ctx);
+    return 0;
+}
+
+#if CONFIG_SRT_ENCODER
+AVCodec ff_srt_encoder = {
+    .name           = "srt",
+    .long_name      = NULL_IF_CONFIG_SMALL("SubRip subtitle with embedded timing"),
+    .type           = AVMEDIA_TYPE_SUBTITLE,
+    .id             = AV_CODEC_ID_SRT,
+    .priv_data_size = sizeof(SRTContext),
+    .init           = srt_encode_init,
+    .encode_sub     = srt_encode_frame,
+    .close          = srt_encode_close,
+};
+#endif
+
+#if CONFIG_SUBRIP_ENCODER
+AVCodec ff_subrip_encoder = {
+    .name           = "subrip",
+    .long_name      = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
+    .type           = AVMEDIA_TYPE_SUBTITLE,
+    .id             = AV_CODEC_ID_SUBRIP,
+    .priv_data_size = sizeof(SRTContext),
+    .init           = srt_encode_init,
+    .encode_sub     = srt_encode_frame,
+    .close          = srt_encode_close,
+};
+#endif
diff --git a/libavcodec/subviewerdec.c b/libavcodec/subviewerdec.c
new file mode 100644
index 0000000..0e8be90
--- /dev/null
+++ b/libavcodec/subviewerdec.c
@@ -0,0 +1,78 @@
+/*
+ * 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 subtitle decoder
+ * @see https://en.wikipedia.org/wiki/SubViewer
+ */
+
+#include "avcodec.h"
+#include "ass.h"
+#include "libavutil/bprint.h"
+
+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')
+                av_bprint_chars(buf, *p, 1);
+            p++;
+        }
+    }
+
+    av_bprintf(buf, "\r\n");
+    return 0;
+}
+
+static int subviewer_decode_frame(AVCodecContext *avctx,
+                                  void *data, int *got_sub_ptr, AVPacket *avpkt)
+{
+    AVSubtitle *sub = data;
+    const char *ptr = avpkt->data;
+    AVBPrint buf;
+
+    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)
+    if (ptr && avpkt->size > 0 && !subviewer_event_to_ass(&buf, ptr))
+        ff_ass_add_rect(sub, buf.str, avpkt->pts, avpkt->duration, 0);
+    *got_sub_ptr = sub->num_rects > 0;
+    av_bprint_finalize(&buf, NULL);
+    return avpkt->size;
+}
+
+AVCodec ff_subviewer_decoder = {
+    .name           = "subviewer",
+    .long_name      = NULL_IF_CONFIG_SMALL("SubViewer subtitle"),
+    .type           = AVMEDIA_TYPE_SUBTITLE,
+    .id             = AV_CODEC_ID_SUBVIEWER,
+    .decode         = subviewer_decode_frame,
+    .init           = ff_ass_subtitle_header_default,
+};
diff --git a/libavcodec/sunrast.c b/libavcodec/sunrast.c
index a10f449..f20e682 100644
--- a/libavcodec/sunrast.c
+++ b/libavcodec/sunrast.c
@@ -2,20 +2,20 @@
  * Sun Rasterfile (.sun/.ras/im{1,8,24}/.sunras) image decoder
  * Copyright (c) 2007, 2008 Ivo van Poorten
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -46,7 +46,7 @@
     AVFrame *picture         = data;
     AVFrame * const p        = &s->picture;
     unsigned int w, h, depth, type, maptype, maplength, stride, x, y, len, alen;
-    uint8_t *ptr;
+    uint8_t *ptr, *ptr2 = NULL;
     const uint8_t *bufstart = buf;
     int ret;
 
@@ -66,7 +66,7 @@
     maplength = AV_RB32(buf + 28);
     buf      += 32;
 
-    if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF || type == RT_EXPERIMENTAL) {
+    if (type == RT_EXPERIMENTAL) {
         av_log_ask_for_sample(avctx, "unsupported (compression) type\n");
         return AVERROR_PATCHWELCOME;
     }
@@ -87,10 +87,17 @@
         return AVERROR_INVALIDDATA;
     }
 
+    if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF) {
+        av_log(avctx, AV_LOG_ERROR, "unsupported (compression) type\n");
+        return -1;
+    }
 
     switch (depth) {
         case 1:
-            avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
+            avctx->pix_fmt = maplength ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_MONOWHITE;
+            break;
+        case 4:
+            avctx->pix_fmt = maplength ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_NONE;
             break;
         case 8:
             avctx->pix_fmt = maplength ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
@@ -98,6 +105,9 @@
         case 24:
             avctx->pix_fmt = (type == RT_FORMAT_RGB) ? AV_PIX_FMT_RGB24 : AV_PIX_FMT_BGR24;
             break;
+        case 32:
+            avctx->pix_fmt = (type == RT_FORMAT_RGB) ? AV_PIX_FMT_0RGB : AV_PIX_FMT_0BGR;
+            break;
         default:
             av_log(avctx, AV_LOG_ERROR, "invalid depth\n");
             return AVERROR_INVALIDDATA;
@@ -118,7 +128,7 @@
     if (buf_end - buf < maplength)
         return AVERROR_INVALIDDATA;
 
-    if (depth != 8 && maplength) {
+    if (depth > 8 && maplength) {
         av_log(avctx, AV_LOG_WARNING, "useless colormap found or file is corrupted, trying to recover\n");
 
     } else if (maplength) {
@@ -131,13 +141,20 @@
 
         ptr = p->data[1];
         for (x = 0; x < len; x++, ptr += 4)
-            *(uint32_t *)ptr = (buf[x] << 16) + (buf[len + x] << 8) + buf[len + len + x];
+            *(uint32_t *)ptr = (0xFF<<24) + (buf[x]<<16) + (buf[len+x]<<8) + buf[len+len+x];
     }
 
     buf += maplength;
 
+    if (maplength && depth < 8) {
+        ptr = ptr2 = av_malloc((w + 15) * h);
+        if (!ptr)
+            return AVERROR(ENOMEM);
+        stride = (w + 15 >> 3) * depth;
+    } else {
     ptr    = p->data[0];
     stride = p->linesize[0];
+    }
 
     /* scanlines are aligned on 16 bit boundaries */
     len  = (depth * w + 7) >> 3;
@@ -178,6 +195,30 @@
             buf += alen;
         }
     }
+    if (avctx->pix_fmt == AV_PIX_FMT_PAL8 && depth < 8) {
+        uint8_t *ptr_free = ptr2;
+        ptr = p->data[0];
+        for (y=0; y<h; y++) {
+            for (x = 0; x < (w + 7 >> 3) * depth; x++) {
+                if (depth == 1) {
+                    ptr[8*x]   = ptr2[x] >> 7;
+                    ptr[8*x+1] = ptr2[x] >> 6 & 1;
+                    ptr[8*x+2] = ptr2[x] >> 5 & 1;
+                    ptr[8*x+3] = ptr2[x] >> 4 & 1;
+                    ptr[8*x+4] = ptr2[x] >> 3 & 1;
+                    ptr[8*x+5] = ptr2[x] >> 2 & 1;
+                    ptr[8*x+6] = ptr2[x] >> 1 & 1;
+                    ptr[8*x+7] = ptr2[x]      & 1;
+                } else {
+                    ptr[2*x]   = ptr2[x] >> 4;
+                    ptr[2*x+1] = ptr2[x] & 0xF;
+                }
+            }
+            ptr  += p->linesize[0];
+            ptr2 += (w + 15 >> 3) * depth;
+        }
+        av_freep(&ptr_free);
+    }
 
     *picture   = s->picture;
     *data_size = sizeof(AVFrame);
diff --git a/libavcodec/sunrastenc.c b/libavcodec/sunrastenc.c
index e1b5211..2c7e72f 100644
--- a/libavcodec/sunrastenc.c
+++ b/libavcodec/sunrastenc.c
@@ -56,7 +56,7 @@
 {
     SUNRASTContext *s = avctx->priv_data;
     const uint8_t *ptr;
-    int len, alen, x;
+    int len, alen, x, y;
 
     if (s->maplength) {     // palettized
         PutByteContext pb_r, pb_g;
@@ -83,33 +83,29 @@
      if (s->type == RT_BYTE_ENCODED) {
         uint8_t value, value2;
         int run;
-        const uint8_t *start = linesize < 0 ? pixels + (avctx->height - 1) * linesize
-                                            : pixels;
-        const uint8_t *end   = linesize < 0 ? pixels - linesize
-                                            : pixels + avctx->height * linesize;
 
         ptr = pixels;
 
-#define GET_VALUE ptr >= end || ptr < start ? 0 : x >= len ? ptr[len-1] : ptr[x]
+#define GET_VALUE y >= avctx->height ? 0 : x >= len ? ptr[len-1] : ptr[x]
 
-        x = 0;
+        x = 0, y = 0;
         value2 = GET_VALUE;
-        while (ptr < end && ptr >= start) {
+        while (y < avctx->height) {
             run = 1;
             value = value2;
             x++;
             if (x >= alen) {
                 x = 0;
-                ptr += linesize;
+                ptr += linesize, y++;
             }
 
             value2 = GET_VALUE;
-            while (value2 == value && run < 256 && ptr < end && ptr >= start) {
+            while (value2 == value && run < 256 && y < avctx->height) {
                 x++;
                 run++;
                 if (x >= alen) {
                     x = 0;
-                    ptr += linesize;
+                    ptr += linesize, y++;
                 }
                 value2 = GET_VALUE;
             }
@@ -128,7 +124,6 @@
         // update data length for header
         s->length = bytestream2_tell_p(&s->p) - 32 - s->maplength;
     } else {
-        int y;
         for (y = 0; y < avctx->height; y++) {
             bytestream2_put_buffer(&s->p, ptr, len);
             if (len < alen)
@@ -189,7 +184,7 @@
     SUNRASTContext *s = avctx->priv_data;
     int ret;
 
-    if ((ret = ff_alloc_packet(avpkt, s->size)) < 0)
+    if ((ret = ff_alloc_packet2(avctx, avpkt, s->size)) < 0)
         return ret;
 
     bytestream2_init_writer(&s->p, avpkt->data, avpkt->size);
diff --git a/libavcodec/svq1.c b/libavcodec/svq1.c
index e20fa43..0c19a6d 100644
--- a/libavcodec/svq1.c
+++ b/libavcodec/svq1.c
@@ -8,20 +8,20 @@
  *
  * SVQ1 Encoder (c) 2004 Mike Melanson <melanson@pcisys.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/svq1.h b/libavcodec/svq1.h
index b2055fa..9b132e2 100644
--- a/libavcodec/svq1.h
+++ b/libavcodec/svq1.h
@@ -8,20 +8,20 @@
  *
  * SVQ1 Encoder (c) 2004 Mike Melanson <melanson@pcisys.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/svq13.c b/libavcodec/svq13.c
index e0d2154..b821a44 100644
--- a/libavcodec/svq13.c
+++ b/libavcodec/svq13.c
@@ -1,20 +1,20 @@
 /*
  * SVQ1/SVQ3 decoder common code
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/svq1_cb.h b/libavcodec/svq1_cb.h
index e22cd60..7926ce1 100644
--- a/libavcodec/svq1_cb.h
+++ b/libavcodec/svq1_cb.h
@@ -6,20 +6,20 @@
  * Copyright (C) 2002 the xine project
  * Copyright (C) 2002 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/svq1_vlc.h b/libavcodec/svq1_vlc.h
index 834279d..e56d894 100644
--- a/libavcodec/svq1_vlc.h
+++ b/libavcodec/svq1_vlc.h
@@ -1,20 +1,20 @@
 /*
  * copyright (C) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c
index 6e096f3..66afdcb 100644
--- a/libavcodec/svq1dec.c
+++ b/libavcodec/svq1dec.c
@@ -8,20 +8,20 @@
  *
  * SVQ1 Encoder (c) 2004 Mike Melanson <melanson@pcisys.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -104,8 +104,7 @@
             break;                                                      \
         /* add child nodes */                                           \
         list[n++] = list[i];                                            \
-        list[n++] = list[i] +                                           \
-                    (((level & 1) ? pitch : 1) << (level / 2 + 1));     \
+        list[n++] = list[i] + (((level & 1) ? pitch : 1) << ((level >> 1) + 1));\
     }
 
 #define SVQ1_ADD_CODEBOOK()                                             \
@@ -167,7 +166,7 @@
                       16 * j) << (level + 1);                           \
     }                                                                   \
     mean -= stages * 128;                                               \
-    n4    = mean + (mean >> 31) << 16 | (mean & 0xFFFF);
+    n4    = (mean << 16) + mean;
 
 static int svq1_decode_block_intra(GetBitContext *bitbuf, uint8_t *pixels,
                                    int pitch)
@@ -539,7 +538,7 @@
 
             svq1_parse_string(bitbuf, msg);
 
-            av_log(s->avctx, AV_LOG_INFO,
+            av_log(s->avctx, AV_LOG_ERROR,
                    "embedded message: \"%s\"\n", (char *)msg);
         }
 
@@ -610,6 +609,9 @@
     if (s->f_code != 0x20) {
         uint32_t *src = (uint32_t *)(buf + 4);
 
+        if (buf_size < 36)
+            return AVERROR_INVALIDDATA;
+
         for (i = 0; i < 4; i++)
             src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i];
     }
diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c
index 1e52e1c..0877795 100644
--- a/libavcodec/svq1enc.c
+++ b/libavcodec/svq1enc.c
@@ -2,20 +2,20 @@
  * SVQ1 Encoder
  * Copyright (C) 2004 Mike Melanson <melanson@pcisys.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -31,11 +31,10 @@
 #include "mpegvideo.h"
 #include "h263.h"
 #include "internal.h"
+#include "libavutil/avassert.h"
 #include "svq1.h"
 #include "svq1enc_cb.h"
 
-#undef NDEBUG
-#include <assert.h>
 
 typedef struct SVQ1Context {
     /* FIXME: Needed for motion estimation, should not be used for anything
@@ -94,7 +93,7 @@
         /* output 5 unknown bits (2 + 2 + 1) */
         put_bits(&s->pb, 5, 2); /* 2 needed by quicktime decoder */
 
-        i = ff_match_2uint16(ff_svq1_frame_size_table,
+        i = ff_match_2uint16((void*)ff_svq1_frame_size_table,
                              FF_ARRAY_ELEMS(ff_svq1_frame_size_table),
                              s->frame_width, s->frame_height);
         put_bits(&s->pb, 3, i);
@@ -178,7 +177,7 @@
                 score  = sqr - (diff * (int64_t)diff >> (level + 3)); // FIXME: 64bit slooow
                 if (score < best_vector_score) {
                     int mean = diff + (size >> 1) >> (level + 3);
-                    assert(mean > -300 && mean < 300);
+                    av_assert2(mean > -300 && mean < 300);
                     mean               = av_clip(mean, intra ? 0 : -256, 255);
                     best_vector_score  = score;
                     best_vector[stage] = i;
@@ -186,7 +185,7 @@
                     best_vector_mean   = mean;
                 }
             }
-            assert(best_vector_mean != -999);
+            av_assert0(best_vector_mean != -999);
             vector = codebook + stage * size * 16 + best_vector[stage] * size;
             for (j = 0; j < size; j++)
                 block[stage + 1][j] = block[stage][j] - vector[j];
@@ -230,10 +229,10 @@
         put_bits(&s->reorder_pb[level], 1, split);
 
     if (!split) {
-        assert(best_mean >= 0 && best_mean < 256 || !intra);
-        assert(best_mean >= -256 && best_mean < 256);
-        assert(best_count >= 0 && best_count < 7);
-        assert(level < 4 || best_count == 0);
+        av_assert1(best_mean >= 0 && best_mean < 256 || !intra);
+        av_assert1(best_mean >= -256 && best_mean < 256);
+        av_assert1(best_count >= 0 && best_count < 7);
+        av_assert1(level < 4 || best_count == 0);
 
         /* output the encoding */
         put_bits(&s->reorder_pb[level],
@@ -243,7 +242,7 @@
                  mean_vlc[best_mean][0]);
 
         for (i = 0; i < best_count; i++) {
-            assert(best_vector[i] >= 0 && best_vector[i] < 16);
+            av_assert2(best_vector[i] >= 0 && best_vector[i] < 16);
             put_bits(&s->reorder_pb[level], 4, best_vector[i]);
         }
 
@@ -434,10 +433,10 @@
                     s->m.pb = s->reorder_pb[5];
                     mx      = motion_ptr[0];
                     my      = motion_ptr[1];
-                    assert(mx     >= -32 && mx     <= 31);
-                    assert(my     >= -32 && my     <= 31);
-                    assert(pred_x >= -32 && pred_x <= 31);
-                    assert(pred_y >= -32 && pred_y <= 31);
+                    av_assert1(mx     >= -32 && mx     <= 31);
+                    av_assert1(my     >= -32 && my     <= 31);
+                    av_assert1(pred_x >= -32 && pred_x <= 31);
+                    av_assert1(pred_y >= -32 && pred_y <= 31);
                     ff_h263_encode_motion(&s->m, mx - pred_x, 1);
                     ff_h263_encode_motion(&s->m, my - pred_y, 1);
                     s->reorder_pb[5] = s->m.pb;
@@ -538,12 +537,9 @@
     AVFrame temp;
     int i, ret;
 
-    if (!pkt->data &&
-        (ret = av_new_packet(pkt, s->y_block_width * s->y_block_height *
-                             MAX_MB_BYTES * 3 + FF_MIN_BUFFER_SIZE) < 0)) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, s->y_block_width * s->y_block_height *
+                             MAX_MB_BYTES*3 + FF_MIN_BUFFER_SIZE) < 0))
         return ret;
-    }
 
     if (avctx->pix_fmt != AV_PIX_FMT_YUV410P) {
         av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
@@ -613,6 +609,10 @@
         av_freep(&s->motion_val8[i]);
         av_freep(&s->motion_val16[i]);
     }
+    if(s->current_picture.data[0])
+        avctx->release_buffer(avctx, &s->current_picture);
+    if(s->last_picture.data[0])
+        avctx->release_buffer(avctx, &s->last_picture);
 
     return 0;
 }
diff --git a/libavcodec/svq1enc_cb.h b/libavcodec/svq1enc_cb.h
index a5cd179..1edb4ec 100644
--- a/libavcodec/svq1enc_cb.h
+++ b/libavcodec/svq1enc_cb.h
@@ -2,20 +2,20 @@
  * SVQ1 Encoder
  * Copyright (C) 2004 Mike Melanson <melanson@pcisys.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c
index bc1a77a..2385eb0 100644
--- a/libavcodec/svq3.c
+++ b/libavcodec/svq3.c
@@ -1,20 +1,20 @@
 /*
- * Copyright (c) 2003 The Libav Project
+ * Copyright (c) 2003 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -37,7 +37,7 @@
  *
  * You will know you have these parameters passed correctly when the decoder
  * correctly decodes this file:
- *  http://samples.libav.org/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov
+ *  http://samples.mplayerhq.hu/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov
  */
 #include "internal.h"
 #include "dsputil.h"
@@ -70,6 +70,8 @@
     int unknown_flag;
     int next_slice_index;
     uint32_t watermark_key;
+    uint8_t *buf;
+    int buf_size;
 } SVQ3Context;
 
 #define FULLPEL_MODE  1
@@ -218,7 +220,7 @@
     for (limit = (16 >> intra); index < 16; index = limit, limit += 8) {
         for (; (vlc = svq3_get_ue_golomb(gb)) != 0; index++) {
 
-          if (vlc == INVALID_VLC)
+          if (vlc < 0)
               return -1;
 
           sign = (vlc & 0x1) - 1;
@@ -236,7 +238,7 @@
                   level = ((vlc + 9) >> 2) - run;
               }
           } else {
-              if (vlc < 16) {
+              if (vlc < 16U) {
                   run   = svq3_dct_tables[intra][vlc].run;
                   level = svq3_dct_tables[intra][vlc].level;
               } else if (intra) {
@@ -568,7 +570,7 @@
             for (i = 0; i < 16; i+=2) {
                 vlc = svq3_get_ue_golomb(&s->gb);
 
-                if (vlc >= 25){
+                if (vlc >= 25U){
                     av_log(h->s.avctx, AV_LOG_ERROR, "luma prediction:%d\n", vlc);
                     return -1;
                 }
@@ -640,7 +642,7 @@
     }
 
     if (!IS_INTRA16x16(mb_type) && (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B)) {
-        if ((vlc = svq3_get_ue_golomb(&s->gb)) >= 48){
+        if ((vlc = svq3_get_ue_golomb(&s->gb)) >= 48U){
             av_log(h->s.avctx, AV_LOG_ERROR, "cbp_vlc=%d\n", vlc);
             return -1;
         }
@@ -650,7 +652,7 @@
     if (IS_INTRA16x16(mb_type) || (s->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) {
         s->qscale += svq3_get_se_golomb(&s->gb);
 
-        if (s->qscale > 31u){
+        if (s->qscale > 31U){
             av_log(h->s.avctx, AV_LOG_ERROR, "qscale:%d\n", s->qscale);
             return -1;
         }
@@ -754,7 +756,7 @@
         skip_bits_long(&s->gb, 0);
     }
 
-    if ((i = svq3_get_ue_golomb(&s->gb)) == INVALID_VLC || i >= 3){
+    if ((i = svq3_get_ue_golomb(&s->gb)) >= 3U){
         av_log(h->s.avctx, AV_LOG_ERROR, "illegal slice type %d \n", i);
         return -1;
     }
@@ -821,6 +823,7 @@
     s->flags2 = avctx->flags2;
     s->unrestricted_mv = 1;
     h->is_complex=1;
+    h->sps.chroma_format_idc = 1;
     avctx->pix_fmt = avctx->codec->pix_fmts[0];
 
     if (!s->context_initialized) {
@@ -830,6 +833,7 @@
         svq3->thirdpel_flag = 1;
         svq3->unknown_flag  = 0;
 
+
         /* prowl for the "SEQH" marker in the extradata */
         extradata = (unsigned char *)avctx->extradata;
         extradata_end = avctx->extradata + avctx->extradata_size;
@@ -902,7 +906,7 @@
                 int offset = (get_bits_count(&gb)+7)>>3;
                 uint8_t *buf;
 
-                if ((uint64_t)watermark_width*4 > UINT_MAX/watermark_height)
+                if (watermark_height<=0 || (uint64_t)watermark_width*4 > UINT_MAX/watermark_height)
                     return -1;
 
                 buf = av_malloc(buf_len);
@@ -945,12 +949,12 @@
                              void *data, int *data_size,
                              AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
     SVQ3Context *svq3 = avctx->priv_data;
     H264Context *h = &svq3->h;
     MpegEncContext *s = &h->s;
     int buf_size = avpkt->size;
-    int m, mb_type;
+    int m, mb_type, left;
+    uint8_t *buf;
 
     /* special case for last picture */
     if (buf_size == 0) {
@@ -962,10 +966,21 @@
         return 0;
     }
 
-    init_get_bits (&s->gb, buf, 8*buf_size);
-
     s->mb_x = s->mb_y = h->mb_xy = 0;
 
+    if (svq3->watermark_key) {
+        av_fast_malloc(&svq3->buf, &svq3->buf_size,
+                       buf_size+FF_INPUT_BUFFER_PADDING_SIZE);
+        if (!svq3->buf)
+            return AVERROR(ENOMEM);
+        memcpy(svq3->buf, avpkt->data, buf_size);
+        buf = svq3->buf;
+    } else {
+        buf = avpkt->data;
+    }
+
+    init_get_bits(&s->gb, buf, 8*buf_size);
+
     if (svq3_decode_slice_header(avctx))
         return -1;
 
@@ -1072,6 +1087,18 @@
         ff_draw_horiz_band(s, 16*s->mb_y, 16);
     }
 
+    left = buf_size*8 - get_bits_count(&s->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);
+        //av_hex_dump(stderr, buf+buf_size-8, 8);
+    }
+
+    if (left < 0) {
+        av_log(avctx, AV_LOG_ERROR, "frame num %d left %d\n", avctx->frame_number, left);
+        return -1;
+    }
+
     ff_MPV_frame_end(s);
 
     if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
@@ -1098,6 +1125,9 @@
 
     ff_MPV_common_end(s);
 
+    av_freep(&svq3->buf);
+    svq3->buf_size = 0;
+
     return 0;
 }
 
diff --git a/libavcodec/synth_filter.c b/libavcodec/synth_filter.c
index 8e6f120..5f10530 100644
--- a/libavcodec/synth_filter.c
+++ b/libavcodec/synth_filter.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/synth_filter.h b/libavcodec/synth_filter.h
index 7b73578..33edcc4 100644
--- a/libavcodec/synth_filter.h
+++ b/libavcodec/synth_filter.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/tableprint.h b/libavcodec/tableprint.h
index 81bb9af..1b39dc6 100644
--- a/libavcodec/tableprint.h
+++ b/libavcodec/tableprint.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/tak.c b/libavcodec/tak.c
new file mode 100644
index 0000000..7e1a047
--- /dev/null
+++ b/libavcodec/tak.c
@@ -0,0 +1,177 @@
+/*
+ * TAK 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 "tak.h"
+#include "libavutil/crc.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/bswap.h"
+
+static const int64_t tak_channel_layouts[] = {
+    0,
+    AV_CH_FRONT_LEFT,
+    AV_CH_FRONT_RIGHT,
+    AV_CH_FRONT_CENTER,
+    AV_CH_LOW_FREQUENCY,
+    AV_CH_BACK_LEFT,
+    AV_CH_BACK_RIGHT,
+    AV_CH_FRONT_LEFT_OF_CENTER,
+    AV_CH_FRONT_RIGHT_OF_CENTER,
+    AV_CH_BACK_CENTER,
+    AV_CH_SIDE_LEFT,
+    AV_CH_SIDE_RIGHT,
+    AV_CH_TOP_CENTER,
+    AV_CH_TOP_FRONT_LEFT,
+    AV_CH_TOP_FRONT_CENTER,
+    AV_CH_TOP_FRONT_RIGHT,
+    AV_CH_TOP_BACK_LEFT,
+    AV_CH_TOP_BACK_CENTER,
+    AV_CH_TOP_BACK_RIGHT,
+};
+
+static const uint16_t frame_duration_type_quants[] = {
+    3, 4, 6, 8, 4096, 8192, 16384, 512, 1024, 2048,
+};
+
+static int tak_get_nb_samples(int sample_rate, enum TAKFrameSizeType type)
+{
+    int nb_samples, max_nb_samples;
+
+    if (type <= TAK_FST_250ms) {
+        nb_samples     = sample_rate * frame_duration_type_quants[type] >>
+                                       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;
+    } else {
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (nb_samples <= 0 || nb_samples > max_nb_samples)
+        return AVERROR_INVALIDDATA;
+
+    return nb_samples;
+}
+
+static int crc_init = 0;
+#if CONFIG_SMALL
+#define CRC_TABLE_SIZE 257
+#else
+#define CRC_TABLE_SIZE 1024
+#endif
+static AVCRC crc_24[CRC_TABLE_SIZE];
+
+av_cold void ff_tak_init_crc(void)
+{
+    if (!crc_init) {
+        av_crc_init(crc_24, 0, 24, 0x864CFBU, sizeof(crc_24));
+        crc_init = 1;
+    }
+}
+
+int ff_tak_check_crc(const uint8_t *buf, unsigned int buf_size)
+{
+    uint32_t crc, CRC;
+
+    if (buf_size < 4)
+        return AVERROR_INVALIDDATA;
+    buf_size -= 3;
+
+    CRC = av_bswap32(AV_RL24(buf + buf_size)) >> 8;
+    crc = av_crc(crc_24, 0xCE04B7U, buf, buf_size);
+    if (CRC != crc)
+        return AVERROR_INVALIDDATA;
+
+    return 0;
+}
+
+void avpriv_tak_parse_streaminfo(GetBitContext *gb, TAKStreamInfo *s)
+{
+    uint64_t channel_mask = 0;
+    int frame_type, i;
+
+    s->codec = get_bits(gb, TAK_ENCODER_CODEC_BITS);
+    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->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;
+
+    if (get_bits1(gb)) {
+        skip_bits(gb, TAK_FORMAT_VALID_BITS);
+        if (get_bits1(gb)) {
+            for (i = 0; i < s->channels; i++) {
+                int value = get_bits(gb, TAK_FORMAT_CH_LAYOUT_BITS);
+
+                if (value < FF_ARRAY_ELEMS(tak_channel_layouts))
+                    channel_mask |= tak_channel_layouts[value];
+            }
+        }
+    }
+
+    s->ch_layout     = channel_mask;
+    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->frame_num = get_bits(gb, TAK_FRAME_HEADER_NO_BITS);
+
+    if (flags & FRAME_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) {
+        avpriv_tak_parse_streaminfo(gb, ti);
+
+        if (get_bits(gb, 6))
+            skip_bits(gb, 25);
+        align_get_bits(gb);
+    }
+
+    if (flags & FRAME_HAVE_METADATA)
+        return AVERROR_INVALIDDATA;
+
+    skip_bits(gb, 24);
+
+    return 0;
+}
diff --git a/libavcodec/tak.h b/libavcodec/tak.h
new file mode 100644
index 0000000..cfa074d
--- /dev/null
+++ b/libavcodec/tak.h
@@ -0,0 +1,151 @@
+/*
+ * TAK decoder/demuxer 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
+ */
+
+/**
+ * @file
+ * TAK (Tom's lossless Audio Kompressor) decoder/demuxer common functions
+ */
+
+#ifndef AVCODEC_TAK_H
+#define AVCODEC_TAK_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_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_MIN_FRAME_HEADER_LAST_BITS    ( TAK_MIN_FRAME_HEADER_BITS + 2 + \
+                                            TAK_FRAME_HEADER_SAMPLE_COUNT_BITS )
+
+#define TAK_ENCODER_BITS         ( TAK_ENCODER_CODEC_BITS        + \
+                                   TAK_ENCODER_PROFILE_BITS )
+
+#define TAK_SIZE_BITS            ( TAK_SIZE_SAMPLES_NUM_BITS     + \
+                                   TAK_SIZE_FRAME_DURATION_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_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 TAKMetaDataType {
+    TAK_METADATA_END = 0,
+    TAK_METADATA_STREAMINFO,
+    TAK_METADATA_SEEKTABLE,
+    TAK_METADATA_SIMPLE_WAVE_DATA,
+    TAK_METADATA_ENCODER,
+    TAK_METADATA_PADDING,
+    TAK_METADATA_MD5,
+    TAK_METADATA_LAST_FRAME,
+};
+
+enum TAKFrameSizeType {
+    TAK_FST_94ms = 0,
+    TAK_FST_125ms,
+    TAK_FST_188ms,
+    TAK_FST_250ms,
+    TAK_FST_4096,
+    TAK_FST_8192,
+    TAK_FST_16384,
+    TAK_FST_512,
+    TAK_FST_1024,
+    TAK_FST_2048,
+};
+
+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;
+} TAKStreamInfo;
+
+void ff_tak_init_crc(void);
+
+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
+ */
+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
+ */
+int ff_tak_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
+                               TAKStreamInfo *s, int log_level_offset);
+#endif /* AVCODEC_TAK_H */
diff --git a/libavcodec/tak_parser.c b/libavcodec/tak_parser.c
new file mode 100644
index 0000000..dcc37ec
--- /dev/null
+++ b/libavcodec/tak_parser.c
@@ -0,0 +1,126 @@
+/*
+ * TAK parser
+ * 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
+ * TAK parser
+ **/
+
+#include "parser.h"
+#include "tak.h"
+
+typedef struct TAKParseContext {
+    ParseContext  pc;
+    TAKStreamInfo ti;
+    int index;
+} TAKParseContext;
+
+static av_cold int tak_init(AVCodecParserContext *s)
+{
+    ff_tak_init_crc();
+    return 0;
+}
+
+static int tak_parse(AVCodecParserContext *s, AVCodecContext *avctx,
+                     const uint8_t **poutbuf, int *poutbuf_size,
+                     const uint8_t *buf, int buf_size)
+{
+    TAKParseContext *t = s->priv_data;
+    ParseContext *pc = &t->pc;
+    int next = END_NOT_FOUND;
+    GetBitContext gb;
+    int consumed = 0;
+    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;
+        *poutbuf      = buf;
+        *poutbuf_size = buf_size;
+        return buf_size;
+    }
+
+    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);
+            const uint8_t *tmp_buf = buf;
+
+            ff_combine_frame(pc, END_NOT_FOUND, &tmp_buf, &tmp_buf_size);
+            consumed += tmp_buf_size;
+            buf      += tmp_buf_size;
+            buf_size -= tmp_buf_size;
+        }
+
+        for (; t->index + needed <= pc->index; t->index++) {
+            if (pc->buffer[ t->index     ] == 0xFF &&
+                pc->buffer[ t->index + 1 ] == 0xA0) {
+                TAKStreamInfo ti;
+
+                init_get_bits(&gb, pc->buffer + t->index,
+                              8 * (pc->index - t->index));
+                if (!ff_tak_decode_frame_header(avctx, &gb,
+                        pc->frame_start_found ? &ti : &t->ti, 127) &&
+                    !ff_tak_check_crc(pc->buffer + t->index,
+                                      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;
+                    } else {
+                        pc->frame_start_found = 0;
+                        next = t->index - pc->index;
+                        t->index = 0;
+                        goto found;
+                    }
+                }
+            }
+        }
+    }
+found:
+
+    if (consumed && !buf_size && next == END_NOT_FOUND ||
+        ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
+        *poutbuf      = NULL;
+        *poutbuf_size = 0;
+        return buf_size + consumed;
+    }
+
+    if (next != END_NOT_FOUND) {
+        next += consumed;
+        pc->overread = FFMAX(0, -next);
+    }
+
+    *poutbuf      = buf;
+    *poutbuf_size = buf_size;
+    return next;
+}
+
+AVCodecParser ff_tak_parser = {
+    .codec_ids      = { AV_CODEC_ID_TAK },
+    .priv_data_size = sizeof(TAKParseContext),
+    .parser_init    = tak_init,
+    .parser_parse   = tak_parse,
+    .parser_close   = ff_parse_close,
+};
diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c
new file mode 100644
index 0000000..76bde55
--- /dev/null
+++ b/libavcodec/takdec.c
@@ -0,0 +1,980 @@
+/*
+ * TAK decoder
+ * 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
+ */
+
+/**
+ * @file
+ * TAK (Tom's lossless Audio Kompressor) decoder
+ * @author Paul B Mahol
+ */
+
+#include "tak.h"
+#include "avcodec.h"
+#include "unary.h"
+#include "dsputil.h"
+
+#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;
+} 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
+
+    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
+
+    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         dmode;                       ///< channel decorrelation type in the current frame
+    int8_t         dshift;
+    int16_t        dfactor;
+    int8_t         dval1;
+    int8_t         dval2;
+
+    MCDParam       mcdparams[TAK_MAX_CHANNELS]; ///< multichannel decorrelation parameters
+
+    int            wlength;
+    int            uval;
+    int            rval;
+    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 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;
+} xcodes[50] = {
+    { 0x01, 0x0000001, 0x0000001, 0x0000003, 0x0000008 },
+    { 0x02, 0x0000003, 0x0000001, 0x0000007, 0x0000006 },
+    { 0x03, 0x0000005, 0x0000002, 0x000000E, 0x000000D },
+    { 0x03, 0x0000003, 0x0000003, 0x000000D, 0x0000018 },
+    { 0x04, 0x000000B, 0x0000004, 0x000001C, 0x0000019 },
+    { 0x04, 0x0000006, 0x0000006, 0x000001A, 0x0000030 },
+    { 0x05, 0x0000016, 0x0000008, 0x0000038, 0x0000032 },
+    { 0x05, 0x000000C, 0x000000C, 0x0000034, 0x0000060 },
+    { 0x06, 0x000002C, 0x0000010, 0x0000070, 0x0000064 },
+    { 0x06, 0x0000018, 0x0000018, 0x0000068, 0x00000C0 },
+    { 0x07, 0x0000058, 0x0000020, 0x00000E0, 0x00000C8 },
+    { 0x07, 0x0000030, 0x0000030, 0x00000D0, 0x0000180 },
+    { 0x08, 0x00000B0, 0x0000040, 0x00001C0, 0x0000190 },
+    { 0x08, 0x0000060, 0x0000060, 0x00001A0, 0x0000300 },
+    { 0x09, 0x0000160, 0x0000080, 0x0000380, 0x0000320 },
+    { 0x09, 0x00000C0, 0x00000C0, 0x0000340, 0x0000600 },
+    { 0x0A, 0x00002C0, 0x0000100, 0x0000700, 0x0000640 },
+    { 0x0A, 0x0000180, 0x0000180, 0x0000680, 0x0000C00 },
+    { 0x0B, 0x0000580, 0x0000200, 0x0000E00, 0x0000C80 },
+    { 0x0B, 0x0000300, 0x0000300, 0x0000D00, 0x0001800 },
+    { 0x0C, 0x0000B00, 0x0000400, 0x0001C00, 0x0001900 },
+    { 0x0C, 0x0000600, 0x0000600, 0x0001A00, 0x0003000 },
+    { 0x0D, 0x0001600, 0x0000800, 0x0003800, 0x0003200 },
+    { 0x0D, 0x0000C00, 0x0000C00, 0x0003400, 0x0006000 },
+    { 0x0E, 0x0002C00, 0x0001000, 0x0007000, 0x0006400 },
+    { 0x0E, 0x0001800, 0x0001800, 0x0006800, 0x000C000 },
+    { 0x0F, 0x0005800, 0x0002000, 0x000E000, 0x000C800 },
+    { 0x0F, 0x0003000, 0x0003000, 0x000D000, 0x0018000 },
+    { 0x10, 0x000B000, 0x0004000, 0x001C000, 0x0019000 },
+    { 0x10, 0x0006000, 0x0006000, 0x001A000, 0x0030000 },
+    { 0x11, 0x0016000, 0x0008000, 0x0038000, 0x0032000 },
+    { 0x11, 0x000C000, 0x000C000, 0x0034000, 0x0060000 },
+    { 0x12, 0x002C000, 0x0010000, 0x0070000, 0x0064000 },
+    { 0x12, 0x0018000, 0x0018000, 0x0068000, 0x00C0000 },
+    { 0x13, 0x0058000, 0x0020000, 0x00E0000, 0x00C8000 },
+    { 0x13, 0x0030000, 0x0030000, 0x00D0000, 0x0180000 },
+    { 0x14, 0x00B0000, 0x0040000, 0x01C0000, 0x0190000 },
+    { 0x14, 0x0060000, 0x0060000, 0x01A0000, 0x0300000 },
+    { 0x15, 0x0160000, 0x0080000, 0x0380000, 0x0320000 },
+    { 0x15, 0x00C0000, 0x00C0000, 0x0340000, 0x0600000 },
+    { 0x16, 0x02C0000, 0x0100000, 0x0700000, 0x0640000 },
+    { 0x16, 0x0180000, 0x0180000, 0x0680000, 0x0C00000 },
+    { 0x17, 0x0580000, 0x0200000, 0x0E00000, 0x0C80000 },
+    { 0x17, 0x0300000, 0x0300000, 0x0D00000, 0x1800000 },
+    { 0x18, 0x0B00000, 0x0400000, 0x1C00000, 0x1900000 },
+    { 0x18, 0x0600000, 0x0600000, 0x1A00000, 0x3000000 },
+    { 0x19, 0x1600000, 0x0800000, 0x3800000, 0x3200000 },
+    { 0x19, 0x0C00000, 0x0C00000, 0x3400000, 0x6000000 },
+    { 0x1A, 0x2C00000, 0x1000000, 0x7000000, 0x6400000 },
+    { 0x1A, 0x1800000, 0x1800000, 0x6800000, 0xC000000 },
+};
+
+static int tak_set_bps(AVCodecContext *avctx, int bps)
+{
+    switch (bps) {
+    case 8:
+        avctx->sample_fmt = AV_SAMPLE_FMT_U8P;
+        break;
+    case 16:
+        avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
+        break;
+    case 24:
+        avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "invalid/unsupported bits per sample\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    return 0;
+}
+
+static int get_shift(int sample_rate)
+{
+    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;
+}
+
+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;
+
+    s->uval = get_scale(avctx->sample_rate, get_shift(avctx->sample_rate));
+    s->subframe_scale = get_scale(avctx->sample_rate, 1);
+
+    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);
+    }
+}
+
+static void decode_lpc(int32_t *coeffs, int mode, int length)
+{
+    int i, a1, a2, a3, a4, a5;
+
+    if (length < 2)
+        return;
+
+    if (mode == 1) {
+        a1 = *coeffs++;
+        for (i = 0; i < (length - 1 >> 1); i++) {
+            *coeffs   += a1;
+            coeffs[1] += *coeffs;
+            a1      = coeffs[1];
+            coeffs    += 2;
+        }
+        if ((length - 1) & 1)
+            *coeffs += a1;
+    } else if (mode == 2) {
+        a1     = coeffs[1];
+        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;
+                *coeffs   = a4;
+                a1     = coeffs[1] + a3;
+                a2     = a1 + a4;
+                coeffs[1] = a2;
+                coeffs   += 2;
+            }
+            if (length & 1)
+                *coeffs  += a1 + a2;
+        }
+    } else if (mode == 3) {
+        a1     = coeffs[1];
+        a2     = a1 + *coeffs;
+        coeffs[1] = a2;
+        if (length > 2) {
+            a3   = coeffs[2];
+            a4   = a3 + a1;
+            a5   = a4 + a2;
+            coeffs += 3;
+            for (i = 0; i < length - 3; i++) {
+                a3  += *coeffs;
+                a4  += a3;
+                a5  += a4;
+                *coeffs = a5;
+                coeffs++;
+            }
+        }
+    }
+}
+
+static int decode_segment(TAKDecContext *s, int8_t value, int32_t *dst, int len)
+{
+    GetBitContext *gb = &s->gb;
+
+    if (!value) {
+        memset(dst, 0, len * 4);
+    } else {
+        int x, y, z, i = 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;
+            }
+
+            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;
+                    }
+                    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);
+    }
+
+    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)
+{
+    GetBitContext *gb = &s->gb;
+    int i, v, ret;
+
+    if (length > s->nb_samples)
+        return AVERROR_INVALIDDATA;
+
+    if (get_bits1(gb)) {
+        if ((s->wlength = xget(s, length, s->uval)) < 0)
+            return AVERROR_INVALIDDATA;
+
+        s->coding_mode[0] = v = get_bits(gb, 6);
+        if (s->coding_mode[0] > FF_ARRAY_ELEMS(xcodes))
+            return AVERROR_INVALIDDATA;
+
+        for (i = 1; i < s->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);
+            }
+
+            if (v > FF_ARRAY_ELEMS(xcodes))
+                return AVERROR_INVALIDDATA;
+            s->coding_mode[i] = v;
+        }
+
+        i = 0;
+        while (i < s->wlength) {
+            int len = 0;
+
+            v = s->coding_mode[i];
+            do {
+                len += get_len(s, i);
+                i++;
+
+                if (i == s->wlength)
+                    break;
+            } while (v == s->coding_mode[i]);
+
+            if ((ret = decode_segment(s, v, dst, len)) < 0)
+                return ret;
+            dst += 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)
+            return ret;
+    }
+
+    return 0;
+}
+
+static int get_b(GetBitContext *gb)
+{
+    if (get_bits1(gb))
+        return get_bits(gb, 4) + 1;
+    else
+        return 0;
+}
+
+static int decode_subframe(TAKDecContext *s, int32_t *ptr, int subframe_size,
+                           int prev_subframe_size)
+{
+    GetBitContext  *gb = &s->gb;
+    int tmp, x, y, i, j, ret = 0;
+    int tfilter[MAX_PREDICTORS];
+
+    if (get_bits1(gb)) {
+        s->filter_order = predictor_sizes[get_bits(gb, 4)];
+
+        if (prev_subframe_size > 0 && get_bits1(gb)) {
+            if (s->filter_order > prev_subframe_size)
+                return AVERROR_INVALIDDATA;
+
+            ptr           -= s->filter_order;
+            subframe_size += s->filter_order;
+
+            if (s->filter_order > subframe_size)
+                return AVERROR_INVALIDDATA;
+        } else {
+            int lpc;
+
+            if (s->filter_order > subframe_size)
+                return AVERROR_INVALIDDATA;
+
+            lpc = get_bits(gb, 2);
+            if (lpc > 2)
+                return AVERROR_INVALIDDATA;
+
+            if ((ret = decode_coeffs(s, ptr, s->filter_order)) < 0)
+                return ret;
+
+            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)
+            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);
+    }
+
+    return ret;
+}
+
+static int decode_channel(TAKDecContext *s, int chan)
+{
+    AVCodecContext *avctx = s->avctx;
+    GetBitContext  *gb = &s->gb;
+    int32_t *dst = s->decoded[chan];
+    int i = 0, ret, prev = 0;
+    int left = s->nb_samples - 1;
+
+    s->sample_shift[chan] = get_b(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]);
+    s->lpc_mode[chan] = get_bits(gb, 2);
+    s->nb_subframes   = get_bits(gb, 3) + 1;
+
+    if (s->nb_subframes > 1) {
+        if (get_bits_left(gb) < (s->nb_subframes - 1) * 6)
+            return AVERROR_INVALIDDATA;
+
+        for (; i < s->nb_subframes - 1; i++) {
+            int v = get_bits(gb, 6);
+
+            s->subframe_len[i] = (v - prev) * s->subframe_scale;
+            if (s->subframe_len[i] <= 0)
+                return AVERROR_INVALIDDATA;
+
+            left -= s->subframe_len[i];
+            prev  = v;
+        }
+
+        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)
+            return ret;
+        dst += s->subframe_len[i];
+        prev = s->subframe_len[i];
+    }
+
+    return 0;
+}
+
+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);
+        }
+    }
+
+    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);
+        }
+        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;
+        }
+        break;
+    case 6:
+        FFSWAP(uint32_t *, p1, p2);
+    case 7:
+        if (length < 256)
+            return AVERROR_INVALIDDATA;
+
+        a = s->filter_order / 2;
+        b = length - (s->filter_order - 1);
+
+        if (s->dval1) {
+            for (i = 0; i < a; i++)
+                p1[i] += p2[i];
+        }
+
+        if (s->dval2) {
+            x = a + b;
+            for (i = 0; i < length - x; i++)
+                p1[x + i] += p2[x + i];
+        }
+
+        for (i = 0; i < s->filter_order; i++)
+            s->residues[i] = *p2++ >> s->dshift;
+
+        p1 += a;
+        x = FF_ARRAY_ELEMS(s->residues) - s->filter_order;
+        for (; b > 0; b -= tmp) {
+            tmp = FFMIN(b, x);
+
+            for (i = 0; i < tmp; i++)
+                s->residues[s->filter_order + i] = *p2++ >> s->dshift;
+
+            for (i = 0; i < tmp; i++) {
+                int v, w, m;
+
+                v = 1 << 9;
+
+                if (s->filter_order == 16) {
+                    v += s->dsp.scalarproduct_int16(&s->residues[i], s->filter,
+                                                    s->filter_order);
+                } else {
+                    v += s->residues[i + 7] * s->filter[7] +
+                         s->residues[i + 6] * s->filter[6] +
+                         s->residues[i + 5] * s->filter[5] +
+                         s->residues[i + 4] * s->filter[4] +
+                         s->residues[i + 3] * s->filter[3] +
+                         s->residues[i + 2] * s->filter[2] +
+                         s->residues[i + 1] * s->filter[1] +
+                         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;
+            }
+
+            memcpy(s->residues, &s->residues[tmp], 2 * s->filter_order);
+        }
+
+        emms_c();
+        break;
+    }
+
+    return 0;
+}
+
+static int tak_decode_frame(AVCodecContext *avctx, void *data,
+                            int *got_frame_ptr, AVPacket *pkt)
+{
+    TAKDecContext  *s = avctx->priv_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 = ff_tak_decode_frame_header(avctx, gb, &s->ti, 0)) < 0)
+        return ret;
+
+    if (avctx->err_recognition & AV_EF_CRCCHECK) {
+        hsize = get_bits_count(gb) / 8;
+        if (ff_tak_check_crc(pkt->data, hsize)) {
+            av_log(avctx, AV_LOG_ERROR, "CRC error\n");
+            return AVERROR_INVALIDDATA;
+        }
+    }
+
+    if (s->ti.codec != 2 && s->ti.codec != 4) {
+        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);
+        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);
+        return AVERROR_INVALIDDATA;
+    }
+    if (s->ti.channels > 6) {
+        av_log(avctx, AV_LOG_ERROR, "unsupported number of channels: %d\n", s->ti.channels);
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (s->ti.frame_samples <= 0) {
+        av_log(avctx, AV_LOG_ERROR, "unsupported/invalid number of samples\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    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)
+            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);
+    }
+    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->frame.nb_samples = s->nb_samples;
+    if ((ret = avctx->get_buffer(avctx, &s->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);
+        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);
+    } else {
+        for (chan = 0; chan < avctx->channels; chan++)
+            s->decoded[chan] = (int32_t *)s->frame.data[chan];
+    }
+
+    if (s->nb_samples < 16) {
+        for (chan = 0; chan < avctx->channels; chan++) {
+            p = s->decoded[chan];
+            for (i = 0; i < s->nb_samples; i++)
+                *p++ = get_code(gb, avctx->bits_per_raw_sample);
+        }
+    } else {
+        if (s->ti.codec == 2) {
+            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)
+                    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) {
+            if (get_bits1(gb)) {
+                int ch_mask = 0;
+
+                chan = get_bits(gb, 4) + 1;
+                if (chan > avctx->channels)
+                    return AVERROR_INVALIDDATA;
+
+                for (i = 0; i < chan; i++) {
+                    int nbit = get_bits(gb, 4);
+
+                    if (nbit >= avctx->channels)
+                        return AVERROR_INVALIDDATA;
+
+                    if (ch_mask & 1 << nbit)
+                        return AVERROR_INVALIDDATA;
+
+                    s->mcdparams[i].present = get_bits1(gb);
+                    if (s->mcdparams[i].present) {
+                        s->mcdparams[i].index = get_bits(gb, 2);
+                        s->mcdparams[i].chan2 = get_bits(gb, 4);
+                        if (s->mcdparams[i].index == 1) {
+                            if ((nbit == s->mcdparams[i].chan2) ||
+                                (ch_mask & 1 << s->mcdparams[i].chan2))
+                                return AVERROR_INVALIDDATA;
+
+                            ch_mask |= 1 << s->mcdparams[i].chan2;
+                        } else if (!(ch_mask & 1 << s->mcdparams[i].chan2)) {
+                            return AVERROR_INVALIDDATA;
+                        }
+                    }
+                    s->mcdparams[i].chan1 = nbit;
+
+                    ch_mask |= 1 << nbit;
+                }
+            } else {
+                chan = avctx->channels;
+                for (i = 0; i < chan; i++) {
+                    s->mcdparams[i].present = 0;
+                    s->mcdparams[i].chan1   = i;
+                }
+            }
+
+            for (i = 0; i < chan; i++) {
+                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))
+                        return ret;
+                }
+            }
+        }
+
+        for (chan = 0; chan < avctx->channels; chan++) {
+            p = s->decoded[chan];
+            decode_lpc(p, 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];
+            }
+        }
+    }
+
+    align_get_bits(gb);
+    skip_bits(gb, 24);
+    if (get_bits_left(gb) < 0)
+        av_log(avctx, AV_LOG_DEBUG, "overread\n");
+    else if (get_bits_left(gb) > 0)
+        av_log(avctx, AV_LOG_DEBUG, "underread\n");
+
+    if (avctx->err_recognition & AV_EF_CRCCHECK) {
+        if (ff_tak_check_crc(pkt->data + hsize,
+                             get_bits_count(gb) / 8 - hsize)) {
+            av_log(avctx, AV_LOG_ERROR, "CRC error\n");
+            return AVERROR_INVALIDDATA;
+        }
+    }
+
+    // convert to output buffer
+    switch (avctx->bits_per_raw_sample) {
+    case 8:
+        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];
+            for (i = 0; i < s->nb_samples; i++)
+                *samples++ <<= 8;
+        }
+        break;
+    }
+
+    *got_frame_ptr   = 1;
+    *(AVFrame *)data = s->frame;
+
+    return pkt->size;
+}
+
+static av_cold int tak_decode_close(AVCodecContext *avctx)
+{
+    TAKDecContext *s = avctx->priv_data;
+
+    av_freep(&s->decode_buffer);
+
+    return 0;
+}
+
+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)"),
+};
diff --git a/libavcodec/targa.c b/libavcodec/targa.c
index 96d1830..e1d83b9 100644
--- a/libavcodec/targa.c
+++ b/libavcodec/targa.c
@@ -2,20 +2,20 @@
  * Targa (.tga) image decoder
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -28,22 +28,37 @@
 typedef struct TargaContext {
     AVFrame picture;
     GetByteContext gb;
-
-    int color_type;
-    int compression_type;
 } TargaContext;
 
+static uint8_t *advance_line(uint8_t *start, uint8_t *line,
+                             int stride, int *y, int h, int interleave)
+{
+    *y += interleave;
+
+    if (*y < h) {
+        return line + interleave * stride;
+    } else {
+        *y = (*y + 1) & (interleave - 1);
+        if (*y) {
+            return start + *y * stride;
+        } else {
+            return NULL;
+        }
+    }
+}
+
 static int targa_decode_rle(AVCodecContext *avctx, TargaContext *s,
-                            uint8_t *dst, int w, int h, int stride, int bpp)
+                            uint8_t *start, int w, int h, int stride,
+                            int bpp, int interleave)
 {
     int x, y;
     int depth = (bpp + 1) >> 3;
     int type, count;
-    int diff;
+    uint8_t *line = start;
+    uint8_t *dst  = line;
 
-    diff = stride - w * depth;
-    x = y = 0;
-    while (y < h) {
+    x = y = count = 0;
+    while (dst) {
         if (bytestream2_get_bytes_left(&s->gb) <= 0) {
             av_log(avctx, AV_LOG_ERROR,
                    "Ran ouf of data before end-of-image\n");
@@ -52,12 +67,6 @@
         type  = bytestream2_get_byteu(&s->gb);
         count = (type & 0x7F) + 1;
         type &= 0x80;
-        if (x + count > w && x + count + 1 > (h - y) * w) {
-            av_log(avctx, AV_LOG_ERROR,
-                   "Packet went out of bounds: position (%i,%i) size %i\n",
-                   x, y, count);
-            return AVERROR_INVALIDDATA;
-        }
         if (!type) {
             do {
                 int n  = FFMIN(count, w - x);
@@ -67,10 +76,9 @@
                 x     += n;
                 if (x == w) {
                     x    = 0;
-                    y++;
-                    dst += diff;
+                    dst = line = advance_line(start, line, stride, &y, h, interleave);
                 }
-            } while (count > 0);
+            } while (dst && count > 0);
         } else {
             uint8_t tmp[4];
             bytestream2_get_buffer(&s->gb, tmp, depth);
@@ -84,12 +92,17 @@
                 } while (--n);
                 if (x == w) {
                     x    = 0;
-                    y++;
-                    dst += diff;
+                    dst = line = advance_line(start, line, stride, &y, h, interleave);
                 }
-            } while (count > 0);
+            } while (dst && count > 0);
         }
     }
+
+    if (count) {
+        av_log(avctx, AV_LOG_ERROR, "Packet went out of bounds\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     return 0;
 }
 
@@ -102,14 +115,15 @@
     AVFrame * const p = &s->picture;
     uint8_t *dst;
     int stride;
-    int idlen, compr, y, w, h, bpp, flags;
+    int idlen, pal, compr, y, w, h, bpp, flags;
     int first_clr, colors, csize;
+    int interleave;
 
     bytestream2_init(&s->gb, avpkt->data, avpkt->size);
 
     /* parse image header */
     idlen     = bytestream2_get_byte(&s->gb);
-    bytestream2_skip(&s->gb, 1); /* pal */
+    pal       = bytestream2_get_byte(&s->gb);
     compr     = bytestream2_get_byte(&s->gb);
     first_clr = bytestream2_get_le16(&s->gb);
     colors    = bytestream2_get_le16(&s->gb);
@@ -118,17 +132,29 @@
     w         = bytestream2_get_le16(&s->gb);
     h         = bytestream2_get_le16(&s->gb);
     bpp       = bytestream2_get_byte(&s->gb);
+
+    if (bytestream2_get_bytes_left(&s->gb) <= idlen) {
+        av_log(avctx, AV_LOG_ERROR,
+                "Not enough data to read header\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     flags     = bytestream2_get_byte(&s->gb);
+
+    if (!pal && (first_clr || colors || csize)) {
+        av_log(avctx, AV_LOG_WARNING, "File without colormap has colormap information set.\n");
+        // specification says we should ignore those value in this case
+        first_clr = colors = csize = 0;
+    }
+
     // skip identifier if any
     bytestream2_skip(&s->gb, idlen);
 
-    switch(bpp){
+    switch (bpp) {
     case 8:
         avctx->pix_fmt = ((compr & (~TGA_RLE)) == TGA_BW) ? AV_PIX_FMT_GRAY8 : AV_PIX_FMT_PAL8;
         break;
     case 15:
-        avctx->pix_fmt = AV_PIX_FMT_RGB555LE;
-        break;
     case 16:
         avctx->pix_fmt = AV_PIX_FMT_RGB555LE;
         break;
@@ -143,32 +169,37 @@
         return -1;
     }
 
-    if(s->picture.data[0])
+    if (s->picture.data[0])
         avctx->release_buffer(avctx, &s->picture);
 
-    if(av_image_check_size(w, h, 0, avctx))
+    if (av_image_check_size(w, h, 0, avctx))
         return -1;
-    if(w != avctx->width || h != avctx->height)
+    if (w != avctx->width || h != avctx->height)
         avcodec_set_dimensions(avctx, w, h);
-    if(avctx->get_buffer(avctx, p) < 0){
+    if (avctx->get_buffer(avctx, p) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
-    if(flags & 0x20){
+
+    if (flags & TGA_TOPTOBOTTOM) {
         dst = p->data[0];
         stride = p->linesize[0];
-    }else{ //image is upside-down
+    } else { //image is upside-down
         dst = p->data[0] + p->linesize[0] * (h - 1);
         stride = -p->linesize[0];
     }
 
-    if(colors){
+    interleave = flags & TGA_INTERLEAVE2 ? 2 :
+                 flags & TGA_INTERLEAVE4 ? 4 : 1;
+
+    if (colors) {
         int pal_size, pal_sample_size;
-        if((colors + first_clr) > 256){
+        if ((colors + first_clr) > 256) {
             av_log(avctx, AV_LOG_ERROR, "Incorrect palette: %i colors with offset %i\n", colors, first_clr);
             return -1;
         }
         switch (csize) {
+        case 32: pal_sample_size = 4; break;
         case 24: pal_sample_size = 3; break;
         case 16:
         case 15: pal_sample_size = 2; break;
@@ -177,9 +208,9 @@
             return -1;
         }
         pal_size = colors * pal_sample_size;
-        if(avctx->pix_fmt != AV_PIX_FMT_PAL8)//should not occur but skip palette anyway
+        if (avctx->pix_fmt != AV_PIX_FMT_PAL8) //should not occur but skip palette anyway
             bytestream2_skip(&s->gb, pal_size);
-        else{
+        else {
             int t;
             uint32_t *pal = ((uint32_t *)p->data[1]) + first_clr;
 
@@ -189,10 +220,14 @@
                 return AVERROR_INVALIDDATA;
             }
             switch (pal_sample_size) {
+            case 4:
+                for (t = 0; t < colors; t++)
+                    *pal++ = bytestream2_get_le32u(&s->gb);
+                break;
             case 3:
                 /* RGB24 */
                 for (t = 0; t < colors; t++)
-                    *pal++ = bytestream2_get_le24u(&s->gb);
+                    *pal++ = (0xffU<<24) | bytestream2_get_le24u(&s->gb);
                 break;
             case 2:
                 /* RGB555 */
@@ -203,30 +238,59 @@
                         ((v & 0x001F) <<  3);
                     /* left bit replication */
                     v |= (v & 0xE0E0E0U) >> 5;
-                    *pal++ = v;
+                    *pal++ = (0xffU<<24) | v;
                 }
                 break;
             }
             p->palette_has_changed = 1;
         }
     }
+
     if ((compr & (~TGA_RLE)) == TGA_NODATA) {
         memset(p->data[0], 0, p->linesize[0] * h);
     } else {
-        if(compr & TGA_RLE){
-            int res = targa_decode_rle(avctx, s, dst, w, h, stride, bpp);
+        if (compr & TGA_RLE) {
+            int res = targa_decode_rle(avctx, s, dst, w, h, stride, bpp, interleave);
             if (res < 0)
                 return res;
         } else {
             size_t img_size = w * ((bpp + 1) >> 3);
+            uint8_t *line;
             if (bytestream2_get_bytes_left(&s->gb) < img_size * h) {
                 av_log(avctx, AV_LOG_ERROR,
                        "Not enough data available for image\n");
                 return AVERROR_INVALIDDATA;
             }
-            for (y = 0; y < h; y++) {
-                bytestream2_get_bufferu(&s->gb, dst, img_size);
-                dst += stride;
+
+            line = dst;
+            y = 0;
+            do {
+                bytestream2_get_bufferu(&s->gb, line, img_size);
+                line = advance_line(dst, line, stride, &y, h, interleave);
+            } while (line);
+        }
+    }
+
+    if (flags & TGA_RIGHTTOLEFT) { // right-to-left, needs horizontal flip
+        int x;
+        for (y = 0; y < h; y++) {
+            void *line = &p->data[0][y * p->linesize[0]];
+            for (x = 0; x < w >> 1; x++) {
+                switch (bpp) {
+                case 32:
+                    FFSWAP(uint32_t, ((uint32_t *)line)[x], ((uint32_t *)line)[w - x - 1]);
+                    break;
+                case 24:
+                    FFSWAP(uint8_t, ((uint8_t *)line)[3 * x    ], ((uint8_t *)line)[3 * w - 3 * x - 3]);
+                    FFSWAP(uint8_t, ((uint8_t *)line)[3 * x + 1], ((uint8_t *)line)[3 * w - 3 * x - 2]);
+                    FFSWAP(uint8_t, ((uint8_t *)line)[3 * x + 2], ((uint8_t *)line)[3 * w - 3 * x - 1]);
+                    break;
+                case 16:
+                    FFSWAP(uint16_t, ((uint16_t *)line)[x], ((uint16_t *)line)[w - x - 1]);
+                    break;
+                case 8:
+                    FFSWAP(uint8_t, ((uint8_t *)line)[x], ((uint8_t *)line)[w - x - 1]);
+                }
             }
         }
     }
@@ -237,7 +301,8 @@
     return avpkt->size;
 }
 
-static av_cold int targa_init(AVCodecContext *avctx){
+static av_cold int targa_init(AVCodecContext *avctx)
+{
     TargaContext *s = avctx->priv_data;
 
     avcodec_get_frame_defaults(&s->picture);
@@ -246,10 +311,11 @@
     return 0;
 }
 
-static av_cold int targa_end(AVCodecContext *avctx){
+static av_cold int targa_end(AVCodecContext *avctx)
+{
     TargaContext *s = avctx->priv_data;
 
-    if(s->picture.data[0])
+    if (s->picture.data[0])
         avctx->release_buffer(avctx, &s->picture);
 
     return 0;
diff --git a/libavcodec/targa.h b/libavcodec/targa.h
index f4ef553..c2f5224 100644
--- a/libavcodec/targa.h
+++ b/libavcodec/targa.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -38,4 +38,11 @@
     TGA_RLE    = 8, // flag pointing that data is RLE-coded
 };
 
+enum TargaFlags {
+    TGA_RIGHTTOLEFT = 0x10, // right-to-left (flipped horizontally)
+    TGA_TOPTOBOTTOM = 0x20, // top-to-bottom (NOT flipped vertically)
+    TGA_INTERLEAVE2 = 0x40, // 2-way interleave, odd then even lines
+    TGA_INTERLEAVE4 = 0x80, // 4-way interleave
+};
+
 #endif /* AVCODEC_TARGA_H */
diff --git a/libavcodec/targa_y216dec.c b/libavcodec/targa_y216dec.c
new file mode 100644
index 0000000..bac5aee
--- /dev/null
+++ b/libavcodec/targa_y216dec.c
@@ -0,0 +1,108 @@
+/*
+ * Pinnacle TARGA CineWave YUV16 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"
+
+static av_cold int y216_decode_init(AVCodecContext *avctx)
+{
+    avctx->pix_fmt             = AV_PIX_FMT_YUV422P16;
+    avctx->bits_per_raw_sample = 14;
+
+    avctx->coded_frame = avcodec_alloc_frame();
+
+    if (!avctx->coded_frame) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int y216_decode_frame(AVCodecContext *avctx, void *data,
+                             int *data_size, AVPacket *avpkt)
+{
+    AVFrame *pic = avctx->coded_frame;
+    const uint16_t *src = (uint16_t *)avpkt->data;
+    uint16_t *y, *u, *v, aligned_width = FFALIGN(avctx->width, 4);
+    int i, j;
+
+    if (pic->data[0])
+        avctx->release_buffer(avctx, pic);
+
+    if (avpkt->size < 4 * avctx->height * aligned_width) {
+        av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
+        return AVERROR(EINVAL);
+    }
+
+    pic->reference = 0;
+
+    if (avctx->get_buffer(avctx, pic) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    pic->key_frame = 1;
+    pic->pict_type = AV_PICTURE_TYPE_I;
+
+    y = (uint16_t *)pic->data[0];
+    u = (uint16_t *)pic->data[1];
+    v = (uint16_t *)pic->data[2];
+
+    for (i = 0; i < avctx->height; i++) {
+        for (j = 0; j < avctx->width >> 1; j++) {
+            u[    j    ] = src[4 * j    ] << 2 | src[4 * j    ] >> 14;
+            y[2 * j    ] = src[4 * j + 1] << 2 | src[4 * j + 1] >> 14;
+            v[    j    ] = src[4 * j + 2] << 2 | src[4 * j + 2] >> 14;
+            y[2 * j + 1] = src[4 * j + 3] << 2 | src[4 * j + 3] >> 14;
+        }
+
+        y += pic->linesize[0] >> 1;
+        u += pic->linesize[1] >> 1;
+        v += pic->linesize[2] >> 1;
+        src += aligned_width << 1;
+    }
+
+    *data_size = sizeof(AVFrame);
+    *(AVFrame *)data = *pic;
+
+    return avpkt->size;
+}
+
+static av_cold int y216_decode_close(AVCodecContext *avctx)
+{
+    if (avctx->coded_frame->data[0])
+        avctx->release_buffer(avctx, avctx->coded_frame);
+
+    av_freep(&avctx->coded_frame);
+
+    return 0;
+}
+
+AVCodec ff_targa_y216_decoder = {
+    .name         = "targa_y216",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_TARGA_Y216,
+    .init         = y216_decode_init,
+    .decode       = y216_decode_frame,
+    .close        = y216_decode_close,
+    .capabilities = CODEC_CAP_DR1,
+    .long_name    = NULL_IF_CONFIG_SMALL("Pinnacle TARGA CineWave YUV16"),
+};
diff --git a/libavcodec/targaenc.c b/libavcodec/targaenc.c
index e13545f..b2c679d 100644
--- a/libavcodec/targaenc.c
+++ b/libavcodec/targaenc.c
@@ -2,20 +2,20 @@
  * Targa (.tga) image encoder
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -81,7 +81,7 @@
 static int targa_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                               const AVFrame *p, int *got_packet)
 {
-    int bpp, picsize, datasize = -1, ret;
+    int bpp, picsize, datasize = -1, ret, i;
     uint8_t *out;
 
     if(avctx->width > 0xffff || avctx->height > 0xffff) {
@@ -89,10 +89,8 @@
         return AVERROR(EINVAL);
     }
     picsize = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
-    if ((ret = ff_alloc_packet(pkt, picsize + 45)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, picsize + 45)) < 0)
         return ret;
-    }
 
     /* zero out the header and only set applicable fields */
     memset(pkt->data, 0, 12);
@@ -101,13 +99,39 @@
     /* image descriptor byte: origin is always top-left, bits 0-3 specify alpha */
     pkt->data[17] = 0x20 | (avctx->pix_fmt == AV_PIX_FMT_BGRA ? 8 : 0);
 
+    out = pkt->data + 18;  /* skip past the header we write */
+
+    avctx->bits_per_coded_sample = av_get_bits_per_pixel(av_pix_fmt_desc_get(avctx->pix_fmt));
     switch(avctx->pix_fmt) {
+    case AV_PIX_FMT_PAL8: {
+        int pal_bpp = 24; /* Only write 32bit palette if there is transparency information */
+        for (i = 0; i < 256; i++)
+            if (AV_RN32(p->data[1] + 4 * i) >> 24 != 0xFF) {
+                pal_bpp = 32;
+                break;
+            }
+        pkt->data[1]  = 1;          /* palette present */
+        pkt->data[2]  = TGA_PAL;    /* uncompressed palettised image */
+        pkt->data[6]  = 1;          /* palette contains 256 entries */
+        pkt->data[7]  = pal_bpp;    /* palette contains pal_bpp bit entries */
+        pkt->data[16] = 8;          /* bpp */
+        for (i = 0; i < 256; i++)
+            if (pal_bpp == 32) {
+                AV_WL32(pkt->data + 18 + 4 * i, *(uint32_t *)(p->data[1] + i * 4));
+            } else {
+            AV_WL24(pkt->data + 18 + 3 * i, *(uint32_t *)(p->data[1] + i * 4));
+            }
+        out += 32 * pal_bpp;        /* skip past the palette we just output */
+        break;
+        }
     case AV_PIX_FMT_GRAY8:
         pkt->data[2]  = TGA_BW;     /* uncompressed grayscale image */
+        avctx->bits_per_coded_sample = 0x28;
         pkt->data[16] = 8;          /* bpp */
         break;
     case AV_PIX_FMT_RGB555LE:
-        pkt->data[2]  = TGA_RGB;    /* uncompresses true-color image */
+        pkt->data[2]  = TGA_RGB;    /* uncompressed true-color image */
+        avctx->bits_per_coded_sample =
         pkt->data[16] = 16;         /* bpp */
         break;
     case AV_PIX_FMT_BGR24:
@@ -125,15 +149,13 @@
     }
     bpp = pkt->data[16] >> 3;
 
-    out = pkt->data + 18;  /* skip past the header we just output */
-
     /* try RLE compression */
     if (avctx->coder_type != FF_CODER_TYPE_RAW)
         datasize = targa_encode_rle(out, picsize, p, bpp, avctx->width, avctx->height);
 
     /* if that worked well, mark the picture as RLE compressed */
     if(datasize >= 0)
-        pkt->data[2] |= 8;
+        pkt->data[2] |= TGA_RLE;
 
     /* if RLE didn't make it smaller, go back to no compression */
     else datasize = targa_encode_normal(out, p, bpp, avctx->width, avctx->height);
@@ -172,7 +194,7 @@
     .init           = targa_encode_init,
     .encode2        = targa_encode_frame,
     .pix_fmts       = (const enum AVPixelFormat[]){
-        AV_PIX_FMT_BGR24, AV_PIX_FMT_BGRA, AV_PIX_FMT_RGB555LE, AV_PIX_FMT_GRAY8,
+        AV_PIX_FMT_BGR24, AV_PIX_FMT_BGRA, AV_PIX_FMT_RGB555LE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_PAL8,
         AV_PIX_FMT_NONE
     },
     .long_name= NULL_IF_CONFIG_SMALL("Truevision Targa image"),
diff --git a/libavcodec/thread.h b/libavcodec/thread.h
index 7f018fc..6de28a5 100644
--- a/libavcodec/thread.h
+++ b/libavcodec/thread.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Alexander Strange <astrange@ithinksw.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -43,7 +43,7 @@
  * Returns the next available frame in picture. *got_picture_ptr
  * will be 0 if none is available.
  * The return value on success is the size of the consumed packet for
- * compatiblity with avcodec_decode_video2(). This means the decoder
+ * compatibility with avcodec_decode_video2(). This means the decoder
  * has to consume the full packet.
  *
  * Parameters are the same as avcodec_decode_video2().
diff --git a/libavcodec/tiertexseqv.c b/libavcodec/tiertexseqv.c
index 98f6477..e6bf0fd 100644
--- a/libavcodec/tiertexseqv.c
+++ b/libavcodec/tiertexseqv.c
@@ -2,20 +2,20 @@
  * Tiertex Limited SEQ Video Decoder
  * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -178,7 +178,7 @@
         for (i = 0; i < 256; i++) {
             for (j = 0; j < 3; j++, data++)
                 c[j] = (*data << 2) | (*data >> 4);
-            palette[i] = AV_RB24(c);
+            palette[i] = 0xFF << 24 | AV_RB24(c);
         }
         seq->frame.palette_has_changed = 1;
     }
@@ -216,6 +216,7 @@
     seq->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
+    avcodec_get_frame_defaults(&seq->frame);
     seq->frame.data[0] = NULL;
 
     return 0;
@@ -230,10 +231,10 @@
 
     SeqVideoContext *seq = avctx->priv_data;
 
-    seq->frame.reference = 1;
+    seq->frame.reference = 3;
     seq->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
     if (avctx->reget_buffer(avctx, &seq->frame)) {
-        av_log(seq->avctx, AV_LOG_ERROR, "tiertexseqvideo: reget_buffer() failed\n");
+        av_log(seq->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
         return -1;
     }
 
diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c
index 48ce5c1..ed4670f 100644
--- a/libavcodec/tiff.c
+++ b/libavcodec/tiff.c
@@ -1,21 +1,20 @@
 /*
- * TIFF image decoder
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,21 +25,25 @@
  */
 
 #include "avcodec.h"
+#include "bytestream.h"
 #include "config.h"
 #if CONFIG_ZLIB
 #include <zlib.h>
 #endif
 #include "lzw.h"
 #include "tiff.h"
+#include "tiff_data.h"
 #include "faxcompr.h"
 #include "mathops.h"
 #include "libavutil/attributes.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
+#include "libavutil/avstring.h"
 
 typedef struct TiffContext {
     AVCodecContext *avctx;
     AVFrame picture;
+    GetByteContext gb;
 
     int width, height;
     unsigned int bpp, bppcount;
@@ -55,36 +58,276 @@
 
     int strips, rps, sstype;
     int sot;
-    const uint8_t *stripdata;
-    const uint8_t *stripsizes;
-    int stripsize, stripoff;
+    int stripsizesoff, stripsize, stripoff, strippos;
     LZWState *lzw;
+
+    int geotag_count;
+    TiffGeoTag *geotags;
 } TiffContext;
 
-static unsigned tget_short(const uint8_t **p, int le)
+static unsigned tget_short(GetByteContext *gb, int le)
 {
-    unsigned v = le ? AV_RL16(*p) : AV_RB16(*p);
-    *p += 2;
+    unsigned v = le ? bytestream2_get_le16u(gb) : bytestream2_get_be16u(gb);
     return v;
 }
 
-static unsigned tget_long(const uint8_t **p, int le)
+static unsigned tget_long(GetByteContext *gb, int le)
 {
-    unsigned v = le ? AV_RL32(*p) : AV_RB32(*p);
-    *p += 4;
+    unsigned v = le ? bytestream2_get_le32u(gb) : bytestream2_get_be32u(gb);
     return v;
 }
 
-static unsigned tget(const uint8_t **p, int type, int le)
+static double tget_double(GetByteContext *gb, int le)
+{
+    av_alias64 i = { .u64 = le ? bytestream2_get_le64u(gb) : bytestream2_get_be64u(gb)};
+    return i.f64;
+}
+
+static unsigned tget(GetByteContext *gb, int type, int le)
 {
     switch (type) {
-    case TIFF_BYTE : return *(*p)++;
-    case TIFF_SHORT: return tget_short(p, le);
-    case TIFF_LONG : return tget_long(p, le);
+    case TIFF_BYTE : return bytestream2_get_byteu(gb);
+    case TIFF_SHORT: return tget_short(gb, le);
+    case TIFF_LONG : return tget_long(gb, le);
     default        : return UINT_MAX;
     }
 }
 
+static void free_geotags(TiffContext *const s)
+{
+    int i;
+    for (i = 0; i < s->geotag_count; i++) {
+        if (s->geotags[i].val)
+            av_freep(&s->geotags[i].val);
+    }
+    av_freep(&s->geotags);
+}
+
+#define RET_GEOKEY(TYPE, array, element)\
+    if (key >= TIFF_##TYPE##_KEY_ID_OFFSET &&\
+        key - TIFF_##TYPE##_KEY_ID_OFFSET < FF_ARRAY_ELEMS(ff_tiff_##array##_name_type_map))\
+        return ff_tiff_##array##_name_type_map[key - TIFF_##TYPE##_KEY_ID_OFFSET].element;
+
+static const char *get_geokey_name(int key)
+{
+    RET_GEOKEY(VERT, vert, name);
+    RET_GEOKEY(PROJ, proj, name);
+    RET_GEOKEY(GEOG, geog, name);
+    RET_GEOKEY(CONF, conf, name);
+
+    return NULL;
+}
+
+static int get_geokey_type(int key)
+{
+    RET_GEOKEY(VERT, vert, type);
+    RET_GEOKEY(PROJ, proj, type);
+    RET_GEOKEY(GEOG, geog, type);
+    RET_GEOKEY(CONF, conf, type);
+
+    return AVERROR_INVALIDDATA;
+}
+
+static int cmp_id_key(const void *id, const void *k)
+{
+    return *(const int*)id - ((const TiffGeoTagKeyName*)k)->key;
+}
+
+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;
+}
+
+static char *get_geokey_val(int key, int val)
+{
+    char *ap;
+
+    if (val == TIFF_GEO_KEY_UNDEFINED)
+        return av_strdup("undefined");
+    if (val == TIFF_GEO_KEY_USER_DEFINED)
+        return av_strdup("User-Defined");
+
+#define RET_GEOKEY_VAL(TYPE, array)\
+    if (val >= TIFF_##TYPE##_OFFSET &&\
+        val - TIFF_##TYPE##_OFFSET < FF_ARRAY_ELEMS(ff_tiff_##array##_codes))\
+        return av_strdup(ff_tiff_##array##_codes[val - TIFF_##TYPE##_OFFSET]);
+
+    switch (key) {
+    case TIFF_GT_MODEL_TYPE_GEOKEY:
+        RET_GEOKEY_VAL(GT_MODEL_TYPE, gt_model_type);
+        break;
+    case TIFF_GT_RASTER_TYPE_GEOKEY:
+        RET_GEOKEY_VAL(GT_RASTER_TYPE, gt_raster_type);
+        break;
+    case TIFF_GEOG_LINEAR_UNITS_GEOKEY:
+    case TIFF_PROJ_LINEAR_UNITS_GEOKEY:
+    case TIFF_VERTICAL_UNITS_GEOKEY:
+        RET_GEOKEY_VAL(LINEAR_UNIT, linear_unit);
+        break;
+    case TIFF_GEOG_ANGULAR_UNITS_GEOKEY:
+    case TIFF_GEOG_AZIMUTH_UNITS_GEOKEY:
+        RET_GEOKEY_VAL(ANGULAR_UNIT, angular_unit);
+        break;
+    case TIFF_GEOGRAPHIC_TYPE_GEOKEY:
+        RET_GEOKEY_VAL(GCS_TYPE, gcs_type);
+        RET_GEOKEY_VAL(GCSE_TYPE, gcse_type);
+        break;
+    case TIFF_GEOG_GEODETIC_DATUM_GEOKEY:
+        RET_GEOKEY_VAL(GEODETIC_DATUM, geodetic_datum);
+        RET_GEOKEY_VAL(GEODETIC_DATUM_E, geodetic_datum_e);
+        break;
+    case TIFF_GEOG_ELLIPSOID_GEOKEY:
+        RET_GEOKEY_VAL(ELLIPSOID, ellipsoid);
+        break;
+    case TIFF_GEOG_PRIME_MERIDIAN_GEOKEY:
+        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));
+        break;
+    case TIFF_PROJECTION_GEOKEY:
+        return av_strdup(search_keyval(ff_tiff_projection_codes, FF_ARRAY_ELEMS(ff_tiff_projection_codes), val));
+        break;
+    case TIFF_PROJ_COORD_TRANS_GEOKEY:
+        RET_GEOKEY_VAL(COORD_TRANS, coord_trans);
+        break;
+    case TIFF_VERTICAL_CS_TYPE_GEOKEY:
+        RET_GEOKEY_VAL(VERT_CS, vert_cs);
+        RET_GEOKEY_VAL(ORTHO_VERT_CS, ortho_vert_cs);
+        break;
+
+    }
+
+    ap = av_malloc(14);
+    if (ap)
+        snprintf(ap, 14, "Unknown-%d", val);
+    return ap;
+}
+
+static char *doubles2str(double *dp, int count, const char *sep)
+{
+    int i;
+    char *ap, *ap0;
+    int component_len = 15 + strlen(sep);
+    if (!sep) sep = ", ";
+    ap = av_malloc(component_len * count);
+    if (!ap)
+        return NULL;
+    ap0   = ap;
+    ap[0] = '\0';
+    for (i = 0; i < count; i++) {
+        unsigned l = snprintf(ap, component_len, "%f%s", dp[i], sep);
+        if(l >= component_len) {
+            av_free(ap0);
+            return NULL;
+        }
+        ap += l;
+    }
+    ap0[strlen(ap0) - strlen(sep)] = '\0';
+    return ap0;
+}
+
+static char *shorts2str(int16_t *sp, int count, const char *sep)
+{
+    int i;
+    char *ap, *ap0;
+    if (!sep) sep = ", ";
+    ap = av_malloc((5 + strlen(sep)) * count);
+    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);
+        ap += l;
+    }
+    ap0[strlen(ap0) - strlen(sep)] = '\0';
+    return ap0;
+}
+
+static int add_doubles_metadata(int count,
+                                const char *name, const char *sep,
+                                TiffContext *s)
+{
+    char *ap;
+    int i;
+    double *dp;
+
+    if (count >= INT_MAX / sizeof(int64_t))
+        return AVERROR_INVALIDDATA;
+    if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int64_t))
+        return AVERROR_INVALIDDATA;
+
+    dp = av_malloc(count * sizeof(double));
+    if (!dp)
+        return AVERROR(ENOMEM);
+
+    for (i = 0; i < count; i++)
+        dp[i] = tget_double(&s->gb, s->le);
+    ap = doubles2str(dp, count, sep);
+    av_freep(&dp);
+    if (!ap)
+        return AVERROR(ENOMEM);
+    av_dict_set(&s->picture.metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
+    return 0;
+}
+
+static int add_shorts_metadata(int count, const char *name,
+                               const char *sep, TiffContext *s)
+{
+    char *ap;
+    int i;
+    int16_t *sp;
+
+    if (count >= INT_MAX / sizeof(int16_t))
+        return AVERROR_INVALIDDATA;
+    if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int16_t))
+        return AVERROR_INVALIDDATA;
+
+    sp = av_malloc(count * sizeof(int16_t));
+    if (!sp)
+        return AVERROR(ENOMEM);
+
+    for (i = 0; i < count; i++)
+        sp[i] = tget_short(&s->gb, s->le);
+    ap = shorts2str(sp, count, sep);
+    av_freep(&sp);
+    if (!ap)
+        return AVERROR(ENOMEM);
+    av_dict_set(&s->picture.metadata, name, ap, AV_DICT_DONT_STRDUP_VAL);
+    return 0;
+}
+
+static int add_string_metadata(int count, const char *name,
+                               TiffContext *s)
+{
+    char *value;
+
+    if (bytestream2_get_bytes_left(&s->gb) < count)
+        return AVERROR_INVALIDDATA;
+
+    value = av_malloc(count + 1);
+    if (!value)
+        return AVERROR(ENOMEM);
+
+    bytestream2_get_bufferu(&s->gb, value, count);
+    value[count] = 0;
+
+    av_dict_set(&s->picture.metadata, name, value, AV_DICT_DONT_STRDUP_VAL);
+    return 0;
+}
+
+static int add_metadata(int count, int type,
+                        const char *name, const char *sep, TiffContext *s)
+{
+    switch(type) {
+    case TIFF_DOUBLE: return add_doubles_metadata(count, name, sep, s);
+    case TIFF_SHORT : return add_shorts_metadata(count, name, sep, s);
+    case TIFF_STRING: return add_string_metadata(count, name, s);
+    default         : return AVERROR_INVALIDDATA;
+    };
+}
+
 #if CONFIG_ZLIB
 static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src,
                            int size)
@@ -92,7 +335,7 @@
     z_stream zstream = { 0 };
     int zret;
 
-    zstream.next_in = src;
+    zstream.next_in = (uint8_t *)src;
     zstream.avail_in = size;
     zstream.next_out = dst;
     zstream.avail_out = *len;
@@ -108,6 +351,46 @@
 }
 #endif
 
+static void av_always_inline horizontal_fill(unsigned int bpp, uint8_t* dst,
+                                             int usePtr, const uint8_t *src,
+                                             uint8_t c, int width, int offset)
+{
+    switch (bpp) {
+    case 1:
+        while (--width >= 0) {
+            dst[(width+offset)*8+7] = (usePtr ? src[width] : c)      & 0x1;
+            dst[(width+offset)*8+6] = (usePtr ? src[width] : c) >> 1 & 0x1;
+            dst[(width+offset)*8+5] = (usePtr ? src[width] : c) >> 2 & 0x1;
+            dst[(width+offset)*8+4] = (usePtr ? src[width] : c) >> 3 & 0x1;
+            dst[(width+offset)*8+3] = (usePtr ? src[width] : c) >> 4 & 0x1;
+            dst[(width+offset)*8+2] = (usePtr ? src[width] : c) >> 5 & 0x1;
+            dst[(width+offset)*8+1] = (usePtr ? src[width] : c) >> 6 & 0x1;
+            dst[(width+offset)*8+0] = (usePtr ? src[width] : c) >> 7;
+        }
+        break;
+    case 2:
+        while (--width >= 0) {
+            dst[(width+offset)*4+3] = (usePtr ? src[width] : c) & 0x3;
+            dst[(width+offset)*4+2] = (usePtr ? src[width] : c) >> 2 & 0x3;
+            dst[(width+offset)*4+1] = (usePtr ? src[width] : c) >> 4 & 0x3;
+            dst[(width+offset)*4+0] = (usePtr ? src[width] : c) >> 6;
+        }
+        break;
+    case 4:
+        while (--width >= 0) {
+            dst[(width+offset)*2+1] = (usePtr ? src[width] : c) & 0xF;
+            dst[(width+offset)*2+0] = (usePtr ? src[width] : c) >> 4;
+        }
+        break;
+    default:
+        if (usePtr) {
+            memcpy(dst + offset, src, width);
+        } else {
+            memset(dst + offset, c, width);
+        }
+    }
+}
+
 static int tiff_unpack_strip(TiffContext *s, uint8_t *dst, int stride,
                              const uint8_t *src, int size, int lines)
 {
@@ -137,7 +420,11 @@
         }
         src = zbuf;
         for (line = 0; line < lines; line++) {
-            memcpy(dst, src, width);
+            if(s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8){
+                horizontal_fill(s->bpp, dst, 1, src, 0, width, 0);
+            }else{
+                memcpy(dst, src, width);
+            }
             dst += stride;
             src += width;
         }
@@ -183,6 +470,11 @@
                                   s->compr, s->fax_opts);
             break;
         }
+        if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
+            for (line = 0; line < lines; line++) {
+                horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0);
+                dst += stride;
+            }
         av_free(src2);
         return ret;
     }
@@ -196,7 +488,8 @@
             if (ssrc + size - src < width)
                 return AVERROR_INVALIDDATA;
             if (!s->fill_order) {
-                memcpy(dst, src, width);
+                horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8),
+                                dst, 1, src, 0, width, 0);
             } else {
                 int i;
                 for (i = 0; i < width; i++)
@@ -206,6 +499,10 @@
             break;
         case TIFF_PACKBITS:
             for (pixels = 0; pixels < width;) {
+                if (ssrc + size - src < 2) {
+                    av_log(s->avctx, AV_LOG_ERROR, "Read went out of bounds\n");
+                    return AVERROR_INVALIDDATA;
+                }
                 code = (int8_t) * src++;
                 if (code >= 0) {
                     code++;
@@ -214,7 +511,12 @@
                                "Copy went out of bounds\n");
                         return -1;
                     }
-                    memcpy(dst + pixels, src, code);
+                    if (ssrc + size - src < code) {
+                        av_log(s->avctx, AV_LOG_ERROR, "Read went out of bounds\n");
+                        return AVERROR_INVALIDDATA;
+                    }
+                    horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8),
+                                    dst, 1, src, 0, code, pixels);
                     src += code;
                     pixels += code;
                 } else if (code != -128) { // -127..-1
@@ -225,7 +527,8 @@
                         return -1;
                     }
                     c = *src++;
-                    memset(dst + pixels, c, code);
+                    horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8),
+                                    dst, 0, NULL, c, code, pixels);
                     pixels += code;
                 }
             }
@@ -237,6 +540,8 @@
                        pixels, width);
                 return -1;
             }
+            if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
+                horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0);
             break;
         }
         dst += stride;
@@ -251,8 +556,12 @@
 
     switch (s->bpp * 10 + s->bppcount) {
     case 11:
-        s->avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
-        break;
+        if (!s->palette_is_set) {
+            s->avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
+            break;
+        }
+    case 21:
+    case 41:
     case 81:
         s->avctx->pix_fmt = AV_PIX_FMT_PAL8;
         break;
@@ -262,12 +571,18 @@
     case 161:
         s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GRAY16LE : AV_PIX_FMT_GRAY16BE;
         break;
+    case 162:
+        s->avctx->pix_fmt = AV_PIX_FMT_GRAY8A;
+        break;
     case 324:
         s->avctx->pix_fmt = AV_PIX_FMT_RGBA;
         break;
     case 483:
         s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGB48LE : AV_PIX_FMT_RGB48BE;
         break;
+    case 644:
+        s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGBA64LE : AV_PIX_FMT_RGBA64BE;
+        break;
     default:
         av_log(s->avctx, AV_LOG_ERROR,
                "This format is not supported (bpp=%d, bppcount=%d)\n",
@@ -291,27 +606,26 @@
         } else {
             /* make default grayscale pal */
             pal = (uint32_t *) s->picture.data[1];
-            for (i = 0; i < 256; i++)
-                pal[i] = i * 0x010101;
+            for (i = 0; i < 1<<s->bpp; i++)
+                pal[i] = 0xFF << 24 | i * 255 / ((1<<s->bpp) - 1) * 0x010101;
         }
     }
     return 0;
 }
 
-static int tiff_decode_tag(TiffContext *s, const uint8_t *start,
-                           const uint8_t *buf, const uint8_t *end_buf)
+static int tiff_decode_tag(TiffContext *s)
 {
     unsigned tag, type, count, off, value = 0;
-    int i, j;
+    int i, j, k, pos, start;
+    int ret;
     uint32_t *pal;
-    const uint8_t *rp, *gp, *bp;
+    double *dp;
 
-    if (end_buf - buf < 12)
-        return -1;
-    tag = tget_short(&buf, s->le);
-    type = tget_short(&buf, s->le);
-    count = tget_long(&buf, s->le);
-    off = tget_long(&buf, s->le);
+    tag   = tget_short(&s->gb, s->le);
+    type  = tget_short(&s->gb, s->le);
+    count = tget_long(&s->gb, s->le);
+    off   = tget_long(&s->gb, s->le);
+    start = bytestream2_tell(&s->gb);
 
     if (type == 0 || type >= FF_ARRAY_ELEMS(type_sizes)) {
         av_log(s->avctx, AV_LOG_DEBUG, "Unknown tiff type (%u) encountered\n",
@@ -323,37 +637,29 @@
         switch (type) {
         case TIFF_BYTE:
         case TIFF_SHORT:
-            buf -= 4;
-            value = tget(&buf, type, s->le);
-            buf = NULL;
+            bytestream2_seek(&s->gb, -4, SEEK_CUR);
+            value = tget(&s->gb, type, s->le);
             break;
         case TIFF_LONG:
             value = off;
-            buf = NULL;
             break;
         case TIFF_STRING:
             if (count <= 4) {
-                buf -= 4;
+                bytestream2_seek(&s->gb, -4, SEEK_CUR);
                 break;
             }
         default:
             value = UINT_MAX;
-            buf = start + off;
+            bytestream2_seek(&s->gb, off, SEEK_SET);
         }
     } else {
         if (count <= 4 && type_sizes[type] * count <= 4) {
-            buf -= 4;
+            bytestream2_seek(&s->gb, -4, SEEK_CUR);
         } else {
-            buf = start + off;
+            bytestream2_seek(&s->gb, off, SEEK_SET);
         }
     }
 
-    if (buf && (buf < start || buf > end_buf)) {
-        av_log(s->avctx, AV_LOG_ERROR,
-               "Tag referencing position outside the image\n");
-        return -1;
-    }
-
     switch (tag) {
     case TIFF_WIDTH:
         s->width = value;
@@ -380,8 +686,10 @@
             case TIFF_SHORT:
             case TIFF_LONG:
                 s->bpp = 0;
-                for (i = 0; i < count && buf < end_buf; i++)
-                    s->bpp += tget(&buf, type, s->le);
+                if (bytestream2_get_bytes_left(&s->gb) < type_sizes[type] * count)
+                    return -1;
+                for (i = 0; i < count; i++)
+                    s->bpp += tget(&s->gb, type, s->le);
                 break;
             default:
                 s->bpp = -1;
@@ -442,15 +750,15 @@
         break;
     case TIFF_STRIP_OFFS:
         if (count == 1) {
-            s->stripdata = NULL;
+            s->strippos = 0;
             s->stripoff = value;
         } else
-            s->stripdata = start + off;
+            s->strippos = off;
         s->strips = count;
         if (s->strips == 1)
             s->rps = s->height;
         s->sot = type;
-        if (s->stripdata > end_buf) {
+        if (s->strippos > bytestream2_size(&s->gb)) {
             av_log(s->avctx, AV_LOG_ERROR,
                    "Tag referencing position outside the image\n");
             return -1;
@@ -458,20 +766,27 @@
         break;
     case TIFF_STRIP_SIZE:
         if (count == 1) {
-            s->stripsizes = NULL;
+            s->stripsizesoff = 0;
             s->stripsize = value;
             s->strips = 1;
         } else {
-            s->stripsizes = start + off;
+            s->stripsizesoff = off;
         }
         s->strips = count;
         s->sstype = type;
-        if (s->stripsizes > end_buf) {
+        if (s->stripsizesoff > bytestream2_size(&s->gb)) {
             av_log(s->avctx, AV_LOG_ERROR,
                    "Tag referencing position outside the image\n");
             return -1;
         }
         break;
+    case TIFF_TILE_BYTE_COUNTS:
+    case TIFF_TILE_LENGTH:
+    case TIFF_TILE_OFFSETS:
+    case TIFF_TILE_WIDTH:
+        av_log(s->avctx, AV_LOG_ERROR, "Tiled images are not supported\n");
+        return AVERROR_PATCHWELCOME;
+        break;
     case TIFF_PREDICTOR:
         s->predictor = value;
         break;
@@ -503,17 +818,16 @@
     case TIFF_PAL:
         pal = (uint32_t *) s->palette;
         off = type_sizes[type];
-        if (count / 3 > 256 || end_buf - buf < count / 3 * off * 3)
+        if (count / 3 > 256 || bytestream2_get_bytes_left(&s->gb) < count / 3 * off * 3)
             return -1;
-        rp = buf;
-        gp = buf + count / 3 * off;
-        bp = buf + count / 3 * off * 2;
         off = (type_sizes[type] - 1) << 3;
-        for (i = 0; i < count / 3; i++) {
-            j  = (tget(&rp, type, s->le) >> off) << 16;
-            j |= (tget(&gp, type, s->le) >> off) << 8;
-            j |=  tget(&bp, type, s->le) >> off;
-            pal[i] = j;
+        for (k = 2; k >= 0; k--) {
+            for (i = 0; i < count / 3; i++) {
+                if (k == 2)
+                    pal[i] = 0xff << 24;
+                j =  (tget(&s->gb, type, s->le) >> off) << (k * 8);
+                pal[i] |= j;
+            }
         }
         s->palette_is_set = 1;
         break;
@@ -531,34 +845,163 @@
         if (s->compr == TIFF_G4)
             s->fax_opts = value;
         break;
+#define ADD_METADATA(count, name, sep)\
+    if (ret = add_metadata(count, type, name, sep, s) < 0) {\
+        av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");\
+        return ret;\
+    }
+    case TIFF_MODEL_PIXEL_SCALE:
+        ADD_METADATA(count, "ModelPixelScaleTag", NULL);
+        break;
+    case TIFF_MODEL_TRANSFORMATION:
+        ADD_METADATA(count, "ModelTransformationTag", NULL);
+        break;
+    case TIFF_MODEL_TIEPOINT:
+        ADD_METADATA(count, "ModelTiepointTag", NULL);
+        break;
+    case TIFF_GEO_KEY_DIRECTORY:
+        ADD_METADATA(1, "GeoTIFF_Version", NULL);
+        ADD_METADATA(2, "GeoTIFF_Key_Revision", ".");
+        s->geotag_count   = tget_short(&s->gb, s->le);
+        if (s->geotag_count > count / 4 - 1) {
+            s->geotag_count = count / 4 - 1;
+            av_log(s->avctx, AV_LOG_WARNING, "GeoTIFF key directory buffer shorter than specified\n");
+        }
+        if (bytestream2_get_bytes_left(&s->gb) < s->geotag_count * sizeof(int16_t) * 4)
+            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");
+            return AVERROR(ENOMEM);
+        }
+        for (i = 0; i < s->geotag_count; i++) {
+            s->geotags[i].key    = tget_short(&s->gb, s->le);
+            s->geotags[i].type   = tget_short(&s->gb, s->le);
+            s->geotags[i].count  = tget_short(&s->gb, s->le);
+
+            if (!s->geotags[i].type)
+                s->geotags[i].val  = get_geokey_val(s->geotags[i].key, tget_short(&s->gb, s->le));
+            else
+                s->geotags[i].offset = tget_short(&s->gb, s->le);
+        }
+        break;
+    case TIFF_GEO_DOUBLE_PARAMS:
+        if (count >= INT_MAX / sizeof(int64_t))
+            return AVERROR_INVALIDDATA;
+        if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int64_t))
+            return AVERROR_INVALIDDATA;
+        dp = av_malloc(count * sizeof(double));
+        if (!dp) {
+            av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
+            return AVERROR(ENOMEM);
+        }
+        for (i = 0; i < count; i++)
+            dp[i] = tget_double(&s->gb, s->le);
+        for (i = 0; i < s->geotag_count; i++) {
+            if (s->geotags[i].type == TIFF_GEO_DOUBLE_PARAMS) {
+                if (s->geotags[i].count == 0
+                    || s->geotags[i].offset + s->geotags[i].count > count) {
+                    av_log(s->avctx, AV_LOG_WARNING, "Invalid GeoTIFF key %d\n", s->geotags[i].key);
+                } else {
+                    char *ap = doubles2str(&dp[s->geotags[i].offset], s->geotags[i].count, ", ");
+                    if (!ap) {
+                        av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
+                        av_freep(&dp);
+                        return AVERROR(ENOMEM);
+                    }
+                    s->geotags[i].val = ap;
+                }
+            }
+        }
+        av_freep(&dp);
+        break;
+    case TIFF_GEO_ASCII_PARAMS:
+        pos = bytestream2_tell(&s->gb);
+        for (i = 0; i < s->geotag_count; i++) {
+            if (s->geotags[i].type == TIFF_GEO_ASCII_PARAMS) {
+                if (s->geotags[i].count == 0
+                    || s->geotags[i].offset +  s->geotags[i].count > count) {
+                    av_log(s->avctx, AV_LOG_WARNING, "Invalid GeoTIFF key %d\n", s->geotags[i].key);
+                } else {
+                    char *ap;
+
+                    bytestream2_seek(&s->gb, pos + s->geotags[i].offset, SEEK_SET);
+                    if (bytestream2_get_bytes_left(&s->gb) < s->geotags[i].count)
+                        return -1;
+                    ap = av_malloc(s->geotags[i].count);
+                    if (!ap) {
+                        av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
+                        return AVERROR(ENOMEM);
+                    }
+                    bytestream2_get_bufferu(&s->gb, ap, s->geotags[i].count);
+                    ap[s->geotags[i].count - 1] = '\0'; //replace the "|" delimiter with a 0 byte
+                    s->geotags[i].val = ap;
+                }
+            }
+        }
+        break;
+    case TIFF_ARTIST:
+        ADD_METADATA(count, "artist", NULL);
+        break;
+    case TIFF_COPYRIGHT:
+        ADD_METADATA(count, "copyright", NULL);
+        break;
+    case TIFF_DATE:
+        ADD_METADATA(count, "date", NULL);
+        break;
+    case TIFF_DOCUMENT_NAME:
+        ADD_METADATA(count, "document_name", NULL);
+        break;
+    case TIFF_HOST_COMPUTER:
+        ADD_METADATA(count, "computer", NULL);
+        break;
+    case TIFF_IMAGE_DESCRIPTION:
+        ADD_METADATA(count, "description", NULL);
+        break;
+    case TIFF_MAKE:
+        ADD_METADATA(count, "make", NULL);
+        break;
+    case TIFF_MODEL:
+        ADD_METADATA(count, "model", NULL);
+        break;
+    case TIFF_PAGE_NAME:
+        ADD_METADATA(count, "page_name", NULL);
+        break;
+    case TIFF_PAGE_NUMBER:
+        ADD_METADATA(count, "page_number", " / ");
+        break;
+    case TIFF_SOFTWARE_NAME:
+        ADD_METADATA(count, "software", NULL);
+        break;
     default:
         av_log(s->avctx, AV_LOG_DEBUG, "Unknown or unsupported tag %d/0X%0X\n",
                tag, tag);
     }
+    bytestream2_seek(&s->gb, start, SEEK_SET);
     return 0;
 }
 
 static int decode_frame(AVCodecContext *avctx,
                         void *data, int *data_size, AVPacket *avpkt)
 {
-    const uint8_t *buf = avpkt->data;
-    int buf_size = avpkt->size;
     TiffContext *const s = avctx->priv_data;
     AVFrame *picture = data;
     AVFrame *const p = &s->picture;
-    const uint8_t *orig_buf = buf, *end_buf = buf + buf_size;
     unsigned off;
     int id, le, ret;
     int i, j, entries;
     int stride;
     unsigned soff, ssize;
     uint8_t *dst;
+    GetByteContext stripsizes;
+    GetByteContext stripdata;
+
+    bytestream2_init(&s->gb, avpkt->data, avpkt->size);
 
     //parse image header
-    if (end_buf - buf < 8)
+    if (avpkt->size < 8)
         return AVERROR_INVALIDDATA;
-    id = AV_RL16(buf);
-    buf += 2;
+    id = bytestream2_get_le16u(&s->gb);
     if (id == 0x4949)
         le = 1;
     else if (id == 0x4D4D)
@@ -568,32 +1011,57 @@
         return -1;
     }
     s->le = le;
+    // TIFF_BPP is not a required tag and defaults to 1
+    s->bppcount = s->bpp = 1;
     s->invert = 0;
     s->compr = TIFF_RAW;
     s->fill_order = 0;
+    free_geotags(s);
+    /* free existing metadata */
+    av_dict_free(&s->picture.metadata);
+
     // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number
     // that further identifies the file as a TIFF file"
-    if (tget_short(&buf, le) != 42) {
+    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;
     }
-    // Reset these pointers so we can tell if they were set this frame
-    s->stripsizes = s->stripdata = NULL;
+    // Reset these offsets so we can tell if they were set this frame
+    s->stripsizesoff = s->strippos = 0;
     /* parse image file directory */
-    off = tget_long(&buf, le);
-    if (off >= UINT_MAX - 14 || end_buf - orig_buf < off + 14) {
+    off = tget_long(&s->gb, le);
+    if (off >= UINT_MAX - 14 || avpkt->size < off + 14) {
         av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n");
         return AVERROR_INVALIDDATA;
     }
-    buf = orig_buf + off;
-    entries = tget_short(&buf, le);
+    bytestream2_seek(&s->gb, off, SEEK_SET);
+    entries = tget_short(&s->gb, le);
+    if (bytestream2_get_bytes_left(&s->gb) < entries * 12)
+        return AVERROR_INVALIDDATA;
     for (i = 0; i < entries; i++) {
-        if (tiff_decode_tag(s, orig_buf, buf, end_buf) < 0)
+        if (tiff_decode_tag(s) < 0)
             return -1;
-        buf += 12;
     }
-    if (!s->stripdata && !s->stripoff) {
+
+    for (i = 0; i<s->geotag_count; i++) {
+        const char *keyname = get_geokey_name(s->geotags[i].key);
+        if (!keyname) {
+            av_log(avctx, AV_LOG_WARNING, "Unknown or unsupported GeoTIFF key %d\n", s->geotags[i].key);
+            continue;
+        }
+        if (get_geokey_type(s->geotags[i].key) != s->geotags[i].type) {
+            av_log(avctx, AV_LOG_WARNING, "Type of GeoTIFF key %d is wrong\n", s->geotags[i].key);
+            continue;
+        }
+        ret = av_dict_set(&s->picture.metadata, keyname, s->geotags[i].val, 0);
+        if (ret<0) {
+            av_log(avctx, AV_LOG_ERROR, "Writing metadata with key '%s' failed\n", keyname);
+            return ret;
+        }
+    }
+
+    if (!s->strippos && !s->stripoff) {
         av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
         return -1;
     }
@@ -603,30 +1071,38 @@
 
     if (s->strips == 1 && !s->stripsize) {
         av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
-        s->stripsize = buf_size - s->stripoff;
+        s->stripsize = avpkt->size - s->stripoff;
     }
     stride = p->linesize[0];
     dst = p->data[0];
+
+    if (s->stripsizesoff) {
+        if (s->stripsizesoff >= avpkt->size)
+            return AVERROR_INVALIDDATA;
+        bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff, avpkt->size - s->stripsizesoff);
+    }
+    if (s->strippos) {
+        if (s->strippos >= avpkt->size)
+            return AVERROR_INVALIDDATA;
+        bytestream2_init(&stripdata, avpkt->data + s->strippos, avpkt->size - s->strippos);
+    }
+
     for (i = 0; i < s->height; i += s->rps) {
-        if (s->stripsizes) {
-            if (s->stripsizes >= end_buf)
-                return AVERROR_INVALIDDATA;
-            ssize = tget(&s->stripsizes, s->sstype, s->le);
-        } else
+        if (s->stripsizesoff)
+            ssize = tget(&stripsizes, s->sstype, s->le);
+        else
             ssize = s->stripsize;
 
-        if (s->stripdata) {
-            if (s->stripdata >= end_buf)
-                return AVERROR_INVALIDDATA;
-            soff = tget(&s->stripdata, s->sot, s->le);
-        } else
+        if (s->strippos)
+            soff = tget(&stripdata, s->sot, s->le);
+        else
             soff = s->stripoff;
 
-        if (soff > buf_size || ssize > buf_size - soff) {
+        if (soff > avpkt->size || ssize > avpkt->size - soff) {
             av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n");
             return -1;
         }
-        if (tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize,
+        if (tiff_unpack_strip(s, dst, stride, avpkt->data + soff, ssize,
                               FFMIN(s->rps, s->height - i)) < 0)
             break;
         dst += s->rps * stride;
@@ -635,28 +1111,41 @@
         dst = p->data[0];
         soff = s->bpp >> 3;
         ssize = s->width * soff;
-        for (i = 0; i < s->height; i++) {
-            for (j = soff; j < ssize; j++)
-                dst[j] += dst[j - soff];
-            dst += stride;
+        if (s->avctx->pix_fmt == AV_PIX_FMT_RGB48LE ||
+            s->avctx->pix_fmt == AV_PIX_FMT_RGBA64LE) {
+            for (i = 0; i < s->height; i++) {
+                for (j = soff; j < ssize; j += 2)
+                    AV_WL16(dst + j, AV_RL16(dst + j) + AV_RL16(dst + j - soff));
+                dst += stride;
+            }
+        } else if (s->avctx->pix_fmt == AV_PIX_FMT_RGB48BE ||
+                   s->avctx->pix_fmt == AV_PIX_FMT_RGBA64BE) {
+            for (i = 0; i < s->height; i++) {
+                for (j = soff; j < ssize; j += 2)
+                    AV_WB16(dst + j, AV_RB16(dst + j) + AV_RB16(dst + j - soff));
+                dst += stride;
+            }
+        } else {
+            for (i = 0; i < s->height; i++) {
+                for (j = soff; j < ssize; j++)
+                    dst[j] += dst[j - soff];
+                dst += stride;
+            }
         }
     }
 
     if (s->invert) {
-        uint8_t *src;
-        int j;
-
-        src = s->picture.data[0];
-        for (j = 0; j < s->height; j++) {
-            for (i = 0; i < s->picture.linesize[0]; i++)
-                src[i] = 255 - src[i];
-            src += s->picture.linesize[0];
+        dst = s->picture.data[0];
+        for (i = 0; i < s->height; i++) {
+            for (j = 0; j < s->picture.linesize[0]; j++)
+                dst[j] = (s->avctx->pix_fmt == AV_PIX_FMT_PAL8 ? (1<<s->bpp) - 1 : 255) - dst[j];
+            dst += s->picture.linesize[0];
         }
     }
     *picture   = s->picture;
     *data_size = sizeof(AVPicture);
 
-    return buf_size;
+    return avpkt->size;
 }
 
 static av_cold int tiff_init(AVCodecContext *avctx)
@@ -678,6 +1167,10 @@
 {
     TiffContext *const s = avctx->priv_data;
 
+    free_geotags(s);
+    if (avctx->coded_frame && avctx->coded_frame->metadata)
+        av_dict_free(&avctx->coded_frame->metadata);
+
     ff_lzw_decode_close(&s->lzw);
     if (s->picture.data[0])
         avctx->release_buffer(avctx, &s->picture);
diff --git a/libavcodec/tiff.h b/libavcodec/tiff.h
index cf890d6..6d760f0 100644
--- a/libavcodec/tiff.h
+++ b/libavcodec/tiff.h
@@ -1,27 +1,29 @@
 /*
- * TIFF tables
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
  * @file
  * TIFF tables
+ *
+ * For more information about the TIFF format, check the official docs at:
+ * http://partners.adobe.com/public/developer/tiff/index.html
  * @author Konstantin Shishkov
  */
 
@@ -39,6 +41,10 @@
     TIFF_COMPR,
     TIFF_INVERT = 0x106,
     TIFF_FILL_ORDER = 0x10A,
+    TIFF_DOCUMENT_NAME = 0x10D,
+    TIFF_IMAGE_DESCRIPTION = 0x10E,
+    TIFF_MAKE = 0x10F,
+    TIFF_MODEL = 0x110,
     TIFF_STRIP_OFFS = 0x111,
     TIFF_SAMPLES_PER_PIXEL = 0x115,
     TIFF_ROWSPERSTRIP = 0x116,
@@ -46,18 +52,35 @@
     TIFF_XRES = 0x11A,
     TIFF_YRES = 0x11B,
     TIFF_PLANAR = 0x11C,
+    TIFF_PAGE_NAME = 0x11D,
     TIFF_XPOS = 0x11E,
     TIFF_YPOS = 0x11F,
     TIFF_T4OPTIONS = 0x124,
     TIFF_T6OPTIONS,
     TIFF_RES_UNIT = 0x128,
+    TIFF_PAGE_NUMBER = 0x129,
     TIFF_SOFTWARE_NAME = 0x131,
+    TIFF_DATE = 0x132,
+    TIFF_ARTIST = 0x13B,
+    TIFF_HOST_COMPUTER = 0x13C,
     TIFF_PREDICTOR = 0x13D,
     TIFF_PAL = 0x140,
+    TIFF_TILE_WIDTH = 0x142,
+    TIFF_TILE_LENGTH = 0x143,
+    TIFF_TILE_OFFSETS = 0x144,
+    TIFF_TILE_BYTE_COUNTS = 0x145,
+    TIFF_EXTRASAMPLES = 0x152,
     TIFF_YCBCR_COEFFICIENTS = 0x211,
     TIFF_YCBCR_SUBSAMPLING = 0x212,
     TIFF_YCBCR_POSITIONING = 0x213,
     TIFF_REFERENCE_BW = 0x214,
+    TIFF_COPYRIGHT = 0x8298,
+    TIFF_MODEL_TIEPOINT = 0x8482,
+    TIFF_MODEL_PIXEL_SCALE = 0x830E,
+    TIFF_MODEL_TRANSFORMATION = 0x8480,
+    TIFF_GEO_KEY_DIRECTORY = 0x87AF,
+    TIFF_GEO_DOUBLE_PARAMS = 0x87B0,
+    TIFF_GEO_ASCII_PARAMS = 0x87B1
 };
 
 /** list of TIFF compression types */
@@ -80,11 +103,91 @@
     TIFF_SHORT,
     TIFF_LONG,
     TIFF_RATIONAL,
+    TIFF_SBYTE,
+    TIFF_UNDEFINED,
+    TIFF_SSHORT,
+    TIFF_SLONG,
+    TIFF_SRATIONAL,
+    TIFF_FLOAT,
+    TIFF_DOUBLE,
+    TIFF_IFD
+};
+
+enum TiffGeoTagKey {
+    TIFF_GT_MODEL_TYPE_GEOKEY                = 1024,
+    TIFF_GT_RASTER_TYPE_GEOKEY               = 1025,
+    TIFF_GT_CITATION_GEOKEY                  = 1026,
+    TIFF_GEOGRAPHIC_TYPE_GEOKEY              = 2048,
+    TIFF_GEOG_CITATION_GEOKEY                = 2049,
+    TIFF_GEOG_GEODETIC_DATUM_GEOKEY          = 2050,
+    TIFF_GEOG_PRIME_MERIDIAN_GEOKEY          = 2051,
+    TIFF_GEOG_LINEAR_UNITS_GEOKEY            = 2052,
+    TIFF_GEOG_LINEAR_UNIT_SIZE_GEOKEY        = 2053,
+    TIFF_GEOG_ANGULAR_UNITS_GEOKEY           = 2054,
+    TIFF_GEOG_ANGULAR_UNIT_SIZE_GEOKEY       = 2055,
+    TIFF_GEOG_ELLIPSOID_GEOKEY               = 2056,
+    TIFF_GEOG_SEMI_MAJOR_AXIS_GEOKEY         = 2057,
+    TIFF_GEOG_SEMI_MINOR_AXIS_GEOKEY         = 2058,
+    TIFF_GEOG_INV_FLATTENING_GEOKEY          = 2059,
+    TIFF_GEOG_AZIMUTH_UNITS_GEOKEY           = 2060,
+    TIFF_GEOG_PRIME_MERIDIAN_LONG_GEOKEY     = 2061,
+    TIFF_PROJECTED_CS_TYPE_GEOKEY            = 3072,
+    TIFF_PCS_CITATION_GEOKEY                 = 3073,
+    TIFF_PROJECTION_GEOKEY                   = 3074,
+    TIFF_PROJ_COORD_TRANS_GEOKEY             = 3075,
+    TIFF_PROJ_LINEAR_UNITS_GEOKEY            = 3076,
+    TIFF_PROJ_LINEAR_UNIT_SIZE_GEOKEY        = 3077,
+    TIFF_PROJ_STD_PARALLEL1_GEOKEY           = 3078,
+    TIFF_PROJ_STD_PARALLEL2_GEOKEY           = 3079,
+    TIFF_PROJ_NAT_ORIGIN_LONG_GEOKEY         = 3080,
+    TIFF_PROJ_NAT_ORIGIN_LAT_GEOKEY          = 3081,
+    TIFF_PROJ_FALSE_EASTING_GEOKEY           = 3082,
+    TIFF_PROJ_FALSE_NORTHING_GEOKEY          = 3083,
+    TIFF_PROJ_FALSE_ORIGIN_LONG_GEOKEY       = 3084,
+    TIFF_PROJ_FALSE_ORIGIN_LAT_GEOKEY        = 3085,
+    TIFF_PROJ_FALSE_ORIGIN_EASTING_GEOKEY    = 3086,
+    TIFF_PROJ_FALSE_ORIGIN_NORTHING_GEOKEY   = 3087,
+    TIFF_PROJ_CENTER_LONG_GEOKEY             = 3088,
+    TIFF_PROJ_CENTER_LAT_GEOKEY              = 3089,
+    TIFF_PROJ_CENTER_EASTING_GEOKEY          = 3090,
+    TIFF_PROJ_CENTER_NORTHING_GEOKEY         = 3091,
+    TIFF_PROJ_SCALE_AT_NAT_ORIGIN_GEOKEY     = 3092,
+    TIFF_PROJ_SCALE_AT_CENTER_GEOKEY         = 3093,
+    TIFF_PROJ_AZIMUTH_ANGLE_GEOKEY           = 3094,
+    TIFF_PROJ_STRAIGHT_VERT_POLE_LONG_GEOKEY = 3095,
+    TIFF_VERTICAL_CS_TYPE_GEOKEY             = 4096,
+    TIFF_VERTICAL_CITATION_GEOKEY            = 4097,
+    TIFF_VERTICAL_DATUM_GEOKEY               = 4098,
+    TIFF_VERTICAL_UNITS_GEOKEY               = 4099
+};
+
+enum TiffGeoTagType {
+    GEOTIFF_SHORT  = 0,
+    GEOTIFF_DOUBLE = 34736,
+    GEOTIFF_STRING = 34737
 };
 
 /** sizes of various TIFF field types (string size = 100)*/
-static const uint8_t type_sizes[6] = {
-    0, 1, 100, 2, 4, 8
+static const uint8_t type_sizes[14] = {
+    0, 1, 100, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4
 };
 
+typedef struct TiffGeoTag {
+    enum TiffGeoTagKey key;
+    enum TiffTags type;
+    int count;
+    int offset;
+    char *val;
+} TiffGeoTag;
+
+typedef struct TiffGeoTagKeyName {
+    const enum TiffGeoTagKey key;
+    const char *const name;
+} TiffGeoTagKeyName;
+
+typedef struct TiffGeoTagNameType {
+    const char *const name;
+    const enum TiffGeoTagType type;
+} TiffGeoTagNameType;
+
 #endif /* AVCODEC_TIFF_H */
diff --git a/libavcodec/tiff_data.c b/libavcodec/tiff_data.c
new file mode 100644
index 0000000..5bfe009
--- /dev/null
+++ b/libavcodec/tiff_data.c
@@ -0,0 +1,1870 @@
+/*
+ * TIFF data tables
+ * Copyright (c) 2011 Thomas Kuehnel
+ *
+ * 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
+ * TIFF data tables
+ * @author Thomas Kuehnel
+ * @see GeoTIFF specification at
+ * http://www.remotesensing.org/geotiff/spec/geotiffhome.html
+ */
+
+#include "tiff_data.h"
+
+const TiffGeoTagNameType ff_tiff_conf_name_type_map[] = {
+    {"GTModelTypeGeoKey",              GEOTIFF_SHORT },
+    {"GTRasterTypeGeoKey",             GEOTIFF_SHORT },
+    {"GTCitationGeoKey",               GEOTIFF_STRING}
+};
+
+const TiffGeoTagNameType ff_tiff_geog_name_type_map[] = {
+    {"GeographicTypeGeoKey",           GEOTIFF_SHORT },
+    {"GeogCitationGeoKey",             GEOTIFF_STRING},
+    {"GeogGeodeticDatumGeoKey",        GEOTIFF_SHORT },
+    {"GeogPrimeMeridianGeoKey",        GEOTIFF_SHORT },
+    {"GeogLinearUnitsGeoKey",          GEOTIFF_SHORT },
+    {"GeogLinearUnitSizeGeoKey",       GEOTIFF_DOUBLE},
+    {"GeogAngularUnitsGeoKey",         GEOTIFF_SHORT },
+    {"GeogAngularUnitSizeGeoKey",      GEOTIFF_DOUBLE},
+    {"GeogEllipsoidGeoKey",            GEOTIFF_SHORT },
+    {"GeogSemiMajorAxisGeoKey",        GEOTIFF_DOUBLE},
+    {"GeogSemiMinorAxisGeoKey",        GEOTIFF_DOUBLE},
+    {"GeogInvFlatteningGeoKey",        GEOTIFF_DOUBLE},
+    {"GeogAzimuthUnitsGeoKey",         GEOTIFF_SHORT },
+    {"GeogPrimeMeridianLongGeoKey",    GEOTIFF_DOUBLE}
+};
+
+const TiffGeoTagNameType ff_tiff_proj_name_type_map[] = {
+    {"ProjectedCSTypeGeoKey",          GEOTIFF_SHORT },
+    {"PCSCitationGeoKey",              GEOTIFF_STRING},
+    {"ProjectionGeoKey",               GEOTIFF_SHORT },
+    {"ProjCoordTransGeoKey",           GEOTIFF_SHORT },
+    {"ProjLinearUnitsGeoKey",          GEOTIFF_SHORT },
+    {"ProjLinearUnitSizeGeoKey",       GEOTIFF_DOUBLE},
+    {"ProjStdParallel1GeoKey",         GEOTIFF_DOUBLE},
+    {"ProjStdParallel2GeoKey",         GEOTIFF_DOUBLE},
+    {"ProjNatOriginLongGeoKey",        GEOTIFF_DOUBLE},
+    {"ProjNatOriginLatGeoKey",         GEOTIFF_DOUBLE},
+    {"ProjFalseEastingGeoKey",         GEOTIFF_DOUBLE},
+    {"ProjFalseNorthingGeoKey",        GEOTIFF_DOUBLE},
+    {"ProjFalseOriginLongGeoKey",      GEOTIFF_DOUBLE},
+    {"ProjFalseOriginLatGeoKey",       GEOTIFF_DOUBLE},
+    {"ProjFalseOriginEastingGeoKey",   GEOTIFF_DOUBLE},
+    {"ProjFalseOriginNorthingGeoKey",  GEOTIFF_DOUBLE},
+    {"ProjCenterLongGeoKey",           GEOTIFF_DOUBLE},
+    {"ProjCenterLatGeoKey",            GEOTIFF_DOUBLE},
+    {"ProjCenterEastingGeoKey",        GEOTIFF_DOUBLE},
+    {"ProjCenterNorthingGeoKey",       GEOTIFF_DOUBLE},
+    {"ProjScaleAtNatOriginGeoKey",     GEOTIFF_DOUBLE},
+    {"ProjScaleAtCenterGeoKey",        GEOTIFF_DOUBLE},
+    {"ProjAzimuthAngleGeoKey",         GEOTIFF_DOUBLE},
+    {"ProjStraightVertPoleLongGeoKey", GEOTIFF_DOUBLE}
+};
+
+const TiffGeoTagNameType ff_tiff_vert_name_type_map[] = {
+    {"VerticalCSTypeGeoKey",           GEOTIFF_SHORT },
+    {"VerticalCitationGeoKey",         GEOTIFF_STRING},
+    {"VerticalDatumGeoKey",            GEOTIFF_SHORT },
+    {"VerticalUnitsGeoKey",            GEOTIFF_SHORT }
+};
+
+const char *const ff_tiff_gt_model_type_codes[] = {
+    "ModelTypeProjected",
+    "ModelTypeGeographic",
+    "ModelTypeGeocentric"
+};
+
+const char *const ff_tiff_gt_raster_type_codes[] = {
+    "RasterPixelIsArea",
+    "RasterPixelIsPoint"
+};
+
+const char *const ff_tiff_linear_unit_codes[] = {
+    "Linear_Meter",
+    "Linear_Foot",
+    "Linear_Foot_US_Survey",
+    "Linear_Foot_Modified_American",
+    "Linear_Foot_Clarke",
+    "Linear_Foot_Indian",
+    "Linear_Link",
+    "Linear_Link_Benoit",
+    "Linear_Link_Sears",
+    "Linear_Chain_Benoit",
+    "Linear_Chain_Sears",
+    "Linear_Yard_Sears",
+    "Linear_Yard_Indian",
+    "Linear_Fathom",
+    "Linear_Mile_International_Nautical"
+};
+
+const char *const ff_tiff_angular_unit_codes[] = {
+    "Angular_Radian",
+    "Angular_Degree",
+    "Angular_Arc_Minute",
+    "Angular_Arc_Second",
+    "Angular_Grad",
+    "Angular_Gon",
+    "Angular_DMS",
+    "Angular_DMS_Hemisphere"
+};
+
+const char *const ff_tiff_gcs_type_codes[] = {
+    "GCS_Adindan",
+    "GCS_AGD66",
+    "GCS_AGD84",
+    "GCS_Ain_el_Abd",
+    "GCS_Afgooye",
+    "GCS_Agadez",
+    "GCS_Lisbon",
+    "GCS_Aratu",
+    "GCS_Arc_1950",
+    "GCS_Arc_1960",
+    "GCS_Batavia",
+    "GCS_Barbados",
+    "GCS_Beduaram",
+    "GCS_Beijing_1954",
+    "GCS_Belge_1950",
+    "GCS_Bermuda_1957",
+    "GCS_Bern_1898",
+    "GCS_Bogota",
+    "GCS_Bukit_Rimpah",
+    "GCS_Camacupa",
+    "GCS_Campo_Inchauspe",
+    "GCS_Cape",
+    "GCS_Carthage",
+    "GCS_Chua",
+    "GCS_Corrego_Alegre",
+    "GCS_Cote_d_Ivoire",
+    "GCS_Deir_ez_Zor",
+    "GCS_Douala",
+    "GCS_Egypt_1907",
+    "GCS_ED50",
+    "GCS_ED87",
+    "GCS_Fahud",
+    "GCS_Gandajika_1970",
+    "GCS_Garoua",
+    "GCS_Guyane_Francaise",
+    "GCS_Hu_Tzu_Shan",
+    "GCS_HD72",
+    "GCS_ID74",
+    "GCS_Indian_1954",
+    "GCS_Indian_1975",
+    "GCS_Jamaica_1875",
+    "GCS_JAD69",
+    "GCS_Kalianpur",
+    "GCS_Kandawala",
+    "GCS_Kertau",
+    "GCS_KOC",
+    "GCS_La_Canoa",
+    "GCS_PSAD56",
+    "GCS_Lake",
+    "GCS_Leigon",
+    "GCS_Liberia_1964",
+    "GCS_Lome",
+    "GCS_Luzon_1911",
+    "GCS_Hito_XVIII_1963",
+    "GCS_Herat_North",
+    "GCS_Mahe_1971",
+    "GCS_Makassar",
+    "GCS_EUREF89",
+    "GCS_Malongo_1987",
+    "GCS_Manoca",
+    "GCS_Merchich",
+    "GCS_Massawa",
+    "GCS_Minna",
+    "GCS_Mhast",
+    "GCS_Monte_Mario",
+    "GCS_M_poraloko",
+    "GCS_NAD27",
+    "GCS_NAD_Michigan",
+    "GCS_NAD83",
+    "GCS_Nahrwan_1967",
+    "GCS_Naparima_1972",
+    "GCS_GD49",
+    "GCS_NGO_1948",
+    "GCS_Datum_73",
+    "GCS_NTF",
+    "GCS_NSWC_9Z_2",
+    "GCS_OSGB_1936",
+    "GCS_OSGB70",
+    "GCS_OS_SN80",
+    "GCS_Padang",
+    "GCS_Palestine_1923",
+    "GCS_Pointe_Noire",
+    "GCS_GDA94",
+    "GCS_Pulkovo_1942",
+    "GCS_Qatar",
+    "GCS_Qatar_1948",
+    "GCS_Qornoq",
+    "GCS_Loma_Quintana",
+    "GCS_Amersfoort",
+    "GCS_RT38",
+    "GCS_SAD69",
+    "GCS_Sapper_Hill_1943",
+    "GCS_Schwarzeck",
+    "GCS_Segora",
+    "GCS_Serindung",
+    "GCS_Sudan",
+    "GCS_Tananarive",
+    "GCS_Timbalai_1948",
+    "GCS_TM65",
+    "GCS_TM75",
+    "GCS_Tokyo",
+    "GCS_Trinidad_1903",
+    "GCS_TC_1948",
+    "GCS_Voirol_1875",
+    "GCS_Voirol_Unifie",
+    "GCS_Bern_1938",
+    "GCS_Nord_Sahara_1959",
+    "GCS_Stockholm_1938",
+    "GCS_Yacare",
+    "GCS_Yoff",
+    "GCS_Zanderij",
+    "GCS_MGI",
+    "GCS_Belge_1972",
+    "GCS_DHDN",
+    "GCS_Conakry_1905",
+    "GCS_WGS_72",
+    "GCS_WGS_72BE",
+    "GCS_WGS_84",
+    "GCS_Bern_1898_Bern",
+    "GCS_Bogota_Bogota",
+    "GCS_Lisbon_Lisbon",
+    "GCS_Makassar_Jakarta",
+    "GCS_MGI_Ferro",
+    "GCS_Monte_Mario_Rome",
+    "GCS_NTF_Paris",
+    "GCS_Padang_Jakarta",
+    "GCS_Belge_1950_Brussels",
+    "GCS_Tananarive_Paris",
+    "GCS_Voirol_1875_Paris",
+    "GCS_Voirol_Unifie_Paris",
+    "GCS_Batavia_Jakarta",
+    "GCS_ATF_Paris",
+    "GCS_NDG_Paris"
+};
+
+const char *const ff_tiff_gcse_type_codes[] = {
+    "GCSE_Airy1830",
+    "GCSE_AiryModified1849",
+    "GCSE_AustralianNationalSpheroid",
+    "GCSE_Bessel1841",
+    "GCSE_BesselModified",
+    "GCSE_BesselNamibia",
+    "GCSE_Clarke1858",
+    "GCSE_Clarke1866",
+    "GCSE_Clarke1866Michigan",
+    "GCSE_Clarke1880_Benoit",
+    "GCSE_Clarke1880_IGN",
+    "GCSE_Clarke1880_RGS",
+    "GCSE_Clarke1880_Arc",
+    "GCSE_Clarke1880_SGA1922",
+    "GCSE_Everest1830_1937Adjustment",
+    "GCSE_Everest1830_1967Definition",
+    "GCSE_Everest1830_1975Definition",
+    "GCSE_Everest1830Modified",
+    "GCSE_GRS1980",
+    "GCSE_Helmert1906",
+    "GCSE_IndonesianNationalSpheroid",
+    "GCSE_International1924",
+    "GCSE_International1967",
+    "GCSE_Krassowsky1940",
+    "GCSE_NWL9D",
+    "GCSE_NWL10D",
+    "GCSE_Plessis1817",
+    "GCSE_Struve1860",
+    "GCSE_WarOffice",
+    "GCSE_WGS84",
+    "GCSE_GEM10C",
+    "GCSE_OSU86F",
+    "GCSE_OSU91A",
+    "GCSE_Clarke1880",
+    "GCSE_Sphere"
+};
+
+const char *const ff_tiff_geodetic_datum_codes[] = {
+    "Datum_Adindan",
+    "Datum_Australian_Geodetic_Datum_1966",
+    "Datum_Australian_Geodetic_Datum_1984",
+    "Datum_Ain_el_Abd_1970",
+    "Datum_Afgooye",
+    "Datum_Agadez",
+    "Datum_Lisbon",
+    "Datum_Aratu",
+    "Datum_Arc_1950",
+    "Datum_Arc_1960",
+    "Datum_Batavia",
+    "Datum_Barbados",
+    "Datum_Beduaram",
+    "Datum_Beijing_1954",
+    "Datum_Reseau_National_Belge_1950",
+    "Datum_Bermuda_1957",
+    "Datum_Bern_1898",
+    "Datum_Bogota",
+    "Datum_Bukit_Rimpah",
+    "Datum_Camacupa",
+    "Datum_Campo_Inchauspe",
+    "Datum_Cape",
+    "Datum_Carthage",
+    "Datum_Chua",
+    "Datum_Corrego_Alegre",
+    "Datum_Cote_d_Ivoire",
+    "Datum_Deir_ez_Zor",
+    "Datum_Douala",
+    "Datum_Egypt_1907",
+    "Datum_European_Datum_1950",
+    "Datum_European_Datum_1987",
+    "Datum_Fahud",
+    "Datum_Gandajika_1970",
+    "Datum_Garoua",
+    "Datum_Guyane_Francaise",
+    "Datum_Hu_Tzu_Shan",
+    "Datum_Hungarian_Datum_1972",
+    "Datum_Indonesian_Datum_1974",
+    "Datum_Indian_1954",
+    "Datum_Indian_1975",
+    "Datum_Jamaica_1875",
+    "Datum_Jamaica_1969",
+    "Datum_Kalianpur",
+    "Datum_Kandawala",
+    "Datum_Kertau",
+    "Datum_Kuwait_Oil_Company",
+    "Datum_La_Canoa",
+    "Datum_Provisional_S_American_Datum_1956",
+    "Datum_Lake",
+    "Datum_Leigon",
+    "Datum_Liberia_1964",
+    "Datum_Lome",
+    "Datum_Luzon_1911",
+    "Datum_Hito_XVIII_1963",
+    "Datum_Herat_North",
+    "Datum_Mahe_1971",
+    "Datum_Makassar",
+    "Datum_European_Reference_System_1989",
+    "Datum_Malongo_1987",
+    "Datum_Manoca",
+    "Datum_Merchich",
+    "Datum_Massawa",
+    "Datum_Minna",
+    "Datum_Mhast",
+    "Datum_Monte_Mario",
+    "Datum_M_poraloko",
+    "Datum_North_American_Datum_1927",
+    "Datum_NAD_Michigan",
+    "Datum_North_American_Datum_1983",
+    "Datum_Nahrwan_1967",
+    "Datum_Naparima_1972",
+    "Datum_New_Zealand_Geodetic_Datum_1949",
+    "Datum_NGO_1948",
+    "Datum_Datum_73",
+    "Datum_Nouvelle_Triangulation_Francaise",
+    "Datum_NSWC_9Z_2",
+    "Datum_OSGB_1936",
+    "Datum_OSGB_1970_SN",
+    "Datum_OS_SN_1980",
+    "Datum_Padang_1884",
+    "Datum_Palestine_1923",
+    "Datum_Pointe_Noire",
+    "Datum_Geocentric_Datum_of_Australia_1994",
+    "Datum_Pulkovo_1942",
+    "Datum_Qatar",
+    "Datum_Qatar_1948",
+    "Datum_Qornoq",
+    "Datum_Loma_Quintana",
+    "Datum_Amersfoort",
+    "Datum_RT38",
+    "Datum_South_American_Datum_1969",
+    "Datum_Sapper_Hill_1943",
+    "Datum_Schwarzeck",
+    "Datum_Segora",
+    "Datum_Serindung",
+    "Datum_Sudan",
+    "Datum_Tananarive_1925",
+    "Datum_Timbalai_1948",
+    "Datum_TM65",
+    "Datum_TM75",
+    "Datum_Tokyo",
+    "Datum_Trinidad_1903",
+    "Datum_Trucial_Coast_1948",
+    "Datum_Voirol_1875",
+    "Datum_Voirol_Unifie_1960",
+    "Datum_Bern_1938",
+    "Datum_Nord_Sahara_1959",
+    "Datum_Stockholm_1938",
+    "Datum_Yacare",
+    "Datum_Yoff",
+    "Datum_Zanderij",
+    "Datum_Militar_Geographische_Institut",
+    "Datum_Reseau_National_Belge_1972",
+    "Datum_Deutsche_Hauptdreiecksnetz",
+    "Datum_Conakry_1905",
+    "Datum_WGS72",
+    "Datum_WGS72_Transit_Broadcast_Ephemeris",
+    "Datum_WGS84",
+    "Datum_Ancienne_Triangulation_Francaise",
+    "Datum_Nord_de_Guerre"
+};
+
+const char *const ff_tiff_geodetic_datum_e_codes[] = {
+    "DatumE_Airy1830",
+    "DatumE_AiryModified1849",
+    "DatumE_AustralianNationalSpheroid",
+    "DatumE_Bessel1841",
+    "DatumE_BesselModified",
+    "DatumE_BesselNamibia",
+    "DatumE_Clarke1858",
+    "DatumE_Clarke1866",
+    "DatumE_Clarke1866Michigan",
+    "DatumE_Clarke1880_Benoit",
+    "DatumE_Clarke1880_IGN",
+    "DatumE_Clarke1880_RGS",
+    "DatumE_Clarke1880_Arc",
+    "DatumE_Clarke1880_SGA1922",
+    "DatumE_Everest1830_1937Adjustment",
+    "DatumE_Everest1830_1967Definition",
+    "DatumE_Everest1830_1975Definition",
+    "DatumE_Everest1830Modified",
+    "DatumE_GRS1980",
+    "DatumE_Helmert1906",
+    "DatumE_IndonesianNationalSpheroid",
+    "DatumE_International1924",
+    "DatumE_International1967",
+    "DatumE_Krassowsky1960",
+    "DatumE_NWL9D",
+    "DatumE_NWL10D",
+    "DatumE_Plessis1817",
+    "DatumE_Struve1860",
+    "DatumE_WarOffice",
+    "DatumE_WGS84",
+    "DatumE_GEM10C",
+    "DatumE_OSU86F",
+    "DatumE_OSU91A",
+    "DatumE_Clarke1880",
+    "DatumE_Sphere"
+};
+
+const char *const ff_tiff_ellipsoid_codes[] = {
+    "Ellipse_Airy_1830",
+    "Ellipse_Airy_Modified_1849",
+    "Ellipse_Australian_National_Spheroid",
+    "Ellipse_Bessel_1841",
+    "Ellipse_Bessel_Modified",
+    "Ellipse_Bessel_Namibia",
+    "Ellipse_Clarke_1858",
+    "Ellipse_Clarke_1866",
+    "Ellipse_Clarke_1866_Michigan",
+    "Ellipse_Clarke_1880_Benoit",
+    "Ellipse_Clarke_1880_IGN",
+    "Ellipse_Clarke_1880_RGS",
+    "Ellipse_Clarke_1880_Arc",
+    "Ellipse_Clarke_1880_SGA_1922",
+    "Ellipse_Everest_1830_1937_Adjustment",
+    "Ellipse_Everest_1830_1967_Definition",
+    "Ellipse_Everest_1830_1975_Definition",
+    "Ellipse_Everest_1830_Modified",
+    "Ellipse_GRS_1980",
+    "Ellipse_Helmert_1906",
+    "Ellipse_Indonesian_National_Spheroid",
+    "Ellipse_International_1924",
+    "Ellipse_International_1967",
+    "Ellipse_Krassowsky_1940",
+    "Ellipse_NWL_9D",
+    "Ellipse_NWL_10D",
+    "Ellipse_Plessis_1817",
+    "Ellipse_Struve_1860",
+    "Ellipse_War_Office",
+    "Ellipse_WGS_84",
+    "Ellipse_GEM_10C",
+    "Ellipse_OSU86F",
+    "Ellipse_OSU91A",
+    "Ellipse_Clarke_1880",
+    "Ellipse_Sphere"
+};
+
+const char *const ff_tiff_prime_meridian_codes[] = {
+    "PM_Greenwich",
+    "PM_Lisbon",
+    "PM_Paris",
+    "PM_Bogota",
+    "PM_Madrid",
+    "PM_Rome",
+    "PM_Bern",
+    "PM_Jakarta",
+    "PM_Ferro",
+    "PM_Brussels",
+    "PM_Stockholm"
+};
+
+const TiffGeoTagKeyName ff_tiff_proj_cs_type_codes[] = {
+    {20137, "PCS_Adindan_UTM_zone_37N"},
+    {20138, "PCS_Adindan_UTM_zone_38N"},
+    {20248, "PCS_AGD66_AMG_zone_48"},
+    {20249, "PCS_AGD66_AMG_zone_49"},
+    {20250, "PCS_AGD66_AMG_zone_50"},
+    {20251, "PCS_AGD66_AMG_zone_51"},
+    {20252, "PCS_AGD66_AMG_zone_52"},
+    {20253, "PCS_AGD66_AMG_zone_53"},
+    {20254, "PCS_AGD66_AMG_zone_54"},
+    {20255, "PCS_AGD66_AMG_zone_55"},
+    {20256, "PCS_AGD66_AMG_zone_56"},
+    {20257, "PCS_AGD66_AMG_zone_57"},
+    {20258, "PCS_AGD66_AMG_zone_58"},
+    {20348, "PCS_AGD84_AMG_zone_48"},
+    {20349, "PCS_AGD84_AMG_zone_49"},
+    {20350, "PCS_AGD84_AMG_zone_50"},
+    {20351, "PCS_AGD84_AMG_zone_51"},
+    {20352, "PCS_AGD84_AMG_zone_52"},
+    {20353, "PCS_AGD84_AMG_zone_53"},
+    {20354, "PCS_AGD84_AMG_zone_54"},
+    {20355, "PCS_AGD84_AMG_zone_55"},
+    {20356, "PCS_AGD84_AMG_zone_56"},
+    {20357, "PCS_AGD84_AMG_zone_57"},
+    {20358, "PCS_AGD84_AMG_zone_58"},
+    {20437, "PCS_Ain_el_Abd_UTM_zone_37N"},
+    {20438, "PCS_Ain_el_Abd_UTM_zone_38N"},
+    {20439, "PCS_Ain_el_Abd_UTM_zone_39N"},
+    {20499, "PCS_Ain_el_Abd_Bahrain_Grid"},
+    {20538, "PCS_Afgooye_UTM_zone_38N"},
+    {20539, "PCS_Afgooye_UTM_zone_39N"},
+    {20700, "PCS_Lisbon_Portugese_Grid"},
+    {20822, "PCS_Aratu_UTM_zone_22S"},
+    {20823, "PCS_Aratu_UTM_zone_23S"},
+    {20824, "PCS_Aratu_UTM_zone_24S"},
+    {20973, "PCS_Arc_1950_Lo13"},
+    {20975, "PCS_Arc_1950_Lo15"},
+    {20977, "PCS_Arc_1950_Lo17"},
+    {20979, "PCS_Arc_1950_Lo19"},
+    {20981, "PCS_Arc_1950_Lo21"},
+    {20983, "PCS_Arc_1950_Lo23"},
+    {20985, "PCS_Arc_1950_Lo25"},
+    {20987, "PCS_Arc_1950_Lo27"},
+    {20989, "PCS_Arc_1950_Lo29"},
+    {20991, "PCS_Arc_1950_Lo31"},
+    {20993, "PCS_Arc_1950_Lo33"},
+    {20995, "PCS_Arc_1950_Lo35"},
+    {21100, "PCS_Batavia_NEIEZ"},
+    {21148, "PCS_Batavia_UTM_zone_48S"},
+    {21149, "PCS_Batavia_UTM_zone_49S"},
+    {21150, "PCS_Batavia_UTM_zone_50S"},
+    {21413, "PCS_Beijing_Gauss_zone_13"},
+    {21414, "PCS_Beijing_Gauss_zone_14"},
+    {21415, "PCS_Beijing_Gauss_zone_15"},
+    {21416, "PCS_Beijing_Gauss_zone_16"},
+    {21417, "PCS_Beijing_Gauss_zone_17"},
+    {21418, "PCS_Beijing_Gauss_zone_18"},
+    {21419, "PCS_Beijing_Gauss_zone_19"},
+    {21420, "PCS_Beijing_Gauss_zone_20"},
+    {21421, "PCS_Beijing_Gauss_zone_21"},
+    {21422, "PCS_Beijing_Gauss_zone_22"},
+    {21423, "PCS_Beijing_Gauss_zone_23"},
+    {21473, "PCS_Beijing_Gauss_13N"},
+    {21474, "PCS_Beijing_Gauss_14N"},
+    {21475, "PCS_Beijing_Gauss_15N"},
+    {21476, "PCS_Beijing_Gauss_16N"},
+    {21477, "PCS_Beijing_Gauss_17N"},
+    {21478, "PCS_Beijing_Gauss_18N"},
+    {21479, "PCS_Beijing_Gauss_19N"},
+    {21480, "PCS_Beijing_Gauss_20N"},
+    {21481, "PCS_Beijing_Gauss_21N"},
+    {21482, "PCS_Beijing_Gauss_22N"},
+    {21483, "PCS_Beijing_Gauss_23N"},
+    {21500, "PCS_Belge_Lambert_50"},
+    {21790, "PCS_Bern_1898_Swiss_Old"},
+    {21817, "PCS_Bogota_UTM_zone_17N"},
+    {21818, "PCS_Bogota_UTM_zone_18N"},
+    {21891, "PCS_Bogota_Colombia_3W"},
+    {21892, "PCS_Bogota_Colombia_Bogota"},
+    {21893, "PCS_Bogota_Colombia_3E"},
+    {21894, "PCS_Bogota_Colombia_6E"},
+    {22032, "PCS_Camacupa_UTM_32S"},
+    {22033, "PCS_Camacupa_UTM_33S"},
+    {22191, "PCS_C_Inchauspe_Argentina_1"},
+    {22192, "PCS_C_Inchauspe_Argentina_2"},
+    {22193, "PCS_C_Inchauspe_Argentina_3"},
+    {22194, "PCS_C_Inchauspe_Argentina_4"},
+    {22195, "PCS_C_Inchauspe_Argentina_5"},
+    {22196, "PCS_C_Inchauspe_Argentina_6"},
+    {22197, "PCS_C_Inchauspe_Argentina_7"},
+    {22332, "PCS_Carthage_UTM_zone_32N"},
+    {22391, "PCS_Carthage_Nord_Tunisie"},
+    {22392, "PCS_Carthage_Sud_Tunisie"},
+    {22523, "PCS_Corrego_Alegre_UTM_23S"},
+    {22524, "PCS_Corrego_Alegre_UTM_24S"},
+    {22832, "PCS_Douala_UTM_zone_32N"},
+    {22992, "PCS_Egypt_1907_Red_Belt"},
+    {22993, "PCS_Egypt_1907_Purple_Belt"},
+    {22994, "PCS_Egypt_1907_Ext_Purple"},
+    {23028, "PCS_ED50_UTM_zone_28N"},
+    {23029, "PCS_ED50_UTM_zone_29N"},
+    {23030, "PCS_ED50_UTM_zone_30N"},
+    {23031, "PCS_ED50_UTM_zone_31N"},
+    {23032, "PCS_ED50_UTM_zone_32N"},
+    {23033, "PCS_ED50_UTM_zone_33N"},
+    {23034, "PCS_ED50_UTM_zone_34N"},
+    {23035, "PCS_ED50_UTM_zone_35N"},
+    {23036, "PCS_ED50_UTM_zone_36N"},
+    {23037, "PCS_ED50_UTM_zone_37N"},
+    {23038, "PCS_ED50_UTM_zone_38N"},
+    {23239, "PCS_Fahud_UTM_zone_39N"},
+    {23240, "PCS_Fahud_UTM_zone_40N"},
+    {23433, "PCS_Garoua_UTM_zone_33N"},
+    {23846, "PCS_ID74_UTM_zone_46N"},
+    {23847, "PCS_ID74_UTM_zone_47N"},
+    {23848, "PCS_ID74_UTM_zone_48N"},
+    {23849, "PCS_ID74_UTM_zone_49N"},
+    {23850, "PCS_ID74_UTM_zone_50N"},
+    {23851, "PCS_ID74_UTM_zone_51N"},
+    {23852, "PCS_ID74_UTM_zone_52N"},
+    {23853, "PCS_ID74_UTM_zone_53N"},
+    {23886, "PCS_ID74_UTM_zone_46S"},
+    {23887, "PCS_ID74_UTM_zone_47S"},
+    {23888, "PCS_ID74_UTM_zone_48S"},
+    {23889, "PCS_ID74_UTM_zone_49S"},
+    {23890, "PCS_ID74_UTM_zone_50S"},
+    {23891, "PCS_ID74_UTM_zone_51S"},
+    {23892, "PCS_ID74_UTM_zone_52S"},
+    {23893, "PCS_ID74_UTM_zone_53S"},
+    {23894, "PCS_ID74_UTM_zone_54S"},
+    {23947, "PCS_Indian_1954_UTM_47N"},
+    {23948, "PCS_Indian_1954_UTM_48N"},
+    {24047, "PCS_Indian_1975_UTM_47N"},
+    {24048, "PCS_Indian_1975_UTM_48N"},
+    {24100, "PCS_Jamaica_1875_Old_Grid"},
+    {24200, "PCS_JAD69_Jamaica_Grid"},
+    {24370, "PCS_Kalianpur_India_0"},
+    {24371, "PCS_Kalianpur_India_I"},
+    {24372, "PCS_Kalianpur_India_IIa"},
+    {24373, "PCS_Kalianpur_India_IIIa"},
+    {24374, "PCS_Kalianpur_India_IVa"},
+    {24382, "PCS_Kalianpur_India_IIb"},
+    {24383, "PCS_Kalianpur_India_IIIb"},
+    {24384, "PCS_Kalianpur_India_IVb"},
+    {24500, "PCS_Kertau_Singapore_Grid"},
+    {24547, "PCS_Kertau_UTM_zone_47N"},
+    {24548, "PCS_Kertau_UTM_zone_48N"},
+    {24720, "PCS_La_Canoa_UTM_zone_20N"},
+    {24721, "PCS_La_Canoa_UTM_zone_21N"},
+    {24818, "PCS_PSAD56_UTM_zone_18N"},
+    {24819, "PCS_PSAD56_UTM_zone_19N"},
+    {24820, "PCS_PSAD56_UTM_zone_20N"},
+    {24821, "PCS_PSAD56_UTM_zone_21N"},
+    {24877, "PCS_PSAD56_UTM_zone_17S"},
+    {24878, "PCS_PSAD56_UTM_zone_18S"},
+    {24879, "PCS_PSAD56_UTM_zone_19S"},
+    {24880, "PCS_PSAD56_UTM_zone_20S"},
+    {24891, "PCS_PSAD56_Peru_west_zone"},
+    {24892, "PCS_PSAD56_Peru_central"},
+    {24893, "PCS_PSAD56_Peru_east_zone"},
+    {25000, "PCS_Leigon_Ghana_Grid"},
+    {25231, "PCS_Lome_UTM_zone_31N"},
+    {25391, "PCS_Luzon_Philippines_I"},
+    {25392, "PCS_Luzon_Philippines_II"},
+    {25393, "PCS_Luzon_Philippines_III"},
+    {25394, "PCS_Luzon_Philippines_IV"},
+    {25395, "PCS_Luzon_Philippines_V"},
+    {25700, "PCS_Makassar_NEIEZ"},
+    {25932, "PCS_Malongo_1987_UTM_32S"},
+    {26191, "PCS_Merchich_Nord_Maroc"},
+    {26192, "PCS_Merchich_Sud_Maroc"},
+    {26193, "PCS_Merchich_Sahara"},
+    {26237, "PCS_Massawa_UTM_zone_37N"},
+    {26331, "PCS_Minna_UTM_zone_31N"},
+    {26332, "PCS_Minna_UTM_zone_32N"},
+    {26391, "PCS_Minna_Nigeria_West"},
+    {26392, "PCS_Minna_Nigeria_Mid_Belt"},
+    {26393, "PCS_Minna_Nigeria_East"},
+    {26432, "PCS_Mhast_UTM_zone_32S"},
+    {26591, "PCS_Monte_Mario_Italy_1"},
+    {26592, "PCS_Monte_Mario_Italy_2"},
+    {26632, "PCS_M_poraloko_UTM_32N"},
+    {26692, "PCS_M_poraloko_UTM_32S"},
+    {26703, "PCS_NAD27_UTM_zone_3N"},
+    {26704, "PCS_NAD27_UTM_zone_4N"},
+    {26705, "PCS_NAD27_UTM_zone_5N"},
+    {26706, "PCS_NAD27_UTM_zone_6N"},
+    {26707, "PCS_NAD27_UTM_zone_7N"},
+    {26708, "PCS_NAD27_UTM_zone_8N"},
+    {26709, "PCS_NAD27_UTM_zone_9N"},
+    {26710, "PCS_NAD27_UTM_zone_10N"},
+    {26711, "PCS_NAD27_UTM_zone_11N"},
+    {26712, "PCS_NAD27_UTM_zone_12N"},
+    {26713, "PCS_NAD27_UTM_zone_13N"},
+    {26714, "PCS_NAD27_UTM_zone_14N"},
+    {26715, "PCS_NAD27_UTM_zone_15N"},
+    {26716, "PCS_NAD27_UTM_zone_16N"},
+    {26717, "PCS_NAD27_UTM_zone_17N"},
+    {26718, "PCS_NAD27_UTM_zone_18N"},
+    {26719, "PCS_NAD27_UTM_zone_19N"},
+    {26720, "PCS_NAD27_UTM_zone_20N"},
+    {26721, "PCS_NAD27_UTM_zone_21N"},
+    {26722, "PCS_NAD27_UTM_zone_22N"},
+    {26729, "PCS_NAD27_Alabama_East"},
+    {26730, "PCS_NAD27_Alabama_West"},
+    {26731, "PCS_NAD27_Alaska_zone_1"},
+    {26732, "PCS_NAD27_Alaska_zone_2"},
+    {26733, "PCS_NAD27_Alaska_zone_3"},
+    {26734, "PCS_NAD27_Alaska_zone_4"},
+    {26735, "PCS_NAD27_Alaska_zone_5"},
+    {26736, "PCS_NAD27_Alaska_zone_6"},
+    {26737, "PCS_NAD27_Alaska_zone_7"},
+    {26738, "PCS_NAD27_Alaska_zone_8"},
+    {26739, "PCS_NAD27_Alaska_zone_9"},
+    {26740, "PCS_NAD27_Alaska_zone_10"},
+    {26741, "PCS_NAD27_California_I"},
+    {26742, "PCS_NAD27_California_II"},
+    {26743, "PCS_NAD27_California_III"},
+    {26744, "PCS_NAD27_California_IV"},
+    {26745, "PCS_NAD27_California_V"},
+    {26746, "PCS_NAD27_California_VI"},
+    {26747, "PCS_NAD27_California_VII"},
+    {26748, "PCS_NAD27_Arizona_East"},
+    {26749, "PCS_NAD27_Arizona_Central"},
+    {26750, "PCS_NAD27_Arizona_West"},
+    {26751, "PCS_NAD27_Arkansas_North"},
+    {26752, "PCS_NAD27_Arkansas_South"},
+    {26753, "PCS_NAD27_Colorado_North"},
+    {26754, "PCS_NAD27_Colorado_Central"},
+    {26755, "PCS_NAD27_Colorado_South"},
+    {26756, "PCS_NAD27_Connecticut"},
+    {26757, "PCS_NAD27_Delaware"},
+    {26758, "PCS_NAD27_Florida_East"},
+    {26759, "PCS_NAD27_Florida_West"},
+    {26760, "PCS_NAD27_Florida_North"},
+    {26761, "PCS_NAD27_Hawaii_zone_1"},
+    {26762, "PCS_NAD27_Hawaii_zone_2"},
+    {26763, "PCS_NAD27_Hawaii_zone_3"},
+    {26764, "PCS_NAD27_Hawaii_zone_4"},
+    {26765, "PCS_NAD27_Hawaii_zone_5"},
+    {26766, "PCS_NAD27_Georgia_East"},
+    {26767, "PCS_NAD27_Georgia_West"},
+    {26768, "PCS_NAD27_Idaho_East"},
+    {26769, "PCS_NAD27_Idaho_Central"},
+    {26770, "PCS_NAD27_Idaho_West"},
+    {26771, "PCS_NAD27_Illinois_East"},
+    {26772, "PCS_NAD27_Illinois_West"},
+    {26773, "PCS_NAD27_Indiana_East"},
+    {26774, "PCS_NAD27_BLM_14N_feet"},
+    {26774, "PCS_NAD27_Indiana_West"},
+    {26775, "PCS_NAD27_BLM_15N_feet"},
+    {26775, "PCS_NAD27_Iowa_North"},
+    {26776, "PCS_NAD27_BLM_16N_feet"},
+    {26776, "PCS_NAD27_Iowa_South"},
+    {26777, "PCS_NAD27_BLM_17N_feet"},
+    {26777, "PCS_NAD27_Kansas_North"},
+    {26778, "PCS_NAD27_Kansas_South"},
+    {26779, "PCS_NAD27_Kentucky_North"},
+    {26780, "PCS_NAD27_Kentucky_South"},
+    {26781, "PCS_NAD27_Louisiana_North"},
+    {26782, "PCS_NAD27_Louisiana_South"},
+    {26783, "PCS_NAD27_Maine_East"},
+    {26784, "PCS_NAD27_Maine_West"},
+    {26785, "PCS_NAD27_Maryland"},
+    {26786, "PCS_NAD27_Massachusetts"},
+    {26787, "PCS_NAD27_Massachusetts_Is"},
+    {26788, "PCS_NAD27_Michigan_North"},
+    {26789, "PCS_NAD27_Michigan_Central"},
+    {26790, "PCS_NAD27_Michigan_South"},
+    {26791, "PCS_NAD27_Minnesota_North"},
+    {26792, "PCS_NAD27_Minnesota_Cent"},
+    {26793, "PCS_NAD27_Minnesota_South"},
+    {26794, "PCS_NAD27_Mississippi_East"},
+    {26795, "PCS_NAD27_Mississippi_West"},
+    {26796, "PCS_NAD27_Missouri_East"},
+    {26797, "PCS_NAD27_Missouri_Central"},
+    {26798, "PCS_NAD27_Missouri_West"},
+    {26801, "PCS_NAD_Michigan_Michigan_East"},
+    {26802, "PCS_NAD_Michigan_Michigan_Old_Central"},
+    {26803, "PCS_NAD_Michigan_Michigan_West"},
+    {26903, "PCS_NAD83_UTM_zone_3N"},
+    {26904, "PCS_NAD83_UTM_zone_4N"},
+    {26905, "PCS_NAD83_UTM_zone_5N"},
+    {26906, "PCS_NAD83_UTM_zone_6N"},
+    {26907, "PCS_NAD83_UTM_zone_7N"},
+    {26908, "PCS_NAD83_UTM_zone_8N"},
+    {26909, "PCS_NAD83_UTM_zone_9N"},
+    {26910, "PCS_NAD83_UTM_zone_10N"},
+    {26911, "PCS_NAD83_UTM_zone_11N"},
+    {26912, "PCS_NAD83_UTM_zone_12N"},
+    {26913, "PCS_NAD83_UTM_zone_13N"},
+    {26914, "PCS_NAD83_UTM_zone_14N"},
+    {26915, "PCS_NAD83_UTM_zone_15N"},
+    {26916, "PCS_NAD83_UTM_zone_16N"},
+    {26917, "PCS_NAD83_UTM_zone_17N"},
+    {26918, "PCS_NAD83_UTM_zone_18N"},
+    {26919, "PCS_NAD83_UTM_zone_19N"},
+    {26920, "PCS_NAD83_UTM_zone_20N"},
+    {26921, "PCS_NAD83_UTM_zone_21N"},
+    {26922, "PCS_NAD83_UTM_zone_22N"},
+    {26923, "PCS_NAD83_UTM_zone_23N"},
+    {26929, "PCS_NAD83_Alabama_East"},
+    {26930, "PCS_NAD83_Alabama_West"},
+    {26931, "PCS_NAD83_Alaska_zone_1"},
+    {26932, "PCS_NAD83_Alaska_zone_2"},
+    {26933, "PCS_NAD83_Alaska_zone_3"},
+    {26934, "PCS_NAD83_Alaska_zone_4"},
+    {26935, "PCS_NAD83_Alaska_zone_5"},
+    {26936, "PCS_NAD83_Alaska_zone_6"},
+    {26937, "PCS_NAD83_Alaska_zone_7"},
+    {26938, "PCS_NAD83_Alaska_zone_8"},
+    {26939, "PCS_NAD83_Alaska_zone_9"},
+    {26940, "PCS_NAD83_Alaska_zone_10"},
+    {26941, "PCS_NAD83_California_1"},
+    {26942, "PCS_NAD83_California_2"},
+    {26943, "PCS_NAD83_California_3"},
+    {26944, "PCS_NAD83_California_4"},
+    {26945, "PCS_NAD83_California_5"},
+    {26946, "PCS_NAD83_California_6"},
+    {26948, "PCS_NAD83_Arizona_East"},
+    {26949, "PCS_NAD83_Arizona_Central"},
+    {26950, "PCS_NAD83_Arizona_West"},
+    {26951, "PCS_NAD83_Arkansas_North"},
+    {26952, "PCS_NAD83_Arkansas_South"},
+    {26953, "PCS_NAD83_Colorado_North"},
+    {26954, "PCS_NAD83_Colorado_Central"},
+    {26955, "PCS_NAD83_Colorado_South"},
+    {26956, "PCS_NAD83_Connecticut"},
+    {26957, "PCS_NAD83_Delaware"},
+    {26958, "PCS_NAD83_Florida_East"},
+    {26959, "PCS_NAD83_Florida_West"},
+    {26960, "PCS_NAD83_Florida_North"},
+    {26961, "PCS_NAD83_Hawaii_zone_1"},
+    {26962, "PCS_NAD83_Hawaii_zone_2"},
+    {26963, "PCS_NAD83_Hawaii_zone_3"},
+    {26964, "PCS_NAD83_Hawaii_zone_4"},
+    {26965, "PCS_NAD83_Hawaii_zone_5"},
+    {26966, "PCS_NAD83_Georgia_East"},
+    {26967, "PCS_NAD83_Georgia_West"},
+    {26968, "PCS_NAD83_Idaho_East"},
+    {26969, "PCS_NAD83_Idaho_Central"},
+    {26970, "PCS_NAD83_Idaho_West"},
+    {26971, "PCS_NAD83_Illinois_East"},
+    {26972, "PCS_NAD83_Illinois_West"},
+    {26973, "PCS_NAD83_Indiana_East"},
+    {26974, "PCS_NAD83_Indiana_West"},
+    {26975, "PCS_NAD83_Iowa_North"},
+    {26976, "PCS_NAD83_Iowa_South"},
+    {26977, "PCS_NAD83_Kansas_North"},
+    {26978, "PCS_NAD83_Kansas_South"},
+    {26979, "PCS_NAD83_Kentucky_North"},
+    {26980, "PCS_NAD83_Kentucky_South"},
+    {26981, "PCS_NAD83_Louisiana_North"},
+    {26982, "PCS_NAD83_Louisiana_South"},
+    {26983, "PCS_NAD83_Maine_East"},
+    {26984, "PCS_NAD83_Maine_West"},
+    {26985, "PCS_NAD83_Maryland"},
+    {26986, "PCS_NAD83_Massachusetts"},
+    {26987, "PCS_NAD83_Massachusetts_Is"},
+    {26988, "PCS_NAD83_Michigan_North"},
+    {26989, "PCS_NAD83_Michigan_Central"},
+    {26990, "PCS_NAD83_Michigan_South"},
+    {26991, "PCS_NAD83_Minnesota_North"},
+    {26992, "PCS_NAD83_Minnesota_Cent"},
+    {26993, "PCS_NAD83_Minnesota_South"},
+    {26994, "PCS_NAD83_Mississippi_East"},
+    {26995, "PCS_NAD83_Mississippi_West"},
+    {26996, "PCS_NAD83_Missouri_East"},
+    {26997, "PCS_NAD83_Missouri_Central"},
+    {26998, "PCS_NAD83_Missouri_West"},
+    {27038, "PCS_Nahrwan_1967_UTM_38N"},
+    {27039, "PCS_Nahrwan_1967_UTM_39N"},
+    {27040, "PCS_Nahrwan_1967_UTM_40N"},
+    {27120, "PCS_Naparima_UTM_20N"},
+    {27200, "PCS_GD49_NZ_Map_Grid"},
+    {27291, "PCS_GD49_North_Island_Grid"},
+    {27292, "PCS_GD49_South_Island_Grid"},
+    {27429, "PCS_Datum_73_UTM_zone_29N"},
+    {27500, "PCS_ATF_Nord_de_Guerre"},
+    {27581, "PCS_NTF_France_I"},
+    {27582, "PCS_NTF_France_II"},
+    {27583, "PCS_NTF_France_III"},
+    {27591, "PCS_NTF_Nord_France"},
+    {27592, "PCS_NTF_Centre_France"},
+    {27593, "PCS_NTF_Sud_France"},
+    {27700, "PCS_British_National_Grid"},
+    {28232, "PCS_Point_Noire_UTM_32S"},
+    {28348, "PCS_GDA94_MGA_zone_48"},
+    {28349, "PCS_GDA94_MGA_zone_49"},
+    {28350, "PCS_GDA94_MGA_zone_50"},
+    {28351, "PCS_GDA94_MGA_zone_51"},
+    {28352, "PCS_GDA94_MGA_zone_52"},
+    {28353, "PCS_GDA94_MGA_zone_53"},
+    {28354, "PCS_GDA94_MGA_zone_54"},
+    {28355, "PCS_GDA94_MGA_zone_55"},
+    {28356, "PCS_GDA94_MGA_zone_56"},
+    {28357, "PCS_GDA94_MGA_zone_57"},
+    {28358, "PCS_GDA94_MGA_zone_58"},
+    {28404, "PCS_Pulkovo_Gauss_zone_4"},
+    {28405, "PCS_Pulkovo_Gauss_zone_5"},
+    {28406, "PCS_Pulkovo_Gauss_zone_6"},
+    {28407, "PCS_Pulkovo_Gauss_zone_7"},
+    {28408, "PCS_Pulkovo_Gauss_zone_8"},
+    {28409, "PCS_Pulkovo_Gauss_zone_9"},
+    {28410, "PCS_Pulkovo_Gauss_zone_10"},
+    {28411, "PCS_Pulkovo_Gauss_zone_11"},
+    {28412, "PCS_Pulkovo_Gauss_zone_12"},
+    {28413, "PCS_Pulkovo_Gauss_zone_13"},
+    {28414, "PCS_Pulkovo_Gauss_zone_14"},
+    {28415, "PCS_Pulkovo_Gauss_zone_15"},
+    {28416, "PCS_Pulkovo_Gauss_zone_16"},
+    {28417, "PCS_Pulkovo_Gauss_zone_17"},
+    {28418, "PCS_Pulkovo_Gauss_zone_18"},
+    {28419, "PCS_Pulkovo_Gauss_zone_19"},
+    {28420, "PCS_Pulkovo_Gauss_zone_20"},
+    {28421, "PCS_Pulkovo_Gauss_zone_21"},
+    {28422, "PCS_Pulkovo_Gauss_zone_22"},
+    {28423, "PCS_Pulkovo_Gauss_zone_23"},
+    {28424, "PCS_Pulkovo_Gauss_zone_24"},
+    {28425, "PCS_Pulkovo_Gauss_zone_25"},
+    {28426, "PCS_Pulkovo_Gauss_zone_26"},
+    {28427, "PCS_Pulkovo_Gauss_zone_27"},
+    {28428, "PCS_Pulkovo_Gauss_zone_28"},
+    {28429, "PCS_Pulkovo_Gauss_zone_29"},
+    {28430, "PCS_Pulkovo_Gauss_zone_30"},
+    {28431, "PCS_Pulkovo_Gauss_zone_31"},
+    {28432, "PCS_Pulkovo_Gauss_zone_32"},
+    {28464, "PCS_Pulkovo_Gauss_4N"},
+    {28465, "PCS_Pulkovo_Gauss_5N"},
+    {28466, "PCS_Pulkovo_Gauss_6N"},
+    {28467, "PCS_Pulkovo_Gauss_7N"},
+    {28468, "PCS_Pulkovo_Gauss_8N"},
+    {28469, "PCS_Pulkovo_Gauss_9N"},
+    {28470, "PCS_Pulkovo_Gauss_10N"},
+    {28471, "PCS_Pulkovo_Gauss_11N"},
+    {28472, "PCS_Pulkovo_Gauss_12N"},
+    {28473, "PCS_Pulkovo_Gauss_13N"},
+    {28474, "PCS_Pulkovo_Gauss_14N"},
+    {28475, "PCS_Pulkovo_Gauss_15N"},
+    {28476, "PCS_Pulkovo_Gauss_16N"},
+    {28477, "PCS_Pulkovo_Gauss_17N"},
+    {28478, "PCS_Pulkovo_Gauss_18N"},
+    {28479, "PCS_Pulkovo_Gauss_19N"},
+    {28480, "PCS_Pulkovo_Gauss_20N"},
+    {28481, "PCS_Pulkovo_Gauss_21N"},
+    {28482, "PCS_Pulkovo_Gauss_22N"},
+    {28483, "PCS_Pulkovo_Gauss_23N"},
+    {28484, "PCS_Pulkovo_Gauss_24N"},
+    {28485, "PCS_Pulkovo_Gauss_25N"},
+    {28486, "PCS_Pulkovo_Gauss_26N"},
+    {28487, "PCS_Pulkovo_Gauss_27N"},
+    {28488, "PCS_Pulkovo_Gauss_28N"},
+    {28489, "PCS_Pulkovo_Gauss_29N"},
+    {28490, "PCS_Pulkovo_Gauss_30N"},
+    {28491, "PCS_Pulkovo_Gauss_31N"},
+    {28492, "PCS_Pulkovo_Gauss_32N"},
+    {28600, "PCS_Qatar_National_Grid"},
+    {28991, "PCS_RD_Netherlands_Old"},
+    {28992, "PCS_RD_Netherlands_New"},
+    {29118, "PCS_SAD69_UTM_zone_18N"},
+    {29119, "PCS_SAD69_UTM_zone_19N"},
+    {29120, "PCS_SAD69_UTM_zone_20N"},
+    {29121, "PCS_SAD69_UTM_zone_21N"},
+    {29122, "PCS_SAD69_UTM_zone_22N"},
+    {29177, "PCS_SAD69_UTM_zone_17S"},
+    {29178, "PCS_SAD69_UTM_zone_18S"},
+    {29179, "PCS_SAD69_UTM_zone_19S"},
+    {29180, "PCS_SAD69_UTM_zone_20S"},
+    {29181, "PCS_SAD69_UTM_zone_21S"},
+    {29182, "PCS_SAD69_UTM_zone_22S"},
+    {29183, "PCS_SAD69_UTM_zone_23S"},
+    {29184, "PCS_SAD69_UTM_zone_24S"},
+    {29185, "PCS_SAD69_UTM_zone_25S"},
+    {29220, "PCS_Sapper_Hill_UTM_20S"},
+    {29221, "PCS_Sapper_Hill_UTM_21S"},
+    {29333, "PCS_Schwarzeck_UTM_33S"},
+    {29635, "PCS_Sudan_UTM_zone_35N"},
+    {29636, "PCS_Sudan_UTM_zone_36N"},
+    {29700, "PCS_Tananarive_Laborde"},
+    {29738, "PCS_Tananarive_UTM_38S"},
+    {29739, "PCS_Tananarive_UTM_39S"},
+    {29800, "PCS_Timbalai_1948_Borneo"},
+    {29849, "PCS_Timbalai_1948_UTM_49N"},
+    {29850, "PCS_Timbalai_1948_UTM_50N"},
+    {29900, "PCS_TM65_Irish_Nat_Grid"},
+    {30200, "PCS_Trinidad_1903_Trinidad"},
+    {30339, "PCS_TC_1948_UTM_zone_39N"},
+    {30340, "PCS_TC_1948_UTM_zone_40N"},
+    {30491, "PCS_Voirol_N_Algerie_ancien"},
+    {30492, "PCS_Voirol_S_Algerie_ancien"},
+    {30591, "PCS_Voirol_Unifie_N_Algerie"},
+    {30592, "PCS_Voirol_Unifie_S_Algerie"},
+    {30600, "PCS_Bern_1938_Swiss_New"},
+    {30729, "PCS_Nord_Sahara_UTM_29N"},
+    {30730, "PCS_Nord_Sahara_UTM_30N"},
+    {30731, "PCS_Nord_Sahara_UTM_31N"},
+    {30732, "PCS_Nord_Sahara_UTM_32N"},
+    {31028, "PCS_Yoff_UTM_zone_28N"},
+    {31121, "PCS_Zanderij_UTM_zone_21N"},
+    {31291, "PCS_MGI_Austria_West"},
+    {31292, "PCS_MGI_Austria_Central"},
+    {31293, "PCS_MGI_Austria_East"},
+    {31300, "PCS_Belge_Lambert_72"},
+    {31491, "PCS_DHDN_Germany_zone_1"},
+    {31492, "PCS_DHDN_Germany_zone_2"},
+    {31493, "PCS_DHDN_Germany_zone_3"},
+    {31494, "PCS_DHDN_Germany_zone_4"},
+    {31495, "PCS_DHDN_Germany_zone_5"},
+    {32001, "PCS_NAD27_Montana_North"},
+    {32002, "PCS_NAD27_Montana_Central"},
+    {32003, "PCS_NAD27_Montana_South"},
+    {32005, "PCS_NAD27_Nebraska_North"},
+    {32006, "PCS_NAD27_Nebraska_South"},
+    {32007, "PCS_NAD27_Nevada_East"},
+    {32008, "PCS_NAD27_Nevada_Central"},
+    {32009, "PCS_NAD27_Nevada_West"},
+    {32010, "PCS_NAD27_New_Hampshire"},
+    {32011, "PCS_NAD27_New_Jersey"},
+    {32012, "PCS_NAD27_New_Mexico_East"},
+    {32013, "PCS_NAD27_New_Mexico_Cent"},
+    {32014, "PCS_NAD27_New_Mexico_West"},
+    {32015, "PCS_NAD27_New_York_East"},
+    {32016, "PCS_NAD27_New_York_Central"},
+    {32017, "PCS_NAD27_New_York_West"},
+    {32018, "PCS_NAD27_New_York_Long_Is"},
+    {32019, "PCS_NAD27_North_Carolina"},
+    {32020, "PCS_NAD27_North_Dakota_N"},
+    {32021, "PCS_NAD27_North_Dakota_S"},
+    {32022, "PCS_NAD27_Ohio_North"},
+    {32023, "PCS_NAD27_Ohio_South"},
+    {32024, "PCS_NAD27_Oklahoma_North"},
+    {32025, "PCS_NAD27_Oklahoma_South"},
+    {32026, "PCS_NAD27_Oregon_North"},
+    {32027, "PCS_NAD27_Oregon_South"},
+    {32028, "PCS_NAD27_Pennsylvania_N"},
+    {32029, "PCS_NAD27_Pennsylvania_S"},
+    {32030, "PCS_NAD27_Rhode_Island"},
+    {32031, "PCS_NAD27_South_Carolina_N"},
+    {32033, "PCS_NAD27_South_Carolina_S"},
+    {32034, "PCS_NAD27_South_Dakota_N"},
+    {32035, "PCS_NAD27_South_Dakota_S"},
+    {32036, "PCS_NAD27_Tennessee"},
+    {32037, "PCS_NAD27_Texas_North"},
+    {32038, "PCS_NAD27_Texas_North_Cen"},
+    {32039, "PCS_NAD27_Texas_Central"},
+    {32040, "PCS_NAD27_Texas_South_Cen"},
+    {32041, "PCS_NAD27_Texas_South"},
+    {32042, "PCS_NAD27_Utah_North"},
+    {32043, "PCS_NAD27_Utah_Central"},
+    {32044, "PCS_NAD27_Utah_South"},
+    {32045, "PCS_NAD27_Vermont"},
+    {32046, "PCS_NAD27_Virginia_North"},
+    {32047, "PCS_NAD27_Virginia_South"},
+    {32048, "PCS_NAD27_Washington_North"},
+    {32049, "PCS_NAD27_Washington_South"},
+    {32050, "PCS_NAD27_West_Virginia_N"},
+    {32051, "PCS_NAD27_West_Virginia_S"},
+    {32052, "PCS_NAD27_Wisconsin_North"},
+    {32053, "PCS_NAD27_Wisconsin_Cen"},
+    {32054, "PCS_NAD27_Wisconsin_South"},
+    {32055, "PCS_NAD27_Wyoming_East"},
+    {32056, "PCS_NAD27_Wyoming_E_Cen"},
+    {32057, "PCS_NAD27_Wyoming_W_Cen"},
+    {32058, "PCS_NAD27_Wyoming_West"},
+    {32059, "PCS_NAD27_Puerto_Rico"},
+    {32060, "PCS_NAD27_St_Croix"},
+    {32100, "PCS_NAD83_Montana"},
+    {32104, "PCS_NAD83_Nebraska"},
+    {32107, "PCS_NAD83_Nevada_East"},
+    {32108, "PCS_NAD83_Nevada_Central"},
+    {32109, "PCS_NAD83_Nevada_West"},
+    {32110, "PCS_NAD83_New_Hampshire"},
+    {32111, "PCS_NAD83_New_Jersey"},
+    {32112, "PCS_NAD83_New_Mexico_East"},
+    {32113, "PCS_NAD83_New_Mexico_Cent"},
+    {32114, "PCS_NAD83_New_Mexico_West"},
+    {32115, "PCS_NAD83_New_York_East"},
+    {32116, "PCS_NAD83_New_York_Central"},
+    {32117, "PCS_NAD83_New_York_West"},
+    {32118, "PCS_NAD83_New_York_Long_Is"},
+    {32119, "PCS_NAD83_North_Carolina"},
+    {32120, "PCS_NAD83_North_Dakota_N"},
+    {32121, "PCS_NAD83_North_Dakota_S"},
+    {32122, "PCS_NAD83_Ohio_North"},
+    {32123, "PCS_NAD83_Ohio_South"},
+    {32124, "PCS_NAD83_Oklahoma_North"},
+    {32125, "PCS_NAD83_Oklahoma_South"},
+    {32126, "PCS_NAD83_Oregon_North"},
+    {32127, "PCS_NAD83_Oregon_South"},
+    {32128, "PCS_NAD83_Pennsylvania_N"},
+    {32129, "PCS_NAD83_Pennsylvania_S"},
+    {32130, "PCS_NAD83_Rhode_Island"},
+    {32133, "PCS_NAD83_South_Carolina"},
+    {32134, "PCS_NAD83_South_Dakota_N"},
+    {32135, "PCS_NAD83_South_Dakota_S"},
+    {32136, "PCS_NAD83_Tennessee"},
+    {32137, "PCS_NAD83_Texas_North"},
+    {32138, "PCS_NAD83_Texas_North_Cen"},
+    {32139, "PCS_NAD83_Texas_Central"},
+    {32140, "PCS_NAD83_Texas_South_Cen"},
+    {32141, "PCS_NAD83_Texas_South"},
+    {32142, "PCS_NAD83_Utah_North"},
+    {32143, "PCS_NAD83_Utah_Central"},
+    {32144, "PCS_NAD83_Utah_South"},
+    {32145, "PCS_NAD83_Vermont"},
+    {32146, "PCS_NAD83_Virginia_North"},
+    {32147, "PCS_NAD83_Virginia_South"},
+    {32148, "PCS_NAD83_Washington_North"},
+    {32149, "PCS_NAD83_Washington_South"},
+    {32150, "PCS_NAD83_West_Virginia_N"},
+    {32151, "PCS_NAD83_West_Virginia_S"},
+    {32152, "PCS_NAD83_Wisconsin_North"},
+    {32153, "PCS_NAD83_Wisconsin_Cen"},
+    {32154, "PCS_NAD83_Wisconsin_South"},
+    {32155, "PCS_NAD83_Wyoming_East"},
+    {32156, "PCS_NAD83_Wyoming_E_Cen"},
+    {32157, "PCS_NAD83_Wyoming_W_Cen"},
+    {32158, "PCS_NAD83_Wyoming_West"},
+    {32161, "PCS_NAD83_Puerto_Rico_Virgin_Is"},
+    {32201, "PCS_WGS72_UTM_zone_1N"},
+    {32202, "PCS_WGS72_UTM_zone_2N"},
+    {32203, "PCS_WGS72_UTM_zone_3N"},
+    {32204, "PCS_WGS72_UTM_zone_4N"},
+    {32205, "PCS_WGS72_UTM_zone_5N"},
+    {32206, "PCS_WGS72_UTM_zone_6N"},
+    {32207, "PCS_WGS72_UTM_zone_7N"},
+    {32208, "PCS_WGS72_UTM_zone_8N"},
+    {32209, "PCS_WGS72_UTM_zone_9N"},
+    {32210, "PCS_WGS72_UTM_zone_10N"},
+    {32211, "PCS_WGS72_UTM_zone_11N"},
+    {32212, "PCS_WGS72_UTM_zone_12N"},
+    {32213, "PCS_WGS72_UTM_zone_13N"},
+    {32214, "PCS_WGS72_UTM_zone_14N"},
+    {32215, "PCS_WGS72_UTM_zone_15N"},
+    {32216, "PCS_WGS72_UTM_zone_16N"},
+    {32217, "PCS_WGS72_UTM_zone_17N"},
+    {32218, "PCS_WGS72_UTM_zone_18N"},
+    {32219, "PCS_WGS72_UTM_zone_19N"},
+    {32220, "PCS_WGS72_UTM_zone_20N"},
+    {32221, "PCS_WGS72_UTM_zone_21N"},
+    {32222, "PCS_WGS72_UTM_zone_22N"},
+    {32223, "PCS_WGS72_UTM_zone_23N"},
+    {32224, "PCS_WGS72_UTM_zone_24N"},
+    {32225, "PCS_WGS72_UTM_zone_25N"},
+    {32226, "PCS_WGS72_UTM_zone_26N"},
+    {32227, "PCS_WGS72_UTM_zone_27N"},
+    {32228, "PCS_WGS72_UTM_zone_28N"},
+    {32229, "PCS_WGS72_UTM_zone_29N"},
+    {32230, "PCS_WGS72_UTM_zone_30N"},
+    {32231, "PCS_WGS72_UTM_zone_31N"},
+    {32232, "PCS_WGS72_UTM_zone_32N"},
+    {32233, "PCS_WGS72_UTM_zone_33N"},
+    {32234, "PCS_WGS72_UTM_zone_34N"},
+    {32235, "PCS_WGS72_UTM_zone_35N"},
+    {32236, "PCS_WGS72_UTM_zone_36N"},
+    {32237, "PCS_WGS72_UTM_zone_37N"},
+    {32238, "PCS_WGS72_UTM_zone_38N"},
+    {32239, "PCS_WGS72_UTM_zone_39N"},
+    {32240, "PCS_WGS72_UTM_zone_40N"},
+    {32241, "PCS_WGS72_UTM_zone_41N"},
+    {32242, "PCS_WGS72_UTM_zone_42N"},
+    {32243, "PCS_WGS72_UTM_zone_43N"},
+    {32244, "PCS_WGS72_UTM_zone_44N"},
+    {32245, "PCS_WGS72_UTM_zone_45N"},
+    {32246, "PCS_WGS72_UTM_zone_46N"},
+    {32247, "PCS_WGS72_UTM_zone_47N"},
+    {32248, "PCS_WGS72_UTM_zone_48N"},
+    {32249, "PCS_WGS72_UTM_zone_49N"},
+    {32250, "PCS_WGS72_UTM_zone_50N"},
+    {32251, "PCS_WGS72_UTM_zone_51N"},
+    {32252, "PCS_WGS72_UTM_zone_52N"},
+    {32253, "PCS_WGS72_UTM_zone_53N"},
+    {32254, "PCS_WGS72_UTM_zone_54N"},
+    {32255, "PCS_WGS72_UTM_zone_55N"},
+    {32256, "PCS_WGS72_UTM_zone_56N"},
+    {32257, "PCS_WGS72_UTM_zone_57N"},
+    {32258, "PCS_WGS72_UTM_zone_58N"},
+    {32259, "PCS_WGS72_UTM_zone_59N"},
+    {32260, "PCS_WGS72_UTM_zone_60N"},
+    {32301, "PCS_WGS72_UTM_zone_1S"},
+    {32302, "PCS_WGS72_UTM_zone_2S"},
+    {32303, "PCS_WGS72_UTM_zone_3S"},
+    {32304, "PCS_WGS72_UTM_zone_4S"},
+    {32305, "PCS_WGS72_UTM_zone_5S"},
+    {32306, "PCS_WGS72_UTM_zone_6S"},
+    {32307, "PCS_WGS72_UTM_zone_7S"},
+    {32308, "PCS_WGS72_UTM_zone_8S"},
+    {32309, "PCS_WGS72_UTM_zone_9S"},
+    {32310, "PCS_WGS72_UTM_zone_10S"},
+    {32311, "PCS_WGS72_UTM_zone_11S"},
+    {32312, "PCS_WGS72_UTM_zone_12S"},
+    {32313, "PCS_WGS72_UTM_zone_13S"},
+    {32314, "PCS_WGS72_UTM_zone_14S"},
+    {32315, "PCS_WGS72_UTM_zone_15S"},
+    {32316, "PCS_WGS72_UTM_zone_16S"},
+    {32317, "PCS_WGS72_UTM_zone_17S"},
+    {32318, "PCS_WGS72_UTM_zone_18S"},
+    {32319, "PCS_WGS72_UTM_zone_19S"},
+    {32320, "PCS_WGS72_UTM_zone_20S"},
+    {32321, "PCS_WGS72_UTM_zone_21S"},
+    {32322, "PCS_WGS72_UTM_zone_22S"},
+    {32323, "PCS_WGS72_UTM_zone_23S"},
+    {32324, "PCS_WGS72_UTM_zone_24S"},
+    {32325, "PCS_WGS72_UTM_zone_25S"},
+    {32326, "PCS_WGS72_UTM_zone_26S"},
+    {32327, "PCS_WGS72_UTM_zone_27S"},
+    {32328, "PCS_WGS72_UTM_zone_28S"},
+    {32329, "PCS_WGS72_UTM_zone_29S"},
+    {32330, "PCS_WGS72_UTM_zone_30S"},
+    {32331, "PCS_WGS72_UTM_zone_31S"},
+    {32332, "PCS_WGS72_UTM_zone_32S"},
+    {32333, "PCS_WGS72_UTM_zone_33S"},
+    {32334, "PCS_WGS72_UTM_zone_34S"},
+    {32335, "PCS_WGS72_UTM_zone_35S"},
+    {32336, "PCS_WGS72_UTM_zone_36S"},
+    {32337, "PCS_WGS72_UTM_zone_37S"},
+    {32338, "PCS_WGS72_UTM_zone_38S"},
+    {32339, "PCS_WGS72_UTM_zone_39S"},
+    {32340, "PCS_WGS72_UTM_zone_40S"},
+    {32341, "PCS_WGS72_UTM_zone_41S"},
+    {32342, "PCS_WGS72_UTM_zone_42S"},
+    {32343, "PCS_WGS72_UTM_zone_43S"},
+    {32344, "PCS_WGS72_UTM_zone_44S"},
+    {32345, "PCS_WGS72_UTM_zone_45S"},
+    {32346, "PCS_WGS72_UTM_zone_46S"},
+    {32347, "PCS_WGS72_UTM_zone_47S"},
+    {32348, "PCS_WGS72_UTM_zone_48S"},
+    {32349, "PCS_WGS72_UTM_zone_49S"},
+    {32350, "PCS_WGS72_UTM_zone_50S"},
+    {32351, "PCS_WGS72_UTM_zone_51S"},
+    {32352, "PCS_WGS72_UTM_zone_52S"},
+    {32353, "PCS_WGS72_UTM_zone_53S"},
+    {32354, "PCS_WGS72_UTM_zone_54S"},
+    {32355, "PCS_WGS72_UTM_zone_55S"},
+    {32356, "PCS_WGS72_UTM_zone_56S"},
+    {32357, "PCS_WGS72_UTM_zone_57S"},
+    {32358, "PCS_WGS72_UTM_zone_58S"},
+    {32359, "PCS_WGS72_UTM_zone_59S"},
+    {32360, "PCS_WGS72_UTM_zone_60S"},
+    {32401, "PCS_WGS72BE_UTM_zone_1N"},
+    {32402, "PCS_WGS72BE_UTM_zone_2N"},
+    {32403, "PCS_WGS72BE_UTM_zone_3N"},
+    {32404, "PCS_WGS72BE_UTM_zone_4N"},
+    {32405, "PCS_WGS72BE_UTM_zone_5N"},
+    {32406, "PCS_WGS72BE_UTM_zone_6N"},
+    {32407, "PCS_WGS72BE_UTM_zone_7N"},
+    {32408, "PCS_WGS72BE_UTM_zone_8N"},
+    {32409, "PCS_WGS72BE_UTM_zone_9N"},
+    {32410, "PCS_WGS72BE_UTM_zone_10N"},
+    {32411, "PCS_WGS72BE_UTM_zone_11N"},
+    {32412, "PCS_WGS72BE_UTM_zone_12N"},
+    {32413, "PCS_WGS72BE_UTM_zone_13N"},
+    {32414, "PCS_WGS72BE_UTM_zone_14N"},
+    {32415, "PCS_WGS72BE_UTM_zone_15N"},
+    {32416, "PCS_WGS72BE_UTM_zone_16N"},
+    {32417, "PCS_WGS72BE_UTM_zone_17N"},
+    {32418, "PCS_WGS72BE_UTM_zone_18N"},
+    {32419, "PCS_WGS72BE_UTM_zone_19N"},
+    {32420, "PCS_WGS72BE_UTM_zone_20N"},
+    {32421, "PCS_WGS72BE_UTM_zone_21N"},
+    {32422, "PCS_WGS72BE_UTM_zone_22N"},
+    {32423, "PCS_WGS72BE_UTM_zone_23N"},
+    {32424, "PCS_WGS72BE_UTM_zone_24N"},
+    {32425, "PCS_WGS72BE_UTM_zone_25N"},
+    {32426, "PCS_WGS72BE_UTM_zone_26N"},
+    {32427, "PCS_WGS72BE_UTM_zone_27N"},
+    {32428, "PCS_WGS72BE_UTM_zone_28N"},
+    {32429, "PCS_WGS72BE_UTM_zone_29N"},
+    {32430, "PCS_WGS72BE_UTM_zone_30N"},
+    {32431, "PCS_WGS72BE_UTM_zone_31N"},
+    {32432, "PCS_WGS72BE_UTM_zone_32N"},
+    {32433, "PCS_WGS72BE_UTM_zone_33N"},
+    {32434, "PCS_WGS72BE_UTM_zone_34N"},
+    {32435, "PCS_WGS72BE_UTM_zone_35N"},
+    {32436, "PCS_WGS72BE_UTM_zone_36N"},
+    {32437, "PCS_WGS72BE_UTM_zone_37N"},
+    {32438, "PCS_WGS72BE_UTM_zone_38N"},
+    {32439, "PCS_WGS72BE_UTM_zone_39N"},
+    {32440, "PCS_WGS72BE_UTM_zone_40N"},
+    {32441, "PCS_WGS72BE_UTM_zone_41N"},
+    {32442, "PCS_WGS72BE_UTM_zone_42N"},
+    {32443, "PCS_WGS72BE_UTM_zone_43N"},
+    {32444, "PCS_WGS72BE_UTM_zone_44N"},
+    {32445, "PCS_WGS72BE_UTM_zone_45N"},
+    {32446, "PCS_WGS72BE_UTM_zone_46N"},
+    {32447, "PCS_WGS72BE_UTM_zone_47N"},
+    {32448, "PCS_WGS72BE_UTM_zone_48N"},
+    {32449, "PCS_WGS72BE_UTM_zone_49N"},
+    {32450, "PCS_WGS72BE_UTM_zone_50N"},
+    {32451, "PCS_WGS72BE_UTM_zone_51N"},
+    {32452, "PCS_WGS72BE_UTM_zone_52N"},
+    {32453, "PCS_WGS72BE_UTM_zone_53N"},
+    {32454, "PCS_WGS72BE_UTM_zone_54N"},
+    {32455, "PCS_WGS72BE_UTM_zone_55N"},
+    {32456, "PCS_WGS72BE_UTM_zone_56N"},
+    {32457, "PCS_WGS72BE_UTM_zone_57N"},
+    {32458, "PCS_WGS72BE_UTM_zone_58N"},
+    {32459, "PCS_WGS72BE_UTM_zone_59N"},
+    {32460, "PCS_WGS72BE_UTM_zone_60N"},
+    {32501, "PCS_WGS72BE_UTM_zone_1S"},
+    {32502, "PCS_WGS72BE_UTM_zone_2S"},
+    {32503, "PCS_WGS72BE_UTM_zone_3S"},
+    {32504, "PCS_WGS72BE_UTM_zone_4S"},
+    {32505, "PCS_WGS72BE_UTM_zone_5S"},
+    {32506, "PCS_WGS72BE_UTM_zone_6S"},
+    {32507, "PCS_WGS72BE_UTM_zone_7S"},
+    {32508, "PCS_WGS72BE_UTM_zone_8S"},
+    {32509, "PCS_WGS72BE_UTM_zone_9S"},
+    {32510, "PCS_WGS72BE_UTM_zone_10S"},
+    {32511, "PCS_WGS72BE_UTM_zone_11S"},
+    {32512, "PCS_WGS72BE_UTM_zone_12S"},
+    {32513, "PCS_WGS72BE_UTM_zone_13S"},
+    {32514, "PCS_WGS72BE_UTM_zone_14S"},
+    {32515, "PCS_WGS72BE_UTM_zone_15S"},
+    {32516, "PCS_WGS72BE_UTM_zone_16S"},
+    {32517, "PCS_WGS72BE_UTM_zone_17S"},
+    {32518, "PCS_WGS72BE_UTM_zone_18S"},
+    {32519, "PCS_WGS72BE_UTM_zone_19S"},
+    {32520, "PCS_WGS72BE_UTM_zone_20S"},
+    {32521, "PCS_WGS72BE_UTM_zone_21S"},
+    {32522, "PCS_WGS72BE_UTM_zone_22S"},
+    {32523, "PCS_WGS72BE_UTM_zone_23S"},
+    {32524, "PCS_WGS72BE_UTM_zone_24S"},
+    {32525, "PCS_WGS72BE_UTM_zone_25S"},
+    {32526, "PCS_WGS72BE_UTM_zone_26S"},
+    {32527, "PCS_WGS72BE_UTM_zone_27S"},
+    {32528, "PCS_WGS72BE_UTM_zone_28S"},
+    {32529, "PCS_WGS72BE_UTM_zone_29S"},
+    {32530, "PCS_WGS72BE_UTM_zone_30S"},
+    {32531, "PCS_WGS72BE_UTM_zone_31S"},
+    {32532, "PCS_WGS72BE_UTM_zone_32S"},
+    {32533, "PCS_WGS72BE_UTM_zone_33S"},
+    {32534, "PCS_WGS72BE_UTM_zone_34S"},
+    {32535, "PCS_WGS72BE_UTM_zone_35S"},
+    {32536, "PCS_WGS72BE_UTM_zone_36S"},
+    {32537, "PCS_WGS72BE_UTM_zone_37S"},
+    {32538, "PCS_WGS72BE_UTM_zone_38S"},
+    {32539, "PCS_WGS72BE_UTM_zone_39S"},
+    {32540, "PCS_WGS72BE_UTM_zone_40S"},
+    {32541, "PCS_WGS72BE_UTM_zone_41S"},
+    {32542, "PCS_WGS72BE_UTM_zone_42S"},
+    {32543, "PCS_WGS72BE_UTM_zone_43S"},
+    {32544, "PCS_WGS72BE_UTM_zone_44S"},
+    {32545, "PCS_WGS72BE_UTM_zone_45S"},
+    {32546, "PCS_WGS72BE_UTM_zone_46S"},
+    {32547, "PCS_WGS72BE_UTM_zone_47S"},
+    {32548, "PCS_WGS72BE_UTM_zone_48S"},
+    {32549, "PCS_WGS72BE_UTM_zone_49S"},
+    {32550, "PCS_WGS72BE_UTM_zone_50S"},
+    {32551, "PCS_WGS72BE_UTM_zone_51S"},
+    {32552, "PCS_WGS72BE_UTM_zone_52S"},
+    {32553, "PCS_WGS72BE_UTM_zone_53S"},
+    {32554, "PCS_WGS72BE_UTM_zone_54S"},
+    {32555, "PCS_WGS72BE_UTM_zone_55S"},
+    {32556, "PCS_WGS72BE_UTM_zone_56S"},
+    {32557, "PCS_WGS72BE_UTM_zone_57S"},
+    {32558, "PCS_WGS72BE_UTM_zone_58S"},
+    {32559, "PCS_WGS72BE_UTM_zone_59S"},
+    {32560, "PCS_WGS72BE_UTM_zone_60S"},
+    {32601, "PCS_WGS84_UTM_zone_1N"},
+    {32602, "PCS_WGS84_UTM_zone_2N"},
+    {32603, "PCS_WGS84_UTM_zone_3N"},
+    {32604, "PCS_WGS84_UTM_zone_4N"},
+    {32605, "PCS_WGS84_UTM_zone_5N"},
+    {32606, "PCS_WGS84_UTM_zone_6N"},
+    {32607, "PCS_WGS84_UTM_zone_7N"},
+    {32608, "PCS_WGS84_UTM_zone_8N"},
+    {32609, "PCS_WGS84_UTM_zone_9N"},
+    {32610, "PCS_WGS84_UTM_zone_10N"},
+    {32611, "PCS_WGS84_UTM_zone_11N"},
+    {32612, "PCS_WGS84_UTM_zone_12N"},
+    {32613, "PCS_WGS84_UTM_zone_13N"},
+    {32614, "PCS_WGS84_UTM_zone_14N"},
+    {32615, "PCS_WGS84_UTM_zone_15N"},
+    {32616, "PCS_WGS84_UTM_zone_16N"},
+    {32617, "PCS_WGS84_UTM_zone_17N"},
+    {32618, "PCS_WGS84_UTM_zone_18N"},
+    {32619, "PCS_WGS84_UTM_zone_19N"},
+    {32620, "PCS_WGS84_UTM_zone_20N"},
+    {32621, "PCS_WGS84_UTM_zone_21N"},
+    {32622, "PCS_WGS84_UTM_zone_22N"},
+    {32623, "PCS_WGS84_UTM_zone_23N"},
+    {32624, "PCS_WGS84_UTM_zone_24N"},
+    {32625, "PCS_WGS84_UTM_zone_25N"},
+    {32626, "PCS_WGS84_UTM_zone_26N"},
+    {32627, "PCS_WGS84_UTM_zone_27N"},
+    {32628, "PCS_WGS84_UTM_zone_28N"},
+    {32629, "PCS_WGS84_UTM_zone_29N"},
+    {32630, "PCS_WGS84_UTM_zone_30N"},
+    {32631, "PCS_WGS84_UTM_zone_31N"},
+    {32632, "PCS_WGS84_UTM_zone_32N"},
+    {32633, "PCS_WGS84_UTM_zone_33N"},
+    {32634, "PCS_WGS84_UTM_zone_34N"},
+    {32635, "PCS_WGS84_UTM_zone_35N"},
+    {32636, "PCS_WGS84_UTM_zone_36N"},
+    {32637, "PCS_WGS84_UTM_zone_37N"},
+    {32638, "PCS_WGS84_UTM_zone_38N"},
+    {32639, "PCS_WGS84_UTM_zone_39N"},
+    {32640, "PCS_WGS84_UTM_zone_40N"},
+    {32641, "PCS_WGS84_UTM_zone_41N"},
+    {32642, "PCS_WGS84_UTM_zone_42N"},
+    {32643, "PCS_WGS84_UTM_zone_43N"},
+    {32644, "PCS_WGS84_UTM_zone_44N"},
+    {32645, "PCS_WGS84_UTM_zone_45N"},
+    {32646, "PCS_WGS84_UTM_zone_46N"},
+    {32647, "PCS_WGS84_UTM_zone_47N"},
+    {32648, "PCS_WGS84_UTM_zone_48N"},
+    {32649, "PCS_WGS84_UTM_zone_49N"},
+    {32650, "PCS_WGS84_UTM_zone_50N"},
+    {32651, "PCS_WGS84_UTM_zone_51N"},
+    {32652, "PCS_WGS84_UTM_zone_52N"},
+    {32653, "PCS_WGS84_UTM_zone_53N"},
+    {32654, "PCS_WGS84_UTM_zone_54N"},
+    {32655, "PCS_WGS84_UTM_zone_55N"},
+    {32656, "PCS_WGS84_UTM_zone_56N"},
+    {32657, "PCS_WGS84_UTM_zone_57N"},
+    {32658, "PCS_WGS84_UTM_zone_58N"},
+    {32659, "PCS_WGS84_UTM_zone_59N"},
+    {32660, "PCS_WGS84_UTM_zone_60N"},
+    {32701, "PCS_WGS84_UTM_zone_1S"},
+    {32702, "PCS_WGS84_UTM_zone_2S"},
+    {32703, "PCS_WGS84_UTM_zone_3S"},
+    {32704, "PCS_WGS84_UTM_zone_4S"},
+    {32705, "PCS_WGS84_UTM_zone_5S"},
+    {32706, "PCS_WGS84_UTM_zone_6S"},
+    {32707, "PCS_WGS84_UTM_zone_7S"},
+    {32708, "PCS_WGS84_UTM_zone_8S"},
+    {32709, "PCS_WGS84_UTM_zone_9S"},
+    {32710, "PCS_WGS84_UTM_zone_10S"},
+    {32711, "PCS_WGS84_UTM_zone_11S"},
+    {32712, "PCS_WGS84_UTM_zone_12S"},
+    {32713, "PCS_WGS84_UTM_zone_13S"},
+    {32714, "PCS_WGS84_UTM_zone_14S"},
+    {32715, "PCS_WGS84_UTM_zone_15S"},
+    {32716, "PCS_WGS84_UTM_zone_16S"},
+    {32717, "PCS_WGS84_UTM_zone_17S"},
+    {32718, "PCS_WGS84_UTM_zone_18S"},
+    {32719, "PCS_WGS84_UTM_zone_19S"},
+    {32720, "PCS_WGS84_UTM_zone_20S"},
+    {32721, "PCS_WGS84_UTM_zone_21S"},
+    {32722, "PCS_WGS84_UTM_zone_22S"},
+    {32723, "PCS_WGS84_UTM_zone_23S"},
+    {32724, "PCS_WGS84_UTM_zone_24S"},
+    {32725, "PCS_WGS84_UTM_zone_25S"},
+    {32726, "PCS_WGS84_UTM_zone_26S"},
+    {32727, "PCS_WGS84_UTM_zone_27S"},
+    {32728, "PCS_WGS84_UTM_zone_28S"},
+    {32729, "PCS_WGS84_UTM_zone_29S"},
+    {32730, "PCS_WGS84_UTM_zone_30S"},
+    {32731, "PCS_WGS84_UTM_zone_31S"},
+    {32732, "PCS_WGS84_UTM_zone_32S"},
+    {32733, "PCS_WGS84_UTM_zone_33S"},
+    {32734, "PCS_WGS84_UTM_zone_34S"},
+    {32735, "PCS_WGS84_UTM_zone_35S"},
+    {32736, "PCS_WGS84_UTM_zone_36S"},
+    {32737, "PCS_WGS84_UTM_zone_37S"},
+    {32738, "PCS_WGS84_UTM_zone_38S"},
+    {32739, "PCS_WGS84_UTM_zone_39S"},
+    {32740, "PCS_WGS84_UTM_zone_40S"},
+    {32741, "PCS_WGS84_UTM_zone_41S"},
+    {32742, "PCS_WGS84_UTM_zone_42S"},
+    {32743, "PCS_WGS84_UTM_zone_43S"},
+    {32744, "PCS_WGS84_UTM_zone_44S"},
+    {32745, "PCS_WGS84_UTM_zone_45S"},
+    {32746, "PCS_WGS84_UTM_zone_46S"},
+    {32747, "PCS_WGS84_UTM_zone_47S"},
+    {32748, "PCS_WGS84_UTM_zone_48S"},
+    {32749, "PCS_WGS84_UTM_zone_49S"},
+    {32750, "PCS_WGS84_UTM_zone_50S"},
+    {32751, "PCS_WGS84_UTM_zone_51S"},
+    {32752, "PCS_WGS84_UTM_zone_52S"},
+    {32753, "PCS_WGS84_UTM_zone_53S"},
+    {32754, "PCS_WGS84_UTM_zone_54S"},
+    {32755, "PCS_WGS84_UTM_zone_55S"},
+    {32756, "PCS_WGS84_UTM_zone_56S"},
+    {32757, "PCS_WGS84_UTM_zone_57S"},
+    {32758, "PCS_WGS84_UTM_zone_58S"},
+    {32759, "PCS_WGS84_UTM_zone_59S"},
+    {32760, "PCS_WGS84_UTM_zone_60S"}
+};
+
+const TiffGeoTagKeyName ff_tiff_projection_codes[] = {
+    {10101, "Proj_Alabama_CS27_East"},
+    {10102, "Proj_Alabama_CS27_West"},
+    {10131, "Proj_Alabama_CS83_East"},
+    {10132, "Proj_Alabama_CS83_West"},
+    {10201, "Proj_Arizona_Coordinate_System_east"},
+    {10202, "Proj_Arizona_Coordinate_System_Central"},
+    {10203, "Proj_Arizona_Coordinate_System_west"},
+    {10231, "Proj_Arizona_CS83_east"},
+    {10232, "Proj_Arizona_CS83_Central"},
+    {10233, "Proj_Arizona_CS83_west"},
+    {10301, "Proj_Arkansas_CS27_North"},
+    {10302, "Proj_Arkansas_CS27_South"},
+    {10331, "Proj_Arkansas_CS83_North"},
+    {10332, "Proj_Arkansas_CS83_South"},
+    {10401, "Proj_California_CS27_I"},
+    {10402, "Proj_California_CS27_II"},
+    {10403, "Proj_California_CS27_III"},
+    {10404, "Proj_California_CS27_IV"},
+    {10405, "Proj_California_CS27_V"},
+    {10406, "Proj_California_CS27_VI"},
+    {10407, "Proj_California_CS27_VII"},
+    {10431, "Proj_California_CS83_1"},
+    {10432, "Proj_California_CS83_2"},
+    {10433, "Proj_California_CS83_3"},
+    {10434, "Proj_California_CS83_4"},
+    {10435, "Proj_California_CS83_5"},
+    {10436, "Proj_California_CS83_6"},
+    {10501, "Proj_Colorado_CS27_North"},
+    {10502, "Proj_Colorado_CS27_Central"},
+    {10503, "Proj_Colorado_CS27_South"},
+    {10531, "Proj_Colorado_CS83_North"},
+    {10532, "Proj_Colorado_CS83_Central"},
+    {10533, "Proj_Colorado_CS83_South"},
+    {10600, "Proj_Connecticut_CS27"},
+    {10630, "Proj_Connecticut_CS83"},
+    {10700, "Proj_Delaware_CS27"},
+    {10730, "Proj_Delaware_CS83"},
+    {10901, "Proj_Florida_CS27_East"},
+    {10902, "Proj_Florida_CS27_West"},
+    {10903, "Proj_Florida_CS27_North"},
+    {10931, "Proj_Florida_CS83_East"},
+    {10932, "Proj_Florida_CS83_West"},
+    {10933, "Proj_Florida_CS83_North"},
+    {11001, "Proj_Georgia_CS27_East"},
+    {11002, "Proj_Georgia_CS27_West"},
+    {11031, "Proj_Georgia_CS83_East"},
+    {11032, "Proj_Georgia_CS83_West"},
+    {11101, "Proj_Idaho_CS27_East"},
+    {11102, "Proj_Idaho_CS27_Central"},
+    {11103, "Proj_Idaho_CS27_West"},
+    {11131, "Proj_Idaho_CS83_East"},
+    {11132, "Proj_Idaho_CS83_Central"},
+    {11133, "Proj_Idaho_CS83_West"},
+    {11201, "Proj_Illinois_CS27_East"},
+    {11202, "Proj_Illinois_CS27_West"},
+    {11231, "Proj_Illinois_CS83_East"},
+    {11232, "Proj_Illinois_CS83_West"},
+    {11301, "Proj_Indiana_CS27_East"},
+    {11302, "Proj_Indiana_CS27_West"},
+    {11331, "Proj_Indiana_CS83_East"},
+    {11332, "Proj_Indiana_CS83_West"},
+    {11401, "Proj_Iowa_CS27_North"},
+    {11402, "Proj_Iowa_CS27_South"},
+    {11431, "Proj_Iowa_CS83_North"},
+    {11432, "Proj_Iowa_CS83_South"},
+    {11501, "Proj_Kansas_CS27_North"},
+    {11502, "Proj_Kansas_CS27_South"},
+    {11531, "Proj_Kansas_CS83_North"},
+    {11532, "Proj_Kansas_CS83_South"},
+    {11601, "Proj_Kentucky_CS27_North"},
+    {11602, "Proj_Kentucky_CS27_South"},
+    {11631, "Proj_Kentucky_CS83_North"},
+    {11632, "Proj_Kentucky_CS83_South"},
+    {11701, "Proj_Louisiana_CS27_North"},
+    {11702, "Proj_Louisiana_CS27_South"},
+    {11731, "Proj_Louisiana_CS83_North"},
+    {11732, "Proj_Louisiana_CS83_South"},
+    {11801, "Proj_Maine_CS27_East"},
+    {11802, "Proj_Maine_CS27_West"},
+    {11831, "Proj_Maine_CS83_East"},
+    {11832, "Proj_Maine_CS83_West"},
+    {11900, "Proj_Maryland_CS27"},
+    {11930, "Proj_Maryland_CS83"},
+    {12001, "Proj_Massachusetts_CS27_Mainland"},
+    {12002, "Proj_Massachusetts_CS27_Island"},
+    {12031, "Proj_Massachusetts_CS83_Mainland"},
+    {12032, "Proj_Massachusetts_CS83_Island"},
+    {12101, "Proj_Michigan_State_Plane_East"},
+    {12102, "Proj_Michigan_State_Plane_Old_Central"},
+    {12103, "Proj_Michigan_State_Plane_West"},
+    {12111, "Proj_Michigan_CS27_North"},
+    {12112, "Proj_Michigan_CS27_Central"},
+    {12113, "Proj_Michigan_CS27_South"},
+    {12141, "Proj_Michigan_CS83_North"},
+    {12142, "Proj_Michigan_CS83_Central"},
+    {12143, "Proj_Michigan_CS83_South"},
+    {12201, "Proj_Minnesota_CS27_North"},
+    {12202, "Proj_Minnesota_CS27_Central"},
+    {12203, "Proj_Minnesota_CS27_South"},
+    {12231, "Proj_Minnesota_CS83_North"},
+    {12232, "Proj_Minnesota_CS83_Central"},
+    {12233, "Proj_Minnesota_CS83_South"},
+    {12301, "Proj_Mississippi_CS27_East"},
+    {12302, "Proj_Mississippi_CS27_West"},
+    {12331, "Proj_Mississippi_CS83_East"},
+    {12332, "Proj_Mississippi_CS83_West"},
+    {12401, "Proj_Missouri_CS27_East"},
+    {12402, "Proj_Missouri_CS27_Central"},
+    {12403, "Proj_Missouri_CS27_West"},
+    {12431, "Proj_Missouri_CS83_East"},
+    {12432, "Proj_Missouri_CS83_Central"},
+    {12433, "Proj_Missouri_CS83_West"},
+    {12501, "Proj_Montana_CS27_North"},
+    {12502, "Proj_Montana_CS27_Central"},
+    {12503, "Proj_Montana_CS27_South"},
+    {12530, "Proj_Montana_CS83"},
+    {12601, "Proj_Nebraska_CS27_North"},
+    {12602, "Proj_Nebraska_CS27_South"},
+    {12630, "Proj_Nebraska_CS83"},
+    {12701, "Proj_Nevada_CS27_East"},
+    {12702, "Proj_Nevada_CS27_Central"},
+    {12703, "Proj_Nevada_CS27_West"},
+    {12731, "Proj_Nevada_CS83_East"},
+    {12732, "Proj_Nevada_CS83_Central"},
+    {12733, "Proj_Nevada_CS83_West"},
+    {12800, "Proj_New_Hampshire_CS27"},
+    {12830, "Proj_New_Hampshire_CS83"},
+    {12900, "Proj_New_Jersey_CS27"},
+    {12930, "Proj_New_Jersey_CS83"},
+    {13001, "Proj_New_Mexico_CS27_East"},
+    {13002, "Proj_New_Mexico_CS27_Central"},
+    {13003, "Proj_New_Mexico_CS27_West"},
+    {13031, "Proj_New_Mexico_CS83_East"},
+    {13032, "Proj_New_Mexico_CS83_Central"},
+    {13033, "Proj_New_Mexico_CS83_West"},
+    {13101, "Proj_New_York_CS27_East"},
+    {13102, "Proj_New_York_CS27_Central"},
+    {13103, "Proj_New_York_CS27_West"},
+    {13104, "Proj_New_York_CS27_Long_Island"},
+    {13131, "Proj_New_York_CS83_East"},
+    {13132, "Proj_New_York_CS83_Central"},
+    {13133, "Proj_New_York_CS83_West"},
+    {13134, "Proj_New_York_CS83_Long_Island"},
+    {13200, "Proj_North_Carolina_CS27"},
+    {13230, "Proj_North_Carolina_CS83"},
+    {13301, "Proj_North_Dakota_CS27_North"},
+    {13302, "Proj_North_Dakota_CS27_South"},
+    {13331, "Proj_North_Dakota_CS83_North"},
+    {13332, "Proj_North_Dakota_CS83_South"},
+    {13401, "Proj_Ohio_CS27_North"},
+    {13402, "Proj_Ohio_CS27_South"},
+    {13431, "Proj_Ohio_CS83_North"},
+    {13432, "Proj_Ohio_CS83_South"},
+    {13501, "Proj_Oklahoma_CS27_North"},
+    {13502, "Proj_Oklahoma_CS27_South"},
+    {13531, "Proj_Oklahoma_CS83_North"},
+    {13532, "Proj_Oklahoma_CS83_South"},
+    {13601, "Proj_Oregon_CS27_North"},
+    {13602, "Proj_Oregon_CS27_South"},
+    {13631, "Proj_Oregon_CS83_North"},
+    {13632, "Proj_Oregon_CS83_South"},
+    {13701, "Proj_Pennsylvania_CS27_North"},
+    {13702, "Proj_Pennsylvania_CS27_South"},
+    {13731, "Proj_Pennsylvania_CS83_North"},
+    {13732, "Proj_Pennsylvania_CS83_South"},
+    {13800, "Proj_Rhode_Island_CS27"},
+    {13830, "Proj_Rhode_Island_CS83"},
+    {13901, "Proj_South_Carolina_CS27_North"},
+    {13902, "Proj_South_Carolina_CS27_South"},
+    {13930, "Proj_South_Carolina_CS83"},
+    {14001, "Proj_South_Dakota_CS27_North"},
+    {14002, "Proj_South_Dakota_CS27_South"},
+    {14031, "Proj_South_Dakota_CS83_North"},
+    {14032, "Proj_South_Dakota_CS83_South"},
+    {14100, "Proj_Tennessee_CS27"},
+    {14130, "Proj_Tennessee_CS83"},
+    {14201, "Proj_Texas_CS27_North"},
+    {14202, "Proj_Texas_CS27_North_Central"},
+    {14203, "Proj_Texas_CS27_Central"},
+    {14204, "Proj_Texas_CS27_South_Central"},
+    {14205, "Proj_Texas_CS27_South"},
+    {14231, "Proj_Texas_CS83_North"},
+    {14232, "Proj_Texas_CS83_North_Central"},
+    {14233, "Proj_Texas_CS83_Central"},
+    {14234, "Proj_Texas_CS83_South_Central"},
+    {14235, "Proj_Texas_CS83_South"},
+    {14301, "Proj_Utah_CS27_North"},
+    {14302, "Proj_Utah_CS27_Central"},
+    {14303, "Proj_Utah_CS27_South"},
+    {14331, "Proj_Utah_CS83_North"},
+    {14332, "Proj_Utah_CS83_Central"},
+    {14333, "Proj_Utah_CS83_South"},
+    {14400, "Proj_Vermont_CS27"},
+    {14430, "Proj_Vermont_CS83"},
+    {14501, "Proj_Virginia_CS27_North"},
+    {14502, "Proj_Virginia_CS27_South"},
+    {14531, "Proj_Virginia_CS83_North"},
+    {14532, "Proj_Virginia_CS83_South"},
+    {14601, "Proj_Washington_CS27_North"},
+    {14602, "Proj_Washington_CS27_South"},
+    {14631, "Proj_Washington_CS83_North"},
+    {14632, "Proj_Washington_CS83_South"},
+    {14701, "Proj_West_Virginia_CS27_North"},
+    {14702, "Proj_West_Virginia_CS27_South"},
+    {14731, "Proj_West_Virginia_CS83_North"},
+    {14732, "Proj_West_Virginia_CS83_South"},
+    {14801, "Proj_Wisconsin_CS27_North"},
+    {14802, "Proj_Wisconsin_CS27_Central"},
+    {14803, "Proj_Wisconsin_CS27_South"},
+    {14831, "Proj_Wisconsin_CS83_North"},
+    {14832, "Proj_Wisconsin_CS83_Central"},
+    {14833, "Proj_Wisconsin_CS83_South"},
+    {14901, "Proj_Wyoming_CS27_East"},
+    {14902, "Proj_Wyoming_CS27_East_Central"},
+    {14903, "Proj_Wyoming_CS27_West_Central"},
+    {14904, "Proj_Wyoming_CS27_West"},
+    {14931, "Proj_Wyoming_CS83_East"},
+    {14932, "Proj_Wyoming_CS83_East_Central"},
+    {14933, "Proj_Wyoming_CS83_West_Central"},
+    {14934, "Proj_Wyoming_CS83_West"},
+    {15001, "Proj_Alaska_CS27_1"},
+    {15002, "Proj_Alaska_CS27_2"},
+    {15003, "Proj_Alaska_CS27_3"},
+    {15004, "Proj_Alaska_CS27_4"},
+    {15005, "Proj_Alaska_CS27_5"},
+    {15006, "Proj_Alaska_CS27_6"},
+    {15007, "Proj_Alaska_CS27_7"},
+    {15008, "Proj_Alaska_CS27_8"},
+    {15009, "Proj_Alaska_CS27_9"},
+    {15010, "Proj_Alaska_CS27_10"},
+    {15031, "Proj_Alaska_CS83_1"},
+    {15032, "Proj_Alaska_CS83_2"},
+    {15033, "Proj_Alaska_CS83_3"},
+    {15034, "Proj_Alaska_CS83_4"},
+    {15035, "Proj_Alaska_CS83_5"},
+    {15036, "Proj_Alaska_CS83_6"},
+    {15037, "Proj_Alaska_CS83_7"},
+    {15038, "Proj_Alaska_CS83_8"},
+    {15039, "Proj_Alaska_CS83_9"},
+    {15040, "Proj_Alaska_CS83_10"},
+    {15101, "Proj_Hawaii_CS27_1"},
+    {15102, "Proj_Hawaii_CS27_2"},
+    {15103, "Proj_Hawaii_CS27_3"},
+    {15104, "Proj_Hawaii_CS27_4"},
+    {15105, "Proj_Hawaii_CS27_5"},
+    {15131, "Proj_Hawaii_CS83_1"},
+    {15132, "Proj_Hawaii_CS83_2"},
+    {15133, "Proj_Hawaii_CS83_3"},
+    {15134, "Proj_Hawaii_CS83_4"},
+    {15135, "Proj_Hawaii_CS83_5"},
+    {15201, "Proj_Puerto_Rico_CS27"},
+    {15202, "Proj_St_Croix"},
+    {15230, "Proj_Puerto_Rico_Virgin_Is"},
+    {15914, "Proj_BLM_14N_feet"},
+    {15915, "Proj_BLM_15N_feet"},
+    {15916, "Proj_BLM_16N_feet"},
+    {15917, "Proj_BLM_17N_feet"},
+    {17348, "Proj_Map_Grid_of_Australia_48"},
+    {17349, "Proj_Map_Grid_of_Australia_49"},
+    {17350, "Proj_Map_Grid_of_Australia_50"},
+    {17351, "Proj_Map_Grid_of_Australia_51"},
+    {17352, "Proj_Map_Grid_of_Australia_52"},
+    {17353, "Proj_Map_Grid_of_Australia_53"},
+    {17354, "Proj_Map_Grid_of_Australia_54"},
+    {17355, "Proj_Map_Grid_of_Australia_55"},
+    {17356, "Proj_Map_Grid_of_Australia_56"},
+    {17357, "Proj_Map_Grid_of_Australia_57"},
+    {17358, "Proj_Map_Grid_of_Australia_58"},
+    {17448, "Proj_Australian_Map_Grid_48"},
+    {17449, "Proj_Australian_Map_Grid_49"},
+    {17450, "Proj_Australian_Map_Grid_50"},
+    {17451, "Proj_Australian_Map_Grid_51"},
+    {17452, "Proj_Australian_Map_Grid_52"},
+    {17453, "Proj_Australian_Map_Grid_53"},
+    {17454, "Proj_Australian_Map_Grid_54"},
+    {17455, "Proj_Australian_Map_Grid_55"},
+    {17456, "Proj_Australian_Map_Grid_56"},
+    {17457, "Proj_Australian_Map_Grid_57"},
+    {17458, "Proj_Australian_Map_Grid_58"},
+    {18031, "Proj_Argentina_1"},
+    {18032, "Proj_Argentina_2"},
+    {18033, "Proj_Argentina_3"},
+    {18034, "Proj_Argentina_4"},
+    {18035, "Proj_Argentina_5"},
+    {18036, "Proj_Argentina_6"},
+    {18037, "Proj_Argentina_7"},
+    {18051, "Proj_Colombia_3W"},
+    {18052, "Proj_Colombia_Bogota"},
+    {18053, "Proj_Colombia_3E"},
+    {18054, "Proj_Colombia_6E"},
+    {18072, "Proj_Egypt_Red_Belt"},
+    {18073, "Proj_Egypt_Purple_Belt"},
+    {18074, "Proj_Extended_Purple_Belt"},
+    {18141, "Proj_New_Zealand_North_Island_Nat_Grid"},
+    {18142, "Proj_New_Zealand_South_Island_Nat_Grid"},
+    {19900, "Proj_Bahrain_Grid"},
+    {19905, "Proj_Netherlands_E_Indies_Equatorial"},
+    {19912, "Proj_RSO_Borneo"}
+};
+
+const char *const ff_tiff_coord_trans_codes[] = {
+    "CT_TransverseMercator",
+    "CT_TransvMercator_Modified_Alaska",
+    "CT_ObliqueMercator",
+    "CT_ObliqueMercator_Laborde",
+    "CT_ObliqueMercator_Rosenmund",
+    "CT_ObliqueMercator_Spherical",
+    "CT_Mercator",
+    "CT_LambertConfConic_2SP",
+    "CT_LambertConfConic_Helmert",
+    "CT_LambertAzimEqualArea",
+    "CT_AlbersEqualArea",
+    "CT_AzimuthalEquidistant",
+    "CT_EquidistantConic",
+    "CT_Stereographic",
+    "CT_PolarStereographic",
+    "CT_ObliqueStereographic",
+    "CT_Equirectangular",
+    "CT_CassiniSoldner",
+    "CT_Gnomonic",
+    "CT_MillerCylindrical",
+    "CT_Orthographic",
+    "CT_Polyconic",
+    "CT_Robinson",
+    "CT_Sinusoidal",
+    "CT_VanDerGrinten",
+    "CT_NewZealandMapGrid",
+    "CT_TransvMercator_SouthOriented"
+};
+
+const char *const ff_tiff_vert_cs_codes[] = {
+    "VertCS_Airy_1830_ellipsoid",
+    "VertCS_Airy_Modified_1849_ellipsoid",
+    "VertCS_ANS_ellipsoid",
+    "VertCS_Bessel_1841_ellipsoid",
+    "VertCS_Bessel_Modified_ellipsoid",
+    "VertCS_Bessel_Namibia_ellipsoid",
+    "VertCS_Clarke_1858_ellipsoid",
+    "VertCS_Clarke_1866_ellipsoid",
+    "VertCS_Clarke_1880_Benoit_ellipsoid",
+    "VertCS_Clarke_1880_IGN_ellipsoid",
+    "VertCS_Clarke_1880_RGS_ellipsoid",
+    "VertCS_Clarke_1880_Arc_ellipsoid",
+    "VertCS_Clarke_1880_SGA_1922_ellipsoid",
+    "VertCS_Everest_1830_1937_Adjustment_ellipsoid",
+    "VertCS_Everest_1830_1967_Definition_ellipsoid",
+    "VertCS_Everest_1830_1975_Definition_ellipsoid",
+    "VertCS_Everest_1830_Modified_ellipsoid",
+    "VertCS_GRS_1980_ellipsoid",
+    "VertCS_Helmert_1906_ellipsoid",
+    "VertCS_INS_ellipsoid",
+    "VertCS_International_1924_ellipsoid",
+    "VertCS_International_1967_ellipsoid",
+    "VertCS_Krassowsky_1940_ellipsoid",
+    "VertCS_NWL_9D_ellipsoid",
+    "VertCS_NWL_10D_ellipsoid",
+    "VertCS_Plessis_1817_ellipsoid",
+    "VertCS_Struve_1860_ellipsoid",
+    "VertCS_War_Office_ellipsoid",
+    "VertCS_WGS_84_ellipsoid",
+    "VertCS_GEM_10C_ellipsoid",
+    "VertCS_OSU86F_ellipsoid",
+    "VertCS_OSU91A_ellipsoid"
+};
+
+const char *const ff_tiff_ortho_vert_cs_codes[] = {
+    "VertCS_Newlyn",
+    "VertCS_North_American_Vertical_Datum_1929",
+    "VertCS_North_American_Vertical_Datum_1988",
+    "VertCS_Yellow_Sea_1956",
+    "VertCS_Baltic_Sea",
+    "VertCS_Caspian_Sea"
+};
diff --git a/libavcodec/tiff_data.h b/libavcodec/tiff_data.h
new file mode 100644
index 0000000..91a4e1e
--- /dev/null
+++ b/libavcodec/tiff_data.h
@@ -0,0 +1,92 @@
+/*
+ * TIFF data tables
+ * Copyright (c) 2011 Thomas Kuehnel
+ *
+ * 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
+ * TIFF data tables
+ * @author Thomas Kuehnel
+ * @see GeoTIFF specification at
+ * http://www.remotesensing.org/geotiff/spec/geotiffhome.html
+ */
+
+#ifndef AVCODEC_TIFF_DATA_H
+#define AVCODEC_TIFF_DATA_H
+
+#include "tiff.h"
+
+#define TIFF_CONF_KEY_ID_OFFSET 1024
+extern const TiffGeoTagNameType ff_tiff_conf_name_type_map[3];
+
+#define TIFF_GEOG_KEY_ID_OFFSET 2048
+extern const TiffGeoTagNameType ff_tiff_geog_name_type_map[14];
+
+#define TIFF_PROJ_KEY_ID_OFFSET 3072
+extern const TiffGeoTagNameType ff_tiff_proj_name_type_map[24];
+
+#define TIFF_VERT_KEY_ID_OFFSET 4096
+extern const TiffGeoTagNameType ff_tiff_vert_name_type_map[4];
+
+#define TIFF_GEO_KEY_UNDEFINED    0
+#define TIFF_GEO_KEY_USER_DEFINED 32767
+
+#define TIFF_GT_MODEL_TYPE_OFFSET 1
+extern const char *const ff_tiff_gt_model_type_codes[3];
+
+#define TIFF_GT_RASTER_TYPE_OFFSET 1
+extern const char *const ff_tiff_gt_raster_type_codes[2];
+
+#define TIFF_LINEAR_UNIT_OFFSET 9001
+extern const char *const ff_tiff_linear_unit_codes[15];
+
+#define TIFF_ANGULAR_UNIT_OFFSET 9101
+extern const char *const ff_tiff_angular_unit_codes[8];
+
+#define TIFF_GCS_TYPE_OFFSET 4201
+extern const char *const ff_tiff_gcs_type_codes[133];
+
+#define TIFF_GCSE_TYPE_OFFSET 4001
+extern const char *const ff_tiff_gcse_type_codes[35];
+
+#define TIFF_GEODETIC_DATUM_OFFSET 6201
+extern const char *const ff_tiff_geodetic_datum_codes[120];
+
+#define TIFF_GEODETIC_DATUM_E_OFFSET 6001
+extern const char *const ff_tiff_geodetic_datum_e_codes[35];
+
+#define TIFF_ELLIPSOID_OFFSET 7001
+extern const char *const ff_tiff_ellipsoid_codes[35];
+
+#define TIFF_PRIME_MERIDIAN_OFFSET 8901
+extern const char *const ff_tiff_prime_meridian_codes[11];
+
+extern const TiffGeoTagKeyName ff_tiff_proj_cs_type_codes[978];
+
+extern const TiffGeoTagKeyName ff_tiff_projection_codes[298];
+
+#define TIFF_COORD_TRANS_OFFSET 1
+extern const char *const ff_tiff_coord_trans_codes[27];
+
+#define TIFF_VERT_CS_OFFSET 5001
+extern const char *const ff_tiff_vert_cs_codes[32];
+
+#define TIFF_ORTHO_VERT_CS_OFFSET 5101
+extern const char *const ff_tiff_ortho_vert_cs_codes[6];
+#endif
diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c
index 9811404..c675c55 100644
--- a/libavcodec/tiffenc.c
+++ b/libavcodec/tiffenc.c
@@ -2,20 +2,20 @@
  * TIFF image encoder
  * Copyright (c) 2007 Bartlomiej Wolowiec
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,7 @@
  * @author Bartlomiej Wolowiec
  */
 
+#include "libavutil/imgutils.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
@@ -35,6 +36,7 @@
 #include <zlib.h>
 #endif
 #include "bytestream.h"
+#include "internal.h"
 #include "tiff.h"
 #include "rle.h"
 #include "lzw.h"
@@ -43,8 +45,8 @@
 #define TIFF_MAX_ENTRY 32
 
 /** sizes of various TIFF field types (string size = 1)*/
-static const uint8_t type_sizes2[6] = {
-    0, 1, 1, 2, 4, 8
+static const uint8_t type_sizes2[14] = {
+    0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 4
 };
 
 typedef struct TiffEncoderContext {
@@ -59,6 +61,12 @@
     int bpp_tab_size;                   ///< bpp_tab size
     int photometric_interpretation;     ///< photometric interpretation
     int strips;                         ///< number of strips
+    uint32_t *strip_sizes;
+    unsigned int strip_sizes_size;
+    uint32_t *strip_offsets;
+    unsigned int strip_offsets_size;
+    uint8_t *yuv_line;
+    unsigned int yuv_line_size;
     int rps;                            ///< row per strip
     uint8_t entries[TIFF_MAX_ENTRY*12]; ///< entires in header
     int num_entries;                    ///< number of entires
@@ -67,11 +75,13 @@
     int buf_size;                       ///< buffer size
     uint16_t subsampling[2];            ///< YUV subsampling factors
     struct LZWEncodeState *lzws;        ///< LZW Encode state
+    uint32_t dpi;                       ///< image resolution in DPI
 } TiffEncoderContext;
 
 
 /**
- * Check free space in buffer
+ * Check free space in buffer.
+ *
  * @param s Tiff context
  * @param need Needed bytes
  * @return 0 - ok, 1 - no free space
@@ -87,13 +97,13 @@
 }
 
 /**
- * Put n values to buffer
+ * Put n values to buffer.
  *
- * @param p Pointer to pointer to output buffer
- * @param n Number of values
- * @param val Pointer to values
- * @param type Type of values
- * @param flip =0 - normal copy, >0 - flip
+ * @param p pointer to pointer to output buffer
+ * @param n number of values
+ * @param val pointer to values
+ * @param type type of values
+ * @param flip = 0 - normal copy, >0 - flip
  */
 static void tnput(uint8_t ** p, int n, const uint8_t * val, enum TiffTypes type,
                   int flip)
@@ -108,11 +118,12 @@
 
 /**
  * Add entry to directory in tiff header.
+ *
  * @param s Tiff context
- * @param tag Tag that identifies the entry
- * @param type Entry type
- * @param count The number of values
- * @param ptr_val Pointer to values
+ * @param tag tag that identifies the entry
+ * @param type entry type
+ * @param count the number of values
+ * @param ptr_val pointer to values
  */
 static void add_entry(TiffEncoderContext * s,
                       enum TiffTags tag, enum TiffTypes type, int count,
@@ -120,7 +131,7 @@
 {
     uint8_t *entries_ptr = s->entries + 12 * s->num_entries;
 
-    assert(s->num_entries < TIFF_MAX_ENTRY);
+    av_assert0(s->num_entries < TIFF_MAX_ENTRY);
 
     bytestream_put_le16(&entries_ptr, tag);
     bytestream_put_le16(&entries_ptr, type);
@@ -145,14 +156,14 @@
 }
 
 /**
- * Encode one strip in tiff file
+ * Encode one strip in tiff file.
  *
  * @param s Tiff context
- * @param src Input buffer
- * @param dst Output buffer
- * @param n Size of input buffer
- * @param compr Compression method
- * @return Number of output bytes. If an output error is encountered, -1 returned
+ * @param src input buffer
+ * @param dst output buffer
+ * @param n size of input buffer
+ * @param compr compression method
+ * @return number of output bytes. If an output error is encountered, -1 is returned
  */
 static int encode_strip(TiffEncoderContext * s, const int8_t * src,
                         uint8_t * dst, int n, int compr)
@@ -192,90 +203,100 @@
     int w = (s->width - 1) / s->subsampling[0] + 1;
     uint8_t *pu = &p->data[1][lnum / s->subsampling[1] * p->linesize[1]];
     uint8_t *pv = &p->data[2][lnum / s->subsampling[1] * p->linesize[2]];
-    for (i = 0; i < w; i++){
-        for (j = 0; j < s->subsampling[1]; j++)
-            for (k = 0; k < s->subsampling[0]; k++)
-                *dst++ = p->data[0][(lnum + j) * p->linesize[0] +
-                                    i * s->subsampling[0] + k];
-        *dst++ = *pu++;
-        *dst++ = *pv++;
+    if(s->width % s->subsampling[0] || s->height % s->subsampling[1]){
+        for (i = 0; i < w; i++){
+            for (j = 0; j < s->subsampling[1]; j++)
+                for (k = 0; k < s->subsampling[0]; k++)
+                    *dst++ = p->data[0][FFMIN(lnum + j, s->height-1) * p->linesize[0] +
+                                        FFMIN(i * s->subsampling[0] + k, s->width-1)];
+            *dst++ = *pu++;
+            *dst++ = *pv++;
+        }
+    }else{
+        for (i = 0; i < w; i++){
+            for (j = 0; j < s->subsampling[1]; j++)
+                for (k = 0; k < s->subsampling[0]; k++)
+                    *dst++ = p->data[0][(lnum + j) * p->linesize[0] +
+                                        i * s->subsampling[0] + k];
+            *dst++ = *pu++;
+            *dst++ = *pv++;
+        }
     }
 }
 
+static av_cold int encode_init(AVCodecContext *avctx)
+{
+    TiffEncoderContext *s = avctx->priv_data;
+
+    avctx->coded_frame= &s->picture;
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    avctx->coded_frame->key_frame = 1;
+    s->avctx = avctx;
+
+    return 0;
+}
+
 static int encode_frame(AVCodecContext * avctx, AVPacket *pkt,
                         const AVFrame *pict, int *got_packet)
 {
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
     TiffEncoderContext *s = avctx->priv_data;
     AVFrame *const p = &s->picture;
     int i;
     uint8_t *ptr;
     uint8_t *offset;
     uint32_t strips;
-    uint32_t *strip_sizes = NULL;
-    uint32_t *strip_offsets = NULL;
     int bytes_per_row;
-    uint32_t res[2] = { 72, 1 };        // image resolution (72/1)
-    uint16_t bpp_tab[] = { 8, 8, 8, 8 };
-    int ret;
-    int is_yuv = 0;
-    uint8_t *yuv_line = NULL;
+    uint32_t res[2] = { s->dpi, 1 };        // image resolution (72/1)
+    uint16_t bpp_tab[4];
+    int ret = -1;
+    int is_yuv = 0, alpha = 0;
     int shift_h, shift_v;
-    const AVPixFmtDescriptor* pfd;
-
-    s->avctx = avctx;
 
     *p = *pict;
-    p->pict_type = AV_PICTURE_TYPE_I;
-    p->key_frame = 1;
-    avctx->coded_frame= &s->picture;
 
     s->width = avctx->width;
     s->height = avctx->height;
     s->subsampling[0] = 1;
     s->subsampling[1] = 1;
 
+    avctx->bits_per_coded_sample =
+    s->bpp = av_get_bits_per_pixel(desc);
+    s->bpp_tab_size = desc->nb_components;
+
     switch (avctx->pix_fmt) {
+    case AV_PIX_FMT_RGBA64LE:
+    case AV_PIX_FMT_RGBA:
+        alpha = 1;
     case AV_PIX_FMT_RGB48LE:
-    case AV_PIX_FMT_GRAY16LE:
     case AV_PIX_FMT_RGB24:
-    case AV_PIX_FMT_GRAY8:
-    case AV_PIX_FMT_PAL8:
-        pfd = av_pix_fmt_desc_get(avctx->pix_fmt);
-        s->bpp = av_get_bits_per_pixel(pfd);
-        if (pfd->flags & PIX_FMT_PAL) {
-            s->photometric_interpretation = 3;
-        } else if (pfd->flags & PIX_FMT_RGB) {
-            s->photometric_interpretation = 2;
-        } else {
-            s->photometric_interpretation = 1;
-        }
-        s->bpp_tab_size = pfd->nb_components;
-        for (i = 0; i < s->bpp_tab_size; i++) {
-            bpp_tab[i] = s->bpp / s->bpp_tab_size;
-        }
+        s->photometric_interpretation = 2;
         break;
+    case AV_PIX_FMT_GRAY8:
+        avctx->bits_per_coded_sample = 0x28;
+    case AV_PIX_FMT_GRAY8A:
+        alpha = avctx->pix_fmt == AV_PIX_FMT_GRAY8A;
+    case AV_PIX_FMT_GRAY16LE:
     case AV_PIX_FMT_MONOBLACK:
-        s->bpp = 1;
         s->photometric_interpretation = 1;
-        s->bpp_tab_size = 0;
+        break;
+    case AV_PIX_FMT_PAL8:
+        s->photometric_interpretation = 3;
         break;
     case AV_PIX_FMT_MONOWHITE:
-        s->bpp = 1;
         s->photometric_interpretation = 0;
-        s->bpp_tab_size = 0;
         break;
     case AV_PIX_FMT_YUV420P:
     case AV_PIX_FMT_YUV422P:
+    case AV_PIX_FMT_YUV440P:
     case AV_PIX_FMT_YUV444P:
     case AV_PIX_FMT_YUV410P:
     case AV_PIX_FMT_YUV411P:
         s->photometric_interpretation = 6;
         avcodec_get_chroma_sub_sample(avctx->pix_fmt,
                 &shift_h, &shift_v);
-        s->bpp = 8 + (16 >> (shift_h + shift_v));
         s->subsampling[0] = 1 << shift_h;
         s->subsampling[1] = 1 << shift_v;
-        s->bpp_tab_size = 3;
         is_yuv = 1;
         break;
     default:
@@ -284,6 +305,9 @@
         return -1;
     }
 
+    for (i = 0; i < s->bpp_tab_size; i++)
+        bpp_tab[i] = desc->comp[i].depth_minus1 + 1;
+
     if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE || s->compr == TIFF_LZW)
         //best choose for DEFLATE
         s->rps = s->height;
@@ -293,12 +317,9 @@
 
     strips = (s->height - 1) / s->rps + 1;
 
-    if (!pkt->data &&
-        (ret = av_new_packet(pkt, avctx->width * avctx->height * s->bpp * 2 +
-                                  avctx->height * 4 + FF_MIN_BUFFER_SIZE)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width * avctx->height * s->bpp * 2 +
+                                  avctx->height * 4 + FF_MIN_BUFFER_SIZE)) < 0)
         return ret;
-    }
     ptr          = pkt->data;
     s->buf_start = pkt->data;
     s->buf       = &ptr;
@@ -314,9 +335,10 @@
     offset = ptr;
     bytestream_put_le32(&ptr, 0);
 
-    strip_sizes = av_mallocz(sizeof(*strip_sizes) * strips);
-    strip_offsets = av_mallocz(sizeof(*strip_offsets) * strips);
-    if (!strip_sizes || !strip_offsets) {
+    av_fast_padded_mallocz(&s->strip_sizes, &s->strip_sizes_size, sizeof(s->strip_sizes[0]) * strips);
+    av_fast_padded_mallocz(&s->strip_offsets, &s->strip_offsets_size, sizeof(s->strip_offsets[0]) * strips);
+
+    if (!s->strip_sizes || !s->strip_offsets) {
         ret = AVERROR(ENOMEM);
         goto fail;
     }
@@ -324,8 +346,8 @@
     bytes_per_row = (((s->width - 1)/s->subsampling[0] + 1) * s->bpp
                     * s->subsampling[0] * s->subsampling[1] + 7) >> 3;
     if (is_yuv){
-        yuv_line = av_malloc(bytes_per_row);
-        if (yuv_line == NULL){
+        av_fast_padded_malloc(&s->yuv_line, &s->yuv_line_size, bytes_per_row);
+        if (s->yuv_line == NULL){
             av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n");
             ret = AVERROR(ENOMEM);
             goto fail;
@@ -344,12 +366,12 @@
             ret = AVERROR(ENOMEM);
             goto fail;
         }
-        strip_offsets[0] = ptr - pkt->data;
+        s->strip_offsets[0] = ptr - pkt->data;
         zn = 0;
         for (j = 0; j < s->rps; j++) {
             if (is_yuv){
-                pack_yuv(s, yuv_line, j);
-                memcpy(zbuf + zn, yuv_line, bytes_per_row);
+                pack_yuv(s, s->yuv_line, j);
+                memcpy(zbuf + zn, s->yuv_line, bytes_per_row);
                 j += s->subsampling[1] - 1;
             }
             else
@@ -364,7 +386,7 @@
             goto fail;
         }
         ptr += ret;
-        strip_sizes[0] = ptr - pkt->data - strip_offsets[0];
+        s->strip_sizes[0] = ptr - pkt->data - s->strip_offsets[0];
     } else
 #endif
     {
@@ -376,16 +398,16 @@
             }
         }
         for (i = 0; i < s->height; i++) {
-            if (strip_sizes[i / s->rps] == 0) {
+            if (s->strip_sizes[i / s->rps] == 0) {
                 if(s->compr == TIFF_LZW){
                     ff_lzw_encode_init(s->lzws, ptr, s->buf_size - (*s->buf - s->buf_start),
                                        12, FF_LZW_TIFF, put_bits);
                 }
-                strip_offsets[i / s->rps] = ptr - pkt->data;
+                s->strip_offsets[i / s->rps] = ptr - pkt->data;
             }
             if (is_yuv){
-                 pack_yuv(s, yuv_line, i);
-                 ret = encode_strip(s, yuv_line, ptr, bytes_per_row, s->compr);
+                 pack_yuv(s, s->yuv_line, i);
+                 ret = encode_strip(s, s->yuv_line, ptr, bytes_per_row, s->compr);
                  i += s->subsampling[1] - 1;
             }
             else
@@ -395,11 +417,11 @@
                 av_log(s->avctx, AV_LOG_ERROR, "Encode strip failed\n");
                 goto fail;
             }
-            strip_sizes[i / s->rps] += ret;
+            s->strip_sizes[i / s->rps] += ret;
             ptr += ret;
             if(s->compr == TIFF_LZW && (i==s->height-1 || i%s->rps == s->rps-1)){
                 ret = ff_lzw_encode_flush(s->lzws, flush_put_bits);
-                strip_sizes[(i / s->rps )] += ret ;
+                s->strip_sizes[(i / s->rps )] += ret ;
                 ptr += ret;
             }
         }
@@ -418,13 +440,13 @@
 
     add_entry1(s,TIFF_COMPR,             TIFF_SHORT,            s->compr);
     add_entry1(s,TIFF_INVERT,            TIFF_SHORT,            s->photometric_interpretation);
-    add_entry(s, TIFF_STRIP_OFFS,        TIFF_LONG,     strips, strip_offsets);
+    add_entry(s, TIFF_STRIP_OFFS,        TIFF_LONG,     strips, s->strip_offsets);
 
     if (s->bpp_tab_size)
     add_entry1(s,TIFF_SAMPLES_PER_PIXEL, TIFF_SHORT,            s->bpp_tab_size);
 
     add_entry1(s,TIFF_ROWSPERSTRIP,      TIFF_LONG,             s->rps);
-    add_entry(s, TIFF_STRIP_SIZE,        TIFF_LONG,     strips, strip_sizes);
+    add_entry(s, TIFF_STRIP_SIZE,        TIFF_LONG,     strips, s->strip_sizes);
     add_entry(s, TIFF_XRES,              TIFF_RATIONAL, 1,      res);
     add_entry(s, TIFF_YRES,              TIFF_RATIONAL, 1,      res);
     add_entry1(s,TIFF_RES_UNIT,          TIFF_SHORT,            2);
@@ -443,6 +465,8 @@
         }
         add_entry(s, TIFF_PAL, TIFF_SHORT, 256 * 3, pal);
     }
+    if (alpha)
+        add_entry1(s,TIFF_EXTRASAMPLES,      TIFF_SHORT,            2);
     if (is_yuv){
         /** according to CCIR Recommendation 601.1 */
         uint32_t refbw[12] = {15, 1, 235, 1, 128, 1, 240, 1, 128, 1, 240, 1};
@@ -464,15 +488,24 @@
     *got_packet = 1;
 
 fail:
-    av_free(strip_sizes);
-    av_free(strip_offsets);
-    av_free(yuv_line);
-    return ret;
+    return ret < 0 ? ret : 0;
+}
+
+static av_cold int encode_close(AVCodecContext *avctx)
+{
+    TiffEncoderContext *s = avctx->priv_data;
+
+    av_freep(&s->strip_sizes);
+    av_freep(&s->strip_offsets);
+    av_freep(&s->yuv_line);
+
+    return 0;
 }
 
 #define OFFSET(x) offsetof(TiffEncoderContext, x)
 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
+    {"dpi", "set the image resolution (in dpi)", OFFSET(dpi), AV_OPT_TYPE_INT, {.i64 = 72}, 1, 0x10000, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_ENCODING_PARAM},
     { "compression_algo", NULL, OFFSET(compr), AV_OPT_TYPE_INT, {.i64 = TIFF_PACKBITS}, TIFF_RAW, TIFF_DEFLATE, VE, "compression_algo" },
     { "packbits", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_PACKBITS}, 0, 0, VE, "compression_algo" },
     { "raw",      NULL, 0, AV_OPT_TYPE_CONST, {.i64 = TIFF_RAW},      0, 0, VE, "compression_algo" },
@@ -495,13 +528,16 @@
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_TIFF,
     .priv_data_size = sizeof(TiffEncoderContext),
+    .init           = encode_init,
     .encode2        = encode_frame,
+    .close          = encode_close,
     .pix_fmts       = (const enum AVPixelFormat[]) {
-        AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB48LE, AV_PIX_FMT_PAL8,
-        AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16LE,
+        AV_PIX_FMT_RGB24, AV_PIX_FMT_PAL8, AV_PIX_FMT_GRAY8,
+        AV_PIX_FMT_GRAY8A, AV_PIX_FMT_GRAY16LE,
         AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_MONOWHITE,
-        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P,
-        AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV444P,
+        AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV411P, AV_PIX_FMT_RGB48LE,
+        AV_PIX_FMT_RGBA, AV_PIX_FMT_RGBA64LE,
         AV_PIX_FMT_NONE
     },
     .long_name      = NULL_IF_CONFIG_SMALL("TIFF image"),
diff --git a/libavcodec/timecode.c b/libavcodec/timecode.c
new file mode 100644
index 0000000..f9862e5
--- /dev/null
+++ b/libavcodec/timecode.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2006 Smartjog S.A.S, Baptiste Coudurier <baptiste.coudurier@gmail.com>
+ * Copyright (C) 2011 Smartjog S.A.S, Clément Bœsch      <clement.boesch@smartjog.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
+ * Timecode helpers
+ * This *private* API is deprecated, please use the one available in libavutil instead.
+ */
+
+#include "version.h"
+
+#if FF_API_OLD_TIMECODE
+
+#include <stdio.h>
+#include "timecode.h"
+#include "libavutil/log.h"
+
+int avpriv_framenum_to_drop_timecode(int frame_num)
+{
+    /* only works for NTSC 29.97 */
+    int d = frame_num / 17982;
+    int m = frame_num % 17982;
+    //if (m < 2) m += 2; /* not needed since -2,-1 / 1798 in C returns 0 */
+    return frame_num + 18 * d + 2 * ((m - 2) / 1798);
+}
+
+uint32_t avpriv_framenum_to_smpte_timecode(unsigned frame, int fps, int drop)
+{
+    return (0                                    << 31) | // color frame flag
+           (drop                                 << 30) | // drop  frame flag
+           ( ((frame % fps) / 10)                << 28) | // tens  of frames
+           ( ((frame % fps) % 10)                << 24) | // units of frames
+           (0                                    << 23) | // field phase (NTSC), b0 (PAL)
+           ((((frame / fps) % 60) / 10)          << 20) | // tens  of seconds
+           ((((frame / fps) % 60) % 10)          << 16) | // units of seconds
+           (0                                    << 15) | // b0 (NTSC), b2 (PAL)
+           ((((frame / (fps * 60)) % 60) / 10)   << 12) | // tens  of minutes
+           ((((frame / (fps * 60)) % 60) % 10)   <<  8) | // units of minutes
+           (0                                    <<  7) | // b1
+           (0                                    <<  6) | // b2 (NTSC), field phase (PAL)
+           ((((frame / (fps * 3600) % 24)) / 10) <<  4) | // tens  of hours
+           (  (frame / (fps * 3600) % 24)) % 10;          // units of hours
+}
+
+int avpriv_check_timecode_rate(void *avcl, AVRational rate, int drop)
+{
+    int fps;
+
+    if (!rate.num || !rate.den) {
+        av_log(avcl, AV_LOG_ERROR, "Timecode frame rate must be specified\n");
+        return -1;
+    }
+    fps = (rate.num + rate.den/2) / rate.den;
+    if (drop && fps != 30) {
+        av_log(avcl, AV_LOG_ERROR, "Drop frame is only allowed with 30000/1001 FPS\n");
+        return -2;
+    }
+    switch (fps) {
+    case 24:
+    case 25:
+    case 30: return  0;
+
+    default:
+        av_log(avcl, AV_LOG_ERROR, "Timecode frame rate not supported\n");
+        return -3;
+    }
+}
+
+char *avpriv_timecode_to_string(char *buf, const struct ff_timecode *tc, unsigned frame)
+{
+    int frame_num = tc->start + frame;
+    int fps = (tc->rate.num + tc->rate.den/2) / tc->rate.den;
+    int hh, mm, ss, ff, neg = 0;
+
+    if (tc->drop)
+        frame_num = avpriv_framenum_to_drop_timecode(frame_num);
+    if (frame_num < 0) {
+        frame_num = -frame_num;
+        neg = 1;
+    }
+    ff = frame_num % fps;
+    ss = frame_num / fps        % 60;
+    mm = frame_num / (fps*60)   % 60;
+    hh = frame_num / (fps*3600);
+    snprintf(buf, 16, "%s%02d:%02d:%02d%c%02d",
+             neg ? "-" : "",
+             hh, mm, ss, tc->drop ? ';' : ':', ff);
+    return buf;
+}
+
+int avpriv_init_smpte_timecode(void *avcl, struct ff_timecode *tc)
+{
+    int hh, mm, ss, ff, fps, ret;
+    char c;
+
+    if (sscanf(tc->str, "%d:%d:%d%c%d", &hh, &mm, &ss, &c, &ff) != 5) {
+        av_log(avcl, AV_LOG_ERROR, "unable to parse timecode, "
+                                   "syntax: hh:mm:ss[:;.]ff\n");
+        return -1;
+    }
+
+    tc->drop  = c != ':'; // drop if ';', '.', ...
+
+    ret = avpriv_check_timecode_rate(avcl, tc->rate, tc->drop);
+    if (ret < 0)
+        return ret;
+
+    fps       = (tc->rate.num + tc->rate.den/2) / tc->rate.den;
+    tc->start = (hh*3600 + mm*60 + ss) * fps + ff;
+
+    if (tc->drop) { /* adjust frame number */
+        int tmins = 60*hh + mm;
+        tc->start -= 2 * (tmins - tmins/10);
+    }
+    return 0;
+}
+
+int ff_framenum_to_drop_timecode(int frame_num)
+{
+    return avpriv_framenum_to_drop_timecode(frame_num);
+}
+
+uint32_t ff_framenum_to_smtpe_timecode(unsigned frame, int fps, int drop)
+{
+    return avpriv_framenum_to_smpte_timecode(frame, fps, drop);
+}
+
+int ff_init_smtpe_timecode(void *avcl, struct ff_timecode *tc)
+{
+    return avpriv_init_smpte_timecode(avcl, tc);
+}
+#endif
diff --git a/libavcodec/timecode.h b/libavcodec/timecode.h
new file mode 100644
index 0000000..8bc69e9
--- /dev/null
+++ b/libavcodec/timecode.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2006 Smartjog S.A.S, Baptiste Coudurier <baptiste.coudurier@gmail.com>
+ * Copyright (C) 2011 Smartjog S.A.S, Clément Bœsch      <clement.boesch@smartjog.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
+ * Timecode helpers header
+ * This *private* API is deprecated, please use the one available in libavutil instead.
+ */
+
+#ifndef AVCODEC_TIMECODE_H
+#define AVCODEC_TIMECODE_H
+
+#include "version.h"
+
+#if FF_API_OLD_TIMECODE
+
+#include <stdint.h>
+#include "avcodec.h"
+#include "libavutil/rational.h"
+
+#define TIMECODE_OPT(ctx, flags)                                         \
+    "timecode", "set timecode value following hh:mm:ss[:;.]ff format, "  \
+                "use ';' or '.' before frame number for drop frame",     \
+    offsetof(ctx, tc.str),                                               \
+    AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, flags
+
+struct ff_timecode {
+    char *str;       ///< string following the hh:mm:ss[:;.]ff format
+    int start;       ///< timecode frame start
+    int drop;        ///< drop flag (1 if drop, else 0)
+    AVRational rate; ///< Frame rate in rational form
+};
+
+/**
+ * @brief           Adjust frame number for NTSC drop frame time code
+ * @param frame_num Actual frame number to adjust
+ * @return          Adjusted frame number
+ * @warning         Adjustment is only valid in NTSC 29.97
+ */
+int avpriv_framenum_to_drop_timecode(int frame_num);
+
+/**
+ * @brief       Convert frame id (timecode) to SMPTE 12M binary representation
+ * @param frame Frame number
+ * @param fps   Frame rate
+ * @param drop  Drop flag
+ * @return      The actual binary representation
+ */
+uint32_t avpriv_framenum_to_smpte_timecode(unsigned frame, int fps, int drop);
+
+/**
+ * @brief       Load timecode string in buf
+ * @param buf   Destination buffer
+ * @param tc    Timecode struct pointer
+ * @param frame Frame id (timecode frame is computed with tc->start+frame)
+ * @return a pointer to the buf parameter
+ * @note  timecode representation can be a negative timecode and have
+ *        more than 24 hours.
+ * @note  buf must have enough space to store the timecode representation: 16
+ *        bytes is the minimum required size.
+ */
+char *avpriv_timecode_to_string(char *buf, const struct ff_timecode *tc, unsigned frame);
+
+/**
+ * Check if timecode rate is valid and consistent with the drop flag.
+ *
+ * @return 0 on success, negative value on failure
+ */
+int avpriv_check_timecode_rate(void *avcl, AVRational rate, int drop);
+
+/**
+ * Parse SMTPE 12M time representation (hh:mm:ss[:;.]ff). str and rate fields
+ * from tc struct must be set.
+ *
+ * @param avcl A pointer to an arbitrary struct of which the first field is a
+ *             pointer to an AVClass struct (used for av_log).
+ * @param tc   Timecode struct pointer
+ * @return     0 on success, negative value on failure
+ * @warning    Adjustement is only valid in NTSC 29.97
+ */
+int avpriv_init_smpte_timecode(void *avcl, struct ff_timecode *tc);
+
+attribute_deprecated int ff_framenum_to_drop_timecode(int frame_num);
+attribute_deprecated uint32_t ff_framenum_to_smtpe_timecode(unsigned frame, int fps, int drop);
+attribute_deprecated int ff_init_smtpe_timecode(void *avcl, struct ff_timecode *tc);
+#endif
+
+#endif /* AVCODEC_TIMECODE_H */
diff --git a/libavcodec/tmv.c b/libavcodec/tmv.c
index 8533707..a0b3f36 100644
--- a/libavcodec/tmv.c
+++ b/libavcodec/tmv.c
@@ -2,20 +2,20 @@
  * 8088flex TMV video decoder
  * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,6 +30,7 @@
 
 #include "avcodec.h"
 #include "libavutil/internal.h"
+#include "libavutil/xga_font_data.h"
 
 #include "cga_data.h"
 
@@ -75,7 +76,7 @@
             bg = *src  >> 4;
             fg = *src++ & 0xF;
             ff_draw_pc_font(dst + x * 8, tmv->pic.linesize[0],
-                            ff_cga_font, 8, c, fg, bg);
+                            avpriv_cga_font, 8, c, fg, bg);
         }
         dst += tmv->pic.linesize[0] * 8;
     }
@@ -87,7 +88,9 @@
 
 static av_cold int tmv_decode_init(AVCodecContext *avctx)
 {
+    TMVContext *tmv = avctx->priv_data;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
+    avcodec_get_frame_defaults(&tmv->pic);
     return 0;
 }
 
diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c
index c2e1589..b46366b 100644
--- a/libavcodec/truemotion1.c
+++ b/libavcodec/truemotion1.c
@@ -2,20 +2,20 @@
  * Duck TrueMotion 1.0 Decoder
  * Copyright (C) 2003 Alex Beregszaszi & Mike Melanson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -316,7 +316,7 @@
     const uint8_t *sel_vector_table;
 
     header.header_size = ((s->buf[0] >> 5) | (s->buf[0] << 3)) & 0x7f;
-    if (s->buf[0] < 0x10)
+    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;
@@ -468,6 +468,7 @@
 //    else
 //        avctx->pix_fmt = AV_PIX_FMT_RGB555;
 
+    avcodec_get_frame_defaults(&s->frame);
     s->frame.data[0] = NULL;
 
     /* there is a vertical predictor for each pixel in a line; each vertical
@@ -513,6 +514,10 @@
 }
 
 #define APPLY_C_PREDICTOR() \
+    if(index > 1023){\
+        av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \
+        return; \
+    }\
     predictor_pair = s->c_predictor_table[index]; \
     horiz_pred += (predictor_pair >> 1); \
     if (predictor_pair & 1) { \
@@ -530,6 +535,10 @@
         index++;
 
 #define APPLY_C_PREDICTOR_24() \
+    if(index > 1023){\
+        av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \
+        return; \
+    }\
     predictor_pair = s->c_predictor_table[index]; \
     horiz_pred += (predictor_pair >> 1); \
     if (predictor_pair & 1) { \
@@ -548,6 +557,10 @@
 
 
 #define APPLY_Y_PREDICTOR() \
+    if(index > 1023){\
+        av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \
+        return; \
+    }\
     predictor_pair = s->y_predictor_table[index]; \
     horiz_pred += (predictor_pair >> 1); \
     if (predictor_pair & 1) { \
@@ -565,6 +578,10 @@
         index++;
 
 #define APPLY_Y_PREDICTOR_24() \
+    if(index > 1023){\
+        av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \
+        return; \
+    }\
     predictor_pair = s->y_predictor_table[index]; \
     horiz_pred += (predictor_pair >> 1); \
     if (predictor_pair & 1) { \
@@ -852,7 +869,7 @@
     if (truemotion1_decode_header(s) == -1)
         return -1;
 
-    s->frame.reference = 1;
+    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) {
diff --git a/libavcodec/truemotion1data.h b/libavcodec/truemotion1data.h
index e950450..3e58143 100644
--- a/libavcodec/truemotion1data.h
+++ b/libavcodec/truemotion1data.h
@@ -6,20 +6,20 @@
  * the GNU LGPL using the common understanding that data tables necessary
  * for decoding algorithms are not necessarily copyrightable.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #ifndef AVCODEC_TRUEMOTION1DATA_H
diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c
index b540eda..48a7a5b 100644
--- a/libavcodec/truemotion2.c
+++ b/libavcodec/truemotion2.c
@@ -2,20 +2,20 @@
  * Duck/ON2 TrueMotion 2 Decoder
  * Copyright (c) 2005 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -45,6 +45,9 @@
     GetBitContext gb;
     DSPContext dsp;
 
+    uint8_t *buffer;
+    int buffer_size;
+
     /* TM2 streams */
     int *tokens[TM2_NUM_STREAMS];
     int tok_lens[TM2_NUM_STREAMS];
@@ -67,7 +70,7 @@
 * Huffman codes for each of streams
 */
 typedef struct TM2Codes{
-    VLC vlc; ///< table for Libav bitstream reader
+    VLC vlc; ///< table for FFmpeg bitstream reader
     int bits;
     int *recode; ///< table for converting from code indexes to values
     int length;
@@ -219,8 +222,6 @@
         av_log (ctx->avctx, AV_LOG_ERROR, "Not a TM2 header: 0x%08X\n", magic);
         return -1;
     }
-
-    return buf - obuf;
 }
 
 static int tm2_read_deltas(TM2Context *ctx, int stream_id) {
@@ -256,6 +257,11 @@
     TM2Codes codes;
     GetByteContext gb;
 
+    if (buf_size < 4) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "not enough space for len left\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     /* get stream length in dwords */
     bytestream2_init(&gb, buf, buf_size);
     len  = bytestream2_get_be32(&gb);
@@ -264,9 +270,9 @@
     if(len == 0)
         return 4;
 
-    if (len >= INT_MAX/4-1 || len < 0 || len > buf_size) {
-        av_log(ctx->avctx, AV_LOG_ERROR, "Error, invalid stream size.\n");
-        return -1;
+    if (len >= INT_MAX/4-1 || len < 0 || skip > buf_size) {
+        av_log(ctx->avctx, AV_LOG_ERROR, "invalid stream size\n");
+        return AVERROR_INVALIDDATA;
     }
 
     toks = bytestream2_get_be32(&gb);
@@ -278,10 +284,10 @@
         if(len > 0) {
             pos = bytestream2_tell(&gb);
             if (skip <= pos)
-                return -1;
+                return AVERROR_INVALIDDATA;
             init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
             if(tm2_read_deltas(ctx, stream_id) == -1)
-                return -1;
+                return AVERROR_INVALIDDATA;
             bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2);
         }
     }
@@ -295,10 +301,10 @@
 
     pos = bytestream2_tell(&gb);
     if (skip <= pos)
-        return -1;
+        return AVERROR_INVALIDDATA;
     init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
     if(tm2_build_huff_table(ctx, &codes) == -1)
-        return -1;
+        return AVERROR_INVALIDDATA;
     bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2);
 
     toks >>= 1;
@@ -306,7 +312,7 @@
     if((toks < 0) || (toks > 0xFFFFFF)){
         av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks);
         tm2_free_codes(&codes);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     ctx->tokens[stream_id] = av_realloc(ctx->tokens[stream_id], toks * sizeof(int));
     ctx->tok_lens[stream_id] = toks;
@@ -314,12 +320,12 @@
     if(len > 0) {
         pos = bytestream2_tell(&gb);
         if (skip <= pos)
-            return -1;
+            return AVERROR_INVALIDDATA;
         init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
         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 -1;
+                return AVERROR_INVALIDDATA;
             }
             ctx->tokens[stream_id][i] = tm2_get_token(&ctx->gb, &codes);
             if (stream_id <= TM2_MOT && ctx->tokens[stream_id][i] >= TM2_DELTAS) {
@@ -348,8 +354,13 @@
         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;
+        }
         return ctx->deltas[type][ctx->tokens[type][ctx->tok_ptrs[type]++]];
+    }
     return ctx->tokens[type][ctx->tok_ptrs[type]++];
 }
 
@@ -654,6 +665,11 @@
     mx = av_clip(mx, -(bx * 4 + 4), ctx->avctx->width  - bx * 4);
     my = av_clip(my, -(by * 4 + 4), ctx->avctx->height - by * 4);
 
+    if (4*bx+mx<0 || 4*by+my<0 || 4*bx+mx+4 > ctx->avctx->width || 4*by+my+4 > ctx->avctx->height) {
+        av_log(0,0, "MV out of picture\n");
+        return;
+    }
+
     Yo += my * oYstride + mx;
     Uo += (my >> 1) * oUstride + (mx >> 1);
     Vo += (my >> 1) * oVstride + (mx >> 1);
@@ -818,38 +834,35 @@
     int buf_size = avpkt->size & ~3;
     TM2Context * const l = avctx->priv_data;
     AVFrame * const p = &l->pic;
-    int i, skip, t;
-    uint8_t *swbuf;
+    int i, ret, skip, t;
 
-    swbuf = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
-    if(!swbuf){
+    av_fast_padded_malloc(&l->buffer, &l->buffer_size, buf_size);
+    if(!l->buffer){
         av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
-        return -1;
+        return AVERROR(ENOMEM);
     }
-    p->reference = 1;
+    p->reference = 3;
     p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
-    if(avctx->reget_buffer(avctx, p) < 0){
+    if((ret = avctx->reget_buffer(avctx, p)) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-        av_free(swbuf);
-        return -1;
+        return ret;
     }
 
-    l->dsp.bswap_buf((uint32_t*)swbuf, (const uint32_t*)buf, buf_size >> 2);
-    skip = tm2_read_header(l, swbuf);
+    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){
-        av_free(swbuf);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     for(i = 0; i < TM2_NUM_STREAMS; i++){
         if (skip >= buf_size) {
-            av_free(swbuf);
+            av_log(avctx, AV_LOG_ERROR, "no space for tm2_read_stream\n");
             return AVERROR_INVALIDDATA;
         }
-        t = tm2_read_stream(l, swbuf + skip, tm2_stream_order[i], buf_size - skip);
+
+        t = tm2_read_stream(l, l->buffer + skip, tm2_stream_order[i], buf_size - skip);
         if(t < 0){
-            av_free(swbuf);
             return t;
         }
         skip += t;
@@ -863,7 +876,6 @@
     l->cur = !l->cur;
     *data_size = sizeof(AVFrame);
     *(AVFrame*)data = l->pic;
-    av_free(swbuf);
 
     return buf_size;
 }
@@ -874,12 +886,13 @@
 
     if((avctx->width & 3) || (avctx->height & 3)){
         av_log(avctx, AV_LOG_ERROR, "Width and height must be multiple of 4\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     l->avctx = avctx;
     l->pic.data[0]=NULL;
     avctx->pix_fmt = AV_PIX_FMT_BGR24;
+    avcodec_get_frame_defaults(&l->pic);
 
     ff_dsputil_init(&l->dsp, avctx);
 
@@ -944,6 +957,8 @@
         av_free(l->U2_base);
         av_free(l->V2_base);
     }
+    av_freep(&l->buffer);
+    l->buffer_size = 0;
 
     if (pic->data[0])
         avctx->release_buffer(avctx, pic);
diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c
index bbee146..6a1e439 100644
--- a/libavcodec/truespeech.c
+++ b/libavcodec/truespeech.c
@@ -2,20 +2,20 @@
  * DSP Group TrueSpeech compatible decoder
  * Copyright (c) 2005 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/truespeech_data.h b/libavcodec/truespeech_data.h
index 6e9806a..73ebda5 100644
--- a/libavcodec/truespeech_data.h
+++ b/libavcodec/truespeech_data.h
@@ -2,20 +2,20 @@
  * DSP Group TrueSpeech compatible decoder
  * copyright (c) 2005 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/tscc.c b/libavcodec/tscc.c
index 6c40e6c..1ba3bb9 100644
--- a/libavcodec/tscc.c
+++ b/libavcodec/tscc.c
@@ -2,20 +2,20 @@
  * TechSmith Camtasia decoder
  * Copyright (c) 2004 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -77,24 +77,21 @@
     CamtasiaContext * const c = avctx->priv_data;
     const unsigned char *encoded = buf;
     int zret; // Zlib return code
-    int len = buf_size;
+    int ret, len = buf_size;
 
-    if(c->pic.data[0])
-            avctx->release_buffer(avctx, &c->pic);
-
-    c->pic.reference = 1;
+    c->pic.reference = 3;
     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
-    if(avctx->get_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;
     }
 
     zret = inflateReset(&c->zstream);
     if (zret != Z_OK) {
         av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
-        return -1;
+        return AVERROR(EINVAL);
     }
-    c->zstream.next_in = encoded;
+    c->zstream.next_in = (uint8_t*)encoded;
     c->zstream.avail_in = len;
     c->zstream.next_out = c->decomp_buf;
     c->zstream.avail_out = c->decomp_size;
@@ -102,7 +99,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 -1;
+        return AVERROR(EINVAL);
     }
 
 
@@ -146,6 +143,7 @@
 
     c->height = avctx->height;
 
+    avcodec_get_frame_defaults(&c->pic);
     // Needed if zlib unused or init aborted before inflateInit
     memset(&c->zstream, 0, sizeof(z_stream));
     switch(avctx->bits_per_coded_sample){
@@ -156,7 +154,7 @@
              break;
     case 32: avctx->pix_fmt = AV_PIX_FMT_RGB32; break;
     default: av_log(avctx, AV_LOG_ERROR, "Camtasia error: unknown depth %i bpp\n", avctx->bits_per_coded_sample);
-             return -1;
+             return AVERROR_PATCHWELCOME;
     }
     c->bpp = avctx->bits_per_coded_sample;
     // buffer size for RLE 'best' case when 2-byte code precedes each pixel and there may be padding after it too
@@ -166,7 +164,7 @@
     if (c->decomp_size) {
         if ((c->decomp_buf = av_malloc(c->decomp_size)) == NULL) {
             av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
-            return 1;
+            return AVERROR(ENOMEM);
         }
     }
 
@@ -176,7 +174,7 @@
     zret = inflateInit(&c->zstream);
     if (zret != Z_OK) {
         av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
-        return 1;
+        return AVERROR(ENOMEM);
     }
 
     return 0;
diff --git a/libavcodec/tscc2.c b/libavcodec/tscc2.c
index 3628713..8692819 100644
--- a/libavcodec/tscc2.c
+++ b/libavcodec/tscc2.c
@@ -2,20 +2,20 @@
  * TechSmith Screen Codec 2 (aka Dora) decoder
  * Copyright (c) 2012 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/tscc2data.h b/libavcodec/tscc2data.h
index 70a06e5..4586da7 100644
--- a/libavcodec/tscc2data.h
+++ b/libavcodec/tscc2data.h
@@ -2,20 +2,20 @@
  * TechSmith Screen Codec 2 (aka Dora) decoder
  * Copyright (c) 2012 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/tta.c b/libavcodec/tta.c
index 7825c0c..ce41cb3 100644
--- a/libavcodec/tta.c
+++ b/libavcodec/tta.c
@@ -2,20 +2,20 @@
  * TTA (The Lossless True Audio) decoder
  * Copyright (c) 2006 Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -99,67 +99,35 @@
 //    c->round = 1 << (shift - 1);
 }
 
-// FIXME: copy paste from original
-static inline void memshl(register int32_t *a, register int32_t *b) {
-    *a++ = *b++;
-    *a++ = *b++;
-    *a++ = *b++;
-    *a++ = *b++;
-    *a++ = *b++;
-    *a++ = *b++;
-    *a++ = *b++;
-    *a = *b;
-}
-
 static inline void ttafilter_process(TTAFilter *c, int32_t *in)
 {
     register int32_t *dl = c->dl, *qm = c->qm, *dx = c->dx, sum = c->round;
 
-    if (!c->error) {
-        sum += *dl++ * *qm, qm++;
-        sum += *dl++ * *qm, qm++;
-        sum += *dl++ * *qm, qm++;
-        sum += *dl++ * *qm, qm++;
-        sum += *dl++ * *qm, qm++;
-        sum += *dl++ * *qm, qm++;
-        sum += *dl++ * *qm, qm++;
-        sum += *dl++ * *qm, qm++;
-        dx += 8;
-    } else if(c->error < 0) {
-        sum += *dl++ * (*qm -= *dx++), qm++;
-        sum += *dl++ * (*qm -= *dx++), qm++;
-        sum += *dl++ * (*qm -= *dx++), qm++;
-        sum += *dl++ * (*qm -= *dx++), qm++;
-        sum += *dl++ * (*qm -= *dx++), qm++;
-        sum += *dl++ * (*qm -= *dx++), qm++;
-        sum += *dl++ * (*qm -= *dx++), qm++;
-        sum += *dl++ * (*qm -= *dx++), qm++;
-    } else {
-        sum += *dl++ * (*qm += *dx++), qm++;
-        sum += *dl++ * (*qm += *dx++), qm++;
-        sum += *dl++ * (*qm += *dx++), qm++;
-        sum += *dl++ * (*qm += *dx++), qm++;
-        sum += *dl++ * (*qm += *dx++), qm++;
-        sum += *dl++ * (*qm += *dx++), qm++;
-        sum += *dl++ * (*qm += *dx++), qm++;
-        sum += *dl++ * (*qm += *dx++), qm++;
+    if (c->error < 0) {
+        qm[0] -= dx[0]; qm[1] -= dx[1]; qm[2] -= dx[2]; qm[3] -= dx[3];
+        qm[4] -= dx[4]; qm[5] -= dx[5]; qm[6] -= dx[6]; qm[7] -= dx[7];
+    } else if (c->error > 0) {
+        qm[0] += dx[0]; qm[1] += dx[1]; qm[2] += dx[2]; qm[3] += dx[3];
+        qm[4] += dx[4]; qm[5] += dx[5]; qm[6] += dx[6]; qm[7] += dx[7];
     }
 
-    *(dx-0) = ((*(dl-1) >> 30) | 1) << 2;
-    *(dx-1) = ((*(dl-2) >> 30) | 1) << 1;
-    *(dx-2) = ((*(dl-3) >> 30) | 1) << 1;
-    *(dx-3) = ((*(dl-4) >> 30) | 1);
+    sum += dl[0] * qm[0] + dl[1] * qm[1] + dl[2] * qm[2] + dl[3] * qm[3] +
+           dl[4] * qm[4] + dl[5] * qm[5] + dl[6] * qm[6] + dl[7] * qm[7];
+
+    dx[0] = dx[1]; dx[1] = dx[2]; dx[2] = dx[3]; dx[3] = dx[4];
+    dl[0] = dl[1]; dl[1] = dl[2]; dl[2] = dl[3]; dl[3] = dl[4];
+
+    dx[4] = ((dl[4] >> 30) | 1);
+    dx[5] = ((dl[5] >> 30) | 2) & ~1;
+    dx[6] = ((dl[6] >> 30) | 2) & ~1;
+    dx[7] = ((dl[7] >> 30) | 4) & ~3;
 
     c->error = *in;
     *in += (sum >> c->shift);
-    *dl = *in;
 
-    *(dl-1) = *dl - *(dl-1);
-    *(dl-2) = *(dl-1) - *(dl-2);
-    *(dl-3) = *(dl-2) - *(dl-3);
-
-    memshl(c->dl, c->dl + 1);
-    memshl(c->dx, c->dx + 1);
+    dl[4] = -dl[5]; dl[5] = -dl[6];
+    dl[6] = *in - dl[7]; dl[7] = *in;
+    dl[5] += dl[6]; dl[4] += dl[5];
 }
 
 static void rice_init(TTARice *c, uint32_t k0, uint32_t k1)
@@ -180,6 +148,16 @@
     return ret;
 }
 
+static const int64_t tta_channel_layouts[7] = {
+    AV_CH_LAYOUT_STEREO,
+    AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY,
+    AV_CH_LAYOUT_QUAD,
+    0,
+    AV_CH_LAYOUT_5POINT1_BACK,
+    AV_CH_LAYOUT_5POINT1_BACK|AV_CH_BACK_CENTER,
+    AV_CH_LAYOUT_7POINT1_WIDE
+};
+
 static int tta_check_crc(TTAContext *s, const uint8_t *buf, int buf_size)
 {
     uint32_t crc, CRC;
@@ -225,6 +203,8 @@
             return AVERROR(EINVAL);
         }
         avctx->channels = s->channels = get_bits(&s->gb, 16);
+        if (s->channels > 1 && s->channels < 9)
+            avctx->channel_layout = tta_channel_layouts[s->channels-2];
         avctx->bits_per_coded_sample = get_bits(&s->gb, 16);
         s->bps = (avctx->bits_per_coded_sample + 7) / 8;
         avctx->sample_rate = get_bits_long(&s->gb, 32);
@@ -240,6 +220,7 @@
         }
 
         switch(s->bps) {
+        case 1: avctx->sample_fmt = AV_SAMPLE_FMT_U8; break;
         case 2:
             avctx->sample_fmt = AV_SAMPLE_FMT_S16;
             avctx->bits_per_raw_sample = 16;
@@ -248,6 +229,7 @@
             avctx->sample_fmt = AV_SAMPLE_FMT_S32;
             avctx->bits_per_raw_sample = 24;
             break;
+        //case 4: avctx->sample_fmt = AV_SAMPLE_FMT_S32; break;
         default:
             av_log(avctx, AV_LOG_ERROR, "Invalid/unsupported sample format.\n");
             return AVERROR_INVALIDDATA;
@@ -270,12 +252,15 @@
         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;
+
         // FIXME: seek table
         if (avctx->extradata_size <= 26 || s->total_frames > INT_MAX / 4 ||
             avctx->extradata_size - 26 < s->total_frames * 4)
             av_log(avctx, AV_LOG_WARNING, "Seek table missing or too small\n");
         else if (avctx->err_recognition & AV_EF_CRCCHECK) {
-            if (tta_check_crc(s, avctx->extradata + 22, s->total_frames * 4))
+            if (avctx->extradata_size < 26 + s->total_frames * 4 || tta_check_crc(s, avctx->extradata + 22, s->total_frames * 4))
                 return AVERROR_INVALIDDATA;
         }
         skip_bits_long(&s->gb, 32 * s->total_frames);
@@ -286,11 +271,12 @@
             return -1;
         }
 
-        if (s->bps == 2) {
+        if (s->bps < 3) {
             s->decode_buffer = av_mallocz(sizeof(int32_t)*s->frame_length*s->channels);
             if (!s->decode_buffer)
                 return AVERROR(ENOMEM);
-        }
+        } else
+            s->decode_buffer = NULL;
         s->ch_ctx = av_malloc(avctx->channels * sizeof(*s->ch_ctx));
         if (!s->ch_ctx) {
             av_freep(&s->decode_buffer);
@@ -433,17 +419,28 @@
     skip_bits_long(&s->gb, 32); // frame crc
 
     // convert to output buffer
-    if (s->bps == 2) {
+    switch (s->bps) {
+    case 1: {
+        uint8_t *samples = (uint8_t *)s->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];
         for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++)
             *samples++ = *p;
-    } else {
+        break;
+        }
+    case 3: {
         // shift samples for 24-bit sample format
         int32_t *samples = (int32_t *)s->frame.data[0];
-        for (i = 0; i < framelen * s->channels; i++)
+        for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++)
             *samples++ <<= 8;
         // reset decode buffer
         s->decode_buffer = NULL;
+        break;
+        }
     }
 
     *got_frame_ptr   = 1;
@@ -460,7 +457,9 @@
 static av_cold int tta_decode_close(AVCodecContext *avctx) {
     TTAContext *s = avctx->priv_data;
 
-    av_free(s->decode_buffer);
+    if (s->bps < 3)
+        av_free(s->decode_buffer);
+    s->decode_buffer = NULL;
     av_freep(&s->ch_ctx);
 
     return 0;
diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c
index d009196..f47f4c3 100644
--- a/libavcodec/twinvq.c
+++ b/libavcodec/twinvq.c
@@ -2,20 +2,20 @@
  * TwinVQ decoder
  * Copyright (c) 2009 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -864,7 +864,7 @@
     }
 
     *got_frame_ptr   = 1;
-    *(AVFrame *)data = tctx->frame;;
+    *(AVFrame *)data = tctx->frame;
 
     return buf_size;
 }
diff --git a/libavcodec/twinvq_data.h b/libavcodec/twinvq_data.h
index a236127..63911f8 100644
--- a/libavcodec/twinvq_data.h
+++ b/libavcodec/twinvq_data.h
@@ -2,20 +2,20 @@
  * TwinVQ decoder
  * Copyright (c) 2009 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/txd.c b/libavcodec/txd.c
index 67c8a09..a526035 100644
--- a/libavcodec/txd.c
+++ b/libavcodec/txd.c
@@ -4,27 +4,27 @@
  *
  * See also: http://wiki.multimedia.cx/index.php?title=TXD
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/intreadwrite.h"
 #include "libavutil/imgutils.h"
-#include "avcodec.h"
 #include "bytestream.h"
+#include "avcodec.h"
 #include "s3tc.h"
 
 typedef struct TXDContext {
@@ -99,6 +99,8 @@
             v = bytestream2_get_be32(&gb);
             pal[y] = (v >> 8) + (v << 24);
         }
+        if (bytestream2_get_bytes_left(&gb) < w * h)
+            return AVERROR_INVALIDDATA;
         bytestream2_skip(&gb, 4);
         for (y=0; y<h; y++) {
             bytestream2_get_buffer(&gb, ptr, w);
@@ -111,9 +113,13 @@
             if (!(flags & 1))
                 goto unsupported;
         case FF_S3TC_DXT1:
+            if (bytestream2_get_bytes_left(&gb) < (w/4) * (h/4) * 8)
+                return AVERROR_INVALIDDATA;
             ff_decode_dxt1(&gb, ptr, w, h, stride);
             break;
         case FF_S3TC_DXT3:
+            if (bytestream2_get_bytes_left(&gb) < (w/4) * (h/4) * 16)
+                return AVERROR_INVALIDDATA;
             ff_decode_dxt3(&gb, ptr, w, h, stride);
             break;
         default:
@@ -123,6 +129,8 @@
         switch (d3d_format) {
         case 0x15:
         case 0x16:
+            if (bytestream2_get_bytes_left(&gb) < h * w * 4)
+                return AVERROR_INVALIDDATA;
             for (y=0; y<h; y++) {
                 bytestream2_get_buffer(&gb, ptr, w * 4);
                 ptr += stride;
diff --git a/libavcodec/ulti.c b/libavcodec/ulti.c
index 41faa3d..f6d6418 100644
--- a/libavcodec/ulti.c
+++ b/libavcodec/ulti.c
@@ -2,20 +2,20 @@
  * IBM Ultimotion Video Decoder
  * Copyright (C) 2004 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -51,6 +51,7 @@
     s->blocks = (s->width / 8) * (s->height / 8);
     avctx->pix_fmt = AV_PIX_FMT_YUV410P;
     avctx->coded_frame = &s->frame;
+    avctx->coded_frame = (AVFrame*) &s->frame;
     s->ulti_codebook = ulti_codebook;
 
     return 0;
@@ -225,7 +226,7 @@
     int skip;
     int tmp;
 
-    s->frame.reference = 1;
+    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) {
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
diff --git a/libavcodec/ulti_cb.h b/libavcodec/ulti_cb.h
index 0bd83ff..7061d83 100644
--- a/libavcodec/ulti_cb.h
+++ b/libavcodec/ulti_cb.h
@@ -2,20 +2,20 @@
  * IBM Ultimotion Video Decoder
  * copyright (C) 2004 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/unary.h b/libavcodec/unary.h
index d14929f..908dc93 100644
--- a/libavcodec/unary.h
+++ b/libavcodec/unary.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 4a3ac72..183776a 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -34,10 +34,12 @@
 #include "libavutil/imgutils.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/dict.h"
+#include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "dsputil.h"
 #include "libavutil/opt.h"
 #include "thread.h"
+#include "frame_thread_encoder.h"
 #include "audioconvert.h"
 #include "internal.h"
 #include "bytestream.h"
@@ -70,30 +72,47 @@
     return ptr;
 }
 
-void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
+static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc)
 {
     void **p = ptr;
     if (min_size < *size)
-        return;
+        return 0;
     min_size = FFMAX(17 * min_size / 16 + 32, min_size);
     av_free(*p);
-    *p = av_malloc(min_size);
+    *p = zero_realloc ? av_mallocz(min_size) : av_malloc(min_size);
     if (!*p)
         min_size = 0;
     *size = min_size;
+    return 1;
+}
+
+void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
+{
+    ff_fast_malloc(ptr, size, min_size, 0);
 }
 
 void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size)
 {
-    void **p = ptr;
+    uint8_t **p = ptr;
     if (min_size > SIZE_MAX - FF_INPUT_BUFFER_PADDING_SIZE) {
         av_freep(p);
         *size = 0;
         return;
     }
-    av_fast_malloc(p, size, min_size + FF_INPUT_BUFFER_PADDING_SIZE);
-    if (*size)
-        memset((uint8_t *)*p + min_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!ff_fast_malloc(p, size, min_size + FF_INPUT_BUFFER_PADDING_SIZE, 1))
+        memset(*p + min_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
+}
+
+void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size)
+{
+    uint8_t **p = ptr;
+    if (min_size > SIZE_MAX - FF_INPUT_BUFFER_PADDING_SIZE) {
+        av_freep(p);
+        *size = 0;
+        return;
+    }
+    if (!ff_fast_malloc(p, size, min_size + FF_INPUT_BUFFER_PADDING_SIZE, 1))
+        memset(*p, 0, min_size + FF_INPUT_BUFFER_PADDING_SIZE);
 }
 
 /* encoder management */
@@ -151,8 +170,8 @@
 {
     s->coded_width  = width;
     s->coded_height = height;
-    s->width        = width;
-    s->height       = height;
+    s->width        = -((-width ) >> s->lowres);
+    s->height       = -((-height) >> s->lowres);
 }
 
 #define INTERNAL_BUFFER_SIZE (32 + 1)
@@ -186,18 +205,34 @@
     case AV_PIX_FMT_YUV420P9BE:
     case AV_PIX_FMT_YUV420P10LE:
     case AV_PIX_FMT_YUV420P10BE:
+    case AV_PIX_FMT_YUV420P12LE:
+    case AV_PIX_FMT_YUV420P12BE:
+    case AV_PIX_FMT_YUV420P14LE:
+    case AV_PIX_FMT_YUV420P14BE:
     case AV_PIX_FMT_YUV422P9LE:
     case AV_PIX_FMT_YUV422P9BE:
     case AV_PIX_FMT_YUV422P10LE:
     case AV_PIX_FMT_YUV422P10BE:
+    case AV_PIX_FMT_YUV422P12LE:
+    case AV_PIX_FMT_YUV422P12BE:
+    case AV_PIX_FMT_YUV422P14LE:
+    case AV_PIX_FMT_YUV422P14BE:
     case AV_PIX_FMT_YUV444P9LE:
     case AV_PIX_FMT_YUV444P9BE:
     case AV_PIX_FMT_YUV444P10LE:
     case AV_PIX_FMT_YUV444P10BE:
+    case AV_PIX_FMT_YUV444P12LE:
+    case AV_PIX_FMT_YUV444P12BE:
+    case AV_PIX_FMT_YUV444P14LE:
+    case AV_PIX_FMT_YUV444P14BE:
     case AV_PIX_FMT_GBRP9LE:
     case AV_PIX_FMT_GBRP9BE:
     case AV_PIX_FMT_GBRP10LE:
     case AV_PIX_FMT_GBRP10BE:
+    case AV_PIX_FMT_GBRP12LE:
+    case AV_PIX_FMT_GBRP12BE:
+    case AV_PIX_FMT_GBRP14LE:
+    case AV_PIX_FMT_GBRP14BE:
         w_align = 16; //FIXME assume 16 pixel per macroblock
         h_align = 16 * 2; // interlaced needs 2 macroblocks height
         break;
@@ -237,10 +272,15 @@
         break;
     }
 
+    if (s->codec_id == AV_CODEC_ID_IFF_ILBM || s->codec_id == AV_CODEC_ID_IFF_BYTERUN1) {
+        w_align = FFMAX(w_align, 8);
+    }
+
     *width  = FFALIGN(*width, w_align);
     *height = FFALIGN(*height, h_align);
-    if (s->codec_id == AV_CODEC_ID_H264)
+    if (s->codec_id == AV_CODEC_ID_H264 || s->lowres)
         // some of the optimized chroma MC reads one line too much
+        // which is also done in mpeg decoders with lowres > 0
         *height += 2;
 
     for (i = 0; i < 4; i++)
@@ -262,6 +302,35 @@
     *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)
@@ -284,10 +353,10 @@
     }
 
     if ((ret = av_samples_fill_arrays(frame->extended_data, &frame->linesize[0],
-                                      buf, nb_channels, frame->nb_samples,
+                                      (uint8_t *)(intptr_t)buf, nb_channels, frame->nb_samples,
                                       sample_fmt, align)) < 0) {
         if (frame->extended_data != frame->data)
-            av_free(frame->extended_data);
+            av_freep(&frame->extended_data);
         return ret;
     }
     if (frame->extended_data != frame->data) {
@@ -366,16 +435,7 @@
     }
 
     frame->type = FF_BUFFER_TYPE_INTERNAL;
-
-    if (avctx->pkt)
-        frame->pkt_pts = avctx->pkt->pts;
-    else
-        frame->pkt_pts = AV_NOPTS_VALUE;
-    frame->reordered_opaque = avctx->reordered_opaque;
-
-    frame->sample_rate    = avctx->sample_rate;
-    frame->format         = avctx->sample_fmt;
-    frame->channel_layout = avctx->channel_layout;
+    ff_init_buffer_info(avctx, frame);
 
     if (avctx->debug & FF_DEBUG_BUFFERS)
         av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p, "
@@ -401,8 +461,10 @@
         return -1;
     }
 
-    if (av_image_check_size(w, h, 0, s))
+    if (av_image_check_size(w, h, 0, s) || s->pix_fmt<0) {
+        av_log(s, AV_LOG_ERROR, "video_get_buffer: image parameters invalid\n");
         return -1;
+    }
 
     if (!avci->buffer) {
         avci->buffer = av_mallocz((INTERNAL_BUFFER_SIZE + 1) *
@@ -468,7 +530,7 @@
 
             buf->base[i] = av_malloc(size[i] + 16); //FIXME 16
             if (buf->base[i] == NULL)
-                return -1;
+                return AVERROR(ENOMEM);
             memset(buf->base[i], 128, size[i]);
 
             // no edge if EDGE EMU or not planar YUV
@@ -499,13 +561,8 @@
     pic->width               = buf->width;
     pic->height              = buf->height;
     pic->format              = buf->pix_fmt;
-    pic->sample_aspect_ratio = s->sample_aspect_ratio;
 
-    if (s->pkt)
-        pic->pkt_pts = s->pkt->pts;
-    else
-        pic->pkt_pts = AV_NOPTS_VALUE;
-    pic->reordered_opaque = s->reordered_opaque;
+    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 "
@@ -532,7 +589,7 @@
     InternalBuffer *buf, *last;
     AVCodecInternal *avci = s->internal;
 
-    assert(s->codec_type == AVMEDIA_TYPE_VIDEO);
+    av_assert0(s->codec_type == AVMEDIA_TYPE_VIDEO);
 
     assert(pic->type == FF_BUFFER_TYPE_INTERNAL);
     assert(avci->buffer_count);
@@ -544,7 +601,7 @@
             if (buf->data[0] == pic->data[0])
                 break;
         }
-        assert(i < avci->buffer_count);
+        av_assert0(i < avci->buffer_count);
         avci->buffer_count--;
         last = &avci->buffer[avci->buffer_count];
 
@@ -566,7 +623,15 @@
     AVFrame temp_pic;
     int i;
 
-    assert(s->codec_type == AVMEDIA_TYPE_VIDEO);
+    av_assert0(s->codec_type == AVMEDIA_TYPE_VIDEO);
+
+    if (pic->data[0] && (pic->width != s->width || pic->height != s->height || pic->format != s->pix_fmt)) {
+        av_log(s, AV_LOG_WARNING, "Picture changed from size:%dx%d fmt:%s to size:%dx%d fmt:%s in reget buffer()\n",
+               pic->width, pic->height, av_get_pix_fmt_name(pic->format), s->width, s->height, av_get_pix_fmt_name(s->pix_fmt));
+        s->release_buffer(s, pic);
+    }
+
+    ff_init_buffer_info(s, pic);
 
     /* If no picture return a new buffer */
     if (pic->data[0] == NULL) {
@@ -579,11 +644,6 @@
 
     /* If internal buffer type return the same buffer */
     if (pic->type == FF_BUFFER_TYPE_INTERNAL) {
-        if (s->pkt)
-            pic->pkt_pts = s->pkt->pts;
-        else
-            pic->pkt_pts = AV_NOPTS_VALUE;
-        pic->reordered_opaque = s->reordered_opaque;
         return 0;
     }
 
@@ -637,12 +697,21 @@
 
 void avcodec_get_frame_defaults(AVFrame *frame)
 {
-    if (frame->extended_data != frame->data)
+#if LIBAVCODEC_VERSION_MAJOR >= 55
+     // extended_data should explicitly be freed when needed, this code is unsafe currently
+     // also this is not compatible to the <55 ABI/API
+    if (frame->extended_data != frame->data && 0)
         av_freep(&frame->extended_data);
+#endif
 
     memset(frame, 0, sizeof(AVFrame));
 
-    frame->pts                 = AV_NOPTS_VALUE;
+    frame->pts                   =
+    frame->pkt_dts               =
+    frame->pkt_pts               =
+    frame->best_effort_timestamp = AV_NOPTS_VALUE;
+    frame->pkt_duration        = 0;
+    frame->pkt_pos             = -1;
     frame->key_frame           = 1;
     frame->sample_aspect_ratio = (AVRational) {0, 1 };
     frame->format              = -1; /* unknown */
@@ -651,11 +720,12 @@
 
 AVFrame *avcodec_alloc_frame(void)
 {
-    AVFrame *frame = av_mallocz(sizeof(AVFrame));
+    AVFrame *frame = av_malloc(sizeof(AVFrame));
 
     if (frame == NULL)
         return NULL;
 
+    frame->extended_data = NULL;
     avcodec_get_frame_defaults(frame);
 
     return frame;
@@ -676,6 +746,58 @@
     av_freep(frame);
 }
 
+#define MAKE_ACCESSORS(str, name, type, field) \
+    type av_##name##_get_##field(const str *s) { return s->field; } \
+    void av_##name##_set_##field(str *s, type v) { s->field = v; }
+
+MAKE_ACCESSORS(AVFrame, frame, int64_t, best_effort_timestamp)
+MAKE_ACCESSORS(AVFrame, frame, int64_t, pkt_duration)
+MAKE_ACCESSORS(AVFrame, frame, int64_t, pkt_pos)
+MAKE_ACCESSORS(AVFrame, frame, int64_t, channel_layout)
+MAKE_ACCESSORS(AVFrame, frame, int,     channels)
+MAKE_ACCESSORS(AVFrame, frame, int,     sample_rate)
+MAKE_ACCESSORS(AVFrame, frame, AVDictionary *, metadata)
+MAKE_ACCESSORS(AVFrame, frame, int,     decode_error_flags)
+
+MAKE_ACCESSORS(AVCodecContext, codec, AVRational, pkt_timebase)
+MAKE_ACCESSORS(AVCodecContext, codec, const AVCodecDescriptor *, codec_descriptor)
+
+static void avcodec_get_subtitle_defaults(AVSubtitle *sub)
+{
+    memset(sub, 0, sizeof(*sub));
+    sub->pts = AV_NOPTS_VALUE;
+}
+
+static int get_bit_rate(AVCodecContext *ctx)
+{
+    int bit_rate;
+    int bits_per_sample;
+
+    switch (ctx->codec_type) {
+    case AVMEDIA_TYPE_VIDEO:
+    case AVMEDIA_TYPE_DATA:
+    case AVMEDIA_TYPE_SUBTITLE:
+    case AVMEDIA_TYPE_ATTACHMENT:
+        bit_rate = ctx->bit_rate;
+        break;
+    case AVMEDIA_TYPE_AUDIO:
+        bits_per_sample = av_get_bits_per_sample(ctx->codec_id);
+        bit_rate = bits_per_sample ? ctx->sample_rate * ctx->channels * bits_per_sample : ctx->bit_rate;
+        break;
+    default:
+        bit_rate = 0;
+        break;
+    }
+    return bit_rate;
+}
+
+#if FF_API_AVCODEC_OPEN
+int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec)
+{
+    return avcodec_open2(avctx, codec, NULL);
+}
+#endif
+
 int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
 {
     int ret = 0;
@@ -741,10 +863,21 @@
     if ((ret = av_opt_set_dict(avctx, &tmp)) < 0)
         goto free_and_end;
 
+    if (codec->capabilities & CODEC_CAP_EXPERIMENTAL)
+        if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
+            av_log(avctx, AV_LOG_ERROR, "Codec is experimental but experimental codecs are not enabled, try -strict -2\n");
+            ret = -1;
+            goto free_and_end;
+        }
+
+    //We only call avcodec_set_dimensions() for non h264 codecs so as not to overwrite previously setup dimensions
+    if (!( avctx->coded_width && avctx->coded_height && avctx->width && avctx->height && avctx->codec_id == AV_CODEC_ID_H264)){
+
     if (avctx->coded_width && avctx->coded_height)
         avcodec_set_dimensions(avctx, avctx->coded_width, avctx->coded_height);
     else if (avctx->width && avctx->height)
         avcodec_set_dimensions(avctx, avctx->width, avctx->height);
+    }
 
     if ((avctx->coded_width || avctx->coded_height || avctx->width || avctx->height)
         && (  av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx) < 0
@@ -777,6 +910,7 @@
         goto free_and_end;
     }
     avctx->frame_number = 0;
+    avctx->codec_descriptor = avcodec_descriptor_get(avctx->codec_id);
 
     if (avctx->codec_type == AVMEDIA_TYPE_AUDIO &&
         (!avctx->time_base.num || !avctx->time_base.den)) {
@@ -784,7 +918,19 @@
         avctx->time_base.den = avctx->sample_rate;
     }
 
-    if (HAVE_THREADS && !avctx->thread_opaque) {
+    if (!HAVE_THREADS)
+        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
+        ret = ff_frame_thread_encoder_init(avctx, options ? *options : NULL);
+        entangled_thread_counter++;
+        if (ret < 0)
+            goto free_and_end;
+    }
+
+    if (HAVE_THREADS && !avctx->thread_opaque
+        && !(avctx->internal->frame_thread_encoder && (avctx->active_thread_type&FF_THREAD_FRAME))) {
         ret = ff_thread_init(avctx);
         if (ret < 0) {
             goto free_and_end;
@@ -793,6 +939,13 @@
     if (!HAVE_THREADS && !(codec->capabilities & CODEC_CAP_AUTO_THREADS))
         avctx->thread_count = 1;
 
+    if (avctx->codec->max_lowres < avctx->lowres || avctx->lowres < 0) {
+        av_log(avctx, AV_LOG_ERROR, "The maximum value for lowres supported by the decoder is %d\n",
+               avctx->codec->max_lowres);
+        ret = AVERROR(EINVAL);
+        goto free_and_end;
+    }
+
     if (av_codec_is_encoder(avctx->codec)) {
         int i;
         if (avctx->codec->sample_fmts) {
@@ -816,7 +969,9 @@
             for (i = 0; avctx->codec->pix_fmts[i] != AV_PIX_FMT_NONE; i++)
                 if (avctx->pix_fmt == avctx->codec->pix_fmts[i])
                     break;
-            if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_NONE) {
+            if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_NONE
+                && !((avctx->codec_id == AV_CODEC_ID_MJPEG || avctx->codec_id == AV_CODEC_ID_LJPEG)
+                     && avctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL)) {
                 av_log(avctx, AV_LOG_ERROR, "Specified pix_fmt is not supported\n");
                 ret = AVERROR(EINVAL);
                 goto free_and_end;
@@ -857,14 +1012,24 @@
         }
     }
 
-    if (avctx->codec->init && !(avctx->active_thread_type & FF_THREAD_FRAME)) {
+    avctx->pts_correction_num_faulty_pts =
+    avctx->pts_correction_num_faulty_dts = 0;
+    avctx->pts_correction_last_pts =
+    avctx->pts_correction_last_dts = INT64_MIN;
+
+    if (   avctx->codec->init && (!(avctx->active_thread_type&FF_THREAD_FRAME)
+        || avctx->internal->frame_thread_encoder)) {
         ret = avctx->codec->init(avctx);
         if (ret < 0) {
             goto free_and_end;
         }
     }
 
+    ret=0;
+
     if (av_codec_is_decoder(avctx->codec)) {
+        if (!avctx->bit_rate)
+            avctx->bit_rate = get_bit_rate(avctx);
         /* validate channel layout from the decoder */
         if (avctx->channel_layout) {
             int channels = av_get_channel_layout_nb_channels(avctx->channel_layout);
@@ -898,26 +1063,48 @@
     goto end;
 }
 
-int ff_alloc_packet(AVPacket *avpkt, int size)
+int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int size)
 {
-    if (size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
+    if (size < 0 || avpkt->size < 0 || size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE) {
+        av_log(avctx, AV_LOG_ERROR, "Size %d invalid\n", size);
         return AVERROR(EINVAL);
+    }
+
+    if (avctx) {
+        av_assert0(!avpkt->data || avpkt->data != avctx->internal->byte_buffer);
+        if (!avpkt->data || avpkt->size < size) {
+            av_fast_padded_malloc(&avctx->internal->byte_buffer, &avctx->internal->byte_buffer_size, size);
+            avpkt->data = avctx->internal->byte_buffer;
+            avpkt->size = avctx->internal->byte_buffer_size;
+            avpkt->destruct = NULL;
+        }
+    }
 
     if (avpkt->data) {
         void *destruct = avpkt->destruct;
 
-        if (avpkt->size < size)
+        if (avpkt->size < size) {
+            av_log(avctx, AV_LOG_ERROR, "User packet is too small (%d < %d)\n", avpkt->size, size);
             return AVERROR(EINVAL);
+        }
 
         av_init_packet(avpkt);
         avpkt->destruct = destruct;
         avpkt->size     = size;
         return 0;
     } else {
-        return av_new_packet(avpkt, size);
+        int ret = av_new_packet(avpkt, size);
+        if (ret < 0)
+            av_log(avctx, AV_LOG_ERROR, "Failed to allocate packet of size %d\n", size);
+        return ret;
     }
 }
 
+int ff_alloc_packet(AVPacket *avpkt, int size)
+{
+    return ff_alloc_packet2(NULL, avpkt, size);
+}
+
 /**
  * Pad last frame with silence.
  */
@@ -972,7 +1159,8 @@
     AVFrame tmp;
     AVFrame *padded_frame = NULL;
     int ret;
-    int user_packet = !!avpkt->data;
+    AVPacket user_pkt = *avpkt;
+    int needs_realloc = !user_pkt.data;
 
     *got_packet_ptr = 0;
 
@@ -1001,8 +1189,10 @@
     /* check for valid frame size */
     if (frame) {
         if (avctx->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) {
-            if (frame->nb_samples > avctx->frame_size)
+            if (frame->nb_samples > avctx->frame_size) {
+                av_log(avctx, AV_LOG_ERROR, "more samples than frame size (avcodec_encode_audio2)\n");
                 return AVERROR(EINVAL);
+            }
         } else if (!(avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) {
             if (frame->nb_samples < avctx->frame_size &&
                 !avctx->internal->last_audio_frame) {
@@ -1015,6 +1205,7 @@
             }
 
             if (frame->nb_samples != avctx->frame_size) {
+                av_log(avctx, AV_LOG_ERROR, "nb_samples (%d) != frame_size (%d) (avcodec_encode_audio2)\n", frame->nb_samples, avctx->frame_size);
                 ret = AVERROR(EINVAL);
                 goto end;
             }
@@ -1035,9 +1226,29 @@
         } else {
             avpkt->size = 0;
         }
+    }
+    if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) {
+        needs_realloc = 0;
+        if (user_pkt.data) {
+            if (user_pkt.size >= avpkt->size) {
+                memcpy(user_pkt.data, avpkt->data, avpkt->size);
+            } else {
+                av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size);
+                avpkt->size = user_pkt.size;
+                ret = -1;
+            }
+            avpkt->data     = user_pkt.data;
+            avpkt->destruct = user_pkt.destruct;
+        } else {
+            if (av_dup_packet(avpkt) < 0) {
+                ret = AVERROR(ENOMEM);
+            }
+        }
+    }
 
-        if (!user_packet && avpkt->size) {
-            uint8_t *new_data = av_realloc(avpkt->data, avpkt->size);
+    if (!ret) {
+        if (needs_realloc && avpkt->data) {
+            uint8_t *new_data = av_realloc(avpkt->data, avpkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
             if (new_data)
                 avpkt->data = new_data;
         }
@@ -1118,8 +1329,11 @@
         /* fabricate frame pts from sample count.
          * this is needed because the avcodec_encode_audio() API does not have
          * a way for the user to provide pts */
-        frame->pts = ff_samples_to_time_base(avctx,
-                                             avctx->internal->sample_count);
+        if (avctx->sample_rate && avctx->time_base.num)
+            frame->pts = ff_samples_to_time_base(avctx,
+                                                 avctx->internal->sample_count);
+        else
+            frame->pts = AV_NOPTS_VALUE;
         avctx->internal->sample_count += frame->nb_samples;
     } else {
         frame = NULL;
@@ -1132,16 +1346,10 @@
         avctx->coded_frame->key_frame = !!(pkt.flags & AV_PKT_FLAG_KEY);
     }
     /* free any side data since we cannot return it */
-    if (pkt.side_data_elems > 0) {
-        int i;
-        for (i = 0; i < pkt.side_data_elems; i++)
-            av_free(pkt.side_data[i].data);
-        av_freep(&pkt.side_data);
-        pkt.side_data_elems = 0;
-    }
+    ff_packet_free_side_data(&pkt);
 
     if (frame && frame->extended_data != frame->data)
-        av_free(frame->extended_data);
+        av_freep(&frame->extended_data);
 
     return ret ? ret : pkt.size;
 }
@@ -1190,10 +1398,14 @@
                                               int *got_packet_ptr)
 {
     int ret;
-    int user_packet = !!avpkt->data;
+    AVPacket user_pkt = *avpkt;
+    int needs_realloc = !user_pkt.data;
 
     *got_packet_ptr = 0;
 
+    if(HAVE_THREADS && avctx->internal->frame_thread_encoder && (avctx->active_thread_type&FF_THREAD_FRAME))
+        return ff_thread_video_encode_frame(avctx, avpkt, frame, got_packet_ptr);
+
     if (!(avctx->codec->capabilities & CODEC_CAP_DELAY) && !frame) {
         av_free_packet(avpkt);
         av_init_packet(avpkt);
@@ -1207,14 +1419,36 @@
     av_assert0(avctx->codec->encode2);
 
     ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr);
+    av_assert0(ret <= 0);
+
+    if (avpkt->data && avpkt->data == avctx->internal->byte_buffer) {
+        needs_realloc = 0;
+        if (user_pkt.data) {
+            if (user_pkt.size >= avpkt->size) {
+                memcpy(user_pkt.data, avpkt->data, avpkt->size);
+            } else {
+                av_log(avctx, AV_LOG_ERROR, "Provided packet is too small, needs to be %d\n", avpkt->size);
+                avpkt->size = user_pkt.size;
+                ret = -1;
+            }
+            avpkt->data     = user_pkt.data;
+            avpkt->destruct = user_pkt.destruct;
+        } else {
+            if (av_dup_packet(avpkt) < 0) {
+                ret = AVERROR(ENOMEM);
+            }
+        }
+    }
+
     if (!ret) {
         if (!*got_packet_ptr)
             avpkt->size = 0;
         else if (!(avctx->codec->capabilities & CODEC_CAP_DELAY))
             avpkt->pts = avpkt->dts = frame->pts;
 
-        if (!user_packet && avpkt->size) {
-            uint8_t *new_data = av_realloc(avpkt->data, avpkt->size);
+        if (needs_realloc && avpkt->data &&
+            avpkt->destruct == av_destruct_packet) {
+            uint8_t *new_data = av_realloc(avpkt->data, avpkt->size + FF_INPUT_BUFFER_PADDING_SIZE);
             if (new_data)
                 avpkt->data = new_data;
         }
@@ -1237,13 +1471,44 @@
         av_log(avctx, AV_LOG_ERROR, "start_display_time must be 0.\n");
         return -1;
     }
-    if (sub->num_rects == 0 || !sub->rects)
-        return -1;
+
     ret = avctx->codec->encode_sub(avctx, buf, buf_size, sub);
     avctx->frame_number++;
     return ret;
 }
 
+/**
+ * Attempt to guess proper monotonic timestamps for decoded video frames
+ * which might have incorrect times. Input timestamps may wrap around, in
+ * which case the output will as well.
+ *
+ * @param pts the pts field of the decoded AVPacket, as passed through
+ * AVFrame.pkt_pts
+ * @param dts the dts field of the decoded AVPacket
+ * @return one of the input values, may be AV_NOPTS_VALUE
+ */
+static int64_t guess_correct_pts(AVCodecContext *ctx,
+                                 int64_t reordered_pts, int64_t dts)
+{
+    int64_t pts = AV_NOPTS_VALUE;
+
+    if (dts != AV_NOPTS_VALUE) {
+        ctx->pts_correction_num_faulty_dts += dts <= ctx->pts_correction_last_dts;
+        ctx->pts_correction_last_dts = dts;
+    }
+    if (reordered_pts != AV_NOPTS_VALUE) {
+        ctx->pts_correction_num_faulty_pts += reordered_pts <= ctx->pts_correction_last_pts;
+        ctx->pts_correction_last_pts = reordered_pts;
+    }
+    if ((ctx->pts_correction_num_faulty_pts<=ctx->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE)
+       && reordered_pts != AV_NOPTS_VALUE)
+        pts = reordered_pts;
+    else
+        pts = dts;
+
+    return pts;
+}
+
 static void apply_param_change(AVCodecContext *avctx, AVPacket *avpkt)
 {
     int size = 0;
@@ -1288,35 +1553,58 @@
 
 int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
                                               int *got_picture_ptr,
-                                              AVPacket *avpkt)
+                                              const AVPacket *avpkt)
 {
     int ret;
+    // copy to ensure we do not change avpkt
+    AVPacket tmp = *avpkt;
+
+    if (avctx->codec->type != AVMEDIA_TYPE_VIDEO) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid media type for video\n");
+        return AVERROR(EINVAL);
+    }
 
     *got_picture_ptr = 0;
     if ((avctx->coded_width || avctx->coded_height) && av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx))
-        return -1;
-
-    avctx->pkt = avpkt;
-    apply_param_change(avctx, avpkt);
+        return AVERROR(EINVAL);
 
     if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) {
+        int did_split = av_packet_split_side_data(&tmp);
+        apply_param_change(avctx, &tmp);
+        avctx->pkt = &tmp;
         if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME)
             ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr,
-                                         avpkt);
+                                         &tmp);
         else {
             ret = avctx->codec->decode(avctx, picture, got_picture_ptr,
-                                       avpkt);
+                                       &tmp);
             picture->pkt_dts             = avpkt->dts;
-            picture->sample_aspect_ratio = avctx->sample_aspect_ratio;
-            picture->width               = avctx->width;
-            picture->height              = avctx->height;
-            picture->format              = avctx->pix_fmt;
+
+            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;
         }
 
         emms_c(); //needed to avoid an emms_c() call before every return;
 
-        if (*got_picture_ptr)
+        avctx->pkt = NULL;
+        if (did_split) {
+            ff_packet_free_side_data(&tmp);
+            if(ret == tmp.size)
+                ret = avpkt->size;
+        }
+
+        if (*got_picture_ptr){
             avctx->frame_number++;
+            picture->best_effort_timestamp = guess_correct_pts(avctx,
+                                                            picture->pkt_pts,
+                                                            picture->pkt_dts);
+        }
     } else
         ret = 0;
 
@@ -1341,6 +1629,7 @@
         av_log(avctx, AV_LOG_ERROR, "Please port your application to "
                                     "avcodec_decode_audio4()\n");
         avctx->get_buffer = avcodec_default_get_buffer;
+        avctx->release_buffer = avcodec_default_release_buffer;
     }
 
     ret = avcodec_decode_audio4(avctx, &frame, &got_frame, avpkt);
@@ -1378,39 +1667,102 @@
 int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx,
                                               AVFrame *frame,
                                               int *got_frame_ptr,
-                                              AVPacket *avpkt)
+                                              const AVPacket *avpkt)
 {
     int planar, channels;
     int ret = 0;
 
     *got_frame_ptr = 0;
 
-    avctx->pkt = avpkt;
-
     if (!avpkt->data && avpkt->size) {
         av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n");
         return AVERROR(EINVAL);
     }
-
-    apply_param_change(avctx, avpkt);
+    if (avctx->codec->type != AVMEDIA_TYPE_AUDIO) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid media type for audio\n");
+        return AVERROR(EINVAL);
+    }
 
     if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) {
-        ret = avctx->codec->decode(avctx, frame, got_frame_ptr, avpkt);
+        uint8_t *side;
+        int side_size;
+        // copy to ensure we do not change avpkt
+        AVPacket tmp = *avpkt;
+        int did_split = av_packet_split_side_data(&tmp);
+        apply_param_change(avctx, &tmp);
+
+        avctx->pkt = &tmp;
+        ret = avctx->codec->decode(avctx, frame, got_frame_ptr, &tmp);
         if (ret >= 0 && *got_frame_ptr) {
             avctx->frame_number++;
             frame->pkt_dts = avpkt->dts;
+            frame->best_effort_timestamp = guess_correct_pts(avctx,
+                                                             frame->pkt_pts,
+                                                             frame->pkt_dts);
             if (frame->format == AV_SAMPLE_FMT_NONE)
                 frame->format = avctx->sample_fmt;
+            if (!frame->channel_layout)
+                frame->channel_layout = avctx->channel_layout;
+            if (!frame->channels)
+                frame->channels = avctx->channels;
+            if (!frame->sample_rate)
+                frame->sample_rate = avctx->sample_rate;
+        }
+
+        side= av_packet_get_side_data(avctx->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
+        if(side && side_size>=10) {
+            avctx->internal->skip_samples = AV_RL32(side);
+            av_log(avctx, AV_LOG_DEBUG, "skip %d samples due to side data\n",
+                   avctx->internal->skip_samples);
+        }
+        if (avctx->internal->skip_samples) {
+            if(frame->nb_samples <= avctx->internal->skip_samples){
+                *got_frame_ptr = 0;
+                avctx->internal->skip_samples -= frame->nb_samples;
+                av_log(avctx, AV_LOG_DEBUG, "skip whole frame, skip left: %d\n",
+                       avctx->internal->skip_samples);
+            } else {
+                av_samples_copy(frame->extended_data, frame->extended_data, 0, avctx->internal->skip_samples,
+                                frame->nb_samples - avctx->internal->skip_samples, avctx->channels, frame->format);
+                if(avctx->pkt_timebase.num && avctx->sample_rate) {
+                    int64_t diff_ts = av_rescale_q(avctx->internal->skip_samples,
+                                                   (AVRational){1, avctx->sample_rate},
+                                                   avctx->pkt_timebase);
+                    if(frame->pkt_pts!=AV_NOPTS_VALUE)
+                        frame->pkt_pts += diff_ts;
+                    if(frame->pkt_dts!=AV_NOPTS_VALUE)
+                        frame->pkt_dts += diff_ts;
+                    if (frame->pkt_duration >= diff_ts)
+                        frame->pkt_duration -= diff_ts;
+                } else {
+                    av_log(avctx, AV_LOG_WARNING, "Could not update timestamps for skipped samples.\n");
+                }
+                av_log(avctx, AV_LOG_DEBUG, "skip %d/%d samples\n",
+                       avctx->internal->skip_samples, frame->nb_samples);
+                frame->nb_samples -= avctx->internal->skip_samples;
+                avctx->internal->skip_samples = 0;
+            }
+        }
+
+        avctx->pkt = NULL;
+        if (did_split) {
+            ff_packet_free_side_data(&tmp);
+            if(ret == tmp.size)
+                ret = avpkt->size;
         }
     }
 
     /* many decoders assign whole AVFrames, thus overwriting extended_data;
      * make sure it's set correctly; assume decoders that actually use
      * extended_data are doing it correctly */
-    planar   = av_sample_fmt_is_planar(frame->format);
-    channels = av_get_channel_layout_nb_channels(frame->channel_layout);
-    if (!(planar && channels > AV_NUM_DATA_POINTERS))
-        frame->extended_data = frame->data;
+    if (*got_frame_ptr) {
+        planar   = av_sample_fmt_is_planar(frame->format);
+        channels = av_get_channel_layout_nb_channels(frame->channel_layout);
+        if (!(planar && channels > AV_NUM_DATA_POINTERS))
+            frame->extended_data = frame->data;
+    } else {
+        frame->extended_data = NULL;
+    }
 
     return ret;
 }
@@ -1421,8 +1773,17 @@
 {
     int ret;
 
+    if (avctx->codec->type != AVMEDIA_TYPE_SUBTITLE) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid media type for subtitles\n");
+        return AVERROR(EINVAL);
+    }
+
     avctx->pkt = avpkt;
     *got_sub_ptr = 0;
+    avcodec_get_subtitle_defaults(sub);
+    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, avpkt);
     if (*got_sub_ptr)
         avctx->frame_number++;
@@ -1464,12 +1825,19 @@
     }
 
     if (avcodec_is_open(avctx)) {
+        if (HAVE_THREADS && avctx->internal->frame_thread_encoder && avctx->thread_count > 1) {
+            entangled_thread_counter --;
+            ff_frame_thread_encoder_free(avctx);
+            entangled_thread_counter ++;
+        }
         if (HAVE_THREADS && avctx->thread_opaque)
             ff_thread_free(avctx);
         if (avctx->codec && avctx->codec->close)
             avctx->codec->close(avctx);
         avcodec_default_free_buffers(avctx);
         avctx->coded_frame = NULL;
+        avctx->internal->byte_buffer_size = 0;
+        av_freep(&avctx->internal->byte_buffer);
         av_freep(&avctx->internal);
     }
 
@@ -1490,10 +1858,22 @@
     return 0;
 }
 
+static enum AVCodecID remap_deprecated_codec_id(enum AVCodecID id)
+{
+    switch(id){
+        //This is for future deprecatec codec ids, its empty since
+        //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;
+        default                         : return id;
+    }
+}
+
 AVCodec *avcodec_find_encoder(enum AVCodecID id)
 {
     AVCodec *p, *experimental = NULL;
     p = first_avcodec;
+    id= remap_deprecated_codec_id(id);
     while (p) {
         if (av_codec_is_encoder(p) && p->id == id) {
             if (p->capabilities & CODEC_CAP_EXPERIMENTAL && !experimental) {
@@ -1522,14 +1902,19 @@
 
 AVCodec *avcodec_find_decoder(enum AVCodecID id)
 {
-    AVCodec *p;
+    AVCodec *p, *experimental=NULL;
     p = first_avcodec;
+    id= remap_deprecated_codec_id(id);
     while (p) {
-        if (av_codec_is_decoder(p) && p->id == id)
-            return p;
+        if (av_codec_is_decoder(p) && p->id == id) {
+            if (p->capabilities & CODEC_CAP_EXPERIMENTAL && !experimental) {
+                experimental = p;
+            } else
+                return p;
+        }
         p = p->next;
     }
-    return NULL;
+    return experimental;
 }
 
 AVCodec *avcodec_find_decoder_by_name(const char *name)
@@ -1546,36 +1931,38 @@
     return NULL;
 }
 
-static int get_bit_rate(AVCodecContext *ctx)
+const char *avcodec_get_name(enum AVCodecID id)
 {
-    int bit_rate;
-    int bits_per_sample;
+    const AVCodecDescriptor *cd;
+    AVCodec *codec;
 
-    switch (ctx->codec_type) {
-    case AVMEDIA_TYPE_VIDEO:
-    case AVMEDIA_TYPE_DATA:
-    case AVMEDIA_TYPE_SUBTITLE:
-    case AVMEDIA_TYPE_ATTACHMENT:
-        bit_rate = ctx->bit_rate;
-        break;
-    case AVMEDIA_TYPE_AUDIO:
-        bits_per_sample = av_get_bits_per_sample(ctx->codec_id);
-        bit_rate = bits_per_sample ? ctx->sample_rate * ctx->channels * bits_per_sample : ctx->bit_rate;
-        break;
-    default:
-        bit_rate = 0;
-        break;
-    }
-    return bit_rate;
+    if (id == AV_CODEC_ID_NONE)
+        return "none";
+    cd = avcodec_descriptor_get(id);
+    if (cd)
+        return cd->name;
+    av_log(NULL, AV_LOG_WARNING, "Codec 0x%x is not in the full list.\n", id);
+    codec = avcodec_find_decoder(id);
+    if (codec)
+        return codec->name;
+    codec = avcodec_find_encoder(id);
+    if (codec)
+        return codec->name;
+    return "unknown_codec";
 }
 
 size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag)
 {
     int i, len, ret = 0;
 
+#define IS_PRINT(x)                                               \
+    (((x) >= '0' && (x) <= '9') ||                                \
+     ((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z') ||  \
+     ((x) == '.' || (x) == ' ' || (x) == '-'))
+
     for (i = 0; i < 4; i++) {
         len = snprintf(buf, buf_size,
-                       isprint(codec_tag & 0xFF) ? "%c" : "[%d]", codec_tag & 0xFF);
+                       IS_PRINT(codec_tag&0xFF) ? "%c" : "[%d]", codec_tag&0xFF);
         buf        += len;
         buf_size    = buf_size > len ? buf_size - len : 0;
         ret        += len;
@@ -1586,45 +1973,41 @@
 
 void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
 {
+    const char *codec_type;
     const char *codec_name;
     const char *profile = NULL;
     const AVCodec *p;
-    char buf1[32];
     int bitrate;
     AVRational display_aspect_ratio;
 
-    if (enc->codec)
-        p = enc->codec;
-    else if (encode)
-        p = avcodec_find_encoder(enc->codec_id);
-    else
-        p = avcodec_find_decoder(enc->codec_id);
+    if (!buf || buf_size <= 0)
+        return;
+    codec_type = av_get_media_type_string(enc->codec_type);
+    codec_name = avcodec_get_name(enc->codec_id);
+    if (enc->profile != FF_PROFILE_UNKNOWN) {
+        if (enc->codec)
+            p = enc->codec;
+        else
+            p = encode ? avcodec_find_encoder(enc->codec_id) :
+                        avcodec_find_decoder(enc->codec_id);
+        if (p)
+            profile = av_get_profile_name(p, enc->profile);
+    }
 
-    if (p) {
-        codec_name = p->name;
-        profile = av_get_profile_name(p, enc->profile);
-    } else if (enc->codec_id == AV_CODEC_ID_MPEG2TS) {
-        /* fake mpeg2 transport stream codec (currently not
-         * registered) */
-        codec_name = "mpeg2ts";
-    } else if (enc->codec_name[0] != '\0') {
-        codec_name = enc->codec_name;
-    } else {
-        /* output avi tags */
+    snprintf(buf, buf_size, "%s: %s%s", codec_type ? codec_type : "unknown",
+             codec_name, enc->mb_decision ? " (hq)" : "");
+    buf[0] ^= 'a' ^ 'A'; /* first letter in uppercase */
+    if (profile)
+        snprintf(buf + strlen(buf), buf_size - strlen(buf), " (%s)", profile);
+    if (enc->codec_tag) {
         char tag_buf[32];
         av_get_codec_tag_string(tag_buf, sizeof(tag_buf), enc->codec_tag);
-        snprintf(buf1, sizeof(buf1), "%s / 0x%04X", tag_buf, enc->codec_tag);
-        codec_name = buf1;
+        snprintf(buf + strlen(buf), buf_size - strlen(buf),
+                 " (%s / 0x%04X)", tag_buf, enc->codec_tag);
     }
 
     switch (enc->codec_type) {
     case AVMEDIA_TYPE_VIDEO:
-        snprintf(buf, buf_size,
-                 "Video: %s%s",
-                 codec_name, enc->mb_decision ? " (hq)" : "");
-        if (profile)
-            snprintf(buf + strlen(buf), buf_size - strlen(buf),
-                     " (%s)", profile);
         if (enc->pix_fmt != AV_PIX_FMT_NONE) {
             snprintf(buf + strlen(buf), buf_size - strlen(buf),
                      ", %s",
@@ -1640,7 +2023,7 @@
                           enc->height * enc->sample_aspect_ratio.den,
                           1024 * 1024);
                 snprintf(buf + strlen(buf), buf_size - strlen(buf),
-                         " [PAR %d:%d DAR %d:%d]",
+                         " [SAR %d:%d DAR %d:%d]",
                          enc->sample_aspect_ratio.num, enc->sample_aspect_ratio.den,
                          display_aspect_ratio.num, display_aspect_ratio.den);
             }
@@ -1657,12 +2040,6 @@
         }
         break;
     case AVMEDIA_TYPE_AUDIO:
-        snprintf(buf, buf_size,
-                 "Audio: %s",
-                 codec_name);
-        if (profile)
-            snprintf(buf + strlen(buf), buf_size - strlen(buf),
-                     " (%s)", profile);
         if (enc->sample_rate) {
             snprintf(buf + strlen(buf), buf_size - strlen(buf),
                      ", %d Hz", enc->sample_rate);
@@ -1674,17 +2051,7 @@
                      ", %s", av_get_sample_fmt_name(enc->sample_fmt));
         }
         break;
-    case AVMEDIA_TYPE_DATA:
-        snprintf(buf, buf_size, "Data: %s", codec_name);
-        break;
-    case AVMEDIA_TYPE_SUBTITLE:
-        snprintf(buf, buf_size, "Subtitle: %s", codec_name);
-        break;
-    case AVMEDIA_TYPE_ATTACHMENT:
-        snprintf(buf, buf_size, "Attachment: %s", codec_name);
-        break;
     default:
-        snprintf(buf, buf_size, "Invalid Codec type %d", enc->codec_type);
         return;
     }
     if (encode) {
@@ -1717,18 +2084,25 @@
 
 unsigned avcodec_version(void)
 {
+//    av_assert0(AV_CODEC_ID_V410==164);
+    av_assert0(AV_CODEC_ID_PCM_S8_PLANAR==65563);
+    av_assert0(AV_CODEC_ID_ADPCM_G722==69660);
+//     av_assert0(AV_CODEC_ID_BMV_AUDIO==86071);
+    av_assert0(AV_CODEC_ID_SRT==94216);
+    av_assert0(LIBAVCODEC_VERSION_MICRO >= 100);
+
     return LIBAVCODEC_VERSION_INT;
 }
 
 const char *avcodec_configuration(void)
 {
-    return LIBAV_CONFIGURATION;
+    return FFMPEG_CONFIGURATION;
 }
 
 const char *avcodec_license(void)
 {
 #define LICENSE_PREFIX "libavcodec license: "
-    return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+    return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
 }
 
 void avcodec_flush_buffers(AVCodecContext *avctx)
@@ -1737,6 +2111,9 @@
         ff_thread_flush(avctx);
     else if (avctx->codec->flush)
         avctx->codec->flush(avctx);
+
+    avctx->pts_correction_last_pts =
+    avctx->pts_correction_last_dts = INT64_MIN;
 }
 
 static void video_free_buffers(AVCodecContext *s)
@@ -1774,7 +2151,7 @@
     if (buf->extended_data) {
         av_free(buf->extended_data[0]);
         if (buf->extended_data != buf->data)
-            av_free(buf->extended_data);
+            av_freep(&buf->extended_data);
     }
     av_freep(&avci->buffer);
 }
@@ -1836,6 +2213,27 @@
     }
 }
 
+enum AVCodecID av_get_pcm_codec(enum AVSampleFormat fmt, int be)
+{
+    static const enum AVCodecID map[AV_SAMPLE_FMT_NB][2] = {
+        [AV_SAMPLE_FMT_U8  ] = { AV_CODEC_ID_PCM_U8,    AV_CODEC_ID_PCM_U8    },
+        [AV_SAMPLE_FMT_S16 ] = { AV_CODEC_ID_PCM_S16LE, AV_CODEC_ID_PCM_S16BE },
+        [AV_SAMPLE_FMT_S32 ] = { AV_CODEC_ID_PCM_S32LE, AV_CODEC_ID_PCM_S32BE },
+        [AV_SAMPLE_FMT_FLT ] = { AV_CODEC_ID_PCM_F32LE, AV_CODEC_ID_PCM_F32BE },
+        [AV_SAMPLE_FMT_DBL ] = { AV_CODEC_ID_PCM_F64LE, AV_CODEC_ID_PCM_F64BE },
+        [AV_SAMPLE_FMT_U8P ] = { AV_CODEC_ID_PCM_U8,    AV_CODEC_ID_PCM_U8    },
+        [AV_SAMPLE_FMT_S16P] = { AV_CODEC_ID_PCM_S16LE, AV_CODEC_ID_PCM_S16BE },
+        [AV_SAMPLE_FMT_S32P] = { AV_CODEC_ID_PCM_S32LE, AV_CODEC_ID_PCM_S32BE },
+        [AV_SAMPLE_FMT_FLTP] = { AV_CODEC_ID_PCM_F32LE, AV_CODEC_ID_PCM_F32BE },
+        [AV_SAMPLE_FMT_DBLP] = { AV_CODEC_ID_PCM_F64LE, AV_CODEC_ID_PCM_F64BE },
+    };
+    if (fmt < 0 || fmt >= AV_SAMPLE_FMT_NB)
+        return AV_CODEC_ID_NONE;
+    if (be < 0 || be > 1)
+        be = AV_NE(1, 0);
+    return map[fmt][be];
+}
+
 int av_get_bits_per_sample(enum AVCodecID codec_id)
 {
     switch (codec_id) {
@@ -1866,8 +2264,8 @@
     bps = av_get_exact_bits_per_sample(avctx->codec_id);
 
     /* codecs with an exact constant bits per sample */
-    if (bps > 0 && ch > 0 && frame_bytes > 0)
-        return (frame_bytes * 8) / (bps * ch);
+    if (bps > 0 && ch > 0 && frame_bytes > 0 && ch < 32768 && bps < 32768)
+        return (frame_bytes * 8LL) / (bps * ch);
     bps = avctx->bits_per_coded_sample;
 
     /* codecs with a fixed packet duration */
@@ -1878,7 +2276,6 @@
     case AV_CODEC_ID_AMR_NB:
     case AV_CODEC_ID_GSM:
     case AV_CODEC_ID_QCELP:
-    case AV_CODEC_ID_RA_144:
     case AV_CODEC_ID_RA_288:       return  160;
     case AV_CODEC_ID_IMC:          return  256;
     case AV_CODEC_ID_AMR_WB:
@@ -1926,6 +2323,8 @@
             return 240 * (frame_bytes / 32);
         if (id == AV_CODEC_ID_NELLYMOSER)
             return 256 * (frame_bytes / 64);
+        if (id == AV_CODEC_ID_RA_144)
+            return 160 * (frame_bytes / 20);
 
         if (bps > 0) {
             /* calc from frame_bytes and bits_per_coded_sample */
@@ -1988,8 +2387,12 @@
                 /* calc from frame_bytes, channels, and bits_per_coded_sample */
                 switch (avctx->codec_id) {
                 case AV_CODEC_ID_PCM_DVD:
+                    if(bps<4)
+                        return 0;
                     return 2 * (frame_bytes / ((bps * 2 / 8) * ch));
                 case AV_CODEC_ID_PCM_BLURAY:
+                    if(bps<4)
+                        return 0;
                     return frame_bytes / ((FFALIGN(ch, 2) * bps) / 8);
                 case AV_CODEC_ID_S302M:
                     return 2 * (frame_bytes / ((bps + 4) / 4)) / ch;
@@ -2032,7 +2435,7 @@
 
 void av_log_missing_feature(void *avc, const char *feature, int want_sample)
 {
-    av_log(avc, AV_LOG_WARNING, "%s is not implemented. Update your Libav "
+    av_log(avc, AV_LOG_WARNING, "%s is not implemented. Update your FFmpeg "
             "version to the newest one from Git. If the problem still "
             "occurs, it means that your file has a feature which has not "
             "been implemented.\n", feature);
@@ -2049,8 +2452,8 @@
     if (msg)
         av_vlog(avc, AV_LOG_WARNING, msg, argument_list);
     av_log(avc, AV_LOG_WARNING, "If you want to help, upload a sample "
-            "of this file to ftp://upload.libav.org/incoming/ "
-            "and contact the libav-devel mailing list.\n");
+            "of this file to ftp://upload.ffmpeg.org/MPlayer/incoming/ "
+            "and contact the ffmpeg-devel mailing list.\n");
 
     va_end(argument_list);
 }
@@ -2133,6 +2536,9 @@
 int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f)
 {
     f->owner = avctx;
+
+    ff_init_buffer_info(avctx, f);
+
     return avctx->get_buffer(avctx, f);
 }
 
@@ -2153,10 +2559,21 @@
 {
 }
 
+int ff_thread_can_start_frame(AVCodecContext *avctx)
+{
+    return 1;
+}
+
 #endif
 
 enum AVMediaType avcodec_get_type(enum AVCodecID codec_id)
 {
+    AVCodec *c= avcodec_find_decoder(codec_id);
+    if(!c)
+        c= avcodec_find_encoder(codec_id);
+    if(c)
+        return c->type;
+
     if (codec_id <= AV_CODEC_ID_NONE)
         return AVMEDIA_TYPE_UNKNOWN;
     else if (codec_id < AV_CODEC_ID_FIRST_AUDIO)
diff --git a/libavcodec/utvideo.c b/libavcodec/utvideo.c
index eb5a924..308adb7 100644
--- a/libavcodec/utvideo.c
+++ b/libavcodec/utvideo.c
@@ -2,20 +2,20 @@
  * Common Ut Video code
  * Copyright (c) 2011 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/utvideo.h b/libavcodec/utvideo.h
index 0d7664c..266291c 100644
--- a/libavcodec/utvideo.h
+++ b/libavcodec/utvideo.h
@@ -2,20 +2,20 @@
  * Common Ut Video header
  * Copyright (c) 2011 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c
index c35a569..cfeb46b 100644
--- a/libavcodec/utvideodec.c
+++ b/libavcodec/utvideodec.c
@@ -2,20 +2,20 @@
  * Ut Video decoder
  * Copyright (c) 2011 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -335,15 +335,13 @@
     if (c->pic.data[0])
         ff_thread_release_buffer(avctx, &c->pic);
 
-    c->pic.reference = 1;
+    c->pic.reference = 3;
     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
     if ((ret = ff_thread_get_buffer(avctx, &c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
 
-    ff_thread_finish_setup(avctx);
-
     /* parse plane structure to get frame flags and validate slice offsets */
     bytestream2_init(&gb, buf, buf_size);
     for (i = 0; i < c->planes; i++) {
diff --git a/libavcodec/utvideoenc.c b/libavcodec/utvideoenc.c
index 085c415..14d301e 100644
--- a/libavcodec/utvideoenc.c
+++ b/libavcodec/utvideoenc.c
@@ -2,20 +2,20 @@
  * Ut Video encoder
  * Copyright (c) 2012 Jan Ekström
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -515,15 +515,11 @@
     int i, ret = 0;
 
     /* Allocate a new packet if needed, and set it to the pointer dst */
-    ret = ff_alloc_packet(pkt, (256 + 4 * c->slices + width * height) *
-                          c->planes + 4);
+    ret = ff_alloc_packet2(avctx, pkt, (256 + 4 * c->slices + width * height) *
+                           c->planes + 4);
 
-    if (ret < 0) {
-        av_log(avctx, AV_LOG_ERROR,
-               "Error allocating the output packet, or the provided packet "
-               "was too small.\n");
+    if (ret < 0)
         return ret;
-    }
 
     dst = pkt->data;
 
diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c
index aa08436..103e136 100644
--- a/libavcodec/v210dec.c
+++ b/libavcodec/v210dec.c
@@ -4,30 +4,54 @@
  * Copyright (C) 2009 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "avcodec.h"
+#include "v210dec.h"
 #include "libavutil/bswap.h"
 #include "libavutil/internal.h"
 #include "libavutil/mem.h"
 
+#define READ_PIXELS(a, b, c)         \
+    do {                             \
+        val  = av_le2ne32(*src++);   \
+        *a++ =  val & 0x3FF;         \
+        *b++ = (val >> 10) & 0x3FF;  \
+        *c++ = (val >> 20) & 0x3FF;  \
+    } while (0)
+
+static void v210_planar_unpack_c(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width)
+{
+    uint32_t val;
+    int i;
+
+    for( i = 0; i < width-5; i += 6 ){
+        READ_PIXELS(u, y, v);
+        READ_PIXELS(y, u, y);
+        READ_PIXELS(v, y, u);
+        READ_PIXELS(y, v, y);
+    }
+}
+
 static av_cold int decode_init(AVCodecContext *avctx)
 {
+    V210DecContext *s = avctx->priv_data;
+
     if (avctx->width & 1) {
         av_log(avctx, AV_LOG_ERROR, "v210 needs even width\n");
         return -1;
@@ -39,27 +63,53 @@
     if (!avctx->coded_frame)
         return AVERROR(ENOMEM);
 
+    s->unpack_frame            = v210_planar_unpack_c;
+
+    if (HAVE_MMX)
+        v210_x86_init(s);
+
     return 0;
 }
 
 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
                         AVPacket *avpkt)
 {
-    int h, w;
+    V210DecContext *s = avctx->priv_data;
+
+    int h, w, stride, aligned_input;
     AVFrame *pic = avctx->coded_frame;
     const uint8_t *psrc = avpkt->data;
     uint16_t *y, *u, *v;
-    int aligned_width = ((avctx->width + 47) / 48) * 48;
-    int stride = aligned_width * 8 / 3;
+
+    if (s->custom_stride )
+        stride = s->custom_stride;
+    else {
+        int aligned_width = ((avctx->width + 47) / 48) * 48;
+        stride = aligned_width * 8 / 3;
+    }
+
+    if (avpkt->size < stride * avctx->height) {
+        if ((((avctx->width + 23) / 24) * 24 * 8) / 3 * avctx->height == avpkt->size) {
+            stride = avpkt->size / avctx->height;
+            if (!s->stride_warning_shown)
+                av_log(avctx, AV_LOG_WARNING, "Broken v210 with too small padding (64 byte) detected\n");
+            s->stride_warning_shown = 1;
+        } else {
+            av_log(avctx, AV_LOG_ERROR, "packet too small\n");
+            return -1;
+        }
+    }
+
+    aligned_input = !((uintptr_t)psrc & 0xf) && !(stride & 0xf);
+    if (aligned_input != s->aligned_input) {
+        s->aligned_input = aligned_input;
+        if (HAVE_MMX)
+            v210_x86_init(s);
+    }
 
     if (pic->data[0])
         avctx->release_buffer(avctx, pic);
 
-    if (avpkt->size < stride * avctx->height) {
-        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
-        return -1;
-    }
-
     pic->reference = 0;
     if (avctx->get_buffer(avctx, pic) < 0)
         return -1;
@@ -70,36 +120,31 @@
     pic->pict_type = AV_PICTURE_TYPE_I;
     pic->key_frame = 1;
 
-#define READ_PIXELS(a, b, c)         \
-    do {                             \
-        val  = av_le2ne32(*src++);   \
-        *a++ =  val & 0x3FF;         \
-        *b++ = (val >> 10) & 0x3FF;  \
-        *c++ = (val >> 20) & 0x3FF;  \
-    } while (0)
-
     for (h = 0; h < avctx->height; h++) {
         const uint32_t *src = (const uint32_t*)psrc;
         uint32_t val;
-        for (w = 0; w < avctx->width - 5; w += 6) {
-            READ_PIXELS(u, y, v);
-            READ_PIXELS(y, u, y);
-            READ_PIXELS(v, y, u);
-            READ_PIXELS(y, v, y);
-        }
+
+        w = (avctx->width / 6) * 6;
+        s->unpack_frame(src, y, u, v, w);
+
+        y += w;
+        u += w >> 1;
+        v += w >> 1;
+        src += (w << 1) / 3;
+
         if (w < avctx->width - 1) {
             READ_PIXELS(u, y, v);
 
             val  = av_le2ne32(*src++);
             *y++ =  val & 0x3FF;
-        }
-        if (w < avctx->width - 3) {
-            *u++ = (val >> 10) & 0x3FF;
-            *y++ = (val >> 20) & 0x3FF;
+            if (w < avctx->width - 3) {
+                *u++ = (val >> 10) & 0x3FF;
+                *y++ = (val >> 20) & 0x3FF;
 
-            val  = av_le2ne32(*src++);
-            *v++ =  val & 0x3FF;
-            *y++ = (val >> 10) & 0x3FF;
+                val  = av_le2ne32(*src++);
+                *v++ =  val & 0x3FF;
+                *y++ = (val >> 10) & 0x3FF;
+            }
         }
 
         psrc += stride;
@@ -124,13 +169,29 @@
     return 0;
 }
 
+#define V210DEC_FLAGS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption v210dec_options[] = {
+    {"custom_stride", "Custom V210 stride", offsetof(V210DecContext, custom_stride), FF_OPT_TYPE_INT,
+     {.dbl = 0}, INT_MIN, INT_MAX, V210DEC_FLAGS},
+    {NULL}
+};
+
+static const AVClass v210dec_class = {
+    "V210 Decoder",
+    av_default_item_name,
+    v210dec_options,
+    LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_v210_decoder = {
     .name           = "v210",
     .type           = AVMEDIA_TYPE_VIDEO,
     .id             = AV_CODEC_ID_V210,
+    .priv_data_size = sizeof(V210DecContext),
     .init           = decode_init,
     .close          = decode_close,
     .decode         = decode_frame,
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
+    .priv_class     = &v210dec_class,
 };
diff --git a/libavcodec/v210dec.h b/libavcodec/v210dec.h
new file mode 100644
index 0000000..e1e3d32
--- /dev/null
+++ b/libavcodec/v210dec.h
@@ -0,0 +1,36 @@
+/*
+ * 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 AVCODEC_V210DEC_H
+#define AVCODEC_V210DEC_H
+
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+
+
+typedef struct {
+    AVClass *av_class;
+    int custom_stride;
+    int aligned_input;
+    int stride_warning_shown;
+    void (*unpack_frame)(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width);
+} V210DecContext;
+
+void v210_x86_init(V210DecContext *s);
+
+#endif /* AVCODEC_V210DEC_H */
diff --git a/libavcodec/v210enc.c b/libavcodec/v210enc.c
index ad8a4a5..5527686 100644
--- a/libavcodec/v210enc.c
+++ b/libavcodec/v210enc.c
@@ -4,20 +4,20 @@
  * Copyright (C) 2009 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -57,10 +57,8 @@
     const uint16_t *v = (const uint16_t*)pic->data[2];
     PutByteContext p;
 
-    if ((ret = ff_alloc_packet(pkt, avctx->height * stride)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, avctx->height * stride)) < 0)
         return ret;
-    }
 
     bytestream2_init_writer(&p, pkt->data, pkt->size);
 
@@ -88,13 +86,13 @@
             val = CLIP(*y++);
             if (w == avctx->width - 2)
                 bytestream2_put_le32u(&p, val);
-        }
-        if (w < avctx->width - 3) {
-            val |= (CLIP(*u++) << 10) | (CLIP(*y++) << 20);
-            bytestream2_put_le32u(&p, val);
+            if (w < avctx->width - 3) {
+                val |= (CLIP(*u++) << 10) | (CLIP(*y++) << 20);
+                bytestream2_put_le32u(&p, val);
 
-            val = CLIP(*v++) | (CLIP(*y++) << 10);
-            bytestream2_put_le32u(&p, val);
+                val = CLIP(*v++) | (CLIP(*y++) << 10);
+                bytestream2_put_le32u(&p, val);
+            }
         }
 
         bytestream2_set_buffer(&p, 0, line_padding);
diff --git a/libavcodec/v210x.c b/libavcodec/v210x.c
index 4aad304..376588c 100644
--- a/libavcodec/v210x.c
+++ b/libavcodec/v210x.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2009 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -33,6 +33,8 @@
     avctx->bits_per_raw_sample= 10;
 
     avctx->coded_frame= avcodec_alloc_frame();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
 
     return 0;
 }
diff --git a/libavcodec/v308dec.c b/libavcodec/v308dec.c
new file mode 100644
index 0000000..fd742ca
--- /dev/null
+++ b/libavcodec/v308dec.c
@@ -0,0 +1,108 @@
+/*
+ * v308 decoder
+ * Copyright (c) 2011 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"
+
+static av_cold int v308_decode_init(AVCodecContext *avctx)
+{
+    avctx->pix_fmt = AV_PIX_FMT_YUV444P;
+
+    if (avctx->width & 1)
+        av_log(avctx, AV_LOG_WARNING, "v308 requires width to be even.\n");
+
+    avctx->coded_frame = avcodec_alloc_frame();
+
+    if (!avctx->coded_frame) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int v308_decode_frame(AVCodecContext *avctx, void *data,
+                             int *data_size, AVPacket *avpkt)
+{
+    AVFrame *pic = avctx->coded_frame;
+    const uint8_t *src = avpkt->data;
+    uint8_t *y, *u, *v;
+    int i, j;
+
+    if (pic->data[0])
+        avctx->release_buffer(avctx, pic);
+
+    if (avpkt->size < 3 * avctx->height * avctx->width) {
+        av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
+        return AVERROR(EINVAL);
+    }
+
+    pic->reference = 0;
+
+    if (avctx->get_buffer(avctx, pic) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    pic->key_frame = 1;
+    pic->pict_type = AV_PICTURE_TYPE_I;
+
+    y = pic->data[0];
+    u = pic->data[1];
+    v = pic->data[2];
+
+    for (i = 0; i < avctx->height; i++) {
+        for (j = 0; j < avctx->width; j++) {
+            v[j] = *src++;
+            y[j] = *src++;
+            u[j] = *src++;
+        }
+
+        y += pic->linesize[0];
+        u += pic->linesize[1];
+        v += pic->linesize[2];
+    }
+
+    *data_size = sizeof(AVFrame);
+    *(AVFrame *)data = *pic;
+
+    return avpkt->size;
+}
+
+static av_cold int v308_decode_close(AVCodecContext *avctx)
+{
+    if (avctx->coded_frame->data[0])
+        avctx->release_buffer(avctx, avctx->coded_frame);
+
+    av_freep(&avctx->coded_frame);
+
+    return 0;
+}
+
+AVCodec ff_v308_decoder = {
+    .name         = "v308",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_V308,
+    .init         = v308_decode_init,
+    .decode       = v308_decode_frame,
+    .close        = v308_decode_close,
+    .capabilities = CODEC_CAP_DR1,
+    .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:4:4"),
+};
diff --git a/libavcodec/v308enc.c b/libavcodec/v308enc.c
new file mode 100644
index 0000000..7a0ca40
--- /dev/null
+++ b/libavcodec/v308enc.c
@@ -0,0 +1,95 @@
+/*
+ * v308 encoder
+ *
+ * Copyright (c) 2011 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 "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "internal.h"
+
+static av_cold int v308_encode_init(AVCodecContext *avctx)
+{
+    if (avctx->width & 1) {
+        av_log(avctx, AV_LOG_ERROR, "v308 requires width to be even.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    avctx->coded_frame = avcodec_alloc_frame();
+
+    if (!avctx->coded_frame) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int v308_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                             const AVFrame *pic, int *got_packet)
+{
+    uint8_t *dst;
+    uint8_t *y, *u, *v;
+    int i, j, ret;
+
+    if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width * avctx->height * 3)) < 0)
+        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;
+
+    y = pic->data[0];
+    u = pic->data[1];
+    v = pic->data[2];
+
+    for (i = 0; i < avctx->height; i++) {
+        for (j = 0; j < avctx->width; j++) {
+            *dst++ = v[j];
+            *dst++ = y[j];
+            *dst++ = u[j];
+        }
+        y += pic->linesize[0];
+        u += pic->linesize[1];
+        v += pic->linesize[2];
+    }
+
+    pkt->flags |= AV_PKT_FLAG_KEY;
+    *got_packet = 1;
+    return 0;
+}
+
+static av_cold int v308_encode_close(AVCodecContext *avctx)
+{
+    av_freep(&avctx->coded_frame);
+
+    return 0;
+}
+
+AVCodec ff_v308_encoder = {
+    .name         = "v308",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_V308,
+    .init         = v308_encode_init,
+    .encode2      = v308_encode_frame,
+    .close        = v308_encode_close,
+    .pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE },
+    .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:4:4"),
+};
diff --git a/libavcodec/v408dec.c b/libavcodec/v408dec.c
new file mode 100644
index 0000000..8820fc4c
--- /dev/null
+++ b/libavcodec/v408dec.c
@@ -0,0 +1,129 @@
+/*
+ * v408 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"
+
+static av_cold int v408_decode_init(AVCodecContext *avctx)
+{
+    avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
+
+    avctx->coded_frame = avcodec_alloc_frame();
+
+    if (!avctx->coded_frame) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int v408_decode_frame(AVCodecContext *avctx, void *data,
+                             int *data_size, AVPacket *avpkt)
+{
+    AVFrame *pic = avctx->coded_frame;
+    const uint8_t *src = avpkt->data;
+    uint8_t *y, *u, *v, *a;
+    int i, j;
+
+    if (pic->data[0])
+        avctx->release_buffer(avctx, pic);
+
+    if (avpkt->size < 4 * avctx->height * avctx->width) {
+        av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
+        return AVERROR(EINVAL);
+    }
+
+    pic->reference = 0;
+
+    if (avctx->get_buffer(avctx, pic) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    pic->key_frame = 1;
+    pic->pict_type = AV_PICTURE_TYPE_I;
+
+    y = pic->data[0];
+    u = pic->data[1];
+    v = pic->data[2];
+    a = pic->data[3];
+
+    for (i = 0; i < avctx->height; i++) {
+        for (j = 0; j < avctx->width; j++) {
+            if (avctx->codec_id==AV_CODEC_ID_AYUV) {
+                v[j] = *src++;
+                u[j] = *src++;
+                y[j] = *src++;
+                a[j] = *src++;
+            } else {
+                u[j] = *src++;
+                y[j] = *src++;
+                v[j] = *src++;
+                a[j] = *src++;
+            }
+        }
+
+        y += pic->linesize[0];
+        u += pic->linesize[1];
+        v += pic->linesize[2];
+        a += pic->linesize[3];
+    }
+
+    *data_size = sizeof(AVFrame);
+    *(AVFrame *)data = *pic;
+
+    return avpkt->size;
+}
+
+static av_cold int v408_decode_close(AVCodecContext *avctx)
+{
+    if (avctx->coded_frame->data[0])
+        avctx->release_buffer(avctx, avctx->coded_frame);
+
+    av_freep(&avctx->coded_frame);
+
+    return 0;
+}
+
+#if CONFIG_AYUV_DECODER
+AVCodec ff_ayuv_decoder = {
+    .name         = "ayuv",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_AYUV,
+    .init         = v408_decode_init,
+    .decode       = v408_decode_frame,
+    .close        = v408_decode_close,
+    .capabilities = CODEC_CAP_DR1,
+    .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed packed MS 4:4:4:4"),
+};
+#endif
+#if CONFIG_V408_DECODER
+AVCodec ff_v408_decoder = {
+    .name         = "v408",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_V408,
+    .init         = v408_decode_init,
+    .decode       = v408_decode_frame,
+    .close        = v408_decode_close,
+    .capabilities = CODEC_CAP_DR1,
+    .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed packed QT 4:4:4:4"),
+};
+#endif
diff --git a/libavcodec/v408enc.c b/libavcodec/v408enc.c
new file mode 100644
index 0000000..9b0ebce
--- /dev/null
+++ b/libavcodec/v408enc.c
@@ -0,0 +1,114 @@
+/*
+ * v408 encoder
+ *
+ * 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 "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "internal.h"
+
+static av_cold int v408_encode_init(AVCodecContext *avctx)
+{
+    avctx->coded_frame = avcodec_alloc_frame();
+
+    if (!avctx->coded_frame) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int v408_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                             const AVFrame *pic, int *got_packet)
+{
+    uint8_t *dst;
+    uint8_t *y, *u, *v, *a;
+    int i, j, ret;
+
+    if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width * avctx->height * 4)) < 0)
+        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;
+
+    y = pic->data[0];
+    u = pic->data[1];
+    v = pic->data[2];
+    a = pic->data[3];
+
+    for (i = 0; i < avctx->height; i++) {
+        for (j = 0; j < avctx->width; j++) {
+           if (avctx->codec_id==AV_CODEC_ID_AYUV) {
+                *dst++ = v[j];
+                *dst++ = u[j];
+                *dst++ = y[j];
+                *dst++ = a[j];
+            } else {
+                *dst++ = u[j];
+                *dst++ = y[j];
+                *dst++ = v[j];
+                *dst++ = a[j];
+            }
+        }
+        y += pic->linesize[0];
+        u += pic->linesize[1];
+        v += pic->linesize[2];
+        a += pic->linesize[3];
+    }
+
+    pkt->flags |= AV_PKT_FLAG_KEY;
+    *got_packet = 1;
+    return 0;
+}
+
+static av_cold int v408_encode_close(AVCodecContext *avctx)
+{
+    av_freep(&avctx->coded_frame);
+
+    return 0;
+}
+
+#if CONFIG_AYUV_ENCODER
+AVCodec ff_ayuv_encoder = {
+    .name         = "ayuv",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_AYUV,
+    .init         = v408_encode_init,
+    .encode2      = v408_encode_frame,
+    .close        = v408_encode_close,
+    .pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUVA444P, AV_PIX_FMT_NONE },
+    .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed packed MS 4:4:4:4"),
+};
+#endif
+#if CONFIG_V408_ENCODER
+AVCodec ff_v408_encoder = {
+    .name         = "v408",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_V408,
+    .init         = v408_encode_init,
+    .encode2      = v408_encode_frame,
+    .close        = v408_encode_close,
+    .pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUVA444P, AV_PIX_FMT_NONE },
+    .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed packed QT 4:4:4:4"),
+};
+#endif
diff --git a/libavcodec/v410dec.c b/libavcodec/v410dec.c
index b96ba11..4d4d625 100644
--- a/libavcodec/v410dec.c
+++ b/libavcodec/v410dec.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2011 Derek Buitenhuis
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/v410enc.c b/libavcodec/v410enc.c
index cc7cef7..67d8fc9 100644
--- a/libavcodec/v410enc.c
+++ b/libavcodec/v410enc.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2011 Derek Buitenhuis
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -28,7 +28,7 @@
 static av_cold int v410_encode_init(AVCodecContext *avctx)
 {
     if (avctx->width & 1) {
-        av_log(avctx, AV_LOG_ERROR, "v410 requires even width.\n");
+        av_log(avctx, AV_LOG_ERROR, "v410 requires width to be even.\n");
         return AVERROR_INVALIDDATA;
     }
 
@@ -50,10 +50,8 @@
     uint32_t val;
     int i, j, ret;
 
-    if ((ret = ff_alloc_packet(pkt, avctx->width * avctx->height * 4)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width * avctx->height * 4)) < 0)
         return ret;
-    }
     dst = pkt->data;
 
     avctx->coded_frame->reference = 0;
diff --git a/libavcodec/vaapi.c b/libavcodec/vaapi.c
index d6b0298..774fde8 100644
--- a/libavcodec/vaapi.c
+++ b/libavcodec/vaapi.c
@@ -4,20 +4,20 @@
  *
  * Copyright (C) 2008-2009 Splitted-Desktop Systems
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vaapi.h b/libavcodec/vaapi.h
index 39e8825..815a27e 100644
--- a/libavcodec/vaapi.h
+++ b/libavcodec/vaapi.h
@@ -1,23 +1,23 @@
 /*
- * Video Acceleration API (shared data between Libav and the video player)
+ * Video Acceleration API (shared data between FFmpeg and the video player)
  * HW decode acceleration for MPEG-2, MPEG-4, H.264 and VC-1
  *
  * Copyright (C) 2008-2009 Splitted-Desktop Systems
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -39,7 +39,7 @@
  */
 
 /**
- * This structure is used to share data between the Libav library and
+ * This structure is used to share data between the FFmpeg library and
  * the client video application.
  * This shall be zero-allocated and available as
  * AVCodecContext.hwaccel_context. All user members can be set once
diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c
index 4ffc7d8..9be51bf 100644
--- a/libavcodec/vaapi_h264.c
+++ b/libavcodec/vaapi_h264.c
@@ -3,20 +3,20 @@
  *
  * Copyright (C) 2008-2009 Splitted-Desktop Systems
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,7 +25,7 @@
 
 /**
  * @file
- * This file implements the glue code between Libav's and VA API's
+ * This file implements the glue code between FFmpeg's and VA API's
  * structures for H.264 decoding.
  */
 
@@ -43,10 +43,10 @@
 }
 
 /**
- * Translate an Libav Picture into its VA API form.
+ * Translate an FFmpeg Picture into its VA API form.
  *
  * @param[out] va_pic          A pointer to VA API's own picture struct
- * @param[in]  pic             A pointer to the Libav picture struct to convert
+ * @param[in]  pic             A pointer to the FFmpeg picture struct to convert
  * @param[in]  pic_structure   The picture field type (as defined in mpegvideo.h),
  *                             supersedes pic's field type if nonzero.
  */
@@ -147,11 +147,11 @@
 }
 
 /**
- * Fill in VA API reference picture lists from the Libav reference
+ * Fill in VA API reference picture lists from the FFmpeg reference
  * picture list.
  *
  * @param[out] RefPicList  VA API internal reference picture list
- * @param[in]  ref_list    A pointer to the Libav reference list
+ * @param[in]  ref_list    A pointer to the FFmpeg reference list
  * @param[in]  ref_count   The number of reference pictures in ref_list
  */
 static void fill_vaapi_RefPicList(VAPictureH264 RefPicList[32],
@@ -259,7 +259,7 @@
     pic_param->seq_fields.bits.delta_pic_order_always_zero_flag = h->sps.delta_pic_order_always_zero_flag;
     pic_param->num_slice_groups_minus1                          = h->pps.slice_group_count - 1;
     pic_param->slice_group_map_type                             = h->pps.mb_slice_group_map_type;
-    pic_param->slice_group_change_rate_minus1                   = 0; /* XXX: unimplemented in Libav */
+    pic_param->slice_group_change_rate_minus1                   = 0; /* XXX: unimplemented in FFmpeg */
     pic_param->pic_init_qp_minus26                              = h->pps.init_qp - 26;
     pic_param->pic_init_qs_minus26                              = h->pps.init_qs - 26;
     pic_param->chroma_qp_index_offset                           = h->pps.chroma_qp_index_offset[0];
@@ -282,7 +282,8 @@
     if (!iq_matrix)
         return -1;
     memcpy(iq_matrix->ScalingList4x4, h->pps.scaling_matrix4, sizeof(iq_matrix->ScalingList4x4));
-    memcpy(iq_matrix->ScalingList8x8, h->pps.scaling_matrix8, sizeof(iq_matrix->ScalingList8x8));
+    memcpy(iq_matrix->ScalingList8x8[0], h->pps.scaling_matrix8[0], sizeof(iq_matrix->ScalingList8x8[0]));
+    memcpy(iq_matrix->ScalingList8x8[1], h->pps.scaling_matrix8[3], sizeof(iq_matrix->ScalingList8x8[0]));
     return 0;
 }
 
diff --git a/libavcodec/vaapi_internal.h b/libavcodec/vaapi_internal.h
index c6d5d6e..e514dd6 100644
--- a/libavcodec/vaapi_internal.h
+++ b/libavcodec/vaapi_internal.h
@@ -4,20 +4,20 @@
  *
  * Copyright (C) 2008-2009 Splitted-Desktop Systems
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c
index cfe5d3a..50ba06d 100644
--- a/libavcodec/vaapi_mpeg2.c
+++ b/libavcodec/vaapi_mpeg2.c
@@ -3,20 +3,20 @@
  *
  * Copyright (C) 2008-2009 Splitted-Desktop Systems
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vaapi_mpeg4.c b/libavcodec/vaapi_mpeg4.c
index 7d9ffd7..3178740 100644
--- a/libavcodec/vaapi_mpeg4.c
+++ b/libavcodec/vaapi_mpeg4.c
@@ -3,20 +3,20 @@
  *
  * Copyright (C) 2008-2009 Splitted-Desktop Systems
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -129,7 +129,7 @@
 
     /* video_plane_with_short_video_header() contains all GOBs
      * in-order, and this is what VA API (Intel backend) expects: only
-     * a single slice param. So fake macroblock_number for Libav so
+     * a single slice param. So fake macroblock_number for FFmpeg so
      * that we don't call vaapi_mpeg4_decode_slice() again
      */
     if (avctx->codec->id == AV_CODEC_ID_H263)
diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c
index 4a98ba7..af01e51 100644
--- a/libavcodec/vaapi_vc1.c
+++ b/libavcodec/vaapi_vc1.c
@@ -3,20 +3,20 @@
  *
  * Copyright (C) 2008-2009 Splitted-Desktop Systems
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,7 +24,7 @@
 #include "vc1.h"
 #include "vc1data.h"
 
-/** Translate Libav MV modes to VA API */
+/** Translate FFmpeg MV modes to VA API */
 static int get_VAMvModeVC1(enum MVModes mv_mode)
 {
     switch (mv_mode) {
@@ -128,7 +128,7 @@
     return 0;
 }
 
-/** Pack Libav bitplanes into a VABitPlaneBuffer element */
+/** Pack FFmpeg bitplanes into a VABitPlaneBuffer element */
 static inline void vc1_pack_bitplanes(uint8_t *bitplane, int n, const uint8_t *ff_bp[3], int x, int y, int stride)
 {
     const int bitplane_index = n / 2;
diff --git a/libavcodec/vb.c b/libavcodec/vb.c
index 39e14a0..78ef669 100644
--- a/libavcodec/vb.c
+++ b/libavcodec/vb.c
@@ -2,20 +2,20 @@
  * Beam Software VB decoder
  * Copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -73,7 +73,7 @@
         return;
     }
     for(i = start; i <= start + size; i++)
-        c->pal[i] = bytestream2_get_be24(&c->stream);
+        c->pal[i] = 0xFFU << 24 | bytestream2_get_be24(&c->stream);
 }
 
 static inline int check_pixel(uint8_t *buf, uint8_t *start, uint8_t *end)
@@ -197,7 +197,7 @@
 
     if(c->pic.data[0])
         avctx->release_buffer(avctx, &c->pic);
-    c->pic.reference = 1;
+    c->pic.reference = 3;
     if(avctx->get_buffer(avctx, &c->pic) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
@@ -212,6 +212,10 @@
     }
     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");
+            return -1;
+        }
         vb_decode_framedata(c, offset);
         bytestream2_skip(&c->stream, size - 4);
     }
@@ -247,6 +251,7 @@
 
     c->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
+    avcodec_get_frame_defaults(&c->pic);
 
     c->frame      = av_mallocz(avctx->width * avctx->height);
     c->prev_frame = av_mallocz(avctx->width * avctx->height);
diff --git a/libavcodec/vble.c b/libavcodec/vble.c
index d112e27..07efad8 100644
--- a/libavcodec/vble.c
+++ b/libavcodec/vble.c
@@ -2,20 +2,20 @@
  * VBLE Decoder
  * Copyright (c) 2011 Derek Buitenhuis
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,55 +36,51 @@
     DSPContext dsp;
 
     int            size;
-    uint8_t        *val; /* First holds the lengths of vlc symbols and then their values */
+    uint8_t        *val; ///< This array first holds the lengths of vlc symbols and then their value.
 } VBLEContext;
 
-static uint8_t vble_read_reverse_unary(GetBitContext *gb)
-{
-    /* At most we need to read 9 bits total to get indices up to 8 */
-    uint8_t val = show_bits(gb, 8);
-
-    if (val) {
-        val = 7 - av_log2_16bit(ff_reverse[val]);
-        skip_bits(gb, val + 1);
-        return val;
-    } else {
-        skip_bits(gb, 8);
-        if (get_bits1(gb))
-            return 8;
-    }
-
-    /* Return something larger than 8 on error */
-    return UINT8_MAX;
-}
-
 static int vble_unpack(VBLEContext *ctx, GetBitContext *gb)
 {
     int i;
+    int allbits = 0;
+    static const uint8_t LUT[256] = {
+        8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+        5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+        6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+        5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+        7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+        5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+        6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+        5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
+    };
 
     /* Read all the lengths in first */
     for (i = 0; i < ctx->size; i++) {
-        ctx->val[i] = vble_read_reverse_unary(gb);
+        /* At most we need to read 9 bits total to get indices up to 8 */
+        int val = show_bits(gb, 8);
 
-        if (ctx->val[i] == UINT8_MAX)
-            return -1;
+        // read reverse unary
+        if (val) {
+            val = LUT[val];
+            skip_bits(gb, val + 1);
+            ctx->val[i] = val;
+        } else {
+            skip_bits(gb, 8);
+            if (!get_bits1(gb))
+                return -1;
+            ctx->val[i] = 8;
+        }
+        allbits += ctx->val[i];
     }
 
-    for (i = 0; i < ctx->size; i++) {
-        /* Check we have enough bits left */
-        if (get_bits_left(gb) < ctx->val[i])
-            return -1;
-
-        /* get_bits can't take a length of 0 */
-        if (ctx->val[i])
-            ctx->val[i] = (1 << ctx->val[i]) + get_bits(gb, ctx->val[i]) - 1;
-    }
-
+    /* Check we have enough bits left */
+    if (get_bits_left(gb) < allbits)
+        return -1;
     return 0;
 }
 
-static void vble_restore_plane(VBLEContext *ctx, int plane, int offset,
-                              int width, int height)
+static void vble_restore_plane(VBLEContext *ctx, GetBitContext *gb, int plane,
+                               int offset, int width, int height)
 {
     AVFrame *pic = ctx->avctx->coded_frame;
     uint8_t *dst = pic->data[plane];
@@ -93,14 +89,17 @@
     int i, j, left, left_top;
 
     for (i = 0; i < height; i++) {
-        for (j = 0; j < width; j++)
-            val[j] = (val[j] >> 1) ^ -(val[j] & 1);
-
+        for (j = 0; j < width; j++) {
+            /* get_bits can't take a length of 0 */
+            if (val[j]) {
+                int v = (1 << val[j]) + get_bits(gb, val[j]) - 1;
+                val[j] = (v >> 1) ^ -(v & 1);
+            }
+        }
         if (i) {
             left = 0;
             left_top = dst[-stride];
-            ctx->dsp.add_hfyu_median_prediction(dst, dst-stride, val,
-                                                width, &left, &left_top);
+            ctx->dsp.add_hfyu_median_prediction(dst, dst-stride, val, width, &left, &left_top);
         } else {
             dst[0] = val[0];
             for (j = 1; j < width; j++)
@@ -155,15 +154,15 @@
     }
 
     /* Restore planes. Should be almost identical to Huffyuv's. */
-    vble_restore_plane(ctx, 0, offset, avctx->width, avctx->height);
+    vble_restore_plane(ctx, &gb, 0, offset, avctx->width, avctx->height);
 
     /* Chroma */
     if (!(ctx->avctx->flags & CODEC_FLAG_GRAY)) {
         offset += avctx->width * avctx->height;
-        vble_restore_plane(ctx, 1, offset, width_uv, height_uv);
+        vble_restore_plane(ctx, &gb, 1, offset, width_uv, height_uv);
 
         offset += width_uv * height_uv;
-        vble_restore_plane(ctx, 2, offset, width_uv, height_uv);
+        vble_restore_plane(ctx, &gb, 2, offset, width_uv, height_uv);
     }
 
     *data_size = sizeof(AVFrame);
diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c
index c7edc25..ae07d17 100644
--- a/libavcodec/vc1.c
+++ b/libavcodec/vc1.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2006-2007 Konstantin Shishkov
  * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -293,7 +293,7 @@
  */
 int ff_vc1_decode_sequence_header(AVCodecContext *avctx, VC1Context *v, GetBitContext *gb)
 {
-    av_log(avctx, AV_LOG_DEBUG, "Header: %0X\n", show_bits(gb, 32));
+    av_log(avctx, AV_LOG_DEBUG, "Header: %0X\n", show_bits_long(gb, 32));
     v->profile = get_bits(gb, 2);
     if (v->profile == PROFILE_COMPLEX) {
         av_log(avctx, AV_LOG_WARNING, "WMV3 Complex Profile is not fully supported\n");
@@ -380,8 +380,9 @@
     v->finterpflag = get_bits1(gb); //common
 
     if (v->res_sprite) {
-        v->s.avctx->width  = v->s.avctx->coded_width  = get_bits(gb, 11);
-        v->s.avctx->height = v->s.avctx->coded_height = get_bits(gb, 11);
+        int w = get_bits(gb, 11);
+        int h = get_bits(gb, 11);
+        avcodec_set_dimensions(v->s.avctx, w, h);
         skip_bits(gb, 5); //frame rate
         v->res_x8 = get_bits1(gb);
         if (get_bits1(gb)) { // something to do with DC VLC selection
@@ -433,10 +434,8 @@
     v->bitrtq_postproc       = get_bits(gb, 5); //common
     v->postprocflag          = get_bits1(gb);   //common
 
-    v->s.avctx->coded_width  = (get_bits(gb, 12) + 1) << 1;
-    v->s.avctx->coded_height = (get_bits(gb, 12) + 1) << 1;
-    v->s.avctx->width        = v->s.avctx->coded_width;
-    v->s.avctx->height       = v->s.avctx->coded_height;
+    v->max_coded_width       = (get_bits(gb, 12) + 1) << 1;
+    v->max_coded_height      = (get_bits(gb, 12) + 1) << 1;
     v->broadcast             = get_bits1(gb);
     v->interlace             = get_bits1(gb);
     v->tfcntrflag            = get_bits1(gb);
@@ -502,9 +501,10 @@
         }
 
         if (get_bits1(gb)) {
-            v->color_prim    = get_bits(gb, 8);
-            v->transfer_char = get_bits(gb, 8);
-            v->matrix_coef   = get_bits(gb, 8);
+            v->s.avctx->color_primaries = get_bits(gb, 8);
+            v->s.avctx->color_trc       = get_bits(gb, 8);
+            v->s.avctx->colorspace      = get_bits(gb, 8);
+            v->s.avctx->color_range     = AVCOL_RANGE_MPEG;
         }
     }
 
@@ -525,6 +525,7 @@
 int ff_vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContext *gb)
 {
     int i;
+    int w,h;
 
     av_log(avctx, AV_LOG_DEBUG, "Entry point: %08X\n", show_bits_long(gb, 32));
     v->broken_link    = get_bits1(gb);
@@ -532,6 +533,8 @@
     v->panscanflag    = get_bits1(gb);
     v->refdist_flag   = get_bits1(gb);
     v->s.loop_filter  = get_bits1(gb);
+    if (v->s.avctx->skip_loop_filter >= AVDISCARD_ALL)
+        v->s.loop_filter = 0;
     v->fastuvmc       = get_bits1(gb);
     v->extended_mv    = get_bits1(gb);
     v->dquant         = get_bits(gb, 2);
@@ -545,10 +548,14 @@
         }
     }
 
-    if (get_bits1(gb)) {
-        avctx->width  = avctx->coded_width  = (get_bits(gb, 12) + 1) << 1;
-        avctx->height = avctx->coded_height = (get_bits(gb, 12) + 1) << 1;
+    if(get_bits1(gb)){
+        w = (get_bits(gb, 12)+1)<<1;
+        h = (get_bits(gb, 12)+1)<<1;
+    } else {
+        w = v->max_coded_width;
+        h = v->max_coded_height;
     }
+    avcodec_set_dimensions(avctx, w, h);
     if (v->extended_mv)
         v->extended_dmv = get_bits1(gb);
     if ((v->range_mapy_flag = get_bits1(gb))) {
@@ -576,6 +583,8 @@
 
     if (v->finterpflag)
         v->interpfrm = get_bits1(gb);
+    if (!v->s.avctx->codec)
+        return -1;
     if (v->s.avctx->codec->id == AV_CODEC_ID_MSS2)
         v->respic   =
         v->rangered =
@@ -826,8 +835,11 @@
     int mbmodetab, imvtab, icbptab, twomvbptab, fourmvbptab; /* useful only for debugging */
     int scale, shift, i; /* for initializing LUT for intensity compensation */
 
+    v->numref=0;
     v->p_frame_skipped = 0;
     if (v->second_field) {
+        if(v->fcm!=2 || v->field_mode!=1)
+            return -1;
         v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I;
         if (v->fptype & 4)
             v->s.pict_type = (v->fptype & 1) ? AV_PICTURE_TYPE_BI : AV_PICTURE_TYPE_B;
@@ -895,6 +907,8 @@
     v->rnd = get_bits1(gb);
     if (v->interlace)
         v->uvsamp = get_bits1(gb);
+    if(!ff_vc1_bfraction_vlc.table)
+        return 0; //parsing only, vlc tables havnt been allocated
     if (v->field_mode) {
         if (!v->refdist_flag)
             v->refdist = 0;
@@ -1138,9 +1152,14 @@
         }
         break;
     case AV_PICTURE_TYPE_B:
-        // TODO: implement interlaced frame B picture decoding
-        if (v->fcm == ILACE_FRAME)
-            return -1;
+        if (v->fcm == ILACE_FRAME) {
+            v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1);
+            v->bfraction           = ff_vc1_bfraction_lut[v->bfraction_lut_index];
+            if (v->bfraction == 0) {
+                return -1;
+            }
+            return -1; // This codepath is still incomplete thus it is disabled
+        }
         if (v->extended_mv)
             v->mvrange = get_unary(gb, 0, 3);
         else
@@ -1159,6 +1178,7 @@
 
         if (v->field_mode) {
             int mvmode;
+            av_log(v->s.avctx, AV_LOG_DEBUG, "B Fields\n");
             if (v->extended_dmv)
                 v->dmvrange = get_unary(gb, 0, 3);
             mvmode = get_unary(gb, 1, 3);
@@ -1186,6 +1206,37 @@
                 v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab];
             }
             v->numref = 1; // interlaced field B pictures are always 2-ref
+        } else if (v->fcm == ILACE_FRAME) {
+            if (v->extended_dmv)
+                v->dmvrange = get_unary(gb, 0, 3);
+            get_bits1(gb); /* intcomp - present but shall always be 0 */
+            v->intcomp          = 0;
+            v->mv_mode          = MV_PMODE_1MV;
+            v->fourmvswitch     = 0;
+            v->qs_last          = v->s.quarter_sample;
+            v->s.quarter_sample = 1;
+            v->s.mspel          = 1;
+            status              = bitplane_decoding(v->direct_mb_plane, &v->dmb_is_raw, v);
+            if (status < 0)
+                return -1;
+            av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct Type plane encoding: "
+                   "Imode: %i, Invert: %i\n", status>>1, status&1);
+            status = bitplane_decoding(v->s.mbskip_table, &v->skip_is_raw, v);
+            if (status < 0)
+                return -1;
+            av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
+                   "Imode: %i, Invert: %i\n", status>>1, status&1);
+            mbmodetab       = get_bits(gb, 2);
+            v->mbmode_vlc   = &ff_vc1_intfr_non4mv_mbmode_vlc[mbmodetab];
+            imvtab          = get_bits(gb, 2);
+            v->imv_vlc      = &ff_vc1_1ref_mvdata_vlc[imvtab];
+            // interlaced p/b-picture cbpcy range is [1, 63]
+            icbptab         = get_bits(gb, 3);
+            v->cbpcy_vlc    = &ff_vc1_icbpcy_vlc[icbptab];
+            twomvbptab      = get_bits(gb, 2);
+            v->twomvbp_vlc  = &ff_vc1_2mv_block_pattern_vlc[twomvbptab];
+            fourmvbptab     = get_bits(gb, 2);
+            v->fourmvbp_vlc = &ff_vc1_4mv_block_pattern_vlc[fourmvbptab];
         } else {
             v->mv_mode          = get_bits1(gb) ? MV_PMODE_1MV : MV_PMODE_1MV_HPEL_BILIN;
             v->qs_last          = v->s.quarter_sample;
diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h
index 13011ae..6263d1d 100644
--- a/libavcodec/vc1.h
+++ b/libavcodec/vc1.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2006-2007 Konstantin Shishkov
  * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -210,9 +210,6 @@
     int panscanflag;      ///< NUMPANSCANWIN, TOPLEFT{X,Y}, BOTRIGHT{X,Y} present
     int refdist_flag;     ///< REFDIST syntax element present in II, IP, PI or PP field picture headers
     int extended_dmv;     ///< Additional extended dmv range at P/B frame-level
-    int color_prim;       ///< 8bits, chroma coordinates of the color primaries
-    int transfer_char;    ///< 8bits, Opto-electronic transfer characteristics
-    int matrix_coef;      ///< 8bits, Color primaries->YCbCr transform matrix
     int hrd_param_flag;   ///< Presence of Hypothetical Reference
                           ///< Decoder parameters
     int psf;              ///< Progressive Segmented Frame
@@ -225,6 +222,7 @@
     int profile;          ///< 2bits, Profile
     int frmrtq_postproc;  ///< 3bits,
     int bitrtq_postproc;  ///< 5bits, quantized framerate-based postprocessing strength
+    int max_coded_width, max_coded_height;
     int fastuvmc;         ///< Rounding of qpel vector to hpel ? (not in Simple)
     int extended_mv;      ///< Ext MV in P/B (not in Simple)
     int dquant;           ///< How qscale varies with MBs, 2bits (not in Simple)
@@ -349,7 +347,7 @@
     uint8_t fourmvbp;
     uint8_t* fieldtx_plane;
     int fieldtx_is_raw;
-    int8_t zzi_8x8[64];
+    uint8_t zzi_8x8[64];
     uint8_t *blk_mv_type_base, *blk_mv_type;    ///< 0: frame MV, 1: field MV (interlaced frame)
     uint8_t *mv_f_base, *mv_f[2];               ///< 0: MV obtained from same field, 1: opposite field
     uint8_t *mv_f_last_base, *mv_f_last[2];
diff --git a/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c
index 5aa1248..53af61c 100644
--- a/libavcodec/vc1_parser.c
+++ b/libavcodec/vc1_parser.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2006-2007 Konstantin Shishkov
  * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vc1acdata.h b/libavcodec/vc1acdata.h
index 73ebe40..a70b44a 100644
--- a/libavcodec/vc1acdata.h
+++ b/libavcodec/vc1acdata.h
@@ -2,20 +2,20 @@
  * VC-1 and WMV3 decoder
  * copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vc1data.c b/libavcodec/vc1data.c
index 70cead8..fc9ba6d 100644
--- a/libavcodec/vc1data.c
+++ b/libavcodec/vc1data.c
@@ -4,20 +4,20 @@
  * copyright (c) 2006 Konstantin Shishkov
  * (c) 2005 anonymous, Alex Beregszaszi, Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -1019,21 +1019,21 @@
 /* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */
 
 /* Table 232 */
-const int8_t ff_vc1_simple_progressive_4x4_zz [16] = {
+const uint8_t ff_vc1_simple_progressive_4x4_zz [16] = {
      0,     8,    16,     1,
      9,    24,    17,     2,
     10,    18,    25,     3,
     11,    26,    19,    27
 };
 
-const int8_t ff_vc1_adv_progressive_8x4_zz [32] = { /* Table 233 */
+const uint8_t ff_vc1_adv_progressive_8x4_zz [32] = { /* Table 233 */
      0,     8,     1,    16,     2,     9,    10,     3,
     24,    17,     4,    11,    18,    12,     5,    19,
     25,    13,    20,    26,    27,     6,    21,    28,
     14,    22,    29,     7,    30,    15,    23,    31
 };
 
-const int8_t ff_vc1_adv_progressive_4x8_zz [32] = { /* Table 234 */
+const uint8_t ff_vc1_adv_progressive_4x8_zz [32] = { /* Table 234 */
      0,     1,     8,     2,
      9,    16,    17,    24,
     10,    32,    25,    18,
@@ -1044,7 +1044,7 @@
     35,    43,    51,    59
 };
 
-const int8_t ff_vc1_adv_interlaced_8x8_zz [64] = { /* Table 235 */
+const uint8_t ff_vc1_adv_interlaced_8x8_zz [64] = { /* Table 235 */
      0,     8,     1,    16,    24,     9,     2,    32,
     40,    48,    56,    17,    10,     3,    25,    18,
     11,     4,    33,    41,    49,    57,    26,    34,
@@ -1055,14 +1055,14 @@
     61,    62,    54,    46,    39,    47,    55,    63
 };
 
-const int8_t ff_vc1_adv_interlaced_8x4_zz [32] = { /* Table 236 */
+const uint8_t ff_vc1_adv_interlaced_8x4_zz [32] = { /* Table 236 */
      0,     8,    16,    24,     1,     9,     2,    17,
     25,    10,     3,    18,    26,     4,    11,    19,
     12,     5,    13,    20,    27,     6,    21,    28,
     14,    22,    29,     7,    30,    15,    23,    31
 };
 
-const int8_t ff_vc1_adv_interlaced_4x8_zz [32] = { /* Table 237 */
+const uint8_t ff_vc1_adv_interlaced_4x8_zz [32] = { /* Table 237 */
      0,     1,     2,     8,
     16,     9,    24,    17,
     10,     3,    32,    40,
@@ -1073,7 +1073,7 @@
     35,    43,    51,    59
 };
 
-const int8_t ff_vc1_adv_interlaced_4x4_zz [16] = { /* Table 238 */
+const uint8_t ff_vc1_adv_interlaced_4x4_zz [16] = { /* Table 238 */
      0,     8,    16,    24,
      1,     9,    17,     2,
     25,    10,    18,     3,
diff --git a/libavcodec/vc1data.h b/libavcodec/vc1data.h
index 84e8188..eecb045 100644
--- a/libavcodec/vc1data.h
+++ b/libavcodec/vc1data.h
@@ -3,20 +3,20 @@
  * copyright (c) 2006 Konstantin Shishkov
  * (c) 2005 anonymous, Alex Beregszaszi, Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -183,15 +183,15 @@
 /* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */
 
 /* Scantables/ZZ scan are at 11.9 (p262) and 8.1.1.12 (p10) */
-extern const int8_t ff_vc1_simple_progressive_4x4_zz [16];
-extern const int8_t ff_vc1_adv_progressive_8x4_zz [32];
-extern const int8_t ff_vc1_adv_progressive_4x8_zz [32];
-extern const int8_t ff_vc1_adv_interlaced_8x8_zz [64];
-extern const int8_t ff_vc1_adv_interlaced_8x4_zz [32];
-extern const int8_t ff_vc1_adv_interlaced_4x8_zz [32];
-extern const int8_t ff_vc1_adv_interlaced_4x4_zz [16];
-extern const int8_t ff_vc1_intra_horz_8x8_zz [64];
-extern const int8_t ff_vc1_intra_vert_8x8_zz [64];
+extern const uint8_t ff_vc1_simple_progressive_4x4_zz [16];
+extern const uint8_t ff_vc1_adv_progressive_8x4_zz [32];
+extern const uint8_t ff_vc1_adv_progressive_4x8_zz [32];
+extern const uint8_t ff_vc1_adv_interlaced_8x8_zz [64];
+extern const uint8_t ff_vc1_adv_interlaced_8x4_zz [32];
+extern const uint8_t ff_vc1_adv_interlaced_4x8_zz [32];
+extern const uint8_t ff_vc1_adv_interlaced_4x4_zz [16];
+extern const uint8_t ff_vc1_intra_horz_8x8_zz [64];
+extern const uint8_t ff_vc1_intra_vert_8x8_zz [64];
 
 /* DQScale as specified in 8.1.3.9 - almost identical to 0x40000/i */
 extern const int32_t ff_vc1_dqscale[63];
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 6bfba68..7aae8cc 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2006-2007 Konstantin Shishkov
  * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -38,6 +38,7 @@
 #include "unary.h"
 #include "mathops.h"
 #include "vdpau_internal.h"
+#include "libavutil/avassert.h"
 
 #undef NDEBUG
 #include <assert.h>
@@ -368,7 +369,7 @@
     }
     if (v->field_mode) { // interlaced field picture
         if (!dir) {
-            if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type) {
+            if ((v->cur_field_type != v->ref_field_type[dir]) && v->second_field) {
                 srcY = s->current_picture.f.data[0];
                 srcU = s->current_picture.f.data[1];
                 srcV = s->current_picture.f.data[2];
@@ -492,7 +493,7 @@
         srcY += s->mspel * (1 + s->linesize);
     }
 
-    if (v->field_mode && v->cur_field_type) {
+    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 {
@@ -560,7 +561,7 @@
 
     if (!dir) {
         if (v->field_mode) {
-            if ((v->cur_field_type != v->ref_field_type[dir]) && v->cur_field_type)
+            if ((v->cur_field_type != v->ref_field_type[dir]) && v->second_field)
                 srcY = s->current_picture.f.data[0];
             else
                 srcY = s->last_picture.f.data[0];
@@ -629,7 +630,7 @@
         off = ((n > 1) ? s->linesize : 0) + (n & 1) * 8;
     else
         off = s->linesize * 4 * (n & 2) + (n & 1) * 8;
-    if (v->field_mode && v->cur_field_type)
+    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);
@@ -861,7 +862,7 @@
             srcU += s->current_picture_ptr->f.linesize[1];
             srcV += s->current_picture_ptr->f.linesize[2];
         }
-        off = v->cur_field_type ? s->current_picture_ptr->f.linesize[1] : 0;
+        off = v->second_field ? s->current_picture_ptr->f.linesize[1] : 0;
     }
 
     if (v->rangeredfrm || (v->mv_mode == MV_PMODE_INTENSITY_COMP)
@@ -1138,6 +1139,7 @@
         }
     }
     else {
+        av_assert0(index < esc);
         if (extend_x)
             offs_tab = offset_table2;
         else
@@ -1791,7 +1793,7 @@
                 } else if (c_valid) {
                     px = C[0];
                     py = C[1];
-                }
+                } else px = py = 0;
             }
         } else if (total_valid == 1) {
             px = (a_valid) ? A[0] : ((b_valid) ? B[0] : C[0]);
@@ -1924,7 +1926,7 @@
         srcY += s->mspel * (1 + s->linesize);
     }
 
-    if (v->field_mode && v->cur_field_type) {
+    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 {
@@ -3691,7 +3693,7 @@
     int idx_mbmode = 0, mvbp;
     int stride_y, fieldtx;
 
-    mquant = v->pq; /* Loosy initialization */
+    mquant = v->pq; /* Lossy initialization */
 
     if (v->skip_is_raw)
         skipped = get_bits1(gb);
@@ -3895,11 +3897,11 @@
     int val; /* temp values */
     int first_block = 1;
     int dst_idx, off;
-    int pred_flag;
+    int pred_flag = 0;
     int block_cbp = 0, pat, block_tt = 0;
     int idx_mbmode = 0;
 
-    mquant = v->pq; /* Loosy initialization */
+    mquant = v->pq; /* Lossy initialization */
 
     idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
     if (idx_mbmode <= 1) { // intra MB
@@ -3934,7 +3936,7 @@
                 continue;
             v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);
             off  = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
-            off += v->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0;
+            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
         }
@@ -3981,7 +3983,7 @@
             dst_idx += i >> 2;
             val = ((cbp >> (5 - i)) & 1);
             off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
-            if (v->cur_field_type)
+            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,
@@ -4172,7 +4174,7 @@
     int bmvtype = BMV_TYPE_BACKWARD;
     int idx_mbmode, interpmvp;
 
-    mquant      = v->pq; /* Loosy initialization */
+    mquant      = v->pq; /* Lossy initialization */
     s->mb_intra = 0;
 
     idx_mbmode = get_vlc2(gb, v->mbmode_vlc->table, VC1_IF_MBMODE_VLC_BITS, 2);
@@ -4211,7 +4213,7 @@
                 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->cur_field_type ? ((i & 4) ? s->current_picture_ptr->f.linesize[1] : s->current_picture_ptr->f.linesize[0]) : 0;
+            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
         }
@@ -4293,7 +4295,7 @@
             dst_idx += i >> 2;
             val = ((cbp >> (5 - i)) & 1);
             off = (i & 4) ? 0 : (i & 1) * 8 + (i & 2) * 4 * s->linesize;
-            if (v->cur_field_type)
+            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,
@@ -4644,7 +4646,7 @@
         if (s->mb_y != s->start_mb_y) ff_draw_horiz_band(s, (s->mb_y - 1) * 16, 16);
         s->first_slice_line = 0;
     }
-    if (apply_loop_filter) {
+    if (apply_loop_filter && v->fcm == PROGRESSIVE) {
         s->mb_x = 0;
         ff_init_block_index(s);
         for (; s->mb_x < s->mb_width; s->mb_x++) {
@@ -5317,13 +5319,16 @@
     AVFrame *pict = data;
     uint8_t *buf2 = NULL;
     const uint8_t *buf_start = buf;
-    int mb_height, n_slices1;
+    int mb_height, n_slices1=-1;
     struct {
         uint8_t *buf;
         GetBitContext gb;
         int mby_start;
     } *slices = NULL, *tmp;
 
+    if(s->flags & CODEC_FLAG_LOW_DELAY)
+        s->low_delay = 1;
+
     /* no supplementary picture */
     if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) {
         /* special case for last picture */
@@ -5334,7 +5339,7 @@
             *data_size = sizeof(AVFrame);
         }
 
-        return 0;
+        return buf_size;
     }
 
     if (s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {
@@ -5488,15 +5493,18 @@
     // do parse frame header
     v->pic_header_flag = 0;
     if (v->profile < PROFILE_ADVANCED) {
-        if (ff_vc1_parse_frame_header(v, &s->gb) == -1) {
+        if (ff_vc1_parse_frame_header(v, &s->gb) < 0) {
             goto err;
         }
     } else {
-        if (ff_vc1_parse_frame_header_adv(v, &s->gb) == -1) {
+        if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) {
             goto err;
         }
     }
 
+    if (avctx->debug & FF_DEBUG_PICT_INFO)
+        av_log(v->s.avctx, AV_LOG_DEBUG, "pict_type: %c\n", av_get_picture_type_char(s->pict_type));
+
     if ((avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE)
         && s->pict_type != AV_PICTURE_TYPE_I) {
         av_log(v->s.avctx, AV_LOG_ERROR, "Sprite decoder: expected I-frame\n");
@@ -5540,6 +5548,9 @@
         goto err;
     }
 
+    v->s.current_picture_ptr->f.interlaced_frame = (v->fcm != PROGRESSIVE);
+    v->s.current_picture_ptr->f.top_field_first  = v->tff;
+
     s->me.qpel_put = s->dsp.put_qpel_pixels_tab;
     s->me.qpel_avg = s->dsp.avg_qpel_pixels_tab;
 
@@ -5611,6 +5622,10 @@
                 s->end_mb_y = (i == n_slices     ) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height);
             else
                 s->end_mb_y = (i <= n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height);
+            if (s->end_mb_y <= s->start_mb_y) {
+                av_log(v->s.avctx, AV_LOG_ERROR, "end mb y %d %d invalid\n", s->end_mb_y, s->start_mb_y);
+                continue;
+            }
             ff_vc1_decode_blocks(v);
             if (i != n_slices)
                 s->gb = slices[i].gb;
@@ -5631,7 +5646,10 @@
                 get_bits_count(&s->gb), s->gb.size_in_bits);
 //  if (get_bits_count(&s->gb) > buf_size * 8)
 //      return -1;
-        ff_er_frame_end(s);
+        if(s->error_occurred && s->pict_type == AV_PICTURE_TYPE_B)
+            goto err;
+        if(!v->field_mode)
+            ff_er_frame_end(s);
     }
 
     ff_MPV_frame_end(s);
diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c
index 81a74e3..a874509 100644
--- a/libavcodec/vc1dsp.c
+++ b/libavcodec/vc1dsp.c
@@ -2,20 +2,20 @@
  * VC-1 and WMV3 decoder - DSP functions
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,6 +26,7 @@
  */
 
 #include "vc1dsp.h"
+#include "libavutil/avassert.h"
 #include "libavutil/common.h"
 
 
@@ -659,7 +660,7 @@
     const int D=(  x)*(  y);
     int i;
 
-    assert(x<8 && y<8 && x>=0 && y>=0);
+    av_assert2(x<8 && y<8 && x>=0 && y>=0);
 
     for(i=0; i<h; i++)
     {
@@ -683,7 +684,7 @@
     const int D=(  x)*(  y);
     int i;
 
-    assert(x<8 && y<8 && x>=0 && y>=0);
+    av_assert2(x<8 && y<8 && x>=0 && y>=0);
 
     for(i=0; i<h; i++)
     {
@@ -704,7 +705,7 @@
     const int D=(  x)*(  y);
     int i;
 
-    assert(x<8 && y<8 && x>=0 && y>=0);
+    av_assert2(x<8 && y<8 && x>=0 && y>=0);
 
     for(i=0; i<h; i++)
     {
diff --git a/libavcodec/vc1dsp.h b/libavcodec/vc1dsp.h
index 5f364b3..8775818 100644
--- a/libavcodec/vc1dsp.h
+++ b/libavcodec/vc1dsp.h
@@ -2,20 +2,20 @@
  * VC-1 and WMV3 decoder - DSP functions
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vcr1.c b/libavcodec/vcr1.c
index df5088c..2a4a090 100644
--- a/libavcodec/vcr1.c
+++ b/libavcodec/vcr1.c
@@ -2,20 +2,20 @@
  * ATI VCR1 codec
  * Copyright (c) 2003 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -39,6 +39,7 @@
     VCR1Context *const a = avctx->priv_data;
 
     avctx->coded_frame = &a->picture;
+    avcodec_get_frame_defaults(&a->picture);
 
     return 0;
 }
@@ -76,6 +77,11 @@
     if (p->data[0])
         avctx->release_buffer(avctx, p);
 
+    if(buf_size < 16 + avctx->height + avctx->width*avctx->height*5/8){
+        av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
+        return AVERROR(EINVAL);
+    }
+
     p->reference = 0;
     if (avctx->get_buffer(avctx, p) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
diff --git a/libavcodec/vda.h b/libavcodec/vda.h
index f0ec2bf..ccbf375 100644
--- a/libavcodec/vda.h
+++ b/libavcodec/vda.h
@@ -3,20 +3,20 @@
  *
  * copyright (c) 2011 Sebastien Zwickert
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -58,7 +58,7 @@
  *
  * @deprecated Use synchronous decoding mode.
  */
-typedef struct vda_frame {
+typedef struct {
     /**
      * The PTS of the frame.
      *
@@ -87,7 +87,7 @@
 
 /**
  * This structure is used to provide the necessary configurations and data
- * to the VDA Libav HWAccel implementation.
+ * to the VDA FFmpeg HWAccel implementation.
  *
  * The application must make it available as AVCodecContext.hwaccel_context.
  */
@@ -172,16 +172,25 @@
 
     /**
      * The current bitstream buffer.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by libavcodec.
      */
     uint8_t             *priv_bitstream;
 
     /**
      * The current size of the bitstream.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by libavcodec.
      */
     int                 priv_bitstream_size;
 
     /**
      * The reference size used for fast reallocation.
+     *
+     * - encoding: unused
+     * - decoding: Set/Unset by libavcodec.
      */
     int                 priv_allocated_size;
 };
diff --git a/libavcodec/vda_h264.c b/libavcodec/vda_h264.c
index 2a78aac..89960d7 100644
--- a/libavcodec/vda_h264.c
+++ b/libavcodec/vda_h264.c
@@ -1,42 +1,41 @@
 /*
- * VDA H.264 hardware acceleration
+ * VDA H264 HW acceleration.
  *
  * copyright (c) 2011 Sebastien Zwickert
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <CoreFoundation/CFDictionary.h>
 #include <CoreFoundation/CFNumber.h>
 #include <CoreFoundation/CFData.h>
-#include <CoreFoundation/CFString.h>
 
+#include "vda.h"
 #include "libavutil/avutil.h"
 #include "h264.h"
-#include "vda.h"
 
 #if FF_API_VDA_ASYNC
-#include <CoreFoundation/CFDictionary.h>
+#include <CoreFoundation/CFString.h>
 
-/* helper to create a dictionary according to the given pts */
+/* Helper to create a dictionary according to the given pts. */
 static CFDictionaryRef vda_dictionary_with_pts(int64_t i_pts)
 {
-    CFStringRef key           = CFSTR("FF_VDA_DECODER_PTS_KEY");
-    CFNumberRef value         = CFNumberCreate(kCFAllocatorDefault,
-                                               kCFNumberSInt64Type, &i_pts);
+    CFStringRef key = CFSTR("FF_VDA_DECODER_PTS_KEY");
+    CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &i_pts);
     CFDictionaryRef user_info = CFDictionaryCreate(kCFAllocatorDefault,
                                                    (const void **)&key,
                                                    (const void **)&value,
@@ -47,7 +46,7 @@
     return user_info;
 }
 
-/* helper to retrieve the pts from the given dictionary */
+/* Helper to retrieve the pts from the given dictionary. */
 static int64_t vda_pts_from_dictionary(CFDictionaryRef user_info)
 {
     CFNumberRef pts;
@@ -64,7 +63,7 @@
     return outValue;
 }
 
-/* Remove and release all frames from the queue. */
+/* Removes and releases all frames from the queue. */
 static void vda_clear_queue(struct vda_context *vda_ctx)
 {
     vda_frame *top_frame;
@@ -72,7 +71,7 @@
     pthread_mutex_lock(&vda_ctx->queue_mutex);
 
     while (vda_ctx->queue) {
-        top_frame      = vda_ctx->queue;
+        top_frame = vda_ctx->queue;
         vda_ctx->queue = top_frame->next_frame;
         ff_vda_release_vda_frame(top_frame);
     }
@@ -85,13 +84,14 @@
                               int bitstream_size,
                               int64_t frame_pts)
 {
-    OSStatus status = kVDADecoderNoErr;
+    OSStatus status;
     CFDictionaryRef user_info;
     CFDataRef coded_frame;
 
     coded_frame = CFDataCreate(kCFAllocatorDefault, bitstream, bitstream_size);
-    user_info   = vda_dictionary_with_pts(frame_pts);
-    status      = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, user_info);
+    user_info = vda_dictionary_with_pts(frame_pts);
+
+    status = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, user_info);
 
     CFRelease(user_info);
     CFRelease(coded_frame);
@@ -107,7 +107,7 @@
         return NULL;
 
     pthread_mutex_lock(&vda_ctx->queue_mutex);
-    top_frame      = vda_ctx->queue;
+    top_frame = vda_ctx->queue;
     vda_ctx->queue = top_frame->next_frame;
     pthread_mutex_unlock(&vda_ctx->queue_mutex);
 
@@ -123,12 +123,12 @@
 }
 #endif
 
-/* Decoder callback that adds the VDA frame to the queue in display order. */
-static void vda_decoder_callback(void *vda_hw_ctx,
-                                 CFDictionaryRef user_info,
-                                 OSStatus status,
-                                 uint32_t infoFlags,
-                                 CVImageBufferRef image_buffer)
+/* Decoder callback that adds the vda frame to the queue in display order. */
+static void vda_decoder_callback (void *vda_hw_ctx,
+                                  CFDictionaryRef user_info,
+                                  OSStatus status,
+                                  uint32_t infoFlags,
+                                  CVImageBufferRef image_buffer)
 {
     struct vda_context *vda_ctx = vda_hw_ctx;
 
@@ -146,25 +146,28 @@
 
         if (!(new_frame = av_mallocz(sizeof(*new_frame))))
             return;
+
         new_frame->next_frame = NULL;
-        new_frame->cv_buffer  = CVPixelBufferRetain(image_buffer);
-        new_frame->pts        = vda_pts_from_dictionary(user_info);
+        new_frame->cv_buffer = CVPixelBufferRetain(image_buffer);
+        new_frame->pts = vda_pts_from_dictionary(user_info);
 
         pthread_mutex_lock(&vda_ctx->queue_mutex);
 
         queue_walker = vda_ctx->queue;
 
-        if (!queue_walker || new_frame->pts < queue_walker->pts) {
+        if (!queue_walker || (new_frame->pts < queue_walker->pts)) {
             /* we have an empty queue, or this frame earlier than the current queue head */
             new_frame->next_frame = queue_walker;
-            vda_ctx->queue        = new_frame;
+            vda_ctx->queue = new_frame;
         } else {
             /* walk the queue and insert this frame where it belongs in display order */
             vda_frame *next_frame;
+
             while (1) {
                 next_frame = queue_walker->next_frame;
-                if (!next_frame || new_frame->pts < next_frame->pts) {
-                    new_frame->next_frame    = next_frame;
+
+                if (!next_frame || (new_frame->pts < next_frame->pts)) {
+                    new_frame->next_frame = next_frame;
                     queue_walker->next_frame = new_frame;
                     break;
                 }
@@ -196,12 +199,11 @@
     return status;
 }
 
-
 static int start_frame(AVCodecContext *avctx,
                        av_unused const uint8_t *buffer,
                        av_unused uint32_t size)
 {
-    struct vda_context *vda_ctx         = avctx->hwaccel_context;
+    struct vda_context *vda_ctx = avctx->hwaccel_context;
 
     if (!vda_ctx->decoder)
         return -1;
@@ -215,7 +217,7 @@
                         const uint8_t *buffer,
                         uint32_t size)
 {
-    struct vda_context *vda_ctx         = avctx->hwaccel_context;
+    struct vda_context *vda_ctx = avctx->hwaccel_context;
     void *tmp;
 
     if (!vda_ctx->decoder)
@@ -266,7 +268,7 @@
                           uint8_t *extradata,
                           int extradata_size)
 {
-    OSStatus status = kVDADecoderNoErr;
+    OSStatus status;
     CFNumberRef height;
     CFNumberRef width;
     CFNumberRef format;
@@ -276,12 +278,15 @@
     CFMutableDictionaryRef io_surface_properties;
     CFNumberRef cv_pix_fmt;
 
+    vda_ctx->priv_bitstream = NULL;
+    vda_ctx->priv_allocated_size = 0;
+
 #if FF_API_VDA_ASYNC
     pthread_mutex_init(&vda_ctx->queue_mutex, NULL);
 #endif
 
     /* Each VCL NAL in the bistream sent to the decoder
-     * is preceeded by a 4 bytes length header.
+     * 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) {
         uint8_t *rw_extradata;
@@ -322,9 +327,9 @@
                                                       0,
                                                       &kCFTypeDictionaryKeyCallBacks,
                                                       &kCFTypeDictionaryValueCallBacks);
-    cv_pix_fmt      = CFNumberCreate(kCFAllocatorDefault,
-                                     kCFNumberSInt32Type,
-                                     &vda_ctx->cv_pix_fmt_type);
+    cv_pix_fmt  = CFNumberCreate(kCFAllocatorDefault,
+                                 kCFNumberSInt32Type,
+                                 &vda_ctx->cv_pix_fmt_type);
     CFDictionarySetValue(buffer_attributes,
                          kCVPixelBufferPixelFormatTypeKey,
                          cv_pix_fmt);
@@ -361,7 +366,6 @@
     vda_clear_queue(vda_ctx);
     pthread_mutex_destroy(&vda_ctx->queue_mutex);
 #endif
-
     av_freep(&vda_ctx->priv_bitstream);
 
     return status;
diff --git a/libavcodec/vda_h264_dec.c b/libavcodec/vda_h264_dec.c
new file mode 100644
index 0000000..3cb13e3
--- /dev/null
+++ b/libavcodec/vda_h264_dec.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2012, Xidorn Quan
+ *
+ * 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 decoder via VDA
+ * @author Xidorn Quan <quanxunzhen@gmail.com>
+ */
+
+#include <string.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "vda.h"
+#include "h264.h"
+#include "avcodec.h"
+
+#ifndef kCFCoreFoundationVersionNumber10_7
+#define kCFCoreFoundationVersionNumber10_7      635.00
+#endif
+
+extern AVCodec ff_h264_decoder, ff_h264_vda_decoder;
+
+static const enum AVPixelFormat vda_pixfmts_prior_10_7[] = {
+    AV_PIX_FMT_UYVY422,
+    AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_NONE
+};
+
+static const enum AVPixelFormat vda_pixfmts[] = {
+    AV_PIX_FMT_UYVY422,
+    AV_PIX_FMT_YUYV422,
+    AV_PIX_FMT_NV12,
+    AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_NONE
+};
+
+typedef struct {
+    H264Context h264ctx;
+    int h264_initialized;
+    struct vda_context vda_ctx;
+    enum AVPixelFormat pix_fmt;
+} VDADecoderContext;
+
+static enum AVPixelFormat get_format(struct AVCodecContext *avctx,
+        const enum AVPixelFormat *fmt)
+{
+    return AV_PIX_FMT_VDA_VLD;
+}
+
+static int get_buffer(AVCodecContext *avctx, AVFrame *pic)
+{
+    pic->type = FF_BUFFER_TYPE_USER;
+    pic->data[0] = (void *)1;
+    return 0;
+}
+
+static void release_buffer(AVCodecContext *avctx, AVFrame *pic)
+{
+    int i;
+
+    CVPixelBufferRef cv_buffer = (CVPixelBufferRef)pic->data[3];
+    CVPixelBufferUnlockBaseAddress(cv_buffer, 0);
+    CVPixelBufferRelease(cv_buffer);
+
+    for (i = 0; i < 4; i++)
+        pic->data[i] = NULL;
+}
+
+static int vdadec_decode(AVCodecContext *avctx,
+        void *data, int *data_size, 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) {
+        CVPixelBufferRef cv_buffer = (CVPixelBufferRef)pic->data[3];
+        CVPixelBufferLockBaseAddress(cv_buffer, 0);
+        pic->format = ctx->pix_fmt;
+        if (CVPixelBufferIsPlanar(cv_buffer)) {
+            int i, count = CVPixelBufferGetPlaneCount(cv_buffer);
+            av_assert0(count < 4);
+            for (i = 0; i < count; i++) {
+                pic->data[i] = CVPixelBufferGetBaseAddressOfPlane(cv_buffer, i);
+                pic->linesize[i] = CVPixelBufferGetBytesPerRowOfPlane(cv_buffer, i);
+            }
+        } else {
+            pic->data[0] = CVPixelBufferGetBaseAddress(cv_buffer);
+            pic->linesize[0] = CVPixelBufferGetBytesPerRow(cv_buffer);
+        }
+    }
+    avctx->pix_fmt = ctx->pix_fmt;
+
+    return ret;
+}
+
+static av_cold int vdadec_close(AVCodecContext *avctx)
+{
+    VDADecoderContext *ctx = avctx->priv_data;
+    /* release buffers and decoder */
+    ff_vda_destroy_decoder(&ctx->vda_ctx);
+    /* close H.264 decoder */
+    if (ctx->h264_initialized)
+        ff_h264_decoder.close(avctx);
+    return 0;
+}
+
+static av_cold int check_format(AVCodecContext *avctx)
+{
+    AVCodecParserContext *parser;
+    uint8_t *pout;
+    int psize;
+    int index;
+    H264Context *h;
+    int ret = -1;
+
+    /* init parser & parse file */
+    parser = av_parser_init(avctx->codec->id);
+    if (!parser) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to open H.264 parser.\n");
+        goto final;
+    }
+    parser->flags = PARSER_FLAG_COMPLETE_FRAMES;
+    index = av_parser_parse2(parser, avctx, &pout, &psize, NULL, 0, 0, 0, 0);
+    if (index < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to parse this file.\n");
+        goto release_parser;
+    }
+
+    /* check if support */
+    h = parser->priv_data;
+    switch (h->sps.bit_depth_luma) {
+    case 8:
+        if (!CHROMA444 && !CHROMA422) {
+            // only this will H.264 decoder switch to hwaccel
+            ret = 0;
+            break;
+        }
+    default:
+        av_log(avctx, AV_LOG_ERROR, "Unsupported file.\n");
+    }
+
+release_parser:
+    av_parser_close(parser);
+
+final:
+    return ret;
+}
+
+static av_cold int vdadec_init(AVCodecContext *avctx)
+{
+    VDADecoderContext *ctx = avctx->priv_data;
+    struct vda_context *vda_ctx = &ctx->vda_ctx;
+    OSStatus status;
+    int ret;
+
+    ctx->h264_initialized = 0;
+
+    /* init pix_fmts of codec */
+    if (!ff_h264_vda_decoder.pix_fmts) {
+        if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber10_7)
+            ff_h264_vda_decoder.pix_fmts = vda_pixfmts_prior_10_7;
+        else
+            ff_h264_vda_decoder.pix_fmts = vda_pixfmts;
+    }
+
+    /* check if VDA supports this file */
+    if (check_format(avctx) < 0)
+        goto failed;
+
+    /* init vda */
+    memset(vda_ctx, 0, sizeof(struct vda_context));
+    vda_ctx->width = avctx->width;
+    vda_ctx->height = avctx->height;
+    vda_ctx->format = 'avc1';
+    vda_ctx->use_sync_decoding = 1;
+    ctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);
+    switch (ctx->pix_fmt) {
+    case AV_PIX_FMT_UYVY422:
+        vda_ctx->cv_pix_fmt_type = '2vuy';
+        break;
+    case AV_PIX_FMT_YUYV422:
+        vda_ctx->cv_pix_fmt_type = 'yuvs';
+        break;
+    case AV_PIX_FMT_NV12:
+        vda_ctx->cv_pix_fmt_type = '420v';
+        break;
+    case AV_PIX_FMT_YUV420P:
+        vda_ctx->cv_pix_fmt_type = 'y420';
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format: %d\n", avctx->pix_fmt);
+        goto failed;
+    }
+    status = ff_vda_create_decoder(vda_ctx,
+                                   avctx->extradata, avctx->extradata_size);
+    if (status != kVDADecoderNoErr) {
+        av_log(avctx, AV_LOG_ERROR,
+                "Failed to init VDA decoder: %d.\n", status);
+        goto failed;
+    }
+    avctx->hwaccel_context = vda_ctx;
+
+    /* changes callback functions */
+    avctx->get_format = get_format;
+    avctx->get_buffer = get_buffer;
+    avctx->release_buffer = release_buffer;
+
+    /* init H.264 decoder */
+    ret = ff_h264_decoder.init(avctx);
+    if (ret < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to open H.264 decoder.\n");
+        goto failed;
+    }
+    ctx->h264_initialized = 1;
+
+    return 0;
+
+failed:
+    vdadec_close(avctx);
+    return -1;
+}
+
+static void vdadec_flush(AVCodecContext *avctx)
+{
+    return ff_h264_decoder.flush(avctx);
+}
+
+AVCodec ff_h264_vda_decoder = {
+    .name           = "h264_vda",
+    .type           = AVMEDIA_TYPE_VIDEO,
+    .id             = AV_CODEC_ID_H264,
+    .priv_data_size = sizeof(VDADecoderContext),
+    .init           = vdadec_init,
+    .close          = vdadec_close,
+    .decode         = vdadec_decode,
+    .capabilities   = CODEC_CAP_DELAY,
+    .flush          = vdadec_flush,
+    .long_name      = NULL_IF_CONFIG_SMALL("H.264 (VDA acceleration)"),
+};
diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c
index 6daf494..6ac195e 100644
--- a/libavcodec/vdpau.c
+++ b/libavcodec/vdpau.c
@@ -4,20 +4,20 @@
  *
  * Copyright (c) 2008 NVIDIA
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -370,4 +370,40 @@
     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 241ff19..23394b5 100644
--- a/libavcodec/vdpau.h
+++ b/libavcodec/vdpau.h
@@ -4,20 +4,20 @@
  *
  * Copyright (C) 2008 NVIDIA
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -39,7 +39,7 @@
  * - VDPAU decoding
  * - VDPAU presentation
  *
- * The VDPAU decoding module parses all headers using Libav
+ * The VDPAU decoding module parses all headers using FFmpeg
  * parsing mechanisms and uses VDPAU for the actual decoding.
  *
  * As per the current implementation, the actual decoding
@@ -62,17 +62,24 @@
 #define FF_VDPAU_STATE_USED_FOR_REFERENCE 2
 
 /**
- * @brief This structure is used as a callback between the Libav
+ * @brief This structure is used as a callback between the FFmpeg
  * decoder (vd_) and presentation (vo_) module.
  * This is used for defining a video frame containing surface,
  * picture parameter, bitstream information etc which are passed
- * between the Libav decoder and its clients.
+ * between the FFmpeg decoder and its clients.
  */
 struct vdpau_render_state {
     VdpVideoSurface surface; ///< Used as rendered surface, never changed.
 
     int state; ///< Holds FF_VDPAU_STATE_* values.
 
+    /** Describe size/location of the compressed video data.
+        Set to 0 when freeing bitstream_buffers. */
+    int bitstream_buffers_allocated;
+    int bitstream_buffers_used;
+    /** The user is responsible for freeing this buffer using av_freep(). */
+    VdpBitstreamBuffer *bitstream_buffers;
+
     /** picture parameter information for all supported codecs */
     union VdpPictureInfo {
         VdpPictureInfoH264        h264;
@@ -80,13 +87,6 @@
         VdpPictureInfoVC1          vc1;
         VdpPictureInfoMPEG4Part2 mpeg4;
     } info;
-
-    /** Describe size/location of the compressed video data.
-        Set to 0 when freeing bitstream_buffers. */
-    int bitstream_buffers_allocated;
-    int bitstream_buffers_used;
-    /** The user is responsible for freeing this buffer using av_freep(). */
-    VdpBitstreamBuffer *bitstream_buffers;
 };
 
 /* @}*/
diff --git a/libavcodec/vdpau_internal.h b/libavcodec/vdpau_internal.h
index 673fd33..0a8d0b6 100644
--- a/libavcodec/vdpau_internal.h
+++ b/libavcodec/vdpau_internal.h
@@ -4,20 +4,20 @@
  *
  * Copyright (C) 2008 NVIDIA
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/version.h b/libavcodec/version.h
index b97439c..daafb01 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -1,19 +1,19 @@
 /*
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,9 +26,11 @@
  * Libavcodec version macros.
  */
 
+#include "libavutil/avutil.h"
+
 #define LIBAVCODEC_VERSION_MAJOR 54
-#define LIBAVCODEC_VERSION_MINOR 31
-#define LIBAVCODEC_VERSION_MICRO  0
+#define LIBAVCODEC_VERSION_MINOR 65
+#define LIBAVCODEC_VERSION_MICRO 100
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                LIBAVCODEC_VERSION_MINOR, \
@@ -49,9 +51,19 @@
 #ifndef FF_API_REQUEST_CHANNELS
 #define FF_API_REQUEST_CHANNELS (LIBAVCODEC_VERSION_MAJOR < 55)
 #endif
+#ifndef FF_API_ALLOC_CONTEXT
+#define FF_API_ALLOC_CONTEXT    (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_AVCODEC_OPEN
+#define FF_API_AVCODEC_OPEN     (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
 #ifndef FF_API_OLD_DECODE_AUDIO
 #define FF_API_OLD_DECODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 55)
 #endif
+#ifndef FF_API_OLD_TIMECODE
+#define FF_API_OLD_TIMECODE (LIBAVCODEC_VERSION_MAJOR < 55)
+#endif
+
 #ifndef FF_API_OLD_ENCODE_AUDIO
 #define FF_API_OLD_ENCODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 55)
 #endif
diff --git a/libavcodec/vima.c b/libavcodec/vima.c
new file mode 100644
index 0000000..648ae55
--- /dev/null
+++ b/libavcodec/vima.c
@@ -0,0 +1,236 @@
+/*
+ * LucasArts VIMA decoder
+ * 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/audioconvert.h"
+#include "avcodec.h"
+#include "get_bits.h"
+#include "adpcm_data.h"
+
+typedef struct {
+    AVFrame     frame;
+    uint16_t    predict_table[5786 * 2];
+} VimaContext;
+
+static const uint8_t size_table[] =
+{
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+    4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+};
+
+static const int8_t index_table1[] =
+{
+    -1, 4, -1, 4
+};
+
+static const int8_t index_table2[] =
+{
+    -1, -1, 2, 6, -1, -1, 2, 6
+};
+
+static const int8_t index_table3[] =
+{
+    -1, -1, -1, -1, 1, 2, 4, 6,
+    -1, -1, -1, -1, 1, 2, 4, 6
+};
+
+static const int8_t index_table4[] =
+{
+    -1, -1, -1, -1, -1, -1, -1, -1,
+     1,  1,  1,  2,  2,  4,  5,  6,
+    -1, -1, -1, -1, -1, -1, -1, -1,
+     1,  1,  1,  2,  2,  4,  5,  6
+};
+
+static const int8_t index_table5[] =
+{
+    -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1,
+     1,  1,  1,  1,  1,  2,  2,  2,
+     2,  4,  4,  4,  5,  5,  6,  6,
+    -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1,
+     1,  1,  1,  1,  1,  2,  2,  2,
+     2,  4,  4,  4,  5,  5,  6,  6
+};
+
+static const int8_t index_table6[] =
+{
+    -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -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,  2,  2,  2,  2,  2,
+     2,  2,  4,  4,  4,  4,  4,  4,
+     5,  5,  5,  5,  6,  6,  6,  6,
+    -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -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,  2,  2,  2,  2,  2,
+     2,  2,  4,  4,  4,  4,  4,  4,
+     5,  5,  5,  5,  6,  6,  6,  6
+};
+
+static const int8_t* const step_index_tables[] =
+{
+    index_table1, index_table2, index_table3,
+    index_table4, index_table5, index_table6
+};
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+    VimaContext *vima = avctx->priv_data;
+    int         start_pos;
+
+    for (start_pos = 0; start_pos < 64; start_pos++) {
+        unsigned int dest_pos, table_pos;
+
+        for (table_pos = 0, dest_pos = start_pos;
+             table_pos < FF_ARRAY_ELEMS(ff_adpcm_step_table);
+             table_pos++, dest_pos += 64) {
+            int put = 0, count, table_value;
+
+            table_value = ff_adpcm_step_table[table_pos];
+            for (count = 32; count != 0; count >>= 1) {
+                if (start_pos & count)
+                    put += table_value;
+                table_value >>= 1;
+            }
+            vima->predict_table[dest_pos] = put;
+        }
+    }
+
+    avcodec_get_frame_defaults(&vima->frame);
+    avctx->coded_frame = &vima->frame;
+    avctx->sample_fmt  = AV_SAMPLE_FMT_S16;
+
+    return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data,
+                        int *got_frame_ptr, AVPacket *pkt)
+{
+    GetBitContext  gb;
+    VimaContext    *vima = avctx->priv_data;
+    int16_t        pcm_data[2];
+    uint32_t       samples;
+    int8_t         channel_hint[2];
+    int            ret, chan, channels = 1;
+
+    if (pkt->size < 13)
+        return AVERROR_INVALIDDATA;
+
+    init_get_bits(&gb, pkt->data, pkt->size * 8);
+
+    samples = get_bits_long(&gb, 32);
+    if (samples == 0xffffffff) {
+        skip_bits_long(&gb, 32);
+        samples = get_bits_long(&gb, 32);
+    }
+
+    if (samples > pkt->size * 2)
+        return AVERROR_INVALIDDATA;
+
+    channel_hint[0] = get_sbits(&gb, 8);
+    if (channel_hint[0] & 0x80) {
+        channel_hint[0] = ~channel_hint[0];
+        channels = 2;
+    }
+    avctx->channels = channels;
+    avctx->channel_layout = (channels == 2) ? AV_CH_LAYOUT_STEREO :
+                                              AV_CH_LAYOUT_MONO;
+    pcm_data[0] = get_sbits(&gb, 16);
+    if (channels > 1) {
+        channel_hint[1] = get_sbits(&gb, 8);
+        pcm_data[1] = get_sbits(&gb, 16);
+    }
+
+    vima->frame.nb_samples = samples;
+    if ((ret = avctx->get_buffer(avctx, &vima->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;
+        int step_index = channel_hint[chan];
+        int output = pcm_data[chan];
+        int sample;
+
+        for (sample = 0; sample < samples; sample++) {
+            int lookup_size, lookup, highbit, lowbits;
+
+            step_index  = av_clip(step_index, 0, 88);
+            lookup_size = size_table[step_index];
+            lookup      = get_bits(&gb, lookup_size);
+            highbit     = 1 << (lookup_size - 1);
+            lowbits     = highbit - 1;
+
+            if (lookup & highbit)
+                lookup ^= highbit;
+            else
+                highbit = 0;
+
+            if (lookup == lowbits) {
+                output = get_sbits(&gb, 16);
+            } else {
+                int predict_index, diff;
+
+                predict_index = (lookup << (7 - lookup_size)) | (step_index << 6);
+                predict_index = av_clip(predict_index, 0, 5785);
+                diff          = vima->predict_table[predict_index];
+                if (lookup)
+                    diff += ff_adpcm_step_table[step_index] >> (lookup_size - 1);
+                if (highbit)
+                    diff  = -diff;
+
+                output  = av_clip_int16(output + diff);
+            }
+
+            *dest = output;
+            dest += channels;
+
+            step_index += step_index_tables[lookup_size - 2][lookup];
+        }
+    }
+
+    *got_frame_ptr   = 1;
+    *(AVFrame *)data = vima->frame;
+
+    return pkt->size;
+}
+
+AVCodec ff_vima_decoder = {
+    .name           = "vima",
+    .type           = AVMEDIA_TYPE_AUDIO,
+    .id             = AV_CODEC_ID_VIMA,
+    .priv_data_size = sizeof(VimaContext),
+    .init           = decode_init,
+    .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("LucasArts VIMA audio"),
+};
diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c
index 5776d92..b0599b9 100644
--- a/libavcodec/vmdav.c
+++ b/libavcodec/vmdav.c
@@ -2,20 +2,20 @@
  * Sierra VMD Audio & Video Decoders
  * Copyright (C) 2004 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -77,7 +77,7 @@
                       unsigned char *dest, int dest_len)
 {
     const unsigned char *s;
-    unsigned int s_len;
+    const unsigned char *s_end;
     unsigned char *d;
     unsigned char *d_end;
     unsigned char queue[QUEUE_SIZE];
@@ -90,16 +90,17 @@
     unsigned int i, j;
 
     s = src;
-    s_len = src_len;
+    s_end = src + src_len;
     d = dest;
     d_end = d + dest_len;
-    dataleft = AV_RL32(s);
-    s += 4; s_len -= 4;
-    memset(queue, 0x20, QUEUE_SIZE);
-    if (s_len < 4)
+
+    if (s_end - s < 8)
         return;
+    dataleft = AV_RL32(s);
+    s += 4;
+    memset(queue, 0x20, QUEUE_SIZE);
     if (AV_RL32(s) == 0x56781234) {
-        s += 4; s_len -= 4;
+        s += 4;
         qpos = 0x111;
         speclen = 0xF + 3;
     } else {
@@ -107,42 +108,38 @@
         speclen = 100;  /* no speclen */
     }
 
-    while (dataleft > 0 && s_len > 0) {
-        tag = *s++; s_len--;
+    while (s_end - s > 0 && dataleft > 0) {
+        tag = *s++;
         if ((tag == 0xFF) && (dataleft > 8)) {
-            if (d + 8 > d_end || s_len < 8)
+            if (d_end - d < 8 || s_end - s < 8)
                 return;
             for (i = 0; i < 8; i++) {
                 queue[qpos++] = *d++ = *s++;
                 qpos &= QUEUE_MASK;
             }
-            s_len -= 8;
             dataleft -= 8;
         } else {
             for (i = 0; i < 8; i++) {
                 if (dataleft == 0)
                     break;
                 if (tag & 0x01) {
-                    if (d + 1 > d_end || s_len < 1)
+                    if (d_end - d < 1 || s_end - s < 1)
                         return;
                     queue[qpos++] = *d++ = *s++;
                     qpos &= QUEUE_MASK;
                     dataleft--;
-                    s_len--;
                 } else {
-                    if (s_len < 2)
+                    if (s_end - s < 2)
                         return;
                     chainofs = *s++;
                     chainofs |= ((*s & 0xF0) << 4);
                     chainlen = (*s++ & 0x0F) + 3;
-                    s_len -= 2;
                     if (chainlen == speclen) {
-                        if (s_len < 1)
+                        if (s_end - s < 1)
                             return;
                         chainlen = *s++ + 0xF + 3;
-                        s_len--;
                     }
-                    if (d + chainlen > d_end)
+                    if (d_end - d < chainlen)
                         return;
                     for (j = 0; j < chainlen; j++) {
                         *d = queue[chainofs++ & QUEUE_MASK];
@@ -157,47 +154,45 @@
     }
 }
 
-static int rle_unpack(const unsigned char *src, unsigned char *dest,
-    int src_count, int src_size, int dest_len)
+static int rle_unpack(const unsigned char *src, int src_len, int src_count,
+                      unsigned char *dest, int dest_len)
 {
     const unsigned char *ps;
+    const unsigned char *ps_end;
     unsigned char *pd;
     int i, l;
     unsigned char *dest_end = dest + dest_len;
 
     ps = src;
+    ps_end = src + src_len;
     pd = dest;
     if (src_count & 1) {
-        if (src_size < 1)
+        if (ps_end - ps < 1)
             return 0;
         *pd++ = *ps++;
-        src_size--;
     }
 
     src_count >>= 1;
     i = 0;
     do {
-        if (src_size < 1)
+        if (ps_end - ps < 1)
             break;
         l = *ps++;
-        src_size--;
         if (l & 0x80) {
             l = (l & 0x7F) * 2;
-            if (pd + l > dest_end || src_size < l)
+            if (dest_end - pd < l || ps_end - ps < l)
                 return ps - src;
             memcpy(pd, ps, l);
             ps += l;
-            src_size -= l;
             pd += l;
         } else {
-            if (pd + i > dest_end || src_size < 2)
+            if (dest_end - pd < i || ps_end - ps < 2)
                 return ps - src;
             for (i = 0; i < l; i++) {
                 *pd++ = ps[0];
                 *pd++ = ps[1];
             }
             ps += 2;
-            src_size -= 2;
         }
         i += l;
     } while (i < src_count);
@@ -213,9 +208,10 @@
 
     /* point to the start of the encoded data */
     const unsigned char *p = s->buf + 16;
+    const unsigned char *p_end = s->buf + s->size;
 
     const unsigned char *pb;
-    unsigned int pb_size;
+    const unsigned char *pb_end;
     unsigned char meth;
     unsigned char *dp;   /* pointer to current frame */
     unsigned char *pp;   /* pointer to previous frame */
@@ -261,29 +257,28 @@
 
     /* check if there is a new palette */
     if (s->buf[15] & 0x02) {
+        if (p_end - p < 2 + 3 * PALETTE_COUNT)
+            return;
         p += 2;
         palette32 = (unsigned int *)s->palette;
         for (i = 0; i < PALETTE_COUNT; i++) {
             r = *p++ * 4;
             g = *p++ * 4;
             b = *p++ * 4;
-            palette32[i] = (r << 16) | (g << 8) | (b);
+            palette32[i] = 0xFF << 24 | r << 16 | g << 8 | b;
+            palette32[i] |= palette32[i] >> 6 & 0x30303;
         }
-        s->size -= (256 * 3 + 2);
     }
-    if (s->size > 0) {
+    if (p < p_end) {
         /* originally UnpackFrame in VAG's code */
         pb = p;
-        pb_size = s->buf + s->size - pb;
-        if (pb_size < 1)
-            return;
-        meth = *pb++; pb_size--;
+        pb_end = p_end;
+        meth = *pb++;
         if (meth & 0x80) {
-            lz_unpack(pb, pb_size,
-                      s->unpack_buffer, s->unpack_buffer_size);
+            lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size);
             meth &= 0x7F;
             pb = s->unpack_buffer;
-            pb_size = s->unpack_buffer_size;
+            pb_end = s->unpack_buffer + s->unpack_buffer_size;
         }
 
         dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
@@ -293,17 +288,15 @@
             for (i = 0; i < frame_height; i++) {
                 ofs = 0;
                 do {
-                    if (pb_size < 1)
+                    if (pb_end - pb < 1)
                         return;
                     len = *pb++;
-                    pb_size--;
                     if (len & 0x80) {
                         len = (len & 0x7F) + 1;
-                        if (ofs + len > frame_width || pb_size < len)
+                        if (ofs + len > frame_width || pb_end - pb < len)
                             return;
                         memcpy(&dp[ofs], pb, len);
                         pb += len;
-                        pb_size -= len;
                         ofs += len;
                     } else {
                         /* interframe pixel copy */
@@ -314,7 +307,7 @@
                     }
                 } while (ofs < frame_width);
                 if (ofs > frame_width) {
-                    av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
+                    av_log(s->avctx, AV_LOG_ERROR, "offset > width (%d > %d)\n",
                         ofs, frame_width);
                     break;
                 }
@@ -325,11 +318,10 @@
 
         case 2:
             for (i = 0; i < frame_height; i++) {
-                if (pb_size < frame_width)
+                if (pb_end -pb < frame_width)
                     return;
                 memcpy(dp, pb, frame_width);
                 pb += frame_width;
-                pb_size -= frame_width;
                 dp += s->frame.linesize[0];
                 pp += s->prev_frame.linesize[0];
             }
@@ -339,23 +331,21 @@
             for (i = 0; i < frame_height; i++) {
                 ofs = 0;
                 do {
-                    if (pb_size < 1)
+                    if (pb_end - pb < 1)
                         return;
                     len = *pb++;
-                    pb_size--;
                     if (len & 0x80) {
                         len = (len & 0x7F) + 1;
-                        if (pb_size < 1)
+                        if (pb_end - pb < 1)
                             return;
                         if (*pb++ == 0xFF)
-                            len = rle_unpack(pb, &dp[ofs], len, pb_size, frame_width - ofs);
+                            len = rle_unpack(pb, pb_end - pb, len, &dp[ofs], frame_width - ofs);
                         else {
-                            if (pb_size < len)
-                                return;
+                        if (pb_end - pb < len)
+                            return;
                             memcpy(&dp[ofs], pb, len);
                         }
                         pb += len;
-                        pb_size -= 1 + len;
                         ofs += len;
                     } else {
                         /* interframe pixel copy */
@@ -366,7 +356,7 @@
                     }
                 } while (ofs < frame_width);
                 if (ofs > frame_width) {
-                    av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
+                    av_log(s->avctx, AV_LOG_ERROR, "offset > width (%d > %d)\n",
                         ofs, frame_width);
                 }
                 dp += s->frame.linesize[0];
@@ -392,7 +382,7 @@
 
     /* make sure the VMD header made it */
     if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
-        av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
+        av_log(s->avctx, AV_LOG_ERROR, "expected extradata size of %d\n",
             VMD_HEADER_SIZE);
         return -1;
     }
@@ -413,6 +403,9 @@
         palette32[i] = (r << 16) | (g << 8) | (b);
     }
 
+    avcodec_get_frame_defaults(&s->frame);
+    avcodec_get_frame_defaults(&s->prev_frame);
+
     return 0;
 }
 
@@ -430,9 +423,9 @@
     if (buf_size < 16)
         return buf_size;
 
-    s->frame.reference = 1;
+    s->frame.reference = 3;
     if (avctx->get_buffer(avctx, &s->frame)) {
-        av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
+        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
 
@@ -626,7 +619,7 @@
     /* decode audio chunks */
     if (audio_chunks > 0) {
         buf_end = buf + buf_size;
-        while (buf < buf_end) {
+        while ( buf_end - buf >= s->chunk_size) {
             if (s->out_bps == 2) {
                 decode_audio_s16(output_samples_s16, buf, s->chunk_size,
                                  avctx->channels);
diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c
index 3153be6..62a1312 100644
--- a/libavcodec/vmnc.c
+++ b/libavcodec/vmnc.c
@@ -2,20 +2,20 @@
  * VMware Screen Codec (VMnc) decoder
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -294,7 +294,7 @@
     const uint8_t *src = buf;
     int dx, dy, w, h, depth, enc, chunks, res, size_left;
 
-    c->pic.reference = 1;
+    c->pic.reference = 3;
     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
     if(avctx->reget_buffer(avctx, &c->pic) < 0){
         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
@@ -471,6 +471,7 @@
 
     c->bpp = avctx->bits_per_coded_sample;
     c->bpp2 = c->bpp/8;
+    avcodec_get_frame_defaults(&c->pic);
 
     switch(c->bpp){
     case 8:
diff --git a/libavcodec/vorbis.c b/libavcodec/vorbis.c
index 78a2467..adf08b5 100644
--- a/libavcodec/vorbis.c
+++ b/libavcodec/vorbis.c
@@ -1,18 +1,22 @@
-/*
- * This file is part of Libav.
+/**
+ * @file
+ * Common code for Vorbis I encoder and decoder
+ * @author Denes Balatoni  ( dbalatoni programozo hu )
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vorbis.h b/libavcodec/vorbis.h
index 6b72f6a..0bab0b9 100644
--- a/libavcodec/vorbis.h
+++ b/libavcodec/vorbis.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Oded Shimon <ods15@ods15.dyndns.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vorbis_data.c b/libavcodec/vorbis_data.c
index 98c7a59..f4b25fb 100644
--- a/libavcodec/vorbis_data.c
+++ b/libavcodec/vorbis_data.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2005 Denes Balatoni ( dbalatoni programozo hu )
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vorbis_enc_data.h b/libavcodec/vorbis_enc_data.h
index a1e743e..a51aaec 100644
--- a/libavcodec/vorbis_enc_data.h
+++ b/libavcodec/vorbis_enc_data.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Oded Shimon <ods15@ods15.dyndns.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -492,13 +492,13 @@
     int dim;
     int subclass;
     int masterbook;
-    const int *nbooks;
+    const int nbooks[4];
 } floor_classes[] = {
-    { 3, 0, 0, (const int[]){  4             } },
-    { 4, 1, 0, (const int[]){  5,  6         } },
-    { 3, 1, 1, (const int[]){  7,  8         } },
-    { 4, 2, 2, (const int[]){ -1,  9, 10, 11 } },
-    { 3, 2, 3, (const int[]){ -1, 12, 13, 14 } },
+    { 3, 0, 0, {  4             } },
+    { 4, 1, 0, {  5,  6         } },
+    { 3, 1, 1, {  7,  8         } },
+    { 4, 2, 2, { -1,  9, 10, 11 } },
+    { 3, 2, 3, { -1, 12, 13, 14 } },
 };
 
 #endif /* AVCODEC_VORBIS_ENC_DATA_H */
diff --git a/libavcodec/vorbis_parser.c b/libavcodec/vorbis_parser.c
index c6d300d..6979d6f 100644
--- a/libavcodec/vorbis_parser.c
+++ b/libavcodec/vorbis_parser.c
@@ -164,7 +164,7 @@
     skip_bits_long(&gb, got_framing_bit);
     for (i = mode_count - 1; i >= 0; i--) {
         skip_bits_long(&gb, 40);
-        s->mode_blocksize[i] = s->blocksize[get_bits1(&gb)];
+        s->mode_blocksize[i] = get_bits1(&gb);
     }
 
 bad_header:
@@ -195,7 +195,7 @@
         return ret;
 
     s->valid_extradata = 1;
-    s->previous_blocksize = s->mode_blocksize[0];
+    s->previous_blocksize = s->blocksize[s->mode_blocksize[0]];
 
     return 0;
 }
@@ -221,11 +221,11 @@
             av_log(s->avctx, AV_LOG_ERROR, "Invalid mode in packet\n");
             return AVERROR_INVALIDDATA;
         }
-        if (mode) {
+        if(s->mode_blocksize[mode]){
             int flag = !!(buf[0] & s->prev_mask);
             previous_blocksize = s->blocksize[flag];
         }
-        current_blocksize     = s->mode_blocksize[mode];
+        current_blocksize     = s->blocksize[s->mode_blocksize[mode]];
         duration              = (previous_blocksize + current_blocksize) >> 2;
         s->previous_blocksize = current_blocksize;
     }
@@ -236,7 +236,7 @@
 void avpriv_vorbis_parse_reset(VorbisParseContext *s)
 {
     if (s->valid_extradata)
-        s->previous_blocksize = s->mode_blocksize[0];
+        s->previous_blocksize = s->blocksize[0];
 }
 
 #if CONFIG_VORBIS_PARSER
diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c
index f5a541a..8ce0fc7 100644
--- a/libavcodec/vorbisdec.c
+++ b/libavcodec/vorbisdec.c
@@ -1,18 +1,22 @@
-/*
- * This file is part of Libav.
+/**
+ * @file
+ * Vorbis I decoder
+ * @author Denes Balatoni  ( dbalatoni programozo hu )
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -27,6 +31,7 @@
 
 #define BITSTREAM_READER_LE
 #include "libavutil/float_dsp.h"
+#include "libavutil/avassert.h"
 #include "avcodec.h"
 #include "get_bits.h"
 #include "dsputil.h"
@@ -41,9 +46,6 @@
 #define V_MAX_VLCS (1 << 16)
 #define V_MAX_PARTITIONS (1 << 20)
 
-#undef NDEBUG
-#include <assert.h>
-
 typedef struct {
     uint8_t      dimensions;
     uint8_t      lookup_type;
@@ -681,7 +683,7 @@
         res_setup->partition_size = get_bits(gb, 24) + 1;
         /* Validations to prevent a buffer overflow later. */
         if (res_setup->begin>res_setup->end ||
-            res_setup->end > (res_setup->type == 2 ? vc->avccontext->channels : 1) * vc->blocksize[1] / 2 ||
+            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,
                    "partition out of bounds: type, begin, end, size, blocksize: %"PRIu16", %"PRIu32", %"PRIu32", %u, %"PRIu32"\n",
@@ -936,12 +938,12 @@
     vc->bitrate_minimum = get_bits_long(gb, 32);
     bl0 = get_bits(gb, 4);
     bl1 = get_bits(gb, 4);
-    vc->blocksize[0] = (1 << bl0);
-    vc->blocksize[1] = (1 << bl1);
     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");
         return AVERROR_INVALIDDATA;
     }
+    vc->blocksize[0] = (1 << bl0);
+    vc->blocksize[1] = (1 << bl1);
     vc->win[0] = ff_vorbis_vwin[bl0 - 6];
     vc->win[1] = ff_vorbis_vwin[bl1 - 6];
 
@@ -1165,7 +1167,7 @@
     uint16_t floor1_Y[258];
     uint16_t floor1_Y_final[258];
     int floor1_flag[258];
-    unsigned class, cdim, cbits, csub, cval, offset, i, j;
+    unsigned partition_class, cdim, cbits, csub, cval, offset, i, j;
     int book, adx, ady, dy, off, predicted, err;
 
 
@@ -1181,20 +1183,20 @@
 
     offset = 2;
     for (i = 0; i < vf->partitions; ++i) {
-        class = vf->partition_class[i];
-        cdim   = vf->class_dimensions[class];
-        cbits  = vf->class_subclasses[class];
+        partition_class = vf->partition_class[i];
+        cdim   = vf->class_dimensions[partition_class];
+        cbits  = vf->class_subclasses[partition_class];
         csub = (1 << cbits) - 1;
         cval = 0;
 
         av_dlog(NULL, "Cbits %u\n", cbits);
 
         if (cbits) // this reads all subclasses for this partition's class
-            cval = get_vlc2(gb, vc->codebooks[vf->class_masterbook[class]].vlc.table,
-                            vc->codebooks[vf->class_masterbook[class]].nb_bits, 3);
+            cval = get_vlc2(gb, vc->codebooks[vf->class_masterbook[partition_class]].vlc.table,
+                            vc->codebooks[vf->class_masterbook[partition_class]].nb_bits, 3);
 
         for (j = 0; j < cdim; ++j) {
-            book = vf->subclass_books[class][cval & csub];
+            book = vf->subclass_books[partition_class][cval & csub];
 
             av_dlog(NULL, "book %d Cbits %u cval %u  bits:%d\n",
                     book, cbits, cval, get_bits_count(gb));
@@ -1330,7 +1332,7 @@
 
                         av_dlog(NULL, "Classword: %u\n", temp);
 
-                        assert(vr->classifications > 1 && temp <= 65536); //needed for inverse[]
+                        av_assert0(vr->classifications > 1 && temp <= 65536); //needed for inverse[]
                         for (i = 0; i < c_p_c; ++i) {
                             unsigned temp2;
 
diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c
index 42713f9..74d6331 100644
--- a/libavcodec/vorbisenc.c
+++ b/libavcodec/vorbisenc.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Oded Shimon <ods15@ods15.dyndns.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -1014,7 +1014,6 @@
     return 1;
 }
 
-
 static int vorbis_encode_frame(AVCodecContext *avccontext, AVPacket *avpkt,
                                const AVFrame *frame, int *got_packet_ptr)
 {
@@ -1030,10 +1029,8 @@
         return 0;
     samples = 1 << (venc->log2_blocksize[0] - 1);
 
-    if ((ret = ff_alloc_packet(avpkt, 8192))) {
-        av_log(avccontext, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avccontext, avpkt, 8192)))
         return ret;
-    }
 
     init_put_bits(&pb, avpkt->data, avpkt->size);
 
@@ -1171,7 +1168,7 @@
     int ret;
 
     if (avccontext->channels != 2) {
-        av_log(avccontext, AV_LOG_ERROR, "Current Libav Vorbis encoder only supports 2 channels.\n");
+        av_log(avccontext, AV_LOG_ERROR, "Current FFmpeg Vorbis encoder only supports 2 channels.\n");
         return -1;
     }
 
@@ -1182,7 +1179,7 @@
     if (avccontext->flags & CODEC_FLAG_QSCALE)
         venc->quality = avccontext->global_quality / (float)FF_QP2LAMBDA;
     else
-        venc->quality = 3.0;
+        venc->quality = 8;
     venc->quality *= venc->quality;
 
     if ((ret = put_main_header(venc, (uint8_t**)&avccontext->extradata)) < 0)
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
index 90532cb..2105bb5 100644
--- a/libavcodec/vp3.c
+++ b/libavcodec/vp3.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2003-2004 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -398,7 +398,7 @@
     int value;
 
     filter_limit = s->filter_limit_values[s->qps[0]];
-    assert(filter_limit < 128);
+    av_assert0(filter_limit < 128U);
 
     /* set up the bounding values */
     memset(s->bounding_values_array, 0, 256 * sizeof(int));
@@ -1575,19 +1575,13 @@
                     /* invert DCT and place (or add) in final output */
 
                     if (s->all_fragments[i].coding_method == MODE_INTRA) {
-                        int index;
-                        index = vp3_dequant(s, s->all_fragments + i, plane, 0, block);
-                        if (index > 63)
-                            continue;
+                        vp3_dequant(s, s->all_fragments + i, plane, 0, block);
                         s->vp3dsp.idct_put(
                             output_plane + first_pixel,
                             stride,
                             block);
                     } else {
-                        int index = vp3_dequant(s, s->all_fragments + i, plane, 1, block);
-                        if (index > 63)
-                            continue;
-                        if (index > 0) {
+                        if (vp3_dequant(s, s->all_fragments + i, plane, 1, block)) {
                         s->vp3dsp.idct_add(
                             output_plane + first_pixel,
                             stride,
@@ -1673,7 +1667,7 @@
     s->avctx = avctx;
     s->width = FFALIGN(avctx->width, 16);
     s->height = FFALIGN(avctx->height, 16);
-    if (avctx->pix_fmt == AV_PIX_FMT_NONE)
+    if (avctx->codec_id != AV_CODEC_ID_THEORA)
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
     ff_dsputil_init(&s->dsp, avctx);
@@ -1866,7 +1860,7 @@
         ||s->width != s1->width
         ||s->height!= s1->height) {
         if (s != s1)
-            copy_fields(s, s1, golden_frame, current_frame);
+            copy_fields(s, s1, golden_frame, keyframe);
         return -1;
     }
 
@@ -1960,6 +1954,7 @@
 
     s->current_frame.reference = 3;
     s->current_frame.pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+    s->current_frame.key_frame = s->keyframe;
     if (ff_thread_get_buffer(avctx, &s->current_frame) < 0) {
         av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         goto error;
@@ -2321,6 +2316,8 @@
     int header_len[3];
     int i;
 
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+
     s->theora = 1;
 
     if (!avctx->extradata_size)
diff --git a/libavcodec/vp3_parser.c b/libavcodec/vp3_parser.c
index ef2c55b..ce15309 100644
--- a/libavcodec/vp3_parser.c
+++ b/libavcodec/vp3_parser.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2008 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vp3data.h b/libavcodec/vp3data.h
index 54d5a6c..904ec6a 100644
--- a/libavcodec/vp3data.h
+++ b/libavcodec/vp3data.h
@@ -1,20 +1,20 @@
 /*
  * copyright (C) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vp3dsp.c b/libavcodec/vp3dsp.c
index 9b0b5d0..0e0c0f5 100644
--- a/libavcodec/vp3dsp.c
+++ b/libavcodec/vp3dsp.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2004 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vp3dsp.h b/libavcodec/vp3dsp.h
index 3781bbf..a14dec1 100644
--- a/libavcodec/vp3dsp.h
+++ b/libavcodec/vp3dsp.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c
index a94fdc8..3ae7c25 100644
--- a/libavcodec/vp5.c
+++ b/libavcodec/vp5.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -35,8 +35,7 @@
 #include "vp5data.h"
 
 
-static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
-                            int *golden_frame)
+static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
 {
     VP56RangeCoder *c = &s->c;
     int rows, cols;
diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c
index d67bdb6..1e373aa 100644
--- a/libavcodec/vp56.c
+++ b/libavcodec/vp56.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -449,9 +449,9 @@
     }
 }
 
-static int vp56_size_changed(AVCodecContext *avctx)
+static int vp56_size_changed(VP56Context *s)
 {
-    VP56Context *s = avctx->priv_data;
+    AVCodecContext *avctx = s->avctx;
     int stride = s->framep[VP56_FRAME_CURRENT]->linesize[0];
     int i;
 
@@ -483,17 +483,35 @@
     if (s->flip < 0)
         s->edge_emu_buffer += 15 * stride;
 
+    if (s->alpha_context)
+        return vp56_size_changed(s->alpha_context);
+
     return 0;
 }
 
+static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *, int, int);
+
 int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
                          AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     VP56Context *s = avctx->priv_data;
-    AVFrame *const p = s->framep[VP56_FRAME_CURRENT];
+    AVFrame *p = 0;
     int remaining_buf_size = avpkt->size;
-    int is_alpha, av_uninit(alpha_offset);
+    int av_uninit(alpha_offset);
+    int i, res;
+
+    /* select a current frame from the unused frames */
+    for (i = 0; i < 4; ++i) {
+        if (!s->frames[i].data[0]) {
+            p = &s->frames[i];
+            break;
+        }
+    }
+    av_assert0(p != 0);
+    s->framep[VP56_FRAME_CURRENT] = p;
+    if (s->alpha_context)
+        s->alpha_context->framep[VP56_FRAME_CURRENT] = p;
 
     if (s->has_alpha) {
         if (remaining_buf_size < 3)
@@ -504,150 +522,53 @@
             return -1;
     }
 
-    for (is_alpha=0; is_alpha < 1+s->has_alpha; is_alpha++) {
-        int mb_row, mb_col, mb_row_flip, mb_offset = 0;
-        int block, y, uv, stride_y, stride_uv;
-        int golden_frame = 0;
-        int res;
+    res = s->parse_header(s, buf, remaining_buf_size);
+    if (!res)
+        return -1;
 
-        s->modelp = &s->models[is_alpha];
-
-        res = s->parse_header(s, buf, remaining_buf_size, &golden_frame);
-        if (!res)
-            return -1;
-
-        if (res == 2) {
-            int i;
-            for (i = 0; i < 4; i++) {
-                if (s->frames[i].data[0])
-                    avctx->release_buffer(avctx, &s->frames[i]);
-            }
-            if (is_alpha) {
-                avcodec_set_dimensions(avctx, 0, 0);
-                return -1;
-            }
-        }
-
-        if (!is_alpha) {
-            p->reference = 1;
-            if (avctx->get_buffer(avctx, p) < 0) {
-                av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
-                return -1;
-            }
-
-            if (res == 2)
-                if (vp56_size_changed(avctx)) {
-                    avctx->release_buffer(avctx, p);
-                    return -1;
-                }
-        }
-
-        if (p->key_frame) {
-            p->pict_type = AV_PICTURE_TYPE_I;
-            s->default_models_init(s);
-            for (block=0; block<s->mb_height*s->mb_width; block++)
-                s->macroblocks[block].type = VP56_MB_INTRA;
-        } else {
-            p->pict_type = AV_PICTURE_TYPE_P;
-            vp56_parse_mb_type_models(s);
-            s->parse_vector_models(s);
-            s->mb_type = VP56_MB_INTER_NOVEC_PF;
-        }
-
-        if (s->parse_coeff_models(s))
-            goto next;
-
-        memset(s->prev_dc, 0, sizeof(s->prev_dc));
-        s->prev_dc[1][VP56_FRAME_CURRENT] = 128;
-        s->prev_dc[2][VP56_FRAME_CURRENT] = 128;
-
-        for (block=0; block < 4*s->mb_width+6; block++) {
-            s->above_blocks[block].ref_frame = VP56_FRAME_NONE;
-            s->above_blocks[block].dc_coeff = 0;
-            s->above_blocks[block].not_null_dc = 0;
-        }
-        s->above_blocks[2*s->mb_width + 2].ref_frame = VP56_FRAME_CURRENT;
-        s->above_blocks[3*s->mb_width + 4].ref_frame = VP56_FRAME_CURRENT;
-
-        stride_y  = p->linesize[0];
-        stride_uv = p->linesize[1];
-
-        if (s->flip < 0)
-            mb_offset = 7;
-
-        /* main macroblocks loop */
-        for (mb_row=0; mb_row<s->mb_height; mb_row++) {
-            if (s->flip < 0)
-                mb_row_flip = s->mb_height - mb_row - 1;
-            else
-                mb_row_flip = mb_row;
-
-            for (block=0; block<4; block++) {
-                s->left_block[block].ref_frame = VP56_FRAME_NONE;
-                s->left_block[block].dc_coeff = 0;
-                s->left_block[block].not_null_dc = 0;
-            }
-            memset(s->coeff_ctx, 0, sizeof(s->coeff_ctx));
-            memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last));
-
-            s->above_block_idx[0] = 1;
-            s->above_block_idx[1] = 2;
-            s->above_block_idx[2] = 1;
-            s->above_block_idx[3] = 2;
-            s->above_block_idx[4] = 2*s->mb_width + 2 + 1;
-            s->above_block_idx[5] = 3*s->mb_width + 4 + 1;
-
-            s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y;
-            s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y;
-            s->block_offset[1] = s->block_offset[0] + 8;
-            s->block_offset[3] = s->block_offset[2] + 8;
-            s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv;
-            s->block_offset[5] = s->block_offset[4];
-
-            for (mb_col=0; mb_col<s->mb_width; mb_col++) {
-                vp56_decode_mb(s, mb_row, mb_col, is_alpha);
-
-                for (y=0; y<4; y++) {
-                    s->above_block_idx[y] += 2;
-                    s->block_offset[y] += 16;
-                }
-
-                for (uv=4; uv<6; uv++) {
-                    s->above_block_idx[uv] += 1;
-                    s->block_offset[uv] += 8;
-                }
-            }
-        }
-
-    next:
-        if (p->key_frame || golden_frame) {
-            if (s->framep[VP56_FRAME_GOLDEN]->data[0] &&
-                s->framep[VP56_FRAME_GOLDEN] != s->framep[VP56_FRAME_GOLDEN2])
-                avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]);
-            s->framep[VP56_FRAME_GOLDEN] = p;
-        }
-
-        if (s->has_alpha) {
-            FFSWAP(AVFrame *, s->framep[VP56_FRAME_GOLDEN],
-                              s->framep[VP56_FRAME_GOLDEN2]);
-            buf += alpha_offset;
-            remaining_buf_size -= alpha_offset;
+    if (res == 2) {
+        for (i = 0; i < 4; i++) {
+            if (s->frames[i].data[0])
+                avctx->release_buffer(avctx, &s->frames[i]);
         }
     }
 
-    if (s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN] ||
-        s->framep[VP56_FRAME_PREVIOUS] == s->framep[VP56_FRAME_GOLDEN2]) {
-        if (s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN] &&
-            s->framep[VP56_FRAME_UNUSED] != s->framep[VP56_FRAME_GOLDEN2])
-            FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS],
-                              s->framep[VP56_FRAME_UNUSED]);
-        else
-            FFSWAP(AVFrame *, s->framep[VP56_FRAME_PREVIOUS],
-                              s->framep[VP56_FRAME_UNUSED2]);
-    } else if (s->framep[VP56_FRAME_PREVIOUS]->data[0])
-        avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]);
-    FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT],
-                      s->framep[VP56_FRAME_PREVIOUS]);
+    p->reference = 3;
+    if (avctx->get_buffer(avctx, p) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return -1;
+    }
+
+    if (res == 2) {
+        if (vp56_size_changed(s)) {
+            avctx->release_buffer(avctx, p);
+            return -1;
+        }
+    }
+
+    if (s->has_alpha) {
+        buf += alpha_offset;
+        remaining_buf_size -= alpha_offset;
+
+        res = s->alpha_context->parse_header(s->alpha_context, buf, remaining_buf_size);
+        if (res != 1) {
+            avctx->release_buffer(avctx, p);
+            return -1;
+        }
+    }
+
+    avctx->execute2(avctx, ff_vp56_decode_mbs, 0, 0, s->has_alpha + 1);
+
+    /* release frames that aren't in use */
+    for (i = 0; i < 4; ++i) {
+        AVFrame *victim = &s->frames[i];
+        if (!victim->data[0])
+            continue;
+        if (victim != s->framep[VP56_FRAME_PREVIOUS] &&
+            victim != s->framep[VP56_FRAME_GOLDEN] &&
+            (!s->has_alpha || victim != s->alpha_context->framep[VP56_FRAME_GOLDEN]))
+            avctx->release_buffer(avctx, victim);
+    }
 
     p->qstride = 0;
     p->qscale_table = s->qscale_table;
@@ -658,9 +579,112 @@
     return avpkt->size;
 }
 
+static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data,
+                              int jobnr, int threadnr)
+{
+    VP56Context *s0 = avctx->priv_data;
+    int is_alpha = (jobnr == 1);
+    VP56Context *s = is_alpha ? s0->alpha_context : s0;
+    AVFrame *const p = s->framep[VP56_FRAME_CURRENT];
+    int mb_row, mb_col, mb_row_flip, mb_offset = 0;
+    int block, y, uv, stride_y, stride_uv;
+
+    if (p->key_frame) {
+        p->pict_type = AV_PICTURE_TYPE_I;
+        s->default_models_init(s);
+        for (block=0; block<s->mb_height*s->mb_width; block++)
+            s->macroblocks[block].type = VP56_MB_INTRA;
+    } else {
+        p->pict_type = AV_PICTURE_TYPE_P;
+        vp56_parse_mb_type_models(s);
+        s->parse_vector_models(s);
+        s->mb_type = VP56_MB_INTER_NOVEC_PF;
+    }
+
+    if (s->parse_coeff_models(s))
+        goto next;
+
+    memset(s->prev_dc, 0, sizeof(s->prev_dc));
+    s->prev_dc[1][VP56_FRAME_CURRENT] = 128;
+    s->prev_dc[2][VP56_FRAME_CURRENT] = 128;
+
+    for (block=0; block < 4*s->mb_width+6; block++) {
+        s->above_blocks[block].ref_frame = VP56_FRAME_NONE;
+        s->above_blocks[block].dc_coeff = 0;
+        s->above_blocks[block].not_null_dc = 0;
+    }
+    s->above_blocks[2*s->mb_width + 2].ref_frame = VP56_FRAME_CURRENT;
+    s->above_blocks[3*s->mb_width + 4].ref_frame = VP56_FRAME_CURRENT;
+
+    stride_y  = p->linesize[0];
+    stride_uv = p->linesize[1];
+
+    if (s->flip < 0)
+        mb_offset = 7;
+
+    /* main macroblocks loop */
+    for (mb_row=0; mb_row<s->mb_height; mb_row++) {
+        if (s->flip < 0)
+            mb_row_flip = s->mb_height - mb_row - 1;
+        else
+            mb_row_flip = mb_row;
+
+        for (block=0; block<4; block++) {
+            s->left_block[block].ref_frame = VP56_FRAME_NONE;
+            s->left_block[block].dc_coeff = 0;
+            s->left_block[block].not_null_dc = 0;
+        }
+        memset(s->coeff_ctx, 0, sizeof(s->coeff_ctx));
+        memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last));
+
+        s->above_block_idx[0] = 1;
+        s->above_block_idx[1] = 2;
+        s->above_block_idx[2] = 1;
+        s->above_block_idx[3] = 2;
+        s->above_block_idx[4] = 2*s->mb_width + 2 + 1;
+        s->above_block_idx[5] = 3*s->mb_width + 4 + 1;
+
+        s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y;
+        s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y;
+        s->block_offset[1] = s->block_offset[0] + 8;
+        s->block_offset[3] = s->block_offset[2] + 8;
+        s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv;
+        s->block_offset[5] = s->block_offset[4];
+
+        for (mb_col=0; mb_col<s->mb_width; mb_col++) {
+            vp56_decode_mb(s, mb_row, mb_col, is_alpha);
+
+            for (y=0; y<4; y++) {
+                s->above_block_idx[y] += 2;
+                s->block_offset[y] += 16;
+            }
+
+            for (uv=4; uv<6; uv++) {
+                s->above_block_idx[uv] += 1;
+                s->block_offset[uv] += 8;
+            }
+        }
+    }
+
+next:
+    if (p->key_frame || s->golden_frame) {
+        s->framep[VP56_FRAME_GOLDEN] = p;
+    }
+
+    FFSWAP(AVFrame *, s->framep[VP56_FRAME_CURRENT],
+                      s->framep[VP56_FRAME_PREVIOUS]);
+    return 0;
+}
+
 av_cold void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha)
 {
     VP56Context *s = avctx->priv_data;
+    ff_vp56_init_context(avctx, s, flip, has_alpha);
+}
+
+av_cold void ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
+                                  int flip, int has_alpha)
+{
     int i;
 
     s->avctx = avctx;
@@ -672,8 +696,10 @@
     ff_init_scantable_permutation(s->dsp.idct_permutation, s->vp3dsp.idct_perm);
     ff_init_scantable(s->dsp.idct_permutation, &s->scantable,ff_zigzag_direct);
 
-    for (i=0; i<4; i++)
+    for (i=0; i<4; i++) {
         s->framep[i] = &s->frames[i];
+        avcodec_get_frame_defaults(&s->frames[i]);
+    }
     s->framep[VP56_FRAME_UNUSED] = s->framep[VP56_FRAME_GOLDEN];
     s->framep[VP56_FRAME_UNUSED2] = s->framep[VP56_FRAME_GOLDEN2];
     s->edge_emu_buffer_alloc = NULL;
@@ -682,10 +708,14 @@
     s->macroblocks = NULL;
     s->quantizer = -1;
     s->deblock_filtering = 1;
+    s->golden_frame = 0;
 
     s->filter = NULL;
 
     s->has_alpha = has_alpha;
+
+    s->modelp = &s->model;
+
     if (flip) {
         s->flip = -1;
         s->frbi = 2;
@@ -700,16 +730,21 @@
 av_cold int ff_vp56_free(AVCodecContext *avctx)
 {
     VP56Context *s = avctx->priv_data;
+    return ff_vp56_free_context(s);
+}
+
+av_cold int ff_vp56_free_context(VP56Context *s)
+{
+    AVCodecContext *avctx = s->avctx;
+    int i;
 
     av_freep(&s->qscale_table);
     av_freep(&s->above_blocks);
     av_freep(&s->macroblocks);
     av_freep(&s->edge_emu_buffer_alloc);
-    if (s->framep[VP56_FRAME_GOLDEN]->data[0])
-        avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN]);
-    if (s->framep[VP56_FRAME_GOLDEN2]->data[0])
-        avctx->release_buffer(avctx, s->framep[VP56_FRAME_GOLDEN2]);
-    if (s->framep[VP56_FRAME_PREVIOUS]->data[0])
-        avctx->release_buffer(avctx, s->framep[VP56_FRAME_PREVIOUS]);
+    for (i = 0; i < 4; ++i) {
+        if (s->frames[i].data[0])
+            avctx->release_buffer(avctx, &s->frames[i]);
+    }
     return 0;
 }
diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h
index 27539c7..65245a2 100644
--- a/libavcodec/vp56.h
+++ b/libavcodec/vp56.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -50,7 +50,7 @@
 typedef void (*VP56ParseVectorModels)(VP56Context *s);
 typedef int  (*VP56ParseCoeffModels)(VP56Context *s);
 typedef int  (*VP56ParseHeader)(VP56Context *s, const uint8_t *buf,
-                                int buf_size, int *golden_frame);
+                                int buf_size);
 
 typedef struct VP56RangeCoder {
     int high;
@@ -105,6 +105,7 @@
     int sub_version;
 
     /* frame info */
+    int golden_frame;
     int plane_width[4];
     int plane_height[4];
     int mb_width;   /* number of horizontal MB */
@@ -160,8 +161,11 @@
     VP56ParseCoeffModels parse_coeff_models;
     VP56ParseHeader parse_header;
 
+    /* for "slice" parallelism between YUV and A */
+    VP56Context *alpha_context;
+
     VP56Model *modelp;
-    VP56Model models[2];
+    VP56Model model;
 
     /* huffman decoding */
     int use_huffman;
@@ -174,7 +178,10 @@
 
 
 void ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha);
+void ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
+                          int flip, int has_alpha);
 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,
                          AVPacket *avpkt);
@@ -335,15 +342,13 @@
     return -tree->val;
 }
 
-/**
- * This is identical to vp8_rac_get_tree except for the possibility of starting
- * on a node other than the root node, needed for coeff decode where this is
- * used to save a bit after a 0 token (by disallowing EOB to immediately follow.)
- */
-static av_always_inline
-int vp8_rac_get_tree_with_offset(VP56RangeCoder *c, const int8_t (*tree)[2],
-                                 const uint8_t *probs, int i)
+// how probabilities are associated with decisions is different I think
+// well, the new scheme fits in the old but this way has one fewer branches per decision
+static av_always_inline int vp8_rac_get_tree(VP56RangeCoder *c, const int8_t (*tree)[2],
+                                   const uint8_t *probs)
 {
+    int i = 0;
+
     do {
         i = tree[i][vp56_rac_get_prob(c, probs[i])];
     } while (i > 0);
@@ -351,15 +356,6 @@
     return -i;
 }
 
-// how probabilities are associated with decisions is different I think
-// well, the new scheme fits in the old but this way has one fewer branches per decision
-static av_always_inline
-int vp8_rac_get_tree(VP56RangeCoder *c, const int8_t (*tree)[2],
-                     const uint8_t *probs)
-{
-    return vp8_rac_get_tree_with_offset(c, tree, probs, 0);
-}
-
 // DCTextra
 static av_always_inline int vp8_rac_get_coeff(VP56RangeCoder *c, const uint8_t *prob)
 {
diff --git a/libavcodec/vp56data.c b/libavcodec/vp56data.c
index 90e2f36..5500fe0 100644
--- a/libavcodec/vp56data.c
+++ b/libavcodec/vp56data.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vp56data.h b/libavcodec/vp56data.h
index 0535425..f30732e 100644
--- a/libavcodec/vp56data.h
+++ b/libavcodec/vp56data.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vp56dsp.c b/libavcodec/vp56dsp.c
index 5a36e52..a72c48e 100644
--- a/libavcodec/vp56dsp.c
+++ b/libavcodec/vp56dsp.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2006 Aurelien Jacobs <aurel@gnuage.org>
  * Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vp56dsp.h b/libavcodec/vp56dsp.h
index 034e2e9..51e8c16 100644
--- a/libavcodec/vp56dsp.h
+++ b/libavcodec/vp56dsp.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vp56rac.c b/libavcodec/vp56rac.c
index c009cad..f11531d 100644
--- a/libavcodec/vp56rac.c
+++ b/libavcodec/vp56rac.c
@@ -2,20 +2,20 @@
  * VP5/6/8 decoder
  * Copyright (c) 2010 Jason Garrett-Glaser <darkshikari@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vp5data.h b/libavcodec/vp5data.h
index b11b99d..e16ff2d 100644
--- a/libavcodec/vp5data.h
+++ b/libavcodec/vp5data.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c
index 826b777..bafa2b4 100644
--- a/libavcodec/vp6.c
+++ b/libavcodec/vp6.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -43,8 +43,7 @@
 static void vp6_parse_coeff(VP56Context *s);
 static void vp6_parse_coeff_huffman(VP56Context *s);
 
-static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
-                            int *golden_frame)
+static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
 {
     VP56RangeCoder *c = &s->c;
     int parse_filter_info = 0;
@@ -100,6 +99,7 @@
         if (sub_version < 8)
             vrt_shift = 5;
         s->sub_version = sub_version;
+        s->golden_frame = 0;
     } else {
         if (!s->sub_version || !s->avctx->coded_width || !s->avctx->coded_height)
             return 0;
@@ -111,7 +111,7 @@
         }
         ff_vp56_init_range_decoder(c, buf+1, buf_size-1);
 
-        *golden_frame = vp56_rac_get(c);
+        s->golden_frame = vp56_rac_get(c);
         if (s->filter_header) {
             s->deblock_filtering = vp56_rac_get(c);
             if (s->deblock_filtering)
@@ -590,12 +590,33 @@
     }
 }
 
+static av_cold void vp6_decode_init_context(VP56Context *s);
+
 static av_cold int vp6_decode_init(AVCodecContext *avctx)
 {
     VP56Context *s = avctx->priv_data;
 
     ff_vp56_init(avctx, avctx->codec->id == AV_CODEC_ID_VP6,
                         avctx->codec->id == AV_CODEC_ID_VP6A);
+    vp6_decode_init_context(s);
+
+    if (s->has_alpha) {
+        int i;
+
+        s->alpha_context = av_mallocz(sizeof(VP56Context));
+        ff_vp56_init_context(avctx, s->alpha_context,
+                             s->flip == -1, s->has_alpha);
+        vp6_decode_init_context(s->alpha_context);
+        for (i = 0; i < 6; ++i)
+            s->alpha_context->framep[i] = s->framep[i];
+    }
+
+    return 0;
+}
+
+static av_cold void vp6_decode_init_context(VP56Context *s)
+{
+    s->deblock_filtering = 0;
     s->vp56_coord_div = vp6_coord_div;
     s->parse_vector_adjustment = vp6_parse_vector_adjustment;
     s->filter = vp6_filter;
@@ -603,16 +624,29 @@
     s->parse_vector_models = vp6_parse_vector_models;
     s->parse_coeff_models = vp6_parse_coeff_models;
     s->parse_header = vp6_parse_header;
-
-    return 0;
 }
 
+static av_cold void vp6_decode_free_context(VP56Context *s);
+
 static av_cold int vp6_decode_free(AVCodecContext *avctx)
 {
     VP56Context *s = avctx->priv_data;
-    int pt, ct, cg;
 
     ff_vp56_free(avctx);
+    vp6_decode_free_context(s);
+
+    if (s->alpha_context) {
+        ff_vp56_free_context(s->alpha_context);
+        vp6_decode_free_context(s->alpha_context);
+        av_free(s->alpha_context);
+    }
+
+    return 0;
+}
+
+static av_cold void vp6_decode_free_context(VP56Context *s)
+{
+    int pt, ct, cg;
 
     for (pt=0; pt<2; pt++) {
         ff_free_vlc(&s->dccv_vlc[pt]);
@@ -621,7 +655,6 @@
             for (cg=0; cg<6; cg++)
                 ff_free_vlc(&s->ract_vlc[pt][ct][cg]);
     }
-    return 0;
 }
 
 AVCodec ff_vp6_decoder = {
@@ -658,6 +691,6 @@
     .init           = vp6_decode_init,
     .close          = vp6_decode_free,
     .decode         = ff_vp56_decode_frame,
-    .capabilities   = CODEC_CAP_DR1,
+    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
     .long_name      = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"),
 };
diff --git a/libavcodec/vp6data.h b/libavcodec/vp6data.h
index 9a11f89..3ebfd0e 100644
--- a/libavcodec/vp6data.h
+++ b/libavcodec/vp6data.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vp6dsp.c b/libavcodec/vp6dsp.c
index 54a96ed..67c6be0 100644
--- a/libavcodec/vp6dsp.c
+++ b/libavcodec/vp6dsp.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index 2766c9e..0bb5495 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -6,20 +6,20 @@
  * Copyright (C) 2010 Jason Garrett-Glaser
  * Copyright (C) 2012 Daniel Kang
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -117,7 +117,7 @@
     AVCodecContext *avctx = s->avctx;
     int i;
 
-    if (width  != s->avctx->width ||
+    if (width  != s->avctx->width || ((width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) && s->macroblocks_base ||
         height != s->avctx->height) {
         if (av_image_check_size(width, height, 0, s->avctx))
             return AVERROR_INVALIDDATA;
@@ -385,7 +385,7 @@
     }
 
     if (!s->macroblocks_base || /* first frame */
-        width != s->avctx->width || height != s->avctx->height) {
+        width != s->avctx->width || height != s->avctx->height || (width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) {
         if ((ret = update_dimensions(s, width, height)) < 0)
             return ret;
     }
@@ -701,9 +701,10 @@
 {
     VP56RangeCoder *c = &s->c;
 
-    if (s->segmentation.update_map)
-        *segment = vp8_rac_get_tree(c, vp8_segmentid_tree, s->prob->segmentid);
-    else if (s->segmentation.enabled)
+    if (s->segmentation.update_map) {
+        int bit  = vp56_rac_get_prob(c, s->prob->segmentid[0]);
+        *segment = vp56_rac_get_prob(c, s->prob->segmentid[1+bit]) + 2*bit;
+    } else if (s->segmentation.enabled)
         *segment = ref ? *ref : *segment;
     mb->segment = *segment;
 
diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h
index 073a033..2193487 100644
--- a/libavcodec/vp8.h
+++ b/libavcodec/vp8.h
@@ -6,20 +6,20 @@
  * Copyright (C) 2010 Jason Garrett-Glaser
  * Copyright (C) 2012 Daniel Kang
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -34,6 +34,8 @@
 #include <pthread.h>
 #elif HAVE_W32THREADS
 #include "w32pthreads.h"
+#elif HAVE_OS2THREADS
+#include "os2threads.h"
 #endif
 
 #define VP8_MAX_QUANT 127
diff --git a/libavcodec/vp8_parser.c b/libavcodec/vp8_parser.c
index 196de83..096961f 100644
--- a/libavcodec/vp8_parser.c
+++ b/libavcodec/vp8_parser.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2008 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vp8data.h b/libavcodec/vp8data.h
index a48b0f6..0ea24d7 100644
--- a/libavcodec/vp8data.h
+++ b/libavcodec/vp8data.h
@@ -2,20 +2,20 @@
  * Copyright (C) 2010 David Conrad
  * Copyright (C) 2010 Ronald S. Bultje
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vp8dsp.c b/libavcodec/vp8dsp.c
index 2ab68bc..a53643c 100644
--- a/libavcodec/vp8dsp.c
+++ b/libavcodec/vp8dsp.c
@@ -2,20 +2,20 @@
  * Copyright (C) 2010 David Conrad
  * Copyright (C) 2010 Ronald S. Bultje
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/vp8dsp.h b/libavcodec/vp8dsp.h
index 62cc010..c4b9aa1 100644
--- a/libavcodec/vp8dsp.h
+++ b/libavcodec/vp8dsp.h
@@ -2,20 +2,20 @@
  * Copyright (C) 2010 David Conrad
  * Copyright (C) 2010 Ronald S. Bultje
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -73,7 +73,7 @@
      * second dimension: 0 if no vertical interpolation is needed;
      *                   1 4-tap vertical interpolation filter (my & 1)
      *                   2 6-tap vertical interpolation filter (!(my & 1))
-     * third dimension: same as second dimention, for horizontal interpolation
+     * third dimension: same as second dimension, for horizontal interpolation
      * so something like put_vp8_epel_pixels_tab[width>>3][2*!!my-(my&1)][2*!!mx-(mx&1)](..., mx, my)
      */
     vp8_mc_func put_vp8_epel_pixels_tab[3][3][3];
diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c
index 32b094d..93a602e 100644
--- a/libavcodec/vqavideo.c
+++ b/libavcodec/vqavideo.c
@@ -2,20 +2,20 @@
  * Westwood Studios VQA Video Decoder
  * Copyright (C) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -128,12 +128,16 @@
 
     /* make sure the extradata made it */
     if (s->avctx->extradata_size != VQA_HEADER_SIZE) {
-        av_log(s->avctx, AV_LOG_ERROR, "  VQA video: expected extradata size of %d\n", VQA_HEADER_SIZE);
+        av_log(s->avctx, AV_LOG_ERROR, "expected extradata size of %d\n", VQA_HEADER_SIZE);
         return -1;
     }
 
     /* load up the VQA parameters from the header */
     s->vqa_version = s->avctx->extradata[0];
+    if (s->vqa_version < 1 || s->vqa_version > 3) {
+        av_log(s->avctx, AV_LOG_ERROR, "unsupported version %d\n", s->vqa_version);
+        return -1;
+    }
     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)){
@@ -151,8 +155,7 @@
         return -1;
     }
 
-    if (s->width  & (s->vector_width  - 1) ||
-        s->height & (s->vector_height - 1)) {
+    if (s->width % s->vector_width || s->height % s->vector_height) {
         av_log(avctx, AV_LOG_ERROR, "Image size not multiple of block size\n");
         return AVERROR_INVALIDDATA;
     }
@@ -187,6 +190,7 @@
     }
     s->next_codebook_buffer_index = 0;
 
+    avcodec_get_frame_defaults(&s->frame);
     s->frame.data[0] = NULL;
 
     return 0;
@@ -199,22 +203,22 @@
 
 #define CHECK_COUNT() \
     if (dest_index + count > dest_size) { \
-        av_log(NULL, AV_LOG_ERROR, "  VQA video: decode_format80 problem: next op would overflow dest_index\n"); \
-        av_log(NULL, AV_LOG_ERROR, "  VQA video: current dest_index = %d, count = %d, dest_size = %d\n", \
+        av_log(s->avctx, AV_LOG_ERROR, "decode_format80 problem: next op would overflow dest_index\n"); \
+        av_log(s->avctx, AV_LOG_ERROR, "current dest_index = %d, count = %d, dest_size = %d\n", \
             dest_index, count, dest_size); \
         return AVERROR_INVALIDDATA; \
     }
 
 #define CHECK_COPY(idx) \
     if (idx < 0 || idx + count > dest_size) { \
-        av_log(NULL, AV_LOG_ERROR, "  VQA video: decode_format80 problem: next op would overflow dest_index\n"); \
-        av_log(NULL, AV_LOG_ERROR, "  VQA video: current src_pos = %d, count = %d, dest_size = %d\n", \
+        av_log(s->avctx, AV_LOG_ERROR, "decode_format80 problem: next op would overflow dest_index\n"); \
+        av_log(s->avctx, AV_LOG_ERROR, "current src_pos = %d, count = %d, dest_size = %d\n", \
             src_pos, count, dest_size); \
         return AVERROR_INVALIDDATA; \
     }
 
 
-static int decode_format80(GetByteContext *gb, int src_size,
+static int decode_format80(VqaContext *s, int src_size,
     unsigned char *dest, int dest_size, int check_size) {
 
     int dest_index = 0;
@@ -223,26 +227,26 @@
     unsigned char color;
     int i;
 
-    start = bytestream2_tell(gb);
-    while (bytestream2_tell(gb) - start < src_size) {
-        opcode = bytestream2_get_byte(gb);
-        av_dlog(NULL, "      opcode %02X: ", opcode);
+    start = bytestream2_tell(&s->gb);
+    while (bytestream2_tell(&s->gb) - start < src_size) {
+        opcode = bytestream2_get_byte(&s->gb);
+        av_dlog(s->avctx, "opcode %02X: ", opcode);
 
         /* 0x80 means that frame is finished */
         if (opcode == 0x80)
             return 0;
 
         if (dest_index >= dest_size) {
-            av_log(NULL, AV_LOG_ERROR, "  VQA video: decode_format80 problem: dest_index (%d) exceeded dest_size (%d)\n",
+            av_log(s->avctx, AV_LOG_ERROR, "decode_format80 problem: dest_index (%d) exceeded dest_size (%d)\n",
                 dest_index, dest_size);
             return AVERROR_INVALIDDATA;
         }
 
         if (opcode == 0xFF) {
 
-            count   = bytestream2_get_le16(gb);
-            src_pos = bytestream2_get_le16(gb);
-            av_dlog(NULL, "(1) copy %X bytes from absolute pos %X\n", count, src_pos);
+            count   = bytestream2_get_le16(&s->gb);
+            src_pos = bytestream2_get_le16(&s->gb);
+            av_dlog(s->avctx, "(1) copy %X bytes from absolute pos %X\n", count, src_pos);
             CHECK_COUNT();
             CHECK_COPY(src_pos);
             for (i = 0; i < count; i++)
@@ -251,9 +255,9 @@
 
         } else if (opcode == 0xFE) {
 
-            count = bytestream2_get_le16(gb);
-            color = bytestream2_get_byte(gb);
-            av_dlog(NULL, "(2) set %X bytes to %02X\n", count, color);
+            count = bytestream2_get_le16(&s->gb);
+            color = bytestream2_get_byte(&s->gb);
+            av_dlog(s->avctx, "(2) set %X bytes to %02X\n", count, color);
             CHECK_COUNT();
             memset(&dest[dest_index], color, count);
             dest_index += count;
@@ -261,8 +265,8 @@
         } else if ((opcode & 0xC0) == 0xC0) {
 
             count = (opcode & 0x3F) + 3;
-            src_pos = bytestream2_get_le16(gb);
-            av_dlog(NULL, "(3) copy %X bytes from absolute pos %X\n", count, src_pos);
+            src_pos = bytestream2_get_le16(&s->gb);
+            av_dlog(s->avctx, "(3) copy %X bytes from absolute pos %X\n", count, src_pos);
             CHECK_COUNT();
             CHECK_COPY(src_pos);
             for (i = 0; i < count; i++)
@@ -272,16 +276,16 @@
         } else if (opcode > 0x80) {
 
             count = opcode & 0x3F;
-            av_dlog(NULL, "(4) copy %X bytes from source to dest\n", count);
+            av_dlog(s->avctx, "(4) copy %X bytes from source to dest\n", count);
             CHECK_COUNT();
-            bytestream2_get_buffer(gb, &dest[dest_index], count);
+            bytestream2_get_buffer(&s->gb, &dest[dest_index], count);
             dest_index += count;
 
         } else {
 
             count = ((opcode & 0x70) >> 4) + 3;
-            src_pos = bytestream2_get_byte(gb) | ((opcode & 0x0F) << 8);
-            av_dlog(NULL, "(5) copy %X bytes from relpos %X\n", count, src_pos);
+            src_pos = bytestream2_get_byte(&s->gb) | ((opcode & 0x0F) << 8);
+            av_dlog(s->avctx, "(5) copy %X bytes from relpos %X\n", count, src_pos);
             CHECK_COUNT();
             CHECK_COPY(dest_index - src_pos);
             for (i = 0; i < count; i++)
@@ -296,7 +300,7 @@
      * not every entry needs to be filled */
     if (check_size)
         if (dest_index < dest_size)
-            av_log(NULL, AV_LOG_ERROR, "  VQA video: decode_format80 problem: decode finished with dest_index (%d) < dest_size (%d)\n",
+            av_log(s->avctx, AV_LOG_ERROR, "decode_format80 problem: decode finished with dest_index (%d) < dest_size (%d)\n",
                 dest_index, dest_size);
 
     return 0; // let's display what we decoded anyway
@@ -368,7 +372,7 @@
             break;
 
         default:
-            av_log(s->avctx, AV_LOG_ERROR, "  VQA video: Found unknown chunk type: %c%c%c%c (%08X)\n",
+            av_log(s->avctx, AV_LOG_ERROR, "Found unknown chunk type: %c%c%c%c (%08X)\n",
             (chunk_type >> 24) & 0xFF,
             (chunk_type >> 16) & 0xFF,
             (chunk_type >>  8) & 0xFF,
@@ -385,7 +389,7 @@
     if ((cpl0_chunk != -1) && (cplz_chunk != -1)) {
 
         /* a chunk should not have both chunk types */
-        av_log(s->avctx, AV_LOG_ERROR, "  VQA video: problem: found both CPL0 and CPLZ chunks\n");
+        av_log(s->avctx, AV_LOG_ERROR, "problem: found both CPL0 and CPLZ chunks\n");
         return AVERROR_INVALIDDATA;
     }
 
@@ -403,7 +407,7 @@
         chunk_size = bytestream2_get_be32(&s->gb);
         /* sanity check the palette size */
         if (chunk_size / 3 > 256 || chunk_size > bytestream2_get_bytes_left(&s->gb)) {
-            av_log(s->avctx, AV_LOG_ERROR, "  VQA video: problem: found a palette chunk with %d colors\n",
+            av_log(s->avctx, AV_LOG_ERROR, "problem: found a palette chunk with %d colors\n",
                 chunk_size / 3);
             return AVERROR_INVALIDDATA;
         }
@@ -412,7 +416,8 @@
             r = bytestream2_get_byteu(&s->gb) * 4;
             g = bytestream2_get_byteu(&s->gb) * 4;
             b = bytestream2_get_byteu(&s->gb) * 4;
-            s->palette[i] = (r << 16) | (g << 8) | (b);
+            s->palette[i] = 0xFF << 24 | r << 16 | g << 8 | b;
+            s->palette[i] |= s->palette[i] >> 6 & 0x30303;
         }
     }
 
@@ -420,7 +425,7 @@
     if ((cbf0_chunk != -1) && (cbfz_chunk != -1)) {
 
         /* a chunk should not have both chunk types */
-        av_log(s->avctx, AV_LOG_ERROR, "  VQA video: problem: found both CBF0 and CBFZ chunks\n");
+        av_log(s->avctx, AV_LOG_ERROR, "problem: found both CBF0 and CBFZ chunks\n");
         return AVERROR_INVALIDDATA;
     }
 
@@ -429,7 +434,7 @@
 
         bytestream2_seek(&s->gb, cbfz_chunk, SEEK_SET);
         chunk_size = bytestream2_get_be32(&s->gb);
-        if ((res = decode_format80(&s->gb, chunk_size, s->codebook,
+        if ((res = decode_format80(s, chunk_size, s->codebook,
                                    s->codebook_size, 0)) < 0)
             return res;
     }
@@ -441,7 +446,7 @@
         chunk_size = bytestream2_get_be32(&s->gb);
         /* sanity check the full codebook size */
         if (chunk_size > MAX_CODEBOOK_SIZE) {
-            av_log(s->avctx, AV_LOG_ERROR, "  VQA video: problem: CBF0 chunk too large (0x%X bytes)\n",
+            av_log(s->avctx, AV_LOG_ERROR, "problem: CBF0 chunk too large (0x%X bytes)\n",
                 chunk_size);
             return AVERROR_INVALIDDATA;
         }
@@ -453,13 +458,13 @@
     if (vptz_chunk == -1) {
 
         /* something is wrong if there is no VPTZ chunk */
-        av_log(s->avctx, AV_LOG_ERROR, "  VQA video: problem: no VPTZ chunk found\n");
+        av_log(s->avctx, AV_LOG_ERROR, "problem: no VPTZ chunk found\n");
         return AVERROR_INVALIDDATA;
     }
 
     bytestream2_seek(&s->gb, vptz_chunk, SEEK_SET);
     chunk_size = bytestream2_get_be32(&s->gb);
-    if ((res = decode_format80(&s->gb, chunk_size,
+    if ((res = decode_format80(s, chunk_size,
                                s->decode_buffer, s->decode_buffer_size, 1)) < 0)
         return res;
 
@@ -522,7 +527,7 @@
     /* handle partial codebook */
     if ((cbp0_chunk != -1) && (cbpz_chunk != -1)) {
         /* a chunk should not have both chunk types */
-        av_log(s->avctx, AV_LOG_ERROR, "  VQA video: problem: found both CBP0 and CBPZ chunks\n");
+        av_log(s->avctx, AV_LOG_ERROR, "problem: found both CBP0 and CBPZ chunks\n");
         return AVERROR_INVALIDDATA;
     }
 
@@ -537,7 +542,7 @@
         s->next_codebook_buffer_index += chunk_size;
 
         s->partial_countdown--;
-        if (s->partial_countdown == 0) {
+        if (s->partial_countdown <= 0) {
 
             /* time to replace codebook */
             memcpy(s->codebook, s->next_codebook_buffer,
@@ -560,12 +565,12 @@
         s->next_codebook_buffer_index += chunk_size;
 
         s->partial_countdown--;
-        if (s->partial_countdown == 0) {
+        if (s->partial_countdown <= 0) {
             GetByteContext gb;
 
             bytestream2_init(&gb, s->next_codebook_buffer, s->next_codebook_buffer_index);
             /* decompress codebook */
-            if ((res = decode_format80(&gb, s->next_codebook_buffer_index,
+            if ((res = decode_format80(s, s->next_codebook_buffer_index,
                                        s->codebook, s->codebook_size, 0)) < 0)
                 return res;
 
@@ -589,7 +594,7 @@
         avctx->release_buffer(avctx, &s->frame);
 
     if (avctx->get_buffer(avctx, &s->frame)) {
-        av_log(s->avctx, AV_LOG_ERROR, "  VQA Video: get_buffer() failed\n");
+        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     }
 
diff --git a/libavcodec/w32pthreads.h b/libavcodec/w32pthreads.h
index 91e7353..29185c7 100644
--- a/libavcodec/w32pthreads.h
+++ b/libavcodec/w32pthreads.h
@@ -39,6 +39,7 @@
 #include <windows.h>
 #include <process.h>
 
+#include "libavutil/common.h"
 #include "libavutil/internal.h"
 #include "libavutil/mem.h"
 
diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index eafb40d..ef4fc4f 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -2,20 +2,20 @@
  * WavPack lossless audio decoder
  * Copyright (c) 2006,2011 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/webvttdec.c b/libavcodec/webvttdec.c
new file mode 100644
index 0000000..6b86bed
--- /dev/null
+++ b/libavcodec/webvttdec.c
@@ -0,0 +1,100 @@
+/*
+ * 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
+ * WebVTT subtitle decoder
+ * @see http://dev.w3.org/html5/webvtt/
+ * @todo need to support extended markups and cue settings
+ */
+
+#include "avcodec.h"
+#include "ass.h"
+#include "libavutil/bprint.h"
+
+static const struct {
+    const char *from;
+    const char *to;
+} webvtt_tag_replace[] = {
+    {"<i>", "{\\i1}"}, {"</i>", "{\\i0}"},
+    {"<b>", "{\\b1}"}, {"</b>", "{\\b0}"},
+    {"<u>", "{\\u1}"}, {"</u>", "{\\u0}"},
+    {"{", "\\{"}, {"}", "\\}"}, // escape to avoid ASS markup conflicts
+};
+
+static int webvtt_event_to_ass(AVBPrint *buf, const char *p)
+{
+    int i, skip = 0;
+
+    while (*p) {
+
+        for (i = 0; i < FF_ARRAY_ELEMS(webvtt_tag_replace); i++) {
+            const char *from = webvtt_tag_replace[i].from;
+            const size_t len = strlen(from);
+            if (!strncmp(p, from, len)) {
+                av_bprintf(buf, "%s", webvtt_tag_replace[i].to);
+                p += len;
+                break;
+            }
+        }
+        if (!*p)
+            break;
+
+        if (*p == '<')
+            skip = 1;
+        else if (*p == '>')
+            skip = 0;
+        else if (p[0] == '\n' && p[1])
+            av_bprintf(buf, "\\N");
+        else if (!skip && *p != '\r')
+            av_bprint_chars(buf, *p, 1);
+        p++;
+    }
+    av_bprintf(buf, "\r\n");
+    return 0;
+}
+
+static int webvtt_decode_frame(AVCodecContext *avctx,
+                               void *data, int *got_sub_ptr, AVPacket *avpkt)
+{
+    AVSubtitle *sub = data;
+    const char *ptr = avpkt->data;
+    AVBPrint buf;
+
+    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
+    if (ptr && avpkt->size > 0 && !webvtt_event_to_ass(&buf, ptr)) {
+        int ts_start     = av_rescale_q(avpkt->pts, avctx->time_base, (AVRational){1,100});
+        int ts_duration  = avpkt->duration != -1 ?
+                           av_rescale_q(avpkt->duration, avctx->time_base, (AVRational){1,100}) : -1;
+        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_webvtt_decoder = {
+    .name           = "webvtt",
+    .long_name      = NULL_IF_CONFIG_SMALL("WebVTT subtitle"),
+    .type           = AVMEDIA_TYPE_SUBTITLE,
+    .id             = AV_CODEC_ID_WEBVTT,
+    .decode         = webvtt_decode_frame,
+    .init           = ff_ass_subtitle_header_default,
+};
diff --git a/libavcodec/wma.c b/libavcodec/wma.c
index f9ba9c3..c652817 100644
--- a/libavcodec/wma.c
+++ b/libavcodec/wma.c
@@ -1,21 +1,21 @@
 /*
  * WMA compatible codec
- * Copyright (c) 2002-2007 The Libav Project
+ * Copyright (c) 2002-2007 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/wma.h b/libavcodec/wma.h
index f81e095..1e7f0e5 100644
--- a/libavcodec/wma.h
+++ b/libavcodec/wma.h
@@ -1,21 +1,21 @@
 /*
  * WMA compatible codec
- * Copyright (c) 2002-2007 The Libav Project
+ * Copyright (c) 2002-2007 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/wma_common.h b/libavcodec/wma_common.h
index 3a786c3..84d2cda 100644
--- a/libavcodec/wma_common.h
+++ b/libavcodec/wma_common.h
@@ -1,20 +1,20 @@
 /*
  * common code shared by all WMA variants
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/wmadata.h b/libavcodec/wmadata.h
index 07a1afe..381f182 100644
--- a/libavcodec/wmadata.h
+++ b/libavcodec/wmadata.h
@@ -1,21 +1,21 @@
 /*
  * WMA compatible decoder
- * copyright (c) 2002 The Libav Project
+ * copyright (c) 2002 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c
index 79401e2..1bcf0da 100644
--- a/libavcodec/wmadec.c
+++ b/libavcodec/wmadec.c
@@ -1,21 +1,21 @@
 /*
  * WMA compatible decoder
- * Copyright (c) 2002 The Libav Project
+ * Copyright (c) 2002 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -100,6 +100,13 @@
     s->use_bit_reservoir = flags2 & 0x0002;
     s->use_variable_block_len = flags2 & 0x0004;
 
+    if(avctx->codec->id == AV_CODEC_ID_WMAV2 && avctx->extradata_size >= 8){
+        if(AV_RL16(extradata+4)==0xd && s->use_variable_block_len){
+            av_log(avctx, AV_LOG_WARNING, "Disabling use_variable_block_len, if this fails contact the ffmpeg developers and send us the file\n");
+            s->use_variable_block_len= 0; // this fixes issue1503
+        }
+    }
+
     if(ff_wma_init(avctx, flags2)<0)
         return -1;
 
@@ -482,6 +489,11 @@
         s->block_len_bits = s->frame_len_bits;
     }
 
+    if (s->frame_len_bits - s->block_len_bits >= s->nb_block_sizes){
+        av_log(s->avctx, AV_LOG_ERROR, "block_len_bits not initialized to a valid value\n");
+        return -1;
+    }
+
     /* now check if the block length is coherent with the frame length */
     s->block_len = 1 << s->block_len_bits;
     if ((s->block_pos + s->block_len) > s->frame_len){
@@ -821,7 +833,8 @@
                buf_size, s->block_align);
         return AVERROR_INVALIDDATA;
     }
-    buf_size = s->block_align;
+    if(s->block_align)
+        buf_size = s->block_align;
 
     init_get_bits(&s->gb, buf, buf_size*8);
 
@@ -920,7 +933,7 @@
     *got_frame_ptr   = 1;
     *(AVFrame *)data = s->frame;
 
-    return s->block_align;
+    return buf_size;
  fail:
     /* when error, we reset the bit reservoir */
     s->last_superframe_len = 0;
@@ -935,6 +948,7 @@
     s->last_superframe_len= 0;
 }
 
+#if CONFIG_WMAV1_DECODER
 AVCodec ff_wmav1_decoder = {
     .name           = "wmav1",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -947,7 +961,8 @@
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"),
 };
-
+#endif
+#if CONFIG_WMAV2_DECODER
 AVCodec ff_wmav2_decoder = {
     .name           = "wmav2",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -960,3 +975,4 @@
     .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"),
 };
+#endif
diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c
index 8abb55b..63f815c 100644
--- a/libavcodec/wmaenc.c
+++ b/libavcodec/wmaenc.c
@@ -2,29 +2,27 @@
  * WMA compatible encoder
  * Copyright (c) 2007 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "avcodec.h"
 #include "internal.h"
 #include "wma.h"
-
-#undef NDEBUG
-#include <assert.h>
+#include "libavutil/avassert.h"
 
 
 static int encode_init(AVCodecContext * avctx){
@@ -66,7 +64,7 @@
         AV_WL32(extradata, flags1);
         AV_WL16(extradata+4, flags2);
     }else
-        assert(0);
+        av_assert0(0);
     avctx->extradata= extradata;
     s->use_exp_vlc = flags2 & 0x0001;
     s->use_bit_reservoir = flags2 & 0x0002;
@@ -84,8 +82,6 @@
                          (avctx->sample_rate * 8);
     s->block_align     = FFMIN(s->block_align, MAX_CODED_SUPERFRAME_SIZE);
     avctx->block_align = s->block_align;
-    avctx->bit_rate    = avctx->block_align * 8LL * avctx->sample_rate /
-                         s->frame_len;
     avctx->frame_size = avctx->delay = s->frame_len;
 
 #if FF_API_OLD_ENCODE_AUDIO
@@ -150,7 +146,7 @@
     q_end = q + s->block_len;
     if (s->version == 1) {
         last_exp= *exp_param++;
-        assert(last_exp-10 >= 0 && last_exp-10 < 32);
+        av_assert0(last_exp-10 >= 0 && last_exp-10 < 32);
         put_bits(&s->pb, 5, last_exp - 10);
         q+= *ptr++;
     }else
@@ -158,7 +154,7 @@
     while (q < q_end) {
         int exp = *exp_param++;
         int code = exp - last_exp + 60;
-        assert(code >= 0 && code < 120);
+        av_assert1(code >= 0 && code < 120);
         put_bits(&s->pb, ff_aac_scalefactor_bits[code], ff_aac_scalefactor_code[code]);
         /* XXX: use a table */
         q+= *ptr++;
@@ -174,7 +170,7 @@
 
     //FIXME remove duplication relative to decoder
     if (s->use_variable_block_len) {
-        assert(0); //FIXME not implemented
+        av_assert0(0); //FIXME not implemented
     }else{
         /* fixed block len */
         s->next_block_len_bits = s->frame_len_bits;
@@ -221,7 +217,7 @@
             mult *= mdct_norm;
             coefs = src_coefs[ch];
             if (s->use_noise_coding && 0) {
-                assert(0); //FIXME not implemented
+                av_assert0(0); //FIXME not implemented
             } else {
                 coefs += s->coefs_start;
                 n = nb_coefs[ch];
@@ -277,13 +273,13 @@
                 if (s->use_exp_vlc) {
                     encode_exp_vlc(s, ch, fixed_exp);
                 } else {
-                    assert(0); //FIXME not implemented
+                    av_assert0(0); //FIXME not implemented
 //                    encode_exp_lsp(s, ch);
                 }
             }
         }
     } else {
-        assert(0); //FIXME not implemented
+        av_assert0(0); //FIXME not implemented
     }
 
     for(ch = 0; ch < s->nb_channels; ch++) {
@@ -305,7 +301,7 @@
                             code= run + s->int_table[tindex][abs_level-1];
                     }
 
-                    assert(code < s->coef_vlcs[tindex]->n);
+                    av_assert2(code < s->coef_vlcs[tindex]->n);
                     put_bits(&s->pb, s->coef_vlcs[tindex]->huffbits[code], s->coef_vlcs[tindex]->huffcodes[code]);
 
                     if(code == 0){
@@ -335,7 +331,7 @@
     init_put_bits(&s->pb, buf, buf_size);
 
     if (s->use_bit_reservoir) {
-        assert(0);//FIXME not implemented
+        av_assert0(0);//FIXME not implemented
     }else{
         if(encode_block(s, src_coefs, total_gain) < 0)
             return INT_MAX;
@@ -350,7 +346,7 @@
                              const AVFrame *frame, int *got_packet_ptr)
 {
     WMACodecContext *s = avctx->priv_data;
-    int i, total_gain, ret;
+    int i, total_gain, ret, error;
 
     s->block_len_bits= s->frame_len_bits; //required by non variable block len
     s->block_len = 1 << s->block_len_bits;
@@ -369,46 +365,27 @@
         }
     }
 
-    if ((ret = ff_alloc_packet(avpkt, 2 * MAX_CODED_SUPERFRAME_SIZE))) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n");
+    if ((ret = ff_alloc_packet2(avctx, avpkt, 2 * MAX_CODED_SUPERFRAME_SIZE)))
         return ret;
-    }
 
-#if 1
     total_gain= 128;
     for(i=64; i; i>>=1){
-        int error = encode_frame(s, s->coefs, avpkt->data, avpkt->size,
+        error = encode_frame(s, s->coefs, avpkt->data, avpkt->size,
                                  total_gain - i);
-        if(error<0)
+        if(error<=0)
             total_gain-= i;
     }
-#else
-    total_gain= 90;
-    best = encode_frame(s, s->coefs, avpkt->data, avpkt->size, total_gain);
-    for(i=32; i; i>>=1){
-        int scoreL = encode_frame(s, s->coefs, avpkt->data, avpkt->size, total_gain - i);
-        int scoreR = encode_frame(s, s->coefs, avpkt->data, avpkt->size, total_gain + i);
-        av_log(NULL, AV_LOG_ERROR, "%d %d %d (%d)\n", scoreL, best, scoreR, total_gain);
-        if(scoreL < FFMIN(best, scoreR)){
-            best = scoreL;
-            total_gain -= i;
-        }else if(scoreR < best){
-            best = scoreR;
-            total_gain += i;
-        }
-    }
-#endif
 
-    if ((i = encode_frame(s, s->coefs, avpkt->data, avpkt->size, total_gain)) >= 0) {
-        av_log(avctx, AV_LOG_ERROR, "required frame size too large. please "
-               "use a higher bit rate.\n");
-        return AVERROR(EINVAL);
-    }
-    assert((put_bits_count(&s->pb) & 7) == 0);
-    while (i++)
+    while(total_gain <= 128 && error > 0)
+        error = encode_frame(s, s->coefs, avpkt->data, avpkt->size, total_gain++);
+    av_assert0((put_bits_count(&s->pb) & 7) == 0);
+    i= s->block_align - (put_bits_count(&s->pb)+7)/8;
+    av_assert0(i>=0);
+    while(i--)
         put_bits(&s->pb, 8, 'N');
 
     flush_put_bits(&s->pb);
+    av_assert0(put_bits_ptr(&s->pb) - s->pb.buf == s->block_align);
 
     if (frame->pts != AV_NOPTS_VALUE)
         avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->delay);
@@ -418,6 +395,7 @@
     return 0;
 }
 
+#if CONFIG_WMAV1_ENCODER
 AVCodec ff_wmav1_encoder = {
     .name           = "wmav1",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -430,7 +408,8 @@
                                                      AV_SAMPLE_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"),
 };
-
+#endif
+#if CONFIG_WMAV2_ENCODER
 AVCodec ff_wmav2_encoder = {
     .name           = "wmav2",
     .type           = AVMEDIA_TYPE_AUDIO,
@@ -443,3 +422,4 @@
                                                      AV_SAMPLE_FMT_NONE },
     .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"),
 };
+#endif
diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c
index df02528..7e09fd0 100644
--- a/libavcodec/wmalosslessdec.c
+++ b/libavcodec/wmalosslessdec.c
@@ -5,20 +5,20 @@
  * Copyright (c) 2011 Andreas Öman
  * Copyright (c) 2011 - 2012 Mashiat Sarker Shakkhar
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -500,9 +500,9 @@
 
     if (s->seekable_tile) {
         if (s->do_inter_ch_decorr)
-            s->channel_residues[ch][0] = get_sbits(&s->gb, s->bits_per_sample + 1);
+            s->channel_residues[ch][0] = get_sbits_long(&s->gb, s->bits_per_sample + 1);
         else
-            s->channel_residues[ch][0] = get_sbits(&s->gb, s->bits_per_sample);
+            s->channel_residues[ch][0] = get_sbits_long(&s->gb, s->bits_per_sample);
         i++;
     }
     for (; i < tile_size; i++) {
@@ -520,7 +520,7 @@
             residue = quo;
         else {
             rem_bits = av_ceil_log2(ave_mean);
-            rem      = rem_bits ? get_bits_long(&s->gb, rem_bits) : 0;
+            rem      = get_bits_long(&s->gb, rem_bits);
             residue  = (quo << rem_bits) + rem;
         }
 
@@ -950,7 +950,7 @@
                 bits * s->num_channels * subframe_len, get_bits_count(&s->gb));
         for (i = 0; i < s->num_channels; i++)
             for (j = 0; j < subframe_len; j++)
-                s->channel_coeffs[i][j] = get_sbits(&s->gb, bits);
+                s->channel_coeffs[i][j] = get_sbits_long(&s->gb, bits);
     } else {
         for (i = 0; i < s->num_channels; i++)
             if (s->is_channel_coded[i]) {
diff --git a/libavcodec/wmaprodata.h b/libavcodec/wmaprodata.h
index f8a52bf..5382479 100644
--- a/libavcodec/wmaprodata.h
+++ b/libavcodec/wmaprodata.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2007 Baptiste Coudurier, Benjamin Larsson, Ulion
  * Copyright (c) 2008 - 2009 Sascha Sommer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c
index 1c9c667..b70e1f5 100644
--- a/libavcodec/wmaprodec.c
+++ b/libavcodec/wmaprodec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2007 Baptiste Coudurier, Benjamin Larsson, Ulion
  * Copyright (c) 2008 - 2011 Sascha Sommer, Benjamin Larsson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -335,6 +335,12 @@
         return AVERROR_INVALIDDATA;
     }
 
+    if (s->min_samples_per_subframe < (1<<WMAPRO_BLOCK_MIN_BITS)) {
+        av_log(avctx, AV_LOG_ERROR, "min_samples_per_subframe of %d too small\n",
+               s->min_samples_per_subframe);
+        return AVERROR_INVALIDDATA;
+    }
+
     if (s->avctx->sample_rate <= 0) {
         av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n");
         return AVERROR_INVALIDDATA;
@@ -534,7 +540,7 @@
     int c;
 
     /* Should never consume more than 3073 bits (256 iterations for the
-     * while loop when always the minimum amount of 128 samples is substracted
+     * while loop when always the minimum amount of 128 samples is subtracted
      * from missing samples in the 8 channel case).
      * 1 + BLOCK_MAX_SIZE * MAX_CHANNELS / BLOCK_MIN_SIZE * (MAX_CHANNELS  + 4)
      */
@@ -1135,7 +1141,7 @@
         int num_fill_bits;
         if (!(num_fill_bits = get_bits(&s->gb, 2))) {
             int len = get_bits(&s->gb, 4);
-            num_fill_bits = get_bits(&s->gb, len) + 1;
+            num_fill_bits = (len ? get_bits(&s->gb, len) : 0) + 1;
         }
 
         if (num_fill_bits >= 0) {
@@ -1165,6 +1171,7 @@
             transmit_coeffs = 1;
     }
 
+    av_assert0(s->subframe_len <= WMAPRO_BLOCK_MAX_SIZE);
     if (transmit_coeffs) {
         int step;
         int quant_step = 90 * s->bits_per_sample >> 4;
@@ -1175,7 +1182,7 @@
             for (i = 0; i < s->channels_for_cur_subframe; i++) {
                 int c = s->channel_indexes_for_cur_subframe[i];
                 int num_vec_coeffs = get_bits(&s->gb, num_bits) << 2;
-                if (num_vec_coeffs > WMAPRO_BLOCK_MAX_SIZE) {
+                if (num_vec_coeffs > s->subframe_len) {
                     av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs);
                     return AVERROR_INVALIDDATA;
                 }
@@ -1447,7 +1454,7 @@
     int buflen;
 
     /** when the frame data does not need to be concatenated, the input buffer
-        is resetted and additional bits from the previous frame are copyed
+        is reset and additional bits from the previous frame are copied
         and skipped later so that a fast byte copy is possible */
 
     if (!append) {
@@ -1456,7 +1463,7 @@
         init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
     }
 
-    buflen = (s->num_saved_bits + len + 8) >> 3;
+    buflen = (put_bits_count(&s->pb) + len + 8) >> 3;
 
     if (len <= 0 || buflen > MAX_FRAMESIZE) {
         av_log_ask_for_sample(s->avctx, "input buffer too small\n");
diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c
index 4a7ba6d..0cf10da 100644
--- a/libavcodec/wmavoice.c
+++ b/libavcodec/wmavoice.c
@@ -2,20 +2,20 @@
  * Windows Media Audio Voice decoder.
  * Copyright (c) 2009 Ronald S. Bultje
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -515,7 +515,7 @@
     float optimal_gain = 0, dot;
     const float *ptr = &in[-FFMAX(s->min_pitch_val, pitch - 3)],
                 *end = &in[-FFMIN(s->max_pitch_val, pitch + 3)],
-                *best_hist_ptr;
+                *best_hist_ptr = NULL;
 
     /* find best fitting point in history */
     do {
@@ -774,7 +774,7 @@
           *synth_pf = &s->synth_filter_out_buf[MAX_LSPS_ALIGN16],
           *synth_filter_in = zero_exc_pf;
 
-    assert(size <= MAX_FRAMESIZE / 2);
+    av_assert0(size <= MAX_FRAMESIZE / 2);
 
     /* generate excitation from input signal */
     ff_celp_lp_zero_synthesis_filterf(zero_exc_pf, lpcs, synth, size, s->lsps);
@@ -1241,7 +1241,7 @@
     float gain;
     int n, r_idx;
 
-    assert(size <= MAX_FRAMESIZE);
+    av_assert0(size <= MAX_FRAMESIZE);
 
     /* Set the offset from which we start reading wmavoice_std_codebook */
     if (frame_desc->fcb_type == FCB_TYPE_SILENCE) {
@@ -1277,7 +1277,7 @@
     int n, idx, gain_weight;
     AMRFixed fcb;
 
-    assert(size <= MAX_FRAMESIZE / 2);
+    av_assert0(size <= MAX_FRAMESIZE / 2);
     memset(pulses, 0, sizeof(*pulses) * size);
 
     fcb.pitch_lag      = block_pitch_sh2 >> 2;
@@ -1654,7 +1654,7 @@
     /* initialize a copy */
     init_get_bits(gb, orig_gb->buffer, orig_gb->size_in_bits);
     skip_bits_long(gb, get_bits_count(orig_gb));
-    assert(get_bits_left(gb) == get_bits_left(orig_gb));
+    av_assert1(get_bits_left(gb) == get_bits_left(orig_gb));
 
     /* superframe header */
     if (get_bits_left(gb) < 14)
@@ -1933,7 +1933,7 @@
     int size, res, pos;
 
     /* Packets are sometimes a multiple of ctx->block_align, with a packet
-     * header at each ctx->block_align bytes. However, Libav's ASF demuxer
+     * header at each ctx->block_align bytes. However, FFmpeg's ASF demuxer
      * feeds us ASF packets, which may concatenate multiple "codec" packets
      * in a single "muxer" packet, so we artificially emulate that by
      * capping the packet size at ctx->block_align. */
@@ -1990,7 +1990,7 @@
         /* rewind bit reader to start of last (incomplete) superframe... */
         init_get_bits(gb, avpkt->data, size << 3);
         skip_bits_long(gb, (size << 3) - pos);
-        assert(get_bits_left(gb) == pos);
+        av_assert1(get_bits_left(gb) == pos);
 
         /* ...and cache it for spillover in next packet */
         init_put_bits(&s->pb, s->sframe_cache, SFRAME_CACHE_MAXSIZE);
diff --git a/libavcodec/wmavoice_data.h b/libavcodec/wmavoice_data.h
index 7f14fb8..cbf65b0 100644
--- a/libavcodec/wmavoice_data.h
+++ b/libavcodec/wmavoice_data.h
@@ -2,20 +2,20 @@
  * Windows Media Voice (WMAVoice) tables.
  * Copyright (c) 2009 Ronald S. Bultje
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/wmv2.c b/libavcodec/wmv2.c
index f113790..621b6be 100644
--- a/libavcodec/wmv2.c
+++ b/libavcodec/wmv2.c
@@ -1,20 +1,20 @@
 /*
- * Copyright (c) 2002 The Libav Project
+ * Copyright (c) 2002 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/wmv2.h b/libavcodec/wmv2.h
index 80f36cc..c69c9f4 100644
--- a/libavcodec/wmv2.h
+++ b/libavcodec/wmv2.h
@@ -1,20 +1,20 @@
 /*
- * Copyright (c) 2002 The Libav Project
+ * Copyright (c) 2002 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/wmv2dec.c b/libavcodec/wmv2dec.c
index c1fd4ee..df11c21 100644
--- a/libavcodec/wmv2dec.c
+++ b/libavcodec/wmv2dec.c
@@ -1,20 +1,20 @@
 /*
- * Copyright (c) 2002 The Libav Project
+ * Copyright (c) 2002 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c
index 4643835..e6e1e67 100644
--- a/libavcodec/wmv2enc.c
+++ b/libavcodec/wmv2enc.c
@@ -1,20 +1,20 @@
 /*
- * Copyright (c) 2002 The Libav Project
+ * Copyright (c) 2002 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -85,10 +85,10 @@
     w->abt_type=0;
     w->j_type=0;
 
-    assert(s->flipflop_rounding);
+    av_assert0(s->flipflop_rounding);
 
     if (s->pict_type == AV_PICTURE_TYPE_I) {
-        assert(s->no_rounding==1);
+        av_assert0(s->no_rounding==1);
         if(w->j_type_bit) put_bits(&s->pb, 1, w->j_type);
 
         if(w->per_mb_rl_bit) put_bits(&s->pb, 1, s->per_mb_rl_table);
diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c
index 3abbce2..22a570c 100644
--- a/libavcodec/wnv1.c
+++ b/libavcodec/wnv1.c
@@ -2,20 +2,20 @@
  * Winnov WNV1 codec
  * Copyright (c) 2005 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -70,6 +70,11 @@
     int prev_y = 0, prev_u = 0, prev_v = 0;
     uint8_t *rbuf;
 
+    if(buf_size<=8) {
+        av_log(avctx, AV_LOG_ERROR, "buf_size %d is too small\n", buf_size);
+        return AVERROR_INVALIDDATA;
+    }
+
     rbuf = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
     if(!rbuf){
         av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
@@ -136,6 +141,7 @@
 
     l->avctx = avctx;
     avctx->pix_fmt = AV_PIX_FMT_YUV422P;
+    avcodec_get_frame_defaults(&l->pic);
 
     code_vlc.table = code_table;
     code_vlc.table_allocated = 1 << CODE_VLC_BITS;
diff --git a/libavcodec/ws-snd1.c b/libavcodec/ws-snd1.c
index 880ae85..dfa02b6 100644
--- a/libavcodec/ws-snd1.c
+++ b/libavcodec/ws-snd1.c
@@ -2,20 +2,20 @@
  * Westwood SNDx codecs
  * Copyright (c) 2005 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile
index 053290b..4ddd06d 100644
--- a/libavcodec/x86/Makefile
+++ b/libavcodec/x86/Makefile
@@ -5,6 +5,7 @@
 OBJS-$(CONFIG_CAVS_DECODER)            += x86/cavsdsp.o
 OBJS-$(CONFIG_DNXHD_ENCODER)           += x86/dnxhdenc.o
 OBJS-$(CONFIG_FFT)                     += x86/fft_init.o
+OBJS-$(CONFIG_GPL)                     += x86/idct_mmx.o
 OBJS-$(CONFIG_H264DSP)                 += x86/h264dsp_init.o
 OBJS-$(CONFIG_H264PRED)                += x86/h264_intrapred_init.o
 OBJS-$(CONFIG_LPC)                     += x86/lpc.o
@@ -13,10 +14,11 @@
 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            \
                                           x86/rv40dsp_init.o
+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_VP3DSP)                  += x86/vp3dsp_init.o
@@ -31,7 +33,8 @@
                                           x86/idct_sse2_xvid.o          \
                                           x86/simple_idct.o             \
 
-MMX-OBJS-$(CONFIG_DWT)                 += x86/snowdsp.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_VC1_DECODER)         += x86/vc1dsp_mmx.o
@@ -39,6 +42,8 @@
 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_ENCODERS)           += x86/dsputilenc.o
 YASM-OBJS-$(CONFIG_FFT)                += x86/fft.o
 YASM-OBJS-$(CONFIG_H264CHROMA)         += x86/h264_chromamc.o           \
@@ -55,9 +60,11 @@
 YASM-OBJS-$(CONFIG_MPEGAUDIODSP)       += x86/imdct36.o
 YASM-OBJS-$(CONFIG_PNG_DECODER)        += x86/pngdsp.o
 YASM-OBJS-$(CONFIG_PRORES_DECODER)     += x86/proresdsp.o
+YASM-OBJS-$(CONFIG_PRORES_LGPL_DECODER) += x86/proresdsp.o
 YASM-OBJS-$(CONFIG_RV30_DECODER)       += x86/rv34dsp.o
 YASM-OBJS-$(CONFIG_RV40_DECODER)       += x86/rv34dsp.o                 \
                                           x86/rv40dsp.o
+YASM-OBJS-$(CONFIG_V210_DECODER)       += x86/v210.o
 YASM-OBJS-$(CONFIG_VC1_DECODER)        += x86/vc1dsp.o
 YASM-OBJS-$(CONFIG_VP3DSP)             += x86/vp3dsp.o
 YASM-OBJS-$(CONFIG_VP6_DECODER)        += x86/vp56dsp.o
diff --git a/libavcodec/x86/ac3dsp.asm b/libavcodec/x86/ac3dsp.asm
index 176fd3d..b085eae 100644
--- a/libavcodec/x86/ac3dsp.asm
+++ b/libavcodec/x86/ac3dsp.asm
@@ -2,25 +2,25 @@
 ;* x86-optimized AC-3 DSP utils
 ;* Copyright (c) 2011 Justin Ruggles
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 SECTION_RODATA
 
@@ -68,7 +68,7 @@
 %define LOOP_ALIGN
 INIT_MMX
 AC3_EXPONENT_MIN mmx
-%if HAVE_MMXEXT
+%if HAVE_MMXEXT_EXTERNAL
 %define PMINUB PMINUB_MMXEXT
 %define LOOP_ALIGN ALIGN 16
 AC3_EXPONENT_MIN mmxext
diff --git a/libavcodec/x86/ac3dsp_init.c b/libavcodec/x86/ac3dsp_init.c
index 5008d65..b1e8cfb 100644
--- a/libavcodec/x86/ac3dsp_init.c
+++ b/libavcodec/x86/ac3dsp_init.c
@@ -2,20 +2,20 @@
  * x86-optimized AC-3 DSP utils
  * Copyright (c) 2011 Justin Ruggles
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/cabac.h b/libavcodec/x86/cabac.h
index a74cf0b..35f4ca7 100644
--- a/libavcodec/x86/cabac.h
+++ b/libavcodec/x86/cabac.h
@@ -73,10 +73,7 @@
         "test   "lowword"   , "lowword"                                 \n\t"\
         "jnz    2f                                                      \n\t"\
         "mov    "byte"      , %%"REG_c"                                 \n\t"\
-        "cmp    "end"       , %%"REG_c"                                 \n\t"\
-        "jge    1f                                                      \n\t"\
         "add"OPSIZE" $2     , "byte"                                    \n\t"\
-        "1:                                                             \n\t"\
         "movzwl (%%"REG_c") , "tmp"                                     \n\t"\
         "lea    -1("low")   , %%ecx                                     \n\t"\
         "xor    "low"       , %%ecx                                     \n\t"\
@@ -93,6 +90,7 @@
 
 #else /* BROKEN_RELOCATIONS */
 #define TABLES_ARG
+#define RIP_ARG
 
 #if HAVE_FAST_CMOV
 #define BRANCHLESS_GET_CABAC_UPDATE(ret, low, range, tmp)\
@@ -134,10 +132,7 @@
         "test   "lowword"   , "lowword"                                 \n\t"\
         " jnz   2f                                                      \n\t"\
         "mov    "byte"      , %%"REG_c"                                 \n\t"\
-        "cmp    "end"       , %%"REG_c"                                 \n\t"\
-        "jge    1f                                                      \n\t"\
         "add"OPSIZE" $2     , "byte"                                    \n\t"\
-        "1:                                                             \n\t"\
         "movzwl (%%"REG_c")     , "tmp"                                 \n\t"\
         "lea    -1("low")   , %%ecx                                     \n\t"\
         "xor    "low"       , %%ecx                                     \n\t"\
@@ -155,7 +150,8 @@
 #endif /* BROKEN_RELOCATIONS */
 
 
-#if HAVE_7REGS
+#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)
 #define get_cabac_inline get_cabac_inline_x86
 static av_always_inline int get_cabac_inline_x86(CABACContext *c,
                                                  uint8_t *const state)
@@ -178,11 +174,12 @@
                              AV_STRINGIFY(H264_LPS_RANGE_OFFSET),
                              AV_STRINGIFY(H264_MLPS_STATE_OFFSET),
                              "%8")
-        : "=&r"(bit), "+&r"(c->low), "+&r"(c->range), "=&q"(tmp)
+        : "=&r"(bit), "=&r"(c->low), "=&r"(c->range), "=&q"(tmp)
         : "r"(state), "r"(c),
           "i"(offsetof(CABACContext, bytestream)),
           "i"(offsetof(CABACContext, bytestream_end))
           TABLES_ARG
+          ,"1"(c->low), "2"(c->range)
         : "%"REG_c, "memory"
     );
     return bit & 1;
@@ -211,10 +208,9 @@
         "movzwl         (%1), %%edx     \n\t"
         "bswap         %%edx            \n\t"
         "shrl            $15, %%edx     \n\t"
+        "add              $2, %1        \n\t"
         "addl          %%edx, %%eax     \n\t"
-        "cmp         %c5(%2), %1        \n\t"
-        "jge              1f            \n\t"
-        "add"OPSIZE"      $2, %c4(%2)   \n\t"
+        "mov              %1, %c4(%2)   \n\t"
         "1:                             \n\t"
         "movl          %%eax, %c3(%2)   \n\t"
 
diff --git a/libavcodec/x86/cavsdsp.c b/libavcodec/x86/cavsdsp.c
index 5350f7e..9643b81 100644
--- a/libavcodec/x86/cavsdsp.c
+++ b/libavcodec/x86/cavsdsp.c
@@ -5,20 +5,20 @@
  * MMX-optimized DSP functions, based on H.264 optimizations by
  * Michael Niedermayer and Loren Merritt
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/dct32.asm b/libavcodec/x86/dct32.asm
index 58ee8d3..91ea493 100644
--- a/libavcodec/x86/dct32.asm
+++ b/libavcodec/x86/dct32.asm
@@ -2,25 +2,25 @@
 ;* 32 point SSE-optimized DCT transform
 ;* Copyright (c) 2010 Vitor Sessak
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 SECTION_RODATA 32
 
diff --git a/libavcodec/x86/deinterlace.asm b/libavcodec/x86/deinterlace.asm
index 8681181..bcc275b 100644
--- a/libavcodec/x86/deinterlace.asm
+++ b/libavcodec/x86/deinterlace.asm
@@ -3,25 +3,25 @@
 ;* Copyright (c) 2010 Vitor Sessak
 ;* Copyright (c) 2002 Michael Niedermayer
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 SECTION_RODATA
 
diff --git a/libavcodec/x86/diracdsp_mmx.c b/libavcodec/x86/diracdsp_mmx.c
new file mode 100644
index 0000000..2a040da
--- /dev/null
+++ b/libavcodec/x86/diracdsp_mmx.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2010 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 "dsputil_mmx.h"
+#include "diracdsp_mmx.h"
+
+void ff_put_rect_clamped_mmx(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height);
+void ff_put_rect_clamped_sse2(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height);
+void ff_put_signed_rect_clamped_mmx(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height);
+void ff_put_signed_rect_clamped_sse2(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height);
+
+#define HPEL_FILTER(MMSIZE, EXT)                                                             \
+    void ff_dirac_hpel_filter_v_ ## EXT(uint8_t *, const uint8_t *, int, int);               \
+    void ff_dirac_hpel_filter_h_ ## EXT(uint8_t *, const uint8_t *, int);                    \
+                                                                                             \
+    static void dirac_hpel_filter_ ## EXT(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc,       \
+                                          const uint8_t *src, int stride, int width, int height)   \
+    {                                                                                        \
+        while( height-- )                                                                    \
+        {                                                                                    \
+            ff_dirac_hpel_filter_v_ ## EXT(dstv-MMSIZE, src-MMSIZE, stride, width+MMSIZE+5); \
+            ff_dirac_hpel_filter_h_ ## EXT(dsth, src, width);                                \
+            ff_dirac_hpel_filter_h_ ## EXT(dstc, dstv, width);                               \
+                                                                                             \
+            dsth += stride;                                                                  \
+            dstv += stride;                                                                  \
+            dstc += stride;                                                                  \
+            src  += stride;                                                                  \
+        }                                                                                    \
+    }
+
+#if !ARCH_X86_64
+HPEL_FILTER(8, mmx)
+#endif
+HPEL_FILTER(16, sse2)
+
+#define PIXFUNC(PFX, IDX, EXT)                                                   \
+    /*MMXDISABLEDc->PFX ## _dirac_pixels_tab[0][IDX] = ff_ ## PFX ## _dirac_pixels8_ ## EXT;*/  \
+    c->PFX ## _dirac_pixels_tab[1][IDX] = ff_ ## PFX ## _dirac_pixels16_ ## EXT; \
+    c->PFX ## _dirac_pixels_tab[2][IDX] = ff_ ## PFX ## _dirac_pixels32_ ## EXT
+
+void ff_diracdsp_init_mmx(DiracDSPContext* c)
+{
+    int mm_flags = av_get_cpu_flags();
+
+#if HAVE_YASM
+    c->add_dirac_obmc[0] = ff_add_dirac_obmc8_mmx;
+#if !ARCH_X86_64
+    c->add_dirac_obmc[1] = ff_add_dirac_obmc16_mmx;
+    c->add_dirac_obmc[2] = ff_add_dirac_obmc32_mmx;
+    c->dirac_hpel_filter = dirac_hpel_filter_mmx;
+    c->add_rect_clamped = ff_add_rect_clamped_mmx;
+    c->put_signed_rect_clamped = ff_put_signed_rect_clamped_mmx;
+#endif
+#endif
+
+#if HAVE_MMX_INLINE
+    PIXFUNC(put, 0, mmx);
+    PIXFUNC(avg, 0, mmx);
+#endif
+
+#if HAVE_MMXEXT_INLINE
+    if (mm_flags & AV_CPU_FLAG_MMX2) {
+        PIXFUNC(avg, 0, mmx2);
+    }
+#endif
+
+    if (mm_flags & AV_CPU_FLAG_SSE2) {
+#if HAVE_YASM
+        c->dirac_hpel_filter = dirac_hpel_filter_sse2;
+        c->add_rect_clamped = ff_add_rect_clamped_sse2;
+        c->put_signed_rect_clamped = ff_put_signed_rect_clamped_sse2;
+
+        c->add_dirac_obmc[1] = ff_add_dirac_obmc16_sse2;
+        c->add_dirac_obmc[2] = ff_add_dirac_obmc32_sse2;
+#endif
+#if HAVE_SSE2_INLINE
+        c->put_dirac_pixels_tab[1][0] = ff_put_dirac_pixels16_sse2;
+        c->avg_dirac_pixels_tab[1][0] = ff_avg_dirac_pixels16_sse2;
+        c->put_dirac_pixels_tab[2][0] = ff_put_dirac_pixels32_sse2;
+        c->avg_dirac_pixels_tab[2][0] = ff_avg_dirac_pixels32_sse2;
+#endif
+    }
+}
diff --git a/libavcodec/x86/diracdsp_mmx.h b/libavcodec/x86/diracdsp_mmx.h
new file mode 100644
index 0000000..3d8e117
--- /dev/null
+++ b/libavcodec/x86/diracdsp_mmx.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2010 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
+ */
+
+#ifndef AVCODEC_X86_DIRACDSP_H
+#define AVCODEC_X86_DIRACDSP_H
+
+#include "libavcodec/diracdsp.h"
+
+void ff_diracdsp_init_mmx(DiracDSPContext* c);
+
+DECL_DIRAC_PIXOP(put, mmx);
+DECL_DIRAC_PIXOP(avg, mmx);
+DECL_DIRAC_PIXOP(avg, mmx2);
+
+void ff_put_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h);
+void ff_avg_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h);
+void ff_put_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h);
+void ff_avg_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h);
+
+void ff_add_rect_clamped_mmx(uint8_t *, const uint16_t *, int, const int16_t *, int, int, int);
+void ff_add_rect_clamped_sse2(uint8_t *, const uint16_t *, int, const int16_t *, int, int, int);
+
+void ff_add_dirac_obmc8_mmx(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen);
+void ff_add_dirac_obmc16_mmx(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen);
+void ff_add_dirac_obmc32_mmx(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen);
+
+void ff_add_dirac_obmc16_sse2(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen);
+void ff_add_dirac_obmc32_sse2(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen);
+
+#endif
diff --git a/libavcodec/x86/diracdsp_yasm.asm b/libavcodec/x86/diracdsp_yasm.asm
new file mode 100644
index 0000000..f5f32b3
--- /dev/null
+++ b/libavcodec/x86/diracdsp_yasm.asm
@@ -0,0 +1,260 @@
+;******************************************************************************
+;* Copyright (c) 2010 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
+;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "x86inc.asm"
+
+SECTION_RODATA
+pw_3: times 8 dw 3
+pw_7: times 8 dw 7
+pw_16: times 8 dw 16
+pw_32: times 8 dw 32
+pb_128: times 16 db 128
+
+section .text
+
+%macro UNPACK_ADD 6
+    mov%5   %1, %3
+    mov%6   m5, %4
+    mova    m4, %1
+    mova    %2, m5
+    punpcklbw %1, m7
+    punpcklbw m5, m7
+    punpckhbw m4, m7
+    punpckhbw %2, m7
+    paddw   %1, m5
+    paddw   %2, m4
+%endmacro
+
+%macro HPEL_FILTER 1
+; dirac_hpel_filter_v_sse2(uint8_t *dst, uint8_t *src, int stride, int width);
+cglobal dirac_hpel_filter_v_%1, 4,6,8, dst, src, stride, width, src0, stridex3
+    mov     src0q, srcq
+    lea     stridex3q, [3*strideq]
+    sub     src0q, stridex3q
+    pxor    m7, m7
+.loop:
+    ; 7*(src[0] + src[1])
+    UNPACK_ADD m0, m1, [srcq], [srcq + strideq], a,a
+    pmullw  m0, [pw_7]
+    pmullw  m1, [pw_7]
+
+    ; 3*( ... + src[-2] + src[3])
+    UNPACK_ADD m2, m3, [src0q + strideq], [srcq + stridex3q], a,a
+    paddw   m0, m2
+    paddw   m1, m3
+    pmullw  m0, [pw_3]
+    pmullw  m1, [pw_3]
+
+    ; ... - 7*(src[-1] + src[2])
+    UNPACK_ADD m2, m3, [src0q + strideq*2], [srcq + strideq*2], a,a
+    pmullw  m2, [pw_7]
+    pmullw  m3, [pw_7]
+    psubw   m0, m2
+    psubw   m1, m3
+
+    ; ... - (src[-3] + src[4])
+    UNPACK_ADD m2, m3, [src0q], [srcq + strideq*4], a,a
+    psubw   m0, m2
+    psubw   m1, m3
+
+    paddw   m0, [pw_16]
+    paddw   m1, [pw_16]
+    psraw   m0, 5
+    psraw   m1, 5
+    packuswb m0, m1
+    mova    [dstq], m0
+    add     dstq, mmsize
+    add     srcq, mmsize
+    add     src0q, mmsize
+    sub     widthd, mmsize
+    jg      .loop
+    RET
+
+; dirac_hpel_filter_h_sse2(uint8_t *dst, uint8_t *src, int width);
+cglobal dirac_hpel_filter_h_%1, 3,3,8, dst, src, width
+    dec     widthd
+    pxor    m7, m7
+    and     widthd, ~(mmsize-1)
+.loop:
+    ; 7*(src[0] + src[1])
+    UNPACK_ADD m0, m1, [srcq + widthq], [srcq + widthq + 1], u,u
+    pmullw  m0, [pw_7]
+    pmullw  m1, [pw_7]
+
+    ; 3*( ... + src[-2] + src[3])
+    UNPACK_ADD m2, m3, [srcq + widthq - 2], [srcq + widthq + 3], u,u
+    paddw   m0, m2
+    paddw   m1, m3
+    pmullw  m0, [pw_3]
+    pmullw  m1, [pw_3]
+
+    ; ... - 7*(src[-1] + src[2])
+    UNPACK_ADD m2, m3, [srcq + widthq - 1], [srcq + widthq + 2], u,u
+    pmullw  m2, [pw_7]
+    pmullw  m3, [pw_7]
+    psubw   m0, m2
+    psubw   m1, m3
+
+    ; ... - (src[-3] + src[4])
+    UNPACK_ADD m2, m3, [srcq + widthq - 3], [srcq + widthq + 4], u,u
+    psubw   m0, m2
+    psubw   m1, m3
+
+    paddw   m0, [pw_16]
+    paddw   m1, [pw_16]
+    psraw   m0, 5
+    psraw   m1, 5
+    packuswb m0, m1
+    mova    [dstq + widthq], m0
+    sub     widthd, mmsize
+    jge     .loop
+    RET
+%endmacro
+
+%macro PUT_RECT 1
+; void put_rect_clamped(uint8_t *dst, int dst_stride, int16_t *src, int src_stride, int width, int height)
+cglobal put_signed_rect_clamped_%1, 5,9,3, dst, dst_stride, src, src_stride, w, dst2, src2
+    mova    m0, [pb_128]
+    add     wd, (mmsize-1)
+    and     wd, ~(mmsize-1)
+
+%if ARCH_X86_64
+    mov   r7d, r5m
+    mov   r8d, wd
+    %define wspill r8d
+    %define hd r7d
+%else
+    mov    r4m, wd
+    %define wspill r4m
+    %define hd r5mp
+%endif
+
+.loopy
+    lea     src2q, [srcq+src_strideq*2]
+    lea     dst2q, [dstq+dst_strideq]
+.loopx:
+    sub      wd, mmsize
+    mova     m1, [srcq +2*wq]
+    mova     m2, [src2q+2*wq]
+    packsswb m1, [srcq +2*wq+mmsize]
+    packsswb m2, [src2q+2*wq+mmsize]
+    paddb    m1, m0
+    paddb    m2, m0
+    mova    [dstq +wq], m1
+    mova    [dst2q+wq], m2
+    jg      .loopx
+
+    lea   srcq, [srcq+src_strideq*4]
+    lea   dstq, [dstq+dst_strideq*2]
+    sub     hd, 2
+    mov     wd, wspill
+    jg      .loopy
+    RET
+%endm
+
+%macro ADD_RECT 1
+; void add_rect_clamped(uint8_t *dst, uint16_t *src, int stride, int16_t *idwt, int idwt_stride, int width, int height)
+cglobal add_rect_clamped_%1, 7,9,3, dst, src, stride, idwt, idwt_stride, w, h
+    mova    m0, [pw_32]
+    add     wd, (mmsize-1)
+    and     wd, ~(mmsize-1)
+
+%if ARCH_X86_64
+    mov   r8d, wd
+    %define wspill r8d
+%else
+    mov    r5m, wd
+    %define wspill r5m
+%endif
+
+.loop:
+    sub     wd, mmsize
+    movu    m1, [srcq +2*wq] ; FIXME: ensure alignment
+    paddw   m1, m0
+    psraw   m1, 6
+    movu    m2, [srcq +2*wq+mmsize] ; FIXME: ensure alignment
+    paddw   m2, m0
+    psraw   m2, 6
+    paddw   m1, [idwtq+2*wq]
+    paddw   m2, [idwtq+2*wq+mmsize]
+    packuswb m1, m2
+    mova    [dstq +wq], m1
+    jg      .loop
+
+    lea   srcq, [srcq + 2*strideq]
+    add   dstq, strideq
+    lea  idwtq, [idwtq+ 2*idwt_strideq]
+    sub     hd, 1
+    mov     wd, wspill
+    jg      .loop
+    RET
+%endm
+
+%macro ADD_OBMC 2
+; void add_obmc(uint16_t *dst, uint8_t *src, int stride, uint8_t *obmc_weight, int yblen)
+cglobal add_dirac_obmc%1_%2, 6,6,5, dst, src, stride, obmc, yblen
+    pxor        m4, m4
+.loop:
+%assign i 0
+%rep %1 / mmsize
+    mova        m0, [srcq+i]
+    mova        m1, m0
+    punpcklbw   m0, m4
+    punpckhbw   m1, m4
+    mova        m2, [obmcq+i]
+    mova        m3, m2
+   punpcklbw   m2, m4
+    punpckhbw   m3, m4
+    pmullw      m0, m2
+    pmullw      m1, m3
+    movu        m2, [dstq+2*i]
+    movu        m3, [dstq+2*i+mmsize]
+    paddw       m0, m2
+    paddw       m1, m3
+    movu        [dstq+2*i], m0
+    movu        [dstq+2*i+mmsize], m1
+%assign i i+mmsize
+%endrep
+    lea         srcq, [srcq+strideq]
+    lea         dstq, [dstq+2*strideq]
+    add         obmcq, 32
+    sub         yblend, 1
+    jg          .loop
+    RET
+%endm
+
+INIT_MMX
+%if ARCH_X86_64 == 0
+PUT_RECT mmx
+ADD_RECT mmx
+
+HPEL_FILTER mmx
+ADD_OBMC 32, mmx
+ADD_OBMC 16, mmx
+%endif
+ADD_OBMC 8, mmx
+
+INIT_XMM
+PUT_RECT sse2
+ADD_RECT sse2
+
+HPEL_FILTER sse2
+ADD_OBMC 32, sse2
+ADD_OBMC 16, sse2
diff --git a/libavcodec/x86/dnxhdenc.c b/libavcodec/x86/dnxhdenc.c
index 43ee246..b2ba894 100644
--- a/libavcodec/x86/dnxhdenc.c
+++ b/libavcodec/x86/dnxhdenc.c
@@ -4,20 +4,20 @@
  *
  * VC-3 encoder funded by the British Broadcasting Corporation
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/dsputil.asm b/libavcodec/x86/dsputil.asm
index fcb1b6d..af7669a 100644
--- a/libavcodec/x86/dsputil.asm
+++ b/libavcodec/x86/dsputil.asm
@@ -2,24 +2,24 @@
 ;* MMX optimized DSP utils
 ;* Copyright (c) 2008 Loren Merritt
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
+%include "libavutil/x86/x86inc.asm"
 %include "x86util.asm"
 
 SECTION_RODATA
@@ -1371,3 +1371,4 @@
     mov      [r0], r2d
 .end:
     RET
+
diff --git a/libavcodec/x86/dsputil_avg_template.c b/libavcodec/x86/dsputil_avg_template.c
index 8b116b7..6f76859 100644
--- a/libavcodec/x86/dsputil_avg_template.c
+++ b/libavcodec/x86/dsputil_avg_template.c
@@ -7,20 +7,20 @@
  * mostly rewritten by Michael Niedermayer <michaelni@gmx.at>
  * and improved by Zdenek Kabelac <kabi@users.sf.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c
index 86a08cb..85c88f8 100644
--- a/libavcodec/x86/dsputil_mmx.c
+++ b/libavcodec/x86/dsputil_mmx.c
@@ -3,23 +3,23 @@
  * Copyright (c) 2000, 2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
+ * This file is part of FFmpeg.
  *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
  */
 
 #include "libavutil/cpu.h"
@@ -30,6 +30,7 @@
 #include "libavcodec/simple_idct.h"
 #include "dsputil_mmx.h"
 #include "idct_xvid.h"
+#include "diracdsp_mmx.h"
 
 //#undef NDEBUG
 //#include <assert.h>
@@ -835,7 +836,7 @@
             : "+r"(ptr)
             : "r"((x86_reg)wrap), "r"((x86_reg)width), "r"(ptr + wrap * height)
             );
-    } else {
+    } else if(w==16){
         __asm__ volatile (
             "1:                                 \n\t"
             "movd            (%0), %%mm0        \n\t"
@@ -856,6 +857,25 @@
             : "+r"(ptr)
             : "r"((x86_reg)wrap), "r"((x86_reg)width), "r"(ptr + wrap * height)
             );
+    } else {
+        av_assert1(w == 4);
+        __asm__ volatile (
+            "1:                             \n\t"
+            "movd            (%0), %%mm0    \n\t"
+            "punpcklbw      %%mm0, %%mm0    \n\t"
+            "punpcklwd      %%mm0, %%mm0    \n\t"
+            "movd           %%mm0, -4(%0)   \n\t"
+            "movd      -4(%0, %2), %%mm1    \n\t"
+            "punpcklbw      %%mm1, %%mm1    \n\t"
+            "punpckhwd      %%mm1, %%mm1    \n\t"
+            "punpckhdq      %%mm1, %%mm1    \n\t"
+            "movd           %%mm1, (%0, %2) \n\t"
+            "add               %1, %0       \n\t"
+            "cmp               %3, %0       \n\t"
+            "jb                1b           \n\t"
+            : "+r"(ptr)
+            : "r"((x86_reg)wrap), "r"((x86_reg)width), "r"(ptr + wrap * height)
+            );
     }
 
     /* top and bottom (and hopefully also the corners) */
@@ -1876,8 +1896,8 @@
     start_x = FFMAX(0, -src_x);
     end_y   = FFMIN(block_h, h-src_y);
     end_x   = FFMIN(block_w, w-src_x);
-    assert(start_x < end_x && block_w > 0);
-    assert(start_y < end_y && block_h > 0);
+    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;
@@ -1909,10 +1929,15 @@
 
 #if HAVE_INLINE_ASM
 
-static void gmc_mmx(uint8_t *dst, uint8_t *src,
-                    int stride, int h, int ox, int oy,
-                    int dxx, int dxy, int dyx, int dyy,
-                    int shift, int r, int width, int height)
+typedef void emulated_edge_mc_func(uint8_t *dst, const uint8_t *src,
+                                   int 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,
+                                 int stride, int h, int ox, int oy,
+                                 int dxx, int dxy, int dyx, int dyy,
+                                 int shift, int r, int width, int height,
+                                 emulated_edge_mc_func *emu_edge_fn)
 {
     const int w    = 8;
     const int ix   = ox  >> (16 + shift);
@@ -1927,19 +1952,24 @@
     const uint16_t dxy4[4] = { dxys, dxys, dxys, dxys };
     const uint16_t dyy4[4] = { dyys, dyys, dyys, dyys };
     const uint64_t shift2 = 2 * shift;
+#define MAX_STRIDE 4096U
+#define MAX_H 8U
+    uint8_t edge_buf[(MAX_H + 1) * MAX_STRIDE];
     int x, y;
 
     const int dxw = (dxx - (1 << (16 + shift))) * (w - 1);
     const int dyh = (dyy - (1 << (16 + shift))) * (h - 1);
     const int dxh = dxy * (h - 1);
     const int dyw = dyx * (w - 1);
+    int need_emu =  (unsigned)ix >= width  - w ||
+                    (unsigned)iy >= height - h;
+
     if ( // non-constant fullpel offset (3% of blocks)
         ((ox ^ (ox + dxw)) | (ox ^ (ox + dxh)) | (ox ^ (ox + dxw + dxh)) |
          (oy ^ (oy + dyw)) | (oy ^ (oy + dyh)) | (oy ^ (oy + dyw + dyh))) >> (16 + shift)
         // uses more than 16 bits of subpel mv (only at huge resolution)
-        || (dxx | dxy | dyx | dyy) & 15 ||
-        (unsigned)ix >= width  - w ||
-        (unsigned)iy >= height - h) {
+        || (dxx | dxy | dyx | dyy) & 15
+        || (need_emu && (h > MAX_H || stride > MAX_STRIDE))) {
         // FIXME could still use mmx for some of the rows
         ff_gmc_c(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy,
                  shift, r, width, height);
@@ -1947,6 +1977,10 @@
     }
 
     src += ix + iy * stride;
+    if (need_emu) {
+        emu_edge_fn(edge_buf, src, stride, w + 1, h + 1, ix, iy, width, height);
+        src = edge_buf;
+    }
 
     __asm__ volatile (
         "movd         %0, %%mm6         \n\t"
@@ -2025,6 +2059,36 @@
     }
 }
 
+#if HAVE_YASM
+#if ARCH_X86_32
+static void gmc_mmx(uint8_t *dst, uint8_t *src,
+                    int stride, int h, int ox, int oy,
+                    int dxx, int dxy, int dyx, int dyy,
+                    int shift, int r, int width, int height)
+{
+    gmc(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r,
+        width, height, &emulated_edge_mc_mmx);
+}
+#endif
+static void gmc_sse(uint8_t *dst, uint8_t *src,
+                    int stride, int h, int ox, int oy,
+                    int dxx, int dxy, int dyx, int dyy,
+                    int shift, int r, int width, int height)
+{
+    gmc(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r,
+        width, height, &emulated_edge_mc_sse);
+}
+#else
+static void gmc_mmx(uint8_t *dst, uint8_t *src,
+                    int stride, int h, int ox, int oy,
+                    int dxx, int dxy, int dyx, int dyy,
+                    int shift, int r, int width, int height)
+{
+    gmc(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r,
+        width, height, &ff_emulated_edge_mc_8);
+}
+#endif
+
 #define PREFETCH(name, op)                      \
 static void name(void *mem, int stride, int h)  \
 {                                               \
@@ -2122,6 +2186,116 @@
     avg_pixels8_mmx2(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)\
+{\
+    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)\
+{\
+    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)\
+{\
+    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, mmx2)
+
+void ff_put_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h)
+{
+    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)
+{
+    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)
+{
+    put_pixels16_sse2(dst   , src[0]   , stride, h);
+    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)
+{
+    avg_pixels16_sse2(dst   , src[0]   , stride, h);
+    avg_pixels16_sse2(dst+16, src[0]+16, stride, h);
+}
+#endif
+
+/* XXX: Those functions should be suppressed ASAP when all IDCTs are
+ * converted. */
+#if CONFIG_GPL
+static void ff_libmpeg2mmx_idct_put(uint8_t *dest, int line_size,
+                                    DCTELEM *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)
+{
+    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)
+{
+    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)
+{
+    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;
@@ -2413,27 +2587,17 @@
         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);
-
-        switch (avctx->idct_algo) {
-        case FF_IDCT_AUTO:
-        case FF_IDCT_SIMPLEMMX:
-            c->idct_put              = ff_simple_idct_put_mmx;
-            c->idct_add              = ff_simple_idct_add_mmx;
-            c->idct                  = ff_simple_idct_mmx;
-            c->idct_permutation_type = FF_SIMPLE_IDCT_PERM;
-            break;
-        case FF_IDCT_XVIDMMX:
-            c->idct_put              = ff_idct_xvid_mmx_put;
-            c->idct_add              = ff_idct_xvid_mmx_add;
-            c->idct                  = ff_idct_xvid_mmx;
-            break;
-        }
     }
 
+#if 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;
@@ -2493,12 +2657,6 @@
         }
     }
 
-    if (!high_bit_depth && avctx->idct_algo == FF_IDCT_XVIDMMX) {
-        c->idct_put = ff_idct_xvid_mmx2_put;
-        c->idct_add = ff_idct_xvid_mmx2_add;
-        c->idct     = ff_idct_xvid_mmx2;
-    }
-
     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_mmx2;
@@ -2688,6 +2846,9 @@
 
     if (!high_bit_depth)
         c->emulated_edge_mc = emulated_edge_mc_sse;
+#if HAVE_INLINE_ASM
+    c->gmc = gmc_sse;
+#endif
 #endif /* HAVE_YASM */
 }
 
@@ -2724,13 +2885,6 @@
         H264_QPEL_FUNCS(3, 2, sse2);
         H264_QPEL_FUNCS(3, 3, sse2);
     }
-
-    if (!high_bit_depth && avctx->idct_algo == FF_IDCT_XVIDMMX) {
-        c->idct_put              = ff_idct_xvid_sse2_put;
-        c->idct_add              = ff_idct_xvid_sse2_add;
-        c->idct                  = ff_idct_xvid_sse2;
-        c->idct_permutation_type = FF_SSE2_IDCT_PERM;
-    }
 #endif /* HAVE_INLINE_ASM */
 
 #if HAVE_YASM
@@ -2857,8 +3011,50 @@
         c->add_hfyu_median_prediction = add_hfyu_median_prediction_cmov;
 #endif
 
-    if (mm_flags & AV_CPU_FLAG_MMX)
+    if (mm_flags & AV_CPU_FLAG_MMX) {
+#if HAVE_INLINE_ASM
+        const int idct_algo = avctx->idct_algo;
+
+        if (avctx->lowres == 0 && avctx->bits_per_raw_sample <= 8) {
+            if (idct_algo == FF_IDCT_AUTO || idct_algo == FF_IDCT_SIMPLEMMX) {
+                c->idct_put              = ff_simple_idct_put_mmx;
+                c->idct_add              = ff_simple_idct_add_mmx;
+                c->idct                  = ff_simple_idct_mmx;
+                c->idct_permutation_type = FF_SIMPLE_IDCT_PERM;
+#if CONFIG_GPL
+            } else if (idct_algo == FF_IDCT_LIBMPEG2MMX) {
+                if (mm_flags & AV_CPU_FLAG_MMX2) {
+                    c->idct_put = ff_libmpeg2mmx2_idct_put;
+                    c->idct_add = ff_libmpeg2mmx2_idct_add;
+                    c->idct     = ff_mmxext_idct;
+                } else {
+                    c->idct_put = ff_libmpeg2mmx_idct_put;
+                    c->idct_add = ff_libmpeg2mmx_idct_add;
+                    c->idct     = ff_mmx_idct;
+                }
+                c->idct_permutation_type = FF_LIBMPEG2_IDCT_PERM;
+#endif
+            } else if (idct_algo == FF_IDCT_XVIDMMX) {
+                if (mm_flags & AV_CPU_FLAG_SSE2) {
+                    c->idct_put              = ff_idct_xvid_sse2_put;
+                    c->idct_add              = ff_idct_xvid_sse2_add;
+                    c->idct                  = ff_idct_xvid_sse2;
+                    c->idct_permutation_type = FF_SSE2_IDCT_PERM;
+                } else if (mm_flags & AV_CPU_FLAG_MMXEXT) {
+                    c->idct_put              = ff_idct_xvid_mmx2_put;
+                    c->idct_add              = ff_idct_xvid_mmx2_add;
+                    c->idct                  = ff_idct_xvid_mmx2;
+                } else {
+                    c->idct_put              = ff_idct_xvid_mmx_put;
+                    c->idct_add              = ff_idct_xvid_mmx_add;
+                    c->idct                  = ff_idct_xvid_mmx;
+                }
+            }
+        }
+#endif /* HAVE_INLINE_ASM */
+
         dsputil_init_mmx(c, avctx, mm_flags);
+    }
 
     if (mm_flags & AV_CPU_FLAG_MMXEXT)
         dsputil_init_mmx2(c, avctx, mm_flags);
diff --git a/libavcodec/x86/dsputil_mmx.h b/libavcodec/x86/dsputil_mmx.h
index bd14c5a..16d741d 100644
--- a/libavcodec/x86/dsputil_mmx.h
+++ b/libavcodec/x86/dsputil_mmx.h
@@ -2,20 +2,20 @@
  * MMX optimized DSP utils
  * Copyright (c) 2007  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -102,6 +102,10 @@
 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_deinterlace_line_mmx(uint8_t *dst,
                              const uint8_t *lum_m4, const uint8_t *lum_m3,
                              const uint8_t *lum_m2, const uint8_t *lum_m1,
diff --git a/libavcodec/x86/dsputil_qns_template.c b/libavcodec/x86/dsputil_qns_template.c
index 20a40a1..77a41b9 100644
--- a/libavcodec/x86/dsputil_qns_template.c
+++ b/libavcodec/x86/dsputil_qns_template.c
@@ -5,20 +5,20 @@
  * MMX optimization by Michael Niedermayer <michaelni@gmx.at>
  * 3DNow! and SSSE3 optimization by Zuxy Meng <zuxy.meng@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/dsputil_rnd_template.c b/libavcodec/x86/dsputil_rnd_template.c
index 34a2c0b..e4c9138 100644
--- a/libavcodec/x86/dsputil_rnd_template.c
+++ b/libavcodec/x86/dsputil_rnd_template.c
@@ -7,20 +7,20 @@
  * mostly rewritten by Michael Niedermayer <michaelni@gmx.at>
  * and improved by Zdenek Kabelac <kabi@users.sf.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/dsputilenc.asm b/libavcodec/x86/dsputilenc.asm
index b7078f1..2d805c7 100644
--- a/libavcodec/x86/dsputilenc.asm
+++ b/libavcodec/x86/dsputilenc.asm
@@ -4,25 +4,25 @@
 ;* Copyright (c) 2000, 2001 Fabrice Bellard
 ;* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;*****************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 SECTION .text
 
diff --git a/libavcodec/x86/dsputilenc_mmx.c b/libavcodec/x86/dsputilenc_mmx.c
index b7d88f0..f6eadc1 100644
--- a/libavcodec/x86/dsputilenc_mmx.c
+++ b/libavcodec/x86/dsputilenc_mmx.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000, 2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  *
  * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
@@ -822,8 +822,9 @@
 }
 #undef SUM
 
-static void diff_bytes_mmx(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){
+static void diff_bytes_mmx(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int w){
     x86_reg i=0;
+    if(w>=16)
     __asm__ volatile(
         "1:                             \n\t"
         "movq  (%2, %0), %%mm0          \n\t"
diff --git a/libavcodec/x86/dwt.c b/libavcodec/x86/dwt.c
new file mode 100644
index 0000000..e718c80
--- /dev/null
+++ b/libavcodec/x86/dwt.c
@@ -0,0 +1,202 @@
+/*
+ * MMX optimized discrete wavelet transform
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2010 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/x86/asm.h"
+#include "dsputil_mmx.h"
+#include "dwt.h"
+
+#define COMPOSE_VERTICAL(ext, align) \
+void ff_vertical_compose53iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width); \
+void ff_vertical_compose_dirac53iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width); \
+void ff_vertical_compose_dd137iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, int width); \
+void ff_vertical_compose_dd97iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, int width); \
+void ff_vertical_compose_haar##ext(IDWTELEM *b0, IDWTELEM *b1, int width); \
+void ff_horizontal_compose_haar0i##ext(IDWTELEM *b, IDWTELEM *tmp, int w);\
+void ff_horizontal_compose_haar1i##ext(IDWTELEM *b, IDWTELEM *tmp, int w);\
+\
+static void vertical_compose53iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width) \
+{ \
+    int i, width_align = width&~(align-1); \
+\
+    for(i=width_align; i<width; i++) \
+        b1[i] = COMPOSE_53iL0(b0[i], b1[i], b2[i]); \
+\
+    ff_vertical_compose53iL0##ext(b0, b1, b2, width_align); \
+} \
+\
+static void vertical_compose_dirac53iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width) \
+{ \
+    int i, width_align = width&~(align-1); \
+\
+    for(i=width_align; i<width; i++) \
+        b1[i] = COMPOSE_DIRAC53iH0(b0[i], b1[i], b2[i]); \
+\
+    ff_vertical_compose_dirac53iH0##ext(b0, b1, b2, width_align); \
+} \
+\
+static void vertical_compose_dd137iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, \
+                                           IDWTELEM *b3, IDWTELEM *b4, int width) \
+{ \
+    int i, width_align = width&~(align-1); \
+\
+    for(i=width_align; i<width; i++) \
+        b2[i] = COMPOSE_DD137iL0(b0[i], b1[i], b2[i], b3[i], b4[i]); \
+\
+    ff_vertical_compose_dd137iL0##ext(b0, b1, b2, b3, b4, width_align); \
+} \
+\
+static void vertical_compose_dd97iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, \
+                                          IDWTELEM *b3, IDWTELEM *b4, int width) \
+{ \
+    int i, width_align = width&~(align-1); \
+\
+    for(i=width_align; i<width; i++) \
+        b2[i] = COMPOSE_DD97iH0(b0[i], b1[i], b2[i], b3[i], b4[i]); \
+\
+    ff_vertical_compose_dd97iH0##ext(b0, b1, b2, b3, b4, width_align); \
+} \
+static void vertical_compose_haar##ext(IDWTELEM *b0, IDWTELEM *b1, int width) \
+{ \
+    int i, width_align = width&~(align-1); \
+\
+    for(i=width_align; i<width; i++) { \
+        b0[i] = COMPOSE_HAARiL0(b0[i], b1[i]); \
+        b1[i] = COMPOSE_HAARiH0(b1[i], b0[i]); \
+    } \
+\
+    ff_vertical_compose_haar##ext(b0, b1, width_align); \
+} \
+static void horizontal_compose_haar0i##ext(IDWTELEM *b, IDWTELEM *tmp, int w)\
+{\
+    int w2= w>>1;\
+    int x= w2 - (w2&(align-1));\
+    ff_horizontal_compose_haar0i##ext(b, tmp, w);\
+\
+    for (; x < w2; x++) {\
+        b[2*x  ] = tmp[x];\
+        b[2*x+1] = COMPOSE_HAARiH0(b[x+w2], tmp[x]);\
+    }\
+}\
+static void horizontal_compose_haar1i##ext(IDWTELEM *b, IDWTELEM *tmp, int w)\
+{\
+    int w2= w>>1;\
+    int x= w2 - (w2&(align-1));\
+    ff_horizontal_compose_haar1i##ext(b, tmp, w);\
+\
+    for (; x < w2; x++) {\
+        b[2*x  ] = (tmp[x] + 1)>>1;\
+        b[2*x+1] = (COMPOSE_HAARiH0(b[x+w2], tmp[x]) + 1)>>1;\
+    }\
+}\
+\
+
+#if HAVE_YASM
+#if !ARCH_X86_64
+COMPOSE_VERTICAL(_mmx, 4)
+#endif
+COMPOSE_VERTICAL(_sse2, 8)
+
+
+void ff_horizontal_compose_dd97i_ssse3(IDWTELEM *b, IDWTELEM *tmp, int w);
+
+static void horizontal_compose_dd97i_ssse3(IDWTELEM *b, IDWTELEM *tmp, int w)
+{
+    int w2= w>>1;
+    int x= w2 - (w2&7);
+    ff_horizontal_compose_dd97i_ssse3(b, tmp, w);
+
+    for (; 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;
+    }
+}
+#endif
+
+void ff_spatial_idwt_init_mmx(DWTContext *d, enum dwt_type type)
+{
+#if HAVE_YASM
+  int mm_flags = av_get_cpu_flags();
+
+#if !ARCH_X86_64
+    if (!(mm_flags & AV_CPU_FLAG_MMX))
+        return;
+
+    switch (type) {
+    case DWT_DIRAC_DD9_7:
+        d->vertical_compose_l0 = (void*)vertical_compose53iL0_mmx;
+        d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_mmx;
+        break;
+    case DWT_DIRAC_LEGALL5_3:
+        d->vertical_compose_l0 = (void*)vertical_compose53iL0_mmx;
+        d->vertical_compose_h0 = (void*)vertical_compose_dirac53iH0_mmx;
+        break;
+    case DWT_DIRAC_DD13_7:
+        d->vertical_compose_l0 = (void*)vertical_compose_dd137iL0_mmx;
+        d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_mmx;
+        break;
+    case DWT_DIRAC_HAAR0:
+        d->vertical_compose   = (void*)vertical_compose_haar_mmx;
+        d->horizontal_compose = horizontal_compose_haar0i_mmx;
+        break;
+    case DWT_DIRAC_HAAR1:
+        d->vertical_compose   = (void*)vertical_compose_haar_mmx;
+        d->horizontal_compose = horizontal_compose_haar1i_mmx;
+        break;
+    }
+#endif
+
+    if (!(mm_flags & AV_CPU_FLAG_SSE2))
+        return;
+
+    switch (type) {
+    case DWT_DIRAC_DD9_7:
+        d->vertical_compose_l0 = (void*)vertical_compose53iL0_sse2;
+        d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_sse2;
+        break;
+    case DWT_DIRAC_LEGALL5_3:
+        d->vertical_compose_l0 = (void*)vertical_compose53iL0_sse2;
+        d->vertical_compose_h0 = (void*)vertical_compose_dirac53iH0_sse2;
+        break;
+    case DWT_DIRAC_DD13_7:
+        d->vertical_compose_l0 = (void*)vertical_compose_dd137iL0_sse2;
+        d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_sse2;
+        break;
+    case DWT_DIRAC_HAAR0:
+        d->vertical_compose   = (void*)vertical_compose_haar_sse2;
+        d->horizontal_compose = horizontal_compose_haar0i_sse2;
+        break;
+    case DWT_DIRAC_HAAR1:
+        d->vertical_compose   = (void*)vertical_compose_haar_sse2;
+        d->horizontal_compose = horizontal_compose_haar1i_sse2;
+        break;
+    }
+
+    if (!(mm_flags & AV_CPU_FLAG_SSSE3))
+        return;
+
+    switch (type) {
+    case DWT_DIRAC_DD9_7:
+        d->horizontal_compose = horizontal_compose_dd97i_ssse3;
+        break;
+    }
+#endif // HAVE_YASM
+}
diff --git a/libavcodec/x86/dwt.h b/libavcodec/x86/dwt.h
new file mode 100644
index 0000000..199f611
--- /dev/null
+++ b/libavcodec/x86/dwt.h
@@ -0,0 +1,30 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_X86_DWT_H
+#define AVCODEC_X86_DWT_H
+
+#include "libavcodec/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);
+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
diff --git a/libavcodec/x86/dwt_yasm.asm b/libavcodec/x86/dwt_yasm.asm
new file mode 100644
index 0000000..ac6c505
--- /dev/null
+++ b/libavcodec/x86/dwt_yasm.asm
@@ -0,0 +1,291 @@
+;******************************************************************************
+;* MMX optimized discrete wavelet trasnform
+;* Copyright (c) 2010 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
+;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+;******************************************************************************
+
+%include "x86inc.asm"
+
+SECTION_RODATA
+pw_1: times 8 dw 1
+pw_2: times 8 dw 2
+pw_8: times 8 dw 8
+pw_16: times 8 dw 16
+pw_1991: times 4 dw 9,-1
+
+section .text
+
+; %1 -= (%2 + %3 + 2)>>2     %4 is pw_2
+%macro COMPOSE_53iL0 4
+    paddw   %2, %3
+    paddw   %2, %4
+    psraw   %2, 2
+    psubw   %1, %2
+%endm
+
+; m1 = %1 + (-m0 + 9*m1 + 9*%2 -%3 + 8)>>4
+; if %4 is supplied, %1 is loaded unaligned from there
+; m2: clobbered  m3: pw_8  m4: pw_1991
+%macro COMPOSE_DD97iH0 3-4
+    paddw   m0, %3
+    paddw   m1, %2
+    psubw   m0, m3
+    mova    m2, m1
+    punpcklwd m1, m0
+    punpckhwd m2, m0
+    pmaddwd m1, m4
+    pmaddwd m2, m4
+%if %0 > 3
+    movu    %1, %4
+%endif
+    psrad   m1, 4
+    psrad   m2, 4
+    packssdw m1, m2
+    paddw   m1, %1
+%endm
+
+%macro COMPOSE_VERTICAL 1
+; void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+;                                  int width)
+cglobal vertical_compose53iL0_%1, 4,4,1, b0, b1, b2, width
+    mova    m2, [pw_2]
+.loop:
+    sub     widthd, mmsize/2
+    mova    m1, [b0q+2*widthq]
+    mova    m0, [b1q+2*widthq]
+    COMPOSE_53iL0 m0, m1, [b2q+2*widthq], m2
+    mova    [b1q+2*widthq], m0
+    jg      .loop
+    REP_RET
+
+; void vertical_compose_dirac53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+;                                  int width)
+cglobal vertical_compose_dirac53iH0_%1, 4,4,1, b0, b1, b2, width
+    mova    m1, [pw_1]
+.loop:
+    sub     widthd, mmsize/2
+    mova    m0, [b0q+2*widthq]
+    paddw   m0, [b2q+2*widthq]
+    paddw   m0, m1
+    psraw   m0, 1
+    paddw   m0, [b1q+2*widthq]
+    mova    [b1q+2*widthq], m0
+    jg      .loop
+    REP_RET
+
+; void vertical_compose_dd97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+;                               IDWTELEM *b3, IDWTELEM *b4, int width)
+cglobal vertical_compose_dd97iH0_%1, 6,6,5, b0, b1, b2, b3, b4, width
+    mova    m3, [pw_8]
+    mova    m4, [pw_1991]
+.loop:
+    sub     widthd, mmsize/2
+    mova    m0, [b0q+2*widthq]
+    mova    m1, [b1q+2*widthq]
+    COMPOSE_DD97iH0 [b2q+2*widthq], [b3q+2*widthq], [b4q+2*widthq]
+    mova    [b2q+2*widthq], m1
+    jg      .loop
+    REP_RET
+
+; void vertical_compose_dd137iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
+;                                IDWTELEM *b3, IDWTELEM *b4, int width)
+cglobal vertical_compose_dd137iL0_%1, 6,6,6, b0, b1, b2, b3, b4, width
+    mova    m3, [pw_16]
+    mova    m4, [pw_1991]
+.loop:
+    sub     widthd, mmsize/2
+    mova    m0, [b0q+2*widthq]
+    mova    m1, [b1q+2*widthq]
+    mova    m5, [b2q+2*widthq]
+    paddw   m0, [b4q+2*widthq]
+    paddw   m1, [b3q+2*widthq]
+    psubw   m0, m3
+    mova    m2, m1
+    punpcklwd m1, m0
+    punpckhwd m2, m0
+    pmaddwd m1, m4
+    pmaddwd m2, m4
+    psrad   m1, 5
+    psrad   m2, 5
+    packssdw m1, m2
+    psubw   m5, m1
+    mova    [b2q+2*widthq], m5
+    jg      .loop
+    REP_RET
+
+; 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]
+.loop:
+    sub     widthd, mmsize/2
+    mova    m1, [b1q+2*widthq]
+    mova    m0, [b0q+2*widthq]
+    mova    m2, m1
+    paddw   m1, m3
+    psraw   m1, 1
+    psubw   m0, m1
+    mova    [b0q+2*widthq], m0
+    paddw   m2, m0
+    mova    [b1q+2*widthq], m2
+    jg      .loop
+    REP_RET
+%endmacro
+
+; extend the left and right edges of the tmp array by %1 and %2 respectively
+%macro EDGE_EXTENSION 3
+    mov     %3, [tmpq]
+%assign %%i 1
+%rep %1
+    mov     [tmpq-2*%%i], %3
+    %assign %%i %%i+1
+%endrep
+    mov     %3, [tmpq+2*w2q-2]
+%assign %%i 0
+%rep %2
+    mov     [tmpq+2*w2q+2*%%i], %3
+    %assign %%i %%i+1
+%endrep
+%endmacro
+
+
+%macro HAAR_HORIZONTAL 2
+; void horizontal_compose_haari(IDWTELEM *b, IDWTELEM *tmp, int width)
+cglobal horizontal_compose_haar%2i_%1, 3,6,4, b, tmp, w, x, w2, b_w2
+    mov    w2d, wd
+    xor     xq, xq
+    shr    w2d, 1
+    lea  b_w2q, [bq+wq]
+    mova    m3, [pw_1]
+.lowpass_loop:
+    movu    m1, [b_w2q + 2*xq]
+    mova    m0, [bq    + 2*xq]
+    paddw   m1, m3
+    psraw   m1, 1
+    psubw   m0, m1
+    mova    [tmpq + 2*xq], m0
+    add     xq, mmsize/2
+    cmp     xq, w2q
+    jl      .lowpass_loop
+
+    xor     xq, xq
+    and    w2q, ~(mmsize/2 - 1)
+    cmp    w2q, mmsize/2
+    jl      .end
+
+.highpass_loop:
+    movu    m1, [b_w2q + 2*xq]
+    mova    m0, [tmpq  + 2*xq]
+    paddw   m1, m0
+
+    ; shift and interleave
+%if %2 == 1
+    paddw   m0, m3
+    paddw   m1, m3
+    psraw   m0, 1
+    psraw   m1, 1
+%endif
+    mova    m2, m0
+    punpcklwd m0, m1
+    punpckhwd m2, m1
+    mova    [bq+4*xq], m0
+    mova    [bq+4*xq+mmsize], m2
+
+    add     xq, mmsize/2
+    cmp     xq, w2q
+    jl      .highpass_loop
+.end:
+    REP_RET
+%endmacro
+
+
+INIT_XMM
+; void horizontal_compose_dd97i(IDWTELEM *b, IDWTELEM *tmp, int width)
+cglobal horizontal_compose_dd97i_ssse3, 3,6,8, b, tmp, w, x, w2, b_w2
+    mov    w2d, wd
+    xor     xd, xd
+    shr    w2d, 1
+    lea  b_w2q, [bq+wq]
+    movu    m4, [bq+wq]
+    mova    m7, [pw_2]
+    pslldq  m4, 14
+.lowpass_loop:
+    movu    m1, [b_w2q + 2*xq]
+    mova    m0, [bq    + 2*xq]
+    mova    m2, m1
+    palignr m1, m4, 14
+    mova    m4, m2
+    COMPOSE_53iL0 m0, m1, m2, m7
+    mova    [tmpq + 2*xq], m0
+    add     xd, mmsize/2
+    cmp     xd, w2d
+    jl      .lowpass_loop
+
+    EDGE_EXTENSION 1, 2, xw
+    ; leave the last up to 7 (sse) or 3 (mmx) values for C
+    xor     xd, xd
+    and    w2d, ~(mmsize/2 - 1)
+    cmp    w2d, mmsize/2
+    jl      .end
+
+    mova    m7, [tmpq-mmsize]
+    mova    m0, [tmpq]
+    mova    m5, [pw_1]
+    mova    m3, [pw_8]
+    mova    m4, [pw_1991]
+.highpass_loop:
+    mova    m6, m0
+    palignr m0, m7, 14
+    mova    m7, [tmpq + 2*xq + 16]
+    mova    m1, m7
+    mova    m2, m7
+    palignr m1, m6, 2
+    palignr m2, m6, 4
+    COMPOSE_DD97iH0 m0, m6, m2, [b_w2q + 2*xq]
+    mova    m0, m7
+    mova    m7, m6
+
+    ; shift and interleave
+    paddw   m6, m5
+    paddw   m1, m5
+    psraw   m6, 1
+    psraw   m1, 1
+    mova    m2, m6
+    punpcklwd m6, m1
+    punpckhwd m2, m1
+    mova    [bq+4*xq], m6
+    mova    [bq+4*xq+mmsize], m2
+
+    add     xd, mmsize/2
+    cmp     xd, w2d
+    jl      .highpass_loop
+.end:
+    REP_RET
+
+
+%if ARCH_X86_64 == 0
+INIT_MMX
+COMPOSE_VERTICAL mmx
+HAAR_HORIZONTAL mmx, 0
+HAAR_HORIZONTAL mmx, 1
+%endif
+
+;;INIT_XMM
+INIT_XMM
+COMPOSE_VERTICAL sse2
+HAAR_HORIZONTAL sse2, 0
+HAAR_HORIZONTAL sse2, 1
diff --git a/libavcodec/x86/fdct.c b/libavcodec/x86/fdct.c
index f9bd3f2..566e0b6 100644
--- a/libavcodec/x86/fdct.c
+++ b/libavcodec/x86/fdct.c
@@ -13,20 +13,20 @@
  * a page about fdct at http://www.geocities.com/ssavekar/dct.htm
  * Skal's fdct at http://skal.planet-d.net/coding/dct.html
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -70,7 +70,7 @@
 
 DECLARE_ALIGNED(8, static const int32_t, fdct_r_row)[2] = {RND_FRW_ROW, RND_FRW_ROW };
 
-static struct
+static const struct
 {
  DECLARE_ALIGNED(16, const int32_t, fdct_r_row_sse2)[4];
 } fdct_r_row_sse2 =
@@ -153,7 +153,7 @@
   29692,  -12299,   26722,  -31521,
 };
 
-static struct
+static const struct
 {
  DECLARE_ALIGNED(16, const int16_t, tab_frw_01234567_sse2)[256];
 } tab_frw_01234567_sse2 =
diff --git a/libavcodec/x86/fft.asm b/libavcodec/x86/fft.asm
index f054298..c2b9cbb 100644
--- a/libavcodec/x86/fft.asm
+++ b/libavcodec/x86/fft.asm
@@ -6,20 +6,20 @@
 ;* This algorithm (though not any of the implementation details) is
 ;* based on libdjbfft by D. J. Bernstein.
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
@@ -28,8 +28,8 @@
 ; in blocks as conventient to the vector size.
 ; i.e. {4x real, 4x imaginary, 4x real, ...} (or 2x respectively)
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 %if ARCH_X86_64
 %define pointer resq
@@ -37,6 +37,8 @@
 %define pointer resd
 %endif
 
+SECTION_RODATA
+
 struc FFTContext
     .nbits:    resd 1
     .reverse:  resd 1
@@ -52,8 +54,6 @@
     .imdcthalf:pointer 1
 endstruc
 
-SECTION_RODATA
-
 %define M_SQRT1_2 0.70710678118654752440
 %define M_COS_PI_1_8 0.923879532511287
 %define M_COS_PI_3_8 0.38268343236509
@@ -394,6 +394,7 @@
     sub r2d, mmsize/4
     jg .deint_loop
     ret
+
 %endif
 
 INIT_XMM sse
diff --git a/libavcodec/x86/fft.h b/libavcodec/x86/fft.h
index 6e80b95..3f8b21d 100644
--- a/libavcodec/x86/fft.h
+++ b/libavcodec/x86/fft.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/fft_init.c b/libavcodec/x86/fft_init.c
index 5554b24..a9d9579 100644
--- a/libavcodec/x86/fft_init.c
+++ b/libavcodec/x86/fft_init.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/fmtconvert.asm b/libavcodec/x86/fmtconvert.asm
index 46b7e85..21e0cce 100644
--- a/libavcodec/x86/fmtconvert.asm
+++ b/libavcodec/x86/fmtconvert.asm
@@ -2,25 +2,25 @@
 ;* x86 optimized Format Conversion Utils
 ;* Copyright (c) 2008 Loren Merritt
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 SECTION_TEXT
 
diff --git a/libavcodec/x86/fmtconvert_init.c b/libavcodec/x86/fmtconvert_init.c
index b97fbf9..528b7b1 100644
--- a/libavcodec/x86/fmtconvert_init.c
+++ b/libavcodec/x86/fmtconvert_init.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000, 2001 Fabrice Bellard
  * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  *
  * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
diff --git a/libavcodec/x86/h264_chromamc.asm b/libavcodec/x86/h264_chromamc.asm
index 56b8e56..bee8330 100644
--- a/libavcodec/x86/h264_chromamc.asm
+++ b/libavcodec/x86/h264_chromamc.asm
@@ -3,25 +3,25 @@
 ;* Copyright (c) 2005 Zoltan Hidvegi <hzoli -a- hzoli -d- com>,
 ;*               2005-2008 Loren Merritt
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 SECTION_RODATA
 
diff --git a/libavcodec/x86/h264_deblock.asm b/libavcodec/x86/h264_deblock.asm
index 940a8f7..6abdba2 100644
--- a/libavcodec/x86/h264_deblock.asm
+++ b/libavcodec/x86/h264_deblock.asm
@@ -7,25 +7,25 @@
 ;*          Jason Garrett-Glaser <darkshikari@gmail.com>
 ;*          Oskar Arvidsson <oskar@irock.se>
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 SECTION_RODATA
 
@@ -390,8 +390,10 @@
 
 INIT_XMM sse2
 DEBLOCK_LUMA
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 DEBLOCK_LUMA
+%endif
 
 %else
 
@@ -509,8 +511,10 @@
 DEBLOCK_LUMA v8, 8
 INIT_XMM sse2
 DEBLOCK_LUMA v, 16
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 DEBLOCK_LUMA v, 16
+%endif
 
 %endif ; ARCH
 
@@ -781,8 +785,10 @@
 
 INIT_XMM sse2
 DEBLOCK_LUMA_INTRA v
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 DEBLOCK_LUMA_INTRA v
+%endif
 %if ARCH_X86_64 == 0
 INIT_MMX mmx2
 DEBLOCK_LUMA_INTRA v8
@@ -843,7 +849,11 @@
     TRANSPOSE4x8_LOAD  bw, wd, dq, PASS8ROWS(t5, r0, r1, t6)
     movq  buf0, m0
     movq  buf1, m3
-    call ff_chroma_inter_body_mmx2
+    LOAD_MASK  r2d, r3d
+    movd       m6, [r4] ; tc0
+    punpcklbw  m6, m6
+    pand       m7, m6
+    DEBLOCK_P0_Q0
     movq  m0, buf0
     movq  m3, buf1
     TRANSPOSE8x4B_STORE PASS8ROWS(t5, r0, r1, t6)
diff --git a/libavcodec/x86/h264_deblock_10bit.asm b/libavcodec/x86/h264_deblock_10bit.asm
index 7b9316d..0517605 100644
--- a/libavcodec/x86/h264_deblock_10bit.asm
+++ b/libavcodec/x86/h264_deblock_10bit.asm
@@ -24,8 +24,8 @@
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 SECTION_RODATA
 
@@ -418,9 +418,11 @@
 
 INIT_XMM sse2
 DEBLOCK_LUMA_64
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 DEBLOCK_LUMA_64
 %endif
+%endif
 
 %macro SWAPMOVA 2
 %ifid %1
@@ -713,8 +715,10 @@
 
 INIT_XMM sse2
 DEBLOCK_LUMA_INTRA_64
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 DEBLOCK_LUMA_INTRA_64
+%endif
 
 %endif
 
@@ -798,10 +802,12 @@
 INIT_XMM sse2
 DEBLOCK_LUMA
 DEBLOCK_LUMA_INTRA
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 DEBLOCK_LUMA
 DEBLOCK_LUMA_INTRA
 %endif
+%endif
 
 ; in: %1=p0, %2=q0, %3=p1, %4=q1, %5=mask, %6=tmp, %7=tmp
 ; out: %1=p0', %2=q0'
@@ -912,5 +918,7 @@
 %endif
 INIT_XMM sse2
 DEBLOCK_CHROMA
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 DEBLOCK_CHROMA
+%endif
diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h
index bb881c3..0dc0a7c 100644
--- a/libavcodec/x86/h264_i386.h
+++ b/libavcodec/x86/h264_i386.h
@@ -2,20 +2,20 @@
  * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/h264_idct.asm b/libavcodec/x86/h264_idct.asm
index 68864a4..7003a14 100644
--- a/libavcodec/x86/h264_idct.asm
+++ b/libavcodec/x86/h264_idct.asm
@@ -9,25 +9,25 @@
 ;*          Holger Lubitz <hal@duncan.ol.sub.de>
 ;*          Min Chen <chenm001.163.com>
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;*****************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 SECTION_RODATA
 
diff --git a/libavcodec/x86/h264_idct_10bit.asm b/libavcodec/x86/h264_idct_10bit.asm
index 6afcee2..525ce39 100644
--- a/libavcodec/x86/h264_idct_10bit.asm
+++ b/libavcodec/x86/h264_idct_10bit.asm
@@ -22,8 +22,8 @@
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 SECTION_RODATA
 
diff --git a/libavcodec/x86/h264_intrapred.asm b/libavcodec/x86/h264_intrapred.asm
index dc418f7..609cb23 100644
--- a/libavcodec/x86/h264_intrapred.asm
+++ b/libavcodec/x86/h264_intrapred.asm
@@ -5,25 +5,25 @@
 ;* Copyright (c) 2010 Loren Merritt
 ;* Copyright (c) 2010 Ronald S. Bultje
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 SECTION_RODATA
 
diff --git a/libavcodec/x86/h264_intrapred_10bit.asm b/libavcodec/x86/h264_intrapred_10bit.asm
index 529134e..4eeb0a4 100644
--- a/libavcodec/x86/h264_intrapred_10bit.asm
+++ b/libavcodec/x86/h264_intrapred_10bit.asm
@@ -22,8 +22,8 @@
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 SECTION_RODATA
 
diff --git a/libavcodec/x86/h264_intrapred_init.c b/libavcodec/x86/h264_intrapred_init.c
index cd82f47..6d8b414 100644
--- a/libavcodec/x86/h264_intrapred_init.c
+++ b/libavcodec/x86/h264_intrapred_init.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Jason Garrett-Glaser
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/h264_qpel.c b/libavcodec/x86/h264_qpel.c
index 284c85a..faf8a76 100644
--- a/libavcodec/x86/h264_qpel.c
+++ b/libavcodec/x86/h264_qpel.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt
  * Copyright (c) 2011 Daniel Kang
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -1286,6 +1286,6 @@
 QPEL16_OP(mc32, MMX)\
 QPEL16_OP(mc33, MMX)
 
-#if ARCH_X86_32 && HAVE_YASM // ARCH_X86_64 implies sse2+
+#if CONFIG_H264QPEL && ARCH_X86_32 && HAVE_YASM // ARCH_X86_64 implies sse2+
 QPEL16(mmxext)
 #endif
diff --git a/libavcodec/x86/h264_weight.asm b/libavcodec/x86/h264_weight.asm
index c8779cc..2ad5a8f 100644
--- a/libavcodec/x86/h264_weight.asm
+++ b/libavcodec/x86/h264_weight.asm
@@ -4,24 +4,24 @@
 ;* Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt
 ;* Copyright (C) 2010 Eli Friedman <eli.friedman@gmail.com>
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
+%include "libavutil/x86/x86inc.asm"
 
 SECTION .text
 
@@ -253,6 +253,13 @@
     add  off_regd, 1
     or   off_regd, 1
     add        r4, 1
+    cmp        r5, 128
+     jne .normal
+    sar        r5, 1
+    sar        r6, 1
+    sar  off_regd, 1
+    sub        r4, 1
+.normal
     movd       m4, r5d
     movd       m0, r6d
     movd       m5, off_regd
diff --git a/libavcodec/x86/h264dsp_init.c b/libavcodec/x86/h264dsp_init.c
index 3f6ded4..bb48867 100644
--- a/libavcodec/x86/h264dsp_init.c
+++ b/libavcodec/x86/h264dsp_init.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -128,7 +128,7 @@
 LF_FUNCS(uint8_t,   8)
 LF_FUNCS(uint16_t, 10)
 
-#if ARCH_X86_32
+#if ARCH_X86_32 && HAVE_YASM
 LF_FUNC(v8, luma, 8, mmx2)
 static void ff_deblock_v_luma_8_mmx2(uint8_t *pix, int stride, int alpha,
                                      int beta, int8_t *tc0)
@@ -210,6 +210,7 @@
 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();
 
     if (chroma_format_idc == 1 && EXTERNAL_MMXEXT(mm_flags))
@@ -371,4 +372,5 @@
             }
         }
     }
+#endif
 }
diff --git a/libavcodec/x86/idct_mmx.c b/libavcodec/x86/idct_mmx.c
new file mode 100644
index 0000000..4b92f5c
--- /dev/null
+++ b/libavcodec/x86/idct_mmx.c
@@ -0,0 +1,632 @@
+/*
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ * See http://libmpeg2.sourceforge.net/ for updates.
+ *
+ * mpeg2dec 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.
+ *
+ * mpeg2dec is distributed in the hope that 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 mpeg2dec; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/common.h"
+#include "libavcodec/dsputil.h"
+
+#include "libavutil/x86/asm.h"
+#include "dsputil_mmx.h"
+
+#if HAVE_INLINE_ASM
+
+#define ROW_SHIFT 11
+#define COL_SHIFT 6
+
+#define round(bias) ((int)(((bias)+0.5) * (1<<ROW_SHIFT)))
+#define rounder(bias) {round (bias), round (bias)}
+
+
+#if 0
+/* C row IDCT - it is just here to document the MMXEXT and MMX versions */
+static inline void idct_row (int16_t * row, int offset,
+                             int16_t * table, int32_t * rounder)
+{
+    int C1, C2, C3, C4, C5, C6, C7;
+    int a0, a1, a2, a3, b0, b1, b2, b3;
+
+    row += offset;
+
+    C1 = table[1];
+    C2 = table[2];
+    C3 = table[3];
+    C4 = table[4];
+    C5 = table[5];
+    C6 = table[6];
+    C7 = table[7];
+
+    a0 = C4*row[0] + C2*row[2] + C4*row[4] + C6*row[6] + *rounder;
+    a1 = C4*row[0] + C6*row[2] - C4*row[4] - C2*row[6] + *rounder;
+    a2 = C4*row[0] - C6*row[2] - C4*row[4] + C2*row[6] + *rounder;
+    a3 = C4*row[0] - C2*row[2] + C4*row[4] - C6*row[6] + *rounder;
+
+    b0 = C1*row[1] + C3*row[3] + C5*row[5] + C7*row[7];
+    b1 = C3*row[1] - C7*row[3] - C1*row[5] - C5*row[7];
+    b2 = C5*row[1] - C1*row[3] + C7*row[5] + C3*row[7];
+    b3 = C7*row[1] - C5*row[3] + C3*row[5] - C1*row[7];
+
+    row[0] = (a0 + b0) >> ROW_SHIFT;
+    row[1] = (a1 + b1) >> ROW_SHIFT;
+    row[2] = (a2 + b2) >> ROW_SHIFT;
+    row[3] = (a3 + b3) >> ROW_SHIFT;
+    row[4] = (a3 - b3) >> ROW_SHIFT;
+    row[5] = (a2 - b2) >> ROW_SHIFT;
+    row[6] = (a1 - b1) >> ROW_SHIFT;
+    row[7] = (a0 - b0) >> ROW_SHIFT;
+}
+#endif
+
+
+/* MMXEXT row IDCT */
+
+#define mmxext_table(c1,c2,c3,c4,c5,c6,c7)      {  c4,  c2, -c4, -c2,   \
+                                                   c4,  c6,  c4,  c6,   \
+                                                   c1,  c3, -c1, -c5,   \
+                                                   c5,  c7,  c3, -c7,   \
+                                                   c4, -c6,  c4, -c6,   \
+                                                  -c4,  c2,  c4, -c2,   \
+                                                   c5, -c1,  c3, -c1,   \
+                                                   c7,  c3,  c7, -c5 }
+
+static inline void mmxext_row_head (int16_t * const row, const int offset,
+                                    const int16_t * const table)
+{
+    __asm__ volatile(
+        "movq     (%0), %%mm2        \n\t"  /* mm2 = x6 x4 x2 x0 */
+
+        "movq    8(%0), %%mm5        \n\t"  /* mm5 = x7 x5 x3 x1 */
+        "movq    %%mm2, %%mm0        \n\t"  /* mm0 = x6 x4 x2 x0 */
+
+        "movq     (%1), %%mm3        \n\t"  /* mm3 = -C2 -C4 C2 C4 */
+        "movq    %%mm5, %%mm6        \n\t"  /* mm6 = x7 x5 x3 x1 */
+
+        "movq    8(%1), %%mm4        \n\t"  /* mm4 = C6 C4 C6 C4 */
+        "pmaddwd %%mm0, %%mm3        \n\t"  /* mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 */
+
+        "pshufw  $0x4e, %%mm2, %%mm2 \n\t"  /* mm2 = x2 x0 x6 x4 */
+        :: "r" ((row+offset)), "r" (table)
+    );
+}
+
+static inline void mmxext_row (const int16_t * const table,
+                               const int32_t * const rounder)
+{
+    __asm__ volatile (
+        "movq    16(%0), %%mm1         \n\t" /* mm1 = -C5 -C1 C3 C1 */
+        "pmaddwd  %%mm2, %%mm4         \n\t" /* mm4 = C4*x0+C6*x2 C4*x4+C6*x6 */
+
+        "pmaddwd 32(%0), %%mm0         \n\t" /* mm0 = C4*x4-C6*x6 C4*x0-C6*x2 */
+        "pshufw   $0x4e, %%mm6, %%mm6  \n\t" /* mm6 = x3 x1 x7 x5 */
+
+        "movq    24(%0), %%mm7         \n\t" /* mm7 = -C7 C3 C7 C5 */
+        "pmaddwd  %%mm5, %%mm1         \n\t" /* mm1= -C1*x5-C5*x7 C1*x1+C3*x3 */
+
+        "paddd     (%1), %%mm3         \n\t" /* mm3 += rounder */
+        "pmaddwd  %%mm6, %%mm7         \n\t" /* mm7 = C3*x1-C7*x3 C5*x5+C7*x7 */
+
+        "pmaddwd 40(%0), %%mm2         \n\t" /* mm2= C4*x0-C2*x2 -C4*x4+C2*x6 */
+        "paddd    %%mm4, %%mm3         \n\t" /* mm3 = a1 a0 + rounder */
+
+        "pmaddwd 48(%0), %%mm5         \n\t" /* mm5 = C3*x5-C1*x7 C5*x1-C1*x3 */
+        "movq     %%mm3, %%mm4         \n\t" /* mm4 = a1 a0 + rounder */
+
+        "pmaddwd 56(%0), %%mm6         \n\t" /* mm6 = C7*x1-C5*x3 C7*x5+C3*x7 */
+        "paddd    %%mm7, %%mm1         \n\t" /* mm1 = b1 b0 */
+
+        "paddd     (%1), %%mm0         \n\t" /* mm0 += rounder */
+        "psubd    %%mm1, %%mm3         \n\t" /* mm3 = a1-b1 a0-b0 + rounder */
+
+        "psrad $" AV_STRINGIFY(ROW_SHIFT) ", %%mm3         \n\t" /* mm3 = y6 y7 */
+        "paddd    %%mm4, %%mm1         \n\t" /* mm1 = a1+b1 a0+b0 + rounder */
+
+        "paddd    %%mm2, %%mm0         \n\t" /* mm0 = a3 a2 + rounder */
+        "psrad $" AV_STRINGIFY(ROW_SHIFT) ", %%mm1         \n\t" /* mm1 = y1 y0 */
+
+        "paddd    %%mm6, %%mm5         \n\t" /* mm5 = b3 b2 */
+        "movq     %%mm0, %%mm4         \n\t" /* mm4 = a3 a2 + rounder */
+
+        "paddd    %%mm5, %%mm0         \n\t" /* mm0 = a3+b3 a2+b2 + rounder */
+        "psubd    %%mm5, %%mm4         \n\t" /* mm4 = a3-b3 a2-b2 + rounder */
+        : : "r" (table), "r" (rounder));
+}
+
+static inline void mmxext_row_tail (int16_t * const row, const int store)
+{
+    __asm__ volatile (
+        "psrad $" AV_STRINGIFY(ROW_SHIFT) ", %%mm0        \n\t"  /* mm0 = y3 y2 */
+
+        "psrad $" AV_STRINGIFY(ROW_SHIFT) ", %%mm4  \n\t"  /* mm4 = y4 y5 */
+
+        "packssdw %%mm0, %%mm1        \n\t"  /* mm1 = y3 y2 y1 y0 */
+
+        "packssdw %%mm3, %%mm4        \n\t"  /* mm4 = y6 y7 y4 y5 */
+
+        "movq     %%mm1, (%0)         \n\t"  /* save y3 y2 y1 y0 */
+        "pshufw   $0xb1, %%mm4, %%mm4 \n\t"  /* mm4 = y7 y6 y5 y4 */
+
+        /* slot */
+
+        "movq     %%mm4, 8(%0)        \n\t"  /* save y7 y6 y5 y4 */
+        :: "r" (row+store)
+        );
+}
+
+static inline void mmxext_row_mid (int16_t * const row, const int store,
+                                   const int offset,
+                                   const int16_t * const table)
+{
+    __asm__ volatile (
+        "movq     (%0,%1), %%mm2       \n\t" /* mm2 = x6 x4 x2 x0 */
+        "psrad $" AV_STRINGIFY(ROW_SHIFT) ", %%mm0 \n\t"   /* mm0 = y3 y2 */
+
+        "movq    8(%0,%1), %%mm5       \n\t" /* mm5 = x7 x5 x3 x1 */
+        "psrad $" AV_STRINGIFY(ROW_SHIFT) ", %%mm4 \n\t" /* mm4 = y4 y5 */
+
+        "packssdw   %%mm0, %%mm1       \n\t" /* mm1 = y3 y2 y1 y0 */
+        "movq       %%mm5, %%mm6       \n\t" /* mm6 = x7 x5 x3 x1 */
+
+        "packssdw   %%mm3, %%mm4       \n\t" /* mm4 = y6 y7 y4 y5 */
+        "movq       %%mm2, %%mm0       \n\t" /* mm0 = x6 x4 x2 x0 */
+
+        "movq       %%mm1, (%0,%2)     \n\t" /* save y3 y2 y1 y0 */
+        "pshufw     $0xb1, %%mm4, %%mm4\n\t" /* mm4 = y7 y6 y5 y4 */
+
+        "movq        (%3), %%mm3       \n\t" /* mm3 = -C2 -C4 C2 C4 */
+        "movq       %%mm4, 8(%0,%2)    \n\t" /* save y7 y6 y5 y4 */
+
+        "pmaddwd    %%mm0, %%mm3       \n\t" /* mm3= -C4*x4-C2*x6 C4*x0+C2*x2 */
+
+        "movq       8(%3), %%mm4       \n\t" /* mm4 = C6 C4 C6 C4 */
+        "pshufw     $0x4e, %%mm2, %%mm2\n\t" /* mm2 = x2 x0 x6 x4 */
+        :: "r" (row), "r" ((x86_reg) (2*offset)), "r" ((x86_reg) (2*store)), "r" (table)
+        );
+}
+
+
+/* MMX row IDCT */
+
+#define mmx_table(c1,c2,c3,c4,c5,c6,c7) {  c4,  c2,  c4,  c6,   \
+                                           c4,  c6, -c4, -c2,   \
+                                           c1,  c3,  c3, -c7,   \
+                                           c5,  c7, -c1, -c5,   \
+                                           c4, -c6,  c4, -c2,   \
+                                          -c4,  c2,  c4, -c6,   \
+                                           c5, -c1,  c7, -c5,   \
+                                           c7,  c3,  c3, -c1 }
+
+static inline void mmx_row_head (int16_t * const row, const int offset,
+                                 const int16_t * const table)
+{
+    __asm__ volatile (
+        "movq (%0), %%mm2       \n\t"    /* mm2 = x6 x4 x2 x0 */
+
+        "movq 8(%0), %%mm5      \n\t"    /* mm5 = x7 x5 x3 x1 */
+        "movq %%mm2, %%mm0      \n\t"    /* mm0 = x6 x4 x2 x0 */
+
+        "movq (%1), %%mm3       \n\t"    /* mm3 = C6 C4 C2 C4 */
+        "movq %%mm5, %%mm6      \n\t"    /* mm6 = x7 x5 x3 x1 */
+
+        "punpckldq %%mm0, %%mm0 \n\t"    /* mm0 = x2 x0 x2 x0 */
+
+        "movq 8(%1), %%mm4      \n\t"    /* mm4 = -C2 -C4 C6 C4 */
+        "pmaddwd %%mm0, %%mm3   \n\t"    /* mm3 = C4*x0+C6*x2 C4*x0+C2*x2 */
+
+        "movq 16(%1), %%mm1     \n\t"    /* mm1 = -C7 C3 C3 C1 */
+        "punpckhdq %%mm2, %%mm2 \n\t"    /* mm2 = x6 x4 x6 x4 */
+        :: "r" ((row+offset)), "r" (table)
+        );
+}
+
+static inline void mmx_row (const int16_t * const table,
+                            const int32_t * const rounder)
+{
+    __asm__ volatile (
+        "pmaddwd   %%mm2, %%mm4    \n\t"  /* mm4 = -C4*x4-C2*x6 C4*x4+C6*x6 */
+        "punpckldq %%mm5, %%mm5    \n\t"  /* mm5 = x3 x1 x3 x1 */
+
+        "pmaddwd  32(%0), %%mm0    \n\t"  /* mm0 = C4*x0-C2*x2 C4*x0-C6*x2 */
+        "punpckhdq %%mm6, %%mm6    \n\t"  /* mm6 = x7 x5 x7 x5 */
+
+        "movq     24(%0), %%mm7    \n\t"  /* mm7 = -C5 -C1 C7 C5 */
+        "pmaddwd   %%mm5, %%mm1    \n\t"  /* mm1 = C3*x1-C7*x3 C1*x1+C3*x3 */
+
+        "paddd      (%1), %%mm3    \n\t"  /* mm3 += rounder */
+        "pmaddwd   %%mm6, %%mm7    \n\t"  /* mm7 = -C1*x5-C5*x7 C5*x5+C7*x7 */
+
+        "pmaddwd  40(%0), %%mm2    \n\t"  /* mm2 = C4*x4-C6*x6 -C4*x4+C2*x6 */
+        "paddd     %%mm4, %%mm3    \n\t"  /* mm3 = a1 a0 + rounder */
+
+        "pmaddwd  48(%0), %%mm5    \n\t"  /* mm5 = C7*x1-C5*x3 C5*x1-C1*x3 */
+        "movq      %%mm3, %%mm4    \n\t"  /* mm4 = a1 a0 + rounder */
+
+        "pmaddwd  56(%0), %%mm6    \n\t"  /* mm6 = C3*x5-C1*x7 C7*x5+C3*x7 */
+        "paddd     %%mm7, %%mm1    \n\t"  /* mm1 = b1 b0 */
+
+        "paddd      (%1), %%mm0    \n\t"  /* mm0 += rounder */
+        "psubd     %%mm1, %%mm3    \n\t"  /* mm3 = a1-b1 a0-b0 + rounder */
+
+        "psrad $" AV_STRINGIFY(ROW_SHIFT) ", %%mm3    \n\t"  /* mm3 = y6 y7 */
+        "paddd     %%mm4, %%mm1    \n\t"  /* mm1 = a1+b1 a0+b0 + rounder */
+
+        "paddd     %%mm2, %%mm0    \n\t"  /* mm0 = a3 a2 + rounder */
+        "psrad $" AV_STRINGIFY(ROW_SHIFT) ", %%mm1    \n\t"  /* mm1 = y1 y0 */
+
+        "paddd     %%mm6, %%mm5    \n\t"  /* mm5 = b3 b2 */
+        "movq      %%mm0, %%mm7    \n\t"  /* mm7 = a3 a2 + rounder */
+
+        "paddd     %%mm5, %%mm0    \n\t"  /* mm0 = a3+b3 a2+b2 + rounder */
+        "psubd     %%mm5, %%mm7    \n\t"  /* mm7 = a3-b3 a2-b2 + rounder */
+        :: "r" (table), "r" (rounder)
+        );
+}
+
+static inline void mmx_row_tail (int16_t * const row, const int store)
+{
+    __asm__ volatile (
+        "psrad $" AV_STRINGIFY(ROW_SHIFT) ", %%mm0      \n\t" /* mm0 = y3 y2 */
+
+        "psrad $" AV_STRINGIFY(ROW_SHIFT) ", %%mm7      \n\t" /* mm7 = y4 y5 */
+
+        "packssdw %%mm0, %%mm1 \n\t" /* mm1 = y3 y2 y1 y0 */
+
+        "packssdw %%mm3, %%mm7 \n\t" /* mm7 = y6 y7 y4 y5 */
+
+        "movq %%mm1, (%0)      \n\t" /* save y3 y2 y1 y0 */
+        "movq %%mm7, %%mm4     \n\t" /* mm4 = y6 y7 y4 y5 */
+
+        "pslld $16, %%mm7      \n\t" /* mm7 = y7 0 y5 0 */
+
+        "psrld $16, %%mm4      \n\t" /* mm4 = 0 y6 0 y4 */
+
+        "por %%mm4, %%mm7      \n\t" /* mm7 = y7 y6 y5 y4 */
+
+        /* slot */
+
+        "movq %%mm7, 8(%0)     \n\t" /* save y7 y6 y5 y4 */
+        :: "r" (row+store)
+        );
+}
+
+static inline void mmx_row_mid (int16_t * const row, const int store,
+                                const int offset, const int16_t * const table)
+{
+
+    __asm__ volatile (
+        "movq    (%0,%1), %%mm2    \n\t" /* mm2 = x6 x4 x2 x0 */
+        "psrad $" AV_STRINGIFY(ROW_SHIFT) ", %%mm0 \n\t" /* mm0 = y3 y2 */
+
+        "movq   8(%0,%1), %%mm5    \n\t" /* mm5 = x7 x5 x3 x1 */
+        "psrad $" AV_STRINGIFY(ROW_SHIFT) ", %%mm7 \n\t" /* mm7 = y4 y5 */
+
+        "packssdw  %%mm0, %%mm1    \n\t" /* mm1 = y3 y2 y1 y0 */
+        "movq      %%mm5, %%mm6    \n\t" /* mm6 = x7 x5 x3 x1 */
+
+        "packssdw  %%mm3, %%mm7    \n\t" /* mm7 = y6 y7 y4 y5 */
+        "movq      %%mm2, %%mm0    \n\t" /* mm0 = x6 x4 x2 x0 */
+
+        "movq      %%mm1, (%0,%2)  \n\t" /* save y3 y2 y1 y0 */
+        "movq      %%mm7, %%mm1    \n\t" /* mm1 = y6 y7 y4 y5 */
+
+        "punpckldq %%mm0, %%mm0    \n\t" /* mm0 = x2 x0 x2 x0 */
+        "psrld       $16, %%mm7    \n\t" /* mm7 = 0 y6 0 y4 */
+
+        "movq       (%3), %%mm3    \n\t" /* mm3 = C6 C4 C2 C4 */
+        "pslld       $16, %%mm1    \n\t" /* mm1 = y7 0 y5 0 */
+
+        "movq      8(%3), %%mm4    \n\t" /* mm4 = -C2 -C4 C6 C4 */
+        "por       %%mm1, %%mm7    \n\t" /* mm7 = y7 y6 y5 y4 */
+
+        "movq     16(%3), %%mm1    \n\t" /* mm1 = -C7 C3 C3 C1 */
+        "punpckhdq %%mm2, %%mm2    \n\t" /* mm2 = x6 x4 x6 x4 */
+
+        "movq      %%mm7, 8(%0,%2) \n\t" /* save y7 y6 y5 y4 */
+        "pmaddwd   %%mm0, %%mm3    \n\t" /* mm3 = C4*x0+C6*x2 C4*x0+C2*x2 */
+        : : "r" (row), "r" ((x86_reg) (2*offset)), "r" ((x86_reg) (2*store)), "r" (table)
+        );
+}
+
+
+#if 0
+/* C column IDCT - it is just here to document the MMXEXT and MMX versions */
+static inline void idct_col (int16_t * col, int offset)
+{
+/* multiplication - as implemented on mmx */
+#define F(c,x) (((c) * (x)) >> 16)
+
+/* saturation - it helps us handle torture test cases */
+#define S(x) (((x)>32767) ? 32767 : ((x)<-32768) ? -32768 : (x))
+
+    int16_t x0, x1, x2, x3, x4, x5, x6, x7;
+    int16_t y0, y1, y2, y3, y4, y5, y6, y7;
+    int16_t a0, a1, a2, a3, b0, b1, b2, b3;
+    int16_t u04, v04, u26, v26, u17, v17, u35, v35, u12, v12;
+
+    col += offset;
+
+    x0 = col[0*8];
+    x1 = col[1*8];
+    x2 = col[2*8];
+    x3 = col[3*8];
+    x4 = col[4*8];
+    x5 = col[5*8];
+    x6 = col[6*8];
+    x7 = col[7*8];
+
+    u04 = S (x0 + x4);
+    v04 = S (x0 - x4);
+    u26 = S (F (T2, x6) + x2);
+    v26 = S (F (T2, x2) - x6);
+
+    a0 = S (u04 + u26);
+    a1 = S (v04 + v26);
+    a2 = S (v04 - v26);
+    a3 = S (u04 - u26);
+
+    u17 = S (F (T1, x7) + x1);
+    v17 = S (F (T1, x1) - x7);
+    u35 = S (F (T3, x5) + x3);
+    v35 = S (F (T3, x3) - x5);
+
+    b0 = S (u17 + u35);
+    b3 = S (v17 - v35);
+    u12 = S (u17 - u35);
+    v12 = S (v17 + v35);
+    u12 = S (2 * F (C4, u12));
+    v12 = S (2 * F (C4, v12));
+    b1 = S (u12 + v12);
+    b2 = S (u12 - v12);
+
+    y0 = S (a0 + b0) >> COL_SHIFT;
+    y1 = S (a1 + b1) >> COL_SHIFT;
+    y2 = S (a2 + b2) >> COL_SHIFT;
+    y3 = S (a3 + b3) >> COL_SHIFT;
+
+    y4 = S (a3 - b3) >> COL_SHIFT;
+    y5 = S (a2 - b2) >> COL_SHIFT;
+    y6 = S (a1 - b1) >> COL_SHIFT;
+    y7 = S (a0 - b0) >> COL_SHIFT;
+
+    col[0*8] = y0;
+    col[1*8] = y1;
+    col[2*8] = y2;
+    col[3*8] = y3;
+    col[4*8] = y4;
+    col[5*8] = y5;
+    col[6*8] = y6;
+    col[7*8] = y7;
+}
+#endif
+
+
+/* MMX column IDCT */
+static inline void idct_col (int16_t * const col, const int offset)
+{
+#define T1 13036
+#define T2 27146
+#define T3 43790
+#define C4 23170
+
+    DECLARE_ALIGNED(8, static const short, t1_vector)[] = {
+        T1,T1,T1,T1,
+        T2,T2,T2,T2,
+        T3,T3,T3,T3,
+        C4,C4,C4,C4
+    };
+
+    /* column code adapted from Peter Gubanov */
+    /* http://www.elecard.com/peter/idct.shtml */
+
+    __asm__ volatile (
+        "movq      (%0), %%mm0    \n\t" /* mm0 = T1 */
+
+        "movq   2*8(%1), %%mm1    \n\t" /* mm1 = x1 */
+        "movq     %%mm0, %%mm2    \n\t" /* mm2 = T1 */
+
+        "movq 7*2*8(%1), %%mm4    \n\t" /* mm4 = x7 */
+        "pmulhw   %%mm1, %%mm0    \n\t" /* mm0 = T1*x1 */
+
+        "movq    16(%0), %%mm5    \n\t" /* mm5 = T3 */
+        "pmulhw   %%mm4, %%mm2    \n\t" /* mm2 = T1*x7 */
+
+        "movq 2*5*8(%1), %%mm6    \n\t" /* mm6 = x5 */
+        "movq     %%mm5, %%mm7    \n\t" /* mm7 = T3-1 */
+
+        "movq 3*8*2(%1), %%mm3    \n\t" /* mm3 = x3 */
+        "psubsw   %%mm4, %%mm0    \n\t" /* mm0 = v17 */
+
+        "movq     8(%0), %%mm4    \n\t" /* mm4 = T2 */
+        "pmulhw   %%mm3, %%mm5    \n\t" /* mm5 = (T3-1)*x3 */
+
+        "paddsw   %%mm2, %%mm1    \n\t" /* mm1 = u17 */
+        "pmulhw   %%mm6, %%mm7    \n\t" /* mm7 = (T3-1)*x5 */
+
+        /* slot */
+
+        "movq     %%mm4, %%mm2    \n\t" /* mm2 = T2 */
+        "paddsw   %%mm3, %%mm5    \n\t" /* mm5 = T3*x3 */
+
+        "pmulhw 2*8*2(%1), %%mm4  \n\t" /* mm4 = T2*x2 */
+        "paddsw   %%mm6, %%mm7    \n\t" /* mm7 = T3*x5 */
+
+        "psubsw   %%mm6, %%mm5    \n\t" /* mm5 = v35 */
+        "paddsw   %%mm3, %%mm7    \n\t" /* mm7 = u35 */
+
+        "movq 6*8*2(%1), %%mm3    \n\t" /* mm3 = x6 */
+        "movq     %%mm0, %%mm6    \n\t" /* mm6 = v17 */
+
+        "pmulhw   %%mm3, %%mm2    \n\t" /* mm2 = T2*x6 */
+        "psubsw   %%mm5, %%mm0    \n\t" /* mm0 = b3 */
+
+        "psubsw   %%mm3, %%mm4    \n\t" /* mm4 = v26 */
+        "paddsw   %%mm6, %%mm5    \n\t" /* mm5 = v12 */
+
+        "movq     %%mm0, 3*8*2(%1)\n\t" /* save b3 in scratch0 */
+        "movq     %%mm1, %%mm6    \n\t" /* mm6 = u17 */
+
+        "paddsw 2*8*2(%1), %%mm2  \n\t" /* mm2 = u26 */
+        "paddsw   %%mm7, %%mm6    \n\t" /* mm6 = b0 */
+
+        "psubsw   %%mm7, %%mm1    \n\t" /* mm1 = u12 */
+        "movq     %%mm1, %%mm7    \n\t" /* mm7 = u12 */
+
+        "movq   0*8(%1), %%mm3    \n\t" /* mm3 = x0 */
+        "paddsw   %%mm5, %%mm1    \n\t" /* mm1 = u12+v12 */
+
+        "movq    24(%0), %%mm0    \n\t" /* mm0 = C4/2 */
+        "psubsw   %%mm5, %%mm7    \n\t" /* mm7 = u12-v12 */
+
+        "movq     %%mm6, 5*8*2(%1)\n\t" /* save b0 in scratch1 */
+        "pmulhw   %%mm0, %%mm1    \n\t" /* mm1 = b1/2 */
+
+        "movq     %%mm4, %%mm6    \n\t" /* mm6 = v26 */
+        "pmulhw   %%mm0, %%mm7    \n\t" /* mm7 = b2/2 */
+
+        "movq 4*8*2(%1), %%mm5    \n\t" /* mm5 = x4 */
+        "movq     %%mm3, %%mm0    \n\t" /* mm0 = x0 */
+
+        "psubsw   %%mm5, %%mm3    \n\t" /* mm3 = v04 */
+        "paddsw   %%mm5, %%mm0    \n\t" /* mm0 = u04 */
+
+        "paddsw   %%mm3, %%mm4    \n\t" /* mm4 = a1 */
+        "movq     %%mm0, %%mm5    \n\t" /* mm5 = u04 */
+
+        "psubsw   %%mm6, %%mm3    \n\t" /* mm3 = a2 */
+        "paddsw   %%mm2, %%mm5    \n\t" /* mm5 = a0 */
+
+        "paddsw   %%mm1, %%mm1    \n\t" /* mm1 = b1 */
+        "psubsw   %%mm2, %%mm0    \n\t" /* mm0 = a3 */
+
+        "paddsw   %%mm7, %%mm7    \n\t" /* mm7 = b2 */
+        "movq     %%mm3, %%mm2    \n\t" /* mm2 = a2 */
+
+        "movq     %%mm4, %%mm6    \n\t" /* mm6 = a1 */
+        "paddsw   %%mm7, %%mm3    \n\t" /* mm3 = a2+b2 */
+
+        "psraw $" AV_STRINGIFY(COL_SHIFT) ", %%mm3\n\t" /* mm3 = y2 */
+        "paddsw   %%mm1, %%mm4\n\t" /* mm4 = a1+b1 */
+
+        "psraw $" AV_STRINGIFY(COL_SHIFT) ", %%mm4\n\t" /* mm4 = y1 */
+        "psubsw   %%mm1, %%mm6    \n\t" /* mm6 = a1-b1 */
+
+        "movq 5*8*2(%1), %%mm1    \n\t" /* mm1 = b0 */
+        "psubsw   %%mm7, %%mm2    \n\t" /* mm2 = a2-b2 */
+
+        "psraw $" AV_STRINGIFY(COL_SHIFT) ", %%mm6\n\t" /* mm6 = y6 */
+        "movq     %%mm5, %%mm7    \n\t" /* mm7 = a0 */
+
+        "movq     %%mm4, 1*8*2(%1)\n\t" /* save y1 */
+        "psraw $" AV_STRINGIFY(COL_SHIFT) ", %%mm2\n\t" /* mm2 = y5 */
+
+        "movq     %%mm3, 2*8*2(%1)\n\t" /* save y2 */
+        "paddsw   %%mm1, %%mm5    \n\t" /* mm5 = a0+b0 */
+
+        "movq 3*8*2(%1), %%mm4    \n\t" /* mm4 = b3 */
+        "psubsw   %%mm1, %%mm7    \n\t" /* mm7 = a0-b0 */
+
+        "psraw $" AV_STRINGIFY(COL_SHIFT) ", %%mm5\n\t" /* mm5 = y0 */
+        "movq     %%mm0, %%mm3    \n\t" /* mm3 = a3 */
+
+        "movq     %%mm2, 5*8*2(%1)\n\t" /* save y5 */
+        "psubsw   %%mm4, %%mm3    \n\t" /* mm3 = a3-b3 */
+
+        "psraw $" AV_STRINGIFY(COL_SHIFT) ", %%mm7\n\t" /* mm7 = y7 */
+        "paddsw   %%mm0, %%mm4    \n\t" /* mm4 = a3+b3 */
+
+        "movq     %%mm5, 0*8*2(%1)\n\t" /* save y0 */
+        "psraw $" AV_STRINGIFY(COL_SHIFT) ", %%mm3\n\t" /* mm3 = y4 */
+
+        "movq     %%mm6, 6*8*2(%1)\n\t" /* save y6 */
+        "psraw $" AV_STRINGIFY(COL_SHIFT) ", %%mm4\n\t" /* mm4 = y3 */
+
+        "movq     %%mm7, 7*8*2(%1)\n\t" /* save y7 */
+
+        "movq     %%mm3, 4*8*2(%1)\n\t" /* save y4 */
+
+        "movq     %%mm4, 3*8*2(%1)\n\t" /* save y3 */
+        :: "r" (t1_vector), "r" (col+offset)
+        );
+
+#undef T1
+#undef T2
+#undef T3
+#undef C4
+}
+
+
+DECLARE_ALIGNED(8, static const int32_t, rounder0)[] =
+    rounder ((1 << (COL_SHIFT - 1)) - 0.5);
+DECLARE_ALIGNED(8, static const int32_t, rounder4)[] = rounder (0);
+DECLARE_ALIGNED(8, static const int32_t, rounder1)[] =
+    rounder (1.25683487303);        /* C1*(C1/C4+C1+C7)/2 */
+DECLARE_ALIGNED(8, static const int32_t, rounder7)[] =
+    rounder (-0.25);                /* C1*(C7/C4+C7-C1)/2 */
+DECLARE_ALIGNED(8, static const int32_t, rounder2)[] =
+    rounder (0.60355339059);        /* C2 * (C6+C2)/2 */
+DECLARE_ALIGNED(8, static const int32_t, rounder6)[] =
+    rounder (-0.25);                /* C2 * (C6-C2)/2 */
+DECLARE_ALIGNED(8, static const int32_t, rounder3)[] =
+    rounder (0.087788325588);       /* C3*(-C3/C4+C3+C5)/2 */
+DECLARE_ALIGNED(8, static const int32_t, rounder5)[] =
+    rounder (-0.441341716183);      /* C3*(-C5/C4+C5-C3)/2 */
+
+#undef COL_SHIFT
+#undef ROW_SHIFT
+
+#define declare_idct(idct,table,idct_row_head,idct_row,idct_row_tail,idct_row_mid) \
+void idct (int16_t * const block)                                       \
+{                                                                       \
+    DECLARE_ALIGNED(16, static const int16_t, table04)[] =              \
+        table (22725, 21407, 19266, 16384, 12873,  8867, 4520);         \
+    DECLARE_ALIGNED(16, static const int16_t, table17)[] =              \
+        table (31521, 29692, 26722, 22725, 17855, 12299, 6270);         \
+    DECLARE_ALIGNED(16, static const int16_t, table26)[] =              \
+        table (29692, 27969, 25172, 21407, 16819, 11585, 5906);         \
+    DECLARE_ALIGNED(16, static const int16_t, table35)[] =              \
+        table (26722, 25172, 22654, 19266, 15137, 10426, 5315);         \
+                                                                        \
+    idct_row_head (block, 0*8, table04);                                \
+    idct_row (table04, rounder0);                                       \
+    idct_row_mid (block, 0*8, 4*8, table04);                            \
+    idct_row (table04, rounder4);                                       \
+    idct_row_mid (block, 4*8, 1*8, table17);                            \
+    idct_row (table17, rounder1);                                       \
+    idct_row_mid (block, 1*8, 7*8, table17);                            \
+    idct_row (table17, rounder7);                                       \
+    idct_row_mid (block, 7*8, 2*8, table26);                            \
+    idct_row (table26, rounder2);                                       \
+    idct_row_mid (block, 2*8, 6*8, table26);                            \
+    idct_row (table26, rounder6);                                       \
+    idct_row_mid (block, 6*8, 3*8, table35);                            \
+    idct_row (table35, rounder3);                                       \
+    idct_row_mid (block, 3*8, 5*8, table35);                            \
+    idct_row (table35, rounder5);                                       \
+    idct_row_tail (block, 5*8);                                         \
+                                                                        \
+    idct_col (block, 0);                                                \
+    idct_col (block, 4);                                                \
+}
+
+declare_idct (ff_mmxext_idct, mmxext_table,
+              mmxext_row_head, mmxext_row, mmxext_row_tail, mmxext_row_mid)
+
+declare_idct (ff_mmx_idct, mmx_table,
+              mmx_row_head, mmx_row, mmx_row_tail, mmx_row_mid)
+
+#endif /* HAVE_INLINE_ASM */
diff --git a/libavcodec/x86/idct_mmx_xvid.c b/libavcodec/x86/idct_mmx_xvid.c
index 08a627d..2465cdf 100644
--- a/libavcodec/x86/idct_mmx_xvid.c
+++ b/libavcodec/x86/idct_mmx_xvid.c
@@ -22,20 +22,20 @@
  *
  * conversion to gcc syntax by Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public License
- * along with Libav; if not, write to the Free Software Foundation,
+ * along with FFmpeg; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/idct_sse2_xvid.c b/libavcodec/x86/idct_sse2_xvid.c
index fe2478e..d121b25 100644
--- a/libavcodec/x86/idct_sse2_xvid.c
+++ b/libavcodec/x86/idct_sse2_xvid.c
@@ -9,7 +9,7 @@
  *
  * Originally from dct/x86_asm/fdct_sse2_skal.asm in Xvid.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
  * Vertical pass is an implementation of the scheme:
  *  Loeffler C., Ligtenberg A., and Moschytz C.S.:
@@ -23,23 +23,22 @@
  *
  * More details at http://skal.planet-d.net/coding/dct.html
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public License
- * along with Libav; if not, write to the Free Software Foundation,
+ * 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 "libavutil/internal.h"
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
 #include "idct_xvid.h"
diff --git a/libavcodec/x86/idct_xvid.h b/libavcodec/x86/idct_xvid.h
index 82fa990..6000654 100644
--- a/libavcodec/x86/idct_xvid.h
+++ b/libavcodec/x86/idct_xvid.h
@@ -1,20 +1,20 @@
 /*
  * XVID MPEG-4 VIDEO CODEC
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/imdct36.asm b/libavcodec/x86/imdct36.asm
index 937a2cc..50b6902 100644
--- a/libavcodec/x86/imdct36.asm
+++ b/libavcodec/x86/imdct36.asm
@@ -2,20 +2,20 @@
 ;* 36 point SSE-optimized IMDCT transform
 ;* Copyright (c) 2011 Vitor Sessak
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
@@ -371,8 +371,10 @@
 INIT_XMM ssse3
 DEFINE_IMDCT
 
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 DEFINE_IMDCT
+%endif
 
 INIT_XMM sse
 
@@ -717,5 +719,7 @@
 INIT_XMM sse
 DEFINE_FOUR_IMDCT
 
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 DEFINE_FOUR_IMDCT
+%endif
diff --git a/libavcodec/x86/lpc.c b/libavcodec/x86/lpc.c
index b8c77e2..a66f1e0 100644
--- a/libavcodec/x86/lpc.c
+++ b/libavcodec/x86/lpc.c
@@ -2,26 +2,25 @@
  * MMX optimized LPC DSP utils
  * Copyright (c) 2007 Loren Merritt
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/x86/asm.h"
 #include "libavutil/cpu.h"
-#include "libavutil/internal.h"
 #include "libavcodec/lpc.h"
 
 #if HAVE_SSE2_INLINE
diff --git a/libavcodec/x86/mathops.h b/libavcodec/x86/mathops.h
index cd408ac..79e29e6 100644
--- a/libavcodec/x86/mathops.h
+++ b/libavcodec/x86/mathops.h
@@ -2,20 +2,20 @@
  * simple math operations
  * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> et al
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/mlpdsp.c b/libavcodec/x86/mlpdsp.c
index a18e9fa..de28e22 100644
--- a/libavcodec/x86/mlpdsp.c
+++ b/libavcodec/x86/mlpdsp.c
@@ -2,24 +2,23 @@
  * MLP DSP functions x86-optimized
  * Copyright (c) 2009 Ramiro Polla
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/internal.h"
 #include "libavutil/x86/asm.h"
 #include "libavcodec/mlpdsp.h"
 #include "libavcodec/mlp.h"
diff --git a/libavcodec/x86/motion_est.c b/libavcodec/x86/motion_est.c
index 6eb44d4..b77d402 100644
--- a/libavcodec/x86/motion_est.c
+++ b/libavcodec/x86/motion_est.c
@@ -5,24 +5,24 @@
  *
  * mostly by Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/internal.h"
+#include "libavutil/avassert.h"
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
 #include "libavcodec/dsputil.h"
@@ -327,7 +327,7 @@
 #define PIX_SAD(suf)\
 static int sad8_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)\
 {\
-    assert(h==8);\
+    av_assert2(h==8);\
     __asm__ volatile("pxor %%mm7, %%mm7     \n\t"\
                  "pxor %%mm6, %%mm6     \n\t":);\
 \
@@ -337,7 +337,7 @@
 }\
 static int sad8_x2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)\
 {\
-    assert(h==8);\
+    av_assert2(h==8);\
     __asm__ volatile("pxor %%mm7, %%mm7     \n\t"\
                  "pxor %%mm6, %%mm6     \n\t"\
                  "movq %0, %%mm5        \n\t"\
@@ -351,7 +351,7 @@
 \
 static int sad8_y2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)\
 {\
-    assert(h==8);\
+    av_assert2(h==8);\
     __asm__ volatile("pxor %%mm7, %%mm7     \n\t"\
                  "pxor %%mm6, %%mm6     \n\t"\
                  "movq %0, %%mm5        \n\t"\
@@ -365,7 +365,7 @@
 \
 static int sad8_xy2_ ## suf(void *v, uint8_t *blk2, uint8_t *blk1, int stride, int h)\
 {\
-    assert(h==8);\
+    av_assert2(h==8);\
     __asm__ volatile("pxor %%mm7, %%mm7     \n\t"\
                  "pxor %%mm6, %%mm6     \n\t"\
                  ::);\
diff --git a/libavcodec/x86/mpegaudiodec.c b/libavcodec/x86/mpegaudiodec.c
index c914fe1..44cbf9a 100644
--- a/libavcodec/x86/mpegaudiodec.c
+++ b/libavcodec/x86/mpegaudiodec.c
@@ -2,20 +2,20 @@
  * MMX optimized MP3 decoding functions
  * Copyright (c) 2010 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,11 +25,16 @@
 #include "libavcodec/dsputil.h"
 #include "libavcodec/mpegaudiodsp.h"
 
-void ff_imdct36_float_sse(float *out, float *buf, float *in, float *win);
-void ff_imdct36_float_sse2(float *out, float *buf, float *in, float *win);
-void ff_imdct36_float_sse3(float *out, float *buf, float *in, float *win);
-void ff_imdct36_float_ssse3(float *out, float *buf, float *in, float *win);
-void ff_imdct36_float_avx(float *out, float *buf, float *in, float *win);
+#define DECL(CPU)\
+static void imdct36_blocks_ ## CPU(float *out, float *buf, float *in, int count, int switch_point, int block_type);\
+void ff_imdct36_float_ ## CPU(float *out, float *buf, float *in, float *win);
+
+DECL(sse)
+DECL(sse2)
+DECL(sse3)
+DECL(ssse3)
+DECL(avx)
+
 void ff_four_imdct36_float_sse(float *out, float *buf, float *in, float *win,
                                float *tmpbuf);
 void ff_four_imdct36_float_avx(float *out, float *buf, float *in, float *win,
@@ -216,11 +221,15 @@
     }                                                                   \
 }
 
+#if HAVE_SSE
 DECL_IMDCT_BLOCKS(sse,sse)
 DECL_IMDCT_BLOCKS(sse2,sse)
 DECL_IMDCT_BLOCKS(sse3,sse)
 DECL_IMDCT_BLOCKS(ssse3,sse)
+#endif
+#if HAVE_AVX_EXTERNAL
 DECL_IMDCT_BLOCKS(avx,avx)
+#endif
 #endif /* HAVE_YASM */
 
 void ff_mpadsp_init_x86(MPADSPContext *s)
diff --git a/libavcodec/x86/mpegvideo.c b/libavcodec/x86/mpegvideo.c
index 3bc93f3..7c7ca87 100644
--- a/libavcodec/x86/mpegvideo.c
+++ b/libavcodec/x86/mpegvideo.c
@@ -2,20 +2,20 @@
  * Optimized for ia32 CPUs by Nick Kurshev <nickols_k@mail.ru>
  * h263, mpeg1, mpeg2 dequantizer & draw_edges by Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/mpegvideoenc.c b/libavcodec/x86/mpegvideoenc.c
index 59e3580..ee2b25f 100644
--- a/libavcodec/x86/mpegvideoenc.c
+++ b/libavcodec/x86/mpegvideoenc.c
@@ -2,20 +2,20 @@
  * The simplest mpeg encoder (well, it was the simplest!)
  * Copyright (c) 2000,2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -80,7 +80,7 @@
 #include "mpegvideoenc_template.c"
 #endif /* HAVE_SSSE3_INLINE */
 
-void ff_MPV_encode_init_x86(MpegEncContext *s)
+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 a6e7ba4..d874f39 100644
--- a/libavcodec/x86/mpegvideoenc_template.c
+++ b/libavcodec/x86/mpegvideoenc_template.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -110,10 +110,15 @@
 
     if (s->mb_intra) {
         int dummy;
-        if (n < 4)
+        if (n < 4){
             q = s->y_dc_scale;
-        else
+            bias = s->q_intra_matrix16[qscale][1];
+            qmat = s->q_intra_matrix16[qscale][0];
+        }else{
             q = s->c_dc_scale;
+            bias = s->q_chroma_intra_matrix16[qscale][1];
+            qmat = s->q_chroma_intra_matrix16[qscale][0];
+        }
         /* note: block[0] is assumed to be positive */
         if (!s->h263_aic) {
         __asm__ volatile (
@@ -128,8 +133,6 @@
         block[0]=0; //avoid fake overflow
 //        temp_block[0] = (block[0] + (q >> 1)) / q;
         last_non_zero_p1 = 1;
-        bias = s->q_intra_matrix16[qscale][1];
-        qmat = s->q_intra_matrix16[qscale][0];
     } else {
         last_non_zero_p1 = 0;
         bias = s->q_inter_matrix16[qscale][1];
diff --git a/libavcodec/x86/pngdsp_init.c b/libavcodec/x86/pngdsp_init.c
index 213b854..05fd051 100644
--- a/libavcodec/x86/pngdsp_init.c
+++ b/libavcodec/x86/pngdsp_init.c
@@ -2,20 +2,20 @@
  * x86 PNG optimizations.
  * Copyright (c) 2008 Loren Merrit <lorenm@u.washington.edu>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/proresdsp.asm b/libavcodec/x86/proresdsp.asm
index bce36ac..41f1087 100644
--- a/libavcodec/x86/proresdsp.asm
+++ b/libavcodec/x86/proresdsp.asm
@@ -1,23 +1,24 @@
 ;******************************************************************************
 ;* x86-SIMD-optimized IDCT for prores
-;* this is identical to "simple" IDCT except for the clip range
+;* this is identical to "simple" IDCT written by Michael Niedermayer
+;* except for the clip range
 ;*
 ;* Copyright (c) 2011 Ronald S. Bultje <rsbultje@gmail.com>
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
@@ -48,10 +49,10 @@
 w5_min_w1:  times 4 dw W5sh2, -W1sh2
 w5_plus_w7: times 4 dw W5sh2, +W7sh2
 w7_min_w5:  times 4 dw W7sh2, -W5sh2
-row_round:  times 8 dw (1<<14)
+pw_88:      times 8 dw 0x2008
 
+cextern pw_1
 cextern pw_4
-cextern pw_8
 cextern pw_512
 cextern pw_1019
 
@@ -92,14 +93,12 @@
     ; a2 -= W6 * row[2];
     ; a3 -= W2 * row[2];
 %ifidn %1, col
-    paddw       m10,[pw_8]
+    paddw       m10,[pw_88]
+%endif
+%ifidn %1, row
+    paddw       m10,[pw_1]
 %endif
     SBUTTERFLY3 wd,  0,  1, 10,  8 ; { row[0], row[2] }[0-3]/[4-7]
-%ifidn %1, row
-    psubw       m10,[row_round]
-%endif
-    SIGNEXTEND  m8,  m9,  m14      ; { row[2] }[0-3] / [4-7]
-    SIGNEXTEND  m10, m11, m14      ; { row[0] }[0-3] / [4-7]
     pmaddwd     m2,  m0, [w4_plus_w6]
     pmaddwd     m3,  m1, [w4_plus_w6]
     pmaddwd     m4,  m0, [w4_min_w6]
@@ -108,75 +107,33 @@
     pmaddwd     m7,  m1, [w4_min_w2]
     pmaddwd     m0, [w4_plus_w2]
     pmaddwd     m1, [w4_plus_w2]
-    pslld       m2,  2
-    pslld       m3,  2
-    pslld       m4,  2
-    pslld       m5,  2
-    pslld       m6,  2
-    pslld       m7,  2
-    pslld       m0,  2
-    pslld       m1,  2
 
     ; a0: -1*row[0]-1*row[2]
     ; a1: -1*row[0]
     ; a2: -1*row[0]
     ; a3: -1*row[0]+1*row[2]
-    psubd       m2,  m10           ; a1[0-3]
-    psubd       m3,  m11           ; a1[4-7]
-    psubd       m4,  m10           ; a2[0-3]
-    psubd       m5,  m11           ; a2[4-7]
-    psubd       m0,  m10
-    psubd       m1,  m11
-    psubd       m6,  m10
-    psubd       m7,  m11
-    psubd       m0,  m8            ; a0[0-3]
-    psubd       m1,  m9            ; a0[4-7]
-    paddd       m6,  m8            ; a3[0-3]
-    paddd       m7,  m9            ; a3[4-7]
 
     ; a0 +=   W4*row[4] + W6*row[6]; i.e. -1*row[4]
     ; a1 -=   W4*row[4] + W2*row[6]; i.e. -1*row[4]-1*row[6]
     ; a2 -=   W4*row[4] - W2*row[6]; i.e. -1*row[4]+1*row[6]
     ; a3 +=   W4*row[4] - W6*row[6]; i.e. -1*row[4]
     SBUTTERFLY3 wd,  8,  9, 13, 12 ; { row[4], row[6] }[0-3]/[4-7]
-    SIGNEXTEND  m13, m14, m10      ; { row[4] }[0-3] / [4-7]
     pmaddwd     m10, m8, [w4_plus_w6]
     pmaddwd     m11, m9, [w4_plus_w6]
-    pslld       m10, 2
-    pslld       m11, 2
-    psubd       m10,  m13
-    psubd       m11,  m14
     paddd       m0,  m10            ; a0[0-3]
     paddd       m1,  m11            ; a0[4-7]
     pmaddwd     m10, m8, [w4_min_w6]
     pmaddwd     m11, m9, [w4_min_w6]
-    pslld       m10, 2
-    pslld       m11, 2
-    psubd       m10, m13
-    psubd       m11, m14
     paddd       m6,  m10           ; a3[0-3]
     paddd       m7,  m11           ; a3[4-7]
     pmaddwd     m10, m8, [w4_min_w2]
     pmaddwd     m11, m9, [w4_min_w2]
     pmaddwd     m8, [w4_plus_w2]
     pmaddwd     m9, [w4_plus_w2]
-    pslld       m10, 2
-    pslld       m11, 2
-    pslld       m8,  2
-    pslld       m9,  2
-    psubd       m10, m13
-    psubd       m11, m14
-    psubd       m8,  m13
-    psubd       m9,  m14
     psubd       m4,  m10           ; a2[0-3] intermediate
     psubd       m5,  m11           ; a2[4-7] intermediate
     psubd       m2,  m8            ; a1[0-3] intermediate
     psubd       m3,  m9            ; a1[4-7] intermediate
-    SIGNEXTEND  m12, m13, m10      ; { row[6] }[0-3] / [4-7]
-    psubd       m4,  m12           ; a2[0-3]
-    psubd       m5,  m13           ; a2[4-7]
-    paddd       m2,  m12           ; a1[0-3]
-    paddd       m3,  m13           ; a1[4-7]
 
     ; load/store
     mova   [r2+  0], m0
@@ -207,8 +164,6 @@
     ; b3 = MUL(W7, row[1]);
     ; MAC(b3, -W5, row[3]);
     SBUTTERFLY3 wd,  0,  1, 10, 8  ; { row[1], row[3] }[0-3]/[4-7]
-    SIGNEXTEND  m10, m11, m12      ; { row[1] }[0-3] / [4-7]
-    SIGNEXTEND  m8,  m9,  m12      ; { row[3] }[0-3] / [4-7]
     pmaddwd     m2,  m0, [w3_min_w7]
     pmaddwd     m3,  m1, [w3_min_w7]
     pmaddwd     m4,  m0, [w5_min_w1]
@@ -217,35 +172,11 @@
     pmaddwd     m7,  m1, [w7_min_w5]
     pmaddwd     m0, [w1_plus_w3]
     pmaddwd     m1, [w1_plus_w3]
-    pslld       m2,  2
-    pslld       m3,  2
-    pslld       m4,  2
-    pslld       m5,  2
-    pslld       m6,  2
-    pslld       m7,  2
-    pslld       m0,  2
-    pslld       m1,  2
 
     ; b0: +1*row[1]+2*row[3]
     ; b1: +2*row[1]-1*row[3]
     ; b2: -1*row[1]-1*row[3]
     ; b3: +1*row[1]+1*row[3]
-    psubd       m2,  m8
-    psubd       m3,  m9
-    paddd       m0,  m8
-    paddd       m1,  m9
-    paddd       m8,  m10           ; { row[1] + row[3] }[0-3]
-    paddd       m9,  m11           ; { row[1] + row[3] }[4-7]
-    paddd       m10, m10
-    paddd       m11, m11
-    paddd       m0,  m8            ; b0[0-3]
-    paddd       m1,  m9            ; b0[4-7]
-    paddd       m2,  m10           ; b1[0-3]
-    paddd       m3,  m11           ; b2[4-7]
-    psubd       m4,  m8            ; b2[0-3]
-    psubd       m5,  m9            ; b2[4-7]
-    paddd       m6,  m8            ; b3[0-3]
-    paddd       m7,  m9            ; b3[4-7]
 
     ; MAC(b0,  W5, row[5]);
     ; MAC(b0,  W7, row[7]);
@@ -256,38 +187,16 @@
     ; MAC(b3,  W3, row[5]);
     ; MAC(b3, -W1, row[7]);
     SBUTTERFLY3 wd,  8,  9, 13, 14 ; { row[5], row[7] }[0-3]/[4-7]
-    SIGNEXTEND  m13, m12, m11      ; { row[5] }[0-3] / [4-7]
-    SIGNEXTEND  m14, m11, m10      ; { row[7] }[0-3] / [4-7]
 
     ; b0: -1*row[5]+1*row[7]
     ; b1: -1*row[5]+1*row[7]
     ; b2: +1*row[5]+2*row[7]
     ; b3: +2*row[5]-1*row[7]
-    paddd       m4,  m13
-    paddd       m5,  m12
-    paddd       m6,  m13
-    paddd       m7,  m12
-    psubd       m13, m14           ; { row[5] - row[7] }[0-3]
-    psubd       m12, m11           ; { row[5] - row[7] }[4-7]
-    paddd       m14, m14
-    paddd       m11, m11
-    psubd       m0,  m13
-    psubd       m1,  m12
-    psubd       m2,  m13
-    psubd       m3,  m12
-    paddd       m4,  m14
-    paddd       m5,  m11
-    paddd       m6,  m13
-    paddd       m7,  m12
 
     pmaddwd     m10, m8, [w1_plus_w5]
     pmaddwd     m11, m9, [w1_plus_w5]
     pmaddwd     m12, m8, [w5_plus_w7]
     pmaddwd     m13, m9, [w5_plus_w7]
-    pslld       m10, 2
-    pslld       m11, 2
-    pslld       m12,  2
-    pslld       m13,  2
     psubd       m2,  m10           ; b1[0-3]
     psubd       m3,  m11           ; b1[4-7]
     paddd       m0,  m12            ; b0[0-3]
@@ -296,10 +205,6 @@
     pmaddwd     m13, m9, [w7_plus_w3]
     pmaddwd     m8, [w3_min_w1]
     pmaddwd     m9, [w3_min_w1]
-    pslld       m12, 2
-    pslld       m13, 2
-    pslld       m8,  2
-    pslld       m9,  2
     paddd       m4,  m12           ; b2[0-3]
     paddd       m5,  m13           ; b2[4-7]
     paddd       m6,  m8            ; b3[0-3]
@@ -346,7 +251,7 @@
     pmullw      m13,[r3+64]
     pmullw      m12,[r3+96]
 
-    IDCT_1D     row, 17
+    IDCT_1D     row, 15
 
     ; transpose for second part of IDCT
     TRANSPOSE8x8W 8, 0, 1, 2, 4, 11, 9, 10, 3
@@ -361,20 +266,11 @@
 
     ; for (i = 0; i < 8; i++)
     ;     idctSparseColAdd(dest + i, line_size, block + i);
-    IDCT_1D     col, 20
+    IDCT_1D     col, 18
 
     ; clip/store
-    mova        m6, [pw_512]
     mova        m3, [pw_4]
     mova        m5, [pw_1019]
-    paddw       m8,  m6
-    paddw       m0,  m6
-    paddw       m1,  m6
-    paddw       m2,  m6
-    paddw       m4,  m6
-    paddw       m11, m6
-    paddw       m9,  m6
-    paddw       m10, m6
     pmaxsw      m8,  m3
     pmaxsw      m0,  m3
     pmaxsw      m1,  m3
@@ -423,7 +319,9 @@
 idct_put_fn 16
 INIT_XMM sse4
 idct_put_fn 16
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 idct_put_fn 16
+%endif
 
 %endif
diff --git a/libavcodec/x86/proresdsp_init.c b/libavcodec/x86/proresdsp_init.c
index 46c26bd..21ce098 100644
--- a/libavcodec/x86/proresdsp_init.c
+++ b/libavcodec/x86/proresdsp_init.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2010-2011 Maxim Poliakovski
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,11 +30,14 @@
 void ff_prores_idct_put_10_avx (uint16_t *dst, int linesize,
                                 DCTELEM *block, const int16_t *qmat);
 
-void ff_proresdsp_x86_init(ProresDSPContext *dsp)
+void ff_proresdsp_x86_init(ProresDSPContext *dsp, AVCodecContext *avctx)
 {
 #if ARCH_X86_64
     int flags = av_get_cpu_flags();
 
+    if(avctx->flags & CODEC_FLAG_BITEXACT)
+        return;
+
     if (EXTERNAL_SSE2(flags)) {
         dsp->idct_permutation_type = FF_TRANSPOSE_IDCT_PERM;
         dsp->idct_put = ff_prores_idct_put_10_sse2;
diff --git a/libavcodec/x86/rv40dsp_init.c b/libavcodec/x86/rv40dsp_init.c
index a7d92f7..902ae19 100644
--- a/libavcodec/x86/rv40dsp_init.c
+++ b/libavcodec/x86/rv40dsp_init.c
@@ -2,20 +2,20 @@
  * RV40 decoder motion compensation functions x86-optimised
  * Copyright (c) 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/simple_idct.c b/libavcodec/x86/simple_idct.c
index 0e80933..c514d75 100644
--- a/libavcodec/x86/simple_idct.c
+++ b/libavcodec/x86/simple_idct.c
@@ -3,25 +3,24 @@
  *
  * Copyright (c) 2001, 2002 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "libavcodec/dsputil.h"
 #include "libavcodec/simple_idct.h"
-#include "libavutil/internal.h"
 #include "libavutil/mem.h"
 #include "dsputil_mmx.h"
 
diff --git a/libavcodec/x86/snowdsp.c b/libavcodec/x86/snowdsp.c
index fb190d8..631291a 100644
--- a/libavcodec/x86/snowdsp.c
+++ b/libavcodec/x86/snowdsp.c
@@ -2,20 +2,20 @@
  * MMX and SSE2 optimized snow DSP utils
  * Copyright (c) 2005-2006 Robert Edele <yartrebo@earthlink.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -675,14 +675,14 @@
 
 #define snow_inner_add_yblock_sse2_end_8\
              "sal $1, %%"REG_c"              \n\t"\
-             "addl $"PTR_SIZE"*2, %1         \n\t"\
+             "add"OPSIZE" $"PTR_SIZE"*2, %1  \n\t"\
              snow_inner_add_yblock_sse2_end_common1\
              "sar $1, %%"REG_c"              \n\t"\
              "sub $2, %2                     \n\t"\
              snow_inner_add_yblock_sse2_end_common2
 
 #define snow_inner_add_yblock_sse2_end_16\
-             "addl $"PTR_SIZE"*1, %1         \n\t"\
+             "add"OPSIZE" $"PTR_SIZE"*1, %1  \n\t"\
              snow_inner_add_yblock_sse2_end_common1\
              "dec %2                         \n\t"\
              snow_inner_add_yblock_sse2_end_common2
diff --git a/libavcodec/x86/v210-init.c b/libavcodec/x86/v210-init.c
new file mode 100644
index 0000000..02c5eaa
--- /dev/null
+++ b/libavcodec/x86/v210-init.c
@@ -0,0 +1,48 @@
+/*
+ * 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/cpu.h"
+#include "libavcodec/v210dec.h"
+
+extern void ff_v210_planar_unpack_unaligned_ssse3(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width);
+extern void ff_v210_planar_unpack_unaligned_avx(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width);
+
+extern void ff_v210_planar_unpack_aligned_ssse3(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width);
+extern void ff_v210_planar_unpack_aligned_avx(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width);
+
+av_cold void v210_x86_init(V210DecContext *s)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+#if HAVE_YASM
+    if (s->aligned_input) {
+        if (cpu_flags & AV_CPU_FLAG_SSSE3)
+            s->unpack_frame = ff_v210_planar_unpack_aligned_ssse3;
+
+        if (HAVE_AVX_EXTERNAL && cpu_flags & AV_CPU_FLAG_AVX)
+            s->unpack_frame = ff_v210_planar_unpack_aligned_avx;
+    }
+    else {
+        if (cpu_flags & AV_CPU_FLAG_SSSE3)
+            s->unpack_frame = ff_v210_planar_unpack_unaligned_ssse3;
+
+        if (HAVE_AVX_EXTERNAL && cpu_flags & AV_CPU_FLAG_AVX)
+            s->unpack_frame = ff_v210_planar_unpack_unaligned_avx;
+    }
+#endif
+}
diff --git a/libavcodec/x86/v210.asm b/libavcodec/x86/v210.asm
new file mode 100644
index 0000000..90305df
--- /dev/null
+++ b/libavcodec/x86/v210.asm
@@ -0,0 +1,89 @@
+;******************************************************************************
+;* V210 SIMD unpack
+;* Copyright (c) 2011 Loren Merritt <lorenm@u.washington.edu>
+;* Copyright (c) 2011 Kieran Kunhya <kieran@kunhya.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
+;******************************************************************************
+
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
+
+SECTION_RODATA
+
+v210_mask: times 4 dd 0x3ff
+v210_mult: dw 64,4,64,4,64,4,64,4
+v210_luma_shuf: db 8,9,0,1,2,3,12,13,4,5,6,7,-1,-1,-1,-1
+v210_chroma_shuf: db 0,1,8,9,6,7,-1,-1,2,3,4,5,12,13,-1,-1
+
+SECTION .text
+
+%macro v210_planar_unpack 2
+
+; v210_planar_unpack(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width)
+cglobal v210_planar_unpack_%1_%2, 5, 5, 7
+    movsxdifnidn r4, r4d
+    lea    r1, [r1+2*r4]
+    add    r2, r4
+    add    r3, r4
+    neg    r4
+
+    mova   m3, [v210_mult]
+    mova   m4, [v210_mask]
+    mova   m5, [v210_luma_shuf]
+    mova   m6, [v210_chroma_shuf]
+.loop
+%ifidn %1, unaligned
+    movu   m0, [r0]
+%else
+    mova   m0, [r0]
+%endif
+
+    pmullw m1, m0, m3
+    psrld  m0, 10
+    psrlw  m1, 6  ; u0 v0 y1 y2 v1 u2 y4 y5
+    pand   m0, m4 ; y0 __ u1 __ y3 __ v2 __
+
+    shufps m2, m1, m0, 0x8d ; y1 y2 y4 y5 y0 __ y3 __
+    pshufb m2, m5 ; y0 y1 y2 y3 y4 y5 __ __
+    movu   [r1+2*r4], m2
+
+    shufps m1, m0, 0xd8 ; u0 v0 v1 u2 u1 __ v2 __
+    pshufb m1, m6 ; u0 u1 u2 __ v0 v1 v2 __
+    movq   [r2+r4], m1
+    movhps [r3+r4], m1
+
+    add r0, mmsize
+    add r4, 6
+    jl  .loop
+
+    REP_RET
+%endmacro
+
+INIT_XMM
+v210_planar_unpack unaligned, ssse3
+%if HAVE_AVX_EXTERNAL
+INIT_AVX
+v210_planar_unpack unaligned, avx
+%endif
+
+INIT_XMM
+v210_planar_unpack aligned, ssse3
+%if HAVE_AVX_EXTERNAL
+INIT_AVX
+v210_planar_unpack aligned, avx
+%endif
diff --git a/libavcodec/x86/vc1dsp.asm b/libavcodec/x86/vc1dsp.asm
index ced2b5b..590aa50 100644
--- a/libavcodec/x86/vc1dsp.asm
+++ b/libavcodec/x86/vc1dsp.asm
@@ -2,25 +2,25 @@
 ;* VC1 deblocking optimizations
 ;* Copyright (c) 2009 David Conrad
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 cextern pw_4
 cextern pw_5
diff --git a/libavcodec/x86/vc1dsp.h b/libavcodec/x86/vc1dsp.h
index 9b6c8ad..fdd4de1 100644
--- a/libavcodec/x86/vc1dsp.h
+++ b/libavcodec/x86/vc1dsp.h
@@ -1,20 +1,20 @@
 /*
  * VC-1 and WMV3 decoder - X86 DSP init functions
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/vc1dsp_mmx.c b/libavcodec/x86/vc1dsp_mmx.c
index 6b1ae37..adf89b2 100644
--- a/libavcodec/x86/vc1dsp_mmx.c
+++ b/libavcodec/x86/vc1dsp_mmx.c
@@ -25,7 +25,6 @@
  */
 
 #include "libavutil/cpu.h"
-#include "libavutil/internal.h"
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
diff --git a/libavcodec/x86/vp3dsp.asm b/libavcodec/x86/vp3dsp.asm
index 7a88892..dcd55f5 100644
--- a/libavcodec/x86/vp3dsp.asm
+++ b/libavcodec/x86/vp3dsp.asm
@@ -2,25 +2,25 @@
 ;* MMX/SSE2-optimized functions for the VP3 decoder
 ;* Copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org>
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 ; MMX-optimized functions cribbed from the original VP3 source code.
 
diff --git a/libavcodec/x86/vp3dsp_init.c b/libavcodec/x86/vp3dsp_init.c
index d91050e..c4d462b 100644
--- a/libavcodec/x86/vp3dsp_init.c
+++ b/libavcodec/x86/vp3dsp_init.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/vp56_arith.h b/libavcodec/x86/vp56_arith.h
index 0a69368..e71dbf8 100644
--- a/libavcodec/x86/vp56_arith.h
+++ b/libavcodec/x86/vp56_arith.h
@@ -4,20 +4,20 @@
  * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
  * Copyright (C) 2010  Eli Friedman
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/vp56dsp.asm b/libavcodec/x86/vp56dsp.asm
index d80680f..bc09903 100644
--- a/libavcodec/x86/vp56dsp.asm
+++ b/libavcodec/x86/vp56dsp.asm
@@ -3,25 +3,25 @@
 ;* Copyright (C) 2009  Sebastien Lucas <sebastien.lucas@gmail.com>
 ;* Copyright (C) 2009  Zuxy Meng <zuxy.meng@gmail.com>
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 cextern pw_64
 
diff --git a/libavcodec/x86/vp56dsp_init.c b/libavcodec/x86/vp56dsp_init.c
index 3b49df6..b699f79 100644
--- a/libavcodec/x86/vp56dsp_init.c
+++ b/libavcodec/x86/vp56dsp_init.c
@@ -3,20 +3,20 @@
  * Copyright (C) 2009  Sebastien Lucas <sebastien.lucas@gmail.com>
  * Copyright (C) 2009  Zuxy Meng <zuxy.meng@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/x86/vp8dsp.asm b/libavcodec/x86/vp8dsp.asm
index ab58e95..19853c4 100644
--- a/libavcodec/x86/vp8dsp.asm
+++ b/libavcodec/x86/vp8dsp.asm
@@ -3,25 +3,25 @@
 ;* Copyright (c) 2010 Ronald S. Bultje <rsbultje@gmail.com>
 ;* Copyright (c) 2010 Jason Garrett-Glaser <darkshikari@gmail.com>
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
-%include "x86inc.asm"
-%include "x86util.asm"
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
 
 SECTION_RODATA
 
diff --git a/libavcodec/x86/vp8dsp_init.c b/libavcodec/x86/vp8dsp_init.c
index 38ad0c7..a9f2740 100644
--- a/libavcodec/x86/vp8dsp_init.c
+++ b/libavcodec/x86/vp8dsp_init.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2010 Ronald S. Bultje <rsbultje@gmail.com>
  * Copyright (c) 2010 Jason Garrett-Glaser <darkshikari@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/xan.c b/libavcodec/xan.c
index 586320b..f11f1bf 100644
--- a/libavcodec/xan.c
+++ b/libavcodec/xan.c
@@ -2,20 +2,20 @@
  * Wing Commander/Xan Video Decoder
  * Copyright (C) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -91,6 +91,8 @@
         av_freep(&s->buffer1);
         return AVERROR(ENOMEM);
     }
+    avcodec_get_frame_defaults(&s->last_frame);
+    avcodec_get_frame_defaults(&s->current_frame);
 
     return 0;
 }
@@ -286,6 +288,7 @@
     const unsigned char *size_segment;
     const unsigned char *vector_segment;
     const unsigned char *imagedata_segment;
+    const unsigned char *buf_end = s->buf + s->size;
     int huffman_offset, size_offset, vector_offset, imagedata_offset,
         imagedata_size;
 
@@ -390,6 +393,10 @@
                 imagedata_size -= size;
             }
         } else {
+            if (vector_segment >= buf_end) {
+                av_log(s->avctx, AV_LOG_ERROR, "vector_segment overread\n");
+                return AVERROR_INVALIDDATA;
+            }
             /* run-based motion compensation from last frame */
             motion_x = sign_extend(*vector_segment >> 4,  4);
             motion_y = sign_extend(*vector_segment & 0xF, 4);
@@ -510,6 +517,10 @@
             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:
@@ -533,7 +544,7 @@
                     int g = gamma_lookup[*buf++];
                     int b = gamma_lookup[*buf++];
 #endif
-                    *tmpptr++ = (r << 16) | (g << 8) | b;
+                    *tmpptr++ = (0xFFU << 24) | (r << 16) | (g << 8) | b;
                 }
                 s->palettes_count++;
                 break;
diff --git a/libavcodec/xbmdec.c b/libavcodec/xbmdec.c
new file mode 100644
index 0000000..130328f
--- /dev/null
+++ b/libavcodec/xbmdec.c
@@ -0,0 +1,137 @@
+/*
+ * XBM image format
+ *
+ * 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 "avcodec.h"
+#include "internal.h"
+
+static av_cold int xbm_decode_init(AVCodecContext *avctx)
+{
+    avctx->coded_frame = avcodec_alloc_frame();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
+
+    return 0;
+}
+
+static int convert(uint8_t x)
+{
+    if (x >= 'a')
+        x -= 87;
+    else if (x >= 'A')
+        x -= 55;
+    else
+        x -= '0';
+    return x;
+}
+
+static int xbm_decode_frame(AVCodecContext *avctx, void *data,
+                            int *data_size, AVPacket *avpkt)
+{
+    AVFrame *p = avctx->coded_frame;
+    const uint8_t *end, *ptr = avpkt->data;
+    uint8_t *dst;
+    int ret, linesize, i, j;
+
+    end = avpkt->data + avpkt->size;
+    while (!avctx->width || !avctx->height) {
+        char name[256];
+        int number, len;
+
+        ptr += strcspn(ptr, "#");
+        if (sscanf(ptr, "#define %256s %u", name, &number) != 2) {
+            av_log(avctx, AV_LOG_ERROR, "Unexpected preprocessor directive\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        len = strlen(name);
+        if ((len > 6) && !avctx->height && !memcmp(name + len - 7, "_height", 7)) {
+                avctx->height = number;
+        } else if ((len > 5) && !avctx->width && !memcmp(name + len - 6, "_width", 6)) {
+                avctx->width = number;
+        } else {
+            av_log(avctx, AV_LOG_ERROR, "Unknown define '%s'\n", name);
+            return AVERROR_INVALIDDATA;
+        }
+        ptr += strcspn(ptr, "\n\r") + 1;
+    }
+
+    avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
+
+    if (p->data[0])
+        avctx->release_buffer(avctx, p);
+
+    p->reference = 0;
+    if ((ret = avctx->get_buffer(avctx, p)) < 0)
+        return ret;
+
+    // goto start of image data
+    ptr += strcspn(ptr, "{") + 1;
+
+    linesize = (avctx->width + 7) / 8;
+    for (i = 0; i < avctx->height; i++) {
+        dst = p->data[0] + i * p->linesize[0];
+        for (j = 0; j < linesize; j++) {
+            uint8_t val;
+
+            ptr += strcspn(ptr, "x") + 1;
+            if (ptr < end && isxdigit(*ptr)) {
+                val = convert(*ptr);
+                ptr++;
+                if (isxdigit(*ptr))
+                    val = (val << 4) + convert(*ptr);
+                *dst++ = av_reverse[val];
+            } else {
+                av_log(avctx, AV_LOG_ERROR, "Unexpected data at '%.8s'\n", ptr);
+                return AVERROR_INVALIDDATA;
+            }
+        }
+    }
+
+    p->key_frame = 1;
+    p->pict_type = AV_PICTURE_TYPE_I;
+
+    *data_size       = sizeof(AVFrame);
+    *(AVFrame *)data = *p;
+
+    return avpkt->size;
+}
+
+static av_cold int xbm_decode_close(AVCodecContext *avctx)
+{
+    if (avctx->coded_frame->data[0])
+        avctx->release_buffer(avctx, avctx->coded_frame);
+
+    av_freep(&avctx->coded_frame);
+
+    return 0;
+}
+
+AVCodec ff_xbm_decoder = {
+    .name         = "xbm",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_XBM,
+    .init         = xbm_decode_init,
+    .close        = xbm_decode_close,
+    .decode       = xbm_decode_frame,
+    .capabilities = CODEC_CAP_DR1,
+    .long_name    = NULL_IF_CONFIG_SMALL("XBM (X BitMap) image"),
+};
diff --git a/libavcodec/xbmenc.c b/libavcodec/xbmenc.c
index e12debe..ddfc15b 100644
--- a/libavcodec/xbmenc.c
+++ b/libavcodec/xbmenc.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2012 Paul B Mahol
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -42,10 +42,8 @@
 
     linesize = (avctx->width + 7) / 8;
     size     = avctx->height * (linesize * 7 + 2) + 110;
-    if ((ret = ff_alloc_packet(pkt, size)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, size)) < 0)
         return ret;
-    }
 
     buf = pkt->data;
     ptr = p->data[0];
diff --git a/libavcodec/xiph.c b/libavcodec/xiph.c
index 7c3c710..0636f8e 100644
--- a/libavcodec/xiph.c
+++ b/libavcodec/xiph.c
@@ -1,20 +1,20 @@
 /*
- * Copyright (C) 2007  Libav Project
+ * Copyright (C) 2007  FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/xiph.h b/libavcodec/xiph.h
index afaece7..cd8caa4 100644
--- a/libavcodec/xiph.h
+++ b/libavcodec/xiph.h
@@ -1,20 +1,20 @@
 /*
- * Copyright (C) 2007  Libav Project
+ * Copyright (C) 2007  FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/xl.c b/libavcodec/xl.c
index b633158..1620c85 100644
--- a/libavcodec/xl.c
+++ b/libavcodec/xl.c
@@ -2,20 +2,20 @@
  * Miro VideoXL codec
  * Copyright (c) 2004 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -53,6 +53,16 @@
     uint32_t val;
     int y0, y1, y2, y3 = 0, c0 = 0, c1 = 0;
 
+    if (avctx->width & 3) {
+        av_log(avctx, AV_LOG_ERROR, "width is not a multiple of 4\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (buf_size < avctx->width * avctx->height) {
+        av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     if(p->data[0])
         avctx->release_buffer(avctx, p);
 
@@ -70,11 +80,6 @@
 
     stride = avctx->width - 4;
 
-    if (buf_size < avctx->width * avctx->height) {
-        av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
-        return AVERROR_INVALIDDATA;
-    }
-
     for (i = 0; i < avctx->height; i++) {
         /* lines are stored in reversed order */
         buf += stride;
@@ -128,8 +133,9 @@
 }
 
 static av_cold int decode_init(AVCodecContext *avctx){
-//    VideoXLContext * const a = avctx->priv_data;
+    VideoXLContext * const a = avctx->priv_data;
 
+    avcodec_get_frame_defaults(&a->pic);
     avctx->pix_fmt= AV_PIX_FMT_YUV411P;
 
     return 0;
diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c
index 11e1d57..d3367b0 100644
--- a/libavcodec/xsubdec.c
+++ b/libavcodec/xsubdec.c
@@ -2,20 +2,20 @@
  * XSUB subtitle decoder
  * Copyright (c) 2007 Reimar Döffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -56,12 +56,11 @@
     int w, h, x, y, i;
     int64_t packet_time = 0;
     GetBitContext gb;
-
-    memset(sub, 0, sizeof(*sub));
+    int has_alpha = avctx->codec_tag == MKTAG('D','X','S','A');
 
     // check that at least header fits
     if (buf_size < 27 + 7 * 2 + 4 * 3) {
-        av_log(avctx, AV_LOG_ERROR, "coded frame too small\n");
+        av_log(avctx, AV_LOG_ERROR, "coded frame size %d too small\n", buf_size);
         return -1;
     }
 
@@ -108,8 +107,8 @@
     for (i = 0; i < sub->rects[0]->nb_colors; i++)
         ((uint32_t*)sub->rects[0]->pict.data[1])[i] = bytestream_get_be24(&buf);
     // make all except background (first entry) non-transparent
-    for (i = 1; i < sub->rects[0]->nb_colors; i++)
-        ((uint32_t*)sub->rects[0]->pict.data[1])[i] |= 0xff000000;
+    for (i = 0; i < sub->rects[0]->nb_colors; i++)
+        ((uint32_t*)sub->rects[0]->pict.data[1])[i] |= (has_alpha ? *buf++ : (i ? 0xff : 0)) << 24;
 
     // process RLE-compressed data
     init_get_bits(&gb, buf, (buf_end - buf) * 8);
diff --git a/libavcodec/xsubenc.c b/libavcodec/xsubenc.c
index 816e651..cb2a908 100644
--- a/libavcodec/xsubenc.c
+++ b/libavcodec/xsubenc.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2005 DivX, Inc.
  * Copyright (c) 2009 Bjorn Axelsson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -128,7 +128,7 @@
     }
 
     // TODO: support multiple rects
-    if (h->num_rects > 1)
+    if (h->num_rects != 1)
         av_log(avctx, AV_LOG_WARNING, "Only single rects supported (%d in subtitle.)\n", h->num_rects);
 
     // TODO: render text-based subtitles into bitmaps
diff --git a/libavcodec/xvmc.h b/libavcodec/xvmc.h
index 1f77e4e..b2bf518 100644
--- a/libavcodec/xvmc.h
+++ b/libavcodec/xvmc.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2003 Ivan Kalvachev
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/xvmc_internal.h b/libavcodec/xvmc_internal.h
index 3c6aed8..04197ce 100644
--- a/libavcodec/xvmc_internal.h
+++ b/libavcodec/xvmc_internal.h
@@ -1,20 +1,20 @@
 /*
  * XVideo Motion Compensation internal functions
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/xwd.h b/libavcodec/xwd.h
index f41e2cd..d046046 100644
--- a/libavcodec/xwd.h
+++ b/libavcodec/xwd.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2012 Paul B Mahol
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavcodec/xwddec.c b/libavcodec/xwddec.c
index 4cec615..ef99a6b 100644
--- a/libavcodec/xwddec.c
+++ b/libavcodec/xwddec.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2012 Paul B Mahol
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -157,10 +157,13 @@
     switch (vclass) {
     case XWD_STATIC_GRAY:
     case XWD_GRAY_SCALE:
-        if (bpp != 1)
+        if (bpp != 1 && bpp != 8)
             return AVERROR_INVALIDDATA;
-        if (pixdepth == 1)
+        if (pixdepth == 1) {
             avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
+        } else if (pixdepth == 8) {
+            avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+        }
         break;
     case XWD_STATIC_COLOR:
     case XWD_PSEUDO_COLOR:
diff --git a/libavcodec/xwdenc.c b/libavcodec/xwdenc.c
index c9a2a56..fac3d0b 100644
--- a/libavcodec/xwdenc.c
+++ b/libavcodec/xwdenc.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2012 Paul B Mahol
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -133,6 +133,11 @@
         bpad     = 8;
         ncolors  = 256;
         break;
+    case AV_PIX_FMT_GRAY8:
+        bpp      = 8;
+        bpad     = 8;
+        vclass   = XWD_STATIC_GRAY;
+        break;
     case AV_PIX_FMT_MONOWHITE:
         be       = 1;
         bitorder = 1;
@@ -149,10 +154,8 @@
     header_size = XWD_HEADER_SIZE + WINDOW_NAME_SIZE;
     out_size    = header_size + ncolors * XWD_CMAP_SIZE + avctx->height * lsize;
 
-    if ((ret = ff_alloc_packet(pkt, out_size)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "output buffer too small\n");
+    if ((ret = ff_alloc_packet2(avctx, pkt, out_size)) < 0)
         return ret;
-    }
     buf = pkt->data;
 
     avctx->coded_frame->key_frame = 1;
@@ -246,6 +249,7 @@
                                                  AV_PIX_FMT_RGB4_BYTE,
                                                  AV_PIX_FMT_BGR4_BYTE,
                                                  AV_PIX_FMT_PAL8,
+                                                 AV_PIX_FMT_GRAY8,
                                                  AV_PIX_FMT_MONOWHITE,
                                                  AV_PIX_FMT_NONE },
     .long_name    = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"),
diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c
index b06d314..f7ffa4e 100644
--- a/libavcodec/xxan.c
+++ b/libavcodec/xxan.c
@@ -3,20 +3,20 @@
  * Copyright (C) 2011 Konstantin Shishkov
  * based on work by Mike Melanson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -197,16 +197,18 @@
     if (mode) {
         for (j = 0; j < avctx->height >> 1; j++) {
             for (i = 0; i < avctx->width >> 1; i++) {
+                if (src_end - src < 1)
+                    return 0;
                 val = *src++;
-                if (val && val < table_size) {
+                if (val) {
+                    if (val >= table_size)
+                        return AVERROR_INVALIDDATA;
                     val  = AV_RL16(table + (val << 1));
                     uval = (val >> 3) & 0xF8;
                     vval = (val >> 8) & 0xF8;
                     U[i] = uval | (uval >> 5);
                     V[i] = vval | (vval >> 5);
                 }
-                if (src == src_end)
-                    return 0;
             }
             U += s->pic.linesize[1];
             V += s->pic.linesize[2];
@@ -217,8 +219,12 @@
 
         for (j = 0; j < avctx->height >> 2; j++) {
             for (i = 0; i < avctx->width >> 1; i += 2) {
+                if (src_end - src < 1)
+                    return 0;
                 val = *src++;
-                if (val && val < table_size) {
+                if (val) {
+                    if (val >= table_size)
+                        return AVERROR_INVALIDDATA;
                     val  = AV_RL16(table + (val << 1));
                     uval = (val >> 3) & 0xF8;
                     vval = (val >> 8) & 0xF8;
@@ -251,7 +257,7 @@
     if ((ret = xan_decode_chroma(avctx, chroma_off)) != 0)
         return ret;
 
-    if (corr_off >= (s->gb.buffer_end - s->gb.buffer_start)) {
+    if (corr_off >= bytestream2_size(&s->gb)) {
         av_log(avctx, AV_LOG_WARNING, "Ignoring invalid correction block position\n");
         corr_off = 0;
     }
@@ -296,6 +302,9 @@
         dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size);
         if (dec_size < 0)
             dec_size = 0;
+        else
+            dec_size = FFMIN(dec_size, s->buffer_size/2 - 1);
+
         for (i = 0; i < dec_size; i++)
             s->y_buffer[i*2+1] = (s->y_buffer[i*2+1] + (s->scratch_buffer[i] << 1)) & 0x3F;
     }
@@ -365,7 +374,7 @@
     int ftype;
     int ret;
 
-    s->pic.reference = 1;
+    s->pic.reference = 3;
     s->pic.buffer_hints = FF_BUFFER_HINTS_VALID |
                           FF_BUFFER_HINTS_PRESERVE |
                           FF_BUFFER_HINTS_REUSABLE;
diff --git a/libavcodec/y41pdec.c b/libavcodec/y41pdec.c
new file mode 100644
index 0000000..e283690
--- /dev/null
+++ b/libavcodec/y41pdec.c
@@ -0,0 +1,116 @@
+/*
+ * y41p decoder
+ *
+ * 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 "avcodec.h"
+
+static av_cold int y41p_decode_init(AVCodecContext *avctx)
+{
+    avctx->pix_fmt             = AV_PIX_FMT_YUV411P;
+    avctx->bits_per_raw_sample = 12;
+
+    if (avctx->width & 7) {
+        av_log(avctx, AV_LOG_WARNING, "y41p requires width to be divisible by 8.\n");
+    }
+
+    avctx->coded_frame = avcodec_alloc_frame();
+    if (!avctx->coded_frame) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int y41p_decode_frame(AVCodecContext *avctx, void *data,
+                             int *data_size, AVPacket *avpkt)
+{
+    AVFrame *pic = avctx->coded_frame;
+    uint8_t *src = avpkt->data;
+    uint8_t *y, *u, *v;
+    int i, j;
+
+    if (pic->data[0])
+        avctx->release_buffer(avctx, pic);
+
+    if (avpkt->size < 1.5 * avctx->height * avctx->width) {
+        av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
+        return AVERROR(EINVAL);
+    }
+
+    pic->reference = 0;
+
+    if (avctx->get_buffer(avctx, pic) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    pic->key_frame = 1;
+    pic->pict_type = AV_PICTURE_TYPE_I;
+
+    for (i = avctx->height - 1; i >= 0 ; i--) {
+        y = &pic->data[0][i * pic->linesize[0]];
+        u = &pic->data[1][i * pic->linesize[1]];
+        v = &pic->data[2][i * pic->linesize[2]];
+        for (j = 0; j < avctx->width; j += 8) {
+            *(u++) = *src++;
+            *(y++) = *src++;
+            *(v++) = *src++;
+            *(y++) = *src++;
+
+            *(u++) = *src++;
+            *(y++) = *src++;
+            *(v++) = *src++;
+            *(y++) = *src++;
+
+            *(y++) = *src++;
+            *(y++) = *src++;
+            *(y++) = *src++;
+            *(y++) = *src++;
+        }
+    }
+
+    *data_size = sizeof(AVFrame);
+    *(AVFrame *)data = *pic;
+
+    return avpkt->size;
+}
+
+static av_cold int y41p_decode_close(AVCodecContext *avctx)
+{
+    if (avctx->coded_frame->data[0])
+        avctx->release_buffer(avctx, avctx->coded_frame);
+
+    av_freep(&avctx->coded_frame);
+
+    return 0;
+}
+
+AVCodec ff_y41p_decoder = {
+    .name         = "y41p",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_Y41P,
+    .init         = y41p_decode_init,
+    .decode       = y41p_decode_frame,
+    .close        = y41p_decode_close,
+    .capabilities = CODEC_CAP_DR1,
+    .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed YUV 4:1:1 12-bit"),
+};
diff --git a/libavcodec/y41penc.c b/libavcodec/y41penc.c
new file mode 100644
index 0000000..f0c212b
--- /dev/null
+++ b/libavcodec/y41penc.c
@@ -0,0 +1,103 @@
+/*
+ * y41p encoder
+ *
+ * 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 "avcodec.h"
+#include "internal.h"
+
+static av_cold int y41p_encode_init(AVCodecContext *avctx)
+{
+    if (avctx->width & 7) {
+        av_log(avctx, AV_LOG_ERROR, "y41p requires width to be divisible by 8.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    avctx->coded_frame = avcodec_alloc_frame();
+    avctx->bits_per_coded_sample = 12;
+
+    if (!avctx->coded_frame) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int y41p_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                             const AVFrame *pic, int *got_packet)
+{
+    uint8_t *dst;
+    uint8_t *y, *u, *v;
+    int i, j, ret;
+
+    if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width * avctx->height * 1.5)) < 0)
+        return ret;
+
+    avctx->coded_frame->reference = 0;
+    avctx->coded_frame->key_frame = 1;
+    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+    dst = pkt->data;
+
+    for (i = avctx->height - 1; i >= 0; i--) {
+        y = &pic->data[0][i * pic->linesize[0]];
+        u = &pic->data[1][i * pic->linesize[1]];
+        v = &pic->data[2][i * pic->linesize[2]];
+        for (j = 0; j < avctx->width; j += 8) {
+            *(dst++) = *(u++);
+            *(dst++) = *(y++);
+            *(dst++) = *(v++);
+            *(dst++) = *(y++);
+
+            *(dst++) = *(u++);
+            *(dst++) = *(y++);
+            *(dst++) = *(v++);
+            *(dst++) = *(y++);
+
+            *(dst++) = *(y++);
+            *(dst++) = *(y++);
+            *(dst++) = *(y++);
+            *(dst++) = *(y++);
+        }
+    }
+
+    pkt->flags |= AV_PKT_FLAG_KEY;
+    *got_packet = 1;
+    return 0;
+}
+
+static av_cold int y41p_encode_close(AVCodecContext *avctx)
+{
+    av_freep(&avctx->coded_frame);
+
+    return 0;
+}
+
+AVCodec ff_y41p_encoder = {
+    .name         = "y41p",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_Y41P,
+    .init         = y41p_encode_init,
+    .encode2      = y41p_encode_frame,
+    .close        = y41p_encode_close,
+    .pix_fmts     = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P,
+                                                 AV_PIX_FMT_NONE },
+    .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed YUV 4:1:1 12-bit"),
+};
diff --git a/libavcodec/yop.c b/libavcodec/yop.c
index cda9cad..3e27c1f 100644
--- a/libavcodec/yop.c
+++ b/libavcodec/yop.c
@@ -5,20 +5,20 @@
  * derived from the code by
  * Copyright (C) 2009 Thomas P. Higdon <thomas.p.higdon@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -89,8 +89,14 @@
         return -1;
     }
 
+    if (!avctx->extradata) {
+        av_log(avctx, AV_LOG_ERROR, "extradata missing\n");
+        return AVERROR_INVALIDDATA;
+    }
+
     avctx->pix_fmt = AV_PIX_FMT_PAL8;
 
+    avcodec_get_frame_defaults(&s->frame);
     s->num_pal_colors = avctx->extradata[0];
     s->first_color[0] = avctx->extradata[1];
     s->first_color[1] = avctx->extradata[2];
@@ -198,6 +204,11 @@
     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);
     if (ret < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
@@ -213,13 +224,20 @@
     s->low_nibble = NULL;
 
     is_odd_frame = avpkt->data[0];
+    if(is_odd_frame>1){
+        av_log(avctx, AV_LOG_ERROR, "frame is too odd %d\n", is_odd_frame);
+        return AVERROR_INVALIDDATA;
+    }
     firstcolor   = s->first_color[is_odd_frame];
     palette      = (uint32_t *)s->frame.data[1];
 
-    for (i = 0; i < s->num_pal_colors; i++, s->srcptr += 3)
+    for (i = 0; i < s->num_pal_colors; i++, s->srcptr += 3) {
         palette[i + firstcolor] = (s->srcptr[0] << 18) |
                                   (s->srcptr[1] << 10) |
                                   (s->srcptr[2] << 2);
+        palette[i + firstcolor] |= 0xFF << 24 |
+                                   (palette[i + firstcolor] >> 6) & 0x30303;
+    }
 
     s->frame.palette_has_changed = 1;
 
diff --git a/libavcodec/yuv4dec.c b/libavcodec/yuv4dec.c
new file mode 100644
index 0000000..ce44f13
--- /dev/null
+++ b/libavcodec/yuv4dec.c
@@ -0,0 +1,109 @@
+/*
+ * libquicktime yuv4 decoder
+ *
+ * Copyright (c) 2011 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"
+
+static av_cold int yuv4_decode_init(AVCodecContext *avctx)
+{
+    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+    avctx->coded_frame = avcodec_alloc_frame();
+
+    if (!avctx->coded_frame) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int yuv4_decode_frame(AVCodecContext *avctx, void *data,
+                             int *data_size, AVPacket *avpkt)
+{
+    AVFrame *pic = avctx->coded_frame;
+    const uint8_t *src = avpkt->data;
+    uint8_t *y, *u, *v;
+    int i, j;
+
+    if (pic->data[0])
+        avctx->release_buffer(avctx, pic);
+
+    if (avpkt->size < 6 * (avctx->width + 1 >> 1) * (avctx->height + 1 >> 1)) {
+        av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
+        return AVERROR(EINVAL);
+    }
+
+    pic->reference = 0;
+
+    if (avctx->get_buffer(avctx, pic) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    pic->key_frame = 1;
+    pic->pict_type = AV_PICTURE_TYPE_I;
+
+    y = pic->data[0];
+    u = pic->data[1];
+    v = pic->data[2];
+
+    for (i = 0; i < (avctx->height + 1) >> 1; i++) {
+        for (j = 0; j < (avctx->width + 1) >> 1; j++) {
+            u[j] = *src++ ^ 0x80;
+            v[j] = *src++ ^ 0x80;
+            y[                   2 * j    ] = *src++;
+            y[                   2 * j + 1] = *src++;
+            y[pic->linesize[0] + 2 * j    ] = *src++;
+            y[pic->linesize[0] + 2 * j + 1] = *src++;
+        }
+
+        y += 2 * pic->linesize[0];
+        u +=     pic->linesize[1];
+        v +=     pic->linesize[2];
+    }
+
+    *data_size = sizeof(AVFrame);
+    *(AVFrame *)data = *pic;
+
+    return avpkt->size;
+}
+
+static av_cold int yuv4_decode_close(AVCodecContext *avctx)
+{
+    if (avctx->coded_frame->data[0])
+        avctx->release_buffer(avctx, avctx->coded_frame);
+
+    av_freep(&avctx->coded_frame);
+
+    return 0;
+}
+
+AVCodec ff_yuv4_decoder = {
+    .name         = "yuv4",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_YUV4,
+    .init         = yuv4_decode_init,
+    .decode       = yuv4_decode_frame,
+    .close        = yuv4_decode_close,
+    .capabilities = CODEC_CAP_DR1,
+    .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:2:0"),
+};
diff --git a/libavcodec/yuv4enc.c b/libavcodec/yuv4enc.c
new file mode 100644
index 0000000..340310a
--- /dev/null
+++ b/libavcodec/yuv4enc.c
@@ -0,0 +1,92 @@
+/*
+ * libquicktime yuv4 encoder
+ *
+ * Copyright (c) 2011 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"
+
+static av_cold int yuv4_encode_init(AVCodecContext *avctx)
+{
+    avctx->coded_frame = avcodec_alloc_frame();
+
+    if (!avctx->coded_frame) {
+        av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n");
+        return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+static int yuv4_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+                             const AVFrame *pic, int *got_packet)
+{
+    uint8_t *dst;
+    uint8_t *y, *u, *v;
+    int i, j, ret;
+
+    if ((ret = ff_alloc_packet2(avctx, pkt, 6 * (avctx->width + 1 >> 1) * (avctx->height + 1 >> 1))) < 0)
+        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;
+
+    y = pic->data[0];
+    u = pic->data[1];
+    v = pic->data[2];
+
+    for (i = 0; i < avctx->height + 1 >> 1; i++) {
+        for (j = 0; j < avctx->width + 1 >> 1; j++) {
+            *dst++ = u[j] ^ 0x80;
+            *dst++ = v[j] ^ 0x80;
+            *dst++ = y[                   2 * j    ];
+            *dst++ = y[                   2 * j + 1];
+            *dst++ = y[pic->linesize[0] + 2 * j    ];
+            *dst++ = y[pic->linesize[0] + 2 * j + 1];
+        }
+        y += 2 * pic->linesize[0];
+        u +=     pic->linesize[1];
+        v +=     pic->linesize[2];
+    }
+
+    pkt->flags |= AV_PKT_FLAG_KEY;
+    *got_packet = 1;
+    return 0;
+}
+
+static av_cold int yuv4_encode_close(AVCodecContext *avctx)
+{
+    av_freep(&avctx->coded_frame);
+
+    return 0;
+}
+
+AVCodec ff_yuv4_encoder = {
+    .name         = "yuv4",
+    .type         = AVMEDIA_TYPE_VIDEO,
+    .id           = AV_CODEC_ID_YUV4,
+    .init         = yuv4_encode_init,
+    .encode2      = yuv4_encode_frame,
+    .close        = yuv4_encode_close,
+    .pix_fmts     = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE },
+    .long_name    = NULL_IF_CONFIG_SMALL("Uncompressed packed 4:2:0"),
+};
diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c
index 8fb1538..762d5728 100644
--- a/libavcodec/zmbv.c
+++ b/libavcodec/zmbv.c
@@ -2,20 +2,20 @@
  * Zip Motion Blocks Video (ZMBV) decoder
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -405,12 +405,11 @@
     int zret = Z_OK; // Zlib return code
     int len = buf_size;
     int hi_ver, lo_ver, ret;
-    uint8_t *tmp;
 
     if (c->pic.data[0])
             avctx->release_buffer(avctx, &c->pic);
 
-    c->pic.reference = 1;
+    c->pic.reference = 3;
     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
     if ((ret = avctx->get_buffer(avctx, &c->pic)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
@@ -421,6 +420,8 @@
     c->flags = buf[0];
     buf++; len--;
     if (c->flags & ZMBV_KEYFRAME) {
+        void *decode_intra = NULL;
+        c->decode_intra= NULL;
         hi_ver = buf[0];
         lo_ver = buf[1];
         c->comp = buf[2];
@@ -452,29 +453,28 @@
         switch (c->fmt) {
         case ZMBV_FMT_8BPP:
             c->bpp = 8;
-            c->decode_intra = zmbv_decode_intra;
+            decode_intra = zmbv_decode_intra;
             c->decode_xor = zmbv_decode_xor_8;
             break;
         case ZMBV_FMT_15BPP:
         case ZMBV_FMT_16BPP:
             c->bpp = 16;
-            c->decode_intra = zmbv_decode_intra;
+            decode_intra = zmbv_decode_intra;
             c->decode_xor = zmbv_decode_xor_16;
             break;
 #ifdef ZMBV_ENABLE_24BPP
         case ZMBV_FMT_24BPP:
             c->bpp = 24;
-            c->decode_intra = zmbv_decode_intra;
+            decode_intra = zmbv_decode_intra;
             c->decode_xor = zmbv_decode_xor_24;
             break;
 #endif //ZMBV_ENABLE_24BPP
         case ZMBV_FMT_32BPP:
             c->bpp = 32;
-            c->decode_intra = zmbv_decode_intra;
+            decode_intra = zmbv_decode_intra;
             c->decode_xor = zmbv_decode_xor_32;
             break;
         default:
-            c->decode_intra = NULL;
             c->decode_xor = NULL;
             av_log_ask_for_sample(avctx, "Unsupported (for now) format %i\n",
                                   c->fmt);
@@ -487,16 +487,13 @@
             return -1;
         }
 
-        tmp = av_realloc(c->cur,  avctx->width * avctx->height * (c->bpp / 8));
-        if (!tmp)
-            return AVERROR(ENOMEM);
-        c->cur = tmp;
-        tmp = av_realloc(c->prev, avctx->width * avctx->height * (c->bpp / 8));
-        if (!tmp)
-            return AVERROR(ENOMEM);
-        c->prev = tmp;
-        c->bx   = (c->width  + c->bw - 1) / c->bw;
-        c->by   = (c->height + c->bh - 1) / c->bh;
+        c->cur  = av_realloc_f(c->cur, avctx->width * avctx->height,  (c->bpp / 8));
+        c->prev = av_realloc_f(c->prev, avctx->width * avctx->height,  (c->bpp / 8));
+        c->bx = (c->width + c->bw - 1) / c->bw;
+        c->by = (c->height+ c->bh - 1) / c->bh;
+        if (!c->cur || !c->prev)
+            return -1;
+        c->decode_intra= decode_intra;
     }
 
     if (c->decode_intra == NULL) {
@@ -509,7 +506,7 @@
         c->decomp_size = 1;
     } else { // ZLIB-compressed data
         c->zstream.total_in = c->zstream.total_out = 0;
-        c->zstream.next_in = buf;
+        c->zstream.next_in = (uint8_t*)buf;
         c->zstream.avail_in = len;
         c->zstream.next_out = c->decomp_buf;
         c->zstream.avail_out = c->decomp_size;
@@ -621,6 +618,7 @@
 
     c->width = avctx->width;
     c->height = avctx->height;
+    avcodec_get_frame_defaults(&c->pic);
 
     c->bpp = avctx->bits_per_coded_sample;
 
diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c
index 9ac7d6d..fb782a4 100644
--- a/libavcodec/zmbvenc.c
+++ b/libavcodec/zmbvenc.c
@@ -2,20 +2,20 @@
  * Zip Motion Blocks Video (ZMBV) encoder
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -229,10 +229,8 @@
     }
 
     pkt_size = c->zstream.total_out + 1 + 6*keyframe;
-    if ((ret = ff_alloc_packet(pkt, pkt_size)) < 0) {
-        av_log(avctx, AV_LOG_ERROR, "Error getting packet of size %d.\n", pkt_size);
+    if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size)) < 0)
         return ret;
-    }
     buf = pkt->data;
 
     fl = (keyframe ? ZMBV_KEYFRAME : 0) | (chpal ? ZMBV_DELTAPAL : 0);
diff --git a/libavdevice/Makefile b/libavdevice/Makefile
index 76d11c1..efffa8b 100644
--- a/libavdevice/Makefile
+++ b/libavdevice/Makefile
@@ -1,5 +1,8 @@
+include $(SUBDIR)../config.mak
+
 NAME    = avdevice
 FFLIBS  = avformat avcodec avutil
+FFLIBS-$(CONFIG_LAVFI_INDEV) += avfilter
 
 HEADERS = avdevice.h                                                    \
           version.h                                                     \
@@ -9,19 +12,28 @@
 
 # input/output devices
 OBJS-$(CONFIG_ALSA_INDEV)                += alsa-audio-common.o \
-                                            alsa-audio-dec.o
+                                            alsa-audio-dec.o timefilter.o
 OBJS-$(CONFIG_ALSA_OUTDEV)               += alsa-audio-common.o \
                                             alsa-audio-enc.o
 OBJS-$(CONFIG_BKTR_INDEV)                += bktr.o
+OBJS-$(CONFIG_CACA_OUTDEV)               += caca.o
+OBJS-$(CONFIG_DSHOW_INDEV)               += dshow.o dshow_enummediatypes.o \
+                                            dshow_enumpins.o dshow_filter.o \
+                                            dshow_pin.o dshow_common.o
 OBJS-$(CONFIG_DV1394_INDEV)              += dv1394.o
 OBJS-$(CONFIG_FBDEV_INDEV)               += fbdev.o
+OBJS-$(CONFIG_IEC61883_INDEV)            += iec61883.o
 OBJS-$(CONFIG_JACK_INDEV)                += jack_audio.o timefilter.o
+OBJS-$(CONFIG_LAVFI_INDEV)               += lavfi.o
+OBJS-$(CONFIG_OPENAL_INDEV)              += openal-dec.o
 OBJS-$(CONFIG_OSS_INDEV)                 += oss_audio.o
 OBJS-$(CONFIG_OSS_OUTDEV)                += oss_audio.o
 OBJS-$(CONFIG_PULSE_INDEV)               += pulse.o
+OBJS-$(CONFIG_SDL_OUTDEV)                += sdl.o
 OBJS-$(CONFIG_SNDIO_INDEV)               += sndio_common.o sndio_dec.o
 OBJS-$(CONFIG_SNDIO_OUTDEV)              += sndio_common.o sndio_enc.o
-OBJS-$(CONFIG_V4L2_INDEV)                += v4l2.o
+OBJS-$(CONFIG_V4L2_INDEV)                += v4l2.o timefilter.o
+OBJS-$(CONFIG_V4L_INDEV)                 += v4l.o
 OBJS-$(CONFIG_VFWCAP_INDEV)              += vfwcap.o
 OBJS-$(CONFIG_X11GRAB_INDEV)             += x11grab.o
 
@@ -29,6 +41,7 @@
 OBJS-$(CONFIG_LIBCDIO_INDEV)             += libcdio.o
 OBJS-$(CONFIG_LIBDC1394_INDEV)           += libdc1394.o
 
+SKIPHEADERS-$(CONFIG_DSHOW_INDEV)        += dshow_capture.h
 SKIPHEADERS-$(HAVE_ALSA_ASOUNDLIB_H)     += alsa-audio.h
 SKIPHEADERS-$(HAVE_SNDIO_H)              += sndio_common.h
 
diff --git a/libavdevice/alldevices.c b/libavdevice/alldevices.c
index 9ec9fdf..7789058 100644
--- a/libavdevice/alldevices.c
+++ b/libavdevice/alldevices.c
@@ -1,25 +1,24 @@
 /*
  * Register all the grabbing devices.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "config.h"
-#include "libavformat/avformat.h"
 #include "avdevice.h"
 
 #define REGISTER_OUTDEV(X,x) { \
@@ -41,13 +40,20 @@
     /* 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);
 
diff --git a/libavdevice/alsa-audio-common.c b/libavdevice/alsa-audio-common.c
index b48e007..9da868f 100644
--- a/libavdevice/alsa-audio-common.c
+++ b/libavdevice/alsa-audio-common.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2007 Luca Abeni ( lucabe72 email it )
  * Copyright (c) 2007 Benoit Fouet ( benoit fouet free fr )
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,7 +29,7 @@
  */
 
 #include <alsa/asoundlib.h>
-#include "libavformat/avformat.h"
+#include "avdevice.h"
 #include "libavutil/avassert.h"
 #include "libavutil/audioconvert.h"
 
@@ -320,6 +320,8 @@
     AlsaData *s = s1->priv_data;
 
     av_freep(&s->reorder_buf);
+    if (CONFIG_ALSA_INDEV)
+        ff_timefilter_destroy(s->timefilter);
     snd_pcm_close(s->h);
     return 0;
 }
diff --git a/libavdevice/alsa-audio-dec.c b/libavdevice/alsa-audio-dec.c
index 5b32ed9..b781daf 100644
--- a/libavdevice/alsa-audio-dec.c
+++ b/libavdevice/alsa-audio-dec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2007 Luca Abeni ( lucabe72 email it )
  * Copyright (c) 2007 Benoit Fouet ( benoit fouet free fr )
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -46,10 +46,11 @@
  */
 
 #include <alsa/asoundlib.h>
-#include "libavformat/avformat.h"
 #include "libavformat/internal.h"
 #include "libavutil/opt.h"
+#include "libavutil/mathematics.h"
 
+#include "avdevice.h"
 #include "alsa-audio.h"
 
 static av_cold int audio_read_header(AVFormatContext *s1)
@@ -58,7 +59,6 @@
     AVStream *st;
     int ret;
     enum AVCodecID codec_id;
-    snd_pcm_sw_params_t *sw_params;
 
     st = avformat_new_stream(s1, NULL);
     if (!st) {
@@ -74,35 +74,17 @@
         return AVERROR(EIO);
     }
 
-    if (snd_pcm_type(s->h) != SND_PCM_TYPE_HW)
-        av_log(s1, AV_LOG_WARNING,
-               "capture with some ALSA plugins, especially dsnoop, "
-               "may hang.\n");
-
-    ret = snd_pcm_sw_params_malloc(&sw_params);
-    if (ret < 0) {
-        av_log(s1, AV_LOG_ERROR, "cannot allocate software parameters structure (%s)\n",
-               snd_strerror(ret));
-        goto fail;
-    }
-
-    snd_pcm_sw_params_current(s->h, sw_params);
-    snd_pcm_sw_params_set_tstamp_mode(s->h, sw_params, SND_PCM_TSTAMP_ENABLE);
-
-    ret = snd_pcm_sw_params(s->h, sw_params);
-    snd_pcm_sw_params_free(sw_params);
-    if (ret < 0) {
-        av_log(s1, AV_LOG_ERROR, "cannot install ALSA software parameters (%s)\n",
-               snd_strerror(ret));
-        goto fail;
-    }
-
     /* take real parameters */
     st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
     st->codec->codec_id    = codec_id;
     st->codec->sample_rate = s->sample_rate;
     st->codec->channels    = s->channels;
     avpriv_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */
+    /* microseconds instead of seconds, MHz instead of Hz */
+    s->timefilter = ff_timefilter_new(1000000.0 / s->sample_rate,
+                                      s->period_size, 1.5E-6);
+    if (!s->timefilter)
+        goto fail;
 
     return 0;
 
@@ -114,16 +96,15 @@
 static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt)
 {
     AlsaData *s  = s1->priv_data;
-    AVStream *st = s1->streams[0];
     int res;
-    snd_htimestamp_t timestamp;
-    snd_pcm_uframes_t ts_delay;
+    int64_t dts;
+    snd_pcm_sframes_t delay = 0;
 
-    if (av_new_packet(pkt, s->period_size) < 0) {
+    if (av_new_packet(pkt, s->period_size * s->frame_size) < 0) {
         return AVERROR(EIO);
     }
 
-    while ((res = snd_pcm_readi(s->h, pkt->data, pkt->size / s->frame_size)) < 0) {
+    while ((res = snd_pcm_readi(s->h, pkt->data, s->period_size)) < 0) {
         if (res == -EAGAIN) {
             av_free_packet(pkt);
 
@@ -136,14 +117,14 @@
 
             return AVERROR(EIO);
         }
+        ff_timefilter_reset(s->timefilter);
     }
 
-    snd_pcm_htimestamp(s->h, &ts_delay, &timestamp);
-    ts_delay += res;
-    pkt->pts = timestamp.tv_sec * 1000000LL
-               + (timestamp.tv_nsec * st->codec->sample_rate
-                  - ts_delay * 1000000000LL + st->codec->sample_rate * 500LL)
-               / (st->codec->sample_rate * 1000LL);
+    dts = av_gettime();
+    snd_pcm_delay(s->h, &delay);
+    dts -= av_rescale(delay + res, 1000000, s->sample_rate);
+    pkt->pts = ff_timefilter_update(s->timefilter, dts, s->last_period);
+    s->last_period = res;
 
     pkt->size = res * s->frame_size;
 
diff --git a/libavdevice/alsa-audio-enc.c b/libavdevice/alsa-audio-enc.c
index bb4575f..403a44f 100644
--- a/libavdevice/alsa-audio-enc.c
+++ b/libavdevice/alsa-audio-enc.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2007 Luca Abeni ( lucabe72 email it )
  * Copyright (c) 2007 Benoit Fouet ( benoit fouet free fr )
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -38,8 +38,9 @@
  */
 
 #include <alsa/asoundlib.h>
-#include "libavformat/avformat.h"
 
+#include "libavformat/internal.h"
+#include "avdevice.h"
 #include "alsa-audio.h"
 
 static av_cold int audio_write_header(AVFormatContext *s1)
@@ -61,6 +62,7 @@
                st->codec->sample_rate, sample_rate);
         goto fail;
     }
+    avpriv_set_pts_info(st, 64, 1, sample_rate);
 
     return res;
 
@@ -101,6 +103,17 @@
     return 0;
 }
 
+static void
+audio_get_output_timestamp(AVFormatContext *s1, int stream,
+    int64_t *dts, int64_t *wall)
+{
+    AlsaData *s  = s1->priv_data;
+    snd_pcm_sframes_t delay = 0;
+    *wall = av_gettime();
+    snd_pcm_delay(s->h, &delay);
+    *dts = s1->streams[0]->cur_dts - delay;
+}
+
 AVOutputFormat ff_alsa_muxer = {
     .name           = "alsa",
     .long_name      = NULL_IF_CONFIG_SMALL("ALSA audio output"),
@@ -110,5 +123,6 @@
     .write_header   = audio_write_header,
     .write_packet   = audio_write_packet,
     .write_trailer  = ff_alsa_close,
+    .get_output_timestamp = audio_get_output_timestamp,
     .flags          = AVFMT_NOFILE,
 };
diff --git a/libavdevice/alsa-audio.h b/libavdevice/alsa-audio.h
index 26eaee6..44b7c72 100644
--- a/libavdevice/alsa-audio.h
+++ b/libavdevice/alsa-audio.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2007 Luca Abeni ( lucabe72 email it )
  * Copyright (c) 2007 Benoit Fouet ( benoit fouet free fr )
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -32,23 +32,28 @@
 
 #include <alsa/asoundlib.h>
 #include "config.h"
-#include "libavformat/avformat.h"
 #include "libavutil/log.h"
+#include "timefilter.h"
+#include "avdevice.h"
 
 /* XXX: we make the assumption that the soundcard accepts this format */
 /* XXX: find better solution with "preinit" method, needed also in
         other formats */
 #define DEFAULT_CODEC_ID AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE)
 
-#define ALSA_BUFFER_SIZE_MAX 32768
+typedef void (*ff_reorder_func)(const void *, void *, int);
+
+#define ALSA_BUFFER_SIZE_MAX 65536
 
 typedef struct AlsaData {
     AVClass *class;
     snd_pcm_t *h;
-    int frame_size;  ///< preferred size for reads and writes
-    int period_size; ///< bytes per sample * channels
+    int frame_size;  ///< bytes per sample * channels
+    int period_size; ///< preferred size for reads and writes, in frames
     int sample_rate; ///< sample rate set by user
     int channels;    ///< number of channels set by user
+    int last_period;
+    TimeFilter *timefilter;
     void (*reorder_func)(const void *, void *, int);
     void *reorder_buf;
     int reorder_buf_size; ///< in frames
diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
index 5a5c762..b9b18f2 100644
--- a/libavdevice/avdevice.c
+++ b/libavdevice/avdevice.c
@@ -1,36 +1,38 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/avassert.h"
 #include "avdevice.h"
 #include "config.h"
 
 unsigned avdevice_version(void)
 {
+    av_assert0(LIBAVDEVICE_VERSION_MICRO >= 100);
     return LIBAVDEVICE_VERSION_INT;
 }
 
 const char * avdevice_configuration(void)
 {
-    return LIBAV_CONFIGURATION;
+    return FFMPEG_CONFIGURATION;
 }
 
 const char * avdevice_license(void)
 {
 #define LICENSE_PREFIX "libavdevice license: "
-    return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+    return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
 }
diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
index 39166a5..93a044f 100644
--- a/libavdevice/avdevice.h
+++ b/libavdevice/avdevice.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -43,6 +43,8 @@
  * @}
  */
 
+#include "libavformat/avformat.h"
+
 /**
  * Return the LIBAVDEVICE_VERSION_INT constant.
  */
diff --git a/libavdevice/bktr.c b/libavdevice/bktr.c
index d0122d3..e83c44a 100644
--- a/libavdevice/bktr.c
+++ b/libavdevice/bktr.c
@@ -7,24 +7,23 @@
  * and
  *           simple_grab.c Copyright (c) 1999 Roger Hardiman
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavformat/avformat.h"
 #include "libavformat/internal.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
@@ -48,6 +47,7 @@
 #include <sys/time.h>
 #include <signal.h>
 #include <stdint.h>
+#include "avdevice.h"
 
 typedef struct {
     AVClass *class;
@@ -56,7 +56,6 @@
     int width, height;
     uint64_t per_frame;
     int standard;
-    char *video_size; /**< String describing video size, set by a private option. */
     char *framerate;  /**< Set by a private option. */
 } VideoData;
 
@@ -246,15 +245,9 @@
 {
     VideoData *s = s1->priv_data;
     AVStream *st;
-    int width, height;
     AVRational framerate;
     int ret = 0;
 
-    if ((ret = av_parse_video_size(&width, &height, s->video_size)) < 0) {
-        av_log(s1, AV_LOG_ERROR, "Could not parse video size '%s'.\n", s->video_size);
-        goto out;
-    }
-
     if (!s->framerate)
         switch (s->standard) {
         case PAL:   s->framerate = av_strdup("pal");  break;
@@ -277,20 +270,18 @@
     }
     avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in use */
 
-    s->width = width;
-    s->height = height;
     s->per_frame = ((uint64_t)1000000 * framerate.den) / framerate.num;
 
     st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     st->codec->pix_fmt = AV_PIX_FMT_YUV420P;
     st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
-    st->codec->width = width;
-    st->codec->height = height;
+    st->codec->width = s->width;
+    st->codec->height = s->height;
     st->codec->time_base.den = framerate.num;
     st->codec->time_base.num = framerate.den;
 
 
-    if (bktr_init(s1->filename, width, height, s->standard,
+    if (bktr_init(s1->filename, s->width, s->height, s->standard,
                   &s->video_fd, &s->tuner_fd, -1, 0.0) < 0) {
         ret = AVERROR(EIO);
         goto out;
@@ -331,7 +322,7 @@
     { "PALN",     "", 0, AV_OPT_TYPE_CONST, {.i64 = PALN},  0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
     { "PALM",     "", 0, AV_OPT_TYPE_CONST, {.i64 = PALM},  0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
     { "NTSCJ",    "", 0, AV_OPT_TYPE_CONST, {.i64 = NTSCJ}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
-    { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = "vga"}, 0, 0, DEC },
+    { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, {.str = "vga"}, 0, 0, DEC },
     { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
     { NULL },
 };
diff --git a/libavdevice/caca.c b/libavdevice/caca.c
new file mode 100644
index 0000000..0a74701
--- /dev/null
+++ b/libavdevice/caca.c
@@ -0,0 +1,240 @@
+/*
+ * 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 <caca.h>
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "avdevice.h"
+
+typedef struct CACAContext {
+    AVClass         *class;
+    AVFormatContext *ctx;
+    char            *window_title;
+    int             window_width,  window_height;
+
+    caca_canvas_t   *canvas;
+    caca_display_t  *display;
+    caca_dither_t   *dither;
+
+    char            *algorithm, *antialias;
+    char            *charset, *color;
+    char            *driver;
+
+    char            *list_dither;
+    int             list_drivers;
+} CACAContext;
+
+static int caca_write_trailer(AVFormatContext *s)
+{
+    CACAContext *c = s->priv_data;
+
+    av_freep(&c->window_title);
+
+    if (c->display) {
+        caca_free_display(c->display);
+        c->display = NULL;
+    }
+    if (c->dither) {
+        caca_free_dither(c->dither);
+        c->dither = NULL;
+    }
+    if (c->canvas) {
+        caca_free_canvas(c->canvas);
+        c->canvas = NULL;
+    }
+    return 0;
+}
+
+static void list_drivers(CACAContext *c)
+{
+    const char *const *drivers = caca_get_display_driver_list();
+    int i;
+
+    av_log(c->ctx, AV_LOG_INFO, "Available drivers:\n");
+    for (i = 0; drivers[i]; i += 2)
+        av_log(c->ctx, AV_LOG_INFO, "%s : %s\n", drivers[i], drivers[i + 1]);
+}
+
+#define DEFINE_LIST_DITHER(thing, thing_str)                                 \
+static void list_dither_## thing(CACAContext *c)                         \
+{                                                                            \
+    const char *const *thing = caca_get_dither_## thing ##_list(c->dither);  \
+    int i;                                                                   \
+                                                                             \
+    av_log(c->ctx, AV_LOG_INFO, "Available %s:\n", thing_str);               \
+    for (i = 0; thing[i]; i += 2)                                            \
+        av_log(c->ctx, AV_LOG_INFO, "%s : %s\n", thing[i], thing[i + 1]);    \
+}
+
+DEFINE_LIST_DITHER(color, "colors");
+DEFINE_LIST_DITHER(charset, "charsets");
+DEFINE_LIST_DITHER(algorithm, "algorithms");
+DEFINE_LIST_DITHER(antialias, "antialias");
+
+static int caca_write_header(AVFormatContext *s)
+{
+    CACAContext *c = s->priv_data;
+    AVStream *st = s->streams[0];
+    AVCodecContext *encctx = st->codec;
+    int ret, bpp;
+
+    c->ctx = s;
+    if (c->list_drivers) {
+        list_drivers(c);
+        return AVERROR_EXIT;
+    }
+    if (c->list_dither) {
+        if (!strcmp(c->list_dither, "colors")) {
+            list_dither_color(c);
+        } else if (!strcmp(c->list_dither, "charsets")) {
+            list_dither_charset(c);
+        } else if (!strcmp(c->list_dither, "algorithms")) {
+            list_dither_algorithm(c);
+        } else if (!strcmp(c->list_dither, "antialiases")) {
+            list_dither_antialias(c);
+        } else {
+            av_log(s, AV_LOG_ERROR,
+                   "Invalid argument '%s', for 'list_dither' option\n"
+                   "Argument must be one of 'algorithms, 'antialiases', 'charsets', 'colors'\n",
+                   c->list_dither);
+            return AVERROR(EINVAL);
+        }
+        return AVERROR_EXIT;
+    }
+
+    if (   s->nb_streams > 1
+        || encctx->codec_type != AVMEDIA_TYPE_VIDEO
+        || encctx->codec_id   != AV_CODEC_ID_RAWVIDEO) {
+        av_log(s, AV_LOG_ERROR, "Only supports one rawvideo stream\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (encctx->pix_fmt != AV_PIX_FMT_RGB24) {
+        av_log(s, AV_LOG_ERROR,
+               "Unsupported pixel format '%s', choose rgb24\n",
+               av_get_pix_fmt_name(encctx->pix_fmt));
+        return AVERROR(EINVAL);
+    }
+
+    c->canvas = caca_create_canvas(c->window_width, c->window_height);
+    if (!c->canvas) {
+        av_log(s, AV_LOG_ERROR, "Failed to create canvas\n");
+        ret = AVERROR(errno);
+        goto fail;
+    }
+
+    bpp = av_get_bits_per_pixel(av_pix_fmt_desc_get(encctx->pix_fmt));
+    c->dither = caca_create_dither(bpp, encctx->width, encctx->height,
+                                   bpp / 8 * encctx->width,
+                                   0x0000ff, 0x00ff00, 0xff0000, 0);
+    if (!c->dither) {
+        av_log(s, AV_LOG_ERROR, "Failed to create dither\n");
+        ret =  AVERROR(errno);
+        goto fail;
+    }
+
+#define CHECK_DITHER_OPT(opt)                                           \
+    if (caca_set_dither_##opt(c->dither, c->opt) < 0)  {                \
+        ret = AVERROR(errno);                                           \
+        av_log(s, AV_LOG_ERROR, "Failed to set value '%s' for option '%s'\n", \
+               c->opt, #opt);                                           \
+        goto fail;                                                      \
+    }
+    CHECK_DITHER_OPT(algorithm);
+    CHECK_DITHER_OPT(antialias);
+    CHECK_DITHER_OPT(charset);
+    CHECK_DITHER_OPT(color);
+
+    c->display = caca_create_display_with_driver(c->canvas, c->driver);
+    if (!c->display) {
+        av_log(s, AV_LOG_ERROR, "Failed to create display\n");
+        list_drivers(c);
+        ret = AVERROR(errno);
+        goto fail;
+    }
+
+    if (!c->window_width || !c->window_height) {
+        c->window_width  = caca_get_canvas_width(c->canvas);
+        c->window_height = caca_get_canvas_height(c->canvas);
+    }
+
+    if (!c->window_title)
+        c->window_title = av_strdup(s->filename);
+    caca_set_display_title(c->display, c->window_title);
+    caca_set_display_time(c->display, av_rescale_q(1, st->codec->time_base, AV_TIME_BASE_Q));
+
+    return 0;
+
+fail:
+    caca_write_trailer(s);
+    return ret;
+}
+
+static int caca_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    CACAContext *c = s->priv_data;
+
+    caca_dither_bitmap(c->canvas, 0, 0, c->window_width, c->window_height, c->dither, pkt->data);
+    caca_refresh_display(c->display);
+
+    return 0;
+}
+
+#define OFFSET(x) offsetof(CACAContext,x)
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+
+static const AVOption options[] = {
+    { "window_size",  "set window forced size",  OFFSET(window_width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL }, 0, 0, ENC},
+    { "window_title", "set window title",        OFFSET(window_title), AV_OPT_TYPE_STRING,     {.str = NULL }, 0, 0, ENC },
+    { "driver",       "set display driver",      OFFSET(driver),    AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, ENC },
+    { "algorithm",    "set dithering algorithm", OFFSET(algorithm), AV_OPT_TYPE_STRING, {.str = "default" }, 0, 0, ENC },
+    { "antialias",    "set antialias method",    OFFSET(antialias), AV_OPT_TYPE_STRING, {.str = "default" }, 0, 0, ENC },
+    { "charset",      "set charset used to render output", OFFSET(charset), AV_OPT_TYPE_STRING, {.str = "default" }, 0, 0, ENC },
+    { "color",        "set color used to render output",   OFFSET(color),   AV_OPT_TYPE_STRING, {.str = "default" }, 0, 0, ENC },
+    { "list_drivers", "list available drivers",  OFFSET(list_drivers), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, ENC, "list_drivers" },
+    { "true",         NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, ENC, "list_drivers" },
+    { "false",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, ENC, "list_drivers" },
+    { "list_dither", "list available dither options", OFFSET(list_dither), AV_OPT_TYPE_STRING, {.dbl=0}, 0, 1, ENC, "list_dither" },
+    { "algorithms",   NULL, 0, AV_OPT_TYPE_CONST, {.str = "algorithms"}, 0, 0, ENC, "list_dither" },
+    { "antialiases",  NULL, 0, AV_OPT_TYPE_CONST, {.str = "antialiases"},0, 0, ENC, "list_dither" },
+    { "charsets",     NULL, 0, AV_OPT_TYPE_CONST, {.str = "charsets"},   0, 0, ENC, "list_dither" },
+    { "colors",       NULL, 0, AV_OPT_TYPE_CONST, {.str = "colors"},     0, 0, ENC, "list_dither" },
+    { NULL },
+};
+
+static const AVClass caca_class = {
+    .class_name = "caca_outdev",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVOutputFormat ff_caca_muxer = {
+    .name           = "caca",
+    .long_name      = NULL_IF_CONFIG_SMALL("caca (color ASCII art) output device"),
+    .priv_data_size = sizeof(CACAContext),
+    .audio_codec    = AV_CODEC_ID_NONE,
+    .video_codec    = AV_CODEC_ID_RAWVIDEO,
+    .write_header   = caca_write_header,
+    .write_packet   = caca_write_packet,
+    .write_trailer  = caca_write_trailer,
+    .flags          = AVFMT_NOFILE,
+    .priv_class     = &caca_class,
+};
diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c
new file mode 100644
index 0000000..3bd90b0
--- /dev/null
+++ b/libavdevice/dshow.c
@@ -0,0 +1,1054 @@
+/*
+ * Directshow capture interface
+ * Copyright (c) 2010 Ramiro Polla
+ *
+ * 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/parseutils.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/opt.h"
+#include "libavformat/internal.h"
+#include "avdevice.h"
+#include "dshow_capture.h"
+
+struct dshow_ctx {
+    const AVClass *class;
+
+    IGraphBuilder *graph;
+
+    char *device_name[2];
+    int video_device_number;
+    int audio_device_number;
+
+    int   list_options;
+    int   list_devices;
+    int   audio_buffer_size;
+
+    IBaseFilter *device_filter[2];
+    IPin        *device_pin[2];
+    libAVFilter *capture_filter[2];
+    libAVPin    *capture_pin[2];
+
+    HANDLE mutex;
+    HANDLE event;
+    AVPacketList *pktl;
+
+    int64_t curbufsize;
+    unsigned int video_frame_num;
+
+    IMediaControl *control;
+
+    enum AVPixelFormat pixel_format;
+    enum AVCodecID video_codec_id;
+    char *framerate;
+
+    int requested_width;
+    int requested_height;
+    AVRational requested_framerate;
+
+    int sample_rate;
+    int sample_size;
+    int channels;
+};
+
+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 */
+            case 1:
+                return AV_PIX_FMT_MONOWHITE;
+            case 4:
+                return AV_PIX_FMT_RGB4;
+            case 8:
+                return AV_PIX_FMT_RGB8;
+            case 16:
+                return AV_PIX_FMT_RGB555;
+            case 24:
+                return AV_PIX_FMT_BGR24;
+            case 32:
+                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;
+}
+
+static int
+dshow_read_close(AVFormatContext *s)
+{
+    struct dshow_ctx *ctx = s->priv_data;
+    AVPacketList *pktl;
+
+    if (ctx->control) {
+        IMediaControl_Stop(ctx->control);
+        IMediaControl_Release(ctx->control);
+    }
+
+    if (ctx->graph) {
+        IEnumFilters *fenum;
+        int r;
+        r = IGraphBuilder_EnumFilters(ctx->graph, &fenum);
+        if (r == S_OK) {
+            IBaseFilter *f;
+            IEnumFilters_Reset(fenum);
+            while (IEnumFilters_Next(fenum, 1, &f, NULL) == S_OK) {
+                if (IGraphBuilder_RemoveFilter(ctx->graph, f) == S_OK)
+                    IEnumFilters_Reset(fenum); /* When a filter is removed,
+                                                * the list must be reset. */
+                IBaseFilter_Release(f);
+            }
+            IEnumFilters_Release(fenum);
+        }
+        IGraphBuilder_Release(ctx->graph);
+    }
+
+    if (ctx->capture_pin[VideoDevice])
+        libAVPin_Release(ctx->capture_pin[VideoDevice]);
+    if (ctx->capture_pin[AudioDevice])
+        libAVPin_Release(ctx->capture_pin[AudioDevice]);
+    if (ctx->capture_filter[VideoDevice])
+        libAVFilter_Release(ctx->capture_filter[VideoDevice]);
+    if (ctx->capture_filter[AudioDevice])
+        libAVFilter_Release(ctx->capture_filter[AudioDevice]);
+
+    if (ctx->device_pin[VideoDevice])
+        IPin_Release(ctx->device_pin[VideoDevice]);
+    if (ctx->device_pin[AudioDevice])
+        IPin_Release(ctx->device_pin[AudioDevice]);
+    if (ctx->device_filter[VideoDevice])
+        IBaseFilter_Release(ctx->device_filter[VideoDevice]);
+    if (ctx->device_filter[AudioDevice])
+        IBaseFilter_Release(ctx->device_filter[AudioDevice]);
+
+    if (ctx->device_name[0])
+        av_free(ctx->device_name[0]);
+    if (ctx->device_name[1])
+        av_free(ctx->device_name[1]);
+
+    if(ctx->mutex)
+        CloseHandle(ctx->mutex);
+    if(ctx->event)
+        CloseHandle(ctx->event);
+
+    pktl = ctx->pktl;
+    while (pktl) {
+        AVPacketList *next = pktl->next;
+        av_destruct_packet(&pktl->pkt);
+        av_free(pktl);
+        pktl = next;
+    }
+
+    return 0;
+}
+
+static char *dup_wchar_to_utf8(wchar_t *w)
+{
+    char *s = NULL;
+    int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);
+    s = av_malloc(l);
+    if (s)
+        WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0);
+    return s;
+}
+
+static int shall_we_drop(AVFormatContext *s)
+{
+    struct dshow_ctx *ctx = s->priv_data;
+    const uint8_t dropscore[] = {62, 75, 87, 100};
+    const int ndropscores = FF_ARRAY_ELEMS(dropscore);
+    unsigned int buffer_fullness = (ctx->curbufsize*100)/s->max_picture_buffer;
+
+    if(dropscore[++ctx->video_frame_num%ndropscores] <= buffer_fullness) {
+        av_log(s, AV_LOG_ERROR,
+              "real-time buffer %d%% full! frame dropped!\n", buffer_fullness);
+        return 1;
+    }
+
+    return 0;
+}
+
+static void
+callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time)
+{
+    AVFormatContext *s = priv_data;
+    struct dshow_ctx *ctx = s->priv_data;
+    AVPacketList **ppktl, *pktl_next;
+
+//    dump_videohdr(s, vdhdr);
+
+    WaitForSingleObject(ctx->mutex, INFINITE);
+
+    if(shall_we_drop(s))
+        goto fail;
+
+    pktl_next = av_mallocz(sizeof(AVPacketList));
+    if(!pktl_next)
+        goto fail;
+
+    if(av_new_packet(&pktl_next->pkt, buf_size) < 0) {
+        av_free(pktl_next);
+        goto fail;
+    }
+
+    pktl_next->pkt.stream_index = index;
+    pktl_next->pkt.pts = time;
+    memcpy(pktl_next->pkt.data, buf, buf_size);
+
+    for(ppktl = &ctx->pktl ; *ppktl ; ppktl = &(*ppktl)->next);
+    *ppktl = pktl_next;
+
+    ctx->curbufsize += buf_size;
+
+    SetEvent(ctx->event);
+    ReleaseMutex(ctx->mutex);
+
+    return;
+fail:
+    ReleaseMutex(ctx->mutex);
+    return;
+}
+
+/**
+ * Cycle through available devices using the device enumerator devenum,
+ * retrieve the device with type specified by devtype and return the
+ * pointer to the object found in *pfilter.
+ * If pfilter is NULL, list all device names.
+ */
+static int
+dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum,
+                    enum dshowDeviceType devtype, IBaseFilter **pfilter)
+{
+    struct dshow_ctx *ctx = avctx->priv_data;
+    IBaseFilter *device_filter = NULL;
+    IEnumMoniker *classenum = NULL;
+    IMoniker *m = NULL;
+    const char *device_name = ctx->device_name[devtype];
+    int skip = (devtype == VideoDevice) ? ctx->video_device_number
+                                        : ctx->audio_device_number;
+    int r;
+
+    const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory,
+                                   &CLSID_AudioInputDeviceCategory };
+    const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
+
+    r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[devtype],
+                                             (IEnumMoniker **) &classenum, 0);
+    if (r != S_OK) {
+        av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices.\n",
+               devtypename);
+        return AVERROR(EIO);
+    }
+
+    while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) {
+        IPropertyBag *bag = NULL;
+        char *buf = NULL;
+        VARIANT var;
+
+        r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag);
+        if (r != S_OK)
+            goto fail1;
+
+        var.vt = VT_BSTR;
+        r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL);
+        if (r != S_OK)
+            goto fail1;
+
+        buf = dup_wchar_to_utf8(var.bstrVal);
+
+        if (pfilter) {
+            if (strcmp(device_name, buf))
+                goto fail1;
+
+            if (!skip--)
+                IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter);
+        } else {
+            av_log(avctx, AV_LOG_INFO, " \"%s\"\n", buf);
+        }
+
+fail1:
+        if (buf)
+            av_free(buf);
+        if (bag)
+            IPropertyBag_Release(bag);
+        IMoniker_Release(m);
+    }
+
+    IEnumMoniker_Release(classenum);
+
+    if (pfilter) {
+        if (!device_filter) {
+            av_log(avctx, AV_LOG_ERROR, "Could not find %s device.\n",
+                   devtypename);
+            return AVERROR(EIO);
+        }
+        *pfilter = device_filter;
+    }
+
+    return 0;
+}
+
+/**
+ * Cycle through available formats using the specified pin,
+ * try to set parameters specified through AVOptions and if successful
+ * return 1 in *pformat_set.
+ * If pformat_set is NULL, list all pin capabilities.
+ */
+static void
+dshow_cycle_formats(AVFormatContext *avctx, enum dshowDeviceType devtype,
+                    IPin *pin, int *pformat_set)
+{
+    struct dshow_ctx *ctx = avctx->priv_data;
+    IAMStreamConfig *config = NULL;
+    AM_MEDIA_TYPE *type = NULL;
+    int format_set = 0;
+    void *caps = NULL;
+    int i, n, size;
+
+    if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
+        return;
+    if (IAMStreamConfig_GetNumberOfCapabilities(config, &n, &size) != S_OK)
+        goto end;
+
+    caps = av_malloc(size);
+    if (!caps)
+        goto end;
+
+    for (i = 0; i < n && !format_set; i++) {
+        IAMStreamConfig_GetStreamCaps(config, i, &type, (void *) caps);
+
+#if DSHOWDEBUG
+        ff_print_AM_MEDIA_TYPE(type);
+#endif
+
+        if (devtype == VideoDevice) {
+            VIDEO_STREAM_CONFIG_CAPS *vcaps = caps;
+            BITMAPINFOHEADER *bih;
+            int64_t *fr;
+#if DSHOWDEBUG
+            ff_print_VIDEO_STREAM_CONFIG_CAPS(vcaps);
+#endif
+            if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
+                VIDEOINFOHEADER *v = (void *) type->pbFormat;
+                fr = &v->AvgTimePerFrame;
+                bih = &v->bmiHeader;
+            } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
+                VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
+                fr = &v->AvgTimePerFrame;
+                bih = &v->bmiHeader;
+            } else {
+                goto next;
+            }
+            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);
+                    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);
+                    } else {
+                        av_log(avctx, AV_LOG_INFO, "  vcodec=%s", codec->name);
+                    }
+                } else {
+                    av_log(avctx, AV_LOG_INFO, "  pixel_format=%s", av_get_pix_fmt_name(pix_fmt));
+                }
+                av_log(avctx, AV_LOG_INFO, "  min s=%ldx%ld fps=%g max s=%ldx%ld fps=%g\n",
+                       vcaps->MinOutputSize.cx, vcaps->MinOutputSize.cy,
+                       1e7 / vcaps->MaxFrameInterval,
+                       vcaps->MaxOutputSize.cx, vcaps->MaxOutputSize.cy,
+                       1e7 / vcaps->MinFrameInterval);
+                continue;
+            }
+            if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
+                if (ctx->video_codec_id != dshow_codecid(bih->biCompression))
+                    goto next;
+            }
+            if (ctx->pixel_format != AV_PIX_FMT_NONE &&
+                ctx->pixel_format != dshow_pixfmt(bih->biCompression, bih->biBitCount)) {
+                goto next;
+            }
+            if (ctx->framerate) {
+                int64_t framerate = ((int64_t) ctx->requested_framerate.den*10000000)
+                                            /  ctx->requested_framerate.num;
+                if (framerate > vcaps->MaxFrameInterval ||
+                    framerate < vcaps->MinFrameInterval)
+                    goto next;
+                *fr = framerate;
+            }
+            if (ctx->requested_width && ctx->requested_height) {
+                if (ctx->requested_width  > vcaps->MaxOutputSize.cx ||
+                    ctx->requested_width  < vcaps->MinOutputSize.cx ||
+                    ctx->requested_height > vcaps->MaxOutputSize.cy ||
+                    ctx->requested_height < vcaps->MinOutputSize.cy)
+                    goto next;
+                bih->biWidth  = ctx->requested_width;
+                bih->biHeight = ctx->requested_height;
+            }
+        } else {
+            AUDIO_STREAM_CONFIG_CAPS *acaps = caps;
+            WAVEFORMATEX *fx;
+#if DSHOWDEBUG
+            ff_print_AUDIO_STREAM_CONFIG_CAPS(acaps);
+#endif
+            if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
+                fx = (void *) type->pbFormat;
+            } else {
+                goto next;
+            }
+            if (!pformat_set) {
+                av_log(avctx, AV_LOG_INFO, "  min ch=%lu bits=%lu rate=%6lu max ch=%lu bits=%lu rate=%6lu\n",
+                       acaps->MinimumChannels, acaps->MinimumBitsPerSample, acaps->MinimumSampleFrequency,
+                       acaps->MaximumChannels, acaps->MaximumBitsPerSample, acaps->MaximumSampleFrequency);
+                continue;
+            }
+            if (ctx->sample_rate) {
+                if (ctx->sample_rate > acaps->MaximumSampleFrequency ||
+                    ctx->sample_rate < acaps->MinimumSampleFrequency)
+                    goto next;
+                fx->nSamplesPerSec = ctx->sample_rate;
+            }
+            if (ctx->sample_size) {
+                if (ctx->sample_size > acaps->MaximumBitsPerSample ||
+                    ctx->sample_size < acaps->MinimumBitsPerSample)
+                    goto next;
+                fx->wBitsPerSample = ctx->sample_size;
+            }
+            if (ctx->channels) {
+                if (ctx->channels > acaps->MaximumChannels ||
+                    ctx->channels < acaps->MinimumChannels)
+                    goto next;
+                fx->nChannels = ctx->channels;
+            }
+        }
+        if (IAMStreamConfig_SetFormat(config, type) != S_OK)
+            goto next;
+        format_set = 1;
+next:
+        if (type->pbFormat)
+            CoTaskMemFree(type->pbFormat);
+        CoTaskMemFree(type);
+    }
+end:
+    IAMStreamConfig_Release(config);
+    if (caps)
+        av_free(caps);
+    if (pformat_set)
+        *pformat_set = format_set;
+}
+
+/**
+ * Set audio device buffer size in milliseconds (which can directly impact
+ * latency, depending on the device).
+ */
+static int
+dshow_set_audio_buffer_size(AVFormatContext *avctx, IPin *pin)
+{
+    struct dshow_ctx *ctx = avctx->priv_data;
+    IAMBufferNegotiation *buffer_negotiation = NULL;
+    ALLOCATOR_PROPERTIES props = { -1, -1, -1, -1 };
+    IAMStreamConfig *config = NULL;
+    AM_MEDIA_TYPE *type = NULL;
+    int ret = AVERROR(EIO);
+
+    if (IPin_QueryInterface(pin, &IID_IAMStreamConfig, (void **) &config) != S_OK)
+        goto end;
+    if (IAMStreamConfig_GetFormat(config, &type) != S_OK)
+        goto end;
+    if (!IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx))
+        goto end;
+
+    props.cbBuffer = (((WAVEFORMATEX *) type->pbFormat)->nAvgBytesPerSec)
+                   * ctx->audio_buffer_size / 1000;
+
+    if (IPin_QueryInterface(pin, &IID_IAMBufferNegotiation, (void **) &buffer_negotiation) != S_OK)
+        goto end;
+    if (IAMBufferNegotiation_SuggestAllocatorProperties(buffer_negotiation, &props) != S_OK)
+        goto end;
+
+    ret = 0;
+
+end:
+    if (buffer_negotiation)
+        IAMBufferNegotiation_Release(buffer_negotiation);
+    if (type) {
+        if (type->pbFormat)
+            CoTaskMemFree(type->pbFormat);
+        CoTaskMemFree(type);
+    }
+    if (config)
+        IAMStreamConfig_Release(config);
+
+    return ret;
+}
+
+/**
+ * Cycle through available pins using the device_filter device, of type
+ * devtype, retrieve the first output pin and return the pointer to the
+ * object found in *ppin.
+ * If ppin is NULL, cycle through all pins listing audio/video capabilities.
+ */
+static int
+dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,
+                 IBaseFilter *device_filter, IPin **ppin)
+{
+    struct dshow_ctx *ctx = avctx->priv_data;
+    IEnumPins *pins = 0;
+    IPin *device_pin = NULL;
+    IPin *pin;
+    int r;
+
+    const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };
+    const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";
+
+    int set_format = (devtype == VideoDevice && (ctx->framerate ||
+                                                (ctx->requested_width && ctx->requested_height) ||
+                                                 ctx->pixel_format != AV_PIX_FMT_NONE ||
+                                                 ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO))
+                  || (devtype == AudioDevice && (ctx->channels || ctx->sample_rate));
+    int format_set = 0;
+
+    r = IBaseFilter_EnumPins(device_filter, &pins);
+    if (r != S_OK) {
+        av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n");
+        return AVERROR(EIO);
+    }
+
+    if (!ppin) {
+        av_log(avctx, AV_LOG_INFO, "DirectShow %s device options\n",
+               devtypename);
+    }
+    while (!device_pin && IEnumPins_Next(pins, 1, &pin, NULL) == S_OK) {
+        IKsPropertySet *p = NULL;
+        IEnumMediaTypes *types = NULL;
+        PIN_INFO info = {0};
+        AM_MEDIA_TYPE *type;
+        GUID category;
+        DWORD r2;
+
+        IPin_QueryPinInfo(pin, &info);
+        IBaseFilter_Release(info.pFilter);
+
+        if (info.dir != PINDIR_OUTPUT)
+            goto next;
+        if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)
+            goto next;
+        if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,
+                               NULL, 0, &category, sizeof(GUID), &r2) != S_OK)
+            goto next;
+        if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))
+            goto next;
+
+        if (!ppin) {
+            char *buf = dup_wchar_to_utf8(info.achName);
+            av_log(avctx, AV_LOG_INFO, " Pin \"%s\"\n", buf);
+            av_free(buf);
+            dshow_cycle_formats(avctx, devtype, pin, NULL);
+            goto next;
+        }
+        if (set_format) {
+            dshow_cycle_formats(avctx, devtype, pin, &format_set);
+            if (!format_set) {
+                goto next;
+            }
+        }
+        if (devtype == AudioDevice && ctx->audio_buffer_size) {
+            if (dshow_set_audio_buffer_size(avctx, pin) < 0)
+                goto next;
+        }
+
+        if (IPin_EnumMediaTypes(pin, &types) != S_OK)
+            goto next;
+
+        IEnumMediaTypes_Reset(types);
+        while (!device_pin && IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK) {
+            if (IsEqualGUID(&type->majortype, mediatype[devtype])) {
+                device_pin = pin;
+                goto next;
+            }
+            CoTaskMemFree(type);
+        }
+
+next:
+        if (types)
+            IEnumMediaTypes_Release(types);
+        if (p)
+            IKsPropertySet_Release(p);
+        if (device_pin != pin)
+            IPin_Release(pin);
+    }
+
+    IEnumPins_Release(pins);
+
+    if (ppin) {
+        if (set_format && !format_set) {
+            av_log(avctx, AV_LOG_ERROR, "Could not set %s options\n", devtypename);
+            return AVERROR(EIO);
+        }
+        if (!device_pin) {
+            av_log(avctx, AV_LOG_ERROR,
+                "Could not find output pin from %s capture device.\n", devtypename);
+            return AVERROR(EIO);
+        }
+        *ppin = device_pin;
+    }
+
+    return 0;
+}
+
+/**
+ * List options for device with type devtype.
+ *
+ * @param devenum device enumerator used for accessing the device
+ */
+static int
+dshow_list_device_options(AVFormatContext *avctx, ICreateDevEnum *devenum,
+                          enum dshowDeviceType devtype)
+{
+    struct dshow_ctx *ctx = avctx->priv_data;
+    IBaseFilter *device_filter = NULL;
+    int r;
+
+    if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0)
+        return r;
+    ctx->device_filter[devtype] = device_filter;
+    if ((r = dshow_cycle_pins(avctx, devtype, device_filter, NULL)) < 0)
+        return r;
+
+    return 0;
+}
+
+static int
+dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum,
+                  enum dshowDeviceType devtype)
+{
+    struct dshow_ctx *ctx = avctx->priv_data;
+    IBaseFilter *device_filter = NULL;
+    IGraphBuilder *graph = ctx->graph;
+    IPin *device_pin = NULL;
+    libAVPin *capture_pin = NULL;
+    libAVFilter *capture_filter = NULL;
+    int ret = AVERROR(EIO);
+    int r;
+
+    const wchar_t *filter_name[2] = { L"Audio capture filter", L"Video capture filter" };
+
+    if ((r = dshow_cycle_devices(avctx, devenum, devtype, &device_filter)) < 0) {
+        ret = r;
+        goto error;
+    }
+
+    ctx->device_filter [devtype] = device_filter;
+
+    r = IGraphBuilder_AddFilter(graph, device_filter, NULL);
+    if (r != S_OK) {
+        av_log(avctx, AV_LOG_ERROR, "Could not add device filter to graph.\n");
+        goto error;
+    }
+
+    if ((r = dshow_cycle_pins(avctx, devtype, device_filter, &device_pin)) < 0) {
+        ret = r;
+        goto error;
+    }
+    ctx->device_pin[devtype] = device_pin;
+
+    capture_filter = libAVFilter_Create(avctx, callback, devtype);
+    if (!capture_filter) {
+        av_log(avctx, AV_LOG_ERROR, "Could not create grabber filter.\n");
+        goto error;
+    }
+    ctx->capture_filter[devtype] = capture_filter;
+
+    r = IGraphBuilder_AddFilter(graph, (IBaseFilter *) capture_filter,
+                                filter_name[devtype]);
+    if (r != S_OK) {
+        av_log(avctx, AV_LOG_ERROR, "Could not add capture filter to graph\n");
+        goto error;
+    }
+
+    libAVPin_AddRef(capture_filter->pin);
+    capture_pin = capture_filter->pin;
+    ctx->capture_pin[devtype] = capture_pin;
+
+    r = IGraphBuilder_ConnectDirect(graph, device_pin, (IPin *) capture_pin, NULL);
+    if (r != S_OK) {
+        av_log(avctx, AV_LOG_ERROR, "Could not connect pins\n");
+        goto error;
+    }
+
+    ret = 0;
+
+error:
+    return ret;
+}
+
+static enum AVCodecID waveform_codec_id(enum AVSampleFormat sample_fmt)
+{
+    switch (sample_fmt) {
+    case AV_SAMPLE_FMT_U8:  return AV_CODEC_ID_PCM_U8;
+    case AV_SAMPLE_FMT_S16: return AV_CODEC_ID_PCM_S16LE;
+    case AV_SAMPLE_FMT_S32: return AV_CODEC_ID_PCM_S32LE;
+    default:                return AV_CODEC_ID_NONE; /* Should never happen. */
+    }
+}
+
+static enum AVSampleFormat sample_fmt_bits_per_sample(int bits)
+{
+    switch (bits) {
+    case 8:  return AV_SAMPLE_FMT_U8;
+    case 16: return AV_SAMPLE_FMT_S16;
+    case 32: return AV_SAMPLE_FMT_S32;
+    default: return AV_SAMPLE_FMT_NONE; /* Should never happen. */
+    }
+}
+
+static int
+dshow_add_device(AVFormatContext *avctx,
+                 enum dshowDeviceType devtype)
+{
+    struct dshow_ctx *ctx = avctx->priv_data;
+    AM_MEDIA_TYPE type;
+    AVCodecContext *codec;
+    AVStream *st;
+    int ret = AVERROR(EIO);
+
+    st = avformat_new_stream(avctx, NULL);
+    if (!st) {
+        ret = AVERROR(ENOMEM);
+        goto error;
+    }
+    st->id = devtype;
+
+    ctx->capture_filter[devtype]->stream_index = st->index;
+
+    libAVPin_ConnectionMediaType(ctx->capture_pin[devtype], &type);
+
+    codec = st->codec;
+    if (devtype == VideoDevice) {
+        BITMAPINFOHEADER *bih = NULL;
+        AVRational time_base;
+
+        if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo)) {
+            VIDEOINFOHEADER *v = (void *) type.pbFormat;
+            time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
+            bih = &v->bmiHeader;
+        } else if (IsEqualGUID(&type.formattype, &FORMAT_VideoInfo2)) {
+            VIDEOINFOHEADER2 *v = (void *) type.pbFormat;
+            time_base = (AVRational) { v->AvgTimePerFrame, 10000000 };
+            bih = &v->bmiHeader;
+        }
+        if (!bih) {
+            av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
+            goto error;
+        }
+
+        codec->time_base  = time_base;
+        codec->codec_type = AVMEDIA_TYPE_VIDEO;
+        codec->width      = bih->biWidth;
+        codec->height     = bih->biHeight;
+        codec->pix_fmt    = dshow_pixfmt(bih->biCompression, bih->biBitCount);
+        if (codec->pix_fmt == AV_PIX_FMT_NONE) {
+            codec->codec_id = dshow_codecid(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);
+                return AVERROR_PATCHWELCOME;
+            }
+            codec->bits_per_coded_sample = bih->biBitCount;
+        } else {
+            codec->codec_id = AV_CODEC_ID_RAWVIDEO;
+            if (bih->biCompression == BI_RGB || bih->biCompression == BI_BITFIELDS) {
+                codec->bits_per_coded_sample = bih->biBitCount;
+                codec->extradata = av_malloc(9 + FF_INPUT_BUFFER_PADDING_SIZE);
+                if (codec->extradata) {
+                    codec->extradata_size = 9;
+                    memcpy(codec->extradata, "BottomUp", 9);
+                }
+            }
+        }
+    } else {
+        WAVEFORMATEX *fx = NULL;
+
+        if (IsEqualGUID(&type.formattype, &FORMAT_WaveFormatEx)) {
+            fx = (void *) type.pbFormat;
+        }
+        if (!fx) {
+            av_log(avctx, AV_LOG_ERROR, "Could not get media type.\n");
+            goto error;
+        }
+
+        codec->codec_type  = AVMEDIA_TYPE_AUDIO;
+        codec->sample_fmt  = sample_fmt_bits_per_sample(fx->wBitsPerSample);
+        codec->codec_id    = waveform_codec_id(codec->sample_fmt);
+        codec->sample_rate = fx->nSamplesPerSec;
+        codec->channels    = fx->nChannels;
+    }
+
+    avpriv_set_pts_info(st, 64, 1, 10000000);
+
+    ret = 0;
+
+error:
+    return ret;
+}
+
+static int parse_device_name(AVFormatContext *avctx)
+{
+    struct dshow_ctx *ctx = avctx->priv_data;
+    char **device_name = ctx->device_name;
+    char *name = av_strdup(avctx->filename);
+    char *tmp = name;
+    int ret = 1;
+    char *type;
+
+    while ((type = strtok(tmp, "="))) {
+        char *token = strtok(NULL, ":");
+        tmp = NULL;
+
+        if        (!strcmp(type, "video")) {
+            device_name[0] = token;
+        } else if (!strcmp(type, "audio")) {
+            device_name[1] = token;
+        } else {
+            device_name[0] = NULL;
+            device_name[1] = NULL;
+            break;
+        }
+    }
+
+    if (!device_name[0] && !device_name[1]) {
+        ret = 0;
+    } else {
+        if (device_name[0])
+            device_name[0] = av_strdup(device_name[0]);
+        if (device_name[1])
+            device_name[1] = av_strdup(device_name[1]);
+    }
+
+    av_free(name);
+    return ret;
+}
+
+static int dshow_read_header(AVFormatContext *avctx)
+{
+    struct dshow_ctx *ctx = avctx->priv_data;
+    IGraphBuilder *graph = NULL;
+    ICreateDevEnum *devenum = NULL;
+    IMediaControl *control = NULL;
+    int ret = AVERROR(EIO);
+    int r;
+
+    if (!ctx->list_devices && !parse_device_name(avctx)) {
+        av_log(avctx, AV_LOG_ERROR, "Malformed dshow input string.\n");
+        goto error;
+    }
+
+    ctx->video_codec_id = avctx->video_codec_id ? avctx->video_codec_id
+                                                : AV_CODEC_ID_RAWVIDEO;
+    if (ctx->pixel_format != AV_PIX_FMT_NONE) {
+        if (ctx->video_codec_id != AV_CODEC_ID_RAWVIDEO) {
+            av_log(avctx, AV_LOG_ERROR, "Pixel format may only be set when "
+                              "video codec is not set or set to rawvideo\n");
+            ret = AVERROR(EINVAL);
+            goto error;
+        }
+    }
+    if (ctx->framerate) {
+        r = av_parse_video_rate(&ctx->requested_framerate, ctx->framerate);
+        if (r < 0) {
+            av_log(avctx, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate);
+            goto error;
+        }
+    }
+
+    CoInitialize(0);
+
+    r = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
+                         &IID_IGraphBuilder, (void **) &graph);
+    if (r != S_OK) {
+        av_log(avctx, AV_LOG_ERROR, "Could not create capture graph.\n");
+        goto error;
+    }
+    ctx->graph = graph;
+
+    r = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
+                         &IID_ICreateDevEnum, (void **) &devenum);
+    if (r != S_OK) {
+        av_log(avctx, AV_LOG_ERROR, "Could not enumerate system devices.\n");
+        goto error;
+    }
+
+    if (ctx->list_devices) {
+        av_log(avctx, AV_LOG_INFO, "DirectShow video devices\n");
+        dshow_cycle_devices(avctx, devenum, VideoDevice, NULL);
+        av_log(avctx, AV_LOG_INFO, "DirectShow audio devices\n");
+        dshow_cycle_devices(avctx, devenum, AudioDevice, NULL);
+        ret = AVERROR_EXIT;
+        goto error;
+    }
+    if (ctx->list_options) {
+        if (ctx->device_name[VideoDevice])
+            dshow_list_device_options(avctx, devenum, VideoDevice);
+        if (ctx->device_name[AudioDevice])
+            dshow_list_device_options(avctx, devenum, AudioDevice);
+        ret = AVERROR_EXIT;
+        goto error;
+    }
+
+    if (ctx->device_name[VideoDevice]) {
+        ret = dshow_open_device(avctx, devenum, VideoDevice);
+        if (ret < 0)
+            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)
+            goto error;
+        ret = dshow_add_device(avctx, AudioDevice);
+        if (ret < 0)
+            goto error;
+    }
+
+    ctx->mutex = CreateMutex(NULL, 0, NULL);
+    if (!ctx->mutex) {
+        av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
+        goto error;
+    }
+    ctx->event = CreateEvent(NULL, 1, 0, NULL);
+    if (!ctx->event) {
+        av_log(avctx, AV_LOG_ERROR, "Could not create Event\n");
+        goto error;
+    }
+
+    r = IGraphBuilder_QueryInterface(graph, &IID_IMediaControl, (void **) &control);
+    if (r != S_OK) {
+        av_log(avctx, AV_LOG_ERROR, "Could not get media control.\n");
+        goto error;
+    }
+    ctx->control = control;
+
+    r = IMediaControl_Run(control);
+    if (r == S_FALSE) {
+        OAFilterState pfs;
+        r = IMediaControl_GetState(control, 0, &pfs);
+    }
+    if (r != S_OK) {
+        av_log(avctx, AV_LOG_ERROR, "Could not run filter\n");
+        goto error;
+    }
+
+    ret = 0;
+
+error:
+
+    if (ret < 0)
+        dshow_read_close(avctx);
+
+    if (devenum)
+        ICreateDevEnum_Release(devenum);
+
+    return ret;
+}
+
+static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    struct dshow_ctx *ctx = s->priv_data;
+    AVPacketList *pktl = NULL;
+
+    while (!pktl) {
+        WaitForSingleObject(ctx->mutex, INFINITE);
+        pktl = ctx->pktl;
+        if (pktl) {
+            *pkt = pktl->pkt;
+            ctx->pktl = ctx->pktl->next;
+            av_free(pktl);
+            ctx->curbufsize -= pkt->size;
+        }
+        ResetEvent(ctx->event);
+        ReleaseMutex(ctx->mutex);
+        if (!pktl) {
+            if (s->flags & AVFMT_FLAG_NONBLOCK) {
+                return AVERROR(EAGAIN);
+            } else {
+                WaitForSingleObject(ctx->event, INFINITE);
+            }
+        }
+    }
+
+    return pkt->size;
+}
+
+#define OFFSET(x) offsetof(struct dshow_ctx, x)
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+    { "video_size", "set video size given a string such as 640x480 or hd720.", OFFSET(requested_width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, DEC },
+    { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_PIXEL_FMT, {.str = NULL}, 0, 0, DEC },
+    { "framerate", "set video frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+    { "sample_rate", "set audio sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
+    { "sample_size", "set audio sample size", OFFSET(sample_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 16, DEC },
+    { "channels", "set number of audio channels, such as 1 or 2", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
+    { "list_devices", "list available devices", OFFSET(list_devices), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, DEC, "list_devices" },
+    { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "list_devices" },
+    { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "list_devices" },
+    { "list_options", "list available options for specified device", OFFSET(list_options), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, DEC, "list_options" },
+    { "true", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, DEC, "list_options" },
+    { "false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, DEC, "list_options" },
+    { "video_device_number", "set video device number for devices with same name (starts at 0)", OFFSET(video_device_number), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
+    { "audio_device_number", "set audio device number for devices with same name (starts at 0)", OFFSET(audio_device_number), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
+    { "audio_buffer_size", "set audio device buffer latency size in milliseconds (default is the device's default)", OFFSET(audio_buffer_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC },
+    { NULL },
+};
+
+static const AVClass dshow_class = {
+    .class_name = "DirectShow indev",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_dshow_demuxer = {
+    .name           = "dshow",
+    .long_name      = NULL_IF_CONFIG_SMALL("DirectShow capture"),
+    .priv_data_size = sizeof(struct dshow_ctx),
+    .read_header    = dshow_read_header,
+    .read_packet    = dshow_read_packet,
+    .read_close     = dshow_read_close,
+    .flags          = AVFMT_NOFILE,
+    .priv_class     = &dshow_class,
+};
diff --git a/libavdevice/dshow_capture.h b/libavdevice/dshow_capture.h
new file mode 100644
index 0000000..e34f14f
--- /dev/null
+++ b/libavdevice/dshow_capture.h
@@ -0,0 +1,273 @@
+/*
+ * DirectShow capture interface
+ * Copyright (c) 2010 Ramiro Polla
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVDEVICE_DSHOW_H
+#define AVDEVICE_DSHOW_H
+
+#define DSHOWDEBUG 0
+
+#include "avdevice.h"
+
+#define COBJMACROS
+#include <windows.h>
+#include <dshow.h>
+#include <dvdmedia.h>
+
+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);
+void ff_print_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *type);
+void ff_printGUID(const GUID *g);
+
+#if DSHOWDEBUG
+extern const AVClass *ff_dshow_context_class_ptr;
+#define dshowdebug(...) av_log(&ff_dshow_context_class_ptr, AV_LOG_DEBUG, __VA_ARGS__)
+#else
+#define dshowdebug(...)
+#endif
+
+static inline void nothing(void *foo)
+{
+}
+
+struct GUIDoffset {
+    const GUID *iid;
+    int offset;
+};
+
+enum dshowDeviceType {
+    VideoDevice = 0,
+    AudioDevice = 1,
+};
+
+#define DECLARE_QUERYINTERFACE(class, ...)                                   \
+long WINAPI                                                                  \
+class##_QueryInterface(class *this, const GUID *riid, void **ppvObject)      \
+{                                                                            \
+    struct GUIDoffset ifaces[] = __VA_ARGS__;                                \
+    int i;                                                                   \
+    dshowdebug(AV_STRINGIFY(class)"_QueryInterface(%p, %p, %p)\n", this, riid, ppvObject); \
+    ff_printGUID(riid);                                                      \
+    if (!ppvObject)                                                          \
+        return E_POINTER;                                                    \
+    for (i = 0; i < sizeof(ifaces)/sizeof(ifaces[0]); i++) {                 \
+        if (IsEqualGUID(riid, ifaces[i].iid)) {                              \
+            void *obj = (void *) ((uint8_t *) this + ifaces[i].offset);      \
+            class##_AddRef(this);                                            \
+            dshowdebug("\tfound %d with offset %d\n", i, ifaces[i].offset);  \
+            *ppvObject = (void *) obj;                                       \
+            return S_OK;                                                     \
+        }                                                                    \
+    }                                                                        \
+    dshowdebug("\tE_NOINTERFACE\n");                                         \
+    *ppvObject = NULL;                                                       \
+    return E_NOINTERFACE;                                                    \
+}
+#define DECLARE_ADDREF(class)                                                \
+unsigned long WINAPI                                                         \
+class##_AddRef(class *this)                                                  \
+{                                                                            \
+    dshowdebug(AV_STRINGIFY(class)"_AddRef(%p)\t%ld\n", this, this->ref+1);  \
+    return InterlockedIncrement(&this->ref);                                 \
+}
+#define DECLARE_RELEASE(class)                                               \
+unsigned long WINAPI                                                         \
+class##_Release(class *this)                                                 \
+{                                                                            \
+    long ref = InterlockedDecrement(&this->ref);                             \
+    dshowdebug(AV_STRINGIFY(class)"_Release(%p)\t%ld\n", this, ref);         \
+    if (!ref)                                                                \
+        class##_Destroy(this);                                               \
+    return ref;                                                              \
+}
+
+#define DECLARE_DESTROY(class, func)                                         \
+void class##_Destroy(class *this)                                            \
+{                                                                            \
+    dshowdebug(AV_STRINGIFY(class)"_Destroy(%p)\n", this);                   \
+    func(this);                                                              \
+    if (this) {                                                              \
+        if (this->vtbl)                                                      \
+            CoTaskMemFree(this->vtbl);                                       \
+        CoTaskMemFree(this);                                                 \
+    }                                                                        \
+}
+#define DECLARE_CREATE(class, setup, ...)                                    \
+class *class##_Create(__VA_ARGS__)                                           \
+{                                                                            \
+    class *this = CoTaskMemAlloc(sizeof(class));                             \
+    void  *vtbl = CoTaskMemAlloc(sizeof(*this->vtbl));                       \
+    dshowdebug(AV_STRINGIFY(class)"_Create(%p)\n", this);                    \
+    if (!this || !vtbl)                                                      \
+        goto fail;                                                           \
+    ZeroMemory(this, sizeof(class));                                         \
+    ZeroMemory(vtbl, sizeof(*this->vtbl));                                   \
+    this->ref  = 1;                                                          \
+    this->vtbl = vtbl;                                                       \
+    if (!setup)                                                              \
+        goto fail;                                                           \
+    dshowdebug("created "AV_STRINGIFY(class)" %p\n", this);                  \
+    return this;                                                             \
+fail:                                                                        \
+    class##_Destroy(this);                                                   \
+    dshowdebug("could not create "AV_STRINGIFY(class)"\n");                  \
+    return NULL;                                                             \
+}
+
+#define SETVTBL(vtbl, class, fn) \
+    do { (vtbl)->fn = (void *) class##_##fn; } while(0)
+
+/*****************************************************************************
+ * Forward Declarations
+ ****************************************************************************/
+typedef struct libAVPin libAVPin;
+typedef struct libAVMemInputPin libAVMemInputPin;
+typedef struct libAVEnumPins libAVEnumPins;
+typedef struct libAVEnumMediaTypes libAVEnumMediaTypes;
+typedef struct libAVFilter libAVFilter;
+
+/*****************************************************************************
+ * libAVPin
+ ****************************************************************************/
+struct libAVPin {
+    IPinVtbl *vtbl;
+    long ref;
+    libAVFilter *filter;
+    IPin *connectedto;
+    AM_MEDIA_TYPE type;
+    IMemInputPinVtbl *imemvtbl;
+};
+
+long          WINAPI libAVPin_QueryInterface          (libAVPin *, const GUID *, void **);
+unsigned long WINAPI libAVPin_AddRef                  (libAVPin *);
+unsigned long WINAPI libAVPin_Release                 (libAVPin *);
+long          WINAPI libAVPin_Connect                 (libAVPin *, IPin *, const AM_MEDIA_TYPE *);
+long          WINAPI libAVPin_ReceiveConnection       (libAVPin *, IPin *, const AM_MEDIA_TYPE *);
+long          WINAPI libAVPin_Disconnect              (libAVPin *);
+long          WINAPI libAVPin_ConnectedTo             (libAVPin *, IPin **);
+long          WINAPI libAVPin_ConnectionMediaType     (libAVPin *, AM_MEDIA_TYPE *);
+long          WINAPI libAVPin_QueryPinInfo            (libAVPin *, PIN_INFO *);
+long          WINAPI libAVPin_QueryDirection          (libAVPin *, PIN_DIRECTION *);
+long          WINAPI libAVPin_QueryId                 (libAVPin *, wchar_t **);
+long          WINAPI libAVPin_QueryAccept             (libAVPin *, const AM_MEDIA_TYPE *);
+long          WINAPI libAVPin_EnumMediaTypes          (libAVPin *, IEnumMediaTypes **);
+long          WINAPI libAVPin_QueryInternalConnections(libAVPin *, IPin **, unsigned long *);
+long          WINAPI libAVPin_EndOfStream             (libAVPin *);
+long          WINAPI libAVPin_BeginFlush              (libAVPin *);
+long          WINAPI libAVPin_EndFlush                (libAVPin *);
+long          WINAPI libAVPin_NewSegment              (libAVPin *, REFERENCE_TIME, REFERENCE_TIME, double);
+
+long          WINAPI libAVMemInputPin_QueryInterface          (libAVMemInputPin *, const GUID *, void **);
+unsigned long WINAPI libAVMemInputPin_AddRef                  (libAVMemInputPin *);
+unsigned long WINAPI libAVMemInputPin_Release                 (libAVMemInputPin *);
+long          WINAPI libAVMemInputPin_GetAllocator            (libAVMemInputPin *, IMemAllocator **);
+long          WINAPI libAVMemInputPin_NotifyAllocator         (libAVMemInputPin *, IMemAllocator *, BOOL);
+long          WINAPI libAVMemInputPin_GetAllocatorRequirements(libAVMemInputPin *, ALLOCATOR_PROPERTIES *);
+long          WINAPI libAVMemInputPin_Receive                 (libAVMemInputPin *, IMediaSample *);
+long          WINAPI libAVMemInputPin_ReceiveMultiple         (libAVMemInputPin *, IMediaSample **, long, long *);
+long          WINAPI libAVMemInputPin_ReceiveCanBlock         (libAVMemInputPin *);
+
+void                 libAVPin_Destroy(libAVPin *);
+libAVPin            *libAVPin_Create (libAVFilter *filter);
+
+void                 libAVMemInputPin_Destroy(libAVMemInputPin *);
+
+/*****************************************************************************
+ * libAVEnumPins
+ ****************************************************************************/
+struct libAVEnumPins {
+    IEnumPinsVtbl *vtbl;
+    long ref;
+    int pos;
+    libAVPin *pin;
+    libAVFilter *filter;
+};
+
+long          WINAPI libAVEnumPins_QueryInterface(libAVEnumPins *, const GUID *, void **);
+unsigned long WINAPI libAVEnumPins_AddRef        (libAVEnumPins *);
+unsigned long WINAPI libAVEnumPins_Release       (libAVEnumPins *);
+long          WINAPI libAVEnumPins_Next          (libAVEnumPins *, unsigned long, IPin **, unsigned long *);
+long          WINAPI libAVEnumPins_Skip          (libAVEnumPins *, unsigned long);
+long          WINAPI libAVEnumPins_Reset         (libAVEnumPins *);
+long          WINAPI libAVEnumPins_Clone         (libAVEnumPins *, libAVEnumPins **);
+
+void                 libAVEnumPins_Destroy(libAVEnumPins *);
+libAVEnumPins       *libAVEnumPins_Create (libAVPin *pin, libAVFilter *filter);
+
+/*****************************************************************************
+ * libAVEnumMediaTypes
+ ****************************************************************************/
+struct libAVEnumMediaTypes {
+    IEnumPinsVtbl *vtbl;
+    long ref;
+    int pos;
+    AM_MEDIA_TYPE type;
+};
+
+long          WINAPI libAVEnumMediaTypes_QueryInterface(libAVEnumMediaTypes *, const GUID *, void **);
+unsigned long WINAPI libAVEnumMediaTypes_AddRef        (libAVEnumMediaTypes *);
+unsigned long WINAPI libAVEnumMediaTypes_Release       (libAVEnumMediaTypes *);
+long          WINAPI libAVEnumMediaTypes_Next          (libAVEnumMediaTypes *, unsigned long, AM_MEDIA_TYPE **, unsigned long *);
+long          WINAPI libAVEnumMediaTypes_Skip          (libAVEnumMediaTypes *, unsigned long);
+long          WINAPI libAVEnumMediaTypes_Reset         (libAVEnumMediaTypes *);
+long          WINAPI libAVEnumMediaTypes_Clone         (libAVEnumMediaTypes *, libAVEnumMediaTypes **);
+
+void                 libAVEnumMediaTypes_Destroy(libAVEnumMediaTypes *);
+libAVEnumMediaTypes *libAVEnumMediaTypes_Create(const AM_MEDIA_TYPE *type);
+
+/*****************************************************************************
+ * libAVFilter
+ ****************************************************************************/
+struct libAVFilter {
+    IBaseFilterVtbl *vtbl;
+    long ref;
+    const wchar_t *name;
+    libAVPin *pin;
+    FILTER_INFO info;
+    FILTER_STATE state;
+    IReferenceClock *clock;
+    enum dshowDeviceType type;
+    void *priv_data;
+    int stream_index;
+    int64_t start_time;
+    void (*callback)(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time);
+};
+
+long          WINAPI libAVFilter_QueryInterface (libAVFilter *, const GUID *, void **);
+unsigned long WINAPI libAVFilter_AddRef         (libAVFilter *);
+unsigned long WINAPI libAVFilter_Release        (libAVFilter *);
+long          WINAPI libAVFilter_GetClassID     (libAVFilter *, CLSID *);
+long          WINAPI libAVFilter_Stop           (libAVFilter *);
+long          WINAPI libAVFilter_Pause          (libAVFilter *);
+long          WINAPI libAVFilter_Run            (libAVFilter *, REFERENCE_TIME);
+long          WINAPI libAVFilter_GetState       (libAVFilter *, DWORD, FILTER_STATE *);
+long          WINAPI libAVFilter_SetSyncSource  (libAVFilter *, IReferenceClock *);
+long          WINAPI libAVFilter_GetSyncSource  (libAVFilter *, IReferenceClock **);
+long          WINAPI libAVFilter_EnumPins       (libAVFilter *, IEnumPins **);
+long          WINAPI libAVFilter_FindPin        (libAVFilter *, const wchar_t *, IPin **);
+long          WINAPI libAVFilter_QueryFilterInfo(libAVFilter *, FILTER_INFO *);
+long          WINAPI libAVFilter_JoinFilterGraph(libAVFilter *, IFilterGraph *, const wchar_t *);
+long          WINAPI libAVFilter_QueryVendorInfo(libAVFilter *, wchar_t **);
+
+void                 libAVFilter_Destroy(libAVFilter *);
+libAVFilter         *libAVFilter_Create (void *, void *, enum dshowDeviceType);
+
+#endif /* AVDEVICE_DSHOW_H */
diff --git a/libavdevice/dshow_common.c b/libavdevice/dshow_common.c
new file mode 100644
index 0000000..f7f0dfb
--- /dev/null
+++ b/libavdevice/dshow_common.c
@@ -0,0 +1,190 @@
+/*
+ * Directshow capture interface
+ * Copyright (c) 2010 Ramiro Polla
+ *
+ * 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 "dshow_capture.h"
+
+long ff_copy_dshow_media_type(AM_MEDIA_TYPE *dst, const AM_MEDIA_TYPE *src)
+{
+    uint8_t *pbFormat = NULL;
+
+    if (src->cbFormat) {
+        pbFormat = CoTaskMemAlloc(src->cbFormat);
+        if (!pbFormat)
+            return E_OUTOFMEMORY;
+        memcpy(pbFormat, src->pbFormat, src->cbFormat);
+    }
+
+    *dst = *src;
+    dst->pUnk = NULL;
+    dst->pbFormat = pbFormat;
+
+    return S_OK;
+}
+
+void ff_printGUID(const GUID *g)
+{
+#if DSHOWDEBUG
+    const uint32_t *d = (const uint32_t *) &g->Data1;
+    const uint16_t *w = (const uint16_t *) &g->Data2;
+    const uint8_t  *c = (const uint8_t  *) &g->Data4;
+
+    dshowdebug("0x%08x 0x%04x 0x%04x %02x%02x%02x%02x%02x%02x%02x%02x",
+               d[0], w[0], w[1],
+               c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
+#endif
+}
+
+static const char *dshow_context_to_name(void *ptr)
+{
+    return "dshow";
+}
+static const AVClass ff_dshow_context_class = { "DirectShow", dshow_context_to_name };
+const AVClass *ff_dshow_context_class_ptr = &ff_dshow_context_class;
+
+#define dstruct(pctx, sname, var, type) \
+    dshowdebug("      "#var":\t%"type"\n", sname->var)
+
+#if DSHOWDEBUG
+static void dump_bih(void *s, BITMAPINFOHEADER *bih)
+{
+    dshowdebug("      BITMAPINFOHEADER\n");
+    dstruct(s, bih, biSize, "lu");
+    dstruct(s, bih, biWidth, "ld");
+    dstruct(s, bih, biHeight, "ld");
+    dstruct(s, bih, biPlanes, "d");
+    dstruct(s, bih, biBitCount, "d");
+    dstruct(s, bih, biCompression, "lu");
+    dshowdebug("      biCompression:\t\"%.4s\"\n",
+                   (char*) &bih->biCompression);
+    dstruct(s, bih, biSizeImage, "lu");
+    dstruct(s, bih, biXPelsPerMeter, "lu");
+    dstruct(s, bih, biYPelsPerMeter, "lu");
+    dstruct(s, bih, biClrUsed, "lu");
+    dstruct(s, bih, biClrImportant, "lu");
+}
+#endif
+
+void ff_print_VIDEO_STREAM_CONFIG_CAPS(const VIDEO_STREAM_CONFIG_CAPS *caps)
+{
+#if DSHOWDEBUG
+    dshowdebug(" VIDEO_STREAM_CONFIG_CAPS\n");
+    dshowdebug("  guid\t");
+    ff_printGUID(&caps->guid);
+    dshowdebug("\n");
+    dshowdebug("  VideoStandard\t%lu\n", caps->VideoStandard);
+    dshowdebug("  InputSize %ld\t%ld\n", caps->InputSize.cx, caps->InputSize.cy);
+    dshowdebug("  MinCroppingSize %ld\t%ld\n", caps->MinCroppingSize.cx, caps->MinCroppingSize.cy);
+    dshowdebug("  MaxCroppingSize %ld\t%ld\n", caps->MaxCroppingSize.cx, caps->MaxCroppingSize.cy);
+    dshowdebug("  CropGranularityX\t%d\n", caps->CropGranularityX);
+    dshowdebug("  CropGranularityY\t%d\n", caps->CropGranularityY);
+    dshowdebug("  CropAlignX\t%d\n", caps->CropAlignX);
+    dshowdebug("  CropAlignY\t%d\n", caps->CropAlignY);
+    dshowdebug("  MinOutputSize %ld\t%ld\n", caps->MinOutputSize.cx, caps->MinOutputSize.cy);
+    dshowdebug("  MaxOutputSize %ld\t%ld\n", caps->MaxOutputSize.cx, caps->MaxOutputSize.cy);
+    dshowdebug("  OutputGranularityX\t%d\n", caps->OutputGranularityX);
+    dshowdebug("  OutputGranularityY\t%d\n", caps->OutputGranularityY);
+    dshowdebug("  StretchTapsX\t%d\n", caps->StretchTapsX);
+    dshowdebug("  StretchTapsY\t%d\n", caps->StretchTapsY);
+    dshowdebug("  ShrinkTapsX\t%d\n", caps->ShrinkTapsX);
+    dshowdebug("  ShrinkTapsY\t%d\n", caps->ShrinkTapsY);
+    dshowdebug("  MinFrameInterval\t%"PRId64"\n", caps->MinFrameInterval);
+    dshowdebug("  MaxFrameInterval\t%"PRId64"\n", caps->MaxFrameInterval);
+    dshowdebug("  MinBitsPerSecond\t%ld\n", caps->MinBitsPerSecond);
+    dshowdebug("  MaxBitsPerSecond\t%ld\n", caps->MaxBitsPerSecond);
+#endif
+}
+
+void ff_print_AUDIO_STREAM_CONFIG_CAPS(const AUDIO_STREAM_CONFIG_CAPS *caps)
+{
+#if DSHOWDEBUG
+    dshowdebug(" AUDIO_STREAM_CONFIG_CAPS\n");
+    dshowdebug("  guid\t");
+    ff_printGUID(&caps->guid);
+    dshowdebug("\n");
+    dshowdebug("  MinimumChannels\t%lu\n", caps->MinimumChannels);
+    dshowdebug("  MaximumChannels\t%lu\n", caps->MaximumChannels);
+    dshowdebug("  ChannelsGranularity\t%lu\n", caps->ChannelsGranularity);
+    dshowdebug("  MinimumBitsPerSample\t%lu\n", caps->MinimumBitsPerSample);
+    dshowdebug("  MaximumBitsPerSample\t%lu\n", caps->MaximumBitsPerSample);
+    dshowdebug("  BitsPerSampleGranularity\t%lu\n", caps->BitsPerSampleGranularity);
+    dshowdebug("  MinimumSampleFrequency\t%lu\n", caps->MinimumSampleFrequency);
+    dshowdebug("  MaximumSampleFrequency\t%lu\n", caps->MaximumSampleFrequency);
+    dshowdebug("  SampleFrequencyGranularity\t%lu\n", caps->SampleFrequencyGranularity);
+#endif
+}
+
+void ff_print_AM_MEDIA_TYPE(const AM_MEDIA_TYPE *type)
+{
+#if DSHOWDEBUG
+    dshowdebug("    majortype\t");
+    ff_printGUID(&type->majortype);
+    dshowdebug("\n");
+    dshowdebug("    subtype\t");
+    ff_printGUID(&type->subtype);
+    dshowdebug("\n");
+    dshowdebug("    bFixedSizeSamples\t%d\n", type->bFixedSizeSamples);
+    dshowdebug("    bTemporalCompression\t%d\n", type->bTemporalCompression);
+    dshowdebug("    lSampleSize\t%lu\n", type->lSampleSize);
+    dshowdebug("    formattype\t");
+    ff_printGUID(&type->formattype);
+    dshowdebug("\n");
+    dshowdebug("    pUnk\t%p\n", type->pUnk);
+    dshowdebug("    cbFormat\t%lu\n", type->cbFormat);
+    dshowdebug("    pbFormat\t%p\n", type->pbFormat);
+
+    if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo)) {
+        VIDEOINFOHEADER *v = (void *) type->pbFormat;
+        dshowdebug("      rcSource: left %ld top %ld right %ld bottom %ld\n",
+                   v->rcSource.left, v->rcSource.top, v->rcSource.right, v->rcSource.bottom);
+        dshowdebug("      rcTarget: left %ld top %ld right %ld bottom %ld\n",
+                   v->rcTarget.left, v->rcTarget.top, v->rcTarget.right, v->rcTarget.bottom);
+        dshowdebug("      dwBitRate: %lu\n", v->dwBitRate);
+        dshowdebug("      dwBitErrorRate: %lu\n", v->dwBitErrorRate);
+        dshowdebug("      AvgTimePerFrame: %"PRId64"\n", v->AvgTimePerFrame);
+        dump_bih(NULL, &v->bmiHeader);
+    } else if (IsEqualGUID(&type->formattype, &FORMAT_VideoInfo2)) {
+        VIDEOINFOHEADER2 *v = (void *) type->pbFormat;
+        dshowdebug("      rcSource: left %ld top %ld right %ld bottom %ld\n",
+                   v->rcSource.left, v->rcSource.top, v->rcSource.right, v->rcSource.bottom);
+        dshowdebug("      rcTarget: left %ld top %ld right %ld bottom %ld\n",
+                   v->rcTarget.left, v->rcTarget.top, v->rcTarget.right, v->rcTarget.bottom);
+        dshowdebug("      dwBitRate: %lu\n", v->dwBitRate);
+        dshowdebug("      dwBitErrorRate: %lu\n", v->dwBitErrorRate);
+        dshowdebug("      AvgTimePerFrame: %"PRId64"\n", v->AvgTimePerFrame);
+        dshowdebug("      dwInterlaceFlags: %lu\n", v->dwInterlaceFlags);
+        dshowdebug("      dwCopyProtectFlags: %lu\n", v->dwCopyProtectFlags);
+        dshowdebug("      dwPictAspectRatioX: %lu\n", v->dwPictAspectRatioX);
+        dshowdebug("      dwPictAspectRatioY: %lu\n", v->dwPictAspectRatioY);
+//        dshowdebug("      dwReserved1: %lu\n", v->u.dwReserved1); /* mingw-w64 is buggy and doesn't name unnamed unions */
+        dshowdebug("      dwReserved2: %lu\n", v->dwReserved2);
+        dump_bih(NULL, &v->bmiHeader);
+    } else if (IsEqualGUID(&type->formattype, &FORMAT_WaveFormatEx)) {
+        WAVEFORMATEX *fx = (void *) type->pbFormat;
+        dshowdebug("      wFormatTag: %u\n", fx->wFormatTag);
+        dshowdebug("      nChannels: %u\n", fx->nChannels);
+        dshowdebug("      nSamplesPerSec: %lu\n", fx->nSamplesPerSec);
+        dshowdebug("      nAvgBytesPerSec: %lu\n", fx->nAvgBytesPerSec);
+        dshowdebug("      nBlockAlign: %u\n", fx->nBlockAlign);
+        dshowdebug("      wBitsPerSample: %u\n", fx->wBitsPerSample);
+        dshowdebug("      cbSize: %u\n", fx->cbSize);
+    }
+#endif
+}
diff --git a/libavdevice/dshow_enummediatypes.c b/libavdevice/dshow_enummediatypes.c
new file mode 100644
index 0000000..aaed58b
--- /dev/null
+++ b/libavdevice/dshow_enummediatypes.c
@@ -0,0 +1,103 @@
+/*
+ * DirectShow capture interface
+ * Copyright (c) 2010 Ramiro Polla
+ *
+ * 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 "dshow_capture.h"
+
+DECLARE_QUERYINTERFACE(libAVEnumMediaTypes,
+    { {&IID_IUnknown,0}, {&IID_IEnumPins,0} })
+DECLARE_ADDREF(libAVEnumMediaTypes)
+DECLARE_RELEASE(libAVEnumMediaTypes)
+
+long WINAPI
+libAVEnumMediaTypes_Next(libAVEnumMediaTypes *this, unsigned long n,
+                         AM_MEDIA_TYPE **types, unsigned long *fetched)
+{
+    int count = 0;
+    dshowdebug("libAVEnumMediaTypes_Next(%p)\n", this);
+    if (!types)
+        return E_POINTER;
+    if (!this->pos && n == 1) {
+        if (!IsEqualGUID(&this->type.majortype, &GUID_NULL)) {
+            AM_MEDIA_TYPE *type = av_malloc(sizeof(AM_MEDIA_TYPE));
+            ff_copy_dshow_media_type(type, &this->type);
+            *types = type;
+            count = 1;
+        }
+        this->pos = 1;
+    }
+    if (fetched)
+        *fetched = count;
+    if (!count)
+        return S_FALSE;
+    return S_OK;
+}
+long WINAPI
+libAVEnumMediaTypes_Skip(libAVEnumMediaTypes *this, unsigned long n)
+{
+    dshowdebug("libAVEnumMediaTypes_Skip(%p)\n", this);
+    if (n) /* Any skip will always fall outside of the only valid type. */
+        return S_FALSE;
+    return S_OK;
+}
+long WINAPI
+libAVEnumMediaTypes_Reset(libAVEnumMediaTypes *this)
+{
+    dshowdebug("libAVEnumMediaTypes_Reset(%p)\n", this);
+    this->pos = 0;
+    return S_OK;
+}
+long WINAPI
+libAVEnumMediaTypes_Clone(libAVEnumMediaTypes *this, libAVEnumMediaTypes **enums)
+{
+    libAVEnumMediaTypes *new;
+    dshowdebug("libAVEnumMediaTypes_Clone(%p)\n", this);
+    if (!enums)
+        return E_POINTER;
+    new = libAVEnumMediaTypes_Create(&this->type);
+    if (!new)
+        return E_OUTOFMEMORY;
+    new->pos = this->pos;
+    *enums = new;
+    return S_OK;
+}
+
+static int
+libAVEnumMediaTypes_Setup(libAVEnumMediaTypes *this, const AM_MEDIA_TYPE *type)
+{
+    IEnumPinsVtbl *vtbl = this->vtbl;
+    SETVTBL(vtbl, libAVEnumMediaTypes, QueryInterface);
+    SETVTBL(vtbl, libAVEnumMediaTypes, AddRef);
+    SETVTBL(vtbl, libAVEnumMediaTypes, Release);
+    SETVTBL(vtbl, libAVEnumMediaTypes, Next);
+    SETVTBL(vtbl, libAVEnumMediaTypes, Skip);
+    SETVTBL(vtbl, libAVEnumMediaTypes, Reset);
+    SETVTBL(vtbl, libAVEnumMediaTypes, Clone);
+
+    if (!type) {
+        this->type.majortype = GUID_NULL;
+    } else {
+        ff_copy_dshow_media_type(&this->type, type);
+    }
+
+    return 1;
+}
+DECLARE_CREATE(libAVEnumMediaTypes, libAVEnumMediaTypes_Setup(this, type), const AM_MEDIA_TYPE *type)
+DECLARE_DESTROY(libAVEnumMediaTypes, nothing)
diff --git a/libavdevice/dshow_enumpins.c b/libavdevice/dshow_enumpins.c
new file mode 100644
index 0000000..e5c11cb
--- /dev/null
+++ b/libavdevice/dshow_enumpins.c
@@ -0,0 +1,105 @@
+/*
+ * DirectShow capture interface
+ * Copyright (c) 2010 Ramiro Polla
+ *
+ * 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 "dshow_capture.h"
+
+DECLARE_QUERYINTERFACE(libAVEnumPins,
+    { {&IID_IUnknown,0}, {&IID_IEnumPins,0} })
+DECLARE_ADDREF(libAVEnumPins)
+DECLARE_RELEASE(libAVEnumPins)
+
+long WINAPI
+libAVEnumPins_Next(libAVEnumPins *this, unsigned long n, IPin **pins,
+                   unsigned long *fetched)
+{
+    int count = 0;
+    dshowdebug("libAVEnumPins_Next(%p)\n", this);
+    if (!pins)
+        return E_POINTER;
+    if (!this->pos && n == 1) {
+        libAVPin_AddRef(this->pin);
+        *pins = (IPin *) this->pin;
+        count = 1;
+        this->pos = 1;
+    }
+    if (fetched)
+        *fetched = count;
+    if (!count)
+        return S_FALSE;
+    return S_OK;
+}
+long WINAPI
+libAVEnumPins_Skip(libAVEnumPins *this, unsigned long n)
+{
+    dshowdebug("libAVEnumPins_Skip(%p)\n", this);
+    if (n) /* Any skip will always fall outside of the only valid pin. */
+        return S_FALSE;
+    return S_OK;
+}
+long WINAPI
+libAVEnumPins_Reset(libAVEnumPins *this)
+{
+    dshowdebug("libAVEnumPins_Reset(%p)\n", this);
+    this->pos = 0;
+    return S_OK;
+}
+long WINAPI
+libAVEnumPins_Clone(libAVEnumPins *this, libAVEnumPins **pins)
+{
+    libAVEnumPins *new;
+    dshowdebug("libAVEnumPins_Clone(%p)\n", this);
+    if (!pins)
+        return E_POINTER;
+    new = libAVEnumPins_Create(this->pin, this->filter);
+    if (!new)
+        return E_OUTOFMEMORY;
+    new->pos = this->pos;
+    *pins = new;
+    return S_OK;
+}
+
+static int
+libAVEnumPins_Setup(libAVEnumPins *this, libAVPin *pin, libAVFilter *filter)
+{
+    IEnumPinsVtbl *vtbl = this->vtbl;
+    SETVTBL(vtbl, libAVEnumPins, QueryInterface);
+    SETVTBL(vtbl, libAVEnumPins, AddRef);
+    SETVTBL(vtbl, libAVEnumPins, Release);
+    SETVTBL(vtbl, libAVEnumPins, Next);
+    SETVTBL(vtbl, libAVEnumPins, Skip);
+    SETVTBL(vtbl, libAVEnumPins, Reset);
+    SETVTBL(vtbl, libAVEnumPins, Clone);
+
+    this->pin = pin;
+    this->filter = filter;
+    libAVFilter_AddRef(this->filter);
+
+    return 1;
+}
+static int
+libAVEnumPins_Cleanup(libAVEnumPins *this)
+{
+    libAVFilter_Release(this->filter);
+    return 1;
+}
+DECLARE_CREATE(libAVEnumPins, libAVEnumPins_Setup(this, pin, filter),
+               libAVPin *pin, libAVFilter *filter)
+DECLARE_DESTROY(libAVEnumPins, libAVEnumPins_Cleanup)
diff --git a/libavdevice/dshow_filter.c b/libavdevice/dshow_filter.c
new file mode 100644
index 0000000..46d7eb0
--- /dev/null
+++ b/libavdevice/dshow_filter.c
@@ -0,0 +1,203 @@
+/*
+ * DirectShow capture interface
+ * Copyright (c) 2010 Ramiro Polla
+ *
+ * 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 NO_DSHOW_STRSAFE
+#include "dshow_capture.h"
+
+DECLARE_QUERYINTERFACE(libAVFilter,
+    { {&IID_IUnknown,0}, {&IID_IBaseFilter,0} })
+DECLARE_ADDREF(libAVFilter)
+DECLARE_RELEASE(libAVFilter)
+
+long WINAPI
+libAVFilter_GetClassID(libAVFilter *this, CLSID *id)
+{
+    dshowdebug("libAVFilter_GetClassID(%p)\n", this);
+    /* I'm not creating a ClassID just for this. */
+    return E_FAIL;
+}
+long WINAPI
+libAVFilter_Stop(libAVFilter *this)
+{
+    dshowdebug("libAVFilter_Stop(%p)\n", this);
+    this->state = State_Stopped;
+    return S_OK;
+}
+long WINAPI
+libAVFilter_Pause(libAVFilter *this)
+{
+    dshowdebug("libAVFilter_Pause(%p)\n", this);
+    this->state = State_Paused;
+    return S_OK;
+}
+long WINAPI
+libAVFilter_Run(libAVFilter *this, REFERENCE_TIME start)
+{
+    dshowdebug("libAVFilter_Run(%p) %"PRId64"\n", this, start);
+    this->state = State_Running;
+    this->start_time = start;
+    return S_OK;
+}
+long WINAPI
+libAVFilter_GetState(libAVFilter *this, DWORD ms, FILTER_STATE *state)
+{
+    dshowdebug("libAVFilter_GetState(%p)\n", this);
+    if (!state)
+        return E_POINTER;
+    *state = this->state;
+    return S_OK;
+}
+long WINAPI
+libAVFilter_SetSyncSource(libAVFilter *this, IReferenceClock *clock)
+{
+    dshowdebug("libAVFilter_SetSyncSource(%p)\n", this);
+
+    if (this->clock != clock) {
+        if (this->clock)
+            IReferenceClock_Release(this->clock);
+        this->clock = clock;
+        if (clock)
+            IReferenceClock_AddRef(clock);
+    }
+
+    return S_OK;
+}
+long WINAPI
+libAVFilter_GetSyncSource(libAVFilter *this, IReferenceClock **clock)
+{
+    dshowdebug("libAVFilter_GetSyncSource(%p)\n", this);
+
+    if (!clock)
+        return E_POINTER;
+    if (this->clock)
+        IReferenceClock_AddRef(this->clock);
+    *clock = this->clock;
+
+    return S_OK;
+}
+long WINAPI
+libAVFilter_EnumPins(libAVFilter *this, IEnumPins **enumpin)
+{
+    libAVEnumPins *new;
+    dshowdebug("libAVFilter_EnumPins(%p)\n", this);
+
+    if (!enumpin)
+        return E_POINTER;
+    new = libAVEnumPins_Create(this->pin, this);
+    if (!new)
+        return E_OUTOFMEMORY;
+
+    *enumpin = (IEnumPins *) new;
+    return S_OK;
+}
+long WINAPI
+libAVFilter_FindPin(libAVFilter *this, const wchar_t *id, IPin **pin)
+{
+    libAVPin *found = NULL;
+    dshowdebug("libAVFilter_FindPin(%p)\n", this);
+
+    if (!id || !pin)
+        return E_POINTER;
+    if (!wcscmp(id, L"In")) {
+        found = this->pin;
+        libAVPin_AddRef(found);
+    }
+    *pin = (IPin *) found;
+    if (!found)
+        return VFW_E_NOT_FOUND;
+
+    return S_OK;
+}
+long WINAPI
+libAVFilter_QueryFilterInfo(libAVFilter *this, FILTER_INFO *info)
+{
+    dshowdebug("libAVFilter_QueryFilterInfo(%p)\n", this);
+
+    if (!info)
+        return E_POINTER;
+    if (this->info.pGraph)
+        IFilterGraph_AddRef(this->info.pGraph);
+    *info = this->info;
+
+    return S_OK;
+}
+long WINAPI
+libAVFilter_JoinFilterGraph(libAVFilter *this, IFilterGraph *graph,
+                            const wchar_t *name)
+{
+    dshowdebug("libAVFilter_JoinFilterGraph(%p)\n", this);
+
+    this->info.pGraph = graph;
+    if (name)
+        wcscpy(this->info.achName, name);
+
+    return S_OK;
+}
+long WINAPI
+libAVFilter_QueryVendorInfo(libAVFilter *this, wchar_t **info)
+{
+    dshowdebug("libAVFilter_QueryVendorInfo(%p)\n", this);
+
+    if (!info)
+        return E_POINTER;
+    *info = wcsdup(L"libAV");
+
+    return S_OK;
+}
+
+static int
+libAVFilter_Setup(libAVFilter *this, void *priv_data, void *callback,
+                  enum dshowDeviceType type)
+{
+    IBaseFilterVtbl *vtbl = this->vtbl;
+    SETVTBL(vtbl, libAVFilter, QueryInterface);
+    SETVTBL(vtbl, libAVFilter, AddRef);
+    SETVTBL(vtbl, libAVFilter, Release);
+    SETVTBL(vtbl, libAVFilter, GetClassID);
+    SETVTBL(vtbl, libAVFilter, Stop);
+    SETVTBL(vtbl, libAVFilter, Pause);
+    SETVTBL(vtbl, libAVFilter, Run);
+    SETVTBL(vtbl, libAVFilter, GetState);
+    SETVTBL(vtbl, libAVFilter, SetSyncSource);
+    SETVTBL(vtbl, libAVFilter, GetSyncSource);
+    SETVTBL(vtbl, libAVFilter, EnumPins);
+    SETVTBL(vtbl, libAVFilter, FindPin);
+    SETVTBL(vtbl, libAVFilter, QueryFilterInfo);
+    SETVTBL(vtbl, libAVFilter, JoinFilterGraph);
+    SETVTBL(vtbl, libAVFilter, QueryVendorInfo);
+
+    this->pin = libAVPin_Create(this);
+
+    this->priv_data = priv_data;
+    this->callback  = callback;
+    this->type      = type;
+
+    return 1;
+}
+static int
+libAVFilter_Cleanup(libAVFilter *this)
+{
+    libAVPin_Release(this->pin);
+    return 1;
+}
+DECLARE_CREATE(libAVFilter, libAVFilter_Setup(this, priv_data, callback, type),
+               void *priv_data, void *callback, enum dshowDeviceType type)
+DECLARE_DESTROY(libAVFilter, libAVFilter_Cleanup)
diff --git a/libavdevice/dshow_pin.c b/libavdevice/dshow_pin.c
new file mode 100644
index 0000000..676877e
--- /dev/null
+++ b/libavdevice/dshow_pin.c
@@ -0,0 +1,363 @@
+/*
+ * DirectShow capture interface
+ * Copyright (c) 2010 Ramiro Polla
+ *
+ * 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 NO_DSHOW_STRSAFE
+#include "dshow_capture.h"
+
+#include <stddef.h>
+#define imemoffset offsetof(libAVPin, imemvtbl)
+
+DECLARE_QUERYINTERFACE(libAVPin,
+    { {&IID_IUnknown,0}, {&IID_IPin,0}, {&IID_IMemInputPin,imemoffset} })
+DECLARE_ADDREF(libAVPin)
+DECLARE_RELEASE(libAVPin)
+
+long WINAPI
+libAVPin_Connect(libAVPin *this, IPin *pin, const AM_MEDIA_TYPE *type)
+{
+    dshowdebug("libAVPin_Connect(%p, %p, %p)\n", this, pin, type);
+    /* Input pins receive connections. */
+    return S_FALSE;
+}
+long WINAPI
+libAVPin_ReceiveConnection(libAVPin *this, IPin *pin,
+                           const AM_MEDIA_TYPE *type)
+{
+    enum dshowDeviceType devtype = this->filter->type;
+    dshowdebug("libAVPin_ReceiveConnection(%p)\n", this);
+
+    if (!pin)
+        return E_POINTER;
+    if (this->connectedto)
+        return VFW_E_ALREADY_CONNECTED;
+
+    ff_print_AM_MEDIA_TYPE(type);
+    if (devtype == VideoDevice) {
+        if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Video))
+            return VFW_E_TYPE_NOT_ACCEPTED;
+    } else {
+        if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Audio))
+            return VFW_E_TYPE_NOT_ACCEPTED;
+    }
+
+    IPin_AddRef(pin);
+    this->connectedto = pin;
+
+    ff_copy_dshow_media_type(&this->type, type);
+
+    return S_OK;
+}
+long WINAPI
+libAVPin_Disconnect(libAVPin *this)
+{
+    dshowdebug("libAVPin_Disconnect(%p)\n", this);
+
+    if (this->filter->state != State_Stopped)
+        return VFW_E_NOT_STOPPED;
+    if (!this->connectedto)
+        return S_FALSE;
+    IPin_Release(this->connectedto);
+    this->connectedto = NULL;
+
+    return S_OK;
+}
+long WINAPI
+libAVPin_ConnectedTo(libAVPin *this, IPin **pin)
+{
+    dshowdebug("libAVPin_ConnectedTo(%p)\n", this);
+
+    if (!pin)
+        return E_POINTER;
+    if (!this->connectedto)
+        return VFW_E_NOT_CONNECTED;
+    IPin_AddRef(this->connectedto);
+    *pin = this->connectedto;
+
+    return S_OK;
+}
+long WINAPI
+libAVPin_ConnectionMediaType(libAVPin *this, AM_MEDIA_TYPE *type)
+{
+    dshowdebug("libAVPin_ConnectionMediaType(%p)\n", this);
+
+    if (!type)
+        return E_POINTER;
+    if (!this->connectedto)
+        return VFW_E_NOT_CONNECTED;
+
+    return ff_copy_dshow_media_type(type, &this->type);
+}
+long WINAPI
+libAVPin_QueryPinInfo(libAVPin *this, PIN_INFO *info)
+{
+    dshowdebug("libAVPin_QueryPinInfo(%p)\n", this);
+
+    if (!info)
+        return E_POINTER;
+
+    if (this->filter)
+        libAVFilter_AddRef(this->filter);
+
+    info->pFilter = (IBaseFilter *) this->filter;
+    info->dir     = PINDIR_INPUT;
+    wcscpy(info->achName, L"Capture");
+
+    return S_OK;
+}
+long WINAPI
+libAVPin_QueryDirection(libAVPin *this, PIN_DIRECTION *dir)
+{
+    dshowdebug("libAVPin_QueryDirection(%p)\n", this);
+    if (!dir)
+        return E_POINTER;
+    *dir = PINDIR_INPUT;
+    return S_OK;
+}
+long WINAPI
+libAVPin_QueryId(libAVPin *this, wchar_t **id)
+{
+    dshowdebug("libAVPin_QueryId(%p)\n", this);
+
+    if (!id)
+        return E_POINTER;
+
+    *id = wcsdup(L"libAV Pin");
+
+    return S_OK;
+}
+long WINAPI
+libAVPin_QueryAccept(libAVPin *this, const AM_MEDIA_TYPE *type)
+{
+    dshowdebug("libAVPin_QueryAccept(%p)\n", this);
+    return S_FALSE;
+}
+long WINAPI
+libAVPin_EnumMediaTypes(libAVPin *this, IEnumMediaTypes **enumtypes)
+{
+    const AM_MEDIA_TYPE *type = NULL;
+    libAVEnumMediaTypes *new;
+    dshowdebug("libAVPin_EnumMediaTypes(%p)\n", this);
+
+    if (!enumtypes)
+        return E_POINTER;
+    new = libAVEnumMediaTypes_Create(type);
+    if (!new)
+        return E_OUTOFMEMORY;
+
+    *enumtypes = (IEnumMediaTypes *) new;
+    return S_OK;
+}
+long WINAPI
+libAVPin_QueryInternalConnections(libAVPin *this, IPin **pin,
+                                  unsigned long *npin)
+{
+    dshowdebug("libAVPin_QueryInternalConnections(%p)\n", this);
+    return E_NOTIMPL;
+}
+long WINAPI
+libAVPin_EndOfStream(libAVPin *this)
+{
+    dshowdebug("libAVPin_EndOfStream(%p)\n", this);
+    /* I don't care. */
+    return S_OK;
+}
+long WINAPI
+libAVPin_BeginFlush(libAVPin *this)
+{
+    dshowdebug("libAVPin_BeginFlush(%p)\n", this);
+    /* I don't care. */
+    return S_OK;
+}
+long WINAPI
+libAVPin_EndFlush(libAVPin *this)
+{
+    dshowdebug("libAVPin_EndFlush(%p)\n", this);
+    /* I don't care. */
+    return S_OK;
+}
+long WINAPI
+libAVPin_NewSegment(libAVPin *this, REFERENCE_TIME start, REFERENCE_TIME stop,
+                    double rate)
+{
+    dshowdebug("libAVPin_NewSegment(%p)\n", this);
+    /* I don't care. */
+    return S_OK;
+}
+
+static int
+libAVPin_Setup(libAVPin *this, libAVFilter *filter)
+{
+    IPinVtbl *vtbl = this->vtbl;
+    IMemInputPinVtbl *imemvtbl;
+
+    if (!filter)
+        return 0;
+
+    imemvtbl = av_malloc(sizeof(IMemInputPinVtbl));
+    if (!imemvtbl)
+        return 0;
+
+    SETVTBL(imemvtbl, libAVMemInputPin, QueryInterface);
+    SETVTBL(imemvtbl, libAVMemInputPin, AddRef);
+    SETVTBL(imemvtbl, libAVMemInputPin, Release);
+    SETVTBL(imemvtbl, libAVMemInputPin, GetAllocator);
+    SETVTBL(imemvtbl, libAVMemInputPin, NotifyAllocator);
+    SETVTBL(imemvtbl, libAVMemInputPin, GetAllocatorRequirements);
+    SETVTBL(imemvtbl, libAVMemInputPin, Receive);
+    SETVTBL(imemvtbl, libAVMemInputPin, ReceiveMultiple);
+    SETVTBL(imemvtbl, libAVMemInputPin, ReceiveCanBlock);
+
+    this->imemvtbl = imemvtbl;
+
+    SETVTBL(vtbl, libAVPin, QueryInterface);
+    SETVTBL(vtbl, libAVPin, AddRef);
+    SETVTBL(vtbl, libAVPin, Release);
+    SETVTBL(vtbl, libAVPin, Connect);
+    SETVTBL(vtbl, libAVPin, ReceiveConnection);
+    SETVTBL(vtbl, libAVPin, Disconnect);
+    SETVTBL(vtbl, libAVPin, ConnectedTo);
+    SETVTBL(vtbl, libAVPin, ConnectionMediaType);
+    SETVTBL(vtbl, libAVPin, QueryPinInfo);
+    SETVTBL(vtbl, libAVPin, QueryDirection);
+    SETVTBL(vtbl, libAVPin, QueryId);
+    SETVTBL(vtbl, libAVPin, QueryAccept);
+    SETVTBL(vtbl, libAVPin, EnumMediaTypes);
+    SETVTBL(vtbl, libAVPin, QueryInternalConnections);
+    SETVTBL(vtbl, libAVPin, EndOfStream);
+    SETVTBL(vtbl, libAVPin, BeginFlush);
+    SETVTBL(vtbl, libAVPin, EndFlush);
+    SETVTBL(vtbl, libAVPin, NewSegment);
+
+    this->filter = filter;
+
+    return 1;
+}
+DECLARE_CREATE(libAVPin, libAVPin_Setup(this, filter), libAVFilter *filter)
+DECLARE_DESTROY(libAVPin, nothing)
+
+/*****************************************************************************
+ * libAVMemInputPin
+ ****************************************************************************/
+long WINAPI
+libAVMemInputPin_QueryInterface(libAVMemInputPin *this, const GUID *riid,
+                                void **ppvObject)
+{
+    libAVPin *pin = (libAVPin *) ((uint8_t *) this - imemoffset);
+    dshowdebug("libAVMemInputPin_QueryInterface(%p)\n", this);
+    return libAVPin_QueryInterface(pin, riid, ppvObject);
+}
+unsigned long WINAPI
+libAVMemInputPin_AddRef(libAVMemInputPin *this)
+{
+    libAVPin *pin = (libAVPin *) ((uint8_t *) this - imemoffset);
+    dshowdebug("libAVMemInputPin_AddRef(%p)\n", this);
+    return libAVPin_AddRef(pin);
+}
+unsigned long WINAPI
+libAVMemInputPin_Release(libAVMemInputPin *this)
+{
+    libAVPin *pin = (libAVPin *) ((uint8_t *) this - imemoffset);
+    dshowdebug("libAVMemInputPin_Release(%p)\n", this);
+    return libAVPin_Release(pin);
+}
+long WINAPI
+libAVMemInputPin_GetAllocator(libAVMemInputPin *this, IMemAllocator **alloc)
+{
+    dshowdebug("libAVMemInputPin_GetAllocator(%p)\n", this);
+    return VFW_E_NO_ALLOCATOR;
+}
+long WINAPI
+libAVMemInputPin_NotifyAllocator(libAVMemInputPin *this, IMemAllocator *alloc,
+                                 BOOL rdwr)
+{
+    dshowdebug("libAVMemInputPin_NotifyAllocator(%p)\n", this);
+    return S_OK;
+}
+long WINAPI
+libAVMemInputPin_GetAllocatorRequirements(libAVMemInputPin *this,
+                                          ALLOCATOR_PROPERTIES *props)
+{
+    dshowdebug("libAVMemInputPin_GetAllocatorRequirements(%p)\n", this);
+    return E_NOTIMPL;
+}
+long WINAPI
+libAVMemInputPin_Receive(libAVMemInputPin *this, IMediaSample *sample)
+{
+    libAVPin *pin = (libAVPin *) ((uint8_t *) this - imemoffset);
+    enum dshowDeviceType devtype = pin->filter->type;
+    void *priv_data;
+    uint8_t *buf;
+    int buf_size;
+    int index;
+    int64_t curtime;
+
+    dshowdebug("libAVMemInputPin_Receive(%p)\n", this);
+
+    if (!sample)
+        return E_POINTER;
+
+    if (devtype == VideoDevice) {
+        /* PTS from video devices is unreliable. */
+        IReferenceClock *clock = pin->filter->clock;
+        IReferenceClock_GetTime(clock, &curtime);
+    } else {
+        int64_t dummy;
+        IMediaSample_GetTime(sample, &curtime, &dummy);
+        curtime += pin->filter->start_time;
+    }
+
+    buf_size = IMediaSample_GetActualDataLength(sample);
+    IMediaSample_GetPointer(sample, &buf);
+    priv_data = pin->filter->priv_data;
+    index = pin->filter->stream_index;
+
+    pin->filter->callback(priv_data, index, buf, buf_size, curtime);
+
+    return S_OK;
+}
+long WINAPI
+libAVMemInputPin_ReceiveMultiple(libAVMemInputPin *this,
+                                 IMediaSample **samples, long n, long *nproc)
+{
+    int i;
+    dshowdebug("libAVMemInputPin_ReceiveMultiple(%p)\n", this);
+
+    for (i = 0; i < n; i++)
+        libAVMemInputPin_Receive(this, samples[i]);
+
+    *nproc = n;
+    return S_OK;
+}
+long WINAPI
+libAVMemInputPin_ReceiveCanBlock(libAVMemInputPin *this)
+{
+    dshowdebug("libAVMemInputPin_ReceiveCanBlock(%p)\n", this);
+    /* I swear I will not block. */
+    return S_FALSE;
+}
+
+void
+libAVMemInputPin_Destroy(libAVMemInputPin *this)
+{
+    libAVPin *pin = (libAVPin *) ((uint8_t *) this - imemoffset);
+    dshowdebug("libAVMemInputPin_Destroy(%p)\n", this);
+    return libAVPin_Destroy(pin);
+}
diff --git a/libavdevice/dv1394.c b/libavdevice/dv1394.c
index 4a63768..2916e49 100644
--- a/libavdevice/dv1394.c
+++ b/libavdevice/dv1394.c
@@ -2,20 +2,20 @@
  * Linux DV1394 interface
  * Copyright (c) 2003 Max Krasnyansky <maxk@qualcomm.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,7 +29,7 @@
 
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
-#include "libavformat/avformat.h"
+#include "avdevice.h"
 #include "libavformat/dv.h"
 #include "dv1394.h"
 
@@ -185,7 +185,7 @@
 
     size = avpriv_dv_produce_packet(dv->dv_demux, pkt,
                              dv->ring + (dv->index * DV1394_PAL_FRAME_SIZE),
-                             DV1394_PAL_FRAME_SIZE);
+                             DV1394_PAL_FRAME_SIZE, -1);
     dv->index = (dv->index + 1) % DV1394_RING_FRAMES;
     dv->done++; dv->avail--;
 
diff --git a/libavdevice/dv1394.h b/libavdevice/dv1394.h
index fc4df24..b76d633 100644
--- a/libavdevice/dv1394.h
+++ b/libavdevice/dv1394.h
@@ -8,20 +8,20 @@
  *   Copyright (C)1999,2000 Sebastien Rougeaux <sebastien.rougeaux@anu.edu.au>
  *                          Peter Schlaile <udbz@rz.uni-karlsruhe.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -186,7 +186,7 @@
    where copy_DV_frame() reads or writes on the dv1394 file descriptor
    (read/write mode) or copies data to/from the mmap ringbuffer and
    then calls ioctl(DV1394_SUBMIT_FRAMES) to notify dv1394 that new
-   frames are availble (mmap mode).
+   frames are available (mmap mode).
 
    reset_dv1394() is called in the event of a buffer
    underflow/overflow or a halt in the DV stream (e.g. due to a 1394
diff --git a/libavdevice/fbdev.c b/libavdevice/fbdev.c
index 7680b29..30595bd 100644
--- a/libavdevice/fbdev.c
+++ b/libavdevice/fbdev.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2009 Giliard B. de Freitas <giliarde@gmail.com>
  * Copyright (C) 2002 Gunnar Monell <gmo@linux.nu>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -42,7 +42,7 @@
 #include "libavutil/time.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/pixdesc.h"
-#include "libavformat/avformat.h"
+#include "avdevice.h"
 #include "libavformat/internal.h"
 
 struct rgb_pixfmt_map_entry {
@@ -51,7 +51,7 @@
     enum AVPixelFormat pixfmt;
 };
 
-static struct rgb_pixfmt_map_entry rgb_pixfmt_map[] = {
+static const struct rgb_pixfmt_map_entry rgb_pixfmt_map[] = {
     // bpp, red_offset,  green_offset, blue_offset, alpha_offset, pixfmt
     {  32,       0,           8,          16,           24,   AV_PIX_FMT_RGBA  },
     {  32,      16,           8,           0,           24,   AV_PIX_FMT_BGRA  },
@@ -66,7 +66,7 @@
     int i;
 
     for (i = 0; i < FF_ARRAY_ELEMS(rgb_pixfmt_map); i++) {
-        struct rgb_pixfmt_map_entry *entry = &rgb_pixfmt_map[i];
+        const struct rgb_pixfmt_map_entry *entry = &rgb_pixfmt_map[i];
         if (entry->bits_per_pixel == varinfo->bits_per_pixel &&
             entry->red_offset     == varinfo->red.offset     &&
             entry->green_offset   == varinfo->green.offset   &&
@@ -164,7 +164,7 @@
     st->codec->width      = fbdev->width;
     st->codec->height     = fbdev->height;
     st->codec->pix_fmt    = pix_fmt;
-    st->codec->time_base  = (AVRational){fbdev->framerate_q.den, fbdev->framerate_q.num};
+    st->codec->time_base  = av_inv_q(fbdev->framerate_q);
     st->codec->bit_rate   =
         fbdev->width * fbdev->height * fbdev->bytes_per_pixel * av_q2d(fbdev->framerate_q) * 8;
 
@@ -193,20 +193,22 @@
         fbdev->time_frame = av_gettime();
 
     /* wait based on the frame rate */
-    curtime = av_gettime();
-    delay = fbdev->time_frame - curtime;
-    av_dlog(avctx,
-            "time_frame:%"PRId64" curtime:%"PRId64" delay:%"PRId64"\n",
-            fbdev->time_frame, curtime, delay);
-    if (delay > 0) {
+    while (1) {
+        curtime = av_gettime();
+        delay = fbdev->time_frame - curtime;
+        av_dlog(avctx,
+                "time_frame:%"PRId64" curtime:%"PRId64" delay:%"PRId64"\n",
+                fbdev->time_frame, curtime, delay);
+        if (delay <= 0) {
+            fbdev->time_frame += INT64_C(1000000) / av_q2d(fbdev->framerate_q);
+            break;
+        }
         if (avctx->flags & AVFMT_FLAG_NONBLOCK)
             return AVERROR(EAGAIN);
         ts.tv_sec  =  delay / 1000000;
         ts.tv_nsec = (delay % 1000000) * 1000;
         while (nanosleep(&ts, &ts) < 0 && errno == EINTR);
     }
-    /* compute the time of the next frame */
-    fbdev->time_frame += INT64_C(1000000) / av_q2d(fbdev->framerate_q);
 
     if ((ret = av_new_packet(pkt, fbdev->frame_size)) < 0)
         return ret;
@@ -223,7 +225,6 @@
                         fbdev->varinfo.yoffset * fbdev->fixinfo.line_length;
     pout = pkt->data;
 
-    // TODO it'd be nice if the lines were aligned
     for (i = 0; i < fbdev->height; i++) {
         memcpy(pout, pin, fbdev->frame_linesize);
         pin  += fbdev->fixinfo.line_length;
diff --git a/libavdevice/iec61883.c b/libavdevice/iec61883.c
new file mode 100644
index 0000000..8c9a39f
--- /dev/null
+++ b/libavdevice/iec61883.c
@@ -0,0 +1,466 @@
+/*
+ * Copyright (c) 2012 Georg Lippitsch <georg.lippitsch@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
+ * libiec61883 interface
+ */
+
+#include <sys/poll.h>
+#include <libraw1394/raw1394.h>
+#include <libavc1394/avc1394.h>
+#include <libavc1394/rom1394.h>
+#include <libiec61883/iec61883.h>
+#include "libavformat/dv.h"
+#include "libavformat/mpegts.h"
+#include "libavutil/opt.h"
+#include "avdevice.h"
+
+#define THREADS HAVE_PTHREADS
+
+#if THREADS
+#include <pthread.h>
+#endif
+
+#define MOTDCT_SPEC_ID      0x00005068
+#define IEC61883_AUTO       0
+#define IEC61883_DV         1
+#define IEC61883_HDV        2
+
+/**
+ * For DV, one packet corresponds exactly to one frame.
+ * For HDV, these are MPEG2 transport stream packets.
+ * The queue is implemented as linked list.
+ */
+typedef struct DVPacket {
+    uint8_t *buf;                       ///< actual buffer data
+    int len;                            ///< size of buffer allocated
+    struct DVPacket *next;              ///< next DVPacket
+} DVPacket;
+
+struct iec61883_data {
+    AVClass *class;
+    raw1394handle_t raw1394;            ///< handle for libraw1394
+    iec61883_dv_fb_t iec61883_dv;       ///< handle for libiec61883 when used with DV
+    iec61883_mpeg2_t iec61883_mpeg2;    ///< handle for libiec61883 when used with HDV
+
+    DVDemuxContext *dv_demux;           ///< generic DV muxing/demuxing context
+    MpegTSContext *mpeg_demux;          ///< generic HDV muxing/demuxing context
+
+    DVPacket *queue_first;              ///< first element of packet queue
+    DVPacket *queue_last;               ///< last element of packet queue
+
+    int packets;                        ///< Number of packets queued
+    int max_packets;                    ///< Max. number of packets in queue
+
+    int bandwidth;                      ///< returned by libiec61883
+    int channel;                        ///< returned by libiec61883
+    int input_port;                     ///< returned by libiec61883
+    int type;                           ///< Stream type, to distinguish DV/HDV
+    int node;                           ///< returned by libiec61883
+    int output_port;                    ///< returned by libiec61883
+    int thread_loop;                    ///< Condition for thread while-loop
+    int receiving;                      ///< True as soon data from device available
+    int receive_error;                  ///< Set in receive task in case of error
+    int eof;                            ///< True as soon as no more data available
+
+    struct pollfd raw1394_poll;         ///< to poll for new data from libraw1394
+
+    /** Parse function for DV/HDV differs, so this is set before packets arrive */
+    int (*parse_queue)(struct iec61883_data *dv, AVPacket *pkt);
+
+#if THREADS
+    pthread_t receive_task_thread;
+    pthread_mutex_t mutex;
+    pthread_cond_t cond;
+#endif
+};
+
+static int iec61883_callback(unsigned char *data, int length,
+                             int complete, void *callback_data)
+{
+    struct iec61883_data *dv = callback_data;
+    DVPacket *packet;
+    int ret;
+
+#ifdef THREADS
+    pthread_mutex_lock(&dv->mutex);
+#endif
+
+    if (dv->packets >= dv->max_packets) {
+        av_log(NULL, AV_LOG_ERROR, "DV packet queue overrun, dropping.\n");
+        ret = 0;
+        goto exit;
+    }
+
+    packet = av_mallocz(sizeof(*packet));
+    if (!packet) {
+        ret = -1;
+        goto exit;
+    }
+
+    packet->buf = av_malloc(length);
+    if (!packet->buf) {
+        ret = -1;
+        goto exit;
+    }
+    packet->len = length;
+
+    memcpy(packet->buf, data, length);
+
+    if (dv->queue_first) {
+        dv->queue_last->next = packet;
+        dv->queue_last = packet;
+    } else {
+        dv->queue_first = packet;
+        dv->queue_last = packet;
+    }
+    dv->packets++;
+
+    ret = 0;
+
+exit:
+#ifdef THREADS
+    pthread_cond_signal(&dv->cond);
+    pthread_mutex_unlock(&dv->mutex);
+#endif
+    return ret;
+}
+
+static void *iec61883_receive_task(void *opaque)
+{
+    struct iec61883_data *dv = (struct iec61883_data *)opaque;
+    int result;
+
+#ifdef THREADS
+    while (dv->thread_loop)
+#endif
+    {
+        while ((result = poll(&dv->raw1394_poll, 1, 200)) < 0) {
+            if (!(errno == EAGAIN || errno == EINTR)) {
+                av_log(NULL, AV_LOG_ERROR, "Raw1394 poll error occurred.\n");
+                dv->receive_error = AVERROR(EIO);
+                return NULL;
+            }
+        }
+        if (result > 0 && ((dv->raw1394_poll.revents & POLLIN)
+                           || (dv->raw1394_poll.revents & POLLPRI))) {
+            dv->receiving = 1;
+            raw1394_loop_iterate(dv->raw1394);
+        } else if (dv->receiving) {
+            av_log(NULL, AV_LOG_ERROR, "No more input data available\n");
+#ifdef THREADS
+            pthread_mutex_lock(&dv->mutex);
+            dv->eof = 1;
+            pthread_cond_signal(&dv->cond);
+            pthread_mutex_unlock(&dv->mutex);
+#else
+            dv->eof = 1;
+#endif
+            return NULL;
+        }
+    }
+
+    return NULL;
+}
+
+static int iec61883_parse_queue_dv(struct iec61883_data *dv, AVPacket *pkt)
+{
+    DVPacket *packet;
+    int size;
+
+    size = avpriv_dv_get_packet(dv->dv_demux, pkt);
+    if (size > 0)
+        return size;
+
+    packet = dv->queue_first;
+    if (!packet)
+        return -1;
+
+    size = avpriv_dv_produce_packet(dv->dv_demux, pkt,
+                                    packet->buf, packet->len, -1);
+    pkt->destruct = av_destruct_packet;
+    dv->queue_first = packet->next;
+    av_free(packet);
+    dv->packets--;
+
+    if (size > 0)
+        return size;
+
+    return -1;
+}
+
+static int iec61883_parse_queue_hdv(struct iec61883_data *dv, AVPacket *pkt)
+{
+    DVPacket *packet;
+    int size;
+
+    while (dv->queue_first) {
+        packet = dv->queue_first;
+        size = ff_mpegts_parse_packet(dv->mpeg_demux, pkt, packet->buf,
+                                      packet->len);
+        dv->queue_first = packet->next;
+        av_free(packet->buf);
+        av_free(packet);
+        dv->packets--;
+
+        if (size > 0)
+            return size;
+    }
+
+    return -1;
+}
+
+static int iec61883_read_header(AVFormatContext *context)
+{
+    struct iec61883_data *dv = context->priv_data;
+    struct raw1394_portinfo pinf[16];
+    rom1394_directory rom_dir;
+    char *endptr;
+    int inport;
+    int nb_ports;
+    int port = -1;
+    int response;
+    int i, j = 0;
+
+    dv->input_port = -1;
+    dv->output_port = -1;
+    dv->channel = -1;
+
+    dv->raw1394 = raw1394_new_handle();
+
+    if (!dv->raw1394) {
+        av_log(context, AV_LOG_ERROR, "Failed to open IEEE1394 interface.\n");
+        return AVERROR(EIO);
+    }
+
+    if ((nb_ports = raw1394_get_port_info(dv->raw1394, pinf, 16)) < 0) {
+        av_log(context, AV_LOG_ERROR, "Failed to get number of IEEE1394 ports.\n");
+        goto fail;
+    }
+
+    inport = strtol(context->filename, &endptr, 10);
+    if (endptr != context->filename && *endptr == '\0') {
+        av_log(context, AV_LOG_INFO, "Selecting IEEE1394 port: %d\n", inport);
+        j = inport;
+        nb_ports = inport + 1;
+    } else if (strcmp(context->filename, "auto")) {
+        av_log(context, AV_LOG_ERROR, "Invalid input \"%s\", you should specify "
+               "\"auto\" for auto-detection, or the port number.\n", context->filename);
+        goto fail;
+    }
+
+    /* Select first AV/C tape recorder player node */
+
+    for (; j < nb_ports && port==-1; ++j) {
+        if (raw1394_set_port(dv->raw1394, j)) {
+            av_log(context, AV_LOG_ERROR, "Failed setting IEEE1394 port.\n");
+            goto fail;
+        }
+        for (i=0; i<raw1394_get_nodecount(dv->raw1394); ++i) {
+            if (rom1394_get_directory(dv->raw1394, i, &rom_dir) < 0)
+                continue;
+            if (((rom1394_get_node_type(&rom_dir) == ROM1394_NODE_TYPE_AVC) &&
+                 avc1394_check_subunit_type(dv->raw1394, i, AVC1394_SUBUNIT_TYPE_VCR)) ||
+                (rom_dir.unit_spec_id == MOTDCT_SPEC_ID)) {
+                rom1394_free_directory(&rom_dir);
+                dv->node = i;
+                port = j;
+                break;
+            }
+            rom1394_free_directory(&rom_dir);
+        }
+    }
+
+    if (port == -1) {
+        av_log(context, AV_LOG_ERROR, "No AV/C devices found.\n");
+        goto fail;
+    }
+
+    /* Find out if device is DV or HDV */
+
+    if (dv->type == IEC61883_AUTO) {
+        response = avc1394_transaction(dv->raw1394, dv->node,
+                                       AVC1394_CTYPE_STATUS |
+                                       AVC1394_SUBUNIT_TYPE_TAPE_RECORDER |
+                                       AVC1394_SUBUNIT_ID_0 |
+                                       AVC1394_VCR_COMMAND_OUTPUT_SIGNAL_MODE |
+                                       0xFF, 2);
+        response = AVC1394_GET_OPERAND0(response);
+        dv->type = (response == 0x10 || response == 0x90 || response == 0x1A || response == 0x9A) ?
+            IEC61883_HDV : IEC61883_DV;
+    }
+
+    /* Connect to device, and do initialization */
+
+    dv->channel = iec61883_cmp_connect(dv->raw1394, dv->node, &dv->output_port,
+                                       raw1394_get_local_id(dv->raw1394),
+                                       &dv->input_port, &dv->bandwidth);
+
+    if (dv->channel < 0)
+        dv->channel = 63;
+
+    if (!dv->max_packets)
+        dv->max_packets = 100;
+
+    if (dv->type == IEC61883_HDV) {
+
+        /* Init HDV receive */
+
+        avformat_new_stream(context, NULL);
+
+        dv->mpeg_demux = ff_mpegts_parse_open(context);
+        if (!dv->mpeg_demux)
+            goto fail;
+
+        dv->parse_queue = iec61883_parse_queue_hdv;
+
+        dv->iec61883_mpeg2 = iec61883_mpeg2_recv_init(dv->raw1394,
+                                                      (iec61883_mpeg2_recv_t)iec61883_callback,
+                                                      dv);
+
+        dv->max_packets *= 766;
+    } else {
+
+        /* Init DV receive */
+
+        dv->dv_demux = avpriv_dv_init_demux(context);
+        if (!dv->dv_demux)
+            goto fail;
+
+        dv->parse_queue = iec61883_parse_queue_dv;
+
+        dv->iec61883_dv = iec61883_dv_fb_init(dv->raw1394, iec61883_callback, dv);
+    }
+
+    dv->raw1394_poll.fd = raw1394_get_fd(dv->raw1394);
+    dv->raw1394_poll.events = POLLIN | POLLERR | POLLHUP | POLLPRI;
+
+    /* Actually start receiving */
+
+    if (dv->type == IEC61883_HDV)
+        iec61883_mpeg2_recv_start(dv->iec61883_mpeg2, dv->channel);
+    else
+        iec61883_dv_fb_start(dv->iec61883_dv, dv->channel);
+
+#if THREADS
+    dv->thread_loop = 1;
+    pthread_mutex_init(&dv->mutex, NULL);
+    pthread_cond_init(&dv->cond, NULL);
+    pthread_create(&dv->receive_task_thread, NULL, iec61883_receive_task, dv);
+#endif
+
+    return 0;
+
+fail:
+    raw1394_destroy_handle(dv->raw1394);
+    return AVERROR(EIO);
+}
+
+static int iec61883_read_packet(AVFormatContext *context, AVPacket *pkt)
+{
+    struct iec61883_data *dv = context->priv_data;
+    int size;
+
+    /**
+     * Try to parse frames from queue
+     */
+
+#ifdef THREADS
+    pthread_mutex_lock(&dv->mutex);
+    while ((size = dv->parse_queue(dv, pkt)) == -1)
+        if (!dv->eof)
+            pthread_cond_wait(&dv->cond, &dv->mutex);
+        else
+            break;
+    pthread_mutex_unlock(&dv->mutex);
+#else
+    int result;
+    while ((size = dv->parse_queue(dv, pkt)) == -1) {
+        iec61883_receive_task((void *)dv);
+        if (dv->receive_error)
+            return dv->receive_error;
+    }
+#endif
+
+    return size;
+}
+
+static int iec61883_close(AVFormatContext *context)
+{
+    struct iec61883_data *dv = context->priv_data;
+
+#if THREADS
+    dv->thread_loop = 0;
+    pthread_join(dv->receive_task_thread, NULL);
+    pthread_cond_destroy(&dv->cond);
+    pthread_mutex_destroy(&dv->mutex);
+#endif
+
+    if (dv->type == IEC61883_HDV) {
+        iec61883_mpeg2_recv_stop(dv->iec61883_mpeg2);
+        iec61883_mpeg2_close(dv->iec61883_mpeg2);
+        ff_mpegts_parse_close(dv->mpeg_demux);
+    } else {
+        iec61883_dv_fb_stop(dv->iec61883_dv);
+        iec61883_dv_fb_close(dv->iec61883_dv);
+    }
+    while (dv->queue_first) {
+        DVPacket *packet = dv->queue_first;
+        dv->queue_first = packet->next;
+        av_free(packet->buf);
+        av_free(packet);
+    }
+
+    iec61883_cmp_disconnect(dv->raw1394, dv->node, dv->output_port,
+                            raw1394_get_local_id(dv->raw1394),
+                            dv->input_port, dv->channel, dv->bandwidth);
+
+    raw1394_destroy_handle(dv->raw1394);
+
+    return 0;
+}
+
+static const AVOption options[] = {
+    { "dvtype", "override autodetection of DV/HDV", offsetof(struct iec61883_data, type), AV_OPT_TYPE_INT, {.i64 = IEC61883_AUTO}, IEC61883_AUTO, IEC61883_HDV, AV_OPT_FLAG_DECODING_PARAM, "dvtype" },
+    { "auto",   "auto detect DV/HDV", 0, AV_OPT_TYPE_CONST, {.i64 = IEC61883_AUTO}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "dvtype" },
+    { "dv",     "force device being treated as DV device", 0, AV_OPT_TYPE_CONST, {.i64 = IEC61883_DV},   0, 0, AV_OPT_FLAG_DECODING_PARAM, "dvtype" },
+    { "hdv" ,   "force device being treated as HDV device", 0, AV_OPT_TYPE_CONST, {.i64 = IEC61883_HDV},  0, 0, AV_OPT_FLAG_DECODING_PARAM, "dvtype" },
+    { "dvbuffer", "set queue buffer size (in packets)", offsetof(struct iec61883_data, max_packets), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+    { NULL },
+};
+
+static const AVClass iec61883_class = {
+    .class_name = "iec61883 indev",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_iec61883_demuxer = {
+    .name           = "iec61883",
+    .long_name      = NULL_IF_CONFIG_SMALL("libiec61883 (new DV1394) A/V input device"),
+    .priv_data_size = sizeof(struct iec61883_data),
+    .read_header    = iec61883_read_header,
+    .read_packet    = iec61883_read_packet,
+    .read_close     = iec61883_close,
+    .flags          = AVFMT_NOFILE,
+    .priv_class     = &iec61883_class,
+};
diff --git a/libavdevice/jack_audio.c b/libavdevice/jack_audio.c
index 280f24d..bd6a770 100644
--- a/libavdevice/jack_audio.c
+++ b/libavdevice/jack_audio.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2009 Samalyse
  * Author: Olivier Guilyardi <olivier samalyse com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -32,6 +32,7 @@
 #include "libavformat/avformat.h"
 #include "libavformat/internal.h"
 #include "timefilter.h"
+#include "avdevice.h"
 
 /**
  * Size of the internal FIFO buffers as a number of audio packets
@@ -151,7 +152,6 @@
     JackData *self = context->priv_data;
     jack_status_t status;
     int i, test;
-    double o, period;
 
     /* Register as a JACK client, using the context filename as client name. */
     self->client = jack_client_open(context->filename, JackNullOption, &status);
@@ -187,9 +187,7 @@
     jack_set_xrun_callback(self->client, xrun_callback, self);
 
     /* Create time filter */
-    period            = (double) self->buffer_size / self->sample_rate;
-    o                 = 2 * M_PI * 1.5 * period; /// bandwidth: 1.5Hz
-    self->timefilter  = ff_timefilter_new (1.0 / self->sample_rate, sqrt(2 * o), o * o);
+    self->timefilter  = ff_timefilter_new (1.0 / self->sample_rate, self->buffer_size, 1.5);
 
     /* Create FIFO buffers */
     self->filled_pkts = av_fifo_alloc(FIFO_PACKETS_NUM * sizeof(AVPacket));
diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c
new file mode 100644
index 0000000..944794f
--- /dev/null
+++ b/libavdevice/lavfi.c
@@ -0,0 +1,376 @@
+/*
+ * 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
+ * libavfilter virtual input device
+ */
+
+/* #define DEBUG */
+
+#include "float.h"              /* DBL_MIN, DBL_MAX */
+
+#include "libavutil/log.h"
+#include "libavutil/mem.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/audioconvert.h"
+#include "libavfilter/avfilter.h"
+#include "libavfilter/avfiltergraph.h"
+#include "libavfilter/buffersink.h"
+#include "libavformat/internal.h"
+#include "avdevice.h"
+
+typedef struct {
+    AVClass *class;          ///< class for private options
+    char          *graph_str;
+    char          *dump_graph;
+    AVFilterGraph *graph;
+    AVFilterContext **sinks;
+    int *sink_stream_map;
+    int *sink_eof;
+    int *stream_sink_map;
+} LavfiContext;
+
+static int *create_all_formats(int n)
+{
+    int i, j, *fmts, count = 0;
+
+    for (i = 0; i < n; i++) {
+        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i);
+        if (!(desc->flags & PIX_FMT_HWACCEL))
+            count++;
+    }
+
+    if (!(fmts = av_malloc((count+1) * sizeof(int))))
+        return NULL;
+    for (j = 0, i = 0; i < n; i++) {
+        const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(i);
+        if (!(desc->flags & PIX_FMT_HWACCEL))
+            fmts[j++] = i;
+    }
+    fmts[j] = -1;
+    return fmts;
+}
+
+av_cold static int lavfi_read_close(AVFormatContext *avctx)
+{
+    LavfiContext *lavfi = avctx->priv_data;
+
+    av_freep(&lavfi->sink_stream_map);
+    av_freep(&lavfi->sink_eof);
+    av_freep(&lavfi->stream_sink_map);
+    av_freep(&lavfi->sinks);
+    avfilter_graph_free(&lavfi->graph);
+
+    return 0;
+}
+
+av_cold static int lavfi_read_header(AVFormatContext *avctx)
+{
+    LavfiContext *lavfi = avctx->priv_data;
+    AVFilterInOut *input_links = NULL, *output_links = NULL, *inout;
+    AVFilter *buffersink, *abuffersink;
+    int *pix_fmts = create_all_formats(AV_PIX_FMT_NB);
+    enum AVMediaType type;
+    int ret = 0, i, n;
+
+#define FAIL(ERR) { ret = ERR; goto end; }
+
+    if (!pix_fmts)
+        FAIL(AVERROR(ENOMEM));
+
+    avfilter_register_all();
+
+    buffersink = avfilter_get_by_name("ffbuffersink");
+    abuffersink = avfilter_get_by_name("ffabuffersink");
+
+    if (!lavfi->graph_str)
+        lavfi->graph_str = av_strdup(avctx->filename);
+
+    /* parse the graph, create a stream for each open output */
+    if (!(lavfi->graph = avfilter_graph_alloc()))
+        FAIL(AVERROR(ENOMEM));
+
+    if ((ret = avfilter_graph_parse(lavfi->graph, lavfi->graph_str,
+                                    &input_links, &output_links, avctx)) < 0)
+        FAIL(ret);
+
+    if (input_links) {
+        av_log(avctx, AV_LOG_ERROR,
+               "Open inputs in the filtergraph are not acceptable\n");
+        FAIL(AVERROR(EINVAL));
+    }
+
+    /* count the outputs */
+    for (n = 0, inout = output_links; inout; n++, inout = inout->next);
+
+    if (!(lavfi->sink_stream_map = av_malloc(sizeof(int) * n)))
+        FAIL(AVERROR(ENOMEM));
+    if (!(lavfi->sink_eof = av_mallocz(sizeof(int) * n)))
+        FAIL(AVERROR(ENOMEM));
+    if (!(lavfi->stream_sink_map = av_malloc(sizeof(int) * n)))
+        FAIL(AVERROR(ENOMEM));
+
+    for (i = 0; i < n; i++)
+        lavfi->stream_sink_map[i] = -1;
+
+    /* parse the output link names - they need to be of the form out0, out1, ...
+     * create a mapping between them and the streams */
+    for (i = 0, inout = output_links; inout; i++, inout = inout->next) {
+        int stream_idx;
+        if (!strcmp(inout->name, "out"))
+            stream_idx = 0;
+        else if (sscanf(inout->name, "out%d\n", &stream_idx) != 1) {
+            av_log(avctx,  AV_LOG_ERROR,
+                   "Invalid outpad name '%s'\n", inout->name);
+            FAIL(AVERROR(EINVAL));
+        }
+
+        if ((unsigned)stream_idx >= n) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Invalid index was specified in output '%s', "
+                   "must be a non-negative value < %d\n",
+                   inout->name, n);
+            FAIL(AVERROR(EINVAL));
+        }
+
+        /* is an audio or video output? */
+        type = inout->filter_ctx->output_pads[inout->pad_idx].type;
+        if (type != AVMEDIA_TYPE_VIDEO && type != AVMEDIA_TYPE_AUDIO) {
+            av_log(avctx,  AV_LOG_ERROR,
+                   "Output '%s' is not a video or audio output, not yet supported\n", inout->name);
+            FAIL(AVERROR(EINVAL));
+        }
+
+        if (lavfi->stream_sink_map[stream_idx] != -1) {
+            av_log(avctx,  AV_LOG_ERROR,
+                   "An output with stream index %d was already specified\n",
+                   stream_idx);
+            FAIL(AVERROR(EINVAL));
+        }
+        lavfi->sink_stream_map[i] = stream_idx;
+        lavfi->stream_sink_map[stream_idx] = i;
+    }
+
+    /* for each open output create a corresponding stream */
+    for (i = 0, inout = output_links; inout; i++, inout = inout->next) {
+        AVStream *st;
+        if (!(st = avformat_new_stream(avctx, NULL)))
+            FAIL(AVERROR(ENOMEM));
+        st->id = i;
+    }
+
+    /* create a sink for each output and connect them to the graph */
+    lavfi->sinks = av_malloc(sizeof(AVFilterContext *) * avctx->nb_streams);
+    if (!lavfi->sinks)
+        FAIL(AVERROR(ENOMEM));
+
+    for (i = 0, inout = output_links; inout; i++, inout = inout->next) {
+        AVFilterContext *sink;
+
+        type = inout->filter_ctx->output_pads[inout->pad_idx].type;
+
+        if (type == AVMEDIA_TYPE_VIDEO && ! buffersink ||
+            type == AVMEDIA_TYPE_AUDIO && ! abuffersink) {
+                av_log(avctx, AV_LOG_ERROR, "Missing required buffersink filter, aborting.\n");
+                FAIL(AVERROR_FILTER_NOT_FOUND);
+        }
+
+        if (type == AVMEDIA_TYPE_VIDEO) {
+            AVBufferSinkParams *buffersink_params = av_buffersink_params_alloc();
+
+            buffersink_params->pixel_fmts = pix_fmts;
+            ret = avfilter_graph_create_filter(&sink, buffersink,
+                                               inout->name, NULL,
+                                               buffersink_params, lavfi->graph);
+            av_freep(&buffersink_params);
+
+            if (ret < 0)
+                goto end;
+        } else if (type == AVMEDIA_TYPE_AUDIO) {
+            enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_U8,
+                                                  AV_SAMPLE_FMT_S16,
+                                                  AV_SAMPLE_FMT_S32,
+                                                  AV_SAMPLE_FMT_FLT,
+                                                  AV_SAMPLE_FMT_DBL, -1 };
+            AVABufferSinkParams *abuffersink_params = av_abuffersink_params_alloc();
+            abuffersink_params->sample_fmts = sample_fmts;
+
+            ret = avfilter_graph_create_filter(&sink, abuffersink,
+                                               inout->name, NULL,
+                                               abuffersink_params, lavfi->graph);
+            av_free(abuffersink_params);
+            if (ret < 0)
+                goto end;
+        }
+
+        lavfi->sinks[i] = sink;
+        if ((ret = avfilter_link(inout->filter_ctx, inout->pad_idx, sink, 0)) < 0)
+            FAIL(ret);
+    }
+
+    /* configure the graph */
+    if ((ret = avfilter_graph_config(lavfi->graph, avctx)) < 0)
+        FAIL(ret);
+
+    if (lavfi->dump_graph) {
+        char *dump = avfilter_graph_dump(lavfi->graph, lavfi->dump_graph);
+        fputs(dump, stderr);
+        fflush(stderr);
+        av_free(dump);
+    }
+
+    /* fill each stream with the information in the corresponding sink */
+    for (i = 0; i < avctx->nb_streams; i++) {
+        AVFilterLink *link = lavfi->sinks[lavfi->stream_sink_map[i]]->inputs[0];
+        AVStream *st = avctx->streams[i];
+        st->codec->codec_type = link->type;
+        avpriv_set_pts_info(st, 64, link->time_base.num, link->time_base.den);
+        if (link->type == AVMEDIA_TYPE_VIDEO) {
+            st->codec->codec_id   = AV_CODEC_ID_RAWVIDEO;
+            st->codec->pix_fmt    = link->format;
+            st->codec->time_base  = link->time_base;
+            st->codec->width      = link->w;
+            st->codec->height     = link->h;
+            st       ->sample_aspect_ratio =
+            st->codec->sample_aspect_ratio = link->sample_aspect_ratio;
+        } else if (link->type == AVMEDIA_TYPE_AUDIO) {
+            st->codec->codec_id    = av_get_pcm_codec(link->format, -1);
+            st->codec->channels    = av_get_channel_layout_nb_channels(link->channel_layout);
+            st->codec->sample_fmt  = link->format;
+            st->codec->sample_rate = link->sample_rate;
+            st->codec->time_base   = link->time_base;
+            st->codec->channel_layout = link->channel_layout;
+            if (st->codec->codec_id == AV_CODEC_ID_NONE)
+                av_log(avctx, AV_LOG_ERROR,
+                       "Could not find PCM codec for sample format %s.\n",
+                       av_get_sample_fmt_name(link->format));
+        }
+    }
+
+end:
+    av_free(pix_fmts);
+    avfilter_inout_free(&input_links);
+    avfilter_inout_free(&output_links);
+    if (ret < 0)
+        lavfi_read_close(avctx);
+    return ret;
+}
+
+static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt)
+{
+    LavfiContext *lavfi = avctx->priv_data;
+    double min_pts = DBL_MAX;
+    int stream_idx, min_pts_sink_idx = 0;
+    AVFilterBufferRef *ref;
+    AVPicture pict;
+    int ret, i;
+    int size = 0;
+
+    /* iterate through all the graph sinks. Select the sink with the
+     * minimum PTS */
+    for (i = 0; i < avctx->nb_streams; i++) {
+        AVRational tb = lavfi->sinks[i]->inputs[0]->time_base;
+        double d;
+        int ret;
+
+        if (lavfi->sink_eof[i])
+            continue;
+
+        ret = av_buffersink_get_buffer_ref(lavfi->sinks[i],
+                                       &ref, AV_BUFFERSINK_FLAG_PEEK);
+        if (ret == AVERROR_EOF) {
+            av_dlog(avctx, "EOF sink_idx:%d\n", i);
+            lavfi->sink_eof[i] = 1;
+            continue;
+        } else if (ret < 0)
+            return ret;
+        d = av_rescale_q(ref->pts, tb, AV_TIME_BASE_Q);
+        av_dlog(avctx, "sink_idx:%d time:%f\n", i, d);
+
+        if (d < min_pts) {
+            min_pts = d;
+            min_pts_sink_idx = i;
+        }
+    }
+    if (min_pts == DBL_MAX)
+        return AVERROR_EOF;
+
+    av_dlog(avctx, "min_pts_sink_idx:%i\n", min_pts_sink_idx);
+
+    av_buffersink_get_buffer_ref(lavfi->sinks[min_pts_sink_idx], &ref, 0);
+    stream_idx = lavfi->sink_stream_map[min_pts_sink_idx];
+
+    if (ref->video) {
+        size = avpicture_get_size(ref->format, ref->video->w, ref->video->h);
+        if ((ret = av_new_packet(pkt, size)) < 0)
+            return ret;
+
+        memcpy(pict.data,     ref->data,     4*sizeof(ref->data[0]));
+        memcpy(pict.linesize, ref->linesize, 4*sizeof(ref->linesize[0]));
+
+        avpicture_layout(&pict, ref->format, ref->video->w,
+                         ref->video->h, pkt->data, size);
+    } else if (ref->audio) {
+        size = ref->audio->nb_samples *
+            av_get_bytes_per_sample(ref->format) *
+            av_get_channel_layout_nb_channels(ref->audio->channel_layout);
+        if ((ret = av_new_packet(pkt, size)) < 0)
+            return ret;
+        memcpy(pkt->data, ref->data[0], size);
+    }
+
+    pkt->stream_index = stream_idx;
+    pkt->pts = ref->pts;
+    pkt->pos = ref->pos;
+    pkt->size = size;
+    avfilter_unref_buffer(ref);
+    return size;
+}
+
+#define OFFSET(x) offsetof(LavfiContext, x)
+
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+
+static const AVOption options[] = {
+    { "graph",     "set libavfilter graph", OFFSET(graph_str),  AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+    { "dumpgraph", "dump graph to stderr",  OFFSET(dump_graph), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
+    { NULL },
+};
+
+static const AVClass lavfi_class = {
+    .class_name = "lavfi indev",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_lavfi_demuxer = {
+    .name           = "lavfi",
+    .long_name      = NULL_IF_CONFIG_SMALL("Libavfilter virtual input device"),
+    .priv_data_size = sizeof(LavfiContext),
+    .read_header    = lavfi_read_header,
+    .read_packet    = lavfi_read_packet,
+    .read_close     = lavfi_read_close,
+    .flags          = AVFMT_NOFILE,
+    .priv_class     = &lavfi_class,
+};
diff --git a/libavdevice/libcdio.c b/libavdevice/libcdio.c
index a82ad67..fa311fd 100644
--- a/libavdevice/libcdio.c
+++ b/libavdevice/libcdio.c
@@ -37,7 +37,7 @@
 #undef free
 
 typedef struct CDIOContext {
-    AVClass             *class;
+    const AVClass       *class;
     cdrom_drive_t       *drive;
     cdrom_paranoia_t *paranoia;
     int32_t last_sector;
diff --git a/libavdevice/libdc1394.c b/libavdevice/libdc1394.c
index d953e12..bae1497 100644
--- a/libavdevice/libdc1394.c
+++ b/libavdevice/libdc1394.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2004 Roman Shaposhnik
  * Copyright (c) 2008 Alessandro Sappia
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavdevice/openal-dec.c b/libavdevice/openal-dec.c
new file mode 100644
index 0000000..6069edc
--- /dev/null
+++ b/libavdevice/openal-dec.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2011 Jonathan Baldwin
+ *
+ * This file is part of FFmpeg.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * @file
+ * OpenAL 1.1 capture device for libavdevice
+ **/
+
+#include <AL/al.h>
+#include <AL/alc.h>
+
+#include "libavutil/opt.h"
+#include "libavformat/internal.h"
+#include "avdevice.h"
+
+typedef struct {
+    AVClass *class;
+    /** OpenAL capture device context. **/
+    ALCdevice *device;
+    /** The number of channels in the captured audio. **/
+    int channels;
+    /** The sample rate (in Hz) of the captured audio. **/
+    int sample_rate;
+    /** The sample size (in bits) of the captured audio. **/
+    int sample_size;
+    /** The OpenAL sample format of the captured audio. **/
+    ALCenum sample_format;
+    /** The number of bytes between two consecutive samples of the same channel/component. **/
+    ALCint sample_step;
+    /** If true, print a list of capture devices on this system and exit. **/
+    int list_devices;
+} al_data;
+
+typedef struct {
+    ALCenum al_fmt;
+    enum AVCodecID codec_id;
+    int channels;
+} al_format_info;
+
+#define LOWEST_AL_FORMAT FFMIN(FFMIN(AL_FORMAT_MONO8,AL_FORMAT_MONO16),FFMIN(AL_FORMAT_STEREO8,AL_FORMAT_STEREO16))
+
+/**
+ * Get information about an AL_FORMAT value.
+ * @param al_fmt the AL_FORMAT value to find information about.
+ * @return A pointer to a structure containing information about the AL_FORMAT value.
+ */
+static inline al_format_info* get_al_format_info(ALCenum al_fmt)
+{
+    static al_format_info info_table[] = {
+        [AL_FORMAT_MONO8-LOWEST_AL_FORMAT]    = {AL_FORMAT_MONO8, AV_CODEC_ID_PCM_U8, 1},
+        [AL_FORMAT_MONO16-LOWEST_AL_FORMAT]   = {AL_FORMAT_MONO16, AV_NE (AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE), 1},
+        [AL_FORMAT_STEREO8-LOWEST_AL_FORMAT]  = {AL_FORMAT_STEREO8, AV_CODEC_ID_PCM_U8, 2},
+        [AL_FORMAT_STEREO16-LOWEST_AL_FORMAT] = {AL_FORMAT_STEREO16, AV_NE (AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE), 2},
+    };
+
+    return &info_table[al_fmt-LOWEST_AL_FORMAT];
+}
+
+/**
+ * Get the OpenAL error code, translated into an av/errno error code.
+ * @param device The ALC device to check for errors.
+ * @param error_msg_ret A pointer to a char* in which to return the error message, or NULL if desired.
+ * @return The error code, or 0 if there is no error.
+ */
+static inline int al_get_error(ALCdevice *device, const char** error_msg_ret)
+{
+    ALCenum error = alcGetError(device);
+    if (error_msg_ret)
+        *error_msg_ret = (const char*) alcGetString(device, error);
+    switch (error) {
+    case ALC_NO_ERROR:
+        return 0;
+    case ALC_INVALID_DEVICE:
+        return AVERROR(ENODEV);
+        break;
+    case ALC_INVALID_CONTEXT:
+    case ALC_INVALID_ENUM:
+    case ALC_INVALID_VALUE:
+        return AVERROR(EINVAL);
+        break;
+    case ALC_OUT_OF_MEMORY:
+        return AVERROR(ENOMEM);
+        break;
+    default:
+        return AVERROR(EIO);
+    }
+}
+
+/**
+ * Print out a list of OpenAL capture devices on this system.
+ */
+static inline void print_al_capture_devices(void *log_ctx)
+{
+    const char *devices;
+
+    if (!(devices = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER)))
+        return;
+
+    av_log(log_ctx, AV_LOG_INFO, "List of OpenAL capture devices on this system:\n");
+
+    for (; *devices != '\0'; devices += strlen(devices) + 1)
+        av_log(log_ctx, AV_LOG_INFO, "  %s\n", devices);
+}
+
+static int read_header(AVFormatContext *ctx)
+{
+    al_data *ad = ctx->priv_data;
+    static const ALCenum sample_formats[2][2] = {
+        { AL_FORMAT_MONO8,  AL_FORMAT_STEREO8  },
+        { AL_FORMAT_MONO16, AL_FORMAT_STEREO16 }
+    };
+    int error = 0;
+    const char *error_msg;
+    AVStream *st = NULL;
+    AVCodecContext *codec = NULL;
+
+    if (ad->list_devices) {
+        print_al_capture_devices(ctx);
+        return AVERROR_EXIT;
+    }
+
+    ad->sample_format = sample_formats[ad->sample_size/8-1][ad->channels-1];
+
+    /* Open device for capture */
+    ad->device =
+        alcCaptureOpenDevice(ctx->filename[0] ? ctx->filename : NULL,
+                             ad->sample_rate,
+                             ad->sample_format,
+                             ad->sample_rate); /* Maximum 1 second of sample data to be read at once */
+
+    if (error = al_get_error(ad->device, &error_msg)) goto fail;
+
+    /* Create stream */
+    if (!(st = avformat_new_stream(ctx, NULL))) {
+        error = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    /* We work in microseconds */
+    avpriv_set_pts_info(st, 64, 1, 1000000);
+
+    /* Set codec parameters */
+    codec = st->codec;
+    codec->codec_type = AVMEDIA_TYPE_AUDIO;
+    codec->sample_rate = ad->sample_rate;
+    codec->channels = get_al_format_info(ad->sample_format)->channels;
+    codec->codec_id = get_al_format_info(ad->sample_format)->codec_id;
+
+    /* This is needed to read the audio data */
+    ad->sample_step = (av_get_bits_per_sample(get_al_format_info(ad->sample_format)->codec_id) *
+                       get_al_format_info(ad->sample_format)->channels) / 8;
+
+    /* Finally, start the capture process */
+    alcCaptureStart(ad->device);
+
+    return 0;
+
+fail:
+    /* Handle failure */
+    if (ad->device)
+        alcCaptureCloseDevice(ad->device);
+    if (error_msg)
+        av_log(ctx, AV_LOG_ERROR, "Cannot open device: %s\n", error_msg);
+    return error;
+}
+
+static int read_packet(AVFormatContext* ctx, AVPacket *pkt)
+{
+    al_data *ad = ctx->priv_data;
+    int error=0;
+    const char *error_msg;
+    ALCint nb_samples;
+
+    /* Get number of samples available */
+    alcGetIntegerv(ad->device, ALC_CAPTURE_SAMPLES, (ALCsizei) sizeof(ALCint), &nb_samples);
+    if (error = al_get_error(ad->device, &error_msg)) goto fail;
+
+    /* Create a packet of appropriate size */
+    av_new_packet(pkt, nb_samples*ad->sample_step);
+    pkt->pts = av_gettime();
+
+    /* Fill the packet with the available samples */
+    alcCaptureSamples(ad->device, pkt->data, nb_samples);
+    if (error = al_get_error(ad->device, &error_msg)) goto fail;
+
+    return pkt->size;
+fail:
+    /* Handle failure */
+    if (pkt->data)
+        av_destruct_packet(pkt);
+    if (error_msg)
+        av_log(ctx, AV_LOG_ERROR, "Error: %s\n", error_msg);
+    return error;
+}
+
+static int read_close(AVFormatContext* ctx)
+{
+    al_data *ad = ctx->priv_data;
+
+    if (ad->device) {
+        alcCaptureStop(ad->device);
+        alcCaptureCloseDevice(ad->device);
+    }
+    return 0;
+}
+
+#define OFFSET(x) offsetof(al_data, x)
+
+static const AVOption options[] = {
+    {"channels", "set number of channels",     OFFSET(channels),     AV_OPT_TYPE_INT, {.i64=2},     1, 2,      AV_OPT_FLAG_DECODING_PARAM },
+    {"sample_rate", "set sample rate",         OFFSET(sample_rate),  AV_OPT_TYPE_INT, {.i64=44100}, 1, 192000, AV_OPT_FLAG_DECODING_PARAM },
+    {"sample_size", "set sample size",         OFFSET(sample_size),  AV_OPT_TYPE_INT, {.i64=16},    8, 16,     AV_OPT_FLAG_DECODING_PARAM },
+    {"list_devices", "list available devices", OFFSET(list_devices), AV_OPT_TYPE_INT, {.i64=0},     0, 1,      AV_OPT_FLAG_DECODING_PARAM, "list_devices"  },
+    {"true",  "", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "list_devices" },
+    {"false", "", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "list_devices" },
+    {NULL},
+};
+
+static const AVClass class = {
+    .class_name = "openal",
+    .item_name = av_default_item_name,
+    .option = options,
+    .version = LIBAVUTIL_VERSION_INT
+};
+
+AVInputFormat ff_openal_demuxer = {
+    .name = "openal",
+    .long_name = NULL_IF_CONFIG_SMALL("OpenAL audio capture device"),
+    .priv_data_size = sizeof(al_data),
+    .read_probe = NULL,
+    .read_header = read_header,
+    .read_packet = read_packet,
+    .read_close = read_close,
+    .flags = AVFMT_NOFILE,
+    .priv_class = &class
+};
diff --git a/libavdevice/oss_audio.c b/libavdevice/oss_audio.c
index e3b9d67..5c8b3b9 100644
--- a/libavdevice/oss_audio.c
+++ b/libavdevice/oss_audio.c
@@ -2,20 +2,20 @@
  * Linux audio play and grab interface
  * Copyright (c) 2000, 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -38,7 +38,7 @@
 #include "libavutil/opt.h"
 #include "libavutil/time.h"
 #include "libavcodec/avcodec.h"
-#include "libavformat/avformat.h"
+#include "avdevice.h"
 #include "libavformat/internal.h"
 
 #define AUDIO_BLOCK_SIZE 4096
diff --git a/libavdevice/pulse.c b/libavdevice/pulse.c
index a8e710d..86fdc22 100644
--- a/libavdevice/pulse.c
+++ b/libavdevice/pulse.c
@@ -162,7 +162,7 @@
 
 static const AVOption options[] = {
     { "server",        "pulse server name",                              OFFSET(server),        AV_OPT_TYPE_STRING, {.str = NULL},     0, 0, D },
-    { "name",          "application name",                               OFFSET(name),          AV_OPT_TYPE_STRING, {.str = "libav"},  0, 0, D },
+    { "name",          "application name",                               OFFSET(name),          AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT},  0, 0, D },
     { "stream_name",   "stream description",                             OFFSET(stream_name),   AV_OPT_TYPE_STRING, {.str = "record"}, 0, 0, D },
     { "sample_rate",   "sample rate in Hz",                              OFFSET(sample_rate),   AV_OPT_TYPE_INT,    {.i64 = 48000},    1, INT_MAX, D },
     { "channels",      "number of audio channels",                       OFFSET(channels),      AV_OPT_TYPE_INT,    {.i64 = 2},        1, INT_MAX, D },
diff --git a/libavdevice/sdl.c b/libavdevice/sdl.c
new file mode 100644
index 0000000..1867139
--- /dev/null
+++ b/libavdevice/sdl.c
@@ -0,0 +1,233 @@
+/*
+ * 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
+ * libSDL output device
+ */
+
+#include <SDL.h>
+#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
+#include "avdevice.h"
+
+typedef struct {
+    AVClass *class;
+    SDL_Surface *surface;
+    SDL_Overlay *overlay;
+    char *window_title;
+    char *icon_title;
+    int window_width,  window_height;  /**< size of the window */
+    int overlay_width, overlay_height; /**< size of the video in the window */
+    int overlay_x, overlay_y;
+    int overlay_fmt;
+    int sdl_was_already_inited;
+} SDLContext;
+
+static const struct sdl_overlay_pix_fmt_entry {
+    enum AVPixelFormat pix_fmt; int overlay_fmt;
+} sdl_overlay_pix_fmt_map[] = {
+    { AV_PIX_FMT_YUV420P, SDL_IYUV_OVERLAY },
+    { AV_PIX_FMT_YUYV422, SDL_YUY2_OVERLAY },
+    { AV_PIX_FMT_UYVY422, SDL_UYVY_OVERLAY },
+    { AV_PIX_FMT_NONE,    0                },
+};
+
+static int sdl_write_trailer(AVFormatContext *s)
+{
+    SDLContext *sdl = s->priv_data;
+
+    av_freep(&sdl->window_title);
+    av_freep(&sdl->icon_title);
+
+    if (sdl->overlay) {
+        SDL_FreeYUVOverlay(sdl->overlay);
+        sdl->overlay = NULL;
+    }
+    if (!sdl->sdl_was_already_inited)
+        SDL_Quit();
+
+    return 0;
+}
+
+static int sdl_write_header(AVFormatContext *s)
+{
+    SDLContext *sdl = s->priv_data;
+    AVStream *st = s->streams[0];
+    AVCodecContext *encctx = st->codec;
+    AVRational sar, dar; /* sample and display aspect ratios */
+    int i, ret;
+
+    if (!sdl->window_title)
+        sdl->window_title = av_strdup(s->filename);
+    if (!sdl->icon_title)
+        sdl->icon_title = av_strdup(sdl->window_title);
+
+    if (SDL_WasInit(SDL_INIT_VIDEO)) {
+        av_log(s, AV_LOG_ERROR,
+               "SDL video subsystem was already inited, aborting\n");
+        sdl->sdl_was_already_inited = 1;
+        ret = AVERROR(EINVAL);
+        goto fail;
+    }
+
+    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
+        av_log(s, AV_LOG_ERROR, "Unable to initialize SDL: %s\n", SDL_GetError());
+        ret = AVERROR(EINVAL);
+        goto fail;
+    }
+
+    if (   s->nb_streams > 1
+        || encctx->codec_type != AVMEDIA_TYPE_VIDEO
+        || encctx->codec_id   != AV_CODEC_ID_RAWVIDEO) {
+        av_log(s, AV_LOG_ERROR, "Only supports one rawvideo stream\n");
+        ret = AVERROR(EINVAL);
+        goto fail;
+    }
+
+    for (i = 0; sdl_overlay_pix_fmt_map[i].pix_fmt != AV_PIX_FMT_NONE; i++) {
+        if (sdl_overlay_pix_fmt_map[i].pix_fmt == encctx->pix_fmt) {
+            sdl->overlay_fmt = sdl_overlay_pix_fmt_map[i].overlay_fmt;
+            break;
+        }
+    }
+
+    if (!sdl->overlay_fmt) {
+        av_log(s, AV_LOG_ERROR,
+               "Unsupported pixel format '%s', choose one of yuv420p, yuyv422, or uyvy422\n",
+               av_get_pix_fmt_name(encctx->pix_fmt));
+        ret = AVERROR(EINVAL);
+        goto fail;
+    }
+
+    /* compute overlay width and height from the codec context information */
+    sar = st->sample_aspect_ratio.num ? st->sample_aspect_ratio : (AVRational){ 1, 1 };
+    dar = av_mul_q(sar, (AVRational){ encctx->width, encctx->height });
+
+    /* we suppose the screen has a 1/1 sample aspect ratio */
+    if (sdl->window_width && sdl->window_height) {
+        /* fit in the window */
+        if (av_cmp_q(dar, (AVRational){ sdl->window_width, sdl->window_height }) > 0) {
+            /* fit in width */
+            sdl->overlay_width  = sdl->window_width;
+            sdl->overlay_height = av_rescale(sdl->overlay_width, dar.den, dar.num);
+        } else {
+            /* fit in height */
+            sdl->overlay_height = sdl->window_height;
+            sdl->overlay_width  = av_rescale(sdl->overlay_height, dar.num, dar.den);
+        }
+    } else {
+        if (sar.num > sar.den) {
+            sdl->overlay_width  = encctx->width;
+            sdl->overlay_height = av_rescale(sdl->overlay_width, dar.den, dar.num);
+        } else {
+            sdl->overlay_height = encctx->height;
+            sdl->overlay_width  = av_rescale(sdl->overlay_height, dar.num, dar.den);
+        }
+        sdl->window_width  = sdl->overlay_width;
+        sdl->window_height = sdl->overlay_height;
+    }
+    sdl->overlay_x = (sdl->window_width  - sdl->overlay_width ) / 2;
+    sdl->overlay_y = (sdl->window_height - sdl->overlay_height) / 2;
+
+    SDL_WM_SetCaption(sdl->window_title, sdl->icon_title);
+    sdl->surface = SDL_SetVideoMode(sdl->window_width, sdl->window_height,
+                                    24, SDL_SWSURFACE);
+    if (!sdl->surface) {
+        av_log(s, AV_LOG_ERROR, "Unable to set video mode: %s\n", SDL_GetError());
+        ret = AVERROR(EINVAL);
+        goto fail;
+    }
+
+    sdl->overlay = SDL_CreateYUVOverlay(encctx->width, encctx->height,
+                                        sdl->overlay_fmt, sdl->surface);
+    if (!sdl->overlay || sdl->overlay->pitches[0] < encctx->width) {
+        av_log(s, AV_LOG_ERROR,
+               "SDL does not support an overlay with size of %dx%d pixels\n",
+               encctx->width, encctx->height);
+        ret = AVERROR(EINVAL);
+        goto fail;
+    }
+
+    av_log(s, AV_LOG_VERBOSE, "w:%d h:%d fmt:%s sar:%d/%d -> w:%d h:%d\n",
+           encctx->width, encctx->height, av_get_pix_fmt_name(encctx->pix_fmt), sar.num, sar.den,
+           sdl->overlay_width, sdl->overlay_height);
+    return 0;
+
+fail:
+    sdl_write_trailer(s);
+    return ret;
+}
+
+static int sdl_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    SDLContext *sdl = s->priv_data;
+    AVCodecContext *encctx = s->streams[0]->codec;
+    SDL_Rect rect = { sdl->overlay_x, sdl->overlay_y, sdl->overlay_width, sdl->overlay_height };
+    AVPicture pict;
+    int i;
+
+    avpicture_fill(&pict, pkt->data, encctx->pix_fmt, encctx->width, encctx->height);
+
+    SDL_FillRect(sdl->surface, &sdl->surface->clip_rect,
+                 SDL_MapRGB(sdl->surface->format, 0, 0, 0));
+    SDL_LockYUVOverlay(sdl->overlay);
+    for (i = 0; i < 3; i++) {
+        sdl->overlay->pixels [i] = pict.data    [i];
+        sdl->overlay->pitches[i] = pict.linesize[i];
+    }
+    SDL_DisplayYUVOverlay(sdl->overlay, &rect);
+    SDL_UnlockYUVOverlay(sdl->overlay);
+
+    SDL_UpdateRect(sdl->surface, rect.x, rect.y, rect.w, rect.h);
+
+    return 0;
+}
+
+#define OFFSET(x) offsetof(SDLContext,x)
+
+static const AVOption options[] = {
+    { "window_title", "set SDL window title",           OFFSET(window_title), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
+    { "icon_title",   "set SDL iconified window title", OFFSET(icon_title)  , AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
+    { "window_size",  "set SDL window forced size",     OFFSET(window_width), AV_OPT_TYPE_IMAGE_SIZE,{.str=NULL}, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
+    { NULL },
+};
+
+static const AVClass sdl_class = {
+    .class_name = "sdl outdev",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVOutputFormat ff_sdl_muxer = {
+    .name           = "sdl",
+    .long_name      = NULL_IF_CONFIG_SMALL("SDL output device"),
+    .priv_data_size = sizeof(SDLContext),
+    .audio_codec    = AV_CODEC_ID_NONE,
+    .video_codec    = AV_CODEC_ID_RAWVIDEO,
+    .write_header   = sdl_write_header,
+    .write_packet   = sdl_write_packet,
+    .write_trailer  = sdl_write_trailer,
+    .flags          = AVFMT_NOFILE | AVFMT_VARIABLE_FPS | AVFMT_NOTIMESTAMPS,
+    .priv_class     = &sdl_class,
+};
diff --git a/libavdevice/sndio_common.c b/libavdevice/sndio_common.c
index 1bea6c5..19f39be 100644
--- a/libavdevice/sndio_common.c
+++ b/libavdevice/sndio_common.c
@@ -2,27 +2,27 @@
  * sndio play and grab interface
  * Copyright (c) 2010 Jacob Meuser
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <stdint.h>
 #include <sndio.h>
 
-#include "libavformat/avformat.h"
+#include "avdevice.h"
 
 #include "sndio_common.h"
 
diff --git a/libavdevice/sndio_common.h b/libavdevice/sndio_common.h
index 2f70213..74f41f5 100644
--- a/libavdevice/sndio_common.h
+++ b/libavdevice/sndio_common.h
@@ -2,20 +2,20 @@
  * sndio play and grab interface
  * Copyright (c) 2010 Jacob Meuser
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,8 +25,8 @@
 #include <stdint.h>
 #include <sndio.h>
 
-#include "libavformat/avformat.h"
 #include "libavutil/log.h"
+#include "avdevice.h"
 
 typedef struct SndioData {
     AVClass *class;
diff --git a/libavdevice/sndio_dec.c b/libavdevice/sndio_dec.c
index a29a088..2d7b848 100644
--- a/libavdevice/sndio_dec.c
+++ b/libavdevice/sndio_dec.c
@@ -2,20 +2,20 @@
  * sndio play and grab interface
  * Copyright (c) 2010 Jacob Meuser
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavdevice/sndio_enc.c b/libavdevice/sndio_enc.c
index 6f69b9e..84d070e 100644
--- a/libavdevice/sndio_enc.c
+++ b/libavdevice/sndio_enc.c
@@ -2,28 +2,27 @@
  * sndio play and grab interface
  * Copyright (c) 2010 Jacob Meuser
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <stdint.h>
 #include <sndio.h>
 
-#include "libavformat/avformat.h"
-
+#include "avdevice.h"
 #include "sndio_common.h"
 
 static av_cold int audio_write_header(AVFormatContext *s1)
diff --git a/libavdevice/timefilter.c b/libavdevice/timefilter.c
index 8f52fc5..343f1b1 100644
--- a/libavdevice/timefilter.c
+++ b/libavdevice/timefilter.c
@@ -5,20 +5,20 @@
  * Author: Olivier Guilyardi <olivier samalyse com>
  *         Michael Niedermayer <michaelni gmx at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -37,14 +37,21 @@
     int count;
 };
 
-TimeFilter *ff_timefilter_new(double clock_period,
-                              double feedback2_factor,
-                              double feedback3_factor)
+/* 1 - exp(-x) using a 3-order power series */
+static double qexpneg(double x)
+{
+    return 1 - 1 / (1 + x * (1 + x / 2 * (1 + x / 3)));
+}
+
+TimeFilter *ff_timefilter_new(double time_base,
+                              double period,
+                              double bandwidth)
 {
     TimeFilter *self       = av_mallocz(sizeof(TimeFilter));
-    self->clock_period     = clock_period;
-    self->feedback2_factor = feedback2_factor;
-    self->feedback3_factor = feedback3_factor;
+    double o               = 2 * M_PI * bandwidth * period * time_base;
+    self->clock_period     = time_base;
+    self->feedback2_factor = qexpneg(M_SQRT2 * o);
+    self->feedback3_factor = qexpneg(o * o) / period;
     return self;
 }
 
@@ -69,11 +76,16 @@
         loop_error = system_time - self->cycle_time;
 
         self->cycle_time   += FFMAX(self->feedback2_factor, 1.0 / self->count) * loop_error;
-        self->clock_period += self->feedback3_factor * loop_error / period;
+        self->clock_period += self->feedback3_factor * loop_error;
     }
     return self->cycle_time;
 }
 
+double ff_timefilter_eval(TimeFilter *self, double delta)
+{
+    return self->cycle_time + self->clock_period * delta;
+}
+
 #ifdef TEST
 #include "libavutil/lfg.h"
 #define LFG_MAX ((1LL << 32) - 1)
@@ -87,17 +99,21 @@
 #define SAMPLES 1000
     double ideal[SAMPLES];
     double samples[SAMPLES];
+    double samplet[SAMPLES];
     for (n0 = 0; n0 < 40; n0 = 2 * n0 + 1) {
         for (n1 = 0; n1 < 10; n1 = 2 * n1 + 1) {
             double best_error = 1000000000;
             double bestpar0   = 1;
-            double bestpar1   = 0.001;
+            double bestpar1   = 1;
             int better, i;
 
             av_lfg_init(&prng, 123);
             for (i = 0; i < SAMPLES; i++) {
-                ideal[i]   = 10 + i + n1 * i / (1000);
+                samplet[i] = 10 + i + (av_lfg_get(&prng) < LFG_MAX/2 ? 0 : 0.999);
+                ideal[i]   = samplet[i] + n1 * i / (1000);
                 samples[i] = ideal[i] + n0 * (av_lfg_get(&prng) - LFG_MAX / 2) / (LFG_MAX * 10LL);
+                if(i && samples[i]<samples[i-1])
+                    samples[i]=samples[i-1]+0.001;
             }
 
             do {
@@ -109,7 +125,9 @@
                         TimeFilter *tf = ff_timefilter_new(1, par0, par1);
                         for (i = 0; i < SAMPLES; i++) {
                             double filtered;
-                            filtered = ff_timefilter_update(tf, samples[i], 1);
+                            filtered = ff_timefilter_update(tf, samples[i], i ? (samplet[i] - samplet[i-1]) : 1);
+                            if(filtered < 0 || filtered > 1000000000)
+                                printf("filter is unstable\n");
                             error   += (filtered - ideal[i]) * (filtered - ideal[i]);
                         }
                         ff_timefilter_destroy(tf);
diff --git a/libavdevice/timefilter.h b/libavdevice/timefilter.h
index 8cadd8b..6662959 100644
--- a/libavdevice/timefilter.h
+++ b/libavdevice/timefilter.h
@@ -5,20 +5,20 @@
  * Author: Olivier Guilyardi <olivier samalyse com>
  *         Michael Niedermayer <michaelni gmx at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -45,16 +45,18 @@
  *
  * Unless you know what you are doing, you should set these as follow:
  *
- * o = 2 * M_PI * bandwidth * period
- * feedback2_factor = sqrt(2 * o)
+ * o = 2 * M_PI * bandwidth * period_in_seconds
+ * feedback2_factor = sqrt(2) * o
  * feedback3_factor = o * o
  *
  * Where bandwidth is up to you to choose. Smaller values will filter out more
  * of the jitter, but also take a longer time for the loop to settle. A good
  * starting point is something between 0.3 and 3 Hz.
  *
- * @param clock_period period of the hardware clock in seconds
- *        (for example 1.0/44100)
+ * @param time_base   period of the hardware clock in seconds
+ *                    (for example 1.0/44100)
+ * @param period      expected update interval, in input units
+ * @param brandwidth  filtering bandwidth, in Hz
  *
  * For more details about these parameters and background concepts please see:
  * http://www.kokkinizita.net/papers/usingdll.pdf
@@ -80,6 +82,15 @@
 double ff_timefilter_update(TimeFilter *self, double system_time, double period);
 
 /**
+ * Evaluate the filter at a specified time
+ *
+ * @param delta  difference between the requested time and the current time
+ *               (last call to ff_timefilter_update).
+ * @return  the filtered time
+ */
+double ff_timefilter_eval(TimeFilter *self, double delta);
+
+/**
  * Reset the filter
  *
  * This function should mainly be called in case of XRUN.
diff --git a/libavdevice/v4l.c b/libavdevice/v4l.c
new file mode 100644
index 0000000..e2f37d6
--- /dev/null
+++ b/libavdevice/v4l.c
@@ -0,0 +1,363 @@
+/*
+ * Linux video grab interface
+ * Copyright (c) 2000,2001 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avdevice.h"
+
+#undef __STRICT_ANSI__ //workaround due to broken kernel headers
+#include "config.h"
+#include "libavutil/rational.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "libavformat/internal.h"
+#include "libavcodec/dsputil.h"
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#define _LINUX_TIME_H 1
+#include <linux/videodev.h>
+#include <time.h>
+#include "avdevice.h"
+
+typedef struct {
+    AVClass *class;
+    int fd;
+    int frame_format; /* see VIDEO_PALETTE_xxx */
+    int use_mmap;
+    AVRational time_base;
+    int64_t time_frame;
+    int frame_size;
+    struct video_capability video_cap;
+    struct video_audio audio_saved;
+    struct video_window video_win;
+    uint8_t *video_buf;
+    struct video_mbuf gb_buffers;
+    struct video_mmap gb_buf;
+    int gb_frame;
+    int standard;
+} VideoData;
+
+static const struct {
+    int palette;
+    int depth;
+    enum AVPixelFormat pix_fmt;
+} video_formats [] = {
+    {.palette = VIDEO_PALETTE_YUV420P, .depth = 12, .pix_fmt = AV_PIX_FMT_YUV420P },
+    {.palette = VIDEO_PALETTE_YUV422,  .depth = 16, .pix_fmt = AV_PIX_FMT_YUYV422 },
+    {.palette = VIDEO_PALETTE_UYVY,    .depth = 16, .pix_fmt = AV_PIX_FMT_UYVY422 },
+    {.palette = VIDEO_PALETTE_YUYV,    .depth = 16, .pix_fmt = AV_PIX_FMT_YUYV422 },
+    /* NOTE: v4l uses BGR24, not RGB24 */
+    {.palette = VIDEO_PALETTE_RGB24,   .depth = 24, .pix_fmt = AV_PIX_FMT_BGR24   },
+    {.palette = VIDEO_PALETTE_RGB565,  .depth = 16, .pix_fmt = AV_PIX_FMT_BGR565  },
+    {.palette = VIDEO_PALETTE_GREY,    .depth = 8,  .pix_fmt = AV_PIX_FMT_GRAY8   },
+};
+
+
+static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap)
+{
+    VideoData *s = s1->priv_data;
+    AVStream *st;
+    int video_fd;
+    int desired_palette, desired_depth;
+    struct video_tuner tuner;
+    struct video_audio audio;
+    struct video_picture pict;
+    int j;
+    int vformat_num = FF_ARRAY_ELEMS(video_formats);
+
+    av_log(s1, AV_LOG_WARNING, "V4L input device is deprecated and will be removed in the next release.");
+
+    if (ap->time_base.den <= 0) {
+        av_log(s1, AV_LOG_ERROR, "Wrong time base (%d)\n", ap->time_base.den);
+        return -1;
+    }
+    s->time_base = ap->time_base;
+
+    s->video_win.width = ap->width;
+    s->video_win.height = ap->height;
+
+    st = avformat_new_stream(s1, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+    avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
+
+    video_fd = open(s1->filename, O_RDWR);
+    if (video_fd < 0) {
+        av_log(s1, AV_LOG_ERROR, "%s: %s\n", s1->filename, strerror(errno));
+        goto fail;
+    }
+
+    if (ioctl(video_fd, VIDIOCGCAP, &s->video_cap) < 0) {
+        av_log(s1, AV_LOG_ERROR, "VIDIOCGCAP: %s\n", strerror(errno));
+        goto fail;
+    }
+
+    if (!(s->video_cap.type & VID_TYPE_CAPTURE)) {
+        av_log(s1, AV_LOG_ERROR, "Fatal: grab device does not handle capture\n");
+        goto fail;
+    }
+
+    /* no values set, autodetect them */
+    if (s->video_win.width <= 0 || s->video_win.height <= 0) {
+        if (ioctl(video_fd, VIDIOCGWIN, &s->video_win, sizeof(s->video_win)) < 0) {
+            av_log(s1, AV_LOG_ERROR, "VIDIOCGWIN: %s\n", strerror(errno));
+            goto fail;
+        }
+    }
+
+    if(av_image_check_size(s->video_win.width, s->video_win.height, 0, s1) < 0)
+        return -1;
+
+    desired_palette = -1;
+    desired_depth = -1;
+    for (j = 0; j < vformat_num; j++) {
+        if (ap->pix_fmt == video_formats[j].pix_fmt) {
+            desired_palette = video_formats[j].palette;
+            desired_depth = video_formats[j].depth;
+            break;
+        }
+    }
+
+    /* set tv standard */
+    if (!ioctl(video_fd, VIDIOCGTUNER, &tuner)) {
+        tuner.mode = s->standard;
+        ioctl(video_fd, VIDIOCSTUNER, &tuner);
+    }
+
+    /* unmute audio */
+    audio.audio = 0;
+    ioctl(video_fd, VIDIOCGAUDIO, &audio);
+    memcpy(&s->audio_saved, &audio, sizeof(audio));
+    audio.flags &= ~VIDEO_AUDIO_MUTE;
+    ioctl(video_fd, VIDIOCSAUDIO, &audio);
+
+    ioctl(video_fd, VIDIOCGPICT, &pict);
+    av_dlog(s1, "v4l: colour=%d hue=%d brightness=%d constrast=%d whiteness=%d\n",
+            pict.colour, pict.hue, pict.brightness, pict.contrast, pict.whiteness);
+    /* try to choose a suitable video format */
+    pict.palette = desired_palette;
+    pict.depth= desired_depth;
+    if (desired_palette == -1 || ioctl(video_fd, VIDIOCSPICT, &pict) < 0) {
+        for (j = 0; j < vformat_num; j++) {
+            pict.palette = video_formats[j].palette;
+            pict.depth = video_formats[j].depth;
+            if (-1 != ioctl(video_fd, VIDIOCSPICT, &pict))
+                break;
+        }
+        if (j >= vformat_num)
+            goto fail1;
+    }
+
+    if (ioctl(video_fd, VIDIOCGMBUF, &s->gb_buffers) < 0) {
+        /* try to use read based access */
+        int val;
+
+        s->video_win.x = 0;
+        s->video_win.y = 0;
+        s->video_win.chromakey = -1;
+        s->video_win.flags = 0;
+
+        if (ioctl(video_fd, VIDIOCSWIN, s->video_win) < 0) {
+            av_log(s1, AV_LOG_ERROR, "VIDIOCSWIN: %s\n", strerror(errno));
+            goto fail;
+        }
+
+        s->frame_format = pict.palette;
+
+        val = 1;
+        if (ioctl(video_fd, VIDIOCCAPTURE, &val) < 0) {
+            av_log(s1, AV_LOG_ERROR, "VIDIOCCAPTURE: %s\n", strerror(errno));
+            goto fail;
+        }
+
+        s->time_frame = av_gettime() * s->time_base.den / s->time_base.num;
+        s->use_mmap = 0;
+    } else {
+        s->video_buf = mmap(0, s->gb_buffers.size, PROT_READ|PROT_WRITE, MAP_SHARED, video_fd, 0);
+        if ((unsigned char*)-1 == s->video_buf) {
+            s->video_buf = mmap(0, s->gb_buffers.size, PROT_READ|PROT_WRITE, MAP_PRIVATE, video_fd, 0);
+            if ((unsigned char*)-1 == s->video_buf) {
+                av_log(s1, AV_LOG_ERROR, "mmap: %s\n", strerror(errno));
+                goto fail;
+            }
+        }
+        s->gb_frame = 0;
+        s->time_frame = av_gettime() * s->time_base.den / s->time_base.num;
+
+        /* start to grab the first frame */
+        s->gb_buf.frame = s->gb_frame % s->gb_buffers.frames;
+        s->gb_buf.height = s->video_win.height;
+        s->gb_buf.width = s->video_win.width;
+        s->gb_buf.format = pict.palette;
+
+        if (ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf) < 0) {
+            if (errno != EAGAIN) {
+            fail1:
+                av_log(s1, AV_LOG_ERROR, "VIDIOCMCAPTURE: %s\n", strerror(errno));
+            } else {
+                av_log(s1, AV_LOG_ERROR, "Fatal: grab device does not receive any video signal\n");
+            }
+            goto fail;
+        }
+        for (j = 1; j < s->gb_buffers.frames; j++) {
+          s->gb_buf.frame = j;
+          ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf);
+        }
+        s->frame_format = s->gb_buf.format;
+        s->use_mmap = 1;
+    }
+
+    for (j = 0; j < vformat_num; j++) {
+        if (s->frame_format == video_formats[j].palette) {
+            s->frame_size = s->video_win.width * s->video_win.height * video_formats[j].depth / 8;
+            st->codec->pix_fmt = video_formats[j].pix_fmt;
+            break;
+        }
+    }
+
+    if (j >= vformat_num)
+        goto fail;
+
+    s->fd = video_fd;
+
+    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+    st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
+    st->codec->width = s->video_win.width;
+    st->codec->height = s->video_win.height;
+    st->codec->time_base = s->time_base;
+    st->codec->bit_rate = s->frame_size * 1/av_q2d(st->codec->time_base) * 8;
+
+    return 0;
+ fail:
+    if (video_fd >= 0)
+        close(video_fd);
+    return AVERROR(EIO);
+}
+
+static int v4l_mm_read_picture(VideoData *s, uint8_t *buf)
+{
+    uint8_t *ptr;
+
+    while (ioctl(s->fd, VIDIOCSYNC, &s->gb_frame) < 0 &&
+           (errno == EAGAIN || errno == EINTR));
+
+    ptr = s->video_buf + s->gb_buffers.offsets[s->gb_frame];
+    memcpy(buf, ptr, s->frame_size);
+
+    /* Setup to capture the next frame */
+    s->gb_buf.frame = s->gb_frame;
+    if (ioctl(s->fd, VIDIOCMCAPTURE, &s->gb_buf) < 0) {
+        if (errno == EAGAIN)
+            av_log(NULL, AV_LOG_ERROR, "Cannot Sync\n");
+        else
+            av_log(NULL, AV_LOG_ERROR, "VIDIOCMCAPTURE: %s\n", strerror(errno));
+        return AVERROR(EIO);
+    }
+
+    /* This is now the grabbing frame */
+    s->gb_frame = (s->gb_frame + 1) % s->gb_buffers.frames;
+
+    return s->frame_size;
+}
+
+static int grab_read_packet(AVFormatContext *s1, AVPacket *pkt)
+{
+    VideoData *s = s1->priv_data;
+    int64_t curtime, delay;
+    struct timespec ts;
+
+    /* Calculate the time of the next frame */
+    s->time_frame += INT64_C(1000000);
+
+    /* wait based on the frame rate */
+    for(;;) {
+        curtime = av_gettime();
+        delay = s->time_frame * s->time_base.num / s->time_base.den - curtime;
+        if (delay <= 0) {
+            if (delay < INT64_C(-1000000) * s->time_base.num / s->time_base.den) {
+                /* printf("grabbing is %d frames late (dropping)\n", (int) -(delay / 16666)); */
+                s->time_frame += INT64_C(1000000);
+            }
+            break;
+        }
+        ts.tv_sec = delay / 1000000;
+        ts.tv_nsec = (delay % 1000000) * 1000;
+        nanosleep(&ts, NULL);
+    }
+
+    if (av_new_packet(pkt, s->frame_size) < 0)
+        return AVERROR(EIO);
+
+    pkt->pts = curtime;
+
+    /* read one frame */
+    if (s->use_mmap) {
+        return v4l_mm_read_picture(s, pkt->data);
+    } else {
+        if (read(s->fd, pkt->data, pkt->size) != pkt->size)
+            return AVERROR(EIO);
+        return s->frame_size;
+    }
+}
+
+static int grab_read_close(AVFormatContext *s1)
+{
+    VideoData *s = s1->priv_data;
+
+    if (s->use_mmap)
+        munmap(s->video_buf, s->gb_buffers.size);
+
+    /* mute audio. we must force it because the BTTV driver does not
+       return its state correctly */
+    s->audio_saved.flags |= VIDEO_AUDIO_MUTE;
+    ioctl(s->fd, VIDIOCSAUDIO, &s->audio_saved);
+
+    close(s->fd);
+    return 0;
+}
+
+static const AVOption options[] = {
+    { "standard", "", offsetof(VideoData, standard), AV_OPT_TYPE_INT, {.i64 = VIDEO_MODE_NTSC}, VIDEO_MODE_PAL, VIDEO_MODE_NTSC, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+    { "PAL",   "", 0, AV_OPT_TYPE_CONST, {.i64 = VIDEO_MODE_PAL},   0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+    { "SECAM", "", 0, AV_OPT_TYPE_CONST, {.i64 = VIDEO_MODE_SECAM}, 0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+    { "NTSC",  "", 0, AV_OPT_TYPE_CONST, {.i64 = VIDEO_MODE_NTSC},  0, 0, AV_OPT_FLAG_DECODING_PARAM, "standard" },
+    { NULL },
+};
+
+static const AVClass v4l_class = {
+    .class_name = "V4L indev",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_v4l_demuxer = {
+    .name           = "video4linux,v4l",
+    .long_name      = NULL_IF_CONFIG_SMALL("Video4Linux device grab"),
+    .priv_data_size = sizeof(VideoData),
+    .read_header    = grab_read_header,
+    .read_packet    = grab_read_packet,
+    .read_close     = grab_read_close,
+    .flags          = AVFMT_NOFILE,
+    .priv_class     = &v4l_class,
+};
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 9e71f1d..cd6aeb2 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -1,54 +1,72 @@
 /*
- * Video4Linux2 grab interface
  * Copyright (c) 2000,2001 Fabrice Bellard
  * Copyright (c) 2006 Luca Abeni
  *
+ * 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
+ * Video4Linux2 grab interface
+ *
  * Part of this file is based on the V4L2 video capture example
  * (http://v4l2spec.bytesex.org/v4l2spec/capture.c)
  *
  * Thanks to Michael Niedermayer for providing the mapping between
  * V4L2_PIX_FMT_* and AV_PIX_FMT_*
- *
- *
- * 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
  */
 
 #undef __STRICT_ANSI__ //workaround due to broken kernel headers
 #include "config.h"
-#include "libavformat/avformat.h"
 #include "libavformat/internal.h"
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <sys/time.h>
-#include <poll.h>
 #if HAVE_SYS_VIDEOIO_H
 #include <sys/videoio.h>
 #else
+#if HAVE_ASM_TYPES_H
+#include <asm/types.h>
+#endif
 #include <linux/videodev2.h>
 #endif
+#include "libavutil/avassert.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
+#include "avdevice.h"
+#include "timefilter.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/avstring.h"
-#include "libavutil/mathematics.h"
+
+#if CONFIG_LIBV4L2
+#include <libv4l2.h>
+#else
+#define v4l2_open   open
+#define v4l2_close  close
+#define v4l2_dup    dup
+#define v4l2_ioctl  ioctl
+#define v4l2_read   read
+#define v4l2_mmap   mmap
+#define v4l2_munmap munmap
+#endif
 
 static const int desired_video_buffers = 256;
 
@@ -56,23 +74,45 @@
 #define V4L_RAWFORMATS  1
 #define V4L_COMPFORMATS 2
 
+/**
+ * Return timestamps to the user exactly as returned by the kernel
+ */
+#define V4L_TS_DEFAULT  0
+/**
+ * Autodetect the kind of timestamps returned by the kernel and convert to
+ * absolute (wall clock) timestamps.
+ */
+#define V4L_TS_ABS      1
+/**
+ * Assume kernel timestamps are from the monotonic clock and convert to
+ * absolute timestamps.
+ */
+#define V4L_TS_MONO2ABS 2
+
+/**
+ * Once the kind of timestamps returned by the kernel have been detected,
+ * the value of the timefilter (NULL or not) determines whether a conversion
+ * takes place.
+ */
+#define V4L_TS_CONVERT_READY V4L_TS_DEFAULT
+
 struct video_data {
     AVClass *class;
     int fd;
     int frame_format; /* V4L2_PIX_FMT_* */
     int width, height;
     int frame_size;
-    int timeout;
     int interlaced;
     int top_field_first;
+    int ts_mode;
+    TimeFilter *timefilter;
+    int64_t last_time_m;
 
     int buffers;
     void **buf_start;
     unsigned int *buf_len;
     char *standard;
     int channel;
-    char *video_size;   /**< String describing video size,
-                             set by a private option. */
     char *pixel_format; /**< Set by a private option. */
     int list_format;    /**< Set by a private option. */
     char *framerate;    /**< Set by a private option. */
@@ -92,20 +132,27 @@
 static struct fmt_map fmt_conversion_table[] = {
     //ff_fmt           codec_id           v4l2_fmt
     { AV_PIX_FMT_YUV420P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV420  },
+    { AV_PIX_FMT_YUV420P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YVU420  },
     { AV_PIX_FMT_YUV422P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV422P },
     { AV_PIX_FMT_YUYV422, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUYV    },
     { AV_PIX_FMT_UYVY422, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_UYVY    },
     { AV_PIX_FMT_YUV411P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV411P },
     { AV_PIX_FMT_YUV410P, AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_YUV410  },
-    { AV_PIX_FMT_RGB555,  AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555  },
-    { AV_PIX_FMT_RGB565,  AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565  },
+    { AV_PIX_FMT_RGB555LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555  },
+    { AV_PIX_FMT_RGB555BE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB555X },
+    { AV_PIX_FMT_RGB565LE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565  },
+    { AV_PIX_FMT_RGB565BE,AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB565X },
     { AV_PIX_FMT_BGR24,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR24   },
     { AV_PIX_FMT_RGB24,   AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_RGB24   },
-    { AV_PIX_FMT_BGRA,    AV_CODEC_ID_RAWVIDEO, V4L2_PIX_FMT_BGR32   },
+    { 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    },
     { 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_CPIA1
+    { AV_PIX_FMT_NONE,    AV_CODEC_ID_CPIA,     V4L2_PIX_FMT_CPIA1   },
+#endif
 };
 
 static int device_open(AVFormatContext *ctx)
@@ -119,7 +166,7 @@
         flags |= O_NONBLOCK;
     }
 
-    fd = open(ctx->filename, flags, 0);
+    fd = v4l2_open(ctx->filename, flags, 0);
     if (fd < 0) {
         err = errno;
 
@@ -129,7 +176,7 @@
         return AVERROR(err);
     }
 
-    res = ioctl(fd, VIDIOC_QUERYCAP, &cap);
+    res = v4l2_ioctl(fd, VIDIOC_QUERYCAP, &cap);
     if (res < 0) {
         err = errno;
         av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",
@@ -159,7 +206,7 @@
     return fd;
 
 fail:
-    close(fd);
+    v4l2_close(fd);
     return AVERROR(err);
 }
 
@@ -178,7 +225,7 @@
     pix->pixelformat = pix_fmt;
     pix->field = V4L2_FIELD_ANY;
 
-    res = ioctl(fd, VIDIOC_S_FMT, &fmt);
+    res = v4l2_ioctl(fd, VIDIOC_S_FMT, &fmt);
 
     if ((*width != fmt.fmt.pix.width) || (*height != fmt.fmt.pix.height)) {
         av_log(ctx, AV_LOG_INFO,
@@ -209,7 +256,7 @@
     int res;
     v4l2_std_id std;
 
-    res = ioctl(fd, VIDIOC_G_STD, &std);
+    res = v4l2_ioctl(fd, VIDIOC_G_STD, &std);
     if (res < 0) {
         return 0;
     }
@@ -338,34 +385,30 @@
         .memory = V4L2_MEMORY_MMAP
     };
 
-    res = ioctl(s->fd, VIDIOC_REQBUFS, &req);
+    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 (req.count < 2) {
         av_log(ctx, AV_LOG_ERROR, "Insufficient buffer memory\n");
-
         return AVERROR(ENOMEM);
     }
     s->buffers = req.count;
     s->buf_start = av_malloc(sizeof(void *) * s->buffers);
     if (s->buf_start == NULL) {
         av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer pointers\n");
-
         return AVERROR(ENOMEM);
     }
     s->buf_len = av_malloc(sizeof(unsigned int) * s->buffers);
     if (s->buf_len == NULL) {
         av_log(ctx, AV_LOG_ERROR, "Cannot allocate buffer sizes\n");
         av_free(s->buf_start);
-
         return AVERROR(ENOMEM);
     }
 
@@ -375,11 +418,9 @@
             .index  = i,
             .memory = V4L2_MEMORY_MMAP
         };
-
-        res = ioctl(s->fd, VIDIOC_QUERYBUF, &buf);
+        res = v4l2_ioctl(s->fd, VIDIOC_QUERYBUF, &buf);
         if (res < 0) {
             av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYBUF)\n");
-
             return AVERROR(errno);
         }
 
@@ -391,13 +432,12 @@
 
             return -1;
         }
-        s->buf_start[i] = mmap(NULL, buf.length,
+        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);
         }
     }
@@ -420,7 +460,7 @@
     fd = buf_descriptor->fd;
     av_free(buf_descriptor);
 
-    res = ioctl(fd, VIDIOC_QBUF, &buf);
+    res = v4l2_ioctl(fd, VIDIOC_QBUF, &buf);
     if (res < 0)
         av_log(NULL, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
                strerror(errno));
@@ -429,6 +469,66 @@
     pkt->size = 0;
 }
 
+#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
+static int64_t av_gettime_monotonic(void)
+{
+    struct timespec tv;
+
+    clock_gettime(CLOCK_MONOTONIC, &tv);
+    return (int64_t)tv.tv_sec * 1000000 + tv.tv_nsec / 1000;
+}
+#endif
+
+static int init_convert_timestamp(AVFormatContext *ctx, int64_t ts)
+{
+    struct video_data *s = ctx->priv_data;
+    int64_t now;
+
+    now = av_gettime();
+    if (s->ts_mode == V4L_TS_ABS &&
+        ts <= now + 1 * AV_TIME_BASE && ts >= now - 10 * AV_TIME_BASE) {
+        av_log(ctx, AV_LOG_INFO, "Detected absolute timestamps\n");
+        s->ts_mode = V4L_TS_CONVERT_READY;
+        return 0;
+    }
+#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
+    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);
+        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);
+        s->ts_mode = V4L_TS_CONVERT_READY;
+        return 0;
+    }
+#endif
+    av_log(ctx, AV_LOG_ERROR, "Unknown timestamps\n");
+    return AVERROR(EIO);
+}
+
+static int convert_timestamp(AVFormatContext *ctx, int64_t *ts)
+{
+    struct video_data *s = ctx->priv_data;
+
+    if (s->ts_mode) {
+        int r = init_convert_timestamp(ctx, *ts);
+        if (r < 0)
+            return r;
+    }
+#if HAVE_CLOCK_GETTIME && defined(CLOCK_MONOTONIC)
+    if (s->timefilter) {
+        int64_t nowa = av_gettime();
+        int64_t nowm = av_gettime_monotonic();
+        ff_timefilter_update(s->timefilter, nowa, nowm - s->last_time_m);
+        s->last_time_m = nowm;
+        *ts = ff_timefilter_eval(s->timefilter, *ts - nowm);
+    }
+#endif
+    return 0;
+}
+
 static int mmap_read_frame(AVFormatContext *ctx, AVPacket *pkt)
 {
     struct video_data *s = ctx->priv_data;
@@ -437,22 +537,13 @@
         .memory = V4L2_MEMORY_MMAP
     };
     struct buff_data *buf_descriptor;
-    struct pollfd p = { .fd = s->fd, .events = POLLIN };
     int res;
 
-    res = poll(&p, 1, s->timeout);
-    if (res < 0)
-        return AVERROR(errno);
-
-    if (!(p.revents & (POLLIN | POLLERR | POLLHUP)))
-        return AVERROR(EAGAIN);
-
     /* FIXME: Some special treatment might be needed in case of loss of signal... */
-    while ((res = ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
+    while ((res = v4l2_ioctl(s->fd, VIDIOC_DQBUF, &buf)) < 0 && (errno == EINTR));
     if (res < 0) {
         if (errno == EAGAIN) {
             pkt->size = 0;
-
             return AVERROR(EAGAIN);
         }
         av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_DQBUF): %s\n",
@@ -460,7 +551,14 @@
 
         return AVERROR(errno);
     }
-    assert (buf.index < s->buffers);
+    av_assert0(buf.index < s->buffers);
+
+    /* 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.
+     */
+    if (ctx->video_codec_id == AV_CODEC_ID_CPIA)
+        s->frame_size = buf.bytesused;
+
     if (s->frame_size > 0 && buf.bytesused != s->frame_size) {
         av_log(ctx, AV_LOG_ERROR,
                "The v4l2 frame is %d bytes, but %d bytes are expected\n",
@@ -473,6 +571,9 @@
     pkt->data= s->buf_start[buf.index];
     pkt->size = buf.bytesused;
     pkt->pts = buf.timestamp.tv_sec * INT64_C(1000000) + buf.timestamp.tv_usec;
+    res = convert_timestamp(ctx, &pkt->pts);
+    if (res < 0)
+        return res;
     pkt->destruct = mmap_release_buffer;
     buf_descriptor = av_malloc(sizeof(struct buff_data));
     if (buf_descriptor == NULL) {
@@ -480,7 +581,7 @@
          * allocate a buffer for memcopying into it
          */
         av_log(ctx, AV_LOG_ERROR, "Failed to allocate a buffer descriptor\n");
-        res = ioctl(s->fd, VIDIOC_QBUF, &buf);
+        res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf);
 
         return AVERROR(ENOMEM);
     }
@@ -504,7 +605,7 @@
             .memory = V4L2_MEMORY_MMAP
         };
 
-        res = ioctl(s->fd, VIDIOC_QBUF, &buf);
+        res = v4l2_ioctl(s->fd, VIDIOC_QBUF, &buf);
         if (res < 0) {
             av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QBUF): %s\n",
                    strerror(errno));
@@ -514,7 +615,7 @@
     }
 
     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    res = ioctl(s->fd, VIDIOC_STREAMON, &type);
+    res = v4l2_ioctl(s->fd, VIDIOC_STREAMON, &type);
     if (res < 0) {
         av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_STREAMON): %s\n",
                strerror(errno));
@@ -534,9 +635,9 @@
     /* We do not check for the result, because we could
      * not do anything about it anyway...
      */
-    ioctl(s->fd, VIDIOC_STREAMOFF, &type);
+    v4l2_ioctl(s->fd, VIDIOC_STREAMOFF, &type);
     for (i = 0; i < s->buffers; i++) {
-        munmap(s->buf_start[i], s->buf_len[i]);
+        v4l2_munmap(s->buf_start[i], s->buf_len[i]);
     }
     av_free(s->buf_start);
     av_free(s->buf_len);
@@ -563,14 +664,14 @@
 
     /* set tv video input */
     input.index = s->channel;
-    if (ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {
+    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 (ioctl(s->fd, VIDIOC_S_INPUT, &input.index) < 0) {
+    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);
@@ -583,22 +684,19 @@
         /* set tv standard */
         for(i=0;;i++) {
             standard.index = i;
-            if (ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {
-                av_log(s1, AV_LOG_ERROR,
-                       "The V4L2 driver ioctl set standard(%s) failed\n",
-                       s->standard);
-                return AVERROR(EIO);
-            }
-
-            if (!av_strcasecmp(standard.name, s->standard)) {
+            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;
         }
 
         av_log(s1, AV_LOG_DEBUG,
                "The V4L2 driver set standard: %s, id: %"PRIu64"\n",
                s->standard, (uint64_t)standard.id);
-        if (ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {
+        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);
@@ -612,7 +710,7 @@
         tpf->numerator   = framerate_q.den;
         tpf->denominator = framerate_q.num;
 
-        if (ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) {
+        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",
                    framerate_q.den, framerate_q.num);
@@ -628,7 +726,7 @@
                    tpf->numerator, tpf->denominator);
         }
     } else {
-        if (ioctl(s->fd, VIDIOC_G_PARM, &streamparm) != 0) {
+        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);
@@ -637,10 +735,6 @@
     s1->streams[0]->codec->time_base.den = tpf->denominator;
     s1->streams[0]->codec->time_base.num = tpf->numerator;
 
-    s->timeout = 100 +
-        av_rescale_q(1, s1->streams[0]->codec->time_base,
-                        (AVRational){1, 1000});
-
     return 0;
 }
 
@@ -671,7 +765,7 @@
 
     if (desired_format != 0) {
         *codec_id = fmt_v4l2codec(desired_format);
-        assert(*codec_id != AV_CODEC_ID_NONE);
+        av_assert0(*codec_id != AV_CODEC_ID_NONE);
     }
 
     return desired_format;
@@ -683,7 +777,7 @@
     AVStream *st;
     int res = 0;
     uint32_t desired_format;
-    enum AVCodecID codec_id;
+    enum AVCodecID codec_id = AV_CODEC_ID_NONE;
     enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;
 
     st = avformat_new_stream(s1, NULL);
@@ -706,13 +800,6 @@
 
     avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
 
-    if (s->video_size &&
-        (res = av_parse_video_size(&s->width, &s->height, s->video_size)) < 0) {
-        av_log(s1, AV_LOG_ERROR, "Could not parse video size '%s'.\n",
-               s->video_size);
-        goto out;
-    }
-
     if (s->pixel_format) {
         AVCodec *codec = avcodec_find_decoder_by_name(s->pixel_format);
 
@@ -736,7 +823,7 @@
         av_log(s1, AV_LOG_VERBOSE,
                "Querying the device for the current frame size\n");
         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-        if (ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {
+        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);
@@ -751,21 +838,28 @@
 
     desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height,
                                      &codec_id);
+
+    /* 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
+     * not be available outside this function
+     */
+    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);
-        close(s->fd);
+        v4l2_close(s->fd);
 
         res = AVERROR(EIO);
         goto out;
     }
-
-    if ((res = av_image_check_size(s->width, s->height, 0, s1) < 0))
+    if ((res = av_image_check_size(s->width, s->height, 0, s1)) < 0)
         goto out;
 
     s->frame_format = desired_format;
 
-    if ((res = v4l2_set_parameters(s1) < 0))
+    if ((res = v4l2_set_parameters(s1)) < 0)
         goto out;
 
     st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);
@@ -774,7 +868,7 @@
 
     if ((res = mmap_init(s1)) ||
         (res = mmap_start(s1)) < 0) {
-        close(s->fd);
+        v4l2_close(s->fd);
         goto out;
     }
 
@@ -785,6 +879,8 @@
     if (codec_id == AV_CODEC_ID_RAWVIDEO)
         st->codec->codec_tag =
             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');
     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;
@@ -818,16 +914,17 @@
 
     mmap_close(s);
 
-    close(s->fd);
+    v4l2_close(s->fd);
     return 0;
 }
 
 #define OFFSET(x) offsetof(struct video_data, x)
 #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(video_size),   AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       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 },
@@ -835,6 +932,11 @@
     { "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" },
     { NULL },
 };
 
@@ -846,7 +948,7 @@
 };
 
 AVInputFormat ff_v4l2_demuxer = {
-    .name           = "video4linux2",
+    .name           = "video4linux2,v4l2",
     .long_name      = NULL_IF_CONFIG_SMALL("Video4Linux2 device grab"),
     .priv_data_size = sizeof(struct video_data),
     .read_header    = v4l2_read_header,
diff --git a/libavdevice/version.h b/libavdevice/version.h
index 52b47db..a178180 100644
--- a/libavdevice/version.h
+++ b/libavdevice/version.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -27,9 +27,9 @@
 
 #include "libavutil/avutil.h"
 
-#define LIBAVDEVICE_VERSION_MAJOR 53
-#define LIBAVDEVICE_VERSION_MINOR  2
-#define LIBAVDEVICE_VERSION_MICRO  0
+#define LIBAVDEVICE_VERSION_MAJOR  54
+#define LIBAVDEVICE_VERSION_MINOR   3
+#define LIBAVDEVICE_VERSION_MICRO 100
 
 #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
                                                LIBAVDEVICE_VERSION_MINOR, \
@@ -39,6 +39,8 @@
                                            LIBAVDEVICE_VERSION_MICRO)
 #define LIBAVDEVICE_BUILD       LIBAVDEVICE_VERSION_INT
 
+#define LIBAVDEVICE_IDENT       "Lavd" AV_STRINGIFY(LIBAVDEVICE_VERSION)
+
 /**
  * FF_API_* defines may be placed below to indicate public API that will be
  * dropped at a future version bump. The defines themselves are not part of
diff --git a/libavdevice/vfwcap.c b/libavdevice/vfwcap.c
index fea85fc..66b02be 100644
--- a/libavdevice/vfwcap.c
+++ b/libavdevice/vfwcap.c
@@ -2,37 +2,35 @@
  * VFW capture interface
  * Copyright (c) 2006-2008 Ramiro Polla
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavformat/avformat.h"
 #include "libavformat/internal.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "libavutil/parseutils.h"
 #include <windows.h>
 #include <vfw.h>
+#include "avdevice.h"
 
 /* Defines for VFW missing from MinGW.
  * Remove this when MinGW incorporates them. */
 #define HWND_MESSAGE                ((HWND)-3)
 
-#define BI_RGB                      0
-
 /* End of missing MinGW defines */
 
 struct vfw_ctx {
@@ -245,7 +243,7 @@
     AVStream *st;
     int devnum;
     int bisize;
-    BITMAPINFO *bi;
+    BITMAPINFO *bi = NULL;
     CAPTUREPARMS cparms;
     DWORD biCompression;
     WORD biBitCount;
@@ -291,7 +289,7 @@
                       (LPARAM) videostream_cb);
     if(!ret) {
         av_log(s, AV_LOG_ERROR, "Could not set video stream callback.\n");
-        goto fail_io;
+        goto fail;
     }
 
     SetWindowLongPtr(ctx->hwnd, GWLP_USERDATA, (LONG_PTR) s);
@@ -305,7 +303,7 @@
     /* Set video format */
     bisize = SendMessage(ctx->hwnd, WM_CAP_GET_VIDEOFORMAT, 0, 0);
     if(!bisize)
-        goto fail_io;
+        goto fail;
     bi = av_malloc(bisize);
     if(!bi) {
         vfw_read_close(s);
@@ -313,16 +311,21 @@
     }
     ret = SendMessage(ctx->hwnd, WM_CAP_GET_VIDEOFORMAT, bisize, (LPARAM) bi);
     if(!ret)
-        goto fail_bi;
+        goto fail;
 
     dump_bih(s, &bi->bmiHeader);
 
+    ret = av_parse_video_rate(&framerate_q, ctx->framerate);
+    if (ret < 0) {
+        av_log(s, AV_LOG_ERROR, "Could not parse framerate '%s'.\n", ctx->framerate);
+        goto fail;
+    }
 
     if (ctx->video_size) {
         ret = av_parse_video_size(&bi->bmiHeader.biWidth, &bi->bmiHeader.biHeight, ctx->video_size);
         if (ret < 0) {
             av_log(s, AV_LOG_ERROR, "Couldn't parse video size.\n");
-            goto fail_bi;
+            goto fail;
         }
     }
 
@@ -341,19 +344,17 @@
     ret = SendMessage(ctx->hwnd, WM_CAP_SET_VIDEOFORMAT, bisize, (LPARAM) bi);
     if(!ret) {
         av_log(s, AV_LOG_ERROR, "Could not set Video Format.\n");
-        goto fail_bi;
+        goto fail;
     }
 
     biCompression = bi->bmiHeader.biCompression;
     biBitCount = bi->bmiHeader.biBitCount;
 
-    av_free(bi);
-
     /* Set sequence setup */
     ret = SendMessage(ctx->hwnd, WM_CAP_GET_SEQUENCE_SETUP, sizeof(cparms),
                       (LPARAM) &cparms);
     if(!ret)
-        goto fail_io;
+        goto fail;
 
     dump_captureparms(s, &cparms);
 
@@ -368,10 +369,10 @@
     ret = SendMessage(ctx->hwnd, WM_CAP_SET_SEQUENCE_SETUP, sizeof(cparms),
                       (LPARAM) &cparms);
     if(!ret)
-        goto fail_io;
+        goto fail;
 
     codec = st->codec;
-    codec->time_base = (AVRational){framerate_q.den, framerate_q.num};
+    codec->time_base = av_inv_q(framerate_q);
     codec->codec_type = AVMEDIA_TYPE_VIDEO;
     codec->width  = bi->bmiHeader.biWidth;
     codec->height = bi->bmiHeader.biHeight;
@@ -397,31 +398,31 @@
         }
     }
 
+    av_freep(&bi);
+
     avpriv_set_pts_info(st, 32, 1, 1000);
 
     ctx->mutex = CreateMutex(NULL, 0, NULL);
     if(!ctx->mutex) {
         av_log(s, AV_LOG_ERROR, "Could not create Mutex.\n" );
-        goto fail_io;
+        goto fail;
     }
     ctx->event = CreateEvent(NULL, 1, 0, NULL);
     if(!ctx->event) {
         av_log(s, AV_LOG_ERROR, "Could not create Event.\n" );
-        goto fail_io;
+        goto fail;
     }
 
     ret = SendMessage(ctx->hwnd, WM_CAP_SEQUENCE_NOFILE, 0, 0);
     if(!ret) {
         av_log(s, AV_LOG_ERROR, "Could not start capture sequence.\n" );
-        goto fail_io;
+        goto fail;
     }
 
     return 0;
 
-fail_bi:
-    av_free(bi);
-
-fail_io:
+fail:
+    av_freep(&bi);
     vfw_read_close(s);
     return AVERROR(EIO);
 }
diff --git a/libavdevice/x11grab.c b/libavdevice/x11grab.c
index 8edbf7b..91c62d9 100644
--- a/libavdevice/x11grab.c
+++ b/libavdevice/x11grab.c
@@ -1,9 +1,9 @@
 /*
  * X11 video grab interface
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav integration:
+ * FFmpeg integration:
  * Copyright (C) 2006 Clemens Fruhwirth <clemens@endorphin.org>
  *                    Edouard Gomez <ed.gomez@free.fr>
  *
@@ -14,18 +14,18 @@
  * Copyright (C) 1997-1998 Rasca, Berlin
  *               2003-2004 Karl H. Beckers, Frankfurt
  *
- * Libav is free software; you can redistribute it and/or modify
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with Libav; if not, write to the Free Software
+ * along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -37,7 +37,6 @@
  */
 
 #include "config.h"
-#include "libavformat/avformat.h"
 #include "libavformat/internal.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
@@ -53,6 +52,7 @@
 #include <X11/extensions/shape.h>
 #include <X11/extensions/XShm.h>
 #include <X11/extensions/Xfixes.h>
+#include "avdevice.h"
 
 /**
  * X11 Device Demuxer context
@@ -63,9 +63,8 @@
     AVRational time_base;    /**< Time base */
     int64_t time_frame;      /**< Current time */
 
-    char *video_size;        /**< String describing video size, set by a private option. */
-    int height;              /**< Height of the grab frame */
     int width;               /**< Width of the grab frame */
+    int height;              /**< Height of the grab frame */
     int x_off;               /**< Horizontal top-left corner coordinate */
     int y_off;               /**< Vertical top-left corner coordinate */
 
@@ -164,33 +163,35 @@
     int y_off = 0;
     int screen;
     int use_shm;
-    char *param, *offset;
+    char *dpyname, *offset;
     int ret = 0;
     AVRational framerate;
 
-    param = av_strdup(s1->filename);
-    if (!param)
+    dpyname = av_strdup(s1->filename);
+    if (!dpyname)
         goto out;
 
-    offset = strchr(param, '+');
+    offset = strchr(dpyname, '+');
     if (offset) {
         sscanf(offset, "%d,%d", &x_off, &y_off);
-        x11grab->draw_mouse = !strstr(offset, "nomouse");
+        if (strstr(offset, "nomouse")) {
+            av_log(s1, AV_LOG_WARNING,
+                   "'nomouse' specification in argument is deprecated: "
+                   "use 'draw_mouse' option with value 0 instead\n");
+            x11grab->draw_mouse = 0;
+        }
         *offset= 0;
     }
 
-    if ((ret = av_parse_video_size(&x11grab->width, &x11grab->height, x11grab->video_size)) < 0) {
-        av_log(s1, AV_LOG_ERROR, "Couldn't parse video size.\n");
-        goto out;
-    }
     if ((ret = av_parse_video_rate(&framerate, x11grab->framerate)) < 0) {
         av_log(s1, AV_LOG_ERROR, "Could not parse framerate: %s.\n", x11grab->framerate);
         goto out;
     }
     av_log(s1, AV_LOG_INFO, "device: %s -> display: %s x: %d y: %d width: %d height: %d\n",
-           s1->filename, param, x_off, y_off, x11grab->width, x11grab->height);
+           s1->filename, dpyname, x_off, y_off, x11grab->width, x11grab->height);
 
-    dpy = XOpenDisplay(param);
+    dpy = XOpenDisplay(dpyname);
+    av_freep(&dpyname);
     if(!dpy) {
         av_log(s1, AV_LOG_ERROR, "Could not open X display.\n");
         ret = AVERROR(EIO);
@@ -221,7 +222,7 @@
     }
 
     use_shm = XShmQueryExtension(dpy);
-    av_log(s1, AV_LOG_INFO, "shared memory extension %s found\n", use_shm ? "" : "not");
+    av_log(s1, AV_LOG_INFO, "shared memory extension%s found\n", use_shm ? "" : " not");
 
     if(use_shm) {
         int scr = XDefaultScreen(dpy);
@@ -296,7 +297,7 @@
         }
         break;
     case 32:
-        input_pixfmt = AV_PIX_FMT_RGB32;
+        input_pixfmt = AV_PIX_FMT_0RGB32;
         break;
     default:
         av_log(s1, AV_LOG_ERROR, "image depth %i not supported ... aborting\n", image->bits_per_pixel);
@@ -306,7 +307,7 @@
 
     x11grab->frame_size = x11grab->width * x11grab->height * image->bits_per_pixel/8;
     x11grab->dpy = dpy;
-    x11grab->time_base  = (AVRational){framerate.den, framerate.num};
+    x11grab->time_base  = av_inv_q(framerate);
     x11grab->time_frame = av_gettime() / av_q2d(x11grab->time_base);
     x11grab->x_off = x_off;
     x11grab->y_off = y_off;
@@ -322,7 +323,7 @@
     st->codec->bit_rate = x11grab->frame_size * 1/av_q2d(x11grab->time_base) * 8;
 
 out:
-    av_free(param);
+    av_free(dpyname);
     return ret;
 }
 
@@ -585,13 +586,16 @@
 #define OFFSET(x) offsetof(struct x11grab, x)
 #define DEC AV_OPT_FLAG_DECODING_PARAM
 static const AVOption options[] = {
-    { "video_size", "A string describing frame size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = "vga"}, 0, 0, DEC },
-    { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "ntsc"}, 0, 0, DEC },
-    { "draw_mouse", "Draw the mouse pointer.", OFFSET(draw_mouse), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, DEC },
-    { "follow_mouse", "Move the grabbing region when the mouse pointer reaches within specified amount of pixels to the edge of region.",
-      OFFSET(follow_mouse), AV_OPT_TYPE_INT, { .i64 = 0 }, -1, INT_MAX, DEC, "follow_mouse" },
-    { "centered", "Keep the mouse pointer at the center of grabbing region when following.", 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, INT_MIN, INT_MAX, DEC, "follow_mouse" },
-    { "show_region", "Show the grabbing region.", OFFSET(show_region), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, DEC },
+    { "draw_mouse", "draw the mouse pointer", OFFSET(draw_mouse), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, DEC },
+
+    { "follow_mouse", "move the grabbing region when the mouse pointer reaches within specified amount of pixels to the edge of region",
+      OFFSET(follow_mouse), AV_OPT_TYPE_INT, {.i64 = 0}, -1, INT_MAX, DEC, "follow_mouse" },
+    { "centered",     "keep the mouse pointer at the center of grabbing region when following",
+      0, AV_OPT_TYPE_CONST, {.i64 = -1}, INT_MIN, INT_MAX, DEC, "follow_mouse" },
+
+    { "framerate",  "set video frame rate",      OFFSET(framerate),   AV_OPT_TYPE_STRING,     {.str = "ntsc"}, 0, 0, DEC },
+    { "show_region", "show the grabbing region", OFFSET(show_region), AV_OPT_TYPE_INT,        {.i64 = 0}, 0, 1, DEC },
+    { "video_size",  "set video frame size",     OFFSET(width),       AV_OPT_TYPE_IMAGE_SIZE, {.str = "vga"}, 0, 0, DEC },
     { NULL },
 };
 
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 530aa57..3618f10 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -1,11 +1,25 @@
+include $(SUBDIR)../config.mak
+
 NAME = avfilter
 FFLIBS = avutil
 FFLIBS-$(CONFIG_ASYNCTS_FILTER) += avresample
-FFLIBS-$(CONFIG_MOVIE_FILTER) += avformat avcodec
 FFLIBS-$(CONFIG_RESAMPLE_FILTER) += avresample
 FFLIBS-$(CONFIG_SCALE_FILTER)   += swscale
 
-HEADERS = avfilter.h                                                    \
+FFLIBS-$(CONFIG_ACONVERT_FILTER)             += swresample
+FFLIBS-$(CONFIG_AMOVIE_FILTER)               += avformat avcodec
+FFLIBS-$(CONFIG_ARESAMPLE_FILTER)            += swresample
+FFLIBS-$(CONFIG_ATEMPO_FILTER)               += avcodec
+FFLIBS-$(CONFIG_DECIMATE_FILTER)             += avcodec
+FFLIBS-$(CONFIG_MOVIE_FILTER)                += avformat avcodec
+FFLIBS-$(CONFIG_PAN_FILTER)                  += swresample
+FFLIBS-$(CONFIG_REMOVELOGO_FILTER)           += avformat avcodec
+FFLIBS-$(CONFIG_MP_FILTER)                   += avcodec postproc
+FFLIBS-$(CONFIG_SMARTBLUR_FILTER)            += swscale
+
+HEADERS = asrc_abuffer.h                                                \
+          avcodec.h                                                     \
+          avfilter.h                                                    \
           avfiltergraph.h                                               \
           buffersink.h                                                  \
           buffersrc.h                                                   \
@@ -20,45 +34,85 @@
        buffersrc.o                                                      \
        drawutils.o                                                      \
        formats.o                                                        \
+       graphdump.o                                                      \
        graphparser.o                                                    \
+       sink_buffer.o                                                    \
+       src_buffer.o                                                     \
+       transform.o                                                      \
        vf_scale.o                                                       \
        video.o                                                          \
 
+
+OBJS-$(CONFIG_AVCODEC)                       += avcodec.o
+OBJS-$(CONFIG_AVFORMAT)                      += lavfutils.o
+OBJS-$(CONFIG_SWSCALE)                       += lswsutils.o
+
+OBJS-$(CONFIG_ACONVERT_FILTER)               += af_aconvert.o
 OBJS-$(CONFIG_AFIFO_FILTER)                  += fifo.o
 OBJS-$(CONFIG_AFORMAT_FILTER)                += af_aformat.o
+OBJS-$(CONFIG_AMERGE_FILTER)                 += af_amerge.o
 OBJS-$(CONFIG_AMIX_FILTER)                   += af_amix.o
 OBJS-$(CONFIG_ANULL_FILTER)                  += af_anull.o
+OBJS-$(CONFIG_ARESAMPLE_FILTER)              += af_aresample.o
+OBJS-$(CONFIG_ASENDCMD_FILTER)               += f_sendcmd.o
+OBJS-$(CONFIG_ASETNSAMPLES_FILTER)           += af_asetnsamples.o
+OBJS-$(CONFIG_ASETPTS_FILTER)                += f_setpts.o
+OBJS-$(CONFIG_ASETTB_FILTER)                 += f_settb.o
+OBJS-$(CONFIG_ASHOWINFO_FILTER)              += af_ashowinfo.o
 OBJS-$(CONFIG_ASPLIT_FILTER)                 += split.o
+OBJS-$(CONFIG_ASTREAMSYNC_FILTER)            += af_astreamsync.o
 OBJS-$(CONFIG_ASYNCTS_FILTER)                += af_asyncts.o
+OBJS-$(CONFIG_ATEMPO_FILTER)                 += af_atempo.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_JOIN_FILTER)                   += af_join.o
+OBJS-$(CONFIG_PAN_FILTER)                    += af_pan.o
 OBJS-$(CONFIG_RESAMPLE_FILTER)               += af_resample.o
+OBJS-$(CONFIG_SILENCEDETECT_FILTER)          += af_silencedetect.o
+OBJS-$(CONFIG_VOLUME_FILTER)                 += af_volume.o
+OBJS-$(CONFIG_VOLUMEDETECT_FILTER)           += af_volumedetect.o
 
+OBJS-$(CONFIG_AEVALSRC_FILTER)               += asrc_aevalsrc.o
 OBJS-$(CONFIG_ANULLSRC_FILTER)               += asrc_anullsrc.o
+OBJS-$(CONFIG_FLITE_FILTER)                  += asrc_flite.o
 
 OBJS-$(CONFIG_ANULLSINK_FILTER)              += asink_anullsink.o
 
+OBJS-$(CONFIG_ASS_FILTER)                    += vf_ass.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_BOXBLUR_FILTER)                += vf_boxblur.o
+OBJS-$(CONFIG_COLORMATRIX_FILTER)            += vf_colormatrix.o
 OBJS-$(CONFIG_COPY_FILTER)                   += vf_copy.o
 OBJS-$(CONFIG_CROP_FILTER)                   += vf_crop.o
 OBJS-$(CONFIG_CROPDETECT_FILTER)             += vf_cropdetect.o
+OBJS-$(CONFIG_DECIMATE_FILTER)               += vf_decimate.o
 OBJS-$(CONFIG_DELOGO_FILTER)                 += vf_delogo.o
+OBJS-$(CONFIG_DESHAKE_FILTER)                += vf_deshake.o
 OBJS-$(CONFIG_DRAWBOX_FILTER)                += vf_drawbox.o
 OBJS-$(CONFIG_DRAWTEXT_FILTER)               += vf_drawtext.o
+OBJS-$(CONFIG_EDGEDETECT_FILTER)             += vf_edgedetect.o
 OBJS-$(CONFIG_FADE_FILTER)                   += vf_fade.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
 OBJS-$(CONFIG_FREI0R_FILTER)                 += vf_frei0r.o
 OBJS-$(CONFIG_GRADFUN_FILTER)                += vf_gradfun.o
 OBJS-$(CONFIG_HFLIP_FILTER)                  += vf_hflip.o
 OBJS-$(CONFIG_HQDN3D_FILTER)                 += vf_hqdn3d.o
+OBJS-$(CONFIG_HUE_FILTER)                    += vf_hue.o
+OBJS-$(CONFIG_IDET_FILTER)                   += vf_idet.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_NULL_FILTER)                   += vf_null.o
@@ -66,28 +120,100 @@
 OBJS-$(CONFIG_OVERLAY_FILTER)                += vf_overlay.o
 OBJS-$(CONFIG_PAD_FILTER)                    += vf_pad.o
 OBJS-$(CONFIG_PIXDESCTEST_FILTER)            += vf_pixdesctest.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_SENDCMD_FILTER)                += f_sendcmd.o
 OBJS-$(CONFIG_SETDAR_FILTER)                 += vf_aspect.o
-OBJS-$(CONFIG_SETPTS_FILTER)                 += vf_setpts.o
+OBJS-$(CONFIG_SETFIELD_FILTER)               += vf_setfield.o
+OBJS-$(CONFIG_SETPTS_FILTER)                 += f_setpts.o
 OBJS-$(CONFIG_SETSAR_FILTER)                 += vf_aspect.o
-OBJS-$(CONFIG_SETTB_FILTER)                  += vf_settb.o
+OBJS-$(CONFIG_SETTB_FILTER)                  += f_settb.o
 OBJS-$(CONFIG_SHOWINFO_FILTER)               += vf_showinfo.o
 OBJS-$(CONFIG_SLICIFY_FILTER)                += vf_slicify.o
+OBJS-$(CONFIG_SMARTBLUR_FILTER)              += vf_smartblur.o
 OBJS-$(CONFIG_SPLIT_FILTER)                  += split.o
+OBJS-$(CONFIG_SUPER2XSAI_FILTER)             += vf_super2xsai.o
+OBJS-$(CONFIG_SWAPUV_FILTER)                 += vf_swapuv.o
+OBJS-$(CONFIG_THUMBNAIL_FILTER)              += vf_thumbnail.o
+OBJS-$(CONFIG_TILE_FILTER)                   += vf_tile.o
+OBJS-$(CONFIG_TINTERLACE_FILTER)             += vf_tinterlace.o
 OBJS-$(CONFIG_TRANSPOSE_FILTER)              += vf_transpose.o
 OBJS-$(CONFIG_UNSHARP_FILTER)                += vf_unsharp.o
 OBJS-$(CONFIG_VFLIP_FILTER)                  += vf_vflip.o
 OBJS-$(CONFIG_YADIF_FILTER)                  += vf_yadif.o
 
-OBJS-$(CONFIG_COLOR_FILTER)                  += vsrc_color.o
+OBJS-$(CONFIG_CELLAUTO_FILTER)               += vsrc_cellauto.o
+OBJS-$(CONFIG_COLOR_FILTER)                  += vsrc_testsrc.o
 OBJS-$(CONFIG_FREI0R_SRC_FILTER)             += vf_frei0r.o
-OBJS-$(CONFIG_MOVIE_FILTER)                  += vsrc_movie.o
-OBJS-$(CONFIG_NULLSRC_FILTER)                += vsrc_nullsrc.o
+OBJS-$(CONFIG_LIFE_FILTER)                   += vsrc_life.o
+OBJS-$(CONFIG_MANDELBROT_FILTER)             += vsrc_mandelbrot.o
+OBJS-$(CONFIG_MPTESTSRC_FILTER)              += vsrc_mptestsrc.o
+OBJS-$(CONFIG_NULLSRC_FILTER)                += vsrc_testsrc.o
 OBJS-$(CONFIG_RGBTESTSRC_FILTER)             += vsrc_testsrc.o
+OBJS-$(CONFIG_SMPTEBARS_FILTER)              += vsrc_testsrc.o
 OBJS-$(CONFIG_TESTSRC_FILTER)                += vsrc_testsrc.o
 
 OBJS-$(CONFIG_NULLSINK_FILTER)               += vsink_nullsink.o
 
+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_field.o
+OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_fil.o
+#OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_filmdint.o
+OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_fixpts.o
+OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_fspp.o
+OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_geq.o
+OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_harddup.o
+OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_hqdn3d.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_palette.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_rectangle.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_tile.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/vf_yuvcsp.o
+OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_yvu9.o
+OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/pullup.o
+
+# multimedia filters
+OBJS-$(CONFIG_CONCAT_FILTER)                 += avf_concat.o
+OBJS-$(CONFIG_SHOWSPECTRUM_FILTER)           += avf_showspectrum.o
+OBJS-$(CONFIG_SHOWWAVES_FILTER)              += avf_showwaves.o
+
+# multimedia sources
+OBJS-$(CONFIG_AMOVIE_FILTER)                 += src_movie.o
+OBJS-$(CONFIG_MOVIE_FILTER)                  += src_movie.o
+
 TOOLS     = graph2dot
-TESTPROGS = filtfmts
+TESTPROGS = drawutils filtfmts formats
+
+clean::
+	$(RM) $(CLEANSUFFIXES:%=libavfilter/libmpcodecs/%)
diff --git a/libavfilter/af_aconvert.c b/libavfilter/af_aconvert.c
new file mode 100644
index 0000000..6dd8452
--- /dev/null
+++ b/libavfilter/af_aconvert.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2010 S.N. Hemanth Meenakshisundaram <smeenaks@ucsd.edu>
+ * Copyright (c) 2011 Stefano Sabatini
+ * Copyright (c) 2011 Mina Nagy Zaki
+ *
+ * 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
+ * sample format and channel layout conversion audio filter
+ */
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/avstring.h"
+#include "libswresample/swresample.h"
+#include "avfilter.h"
+#include "audio.h"
+#include "internal.h"
+
+typedef struct {
+    enum AVSampleFormat  out_sample_fmt;
+    int64_t              out_chlayout;
+    struct SwrContext *swr;
+} AConvertContext;
+
+static av_cold int init(AVFilterContext *ctx, const char *args0)
+{
+    AConvertContext *aconvert = ctx->priv;
+    char *arg, *ptr = NULL;
+    int ret = 0;
+    char *args = av_strdup(args0);
+
+    aconvert->out_sample_fmt  = AV_SAMPLE_FMT_NONE;
+    aconvert->out_chlayout    = 0;
+
+    if ((arg = av_strtok(args, ":", &ptr)) && strcmp(arg, "auto")) {
+        if ((ret = ff_parse_sample_format(&aconvert->out_sample_fmt, arg, ctx)) < 0)
+            goto end;
+    }
+    if ((arg = av_strtok(NULL, ":", &ptr)) && strcmp(arg, "auto")) {
+        if ((ret = ff_parse_channel_layout(&aconvert->out_chlayout, arg, ctx)) < 0)
+            goto end;
+    }
+
+end:
+    av_freep(&args);
+    return ret;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    AConvertContext *aconvert = ctx->priv;
+    swr_free(&aconvert->swr);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterFormats *formats = NULL;
+    AConvertContext *aconvert = ctx->priv;
+    AVFilterLink *inlink  = ctx->inputs[0];
+    AVFilterLink *outlink = ctx->outputs[0];
+    AVFilterChannelLayouts *layouts;
+
+    ff_formats_ref(ff_all_formats(AVMEDIA_TYPE_AUDIO),
+                         &inlink->out_formats);
+    if (aconvert->out_sample_fmt != AV_SAMPLE_FMT_NONE) {
+        formats = NULL;
+        ff_add_format(&formats, aconvert->out_sample_fmt);
+        ff_formats_ref(formats, &outlink->in_formats);
+    } else
+        ff_formats_ref(ff_all_formats(AVMEDIA_TYPE_AUDIO),
+                             &outlink->in_formats);
+
+    ff_channel_layouts_ref(ff_all_channel_layouts(),
+                         &inlink->out_channel_layouts);
+    if (aconvert->out_chlayout != 0) {
+        layouts = NULL;
+        ff_add_channel_layout(&layouts, aconvert->out_chlayout);
+        ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
+    } else
+        ff_channel_layouts_ref(ff_all_channel_layouts(),
+                             &outlink->in_channel_layouts);
+
+    return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    int ret;
+    AVFilterContext *ctx = outlink->src;
+    AVFilterLink *inlink = ctx->inputs[0];
+    AConvertContext *aconvert = ctx->priv;
+    char buf1[64], buf2[64];
+
+    /* if not specified in args, use the format and layout of the output */
+    if (aconvert->out_sample_fmt == AV_SAMPLE_FMT_NONE)
+        aconvert->out_sample_fmt = outlink->format;
+    if (aconvert->out_chlayout   == 0)
+        aconvert->out_chlayout   = outlink->channel_layout;
+
+    aconvert->swr = swr_alloc_set_opts(aconvert->swr,
+                                       aconvert->out_chlayout, aconvert->out_sample_fmt, inlink->sample_rate,
+                                       inlink->channel_layout, inlink->format,           inlink->sample_rate,
+                                       0, ctx);
+    if (!aconvert->swr)
+        return AVERROR(ENOMEM);
+    ret = swr_init(aconvert->swr);
+    if (ret < 0)
+        return ret;
+
+    av_get_channel_layout_string(buf1, sizeof(buf1),
+                                 -1, inlink ->channel_layout);
+    av_get_channel_layout_string(buf2, sizeof(buf2),
+                                 -1, outlink->channel_layout);
+    av_log(ctx, AV_LOG_VERBOSE,
+           "fmt:%s cl:%s -> fmt:%s cl:%s\n",
+           av_get_sample_fmt_name(inlink ->format), buf1,
+           av_get_sample_fmt_name(outlink->format), buf2);
+
+    return 0;
+}
+
+static int  filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
+{
+    AConvertContext *aconvert = inlink->dst->priv;
+    const int n = insamplesref->audio->nb_samples;
+    AVFilterLink *const outlink = inlink->dst->outputs[0];
+    AVFilterBufferRef *outsamplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n);
+    int ret;
+
+    swr_convert(aconvert->swr, outsamplesref->data, n,
+                        (void *)insamplesref->data, n);
+
+    avfilter_copy_buffer_ref_props(outsamplesref, insamplesref);
+    outsamplesref->audio->channel_layout = outlink->channel_layout;
+
+    ret = ff_filter_samples(outlink, outsamplesref);
+    avfilter_unref_buffer(insamplesref);
+    return ret;
+}
+
+AVFilter avfilter_af_aconvert = {
+    .name          = "aconvert",
+    .description   = NULL_IF_CONFIG_SMALL("Convert the input audio to sample_fmt:channel_layout."),
+    .priv_size     = sizeof(AConvertContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+
+    .inputs    = (const AVFilterPad[]) {{ .name      = "default",
+                                    .type            = AVMEDIA_TYPE_AUDIO,
+                                    .filter_samples  = filter_samples,
+                                    .min_perms       = AV_PERM_READ, },
+                                  { .name = NULL}},
+    .outputs   = (const AVFilterPad[]) {{ .name      = "default",
+                                    .type            = AVMEDIA_TYPE_AUDIO,
+                                    .config_props    = config_output, },
+                                  { .name = NULL}},
+};
diff --git a/libavfilter/af_aformat.c b/libavfilter/af_aformat.c
index 77c16be..79e0db2 100644
--- a/libavfilter/af_aformat.c
+++ b/libavfilter/af_aformat.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2011 Mina Nagy Zaki
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -47,19 +47,15 @@
 
 #define OFFSET(x) offsetof(AFormatContext, x)
 #define A AV_OPT_FLAG_AUDIO_PARAM
-static const AVOption options[] = {
-    { "sample_fmts",     "A comma-separated list of sample formats.",  OFFSET(formats_str),         AV_OPT_TYPE_STRING, .flags = A },
-    { "sample_rates",    "A comma-separated list of sample rates.",    OFFSET(sample_rates_str),    AV_OPT_TYPE_STRING, .flags = A },
-    { "channel_layouts", "A comma-separated list of channel layouts.", OFFSET(channel_layouts_str), AV_OPT_TYPE_STRING, .flags = A },
+#define F AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption aformat_options[] = {
+    { "sample_fmts",     "A comma-separated list of sample formats.",  OFFSET(formats_str),         AV_OPT_TYPE_STRING, .flags = A|F },
+    { "sample_rates",    "A comma-separated list of sample rates.",    OFFSET(sample_rates_str),    AV_OPT_TYPE_STRING, .flags = A|F },
+    { "channel_layouts", "A comma-separated list of channel layouts.", OFFSET(channel_layouts_str), AV_OPT_TYPE_STRING, .flags = A|F },
     { NULL },
 };
 
-static const AVClass aformat_class = {
-    .class_name = "aformat filter",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+AVFILTER_DEFINE_CLASS(aformat);
 
 #define PARSE_FORMATS(str, type, list, add_to_list, get_fmt, none, desc)    \
 do {                                                                        \
@@ -100,10 +96,8 @@
     s->class = &aformat_class;
     av_opt_set_defaults(s);
 
-    if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", args);
+    if ((ret = av_set_options_string(s, args, "=", ":")) < 0)
         return ret;
-    }
 
     PARSE_FORMATS(s->formats_str, enum AVSampleFormat, s->formats,
                   ff_add_format, av_get_sample_fmt, AV_SAMPLE_FMT_NONE, "sample format");
@@ -157,4 +151,5 @@
 
     .inputs        = avfilter_af_aformat_inputs,
     .outputs       = avfilter_af_aformat_outputs,
+    .priv_class    = &aformat_class,
 };
diff --git a/libavfilter/af_amerge.c b/libavfilter/af_amerge.c
new file mode 100644
index 0000000..77ea297
--- /dev/null
+++ b/libavfilter/af_amerge.c
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2011 Nicolas George <nicolas.george@normalesup.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
+ * Audio merging filter
+ */
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+#include "libavutil/opt.h"
+#include "libswresample/swresample.h" // only for SWR_CH_MAX
+#include "avfilter.h"
+#include "audio.h"
+#include "bufferqueue.h"
+#include "internal.h"
+
+typedef struct {
+    const AVClass *class;
+    int nb_inputs;
+    int route[SWR_CH_MAX]; /**< channels routing, see copy_samples */
+    int bps;
+    struct amerge_input {
+        struct FFBufQueue queue;
+        int nb_ch;         /**< number of channels for the input */
+        int nb_samples;
+        int pos;
+    } *in;
+} AMergeContext;
+
+#define OFFSET(x) offsetof(AMergeContext, x)
+#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption amerge_options[] = {
+    { "inputs", "specify the number of inputs", OFFSET(nb_inputs),
+      AV_OPT_TYPE_INT, { .i64 = 2 }, 2, SWR_CH_MAX, FLAGS },
+    {0}
+};
+
+AVFILTER_DEFINE_CLASS(amerge);
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    AMergeContext *am = ctx->priv;
+    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);
+    }
+    av_freep(&am->in);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AMergeContext *am = ctx->priv;
+    int64_t inlayout[SWR_CH_MAX], outlayout = 0;
+    AVFilterFormats *formats;
+    AVFilterChannelLayouts *layouts;
+    int i, overlap = 0, nb_ch = 0;
+
+    for (i = 0; i < am->nb_inputs; i++) {
+        if (!ctx->inputs[i]->in_channel_layouts ||
+            !ctx->inputs[i]->in_channel_layouts->nb_channel_layouts) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "No channel layout for input %d\n", i + 1);
+            return AVERROR(EINVAL);
+        }
+        inlayout[i] = ctx->inputs[i]->in_channel_layouts->channel_layouts[0];
+        if (ctx->inputs[i]->in_channel_layouts->nb_channel_layouts > 1) {
+            char buf[256];
+            av_get_channel_layout_string(buf, sizeof(buf), 0, inlayout[i]);
+            av_log(ctx, AV_LOG_INFO, "Using \"%s\" for input %d\n", buf, i + 1);
+        }
+        am->in[i].nb_ch = av_get_channel_layout_nb_channels(inlayout[i]);
+        if (outlayout & inlayout[i])
+            overlap++;
+        outlayout |= inlayout[i];
+        nb_ch += am->in[i].nb_ch;
+    }
+    if (nb_ch > SWR_CH_MAX) {
+        av_log(ctx, AV_LOG_ERROR, "Too many channels (max %d)\n", SWR_CH_MAX);
+        return AVERROR(EINVAL);
+    }
+    if (overlap) {
+        av_log(ctx, AV_LOG_WARNING,
+               "Input channel layouts overlap: "
+               "output layout will be determined by the number of distinct input channels\n");
+        for (i = 0; i < nb_ch; i++)
+            am->route[i] = i;
+        outlayout = av_get_default_channel_layout(nb_ch);
+        if (!outlayout)
+            outlayout = ((int64_t)1 << nb_ch) - 1;
+    } else {
+        int *route[SWR_CH_MAX];
+        int c, out_ch_number = 0;
+
+        route[0] = am->route;
+        for (i = 1; i < am->nb_inputs; i++)
+            route[i] = route[i - 1] + am->in[i - 1].nb_ch;
+        for (c = 0; c < 64; c++)
+            for (i = 0; i < am->nb_inputs; i++)
+                if ((inlayout[i] >> c) & 1)
+                    *(route[i]++) = out_ch_number++;
+    }
+    formats = ff_make_format_list(ff_packed_sample_fmts_array);
+    ff_set_common_formats(ctx, formats);
+    for (i = 0; i < am->nb_inputs; i++) {
+        layouts = NULL;
+        ff_add_channel_layout(&layouts, inlayout[i]);
+        ff_channel_layouts_ref(layouts, &ctx->inputs[i]->out_channel_layouts);
+    }
+    layouts = NULL;
+    ff_add_channel_layout(&layouts, outlayout);
+    ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts);
+    ff_set_common_samplerates(ctx, ff_all_samplerates());
+    return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    AMergeContext *am = ctx->priv;
+    AVBPrint bp;
+    int i;
+
+    for (i = 1; i < am->nb_inputs; i++) {
+        if (ctx->inputs[i]->sample_rate != ctx->inputs[0]->sample_rate) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Inputs must have the same sample rate "
+                   "%d for in%d vs %d\n",
+                   ctx->inputs[i]->sample_rate, i, ctx->inputs[0]->sample_rate);
+            return AVERROR(EINVAL);
+        }
+    }
+    am->bps = av_get_bytes_per_sample(ctx->outputs[0]->format);
+    outlink->sample_rate = ctx->inputs[0]->sample_rate;
+    outlink->time_base   = ctx->inputs[0]->time_base;
+
+    av_bprint_init(&bp, 0, 1);
+    for (i = 0; i < am->nb_inputs; i++) {
+        av_bprintf(&bp, "%sin%d:", i ? " + " : "", i);
+        av_bprint_channel_layout(&bp, -1, ctx->inputs[i]->channel_layout);
+    }
+    av_bprintf(&bp, " -> out:");
+    av_bprint_channel_layout(&bp, -1, ctx->outputs[0]->channel_layout);
+    av_log(ctx, AV_LOG_VERBOSE, "%s\n", bp.str);
+
+    return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    AMergeContext *am = ctx->priv;
+    int i, ret;
+
+    for (i = 0; i < am->nb_inputs; i++)
+        if (!am->in[i].nb_samples)
+            if ((ret = ff_request_frame(ctx->inputs[i])) < 0)
+                return ret;
+    return 0;
+}
+
+/**
+ * Copy samples from several input streams to one output stream.
+ * @param nb_inputs number of inputs
+ * @param in        inputs; used only for the nb_ch field;
+ * @param route     routing values;
+ *                  input channel i goes to output channel route[i];
+ *                  i <  in[0].nb_ch are the channels from the first output;
+ *                  i >= in[0].nb_ch are the channels from the second output
+ * @param ins       pointer to the samples of each inputs, in packed format;
+ *                  will be left at the end of the copied samples
+ * @param outs      pointer to the samples of the output, in packet format;
+ *                  must point to a buffer big enough;
+ *                  will be left at the end of the copied samples
+ * @param ns        number of samples to copy
+ * @param bps       bytes per sample
+ */
+static inline void copy_samples(int nb_inputs, struct amerge_input in[],
+                                int *route, uint8_t *ins[],
+                                uint8_t **outs, int ns, int bps)
+{
+    int *route_cur;
+    int i, c, nb_ch = 0;
+
+    for (i = 0; i < nb_inputs; i++)
+        nb_ch += in[i].nb_ch;
+    while (ns--) {
+        route_cur = route;
+        for (i = 0; i < nb_inputs; i++) {
+            for (c = 0; c < in[i].nb_ch; c++) {
+                memcpy((*outs) + bps * *(route_cur++), ins[i], bps);
+                ins[i] += bps;
+            }
+        }
+        *outs += nb_ch * bps;
+    }
+}
+
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AMergeContext *am = ctx->priv;
+    AVFilterLink *const outlink = ctx->outputs[0];
+    int input_number;
+    int nb_samples, ns, i;
+    AVFilterBufferRef *outbuf, *inbuf[SWR_CH_MAX];
+    uint8_t *ins[SWR_CH_MAX], *outs;
+
+    for (input_number = 0; input_number < am->nb_inputs; input_number++)
+        if (inlink == ctx->inputs[input_number])
+            break;
+    av_assert1(input_number < am->nb_inputs);
+    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;
+    for (i = 1; i < am->nb_inputs; i++)
+        nb_samples = FFMIN(nb_samples, am->in[i].nb_samples);
+    if (!nb_samples)
+        return 0;
+
+    outbuf = ff_get_audio_buffer(ctx->outputs[0], AV_PERM_WRITE, nb_samples);
+    outs = outbuf->data[0];
+    for (i = 0; i < am->nb_inputs; i++) {
+        inbuf[i] = ff_bufqueue_peek(&am->in[i].queue, 0);
+        ins[i] = inbuf[i]->data[0] +
+                 am->in[i].pos * am->in[i].nb_ch * am->bps;
+    }
+    avfilter_copy_buffer_ref_props(outbuf, inbuf[0]);
+    outbuf->pts = inbuf[0]->pts == AV_NOPTS_VALUE ? AV_NOPTS_VALUE :
+                  inbuf[0]->pts +
+                  av_rescale_q(am->in[0].pos,
+                               (AVRational){ 1, ctx->inputs[0]->sample_rate },
+                               ctx->outputs[0]->time_base);
+
+    outbuf->audio->nb_samples     = nb_samples;
+    outbuf->audio->channel_layout = outlink->channel_layout;
+
+    while (nb_samples) {
+        ns = nb_samples;
+        for (i = 0; i < am->nb_inputs; i++)
+            ns = FFMIN(ns, inbuf[i]->audio->nb_samples - am->in[i].pos);
+        /* Unroll the most common sample formats: speed +~350% for the loop,
+           +~13% overall (including two common decoders) */
+        switch (am->bps) {
+            case 1:
+                copy_samples(am->nb_inputs, am->in, am->route, ins, &outs, ns, 1);
+                break;
+            case 2:
+                copy_samples(am->nb_inputs, am->in, am->route, ins, &outs, ns, 2);
+                break;
+            case 4:
+                copy_samples(am->nb_inputs, am->in, am->route, ins, &outs, ns, 4);
+                break;
+            default:
+                copy_samples(am->nb_inputs, am->in, am->route, ins, &outs, ns, am->bps);
+                break;
+        }
+
+        nb_samples -= ns;
+        for (i = 0; i < am->nb_inputs; i++) {
+            am->in[i].nb_samples -= ns;
+            am->in[i].pos += ns;
+            if (am->in[i].pos == inbuf[i]->audio->nb_samples) {
+                am->in[i].pos = 0;
+                avfilter_unref_buffer(inbuf[i]);
+                ff_bufqueue_get(&am->in[i].queue);
+                inbuf[i] = ff_bufqueue_peek(&am->in[i].queue, 0);
+                ins[i] = inbuf[i] ? inbuf[i]->data[0] : NULL;
+            }
+        }
+    }
+    return ff_filter_samples(ctx->outputs[0], outbuf);
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    AMergeContext *am = ctx->priv;
+    int ret, i;
+
+    am->class = &amerge_class;
+    av_opt_set_defaults(am);
+    ret = av_set_options_string(am, args, "=", ":");
+    if (ret < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Error parsing options: '%s'\n", args);
+        return ret;
+    }
+    am->in = av_calloc(am->nb_inputs, sizeof(*am->in));
+    if (!am->in)
+        return AVERROR(ENOMEM);
+    for (i = 0; i < am->nb_inputs; i++) {
+        char *name = av_asprintf("in%d", i);
+        AVFilterPad pad = {
+            .name             = name,
+            .type             = AVMEDIA_TYPE_AUDIO,
+            .filter_samples   = filter_samples,
+            .min_perms        = AV_PERM_READ | AV_PERM_PRESERVE,
+        };
+        if (!name)
+            return AVERROR(ENOMEM);
+        ff_insert_inpad(ctx, i, &pad);
+    }
+    return 0;
+}
+
+AVFilter avfilter_af_amerge = {
+    .name          = "amerge",
+    .description   = NULL_IF_CONFIG_SMALL("Merge two audio streams into "
+                                          "a single multi-channel stream."),
+    .priv_size     = sizeof(AMergeContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+
+    .inputs    = (const AVFilterPad[]) { { .name = NULL } },
+    .outputs   = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_AUDIO,
+          .config_props     = config_output,
+          .request_frame    = request_frame, },
+        { .name = NULL }
+    },
+    .priv_class = &amerge_class,
+};
diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c
index dde9595..a93addd 100644
--- a/libavfilter/af_amix.c
+++ b/libavfilter/af_amix.c
@@ -174,27 +174,22 @@
 
 #define OFFSET(x) offsetof(MixContext, x)
 #define A AV_OPT_FLAG_AUDIO_PARAM
-static const AVOption options[] = {
+#define F AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption amix_options[] = {
     { "inputs", "Number of inputs.",
-            OFFSET(nb_inputs), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, 32, A },
+            OFFSET(nb_inputs), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, 32, A|F },
     { "duration", "How to determine the end-of-stream.",
-            OFFSET(duration_mode), AV_OPT_TYPE_INT, { .i64 = DURATION_LONGEST }, 0,  2, A, "duration" },
-        { "longest",  "Duration of longest input.",  0, AV_OPT_TYPE_CONST, { .i64 = DURATION_LONGEST  }, INT_MIN, INT_MAX, A, "duration" },
-        { "shortest", "Duration of shortest input.", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_SHORTEST }, INT_MIN, INT_MAX, A, "duration" },
-        { "first",    "Duration of first input.",    0, AV_OPT_TYPE_CONST, { .i64 = DURATION_FIRST    }, INT_MIN, INT_MAX, A, "duration" },
+            OFFSET(duration_mode), AV_OPT_TYPE_INT, { .i64 = DURATION_LONGEST }, 0,  2, A|F, "duration" },
+        { "longest",  "Duration of longest input.",  0, AV_OPT_TYPE_CONST, { .i64 = DURATION_LONGEST  }, INT_MIN, INT_MAX, A|F, "duration" },
+        { "shortest", "Duration of shortest input.", 0, AV_OPT_TYPE_CONST, { .i64 = DURATION_SHORTEST }, INT_MIN, INT_MAX, A|F, "duration" },
+        { "first",    "Duration of first input.",    0, AV_OPT_TYPE_CONST, { .i64 = DURATION_FIRST    }, INT_MIN, INT_MAX, A|F, "duration" },
     { "dropout_transition", "Transition time, in seconds, for volume "
                             "renormalization when an input stream ends.",
-            OFFSET(dropout_transition), AV_OPT_TYPE_FLOAT, { .dbl = 2.0 }, 0, INT_MAX, A },
+            OFFSET(dropout_transition), AV_OPT_TYPE_FLOAT, { .dbl = 2.0 }, 0, INT_MAX, A|F },
     { NULL },
 };
 
-static const AVClass amix_class = {
-    .class_name = "amix filter",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
-
+AVFILTER_DEFINE_CLASS(amix);
 
 /**
  * Update the scaling factors to apply to each input during mixing.
@@ -496,10 +491,8 @@
     s->class = &amix_class;
     av_opt_set_defaults(s);
 
-    if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", args);
+    if ((ret = av_set_options_string(s, args, "=", ":")) < 0)
         return ret;
-    }
     av_opt_free(s);
 
     for (i = 0; i < s->nb_inputs; i++) {
@@ -570,4 +563,5 @@
 
     .inputs    = NULL,
     .outputs   = avfilter_af_amix_outputs,
+    .priv_class = &amix_class,
 };
diff --git a/libavfilter/af_anull.c b/libavfilter/af_anull.c
index a791064..40af7b8 100644
--- a/libavfilter/af_anull.c
+++ b/libavfilter/af_anull.c
@@ -1,18 +1,19 @@
 /*
- * This file is part of Libav.
+ * Copyright (c) 2010 S.N. Hemanth Meenakshisundaram <smeenaks@ucsd.edu>
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavfilter/af_aresample.c b/libavfilter/af_aresample.c
new file mode 100644
index 0000000..e400e1f
--- /dev/null
+++ b/libavfilter/af_aresample.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2011 Stefano Sabatini
+ * Copyright (c) 2011 Mina Nagy Zaki
+ *
+ * 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
+ * resampling audio filter
+ */
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
+#include "libavutil/avassert.h"
+#include "libswresample/swresample.h"
+#include "avfilter.h"
+#include "audio.h"
+#include "internal.h"
+
+typedef struct {
+    double ratio;
+    struct SwrContext *swr;
+    int64_t next_pts;
+    int req_fullfilled;
+} AResampleContext;
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    AResampleContext *aresample = ctx->priv;
+    int ret = 0;
+    char *argd = av_strdup(args);
+
+    aresample->next_pts = AV_NOPTS_VALUE;
+    aresample->swr = swr_alloc();
+    if (!aresample->swr) {
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+
+    if (args) {
+        char *ptr=argd, *token;
+
+        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)
+                    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)
+                    goto end;
+            }
+        }
+    }
+end:
+    av_free(argd);
+    return ret;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    AResampleContext *aresample = ctx->priv;
+    swr_free(&aresample->swr);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AResampleContext *aresample = ctx->priv;
+    int out_rate                   = av_get_int(aresample->swr, "osr", NULL);
+    uint64_t out_layout            = av_get_int(aresample->swr, "ocl", NULL);
+    enum AVSampleFormat out_format = av_get_int(aresample->swr, "osf", NULL);
+
+    AVFilterLink *inlink  = ctx->inputs[0];
+    AVFilterLink *outlink = ctx->outputs[0];
+
+    AVFilterFormats        *in_formats      = ff_all_formats(AVMEDIA_TYPE_AUDIO);
+    AVFilterFormats        *out_formats;
+    AVFilterFormats        *in_samplerates  = ff_all_samplerates();
+    AVFilterFormats        *out_samplerates;
+    AVFilterChannelLayouts *in_layouts      = ff_all_channel_layouts();
+    AVFilterChannelLayouts *out_layouts;
+
+    ff_formats_ref  (in_formats,      &inlink->out_formats);
+    ff_formats_ref  (in_samplerates,  &inlink->out_samplerates);
+    ff_channel_layouts_ref(in_layouts,      &inlink->out_channel_layouts);
+
+    if(out_rate > 0) {
+        out_samplerates = ff_make_format_list((int[]){ out_rate, -1 });
+    } else {
+        out_samplerates = ff_all_samplerates();
+    }
+    ff_formats_ref(out_samplerates, &outlink->in_samplerates);
+
+    if(out_format != AV_SAMPLE_FMT_NONE) {
+        out_formats = ff_make_format_list((int[]){ out_format, -1 });
+    } else
+        out_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO);
+    ff_formats_ref(out_formats, &outlink->in_formats);
+
+    if(out_layout) {
+        out_layouts = avfilter_make_format64_list((int64_t[]){ out_layout, -1 });
+    } else
+        out_layouts = ff_all_channel_layouts();
+    ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts);
+
+    return 0;
+}
+
+
+static int config_output(AVFilterLink *outlink)
+{
+    int ret;
+    AVFilterContext *ctx = outlink->src;
+    AVFilterLink *inlink = ctx->inputs[0];
+    AResampleContext *aresample = ctx->priv;
+    int out_rate;
+    uint64_t out_layout;
+    enum AVSampleFormat out_format;
+    char inchl_buf[128], outchl_buf[128];
+
+    aresample->swr = swr_alloc_set_opts(aresample->swr,
+                                        outlink->channel_layout, outlink->format, outlink->sample_rate,
+                                        inlink->channel_layout, inlink->format, inlink->sample_rate,
+                                        0, ctx);
+    if (!aresample->swr)
+        return AVERROR(ENOMEM);
+
+    ret = swr_init(aresample->swr);
+    if (ret < 0)
+        return ret;
+
+    out_rate   = av_get_int(aresample->swr, "osr", NULL);
+    out_layout = av_get_int(aresample->swr, "ocl", NULL);
+    out_format = av_get_int(aresample->swr, "osf", NULL);
+    outlink->time_base = (AVRational) {1, out_rate};
+
+    av_assert0(outlink->sample_rate == out_rate);
+    av_assert0(outlink->channel_layout == out_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_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);
+    return 0;
+}
+
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamplesref)
+{
+    AResampleContext *aresample = inlink->dst->priv;
+    const int n_in  = insamplesref->audio->nb_samples;
+    int n_out       = n_in * aresample->ratio * 2 ;
+    AVFilterLink *const outlink = inlink->dst->outputs[0];
+    AVFilterBufferRef *outsamplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n_out);
+    int ret;
+
+
+    avfilter_copy_buffer_ref_props(outsamplesref, insamplesref);
+    outsamplesref->format                = outlink->format;
+    outsamplesref->audio->channel_layout = outlink->channel_layout;
+    outsamplesref->audio->sample_rate    = outlink->sample_rate;
+
+    if(insamplesref->pts != AV_NOPTS_VALUE) {
+        int64_t inpts = av_rescale(insamplesref->pts, inlink->time_base.num * (int64_t)outlink->sample_rate * inlink->sample_rate, inlink->time_base.den);
+        int64_t outpts= swr_next_pts(aresample->swr, inpts);
+        aresample->next_pts =
+        outsamplesref->pts  = (outpts + inlink->sample_rate/2) / inlink->sample_rate;
+    } else {
+        outsamplesref->pts  = AV_NOPTS_VALUE;
+    }
+
+    n_out = swr_convert(aresample->swr, outsamplesref->extended_data, n_out,
+                                 (void *)insamplesref->extended_data, n_in);
+    if (n_out <= 0) {
+        avfilter_unref_buffer(outsamplesref);
+        avfilter_unref_buffer(insamplesref);
+        return 0;
+    }
+
+    outsamplesref->audio->nb_samples  = n_out;
+
+    ret = ff_filter_samples(outlink, outsamplesref);
+    aresample->req_fullfilled= 1;
+    avfilter_unref_buffer(insamplesref);
+    return ret;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    AResampleContext *aresample = ctx->priv;
+    AVFilterLink *const inlink = outlink->src->inputs[0];
+    int ret;
+
+    aresample->req_fullfilled = 0;
+    do{
+        ret = ff_request_frame(ctx->inputs[0]);
+    }while(!aresample->req_fullfilled && ret>=0);
+
+    if (ret == AVERROR_EOF) {
+        AVFilterBufferRef *outsamplesref;
+        int n_out = 4096;
+
+        outsamplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n_out);
+        if (!outsamplesref)
+            return AVERROR(ENOMEM);
+        n_out = swr_convert(aresample->swr, outsamplesref->extended_data, n_out, 0, 0);
+        if (n_out <= 0) {
+            avfilter_unref_buffer(outsamplesref);
+            return (n_out == 0) ? AVERROR_EOF : n_out;
+        }
+
+        outsamplesref->audio->sample_rate = outlink->sample_rate;
+        outsamplesref->audio->nb_samples  = n_out;
+#if 0
+        outsamplesref->pts = aresample->next_pts;
+        if(aresample->next_pts != AV_NOPTS_VALUE)
+            aresample->next_pts += av_rescale_q(n_out, (AVRational){1 ,outlink->sample_rate}, outlink->time_base);
+#else
+        outsamplesref->pts = (swr_next_pts(aresample->swr, INT64_MIN) + inlink->sample_rate/2) / inlink->sample_rate;
+#endif
+
+        ff_filter_samples(outlink, outsamplesref);
+        return 0;
+    }
+    return ret;
+}
+
+AVFilter avfilter_af_aresample = {
+    .name          = "aresample",
+    .description   = NULL_IF_CONFIG_SMALL("Resample audio data."),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .priv_size     = sizeof(AResampleContext),
+
+    .inputs    = (const AVFilterPad[]) {{ .name      = "default",
+                                    .type            = AVMEDIA_TYPE_AUDIO,
+                                    .filter_samples  = filter_samples,
+                                    .min_perms       = AV_PERM_READ, },
+                                  { .name = NULL}},
+    .outputs   = (const AVFilterPad[]) {{ .name      = "default",
+                                    .config_props    = config_output,
+                                    .request_frame   = request_frame,
+                                    .type            = AVMEDIA_TYPE_AUDIO, },
+                                  { .name = NULL}},
+};
diff --git a/libavfilter/af_asetnsamples.c b/libavfilter/af_asetnsamples.c
new file mode 100644
index 0000000..467af76
--- /dev/null
+++ b/libavfilter/af_asetnsamples.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2012 Andrey Utkin
+ * Copyright (c) 2012 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
+ * Filter that changes number of samples on single output operation
+ */
+
+#include "libavutil/audio_fifo.h"
+#include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
+#include "libavutil/opt.h"
+#include "avfilter.h"
+#include "audio.h"
+#include "internal.h"
+#include "formats.h"
+
+typedef struct {
+    const AVClass *class;
+    int nb_out_samples;  ///< how many samples to output
+    AVAudioFifo *fifo;   ///< samples are queued here
+    int64_t next_out_pts;
+    int req_fullfilled;
+    int pad;
+} ASNSContext;
+
+#define OFFSET(x) offsetof(ASNSContext, x)
+#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption asetnsamples_options[] = {
+{ "pad", "pad last frame with zeros", OFFSET(pad), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS },
+{ "p",   "pad last frame with zeros", OFFSET(pad), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS },
+{ "nb_out_samples", "set the number of per-frame output samples", OFFSET(nb_out_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, FLAGS },
+{ "n",              "set the number of per-frame output samples", OFFSET(nb_out_samples), AV_OPT_TYPE_INT, {.i64=1024}, 1, INT_MAX, FLAGS },
+{ NULL }
+};
+
+AVFILTER_DEFINE_CLASS(asetnsamples);
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    ASNSContext *asns = ctx->priv;
+    int err;
+
+    asns->class = &asetnsamples_class;
+    av_opt_set_defaults(asns);
+
+    if ((err = av_set_options_string(asns, args, "=", ":")) < 0)
+        return err;
+
+    asns->next_out_pts = AV_NOPTS_VALUE;
+    av_log(ctx, AV_LOG_VERBOSE, "nb_out_samples:%d pad:%d\n", asns->nb_out_samples, asns->pad);
+
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    ASNSContext *asns = ctx->priv;
+    av_audio_fifo_free(asns->fifo);
+}
+
+static int config_props_output(AVFilterLink *outlink)
+{
+    ASNSContext *asns = outlink->src->priv;
+    int nb_channels = av_get_channel_layout_nb_channels(outlink->channel_layout);
+
+    asns->fifo = av_audio_fifo_alloc(outlink->format, nb_channels, asns->nb_out_samples);
+    if (!asns->fifo)
+        return AVERROR(ENOMEM);
+
+    return 0;
+}
+
+static int push_samples(AVFilterLink *outlink)
+{
+    ASNSContext *asns = outlink->src->priv;
+    AVFilterBufferRef *outsamples = NULL;
+    int nb_out_samples, nb_pad_samples;
+
+    if (asns->pad) {
+        nb_out_samples = av_audio_fifo_size(asns->fifo) ? asns->nb_out_samples : 0;
+        nb_pad_samples = nb_out_samples - FFMIN(nb_out_samples, av_audio_fifo_size(asns->fifo));
+    } else {
+        nb_out_samples = FFMIN(asns->nb_out_samples, av_audio_fifo_size(asns->fifo));
+        nb_pad_samples = 0;
+    }
+
+    if (!nb_out_samples)
+        return 0;
+
+    outsamples = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_out_samples);
+    av_assert0(outsamples);
+
+    av_audio_fifo_read(asns->fifo,
+                       (void **)outsamples->extended_data, nb_out_samples);
+
+    if (nb_pad_samples)
+        av_samples_set_silence(outsamples->extended_data, nb_out_samples - nb_pad_samples,
+                               nb_pad_samples, av_get_channel_layout_nb_channels(outlink->channel_layout),
+                               outlink->format);
+    outsamples->audio->nb_samples     = nb_out_samples;
+    outsamples->audio->channel_layout = outlink->channel_layout;
+    outsamples->audio->sample_rate    = outlink->sample_rate;
+    outsamples->pts = asns->next_out_pts;
+
+    if (asns->next_out_pts != AV_NOPTS_VALUE)
+        asns->next_out_pts += nb_out_samples;
+
+    ff_filter_samples(outlink, outsamples);
+    asns->req_fullfilled = 1;
+    return nb_out_samples;
+}
+
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
+{
+    AVFilterContext *ctx = inlink->dst;
+    ASNSContext *asns = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
+    int ret;
+    int nb_samples = insamples->audio->nb_samples;
+
+    if (av_audio_fifo_space(asns->fifo) < nb_samples) {
+        av_log(ctx, AV_LOG_DEBUG, "No space for %d samples, stretching audio fifo\n", nb_samples);
+        ret = av_audio_fifo_realloc(asns->fifo, av_audio_fifo_size(asns->fifo) + nb_samples);
+        if (ret < 0) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Stretching audio fifo failed, discarded %d samples\n", nb_samples);
+            return -1;
+        }
+    }
+    av_audio_fifo_write(asns->fifo, (void **)insamples->extended_data, nb_samples);
+    if (asns->next_out_pts == AV_NOPTS_VALUE)
+        asns->next_out_pts = insamples->pts;
+    avfilter_unref_buffer(insamples);
+
+    while (av_audio_fifo_size(asns->fifo) >= asns->nb_out_samples)
+        push_samples(outlink);
+    return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    ASNSContext *asns = outlink->src->priv;
+    AVFilterLink *inlink = outlink->src->inputs[0];
+    int ret;
+
+    asns->req_fullfilled = 0;
+    do {
+        ret = ff_request_frame(inlink);
+    } while (!asns->req_fullfilled && ret >= 0);
+
+    if (ret == AVERROR_EOF)
+        while (push_samples(outlink))
+            ;
+
+    return ret;
+}
+
+AVFilter avfilter_af_asetnsamples = {
+    .name           = "asetnsamples",
+    .description    = NULL_IF_CONFIG_SMALL("Set the number of samples for each output audio frames."),
+    .priv_size      = sizeof(ASNSContext),
+    .init           = init,
+    .uninit         = uninit,
+
+    .inputs  = (const AVFilterPad[]) {
+        {
+            .name           = "default",
+            .type           = AVMEDIA_TYPE_AUDIO,
+            .filter_samples = filter_samples,
+            .min_perms      = AV_PERM_READ|AV_PERM_WRITE
+        },
+        { .name = NULL }
+    },
+
+    .outputs = (const AVFilterPad[]) {
+        {
+            .name           = "default",
+            .type           = AVMEDIA_TYPE_AUDIO,
+            .request_frame  = request_frame,
+            .config_props   = config_props_output,
+        },
+        { .name = NULL }
+    },
+    .priv_class = &asetnsamples_class,
+};
diff --git a/libavfilter/af_ashowinfo.c b/libavfilter/af_ashowinfo.c
new file mode 100644
index 0000000..25a5e2c
--- /dev/null
+++ b/libavfilter/af_ashowinfo.c
@@ -0,0 +1,106 @@
+/*
+ * 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
+ * filter for showing textual audio frame information
+ */
+
+#include "libavutil/adler32.h"
+#include "libavutil/audioconvert.h"
+#include "libavutil/timestamp.h"
+#include "audio.h"
+#include "avfilter.h"
+
+typedef struct {
+    unsigned int frame;
+} ShowInfoContext;
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    ShowInfoContext *showinfo = ctx->priv;
+    showinfo->frame = 0;
+    return 0;
+}
+
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
+{
+    AVFilterContext *ctx = inlink->dst;
+    ShowInfoContext *showinfo = ctx->priv;
+    uint32_t plane_checksum[8] = {0}, checksum = 0;
+    char chlayout_str[128];
+    int plane;
+    int linesize =
+        samplesref->audio->nb_samples *
+        av_get_bytes_per_sample(samplesref->format);
+    if (!av_sample_fmt_is_planar(samplesref->format))
+        linesize *= av_get_channel_layout_nb_channels(samplesref->audio->channel_layout);
+
+    for (plane = 0; plane < 8 && samplesref->data[plane]; plane++) {
+        uint8_t *data = samplesref->data[plane];
+
+        plane_checksum[plane] = av_adler32_update(plane_checksum[plane],
+                                                  data, linesize);
+        checksum = av_adler32_update(checksum, data, linesize);
+    }
+
+    av_get_channel_layout_string(chlayout_str, sizeof(chlayout_str), -1,
+                                 samplesref->audio->channel_layout);
+
+    av_log(ctx, AV_LOG_INFO,
+           "n:%d pts:%s pts_time:%s pos:%"PRId64" "
+           "fmt:%s chlayout:%s nb_samples:%d rate:%d "
+           "checksum:%08X plane_checksum[%08X",
+           showinfo->frame,
+           av_ts2str(samplesref->pts), av_ts2timestr(samplesref->pts, &inlink->time_base),
+           samplesref->pos,
+           av_get_sample_fmt_name(samplesref->format),
+           chlayout_str,
+           samplesref->audio->nb_samples,
+           samplesref->audio->sample_rate,
+           checksum,
+           plane_checksum[0]);
+
+    for (plane = 1; plane < 8 && samplesref->data[plane]; plane++)
+        av_log(ctx, AV_LOG_INFO, " %08X", plane_checksum[plane]);
+    av_log(ctx, AV_LOG_INFO, "]\n");
+
+    showinfo->frame++;
+    return ff_filter_samples(inlink->dst->outputs[0], samplesref);
+}
+
+AVFilter avfilter_af_ashowinfo = {
+    .name        = "ashowinfo",
+    .description = NULL_IF_CONFIG_SMALL("Show textual information for each audio frame."),
+
+    .priv_size = sizeof(ShowInfoContext),
+    .init      = init,
+
+    .inputs    = (const AVFilterPad[]) {{ .name       = "default",
+                                    .type             = AVMEDIA_TYPE_AUDIO,
+                                    .get_audio_buffer = ff_null_get_audio_buffer,
+                                    .filter_samples   = filter_samples,
+                                    .min_perms        = AV_PERM_READ, },
+                                  { .name = NULL}},
+
+    .outputs   = (const AVFilterPad[]) {{ .name       = "default",
+                                    .type             = AVMEDIA_TYPE_AUDIO },
+                                  { .name = NULL}},
+};
diff --git a/libavfilter/af_astreamsync.c b/libavfilter/af_astreamsync.c
new file mode 100644
index 0000000..9768647
--- /dev/null
+++ b/libavfilter/af_astreamsync.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2011 Nicolas George <nicolas.george@normalesup.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
+ * Stream (de)synchronization filter
+ */
+
+#include "libavutil/eval.h"
+#include "avfilter.h"
+#include "audio.h"
+#include "internal.h"
+
+#define QUEUE_SIZE 16
+
+static const char * const var_names[] = {
+    "b1", "b2",
+    "s1", "s2",
+    "t1", "t2",
+    NULL
+};
+
+enum var_name {
+    VAR_B1, VAR_B2,
+    VAR_S1, VAR_S2,
+    VAR_T1, VAR_T2,
+    VAR_NB
+};
+
+typedef struct {
+    AVExpr *expr;
+    double var_values[VAR_NB];
+    struct buf_queue {
+        AVFilterBufferRef *buf[QUEUE_SIZE];
+        unsigned tail, nb;
+        /* buf[tail] is the oldest,
+           buf[(tail + nb) % QUEUE_SIZE] is where the next is added */
+    } queue[2];
+    int req[2];
+    int next_out;
+    int eof; /* bitmask, one bit for each stream */
+} AStreamSyncContext;
+
+static const char *default_expr = "t1-t2";
+
+static av_cold int init(AVFilterContext *ctx, const char *args0)
+{
+    AStreamSyncContext *as = ctx->priv;
+    const char *expr = args0 ? args0 : default_expr;
+    int r, i;
+
+    r = av_expr_parse(&as->expr, expr, var_names,
+                      NULL, NULL, NULL, NULL, 0, ctx);
+    if (r < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Error in expression \"%s\"\n", expr);
+        return r;
+    }
+    for (i = 0; i < 42; i++)
+        av_expr_eval(as->expr, as->var_values, NULL); /* exercize prng */
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    int i;
+    AVFilterFormats *formats, *rates;
+    AVFilterChannelLayouts *layouts;
+
+    for (i = 0; i < 2; i++) {
+        formats = ctx->inputs[i]->in_formats;
+        ff_formats_ref(formats, &ctx->inputs[i]->out_formats);
+        ff_formats_ref(formats, &ctx->outputs[i]->in_formats);
+        rates = ff_all_samplerates();
+        ff_formats_ref(rates, &ctx->inputs[i]->out_samplerates);
+        ff_formats_ref(rates, &ctx->outputs[i]->in_samplerates);
+        layouts = ctx->inputs[i]->in_channel_layouts;
+        ff_channel_layouts_ref(layouts, &ctx->inputs[i]->out_channel_layouts);
+        ff_channel_layouts_ref(layouts, &ctx->outputs[i]->in_channel_layouts);
+    }
+    return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    int id = outlink == ctx->outputs[1];
+
+    outlink->sample_rate = ctx->inputs[id]->sample_rate;
+    outlink->time_base   = ctx->inputs[id]->time_base;
+    return 0;
+}
+
+static int send_out(AVFilterContext *ctx, int out_id)
+{
+    AStreamSyncContext *as = ctx->priv;
+    struct buf_queue *queue = &as->queue[out_id];
+    AVFilterBufferRef *buf = queue->buf[queue->tail];
+    int ret;
+
+    queue->buf[queue->tail] = NULL;
+    as->var_values[VAR_B1 + out_id]++;
+    as->var_values[VAR_S1 + out_id] += buf->audio->nb_samples;
+    if (buf->pts != AV_NOPTS_VALUE)
+        as->var_values[VAR_T1 + out_id] =
+            av_q2d(ctx->outputs[out_id]->time_base) * buf->pts;
+    as->var_values[VAR_T1 + out_id] += buf->audio->nb_samples /
+                                   (double)ctx->inputs[out_id]->sample_rate;
+    ret = ff_filter_samples(ctx->outputs[out_id], buf);
+    queue->nb--;
+    queue->tail = (queue->tail + 1) % QUEUE_SIZE;
+    if (as->req[out_id])
+        as->req[out_id]--;
+    return ret;
+}
+
+static void send_next(AVFilterContext *ctx)
+{
+    AStreamSyncContext *as = ctx->priv;
+    int i;
+
+    while (1) {
+        if (!as->queue[as->next_out].nb)
+            break;
+        send_out(ctx, as->next_out);
+        if (!as->eof)
+            as->next_out = av_expr_eval(as->expr, as->var_values, NULL) >= 0;
+    }
+    for (i = 0; i < 2; i++)
+        if (as->queue[i].nb == QUEUE_SIZE)
+            send_out(ctx, i);
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    AStreamSyncContext *as = ctx->priv;
+    int id = outlink == ctx->outputs[1];
+
+    as->req[id]++;
+    while (as->req[id] && !(as->eof & (1 << id))) {
+        if (as->queue[as->next_out].nb) {
+            send_next(ctx);
+        } else {
+            as->eof |= 1 << as->next_out;
+            ff_request_frame(ctx->inputs[as->next_out]);
+            if (as->eof & (1 << as->next_out))
+                as->next_out = !as->next_out;
+        }
+    }
+    return 0;
+}
+
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AStreamSyncContext *as = ctx->priv;
+    int id = inlink == ctx->inputs[1];
+
+    as->queue[id].buf[(as->queue[id].tail + as->queue[id].nb++) % QUEUE_SIZE] =
+        insamples;
+    as->eof &= ~(1 << id);
+    send_next(ctx);
+    return 0;
+}
+
+AVFilter avfilter_af_astreamsync = {
+    .name          = "astreamsync",
+    .description   = NULL_IF_CONFIG_SMALL("Copy two streams of audio data "
+                                          "in a configurable order."),
+    .priv_size     = sizeof(AStreamSyncContext),
+    .init          = init,
+    .query_formats = query_formats,
+
+    .inputs    = (const AVFilterPad[]) {
+        { .name             = "in1",
+          .type             = AVMEDIA_TYPE_AUDIO,
+          .filter_samples   = filter_samples,
+          .min_perms        = AV_PERM_READ | AV_PERM_PRESERVE, },
+        { .name             = "in2",
+          .type             = AVMEDIA_TYPE_AUDIO,
+          .filter_samples   = filter_samples,
+          .min_perms        = AV_PERM_READ | AV_PERM_PRESERVE, },
+        { .name = NULL }
+    },
+    .outputs   = (const AVFilterPad[]) {
+        { .name             = "out1",
+          .type             = AVMEDIA_TYPE_AUDIO,
+          .config_props     = config_output,
+          .request_frame    = request_frame, },
+        { .name             = "out2",
+          .type             = AVMEDIA_TYPE_AUDIO,
+          .config_props     = config_output,
+          .request_frame    = request_frame, },
+        { .name = NULL }
+    },
+};
diff --git a/libavfilter/af_asyncts.c b/libavfilter/af_asyncts.c
index 94c5452..6288433 100644
--- a/libavfilter/af_asyncts.c
+++ b/libavfilter/af_asyncts.c
@@ -45,34 +45,28 @@
 
 #define OFFSET(x) offsetof(ASyncContext, x)
 #define A AV_OPT_FLAG_AUDIO_PARAM
-static const AVOption options[] = {
-    { "compensate", "Stretch/squeeze the data to make it match the timestamps", OFFSET(resample),      AV_OPT_TYPE_INT,   { .i64 = 0 },   0, 1,       A },
+#define F AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption asyncts_options[] = {
+    { "compensate", "Stretch/squeeze the data to make it match the timestamps", OFFSET(resample),      AV_OPT_TYPE_INT,   { .i64 = 0 },   0, 1,       A|F },
     { "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 },
-    { "max_comp",   "Maximum compensation in samples per second.",              OFFSET(max_comp),      AV_OPT_TYPE_INT,   { .i64 = 500 }, 0, INT_MAX, A },
-    { "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 },
+                    "(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 },
     { NULL },
 };
 
-static const AVClass async_class = {
-    .class_name = "asyncts filter",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+AVFILTER_DEFINE_CLASS(asyncts);
 
 static int init(AVFilterContext *ctx, const char *args)
 {
     ASyncContext *s = ctx->priv;
     int ret;
 
-    s->class = &async_class;
+    s->class = &asyncts_class;
     av_opt_set_defaults(s);
 
-    if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", args);
+    if ((ret = av_set_options_string(s, args, "=", ":")) < 0)
         return ret;
-    }
     av_opt_free(s);
 
     return 0;
@@ -269,4 +263,5 @@
 
     .inputs      = avfilter_af_asyncts_inputs,
     .outputs     = avfilter_af_asyncts_outputs,
+    .priv_class = &asyncts_class,
 };
diff --git a/libavfilter/af_atempo.c b/libavfilter/af_atempo.c
new file mode 100644
index 0000000..c2d1fc1
--- /dev/null
+++ b/libavfilter/af_atempo.c
@@ -0,0 +1,1163 @@
+/*
+ * Copyright (c) 2012 Pavel Koshevoy <pkoshevoy at gmail dot 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
+ * tempo scaling audio filter -- an implementation of WSOLA algorithm
+ *
+ * Based on MIT licensed yaeAudioTempoFilter.h and yaeAudioFragment.h
+ * from Apprentice Video player by Pavel Koshevoy.
+ * https://sourceforge.net/projects/apprenticevideo/
+ *
+ * An explanation of SOLA algorithm is available at
+ * http://www.surina.net/article/time-and-pitch-scaling.html
+ *
+ * WSOLA is very similar to SOLA, only one major difference exists between
+ * these algorithms.  SOLA shifts audio fragments along the output stream,
+ * where as WSOLA shifts audio fragments along the input stream.
+ *
+ * The advantage of WSOLA algorithm is that the overlap region size is
+ * always the same, therefore the blending function is constant and
+ * can be precomputed.
+ */
+
+#include <float.h>
+#include "libavcodec/avfft.h"
+#include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/eval.h"
+#include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
+#include "avfilter.h"
+#include "audio.h"
+#include "internal.h"
+
+/**
+ * A fragment of audio waveform
+ */
+typedef struct {
+    // index of the first sample of this fragment in the overall waveform;
+    // 0: input sample position
+    // 1: output sample position
+    int64_t position[2];
+
+    // original packed multi-channel samples:
+    uint8_t *data;
+
+    // number of samples in this fragment:
+    int nsamples;
+
+    // rDFT transform of the down-mixed mono fragment, used for
+    // fast waveform alignment via correlation in frequency domain:
+    FFTSample *xdat;
+} AudioFragment;
+
+/**
+ * Filter state machine states
+ */
+typedef enum {
+    YAE_LOAD_FRAGMENT,
+    YAE_ADJUST_POSITION,
+    YAE_RELOAD_FRAGMENT,
+    YAE_OUTPUT_OVERLAP_ADD,
+    YAE_FLUSH_OUTPUT,
+} FilterState;
+
+/**
+ * Filter state machine
+ */
+typedef struct {
+    // ring-buffer of input samples, necessary because some times
+    // input fragment position may be adjusted backwards:
+    uint8_t *buffer;
+
+    // ring-buffer maximum capacity, expressed in sample rate time base:
+    int ring;
+
+    // ring-buffer house keeping:
+    int size;
+    int head;
+    int tail;
+
+    // 0: input sample position corresponding to the ring buffer tail
+    // 1: output sample position
+    int64_t position[2];
+
+    // sample format:
+    enum AVSampleFormat format;
+
+    // number of channels:
+    int channels;
+
+    // row of bytes to skip from one sample to next, across multple channels;
+    // stride = (number-of-channels * bits-per-sample-per-channel) / 8
+    int stride;
+
+    // fragment window size, power-of-two integer:
+    int window;
+
+    // Hann window coefficients, for feathering
+    // (blending) the overlapping fragment region:
+    float *hann;
+
+    // tempo scaling factor:
+    double tempo;
+
+    // cumulative alignment drift:
+    int drift;
+
+    // current/previous fragment ring-buffer:
+    AudioFragment frag[2];
+
+    // current fragment index:
+    uint64_t nfrag;
+
+    // current state:
+    FilterState state;
+
+    // for fast correlation calculation in frequency domain:
+    RDFTContext *real_to_complex;
+    RDFTContext *complex_to_real;
+    FFTSample *correlation;
+
+    // for managing AVFilterPad.request_frame and AVFilterPad.filter_samples
+    int request_fulfilled;
+    AVFilterBufferRef *dst_buffer;
+    uint8_t *dst;
+    uint8_t *dst_end;
+    uint64_t nsamples_in;
+    uint64_t nsamples_out;
+} ATempoContext;
+
+/**
+ * Reset filter to initial state, do not deallocate existing local buffers.
+ */
+static void yae_clear(ATempoContext *atempo)
+{
+    atempo->size = 0;
+    atempo->head = 0;
+    atempo->tail = 0;
+
+    atempo->drift = 0;
+    atempo->nfrag = 0;
+    atempo->state = YAE_LOAD_FRAGMENT;
+
+    atempo->position[0] = 0;
+    atempo->position[1] = 0;
+
+    atempo->frag[0].position[0] = 0;
+    atempo->frag[0].position[1] = 0;
+    atempo->frag[0].nsamples    = 0;
+
+    atempo->frag[1].position[0] = 0;
+    atempo->frag[1].position[1] = 0;
+    atempo->frag[1].nsamples    = 0;
+
+    // shift left position of 1st fragment by half a window
+    // so that no re-normalization would be required for
+    // the left half of the 1st fragment:
+    atempo->frag[0].position[0] = -(int64_t)(atempo->window / 2);
+    atempo->frag[0].position[1] = -(int64_t)(atempo->window / 2);
+
+    avfilter_unref_bufferp(&atempo->dst_buffer);
+    atempo->dst     = NULL;
+    atempo->dst_end = NULL;
+
+    atempo->request_fulfilled = 0;
+    atempo->nsamples_in       = 0;
+    atempo->nsamples_out      = 0;
+}
+
+/**
+ * Reset filter to initial state and deallocate all buffers.
+ */
+static void yae_release_buffers(ATempoContext *atempo)
+{
+    yae_clear(atempo);
+
+    av_freep(&atempo->frag[0].data);
+    av_freep(&atempo->frag[1].data);
+    av_freep(&atempo->frag[0].xdat);
+    av_freep(&atempo->frag[1].xdat);
+
+    av_freep(&atempo->buffer);
+    av_freep(&atempo->hann);
+    av_freep(&atempo->correlation);
+
+    av_rdft_end(atempo->real_to_complex);
+    atempo->real_to_complex = NULL;
+
+    av_rdft_end(atempo->complex_to_real);
+    atempo->complex_to_real = NULL;
+}
+
+/* av_realloc is not aligned enough; fortunately, the data does not need to
+ * be preserved */
+#define RE_MALLOC_OR_FAIL(field, field_size)                    \
+    do {                                                        \
+        av_freep(&field);                                       \
+        field = av_malloc(field_size);                          \
+        if (!field) {                                           \
+            yae_release_buffers(atempo);                        \
+            return AVERROR(ENOMEM);                             \
+        }                                                       \
+    } while (0)
+
+/**
+ * Prepare filter for processing audio data of given format,
+ * sample rate and number of channels.
+ */
+static int yae_reset(ATempoContext *atempo,
+                     enum AVSampleFormat format,
+                     int sample_rate,
+                     int channels)
+{
+    const int sample_size = av_get_bytes_per_sample(format);
+    uint32_t nlevels  = 0;
+    uint32_t pot;
+    int i;
+
+    atempo->format   = format;
+    atempo->channels = channels;
+    atempo->stride   = sample_size * channels;
+
+    // pick a segment window size:
+    atempo->window = sample_rate / 24;
+
+    // adjust window size to be a power-of-two integer:
+    nlevels = av_log2(atempo->window);
+    pot = 1 << nlevels;
+    av_assert0(pot <= atempo->window);
+
+    if (pot < atempo->window) {
+        atempo->window = pot * 2;
+        nlevels++;
+    }
+
+    // initialize audio fragment buffers:
+    RE_MALLOC_OR_FAIL(atempo->frag[0].data, atempo->window * atempo->stride);
+    RE_MALLOC_OR_FAIL(atempo->frag[1].data, atempo->window * atempo->stride);
+    RE_MALLOC_OR_FAIL(atempo->frag[0].xdat, atempo->window * sizeof(FFTComplex));
+    RE_MALLOC_OR_FAIL(atempo->frag[1].xdat, atempo->window * sizeof(FFTComplex));
+
+    // initialize rDFT contexts:
+    av_rdft_end(atempo->real_to_complex);
+    atempo->real_to_complex = NULL;
+
+    av_rdft_end(atempo->complex_to_real);
+    atempo->complex_to_real = NULL;
+
+    atempo->real_to_complex = av_rdft_init(nlevels + 1, DFT_R2C);
+    if (!atempo->real_to_complex) {
+        yae_release_buffers(atempo);
+        return AVERROR(ENOMEM);
+    }
+
+    atempo->complex_to_real = av_rdft_init(nlevels + 1, IDFT_C2R);
+    if (!atempo->complex_to_real) {
+        yae_release_buffers(atempo);
+        return AVERROR(ENOMEM);
+    }
+
+    RE_MALLOC_OR_FAIL(atempo->correlation, atempo->window * sizeof(FFTComplex));
+
+    atempo->ring = atempo->window * 3;
+    RE_MALLOC_OR_FAIL(atempo->buffer, atempo->ring * atempo->stride);
+
+    // initialize the Hann window function:
+    RE_MALLOC_OR_FAIL(atempo->hann, atempo->window * sizeof(float));
+
+    for (i = 0; i < atempo->window; i++) {
+        double t = (double)i / (double)(atempo->window - 1);
+        double h = 0.5 * (1.0 - cos(2.0 * M_PI * t));
+        atempo->hann[i] = (float)h;
+    }
+
+    yae_clear(atempo);
+    return 0;
+}
+
+static int yae_set_tempo(AVFilterContext *ctx, const char *arg_tempo)
+{
+    ATempoContext *atempo = ctx->priv;
+    char   *tail = NULL;
+    double tempo = av_strtod(arg_tempo, &tail);
+
+    if (tail && *tail) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid tempo value '%s'\n", arg_tempo);
+        return AVERROR(EINVAL);
+    }
+
+    if (tempo < 0.5 || tempo > 2.0) {
+        av_log(ctx, AV_LOG_ERROR, "Tempo value %f exceeds [0.5, 2.0] range\n",
+               tempo);
+        return AVERROR(EINVAL);
+    }
+
+    atempo->tempo = tempo;
+    return 0;
+}
+
+inline static AudioFragment *yae_curr_frag(ATempoContext *atempo)
+{
+    return &atempo->frag[atempo->nfrag % 2];
+}
+
+inline static AudioFragment *yae_prev_frag(ATempoContext *atempo)
+{
+    return &atempo->frag[(atempo->nfrag + 1) % 2];
+}
+
+/**
+ * A helper macro for initializing complex data buffer with scalar data
+ * of a given type.
+ */
+#define yae_init_xdat(scalar_type, scalar_max)                          \
+    do {                                                                \
+        const uint8_t *src_end = src +                                  \
+            frag->nsamples * atempo->channels * sizeof(scalar_type);    \
+                                                                        \
+        FFTSample *xdat = frag->xdat;                                   \
+        scalar_type tmp;                                                \
+                                                                        \
+        if (atempo->channels == 1) {                                    \
+            for (; src < src_end; xdat++) {                             \
+                tmp = *(const scalar_type *)src;                        \
+                src += sizeof(scalar_type);                             \
+                                                                        \
+                *xdat = (FFTSample)tmp;                                 \
+            }                                                           \
+        } else {                                                        \
+            FFTSample s, max, ti, si;                                   \
+            int i;                                                      \
+                                                                        \
+            for (; src < src_end; xdat++) {                             \
+                tmp = *(const scalar_type *)src;                        \
+                src += sizeof(scalar_type);                             \
+                                                                        \
+                max = (FFTSample)tmp;                                   \
+                s = FFMIN((FFTSample)scalar_max,                        \
+                          (FFTSample)fabsf(max));                       \
+                                                                        \
+                for (i = 1; i < atempo->channels; i++) {                \
+                    tmp = *(const scalar_type *)src;                    \
+                    src += sizeof(scalar_type);                         \
+                                                                        \
+                    ti = (FFTSample)tmp;                                \
+                    si = FFMIN((FFTSample)scalar_max,                   \
+                               (FFTSample)fabsf(ti));                   \
+                                                                        \
+                    if (s < si) {                                       \
+                        s   = si;                                       \
+                        max = ti;                                       \
+                    }                                                   \
+                }                                                       \
+                                                                        \
+                *xdat = max;                                            \
+            }                                                           \
+        }                                                               \
+    } while (0)
+
+/**
+ * Initialize complex data buffer of a given audio fragment
+ * with down-mixed mono data of appropriate scalar type.
+ */
+static void yae_downmix(ATempoContext *atempo, AudioFragment *frag)
+{
+    // shortcuts:
+    const uint8_t *src = frag->data;
+
+    // init complex data buffer used for FFT and Correlation:
+    memset(frag->xdat, 0, sizeof(FFTComplex) * atempo->window);
+
+    if (atempo->format == AV_SAMPLE_FMT_U8) {
+        yae_init_xdat(uint8_t, 127);
+    } else if (atempo->format == AV_SAMPLE_FMT_S16) {
+        yae_init_xdat(int16_t, 32767);
+    } else if (atempo->format == AV_SAMPLE_FMT_S32) {
+        yae_init_xdat(int, 2147483647);
+    } else if (atempo->format == AV_SAMPLE_FMT_FLT) {
+        yae_init_xdat(float, 1);
+    } else if (atempo->format == AV_SAMPLE_FMT_DBL) {
+        yae_init_xdat(double, 1);
+    }
+}
+
+/**
+ * Populate the internal data buffer on as-needed basis.
+ *
+ * @return
+ *   0 if requested data was already available or was successfully loaded,
+ *   AVERROR(EAGAIN) if more input data is required.
+ */
+static int yae_load_data(ATempoContext *atempo,
+                         const uint8_t **src_ref,
+                         const uint8_t *src_end,
+                         int64_t stop_here)
+{
+    // shortcut:
+    const uint8_t *src = *src_ref;
+    const int read_size = stop_here - atempo->position[0];
+
+    if (stop_here <= atempo->position[0]) {
+        return 0;
+    }
+
+    // samples are not expected to be skipped:
+    av_assert0(read_size <= atempo->ring);
+
+    while (atempo->position[0] < stop_here && src < src_end) {
+        int src_samples = (src_end - src) / atempo->stride;
+
+        // load data piece-wise, in order to avoid complicating the logic:
+        int nsamples = FFMIN(read_size, src_samples);
+        int na;
+        int nb;
+
+        nsamples = FFMIN(nsamples, atempo->ring);
+        na = FFMIN(nsamples, atempo->ring - atempo->tail);
+        nb = FFMIN(nsamples - na, atempo->ring);
+
+        if (na) {
+            uint8_t *a = atempo->buffer + atempo->tail * atempo->stride;
+            memcpy(a, src, na * atempo->stride);
+
+            src += na * atempo->stride;
+            atempo->position[0] += na;
+
+            atempo->size = FFMIN(atempo->size + na, atempo->ring);
+            atempo->tail = (atempo->tail + na) % atempo->ring;
+            atempo->head =
+                atempo->size < atempo->ring ?
+                atempo->tail - atempo->size :
+                atempo->tail;
+        }
+
+        if (nb) {
+            uint8_t *b = atempo->buffer;
+            memcpy(b, src, nb * atempo->stride);
+
+            src += nb * atempo->stride;
+            atempo->position[0] += nb;
+
+            atempo->size = FFMIN(atempo->size + nb, atempo->ring);
+            atempo->tail = (atempo->tail + nb) % atempo->ring;
+            atempo->head =
+                atempo->size < atempo->ring ?
+                atempo->tail - atempo->size :
+                atempo->tail;
+        }
+    }
+
+    // pass back the updated source buffer pointer:
+    *src_ref = src;
+
+    // sanity check:
+    av_assert0(atempo->position[0] <= stop_here);
+
+    return atempo->position[0] == stop_here ? 0 : AVERROR(EAGAIN);
+}
+
+/**
+ * Populate current audio fragment data buffer.
+ *
+ * @return
+ *   0 when the fragment is ready,
+ *   AVERROR(EAGAIN) if more input data is required.
+ */
+static int yae_load_frag(ATempoContext *atempo,
+                         const uint8_t **src_ref,
+                         const uint8_t *src_end)
+{
+    // shortcuts:
+    AudioFragment *frag = yae_curr_frag(atempo);
+    uint8_t *dst;
+    int64_t missing, start, zeros;
+    uint32_t nsamples;
+    const uint8_t *a, *b;
+    int i0, i1, n0, n1, na, nb;
+
+    int64_t stop_here = frag->position[0] + atempo->window;
+    if (src_ref && yae_load_data(atempo, src_ref, src_end, stop_here) != 0) {
+        return AVERROR(EAGAIN);
+    }
+
+    // calculate the number of samples we don't have:
+    missing =
+        stop_here > atempo->position[0] ?
+        stop_here - atempo->position[0] : 0;
+
+    nsamples =
+        missing < (int64_t)atempo->window ?
+        (uint32_t)(atempo->window - missing) : 0;
+
+    // setup the output buffer:
+    frag->nsamples = nsamples;
+    dst = frag->data;
+
+    start = atempo->position[0] - atempo->size;
+    zeros = 0;
+
+    if (frag->position[0] < start) {
+        // what we don't have we substitute with zeros:
+        zeros = FFMIN(start - frag->position[0], (int64_t)nsamples);
+        av_assert0(zeros != nsamples);
+
+        memset(dst, 0, zeros * atempo->stride);
+        dst += zeros * atempo->stride;
+    }
+
+    if (zeros == nsamples) {
+        return 0;
+    }
+
+    // get the remaining data from the ring buffer:
+    na = (atempo->head < atempo->tail ?
+          atempo->tail - atempo->head :
+          atempo->ring - atempo->head);
+
+    nb = atempo->head < atempo->tail ? 0 : atempo->tail;
+
+    // sanity check:
+    av_assert0(nsamples <= zeros + na + nb);
+
+    a = atempo->buffer + atempo->head * atempo->stride;
+    b = atempo->buffer;
+
+    i0 = frag->position[0] + zeros - start;
+    i1 = i0 < na ? 0 : i0 - na;
+
+    n0 = i0 < na ? FFMIN(na - i0, (int)(nsamples - zeros)) : 0;
+    n1 = nsamples - zeros - n0;
+
+    if (n0) {
+        memcpy(dst, a + i0 * atempo->stride, n0 * atempo->stride);
+        dst += n0 * atempo->stride;
+    }
+
+    if (n1) {
+        memcpy(dst, b + i1 * atempo->stride, n1 * atempo->stride);
+    }
+
+    return 0;
+}
+
+/**
+ * Prepare for loading next audio fragment.
+ */
+static void yae_advance_to_next_frag(ATempoContext *atempo)
+{
+    const double fragment_step = atempo->tempo * (double)(atempo->window / 2);
+
+    const AudioFragment *prev;
+    AudioFragment       *frag;
+
+    atempo->nfrag++;
+    prev = yae_prev_frag(atempo);
+    frag = yae_curr_frag(atempo);
+
+    frag->position[0] = prev->position[0] + (int64_t)fragment_step;
+    frag->position[1] = prev->position[1] + atempo->window / 2;
+    frag->nsamples    = 0;
+}
+
+/**
+ * Calculate cross-correlation via rDFT.
+ *
+ * Multiply two vectors of complex numbers (result of real_to_complex rDFT)
+ * and transform back via complex_to_real rDFT.
+ */
+static void yae_xcorr_via_rdft(FFTSample *xcorr,
+                               RDFTContext *complex_to_real,
+                               const FFTComplex *xa,
+                               const FFTComplex *xb,
+                               const int window)
+{
+    FFTComplex *xc = (FFTComplex *)xcorr;
+    int i;
+
+    // NOTE: first element requires special care -- Given Y = rDFT(X),
+    // Im(Y[0]) and Im(Y[N/2]) are always zero, therefore av_rdft_calc
+    // stores Re(Y[N/2]) in place of Im(Y[0]).
+
+    xc->re = xa->re * xb->re;
+    xc->im = xa->im * xb->im;
+    xa++;
+    xb++;
+    xc++;
+
+    for (i = 1; i < window; i++, xa++, xb++, xc++) {
+        xc->re = (xa->re * xb->re + xa->im * xb->im);
+        xc->im = (xa->im * xb->re - xa->re * xb->im);
+    }
+
+    // apply inverse rDFT:
+    av_rdft_calc(complex_to_real, xcorr);
+}
+
+/**
+ * Calculate alignment offset for given fragment
+ * relative to the previous fragment.
+ *
+ * @return alignment offset of current fragment relative to previous.
+ */
+static int yae_align(AudioFragment *frag,
+                     const AudioFragment *prev,
+                     const int window,
+                     const int delta_max,
+                     const int drift,
+                     FFTSample *correlation,
+                     RDFTContext *complex_to_real)
+{
+    int       best_offset = -drift;
+    FFTSample best_metric = -FLT_MAX;
+    FFTSample *xcorr;
+
+    int i0;
+    int i1;
+    int i;
+
+    yae_xcorr_via_rdft(correlation,
+                       complex_to_real,
+                       (const FFTComplex *)prev->xdat,
+                       (const FFTComplex *)frag->xdat,
+                       window);
+
+    // identify search window boundaries:
+    i0 = FFMAX(window / 2 - delta_max - drift, 0);
+    i0 = FFMIN(i0, window);
+
+    i1 = FFMIN(window / 2 + delta_max - drift, window - window / 16);
+    i1 = FFMAX(i1, 0);
+
+    // identify cross-correlation peaks within search window:
+    xcorr = correlation + i0;
+
+    for (i = i0; i < i1; i++, xcorr++) {
+        FFTSample metric = *xcorr;
+
+        // normalize:
+        FFTSample drifti = (FFTSample)(drift + i);
+        metric *= drifti * (FFTSample)(i - i0) * (FFTSample)(i1 - i);
+
+        if (metric > best_metric) {
+            best_metric = metric;
+            best_offset = i - window / 2;
+        }
+    }
+
+    return best_offset;
+}
+
+/**
+ * Adjust current fragment position for better alignment
+ * with previous fragment.
+ *
+ * @return alignment correction.
+ */
+static int yae_adjust_position(ATempoContext *atempo)
+{
+    const AudioFragment *prev = yae_prev_frag(atempo);
+    AudioFragment       *frag = yae_curr_frag(atempo);
+
+    const int delta_max  = atempo->window / 2;
+    const int correction = yae_align(frag,
+                                     prev,
+                                     atempo->window,
+                                     delta_max,
+                                     atempo->drift,
+                                     atempo->correlation,
+                                     atempo->complex_to_real);
+
+    if (correction) {
+        // adjust fragment position:
+        frag->position[0] -= correction;
+
+        // clear so that the fragment can be reloaded:
+        frag->nsamples = 0;
+
+        // update cumulative correction drift counter:
+        atempo->drift += correction;
+    }
+
+    return correction;
+}
+
+/**
+ * A helper macro for blending the overlap region of previous
+ * and current audio fragment.
+ */
+#define yae_blend(scalar_type)                                          \
+    do {                                                                \
+        const scalar_type *aaa = (const scalar_type *)a;                \
+        const scalar_type *bbb = (const scalar_type *)b;                \
+                                                                        \
+        scalar_type *out     = (scalar_type *)dst;                      \
+        scalar_type *out_end = (scalar_type *)dst_end;                  \
+        int64_t i;                                                      \
+                                                                        \
+        for (i = 0; i < overlap && out < out_end;                       \
+             i++, atempo->position[1]++, wa++, wb++) {                  \
+            float w0 = *wa;                                             \
+            float w1 = *wb;                                             \
+            int j;                                                      \
+                                                                        \
+            for (j = 0; j < atempo->channels;                           \
+                 j++, aaa++, bbb++, out++) {                            \
+                float t0 = (float)*aaa;                                 \
+                float t1 = (float)*bbb;                                 \
+                                                                        \
+                *out =                                                  \
+                    frag->position[0] + i < 0 ?                         \
+                    *aaa :                                              \
+                    (scalar_type)(t0 * w0 + t1 * w1);                   \
+            }                                                           \
+        }                                                               \
+        dst = (uint8_t *)out;                                           \
+    } while (0)
+
+/**
+ * Blend the overlap region of previous and current audio fragment
+ * and output the results to the given destination buffer.
+ *
+ * @return
+ *   0 if the overlap region was completely stored in the dst buffer,
+ *   AVERROR(EAGAIN) if more destination buffer space is required.
+ */
+static int yae_overlap_add(ATempoContext *atempo,
+                           uint8_t **dst_ref,
+                           uint8_t *dst_end)
+{
+    // shortcuts:
+    const AudioFragment *prev = yae_prev_frag(atempo);
+    const AudioFragment *frag = yae_curr_frag(atempo);
+
+    const int64_t start_here = FFMAX(atempo->position[1],
+                                     frag->position[1]);
+
+    const int64_t stop_here = FFMIN(prev->position[1] + prev->nsamples,
+                                    frag->position[1] + frag->nsamples);
+
+    const int64_t overlap = stop_here - start_here;
+
+    const int64_t ia = start_here - prev->position[1];
+    const int64_t ib = start_here - frag->position[1];
+
+    const float *wa = atempo->hann + ia;
+    const float *wb = atempo->hann + ib;
+
+    const uint8_t *a = prev->data + ia * atempo->stride;
+    const uint8_t *b = frag->data + ib * atempo->stride;
+
+    uint8_t *dst = *dst_ref;
+
+    av_assert0(start_here <= stop_here &&
+               frag->position[1] <= start_here &&
+               overlap <= frag->nsamples);
+
+    if (atempo->format == AV_SAMPLE_FMT_U8) {
+        yae_blend(uint8_t);
+    } else if (atempo->format == AV_SAMPLE_FMT_S16) {
+        yae_blend(int16_t);
+    } else if (atempo->format == AV_SAMPLE_FMT_S32) {
+        yae_blend(int);
+    } else if (atempo->format == AV_SAMPLE_FMT_FLT) {
+        yae_blend(float);
+    } else if (atempo->format == AV_SAMPLE_FMT_DBL) {
+        yae_blend(double);
+    }
+
+    // pass-back the updated destination buffer pointer:
+    *dst_ref = dst;
+
+    return atempo->position[1] == stop_here ? 0 : AVERROR(EAGAIN);
+}
+
+/**
+ * Feed as much data to the filter as it is able to consume
+ * and receive as much processed data in the destination buffer
+ * as it is able to produce or store.
+ */
+static void
+yae_apply(ATempoContext *atempo,
+          const uint8_t **src_ref,
+          const uint8_t *src_end,
+          uint8_t **dst_ref,
+          uint8_t *dst_end)
+{
+    while (1) {
+        if (atempo->state == YAE_LOAD_FRAGMENT) {
+            // load additional data for the current fragment:
+            if (yae_load_frag(atempo, src_ref, src_end) != 0) {
+                break;
+            }
+
+            // down-mix to mono:
+            yae_downmix(atempo, yae_curr_frag(atempo));
+
+            // apply rDFT:
+            av_rdft_calc(atempo->real_to_complex, yae_curr_frag(atempo)->xdat);
+
+            // must load the second fragment before alignment can start:
+            if (!atempo->nfrag) {
+                yae_advance_to_next_frag(atempo);
+                continue;
+            }
+
+            atempo->state = YAE_ADJUST_POSITION;
+        }
+
+        if (atempo->state == YAE_ADJUST_POSITION) {
+            // adjust position for better alignment:
+            if (yae_adjust_position(atempo)) {
+                // reload the fragment at the corrected position, so that the
+                // Hann window blending would not require normalization:
+                atempo->state = YAE_RELOAD_FRAGMENT;
+            } else {
+                atempo->state = YAE_OUTPUT_OVERLAP_ADD;
+            }
+        }
+
+        if (atempo->state == YAE_RELOAD_FRAGMENT) {
+            // load additional data if necessary due to position adjustment:
+            if (yae_load_frag(atempo, src_ref, src_end) != 0) {
+                break;
+            }
+
+            // down-mix to mono:
+            yae_downmix(atempo, yae_curr_frag(atempo));
+
+            // apply rDFT:
+            av_rdft_calc(atempo->real_to_complex, yae_curr_frag(atempo)->xdat);
+
+            atempo->state = YAE_OUTPUT_OVERLAP_ADD;
+        }
+
+        if (atempo->state == YAE_OUTPUT_OVERLAP_ADD) {
+            // overlap-add and output the result:
+            if (yae_overlap_add(atempo, dst_ref, dst_end) != 0) {
+                break;
+            }
+
+            // advance to the next fragment, repeat:
+            yae_advance_to_next_frag(atempo);
+            atempo->state = YAE_LOAD_FRAGMENT;
+        }
+    }
+}
+
+/**
+ * Flush any buffered data from the filter.
+ *
+ * @return
+ *   0 if all data was completely stored in the dst buffer,
+ *   AVERROR(EAGAIN) if more destination buffer space is required.
+ */
+static int yae_flush(ATempoContext *atempo,
+                     uint8_t **dst_ref,
+                     uint8_t *dst_end)
+{
+    AudioFragment *frag = yae_curr_frag(atempo);
+    int64_t overlap_end;
+    int64_t start_here;
+    int64_t stop_here;
+    int64_t offset;
+
+    const uint8_t *src;
+    uint8_t *dst;
+
+    int src_size;
+    int dst_size;
+    int nbytes;
+
+    atempo->state = YAE_FLUSH_OUTPUT;
+
+    if (atempo->position[0] == frag->position[0] + frag->nsamples &&
+        atempo->position[1] == frag->position[1] + frag->nsamples) {
+        // the current fragment is already flushed:
+        return 0;
+    }
+
+    if (frag->position[0] + frag->nsamples < atempo->position[0]) {
+        // finish loading the current (possibly partial) fragment:
+        yae_load_frag(atempo, NULL, NULL);
+
+        if (atempo->nfrag) {
+            // down-mix to mono:
+            yae_downmix(atempo, frag);
+
+            // apply rDFT:
+            av_rdft_calc(atempo->real_to_complex, frag->xdat);
+
+            // align current fragment to previous fragment:
+            if (yae_adjust_position(atempo)) {
+                // reload the current fragment due to adjusted position:
+                yae_load_frag(atempo, NULL, NULL);
+            }
+        }
+    }
+
+    // flush the overlap region:
+    overlap_end = frag->position[1] + FFMIN(atempo->window / 2,
+                                            frag->nsamples);
+
+    while (atempo->position[1] < overlap_end) {
+        if (yae_overlap_add(atempo, dst_ref, dst_end) != 0) {
+            return AVERROR(EAGAIN);
+        }
+    }
+
+    // flush the remaininder of the current fragment:
+    start_here = FFMAX(atempo->position[1], overlap_end);
+    stop_here  = frag->position[1] + frag->nsamples;
+    offset     = start_here - frag->position[1];
+    av_assert0(start_here <= stop_here && frag->position[1] <= start_here);
+
+    src = frag->data + offset * atempo->stride;
+    dst = (uint8_t *)*dst_ref;
+
+    src_size = (int)(stop_here - start_here) * atempo->stride;
+    dst_size = dst_end - dst;
+    nbytes = FFMIN(src_size, dst_size);
+
+    memcpy(dst, src, nbytes);
+    dst += nbytes;
+
+    atempo->position[1] += (nbytes / atempo->stride);
+
+    // pass-back the updated destination buffer pointer:
+    *dst_ref = (uint8_t *)dst;
+
+    return atempo->position[1] == stop_here ? 0 : AVERROR(EAGAIN);
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    ATempoContext *atempo = ctx->priv;
+
+    // NOTE: this assumes that the caller has memset ctx->priv to 0:
+    atempo->format = AV_SAMPLE_FMT_NONE;
+    atempo->tempo  = 1.0;
+    atempo->state  = YAE_LOAD_FRAGMENT;
+
+    return args ? yae_set_tempo(ctx, args) : 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    ATempoContext *atempo = ctx->priv;
+    yae_release_buffers(atempo);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterChannelLayouts *layouts = NULL;
+    AVFilterFormats        *formats = NULL;
+
+    // WSOLA necessitates an internal sliding window ring buffer
+    // for incoming audio stream.
+    //
+    // Planar sample formats are too cumbersome to store in a ring buffer,
+    // therefore planar sample formats are not supported.
+    //
+    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
+    };
+
+    layouts = ff_all_channel_layouts();
+    if (!layouts) {
+        return AVERROR(ENOMEM);
+    }
+    ff_set_common_channel_layouts(ctx, layouts);
+
+    formats = ff_make_format_list(sample_fmts);
+    if (!formats) {
+        return AVERROR(ENOMEM);
+    }
+    ff_set_common_formats(ctx, formats);
+
+    formats = ff_all_samplerates();
+    if (!formats) {
+        return AVERROR(ENOMEM);
+    }
+    ff_set_common_samplerates(ctx, formats);
+
+    return 0;
+}
+
+static int config_props(AVFilterLink *inlink)
+{
+    AVFilterContext  *ctx = inlink->dst;
+    ATempoContext *atempo = ctx->priv;
+
+    enum AVSampleFormat format = inlink->format;
+    int sample_rate = (int)inlink->sample_rate;
+    int channels = av_get_channel_layout_nb_channels(inlink->channel_layout);
+
+    return yae_reset(atempo, format, sample_rate, channels);
+}
+
+static void push_samples(ATempoContext *atempo,
+                         AVFilterLink *outlink,
+                         int n_out)
+{
+    atempo->dst_buffer->audio->sample_rate = outlink->sample_rate;
+    atempo->dst_buffer->audio->nb_samples  = n_out;
+
+    // adjust the PTS:
+    atempo->dst_buffer->pts =
+        av_rescale_q(atempo->nsamples_out,
+                     (AVRational){ 1, outlink->sample_rate },
+                     outlink->time_base);
+
+    ff_filter_samples(outlink, atempo->dst_buffer);
+    atempo->dst_buffer = NULL;
+    atempo->dst        = NULL;
+    atempo->dst_end    = NULL;
+
+    atempo->nsamples_out += n_out;
+}
+
+static int filter_samples(AVFilterLink *inlink,
+                           AVFilterBufferRef *src_buffer)
+{
+    AVFilterContext  *ctx = inlink->dst;
+    ATempoContext *atempo = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
+
+    int n_in = src_buffer->audio->nb_samples;
+    int n_out = (int)(0.5 + ((double)n_in) / atempo->tempo);
+
+    const uint8_t *src = src_buffer->data[0];
+    const uint8_t *src_end = src + n_in * atempo->stride;
+
+    while (src < src_end) {
+        if (!atempo->dst_buffer) {
+            atempo->dst_buffer = ff_get_audio_buffer(outlink,
+                                                     AV_PERM_WRITE,
+                                                     n_out);
+            avfilter_copy_buffer_ref_props(atempo->dst_buffer, src_buffer);
+
+            atempo->dst = atempo->dst_buffer->data[0];
+            atempo->dst_end = atempo->dst + n_out * atempo->stride;
+        }
+
+        yae_apply(atempo, &src, src_end, &atempo->dst, atempo->dst_end);
+
+        if (atempo->dst == atempo->dst_end) {
+            push_samples(atempo, outlink, n_out);
+            atempo->request_fulfilled = 1;
+        }
+    }
+
+    atempo->nsamples_in += n_in;
+    avfilter_unref_bufferp(&src_buffer);
+    return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext  *ctx = outlink->src;
+    ATempoContext *atempo = ctx->priv;
+    int ret;
+
+    atempo->request_fulfilled = 0;
+    do {
+        ret = ff_request_frame(ctx->inputs[0]);
+    }
+    while (!atempo->request_fulfilled && ret >= 0);
+
+    if (ret == AVERROR_EOF) {
+        // flush the filter:
+        int n_max = atempo->ring;
+        int n_out;
+        int err = AVERROR(EAGAIN);
+
+        while (err == AVERROR(EAGAIN)) {
+            if (!atempo->dst_buffer) {
+                atempo->dst_buffer = ff_get_audio_buffer(outlink,
+                                                         AV_PERM_WRITE,
+                                                         n_max);
+
+                atempo->dst = atempo->dst_buffer->data[0];
+                atempo->dst_end = atempo->dst + n_max * atempo->stride;
+            }
+
+            err = yae_flush(atempo, &atempo->dst, atempo->dst_end);
+
+            n_out = ((atempo->dst - atempo->dst_buffer->data[0]) /
+                     atempo->stride);
+
+            if (n_out) {
+                push_samples(atempo, outlink, n_out);
+            }
+        }
+
+        avfilter_unref_bufferp(&atempo->dst_buffer);
+        atempo->dst     = NULL;
+        atempo->dst_end = NULL;
+
+        return AVERROR_EOF;
+    }
+
+    return ret;
+}
+
+static int process_command(AVFilterContext *ctx,
+                           const char *cmd,
+                           const char *arg,
+                           char *res,
+                           int res_len,
+                           int flags)
+{
+    return !strcmp(cmd, "tempo") ? yae_set_tempo(ctx, arg) : AVERROR(ENOSYS);
+}
+
+AVFilter avfilter_af_atempo = {
+    .name            = "atempo",
+    .description     = NULL_IF_CONFIG_SMALL("Adjust audio tempo."),
+    .init            = init,
+    .uninit          = uninit,
+    .query_formats   = query_formats,
+    .process_command = process_command,
+    .priv_size       = sizeof(ATempoContext),
+
+    .inputs    = (const AVFilterPad[]) {
+        { .name            = "default",
+          .type            = AVMEDIA_TYPE_AUDIO,
+          .filter_samples  = filter_samples,
+          .config_props    = config_props,
+          .min_perms       = AV_PERM_READ, },
+        { .name = NULL}
+    },
+
+    .outputs   = (const AVFilterPad[]) {
+        { .name            = "default",
+          .request_frame   = request_frame,
+          .type            = AVMEDIA_TYPE_AUDIO, },
+        { .name = NULL}
+    },
+};
diff --git a/libavfilter/af_channelmap.c b/libavfilter/af_channelmap.c
index 8c49d10..6e3f021 100644
--- a/libavfilter/af_channelmap.c
+++ b/libavfilter/af_channelmap.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2012 Google, Inc.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -68,11 +68,12 @@
 
 #define OFFSET(x) offsetof(ChannelMapContext, x)
 #define A AV_OPT_FLAG_AUDIO_PARAM
+#define F AV_OPT_FLAG_FILTERING_PARAM
 static const AVOption options[] = {
     { "map", "A comma-separated list of input channel numbers in output order.",
-          OFFSET(mapping_str),        AV_OPT_TYPE_STRING, .flags = A },
+          OFFSET(mapping_str),        AV_OPT_TYPE_STRING, .flags = A|F },
     { "channel_layout", "Output channel layout.",
-          OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, .flags = A },
+          OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, .flags = A|F },
     { NULL },
 };
 
@@ -139,10 +140,8 @@
     s->class = &channelmap_class;
     av_opt_set_defaults(s);
 
-    if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", args);
+    if ((ret = av_set_options_string(s, args, "=", ":")) < 0)
         return ret;
-    }
 
     mapping = s->mapping_str;
 
@@ -390,6 +389,7 @@
     {
         .name           = "default",
         .type           = AVMEDIA_TYPE_AUDIO,
+        .min_perms      = AV_PERM_READ | AV_PERM_WRITE,
         .filter_samples = channelmap_filter_samples,
         .config_props   = channelmap_config_input
     },
@@ -413,4 +413,5 @@
 
     .inputs        = avfilter_af_channelmap_inputs,
     .outputs       = avfilter_af_channelmap_outputs,
+    .priv_class    = &channelmap_class,
 };
diff --git a/libavfilter/af_channelsplit.c b/libavfilter/af_channelsplit.c
index 92fb27e..56950c8 100644
--- a/libavfilter/af_channelsplit.c
+++ b/libavfilter/af_channelsplit.c
@@ -41,17 +41,13 @@
 
 #define OFFSET(x) offsetof(ChannelSplitContext, x)
 #define A AV_OPT_FLAG_AUDIO_PARAM
-static const AVOption options[] = {
-    { "channel_layout", "Input channel layout.", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, { .str = "stereo" }, .flags = A },
+#define F AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption channelsplit_options[] = {
+    { "channel_layout", "Input channel layout.", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, { .str = "stereo" }, .flags = A|F },
     { NULL },
 };
 
-static const AVClass channelsplit_class = {
-    .class_name = "channelsplit filter",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+AVFILTER_DEFINE_CLASS(channelsplit);
 
 static int init(AVFilterContext *ctx, const char *arg)
 {
@@ -61,10 +57,8 @@
 
     s->class = &channelsplit_class;
     av_opt_set_defaults(s);
-    if ((ret = av_set_options_string(s, arg, "=", ":")) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", arg);
+    if ((ret = av_set_options_string(s, arg, "=", ":")) < 0)
         return ret;
-    }
     if (!(s->channel_layout = av_get_channel_layout(s->channel_layout_str))) {
         av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout '%s'.\n",
                s->channel_layout_str);
@@ -155,4 +149,5 @@
 
     .inputs  = avfilter_af_channelsplit_inputs,
     .outputs = NULL,
+    .priv_class = &channelsplit_class,
 };
diff --git a/libavfilter/af_earwax.c b/libavfilter/af_earwax.c
new file mode 100644
index 0000000..7265c43
--- /dev/null
+++ b/libavfilter/af_earwax.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2011 Mina Nagy Zaki
+ * Copyright (c) 2000 Edward Beingessner And Sundry Contributors.
+ * This source code is freely redistributable and may be used for any purpose.
+ * This copyright notice must be maintained.  Edward Beingessner And Sundry
+ * Contributors are not responsible for the consequences of using this
+ * software.
+ *
+ * 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
+ * Stereo Widening Effect. Adds audio cues to move stereo image in
+ * front of the listener. Adapted from the libsox earwax effect.
+ */
+
+#include "libavutil/audioconvert.h"
+#include "avfilter.h"
+#include "audio.h"
+#include "formats.h"
+
+#define NUMTAPS 64
+
+static const int8_t filt[NUMTAPS] = {
+/* 30°  330° */
+    4,   -6,     /* 32 tap stereo FIR filter. */
+    4,  -11,     /* One side filters as if the */
+   -1,   -5,     /* signal was from 30 degrees */
+    3,    3,     /* from the ear, the other as */
+   -2,    5,     /* if 330 degrees. */
+   -5,    0,
+    9,    1,
+    6,    3,     /*                         Input                         */
+   -4,   -1,     /*                   Left         Right                  */
+   -5,   -3,     /*                __________   __________                */
+   -2,   -5,     /*               |          | |          |               */
+   -7,    1,     /*           .---|  Hh,0(f) | |  Hh,0(f) |---.           */
+    6,   -7,     /*          /    |__________| |__________|    \          */
+   30,  -29,     /*         /                \ /                \         */
+   12,   -3,     /*        /                  X                  \        */
+  -11,    4,     /*       /                  / \                  \       */
+   -3,    7,     /*  ____V_____   __________V   V__________   _____V____  */
+  -20,   23,     /* |          | |          |   |          | |          | */
+    2,    0,     /* | Hh,30(f) | | Hh,330(f)|   | Hh,330(f)| | Hh,30(f) | */
+    1,   -6,     /* |__________| |__________|   |__________| |__________| */
+  -14,   -5,     /*      \     ___      /           \      ___     /      */
+   15,  -18,     /*       \   /   \    /    _____    \    /   \   /       */
+    6,    7,     /*        `->| + |<--'    /     \    `-->| + |<-'        */
+   15,  -10,     /*           \___/      _/       \_      \___/           */
+  -14,   22,     /*               \     / \       / \     /               */
+   -7,   -2,     /*                `--->| |       | |<---'                */
+   -4,    9,     /*                     \_/       \_/                     */
+    6,  -12,     /*                                                       */
+    6,   -6,     /*                       Headphones                      */
+    0,  -11,
+    0,   -5,
+    4,    0};
+
+typedef struct {
+    int16_t taps[NUMTAPS * 2];
+} EarwaxContext;
+
+static int query_formats(AVFilterContext *ctx)
+{
+    int sample_rates[] = { 44100, -1 };
+
+    AVFilterFormats *formats = NULL;
+    AVFilterChannelLayouts *layout = NULL;
+
+    ff_add_format(&formats, AV_SAMPLE_FMT_S16);
+    ff_set_common_formats(ctx, formats);
+    ff_add_channel_layout(&layout, AV_CH_LAYOUT_STEREO);
+    ff_set_common_channel_layouts(ctx, layout);
+    ff_set_common_samplerates(ctx, ff_make_format_list(sample_rates));
+
+    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)
+{
+    int32_t sample;
+    int16_t j;
+
+    while (in < endin) {
+        sample = 32;
+        for (j = 0; j < NUMTAPS; j++)
+            sample += in[j] * filt[j];
+        *out = sample >> 6;
+        out++;
+        in++;
+    }
+
+    return out;
+}
+
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
+{
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    int16_t *taps, *endin, *in, *out;
+    AVFilterBufferRef *outsamples =
+        ff_get_audio_buffer(inlink, AV_PERM_WRITE,
+                                  insamples->audio->nb_samples);
+    int ret;
+
+    avfilter_copy_buffer_ref_props(outsamples, insamples);
+
+    taps  = ((EarwaxContext *)inlink->dst->priv)->taps;
+    out   = (int16_t *)outsamples->data[0];
+    in    = (int16_t *)insamples ->data[0];
+
+    // copy part of new input and process with saved input
+    memcpy(taps+NUMTAPS, in, NUMTAPS * sizeof(*taps));
+    out   = scalarproduct(taps, taps + NUMTAPS, out);
+
+    // process current input
+    endin = in + insamples->audio->nb_samples * 2 - NUMTAPS;
+    out   = scalarproduct(in, endin, out);
+
+    // save part of input for next round
+    memcpy(taps, endin, NUMTAPS * sizeof(*taps));
+
+    ret = ff_filter_samples(outlink, outsamples);
+    avfilter_unref_buffer(insamples);
+    return ret;
+}
+
+AVFilter avfilter_af_earwax = {
+    .name           = "earwax",
+    .description    = NULL_IF_CONFIG_SMALL("Widen the stereo image."),
+    .query_formats  = query_formats,
+    .priv_size      = sizeof(EarwaxContext),
+    .inputs  = (const AVFilterPad[])  {{  .name     = "default",
+                                    .type           = AVMEDIA_TYPE_AUDIO,
+                                    .filter_samples = filter_samples,
+                                    .config_props   = config_input,
+                                    .min_perms      = AV_PERM_READ, },
+                                 {  .name = NULL}},
+
+    .outputs = (const AVFilterPad[])  {{  .name     = "default",
+                                    .type           = AVMEDIA_TYPE_AUDIO, },
+                                 {  .name = NULL}},
+};
diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c
index 7e3a542..210c844 100644
--- a/libavfilter/af_join.c
+++ b/libavfilter/af_join.c
@@ -76,13 +76,14 @@
 
 #define OFFSET(x) offsetof(JoinContext, x)
 #define A AV_OPT_FLAG_AUDIO_PARAM
+#define F AV_OPT_FLAG_FILTERING_PARAM
 static const AVOption join_options[] = {
-    { "inputs",         "Number of input streams.", OFFSET(inputs),             AV_OPT_TYPE_INT,    { .i64 = 2 }, 1, INT_MAX,       A },
+    { "inputs",         "Number of input streams.", OFFSET(inputs),             AV_OPT_TYPE_INT,    { .i64 = 2 }, 1, INT_MAX,       A|F },
     { "channel_layout", "Channel layout of the "
-                        "output stream.",           OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0, A },
+                        "output stream.",           OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0, A|F },
     { "map",            "A comma-separated list of channels maps in the format "
                         "'input_stream.input_channel-output_channel.",
-                                                    OFFSET(map),                AV_OPT_TYPE_STRING,                 .flags = A },
+                                                    OFFSET(map),                AV_OPT_TYPE_STRING,                 .flags = A|F },
     { NULL },
 };
 
@@ -194,10 +195,8 @@
 
     s->class = &join_class;
     av_opt_set_defaults(s);
-    if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing options string '%s'.\n", args);
+    if ((ret = av_set_options_string(s, args, "=", ":")) < 0)
         return ret;
-    }
 
     if (!(s->channel_layout = av_get_channel_layout(s->channel_layout_str))) {
         av_log(ctx, AV_LOG_ERROR, "Error parsing channel layout '%s'.\n",
@@ -507,4 +506,5 @@
 
     .inputs  = NULL,
     .outputs = avfilter_af_join_outputs,
+    .priv_class = &join_class,
 };
diff --git a/libavfilter/af_pan.c b/libavfilter/af_pan.c
new file mode 100644
index 0000000..8d1bb5b
--- /dev/null
+++ b/libavfilter/af_pan.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2002 Anders Johansson <ajh@atri.curtin.edu.au>
+ * Copyright (c) 2011 Clément Bœsch <ubitux@gmail.com>
+ * Copyright (c) 2011 Nicolas George <nicolas.george@normalesup.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
+ * Audio panning filter (channels mixing)
+ * Original code written by Anders Johansson for MPlayer,
+ * reimplemented for FFmpeg.
+ */
+
+#include <stdio.h>
+#include "libavutil/audioconvert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
+#include "libswresample/swresample.h"
+#include "audio.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+
+#define MAX_CHANNELS 63
+
+typedef struct PanContext {
+    int64_t out_channel_layout;
+    double gain[MAX_CHANNELS][MAX_CHANNELS];
+    int64_t need_renorm;
+    int need_renumber;
+    int nb_input_channels;
+    int nb_output_channels;
+
+    int pure_gains;
+    /* channel mapping specific */
+    int channel_map[SWR_CH_MAX];
+    struct SwrContext *swr;
+} PanContext;
+
+static int parse_channel_name(char **arg, int *rchannel, int *rnamed)
+{
+    char buf[8];
+    int len, i, channel_id = 0;
+    int64_t layout, layout0;
+
+    /* try to parse a channel name, e.g. "FL" */
+    if (sscanf(*arg, "%7[A-Z]%n", buf, &len)) {
+        layout0 = layout = av_get_channel_layout(buf);
+        /* channel_id <- first set bit in layout */
+        for (i = 32; i > 0; i >>= 1) {
+            if (layout >= (int64_t)1 << i) {
+                channel_id += i;
+                layout >>= i;
+            }
+        }
+        /* reject layouts that are not a single channel */
+        if (channel_id >= MAX_CHANNELS || layout0 != (int64_t)1 << channel_id)
+            return AVERROR(EINVAL);
+        *rchannel = channel_id;
+        *rnamed = 1;
+        *arg += len;
+        return 0;
+    }
+    /* try to parse a channel number, e.g. "c2" */
+    if (sscanf(*arg, "c%d%n", &channel_id, &len) &&
+        channel_id >= 0 && channel_id < MAX_CHANNELS) {
+        *rchannel = channel_id;
+        *rnamed = 0;
+        *arg += len;
+        return 0;
+    }
+    return AVERROR(EINVAL);
+}
+
+static void skip_spaces(char **arg)
+{
+    int len = 0;
+
+    sscanf(*arg, " %n", &len);
+    *arg += len;
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args0)
+{
+    PanContext *const pan = ctx->priv;
+    char *arg, *arg0, *tokenizer, *args = av_strdup(args0);
+    int out_ch_id, in_ch_id, len, named, ret;
+    int nb_in_channels[2] = { 0, 0 }; // number of unnamed and named input channels
+    double gain;
+
+    if (!args0) {
+        av_log(ctx, AV_LOG_ERROR,
+               "pan filter needs a channel layout and a set "
+               "of channels definitions as parameter\n");
+        return AVERROR(EINVAL);
+    }
+    if (!args)
+        return AVERROR(ENOMEM);
+    arg = av_strtok(args, ":", &tokenizer);
+    ret = ff_parse_channel_layout(&pan->out_channel_layout, arg, ctx);
+    if (ret < 0)
+        goto fail;
+    pan->nb_output_channels = av_get_channel_layout_nb_channels(pan->out_channel_layout);
+
+    /* parse channel specifications */
+    while ((arg = arg0 = av_strtok(NULL, ":", &tokenizer))) {
+        /* channel name */
+        if (parse_channel_name(&arg, &out_ch_id, &named)) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Expected out channel name, got \"%.8s\"\n", arg);
+            ret = AVERROR(EINVAL);
+            goto fail;
+        }
+        if (named) {
+            if (!((pan->out_channel_layout >> out_ch_id) & 1)) {
+                av_log(ctx, AV_LOG_ERROR,
+                       "Channel \"%.8s\" does not exist in the chosen layout\n", arg0);
+                ret = AVERROR(EINVAL);
+                goto fail;
+            }
+            /* get the channel number in the output channel layout:
+             * out_channel_layout & ((1 << out_ch_id) - 1) are all the
+             * channels that come before out_ch_id,
+             * so their count is the index of out_ch_id */
+            out_ch_id = av_get_channel_layout_nb_channels(pan->out_channel_layout & (((int64_t)1 << out_ch_id) - 1));
+        }
+        if (out_ch_id < 0 || out_ch_id >= pan->nb_output_channels) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Invalid out channel name \"%.8s\"\n", arg0);
+            ret = AVERROR(EINVAL);
+            goto fail;
+        }
+        skip_spaces(&arg);
+        if (*arg == '=') {
+            arg++;
+        } else if (*arg == '<') {
+            pan->need_renorm |= (int64_t)1 << out_ch_id;
+            arg++;
+        } else {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Syntax error after channel name in \"%.8s\"\n", arg0);
+            ret = AVERROR(EINVAL);
+            goto fail;
+        }
+        /* gains */
+        while (1) {
+            gain = 1;
+            if (sscanf(arg, "%lf%n *%n", &gain, &len, &len))
+                arg += len;
+            if (parse_channel_name(&arg, &in_ch_id, &named)){
+                av_log(ctx, AV_LOG_ERROR,
+                       "Expected in channel name, got \"%.8s\"\n", arg);
+                 ret = AVERROR(EINVAL);
+                 goto fail;
+            }
+            nb_in_channels[named]++;
+            if (nb_in_channels[!named]) {
+                av_log(ctx, AV_LOG_ERROR,
+                       "Can not mix named and numbered channels\n");
+                ret = AVERROR(EINVAL);
+                goto fail;
+            }
+            pan->gain[out_ch_id][in_ch_id] = gain;
+            skip_spaces(&arg);
+            if (!*arg)
+                break;
+            if (*arg != '+') {
+                av_log(ctx, AV_LOG_ERROR, "Syntax error near \"%.8s\"\n", arg);
+                ret = AVERROR(EINVAL);
+                goto fail;
+            }
+            arg++;
+        }
+    }
+    pan->need_renumber = !!nb_in_channels[1];
+
+    ret = 0;
+fail:
+    av_free(args);
+    return ret;
+}
+
+static int are_gains_pure(const PanContext *pan)
+{
+    int i, j;
+
+    for (i = 0; i < MAX_CHANNELS; i++) {
+        int nb_gain = 0;
+
+        for (j = 0; j < MAX_CHANNELS; j++) {
+            double gain = pan->gain[i][j];
+
+            /* channel mapping is effective only if 0% or 100% of a channel is
+             * selected... */
+            if (gain != 0. && gain != 1.)
+                return 0;
+            /* ...and if the output channel is only composed of one input */
+            if (gain && nb_gain++)
+                return 0;
+        }
+    }
+    return 1;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    PanContext *pan = ctx->priv;
+    AVFilterLink *inlink  = ctx->inputs[0];
+    AVFilterLink *outlink = ctx->outputs[0];
+    AVFilterFormats *formats = NULL;
+    AVFilterChannelLayouts *layouts;
+
+    pan->pure_gains = are_gains_pure(pan);
+    /* libswr supports any sample and packing formats */
+    ff_set_common_formats(ctx, ff_all_formats(AVMEDIA_TYPE_AUDIO));
+
+    formats = ff_all_samplerates();
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_set_common_samplerates(ctx, formats);
+
+    // inlink supports any channel layout
+    layouts = ff_all_channel_layouts();
+    ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts);
+
+    // outlink supports only requested output channel layout
+    layouts = NULL;
+    ff_add_channel_layout(&layouts, pan->out_channel_layout);
+    ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
+    return 0;
+}
+
+static int config_props(AVFilterLink *link)
+{
+    AVFilterContext *ctx = link->dst;
+    PanContext *pan = ctx->priv;
+    char buf[1024], *cur;
+    int i, j, k, r;
+    double t;
+
+    pan->nb_input_channels = av_get_channel_layout_nb_channels(link->channel_layout);
+    if (pan->need_renumber) {
+        // input channels were given by their name: renumber them
+        for (i = j = 0; i < MAX_CHANNELS; i++) {
+            if ((link->channel_layout >> i) & 1) {
+                for (k = 0; k < pan->nb_output_channels; k++)
+                    pan->gain[k][j] = pan->gain[k][i];
+                j++;
+            }
+        }
+    }
+
+    // sanity check; can't be done in query_formats since the inlink
+    // channel layout is unknown at that time
+    if (pan->nb_input_channels > SWR_CH_MAX ||
+        pan->nb_output_channels > SWR_CH_MAX) {
+        av_log(ctx, AV_LOG_ERROR,
+               "libswresample support a maximum of %d channels. "
+               "Feel free to ask for a higher limit.\n", SWR_CH_MAX);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    // init libswresample context
+    pan->swr = swr_alloc_set_opts(pan->swr,
+                                  pan->out_channel_layout, link->format, link->sample_rate,
+                                  link->channel_layout,    link->format, link->sample_rate,
+                                  0, ctx);
+    if (!pan->swr)
+        return AVERROR(ENOMEM);
+
+    // gains are pure, init the channel mapping
+    if (pan->pure_gains) {
+
+        // get channel map from the pure gains
+        for (i = 0; i < pan->nb_output_channels; i++) {
+            int ch_id = -1;
+            for (j = 0; j < pan->nb_input_channels; j++) {
+                if (pan->gain[i][j]) {
+                    ch_id = j;
+                    break;
+                }
+            }
+            pan->channel_map[i] = ch_id;
+        }
+
+        av_opt_set_int(pan->swr, "icl", pan->out_channel_layout, 0);
+        av_opt_set_int(pan->swr, "uch", pan->nb_output_channels, 0);
+        swr_set_channel_mapping(pan->swr, pan->channel_map);
+    } else {
+        // renormalize
+        for (i = 0; i < pan->nb_output_channels; i++) {
+            if (!((pan->need_renorm >> i) & 1))
+                continue;
+            t = 0;
+            for (j = 0; j < pan->nb_input_channels; j++)
+                t += pan->gain[i][j];
+            if (t > -1E-5 && t < 1E-5) {
+                // t is almost 0 but not exactly, this is probably a mistake
+                if (t)
+                    av_log(ctx, AV_LOG_WARNING,
+                           "Degenerate coefficients while renormalizing\n");
+                continue;
+            }
+            for (j = 0; j < pan->nb_input_channels; j++)
+                pan->gain[i][j] /= t;
+        }
+        av_opt_set_int(pan->swr, "icl", link->channel_layout, 0);
+        av_opt_set_int(pan->swr, "ocl", pan->out_channel_layout, 0);
+        swr_set_matrix(pan->swr, pan->gain[0], pan->gain[1] - pan->gain[0]);
+    }
+
+    r = swr_init(pan->swr);
+    if (r < 0)
+        return r;
+
+    // summary
+    for (i = 0; i < pan->nb_output_channels; i++) {
+        cur = buf;
+        for (j = 0; j < pan->nb_input_channels; j++) {
+            r = snprintf(cur, buf + sizeof(buf) - cur, "%s%.3g i%d",
+                         j ? " + " : "", pan->gain[i][j], j);
+            cur += FFMIN(buf + sizeof(buf) - cur, r);
+        }
+        av_log(ctx, AV_LOG_VERBOSE, "o%d = %s\n", i, buf);
+    }
+    // add channel mapping summary if possible
+    if (pan->pure_gains) {
+        av_log(ctx, AV_LOG_INFO, "Pure channel mapping detected:");
+        for (i = 0; i < pan->nb_output_channels; i++)
+            if (pan->channel_map[i] < 0)
+                av_log(ctx, AV_LOG_INFO, " M");
+            else
+                av_log(ctx, AV_LOG_INFO, " %d", pan->channel_map[i]);
+        av_log(ctx, AV_LOG_INFO, "\n");
+        return 0;
+    }
+    return 0;
+}
+
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
+{
+    int ret;
+    int n = insamples->audio->nb_samples;
+    AVFilterLink *const outlink = inlink->dst->outputs[0];
+    AVFilterBufferRef *outsamples = ff_get_audio_buffer(outlink, AV_PERM_WRITE, n);
+    PanContext *pan = inlink->dst->priv;
+
+    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;
+
+    ret = ff_filter_samples(outlink, outsamples);
+    avfilter_unref_buffer(insamples);
+    return ret;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    PanContext *pan = ctx->priv;
+    swr_free(&pan->swr);
+}
+
+AVFilter avfilter_af_pan = {
+    .name          = "pan",
+    .description   = NULL_IF_CONFIG_SMALL("Remix channels with coefficients (panning)."),
+    .priv_size     = sizeof(PanContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+
+    .inputs    = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_AUDIO,
+          .config_props     = config_props,
+          .filter_samples   = filter_samples,
+          .min_perms        = AV_PERM_READ, },
+        { .name = NULL}
+    },
+    .outputs   = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_AUDIO, },
+        { .name = NULL}
+    },
+};
diff --git a/libavfilter/af_silencedetect.c b/libavfilter/af_silencedetect.c
new file mode 100644
index 0000000..2ea5d7f
--- /dev/null
+++ b/libavfilter/af_silencedetect.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2012 Clément Bœsch <ubitux@gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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 silence detector
+ */
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/opt.h"
+#include "libavutil/timestamp.h"
+#include "audio.h"
+#include "formats.h"
+#include "avfilter.h"
+#include "internal.h"
+
+typedef struct {
+    const AVClass *class;
+    char *noise_str;            ///< noise option string
+    double noise;               ///< noise amplitude ratio
+    int duration;               ///< minimum duration of silence until notification
+    int64_t nb_null_samples;    ///< current number of continuous zero samples
+    int64_t start;              ///< if silence is detected, this value contains the time of the first zero sample
+    int last_sample_rate;       ///< last sample rate to check for sample rate changes
+} SilenceDetectContext;
+
+#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 },
+    { "d",         "set minimum duration in seconds",  OFFSET(duration),  AV_OPT_TYPE_INT,    {.i64=2},    0, INT_MAX, FLAGS },
+    { "duration",  "set minimum duration in seconds",  OFFSET(duration),  AV_OPT_TYPE_INT,    {.i64=2},    0, INT_MAX, FLAGS },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(silencedetect);
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    int ret;
+    char *tail;
+    SilenceDetectContext *silence = ctx->priv;
+
+    silence->class = &silencedetect_class;
+    av_opt_set_defaults(silence);
+
+    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;
+}
+
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
+{
+    int i;
+    SilenceDetectContext *silence = inlink->dst->priv;
+    const int nb_channels           = av_get_channel_layout_nb_channels(inlink->channel_layout);
+    const int srate                 = inlink->sample_rate;
+    const int nb_samples            = insamples->audio->nb_samples * nb_channels;
+    const int64_t nb_samples_notify = srate * silence->duration    * nb_channels;
+
+    // scale number of null samples to the new sample rate
+    if (silence->last_sample_rate && silence->last_sample_rate != srate)
+        silence->nb_null_samples =
+            srate * silence->nb_null_samples / silence->last_sample_rate;
+    silence->last_sample_rate = srate;
+
+    // TODO: support more sample formats
+    if (insamples->format == AV_SAMPLE_FMT_DBL) {
+        double *p = (double *)insamples->data[0];
+
+        for (i = 0; i < nb_samples; i++, p++) {
+            if (*p < silence->noise && *p > -silence->noise) {
+                if (!silence->start) {
+                    silence->nb_null_samples++;
+                    if (silence->nb_null_samples >= nb_samples_notify) {
+                        silence->start = insamples->pts - silence->duration / av_q2d(inlink->time_base);
+                        av_log(silence, AV_LOG_INFO,
+                               "silence_start: %s\n", av_ts2timestr(silence->start, &inlink->time_base));
+                    }
+                }
+            } else {
+                if (silence->start)
+                    av_log(silence, AV_LOG_INFO,
+                           "silence_end: %s | silence_duration: %s\n",
+                           av_ts2timestr(insamples->pts,                  &inlink->time_base),
+                           av_ts2timestr(insamples->pts - silence->start, &inlink->time_base));
+                silence->nb_null_samples = silence->start = 0;
+            }
+        }
+    }
+
+    return ff_filter_samples(inlink->dst->outputs[0], insamples);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterFormats *formats = NULL;
+    AVFilterChannelLayouts *layouts = NULL;
+    enum AVSampleFormat sample_fmts[] = {
+        AV_SAMPLE_FMT_DBL,
+        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;
+}
+
+AVFilter avfilter_af_silencedetect = {
+    .name          = "silencedetect",
+    .description   = NULL_IF_CONFIG_SMALL("Detect silence."),
+    .priv_size     = sizeof(SilenceDetectContext),
+    .init          = init,
+    .query_formats = query_formats,
+
+    .inputs = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_AUDIO,
+          .get_audio_buffer = ff_null_get_audio_buffer,
+          .filter_samples   = filter_samples, },
+        { .name = NULL }
+    },
+    .outputs = (const AVFilterPad[]) {
+        { .name = "default",
+          .type = AVMEDIA_TYPE_AUDIO, },
+        { .name = NULL }
+    },
+    .priv_class = &silencedetect_class,
+};
diff --git a/libavfilter/af_volume.c b/libavfilter/af_volume.c
new file mode 100644
index 0000000..1aca7d9
--- /dev/null
+++ b/libavfilter/af_volume.c
@@ -0,0 +1,191 @@
+/*
+ * 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
+ * audio volume filter
+ * based on ffmpeg.c code
+ */
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/eval.h"
+#include "audio.h"
+#include "avfilter.h"
+#include "formats.h"
+
+typedef struct {
+    double volume;
+    int    volume_i;
+} VolumeContext;
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    VolumeContext *vol = ctx->priv;
+    char *tail;
+    int ret = 0;
+
+    vol->volume = 1.0;
+
+    if (args) {
+        /* parse the number as a decimal number */
+        double d = strtod(args, &tail);
+
+        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;
+    }
+
+    vol->volume_i = (int)(vol->volume * 256 + 0.5);
+    av_log(ctx, AV_LOG_VERBOSE, "volume=%f\n", vol->volume);
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    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
+    };
+
+    layouts = ff_all_channel_layouts();
+    if (!layouts)
+        return AVERROR(ENOMEM);
+    ff_set_common_channel_layouts(ctx, layouts);
+
+    formats = ff_make_format_list(sample_fmts);
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_set_common_formats(ctx, formats);
+
+    formats = ff_all_samplerates();
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_set_common_samplerates(ctx, formats);
+
+    return 0;
+}
+
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
+{
+    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_samples(outlink, insamples);
+}
+
+AVFilter avfilter_af_volume = {
+    .name           = "volume",
+    .description    = NULL_IF_CONFIG_SMALL("Change input volume."),
+    .query_formats  = query_formats,
+    .priv_size      = sizeof(VolumeContext),
+    .init           = init,
+
+    .inputs  = (const AVFilterPad[])  {{ .name     = "default",
+                                   .type           = AVMEDIA_TYPE_AUDIO,
+                                   .filter_samples = filter_samples,
+                                   .min_perms      = AV_PERM_READ|AV_PERM_WRITE},
+                                 { .name = NULL}},
+
+    .outputs = (const AVFilterPad[])  {{ .name     = "default",
+                                   .type           = AVMEDIA_TYPE_AUDIO, },
+                                 { .name = NULL}},
+};
diff --git a/libavfilter/af_volumedetect.c b/libavfilter/af_volumedetect.c
new file mode 100644
index 0000000..9bc40f6
--- /dev/null
+++ b/libavfilter/af_volumedetect.c
@@ -0,0 +1,159 @@
+/*
+ * 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/audioconvert.h"
+#include "libavutil/avassert.h"
+#include "audio.h"
+#include "avfilter.h"
+#include "internal.h"
+
+typedef struct {
+    /**
+     * Number of samples at each PCM value.
+     * histogram[0x8000 + i] is the number of samples at value i.
+     * The extra element is there for symmetry.
+     */
+    uint64_t histogram[0x10001];
+} VolDetectContext;
+
+static int query_formats(AVFilterContext *ctx)
+{
+    enum AVSampleFormat sample_fmts[] = {
+        AV_SAMPLE_FMT_S16,
+        AV_SAMPLE_FMT_S16P,
+        AV_SAMPLE_FMT_NONE
+    };
+    AVFilterFormats *formats;
+
+    if (!(formats = ff_make_format_list(sample_fmts)))
+        return AVERROR(ENOMEM);
+    ff_set_common_formats(ctx, formats);
+
+    return 0;
+}
+
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samples)
+{
+    AVFilterContext *ctx = inlink->dst;
+    VolDetectContext *vd = ctx->priv;
+    int64_t layout  = samples->audio->channel_layout;
+    int nb_samples  = samples->audio->nb_samples;
+    int nb_channels = av_get_channel_layout_nb_channels(layout);
+    int nb_planes   = nb_channels;
+    int plane, i;
+    int16_t *pcm;
+
+    if (!av_sample_fmt_is_planar(samples->format)) {
+        nb_samples *= nb_channels;
+        nb_planes = 1;
+    }
+    for (plane = 0; plane < nb_planes; plane++) {
+        pcm = (int16_t *)samples->extended_data[plane];
+        for (i = 0; i < nb_samples; i++)
+            vd->histogram[pcm[i] + 0x8000]++;
+    }
+
+    return ff_filter_samples(inlink->dst->outputs[0], samples);
+}
+
+#define MAX_DB 91
+
+static inline double logdb(uint64_t v)
+{
+    double d = v / (double)(0x8000 * 0x8000);
+    if (!v)
+        return MAX_DB;
+    return log(d) * -4.3429448190325182765112891891660508229; /* -10/log(10) */
+}
+
+static void print_stats(AVFilterContext *ctx)
+{
+    VolDetectContext *vd = ctx->priv;
+    int i, max_volume, shift;
+    uint64_t nb_samples = 0, power = 0, nb_samples_shift = 0, sum = 0;
+    uint64_t histdb[MAX_DB + 1] = { 0 };
+
+    for (i = 0; i < 0x10000; i++)
+        nb_samples += vd->histogram[i];
+    av_log(ctx, AV_LOG_INFO, "n_samples: %"PRId64"\n", nb_samples);
+    if (!nb_samples)
+        return;
+
+    /* If nb_samples > 1<<34, there is a risk of overflow in the
+       multiplication or the sum: shift all histogram values to avoid that.
+       The total number of samples must be recomputed to avoid rounding
+       errors. */
+    shift = av_log2(nb_samples >> 33);
+    for (i = 0; i < 0x10000; i++) {
+        nb_samples_shift += vd->histogram[i] >> shift;
+        power += (i - 0x8000) * (i - 0x8000) * (vd->histogram[i] >> shift);
+    }
+    if (!nb_samples_shift)
+        return;
+    power = (power + nb_samples_shift / 2) / nb_samples_shift;
+    av_assert0(power <= 0x8000 * 0x8000);
+    av_log(ctx, AV_LOG_INFO, "mean_volume: %.1f dB\n", -logdb(power));
+
+    max_volume = 0x8000;
+    while (max_volume > 0 && !vd->histogram[0x8000 + max_volume] &&
+                             !vd->histogram[0x8000 - max_volume])
+        max_volume--;
+    av_log(ctx, AV_LOG_INFO, "max_volume: %.1f dB\n", -logdb(max_volume * max_volume));
+
+    for (i = 0; i < 0x10000; i++)
+        histdb[(int)logdb((i - 0x8000) * (i - 0x8000))] += vd->histogram[i];
+    for (i = 0; i <= MAX_DB && !histdb[i]; i++);
+    for (; i <= MAX_DB && sum < nb_samples / 1000; i++) {
+        av_log(ctx, AV_LOG_INFO, "histogram_%ddb: %"PRId64"\n", i, histdb[i]);
+        sum += histdb[i];
+    }
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    int ret = ff_request_frame(ctx->inputs[0]);
+    if (ret == AVERROR_EOF)
+        print_stats(ctx);
+    return ret;
+}
+
+AVFilter avfilter_af_volumedetect = {
+    .name          = "volumedetect",
+    .description   = NULL_IF_CONFIG_SMALL("Detect audio volume."),
+
+    .priv_size     = sizeof(VolDetectContext),
+    .query_formats = query_formats,
+
+    .inputs    = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_AUDIO,
+          .get_audio_buffer = ff_null_get_audio_buffer,
+          .filter_samples   = filter_samples,
+          .min_perms        = AV_PERM_READ, },
+        { .name = NULL }
+    },
+    .outputs   = (const AVFilterPad[]) {
+        { .name = "default",
+          .type = AVMEDIA_TYPE_AUDIO,
+          .request_frame = request_frame, },
+        { .name = NULL }
+    },
+};
diff --git a/libavfilter/all_channel_layouts.inc b/libavfilter/all_channel_layouts.inc
new file mode 100644
index 0000000..878e1f5
--- /dev/null
+++ b/libavfilter/all_channel_layouts.inc
@@ -0,0 +1,68 @@
+AV_CH_FRONT_CENTER,
+AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY,
+AV_CH_FRONT_CENTER|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER,
+AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_CENTER,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER,
+AV_CH_FRONT_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_CENTER|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_LOW_FREQUENCY|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
+AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT|AV_CH_FRONT_CENTER|AV_CH_BACK_CENTER|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT|AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT,
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 94b3115..348f369 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -2,20 +2,20 @@
  * filter registration
  * Copyright (c) 2008 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -27,6 +27,10 @@
           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 ); }
+
 void avfilter_register_all(void)
 {
     static int initialized;
@@ -35,41 +39,72 @@
         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 (AEVALSRC,    aevalsrc,    asrc);
     REGISTER_FILTER (ANULLSRC,    anullsrc,    asrc);
+    REGISTER_FILTER (FLITE,       flite,       asrc);
 
     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 (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 (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);
@@ -77,29 +112,58 @@
     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 (SLICIFY,     slicify,     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 (CELLAUTO,    cellauto,    vsrc);
     REGISTER_FILTER (COLOR,       color,       vsrc);
     REGISTER_FILTER (FREI0R,      frei0r_src,  vsrc);
-    REGISTER_FILTER (MOVIE,       movie,       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);
 
+    /* multimedia filters */
+    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_BUILTIN_FILTER (ffbuffersink,  vsink);
+    REGISTER_BUILTIN_FILTER (ffabuffersink, asink);
+#if !AV_HAVE_INCOMPATIBLE_FORK_ABI
+    REGISTER_BUILTIN_FILTER (buffersink,    vsink);
+    REGISTER_BUILTIN_FILTER (abuffersink,   asink);
+#endif
+
     /* those filters are part of public or internal API => registered
      * unconditionally */
     {
diff --git a/libavfilter/asink_anullsink.c b/libavfilter/asink_anullsink.c
index b679ffa..7b337e6 100644
--- a/libavfilter/asink_anullsink.c
+++ b/libavfilter/asink_anullsink.c
@@ -1,18 +1,20 @@
 /*
- * This file is part of Libav.
+ * Copyright (c) 2010 S.N. Hemanth Meenakshisundaram <smeenaks@ucsd.edu>
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavfilter/asrc_abuffer.h b/libavfilter/asrc_abuffer.h
new file mode 100644
index 0000000..aa34461
--- /dev/null
+++ b/libavfilter/asrc_abuffer.h
@@ -0,0 +1,91 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFILTER_ASRC_ABUFFER_H
+#define AVFILTER_ASRC_ABUFFER_H
+
+#include "avfilter.h"
+
+/**
+ * @file
+ * memory buffer source for audio
+ *
+ * @deprecated use buffersrc.h instead.
+ */
+
+/**
+ * Queue an audio buffer to the audio buffer source.
+ *
+ * @param abuffersrc audio source buffer context
+ * @param data pointers to the samples planes
+ * @param linesize linesizes of each audio buffer plane
+ * @param nb_samples number of samples per channel
+ * @param sample_fmt sample format of the audio data
+ * @param ch_layout channel layout of the audio data
+ * @param planar flag to indicate if audio data is planar or packed
+ * @param pts presentation timestamp of the audio buffer
+ * @param flags unused
+ *
+ * @deprecated use av_buffersrc_add_ref() instead.
+ */
+attribute_deprecated
+int av_asrc_buffer_add_samples(AVFilterContext *abuffersrc,
+                               uint8_t *data[8], int linesize[8],
+                               int nb_samples, int sample_rate,
+                               int sample_fmt, int64_t ch_layout, int planar,
+                               int64_t pts, int av_unused flags);
+
+/**
+ * Queue an audio buffer to the audio buffer source.
+ *
+ * This is similar to av_asrc_buffer_add_samples(), but the samples
+ * are stored in a buffer with known size.
+ *
+ * @param abuffersrc audio source buffer context
+ * @param buf pointer to the samples data, packed is assumed
+ * @param size the size in bytes of the buffer, it must contain an
+ * integer number of samples
+ * @param sample_fmt sample format of the audio data
+ * @param ch_layout channel layout of the audio data
+ * @param pts presentation timestamp of the audio buffer
+ * @param flags unused
+ *
+ * @deprecated use av_buffersrc_add_ref() instead.
+ */
+attribute_deprecated
+int av_asrc_buffer_add_buffer(AVFilterContext *abuffersrc,
+                              uint8_t *buf, int buf_size,
+                              int sample_rate,
+                              int sample_fmt, int64_t ch_layout, int planar,
+                              int64_t pts, int av_unused flags);
+
+/**
+ * Queue an audio buffer to the audio buffer source.
+ *
+ * @param abuffersrc audio source buffer context
+ * @param samplesref buffer ref to queue
+ * @param flags unused
+ *
+ * @deprecated use av_buffersrc_add_ref() instead.
+ */
+attribute_deprecated
+int av_asrc_buffer_add_audio_buffer_ref(AVFilterContext *abuffersrc,
+                                        AVFilterBufferRef *samplesref,
+                                        int av_unused flags);
+
+#endif /* AVFILTER_ASRC_ABUFFER_H */
diff --git a/libavfilter/asrc_aevalsrc.c b/libavfilter/asrc_aevalsrc.c
new file mode 100644
index 0000000..c8b5e02
--- /dev/null
+++ b/libavfilter/asrc_aevalsrc.c
@@ -0,0 +1,262 @@
+/*
+ * 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
+ * eval audio source
+ */
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/eval.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "avfilter.h"
+#include "audio.h"
+#include "internal.h"
+
+static const char * const var_names[] = {
+    "n",            ///< number of frame
+    "t",            ///< timestamp expressed in seconds
+    "s",            ///< sample rate
+    NULL
+};
+
+enum var_name {
+    VAR_N,
+    VAR_T,
+    VAR_S,
+    VAR_VARS_NB
+};
+
+typedef struct {
+    const AVClass *class;
+    char *sample_rate_str;
+    int sample_rate;
+    int64_t chlayout;
+    char *chlayout_str;
+    int nb_channels;
+    int64_t pts;
+    AVExpr *expr[8];
+    char *expr_str[8];
+    int nb_samples;             ///< number of samples per requested frame
+    char *duration_str;         ///< total duration of the generated audio
+    double duration;
+    uint64_t n;
+    double var_values[VAR_VARS_NB];
+} EvalContext;
+
+#define OFFSET(x) offsetof(EvalContext, x)
+#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption aevalsrc_options[]= {
+    { "nb_samples",  "set the number of samples per requested frame", OFFSET(nb_samples),      AV_OPT_TYPE_INT,    {.i64 = 1024},    0,        INT_MAX, FLAGS },
+    { "n",           "set the number of samples per requested frame", OFFSET(nb_samples),      AV_OPT_TYPE_INT,    {.i64 = 1024},    0,        INT_MAX, FLAGS },
+    { "sample_rate", "set the sample rate",                           OFFSET(sample_rate_str), AV_OPT_TYPE_STRING, {.str = "44100"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "s",           "set the sample rate",                           OFFSET(sample_rate_str), AV_OPT_TYPE_STRING, {.str = "44100"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "duration",    "set audio duration", OFFSET(duration_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+    { "d",           "set audio duration", OFFSET(duration_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+    { "channel_layout", "set channel layout", OFFSET(chlayout_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+    { "c",              "set channel layout", OFFSET(chlayout_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+{NULL},
+};
+
+AVFILTER_DEFINE_CLASS(aevalsrc);
+
+static int init(AVFilterContext *ctx, const char *args)
+{
+    EvalContext *eval = ctx->priv;
+    char *args1 = av_strdup(args);
+    char *expr, *buf, *bufptr;
+    int ret, i;
+
+    eval->class = &aevalsrc_class;
+    av_opt_set_defaults(eval);
+
+    if (!args1) {
+        av_log(ctx, AV_LOG_ERROR, "Argument is empty\n");
+        ret = args ? AVERROR(ENOMEM) : AVERROR(EINVAL);
+        goto end;
+    }
+
+    /* parse expressions */
+    buf = args1;
+    i = 0;
+    while (expr = av_strtok(buf, ":", &bufptr)) {
+        ret = av_expr_parse(&eval->expr[i], expr, var_names,
+                            NULL, NULL, NULL, NULL, 0, ctx);
+        if (ret < 0)
+            goto end;
+        i++;
+        if (bufptr && *bufptr == ':') { /* found last expression */
+            bufptr++;
+            break;
+        }
+        buf = NULL;
+    }
+    eval->nb_channels = i;
+
+    if (bufptr && (ret = av_set_options_string(eval, bufptr, "=", ":")) < 0)
+        goto end;
+
+    if (eval->chlayout_str) {
+        int n;
+        ret = ff_parse_channel_layout(&eval->chlayout, eval->chlayout_str, ctx);
+        if (ret < 0)
+            goto end;
+
+        n = av_get_channel_layout_nb_channels(eval->chlayout);
+        if (n != eval->nb_channels) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Mismatch between the specified number of channels '%d' "
+                   "and the number of channels '%d' in the specified channel layout '%s'\n",
+                   eval->nb_channels, n, eval->chlayout_str);
+            ret = AVERROR(EINVAL);
+            goto end;
+        }
+    } else {
+        /* guess channel layout from nb expressions/channels */
+        eval->chlayout = av_get_default_channel_layout(eval->nb_channels);
+        if (!eval->chlayout) {
+            av_log(ctx, AV_LOG_ERROR, "Invalid number of channels '%d' provided\n",
+                   eval->nb_channels);
+            ret = AVERROR(EINVAL);
+            goto end;
+        }
+    }
+
+    if ((ret = ff_parse_sample_rate(&eval->sample_rate, eval->sample_rate_str, ctx)))
+        goto end;
+
+    eval->duration = -1;
+    if (eval->duration_str) {
+        int64_t us = -1;
+        if ((ret = av_parse_time(&us, eval->duration_str, 1)) < 0) {
+            av_log(ctx, AV_LOG_ERROR, "Invalid duration: '%s'\n", eval->duration_str);
+            goto end;
+        }
+        eval->duration = (double)us / 1000000;
+    }
+    eval->n = 0;
+
+end:
+    av_free(args1);
+    return ret;
+}
+
+static void uninit(AVFilterContext *ctx)
+{
+    EvalContext *eval = ctx->priv;
+    int i;
+
+    for (i = 0; i < 8; i++) {
+        av_expr_free(eval->expr[i]);
+        eval->expr[i] = NULL;
+    }
+    av_freep(&eval->chlayout_str);
+    av_freep(&eval->duration_str);
+    av_freep(&eval->sample_rate_str);
+}
+
+static int config_props(AVFilterLink *outlink)
+{
+    EvalContext *eval = outlink->src->priv;
+    char buf[128];
+
+    outlink->time_base = (AVRational){1, eval->sample_rate};
+    outlink->sample_rate = eval->sample_rate;
+
+    eval->var_values[VAR_S] = eval->sample_rate;
+
+    av_get_channel_layout_string(buf, sizeof(buf), 0, eval->chlayout);
+
+    av_log(outlink->src, AV_LOG_VERBOSE,
+           "sample_rate:%d chlayout:%s duration:%f\n",
+           eval->sample_rate, buf, eval->duration);
+
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    EvalContext *eval = ctx->priv;
+    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 };
+
+    ff_set_common_formats (ctx, ff_make_format_list(sample_fmts));
+    ff_set_common_channel_layouts(ctx, avfilter_make_format64_list(chlayouts));
+    ff_set_common_samplerates(ctx, ff_make_format_list(sample_rates));
+
+    return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    EvalContext *eval = outlink->src->priv;
+    AVFilterBufferRef *samplesref;
+    int i, j;
+    double t = eval->var_values[VAR_N] * (double)1/eval->sample_rate;
+
+    if (eval->duration >= 0 && t > eval->duration)
+        return AVERROR_EOF;
+
+    samplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, eval->nb_samples);
+
+    /* evaluate expression for each single sample and for each channel */
+    for (i = 0; i < eval->nb_samples; i++, eval->n++) {
+        eval->var_values[VAR_N] = eval->n;
+        eval->var_values[VAR_T] = eval->var_values[VAR_N] * (double)1/eval->sample_rate;
+
+        for (j = 0; j < eval->nb_channels; j++) {
+            *((double *) samplesref->extended_data[j] + i) =
+                av_expr_eval(eval->expr[j], eval->var_values, NULL);
+        }
+    }
+
+    samplesref->pts = eval->pts;
+    samplesref->pos = -1;
+    samplesref->audio->sample_rate = eval->sample_rate;
+    eval->pts += eval->nb_samples;
+
+    ff_filter_samples(outlink, samplesref);
+
+    return 0;
+}
+
+AVFilter avfilter_asrc_aevalsrc = {
+    .name        = "aevalsrc",
+    .description = NULL_IF_CONFIG_SMALL("Generate an audio signal generated by an expression."),
+
+    .query_formats = query_formats,
+    .init        = init,
+    .uninit      = uninit,
+    .priv_size   = sizeof(EvalContext),
+
+    .inputs      = (const AVFilterPad[]) {{ .name = NULL}},
+
+    .outputs     = (const AVFilterPad[]) {{ .name = "default",
+                                      .type = AVMEDIA_TYPE_AUDIO,
+                                      .config_props = config_props,
+                                      .request_frame = request_frame, },
+                                    { .name = NULL}},
+    .priv_class = &aevalsrc_class,
+};
diff --git a/libavfilter/asrc_anullsrc.c b/libavfilter/asrc_anullsrc.c
index 7096cea..3b20aca 100644
--- a/libavfilter/asrc_anullsrc.c
+++ b/libavfilter/asrc_anullsrc.c
@@ -1,18 +1,21 @@
 /*
- * This file is part of Libav.
+ * Copyright 2010 S.N. Hemanth Meenakshisundaram <smeenaks ucsd edu>
+ * Copyright 2010 Stefano Sabatini <stefano.sabatini-lala poste it>
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,64 +27,96 @@
 #include <inttypes.h>
 #include <stdio.h>
 
+#include "audio.h"
 #include "avfilter.h"
 #include "internal.h"
+
 #include "libavutil/audioconvert.h"
 #include "libavutil/internal.h"
+#include "libavutil/opt.h"
 
 typedef struct {
+    const AVClass *class;
+    char   *channel_layout_str;
     uint64_t channel_layout;
-    int64_t sample_rate;
+    char   *sample_rate_str;
+    int     sample_rate;
+    int nb_samples;             ///< number of samples per requested frame
+    int64_t pts;
 } ANullContext;
 
+#define OFFSET(x) offsetof(ANullContext, x)
+#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption anullsrc_options[]= {
+    { "channel_layout", "set channel_layout", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0, FLAGS },
+    { "cl",             "set channel_layout", OFFSET(channel_layout_str), AV_OPT_TYPE_STRING, {.str = "stereo"}, 0, 0, FLAGS },
+    { "sample_rate",    "set sample rate",    OFFSET(sample_rate_str)   , AV_OPT_TYPE_STRING, {.str = "44100"}, 0, 0, FLAGS },
+    { "r",              "set sample rate",    OFFSET(sample_rate_str)   , AV_OPT_TYPE_STRING, {.str = "44100"}, 0, 0, FLAGS },
+    { "nb_samples",     "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 0, INT_MAX, FLAGS },
+    { "n",              "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 0, INT_MAX, FLAGS },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(anullsrc);
+
 static int init(AVFilterContext *ctx, const char *args)
 {
-    ANullContext *priv = ctx->priv;
-    char channel_layout_str[128] = "";
+    ANullContext *null = ctx->priv;
+    int ret;
 
-    priv->sample_rate = 44100;
-    priv->channel_layout = AV_CH_LAYOUT_STEREO;
+    null->class = &anullsrc_class;
+    av_opt_set_defaults(null);
 
-    if (args)
-        sscanf(args, "%"PRId64":%s", &priv->sample_rate, channel_layout_str);
+    if ((ret = (av_set_options_string(null, args, "=", ":"))) < 0)
+        return ret;
 
-    if (priv->sample_rate < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid negative sample rate: %"PRId64"\n", priv->sample_rate);
-        return AVERROR(EINVAL);
-    }
+    if ((ret = ff_parse_sample_rate(&null->sample_rate,
+                                     null->sample_rate_str, ctx)) < 0)
+        return ret;
 
-    if (*channel_layout_str)
-        if (!(priv->channel_layout = av_get_channel_layout(channel_layout_str))
-            && sscanf(channel_layout_str, "%"PRId64, &priv->channel_layout) != 1) {
-            av_log(ctx, AV_LOG_ERROR, "Invalid value '%s' for channel layout\n",
-                   channel_layout_str);
-            return AVERROR(EINVAL);
-        }
+    if ((ret = ff_parse_channel_layout(&null->channel_layout,
+                                        null->channel_layout_str, ctx)) < 0)
+        return ret;
 
     return 0;
 }
 
 static int config_props(AVFilterLink *outlink)
 {
-    ANullContext *priv = outlink->src->priv;
+    ANullContext *null = outlink->src->priv;
     char buf[128];
     int chans_nb;
 
-    outlink->sample_rate = priv->sample_rate;
-    outlink->channel_layout = priv->channel_layout;
+    outlink->sample_rate = null->sample_rate;
+    outlink->channel_layout = null->channel_layout;
 
-    chans_nb = av_get_channel_layout_nb_channels(priv->channel_layout);
-    av_get_channel_layout_string(buf, sizeof(buf), chans_nb, priv->channel_layout);
+    chans_nb = av_get_channel_layout_nb_channels(null->channel_layout);
+    av_get_channel_layout_string(buf, sizeof(buf), chans_nb, null->channel_layout);
     av_log(outlink->src, AV_LOG_VERBOSE,
-           "sample_rate:%"PRId64 " channel_layout:%"PRId64 " channel_layout_description:'%s'\n",
-           priv->sample_rate, priv->channel_layout, buf);
+           "sample_rate:%d channel_layout:'%s' nb_samples:%d\n",
+           null->sample_rate, buf, null->nb_samples);
 
     return 0;
 }
 
-static int request_frame(AVFilterLink *link)
+static int request_frame(AVFilterLink *outlink)
 {
-    return -1;
+    ANullContext *null = outlink->src->priv;
+    AVFilterBufferRef *samplesref;
+
+    samplesref =
+        ff_get_audio_buffer(outlink, AV_PERM_WRITE, null->nb_samples);
+    samplesref->pts = null->pts;
+    samplesref->pos = -1;
+    samplesref->audio->channel_layout = null->channel_layout;
+    samplesref->audio->sample_rate = outlink->sample_rate;
+
+    ff_filter_samples(outlink, avfilter_ref_buffer(samplesref, ~0));
+    avfilter_unref_buffer(samplesref);
+
+    null->pts += null->nb_samples;
+    return 0;
 }
 
 static const AVFilterPad avfilter_asrc_anullsrc_outputs[] = {
@@ -96,7 +131,7 @@
 
 AVFilter avfilter_asrc_anullsrc = {
     .name        = "anullsrc",
-    .description = NULL_IF_CONFIG_SMALL("Null audio source, never return audio frames."),
+    .description = NULL_IF_CONFIG_SMALL("Null audio source, return empty audio frames."),
 
     .init        = init,
     .priv_size   = sizeof(ANullContext),
@@ -104,4 +139,5 @@
     .inputs      = NULL,
 
     .outputs     = avfilter_asrc_anullsrc_outputs,
+    .priv_class = &anullsrc_class,
 };
diff --git a/libavfilter/asrc_flite.c b/libavfilter/asrc_flite.c
new file mode 100644
index 0000000..6f8cc95
--- /dev/null
+++ b/libavfilter/asrc_flite.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2012 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
+ * flite voice synth source
+ */
+
+#include <flite/flite.h>
+#include "libavutil/audioconvert.h"
+#include "libavutil/file.h"
+#include "libavutil/opt.h"
+#include "avfilter.h"
+#include "audio.h"
+#include "formats.h"
+#include "internal.h"
+
+typedef struct {
+    const AVClass *class;
+    char *voice_str;
+    char *textfile;
+    char *text;
+    cst_wave *wave;
+    int16_t *wave_samples;
+    int      wave_nb_samples;
+    int list_voices;
+    cst_voice *voice;
+    struct voice_entry *voice_entry;
+    int64_t pts;
+    int frame_nb_samples; ///< number of samples per frame
+} FliteContext;
+
+#define OFFSET(x) offsetof(FliteContext, x)
+#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption flite_options[] = {
+    { "list_voices", "list voices and exit",              OFFSET(list_voices), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS },
+    { "nb_samples",  "set number of samples per frame",   OFFSET(frame_nb_samples), AV_OPT_TYPE_INT, {.i64=512}, 0, INT_MAX, FLAGS },
+    { "n",           "set number of samples per frame",   OFFSET(frame_nb_samples), AV_OPT_TYPE_INT, {.i64=512}, 0, INT_MAX, FLAGS },
+    { "text",        "set text to speak",                 OFFSET(text),      AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "textfile",    "set filename of the text to speak", OFFSET(textfile),  AV_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "v",           "set voice",                         OFFSET(voice_str), AV_OPT_TYPE_STRING, {.str="kal"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "voice",       "set voice",                         OFFSET(voice_str), AV_OPT_TYPE_STRING, {.str="kal"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(flite);
+
+static volatile int flite_inited = 0;
+
+/* declare functions for all the supported voices */
+#define DECLARE_REGISTER_VOICE_FN(name) \
+    cst_voice *register_cmu_us_## name(const char *); \
+    void     unregister_cmu_us_## name(cst_voice *);
+DECLARE_REGISTER_VOICE_FN(awb);
+DECLARE_REGISTER_VOICE_FN(kal);
+DECLARE_REGISTER_VOICE_FN(kal16);
+DECLARE_REGISTER_VOICE_FN(rms);
+DECLARE_REGISTER_VOICE_FN(slt);
+
+struct voice_entry {
+    const char *name;
+    cst_voice * (*register_fn)(const char *);
+    void (*unregister_fn)(cst_voice *);
+    cst_voice *voice;
+    unsigned usage_count;
+} voice_entry;
+
+#define MAKE_VOICE_STRUCTURE(voice_name) {             \
+    .name          =                      #voice_name, \
+    .register_fn   =   register_cmu_us_ ## voice_name, \
+    .unregister_fn = unregister_cmu_us_ ## voice_name, \
+}
+static struct voice_entry voice_entries[] = {
+    MAKE_VOICE_STRUCTURE(awb),
+    MAKE_VOICE_STRUCTURE(kal),
+    MAKE_VOICE_STRUCTURE(kal16),
+    MAKE_VOICE_STRUCTURE(rms),
+    MAKE_VOICE_STRUCTURE(slt),
+};
+
+static void list_voices(void *log_ctx, const char *sep)
+{
+    int i, n = FF_ARRAY_ELEMS(voice_entries);
+    for (i = 0; i < n; i++)
+        av_log(log_ctx, AV_LOG_INFO, "%s%s",
+               voice_entries[i].name, i < (n-1) ? sep : "\n");
+}
+
+static int select_voice(struct voice_entry **entry_ret, const char *voice_name, void *log_ctx)
+{
+    int i;
+
+    for (i = 0; i < FF_ARRAY_ELEMS(voice_entries); i++) {
+        struct voice_entry *entry = &voice_entries[i];
+        if (!strcmp(entry->name, voice_name)) {
+            if (!entry->voice)
+                entry->voice = entry->register_fn(NULL);
+            if (!entry->voice) {
+                av_log(log_ctx, AV_LOG_ERROR,
+                       "Could not register voice '%s'\n", voice_name);
+                return AVERROR_UNKNOWN;
+            }
+            entry->usage_count++;
+            *entry_ret = entry;
+            return 0;
+        }
+    }
+
+    av_log(log_ctx, AV_LOG_ERROR, "Could not find voice '%s'\n", voice_name);
+    av_log(log_ctx, AV_LOG_INFO, "Choose between the voices: ");
+    list_voices(log_ctx, ", ");
+
+    return AVERROR(EINVAL);
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    FliteContext *flite = ctx->priv;
+    int ret = 0;
+
+    flite->class = &flite_class;
+    av_opt_set_defaults(flite);
+
+    if ((ret = av_set_options_string(flite, args, "=", ":")) < 0)
+        return ret;
+
+    if (flite->list_voices) {
+        list_voices(ctx, "\n");
+        return AVERROR_EXIT;
+    }
+
+    if (!flite_inited) {
+        if (flite_init() < 0) {
+            av_log(ctx, AV_LOG_ERROR, "flite initialization failed\n");
+            return AVERROR_UNKNOWN;
+        }
+        flite_inited++;
+    }
+
+    if ((ret = select_voice(&flite->voice_entry, flite->voice_str, ctx)) < 0)
+        return ret;
+    flite->voice = flite->voice_entry->voice;
+
+    if (flite->textfile && flite->text) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Both text and textfile options set: only one must be specified\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (flite->textfile) {
+        uint8_t *textbuf;
+        size_t textbuf_size;
+
+        if ((ret = av_file_map(flite->textfile, &textbuf, &textbuf_size, 0, ctx)) < 0) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "The text file '%s' could not be read: %s\n",
+                   flite->textfile, av_err2str(ret));
+            return ret;
+        }
+
+        if (!(flite->text = av_malloc(textbuf_size+1)))
+            return AVERROR(ENOMEM);
+        memcpy(flite->text, textbuf, textbuf_size);
+        flite->text[textbuf_size] = 0;
+        av_file_unmap(textbuf, textbuf_size);
+    }
+
+    if (!flite->text) {
+        av_log(ctx, AV_LOG_ERROR,
+               "No speech text specified, specify the 'text' or 'textfile' option\n");
+        return AVERROR(EINVAL);
+    }
+
+    /* synth all the file data in block */
+    flite->wave = flite_text_to_wave(flite->text, flite->voice);
+    flite->wave_samples    = flite->wave->samples;
+    flite->wave_nb_samples = flite->wave->num_samples;
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    FliteContext *flite = ctx->priv;
+
+    av_opt_free(flite);
+
+    if (!--flite->voice_entry->usage_count)
+        flite->voice_entry->unregister_fn(flite->voice);
+    flite->voice = NULL;
+    flite->voice_entry = NULL;
+    delete_wave(flite->wave);
+    flite->wave = NULL;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    FliteContext *flite = ctx->priv;
+
+    AVFilterChannelLayouts *chlayouts = NULL;
+    int64_t chlayout = av_get_default_channel_layout(flite->wave->num_channels);
+    AVFilterFormats *sample_formats = NULL;
+    AVFilterFormats *sample_rates = NULL;
+
+    ff_add_channel_layout(&chlayouts, chlayout);
+    ff_set_common_channel_layouts(ctx, chlayouts);
+    ff_add_format(&sample_formats, AV_SAMPLE_FMT_S16);
+    ff_set_common_formats(ctx, sample_formats);
+    ff_add_format(&sample_rates, flite->wave->sample_rate);
+    ff_set_common_samplerates (ctx, sample_rates);
+
+    return 0;
+}
+
+static int config_props(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    FliteContext *flite = ctx->priv;
+
+    outlink->sample_rate = flite->wave->sample_rate;
+    outlink->time_base = (AVRational){1, flite->wave->sample_rate};
+
+    av_log(ctx, AV_LOG_VERBOSE, "voice:%s fmt:%s sample_rate:%d\n",
+           flite->voice_str,
+           av_get_sample_fmt_name(outlink->format), outlink->sample_rate);
+    return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterBufferRef *samplesref;
+    FliteContext *flite = outlink->src->priv;
+    int nb_samples = FFMIN(flite->wave_nb_samples, flite->frame_nb_samples);
+
+    if (!nb_samples)
+        return AVERROR_EOF;
+
+    samplesref = ff_get_audio_buffer(outlink, AV_PERM_WRITE, nb_samples);
+    if (!samplesref)
+        return AVERROR(ENOMEM);
+
+    memcpy(samplesref->data[0], flite->wave_samples,
+           nb_samples * flite->wave->num_channels * 2);
+    samplesref->pts = flite->pts;
+    samplesref->pos = -1;
+    samplesref->audio->sample_rate = flite->wave->sample_rate;
+    flite->pts += nb_samples;
+    flite->wave_samples += nb_samples * flite->wave->num_channels;
+    flite->wave_nb_samples -= nb_samples;
+
+    return ff_filter_samples(outlink, samplesref);
+}
+
+AVFilter avfilter_asrc_flite = {
+    .name        = "flite",
+    .description = NULL_IF_CONFIG_SMALL("Synthesize voice from text using libflite."),
+    .query_formats = query_formats,
+    .init        = init,
+    .uninit      = uninit,
+    .priv_size   = sizeof(FliteContext),
+
+    .inputs = (const AVFilterPad[]) {{ .name = NULL}},
+
+    .outputs = (const AVFilterPad[]) {
+        {
+            .name = "default",
+            .type = AVMEDIA_TYPE_AUDIO,
+            .config_props = config_props,
+            .request_frame = request_frame,
+        },
+        { .name = NULL }
+    },
+
+    .priv_class = &flite_class,
+};
diff --git a/libavfilter/audio.c b/libavfilter/audio.c
index 66010c1..06702a6 100644
--- a/libavfilter/audio.c
+++ b/libavfilter/audio.c
@@ -1,21 +1,25 @@
 /*
- * This file is part of Libav.
+ * Copyright (c) Stefano Sabatini | stefasab at gmail.com
+ * Copyright (c) S.N. Hemanth Meenakshisundaram | smeenaks at ucsd.edu
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/audioconvert.h"
 #include "libavutil/common.h"
 
@@ -38,6 +42,10 @@
     int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
     int planes      = planar ? nb_channels : 1;
     int linesize;
+    int full_perms = AV_PERM_READ | AV_PERM_WRITE | AV_PERM_PRESERVE |
+                     AV_PERM_REUSE | AV_PERM_REUSE2 | AV_PERM_ALIGN;
+
+    av_assert1(!(perms & ~(full_perms | AV_PERM_NEG_LINESIZES)));
 
     if (!(data = av_mallocz(sizeof(*data) * planes)))
         goto fail;
@@ -45,12 +53,14 @@
     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, perms,
+    samplesref = avfilter_get_audio_buffer_ref_from_arrays(data, linesize, full_perms,
                                                            nb_samples, link->format,
                                                            link->channel_layout);
     if (!samplesref)
         goto fail;
 
+    samplesref->audio->sample_rate = link->sample_rate;
+
     av_freep(&data);
 
 fail:
@@ -97,9 +107,9 @@
 
     samplesref->audio->nb_samples     = nb_samples;
     samplesref->audio->channel_layout = channel_layout;
-    samplesref->audio->planar         = av_sample_fmt_is_planar(sample_fmt);
 
-    planes = samplesref->audio->planar ? av_get_channel_layout_nb_channels(channel_layout) : 1;
+    planes = av_sample_fmt_is_planar(sample_fmt) ?
+        av_get_channel_layout_nb_channels(channel_layout) : 1;
 
     /* make sure the buffer gets read permission or it's useless for output */
     samplesref->perms = perms | AV_PERM_READ;
@@ -153,17 +163,28 @@
     return ff_filter_samples(link->dst->outputs[0], samplesref);
 }
 
-int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
+int ff_filter_samples_framed(AVFilterLink *link, AVFilterBufferRef *samplesref)
 {
     int (*filter_samples)(AVFilterLink *, AVFilterBufferRef *);
+    AVFilterPad *src = link->srcpad;
     AVFilterPad *dst = link->dstpad;
+    int64_t pts;
     AVFilterBufferRef *buf_out;
+    int ret;
 
-    FF_DPRINTF_START(NULL, filter_samples); ff_dlog_link(NULL, link, 1);
+    FF_TPRINTF_START(NULL, filter_samples); ff_tlog_link(NULL, link, 1);
+
+    if (link->closed) {
+        avfilter_unref_buffer(samplesref);
+        return AVERROR_EOF;
+    }
 
     if (!(filter_samples = dst->filter_samples))
         filter_samples = default_filter_samples;
 
+    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) {
@@ -190,6 +211,59 @@
     } else
         buf_out = samplesref;
 
-    return filter_samples(link, buf_out);
+    link->cur_buf = buf_out;
+    pts = buf_out->pts;
+    ret = filter_samples(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;
+}
diff --git a/libavfilter/audio.h b/libavfilter/audio.h
index fa448e2..a84c378 100644
--- a/libavfilter/audio.h
+++ b/libavfilter/audio.h
@@ -1,18 +1,21 @@
 /*
- * This file is part of Libav.
+ * Copyright (c) Stefano Sabatini | stefasab at gmail.com
+ * Copyright (c) S.N. Hemanth Meenakshisundaram | smeenaks at ucsd.edu
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -21,6 +24,24 @@
 
 #include "avfilter.h"
 
+static const enum AVSampleFormat ff_packed_sample_fmts_array[] = {
+    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 ff_planar_sample_fmts_array[] = {
+    AV_SAMPLE_FMT_U8P,
+    AV_SAMPLE_FMT_S16P,
+    AV_SAMPLE_FMT_S32P,
+    AV_SAMPLE_FMT_FLTP,
+    AV_SAMPLE_FMT_DBLP,
+    AV_SAMPLE_FMT_NONE
+};
+
 /** default handler for get_audio_buffer() for audio inputs */
 AVFilterBufferRef *ff_default_get_audio_buffer(AVFilterLink *link, int perms,
                                                      int nb_samples);
@@ -55,4 +76,11 @@
  */
 int ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref);
 
+/**
+ * Send a buffer of audio samples to the next link, without checking
+ * min_samples.
+ */
+int ff_filter_samples_framed(AVFilterLink *link,
+                              AVFilterBufferRef *samplesref);
+
 #endif /* AVFILTER_AUDIO_H */
diff --git a/libavfilter/avcodec.c b/libavfilter/avcodec.c
new file mode 100644
index 0000000..313080d
--- /dev/null
+++ b/libavfilter/avcodec.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2011 Stefano Sabatini | stefasab at 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
+ */
+
+/**
+ * @file
+ * libavcodec/libavfilter gluing utilities
+ */
+
+#include "avcodec.h"
+#include "libavutil/avassert.h"
+#include "libavutil/opt.h"
+
+int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src)
+{
+    dst->pts    = src->pts;
+    dst->pos    = av_frame_get_pkt_pos(src);
+    dst->format = src->format;
+
+    switch (dst->type) {
+    case AVMEDIA_TYPE_VIDEO:
+        dst->video->w                   = src->width;
+        dst->video->h                   = src->height;
+        dst->video->sample_aspect_ratio = src->sample_aspect_ratio;
+        dst->video->interlaced          = src->interlaced_frame;
+        dst->video->top_field_first     = src->top_field_first;
+        dst->video->key_frame           = src->key_frame;
+        dst->video->pict_type           = src->pict_type;
+        av_freep(&dst->video->qp_table);
+        dst->video->qp_table_linesize = 0;
+        if (src->qscale_table) {
+            int qsize = src->qstride ? src->qstride * ((src->height+15)/16) : (src->width+15)/16;
+            dst->video->qp_table = av_malloc(qsize);
+            if (!dst->video->qp_table)
+                return AVERROR(ENOMEM);
+            dst->video->qp_table_linesize = src->qstride;
+            dst->video->qp_table_size     = qsize;
+            memcpy(dst->video->qp_table, src->qscale_table, qsize);
+        }
+        break;
+    case AVMEDIA_TYPE_AUDIO:
+        dst->audio->sample_rate         = src->sample_rate;
+        dst->audio->channel_layout      = src->channel_layout;
+        break;
+    default:
+        return AVERROR(EINVAL);
+    }
+
+    return 0;
+}
+
+AVFilterBufferRef *avfilter_get_video_buffer_ref_from_frame(const AVFrame *frame,
+                                                            int perms)
+{
+    AVFilterBufferRef *picref =
+        avfilter_get_video_buffer_ref_from_arrays(frame->data, frame->linesize, perms,
+                                                  frame->width, frame->height,
+                                                  frame->format);
+    if (!picref)
+        return NULL;
+    avfilter_copy_frame_props(picref, frame);
+    return picref;
+}
+
+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));
+    if (!samplesref)
+        return NULL;
+    avfilter_copy_frame_props(samplesref, frame);
+    return samplesref;
+}
+
+AVFilterBufferRef *avfilter_get_buffer_ref_from_frame(enum AVMediaType type,
+                                                      const AVFrame *frame,
+                                                      int perms)
+{
+    switch (type) {
+    case AVMEDIA_TYPE_VIDEO:
+        return avfilter_get_video_buffer_ref_from_frame(frame, perms);
+    case AVMEDIA_TYPE_AUDIO:
+        return avfilter_get_audio_buffer_ref_from_frame(frame, perms);
+    default:
+        return NULL;
+    }
+}
+
+int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src)
+{
+    int planes, nb_channels;
+
+    if (!dst)
+        return AVERROR(EINVAL);
+    /* abort in case the src is NULL and dst is not, avoid inconsistent state in dst */
+    av_assert0(src);
+
+    memcpy(dst->data, src->data, sizeof(dst->data));
+    memcpy(dst->linesize, src->linesize, sizeof(dst->linesize));
+
+    dst->pts     = src->pts;
+    dst->format  = src->format;
+    av_frame_set_pkt_pos(dst, src->pos);
+
+    switch (src->type) {
+    case AVMEDIA_TYPE_VIDEO:
+        av_assert0(src->video);
+        dst->width               = src->video->w;
+        dst->height              = src->video->h;
+        dst->sample_aspect_ratio = src->video->sample_aspect_ratio;
+        dst->interlaced_frame    = src->video->interlaced;
+        dst->top_field_first     = src->video->top_field_first;
+        dst->key_frame           = src->video->key_frame;
+        dst->pict_type           = src->video->pict_type;
+        break;
+    case AVMEDIA_TYPE_AUDIO:
+        av_assert0(src->audio);
+        nb_channels = av_get_channel_layout_nb_channels(src->audio->channel_layout);
+        planes      = av_sample_fmt_is_planar(src->format) ? nb_channels : 1;
+
+        if (planes > FF_ARRAY_ELEMS(dst->data)) {
+            dst->extended_data = av_mallocz(planes * sizeof(*dst->extended_data));
+            if (!dst->extended_data)
+                return AVERROR(ENOMEM);
+            memcpy(dst->extended_data, src->extended_data,
+                   planes * sizeof(*dst->extended_data));
+        } else
+            dst->extended_data = dst->data;
+        dst->nb_samples          = src->audio->nb_samples;
+        av_frame_set_sample_rate   (dst, src->audio->sample_rate);
+        av_frame_set_channel_layout(dst, src->audio->channel_layout);
+        break;
+    default:
+        return AVERROR(EINVAL);
+    }
+
+    return 0;
+}
+
+#ifdef FF_API_FILL_FRAME
+int avfilter_fill_frame_from_audio_buffer_ref(AVFrame *frame,
+                                              const AVFilterBufferRef *samplesref)
+{
+    return avfilter_copy_buf_props(frame, samplesref);
+}
+
+int avfilter_fill_frame_from_video_buffer_ref(AVFrame *frame,
+                                              const AVFilterBufferRef *picref)
+{
+    return avfilter_copy_buf_props(frame, picref);
+}
+
+int avfilter_fill_frame_from_buffer_ref(AVFrame *frame,
+                                        const AVFilterBufferRef *ref)
+{
+    return avfilter_copy_buf_props(frame, ref);
+}
+#endif
diff --git a/libavfilter/avcodec.h b/libavfilter/avcodec.h
new file mode 100644
index 0000000..5f4209a
--- /dev/null
+++ b/libavfilter/avcodec.h
@@ -0,0 +1,131 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVFILTER_AVCODEC_H
+#define AVFILTER_AVCODEC_H
+
+/**
+ * @file
+ * libavcodec/libavfilter gluing utilities
+ *
+ * This should be included in an application ONLY if the installed
+ * libavfilter has been compiled with libavcodec support, otherwise
+ * symbols defined below will not be available.
+ */
+
+#include "libavcodec/avcodec.h" // AVFrame
+#include "avfilter.h"
+
+/**
+ * Copy the frame properties of src to dst, without copying the actual
+ * image data.
+ *
+ * @return 0 on success, a negative number on error.
+ */
+int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src);
+
+/**
+ * Copy the frame properties and data pointers of src to dst, without copying
+ * the actual data.
+ *
+ * @return 0 on success, a negative number on error.
+ */
+int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src);
+
+/**
+ * Create and return a picref reference from the data and properties
+ * contained in frame.
+ *
+ * @param perms permissions to assign to the new buffer reference
+ */
+AVFilterBufferRef *avfilter_get_video_buffer_ref_from_frame(const AVFrame *frame, int perms);
+
+
+/**
+ * Create and return a picref reference from the data and properties
+ * contained in frame.
+ *
+ * @param perms permissions to assign to the new buffer reference
+ */
+AVFilterBufferRef *avfilter_get_audio_buffer_ref_from_frame(const AVFrame *frame,
+                                                            int perms);
+
+/**
+ * Create and return a buffer reference from the data and properties
+ * contained in frame.
+ *
+ * @param perms permissions to assign to the new buffer reference
+ */
+AVFilterBufferRef *avfilter_get_buffer_ref_from_frame(enum AVMediaType type,
+                                                      const AVFrame *frame,
+                                                      int perms);
+
+#ifdef FF_API_FILL_FRAME
+/**
+ * Fill an AVFrame with the information stored in samplesref.
+ *
+ * @param frame an already allocated AVFrame
+ * @param samplesref an audio buffer reference
+ * @return 0 in case of success, a negative AVERROR code in case of
+ * failure
+ * @deprecated Use avfilter_copy_buf_props() instead.
+ */
+attribute_deprecated
+int avfilter_fill_frame_from_audio_buffer_ref(AVFrame *frame,
+                                              const AVFilterBufferRef *samplesref);
+
+/**
+ * Fill an AVFrame with the information stored in picref.
+ *
+ * @param frame an already allocated AVFrame
+ * @param picref a video buffer reference
+ * @return 0 in case of success, a negative AVERROR code in case of
+ * failure
+ * @deprecated Use avfilter_copy_buf_props() instead.
+ */
+attribute_deprecated
+int avfilter_fill_frame_from_video_buffer_ref(AVFrame *frame,
+                                              const AVFilterBufferRef *picref);
+
+/**
+ * Fill an AVFrame with information stored in ref.
+ *
+ * @param frame an already allocated AVFrame
+ * @param ref a video or audio buffer reference
+ * @return 0 in case of success, a negative AVERROR code in case of
+ * failure
+ * @deprecated Use avfilter_copy_buf_props() instead.
+ */
+attribute_deprecated
+int avfilter_fill_frame_from_buffer_ref(AVFrame *frame,
+                                        const AVFilterBufferRef *ref);
+#endif
+
+/**
+ * Add frame data to buffer_src.
+ *
+ * @param buffer_src  pointer to a buffer source context
+ * @param frame       a frame, or NULL to mark EOF
+ * @param flags       a combination of AV_BUFFERSRC_FLAG_*
+ * @return            >= 0 in case of success, a negative AVERROR code
+ *                    in case of failure
+ */
+int av_buffersrc_add_frame(AVFilterContext *buffer_src,
+                           const AVFrame *frame, int flags);
+
+#endif /* AVFILTER_AVCODEC_H */
diff --git a/libavfilter/avf_concat.c b/libavfilter/avf_concat.c
new file mode 100644
index 0000000..c0bd621
--- /dev/null
+++ b/libavfilter/avf_concat.c
@@ -0,0 +1,446 @@
+/*
+ * 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
+ */
+
+/**
+ * @file
+ * concat audio-video filter
+ */
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
+#include "libavutil/opt.h"
+#include "avfilter.h"
+#define FF_BUFQUEUE_SIZE 256
+#include "bufferqueue.h"
+#include "internal.h"
+#include "video.h"
+#include "audio.h"
+
+#define TYPE_ALL 2
+
+typedef struct {
+    const AVClass *class;
+    unsigned nb_streams[TYPE_ALL]; /**< number of out streams of each type */
+    unsigned nb_segments;
+    unsigned cur_idx; /**< index of the first input of current segment */
+    int64_t delta_ts; /**< timestamp to add to produce output timestamps */
+    unsigned nb_in_active; /**< number of active inputs in current segment */
+    struct concat_in {
+        int64_t pts;
+        int64_t nb_frames;
+        unsigned eof;
+        struct FFBufQueue queue;
+    } *in;
+} ConcatContext;
+
+#define OFFSET(x) offsetof(ConcatContext, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM
+#define F AV_OPT_FLAG_FILTERING_PARAM
+#define V AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption concat_options[] = {
+    { "n", "specify the number of segments", OFFSET(nb_segments),
+      AV_OPT_TYPE_INT, { .i64 = 2 }, 2, INT_MAX, V|A|F},
+    { "v", "specify the number of video streams",
+      OFFSET(nb_streams[AVMEDIA_TYPE_VIDEO]),
+      AV_OPT_TYPE_INT, { .i64 = 1 }, 0, INT_MAX, V|F },
+    { "a", "specify the number of audio streams",
+      OFFSET(nb_streams[AVMEDIA_TYPE_AUDIO]),
+      AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, A|F},
+    { 0 }
+};
+
+AVFILTER_DEFINE_CLASS(concat);
+
+static int query_formats(AVFilterContext *ctx)
+{
+    ConcatContext *cat = ctx->priv;
+    unsigned type, nb_str, idx0 = 0, idx, str, seg;
+    AVFilterFormats *formats, *rates;
+    AVFilterChannelLayouts *layouts;
+
+    for (type = 0; type < TYPE_ALL; type++) {
+        nb_str = cat->nb_streams[type];
+        for (str = 0; str < nb_str; str++) {
+            idx = idx0;
+
+            /* Set the output formats */
+            formats = ff_all_formats(type);
+            if (!formats)
+                return AVERROR(ENOMEM);
+            ff_formats_ref(formats, &ctx->outputs[idx]->in_formats);
+            if (type == AVMEDIA_TYPE_AUDIO) {
+                rates = ff_all_samplerates();
+                if (!rates)
+                    return AVERROR(ENOMEM);
+                ff_formats_ref(rates, &ctx->outputs[idx]->in_samplerates);
+                layouts = ff_all_channel_layouts();
+                if (!layouts)
+                    return AVERROR(ENOMEM);
+                ff_channel_layouts_ref(layouts, &ctx->outputs[idx]->in_channel_layouts);
+            }
+
+            /* Set the same formats for each corresponding input */
+            for (seg = 0; seg < cat->nb_segments; seg++) {
+                ff_formats_ref(formats, &ctx->inputs[idx]->out_formats);
+                if (type == AVMEDIA_TYPE_AUDIO) {
+                    ff_formats_ref(rates, &ctx->inputs[idx]->out_samplerates);
+                    ff_channel_layouts_ref(layouts, &ctx->inputs[idx]->out_channel_layouts);
+                }
+                idx += ctx->nb_outputs;
+            }
+
+            idx0++;
+        }
+    }
+    return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    ConcatContext *cat   = ctx->priv;
+    unsigned out_no = FF_OUTLINK_IDX(outlink);
+    unsigned in_no  = out_no, seg;
+    AVFilterLink *inlink = ctx->inputs[in_no];
+
+    /* enhancement: find a common one */
+    outlink->time_base           = AV_TIME_BASE_Q;
+    outlink->w                   = inlink->w;
+    outlink->h                   = inlink->h;
+    outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
+    outlink->format              = inlink->format;
+    for (seg = 1; seg < cat->nb_segments; seg++) {
+        inlink = ctx->inputs[in_no += ctx->nb_outputs];
+        /* possible enhancement: unsafe mode, do not check */
+        if (outlink->w                       != inlink->w                       ||
+            outlink->h                       != inlink->h                       ||
+            outlink->sample_aspect_ratio.num != inlink->sample_aspect_ratio.num ||
+            outlink->sample_aspect_ratio.den != inlink->sample_aspect_ratio.den) {
+            av_log(ctx, AV_LOG_ERROR, "Input link %s parameters "
+                   "(size %dx%d, SAR %d:%d) do not match the corresponding "
+                   "output link %s parameters (%dx%d, SAR %d:%d)\n",
+                   ctx->input_pads[in_no].name, inlink->w, inlink->h,
+                   inlink->sample_aspect_ratio.num,
+                   inlink->sample_aspect_ratio.den,
+                   ctx->input_pads[out_no].name, outlink->w, outlink->h,
+                   outlink->sample_aspect_ratio.num,
+                   outlink->sample_aspect_ratio.den);
+            return AVERROR(EINVAL);
+        }
+    }
+
+    return 0;
+}
+
+static void push_frame(AVFilterContext *ctx, unsigned in_no,
+                       AVFilterBufferRef *buf)
+{
+    ConcatContext *cat = ctx->priv;
+    unsigned out_no = in_no % ctx->nb_outputs;
+    AVFilterLink * inlink = ctx-> inputs[ in_no];
+    AVFilterLink *outlink = ctx->outputs[out_no];
+    struct concat_in *in = &cat->in[in_no];
+
+    buf->pts = av_rescale_q(buf->pts, inlink->time_base, outlink->time_base);
+    in->pts = buf->pts;
+    in->nb_frames++;
+    /* add duration to input PTS */
+    if (inlink->sample_rate)
+        /* use number of audio samples */
+        in->pts += av_rescale_q(buf->audio->nb_samples,
+                                (AVRational){ 1, inlink->sample_rate },
+                                outlink->time_base);
+    else if (in->nb_frames >= 2)
+        /* use mean duration */
+        in->pts = av_rescale(in->pts, in->nb_frames, in->nb_frames - 1);
+
+    buf->pts += cat->delta_ts;
+    switch (buf->type) {
+    case AVMEDIA_TYPE_VIDEO:
+        ff_start_frame(outlink, buf);
+        ff_draw_slice(outlink, 0, outlink->h, 1);
+        ff_end_frame(outlink);
+        break;
+    case AVMEDIA_TYPE_AUDIO:
+        ff_filter_samples(outlink, buf);
+        break;
+    }
+}
+
+static void process_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
+{
+    AVFilterContext *ctx  = inlink->dst;
+    ConcatContext *cat    = ctx->priv;
+    unsigned in_no = FF_INLINK_IDX(inlink);
+
+    if (in_no < cat->cur_idx) {
+        av_log(ctx, AV_LOG_ERROR, "Frame after EOF on input %s\n",
+               ctx->input_pads[in_no].name);
+        avfilter_unref_buffer(buf);
+    } if (in_no >= cat->cur_idx + ctx->nb_outputs) {
+        ff_bufqueue_add(ctx, &cat->in[in_no].queue, buf);
+    } else {
+        push_frame(ctx, in_no, buf);
+    }
+}
+
+static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms,
+                                           int w, int h)
+{
+    AVFilterContext *ctx = inlink->dst;
+    unsigned in_no = FF_INLINK_IDX(inlink);
+    AVFilterLink *outlink = ctx->outputs[in_no % ctx->nb_outputs];
+
+    return ff_get_video_buffer(outlink, perms, w, h);
+}
+
+static AVFilterBufferRef *get_audio_buffer(AVFilterLink *inlink, int perms,
+                                           int nb_samples)
+{
+    AVFilterContext *ctx = inlink->dst;
+    unsigned in_no = FF_INLINK_IDX(inlink);
+    AVFilterLink *outlink = ctx->outputs[in_no % ctx->nb_outputs];
+
+    return ff_get_audio_buffer(outlink, perms, nb_samples);
+}
+
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
+{
+    return 0;
+}
+
+static int draw_slice(AVFilterLink *inlink, int y, int h, int dir)
+{
+    return 0;
+}
+
+static int end_frame(AVFilterLink *inlink)
+{
+    process_frame(inlink, inlink->cur_buf);
+    inlink->cur_buf = NULL;
+    return 0;
+}
+
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf)
+{
+    process_frame(inlink, buf);
+    return 0; /* enhancement: handle error return */
+}
+
+static void close_input(AVFilterContext *ctx, unsigned in_no)
+{
+    ConcatContext *cat = ctx->priv;
+
+    cat->in[in_no].eof = 1;
+    cat->nb_in_active--;
+    av_log(ctx, AV_LOG_VERBOSE, "EOF on %s, %d streams left in segment.\n",
+           ctx->input_pads[in_no].name, cat->nb_in_active);
+}
+
+static void find_next_delta_ts(AVFilterContext *ctx)
+{
+    ConcatContext *cat = ctx->priv;
+    unsigned i = cat->cur_idx;
+    unsigned imax = i + ctx->nb_outputs;
+    int64_t pts;
+
+    pts = cat->in[i++].pts;
+    for (; i < imax; i++)
+        pts = FFMAX(pts, cat->in[i].pts);
+    cat->delta_ts += pts;
+}
+
+static void send_silence(AVFilterContext *ctx, unsigned in_no, unsigned out_no)
+{
+    ConcatContext *cat = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[out_no];
+    int64_t base_pts = cat->in[in_no].pts + cat->delta_ts;
+    int64_t nb_samples, sent = 0;
+    int frame_nb_samples;
+    AVRational rate_tb = { 1, ctx->inputs[in_no]->sample_rate };
+    AVFilterBufferRef *buf;
+    int nb_channels = av_get_channel_layout_nb_channels(outlink->channel_layout);
+
+    if (!rate_tb.den)
+        return;
+    nb_samples = av_rescale_q(cat->delta_ts - base_pts,
+                              outlink->time_base, rate_tb);
+    frame_nb_samples = FFMAX(9600, rate_tb.den / 5); /* arbitrary */
+    while (nb_samples) {
+        frame_nb_samples = FFMIN(frame_nb_samples, nb_samples);
+        buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE, frame_nb_samples);
+        if (!buf)
+            return;
+        av_samples_set_silence(buf->extended_data, 0, frame_nb_samples,
+                               nb_channels, outlink->format);
+        buf->pts = base_pts + av_rescale_q(sent, rate_tb, outlink->time_base);
+        ff_filter_samples(outlink, buf);
+        sent       += frame_nb_samples;
+        nb_samples -= frame_nb_samples;
+    }
+}
+
+static void flush_segment(AVFilterContext *ctx)
+{
+    ConcatContext *cat = ctx->priv;
+    unsigned str, str_max;
+
+    find_next_delta_ts(ctx);
+    cat->cur_idx += ctx->nb_outputs;
+    cat->nb_in_active = ctx->nb_outputs;
+    av_log(ctx, AV_LOG_VERBOSE, "Segment finished at pts=%"PRId64"\n",
+           cat->delta_ts);
+
+    if (cat->cur_idx < ctx->nb_inputs) {
+        /* pad audio streams with silence */
+        str = cat->nb_streams[AVMEDIA_TYPE_VIDEO];
+        str_max = str + cat->nb_streams[AVMEDIA_TYPE_AUDIO];
+        for (; str < str_max; str++)
+            send_silence(ctx, cat->cur_idx - ctx->nb_outputs + str, str);
+        /* flush queued buffers */
+        /* possible enhancement: flush in PTS order */
+        str_max = cat->cur_idx + ctx->nb_outputs;
+        for (str = cat->cur_idx; str < str_max; str++)
+            while (cat->in[str].queue.available)
+                push_frame(ctx, str, ff_bufqueue_get(&cat->in[str].queue));
+    }
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    ConcatContext *cat   = ctx->priv;
+    unsigned out_no = FF_OUTLINK_IDX(outlink);
+    unsigned in_no  = out_no + cat->cur_idx;
+    unsigned str, str_max;
+    int ret;
+
+    while (1) {
+        if (in_no >= ctx->nb_inputs)
+            return AVERROR_EOF;
+        if (!cat->in[in_no].eof) {
+            ret = ff_request_frame(ctx->inputs[in_no]);
+            if (ret != AVERROR_EOF)
+                return ret;
+            close_input(ctx, in_no);
+        }
+        /* cycle on all inputs to finish the segment */
+        /* possible enhancement: request in PTS order */
+        str_max = cat->cur_idx + ctx->nb_outputs - 1;
+        for (str = cat->cur_idx; cat->nb_in_active;
+             str = str == str_max ? cat->cur_idx : str + 1) {
+            if (cat->in[str].eof)
+                continue;
+            ret = ff_request_frame(ctx->inputs[str]);
+            if (ret == AVERROR_EOF)
+                close_input(ctx, str);
+            else if (ret < 0)
+                return ret;
+        }
+        flush_segment(ctx);
+        in_no += ctx->nb_outputs;
+    }
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    ConcatContext *cat = ctx->priv;
+    int ret;
+    unsigned seg, type, str;
+    char name[32];
+
+    cat->class = &concat_class;
+    av_opt_set_defaults(cat);
+    ret = av_set_options_string(cat, args, "=", ":");
+    if (ret < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Error parsing options: '%s'\n", args);
+        return ret;
+    }
+
+    /* create input pads */
+    for (seg = 0; seg < cat->nb_segments; seg++) {
+        for (type = 0; type < TYPE_ALL; type++) {
+            for (str = 0; str < cat->nb_streams[type]; str++) {
+                AVFilterPad pad = {
+                    .type             = type,
+                    .min_perms        = AV_PERM_READ | AV_PERM_PRESERVE,
+                    .get_video_buffer = get_video_buffer,
+                    .get_audio_buffer = get_audio_buffer,
+                };
+                snprintf(name, sizeof(name), "in%d:%c%d", seg, "va"[type], str);
+                pad.name = av_strdup(name);
+                if (type == AVMEDIA_TYPE_VIDEO) {
+                    pad.start_frame = start_frame;
+                    pad.draw_slice  = draw_slice;
+                    pad.end_frame   = end_frame;
+                } else {
+                    pad.filter_samples = filter_samples;
+                }
+                ff_insert_inpad(ctx, ctx->nb_inputs, &pad);
+            }
+        }
+    }
+    /* create output pads */
+    for (type = 0; type < TYPE_ALL; type++) {
+        for (str = 0; str < cat->nb_streams[type]; str++) {
+            AVFilterPad pad = {
+                .type          = type,
+                .config_props  = config_output,
+                .request_frame = request_frame,
+            };
+            snprintf(name, sizeof(name), "out:%c%d", "va"[type], str);
+            pad.name = av_strdup(name);
+            ff_insert_outpad(ctx, ctx->nb_outputs, &pad);
+        }
+    }
+
+    cat->in = av_calloc(ctx->nb_inputs, sizeof(*cat->in));
+    if (!cat->in)
+        return AVERROR(ENOMEM);
+    cat->nb_in_active = ctx->nb_outputs;
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    ConcatContext *cat = ctx->priv;
+    unsigned i;
+
+    for (i = 0; i < ctx->nb_inputs; i++) {
+        av_freep(&ctx->input_pads[i].name);
+        ff_bufqueue_discard_all(&cat->in[i].queue);
+    }
+    for (i = 0; i < ctx->nb_outputs; i++)
+        av_freep(&ctx->output_pads[i].name);
+    av_free(cat->in);
+}
+
+AVFilter avfilter_avf_concat = {
+    .name          = "concat",
+    .description   = NULL_IF_CONFIG_SMALL("Concatenate audio and video streams."),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .priv_size     = sizeof(ConcatContext),
+    .inputs        = (const AVFilterPad[]) { { .name = NULL } },
+    .outputs       = (const AVFilterPad[]) { { .name = NULL } },
+    .priv_class    = &concat_class,
+};
diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c
new file mode 100644
index 0000000..641c27f
--- /dev/null
+++ b/libavfilter/avf_showspectrum.c
@@ -0,0 +1,317 @@
+/*
+ * 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
+ * audio to spectrum (video) transmedia filter, based on ffplay rdft showmode
+ * (by Michael Niedermayer) and lavfi/avf_showwaves (by Stefano Sabatini).
+ */
+
+#include <math.h>
+
+#include "libavcodec/avfft.h"
+#include "libavutil/audioconvert.h"
+#include "libavutil/opt.h"
+#include "avfilter.h"
+#include "internal.h"
+
+typedef struct {
+    const AVClass *class;
+    int w, h;
+    AVFilterBufferRef *outpicref;
+    int req_fullfilled;
+    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
+    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
+} 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 },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(showspectrum);
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    ShowSpectrumContext *showspectrum = ctx->priv;
+    int err;
+
+    showspectrum->class = &showspectrum_class;
+    av_opt_set_defaults(showspectrum);
+
+    if ((err = av_set_options_string(showspectrum, args, "=", ":")) < 0)
+        return err;
+
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    ShowSpectrumContext *showspectrum = ctx->priv;
+
+    av_rdft_end(showspectrum->rdft);
+    av_freep(&showspectrum->rdft_data);
+    av_freep(&showspectrum->window_func_lut);
+    avfilter_unref_bufferp(&showspectrum->outpicref);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterFormats *formats = NULL;
+    AVFilterChannelLayouts *layouts = NULL;
+    AVFilterLink *inlink = ctx->inputs[0];
+    AVFilterLink *outlink = ctx->outputs[0];
+    static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16P, -1 };
+    static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_RGB24, -1 };
+
+    /* set input audio formats */
+    formats = ff_make_format_list(sample_fmts);
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_formats_ref(formats, &inlink->out_formats);
+
+    layouts = ff_all_channel_layouts();
+    if (!layouts)
+        return AVERROR(ENOMEM);
+    ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts);
+
+    formats = ff_all_samplerates();
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_formats_ref(formats, &inlink->out_samplerates);
+
+    /* set output video format */
+    formats = ff_make_format_list(pix_fmts);
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_formats_ref(formats, &outlink->in_formats);
+
+    return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    ShowSpectrumContext *showspectrum = ctx->priv;
+    int i, rdft_bits, win_size;
+
+    outlink->w = showspectrum->w;
+    outlink->h = showspectrum->h;
+
+    /* RDFT window size (precision) according to the requested output frame height */
+    for (rdft_bits = 1; 1<<rdft_bits < 2*outlink->h; rdft_bits++);
+    win_size = 1 << rdft_bits;
+
+    /* (re-)configuration if the video output changed (or first init) */
+    if (rdft_bits != showspectrum->rdft_bits) {
+        AVFilterBufferRef *outpicref;
+
+        av_rdft_end(showspectrum->rdft);
+        showspectrum->rdft = av_rdft_init(rdft_bits, DFT_R2C);
+        showspectrum->rdft_bits = rdft_bits;
+
+        /* RDFT buffers: x2 for each (display) channel buffer */
+        showspectrum->rdft_data =
+            av_realloc_f(showspectrum->rdft_data, 2 * win_size,
+                         sizeof(*showspectrum->rdft_data));
+        if (!showspectrum->rdft_data)
+            return AVERROR(ENOMEM);
+        showspectrum->filled = 0;
+
+        /* pre-calc windowing function (hann here) */
+        showspectrum->window_func_lut =
+            av_realloc_f(showspectrum->window_func_lut, win_size,
+                         sizeof(*showspectrum->window_func_lut));
+        if (!showspectrum->window_func_lut)
+            return AVERROR(ENOMEM);
+        for (i = 0; i < win_size; i++)
+            showspectrum->window_func_lut[i] = .5f * (1 - cos(2*M_PI*i / (win_size-1)));
+
+        /* prepare the initial picref buffer (black frame) */
+        avfilter_unref_bufferp(&showspectrum->outpicref);
+        showspectrum->outpicref = outpicref =
+            ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_PRESERVE|AV_PERM_REUSE2,
+                                outlink->w, outlink->h);
+        if (!outpicref)
+            return AVERROR(ENOMEM);
+        outlink->sample_aspect_ratio = (AVRational){1,1};
+        memset(outpicref->data[0], 0, outlink->h * outpicref->linesize[0]);
+    }
+
+    if (showspectrum->xpos >= outlink->w)
+        showspectrum->xpos = 0;
+
+    av_log(ctx, AV_LOG_VERBOSE, "s:%dx%d RDFT window size:%d\n",
+           showspectrum->w, showspectrum->h, win_size);
+    return 0;
+}
+
+inline static void push_frame(AVFilterLink *outlink)
+{
+    ShowSpectrumContext *showspectrum = outlink->src->priv;
+
+    showspectrum->xpos++;
+    if (showspectrum->xpos >= outlink->w)
+        showspectrum->xpos = 0;
+    showspectrum->filled = 0;
+    showspectrum->req_fullfilled = 1;
+
+    ff_start_frame(outlink, avfilter_ref_buffer(showspectrum->outpicref, ~AV_PERM_WRITE));
+    ff_draw_slice(outlink, 0, outlink->h, 1);
+    ff_end_frame(outlink);
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    ShowSpectrumContext *showspectrum = outlink->src->priv;
+    AVFilterLink *inlink = outlink->src->inputs[0];
+    int ret;
+
+    showspectrum->req_fullfilled = 0;
+    do {
+        ret = ff_request_frame(inlink);
+    } while (!showspectrum->req_fullfilled && ret >= 0);
+
+    if (ret == AVERROR_EOF && showspectrum->outpicref)
+        push_frame(outlink);
+    return ret;
+}
+
+static int plot_spectrum_column(AVFilterLink *inlink, AVFilterBufferRef *insamples, int nb_samples)
+{
+    AVFilterContext *ctx = inlink->dst;
+    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;
+
+    int ch, n, y;
+    FFTSample *data[2];
+    const int nb_display_channels = FFMIN(nb_channels, 2);
+    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++) {
+        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->filled += add_samples;
+
+    /* complete RDFT window size? */
+    if (showspectrum->filled == win_size) {
+
+        /* run RDFT on each samples set */
+        for (ch = 0; ch < nb_display_channels; ch++)
+            av_rdft_calc(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))
+
+        for (y = 0; y < outlink->h; y++) {
+            // FIXME: bin[0] contains first and last bins
+            const int pos = showspectrum->xpos * 3 + (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;
+
+            a = FFMIN(a, 255);
+            b = FFMIN(b, 255);
+            outpicref->data[0][pos]   = a;
+            outpicref->data[0][pos+1] = b;
+            outpicref->data[0][pos+2] = (a + b) / 2;
+        }
+        outpicref->pts = insamples->pts +
+            av_rescale_q(showspectrum->consumed,
+                         (AVRational){ 1, inlink->sample_rate },
+                         outlink->time_base);
+        push_frame(outlink);
+    }
+
+    return add_samples;
+}
+
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
+{
+    AVFilterContext *ctx = inlink->dst;
+    ShowSpectrumContext *showspectrum = ctx->priv;
+    int left_samples = insamples->audio->nb_samples;
+
+    showspectrum->consumed = 0;
+    while (left_samples) {
+        const int added_samples = plot_spectrum_column(inlink, insamples, left_samples);
+        showspectrum->consumed += added_samples;
+        left_samples -= added_samples;
+    }
+
+    avfilter_unref_buffer(insamples);
+    return 0;
+}
+
+AVFilter avfilter_avf_showspectrum = {
+    .name           = "showspectrum",
+    .description    = NULL_IF_CONFIG_SMALL("Convert input audio to a spectrum video output."),
+    .init           = init,
+    .uninit         = uninit,
+    .query_formats  = query_formats,
+    .priv_size      = sizeof(ShowSpectrumContext),
+
+    .inputs  = (const AVFilterPad[]) {
+        {
+            .name           = "default",
+            .type           = AVMEDIA_TYPE_AUDIO,
+            .filter_samples = filter_samples,
+            .min_perms      = AV_PERM_READ,
+        },
+        { .name = NULL }
+    },
+
+    .outputs = (const AVFilterPad[]) {
+        {
+            .name           = "default",
+            .type           = AVMEDIA_TYPE_VIDEO,
+            .config_props   = config_output,
+            .request_frame  = request_frame,
+        },
+        { .name = NULL }
+    },
+
+    .priv_class = &showspectrum_class,
+};
diff --git a/libavfilter/avf_showwaves.c b/libavfilter/avf_showwaves.c
new file mode 100644
index 0000000..2e3bfba
--- /dev/null
+++ b/libavfilter/avf_showwaves.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2012 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
+ * audio to video multimedia filter
+ */
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "audio.h"
+#include "video.h"
+#include "internal.h"
+
+typedef struct {
+    const AVClass *class;
+    int w, h;
+    char *rate_str;
+    AVRational rate;
+    int buf_idx;
+    AVFilterBufferRef *outpicref;
+    int req_fullfilled;
+    int n;
+    int sample_count_mod;
+} ShowWavesContext;
+
+#define OFFSET(x) offsetof(ShowWavesContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption showwaves_options[] = {
+    { "rate", "set video rate", OFFSET(rate_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+    { "r",    "set video rate", OFFSET(rate_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+    { "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 },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(showwaves);
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    ShowWavesContext *showwaves = ctx->priv;
+    int err;
+
+    showwaves->class = &showwaves_class;
+    av_opt_set_defaults(showwaves);
+    showwaves->buf_idx = 0;
+
+    if ((err = av_set_options_string(showwaves, args, "=", ":")) < 0)
+        return err;
+
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    ShowWavesContext *showwaves = ctx->priv;
+
+    av_freep(&showwaves->rate_str);
+    avfilter_unref_bufferp(&showwaves->outpicref);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterFormats *formats = NULL;
+    AVFilterChannelLayouts *layouts = NULL;
+    AVFilterLink *inlink = ctx->inputs[0];
+    AVFilterLink *outlink = ctx->outputs[0];
+    static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, -1 };
+    static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, -1 };
+
+    /* set input audio formats */
+    formats = ff_make_format_list(sample_fmts);
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_formats_ref(formats, &inlink->out_formats);
+
+    layouts = ff_all_channel_layouts();
+    if (!layouts)
+        return AVERROR(ENOMEM);
+    ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts);
+
+    formats = ff_all_samplerates();
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_formats_ref(formats, &inlink->out_samplerates);
+
+    /* set output video format */
+    formats = ff_make_format_list(pix_fmts);
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_formats_ref(formats, &outlink->in_formats);
+
+    return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    AVFilterLink *inlink = ctx->inputs[0];
+    ShowWavesContext *showwaves = ctx->priv;
+    int err;
+
+    if (showwaves->n && showwaves->rate_str) {
+        av_log(ctx, AV_LOG_ERROR, "Options 'n' and 'rate' cannot be set at the same time\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (!showwaves->n) {
+        if (!showwaves->rate_str)
+            showwaves->rate = (AVRational){25,1}; /* set default value */
+        else if ((err = av_parse_video_rate(&showwaves->rate, showwaves->rate_str)) < 0) {
+            av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", showwaves->rate_str);
+            return err;
+        }
+        showwaves->n = FFMAX(1, ((double)inlink->sample_rate / (showwaves->w * av_q2d(showwaves->rate))) + 0.5);
+    }
+
+    outlink->w = showwaves->w;
+    outlink->h = showwaves->h;
+    outlink->sample_aspect_ratio = (AVRational){1,1};
+
+    outlink->frame_rate = av_div_q((AVRational){inlink->sample_rate,showwaves->n},
+                                   (AVRational){showwaves->w,1});
+
+    av_log(ctx, AV_LOG_VERBOSE, "s:%dx%d r:%f n:%d\n",
+           showwaves->w, showwaves->h, av_q2d(outlink->frame_rate), showwaves->n);
+    return 0;
+}
+
+inline static void push_frame(AVFilterLink *outlink)
+{
+    ShowWavesContext *showwaves = outlink->src->priv;
+
+    ff_start_frame(outlink, showwaves->outpicref);
+    ff_draw_slice(outlink, 0, outlink->h, 1);
+    ff_end_frame(outlink);
+    showwaves->req_fullfilled = 1;
+    showwaves->outpicref = NULL;
+    showwaves->buf_idx = 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    ShowWavesContext *showwaves = outlink->src->priv;
+    AVFilterLink *inlink = outlink->src->inputs[0];
+    int ret;
+
+    showwaves->req_fullfilled = 0;
+    do {
+        ret = ff_request_frame(inlink);
+    } while (!showwaves->req_fullfilled && ret >= 0);
+
+    if (ret == AVERROR_EOF && showwaves->outpicref)
+        push_frame(outlink);
+    return ret;
+}
+
+#define MAX_INT16 ((1<<15) -1)
+
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AVFilterLink *outlink = ctx->outputs[0];
+    ShowWavesContext *showwaves = ctx->priv;
+    const int nb_samples = insamples->audio->nb_samples;
+    AVFilterBufferRef *outpicref = showwaves->outpicref;
+    int linesize = outpicref ? outpicref->linesize[0] : 0;
+    int16_t *p = (int16_t *)insamples->data[0];
+    int nb_channels = av_get_channel_layout_nb_channels(insamples->audio->channel_layout);
+    int i, j, h;
+    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 (showwaves->buf_idx == 0 && showwaves->sample_count_mod == 0) {
+            showwaves->outpicref = outpicref =
+                ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN,
+                                    outlink->w, outlink->h);
+            outpicref->video->w = outlink->w;
+            outpicref->video->h = outlink->h;
+            outpicref->pts = insamples->pts +
+                             av_rescale_q((p - (int16_t *)insamples->data[0]) / nb_channels,
+                                          (AVRational){ 1, inlink->sample_rate },
+                                          outlink->time_base);
+            linesize = outpicref->linesize[0];
+            memset(outpicref->data[0], 0, showwaves->h*linesize);
+        }
+        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;
+        }
+        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);
+    }
+
+    avfilter_unref_buffer(insamples);
+    return 0;
+}
+
+AVFilter avfilter_avf_showwaves = {
+    .name           = "showwaves",
+    .description    = NULL_IF_CONFIG_SMALL("Convert input audio to a video output."),
+    .init           = init,
+    .uninit         = uninit,
+    .query_formats  = query_formats,
+    .priv_size      = sizeof(ShowWavesContext),
+
+    .inputs  = (const AVFilterPad[]) {
+        {
+            .name           = "default",
+            .type           = AVMEDIA_TYPE_AUDIO,
+            .filter_samples = filter_samples,
+            .min_perms      = AV_PERM_READ,
+        },
+        { .name = NULL }
+    },
+
+    .outputs = (const AVFilterPad[]) {
+        {
+            .name           = "default",
+            .type           = AVMEDIA_TYPE_VIDEO,
+            .config_props   = config_output,
+            .request_frame  = request_frame,
+        },
+        { .name = NULL }
+    },
+
+    .priv_class = &showwaves_class,
+};
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 1e3b001..dee7ba0 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -2,47 +2,98 @@
  * filter layer
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-/* #define DEBUG */
-
 #include "libavutil/common.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/rational.h"
 #include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
 
 #include "avfilter.h"
 #include "formats.h"
 #include "internal.h"
+#include "audio.h"
+
+char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms)
+{
+    snprintf(buf, buf_size, "%s%s%s%s%s%s",
+             perms & AV_PERM_READ      ? "r" : "",
+             perms & AV_PERM_WRITE     ? "w" : "",
+             perms & AV_PERM_PRESERVE  ? "p" : "",
+             perms & AV_PERM_REUSE     ? "u" : "",
+             perms & AV_PERM_REUSE2    ? "U" : "",
+             perms & AV_PERM_NEG_LINESIZES ? "n" : "");
+    return buf;
+}
+
+void ff_tlog_ref(void *ctx, AVFilterBufferRef *ref, int end)
+{
+    av_unused char buf[16];
+    ff_tlog(ctx,
+            "ref[%p buf:%p refcount:%d perms:%s data:%p linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64,
+            ref, ref->buf, ref->buf->refcount, ff_get_ref_perms_string(buf, sizeof(buf), ref->perms), ref->data[0],
+            ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3],
+            ref->pts, ref->pos);
+
+    if (ref->video) {
+        ff_tlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c",
+                ref->video->sample_aspect_ratio.num, ref->video->sample_aspect_ratio.den,
+                ref->video->w, ref->video->h,
+                !ref->video->interlaced     ? 'P' :         /* Progressive  */
+                ref->video->top_field_first ? 'T' : 'B',    /* Top / Bottom */
+                ref->video->key_frame,
+                av_get_picture_type_char(ref->video->pict_type));
+    }
+    if (ref->audio) {
+        ff_tlog(ctx, " cl:%"PRId64"d n:%d r:%d",
+                ref->audio->channel_layout,
+                ref->audio->nb_samples,
+                ref->audio->sample_rate);
+    }
+
+    ff_tlog(ctx, "]%s", end ? "\n" : "");
+}
 
 unsigned avfilter_version(void) {
+    av_assert0(LIBAVFILTER_VERSION_MICRO >= 100);
     return LIBAVFILTER_VERSION_INT;
 }
 
 const char *avfilter_configuration(void)
 {
-    return LIBAV_CONFIGURATION;
+    return FFMPEG_CONFIGURATION;
 }
 
 const char *avfilter_license(void)
 {
 #define LICENSE_PREFIX "libavfilter license: "
-    return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+    return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+}
+
+void ff_command_queue_pop(AVFilterContext *filter)
+{
+    AVFilterCommand *c= filter->command_queue;
+    av_freep(&c->arg);
+    av_freep(&c->command);
+    filter->command_queue= c->next;
+    av_free(c);
 }
 
 void ff_insert_pad(unsigned idx, unsigned *count, size_t padidx_off,
@@ -77,8 +128,9 @@
 
     if (src->output_pads[srcpad].type != dst->input_pads[dstpad].type) {
         av_log(src, AV_LOG_ERROR,
-               "Media type mismatch between the '%s' filter output pad %d and the '%s' filter input pad %d\n",
-               src->name, srcpad, dst->name, dstpad);
+               "Media type mismatch between the '%s' filter output pad %d (%s) and the '%s' filter input pad %d (%s)\n",
+               src->name, srcpad, (char *)av_x_if_null(av_get_media_type_string(src->output_pads[srcpad].type), "?"),
+               dst->name, dstpad, (char *)av_x_if_null(av_get_media_type_string(dst-> input_pads[dstpad].type), "?"));
         return AVERROR(EINVAL);
     }
 
@@ -90,12 +142,30 @@
     link->srcpad  = &src->output_pads[srcpad];
     link->dstpad  = &dst->input_pads[dstpad];
     link->type    = src->output_pads[srcpad].type;
-    assert(AV_PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);
+    av_assert0(AV_PIX_FMT_NONE == -1 && AV_SAMPLE_FMT_NONE == -1);
     link->format  = -1;
 
     return 0;
 }
 
+void avfilter_link_free(AVFilterLink **link)
+{
+    if (!*link)
+        return;
+
+    if ((*link)->pool)
+        ff_free_pool((*link)->pool);
+
+    avfilter_unref_bufferp(&(*link)->partial_buf);
+
+    av_freep(link);
+}
+
+void avfilter_link_set_closed(AVFilterLink *link, int closed)
+{
+    link->closed = closed;
+}
+
 int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
                            unsigned filt_srcpad_idx, unsigned filt_dstpad_idx)
 {
@@ -123,6 +193,7 @@
     if (link->out_formats)
         ff_formats_changeref(&link->out_formats,
                                    &filt->outputs[filt_dstpad_idx]->out_formats);
+
     if (link->out_samplerates)
         ff_formats_changeref(&link->out_samplerates,
                                    &filt->outputs[filt_dstpad_idx]->out_samplerates);
@@ -141,9 +212,13 @@
 
     for (i = 0; i < filter->nb_inputs; i ++) {
         AVFilterLink *link = filter->inputs[i];
+        AVFilterLink *inlink = link->src->nb_inputs ?
+            link->src->inputs[0] : NULL;
 
         if (!link) continue;
 
+        link->current_pts = AV_NOPTS_VALUE;
+
         switch (link->init_state) {
         case AVLINK_INIT:
             continue;
@@ -171,26 +246,48 @@
                 return ret;
             }
 
-            if (link->time_base.num == 0 && link->time_base.den == 0)
-                link->time_base = link->src && link->src->nb_inputs ?
-                    link->src->inputs[0]->time_base : AV_TIME_BASE_Q;
+            switch (link->type) {
+            case AVMEDIA_TYPE_VIDEO:
+                if (!link->time_base.num && !link->time_base.den)
+                    link->time_base = inlink ? inlink->time_base : AV_TIME_BASE_Q;
 
-            if (link->type == AVMEDIA_TYPE_VIDEO) {
                 if (!link->sample_aspect_ratio.num && !link->sample_aspect_ratio.den)
-                    link->sample_aspect_ratio = link->src->nb_inputs ?
-                        link->src->inputs[0]->sample_aspect_ratio : (AVRational){1,1};
+                    link->sample_aspect_ratio = inlink ?
+                        inlink->sample_aspect_ratio : (AVRational){1,1};
 
-                if (link->src->nb_inputs) {
+                if (inlink && !link->frame_rate.num && !link->frame_rate.den)
+                    link->frame_rate = inlink->frame_rate;
+
+                if (inlink) {
                     if (!link->w)
-                        link->w = link->src->inputs[0]->w;
+                        link->w = inlink->w;
                     if (!link->h)
-                        link->h = link->src->inputs[0]->h;
+                        link->h = inlink->h;
                 } else if (!link->w || !link->h) {
                     av_log(link->src, AV_LOG_ERROR,
                            "Video source filters must set their output link's "
                            "width and height\n");
                     return AVERROR(EINVAL);
                 }
+                break;
+
+            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)
+                    link->time_base = (AVRational) {1, link->sample_rate};
             }
 
             if ((config_link = link->dstpad->config_props))
@@ -208,11 +305,11 @@
     return 0;
 }
 
-void ff_dlog_link(void *ctx, AVFilterLink *link, int end)
+void ff_tlog_link(void *ctx, AVFilterLink *link, int end)
 {
     if (link->type == AVMEDIA_TYPE_VIDEO) {
-        av_dlog(ctx,
-                "link[%p s:%dx%d fmt:%-16s %-16s->%-16s]%s",
+        ff_tlog(ctx,
+                "link[%p s:%dx%d fmt:%s %s->%s]%s",
                 link, link->w, link->h,
                 av_get_pix_fmt_name(link->format),
                 link->src ? link->src->filter->name : "",
@@ -222,9 +319,9 @@
         char buf[128];
         av_get_channel_layout_string(buf, sizeof(buf), -1, link->channel_layout);
 
-        av_dlog(ctx,
-                "link[%p r:%d cl:%s fmt:%-16s %-16s->%-16s]%s",
-                link, link->sample_rate, buf,
+        ff_tlog(ctx,
+                "link[%p r:%d cl:%s fmt:%s %s->%s]%s",
+                link, (int)link->sample_rate, buf,
                 av_get_sample_fmt_name(link->format),
                 link->src ? link->src->filter->name : "",
                 link->dst ? link->dst->filter->name : "",
@@ -234,13 +331,24 @@
 
 int ff_request_frame(AVFilterLink *link)
 {
-    FF_DPRINTF_START(NULL, request_frame); ff_dlog_link(NULL, link, 1);
+    int ret = -1;
+    FF_TPRINTF_START(NULL, request_frame); ff_tlog_link(NULL, link, 1);
 
+    if (link->closed)
+        return AVERROR_EOF;
     if (link->srcpad->request_frame)
-        return link->srcpad->request_frame(link);
+        ret = link->srcpad->request_frame(link);
     else if (link->src->inputs[0])
-        return ff_request_frame(link->src->inputs[0]);
-    else return -1;
+        ret = ff_request_frame(link->src->inputs[0]);
+    if (ret == AVERROR_EOF && link->partial_buf) {
+        AVFilterBufferRef *pbuf = link->partial_buf;
+        link->partial_buf = NULL;
+        ff_filter_samples_framed(link, pbuf);
+        return 0;
+    }
+    if (ret == AVERROR_EOF)
+        link->closed = 1;
+    return ret;
 }
 
 int ff_poll_frame(AVFilterLink *link)
@@ -261,7 +369,28 @@
     return min;
 }
 
-#define MAX_REGISTERED_AVFILTERS_NB 64
+void ff_update_link_current_pts(AVFilterLink *link, int64_t pts)
+{
+    if (pts == AV_NOPTS_VALUE)
+        return;
+    link->current_pts = av_rescale_q(pts, link->time_base, AV_TIME_BASE_Q);
+    /* TODO use duration */
+    if (link->graph && link->age_index >= 0)
+        ff_avfilter_graph_update_heap(link->graph, link);
+}
+
+int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags)
+{
+    if(!strcmp(cmd, "ping")){
+        av_strlcatf(res, res_len, "pong from:%s %s\n", filter->filter->name, filter->name);
+        return 0;
+    }else if(filter->filter->process_command) {
+        return filter->filter->process_command(filter, cmd, arg, res, res_len, flags);
+    }
+    return AVERROR(ENOSYS);
+}
+
+#define MAX_REGISTERED_AVFILTERS_NB 128
 
 static AVFilter *registered_avfilters[MAX_REGISTERED_AVFILTERS_NB + 1];
 
@@ -280,8 +409,13 @@
 
 int avfilter_register(AVFilter *filter)
 {
-    if (next_registered_avfilter_idx == MAX_REGISTERED_AVFILTERS_NB)
-        return -1;
+    if (next_registered_avfilter_idx == MAX_REGISTERED_AVFILTERS_NB) {
+        av_log(NULL, AV_LOG_ERROR,
+               "Maximum number of registered filters %d reached, "
+               "impossible to register filter with name '%s'\n",
+               MAX_REGISTERED_AVFILTERS_NB, filter->name);
+        return AVERROR(ENOMEM);
+    }
 
     registered_avfilters[next_registered_avfilter_idx++] = filter;
     return 0;
@@ -309,19 +443,54 @@
     return count;
 }
 
-static const char *filter_name(void *p)
+static const char *default_filter_name(void *filter_ctx)
 {
-    AVFilterContext *filter = p;
-    return filter->filter->name;
+    AVFilterContext *ctx = filter_ctx;
+    return ctx->name ? ctx->name : ctx->filter->name;
+}
+
+static void *filter_child_next(void *obj, void *prev)
+{
+    AVFilterContext *ctx = obj;
+    if (!prev && ctx->filter && ctx->filter->priv_class)
+        return ctx->priv;
+    return NULL;
+}
+
+static const AVClass *filter_child_class_next(const AVClass *prev)
+{
+    AVFilter **filter_ptr = NULL;
+
+    /* find the filter that corresponds to prev */
+    while (prev && *(filter_ptr = av_filter_next(filter_ptr)))
+        if ((*filter_ptr)->priv_class == prev)
+            break;
+
+    /* could not find filter corresponding to prev */
+    if (prev && !(*filter_ptr))
+        return NULL;
+
+    /* find next filter with specific options */
+    while (*(filter_ptr = av_filter_next(filter_ptr)))
+        if ((*filter_ptr)->priv_class)
+            return (*filter_ptr)->priv_class;
+    return NULL;
 }
 
 static const AVClass avfilter_class = {
-    "AVFilter",
-    filter_name,
-    NULL,
-    LIBAVUTIL_VERSION_INT,
+    .class_name = "AVFilter",
+    .item_name  = default_filter_name,
+    .version    = LIBAVUTIL_VERSION_INT,
+    .category   = AV_CLASS_CATEGORY_FILTER,
+    .child_next = filter_child_next,
+    .child_class_next = filter_child_class_next,
 };
 
+const AVClass *avfilter_get_class(void)
+{
+    return &avfilter_class;
+}
+
 int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *inst_name)
 {
     AVFilterContext *ret;
@@ -389,6 +558,9 @@
     int i;
     AVFilterLink *link;
 
+    if (!filter)
+        return;
+
     if (filter->filter->uninit)
         filter->filter->uninit(filter);
 
@@ -403,7 +575,7 @@
             ff_channel_layouts_unref(&link->in_channel_layouts);
             ff_channel_layouts_unref(&link->out_channel_layouts);
         }
-        av_freep(&link);
+        avfilter_link_free(&link);
     }
     for (i = 0; i < filter->nb_outputs; i++) {
         if ((link = filter->outputs[i])) {
@@ -416,7 +588,7 @@
             ff_channel_layouts_unref(&link->in_channel_layouts);
             ff_channel_layouts_unref(&link->out_channel_layouts);
         }
-        av_freep(&link);
+        avfilter_link_free(&link);
     }
 
     av_freep(&filter->name);
@@ -425,6 +597,9 @@
     av_freep(&filter->inputs);
     av_freep(&filter->outputs);
     av_freep(&filter->priv);
+    while(filter->command_queue){
+        ff_command_queue_pop(filter);
+    }
     av_free(filter);
 }
 
@@ -432,7 +607,9 @@
 {
     int ret=0;
 
-    if (filter->filter->init)
+    if (filter->filter->init_opaque)
+        ret = filter->filter->init_opaque(filter, args, opaque);
+    else if (filter->filter->init)
         ret = filter->filter->init(filter, args);
     return ret;
 }
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index adb8b79..510f28a 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -2,34 +2,33 @@
  * filter layer
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #ifndef AVFILTER_AVFILTER_H
 #define AVFILTER_AVFILTER_H
 
+#include <stddef.h>
+
 #include "libavutil/avutil.h"
 #include "libavutil/log.h"
 #include "libavutil/samplefmt.h"
 #include "libavutil/pixfmt.h"
 #include "libavutil/rational.h"
-#include "libavcodec/avcodec.h"
-
-#include <stddef.h>
 
 #include "libavfilter/version.h"
 
@@ -48,6 +47,10 @@
  */
 const char *avfilter_license(void);
 
+/**
+ * Get the class for the AVFilterContext struct.
+ */
+const AVClass *avfilter_get_class(void);
 
 typedef struct AVFilterContext AVFilterContext;
 typedef struct AVFilterLink    AVFilterLink;
@@ -100,6 +103,9 @@
 #define AV_PERM_REUSE    0x08   ///< can output the buffer multiple times, with the same contents each time
 #define AV_PERM_REUSE2   0x10   ///< can output the buffer multiple times, modified each time
 #define AV_PERM_NEG_LINESIZES 0x20  ///< the buffer requested can have negative linesizes
+#define AV_PERM_ALIGN    0x40   ///< the buffer must be aligned
+
+#define AVFILTER_ALIGN 16 //not part of ABI
 
 /**
  * Audio specific properties in a reference to an AVFilterBuffer. Since
@@ -108,9 +114,8 @@
  */
 typedef struct AVFilterBufferRefAudioProps {
     uint64_t channel_layout;    ///< channel layout of audio buffer
-    int nb_samples;             ///< number of audio samples
+    int nb_samples;             ///< number of audio samples per channel
     int sample_rate;            ///< audio buffer sample rate
-    int planar;                 ///< audio buffer - planar or packed
 } AVFilterBufferRefAudioProps;
 
 /**
@@ -121,11 +126,14 @@
 typedef struct AVFilterBufferRefVideoProps {
     int w;                      ///< image width
     int h;                      ///< image height
-    AVRational pixel_aspect;    ///< pixel aspect ratio
+    AVRational sample_aspect_ratio; ///< sample aspect ratio
     int interlaced;             ///< is frame interlaced
     int top_field_first;        ///< field order
     enum AVPictureType pict_type; ///< picture type of the frame
     int key_frame;              ///< 1 -> keyframe, 0-> not
+    int qp_table_linesize;                ///< qp_table stride
+    int qp_table_size;            ///< qp_table size
+    int8_t *qp_table;             ///< array of Quantization Parameters
 } AVFilterBufferRefVideoProps;
 
 /**
@@ -214,7 +222,9 @@
 /**
  * A filter pad used for either input or output.
  *
- * @warning this struct will be removed from public API.
+ * See doc/filter_design.txt for details on how to implement the methods.
+ *
+ * @warning this struct might be removed from public API.
  * users should call avfilter_pad_get_name() and avfilter_pad_get_type()
  * to access the name and type fields; there should be no need to access
  * any other fields from outside of libavfilter.
@@ -233,22 +243,29 @@
     enum AVMediaType type;
 
     /**
+     * Input pads:
      * Minimum required permissions on incoming buffers. Any buffer with
      * insufficient permissions will be automatically copied by the filter
      * system to a new buffer which provides the needed access permissions.
      *
-     * Input pads only.
+     * Output pads:
+     * Guaranteed permissions on outgoing buffers. Any buffer pushed on the
+     * link must have at least these permissions; this fact is checked by
+     * asserts. It can be used to optimize buffer allocation.
      */
     int min_perms;
 
     /**
+     * Input pads:
      * Permissions which are not accepted on incoming buffers. Any buffer
      * which has any of these permissions set will be automatically copied
      * by the filter system to a new buffer which does not have those
      * permissions. This can be used to easily disallow buffers with
      * AV_PERM_REUSE.
      *
-     * Input pads only.
+     * Output pads:
+     * Permissions which are automatically removed on outgoing buffers. It
+     * can be used to optimize buffer allocation.
      */
     int rej_perms;
 
@@ -257,6 +274,12 @@
      * NULL, the filter layer will default to storing a reference to the
      * picture inside the link structure.
      *
+     * The reference given as argument is also available in link->cur_buf.
+     * It can be stored elsewhere or given away, but then clearing
+     * link->cur_buf is advised, as it is automatically unreferenced.
+     * The reference must not be unreferenced before end_frame(), as it may
+     * still be in use by the automatic copy mechanism.
+     *
      * Input video pads only.
      *
      * @return >= 0 on success, a negative AVERROR on error. picref will be
@@ -329,6 +352,8 @@
      * Frame request callback. A call to this should result in at least one
      * frame being output over the given link. This should return zero on
      * success, and another value on error.
+     * See ff_request_frame() for the error codes with a specific
+     * meaning.
      *
      * Output pads only.
      */
@@ -337,15 +362,18 @@
     /**
      * Link configuration callback.
      *
-     * For output pads, this should set the link properties such as
-     * width/height. This should NOT set the format property - that is
-     * negotiated between filters by the filter system using the
+     * For output pads, this should set the following link properties:
+     * video: width, height, sample_aspect_ratio, time_base
+     * audio: sample_rate.
+     *
+     * This should NOT set properties such as format, channel_layout, etc which
+     * are negotiated between filters by the filter system using the
      * query_formats() callback before this function is called.
      *
      * For input pads, this should check the properties of the link, and update
      * the filter's internal state as necessary.
      *
-     * For both input and output filters, this should return zero on success,
+     * For both input and output pads, this should return zero on success,
      * and another value on error.
      */
     int (*config_props)(AVFilterLink *link);
@@ -420,9 +448,9 @@
     void (*uninit)(AVFilterContext *ctx);
 
     /**
-     * Queries formats supported by the filter and its pads, and sets the
-     * in_formats for links connected to its output pads, and out_formats
-     * for links connected to its input pads.
+     * Queries formats/layouts supported by the filter and its pads, and sets
+     * the in_formats/in_chlayouts for links connected to its output pads,
+     * and out_formats/out_chlayouts for links connected to its input pads.
      *
      * @return zero on success, a negative value corresponding to an
      * AVERROR code otherwise
@@ -430,11 +458,34 @@
     int (*query_formats)(AVFilterContext *);
 
     int priv_size;      ///< size of private data to allocate for the filter
+
+    /**
+     * Make the filter instance process a command.
+     *
+     * @param cmd    the command to process, for handling simplicity all commands must be alphanumeric only
+     * @param arg    the argument for the command
+     * @param res    a buffer with size res_size where the filter(s) can return a response. This must not change when the command is not supported.
+     * @param flags  if AVFILTER_CMD_FLAG_FAST is set and the command would be
+     *               time consuming then a filter should treat it like an unsupported command
+     *
+     * @returns >=0 on success otherwise an error code.
+     *          AVERROR(ENOSYS) on unsupported commands
+     */
+    int (*process_command)(AVFilterContext *, const char *cmd, const char *arg, char *res, int res_len, int flags);
+
+    /**
+     * Filter initialization function, alternative to the init()
+     * callback. Args contains the user-supplied parameters, opaque is
+     * used for providing binary data.
+     */
+    int (*init_opaque)(AVFilterContext *ctx, const char *args, void *opaque);
+
+    const AVClass *priv_class;      ///< private class, containing filter specific options
 } AVFilter;
 
 /** An instance of a filter */
 struct AVFilterContext {
-    const AVClass *av_class;              ///< needed for av_log()
+    const AVClass *av_class;        ///< needed for av_log()
 
     AVFilter *filter;               ///< the AVFilter of which this is an instance
 
@@ -455,6 +506,8 @@
     unsigned    nb_outputs;         ///< number of output pads
 
     void *priv;                     ///< private data for use by the filter
+
+    struct AVFilterCommand *command_queue;
 };
 
 /**
@@ -477,7 +530,7 @@
     int w;                      ///< agreed upon image width
     int h;                      ///< agreed upon image height
     AVRational sample_aspect_ratio; ///< agreed upon sample aspect ratio
-    /* These two parameters apply only to audio */
+    /* These parameters apply only to audio */
     uint64_t channel_layout;    ///< channel layout of current buffer (see libavutil/audioconvert.h)
     int sample_rate;            ///< samples per second
 
@@ -500,9 +553,11 @@
      *****************************************************************
      */
     /**
-     * Lists of formats supported by the input and output filters respectively.
-     * These lists are used for negotiating the format to actually be used,
-     * which will be loaded into the format member, above, when chosen.
+     * Lists of formats and channel layouts supported by the input and output
+     * filters respectively. These lists are used for negotiating the format
+     * to actually be used, which will be loaded into the format and
+     * channel_layout members, above, when chosen.
+     *
      */
     AVFilterFormats *in_formats;
     AVFilterFormats *out_formats;
@@ -541,8 +596,118 @@
      */
     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;
+
+    /**
+     * Graph the filter belongs to.
+     */
+    struct AVFilterGraph *graph;
+
+    /**
+     * Current timestamp of the link, as defined by the most recent
+     * frame(s), in AV_TIME_BASE units.
+     */
+    int64_t current_pts;
+
+    /**
+     * Index in the age array.
+     */
+    int age_index;
+
+    /**
+     * Frame rate of the stream on the link, or 1/0 if unknown;
+     * if left to 0/0, will be automatically be copied from the first input
+     * of the source filter if it exists.
+     *
+     * Sources should set it to the best estimation of the real frame rate.
+     * Filters should update it if necessary depending on their function.
+     * Sinks can use it to set a default output frame rate.
+     * It is similar to the r_frame_rate field in AVStream.
+     */
+    AVRational frame_rate;
+
+    /**
+     * Buffer partially filled with samples to achieve a fixed/minimum size.
+     */
+    AVFilterBufferRef *partial_buf;
+
+    /**
+     * Size of the partial buffer to allocate.
+     * Must be between min_samples and max_samples.
+     */
+    int partial_buf_size;
+
+    /**
+     * Minimum number of samples to filter at once. If filter_samples() is
+     * called with fewer samples, it will accumulate them in partial_buf.
+     * This field and the related ones must not be changed after filtering
+     * has started.
+     * If 0, all related fields are ignored.
+     */
+    int min_samples;
+
+    /**
+     * Maximum number of samples to filter at once. If filter_samples() is
+     * called with more samples, it will split them.
+     */
+    int max_samples;
+
+    /**
+     * The buffer reference currently being received across the link by the
+     * destination 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 *cur_buf_copy;
+
+    /**
+     * True if the link is closed.
+     * If set, all attemps of start_frame, filter_samples or request_frame
+     * will fail with AVERROR_EOF, and if necessary the reference will be
+     * destroyed.
+     * If request_frame returns AVERROR_EOF, this flag is set on the
+     * corresponding link.
+     * It can be set also be set by either the source or the destination
+     * filter.
+     */
+    int closed;
 };
 
 /**
@@ -558,6 +723,16 @@
                   AVFilterContext *dst, unsigned dstpad);
 
 /**
+ * Free the link in *link, and set its pointer to NULL.
+ */
+void avfilter_link_free(AVFilterLink **link);
+
+/**
+ * Set the closed field of a link.
+ */
+void avfilter_link_set_closed(AVFilterLink *link, int closed);
+
+/**
  * Negotiate the media format, dimensions, etc of all inputs to a filter.
  *
  * @param filter the filter to negotiate the properties for its inputs
@@ -577,7 +752,7 @@
  * @param format the pixel format of the image specified by the data and linesize arrays
  */
 AVFilterBufferRef *
-avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int perms,
+avfilter_get_video_buffer_ref_from_arrays(uint8_t * const data[4], const int linesize[4], int perms,
                                           int w, int h, enum AVPixelFormat format);
 
 /**
@@ -598,6 +773,16 @@
                                                              enum AVSampleFormat sample_fmt,
                                                              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
+#define AVFILTER_CMD_FLAG_FAST  2 ///< Only execute command when its fast (like a video out that supports contrast adjustment in hw)
+
+/**
+ * Make the filter instance process a command.
+ * It is recommended to use avfilter_graph_send_command().
+ */
+int avfilter_process_command(AVFilterContext *filter, const char *cmd, const char *arg, char *res, int res_len, int flags);
+
 /** Initialize the filter system. Register all builtin filters. */
 void avfilter_register_all(void);
 
@@ -611,7 +796,7 @@
  * registered.
  *
  * @param filter the filter to register
- * @return 0 if the registration was succesfull, a negative value
+ * @return 0 if the registration was successful, a negative value
  * otherwise
  */
 int avfilter_register(AVFilter *filter);
@@ -675,20 +860,4 @@
 int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
                            unsigned filt_srcpad_idx, unsigned filt_dstpad_idx);
 
-/**
- * Copy the frame properties of src to dst, without copying the actual
- * image data.
- *
- * @return 0 on success, a negative number on error.
- */
-int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src);
-
-/**
- * Copy the frame properties and data pointers of src to dst, without copying
- * the actual data.
- *
- * @return 0 on success, a negative number on error.
- */
-int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src);
-
 #endif /* AVFILTER_AVFILTER_H */
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 4a66c78..ab37fae 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -3,26 +3,30 @@
  * Copyright (c) 2008 Vitor Sessak
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <ctype.h>
 #include <string.h>
 
+#include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
+#include "libavutil/pixdesc.h"
+#include "libavcodec/avcodec.h" // avcodec_find_best_pix_fmt_of_2()
 #include "avfilter.h"
 #include "avfiltergraph.h"
 #include "formats.h"
@@ -37,6 +41,7 @@
     .class_name = "AVFilterGraph",
     .item_name  = av_default_item_name,
     .version    = LIBAVUTIL_VERSION_INT,
+    .category   = AV_CLASS_CATEGORY_FILTER,
 };
 
 AVFilterGraph *avfilter_graph_alloc(void)
@@ -54,6 +59,7 @@
         return;
     for (; (*graph)->filter_count > 0; (*graph)->filter_count--)
         avfilter_free((*graph)->filters[(*graph)->filter_count - 1]);
+    av_freep(&(*graph)->sink_links);
     av_freep(&(*graph)->scale_sws_opts);
     av_freep(&(*graph)->filters);
     av_freep(graph);
@@ -93,6 +99,11 @@
     return ret;
 }
 
+void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
+{
+    graph->disable_auto_convert = flags;
+}
+
 /**
  * Check for the validity of graph.
  *
@@ -164,17 +175,113 @@
     return NULL;
 }
 
+static int filter_query_formats(AVFilterContext *ctx)
+{
+    int ret;
+    AVFilterFormats *formats;
+    AVFilterChannelLayouts *chlayouts;
+    AVFilterFormats *samplerates;
+    enum AVMediaType type = ctx->inputs  && ctx->inputs [0] ? ctx->inputs [0]->type :
+                            ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
+                            AVMEDIA_TYPE_VIDEO;
+
+    if ((ret = ctx->filter->query_formats(ctx)) < 0)
+        return ret;
+
+    formats = ff_all_formats(type);
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_set_common_formats(ctx, formats);
+    if (type == AVMEDIA_TYPE_AUDIO) {
+        samplerates = ff_all_samplerates();
+        if (!samplerates)
+            return AVERROR(ENOMEM);
+        ff_set_common_samplerates(ctx, samplerates);
+        chlayouts = ff_all_channel_layouts();
+        if (!chlayouts)
+            return AVERROR(ENOMEM);
+        ff_set_common_channel_layouts(ctx, chlayouts);
+    }
+    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++) {
     /* ask all the sub-filters for their supported media formats */
     for (i = 0; i < graph->filter_count; i++) {
+        /* Call query_formats on sources first.
+           This is a temporary workaround for amerge,
+           until format renegociation is implemented. */
+        if (!graph->filters[i]->nb_inputs == j)
+            continue;
         if (graph->filters[i]->filter->query_formats)
-            graph->filters[i]->filter->query_formats(graph->filters[i]);
+            ret = filter_query_formats(graph->filters[i]);
         else
-            ff_default_query_formats(graph->filters[i]);
+            ret = ff_default_query_formats(graph->filters[i]);
+        if (ret < 0)
+            return ret;
+    }
     }
 
     /* go through and merge as many format lists as possible */
@@ -183,6 +290,36 @@
 
         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)
@@ -228,8 +365,8 @@
                         return ret;
                     break;
                 case AVMEDIA_TYPE_AUDIO:
-                    if (!(filter = avfilter_get_by_name("resample"))) {
-                        av_log(log_ctx, AV_LOG_ERROR, "'resample' filter "
+                    if (!(filter = avfilter_get_by_name("aresample"))) {
+                        av_log(log_ctx, AV_LOG_ERROR, "'aresample' filter "
                                "not present, cannot convert audio formats.\n");
                         return AVERROR(EINVAL);
                     }
@@ -247,7 +384,7 @@
                 if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
                     return ret;
 
-                convert->filter->query_formats(convert);
+                filter_query_formats(convert);
                 inlink  = convert->inputs[0];
                 outlink = convert->outputs[0];
                 if (!ff_merge_formats( inlink->in_formats,  inlink->out_formats) ||
@@ -272,6 +409,7 @@
                            "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
                     return ret;
                 }
+#endif
             }
         }
     }
@@ -279,11 +417,27 @@
     return 0;
 }
 
-static int pick_format(AVFilterLink *link)
+static int pick_format(AVFilterLink *link, AVFilterLink *ref)
 {
     if (!link || !link->in_formats)
         return 0;
 
+    if (link->type == AVMEDIA_TYPE_VIDEO) {
+        if(ref && ref->type == AVMEDIA_TYPE_VIDEO){
+            int has_alpha= av_pix_fmt_descriptors[ref->format].nb_components % 2 == 0;
+            enum AVPixelFormat best= AV_PIX_FMT_NONE;
+            int i;
+            for (i=0; i<link->in_formats->format_count; i++) {
+                enum AVPixelFormat p = link->in_formats->formats[i];
+                best= avcodec_find_best_pix_fmt_of_2(best, p, ref->format, has_alpha, NULL);
+            }
+            av_log(link->src,AV_LOG_DEBUG, "picking %s out of %d ref:%s alpha:%d\n",
+                   av_get_pix_fmt_name(best), link->in_formats->format_count,
+                   av_get_pix_fmt_name(ref->format), has_alpha);
+            link->in_formats->formats[0] = best;
+        }
+    }
+
     link->in_formats->format_count = 1;
     link->format = link->in_formats->formats[0];
 
@@ -612,15 +766,47 @@
 static int pick_formats(AVFilterGraph *graph)
 {
     int i, j, ret;
+    int change;
+
+    do{
+        change = 0;
+        for (i = 0; i < graph->filter_count; i++) {
+            AVFilterContext *filter = graph->filters[i];
+            if (filter->nb_inputs){
+                for (j = 0; j < filter->nb_inputs; j++){
+                    if(filter->inputs[j]->in_formats && filter->inputs[j]->in_formats->format_count == 1) {
+                        pick_format(filter->inputs[j], NULL);
+                        change = 1;
+                    }
+                }
+            }
+            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);
+                        change = 1;
+                    }
+                }
+            }
+            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]);
+                        change = 1;
+                    }
+                }
+            }
+        }
+    }while(change);
 
     for (i = 0; i < graph->filter_count; i++) {
         AVFilterContext *filter = graph->filters[i];
 
         for (j = 0; j < filter->nb_inputs; j++)
-            if ((ret = pick_format(filter->inputs[j])) < 0)
+            if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
                 return ret;
         for (j = 0; j < filter->nb_outputs; j++)
-            if ((ret = pick_format(filter->outputs[j])) < 0)
+            if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
                 return ret;
     }
     return 0;
@@ -654,6 +840,48 @@
     return 0;
 }
 
+static int ff_avfilter_graph_config_pointers(AVFilterGraph *graph,
+                                             AVClass *log_ctx)
+{
+    unsigned i, j;
+    int sink_links_count = 0, n = 0;
+    AVFilterContext *f;
+    AVFilterLink **sinks;
+
+    for (i = 0; i < graph->filter_count; i++) {
+        f = graph->filters[i];
+        for (j = 0; j < f->nb_inputs; j++) {
+            f->inputs[j]->graph     = graph;
+            f->inputs[j]->age_index = -1;
+        }
+        for (j = 0; j < f->nb_outputs; j++) {
+            f->outputs[j]->graph    = graph;
+            f->outputs[j]->age_index= -1;
+        }
+        if (!f->nb_outputs) {
+            if (f->nb_inputs > INT_MAX - sink_links_count)
+                return AVERROR(EINVAL);
+            sink_links_count += f->nb_inputs;
+        }
+    }
+    sinks = av_calloc(sink_links_count, sizeof(*sinks));
+    if (!sinks)
+        return AVERROR(ENOMEM);
+    for (i = 0; i < graph->filter_count; i++) {
+        f = graph->filters[i];
+        if (!f->nb_outputs) {
+            for (j = 0; j < f->nb_inputs; j++) {
+                sinks[n] = f->inputs[j];
+                f->inputs[j]->age_index = n++;
+            }
+        }
+    }
+    av_assert0(n == sink_links_count);
+    graph->sink_links       = sinks;
+    graph->sink_links_count = sink_links_count;
+    return 0;
+}
+
 static int graph_insert_fifos(AVFilterGraph *graph, AVClass *log_ctx)
 {
     AVFilterContext *f;
@@ -704,6 +932,131 @@
         return ret;
     if ((ret = graph_config_links(graphctx, log_ctx)))
         return ret;
+    if ((ret = ff_avfilter_graph_config_pointers(graphctx, log_ctx)))
+        return ret;
 
     return 0;
 }
+
+int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags)
+{
+    int i, r = AVERROR(ENOSYS);
+
+    if(!graph)
+        return r;
+
+    if((flags & AVFILTER_CMD_FLAG_ONE) && !(flags & AVFILTER_CMD_FLAG_FAST)) {
+        r=avfilter_graph_send_command(graph, target, cmd, arg, res, res_len, flags | AVFILTER_CMD_FLAG_FAST);
+        if(r != AVERROR(ENOSYS))
+            return r;
+    }
+
+    if(res_len && res)
+        res[0]= 0;
+
+    for (i = 0; i < graph->filter_count; i++) {
+        AVFilterContext *filter = graph->filters[i];
+        if(!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)){
+            r = avfilter_process_command(filter, cmd, arg, res, res_len, flags);
+            if(r != AVERROR(ENOSYS)) {
+                if((flags & AVFILTER_CMD_FLAG_ONE) || r<0)
+                    return r;
+            }
+        }
+    }
+
+    return r;
+}
+
+int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *command, const char *arg, int flags, double ts)
+{
+    int i;
+
+    if(!graph)
+        return 0;
+
+    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;
+            if(flags & AVFILTER_CMD_FLAG_ONE)
+                return 0;
+        }
+    }
+
+    return 0;
+}
+
+static void heap_bubble_up(AVFilterGraph *graph,
+                           AVFilterLink *link, int index)
+{
+    AVFilterLink **links = graph->sink_links;
+
+    while (index) {
+        int parent = (index - 1) >> 1;
+        if (links[parent]->current_pts >= link->current_pts)
+            break;
+        links[index] = links[parent];
+        links[index]->age_index = index;
+        index = parent;
+    }
+    links[index] = link;
+    link->age_index = index;
+}
+
+static void heap_bubble_down(AVFilterGraph *graph,
+                             AVFilterLink *link, int index)
+{
+    AVFilterLink **links = graph->sink_links;
+
+    while (1) {
+        int child = 2 * index + 1;
+        if (child >= graph->sink_links_count)
+            break;
+        if (child + 1 < graph->sink_links_count &&
+            links[child + 1]->current_pts < links[child]->current_pts)
+            child++;
+        if (link->current_pts < links[child]->current_pts)
+            break;
+        links[index] = links[child];
+        links[index]->age_index = index;
+        index = child;
+    }
+    links[index] = link;
+    link->age_index = index;
+}
+
+void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link)
+{
+    heap_bubble_up  (graph, link, link->age_index);
+    heap_bubble_down(graph, link, link->age_index);
+}
+
+
+int avfilter_graph_request_oldest(AVFilterGraph *graph)
+{
+    while (graph->sink_links_count) {
+        AVFilterLink *oldest = graph->sink_links[0];
+        int r = ff_request_frame(oldest);
+        if (r != AVERROR_EOF)
+            return r;
+        av_log(oldest->dst, AV_LOG_DEBUG, "EOF on sink link %s:%s.\n",
+               oldest->dst ? oldest->dst->name : "unknown",
+               oldest->dstpad ? oldest->dstpad->name : "unknown");
+        /* EOF: remove the link from the heap */
+        if (oldest->age_index < --graph->sink_links_count)
+            heap_bubble_down(graph, graph->sink_links[graph->sink_links_count],
+                             oldest->age_index);
+        oldest->age_index = -1;
+    }
+    return AVERROR_EOF;
+}
diff --git a/libavfilter/avfiltergraph.h b/libavfilter/avfiltergraph.h
index 7c4672d..0518124 100644
--- a/libavfilter/avfiltergraph.h
+++ b/libavfilter/avfiltergraph.h
@@ -2,20 +2,20 @@
  * Filter graphs
  * copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -31,6 +31,18 @@
     AVFilterContext **filters;
 
     char *scale_sws_opts; ///< sws options to use for the auto-inserted scale filters
+
+    /**
+     * Private fields
+     *
+     * The following fields are for internal use only.
+     * Their type, offset, number and semantic can change without notice.
+     */
+
+    AVFilterLink **sink_links;
+    int sink_links_count;
+
+    unsigned disable_auto_convert;
 } AVFilterGraph;
 
 /**
@@ -72,6 +84,21 @@
                                  AVFilterGraph *graph_ctx);
 
 /**
+ * Enable or disable automatic format conversion inside the graph.
+ *
+ * Note that format conversion can still happen inside explicitly inserted
+ * scale and aconvert filters.
+ *
+ * @param flags  any of the AVFILTER_AUTO_CONVERT_* constants
+ */
+void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags);
+
+enum {
+    AVFILTER_AUTO_CONVERT_ALL  =  0, /**< all automatic conversions enabled */
+    AVFILTER_AUTO_CONVERT_NONE = -1, /**< all automatic conversions disabled */
+};
+
+/**
  * Check validity and configure all the links and formats in the graph.
  *
  * @param graphctx the filter graph
@@ -127,12 +154,16 @@
  *
  * @param graph   the filter graph where to link the parsed graph context
  * @param filters string to be parsed
- * @param inputs  linked list to the inputs of the graph
- * @param outputs linked list to the outputs of the graph
- * @return zero on success, a negative AVERROR code on error
+ * @param inputs  pointer to a linked list to the inputs of the graph, may be NULL.
+ *                If non-NULL, *inputs is updated to contain the list of open inputs
+ *                after the parsing, should be freed with avfilter_inout_free().
+ * @param outputs pointer to a linked list to the outputs of the graph, may be NULL.
+ *                If non-NULL, *outputs is updated to contain the list of open outputs
+ *                after the parsing, should be freed with avfilter_inout_free().
+ * @return non negative on success, a negative AVERROR code on error
  */
 int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
-                         AVFilterInOut *inputs, AVFilterInOut *outputs,
+                         AVFilterInOut **inputs, AVFilterInOut **outputs,
                          void *log_ctx);
 
 /**
@@ -169,4 +200,70 @@
                           AVFilterInOut **inputs,
                           AVFilterInOut **outputs);
 
+
+/**
+ * Send a command to one or more filter instances.
+ *
+ * @param graph  the filter graph
+ * @param target the filter(s) to which the command should be sent
+ *               "all" sends to all filters
+ *               otherwise it can be a filter or filter instance name
+ *               which will send the command to all matching filters.
+ * @param cmd    the command to sent, for handling simplicity all commands must be alphanumeric only
+ * @param arg    the argument for the command
+ * @param res    a buffer with size res_size where the filter(s) can return a response.
+ *
+ * @returns >=0 on success otherwise an error code.
+ *              AVERROR(ENOSYS) on unsupported commands
+ */
+int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags);
+
+/**
+ * Queue a command for one or more filter instances.
+ *
+ * @param graph  the filter graph
+ * @param target the filter(s) to which the command should be sent
+ *               "all" sends to all filters
+ *               otherwise it can be a filter or filter instance name
+ *               which will send the command to all matching filters.
+ * @param cmd    the command to sent, for handling simplicity all commands must be alphanummeric only
+ * @param arg    the argument for the command
+ * @param ts     time at which the command should be sent to the filter
+ *
+ * @note As this executes commands after this function returns, no return code
+ *       from the filter is provided, also AVFILTER_CMD_FLAG_ONE is not supported.
+ */
+int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, int flags, double ts);
+
+
+/**
+ * Dump a graph into a human-readable string representation.
+ *
+ * @param graph    the graph to dump
+ * @param options  formatting options; currently ignored
+ * @return  a string, or NULL in case of memory allocation failure;
+ *          the string must be freed using av_free
+ */
+char *avfilter_graph_dump(AVFilterGraph *graph, const char *options);
+
+/**
+ * Request a frame on the oldest sink link.
+ *
+ * If the request returns AVERROR_EOF, try the next.
+ *
+ * Note that this function is not meant to be the sole scheduling mechanism
+ * of a filtergraph, only a convenience function to help drain a filtergraph
+ * in a balanced way under normal circumstances.
+ *
+ * Also note that AVERROR_EOF does not mean that frames did not arrive on
+ * some of the sinks during the process.
+ * When there are multiple sink links, in case the requested link
+ * returns an EOF, this may cause a filter to flush pending frames
+ * which are sent to another sink link, although unrequested.
+ *
+ * @return  the return value of ff_request_frame(),
+ *          or AVERROR_EOF if all links returned AVERROR_EOF
+ */
+int avfilter_graph_request_oldest(AVFilterGraph *graph);
+
 #endif /* AVFILTER_AVFILTERGRAPH_H */
diff --git a/libavfilter/bbox.c b/libavfilter/bbox.c
new file mode 100644
index 0000000..be9b2e6
--- /dev/null
+++ b/libavfilter/bbox.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2005 Robert Edele <yartrebo@earthlink.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 "bbox.h"
+
+int ff_calculate_bounding_box(FFBoundingBox *bbox,
+                              const uint8_t *data, int linesize, int w, int h,
+                              int min_val)
+{
+    int x, y;
+    int start_x;
+    int start_y;
+    int end_x;
+    int end_y;
+    const uint8_t *line;
+
+    /* left bound */
+    for (start_x = 0; start_x < w; start_x++)
+        for (y = 0; y < h; y++)
+            if ((data[y * linesize + start_x] > min_val))
+                goto outl;
+outl:
+    if (start_x == w) /* no points found */
+        return 0;
+
+    /* right bound */
+    for (end_x = w - 1; end_x >= start_x; end_x--)
+        for (y = 0; y < h; y++)
+            if ((data[y * linesize + end_x] > min_val))
+                goto outr;
+outr:
+
+    /* top bound */
+    line = data;
+    for (start_y = 0; start_y < h; start_y++) {
+        for (x = 0; x < w; x++)
+            if (line[x] > min_val)
+                goto outt;
+        line += linesize;
+    }
+outt:
+
+    /* bottom bound */
+    line = data + (h-1)*linesize;
+    for (end_y = h - 1; end_y >= start_y; end_y--) {
+        for (x = 0; x < w; x++)
+            if (line[x] > min_val)
+                goto outb;
+        line -= linesize;
+    }
+outb:
+
+    bbox->x1 = start_x;
+    bbox->y1 = start_y;
+    bbox->x2 = end_x;
+    bbox->y2 = end_y;
+    return 1;
+}
diff --git a/libavfilter/bbox.h b/libavfilter/bbox.h
new file mode 100644
index 0000000..eb73154
--- /dev/null
+++ b/libavfilter/bbox.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2005 Robert Edele <yartrebo@earthlink.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
+ */
+
+#ifndef AVFILTER_BBOX_H
+#define AVFILTER_BBOX_H
+
+#include <stdint.h>
+
+typedef struct {
+    int x1, x2, y1, y2;
+} FFBoundingBox;
+
+/**
+ * Calculate the smallest rectangle that will encompass the
+ * region with values > min_val.
+ *
+ * @param bbox bounding box structure which is updated with the found values.
+ *             If no pixels could be found with value > min_val, the
+ *             structure is not modified.
+ * @return 1 in case at least one pixel with value > min_val was found,
+ *         0 otherwise
+ */
+int ff_calculate_bounding_box(FFBoundingBox *bbox,
+                              const uint8_t *data, int linesize,
+                              int w, int h, int min_val);
+
+#endif /* AVFILTER_BBOX_H */
diff --git a/libavfilter/buffer.c b/libavfilter/buffer.c
index 439425a..fc65b82 100644
--- a/libavfilter/buffer.c
+++ b/libavfilter/buffer.c
@@ -1,29 +1,36 @@
 /*
- * This file is part of Libav.
+ * Copyright Stefano Sabatini <stefasab gmail com>
+ * Copyright Anton Khirnov <anton khirnov net>
+ * Copyright Michael Niedermayer <michaelni gmx at>
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
 #include "libavutil/common.h"
+#include "libavutil/imgutils.h"
 #include "libavcodec/avcodec.h"
 
 #include "avfilter.h"
 #include "internal.h"
+#include "audio.h"
+#include "avcodec.h"
 
-/* TODO: buffer pool.  see comment for avfilter_default_get_video_buffer() */
 void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
 {
     if (ptr->extended_data != ptr->data)
@@ -32,6 +39,15 @@
     av_free(ptr);
 }
 
+static void copy_video_props(AVFilterBufferRefVideoProps *dst, AVFilterBufferRefVideoProps *src) {
+    *dst = *src;
+    if (src->qp_table) {
+        int qsize = src->qp_table_size;
+        dst->qp_table = av_malloc(qsize);
+        memcpy(dst->qp_table, src->qp_table, qsize);
+    }
+}
+
 AVFilterBufferRef *avfilter_ref_buffer(AVFilterBufferRef *ref, int pmask)
 {
     AVFilterBufferRef *ret = av_malloc(sizeof(AVFilterBufferRef));
@@ -44,7 +60,7 @@
             av_free(ret);
             return NULL;
         }
-        *ret->video = *ref->video;
+        copy_video_props(ret->video, ref->video);
         ret->extended_data = ret->data;
     } else if (ref->type == AVMEDIA_TYPE_AUDIO) {
         ret->audio = av_malloc(sizeof(AVFilterBufferRefAudioProps));
@@ -54,7 +70,7 @@
         }
         *ret->audio = *ref->audio;
 
-        if (ref->extended_data != ref->data) {
+        if (ref->extended_data && ref->extended_data != ref->data) {
             int nb_channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout);
             if (!(ret->extended_data = av_malloc(sizeof(*ret->extended_data) *
                                                  nb_channels))) {
@@ -72,16 +88,90 @@
     return ret;
 }
 
+void ff_free_pool(AVFilterPool *pool)
+{
+    int i;
+
+    av_assert0(pool->refcount > 0);
+
+    for (i = 0; i < POOL_SIZE; i++) {
+        if (pool->pic[i]) {
+            AVFilterBufferRef *picref = pool->pic[i];
+            /* free buffer: picrefs stored in the pool are not
+             * supposed to contain a free callback */
+            av_assert0(!picref->buf->refcount);
+            av_freep(&picref->buf->data[0]);
+            av_freep(&picref->buf);
+
+            av_freep(&picref->audio);
+            av_assert0(!picref->video || !picref->video->qp_table);
+            av_freep(&picref->video);
+            av_freep(&pool->pic[i]);
+            pool->count--;
+        }
+    }
+    pool->draining = 1;
+
+    if (!--pool->refcount) {
+        av_assert0(!pool->count);
+        av_free(pool);
+    }
+}
+
+static void store_in_pool(AVFilterBufferRef *ref)
+{
+    int i;
+    AVFilterPool *pool= ref->buf->priv;
+
+    av_assert0(ref->buf->data[0]);
+    av_assert0(pool->refcount>0);
+
+    if (ref->video)
+        av_freep(&ref->video->qp_table);
+
+    if (pool->count == POOL_SIZE) {
+        AVFilterBufferRef *ref1 = pool->pic[0];
+        av_freep(&ref1->video);
+        av_freep(&ref1->audio);
+        av_freep(&ref1->buf->data[0]);
+        av_freep(&ref1->buf);
+        av_free(ref1);
+        memmove(&pool->pic[0], &pool->pic[1], sizeof(void*)*(POOL_SIZE-1));
+        pool->count--;
+        pool->pic[POOL_SIZE-1] = NULL;
+    }
+
+    for (i = 0; i < POOL_SIZE; i++) {
+        if (!pool->pic[i]) {
+            pool->pic[i] = ref;
+            pool->count++;
+            break;
+        }
+    }
+    if (pool->draining) {
+        ff_free_pool(pool);
+    } else
+        --pool->refcount;
+}
+
 void avfilter_unref_buffer(AVFilterBufferRef *ref)
 {
     if (!ref)
         return;
-    if (!(--ref->buf->refcount))
+    av_assert0(ref->buf->refcount > 0);
+    if (!(--ref->buf->refcount)) {
+        if (!ref->buf->free) {
+            store_in_pool(ref);
+            return;
+        }
         ref->buf->free(ref->buf);
+    }
     if (ref->extended_data != ref->data)
         av_freep(&ref->extended_data);
-    av_free(ref->video);
-    av_free(ref->audio);
+    if (ref->video)
+        av_freep(&ref->video->qp_table);
+    av_freep(&ref->video);
+    av_freep(&ref->audio);
     av_free(ref);
 }
 
@@ -91,76 +181,6 @@
     *ref = NULL;
 }
 
-int avfilter_copy_frame_props(AVFilterBufferRef *dst, const AVFrame *src)
-{
-    dst->pts    = src->pts;
-    dst->format = src->format;
-
-    switch (dst->type) {
-    case AVMEDIA_TYPE_VIDEO:
-        dst->video->w                   = src->width;
-        dst->video->h                   = src->height;
-        dst->video->pixel_aspect        = src->sample_aspect_ratio;
-        dst->video->interlaced          = src->interlaced_frame;
-        dst->video->top_field_first     = src->top_field_first;
-        dst->video->key_frame           = src->key_frame;
-        dst->video->pict_type           = src->pict_type;
-        break;
-    case AVMEDIA_TYPE_AUDIO:
-        dst->audio->sample_rate         = src->sample_rate;
-        dst->audio->channel_layout      = src->channel_layout;
-        break;
-    default:
-        return AVERROR(EINVAL);
-    }
-
-    return 0;
-}
-
-int avfilter_copy_buf_props(AVFrame *dst, const AVFilterBufferRef *src)
-{
-    int planes, nb_channels;
-
-    memcpy(dst->data, src->data, sizeof(dst->data));
-    memcpy(dst->linesize, src->linesize, sizeof(dst->linesize));
-
-    dst->pts     = src->pts;
-    dst->format  = src->format;
-
-    switch (src->type) {
-    case AVMEDIA_TYPE_VIDEO:
-        dst->width               = src->video->w;
-        dst->height              = src->video->h;
-        dst->sample_aspect_ratio = src->video->pixel_aspect;
-        dst->interlaced_frame    = src->video->interlaced;
-        dst->top_field_first     = src->video->top_field_first;
-        dst->key_frame           = src->video->key_frame;
-        dst->pict_type           = src->video->pict_type;
-        break;
-    case AVMEDIA_TYPE_AUDIO:
-        nb_channels = av_get_channel_layout_nb_channels(src->audio->channel_layout);
-        planes      = av_sample_fmt_is_planar(src->format) ? nb_channels : 1;
-
-        if (planes > FF_ARRAY_ELEMS(dst->data)) {
-            dst->extended_data = av_mallocz(planes * sizeof(*dst->extended_data));
-            if (!dst->extended_data)
-                return AVERROR(ENOMEM);
-            memcpy(dst->extended_data, src->extended_data,
-                   planes * sizeof(*dst->extended_data));
-        } else
-            dst->extended_data = dst->data;
-
-        dst->sample_rate         = src->audio->sample_rate;
-        dst->channel_layout      = src->audio->channel_layout;
-        dst->nb_samples          = src->audio->nb_samples;
-        break;
-    default:
-        return AVERROR(EINVAL);
-    }
-
-    return 0;
-}
-
 void avfilter_copy_buffer_ref_props(AVFilterBufferRef *dst, AVFilterBufferRef *src)
 {
     // copy common properties
@@ -168,8 +188,50 @@
     dst->pos             = src->pos;
 
     switch (src->type) {
-    case AVMEDIA_TYPE_VIDEO: *dst->video = *src->video; break;
+    case AVMEDIA_TYPE_VIDEO: {
+        if (dst->video->qp_table)
+            av_freep(&dst->video->qp_table);
+        copy_video_props(dst->video, src->video);
+        break;
+    }
     case AVMEDIA_TYPE_AUDIO: *dst->audio = *src->audio; break;
     default: break;
     }
 }
+
+AVFilterBufferRef *ff_copy_buffer_ref(AVFilterLink *outlink,
+                                      AVFilterBufferRef *ref)
+{
+    AVFilterBufferRef *buf;
+    int channels;
+
+    switch (outlink->type) {
+
+    case AVMEDIA_TYPE_VIDEO:
+        buf = ff_get_video_buffer(outlink, AV_PERM_WRITE,
+                                  ref->video->w, ref->video->h);
+        if(!buf)
+            return NULL;
+        av_image_copy(buf->data, buf->linesize,
+                      (void*)ref->data, ref->linesize,
+                      ref->format, ref->video->w, ref->video->h);
+        break;
+
+    case AVMEDIA_TYPE_AUDIO:
+        buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE,
+                                        ref->audio->nb_samples);
+        if(!buf)
+            return NULL;
+        channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout);
+        av_samples_copy(buf->extended_data, ref->buf->extended_data,
+                        0, 0, ref->audio->nb_samples,
+                        channels,
+                        ref->format);
+        break;
+
+    default:
+        return NULL;
+    }
+    avfilter_copy_buffer_ref_props(buf, ref);
+    return buf;
+}
diff --git a/libavfilter/bufferqueue.h b/libavfilter/bufferqueue.h
new file mode 100644
index 0000000..a27fb86
--- /dev/null
+++ b/libavfilter/bufferqueue.h
@@ -0,0 +1,111 @@
+/*
+ * Generic buffer queue
+ * 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
+ */
+
+#ifndef AVFILTER_BUFFERQUEUE_H
+#define AVFILTER_BUFFERQUEUE_H
+
+/**
+ * FFBufQueue: simple AVFilterBufferRef queue API
+ *
+ * Note: this API is not thread-safe. Concurrent access to the same queue
+ * must be protected by a mutex or any synchronization mechanism.
+ */
+
+/**
+ * Maximum size of the queue.
+ *
+ * This value can be overridden by definying it before including this
+ * header.
+ * Powers of 2 are recommended.
+ */
+#ifndef FF_BUFQUEUE_SIZE
+#define FF_BUFQUEUE_SIZE 32
+#endif
+
+#include "avfilter.h"
+#include "libavutil/avassert.h"
+
+/**
+ * Structure holding the queue
+ */
+struct FFBufQueue {
+    AVFilterBufferRef *queue[FF_BUFQUEUE_SIZE];
+    unsigned short head;
+    unsigned short available; /**< number of available buffers */
+};
+
+#define BUCKET(i) queue->queue[(queue->head + (i)) % FF_BUFQUEUE_SIZE]
+
+/**
+ * Add a buffer to the queue.
+ *
+ * If the queue is already full, then the current last buffer is dropped
+ * (and unrefed) with a warning before adding the new buffer.
+ */
+static inline void ff_bufqueue_add(void *log, struct FFBufQueue *queue,
+                                   AVFilterBufferRef *buf)
+{
+    if (queue->available == FF_BUFQUEUE_SIZE) {
+        av_log(log, AV_LOG_WARNING, "Buffer queue overflow, dropping.\n");
+        avfilter_unref_buffer(BUCKET(--queue->available));
+    }
+    BUCKET(queue->available++) = buf;
+}
+
+/**
+ * Get a buffer from the queue without altering it.
+ *
+ * Buffer with index 0 is the first buffer in the queue.
+ * Return NULL if the queue has not enough buffers.
+ */
+static inline AVFilterBufferRef *ff_bufqueue_peek(struct FFBufQueue *queue,
+                                                  unsigned index)
+{
+    return index < queue->available ? BUCKET(index) : NULL;
+}
+
+/**
+ * Get the first buffer from the queue and remove it.
+ *
+ * Do not use on an empty queue.
+ */
+static inline AVFilterBufferRef *ff_bufqueue_get(struct FFBufQueue *queue)
+{
+    AVFilterBufferRef *ret = queue->queue[queue->head];
+    av_assert0(queue->available);
+    queue->available--;
+    queue->queue[queue->head] = NULL;
+    queue->head = (queue->head + 1) % FF_BUFQUEUE_SIZE;
+    return ret;
+}
+
+/**
+ * Unref and remove all buffers from the queue.
+ */
+static inline void ff_bufqueue_discard_all(struct FFBufQueue *queue)
+{
+    while (queue->available)
+        avfilter_unref_buffer(ff_bufqueue_get(queue));
+}
+
+#undef BUCKET
+
+#endif /* AVFILTER_BUFFERQUEUE_H */
diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
index 73af25d..9a9aaf1 100644
--- a/libavfilter/buffersink.c
+++ b/libavfilter/buffersink.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2011 Stefano Sabatini
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -52,14 +52,14 @@
 {
     BufferSinkContext *s = link->dst->priv;
 
-    av_assert0(!s->cur_buf);
+//     av_assert0(!s->cur_buf);
     s->cur_buf    = buf;
     link->cur_buf = NULL;
 
     return 0;
-};
+}
 
-int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
+int ff_buffersink_read_compat(AVFilterContext *ctx, AVFilterBufferRef **buf)
 {
     BufferSinkContext *s    = ctx->priv;
     AVFilterLink      *link = ctx->inputs[0];
@@ -100,8 +100,8 @@
 
 }
 
-int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **pbuf,
-                               int nb_samples)
+int ff_buffersink_read_samples_compat(AVFilterContext *ctx, AVFilterBufferRef **pbuf,
+                                      int nb_samples)
 {
     BufferSinkContext *s = ctx->priv;
     AVFilterLink   *link = ctx->inputs[0];
@@ -152,7 +152,11 @@
 };
 
 AVFilter avfilter_vsink_buffer = {
+#if AV_HAVE_INCOMPATIBLE_FORK_ABI
     .name      = "buffersink",
+#else
+    .name      = "buffersink_old",
+#endif
     .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
     .priv_size = sizeof(BufferSinkContext),
     .uninit    = uninit,
@@ -173,7 +177,11 @@
 };
 
 AVFilter avfilter_asink_abuffer = {
+#if AV_HAVE_INCOMPATIBLE_FORK_ABI
     .name      = "abuffersink",
+#else
+    .name      = "abuffersink_old",
+#endif
     .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
     .priv_size = sizeof(BufferSinkContext),
     .uninit    = uninit,
diff --git a/libavfilter/buffersink.h b/libavfilter/buffersink.h
index e358ac3..a401937 100644
--- a/libavfilter/buffersink.h
+++ b/libavfilter/buffersink.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -21,12 +21,93 @@
 
 /**
  * @file
- * memory buffer sink API
+ * memory buffer sink API for audio and video
  */
 
 #include "avfilter.h"
 
 /**
+ * Struct to use for initializing a buffersink context.
+ */
+typedef struct {
+    const enum AVPixelFormat *pixel_fmts; ///< list of allowed pixel formats, terminated by AV_PIX_FMT_NONE
+} AVBufferSinkParams;
+
+/**
+ * Create an AVBufferSinkParams structure.
+ *
+ * Must be freed with av_free().
+ */
+AVBufferSinkParams *av_buffersink_params_alloc(void);
+
+/**
+ * Struct to use for initializing an abuffersink context.
+ */
+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
+} AVABufferSinkParams;
+
+/**
+ * Create an AVABufferSinkParams structure.
+ *
+ * Must be freed with av_free().
+ */
+AVABufferSinkParams *av_abuffersink_params_alloc(void);
+
+/**
+ * Set the frame size for an audio buffer sink.
+ *
+ * All calls to av_buffersink_get_buffer_ref will return a buffer with
+ * exactly the specified number of samples, or AVERROR(EAGAIN) if there is
+ * not enough. The last buffer at EOF will be padded with 0.
+ */
+void av_buffersink_set_frame_size(AVFilterContext *ctx, unsigned frame_size);
+
+/**
+ * Tell av_buffersink_get_buffer_ref() to read video/samples buffer
+ * reference, but not remove it from the buffer. This is useful if you
+ * need only to read a video/samples buffer, without to fetch it.
+ */
+#define AV_BUFFERSINK_FLAG_PEEK 1
+
+/**
+ * Tell av_buffersink_get_buffer_ref() not to request a frame from its input.
+ * If a frame is already buffered, it is read (and removed from the buffer),
+ * but if no frame is present, return AVERROR(EAGAIN).
+ */
+#define AV_BUFFERSINK_FLAG_NO_REQUEST 2
+
+/**
+ * Get an audio/video buffer data from buffer_sink and put it in bufref.
+ *
+ * This function works with both audio and video buffer sinks.
+ *
+ * @param buffer_sink pointer to a buffersink or abuffersink context
+ * @param flags a combination of AV_BUFFERSINK_FLAG_* flags
+ * @return >= 0 in case of success, a negative AVERROR code in case of
+ * failure
+ */
+int av_buffersink_get_buffer_ref(AVFilterContext *buffer_sink,
+                                 AVFilterBufferRef **bufref, int flags);
+
+
+/**
+ * Get the number of immediately available frames.
+ */
+int av_buffersink_poll_frame(AVFilterContext *ctx);
+
+/**
+ * Get the frame rate of the input.
+ */
+AVRational av_buffersink_get_frame_rate(AVFilterContext *ctx);
+
+/**
+ * @defgroup libav_api Libav API
+ * @{
+ */
+
+/**
  * Get a buffer with filtered data from sink and put it in buf.
  *
  * @param ctx pointer to a context of a buffersink or abuffersink AVFilter.
@@ -59,4 +140,8 @@
 int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf,
                                int nb_samples);
 
+/**
+ * @}
+ */
+
 #endif /* AVFILTER_BUFFERSINK_H */
diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
index a2d5edb..b4b502a 100644
--- a/libavfilter/buffersrc.c
+++ b/libavfilter/buffersrc.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,6 +29,7 @@
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
+#include "avcodec.h"
 
 #include "libavutil/audioconvert.h"
 #include "libavutil/common.h"
@@ -41,11 +42,15 @@
     const AVClass    *class;
     AVFifoBuffer     *fifo;
     AVRational        time_base;     ///< time_base to set in the output link
+    AVRational        frame_rate;    ///< frame_rate to set in the output link
+    unsigned          nb_failed_requests;
+    unsigned          warning_limit;
 
     /* video only */
-    int               h, w;
+    int               w, h;
     enum AVPixelFormat  pix_fmt;
     AVRational        pixel_aspect;
+    char              *sws_param;
 
     /* audio only */
     int sample_rate;
@@ -70,65 +75,34 @@
         return AVERROR(EINVAL);\
     }
 
-int av_buffersrc_write_frame(AVFilterContext *buffer_filter, const AVFrame *frame)
+int av_buffersrc_add_frame(AVFilterContext *buffer_src,
+                           const AVFrame *frame, int flags)
 {
-    BufferSourceContext *c = buffer_filter->priv;
-    AVFilterBufferRef *buf;
+    AVFilterBufferRef *picref;
     int ret;
 
-    if (!frame) {
-        c->eof = 1;
-        return 0;
-    } else if (c->eof)
-        return AVERROR(EINVAL);
+    if (!frame) /* NULL for EOF */
+        return av_buffersrc_add_ref(buffer_src, NULL, flags);
 
-    if (!av_fifo_space(c->fifo) &&
-        (ret = av_fifo_realloc2(c->fifo, av_fifo_size(c->fifo) +
-                                         sizeof(buf))) < 0)
-        return ret;
-
-    switch (buffer_filter->outputs[0]->type) {
-    case AVMEDIA_TYPE_VIDEO:
-        CHECK_VIDEO_PARAM_CHANGE(buffer_filter, c, frame->width, frame->height,
-                                 frame->format);
-        buf = ff_get_video_buffer(buffer_filter->outputs[0], AV_PERM_WRITE,
-                                  c->w, c->h);
-        if (!buf)
-            return AVERROR(ENOMEM);
-
-        av_image_copy(buf->data, buf->linesize, frame->data, frame->linesize,
-                      c->pix_fmt, c->w, c->h);
-        break;
-    case AVMEDIA_TYPE_AUDIO:
-        CHECK_AUDIO_PARAM_CHANGE(buffer_filter, c, frame->sample_rate, frame->channel_layout,
-                                 frame->format);
-        buf = ff_get_audio_buffer(buffer_filter->outputs[0], AV_PERM_WRITE,
-                                  frame->nb_samples);
-        if (!buf)
-            return AVERROR(ENOMEM);
-
-        av_samples_copy(buf->extended_data, frame->extended_data,
-                        0, 0, frame->nb_samples,
-                        av_get_channel_layout_nb_channels(frame->channel_layout),
-                        frame->format);
-        break;
-    default:
-        return AVERROR(EINVAL);
-    }
-
-    avfilter_copy_frame_props(buf, frame);
-
-    if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0) {
-        avfilter_unref_buffer(buf);
-        return ret;
-    }
-
-    return 0;
+    picref = avfilter_get_buffer_ref_from_frame(buffer_src->outputs[0]->type,
+                                                frame, AV_PERM_WRITE);
+    if (!picref)
+        return AVERROR(ENOMEM);
+    ret = av_buffersrc_add_ref(buffer_src, picref, flags);
+    picref->buf->data[0] = NULL;
+    avfilter_unref_buffer(picref);
+    return ret;
 }
 
-int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf)
+int av_buffersrc_write_frame(AVFilterContext *buffer_filter, const AVFrame *frame)
+{
+    return av_buffersrc_add_frame(buffer_filter, frame, 0);
+}
+
+int av_buffersrc_add_ref(AVFilterContext *s, AVFilterBufferRef *buf, int flags)
 {
     BufferSourceContext *c = s->priv;
+    AVFilterBufferRef *to_free = NULL;
     int ret;
 
     if (!buf) {
@@ -142,69 +116,137 @@
                                          sizeof(buf))) < 0)
         return ret;
 
-    switch (s->outputs[0]->type) {
-    case AVMEDIA_TYPE_VIDEO:
-        CHECK_VIDEO_PARAM_CHANGE(s, c, buf->video->w, buf->video->h, buf->format);
-        break;
-    case AVMEDIA_TYPE_AUDIO:
-        CHECK_AUDIO_PARAM_CHANGE(s, c, buf->audio->sample_rate, buf->audio->channel_layout,
-                                 buf->format);
-        break;
-    default:
-        return AVERROR(EINVAL);
+    if (!(flags & AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT)) {
+        switch (s->outputs[0]->type) {
+        case AVMEDIA_TYPE_VIDEO:
+            CHECK_VIDEO_PARAM_CHANGE(s, c, buf->video->w, buf->video->h, buf->format);
+            break;
+        case AVMEDIA_TYPE_AUDIO:
+            CHECK_AUDIO_PARAM_CHANGE(s, c, buf->audio->sample_rate, buf->audio->channel_layout,
+                                     buf->format);
+            break;
+        default:
+            return AVERROR(EINVAL);
+        }
+    }
+    if (!(flags & AV_BUFFERSRC_FLAG_NO_COPY))
+        to_free = buf = ff_copy_buffer_ref(s->outputs[0], buf);
+    if(!buf)
+        return -1;
+
+    if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0) {
+        avfilter_unref_buffer(to_free);
+        return ret;
+    }
+    c->nb_failed_requests = 0;
+    if (c->warning_limit &&
+        av_fifo_size(c->fifo) / sizeof(buf) >= c->warning_limit) {
+        av_log(s, AV_LOG_WARNING,
+               "%d buffers queued in %s, something may be wrong.\n",
+               c->warning_limit,
+               (char *)av_x_if_null(s->name, s->filter->name));
+        c->warning_limit *= 10;
     }
 
-    if ((ret = av_fifo_generic_write(c->fifo, &buf, sizeof(buf), NULL)) < 0)
-        return ret;
+    if ((flags & AV_BUFFERSRC_FLAG_PUSH))
+        if ((ret = s->output_pads[0].request_frame(s->outputs[0])) < 0)
+            return ret;
 
     return 0;
 }
 
+#ifdef FF_API_BUFFERSRC_BUFFER
+int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf)
+{
+    return av_buffersrc_add_ref(s, buf, AV_BUFFERSRC_FLAG_NO_COPY);
+}
+#endif
+
+unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src)
+{
+    return ((BufferSourceContext *)buffer_src->priv)->nb_failed_requests;
+}
+
+#define OFFSET(x) offsetof(BufferSourceContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption buffer_options[] = {
+    { "time_base",      NULL, OFFSET(time_base),           AV_OPT_TYPE_RATIONAL,   { .dbl = 0 }, 0, INT_MAX, FLAGS },
+    { "frame_rate",     NULL, OFFSET(frame_rate),          AV_OPT_TYPE_RATIONAL,   { .dbl = 0 }, 0, INT_MAX, FLAGS },
+    { "video_size",     NULL, OFFSET(w),                   AV_OPT_TYPE_IMAGE_SIZE, .flags = FLAGS },
+    { "pix_fmt",        NULL, OFFSET(pix_fmt),             AV_OPT_TYPE_PIXEL_FMT,  .flags = FLAGS },
+    { "pixel_aspect",   NULL, OFFSET(pixel_aspect),        AV_OPT_TYPE_RATIONAL,   { .dbl = 0 }, 0, INT_MAX, FLAGS },
+    { "sws_param",      NULL, OFFSET(sws_param),           AV_OPT_TYPE_STRING,     .flags = FLAGS },
+    { NULL },
+};
+#undef FLAGS
+
+AVFILTER_DEFINE_CLASS(buffer);
+
 static av_cold int init_video(AVFilterContext *ctx, const char *args)
 {
     BufferSourceContext *c = ctx->priv;
-    char pix_fmt_str[128];
-    int n = 0;
+    char pix_fmt_str[128], sws_param[256] = "", *colon, *equal;
+    int ret, n = 0;
 
-    if (!args ||
-        (n = sscanf(args, "%d:%d:%127[^:]:%d:%d:%d:%d", &c->w, &c->h, pix_fmt_str,
-                    &c->time_base.num, &c->time_base.den,
-                    &c->pixel_aspect.num, &c->pixel_aspect.den)) != 7) {
-        av_log(ctx, AV_LOG_ERROR, "Expected 7 arguments, but %d found in '%s'\n", n, args);
+    c->class = &buffer_class;
+
+    if (!args) {
+        av_log(ctx, AV_LOG_ERROR, "Arguments required\n");
         return AVERROR(EINVAL);
     }
-    if ((c->pix_fmt = av_get_pix_fmt(pix_fmt_str)) == AV_PIX_FMT_NONE) {
-        char *tail;
-        c->pix_fmt = strtol(pix_fmt_str, &tail, 10);
-        if (*tail || c->pix_fmt < 0 || c->pix_fmt >= AV_PIX_FMT_NB) {
-            av_log(ctx, AV_LOG_ERROR, "Invalid pixel format string '%s'\n", pix_fmt_str);
-            return AVERROR(EINVAL);
-        }
+    colon = strchr(args, ':');
+    equal = strchr(args, '=');
+    if (equal && (!colon || equal < colon)) {
+        av_opt_set_defaults(c);
+        ret = av_set_options_string(c, args, "=", ":");
+        if (ret < 0)
+            goto fail;
+    } else {
+    if ((n = sscanf(args, "%d:%d:%127[^:]:%d:%d:%d:%d:%255c", &c->w, &c->h, pix_fmt_str,
+                    &c->time_base.num, &c->time_base.den,
+                    &c->pixel_aspect.num, &c->pixel_aspect.den, sws_param)) < 7) {
+        av_log(ctx, AV_LOG_ERROR, "Expected at least 7 arguments, but only %d found in '%s'\n", n, args);
+        ret = AVERROR(EINVAL);
+        goto fail;
+    }
+    av_log(ctx, AV_LOG_WARNING, "Flat options syntax is deprecated, use key=value pairs\n");
+
+    if ((ret = ff_parse_pixel_format(&c->pix_fmt, pix_fmt_str, ctx)) < 0)
+        goto fail;
+    c->sws_param = av_strdup(sws_param);
+    if (!c->sws_param) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
     }
 
-    if (!(c->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*))))
-        return AVERROR(ENOMEM);
+    if (!(c->fifo = av_fifo_alloc(sizeof(AVFilterBufferRef*)))) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
 
-    av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s\n", c->w, c->h, av_get_pix_fmt_name(c->pix_fmt));
+    av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d pixfmt:%s tb:%d/%d fr:%d/%d sar:%d/%d sws_param:%s\n",
+           c->w, c->h, av_get_pix_fmt_name(c->pix_fmt),
+           c->time_base.num, c->time_base.den, c->frame_rate.num, c->frame_rate.den,
+           c->pixel_aspect.num, c->pixel_aspect.den, (char *)av_x_if_null(c->sws_param, ""));
+    c->warning_limit = 100;
     return 0;
+
+fail:
+    av_opt_free(c);
+    return ret;
 }
 
-#define OFFSET(x) offsetof(BufferSourceContext, x)
-#define A AV_OPT_FLAG_AUDIO_PARAM
-static const AVOption audio_options[] = {
-    { "time_base",      NULL, OFFSET(time_base),           AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, A },
-    { "sample_rate",    NULL, OFFSET(sample_rate),         AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, INT_MAX, A },
-    { "sample_fmt",     NULL, OFFSET(sample_fmt_str),      AV_OPT_TYPE_STRING,             .flags = A },
-    { "channel_layout", NULL, OFFSET(channel_layout_str),  AV_OPT_TYPE_STRING,             .flags = A },
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
+static const AVOption abuffer_options[] = {
+    { "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 },
+    { "channel_layout", NULL, OFFSET(channel_layout_str),  AV_OPT_TYPE_STRING, .flags = FLAGS },
     { NULL },
 };
 
-static const AVClass abuffer_class = {
-    .class_name = "abuffer source",
-    .item_name  = av_default_item_name,
-    .option     = audio_options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+AVFILTER_DEFINE_CLASS(abuffer);
 
 static av_cold int init_audio(AVFilterContext *ctx, const char *args)
 {
@@ -214,14 +256,12 @@
     s->class = &abuffer_class;
     av_opt_set_defaults(s);
 
-    if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing options string: %s.\n", args);
+    if ((ret = av_set_options_string(s, args, "=", ":")) < 0)
         goto fail;
-    }
 
     s->sample_fmt = av_get_sample_fmt(s->sample_fmt_str);
     if (s->sample_fmt == AV_SAMPLE_FMT_NONE) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid sample format %s.\n",
+        av_log(ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n",
                s->sample_fmt_str);
         ret = AVERROR(EINVAL);
         goto fail;
@@ -229,7 +269,7 @@
 
     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",
+        av_log(ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n",
                s->channel_layout_str);
         ret = AVERROR(EINVAL);
         goto fail;
@@ -243,9 +283,11 @@
     if (!s->time_base.num)
         s->time_base = (AVRational){1, s->sample_rate};
 
-    av_log(ctx, AV_LOG_VERBOSE, "tb:%d/%d samplefmt:%s samplerate: %d "
-           "ch layout:%s\n", s->time_base.num, s->time_base.den, s->sample_fmt_str,
+    av_log(ctx, AV_LOG_VERBOSE,
+           "tb:%d/%d samplefmt:%s samplerate:%d chlayout:%s\n",
+           s->time_base.num, s->time_base.den, s->sample_fmt_str,
            s->sample_rate, s->channel_layout_str);
+    s->warning_limit = 100;
 
 fail:
     av_opt_free(s);
@@ -262,6 +304,7 @@
     }
     av_fifo_free(s->fifo);
     s->fifo = NULL;
+    av_freep(&s->sws_param);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -312,6 +355,7 @@
     }
 
     link->time_base = c->time_base;
+    link->frame_rate = c->frame_rate;
     return 0;
 }
 
@@ -324,6 +368,7 @@
     if (!av_fifo_size(c->fifo)) {
         if (c->eof)
             return AVERROR_EOF;
+        c->nb_failed_requests++;
         return AVERROR(EAGAIN);
     }
     av_fifo_generic_read(c->fifo, &buf, sizeof(buf), NULL);
@@ -377,6 +422,7 @@
 
     .inputs    = NULL,
     .outputs   = avfilter_vsrc_buffer_outputs,
+    .priv_class = &buffer_class,
 };
 
 static const AVFilterPad avfilter_asrc_abuffer_outputs[] = {
@@ -401,4 +447,5 @@
 
     .inputs    = NULL,
     .outputs   = avfilter_asrc_abuffer_outputs,
+    .priv_class = &abuffer_class,
 };
diff --git a/libavfilter/buffersrc.h b/libavfilter/buffersrc.h
index 452c691..7f3c8d8 100644
--- a/libavfilter/buffersrc.h
+++ b/libavfilter/buffersrc.h
@@ -25,16 +25,61 @@
  * Memory buffer source API.
  */
 
+#include "libavcodec/avcodec.h"
 #include "avfilter.h"
 
+enum {
+
+    /**
+     * Do not check for format changes.
+     */
+    AV_BUFFERSRC_FLAG_NO_CHECK_FORMAT = 1,
+
+    /**
+     * Do not copy buffer data.
+     */
+    AV_BUFFERSRC_FLAG_NO_COPY = 2,
+
+    /**
+     * Immediately push the frame to the output.
+     */
+    AV_BUFFERSRC_FLAG_PUSH = 4,
+
+};
+
+/**
+ * Add buffer data in picref to buffer_src.
+ *
+ * @param buffer_src  pointer to a buffer source context
+ * @param picref      a buffer reference, or NULL to mark EOF
+ * @param flags       a combination of AV_BUFFERSRC_FLAG_*
+ * @return            >= 0 in case of success, a negative AVERROR code
+ *                    in case of failure
+ */
+int av_buffersrc_add_ref(AVFilterContext *buffer_src,
+                         AVFilterBufferRef *picref, int flags);
+
+/**
+ * Get the number of failed requests.
+ *
+ * A failed request is when the request_frame method is called while no
+ * frame is present in the buffer.
+ * The number is reset when a frame is added.
+ */
+unsigned av_buffersrc_get_nb_failed_requests(AVFilterContext *buffer_src);
+
+#ifdef FF_API_BUFFERSRC_BUFFER
 /**
  * Add a buffer to the filtergraph s.
  *
  * @param buf buffer containing frame data to be passed down the filtergraph.
  * This function will take ownership of buf, the user must not free it.
  * A NULL buf signals EOF -- i.e. no more frames will be sent to this filter.
+ * @deprecated Use av_buffersrc_add_ref(s, picref, AV_BUFFERSRC_FLAG_NO_COPY) instead.
  */
+attribute_deprecated
 int av_buffersrc_buffer(AVFilterContext *s, AVFilterBufferRef *buf);
+#endif
 
 /**
  * Add a frame to the buffer source.
diff --git a/libavfilter/drawutils.c b/libavfilter/drawutils.c
index e837760..23ab17a 100644
--- a/libavfilter/drawutils.c
+++ b/libavfilter/drawutils.c
@@ -1,18 +1,21 @@
 /*
- * This file is part of Libav.
+ * Copyright 2011 Stefano Sabatini <stefano.sabatini-lala poste it>
+ * Copyright 2012 Nicolas George <nicolas.george normalesup org>
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -23,9 +26,29 @@
 #include "libavutil/mem.h"
 #include "libavutil/pixdesc.h"
 #include "drawutils.h"
+#include "formats.h"
 
 enum { RED = 0, GREEN, BLUE, ALPHA };
 
+int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt)
+{
+    switch (pix_fmt) {
+    case AV_PIX_FMT_0RGB:
+    case AV_PIX_FMT_ARGB:  rgba_map[ALPHA] = 0; rgba_map[RED  ] = 1; rgba_map[GREEN] = 2; rgba_map[BLUE ] = 3; break;
+    case AV_PIX_FMT_0BGR:
+    case AV_PIX_FMT_ABGR:  rgba_map[ALPHA] = 0; rgba_map[BLUE ] = 1; rgba_map[GREEN] = 2; rgba_map[RED  ] = 3; break;
+    case AV_PIX_FMT_RGB0:
+    case AV_PIX_FMT_RGBA:
+    case AV_PIX_FMT_RGB24: rgba_map[RED  ] = 0; rgba_map[GREEN] = 1; rgba_map[BLUE ] = 2; rgba_map[ALPHA] = 3; break;
+    case AV_PIX_FMT_BGRA:
+    case AV_PIX_FMT_BGR0:
+    case AV_PIX_FMT_BGR24: rgba_map[BLUE ] = 0; rgba_map[GREEN] = 1; rgba_map[RED  ] = 2; rgba_map[ALPHA] = 3; break;
+    default:                    /* unsupported */
+        return AVERROR(EINVAL);
+    }
+    return 0;
+}
+
 int ff_fill_line_with_color(uint8_t *line[4], int pixel_step[4], int w, uint8_t dst_color[4],
                             enum AVPixelFormat pix_fmt, uint8_t rgba_color[4],
                             int *is_packed_rgba, uint8_t rgba_map_ptr[4])
@@ -35,17 +58,7 @@
     const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(pix_fmt);
     int hsub = pix_desc->log2_chroma_w;
 
-    *is_packed_rgba = 1;
-    switch (pix_fmt) {
-    case AV_PIX_FMT_ARGB:  rgba_map[ALPHA] = 0; rgba_map[RED  ] = 1; rgba_map[GREEN] = 2; rgba_map[BLUE ] = 3; break;
-    case AV_PIX_FMT_ABGR:  rgba_map[ALPHA] = 0; rgba_map[BLUE ] = 1; rgba_map[GREEN] = 2; rgba_map[RED  ] = 3; break;
-    case AV_PIX_FMT_RGBA:
-    case AV_PIX_FMT_RGB24: rgba_map[RED  ] = 0; rgba_map[GREEN] = 1; rgba_map[BLUE ] = 2; rgba_map[ALPHA] = 3; break;
-    case AV_PIX_FMT_BGRA:
-    case AV_PIX_FMT_BGR24: rgba_map[BLUE ] = 0; rgba_map[GREEN] = 1; rgba_map[RED  ] = 2; rgba_map[ALPHA] = 3; break;
-    default:
-        *is_packed_rgba = 0;
-    }
+    *is_packed_rgba = ff_fill_rgba_map(rgba_map, pix_fmt) >= 0;
 
     if (*is_packed_rgba) {
         pixel_step[0] = (av_get_bits_per_pixel(pix_desc))>>3;
@@ -118,3 +131,423 @@
         }
     }
 }
+
+int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
+    const AVComponentDescriptor *c;
+    unsigned i, nb_planes = 0;
+    int pixelstep[MAX_PLANES] = { 0 };
+
+    if (!desc->name)
+        return AVERROR(EINVAL);
+    if (desc->flags & ~(PIX_FMT_PLANAR | PIX_FMT_RGB | PIX_FMT_PSEUDOPAL))
+        return AVERROR(ENOSYS);
+    for (i = 0; i < desc->nb_components; i++) {
+        c = &desc->comp[i];
+        /* for now, only 8-bits formats */
+        if (c->depth_minus1 != 8 - 1)
+            return AVERROR(ENOSYS);
+        if (c->plane >= MAX_PLANES)
+            return AVERROR(ENOSYS);
+        /* strange interleaving */
+        if (pixelstep[c->plane] != 0 &&
+            pixelstep[c->plane] != c->step_minus1 + 1)
+            return AVERROR(ENOSYS);
+        pixelstep[c->plane] = c->step_minus1 + 1;
+        if (pixelstep[c->plane] >= 8)
+            return AVERROR(ENOSYS);
+        nb_planes = FFMAX(nb_planes, c->plane + 1);
+    }
+    if ((desc->log2_chroma_w || desc->log2_chroma_h) && nb_planes < 3)
+        return AVERROR(ENOSYS); /* exclude NV12 and NV21 */
+    memset(draw, 0, sizeof(*draw));
+    draw->desc      = desc;
+    draw->format    = format;
+    draw->nb_planes = nb_planes;
+    memcpy(draw->pixelstep, pixelstep, sizeof(draw->pixelstep));
+    if (nb_planes >= 3 && !(desc->flags & PIX_FMT_RGB)) {
+        draw->hsub[1] = draw->hsub[2] = draw->hsub_max = desc->log2_chroma_w;
+        draw->vsub[1] = draw->vsub[2] = draw->vsub_max = desc->log2_chroma_h;
+    }
+    for (i = 0; i < ((desc->nb_components - 1) | 1); i++)
+        draw->comp_mask[desc->comp[i].plane] |=
+            1 << (desc->comp[i].offset_plus1 - 1);
+    return 0;
+}
+
+void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4])
+{
+    unsigned i;
+    uint8_t rgba_map[4];
+
+    if (rgba != color->rgba)
+        memcpy(color->rgba, rgba, sizeof(color->rgba));
+    if ((draw->desc->flags & PIX_FMT_RGB) && draw->nb_planes == 1 &&
+        ff_fill_rgba_map(rgba_map, draw->format) >= 0) {
+        for (i = 0; i < 4; i++)
+            color->comp[0].u8[rgba_map[i]] = rgba[i];
+    } else if (draw->nb_planes == 3 || draw->nb_planes == 4) {
+        /* assume YUV */
+        color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
+        color->comp[1].u8[0] = RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0);
+        color->comp[2].u8[0] = RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0);
+        color->comp[3].u8[0] = rgba[3];
+    } else if (draw->format == AV_PIX_FMT_GRAY8 || draw->format == AV_PIX_FMT_GRAY8A) {
+        color->comp[0].u8[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
+        color->comp[1].u8[0] = rgba[3];
+    } else {
+        av_log(NULL, AV_LOG_WARNING,
+               "Color conversion not implemented for %s\n", draw->desc->name);
+        memset(color, 128, sizeof(*color));
+    }
+}
+
+static uint8_t *pointer_at(FFDrawContext *draw, uint8_t *data[], int linesize[],
+                           int plane, int x, int y)
+{
+    return data[plane] +
+           (y >> draw->vsub[plane]) * linesize[plane] +
+           (x >> draw->hsub[plane]) * draw->pixelstep[plane];
+}
+
+void ff_copy_rectangle2(FFDrawContext *draw,
+                        uint8_t *dst[], int dst_linesize[],
+                        uint8_t *src[], int src_linesize[],
+                        int dst_x, int dst_y, int src_x, int src_y,
+                        int w, int h)
+{
+    int plane, y, wp, hp;
+    uint8_t *p, *q;
+
+    for (plane = 0; plane < draw->nb_planes; plane++) {
+        p = pointer_at(draw, src, src_linesize, plane, src_x, src_y);
+        q = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y);
+        wp = (w >> draw->hsub[plane]) * draw->pixelstep[plane];
+        hp = (h >> draw->vsub[plane]);
+        for (y = 0; y < hp; y++) {
+            memcpy(q, p, wp);
+            p += src_linesize[plane];
+            q += dst_linesize[plane];
+        }
+    }
+}
+
+void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color,
+                       uint8_t *dst[], int dst_linesize[],
+                       int dst_x, int dst_y, int w, int h)
+{
+    int plane, x, y, wp, hp;
+    uint8_t *p0, *p;
+
+    for (plane = 0; plane < draw->nb_planes; plane++) {
+        p0 = pointer_at(draw, dst, dst_linesize, plane, dst_x, dst_y);
+        wp = (w >> draw->hsub[plane]);
+        hp = (h >> draw->vsub[plane]);
+        if (!hp)
+            return;
+        p = p0;
+        /* copy first line from color */
+        for (x = 0; x < wp; x++) {
+            memcpy(p, color->comp[plane].u8, draw->pixelstep[plane]);
+            p += draw->pixelstep[plane];
+        }
+        wp *= draw->pixelstep[plane];
+        /* copy next lines from first line */
+        p = p0 + dst_linesize[plane];
+        for (y = 1; y < hp; y++) {
+            memcpy(p, p0, wp);
+            p += dst_linesize[plane];
+        }
+    }
+}
+
+/**
+ * Clip interval [x; x+w[ within [0; wmax[.
+ * The resulting w may be negative if the final interval is empty.
+ * dx, if not null, return the difference between in and out value of x.
+ */
+static void clip_interval(int wmax, int *x, int *w, int *dx)
+{
+    if (dx)
+        *dx = 0;
+    if (*x < 0) {
+        if (dx)
+            *dx = -*x;
+        *w += *x;
+        *x = 0;
+    }
+    if (*x + *w > wmax)
+        *w = wmax - *x;
+}
+
+/**
+ * Decompose w pixels starting at x
+ * into start + (w starting at x) + end
+ * with x and w aligned on multiples of 1<<sub.
+ */
+static void subsampling_bounds(int sub, int *x, int *w, int *start, int *end)
+{
+    int mask = (1 << sub) - 1;
+
+    *start = (-*x) & mask;
+    *x += *start;
+    *start = FFMIN(*start, *w);
+    *w -= *start;
+    *end = *w & mask;
+    *w >>= sub;
+}
+
+static int component_used(FFDrawContext *draw, int plane, int comp)
+{
+    return (draw->comp_mask[plane] >> comp) & 1;
+}
+
+/* If alpha is in the [ 0 ; 0x1010101 ] range,
+   then alpha * value is in the [ 0 ; 0xFFFFFFFF ] range,
+   and >> 24 gives a correct rounding. */
+static void blend_line(uint8_t *dst, unsigned src, unsigned alpha,
+                       int dx, int w, unsigned hsub, int left, int right)
+{
+    unsigned asrc = alpha * src;
+    unsigned tau = 0x1010101 - alpha;
+    int x;
+
+    src *= alpha;
+    if (left) {
+        unsigned suba = (left * alpha) >> hsub;
+        *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24;
+        dst += dx;
+    }
+    for (x = 0; x < w; x++) {
+        *dst = (*dst * tau + asrc) >> 24;
+        dst += dx;
+    }
+    if (right) {
+        unsigned suba = (right * alpha) >> hsub;
+        *dst = (*dst * (0x1010101 - suba) + src * suba) >> 24;
+    }
+}
+
+void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color,
+                        uint8_t *dst[], int dst_linesize[],
+                        int dst_w, int dst_h,
+                        int x0, int y0, int w, int h)
+{
+    unsigned alpha, nb_planes, nb_comp, plane, comp;
+    int w_sub, h_sub, x_sub, y_sub, left, right, top, bottom, y;
+    uint8_t *p0, *p;
+
+    /* TODO optimize if alpha = 0xFF */
+    clip_interval(dst_w, &x0, &w, NULL);
+    clip_interval(dst_h, &y0, &h, NULL);
+    if (w <= 0 || h <= 0 || !color->rgba[3])
+        return;
+    /* 0x10203 * alpha + 2 is in the [ 2 ; 0x1010101 - 2 ] range */
+    alpha = 0x10203 * color->rgba[3] + 0x2;
+    nb_planes = (draw->nb_planes - 1) | 1; /* eliminate alpha */
+    for (plane = 0; plane < nb_planes; plane++) {
+        nb_comp = draw->pixelstep[plane];
+        p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0);
+        w_sub = w;
+        h_sub = h;
+        x_sub = x0;
+        y_sub = y0;
+        subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right);
+        subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom);
+        for (comp = 0; comp < nb_comp; comp++) {
+            if (!component_used(draw, plane, comp))
+                continue;
+            p = p0 + comp;
+            if (top) {
+                blend_line(p, color->comp[plane].u8[comp], alpha >> 1,
+                           draw->pixelstep[plane], w_sub,
+                           draw->hsub[plane], left, right);
+                p += dst_linesize[plane];
+            }
+            for (y = 0; y < h_sub; y++) {
+                blend_line(p, color->comp[plane].u8[comp], alpha,
+                           draw->pixelstep[plane], w_sub,
+                           draw->hsub[plane], left, right);
+                p += dst_linesize[plane];
+            }
+            if (bottom)
+                blend_line(p, color->comp[plane].u8[comp], alpha >> 1,
+                           draw->pixelstep[plane], w_sub,
+                           draw->hsub[plane], left, right);
+        }
+    }
+}
+
+static void blend_pixel(uint8_t *dst, unsigned src, unsigned alpha,
+                        uint8_t *mask, int mask_linesize, int l2depth,
+                        unsigned w, unsigned h, unsigned shift, unsigned xm0)
+{
+    unsigned xm, x, y, t = 0;
+    unsigned xmshf = 3 - l2depth;
+    unsigned xmmod = 7 >> l2depth;
+    unsigned mbits = (1 << (1 << l2depth)) - 1;
+    unsigned mmult = 255 / mbits;
+
+    for (y = 0; y < h; y++) {
+        xm = xm0;
+        for (x = 0; x < w; x++) {
+            t += ((mask[xm >> xmshf] >> ((~xm & xmmod) << l2depth)) & mbits)
+                 * mmult;
+            xm++;
+        }
+        mask += mask_linesize;
+    }
+    alpha = (t >> shift) * alpha;
+    *dst = ((0x1010101 - alpha) * *dst + alpha * src) >> 24;
+}
+
+static void blend_line_hv(uint8_t *dst, int dst_delta,
+                          unsigned src, unsigned alpha,
+                          uint8_t *mask, int mask_linesize, int l2depth, int w,
+                          unsigned hsub, unsigned vsub,
+                          int xm, int left, int right, int hband)
+{
+    int x;
+
+    if (left) {
+        blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth,
+                    left, hband, hsub + vsub, xm);
+        dst += dst_delta;
+        xm += left;
+    }
+    for (x = 0; x < w; x++) {
+        blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth,
+                    1 << hsub, hband, hsub + vsub, xm);
+        dst += dst_delta;
+        xm += 1 << hsub;
+    }
+    if (right)
+        blend_pixel(dst, src, alpha, mask, mask_linesize, l2depth,
+                    right, hband, hsub + vsub, xm);
+}
+
+void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color,
+                   uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h,
+                   uint8_t *mask,  int mask_linesize, int mask_w, int mask_h,
+                   int l2depth, unsigned endianness, int x0, int y0)
+{
+    unsigned alpha, nb_planes, nb_comp, plane, comp;
+    int xm0, ym0, w_sub, h_sub, x_sub, y_sub, left, right, top, bottom, y;
+    uint8_t *p0, *p, *m;
+
+    clip_interval(dst_w, &x0, &mask_w, &xm0);
+    clip_interval(dst_h, &y0, &mask_h, &ym0);
+    mask += ym0 * mask_linesize;
+    if (mask_w <= 0 || mask_h <= 0 || !color->rgba[3])
+        return;
+    /* alpha is in the [ 0 ; 0x10203 ] range,
+       alpha * mask is in the [ 0 ; 0x1010101 - 4 ] range */
+    alpha = (0x10307 * color->rgba[3] + 0x3) >> 8;
+    nb_planes = (draw->nb_planes - 1) | 1; /* eliminate alpha */
+    for (plane = 0; plane < nb_planes; plane++) {
+        nb_comp = draw->pixelstep[plane];
+        p0 = pointer_at(draw, dst, dst_linesize, plane, x0, y0);
+        w_sub = mask_w;
+        h_sub = mask_h;
+        x_sub = x0;
+        y_sub = y0;
+        subsampling_bounds(draw->hsub[plane], &x_sub, &w_sub, &left, &right);
+        subsampling_bounds(draw->vsub[plane], &y_sub, &h_sub, &top, &bottom);
+        for (comp = 0; comp < nb_comp; comp++) {
+            if (!component_used(draw, plane, comp))
+                continue;
+            p = p0 + comp;
+            m = mask;
+            if (top) {
+                blend_line_hv(p, draw->pixelstep[plane],
+                              color->comp[plane].u8[comp], alpha,
+                              m, mask_linesize, l2depth, w_sub,
+                              draw->hsub[plane], draw->vsub[plane],
+                              xm0, left, right, top);
+                p += dst_linesize[plane];
+                m += top * mask_linesize;
+            }
+            for (y = 0; y < h_sub; y++) {
+                blend_line_hv(p, draw->pixelstep[plane],
+                              color->comp[plane].u8[comp], alpha,
+                              m, mask_linesize, l2depth, w_sub,
+                              draw->hsub[plane], draw->vsub[plane],
+                              xm0, left, right, 1 << draw->vsub[plane]);
+                p += dst_linesize[plane];
+                m += mask_linesize << draw->vsub[plane];
+            }
+            if (bottom)
+                blend_line_hv(p, draw->pixelstep[plane],
+                              color->comp[plane].u8[comp], alpha,
+                              m, mask_linesize, l2depth, w_sub,
+                              draw->hsub[plane], draw->vsub[plane],
+                              xm0, left, right, bottom);
+        }
+    }
+}
+
+int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir,
+                         int value)
+{
+    unsigned shift = sub_dir ? draw->vsub_max : draw->hsub_max;
+
+    if (!shift)
+        return value;
+    if (round_dir >= 0)
+        value += round_dir ? (1 << shift) - 1 : 1 << (shift - 1);
+    return (value >> shift) << shift;
+}
+
+AVFilterFormats *ff_draw_supported_pixel_formats(unsigned flags)
+{
+    enum AVPixelFormat i, pix_fmts[AV_PIX_FMT_NB + 1];
+    unsigned n = 0;
+    FFDrawContext draw;
+
+    for (i = 0; i < AV_PIX_FMT_NB; i++)
+        if (ff_draw_init(&draw, i, flags) >= 0)
+            pix_fmts[n++] = i;
+    pix_fmts[n++] = AV_PIX_FMT_NONE;
+    return ff_make_format_list(pix_fmts);
+}
+
+#ifdef TEST
+
+#undef printf
+
+int main(void)
+{
+    enum AVPixelFormat f;
+    const AVPixFmtDescriptor *desc;
+    FFDrawContext draw;
+    FFDrawColor color;
+    int r, i;
+
+    for (f = 0; f < AV_PIX_FMT_NB; f++) {
+        desc = av_pix_fmt_desc_get(f);
+        if (!desc->name)
+            continue;
+        printf("Testing %s...%*s", desc->name,
+               (int)(16 - strlen(desc->name)), "");
+        r = ff_draw_init(&draw, f, 0);
+        if (r < 0) {
+            char buf[128];
+            av_strerror(r, buf, sizeof(buf));
+            printf("no: %s\n", buf);
+            continue;
+        }
+        ff_draw_color(&draw, &color, (uint8_t[]) { 1, 0, 0, 1 });
+        for (i = 0; i < sizeof(color); i++)
+            if (((uint8_t *)&color)[i] != 128)
+                break;
+        if (i == sizeof(color)) {
+            printf("fallback color\n");
+            continue;
+        }
+        printf("ok\n");
+    }
+    return 0;
+}
+
+#endif
diff --git a/libavfilter/drawutils.h b/libavfilter/drawutils.h
index 73f482e..df41695 100644
--- a/libavfilter/drawutils.h
+++ b/libavfilter/drawutils.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,8 +25,11 @@
  */
 
 #include <stdint.h>
+#include "avfilter.h"
 #include "libavutil/pixfmt.h"
 
+int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt);
+
 int ff_fill_line_with_color(uint8_t *line[4], int pixel_step[4], int w,
                             uint8_t dst_color[4],
                             enum AVPixelFormat pix_fmt, uint8_t rgba_color[4],
@@ -40,4 +43,113 @@
                        uint8_t *src[4], int src_linesize[4], int pixelstep[4],
                        int hsub, int vsub, int x, int y, int y2, int w, int h);
 
+#define MAX_PLANES 4
+
+typedef struct FFDrawContext {
+    const struct AVPixFmtDescriptor *desc;
+    enum AVPixelFormat format;
+    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;
+    uint8_t vsub_max;
+} FFDrawContext;
+
+typedef struct FFDrawColor {
+    uint8_t rgba[4];
+    union {
+        uint32_t u32;
+        uint16_t u16;
+        uint8_t  u8[4];
+    } comp[MAX_PLANES];
+} FFDrawColor;
+
+/**
+ * Init a draw context.
+ *
+ * Only a limited number of pixel formats are supported, if format is not
+ * supported the function will return an error.
+ * No flags currently defined.
+ * @return  0 for success, < 0 for error
+ */
+int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags);
+
+/**
+ * Prepare a color.
+ */
+void ff_draw_color(FFDrawContext *draw, FFDrawColor *color, const uint8_t rgba[4]);
+
+/**
+ * Copy a rectangle from an image to another.
+ *
+ * The coordinates must be as even as the subsampling requires.
+ */
+void ff_copy_rectangle2(FFDrawContext *draw,
+                        uint8_t *dst[], int dst_linesize[],
+                        uint8_t *src[], int src_linesize[],
+                        int dst_x, int dst_y, int src_x, int src_y,
+                        int w, int h);
+
+/**
+ * Fill a rectangle with an uniform color.
+ *
+ * The coordinates must be as even as the subsampling requires.
+ * The color needs to be inited with ff_draw_color.
+ */
+void ff_fill_rectangle(FFDrawContext *draw, FFDrawColor *color,
+                       uint8_t *dst[], int dst_linesize[],
+                       int dst_x, int dst_y, int w, int h);
+
+/**
+ * Blend a rectangle with an uniform color.
+ */
+void ff_blend_rectangle(FFDrawContext *draw, FFDrawColor *color,
+                        uint8_t *dst[], int dst_linesize[],
+                        int dst_w, int dst_h,
+                        int x0, int y0, int w, int h);
+
+/**
+ * Blend an alpha mask with an uniform color.
+ *
+ * @param draw           draw context
+ * @param color          color for the overlay;
+ * @param dst            destination image
+ * @param dst_linesize   line stride of the destination
+ * @param dst_w          width of the destination image
+ * @param dst_h          height of the destination image
+ * @param mask           mask
+ * @param mask_linesize  line stride of the mask
+ * @param mask_w         width of the mask
+ * @param mask_h         height of the mask
+ * @param l2depth        log2 of depth of the mask (0 for 1bpp, 3 for 8bpp)
+ * @param endianness     bit order of the mask (0: MSB to the left)
+ * @param x0             horizontal position of the overlay
+ * @param y0             vertical position of the overlay
+ */
+void ff_blend_mask(FFDrawContext *draw, FFDrawColor *color,
+                   uint8_t *dst[], int dst_linesize[], int dst_w, int dst_h,
+                   uint8_t *mask, int mask_linesize, int mask_w, int mask_h,
+                   int l2depth, unsigned endianness, int x0, int y0);
+
+/**
+ * Round a dimension according to subsampling.
+ *
+ * @param draw       draw context
+ * @param sub_dir    0 for horizontal, 1 for vertical
+ * @param round_dir  0 nearest, -1 round down, +1 round up
+ * @param value      value to round
+ * @return  the rounded value
+ */
+int ff_draw_round_to_sub(FFDrawContext *draw, int sub_dir, int round_dir,
+                         int value);
+
+/**
+ * Return the list of pixel formats supported by the draw functions.
+ *
+ * The flags are the same as ff_draw_init, i.e., none currently.
+ */
+AVFilterFormats *ff_draw_supported_pixel_formats(unsigned flags);
+
 #endif /* AVFILTER_DRAWUTILS_H */
diff --git a/libavfilter/f_ebur128.c b/libavfilter/f_ebur128.c
new file mode 100644
index 0000000..5424276
--- /dev/null
+++ b/libavfilter/f_ebur128.c
@@ -0,0 +1,747 @@
+/*
+ * 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
+ * EBU R.128 implementation
+ * @see http://tech.ebu.ch/loudness
+ * @see https://www.youtube.com/watch?v=iuEtQqC-Sqo "EBU R128 Introduction - Florian Camerer"
+ * @todo True Peak
+ * @todo implement start/stop/reset through filter command injection
+ * @todo support other frequencies to avoid resampling
+ */
+
+#include <math.h>
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/xga_font_data.h"
+#include "libavutil/opt.h"
+#include "libavutil/timestamp.h"
+#include "audio.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+
+#define MAX_CHANNELS 63
+
+/* pre-filter coefficients */
+#define PRE_B0  1.53512485958697
+#define PRE_B1 -2.69169618940638
+#define PRE_B2  1.19839281085285
+#define PRE_A1 -1.69065929318241
+#define PRE_A2  0.73248077421585
+
+/* RLB-filter coefficients */
+#define RLB_B0  1.0
+#define RLB_B1 -2.0
+#define RLB_B2  1.0
+#define RLB_A1 -1.99004745483398
+#define RLB_A2  0.99007225036621
+
+#define ABS_THRES    -70            ///< silence gate: we discard anything below this absolute (LUFS) threshold
+#define ABS_UP_THRES  10            ///< upper loud limit to consider (ABS_THRES being the minimum)
+#define HIST_GRAIN   100            ///< defines histogram precision
+#define HIST_SIZE  ((ABS_UP_THRES - ABS_THRES) * HIST_GRAIN + 1)
+
+/**
+ * An histogram is an array of HIST_SIZE hist_entry storing all the energies
+ * recorded (with an accuracy of 1/HIST_GRAIN) of the loudnesses from ABS_THRES
+ * (at 0) to ABS_UP_THRES (at HIST_SIZE-1).
+ * This fixed-size system avoids the need of a list of energies growing
+ * infinitely over the time and is thus more scalable.
+ */
+struct hist_entry {
+    int count;                      ///< how many times the corresponding value occurred
+    double energy;                  ///< E = 10^((L + 0.691) / 10)
+    double loudness;                ///< L = -0.691 + 10 * log10(E)
+};
+
+struct integrator {
+    double *cache[MAX_CHANNELS];    ///< window of filtered samples (N ms)
+    int cache_pos;                  ///< focus on the last added bin in the cache array
+    double sum[MAX_CHANNELS];       ///< sum of the last N ms filtered samples (cache content)
+    int filled;                     ///< 1 if the cache is completely filled, 0 otherwise
+    double rel_threshold;           ///< relative threshold
+    double sum_kept_powers;         ///< sum of the powers (weighted sums) above absolute threshold
+    int nb_kept_powers;             ///< number of sum above absolute threshold
+    struct hist_entry *histogram;   ///< histogram of the powers, used to compute LRA and I
+};
+
+struct rect { int x, y, w, h; };
+
+typedef struct {
+    const AVClass *class;           ///< AVClass context for log and options purpose
+
+    /* video  */
+    int do_video;                   ///< 1 if video output enabled, 0 otherwise
+    int w, h;                       ///< size of the video output
+    struct rect text;               ///< rectangle for the LU legend on the left
+    struct rect graph;              ///< rectangle for the main graph in the center
+    struct rect gauge;              ///< rectangle for the gauge on the right
+    AVFilterBufferRef *outpicref;   ///< output picture reference, updated regularly
+    int meter;                      ///< select a EBU mode between +9 and +18
+    int scale_range;                ///< the range of LU values according to the meter
+    int y_zero_lu;                  ///< the y value (pixel position) for 0 LU
+    int *y_line_ref;                ///< y reference values for drawing the LU lines in the graph and the gauge
+
+    /* audio */
+    int nb_channels;                ///< number of channels in the input
+    double *ch_weighting;           ///< channel weighting mapping
+    int sample_count;               ///< sample count used for refresh frequency, reset at refresh
+
+    /* Filter caches.
+     * The mult by 3 in the following is for X[i], X[i-1] and X[i-2] */
+    double x[MAX_CHANNELS * 3];     ///< 3 input samples cache for each channel
+    double y[MAX_CHANNELS * 3];     ///< 3 pre-filter samples cache for each channel
+    double z[MAX_CHANNELS * 3];     ///< 3 RLB-filter samples cache for each channel
+
+#define I400_BINS  (48000 * 4 / 10)
+#define I3000_BINS (48000 * 3)
+    struct integrator i400;         ///< 400ms integrator, used for Momentary loudness  (M), and Integrated loudness (I)
+    struct integrator i3000;        ///<    3s integrator, used for Short term loudness (S), and Loudness Range      (LRA)
+
+    /* I and LRA specific */
+    double integrated_loudness;     ///< integrated loudness in LUFS (I)
+    double loudness_range;          ///< loudness range in LU (LRA)
+    double lra_low, lra_high;       ///< low and high LRA values
+} EBUR128Context;
+
+#define OFFSET(x) offsetof(EBUR128Context, x)
+#define A AV_OPT_FLAG_AUDIO_PARAM
+#define V AV_OPT_FLAG_VIDEO_PARAM
+#define F AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption ebur128_options[] = {
+    { "video", "set video output", OFFSET(do_video), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, V|F },
+    { "size",  "set video size",   OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x480"}, 0, 0, V|F },
+    { "meter", "set scale meter (+9 to +18)",  OFFSET(meter), AV_OPT_TYPE_INT, {.i64 = 9}, 9, 18, V|F },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(ebur128);
+
+static const uint8_t graph_colors[] = {
+    0xdd, 0x66, 0x66,   // value above 0LU non reached
+    0x66, 0x66, 0xdd,   // value below 0LU non reached
+    0x96, 0x33, 0x33,   // value above 0LU reached
+    0x33, 0x33, 0x96,   // value below 0LU reached
+    0xdd, 0x96, 0x96,   // value above 0LU line non reached
+    0x96, 0x96, 0xdd,   // value below 0LU line non reached
+    0xdd, 0x33, 0x33,   // value above 0LU line reached
+    0x33, 0x33, 0xdd,   // value below 0LU line reached
+};
+
+static const uint8_t *get_graph_color(const EBUR128Context *ebur128, int v, int y)
+{
+    const int below0  = y > ebur128->y_zero_lu;
+    const int reached = y >= v;
+    const int line    = ebur128->y_line_ref[y] || y == ebur128->y_zero_lu;
+    const int colorid = 4*line + 2*reached + below0;
+    return graph_colors + 3*colorid;
+}
+
+static inline int lu_to_y(const EBUR128Context *ebur128, double v)
+{
+    v += 2 * ebur128->meter;                            // make it in range [0;...]
+    v  = av_clipf(v, 0, ebur128->scale_range);          // make sure it's in the graph scale
+    v  = ebur128->scale_range - v;                      // invert value (y=0 is on top)
+    return v * ebur128->graph.h / ebur128->scale_range; // rescale from scale range to px height
+}
+
+#define FONT8   0
+#define FONT16  1
+
+static const uint8_t font_colors[] = {
+    0xdd, 0xdd, 0x00,
+    0x00, 0x96, 0x96,
+};
+
+static void drawtext(AVFilterBufferRef *pic, int x, int y, int ftid, const uint8_t *color, const char *fmt, ...)
+{
+    int i;
+    char buf[128] = {0};
+    const uint8_t *font;
+    int font_height;
+    va_list vl;
+
+    if      (ftid == FONT16) font = avpriv_vga16_font, font_height = 16;
+    else if (ftid == FONT8)  font = avpriv_cga_font,   font_height =  8;
+    else return;
+
+    va_start(vl, fmt);
+    vsnprintf(buf, sizeof(buf), fmt, vl);
+    va_end(vl);
+
+    for (i = 0; buf[i]; i++) {
+        int char_y, mask;
+        uint8_t *p = pic->data[0] + y*pic->linesize[0] + (x + i*8)*3;
+
+        for (char_y = 0; char_y < font_height; char_y++) {
+            for (mask = 0x80; mask; mask >>= 1) {
+                if (font[buf[i] * font_height + char_y] & mask)
+                    memcpy(p, color, 3);
+                else
+                    memcpy(p, "\x00\x00\x00", 3);
+                p += 3;
+            }
+            p += pic->linesize[0] - 8*3;
+        }
+    }
+}
+
+static void drawline(AVFilterBufferRef *pic, int x, int y, int len, int step)
+{
+    int i;
+    uint8_t *p = pic->data[0] + y*pic->linesize[0] + x*3;
+
+    for (i = 0; i < len; i++) {
+        memcpy(p, "\x00\xff\x00", 3);
+        p += step;
+    }
+}
+
+static int config_video_output(AVFilterLink *outlink)
+{
+    int i, x, y;
+    uint8_t *p;
+    AVFilterContext *ctx = outlink->src;
+    EBUR128Context *ebur128 = ctx->priv;
+    AVFilterBufferRef *outpicref;
+
+    /* check if there is enough space to represent everything decently */
+    if (ebur128->w < 640 || ebur128->h < 480) {
+        av_log(ctx, AV_LOG_ERROR, "Video size %dx%d is too small, "
+               "minimum size is 640x480\n", ebur128->w, ebur128->h);
+        return AVERROR(EINVAL);
+    }
+    outlink->w = ebur128->w;
+    outlink->h = ebur128->h;
+
+#define PAD 8
+
+    /* configure text area position and size */
+    ebur128->text.x  = PAD;
+    ebur128->text.y  = 40;
+    ebur128->text.w  = 3 * 8;   // 3 characters
+    ebur128->text.h  = ebur128->h - PAD - ebur128->text.y;
+
+    /* configure gauge position and size */
+    ebur128->gauge.w = 20;
+    ebur128->gauge.h = ebur128->text.h;
+    ebur128->gauge.x = ebur128->w - PAD - ebur128->gauge.w;
+    ebur128->gauge.y = ebur128->text.y;
+
+    /* configure graph position and size */
+    ebur128->graph.x = ebur128->text.x + ebur128->text.w + PAD;
+    ebur128->graph.y = ebur128->gauge.y;
+    ebur128->graph.w = ebur128->gauge.x - ebur128->graph.x - PAD;
+    ebur128->graph.h = ebur128->gauge.h;
+
+    /* graph and gauge share the LU-to-pixel code */
+    av_assert0(ebur128->graph.h == ebur128->gauge.h);
+
+    /* prepare the initial picref buffer */
+    avfilter_unref_bufferp(&ebur128->outpicref);
+    ebur128->outpicref = outpicref =
+        ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_PRESERVE|AV_PERM_REUSE2,
+                            outlink->w, outlink->h);
+    if (!outpicref)
+        return AVERROR(ENOMEM);
+    outlink->sample_aspect_ratio = (AVRational){1,1};
+
+    /* init y references values (to draw LU lines) */
+    ebur128->y_line_ref = av_calloc(ebur128->graph.h + 1, sizeof(*ebur128->y_line_ref));
+    if (!ebur128->y_line_ref)
+        return AVERROR(ENOMEM);
+
+    /* black background */
+    memset(outpicref->data[0], 0, ebur128->h * outpicref->linesize[0]);
+
+    /* draw LU legends */
+    drawtext(outpicref, PAD, PAD+16, FONT8, font_colors+3, " LU");
+    for (i = ebur128->meter; i >= -ebur128->meter * 2; i--) {
+        y = lu_to_y(ebur128, i);
+        x = PAD + (i < 10 && i > -10) * 8;
+        ebur128->y_line_ref[y] = i;
+        y -= 4; // -4 to center vertically
+        drawtext(outpicref, x, y + ebur128->graph.y, FONT8, font_colors+3,
+                 "%c%d", i < 0 ? '-' : i > 0 ? '+' : ' ', FFABS(i));
+    }
+
+    /* draw graph */
+    ebur128->y_zero_lu = lu_to_y(ebur128, 0);
+    p = outpicref->data[0] + ebur128->graph.y * outpicref->linesize[0]
+                           + ebur128->graph.x * 3;
+    for (y = 0; y < ebur128->graph.h; y++) {
+        const uint8_t *c = get_graph_color(ebur128, INT_MAX, y);
+
+        for (x = 0; x < ebur128->graph.w; x++)
+            memcpy(p + x*3, c, 3);
+        p += outpicref->linesize[0];
+    }
+
+    /* draw fancy rectangles around the graph and the gauge */
+#define DRAW_RECT(r) do { \
+    drawline(outpicref, r.x,       r.y - 1,   r.w, 3); \
+    drawline(outpicref, r.x,       r.y + r.h, r.w, 3); \
+    drawline(outpicref, r.x - 1,   r.y,       r.h, outpicref->linesize[0]); \
+    drawline(outpicref, r.x + r.w, r.y,       r.h, outpicref->linesize[0]); \
+} while (0)
+    DRAW_RECT(ebur128->graph);
+    DRAW_RECT(ebur128->gauge);
+
+    return 0;
+}
+
+static int config_audio_output(AVFilterLink *outlink)
+{
+    int i;
+    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)
+
+    ebur128->nb_channels  = nb_channels;
+    ebur128->ch_weighting = av_calloc(nb_channels, sizeof(*ebur128->ch_weighting));
+    if (!ebur128->ch_weighting)
+        return AVERROR(ENOMEM);
+
+    for (i = 0; i < nb_channels; i++) {
+
+        /* channel weighting */
+        if ((outlink->channel_layout & 1ULL<<i) == AV_CH_LOW_FREQUENCY)
+            continue;
+        if (outlink->channel_layout & 1ULL<<i & BACK_MASK)
+            ebur128->ch_weighting[i] = 1.41;
+        else
+            ebur128->ch_weighting[i] = 1.0;
+
+        /* bins buffer for the two integration window (400ms and 3s) */
+        ebur128->i400.cache[i]  = av_calloc(I400_BINS,  sizeof(*ebur128->i400.cache[0]));
+        ebur128->i3000.cache[i] = av_calloc(I3000_BINS, sizeof(*ebur128->i3000.cache[0]));
+        if (!ebur128->i400.cache[i] || !ebur128->i3000.cache[i])
+            return AVERROR(ENOMEM);
+    }
+
+    return 0;
+}
+
+#define ENERGY(loudness) (pow(10, ((loudness) + 0.691) / 10.))
+#define LOUDNESS(energy) (-0.691 + 10 * log10(energy))
+
+static struct hist_entry *get_histogram(void)
+{
+    int i;
+    struct hist_entry *h = av_calloc(HIST_SIZE, sizeof(*h));
+
+    for (i = 0; i < HIST_SIZE; i++) {
+        h[i].loudness = i / (double)HIST_GRAIN + ABS_THRES;
+        h[i].energy   = ENERGY(h[i].loudness);
+    }
+    return h;
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    int ret;
+    EBUR128Context *ebur128 = ctx->priv;
+    AVFilterPad pad;
+
+    ebur128->class = &ebur128_class;
+    av_opt_set_defaults(ebur128);
+
+    if ((ret = av_set_options_string(ebur128, args, "=", ":")) < 0)
+        return ret;
+
+    // if meter is  +9 scale, scale range is from -18 LU to  +9 LU (or 3*9)
+    // if meter is +18 scale, scale range is from -36 LU to +18 LU (or 3*18)
+    ebur128->scale_range = 3 * ebur128->meter;
+
+    ebur128->i400.histogram  = get_histogram();
+    ebur128->i3000.histogram = get_histogram();
+
+    ebur128->integrated_loudness = ABS_THRES;
+    ebur128->loudness_range = 0;
+
+    /* insert output pads */
+    if (ebur128->do_video) {
+        pad = (AVFilterPad){
+            .name         = av_strdup("out0"),
+            .type         = AVMEDIA_TYPE_VIDEO,
+            .config_props = config_video_output,
+        };
+        if (!pad.name)
+            return AVERROR(ENOMEM);
+        ff_insert_outpad(ctx, 0, &pad);
+    }
+    pad = (AVFilterPad){
+        .name         = av_asprintf("out%d", ebur128->do_video),
+        .type         = AVMEDIA_TYPE_AUDIO,
+        .config_props = config_audio_output,
+    };
+    if (!pad.name)
+        return AVERROR(ENOMEM);
+    ff_insert_outpad(ctx, ebur128->do_video, &pad);
+
+    /* summary */
+    av_log(ctx, AV_LOG_VERBOSE, "EBU +%d scale\n", ebur128->meter);
+
+    return 0;
+}
+
+#define HIST_POS(power) (int)(((power) - ABS_THRES) * HIST_GRAIN)
+
+/* loudness and power should be set such as loudness = -0.691 +
+ * 10*log10(power), we just avoid doing that calculus two times */
+static int gate_update(struct integrator *integ, double power,
+                       double loudness, int gate_thres)
+{
+    int ipower;
+    double relative_threshold;
+    int gate_hist_pos;
+
+    /* update powers histograms by incrementing current power count */
+    ipower = av_clip(HIST_POS(loudness), 0, HIST_SIZE - 1);
+    integ->histogram[ipower].count++;
+
+    /* compute relative threshold and get its position in the histogram */
+    integ->sum_kept_powers += power;
+    integ->nb_kept_powers++;
+    relative_threshold = integ->sum_kept_powers / integ->nb_kept_powers;
+    if (!relative_threshold)
+        relative_threshold = 1e-12;
+    integ->rel_threshold = LOUDNESS(relative_threshold) + gate_thres;
+    gate_hist_pos = av_clip(HIST_POS(integ->rel_threshold), 0, HIST_SIZE - 1);
+
+    return gate_hist_pos;
+}
+
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *insamples)
+{
+    int i, ch;
+    AVFilterContext *ctx = inlink->dst;
+    EBUR128Context *ebur128 = ctx->priv;
+    const int nb_channels = ebur128->nb_channels;
+    const int nb_samples  = insamples->audio->nb_samples;
+    const double *samples = (double *)insamples->data[0];
+    AVFilterBufferRef *pic = ebur128->outpicref;
+
+    for (i = 0; i < nb_samples; i++) {
+        const int bin_id_400  = ebur128->i400.cache_pos;
+        const int bin_id_3000 = ebur128->i3000.cache_pos;
+
+#define MOVE_TO_NEXT_CACHED_ENTRY(time) do {                \
+    ebur128->i##time.cache_pos++;                           \
+    if (ebur128->i##time.cache_pos == I##time##_BINS) {     \
+        ebur128->i##time.filled    = 1;                     \
+        ebur128->i##time.cache_pos = 0;                     \
+    }                                                       \
+} while (0)
+
+        MOVE_TO_NEXT_CACHED_ENTRY(400);
+        MOVE_TO_NEXT_CACHED_ENTRY(3000);
+
+        for (ch = 0; ch < nb_channels; ch++) {
+            double bin;
+
+            if (!ebur128->ch_weighting[ch])
+                continue;
+
+            /* Y[i] = X[i]*b0 + X[i-1]*b1 + X[i-2]*b2 - Y[i-1]*a1 - Y[i-2]*a2 */
+#define FILTER(Y, X, name) do {                                                 \
+            double *dst = ebur128->Y + ch*3;                                    \
+            double *src = ebur128->X + ch*3;                                    \
+            dst[2] = dst[1];                                                    \
+            dst[1] = dst[0];                                                    \
+            dst[0] = src[0]*name##_B0 + src[1]*name##_B1 + src[2]*name##_B2     \
+                                      - 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];
+            ebur128->x[ch * 3 + 1] = ebur128->x[ch * 3    ];
+            FILTER(z, y, RLB);  // apply RLB-filter
+
+            bin = ebur128->z[ch * 3] * ebur128->z[ch * 3];
+
+            /* add the new value, and limit the sum to the cache size (400ms or 3s)
+             * by removing the oldest one */
+            ebur128->i400.sum [ch] = ebur128->i400.sum [ch] + bin - ebur128->i400.cache [ch][bin_id_400];
+            ebur128->i3000.sum[ch] = ebur128->i3000.sum[ch] + bin - ebur128->i3000.cache[ch][bin_id_3000];
+
+            /* override old cache entry with the new value */
+            ebur128->i400.cache [ch][bin_id_400 ] = bin;
+            ebur128->i3000.cache[ch][bin_id_3000] = bin;
+        }
+
+        /* For integrated loudness, gating blocks are 400ms long with 75%
+         * overlap (see BS.1770-2 p5), so a re-computation is needed each 100ms
+         * (4800 samples at 48kHz). */
+        if (++ebur128->sample_count == 4800) {
+            double loudness_400, loudness_3000;
+            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 },
+                             outlink->time_base);
+
+            ebur128->sample_count = 0;
+
+#define COMPUTE_LOUDNESS(m, time) do {                                              \
+    if (ebur128->i##time.filled) {                                                  \
+        /* weighting sum of the last <time> ms */                                   \
+        for (ch = 0; ch < nb_channels; ch++)                                        \
+            power_##time += ebur128->ch_weighting[ch] * ebur128->i##time.sum[ch];   \
+        power_##time /= I##time##_BINS;                                             \
+    }                                                                               \
+    loudness_##time = LOUDNESS(power_##time);                                       \
+} while (0)
+
+            COMPUTE_LOUDNESS(M,  400);
+            COMPUTE_LOUDNESS(S, 3000);
+
+            /* Integrated loudness */
+#define I_GATE_THRES -10  // initially defined to -8 LU in the first EBU standard
+
+            if (loudness_400 >= ABS_THRES) {
+                double integrated_sum = 0;
+                int nb_integrated = 0;
+                int gate_hist_pos = gate_update(&ebur128->i400, power_400,
+                                                loudness_400, I_GATE_THRES);
+
+                /* compute integrated loudness by summing the histogram values
+                 * above the relative threshold */
+                for (i = gate_hist_pos; i < HIST_SIZE; i++) {
+                    const int nb_v = ebur128->i400.histogram[i].count;
+                    nb_integrated  += nb_v;
+                    integrated_sum += nb_v * ebur128->i400.histogram[i].energy;
+                }
+                if (nb_integrated)
+                    ebur128->integrated_loudness = LOUDNESS(integrated_sum / nb_integrated);
+            }
+
+            /* LRA */
+#define LRA_GATE_THRES -20
+#define LRA_LOWER_PRC   10
+#define LRA_HIGHER_PRC  95
+
+            /* XXX: example code in EBU 3342 is ">=" but formula in BS.1770
+             * specs is ">" */
+            if (loudness_3000 >= ABS_THRES) {
+                int nb_powers = 0;
+                int gate_hist_pos = gate_update(&ebur128->i3000, power_3000,
+                                                loudness_3000, LRA_GATE_THRES);
+
+                for (i = gate_hist_pos; i < HIST_SIZE; i++)
+                    nb_powers += ebur128->i3000.histogram[i].count;
+                if (nb_powers) {
+                    int n, nb_pow;
+
+                    /* get lower loudness to consider */
+                    n = 0;
+                    nb_pow = LRA_LOWER_PRC  * nb_powers / 100. + 0.5;
+                    for (i = gate_hist_pos; i < HIST_SIZE; i++) {
+                        n += ebur128->i3000.histogram[i].count;
+                        if (n >= nb_pow) {
+                            ebur128->lra_low = ebur128->i3000.histogram[i].loudness;
+                            break;
+                        }
+                    }
+
+                    /* get higher loudness to consider */
+                    n = nb_powers;
+                    nb_pow = LRA_HIGHER_PRC * nb_powers / 100. + 0.5;
+                    for (i = HIST_SIZE - 1; i >= 0; i--) {
+                        n -= ebur128->i3000.histogram[i].count;
+                        if (n < nb_pow) {
+                            ebur128->lra_high = ebur128->i3000.histogram[i].loudness;
+                            break;
+                        }
+                    }
+
+                    // XXX: show low & high on the graph?
+                    ebur128->loudness_range = ebur128->lra_high - ebur128->lra_low;
+                }
+            }
+
+#define LOG_FMT "M:%6.1f S:%6.1f     I:%6.1f LUFS     LRA:%6.1f LU"
+
+            /* push one video frame */
+            if (ebur128->do_video) {
+                int x, y, ret;
+                uint8_t *p;
+
+                const int y_loudness_lu_graph = lu_to_y(ebur128, loudness_3000 + 23);
+                const int y_loudness_lu_gauge = lu_to_y(ebur128, loudness_400  + 23);
+
+                /* draw the graph using the short-term loudness */
+                p = pic->data[0] + ebur128->graph.y*pic->linesize[0] + ebur128->graph.x*3;
+                for (y = 0; y < ebur128->graph.h; y++) {
+                    const uint8_t *c = get_graph_color(ebur128, y_loudness_lu_graph, y);
+
+                    memmove(p, p + 3, (ebur128->graph.w - 1) * 3);
+                    memcpy(p + (ebur128->graph.w - 1) * 3, c, 3);
+                    p += pic->linesize[0];
+                }
+
+                /* draw the gauge using the momentary loudness */
+                p = pic->data[0] + ebur128->gauge.y*pic->linesize[0] + ebur128->gauge.x*3;
+                for (y = 0; y < ebur128->gauge.h; y++) {
+                    const uint8_t *c = get_graph_color(ebur128, y_loudness_lu_gauge, y);
+
+                    for (x = 0; x < ebur128->gauge.w; x++)
+                        memcpy(p + x*3, c, 3);
+                    p += pic->linesize[0];
+                }
+
+                /* draw textual info */
+                drawtext(pic, PAD, PAD - PAD/2, FONT16, font_colors,
+                         LOG_FMT "     ", // padding to erase trailing characters
+                         loudness_400, loudness_3000,
+                         ebur128->integrated_loudness, ebur128->loudness_range);
+
+                /* set pts and push frame */
+                pic->pts = pts;
+                if ((ret = ff_start_frame(outlink, avfilter_ref_buffer(pic, ~AV_PERM_WRITE))) < 0 ||
+                    (ret = ff_draw_slice(outlink, 0, outlink->h, 1)) < 0 ||
+                    (ret = ff_end_frame(outlink)) < 0)
+                    return ret;
+            }
+
+            av_log(ctx, ebur128->do_video ? AV_LOG_VERBOSE : AV_LOG_INFO,
+                   "t: %-10s " LOG_FMT "\n", av_ts2timestr(pts, &outlink->time_base),
+                   loudness_400, loudness_3000,
+                   ebur128->integrated_loudness, ebur128->loudness_range);
+        }
+    }
+
+    return ff_filter_samples(ctx->outputs[ebur128->do_video], insamples);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    EBUR128Context *ebur128 = ctx->priv;
+    AVFilterFormats *formats;
+    AVFilterChannelLayouts *layouts;
+    AVFilterLink *inlink = ctx->inputs[0];
+    AVFilterLink *outlink = ctx->outputs[0];
+
+    static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_DBL, -1 };
+    static const int input_srate[] = {48000, -1}; // ITU-R BS.1770 provides coeff only for 48kHz
+    static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_RGB24, -1 };
+
+    /* set input audio formats */
+    formats = ff_make_format_list(sample_fmts);
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_formats_ref(formats, &inlink->out_formats);
+
+    layouts = ff_all_channel_layouts();
+    if (!layouts)
+        return AVERROR(ENOMEM);
+    ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts);
+
+    formats = ff_make_format_list(input_srate);
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_formats_ref(formats, &inlink->out_samplerates);
+
+    /* set optional output video format */
+    if (ebur128->do_video) {
+        formats = ff_make_format_list(pix_fmts);
+        if (!formats)
+            return AVERROR(ENOMEM);
+        ff_formats_ref(formats, &outlink->in_formats);
+        outlink = ctx->outputs[1];
+    }
+
+    /* set audio output formats (same as input since it's just a passthrough) */
+    formats = ff_make_format_list(sample_fmts);
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_formats_ref(formats, &outlink->in_formats);
+
+    layouts = ff_all_channel_layouts();
+    if (!layouts)
+        return AVERROR(ENOMEM);
+    ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts);
+
+    formats = ff_make_format_list(input_srate);
+    if (!formats)
+        return AVERROR(ENOMEM);
+    ff_formats_ref(formats, &outlink->in_samplerates);
+
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    int i;
+    EBUR128Context *ebur128 = ctx->priv;
+
+    av_log(ctx, AV_LOG_INFO, "Summary:\n\n"
+           "  Integrated loudness:\n"
+           "    I:         %5.1f LUFS\n"
+           "    Threshold: %5.1f LUFS\n\n"
+           "  Loudness range:\n"
+           "    LRA:       %5.1f LU\n"
+           "    Threshold: %5.1f LUFS\n"
+           "    LRA low:   %5.1f LUFS\n"
+           "    LRA high:  %5.1f LUFS\n",
+           ebur128->integrated_loudness, ebur128->i400.rel_threshold,
+           ebur128->loudness_range,      ebur128->i3000.rel_threshold,
+           ebur128->lra_low, ebur128->lra_high);
+
+    av_freep(&ebur128->y_line_ref);
+    av_freep(&ebur128->ch_weighting);
+    av_freep(&ebur128->i400.histogram);
+    av_freep(&ebur128->i3000.histogram);
+    for (i = 0; i < ebur128->nb_channels; i++) {
+        av_freep(&ebur128->i400.cache[i]);
+        av_freep(&ebur128->i3000.cache[i]);
+    }
+    for (i = 0; i < ctx->nb_outputs; i++)
+        av_freep(&ctx->output_pads[i].name);
+    avfilter_unref_bufferp(&ebur128->outpicref);
+}
+
+AVFilter avfilter_af_ebur128 = {
+    .name          = "ebur128",
+    .description   = NULL_IF_CONFIG_SMALL("EBU R128 scanner."),
+    .priv_size     = sizeof(EBUR128Context),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+
+    .inputs = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_AUDIO,
+          .get_audio_buffer = ff_null_get_audio_buffer,
+          .filter_samples   = filter_samples, },
+        { .name = NULL }
+    },
+    .outputs = NULL,
+};
diff --git a/libavfilter/f_sendcmd.c b/libavfilter/f_sendcmd.c
new file mode 100644
index 0000000..7081de8
--- /dev/null
+++ b/libavfilter/f_sendcmd.c
@@ -0,0 +1,577 @@
+/*
+ * Copyright (c) 2012 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
+ * send commands filter
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+#include "libavutil/file.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "avfilter.h"
+#include "internal.h"
+#include "avfiltergraph.h"
+#include "audio.h"
+#include "video.h"
+
+#define COMMAND_FLAG_ENTER 1
+#define COMMAND_FLAG_LEAVE 2
+
+static inline char *make_command_flags_str(AVBPrint *pbuf, int flags)
+{
+    const char *flag_strings[] = { "enter", "leave" };
+    int i, is_first = 1;
+
+    av_bprint_init(pbuf, 0, AV_BPRINT_SIZE_AUTOMATIC);
+    for (i = 0; i < FF_ARRAY_ELEMS(flag_strings); i++) {
+        if (flags & 1<<i) {
+            if (!is_first)
+                av_bprint_chars(pbuf, '+', 1);
+            av_bprintf(pbuf, "%s", flag_strings[i]);
+            is_first = 0;
+        }
+    }
+
+    return pbuf->str;
+}
+
+typedef struct {
+    int flags;
+    char *target, *command, *arg;
+    int index;
+} Command;
+
+typedef struct {
+    int64_t start_ts;          ///< start timestamp expressed as microseconds units
+    int64_t end_ts;            ///< end   timestamp expressed as microseconds units
+    int index;                 ///< unique index for these interval commands
+    Command *commands;
+    int   nb_commands;
+    int enabled;               ///< current time detected inside this interval
+} Interval;
+
+typedef struct {
+    const AVClass *class;
+    Interval *intervals;
+    int   nb_intervals;
+
+    char *commands_filename;
+    char *commands_str;
+} SendCmdContext;
+
+#define OFFSET(x) offsetof(SendCmdContext, x)
+
+static const AVOption sendcmd_options[]= {
+    { "commands", "set commands", OFFSET(commands_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0 },
+    { "c",        "set commands", OFFSET(commands_str), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0 },
+    { "filename", "set commands file",  OFFSET(commands_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0 },
+    { "f",        "set commands file",  OFFSET(commands_filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0 },
+    {NULL},
+};
+
+AVFILTER_DEFINE_CLASS(sendcmd);
+
+#define SPACES " \f\t\n\r"
+
+static void skip_comments(const char **buf)
+{
+    while (**buf) {
+        /* skip leading spaces */
+        *buf += strspn(*buf, SPACES);
+        if (**buf != '#')
+            break;
+
+        (*buf)++;
+
+        /* skip comment until the end of line */
+        *buf += strcspn(*buf, "\n");
+        if (**buf)
+            (*buf)++;
+    }
+}
+
+#define COMMAND_DELIMS " \f\t\n\r,;"
+
+static int parse_command(Command *cmd, int cmd_count, int interval_count,
+                         const char **buf, void *log_ctx)
+{
+    int ret;
+
+    memset(cmd, 0, sizeof(Command));
+    cmd->index = cmd_count;
+
+    /* format: [FLAGS] target command arg */
+    *buf += strspn(*buf, SPACES);
+
+    /* parse flags */
+    if (**buf == '[') {
+        (*buf)++; /* skip "[" */
+
+        while (**buf) {
+            int len = strcspn(*buf, "|+]");
+
+            if      (!strncmp(*buf, "enter", strlen("enter"))) cmd->flags |= COMMAND_FLAG_ENTER;
+            else if (!strncmp(*buf, "leave", strlen("leave"))) cmd->flags |= COMMAND_FLAG_LEAVE;
+            else {
+                char flag_buf[64];
+                av_strlcpy(flag_buf, *buf, sizeof(flag_buf));
+                av_log(log_ctx, AV_LOG_ERROR,
+                       "Unknown flag '%s' in in interval #%d, command #%d\n",
+                       flag_buf, interval_count, cmd_count);
+                return AVERROR(EINVAL);
+            }
+            *buf += len;
+            if (**buf == ']')
+                break;
+            if (!strspn(*buf, "+|")) {
+                av_log(log_ctx, AV_LOG_ERROR,
+                       "Invalid flags char '%c' in interval #%d, command #%d\n",
+                       **buf, interval_count, cmd_count);
+                return AVERROR(EINVAL);
+            }
+            if (**buf)
+                (*buf)++;
+        }
+
+        if (**buf != ']') {
+            av_log(log_ctx, AV_LOG_ERROR,
+                   "Missing flag terminator or extraneous data found at the end of flags "
+                   "in interval #%d, command #%d\n", interval_count, cmd_count);
+            return AVERROR(EINVAL);
+        }
+        (*buf)++; /* skip "]" */
+    } else {
+        cmd->flags = COMMAND_FLAG_ENTER;
+    }
+
+    *buf += strspn(*buf, SPACES);
+    cmd->target = av_get_token(buf, COMMAND_DELIMS);
+    if (!cmd->target || !cmd->target[0]) {
+        av_log(log_ctx, AV_LOG_ERROR,
+               "No target specified in in interval #%d, command #%d\n",
+               interval_count, cmd_count);
+        ret = AVERROR(EINVAL);
+        goto fail;
+    }
+
+    *buf += strspn(*buf, SPACES);
+    cmd->command = av_get_token(buf, COMMAND_DELIMS);
+    if (!cmd->command || !cmd->command[0]) {
+        av_log(log_ctx, AV_LOG_ERROR,
+               "No command specified in in interval #%d, command #%d\n",
+               interval_count, cmd_count);
+        ret = AVERROR(EINVAL);
+        goto fail;
+    }
+
+    *buf += strspn(*buf, SPACES);
+    cmd->arg = av_get_token(buf, COMMAND_DELIMS);
+
+    return 1;
+
+fail:
+    av_freep(&cmd->target);
+    av_freep(&cmd->command);
+    av_freep(&cmd->arg);
+    return ret;
+}
+
+static int parse_commands(Command **cmds, int *nb_cmds, int interval_count,
+                          const char **buf, void *log_ctx)
+{
+    int cmd_count = 0;
+    int ret, n = 0;
+    AVBPrint pbuf;
+
+    *cmds = NULL;
+    *nb_cmds = 0;
+
+    while (**buf) {
+        Command cmd;
+
+        if ((ret = parse_command(&cmd, cmd_count, interval_count, buf, log_ctx)) < 0)
+            return ret;
+        cmd_count++;
+
+        /* (re)allocate commands array if required */
+        if (*nb_cmds == n) {
+            n = FFMAX(16, 2*n); /* first allocation = 16, or double the number */
+            *cmds = av_realloc_f(*cmds, n, 2*sizeof(Command));
+            if (!*cmds) {
+                av_log(log_ctx, AV_LOG_ERROR,
+                       "Could not (re)allocate command array\n");
+                return AVERROR(ENOMEM);
+            }
+        }
+
+        (*cmds)[(*nb_cmds)++] = cmd;
+
+        *buf += strspn(*buf, SPACES);
+        if (**buf && **buf != ';' && **buf != ',') {
+            av_log(log_ctx, AV_LOG_ERROR,
+                   "Missing separator or extraneous data found at the end of "
+                   "interval #%d, in command #%d\n",
+                   interval_count, cmd_count);
+            av_log(log_ctx, AV_LOG_ERROR,
+                   "Command was parsed as: flags:[%s] target:%s command:%s arg:%s\n",
+                   make_command_flags_str(&pbuf, cmd.flags), cmd.target, cmd.command, cmd.arg);
+            return AVERROR(EINVAL);
+        }
+        if (**buf == ';')
+            break;
+        if (**buf == ',')
+            (*buf)++;
+    }
+
+    return 0;
+}
+
+#define DELIMS " \f\t\n\r,;"
+
+static int parse_interval(Interval *interval, int interval_count,
+                          const char **buf, void *log_ctx)
+{
+    char *intervalstr;
+    int ret;
+
+    *buf += strspn(*buf, SPACES);
+    if (!**buf)
+        return 0;
+
+    /* reset data */
+    memset(interval, 0, sizeof(Interval));
+    interval->index = interval_count;
+
+    /* format: INTERVAL COMMANDS */
+
+    /* parse interval */
+    intervalstr = av_get_token(buf, DELIMS);
+    if (intervalstr && intervalstr[0]) {
+        char *start, *end;
+
+        start = av_strtok(intervalstr, "-", &end);
+        if ((ret = av_parse_time(&interval->start_ts, start, 1)) < 0) {
+            av_log(log_ctx, AV_LOG_ERROR,
+                   "Invalid start time specification '%s' in interval #%d\n",
+                   start, interval_count);
+            goto end;
+        }
+
+        if (end) {
+            if ((ret = av_parse_time(&interval->end_ts, end, 1)) < 0) {
+                av_log(log_ctx, AV_LOG_ERROR,
+                       "Invalid end time specification '%s' in interval #%d\n",
+                       end, interval_count);
+                goto end;
+            }
+        } else {
+            interval->end_ts = INT64_MAX;
+        }
+        if (interval->end_ts < interval->start_ts) {
+            av_log(log_ctx, AV_LOG_ERROR,
+                   "Invalid end time '%s' in interval #%d: "
+                   "cannot be lesser than start time '%s'\n",
+                   end, interval_count, start);
+            ret = AVERROR(EINVAL);
+            goto end;
+        }
+    } else {
+        av_log(log_ctx, AV_LOG_ERROR,
+               "No interval specified for interval #%d\n", interval_count);
+        ret = AVERROR(EINVAL);
+        goto end;
+    }
+
+    /* parse commands */
+    ret = parse_commands(&interval->commands, &interval->nb_commands,
+                         interval_count, buf, log_ctx);
+
+end:
+    av_free(intervalstr);
+    return ret;
+}
+
+static int parse_intervals(Interval **intervals, int *nb_intervals,
+                           const char *buf, void *log_ctx)
+{
+    int interval_count = 0;
+    int ret, n = 0;
+
+    *intervals = NULL;
+    *nb_intervals = 0;
+
+    while (1) {
+        Interval interval;
+
+        skip_comments(&buf);
+        if (!(*buf))
+            break;
+
+        if ((ret = parse_interval(&interval, interval_count, &buf, log_ctx)) < 0)
+            return ret;
+
+        buf += strspn(buf, SPACES);
+        if (*buf) {
+            if (*buf != ';') {
+                av_log(log_ctx, AV_LOG_ERROR,
+                       "Missing terminator or extraneous data found at the end of interval #%d\n",
+                       interval_count);
+                return AVERROR(EINVAL);
+            }
+            buf++; /* skip ';' */
+        }
+        interval_count++;
+
+        /* (re)allocate commands array if required */
+        if (*nb_intervals == n) {
+            n = FFMAX(16, 2*n); /* first allocation = 16, or double the number */
+            *intervals = av_realloc_f(*intervals, n, 2*sizeof(Interval));
+            if (!*intervals) {
+                av_log(log_ctx, AV_LOG_ERROR,
+                       "Could not (re)allocate intervals array\n");
+                return AVERROR(ENOMEM);
+            }
+        }
+
+        (*intervals)[(*nb_intervals)++] = interval;
+    }
+
+    return 0;
+}
+
+static int cmp_intervals(const void *a, const void *b)
+{
+    const Interval *i1 = a;
+    const Interval *i2 = b;
+    int64_t ts_diff = i1->start_ts - i2->start_ts;
+    int ret;
+
+    ret = ts_diff > 0 ? 1 : ts_diff < 0 ? -1 : 0;
+    return ret == 0 ? i1->index - i2->index : ret;
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    SendCmdContext *sendcmd = ctx->priv;
+    int ret, i, j;
+    char *buf;
+
+    sendcmd->class = &sendcmd_class;
+    av_opt_set_defaults(sendcmd);
+
+    if ((ret = av_set_options_string(sendcmd, args, "=", ":")) < 0)
+        return ret;
+
+    if (sendcmd->commands_filename && sendcmd->commands_str) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Only one of the filename or commands options must be specified\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (sendcmd->commands_filename) {
+        uint8_t *file_buf;
+        size_t file_bufsize;
+        ret = av_file_map(sendcmd->commands_filename,
+                          &file_buf, &file_bufsize, 0, ctx);
+        if (ret < 0)
+            return ret;
+
+        /* create a 0-terminated string based on the read file */
+        buf = av_malloc(file_bufsize + 1);
+        if (!buf)
+            return AVERROR(ENOMEM);
+        memcpy(buf, file_buf, file_bufsize);
+        buf[file_bufsize] = 0;
+        av_file_unmap(file_buf, file_bufsize);
+        sendcmd->commands_str = buf;
+    }
+
+    if ((ret = parse_intervals(&sendcmd->intervals, &sendcmd->nb_intervals,
+                               sendcmd->commands_str, ctx)) < 0)
+        return ret;
+
+    qsort(sendcmd->intervals, sendcmd->nb_intervals, sizeof(Interval), cmp_intervals);
+
+    av_log(ctx, AV_LOG_DEBUG, "Parsed commands:\n");
+    for (i = 0; i < sendcmd->nb_intervals; i++) {
+        AVBPrint pbuf;
+        Interval *interval = &sendcmd->intervals[i];
+        av_log(ctx, AV_LOG_VERBOSE, "start_time:%f end_time:%f index:%d\n",
+               (double)interval->start_ts/1000000, (double)interval->end_ts/1000000, interval->index);
+        for (j = 0; j < interval->nb_commands; j++) {
+            Command *cmd = &interval->commands[j];
+            av_log(ctx, AV_LOG_VERBOSE,
+                   "    [%s] target:%s command:%s arg:%s index:%d\n",
+                   make_command_flags_str(&pbuf, cmd->flags), cmd->target, cmd->command, cmd->arg, cmd->index);
+        }
+    }
+
+    return 0;
+}
+
+static void av_cold uninit(AVFilterContext *ctx)
+{
+    SendCmdContext *sendcmd = ctx->priv;
+    int i, j;
+
+    av_opt_free(sendcmd);
+
+    for (i = 0; i < sendcmd->nb_intervals; i++) {
+        Interval *interval = &sendcmd->intervals[i];
+        for (j = 0; j < interval->nb_commands; j++) {
+            Command *cmd = &interval->commands[j];
+            av_free(cmd->target);
+            av_free(cmd->command);
+            av_free(cmd->arg);
+        }
+        av_free(interval->commands);
+    }
+    av_freep(&sendcmd->intervals);
+}
+
+static int process_frame(AVFilterLink *inlink, AVFilterBufferRef *ref)
+{
+    AVFilterContext *ctx = inlink->dst;
+    SendCmdContext *sendcmd = ctx->priv;
+    int64_t ts;
+    int i, j, ret;
+
+    if (ref->pts == AV_NOPTS_VALUE)
+        goto end;
+
+    ts = av_rescale_q(ref->pts, inlink->time_base, AV_TIME_BASE_Q);
+
+#define WITHIN_INTERVAL(ts, start_ts, end_ts) ((ts) >= (start_ts) && (ts) < (end_ts))
+
+    for (i = 0; i < sendcmd->nb_intervals; i++) {
+        Interval *interval = &sendcmd->intervals[i];
+        int flags = 0;
+
+        if (!interval->enabled && WITHIN_INTERVAL(ts, interval->start_ts, interval->end_ts)) {
+            flags += COMMAND_FLAG_ENTER;
+            interval->enabled = 1;
+        }
+        if (interval->enabled && !WITHIN_INTERVAL(ts, interval->start_ts, interval->end_ts)) {
+            flags += COMMAND_FLAG_LEAVE;
+            interval->enabled = 0;
+        }
+
+        if (flags) {
+            AVBPrint pbuf;
+            av_log(ctx, AV_LOG_VERBOSE,
+                   "[%s] interval #%d start_ts:%f end_ts:%f ts:%f\n",
+                   make_command_flags_str(&pbuf, flags), interval->index,
+                   (double)interval->start_ts/1000000, (double)interval->end_ts/1000000,
+                   (double)ts/1000000);
+
+            for (j = 0; flags && j < interval->nb_commands; j++) {
+                Command *cmd = &interval->commands[j];
+                char buf[1024];
+
+                if (cmd->flags & flags) {
+                    av_log(ctx, AV_LOG_VERBOSE,
+                           "Processing command #%d target:%s command:%s arg:%s\n",
+                           cmd->index, cmd->target, cmd->command, cmd->arg);
+                    ret = avfilter_graph_send_command(inlink->graph,
+                                                      cmd->target, cmd->command, cmd->arg,
+                                                      buf, sizeof(buf),
+                                                      AVFILTER_CMD_FLAG_ONE);
+                    av_log(ctx, AV_LOG_VERBOSE,
+                           "Command reply for command #%d: ret:%s res:%s\n",
+                           cmd->index, av_err2str(ret), buf);
+                }
+            }
+        }
+    }
+
+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_samples(inlink->dst->outputs[0], ref);
+    }
+    return AVERROR(ENOSYS);
+}
+
+#if CONFIG_SENDCMD_FILTER
+
+AVFilter avfilter_vf_sendcmd = {
+    .name      = "sendcmd",
+    .description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
+
+    .init = init,
+    .uninit = uninit,
+    .priv_size = sizeof(SendCmdContext),
+
+    .inputs = (const AVFilterPad[]) {
+        {
+            .name             = "default",
+            .type             = AVMEDIA_TYPE_VIDEO,
+            .get_video_buffer = ff_null_get_video_buffer,
+            .start_frame      = process_frame,
+            .end_frame        = ff_null_end_frame,
+        },
+        { .name = NULL }
+    },
+    .outputs = (const AVFilterPad[]) {
+        {
+            .name             = "default",
+            .type             = AVMEDIA_TYPE_VIDEO,
+        },
+        { .name = NULL }
+    },
+};
+
+#endif
+
+#if CONFIG_ASENDCMD_FILTER
+
+AVFilter avfilter_af_asendcmd = {
+    .name      = "asendcmd",
+    .description = NULL_IF_CONFIG_SMALL("Send commands to filters."),
+
+    .init = init,
+    .uninit = uninit,
+    .priv_size = sizeof(SendCmdContext),
+
+    .inputs = (const AVFilterPad[]) {
+        {
+            .name             = "default",
+            .type             = AVMEDIA_TYPE_AUDIO,
+            .get_audio_buffer = ff_null_get_audio_buffer,
+            .filter_samples   = process_frame,
+        },
+        { .name = NULL }
+    },
+    .outputs = (const AVFilterPad[]) {
+        {
+            .name             = "default",
+            .type             = AVMEDIA_TYPE_AUDIO,
+        },
+        { .name = NULL }
+    },
+};
+
+#endif
diff --git a/libavfilter/f_setpts.c b/libavfilter/f_setpts.c
new file mode 100644
index 0000000..5a58ce3
--- /dev/null
+++ b/libavfilter/f_setpts.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2010 Stefano Sabatini
+ * Copyright (c) 2008 Victor Paesa
+ *
+ * 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
+ * video presentation timestamp (PTS) modification filter
+ */
+
+/* #define DEBUG */
+
+#include "libavutil/eval.h"
+#include "libavutil/internal.h"
+#include "libavutil/mathematics.h"
+#include "avfilter.h"
+#include "internal.h"
+#include "audio.h"
+#include "video.h"
+
+static const char *const var_names[] = {
+    "FRAME_RATE",  ///< defined only for constant frame-rate video
+    "INTERLACED",  ///< tell if the current frame is interlaced
+    "N",           ///< frame number (starting at zero)
+    "NB_CONSUMED_SAMPLES", ///< number of samples consumed by the filter (only audio)
+    "NB_SAMPLES",  ///< number of samples in the current frame (only audio)
+    "POS",         ///< original position in the file of the frame
+    "PREV_INPTS",  ///< previous  input PTS
+    "PREV_INT",    ///< previous  input time in seconds
+    "PREV_OUTPTS", ///< previous output PTS
+    "PREV_OUTT",   ///< previous output time in seconds
+    "PTS",         ///< original pts in the file of the frame
+    "SAMPLE_RATE", ///< sample rate (only audio)
+    "STARTPTS",    ///< PTS at start of movie
+    "STARTT",      ///< time at start of movie
+    "T",           ///< original time in the file of the frame
+    "TB",          ///< timebase
+    NULL
+};
+
+enum var_name {
+    VAR_FRAME_RATE,
+    VAR_INTERLACED,
+    VAR_N,
+    VAR_NB_CONSUMED_SAMPLES,
+    VAR_NB_SAMPLES,
+    VAR_POS,
+    VAR_PREV_INPTS,
+    VAR_PREV_INT,
+    VAR_PREV_OUTPTS,
+    VAR_PREV_OUTT,
+    VAR_PTS,
+    VAR_SAMPLE_RATE,
+    VAR_STARTPTS,
+    VAR_STARTT,
+    VAR_T,
+    VAR_TB,
+    VAR_VARS_NB
+};
+
+typedef struct {
+    AVExpr *expr;
+    double var_values[VAR_VARS_NB];
+    enum AVMediaType type;
+} SetPTSContext;
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    SetPTSContext *setpts = ctx->priv;
+    int ret;
+
+    if ((ret = av_expr_parse(&setpts->expr, args ? args : "PTS",
+                             var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", args);
+        return ret;
+    }
+
+    setpts->var_values[VAR_N          ] = 0.0;
+    setpts->var_values[VAR_PREV_INPTS ] = setpts->var_values[VAR_PREV_INT ] = NAN;
+    setpts->var_values[VAR_PREV_OUTPTS] = setpts->var_values[VAR_PREV_OUTT] = NAN;
+    setpts->var_values[VAR_STARTPTS   ] = setpts->var_values[VAR_STARTT   ] = NAN;
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    SetPTSContext *setpts = ctx->priv;
+
+    setpts->type = inlink->type;
+    setpts->var_values[VAR_TB] = av_q2d(inlink->time_base);
+
+    setpts->var_values[VAR_SAMPLE_RATE] =
+        setpts->type == AVMEDIA_TYPE_AUDIO ? inlink->sample_rate : NAN;
+
+    setpts->var_values[VAR_FRAME_RATE] = inlink->frame_rate.num && inlink->frame_rate.den ?
+        av_q2d(inlink->frame_rate) : NAN;
+
+    av_log(inlink->src, AV_LOG_VERBOSE, "TB:%f FRAME_RATE:%f SAMPLE_RATE:%f\n",
+           setpts->var_values[VAR_TB],
+           setpts->var_values[VAR_FRAME_RATE],
+           setpts->var_values[VAR_SAMPLE_RATE]);
+    return 0;
+}
+
+#define D2TS(d)  (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
+#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
+#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts)*av_q2d(tb))
+
+static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+{
+    SetPTSContext *setpts = inlink->dst->priv;
+    double d;
+    AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
+
+    if (!outpicref)
+        return AVERROR(ENOMEM);
+
+    if (isnan(setpts->var_values[VAR_STARTPTS])) {
+        setpts->var_values[VAR_STARTPTS] = TS2D(inpicref->pts);
+        setpts->var_values[VAR_STARTT  ] = TS2T(inpicref->pts, inlink->time_base);
+    }
+    setpts->var_values[VAR_PTS       ] = TS2D(inpicref->pts);
+    setpts->var_values[VAR_T         ] = TS2T(inpicref->pts, inlink->time_base);
+    setpts->var_values[VAR_POS       ] = inpicref->pos == -1 ? NAN : inpicref->pos;
+
+    switch (inlink->type) {
+    case AVMEDIA_TYPE_VIDEO:
+        setpts->var_values[VAR_INTERLACED] = inpicref->video->interlaced;
+        break;
+
+    case AVMEDIA_TYPE_AUDIO:
+        setpts->var_values[VAR_NB_SAMPLES] = inpicref->audio->nb_samples;
+        break;
+    }
+
+    d = av_expr_eval(setpts->expr, setpts->var_values, NULL);
+    outpicref->pts = D2TS(d);
+
+    setpts->var_values[VAR_PREV_INPTS ] = TS2D(inpicref ->pts);
+    setpts->var_values[VAR_PREV_INT   ] = TS2T(inpicref ->pts, inlink->time_base);
+    setpts->var_values[VAR_PREV_OUTPTS] = TS2D(outpicref->pts);
+    setpts->var_values[VAR_PREV_OUTT]   = TS2T(outpicref->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] += inpicref->audio->nb_samples;
+        return ff_filter_samples(inlink->dst->outputs[0], outpicref);
+    } else
+        return ff_start_frame   (inlink->dst->outputs[0], outpicref);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    SetPTSContext *setpts = ctx->priv;
+    av_expr_free(setpts->expr);
+    setpts->expr = NULL;
+}
+
+#if CONFIG_ASETPTS_FILTER
+AVFilter avfilter_af_asetpts = {
+    .name      = "asetpts",
+    .description = NULL_IF_CONFIG_SMALL("Set PTS for the output audio frame."),
+    .init      = init,
+    .uninit    = uninit,
+
+    .priv_size = sizeof(SetPTSContext),
+
+    .inputs = (const AVFilterPad[]) {
+        {
+            .name             = "default",
+            .type             = AVMEDIA_TYPE_AUDIO,
+            .get_audio_buffer = ff_null_get_audio_buffer,
+            .config_props     = config_input,
+            .filter_samples   = filter_frame,
+        },
+        { .name = NULL }
+    },
+    .outputs = (const AVFilterPad[]) {
+        {
+            .name             = "default",
+            .type             = AVMEDIA_TYPE_AUDIO,
+        },
+        { .name = NULL }
+    },
+};
+#endif /* CONFIG_ASETPTS_FILTER */
+
+#if CONFIG_SETPTS_FILTER
+static const AVFilterPad avfilter_vf_setpts_inputs[] = {
+    {
+        .name             = "default",
+        .type             = AVMEDIA_TYPE_VIDEO,
+        .get_video_buffer = ff_null_get_video_buffer,
+        .config_props     = config_input,
+        .start_frame      = filter_frame,
+    },
+    { NULL }
+};
+
+static const AVFilterPad avfilter_vf_setpts_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_setpts = {
+    .name      = "setpts",
+    .description = NULL_IF_CONFIG_SMALL("Set PTS for the output video frame."),
+    .init      = init,
+    .uninit    = uninit,
+
+    .priv_size = sizeof(SetPTSContext),
+
+    .inputs    = avfilter_vf_setpts_inputs,
+    .outputs   = avfilter_vf_setpts_outputs,
+};
+#endif /* CONFIG_SETPTS_FILTER */
diff --git a/libavfilter/f_settb.c b/libavfilter/f_settb.c
new file mode 100644
index 0000000..f42a15c
--- /dev/null
+++ b/libavfilter/f_settb.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2010 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
+ * Set timebase for the output link.
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+
+#include "libavutil/avstring.h"
+#include "libavutil/eval.h"
+#include "libavutil/internal.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/rational.h"
+#include "avfilter.h"
+#include "internal.h"
+#include "audio.h"
+#include "video.h"
+
+static const char *const var_names[] = {
+    "AVTB",   /* default timebase 1/AV_TIME_BASE */
+    "intb",   /* input timebase */
+    "sr",     /* sample rate */
+    NULL
+};
+
+enum var_name {
+    VAR_AVTB,
+    VAR_INTB,
+    VAR_SR,
+    VAR_VARS_NB
+};
+
+typedef struct {
+    char tb_expr[256];
+    double var_values[VAR_VARS_NB];
+} SetTBContext;
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    SetTBContext *settb = ctx->priv;
+    av_strlcpy(settb->tb_expr, "intb", sizeof(settb->tb_expr));
+
+    if (args)
+        sscanf(args, "%255[^:]", settb->tb_expr);
+
+    return 0;
+}
+
+static int config_output_props(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    SetTBContext *settb = ctx->priv;
+    AVFilterLink *inlink = ctx->inputs[0];
+    AVRational time_base;
+    int ret;
+    double res;
+
+    settb->var_values[VAR_AVTB] = av_q2d(AV_TIME_BASE_Q);
+    settb->var_values[VAR_INTB] = av_q2d(inlink->time_base);
+    settb->var_values[VAR_SR]   = inlink->sample_rate;
+
+    outlink->w = inlink->w;
+    outlink->h = inlink->h;
+
+    if ((ret = av_expr_parse_and_eval(&res, settb->tb_expr, var_names, settb->var_values,
+                                      NULL, NULL, NULL, NULL, NULL, 0, NULL)) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid expression '%s' for timebase.\n", settb->tb_expr);
+        return ret;
+    }
+    time_base = av_d2q(res, INT_MAX);
+    if (time_base.num <= 0 || time_base.den <= 0) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Invalid non-positive values for the timebase num:%d or den:%d.\n",
+               time_base.num, time_base.den);
+        return AVERROR(EINVAL);
+    }
+
+    outlink->time_base = time_base;
+    av_log(outlink->src, AV_LOG_VERBOSE, "tb:%d/%d -> tb:%d/%d\n",
+           inlink ->time_base.num, inlink ->time_base.den,
+           outlink->time_base.num, outlink->time_base.den);
+
+    return 0;
+}
+
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AVFilterLink *outlink = ctx->outputs[0];
+
+    if (av_cmp_q(inlink->time_base, outlink->time_base)) {
+        int64_t orig_pts = picref->pts;
+        picref->pts = av_rescale_q(picref->pts, inlink->time_base, outlink->time_base);
+        av_log(ctx, AV_LOG_DEBUG, "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
+               inlink ->time_base.num, inlink ->time_base.den, orig_pts,
+               outlink->time_base.num, outlink->time_base.den, picref->pts);
+    }
+    inlink->cur_buf = NULL;
+
+    return ff_start_frame(outlink, picref);
+}
+
+static int filter_samples(AVFilterLink *inlink, AVFilterBufferRef *samplesref)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AVFilterLink *outlink = ctx->outputs[0];
+
+    if (av_cmp_q(inlink->time_base, outlink->time_base)) {
+        int64_t orig_pts = samplesref->pts;
+        samplesref->pts = av_rescale_q(samplesref->pts, inlink->time_base, outlink->time_base);
+        av_log(ctx, AV_LOG_DEBUG, "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
+               inlink ->time_base.num, inlink ->time_base.den, orig_pts,
+               outlink->time_base.num, outlink->time_base.den, samplesref->pts);
+    }
+
+    return ff_filter_samples(outlink, samplesref);
+}
+
+#if CONFIG_SETTB_FILTER
+static const AVFilterPad avfilter_vf_settb_inputs[] = {
+    {
+        .name             = "default",
+        .type             = AVMEDIA_TYPE_VIDEO,
+        .get_video_buffer = ff_null_get_video_buffer,
+        .start_frame      = start_frame,
+        .end_frame        = ff_null_end_frame
+    },
+    { NULL }
+};
+
+static const AVFilterPad avfilter_vf_settb_outputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .config_props = config_output_props,
+    },
+    { NULL }
+};
+
+AVFilter avfilter_vf_settb = {
+    .name      = "settb",
+    .description = NULL_IF_CONFIG_SMALL("Set timebase for the video output link."),
+    .init      = init,
+
+    .priv_size = sizeof(SetTBContext),
+
+    .inputs    = avfilter_vf_settb_inputs,
+    .outputs   = avfilter_vf_settb_outputs,
+};
+#endif
+
+#if CONFIG_ASETTB_FILTER
+AVFilter avfilter_af_asettb = {
+    .name      = "asettb",
+    .description = NULL_IF_CONFIG_SMALL("Set timebase for the audio output link."),
+    .init      = init,
+
+    .priv_size = sizeof(SetTBContext),
+
+    .inputs    = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_AUDIO,
+          .get_audio_buffer = ff_null_get_audio_buffer,
+          .filter_samples   = filter_samples, },
+        { .name = NULL }
+    },
+    .outputs   = (const AVFilterPad[]) {
+        { .name            = "default",
+          .type            = AVMEDIA_TYPE_AUDIO,
+          .config_props    = config_output_props, },
+        { .name = NULL}
+    },
+};
+#endif
diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c
index b13be68..e05f982 100644
--- a/libavfilter/fifo.c
+++ b/libavfilter/fifo.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -275,7 +275,7 @@
         .start_frame      = add_to_queue,
         .draw_slice       = draw_slice,
         .end_frame        = end_frame,
-        .rej_perms        = AV_PERM_REUSE2,
+        .min_perms        = AV_PERM_PRESERVE,
     },
     { NULL }
 };
@@ -308,7 +308,7 @@
         .type             = AVMEDIA_TYPE_AUDIO,
         .get_audio_buffer = ff_null_get_audio_buffer,
         .filter_samples   = add_to_queue,
-        .rej_perms        = AV_PERM_REUSE2,
+        .min_perms        = AV_PERM_PRESERVE,
     },
     { NULL }
 };
diff --git a/libavfilter/filtfmts.c b/libavfilter/filtfmts.c
index 3ec8116..14417cb 100644
--- a/libavfilter/filtfmts.c
+++ b/libavfilter/filtfmts.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Stefano Sabatini
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -22,29 +22,69 @@
 
 #include "libavformat/avformat.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/samplefmt.h"
 #include "libavfilter/avfilter.h"
 #include "libavfilter/formats.h"
 
 #undef fprintf
 #undef printf
 
+static void print_formats(AVFilterContext *filter_ctx)
+{
+    int i, j;
+
+#define PRINT_FMTS(inout, outin, INOUT)                                 \
+    for (i = 0; i < filter_ctx->inout##put_count; i++) {                     \
+        if (filter_ctx->inout##puts[i]->type == AVMEDIA_TYPE_VIDEO) {   \
+            AVFilterFormats *fmts =                                     \
+                filter_ctx->inout##puts[i]->outin##_formats;            \
+            for (j = 0; j < fmts->format_count; j++)                    \
+                if(av_get_pix_fmt_name(fmts->formats[j]))               \
+                printf(#INOUT "PUT[%d] %s: fmt:%s\n",                   \
+                       i, filter_ctx->filter->inout##puts[i].name,      \
+                       av_get_pix_fmt_name(fmts->formats[j]));          \
+        } else if (filter_ctx->inout##puts[i]->type == AVMEDIA_TYPE_AUDIO) { \
+            AVFilterFormats *fmts;                                      \
+            AVFilterChannelLayouts *layouts;                            \
+                                                                        \
+            fmts = filter_ctx->inout##puts[i]->outin##_formats;         \
+            for (j = 0; j < fmts->format_count; j++)                    \
+                printf(#INOUT "PUT[%d] %s: fmt:%s\n",                   \
+                       i, filter_ctx->filter->inout##puts[i].name,      \
+                       av_get_sample_fmt_name(fmts->formats[j]));       \
+                                                                        \
+            layouts = filter_ctx->inout##puts[i]->outin##_channel_layouts; \
+            for (j = 0; j < layouts->nb_channel_layouts; j++) {                  \
+                char buf[256];                                          \
+                av_get_channel_layout_string(buf, sizeof(buf), -1,      \
+                                             layouts->channel_layouts[j]);         \
+                printf(#INOUT "PUT[%d] %s: chlayout:%s\n",              \
+                       i, filter_ctx->filter->inout##puts[i].name, buf); \
+            }                                                           \
+        }                                                               \
+    }                                                                   \
+
+    PRINT_FMTS(in,  out, IN);
+    PRINT_FMTS(out, in,  OUT);
+}
+
 int main(int argc, char **argv)
 {
     AVFilter *filter;
     AVFilterContext *filter_ctx;
     const char *filter_name;
     const char *filter_args = NULL;
-    int i, j;
+    int i;
 
     av_log_set_level(AV_LOG_DEBUG);
 
-    if (!argv[1]) {
+    if (argc < 2) {
         fprintf(stderr, "Missing filter name as argument\n");
         return 1;
     }
 
     filter_name = argv[1];
-    if (argv[2])
+    if (argc > 2)
         filter_args = argv[2];
 
     avfilter_register_all();
@@ -83,23 +123,7 @@
     else
         ff_default_query_formats(filter_ctx);
 
-    /* print the supported formats in input */
-    for (i = 0; i < filter_ctx->input_count; i++) {
-        AVFilterFormats *fmts = filter_ctx->inputs[i]->out_formats;
-        for (j = 0; j < fmts->format_count; j++)
-            printf("INPUT[%d] %s: %s\n",
-                   i, filter_ctx->filter->inputs[i].name,
-                   av_get_pix_fmt_name(fmts->formats[j]));
-    }
-
-    /* print the supported formats in output */
-    for (i = 0; i < filter_ctx->output_count; i++) {
-        AVFilterFormats *fmts = filter_ctx->outputs[i]->in_formats;
-        for (j = 0; j < fmts->format_count; j++)
-            printf("OUTPUT[%d] %s: %s\n",
-                   i, filter_ctx->filter->outputs[i].name,
-                   av_get_pix_fmt_name(fmts->formats[j]));
-    }
+    print_formats(filter_ctx);
 
     avfilter_free(filter_ctx);
     fflush(stdout);
diff --git a/libavfilter/formats.c b/libavfilter/formats.c
index 3b890d2..c8c2257 100644
--- a/libavfilter/formats.c
+++ b/libavfilter/formats.c
@@ -2,25 +2,28 @@
  * Filter layer - format negotiation
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/common.h"
+#include "libavutil/eval.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/audioconvert.h"
 #include "avfilter.h"
 #include "internal.h"
 #include "formats.h"
@@ -64,11 +67,17 @@
             goto fail;                                                          \
         for (i = 0; i < a->nb; i++)                                             \
             for (j = 0; j < b->nb; j++)                                         \
-                if (a->fmts[i] == b->fmts[j])                                   \
+                if (a->fmts[i] == b->fmts[j]) {                                 \
+                    if(k >= FFMIN(a->nb, b->nb)){                               \
+                        av_log(0, AV_LOG_ERROR, "Duplicate formats in avfilter_merge_formats() detected\n"); \
+                        av_free(ret->fmts);                                     \
+                        av_free(ret);                                           \
+                        return NULL;                                            \
+                    }                                                           \
                     ret->fmts[k++] = a->fmts[i];                                \
-                                                                                \
-        ret->nb = k;                                                            \
+                }                                                               \
     }                                                                           \
+    ret->nb = k;                                                                \
     /* check that there was at least one common format */                       \
     if (!ret->nb)                                                               \
         goto fail;                                                              \
@@ -155,26 +164,72 @@
 {
     const int *p;
 
-    for (p = fmts; *p != AV_PIX_FMT_NONE; p++) {
+    for (p = fmts; *p != -1; p++) {
         if (fmt == *p)
             return 1;
     }
     return 0;
 }
 
+#define COPY_INT_LIST(list_copy, list, type) {                          \
+    int count = 0;                                                      \
+    if (list)                                                           \
+        for (count = 0; list[count] != -1; count++)                     \
+            ;                                                           \
+    list_copy = av_calloc(count+1, sizeof(type));                       \
+    if (list_copy) {                                                    \
+        memcpy(list_copy, list, sizeof(type) * count);                  \
+        list_copy[count] = -1;                                          \
+    }                                                                   \
+}
+
+int *ff_copy_int_list(const int * const list)
+{
+    int *ret = NULL;
+    COPY_INT_LIST(ret, list, int);
+    return ret;
+}
+
+int64_t *ff_copy_int64_list(const int64_t * const list)
+{
+    int64_t *ret = NULL;
+    COPY_INT_LIST(ret, list, int64_t);
+    return ret;
+}
+
+#define MAKE_FORMAT_LIST(type, field, count_field)                      \
+    type *formats;                                                      \
+    int count = 0;                                                      \
+    if (fmts)                                                           \
+        for (count = 0; fmts[count] != -1; count++)                     \
+            ;                                                           \
+    formats = av_mallocz(sizeof(*formats));                             \
+    if (!formats) return NULL;                                          \
+    formats->count_field = count;                                       \
+    if (count) {                                                        \
+        formats->field = av_malloc(sizeof(*formats->field)*count);      \
+        if (!formats->field) {                                          \
+            av_free(formats);                                           \
+            return NULL;                                                \
+        }                                                               \
+    }
+
 AVFilterFormats *ff_make_format_list(const int *fmts)
 {
-    AVFilterFormats *formats;
-    int count;
+    MAKE_FORMAT_LIST(AVFilterFormats, formats, format_count);
+    while (count--)
+        formats->formats[count] = fmts[count];
 
-    for (count = 0; fmts[count] != -1; count++)
-        ;
+    return formats;
+}
 
-    formats               = av_mallocz(sizeof(*formats));
+AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts)
+{
+    MAKE_FORMAT_LIST(AVFilterChannelLayouts,
+                     channel_layouts, nb_channel_layouts);
     if (count)
-        formats->formats  = av_malloc(sizeof(*formats->formats) * count);
-    formats->format_count = count;
-    memcpy(formats->formats, fmts, sizeof(*formats->formats) * count);
+        memcpy(formats->channel_layouts, fmts,
+               sizeof(*formats->channel_layouts) * count);
 
     return formats;
 }
@@ -196,7 +251,7 @@
     return 0;                                               \
 } while (0)
 
-int ff_add_format(AVFilterFormats **avff, int fmt)
+int ff_add_format(AVFilterFormats **avff, int64_t fmt)
 {
     ADD_FORMAT(avff, fmt, int, formats, format_count);
 }
@@ -223,6 +278,16 @@
     return ret;
 }
 
+const int64_t avfilter_all_channel_layouts[] = {
+#include "all_channel_layouts.inc"
+    -1
+};
+
+// AVFilterFormats *avfilter_make_all_channel_layouts(void)
+// {
+//     return avfilter_make_format64_list(avfilter_all_channel_layouts);
+// }
+
 AVFilterFormats *ff_planar_sample_fmts(void)
 {
     AVFilterFormats *ret = NULL;
@@ -334,13 +399,13 @@
     int count = 0, i;                                               \
                                                                     \
     for (i = 0; i < ctx->nb_inputs; i++) {                          \
-        if (ctx->inputs[i]) {                                       \
+        if (ctx->inputs[i] && !ctx->inputs[i]->out_fmts) {          \
             ref(fmts, &ctx->inputs[i]->out_fmts);                   \
             count++;                                                \
         }                                                           \
     }                                                               \
     for (i = 0; i < ctx->nb_outputs; i++) {                         \
-        if (ctx->outputs[i]) {                                      \
+        if (ctx->outputs[i] && !ctx->outputs[i]->in_fmts) {         \
             ref(fmts, &ctx->outputs[i]->in_fmts);                   \
             count++;                                                \
         }                                                           \
@@ -392,3 +457,93 @@
 
     return 0;
 }
+
+/* internal functions for parsing audio format arguments */
+
+int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
+{
+    char *tail;
+    int pix_fmt = av_get_pix_fmt(arg);
+    if (pix_fmt == AV_PIX_FMT_NONE) {
+        pix_fmt = strtol(arg, &tail, 0);
+        if (*tail || (unsigned)pix_fmt >= AV_PIX_FMT_NB) {
+            av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
+            return AVERROR(EINVAL);
+        }
+    }
+    *ret = pix_fmt;
+    return 0;
+}
+
+int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
+{
+    char *tail;
+    int sfmt = av_get_sample_fmt(arg);
+    if (sfmt == AV_SAMPLE_FMT_NONE) {
+        sfmt = strtol(arg, &tail, 0);
+        if (*tail || (unsigned)sfmt >= AV_SAMPLE_FMT_NB) {
+            av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
+            return AVERROR(EINVAL);
+        }
+    }
+    *ret = sfmt;
+    return 0;
+}
+
+int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx)
+{
+    AVRational r;
+    if(av_parse_ratio(&r, arg, INT_MAX, 0, log_ctx) < 0 ||r.num<=0  ||r.den<=0) {
+        av_log(log_ctx, AV_LOG_ERROR, "Invalid time base '%s'\n", arg);
+        return AVERROR(EINVAL);
+    }
+    *ret = r;
+    return 0;
+}
+
+int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
+{
+    char *tail;
+    double srate = av_strtod(arg, &tail);
+    if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
+        av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
+        return AVERROR(EINVAL);
+    }
+    *ret = srate;
+    return 0;
+}
+
+int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
+{
+    char *tail;
+    int64_t chlayout = av_get_channel_layout(arg);
+    if (chlayout == 0) {
+        chlayout = strtol(arg, &tail, 10);
+        if (*tail || chlayout == 0) {
+            av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
+            return AVERROR(EINVAL);
+        }
+    }
+    *ret = chlayout;
+    return 0;
+}
+
+#ifdef TEST
+
+#undef printf
+
+int main(void)
+{
+    const int64_t *cl;
+    char buf[512];
+
+    for (cl = avfilter_all_channel_layouts; *cl != -1; cl++) {
+        av_get_channel_layout_string(buf, sizeof(buf), -1, *cl);
+        printf("%s\n", buf);
+    }
+
+    return 0;
+}
+
+#endif
+
diff --git a/libavfilter/formats.h b/libavfilter/formats.h
index 0e1628c..c5a4e3d 100644
--- a/libavfilter/formats.h
+++ b/libavfilter/formats.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -97,6 +97,9 @@
 AVFilterChannelLayouts *ff_all_channel_layouts(void);
 AVFilterFormats *ff_all_samplerates(void);
 
+AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts);
+
+
 /**
  * A helper for query_formats() which sets all links to the same list of channel
  * layouts/sample rates. If there are no links hooked to this filter, the list
@@ -150,10 +153,10 @@
  * @return a non negative value in case of success, or a negative
  * value corresponding to an AVERROR code in case of error
  */
-int ff_add_format(AVFilterFormats **avff, int fmt);
+int ff_add_format(AVFilterFormats **avff, int64_t fmt);
 
 /**
- * Return a list of all formats supported by Libav for the given media type.
+ * Return a list of all formats supported by FFmpeg for the given media type.
  */
 AVFilterFormats *ff_all_formats(enum AVMediaType type);
 
diff --git a/libavfilter/gradfun.h b/libavfilter/gradfun.h
index 876579a..939b129 100644
--- a/libavfilter/gradfun.h
+++ b/libavfilter/gradfun.h
@@ -2,20 +2,20 @@
  * Copyright (c) 2010 Nolan Lum <nol888@gmail.com>
  * Copyright (c) 2009 Loren Merritt <lorenm@u.washignton.edu>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -33,13 +33,13 @@
     int chroma_r;  ///< blur radius for the chroma planes
     uint16_t *buf; ///< holds image data for blur algorithm passed into filter.
     /// DSP functions.
-    void (*filter_line) (uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers);
-    void (*blur_line) (uint16_t *dc, uint16_t *buf, uint16_t *buf1, uint8_t *src, int src_linesize, int width);
+    void (*filter_line) (uint8_t *dst, const uint8_t *src, const uint16_t *dc, int width, int thresh, const uint16_t *dithers);
+    void (*blur_line) (uint16_t *dc, uint16_t *buf, const uint16_t *buf1, const uint8_t *src, int src_linesize, int width);
 } GradFunContext;
 
 void ff_gradfun_init_x86(GradFunContext *gf);
 
-void ff_gradfun_filter_line_c(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers);
-void ff_gradfun_blur_line_c(uint16_t *dc, uint16_t *buf, uint16_t *buf1, uint8_t *src, int src_linesize, int width);
+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);
+void ff_gradfun_blur_line_c(uint16_t *dc, uint16_t *buf, const uint16_t *buf1, const uint8_t *src, int src_linesize, int width);
 
 #endif /* AVFILTER_GRADFUN_H */
diff --git a/libavfilter/graphdump.c b/libavfilter/graphdump.c
new file mode 100644
index 0000000..c9d0fb0
--- /dev/null
+++ b/libavfilter/graphdump.c
@@ -0,0 +1,164 @@
+/*
+ * Filter graphs to bad ASCII-art
+ * 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/audioconvert.h"
+#include "libavutil/bprint.h"
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+#include "avfiltergraph.h"
+
+static int print_link_prop(AVBPrint *buf, AVFilterLink *link)
+{
+    char *format;
+    char layout[64];
+
+    if (!buf)
+        buf = &(AVBPrint){ 0 }; /* dummy buffer */
+    switch (link->type) {
+        case AVMEDIA_TYPE_VIDEO:
+            format = av_x_if_null(av_get_pix_fmt_name(link->format), "?");
+            av_bprintf(buf, "[%dx%d %d:%d %s]", link->w, link->h,
+                    link->sample_aspect_ratio.num,
+                    link->sample_aspect_ratio.den,
+                    format);
+            break;
+
+        case AVMEDIA_TYPE_AUDIO:
+            av_get_channel_layout_string(layout, sizeof(layout),
+                                         -1, link->channel_layout);
+            format = av_x_if_null(av_get_sample_fmt_name(link->format), "?");
+            av_bprintf(buf, "[%dHz %s:%s]",
+                       (int)link->sample_rate, format, layout);
+            break;
+
+        default:
+            av_bprintf(buf, "?");
+            break;
+    }
+    return buf->len;
+}
+
+static void avfilter_graph_dump_to_buf(AVBPrint *buf, AVFilterGraph *graph)
+{
+    unsigned i, j, x, e;
+
+    for (i = 0; i < graph->filter_count; i++) {
+        AVFilterContext *filter = graph->filters[i];
+        unsigned max_src_name = 0, max_dst_name = 0;
+        unsigned max_in_name  = 0, max_out_name = 0;
+        unsigned max_in_fmt   = 0, max_out_fmt  = 0;
+        unsigned width, height, in_indent;
+        unsigned lname = strlen(filter->name);
+        unsigned ltype = strlen(filter->filter->name);
+
+        for (j = 0; j < filter->input_count; j++) {
+            AVFilterLink *l = filter->inputs[j];
+            unsigned ln = strlen(l->src->name) + 1 + strlen(l->srcpad->name);
+            max_src_name = FFMAX(max_src_name, ln);
+            max_in_name = FFMAX(max_in_name, strlen(l->dstpad->name));
+            max_in_fmt = FFMAX(max_in_fmt, print_link_prop(NULL, l));
+        }
+        for (j = 0; j < filter->output_count; j++) {
+            AVFilterLink *l = filter->outputs[j];
+            unsigned ln = strlen(l->dst->name) + 1 + strlen(l->dstpad->name);
+            max_dst_name = FFMAX(max_dst_name, ln);
+            max_out_name = FFMAX(max_out_name, strlen(l->srcpad->name));
+            max_out_fmt = FFMAX(max_out_fmt, print_link_prop(NULL, l));
+        }
+        in_indent = max_src_name + max_in_name + max_in_fmt;
+        in_indent += in_indent ? 4 : 0;
+        width = FFMAX(lname + 2, ltype + 4);
+        height = FFMAX3(2, filter->input_count, filter->output_count);
+        av_bprint_chars(buf, ' ', in_indent);
+        av_bprintf(buf, "+");
+        av_bprint_chars(buf, '-', width);
+        av_bprintf(buf, "+\n");
+        for (j = 0; j < height; j++) {
+            unsigned in_no  = j - (height - filter->input_count ) / 2;
+            unsigned out_no = j - (height - filter->output_count) / 2;
+
+            /* Input link */
+            if (in_no < filter->input_count) {
+                AVFilterLink *l = filter->inputs[in_no];
+                e = buf->len + max_src_name + 2;
+                av_bprintf(buf, "%s:%s", l->src->name, l->srcpad->name);
+                av_bprint_chars(buf, '-', e - buf->len);
+                e = buf->len + max_in_fmt + 2 +
+                    max_in_name - strlen(l->dstpad->name);
+                print_link_prop(buf, l);
+                av_bprint_chars(buf, '-', e - buf->len);
+                av_bprintf(buf, "%s", l->dstpad->name);
+            } else {
+                av_bprint_chars(buf, ' ', in_indent);
+            }
+
+            /* Filter */
+            av_bprintf(buf, "|");
+            if (j == (height - 2) / 2) {
+                x = (width - lname) / 2;
+                av_bprintf(buf, "%*s%-*s", x, "", width - x, filter->name);
+            } else if (j == (height - 2) / 2 + 1) {
+                x = (width - ltype - 2) / 2;
+                av_bprintf(buf, "%*s(%s)%*s", x, "", filter->filter->name,
+                        width - ltype - 2 - x, "");
+            } else {
+                av_bprint_chars(buf, ' ', width);
+            }
+            av_bprintf(buf, "|");
+
+            /* Output link */
+            if (out_no < filter->output_count) {
+                AVFilterLink *l = filter->outputs[out_no];
+                unsigned ln = strlen(l->dst->name) + 1 +
+                              strlen(l->dstpad->name);
+                e = buf->len + max_out_name + 2;
+                av_bprintf(buf, "%s", l->srcpad->name);
+                av_bprint_chars(buf, '-', e - buf->len);
+                e = buf->len + max_out_fmt + 2 +
+                    max_dst_name - ln;
+                print_link_prop(buf, l);
+                av_bprint_chars(buf, '-', e - buf->len);
+                av_bprintf(buf, "%s:%s", l->dst->name, l->dstpad->name);
+            }
+            av_bprintf(buf, "\n");
+        }
+        av_bprint_chars(buf, ' ', in_indent);
+        av_bprintf(buf, "+");
+        av_bprint_chars(buf, '-', width);
+        av_bprintf(buf, "+\n");
+        av_bprintf(buf, "\n");
+    }
+}
+
+char *avfilter_graph_dump(AVFilterGraph *graph, const char *options)
+{
+    AVBPrint buf;
+    char *dump;
+
+    av_bprint_init(&buf, 0, 0);
+    avfilter_graph_dump_to_buf(&buf, graph);
+    av_bprint_init(&buf, buf.len + 1, buf.len + 1);
+    avfilter_graph_dump_to_buf(&buf, graph);
+    av_bprint_finalize(&buf, &dump);
+    return dump;
+}
diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c
index 3921189..c34651f 100644
--- a/libavfilter/graphparser.c
+++ b/libavfilter/graphparser.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2008 Vitor Sessak
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -101,7 +101,7 @@
     char tmp_args[256];
     int ret;
 
-    snprintf(inst_name, sizeof(inst_name), "Parsed filter %d %s", index, filt_name);
+    snprintf(inst_name, sizeof(inst_name), "Parsed_%s_%d", filt_name, index);
 
     filt = avfilter_get_by_name(filt_name);
 
@@ -379,7 +379,7 @@
                           AVFilterInOut **inputs,
                           AVFilterInOut **outputs)
 {
-    int index = 0, ret;
+    int index = 0, ret = 0;
     char chr = 0;
 
     AVFilterInOut *curr_inputs = NULL, *open_inputs = NULL, *open_outputs = NULL;
@@ -394,18 +394,17 @@
         filters += strspn(filters, WHITESPACES);
 
         if ((ret = parse_inputs(&filters, &curr_inputs, &open_outputs, graph)) < 0)
-            goto fail;
-
+            goto end;
         if ((ret = parse_filter(&filter, &filters, graph, index, graph)) < 0)
-            goto fail;
+            goto end;
 
 
         if ((ret = link_filter_inouts(filter, &curr_inputs, &open_inputs, graph)) < 0)
-            goto fail;
+            goto end;
 
         if ((ret = parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs,
                                  graph)) < 0)
-            goto fail;
+            goto end;
 
         filters += strspn(filters, WHITESPACES);
         chr = *filters++;
@@ -420,16 +419,17 @@
                "Unable to parse graph description substring: \"%s\"\n",
                filters - 1);
         ret = AVERROR(EINVAL);
-        goto fail;
+        goto end;
     }
 
     append_inout(&open_outputs, &curr_inputs);
 
+
     *inputs  = open_inputs;
     *outputs = open_outputs;
     return 0;
 
- fail:
+ fail:end:
     for (; graph->filter_count > 0; graph->filter_count--)
         avfilter_free(graph->filters[graph->filter_count - 1]);
     av_freep(&graph->filters);
@@ -444,10 +444,13 @@
 }
 
 int avfilter_graph_parse(AVFilterGraph *graph, const char *filters,
-                         AVFilterInOut *open_inputs,
-                         AVFilterInOut *open_outputs, void *log_ctx)
+                         AVFilterInOut **open_inputs_ptr, AVFilterInOut **open_outputs_ptr,
+                         void *log_ctx)
 {
+#if 0
     int ret;
+    AVFilterInOut *open_inputs  = open_inputs_ptr  ? *open_inputs_ptr  : NULL;
+    AVFilterInOut *open_outputs = open_outputs_ptr ? *open_outputs_ptr : NULL;
     AVFilterInOut *cur, *match, *inputs = NULL, *outputs = NULL;
 
     if ((ret = avfilter_graph_parse2(graph, filters, &inputs, &outputs)) < 0)
@@ -501,7 +504,89 @@
     }
     avfilter_inout_free(&inputs);
     avfilter_inout_free(&outputs);
-    avfilter_inout_free(&open_inputs);
-    avfilter_inout_free(&open_outputs);
+    /* clear open_in/outputs only if not passed as parameters */
+    if (open_inputs_ptr) *open_inputs_ptr = open_inputs;
+    else avfilter_inout_free(&open_inputs);
+    if (open_outputs_ptr) *open_outputs_ptr = open_outputs;
+    else avfilter_inout_free(&open_outputs);
     return ret;
 }
+#else
+    int index = 0, ret = 0;
+    char chr = 0;
+
+    AVFilterInOut *curr_inputs = NULL;
+    AVFilterInOut *open_inputs  = open_inputs_ptr  ? *open_inputs_ptr  : NULL;
+    AVFilterInOut *open_outputs = open_outputs_ptr ? *open_outputs_ptr : NULL;
+
+    do {
+        AVFilterContext *filter;
+        const char *filterchain = filters;
+        filters += strspn(filters, WHITESPACES);
+
+        if ((ret = parse_inputs(&filters, &curr_inputs, &open_outputs, log_ctx)) < 0)
+            goto end;
+
+        if ((ret = parse_filter(&filter, &filters, graph, index, log_ctx)) < 0)
+            goto end;
+
+        if (filter->input_count == 1 && !curr_inputs && !index) {
+            /* First input pad, assume it is "[in]" if not specified */
+            const char *tmp = "[in]";
+            if ((ret = parse_inputs(&tmp, &curr_inputs, &open_outputs, log_ctx)) < 0)
+                goto end;
+        }
+
+        if ((ret = link_filter_inouts(filter, &curr_inputs, &open_inputs, log_ctx)) < 0)
+            goto end;
+
+        if ((ret = parse_outputs(&filters, &curr_inputs, &open_inputs, &open_outputs,
+                                 log_ctx)) < 0)
+            goto end;
+
+        filters += strspn(filters, WHITESPACES);
+        chr = *filters++;
+
+        if (chr == ';' && curr_inputs) {
+            av_log(log_ctx, AV_LOG_ERROR,
+                   "Invalid filterchain containing an unlabelled output pad: \"%s\"\n",
+                   filterchain);
+            ret = AVERROR(EINVAL);
+            goto end;
+        }
+        index++;
+    } while (chr == ',' || chr == ';');
+
+    if (chr) {
+        av_log(log_ctx, AV_LOG_ERROR,
+               "Unable to parse graph description substring: \"%s\"\n",
+               filters - 1);
+        ret = AVERROR(EINVAL);
+        goto end;
+    }
+
+    if (curr_inputs) {
+        /* Last output pad, assume it is "[out]" if not specified */
+        const char *tmp = "[out]";
+        if ((ret = parse_outputs(&tmp, &curr_inputs, &open_inputs, &open_outputs,
+                                 log_ctx)) < 0)
+            goto end;
+    }
+
+end:
+    /* clear open_in/outputs only if not passed as parameters */
+    if (open_inputs_ptr) *open_inputs_ptr = open_inputs;
+    else avfilter_inout_free(&open_inputs);
+    if (open_outputs_ptr) *open_outputs_ptr = open_outputs;
+    else avfilter_inout_free(&open_outputs);
+    avfilter_inout_free(&curr_inputs);
+
+    if (ret < 0) {
+        for (; graph->filter_count > 0; graph->filter_count--)
+            avfilter_free(graph->filters[graph->filter_count - 1]);
+        av_freep(&graph->filters);
+    }
+    return ret;
+}
+
+#endif
diff --git a/libavfilter/internal.h b/libavfilter/internal.h
index 6f868ae..8d03913 100644
--- a/libavfilter/internal.h
+++ b/libavfilter/internal.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,30 @@
  */
 
 #include "avfilter.h"
+#include "avfiltergraph.h"
+#include "formats.h"
+#include "video.h"
+
+#define POOL_SIZE 32
+typedef struct AVFilterPool {
+    AVFilterBufferRef *pic[POOL_SIZE];
+    int count;
+    int refcount;
+    int draining;
+} AVFilterPool;
+
+typedef struct AVFilterCommand {
+    double time;                ///< time expressed in seconds
+    char *command;              ///< command
+    char *arg;                  ///< optional argument for the command
+    int flags;
+    struct AVFilterCommand *next;
+} AVFilterCommand;
+
+/**
+ * Update the position of a link in the age heap.
+ */
+void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link);
 
 #if !FF_API_AVFILTERPAD_PUBLIC
 /**
@@ -177,9 +201,93 @@
 /** Tell is a format is contained in the provided list terminated by -1. */
 int ff_fmt_is_in(int fmt, const int *fmts);
 
-#define FF_DPRINTF_START(ctx, func) av_dlog(NULL, "%-16s: ", #func)
+/**
+ * Return a copy of a list of integers terminated by -1, or NULL in
+ * case of copy failure.
+ */
+int *ff_copy_int_list(const int * const list);
 
-void ff_dlog_link(void *ctx, AVFilterLink *link, int end);
+/**
+ * Return a copy of a list of 64-bit integers, or NULL in case of
+ * copy failure.
+ */
+int64_t *ff_copy_int64_list(const int64_t * const list);
+
+/* Functions to parse audio format arguments */
+
+/**
+ * Parse a pixel format.
+ *
+ * @param ret pixel format pointer to where the value should be written
+ * @param arg string to parse
+ * @param log_ctx log context
+ * @return 0 in case of success, a negative AVERROR code on error
+ */
+int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx);
+
+/**
+ * Parse a sample rate.
+ *
+ * @param ret unsigned integer pointer to where the value should be written
+ * @param arg string to parse
+ * @param log_ctx log context
+ * @return 0 in case of success, a negative AVERROR code on error
+ */
+int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx);
+
+/**
+ * Parse a time base.
+ *
+ * @param ret unsigned AVRational pointer to where the value should be written
+ * @param arg string to parse
+ * @param log_ctx log context
+ * @return 0 in case of success, a negative AVERROR code on error
+ */
+int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx);
+
+/**
+ * Parse a sample format name or a corresponding integer representation.
+ *
+ * @param ret integer pointer to where the value should be written
+ * @param arg string to parse
+ * @param log_ctx log context
+ * @return 0 in case of success, a negative AVERROR code on error
+ */
+int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx);
+
+/**
+ * Parse a channel layout or a corresponding integer representation.
+ *
+ * @param ret 64bit integer pointer to where the value should be written.
+ * @param arg string to parse
+ * @param log_ctx log context
+ * @return 0 in case of success, a negative AVERROR code on error
+ */
+int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx);
+
+void ff_update_link_current_pts(AVFilterLink *link, int64_t pts);
+
+void ff_free_pool(AVFilterPool *pool);
+
+void ff_command_queue_pop(AVFilterContext *filter);
+
+/* misc trace functions */
+
+/* #define FF_AVFILTER_TRACE */
+
+#ifdef FF_AVFILTER_TRACE
+#    define ff_tlog(pctx, ...) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__)
+#else
+#    define ff_tlog(pctx, ...) do { if (0) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__); } while (0)
+#endif
+
+#define FF_TPRINTF_START(ctx, func) ff_tlog(NULL, "%-16s: ", #func)
+
+char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms);
+
+void ff_tlog_ref(void *ctx, AVFilterBufferRef *ref, int end);
+
+void ff_tlog_link(void *ctx, AVFilterLink *link, int end);
 
 /**
  * Insert a new pad.
@@ -237,4 +345,28 @@
  */
 int ff_request_frame(AVFilterLink *link);
 
+#define AVFILTER_DEFINE_CLASS(fname)            \
+    static const AVClass fname##_class = {      \
+        .class_name = #fname,                   \
+        .item_name  = av_default_item_name,     \
+        .option     = fname##_options,          \
+        .version    = LIBAVUTIL_VERSION_INT,    \
+        .category   = AV_CLASS_CATEGORY_FILTER, \
+    }
+
+AVFilterBufferRef *ff_copy_buffer_ref(AVFilterLink *outlink,
+                                      AVFilterBufferRef *ref);
+
+/**
+ * Find the index of a link.
+ *
+ * I.e. find i such that link == ctx->(in|out)puts[i]
+ */
+#define FF_INLINK_IDX(link)  ((int)((link)->dstpad - (link)->dst->input_pads))
+#define FF_OUTLINK_IDX(link) ((int)((link)->srcpad - (link)->src->output_pads))
+
+int ff_buffersink_read_compat(AVFilterContext *ctx, AVFilterBufferRef **buf);
+int ff_buffersink_read_samples_compat(AVFilterContext *ctx, AVFilterBufferRef **pbuf,
+                                      int nb_samples);
+
 #endif /* AVFILTER_INTERNAL_H */
diff --git a/libavfilter/lavfutils.c b/libavfilter/lavfutils.c
new file mode 100644
index 0000000..a4711f9
--- /dev/null
+++ b/libavfilter/lavfutils.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2012 Stefano Sabatini <stefasab 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/imgutils.h"
+#include "lavfutils.h"
+
+int ff_load_image(uint8_t *data[4], int linesize[4],
+                  int *w, int *h, enum AVPixelFormat *pix_fmt,
+                  const char *filename, void *log_ctx)
+{
+    AVInputFormat *iformat = NULL;
+    AVFormatContext *format_ctx = NULL;
+    AVCodec *codec;
+    AVCodecContext *codec_ctx;
+    AVFrame *frame;
+    int frame_decoded, ret = 0;
+    AVPacket pkt;
+
+    av_register_all();
+
+    iformat = av_find_input_format("image2");
+    if ((ret = avformat_open_input(&format_ctx, filename, iformat, NULL)) < 0) {
+        av_log(log_ctx, AV_LOG_ERROR,
+               "Failed to open input file '%s'\n", filename);
+        return ret;
+    }
+
+    codec_ctx = format_ctx->streams[0]->codec;
+    codec = avcodec_find_decoder(codec_ctx->codec_id);
+    if (!codec) {
+        av_log(log_ctx, AV_LOG_ERROR, "Failed to find codec\n");
+        ret = AVERROR(EINVAL);
+        goto end;
+    }
+
+    if ((ret = avcodec_open2(codec_ctx, codec, NULL)) < 0) {
+        av_log(log_ctx, AV_LOG_ERROR, "Failed to open codec\n");
+        goto end;
+    }
+
+    if (!(frame = avcodec_alloc_frame()) ) {
+        av_log(log_ctx, AV_LOG_ERROR, "Failed to alloc frame\n");
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+
+    ret = av_read_frame(format_ctx, &pkt);
+    if (ret < 0) {
+        av_log(log_ctx, AV_LOG_ERROR, "Failed to read frame from file\n");
+        goto end;
+    }
+
+    ret = avcodec_decode_video2(codec_ctx, frame, &frame_decoded, &pkt);
+    if (ret < 0 || !frame_decoded) {
+        av_log(log_ctx, AV_LOG_ERROR, "Failed to decode image from file\n");
+        goto end;
+    }
+    ret = 0;
+
+    *w       = frame->width;
+    *h       = frame->height;
+    *pix_fmt = frame->format;
+
+    if ((ret = av_image_alloc(data, linesize, *w, *h, *pix_fmt, 16)) < 0)
+        goto end;
+    ret = 0;
+
+    av_image_copy(data, linesize, (const uint8_t **)frame->data, frame->linesize, *pix_fmt, *w, *h);
+
+end:
+    if (codec_ctx)
+        avcodec_close(codec_ctx);
+    if (format_ctx)
+        avformat_close_input(&format_ctx);
+    av_freep(&frame);
+
+    if (ret < 0)
+        av_log(log_ctx, AV_LOG_ERROR, "Error loading image file '%s'\n", filename);
+    return ret;
+}
diff --git a/libavfilter/lavfutils.h b/libavfilter/lavfutils.h
new file mode 100644
index 0000000..a310e83
--- /dev/null
+++ b/libavfilter/lavfutils.h
@@ -0,0 +1,43 @@
+/*
+ * 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
+ * Miscellaneous utilities which make use of the libavformat library
+ */
+
+#ifndef AVFILTER_LAVFUTILS_H
+#define AVFILTER_LAVFUTILS_H
+
+#include "libavformat/avformat.h"
+
+/**
+ * Load image from filename and put the resulting image in data.
+ *
+ * @param w pointer to the width of the loaded image
+ * @param h pointer to the height of the loaded image
+ * @param pix_fmt pointer to the pixel format of the loaded image
+ * @param filename the name of the image file to load
+ * @param log_ctx log context
+ * @return 0 in case of success, a negative error code otherwise.
+ */
+int ff_load_image(uint8_t *data[4], int linesize[4],
+                  int *w, int *h, enum AVPixelFormat *pix_fmt,
+                  const char *filename, void *log_ctx);
+
+#endif  /* AVFILTER_LAVFUTILS_H */
diff --git a/libavfilter/libavfilter.v b/libavfilter/libavfilter.v
index 83e8887..a3d33a3 100644
--- a/libavfilter/libavfilter.v
+++ b/libavfilter/libavfilter.v
@@ -1,4 +1,5 @@
 LIBAVFILTER_$MAJOR {
         global: avfilter_*; av_*;
+            ff_default_query_formats;
         local: *;
 };
diff --git a/libavfilter/libmpcodecs/cpudetect.h b/libavfilter/libmpcodecs/cpudetect.h
new file mode 100644
index 0000000..0f433e7
--- /dev/null
+++ b/libavfilter/libmpcodecs/cpudetect.h
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+#ifndef MPLAYER_CPUDETECT_H
+#define MPLAYER_CPUDETECT_H
+
+//#include "config.h"
+
+#define CPUTYPE_I386    3
+#define CPUTYPE_I486    4
+#define CPUTYPE_I586    5
+#define CPUTYPE_I686    6
+
+#include "libavutil/x86_cpu.h"
+
+typedef struct cpucaps_s {
+    int cpuType;
+    int cpuModel;
+    int cpuStepping;
+    int hasMMX;
+    int hasMMX2;
+    int has3DNow;
+    int has3DNowExt;
+    int hasSSE;
+    int hasSSE2;
+    int hasSSE3;
+    int hasSSSE3;
+    int hasSSE4a;
+    int isX86;
+    unsigned cl_size; /* size of cache line */
+    int hasAltiVec;
+    int hasTSC;
+} CpuCaps;
+
+extern CpuCaps gCpuCaps;
+
+void do_cpuid(unsigned int ax, unsigned int *p);
+
+void GetCpuCaps(CpuCaps *caps);
+
+/* returned value is malloc()'ed so free() it after use */
+char *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
new file mode 100644
index 0000000..87b828d
--- /dev/null
+++ b/libavfilter/libmpcodecs/help_mp.h
@@ -0,0 +1,2136 @@
+/* WARNING! This is a generated file, do NOT edit.
+ * See the help/ subdirectory for the editable files. */
+
+#ifndef MPLAYER_HELP_MP_H
+#define MPLAYER_HELP_MP_H
+
+// $Revision: 32397 $
+// MASTER FILE. Use this file as base for translations.
+// Translated files should be sent to the mplayer-DOCS mailing list or
+// to the help messages maintainer, see DOCS/tech/MAINTAINERS.
+// The header of the translated file should contain credits and contact
+// information. Before major releases we will notify all translators to update
+// their files. Please do not simply translate and forget this, outdated
+// translations quickly become worthless. To help us spot outdated files put a
+// note like "sync'ed with help_mp-en.h XXX" in the header of the translation.
+// Do NOT translate the above lines, just follow the instructions.
+
+
+// ========================= MPlayer help ===========================
+
+static const char help_text[]=
+"Usage:   mplayer [options] [url|path/]filename\n"
+"\n"
+"Basic options: (complete list in the man page)\n"
+" -vo <drv>        select video output driver ('-vo help' for a list)\n"
+" -ao <drv>        select audio output driver ('-ao help' for a list)\n"
+#ifdef CONFIG_VCD
+" vcd://<trackno>  play (S)VCD (Super Video CD) track (raw device, no mount)\n"
+#endif
+#ifdef CONFIG_DVDREAD
+" dvd://<titleno>  play DVD title from device instead of plain file\n"
+#endif
+" -alang/-slang    select DVD audio/subtitle language (by 2-char country code)\n"
+" -ss <position>   seek to given (seconds or hh:mm:ss) position\n"
+" -nosound         do not play sound\n"
+" -fs              fullscreen playback (or -vm, -zoom, details in the man page)\n"
+" -x <x> -y <y>    set display resolution (for use with -vm or -zoom)\n"
+" -sub <file>      specify subtitle file to use (also see -subfps, -subdelay)\n"
+" -playlist <file> specify playlist file\n"
+" -vid x -aid y    select video (x) and audio (y) stream to play\n"
+" -fps x -srate y  change video (x fps) and audio (y Hz) rate\n"
+" -pp <quality>    enable postprocessing filter (details in the man page)\n"
+" -framedrop       enable frame dropping (for slow machines)\n"
+"\n"
+"Basic keys: (complete list in the man page, also check input.conf)\n"
+" <-  or  ->       seek backward/forward 10 seconds\n"
+" down or up       seek backward/forward  1 minute\n"
+" pgdown or pgup   seek backward/forward 10 minutes\n"
+" < or >           step backward/forward in playlist\n"
+" p or SPACE       pause movie (press any key to continue)\n"
+" q or ESC         stop playing and quit program\n"
+" + or -           adjust audio delay by +/- 0.1 second\n"
+" o                cycle OSD mode:  none / seekbar / seekbar + timer\n"
+" * or /           increase or decrease PCM volume\n"
+" x or z           adjust subtitle delay by +/- 0.1 second\n"
+" r or t           adjust subtitle position up/down, also see -vf expand\n"
+"\n"
+" * * * SEE THE MAN PAGE FOR DETAILS, FURTHER (ADVANCED) OPTIONS AND KEYS * * *\n"
+"\n";
+
+// ========================= MPlayer messages ===========================
+
+// mplayer.c
+#define MSGTR_Exiting "\nExiting...\n"
+#define MSGTR_ExitingHow "\nExiting... (%s)\n"
+#define MSGTR_Exit_quit "Quit"
+#define MSGTR_Exit_eof "End of file"
+#define MSGTR_Exit_error "Fatal error"
+#define MSGTR_IntBySignal "\nMPlayer interrupted by signal %d in module: %s\n"
+#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_DumpSelectedStreamMissing "dump: FATAL: Selected stream missing!\n"
+#define MSGTR_CantOpenDumpfile "Cannot open dump file.\n"
+#define MSGTR_CoreDumped "Core dumped ;)\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"
+#define MSGTR_TryForceVideoFmtStr "Trying to force video codec driver family %s...\n"
+#define MSGTR_CantFindVideoCodec "Cannot find codec matching selected -vo and video format 0x%X.\n"
+#define MSGTR_CannotInitVO "FATAL: Cannot initialize video driver.\n"
+#define MSGTR_CannotInitAO "Could not open/initialize audio device -> no sound.\n"
+#define MSGTR_StartPlaying "Starting playback...\n"
+
+#define MSGTR_SystemTooSlow "\n\n"\
+"           ************************************************\n"\
+"           **** Your system is too SLOW to play this!  ****\n"\
+"           ************************************************\n\n"\
+"Possible reasons, problems, workarounds:\n"\
+"- Most common: broken/buggy _audio_ driver\n"\
+"  - Try -ao sdl or use the OSS emulation of ALSA.\n"\
+"  - Experiment with different values for -autosync, 30 is a good start.\n"\
+"- Slow video output\n"\
+"  - Try a different -vo driver (-vo help for a list) or try -framedrop!\n"\
+"- Slow CPU\n"\
+"  - Don't try to play a big DVD/DivX on a slow CPU! Try some of the lavdopts,\n"\
+"    e.g. -vfm ffmpeg -lavdopts lowres=1:fast:skiploopfilter=all.\n"\
+"- Broken file\n"\
+"  - Try various combinations of -nobps -ni -forceidx -mc 0.\n"\
+"- Slow media (NFS/SMB mounts, DVD, VCD etc)\n"\
+"  - Try -cache 8192.\n"\
+"- Are you using -cache to play a non-interleaved AVI file?\n"\
+"  - Try -nocache.\n"\
+"Read DOCS/HTML/en/video.html for tuning/speedup tips.\n"\
+"If none of this helps you, read DOCS/HTML/en/bugreports.html.\n\n"
+
+#define MSGTR_NoGui "MPlayer was compiled WITHOUT GUI support.\n"
+#define MSGTR_GuiNeedsX "MPlayer GUI requires X11.\n"
+#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"
+#define MSGTR_AvailableVideoCodecs "Available video codecs:\n"
+#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"
+#define MSGTR_ForcedVideoCodec "Forced video codec: %s\n"
+#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_PlaylistLoadUnable "\nUnable to load playlist %s.\n"
+#define MSGTR_Exit_SIGILL_RTCpuSel \
+"- MPlayer crashed by an 'Illegal Instruction'.\n"\
+"  It may be a bug in our new runtime CPU-detection code...\n"\
+"  Please read DOCS/HTML/en/bugreports.html.\n"
+#define MSGTR_Exit_SIGILL \
+"- MPlayer crashed by an 'Illegal Instruction'.\n"\
+"  It usually happens when you run it on a CPU different than the one it was\n"\
+"  compiled/optimized for.\n"\
+"  Verify this!\n"
+#define MSGTR_Exit_SIGSEGV_SIGFPE \
+"- MPlayer crashed by bad usage of CPU/FPU/RAM.\n"\
+"  Recompile MPlayer with --enable-debug and make a 'gdb' backtrace and\n"\
+"  disassembly. Details in DOCS/HTML/en/bugreports_what.html#bugreports_crash.\n"
+#define MSGTR_Exit_SIGCRASH \
+"- MPlayer crashed. This shouldn't happen.\n"\
+"  It can be a bug in the MPlayer code _or_ in your drivers _or_ in your\n"\
+"  gcc version. If you think it's MPlayer's fault, please read\n"\
+"  DOCS/HTML/en/bugreports.html and follow the instructions there. We can't and\n"\
+"  won't help unless you provide this information when reporting a possible bug.\n"
+#define MSGTR_LoadingConfig "Loading config '%s'\n"
+#define MSGTR_LoadingProtocolProfile "Loading protocol-related profile '%s'\n"
+#define MSGTR_LoadingExtensionProfile "Loading extension-related profile '%s'\n"
+#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"
+#define MSGTR_AudioFilterChainPreinitError "Error at audio filter chain pre-init!\n"
+#define MSGTR_LinuxRTCReadError "Linux RTC read error: %s\n"
+#define MSGTR_SoftsleepUnderflow "Warning! Softsleep underflow!\n"
+#define MSGTR_DvdnavNullEvent "DVDNAV Event NULL?!\n"
+#define MSGTR_DvdnavHighlightEventBroken "DVDNAV Event: Highlight event broken\n"
+#define MSGTR_DvdnavEvent "DVDNAV Event: %s\n"
+#define MSGTR_DvdnavHighlightHide "DVDNAV Event: Highlight Hide\n"
+#define MSGTR_DvdnavStillFrame "######################################## DVDNAV Event: Still Frame: %d sec(s)\n"
+#define MSGTR_DvdnavNavStop "DVDNAV Event: Nav Stop\n"
+#define MSGTR_DvdnavNavNOP "DVDNAV Event: Nav NOP\n"
+#define MSGTR_DvdnavNavSpuStreamChangeVerbose "DVDNAV Event: Nav SPU Stream Change: phys: %d/%d/%d logical: %d\n"
+#define MSGTR_DvdnavNavSpuStreamChange "DVDNAV Event: Nav SPU Stream Change: phys: %d logical: %d\n"
+#define MSGTR_DvdnavNavAudioStreamChange "DVDNAV Event: Nav Audio Stream Change: phys: %d logical: %d\n"
+#define MSGTR_DvdnavNavVTSChange "DVDNAV Event: Nav VTS Change\n"
+#define MSGTR_DvdnavNavCellChange "DVDNAV Event: Nav Cell Change\n"
+#define MSGTR_DvdnavNavSpuClutChange "DVDNAV Event: Nav SPU CLUT Change\n"
+#define MSGTR_DvdnavNavSeekDone "DVDNAV Event: Nav Seek Done\n"
+#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"
+
+// --- edit decision lists
+#define MSGTR_EdlOutOfMem "Can't allocate enough memory to hold EDL data.\n"
+#define MSGTR_EdlOutOfMemFile "Can't allocate enough memory to hold EDL file name [%s].\n"
+#define MSGTR_EdlRecordsNo "Read %d EDL actions.\n"
+#define MSGTR_EdlQueueEmpty "There are no EDL actions to take care of.\n"
+#define MSGTR_EdlCantOpenForWrite "Can't open EDL file [%s] for writing.\n"
+#define MSGTR_EdlCantOpenForRead "Can't open EDL file [%s] for reading.\n"
+#define MSGTR_EdlNOsh_video "Cannot use EDL without video, disabling.\n"
+#define MSGTR_EdlNOValidLine "Invalid EDL line: %s\n"
+#define MSGTR_EdlBadlyFormattedLine "Badly formatted EDL line [%d], discarding.\n"
+#define MSGTR_EdlBadLineOverlap "Last stop position was [%f]; next start is [%f].\n"\
+"Entries must be in chronological order, cannot overlap. Discarding.\n"
+#define MSGTR_EdlBadLineBadStop "Stop time has to be after start time.\n"
+#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"
+#define MSGTR_OSDdisabled "disabled"
+#define MSGTR_OSDAudio "Audio: %s"
+#define MSGTR_OSDVideo "Video: %s"
+#define MSGTR_OSDChannel "Channel: %s"
+#define MSGTR_OSDSubDelay "Sub delay: %d ms"
+#define MSGTR_OSDSpeed "Speed: x %6.2f"
+#define MSGTR_OSDosd "OSD: %s"
+#define MSGTR_OSDChapter "Chapter: (%d) %s"
+#define MSGTR_OSDAngle "Angle: %d/%d"
+#define MSGTR_OSDDeinterlace "Deinterlace: %s"
+
+// property values
+#define MSGTR_Enabled "enabled"
+#define MSGTR_EnabledEdl "enabled (EDL)"
+#define MSGTR_Disabled "disabled"
+#define MSGTR_HardFrameDrop "hard"
+#define MSGTR_Unknown "unknown"
+#define MSGTR_Bottom "bottom"
+#define MSGTR_Center "center"
+#define MSGTR_Top "top"
+#define MSGTR_SubSourceFile "file"
+#define MSGTR_SubSourceVobsub "vobsub"
+#define MSGTR_SubSourceDemux "embedded"
+
+// OSD bar names
+#define MSGTR_Volume "Volume"
+#define MSGTR_Panscan "Panscan"
+#define MSGTR_Gamma "Gamma"
+#define MSGTR_Brightness "Brightness"
+#define MSGTR_Contrast "Contrast"
+#define MSGTR_Saturation "Saturation"
+#define MSGTR_Hue "Hue"
+#define MSGTR_Balance "Balance"
+
+// property state
+#define MSGTR_LoopStatus "Loop: %s"
+#define MSGTR_MuteStatus "Mute: %s"
+#define MSGTR_AVDelayStatus "A-V delay: %s"
+#define MSGTR_OnTopStatus "Stay on top: %s"
+#define MSGTR_RootwinStatus "Rootwin: %s"
+#define MSGTR_BorderStatus "Border: %s"
+#define MSGTR_FramedroppingStatus "Framedropping: %s"
+#define MSGTR_VSyncStatus "VSync: %s"
+#define MSGTR_SubSelectStatus "Subtitles: %s"
+#define MSGTR_SubSourceStatus "Sub source: %s"
+#define MSGTR_SubPosStatus "Sub position: %s/100"
+#define MSGTR_SubAlignStatus "Sub alignment: %s"
+#define MSGTR_SubDelayStatus "Sub delay: %s"
+#define MSGTR_SubScale "Sub Scale: %s"
+#define MSGTR_SubVisibleStatus "Subtitles: %s"
+#define MSGTR_SubForcedOnlyStatus "Forced sub only: %s"
+
+// mencoder.c
+#define MSGTR_UsingPass3ControlFile "Using pass3 control file: %s\n"
+#define MSGTR_MissingFilename "\nFilename missing.\n\n"
+#define MSGTR_CannotOpenFile_Device "Cannot open file/device.\n"
+#define MSGTR_CannotOpenDemuxer "Cannot open demuxer.\n"
+#define MSGTR_NoAudioEncoderSelected "\nNo audio encoder (-oac) selected. Select one (see -oac help) or use -nosound.\n"
+#define MSGTR_NoVideoEncoderSelected "\nNo video encoder (-ovc) selected. Select one (see -ovc help).\n"
+#define MSGTR_CannotOpenOutputFile "Cannot open output file '%s'.\n"
+#define MSGTR_EncoderOpenFailed "Failed to open the encoder.\n"
+#define MSGTR_MencoderWrongFormatAVI "\nWARNING: OUTPUT FILE FORMAT IS _AVI_. See -of help.\n"
+#define MSGTR_MencoderWrongFormatMPG "\nWARNING: OUTPUT FILE FORMAT IS _MPEG_. See -of help.\n"
+#define MSGTR_MissingOutputFilename "No output file specified, please see the -o option."
+#define MSGTR_ForcingOutputFourcc "Forcing output FourCC to %x [%.4s].\n"
+#define MSGTR_ForcingOutputAudiofmtTag "Forcing output audio format tag to 0x%x.\n"
+#define MSGTR_DuplicateFrames "\n%d duplicate frame(s)!\n"
+#define MSGTR_SkipFrame "\nSkipping frame!\n"
+#define MSGTR_ResolutionDoesntMatch "\nNew video file has different resolution or colorspace than the previous one.\n"
+#define MSGTR_FrameCopyFileMismatch "\nAll video files must have identical fps, resolution, and codec for -ovc copy.\n"
+#define MSGTR_AudioCopyFileMismatch "\nAll files must have identical audio codec and format for -oac copy.\n"
+#define MSGTR_NoAudioFileMismatch "\nCannot mix video-only files with audio and video files. Try -nosound.\n"
+#define MSGTR_NoSpeedWithFrameCopy "WARNING: -speed is not guaranteed to work correctly with -oac copy!\n"\
+"Your encode might be broken!\n"
+#define MSGTR_ErrorWritingFile "%s: Error writing file.\n"
+#define MSGTR_FlushingVideoFrames "\nFlushing video frames.\n"
+#define MSGTR_FiltersHaveNotBeenConfiguredEmptyFile "Filters have not been configured! Empty file?\n"
+#define MSGTR_RecommendedVideoBitrate "Recommended video bitrate for %s CD: %d\n"
+#define MSGTR_VideoStreamResult "\nVideo stream: %8.3f kbit/s  (%d B/s)  size: %"PRIu64" bytes  %5.3f secs  %d frames\n"
+#define MSGTR_AudioStreamResult "\nAudio stream: %8.3f kbit/s  (%d B/s)  size: %"PRIu64" bytes  %5.3f secs\n"
+#define MSGTR_EdlSkipStartEndCurrent "EDL SKIP: Start: %.2f  End: %.2f   Current: V: %.2f  A: %.2f     \r"
+#define MSGTR_OpenedStream "success: format: %d  data: 0x%X - 0x%x\n"
+#define MSGTR_VCodecFramecopy "videocodec: framecopy (%dx%d %dbpp fourcc=%x)\n"
+#define MSGTR_ACodecFramecopy "audiocodec: framecopy (format=%x chans=%d rate=%d bits=%d B/s=%d sample-%d)\n"
+#define MSGTR_CBRPCMAudioSelected "CBR PCM audio selected.\n"
+#define MSGTR_MP3AudioSelected "MP3 audio selected.\n"
+#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"\
+"When using this mode you must enter a value between \"8\" and \"320\".\n"\
+"\n"\
+"For further information try: \"-lameopts preset=help\"\n"
+#define MSGTR_InvalidLamePresetOptions "Error: You did not enter a valid profile and/or options with preset.\n"\
+"\n"\
+"Available profiles are:\n"\
+"\n"\
+"   <fast>        standard\n"\
+"   <fast>        extreme\n"\
+"                 insane\n"\
+"   <cbr> (ABR Mode) - The ABR Mode is implied. To use it,\n"\
+"                      simply specify a bitrate. For example:\n"\
+"                      \"preset=185\" activates this\n"\
+"                      preset and uses 185 as an average kbps.\n"\
+"\n"\
+"    Some examples:\n"\
+"\n"\
+"    \"-lameopts fast:preset=standard  \"\n"\
+" or \"-lameopts  cbr:preset=192       \"\n"\
+" or \"-lameopts      preset=172       \"\n"\
+" or \"-lameopts      preset=extreme   \"\n"\
+"\n"\
+"For further information try: \"-lameopts preset=help\"\n"
+#define MSGTR_LamePresetsLongInfo "\n"\
+"The preset switches are designed to provide the highest possible quality.\n"\
+"\n"\
+"They have for the most part been subjected to and tuned via rigorous double\n"\
+"blind listening tests to verify and achieve this objective.\n"\
+"\n"\
+"These are continually updated to coincide with the latest developments that\n"\
+"occur and as a result should provide you with nearly the best quality\n"\
+"currently possible from LAME.\n"\
+"\n"\
+"To activate these presets:\n"\
+"\n"\
+"   For VBR modes (generally highest quality):\n"\
+"\n"\
+"     \"preset=standard\" This preset should generally be transparent\n"\
+"                             to most people on most music and is already\n"\
+"                             quite high in quality.\n"\
+"\n"\
+"     \"preset=extreme\" If you have extremely good hearing and similar\n"\
+"                             equipment, this preset will generally provide\n"\
+"                             slightly higher quality than the \"standard\"\n"\
+"                             mode.\n"\
+"\n"\
+"   For CBR 320kbps (highest quality possible from the preset switches):\n"\
+"\n"\
+"     \"preset=insane\"  This preset will usually be overkill for most\n"\
+"                             people and most situations, but if you must\n"\
+"                             have the absolute highest quality with no\n"\
+"                             regard to filesize, this is the way to go.\n"\
+"\n"\
+"   For ABR modes (high quality per given bitrate but not as high as VBR):\n"\
+"\n"\
+"     \"preset=<kbps>\"  Using this preset will usually give you good\n"\
+"                             quality at a specified bitrate. Depending on the\n"\
+"                             bitrate entered, this preset will determine the\n"\
+"                             optimal settings for that particular situation.\n"\
+"                             While this approach works, it is not nearly as\n"\
+"                             flexible as VBR, and usually will not attain the\n"\
+"                             same level of quality as VBR at higher bitrates.\n"\
+"\n"\
+"The following options are also available for the corresponding profiles:\n"\
+"\n"\
+"   <fast>        standard\n"\
+"   <fast>        extreme\n"\
+"                 insane\n"\
+"   <cbr> (ABR Mode) - The ABR Mode is implied. To use it,\n"\
+"                      simply specify a bitrate. For example:\n"\
+"                      \"preset=185\" activates this\n"\
+"                      preset and uses 185 as an average kbps.\n"\
+"\n"\
+"   \"fast\" - Enables the new fast VBR for a particular profile. The\n"\
+"            disadvantage to the speed switch is that often times the\n"\
+"            bitrate will be slightly higher than with the normal mode\n"\
+"            and quality may be slightly lower also.\n"\
+"   Warning: with the current version fast presets might result in too\n"\
+"            high bitrate compared to regular presets.\n"\
+"\n"\
+"   \"cbr\"  - If you use the ABR mode (read above) with a significant\n"\
+"            bitrate such as 80, 96, 112, 128, 160, 192, 224, 256, 320,\n"\
+"            you can use the \"cbr\" option to force CBR mode encoding\n"\
+"            instead of the standard abr mode. ABR does provide higher\n"\
+"            quality but CBR may be useful in situations such as when\n"\
+"            streaming an MP3 over the internet may be important.\n"\
+"\n"\
+"    For example:\n"\
+"\n"\
+"    \"-lameopts fast:preset=standard  \"\n"\
+" or \"-lameopts  cbr:preset=192       \"\n"\
+" or \"-lameopts      preset=172       \"\n"\
+" or \"-lameopts      preset=extreme   \"\n"\
+"\n"\
+"\n"\
+"A few aliases are available for ABR mode:\n"\
+"phone => 16kbps/mono        phon+/lw/mw-eu/sw => 24kbps/mono\n"\
+"mw-us => 40kbps/mono        voice => 56kbps/mono\n"\
+"fm/radio/tape => 112kbps    hifi => 160kbps\n"\
+"cd => 192kbps               studio => 256kbps"
+#define MSGTR_LameCantInit \
+"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_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"
+#define MSGTR_RawvideoDoesNotSupportAudio "Output file format RAWVIDEO does not support audio - disabling audio.\n"
+#define MSGTR_DemuxerDoesntSupportNosound "This demuxer doesn't support -nosound yet.\n"
+#define MSGTR_MemAllocFailed "Memory allocation failed.\n"
+#define MSGTR_NoMatchingFilter "Couldn't find matching filter/ao format!\n"
+#define MSGTR_MP3WaveFormatSizeNot30 "sizeof(MPEGLAYER3WAVEFORMAT)==%d!=30, maybe broken C compiler?\n"
+#define MSGTR_NoLavcAudioCodecName "Audio LAVC, Missing codec name!\n"
+#define MSGTR_LavcAudioCodecNotFound "Audio LAVC, couldn't find encoder for codec %s.\n"
+#define MSGTR_CouldntAllocateLavcContext "Audio LAVC, couldn't allocate context!\n"
+#define MSGTR_CouldntOpenCodec "Couldn't open codec %s, br=%d.\n"
+#define MSGTR_CantCopyAudioFormat "Audio format 0x%x is incompatible with '-oac copy', please try '-oac pcm' instead or use '-fafmttag' to override it.\n"
+
+// cfg-mencoder.h
+#define MSGTR_MEncoderMP3LameHelp "\n\n"\
+" vbr=<0-4>     variable bitrate method\n"\
+"                0: cbr (constant bitrate)\n"\
+"                1: mt (Mark Taylor VBR algorithm)\n"\
+"                2: rh (Robert Hegemann VBR algorithm - default)\n"\
+"                3: abr (average bitrate)\n"\
+"                4: mtrh (Mark Taylor Robert Hegemann VBR algorithm)\n"\
+"\n"\
+" abr           average bitrate\n"\
+"\n"\
+" cbr           constant bitrate\n"\
+"               Also forces CBR mode encoding on subsequent ABR presets modes.\n"\
+"\n"\
+" br=<0-1024>   specify bitrate in kBit (CBR and ABR only)\n"\
+"\n"\
+" q=<0-9>       quality (0-highest, 9-lowest) (only for VBR)\n"\
+"\n"\
+" aq=<0-9>      algorithmic quality (0-best/slowest, 9-worst/fastest)\n"\
+"\n"\
+" ratio=<1-100> compression ratio\n"\
+"\n"\
+" vol=<0-10>    set audio input gain\n"\
+"\n"\
+" mode=<0-3>    (default: auto)\n"\
+"                0: stereo\n"\
+"                1: joint-stereo\n"\
+"                2: dualchannel\n"\
+"                3: mono\n"\
+"\n"\
+" padding=<0-2>\n"\
+"                0: no\n"\
+"                1: all\n"\
+"                2: adjust\n"\
+"\n"\
+" fast          Switch on faster encoding on subsequent VBR presets modes,\n"\
+"               slightly lower quality and higher bitrates.\n"\
+"\n"\
+" preset=<value> Provide the highest possible quality settings.\n"\
+"                 medium: VBR  encoding,  good  quality\n"\
+"                 (150-180 kbps bitrate range)\n"\
+"                 standard:  VBR encoding, high quality\n"\
+"                 (170-210 kbps bitrate range)\n"\
+"                 extreme: VBR encoding, very high quality\n"\
+"                 (200-240 kbps bitrate range)\n"\
+"                 insane:  CBR  encoding, highest preset quality\n"\
+"                 (320 kbps bitrate)\n"\
+"                 <8-320>: ABR encoding at average given kbps bitrate.\n\n"
+
+// codec-cfg.c
+#define MSGTR_DuplicateFourcc "duplicated FourCC"
+#define MSGTR_TooManyFourccs "too many FourCCs/formats..."
+#define MSGTR_ParseError "parse error"
+#define MSGTR_ParseErrorFIDNotNumber "parse error (format ID not a number?)"
+#define MSGTR_ParseErrorFIDAliasNotNumber "parse error (format ID alias not a number?)"
+#define MSGTR_DuplicateFID "duplicated format ID"
+#define MSGTR_TooManyOut "too many out..."
+#define MSGTR_InvalidCodecName "\ncodec(%s) name is not valid!\n"
+#define MSGTR_CodecLacksFourcc "\ncodec(%s) does not have FourCC/format!\n"
+#define MSGTR_CodecLacksDriver "\ncodec(%s) does not have a driver!\n"
+#define MSGTR_CodecNeedsDLL "\ncodec(%s) needs a 'dll'!\n"
+#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."
+#define MSGTR_CantStrdupName "Can't strdup -> 'name': %s\n"
+#define MSGTR_CantStrdupInfo "Can't strdup -> 'info': %s\n"
+#define MSGTR_CantStrdupDriver "Can't strdup -> 'driver': %s\n"
+#define MSGTR_CantStrdupDLL "Can't strdup -> 'dll': %s"
+#define MSGTR_AudioVideoCodecTotals "%d audio & %d video codecs\n"
+#define MSGTR_CodecDefinitionIncorrect "Codec is not defined correctly."
+#define MSGTR_OutdatedCodecsConf "This codecs.conf is too old and incompatible with this MPlayer release!"
+
+// fifo.c
+#define MSGTR_CannotMakePipe "Cannot make PIPE!\n"
+
+// parser-mecmd.c, parser-mpcmd.c
+#define MSGTR_NoFileGivenOnCommandLine "'--' indicates no more options, but no filename was given on the command line.\n"
+#define MSGTR_TheLoopOptionMustBeAnInteger "The loop option must be an integer: %s\n"
+#define MSGTR_UnknownOptionOnCommandLine "Unknown option on the command line: -%s\n"
+#define MSGTR_ErrorParsingOptionOnCommandLine "Error parsing option on the command line: -%s\n"
+#define MSGTR_InvalidPlayEntry "Invalid play entry %s\n"
+#define MSGTR_NotAnMEncoderOption "-%s is not an MEncoder option\n"
+#define MSGTR_NoFileGiven "No file given\n"
+
+// m_config.c
+#define MSGTR_SaveSlotTooOld "Save slot found from lvl %d is too old: %d !!!\n"
+#define MSGTR_InvalidCfgfileOption "The %s option can't be used in a config file.\n"
+#define MSGTR_InvalidCmdlineOption "The %s option can't be used on the command line.\n"
+#define MSGTR_InvalidSuboption "Error: option '%s' has no suboption '%s'.\n"
+#define MSGTR_MissingSuboptionParameter "Error: suboption '%s' of '%s' must have a parameter!\n"
+#define MSGTR_MissingOptionParameter "Error: option '%s' must have a parameter!\n"
+#define MSGTR_OptionListHeader "\n Name                 Type            Min        Max      Global  CL    Cfg\n\n"
+#define MSGTR_TotalOptions "\nTotal: %d options\n"
+#define MSGTR_ProfileInclusionTooDeep "WARNING: Profile inclusion too deep.\n"
+#define MSGTR_NoProfileDefined "No profiles have been defined.\n"
+#define MSGTR_AvailableProfiles "Available profiles:\n"
+#define MSGTR_UnknownProfile "Unknown profile '%s'.\n"
+#define MSGTR_Profile "Profile %s: %s\n"
+
+// m_property.c
+#define MSGTR_PropertyListHeader "\n Name                 Type            Min        Max\n\n"
+#define MSGTR_TotalProperties "\nTotal: %d properties\n"
+
+// loader/ldt_keeper.c
+#define MSGTR_LOADER_DYLD_Warning "WARNING: Attempting to use DLL codecs but environment variable\n         DYLD_BIND_AT_LAUNCH not set. This will likely crash.\n"
+
+
+// ====================== GUI messages/buttons ========================
+
+// --- labels ---
+#define MSGTR_About "About"
+#define MSGTR_FileSelect "Select file..."
+#define MSGTR_SubtitleSelect "Select subtitle..."
+#define MSGTR_OtherSelect "Select..."
+#define MSGTR_AudioFileSelect "Select external audio channel..."
+#define MSGTR_FontSelect "Select font..."
+// Note: If you change MSGTR_PlayList please see if it still fits MSGTR_MENU_PlayList
+#define MSGTR_PlayList "Playlist"
+#define MSGTR_Equalizer "Equalizer"
+#define MSGTR_ConfigureEqualizer "Configure Equalizer"
+#define MSGTR_SkinBrowser "Skin Browser"
+#define MSGTR_Network "Network streaming..."
+// Note: If you change MSGTR_Preferences please see if it still fits MSGTR_MENU_Preferences
+#define MSGTR_Preferences "Preferences"
+#define MSGTR_AudioPreferences "Audio driver configuration"
+#define MSGTR_NoMediaOpened "No media opened."
+#define MSGTR_VCDTrack "VCD track %d"
+#define MSGTR_NoChapter "No chapter"
+#define MSGTR_Chapter "Chapter %d"
+#define MSGTR_NoFileLoaded "No file loaded."
+
+// --- buttons ---
+#define MSGTR_Ok "OK"
+#define MSGTR_Cancel "Cancel"
+#define MSGTR_Add "Add"
+#define MSGTR_Remove "Remove"
+#define MSGTR_Clear "Clear"
+#define MSGTR_Config "Config"
+#define MSGTR_ConfigDriver "Configure driver"
+#define MSGTR_Browse "Browse"
+
+// --- error messages ---
+#define MSGTR_NEMDB "Sorry, not enough memory to draw buffer."
+#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_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 ..."
+
+// --- 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_FONT_TooManyFontsDeclared "Too many fonts declared.\n"
+#define MSGTR_SKIN_FONT_FontFileNotFound "Font 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_LABEL "Skins:"
+
+// --- GTK menus
+#define MSGTR_MENU_AboutMPlayer "About MPlayer"
+#define MSGTR_MENU_Open "Open..."
+#define MSGTR_MENU_PlayFile "Play file..."
+#define MSGTR_MENU_PlayVCD "Play VCD..."
+#define MSGTR_MENU_PlayDVD "Play DVD..."
+#define MSGTR_MENU_PlayURL "Play URL..."
+#define MSGTR_MENU_LoadSubtitle "Load subtitle..."
+#define MSGTR_MENU_DropSubtitle "Drop subtitle..."
+#define MSGTR_MENU_LoadExternAudioFile "Load external audio file..."
+#define MSGTR_MENU_Playing "Playing"
+#define MSGTR_MENU_Play "Play"
+#define MSGTR_MENU_Pause "Pause"
+#define MSGTR_MENU_Stop "Stop"
+#define MSGTR_MENU_NextStream "Next stream"
+#define MSGTR_MENU_PrevStream "Prev stream"
+#define MSGTR_MENU_Size "Size"
+#define MSGTR_MENU_HalfSize   "Half size"
+#define MSGTR_MENU_NormalSize "Normal size"
+#define MSGTR_MENU_DoubleSize "Double size"
+#define MSGTR_MENU_FullScreen "Fullscreen"
+#define MSGTR_MENU_DVD "DVD"
+#define MSGTR_MENU_VCD "VCD"
+#define MSGTR_MENU_PlayDisc "Open disc..."
+#define MSGTR_MENU_ShowDVDMenu "Show DVD menu"
+#define MSGTR_MENU_Titles "Titles"
+#define MSGTR_MENU_Title "Title %2d"
+#define MSGTR_MENU_None "(none)"
+#define MSGTR_MENU_Chapters "Chapters"
+#define MSGTR_MENU_Chapter "Chapter %2d"
+#define MSGTR_MENU_AudioLanguages "Audio languages"
+#define MSGTR_MENU_SubtitleLanguages "Subtitle languages"
+#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_Mute "Mute"
+#define MSGTR_MENU_Original "Original"
+#define MSGTR_MENU_AspectRatio "Aspect ratio"
+#define MSGTR_MENU_AudioTrack "Audio track"
+#define MSGTR_MENU_Track "Track %d"
+#define MSGTR_MENU_VideoTrack "Video track"
+#define MSGTR_MENU_Subtitles "Subtitles"
+
+// --- equalizer
+// Note: If you change MSGTR_EQU_Audio please see if it still fits MSGTR_PREFERENCES_Audio
+#define MSGTR_EQU_Audio "Audio"
+// Note: If you change MSGTR_EQU_Video please see if it still fits MSGTR_PREFERENCES_Video
+#define MSGTR_EQU_Video "Video"
+#define MSGTR_EQU_Contrast "Contrast: "
+#define MSGTR_EQU_Brightness "Brightness: "
+#define MSGTR_EQU_Hue "Hue: "
+#define MSGTR_EQU_Saturation "Saturation: "
+#define MSGTR_EQU_Front_Left "Front Left"
+#define MSGTR_EQU_Front_Right "Front Right"
+#define MSGTR_EQU_Back_Left "Rear Left"
+#define MSGTR_EQU_Back_Right "Rear Right"
+#define MSGTR_EQU_Center "Center"
+#define MSGTR_EQU_Bass "Bass"
+#define MSGTR_EQU_All "All"
+#define MSGTR_EQU_Channel1 "Channel 1:"
+#define MSGTR_EQU_Channel2 "Channel 2:"
+#define MSGTR_EQU_Channel3 "Channel 3:"
+#define MSGTR_EQU_Channel4 "Channel 4:"
+#define MSGTR_EQU_Channel5 "Channel 5:"
+#define MSGTR_EQU_Channel6 "Channel 6:"
+
+// --- playlist
+#define MSGTR_PLAYLIST_Path "Path"
+#define MSGTR_PLAYLIST_Selected "Selected files"
+#define MSGTR_PLAYLIST_Files "Files"
+#define MSGTR_PLAYLIST_DirectoryTree "Directory tree"
+
+// --- preferences
+#define MSGTR_PREFERENCES_Audio MSGTR_EQU_Audio
+#define MSGTR_PREFERENCES_Video MSGTR_EQU_Video
+#define MSGTR_PREFERENCES_SubtitleOSD "Subtitles & OSD"
+#define MSGTR_PREFERENCES_Codecs "Codecs & demuxer"
+// Note: If you change MSGTR_PREFERENCES_Misc see if it still fits MSGTR_PREFERENCES_FRAME_Misc
+#define MSGTR_PREFERENCES_Misc "Misc"
+#define MSGTR_PREFERENCES_None "None"
+#define MSGTR_PREFERENCES_DriverDefault "driver default"
+#define MSGTR_PREFERENCES_AvailableDrivers "Available drivers:"
+#define MSGTR_PREFERENCES_DoNotPlaySound "Do not play sound"
+#define MSGTR_PREFERENCES_NormalizeSound "Normalize sound"
+#define MSGTR_PREFERENCES_EnableEqualizer "Enable equalizer"
+#define MSGTR_PREFERENCES_SoftwareMixer "Enable Software Mixer"
+#define MSGTR_PREFERENCES_ExtraStereo "Enable extra stereo"
+#define MSGTR_PREFERENCES_Coefficient "Coefficient:"
+#define MSGTR_PREFERENCES_AudioDelay "Audio delay"
+#define MSGTR_PREFERENCES_DoubleBuffer "Enable double buffering"
+#define MSGTR_PREFERENCES_DirectRender "Enable direct rendering"
+#define MSGTR_PREFERENCES_FrameDrop "Enable frame dropping"
+#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_Subtitle "Subtitle:"
+#define MSGTR_PREFERENCES_SUB_Delay "Delay: "
+#define MSGTR_PREFERENCES_SUB_FPS "FPS:"
+#define MSGTR_PREFERENCES_SUB_POS "Position: "
+#define MSGTR_PREFERENCES_SUB_AutoLoad "Disable subtitle autoloading"
+#define MSGTR_PREFERENCES_SUB_Unicode "Unicode subtitle"
+#define MSGTR_PREFERENCES_SUB_MPSUB "Convert the given subtitle to MPlayer's subtitle format"
+#define MSGTR_PREFERENCES_SUB_SRT "Convert the given subtitle to the time based SubViewer (SRT) format"
+#define MSGTR_PREFERENCES_SUB_Overlap "Toggle subtitle overlapping"
+#define MSGTR_PREFERENCES_SUB_USE_ASS "SSA/ASS subtitle rendering"
+#define MSGTR_PREFERENCES_SUB_ASS_USE_MARGINS "Use margins"
+#define MSGTR_PREFERENCES_SUB_ASS_TOP_MARGIN "Top: "
+#define MSGTR_PREFERENCES_SUB_ASS_BOTTOM_MARGIN "Bottom: "
+#define MSGTR_PREFERENCES_Font "Font:"
+#define MSGTR_PREFERENCES_FontFactor "Font factor:"
+#define MSGTR_PREFERENCES_PostProcess "Enable postprocessing"
+#define MSGTR_PREFERENCES_AutoQuality "Auto quality: "
+#define MSGTR_PREFERENCES_NI "Use non-interleaved AVI parser"
+#define MSGTR_PREFERENCES_IDX "Rebuild index table, if needed"
+#define MSGTR_PREFERENCES_VideoCodecFamily "Video codec family:"
+#define MSGTR_PREFERENCES_AudioCodecFamily "Audio codec family:"
+#define MSGTR_PREFERENCES_FRAME_OSD_Level "OSD level"
+#define MSGTR_PREFERENCES_FRAME_Subtitle "Subtitle"
+#define MSGTR_PREFERENCES_FRAME_Font "Font"
+#define MSGTR_PREFERENCES_FRAME_PostProcess "Postprocessing"
+#define MSGTR_PREFERENCES_FRAME_CodecDemuxer "Codec & demuxer"
+#define MSGTR_PREFERENCES_FRAME_Cache "Cache"
+#define MSGTR_PREFERENCES_FRAME_Misc MSGTR_PREFERENCES_Misc
+#define MSGTR_PREFERENCES_Audio_Device "Device:"
+#define MSGTR_PREFERENCES_Audio_Mixer "Mixer:"
+#define MSGTR_PREFERENCES_Audio_MixerChannel "Mixer channel:"
+#define MSGTR_PREFERENCES_Message "Please remember that you need to restart playback for some options to take effect!"
+#define MSGTR_PREFERENCES_DXR3_VENC "Video encoder:"
+#define MSGTR_PREFERENCES_DXR3_LAVC "Use LAVC (FFmpeg)"
+#define MSGTR_PREFERENCES_FontEncoding1 "Unicode"
+#define MSGTR_PREFERENCES_FontEncoding2 "Western European Languages (ISO-8859-1)"
+#define MSGTR_PREFERENCES_FontEncoding3 "Western European Languages with Euro (ISO-8859-15)"
+#define MSGTR_PREFERENCES_FontEncoding4 "Slavic/Central European Languages (ISO-8859-2)"
+#define MSGTR_PREFERENCES_FontEncoding5 "Esperanto, Galician, Maltese, Turkish (ISO-8859-3)"
+#define MSGTR_PREFERENCES_FontEncoding6 "Old Baltic charset (ISO-8859-4)"
+#define MSGTR_PREFERENCES_FontEncoding7 "Cyrillic (ISO-8859-5)"
+#define MSGTR_PREFERENCES_FontEncoding8 "Arabic (ISO-8859-6)"
+#define MSGTR_PREFERENCES_FontEncoding9 "Modern Greek (ISO-8859-7)"
+#define MSGTR_PREFERENCES_FontEncoding10 "Turkish (ISO-8859-9)"
+#define MSGTR_PREFERENCES_FontEncoding11 "Baltic (ISO-8859-13)"
+#define MSGTR_PREFERENCES_FontEncoding12 "Celtic (ISO-8859-14)"
+#define MSGTR_PREFERENCES_FontEncoding13 "Hebrew charsets (ISO-8859-8)"
+#define MSGTR_PREFERENCES_FontEncoding14 "Russian (KOI8-R)"
+#define MSGTR_PREFERENCES_FontEncoding15 "Ukrainian, Belarusian (KOI8-U/RU)"
+#define MSGTR_PREFERENCES_FontEncoding16 "Simplified Chinese charset (CP936)"
+#define MSGTR_PREFERENCES_FontEncoding17 "Traditional Chinese charset (BIG5)"
+#define MSGTR_PREFERENCES_FontEncoding18 "Japanese charsets (SHIFT-JIS)"
+#define MSGTR_PREFERENCES_FontEncoding19 "Korean charset (CP949)"
+#define MSGTR_PREFERENCES_FontEncoding20 "Thai charset (CP874)"
+#define MSGTR_PREFERENCES_FontEncoding21 "Cyrillic Windows (CP1251)"
+#define MSGTR_PREFERENCES_FontEncoding22 "Slavic/Central European Windows (CP1250)"
+#define MSGTR_PREFERENCES_FontEncoding23 "Arabic Windows (CP1256)"
+#define MSGTR_PREFERENCES_FontNoAutoScale "No autoscale"
+#define MSGTR_PREFERENCES_FontPropWidth "Proportional to movie width"
+#define MSGTR_PREFERENCES_FontPropHeight "Proportional to movie height"
+#define MSGTR_PREFERENCES_FontPropDiagonal "Proportional to movie diagonal"
+#define MSGTR_PREFERENCES_FontEncoding "Encoding:"
+#define MSGTR_PREFERENCES_FontBlur "Blur:"
+#define MSGTR_PREFERENCES_FontOutLine "Outline:"
+#define MSGTR_PREFERENCES_FontTextScale "Text scale:"
+#define MSGTR_PREFERENCES_FontOSDScale "OSD scale:"
+#define MSGTR_PREFERENCES_Cache "Cache on/off"
+#define MSGTR_PREFERENCES_CacheSize "Cache size: "
+#define MSGTR_PREFERENCES_LoadFullscreen "Start in fullscreen"
+#define MSGTR_PREFERENCES_SaveWinPos "Save window position"
+#define MSGTR_PREFERENCES_XSCREENSAVER "Stop XScreenSaver"
+#define MSGTR_PREFERENCES_PlayBar "Enable playbar"
+#define MSGTR_PREFERENCES_AutoSync "AutoSync on/off"
+#define MSGTR_PREFERENCES_AutoSyncValue "Autosync: "
+#define MSGTR_PREFERENCES_CDROMDevice "CD-ROM device:"
+#define MSGTR_PREFERENCES_DVDDevice "DVD device:"
+#define MSGTR_PREFERENCES_FPS "Movie FPS:"
+#define MSGTR_PREFERENCES_ShowVideoWindow "Show video window when inactive"
+#define MSGTR_PREFERENCES_ArtsBroken "Newer aRts versions are incompatible "\
+           "with GTK 1.x and will crash GMPlayer!"
+
+// -- aboutbox
+#define MSGTR_ABOUT_UHU "GUI development sponsored by UHU Linux\n"
+#define MSGTR_ABOUT_Contributors "Code and documentation contributors\n"
+#define MSGTR_ABOUT_Codecs_libs_contributions "Codecs and third party libraries\n"
+#define MSGTR_ABOUT_Translations "Translations\n"
+#define MSGTR_ABOUT_Skins "Skins\n"
+
+// --- messagebox
+#define MSGTR_MSGBOX_LABEL_FatalError "Fatal error!"
+#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"
+
+// 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"
+
+// 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_DpmsUnavailable "DPMS not available?\n"
+#define MSGTR_WS_DpmsNotEnabled "Could not enable DPMS.\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"
+
+// ======================= video output drivers ========================
+
+#define MSGTR_VOincompCodec "The selected video_out device is incompatible with this codec.\n"\
+                "Try appending the scale filter to your filter list,\n"\
+                "e.g. -vf spp,scale instead of -vf spp.\n"
+#define MSGTR_VO_GenericError "This error has occurred"
+#define MSGTR_VO_UnableToAccess "Unable to access"
+#define MSGTR_VO_ExistsButNoDirectory "already exists, but is not a directory."
+#define MSGTR_VO_DirExistsButNotWritable "Output directory already exists, but is not writable."
+#define MSGTR_VO_DirExistsAndIsWritable "Output directory already exists and is writable."
+#define MSGTR_VO_CantCreateDirectory "Unable to create output directory."
+#define MSGTR_VO_CantCreateFile "Unable to create output file."
+#define MSGTR_VO_DirectoryCreateSuccess "Output directory successfully created."
+#define MSGTR_VO_ValueOutOfRange "value out of range"
+#define MSGTR_VO_NoValueSpecified "No value specified."
+#define MSGTR_VO_UnknownSuboptions "unknown suboption(s)"
+
+// aspect.c
+#define MSGTR_LIBVO_ASPECT_NoSuitableNewResFound "[ASPECT] Warning: No suitable new res found!\n"
+#define MSGTR_LIBVO_ASPECT_NoNewSizeFoundThatFitsIntoRes "[ASPECT] Error: No new size found that fits into res!\n"
+
+// font_load_ft.c
+#define MSGTR_LIBVO_FONT_LOAD_FT_NewFaceFailed "New_Face failed. Maybe the font path is wrong.\nPlease supply the text font file (~/.mplayer/subfont.ttf).\n"
+#define MSGTR_LIBVO_FONT_LOAD_FT_NewMemoryFaceFailed "New_Memory_Face failed..\n"
+#define MSGTR_LIBVO_FONT_LOAD_FT_SubFaceFailed "subtitle font: load_sub_face failed.\n"
+#define MSGTR_LIBVO_FONT_LOAD_FT_SubFontCharsetFailed "subtitle font: prepare_charset failed.\n"
+#define MSGTR_LIBVO_FONT_LOAD_FT_CannotPrepareSubtitleFont "Cannot prepare subtitle font.\n"
+#define MSGTR_LIBVO_FONT_LOAD_FT_CannotPrepareOSDFont "Cannot prepare OSD font.\n"
+#define MSGTR_LIBVO_FONT_LOAD_FT_CannotGenerateTables "Cannot generate tables.\n"
+#define MSGTR_LIBVO_FONT_LOAD_FT_DoneFreeTypeFailed "FT_Done_FreeType failed.\n"
+#define MSGTR_LIBVO_FONT_LOAD_FT_FontconfigNoMatch "Fontconfig failed to select a font. Trying without fontconfig...\n"
+
+// sub.c
+#define MSGTR_VO_SUB_Seekbar "Seekbar"
+#define MSGTR_VO_SUB_Play "Play"
+#define MSGTR_VO_SUB_Pause "Pause"
+#define MSGTR_VO_SUB_Stop "Stop"
+#define MSGTR_VO_SUB_Rewind "Rewind"
+#define MSGTR_VO_SUB_Forward "Forward"
+#define MSGTR_VO_SUB_Clock "Clock"
+#define MSGTR_VO_SUB_Contrast "Contrast"
+#define MSGTR_VO_SUB_Saturation "Saturation"
+#define MSGTR_VO_SUB_Volume "Volume"
+#define MSGTR_VO_SUB_Brightness "Brightness"
+#define MSGTR_VO_SUB_Hue "Hue"
+#define MSGTR_VO_SUB_Balance "Balance"
+
+// vo_3dfx.c
+#define MSGTR_LIBVO_3DFX_Only16BppSupported "[VO_3DFX] Only 16bpp supported!"
+#define MSGTR_LIBVO_3DFX_VisualIdIs "[VO_3DFX] Visual ID is  %lx.\n"
+#define MSGTR_LIBVO_3DFX_UnableToOpenDevice "[VO_3DFX] Unable to open /dev/3dfx.\n"
+#define MSGTR_LIBVO_3DFX_Error "[VO_3DFX] Error: %d.\n"
+#define MSGTR_LIBVO_3DFX_CouldntMapMemoryArea "[VO_3DFX] Couldn't map 3dfx memory areas: %p,%p,%d.\n"
+#define MSGTR_LIBVO_3DFX_DisplayInitialized "[VO_3DFX] Initialized: %p.\n"
+#define MSGTR_LIBVO_3DFX_UnknownSubdevice "[VO_3DFX] Unknown subdevice: %s.\n"
+
+// vo_aa.c
+#define MSGTR_VO_AA_HelpHeader "\n\nHere are the aalib vo_aa suboptions:\n"
+#define MSGTR_VO_AA_AdditionalOptions "Additional options vo_aa provides:\n" \
+"  help        print this help message\n" \
+"  osdcolor    set OSD color\n  subcolor    set subtitle color\n" \
+"        the color parameters are:\n           0 : normal\n" \
+"           1 : dim\n           2 : bold\n           3 : boldfont\n" \
+"           4 : reverse\n           5 : special\n\n\n"
+
+// vo_dxr3.c
+#define MSGTR_LIBVO_DXR3_UnableToLoadNewSPUPalette "[VO_DXR3] Unable to load new SPU palette!\n"
+#define MSGTR_LIBVO_DXR3_UnableToSetPlaymode "[VO_DXR3] Unable to set playmode!\n"
+#define MSGTR_LIBVO_DXR3_UnableToSetSubpictureMode "[VO_DXR3] Unable to set subpicture mode!\n"
+#define MSGTR_LIBVO_DXR3_UnableToGetTVNorm "[VO_DXR3] Unable to get TV norm!\n"
+#define MSGTR_LIBVO_DXR3_AutoSelectedTVNormByFrameRate "[VO_DXR3] Auto-selected TV norm by framerate: "
+#define MSGTR_LIBVO_DXR3_UnableToSetTVNorm "[VO_DXR3] Unable to set TV norm!\n"
+#define MSGTR_LIBVO_DXR3_SettingUpForNTSC "[VO_DXR3] Setting up for NTSC.\n"
+#define MSGTR_LIBVO_DXR3_SettingUpForPALSECAM "[VO_DXR3] Setting up for PAL/SECAM.\n"
+#define MSGTR_LIBVO_DXR3_SettingAspectRatioTo43 "[VO_DXR3] Setting aspect ratio to 4:3.\n"
+#define MSGTR_LIBVO_DXR3_SettingAspectRatioTo169 "[VO_DXR3] Setting aspect ratio to 16:9.\n"
+#define MSGTR_LIBVO_DXR3_OutOfMemory "[VO_DXR3] out of memory\n"
+#define MSGTR_LIBVO_DXR3_UnableToAllocateKeycolor "[VO_DXR3] Unable to allocate keycolor!\n"
+#define MSGTR_LIBVO_DXR3_UnableToAllocateExactKeycolor "[VO_DXR3] Unable to allocate exact keycolor, using closest match (0x%lx).\n"
+#define MSGTR_LIBVO_DXR3_Uninitializing "[VO_DXR3] Uninitializing.\n"
+#define MSGTR_LIBVO_DXR3_FailedRestoringTVNorm "[VO_DXR3] Failed restoring TV norm!\n"
+#define MSGTR_LIBVO_DXR3_EnablingPrebuffering "[VO_DXR3] Enabling prebuffering.\n"
+#define MSGTR_LIBVO_DXR3_UsingNewSyncEngine "[VO_DXR3] Using new sync engine.\n"
+#define MSGTR_LIBVO_DXR3_UsingOverlay "[VO_DXR3] Using overlay.\n"
+#define MSGTR_LIBVO_DXR3_ErrorYouNeedToCompileMplayerWithX11 "[VO_DXR3] Error: Overlay requires compiling with X11 libs/headers installed.\n"
+#define MSGTR_LIBVO_DXR3_WillSetTVNormTo "[VO_DXR3] Will set TV norm to: "
+#define MSGTR_LIBVO_DXR3_AutoAdjustToMovieFrameRatePALPAL60 "auto-adjust to movie framerate (PAL/PAL-60)"
+#define MSGTR_LIBVO_DXR3_AutoAdjustToMovieFrameRatePALNTSC "auto-adjust to movie framerate (PAL/NTSC)"
+#define MSGTR_LIBVO_DXR3_UseCurrentNorm "Use current norm."
+#define MSGTR_LIBVO_DXR3_UseUnknownNormSuppliedCurrentNorm "Unknown norm supplied. Use current norm."
+#define MSGTR_LIBVO_DXR3_ErrorOpeningForWritingTrying "[VO_DXR3] Error opening %s for writing, trying /dev/em8300 instead.\n"
+#define MSGTR_LIBVO_DXR3_ErrorOpeningForWritingTryingMV "[VO_DXR3] Error opening %s for writing, trying /dev/em8300_mv instead.\n"
+#define MSGTR_LIBVO_DXR3_ErrorOpeningForWritingAsWell "[VO_DXR3] Error opening /dev/em8300 for writing as well!\nBailing out.\n"
+#define MSGTR_LIBVO_DXR3_ErrorOpeningForWritingAsWellMV "[VO_DXR3] Error opening /dev/em8300_mv for writing as well!\nBailing out.\n"
+#define MSGTR_LIBVO_DXR3_Opened "[VO_DXR3] Opened: %s.\n"
+#define MSGTR_LIBVO_DXR3_ErrorOpeningForWritingTryingSP "[VO_DXR3] Error opening %s for writing, trying /dev/em8300_sp instead.\n"
+#define MSGTR_LIBVO_DXR3_ErrorOpeningForWritingAsWellSP "[VO_DXR3] Error opening /dev/em8300_sp for writing as well!\nBailing out.\n"
+#define MSGTR_LIBVO_DXR3_UnableToOpenDisplayDuringHackSetup "[VO_DXR3] Unable to open display during overlay hack setup!\n"
+#define MSGTR_LIBVO_DXR3_UnableToInitX11 "[VO_DXR3] Unable to init X11!\n"
+#define MSGTR_LIBVO_DXR3_FailedSettingOverlayAttribute "[VO_DXR3] Failed setting overlay attribute.\n"
+#define MSGTR_LIBVO_DXR3_FailedSettingOverlayScreen "[VO_DXR3] Failed setting overlay screen!\nExiting.\n"
+#define MSGTR_LIBVO_DXR3_FailedEnablingOverlay "[VO_DXR3] Failed enabling overlay!\nExiting.\n"
+#define MSGTR_LIBVO_DXR3_FailedResizingOverlayWindow "[VO_DXR3] Failed resizing overlay window!\n"
+#define MSGTR_LIBVO_DXR3_FailedSettingOverlayBcs "[VO_DXR3] Failed setting overlay bcs!\n"
+#define MSGTR_LIBVO_DXR3_FailedGettingOverlayYOffsetValues "[VO_DXR3] Failed getting overlay Y-offset values!\nExiting.\n"
+#define MSGTR_LIBVO_DXR3_FailedGettingOverlayXOffsetValues "[VO_DXR3] Failed getting overlay X-offset values!\nExiting.\n"
+#define MSGTR_LIBVO_DXR3_FailedGettingOverlayXScaleCorrection "[VO_DXR3] Failed getting overlay X scale correction!\nExiting.\n"
+#define MSGTR_LIBVO_DXR3_YOffset "[VO_DXR3] Yoffset: %d.\n"
+#define MSGTR_LIBVO_DXR3_XOffset "[VO_DXR3] Xoffset: %d.\n"
+#define MSGTR_LIBVO_DXR3_XCorrection "[VO_DXR3] Xcorrection: %d.\n"
+#define MSGTR_LIBVO_DXR3_FailedSetSignalMix "[VO_DXR3] Failed to set signal mix!\n"
+
+// vo_jpeg.c
+#define MSGTR_VO_JPEG_ProgressiveJPEG "Progressive JPEG enabled."
+#define MSGTR_VO_JPEG_NoProgressiveJPEG "Progressive JPEG disabled."
+#define MSGTR_VO_JPEG_BaselineJPEG "Baseline JPEG enabled."
+#define MSGTR_VO_JPEG_NoBaselineJPEG "Baseline JPEG disabled."
+
+// vo_mga.c
+#define MSGTR_LIBVO_MGA_AspectResized "[VO_MGA] aspect(): resized to %dx%d.\n"
+#define MSGTR_LIBVO_MGA_Uninit "[VO] uninit!\n"
+
+// mga_template.c
+#define MSGTR_LIBVO_MGA_ErrorInConfigIoctl "[MGA] error in mga_vid_config ioctl (wrong mga_vid.o version?)"
+#define MSGTR_LIBVO_MGA_CouldNotGetLumaValuesFromTheKernelModule "[MGA] Could not get luma values from the kernel module!\n"
+#define MSGTR_LIBVO_MGA_CouldNotSetLumaValuesFromTheKernelModule "[MGA] Could not set luma values from the kernel module!\n"
+#define MSGTR_LIBVO_MGA_ScreenWidthHeightUnknown "[MGA] Screen width/height unknown!\n"
+#define MSGTR_LIBVO_MGA_InvalidOutputFormat "[MGA] invalid output format %0X\n"
+#define MSGTR_LIBVO_MGA_IncompatibleDriverVersion "[MGA] Your mga_vid driver version is incompatible with this MPlayer version!\n"
+#define MSGTR_LIBVO_MGA_CouldntOpen "[MGA] Couldn't open: %s\n"
+#define MSGTR_LIBVO_MGA_ResolutionTooHigh "[MGA] Source resolution exceeds 1023x1023 in at least one dimension.\n[MGA] Rescale in software or use -lavdopts lowres=1.\n"
+#define MSGTR_LIBVO_MGA_mgavidVersionMismatch "[MGA] mismatch between kernel (%u) and MPlayer (%u) mga_vid driver versions\n"
+
+// vo_null.c
+#define MSGTR_LIBVO_NULL_UnknownSubdevice "[VO_NULL] Unknown subdevice: %s.\n"
+
+// vo_png.c
+#define MSGTR_LIBVO_PNG_Warning1 "[VO_PNG] Warning: compression level set to 0, compression disabled!\n"
+#define MSGTR_LIBVO_PNG_Warning2 "[VO_PNG] Info: Use -vo png:z=<n> to set compression level from 0 to 9.\n"
+#define MSGTR_LIBVO_PNG_Warning3 "[VO_PNG] Info: (0 = no compression, 1 = fastest, lowest - 9 best, slowest compression)\n"
+#define MSGTR_LIBVO_PNG_ErrorOpeningForWriting "\n[VO_PNG] Error opening '%s' for writing!\n"
+#define MSGTR_LIBVO_PNG_ErrorInCreatePng "[VO_PNG] Error in create_png.\n"
+
+// vo_pnm.c
+#define MSGTR_VO_PNM_ASCIIMode "ASCII mode enabled."
+#define MSGTR_VO_PNM_RawMode "Raw mode enabled."
+#define MSGTR_VO_PNM_PPMType "Will write PPM files."
+#define MSGTR_VO_PNM_PGMType "Will write PGM files."
+#define MSGTR_VO_PNM_PGMYUVType "Will write PGMYUV files."
+
+// 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"
+#define MSGTR_LIBVO_SDL_FailedToSetVideoMode "[VO_SDL] Failed to set video mode: %s.\n"
+#define MSGTR_LIBVO_SDL_CouldntCreateAYUVOverlay "[VO_SDL] Couldn't create a YUV overlay: %s.\n"
+#define MSGTR_LIBVO_SDL_CouldntCreateARGBSurface "[VO_SDL] Couldn't create an RGB surface: %s.\n"
+#define MSGTR_LIBVO_SDL_UsingDepthColorspaceConversion "[VO_SDL] Using depth/colorspace conversion, this will slow things down (%ibpp -> %ibpp).\n"
+#define MSGTR_LIBVO_SDL_UnsupportedImageFormatInDrawslice "[VO_SDL] Unsupported image format in draw_slice, contact MPlayer developers!\n"
+#define MSGTR_LIBVO_SDL_BlitFailed "[VO_SDL] Blit failed: %s.\n"
+#define MSGTR_LIBVO_SDL_InitializationFailed "[VO_SDL] SDL initialization failed: %s.\n"
+#define MSGTR_LIBVO_SDL_UsingDriver "[VO_SDL] Using driver: %s.\n"
+
+// vo_svga.c
+#define MSGTR_LIBVO_SVGA_ForcedVidmodeNotAvailable "[VO_SVGA] Forced vid_mode %d (%s) not available.\n"
+#define MSGTR_LIBVO_SVGA_ForcedVidmodeTooSmall "[VO_SVGA] Forced vid_mode %d (%s) too small.\n"
+#define MSGTR_LIBVO_SVGA_Vidmode "[VO_SVGA] Vid_mode: %d, %dx%d %dbpp.\n"
+#define MSGTR_LIBVO_SVGA_VgasetmodeFailed "[VO_SVGA] Vga_setmode(%d) failed.\n"
+#define MSGTR_LIBVO_SVGA_VideoModeIsLinearAndMemcpyCouldBeUsed "[VO_SVGA] Video mode is linear and memcpy could be used for image transfer.\n"
+#define MSGTR_LIBVO_SVGA_VideoModeHasHardwareAcceleration "[VO_SVGA] Video mode has hardware acceleration and put_image could be used.\n"
+#define MSGTR_LIBVO_SVGA_IfItWorksForYouIWouldLikeToKnow "[VO_SVGA] If it works for you I would like to know.\n[VO_SVGA] (send log with `mplayer test.avi -v -v -v -v &> svga.log`). Thx!\n"
+#define MSGTR_LIBVO_SVGA_VideoModeHas "[VO_SVGA] Video mode has %d page(s).\n"
+#define MSGTR_LIBVO_SVGA_CenteringImageStartAt "[VO_SVGA] Centering image. Starting at (%d,%d)\n"
+#define MSGTR_LIBVO_SVGA_UsingVidix "[VO_SVGA] Using VIDIX. w=%i h=%i  mw=%i mh=%i\n"
+
+// vo_tdfx_vid.c
+#define MSGTR_LIBVO_TDFXVID_Move "[VO_TDXVID] Move %d(%d) x %d => %d.\n"
+#define MSGTR_LIBVO_TDFXVID_AGPMoveFailedToClearTheScreen "[VO_TDFXVID] AGP move failed to clear the screen.\n"
+#define MSGTR_LIBVO_TDFXVID_BlitFailed "[VO_TDFXVID] Blit failed.\n"
+#define MSGTR_LIBVO_TDFXVID_NonNativeOverlayFormatNeedConversion "[VO_TDFXVID] Non-native overlay format needs conversion.\n"
+#define MSGTR_LIBVO_TDFXVID_UnsupportedInputFormat "[VO_TDFXVID] Unsupported input format 0x%x.\n"
+#define MSGTR_LIBVO_TDFXVID_OverlaySetupFailed "[VO_TDFXVID] Overlay setup failed.\n"
+#define MSGTR_LIBVO_TDFXVID_OverlayOnFailed "[VO_TDFXVID] Overlay on failed.\n"
+#define MSGTR_LIBVO_TDFXVID_OverlayReady "[VO_TDFXVID] Overlay ready: %d(%d) x %d @ %d => %d(%d) x %d @ %d.\n"
+#define MSGTR_LIBVO_TDFXVID_TextureBlitReady "[VO_TDFXVID] Texture blit ready: %d(%d) x %d @ %d => %d(%d) x %d @ %d.\n"
+#define MSGTR_LIBVO_TDFXVID_OverlayOffFailed "[VO_TDFXVID] Overlay off failed\n"
+#define MSGTR_LIBVO_TDFXVID_CantOpen "[VO_TDFXVID] Can't open %s: %s.\n"
+#define MSGTR_LIBVO_TDFXVID_CantGetCurrentCfg "[VO_TDFXVID] Can't get current configuration: %s.\n"
+#define MSGTR_LIBVO_TDFXVID_MemmapFailed "[VO_TDFXVID] Memmap failed !!!!!\n"
+#define MSGTR_LIBVO_TDFXVID_GetImageTodo "Get image todo.\n"
+#define MSGTR_LIBVO_TDFXVID_AgpMoveFailed "[VO_TDFXVID] AGP move failed.\n"
+#define MSGTR_LIBVO_TDFXVID_SetYuvFailed "[VO_TDFXVID] Set YUV failed.\n"
+#define MSGTR_LIBVO_TDFXVID_AgpMoveFailedOnYPlane "[VO_TDFXVID] AGP move failed on Y plane.\n"
+#define MSGTR_LIBVO_TDFXVID_AgpMoveFailedOnUPlane "[VO_TDFXVID] AGP move failed on U plane.\n"
+#define MSGTR_LIBVO_TDFXVID_AgpMoveFailedOnVPlane "[VO_TDFXVID] AGP move failed on V plane.\n"
+#define MSGTR_LIBVO_TDFXVID_UnknownFormat "[VO_TDFXVID] unknown format: 0x%x.\n"
+
+// vo_tdfxfb.c
+#define MSGTR_LIBVO_TDFXFB_CantOpen "[VO_TDFXFB] Can't open %s: %s.\n"
+#define MSGTR_LIBVO_TDFXFB_ProblemWithFbitgetFscreenInfo "[VO_TDFXFB] Problem with FBITGET_FSCREENINFO ioctl: %s.\n"
+#define MSGTR_LIBVO_TDFXFB_ProblemWithFbitgetVscreenInfo "[VO_TDFXFB] Problem with FBITGET_VSCREENINFO ioctl: %s.\n"
+#define MSGTR_LIBVO_TDFXFB_ThisDriverOnlySupports "[VO_TDFXFB] This driver only supports the 3Dfx Banshee, Voodoo3 and Voodoo 5.\n"
+#define MSGTR_LIBVO_TDFXFB_OutputIsNotSupported "[VO_TDFXFB] %d bpp output is not supported.\n"
+#define MSGTR_LIBVO_TDFXFB_CouldntMapMemoryAreas "[VO_TDFXFB] Couldn't map memory areas: %s.\n"
+#define MSGTR_LIBVO_TDFXFB_BppOutputIsNotSupported "[VO_TDFXFB] %d bpp output is not supported (This should never have happened).\n"
+#define MSGTR_LIBVO_TDFXFB_SomethingIsWrongWithControl "[VO_TDFXFB] Eik! Something's wrong with control().\n"
+#define MSGTR_LIBVO_TDFXFB_NotEnoughVideoMemoryToPlay "[VO_TDFXFB] Not enough video memory to play this movie. Try at a lower resolution.\n"
+#define MSGTR_LIBVO_TDFXFB_ScreenIs "[VO_TDFXFB] Screen is %dx%d at %d bpp, in is %dx%d at %d bpp, norm is %dx%d.\n"
+
+// vo_tga.c
+#define MSGTR_LIBVO_TGA_UnknownSubdevice "[VO_TGA] Unknown subdevice: %s.\n"
+
+// vo_vesa.c
+#define MSGTR_LIBVO_VESA_FatalErrorOccurred "[VO_VESA] Fatal error occurred! Can't continue.\n"
+#define MSGTR_LIBVO_VESA_UnknownSubdevice "[VO_VESA] unknown subdevice: '%s'.\n"
+#define MSGTR_LIBVO_VESA_YouHaveTooLittleVideoMemory "[VO_VESA] You have too little video memory for this mode:\n[VO_VESA] Required: %08lX present: %08lX.\n"
+#define MSGTR_LIBVO_VESA_YouHaveToSpecifyTheCapabilitiesOfTheMonitor "[VO_VESA] You have to specify the capabilities of the monitor. Not changing refresh rate.\n"
+#define MSGTR_LIBVO_VESA_UnableToFitTheMode "[VO_VESA] The mode does not fit the monitor limits. Not changing refresh rate.\n"
+#define MSGTR_LIBVO_VESA_DetectedInternalFatalError "[VO_VESA] Detected internal fatal error: init is called before preinit.\n"
+#define MSGTR_LIBVO_VESA_SwitchFlipIsNotSupported "[VO_VESA] The -flip option is not supported.\n"
+#define MSGTR_LIBVO_VESA_PossibleReasonNoVbe2BiosFound "[VO_VESA] Possible reason: No VBE2 BIOS found.\n"
+#define MSGTR_LIBVO_VESA_FoundVesaVbeBiosVersion "[VO_VESA] Found VESA VBE BIOS Version %x.%x Revision: %x.\n"
+#define MSGTR_LIBVO_VESA_VideoMemory "[VO_VESA] Video memory: %u Kb.\n"
+#define MSGTR_LIBVO_VESA_Capabilites "[VO_VESA] VESA Capabilities: %s %s %s %s %s.\n"
+#define MSGTR_LIBVO_VESA_BelowWillBePrintedOemInfo "[VO_VESA] !!! OEM info will be printed below !!!\n"
+#define MSGTR_LIBVO_VESA_YouShouldSee5OemRelatedLines "[VO_VESA] You should see 5 OEM related lines below; If not, you've broken vm86.\n"
+#define MSGTR_LIBVO_VESA_OemInfo "[VO_VESA] OEM info: %s.\n"
+#define MSGTR_LIBVO_VESA_OemRevision "[VO_VESA] OEM Revision: %x.\n"
+#define MSGTR_LIBVO_VESA_OemVendor "[VO_VESA] OEM vendor: %s.\n"
+#define MSGTR_LIBVO_VESA_OemProductName "[VO_VESA] OEM Product Name: %s.\n"
+#define MSGTR_LIBVO_VESA_OemProductRev "[VO_VESA] OEM Product Rev: %s.\n"
+#define MSGTR_LIBVO_VESA_Hint "[VO_VESA] Hint: For working TV-Out you should have plugged in the TV connector\n"\
+"[VO_VESA] before booting since VESA BIOS initializes itself only during POST.\n"
+#define MSGTR_LIBVO_VESA_UsingVesaMode "[VO_VESA] Using VESA mode (%u) = %x [%ux%u@%u]\n"
+#define MSGTR_LIBVO_VESA_CantInitializeSwscaler "[VO_VESA] Can't initialize software scaler.\n"
+#define MSGTR_LIBVO_VESA_CantUseDga "[VO_VESA] Can't use DGA. Force bank switching mode. :(\n"
+#define MSGTR_LIBVO_VESA_UsingDga "[VO_VESA] Using DGA (physical resources: %08lXh, %08lXh)"
+#define MSGTR_LIBVO_VESA_CantUseDoubleBuffering "[VO_VESA] Can't use double buffering: not enough video memory.\n"
+#define MSGTR_LIBVO_VESA_CantFindNeitherDga "[VO_VESA] Can find neither DGA nor relocatable window frame.\n"
+#define MSGTR_LIBVO_VESA_YouveForcedDga "[VO_VESA] You've forced DGA. Exiting\n"
+#define MSGTR_LIBVO_VESA_CantFindValidWindowAddress "[VO_VESA] Can't find valid window address.\n"
+#define MSGTR_LIBVO_VESA_UsingBankSwitchingMode "[VO_VESA] Using bank switching mode (physical resources: %08lXh, %08lXh).\n"
+#define MSGTR_LIBVO_VESA_CantAllocateTemporaryBuffer "[VO_VESA] Can't allocate temporary buffer.\n"
+#define MSGTR_LIBVO_VESA_SorryUnsupportedMode "[VO_VESA] Sorry, unsupported mode -- try -x 640 -zoom.\n"
+#define MSGTR_LIBVO_VESA_OhYouReallyHavePictureOnTv "[VO_VESA] Oh you really have a picture on the TV!\n"
+#define MSGTR_LIBVO_VESA_CantInitialozeLinuxVideoOverlay "[VO_VESA] Can't initialize Linux Video Overlay.\n"
+#define MSGTR_LIBVO_VESA_UsingVideoOverlay "[VO_VESA] Using video overlay: %s.\n"
+#define MSGTR_LIBVO_VESA_CantInitializeVidixDriver "[VO_VESA] Can't initialize VIDIX driver.\n"
+#define MSGTR_LIBVO_VESA_UsingVidix "[VO_VESA] Using VIDIX.\n"
+#define MSGTR_LIBVO_VESA_CantFindModeFor "[VO_VESA] Can't find mode for: %ux%u@%u.\n"
+#define MSGTR_LIBVO_VESA_InitializationComplete "[VO_VESA] VESA initialization complete.\n"
+
+// vesa_lvo.c
+#define MSGTR_LIBVO_VESA_ThisBranchIsNoLongerSupported "[VESA_LVO] This branch is no longer supported.\n[VESA_LVO] Please use -vo vesa:vidix instead.\n"
+#define MSGTR_LIBVO_VESA_CouldntOpen "[VESA_LVO] Couldn't open: '%s'\n"
+#define MSGTR_LIBVO_VESA_InvalidOutputFormat "[VESA_LVI] Invalid output format: %s(%0X)\n"
+#define MSGTR_LIBVO_VESA_IncompatibleDriverVersion "[VESA_LVO] Your fb_vid driver version is incompatible with this MPlayer version!\n"
+
+// vo_x11.c
+#define MSGTR_LIBVO_X11_DrawFrameCalled "[VO_X11] draw_frame() called!!!!!!\n"
+
+// vo_xv.c
+#define MSGTR_LIBVO_XV_DrawFrameCalled "[VO_XV] draw_frame() called!!!!!!\n"
+#define MSGTR_LIBVO_XV_SharedMemoryNotSupported "[VO_XV] Shared memory not supported\nReverting to normal Xv.\n"
+#define MSGTR_LIBVO_XV_XvNotSupportedByX11 "[VO_XV] Sorry, Xv not supported by this X11 version/driver\n[VO_XV] ******** Try with  -vo x11  or  -vo sdl  *********\n"
+#define MSGTR_LIBVO_XV_XvQueryAdaptorsFailed  "[VO_XV] XvQueryAdaptors failed.\n"
+#define MSGTR_LIBVO_XV_InvalidPortParameter "[VO_XV] Invalid port parameter, overriding with port 0.\n"
+#define MSGTR_LIBVO_XV_CouldNotGrabPort "[VO_XV] Could not grab port %i.\n"
+#define MSGTR_LIBVO_XV_CouldNotFindFreePort "[VO_XV] Could not find free Xvideo port - maybe another process is already\n"\
+"[VO_XV] using it. Close all video applications, and try again. If that does\n"\
+"[VO_XV] not help, see 'mplayer -vo help' for other (non-xv) video out drivers.\n"
+#define MSGTR_LIBVO_XV_NoXvideoSupport "[VO_XV] It seems there is no Xvideo support for your video card available.\n"\
+"[VO_XV] Run 'xvinfo' to verify its Xv support and read\n"\
+"[VO_XV] DOCS/HTML/en/video.html#xv!\n"\
+"[VO_XV] See 'mplayer -vo help' for other (non-xv) video out drivers.\n"\
+"[VO_XV] Try -vo x11.\n"
+#define MSGTR_VO_XV_ImagedimTooHigh "Source image dimensions are too high: %ux%u (maximum is %ux%u)\n"
+
+// vo_yuv4mpeg.c
+#define MSGTR_VO_YUV4MPEG_InterlacedHeightDivisibleBy4 "Interlaced mode requires image height to be divisible by 4."
+#define MSGTR_VO_YUV4MPEG_InterlacedLineBufAllocFail "Unable to allocate line buffer for interlaced mode."
+#define MSGTR_VO_YUV4MPEG_WidthDivisibleBy2 "Image width must be divisible by 2."
+#define MSGTR_VO_YUV4MPEG_OutFileOpenError "Can't get memory or file handle to write \"%s\"!"
+#define MSGTR_VO_YUV4MPEG_OutFileWriteError "Error writing image to output!"
+#define MSGTR_VO_YUV4MPEG_UnknownSubDev "Unknown subdevice: %s"
+#define MSGTR_VO_YUV4MPEG_InterlacedTFFMode "Using interlaced output mode, top-field first."
+#define MSGTR_VO_YUV4MPEG_InterlacedBFFMode "Using interlaced output mode, bottom-field first."
+#define MSGTR_VO_YUV4MPEG_ProgressiveMode "Using (default) progressive frame mode."
+
+// vosub_vidix.c
+#define MSGTR_LIBVO_SUB_VIDIX_CantStartPlayback "[VO_SUB_VIDIX] Can't start playback: %s\n"
+#define MSGTR_LIBVO_SUB_VIDIX_CantStopPlayback "[VO_SUB_VIDIX] Can't stop playback: %s\n"
+#define MSGTR_LIBVO_SUB_VIDIX_InterleavedUvForYuv410pNotSupported "[VO_SUB_VIDIX] Interleaved UV for YUV410P not supported.\n"
+#define MSGTR_LIBVO_SUB_VIDIX_DummyVidixdrawsliceWasCalled "[VO_SUB_VIDIX] Dummy vidix_draw_slice() was called.\n"
+#define MSGTR_LIBVO_SUB_VIDIX_DummyVidixdrawframeWasCalled "[VO_SUB_VIDIX] Dummy vidix_draw_frame() was called.\n"
+#define MSGTR_LIBVO_SUB_VIDIX_UnsupportedFourccForThisVidixDriver "[VO_SUB_VIDIX] Unsupported FourCC for this VIDIX driver: %x (%s).\n"
+#define MSGTR_LIBVO_SUB_VIDIX_VideoServerHasUnsupportedResolution "[VO_SUB_VIDIX] Video server has unsupported resolution (%dx%d), supported: %dx%d-%dx%d.\n"
+#define MSGTR_LIBVO_SUB_VIDIX_VideoServerHasUnsupportedColorDepth "[VO_SUB_VIDIX] Video server has unsupported color depth by vidix (%d).\n"
+#define MSGTR_LIBVO_SUB_VIDIX_DriverCantUpscaleImage "[VO_SUB_VIDIX] VIDIX driver can't upscale image (%d%d -> %d%d).\n"
+#define MSGTR_LIBVO_SUB_VIDIX_DriverCantDownscaleImage "[VO_SUB_VIDIX] VIDIX driver can't downscale image (%d%d -> %d%d).\n"
+#define MSGTR_LIBVO_SUB_VIDIX_CantConfigurePlayback "[VO_SUB_VIDIX] Can't configure playback: %s.\n"
+#define MSGTR_LIBVO_SUB_VIDIX_YouHaveWrongVersionOfVidixLibrary "[VO_SUB_VIDIX] You have the wrong version of the VIDIX library.\n"
+#define MSGTR_LIBVO_SUB_VIDIX_CouldntFindWorkingVidixDriver "[VO_SUB_VIDIX] Couldn't find working VIDIX driver.\n"
+#define MSGTR_LIBVO_SUB_VIDIX_CouldntGetCapability "[VO_SUB_VIDIX] Couldn't get capability: %s.\n"
+
+// x11_common.c
+#define MSGTR_EwmhFullscreenStateFailed "\nX11: Couldn't send EWMH fullscreen event!\n"
+#define MSGTR_CouldNotFindXScreenSaver "xscreensaver_disable: Could not find XScreenSaver window.\n"
+#define MSGTR_SelectedVideoMode "XF86VM: Selected video mode %dx%d for image size %dx%d.\n"
+
+#define MSGTR_InsertingAfVolume "[Mixer] No hardware mixing, inserting volume filter.\n"
+#define MSGTR_NoVolume "[Mixer] No volume control available.\n"
+#define MSGTR_NoBalance "[Mixer] No balance control available.\n"
+
+// 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"
+
+
+// ======================= 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"
+#define MSGTR_AO_OSS_ChanNotFound "[AO OSS] audio_setup: Audio card mixer does not have channel '%s', using default.\n"
+#define MSGTR_AO_OSS_CantOpenDev "[AO OSS] audio_setup: Can't open audio device %s: %s\n"
+#define MSGTR_AO_OSS_CantMakeFd "[AO OSS] audio_setup: Can't make file descriptor blocking: %s\n"
+#define MSGTR_AO_OSS_CantSet "[AO OSS] Can't set audio device %s to %s output, trying %s...\n"
+#define MSGTR_AO_OSS_CantSetChans "[AO OSS] audio_setup: Failed to set audio device to %d channels.\n"
+#define MSGTR_AO_OSS_CantUseGetospace "[AO OSS] audio_setup: driver doesn't support SNDCTL_DSP_GETOSPACE :-(\n"
+#define MSGTR_AO_OSS_CantUseSelect "[AO OSS]\n   ***  Your audio driver DOES NOT support select()  ***\n Recompile MPlayer with #undef HAVE_AUDIO_SELECT in config.h !\n\n"
+#define MSGTR_AO_OSS_CantReopen "[AO OSS]\nFatal error: *** CANNOT RE-OPEN / RESET AUDIO DEVICE *** %s\n"
+#define MSGTR_AO_OSS_UnknownUnsupportedFormat "[AO OSS] Unknown/Unsupported OSS format: %x.\n"
+
+// ao_arts.c
+#define MSGTR_AO_ARTS_CantInit "[AO ARTS] %s\n"
+#define MSGTR_AO_ARTS_ServerConnect "[AO ARTS] Connected to sound server.\n"
+#define MSGTR_AO_ARTS_CantOpenStream "[AO ARTS] Unable to open a stream.\n"
+#define MSGTR_AO_ARTS_StreamOpen "[AO ARTS] Stream opened.\n"
+#define MSGTR_AO_ARTS_BufferSize "[AO ARTS] buffer size: %d\n"
+
+// ao_dxr2.c
+#define MSGTR_AO_DXR2_SetVolFailed "[AO DXR2] Setting volume to %d failed.\n"
+#define MSGTR_AO_DXR2_UnsupSamplerate "[AO DXR2] %d Hz not supported, try to resample.\n"
+
+// ao_esd.c
+#define MSGTR_AO_ESD_CantOpenSound "[AO ESD] esd_open_sound failed: %s\n"
+#define MSGTR_AO_ESD_LatencyInfo "[AO ESD] latency: [server: %0.2fs, net: %0.2fs] (adjust %0.2fs)\n"
+#define MSGTR_AO_ESD_CantOpenPBStream "[AO ESD] failed to open ESD playback stream: %s\n"
+
+// ao_mpegpes.c
+#define MSGTR_AO_MPEGPES_CantSetMixer "[AO MPEGPES] DVB audio set mixer failed: %s.\n"
+#define MSGTR_AO_MPEGPES_UnsupSamplerate "[AO MPEGPES] %d Hz not supported, try to resample.\n"
+
+// 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_CantOpenOutputFile "[AO PCM] Failed to open %s for writing!\n"
+
+// ao_sdl.c
+#define MSGTR_AO_SDL_INFO "[AO SDL] Samplerate: %iHz Channels: %s Format %s\n"
+#define MSGTR_AO_SDL_DriverInfo "[AO SDL] using %s audio driver.\n"
+#define MSGTR_AO_SDL_UnsupportedAudioFmt "[AO SDL] Unsupported audio format: 0x%x.\n"
+#define MSGTR_AO_SDL_CantInit "[AO SDL] SDL Audio initialization failed: %s\n"
+#define MSGTR_AO_SDL_CantOpenAudio "[AO SDL] Unable to open audio: %s\n"
+
+// ao_sgi.c
+#define MSGTR_AO_SGI_INFO "[AO SGI] control.\n"
+#define MSGTR_AO_SGI_InitInfo "[AO SGI] init: Samplerate: %iHz Channels: %s Format %s\n"
+#define MSGTR_AO_SGI_InvalidDevice "[AO SGI] play: invalid device.\n"
+#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_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"
+#define MSGTR_AO_SGI_Reset "[AO SGI] reset: ...\n"
+#define MSGTR_AO_SGI_PauseInfo "[AO SGI] audio_pause: ...\n"
+#define MSGTR_AO_SGI_ResumeInfo "[AO SGI] audio_resume: ...\n"
+
+// ao_sun.c
+#define MSGTR_AO_SUN_RtscSetinfoFailed "[AO SUN] rtsc: SETINFO failed.\n"
+#define MSGTR_AO_SUN_RtscWriteFailed "[AO SUN] rtsc: write failed.\n"
+#define MSGTR_AO_SUN_CantOpenAudioDev "[AO SUN] Can't open audio device %s, %s  -> nosound.\n"
+#define MSGTR_AO_SUN_UnsupSampleRate "[AO SUN] audio_setup: your card doesn't support %d channel, %s, %d Hz samplerate.\n"
+#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"
+#define MSGTR_AO_ALSA_MixerAttachError "[AO_ALSA] Mixer attach %s error: %s\n"
+#define MSGTR_AO_ALSA_MixerRegisterError "[AO_ALSA] Mixer register error: %s\n"
+#define MSGTR_AO_ALSA_MixerLoadError "[AO_ALSA] Mixer load error: %s\n"
+#define MSGTR_AO_ALSA_UnableToFindSimpleControl "[AO_ALSA] Unable to find simple control '%s',%i.\n"
+#define MSGTR_AO_ALSA_ErrorSettingLeftChannel "[AO_ALSA] Error setting left channel, %s\n"
+#define MSGTR_AO_ALSA_ErrorSettingRightChannel "[AO_ALSA] Error setting right channel, %s\n"
+#define MSGTR_AO_ALSA_CommandlineHelp "\n[AO_ALSA] -ao alsa commandline help:\n"\
+"[AO_ALSA] Example: mplayer -ao alsa:device=hw=0.3\n"\
+"[AO_ALSA]   Sets first card fourth hardware device.\n\n"\
+"[AO_ALSA] Options:\n"\
+"[AO_ALSA]   noblock\n"\
+"[AO_ALSA]     Opens device in non-blocking mode.\n"\
+"[AO_ALSA]   device=<device-name>\n"\
+"[AO_ALSA]     Sets device (change , to . and : to =)\n"
+#define MSGTR_AO_ALSA_ChannelsNotSupported "[AO_ALSA] %d channels are not supported.\n"
+#define MSGTR_AO_ALSA_OpenInNonblockModeFailed "[AO_ALSA] Open in nonblock-mode failed, trying to open in block-mode.\n"
+#define MSGTR_AO_ALSA_PlaybackOpenError "[AO_ALSA] Playback open error: %s\n"
+#define MSGTR_AO_ALSA_ErrorSetBlockMode "[AL_ALSA] Error setting block-mode %s.\n"
+#define MSGTR_AO_ALSA_UnableToGetInitialParameters "[AO_ALSA] Unable to get initial parameters: %s\n"
+#define MSGTR_AO_ALSA_UnableToSetAccessType "[AO_ALSA] Unable to set access type: %s\n"
+#define MSGTR_AO_ALSA_FormatNotSupportedByHardware "[AO_ALSA] Format %s is not supported by hardware, trying default.\n"
+#define MSGTR_AO_ALSA_UnableToSetFormat "[AO_ALSA] Unable to set format: %s\n"
+#define MSGTR_AO_ALSA_UnableToSetChannels "[AO_ALSA] Unable to set channels: %s\n"
+#define MSGTR_AO_ALSA_UnableToDisableResampling "[AO_ALSA] Unable to disable resampling: %s\n"
+#define MSGTR_AO_ALSA_UnableToSetSamplerate2 "[AO_ALSA] Unable to set samplerate-2: %s\n"
+#define MSGTR_AO_ALSA_UnableToSetBufferTimeNear "[AO_ALSA] Unable to set buffer time near: %s\n"
+#define MSGTR_AO_ALSA_UnableToGetPeriodSize "[AO ALSA] Unable to get period size: %s\n"
+#define MSGTR_AO_ALSA_UnableToSetPeriods "[AO_ALSA] Unable to set periods: %s\n"
+#define MSGTR_AO_ALSA_UnableToSetHwParameters "[AO_ALSA] Unable to set hw-parameters: %s\n"
+#define MSGTR_AO_ALSA_UnableToGetBufferSize "[AO_ALSA] Unable to get buffersize: %s\n"
+#define MSGTR_AO_ALSA_UnableToGetSwParameters "[AO_ALSA] Unable to get sw-parameters: %s\n"
+#define MSGTR_AO_ALSA_UnableToSetSwParameters "[AO_ALSA] Unable to set sw-parameters: %s\n"
+#define MSGTR_AO_ALSA_UnableToGetBoundary "[AO_ALSA] Unable to get boundary: %s\n"
+#define MSGTR_AO_ALSA_UnableToSetStartThreshold "[AO_ALSA] Unable to set start threshold: %s\n"
+#define MSGTR_AO_ALSA_UnableToSetStopThreshold "[AO_ALSA] Unable to set stop threshold: %s\n"
+#define MSGTR_AO_ALSA_UnableToSetSilenceSize "[AO_ALSA] Unable to set silence size: %s\n"
+#define MSGTR_AO_ALSA_PcmCloseError "[AO_ALSA] pcm close error: %s\n"
+#define MSGTR_AO_ALSA_NoHandlerDefined "[AO_ALSA] No handler defined!\n"
+#define MSGTR_AO_ALSA_PcmPrepareError "[AO_ALSA] pcm prepare error: %s\n"
+#define MSGTR_AO_ALSA_PcmPauseError "[AO_ALSA] pcm pause error: %s\n"
+#define MSGTR_AO_ALSA_PcmDropError "[AO_ALSA] pcm drop error: %s\n"
+#define MSGTR_AO_ALSA_PcmResumeError "[AO_ALSA] pcm resume error: %s\n"
+#define MSGTR_AO_ALSA_DeviceConfigurationError "[AO_ALSA] Device configuration error."
+#define MSGTR_AO_ALSA_PcmInSuspendModeTryingResume "[AO_ALSA] Pcm in suspend mode, trying to resume.\n"
+#define MSGTR_AO_ALSA_WriteError "[AO_ALSA] Write error: %s\n"
+#define MSGTR_AO_ALSA_TryingToResetSoundcard "[AO_ALSA] Trying to reset soundcard.\n"
+#define MSGTR_AO_ALSA_CannotGetPcmStatus "[AO_ALSA] Cannot get pcm status: %s\n"
+
+// ao_plugin.c
+#define MSGTR_AO_PLUGIN_InvalidPlugin "[AO PLUGIN] invalid plugin: %s\n"
+
+
+// ======================= audio filters ================================
+
+// af_scaletempo.c
+#define MSGTR_AF_ValueOutOfRange MSGTR_VO_ValueOutOfRange
+
+// af_ladspa.c
+#define MSGTR_AF_LADSPA_AvailableLabels "available labels in"
+#define MSGTR_AF_LADSPA_WarnNoInputs "WARNING! This LADSPA plugin has no audio inputs.\n  The incoming audio signal will be lost."
+#define MSGTR_AF_LADSPA_ErrMultiChannel "Multi-channel (>2) plugins are not supported (yet).\n  Use only mono and stereo plugins."
+#define MSGTR_AF_LADSPA_ErrNoOutputs "This LADSPA plugin has no audio outputs."
+#define MSGTR_AF_LADSPA_ErrInOutDiff "The number of audio inputs and audio outputs of the LADSPA plugin differ."
+#define MSGTR_AF_LADSPA_ErrFailedToLoad "failed to load"
+#define MSGTR_AF_LADSPA_ErrNoDescriptor "Couldn't find ladspa_descriptor() function in the specified library file."
+#define MSGTR_AF_LADSPA_ErrLabelNotFound "Couldn't find label in plugin library."
+#define MSGTR_AF_LADSPA_ErrNoSuboptions "No suboptions specified."
+#define MSGTR_AF_LADSPA_ErrNoLibFile "No library file specified."
+#define MSGTR_AF_LADSPA_ErrNoLabel "No filter label specified."
+#define MSGTR_AF_LADSPA_ErrNotEnoughControls "Not enough controls specified on the command line."
+#define MSGTR_AF_LADSPA_ErrControlBelow "%s: Input control #%d is below lower boundary of %0.4f.\n"
+#define MSGTR_AF_LADSPA_ErrControlAbove "%s: Input control #%d is above upper boundary of %0.4f.\n"
+
+// format.c
+#define MSGTR_AF_FORMAT_UnknownFormat "unknown format "
+
+
+// ========================== 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"
+#define MSGTR_INPUT_JOYSTICK_WarnLostSync "Joystick: warning init event, we have lost sync with driver.\n"
+#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
+#define MSGTR_INPUT_INPUT_ErrCantRegister2ManyCmdFds "Too many command file descriptors, cannot register file descriptor %d.\n"
+#define MSGTR_INPUT_INPUT_ErrCantRegister2ManyKeyFds "Too many key file descriptors, cannot register file descriptor %d.\n"
+#define MSGTR_INPUT_INPUT_ErrArgMustBeInt "Command %s: argument %d isn't an integer.\n"
+#define MSGTR_INPUT_INPUT_ErrArgMustBeFloat "Command %s: argument %d isn't a float.\n"
+#define MSGTR_INPUT_INPUT_ErrUnterminatedArg "Command %s: argument %d is unterminated.\n"
+#define MSGTR_INPUT_INPUT_ErrUnknownArg "Unknown argument %d\n"
+#define MSGTR_INPUT_INPUT_Err2FewArgs "Command %s requires at least %d arguments, we found only %d so far.\n"
+#define MSGTR_INPUT_INPUT_ErrReadingCmdFd "Error while reading command file descriptor %d: %s\n"
+#define MSGTR_INPUT_INPUT_ErrCmdBufferFullDroppingContent "Command buffer of file descriptor %d is full: dropping content.\n"
+#define MSGTR_INPUT_INPUT_ErrInvalidCommandForKey "Invalid command for bound key %s"
+#define MSGTR_INPUT_INPUT_ErrSelect "Select error: %s\n"
+#define MSGTR_INPUT_INPUT_ErrOnKeyInFd "Error on key input file descriptor %d\n"
+#define MSGTR_INPUT_INPUT_ErrDeadKeyOnFd "Dead key input on file descriptor %d\n"
+#define MSGTR_INPUT_INPUT_Err2ManyKeyDowns "Too many key down events at the same time\n"
+#define MSGTR_INPUT_INPUT_ErrOnCmdFd "Error on command file descriptor %d\n"
+#define MSGTR_INPUT_INPUT_ErrReadingInputConfig "Error while reading input config file %s: %s\n"
+#define MSGTR_INPUT_INPUT_ErrUnknownKey "Unknown key '%s'\n"
+#define MSGTR_INPUT_INPUT_ErrUnfinishedBinding "Unfinished binding %s\n"
+#define MSGTR_INPUT_INPUT_ErrBuffer2SmallForKeyName "Buffer is too small for this key name: %s\n"
+#define MSGTR_INPUT_INPUT_ErrNoCmdForKey "No command found for key %s"
+#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"
+
+
+// ========================== LIBMPDEMUX ===================================
+
+// muxer.c, muxer_*.c
+#define MSGTR_TooManyStreams "Too many streams!"
+#define MSGTR_RawMuxerOnlyOneStream "Rawaudio muxer supports only one audio stream!\n"
+#define MSGTR_IgnoringVideoStream "Ignoring video stream!\n"
+#define MSGTR_UnknownStreamType "Warning, unknown stream type: %d\n"
+#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"
+
+// demuxer.c, demux_*.c
+#define MSGTR_AudioStreamRedefined "WARNING: Audio stream header %d redefined.\n"
+#define MSGTR_VideoStreamRedefined "WARNING: Video stream header %d redefined.\n"
+#define MSGTR_TooManyAudioInBuffer "\nToo many audio packets in the buffer: (%d in %d bytes).\n"
+#define MSGTR_TooManyVideoInBuffer "\nToo many video packets in the buffer: (%d in %d bytes).\n"
+#define MSGTR_MaybeNI "Maybe you are playing a non-interleaved stream/file or the codec failed?\n" \
+                      "For AVI files, try to force non-interleaved mode with the -ni option.\n"
+#define MSGTR_WorkAroundBlockAlignHeaderBug "AVI: Working around CBR-MP3 nBlockAlign header bug!\n"
+#define MSGTR_SwitchToNi "\nBadly interleaved AVI file detected - switching to -ni mode...\n"
+#define MSGTR_InvalidAudioStreamNosound "AVI: invalid audio stream ID: %d - ignoring (nosound)\n"
+#define MSGTR_InvalidAudioStreamUsingDefault "AVI: invalid video stream ID: %d - ignoring (using default)\n"
+#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"
+#define MSGTR_SettingProcessPriority "Setting process priority: %s\n"
+#define MSGTR_FilefmtFourccSizeFpsFtime "[V] filefmt:%d  fourcc:0x%X  size:%dx%d  fps:%5.3f  ftime:=%6.4f\n"
+#define MSGTR_CannotInitializeMuxer "Cannot initialize muxer."
+#define MSGTR_MissingVideoStream "No video stream found.\n"
+#define MSGTR_MissingAudioStream "No audio stream found -> no sound.\n"
+#define MSGTR_MissingVideoStreamBug "Missing video stream!? Contact the author, it may be a bug :(\n"
+
+#define MSGTR_DoesntContainSelectedStream "demux: File doesn't contain the selected audio or video stream.\n"
+
+#define MSGTR_NI_Forced "Forced"
+#define MSGTR_NI_Detected "Detected"
+#define MSGTR_NI_Message "%s NON-INTERLEAVED AVI file format.\n"
+
+#define MSGTR_UsingNINI "Using NON-INTERLEAVED broken AVI file format.\n"
+#define MSGTR_CouldntDetFNo "Could not determine number of frames (for absolute seek).\n"
+#define MSGTR_CantSeekRawAVI "Cannot seek in raw AVI streams. (Index required, try with the -idx switch.)\n"
+#define MSGTR_CantSeekFile "Cannot seek in this file.\n"
+
+#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"
+#define MSGTR_OpeningSubtitlesDemuxerFailed "Failed to open subtitle demuxer: %s\n"
+#define MSGTR_TVInputNotSeekable "TV input is not seekable! (Seeking will probably be for changing channels ;)\n"
+#define MSGTR_DemuxerInfoChanged "Demuxer info %s changed to %s\n"
+#define MSGTR_ClipInfo "Clip info:\n"
+
+#define MSGTR_LeaveTelecineMode "\ndemux_mpg: 30000/1001fps NTSC content detected, switching framerate.\n"
+#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_FailedToOpen "Failed to open %s.\n"
+
+#define MSGTR_VideoID "[%s] Video stream found, -vid %d\n"
+#define MSGTR_AudioID "[%s] Audio stream found, -aid %d\n"
+#define MSGTR_SubtitleID "[%s] Subtitle stream found, -sid %d\n"
+
+// asfheader.c
+#define MSGTR_MPDEMUX_ASFHDR_HeaderSizeOver1MB "FATAL: header size bigger than 1 MB (%d)!\nPlease contact MPlayer authors, and upload/send this file.\n"
+#define MSGTR_MPDEMUX_ASFHDR_HeaderMallocFailed "Could not allocate %d bytes for header.\n"
+#define MSGTR_MPDEMUX_ASFHDR_EOFWhileReadingHeader "EOF while reading ASF header, broken/incomplete file?\n"
+#define MSGTR_MPDEMUX_ASFHDR_DVRWantsLibavformat "DVR will probably only work with libavformat, try -demuxer 35 if you have problems\n"
+#define MSGTR_MPDEMUX_ASFHDR_NoDataChunkAfterHeader "No data chunk following header!\n"
+#define MSGTR_MPDEMUX_ASFHDR_AudioVideoHeaderNotFound "ASF: no audio or video headers found - broken file?\n"
+#define MSGTR_MPDEMUX_ASFHDR_InvalidLengthInASFHeader "Invalid length in ASF header!\n"
+#define MSGTR_MPDEMUX_ASFHDR_DRMLicenseURL "DRM License URL: %s\n"
+#define MSGTR_MPDEMUX_ASFHDR_DRMProtected "This file has been encumbered with DRM encryption, it will not play in MPlayer!\n"
+
+// 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"
+#define MSGTR_MPDEMUX_AVIHDR_NotValidMPidxFile "%s is not a valid MPlayer index file.\n"
+#define MSGTR_MPDEMUX_AVIHDR_FailedMallocForIdxFile "Could not allocate memory for index data from %s.\n"
+#define MSGTR_MPDEMUX_AVIHDR_PrematureEOF "premature end of index file %s\n"
+#define MSGTR_MPDEMUX_AVIHDR_IdxFileLoaded "Loaded index file: %s\n"
+#define MSGTR_MPDEMUX_AVIHDR_GeneratingIdx "Generating Index: %3lu %s     \r"
+#define MSGTR_MPDEMUX_AVIHDR_IdxGeneratedForHowManyChunks "AVI: Generated index table for %d chunks!\n"
+#define MSGTR_MPDEMUX_AVIHDR_Failed2WriteIdxFile "Couldn't write index file %s: %s\n"
+#define MSGTR_MPDEMUX_AVIHDR_IdxFileSaved "Saved index file: %s\n"
+
+// demux_audio.c
+#define MSGTR_MPDEMUX_AUDIO_UnknownFormat "Audio demuxer: unknown format %d.\n"
+
+// demux_demuxers.c
+#define MSGTR_MPDEMUX_DEMUXERS_FillBufferError "fill_buffer error: bad demuxer: not vd, ad or sd.\n"
+
+// demux_mkv.c
+#define MSGTR_MPDEMUX_MKV_ZlibInitializationFailed "[mkv] zlib initialization failed.\n"
+#define MSGTR_MPDEMUX_MKV_ZlibDecompressionFailed "[mkv] zlib decompression failed.\n"
+#define MSGTR_MPDEMUX_MKV_LzoInitializationFailed "[mkv] lzo initialization failed.\n"
+#define MSGTR_MPDEMUX_MKV_LzoDecompressionFailed "[mkv] lzo decompression failed.\n"
+#define MSGTR_MPDEMUX_MKV_TrackEncrypted "[mkv] Track number %u has been encrypted  and decryption has not yet been\n[mkv] implemented. Skipping track.\n"
+#define MSGTR_MPDEMUX_MKV_UnknownContentEncoding "[mkv] Unknown content encoding type for track %u. Skipping track.\n"
+#define MSGTR_MPDEMUX_MKV_UnknownCompression "[mkv] Track %u has been compressed with an unknown/unsupported compression\n[mkv] algorithm (%u). Skipping track.\n"
+#define MSGTR_MPDEMUX_MKV_ZlibCompressionUnsupported "[mkv] Track %u was compressed with zlib but mplayer has not been compiled\n[mkv] with support for zlib compression. Skipping track.\n"
+#define MSGTR_MPDEMUX_MKV_TrackIDName "[mkv] Track ID %u: %s (%s) \"%s\", %s\n"
+#define MSGTR_MPDEMUX_MKV_TrackID "[mkv] Track ID %u: %s (%s), %s\n"
+#define MSGTR_MPDEMUX_MKV_UnknownCodecID "[mkv] Unknown/unsupported CodecID (%s) or missing/bad CodecPrivate\n[mkv] data (track %u).\n"
+#define MSGTR_MPDEMUX_MKV_FlacTrackDoesNotContainValidHeaders "[mkv] FLAC track does not contain valid headers.\n"
+#define MSGTR_MPDEMUX_MKV_UnknownAudioCodec "[mkv] Unknown/unsupported audio codec ID '%s' for track %u or missing/faulty\n[mkv] private codec data.\n"
+#define MSGTR_MPDEMUX_MKV_SubtitleTypeNotSupported "[mkv] Subtitle type '%s' is not supported.\n"
+#define MSGTR_MPDEMUX_MKV_WillPlayVideoTrack "[mkv] Will play video track %u.\n"
+#define MSGTR_MPDEMUX_MKV_NoVideoTrackFound "[mkv] No video track found/wanted.\n"
+#define MSGTR_MPDEMUX_MKV_NoAudioTrackFound "[mkv] No audio track found/wanted.\n"
+#define MSGTR_MPDEMUX_MKV_WillDisplaySubtitleTrack "[mkv] Will display subtitle track %u.\n"
+#define MSGTR_MPDEMUX_MKV_NoBlockDurationForSubtitleTrackFound "[mkv] Warning: No BlockDuration for subtitle track found.\n"
+#define MSGTR_MPDEMUX_MKV_TooManySublines "[mkv] Warning: too many sublines to render, skipping.\n"
+#define MSGTR_MPDEMUX_MKV_TooManySublinesSkippingAfterFirst "\n[mkv] Warning: too many sublines to render, skipping after first %i.\n"
+
+// demux_nuv.c
+#define MSGTR_MPDEMUX_NUV_NoVideoBlocksInFile "No video blocks in file.\n"
+
+// demux_xmms.c
+#define MSGTR_MPDEMUX_XMMS_FoundPlugin "Found plugin: %s (%s).\n"
+#define MSGTR_MPDEMUX_XMMS_ClosingPlugin "Closing plugin: %s.\n"
+#define MSGTR_MPDEMUX_XMMS_WaitForStart "Waiting for the XMMS plugin to start playback of '%s'...\n"
+
+
+// ========================== LIBMENU ===================================
+
+// common
+#define MSGTR_LIBMENU_NoEntryFoundInTheMenuDefinition "[MENU] No entry found in the menu definition.\n"
+
+// libmenu/menu.c
+#define MSGTR_LIBMENU_SyntaxErrorAtLine "[MENU] syntax error at line: %d\n"
+#define MSGTR_LIBMENU_MenuDefinitionsNeedANameAttrib "[MENU] Menu definitions need a name attribute (line %d).\n"
+#define MSGTR_LIBMENU_BadAttrib "[MENU] bad attribute %s=%s in menu '%s' at line %d\n"
+#define MSGTR_LIBMENU_UnknownMenuType "[MENU] unknown menu type '%s' at line %d\n"
+#define MSGTR_LIBMENU_CantOpenConfigFile "[MENU] Can't open menu config file: %s\n"
+#define MSGTR_LIBMENU_ConfigFileIsTooBig "[MENU] Config file is too big (> %d KB)\n"
+#define MSGTR_LIBMENU_ConfigFileIsEmpty "[MENU] Config file is empty.\n"
+#define MSGTR_LIBMENU_MenuNotFound "[MENU] Menu %s not found.\n"
+#define MSGTR_LIBMENU_MenuInitFailed "[MENU] Menu '%s': Init failed.\n"
+#define MSGTR_LIBMENU_UnsupportedOutformat "[MENU] Unsupported output format!!!!\n"
+
+// libmenu/menu_cmdlist.c
+#define MSGTR_LIBMENU_ListMenuEntryDefinitionsNeedAName "[MENU] List menu entry definitions need a name (line %d).\n"
+#define MSGTR_LIBMENU_ListMenuNeedsAnArgument "[MENU] List menu needs an argument.\n"
+
+// libmenu/menu_console.c
+#define MSGTR_LIBMENU_WaitPidError "[MENU] Waitpid error: %s.\n"
+#define MSGTR_LIBMENU_SelectError "[MENU] Select error.\n"
+#define MSGTR_LIBMENU_ReadErrorOnChildFD "[MENU] Read error on child's file descriptor: %s.\n"
+#define MSGTR_LIBMENU_ConsoleRun "[MENU] Console run: %s ...\n"
+#define MSGTR_LIBMENU_AChildIsAlreadyRunning "[MENU] A child is already running.\n"
+#define MSGTR_LIBMENU_ForkFailed "[MENU] Fork failed !!!\n"
+#define MSGTR_LIBMENU_WriteError "[MENU] write error\n"
+
+// libmenu/menu_filesel.c
+#define MSGTR_LIBMENU_OpendirError "[MENU] opendir error: %s\n"
+#define MSGTR_LIBMENU_ReallocError "[MENU] realloc error: %s\n"
+#define MSGTR_LIBMENU_MallocError "[MENU] memory allocation error: %s\n"
+#define MSGTR_LIBMENU_ReaddirError "[MENU] readdir error: %s\n"
+#define MSGTR_LIBMENU_CantOpenDirectory "[MENU] Can't open directory %s.\n"
+
+// libmenu/menu_param.c
+#define MSGTR_LIBMENU_SubmenuDefinitionNeedAMenuAttribut "[MENU] Submenu definition needs a 'menu' attribute.\n"
+#define MSGTR_LIBMENU_InvalidProperty "[MENU] Invalid property '%s' in pref menu entry. (line %d).\n"
+#define MSGTR_LIBMENU_PrefMenuEntryDefinitionsNeed "[MENU] Pref menu entry definitions need a valid 'property' or 'txt' attribute (line %d).\n"
+#define MSGTR_LIBMENU_PrefMenuNeedsAnArgument "[MENU] Pref menu needs an argument.\n"
+
+// libmenu/menu_pt.c
+#define MSGTR_LIBMENU_CantfindTheTargetItem "[MENU] Can't find the target item ????\n"
+#define MSGTR_LIBMENU_FailedToBuildCommand "[MENU] Failed to build command: %s.\n"
+
+// libmenu/menu_txt.c
+#define MSGTR_LIBMENU_MenuTxtNeedATxtFileName "[MENU] Text menu needs a textfile name (parameter file).\n"
+#define MSGTR_LIBMENU_MenuTxtCantOpen "[MENU] Can't open %s.\n"
+#define MSGTR_LIBMENU_WarningTooLongLineSplitting "[MENU] Warning, line too long. Splitting it.\n"
+#define MSGTR_LIBMENU_ParsedLines "[MENU] Parsed %d lines.\n"
+
+// libmenu/vf_menu.c
+#define MSGTR_LIBMENU_UnknownMenuCommand "[MENU] Unknown command: '%s'.\n"
+#define MSGTR_LIBMENU_FailedToOpenMenu "[MENU] Failed to open menu: '%s'.\n"
+
+
+// ========================== LIBMPCODECS ===================================
+
+// dec_video.c & dec_audio.c:
+#define MSGTR_CantOpenCodec "Could not open codec.\n"
+#define MSGTR_CantCloseCodec "Could not close codec.\n"
+
+#define MSGTR_MissingDLLcodec "ERROR: Could not open required DirectShow codec %s.\n"
+#define MSGTR_ACMiniterror "Could not load/initialize Win32/ACM audio codec (missing DLL file?).\n"
+#define MSGTR_MissingLAVCcodec "Cannot find codec '%s' in libavcodec...\n"
+
+#define MSGTR_MpegNoSequHdr "MPEG: FATAL: EOF while searching for sequence header.\n"
+#define MSGTR_CannotReadMpegSequHdr "FATAL: Cannot read sequence header.\n"
+#define MSGTR_CannotReadMpegSequHdrEx "FATAL: Cannot read sequence header extension.\n"
+#define MSGTR_BadMpegSequHdr "MPEG: bad sequence header\n"
+#define MSGTR_BadMpegSequHdrEx "MPEG: bad sequence header extension\n"
+
+#define MSGTR_ShMemAllocFail "Cannot allocate shared memory.\n"
+#define MSGTR_CantAllocAudioBuf "Cannot allocate audio out buffer.\n"
+
+#define MSGTR_UnknownAudio "Unknown/missing audio format -> no sound\n"
+
+#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"
+
+// libmpcodecs/ad_libdv.c
+#define MSGTR_MPCODECS_AudioFramesizeDiffers "[AD_LIBDV] Warning! Audio framesize differs! read=%d  hdr=%d.\n"
+
+// vd.c
+#define MSGTR_CodecDidNotSet "VDec: Codec did not set sh->disp_w and sh->disp_h, trying workaround.\n"
+#define MSGTR_CouldNotFindColorspace "Could not find matching colorspace - retrying with -vf scale...\n"
+#define MSGTR_MovieAspectIsSet "Movie-Aspect is %.2f:1 - prescaling to correct movie aspect.\n"
+#define MSGTR_MovieAspectUndefined "Movie-Aspect is undefined - no prescaling applied.\n"
+
+// 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"
+
+// libmpcodecs/vd_ffmpeg.c
+#define MSGTR_MPCODECS_XVMCAcceleratedCodec "[VD_FFMPEG] XVMC accelerated codec.\n"
+#define MSGTR_MPCODECS_ArithmeticMeanOfQP "[VD_FFMPEG] Arithmetic mean of QP: %2.4f, Harmonic mean of QP: %2.4f\n"
+#define MSGTR_MPCODECS_DRIFailure "[VD_FFMPEG] DRI failure.\n"
+#define MSGTR_MPCODECS_CouldntAllocateImageForCodec "[VD_FFMPEG] Couldn't allocate image for codec.\n"
+#define MSGTR_MPCODECS_XVMCAcceleratedMPEG2 "[VD_FFMPEG] XVMC-accelerated MPEG-2.\n"
+#define MSGTR_MPCODECS_TryingPixfmt "[VD_FFMPEG] Trying pixfmt=%d.\n"
+#define MSGTR_MPCODECS_McGetBufferShouldWorkOnlyWithXVMC "[VD_FFMPEG] The mc_get_buffer should work only with XVMC acceleration!!"
+#define MSGTR_MPCODECS_UnexpectedInitVoError "[VD_FFMPEG] Unexpected init_vo error.\n"
+#define MSGTR_MPCODECS_UnrecoverableErrorRenderBuffersNotTaken "[VD_FFMPEG] Unrecoverable error, render buffers not taken.\n"
+#define MSGTR_MPCODECS_OnlyBuffersAllocatedByVoXvmcAllowed "[VD_FFMPEG] Only buffers allocated by vo_xvmc allowed.\n"
+
+// libmpcodecs/ve_lavc.c
+#define MSGTR_MPCODECS_HighQualityEncodingSelected "[VE_LAVC] High quality encoding selected (non-realtime)!\n"
+#define MSGTR_MPCODECS_UsingConstantQscale "[VE_LAVC] Using constant qscale = %f (VBR).\n"
+
+// libmpcodecs/ve_raw.c
+#define MSGTR_MPCODECS_OutputWithFourccNotSupported "[VE_RAW] Raw output with FourCC [%x] not supported!\n"
+#define MSGTR_MPCODECS_NoVfwCodecSpecified "[VE_RAW] Required VfW codec not specified!!\n"
+
+// vf.c
+#define MSGTR_CouldNotFindVideoFilter "Couldn't find video filter '%s'.\n"
+#define MSGTR_CouldNotOpenVideoFilter "Couldn't open video filter '%s'.\n"
+#define MSGTR_OpeningVideoFilter "Opening video filter: "
+#define MSGTR_CannotFindColorspace "Cannot find matching colorspace, even by inserting 'scale' :(\n"
+
+// libmpcodecs/vf_crop.c
+#define MSGTR_MPCODECS_CropBadPositionWidthHeight "[CROP] Bad position/width/height - cropped area outside of the original!\n"
+
+// libmpcodecs/vf_cropdetect.c
+#define MSGTR_MPCODECS_CropArea "[CROP] Crop area: X: %d..%d  Y: %d..%d  (-vf crop=%d:%d:%d:%d).\n"
+
+// libmpcodecs/vf_format.c, vf_palette.c, vf_noformat.c
+#define MSGTR_MPCODECS_UnknownFormatName "[VF_FORMAT] Unknown format name: '%s'.\n"
+
+// libmpcodecs/vf_framestep.c vf_noformat.c vf_palette.c vf_tile.c
+#define MSGTR_MPCODECS_ErrorParsingArgument "[VF_FRAMESTEP] Error parsing argument.\n"
+
+// libmpcodecs/ve_vfw.c
+#define MSGTR_MPCODECS_CompressorType "Compressor type: %.4lx\n"
+#define MSGTR_MPCODECS_CompressorSubtype "Compressor subtype: %.4lx\n"
+#define MSGTR_MPCODECS_CompressorFlags "Compressor flags: %lu, version %lu, ICM version: %lu\n"
+#define MSGTR_MPCODECS_Flags "Flags:"
+#define MSGTR_MPCODECS_Quality " quality"
+
+// libmpcodecs/vf_expand.c
+#define MSGTR_MPCODECS_FullDRNotPossible "Full DR not possible, trying SLICES instead!\n"
+#define MSGTR_MPCODECS_WarnNextFilterDoesntSupportSlices  "WARNING! Next filter doesn't support SLICES, get ready for sig11...\n"
+#define MSGTR_MPCODECS_FunWhydowegetNULL "Why do we get NULL??\n"
+
+// libmpcodecs/vf_test.c, vf_yuy2.c, vf_yvu9.c
+#define MSGTR_MPCODECS_WarnNextFilterDoesntSupport "%s not supported by next filter/vo :(\n"
+
+
+// ================================== LIBASS ====================================
+
+// ass_bitmap.c
+#define MSGTR_LIBASS_FT_Glyph_To_BitmapError "[ass] FT_Glyph_To_Bitmap error %d \n"
+#define MSGTR_LIBASS_UnsupportedPixelMode "[ass] Unsupported pixel mode: %d\n"
+#define MSGTR_LIBASS_GlyphBBoxTooLarge "[ass] Glyph bounding box too large: %dx%dpx\n"
+
+// ass.c
+#define MSGTR_LIBASS_NoStyleNamedXFoundUsingY "[ass] [%p] Warning: no style named '%s' found, using '%s'\n"
+#define MSGTR_LIBASS_BadTimestamp "[ass] bad timestamp\n"
+#define MSGTR_LIBASS_BadEncodedDataSize "[ass] bad encoded data size\n"
+#define MSGTR_LIBASS_FontLineTooLong "[ass] Font line too long: %d, %s\n"
+#define MSGTR_LIBASS_EventFormatHeaderMissing "[ass] Event format header missing\n"
+#define MSGTR_LIBASS_ErrorOpeningIconvDescriptor "[ass] error opening iconv descriptor.\n"
+#define MSGTR_LIBASS_ErrorRecodingFile "[ass] error recoding file.\n"
+#define MSGTR_LIBASS_FopenFailed "[ass] ass_read_file(%s): fopen failed\n"
+#define MSGTR_LIBASS_FseekFailed "[ass] ass_read_file(%s): fseek failed\n"
+#define MSGTR_LIBASS_RefusingToLoadSubtitlesLargerThan100M "[ass] ass_read_file(%s): Refusing to load subtitles larger than 100M\n"
+#define MSGTR_LIBASS_ReadFailed "Read failed, %d: %s\n"
+#define MSGTR_LIBASS_AddedSubtitleFileMemory "[ass] Added subtitle file: <memory> (%d styles, %d events)\n"
+#define MSGTR_LIBASS_AddedSubtitleFileFname "[ass] Added subtitle file: %s (%d styles, %d events)\n"
+#define MSGTR_LIBASS_FailedToCreateDirectory "[ass] Failed to create directory %s\n"
+#define MSGTR_LIBASS_NotADirectory "[ass] Not a directory: %s\n"
+
+// ass_cache.c
+#define MSGTR_LIBASS_TooManyFonts "[ass] Too many fonts\n"
+#define MSGTR_LIBASS_ErrorOpeningFont "[ass] Error opening font: %s, %d\n"
+
+// ass_fontconfig.c
+#define MSGTR_LIBASS_SelectedFontFamilyIsNotTheRequestedOne "[ass] fontconfig: Selected font is not the requested one: '%s' != '%s'\n"
+#define MSGTR_LIBASS_UsingDefaultFontFamily "[ass] fontconfig_select: Using default font family: (%s, %d, %d) -> %s, %d\n"
+#define MSGTR_LIBASS_UsingDefaultFont "[ass] fontconfig_select: Using default font: (%s, %d, %d) -> %s, %d\n"
+#define MSGTR_LIBASS_UsingArialFontFamily "[ass] fontconfig_select: Using 'Arial' font family: (%s, %d, %d) -> %s, %d\n"
+#define MSGTR_LIBASS_FcInitLoadConfigAndFontsFailed "[ass] FcInitLoadConfigAndFonts failed.\n"
+#define MSGTR_LIBASS_UpdatingFontCache "[ass] Updating font cache.\n"
+#define MSGTR_LIBASS_BetaVersionsOfFontconfigAreNotSupported "[ass] Beta versions of fontconfig are not supported.\n[ass] Update before reporting any bugs.\n"
+#define MSGTR_LIBASS_FcStrSetAddFailed "[ass] FcStrSetAdd failed.\n"
+#define MSGTR_LIBASS_FcDirScanFailed "[ass] FcDirScan failed.\n"
+#define MSGTR_LIBASS_FcDirSave "[ass] FcDirSave failed.\n"
+#define MSGTR_LIBASS_FcConfigAppFontAddDirFailed "[ass] FcConfigAppFontAddDir failed\n"
+#define MSGTR_LIBASS_FontconfigDisabledDefaultFontWillBeUsed "[ass] Fontconfig disabled, only default font will be used.\n"
+#define MSGTR_LIBASS_FunctionCallFailed "[ass] %s failed\n"
+
+// ass_render.c
+#define MSGTR_LIBASS_NeitherPlayResXNorPlayResYDefined "[ass] Neither PlayResX nor PlayResY defined. Assuming 384x288.\n"
+#define MSGTR_LIBASS_PlayResYUndefinedSettingY "[ass] PlayResY undefined, setting %d.\n"
+#define MSGTR_LIBASS_PlayResXUndefinedSettingX "[ass] PlayResX undefined, setting %d.\n"
+#define MSGTR_LIBASS_FT_Init_FreeTypeFailed "[ass] FT_Init_FreeType failed.\n"
+#define MSGTR_LIBASS_Init "[ass] Init\n"
+#define MSGTR_LIBASS_InitFailed "[ass] Init failed.\n"
+#define MSGTR_LIBASS_BadCommand "[ass] Bad command: %c%c\n"
+#define MSGTR_LIBASS_ErrorLoadingGlyph  "[ass] Error loading glyph.\n"
+#define MSGTR_LIBASS_FT_Glyph_Stroke_Error "[ass] FT_Glyph_Stroke error %d \n"
+#define MSGTR_LIBASS_UnknownEffectType_InternalError "[ass] Unknown effect type (internal error)\n"
+#define MSGTR_LIBASS_NoStyleFound "[ass] No style found!\n"
+#define MSGTR_LIBASS_EmptyEvent "[ass] Empty event!\n"
+#define MSGTR_LIBASS_MAX_GLYPHS_Reached "[ass] MAX_GLYPHS reached: event %d, start = %llu, duration = %llu\n Text = %s\n"
+#define MSGTR_LIBASS_EventHeightHasChanged "[ass] Warning! Event height has changed!  \n"
+
+// ass_font.c
+#define MSGTR_LIBASS_GlyphNotFoundReselectingFont "[ass] Glyph 0x%X not found, selecting one more font for (%s, %d, %d)\n"
+#define MSGTR_LIBASS_GlyphNotFound "[ass] Glyph 0x%X not found in font for (%s, %d, %d)\n"
+#define MSGTR_LIBASS_ErrorOpeningMemoryFont "[ass] Error opening memory font: %s\n"
+#define MSGTR_LIBASS_NoCharmaps "[ass] font face with no charmaps\n"
+#define MSGTR_LIBASS_NoCharmapAutodetected "[ass] no charmap autodetected, trying the first one\n"
+
+
+// ================================== 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_alsa1x.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"
+#define MSGTR_MPDEMUX_AIALSA_UnavailableChanCount "Channel count not available - reverting to default: %d\n"
+#define MSGTR_MPDEMUX_AIALSA_CannotInstallHWParams "Unable to install hardware parameters: %s"
+#define MSGTR_MPDEMUX_AIALSA_PeriodEqualsBufferSize "Can't use period equal to buffer size (%u == %lu)\n"
+#define MSGTR_MPDEMUX_AIALSA_CannotInstallSWParams "Unable to install software parameters:\n"
+#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"
+
+// ai_oss.c
+#define MSGTR_MPDEMUX_AIOSS_Unable2SetChanCount "Unable to set channel count: %d\n"
+#define MSGTR_MPDEMUX_AIOSS_Unable2SetStereo "Unable to set stereo: %d\n"
+#define MSGTR_MPDEMUX_AIOSS_Unable2Open "Unable to open '%s': %s\n"
+#define MSGTR_MPDEMUX_AIOSS_UnsupportedFmt "unsupported format\n"
+#define MSGTR_MPDEMUX_AIOSS_Unable2SetAudioFmt "Unable to set audio format."
+#define MSGTR_MPDEMUX_AIOSS_Unable2SetSamplerate "Unable to set samplerate: %d\n"
+#define MSGTR_MPDEMUX_AIOSS_Unable2SetTrigger "Unable to set trigger: %d\n"
+#define MSGTR_MPDEMUX_AIOSS_Unable2GetBlockSize "Unable to get block size!\n"
+#define MSGTR_MPDEMUX_AIOSS_AudioBlockSizeZero "Audio block size is zero, setting to %d!\n"
+#define MSGTR_MPDEMUX_AIOSS_AudioBlockSize2Low "Audio block size too low, setting to %d!\n"
+
+// asf_mmst_streaming.c
+#define MSGTR_MPDEMUX_MMST_WriteError "write error\n"
+#define MSGTR_MPDEMUX_MMST_EOFAlert "\nAlert! EOF\n"
+#define MSGTR_MPDEMUX_MMST_PreHeaderReadFailed "pre-header read failed\n"
+#define MSGTR_MPDEMUX_MMST_InvalidHeaderSize "Invalid header size, giving up.\n"
+#define MSGTR_MPDEMUX_MMST_HeaderDataReadFailed "Header data read failed.\n"
+#define MSGTR_MPDEMUX_MMST_packet_lenReadFailed "packet_len read failed.\n"
+#define MSGTR_MPDEMUX_MMST_InvalidRTSPPacketSize "Invalid RTSP packet size, giving up.\n"
+#define MSGTR_MPDEMUX_MMST_CmdDataReadFailed "Command data read failed.\n"
+#define MSGTR_MPDEMUX_MMST_HeaderObject "header object\n"
+#define MSGTR_MPDEMUX_MMST_DataObject "data object\n"
+#define MSGTR_MPDEMUX_MMST_FileObjectPacketLen "file object, packet length = %d (%d)\n"
+#define MSGTR_MPDEMUX_MMST_StreamObjectStreamID "stream object, stream ID: %d\n"
+#define MSGTR_MPDEMUX_MMST_2ManyStreamID "Too many IDs, stream skipped."
+#define MSGTR_MPDEMUX_MMST_UnknownObject "unknown object\n"
+#define MSGTR_MPDEMUX_MMST_MediaDataReadFailed "Media data read failed.\n"
+#define MSGTR_MPDEMUX_MMST_MissingSignature "missing signature\n"
+#define MSGTR_MPDEMUX_MMST_PatentedTechnologyJoke "Everything done. Thank you for downloading a media file containing proprietary and patented technology.\n"
+#define MSGTR_MPDEMUX_MMST_UnknownCmd "unknown command %02x\n"
+#define MSGTR_MPDEMUX_MMST_GetMediaPacketErr "get_media_packet error : %s\n"
+#define MSGTR_MPDEMUX_MMST_Connected "Connected\n"
+
+// asf_streaming.c
+#define MSGTR_MPDEMUX_ASF_StreamChunkSize2Small "Ahhhh, stream_chunck size is too small: %d\n"
+#define MSGTR_MPDEMUX_ASF_SizeConfirmMismatch "size_confirm mismatch!: %d %d\n"
+#define MSGTR_MPDEMUX_ASF_WarnDropHeader "Warning: drop header ????\n"
+#define MSGTR_MPDEMUX_ASF_ErrorParsingChunkHeader "Error while parsing chunk header\n"
+#define MSGTR_MPDEMUX_ASF_NoHeaderAtFirstChunk "Didn't get a header as first chunk !!!!\n"
+#define MSGTR_MPDEMUX_ASF_BufferMallocFailed "Error: Can't allocate %d bytes buffer.\n"
+#define MSGTR_MPDEMUX_ASF_ErrReadingNetworkStream "Error while reading network stream.\n"
+#define MSGTR_MPDEMUX_ASF_ErrChunk2Small "Error: Chunk is too small.\n"
+#define MSGTR_MPDEMUX_ASF_ErrSubChunkNumberInvalid "Error: Subchunk number is invalid.\n"
+#define MSGTR_MPDEMUX_ASF_Bandwidth2SmallCannotPlay "Bandwidth too small, file cannot be played!\n"
+#define MSGTR_MPDEMUX_ASF_Bandwidth2SmallDeselectedAudio "Bandwidth too small, deselected audio stream.\n"
+#define MSGTR_MPDEMUX_ASF_Bandwidth2SmallDeselectedVideo "Bandwidth too small, deselected video stream.\n"
+#define MSGTR_MPDEMUX_ASF_InvalidLenInHeader "Invalid length in ASF header!\n"
+#define MSGTR_MPDEMUX_ASF_ErrReadingChunkHeader "Error while reading chunk header.\n"
+#define MSGTR_MPDEMUX_ASF_ErrChunkBiggerThanPacket "Error: chunk_size > packet_size\n"
+#define MSGTR_MPDEMUX_ASF_ErrReadingChunk "Error while reading chunk.\n"
+#define MSGTR_MPDEMUX_ASF_ASFRedirector "=====> ASF Redirector\n"
+#define MSGTR_MPDEMUX_ASF_InvalidProxyURL "invalid proxy URL\n"
+#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_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"
+#define MSGTR_MPDEMUX_ASF_UnknownASFStreamingType "unknown ASF streaming type\n"
+#define MSGTR_MPDEMUX_ASF_InfoStreamASFURL "STREAM_ASF, URL: %s\n"
+#define MSGTR_MPDEMUX_ASF_StreamingFailed "Failed, exiting.\n"
+
+// audio_in.c
+#define MSGTR_MPDEMUX_AUDIOIN_ErrReadingAudio "\nError reading audio: %s\n"
+#define MSGTR_MPDEMUX_AUDIOIN_XRUNSomeFramesMayBeLeftOut "Recovered from cross-run, some frames may be left out!\n"
+#define MSGTR_MPDEMUX_AUDIOIN_ErrFatalCannotRecover "Fatal error, cannot recover!\n"
+#define MSGTR_MPDEMUX_AUDIOIN_NotEnoughSamples "\nNot enough audio samples!\n"
+
+// cache2.c
+#define MSGTR_MPDEMUX_CACHE2_NonCacheableStream "\rThis stream is non-cacheable.\n"
+#define MSGTR_MPDEMUX_CACHE2_ReadFileposDiffers "!!! read_filepos differs!!! Report this bug...\n"
+
+// network.c
+#define MSGTR_MPDEMUX_NW_UnknownAF "Unknown address family %d\n"
+#define MSGTR_MPDEMUX_NW_ResolvingHostForAF "Resolving %s for %s...\n"
+#define MSGTR_MPDEMUX_NW_CantResolv "Couldn't resolve name for %s: %s\n"
+#define MSGTR_MPDEMUX_NW_ConnectingToServer "Connecting to server %s[%s]: %d...\n"
+#define MSGTR_MPDEMUX_NW_CantConnect2Server "Failed to connect to server with %s\n"
+#define MSGTR_MPDEMUX_NW_SelectFailed "Select failed.\n"
+#define MSGTR_MPDEMUX_NW_ConnTimeout "connection timeout\n"
+#define MSGTR_MPDEMUX_NW_GetSockOptFailed "getsockopt failed: %s\n"
+#define MSGTR_MPDEMUX_NW_ConnectError "connect error: %s\n"
+#define MSGTR_MPDEMUX_NW_InvalidProxySettingTryingWithout "Invalid proxy setting... Trying without proxy.\n"
+#define MSGTR_MPDEMUX_NW_CantResolvTryingWithoutProxy "Could not resolve remote hostname for AF_INET. Trying without proxy.\n"
+#define MSGTR_MPDEMUX_NW_ErrSendingHTTPRequest "Error while sending HTTP request: Didn't send all the request.\n"
+#define MSGTR_MPDEMUX_NW_ReadFailed "Read failed.\n"
+#define MSGTR_MPDEMUX_NW_Read0CouldBeEOF "http_read_response read 0 (i.e. EOF).\n"
+#define MSGTR_MPDEMUX_NW_AuthFailed "Authentication failed. Please use the -user and -passwd options to provide your\n"\
+"username/password for a list of URLs, or form an URL like:\n"\
+"http://username:password@hostname/file\n"
+#define MSGTR_MPDEMUX_NW_AuthRequiredFor "Authentication required for %s\n"
+#define MSGTR_MPDEMUX_NW_AuthRequired "Authentication required.\n"
+#define MSGTR_MPDEMUX_NW_NoPasswdProvidedTryingBlank "No password provided, trying blank password.\n"
+#define MSGTR_MPDEMUX_NW_ErrServerReturned "Server returns %d: %s\n"
+#define MSGTR_MPDEMUX_NW_CacheSizeSetTo "Cache size set to %d KBytes\n"
+
+// open.c, stream.c:
+#define MSGTR_CdDevNotfound "CD-ROM Device '%s' not found.\n"
+#define MSGTR_ErrTrackSelect "Error selecting VCD track."
+#define MSGTR_ReadSTDIN "Reading from stdin...\n"
+#define MSGTR_UnableOpenURL "Unable to open URL: %s\n"
+#define MSGTR_ConnToServer "Connected to server: %s\n"
+#define MSGTR_FileNotFound "File not found: '%s'\n"
+
+#define MSGTR_SMBInitError "Cannot init the libsmbclient library: %d\n"
+#define MSGTR_SMBFileNotFound "Could not open from LAN: '%s'\n"
+#define MSGTR_SMBNotCompiled "MPlayer was not compiled with SMB reading support.\n"
+
+#define MSGTR_CantOpenBluray "Couldn't open Blu-ray device: %s\n"
+#define MSGTR_CantOpenDVD "Couldn't open DVD device: %s (%s)\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"
+#define MSGTR_MPDEMUX_CDDA_AudioCDFoundWithNTracks "Found audio CD with %d tracks.\n"
+
+// stream_cddb.c
+#define MSGTR_MPDEMUX_CDDB_FailedToReadTOC "Failed to read TOC.\n"
+#define MSGTR_MPDEMUX_CDDB_FailedToOpenDevice "Failed to open %s device.\n"
+#define MSGTR_MPDEMUX_CDDB_NotAValidURL "not a valid URL\n"
+#define MSGTR_MPDEMUX_CDDB_FailedToSendHTTPRequest "Failed to send the HTTP request.\n"
+#define MSGTR_MPDEMUX_CDDB_FailedToReadHTTPResponse "Failed to read the HTTP response.\n"
+#define MSGTR_MPDEMUX_CDDB_HTTPErrorNOTFOUND "Not Found.\n"
+#define MSGTR_MPDEMUX_CDDB_HTTPErrorUnknown "unknown error code\n"
+#define MSGTR_MPDEMUX_CDDB_NoCacheFound "No cache found.\n"
+#define MSGTR_MPDEMUX_CDDB_NotAllXMCDFileHasBeenRead "Not all the xmcd file has been read.\n"
+#define MSGTR_MPDEMUX_CDDB_FailedToCreateDirectory "Failed to create directory %s.\n"
+#define MSGTR_MPDEMUX_CDDB_NotAllXMCDFileHasBeenWritten "Not all of the xmcd file has been written.\n"
+#define MSGTR_MPDEMUX_CDDB_InvalidXMCDDatabaseReturned "Invalid xmcd database file returned.\n"
+#define MSGTR_MPDEMUX_CDDB_UnexpectedFIXME "unexpected FIXME\n"
+#define MSGTR_MPDEMUX_CDDB_UnhandledCode "unhandled code\n"
+#define MSGTR_MPDEMUX_CDDB_UnableToFindEOL "Unable to find end of line.\n"
+#define MSGTR_MPDEMUX_CDDB_ParseOKFoundAlbumTitle "Parse OK, found: %s\n"
+#define MSGTR_MPDEMUX_CDDB_AlbumNotFound "Album not found.\n"
+#define MSGTR_MPDEMUX_CDDB_ServerReturnsCommandSyntaxErr "Server returns: Command syntax error\n"
+#define MSGTR_MPDEMUX_CDDB_NoSitesInfoAvailable "No sites information available.\n"
+#define MSGTR_MPDEMUX_CDDB_FailedToGetProtocolLevel "Failed to get the protocol level.\n"
+#define MSGTR_MPDEMUX_CDDB_NoCDInDrive "No CD in the drive.\n"
+
+// stream_cue.c
+#define MSGTR_MPDEMUX_CUEREAD_UnexpectedCuefileLine "[bincue] Unexpected cuefile line: %s\n"
+#define MSGTR_MPDEMUX_CUEREAD_BinFilenameTested "[bincue] bin filename tested: %s\n"
+#define MSGTR_MPDEMUX_CUEREAD_CannotFindBinFile "[bincue] Couldn't find the bin file - giving up.\n"
+#define MSGTR_MPDEMUX_CUEREAD_UsingBinFile "[bincue] Using bin file %s.\n"
+#define MSGTR_MPDEMUX_CUEREAD_UnknownModeForBinfile "[bincue] unknown mode for binfile. Should not happen. Aborting.\n"
+#define MSGTR_MPDEMUX_CUEREAD_CannotOpenCueFile "[bincue] Cannot open %s.\n"
+#define MSGTR_MPDEMUX_CUEREAD_ErrReadingFromCueFile "[bincue] Error reading from  %s\n"
+#define MSGTR_MPDEMUX_CUEREAD_ErrGettingBinFileSize "[bincue] Error getting size of bin file.\n"
+#define MSGTR_MPDEMUX_CUEREAD_InfoTrackFormat "track %02d:  format=%d  %02d:%02d:%02d\n"
+#define MSGTR_MPDEMUX_CUEREAD_UnexpectedBinFileEOF "[bincue] unexpected end of bin file\n"
+#define MSGTR_MPDEMUX_CUEREAD_CannotReadNBytesOfPayload "[bincue] Couldn't read %d bytes of payload.\n"
+#define MSGTR_MPDEMUX_CUEREAD_CueStreamInfo_FilenameTrackTracksavail "CUE stream_open, filename=%s, track=%d, available tracks: %d -> %d\n"
+
+// stream_dvd.c
+#define MSGTR_DVDspeedCantOpen "Couldn't open DVD device for writing, changing DVD speed needs write access.\n"
+#define MSGTR_DVDrestoreSpeed "Restoring DVD speed... "
+#define MSGTR_DVDlimitSpeed "Limiting DVD speed to %dKB/s... "
+#define MSGTR_DVDlimitFail "failed\n"
+#define MSGTR_DVDlimitOk "successful\n"
+#define MSGTR_NoDVDSupport "MPlayer was compiled without DVD support, exiting.\n"
+#define MSGTR_DVDnumTitles "There are %d titles on this DVD.\n"
+#define MSGTR_DVDinvalidTitle "Invalid DVD title number: %d\n"
+#define MSGTR_DVDnumChapters "There are %d chapters in this DVD title.\n"
+#define MSGTR_DVDinvalidChapter "Invalid DVD chapter number: %d\n"
+#define MSGTR_DVDinvalidChapterRange "Invalid chapter range specification %s\n"
+#define MSGTR_DVDinvalidLastChapter "Invalid DVD last chapter number: %d\n"
+#define MSGTR_DVDnumAngles "There are %d angles in this DVD title.\n"
+#define MSGTR_DVDinvalidAngle "Invalid DVD angle number: %d\n"
+#define MSGTR_DVDnoIFO "Cannot open the IFO file for DVD title %d.\n"
+#define MSGTR_DVDnoVMG "Can't open VMG info!\n"
+#define MSGTR_DVDnoVOBs "Cannot open title VOBS (VTS_%02d_1.VOB).\n"
+#define MSGTR_DVDnoMatchingAudio "No matching DVD audio language found!\n"
+#define MSGTR_DVDaudioChannel "Selected DVD audio channel: %d language: %c%c\n"
+#define MSGTR_DVDaudioStreamInfo "audio stream: %d format: %s (%s) language: %s aid: %d.\n"
+#define MSGTR_DVDnumAudioChannels "number of audio channels on disk: %d.\n"
+#define MSGTR_DVDnoMatchingSubtitle "No matching DVD subtitle language found!\n"
+#define MSGTR_DVDsubtitleChannel "Selected DVD subtitle channel: %d language: %c%c\n"
+#define MSGTR_DVDsubtitleLanguage "subtitle ( sid ): %d language: %s\n"
+#define MSGTR_DVDnumSubtitles "number of subtitles on disk: %d\n"
+
+// 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"
+#define MSGTR_RADIO_QueryControlFailed "[radio] ioctl query control failed: %s\n"
+#define MSGTR_RADIO_GetVolumeFailed "[radio] ioctl get volume failed: %s\n"
+#define MSGTR_RADIO_SetVolumeFailed "[radio] ioctl set volume failed: %s\n"
+#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"
+#define MSGTR_TV_NoVideoInputPresent "Error: No video input present!\n"
+#define MSGTR_TV_UnknownImageFormat ""\
+"==================================================================\n"\
+" WARNING: UNTESTED OR UNKNOWN OUTPUT IMAGE FORMAT REQUESTED (0x%x)\n"\
+" This may cause buggy playback or program crash! Bug reports will\n"\
+" 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"
+#define MSGTR_TV_Bt848ErrorOpeningBktrDev "tvi_bsdbt848: Unable to open bktr device. Error: %s\n"
+#define MSGTR_TV_Bt848ErrorOpeningTunerDev "tvi_bsdbt848: Unable to open tuner device. Error: %s\n"
+#define MSGTR_TV_Bt848ErrorOpeningDspDev "tvi_bsdbt848: Unable to open dsp device. Error: %s\n"
+#define MSGTR_TV_Bt848ErrorConfiguringDsp "tvi_bsdbt848: Configuration of dsp failed. Error: %s\n"
+#define MSGTR_TV_Bt848ErrorReadingAudio "tvi_bsdbt848: Error reading audio data. Error: %s\n"
+#define MSGTR_TV_Bt848MmapFailed "tvi_bsdbt848: mmap failed. Error: %s\n"
+#define MSGTR_TV_Bt848FrameBufAllocFailed "tvi_bsdbt848: Frame buffer allocation failed. Error: %s\n"
+#define MSGTR_TV_Bt848ErrorSettingWidth "tvi_bsdbt848: Error setting picture width. Error: %s\n"
+#define MSGTR_TV_Bt848ErrorSettingHeight "tvi_bsdbt848: Error setting picture height. Error: %s\n"
+#define MSGTR_TV_Bt848UnableToStopCapture "tvi_bsdbt848: Unable to stop capture. Error: %s\n"
+#define MSGTR_TV_TTSupportedLanguages "Supported Teletext languages:\n"
+#define MSGTR_TV_TTSelectedLanguage "Selected default teletext language: %s\n"
+#define MSGTR_TV_ScannerNotAvailableWithoutTuner "Channel scanner is not available without tuner\n"
+
+//tvi_dshow.c
+#define MSGTR_TVI_DS_UnableConnectInputVideoDecoder  "Unable to connect given input to video decoder. Error:0x%x\n"
+#define MSGTR_TVI_DS_UnableConnectInputAudioDecoder  "Unable to connect given input to audio decoder. Error:0x%x\n"
+#define MSGTR_TVI_DS_UnableSelectVideoFormat "tvi_dshow: Unable to select video format. Error:0x%x\n"
+#define MSGTR_TVI_DS_UnableSelectAudioFormat "tvi_dshow: Unable to select audio format. Error:0x%x\n"
+#define MSGTR_TVI_DS_UnableGetMediaControlInterface "tvi_dshow: Unable to get IMediaControl interface. Error:0x%x\n"
+#define MSGTR_TVI_DS_UnableStartGraph "tvi_dshow: Unable to start graph! Error:0x%x\n"
+#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"
+#define MSGTR_TVI_DS_WrongADeviceParam "tvi_dshow: Wrong adevice parameter: %s\n"
+#define MSGTR_TVI_DS_WrongADeviceIndex "tvi_dshow: Wrong adevice index: %d\n"
+
+#define MSGTR_TVI_DS_SamplerateNotsupported "tvi_dshow: Samplerate %d is not supported by device. Failing back to first available.\n"
+#define MSGTR_TVI_DS_VideoAdjustigNotSupported "tvi_dshow: Adjusting of brightness/hue/saturation/contrast is not supported by device\n"
+
+#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"
+#define MSGTR_TVI_DS_UnsupportedMediaType "tvi_dshow: Unsupported media type passed to %s\n"
+#define MSGTR_TVI_DS_UnableGetsupportedVideoFormats "tvi_dshow: Unable to get supported media formats from video pin. Error:0x%x\n"
+#define MSGTR_TVI_DS_UnableGetsupportedAudioFormats "tvi_dshow: Unable to get supported media formats from audio pin. Error:0x%x Disabling audio.\n"
+#define MSGTR_TVI_DS_UnableFindNearestChannel "tvi_dshow: Unable to find nearest channel in system frequency table\n"
+#define MSGTR_TVI_DS_UnableToSetChannel "tvi_dshow: Unable to switch to nearest channel from system frequency table. Error:0x%x\n"
+#define MSGTR_TVI_DS_UnableTerminateVPPin "tvi_dshow: Unable to terminate VideoPort pin with any filter in graph. Error:0x%x\n"
+#define MSGTR_TVI_DS_UnableBuildVideoSubGraph "tvi_dshow: Unable to build video chain of capture graph. Error:0x%x\n"
+#define MSGTR_TVI_DS_UnableBuildAudioSubGraph "tvi_dshow: Unable to build audio chain of capture graph. Error:0x%x\n"
+#define MSGTR_TVI_DS_UnableBuildVBISubGraph "tvi_dshow: Unable to build VBI chain of capture graph. Error:0x%x\n"
+#define MSGTR_TVI_DS_GraphInitFailure "tvi_dshow: Directshow graph initialization failure.\n"
+#define MSGTR_TVI_DS_NoVideoCaptureDevice "tvi_dshow: Unable to find video capture device\n"
+#define MSGTR_TVI_DS_NoAudioCaptureDevice "tvi_dshow: Unable to find audio capture device\n"
+#define MSGTR_TVI_DS_GetActualMediatypeFailed "tvi_dshow: Unable to get actual mediatype (Error:0x%x). Assuming equal to requested.\n"
+
+// url.c
+#define MSGTR_MPDEMUX_URL_StringAlreadyEscaped "String appears to be already escaped in url_escape %c%c1%c2\n"
+
+// subtitles
+#define MSGTR_SUBTITLES_SubRip_UnknownFontColor "SubRip: unknown font color in subtitle: %s\n"
+
+
+/* untranslated messages from the English master file */
+
+
+#endif /* MPLAYER_HELP_MP_H */
diff --git a/libavfilter/libmpcodecs/img_format.c b/libavfilter/libmpcodecs/img_format.c
new file mode 100644
index 0000000..ba87042
--- /dev/null
+++ b/libavfilter/libmpcodecs/img_format.c
@@ -0,0 +1,170 @@
+/*
+ * 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 "config.h"
+#include "img_format.h"
+#include "stdio.h"
+
+const char *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_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_420P16_LE: return "Planar 420P 16-bit little-endian";
+    case IMGFMT_420P16_BE: return "Planar 420P 16-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_444P16_LE: return "Planar 444P 16-bit little-endian";
+    case IMGFMT_444P16_BE: return "Planar 444P 16-bit big-endian";
+    case IMGFMT_420A: return "Planar 420P with alpha";
+    case IMGFMT_444P: return "Planar 444P";
+    case IMGFMT_422P: return "Planar 422P";
+    case IMGFMT_411P: return "Planar 411P";
+    case IMGFMT_NV12: return "Planar NV12";
+    case IMGFMT_NV21: return "Planar NV21";
+    case IMGFMT_HM12: return "Planar NV12 Macroblock";
+    case IMGFMT_IUYV: return "Packed IUYV";
+    case IMGFMT_IY41: return "Packed IY41";
+    case IMGFMT_IYU1: return "Packed IYU1";
+    case IMGFMT_IYU2: return "Packed IYU2";
+    case IMGFMT_UYVY: return "Packed UYVY";
+    case IMGFMT_UYNV: return "Packed UYNV";
+    case IMGFMT_cyuv: return "Packed CYUV";
+    case IMGFMT_Y422: return "Packed Y422";
+    case IMGFMT_YUY2: return "Packed YUY2";
+    case IMGFMT_YUNV: return "Packed YUNV";
+    case IMGFMT_YVYU: return "Packed YVYU";
+    case IMGFMT_Y41P: return "Packed Y41P";
+    case IMGFMT_Y211: return "Packed Y211";
+    case IMGFMT_Y41T: return "Packed Y41T";
+    case IMGFMT_Y42T: return "Packed Y42T";
+    case IMGFMT_V422: return "Packed V422";
+    case IMGFMT_V655: return "Packed V655";
+    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_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";
+    }
+    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 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;
+    case IMGFMT_420A:
+    case IMGFMT_I420:
+    case IMGFMT_IYUV:
+    case IMGFMT_YV12:
+        xs = 1;
+        ys = 1;
+        break;
+    case IMGFMT_IF09:
+    case IMGFMT_YVU9:
+        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;
+        ys = 31;
+        break;
+    default:
+        err = 1;
+        break;
+    }
+    if (x_shift) *x_shift = xs;
+    if (y_shift) *y_shift = ys;
+    bpp = 8 + ((16 >> xs) >> ys);
+    if (format == IMGFMT_420A)
+        bpp += 8;
+    bpp *= bpp_factor;
+    return err ? 0 : bpp;
+}
diff --git a/libavfilter/libmpcodecs/img_format.h b/libavfilter/libmpcodecs/img_format.h
new file mode 100644
index 0000000..c95ed4d
--- /dev/null
+++ b/libavfilter/libmpcodecs/img_format.h
@@ -0,0 +1,214 @@
+/*
+ * 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.
+ */
+
+#ifndef MPLAYER_IMG_FORMAT_H
+#define MPLAYER_IMG_FORMAT_H
+
+#include "config.h"
+
+/* RGB/BGR Formats */
+
+#define IMGFMT_RGB_MASK 0xFFFFFF00
+#define IMGFMT_RGB (('R'<<24)|('G'<<16)|('B'<<8))
+#define IMGFMT_RGB1  (IMGFMT_RGB|1)
+#define IMGFMT_RGB4  (IMGFMT_RGB|4)
+#define IMGFMT_RGB4_CHAR  (IMGFMT_RGB|4|128) // RGB4 with 1 pixel per byte
+#define IMGFMT_RGB8  (IMGFMT_RGB|8)
+#define IMGFMT_RGB12 (IMGFMT_RGB|12)
+#define IMGFMT_RGB15 (IMGFMT_RGB|15)
+#define IMGFMT_RGB16 (IMGFMT_RGB|16)
+#define IMGFMT_RGB24 (IMGFMT_RGB|24)
+#define IMGFMT_RGB32 (IMGFMT_RGB|32)
+#define IMGFMT_RGB48LE (IMGFMT_RGB|48)
+#define IMGFMT_RGB48BE (IMGFMT_RGB|48|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_BGR4_CHAR (IMGFMT_BGR|4|128) // BGR4 with 1 pixel per byte
+#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)
+
+#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_RGB48NE IMGFMT_RGB48BE
+#define IMGFMT_RGB12BE IMGFMT_RGB12
+#define IMGFMT_RGB12LE (IMGFMT_RGB12|64)
+#define IMGFMT_RGB15BE IMGFMT_RGB15
+#define IMGFMT_RGB15LE (IMGFMT_RGB15|64)
+#define IMGFMT_RGB16BE IMGFMT_RGB16
+#define IMGFMT_RGB16LE (IMGFMT_RGB16|64)
+#define IMGFMT_BGR12BE IMGFMT_BGR12
+#define IMGFMT_BGR12LE (IMGFMT_BGR12|64)
+#define IMGFMT_BGR15BE IMGFMT_BGR15
+#define IMGFMT_BGR15LE (IMGFMT_BGR15|64)
+#define IMGFMT_BGR16BE IMGFMT_BGR16
+#define IMGFMT_BGR16LE (IMGFMT_BGR16|64)
+#else
+#define IMGFMT_ABGR (IMGFMT_BGR32|64)
+#define IMGFMT_BGRA IMGFMT_BGR32
+#define IMGFMT_ARGB (IMGFMT_RGB32|64)
+#define IMGFMT_RGBA IMGFMT_RGB32
+#define IMGFMT_RGB48NE IMGFMT_RGB48LE
+#define IMGFMT_RGB12BE (IMGFMT_RGB12|64)
+#define IMGFMT_RGB12LE IMGFMT_RGB12
+#define IMGFMT_RGB15BE (IMGFMT_RGB15|64)
+#define IMGFMT_RGB15LE IMGFMT_RGB15
+#define IMGFMT_RGB16BE (IMGFMT_RGB16|64)
+#define IMGFMT_RGB16LE IMGFMT_RGB16
+#define IMGFMT_BGR12BE (IMGFMT_BGR12|64)
+#define IMGFMT_BGR12LE IMGFMT_BGR12
+#define IMGFMT_BGR15BE (IMGFMT_BGR15|64)
+#define IMGFMT_BGR15LE IMGFMT_BGR15
+#define IMGFMT_BGR16BE (IMGFMT_BGR16|64)
+#define IMGFMT_BGR16LE IMGFMT_BGR16
+#endif
+
+/* old names for compatibility */
+#define IMGFMT_RG4B  IMGFMT_RGB4_CHAR
+#define IMGFMT_BG4B  IMGFMT_BGR4_CHAR
+
+#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)
+
+
+/* Planar YUV Formats */
+
+#define IMGFMT_YVU9 0x39555659
+#define IMGFMT_IF09 0x39304649
+#define IMGFMT_YV12 0x32315659
+#define IMGFMT_I420 0x30323449
+#define IMGFMT_IYUV 0x56555949
+#define IMGFMT_CLPL 0x4C504C43
+#define IMGFMT_Y800 0x30303859
+#define IMGFMT_Y8   0x20203859
+#define IMGFMT_NV12 0x3231564E
+#define IMGFMT_NV21 0x3132564E
+
+/* unofficial Planar Formats, FIXME if official 4CC exists */
+#define IMGFMT_444P 0x50343434
+#define IMGFMT_422P 0x50323234
+#define IMGFMT_411P 0x50313134
+#define IMGFMT_440P 0x50303434
+#define IMGFMT_HM12 0x32314D48
+
+// 4:2:0 planar with alpha
+#define IMGFMT_420A 0x41303234
+
+#define IMGFMT_444P16_LE 0x51343434
+#define IMGFMT_444P16_BE 0x34343451
+#define IMGFMT_422P16_LE 0x51323234
+#define IMGFMT_422P16_BE 0x34323251
+#define IMGFMT_420P16_LE 0x51303234
+#define IMGFMT_420P16_BE 0x34323051
+#if HAVE_BIGENDIAN
+#define IMGFMT_444P16 IMGFMT_444P16_BE
+#define IMGFMT_422P16 IMGFMT_422P16_BE
+#define IMGFMT_420P16 IMGFMT_420P16_BE
+#else
+#define IMGFMT_444P16 IMGFMT_444P16_LE
+#define IMGFMT_422P16 IMGFMT_422P16_LE
+#define IMGFMT_420P16 IMGFMT_420P16_LE
+#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(fmt)    (IMGFMT_IS_YUVP16_LE(fmt) || IMGFMT_IS_YUVP16_BE(fmt))
+
+/* Packed YUV Formats */
+
+#define IMGFMT_IUYV 0x56595549
+#define IMGFMT_IY41 0x31435949
+#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_YUY2 0x32595559
+#define IMGFMT_YUNV 0x564E5559
+#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_V655 0x35353656
+#define IMGFMT_CLJR 0x524A4C43
+#define IMGFMT_YUVP 0x50565559
+#define IMGFMT_UYVP 0x50565955
+
+/* Compressed Formats */
+#define IMGFMT_MPEGPES (('M'<<24)|('P'<<16)|('E'<<8)|('S'))
+#define IMGFMT_MJPEG (('M')|('J'<<8)|('P'<<16)|('G'<<24))
+/* Formats that are understood by zoran chips, we include
+ * non-interlaced, interlaced top-first, interlaced bottom-first */
+#define IMGFMT_ZRMJPEGNI  (('Z'<<24)|('R'<<16)|('N'<<8)|('I'))
+#define IMGFMT_ZRMJPEGIT (('Z'<<24)|('R'<<16)|('I'<<8)|('T'))
+#define IMGFMT_ZRMJPEGIB (('Z'<<24)|('R'<<16)|('I'<<8)|('B'))
+
+// I think that this code could not be used by any other codec/format
+#define IMGFMT_XVMC 0x1DC70000
+#define IMGFMT_XVMC_MASK 0xFFFF0000
+#define IMGFMT_IS_XVMC(fmt) (((fmt)&IMGFMT_XVMC_MASK)==IMGFMT_XVMC)
+//these are chroma420
+#define IMGFMT_XVMC_MOCO_MPEG2 (IMGFMT_XVMC|0x02)
+#define IMGFMT_XVMC_IDCT_MPEG2 (IMGFMT_XVMC|0x82)
+
+// VDPAU specific format.
+#define IMGFMT_VDPAU               0x1DC80000
+#define IMGFMT_VDPAU_MASK          0xFFFF0000
+#define IMGFMT_IS_VDPAU(fmt)       (((fmt)&IMGFMT_VDPAU_MASK)==IMGFMT_VDPAU)
+#define IMGFMT_VDPAU_MPEG1         (IMGFMT_VDPAU|0x01)
+#define IMGFMT_VDPAU_MPEG2         (IMGFMT_VDPAU|0x02)
+#define IMGFMT_VDPAU_H264          (IMGFMT_VDPAU|0x03)
+#define IMGFMT_VDPAU_WMV3          (IMGFMT_VDPAU|0x04)
+#define IMGFMT_VDPAU_VC1           (IMGFMT_VDPAU|0x05)
+#define IMGFMT_VDPAU_MPEG4         (IMGFMT_VDPAU|0x06)
+
+#define IMGFMT_IS_HWACCEL(fmt) (IMGFMT_IS_VDPAU(fmt) || IMGFMT_IS_XVMC(fmt))
+
+typedef struct {
+    void* data;
+    int size;
+    int id;        // stream id. usually 0x1E0
+    int timestamp; // pts, 90000 Hz counter based
+} vo_mpegpes_t;
+
+const char *vo_format_name(int format);
+
+/**
+ * Calculates the scale shifts for the chroma planes for planar YUV
+ *
+ * \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);
+
+#endif /* MPLAYER_IMG_FORMAT_H */
diff --git a/libavfilter/libmpcodecs/libvo/fastmemcpy.h b/libavfilter/libmpcodecs/libvo/fastmemcpy.h
new file mode 100644
index 0000000..5a17d01
--- /dev/null
+++ b/libavfilter/libmpcodecs/libvo/fastmemcpy.h
@@ -0,0 +1,99 @@
+/*
+ * This file is part of MPlayer.
+ *
+ * MPlayer 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.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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
+ */
+
+#ifndef MPLAYER_FASTMEMCPY_H
+#define MPLAYER_FASTMEMCPY_H
+
+#include <inttypes.h>
+#include <string.h>
+#include <stddef.h>
+
+void * fast_memcpy(void * to, const void * from, size_t len);
+void * mem2agpcpy(void * to, const void * from, size_t len);
+
+#if ! defined(CONFIG_FASTMEMCPY) || ! (HAVE_MMX || HAVE_MMX2 || HAVE_AMD3DNOW /* || HAVE_SSE || HAVE_SSE2 */)
+#define mem2agpcpy(a,b,c) memcpy(a,b,c)
+#define fast_memcpy(a,b,c) memcpy(a,b,c)
+#endif
+
+static inline void * mem2agpcpy_pic(void * dst, const void * src, int bytesPerLine, int height, int dstStride, int srcStride)
+{
+    int i;
+    void *retval=dst;
+
+    if(dstStride == srcStride)
+    {
+        if (srcStride < 0) {
+                src = (const uint8_t*)src + (height-1)*srcStride;
+                dst = (uint8_t*)dst + (height-1)*dstStride;
+                srcStride = -srcStride;
+        }
+
+        mem2agpcpy(dst, src, srcStride*height);
+    }
+    else
+    {
+        for(i=0; i<height; i++)
+        {
+            mem2agpcpy(dst, src, bytesPerLine);
+            src = (const uint8_t*)src + srcStride;
+            dst = (uint8_t*)dst + dstStride;
+        }
+    }
+
+    return retval;
+}
+
+#define memcpy_pic(d, s, b, h, ds, ss) memcpy_pic2(d, s, b, h, ds, ss, 0)
+#define my_memcpy_pic(d, s, b, h, ds, ss) memcpy_pic2(d, s, b, h, ds, ss, 1)
+
+/**
+ * \param limit2width always skip data between end of line and start of next
+ *                    instead of copying the full block when strides are the same
+ */
+static inline void * memcpy_pic2(void * dst, const void * src,
+                                 int bytesPerLine, int height,
+                                 int dstStride, int srcStride, int limit2width)
+{
+    int i;
+    void *retval=dst;
+
+    if(!limit2width && dstStride == srcStride)
+    {
+        if (srcStride < 0) {
+                src = (const uint8_t*)src + (height-1)*srcStride;
+                dst = (uint8_t*)dst + (height-1)*dstStride;
+                srcStride = -srcStride;
+        }
+
+        fast_memcpy(dst, src, srcStride*height);
+    }
+    else
+    {
+        for(i=0; i<height; i++)
+        {
+            fast_memcpy(dst, src, bytesPerLine);
+            src = (const uint8_t*)src + srcStride;
+            dst = (uint8_t*)dst + dstStride;
+        }
+    }
+
+    return retval;
+}
+
+#endif /* MPLAYER_FASTMEMCPY_H */
diff --git a/libavfilter/libmpcodecs/libvo/video_out.h b/libavfilter/libmpcodecs/libvo/video_out.h
new file mode 100644
index 0000000..2a3a0fa
--- /dev/null
+++ b/libavfilter/libmpcodecs/libvo/video_out.h
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) Aaron Holtzman - Aug 1999
+ * Strongly modified, most parts rewritten: A'rpi/ESP-team - 2000-2001
+ * (C) MPlayer developers
+ *
+ * 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.
+ */
+
+#ifndef MPLAYER_VIDEO_OUT_H
+#define MPLAYER_VIDEO_OUT_H
+
+#include <inttypes.h>
+#include <stdarg.h>
+
+//#include "sub/font_load.h"
+#include "../img_format.h"
+//#include "vidix/vidix.h"
+
+#define VO_EVENT_EXPOSE 1
+#define VO_EVENT_RESIZE 2
+#define VO_EVENT_KEYPRESS 4
+#define VO_EVENT_REINIT 8
+#define VO_EVENT_MOVE 16
+
+/* Obsolete: VOCTRL_QUERY_VAA 1 */
+/* does the device support the required format */
+#define VOCTRL_QUERY_FORMAT 2
+/* signal a device reset seek */
+#define VOCTRL_RESET 3
+/* true if vo driver can use GUI created windows */
+#define VOCTRL_GUISUPPORT 4
+#define VOCTRL_GUI_NOWINDOW 19
+/* used to switch to fullscreen */
+#define VOCTRL_FULLSCREEN 5
+/* signal a device pause */
+#define VOCTRL_PAUSE 7
+/* start/resume playback */
+#define VOCTRL_RESUME 8
+/* libmpcodecs direct rendering: */
+#define VOCTRL_GET_IMAGE 9
+#define VOCTRL_DRAW_IMAGE 13
+#define VOCTRL_SET_SPU_PALETTE 14
+/* decoding ahead: */
+#define VOCTRL_GET_NUM_FRAMES 10
+#define VOCTRL_GET_FRAME_NUM  11
+#define VOCTRL_SET_FRAME_NUM  12
+#define VOCTRL_GET_PANSCAN 15
+#define VOCTRL_SET_PANSCAN 16
+/* equalizer controls */
+#define VOCTRL_SET_EQUALIZER 17
+#define VOCTRL_GET_EQUALIZER 18
+//#define VOCTRL_GUI_NOWINDOW 19
+/* Frame duplication */
+#define VOCTRL_DUPLICATE_FRAME 20
+// ... 21
+#define VOCTRL_START_SLICE 21
+
+#define VOCTRL_ONTOP 25
+#define VOCTRL_ROOTWIN 26
+#define VOCTRL_BORDER 27
+#define VOCTRL_DRAW_EOSD 28
+#define VOCTRL_GET_EOSD_RES 29
+
+#define VOCTRL_SET_DEINTERLACE 30
+#define VOCTRL_GET_DEINTERLACE 31
+
+#define VOCTRL_UPDATE_SCREENINFO 32
+
+// Vo can be used by xover
+#define VOCTRL_XOVERLAY_SUPPORT 22
+
+#define VOCTRL_XOVERLAY_SET_COLORKEY 24
+typedef struct {
+  uint32_t x11; // The raw x11 color
+  uint16_t r,g,b;
+} mp_colorkey_t;
+
+#define VOCTRL_XOVERLAY_SET_WIN 23
+typedef struct {
+  int x,y;
+  int w,h;
+} mp_win_t;
+
+#define VO_TRUE      1
+#define VO_FALSE     0
+#define VO_ERROR    -1
+#define VO_NOTAVAIL -2
+#define VO_NOTIMPL  -3
+
+#define VOFLAG_FULLSCREEN         0x01
+#define VOFLAG_MODESWITCHING      0x02
+#define VOFLAG_SWSCALE            0x04
+#define VOFLAG_FLIPPING           0x08
+#define VOFLAG_HIDDEN             0x10  //< Use to create a hidden window
+#define VOFLAG_STEREO             0x20  //< Use to create a stereo-capable window
+#define VOFLAG_XOVERLAY_SUB_VO 0x10000
+
+typedef struct vo_info_s
+{
+    /* driver name ("Matrox Millennium G200/G400" */
+    const char *name;
+    /* short name (for config strings) ("mga") */
+    const char *short_name;
+    /* author ("Aaron Holtzman <aholtzma@ess.engr.uvic.ca>") */
+    const char *author;
+    /* any additional comments */
+    const char *comment;
+} vo_info_t;
+
+typedef struct vo_functions_s
+{
+    const vo_info_t *info;
+    /*
+     * Preinitializes driver (real INITIALIZATION)
+     *   arg - currently it's vo_subdevice
+     *   returns: zero on successful initialization, non-zero on error.
+     */
+    int (*preinit)(const char *arg);
+    /*
+     * Initialize (means CONFIGURE) the display driver.
+     * params:
+     *   width,height: image source size
+     *   d_width,d_height: size of the requested window size, just a hint
+     *   fullscreen: flag, 0=windowd 1=fullscreen, just a hint
+     *   title: window title, if available
+     *   format: fourcc of pixel format
+     * returns : zero on successful initialization, non-zero on error.
+     */
+    int (*config)(uint32_t width, uint32_t height, uint32_t d_width,
+                  uint32_t d_height, uint32_t fullscreen, char *title,
+                  uint32_t format);
+
+    /*
+     * Control interface
+     */
+    int (*control)(uint32_t request, void *data, ...);
+
+    /*
+     * Display a new RGB/BGR frame of the video to the screen.
+     * params:
+     *   src[0] - pointer to the image
+     */
+    int (*draw_frame)(uint8_t *src[]);
+
+    /*
+     * Draw a planar YUV slice to the buffer:
+     * params:
+     *   src[3] = source image planes (Y,U,V)
+     *   stride[3] = source image planes line widths (in bytes)
+     *   w,h = width*height of area to be copied (in Y pixels)
+     *   x,y = position at the destination image (in Y pixels)
+     */
+    int (*draw_slice)(uint8_t *src[], int stride[], int w,int h, int x,int y);
+
+    /*
+     * Draws OSD to the screen buffer
+     */
+    void (*draw_osd)(void);
+
+    /*
+     * Blit/Flip buffer to the screen. Must be called after each frame!
+     */
+    void (*flip_page)(void);
+
+    /*
+     * This func is called after every frames to handle keyboard and
+     * other events. It's called in PAUSE mode too!
+     */
+    void (*check_events)(void);
+
+    /*
+     * Closes driver. Should restore the original state of the system.
+     */
+    void (*uninit)(void);
+} vo_functions_t;
+
+const vo_functions_t* init_best_video_out(char** vo_list);
+int config_video_out(const vo_functions_t *vo, uint32_t width, uint32_t height,
+                     uint32_t d_width, uint32_t d_height, uint32_t flags,
+                     char *title, uint32_t format);
+void list_video_out(void);
+
+// NULL terminated array of all drivers
+extern const vo_functions_t* const video_out_drivers[];
+
+extern int vo_flags;
+
+extern int vo_config_count;
+
+extern int xinerama_screen;
+extern int xinerama_x;
+extern int xinerama_y;
+
+// correct resolution/bpp on screen:  (should be autodetected by vo_init())
+extern int vo_depthonscreen;
+extern int vo_screenwidth;
+extern int vo_screenheight;
+
+// requested resolution/bpp:  (-x -y -bpp options)
+extern int vo_dx;
+extern int vo_dy;
+extern int vo_dwidth;
+extern int vo_dheight;
+extern int vo_dbpp;
+
+extern int vo_grabpointer;
+extern int vo_doublebuffering;
+extern int vo_directrendering;
+extern int vo_vsync;
+extern int vo_fsmode;
+extern float vo_panscan;
+extern int vo_adapter_num;
+extern int vo_refresh_rate;
+extern int vo_keepaspect;
+extern int vo_rootwin;
+extern int vo_ontop;
+extern int vo_border;
+
+extern int vo_gamma_gamma;
+extern int vo_gamma_brightness;
+extern int vo_gamma_saturation;
+extern int vo_gamma_contrast;
+extern int vo_gamma_hue;
+extern int vo_gamma_red_intensity;
+extern int vo_gamma_green_intensity;
+extern int vo_gamma_blue_intensity;
+
+extern int vo_nomouse_input;
+extern int enable_mouse_movements;
+
+extern int vo_pts;
+extern float vo_fps;
+
+extern char *vo_subdevice;
+
+extern int vo_colorkey;
+
+extern char *vo_winname;
+extern char *vo_wintitle;
+
+extern int64_t WinID;
+
+typedef struct {
+        float min;
+        float max;
+        } range_t;
+
+float range_max(range_t *r);
+int in_range(range_t *r, float f);
+range_t *str2range(char *s);
+extern char *monitor_hfreq_str;
+extern char *monitor_vfreq_str;
+extern char *monitor_dotclock_str;
+
+struct mp_keymap {
+  int from;
+  int to;
+};
+int lookup_keymap_table(const struct mp_keymap *map, int key);
+struct vo_rect {
+  int left, right, top, bottom, width, height;
+};
+void calc_src_dst_rects(int src_width, int src_height, struct vo_rect *src, struct vo_rect *dst,
+                        struct vo_rect *borders, const struct vo_rect *crop);
+void vo_mouse_movement(int posx, int posy);
+
+#endif /* MPLAYER_VIDEO_OUT_H */
diff --git a/libavfilter/libmpcodecs/mp_image.c b/libavfilter/libmpcodecs/mp_image.c
new file mode 100644
index 0000000..bd6d33f
--- /dev/null
+++ b/libavfilter/libmpcodecs/mp_image.c
@@ -0,0 +1,200 @@
+/*
+ * 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 "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#include "img_format.h"
+#include "mp_image.h"
+
+#include "libvo/fastmemcpy.h"
+//#include "libavutil/mem.h"
+
+void mp_image_alloc_planes(mp_image_t *mpi) {
+  // 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+
+                            mpi->chroma_width*mpi->chroma_height);
+  } else
+    mpi->planes[0]=av_malloc(mpi->bpp*mpi->width*(mpi->height+2)/8);
+  if (mpi->flags&MP_IMGFLAG_PLANAR) {
+    int bpp = IMGFMT_IS_YUVP16(mpi->imgfmt)? 2 : 1;
+    // YV12/I420/YVU9/IF09. feel free to add other planar formats here...
+    mpi->stride[0]=mpi->stride[3]=bpp*mpi->width;
+    if(mpi->num_planes > 2){
+      mpi->stride[1]=mpi->stride[2]=bpp*mpi->chroma_width;
+      if(mpi->flags&MP_IMGFLAG_SWAPPED){
+        // I420/IYUV  (Y,U,V)
+        mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height;
+        mpi->planes[2]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height;
+        if (mpi->num_planes > 3)
+            mpi->planes[3]=mpi->planes[2]+mpi->stride[2]*mpi->chroma_height;
+      } else {
+        // YV12,YVU9,IF09  (Y,V,U)
+        mpi->planes[2]=mpi->planes[0]+mpi->stride[0]*mpi->height;
+        mpi->planes[1]=mpi->planes[2]+mpi->stride[1]*mpi->chroma_height;
+        if (mpi->num_planes > 3)
+            mpi->planes[3]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height;
+      }
+    } else {
+      // NV12/NV21
+      mpi->stride[1]=mpi->chroma_width;
+      mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height;
+    }
+  } else {
+    mpi->stride[0]=mpi->width*mpi->bpp/8;
+    if (mpi->flags & MP_IMGFLAG_RGB_PALETTE)
+      mpi->planes[1] = av_malloc(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_setfmt(mpi,fmt);
+  mp_image_alloc_planes(mpi);
+
+  return mpi;
+}
+
+void 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]);
+    memcpy_pic(dmpi->planes[1],mpi->planes[1], mpi->chroma_width, mpi->chroma_height,
+               dmpi->stride[1],mpi->stride[1]);
+    memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height,
+               dmpi->stride[2],mpi->stride[2]);
+  } else {
+    memcpy_pic(dmpi->planes[0],mpi->planes[0],
+               mpi->w*(dmpi->bpp/8), mpi->h,
+               dmpi->stride[0],mpi->stride[0]);
+  }
+}
+
+void 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
+    if(out_fmt == IMGFMT_MPEGPES ||
+       out_fmt == IMGFMT_ZRMJPEGNI || out_fmt == IMGFMT_ZRMJPEGIT || out_fmt == IMGFMT_ZRMJPEGIB ||
+       IMGFMT_IS_HWACCEL(out_fmt)){
+        mpi->bpp=0;
+        return;
+    }
+    mpi->num_planes=1;
+    if (IMGFMT_IS_RGB(out_fmt)) {
+        if (IMGFMT_RGB_DEPTH(out_fmt) < 8 && !(out_fmt&128))
+            mpi->bpp = IMGFMT_RGB_DEPTH(out_fmt);
+        else
+            mpi->bpp=(IMGFMT_RGB_DEPTH(out_fmt)+7)&(~7);
+        return;
+    }
+    if (IMGFMT_IS_BGR(out_fmt)) {
+        if (IMGFMT_BGR_DEPTH(out_fmt) < 8 && !(out_fmt&128))
+            mpi->bpp = IMGFMT_BGR_DEPTH(out_fmt);
+        else
+            mpi->bpp=(IMGFMT_BGR_DEPTH(out_fmt)+7)&(~7);
+        mpi->flags|=MP_IMGFLAG_SWAPPED;
+        return;
+    }
+    mpi->flags|=MP_IMGFLAG_YUV;
+    mpi->num_planes=3;
+    if (mp_get_chroma_shift(out_fmt, NULL, NULL)) {
+        mpi->flags|=MP_IMGFLAG_PLANAR;
+        mpi->bpp = mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift);
+        mpi->chroma_width  = mpi->width  >> mpi->chroma_x_shift;
+        mpi->chroma_height = mpi->height >> mpi->chroma_y_shift;
+    }
+    switch(out_fmt){
+    case IMGFMT_I420:
+    case IMGFMT_IYUV:
+        mpi->flags|=MP_IMGFLAG_SWAPPED;
+    case IMGFMT_YV12:
+        return;
+    case IMGFMT_420A:
+    case IMGFMT_IF09:
+        mpi->num_planes=4;
+    case IMGFMT_YVU9:
+    case IMGFMT_444P:
+    case IMGFMT_422P:
+    case IMGFMT_411P:
+    case IMGFMT_440P:
+    case IMGFMT_444P16_LE:
+    case IMGFMT_444P16_BE:
+    case IMGFMT_422P16_LE:
+    case IMGFMT_422P16_BE:
+    case IMGFMT_420P16_LE:
+    case IMGFMT_420P16_BE:
+        return;
+    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_UYVY:
+        mpi->flags|=MP_IMGFLAG_SWAPPED;
+    case IMGFMT_YUY2:
+        mpi->bpp=16;
+        mpi->num_planes=1;
+        return;
+    case IMGFMT_NV12:
+        mpi->flags|=MP_IMGFLAG_SWAPPED;
+    case IMGFMT_NV21:
+        mpi->flags|=MP_IMGFLAG_PLANAR;
+        mpi->bpp=12;
+        mpi->num_planes=2;
+        mpi->chroma_width=(mpi->width>>0);
+        mpi->chroma_height=(mpi->height>>1);
+        mpi->chroma_x_shift=0;
+        mpi->chroma_y_shift=1;
+        return;
+    }
+    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* mpi = malloc(sizeof(mp_image_t));
+    if(!mpi) return NULL; // error!
+    memset(mpi,0,sizeof(mp_image_t));
+    mpi->width=mpi->w=w;
+    mpi->height=mpi->h=h;
+    return mpi;
+}
+
+void free_mp_image(mp_image_t* mpi){
+    if(!mpi) return;
+    if(mpi->flags&MP_IMGFLAG_ALLOCATED){
+        /* becouse we allocate the whole image in once */
+        av_free(mpi->planes[0]);
+        if (mpi->flags & MP_IMGFLAG_RGB_PALETTE)
+            av_free(mpi->planes[1]);
+    }
+    free(mpi);
+}
+
diff --git a/libavfilter/libmpcodecs/mp_image.h b/libavfilter/libmpcodecs/mp_image.h
new file mode 100644
index 0000000..162f57a
--- /dev/null
+++ b/libavfilter/libmpcodecs/mp_image.h
@@ -0,0 +1,150 @@
+/*
+ * 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.
+ */
+
+#ifndef MPLAYER_MP_IMAGE_H
+#define MPLAYER_MP_IMAGE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#undef printf //FIXME
+#undef fprintf //FIXME
+#include "mp_msg.h"
+#include "libavutil/avutil.h"
+#include "libavutil/avassert.h"
+#undef realloc
+#undef malloc
+#undef free
+#undef rand
+#undef srand
+#undef printf
+#undef strncpy
+#define ASMALIGN(ZEROBITS) ".p2align " #ZEROBITS "\n\t"
+#define CODEC_FLAG2_MEMC_ONLY     0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC).
+
+//--------- 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)
+#define MP_IMGFLAG_READABLE 0x02
+
+//--- buffer width/stride/plane restrictions: (used for direct rendering)
+// stride _have_to_ be aligned to MB boundary:  [for DR restrictions]
+#define MP_IMGFLAG_ACCEPT_ALIGNED_STRIDE 0x4
+// stride should be aligned to MB boundary:     [for buffer allocation]
+#define MP_IMGFLAG_PREFER_ALIGNED_STRIDE 0x8
+// codec accept any stride (>=width):
+#define MP_IMGFLAG_ACCEPT_STRIDE 0x10
+// codec accept any width (width*bpp=stride -> stride%bpp==0) (>=width):
+#define MP_IMGFLAG_ACCEPT_WIDTH 0x20
+//--- for planar formats only:
+// uses only stride[0], and stride[1]=stride[2]=stride[0]>>mpi->chroma_x_shift
+#define MP_IMGFLAG_COMMON_STRIDE 0x40
+// uses only planes[0], and calculates planes[1,2] from width,height,imgfmt
+#define MP_IMGFLAG_COMMON_PLANE 0x80
+
+#define MP_IMGFLAGMASK_RESTRICTIONS 0xFF
+
+//--------- color info (filled by 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.
+#define MP_IMGFLAG_RGB_PALETTE 0x800
+
+#define MP_IMGFLAGMASK_COLORS 0xF00
+
+// codec uses drawing/rendering callbacks (draw_slice()-like thing, DR method 2)
+// [the codec will set this flag if it supports callbacks, and the vo _may_
+//  clear it in get_image() if draw_slice() not implemented]
+#define MP_IMGFLAG_DRAW_CALLBACK 0x1000
+// set if it's in video buffer/memory: [set by vo/vf's get_image() !!!]
+#define MP_IMGFLAG_DIRECT 0x2000
+// set if buffer is allocated (used in destination images):
+#define MP_IMGFLAG_ALLOCATED 0x4000
+
+// buffer type was printed (do NOT set this flag - it's for INTERNAL USE!!!)
+#define MP_IMGFLAG_TYPE_DISPLAYED 0x8000
+
+// codec doesn't support any form of direct rendering - it has own buffer
+// allocation. so we just export its buffer pointers:
+#define MP_IMGTYPE_EXPORT 0
+// codec requires a static WO buffer, but it does only partial updates later:
+#define MP_IMGTYPE_STATIC 1
+// codec just needs some WO memory, where it writes/copies the whole frame to:
+#define MP_IMGTYPE_TEMP 2
+// I+P type, requires 2+ independent static R/W buffers
+#define MP_IMGTYPE_IP 3
+// I+P+B type, requires 2+ independent static R/W and 1+ temp WO buffers
+#define MP_IMGTYPE_IPB 4
+// Upper 16 bits give desired buffer number, -1 means get next available
+#define MP_IMGTYPE_NUMBERED 5
+// Doesn't need any buffer, incomplete image (probably a first field only)
+// we need this type to be able to differentiate between half frames and
+// all other cases
+#define MP_IMGTYPE_INCOMPLETE 6
+
+#define MP_MAX_PLANES 4
+
+#define MP_IMGFIELD_ORDERED 0x01
+#define MP_IMGFIELD_TOP_FIRST 0x02
+#define MP_IMGFIELD_REPEAT_FIRST 0x04
+#define MP_IMGFIELD_TOP 0x08
+#define MP_IMGFIELD_BOTTOM 0x10
+#define MP_IMGFIELD_INTERLACED 0x20
+
+typedef struct mp_image {
+    unsigned int flags;
+    unsigned char type;
+    int number;
+    unsigned char bpp;  // bits/pixel. NOT depth! for RGB it will be n*8
+    unsigned int imgfmt;
+    int width,height;  // stored dimensions
+    int x,y,w,h;  // visible dimensions
+    unsigned char* planes[MP_MAX_PLANES];
+    int stride[MP_MAX_PLANES];
+    char * qscale;
+    int qstride;
+    int pict_type; // 0->unknown, 1->I, 2->P, 3->B
+    int fields;
+    int qscale_type; // 0->mpeg1/4/h263, 1->mpeg2
+    int num_planes;
+    /* these are only used by planar formats Y,U(Cb),V(Cr) */
+    int chroma_width;
+    int chroma_height;
+    int chroma_x_shift; // horizontal
+    int chroma_y_shift; // vertical
+    int usage_count;
+    /* for private use by filter or vo driver (to store buffer id or dmpi) */
+    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);
+
+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);
+
+#endif /* MPLAYER_MP_IMAGE_H */
diff --git a/libavfilter/libmpcodecs/mp_msg.h b/libavfilter/libmpcodecs/mp_msg.h
new file mode 100644
index 0000000..7b6405b
--- /dev/null
+++ b/libavfilter/libmpcodecs/mp_msg.h
@@ -0,0 +1,164 @@
+/*
+ * 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.
+ */
+
+#ifndef MPLAYER_MP_MSG_H
+#define MPLAYER_MP_MSG_H
+
+#include <stdarg.h>
+
+// defined in mplayer.c and mencoder.c
+extern int verbose;
+
+// verbosity elevel:
+
+/* Only messages level MSGL_FATAL-MSGL_STATUS should be translated,
+ * messages level MSGL_V and above should not be translated. */
+
+#define MSGL_FATAL 0  // will exit/abort
+#define MSGL_ERR 1    // continues
+#define MSGL_WARN 2   // only warning
+#define MSGL_HINT 3   // short help message
+#define MSGL_INFO 4   // -quiet
+#define MSGL_STATUS 5 // v=0
+#define MSGL_V 6      // v=1
+#define MSGL_DBG2 7   // v=2
+#define MSGL_DBG3 8   // v=3
+#define MSGL_DBG4 9   // v=4
+#define MSGL_DBG5 10  // v=5
+
+#define MSGL_FIXME 1  // for conversions from printf where the appropriate MSGL is not known; set equal to ERR for obtrusiveness
+#define MSGT_FIXME 0  // for conversions from printf where the appropriate MSGT is not known; set equal to GLOBAL for obtrusiveness
+
+// code/module:
+
+#define MSGT_GLOBAL 0        // common player stuff errors
+#define MSGT_CPLAYER 1       // console player (mplayer.c)
+#define MSGT_GPLAYER 2       // gui player
+
+#define MSGT_VO 3       // libvo
+#define MSGT_AO 4       // libao
+
+#define MSGT_DEMUXER 5    // demuxer.c (general stuff)
+#define MSGT_DS 6         // demux stream (add/read packet etc)
+#define MSGT_DEMUX 7      // fileformat-specific stuff (demux_*.c)
+#define MSGT_HEADER 8     // fileformat-specific header (*header.c)
+
+#define MSGT_AVSYNC 9     // mplayer.c timer stuff
+#define MSGT_AUTOQ 10     // mplayer.c auto-quality stuff
+
+#define MSGT_CFGPARSER 11 // cfgparser.c
+
+#define MSGT_DECAUDIO 12  // av decoder
+#define MSGT_DECVIDEO 13
+
+#define MSGT_SEEK 14    // seeking code
+#define MSGT_WIN32 15   // win32 dll stuff
+#define MSGT_OPEN 16    // open.c (stream opening)
+#define MSGT_DVD 17     // open.c (DVD init/read/seek)
+
+#define MSGT_PARSEES 18 // parse_es.c (mpeg stream parser)
+#define MSGT_LIRC 19    // lirc_mp.c and input lirc driver
+
+#define MSGT_STREAM 20  // stream.c
+#define MSGT_CACHE 21   // cache2.c
+
+#define MSGT_MENCODER 22
+
+#define MSGT_XACODEC 23 // XAnim codecs
+
+#define MSGT_TV 24      // TV input subsystem
+
+#define MSGT_OSDEP 25  // OS-dependent parts
+
+#define MSGT_SPUDEC 26 // spudec.c
+
+#define MSGT_PLAYTREE 27    // Playtree handeling (playtree.c, playtreeparser.c)
+
+#define MSGT_INPUT 28
+
+#define MSGT_VFILTER 29
+
+#define MSGT_OSD 30
+
+#define MSGT_NETWORK 31
+
+#define MSGT_CPUDETECT 32
+
+#define MSGT_CODECCFG 33
+
+#define MSGT_SWS 34
+
+#define MSGT_VOBSUB 35
+#define MSGT_SUBREADER 36
+
+#define MSGT_AFILTER 37  // Audio filter messages
+
+#define MSGT_NETST 38 // Netstream
+
+#define MSGT_MUXER 39 // muxer layer
+
+#define MSGT_OSD_MENU 40
+
+#define MSGT_IDENTIFY 41  // -identify output
+
+#define MSGT_RADIO 42
+
+#define MSGT_ASS 43 // libass messages
+
+#define MSGT_LOADER 44 // dll loader messages
+
+#define MSGT_STATUSLINE 45 // playback/encoding status line
+
+#define MSGT_TELETEXT 46       // Teletext decoder
+
+#define MSGT_MAX 64
+
+
+extern char *mp_msg_charset;
+extern int mp_msg_color;
+extern int mp_msg_module;
+
+extern int mp_msg_levels[MSGT_MAX];
+extern int mp_msg_level_all;
+
+
+void mp_msg_init(void);
+int mp_msg_test(int mod, int lev);
+
+#include "config.h"
+
+void 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)));
+#   ifdef MP_DEBUG
+#      define mp_dbg(mod,lev, args... ) mp_msg(mod, lev, ## args )
+#   else
+#      define mp_dbg(mod,lev, args... ) /* only useful for developers */
+#   endif
+#else // not GNU C
+void mp_msg(int mod, int lev, const char *format, ... );
+#   ifdef MP_DEBUG
+#      define mp_dbg(mod,lev, ... ) mp_msg(mod, lev, __VA_ARGS__)
+#   else
+#      define mp_dbg(mod,lev, ... ) /* only useful for developers */
+#   endif
+#endif /* __GNUC__ */
+
+const char* filename_recode(const char* filename);
+
+#endif /* MPLAYER_MP_MSG_H */
diff --git a/libavfilter/libmpcodecs/mpbswap.h b/libavfilter/libmpcodecs/mpbswap.h
new file mode 100644
index 0000000..28f7337
--- /dev/null
+++ b/libavfilter/libmpcodecs/mpbswap.h
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+#ifndef MPLAYER_MPBSWAP_H
+#define MPLAYER_MPBSWAP_H
+
+#include <sys/types.h>
+#include "config.h"
+#include "libavutil/bswap.h"
+
+#define bswap_16(v) av_bswap16(v)
+#define bswap_32(v) av_bswap32(v)
+#define le2me_16(v) av_le2ne16(v)
+#define le2me_32(v) av_le2ne32(v)
+#define le2me_64(v) av_le2ne64(v)
+#define be2me_16(v) av_be2ne16(v)
+#define be2me_32(v) av_be2ne32(v)
+
+#endif /* MPLAYER_MPBSWAP_H */
diff --git a/libavfilter/libmpcodecs/mpc_info.h b/libavfilter/libmpcodecs/mpc_info.h
new file mode 100644
index 0000000..8554699
--- /dev/null
+++ b/libavfilter/libmpcodecs/mpc_info.h
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+#ifndef MPLAYER_MPC_INFO_H
+#define MPLAYER_MPC_INFO_H
+
+typedef struct mp_codec_info_s
+{
+        /* codec long name ("Autodesk FLI/FLC Animation decoder" */
+        const char *name;
+        /* short name (same as driver name in codecs.conf) ("dshow") */
+        const char *short_name;
+        /* interface author/maintainer */
+        const char *maintainer;
+        /* codec author ("Aaron Holtzman <aholtzma@ess.engr.uvic.ca>") */
+        const char *author;
+        /* any additional comments */
+        const char *comment;
+} mp_codec_info_t;
+
+#define CONTROL_OK 1
+#define CONTROL_TRUE 1
+#define CONTROL_FALSE 0
+#define CONTROL_UNKNOWN -1
+#define CONTROL_ERROR -2
+#define CONTROL_NA -3
+
+#endif /* MPLAYER_MPC_INFO_H */
diff --git a/libavfilter/libmpcodecs/pullup.c b/libavfilter/libmpcodecs/pullup.c
new file mode 100644
index 0000000..c1c4e0f
--- /dev/null
+++ b/libavfilter/libmpcodecs/pullup.c
@@ -0,0 +1,822 @@
+/*
+ * 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 "pullup.h"
+#include "cpudetect.h"
+
+
+
+#if ARCH_X86
+#if HAVE_MMX
+static int diff_y_mmx(unsigned char *a, unsigned char *b, int s)
+{
+    int ret;
+    __asm__ volatile (
+        "movl $4, %%ecx \n\t"
+        "pxor %%mm4, %%mm4 \n\t"
+        "pxor %%mm7, %%mm7 \n\t"
+
+        "1: \n\t"
+
+        "movq (%%"REG_S"), %%mm0 \n\t"
+        "movq (%%"REG_S"), %%mm2 \n\t"
+        "add  %%"REG_a", %%"REG_S" \n\t"
+        "movq (%%"REG_D"), %%mm1 \n\t"
+        "add  %%"REG_a", %%"REG_D" \n\t"
+        "psubusb %%mm1, %%mm2 \n\t"
+        "psubusb %%mm0, %%mm1 \n\t"
+        "movq %%mm2, %%mm0 \n\t"
+        "movq %%mm1, %%mm3 \n\t"
+        "punpcklbw %%mm7, %%mm0 \n\t"
+        "punpcklbw %%mm7, %%mm1 \n\t"
+        "punpckhbw %%mm7, %%mm2 \n\t"
+        "punpckhbw %%mm7, %%mm3 \n\t"
+        "paddw %%mm0, %%mm4 \n\t"
+        "paddw %%mm1, %%mm4 \n\t"
+        "paddw %%mm2, %%mm4 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+
+        "decl %%ecx \n\t"
+        "jnz 1b \n\t"
+
+        "movq %%mm4, %%mm3 \n\t"
+        "punpcklwd %%mm7, %%mm4 \n\t"
+        "punpckhwd %%mm7, %%mm3 \n\t"
+        "paddd %%mm4, %%mm3 \n\t"
+        "movd %%mm3, %%eax \n\t"
+        "psrlq $32, %%mm3 \n\t"
+        "movd %%mm3, %%edx \n\t"
+        "addl %%edx, %%eax \n\t"
+        "emms \n\t"
+        : "=a" (ret)
+        : "S" (a), "D" (b), "a" (s)
+        : "%ecx", "%edx"
+        );
+    return ret;
+}
+
+static int licomb_y_mmx(unsigned char *a, unsigned char *b, int s)
+{
+    int ret;
+    __asm__ volatile (
+        "movl $4, %%ecx \n\t"
+        "pxor %%mm6, %%mm6 \n\t"
+        "pxor %%mm7, %%mm7 \n\t"
+        "sub  %%"REG_a", %%"REG_D" \n\t"
+
+        "2: \n\t"
+
+        "movq (%%"REG_D"), %%mm0 \n\t"
+        "movq (%%"REG_D"), %%mm1 \n\t"
+        "punpcklbw %%mm7, %%mm0 \n\t"
+        "movq (%%"REG_D",%%"REG_a"), %%mm2 \n\t"
+        "punpcklbw %%mm7, %%mm1 \n\t"
+        "punpcklbw %%mm7, %%mm2 \n\t"
+        "paddw %%mm0, %%mm0 \n\t"
+        "paddw %%mm2, %%mm1 \n\t"
+        "movq %%mm0, %%mm2 \n\t"
+        "psubusw %%mm1, %%mm0 \n\t"
+        "psubusw %%mm2, %%mm1 \n\t"
+        "paddw %%mm0, %%mm6 \n\t"
+        "paddw %%mm1, %%mm6 \n\t"
+
+        "movq (%%"REG_S"), %%mm0 \n\t"
+        "movq (%%"REG_D"), %%mm1 \n\t"
+        "punpckhbw %%mm7, %%mm0 \n\t"
+        "movq (%%"REG_D",%%"REG_a"), %%mm2 \n\t"
+        "punpckhbw %%mm7, %%mm1 \n\t"
+        "punpckhbw %%mm7, %%mm2 \n\t"
+        "paddw %%mm0, %%mm0 \n\t"
+        "paddw %%mm2, %%mm1 \n\t"
+        "movq %%mm0, %%mm2 \n\t"
+        "psubusw %%mm1, %%mm0 \n\t"
+        "psubusw %%mm2, %%mm1 \n\t"
+        "paddw %%mm0, %%mm6 \n\t"
+        "paddw %%mm1, %%mm6 \n\t"
+
+        "movq (%%"REG_D",%%"REG_a"), %%mm0 \n\t"
+        "movq (%%"REG_S"), %%mm1 \n\t"
+        "punpcklbw %%mm7, %%mm0 \n\t"
+        "movq (%%"REG_S",%%"REG_a"), %%mm2 \n\t"
+        "punpcklbw %%mm7, %%mm1 \n\t"
+        "punpcklbw %%mm7, %%mm2 \n\t"
+        "paddw %%mm0, %%mm0 \n\t"
+        "paddw %%mm2, %%mm1 \n\t"
+        "movq %%mm0, %%mm2 \n\t"
+        "psubusw %%mm1, %%mm0 \n\t"
+        "psubusw %%mm2, %%mm1 \n\t"
+        "paddw %%mm0, %%mm6 \n\t"
+        "paddw %%mm1, %%mm6 \n\t"
+
+        "movq (%%"REG_D",%%"REG_a"), %%mm0 \n\t"
+        "movq (%%"REG_S"), %%mm1 \n\t"
+        "punpckhbw %%mm7, %%mm0 \n\t"
+        "movq (%%"REG_S",%%"REG_a"), %%mm2 \n\t"
+        "punpckhbw %%mm7, %%mm1 \n\t"
+        "punpckhbw %%mm7, %%mm2 \n\t"
+        "paddw %%mm0, %%mm0 \n\t"
+        "paddw %%mm2, %%mm1 \n\t"
+        "movq %%mm0, %%mm2 \n\t"
+        "psubusw %%mm1, %%mm0 \n\t"
+        "psubusw %%mm2, %%mm1 \n\t"
+        "paddw %%mm0, %%mm6 \n\t"
+        "paddw %%mm1, %%mm6 \n\t"
+
+        "add  %%"REG_a", %%"REG_S" \n\t"
+        "add  %%"REG_a", %%"REG_D" \n\t"
+        "decl %%ecx \n\t"
+        "jnz 2b \n\t"
+
+        "movq %%mm6, %%mm5 \n\t"
+        "punpcklwd %%mm7, %%mm6 \n\t"
+        "punpckhwd %%mm7, %%mm5 \n\t"
+        "paddd %%mm6, %%mm5 \n\t"
+        "movd %%mm5, %%eax \n\t"
+        "psrlq $32, %%mm5 \n\t"
+        "movd %%mm5, %%edx \n\t"
+        "addl %%edx, %%eax \n\t"
+
+        "emms \n\t"
+        : "=a" (ret)
+        : "S" (a), "D" (b), "a" (s)
+        : "%ecx", "%edx"
+        );
+    return ret;
+}
+
+static int var_y_mmx(unsigned char *a, unsigned char *b, int s)
+{
+    int ret;
+    __asm__ volatile (
+        "movl $3, %%ecx \n\t"
+        "pxor %%mm4, %%mm4 \n\t"
+        "pxor %%mm7, %%mm7 \n\t"
+
+        "1: \n\t"
+
+        "movq (%%"REG_S"), %%mm0 \n\t"
+        "movq (%%"REG_S"), %%mm2 \n\t"
+        "movq (%%"REG_S",%%"REG_a"), %%mm1 \n\t"
+        "add  %%"REG_a", %%"REG_S" \n\t"
+        "psubusb %%mm1, %%mm2 \n\t"
+        "psubusb %%mm0, %%mm1 \n\t"
+        "movq %%mm2, %%mm0 \n\t"
+        "movq %%mm1, %%mm3 \n\t"
+        "punpcklbw %%mm7, %%mm0 \n\t"
+        "punpcklbw %%mm7, %%mm1 \n\t"
+        "punpckhbw %%mm7, %%mm2 \n\t"
+        "punpckhbw %%mm7, %%mm3 \n\t"
+        "paddw %%mm0, %%mm4 \n\t"
+        "paddw %%mm1, %%mm4 \n\t"
+        "paddw %%mm2, %%mm4 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+
+        "decl %%ecx \n\t"
+        "jnz 1b \n\t"
+
+        "movq %%mm4, %%mm3 \n\t"
+        "punpcklwd %%mm7, %%mm4 \n\t"
+        "punpckhwd %%mm7, %%mm3 \n\t"
+        "paddd %%mm4, %%mm3 \n\t"
+        "movd %%mm3, %%eax \n\t"
+        "psrlq $32, %%mm3 \n\t"
+        "movd %%mm3, %%edx \n\t"
+        "addl %%edx, %%eax \n\t"
+        "emms \n\t"
+        : "=a" (ret)
+        : "S" (a), "a" (s)
+        : "%ecx", "%edx"
+        );
+    return 4*ret;
+}
+#endif
+#endif
+
+#define ABS(a) (((a)^((a)>>31))-((a)>>31))
+
+static int diff_y(unsigned char *a, unsigned char *b, int s)
+{
+    int i, j, diff=0;
+    for (i=4; i; i--) {
+        for (j=0; j<8; j++) diff += ABS(a[j]-b[j]);
+        a+=s; b+=s;
+    }
+    return diff;
+}
+
+static int licomb_y(unsigned char *a, unsigned char *b, int s)
+{
+    int i, j, diff=0;
+    for (i=4; i; i--) {
+        for (j=0; j<8; j++)
+            diff += ABS((a[j]<<1) - b[j-s] - b[j])
+                + ABS((b[j]<<1) - a[j] - a[j+s]);
+        a+=s; b+=s;
+    }
+    return diff;
+}
+
+#if 0
+static int qpcomb_y(unsigned char *a, unsigned char *b, int s)
+{
+    int i, j, diff=0;
+    for (i=4; i; i--) {
+        for (j=0; j<8; j++)
+            diff += ABS(a[j] - 3*b[j-s] + 3*a[j+s] - b[j]);
+        a+=s; b+=s;
+    }
+    return diff;
+}
+
+static int licomb_y_test(unsigned char *a, unsigned char *b, int s)
+{
+    int c = licomb_y(a,b,s);
+    int m = licomb_y_mmx(a,b,s);
+    if (c != m) printf("%d != %d\n", c, m);
+    return m;
+}
+#endif
+
+static int var_y(unsigned char *a, unsigned char *b, int s)
+{
+    int i, j, var=0;
+    for (i=3; i; i--) {
+        for (j=0; j<8; j++) {
+            var += ABS(a[j]-a[j+s]);
+        }
+        a+=s; b+=s;
+    }
+    return 4*var; /* match comb scaling */
+}
+
+
+
+
+
+
+
+
+
+static void alloc_buffer(struct pullup_context *c, struct pullup_buffer *b)
+{
+    int i;
+    if (b->planes) return;
+    b->planes = calloc(c->nplanes, sizeof(unsigned char *));
+    for (i = 0; i < c->nplanes; i++) {
+        b->planes[i] = malloc(c->h[i]*c->stride[i]);
+        /* Deal with idiotic 128=0 for chroma: */
+        memset(b->planes[i], c->background[i], c->h[i]*c->stride[i]);
+    }
+}
+
+struct pullup_buffer *pullup_lock_buffer(struct pullup_buffer *b, int parity)
+{
+    if (!b) return 0;
+    if ((parity+1) & 1) b->lock[0]++;
+    if ((parity+1) & 2) b->lock[1]++;
+    return b;
+}
+
+void 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)
+{
+    int i;
+
+    /* Try first to get the sister buffer for the previous field */
+    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);
+    }
+
+    /* Prefer a buffer with both fields open */
+    for (i = 0; i < c->nbuffers; i++) {
+        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);
+    }
+
+    if (parity == 2) return 0;
+
+    /* Search for any half-free buffer */
+    for (i = 0; i < c->nbuffers; i++) {
+        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 0;
+}
+
+
+
+
+
+
+static void compute_metric(struct pullup_context *c,
+    struct pullup_field *fa, int pa,
+    struct pullup_field *fb, int pb,
+    int (*func)(unsigned char *, unsigned char *, int), int *dest)
+{
+    unsigned char *a, *b;
+    int x, y;
+    int mp = c->metric_plane;
+    int xstep = c->bpp[mp];
+    int ystep = c->stride[mp]<<3;
+    int s = c->stride[mp]<<1; /* field stride */
+    int w = c->metric_w*xstep;
+
+    if (!fa->buffer || !fb->buffer) return;
+
+    /* Shortcut for duplicate fields (e.g. from RFF flag) */
+    if (fa->buffer == fb->buffer && pa == pb) {
+        memset(dest, 0, c->metric_len * sizeof(int));
+        return;
+    }
+
+    a = fa->buffer->planes[mp] + pa * c->stride[mp] + c->metric_offset;
+    b = fb->buffer->planes[mp] + pb * c->stride[mp] + c->metric_offset;
+
+    for (y = c->metric_h; y; y--) {
+        for (x = 0; x < w; x += xstep) {
+            *dest++ = func(a + x, b + x, s);
+        }
+        a += ystep; b += ystep;
+    }
+}
+
+
+
+
+
+static void alloc_metrics(struct pullup_context *c, struct pullup_field *f)
+{
+    f->diffs = calloc(c->metric_len, sizeof(int));
+    f->comb = calloc(c->metric_len, sizeof(int));
+    f->var = calloc(c->metric_len, sizeof(int));
+    /* add more metrics here as needed */
+}
+
+static struct pullup_field *make_field_queue(struct pullup_context *c, int len)
+{
+    struct pullup_field *head, *f;
+    f = head = calloc(1, sizeof(struct pullup_field));
+    alloc_metrics(c, f);
+    for (; len > 0; len--) {
+        f->next = calloc(1, sizeof(struct pullup_field));
+        f->next->prev = f;
+        f = f->next;
+        alloc_metrics(c, f);
+    }
+    f->next = head;
+    head->prev = f;
+    return head;
+}
+
+static void check_field_queue(struct pullup_context *c)
+{
+    if (c->head->next == c->first) {
+        struct pullup_field *f = calloc(1, sizeof(struct pullup_field));
+        alloc_metrics(c, f);
+        f->prev = c->head;
+        f->next = c->first;
+        c->head->next = f;
+        c->first->prev = f;
+    }
+}
+
+void pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b, int parity)
+{
+    struct pullup_field *f;
+
+    /* Grow the circular list if needed */
+    check_field_queue(c);
+
+    /* Cannot have two fields of same parity in a row; drop the new one */
+    if (c->last && c->last->parity == parity) return;
+
+    f = c->head;
+    f->parity = parity;
+    f->buffer = pullup_lock_buffer(b, parity);
+    f->flags = 0;
+    f->breaks = 0;
+    f->affinity = 0;
+
+    compute_metric(c, f, parity, f->prev->prev, parity, c->diff, f->diffs);
+    compute_metric(c, parity?f->prev:f, 0, parity?f:f->prev, 1, c->comb, f->comb);
+    compute_metric(c, f, parity, f, -1, c->var, f->var);
+
+    /* Advance the circular list */
+    if (!c->first) c->first = c->head;
+    c->last = c->head;
+    c->head = c->head->next;
+}
+
+void 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);
+        f->buffer = 0;
+    }
+    c->first = c->last = 0;
+}
+
+
+
+
+
+
+
+
+#define F_HAVE_BREAKS 1
+#define F_HAVE_AFFINITY 2
+
+
+#define BREAK_LEFT 1
+#define BREAK_RIGHT 2
+
+
+
+
+static int queue_length(struct pullup_field *begin, struct pullup_field *end)
+{
+    int count = 1;
+    struct pullup_field *f;
+
+    if (!begin || !end) return 0;
+    for (f = begin; f != end; f = f->next) count++;
+    return count;
+}
+
+static int find_first_break(struct pullup_field *f, int max)
+{
+    int i;
+    for (i = 0; i < max; i++) {
+        if (f->breaks & BREAK_RIGHT || f->next->breaks & BREAK_LEFT)
+            return i+1;
+        f = f->next;
+    }
+    return 0;
+}
+
+static void compute_breaks(struct pullup_context *c, struct pullup_field *f0)
+{
+    int i;
+    struct pullup_field *f1 = f0->next;
+    struct pullup_field *f2 = f1->next;
+    struct pullup_field *f3 = f2->next;
+    int l, max_l=0, max_r=0;
+    //struct pullup_field *ff;
+    //for (i=0, ff=c->first; ff != f0; i++, ff=ff->next);
+
+    if (f0->flags & F_HAVE_BREAKS) return;
+    //printf("\n%d: ", i);
+    f0->flags |= F_HAVE_BREAKS;
+
+    /* Special case when fields are 100% identical */
+    if (f0->buffer == f2->buffer && f1->buffer != f3->buffer) {
+        f2->breaks |= BREAK_RIGHT;
+        return;
+    }
+    if (f0->buffer != f2->buffer && f1->buffer == f3->buffer) {
+        f1->breaks |= BREAK_LEFT;
+        return;
+    }
+
+    for (i = 0; i < c->metric_len; i++) {
+        l = f2->diffs[i] - f3->diffs[i];
+        if (l > max_l) max_l = l;
+        if (-l > max_r) max_r = -l;
+    }
+    /* Don't get tripped up when differences are mostly quant error */
+    //printf("%d %d\n", max_l, max_r);
+    if (max_l + max_r < 128) return;
+    if (max_l > 4*max_r) f1->breaks |= BREAK_LEFT;
+    if (max_r > 4*max_l) f2->breaks |= BREAK_RIGHT;
+}
+
+static void compute_affinity(struct pullup_context *c, struct pullup_field *f)
+{
+    int i;
+    int max_l=0, max_r=0, l;
+    if (f->flags & F_HAVE_AFFINITY) return;
+    f->flags |= F_HAVE_AFFINITY;
+    if (f->buffer == f->next->next->buffer) {
+        f->affinity = 1;
+        f->next->affinity = 0;
+        f->next->next->affinity = -1;
+        f->next->flags |= F_HAVE_AFFINITY;
+        f->next->next->flags |= F_HAVE_AFFINITY;
+        return;
+    }
+    if (1) {
+        for (i = 0; i < c->metric_len; i++) {
+            int lv = f->prev->var[i];
+            int rv = f->next->var[i];
+            int v = f->var[i];
+            int lc = f->comb[i] - (v+lv) + ABS(v-lv);
+            int rc = f->next->comb[i] - (v+rv) + ABS(v-rv);
+            lc = lc>0 ? lc : 0;
+            rc = rc>0 ? rc : 0;
+            l = lc - rc;
+            if (l > max_l) max_l = l;
+            if (-l > max_r) max_r = -l;
+        }
+        if (max_l + max_r < 64) return;
+        if (max_r > 6*max_l) f->affinity = -1;
+        else if (max_l > 6*max_r) f->affinity = 1;
+    } else {
+        for (i = 0; i < c->metric_len; i++) {
+            l = f->comb[i] - f->next->comb[i];
+            if (l > max_l) max_l = l;
+            if (-l > max_r) max_r = -l;
+        }
+        if (max_l + max_r < 64) return;
+        if (max_r > 2*max_l) f->affinity = -1;
+        else if (max_l > 2*max_r) f->affinity = 1;
+    }
+}
+
+static void foo(struct pullup_context *c)
+{
+    struct pullup_field *f = c->first;
+    int i, n = queue_length(f, c->last);
+    for (i = 0; i < n-1; i++) {
+        if (i < n-3) compute_breaks(c, f);
+        compute_affinity(c, f);
+        f = f->next;
+    }
+}
+
+static int decide_frame_length(struct pullup_context *c)
+{
+    struct pullup_field *f0 = c->first;
+    struct pullup_field *f1 = f0->next;
+    struct pullup_field *f2 = f1->next;
+    int l;
+
+    if (queue_length(c->first, c->last) < 4) return 0;
+    foo(c);
+
+    if (f0->affinity == -1) return 1;
+
+    l = find_first_break(f0, 3);
+    if (l == 1 && c->strict_breaks < 0) l = 0;
+
+    switch (l) {
+    case 1:
+        if (c->strict_breaks < 1 && f0->affinity == 1 && f1->affinity == -1)
+            return 2;
+        else return 1;
+    case 2:
+        /* FIXME: strictly speaking, f0->prev is no longer valid... :) */
+        if (c->strict_pairs
+            && (f0->prev->breaks & BREAK_RIGHT) && (f2->breaks & BREAK_LEFT)
+            && (f0->affinity != 1 || f1->affinity != -1) )
+            return 1;
+        if (f1->affinity == 1) return 1;
+        else return 2;
+    case 3:
+        if (f2->affinity == 1) return 2;
+        else return 3;
+    default:
+        /* 9 possibilities covered before switch */
+        if (f1->affinity == 1) return 1; /* covers 6 */
+        else if (f1->affinity == -1) return 2; /* covers 6 */
+        else if (f2->affinity == -1) { /* covers 2 */
+            if (f0->affinity == 1) return 3;
+            else return 1;
+        }
+        else return 2; /* the remaining 6 */
+    }
+}
+
+
+static void print_aff_and_breaks(struct pullup_context *c, struct pullup_field *f)
+{
+    int i;
+    struct pullup_field *f0 = f;
+    const char aff_l[] = "+..", aff_r[] = "..+";
+    printf("\naffinity: ");
+    for (i = 0; i < 4; i++) {
+        printf("%c%d%c", aff_l[1+f->affinity], i, aff_r[1+f->affinity]);
+        f = f->next;
+    }
+    f = f0;
+    printf("\nbreaks:   ");
+    for (i=0; i<4; i++) {
+        printf("%c%d%c", f->breaks & BREAK_LEFT ? '|' : '.', i, f->breaks & BREAK_RIGHT ? '|' : '.');
+        f = f->next;
+    }
+    printf("\n");
+}
+
+
+
+
+
+struct pullup_frame *pullup_get_frame(struct pullup_context *c)
+{
+    int i;
+    struct pullup_frame *fr = c->frame;
+    int n = decide_frame_length(c);
+    int aff = c->first->next->affinity;
+
+    if (!n) return 0;
+    if (fr->lock) return 0;
+
+    if (c->verbose) {
+        print_aff_and_breaks(c, c->first);
+        printf("duration: %d    \n", n);
+    }
+
+    fr->lock++;
+    fr->length = n;
+    fr->parity = c->first->parity;
+    fr->buffer = 0;
+    for (i = 0; i < n; i++) {
+        /* We cheat and steal the buffer without release+relock */
+        fr->ifields[i] = c->first->buffer;
+        c->first->buffer = 0;
+        c->first = c->first->next;
+    }
+
+    if (n == 1) {
+        fr->ofields[fr->parity] = fr->ifields[0];
+        fr->ofields[fr->parity^1] = 0;
+    } else if (n == 2) {
+        fr->ofields[fr->parity] = fr->ifields[0];
+        fr->ofields[fr->parity^1] = fr->ifields[1];
+    } else if (n == 3) {
+        if (aff == 0)
+            aff = (fr->ifields[0] == fr->ifields[1]) ? -1 : 1;
+        /* else if (c->verbose) printf("forced aff: %d    \n", aff); */
+        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);
+
+    if (fr->ofields[0] == fr->ofields[1]) {
+        fr->buffer = fr->ofields[0];
+        pullup_lock_buffer(fr->buffer, 2);
+        return fr;
+    }
+    return fr;
+}
+
+static void copy_field(struct pullup_context *c, struct pullup_buffer *dest,
+    struct pullup_buffer *src, int parity)
+{
+    int i, j;
+    unsigned char *d, *s;
+    for (i = 0; i < c->nplanes; i++) {
+        s = src->planes[i] + parity*c->stride[i];
+        d = dest->planes[i] + parity*c->stride[i];
+        for (j = c->h[i]>>1; j; j--) {
+            memcpy(d, s, c->stride[i]);
+            s += c->stride[i]<<1;
+            d += c->stride[i]<<1;
+        }
+    }
+}
+
+void pullup_pack_frame(struct pullup_context *c, struct pullup_frame *fr)
+{
+    int i;
+    if (fr->buffer) return;
+    if (fr->length < 2) return; /* FIXME: deal with this */
+    for (i = 0; i < 2; i++)
+    {
+        if (fr->ofields[i]->lock[i^1]) continue;
+        fr->buffer = fr->ofields[i];
+        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);
+    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)
+{
+    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);
+    fr->lock--;
+}
+
+
+
+
+
+
+struct pullup_context *pullup_alloc_context(void)
+{
+    struct pullup_context *c;
+
+    c = calloc(1, sizeof(struct pullup_context));
+
+    return c;
+}
+
+void pullup_preinit_context(struct pullup_context *c)
+{
+    c->bpp = calloc(c->nplanes, sizeof(int));
+    c->w = calloc(c->nplanes, sizeof(int));
+    c->h = calloc(c->nplanes, sizeof(int));
+    c->stride = calloc(c->nplanes, sizeof(int));
+    c->background = calloc(c->nplanes, sizeof(int));
+}
+
+void pullup_init_context(struct pullup_context *c)
+{
+    int mp = c->metric_plane;
+    if (c->nbuffers < 10) c->nbuffers = 10;
+    c->buffers = calloc(c->nbuffers, sizeof (struct pullup_buffer));
+
+    c->metric_w = (c->w[mp] - ((c->junk_left + c->junk_right) << 3)) >> 3;
+    c->metric_h = (c->h[mp] - ((c->junk_top + c->junk_bottom) << 1)) >> 3;
+    c->metric_offset = c->junk_left*c->bpp[mp] + (c->junk_top<<1)*c->stride[mp];
+    c->metric_len = c->metric_w * c->metric_h;
+
+    c->head = make_field_queue(c, 8);
+
+    c->frame = calloc(1, sizeof (struct pullup_frame));
+    c->frame->ifields = calloc(3, sizeof (struct pullup_buffer *));
+
+    switch(c->format) {
+    case PULLUP_FMT_Y:
+        c->diff = diff_y;
+        c->comb = licomb_y;
+        c->var = var_y;
+#if ARCH_X86
+#if HAVE_MMX
+        if (c->cpu & PULLUP_CPU_MMX) {
+            c->diff = diff_y_mmx;
+            c->comb = licomb_y_mmx;
+            c->var = var_y_mmx;
+        }
+#endif
+#endif
+        /* c->comb = qpcomb_y; */
+        break;
+#if 0
+    case PULLUP_FMT_YUY2:
+        c->diff = diff_yuy2;
+        break;
+    case PULLUP_FMT_RGB32:
+        c->diff = diff_rgb32;
+        break;
+#endif
+    }
+}
+
+void pullup_free_context(struct pullup_context *c)
+{
+    struct pullup_field *f;
+    free(c->buffers);
+    f = c->head;
+    do {
+        if (!f) break;
+        free(f->diffs);
+        free(f->comb);
+        f = f->next;
+        free(f->prev);
+    } while (f != c->head);
+    free(c->frame);
+    free(c);
+}
diff --git a/libavfilter/libmpcodecs/pullup.h b/libavfilter/libmpcodecs/pullup.h
new file mode 100644
index 0000000..9c74fb5
--- /dev/null
+++ b/libavfilter/libmpcodecs/pullup.h
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+#ifndef MPLAYER_PULLUP_H
+#define MPLAYER_PULLUP_H
+
+#define PULLUP_CPU_MMX 1
+#define PULLUP_CPU_MMX2 2
+#define PULLUP_CPU_3DNOW 4
+#define PULLUP_CPU_3DNOWEXT 8
+#define PULLUP_CPU_SSE 16
+#define PULLUP_CPU_SSE2 32
+
+#define PULLUP_FMT_Y 1
+#define PULLUP_FMT_YUY2 2
+#define PULLUP_FMT_UYVY 3
+#define PULLUP_FMT_RGB32 4
+
+struct pullup_buffer
+{
+    int lock[2];
+    unsigned char **planes;
+};
+
+struct pullup_field
+{
+    int parity;
+    struct pullup_buffer *buffer;
+    unsigned int flags;
+    int breaks;
+    int affinity;
+    int *diffs;
+    int *comb;
+    int *var;
+    struct pullup_field *prev, *next;
+};
+
+struct pullup_frame
+{
+    int lock;
+    int length;
+    int parity;
+    struct pullup_buffer **ifields, *ofields[2];
+    struct pullup_buffer *buffer;
+};
+
+struct pullup_context
+{
+    /* Public interface */
+    int format;
+    int nplanes;
+    int *bpp, *w, *h, *stride, *background;
+    unsigned int cpu;
+    int junk_left, junk_right, junk_top, junk_bottom;
+    int verbose;
+    int metric_plane;
+    int strict_breaks;
+    int strict_pairs;
+    /* Internal data */
+    struct pullup_field *first, *last, *head;
+    struct pullup_buffer *buffers;
+    int nbuffers;
+    int (*diff)(unsigned char *, unsigned char *, int);
+    int (*comb)(unsigned char *, unsigned char *, int);
+    int (*var)(unsigned char *, unsigned char *, int);
+    int metric_w, metric_h, metric_len, metric_offset;
+    struct pullup_frame *frame;
+};
+
+
+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);
+
+void pullup_submit_field(struct pullup_context *c, struct pullup_buffer *b, int parity);
+void 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_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);
+
+#endif /* MPLAYER_PULLUP_H */
diff --git a/libavfilter/libmpcodecs/vd_ffmpeg.h b/libavfilter/libmpcodecs/vd_ffmpeg.h
new file mode 100644
index 0000000..004d477
--- /dev/null
+++ b/libavfilter/libmpcodecs/vd_ffmpeg.h
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+#ifndef MPLAYER_VD_FFMPEG_H
+#define MPLAYER_VD_FFMPEG_H
+
+void init_avcodec(void);
+
+#endif /* MPLAYER_VD_FFMPEG_H */
diff --git a/libavfilter/libmpcodecs/vf.h b/libavfilter/libmpcodecs/vf.h
new file mode 100644
index 0000000..9119b62
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf.h
@@ -0,0 +1,169 @@
+/*
+ * 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.
+ */
+
+#ifndef MPLAYER_VF_H
+#define MPLAYER_VF_H
+
+//#include "m_option.h"
+#include "mp_image.h"
+
+//extern m_obj_settings_t* vf_settings;
+//extern const m_obj_list_t vf_obj_list;
+
+struct vf_instance;
+struct vf_priv_s;
+
+typedef struct vf_info_s {
+    const char *info;
+    const char *name;
+    const char *author;
+    const char *comment;
+    int (*vf_open)(struct vf_instance *vf,char* args);
+    // Ptr to a struct dscribing the options
+    const void* opts;
+} vf_info_t;
+
+#define NUM_NUMBERED_MPI 50
+
+typedef struct vf_image_context_s {
+    mp_image_t* static_images[2];
+    mp_image_t* temp_images[1];
+    mp_image_t* export_images[1];
+    mp_image_t* numbered_images[NUM_NUMBERED_MPI];
+    int static_idx;
+} vf_image_context_t;
+
+typedef struct vf_format_context_t {
+    int have_configured;
+    int orig_width, orig_height, orig_fmt;
+} vf_format_context_t;
+
+typedef struct vf_instance {
+    const vf_info_t* info;
+    // funcs:
+    int (*config)(struct vf_instance *vf,
+        int width, int height, int d_width, int d_height,
+        unsigned int flags, unsigned int outfmt);
+    int (*control)(struct vf_instance *vf,
+        int request, void* data);
+    int (*query_format)(struct vf_instance *vf,
+        unsigned int fmt);
+    void (*get_image)(struct vf_instance *vf,
+        mp_image_t *mpi);
+    int (*put_image)(struct vf_instance *vf,
+        mp_image_t *mpi, double pts);
+    void (*start_slice)(struct vf_instance *vf,
+        mp_image_t *mpi);
+    void (*draw_slice)(struct vf_instance *vf,
+        unsigned char** src, int* stride, int w,int h, int x, int y);
+    void (*uninit)(struct vf_instance *vf);
+
+    int (*continue_buffered_image)(struct vf_instance *vf);
+    // caps:
+    unsigned int default_caps; // used by default query_format()
+    unsigned int default_reqs; // used by default config()
+    // data:
+    int w, h;
+    vf_image_context_t imgctx;
+    vf_format_context_t fmt;
+    struct vf_instance *next;
+    mp_image_t *dmpi;
+    struct vf_priv_s* priv;
+} vf_instance_t;
+
+// control codes:
+#include "mpc_info.h"
+
+typedef struct vf_seteq_s
+{
+    const char *item;
+    int value;
+} vf_equalizer_t;
+
+#define VFCTRL_QUERY_MAX_PP_LEVEL 4 /* test for postprocessing support (max level) */
+#define VFCTRL_SET_PP_LEVEL 5 /* set postprocessing level */
+#define VFCTRL_SET_EQUALIZER 6 /* set color options (brightness,contrast etc) */
+#define VFCTRL_GET_EQUALIZER 8 /* gset color options (brightness,contrast etc) */
+#define VFCTRL_DRAW_OSD 7
+#define VFCTRL_CHANGE_RECTANGLE 9 /* Change the rectangle boundaries */
+#define VFCTRL_FLIP_PAGE 10 /* Tell the vo to flip pages */
+#define VFCTRL_DUPLICATE_FRAME 11 /* For encoding - encode zero-change frame */
+#define VFCTRL_SKIP_NEXT_FRAME 12 /* For encoding - drop the next frame that passes thru */
+#define VFCTRL_FLUSH_FRAMES    13 /* For encoding - flush delayed frames */
+#define VFCTRL_SCREENSHOT      14 /* Make a screenshot */
+#define VFCTRL_INIT_EOSD       15 /* Select EOSD renderer */
+#define VFCTRL_DRAW_EOSD       16 /* Render EOSD */
+#define VFCTRL_GET_PTS         17 /* Return last pts value that reached vf_vo*/
+#define VFCTRL_SET_DEINTERLACE 18 /* Set deinterlacing status */
+#define VFCTRL_GET_DEINTERLACE 19 /* Get deinterlacing status */
+
+#include "vfcap.h"
+
+//FIXME this should be in a common header, but i dunno which
+#define MP_NOPTS_VALUE (-1LL<<63) //both int64_t and double should be able to represent this exactly
+
+
+// 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);
+
+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* 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);
+
+// default wrappers:
+int 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);
+
+vf_instance_t* append_filters(vf_instance_t* last);
+
+void vf_uninit_filter(vf_instance_t* vf);
+void vf_uninit_filter_chain(vf_instance_t* vf);
+
+int vf_config_wrapper(struct vf_instance *vf,
+                      int width, int height, int d_width, int d_height,
+                      unsigned int flags, unsigned int outfmt);
+
+static inline int norm_qscale(int qscale, int type)
+{
+    switch (type) {
+    case 0: // MPEG-1
+        return qscale;
+    case 1: // MPEG-2
+        return qscale >> 1;
+    case 2: // H264
+        return qscale >> 2;
+    case 3: // VP56
+        return (63 - qscale + 2) >> 2;
+    }
+    return qscale;
+}
+
+#endif /* MPLAYER_VF_H */
diff --git a/libavfilter/libmpcodecs/vf_denoise3d.c b/libavfilter/libmpcodecs/vf_denoise3d.c
new file mode 100644
index 0000000..a952a22
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_denoise3d.c
@@ -0,0 +1,268 @@
+/*
+ * 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
new file mode 100644
index 0000000..28d20e0
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_detc.c
@@ -0,0 +1,453 @@
+/*
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "mp_msg.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "libvo/fastmemcpy.h"
+
+struct metrics {
+        int even;
+        int odd;
+        int noise;
+        int temp;
+};
+
+struct vf_priv_s {
+        int frame;
+        int drop, lastdrop;
+        struct metrics pm;
+        int thres[5];
+        int inframes, outframes;
+        int mode;
+        int (*analyze)(struct vf_priv_s *, mp_image_t *, mp_image_t *);
+        int needread;
+};
+
+#define COMPE(a,b,e) (abs((a)-(b)) < (((a)+(b))>>(e)))
+#define COMPARABLE(a,b) COMPE((a),(b),2)
+#define VERYCLOSE(a,b) COMPE((a),(b),3)
+
+#define OUTER_TC_NBHD(s) ( \
+ COMPARABLE((s)[-1].m.even,(s)[-1].m.odd) && \
+ COMPARABLE((s)[1].m.even,(s)[0].m.odd) && \
+ COMPARABLE((s)[2].m.even,(s)[1].m.odd) && \
+ COMPARABLE((s)[-1].m.noise,(s)[0].m.temp) && \
+ COMPARABLE((s)[2].m.noise,(s)[2].m.temp) )
+
+#define INNER_TC_NBHD(s,l,h) ( \
+ COMPARABLE((s)[0].m.even,(l)) && \
+ COMPARABLE((s)[2].m.odd,(l)) && ( \
+ COMPARABLE((s)[0].m.noise,(h)) || \
+ COMPARABLE((s)[1].m.noise,(h)) ) )
+
+enum {
+        TC_DROP,
+        TC_PROG,
+        TC_IL1,
+        TC_IL2
+};
+
+static void block_diffs(struct metrics *m, unsigned char *old, unsigned char *new, int os, int ns)
+{
+        int x, y, even=0, odd=0, noise, temp;
+        unsigned char *oldp, *newp;
+        m->noise = m->temp = 0;
+        for (x = 8; x; x--) {
+                oldp = old++;
+                newp = new++;
+                noise = temp = 0;
+                for (y = 4; y; y--) {
+                        even += abs(newp[0]-oldp[0]);
+                        odd += abs(newp[ns]-oldp[os]);
+                        noise += newp[ns]-newp[0];
+                        temp += oldp[os]-newp[0];
+                        oldp += os<<1;
+                        newp += ns<<1;
+                }
+                m->noise += abs(noise);
+                m->temp += abs(temp);
+        }
+        m->even = even;
+        m->odd = odd;
+}
+
+static void diff_planes(struct metrics *m, unsigned char *old, unsigned char *new, int w, int h, int os, int ns)
+{
+        int x, y, me=0, mo=0, mn=0, mt=0;
+        struct metrics l;
+        for (y = 0; y < h-7; y += 8) {
+                for (x = 0; x < w-7; x += 8) {
+                        block_diffs(&l, old+x+y*os, new+x+y*ns, os, ns);
+                        if (l.even > me) me = l.even;
+                        if (l.odd > mo) mo = l.odd;
+                        if (l.noise > mn) mn = l.noise;
+                        if (l.temp > mt) mt = l.temp;
+                }
+        }
+        m->even = me;
+        m->odd = mo;
+        m->noise = mn;
+        m->temp = mt;
+}
+
+static void diff_fields(struct metrics *metr, mp_image_t *old, mp_image_t *new)
+{
+        struct metrics m, mu, mv;
+        diff_planes(&m, old->planes[0], new->planes[0],
+                new->w, new->h, old->stride[0], new->stride[0]);
+        if (new->flags & MP_IMGFLAG_PLANAR) {
+                diff_planes(&mu, old->planes[1], new->planes[1],
+                        new->chroma_width, new->chroma_height,
+                        old->stride[1], new->stride[1]);
+                diff_planes(&mv, old->planes[2], new->planes[2],
+                        new->chroma_width, new->chroma_height,
+                        old->stride[2], new->stride[2]);
+                if (mu.even > m.even) m.even = mu.even;
+                if (mu.odd > m.odd) m.odd = mu.odd;
+                if (mu.noise > m.noise) m.noise = mu.noise;
+                if (mu.temp > m.temp) m.temp = mu.temp;
+                if (mv.even > m.even) m.even = mv.even;
+                if (mv.odd > m.odd) m.odd = mv.odd;
+                if (mv.noise > m.noise) m.noise = mv.noise;
+                if (mv.temp > m.temp) m.temp = mv.temp;
+        }
+        *metr = m;
+}
+
+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",
+                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);
+        switch (p->frame) {
+        case -1: case 0: case 1: case 2:
+                return TC_PROG;
+        case 3:
+                return TC_IL1;
+        case 4:
+                return TC_IL2;
+        }
+        return 0;
+}
+
+static int analyze_aggressive(struct vf_priv_s *p, mp_image_t *new, mp_image_t *old)
+{
+        struct metrics m, pm;
+
+        if (p->frame >= 0) p->frame = (p->frame+1)%5;
+
+        diff_fields(&m, old, new);
+
+        status(p->frame, &m);
+
+        pm = p->pm;
+        p->pm = m;
+
+        if (p->frame == 4) {
+                /* 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");
+                        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");
+                                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");
+                                p->pm = pm; /* hack :) */
+                                p->frame = 3;
+                                return TC_IL1;
+                        }
+                } else {
+                        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");
+                p->frame = 3;
+                return TC_IL1;
+        }
+
+        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");
+                                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");
+                                return TC_DROP;
+                        }
+                }
+        }
+
+        switch (p->frame) {
+        case -1:
+                if (4*m.noise > 5*m.temp) {
+                        mp_msg(MSGT_VFILTER, MSGL_V, "merging fields out of sequence!\n");
+                        return TC_IL2;
+                }
+        case 0:
+        case 1:
+        case 2:
+                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");
+                        p->frame = -1;
+                        return TC_PROG;
+                }
+                return TC_IL1;
+        case 4:
+                return TC_IL2;
+        }
+        return 0;
+}
+
+static void copy_image(mp_image_t *dmpi, mp_image_t *mpi, int field)
+{
+        switch (field) {
+        case 0:
+                my_memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2,
+                        dmpi->stride[0]*2, mpi->stride[0]*2);
+                if (mpi->flags & MP_IMGFLAG_PLANAR) {
+                        my_memcpy_pic(dmpi->planes[1], mpi->planes[1],
+                                mpi->chroma_width, mpi->chroma_height/2,
+                                dmpi->stride[1]*2, mpi->stride[1]*2);
+                        my_memcpy_pic(dmpi->planes[2], mpi->planes[2],
+                                mpi->chroma_width, mpi->chroma_height/2,
+                                dmpi->stride[2]*2, mpi->stride[2]*2);
+                }
+                break;
+        case 1:
+                my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0],
+                        mpi->planes[0]+mpi->stride[0], mpi->w, mpi->h/2,
+                        dmpi->stride[0]*2, mpi->stride[0]*2);
+                if (mpi->flags & MP_IMGFLAG_PLANAR) {
+                        my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1],
+                                mpi->planes[1]+mpi->stride[1],
+                                mpi->chroma_width, mpi->chroma_height/2,
+                                dmpi->stride[1]*2, mpi->stride[1]*2);
+                        my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2],
+                                mpi->planes[2]+mpi->stride[2],
+                                mpi->chroma_width, mpi->chroma_height/2,
+                                dmpi->stride[2]*2, mpi->stride[2]*2);
+                }
+                break;
+        case 2:
+                memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h,
+                        dmpi->stride[0], mpi->stride[0]);
+                if (mpi->flags & MP_IMGFLAG_PLANAR) {
+                        memcpy_pic(dmpi->planes[1], mpi->planes[1],
+                                mpi->chroma_width, mpi->chroma_height,
+                                dmpi->stride[1], mpi->stride[1]);
+                        memcpy_pic(dmpi->planes[2], mpi->planes[2],
+                                mpi->chroma_width, mpi->chroma_height,
+                                dmpi->stride[2], mpi->stride[2]);
+                }
+                break;
+        }
+}
+
+static int do_put_image(struct vf_instance *vf, mp_image_t *dmpi)
+{
+        struct vf_priv_s *p = vf->priv;
+        int dropflag;
+
+        switch (p->drop) {
+        default:
+                dropflag = 0;
+                break;
+        case 1:
+                dropflag = (++p->lastdrop >= 5);
+                break;
+        case 2:
+                dropflag = (++p->lastdrop >= 5) && (4*p->inframes <= 5*p->outframes);
+                break;
+        }
+
+        if (dropflag) {
+                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);
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+        int ret=0;
+        mp_image_t *dmpi;
+        struct vf_priv_s *p = vf->priv;
+
+        p->inframes++;
+
+        if (p->needread) dmpi = 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,
+                MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
+                MP_IMGFLAG_PRESERVE, mpi->width, mpi->height);
+
+        switch (p->analyze(p, mpi, dmpi)) {
+        case TC_DROP:
+                /* Don't copy anything unless we'll need to read it. */
+                if (p->needread) copy_image(dmpi, mpi, 2);
+                p->lastdrop = 0;
+                break;
+        case TC_PROG:
+                /* Copy and display the whole frame. */
+                copy_image(dmpi, mpi, 2);
+                ret = do_put_image(vf, dmpi);
+                break;
+        case TC_IL1:
+                /* Only copy bottom field unless we need to read. */
+                if (p->needread) copy_image(dmpi, mpi, 2);
+                else copy_image(dmpi, mpi, 1);
+                p->lastdrop = 0;
+                break;
+        case TC_IL2:
+                /* Copy top field and show frame, then copy bottom if needed. */
+                copy_image(dmpi, mpi, 0);
+                ret = do_put_image(vf, dmpi);
+                if (p->needread) copy_image(dmpi, mpi, 1);
+                break;
+        }
+        return ret;
+}
+
+static int query_format(struct vf_instance *vf, unsigned int fmt)
+{
+        /* FIXME - figure out which other formats work */
+        switch (fmt) {
+        case IMGFMT_YV12:
+        case IMGFMT_IYUV:
+        case IMGFMT_I420:
+                return vf_next_query_format(vf, fmt);
+        }
+        return 0;
+}
+
+static int config(struct vf_instance *vf,
+        int width, int height, int d_width, int d_height,
+        unsigned int flags, unsigned int outfmt)
+{
+        return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+}
+
+static void uninit(struct vf_instance *vf)
+{
+        free(vf->priv);
+}
+
+static struct {
+        const char *name;
+        int (*func)(struct vf_priv_s *p, mp_image_t *new, mp_image_t *old);
+        int needread;
+} anal_funcs[] = {
+        { "fixed", analyze_fixed_pattern, 0 },
+        { "aggressive", analyze_aggressive, 1 },
+        { NULL, NULL, 0 }
+};
+
+#define STARTVARS if (0)
+#define GETVAR(str, name, out, func) \
+ else if (!strncmp((str), name "=", sizeof(name))) \
+ (out) = (func)((str) + sizeof(name))
+
+static void parse_var(struct vf_priv_s *p, char *var)
+{
+        STARTVARS;
+        GETVAR(var, "dr", p->drop, atoi);
+        GETVAR(var, "t0", p->thres[0], atoi);
+        GETVAR(var, "t1", p->thres[1], atoi);
+        GETVAR(var, "t2", p->thres[2], atoi);
+        GETVAR(var, "t3", p->thres[3], atoi);
+        GETVAR(var, "t4", p->thres[4], atoi);
+        GETVAR(var, "fr", p->frame, atoi);
+        GETVAR(var, "am", p->mode, atoi);
+}
+
+static void parse_args(struct vf_priv_s *p, char *args)
+{
+        char *next, *orig;
+        for (args=orig=av_strdup(args); args; args=next) {
+                next = strchr(args, ':');
+                if (next) *next++ = 0;
+                parse_var(p, args);
+        }
+        free(orig);
+}
+
+static int vf_open(vf_instance_t *vf, char *args)
+{
+        struct vf_priv_s *p;
+        vf->config = config;
+        vf->put_image = put_image;
+        vf->query_format = query_format;
+        vf->uninit = uninit;
+        vf->default_reqs = VFCAP_ACCEPT_STRIDE;
+        vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
+        p->frame = -1;
+        p->thres[0] = 440;
+        p->thres[1] = 720;
+        p->thres[2] = 2500;
+        p->thres[3] = 2500;
+        p->thres[4] = 800;
+        p->drop = 0;
+        p->mode = 1;
+        if (args) parse_args(p, args);
+        p->analyze = anal_funcs[p->mode].func;
+        p->needread = anal_funcs[p->mode].needread;
+        return 1;
+}
+
+const vf_info_t vf_info_detc = {
+    "de-telecine filter",
+    "detc",
+    "Rich Felker",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_dint.c b/libavfilter/libmpcodecs/vf_dint.c
new file mode 100644
index 0000000..ac5bf54
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_dint.c
@@ -0,0 +1,214 @@
+/*
+ * 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 "mp_image.h"
+#include "img_format.h"
+#include "vf.h"
+
+struct vf_priv_s {
+  float sense; // first parameter
+  float level; // second parameter
+  unsigned int imgfmt;
+  int diff;
+  uint32_t max;
+//  int dfr;
+//  int rdfr;
+  int was_dint;
+  mp_image_t *pmpi; // previous mpi
+};
+
+#define MAXROWSIZE 1200
+
+static int config (struct vf_instance *vf,
+        int width, int height, int d_width, int d_height,
+        unsigned int flags, unsigned int outfmt)
+{
+    int rowsize;
+
+    vf->priv->pmpi = 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");
+      return 0;
+    }
+    vf->priv->imgfmt = outfmt;
+    // recalculate internal values
+    rowsize = vf->priv->pmpi->width;
+    if (rowsize > MAXROWSIZE) rowsize = MAXROWSIZE;
+    vf->priv->max = vf->priv->level * vf->priv->pmpi->height * rowsize / 2;
+    if (vf->priv->pmpi->flags & MP_IMGFLAG_PLANAR) // planar YUV
+      vf->priv->diff = vf->priv->sense * 256;
+    else
+      vf->priv->diff = vf->priv->sense * (1 << (vf->priv->pmpi->bpp/3));
+    if (vf->priv->diff < 0) vf->priv->diff = 0;
+    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",
+           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);
+}
+
+static int put_image (struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+    int8_t rrow0[MAXROWSIZE];
+    int8_t rrow1[MAXROWSIZE];
+    int8_t rrow2[MAXROWSIZE];
+    int8_t *row0 = rrow0, *row1 = rrow1, *row2 = rrow2/*, *row3 = rrow3*/;
+    int rowsize = mpi->width;
+    uint32_t nok = 0, max = vf->priv->max;
+    int diff = vf->priv->diff;
+    int i, j;
+    register int n1, n2;
+    unsigned char *cur0, *prv0;
+    register unsigned char *cur, *prv;
+
+    if (rowsize > MAXROWSIZE) rowsize = MAXROWSIZE;
+    // check if nothing to do
+    if (mpi->imgfmt == vf->priv->imgfmt)
+    {
+      cur0 = mpi->planes[0] + mpi->stride[0];
+      prv0 = mpi->planes[0];
+      for (j = 1; j < mpi->height && nok <= max; j++)
+      {
+        cur = cur0;
+        prv = prv0;
+        // analyse row (row0)
+        if (mpi->flags & MP_IMGFLAG_PLANAR) // planar YUV - check luminance
+          for (i = 0; i < rowsize; i++)
+          {
+            if (cur[0] - prv[0] > diff)
+              row0[i] = 1;
+            else if (cur[0] - prv[0] < -diff)
+              row0[i] = -1;
+            else
+              row0[i] = 0;
+            cur++;
+            prv++;
+            // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
+            // but row3 is 1 so it's interlaced ptr (nok++)
+            if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
+                (++nok) > max)
+              break;
+          }
+        else if (mpi->bpp < 24) // RGB/BGR 16 - check all colors
+          for (i = 0; i < rowsize; i++)
+          {
+            n1 = cur[0] + (cur[1]<<8);
+            n2 = prv[0] + (prv[1]<<8);
+            if ((n1&0x1f) - (n2&0x1f) > diff ||
+                ((n1>>5)&0x3f) - ((n2>>5)&0x3f) > diff ||
+                ((n1>>11)&0x1f) - ((n2>>11)&0x1f) > diff)
+              row0[i] = 1;
+            else if ((n1&0x1f) - (n2&0x1f) < -diff ||
+                     ((n1>>5)&0x3f) - ((n2>>5)&0x3f) < -diff ||
+                     ((n1>>11)&0x1f) - ((n2>>11)&0x1f) < -diff)
+              row0[i] = -1;
+            else
+              row0[i] = 0;
+            cur += 2;
+            prv += 2;
+            // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
+            // but row3 is 1 so it's interlaced ptr (nok++)
+            if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
+                (++nok) > max)
+              break;
+          }
+        else // RGB/BGR 24/32
+          for (i = 0; i < rowsize; i++)
+          {
+            if (cur[0] - prv[0] > diff ||
+                cur[1] - prv[1] > diff ||
+                cur[2] - prv[2] > diff)
+              row0[i] = 1;
+            else if (prv[0] - cur[0] > diff ||
+                     prv[1] - cur[1] > diff ||
+                     prv[2] - cur[2] > diff)
+              row0[i] = -1;
+            else
+              row0[i] = 0;
+            cur += mpi->bpp/8;
+            prv += mpi->bpp/8;
+            // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
+            // but row3 is 1 so it's interlaced ptr (nok++)
+            if (j > 2 && row0[i] > 0 && (row1[i] < 0 || (!row1[i] && row2[i] < 0)) &&
+                (++nok) > max)
+              break;
+          }
+        cur0 += mpi->stride[0];
+        prv0 += mpi->stride[0];
+        // rotate rows
+        cur = row2;
+        row2 = row1;
+        row1 = row0;
+        row0 = cur;
+      }
+    }
+    // check if number of interlaced is above of max
+    if (nok > max)
+    {
+//    vf->priv->dfr++;
+      if (vf->priv->was_dint < 1) // can skip at most one frame!
+      {
+        vf->priv->was_dint++;
+//      vf->priv->rdfr++;
+//      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);
+}
+
+static int vf_open(vf_instance_t *vf, char *args){
+    vf->config = config;
+    vf->put_image = put_image;
+//  vf->default_reqs=VFCAP_ACCEPT_STRIDE;
+    vf->priv = malloc (sizeof(struct vf_priv_s));
+    vf->priv->sense = 0.1;
+    vf->priv->level = 0.15;
+    vf->priv->pmpi = NULL;
+    if (args)
+      sscanf (args, "%f:%f", &vf->priv->sense, &vf->priv->level);
+    return 1;
+}
+
+const vf_info_t vf_info_dint = {
+    "drop interlaced frames",
+    "dint",
+    "A.G.",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_divtc.c b/libavfilter/libmpcodecs/vf_divtc.c
new file mode 100644
index 0000000..4c171d1
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_divtc.c
@@ -0,0 +1,721 @@
+/*
+ * 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 <limits.h>
+#include <math.h>
+
+#include "config.h"
+#include "mp_msg.h"
+#include "cpudetect.h"
+#include "libavutil/common.h"
+#include "mpbswap.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "libvo/fastmemcpy.h"
+
+const vf_info_t vf_info_divtc;
+
+struct vf_priv_s
+   {
+   int deghost, pass, phase, window, fcount, bcount, frameno, misscount,
+      ocount, sum[5];
+   double threshold;
+   FILE *file;
+   int8_t *bdata;
+   unsigned int *csdata;
+   int *history;
+   };
+
+/*
+ * diff_MMX and diff_C stolen from vf_decimate.c
+ */
+
+#if HAVE_MMX && HAVE_EBX_AVAILABLE
+static int diff_MMX(unsigned char *old, unsigned char *new, int os, int ns)
+   {
+   volatile short out[4];
+   __asm__ (
+        "movl $8, %%ecx \n\t"
+        "pxor %%mm4, %%mm4 \n\t"
+        "pxor %%mm7, %%mm7 \n\t"
+
+        ASMALIGN(4)
+        "1: \n\t"
+
+        "movq (%%"REG_S"), %%mm0 \n\t"
+        "movq (%%"REG_S"), %%mm2 \n\t"
+        "add %%"REG_a", %%"REG_S" \n\t"
+        "movq (%%"REG_D"), %%mm1 \n\t"
+        "add %%"REG_b", %%"REG_D" \n\t"
+        "psubusb %%mm1, %%mm2 \n\t"
+        "psubusb %%mm0, %%mm1 \n\t"
+        "movq %%mm2, %%mm0 \n\t"
+        "movq %%mm1, %%mm3 \n\t"
+        "punpcklbw %%mm7, %%mm0 \n\t"
+        "punpcklbw %%mm7, %%mm1 \n\t"
+        "punpckhbw %%mm7, %%mm2 \n\t"
+        "punpckhbw %%mm7, %%mm3 \n\t"
+        "paddw %%mm0, %%mm4 \n\t"
+        "paddw %%mm1, %%mm4 \n\t"
+        "paddw %%mm2, %%mm4 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+
+        "decl %%ecx \n\t"
+        "jnz 1b \n\t"
+        "movq %%mm4, (%%"REG_d") \n\t"
+        "emms \n\t"
+        :
+        : "S" (old), "D" (new), "a" ((long)os), "b" ((long)ns), "d" (out)
+        : "%ecx", "memory"
+        );
+   return out[0]+out[1]+out[2]+out[3];
+   }
+#endif
+
+static int diff_C(unsigned char *old, unsigned char *new, int os, int ns)
+   {
+   int x, y, d=0;
+
+   for(y=8; y; y--, new+=ns, old+=os)
+      for(x=8; x; x--)
+         d+=abs(new[x]-old[x]);
+
+   return d;
+   }
+
+static int (*diff)(unsigned char *, unsigned char *, int, int);
+
+static int diff_plane(unsigned char *old, unsigned char *new,
+                      int w, int h, int os, int ns, int arg)
+   {
+   int x, y, d, max=0, sum=0, n=0;
+
+   for(y=0; y<h-7; y+=8)
+      {
+      for(x=0; x<w-7; x+=8)
+         {
+         d=diff(old+x+y*os, new+x+y*ns, os, ns);
+         if(d>max) max=d;
+         sum+=d;
+         n++;
+         }
+      }
+
+   return (sum+n*max)/2;
+   }
+
+/*
+static unsigned int checksum_plane(unsigned char *p, unsigned char *z,
+                                   int w, int h, int s, int zs, int arg)
+   {
+   unsigned int shift, sum;
+   unsigned char *e;
+
+   for(sum=0; h; h--, p+=s-w)
+      for(e=p+w, shift=32; p<e;)
+         sum^=(*p++)<<(shift=(shift-8)&31);
+
+   return sum;
+   }
+*/
+
+static unsigned int checksum_plane(unsigned char *p, unsigned char *z,
+                                   int w, int h, int s, int zs, int arg)
+   {
+   unsigned int shift;
+   uint32_t sum, t;
+   unsigned char *e, *e2;
+#if HAVE_FAST_64BIT
+   typedef uint64_t wsum_t;
+#else
+   typedef uint32_t wsum_t;
+#endif
+   wsum_t wsum;
+
+   for(sum=0; h; h--, p+=s-w)
+      {
+      for(shift=0, e=p+w; (int)p&(sizeof(wsum_t)-1) && p<e;)
+         sum^=*p++<<(shift=(shift-8)&31);
+
+      for(wsum=0, e2=e-sizeof(wsum_t)+1; p<e2; p+=sizeof(wsum_t))
+         wsum^=*(wsum_t *)p;
+
+#if HAVE_FAST_64BIT
+      t=be2me_32((uint32_t)(wsum>>32^wsum));
+#else
+      t=be2me_32(wsum);
+#endif
+
+      for(sum^=(t<<shift|t>>(32-shift)); p<e;)
+         sum^=*p++<<(shift=(shift-8)&31);
+      }
+
+   return sum;
+   }
+
+static int deghost_plane(unsigned char *d, unsigned char *s,
+                         int w, int h, int ds, int ss, int threshold)
+   {
+   int t;
+   unsigned char *e;
+
+   for(; h; h--, s+=ss-w, d+=ds-w)
+      for(e=d+w; d<e; d++, s++)
+         if(abs(*d-*s)>=threshold)
+            *d=(t=(*d<<1)-*s)<0?0:t>255?255:t;
+
+   return 0;
+   }
+
+static int copyop(unsigned char *d, unsigned char *s, int bpl, int h, int dstride, int sstride, int dummy) {
+  memcpy_pic(d, s, bpl, h, dstride, sstride);
+  return 0;
+}
+
+static int imgop(int(*planeop)(unsigned char *, unsigned char *,
+                               int, int, int, int, int),
+                 mp_image_t *dst, mp_image_t *src, int arg)
+   {
+   if(dst->flags&MP_IMGFLAG_PLANAR)
+      return planeop(dst->planes[0], src?src->planes[0]:0,
+                     dst->w, dst->h,
+                     dst->stride[0], src?src->stride[0]:0, arg)+
+             planeop(dst->planes[1], src?src->planes[1]:0,
+                     dst->chroma_width, dst->chroma_height,
+                     dst->stride[1], src?src->stride[1]:0, arg)+
+             planeop(dst->planes[2], src?src->planes[2]:0,
+                     dst->chroma_width, dst->chroma_height,
+                     dst->stride[2], src?src->stride[2]:0, arg);
+
+   return planeop(dst->planes[0], src?src->planes[0]:0,
+                  dst->w*(dst->bpp/8), dst->h,
+                  dst->stride[0], src?src->stride[0]:0, arg);
+   }
+
+/*
+ * Find the phase in which the telecine pattern fits best to the
+ * given 5 frame slice of frame difference measurements.
+ *
+ * If phase1 and phase2 are not negative, only the two specified
+ * phases are tested.
+ */
+
+static int match(struct vf_priv_s *p, int *diffs,
+                 int phase1, int phase2, double *strength)
+   {
+   static const int pattern1[]={ -4,  1, 1, 1, 1 },
+      pattern2[]={ -2, -3, 4, 4, -3 }, *pattern;
+   int f, m, n, t[5];
+
+   pattern=p->deghost>0?pattern2:pattern1;
+
+   for(f=0; f<5; f++)
+      {
+      if(phase1<0 || phase2<0 || f==phase1 || f==phase2)
+         {
+         for(n=t[f]=0; n<5; n++)
+            t[f]+=diffs[n]*pattern[(n-f+5)%5];
+         }
+      else
+         t[f]=INT_MIN;
+      }
+
+   /* find the best match */
+   for(m=0, n=1; n<5; n++)
+      if(t[n]>t[m]) m=n;
+
+   if(strength)
+      {
+      /* the second best match */
+      for(f=m?0:1, n=f+1; n<5; n++)
+         if(n!=m && t[n]>t[f]) f=n;
+
+      *strength=(t[m]>0?(double)(t[m]-t[f])/t[m]:0.0);
+      }
+
+   return m;
+   }
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+   {
+   mp_image_t *dmpi, *tmpi=0;
+   int n, m, f, newphase;
+   struct vf_priv_s *p=vf->priv;
+   unsigned int checksum;
+   double d;
+
+   dmpi=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);
+
+   newphase=p->phase;
+
+   switch(p->pass)
+      {
+      case 1:
+         fprintf(p->file, "%08x %d\n",
+                 (unsigned int)imgop((void *)checksum_plane, mpi, 0, 0),
+                 p->frameno?imgop(diff_plane, dmpi, mpi, 0):0);
+         break;
+
+      case 2:
+         if(p->frameno/5>p->bcount)
+            {
+            mp_msg(MSGT_VFILTER, MSGL_ERR,
+                   "\n%s: Log file ends prematurely! "
+                   "Switching to one pass mode.\n", vf->info->name);
+            p->pass=0;
+            break;
+            }
+
+         checksum=(unsigned int)imgop((void *)checksum_plane, mpi, 0, 0);
+
+         if(checksum!=p->csdata[p->frameno])
+            {
+            for(f=0; f<100; f++)
+               if(p->frameno+f<p->fcount && p->csdata[p->frameno+f]==checksum)
+                  break;
+               else if(p->frameno-f>=0 && p->csdata[p->frameno-f]==checksum)
+                  {
+                  f=-f;
+                  break;
+                  }
+
+            if(f<100)
+               {
+               mp_msg(MSGT_VFILTER, MSGL_INFO,
+                      "\n%s: Mismatch with pass-1: %+d frame(s).\n",
+                      vf->info->name, f);
+
+               p->frameno+=f;
+               p->misscount=0;
+               }
+            else if(p->misscount++>=30)
+               {
+               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;
+               break;
+               }
+            }
+
+         n=(p->frameno)/5;
+         if(n>=p->bcount) n=p->bcount-1;
+
+         newphase=p->bdata[n];
+         break;
+
+      default:
+         if(p->frameno)
+            {
+            int *sump=p->sum+p->frameno%5,
+               *histp=p->history+p->frameno%p->window;
+
+            *sump-=*histp;
+            *sump+=(*histp=imgop(diff_plane, dmpi, mpi, 0));
+            }
+
+         m=match(p, p->sum, -1, -1, &d);
+
+         if(d>=p->threshold)
+            newphase=m;
+      }
+
+   n=p->ocount++%5;
+
+   if(newphase!=p->phase && ((p->phase+4)%5<n)==((newphase+4)%5<n))
+      {
+      p->phase=newphase;
+      mp_msg(MSGT_VFILTER, MSGL_STATUS,
+             "\n%s: Telecine phase %d.\n", vf->info->name, p->phase);
+      }
+
+   switch((p->frameno++-p->phase+10)%5)
+      {
+      case 0:
+         imgop(copyop, dmpi, mpi, 0);
+         return 0;
+
+      case 4:
+         if(p->deghost>0)
+            {
+            tmpi=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);
+
+            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);
+            }
+      }
+
+   imgop(copyop, dmpi, mpi, 0);
+   return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+   }
+
+static int analyze(struct vf_priv_s *p)
+   {
+   int *buf=0, *bp, bufsize=0, n, b, f, i, j, m, s;
+   unsigned int *cbuf=0, *cp;
+   int8_t *pbuf;
+   int8_t lbuf[256];
+   int sum[5];
+   double d;
+
+   /* read the file */
+
+   n=15;
+   while(fgets(lbuf, 256, p->file))
+      {
+      if(n>=bufsize-19)
+         {
+         bufsize=bufsize?bufsize*2:30000;
+         if((bp=realloc(buf, bufsize*sizeof *buf))) buf=bp;
+         if((cp=realloc(cbuf, bufsize*sizeof *cbuf))) cbuf=cp;
+
+         if(!bp || !cp)
+            {
+            mp_msg(MSGT_VFILTER, MSGL_FATAL, "%s: Not enough memory.\n",
+                   vf_info_divtc.name);
+            free(buf);
+            free(cbuf);
+            return 0;
+            }
+         }
+      sscanf(lbuf, "%x %d", cbuf+n, buf+n);
+      n++;
+      }
+
+   if(!n)
+      {
+      mp_msg(MSGT_VFILTER, MSGL_FATAL, "%s: Empty 2-pass log file.\n",
+             vf_info_divtc.name);
+      free(buf);
+      free(cbuf);
+      return 0;
+      }
+
+   /* generate some dummy data past the beginning and end of the array */
+
+   buf+=15, cbuf+=15;
+   n-=15;
+
+   memcpy(buf-15, buf, 15*sizeof *buf);
+   memset(cbuf-15, 0, 15*sizeof *cbuf);
+
+   while(n%5)
+      buf[n]=buf[n-5], cbuf[n]=0, n++;
+
+   memcpy(buf+n, buf+n-15, 15*sizeof *buf);
+   memset(cbuf+n, 0, 15*sizeof *cbuf);
+
+   p->csdata=cbuf;
+   p->fcount=n;
+
+   /* array with one slot for each slice of 5 frames */
+
+   p->bdata=pbuf=malloc(p->bcount=b=(n/5));
+   memset(pbuf, 255, b);
+
+   /* resolve the automatic mode */
+
+   if(p->deghost<0)
+      {
+      int deghost=-p->deghost;
+      double s0=0.0, s1=0.0;
+
+      for(f=0; f<n; f+=5)
+         {
+         p->deghost=0; match(p, buf+f, -1, -1, &d); s0+=d;
+         p->deghost=1; match(p, buf+f, -1, -1, &d); s1+=d;
+         }
+
+      p->deghost=s1>s0?deghost:0;
+
+      mp_msg(MSGT_VFILTER, MSGL_INFO,
+             "%s: Deghosting %-3s (relative pattern strength %+.2fdB).\n",
+             vf_info_divtc.name,
+             p->deghost?"ON":"OFF",
+             10.0*log10(s1/s0));
+      }
+
+   /* analyze the data */
+
+   for(f=0; f<5; f++)
+      for(sum[f]=0, n=-15; n<20; n+=5)
+         sum[f]+=buf[n+f];
+
+   for(f=0; f<b; f++)
+      {
+      m=match(p, sum, -1, -1, &d);
+
+      if(d>=p->threshold)
+         pbuf[f]=m;
+
+      if(f<b-1)
+         for(n=0; n<5; n++)
+            sum[n]=sum[n]-buf[5*(f-3)+n]+buf[5*(f+4)+n];
+      }
+
+   /* fill in the gaps */
+
+   /* the beginning */
+   for(f=0; f<b && pbuf[f]==-1; f++);
+
+   if(f==b)
+      {
+      free(buf-15);
+      mp_msg(MSGT_VFILTER, MSGL_FATAL, "%s: No telecine pattern found!\n",
+             vf_info_divtc.name);
+      return 0;
+      }
+
+   for(n=0; n<f; pbuf[n++]=pbuf[f]);
+
+   /* the end */
+   for(f=b-1; pbuf[f]==-1; f--);
+   for(n=f+1; n<b; pbuf[n++]=pbuf[f]);
+
+   /* the rest */
+   for(f=0;;)
+      {
+      while(f<b && pbuf[f]!=-1) f++;
+      if(f==b) break;
+      for(n=f; pbuf[n]==-1; n++);
+
+      if(pbuf[f-1]==pbuf[n])
+         {
+         /* just a gap */
+         while(f<n) pbuf[f++]=pbuf[n];
+         }
+      else
+         {
+         /* phase change, reanalyze the original data in the gap with zero
+            threshold for only the two phases that appear at the ends */
+
+         for(i=0; i<5; i++)
+            for(sum[i]=0, j=5*f-15; j<5*f; j+=5)
+               sum[i]+=buf[i+j];
+
+         for(i=f; i<n; i++)
+            {
+            pbuf[i]=match(p, sum, pbuf[f-1], pbuf[n], 0);
+
+            for(j=0; j<5; j++)
+               sum[j]=sum[j]-buf[5*(i-3)+j]+buf[5*(i+4)+j];
+            }
+
+         /* estimate the transition point by dividing the gap
+            in the same proportion as the number of matches of each kind */
+
+         for(i=f, m=f; i<n; i++)
+            if(pbuf[i]==pbuf[f-1]) m++;
+
+         /* find the transition of the right direction nearest to the
+            estimated point */
+
+         if(m>f && m<n)
+            {
+            for(j=m; j>f; j--)
+               if(pbuf[j-1]==pbuf[f-1] && pbuf[j]==pbuf[n]) break;
+            for(s=m; s<n; s++)
+               if(pbuf[s-1]==pbuf[f-1] && pbuf[s]==pbuf[n]) break;
+
+            m=(s-m<m-j)?s:j;
+            }
+
+         /* and rewrite the data to allow only this one transition */
+
+         for(i=f; i<m; i++)
+            pbuf[i]=pbuf[f-1];
+
+         for(; i<n; i++)
+            pbuf[i]=pbuf[n];
+
+         f=n;
+         }
+      }
+
+   free(buf-15);
+
+   return 1;
+   }
+
+static int query_format(struct vf_instance *vf, unsigned int fmt)
+   {
+   switch(fmt)
+      {
+      case IMGFMT_444P: case IMGFMT_IYUV: case IMGFMT_RGB24:
+      case IMGFMT_422P: case IMGFMT_UYVY: case IMGFMT_BGR24:
+      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 0;
+   }
+
+static void uninit(struct vf_instance *vf)
+   {
+   if(vf->priv)
+      {
+      if(vf->priv->file) fclose(vf->priv->file);
+      if(vf->priv->csdata) free(vf->priv->csdata-15);
+      free(vf->priv->bdata);
+      free(vf->priv->history);
+      free(vf->priv);
+      }
+   }
+
+static int vf_open(vf_instance_t *vf, char *args)
+   {
+   struct vf_priv_s *p;
+   const char *filename="framediff.log";
+   char *ap, *q, *a;
+
+   if(args && !(args=av_strdup(args)))
+      {
+   nomem:
+      mp_msg(MSGT_VFILTER, MSGL_FATAL,
+             "%s: Not enough memory.\n", vf->info->name);
+   fail:
+      uninit(vf);
+      free(args);
+      return 0;
+      }
+
+   vf->put_image=put_image;
+   vf->uninit=uninit;
+   vf->query_format=query_format;
+   vf->default_reqs=VFCAP_ACCEPT_STRIDE;
+   if(!(vf->priv=p=calloc(1, sizeof(struct vf_priv_s))))
+      goto nomem;
+
+   p->phase=5;
+   p->threshold=0.5;
+   p->window=30;
+
+   if((ap=args))
+      while(*ap)
+         {
+         q=ap;
+         if((ap=strchr(q, ':'))) *ap++=0; else ap=q+strlen(q);
+         if((a=strchr(q, '='))) *a++=0; else a=q+strlen(q);
+
+         switch(*q)
+            {
+            case 0:                              break;
+            case 'f': filename=a;                break;
+            case 't': p->threshold=atof(a);      break;
+            case 'w': p->window=5*(atoi(a)+4)/5; break;
+            case 'd': p->deghost=atoi(a);        break;
+            case 'p':
+               if(q[1]=='h') p->phase=atoi(a);
+               else p->pass=atoi(a);
+               break;
+
+            case 'h':
+               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 "
+                      "(default %s).\n"
+                      "threshold=value  - Set the pattern recognition "
+                      "sensitivity (default %g).\n"
+                      "deghost=value    - Select deghosting threshold "
+                      "(default %d).\n"
+                      "window=numframes - Set the statistics window "
+                      "for 1-pass mode (default %d).\n"
+                      "phase=0|1|2|3|4  - Set the initial phase "
+                      "for 1-pass mode (default %d).\n\n"
+                      "The option names can be abbreviated to the shortest "
+                      "unique prefix.\n\n",
+                      vf->info->name, filename, p->threshold, p->deghost,
+                      p->window, p->phase%5);
+               break;
+
+            default:
+               mp_msg(MSGT_VFILTER, MSGL_FATAL,
+                      "%s: Unknown argument %s.\n", vf->info->name, q);
+               goto fail;
+            }
+         }
+
+   switch(p->pass)
+      {
+      case 1:
+         if(!(p->file=fopen(filename, "w")))
+            {
+            mp_msg(MSGT_VFILTER, MSGL_FATAL,
+                   "%s: Can't create file %s.\n", vf->info->name, filename);
+            goto fail;
+            }
+
+         break;
+
+      case 2:
+         if(!(p->file=fopen(filename, "r")))
+            {
+            mp_msg(MSGT_VFILTER, MSGL_FATAL,
+                   "%s: Can't open file %s.\n", vf->info->name, filename);
+            goto fail;
+            }
+
+         if(!analyze(p))
+            goto fail;
+
+         fclose(p->file);
+         p->file=0;
+         break;
+      }
+
+   if(p->window<5) p->window=5;
+   if(!(p->history=calloc(sizeof *p->history, p->window)))
+      goto nomem;
+
+   diff = diff_C;
+#if HAVE_MMX && HAVE_EBX_AVAILABLE
+   if(gCpuCaps.hasMMX) diff = diff_MMX;
+#endif
+
+   free(args);
+   return 1;
+   }
+
+const vf_info_t vf_info_divtc =
+   {
+   "inverse telecine for deinterlaced video",
+   "divtc",
+   "Ville Saari",
+   "",
+   vf_open,
+   NULL
+   };
diff --git a/libavfilter/libmpcodecs/vf_down3dright.c b/libavfilter/libmpcodecs/vf_down3dright.c
new file mode 100644
index 0000000..4dba19a
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_down3dright.c
@@ -0,0 +1,166 @@
+/*
+ * 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 "cpudetect.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "libvo/fastmemcpy.h"
+
+struct vf_priv_s {
+        int skipline;
+        int scalew;
+        int scaleh;
+};
+
+static void toright(unsigned char *dst[3], unsigned char *src[3],
+                    int dststride[3], int srcstride[3],
+                    int w, int h, struct vf_priv_s* p)
+{
+        int k;
+
+        for (k = 0; k < 3; k++) {
+                unsigned char* fromL = src[k];
+                unsigned char* fromR = src[k];
+                unsigned char* to = dst[k];
+                int src = srcstride[k];
+                int dst = dststride[k];
+                int ss;
+                unsigned int dd;
+                int i;
+
+                if (k > 0) {
+                        i = h / 4 - p->skipline / 2;
+                        ss = src * (h / 4 + p->skipline / 2);
+                        dd = w / 4;
+                } else {
+                        i = h / 2 - p->skipline;
+                        ss = src * (h / 2 + p->skipline);
+                        dd = w / 2;
+                }
+                fromR += ss;
+                for ( ; i > 0; i--) {
+                        int j;
+                        unsigned char* t = to;
+                        unsigned char* sL = fromL;
+                        unsigned char* sR = fromR;
+
+                        if (p->scalew == 1) {
+                                for (j = dd; j > 0; j--) {
+                                        *t++ = (sL[0] + sL[1]) / 2;
+                                        sL+=2;
+                                }
+                                for (j = dd ; j > 0; j--) {
+                                        *t++ = (sR[0] + sR[1]) / 2;
+                                        sR+=2;
+                                }
+                        } else {
+                                for (j = dd * 2 ; j > 0; j--)
+                                        *t++ = *sL++;
+                                for (j = dd * 2 ; j > 0; j--)
+                                        *t++ = *sR++;
+                        }
+                        if (p->scaleh == 1) {
+                                fast_memcpy(to + dst, to, dst);
+                                to += dst;
+                        }
+                        to += dst;
+                        fromL += src;
+                        fromR += src;
+                }
+                //printf("K %d  %d   %d   %d  %d \n", k, w, h,  src, dst);
+        }
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+        mp_image_t *dmpi;
+
+        // hope we'll get DR buffer:
+        dmpi=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,
+                          mpi->h / vf->priv->scaleh - vf->priv->skipline);
+
+        toright(dmpi->planes, mpi->planes, dmpi->stride,
+                mpi->stride, mpi->w, mpi->h, vf->priv);
+
+        return vf_next_put_image(vf,dmpi, pts);
+}
+
+static int config(struct vf_instance *vf,
+                  int width, int height, int d_width, int d_height,
+                  unsigned int flags, unsigned int outfmt)
+{
+        /* FIXME - also support UYVY output? */
+        return vf_next_config(vf, width * vf->priv->scalew,
+                              height / vf->priv->scaleh - vf->priv->skipline, d_width, d_height, flags, IMGFMT_YV12);
+}
+
+
+static int query_format(struct vf_instance *vf, unsigned int fmt)
+{
+        /* FIXME - really any YUV 4:2:0 input format should work */
+        switch (fmt) {
+        case IMGFMT_YV12:
+        case IMGFMT_IYUV:
+        case IMGFMT_I420:
+                return vf_next_query_format(vf, IMGFMT_YV12);
+        }
+        return 0;
+}
+
+static void uninit(struct vf_instance *vf)
+{
+        free(vf->priv);
+}
+
+static int vf_open(vf_instance_t *vf, char *args)
+{
+        vf->config=config;
+        vf->query_format=query_format;
+        vf->put_image=put_image;
+        vf->uninit=uninit;
+
+        vf->priv = calloc(1, sizeof (struct vf_priv_s));
+        vf->priv->skipline = 0;
+        vf->priv->scalew = 1;
+        vf->priv->scaleh = 2;
+        if (args) sscanf(args, "%d:%d:%d", &vf->priv->skipline, &vf->priv->scalew, &vf->priv->scaleh);
+
+        return 1;
+}
+
+const vf_info_t vf_info_down3dright = {
+        "convert stereo movie from top-bottom to left-right field",
+        "down3dright",
+        "Zdenek Kabelac",
+        "",
+        vf_open,
+        NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_dsize.c b/libavfilter/libmpcodecs/vf_dsize.c
new file mode 100644
index 0000000..7772b37
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_dsize.c
@@ -0,0 +1,123 @@
+/*
+ * 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
new file mode 100644
index 0000000..df4e851
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_eq.c
@@ -0,0 +1,240 @@
+/*
+ * 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 "cpudetect.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "libvo/video_out.h"
+
+static struct vf_priv_s {
+        unsigned char *buf;
+        int brightness;
+        int contrast;
+};
+
+#if HAVE_MMX
+static void process_MMX(unsigned char *dest, int dstride, unsigned char *src, int sstride,
+                    int w, int h, int brightness, int contrast)
+{
+        int i;
+        int pel;
+        int dstep = dstride-w;
+        int sstep = sstride-w;
+        short brvec[4];
+        short contvec[4];
+
+        contrast = ((contrast+100)*256*16)/100;
+        brightness = ((brightness+100)*511)/200-128 - contrast/32;
+
+        brvec[0] = brvec[1] = brvec[2] = brvec[3] = brightness;
+        contvec[0] = contvec[1] = contvec[2] = contvec[3] = contrast;
+
+        while (h--) {
+                __asm__ volatile (
+                        "movq (%5), %%mm3 \n\t"
+                        "movq (%6), %%mm4 \n\t"
+                        "pxor %%mm0, %%mm0 \n\t"
+                        "movl %4, %%eax\n\t"
+                        ASMALIGN(4)
+                        "1: \n\t"
+                        "movq (%0), %%mm1 \n\t"
+                        "movq (%0), %%mm2 \n\t"
+                        "punpcklbw %%mm0, %%mm1 \n\t"
+                        "punpckhbw %%mm0, %%mm2 \n\t"
+                        "psllw $4, %%mm1 \n\t"
+                        "psllw $4, %%mm2 \n\t"
+                        "pmulhw %%mm4, %%mm1 \n\t"
+                        "pmulhw %%mm4, %%mm2 \n\t"
+                        "paddw %%mm3, %%mm1 \n\t"
+                        "paddw %%mm3, %%mm2 \n\t"
+                        "packuswb %%mm2, %%mm1 \n\t"
+                        "add $8, %0 \n\t"
+                        "movq %%mm1, (%1) \n\t"
+                        "add $8, %1 \n\t"
+                        "decl %%eax \n\t"
+                        "jnz 1b \n\t"
+                        : "=r" (src), "=r" (dest)
+                        : "0" (src), "1" (dest), "r" (w>>3), "r" (brvec), "r" (contvec)
+                        : "%eax"
+                );
+
+                for (i = w&7; i; i--)
+                {
+                        pel = ((*src++* contrast)>>12) + brightness;
+                        if(pel&768) pel = (-pel)>>31;
+                        *dest++ = pel;
+                }
+
+                src += sstep;
+                dest += dstep;
+        }
+        __asm__ volatile ( "emms \n\t" ::: "memory" );
+}
+#endif
+
+static void process_C(unsigned char *dest, int dstride, unsigned char *src, int sstride,
+                    int w, int h, int brightness, int contrast)
+{
+        int i;
+        int pel;
+        int dstep = dstride-w;
+        int sstep = sstride-w;
+
+        contrast = ((contrast+100)*256*256)/100;
+        brightness = ((brightness+100)*511)/200-128 - contrast/512;
+
+        while (h--) {
+                for (i = w; i; i--)
+                {
+                        pel = ((*src++* contrast)>>16) + brightness;
+                        if(pel&768) pel = (-pel)>>31;
+                        *dest++ = pel;
+                }
+                src += sstep;
+                dest += dstep;
+        }
+}
+
+static void (*process)(unsigned char *dest, int dstride, unsigned char *src, int sstride,
+                       int w, int h, int brightness, int contrast);
+
+/* FIXME: add packed yuv version of process */
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+        mp_image_t *dmpi;
+
+        dmpi=vf_get_image(vf->next, mpi->imgfmt,
+                          MP_IMGTYPE_EXPORT, 0,
+                          mpi->w, mpi->h);
+
+        dmpi->stride[0] = mpi->stride[0];
+        dmpi->planes[1] = mpi->planes[1];
+        dmpi->planes[2] = mpi->planes[2];
+        dmpi->stride[1] = mpi->stride[1];
+        dmpi->stride[2] = mpi->stride[2];
+
+        if (!vf->priv->buf) vf->priv->buf = malloc(mpi->stride[0]*mpi->h);
+
+        if ((vf->priv->brightness == 0) && (vf->priv->contrast == 0))
+                dmpi->planes[0] = mpi->planes[0];
+        else {
+                dmpi->planes[0] = vf->priv->buf;
+                process(dmpi->planes[0], dmpi->stride[0],
+                        mpi->planes[0], mpi->stride[0],
+                        mpi->w, mpi->h, vf->priv->brightness,
+                        vf->priv->contrast);
+        }
+
+        return vf_next_put_image(vf,dmpi, pts);
+}
+
+static int control(struct vf_instance *vf, int request, void* data)
+{
+        vf_equalizer_t *eq;
+
+        switch (request) {
+        case VFCTRL_SET_EQUALIZER:
+                eq = data;
+                if (!strcmp(eq->item,"brightness")) {
+                        vf->priv->brightness = eq->value;
+                        return CONTROL_TRUE;
+                }
+                else if (!strcmp(eq->item,"contrast")) {
+                        vf->priv->contrast = eq->value;
+                        return CONTROL_TRUE;
+                }
+                break;
+        case VFCTRL_GET_EQUALIZER:
+                eq = data;
+                if (!strcmp(eq->item,"brightness")) {
+                        eq->value = vf->priv->brightness;
+                        return CONTROL_TRUE;
+                }
+                else if (!strcmp(eq->item,"contrast")) {
+                        eq->value = vf->priv->contrast;
+                        return CONTROL_TRUE;
+                }
+                break;
+        }
+        return vf_next_control(vf, request, data);
+}
+
+static int query_format(struct vf_instance *vf, unsigned int fmt)
+{
+        switch (fmt) {
+        case IMGFMT_YVU9:
+        case IMGFMT_IF09:
+        case IMGFMT_YV12:
+        case IMGFMT_I420:
+        case IMGFMT_IYUV:
+        case IMGFMT_CLPL:
+        case IMGFMT_Y800:
+        case IMGFMT_Y8:
+        case IMGFMT_NV12:
+        case IMGFMT_NV21:
+        case IMGFMT_444P:
+        case IMGFMT_422P:
+        case IMGFMT_411P:
+                return vf_next_query_format(vf, fmt);
+        }
+        return 0;
+}
+
+static void uninit(struct vf_instance *vf)
+{
+        free(vf->priv->buf);
+        free(vf->priv);
+}
+
+static int vf_open(vf_instance_t *vf, char *args)
+{
+        vf->control=control;
+        vf->query_format=query_format;
+        vf->put_image=put_image;
+        vf->uninit=uninit;
+
+    vf->priv = malloc(sizeof(struct vf_priv_s));
+    memset(vf->priv, 0, sizeof(struct vf_priv_s));
+    if (args) sscanf(args, "%d:%d", &vf->priv->brightness, &vf->priv->contrast);
+
+        process = process_C;
+#if HAVE_MMX
+        if(gCpuCaps.hasMMX) process = process_MMX;
+#endif
+
+        return 1;
+}
+
+const vf_info_t vf_info_eq = {
+        "soft video equalizer",
+        "eq",
+        "Richard Felker",
+        "",
+        vf_open,
+};
diff --git a/libavfilter/libmpcodecs/vf_eq2.c b/libavfilter/libmpcodecs/vf_eq2.c
new file mode 100644
index 0000000..fe4a89f
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_eq2.c
@@ -0,0 +1,519 @@
+/*
+ * Software equalizer (brightness, contrast, gamma, saturation)
+ *
+ * Hampa Hug <hampa@hampa.ch> (original LUT gamma/contrast/brightness filter)
+ * Daniel Moreno <comac@comac.darktech.org> (saturation, R/G/B gamma support)
+ * Richard Felker (original MMX contrast/brightness code (vf_eq.c))
+ * Michael Niedermayer <michalni@gmx.at> (LUT16)
+ *
+ * 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 <math.h>
+#include <inttypes.h>
+
+#include "config.h"
+#include "mp_msg.h"
+#include "cpudetect.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#define LUT16
+
+/* Per channel parameters */
+typedef struct eq2_param_t {
+  unsigned char lut[256];
+#ifdef LUT16
+  uint16_t lut16[256*256];
+#endif
+  int           lut_clean;
+
+  void (*adjust) (struct eq2_param_t *par, unsigned char *dst, unsigned char *src,
+    unsigned w, unsigned h, unsigned dstride, unsigned sstride);
+
+  double        c;
+  double        b;
+  double        g;
+  double        w;
+} eq2_param_t;
+
+typedef struct vf_priv_s {
+  eq2_param_t param[3];
+
+  double        contrast;
+  double        brightness;
+  double        saturation;
+
+  double        gamma;
+  double        gamma_weight;
+  double        rgamma;
+  double        ggamma;
+  double        bgamma;
+
+  unsigned      buf_w[3];
+  unsigned      buf_h[3];
+  unsigned char *buf[3];
+} vf_eq2_t;
+
+
+static
+void create_lut (eq2_param_t *par)
+{
+  unsigned i;
+  double   g, v;
+  double   lw, gw;
+
+  g = par->g;
+  gw = par->w;
+  lw = 1.0 - gw;
+
+  if ((g < 0.001) || (g > 1000.0)) {
+    g = 1.0;
+  }
+
+  g = 1.0 / g;
+
+  for (i = 0; i < 256; i++) {
+    v = (double) i / 255.0;
+    v = par->c * (v - 0.5) + 0.5 + par->b;
+
+    if (v <= 0.0) {
+      par->lut[i] = 0;
+    }
+    else {
+      v = v*lw + pow(v, g)*gw;
+
+      if (v >= 1.0) {
+        par->lut[i] = 255;
+      }
+      else {
+        par->lut[i] = (unsigned char) (256.0 * v);
+      }
+    }
+  }
+
+#ifdef LUT16
+  for(i=0; i<256*256; i++){
+    par->lut16[i]= par->lut[i&0xFF] + (par->lut[i>>8]<<8);
+  }
+#endif
+
+  par->lut_clean = 1;
+}
+
+#if HAVE_MMX
+static
+void affine_1d_MMX (eq2_param_t *par, unsigned char *dst, unsigned char *src,
+  unsigned w, unsigned h, unsigned dstride, unsigned sstride)
+{
+  unsigned i;
+  int      contrast, brightness;
+  unsigned dstep, sstep;
+  int      pel;
+  short    brvec[4];
+  short    contvec[4];
+
+//  printf("\nmmx: src=%p dst=%p w=%d h=%d ds=%d ss=%d\n",src,dst,w,h,dstride,sstride);
+
+  contrast = (int) (par->c * 256 * 16);
+  brightness = ((int) (100.0 * par->b + 100.0) * 511) / 200 - 128 - contrast / 32;
+
+  brvec[0] = brvec[1] = brvec[2] = brvec[3] = brightness;
+  contvec[0] = contvec[1] = contvec[2] = contvec[3] = contrast;
+
+  sstep = sstride - w;
+  dstep = dstride - w;
+
+  while (h-- > 0) {
+    __asm__ volatile (
+      "movq (%5), %%mm3 \n\t"
+      "movq (%6), %%mm4 \n\t"
+      "pxor %%mm0, %%mm0 \n\t"
+      "movl %4, %%eax\n\t"
+      ASMALIGN(4)
+      "1: \n\t"
+      "movq (%0), %%mm1 \n\t"
+      "movq (%0), %%mm2 \n\t"
+      "punpcklbw %%mm0, %%mm1 \n\t"
+      "punpckhbw %%mm0, %%mm2 \n\t"
+      "psllw $4, %%mm1 \n\t"
+      "psllw $4, %%mm2 \n\t"
+      "pmulhw %%mm4, %%mm1 \n\t"
+      "pmulhw %%mm4, %%mm2 \n\t"
+      "paddw %%mm3, %%mm1 \n\t"
+      "paddw %%mm3, %%mm2 \n\t"
+      "packuswb %%mm2, %%mm1 \n\t"
+      "add $8, %0 \n\t"
+      "movq %%mm1, (%1) \n\t"
+      "add $8, %1 \n\t"
+      "decl %%eax \n\t"
+      "jnz 1b \n\t"
+      : "=r" (src), "=r" (dst)
+      : "0" (src), "1" (dst), "r" (w >> 3), "r" (brvec), "r" (contvec)
+      : "%eax"
+    );
+
+    for (i = w & 7; i > 0; i--) {
+      pel = ((*src++ * contrast) >> 12) + brightness;
+      if (pel & 768) {
+        pel = (-pel) >> 31;
+      }
+      *dst++ = pel;
+    }
+
+    src += sstep;
+    dst += dstep;
+  }
+
+  __asm__ volatile ( "emms \n\t" ::: "memory" );
+}
+#endif
+
+static
+void apply_lut (eq2_param_t *par, unsigned char *dst, unsigned char *src,
+  unsigned w, unsigned h, unsigned dstride, unsigned sstride)
+{
+  unsigned      i, j, w2;
+  unsigned char *lut;
+  uint16_t *lut16;
+
+  if (!par->lut_clean) {
+    create_lut (par);
+  }
+
+  lut = par->lut;
+#ifdef LUT16
+  lut16 = par->lut16;
+  w2= (w>>3)<<2;
+  for (j = 0; j < h; j++) {
+    uint16_t *src16= (uint16_t*)src;
+    uint16_t *dst16= (uint16_t*)dst;
+    for (i = 0; i < w2; i+=4) {
+      dst16[i+0] = lut16[src16[i+0]];
+      dst16[i+1] = lut16[src16[i+1]];
+      dst16[i+2] = lut16[src16[i+2]];
+      dst16[i+3] = lut16[src16[i+3]];
+    }
+    i <<= 1;
+#else
+  w2= (w>>3)<<3;
+  for (j = 0; j < h; j++) {
+    for (i = 0; i < w2; i+=8) {
+      dst[i+0] = lut[src[i+0]];
+      dst[i+1] = lut[src[i+1]];
+      dst[i+2] = lut[src[i+2]];
+      dst[i+3] = lut[src[i+3]];
+      dst[i+4] = lut[src[i+4]];
+      dst[i+5] = lut[src[i+5]];
+      dst[i+6] = lut[src[i+6]];
+      dst[i+7] = lut[src[i+7]];
+    }
+#endif
+    for (; i < w; i++) {
+      dst[i] = lut[src[i]];
+    }
+
+    src += sstride;
+    dst += dstride;
+  }
+}
+
+static
+int put_image (vf_instance_t *vf, mp_image_t *src, double pts)
+{
+  unsigned      i;
+  vf_eq2_t      *eq2;
+  mp_image_t    *dst;
+  unsigned long img_n,img_c;
+
+  eq2 = vf->priv;
+
+  if ((eq2->buf_w[0] != src->w) || (eq2->buf_h[0] != src->h)) {
+    eq2->buf_w[0] = src->w;
+    eq2->buf_h[0] = src->h;
+      eq2->buf_w[1] = eq2->buf_w[2] = src->w >> src->chroma_x_shift;
+      eq2->buf_h[1] = eq2->buf_h[2] = src->h >> src->chroma_y_shift;
+    img_n = eq2->buf_w[0]*eq2->buf_h[0];
+    if(src->num_planes>1){
+      img_c = eq2->buf_w[1]*eq2->buf_h[1];
+      eq2->buf[0] = realloc (eq2->buf[0], img_n + 2*img_c);
+      eq2->buf[1] = eq2->buf[0] + img_n;
+      eq2->buf[2] = eq2->buf[1] + img_c;
+    } else
+      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);
+
+  for (i = 0; i < ((src->num_planes>1)?3:1); i++) {
+    if (eq2->param[i].adjust != NULL) {
+      dst->planes[i] = eq2->buf[i];
+      dst->stride[i] = eq2->buf_w[i];
+
+      eq2->param[i].adjust (&eq2->param[i], dst->planes[i], src->planes[i],
+        eq2->buf_w[i], eq2->buf_h[i], dst->stride[i], src->stride[i]);
+    }
+    else {
+      dst->planes[i] = src->planes[i];
+      dst->stride[i] = src->stride[i];
+    }
+  }
+
+  return vf_next_put_image (vf, dst, pts);
+}
+
+static
+void check_values (eq2_param_t *par)
+{
+  /* yuck! floating point comparisons... */
+
+  if ((par->c == 1.0) && (par->b == 0.0) && (par->g == 1.0)) {
+    par->adjust = NULL;
+  }
+#if HAVE_MMX
+  else if (par->g == 1.0 && gCpuCaps.hasMMX) {
+    par->adjust = &affine_1d_MMX;
+  }
+#endif
+  else {
+    par->adjust = &apply_lut;
+  }
+}
+
+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",
+    eq2->contrast, eq2->brightness, eq2->gamma, eq2->saturation
+  );
+}
+
+static
+void set_contrast (vf_eq2_t *eq2, double c)
+{
+  eq2->contrast = c;
+  eq2->param[0].c = c;
+  eq2->param[0].lut_clean = 0;
+  check_values (&eq2->param[0]);
+  print_values (eq2);
+}
+
+static
+void set_brightness (vf_eq2_t *eq2, double b)
+{
+  eq2->brightness = b;
+  eq2->param[0].b = b;
+  eq2->param[0].lut_clean = 0;
+  check_values (&eq2->param[0]);
+  print_values (eq2);
+}
+
+static
+void set_gamma (vf_eq2_t *eq2, double g)
+{
+  eq2->gamma = g;
+
+  eq2->param[0].g = eq2->gamma * eq2->ggamma;
+  eq2->param[1].g = sqrt (eq2->bgamma / eq2->ggamma);
+  eq2->param[2].g = sqrt (eq2->rgamma / eq2->ggamma);
+  eq2->param[0].w = eq2->param[1].w = eq2->param[2].w = eq2->gamma_weight;
+
+  eq2->param[0].lut_clean = 0;
+  eq2->param[1].lut_clean = 0;
+  eq2->param[2].lut_clean = 0;
+
+  check_values (&eq2->param[0]);
+  check_values (&eq2->param[1]);
+  check_values (&eq2->param[2]);
+
+  print_values (eq2);
+}
+
+static
+void set_saturation (vf_eq2_t *eq2, double s)
+{
+  eq2->saturation = s;
+
+  eq2->param[1].c = s;
+  eq2->param[2].c = s;
+
+  eq2->param[1].lut_clean = 0;
+  eq2->param[2].lut_clean = 0;
+
+  check_values (&eq2->param[1]);
+  check_values (&eq2->param[2]);
+
+  print_values (eq2);
+}
+
+static
+int control (vf_instance_t *vf, int request, void *data)
+{
+  vf_equalizer_t *eq;
+
+  switch (request) {
+    case VFCTRL_SET_EQUALIZER:
+      eq = (vf_equalizer_t *) data;
+
+      if (strcmp (eq->item, "gamma") == 0) {
+        set_gamma (vf->priv, exp (log (8.0) * eq->value / 100.0));
+        return CONTROL_TRUE;
+      }
+      else if (strcmp (eq->item, "contrast") == 0) {
+        set_contrast (vf->priv, (1.0 / 100.0) * (eq->value + 100));
+        return CONTROL_TRUE;
+      }
+      else if (strcmp (eq->item, "brightness") == 0) {
+        set_brightness (vf->priv, (1.0 / 100.0) * eq->value);
+        return CONTROL_TRUE;
+      }
+      else if (strcmp (eq->item, "saturation") == 0) {
+        set_saturation (vf->priv, (double) (eq->value + 100) / 100.0);
+        return CONTROL_TRUE;
+      }
+      break;
+
+    case VFCTRL_GET_EQUALIZER:
+      eq = (vf_equalizer_t *) data;
+      if (strcmp (eq->item, "gamma") == 0) {
+        eq->value = (int) (100.0 * log (vf->priv->gamma) / log (8.0));
+        return CONTROL_TRUE;
+      }
+      else if (strcmp (eq->item, "contrast") == 0) {
+        eq->value = (int) (100.0 * vf->priv->contrast) - 100;
+        return CONTROL_TRUE;
+      }
+      else if (strcmp (eq->item, "brightness") == 0) {
+        eq->value = (int) (100.0 * vf->priv->brightness);
+        return CONTROL_TRUE;
+      }
+      else if (strcmp (eq->item, "saturation") == 0) {
+        eq->value = (int) (100.0 * vf->priv->saturation) - 100;
+        return CONTROL_TRUE;
+      }
+      break;
+  }
+
+  return vf_next_control (vf, request, data);
+}
+
+static
+int query_format (vf_instance_t *vf, unsigned fmt)
+{
+  switch (fmt) {
+    case IMGFMT_YVU9:
+    case IMGFMT_IF09:
+    case IMGFMT_YV12:
+    case IMGFMT_I420:
+    case IMGFMT_IYUV:
+    case IMGFMT_Y800:
+    case IMGFMT_Y8:
+    case IMGFMT_444P:
+    case IMGFMT_422P:
+    case IMGFMT_411P:
+      return vf_next_query_format (vf, fmt);
+  }
+
+  return 0;
+}
+
+static
+void uninit (vf_instance_t *vf)
+{
+  if (vf->priv != NULL) {
+    free (vf->priv->buf[0]);
+    free (vf->priv);
+  }
+}
+
+static
+int vf_open(vf_instance_t *vf, char *args)
+{
+  unsigned i;
+  vf_eq2_t *eq2;
+  double   par[8];
+
+  vf->control = control;
+  vf->query_format = query_format;
+  vf->put_image = put_image;
+  vf->uninit = uninit;
+
+  vf->priv = malloc (sizeof (vf_eq2_t));
+  eq2 = vf->priv;
+
+  for (i = 0; i < 3; i++) {
+    eq2->buf[i] = NULL;
+    eq2->buf_w[i] = 0;
+    eq2->buf_h[i] = 0;
+
+    eq2->param[i].adjust = NULL;
+    eq2->param[i].c = 1.0;
+    eq2->param[i].b = 0.0;
+    eq2->param[i].g = 1.0;
+    eq2->param[i].lut_clean = 0;
+  }
+
+  eq2->contrast = 1.0;
+  eq2->brightness = 0.0;
+  eq2->saturation = 1.0;
+
+  eq2->gamma = 1.0;
+  eq2->gamma_weight = 1.0;
+  eq2->rgamma = 1.0;
+  eq2->ggamma = 1.0;
+  eq2->bgamma = 1.0;
+
+  if (args != NULL) {
+    par[0] = 1.0;
+    par[1] = 1.0;
+    par[2] = 0.0;
+    par[3] = 1.0;
+    par[4] = 1.0;
+    par[5] = 1.0;
+    par[6] = 1.0;
+    par[7] = 1.0;
+    sscanf (args, "%lf:%lf:%lf:%lf:%lf:%lf:%lf:%lf",
+      par, par + 1, par + 2, par + 3, par + 4, par + 5, par + 6, par + 7
+    );
+
+    eq2->rgamma = par[4];
+    eq2->ggamma = par[5];
+    eq2->bgamma = par[6];
+    eq2->gamma_weight = par[7];
+
+    set_gamma (eq2, par[0]);
+    set_contrast (eq2, par[1]);
+    set_brightness (eq2, par[2]);
+    set_saturation (eq2, par[3]);
+  }
+
+  return 1;
+}
+
+const vf_info_t vf_info_eq2 = {
+  "Software equalizer",
+  "eq2",
+  "Hampa Hug, Daniel Moreno, Richard Felker",
+  "",
+  &vf_open,
+  NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_field.c b/libavfilter/libmpcodecs/vf_field.c
new file mode 100644
index 0000000..fcf24be
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_field.c
@@ -0,0 +1,89 @@
+/*
+ * 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 "mp_image.h"
+#include "vf.h"
+
+struct vf_priv_s {
+    int field;
+};
+
+//===========================================================================//
+
+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/2,d_width,d_height,flags,outfmt);
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+    vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
+        MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE,
+        mpi->width, mpi->height/2);
+
+    // set up mpi as a double-stride image of dmpi:
+    vf->dmpi->planes[0]=mpi->planes[0]+mpi->stride[0]*vf->priv->field;
+    vf->dmpi->stride[0]=2*mpi->stride[0];
+    if(vf->dmpi->flags&MP_IMGFLAG_PLANAR){
+        vf->dmpi->planes[1]=mpi->planes[1]+
+            mpi->stride[1]*vf->priv->field;
+        vf->dmpi->stride[1]=2*mpi->stride[1];
+        vf->dmpi->planes[2]=mpi->planes[2]+
+            mpi->stride[2]*vf->priv->field;
+        vf->dmpi->stride[2]=2*mpi->stride[2];
+    } else
+        vf->dmpi->planes[1]=mpi->planes[1]; // passthru bgr8 palette!!!
+
+    return vf_next_put_image(vf,vf->dmpi, pts);
+}
+
+//===========================================================================//
+
+static void uninit(struct vf_instance *vf)
+{
+        free(vf->priv);
+}
+
+static int vf_open(vf_instance_t *vf, char *args){
+    vf->config=config;
+    vf->put_image=put_image;
+    vf->uninit=uninit;
+    vf->default_reqs=VFCAP_ACCEPT_STRIDE;
+    vf->priv=calloc(1, sizeof(struct vf_priv_s));
+    if (args) sscanf(args, "%d", &vf->priv->field);
+    vf->priv->field &= 1;
+    return 1;
+}
+
+const vf_info_t vf_info_field = {
+    "extract single field",
+    "field",
+    "Rich Felker",
+    "",
+    vf_open,
+    NULL
+};
+
+//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vf_fil.c b/libavfilter/libmpcodecs/vf_fil.c
new file mode 100644
index 0000000..7df7eb0
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_fil.c
@@ -0,0 +1,116 @@
+/*
+ * 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 "mp_image.h"
+#include "vf.h"
+
+struct vf_priv_s {
+    int interleave;
+    int height;
+    int width;
+    int stridefactor;
+};
+
+//===========================================================================//
+
+static int config(struct vf_instance *vf,
+        int width, int height, int d_width, int d_height,
+        unsigned int flags, unsigned int outfmt){
+        int pixel_stride= (width+15)&~15; //FIXME this is ust a guess ... especially for non planar its somewhat bad one
+
+#if 0
+    if(mpi->flags&MP_IMGFLAG_PLANAR)
+        pixel_stride= mpi->stride[0];
+    else
+        pixel_stride= 8*mpi->stride[0] / mpi->bpp;
+
+#endif
+
+    if(vf->priv->interleave){
+        vf->priv->height= 2*height;
+        vf->priv->width= width - (pixel_stride/2);
+        vf->priv->stridefactor=1;
+    }else{
+        vf->priv->height= height/2;
+        vf->priv->width= width + pixel_stride;
+        vf->priv->stridefactor=4;
+    }
+//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,
+        (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);
+    }
+
+    vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
+        MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE,
+        vf->priv->width, vf->priv->height);
+
+    // set up mpi as a double-stride image of dmpi:
+    vf->dmpi->planes[0]=mpi->planes[0];
+    vf->dmpi->stride[0]=(mpi->stride[0]*vf->priv->stridefactor)>>1;
+    if(vf->dmpi->flags&MP_IMGFLAG_PLANAR){
+        vf->dmpi->planes[1]=mpi->planes[1];
+        vf->dmpi->stride[1]=(mpi->stride[1]*vf->priv->stridefactor)>>1;
+        vf->dmpi->planes[2]=mpi->planes[2];
+        vf->dmpi->stride[2]=(mpi->stride[2]*vf->priv->stridefactor)>>1;
+    } else
+        vf->dmpi->planes[1]=mpi->planes[1]; // passthru bgr8 palette!!!
+
+    return vf_next_put_image(vf,vf->dmpi, pts);
+}
+
+//===========================================================================//
+
+static void uninit(struct vf_instance *vf)
+{
+        free(vf->priv);
+}
+
+static int vf_open(vf_instance_t *vf, char *args){
+    vf->config=config;
+    vf->put_image=put_image;
+    vf->uninit=uninit;
+    vf->default_reqs=VFCAP_ACCEPT_STRIDE;
+    vf->priv=calloc(1, sizeof(struct vf_priv_s));
+    vf->priv->interleave= args && (*args == 'i');
+    return 1;
+}
+
+const vf_info_t vf_info_fil = {
+    "fast (de)interleaver",
+    "fil",
+    "Michael Niedermayer",
+    "",
+    vf_open,
+    NULL
+};
+
+//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vf_filmdint.c b/libavfilter/libmpcodecs/vf_filmdint.c
new file mode 100644
index 0000000..70db246
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_filmdint.c
@@ -0,0 +1,1461 @@
+/*
+ * 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 <sys/time.h>
+
+#include "config.h"
+#include "mp_msg.h"
+#include "cpudetect.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vd.h"
+#include "vf.h"
+#include "cmmx.h"
+
+#include "libvo/fastmemcpy.h"
+
+#define NUM_STORED 4
+
+enum pu_field_type_t {
+    PU_1ST_OF_3,
+    PU_2ND_OF_3,
+    PU_3RD_OF_3,
+    PU_1ST_OF_2,
+    PU_2ND_OF_2,
+    PU_INTERLACED
+};
+
+struct metrics {
+    /* This struct maps to a packed word 64-bit MMX register */
+    unsigned short int even;
+    unsigned short int odd;
+    unsigned short int noise;
+    unsigned short int temp;
+} __attribute__ ((aligned (8)));
+
+struct frame_stats {
+    struct metrics tiny, low, high, bigger, twox, max;
+    struct { unsigned int even, odd, noise, temp; } sad;
+    unsigned short interlaced_high;
+    unsigned short interlaced_low;
+    unsigned short num_blocks;
+};
+
+struct vf_priv_s {
+    unsigned long inframes;
+    unsigned long outframes;
+    enum pu_field_type_t prev_type;
+    unsigned swapped, chroma_swapped;
+    unsigned luma_only;
+    unsigned verbose;
+    unsigned fast;
+    unsigned long w, h, cw, ch, stride, chroma_stride, nplanes;
+    unsigned long sad_thres;
+    unsigned long dint_thres;
+    unsigned char *memory_allocated;
+    unsigned char *planes[2*NUM_STORED][4];
+    unsigned char **old_planes;
+    unsigned long static_idx;
+    unsigned long temp_idx;
+    unsigned long crop_x, crop_y, crop_cx, crop_cy;
+    unsigned long export_count, merge_count;
+    unsigned long num_breaks;
+    unsigned long num_copies;
+    long in_inc, out_dec, iosync;
+    long num_fields;
+    long prev_fields;
+    long notout;
+    long mmx2;
+    unsigned small_bytes[2];
+    unsigned mmx_temp[2];
+    struct frame_stats stats[2];
+    struct metrics thres;
+    char chflag;
+    double diff_time, merge_time, decode_time, vo_time, filter_time;
+};
+
+#define PPZ { 2000, 2000, 0, 2000 }
+#define PPR { 2000, 2000, 0, 2000 }
+static const struct frame_stats ppzs = {PPZ,PPZ,PPZ,PPZ,PPZ,PPZ,PPZ,0,0,9999};
+static const struct frame_stats pprs = {PPR,PPR,PPR,PPR,PPR,PPR,PPR,0,0,9999};
+
+#ifndef MIN
+#define        MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+#ifndef MAX
+#define        MAX(a,b) (((a)>(b))?(a):(b))
+#endif
+
+#define PDIFFUB(X,Y,T) "movq "    #X "," #T "\n\t" \
+                       "psubusb " #Y "," #T "\n\t" \
+                       "psubusb " #X "," #Y "\n\t" \
+                       "paddusb " #Y "," #T "\n\t"
+
+#define PDIFFUBT(X,Y,T) "movq "    #X "," #T "\n\t" \
+                        "psubusb " #Y "," #T "\n\t" \
+                        "psubusb " #X "," #Y "\n\t" \
+                        "paddusb " #T "," #Y "\n\t"
+
+#define PSUMBW(X,T,Z)        "movq " #X "," #T "\n\t" \
+                        "punpcklbw " #Z "," #X "\n\t" \
+                        "punpckhbw " #Z "," #T "\n\t" \
+                        "paddw " #T "," #X "\n\t" \
+                        "movq " #X "," #T "\n\t" \
+                        "psllq $32, " #T "\n\t" \
+                        "paddw " #T "," #X "\n\t" \
+                        "movq " #X "," #T "\n\t" \
+                        "psllq $16, " #T "\n\t" \
+                        "paddw " #T "," #X "\n\t" \
+                        "psrlq $48, " #X "\n\t"
+
+#define PSADBW(X,Y,T,Z)        PDIFFUBT(X,Y,T) PSUMBW(Y,T,Z)
+
+#define PMAXUB(X,Y) "psubusb " #X "," #Y "\n\tpaddusb " #X "," #Y "\n\t"
+#define PMAXUW(X,Y) "psubusw " #X "," #Y "\n\tpaddusw " #X "," #Y "\n\t"
+#define PMINUBT(X,Y,T)        "movq " #Y "," #T "\n\t" \
+                        "psubusb " #X "," #T "\n\t" \
+                        "psubusb " #T "," #Y "\n\t"
+#define PAVGB(X,Y)        "pavgusb " #X "," #Y "\n\t"
+
+static inline void
+get_metrics_c(unsigned char *a, unsigned char *b, int as, int bs, int lines,
+              struct metrics *m)
+{
+    a -= as;
+    b -= bs;
+    do {
+        cmmx_t old_po = *(cmmx_t*)(a      );
+        cmmx_t     po = *(cmmx_t*)(b      );
+        cmmx_t      e = *(cmmx_t*)(b +   bs);
+        cmmx_t  old_o = *(cmmx_t*)(a + 2*as);
+        cmmx_t      o = *(cmmx_t*)(b + 2*bs);
+        cmmx_t     ne = *(cmmx_t*)(b + 3*bs);
+        cmmx_t old_no = *(cmmx_t*)(a + 4*as);
+        cmmx_t     no = *(cmmx_t*)(b + 4*bs);
+
+        cmmx_t   qup_old_odd = p31avgb(old_o, old_po);
+        cmmx_t       qup_odd = p31avgb(    o,     po);
+        cmmx_t qdown_old_odd = p31avgb(old_o, old_no);
+        cmmx_t     qdown_odd = p31avgb(    o,     no);
+
+        cmmx_t   qup_even = p31avgb(ne, e);
+        cmmx_t qdown_even = p31avgb(e, ne);
+
+        cmmx_t    temp_up_diff = pdiffub(qdown_even, qup_old_odd);
+        cmmx_t   noise_up_diff = pdiffub(qdown_even, qup_odd);
+        cmmx_t  temp_down_diff = pdiffub(qup_even, qdown_old_odd);
+        cmmx_t noise_down_diff = pdiffub(qup_even, qdown_odd);
+
+        cmmx_t odd_diff = pdiffub(o, old_o);
+        m->odd  += psumbw(odd_diff);
+        m->even += psadbw(e, *(cmmx_t*)(a+as));
+
+        temp_up_diff  = pminub(temp_up_diff, temp_down_diff);
+        temp_up_diff  = pminub(temp_up_diff, odd_diff);
+        m->temp  += psumbw(temp_up_diff);
+        noise_up_diff = pminub(noise_up_diff, odd_diff);
+        noise_up_diff = pminub(noise_up_diff, noise_down_diff);
+
+        m->noise += psumbw(noise_up_diff);
+        a += 2*as;
+        b += 2*bs;
+    } while (--lines);
+}
+
+static inline void
+get_metrics_fast_c(unsigned char *a, unsigned char *b, int as, int bs,
+                   int lines, struct metrics *m)
+{
+    a -= as;
+    b -= bs;
+    do {
+        cmmx_t old_po = (*(cmmx_t*)(a       ) >> 1) & ~SIGN_BITS;
+        cmmx_t     po = (*(cmmx_t*)(b       ) >> 1) & ~SIGN_BITS;
+        cmmx_t  old_e = (*(cmmx_t*)(a +   as) >> 1) & ~SIGN_BITS;
+        cmmx_t      e = (*(cmmx_t*)(b +   bs) >> 1) & ~SIGN_BITS;
+        cmmx_t  old_o = (*(cmmx_t*)(a + 2*as) >> 1) & ~SIGN_BITS;
+        cmmx_t      o = (*(cmmx_t*)(b + 2*bs) >> 1) & ~SIGN_BITS;
+        cmmx_t     ne = (*(cmmx_t*)(b + 3*bs) >> 1) & ~SIGN_BITS;
+        cmmx_t old_no = (*(cmmx_t*)(a + 4*as) >> 1) & ~SIGN_BITS;
+        cmmx_t     no = (*(cmmx_t*)(b + 4*bs) >> 1) & ~SIGN_BITS;
+
+        cmmx_t   qup_old_odd = p31avgb_s(old_o, old_po);
+        cmmx_t       qup_odd = p31avgb_s(    o,     po);
+        cmmx_t qdown_old_odd = p31avgb_s(old_o, old_no);
+        cmmx_t     qdown_odd = p31avgb_s(    o,     no);
+
+        cmmx_t   qup_even = p31avgb_s(ne, e);
+        cmmx_t qdown_even = p31avgb_s(e, ne);
+
+        cmmx_t    temp_up_diff = pdiffub_s(qdown_even, qup_old_odd);
+        cmmx_t   noise_up_diff = pdiffub_s(qdown_even, qup_odd);
+        cmmx_t  temp_down_diff = pdiffub_s(qup_even, qdown_old_odd);
+        cmmx_t noise_down_diff = pdiffub_s(qup_even, qdown_odd);
+
+        cmmx_t odd_diff = pdiffub_s(o, old_o);
+        m->odd  += psumbw_s(odd_diff) << 1;
+        m->even += psadbw_s(e, old_e) << 1;
+
+        temp_up_diff  = pminub_s(temp_up_diff, temp_down_diff);
+        temp_up_diff  = pminub_s(temp_up_diff, odd_diff);
+        m->temp      += psumbw_s(temp_up_diff) << 1;
+        noise_up_diff = pminub_s(noise_up_diff, odd_diff);
+        noise_up_diff = pminub_s(noise_up_diff, noise_down_diff);
+
+        m->noise += psumbw_s(noise_up_diff) << 1;
+        a += 2*as;
+        b += 2*bs;
+    } while (--lines);
+}
+
+static inline void
+get_metrics_faster_c(unsigned char *a, unsigned char *b, int as, int bs,
+                   int lines, struct metrics *m)
+{
+    a -= as;
+    b -= bs;
+    do {
+        cmmx_t old_po = (*(cmmx_t*)(a       )>>1) & ~SIGN_BITS;
+        cmmx_t     po = (*(cmmx_t*)(b       )>>1) & ~SIGN_BITS;
+        cmmx_t  old_e = (*(cmmx_t*)(a +   as)>>1) & ~SIGN_BITS;
+        cmmx_t      e = (*(cmmx_t*)(b +   bs)>>1) & ~SIGN_BITS;
+        cmmx_t  old_o = (*(cmmx_t*)(a + 2*as)>>1) & ~SIGN_BITS;
+        cmmx_t      o = (*(cmmx_t*)(b + 2*bs)>>1) & ~SIGN_BITS;
+        cmmx_t     ne = (*(cmmx_t*)(b + 3*bs)>>1) & ~SIGN_BITS;
+
+        cmmx_t  down_even = p31avgb_s(e, ne);
+        cmmx_t     up_odd = p31avgb_s(o, po);
+        cmmx_t up_old_odd = p31avgb_s(old_o, old_po);
+
+        cmmx_t   odd_diff = pdiffub_s(o, old_o);
+        cmmx_t  temp_diff = pdiffub_s(down_even, up_old_odd);
+        cmmx_t noise_diff = pdiffub_s(down_even, up_odd);
+
+        m->even += psadbw_s(e, old_e) << 1;
+        m->odd  += psumbw_s(odd_diff) << 1;
+
+        temp_diff  = pminub_s(temp_diff, odd_diff);
+        noise_diff = pminub_s(noise_diff, odd_diff);
+
+        m->noise += psumbw_s(noise_diff) << 1;
+        m->temp  += psumbw_s(temp_diff) << 1;
+        a += 2*as;
+        b += 2*bs;
+    } while (--lines);
+
+}
+
+static inline void
+get_block_stats(struct metrics *m, struct vf_priv_s *p, struct frame_stats *s)
+{
+    unsigned two_e = m->even  + MAX(m->even , p->thres.even );
+    unsigned two_o = m->odd   + MAX(m->odd  , p->thres.odd  );
+    unsigned two_n = m->noise + MAX(m->noise, p->thres.noise);
+    unsigned two_t = m->temp  + MAX(m->temp , p->thres.temp );
+
+    unsigned e_big   = m->even  >= (m->odd   + two_o + 1)/2;
+    unsigned o_big   = m->odd   >= (m->even  + two_e + 1)/2;
+    unsigned n_big   = m->noise >= (m->temp  + two_t + 1)/2;
+    unsigned t_big   = m->temp  >= (m->noise + two_n + 1)/2;
+
+    unsigned e2x     = m->even  >= two_o;
+    unsigned o2x     = m->odd   >= two_e;
+    unsigned n2x     = m->noise >= two_t;
+    unsigned t2x     = m->temp  >= two_n;
+
+    unsigned ntiny_e = m->even  > p->thres.even ;
+    unsigned ntiny_o = m->odd   > p->thres.odd  ;
+    unsigned ntiny_n = m->noise > p->thres.noise;
+    unsigned ntiny_t = m->temp  > p->thres.temp ;
+
+    unsigned nlow_e  = m->even  > 2*p->thres.even ;
+    unsigned nlow_o  = m->odd   > 2*p->thres.odd  ;
+    unsigned nlow_n  = m->noise > 2*p->thres.noise;
+    unsigned nlow_t  = m->temp  > 2*p->thres.temp ;
+
+    unsigned high_e  = m->even  > 4*p->thres.even ;
+    unsigned high_o  = m->odd   > 4*p->thres.odd  ;
+    unsigned high_n  = m->noise > 4*p->thres.noise;
+    unsigned high_t  = m->temp  > 4*p->thres.temp ;
+
+    unsigned low_il  = !n_big && !t_big && ntiny_n && ntiny_t;
+    unsigned high_il = !n_big && !t_big && nlow_n  && nlow_t;
+
+    if (low_il | high_il) {
+        s->interlaced_low  += low_il;
+        s->interlaced_high += high_il;
+    } else {
+        s->tiny.even  += ntiny_e;
+        s->tiny.odd   += ntiny_o;
+        s->tiny.noise += ntiny_n;
+        s->tiny.temp  += ntiny_t;
+
+        s->low .even  += nlow_e ;
+        s->low .odd   += nlow_o ;
+        s->low .noise += nlow_n ;
+        s->low .temp  += nlow_t ;
+
+        s->high.even  += high_e ;
+        s->high.odd   += high_o ;
+        s->high.noise += high_n ;
+        s->high.temp  += high_t ;
+
+        if (m->even  >=        p->sad_thres) s->sad.even  += m->even ;
+        if (m->odd   >=        p->sad_thres) s->sad.odd   += m->odd  ;
+        if (m->noise >=        p->sad_thres) s->sad.noise += m->noise;
+        if (m->temp  >=        p->sad_thres) s->sad.temp  += m->temp ;
+    }
+    s->num_blocks++;
+    s->max.even  = MAX(s->max.even , m->even );
+    s->max.odd   = MAX(s->max.odd  , m->odd  );
+    s->max.noise = MAX(s->max.noise, m->noise);
+    s->max.temp  = MAX(s->max.temp , m->temp );
+
+    s->bigger.even  += e_big  ;
+    s->bigger.odd   += o_big  ;
+    s->bigger.noise += n_big  ;
+    s->bigger.temp  += t_big  ;
+
+    s->twox.even  += e2x    ;
+    s->twox.odd   += o2x    ;
+    s->twox.noise += n2x    ;
+    s->twox.temp  += t2x    ;
+
+}
+
+static inline struct metrics
+block_metrics_c(unsigned char *a, unsigned char *b, int as, int bs,
+                int lines, struct vf_priv_s *p, struct frame_stats *s)
+{
+    struct metrics tm;
+    tm.even = tm.odd = tm.noise = tm.temp = 0;
+    get_metrics_c(a, b, as, bs, lines, &tm);
+    if (sizeof(cmmx_t) < 8)
+        get_metrics_c(a+4, b+4, as, bs, lines, &tm);
+    get_block_stats(&tm, p, s);
+    return tm;
+}
+
+static inline struct metrics
+block_metrics_fast_c(unsigned char *a, unsigned char *b, int as, int bs,
+                int lines, struct vf_priv_s *p, struct frame_stats *s)
+{
+    struct metrics tm;
+    tm.even = tm.odd = tm.noise = tm.temp = 0;
+    get_metrics_fast_c(a, b, as, bs, lines, &tm);
+    if (sizeof(cmmx_t) < 8)
+        get_metrics_fast_c(a+4, b+4, as, bs, lines, &tm);
+    get_block_stats(&tm, p, s);
+    return tm;
+}
+
+static inline struct metrics
+block_metrics_faster_c(unsigned char *a, unsigned char *b, int as, int bs,
+                int lines, struct vf_priv_s *p, struct frame_stats *s)
+{
+    struct metrics tm;
+    tm.even = tm.odd = tm.noise = tm.temp = 0;
+    get_metrics_faster_c(a, b, as, bs, lines, &tm);
+    if (sizeof(cmmx_t) < 8)
+        get_metrics_faster_c(a+4, b+4, as, bs, lines, &tm);
+    get_block_stats(&tm, p, s);
+    return tm;
+}
+
+#define MEQ(X,Y) ((X).even == (Y).even && (X).odd == (Y).odd && (X).temp == (Y).temp && (X).noise == (Y).noise)
+
+#define BLOCK_METRICS_TEMPLATE() \
+    __asm__ volatile("pxor %mm7, %mm7\n\t"   /* The result is colleted in mm7 */ \
+                 "pxor %mm6, %mm6\n\t"   /* Temp to stay at 0 */             \
+        );                                                                     \
+    a -= as;                                                                     \
+    b -= bs;                                                                     \
+    do {                                                                     \
+        __asm__ volatile(                                                     \
+            "movq (%0,%2), %%mm0\n\t"                                             \
+            "movq (%1,%3), %%mm1\n\t"   /* mm1 = even */                     \
+            PSADBW(%%mm1, %%mm0, %%mm4, %%mm6)                                     \
+            "paddusw %%mm0, %%mm7\n\t"  /* even diff */                             \
+            "movq (%0,%2,2), %%mm0\n\t" /* mm0 = old odd */                     \
+            "movq (%1,%3,2), %%mm2\n\t" /* mm2 = odd */                             \
+            "movq (%0), %%mm3\n\t"                                             \
+            "psubusb %4, %%mm3\n\t"                                             \
+            PAVGB(%%mm0, %%mm3)                                                     \
+            PAVGB(%%mm0, %%mm3)    /* mm3 = qup old odd */                     \
+            "movq %%mm0, %%mm5\n\t"                                             \
+            PSADBW(%%mm2, %%mm0, %%mm4, %%mm6)                                     \
+            "psllq $16, %%mm0\n\t"                                             \
+            "paddusw %%mm0, %%mm7\n\t"                                             \
+            "movq (%1), %%mm4\n\t"                                             \
+            "lea (%0,%2,2), %0\n\t"                                             \
+            "lea (%1,%3,2), %1\n\t"                                             \
+            "psubusb %4, %%mm4\n\t"                                             \
+            PAVGB(%%mm2, %%mm4)                                                     \
+            PAVGB(%%mm2, %%mm4)    /* mm4 = qup odd */                             \
+            PDIFFUBT(%%mm5, %%mm2, %%mm0) /* mm2 =abs(oldodd-odd) */             \
+            "movq (%1,%3), %%mm5\n\t"                                             \
+            "psubusb %4, %%mm5\n\t"                                             \
+            PAVGB(%%mm1, %%mm5)                                                     \
+            PAVGB(%%mm5, %%mm1)    /* mm1 = qdown even */                     \
+            PAVGB((%1,%3), %%mm5)  /* mm5 = qup next even */                     \
+            PDIFFUBT(%%mm1, %%mm3, %%mm0) /* mm3 = abs(qupoldo-qde) */             \
+            PDIFFUBT(%%mm1, %%mm4, %%mm0) /* mm4 = abs(qupodd-qde) */             \
+            PMINUBT(%%mm2, %%mm3, %%mm0)  /* limit temp to odd diff */             \
+            PMINUBT(%%mm2, %%mm4, %%mm0)  /* limit noise to odd diff */             \
+            "movq (%1,%3,2), %%mm2\n\t"                                             \
+            "psubusb %4, %%mm2\n\t"                                             \
+            PAVGB((%1), %%mm2)                                                     \
+            PAVGB((%1), %%mm2)    /* mm2 = qdown odd */                             \
+            "movq (%0,%2,2), %%mm1\n\t"                                             \
+            "psubusb %4, %%mm1\n\t"                                             \
+            PAVGB((%0), %%mm1)                                                     \
+            PAVGB((%0), %%mm1)  /* mm1 = qdown old odd */                     \
+            PDIFFUBT(%%mm5, %%mm2, %%mm0) /* mm2 = abs(qdo-qune) */             \
+            PDIFFUBT(%%mm5, %%mm1, %%mm0) /* mm1 = abs(qdoo-qune) */             \
+            PMINUBT(%%mm4, %%mm2, %%mm0)  /* current */                             \
+            PMINUBT(%%mm3, %%mm1, %%mm0)  /* old */                             \
+            PSUMBW(%%mm2, %%mm0, %%mm6)                                             \
+            PSUMBW(%%mm1, %%mm0, %%mm6)                                             \
+            "psllq $32, %%mm2\n\t"                                             \
+            "psllq $48, %%mm1\n\t"                                             \
+            "paddusw %%mm2, %%mm7\n\t"                                             \
+            "paddusw %%mm1, %%mm7\n\t"                                             \
+            : "=r" (a), "=r" (b)                                             \
+            : "r"((x86_reg)as), "r"((x86_reg)bs), "m" (ones), "0"(a), "1"(b), "X"(*a), "X"(*b) \
+            );                                                                     \
+    } while (--lines);
+
+static inline struct metrics
+block_metrics_3dnow(unsigned char *a, unsigned char *b, int as, int bs,
+                    int lines, struct vf_priv_s *p, struct frame_stats *s)
+{
+    struct metrics tm;
+#if !HAVE_AMD3DNOW
+    mp_msg(MSGT_VFILTER, MSGL_FATAL, "block_metrics_3dnow: internal error\n");
+#else
+    static const unsigned long long ones = 0x0101010101010101ull;
+
+    BLOCK_METRICS_TEMPLATE();
+    __asm__ volatile("movq %%mm7, %0\n\temms" : "=m" (tm));
+    get_block_stats(&tm, p, s);
+#endif
+    return tm;
+}
+
+#undef PSUMBW
+#undef PSADBW
+#undef PMAXUB
+#undef PMINUBT
+#undef PAVGB
+
+#define PSUMBW(X,T,Z)        "psadbw " #Z "," #X "\n\t"
+#define PSADBW(X,Y,T,Z) "psadbw " #X "," #Y "\n\t"
+#define PMAXUB(X,Y)        "pmaxub " #X "," #Y "\n\t"
+#define PMINUBT(X,Y,T)        "pminub " #X "," #Y "\n\t"
+#define PAVGB(X,Y)        "pavgb "  #X "," #Y "\n\t"
+
+static inline struct metrics
+block_metrics_mmx2(unsigned char *a, unsigned char *b, int as, int bs,
+                   int lines, struct vf_priv_s *p, struct frame_stats *s)
+{
+    struct metrics tm;
+#if !HAVE_MMX
+    mp_msg(MSGT_VFILTER, MSGL_FATAL, "block_metrics_mmx2: internal error\n");
+#else
+    static const unsigned long long ones = 0x0101010101010101ull;
+    x86_reg interlaced;
+    x86_reg prefetch_line = (((long)a>>3) & 7) + 10;
+#ifdef DEBUG
+    struct frame_stats ts = *s;
+#endif
+    __asm__ volatile("prefetcht0 (%0,%2)\n\t"
+                 "prefetcht0 (%1,%3)\n\t" :
+                 : "r" (a), "r" (b),
+                 "r" (prefetch_line * as), "r" (prefetch_line * bs));
+
+    BLOCK_METRICS_TEMPLATE();
+
+    s->num_blocks++;
+    __asm__ volatile(
+        "movq %3, %%mm0\n\t"
+        "movq %%mm7, %%mm1\n\t"
+        "psubusw %%mm0, %%mm1\n\t"
+        "movq %%mm1, %%mm2\n\t"
+        "paddusw %%mm0, %%mm2\n\t"
+        "paddusw %%mm7, %%mm2\n\t"
+        "pshufw $0xb1, %%mm2, %%mm3\n\t"
+        "pavgw %%mm7, %%mm2\n\t"
+        "pshufw $0xb1, %%mm2, %%mm2\n\t"
+        "psubusw %%mm7, %%mm2\n\t"
+        "pcmpeqw %%mm6, %%mm2\n\t" /* 1 if >= 1.5x */
+        "psubusw %%mm7, %%mm3\n\t"
+        "pcmpeqw %%mm6, %%mm3\n\t" /* 1 if >= 2x */
+        "movq %1, %%mm4\n\t"
+        "movq %2, %%mm5\n\t"
+        "psubw %%mm2, %%mm4\n\t"
+        "psubw %%mm3, %%mm5\n\t"
+        "movq %%mm4, %1\n\t"
+        "movq %%mm5, %2\n\t"
+        "pxor %%mm4, %%mm4\n\t"
+        "pcmpeqw %%mm1, %%mm4\n\t" /* 1 if <= t */
+        "psubusw %%mm0, %%mm1\n\t"
+        "pxor %%mm5, %%mm5\n\t"
+        "pcmpeqw %%mm1, %%mm5\n\t" /* 1 if <= 2t */
+        "psubusw %%mm0, %%mm1\n\t"
+        "psubusw %%mm0, %%mm1\n\t"
+        "pcmpeqw %%mm6, %%mm1\n\t" /* 1 if <= 4t */
+        "pshufw $0xb1, %%mm2, %%mm0\n\t"
+        "por %%mm2, %%mm0\n\t"     /* 1 if not close */
+        "punpckhdq %%mm0, %%mm0\n\t"
+        "movq %%mm4, %%mm2\n\t"      /* tttt */
+        "punpckhdq %%mm5, %%mm2\n\t" /* ttll */
+        "por %%mm2, %%mm0\n\t"
+        "pcmpeqd %%mm6, %%mm0\n\t" /* close && big */
+        "psrlq $16, %%mm0\n\t"
+        "psrlw $15, %%mm0\n\t"
+        "movd %%mm0, %0\n\t"
+        : "=r" (interlaced), "=m" (s->bigger), "=m" (s->twox)
+        : "m" (p->thres)
+        );
+
+    if (interlaced) {
+        s->interlaced_high += interlaced >> 16;
+        s->interlaced_low += interlaced;
+    } else {
+        __asm__ volatile(
+            "pcmpeqw %%mm0, %%mm0\n\t" /* -1 */
+            "psubw         %%mm0, %%mm4\n\t"
+            "psubw         %%mm0, %%mm5\n\t"
+            "psubw         %%mm0, %%mm1\n\t"
+            "paddw %0, %%mm4\n\t"
+            "paddw %1, %%mm5\n\t"
+            "paddw %2, %%mm1\n\t"
+            "movq %%mm4, %0\n\t"
+            "movq %%mm5, %1\n\t"
+            "movq %%mm1, %2\n\t"
+            : "=m" (s->tiny), "=m" (s->low), "=m" (s->high)
+            );
+
+        __asm__ volatile(
+            "pshufw $0, %2, %%mm0\n\t"
+            "psubusw %%mm7, %%mm0\n\t"
+            "pcmpeqw %%mm6, %%mm0\n\t"   /* 0 if below sad_thres */
+            "pand %%mm7, %%mm0\n\t"
+            "movq %%mm0, %%mm1\n\t"
+            "punpcklwd %%mm6, %%mm0\n\t" /* sad even, odd */
+            "punpckhwd %%mm6, %%mm1\n\t" /* sad noise, temp */
+            "paddd %0, %%mm0\n\t"
+            "paddd %1, %%mm1\n\t"
+            "movq %%mm0, %0\n\t"
+            "movq %%mm1, %1\n\t"
+            : "=m" (s->sad.even), "=m" (s->sad.noise)
+            : "m" (p->sad_thres)
+            );
+    }
+
+    __asm__ volatile(
+        "movq %%mm7, (%1)\n\t"
+        PMAXUW((%0), %%mm7)
+        "movq %%mm7, (%0)\n\t"
+        "emms"
+        : : "r" (&s->max), "r" (&tm), "X" (s->max)
+        : "memory"
+        );
+#ifdef DEBUG
+    if (1) {
+        struct metrics cm;
+        a -= 7*as;
+        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");
+        if (s) {
+#           define CHECK(X) if (!MEQ(s->X, ts.X)) \
+                mp_msg(MSGT_VFILTER, MSGL_WARN, "Bad " #X "\n");
+            CHECK(tiny);
+            CHECK(low);
+            CHECK(high);
+            CHECK(sad);
+            CHECK(max);
+        }
+    }
+#endif
+#endif
+    return tm;
+}
+
+static inline int
+dint_copy_line_mmx2(unsigned char *dst, unsigned char *a, long bos,
+                    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");
+    return 0;
+#else
+    unsigned long len = (w+7) >> 3;
+    int ret;
+    __asm__ volatile (
+        "pxor %%mm6, %%mm6 \n\t"       /* deinterlaced pixel counter */
+        "movd %0, %%mm7 \n\t"
+        "punpcklbw %%mm7, %%mm7 \n\t"
+        "punpcklwd %%mm7, %%mm7 \n\t"
+        "punpckldq %%mm7, %%mm7 \n\t"  /* mm7 = threshold */
+        : /* no output */
+        : "rm" (t)
+        );
+    do {
+        __asm__ volatile (
+            "movq (%0), %%mm0\n\t"
+            "movq (%0,%3,2), %%mm1\n\t"
+            "movq %%mm0, (%2)\n\t"
+            "pmaxub %%mm1, %%mm0\n\t"
+            "pavgb (%0), %%mm1\n\t"
+            "psubusb %%mm1, %%mm0\n\t"
+            "paddusb %%mm7, %%mm0\n\t"  /* mm0 = max-avg+thr */
+            "movq (%0,%1), %%mm2\n\t"
+            "movq (%0,%5), %%mm3\n\t"
+            "movq %%mm2, %%mm4\n\t"
+            PDIFFUBT(%%mm1, %%mm2, %%mm5)
+            PDIFFUBT(%%mm1, %%mm3, %%mm5)
+            "pminub %%mm2, %%mm3\n\t"
+            "pcmpeqb %%mm3, %%mm2\n\t"  /* b = min */
+            "pand %%mm2, %%mm4\n\t"
+            "pandn (%0,%5), %%mm2\n\t"
+            "por %%mm4, %%mm2\n\t"
+            "pminub %%mm0, %%mm3\n\t"
+            "pcmpeqb %%mm0, %%mm3\n\t"  /* set to 1s if >= threshold */
+            "psubb %%mm3, %%mm6\n\t"    /* count pixels above thr. */
+            "pand %%mm3, %%mm1 \n\t"
+            "pandn %%mm2, %%mm3 \n\t"
+            "por %%mm3, %%mm1 \n\t"     /* avg if >= threshold */
+            "movq %%mm1, (%2,%4) \n\t"
+            : /* no output */
+            : "r" (a), "r" ((x86_reg)bos), "r" ((x86_reg)dst), "r" ((x86_reg)ss), "r" ((x86_reg)ds), "r" ((x86_reg)cos)
+            );
+        a += 8;
+        dst += 8;
+    } while (--len);
+
+    __asm__ volatile ("pxor %%mm7, %%mm7 \n\t"
+                  "psadbw %%mm6, %%mm7 \n\t"
+                  "movd %%mm7, %0 \n\t"
+                  "emms \n\t"
+                  : "=r" (ret)
+        );
+    return ret;
+#endif
+}
+
+static inline int
+dint_copy_line(unsigned char *dst, unsigned char *a, long bos,
+               long cos, int ds, int ss, int w, int t)
+{
+    unsigned long len = ((unsigned long)w+sizeof(cmmx_t)-1) / sizeof(cmmx_t);
+    cmmx_t dint_count = 0;
+    cmmx_t thr;
+    t |= t <<  8;
+    thr = t | (t << 16);
+    if (sizeof(cmmx_t) > 4)
+        thr |= thr << (sizeof(cmmx_t)*4);
+    do {
+        cmmx_t e = *(cmmx_t*)a;
+        cmmx_t ne = *(cmmx_t*)(a+2*ss);
+        cmmx_t o = *(cmmx_t*)(a+bos);
+        cmmx_t oo = *(cmmx_t*)(a+cos);
+        cmmx_t maxe = pmaxub(e, ne);
+        cmmx_t avge = pavgb(e, ne);
+        cmmx_t max_diff = maxe - avge + thr; /* 0<=max-avg<128, thr<128 */
+        cmmx_t diffo  = pdiffub(avge, o);
+        cmmx_t diffoo = pdiffub(avge, oo);
+        cmmx_t diffcmp = pcmpgtub(diffo, diffoo);
+        cmmx_t bo = ((oo ^ o) & diffcmp) ^ o;
+        cmmx_t diffbo = ((diffoo ^ diffo) & diffcmp) ^ diffo;
+        cmmx_t above_thr = ~pcmpgtub(max_diff, diffbo);
+        cmmx_t bo_or_avg = ((avge ^ bo) & above_thr) ^ bo;
+        dint_count += above_thr & ONE_BYTES;
+        *(cmmx_t*)(dst) = e;
+        *(cmmx_t*)(dst+ds) = bo_or_avg;
+        a += sizeof(cmmx_t);
+        dst += sizeof(cmmx_t);
+    } while (--len);
+    return psumbw(dint_count);
+}
+
+static int
+dint_copy_plane(unsigned char *d, unsigned char *a, unsigned char *b,
+                unsigned char *c, unsigned long w, unsigned long h,
+                unsigned long ds, unsigned long ss, unsigned long threshold,
+                long field, long mmx2)
+{
+    unsigned long ret = 0;
+    long bos = b - a;
+    long cos = c - a;
+    if (field) {
+        fast_memcpy(d, b, w);
+        h--;
+        d += ds;
+        a += ss;
+    }
+    bos += ss;
+    cos += ss;
+    while (h > 2) {
+        if (threshold >= 128) {
+            fast_memcpy(d, a, w);
+            fast_memcpy(d+ds, a+bos, w);
+        } else if (mmx2 == 1) {
+            ret += dint_copy_line_mmx2(d, a, bos, cos, ds, ss, w, threshold);
+        } else
+            ret += dint_copy_line(d, a, bos, cos, ds, ss, w, threshold);
+        h -= 2;
+        d += 2*ds;
+        a += 2*ss;
+    }
+    fast_memcpy(d, a, w);
+    if (h == 2)
+        fast_memcpy(d+ds, a+bos, w);
+    return ret;
+}
+
+static void
+copy_merge_fields(struct vf_priv_s *p, mp_image_t *dmpi,
+                  unsigned char **old, unsigned char **new, unsigned long show)
+{
+    unsigned long threshold = 256;
+    unsigned long field = p->swapped;
+    unsigned long dint_pixels = 0;
+    unsigned char **other = old;
+    if (show >= 12 || !(show & 3))
+        show >>= 2, other = new, new = old;
+    if (show <= 2) {  /* Single field: de-interlace */
+        threshold = p->dint_thres;
+        field ^= show & 1;
+        old = new;
+    } else if (show == 3)
+        old = new;
+    else
+        field ^= 1;
+    dint_pixels +=dint_copy_plane(dmpi->planes[0], old[0], new[0],
+                                  other[0], p->w, p->h, dmpi->stride[0],
+                                  p->stride, threshold, field, p->mmx2);
+    if (dmpi->flags & MP_IMGFLAG_PLANAR) {
+        if (p->luma_only)
+            old = new, other = new;
+        else
+            threshold = threshold/2 + 1;
+        field ^= p->chroma_swapped;
+        dint_copy_plane(dmpi->planes[1], old[1], new[1],
+                        other[1], p->cw, p->ch,        dmpi->stride[1],
+                        p->chroma_stride, threshold, field, p->mmx2);
+        dint_copy_plane(dmpi->planes[2], old[2], new[2],
+                        other[2], p->cw, p->ch, dmpi->stride[2],
+                        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);
+}
+
+static void diff_planes(struct vf_priv_s *p, struct frame_stats *s,
+                        unsigned char *of, unsigned char *nf,
+                        int w, int h, int os, int ns, int swapped)
+{
+    int i, y;
+    int align = -(long)nf & 7;
+    of += align;
+    nf += align;
+    w -= align;
+    if (swapped)
+        of -= os, nf -= ns;
+    i = (h*3 >> 7) & ~1;
+    of += i*os + 8;
+    nf += i*ns + 8;
+    h -= i;
+    w -= 16;
+
+    memset(s, 0, sizeof(*s));
+
+    for (y = (h-8) >> 3; y; y--) {
+        if (p->mmx2 == 1) {
+            for (i = 0; i < w; i += 8)
+                block_metrics_mmx2(of+i, nf+i, os, ns, 4, p, s);
+        } else if (p->mmx2 == 2) {
+            for (i = 0; i < w; i += 8)
+                block_metrics_3dnow(of+i, nf+i, os, ns, 4, p, s);
+        } else if (p->fast > 3) {
+            for (i = 0; i < w; i += 8)
+                block_metrics_faster_c(of+i, nf+i, os, ns, 4, p, s);
+        } else if (p->fast > 1) {
+            for (i = 0; i < w; i += 8)
+                block_metrics_fast_c(of+i, nf+i, os, ns, 4, p, s);
+        } else {
+            for (i = 0; i < w; i += 8)
+                block_metrics_c(of+i, nf+i, os, ns, 4, p, s);
+        }
+        of += 8*os;
+        nf += 8*ns;
+    }
+}
+
+#define METRICS(X) (X).even, (X).odd, (X).noise, (X).temp
+
+static void diff_fields(struct vf_priv_s *p, struct frame_stats *s,
+                        unsigned char **old, unsigned char **new)
+{
+    diff_planes(p, s, old[0], new[0], p->w, p->h,
+                p->stride, p->stride, p->swapped);
+    s->sad.even  = (s->sad.even  * 16ul) / s->num_blocks;
+    s->sad.odd   = (s->sad.odd   * 16ul) / s->num_blocks;
+    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, "
+               "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,
+               METRICS(s->tiny), METRICS(s->low), METRICS(s->high),
+               METRICS(s->bigger), METRICS(s->twox), METRICS(s->sad),
+               s->interlaced_low, s->interlaced_high,
+               p->iosync / (double) p->in_inc);
+}
+
+static const char *parse_args(struct vf_priv_s *p, const char *args)
+{
+    args--;
+    while (args && *++args &&
+           (sscanf(args, "io=%lu:%lu", &p->out_dec, &p->in_inc) == 2 ||
+            sscanf(args, "diff_thres=%hu", &p->thres.even ) == 1 ||
+            sscanf(args, "comb_thres=%hu", &p->thres.noise) == 1 ||
+            sscanf(args, "sad_thres=%lu",  &p->sad_thres  ) == 1 ||
+            sscanf(args, "dint_thres=%lu", &p->dint_thres ) == 1 ||
+            sscanf(args, "fast=%u",        &p->fast       ) == 1 ||
+            sscanf(args, "mmx2=%lu",       &p->mmx2       ) == 1 ||
+            sscanf(args, "luma_only=%u",   &p->luma_only  ) == 1 ||
+            sscanf(args, "verbose=%u",     &p->verbose    ) == 1 ||
+            sscanf(args, "crop=%lu:%lu:%lu:%lu", &p->w,
+                   &p->h, &p->crop_x, &p->crop_y) == 4))
+        args = strchr(args, '/');
+    return args;
+}
+
+static unsigned long gcd(unsigned long x, unsigned long y)
+{
+    unsigned long t;
+    if (x > y)
+        t = x, x = y, y = t;
+
+    while (x) {
+        t = y % x;
+        y = x;
+        x = t;
+    }
+    return y;
+}
+
+static void init(struct vf_priv_s *p, mp_image_t *mpi)
+{
+    unsigned long i;
+    unsigned long plane_size, chroma_plane_size;
+    unsigned char *plane;
+    unsigned long cos, los;
+    p->crop_cx = p->crop_x >> mpi->chroma_x_shift;
+    p->crop_cy = p->crop_y >> mpi->chroma_y_shift;
+    if (mpi->flags & MP_IMGFLAG_ACCEPT_STRIDE) {
+        p->stride = (mpi->w + 15) & ~15;
+        p->chroma_stride = p->stride >> mpi->chroma_x_shift;
+    } else {
+        p->stride = mpi->width;
+        p->chroma_stride = mpi->chroma_width;
+    }
+    p->cw = p->w >> mpi->chroma_x_shift;
+    p->ch = p->h >> mpi->chroma_y_shift;
+    p->nplanes = 1;
+    p->static_idx = 0;
+    p->temp_idx = 0;
+    p->old_planes = p->planes[0];
+    plane_size = mpi->h * p->stride;
+    chroma_plane_size = mpi->flags & MP_IMGFLAG_PLANAR ?
+        mpi->chroma_height * p->chroma_stride : 0;
+    p->memory_allocated =
+        malloc(NUM_STORED * (plane_size+2*chroma_plane_size) +
+               8*p->chroma_stride + 4096);
+    /* align to page boundary */
+    plane = p->memory_allocated + (-(long)p->memory_allocated & 4095);
+    memset(plane, 0, NUM_STORED * plane_size);
+    los = p->crop_x  + p->crop_y  * p->stride;
+    cos = p->crop_cx + p->crop_cy * p->chroma_stride;
+    for (i = 0; i != NUM_STORED; i++, plane += plane_size) {
+        p->planes[i][0] = plane;
+        p->planes[NUM_STORED + i][0] = plane + los;
+    }
+    if (mpi->flags & MP_IMGFLAG_PLANAR) {
+        p->nplanes = 3;
+        memset(plane, 0x80, NUM_STORED * 2 * chroma_plane_size);
+        for (i = 0; i != NUM_STORED; i++) {
+            p->planes[i][1] = plane;
+            p->planes[NUM_STORED + i][1] = plane + cos;
+            plane += chroma_plane_size;
+            p->planes[i][2] = plane;
+            p->planes[NUM_STORED + i][2] = plane + cos;
+            plane += chroma_plane_size;
+        }
+    }
+    p->out_dec <<= 2;
+    i = gcd(p->in_inc, p->out_dec);
+    p->in_inc /= i;
+    p->out_dec /= i;
+    p->iosync = 0;
+    p->num_fields = 3;
+}
+
+static inline double get_time(void)
+{
+    struct timeval tv;
+    gettimeofday(&tv, 0);
+    return tv.tv_sec + tv.tv_usec * 1e-6;
+}
+
+static void get_image(struct vf_instance *vf, mp_image_t *mpi)
+{
+    struct vf_priv_s *p = vf->priv;
+    static unsigned char **planes, planes_idx;
+
+    if (mpi->type == MP_IMGTYPE_STATIC) return;
+
+    if (!p->planes[0][0]) init(p, mpi);
+
+    if (mpi->type == MP_IMGTYPE_TEMP ||
+        (mpi->type == MP_IMGTYPE_IPB && !(mpi->flags & MP_IMGFLAG_READABLE)))
+        planes_idx = NUM_STORED/2 + (++p->temp_idx % (NUM_STORED/2));
+    else
+        planes_idx = ++p->static_idx % (NUM_STORED/2);
+    planes = p->planes[planes_idx];
+    mpi->priv = p->planes[NUM_STORED + planes_idx];
+    if (mpi->priv == p->old_planes) {
+        unsigned char **old_planes =
+            p->planes[NUM_STORED + 2 + (++p->temp_idx & 1)];
+        my_memcpy_pic(old_planes[0], p->old_planes[0],
+                      p->w, p->h, p->stride, p->stride);
+        if (mpi->flags & MP_IMGFLAG_PLANAR) {
+            my_memcpy_pic(old_planes[1], p->old_planes[1],
+                          p->cw, p->ch, p->chroma_stride, p->chroma_stride);
+            my_memcpy_pic(old_planes[2], p->old_planes[2],
+                          p->cw, p->ch, p->chroma_stride, p->chroma_stride);
+        }
+        p->old_planes = old_planes;
+        p->num_copies++;
+    }
+    mpi->planes[0] = planes[0];
+    mpi->stride[0] = p->stride;
+    if (mpi->flags & MP_IMGFLAG_PLANAR) {
+        mpi->planes[1] = planes[1];
+        mpi->planes[2] = planes[2];
+        mpi->stride[1] = mpi->stride[2] = p->chroma_stride;
+    }
+    mpi->width = p->stride;
+
+    mpi->flags |= MP_IMGFLAG_DIRECT;
+    mpi->flags &= ~MP_IMGFLAG_DRAW_CALLBACK;
+}
+
+static inline long
+cmpe(unsigned long x, unsigned long y, unsigned long err, unsigned long e)
+{
+    long diff = x-y;
+    long unit = ((x+y+err) >> e);
+    long ret = (diff > unit) - (diff < -unit);
+    unit >>= 1;
+    return ret + (diff > unit) - (diff < -unit);
+}
+
+static unsigned long
+find_breaks(struct vf_priv_s *p, struct frame_stats *s)
+{
+    struct frame_stats *ps = &p->stats[(p->inframes-1) & 1];
+    long notfilm = 5*p->in_inc - p->out_dec;
+    unsigned long n = s->num_blocks >> 8;
+    unsigned long sad_comb_cmp = cmpe(s->sad.temp, s->sad.noise, 512, 1);
+    unsigned long ret = 8;
+
+    if (cmpe(s->sad.temp, s->sad.even, 512, 1) > 0)
+        mp_msg(MSGT_VFILTER, MSGL_WARN,
+               "@@@@@@@@ Bottom-first field??? @@@@@@@@\n");
+    if (s->sad.temp > 1000 && s->sad.noise > 1000)
+        return 3;
+    if (s->interlaced_high >= 2*n && s->sad.temp > 256 && s->sad.noise > 256)
+        return 3;
+    if (s->high.noise > s->num_blocks/4 && s->sad.noise > 10000 &&
+        s->sad.noise > 2*s->sad.even && s->sad.noise > 2*ps->sad.odd) {
+        // Mid-frame scene change
+        if (s->tiny.temp + s->interlaced_low  < n   ||
+            s->low.temp  + s->interlaced_high < n/4 ||
+            s->high.temp + s->interlaced_high < n/8 ||
+            s->sad.temp < 160)
+            return 1;
+        return 3;
+    }
+    if (s->high.temp > s->num_blocks/4 && s->sad.temp > 10000 &&
+        s->sad.temp > 2*ps->sad.odd && s->sad.temp > 2*ps->sad.even) {
+        // Start frame scene change
+        if (s->tiny.noise + s->interlaced_low  < n   ||
+            s->low.noise  + s->interlaced_high < n/4 ||
+            s->high.noise + s->interlaced_high < n/8 ||
+            s->sad.noise < 160)
+            return 2;
+        return 3;
+    }
+    if (sad_comb_cmp == 2)
+        return 2;
+    if (sad_comb_cmp == -2)
+        return 1;
+
+    if (s->tiny.odd > 3*MAX(n,s->tiny.even) + s->interlaced_low)
+        return 1;
+    if (s->tiny.even > 3*MAX(n,s->tiny.odd)+s->interlaced_low &&
+        (!sad_comb_cmp || (s->low.noise <= n/4 && s->low.temp <= n/4)))
+        return 4;
+
+    if (s->sad.noise < 64 && s->sad.temp < 64 &&
+        s->low.noise <= n/2 && s->high.noise <= n/4 &&
+        s->low.temp  <= n/2 && s->high.temp  <= n/4)
+        goto still;
+
+    if (s->tiny.temp > 3*MAX(n,s->tiny.noise) + s->interlaced_low)
+        return 2;
+    if (s->tiny.noise > 3*MAX(n,s->tiny.temp) + s->interlaced_low)
+        return 1;
+
+    if (s->low.odd > 3*MAX(n/4,s->low.even) + s->interlaced_high)
+        return 1;
+    if (s->low.even > 3*MAX(n/4,s->low.odd)+s->interlaced_high &&
+        s->sad.even > 2*s->sad.odd &&
+        (!sad_comb_cmp || (s->low.noise <= n/4 && s->low.temp <= n/4)))
+        return 4;
+
+    if (s->low.temp > 3*MAX(n/4,s->low.noise) + s->interlaced_high)
+        return 2;
+    if (s->low.noise > 3*MAX(n/4,s->low.temp) + s->interlaced_high)
+        return 1;
+
+    if (sad_comb_cmp == 1 && s->sad.noise < 64)
+        return 2;
+    if (sad_comb_cmp == -1 && s->sad.temp < 64)
+        return 1;
+
+    if (s->tiny.odd <= n || (s->tiny.noise <= n/2 && s->tiny.temp <= n/2)) {
+        if (s->interlaced_low <= n) {
+            if (p->num_fields == 1)
+                goto still;
+            if (s->tiny.even <= n || ps->tiny.noise <= n/2)
+                /* Still frame */
+                goto still;
+            if (s->bigger.even >= 2*MAX(n,s->bigger.odd) + s->interlaced_low)
+                return 4;
+            if (s->low.even >= 2*n + s->interlaced_low)
+                return 4;
+            goto still;
+        }
+    }
+    if (s->low.odd <= n/4) {
+        if (s->interlaced_high <= n/4) {
+            if (p->num_fields == 1)
+                goto still;
+            if (s->low.even <= n/4)
+                /* Still frame */
+                goto still;
+            if (s->bigger.even >= 2*MAX(n/4,s->bigger.odd)+s->interlaced_high)
+                return 4;
+            if (s->low.even >= n/2 + s->interlaced_high)
+                return 4;
+            goto still;
+        }
+    }
+    if (s->bigger.temp > 2*MAX(n,s->bigger.noise) + s->interlaced_low)
+        return 2;
+    if (s->bigger.noise > 2*MAX(n,s->bigger.temp) + s->interlaced_low)
+        return 1;
+    if (s->bigger.temp > 2*MAX(n,s->bigger.noise) + s->interlaced_high)
+        return 2;
+    if (s->bigger.noise > 2*MAX(n,s->bigger.temp) + s->interlaced_high)
+        return 1;
+    if (s->twox.temp > 2*MAX(n,s->twox.noise) + s->interlaced_high)
+        return 2;
+    if (s->twox.noise > 2*MAX(n,s->twox.temp) + s->interlaced_high)
+        return 1;
+    if (s->bigger.even > 2*MAX(n,s->bigger.odd) + s->interlaced_low &&
+        s->bigger.temp < n && s->bigger.noise < n)
+        return 4;
+    if (s->interlaced_low > MIN(2*n, s->tiny.odd))
+        return 3;
+    ret = 8 + (1 << (s->sad.temp > s->sad.noise));
+  still:
+    if (p->num_fields == 1 && p->prev_fields == 3 && notfilm >= 0 &&
+        (s->tiny.temp <= s->tiny.noise || s->sad.temp < s->sad.noise+16))
+        return 1;
+    if (p->notout < p->num_fields && p->iosync > 2*p->in_inc && notfilm < 0)
+        notfilm = 0;
+    if (p->num_fields < 2 ||
+        (p->num_fields == 2 && p->prev_fields == 2 && notfilm < 0))
+        return ret;
+    if (!notfilm && (p->prev_fields&~1) == 2) {
+        if (p->prev_fields + p->num_fields == 5) {
+            if (s->tiny.noise <= s->tiny.temp ||
+                s->low.noise == 0 || s->low.noise < s->low.temp ||
+                s->sad.noise < s->sad.temp+16)
+                return 2;
+        }
+        if (p->prev_fields + p->num_fields == 4) {
+            if (s->tiny.temp <= s->tiny.noise ||
+                s->low.temp == 0 || s->low.temp < s->low.noise ||
+                s->sad.temp < s->sad.noise+16)
+                return 1;
+        }
+    }
+    if (p->num_fields > 2 &&
+        ps->sad.noise > s->sad.noise && ps->sad.noise > s->sad.temp)
+        return 4;
+    return 2 >> (s->sad.noise > s->sad.temp);
+}
+
+#define ITOC(X) (!(X) ? ' ' : (X) + ((X)>9 ? 'a'-10 : '0'))
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+    mp_image_t *dmpi;
+    struct vf_priv_s *p = vf->priv;
+    unsigned char **planes, **old_planes;
+    struct frame_stats *s  = &p->stats[p->inframes & 1];
+    struct frame_stats *ps = &p->stats[(p->inframes-1) & 1];
+    int swapped = 0;
+    const int flags = mpi->fields;
+    int breaks, prev;
+    int show_fields = 0;
+    int dropped_fields = 0;
+    double start_time, diff_time;
+    char prev_chflag = p->chflag;
+    int keep_rate;
+
+    if (!p->planes[0][0]) init(p, mpi);
+
+    old_planes = p->old_planes;
+
+    if ((mpi->flags & MP_IMGFLAG_DIRECT) && mpi->priv) {
+        planes = mpi->priv;
+        mpi->priv = 0;
+    } else {
+        planes = p->planes[2 + (++p->temp_idx & 1)];
+        my_memcpy_pic(planes[0],
+                      mpi->planes[0] + p->crop_x + p->crop_y * mpi->stride[0],
+                      p->w, p->h, p->stride, mpi->stride[0]);
+        if (mpi->flags & MP_IMGFLAG_PLANAR) {
+            my_memcpy_pic(planes[1],
+                          mpi->planes[1] + p->crop_cx + p->crop_cy * mpi->stride[1],
+                          p->cw, p->ch, p->chroma_stride, mpi->stride[1]);
+            my_memcpy_pic(planes[2],
+                          mpi->planes[2] + p->crop_cx + p->crop_cy * mpi->stride[2],
+                          p->cw, p->ch, p->chroma_stride, mpi->stride[2]);
+            p->num_copies++;
+        }
+    }
+
+    p->old_planes = planes;
+    p->chflag = ';';
+    if (flags & MP_IMGFIELD_ORDERED) {
+        swapped = !(flags & MP_IMGFIELD_TOP_FIRST);
+        p->chflag = (flags & MP_IMGFIELD_REPEAT_FIRST ? '|' :
+                     flags & MP_IMGFIELD_TOP_FIRST ? ':' : '.');
+    }
+    p->swapped = swapped;
+
+    start_time = get_time();
+    if (p->chflag == '|') {
+        *s = ppzs;
+        p->iosync += p->in_inc;
+    } else if ((p->fast & 1) && prev_chflag == '|')
+        *s = pprs;
+    else
+        diff_fields(p, s, old_planes, planes);
+    diff_time = get_time();
+    p->diff_time += diff_time - start_time;
+    breaks = p->inframes ? find_breaks(p, s) : 2;
+    p->inframes++;
+    keep_rate = 4*p->in_inc == p->out_dec;
+
+    switch (breaks) {
+      case 0:
+      case 8:
+      case 9:
+      case 10:
+        if (!keep_rate && p->notout < p->num_fields && p->iosync < 2*p->in_inc)
+            break;
+        if (p->notout < p->num_fields)
+            dropped_fields = -2;
+      case 4:
+        if (keep_rate || p->iosync >= -2*p->in_inc)
+            show_fields = (4<<p->num_fields)-1;
+        break;
+      case 3:
+        if (keep_rate)
+            show_fields = 2;
+        else if (p->iosync > 0) {
+            if (p->notout >= p->num_fields && p->iosync > 2*p->in_inc) {
+                show_fields = 4; /* prev odd only */
+                if (p->num_fields > 1)
+                    show_fields |= 8; /* + prev even */
+            } else {
+                show_fields = 2; /* even only */
+                if (p->notout >= p->num_fields)
+                    dropped_fields += p->num_fields;
+            }
+        }
+        break;
+      case 2:
+        if (p->iosync <= -3*p->in_inc) {
+            if (p->notout >= p->num_fields)
+                dropped_fields = p->num_fields;
+            break;
+        }
+        if (p->num_fields == 1) {
+            int prevbreak = ps->sad.noise >= 128;
+            if (p->iosync < 4*p->in_inc) {
+                show_fields = 3;
+                dropped_fields = prevbreak;
+            } else {
+                show_fields = 4 | (!prevbreak << 3);
+                if (p->notout < 1 + p->prev_fields)
+                    dropped_fields = -!prevbreak;
+            }
+            break;
+        }
+      default:
+        if (keep_rate)
+            show_fields = 3 << (breaks & 1);
+        else if (p->notout >= p->num_fields &&
+            p->iosync >= (breaks == 1 ? -p->in_inc :
+                          p->in_inc << (p->num_fields == 1))) {
+            show_fields = (1 << (2 + p->num_fields)) - (1<<breaks);
+        } else {
+            if (p->notout >= p->num_fields)
+                dropped_fields += p->num_fields + 2 - breaks;
+            if (breaks == 1) {
+                if (p->iosync >= 4*p->in_inc)
+                    show_fields = 6;
+            } else if (p->iosync > -3*p->in_inc)
+                show_fields = 3;  /* odd+even */
+        }
+        break;
+    }
+
+    show_fields &= 15;
+    prev = p->prev_fields;
+    if (breaks < 8) {
+        if (p->num_fields == 1)
+            breaks &= ~4;
+        if (breaks)
+            p->num_breaks++;
+        if (breaks == 3)
+            p->prev_fields = p->num_fields = 1;
+        else if (breaks) {
+            p->prev_fields = p->num_fields + (breaks==1) - (breaks==4);
+            p->num_fields = breaks - (breaks == 4) + (p->chflag == '|');
+        } else
+            p->num_fields += 2;
+    } else
+        p->num_fields += 2;
+
+    p->iosync += 4 * p->in_inc;
+    if (p->chflag == '|')
+        p->iosync += p->in_inc;
+
+    if (show_fields) {
+        p->iosync -= p->out_dec;
+        p->notout = !(show_fields & 1) + !(show_fields & 3);
+        if (((show_fields &  3) ==  3 &&
+             (s->low.noise + s->interlaced_low < (s->num_blocks>>8) ||
+              s->sad.noise < 160)) ||
+            ((show_fields & 12) == 12 &&
+             (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,
+                                MP_IMGFLAG_PRESERVE|MP_IMGFLAG_READABLE,
+                                p->w, p->h);
+            if ((show_fields & 3) != 3) planes = old_planes;
+            dmpi->planes[0] = planes[0];
+            dmpi->stride[0] = p->stride;
+            dmpi->width = mpi->width;
+            if (mpi->flags & MP_IMGFLAG_PLANAR) {
+                dmpi->planes[1] = planes[1];
+                dmpi->planes[2] = planes[2];
+                dmpi->stride[1] = p->chroma_stride;
+                dmpi->stride[2] = p->chroma_stride;
+            }
+        } else {
+            p->merge_count++;
+            dmpi = 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);
+        }
+        p->outframes++;
+    } else
+        p->notout += 2;
+
+    if (p->verbose)
+        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),
+               p->num_breaks, 5*p->in_inc == p->out_dec && breaks<8 &&
+               breaks>0 && ((prev&~1)!=2 || prev+p->prev_fields!=5) ?
+               " ######## bad telecine ########" : "",
+               dropped_fields ? " ======== dropped ":"", ITOC(dropped_fields),
+               !show_fields || (show_fields & (show_fields-1)) ?
+               "" : " @@@@@@@@@@@@@@@@@");
+
+    p->merge_time += get_time() - diff_time;
+    return show_fields ? vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE) : 0;
+}
+
+static int query_format(struct vf_instance *vf, unsigned int fmt)
+{
+    /* FIXME - support more formats */
+    switch (fmt) {
+      case IMGFMT_YV12:
+      case IMGFMT_IYUV:
+      case IMGFMT_I420:
+      case IMGFMT_411P:
+      case IMGFMT_422P:
+      case IMGFMT_444P:
+        return vf_next_query_format(vf, fmt);
+    }
+    return 0;
+}
+
+static int config(struct vf_instance *vf,
+                  int width, int height, int d_width, int d_height,
+                  unsigned int flags, unsigned int outfmt)
+{
+    unsigned long cxm = 0;
+    unsigned long cym = 0;
+    struct vf_priv_s *p = vf->priv;
+    // rounding:
+    if(!IMGFMT_IS_RGB(outfmt) && !IMGFMT_IS_BGR(outfmt)){
+        switch(outfmt){
+          case IMGFMT_444P:
+          case IMGFMT_Y800:
+          case IMGFMT_Y8:
+            break;
+          case IMGFMT_YVU9:
+          case IMGFMT_IF09:
+            cym = 3;
+          case IMGFMT_411P:
+            cxm = 3;
+            break;
+          case IMGFMT_YV12:
+          case IMGFMT_I420:
+          case IMGFMT_IYUV:
+            cym = 1;
+          default:
+            cxm = 1;
+        }
+    }
+    p->chroma_swapped = !!(p->crop_y & (cym+1));
+    if (p->w) p->w += p->crop_x & cxm;
+    if (p->h) p->h += p->crop_y & cym;
+    p->crop_x &= ~cxm;
+    p->crop_y &= ~cym;
+    if (!p->w || p->w > width ) p->w = width;
+    if (!p->h || p->h > height) p->h = height;
+    if (p->crop_x + p->w > width ) p->crop_x = 0;
+    if (p->crop_y + p->h > height) p->crop_y = 0;
+
+    if(!opt_screen_size_x && !opt_screen_size_y){
+        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);
+}
+
+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, "
+           "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);
+    free(p);
+}
+
+static int vf_open(vf_instance_t *vf, char *args)
+{
+    struct vf_priv_s *p;
+    vf->get_image = get_image;
+    vf->put_image = put_image;
+    vf->config = config;
+    vf->query_format = query_format;
+    vf->uninit = uninit;
+    vf->default_reqs = VFCAP_ACCEPT_STRIDE;
+    vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
+    p->out_dec = 5;
+    p->in_inc = 4;
+    p->thres.noise = 128;
+    p->thres.even  = 128;
+    p->sad_thres = 64;
+    p->dint_thres = 4;
+    p->luma_only = 0;
+    p->fast = 3;
+    p->mmx2 = gCpuCaps.hasMMX2 ? 1 : gCpuCaps.has3DNow ? 2 : 0;
+    if (args) {
+        const char *args_remain = parse_args(p, args);
+        if (args_remain) {
+            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,
+                   "filmdint: increasing the frame rate is not supported\n");
+            return 0;
+        }
+    }
+    if (p->mmx2 > 2)
+        p->mmx2 = 0;
+#if !HAVE_MMX
+    p->mmx2 = 0;
+#endif
+#if !HAVE_AMD3DNOW
+    p->mmx2 &= 1;
+#endif
+    p->thres.odd  = p->thres.even;
+    p->thres.temp = p->thres.noise;
+    p->diff_time = 0;
+    p->merge_time = 0;
+    return 1;
+}
+
+const vf_info_t vf_info_filmdint = {
+    "Advanced inverse telecine filer",
+    "filmdint",
+    "Zoltan Hidvegi",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_fixpts.c b/libavfilter/libmpcodecs/vf_fixpts.c
new file mode 100644
index 0000000..ae32b40
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_fixpts.c
@@ -0,0 +1,137 @@
+/*
+ * 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 "help_mp.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+struct vf_priv_s {
+    double current;
+    double step;
+    int autostart;
+    int autostep;
+    unsigned have_step:1;
+    unsigned print:1;
+};
+
+static int put_image(vf_instance_t *vf, mp_image_t *src, double pts)
+{
+    struct vf_priv_s *p = vf->priv;
+
+    if (p->print) {
+        if (pts == MP_NOPTS_VALUE)
+            mp_msg(MSGT_VFILTER, MSGL_INFO, "PTS: undef\n");
+        else
+            mp_msg(MSGT_VFILTER, MSGL_INFO, "PTS: %f\n", pts);
+    }
+    if (pts != MP_NOPTS_VALUE && p->autostart != 0) {
+        p->current = pts;
+        if (p->autostart > 0)
+            p->autostart--;
+    } else if (pts != MP_NOPTS_VALUE && p->autostep > 0) {
+        p->step = pts - p->current;
+        p->current = pts;
+        p->autostep--;
+        p->have_step = 1;
+    } else if (p->have_step) {
+        p->current += p->step;
+        pts = p->current;
+    } else {
+        pts = MP_NOPTS_VALUE;
+    }
+    return vf_next_put_image(vf, src, pts);
+}
+
+static void uninit(vf_instance_t *vf)
+{
+    free(vf->priv);
+}
+
+static int parse_args(struct vf_priv_s *p, const char *args)
+{
+    int pos;
+    double num, denom = 1;
+    int iarg;
+
+    while (*args != 0) {
+        pos = 0;
+        if (sscanf(args, "print%n", &pos) == 0 && pos > 0) {
+            p->print = 1;
+        } else if (sscanf(args, "fps=%lf%n/%lf%n", &num, &pos, &denom, &pos) >=
+                   1 && pos > 0) {
+            p->step = denom / num;
+            p->have_step = 1;
+        } else if (sscanf(args, "start=%lf%n", &num, &pos) >= 1 && pos > 0) {
+            p->current = num;
+        } else if (sscanf(args, "autostart=%d%n", &iarg, &pos) == 1 && pos > 0) {
+            p->autostart = iarg;
+        } else if (sscanf(args, "autofps=%d%n", &iarg, &pos) == 1 && pos > 0) {
+            p->autostep = iarg;
+        } else {
+            mp_msg(MSGT_VFILTER, MSGL_FATAL,
+                   "fixpts: unknown suboption: %s\n", args);
+            return 0;
+        }
+        args += pos;
+        if (*args == ':')
+            args++;
+    }
+    return 1;
+}
+
+static int open(vf_instance_t *vf, char *args)
+{
+    struct vf_priv_s *p;
+    struct vf_priv_s ptmp = {
+        .current = 0,
+        .step = 0,
+        .autostart = 0,
+        .autostep = 0,
+        .have_step = 0,
+        .print = 0,
+    };
+
+    if (!parse_args(&ptmp, args == NULL ? "" : args))
+        return 0;
+
+    vf->put_image = put_image;
+    vf->uninit = uninit;
+    vf->priv = p = malloc(sizeof(struct vf_priv_s));
+    *p = ptmp;
+    p->current = -p->step;
+
+    return 1;
+}
+
+const vf_info_t vf_info_fixpts = {
+    "Fix presentation timestamps",
+    "fixpts",
+    "Nicolas George",
+    "",
+    &open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_fspp.c b/libavfilter/libmpcodecs/vf_fspp.c
new file mode 100644
index 0000000..3653187
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_fspp.c
@@ -0,0 +1,2117 @@
+/*
+ * Copyright (C) 2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2005 Nikolaj Poroshin <porosh3@psu.ru>
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ * This implementation is based on an algorithm described in
+ * "Aria Nosratinia Embedded Post-Processing for
+ * Enhancement of Compressed Images (1999)"
+ * (http://citeseer.nj.nec.com/nosratinia99embedded.html)
+ * Futher, with splitting (i)dct into hor/ver passes, one of them can be
+ * performed once per block, not pixel. This allows for much better speed.
+ */
+
+/*
+  Heavily optimized version of SPP filter by Nikolaj
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <math.h>
+
+#include "config.h"
+
+#include "mp_msg.h"
+#include "cpudetect.h"
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+#include "vd_ffmpeg.h"
+#include "libvo/fastmemcpy.h"
+
+#include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mem.h"
+#include "libavcodec/avcodec.h"
+#include "libavcodec/dsputil.h"
+
+#undef free
+#undef malloc
+
+//===========================================================================//
+#define BLOCKSZ 12
+
+static const short custom_threshold[64]=
+// values (296) can't be too high
+// -it causes too big quant dependence
+// or maybe overflow(check), which results in some flashing
+{ 71, 296, 295, 237,  71,  40,  38,  19,
+  245, 193, 185, 121, 102,  73,  53,  27,
+  158, 129, 141, 107,  97,  73,  50,  26,
+  102, 116, 109,  98,  82,  66,  45,  23,
+  71,  94,  95,  81,  70,  56,  38,  20,
+  56,  77,  74,  66,  56,  44,  30,  15,
+  38,  53,  50,  45,  38,  30,  21,  11,
+  20,  27,  26,  23,  20,  15,  11,   5
+};
+
+static const uint8_t  __attribute__((aligned(32))) dither[8][8]={
+    {  0,  48,  12,  60,   3,  51,  15,  63, },
+    { 32,  16,  44,  28,  35,  19,  47,  31, },
+    {  8,  56,   4,  52,  11,  59,   7,  55, },
+    { 40,  24,  36,  20,  43,  27,  39,  23, },
+    {  2,  50,  14,  62,   1,  49,  13,  61, },
+    { 34,  18,  46,  30,  33,  17,  45,  29, },
+    { 10,  58,   6,  54,   9,  57,   5,  53, },
+    { 42,  26,  38,  22,  41,  25,  37,  21, },
+};
+
+struct vf_priv_s { //align 16 !
+    uint64_t threshold_mtx_noq[8*2];
+    uint64_t threshold_mtx[8*2];//used in both C & MMX (& later SSE2) versions
+
+    int log2_count;
+    int temp_stride;
+    int qp;
+    int mpeg2;
+    int prev_q;
+    uint8_t *src;
+    int16_t *temp;
+    int bframes;
+    char *non_b_qp;
+};
+
+
+#if !HAVE_MMX
+
+//This func reads from 1 slice, 1 and clears 0 & 1
+static void store_slice_c(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale)
+{int y, x;
+#define STORE(pos)                                                        \
+    temp= (src[x + pos] + (d[pos]>>log2_scale))>>(6-log2_scale);        \
+    src[x + pos]=src[x + pos - 8*src_stride]=0;                                \
+    if(temp & 0x100) temp= ~(temp>>31);                                        \
+    dst[x + pos]= temp;
+
+    for(y=0; y<height; y++){
+        const uint8_t *d= dither[y];
+        for(x=0; x<width; x+=8){
+            int temp;
+            STORE(0);
+            STORE(1);
+            STORE(2);
+            STORE(3);
+            STORE(4);
+            STORE(5);
+            STORE(6);
+            STORE(7);
+        }
+        src+=src_stride;
+        dst+=dst_stride;
+    }
+}
+
+//This func reads from 2 slices, 0 & 2  and clears 2-nd
+static void store_slice2_c(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale)
+{int y, x;
+#define STORE2(pos)                                                        \
+    temp= (src[x + pos] + src[x + pos + 16*src_stride] + (d[pos]>>log2_scale))>>(6-log2_scale);        \
+    src[x + pos + 16*src_stride]=0;                                        \
+    if(temp & 0x100) temp= ~(temp>>31);                                        \
+    dst[x + pos]= temp;
+
+    for(y=0; y<height; y++){
+        const uint8_t *d= dither[y];
+        for(x=0; x<width; x+=8){
+            int temp;
+            STORE2(0);
+            STORE2(1);
+            STORE2(2);
+            STORE2(3);
+            STORE2(4);
+            STORE2(5);
+            STORE2(6);
+            STORE2(7);
+        }
+        src+=src_stride;
+        dst+=dst_stride;
+    }
+}
+
+static void mul_thrmat_c(struct vf_priv_s *p,int q)
+{
+    int a;
+    for(a=0;a<64;a++)
+        ((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,
+                       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);
+
+//this is rather ugly, but there is no need for function pointers
+#define store_slice_s store_slice_c
+#define store_slice2_s store_slice2_c
+#define mul_thrmat_s mul_thrmat_c
+#define column_fidct_s column_fidct_c
+#define row_idct_s row_idct_c
+#define row_fdct_s row_fdct_c
+
+#else /* HAVE_MMX */
+
+//This func reads from 1 slice, 1 and clears 0 & 1
+static void store_slice_mmx(uint8_t *dst, int16_t *src, long dst_stride, long src_stride, long width, long height, long log2_scale)
+{
+    const uint8_t *od=&dither[0][0];
+    const uint8_t *end=&dither[height][0];
+    width = (width+7)&~7;
+    dst_stride-=width;
+    //src_stride=(src_stride-width)*2;
+    __asm__ volatile(
+        "mov %5, %%"REG_d"                \n\t"
+        "mov %6, %%"REG_S"                \n\t"
+        "mov %7, %%"REG_D"                \n\t"
+        "mov %1, %%"REG_a"                \n\t"
+        "movd %%"REG_d", %%mm5             \n\t"
+        "xor $-1, %%"REG_d"              \n\t"
+        "mov %%"REG_a", %%"REG_c"             \n\t"
+        "add $7, %%"REG_d"               \n\t"
+        "neg %%"REG_a"                   \n\t"
+        "sub %0, %%"REG_c"            \n\t"
+        "add %%"REG_c", %%"REG_c"             \n\t"
+        "movd %%"REG_d", %%mm2             \n\t"
+        "mov %%"REG_c", %1       \n\t"
+        "mov %2, %%"REG_d"               \n\t"
+        "shl $4, %%"REG_a"               \n\t"
+
+        "2:                        \n\t"
+        "movq (%%"REG_d"), %%mm3           \n\t"
+        "movq %%mm3, %%mm4             \n\t"
+        "pxor %%mm7, %%mm7             \n\t"
+        "punpcklbw %%mm7, %%mm3        \n\t"
+        "punpckhbw %%mm7, %%mm4        \n\t"
+        "mov %0, %%"REG_c"            \n\t"
+        "psraw %%mm5, %%mm3            \n\t"
+        "psraw %%mm5, %%mm4            \n\t"
+        "1:                        \n\t"
+        "movq %%mm7, (%%"REG_S",%%"REG_a",)     \n\t"
+        "movq (%%"REG_S"), %%mm0           \n\t"
+        "movq 8(%%"REG_S"), %%mm1          \n\t"
+
+        "movq %%mm7, 8(%%"REG_S",%%"REG_a",)    \n\t"
+        "paddw %%mm3, %%mm0            \n\t"
+        "paddw %%mm4, %%mm1            \n\t"
+
+        "movq %%mm7, (%%"REG_S")           \n\t"
+        "psraw %%mm2, %%mm0            \n\t"
+        "psraw %%mm2, %%mm1            \n\t"
+
+        "movq %%mm7, 8(%%"REG_S")          \n\t"
+        "packuswb %%mm1, %%mm0         \n\t"
+        "add $16, %%"REG_S"              \n\t"
+
+        "movq %%mm0, (%%"REG_D")           \n\t"
+        "add $8, %%"REG_D"               \n\t"
+        "sub $8, %%"REG_c"               \n\t"
+        "jg 1b                      \n\t"
+        "add %1, %%"REG_S"       \n\t"
+        "add $8, %%"REG_d"               \n\t"
+        "add %3, %%"REG_D"       \n\t"
+        "cmp %4, %%"REG_d"           \n\t"
+        "jl 2b                      \n\t"
+
+        :
+        : "m" (width), "m" (src_stride), "erm" (od), "m" (dst_stride), "erm" (end),
+          "m" (log2_scale), "m" (src), "m" (dst) //input
+        : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D
+        );
+}
+
+//This func reads from 2 slices, 0 & 2  and clears 2-nd
+static void store_slice2_mmx(uint8_t *dst, int16_t *src, long dst_stride, long src_stride, long width, long height, long log2_scale)
+{
+    const uint8_t *od=&dither[0][0];
+    const uint8_t *end=&dither[height][0];
+    width = (width+7)&~7;
+    dst_stride-=width;
+    //src_stride=(src_stride-width)*2;
+    __asm__ volatile(
+        "mov %5, %%"REG_d"                \n\t"
+        "mov %6, %%"REG_S"                \n\t"
+        "mov %7, %%"REG_D"                \n\t"
+        "mov %1, %%"REG_a"            \n\t"
+        "movd %%"REG_d", %%mm5             \n\t"
+        "xor $-1, %%"REG_d"              \n\t"
+        "mov %%"REG_a", %%"REG_c"             \n\t"
+        "add $7, %%"REG_d"               \n\t"
+        "sub %0, %%"REG_c"            \n\t"
+        "add %%"REG_c", %%"REG_c"             \n\t"
+        "movd %%"REG_d", %%mm2             \n\t"
+        "mov %%"REG_c", %1       \n\t"
+        "mov %2, %%"REG_d"               \n\t"
+        "shl $5, %%"REG_a"               \n\t"
+
+        "2:                        \n\t"
+        "movq (%%"REG_d"), %%mm3           \n\t"
+        "movq %%mm3, %%mm4             \n\t"
+        "pxor %%mm7, %%mm7             \n\t"
+        "punpcklbw %%mm7, %%mm3        \n\t"
+        "punpckhbw %%mm7, %%mm4        \n\t"
+        "mov %0, %%"REG_c"            \n\t"
+        "psraw %%mm5, %%mm3            \n\t"
+        "psraw %%mm5, %%mm4            \n\t"
+        "1:                        \n\t"
+        "movq (%%"REG_S"), %%mm0           \n\t"
+        "movq 8(%%"REG_S"), %%mm1          \n\t"
+        "paddw %%mm3, %%mm0            \n\t"
+
+        "paddw (%%"REG_S",%%"REG_a",), %%mm0    \n\t"
+        "paddw %%mm4, %%mm1            \n\t"
+        "movq 8(%%"REG_S",%%"REG_a",), %%mm6    \n\t"
+
+        "movq %%mm7, (%%"REG_S",%%"REG_a",)     \n\t"
+        "psraw %%mm2, %%mm0            \n\t"
+        "paddw %%mm6, %%mm1            \n\t"
+
+        "movq %%mm7, 8(%%"REG_S",%%"REG_a",)    \n\t"
+        "psraw %%mm2, %%mm1            \n\t"
+        "packuswb %%mm1, %%mm0         \n\t"
+
+        "movq %%mm0, (%%"REG_D")           \n\t"
+        "add $16, %%"REG_S"              \n\t"
+        "add $8, %%"REG_D"               \n\t"
+        "sub $8, %%"REG_c"               \n\t"
+        "jg 1b                      \n\t"
+        "add %1, %%"REG_S"       \n\t"
+        "add $8, %%"REG_d"               \n\t"
+        "add %3, %%"REG_D"       \n\t"
+        "cmp %4, %%"REG_d"           \n\t"
+        "jl 2b                      \n\t"
+
+        :
+        : "m" (width), "m" (src_stride), "erm" (od), "m" (dst_stride), "erm" (end),
+          "m" (log2_scale), "m" (src), "m" (dst) //input
+        : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_D, "%"REG_S
+        );
+}
+
+static void mul_thrmat_mmx(struct vf_priv_s *p, int q)
+{
+    uint64_t *adr=&p->threshold_mtx_noq[0];
+    __asm__ volatile(
+        "movd %0, %%mm7                \n\t"
+        "add $8*8*2, %%"REG_D"            \n\t"
+        "movq 0*8(%%"REG_S"), %%mm0        \n\t"
+        "punpcklwd %%mm7, %%mm7        \n\t"
+        "movq 1*8(%%"REG_S"), %%mm1        \n\t"
+        "punpckldq %%mm7, %%mm7        \n\t"
+        "pmullw %%mm7, %%mm0           \n\t"
+
+        "movq 2*8(%%"REG_S"), %%mm2        \n\t"
+        "pmullw %%mm7, %%mm1           \n\t"
+
+        "movq 3*8(%%"REG_S"), %%mm3        \n\t"
+        "pmullw %%mm7, %%mm2           \n\t"
+
+        "movq %%mm0, 0*8(%%"REG_D")        \n\t"
+        "movq 4*8(%%"REG_S"), %%mm4        \n\t"
+        "pmullw %%mm7, %%mm3           \n\t"
+
+        "movq %%mm1, 1*8(%%"REG_D")        \n\t"
+        "movq 5*8(%%"REG_S"), %%mm5        \n\t"
+        "pmullw %%mm7, %%mm4           \n\t"
+
+        "movq %%mm2, 2*8(%%"REG_D")        \n\t"
+        "movq 6*8(%%"REG_S"), %%mm6        \n\t"
+        "pmullw %%mm7, %%mm5           \n\t"
+
+        "movq %%mm3, 3*8(%%"REG_D")        \n\t"
+        "movq 7*8+0*8(%%"REG_S"), %%mm0    \n\t"
+        "pmullw %%mm7, %%mm6           \n\t"
+
+        "movq %%mm4, 4*8(%%"REG_D")        \n\t"
+        "movq 7*8+1*8(%%"REG_S"), %%mm1    \n\t"
+        "pmullw %%mm7, %%mm0           \n\t"
+
+        "movq %%mm5, 5*8(%%"REG_D")        \n\t"
+        "movq 7*8+2*8(%%"REG_S"), %%mm2    \n\t"
+        "pmullw %%mm7, %%mm1           \n\t"
+
+        "movq %%mm6, 6*8(%%"REG_D")        \n\t"
+        "movq 7*8+3*8(%%"REG_S"), %%mm3    \n\t"
+        "pmullw %%mm7, %%mm2           \n\t"
+
+        "movq %%mm0, 7*8+0*8(%%"REG_D")    \n\t"
+        "movq 7*8+4*8(%%"REG_S"), %%mm4    \n\t"
+        "pmullw %%mm7, %%mm3           \n\t"
+
+        "movq %%mm1, 7*8+1*8(%%"REG_D")    \n\t"
+        "movq 7*8+5*8(%%"REG_S"), %%mm5    \n\t"
+        "pmullw %%mm7, %%mm4           \n\t"
+
+        "movq %%mm2, 7*8+2*8(%%"REG_D")    \n\t"
+        "movq 7*8+6*8(%%"REG_S"), %%mm6    \n\t"
+        "pmullw %%mm7, %%mm5           \n\t"
+
+        "movq %%mm3, 7*8+3*8(%%"REG_D")    \n\t"
+        "movq 14*8+0*8(%%"REG_S"), %%mm0   \n\t"
+        "pmullw %%mm7, %%mm6           \n\t"
+
+        "movq %%mm4, 7*8+4*8(%%"REG_D")    \n\t"
+        "movq 14*8+1*8(%%"REG_S"), %%mm1   \n\t"
+        "pmullw %%mm7, %%mm0           \n\t"
+
+        "movq %%mm5, 7*8+5*8(%%"REG_D")    \n\t"
+        "pmullw %%mm7, %%mm1           \n\t"
+
+        "movq %%mm6, 7*8+6*8(%%"REG_D")    \n\t"
+        "movq %%mm0, 14*8+0*8(%%"REG_D")   \n\t"
+        "movq %%mm1, 14*8+1*8(%%"REG_D")   \n\t"
+
+        : "+g" (q), "+S" (adr), "+D" (adr)
+        :
+        );
+}
+
+static void column_fidct_mmx(int16_t* thr_adr,  DCTELEM *data,  DCTELEM *output,  int cnt);
+static void row_idct_mmx(DCTELEM* 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);
+
+#define store_slice_s store_slice_mmx
+#define store_slice2_s store_slice2_mmx
+#define mul_thrmat_s mul_thrmat_mmx
+#define column_fidct_s column_fidct_mmx
+#define row_idct_s row_idct_mmx
+#define row_fdct_s row_fdct_mmx
+#endif // HAVE_MMX
+
+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, x0, y, es, qy, t;
+    const int stride= is_luma ? p->temp_stride : (width+16);//((width+16+15)&(~15))
+    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);
+
+    memset(block3, 0, 4*8*BLOCKSZ);
+
+    //p->src=src-src_stride*8-8;//!
+    if (!src || !dst) return; // HACK avoid crash for Y8 colourspace
+    for(y=0; y<height; y++){
+        int index= 8 + 8*stride + y*stride;
+        fast_memcpy(p->src + index, src + y*src_stride, width);//this line can be avoided by using DR & user fr.buffers
+        for(x=0; x<8; x++){
+            p->src[index         - x - 1]= p->src[index +         x    ];
+            p->src[index + width + x    ]= p->src[index + width - x - 1];
+        }
+    }
+    for(y=0; y<8; y++){
+        fast_memcpy(p->src + (      7-y)*stride, p->src + (      y+8)*stride, stride);
+        fast_memcpy(p->src + (height+8+y)*stride, p->src + (height-y+7)*stride, stride);
+    }
+    //FIXME (try edge emu)
+
+    for(y=8; y<24; y++)
+        memset(p->temp+ 8 +y*stride, 0,width*sizeof(int16_t));
+
+    for(y=step; y<height+8; y+=step){    //step= 1,2
+        qy=y-4;
+        if (qy>height-1) qy=height-1;
+        if (qy<0) qy=0;
+        qy=(qy>>qps)*qp_stride;
+        row_fdct_s(block, p->src + y*stride +2-(y&1), stride, 2);
+        for(x0=0; x0<width+8-8*(BLOCKSZ-1); x0+=8*(BLOCKSZ-1)){
+            row_fdct_s(block+8*8, p->src + y*stride+8+x0 +2-(y&1), stride, 2*(BLOCKSZ-1));
+            if(p->qp)
+                column_fidct_s((int16_t*)(&p->threshold_mtx[0]), block+0*8, block3+0*8, 8*(BLOCKSZ-1)); //yes, this is a HOTSPOT
+            else
+                for (x=0; x<8*(BLOCKSZ-1); x+=8) {
+                    t=x+x0-2; //correct t=x+x0-2-(y&1), but its the same
+                    if (t<0) t=0;//t always < width-2
+                    t=qp_store[qy+(t>>qps)];
+                    t=norm_qscale(t, p->mpeg2);
+                    if (t!=p->prev_q) p->prev_q=t, mul_thrmat_s(p, t);
+                    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));
+        }
+        //
+        es=width+8-x0; //  8, ...
+        if (es>8)
+            row_fdct_s(block+8*8, p->src + y*stride+8+x0 +2-(y&1), stride, (es-4)>>2);
+        column_fidct_s((int16_t*)(&p->threshold_mtx[0]), block, block3, es&(~1));
+        row_idct_s(block3+0*8, p->temp + (y&15)*stride+x0+2-(y&1), stride, es>>2);
+        {const int y1=y-8+step;//l5-7  l4-6
+            if (!(y1&7) && y1) {
+                if (y1&8) store_slice_s(dst + (y1-8)*dst_stride, p->temp+ 8 +8*stride,
+                                        dst_stride, stride, width, 8, 5-p->log2_count);
+                else store_slice2_s(dst + (y1-8)*dst_stride, p->temp+ 8 +0*stride,
+                                    dst_stride, stride, width, 8, 5-p->log2_count);
+            } }
+    }
+
+    if (y&7) {  // == height & 7
+        if (y&8) store_slice_s(dst + ((y-8)&~7)*dst_stride, p->temp+ 8 +8*stride,
+                               dst_stride, stride, width, y&7, 5-p->log2_count);
+        else store_slice2_s(dst + ((y-8)&~7)*dst_stride, p->temp+ 8 +0*stride,
+                            dst_stride, stride, width, y&7, 5-p->log2_count);
+    }
+}
+
+static int config(struct vf_instance *vf,
+                  int width, int height, int d_width, int d_height,
+                  unsigned int flags, unsigned int outfmt)
+{
+    int h= (height+16+15)&(~15);
+
+    vf->priv->temp_stride= (width+16+15)&(~15);
+    vf->priv->temp= (int16_t*)av_mallocz(vf->priv->temp_stride*3*8*sizeof(int16_t));
+    //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);
+}
+
+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,
+                          mpi->type, mpi->flags, mpi->width, mpi->height);
+    mpi->planes[0]=vf->dmpi->planes[0];
+    mpi->stride[0]=vf->dmpi->stride[0];
+    mpi->width=vf->dmpi->width;
+    if(mpi->flags&MP_IMGFLAG_PLANAR){
+        mpi->planes[1]=vf->dmpi->planes[1];
+        mpi->planes[2]=vf->dmpi->planes[2];
+        mpi->stride[1]=vf->dmpi->stride[1];
+        mpi->stride[2]=vf->dmpi->stride[2];
+    }
+    mpi->flags|=MP_IMGFLAG_DIRECT;
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+    mp_image_t *dmpi;
+    if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
+        // no DR, so get a new image! hope we'll get DR buffer:
+        dmpi=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);
+    }else{
+        dmpi=vf->dmpi;
+    }
+
+    vf->priv->mpeg2= mpi->qscale_type;
+    if(mpi->pict_type != 3 && mpi->qscale && !vf->priv->qp){
+        int w = mpi->qstride;
+        int h = (mpi->h + 15) >> 4;
+        if (!w) {
+            w = (mpi->w + 15) >> 4;
+            h = 1;
+        }
+        if(!vf->priv->non_b_qp)
+            vf->priv->non_b_qp= malloc(w*h);
+        fast_memcpy(vf->priv->non_b_qp, mpi->qscale, w*h);
+    }
+    if(vf->priv->log2_count || !(mpi->flags&MP_IMGFLAG_DIRECT)){
+        char *qp_tab= vf->priv->non_b_qp;
+        if(vf->priv->bframes || !qp_tab)
+            qp_tab= mpi->qscale;
+
+        if(qp_tab || vf->priv->qp){
+            filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0],
+                   mpi->w, mpi->h, qp_tab, mpi->qstride, 1);
+            filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1],
+                   mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, qp_tab, mpi->qstride, 0);
+            filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2],
+                   mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, qp_tab, mpi->qstride, 0);
+        }else{
+            memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]);
+            memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]);
+            memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]);
+        }
+    }
+
+#if HAVE_MMX
+    if(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)
+{
+    if(!vf->priv) return;
+
+    av_free(vf->priv->temp);
+    vf->priv->temp= NULL;
+    av_free(vf->priv->src);
+    vf->priv->src= NULL;
+    //free(vf->priv->avctx);
+    //vf->priv->avctx= NULL;
+    free(vf->priv->non_b_qp);
+    vf->priv->non_b_qp= NULL;
+
+    av_free(vf->priv);
+    vf->priv=NULL;
+}
+
+//===========================================================================//
+
+static int query_format(struct vf_instance *vf, unsigned int fmt)
+{
+    switch(fmt){
+    case IMGFMT_YVU9:
+    case IMGFMT_IF09:
+    case IMGFMT_YV12:
+    case IMGFMT_I420:
+    case IMGFMT_IYUV:
+    case IMGFMT_CLPL:
+    case IMGFMT_Y800:
+    case IMGFMT_Y8:
+    case IMGFMT_444P:
+    case IMGFMT_422P:
+    case IMGFMT_411P:
+        return 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 5;
+    case VFCTRL_SET_PP_LEVEL:
+        vf->priv->log2_count= *((unsigned int*)data);
+        if (vf->priv->log2_count < 4) vf->priv->log2_count=4;
+        return CONTROL_TRUE;
+    }
+    return vf_next_control(vf,request,data);
+}
+
+static int vf_open(vf_instance_t *vf, char *args)
+{
+    int i=0, bias;
+    int custom_threshold_m[64];
+    int log2c=-1;
+
+    vf->config=config;
+    vf->put_image=put_image;
+    vf->get_image=get_image;
+    vf->query_format=query_format;
+    vf->uninit=uninit;
+    vf->control= control;
+    vf->priv=av_mallocz(sizeof(struct vf_priv_s));//assumes align 16 !
+
+    init_avcodec();
+
+    //vf->priv->avctx= avcodec_alloc_context();
+    //dsputil_init(&vf->priv->dsp, vf->priv->avctx);
+
+    vf->priv->log2_count= 4;
+    vf->priv->bframes = 0;
+
+    if (args) sscanf(args, "%d:%d:%d:%d", &log2c, &vf->priv->qp, &i, &vf->priv->bframes);
+
+    if( log2c >=4 && log2c <=5 )
+        vf->priv->log2_count = log2c;
+    else if( log2c >= 6 )
+        vf->priv->log2_count = 5;
+
+    if(vf->priv->qp < 0)
+        vf->priv->qp = 0;
+
+    if (i < -15) i = -15;
+    if (i > 32) i = 32;
+
+    bias= (1<<4)+i; //regulable
+    vf->priv->prev_q=0;
+    //
+    for(i=0;i<64;i++) //FIXME: tune custom_threshold[] and remove this !
+        custom_threshold_m[i]=(int)(custom_threshold[i]*(bias/71.)+ 0.5);
+    for(i=0;i<8;i++){
+        vf->priv->threshold_mtx_noq[2*i]=(uint64_t)custom_threshold_m[i*8+2]
+            |(((uint64_t)custom_threshold_m[i*8+6])<<16)
+            |(((uint64_t)custom_threshold_m[i*8+0])<<32)
+            |(((uint64_t)custom_threshold_m[i*8+4])<<48);
+        vf->priv->threshold_mtx_noq[2*i+1]=(uint64_t)custom_threshold_m[i*8+5]
+            |(((uint64_t)custom_threshold_m[i*8+3])<<16)
+            |(((uint64_t)custom_threshold_m[i*8+1])<<32)
+            |(((uint64_t)custom_threshold_m[i*8+7])<<48);
+    }
+
+    if (vf->priv->qp) vf->priv->prev_q=vf->priv->qp, mul_thrmat_s(vf->priv, vf->priv->qp);
+
+    return 1;
+}
+
+const vf_info_t vf_info_fspp = {
+    "fast simple postprocess",
+    "fspp",
+    "Michael Niedermayer, Nikolaj Poroshin",
+    "",
+    vf_open,
+    NULL
+};
+
+//====================================================================
+//Specific spp's dct, idct and threshold functions
+//I'd prefer to have them in the separate file.
+
+//#define MANGLE(a) #a
+
+//typedef int16_t DCTELEM; //! only int16_t
+
+#define DCTSIZE 8
+#define DCTSIZE_S "8"
+
+#define FIX(x,s)  ((int) ((x) * (1<<s) + 0.5)&0xffff)
+#define C64(x)    ((uint64_t)((x)|(x)<<16))<<32 | (uint64_t)(x) | (uint64_t)(x)<<16
+#define FIX64(x,s)  C64(FIX(x,s))
+
+#define MULTIPLY16H(x,k)   (((x)*(k))>>16)
+#define THRESHOLD(r,x,t) if(((unsigned)((x)+t))>t*2) r=(x);else r=0;
+#define DESCALE(x,n)  (((x) + (1 << ((n)-1))) >> n)
+
+#if HAVE_MMX
+
+DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_382683433)=FIX64(0.382683433, 14);
+DECLARE_ALIGNED(8, uint64_t, ff_MM_FIX_0_541196100)=FIX64(0.541196100, 14);
+DECLARE_ALIGNED(8, uint64_t, ff_MM_FIX_0_707106781)=FIX64(0.707106781, 14);
+DECLARE_ASM_CONST(8, uint64_t, MM_FIX_1_306562965)=FIX64(1.306562965, 14);
+
+DECLARE_ASM_CONST(8, uint64_t, MM_FIX_1_414213562_A)=FIX64(1.414213562, 14);
+
+DECLARE_ASM_CONST(8, uint64_t, MM_FIX_1_847759065)=FIX64(1.847759065, 13);
+DECLARE_ASM_CONST(8, uint64_t, MM_FIX_2_613125930)=FIX64(-2.613125930, 13); //-
+DECLARE_ASM_CONST(8, uint64_t, MM_FIX_1_414213562)=FIX64(1.414213562, 13);
+DECLARE_ASM_CONST(8, uint64_t, MM_FIX_1_082392200)=FIX64(1.082392200, 13);
+//for t3,t5,t7 == 0 shortcut
+DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_847759065)=FIX64(0.847759065, 14);
+DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_566454497)=FIX64(0.566454497, 14);
+DECLARE_ASM_CONST(8, uint64_t, MM_FIX_0_198912367)=FIX64(0.198912367, 14);
+
+DECLARE_ASM_CONST(8, uint64_t, MM_DESCALE_RND)=C64(4);
+DECLARE_ASM_CONST(8, uint64_t, MM_2)=C64(2);
+
+#else /* !HAVE_MMX */
+
+typedef int32_t int_simd16_t;
+static const int16_t FIX_0_382683433=FIX(0.382683433, 14);
+static const int16_t FIX_0_541196100=FIX(0.541196100, 14);
+static const int16_t FIX_0_707106781=FIX(0.707106781, 14);
+static const int16_t FIX_1_306562965=FIX(1.306562965, 14);
+static const int16_t FIX_1_414213562_A=FIX(1.414213562, 14);
+static const int16_t FIX_1_847759065=FIX(1.847759065, 13);
+static const int16_t FIX_2_613125930=FIX(-2.613125930, 13); //-
+static const int16_t FIX_1_414213562=FIX(1.414213562, 13);
+static const int16_t FIX_1_082392200=FIX(1.082392200, 13);
+
+#endif
+
+#if !HAVE_MMX
+
+static void column_fidct_c(int16_t* thr_adr, DCTELEM *data, DCTELEM *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 *threshold;
+    int ctr;
+
+    dataptr = data;
+    wsptr = output;
+
+    for (; cnt > 0; cnt-=2) { //start positions
+        threshold=(int16_t*)thr_adr;//threshold_mtx
+        for (ctr = DCTSIZE; ctr > 0; ctr--) {
+            // Process columns from input, add to output.
+            tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
+            tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
+
+            tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
+            tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
+
+            tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
+            tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
+
+            tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
+            tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
+
+            // Even part of FDCT
+
+            tmp10 = tmp0 + tmp3;
+            tmp13 = tmp0 - tmp3;
+            tmp11 = tmp1 + tmp2;
+            tmp12 = tmp1 - tmp2;
+
+            d0 = tmp10 + tmp11;
+            d4 = tmp10 - tmp11;
+
+            z1 = MULTIPLY16H((tmp12 + tmp13) <<2, FIX_0_707106781);
+            d2 = tmp13 + z1;
+            d6 = tmp13 - z1;
+
+            // Even part of IDCT
+
+            THRESHOLD(tmp0, d0, threshold[0*8]);
+            THRESHOLD(tmp1, d2, threshold[2*8]);
+            THRESHOLD(tmp2, d4, threshold[4*8]);
+            THRESHOLD(tmp3, d6, threshold[6*8]);
+            tmp0+=2;
+            tmp10 = (tmp0 + tmp2)>>2;
+            tmp11 = (tmp0 - tmp2)>>2;
+
+            tmp13 = (tmp1 + tmp3)>>2; //+2 !  (psnr decides)
+            tmp12 = MULTIPLY16H((tmp1 - tmp3), FIX_1_414213562_A) - tmp13; //<<2
+
+            tmp0 = tmp10 + tmp13; //->temps
+            tmp3 = tmp10 - tmp13; //->temps
+            tmp1 = tmp11 + tmp12; //->temps
+            tmp2 = tmp11 - tmp12; //->temps
+
+            // Odd part of FDCT
+
+            tmp10 = tmp4 + tmp5;
+            tmp11 = tmp5 + tmp6;
+            tmp12 = tmp6 + tmp7;
+
+            z5 = MULTIPLY16H((tmp10 - tmp12)<<2, FIX_0_382683433);
+            z2 = MULTIPLY16H(tmp10 <<2, FIX_0_541196100) + z5;
+            z4 = MULTIPLY16H(tmp12 <<2, FIX_1_306562965) + z5;
+            z3 = MULTIPLY16H(tmp11 <<2, FIX_0_707106781);
+
+            z11 = tmp7 + z3;
+            z13 = tmp7 - z3;
+
+            d5 = z13 + z2;
+            d3 = z13 - z2;
+            d1 = z11 + z4;
+            d7 = z11 - z4;
+
+            // Odd part of IDCT
+
+            THRESHOLD(tmp4, d1, threshold[1*8]);
+            THRESHOLD(tmp5, d3, threshold[3*8]);
+            THRESHOLD(tmp6, d5, threshold[5*8]);
+            THRESHOLD(tmp7, d7, threshold[7*8]);
+
+            //Simd version uses here a shortcut for the tmp5,tmp6,tmp7 == 0
+            z13 = tmp6 + tmp5;
+            z10 = (tmp6 - tmp5)<<1;
+            z11 = tmp4 + tmp7;
+            z12 = (tmp4 - tmp7)<<1;
+
+            tmp7 = (z11 + z13)>>2; //+2 !
+            tmp11 = MULTIPLY16H((z11 - z13)<<1, FIX_1_414213562);
+            z5 =    MULTIPLY16H(z10 + z12, FIX_1_847759065);
+            tmp10 = MULTIPLY16H(z12, FIX_1_082392200) - z5;
+            tmp12 = MULTIPLY16H(z10, FIX_2_613125930) + z5; // - !!
+
+            tmp6 = tmp12 - tmp7;
+            tmp5 = tmp11 - tmp6;
+            tmp4 = tmp10 + tmp5;
+
+            wsptr[DCTSIZE*0]+=  (tmp0 + tmp7);
+            wsptr[DCTSIZE*1]+=  (tmp1 + tmp6);
+            wsptr[DCTSIZE*2]+=  (tmp2 + tmp5);
+            wsptr[DCTSIZE*3]+=  (tmp3 - tmp4);
+            wsptr[DCTSIZE*4]+=  (tmp3 + tmp4);
+            wsptr[DCTSIZE*5]+=  (tmp2 - tmp5);
+            wsptr[DCTSIZE*6]=  (tmp1 - tmp6);
+            wsptr[DCTSIZE*7]=  (tmp0 - tmp7);
+            //
+            dataptr++; //next column
+            wsptr++;
+            threshold++;
+        }
+        dataptr+=8; //skip each second start pos
+        wsptr  +=8;
+    }
+}
+
+#else /* HAVE_MMX */
+
+static void column_fidct_mmx(int16_t* thr_adr,  DCTELEM *data,  DCTELEM *output,  int cnt)
+{
+    uint64_t __attribute__((aligned(8))) temps[4];
+    __asm__ volatile(
+        ASMALIGN(4)
+        "1:                   \n\t"
+        "movq "DCTSIZE_S"*0*2(%%"REG_S"), %%mm1 \n\t"
+        //
+        "movq "DCTSIZE_S"*3*2(%%"REG_S"), %%mm7 \n\t"
+        "movq %%mm1, %%mm0             \n\t"
+
+        "paddw "DCTSIZE_S"*7*2(%%"REG_S"), %%mm1 \n\t" //t0
+        "movq %%mm7, %%mm3             \n\t"
+
+        "paddw "DCTSIZE_S"*4*2(%%"REG_S"), %%mm7 \n\t" //t3
+        "movq %%mm1, %%mm5             \n\t"
+
+        "movq "DCTSIZE_S"*1*2(%%"REG_S"), %%mm6 \n\t"
+        "psubw %%mm7, %%mm1            \n\t" //t13
+
+        "movq "DCTSIZE_S"*2*2(%%"REG_S"), %%mm2 \n\t"
+        "movq %%mm6, %%mm4             \n\t"
+
+        "paddw "DCTSIZE_S"*6*2(%%"REG_S"), %%mm6 \n\t" //t1
+        "paddw %%mm7, %%mm5            \n\t" //t10
+
+        "paddw "DCTSIZE_S"*5*2(%%"REG_S"), %%mm2 \n\t" //t2
+        "movq %%mm6, %%mm7             \n\t"
+
+        "paddw %%mm2, %%mm6            \n\t" //t11
+        "psubw %%mm2, %%mm7            \n\t" //t12
+
+        "movq %%mm5, %%mm2             \n\t"
+        "paddw %%mm6, %%mm5            \n\t" //d0
+        // i0 t13 t12 i3 i1 d0 - d4
+        "psubw %%mm6, %%mm2            \n\t" //d4
+        "paddw %%mm1, %%mm7            \n\t"
+
+        "movq  4*16(%%"REG_d"), %%mm6      \n\t"
+        "psllw $2, %%mm7              \n\t"
+
+        "psubw 0*16(%%"REG_d"), %%mm5      \n\t"
+        "psubw %%mm6, %%mm2            \n\t"
+
+        "paddusw 0*16(%%"REG_d"), %%mm5    \n\t"
+        "paddusw %%mm6, %%mm2          \n\t"
+
+        "pmulhw "MANGLE(ff_MM_FIX_0_707106781)", %%mm7 \n\t"
+        //
+        "paddw 0*16(%%"REG_d"), %%mm5      \n\t"
+        "paddw %%mm6, %%mm2            \n\t"
+
+        "psubusw 0*16(%%"REG_d"), %%mm5    \n\t"
+        "psubusw %%mm6, %%mm2          \n\t"
+
+//This func is totally compute-bound,  operates at huge speed. So,  DC shortcut
+// at this place isn't worthwhile due to BTB miss penalty (checked on Pent. 3).
+//However,  typical numbers: nondc - 29%%,  dc - 46%%,  zero - 25%%. All <> 0 case is very rare.
+        "paddw "MANGLE(MM_2)", %%mm5            \n\t"
+        "movq %%mm2, %%mm6             \n\t"
+
+        "paddw %%mm5, %%mm2            \n\t"
+        "psubw %%mm6, %%mm5            \n\t"
+
+        "movq %%mm1, %%mm6             \n\t"
+        "paddw %%mm7, %%mm1            \n\t" //d2
+
+        "psubw 2*16(%%"REG_d"), %%mm1      \n\t"
+        "psubw %%mm7, %%mm6            \n\t" //d6
+
+        "movq 6*16(%%"REG_d"), %%mm7       \n\t"
+        "psraw $2, %%mm5              \n\t"
+
+        "paddusw 2*16(%%"REG_d"), %%mm1    \n\t"
+        "psubw %%mm7, %%mm6            \n\t"
+        // t7 d2 /t11 t4 t6 - d6 /t10
+
+        "paddw 2*16(%%"REG_d"), %%mm1      \n\t"
+        "paddusw %%mm7, %%mm6          \n\t"
+
+        "psubusw 2*16(%%"REG_d"), %%mm1    \n\t"
+        "paddw %%mm7, %%mm6            \n\t"
+
+        "psubw "DCTSIZE_S"*4*2(%%"REG_S"), %%mm3 \n\t"
+        "psubusw %%mm7, %%mm6          \n\t"
+
+        //movq [edi+"DCTSIZE_S"*2*2], mm1
+        //movq [edi+"DCTSIZE_S"*6*2], mm6
+        "movq %%mm1, %%mm7             \n\t"
+        "psraw $2, %%mm2              \n\t"
+
+        "psubw "DCTSIZE_S"*6*2(%%"REG_S"), %%mm4 \n\t"
+        "psubw %%mm6, %%mm1            \n\t"
+
+        "psubw "DCTSIZE_S"*7*2(%%"REG_S"), %%mm0 \n\t"
+        "paddw %%mm7, %%mm6            \n\t" //'t13
+
+        "psraw $2, %%mm6              \n\t" //paddw mm6, MM_2 !!    ---
+        "movq %%mm2, %%mm7             \n\t"
+
+        "pmulhw "MANGLE(MM_FIX_1_414213562_A)", %%mm1 \n\t"
+        "paddw %%mm6, %%mm2            \n\t" //'t0
+
+        "movq %%mm2, 0*8+%3            \n\t" //!
+        "psubw %%mm6, %%mm7            \n\t" //'t3
+
+        "movq "DCTSIZE_S"*2*2(%%"REG_S"), %%mm2 \n\t"
+        "psubw %%mm6, %%mm1            \n\t" //'t12
+
+        "psubw "DCTSIZE_S"*5*2(%%"REG_S"), %%mm2 \n\t" //t5
+        "movq %%mm5, %%mm6             \n\t"
+
+        "movq %%mm7, 3*8+%3            \n\t"
+        "paddw %%mm2, %%mm3            \n\t" //t10
+
+        "paddw %%mm4, %%mm2            \n\t" //t11
+        "paddw %%mm0, %%mm4            \n\t" //t12
+
+        "movq %%mm3, %%mm7             \n\t"
+        "psubw %%mm4, %%mm3            \n\t"
+
+        "psllw $2, %%mm3              \n\t"
+        "psllw $2, %%mm7              \n\t" //opt for P6
+
+        "pmulhw "MANGLE(MM_FIX_0_382683433)", %%mm3 \n\t"
+        "psllw $2, %%mm4              \n\t"
+
+        "pmulhw "MANGLE(ff_MM_FIX_0_541196100)", %%mm7 \n\t"
+        "psllw $2, %%mm2              \n\t"
+
+        "pmulhw "MANGLE(MM_FIX_1_306562965)", %%mm4 \n\t"
+        "paddw %%mm1, %%mm5            \n\t" //'t1
+
+        "pmulhw "MANGLE(ff_MM_FIX_0_707106781)", %%mm2 \n\t"
+        "psubw %%mm1, %%mm6            \n\t" //'t2
+        // t7 't12 't11 t4 t6 - 't13 't10   ---
+
+        "paddw %%mm3, %%mm7            \n\t" //z2
+
+        "movq %%mm5, 1*8+%3            \n\t"
+        "paddw %%mm3, %%mm4            \n\t" //z4
+
+        "movq 3*16(%%"REG_d"), %%mm3       \n\t"
+        "movq %%mm0, %%mm1             \n\t"
+
+        "movq %%mm6, 2*8+%3            \n\t"
+        "psubw %%mm2, %%mm1            \n\t" //z13
+
+//===
+        "paddw %%mm2, %%mm0            \n\t" //z11
+        "movq %%mm1, %%mm5             \n\t"
+
+        "movq 5*16(%%"REG_d"), %%mm2       \n\t"
+        "psubw %%mm7, %%mm1            \n\t" //d3
+
+        "paddw %%mm7, %%mm5            \n\t" //d5
+        "psubw %%mm3, %%mm1            \n\t"
+
+        "movq 1*16(%%"REG_d"), %%mm7       \n\t"
+        "psubw %%mm2, %%mm5            \n\t"
+
+        "movq %%mm0, %%mm6             \n\t"
+        "paddw %%mm4, %%mm0            \n\t" //d1
+
+        "paddusw %%mm3, %%mm1          \n\t"
+        "psubw %%mm4, %%mm6            \n\t" //d7
+
+        // d1 d3 - - - d5 d7 -
+        "movq 7*16(%%"REG_d"), %%mm4       \n\t"
+        "psubw %%mm7, %%mm0            \n\t"
+
+        "psubw %%mm4, %%mm6            \n\t"
+        "paddusw %%mm2, %%mm5          \n\t"
+
+        "paddusw %%mm4, %%mm6          \n\t"
+        "paddw %%mm3, %%mm1            \n\t"
+
+        "paddw %%mm2, %%mm5            \n\t"
+        "paddw %%mm4, %%mm6            \n\t"
+
+        "psubusw %%mm3, %%mm1          \n\t"
+        "psubusw %%mm2, %%mm5          \n\t"
+
+        "psubusw %%mm4, %%mm6          \n\t"
+        "movq %%mm1, %%mm4             \n\t"
+
+        "por %%mm5, %%mm4              \n\t"
+        "paddusw %%mm7, %%mm0          \n\t"
+
+        "por %%mm6, %%mm4              \n\t"
+        "paddw %%mm7, %%mm0            \n\t"
+
+        "packssdw %%mm4, %%mm4         \n\t"
+        "psubusw %%mm7, %%mm0          \n\t"
+
+        "movd %%mm4, %%"REG_a"             \n\t"
+        "or %%"REG_a", %%"REG_a"              \n\t"
+        "jnz 2f                 \n\t"
+        //movq [edi+"DCTSIZE_S"*3*2], mm1
+        //movq [edi+"DCTSIZE_S"*5*2], mm5
+        //movq [edi+"DCTSIZE_S"*1*2], mm0
+        //movq [edi+"DCTSIZE_S"*7*2], mm6
+        // t4 t5 - - - t6 t7 -
+        //--- t4 (mm0) may be <>0; mm1, mm5, mm6 == 0
+//Typical numbers: nondc - 19%%,  dc - 26%%,  zero - 55%%. zero case alone isn't worthwhile
+        "movq 0*8+%3, %%mm4            \n\t"
+        "movq %%mm0, %%mm1             \n\t"
+
+        "pmulhw "MANGLE(MM_FIX_0_847759065)", %%mm0 \n\t" //tmp6
+        "movq %%mm1, %%mm2             \n\t"
+
+        "movq "DCTSIZE_S"*0*2(%%"REG_D"), %%mm5 \n\t"
+        "movq %%mm2, %%mm3             \n\t"
+
+        "pmulhw "MANGLE(MM_FIX_0_566454497)", %%mm1 \n\t" //tmp5
+        "paddw %%mm4, %%mm5            \n\t"
+
+        "movq 1*8+%3, %%mm6            \n\t"
+        //paddw mm3, MM_2
+        "psraw $2, %%mm3              \n\t" //tmp7
+
+        "pmulhw "MANGLE(MM_FIX_0_198912367)", %%mm2 \n\t" //-tmp4
+        "psubw %%mm3, %%mm4            \n\t"
+
+        "movq "DCTSIZE_S"*1*2(%%"REG_D"), %%mm7 \n\t"
+        "paddw %%mm3, %%mm5            \n\t"
+
+        "movq %%mm4, "DCTSIZE_S"*7*2(%%"REG_D") \n\t"
+        "paddw %%mm6, %%mm7            \n\t"
+
+        "movq 2*8+%3, %%mm3            \n\t"
+        "psubw %%mm0, %%mm6            \n\t"
+
+        "movq "DCTSIZE_S"*2*2(%%"REG_D"), %%mm4 \n\t"
+        "paddw %%mm0, %%mm7            \n\t"
+
+        "movq %%mm5, "DCTSIZE_S"*0*2(%%"REG_D") \n\t"
+        "paddw %%mm3, %%mm4            \n\t"
+
+        "movq %%mm6, "DCTSIZE_S"*6*2(%%"REG_D") \n\t"
+        "psubw %%mm1, %%mm3            \n\t"
+
+        "movq "DCTSIZE_S"*5*2(%%"REG_D"), %%mm5 \n\t"
+        "paddw %%mm1, %%mm4            \n\t"
+
+        "movq "DCTSIZE_S"*3*2(%%"REG_D"), %%mm6 \n\t"
+        "paddw %%mm3, %%mm5            \n\t"
+
+        "movq 3*8+%3, %%mm0            \n\t"
+        "add $8, %%"REG_S"               \n\t"
+
+        "movq %%mm7, "DCTSIZE_S"*1*2(%%"REG_D") \n\t"
+        "paddw %%mm0, %%mm6            \n\t"
+
+        "movq %%mm4, "DCTSIZE_S"*2*2(%%"REG_D") \n\t"
+        "psubw %%mm2, %%mm0            \n\t"
+
+        "movq "DCTSIZE_S"*4*2(%%"REG_D"), %%mm7 \n\t"
+        "paddw %%mm2, %%mm6            \n\t"
+
+        "movq %%mm5, "DCTSIZE_S"*5*2(%%"REG_D") \n\t"
+        "paddw %%mm0, %%mm7            \n\t"
+
+        "movq %%mm6, "DCTSIZE_S"*3*2(%%"REG_D") \n\t"
+
+        "movq %%mm7, "DCTSIZE_S"*4*2(%%"REG_D") \n\t"
+        "add $8, %%"REG_D"               \n\t"
+        "jmp 4f                  \n\t"
+
+        "2:                    \n\t"
+        //--- non DC2
+        //psraw mm1, 2 w/o it -> offset. thr1, thr1, thr1  (actually thr1, thr1, thr1-1)
+        //psraw mm5, 2
+        //psraw mm0, 2
+        //psraw mm6, 2
+        "movq %%mm5, %%mm3             \n\t"
+        "psubw %%mm1, %%mm5            \n\t"
+
+        "psllw $1, %%mm5              \n\t" //'z10
+        "paddw %%mm1, %%mm3            \n\t" //'z13
+
+        "movq %%mm0, %%mm2             \n\t"
+        "psubw %%mm6, %%mm0            \n\t"
+
+        "movq %%mm5, %%mm1             \n\t"
+        "psllw $1, %%mm0              \n\t" //'z12
+
+        "pmulhw "MANGLE(MM_FIX_2_613125930)", %%mm1 \n\t" //-
+        "paddw %%mm0, %%mm5            \n\t"
+
+        "pmulhw "MANGLE(MM_FIX_1_847759065)", %%mm5 \n\t" //'z5
+        "paddw %%mm6, %%mm2            \n\t" //'z11
+
+        "pmulhw "MANGLE(MM_FIX_1_082392200)", %%mm0 \n\t"
+        "movq %%mm2, %%mm7             \n\t"
+
+        //---
+        "movq 0*8+%3, %%mm4            \n\t"
+        "psubw %%mm3, %%mm2            \n\t"
+
+        "psllw $1, %%mm2              \n\t"
+        "paddw %%mm3, %%mm7            \n\t" //'t7
+
+        "pmulhw "MANGLE(MM_FIX_1_414213562)", %%mm2 \n\t" //'t11
+        "movq %%mm4, %%mm6             \n\t"
+        //paddw mm7, MM_2
+        "psraw $2, %%mm7              \n\t"
+
+        "paddw "DCTSIZE_S"*0*2(%%"REG_D"), %%mm4 \n\t"
+        "psubw %%mm7, %%mm6            \n\t"
+
+        "movq 1*8+%3, %%mm3            \n\t"
+        "paddw %%mm7, %%mm4            \n\t"
+
+        "movq %%mm6, "DCTSIZE_S"*7*2(%%"REG_D") \n\t"
+        "paddw %%mm5, %%mm1            \n\t" //'t12
+
+        "movq %%mm4, "DCTSIZE_S"*0*2(%%"REG_D") \n\t"
+        "psubw %%mm7, %%mm1            \n\t" //'t6
+
+        "movq 2*8+%3, %%mm7            \n\t"
+        "psubw %%mm5, %%mm0            \n\t" //'t10
+
+        "movq 3*8+%3, %%mm6            \n\t"
+        "movq %%mm3, %%mm5             \n\t"
+
+        "paddw "DCTSIZE_S"*1*2(%%"REG_D"), %%mm3 \n\t"
+        "psubw %%mm1, %%mm5            \n\t"
+
+        "psubw %%mm1, %%mm2            \n\t" //'t5
+        "paddw %%mm1, %%mm3            \n\t"
+
+        "movq %%mm5, "DCTSIZE_S"*6*2(%%"REG_D") \n\t"
+        "movq %%mm7, %%mm4             \n\t"
+
+        "paddw "DCTSIZE_S"*2*2(%%"REG_D"), %%mm7 \n\t"
+        "psubw %%mm2, %%mm4            \n\t"
+
+        "paddw "DCTSIZE_S"*5*2(%%"REG_D"), %%mm4 \n\t"
+        "paddw %%mm2, %%mm7            \n\t"
+
+        "movq %%mm3, "DCTSIZE_S"*1*2(%%"REG_D") \n\t"
+        "paddw %%mm2, %%mm0            \n\t" //'t4
+
+        // 't4 't6 't5 - - - - 't7
+        "movq %%mm7, "DCTSIZE_S"*2*2(%%"REG_D") \n\t"
+        "movq %%mm6, %%mm1             \n\t"
+
+        "paddw "DCTSIZE_S"*4*2(%%"REG_D"), %%mm6 \n\t"
+        "psubw %%mm0, %%mm1            \n\t"
+
+        "paddw "DCTSIZE_S"*3*2(%%"REG_D"), %%mm1 \n\t"
+        "paddw %%mm0, %%mm6            \n\t"
+
+        "movq %%mm4, "DCTSIZE_S"*5*2(%%"REG_D") \n\t"
+        "add $8, %%"REG_S"               \n\t"
+
+        "movq %%mm6, "DCTSIZE_S"*4*2(%%"REG_D") \n\t"
+
+        "movq %%mm1, "DCTSIZE_S"*3*2(%%"REG_D") \n\t"
+        "add $8, %%"REG_D"               \n\t"
+
+        "4:                     \n\t"
+//=part 2 (the same)===========================================================
+        "movq "DCTSIZE_S"*0*2(%%"REG_S"), %%mm1 \n\t"
+        //
+        "movq "DCTSIZE_S"*3*2(%%"REG_S"), %%mm7 \n\t"
+        "movq %%mm1, %%mm0             \n\t"
+
+        "paddw "DCTSIZE_S"*7*2(%%"REG_S"), %%mm1 \n\t" //t0
+        "movq %%mm7, %%mm3             \n\t"
+
+        "paddw "DCTSIZE_S"*4*2(%%"REG_S"), %%mm7 \n\t" //t3
+        "movq %%mm1, %%mm5             \n\t"
+
+        "movq "DCTSIZE_S"*1*2(%%"REG_S"), %%mm6 \n\t"
+        "psubw %%mm7, %%mm1            \n\t" //t13
+
+        "movq "DCTSIZE_S"*2*2(%%"REG_S"), %%mm2 \n\t"
+        "movq %%mm6, %%mm4             \n\t"
+
+        "paddw "DCTSIZE_S"*6*2(%%"REG_S"), %%mm6 \n\t" //t1
+        "paddw %%mm7, %%mm5            \n\t" //t10
+
+        "paddw "DCTSIZE_S"*5*2(%%"REG_S"), %%mm2 \n\t" //t2
+        "movq %%mm6, %%mm7             \n\t"
+
+        "paddw %%mm2, %%mm6            \n\t" //t11
+        "psubw %%mm2, %%mm7            \n\t" //t12
+
+        "movq %%mm5, %%mm2             \n\t"
+        "paddw %%mm6, %%mm5            \n\t" //d0
+        // i0 t13 t12 i3 i1 d0 - d4
+        "psubw %%mm6, %%mm2            \n\t" //d4
+        "paddw %%mm1, %%mm7            \n\t"
+
+        "movq  1*8+4*16(%%"REG_d"), %%mm6  \n\t"
+        "psllw $2, %%mm7              \n\t"
+
+        "psubw 1*8+0*16(%%"REG_d"), %%mm5  \n\t"
+        "psubw %%mm6, %%mm2            \n\t"
+
+        "paddusw 1*8+0*16(%%"REG_d"), %%mm5 \n\t"
+        "paddusw %%mm6, %%mm2          \n\t"
+
+        "pmulhw "MANGLE(ff_MM_FIX_0_707106781)", %%mm7 \n\t"
+        //
+        "paddw 1*8+0*16(%%"REG_d"), %%mm5  \n\t"
+        "paddw %%mm6, %%mm2            \n\t"
+
+        "psubusw 1*8+0*16(%%"REG_d"), %%mm5 \n\t"
+        "psubusw %%mm6, %%mm2          \n\t"
+
+//This func is totally compute-bound,  operates at huge speed. So,  DC shortcut
+// at this place isn't worthwhile due to BTB miss penalty (checked on Pent. 3).
+//However,  typical numbers: nondc - 29%%,  dc - 46%%,  zero - 25%%. All <> 0 case is very rare.
+        "paddw "MANGLE(MM_2)", %%mm5            \n\t"
+        "movq %%mm2, %%mm6             \n\t"
+
+        "paddw %%mm5, %%mm2            \n\t"
+        "psubw %%mm6, %%mm5            \n\t"
+
+        "movq %%mm1, %%mm6             \n\t"
+        "paddw %%mm7, %%mm1            \n\t" //d2
+
+        "psubw 1*8+2*16(%%"REG_d"), %%mm1  \n\t"
+        "psubw %%mm7, %%mm6            \n\t" //d6
+
+        "movq 1*8+6*16(%%"REG_d"), %%mm7   \n\t"
+        "psraw $2, %%mm5              \n\t"
+
+        "paddusw 1*8+2*16(%%"REG_d"), %%mm1 \n\t"
+        "psubw %%mm7, %%mm6            \n\t"
+        // t7 d2 /t11 t4 t6 - d6 /t10
+
+        "paddw 1*8+2*16(%%"REG_d"), %%mm1  \n\t"
+        "paddusw %%mm7, %%mm6          \n\t"
+
+        "psubusw 1*8+2*16(%%"REG_d"), %%mm1 \n\t"
+        "paddw %%mm7, %%mm6            \n\t"
+
+        "psubw "DCTSIZE_S"*4*2(%%"REG_S"), %%mm3 \n\t"
+        "psubusw %%mm7, %%mm6          \n\t"
+
+        //movq [edi+"DCTSIZE_S"*2*2], mm1
+        //movq [edi+"DCTSIZE_S"*6*2], mm6
+        "movq %%mm1, %%mm7             \n\t"
+        "psraw $2, %%mm2              \n\t"
+
+        "psubw "DCTSIZE_S"*6*2(%%"REG_S"), %%mm4 \n\t"
+        "psubw %%mm6, %%mm1            \n\t"
+
+        "psubw "DCTSIZE_S"*7*2(%%"REG_S"), %%mm0 \n\t"
+        "paddw %%mm7, %%mm6            \n\t" //'t13
+
+        "psraw $2, %%mm6              \n\t" //paddw mm6, MM_2 !!    ---
+        "movq %%mm2, %%mm7             \n\t"
+
+        "pmulhw "MANGLE(MM_FIX_1_414213562_A)", %%mm1 \n\t"
+        "paddw %%mm6, %%mm2            \n\t" //'t0
+
+        "movq %%mm2, 0*8+%3            \n\t" //!
+        "psubw %%mm6, %%mm7            \n\t" //'t3
+
+        "movq "DCTSIZE_S"*2*2(%%"REG_S"), %%mm2 \n\t"
+        "psubw %%mm6, %%mm1            \n\t" //'t12
+
+        "psubw "DCTSIZE_S"*5*2(%%"REG_S"), %%mm2 \n\t" //t5
+        "movq %%mm5, %%mm6             \n\t"
+
+        "movq %%mm7, 3*8+%3            \n\t"
+        "paddw %%mm2, %%mm3            \n\t" //t10
+
+        "paddw %%mm4, %%mm2            \n\t" //t11
+        "paddw %%mm0, %%mm4            \n\t" //t12
+
+        "movq %%mm3, %%mm7             \n\t"
+        "psubw %%mm4, %%mm3            \n\t"
+
+        "psllw $2, %%mm3              \n\t"
+        "psllw $2, %%mm7              \n\t" //opt for P6
+
+        "pmulhw "MANGLE(MM_FIX_0_382683433)", %%mm3 \n\t"
+        "psllw $2, %%mm4              \n\t"
+
+        "pmulhw "MANGLE(ff_MM_FIX_0_541196100)", %%mm7 \n\t"
+        "psllw $2, %%mm2              \n\t"
+
+        "pmulhw "MANGLE(MM_FIX_1_306562965)", %%mm4 \n\t"
+        "paddw %%mm1, %%mm5            \n\t" //'t1
+
+        "pmulhw "MANGLE(ff_MM_FIX_0_707106781)", %%mm2 \n\t"
+        "psubw %%mm1, %%mm6            \n\t" //'t2
+        // t7 't12 't11 t4 t6 - 't13 't10   ---
+
+        "paddw %%mm3, %%mm7            \n\t" //z2
+
+        "movq %%mm5, 1*8+%3            \n\t"
+        "paddw %%mm3, %%mm4            \n\t" //z4
+
+        "movq 1*8+3*16(%%"REG_d"), %%mm3   \n\t"
+        "movq %%mm0, %%mm1             \n\t"
+
+        "movq %%mm6, 2*8+%3            \n\t"
+        "psubw %%mm2, %%mm1            \n\t" //z13
+
+//===
+        "paddw %%mm2, %%mm0            \n\t" //z11
+        "movq %%mm1, %%mm5             \n\t"
+
+        "movq 1*8+5*16(%%"REG_d"), %%mm2   \n\t"
+        "psubw %%mm7, %%mm1            \n\t" //d3
+
+        "paddw %%mm7, %%mm5            \n\t" //d5
+        "psubw %%mm3, %%mm1            \n\t"
+
+        "movq 1*8+1*16(%%"REG_d"), %%mm7   \n\t"
+        "psubw %%mm2, %%mm5            \n\t"
+
+        "movq %%mm0, %%mm6             \n\t"
+        "paddw %%mm4, %%mm0            \n\t" //d1
+
+        "paddusw %%mm3, %%mm1          \n\t"
+        "psubw %%mm4, %%mm6            \n\t" //d7
+
+        // d1 d3 - - - d5 d7 -
+        "movq 1*8+7*16(%%"REG_d"), %%mm4   \n\t"
+        "psubw %%mm7, %%mm0            \n\t"
+
+        "psubw %%mm4, %%mm6            \n\t"
+        "paddusw %%mm2, %%mm5          \n\t"
+
+        "paddusw %%mm4, %%mm6          \n\t"
+        "paddw %%mm3, %%mm1            \n\t"
+
+        "paddw %%mm2, %%mm5            \n\t"
+        "paddw %%mm4, %%mm6            \n\t"
+
+        "psubusw %%mm3, %%mm1          \n\t"
+        "psubusw %%mm2, %%mm5          \n\t"
+
+        "psubusw %%mm4, %%mm6          \n\t"
+        "movq %%mm1, %%mm4             \n\t"
+
+        "por %%mm5, %%mm4              \n\t"
+        "paddusw %%mm7, %%mm0          \n\t"
+
+        "por %%mm6, %%mm4              \n\t"
+        "paddw %%mm7, %%mm0            \n\t"
+
+        "packssdw %%mm4, %%mm4         \n\t"
+        "psubusw %%mm7, %%mm0          \n\t"
+
+        "movd %%mm4, %%"REG_a"             \n\t"
+        "or %%"REG_a", %%"REG_a"              \n\t"
+        "jnz 3f                 \n\t"
+        //movq [edi+"DCTSIZE_S"*3*2], mm1
+        //movq [edi+"DCTSIZE_S"*5*2], mm5
+        //movq [edi+"DCTSIZE_S"*1*2], mm0
+        //movq [edi+"DCTSIZE_S"*7*2], mm6
+        // t4 t5 - - - t6 t7 -
+        //--- t4 (mm0) may be <>0; mm1, mm5, mm6 == 0
+//Typical numbers: nondc - 19%%,  dc - 26%%,  zero - 55%%. zero case alone isn't worthwhile
+        "movq 0*8+%3, %%mm4            \n\t"
+        "movq %%mm0, %%mm1             \n\t"
+
+        "pmulhw "MANGLE(MM_FIX_0_847759065)", %%mm0 \n\t" //tmp6
+        "movq %%mm1, %%mm2             \n\t"
+
+        "movq "DCTSIZE_S"*0*2(%%"REG_D"), %%mm5 \n\t"
+        "movq %%mm2, %%mm3             \n\t"
+
+        "pmulhw "MANGLE(MM_FIX_0_566454497)", %%mm1 \n\t" //tmp5
+        "paddw %%mm4, %%mm5            \n\t"
+
+        "movq 1*8+%3, %%mm6            \n\t"
+        //paddw mm3, MM_2
+        "psraw $2, %%mm3              \n\t" //tmp7
+
+        "pmulhw "MANGLE(MM_FIX_0_198912367)", %%mm2 \n\t" //-tmp4
+        "psubw %%mm3, %%mm4            \n\t"
+
+        "movq "DCTSIZE_S"*1*2(%%"REG_D"), %%mm7 \n\t"
+        "paddw %%mm3, %%mm5            \n\t"
+
+        "movq %%mm4, "DCTSIZE_S"*7*2(%%"REG_D") \n\t"
+        "paddw %%mm6, %%mm7            \n\t"
+
+        "movq 2*8+%3, %%mm3            \n\t"
+        "psubw %%mm0, %%mm6            \n\t"
+
+        "movq "DCTSIZE_S"*2*2(%%"REG_D"), %%mm4 \n\t"
+        "paddw %%mm0, %%mm7            \n\t"
+
+        "movq %%mm5, "DCTSIZE_S"*0*2(%%"REG_D") \n\t"
+        "paddw %%mm3, %%mm4            \n\t"
+
+        "movq %%mm6, "DCTSIZE_S"*6*2(%%"REG_D") \n\t"
+        "psubw %%mm1, %%mm3            \n\t"
+
+        "movq "DCTSIZE_S"*5*2(%%"REG_D"), %%mm5 \n\t"
+        "paddw %%mm1, %%mm4            \n\t"
+
+        "movq "DCTSIZE_S"*3*2(%%"REG_D"), %%mm6 \n\t"
+        "paddw %%mm3, %%mm5            \n\t"
+
+        "movq 3*8+%3, %%mm0            \n\t"
+        "add $24, %%"REG_S"              \n\t"
+
+        "movq %%mm7, "DCTSIZE_S"*1*2(%%"REG_D") \n\t"
+        "paddw %%mm0, %%mm6            \n\t"
+
+        "movq %%mm4, "DCTSIZE_S"*2*2(%%"REG_D") \n\t"
+        "psubw %%mm2, %%mm0            \n\t"
+
+        "movq "DCTSIZE_S"*4*2(%%"REG_D"), %%mm7 \n\t"
+        "paddw %%mm2, %%mm6            \n\t"
+
+        "movq %%mm5, "DCTSIZE_S"*5*2(%%"REG_D") \n\t"
+        "paddw %%mm0, %%mm7            \n\t"
+
+        "movq %%mm6, "DCTSIZE_S"*3*2(%%"REG_D") \n\t"
+
+        "movq %%mm7, "DCTSIZE_S"*4*2(%%"REG_D") \n\t"
+        "add $24, %%"REG_D"              \n\t"
+        "sub $2, %%"REG_c"               \n\t"
+        "jnz 1b                \n\t"
+        "jmp 5f                   \n\t"
+
+        "3:                    \n\t"
+        //--- non DC2
+        //psraw mm1, 2 w/o it -> offset. thr1, thr1, thr1  (actually thr1, thr1, thr1-1)
+        //psraw mm5, 2
+        //psraw mm0, 2
+        //psraw mm6, 2
+        "movq %%mm5, %%mm3             \n\t"
+        "psubw %%mm1, %%mm5            \n\t"
+
+        "psllw $1, %%mm5              \n\t" //'z10
+        "paddw %%mm1, %%mm3            \n\t" //'z13
+
+        "movq %%mm0, %%mm2             \n\t"
+        "psubw %%mm6, %%mm0            \n\t"
+
+        "movq %%mm5, %%mm1             \n\t"
+        "psllw $1, %%mm0              \n\t" //'z12
+
+        "pmulhw "MANGLE(MM_FIX_2_613125930)", %%mm1 \n\t" //-
+        "paddw %%mm0, %%mm5            \n\t"
+
+        "pmulhw "MANGLE(MM_FIX_1_847759065)", %%mm5 \n\t" //'z5
+        "paddw %%mm6, %%mm2            \n\t" //'z11
+
+        "pmulhw "MANGLE(MM_FIX_1_082392200)", %%mm0 \n\t"
+        "movq %%mm2, %%mm7             \n\t"
+
+        //---
+        "movq 0*8+%3, %%mm4            \n\t"
+        "psubw %%mm3, %%mm2            \n\t"
+
+        "psllw $1, %%mm2              \n\t"
+        "paddw %%mm3, %%mm7            \n\t" //'t7
+
+        "pmulhw "MANGLE(MM_FIX_1_414213562)", %%mm2 \n\t" //'t11
+        "movq %%mm4, %%mm6             \n\t"
+        //paddw mm7, MM_2
+        "psraw $2, %%mm7              \n\t"
+
+        "paddw "DCTSIZE_S"*0*2(%%"REG_D"), %%mm4 \n\t"
+        "psubw %%mm7, %%mm6            \n\t"
+
+        "movq 1*8+%3, %%mm3            \n\t"
+        "paddw %%mm7, %%mm4            \n\t"
+
+        "movq %%mm6, "DCTSIZE_S"*7*2(%%"REG_D") \n\t"
+        "paddw %%mm5, %%mm1            \n\t" //'t12
+
+        "movq %%mm4, "DCTSIZE_S"*0*2(%%"REG_D") \n\t"
+        "psubw %%mm7, %%mm1            \n\t" //'t6
+
+        "movq 2*8+%3, %%mm7            \n\t"
+        "psubw %%mm5, %%mm0            \n\t" //'t10
+
+        "movq 3*8+%3, %%mm6            \n\t"
+        "movq %%mm3, %%mm5             \n\t"
+
+        "paddw "DCTSIZE_S"*1*2(%%"REG_D"), %%mm3 \n\t"
+        "psubw %%mm1, %%mm5            \n\t"
+
+        "psubw %%mm1, %%mm2            \n\t" //'t5
+        "paddw %%mm1, %%mm3            \n\t"
+
+        "movq %%mm5, "DCTSIZE_S"*6*2(%%"REG_D") \n\t"
+        "movq %%mm7, %%mm4             \n\t"
+
+        "paddw "DCTSIZE_S"*2*2(%%"REG_D"), %%mm7 \n\t"
+        "psubw %%mm2, %%mm4            \n\t"
+
+        "paddw "DCTSIZE_S"*5*2(%%"REG_D"), %%mm4 \n\t"
+        "paddw %%mm2, %%mm7            \n\t"
+
+        "movq %%mm3, "DCTSIZE_S"*1*2(%%"REG_D") \n\t"
+        "paddw %%mm2, %%mm0            \n\t" //'t4
+
+        // 't4 't6 't5 - - - - 't7
+        "movq %%mm7, "DCTSIZE_S"*2*2(%%"REG_D") \n\t"
+        "movq %%mm6, %%mm1             \n\t"
+
+        "paddw "DCTSIZE_S"*4*2(%%"REG_D"), %%mm6 \n\t"
+        "psubw %%mm0, %%mm1            \n\t"
+
+        "paddw "DCTSIZE_S"*3*2(%%"REG_D"), %%mm1 \n\t"
+        "paddw %%mm0, %%mm6            \n\t"
+
+        "movq %%mm4, "DCTSIZE_S"*5*2(%%"REG_D") \n\t"
+        "add $24, %%"REG_S"              \n\t"
+
+        "movq %%mm6, "DCTSIZE_S"*4*2(%%"REG_D") \n\t"
+
+        "movq %%mm1, "DCTSIZE_S"*3*2(%%"REG_D") \n\t"
+        "add $24, %%"REG_D"              \n\t"
+        "sub $2, %%"REG_c"               \n\t"
+        "jnz 1b                \n\t"
+        "5:                      \n\t"
+
+        : "+S"(data), "+D"(output), "+c"(cnt), "=o"(temps)
+        : "d"(thr_adr)
+        : "%"REG_a
+        );
+}
+
+#endif // HAVE_MMX
+
+#if !HAVE_MMX
+
+static void row_idct_c(DCTELEM* 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;
+
+    cnt*=4;
+    wsptr = workspace;
+    outptr = output_adr;
+    for (; cnt > 0; cnt--) {
+        // Even part
+        //Simd version reads 4x4 block and transposes it
+        tmp10 = ( wsptr[2] +  wsptr[3]);
+        tmp11 = ( wsptr[2] -  wsptr[3]);
+
+        tmp13 = ( wsptr[0] +  wsptr[1]);
+        tmp12 = (MULTIPLY16H( wsptr[0] - wsptr[1], FIX_1_414213562_A)<<2) - tmp13;//this shift order to avoid overflow
+
+        tmp0 = tmp10 + tmp13; //->temps
+        tmp3 = tmp10 - tmp13; //->temps
+        tmp1 = tmp11 + tmp12;
+        tmp2 = tmp11 - tmp12;
+
+        // Odd part
+        //Also transpose, with previous:
+        // ---- ----      ||||
+        // ---- ---- idct ||||
+        // ---- ---- ---> ||||
+        // ---- ----      ||||
+        z13 = wsptr[4] + wsptr[5];
+        z10 = wsptr[4] - wsptr[5];
+        z11 = wsptr[6] + wsptr[7];
+        z12 = wsptr[6] - wsptr[7];
+
+        tmp7 = z11 + z13;
+        tmp11 = MULTIPLY16H(z11 - z13, FIX_1_414213562);
+
+        z5 =    MULTIPLY16H(z10 + z12, FIX_1_847759065);
+        tmp10 = MULTIPLY16H(z12, FIX_1_082392200) - z5;
+        tmp12 = MULTIPLY16H(z10, FIX_2_613125930) + z5; // - FIX_
+
+        tmp6 = (tmp12<<3) - tmp7;
+        tmp5 = (tmp11<<3) - tmp6;
+        tmp4 = (tmp10<<3) + tmp5;
+
+        // Final output stage: descale and write column
+        outptr[0*output_stride]+= DESCALE(tmp0 + tmp7, 3);
+        outptr[1*output_stride]+= DESCALE(tmp1 + tmp6, 3);
+        outptr[2*output_stride]+= DESCALE(tmp2 + tmp5, 3);
+        outptr[3*output_stride]+= DESCALE(tmp3 - tmp4, 3);
+        outptr[4*output_stride]+= DESCALE(tmp3 + tmp4, 3);
+        outptr[5*output_stride]+= DESCALE(tmp2 - tmp5, 3);
+        outptr[6*output_stride]+= DESCALE(tmp1 - tmp6, 3); //no += ?
+        outptr[7*output_stride]+= DESCALE(tmp0 - tmp7, 3); //no += ?
+        outptr++;
+
+        wsptr += DCTSIZE;       // advance pointer to next row
+    }
+}
+
+#else /* HAVE_MMX */
+
+static void row_idct_mmx (DCTELEM* workspace,
+                          int16_t* output_adr,  int output_stride,  int cnt)
+{
+    uint64_t __attribute__((aligned(8))) temps[4];
+    __asm__ volatile(
+        "lea (%%"REG_a",%%"REG_a",2), %%"REG_d"    \n\t"
+        "1:                     \n\t"
+        "movq "DCTSIZE_S"*0*2(%%"REG_S"), %%mm0 \n\t"
+        //
+
+        "movq "DCTSIZE_S"*1*2(%%"REG_S"), %%mm1 \n\t"
+        "movq %%mm0, %%mm4             \n\t"
+
+        "movq "DCTSIZE_S"*2*2(%%"REG_S"), %%mm2 \n\t"
+        "punpcklwd %%mm1, %%mm0        \n\t"
+
+        "movq "DCTSIZE_S"*3*2(%%"REG_S"), %%mm3 \n\t"
+        "punpckhwd %%mm1, %%mm4        \n\t"
+
+        //transpose 4x4
+        "movq %%mm2, %%mm7             \n\t"
+        "punpcklwd %%mm3, %%mm2        \n\t"
+
+        "movq %%mm0, %%mm6             \n\t"
+        "punpckldq %%mm2, %%mm0        \n\t" //0
+
+        "punpckhdq %%mm2, %%mm6        \n\t" //1
+        "movq %%mm0, %%mm5             \n\t"
+
+        "punpckhwd %%mm3, %%mm7        \n\t"
+        "psubw %%mm6, %%mm0            \n\t"
+
+        "pmulhw "MANGLE(MM_FIX_1_414213562_A)", %%mm0 \n\t"
+        "movq %%mm4, %%mm2             \n\t"
+
+        "punpckldq %%mm7, %%mm4        \n\t" //2
+        "paddw %%mm6, %%mm5            \n\t"
+
+        "punpckhdq %%mm7, %%mm2        \n\t" //3
+        "movq %%mm4, %%mm1             \n\t"
+
+        "psllw $2, %%mm0              \n\t"
+        "paddw %%mm2, %%mm4            \n\t" //t10
+
+        "movq "DCTSIZE_S"*0*2+"DCTSIZE_S"(%%"REG_S"), %%mm3 \n\t"
+        "psubw %%mm2, %%mm1            \n\t" //t11
+
+        "movq "DCTSIZE_S"*1*2+"DCTSIZE_S"(%%"REG_S"), %%mm2 \n\t"
+        "psubw %%mm5, %%mm0            \n\t"
+
+        "movq %%mm4, %%mm6             \n\t"
+        "paddw %%mm5, %%mm4            \n\t" //t0
+
+        "psubw %%mm5, %%mm6            \n\t" //t3
+        "movq %%mm1, %%mm7             \n\t"
+
+        "movq "DCTSIZE_S"*2*2+"DCTSIZE_S"(%%"REG_S"), %%mm5 \n\t"
+        "paddw %%mm0, %%mm1            \n\t" //t1
+
+        "movq %%mm4, 0*8+%3            \n\t" //t0
+        "movq %%mm3, %%mm4             \n\t"
+
+        "movq %%mm6, 1*8+%3            \n\t" //t3
+        "punpcklwd %%mm2, %%mm3        \n\t"
+
+        //transpose 4x4
+        "movq "DCTSIZE_S"*3*2+"DCTSIZE_S"(%%"REG_S"), %%mm6 \n\t"
+        "punpckhwd %%mm2, %%mm4        \n\t"
+
+        "movq %%mm5, %%mm2             \n\t"
+        "punpcklwd %%mm6, %%mm5        \n\t"
+
+        "psubw %%mm0, %%mm7            \n\t" //t2
+        "punpckhwd %%mm6, %%mm2        \n\t"
+
+        "movq %%mm3, %%mm0             \n\t"
+        "punpckldq %%mm5, %%mm3        \n\t" //4
+
+        "punpckhdq %%mm5, %%mm0        \n\t" //5
+        "movq %%mm4, %%mm5             \n\t"
+
+        //
+        "movq %%mm3, %%mm6             \n\t"
+        "punpckldq %%mm2, %%mm4        \n\t" //6
+
+        "psubw %%mm0, %%mm3            \n\t" //z10
+        "punpckhdq %%mm2, %%mm5        \n\t" //7
+
+        "paddw %%mm0, %%mm6            \n\t" //z13
+        "movq %%mm4, %%mm2             \n\t"
+
+        "movq %%mm3, %%mm0             \n\t"
+        "psubw %%mm5, %%mm4            \n\t" //z12
+
+        "pmulhw "MANGLE(MM_FIX_2_613125930)", %%mm0 \n\t" //-
+        "paddw %%mm4, %%mm3            \n\t"
+
+        "pmulhw "MANGLE(MM_FIX_1_847759065)", %%mm3 \n\t" //z5
+        "paddw %%mm5, %%mm2            \n\t" //z11  >
+
+        "pmulhw "MANGLE(MM_FIX_1_082392200)", %%mm4 \n\t"
+        "movq %%mm2, %%mm5             \n\t"
+
+        "psubw %%mm6, %%mm2            \n\t"
+        "paddw %%mm6, %%mm5            \n\t" //t7
+
+        "pmulhw "MANGLE(MM_FIX_1_414213562)", %%mm2 \n\t" //t11
+        "paddw %%mm3, %%mm0            \n\t" //t12
+
+        "psllw $3, %%mm0              \n\t"
+        "psubw %%mm3, %%mm4            \n\t" //t10
+
+        "movq 0*8+%3, %%mm6            \n\t"
+        "movq %%mm1, %%mm3             \n\t"
+
+        "psllw $3, %%mm4              \n\t"
+        "psubw %%mm5, %%mm0            \n\t" //t6
+
+        "psllw $3, %%mm2              \n\t"
+        "paddw %%mm0, %%mm1            \n\t" //d1
+
+        "psubw %%mm0, %%mm2            \n\t" //t5
+        "psubw %%mm0, %%mm3            \n\t" //d6
+
+        "paddw %%mm2, %%mm4            \n\t" //t4
+        "movq %%mm7, %%mm0             \n\t"
+
+        "paddw %%mm2, %%mm7            \n\t" //d2
+        "psubw %%mm2, %%mm0            \n\t" //d5
+
+        "movq "MANGLE(MM_DESCALE_RND)", %%mm2   \n\t" //4
+        "psubw %%mm5, %%mm6            \n\t" //d7
+
+        "paddw 0*8+%3, %%mm5           \n\t" //d0
+        "paddw %%mm2, %%mm1            \n\t"
+
+        "paddw %%mm2, %%mm5            \n\t"
+        "psraw $3, %%mm1              \n\t"
+
+        "paddw %%mm2, %%mm7            \n\t"
+        "psraw $3, %%mm5              \n\t"
+
+        "paddw (%%"REG_D"), %%mm5          \n\t"
+        "psraw $3, %%mm7              \n\t"
+
+        "paddw (%%"REG_D",%%"REG_a",), %%mm1    \n\t"
+        "paddw %%mm2, %%mm0            \n\t"
+
+        "paddw (%%"REG_D",%%"REG_a",2), %%mm7   \n\t"
+        "paddw %%mm2, %%mm3            \n\t"
+
+        "movq %%mm5, (%%"REG_D")           \n\t"
+        "paddw %%mm2, %%mm6            \n\t"
+
+        "movq %%mm1, (%%"REG_D",%%"REG_a",)     \n\t"
+        "psraw $3, %%mm0              \n\t"
+
+        "movq %%mm7, (%%"REG_D",%%"REG_a",2)    \n\t"
+        "add %%"REG_d", %%"REG_D"             \n\t" //3*ls
+
+        "movq 1*8+%3, %%mm5           \n\t" //t3
+        "psraw $3, %%mm3              \n\t"
+
+        "paddw (%%"REG_D",%%"REG_a",2), %%mm0   \n\t"
+        "psubw %%mm4, %%mm5            \n\t" //d3
+
+        "paddw (%%"REG_D",%%"REG_d",), %%mm3    \n\t"
+        "psraw $3, %%mm6              \n\t"
+
+        "paddw 1*8+%3, %%mm4           \n\t" //d4
+        "paddw %%mm2, %%mm5            \n\t"
+
+        "paddw (%%"REG_D",%%"REG_a",4), %%mm6   \n\t"
+        "paddw %%mm2, %%mm4            \n\t"
+
+        "movq %%mm0, (%%"REG_D",%%"REG_a",2)    \n\t"
+        "psraw $3, %%mm5              \n\t"
+
+        "paddw (%%"REG_D"), %%mm5          \n\t"
+        "psraw $3, %%mm4              \n\t"
+
+        "paddw (%%"REG_D",%%"REG_a",), %%mm4    \n\t"
+        "add $"DCTSIZE_S"*2*4, %%"REG_S"      \n\t" //4 rows
+
+        "movq %%mm3, (%%"REG_D",%%"REG_d",)     \n\t"
+        "movq %%mm6, (%%"REG_D",%%"REG_a",4)    \n\t"
+        "movq %%mm5, (%%"REG_D")           \n\t"
+        "movq %%mm4, (%%"REG_D",%%"REG_a",)     \n\t"
+
+        "sub %%"REG_d", %%"REG_D"             \n\t"
+        "add $8, %%"REG_D"               \n\t"
+        "dec %%"REG_c"                   \n\t"
+        "jnz 1b                  \n\t"
+
+        : "+S"(workspace), "+D"(output_adr), "+c"(cnt), "=o"(temps)
+        : "a"(output_stride*sizeof(short))
+        : "%"REG_d
+        );
+}
+
+#endif // HAVE_MMX
+
+#if !HAVE_MMX
+
+static void row_fdct_c(DCTELEM *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;
+
+    cnt*=4;
+    // Pass 1: process rows.
+
+    dataptr = data;
+    for (; cnt > 0; cnt--) {
+        tmp0 = pixels[line_size*0] + pixels[line_size*7];
+        tmp7 = pixels[line_size*0] - pixels[line_size*7];
+        tmp1 = pixels[line_size*1] + pixels[line_size*6];
+        tmp6 = pixels[line_size*1] - pixels[line_size*6];
+        tmp2 = pixels[line_size*2] + pixels[line_size*5];
+        tmp5 = pixels[line_size*2] - pixels[line_size*5];
+        tmp3 = pixels[line_size*3] + pixels[line_size*4];
+        tmp4 = pixels[line_size*3] - pixels[line_size*4];
+
+        // Even part
+
+        tmp10 = tmp0 + tmp3;
+        tmp13 = tmp0 - tmp3;
+        tmp11 = tmp1 + tmp2;
+        tmp12 = tmp1 - tmp2;
+        //Even columns are written first, this leads to different order of columns
+        //in column_fidct(), but they are processed independently, so all ok.
+        //Later in the row_idct() columns readed at the same order.
+        dataptr[2] = tmp10 + tmp11;
+        dataptr[3] = tmp10 - tmp11;
+
+        z1 = MULTIPLY16H((tmp12 + tmp13)<<2, FIX_0_707106781);
+        dataptr[0] = tmp13 + z1;
+        dataptr[1] = tmp13 - z1;
+
+        // Odd part
+
+        tmp10 = (tmp4 + tmp5) <<2;
+        tmp11 = (tmp5 + tmp6) <<2;
+        tmp12 = (tmp6 + tmp7) <<2;
+
+        z5 = MULTIPLY16H(tmp10 - tmp12, FIX_0_382683433);
+        z2 = MULTIPLY16H(tmp10, FIX_0_541196100) + z5;
+        z4 = MULTIPLY16H(tmp12, FIX_1_306562965) + z5;
+        z3 = MULTIPLY16H(tmp11, FIX_0_707106781);
+
+        z11 = tmp7 + z3;
+        z13 = tmp7 - z3;
+
+        dataptr[4] = z13 + z2;
+        dataptr[5] = z13 - z2;
+        dataptr[6] = z11 + z4;
+        dataptr[7] = z11 - z4;
+
+        pixels++;               // advance pointer to next column
+        dataptr += DCTSIZE;
+    }
+}
+
+#else /* HAVE_MMX */
+
+static void row_fdct_mmx(DCTELEM *data,  const uint8_t *pixels,  int line_size,  int cnt)
+{
+    uint64_t __attribute__((aligned(8))) temps[4];
+    __asm__ volatile(
+        "lea (%%"REG_a",%%"REG_a",2), %%"REG_d"    \n\t"
+        "6:                     \n\t"
+        "movd (%%"REG_S"), %%mm0           \n\t"
+        "pxor %%mm7, %%mm7             \n\t"
+
+        "movd (%%"REG_S",%%"REG_a",), %%mm1     \n\t"
+        "punpcklbw %%mm7, %%mm0        \n\t"
+
+        "movd (%%"REG_S",%%"REG_a",2), %%mm2    \n\t"
+        "punpcklbw %%mm7, %%mm1        \n\t"
+
+        "punpcklbw %%mm7, %%mm2        \n\t"
+        "add %%"REG_d", %%"REG_S"             \n\t"
+
+        "movq %%mm0, %%mm5             \n\t"
+        //
+
+        "movd (%%"REG_S",%%"REG_a",4), %%mm3    \n\t" //7  ;prefetch!
+        "movq %%mm1, %%mm6             \n\t"
+
+        "movd (%%"REG_S",%%"REG_d",), %%mm4     \n\t" //6
+        "punpcklbw %%mm7, %%mm3        \n\t"
+
+        "psubw %%mm3, %%mm5            \n\t"
+        "punpcklbw %%mm7, %%mm4        \n\t"
+
+        "paddw %%mm3, %%mm0            \n\t"
+        "psubw %%mm4, %%mm6            \n\t"
+
+        "movd (%%"REG_S",%%"REG_a",2), %%mm3    \n\t" //5
+        "paddw %%mm4, %%mm1            \n\t"
+
+        "movq %%mm5, 0*8+%3            \n\t" //t7
+        "punpcklbw %%mm7, %%mm3        \n\t"
+
+        "movq %%mm6, 1*8+%3            \n\t" //t6
+        "movq %%mm2, %%mm4             \n\t"
+
+        "movd (%%"REG_S"), %%mm5           \n\t" //3
+        "paddw %%mm3, %%mm2            \n\t"
+
+        "movd (%%"REG_S",%%"REG_a",), %%mm6     \n\t" //4
+        "punpcklbw %%mm7, %%mm5        \n\t"
+
+        "psubw %%mm3, %%mm4            \n\t"
+        "punpcklbw %%mm7, %%mm6        \n\t"
+
+        "movq %%mm5, %%mm3             \n\t"
+        "paddw %%mm6, %%mm5            \n\t" //t3
+
+        "psubw %%mm6, %%mm3            \n\t" //t4  ; t0 t1 t2 t4 t5 t3 - -
+        "movq %%mm0, %%mm6             \n\t"
+
+        "movq %%mm1, %%mm7             \n\t"
+        "psubw %%mm5, %%mm0            \n\t" //t13
+
+        "psubw %%mm2, %%mm1            \n\t"
+        "paddw %%mm2, %%mm7            \n\t" //t11
+
+        "paddw %%mm0, %%mm1            \n\t"
+        "movq %%mm7, %%mm2             \n\t"
+
+        "psllw $2, %%mm1              \n\t"
+        "paddw %%mm5, %%mm6            \n\t" //t10
+
+        "pmulhw "MANGLE(ff_MM_FIX_0_707106781)", %%mm1 \n\t"
+        "paddw %%mm6, %%mm7            \n\t" //d2
+
+        "psubw %%mm2, %%mm6            \n\t" //d3
+        "movq %%mm0, %%mm5             \n\t"
+
+        //transpose 4x4
+        "movq %%mm7, %%mm2             \n\t"
+        "punpcklwd %%mm6, %%mm7        \n\t"
+
+        "paddw %%mm1, %%mm0            \n\t" //d0
+        "punpckhwd %%mm6, %%mm2        \n\t"
+
+        "psubw %%mm1, %%mm5            \n\t" //d1
+        "movq %%mm0, %%mm6             \n\t"
+
+        "movq 1*8+%3, %%mm1            \n\t"
+        "punpcklwd %%mm5, %%mm0        \n\t"
+
+        "punpckhwd %%mm5, %%mm6        \n\t"
+        "movq %%mm0, %%mm5             \n\t"
+
+        "punpckldq %%mm7, %%mm0        \n\t" //0
+        "paddw %%mm4, %%mm3            \n\t"
+
+        "punpckhdq %%mm7, %%mm5        \n\t" //1
+        "movq %%mm6, %%mm7             \n\t"
+
+        "movq %%mm0, "DCTSIZE_S"*0*2(%%"REG_D") \n\t"
+        "punpckldq %%mm2, %%mm6        \n\t" //2
+
+        "movq %%mm5, "DCTSIZE_S"*1*2(%%"REG_D") \n\t"
+        "punpckhdq %%mm2, %%mm7        \n\t" //3
+
+        "movq %%mm6, "DCTSIZE_S"*2*2(%%"REG_D") \n\t"
+        "paddw %%mm1, %%mm4            \n\t"
+
+        "movq %%mm7, "DCTSIZE_S"*3*2(%%"REG_D") \n\t"
+        "psllw $2, %%mm3              \n\t" //t10
+
+        "movq 0*8+%3, %%mm2           \n\t"
+        "psllw $2, %%mm4              \n\t" //t11
+
+        "pmulhw "MANGLE(ff_MM_FIX_0_707106781)", %%mm4 \n\t" //z3
+        "paddw %%mm2, %%mm1            \n\t"
+
+        "psllw $2, %%mm1              \n\t" //t12
+        "movq %%mm3, %%mm0             \n\t"
+
+        "pmulhw "MANGLE(ff_MM_FIX_0_541196100)", %%mm0 \n\t"
+        "psubw %%mm1, %%mm3            \n\t"
+
+        "pmulhw "MANGLE(MM_FIX_0_382683433)", %%mm3 \n\t" //z5
+        "movq %%mm2, %%mm5             \n\t"
+
+        "pmulhw "MANGLE(MM_FIX_1_306562965)", %%mm1 \n\t"
+        "psubw %%mm4, %%mm2            \n\t" //z13
+
+        "paddw %%mm4, %%mm5            \n\t" //z11
+        "movq %%mm2, %%mm6             \n\t"
+
+        "paddw %%mm3, %%mm0            \n\t" //z2
+        "movq %%mm5, %%mm7             \n\t"
+
+        "paddw %%mm0, %%mm2            \n\t" //d4
+        "psubw %%mm0, %%mm6            \n\t" //d5
+
+        "movq %%mm2, %%mm4             \n\t"
+        "paddw %%mm3, %%mm1            \n\t" //z4
+
+        //transpose 4x4
+        "punpcklwd %%mm6, %%mm2        \n\t"
+        "paddw %%mm1, %%mm5            \n\t" //d6
+
+        "punpckhwd %%mm6, %%mm4        \n\t"
+        "psubw %%mm1, %%mm7            \n\t" //d7
+
+        "movq %%mm5, %%mm6             \n\t"
+        "punpcklwd %%mm7, %%mm5        \n\t"
+
+        "punpckhwd %%mm7, %%mm6        \n\t"
+        "movq %%mm2, %%mm7             \n\t"
+
+        "punpckldq %%mm5, %%mm2        \n\t" //4
+        "sub %%"REG_d", %%"REG_S"             \n\t"
+
+        "punpckhdq %%mm5, %%mm7        \n\t" //5
+        "movq %%mm4, %%mm5             \n\t"
+
+        "movq %%mm2, "DCTSIZE_S"*0*2+"DCTSIZE_S"(%%"REG_D") \n\t"
+        "punpckldq %%mm6, %%mm4        \n\t" //6
+
+        "movq %%mm7, "DCTSIZE_S"*1*2+"DCTSIZE_S"(%%"REG_D") \n\t"
+        "punpckhdq %%mm6, %%mm5        \n\t" //7
+
+        "movq %%mm4, "DCTSIZE_S"*2*2+"DCTSIZE_S"(%%"REG_D") \n\t"
+        "add $4, %%"REG_S"               \n\t"
+
+        "movq %%mm5, "DCTSIZE_S"*3*2+"DCTSIZE_S"(%%"REG_D") \n\t"
+        "add $"DCTSIZE_S"*2*4, %%"REG_D"      \n\t" //4 rows
+        "dec %%"REG_c"                   \n\t"
+        "jnz 6b                  \n\t"
+
+        : "+S"(pixels), "+D"(data), "+c"(cnt), "=o"(temps)
+        : "a"(line_size)
+        : "%"REG_d);
+}
+
+#endif // HAVE_MMX
diff --git a/libavfilter/libmpcodecs/vf_geq.c b/libavfilter/libmpcodecs/vf_geq.c
new file mode 100644
index 0000000..22f2938
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_geq.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <inttypes.h>
+
+#include "config.h"
+
+#include "mp_msg.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "libavcodec/avcodec.h"
+#include "libavutil/eval.h"
+
+struct vf_priv_s {
+    AVExpr * e[3];
+    int framenum;
+    mp_image_t *mpi;
+};
+
+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 inline double getpix(struct vf_instance *vf, double x, double y, int plane){
+    int xi, yi;
+    mp_image_t *mpi= vf->priv->mpi;
+    int stride= mpi->stride[plane];
+    uint8_t *src=  mpi->planes[plane];
+    xi=x= FFMIN(FFMAX(x, 0), (mpi->w >> (plane ? mpi->chroma_x_shift : 0))-1);
+    yi=y= FFMIN(FFMAX(y, 0), (mpi->h >> (plane ? mpi->chroma_y_shift : 0))-1);
+
+    x-=xi;
+    y-=yi;
+
+    return
+     (1-y)*((1-x)*src[xi +  yi    * stride] + x*src[xi + 1 +  yi    * stride])
+    +   y *((1-x)*src[xi + (yi+1) * stride] + x*src[xi + 1 + (yi+1) * stride]);
+}
+
+//FIXME cubic interpolate
+//FIXME keep the last few frames
+static double lum(void *vf, double x, double y){
+    return getpix(vf, x, y, 0);
+}
+
+static double cb(void *vf, double x, double y){
+    return getpix(vf, x, y, 1);
+}
+
+static double cr(void *vf, double x, double y){
+    return getpix(vf, x, y, 2);
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+    mp_image_t *dmpi;
+    int x,y, plane;
+
+    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,
+                              mpi->w,mpi->h);
+    }
+
+    dmpi= vf->dmpi;
+    vf->priv->mpi= mpi;
+
+    vf_clone_mpi_attributes(dmpi, mpi);
+
+    for(plane=0; plane<3; plane++){
+        int w= mpi->w >> (plane ? mpi->chroma_x_shift : 0);
+        int h= mpi->h >> (plane ? mpi->chroma_y_shift : 0);
+        uint8_t *dst  = dmpi->planes[plane];
+        int dst_stride= dmpi->stride[plane];
+        double const_values[]={
+            M_PI,
+            M_E,
+            0,
+            0,
+            w,
+            h,
+            vf->priv->framenum,
+            w/(double)mpi->w,
+            h/(double)mpi->h,
+            0
+        };
+        if (!vf->priv->e[plane]) continue;
+        for(y=0; y<h; y++){
+            const_values[3]=y;
+            for(x=0; x<w; x++){
+                const_values[2]=x;
+                dst[x + y * dst_stride] = av_expr_eval(vf->priv->e[plane],
+                                                       const_values, vf);
+            }
+        }
+    }
+
+    vf->priv->framenum++;
+
+    return vf_next_put_image(vf,dmpi, pts);
+}
+
+static void uninit(struct vf_instance *vf){
+    av_free(vf->priv);
+    vf->priv=NULL;
+}
+
+//===========================================================================//
+static int vf_open(vf_instance_t *vf, char *args){
+    char eq[3][2000] = { { 0 }, { 0 }, { 0 } };
+    int plane, res;
+
+    vf->config=config;
+    vf->put_image=put_image;
+//    vf->get_image=get_image;
+    vf->uninit=uninit;
+    vf->priv=av_malloc(sizeof(struct vf_priv_s));
+    memset(vf->priv, 0, sizeof(struct vf_priv_s));
+
+    if (args) sscanf(args, "%1999[^:]:%1999[^:]:%1999[^:]", eq[0], eq[1], eq[2]);
+
+    if (!eq[1][0]) strncpy(eq[1], eq[0], sizeof(eq[0])-1);
+    if (!eq[2][0]) strncpy(eq[2], eq[1], sizeof(eq[0])-1);
+
+    for(plane=0; plane<3; plane++){
+        static const char *const_names[]={
+            "PI",
+            "E",
+            "X",
+            "Y",
+            "W",
+            "H",
+            "N",
+            "SW",
+            "SH",
+            NULL
+        };
+        static const char *func2_names[]={
+            "lum",
+            "cb",
+            "cr",
+            "p",
+            NULL
+        };
+        double (*func2[])(void *, double, double)={
+            lum,
+            cb,
+            cr,
+            plane==0 ? lum : (plane==1 ? cb : cr),
+            NULL
+        };
+        res = av_expr_parse(&vf->priv->e[plane], eq[plane], const_names, NULL, NULL, func2_names, func2, 0, NULL);
+
+        if (res < 0) {
+            mp_msg(MSGT_VFILTER, MSGL_ERR, "geq: error loading equation `%s'\n", eq[plane]);
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+const vf_info_t vf_info_geq = {
+    "generic equation filter",
+    "geq",
+    "Michael Niedermayer",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_harddup.c b/libavfilter/libmpcodecs/vf_harddup.c
new file mode 100644
index 0000000..5b6c2ff
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_harddup.c
@@ -0,0 +1,92 @@
+/*
+ * 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 {
+    mp_image_t *last_mpi;
+};
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+    mp_image_t *dmpi;
+
+    vf->priv->last_mpi = mpi;
+
+    dmpi = vf_get_image(vf->next, mpi->imgfmt,
+        MP_IMGTYPE_EXPORT, 0, mpi->width, mpi->height);
+
+    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_DUPLICATE_FRAME:
+        if (!vf->priv->last_mpi) break;
+        // This is a huge hack. We assume nothing
+        // has been called earlier in the filter chain
+        // since the last put_image. This is reasonable
+        // because we're handling a duplicate frame!
+        if (put_image(vf, vf->priv->last_mpi, MP_NOPTS_VALUE))
+            return CONTROL_TRUE;
+        break;
+    }
+    return vf_next_control(vf, request, data);
+}
+
+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_harddup = {
+    "resubmit duplicate frames for encoding",
+    "harddup",
+    "Rich Felker",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_hqdn3d.c b/libavfilter/libmpcodecs/vf_hqdn3d.c
new file mode 100644
index 0000000..eba3439
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_hqdn3d.c
@@ -0,0 +1,373 @@
+/*
+ * 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*16];
+        unsigned int *Line;
+        unsigned short *Frame[3];
+};
+
+
+/***************************************************************************/
+
+static void uninit(struct vf_instance *vf)
+{
+        free(vf->priv->Line);
+        free(vf->priv->Frame[0]);
+        free(vf->priv->Frame[1]);
+        free(vf->priv->Frame[2]);
+
+        vf->priv->Line     = NULL;
+        vf->priv->Frame[0] = NULL;
+        vf->priv->Frame[1] = NULL;
+        vf->priv->Frame[2] = NULL;
+}
+
+static int config(struct vf_instance *vf,
+        int width, int height, int d_width, int d_height,
+        unsigned int flags, unsigned int outfmt){
+
+        uninit(vf);
+        vf->priv->Line = malloc(width*sizeof(int));
+
+        return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+}
+
+static inline unsigned int LowPassMul(unsigned int PrevMul, unsigned int CurrMul, int* Coef){
+//    int dMul= (PrevMul&0xFFFFFF)-(CurrMul&0xFFFFFF);
+    int dMul= PrevMul-CurrMul;
+    unsigned int d=((dMul+0x10007FF)>>12);
+    return CurrMul + Coef[d];
+}
+
+static void deNoiseTemporal(
+                    unsigned char *Frame,        // mpi->planes[x]
+                    unsigned char *FrameDest,    // dmpi->planes[x]
+                    unsigned short *FrameAnt,
+                    int W, int H, int sStride, int dStride,
+                    int *Temporal)
+{
+    long X, Y;
+    unsigned int PixelDst;
+
+    for (Y = 0; Y < H; Y++){
+        for (X = 0; X < W; X++){
+            PixelDst = LowPassMul(FrameAnt[X]<<8, Frame[X]<<16, Temporal);
+            FrameAnt[X] = ((PixelDst+0x1000007F)>>8);
+            FrameDest[X]= ((PixelDst+0x10007FFF)>>16);
+        }
+        Frame += sStride;
+        FrameDest += dStride;
+        FrameAnt += W;
+    }
+}
+
+static void deNoiseSpacial(
+                    unsigned char *Frame,        // mpi->planes[x]
+                    unsigned char *FrameDest,    // dmpi->planes[x]
+                    unsigned int *LineAnt,       // vf->priv->Line (width bytes)
+                    int W, int H, int sStride, int dStride,
+                    int *Horizontal, int *Vertical)
+{
+    long X, Y;
+    long sLineOffs = 0, dLineOffs = 0;
+    unsigned int PixelAnt;
+    unsigned int PixelDst;
+
+    /* First pixel has no left nor top neighbor. */
+    PixelDst = LineAnt[0] = PixelAnt = Frame[0]<<16;
+    FrameDest[0]= ((PixelDst+0x10007FFF)>>16);
+
+    /* First line has no top neighbor, only left. */
+    for (X = 1; X < W; X++){
+        PixelDst = LineAnt[X] = LowPassMul(PixelAnt, Frame[X]<<16, Horizontal);
+        FrameDest[X]= ((PixelDst+0x10007FFF)>>16);
+    }
+
+    for (Y = 1; Y < H; Y++){
+        unsigned int PixelAnt;
+        sLineOffs += sStride, dLineOffs += dStride;
+        /* First pixel on each line doesn't have previous pixel */
+        PixelAnt = Frame[sLineOffs]<<16;
+        PixelDst = LineAnt[0] = LowPassMul(LineAnt[0], PixelAnt, Vertical);
+        FrameDest[dLineOffs]= ((PixelDst+0x10007FFF)>>16);
+
+        for (X = 1; X < W; X++){
+            unsigned int PixelDst;
+            /* The rest are normal */
+            PixelAnt = LowPassMul(PixelAnt, Frame[sLineOffs+X]<<16, Horizontal);
+            PixelDst = LineAnt[X] = LowPassMul(LineAnt[X], PixelAnt, Vertical);
+            FrameDest[dLineOffs+X]= ((PixelDst+0x10007FFF)>>16);
+        }
+    }
+}
+
+static void deNoise(unsigned char *Frame,        // mpi->planes[x]
+                    unsigned char *FrameDest,    // dmpi->planes[x]
+                    unsigned int *LineAnt,      // vf->priv->Line (width bytes)
+                    unsigned short **FrameAntPtr,
+                    int W, int H, int sStride, int dStride,
+                    int *Horizontal, int *Vertical, int *Temporal)
+{
+    long X, Y;
+    long sLineOffs = 0, dLineOffs = 0;
+    unsigned int PixelAnt;
+    unsigned int PixelDst;
+    unsigned short* FrameAnt=(*FrameAntPtr);
+
+    if(!FrameAnt){
+        (*FrameAntPtr)=FrameAnt=malloc(W*H*sizeof(unsigned short));
+        for (Y = 0; Y < H; Y++){
+            unsigned short* dst=&FrameAnt[Y*W];
+            unsigned char* src=Frame+Y*sStride;
+            for (X = 0; X < W; X++) dst[X]=src[X]<<8;
+        }
+    }
+
+    if(!Horizontal[0] && !Vertical[0]){
+        deNoiseTemporal(Frame, FrameDest, FrameAnt,
+                        W, H, sStride, dStride, Temporal);
+        return;
+    }
+    if(!Temporal[0]){
+        deNoiseSpacial(Frame, FrameDest, LineAnt,
+                       W, H, sStride, dStride, Horizontal, Vertical);
+        return;
+    }
+
+    /* First pixel has no left nor top neighbor. Only previous frame */
+    LineAnt[0] = PixelAnt = Frame[0]<<16;
+    PixelDst = LowPassMul(FrameAnt[0]<<8, PixelAnt, Temporal);
+    FrameAnt[0] = ((PixelDst+0x1000007F)>>8);
+    FrameDest[0]= ((PixelDst+0x10007FFF)>>16);
+
+    /* First line has no top neighbor. Only left one for each pixel and
+     * last frame */
+    for (X = 1; X < W; X++){
+        LineAnt[X] = PixelAnt = LowPassMul(PixelAnt, Frame[X]<<16, Horizontal);
+        PixelDst = LowPassMul(FrameAnt[X]<<8, PixelAnt, Temporal);
+        FrameAnt[X] = ((PixelDst+0x1000007F)>>8);
+        FrameDest[X]= ((PixelDst+0x10007FFF)>>16);
+    }
+
+    for (Y = 1; Y < H; Y++){
+        unsigned int PixelAnt;
+        unsigned short* LinePrev=&FrameAnt[Y*W];
+        sLineOffs += sStride, dLineOffs += dStride;
+        /* First pixel on each line doesn't have previous pixel */
+        PixelAnt = Frame[sLineOffs]<<16;
+        LineAnt[0] = LowPassMul(LineAnt[0], PixelAnt, Vertical);
+        PixelDst = LowPassMul(LinePrev[0]<<8, LineAnt[0], Temporal);
+        LinePrev[0] = ((PixelDst+0x1000007F)>>8);
+        FrameDest[dLineOffs]= ((PixelDst+0x10007FFF)>>16);
+
+        for (X = 1; X < W; X++){
+            unsigned int PixelDst;
+            /* The rest are normal */
+            PixelAnt = LowPassMul(PixelAnt, Frame[sLineOffs+X]<<16, Horizontal);
+            LineAnt[X] = LowPassMul(LineAnt[X], PixelAnt, Vertical);
+            PixelDst = LowPassMul(LinePrev[X]<<8, LineAnt[X], Temporal);
+            LinePrev[X] = ((PixelDst+0x1000007F)>>8);
+            FrameDest[dLineOffs+X]= ((PixelDst+0x10007FFF)>>16);
+        }
+    }
+}
+
+
+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_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
+                mpi->w,mpi->h);
+
+        if(!dmpi) return 0;
+
+        deNoise(mpi->planes[0], dmpi->planes[0],
+                vf->priv->Line, &vf->priv->Frame[0], W, H,
+                mpi->stride[0], dmpi->stride[0],
+                vf->priv->Coefs[0],
+                vf->priv->Coefs[0],
+                vf->priv->Coefs[1]);
+        deNoise(mpi->planes[1], dmpi->planes[1],
+                vf->priv->Line, &vf->priv->Frame[1], cw, ch,
+                mpi->stride[1], dmpi->stride[1],
+                vf->priv->Coefs[2],
+                vf->priv->Coefs[2],
+                vf->priv->Coefs[3]);
+        deNoise(mpi->planes[2], dmpi->planes[2],
+                vf->priv->Line, &vf->priv->Frame[2], cw, ch,
+                mpi->stride[2], dmpi->stride[2],
+                vf->priv->Coefs[2],
+                vf->priv->Coefs[2],
+                vf->priv->Coefs[3]);
+
+        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 - 0.00001);
+
+    for (i = -255*16; i <= 255*16; i++)
+    {
+        Simil = 1.0 - ABS(i) / (16*255.0);
+        C = pow(Simil, Gamma) * 65536.0 * (double)i / 16.0;
+        Ct[16*256+i] = (C<0) ? (C-0.5) : (C+0.5);
+    }
+
+    Ct[0] = (Dist25 != 0);
+}
+
+
+static int vf_open(vf_instance_t *vf, char *args){
+        double LumSpac, LumTmp, ChromSpac, ChromTmp;
+        double Param1, Param2, Param3, Param4;
+
+        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:%lf",
+                          &Param1, &Param2, &Param3, &Param4
+                         ))
+            {
+            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;
+
+            case 4:
+                LumSpac = Param1;
+                LumTmp = Param3;
+
+                ChromSpac = Param2;
+                ChromTmp = Param4;
+                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_hqdn3d = {
+    "High Quality 3D Denoiser",
+    "hqdn3d",
+    "Daniel Moreno & A'rpi",
+    "",
+    vf_open,
+    NULL
+};
+
+//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vf_il.c b/libavfilter/libmpcodecs/vf_il.c
new file mode 100644
index 0000000..210e30d
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_il.c
@@ -0,0 +1,148 @@
+/*
+ * 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
new file mode 100644
index 0000000..db4a849
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_ilpack.c
@@ -0,0 +1,456 @@
+/*
+ * 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 "cpudetect.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+#include "libavutil/attributes.h"
+
+typedef void (pack_func_t)(unsigned char *dst, unsigned char *y,
+    unsigned char *u, unsigned char *v, int w, int us, int vs);
+
+struct vf_priv_s {
+    int mode;
+    pack_func_t *pack[2];
+};
+
+static void pack_nn_C(unsigned char *dst, unsigned char *y,
+    unsigned char *u, unsigned char *v, int w,
+    int av_unused us, int av_unused vs)
+{
+    int j;
+    for (j = w/2; j; j--) {
+        *dst++ = *y++;
+        *dst++ = *u++;
+        *dst++ = *y++;
+        *dst++ = *v++;
+    }
+}
+
+static void pack_li_0_C(unsigned char *dst, unsigned char *y,
+    unsigned char *u, unsigned char *v, int w, int us, int vs)
+{
+    int j;
+    for (j = w/2; j; j--) {
+        *dst++ = *y++;
+        *dst++ = (u[us+us] + 7*u[0])>>3;
+        *dst++ = *y++;
+        *dst++ = (v[vs+vs] + 7*v[0])>>3;
+        u++; v++;
+    }
+}
+
+static void pack_li_1_C(unsigned char *dst, unsigned char *y,
+    unsigned char *u, unsigned char *v, int w, int us, int vs)
+{
+    int j;
+    for (j = w/2; j; j--) {
+        *dst++ = *y++;
+        *dst++ = (3*u[us+us] + 5*u[0])>>3;
+        *dst++ = *y++;
+        *dst++ = (3*v[vs+vs] + 5*v[0])>>3;
+        u++; v++;
+    }
+}
+
+#if HAVE_MMX
+static void pack_nn_MMX(unsigned char *dst, unsigned char *y,
+    unsigned char *u, unsigned char *v, int w,
+    int av_unused us, int av_unused vs)
+{
+    __asm__ volatile (""
+        ASMALIGN(4)
+        "1: \n\t"
+        "movq (%0), %%mm1 \n\t"
+        "movq (%0), %%mm2 \n\t"
+        "movq (%1), %%mm4 \n\t"
+        "movq (%2), %%mm6 \n\t"
+        "punpcklbw %%mm6, %%mm4 \n\t"
+        "punpcklbw %%mm4, %%mm1 \n\t"
+        "punpckhbw %%mm4, %%mm2 \n\t"
+
+        "add $8, %0 \n\t"
+        "add $4, %1 \n\t"
+        "add $4, %2 \n\t"
+        "movq %%mm1, (%3) \n\t"
+        "movq %%mm2, 8(%3) \n\t"
+        "add $16, %3 \n\t"
+        "decl %4 \n\t"
+        "jnz 1b \n\t"
+        "emms \n\t"
+        :
+        : "r" (y), "r" (u), "r" (v), "r" (dst), "r" (w/8)
+        : "memory"
+        );
+    pack_nn_C(dst, y, u, v, (w&7), 0, 0);
+}
+
+#if HAVE_EBX_AVAILABLE
+static void pack_li_0_MMX(unsigned char *dst, unsigned char *y,
+    unsigned char *u, unsigned char *v, int w, int us, int vs)
+{
+    __asm__ volatile (""
+        "push %%"REG_BP" \n\t"
+#if ARCH_X86_64
+        "mov %6, %%"REG_BP" \n\t"
+#else
+        "movl 4(%%"REG_d"), %%"REG_BP" \n\t"
+        "movl (%%"REG_d"), %%"REG_d" \n\t"
+#endif
+        "pxor %%mm0, %%mm0 \n\t"
+
+        ASMALIGN(4)
+        ".Lli0: \n\t"
+        "movq (%%"REG_S"), %%mm1 \n\t"
+        "movq (%%"REG_S"), %%mm2 \n\t"
+
+        "movq (%%"REG_a",%%"REG_d",2), %%mm4 \n\t"
+        "movq (%%"REG_b",%%"REG_BP",2), %%mm6 \n\t"
+        "punpcklbw %%mm0, %%mm4 \n\t"
+        "punpcklbw %%mm0, %%mm6 \n\t"
+        "movq (%%"REG_a"), %%mm3 \n\t"
+        "movq (%%"REG_b"), %%mm5 \n\t"
+        "punpcklbw %%mm0, %%mm3 \n\t"
+        "punpcklbw %%mm0, %%mm5 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "psrlw $3, %%mm4 \n\t"
+        "psrlw $3, %%mm6 \n\t"
+        "packuswb %%mm4, %%mm4 \n\t"
+        "packuswb %%mm6, %%mm6 \n\t"
+        "punpcklbw %%mm6, %%mm4 \n\t"
+        "punpcklbw %%mm4, %%mm1 \n\t"
+        "punpckhbw %%mm4, %%mm2 \n\t"
+
+        "movq %%mm1, (%%"REG_D") \n\t"
+        "movq %%mm2, 8(%%"REG_D") \n\t"
+
+        "movq 8(%%"REG_S"), %%mm1 \n\t"
+        "movq 8(%%"REG_S"), %%mm2 \n\t"
+
+        "movq (%%"REG_a",%%"REG_d",2), %%mm4 \n\t"
+        "movq (%%"REG_b",%%"REG_BP",2), %%mm6 \n\t"
+        "punpckhbw %%mm0, %%mm4 \n\t"
+        "punpckhbw %%mm0, %%mm6 \n\t"
+        "movq (%%"REG_a"), %%mm3 \n\t"
+        "movq (%%"REG_b"), %%mm5 \n\t"
+        "punpckhbw %%mm0, %%mm3 \n\t"
+        "punpckhbw %%mm0, %%mm5 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "psrlw $3, %%mm4 \n\t"
+        "psrlw $3, %%mm6 \n\t"
+        "packuswb %%mm4, %%mm4 \n\t"
+        "packuswb %%mm6, %%mm6 \n\t"
+        "punpcklbw %%mm6, %%mm4 \n\t"
+        "punpcklbw %%mm4, %%mm1 \n\t"
+        "punpckhbw %%mm4, %%mm2 \n\t"
+
+        "add $16, %%"REG_S" \n\t"
+        "add $8, %%"REG_a" \n\t"
+        "add $8, %%"REG_b" \n\t"
+
+        "movq %%mm1, 16(%%"REG_D") \n\t"
+        "movq %%mm2, 24(%%"REG_D") \n\t"
+        "add $32, %%"REG_D" \n\t"
+
+        "decl %%ecx \n\t"
+        "jnz .Lli0 \n\t"
+        "emms \n\t"
+        "pop %%"REG_BP" \n\t"
+        :
+        : "S" (y), "D" (dst), "a" (u), "b" (v), "c" (w/16),
+#if ARCH_X86_64
+        "d" ((x86_reg)us), "r" ((x86_reg)vs)
+#else
+        "d" (&us)
+#endif
+        : "memory"
+        );
+    pack_li_0_C(dst, y, u, v, (w&15), us, vs);
+}
+
+static void pack_li_1_MMX(unsigned char *dst, unsigned char *y,
+    unsigned char *u, unsigned char *v, int w, int us, int vs)
+{
+    __asm__ volatile (""
+        "push %%"REG_BP" \n\t"
+#if ARCH_X86_64
+        "mov %6, %%"REG_BP" \n\t"
+#else
+        "movl 4(%%"REG_d"), %%"REG_BP" \n\t"
+        "movl (%%"REG_d"), %%"REG_d" \n\t"
+#endif
+        "pxor %%mm0, %%mm0 \n\t"
+
+        ASMALIGN(4)
+        ".Lli1: \n\t"
+        "movq (%%"REG_S"), %%mm1 \n\t"
+        "movq (%%"REG_S"), %%mm2 \n\t"
+
+        "movq (%%"REG_a",%%"REG_d",2), %%mm4 \n\t"
+        "movq (%%"REG_b",%%"REG_BP",2), %%mm6 \n\t"
+        "punpcklbw %%mm0, %%mm4 \n\t"
+        "punpcklbw %%mm0, %%mm6 \n\t"
+        "movq (%%"REG_a"), %%mm3 \n\t"
+        "movq (%%"REG_b"), %%mm5 \n\t"
+        "punpcklbw %%mm0, %%mm3 \n\t"
+        "punpcklbw %%mm0, %%mm5 \n\t"
+        "movq %%mm4, %%mm7 \n\t"
+        "paddw %%mm4, %%mm4 \n\t"
+        "paddw %%mm7, %%mm4 \n\t"
+        "movq %%mm6, %%mm7 \n\t"
+        "paddw %%mm6, %%mm6 \n\t"
+        "paddw %%mm7, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "psrlw $3, %%mm4 \n\t"
+        "psrlw $3, %%mm6 \n\t"
+        "packuswb %%mm4, %%mm4 \n\t"
+        "packuswb %%mm6, %%mm6 \n\t"
+        "punpcklbw %%mm6, %%mm4 \n\t"
+        "punpcklbw %%mm4, %%mm1 \n\t"
+        "punpckhbw %%mm4, %%mm2 \n\t"
+
+        "movq %%mm1, (%%"REG_D") \n\t"
+        "movq %%mm2, 8(%%"REG_D") \n\t"
+
+        "movq 8(%%"REG_S"), %%mm1 \n\t"
+        "movq 8(%%"REG_S"), %%mm2 \n\t"
+
+        "movq (%%"REG_a",%%"REG_d",2), %%mm4 \n\t"
+        "movq (%%"REG_b",%%"REG_BP",2), %%mm6 \n\t"
+        "punpckhbw %%mm0, %%mm4 \n\t"
+        "punpckhbw %%mm0, %%mm6 \n\t"
+        "movq (%%"REG_a"), %%mm3 \n\t"
+        "movq (%%"REG_b"), %%mm5 \n\t"
+        "punpckhbw %%mm0, %%mm3 \n\t"
+        "punpckhbw %%mm0, %%mm5 \n\t"
+        "movq %%mm4, %%mm7 \n\t"
+        "paddw %%mm4, %%mm4 \n\t"
+        "paddw %%mm7, %%mm4 \n\t"
+        "movq %%mm6, %%mm7 \n\t"
+        "paddw %%mm6, %%mm6 \n\t"
+        "paddw %%mm7, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+        "paddw %%mm5, %%mm6 \n\t"
+        "psrlw $3, %%mm4 \n\t"
+        "psrlw $3, %%mm6 \n\t"
+        "packuswb %%mm4, %%mm4 \n\t"
+        "packuswb %%mm6, %%mm6 \n\t"
+        "punpcklbw %%mm6, %%mm4 \n\t"
+        "punpcklbw %%mm4, %%mm1 \n\t"
+        "punpckhbw %%mm4, %%mm2 \n\t"
+
+        "add $16, %%"REG_S" \n\t"
+        "add $8, %%"REG_a" \n\t"
+        "add $8, %%"REG_b" \n\t"
+
+        "movq %%mm1, 16(%%"REG_D") \n\t"
+        "movq %%mm2, 24(%%"REG_D") \n\t"
+        "add $32, %%"REG_D" \n\t"
+
+        "decl %%ecx \n\t"
+        "jnz .Lli1 \n\t"
+        "emms \n\t"
+        "pop %%"REG_BP" \n\t"
+        :
+        : "S" (y), "D" (dst), "a" (u), "b" (v), "c" (w/16),
+#if ARCH_X86_64
+        "d" ((x86_reg)us), "r" ((x86_reg)vs)
+#else
+        "d" (&us)
+#endif
+        : "memory"
+        );
+    pack_li_1_C(dst, y, u, v, (w&15), us, vs);
+}
+#endif /* HAVE_EBX_AVAILABLE */
+#endif
+
+static pack_func_t *pack_nn;
+static pack_func_t *pack_li_0;
+static pack_func_t *pack_li_1;
+
+static void ilpack(unsigned char *dst, unsigned char *src[3],
+    int dststride, int srcstride[3], int w, int h, pack_func_t *pack[2])
+{
+    int i;
+    unsigned char *y, *u, *v;
+    int ys = srcstride[0], us = srcstride[1], vs = srcstride[2];
+    int a, b;
+
+    y = src[0];
+    u = src[1];
+    v = src[2];
+
+    pack_nn(dst, y, u, v, w, 0, 0);
+    y += ys; dst += dststride;
+    pack_nn(dst, y, u+us, v+vs, w, 0, 0);
+    y += ys; dst += dststride;
+    for (i=2; i<h-2; i++) {
+        a = (i&2) ? 1 : -1;
+        b = (i&1) ^ ((i&2)>>1);
+        pack[b](dst, y, u, v, w, us*a, vs*a);
+        y += ys;
+        if ((i&3) == 1) {
+            u -= us;
+            v -= vs;
+        } else {
+            u += us;
+            v += vs;
+        }
+        dst += dststride;
+    }
+    pack_nn(dst, y, u, v, w, 0, 0);
+    y += ys; dst += dststride; u += us; v += vs;
+    pack_nn(dst, y, u, v, w, 0, 0);
+}
+
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+    mp_image_t *dmpi;
+
+    // hope we'll get DR buffer:
+    dmpi=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);
+}
+
+static int config(struct vf_instance *vf,
+          int width, int height, int d_width, int d_height,
+          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);
+}
+
+
+static int query_format(struct vf_instance *vf, unsigned int fmt)
+{
+    /* FIXME - really any YUV 4:2:0 input format should work */
+    switch (fmt) {
+    case IMGFMT_YV12:
+    case IMGFMT_IYUV:
+    case IMGFMT_I420:
+        return vf_next_query_format(vf,IMGFMT_YUY2);
+    }
+    return 0;
+}
+
+static int vf_open(vf_instance_t *vf, char *args)
+{
+    vf->config=config;
+    vf->query_format=query_format;
+    vf->put_image=put_image;
+    vf->priv = calloc(1, sizeof(struct vf_priv_s));
+    vf->priv->mode = 1;
+    if (args) sscanf(args, "%d", &vf->priv->mode);
+
+    pack_nn = pack_nn_C;
+    pack_li_0 = pack_li_0_C;
+    pack_li_1 = pack_li_1_C;
+#if HAVE_MMX
+    if(gCpuCaps.hasMMX) {
+        pack_nn = pack_nn_MMX;
+#if HAVE_EBX_AVAILABLE
+        pack_li_0 = pack_li_0_MMX;
+        pack_li_1 = pack_li_1_MMX;
+#endif
+    }
+#endif
+
+    switch(vf->priv->mode) {
+    case 0:
+        vf->priv->pack[0] = vf->priv->pack[1] = pack_nn;
+        break;
+    default:
+        mp_msg(MSGT_VFILTER, MSGL_WARN,
+            "ilpack: unknown mode %d (fallback to linear)\n",
+            vf->priv->mode);
+    case 1:
+        vf->priv->pack[0] = pack_li_0;
+        vf->priv->pack[1] = pack_li_1;
+        break;
+    }
+
+    return 1;
+}
+
+const vf_info_t vf_info_ilpack = {
+    "4:2:0 planar -> 4:2:2 packed reinterlacer",
+    "ilpack",
+    "Richard Felker",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_ivtc.c b/libavfilter/libmpcodecs/vf_ivtc.c
new file mode 100644
index 0000000..b10e505
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_ivtc.c
@@ -0,0 +1,550 @@
+/*
+ * 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 "cpudetect.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "libvo/fastmemcpy.h"
+
+
+struct metrics {
+    /* difference: total, even lines, odd lines */
+    int d, e, o;
+    /* noise: temporal, spacial (current), spacial (past) */
+    int t, s, p;
+};
+
+struct frameinfo {
+    /* peak, relative, mean */
+    struct metrics p, r, m;
+};
+
+struct vf_priv_s {
+    struct frameinfo fi[2];
+    mp_image_t *dmpi;
+    int first;
+    int drop, lastdrop, dropnext;
+    int inframes, outframes;
+};
+
+enum {
+    F_DROP,
+    F_MERGE,
+    F_NEXT,
+    F_SHOW
+};
+
+#if HAVE_MMX && HAVE_EBX_AVAILABLE
+static void block_diffs_MMX(struct metrics *m, unsigned char *old, unsigned char *new, int os, int ns)
+{
+    int i;
+    short out[24]; // output buffer for the partial metrics from the mmx code
+
+    __asm__ (
+        "movl $4, %%ecx \n\t"
+        "pxor %%mm4, %%mm4 \n\t" // 4 even difference sums
+        "pxor %%mm5, %%mm5 \n\t" // 4 odd difference sums
+        "pxor %%mm7, %%mm7 \n\t" // all zeros
+
+        ASMALIGN(4)
+        "1: \n\t"
+
+        // Even difference
+        "movq (%%"REG_S"), %%mm0 \n\t"
+        "movq (%%"REG_S"), %%mm2 \n\t"
+        "add %%"REG_a", %%"REG_S" \n\t"
+        "movq (%%"REG_D"), %%mm1 \n\t"
+        "add %%"REG_b", %%"REG_D" \n\t"
+        "psubusb %%mm1, %%mm2 \n\t"
+        "psubusb %%mm0, %%mm1 \n\t"
+        "movq %%mm2, %%mm0 \n\t"
+        "movq %%mm1, %%mm3 \n\t"
+        "punpcklbw %%mm7, %%mm0 \n\t"
+        "punpcklbw %%mm7, %%mm1 \n\t"
+        "punpckhbw %%mm7, %%mm2 \n\t"
+        "punpckhbw %%mm7, %%mm3 \n\t"
+        "paddw %%mm0, %%mm4 \n\t"
+        "paddw %%mm1, %%mm4 \n\t"
+        "paddw %%mm2, %%mm4 \n\t"
+        "paddw %%mm3, %%mm4 \n\t"
+
+        // Odd difference
+        "movq (%%"REG_S"), %%mm0 \n\t"
+        "movq (%%"REG_S"), %%mm2 \n\t"
+        "add %%"REG_a", %%"REG_S" \n\t"
+        "movq (%%"REG_D"), %%mm1 \n\t"
+        "add %%"REG_b", %%"REG_D" \n\t"
+        "psubusb %%mm1, %%mm2 \n\t"
+        "psubusb %%mm0, %%mm1 \n\t"
+        "movq %%mm2, %%mm0 \n\t"
+        "movq %%mm1, %%mm3 \n\t"
+        "punpcklbw %%mm7, %%mm0 \n\t"
+        "punpcklbw %%mm7, %%mm1 \n\t"
+        "punpckhbw %%mm7, %%mm2 \n\t"
+        "punpckhbw %%mm7, %%mm3 \n\t"
+        "paddw %%mm0, %%mm5 \n\t"
+        "paddw %%mm1, %%mm5 \n\t"
+        "paddw %%mm2, %%mm5 \n\t"
+        "paddw %%mm3, %%mm5 \n\t"
+
+        "decl %%ecx \n\t"
+        "jnz 1b \n\t"
+        "movq %%mm4, (%%"REG_d") \n\t"
+        "movq %%mm5, 8(%%"REG_d") \n\t"
+        :
+        : "S" (old), "D" (new), "a" (os), "b" (ns), "d" (out)
+        : "memory"
+        );
+    m->e = out[0]+out[1]+out[2]+out[3];
+    m->o = out[4]+out[5]+out[6]+out[7];
+    m->d = m->e + m->o;
+
+    __asm__ (
+        // First loop to measure first four columns
+        "movl $4, %%ecx \n\t"
+        "pxor %%mm4, %%mm4 \n\t" // Past spacial noise
+        "pxor %%mm5, %%mm5 \n\t" // Temporal noise
+        "pxor %%mm6, %%mm6 \n\t" // Current spacial noise
+
+        ASMALIGN(4)
+        "2: \n\t"
+
+        "movq (%%"REG_S"), %%mm0 \n\t"
+        "movq (%%"REG_S",%%"REG_a"), %%mm1 \n\t"
+        "add %%"REG_a", %%"REG_S" \n\t"
+        "add %%"REG_a", %%"REG_S" \n\t"
+        "movq (%%"REG_D"), %%mm2 \n\t"
+        "movq (%%"REG_D",%%"REG_b"), %%mm3 \n\t"
+        "add %%"REG_b", %%"REG_D" \n\t"
+        "add %%"REG_b", %%"REG_D" \n\t"
+        "punpcklbw %%mm7, %%mm0 \n\t"
+        "punpcklbw %%mm7, %%mm1 \n\t"
+        "punpcklbw %%mm7, %%mm2 \n\t"
+        "punpcklbw %%mm7, %%mm3 \n\t"
+        "paddw %%mm1, %%mm4 \n\t"
+        "paddw %%mm1, %%mm5 \n\t"
+        "paddw %%mm3, %%mm6 \n\t"
+        "psubw %%mm0, %%mm4 \n\t"
+        "psubw %%mm2, %%mm5 \n\t"
+        "psubw %%mm2, %%mm6 \n\t"
+
+        "decl %%ecx \n\t"
+        "jnz 2b \n\t"
+
+        "movq %%mm0, %%mm1 \n\t"
+        "movq %%mm0, %%mm2 \n\t"
+        "movq %%mm0, %%mm3 \n\t"
+        "pcmpgtw %%mm4, %%mm1 \n\t"
+        "pcmpgtw %%mm5, %%mm2 \n\t"
+        "pcmpgtw %%mm6, %%mm3 \n\t"
+        "pxor %%mm1, %%mm4 \n\t"
+        "pxor %%mm2, %%mm5 \n\t"
+        "pxor %%mm3, %%mm6 \n\t"
+        "psubw %%mm1, %%mm4 \n\t"
+        "psubw %%mm2, %%mm5 \n\t"
+        "psubw %%mm3, %%mm6 \n\t"
+        "movq %%mm4, (%%"REG_d") \n\t"
+        "movq %%mm5, 16(%%"REG_d") \n\t"
+        "movq %%mm6, 32(%%"REG_d") \n\t"
+
+        "mov %%"REG_a", %%"REG_c" \n\t"
+        "shl $3, %%"REG_c" \n\t"
+        "sub %%"REG_c", %%"REG_S" \n\t"
+        "mov %%"REG_b", %%"REG_c" \n\t"
+        "shl $3, %%"REG_c" \n\t"
+        "sub %%"REG_c", %%"REG_D" \n\t"
+
+        // Second loop for the last four columns
+        "movl $4, %%ecx \n\t"
+        "pxor %%mm4, %%mm4 \n\t"
+        "pxor %%mm5, %%mm5 \n\t"
+        "pxor %%mm6, %%mm6 \n\t"
+
+        ASMALIGN(4)
+        "3: \n\t"
+
+        "movq (%%"REG_S"), %%mm0 \n\t"
+        "movq (%%"REG_S",%%"REG_a"), %%mm1 \n\t"
+        "add %%"REG_a", %%"REG_S" \n\t"
+        "add %%"REG_a", %%"REG_S" \n\t"
+        "movq (%%"REG_D"), %%mm2 \n\t"
+        "movq (%%"REG_D",%%"REG_b"), %%mm3 \n\t"
+        "add %%"REG_b", %%"REG_D" \n\t"
+        "add %%"REG_b", %%"REG_D" \n\t"
+        "punpckhbw %%mm7, %%mm0 \n\t"
+        "punpckhbw %%mm7, %%mm1 \n\t"
+        "punpckhbw %%mm7, %%mm2 \n\t"
+        "punpckhbw %%mm7, %%mm3 \n\t"
+        "paddw %%mm1, %%mm4 \n\t"
+        "paddw %%mm1, %%mm5 \n\t"
+        "paddw %%mm3, %%mm6 \n\t"
+        "psubw %%mm0, %%mm4 \n\t"
+        "psubw %%mm2, %%mm5 \n\t"
+        "psubw %%mm2, %%mm6 \n\t"
+
+        "decl %%ecx \n\t"
+        "jnz 3b \n\t"
+
+        "movq %%mm0, %%mm1 \n\t"
+        "movq %%mm0, %%mm2 \n\t"
+        "movq %%mm0, %%mm3 \n\t"
+        "pcmpgtw %%mm4, %%mm1 \n\t"
+        "pcmpgtw %%mm5, %%mm2 \n\t"
+        "pcmpgtw %%mm6, %%mm3 \n\t"
+        "pxor %%mm1, %%mm4 \n\t"
+        "pxor %%mm2, %%mm5 \n\t"
+        "pxor %%mm3, %%mm6 \n\t"
+        "psubw %%mm1, %%mm4 \n\t"
+        "psubw %%mm2, %%mm5 \n\t"
+        "psubw %%mm3, %%mm6 \n\t"
+        "movq %%mm4, 8(%%"REG_d") \n\t"
+        "movq %%mm5, 24(%%"REG_d") \n\t"
+        "movq %%mm6, 40(%%"REG_d") \n\t"
+
+        "emms \n\t"
+        :
+        : "S" (old), "D" (new), "a" ((long)os), "b" ((long)ns), "d" (out)
+        : "memory"
+        );
+    m->p = m->t = m->s = 0;
+    for (i=0; i<8; i++) {
+        m->p += out[i];
+        m->t += out[8+i];
+        m->s += out[16+i];
+    }
+    //printf("e=%d o=%d d=%d p=%d t=%d s=%d\n", m->e, m->o, m->d, m->p, m->t, m->s);
+}
+#endif
+
+//#define MAG(a) ((a)*(a))
+//#define MAG(a) (abs(a))
+#define MAG(a) (((a)^((a)>>31))-((a)>>31))
+
+//#define LOWPASS(s) (((s)[-2] + 4*(s)[-1] + 6*(s)[0] + 4*(s)[1] + (s)[2])>>4)
+//#define LOWPASS(s) (((s)[-1] + 2*(s)[0] + (s)[1])>>2)
+#define LOWPASS(s) ((s)[0])
+
+
+static void block_diffs_C(struct metrics *m, unsigned char *old, unsigned char *new, int os, int ns)
+{
+    int x, y, e=0, o=0, s=0, p=0, t=0;
+    unsigned char *oldp, *newp;
+    m->s = m->p = m->t = 0;
+    for (x = 8; x; x--) {
+        oldp = old++;
+        newp = new++;
+        s = p = t = 0;
+        for (y = 4; y; y--) {
+            e += MAG(newp[0]-oldp[0]);
+            o += MAG(newp[ns]-oldp[os]);
+            s += newp[ns]-newp[0];
+            p += oldp[os]-oldp[0];
+            t += oldp[os]-newp[0];
+            oldp += os<<1;
+            newp += ns<<1;
+        }
+        m->s += MAG(s);
+        m->p += MAG(p);
+        m->t += MAG(t);
+    }
+    m->e = e;
+    m->o = o;
+    m->d = e+o;
+}
+
+static void (*block_diffs)(struct metrics *, unsigned char *, unsigned char *, int, int);
+
+#define MAXUP(a,b) ((a) = ((a)>(b)) ? (a) : (b))
+
+static void diff_planes(struct frameinfo *fi,
+    unsigned char *old, unsigned char *new, int w, int h, int os, int ns)
+{
+    int x, y;
+    struct metrics l;
+    struct metrics *peak=&fi->p, *rel=&fi->r, *mean=&fi->m;
+    memset(peak, 0, sizeof(struct metrics));
+    memset(rel, 0, sizeof(struct metrics));
+    memset(mean, 0, sizeof(struct metrics));
+    for (y = 0; y < h-7; y += 8) {
+        for (x = 8; x < w-8-7; x += 8) {
+            block_diffs(&l, old+x+y*os, new+x+y*ns, os, ns);
+            mean->d += l.d;
+            mean->e += l.e;
+            mean->o += l.o;
+            mean->s += l.s;
+            mean->p += l.p;
+            mean->t += l.t;
+            MAXUP(peak->d, l.d);
+            MAXUP(peak->e, l.e);
+            MAXUP(peak->o, l.o);
+            MAXUP(peak->s, l.s);
+            MAXUP(peak->p, l.p);
+            MAXUP(peak->t, l.t);
+            MAXUP(rel->e, l.e-l.o);
+            MAXUP(rel->o, l.o-l.e);
+            MAXUP(rel->s, l.s-l.t);
+            MAXUP(rel->p, l.p-l.t);
+            MAXUP(rel->t, l.t-l.p);
+            MAXUP(rel->d, l.t-l.s); /* hack */
+        }
+    }
+    x = (w/8-2)*(h/8);
+    mean->d /= x;
+    mean->e /= x;
+    mean->o /= x;
+    mean->s /= x;
+    mean->p /= x;
+    mean->t /= x;
+}
+
+static void diff_fields(struct frameinfo *fi, mp_image_t *old, mp_image_t *new)
+{
+    diff_planes(fi, old->planes[0], new->planes[0],
+        new->w, new->h, old->stride[0], new->stride[0]);
+}
+
+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",
+        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);
+}
+
+static int foo(struct vf_priv_s *p, mp_image_t *new, mp_image_t *cur)
+{
+    struct frameinfo *f = p->fi;
+
+    f[0] = f[1];
+    diff_fields(&f[1], cur, new);
+    stats(&f[1]);
+
+    // Immediately drop this frame if it's already been used.
+    if (p->dropnext) {
+        p->dropnext = 0;
+        return F_DROP;
+    }
+
+    // Sometimes a pulldown frame comes all by itself, so both
+    // its top and bottom field are duplicates from the adjacent
+    // two frames. We can just drop such a frame, but we
+    // immediately show the next frame instead to keep the frame
+    // drops evenly spaced during normal 3:2 pulldown sequences.
+    if ((3*f[1].r.o < f[1].r.e) && (f[1].r.s < f[1].r.d)) {
+        p->dropnext = 1;
+        return F_NEXT;
+    }
+
+    // If none of these conditions hold, we will consider the frame
+    // progressive and just show it as-is.
+    if (!(  (3*f[0].r.e < f[0].r.o) ||
+        ((2*f[0].r.d < f[0].r.s) && (f[0].r.s > 1200)) ||
+        ((2*f[1].r.t < f[1].r.p) && (f[1].r.p > 1200))  ))
+        return F_SHOW;
+
+    // Otherwise, we have to decide whether to merge or drop.
+    // If the noise metric only increases minimally, we're off
+    // to a good start...
+    if (((2*f[1].r.t < 3*f[1].r.p) && (f[1].r.t < 3600)) ||
+        (f[1].r.t < 900) || (f[1].r.d < 900)) {
+        // ...and if noise decreases or the duplicate even field
+        // is detected, we go ahead with the merge.
+        if ((3*f[0].r.e < f[0].r.o) || (2*f[1].r.t < f[1].r.p)) {
+            p->dropnext = 1;
+            return F_MERGE;
+        }
+    }
+    return F_DROP;
+}
+
+
+
+static void copy_image(mp_image_t *dmpi, mp_image_t *mpi, int field)
+{
+    switch (field) {
+    case 0:
+        my_memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2,
+            dmpi->stride[0]*2, mpi->stride[0]*2);
+        if (mpi->flags & MP_IMGFLAG_PLANAR) {
+            my_memcpy_pic(dmpi->planes[1], mpi->planes[1],
+                mpi->chroma_width, mpi->chroma_height/2,
+                dmpi->stride[1]*2, mpi->stride[1]*2);
+            my_memcpy_pic(dmpi->planes[2], mpi->planes[2],
+                mpi->chroma_width, mpi->chroma_height/2,
+                dmpi->stride[2]*2, mpi->stride[2]*2);
+        }
+        break;
+    case 1:
+        my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0],
+            mpi->planes[0]+mpi->stride[0], mpi->w, mpi->h/2,
+            dmpi->stride[0]*2, mpi->stride[0]*2);
+        if (mpi->flags & MP_IMGFLAG_PLANAR) {
+            my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1],
+                mpi->planes[1]+mpi->stride[1],
+                mpi->chroma_width, mpi->chroma_height/2,
+                dmpi->stride[1]*2, mpi->stride[1]*2);
+            my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2],
+                mpi->planes[2]+mpi->stride[2],
+                mpi->chroma_width, mpi->chroma_height/2,
+                dmpi->stride[2]*2, mpi->stride[2]*2);
+        }
+        break;
+    case 2:
+        memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h,
+            dmpi->stride[0], mpi->stride[0]);
+        if (mpi->flags & MP_IMGFLAG_PLANAR) {
+            memcpy_pic(dmpi->planes[1], mpi->planes[1],
+                mpi->chroma_width, mpi->chroma_height,
+                dmpi->stride[1], mpi->stride[1]);
+            memcpy_pic(dmpi->planes[2], mpi->planes[2],
+                mpi->chroma_width, mpi->chroma_height,
+                dmpi->stride[2], mpi->stride[2]);
+        }
+        break;
+    }
+}
+
+static int do_put_image(struct vf_instance *vf, mp_image_t *dmpi)
+{
+    struct vf_priv_s *p = vf->priv;
+    int dropflag=0;
+
+    if (!p->dropnext) switch (p->drop) {
+    case 0:
+        dropflag = 0;
+        break;
+    case 1:
+        dropflag = (++p->lastdrop >= 5);
+        break;
+    case 2:
+        dropflag = (++p->lastdrop >= 5) && (4*p->inframes <= 5*p->outframes);
+        break;
+    }
+
+    if (dropflag) {
+        //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, "!");
+        p->lastdrop = 0;
+        return 0;
+    }
+
+    p->outframes++;
+    return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+    int ret=0;
+    struct vf_priv_s *p = vf->priv;
+
+    p->inframes++;
+
+    if (p->first) { /* hack */
+        p->first = 0;
+        return 1;
+    }
+
+    if (!p->dmpi) p->dmpi = 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 -- not correct, off by one frame! */
+    p->dmpi->qscale = mpi->qscale;
+    p->dmpi->qstride = mpi->qstride;
+    p->dmpi->qscale_type = mpi->qscale_type;
+
+    switch (foo(p, mpi, p->dmpi)) {
+    case F_DROP:
+        copy_image(p->dmpi, mpi, 2);
+        ret = 0;
+        p->lastdrop = 0;
+        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");
+        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");
+        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");
+        p->dmpi = NULL;
+        break;
+    }
+    return ret;
+}
+
+static int query_format(struct vf_instance *vf, unsigned int fmt)
+{
+    switch (fmt) {
+    case IMGFMT_YV12:
+    case IMGFMT_IYUV:
+    case IMGFMT_I420:
+        return vf_next_query_format(vf, fmt);
+    }
+    return 0;
+}
+
+static void uninit(struct vf_instance *vf)
+{
+    free(vf->priv);
+}
+
+static int vf_open(vf_instance_t *vf, char *args)
+{
+    struct vf_priv_s *p;
+    vf->put_image = put_image;
+    vf->query_format = query_format;
+    vf->uninit = uninit;
+    vf->default_reqs = VFCAP_ACCEPT_STRIDE;
+    vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
+    p->drop = 0;
+    p->first = 1;
+    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;
+#endif
+    return 1;
+}
+
+const vf_info_t vf_info_ivtc = {
+    "inverse telecine, take 2",
+    "ivtc",
+    "Rich Felker",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_kerndeint.c b/libavfilter/libmpcodecs/vf_kerndeint.c
new file mode 100644
index 0000000..c5197fc
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_kerndeint.c
@@ -0,0 +1,345 @@
+/*
+ * 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
new file mode 100644
index 0000000..01a3cb3
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_mcdeint.c
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+/*
+Known Issues:
+* The motion estimation is somewhat at the mercy of the input, if the input
+  frames are created purely based on spatial interpolation then for example
+  a thin black line or another random and not interpolateable pattern
+  will cause problems
+  Note: completly ignoring the "unavailable" lines during motion estimation
+  didnt look any better, so the most obvious solution would be to improve
+  tfields or penalize problematic motion vectors ...
+
+* If non iterative ME is used then snow currently ignores the OBMC window
+  and as a result sometimes creates artifacts
+
+* only past frames are used, we should ideally use future frames too, something
+  like filtering the whole movie in forward and then backward direction seems
+  like a interresting idea but the current filter framework is FAR from
+  supporting such things
+
+* combining the motion compensated image with the input image also isnt
+  as trivial as it seems, simple blindly taking even lines from one and
+  odd ones from the other doesnt work at all as ME/MC sometimes simple
+  has nothing in the previous frames which matches the current, the current
+  algo has been found by trial and error and almost certainly can be
+  improved ...
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <math.h>
+
+#include "mp_msg.h"
+#include "cpudetect.h"
+
+#include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavcodec/avcodec.h"
+#include "libavcodec/dsputil.h"
+
+#undef fprintf
+#undef free
+#undef malloc
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+#include "vd_ffmpeg.h"
+
+#define MIN(a,b) ((a) > (b) ? (b) : (a))
+#define MAX(a,b) ((a) < (b) ? (b) : (a))
+#define ABS(a) ((a) > 0 ? (a) : (-(a)))
+
+//===========================================================================//
+
+struct vf_priv_s {
+    int mode;
+    int qp;
+    int parity;
+#if 0
+    int temp_stride[3];
+    uint8_t *src[3];
+    int16_t *temp[3];
+#endif
+    int outbuf_size;
+    uint8_t *outbuf;
+    AVCodecContext *avctx_enc;
+    AVFrame *frame;
+    AVFrame *frame_dec;
+};
+
+static void filter(struct vf_priv_s *p, uint8_t *dst[3], uint8_t *src[3], int dst_stride[3], int src_stride[3], int width, int height){
+    int x, y, i;
+
+    for(i=0; i<3; i++){
+        p->frame->data[i]= src[i];
+        p->frame->linesize[i]= src_stride[i];
+    }
+
+    p->avctx_enc->me_cmp=
+    p->avctx_enc->me_sub_cmp= FF_CMP_SAD /*| (p->parity ? FF_CMP_ODD : FF_CMP_EVEN)*/;
+    p->frame->quality= p->qp*FF_QP2LAMBDA;
+    avcodec_encode_video(p->avctx_enc, p->outbuf, p->outbuf_size, p->frame);
+    p->frame_dec = p->avctx_enc->coded_frame;
+
+    for(i=0; i<3; i++){
+        int is_chroma= !!i;
+        int w= width >>is_chroma;
+        int h= height>>is_chroma;
+        int fils= p->frame_dec->linesize[i];
+        int srcs= src_stride[i];
+
+        for(y=0; y<h; y++){
+            if((y ^ p->parity) & 1){
+                for(x=0; x<w; x++){
+                    if((x-2)+(y-1)*w>=0 && (x+2)+(y+1)*w<w*h){ //FIXME either alloc larger images or optimize this
+                        uint8_t *filp= &p->frame_dec->data[i][x + y*fils];
+                        uint8_t *srcp= &src[i][x + y*srcs];
+                        int diff0= filp[-fils] - srcp[-srcs];
+                        int diff1= filp[+fils] - srcp[+srcs];
+                        int spatial_score= ABS(srcp[-srcs-1] - srcp[+srcs-1])
+                                          +ABS(srcp[-srcs  ] - srcp[+srcs  ])
+                                          +ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
+                        int temp= filp[0];
+
+#define CHECK(j)\
+    {   int score= ABS(srcp[-srcs-1+(j)] - srcp[+srcs-1-(j)])\
+                 + ABS(srcp[-srcs  +(j)] - srcp[+srcs  -(j)])\
+                 + ABS(srcp[-srcs+1+(j)] - srcp[+srcs+1-(j)]);\
+        if(score < spatial_score){\
+            spatial_score= score;\
+            diff0= filp[-fils+(j)] - srcp[-srcs+(j)];\
+            diff1= filp[+fils-(j)] - srcp[+srcs-(j)];
+
+                        CHECK(-1) CHECK(-2) }} }}
+                        CHECK( 1) CHECK( 2) }} }}
+#if 0
+                        if((diff0 ^ diff1) > 0){
+                            int mindiff= ABS(diff0) > ABS(diff1) ? diff1 : diff0;
+                            temp-= mindiff;
+                        }
+#elif 1
+                        if(diff0 + diff1 > 0)
+                            temp-= (diff0 + diff1 - ABS( ABS(diff0) - ABS(diff1) )/2)/2;
+                        else
+                            temp-= (diff0 + diff1 + ABS( ABS(diff0) - ABS(diff1) )/2)/2;
+#else
+                        temp-= (diff0 + diff1)/2;
+#endif
+#if 1
+                        filp[0]=
+                        dst[i][x + y*dst_stride[i]]= temp > 255U ? ~(temp>>31) : temp;
+#else
+                        dst[i][x + y*dst_stride[i]]= filp[0];
+                        filp[0]= temp > 255U ? ~(temp>>31) : temp;
+#endif
+                    }else
+                        dst[i][x + y*dst_stride[i]]= p->frame_dec->data[i][x + y*fils];
+                }
+            }
+        }
+        for(y=0; y<h; y++){
+            if(!((y ^ p->parity) & 1)){
+                for(x=0; x<w; x++){
+#if 1
+                    p->frame_dec->data[i][x + y*fils]=
+                    dst[i][x + y*dst_stride[i]]= src[i][x + y*srcs];
+#else
+                    dst[i][x + y*dst_stride[i]]= p->frame_dec->data[i][x + y*fils];
+                    p->frame_dec->data[i][x + y*fils]= src[i][x + y*srcs];
+#endif
+                }
+            }
+        }
+    }
+    p->parity ^= 1;
+
+}
+
+static int config(struct vf_instance *vf,
+        int width, int height, int d_width, int d_height,
+        unsigned int flags, unsigned int outfmt){
+        int i;
+        AVCodec *enc= avcodec_find_encoder(AV_CODEC_ID_SNOW);
+
+        for(i=0; i<3; i++){
+            AVCodecContext *avctx_enc;
+#if 0
+            int is_chroma= !!i;
+            int w= ((width  + 31) & (~31))>>is_chroma;
+            int h= ((height + 31) & (~31))>>is_chroma;
+
+            vf->priv->temp_stride[i]= w;
+            vf->priv->temp[i]= malloc(vf->priv->temp_stride[i]*h*sizeof(int16_t));
+            vf->priv->src [i]= malloc(vf->priv->temp_stride[i]*h*sizeof(uint8_t));
+#endif
+            avctx_enc=
+            vf->priv->avctx_enc= avcodec_alloc_context();
+            avctx_enc->width = width;
+            avctx_enc->height = height;
+            avctx_enc->time_base= (AVRational){1,25};  // meaningless
+            avctx_enc->gop_size = 300;
+            avctx_enc->max_b_frames= 0;
+            avctx_enc->pix_fmt = AV_PIX_FMT_YUV420P;
+            avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
+            avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
+            avctx_enc->global_quality= 1;
+            avctx_enc->flags2= CODEC_FLAG2_MEMC_ONLY;
+            avctx_enc->me_cmp=
+            avctx_enc->me_sub_cmp= FF_CMP_SAD; //SSE;
+            avctx_enc->mb_cmp= FF_CMP_SSE;
+
+            switch(vf->priv->mode){
+            case 3:
+                avctx_enc->refs= 3;
+            case 2:
+                avctx_enc->me_method= ME_ITER;
+            case 1:
+                avctx_enc->flags |= CODEC_FLAG_4MV;
+                avctx_enc->dia_size=2;
+//                avctx_enc->mb_decision = MB_DECISION_RD;
+            case 0:
+                avctx_enc->flags |= CODEC_FLAG_QPEL;
+            }
+
+            avcodec_open(avctx_enc, enc);
+
+        }
+        vf->priv->frame= avcodec_alloc_frame();
+
+        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);
+}
+
+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,
+        mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height);
+    mpi->planes[0]=vf->dmpi->planes[0];
+    mpi->stride[0]=vf->dmpi->stride[0];
+    mpi->width=vf->dmpi->width;
+    if(mpi->flags&MP_IMGFLAG_PLANAR){
+        mpi->planes[1]=vf->dmpi->planes[1];
+        mpi->planes[2]=vf->dmpi->planes[2];
+        mpi->stride[1]=vf->dmpi->stride[1];
+        mpi->stride[2]=vf->dmpi->stride[2];
+    }
+    mpi->flags|=MP_IMGFLAG_DIRECT;
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+    mp_image_t *dmpi;
+
+    if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
+        // no DR, so get a new image! hope we'll get DR buffer:
+        dmpi=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);
+    }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);
+}
+
+static void uninit(struct vf_instance *vf){
+    if(!vf->priv) return;
+
+#if 0
+    for(i=0; i<3; i++){
+        free(vf->priv->temp[i]);
+        vf->priv->temp[i]= NULL;
+        free(vf->priv->src[i]);
+        vf->priv->src[i]= NULL;
+    }
+#endif
+    if (vf->priv->avctx_enc) {
+    avcodec_close(vf->priv->avctx_enc);
+    av_freep(&vf->priv->avctx_enc);
+    }
+
+    free(vf->priv->outbuf);
+    free(vf->priv);
+    vf->priv=NULL;
+}
+
+//===========================================================================//
+static int query_format(struct vf_instance *vf, unsigned int fmt){
+    switch(fmt){
+        case IMGFMT_YV12:
+        case IMGFMT_I420:
+        case IMGFMT_IYUV:
+        case IMGFMT_Y800:
+        case IMGFMT_Y8:
+            return vf_next_query_format(vf,fmt);
+    }
+    return 0;
+}
+
+static int vf_open(vf_instance_t *vf, char *args){
+
+    vf->config=config;
+    vf->put_image=put_image;
+    vf->get_image=get_image;
+    vf->query_format=query_format;
+    vf->uninit=uninit;
+    vf->priv=malloc(sizeof(struct vf_priv_s));
+    memset(vf->priv, 0, sizeof(struct vf_priv_s));
+
+    init_avcodec();
+
+    vf->priv->mode=0;
+    vf->priv->parity= -1;
+    vf->priv->qp=1;
+
+    if (args) sscanf(args, "%d:%d:%d", &vf->priv->mode, &vf->priv->parity, &vf->priv->qp);
+
+    return 1;
+}
+
+const vf_info_t vf_info_mcdeint = {
+    "motion compensating deinterlacer",
+    "mcdeint",
+    "Michael Niedermayer",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_noise.c b/libavfilter/libmpcodecs/vf_noise.c
new file mode 100644
index 0000000..9521619
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_noise.c
@@ -0,0 +1,474 @@
+/*
+ * 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 <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/mem.h"
+
+#define MAX_NOISE 4096
+#define MAX_SHIFT 1024
+#define MAX_RES (MAX_NOISE-MAX_SHIFT)
+
+//===========================================================================//
+
+static inline void lineNoise_C(uint8_t *dst, uint8_t *src, int8_t *noise, int len, int shift);
+static inline void lineNoiseAvg_C(uint8_t *dst, uint8_t *src, int len, int8_t **shift);
+
+static void (*lineNoise)(uint8_t *dst, uint8_t *src, int8_t *noise, int len, int shift)= lineNoise_C;
+static void (*lineNoiseAvg)(uint8_t *dst, uint8_t *src, int len, int8_t **shift)= lineNoiseAvg_C;
+
+typedef struct FilterParam{
+        int strength;
+        int uniform;
+        int temporal;
+        int quality;
+        int averaged;
+        int pattern;
+        int shiftptr;
+        int8_t *noise;
+        int8_t *prev_shift[MAX_RES][3];
+}FilterParam;
+
+struct vf_priv_s {
+        FilterParam lumaParam;
+        FilterParam chromaParam;
+        unsigned int outfmt;
+};
+
+static int nonTempRandShift_init;
+static int nonTempRandShift[MAX_RES];
+
+static int patt[4] = {
+    -1,0,1,0
+};
+
+#define RAND_N(range) ((int) ((double)range*rand()/(RAND_MAX+1.0)))
+static int8_t *initNoise(FilterParam *fp){
+        int strength= fp->strength;
+        int uniform= fp->uniform;
+        int averaged= fp->averaged;
+        int pattern= fp->pattern;
+        int8_t *noise= av_malloc(MAX_NOISE*sizeof(int8_t));
+        int i, j;
+
+        srand(123457);
+
+        for(i=0,j=0; i<MAX_NOISE; i++,j++)
+        {
+                if(uniform) {
+                        if (averaged) {
+                                    if (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 (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 * rand()/(float)RAND_MAX - 1.0;
+                                x2 = 2.0 * rand()/(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 (pattern) {
+                            y1 /= 2;
+                            y1 += patt[j%4]*strength*0.35;
+                        }
+                        if     (y1<-128) y1=-128;
+                        else if(y1> 127) y1= 127;
+                        if (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 + (rand()&(MAX_SHIFT-1));
+
+        if(!nonTempRandShift_init){
+                for(i=0; i<MAX_RES; i++){
+                        nonTempRandShift[i]= rand()&(MAX_SHIFT-1);
+                }
+                nonTempRandShift_init = 1;
+        }
+
+        fp->noise= noise;
+        fp->shiftptr= 0;
+        return noise;
+}
+
+/***************************************************************************/
+
+#if HAVE_MMX
+static inline void lineNoise_MMX(uint8_t *dst, uint8_t *src, int8_t *noise, int len, int shift){
+        x86_reg mmx_len= len&(~7);
+        noise+=shift;
+
+        __asm__ volatile(
+                "mov %3, %%"REG_a"                \n\t"
+                "pcmpeqb %%mm7, %%mm7                \n\t"
+                "psllw $15, %%mm7                \n\t"
+                "packsswb %%mm7, %%mm7                \n\t"
+                ASMALIGN(4)
+                "1:                                \n\t"
+                "movq (%0, %%"REG_a"), %%mm0        \n\t"
+                "movq (%1, %%"REG_a"), %%mm1        \n\t"
+                "pxor %%mm7, %%mm0                \n\t"
+                "paddsb %%mm1, %%mm0                \n\t"
+                "pxor %%mm7, %%mm0                \n\t"
+                "movq %%mm0, (%2, %%"REG_a")        \n\t"
+                "add $8, %%"REG_a"                \n\t"
+                " js 1b                                \n\t"
+                :: "r" (src+mmx_len), "r" (noise+mmx_len), "r" (dst+mmx_len), "g" (-mmx_len)
+                : "%"REG_a
+        );
+        if(mmx_len!=len)
+                lineNoise_C(dst+mmx_len, src+mmx_len, noise+mmx_len, len-mmx_len, 0);
+}
+#endif
+
+//duplicate of previous except movntq
+#if HAVE_MMX2
+static inline void lineNoise_MMX2(uint8_t *dst, uint8_t *src, int8_t *noise, int len, int shift){
+        x86_reg mmx_len= len&(~7);
+        noise+=shift;
+
+        __asm__ volatile(
+                "mov %3, %%"REG_a"                \n\t"
+                "pcmpeqb %%mm7, %%mm7                \n\t"
+                "psllw $15, %%mm7                \n\t"
+                "packsswb %%mm7, %%mm7                \n\t"
+                ASMALIGN(4)
+                "1:                                \n\t"
+                "movq (%0, %%"REG_a"), %%mm0        \n\t"
+                "movq (%1, %%"REG_a"), %%mm1        \n\t"
+                "pxor %%mm7, %%mm0                \n\t"
+                "paddsb %%mm1, %%mm0                \n\t"
+                "pxor %%mm7, %%mm0                \n\t"
+                "movntq %%mm0, (%2, %%"REG_a")        \n\t"
+                "add $8, %%"REG_a"                \n\t"
+                " js 1b                                \n\t"
+                :: "r" (src+mmx_len), "r" (noise+mmx_len), "r" (dst+mmx_len), "g" (-mmx_len)
+                : "%"REG_a
+        );
+        if(mmx_len!=len)
+                lineNoise_C(dst+mmx_len, src+mmx_len, noise+mmx_len, len-mmx_len, 0);
+}
+#endif
+
+static inline void lineNoise_C(uint8_t *dst, 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];
+                if(v>255)         dst[i]=255; //FIXME optimize
+                else if(v<0)         dst[i]=0;
+                else                dst[i]=v;
+        }
+}
+
+/***************************************************************************/
+
+#if HAVE_MMX
+static inline void lineNoiseAvg_MMX(uint8_t *dst, uint8_t *src, int len, int8_t **shift){
+        x86_reg mmx_len= len&(~7);
+
+        __asm__ volatile(
+                "mov %5, %%"REG_a"                \n\t"
+                ASMALIGN(4)
+                "1:                                \n\t"
+                "movq (%1, %%"REG_a"), %%mm1        \n\t"
+                "movq (%0, %%"REG_a"), %%mm0        \n\t"
+                "paddb (%2, %%"REG_a"), %%mm1        \n\t"
+                "paddb (%3, %%"REG_a"), %%mm1        \n\t"
+                "movq %%mm0, %%mm2                \n\t"
+                "movq %%mm1, %%mm3                \n\t"
+                "punpcklbw %%mm0, %%mm0                \n\t"
+                "punpckhbw %%mm2, %%mm2                \n\t"
+                "punpcklbw %%mm1, %%mm1                \n\t"
+                "punpckhbw %%mm3, %%mm3                \n\t"
+                "pmulhw %%mm0, %%mm1                \n\t"
+                "pmulhw %%mm2, %%mm3                \n\t"
+                "paddw %%mm1, %%mm1                \n\t"
+                "paddw %%mm3, %%mm3                \n\t"
+                "paddw %%mm0, %%mm1                \n\t"
+                "paddw %%mm2, %%mm3                \n\t"
+                "psrlw $8, %%mm1                \n\t"
+                "psrlw $8, %%mm3                \n\t"
+                "packuswb %%mm3, %%mm1                \n\t"
+                "movq %%mm1, (%4, %%"REG_a")        \n\t"
+                "add $8, %%"REG_a"                \n\t"
+                " js 1b                                \n\t"
+                :: "r" (src+mmx_len), "r" (shift[0]+mmx_len), "r" (shift[1]+mmx_len), "r" (shift[2]+mmx_len),
+                   "r" (dst+mmx_len), "g" (-mmx_len)
+                : "%"REG_a
+        );
+
+        if(mmx_len!=len){
+                int8_t *shift2[3]={shift[0]+mmx_len, shift[1]+mmx_len, shift[2]+mmx_len};
+                lineNoiseAvg_C(dst+mmx_len, src+mmx_len, len-mmx_len, shift2);
+        }
+}
+#endif
+
+static inline void lineNoiseAvg_C(uint8_t *dst, 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, uint8_t *src, int dstStride, int srcStride, int width, int height, FilterParam *fp){
+        int8_t *noise= fp->noise;
+        int y;
+        int shift=0;
+
+        if(!noise)
+        {
+                if(src==dst) return;
+
+                if(dstStride==srcStride) fast_memcpy(dst, src, srcStride*height);
+                else
+                {
+                        for(y=0; y<height; y++)
+                        {
+                                fast_memcpy(dst, src, width);
+                                dst+= dstStride;
+                                src+= srcStride;
+                        }
+                }
+                return;
+        }
+
+        for(y=0; y<height; y++)
+        {
+                if(fp->temporal)        shift=  rand()&(MAX_SHIFT  -1);
+                else                        shift= nonTempRandShift[y];
+
+                if(fp->quality==0) shift&= ~7;
+                if (fp->averaged) {
+                    lineNoiseAvg(dst, src, width, fp->prev_shift[y]);
+                    fp->prev_shift[y][fp->shiftptr] = noise + shift;
+                } else {
+                    lineNoise(dst, src, noise, width, shift);
+                }
+                dst+= dstStride;
+                src+= srcStride;
+        }
+        fp->shiftptr++;
+        if (fp->shiftptr == 3) fp->shiftptr = 0;
+}
+
+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 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,
+        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);
+//printf("nodr\n");
+        }
+//else printf("dr\n");
+        dmpi= vf->dmpi;
+
+        noise(dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, &vf->priv->lumaParam);
+        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);
+
+#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){
+        if(!vf->priv) return;
+
+        av_free(vf->priv->chromaParam.noise);
+        vf->priv->chromaParam.noise= NULL;
+
+        av_free(vf->priv->lumaParam.noise);
+        vf->priv->lumaParam.noise= 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){
+        char *pos;
+        char *max= strchr(args, ':');
+
+        if(!max) max= args + strlen(args);
+
+        fp->strength= atoi(args);
+        pos= strchr(args, 'u');
+        if(pos && pos<max) fp->uniform=1;
+        pos= strchr(args, 't');
+        if(pos && pos<max) fp->temporal=1;
+        pos= strchr(args, 'h');
+        if(pos && pos<max) fp->quality=1;
+        pos= strchr(args, 'p');
+        if(pos && pos<max) fp->pattern=1;
+        pos= strchr(args, 'a');
+        if(pos && pos<max) {
+            fp->temporal=1;
+            fp->averaged=1;
+        }
+
+        if(fp->strength) initNoise(fp);
+}
+
+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 *arg2= strchr(args,':');
+        if(arg2) parse(&vf->priv->chromaParam, arg2+1);
+        parse(&vf->priv->lumaParam, args);
+    }
+
+    // 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 :(
+    }
+
+
+#if HAVE_MMX
+    if(gCpuCaps.hasMMX){
+        lineNoise= lineNoise_MMX;
+        lineNoiseAvg= lineNoiseAvg_MMX;
+    }
+#endif
+#if HAVE_MMX2
+    if(gCpuCaps.hasMMX2) lineNoise= lineNoise_MMX2;
+//    if(gCpuCaps.hasMMX) lineNoiseAvg= lineNoiseAvg_MMX2;
+#endif
+
+    return 1;
+}
+
+const vf_info_t vf_info_noise = {
+    "noise generator",
+    "noise",
+    "Michael Niedermayer",
+    "",
+    vf_open,
+    NULL
+};
+
+//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vf_ow.c b/libavfilter/libmpcodecs/vf_ow.c
new file mode 100644
index 0000000..f7fb02d
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_ow.c
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * @todo try to change to int
+ * @todo try lifting based implementation
+ * @todo optimize optimize optimize
+ * @todo hard tresholding
+ * @todo use QP to decide filter strength
+ * @todo wavelet normalization / least squares optimal signal vs. noise thresholds
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <math.h>
+
+#include "mp_msg.h"
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+//===========================================================================//
+static const uint8_t  __attribute__((aligned(8))) dither[8][8]={
+{  0,  48,  12,  60,   3,  51,  15,  63, },
+{ 32,  16,  44,  28,  35,  19,  47,  31, },
+{  8,  56,   4,  52,  11,  59,   7,  55, },
+{ 40,  24,  36,  20,  43,  27,  39,  23, },
+{  2,  50,  14,  62,   1,  49,  13,  61, },
+{ 34,  18,  46,  30,  33,  17,  45,  29, },
+{ 10,  58,   6,  54,   9,  57,   5,  53, },
+{ 42,  26,  38,  22,  41,  25,  37,  21, },
+};
+//FIXME the above is duplicated in many filters
+
+struct vf_priv_s {
+    float strength[2];
+    float delta;
+    int mode;
+    int depth;
+    float *plane[16][4];
+    int stride;
+};
+
+#define S 1.41421356237 //sqrt(2)
+
+static const double coeff[2][5]={
+    {
+         0.6029490182363579  *S,
+         0.2668641184428723  *S,
+        -0.07822326652898785 *S,
+        -0.01686411844287495 *S,
+         0.02674875741080976 *S
+    },{
+         1.115087052456994   /S,
+        -0.5912717631142470  /S,
+        -0.05754352622849957 /S,
+         0.09127176311424948 /S
+    }
+};
+
+static const double icoeff[2][5]={
+    {
+         1.115087052456994   /S,
+         0.5912717631142470  /S,
+        -0.05754352622849957 /S,
+        -0.09127176311424948 /S
+    },{
+         0.6029490182363579  *S,
+        -0.2668641184428723  *S,
+        -0.07822326652898785 *S,
+         0.01686411844287495 *S,
+         0.02674875741080976 *S
+    }
+};
+#undef S
+
+static inline int mirror(int x, int w){
+    while((unsigned)x > (unsigned)w){
+        x=-x;
+        if(x<0) x+= 2*w;
+    }
+    return x;
+}
+
+static inline void decompose(float *dstL, float *dstH, float *src, int stride, int w){
+    int x, i;
+    for(x=0; x<w; x++){
+        double sumL= src[x*stride] * coeff[0][0];
+        double sumH= src[x*stride] * coeff[1][0];
+        for(i=1; i<=4; i++){
+            double s= (src[mirror(x-i, w-1)*stride] + src[mirror(x+i, w-1)*stride]);
+
+            sumL+= coeff[0][i]*s;
+            sumH+= coeff[1][i]*s;
+        }
+        dstL[x*stride]= sumL;
+        dstH[x*stride]= sumH;
+    }
+}
+
+static inline void compose(float *dst, float *srcL, float *srcH, int stride, int w){
+    int x, i;
+    for(x=0; x<w; x++){
+        double sumL= srcL[x*stride] * icoeff[0][0];
+        double sumH= srcH[x*stride] * icoeff[1][0];
+        for(i=1; i<=4; i++){
+            int x0= mirror(x-i, w-1)*stride;
+            int x1= mirror(x+i, w-1)*stride;
+
+            sumL+= icoeff[0][i]*(srcL[x0] + srcL[x1]);
+            sumH+= icoeff[1][i]*(srcH[x0] + srcH[x1]);
+        }
+        dst[x*stride]= (sumL + sumH)*0.5;
+    }
+}
+
+static inline void decompose2D(float *dstL, float *dstH, float *src, int xstride, int ystride, int step, int w, int h){
+    int y, x;
+    for(y=0; y<h; y++)
+        for(x=0; x<step; x++)
+            decompose(dstL + ystride*y + xstride*x, dstH + ystride*y + xstride*x, src + ystride*y + xstride*x, step*xstride, (w-x+step-1)/step);
+}
+
+static inline void compose2D(float *dst, float *srcL, float *srcH, int xstride, int ystride, int step, int w, int h){
+    int y, x;
+    for(y=0; y<h; y++)
+        for(x=0; x<step; x++)
+            compose(dst + ystride*y + xstride*x, srcL + ystride*y + xstride*x, srcH + ystride*y + xstride*x, step*xstride, (w-x+step-1)/step);
+}
+
+static void decompose2D2(float *dst[4], float *src, float *temp[2], int stride, int step, int w, int h){
+    decompose2D(temp[0], temp[1], src    , 1, stride, step  , w, h);
+    decompose2D( dst[0],  dst[1], temp[0], stride, 1, step  , h, w);
+    decompose2D( dst[2],  dst[3], temp[1], stride, 1, step  , h, w);
+}
+
+static void compose2D2(float *dst, float *src[4], float *temp[2], int stride, int step, int w, int h){
+    compose2D(temp[0],  src[0],  src[1], stride, 1, step  , h, w);
+    compose2D(temp[1],  src[2],  src[3], stride, 1, step  , h, w);
+    compose2D(dst    , temp[0], temp[1], 1, stride, step  , w, h);
+}
+
+static void filter(struct vf_priv_s *p, uint8_t *dst, uint8_t *src, int dst_stride, int src_stride, int width, int height, int is_luma){
+    int x,y, i, j;
+//    double sum=0;
+    double s= p->strength[!is_luma];
+    int depth= p->depth;
+
+    while(1<<depth > width || 1<<depth > height)
+        depth--;
+
+    for(y=0; y<height; y++)
+        for(x=0; x<width; x++)
+            p->plane[0][0][x + y*p->stride]= src[x + y*src_stride];
+
+    for(i=0; i<depth; i++){
+        decompose2D2(p->plane[i+1], p->plane[i][0], p->plane[0]+1,p->stride, 1<<i, width, height);
+    }
+    for(i=0; i<depth; i++){
+        for(j=1; j<4; j++){
+            for(y=0; y<height; y++){
+                for(x=0; x<width; x++){
+                    double v= p->plane[i+1][j][x + y*p->stride];
+                    if     (v> s) v-=s;
+                    else if(v<-s) v+=s;
+                    else          v =0;
+                    p->plane[i+1][j][x + y*p->stride]= v;
+                }
+            }
+        }
+    }
+    for(i=depth-1; i>=0; i--){
+        compose2D2(p->plane[i][0], p->plane[i+1], p->plane[0]+1, p->stride, 1<<i, width, height);
+    }
+
+    for(y=0; y<height; y++)
+        for(x=0; x<width; x++){
+            i= p->plane[0][0][x + y*p->stride] + dither[x&7][y&7]*(1.0/64) + 1.0/128; //yes the rounding is insane but optimal :)
+//            double e= i - src[x + y*src_stride];
+//            sum += e*e;
+            if((unsigned)i > 255U) i= ~(i>>31);
+            dst[x + y*dst_stride]= i;
+        }
+
+//    printf("%f\n", sum/height/width);
+}
+
+static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt){
+    int h= (height+15)&(~15);
+    int i,j;
+
+    vf->priv->stride= (width+15)&(~15);
+    for(j=0; j<4; j++){
+        for(i=0; i<=vf->priv->depth; i++)
+            vf->priv->plane[i][j]= malloc(vf->priv->stride*h*sizeof(vf->priv->plane[0][0][0]));
+    }
+
+    return 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,
+        mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height);
+    mpi->planes[0]=vf->dmpi->planes[0];
+    mpi->stride[0]=vf->dmpi->stride[0];
+    mpi->width=vf->dmpi->width;
+    if(mpi->flags&MP_IMGFLAG_PLANAR){
+        mpi->planes[1]=vf->dmpi->planes[1];
+        mpi->planes[2]=vf->dmpi->planes[2];
+        mpi->stride[1]=vf->dmpi->stride[1];
+        mpi->stride[2]=vf->dmpi->stride[2];
+    }
+    mpi->flags|=MP_IMGFLAG_DIRECT;
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+    mp_image_t *dmpi;
+
+    if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
+        // no DR, so get a new image! hope we'll get DR buffer:
+        dmpi=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);
+    }else{
+        dmpi=vf->dmpi;
+    }
+
+    filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, 1);
+    filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, 0);
+    filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, 0);
+
+    return vf_next_put_image(vf,dmpi, pts);
+}
+
+static void uninit(struct vf_instance *vf){
+    int i,j;
+    if(!vf->priv) return;
+
+    for(j=0; j<4; j++){
+        for(i=0; i<16; i++){
+            free(vf->priv->plane[i][j]);
+            vf->priv->plane[i][j]= NULL;
+        }
+    }
+
+    free(vf->priv);
+    vf->priv=NULL;
+}
+
+//===========================================================================//
+static int query_format(struct vf_instance *vf, unsigned int fmt){
+    switch(fmt){
+        case IMGFMT_YVU9:
+        case IMGFMT_IF09:
+        case IMGFMT_YV12:
+        case IMGFMT_I420:
+        case IMGFMT_IYUV:
+        case IMGFMT_CLPL:
+        case IMGFMT_Y800:
+        case IMGFMT_Y8:
+        case IMGFMT_444P:
+        case IMGFMT_422P:
+        case IMGFMT_411P:
+            return vf_next_query_format(vf,fmt);
+    }
+    return 0;
+}
+
+
+static int vf_open(vf_instance_t *vf, char *args){
+    vf->config=config;
+    vf->put_image=put_image;
+    vf->get_image=get_image;
+    vf->query_format=query_format;
+    vf->uninit=uninit;
+    vf->priv=malloc(sizeof(struct vf_priv_s));
+    memset(vf->priv, 0, sizeof(struct vf_priv_s));
+
+    vf->priv->depth= 8;
+    vf->priv->strength[0]= 1.0;
+    vf->priv->strength[1]= 1.0;
+    vf->priv->delta= 1.0;
+
+    if (args) sscanf(args, "%d:%f:%f:%d:%f", &vf->priv->depth,
+                     &vf->priv->strength[0],
+                     &vf->priv->strength[1],
+                     &vf->priv->mode,
+                     &vf->priv->delta);
+
+    return 1;
+}
+
+const vf_info_t vf_info_ow = {
+    "overcomplete wavelet denoiser",
+    "ow",
+    "Michael Niedermayer",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_palette.c b/libavfilter/libmpcodecs/vf_palette.c
new file mode 100644
index 0000000..543b6c7
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_palette.c
@@ -0,0 +1,236 @@
+/*
+ * 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 <inttypes.h>
+
+#include "config.h"
+#include "mp_msg.h"
+#include "help_mp.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+#include "mpbswap.h"
+
+#include "libswscale/swscale.h"
+
+#include "libavutil/avstring.h"
+
+//===========================================================================//
+
+// commented out 16 and 15 bit output support, because the conversion
+// routines are incorrrect.  they assume the palette to be of the same
+// depth as the output, which is incorrect. --Joey
+
+static const unsigned int bgr_list[]={
+    IMGFMT_BGR32,
+    IMGFMT_BGR24,
+//    IMGFMT_BGR16,
+//    IMGFMT_BGR15,
+    0
+};
+static const unsigned int rgb_list[]={
+    IMGFMT_RGB32,
+    IMGFMT_RGB24,
+//    IMGFMT_RGB16,
+//    IMGFMT_RGB15,
+    0
+};
+
+/**
+ * Palette is assumed to contain BGR16, see rgb32to16 to convert the palette.
+ */
+static void palette8torgb16(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
+{
+    long i;
+    for (i=0; i<num_pixels; i++)
+        ((uint16_t *)dst)[i] = ((const uint16_t *)palette)[src[i]];
+}
+
+static void palette8tobgr16(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)
+{
+    long i;
+    for (i=0; i<num_pixels; i++)
+        ((uint16_t *)dst)[i] = bswap_16(((const uint16_t *)palette)[src[i]]);
+}
+
+static unsigned int gray_pal[256];
+
+static unsigned int find_best(struct vf_instance *vf, unsigned int fmt){
+    unsigned int best=0;
+    int ret;
+    const unsigned int* p;
+    if(fmt==IMGFMT_BGR8) p=bgr_list;
+    else if(fmt==IMGFMT_RGB8) p=rgb_list;
+    else return 0;
+    while(*p){
+        ret=vf->next->query_format(vf->next,*p);
+        mp_msg(MSGT_VFILTER,MSGL_DBG2,"[%s] query(%s) -> %d\n",vf->info->name,vo_format_name(*p),ret&3);
+        if(ret&VFCAP_CSP_SUPPORTED_BY_HW){ best=*p; break;} // no conversion -> bingo!
+        if(ret&VFCAP_CSP_SUPPORTED && !best) best=*p; // best with conversion
+        ++p;
+    }
+    return best;
+}
+
+//===========================================================================//
+
+struct vf_priv_s {
+    unsigned int fmt;
+    int pal_msg;
+};
+
+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->fmt)
+        vf->priv->fmt=find_best(vf,outfmt);
+    if(!vf->priv->fmt){
+        // no matching fmt, so force one...
+        if(outfmt==IMGFMT_RGB8) vf->priv->fmt=IMGFMT_RGB32;
+        else if(outfmt==IMGFMT_BGR8) vf->priv->fmt=IMGFMT_BGR32;
+        else return 0;
+    }
+    return vf_next_config(vf,width,height,d_width,d_height,flags,vf->priv->fmt);
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+    mp_image_t *dmpi;
+    uint8_t *old_palette = mpi->planes[1];
+
+    // hope we'll get DR buffer:
+    dmpi=vf_get_image(vf->next,vf->priv->fmt,
+        MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
+        mpi->w, mpi->h);
+
+    if (!mpi->planes[1])
+    {
+        if(!vf->priv->pal_msg){
+            mp_msg(MSGT_VFILTER,MSGL_V,"[%s] no palette given, assuming builtin grayscale one\n",vf->info->name);
+            vf->priv->pal_msg=1;
+        }
+        mpi->planes[1] = (unsigned char*)gray_pal;
+    }
+
+    if(mpi->w==mpi->stride[0] && dmpi->w*(dmpi->bpp>>3)==dmpi->stride[0]){
+        // no stride conversion needed
+        switch(IMGFMT_RGB_DEPTH(dmpi->imgfmt)){
+        case 15:
+        case 16:
+            if (IMGFMT_IS_BGR(dmpi->imgfmt))
+                palette8tobgr16(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]);
+            else
+                palette8torgb16(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]);
+            break;
+        case 24:
+            if (IMGFMT_IS_BGR(dmpi->imgfmt))
+                sws_convertPalette8ToPacked24(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]);
+            else
+                sws_convertPalette8ToPacked24(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]);
+            break;
+        case 32:
+            if (IMGFMT_IS_BGR(dmpi->imgfmt))
+                sws_convertPalette8ToPacked32(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]);
+            else
+                sws_convertPalette8ToPacked32(mpi->planes[0],dmpi->planes[0],mpi->h*mpi->w,mpi->planes[1]);
+            break;
+        }
+    } else {
+        int y;
+        for(y=0;y<mpi->h;y++){
+            unsigned char* src=mpi->planes[0]+y*mpi->stride[0];
+            unsigned char* dst=dmpi->planes[0]+y*dmpi->stride[0];
+            switch(IMGFMT_RGB_DEPTH(dmpi->imgfmt)){
+            case 15:
+            case 16:
+                if (IMGFMT_IS_BGR(dmpi->imgfmt))
+                    palette8tobgr16(src,dst,mpi->w,mpi->planes[1]);
+                else
+                    palette8torgb16(src,dst,mpi->w,mpi->planes[1]);
+                break;
+            case 24:
+                if (IMGFMT_IS_BGR(dmpi->imgfmt))
+                    sws_convertPalette8ToPacked24(src,dst,mpi->w,mpi->planes[1]);
+                else
+                    sws_convertPalette8ToPacked24(src,dst,mpi->w,mpi->planes[1]);
+                break;
+            case 32:
+                if (IMGFMT_IS_BGR(dmpi->imgfmt))
+                    sws_convertPalette8ToPacked32(src,dst,mpi->w,mpi->planes[1]);
+                else
+                    sws_convertPalette8ToPacked32(src,dst,mpi->w,mpi->planes[1]);
+                break;
+            }
+        }
+    }
+    mpi->planes[1] = old_palette;
+
+    return vf_next_put_image(vf,dmpi, pts);
+}
+
+//===========================================================================//
+
+static int query_format(struct vf_instance *vf, unsigned int fmt){
+    int best=find_best(vf,fmt);
+    if(!best) return 0; // no match
+    return vf->next->query_format(vf->next,best);
+}
+
+static void uninit(vf_instance_t *vf) {
+  free(vf->priv);
+}
+
+static int vf_open(vf_instance_t *vf, char *args){
+    unsigned int i;
+    vf->config=config;
+    vf->uninit=uninit;
+    vf->put_image=put_image;
+    vf->query_format=query_format;
+    vf->priv=malloc(sizeof(struct vf_priv_s));
+    memset(vf->priv, 0, sizeof(struct vf_priv_s));
+    for(i=0;i<256;i++) gray_pal[i]=0x01010101*i;
+    if (args)
+    {
+        if (!av_strcasecmp(args,"rgb15")) vf->priv->fmt=IMGFMT_RGB15; else
+        if (!av_strcasecmp(args,"rgb16")) vf->priv->fmt=IMGFMT_RGB16; else
+        if (!av_strcasecmp(args,"rgb24")) vf->priv->fmt=IMGFMT_RGB24; else
+        if (!av_strcasecmp(args,"rgb32")) vf->priv->fmt=IMGFMT_RGB32; else
+        if (!av_strcasecmp(args,"bgr15")) vf->priv->fmt=IMGFMT_BGR15; else
+        if (!av_strcasecmp(args,"bgr16")) vf->priv->fmt=IMGFMT_BGR16; else
+        if (!av_strcasecmp(args,"bgr24")) vf->priv->fmt=IMGFMT_BGR24; else
+        if (!av_strcasecmp(args,"bgr32")) vf->priv->fmt=IMGFMT_BGR32; else
+        {
+            mp_msg(MSGT_VFILTER, MSGL_WARN, MSGTR_MPCODECS_UnknownFormatName, args);
+            return 0;
+        }
+    }
+    return 1;
+}
+
+const vf_info_t vf_info_palette = {
+    "8bpp indexed (using palette) -> BGR 15/16/24/32 conversion",
+    "palette",
+    "A'rpi & Alex",
+    "",
+    vf_open,
+    NULL
+};
+
+//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vf_perspective.c b/libavfilter/libmpcodecs/vf_perspective.c
new file mode 100644
index 0000000..f5a9d6b
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_perspective.c
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <assert.h>
+#include <math.h>
+
+#include "config.h"
+#include "mp_msg.h"
+
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#include "libavutil/mem.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#define SUB_PIXEL_BITS 8
+#define SUB_PIXELS (1<<SUB_PIXEL_BITS)
+#define COEFF_BITS 11
+
+//===========================================================================//
+
+struct vf_priv_s {
+    double ref[4][2];
+    int32_t coeff[1<<SUB_PIXEL_BITS][4];
+    int32_t (*pv)[2];
+    int pvStride;
+    int cubic;
+};
+
+
+/***************************************************************************/
+
+static void initPv(struct vf_priv_s *priv, int W, int H){
+    double a,b,c,d,e,f,g,h,D;
+    double (*ref)[2]= priv->ref;
+    int x,y;
+
+    g= (  (ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0])*(ref[2][1] - ref[3][1])
+        - (ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1])*(ref[2][0] - ref[3][0]))*H;
+    h= (  (ref[0][1] - ref[1][1] - ref[2][1] + ref[3][1])*(ref[1][0] - ref[3][0])
+        - (ref[0][0] - ref[1][0] - ref[2][0] + ref[3][0])*(ref[1][1] - ref[3][1]))*W;
+    D=   (ref[1][0] - ref[3][0])*(ref[2][1] - ref[3][1])
+       - (ref[2][0] - ref[3][0])*(ref[1][1] - ref[3][1]);
+
+    a= D*(ref[1][0] - ref[0][0])*H + g*ref[1][0];
+    b= D*(ref[2][0] - ref[0][0])*W + h*ref[2][0];
+    c= D*ref[0][0]*W*H;
+    d= D*(ref[1][1] - ref[0][1])*H + g*ref[1][1];
+    e= D*(ref[2][1] - ref[0][1])*W + h*ref[2][1];
+    f= D*ref[0][1]*W*H;
+
+    for(y=0; y<H; y++){
+        for(x=0; x<W; x++){
+            int u, v;
+
+            u= (int)floor( SUB_PIXELS*(a*x + b*y + c)/(g*x + h*y + D*W*H) + 0.5);
+            v= (int)floor( SUB_PIXELS*(d*x + e*y + f)/(g*x + h*y + D*W*H) + 0.5);
+
+            priv->pv[x + y*W][0]= u;
+            priv->pv[x + y*W][1]= v;
+        }
+    }
+}
+
+static double getCoeff(double d){
+    double A= -0.60;
+    double coeff;
+
+    d= fabs(d);
+
+    // Equation is from VirtualDub
+    if(d<1.0)
+        coeff = (1.0 - (A+3.0)*d*d + (A+2.0)*d*d*d);
+    else if(d<2.0)
+        coeff = (-4.0*A + 8.0*A*d - 5.0*A*d*d + A*d*d*d);
+    else
+        coeff=0.0;
+
+    return coeff;
+}
+
+static int config(struct vf_instance *vf,
+    int width, int height, int d_width, int d_height,
+    unsigned int flags, unsigned int outfmt){
+    int i, j;
+
+    vf->priv->pvStride= width;
+    vf->priv->pv= av_malloc(width*height*2*sizeof(int32_t));
+    initPv(vf->priv, width, height);
+
+    for(i=0; i<SUB_PIXELS; i++){
+        double d= i/(double)SUB_PIXELS;
+        double temp[4];
+        double sum=0;
+
+        for(j=0; j<4; j++)
+            temp[j]= getCoeff(j - d - 1);
+
+        for(j=0; j<4; j++)
+            sum+= temp[j];
+
+        for(j=0; j<4; j++)
+            vf->priv->coeff[i][j]= (int)floor((1<<COEFF_BITS)*temp[j]/sum + 0.5);
+    }
+
+    return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+}
+
+static void uninit(struct vf_instance *vf){
+    if(!vf->priv) return;
+
+    av_free(vf->priv->pv);
+    vf->priv->pv= NULL;
+
+    free(vf->priv);
+    vf->priv=NULL;
+}
+
+static inline void resampleCubic(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride, struct vf_priv_s *privParam, int xShift, int yShift){
+    int x, y;
+    struct vf_priv_s priv= *privParam;
+
+    for(y=0; y<h; y++){
+        for(x=0; x<w; x++){
+            int u, v, subU, subV, sum, sx, sy;
+
+            sx= x << xShift;
+            sy= y << yShift;
+            u= priv.pv[sx + sy*priv.pvStride][0]>>xShift;
+            v= priv.pv[sx + sy*priv.pvStride][1]>>yShift;
+            subU= u & (SUB_PIXELS-1);
+            subV= v & (SUB_PIXELS-1);
+            u >>= SUB_PIXEL_BITS;
+            v >>= SUB_PIXEL_BITS;
+
+            if(u>0 && v>0 && u<w-2 && v<h-2){
+                const int index= u + v*srcStride;
+                const int a= priv.coeff[subU][0];
+                const int b= priv.coeff[subU][1];
+                const int c= priv.coeff[subU][2];
+                const int d= priv.coeff[subU][3];
+
+                sum=
+                 priv.coeff[subV][0]*(  a*src[index - 1 - srcStride] + b*src[index - 0 - srcStride]
+                                      + c*src[index + 1 - srcStride] + d*src[index + 2 - srcStride])
+                +priv.coeff[subV][1]*(  a*src[index - 1            ] + b*src[index - 0            ]
+                                      + c*src[index + 1            ] + d*src[index + 2            ])
+                +priv.coeff[subV][2]*(  a*src[index - 1 + srcStride] + b*src[index - 0 + srcStride]
+                                      + c*src[index + 1 + srcStride] + d*src[index + 2 + srcStride])
+                +priv.coeff[subV][3]*(  a*src[index - 1+2*srcStride] + b*src[index - 0+2*srcStride]
+                                      + c*src[index + 1+2*srcStride] + d*src[index + 2+2*srcStride]);
+            }else{
+                int dx, dy;
+                sum=0;
+
+                for(dy=0; dy<4; dy++){
+                    int iy= v + dy - 1;
+                    if     (iy< 0) iy=0;
+                    else if(iy>=h) iy=h-1;
+                    for(dx=0; dx<4; dx++){
+                        int ix= u + dx - 1;
+                        if     (ix< 0) ix=0;
+                        else if(ix>=w) ix=w-1;
+
+                        sum+=  priv.coeff[subU][dx]*priv.coeff[subV][dy]
+                              *src[ ix + iy*srcStride];
+                    }
+                }
+            }
+            sum= (sum + (1<<(COEFF_BITS*2-1)) ) >> (COEFF_BITS*2);
+            if(sum&~255){
+                if(sum<0) sum=0;
+                else      sum=255;
+            }
+            dst[ x + y*dstStride]= sum;
+        }
+    }
+}
+
+static inline void resampleLinear(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride,
+                  struct vf_priv_s *privParam, int xShift, int yShift){
+    int x, y;
+    struct vf_priv_s priv= *privParam;
+
+    for(y=0; y<h; y++){
+        for(x=0; x<w; x++){
+            int u, v, subU, subV, sum, sx, sy, index, subUI, subVI;
+
+            sx= x << xShift;
+            sy= y << yShift;
+            u= priv.pv[sx + sy*priv.pvStride][0]>>xShift;
+            v= priv.pv[sx + sy*priv.pvStride][1]>>yShift;
+            subU= u & (SUB_PIXELS-1);
+            subV= v & (SUB_PIXELS-1);
+            u >>= SUB_PIXEL_BITS;
+            v >>= SUB_PIXEL_BITS;
+            index= u + v*srcStride;
+            subUI= SUB_PIXELS - subU;
+            subVI= SUB_PIXELS - subV;
+
+            if((unsigned)u < (unsigned)(w - 1)){
+                if((unsigned)v < (unsigned)(h - 1)){
+                    sum= subVI*(subUI*src[index          ] + subU*src[index          +1])
+                        +subV *(subUI*src[index+srcStride] + subU*src[index+srcStride+1]);
+                    sum= (sum + (1<<(SUB_PIXEL_BITS*2-1)) ) >> (SUB_PIXEL_BITS*2);
+                }else{
+                    if(v<0) v= 0;
+                    else    v= h-1;
+                    index= u + v*srcStride;
+                    sum= subUI*src[index] + subU*src[index+1];
+                    sum= (sum + (1<<(SUB_PIXEL_BITS-1)) ) >> SUB_PIXEL_BITS;
+                }
+            }else{
+                if((unsigned)v < (unsigned)(h - 1)){
+                    if(u<0) u= 0;
+                    else    u= w-1;
+                    index= u + v*srcStride;
+                    sum= subVI*src[index] + subV*src[index+srcStride];
+                    sum= (sum + (1<<(SUB_PIXEL_BITS-1)) ) >> SUB_PIXEL_BITS;
+                }else{
+                    if(u<0) u= 0;
+                    else    u= w-1;
+                    if(v<0) v= 0;
+                    else    v= h-1;
+                    index= u + v*srcStride;
+                    sum= src[index];
+                }
+            }
+            if(sum&~255){
+                if(sum<0) sum=0;
+                else      sum=255;
+            }
+            dst[ x + y*dstStride]= sum;
+        }
+    }
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+    int cw= mpi->w >> mpi->chroma_x_shift;
+    int ch= mpi->h >> mpi->chroma_y_shift;
+
+    mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt,
+        MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
+        mpi->w,mpi->h);
+
+    assert(mpi->flags&MP_IMGFLAG_PLANAR);
+
+    if(vf->priv->cubic){
+        resampleCubic(dmpi->planes[0], mpi->planes[0], mpi->w,mpi->h, dmpi->stride[0], mpi->stride[0],
+                vf->priv, 0, 0);
+        resampleCubic(dmpi->planes[1], mpi->planes[1], cw    , ch   , dmpi->stride[1], mpi->stride[1],
+                vf->priv, mpi->chroma_x_shift, mpi->chroma_y_shift);
+        resampleCubic(dmpi->planes[2], mpi->planes[2], cw    , ch   , dmpi->stride[2], mpi->stride[2],
+                vf->priv, mpi->chroma_x_shift, mpi->chroma_y_shift);
+    }else{
+        resampleLinear(dmpi->planes[0], mpi->planes[0], mpi->w,mpi->h, dmpi->stride[0], mpi->stride[0],
+                vf->priv, 0, 0);
+        resampleLinear(dmpi->planes[1], mpi->planes[1], cw    , ch   , dmpi->stride[1], mpi->stride[1],
+                vf->priv, mpi->chroma_x_shift, mpi->chroma_y_shift);
+        resampleLinear(dmpi->planes[2], mpi->planes[2], cw    , ch   , dmpi->stride[2], mpi->stride[2],
+                vf->priv, mpi->chroma_x_shift, mpi->chroma_y_shift);
+    }
+
+    return 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;
+}
+
+static int vf_open(vf_instance_t *vf, char *args){
+    int e;
+
+    vf->config=config;
+    vf->put_image=put_image;
+//  vf->get_image=get_image;
+    vf->query_format=query_format;
+    vf->uninit=uninit;
+    vf->priv=malloc(sizeof(struct vf_priv_s));
+    memset(vf->priv, 0, sizeof(struct vf_priv_s));
+
+    if(args==NULL) return 0;
+
+    e=sscanf(args, "%lf:%lf:%lf:%lf:%lf:%lf:%lf:%lf:%d",
+        &vf->priv->ref[0][0], &vf->priv->ref[0][1],
+        &vf->priv->ref[1][0], &vf->priv->ref[1][1],
+        &vf->priv->ref[2][0], &vf->priv->ref[2][1],
+        &vf->priv->ref[3][0], &vf->priv->ref[3][1],
+        &vf->priv->cubic
+        );
+
+    if(e!=9)
+        return 0;
+
+    return 1;
+}
+
+const vf_info_t vf_info_perspective = {
+    "perspective correcture",
+    "perspective",
+    "Michael Niedermayer",
+    "",
+    vf_open,
+    NULL
+};
+
+//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vf_phase.c b/libavfilter/libmpcodecs/vf_phase.c
new file mode 100644
index 0000000..7dd642e
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_phase.c
@@ -0,0 +1,301 @@
+/*
+ * 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 <limits.h>
+
+#include "config.h"
+#include "mp_msg.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "libvo/fastmemcpy.h"
+
+enum mode { PROGRESSIVE, TOP_FIRST, BOTTOM_FIRST,
+            TOP_FIRST_ANALYZE, BOTTOM_FIRST_ANALYZE,
+            ANALYZE, FULL_ANALYZE, AUTO, AUTO_ANALYZE };
+
+#define fixed_mode(p) ((p)<=BOTTOM_FIRST)
+
+struct vf_priv_s
+   {
+   enum mode mode;
+   int verbose;
+   unsigned char *buf[3];
+   };
+
+/*
+ * Copy fields from either current or buffered previous frame to the
+ * output and store the current frame unmodified to the buffer.
+ */
+
+static void do_plane(unsigned char *to, unsigned char *from,
+                     int w, int h, int ts, int fs,
+                     unsigned char **bufp, enum mode mode)
+   {
+   unsigned char *buf, *end;
+   int top;
+
+   if(!*bufp)
+      {
+      mode=PROGRESSIVE;
+      if(!(*bufp=malloc(h*w))) return;
+      }
+
+   for(end=to+h*ts, buf=*bufp, top=1; to<end; from+=fs, to+=ts, buf+=w, top^=1)
+      {
+      fast_memcpy(to, mode==(top?BOTTOM_FIRST:TOP_FIRST)?buf:from, w);
+      fast_memcpy(buf, from, w);
+      }
+   }
+
+/*
+ * This macro interpolates the value of both fields at a point halfway
+ * between lines and takes the squared difference. In field resolution
+ * the point is a quarter pixel below a line in one field and a quarter
+ * pixel above a line in other.
+ *
+ * (the result is actually multiplied by 25)
+ */
+
+#define diff(a, as, b, bs) (t=((*a-b[bs])<<2)+a[as<<1]-b[-bs], t*t)
+
+/*
+ * Find which field combination has the smallest average squared difference
+ * between the fields.
+ */
+
+static enum mode analyze_plane(unsigned char *old, unsigned char *new,
+                               int w, int h, int os, int ns, enum mode mode,
+                               int verbose, int fields)
+   {
+   double bdiff, pdiff, tdiff, scale;
+   int bdif, tdif, pdif;
+   int top, t;
+   unsigned char *end, *rend;
+
+   if(mode==AUTO)
+      mode=fields&MP_IMGFIELD_ORDERED?fields&MP_IMGFIELD_TOP_FIRST?
+         TOP_FIRST:BOTTOM_FIRST:PROGRESSIVE;
+   else if(mode==AUTO_ANALYZE)
+      mode=fields&MP_IMGFIELD_ORDERED?fields&MP_IMGFIELD_TOP_FIRST?
+         TOP_FIRST_ANALYZE:BOTTOM_FIRST_ANALYZE:FULL_ANALYZE;
+
+   if(fixed_mode(mode))
+      bdiff=pdiff=tdiff=65536.0;
+   else
+      {
+      bdiff=pdiff=tdiff=0.0;
+
+      for(end=new+(h-2)*ns, new+=ns, old+=os, top=0;
+          new<end; new+=ns-w, old+=os-w, top^=1)
+         {
+         pdif=tdif=bdif=0;
+
+         switch(mode)
+            {
+            case TOP_FIRST_ANALYZE:
+               if(top)
+                  for(rend=new+w; new<rend; new++, old++)
+                     pdif+=diff(new, ns, new, ns),
+                     tdif+=diff(new, ns, old, os);
+               else
+                  for(rend=new+w; new<rend; new++, old++)
+                     pdif+=diff(new, ns, new, ns),
+                     tdif+=diff(old, os, new, ns);
+               break;
+
+            case BOTTOM_FIRST_ANALYZE:
+               if(top)
+                  for(rend=new+w; new<rend; new++, old++)
+                     pdif+=diff(new, ns, new, ns),
+                     bdif+=diff(old, os, new, ns);
+               else
+                  for(rend=new+w; new<rend; new++, old++)
+                     pdif+=diff(new, ns, new, ns),
+                     bdif+=diff(new, ns, old, os);
+               break;
+
+            case ANALYZE:
+               if(top)
+                  for(rend=new+w; new<rend; new++, old++)
+                     tdif+=diff(new, ns, old, os),
+                     bdif+=diff(old, os, new, ns);
+               else
+                  for(rend=new+w; new<rend; new++, old++)
+                     bdif+=diff(new, ns, old, os),
+                     tdif+=diff(old, os, new, ns);
+               break;
+
+            default: /* FULL_ANALYZE */
+               if(top)
+                  for(rend=new+w; new<rend; new++, old++)
+                     pdif+=diff(new, ns, new, ns),
+                     tdif+=diff(new, ns, old, os),
+                     bdif+=diff(old, os, new, ns);
+               else
+                  for(rend=new+w; new<rend; new++, old++)
+                     pdif+=diff(new, ns, new, ns),
+                     bdif+=diff(new, ns, old, os),
+                     tdif+=diff(old, os, new, ns);
+            }
+
+         pdiff+=(double)pdif;
+         tdiff+=(double)tdif;
+         bdiff+=(double)bdif;
+         }
+
+      scale=1.0/(w*(h-3))/25.0;
+      pdiff*=scale;
+      tdiff*=scale;
+      bdiff*=scale;
+
+      if(mode==TOP_FIRST_ANALYZE)
+         bdiff=65536.0;
+      else if(mode==BOTTOM_FIRST_ANALYZE)
+         tdiff=65536.0;
+      else if(mode==ANALYZE)
+         pdiff=65536.0;
+
+      if(bdiff<pdiff && bdiff<tdiff)
+         mode=BOTTOM_FIRST;
+      else if(tdiff<pdiff && tdiff<bdiff)
+         mode=TOP_FIRST;
+      else
+         mode=PROGRESSIVE;
+      }
+
+   if( 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");
+      }
+
+   return mode;
+   }
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+   {
+   mp_image_t *dmpi;
+   int w;
+   enum mode mode;
+
+   if(!(dmpi=vf_get_image(vf->next, mpi->imgfmt,
+                          MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
+                          mpi->w, mpi->h)))
+      return 0;
+
+   w=dmpi->w;
+   if(!(dmpi->flags&MP_IMGFLAG_PLANAR))
+      w*=dmpi->bpp/8;
+
+   mode=vf->priv->mode;
+
+   if(!vf->priv->buf[0])
+      mode=PROGRESSIVE;
+   else
+      mode=analyze_plane(vf->priv->buf[0], mpi->planes[0],
+                         w, dmpi->h, w, mpi->stride[0], mode,
+                         vf->priv->verbose, mpi->fields);
+
+   do_plane(dmpi->planes[0], mpi->planes[0],
+            w, dmpi->h,
+            dmpi->stride[0], mpi->stride[0],
+            &vf->priv->buf[0], mode);
+
+   if(dmpi->flags&MP_IMGFLAG_PLANAR)
+      {
+      do_plane(dmpi->planes[1], mpi->planes[1],
+               dmpi->chroma_width, dmpi->chroma_height,
+               dmpi->stride[1], mpi->stride[1],
+               &vf->priv->buf[1], mode);
+      do_plane(dmpi->planes[2], mpi->planes[2],
+               dmpi->chroma_width, dmpi->chroma_height,
+               dmpi->stride[2], mpi->stride[2],
+               &vf->priv->buf[2], mode);
+      }
+
+   return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+   }
+
+static void uninit(struct vf_instance *vf)
+   {
+   free(vf->priv->buf[0]);
+   free(vf->priv->buf[1]);
+   free(vf->priv->buf[2]);
+   free(vf->priv);
+   }
+
+static int vf_open(vf_instance_t *vf, char *args)
+   {
+   vf->put_image = put_image;
+   vf->uninit = uninit;
+   vf->default_reqs = VFCAP_ACCEPT_STRIDE;
+
+   if(!(vf->priv = calloc(1, sizeof(struct vf_priv_s))))
+      {
+      uninit(vf);
+      return 0;
+      }
+
+   vf->priv->mode=AUTO_ANALYZE;
+   vf->priv->verbose=0;
+
+   while(args && *args)
+      {
+      switch(*args)
+         {
+         case 't': vf->priv->mode=TOP_FIRST;            break;
+         case 'a': vf->priv->mode=AUTO;                 break;
+         case 'b': vf->priv->mode=BOTTOM_FIRST;         break;
+         case 'u': vf->priv->mode=ANALYZE;              break;
+         case 'T': vf->priv->mode=TOP_FIRST_ANALYZE;    break;
+         case 'A': vf->priv->mode=AUTO_ANALYZE;         break;
+         case 'B': vf->priv->mode=BOTTOM_FIRST_ANALYZE; break;
+         case 'U': vf->priv->mode=FULL_ANALYZE;         break;
+         case 'p': vf->priv->mode=PROGRESSIVE;          break;
+         case 'v': vf->priv->verbose=1;                 break;
+         case ':': break;
+
+         default:
+            uninit(vf);
+            return 0; /* bad args */
+         }
+
+      if( (args=strchr(args, ':')) ) args++;
+      }
+
+   return 1;
+   }
+
+const vf_info_t vf_info_phase =
+   {
+   "phase shift fields",
+   "phase",
+   "Ville Saari",
+   "",
+   vf_open,
+   NULL
+   };
diff --git a/libavfilter/libmpcodecs/vf_pp.c b/libavfilter/libmpcodecs/vf_pp.c
new file mode 100644
index 0000000..78cce1f
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_pp.c
@@ -0,0 +1,242 @@
+/*
+ * 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=
+          (gCpuCaps.hasMMX   ? PP_CPU_CAPS_MMX   : 0)
+        | (gCpuCaps.hasMMX2  ? PP_CPU_CAPS_MMX2  : 0)
+        | (gCpuCaps.has3DNow ? PP_CPU_CAPS_3DNOW : 0);
+
+    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
new file mode 100644
index 0000000..eae30bf
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_pp7.c
@@ -0,0 +1,493 @@
+/*
+ * Copyright (C) 2005 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 <math.h>
+
+#include "config.h"
+
+#include "mp_msg.h"
+#include "cpudetect.h"
+
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#include "libavutil/mem.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+#include "libvo/fastmemcpy.h"
+
+#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, },
+{ 32,  16,  44,  28,  35,  19,  47,  31, },
+{  8,  56,   4,  52,  11,  59,   7,  55, },
+{ 40,  24,  36,  20,  43,  27,  39,  23, },
+{  2,  50,  14,  62,   1,  49,  13,  61, },
+{ 34,  18,  46,  30,  33,  17,  45,  29, },
+{ 10,  58,   6,  54,   9,  57,   5,  53, },
+{ 42,  26,  38,  22,  41,  25,  37,  21, },
+};
+
+struct vf_priv_s {
+    int qp;
+    int mode;
+    int mpeg2;
+    int temp_stride;
+    uint8_t *src;
+};
+#if 0
+static inline void dct7_c(DCTELEM *dst, int s0, int s1, int s2, int s3, int step){
+    int s, d;
+    int dst2[64];
+//#define S0 (1024/0.37796447300922719759)
+#define C0 ((int)(1024*0.37796447300922719759+0.5)) //sqrt(1/7)
+#define C1 ((int)(1024*0.53452248382484879308/6+0.5)) //sqrt(2/7)/6
+
+#define C2 ((int)(1024*0.45221175985034745004/2+0.5))
+#define C3 ((int)(1024*0.36264567479870879474/2+0.5))
+
+//0.1962505182412941918 0.0149276808419397944-0.2111781990832339584
+#define C4 ((int)(1024*0.1962505182412941918+0.5))
+#define C5 ((int)(1024*0.0149276808419397944+0.5))
+//#define C6 ((int)(1024*0.2111781990832339584+0.5))
+#if 0
+    s= s0 + s1 + s2;
+    dst[0*step] = ((s + s3)*C0 + 512) >> 10;
+    s= (s - 6*s3)*C1 + 512;
+    d= (s0-s2)*C4 + (s1-s2)*C5;
+    dst[1*step] = (s + 2*d)>>10;
+    s -= d;
+    d= (s1-s0)*C2 + (s1-s2)*C3;
+    dst[2*step] = (s + d)>>10;
+    dst[3*step] = (s - d)>>10;
+#elif 1
+    s = s3+s3;
+    s3= s-s0;
+    s0= s+s0;
+    s = s2+s1;
+    s2= s2-s1;
+    dst[0*step]= s0 + s;
+    dst[2*step]= s0 - s;
+    dst[1*step]= 2*s3 +   s2;
+    dst[3*step]=   s3 - 2*s2;
+#else
+    int i,j,n=7;
+    for(i=0; i<7; i+=2){
+        dst2[i*step/2]= 0;
+        for(j=0; j<4; j++)
+            dst2[i*step/2] += src[j*step] * cos(i*M_PI/n*(j+0.5)) * sqrt((i?2.0:1.0)/n);
+        if(fabs(dst2[i*step/2] - dst[i*step/2]) > 20)
+            printf("%d %d %d (%d %d %d %d) -> (%d %d %d %d)\n", i,dst2[i*step/2], dst[i*step/2],src[0*step], src[1*step], src[2*step], src[3*step], dst[0*step], dst[1*step],dst[2*step],dst[3*step]);
+    }
+#endif
+}
+#endif
+
+static inline void dctA_c(DCTELEM *dst, uint8_t *src, int stride){
+    int i;
+
+    for(i=0; i<4; i++){
+        int s0=  src[0*stride] + src[6*stride];
+        int s1=  src[1*stride] + src[5*stride];
+        int s2=  src[2*stride] + src[4*stride];
+        int s3=  src[3*stride];
+        int s= s3+s3;
+        s3= s-s0;
+        s0= s+s0;
+        s = s2+s1;
+        s2= s2-s1;
+        dst[0]= s0 + s;
+        dst[2]= s0 - s;
+        dst[1]= 2*s3 +   s2;
+        dst[3]=   s3 - 2*s2;
+        src++;
+        dst+=4;
+    }
+}
+
+static void dctB_c(DCTELEM *dst, DCTELEM *src){
+    int i;
+
+    for(i=0; i<4; i++){
+        int s0=  src[0*4] + src[6*4];
+        int s1=  src[1*4] + src[5*4];
+        int s2=  src[2*4] + src[4*4];
+        int s3=  src[3*4];
+        int s= s3+s3;
+        s3= s-s0;
+        s0= s+s0;
+        s = s2+s1;
+        s2= s2-s1;
+        dst[0*4]= s0 + s;
+        dst[2*4]= s0 - s;
+        dst[1*4]= 2*s3 +   s2;
+        dst[3*4]=   s3 - 2*s2;
+        src++;
+        dst++;
+    }
+}
+
+#if HAVE_MMX
+static void dctB_mmx(DCTELEM *dst, DCTELEM *src){
+    __asm__ volatile (
+        "movq  (%0), %%mm0      \n\t"
+        "movq  1*4*2(%0), %%mm1 \n\t"
+        "paddw 6*4*2(%0), %%mm0 \n\t"
+        "paddw 5*4*2(%0), %%mm1 \n\t"
+        "movq  2*4*2(%0), %%mm2 \n\t"
+        "movq  3*4*2(%0), %%mm3 \n\t"
+        "paddw 4*4*2(%0), %%mm2 \n\t"
+        "paddw %%mm3, %%mm3     \n\t" //s
+        "movq %%mm3, %%mm4      \n\t" //s
+        "psubw %%mm0, %%mm3     \n\t" //s-s0
+        "paddw %%mm0, %%mm4     \n\t" //s+s0
+        "movq %%mm2, %%mm0      \n\t" //s2
+        "psubw %%mm1, %%mm2     \n\t" //s2-s1
+        "paddw %%mm1, %%mm0     \n\t" //s2+s1
+        "movq %%mm4, %%mm1      \n\t" //s0'
+        "psubw %%mm0, %%mm4     \n\t" //s0'-s'
+        "paddw %%mm0, %%mm1     \n\t" //s0'+s'
+        "movq %%mm3, %%mm0      \n\t" //s3'
+        "psubw %%mm2, %%mm3     \n\t"
+        "psubw %%mm2, %%mm3     \n\t"
+        "paddw %%mm0, %%mm2     \n\t"
+        "paddw %%mm0, %%mm2     \n\t"
+        "movq %%mm1, (%1)       \n\t"
+        "movq %%mm4, 2*4*2(%1)  \n\t"
+        "movq %%mm2, 1*4*2(%1)  \n\t"
+        "movq %%mm3, 3*4*2(%1)  \n\t"
+        :: "r" (src), "r"(dst)
+    );
+}
+#endif
+
+static void (*dctB)(DCTELEM *dst, DCTELEM *src)= dctB_c;
+
+#define N0 4
+#define N1 5
+#define N2 10
+#define SN0 2
+#define SN1 2.2360679775
+#define SN2 3.16227766017
+#define N (1<<16)
+
+static const int factor[16]={
+    N/(N0*N0), N/(N0*N1), N/(N0*N0),N/(N0*N2),
+    N/(N1*N0), N/(N1*N1), N/(N1*N0),N/(N1*N2),
+    N/(N0*N0), N/(N0*N1), N/(N0*N0),N/(N0*N2),
+    N/(N2*N0), N/(N2*N1), N/(N2*N0),N/(N2*N2),
+};
+
+static const int thres[16]={
+    N/(SN0*SN0), N/(SN0*SN2), N/(SN0*SN0),N/(SN0*SN2),
+    N/(SN2*SN0), N/(SN2*SN2), N/(SN2*SN0),N/(SN2*SN2),
+    N/(SN0*SN0), N/(SN0*SN2), N/(SN0*SN0),N/(SN0*SN2),
+    N/(SN2*SN0), N/(SN2*SN2), N/(SN2*SN0),N/(SN2*SN2),
+};
+
+static int thres2[99][16];
+
+static void init_thres2(void){
+    int qp, i;
+    int bias= 0; //FIXME
+
+    for(qp=0; qp<99; qp++){
+        for(i=0; i<16; i++){
+            thres2[qp][i]= ((i&1)?SN2:SN0) * ((i&4)?SN2:SN0) * XMAX(1,qp) * (1<<2) - 1 - bias;
+        }
+    }
+}
+
+static int hardthresh_c(DCTELEM *src, int qp){
+    int i;
+    int a;
+
+    a= src[0] * factor[0];
+    for(i=1; i<16; i++){
+        unsigned int threshold1= thres2[qp][i];
+        unsigned int threshold2= (threshold1<<1);
+        int level= src[i];
+        if(((unsigned)(level+threshold1))>threshold2){
+            a += level * factor[i];
+        }
+    }
+    return (a + (1<<11))>>12;
+}
+
+static int mediumthresh_c(DCTELEM *src, int qp){
+    int i;
+    int a;
+
+    a= src[0] * factor[0];
+    for(i=1; i<16; i++){
+        unsigned int threshold1= thres2[qp][i];
+        unsigned int threshold2= (threshold1<<1);
+        int level= src[i];
+        if(((unsigned)(level+threshold1))>threshold2){
+            if(((unsigned)(level+2*threshold1))>2*threshold2){
+                a += level * factor[i];
+            }else{
+                if(level>0) a+= 2*(level - (int)threshold1)*factor[i];
+                else        a+= 2*(level + (int)threshold1)*factor[i];
+            }
+        }
+    }
+    return (a + (1<<11))>>12;
+}
+
+static int softthresh_c(DCTELEM *src, int qp){
+    int i;
+    int a;
+
+    a= src[0] * factor[0];
+    for(i=1; i<16; i++){
+        unsigned int threshold1= thres2[qp][i];
+        unsigned int threshold2= (threshold1<<1);
+        int level= src[i];
+        if(((unsigned)(level+threshold1))>threshold2){
+            if(level>0) a+= (level - (int)threshold1)*factor[i];
+            else        a+= (level + (int)threshold1)*factor[i];
+        }
+    }
+    return (a + (1<<11))>>12;
+}
+
+static int (*requantize)(DCTELEM *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);
+
+    if (!src || !dst) return; // HACK avoid crash for Y8 colourspace
+    for(y=0; y<height; y++){
+        int index= 8 + 8*stride + y*stride;
+        fast_memcpy(p_src + index, src + y*src_stride, width);
+        for(x=0; x<8; x++){
+            p_src[index         - x - 1]= p_src[index +         x    ];
+            p_src[index + width + x    ]= p_src[index + width - x - 1];
+        }
+    }
+    for(y=0; y<8; y++){
+        fast_memcpy(p_src + (       7-y)*stride, p_src + (       y+8)*stride, stride);
+        fast_memcpy(p_src + (height+8+y)*stride, p_src + (height-y+7)*stride, stride);
+    }
+    //FIXME (try edge emu)
+
+    for(y=0; y<height; y++){
+        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;
+
+            dctA_c(tp+4*8, src, stride);
+        }
+        for(x=0; x<width; ){
+            const int qps= 3 + is_luma;
+            int qp;
+            int end= XMIN(x+8, width);
+
+            if(p->qp)
+                qp= p->qp;
+            else{
+                qp= qp_store[ (XMIN(x, width-1)>>qps) + (XMIN(y, height-1)>>qps) * qp_stride];
+                qp=norm_qscale(qp, p->mpeg2);
+            }
+            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;
+                int v;
+
+                if((x&3)==0)
+                    dctA_c(tp+4*8, src, stride);
+
+                dctB(block, tp);
+
+                v= requantize(block, qp);
+                v= (v + dither[y&7][x&7])>>6;
+                if((unsigned)v > 255)
+                    v= (-v)>>31;
+                dst[x + y*dst_stride]= v;
+            }
+        }
+    }
+}
+
+static int config(struct vf_instance *vf,
+    int width, int height, int d_width, int d_height,
+    unsigned int flags, unsigned int outfmt){
+    int h= (height+16+15)&(~15);
+
+    vf->priv->temp_stride= (width+16+15)&(~15);
+    vf->priv->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);
+}
+
+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,
+        mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height);
+    mpi->planes[0]=vf->dmpi->planes[0];
+    mpi->stride[0]=vf->dmpi->stride[0];
+    mpi->width=vf->dmpi->width;
+    if(mpi->flags&MP_IMGFLAG_PLANAR){
+        mpi->planes[1]=vf->dmpi->planes[1];
+        mpi->planes[2]=vf->dmpi->planes[2];
+        mpi->stride[1]=vf->dmpi->stride[1];
+        mpi->stride[2]=vf->dmpi->stride[2];
+    }
+    mpi->flags|=MP_IMGFLAG_DIRECT;
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+    mp_image_t *dmpi;
+
+    if(mpi->flags&MP_IMGFLAG_DIRECT){
+        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,
+            MP_IMGTYPE_TEMP,
+            MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
+            mpi->width,mpi->height);
+        vf_clone_mpi_attributes(dmpi, mpi);
+    }
+
+    vf->priv->mpeg2= mpi->qscale_type;
+    if(mpi->qscale || vf->priv->qp){
+        filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, mpi->qscale, mpi->qstride, 1);
+        filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, mpi->qscale, mpi->qstride, 0);
+        filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, mpi->qscale, mpi->qstride, 0);
+    }else{
+        memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]);
+        memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]);
+        memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]);
+    }
+
+#if HAVE_MMX
+    if(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){
+    if(!vf->priv) return;
+
+    av_free(vf->priv->src);
+    vf->priv->src= NULL;
+
+    free(vf->priv);
+    vf->priv=NULL;
+}
+
+//===========================================================================//
+static int query_format(struct vf_instance *vf, unsigned int fmt){
+    switch(fmt){
+    case IMGFMT_YVU9:
+    case IMGFMT_IF09:
+    case IMGFMT_YV12:
+    case IMGFMT_I420:
+    case IMGFMT_IYUV:
+    case IMGFMT_CLPL:
+    case IMGFMT_Y800:
+    case IMGFMT_Y8:
+    case IMGFMT_444P:
+    case IMGFMT_422P:
+    case IMGFMT_411P:
+        return 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);
+}
+
+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->control= control;
+    vf->priv=malloc(sizeof(struct vf_priv_s));
+    memset(vf->priv, 0, sizeof(struct vf_priv_s));
+
+    if (args) sscanf(args, "%d:%d", &vf->priv->qp, &vf->priv->mode);
+
+    if(vf->priv->qp < 0)
+        vf->priv->qp = 0;
+
+    init_thres2();
+
+    switch(vf->priv->mode){
+        case 0: requantize= hardthresh_c; break;
+        case 1: requantize= softthresh_c; break;
+        default:
+        case 2: requantize= mediumthresh_c; break;
+    }
+
+#if HAVE_MMX
+    if(gCpuCaps.hasMMX){
+        dctB= dctB_mmx;
+    }
+#endif
+#if 0
+    if(gCpuCaps.hasMMX){
+        switch(vf->priv->mode){
+            case 0: requantize= hardthresh_mmx; break;
+            case 1: requantize= softthresh_mmx; break;
+        }
+    }
+#endif
+
+    return 1;
+}
+
+const vf_info_t vf_info_pp7 = {
+    "postprocess 7",
+    "pp7",
+    "Michael Niedermayer",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_pullup.c b/libavfilter/libmpcodecs/vf_pullup.c
new file mode 100644
index 0000000..ba4ae02
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_pullup.c
@@ -0,0 +1,313 @@
+/*
+ * 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 "cpudetect.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "libvo/fastmemcpy.h"
+
+#include "pullup.h"
+
+#undef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+
+struct vf_priv_s {
+    struct pullup_context *ctx;
+    int init;
+    int fakecount;
+    char *qbuf;
+};
+
+static void init_pullup(struct vf_instance *vf, mp_image_t *mpi)
+{
+    struct pullup_context *c = vf->priv->ctx;
+
+    if (mpi->flags & MP_IMGFLAG_PLANAR) {
+        c->format = PULLUP_FMT_Y;
+        c->nplanes = 4;
+        pullup_preinit_context(c);
+        c->bpp[0] = c->bpp[1] = c->bpp[2] = 8;
+        c->w[0] = mpi->w;
+        c->h[0] = mpi->h;
+        c->w[1] = c->w[2] = mpi->chroma_width;
+        c->h[1] = c->h[2] = mpi->chroma_height;
+        c->w[3] = ((mpi->w+15)/16) * ((mpi->h+15)/16);
+        c->h[3] = 2;
+        c->stride[0] = mpi->width;
+        c->stride[1] = c->stride[2] = mpi->chroma_width;
+        c->stride[3] = c->w[3];
+        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;
+
+    pullup_init_context(c);
+
+    vf->priv->init = 1;
+    vf->priv->qbuf = malloc(c->w[3]);
+}
+
+
+#if 0
+static void get_image(struct vf_instance *vf, mp_image_t *mpi)
+{
+    struct pullup_context *c = vf->priv->ctx;
+    struct pullup_buffer *b;
+
+    if (mpi->type == MP_IMGTYPE_STATIC) return;
+
+    if (!vf->priv->init) init_pullup(vf, mpi);
+
+    b = pullup_get_buffer(c, 2);
+    if (!b) return; /* shouldn't happen... */
+
+    mpi->priv = b;
+
+    mpi->planes[0] = b->planes[0];
+    mpi->planes[1] = b->planes[1];
+    mpi->planes[2] = b->planes[2];
+    mpi->stride[0] = c->stride[0];
+    mpi->stride[1] = c->stride[1];
+    mpi->stride[2] = c->stride[2];
+
+    mpi->flags |= MP_IMGFLAG_DIRECT;
+    mpi->flags &= ~MP_IMGFLAG_DRAW_CALLBACK;
+}
+#endif
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+    struct pullup_context *c = vf->priv->ctx;
+    struct pullup_buffer *b;
+    struct pullup_frame *f;
+    mp_image_t *dmpi;
+    int ret;
+    int p;
+    int i;
+
+    if (!vf->priv->init) init_pullup(vf, mpi);
+
+    if (mpi->flags & MP_IMGFLAG_DIRECT) {
+        b = mpi->priv;
+        mpi->priv = 0;
+    } else {
+        b = 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);
+            return 0;
+        }
+        memcpy_pic(b->planes[0], mpi->planes[0], mpi->w, mpi->h,
+            c->stride[0], mpi->stride[0]);
+        if (mpi->flags & MP_IMGFLAG_PLANAR) {
+            memcpy_pic(b->planes[1], mpi->planes[1],
+                mpi->chroma_width, mpi->chroma_height,
+                c->stride[1], mpi->stride[1]);
+            memcpy_pic(b->planes[2], mpi->planes[2],
+                mpi->chroma_width, mpi->chroma_height,
+                c->stride[2], mpi->stride[2]);
+        }
+    }
+    if (mpi->qscale) {
+        fast_memcpy(b->planes[3], mpi->qscale, c->w[3]);
+        fast_memcpy(b->planes[3]+c->w[3], mpi->qscale, c->w[3]);
+    }
+
+    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);
+    if (mpi->fields & MP_IMGFIELD_REPEAT_FIRST)
+        pullup_submit_field(c, b, p);
+
+    pullup_release_buffer(b, 2);
+
+    f = 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);
+        if (!f) return 0;
+        if (f->length < 2) {
+            pullup_release_frame(f);
+            if (!(mpi->fields & MP_IMGFIELD_REPEAT_FIRST))
+                return 0;
+            f = pullup_get_frame(c);
+            if (!f) return 0;
+            if (f->length < 2) {
+                pullup_release_frame(f);
+                return 0;
+            }
+        }
+    }
+
+#if 0
+    /* Average qscale tables from both frames. */
+    if (mpi->qscale) {
+        for (i=0; i<c->w[3]; i++) {
+            vf->priv->qbuf[i] = (f->ofields[0]->planes[3][i]
+                + f->ofields[1]->planes[3][i+c->w[3]])>>1;
+        }
+    }
+#else
+    /* Take worst of qscale tables from both frames. */
+    if (mpi->qscale) {
+        for (i=0; i<c->w[3]; i++) {
+            vf->priv->qbuf[i] = MAX(f->ofields[0]->planes[3][i], f->ofields[1]->planes[3][i+c->w[3]]);
+        }
+    }
+#endif
+
+    /* If the frame isn't already exportable... */
+    while (!f->buffer) {
+        dmpi = 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);
+            break;
+        }
+        /* Direct render fields into output buffer */
+        my_memcpy_pic(dmpi->planes[0], f->ofields[0]->planes[0],
+            mpi->w, mpi->h/2, dmpi->stride[0]*2, c->stride[0]*2);
+        my_memcpy_pic(dmpi->planes[0] + dmpi->stride[0],
+            f->ofields[1]->planes[0] + c->stride[0],
+            mpi->w, mpi->h/2, dmpi->stride[0]*2, c->stride[0]*2);
+        if (mpi->flags & MP_IMGFLAG_PLANAR) {
+            my_memcpy_pic(dmpi->planes[1], f->ofields[0]->planes[1],
+                mpi->chroma_width, mpi->chroma_height/2,
+                dmpi->stride[1]*2, c->stride[1]*2);
+            my_memcpy_pic(dmpi->planes[1] + dmpi->stride[1],
+                f->ofields[1]->planes[1] + c->stride[1],
+                mpi->chroma_width, mpi->chroma_height/2,
+                dmpi->stride[1]*2, c->stride[1]*2);
+            my_memcpy_pic(dmpi->planes[2], f->ofields[0]->planes[2],
+                mpi->chroma_width, mpi->chroma_height/2,
+                dmpi->stride[2]*2, c->stride[2]*2);
+            my_memcpy_pic(dmpi->planes[2] + dmpi->stride[2],
+                f->ofields[1]->planes[2] + c->stride[2],
+                mpi->chroma_width, mpi->chroma_height/2,
+                dmpi->stride[2]*2, c->stride[2]*2);
+        }
+        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);
+    }
+    dmpi = vf_get_image(vf->next, mpi->imgfmt,
+        MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE,
+        mpi->width, mpi->height);
+
+    dmpi->planes[0] = f->buffer->planes[0];
+    dmpi->planes[1] = f->buffer->planes[1];
+    dmpi->planes[2] = f->buffer->planes[2];
+
+    dmpi->stride[0] = c->stride[0];
+    dmpi->stride[1] = c->stride[1];
+    dmpi->stride[2] = c->stride[2];
+
+    if (mpi->qscale) {
+        dmpi->qscale = vf->priv->qbuf;
+        dmpi->qstride = mpi->qstride;
+        dmpi->qscale_type = mpi->qscale_type;
+    }
+    ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+    pullup_release_frame(f);
+    return ret;
+}
+
+static int query_format(struct vf_instance *vf, unsigned int fmt)
+{
+    /* FIXME - support more formats */
+    switch (fmt) {
+    case IMGFMT_YV12:
+    case IMGFMT_IYUV:
+    case IMGFMT_I420:
+        return vf_next_query_format(vf, fmt);
+    }
+    return 0;
+}
+
+static int config(struct vf_instance *vf,
+    int width, int height, int d_width, int d_height,
+    unsigned int flags, unsigned int outfmt)
+{
+    if (height&3) return 0;
+    return 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);
+    free(vf->priv);
+}
+
+static int vf_open(vf_instance_t *vf, char *args)
+{
+    struct vf_priv_s *p;
+    struct pullup_context *c;
+    //vf->get_image = get_image;
+    vf->put_image = put_image;
+    vf->config = config;
+    vf->query_format = query_format;
+    vf->uninit = uninit;
+    vf->default_reqs = VFCAP_ACCEPT_STRIDE;
+    vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
+    p->ctx = c = pullup_alloc_context();
+    p->fakecount = 1;
+    c->junk_left = c->junk_right = 1;
+    c->junk_top = c->junk_bottom = 4;
+    c->strict_breaks = 0;
+    c->metric_plane = 0;
+    if (args) {
+        sscanf(args, "%d:%d:%d:%d:%d:%d", &c->junk_left, &c->junk_right, &c->junk_top, &c->junk_bottom, &c->strict_breaks, &c->metric_plane);
+    }
+    return 1;
+}
+
+const vf_info_t vf_info_pullup = {
+    "pullup (from field sequence to frames)",
+    "pullup",
+    "Rich Felker",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_qp.c b/libavfilter/libmpcodecs/vf_qp.c
new file mode 100644
index 0000000..d74f138
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_qp.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2004 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 <math.h>
+#include <inttypes.h>
+
+#include "mp_msg.h"
+#include "cpudetect.h"
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+#include "libvo/fastmemcpy.h"
+
+#include "libavcodec/avcodec.h"
+#include "libavutil/eval.h"
+
+
+struct vf_priv_s {
+        char eq[200];
+        int8_t *qp;
+        int8_t lut[257];
+        int qp_stride;
+};
+
+static int config(struct vf_instance *vf,
+        int width, int height, int d_width, int d_height,
+        unsigned int flags, unsigned int outfmt){
+        int h= (height+15)>>4;
+        int i;
+
+        vf->priv->qp_stride= (width+15)>>4;
+        vf->priv->qp= av_malloc(vf->priv->qp_stride*h*sizeof(int8_t));
+
+        for(i=-129; i<128; i++){
+            double const_values[]={
+                M_PI,
+                M_E,
+                i != -129,
+                i,
+                0
+            };
+            static const char *const_names[]={
+                "PI",
+                "E",
+                "known",
+                "qp",
+                NULL
+            };
+            double temp_val;
+            int res;
+
+            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);
+                return 0;
+            }
+            vf->priv->lut[i+129]= lrintf(temp_val);
+        }
+
+        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
+    // ok, we can do pp in-place (or pp disabled):
+    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;
+        int x,y;
+
+        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,
+                mpi->w,mpi->h);
+        }
+
+        dmpi= vf->dmpi;
+
+        if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
+                memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]);
+                    if(mpi->flags&MP_IMGFLAG_PLANAR){
+                    memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]);
+                    memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]);
+                }
+        }
+        vf_clone_mpi_attributes(dmpi, mpi);
+
+        dmpi->qscale = vf->priv->qp;
+        dmpi->qstride= vf->priv->qp_stride;
+        if(mpi->qscale){
+            for(y=0; y<((dmpi->h+15)>>4); y++){
+                for(x=0; x<vf->priv->qp_stride; x++){
+                    dmpi->qscale[x + dmpi->qstride*y]=
+                        vf->priv->lut[ 129 + ((int8_t)mpi->qscale[x + mpi->qstride*y]) ];
+                }
+            }
+        }else{
+            int qp= vf->priv->lut[0];
+            for(y=0; y<((dmpi->h+15)>>4); y++){
+                for(x=0; x<vf->priv->qp_stride; x++){
+                    dmpi->qscale[x + dmpi->qstride*y]= qp;
+                }
+            }
+        }
+
+        return vf_next_put_image(vf,dmpi, pts);
+}
+
+static void uninit(struct vf_instance *vf){
+        if(!vf->priv) return;
+
+        av_free(vf->priv->qp);
+        vf->priv->qp= NULL;
+
+        av_free(vf->priv);
+        vf->priv=NULL;
+}
+
+//===========================================================================//
+static int vf_open(vf_instance_t *vf, char *args){
+    vf->config=config;
+    vf->put_image=put_image;
+    vf->get_image=get_image;
+    vf->uninit=uninit;
+    vf->priv=av_malloc(sizeof(struct vf_priv_s));
+    memset(vf->priv, 0, sizeof(struct vf_priv_s));
+
+//    avcodec_init();
+
+    if (args) strncpy(vf->priv->eq, args, 199);
+
+    return 1;
+}
+
+const vf_info_t vf_info_qp = {
+    "QP changer",
+    "qp",
+    "Michael Niedermayer",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_rectangle.c b/libavfilter/libmpcodecs/vf_rectangle.c
new file mode 100644
index 0000000..21bc209
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_rectangle.c
@@ -0,0 +1,181 @@
+/*
+ * 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 "mp_image.h"
+#include "mp_msg.h"
+#include "vf.h"
+
+#include "libvo/fastmemcpy.h"
+#include "libavutil/common.h"
+
+struct vf_priv_s {
+    int x, y, w, h;
+};
+
+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->w < 0 || width < vf->priv->w)
+        vf->priv->w = width;
+    if (vf->priv->h < 0 || height < vf->priv->h)
+        vf->priv->h = height;
+    if (vf->priv->x < 0)
+        vf->priv->x = (width - vf->priv->w) / 2;
+    if (vf->priv->y < 0)
+        vf->priv->y = (height - vf->priv->h) / 2;
+    if (vf->priv->w + vf->priv->x > width
+        || vf->priv->h + vf->priv->y > height) {
+        mp_msg(MSGT_VFILTER,MSGL_WARN,"rectangle: bad position/width/height - rectangle area is out of the original!\n");
+        return 0;
+    }
+    return vf_next_config(vf, width, height, d_width, d_height, flags, outfmt);
+}
+
+static int
+control(struct vf_instance *vf, int request, void *data)
+{
+    const int *const tmp = data;
+    switch(request){
+    case VFCTRL_CHANGE_RECTANGLE:
+        switch (tmp[0]){
+        case 0:
+            vf->priv->w += tmp[1];
+            return 1;
+            break;
+        case 1:
+            vf->priv->h += tmp[1];
+            return 1;
+            break;
+        case 2:
+            vf->priv->x += tmp[1];
+            return 1;
+            break;
+        case 3:
+            vf->priv->y += tmp[1];
+            return 1;
+            break;
+        default:
+            mp_msg(MSGT_VFILTER,MSGL_FATAL,"Unknown param %d \n", tmp[0]);
+            return 0;
+        }
+    }
+    return vf_next_control(vf, request, data);
+    return 0;
+}
+static int
+put_image(struct vf_instance *vf, mp_image_t* mpi, double pts){
+    mp_image_t* dmpi;
+    unsigned int bpp = mpi->bpp / 8;
+    int x, y, w, h;
+    dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_TEMP,
+                        MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
+                        mpi->w, mpi->h);
+
+    memcpy_pic(dmpi->planes[0],mpi->planes[0],mpi->w*bpp, mpi->h,
+               dmpi->stride[0],mpi->stride[0]);
+    if(mpi->flags&MP_IMGFLAG_PLANAR && mpi->flags&MP_IMGFLAG_YUV){
+        memcpy_pic(dmpi->planes[1],mpi->planes[1],
+                   mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift,
+                   dmpi->stride[1],mpi->stride[1]);
+        memcpy_pic(dmpi->planes[2],mpi->planes[2],
+                   mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift,
+                   dmpi->stride[2],mpi->stride[2]);
+    }
+
+    /* Draw the rectangle */
+
+    mp_msg(MSGT_VFILTER,MSGL_INFO, "rectangle: -vf rectangle=%d:%d:%d:%d \n", vf->priv->w, vf->priv->h, vf->priv->x, vf->priv->y);
+
+    x = FFMIN(vf->priv->x, dmpi->width);
+    x = FFMAX(x, 0);
+
+    w = vf->priv->x + vf->priv->w - 1 - x;
+    w = FFMIN(w, dmpi->width - x);
+    w = FFMAX(w, 0);
+
+    y = FFMIN(vf->priv->y, dmpi->height);
+    y = FFMAX(y, 0);
+
+    h = vf->priv->y + vf->priv->h - 1 - y;
+    h = FFMIN(h, dmpi->height - y);
+    h = FFMAX(h, 0);
+
+    if (0 <= vf->priv->y && vf->priv->y <= dmpi->height) {
+        unsigned char *p = dmpi->planes[0] + y * dmpi->stride[0] + x * bpp;
+        unsigned int count = w * bpp;
+        while (count--)
+            p[count] = 0xff - p[count];
+    }
+    if (h != 1 && vf->priv->y + vf->priv->h - 1 <= mpi->height) {
+        unsigned char *p = dmpi->planes[0] + (vf->priv->y + vf->priv->h - 1) * dmpi->stride[0] + x * bpp;
+        unsigned int count = w * bpp;
+        while (count--)
+            p[count] = 0xff - p[count];
+    }
+    if (0 <= vf->priv->x  && vf->priv->x <= dmpi->width) {
+        unsigned char *p = dmpi->planes[0] + y * dmpi->stride[0] + x * bpp;
+        unsigned int count = h;
+        while (count--) {
+            unsigned int i = bpp;
+            while (i--)
+                p[i] = 0xff - p[i];
+            p += dmpi->stride[0];
+        }
+    }
+    if (w != 1 && vf->priv->x + vf->priv->w - 1 <= mpi->width) {
+        unsigned char *p = dmpi->planes[0] + y * dmpi->stride[0] + (vf->priv->x + vf->priv->w - 1) * bpp;
+        unsigned int count = h;
+        while (count--) {
+            unsigned int i = bpp;
+            while (i--)
+                p[i] = 0xff - p[i];
+            p += dmpi->stride[0];
+        }
+    }
+    return vf_next_put_image(vf, dmpi, pts);
+}
+
+static int
+vf_open(vf_instance_t *vf, char *args) {
+    vf->config = config;
+    vf->control = control;
+    vf->put_image = put_image;
+    vf->priv = malloc(sizeof(struct vf_priv_s));
+    vf->priv->x = -1;
+    vf->priv->y = -1;
+    vf->priv->w = -1;
+    vf->priv->h = -1;
+    if (args)
+        sscanf(args, "%d:%d:%d:%d",
+               &vf->priv->w, &vf->priv->h, &vf->priv->x, &vf->priv->y);
+    return 1;
+}
+
+const vf_info_t vf_info_rectangle = {
+    "draw rectangle",
+    "rectangle",
+    "Kim Minh Kaplan",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_sab.c b/libavfilter/libmpcodecs/vf_sab.c
new file mode 100644
index 0000000..807b726
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_sab.c
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <assert.h>
+
+#include "config.h"
+#include "mp_msg.h"
+
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#include "libavutil/avutil.h"
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+#include "libswscale/swscale.h"
+#include "vf_scale.h"
+
+
+//===========================================================================//
+
+typedef struct FilterParam{
+    float radius;
+    float preFilterRadius;
+    float strength;
+    float quality;
+    struct SwsContext *preFilterContext;
+    uint8_t *preFilterBuf;
+    int preFilterStride;
+    int distWidth;
+    int distStride;
+    int *distCoeff;
+    int colorDiffCoeff[512];
+}FilterParam;
+
+struct vf_priv_s {
+    FilterParam luma;
+    FilterParam chroma;
+};
+
+
+/***************************************************************************/
+
+//FIXME stupid code duplication
+static void getSubSampleFactors(int *h, int *v, int format){
+    switch(format){
+    default:
+        assert(0);
+    case IMGFMT_YV12:
+    case IMGFMT_I420:
+        *h=1;
+        *v=1;
+        break;
+    case IMGFMT_YVU9:
+        *h=2;
+        *v=2;
+        break;
+    case IMGFMT_444P:
+        *h=0;
+        *v=0;
+        break;
+    case IMGFMT_422P:
+        *h=1;
+        *v=0;
+        break;
+    case IMGFMT_411P:
+        *h=2;
+        *v=0;
+        break;
+    }
+}
+
+static int allocStuff(FilterParam *f, int width, int height){
+    int stride= (width+7)&~7;
+    SwsVector *vec;
+    SwsFilter swsF;
+    int i,x,y;
+    f->preFilterBuf= av_malloc(stride*height);
+    f->preFilterStride= stride;
+
+    vec = sws_getGaussianVec(f->preFilterRadius, f->quality);
+    swsF.lumH= swsF.lumV= vec;
+    swsF.chrH= swsF.chrV= NULL;
+    f->preFilterContext= sws_getContext(
+        width, height, AV_PIX_FMT_GRAY8, width, height, AV_PIX_FMT_GRAY8, SWS_POINT, &swsF, NULL, NULL);
+
+    sws_freeVec(vec);
+    vec = sws_getGaussianVec(f->strength, 5.0);
+    for(i=0; i<512; i++){
+        double d;
+        int index= i-256 + vec->length/2;
+
+        if(index<0 || index>=vec->length)     d= 0.0;
+        else                    d= vec->coeff[index];
+
+        f->colorDiffCoeff[i]= (int)(d/vec->coeff[vec->length/2]*(1<<12) + 0.5);
+    }
+    sws_freeVec(vec);
+    vec = sws_getGaussianVec(f->radius, f->quality);
+    f->distWidth= vec->length;
+    f->distStride= (vec->length+7)&~7;
+    f->distCoeff= av_malloc(f->distWidth*f->distStride*sizeof(int32_t));
+
+    for(y=0; y<vec->length; y++){
+        for(x=0; x<vec->length; x++){
+            double d= vec->coeff[x] * vec->coeff[y];
+
+            f->distCoeff[x + y*f->distStride]= (int)(d*(1<<10) + 0.5);
+//            if(y==vec->length/2)
+//                printf("%6d ", f->distCoeff[x + y*f->distStride]);
+        }
+    }
+    sws_freeVec(vec);
+
+    return 0;
+}
+
+static int config(struct vf_instance *vf,
+    int width, int height, int d_width, int d_height,
+    unsigned int flags, unsigned int outfmt){
+
+    int sw, sh;
+//__asm__ volatile("emms\n\t");
+    allocStuff(&vf->priv->luma, width, height);
+
+    getSubSampleFactors(&sw, &sh, outfmt);
+    allocStuff(&vf->priv->chroma, width>>sw, height>>sh);
+
+    return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
+}
+
+static void freeBuffers(FilterParam *f){
+    if(f->preFilterContext) sws_freeContext(f->preFilterContext);
+    f->preFilterContext=NULL;
+
+    av_free(f->preFilterBuf);
+    f->preFilterBuf=NULL;
+
+    av_free(f->distCoeff);
+    f->distCoeff=NULL;
+}
+
+static void uninit(struct vf_instance *vf){
+    if(!vf->priv) return;
+
+    freeBuffers(&vf->priv->luma);
+    freeBuffers(&vf->priv->chroma);
+
+    free(vf->priv);
+    vf->priv=NULL;
+}
+
+static inline void blur(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride, FilterParam *fp){
+    int x, y;
+    FilterParam f= *fp;
+    const int radius= f.distWidth/2;
+    const uint8_t* const srcArray[MP_MAX_PLANES] = {src};
+    uint8_t *dstArray[MP_MAX_PLANES]= {f.preFilterBuf};
+    int srcStrideArray[MP_MAX_PLANES]= {srcStride};
+    int dstStrideArray[MP_MAX_PLANES]= {f.preFilterStride};
+
+//    f.preFilterContext->swScale(f.preFilterContext, srcArray, srcStrideArray, 0, h, dstArray, dstStrideArray);
+    sws_scale(f.preFilterContext, srcArray, srcStrideArray, 0, h, dstArray, dstStrideArray);
+
+    for(y=0; y<h; y++){
+        for(x=0; x<w; x++){
+            int sum=0;
+            int div=0;
+            int dy;
+            const int preVal= f.preFilterBuf[x + y*f.preFilterStride];
+#if 0
+            const int srcVal= src[x + y*srcStride];
+if((x/32)&1){
+    dst[x + y*dstStride]= srcVal;
+    if(y%32==0) dst[x + y*dstStride]= 0;
+    continue;
+}
+#endif
+            if(x >= radius && x < w - radius){
+                for(dy=0; dy<radius*2+1; dy++){
+                    int dx;
+                    int iy= y+dy - radius;
+                    if     (iy<0)  iy=  -iy;
+                    else if(iy>=h) iy= h+h-iy-1;
+
+                    for(dx=0; dx<radius*2+1; dx++){
+                        const int ix= x+dx - radius;
+                        int factor;
+
+                        factor= f.colorDiffCoeff[256+preVal - f.preFilterBuf[ix + iy*f.preFilterStride] ]
+                            *f.distCoeff[dx + dy*f.distStride];
+                        sum+= src[ix + iy*srcStride] *factor;
+                        div+= factor;
+                    }
+                }
+            }else{
+                for(dy=0; dy<radius*2+1; dy++){
+                    int dx;
+                    int iy= y+dy - radius;
+                    if     (iy<0)  iy=  -iy;
+                    else if(iy>=h) iy= h+h-iy-1;
+
+                    for(dx=0; dx<radius*2+1; dx++){
+                        int ix= x+dx - radius;
+                        int factor;
+                        if     (ix<0)  ix=  -ix;
+                        else if(ix>=w) ix= w+w-ix-1;
+
+                        factor= f.colorDiffCoeff[256+preVal - f.preFilterBuf[ix + iy*f.preFilterStride] ]
+                            *f.distCoeff[dx + dy*f.distStride];
+                        sum+= src[ix + iy*srcStride] *factor;
+                        div+= factor;
+                    }
+                }
+            }
+            dst[x + y*dstStride]= (sum + div/2)/div;
+        }
+    }
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+    int cw= mpi->w >> mpi->chroma_x_shift;
+    int ch= mpi->h >> mpi->chroma_y_shift;
+
+    mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt,
+        MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
+        mpi->w,mpi->h);
+
+    assert(mpi->flags&MP_IMGFLAG_PLANAR);
+
+    blur(dmpi->planes[0], mpi->planes[0], mpi->w,mpi->h, dmpi->stride[0], mpi->stride[0], &vf->priv->luma);
+    blur(dmpi->planes[1], mpi->planes[1], cw    , ch   , dmpi->stride[1], mpi->stride[1], &vf->priv->chroma);
+    blur(dmpi->planes[2], mpi->planes[2], cw    , ch   , dmpi->stride[2], mpi->stride[2], &vf->priv->chroma);
+
+    return 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;
+}
+
+static int vf_open(vf_instance_t *vf, char *args){
+    int e;
+
+    vf->config=config;
+    vf->put_image=put_image;
+//    vf->get_image=get_image;
+    vf->query_format=query_format;
+    vf->uninit=uninit;
+    vf->priv=malloc(sizeof(struct vf_priv_s));
+    memset(vf->priv, 0, sizeof(struct vf_priv_s));
+
+    if(args==NULL) return 0;
+
+    e=sscanf(args, "%f:%f:%f:%f:%f:%f",
+        &vf->priv->luma.radius,
+        &vf->priv->luma.preFilterRadius,
+        &vf->priv->luma.strength,
+        &vf->priv->chroma.radius,
+        &vf->priv->chroma.preFilterRadius,
+        &vf->priv->chroma.strength
+        );
+
+    vf->priv->luma.quality = vf->priv->chroma.quality= 3.0;
+
+    if(e==3){
+        vf->priv->chroma.radius= vf->priv->luma.radius;
+        vf->priv->chroma.preFilterRadius = vf->priv->luma.preFilterRadius;
+        vf->priv->chroma.strength= vf->priv->luma.strength;
+    }else if(e!=6)
+        return 0;
+
+//    if(vf->priv->luma.radius < 0) return 0;
+//    if(vf->priv->chroma.radius < 0) return 0;
+
+    return 1;
+}
+
+const vf_info_t vf_info_sab = {
+    "shape adaptive blur",
+    "sab",
+    "Michael Niedermayer",
+    "",
+    vf_open,
+    NULL
+};
+
+//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vf_scale.h b/libavfilter/libmpcodecs/vf_scale.h
new file mode 100644
index 0000000..4de3b48
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_scale.h
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+#ifndef MPLAYER_VF_SCALE_H
+#define MPLAYER_VF_SCALE_H
+
+extern int sws_chr_vshift;
+extern int sws_chr_hshift;
+
+extern float sws_chr_gblur;
+extern float sws_lum_gblur;
+extern float sws_chr_sharpen;
+extern float sws_lum_sharpen;
+
+extern int sws_flags;
+
+struct SwsContext *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
new file mode 100644
index 0000000..04d1eae
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_softpulldown.c
@@ -0,0 +1,164 @@
+/*
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "mp_msg.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "libvo/fastmemcpy.h"
+
+struct vf_priv_s {
+    int state;
+    long long in;
+    long long out;
+};
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+    mp_image_t *dmpi;
+    int ret = 0;
+    int flags = mpi->fields;
+    int state = vf->priv->state;
+
+    dmpi = vf_get_image(vf->next, mpi->imgfmt,
+                        MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
+                        MP_IMGFLAG_PRESERVE, mpi->width, mpi->height);
+
+    vf->priv->in++;
+
+    if ((state == 0 &&
+         !(flags & MP_IMGFIELD_TOP_FIRST)) ||
+        (state == 1 &&
+         flags & MP_IMGFIELD_TOP_FIRST)) {
+        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,
+               (flags & MP_IMGFIELD_REPEAT_FIRST) != 0);
+        state ^= 1;
+    }
+
+    if (state == 0) {
+        ret = vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
+        vf->priv->out++;
+        if (flags & MP_IMGFIELD_REPEAT_FIRST) {
+            my_memcpy_pic(dmpi->planes[0],
+                       mpi->planes[0], mpi->w, mpi->h/2,
+                       dmpi->stride[0]*2, mpi->stride[0]*2);
+            if (mpi->flags & MP_IMGFLAG_PLANAR) {
+                my_memcpy_pic(dmpi->planes[1],
+                              mpi->planes[1],
+                              mpi->chroma_width,
+                              mpi->chroma_height/2,
+                              dmpi->stride[1]*2,
+                              mpi->stride[1]*2);
+                my_memcpy_pic(dmpi->planes[2],
+                              mpi->planes[2],
+                              mpi->chroma_width,
+                              mpi->chroma_height/2,
+                              dmpi->stride[2]*2,
+                              mpi->stride[2]*2);
+            }
+            state=1;
+        }
+    } else {
+        my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0],
+                      mpi->planes[0]+mpi->stride[0], mpi->w, mpi->h/2,
+                      dmpi->stride[0]*2, mpi->stride[0]*2);
+        if (mpi->flags & MP_IMGFLAG_PLANAR) {
+            my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1],
+                          mpi->planes[1]+mpi->stride[1],
+                          mpi->chroma_width, mpi->chroma_height/2,
+                          dmpi->stride[1]*2, mpi->stride[1]*2);
+            my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2],
+                          mpi->planes[2]+mpi->stride[2],
+                          mpi->chroma_width, mpi->chroma_height/2,
+                          dmpi->stride[2]*2, mpi->stride[2]*2);
+        }
+        ret = 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);
+            vf->priv->out++;
+            state=0;
+        } else {
+            my_memcpy_pic(dmpi->planes[0],
+                          mpi->planes[0], mpi->w, mpi->h/2,
+                          dmpi->stride[0]*2, mpi->stride[0]*2);
+            if (mpi->flags & MP_IMGFLAG_PLANAR) {
+                my_memcpy_pic(dmpi->planes[1],
+                              mpi->planes[1],
+                              mpi->chroma_width,
+                              mpi->chroma_height/2,
+                              dmpi->stride[1]*2,
+                              mpi->stride[1]*2);
+                my_memcpy_pic(dmpi->planes[2],
+                              mpi->planes[2],
+                              mpi->chroma_width,
+                              mpi->chroma_height/2,
+                              dmpi->stride[2]*2,
+                              mpi->stride[2]*2);
+            }
+        }
+    }
+
+    vf->priv->state = state;
+
+    return ret;
+}
+
+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)
+{
+    mp_msg(MSGT_VFILTER, MSGL_INFO, "softpulldown: %lld frames in, %lld frames out\n", vf->priv->in, vf->priv->out);
+    free(vf->priv);
+}
+
+static int vf_open(vf_instance_t *vf, char *args)
+{
+    struct vf_priv_s *p;
+    vf->config = config;
+    vf->put_image = put_image;
+    vf->uninit = uninit;
+    vf->default_reqs = VFCAP_ACCEPT_STRIDE;
+    vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
+    vf->priv->state = 0;
+    return 1;
+}
+
+const vf_info_t vf_info_softpulldown = {
+    "mpeg2 soft 3:2 pulldown",
+    "softpulldown",
+    "Tobias Diedrich <ranma+mplayer@tdiedrich.de>",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_softskip.c b/libavfilter/libmpcodecs/vf_softskip.c
new file mode 100644
index 0000000..150c3e7
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_softskip.c
@@ -0,0 +1,102 @@
+/*
+ * 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
new file mode 100644
index 0000000..0b4b230
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_spp.c
@@ -0,0 +1,620 @@
+/*
+ * Copyright (C) 2003 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ * This implementation is based on an algorithm described in
+ * "Aria Nosratinia Embedded Post-Processing for
+ * Enhancement of Compressed Images (1999)"
+ * (http://citeseer.nj.nec.com/nosratinia99embedded.html)
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <math.h>
+
+#include "config.h"
+
+#include "mp_msg.h"
+#include "cpudetect.h"
+
+#include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavcodec/avcodec.h"
+#include "libavcodec/dsputil.h"
+
+#undef fprintf
+#undef free
+#undef malloc
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+#include "vd_ffmpeg.h"
+#include "libvo/fastmemcpy.h"
+
+#define XMIN(a,b) ((a) < (b) ? (a) : (b))
+
+//===========================================================================//
+static const uint8_t  __attribute__((aligned(8))) dither[8][8]={
+{  0,  48,  12,  60,   3,  51,  15,  63, },
+{ 32,  16,  44,  28,  35,  19,  47,  31, },
+{  8,  56,   4,  52,  11,  59,   7,  55, },
+{ 40,  24,  36,  20,  43,  27,  39,  23, },
+{  2,  50,  14,  62,   1,  49,  13,  61, },
+{ 34,  18,  46,  30,  33,  17,  45,  29, },
+{ 10,  58,   6,  54,   9,  57,   5,  53, },
+{ 42,  26,  38,  22,  41,  25,  37,  21, },
+};
+
+static const uint8_t offset[127][2]= {
+{0,0},
+{0,0}, {4,4},
+{0,0}, {2,2}, {6,4}, {4,6},
+{0,0}, {5,1}, {2,2}, {7,3}, {4,4}, {1,5}, {6,6}, {3,7},
+
+{0,0}, {4,0}, {1,1}, {5,1}, {3,2}, {7,2}, {2,3}, {6,3},
+{0,4}, {4,4}, {1,5}, {5,5}, {3,6}, {7,6}, {2,7}, {6,7},
+
+{0,0}, {0,2}, {0,4}, {0,6}, {1,1}, {1,3}, {1,5}, {1,7},
+{2,0}, {2,2}, {2,4}, {2,6}, {3,1}, {3,3}, {3,5}, {3,7},
+{4,0}, {4,2}, {4,4}, {4,6}, {5,1}, {5,3}, {5,5}, {5,7},
+{6,0}, {6,2}, {6,4}, {6,6}, {7,1}, {7,3}, {7,5}, {7,7},
+
+{0,0}, {4,4}, {0,4}, {4,0}, {2,2}, {6,6}, {2,6}, {6,2},
+{0,2}, {4,6}, {0,6}, {4,2}, {2,0}, {6,4}, {2,4}, {6,0},
+{1,1}, {5,5}, {1,5}, {5,1}, {3,3}, {7,7}, {3,7}, {7,3},
+{1,3}, {5,7}, {1,7}, {5,3}, {3,1}, {7,5}, {3,5}, {7,1},
+{0,1}, {4,5}, {0,5}, {4,1}, {2,3}, {6,7}, {2,7}, {6,3},
+{0,3}, {4,7}, {0,7}, {4,3}, {2,1}, {6,5}, {2,5}, {6,1},
+{1,0}, {5,4}, {1,4}, {5,0}, {3,2}, {7,6}, {3,6}, {7,2},
+{1,2}, {5,6}, {1,6}, {5,2}, {3,0}, {7,4}, {3,4}, {7,0},
+};
+
+struct vf_priv_s {
+        int log2_count;
+        int qp;
+        int mode;
+        int mpeg2;
+        int temp_stride;
+        uint8_t *src;
+        int16_t *temp;
+        AVCodecContext *avctx;
+        DSPContext dsp;
+        char *non_b_qp;
+};
+
+#define SHIFT 22
+
+static void hardthresh_c(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){
+        int i;
+        int bias= 0; //FIXME
+        unsigned int threshold1, threshold2;
+
+        threshold1= qp*((1<<4) - bias) - 1;
+        threshold2= (threshold1<<1);
+
+        memset(dst, 0, 64*sizeof(DCTELEM));
+        dst[0]= (src[0] + 4)>>3;
+
+        for(i=1; i<64; i++){
+                int level= src[i];
+                if(((unsigned)(level+threshold1))>threshold2){
+                        const int j= permutation[i];
+                        dst[j]= (level + 4)>>3;
+                }
+        }
+}
+
+static void softthresh_c(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){
+        int i;
+        int bias= 0; //FIXME
+        unsigned int threshold1, threshold2;
+
+        threshold1= qp*((1<<4) - bias) - 1;
+        threshold2= (threshold1<<1);
+
+        memset(dst, 0, 64*sizeof(DCTELEM));
+        dst[0]= (src[0] + 4)>>3;
+
+        for(i=1; i<64; i++){
+                int level= src[i];
+                if(((unsigned)(level+threshold1))>threshold2){
+                        const int j= permutation[i];
+                        if(level>0)
+                                dst[j]= (level - threshold1 + 4)>>3;
+                        else
+                                dst[j]= (level + threshold1 + 4)>>3;
+                }
+        }
+}
+
+#if HAVE_MMX
+static void hardthresh_mmx(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){
+        int bias= 0; //FIXME
+        unsigned int threshold1;
+
+        threshold1= qp*((1<<4) - bias) - 1;
+
+        __asm__ volatile(
+#define REQUANT_CORE(dst0, dst1, dst2, dst3, src0, src1, src2, src3) \
+                "movq " #src0 ", %%mm0        \n\t"\
+                "movq " #src1 ", %%mm1        \n\t"\
+                "movq " #src2 ", %%mm2        \n\t"\
+                "movq " #src3 ", %%mm3        \n\t"\
+                "psubw %%mm4, %%mm0        \n\t"\
+                "psubw %%mm4, %%mm1        \n\t"\
+                "psubw %%mm4, %%mm2        \n\t"\
+                "psubw %%mm4, %%mm3        \n\t"\
+                "paddusw %%mm5, %%mm0        \n\t"\
+                "paddusw %%mm5, %%mm1        \n\t"\
+                "paddusw %%mm5, %%mm2        \n\t"\
+                "paddusw %%mm5, %%mm3        \n\t"\
+                "paddw %%mm6, %%mm0        \n\t"\
+                "paddw %%mm6, %%mm1        \n\t"\
+                "paddw %%mm6, %%mm2        \n\t"\
+                "paddw %%mm6, %%mm3        \n\t"\
+                "psubusw %%mm6, %%mm0        \n\t"\
+                "psubusw %%mm6, %%mm1        \n\t"\
+                "psubusw %%mm6, %%mm2        \n\t"\
+                "psubusw %%mm6, %%mm3        \n\t"\
+                "psraw $3, %%mm0        \n\t"\
+                "psraw $3, %%mm1        \n\t"\
+                "psraw $3, %%mm2        \n\t"\
+                "psraw $3, %%mm3        \n\t"\
+\
+                "movq %%mm0, %%mm7        \n\t"\
+                "punpcklwd %%mm2, %%mm0        \n\t" /*A*/\
+                "punpckhwd %%mm2, %%mm7        \n\t" /*C*/\
+                "movq %%mm1, %%mm2        \n\t"\
+                "punpcklwd %%mm3, %%mm1        \n\t" /*B*/\
+                "punpckhwd %%mm3, %%mm2        \n\t" /*D*/\
+                "movq %%mm0, %%mm3        \n\t"\
+                "punpcklwd %%mm1, %%mm0        \n\t" /*A*/\
+                "punpckhwd %%mm7, %%mm3        \n\t" /*C*/\
+                "punpcklwd %%mm2, %%mm7        \n\t" /*B*/\
+                "punpckhwd %%mm2, %%mm1        \n\t" /*D*/\
+\
+                "movq %%mm0, " #dst0 "        \n\t"\
+                "movq %%mm7, " #dst1 "        \n\t"\
+                "movq %%mm3, " #dst2 "        \n\t"\
+                "movq %%mm1, " #dst3 "        \n\t"
+
+                "movd %2, %%mm4                \n\t"
+                "movd %3, %%mm5                \n\t"
+                "movd %4, %%mm6                \n\t"
+                "packssdw %%mm4, %%mm4        \n\t"
+                "packssdw %%mm5, %%mm5        \n\t"
+                "packssdw %%mm6, %%mm6        \n\t"
+                "packssdw %%mm4, %%mm4        \n\t"
+                "packssdw %%mm5, %%mm5        \n\t"
+                "packssdw %%mm6, %%mm6        \n\t"
+                REQUANT_CORE(  (%1),  8(%1), 16(%1), 24(%1),  (%0), 8(%0), 64(%0), 72(%0))
+                REQUANT_CORE(32(%1), 40(%1), 48(%1), 56(%1),16(%0),24(%0), 48(%0), 56(%0))
+                REQUANT_CORE(64(%1), 72(%1), 80(%1), 88(%1),32(%0),40(%0), 96(%0),104(%0))
+                REQUANT_CORE(96(%1),104(%1),112(%1),120(%1),80(%0),88(%0),112(%0),120(%0))
+                : : "r" (src), "r" (dst), "g" (threshold1+1), "g" (threshold1+5), "g" (threshold1-4) //FIXME maybe more accurate then needed?
+        );
+        dst[0]= (src[0] + 4)>>3;
+}
+
+static void softthresh_mmx(DCTELEM dst[64], DCTELEM src[64], int qp, uint8_t *permutation){
+        int bias= 0; //FIXME
+        unsigned int threshold1;
+
+        threshold1= qp*((1<<4) - bias) - 1;
+
+        __asm__ volatile(
+#undef REQUANT_CORE
+#define REQUANT_CORE(dst0, dst1, dst2, dst3, src0, src1, src2, src3) \
+                "movq " #src0 ", %%mm0        \n\t"\
+                "movq " #src1 ", %%mm1        \n\t"\
+                "pxor %%mm6, %%mm6        \n\t"\
+                "pxor %%mm7, %%mm7        \n\t"\
+                "pcmpgtw %%mm0, %%mm6        \n\t"\
+                "pcmpgtw %%mm1, %%mm7        \n\t"\
+                "pxor %%mm6, %%mm0        \n\t"\
+                "pxor %%mm7, %%mm1        \n\t"\
+                "psubusw %%mm4, %%mm0        \n\t"\
+                "psubusw %%mm4, %%mm1        \n\t"\
+                "pxor %%mm6, %%mm0        \n\t"\
+                "pxor %%mm7, %%mm1        \n\t"\
+                "movq " #src2 ", %%mm2        \n\t"\
+                "movq " #src3 ", %%mm3        \n\t"\
+                "pxor %%mm6, %%mm6        \n\t"\
+                "pxor %%mm7, %%mm7        \n\t"\
+                "pcmpgtw %%mm2, %%mm6        \n\t"\
+                "pcmpgtw %%mm3, %%mm7        \n\t"\
+                "pxor %%mm6, %%mm2        \n\t"\
+                "pxor %%mm7, %%mm3        \n\t"\
+                "psubusw %%mm4, %%mm2        \n\t"\
+                "psubusw %%mm4, %%mm3        \n\t"\
+                "pxor %%mm6, %%mm2        \n\t"\
+                "pxor %%mm7, %%mm3        \n\t"\
+\
+                "paddsw %%mm5, %%mm0        \n\t"\
+                "paddsw %%mm5, %%mm1        \n\t"\
+                "paddsw %%mm5, %%mm2        \n\t"\
+                "paddsw %%mm5, %%mm3        \n\t"\
+                "psraw $3, %%mm0        \n\t"\
+                "psraw $3, %%mm1        \n\t"\
+                "psraw $3, %%mm2        \n\t"\
+                "psraw $3, %%mm3        \n\t"\
+\
+                "movq %%mm0, %%mm7        \n\t"\
+                "punpcklwd %%mm2, %%mm0        \n\t" /*A*/\
+                "punpckhwd %%mm2, %%mm7        \n\t" /*C*/\
+                "movq %%mm1, %%mm2        \n\t"\
+                "punpcklwd %%mm3, %%mm1        \n\t" /*B*/\
+                "punpckhwd %%mm3, %%mm2        \n\t" /*D*/\
+                "movq %%mm0, %%mm3        \n\t"\
+                "punpcklwd %%mm1, %%mm0        \n\t" /*A*/\
+                "punpckhwd %%mm7, %%mm3        \n\t" /*C*/\
+                "punpcklwd %%mm2, %%mm7        \n\t" /*B*/\
+                "punpckhwd %%mm2, %%mm1        \n\t" /*D*/\
+\
+                "movq %%mm0, " #dst0 "        \n\t"\
+                "movq %%mm7, " #dst1 "        \n\t"\
+                "movq %%mm3, " #dst2 "        \n\t"\
+                "movq %%mm1, " #dst3 "        \n\t"
+
+                "movd %2, %%mm4                \n\t"
+                "movd %3, %%mm5                \n\t"
+                "packssdw %%mm4, %%mm4        \n\t"
+                "packssdw %%mm5, %%mm5        \n\t"
+                "packssdw %%mm4, %%mm4        \n\t"
+                "packssdw %%mm5, %%mm5        \n\t"
+                REQUANT_CORE(  (%1),  8(%1), 16(%1), 24(%1),  (%0), 8(%0), 64(%0), 72(%0))
+                REQUANT_CORE(32(%1), 40(%1), 48(%1), 56(%1),16(%0),24(%0), 48(%0), 56(%0))
+                REQUANT_CORE(64(%1), 72(%1), 80(%1), 88(%1),32(%0),40(%0), 96(%0),104(%0))
+                REQUANT_CORE(96(%1),104(%1),112(%1),120(%1),80(%0),88(%0),112(%0),120(%0))
+                : : "r" (src), "r" (dst), "g" (threshold1), "rm" (4) //FIXME maybe more accurate then needed?
+        );
+
+        dst[0]= (src[0] + 4)>>3;
+}
+#endif
+
+static inline void add_block(int16_t *dst, int stride, DCTELEM block[64]){
+        int y;
+
+        for(y=0; y<8; y++){
+                *(uint32_t*)&dst[0 + y*stride]+= *(uint32_t*)&block[0 + y*8];
+                *(uint32_t*)&dst[2 + y*stride]+= *(uint32_t*)&block[2 + y*8];
+                *(uint32_t*)&dst[4 + y*stride]+= *(uint32_t*)&block[4 + y*8];
+                *(uint32_t*)&dst[6 + y*stride]+= *(uint32_t*)&block[6 + y*8];
+        }
+}
+
+static void store_slice_c(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale){
+        int y, x;
+
+#define STORE(pos) \
+        temp= ((src[x + y*src_stride + pos]<<log2_scale) + d[pos])>>6;\
+        if(temp & 0x100) temp= ~(temp>>31);\
+        dst[x + y*dst_stride + pos]= temp;
+
+        for(y=0; y<height; y++){
+                const uint8_t *d= dither[y];
+                for(x=0; x<width; x+=8){
+                        int temp;
+                        STORE(0);
+                        STORE(1);
+                        STORE(2);
+                        STORE(3);
+                        STORE(4);
+                        STORE(5);
+                        STORE(6);
+                        STORE(7);
+                }
+        }
+}
+
+#if HAVE_MMX
+static void store_slice_mmx(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale){
+        int y;
+
+        for(y=0; y<height; y++){
+                uint8_t *dst1= dst;
+                int16_t *src1= src;
+                __asm__ volatile(
+                        "movq (%3), %%mm3        \n\t"
+                        "movq (%3), %%mm4        \n\t"
+                        "movd %4, %%mm2                \n\t"
+                        "pxor %%mm0, %%mm0        \n\t"
+                        "punpcklbw %%mm0, %%mm3        \n\t"
+                        "punpckhbw %%mm0, %%mm4        \n\t"
+                        "psraw %%mm2, %%mm3        \n\t"
+                        "psraw %%mm2, %%mm4        \n\t"
+                        "movd %5, %%mm2                \n\t"
+                        "1:                        \n\t"
+                        "movq (%0), %%mm0        \n\t"
+                        "movq 8(%0), %%mm1        \n\t"
+                        "paddw %%mm3, %%mm0        \n\t"
+                        "paddw %%mm4, %%mm1        \n\t"
+                        "psraw %%mm2, %%mm0        \n\t"
+                        "psraw %%mm2, %%mm1        \n\t"
+                        "packuswb %%mm1, %%mm0        \n\t"
+                        "movq %%mm0, (%1)         \n\t"
+                        "add $16, %0                \n\t"
+                        "add $8, %1                \n\t"
+                        "cmp %2, %1                \n\t"
+                        " jb 1b                        \n\t"
+                        : "+r" (src1), "+r"(dst1)
+                        : "r"(dst + width), "r"(dither[y]), "g"(log2_scale), "g"(6-log2_scale)
+                );
+                src += src_stride;
+                dst += dst_stride;
+        }
+//        if(width != mmxw)
+//                store_slice_c(dst + mmxw, src + mmxw, dst_stride, src_stride, width - mmxw, log2_scale);
+}
+#endif
+
+static void (*store_slice)(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale)= store_slice_c;
+
+static void (*requantize)(DCTELEM dst[64], DCTELEM 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);
+
+        if (!src || !dst) return; // HACK avoid crash for Y8 colourspace
+        for(y=0; y<height; y++){
+                int index= 8 + 8*stride + y*stride;
+                fast_memcpy(p->src + index, src + y*src_stride, width);
+                for(x=0; x<8; x++){
+                        p->src[index         - x - 1]= p->src[index +         x    ];
+                        p->src[index + width + x    ]= p->src[index + width - x - 1];
+                }
+        }
+        for(y=0; y<8; y++){
+                fast_memcpy(p->src + (      7-y)*stride, p->src + (      y+8)*stride, stride);
+                fast_memcpy(p->src + (height+8+y)*stride, p->src + (height-y+7)*stride, stride);
+        }
+        //FIXME (try edge emu)
+
+        for(y=0; y<height+8; y+=8){
+                memset(p->temp + (8+y)*stride, 0, 8*stride*sizeof(int16_t));
+                for(x=0; x<width+8; x+=8){
+                        const int qps= 3 + is_luma;
+                        int qp;
+
+                        if(p->qp)
+                                qp= p->qp;
+                        else{
+                                qp= qp_store[ (XMIN(x, width-1)>>qps) + (XMIN(y, height-1)>>qps) * qp_stride];
+                                qp = FFMAX(1, norm_qscale(qp, p->mpeg2));
+                        }
+                        for(i=0; i<count; i++){
+                                const int x1= x + offset[i+count-1][0];
+                                const int y1= y + offset[i+count-1][1];
+                                const int index= x1 + y1*stride;
+                                p->dsp.get_pixels(block, p->src + index, stride);
+                                p->dsp.fdct(block);
+                                requantize(block2, block, qp, p->dsp.idct_permutation);
+                                p->dsp.idct(block2);
+                                add_block(p->temp + index, stride, block2);
+                        }
+                }
+                if(y)
+                        store_slice(dst + (y-8)*dst_stride, p->temp + 8 + y*stride, dst_stride, stride, width, XMIN(8, height+8-y), 6-p->log2_count);
+        }
+#if 0
+        for(y=0; y<height; y++){
+                for(x=0; x<width; x++){
+                        if((((x>>6) ^ (y>>6)) & 1) == 0)
+                                dst[x + y*dst_stride]= p->src[8 + 8*stride  + x + y*stride];
+                        if((x&63) == 0 || (y&63)==0)
+                                dst[x + y*dst_stride] += 128;
+                }
+        }
+#endif
+        //FIXME reorder for better caching
+}
+
+static int config(struct vf_instance *vf,
+        int width, int height, int d_width, int d_height,
+        unsigned int flags, unsigned int outfmt){
+        int h= (height+16+15)&(~15);
+
+        vf->priv->temp_stride= (width+16+15)&(~15);
+        vf->priv->temp= malloc(vf->priv->temp_stride*h*sizeof(int16_t));
+        vf->priv->src = malloc(vf->priv->temp_stride*h*sizeof(uint8_t));
+
+        return 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,
+        mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height);
+    mpi->planes[0]=vf->dmpi->planes[0];
+    mpi->stride[0]=vf->dmpi->stride[0];
+    mpi->width=vf->dmpi->width;
+    if(mpi->flags&MP_IMGFLAG_PLANAR){
+        mpi->planes[1]=vf->dmpi->planes[1];
+        mpi->planes[2]=vf->dmpi->planes[2];
+        mpi->stride[1]=vf->dmpi->stride[1];
+        mpi->stride[2]=vf->dmpi->stride[2];
+    }
+    mpi->flags|=MP_IMGFLAG_DIRECT;
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+        mp_image_t *dmpi;
+
+        if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
+                // no DR, so get a new image! hope we'll get DR buffer:
+                dmpi=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);
+        }else{
+           dmpi=vf->dmpi;
+        }
+
+        vf->priv->mpeg2= mpi->qscale_type;
+        if(mpi->pict_type != 3 && mpi->qscale && !vf->priv->qp){
+            int w = mpi->qstride;
+            int h = (mpi->h + 15) >> 4;
+            if (!w) {
+                w = (mpi->w + 15) >> 4;
+                h = 1;
+            }
+            if(!vf->priv->non_b_qp)
+                vf->priv->non_b_qp= malloc(w*h);
+            fast_memcpy(vf->priv->non_b_qp, mpi->qscale, w*h);
+        }
+        if(vf->priv->log2_count || !(mpi->flags&MP_IMGFLAG_DIRECT)){
+            char *qp_tab= vf->priv->non_b_qp;
+            if((vf->priv->mode&4) || !qp_tab)
+                qp_tab= mpi->qscale;
+
+            if(qp_tab || vf->priv->qp){
+                filter(vf->priv, dmpi->planes[0], mpi->planes[0], dmpi->stride[0], mpi->stride[0], mpi->w, mpi->h, qp_tab, mpi->qstride, 1);
+                filter(vf->priv, dmpi->planes[1], mpi->planes[1], dmpi->stride[1], mpi->stride[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, qp_tab, mpi->qstride, 0);
+                filter(vf->priv, dmpi->planes[2], mpi->planes[2], dmpi->stride[2], mpi->stride[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, qp_tab, mpi->qstride, 0);
+            }else{
+                memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]);
+                memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]);
+                memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]);
+            }
+        }
+
+#if HAVE_MMX
+        if(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){
+        if(!vf->priv) return;
+
+        free(vf->priv->temp);
+        vf->priv->temp= NULL;
+        free(vf->priv->src);
+        vf->priv->src= NULL;
+        free(vf->priv->avctx);
+        vf->priv->avctx= NULL;
+        free(vf->priv->non_b_qp);
+        vf->priv->non_b_qp= NULL;
+
+        free(vf->priv);
+        vf->priv=NULL;
+}
+
+//===========================================================================//
+static int query_format(struct vf_instance *vf, unsigned int fmt){
+    switch(fmt){
+        case IMGFMT_YVU9:
+        case IMGFMT_IF09:
+        case IMGFMT_YV12:
+        case IMGFMT_I420:
+        case IMGFMT_IYUV:
+        case IMGFMT_CLPL:
+        case IMGFMT_Y800:
+        case IMGFMT_Y8:
+        case IMGFMT_444P:
+        case IMGFMT_422P:
+        case IMGFMT_411P:
+            return vf_next_query_format(vf,fmt);
+    }
+    return 0;
+}
+
+static int control(struct vf_instance *vf, int request, void* data){
+    switch(request){
+    case VFCTRL_QUERY_MAX_PP_LEVEL:
+        return 6;
+    case VFCTRL_SET_PP_LEVEL:
+        vf->priv->log2_count= *((unsigned int*)data);
+        return CONTROL_TRUE;
+    }
+    return vf_next_control(vf,request,data);
+}
+
+static int vf_open(vf_instance_t *vf, char *args){
+
+    int log2c=-1;
+
+    vf->config=config;
+    vf->put_image=put_image;
+    vf->get_image=get_image;
+    vf->query_format=query_format;
+    vf->uninit=uninit;
+    vf->control= control;
+    vf->priv=malloc(sizeof(struct vf_priv_s));
+    memset(vf->priv, 0, sizeof(struct vf_priv_s));
+
+    init_avcodec();
+
+    vf->priv->avctx= avcodec_alloc_context();
+    dsputil_init(&vf->priv->dsp, vf->priv->avctx);
+
+    vf->priv->log2_count= 3;
+
+    if (args) sscanf(args, "%d:%d:%d", &log2c, &vf->priv->qp, &vf->priv->mode);
+
+    if( log2c >=0 && log2c <=6 )
+        vf->priv->log2_count = log2c;
+
+    if(vf->priv->qp < 0)
+        vf->priv->qp = 0;
+
+    switch(vf->priv->mode&3){
+        default:
+        case 0: requantize= hardthresh_c; break;
+        case 1: requantize= softthresh_c; break;
+    }
+
+#if HAVE_MMX
+    if(gCpuCaps.hasMMX){
+        store_slice= store_slice_mmx;
+        switch(vf->priv->mode&3){
+            case 0: requantize= hardthresh_mmx; break;
+            case 1: requantize= softthresh_mmx; break;
+        }
+    }
+#endif
+
+    return 1;
+}
+
+const vf_info_t vf_info_spp = {
+    "simple postprocess",
+    "spp",
+    "Michael Niedermayer",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_stereo3d.c b/libavfilter/libmpcodecs/vf_stereo3d.c
new file mode 100644
index 0000000..b8bc390
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_stereo3d.c
@@ -0,0 +1,512 @@
+/*
+ * Copyright (C) 2010 Gordon Schmidt <gordon.schmidt <at> s2000.tu-chemnitz.de>
+ *
+ * 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.
+ */
+
+//==includes==//
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "mp_msg.h"
+#include "help_mp.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "libavutil/common.h"
+#include "libvo/fastmemcpy.h"
+
+//==types==//
+typedef enum stereo_code {
+    ANAGLYPH_RC_GRAY,   //anaglyph red/cyan gray
+    ANAGLYPH_RC_HALF,   //anaglyph red/cyan half colored
+    ANAGLYPH_RC_COLOR,  //anaglyph red/cyan colored
+    ANAGLYPH_RC_DUBOIS, //anaglyph red/cyan dubois
+    ANAGLYPH_GM_GRAY,   //anaglyph green/magenta gray
+    ANAGLYPH_GM_HALF,   //anaglyph green/magenta half colored
+    ANAGLYPH_GM_COLOR,  //anaglyph green/magenta colored
+    ANAGLYPH_YB_GRAY,   //anaglyph yellow/blue gray
+    ANAGLYPH_YB_HALF,   //anaglyph yellow/blue half colored
+    ANAGLYPH_YB_COLOR,  //anaglyph yellow/blue colored
+    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)
+    SIDE_BY_SIDE_RL,    //side by side crosseye (right eye left, left eye right)
+    SIDE_BY_SIDE_2_LR,  //side by side parallel with half width resolution
+    SIDE_BY_SIDE_2_RL,  //side by side crosseye with half width resolution
+    ABOVE_BELOW_LR,     //above-below (left eye above, right eye below)
+    ABOVE_BELOW_RL,     //above-below (right eye above, left eye below)
+    ABOVE_BELOW_2_LR,   //above-below with half height resolution
+    ABOVE_BELOW_2_RL,   //above-below with half height resolution
+    INTERLEAVE_ROWS_LR, //row-interleave (left eye has top row)
+    INTERLEAVE_ROWS_RL, //row-interleave (right eye has top row)
+    STEREO_CODE_COUNT   //no value set - TODO: needs autodetection
+} stereo_code;
+
+typedef struct component {
+    stereo_code  fmt;
+    unsigned int width;
+    unsigned int height;
+    unsigned int off_left;
+    unsigned int off_right;
+    unsigned int row_left;
+    unsigned int row_right;
+} component;
+
+//==global variables==//
+static const int ana_coeff[10][3][6] = {
+    {{19595, 38470,  7471,     0,     0,     0},    //ANAGLYPH_RC_GRAY
+     {    0,     0,     0, 19595, 38470,  7471},
+     {    0,     0,     0, 19595, 38470,  7471}},
+    {{19595, 38470,  7471,     0,     0,     0},    //ANAGLYPH_RC_HALF
+     {    0,     0,     0,     0, 65536,     0},
+     {    0,     0,     0,     0,     0, 65536}},
+    {{65536,     0,     0,     0,     0,     0},    //ANAGLYPH_RC_COLOR
+     {    0,     0,     0,     0, 65536,     0},
+     {    0,     0,     0,     0,     0, 65536}},
+    {{29891, 32800, 11559, -2849, -5763,  -102},    //ANAGLYPH_RC_DUBOIS
+     {-2627, -2479, -1033, 24804, 48080, -1209},
+     { -997, -1350,  -358, -4729, -7403, 80373}},
+    {{    0,     0,     0, 19595, 38470,  7471},    //ANAGLYPH_GM_GRAY
+     {19595, 38470,  7471,     0,     0,     0},
+     {    0,     0,     0, 19595, 38470,  7471}},
+    {{    0,     0,     0, 65536,     0,     0},    //ANAGLYPH_GM_HALF
+     {19595, 38470,  7471,     0,     0,     0},
+     {    0,     0,     0,     0,     0, 65536}},
+    {{    0,     0,     0, 65536,     0,     0},    //ANAGLYPH_GM_COLOR
+     {    0, 65536,     0,     0,     0,     0},
+     {    0,     0,     0,     0,     0, 65536}},
+    {{    0,     0,     0, 19595, 38470,  7471},    //ANAGLYPH_YB_GRAY
+     {    0,     0,     0, 19595, 38470,  7471},
+     {19595, 38470,  7471,     0,     0,     0}},
+    {{    0,     0,     0, 65536,     0,     0},    //ANAGLYPH_YB_HALF
+     {    0,     0,     0,     0, 65536,     0},
+     {19595, 38470,  7471,     0,     0,     0}},
+    {{    0,     0,     0, 65536,     0,     0},    //ANAGLYPH_YB_COLOR
+     {    0,     0,     0,     0, 65536,     0},
+     {    0,     0, 65536,     0,     0,     0}}
+};
+
+struct vf_priv_s {
+    component in;
+    component out;
+    int ana_matrix[3][6];
+    unsigned int width;
+    unsigned int height;
+    unsigned int row_step;
+} const vf_priv_default = {
+  {SIDE_BY_SIDE_LR},
+  {ANAGLYPH_RC_DUBOIS}
+};
+
+//==functions==//
+static inline uint8_t ana_convert(int coeff[6], uint8_t left[3], uint8_t right[3])
+{
+    int sum;
+
+    sum  = coeff[0] * left[0] + coeff[3] * right[0]; //red in
+    sum += coeff[1] * left[1] + coeff[4] * right[1]; //green in
+    sum += coeff[2] * left[2] + coeff[5] * right[2]; //blue in
+    return av_clip_uint8(sum >> 16);
+}
+
+static int config(struct vf_instance *vf, int width, int height, int d_width,
+                  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");
+        return 0;
+    }
+    //default input values
+    vf->priv->width             = width;
+    vf->priv->height            = height;
+    vf->priv->row_step          = 1;
+    vf->priv->in.width          = width;
+    vf->priv->in.height         = height;
+    vf->priv->in.off_left       = 0;
+    vf->priv->in.off_right      = 0;
+    vf->priv->in.row_left       = 0;
+    vf->priv->in.row_right      = 0;
+
+    //check input format
+    switch (vf->priv->in.fmt) {
+    case SIDE_BY_SIDE_2_LR:
+        d_width                *= 2;
+    case SIDE_BY_SIDE_LR:
+        vf->priv->width         = width / 2;
+        vf->priv->in.off_right  = vf->priv->width * 3;
+        break;
+    case SIDE_BY_SIDE_2_RL:
+        d_width                *= 2;
+    case SIDE_BY_SIDE_RL:
+        vf->priv->width         = width / 2;
+        vf->priv->in.off_left   = vf->priv->width * 3;
+        break;
+    case ABOVE_BELOW_2_LR:
+        d_height               *= 2;
+    case ABOVE_BELOW_LR:
+        vf->priv->height        = height / 2;
+        vf->priv->in.row_right  = vf->priv->height;
+        break;
+    case ABOVE_BELOW_2_RL:
+        d_height               *= 2;
+    case ABOVE_BELOW_RL:
+        vf->priv->height        = height / 2;
+        vf->priv->in.row_left   = vf->priv->height;
+        break;
+    default:
+        mp_msg(MSGT_VFILTER, MSGL_WARN,
+               "[stereo3d] stereo format of input is not supported\n");
+        return 0;
+        break;
+    }
+    //default output values
+    vf->priv->out.width         = vf->priv->width;
+    vf->priv->out.height        = vf->priv->height;
+    vf->priv->out.off_left      = 0;
+    vf->priv->out.off_right     = 0;
+    vf->priv->out.row_left      = 0;
+    vf->priv->out.row_right     = 0;
+
+    //check output format
+    switch (vf->priv->out.fmt) {
+    case ANAGLYPH_RC_GRAY:
+    case ANAGLYPH_RC_HALF:
+    case ANAGLYPH_RC_COLOR:
+    case ANAGLYPH_RC_DUBOIS:
+    case ANAGLYPH_GM_GRAY:
+    case ANAGLYPH_GM_HALF:
+    case ANAGLYPH_GM_COLOR:
+    case ANAGLYPH_YB_GRAY:
+    case ANAGLYPH_YB_HALF:
+    case ANAGLYPH_YB_COLOR:
+        memcpy(vf->priv->ana_matrix, ana_coeff[vf->priv->out.fmt],
+               sizeof(vf->priv->ana_matrix));
+        break;
+    case SIDE_BY_SIDE_2_LR:
+        d_width                /= 2;
+    case SIDE_BY_SIDE_LR:
+        vf->priv->out.width     = vf->priv->width * 2;
+        vf->priv->out.off_right = vf->priv->width * 3;
+        break;
+    case SIDE_BY_SIDE_2_RL:
+        d_width                /= 2;
+    case SIDE_BY_SIDE_RL:
+        vf->priv->out.width     = vf->priv->width * 2;
+        vf->priv->out.off_left  = vf->priv->width * 3;
+        break;
+    case ABOVE_BELOW_2_LR:
+        d_height               /= 2;
+    case ABOVE_BELOW_LR:
+        vf->priv->out.height    = vf->priv->height * 2;
+        vf->priv->out.row_right = vf->priv->height;
+        break;
+    case ABOVE_BELOW_2_RL:
+        d_height               /= 2;
+    case ABOVE_BELOW_RL:
+        vf->priv->out.height    = vf->priv->height * 2;
+        vf->priv->out.row_left  = vf->priv->height;
+        break;
+    case INTERLEAVE_ROWS_LR:
+        vf->priv->row_step      = 2;
+        vf->priv->height        = vf->priv->height / 2;
+        vf->priv->out.off_right = vf->priv->width * 3;
+        vf->priv->in.off_right += vf->priv->in.width * 3;
+        break;
+    case INTERLEAVE_ROWS_RL:
+        vf->priv->row_step      = 2;
+        vf->priv->height        = vf->priv->height / 2;
+        vf->priv->out.off_left  = vf->priv->width * 3;
+        vf->priv->in.off_left  += vf->priv->in.width * 3;
+        break;
+    case MONO_R:
+        //same as MONO_L only needs switching of input offsets
+        vf->priv->in.off_left   = vf->priv->in.off_right;
+        vf->priv->in.row_left   = vf->priv->in.row_right;
+        //nobreak;
+    case MONO_L:
+        //use default settings
+        break;
+    default:
+        mp_msg(MSGT_VFILTER, MSGL_WARN,
+            "[stereo3d] stereo format of output is not supported\n");
+        return 0;
+        break;
+    }
+//    if (!opt_screen_size_x && !opt_screen_size_y) {
+        d_width     = d_width  * vf->priv->out.width  / width;
+        d_height    = d_height * vf->priv->out.height / height;
+//    }
+
+    return vf_next_config(vf, vf->priv->out.width, vf->priv->out.height,
+                          d_width, d_height, flags, outfmt);
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+    mp_image_t *dmpi;
+    if (vf->priv->in.fmt == vf->priv->out.fmt) { //nothing to do
+        dmpi = mpi;
+    } else {
+        int out_off_left, out_off_right;
+        int in_off_left  = vf->priv->in.row_left   * mpi->stride[0]  +
+                           vf->priv->in.off_left;
+        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,
+                            MP_IMGFLAG_ACCEPT_STRIDE,
+                            vf->priv->out.width, vf->priv->out.height);
+        out_off_left   = vf->priv->out.row_left  * dmpi->stride[0] +
+                         vf->priv->out.off_left;
+        out_off_right  = vf->priv->out.row_right * dmpi->stride[0] +
+                         vf->priv->out.off_right;
+
+        switch (vf->priv->out.fmt) {
+        case SIDE_BY_SIDE_LR:
+        case SIDE_BY_SIDE_RL:
+        case SIDE_BY_SIDE_2_LR:
+        case SIDE_BY_SIDE_2_RL:
+        case ABOVE_BELOW_LR:
+        case ABOVE_BELOW_RL:
+        case ABOVE_BELOW_2_LR:
+        case ABOVE_BELOW_2_RL:
+        case INTERLEAVE_ROWS_LR:
+        case INTERLEAVE_ROWS_RL:
+            memcpy_pic2(dmpi->planes[0] + out_off_left,
+                       mpi->planes[0] + in_off_left,
+                       3 * vf->priv->width,
+                       vf->priv->height,
+                       dmpi->stride[0] * vf->priv->row_step,
+                       mpi->stride[0] * vf->priv->row_step,
+                       vf->priv->row_step != 1);
+            memcpy_pic2(dmpi->planes[0] + out_off_right,
+                       mpi->planes[0] + in_off_right,
+                       3 * vf->priv->width,
+                       vf->priv->height,
+                       dmpi->stride[0] * vf->priv->row_step,
+                       mpi->stride[0] * vf->priv->row_step,
+                       vf->priv->row_step != 1);
+            break;
+        case MONO_L:
+        case MONO_R:
+            memcpy_pic(dmpi->planes[0],
+                       mpi->planes[0] + in_off_left,
+                       3 * vf->priv->width,
+                       vf->priv->height,
+                       dmpi->stride[0],
+                       mpi->stride[0]);
+            break;
+        case ANAGLYPH_RC_GRAY:
+        case ANAGLYPH_RC_HALF:
+        case ANAGLYPH_RC_COLOR:
+        case ANAGLYPH_RC_DUBOIS:
+        case ANAGLYPH_GM_GRAY:
+        case ANAGLYPH_GM_HALF:
+        case ANAGLYPH_GM_COLOR:
+        case ANAGLYPH_YB_GRAY:
+        case ANAGLYPH_YB_HALF:
+        case ANAGLYPH_YB_COLOR: {
+            int i,x,y,il,ir,o;
+            unsigned char *source     = mpi->planes[0];
+            unsigned char *dest       = dmpi->planes[0];
+            unsigned int   out_width  = vf->priv->out.width;
+            int           *ana_matrix[3];
+
+            for(i = 0; i < 3; i++)
+                ana_matrix[i] = vf->priv->ana_matrix[i];
+
+            for (y = 0; y < vf->priv->out.height; y++) {
+                o   = dmpi->stride[0] * y;
+                il  = in_off_left  + y * mpi->stride[0];
+                ir  = in_off_right + y * mpi->stride[0];
+                for (x = 0; x < out_width; x++) {
+                    dest[o    ]  = ana_convert(
+                                   ana_matrix[0], source + il, source + ir); //red out
+                    dest[o + 1]  = ana_convert(
+                                   ana_matrix[1], source + il, source + ir); //green out
+                    dest[o + 2]  = ana_convert(
+                                   ana_matrix[2], source + il, source + ir); //blue out
+                    il += 3;
+                    ir += 3;
+                    o  += 3;
+                }
+            }
+            break;
+        }
+        default:
+            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);
+}
+
+static int query_format(struct vf_instance *vf, unsigned int fmt)
+{
+    switch (fmt)
+    case IMGFMT_RGB24:
+        return vf_next_query_format(vf, fmt);
+    return 0;
+}
+
+static void uninit(vf_instance_t *vf)
+{
+    free(vf->priv);
+}
+
+static int vf_open(vf_instance_t *vf, char *args)
+{
+    vf->config          = config;
+    vf->uninit          = uninit;
+    vf->put_image       = put_image;
+    vf->query_format    = query_format;
+    vf->priv=malloc(sizeof(struct vf_priv_s));
+    memset(vf->priv, 0, sizeof(struct vf_priv_s));
+
+    vf->priv->in.fmt = SIDE_BY_SIDE_LR;
+    vf->priv->out.fmt= ANAGLYPH_RC_DUBOIS;
+    if (args) sscanf(args, "%d:%d", &vf->priv->in.fmt, &vf->priv->out.fmt);
+
+    return 1;
+}
+#if 0
+///Presets usage
+static const struct format_preset {
+  char* name;
+  stereo_code scode;
+} vf_format_presets_defs[] = {
+    {"arcg",                             ANAGLYPH_RC_GRAY},
+    {"anaglyph_red_cyan_gray",           ANAGLYPH_RC_GRAY},
+    {"arch",                             ANAGLYPH_RC_HALF},
+    {"anaglyph_red_cyan_half_color",     ANAGLYPH_RC_HALF},
+    {"arcc",                             ANAGLYPH_RC_COLOR},
+    {"anaglyph_red_cyan_color",          ANAGLYPH_RC_COLOR},
+    {"arcd",                             ANAGLYPH_RC_DUBOIS},
+    {"anaglyph_red_cyan_dubios",         ANAGLYPH_RC_DUBOIS},
+    {"agmg",                             ANAGLYPH_GM_GRAY},
+    {"anaglyph_green_magenta_gray",      ANAGLYPH_GM_GRAY},
+    {"agmh",                             ANAGLYPH_GM_HALF},
+    {"anaglyph_green_magenta_half_color",ANAGLYPH_GM_HALF},
+    {"agmc",                             ANAGLYPH_GM_COLOR},
+    {"anaglyph_green_magenta_color",     ANAGLYPH_GM_COLOR},
+    {"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},
+    {"ml",                               MONO_L},
+    {"mono_left",                        MONO_L},
+    {"mr",                               MONO_R},
+    {"mono_right",                       MONO_R},
+    {"sbsl",                             SIDE_BY_SIDE_LR},
+    {"side_by_side_left_first",          SIDE_BY_SIDE_LR},
+    {"sbsr",                             SIDE_BY_SIDE_RL},
+    {"side_by_side_right_first",         SIDE_BY_SIDE_RL},
+    {"sbs2l",                              SIDE_BY_SIDE_2_LR},
+    {"side_by_side_half_width_left_first", SIDE_BY_SIDE_2_LR},
+    {"sbs2r",                              SIDE_BY_SIDE_2_RL},
+    {"side_by_side_half_width_right_first",SIDE_BY_SIDE_2_RL},
+    {"abl",                              ABOVE_BELOW_LR},
+    {"above_below_left_first",           ABOVE_BELOW_LR},
+    {"abr",                              ABOVE_BELOW_RL},
+    {"above_below_right_first",          ABOVE_BELOW_RL},
+    {"ab2l",                               ABOVE_BELOW_2_LR},
+    {"above_below_half_height_left_first", ABOVE_BELOW_2_LR},
+    {"ab2r",                               ABOVE_BELOW_2_RL},
+    {"above_below_half_height_right_first",ABOVE_BELOW_2_RL},
+    {"irl",                                INTERLEAVE_ROWS_LR},
+    {"interleave_rows_left_first",         INTERLEAVE_ROWS_LR},
+    {"irr",                                INTERLEAVE_ROWS_RL},
+    {"interleave_rows_right_first",        INTERLEAVE_ROWS_RL},
+    { NULL, 0}
+};
+
+#define ST_OFF(f) M_ST_OFF(struct format_preset,f)
+static const m_option_t vf_format_preset_fields_in[] = {
+  {"in", ST_OFF(scode), CONF_TYPE_INT, 0,0,0, NULL},
+  { NULL, NULL, 0, 0, 0, 0,  NULL }
+};
+static const m_option_t vf_format_preset_fields_out[] = {
+  {"out", ST_OFF(scode), CONF_TYPE_INT, 0,0,0, NULL},
+  { NULL, NULL, 0, 0, 0, 0,  NULL }
+};
+
+static const m_struct_t vf_format_preset_in = {
+  "stereo_format_preset_in",
+  sizeof(struct format_preset),
+  NULL,
+  vf_format_preset_fields_in
+};
+static const m_struct_t vf_format_preset_out = {
+  "stereo_format_preset_out",
+  sizeof(struct format_preset),
+  NULL,
+  vf_format_preset_fields_out
+};
+
+static const m_struct_t vf_opts;
+static const m_obj_presets_t format_preset_in = {
+  (struct m_struct_st*)&vf_format_preset_in,
+  (struct m_struct_st*)&vf_opts,
+  (struct format_preset*)vf_format_presets_defs,
+  ST_OFF(name)
+};
+static const m_obj_presets_t format_preset_out = {
+  (struct m_struct_st*)&vf_format_preset_out,
+  (struct m_struct_st*)&vf_opts,
+  (struct format_preset*)vf_format_presets_defs,
+  ST_OFF(name)
+};
+
+/// Now the options
+#undef ST_OFF
+#define ST_OFF(f) M_ST_OFF(struct vf_priv_s,f)
+static const m_option_t vf_opts_fields[] = {
+  {"stereo_in", 0, CONF_TYPE_OBJ_PRESETS, 0, 0, 0,
+                   (m_obj_presets_t*)&format_preset_in},
+  {"stereo_out", 0, CONF_TYPE_OBJ_PRESETS, 0, 0, 0,
+                    (m_obj_presets_t*)&format_preset_out},
+  {"in", ST_OFF(in.fmt), CONF_TYPE_INT, 0,0,0, NULL},
+  {"out", ST_OFF(out.fmt), CONF_TYPE_INT, 0,0,0, NULL},
+  { NULL, NULL, 0, 0, 0, 0,  NULL }
+};
+
+static const m_struct_t vf_opts = {
+  "stereo3d",
+  sizeof(struct vf_priv_s),
+  &vf_priv_default,
+  vf_opts_fields
+};
+#endif
+
+//==info struct==//
+const vf_info_t vf_info_stereo3d = {
+    "stereoscopic 3d view",
+    "stereo3d",
+    "Gordon Schmidt",
+    "view stereoscopic videos",
+    vf_open,
+//    &vf_opts
+};
diff --git a/libavfilter/libmpcodecs/vf_telecine.c b/libavfilter/libmpcodecs/vf_telecine.c
new file mode 100644
index 0000000..3b92518
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_telecine.c
@@ -0,0 +1,155 @@
+/*
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "mp_msg.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "libvo/fastmemcpy.h"
+
+struct vf_priv_s {
+    int frame;
+};
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+    mp_image_t *dmpi;
+    int ret;
+
+    vf->priv->frame = (vf->priv->frame+1)%4;
+
+    dmpi = vf_get_image(vf->next, mpi->imgfmt,
+        MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
+        MP_IMGFLAG_PRESERVE, mpi->width, mpi->height);
+
+    ret = 0;
+    //    0/0  1/1  2/2  2/3  3/0
+    switch (vf->priv->frame) {
+    case 0:
+        my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0],
+            mpi->planes[0]+mpi->stride[0], mpi->w, mpi->h/2,
+            dmpi->stride[0]*2, mpi->stride[0]*2);
+        if (mpi->flags & MP_IMGFLAG_PLANAR) {
+            my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1],
+                mpi->planes[1]+mpi->stride[1],
+                mpi->chroma_width, mpi->chroma_height/2,
+                dmpi->stride[1]*2, mpi->stride[1]*2);
+            my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2],
+                mpi->planes[2]+mpi->stride[2],
+                mpi->chroma_width, mpi->chroma_height/2,
+                dmpi->stride[2]*2, mpi->stride[2]*2);
+        }
+        ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+    case 1:
+    case 2:
+        memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h,
+            dmpi->stride[0], mpi->stride[0]);
+        if (mpi->flags & MP_IMGFLAG_PLANAR) {
+            memcpy_pic(dmpi->planes[1], mpi->planes[1],
+                mpi->chroma_width, mpi->chroma_height,
+                dmpi->stride[1], mpi->stride[1]);
+            memcpy_pic(dmpi->planes[2], mpi->planes[2],
+                mpi->chroma_width, mpi->chroma_height,
+                dmpi->stride[2], mpi->stride[2]);
+        }
+        return 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], mpi->w, mpi->h/2,
+            dmpi->stride[0]*2, mpi->stride[0]*2);
+        if (mpi->flags & MP_IMGFLAG_PLANAR) {
+            my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1],
+                mpi->planes[1]+mpi->stride[1],
+                mpi->chroma_width, mpi->chroma_height/2,
+                dmpi->stride[1]*2, mpi->stride[1]*2);
+            my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2],
+                mpi->planes[2]+mpi->stride[2],
+                mpi->chroma_width, mpi->chroma_height/2,
+                dmpi->stride[2]*2, mpi->stride[2]*2);
+        }
+        ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        my_memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2,
+            dmpi->stride[0]*2, mpi->stride[0]*2);
+        if (mpi->flags & MP_IMGFLAG_PLANAR) {
+            my_memcpy_pic(dmpi->planes[1], mpi->planes[1],
+                mpi->chroma_width, mpi->chroma_height/2,
+                dmpi->stride[1]*2, mpi->stride[1]*2);
+            my_memcpy_pic(dmpi->planes[2], mpi->planes[2],
+                mpi->chroma_width, mpi->chroma_height/2,
+                dmpi->stride[2]*2, mpi->stride[2]*2);
+        }
+        return ret;
+    }
+    return 0;
+}
+
+#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;
+}
+
+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);
+}
+#endif
+
+static void uninit(struct vf_instance *vf)
+{
+    free(vf->priv);
+}
+
+static int vf_open(vf_instance_t *vf, char *args)
+{
+    //vf->config = config;
+    vf->put_image = put_image;
+    //vf->query_format = query_format;
+    vf->uninit = uninit;
+    vf->default_reqs = VFCAP_ACCEPT_STRIDE;
+    vf->priv = calloc(1, sizeof(struct vf_priv_s));
+    vf->priv->frame = 1;
+    if (args) sscanf(args, "%d", &vf->priv->frame);
+    vf->priv->frame--;
+    return 1;
+}
+
+const vf_info_t vf_info_telecine = {
+    "telecine filter",
+    "telecine",
+    "Rich Felker",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_tile.c b/libavfilter/libmpcodecs/vf_tile.c
new file mode 100644
index 0000000..a66573a
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_tile.c
@@ -0,0 +1,330 @@
+/*
+ * filter to tile a series of images in a single, bigger, image
+ *
+ * The parameters are:
+ *
+ *    xtile:  number of tiles on the x axis (5)
+ *    ytile:  number of tiles on the y axis (5)
+ *    xytile: when writing the image, it can be different than xtile * ytile
+ *            (for example you can write 8 * 7 tiles, writing the file every
+ *            50 frames, to have one image every 2 seconds @ 25 fps ).
+ *    start:  pixels at the start (x/y), default 2
+ *    delta:  pixels between 2 tiles, (x/y), default 4
+ *
+ * For example a valid command line is:
+ *    ... -vf tile=10:5:-1:4:8 ...
+ * that makes images of 10 * 5 tiles, with 4 pixels at the beginning and
+ * 8 pixels between tiles.
+ *
+ * The default command is:
+ *    ... -vf tile=5:5:25:2:4
+ *
+ * If you omit a parameter or put a value less than 0, the default is used.
+ *    ... -vf tile=10:5::-1:10
+ *
+ * You can also stop when you're ok
+ *    ... -vf tile=10:5
+ * (and this is probably the option you will use more often ...)
+ *
+ * Probably is good to put the scale filter before the tile :-)
+ *
+ * Copyright (c) 2003 Daniele Forghieri ( guru@digitalfantasy.it )
+ *
+ * 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.
+ */
+
+// strtoi memcpy_pic
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "mp_msg.h"
+#include "help_mp.h"
+#include "cpudetect.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "libvo/fastmemcpy.h"
+
+/* private data */
+struct vf_priv_s {
+    /* configuration data */
+    /* Number on hor/ver tiles */
+    int  xtile;
+    int  ytile;
+    /* When write the whole frame (default = xtile * ytile) */
+    int  xytile;
+    /* pixel at start / end (default = 4) */
+    int  start;
+    /* pixel between image (default = 2) */
+    int  delta;
+//    /* Background color, in destination format */
+//    int  bkgSet;
+
+    /* Work data */
+    int  frame_cur;
+};
+
+
+static int config(struct vf_instance *vf,
+                  int width, int height, int d_width, int d_height,
+              unsigned int flags, unsigned int outfmt){
+
+    struct vf_priv_s  *priv;
+    int               xw;
+    int               yh;
+
+    /* Calculate new destination size */
+    priv = vf->priv;
+    xw = priv->start * 2 +
+        priv->xtile * width +
+        (priv->xtile - 1) * priv->delta;
+    yh = priv->start * 2 +
+        priv->ytile * height +
+        (priv->ytile - 1) * priv->delta;
+
+    mp_msg(MSGT_VFILTER,MSGL_V,"vf_tile:config size set to %d * %d\n", xw, yh);
+
+    return vf_next_config(vf, xw, yh, xw, yh, flags, outfmt);
+}
+
+/* Filter handler */
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+    mp_image_t        *dmpi;
+    struct vf_priv_s  *priv;
+    int               t;
+    int               xw;
+    int               yh;
+    int               xi;
+    int               yi;
+    int               by;
+    int               dw;
+
+    /* Calculate new size */
+    priv = vf->priv;
+    xw = priv->start * 2 +
+        priv->xtile * mpi->w +
+        (priv->xtile - 1) * priv->delta;
+    yh = priv->start * 2 +
+        priv->ytile * mpi->h+
+        (priv->ytile - 1) * priv->delta;
+
+    /* Get the big image! */
+    dmpi=vf_get_image(vf->next, mpi->imgfmt,
+                      MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE,
+                      xw, yh);
+
+    /* bytes x pixel & bytes x line */
+    if (mpi->flags & MP_IMGFLAG_PLANAR) {
+        by = 1;
+        dw = mpi->w;
+    }
+    else {
+        by = (mpi->bpp + 7) / 8;
+        dw = mpi->w * by;
+    }
+    /* Index position */
+    t = priv->frame_cur % priv->xytile;
+//    if ((t == 0) && (bkg != 0)) {
+//        /* First frame, delete the background */
+//
+//    }
+
+    /* Position of image */
+    xi = priv->start + (mpi->w + priv->delta) * (t % priv->xtile);
+    yi = priv->start + (mpi->h + priv->delta) * (t / priv->xtile);
+
+    /* Copy first (or only) plane */
+    memcpy_pic( dmpi->planes[0] + xi * by + yi * dmpi->stride[0],
+                mpi->planes[0],
+                dw,
+                mpi->h,
+                dmpi->stride[0],
+                mpi->stride[0]);
+
+    if (mpi->flags & MP_IMGFLAG_PLANAR) {
+        /* Copy the other 2 planes */
+        memcpy_pic( dmpi->planes[1] + (xi >> mpi->chroma_x_shift) + (yi >> mpi->chroma_y_shift) * dmpi->stride[1],
+                    mpi->planes[1],
+                    mpi->chroma_width,
+                    mpi->chroma_height,
+                    dmpi->stride[1],
+                    mpi->stride[1]);
+         memcpy_pic( dmpi->planes[2] + (xi >> mpi->chroma_x_shift) + (yi >> mpi->chroma_y_shift) * dmpi->stride[2],
+                    mpi->planes[2],
+                    mpi->chroma_width,
+                    mpi->chroma_height,
+                    dmpi->stride[2],
+                    mpi->stride[2]);
+    }
+
+    /* Increment current frame */
+    ++priv->frame_cur;
+
+    if (t == priv->xytile - 1)  {
+        /* Display the composition */
+        dmpi->width  = xw;
+        dmpi->height = yh;
+        return vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+    }
+    else {
+        /* Skip the frame */
+        return 0;
+    }
+}
+
+static void uninit(struct vf_instance *vf)
+{
+    /* free local data */
+    free(vf->priv);
+}
+
+/* rgb/bgr 12...32 supported & some Yxxx */
+static int query_format(struct vf_instance *vf, unsigned int fmt)
+{
+    switch (fmt) {
+        /* rgb 12...32 bit */
+        case IMGFMT_RGB12:
+        case IMGFMT_RGB15:
+        case IMGFMT_RGB16:
+        case IMGFMT_RGB24:
+        case IMGFMT_RGB32:
+        /* bgr 12...32 bit */
+        case IMGFMT_BGR12:
+        case IMGFMT_BGR15:
+        case IMGFMT_BGR16:
+        case IMGFMT_BGR24:
+        case IMGFMT_BGR32:
+        /* Various Yxxx Formats */
+        case IMGFMT_444P:
+        case IMGFMT_422P:
+        case IMGFMT_411P:
+        case IMGFMT_YUY2:
+        case IMGFMT_YV12:
+        case IMGFMT_I420:
+        case IMGFMT_YVU9:
+        case IMGFMT_IF09:
+        case IMGFMT_IYUV:
+        return vf_next_query_format(vf, fmt);
+    }
+    return 0;
+}
+
+/* Get an integer from the string pointed by s, adjusting s.
+ * If the value is less then 0 def_val is used.
+ * Return 0 for ok
+ *
+ * Look below ( in vf_open(...) ) for a use ...
+ */
+static int parse_int(char **s, int *rt, int def_val)
+{
+
+    int     t = 0;
+
+    if (**s) {
+        /* Get value (dec, hex or octal) */
+        t = strtol( *s, s, 0 );
+
+        /* Use default */
+        if (t < 0) {
+            t = def_val;
+        }
+
+        if (**s == ':') {
+            /* Point to next character (probably a digit) */
+            ++(*s);
+        }
+        else if (**s != '\0') {
+            /* Error, we got some wrong char */
+            return 1;
+        }
+    }
+    else {
+        t = def_val;
+    }
+
+    *rt = t;
+    return 0;
+
+}
+
+/* Main entry funct for the filter */
+static int vf_open(vf_instance_t *vf, char *args)
+{
+    struct vf_priv_s *p;
+    int              er;
+
+    vf->put_image    = put_image;
+    vf->query_format = query_format;
+    vf->config       = config;
+    vf->uninit       = uninit;
+    vf->default_reqs = VFCAP_ACCEPT_STRIDE;
+    /* Private data */
+    vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
+    if (p == NULL) {
+        return 0;
+    }
+
+    if (args == NULL) {
+        /* Use the default */
+        args = "";
+    }
+    /* Parse all the arguments */
+    er =  parse_int( &args, &p->xtile,  5 );
+    er |= parse_int( &args, &p->ytile,  5 );
+    er |= parse_int( &args, &p->xytile, 0 );
+    er |= parse_int( &args, &p->start,  2 );
+    er |= parse_int( &args, &p->delta,  4 );
+//    er |= parse_int( &args, &p->bkgSet, 0 );
+
+    if (er) {
+        mp_msg(MSGT_VFILTER, MSGL_ERR, MSGTR_MPCODECS_ErrorParsingArgument);
+        return 0;
+    }
+    /* Load some default */
+    if ((p->xytile <= 0) || (p->xytile > p->xtile * p->ytile)) {
+        p->xytile = p->xtile * p->ytile;
+    }
+
+    /* Say what happen: use mp_msg(...)? */
+    if ( mp_msg_test(MSGT_VFILTER,MSGL_V) ) {
+        printf("vf_tile: tiling %d * %d, output every %d frames\n",
+               p->xtile,
+               p->ytile,
+               p->xytile);
+        printf("vf_tile: start pixel %d, delta pixel %d\n",
+               p->start,
+               p->delta);
+//      printf("vf_tile: background 0x%x\n",
+//             p->bkgSet);
+    }
+    return 1;
+}
+
+const vf_info_t vf_info_tile = {
+    "Make a single image tiling x/y images",
+    "tile",
+    "Daniele Forghieri",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_tinterlace.c b/libavfilter/libmpcodecs/vf_tinterlace.c
new file mode 100644
index 0000000..6dbcbc9
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_tinterlace.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2003 Michael Zucchi <notzed@ximian.com>
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "mp_msg.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "libvo/fastmemcpy.h"
+
+struct vf_priv_s {
+    int mode;
+    int frame;
+    mp_image_t *dmpi;
+};
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
+{
+    int ret = 0;
+    mp_image_t *dmpi;
+
+    switch (vf->priv->mode) {
+    case 0:
+        dmpi = vf->priv->dmpi;
+        if (dmpi == NULL) {
+            dmpi = vf_get_image(vf->next, mpi->imgfmt,
+                        MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
+                        MP_IMGFLAG_PRESERVE,
+                        mpi->width, mpi->height*2);
+
+            vf->priv->dmpi = dmpi;
+
+            memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h,
+                   dmpi->stride[0]*2, mpi->stride[0]);
+            if (mpi->flags & MP_IMGFLAG_PLANAR) {
+                memcpy_pic(dmpi->planes[1], mpi->planes[1],
+                       mpi->chroma_width, mpi->chroma_height,
+                       dmpi->stride[1]*2, mpi->stride[1]);
+                memcpy_pic(dmpi->planes[2], mpi->planes[2],
+                       mpi->chroma_width, mpi->chroma_height,
+                       dmpi->stride[2]*2, mpi->stride[2]);
+            }
+        } else {
+            vf->priv->dmpi = NULL;
+
+            memcpy_pic(dmpi->planes[0]+dmpi->stride[0], mpi->planes[0], mpi->w, mpi->h,
+                   dmpi->stride[0]*2, mpi->stride[0]);
+            if (mpi->flags & MP_IMGFLAG_PLANAR) {
+                memcpy_pic(dmpi->planes[1]+dmpi->stride[1], mpi->planes[1],
+                       mpi->chroma_width, mpi->chroma_height,
+                       dmpi->stride[1]*2, mpi->stride[1]);
+                memcpy_pic(dmpi->planes[2]+dmpi->stride[2], mpi->planes[2],
+                       mpi->chroma_width, mpi->chroma_height,
+                       dmpi->stride[2]*2, mpi->stride[2]);
+            }
+            ret = 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);
+        break;
+    case 2:
+        if ((vf->priv->frame & 1) == 0)
+            ret = vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
+        break;
+    case 3:
+        dmpi = 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);
+        if ((vf->priv->frame & 1) == 0) {
+            memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h,
+                   dmpi->stride[0]*2, mpi->stride[0]);
+            if (mpi->flags & MP_IMGFLAG_PLANAR) {
+                memcpy_pic(dmpi->planes[1], mpi->planes[1],
+                       mpi->chroma_width, mpi->chroma_height,
+                       dmpi->stride[1]*2, mpi->stride[1]);
+                memcpy_pic(dmpi->planes[2], mpi->planes[2],
+                       mpi->chroma_width, mpi->chroma_height,
+                       dmpi->stride[2]*2, mpi->stride[2]);
+            }
+        } else {
+            memcpy_pic(dmpi->planes[0]+dmpi->stride[0], mpi->planes[0], mpi->w, mpi->h,
+                   dmpi->stride[0]*2, mpi->stride[0]);
+            if (mpi->flags & MP_IMGFLAG_PLANAR) {
+                memcpy_pic(dmpi->planes[1]+dmpi->stride[1], mpi->planes[1],
+                       mpi->chroma_width, mpi->chroma_height,
+                       dmpi->stride[1]*2, mpi->stride[1]);
+                memcpy_pic(dmpi->planes[2]+dmpi->stride[2], mpi->planes[2],
+                       mpi->chroma_width, mpi->chroma_height,
+                       dmpi->stride[2]*2, mpi->stride[2]);
+            }
+        }
+        ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        break;
+    case 4:
+        // Interleave even lines (only) from Frame 'i' with odd
+        // lines (only) from Frame 'i+1', halving the Frame
+        // rate and preserving image height.
+
+        dmpi = vf->priv->dmpi;
+
+        // @@ Need help:  Should I set dmpi->fields to indicate
+        // that the (new) frame will be interlaced!?  E.g. ...
+        // dmpi->fields |= MP_IMGFIELD_INTERLACED;
+        // dmpi->fields |= MP_IMGFIELD_TOP_FIRST;
+        // etc.
+
+        if (dmpi == NULL) {
+            dmpi = vf_get_image(vf->next, mpi->imgfmt,
+                        MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE |
+                        MP_IMGFLAG_PRESERVE,
+                        mpi->width, mpi->height);
+
+            vf->priv->dmpi = dmpi;
+
+            my_memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2,
+                      dmpi->stride[0]*2, mpi->stride[0]*2);
+            if (mpi->flags & MP_IMGFLAG_PLANAR) {
+                my_memcpy_pic(dmpi->planes[1], mpi->planes[1],
+                          mpi->chroma_width, mpi->chroma_height/2,
+                          dmpi->stride[1]*2, mpi->stride[1]*2);
+                my_memcpy_pic(dmpi->planes[2], mpi->planes[2],
+                          mpi->chroma_width, mpi->chroma_height/2,
+                          dmpi->stride[2]*2, mpi->stride[2]*2);
+            }
+        } else {
+            vf->priv->dmpi = NULL;
+
+            my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0],
+                      mpi->planes[0]+mpi->stride[0],
+                      mpi->w, mpi->h/2,
+                      dmpi->stride[0]*2, mpi->stride[0]*2);
+            if (mpi->flags & MP_IMGFLAG_PLANAR) {
+                my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1],
+                          mpi->planes[1]+mpi->stride[1],
+                          mpi->chroma_width, mpi->chroma_height/2,
+                          dmpi->stride[1]*2, mpi->stride[1]*2);
+                my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2],
+                          mpi->planes[2]+mpi->stride[2],
+                          mpi->chroma_width, mpi->chroma_height/2,
+                          dmpi->stride[2]*2, mpi->stride[2]*2);
+            }
+            ret = vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
+        }
+        break;
+    }
+
+    vf->priv->frame++;
+
+    return ret;
+}
+
+static int query_format(struct vf_instance *vf, unsigned int fmt)
+{
+    /* FIXME - figure out which other formats work */
+    switch (fmt) {
+    case IMGFMT_YV12:
+    case IMGFMT_IYUV:
+    case IMGFMT_I420:
+        return vf_next_query_format(vf, fmt);
+    }
+    return 0;
+}
+
+static int config(struct vf_instance *vf,
+    int width, int height, int d_width, int d_height,
+    unsigned int flags, unsigned int outfmt)
+{
+    switch (vf->priv->mode) {
+    case 0:
+    case 3:
+        return 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 0;
+}
+
+static void uninit(struct vf_instance *vf)
+{
+    free(vf->priv);
+}
+
+static int vf_open(vf_instance_t *vf, char *args)
+{
+    struct vf_priv_s *p;
+    vf->config = config;
+    vf->put_image = put_image;
+    vf->query_format = query_format;
+    vf->uninit = uninit;
+    vf->default_reqs = VFCAP_ACCEPT_STRIDE;
+    vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
+    vf->priv->mode = 0;
+    if (args)
+      sscanf(args, "%d", &vf->priv->mode);
+    vf->priv->frame = 0;
+    return 1;
+}
+
+const vf_info_t vf_info_tinterlace = {
+    "temporal field interlacing",
+    "tinterlace",
+    "Michael Zucchi",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_unsharp.c b/libavfilter/libmpcodecs/vf_unsharp.c
new file mode 100644
index 0000000..db22f78
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_unsharp.c
@@ -0,0 +1,324 @@
+/*
+ * 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
new file mode 100644
index 0000000..1c683f7
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_uspp.c
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2005 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 <math.h>
+#include <assert.h>
+
+#include "config.h"
+
+#include "mp_msg.h"
+#include "cpudetect.h"
+
+#include "libavcodec/avcodec.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+#include "vd_ffmpeg.h"
+#include "libvo/fastmemcpy.h"
+
+#define XMIN(a,b) ((a) < (b) ? (a) : (b))
+
+#define BLOCK 16
+
+//===========================================================================//
+static const uint8_t  __attribute__((aligned(8))) dither[8][8]={
+{  0*4,  48*4,  12*4,  60*4,   3*4,  51*4,  15*4,  63*4, },
+{ 32*4,  16*4,  44*4,  28*4,  35*4,  19*4,  47*4,  31*4, },
+{  8*4,  56*4,   4*4,  52*4,  11*4,  59*4,   7*4,  55*4, },
+{ 40*4,  24*4,  36*4,  20*4,  43*4,  27*4,  39*4,  23*4, },
+{  2*4,  50*4,  14*4,  62*4,   1*4,  49*4,  13*4,  61*4, },
+{ 34*4,  18*4,  46*4,  30*4,  33*4,  17*4,  45*4,  29*4, },
+{ 10*4,  58*4,   6*4,  54*4,   9*4,  57*4,   5*4,  53*4, },
+{ 42*4,  26*4,  38*4,  22*4,  41*4,  25*4,  37*4,  21*4, },
+};
+
+static const uint8_t offset[511][2]= {
+{ 0, 0},
+{ 0, 0}, { 8, 8},
+{ 0, 0}, { 4, 4}, {12, 8}, { 8,12},
+{ 0, 0}, {10, 2}, { 4, 4}, {14, 6}, { 8, 8}, { 2,10}, {12,12}, { 6,14},
+
+{ 0, 0}, {10, 2}, { 4, 4}, {14, 6}, { 8, 8}, { 2,10}, {12,12}, { 6,14},
+{ 5, 1}, {15, 3}, { 9, 5}, { 3, 7}, {13, 9}, { 7,11}, { 1,13}, {11,15},
+
+{ 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9},
+{ 2, 2}, {10, 2}, { 2,10}, {10,10}, { 7, 3}, {15, 3}, { 7,11}, {15,11},
+{ 4, 4}, {12, 4}, { 4,12}, {12,12}, { 1, 5}, { 9, 5}, { 1,13}, { 9,13},
+{ 6, 6}, {14, 6}, { 6,14}, {14,14}, { 3, 7}, {11, 7}, { 3,15}, {11,15},
+
+{ 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 4, 0}, {12, 0}, { 4, 8}, {12, 8},
+{ 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9},
+{ 3, 2}, {11, 2}, { 3,10}, {11,10}, { 7, 2}, {15, 2}, { 7,10}, {15,10},
+{ 2, 3}, {10, 3}, { 2,11}, {10,11}, { 6, 3}, {14, 3}, { 6,11}, {14,11},
+{ 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 4, 4}, {12, 4}, { 4,12}, {12,12},
+{ 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 5, 5}, {13, 5}, { 5,13}, {13,13},
+{ 3, 6}, {11, 6}, { 3,14}, {11,14}, { 7, 6}, {15, 6}, { 7,14}, {15,14},
+{ 2, 7}, {10, 7}, { 2,15}, {10,15}, { 6, 7}, {14, 7}, { 6,15}, {14,15},
+
+{ 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 0, 2}, { 8, 2}, { 0,10}, { 8,10},
+{ 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 0, 6}, { 8, 6}, { 0,14}, { 8,14},
+{ 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 1, 3}, { 9, 3}, { 1,11}, { 9,11},
+{ 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 1, 7}, { 9, 7}, { 1,15}, { 9,15},
+{ 2, 0}, {10, 0}, { 2, 8}, {10, 8}, { 2, 2}, {10, 2}, { 2,10}, {10,10},
+{ 2, 4}, {10, 4}, { 2,12}, {10,12}, { 2, 6}, {10, 6}, { 2,14}, {10,14},
+{ 3, 1}, {11, 1}, { 3, 9}, {11, 9}, { 3, 3}, {11, 3}, { 3,11}, {11,11},
+{ 3, 5}, {11, 5}, { 3,13}, {11,13}, { 3, 7}, {11, 7}, { 3,15}, {11,15},
+{ 4, 0}, {12, 0}, { 4, 8}, {12, 8}, { 4, 2}, {12, 2}, { 4,10}, {12,10},
+{ 4, 4}, {12, 4}, { 4,12}, {12,12}, { 4, 6}, {12, 6}, { 4,14}, {12,14},
+{ 5, 1}, {13, 1}, { 5, 9}, {13, 9}, { 5, 3}, {13, 3}, { 5,11}, {13,11},
+{ 5, 5}, {13, 5}, { 5,13}, {13,13}, { 5, 7}, {13, 7}, { 5,15}, {13,15},
+{ 6, 0}, {14, 0}, { 6, 8}, {14, 8}, { 6, 2}, {14, 2}, { 6,10}, {14,10},
+{ 6, 4}, {14, 4}, { 6,12}, {14,12}, { 6, 6}, {14, 6}, { 6,14}, {14,14},
+{ 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},
+};
+
+struct vf_priv_s {
+    int log2_count;
+    int qp;
+    int mode;
+    int mpeg2;
+    int temp_stride[3];
+    uint8_t *src[3];
+    int16_t *temp[3];
+    int outbuf_size;
+    uint8_t *outbuf;
+    AVCodecContext *avctx_enc[BLOCK*BLOCK];
+    AVFrame *frame;
+    AVFrame *frame_dec;
+};
+
+static void store_slice_c(uint8_t *dst, int16_t *src, int dst_stride, int src_stride, int width, int height, int log2_scale){
+        int y, x;
+
+#define STORE(pos) \
+        temp= ((src[x + y*src_stride + pos]<<log2_scale) + d[pos])>>8;\
+        if(temp & 0x100) temp= ~(temp>>31);\
+        dst[x + y*dst_stride + pos]= temp;
+
+        for(y=0; y<height; y++){
+                const uint8_t *d= dither[y&7];
+                for(x=0; x<width; x+=8){
+                        int temp;
+                        STORE(0);
+                        STORE(1);
+                        STORE(2);
+                        STORE(3);
+                        STORE(4);
+                        STORE(5);
+                        STORE(6);
+                        STORE(7);
+                }
+        }
+}
+
+static void filter(struct vf_priv_s *p, uint8_t *dst[3], uint8_t *src[3], int dst_stride[3], int src_stride[3], int width, int height, uint8_t *qp_store, int qp_stride){
+    int x, y, i, j;
+    const int count= 1<<p->log2_count;
+
+    for(i=0; i<3; i++){
+        int is_chroma= !!i;
+        int w= width >>is_chroma;
+        int h= height>>is_chroma;
+        int stride= p->temp_stride[i];
+        int block= BLOCK>>is_chroma;
+
+        if (!src[i] || !dst[i])
+            continue; // HACK avoid crash for Y8 colourspace
+        for(y=0; y<h; y++){
+            int index= block + block*stride + y*stride;
+            fast_memcpy(p->src[i] + index, src[i] + y*src_stride[i], w);
+            for(x=0; x<block; x++){
+                p->src[i][index     - x - 1]= p->src[i][index +     x    ];
+                p->src[i][index + w + x    ]= p->src[i][index + w - x - 1];
+            }
+        }
+        for(y=0; y<block; y++){
+            fast_memcpy(p->src[i] + (  block-1-y)*stride, p->src[i] + (  y+block  )*stride, stride);
+            fast_memcpy(p->src[i] + (h+block  +y)*stride, p->src[i] + (h-y+block-1)*stride, stride);
+        }
+
+        p->frame->linesize[i]= stride;
+        memset(p->temp[i], 0, (h+2*block)*stride*sizeof(int16_t));
+    }
+
+    if(p->qp)
+        p->frame->quality= p->qp * FF_QP2LAMBDA;
+    else
+        p->frame->quality= norm_qscale(qp_store[0], p->mpeg2) * FF_QP2LAMBDA;
+//    init per MB qscale stuff FIXME
+
+    for(i=0; i<count; i++){
+        const int x1= offset[i+count-1][0];
+        const int y1= offset[i+count-1][1];
+        int offset;
+        p->frame->data[0]= p->src[0] + x1 + y1 * p->frame->linesize[0];
+        p->frame->data[1]= p->src[1] + x1/2 + y1/2 * p->frame->linesize[1];
+        p->frame->data[2]= p->src[2] + x1/2 + y1/2 * p->frame->linesize[2];
+
+        avcodec_encode_video(p->avctx_enc[i], p->outbuf, p->outbuf_size, p->frame);
+        p->frame_dec = p->avctx_enc[i]->coded_frame;
+
+        offset= (BLOCK-x1) + (BLOCK-y1)*p->frame_dec->linesize[0];
+        //FIXME optimize
+        for(y=0; y<height; y++){
+            for(x=0; x<width; x++){
+                p->temp[0][ x + y*p->temp_stride[0] ] += p->frame_dec->data[0][ x + y*p->frame_dec->linesize[0] + offset ];
+            }
+        }
+        offset= (BLOCK/2-x1/2) + (BLOCK/2-y1/2)*p->frame_dec->linesize[1];
+        for(y=0; y<height/2; y++){
+            for(x=0; x<width/2; x++){
+                p->temp[1][ x + y*p->temp_stride[1] ] += p->frame_dec->data[1][ x + y*p->frame_dec->linesize[1] + offset ];
+                p->temp[2][ x + y*p->temp_stride[2] ] += p->frame_dec->data[2][ x + y*p->frame_dec->linesize[2] + offset ];
+            }
+        }
+    }
+
+    for(j=0; j<3; j++){
+        int is_chroma= !!j;
+        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);
+    }
+}
+
+static int config(struct vf_instance *vf,
+        int width, int height, int d_width, int d_height,
+        unsigned int flags, unsigned int outfmt){
+        int i;
+        AVCodec *enc= avcodec_find_encoder(AV_CODEC_ID_SNOW);
+
+        for(i=0; i<3; i++){
+            int is_chroma= !!i;
+            int w= ((width  + 4*BLOCK-1) & (~(2*BLOCK-1)))>>is_chroma;
+            int h= ((height + 4*BLOCK-1) & (~(2*BLOCK-1)))>>is_chroma;
+
+            vf->priv->temp_stride[i]= w;
+            vf->priv->temp[i]= malloc(vf->priv->temp_stride[i]*h*sizeof(int16_t));
+            vf->priv->src [i]= malloc(vf->priv->temp_stride[i]*h*sizeof(uint8_t));
+        }
+        for(i=0; i< (1<<vf->priv->log2_count); i++){
+            AVCodecContext *avctx_enc;
+
+            avctx_enc=
+            vf->priv->avctx_enc[i]= avcodec_alloc_context();
+            avctx_enc->width = width + BLOCK;
+            avctx_enc->height = height + BLOCK;
+            avctx_enc->time_base= (AVRational){1,25};  // meaningless
+            avctx_enc->gop_size = 300;
+            avctx_enc->max_b_frames= 0;
+            avctx_enc->pix_fmt = AV_PIX_FMT_YUV420P;
+            avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
+            avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
+            avctx_enc->global_quality= 123;
+            avcodec_open(avctx_enc, enc);
+            assert(avctx_enc->codec);
+        }
+        vf->priv->frame= avcodec_alloc_frame();
+        vf->priv->frame_dec= avcodec_alloc_frame();
+
+        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);
+}
+
+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,
+        mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height);
+    mpi->planes[0]=vf->dmpi->planes[0];
+    mpi->stride[0]=vf->dmpi->stride[0];
+    mpi->width=vf->dmpi->width;
+    if(mpi->flags&MP_IMGFLAG_PLANAR){
+        mpi->planes[1]=vf->dmpi->planes[1];
+        mpi->planes[2]=vf->dmpi->planes[2];
+        mpi->stride[1]=vf->dmpi->stride[1];
+        mpi->stride[2]=vf->dmpi->stride[2];
+    }
+    mpi->flags|=MP_IMGFLAG_DIRECT;
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+    mp_image_t *dmpi;
+
+    if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
+        // no DR, so get a new image! hope we'll get DR buffer:
+        dmpi=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);
+    }else{
+        dmpi=vf->dmpi;
+    }
+
+    vf->priv->mpeg2= mpi->qscale_type;
+    if(vf->priv->log2_count || !(mpi->flags&MP_IMGFLAG_DIRECT)){
+        if(mpi->qscale || vf->priv->qp){
+            filter(vf->priv, dmpi->planes, mpi->planes, dmpi->stride, mpi->stride, mpi->w, mpi->h, mpi->qscale, mpi->qstride);
+        }else{
+            memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h, dmpi->stride[0], mpi->stride[0]);
+            memcpy_pic(dmpi->planes[1], mpi->planes[1], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[1], mpi->stride[1]);
+            memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->w>>mpi->chroma_x_shift, mpi->h>>mpi->chroma_y_shift, dmpi->stride[2], mpi->stride[2]);
+        }
+    }
+
+#if HAVE_MMX
+    if(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){
+    int i;
+    if(!vf->priv) return;
+
+    for(i=0; i<3; i++){
+        free(vf->priv->temp[i]);
+        vf->priv->temp[i]= NULL;
+        free(vf->priv->src[i]);
+        vf->priv->src[i]= NULL;
+    }
+    for(i=0; i<BLOCK*BLOCK; i++){
+        av_freep(&vf->priv->avctx_enc[i]);
+    }
+
+    free(vf->priv);
+    vf->priv=NULL;
+}
+
+//===========================================================================//
+static int query_format(struct vf_instance *vf, unsigned int fmt){
+    switch(fmt){
+        case IMGFMT_YV12:
+        case IMGFMT_I420:
+        case IMGFMT_IYUV:
+        case IMGFMT_Y800:
+        case IMGFMT_Y8:
+            return 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 8;
+    case VFCTRL_SET_PP_LEVEL:
+        vf->priv->log2_count= *((unsigned int*)data);
+        //FIXME we have to realloc a few things here
+        return CONTROL_TRUE;
+    }
+    return vf_next_control(vf,request,data);
+}
+
+static int vf_open(vf_instance_t *vf, char *args){
+
+    int log2c=-1;
+
+    vf->config=config;
+    vf->put_image=put_image;
+    vf->get_image=get_image;
+    vf->query_format=query_format;
+    vf->uninit=uninit;
+    vf->control= control;
+    vf->priv=malloc(sizeof(struct vf_priv_s));
+    memset(vf->priv, 0, sizeof(struct vf_priv_s));
+
+    init_avcodec();
+
+    vf->priv->log2_count= 4;
+
+    if (args) sscanf(args, "%d:%d:%d", &log2c, &vf->priv->qp, &vf->priv->mode);
+
+    if( log2c >=0 && log2c <=8 )
+        vf->priv->log2_count = log2c;
+
+    if(vf->priv->qp < 0)
+        vf->priv->qp = 0;
+
+// #if HAVE_MMX
+//     if(gCpuCaps.hasMMX){
+//         store_slice= store_slice_mmx;
+//     }
+// #endif
+
+    return 1;
+}
+
+const vf_info_t vf_info_uspp = {
+    "ultra simple/slow postprocess",
+    "uspp",
+    "Michael Niedermayer",
+    "",
+    vf_open,
+    NULL
+};
diff --git a/libavfilter/libmpcodecs/vf_yuvcsp.c b/libavfilter/libmpcodecs/vf_yuvcsp.c
new file mode 100644
index 0000000..102ce14
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_yuvcsp.c
@@ -0,0 +1,120 @@
+/*
+ * 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 csp;
+};
+
+//===========================================================================//
+
+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 inline int clamp_y(int x){
+    return (x > 235) ? 235 : (x < 16) ? 16 : x;
+}
+
+static inline int clamp_c(int x){
+    return (x > 240) ? 240 : (x < 16) ? 16 : x;
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+    int i,j;
+    uint8_t *y_in, *cb_in, *cr_in;
+    uint8_t *y_out, *cb_out, *cr_out;
+
+    vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
+        MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
+        mpi->width, mpi->height);
+
+    y_in = mpi->planes[0];
+    cb_in = mpi->planes[1];
+    cr_in = mpi->planes[2];
+
+    y_out = vf->dmpi->planes[0];
+    cb_out = vf->dmpi->planes[1];
+    cr_out = vf->dmpi->planes[2];
+
+    for (i = 0; i < mpi->height; i++)
+        for (j = 0; j < mpi->width; j++)
+            y_out[i*vf->dmpi->stride[0]+j] = clamp_y(y_in[i*mpi->stride[0]+j]);
+
+    for (i = 0; i < mpi->chroma_height; i++)
+        for (j = 0; j < mpi->chroma_width; j++)
+        {
+            cb_out[i*vf->dmpi->stride[1]+j] = clamp_c(cb_in[i*mpi->stride[1]+j]);
+            cr_out[i*vf->dmpi->stride[2]+j] = clamp_c(cr_in[i*mpi->stride[2]+j]);
+        }
+
+    return vf_next_put_image(vf,vf->dmpi, pts);
+}
+
+//===========================================================================//
+
+/*
+static void uninit(struct vf_instance *vf){
+        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:
+            return 1;
+    }
+    return 0;
+}
+
+static int vf_open(vf_instance_t *vf, char *args){
+    vf->config=config;
+    vf->put_image=put_image;
+//    vf->uninit=uninit;
+    vf->query_format=query_format;
+//    vf->priv=calloc(1, sizeof(struct vf_priv_s));
+//    if (args)
+//        vf->priv->csp = atoi(args);
+    return 1;
+}
+
+const vf_info_t vf_info_yuvcsp = {
+    "yuv colorspace converter",
+    "yuvcsp",
+    "Alex Beregszaszi",
+    "",
+    vf_open,
+    NULL
+};
+
+//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vf_yvu9.c b/libavfilter/libmpcodecs/vf_yvu9.c
new file mode 100644
index 0000000..1f74261
--- /dev/null
+++ b/libavfilter/libmpcodecs/vf_yvu9.c
@@ -0,0 +1,105 @@
+/*
+ * 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 "help_mp.h"
+
+#include "img_format.h"
+#include "mp_image.h"
+#include "vf.h"
+
+#include "libvo/fastmemcpy.h"
+
+//===========================================================================//
+
+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_next_query_format(vf,IMGFMT_YV12)<=0){
+        mp_msg(MSGT_VFILTER, MSGL_WARN, MSGTR_MPCODECS_WarnNextFilterDoesntSupport, "YVU9");
+        return 0;
+    }
+
+    return vf_next_config(vf,width,height,d_width,d_height,flags,IMGFMT_YV12);
+}
+
+static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
+    mp_image_t *dmpi;
+    int y,w,h;
+
+    // hope we'll get DR buffer:
+    dmpi=vf_get_image(vf->next,IMGFMT_YV12,
+        MP_IMGTYPE_TEMP, 0/*MP_IMGFLAG_ACCEPT_STRIDE*/,
+        mpi->w, mpi->h);
+
+    for(y=0;y<mpi->h;y++)
+        fast_memcpy(dmpi->planes[0]+dmpi->stride[0]*y,
+               mpi->planes[0]+mpi->stride[0]*y,
+               mpi->w);
+
+    w=mpi->w/4; h=mpi->h/2;
+    for(y=0;y<h;y++){
+        unsigned char* s=mpi->planes[1]+mpi->stride[1]*(y>>1);
+        unsigned char* d=dmpi->planes[1]+dmpi->stride[1]*y;
+        int x;
+        for(x=0;x<w;x++) d[2*x]=d[2*x+1]=s[x];
+    }
+    for(y=0;y<h;y++){
+        unsigned char* s=mpi->planes[2]+mpi->stride[2]*(y>>1);
+        unsigned char* d=dmpi->planes[2]+dmpi->stride[2]*y;
+        int x;
+        for(x=0;x<w;x++) d[2*x]=d[2*x+1]=s[x];
+    }
+
+    vf_clone_mpi_attributes(dmpi, mpi);
+
+    return vf_next_put_image(vf,dmpi, pts);
+}
+
+//===========================================================================//
+
+static int query_format(struct vf_instance *vf, unsigned int fmt){
+    if (fmt == IMGFMT_YVU9 || fmt == IMGFMT_IF09)
+        return vf_next_query_format(vf,IMGFMT_YV12) & (~VFCAP_CSP_SUPPORTED_BY_HW);
+    return 0;
+}
+
+static int vf_open(vf_instance_t *vf, char *args){
+    vf->config=config;
+    vf->put_image=put_image;
+    vf->query_format=query_format;
+    return 1;
+}
+
+const vf_info_t vf_info_yvu9 = {
+    "fast YVU9->YV12 conversion",
+    "yvu9",
+    "alex",
+    "",
+    vf_open,
+    NULL
+};
+
+//===========================================================================//
diff --git a/libavfilter/libmpcodecs/vfcap.h b/libavfilter/libmpcodecs/vfcap.h
new file mode 100644
index 0000000..611d642
--- /dev/null
+++ b/libavfilter/libmpcodecs/vfcap.h
@@ -0,0 +1,56 @@
+/* VFCAP_* values: they are flags, returned by query_format():
+ *
+ * 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.
+ */
+
+#ifndef MPLAYER_VFCAP_H
+#define MPLAYER_VFCAP_H
+
+// set, if the given colorspace is supported (with or without conversion)
+#define VFCAP_CSP_SUPPORTED 0x1
+// set, if the given colorspace is supported _without_ conversion
+#define VFCAP_CSP_SUPPORTED_BY_HW 0x2
+// set if the driver/filter can draw OSD
+#define VFCAP_OSD 0x4
+// set if the driver/filter can handle compressed SPU stream
+#define VFCAP_SPU 0x8
+// scaling up/down by hardware, or software:
+#define VFCAP_HWSCALE_UP 0x10
+#define VFCAP_HWSCALE_DOWN 0x20
+#define VFCAP_SWSCALE 0x40
+// driver/filter can do vertical flip (upside-down)
+#define VFCAP_FLIP 0x80
+
+// driver/hardware handles timing (blocking)
+#define VFCAP_TIMER 0x100
+// driver _always_ flip image upside-down (for ve_vfw)
+#define VFCAP_FLIPPED 0x200
+// vf filter: accepts stride (put_image)
+// vo driver: has draw_slice() support for the given csp
+#define VFCAP_ACCEPT_STRIDE 0x400
+// filter does postprocessing (so you shouldn't scale/filter image before it)
+#define VFCAP_POSTPROC 0x800
+// filter cannot be reconfigured to different size & format
+#define VFCAP_CONSTANT 0x1000
+// filter can draw EOSD
+#define VFCAP_EOSD 0x2000
+// filter will draw EOSD at screen resolution (without scaling)
+#define VFCAP_EOSD_UNSCALED 0x4000
+// used by libvo and vf_vo, indicates the VO does not support draw_slice for this format
+#define VOCAP_NOSLICES 0x8000
+
+#endif /* MPLAYER_VFCAP_H */
diff --git a/libavfilter/lswsutils.c b/libavfilter/lswsutils.c
new file mode 100644
index 0000000..6902ee9
--- /dev/null
+++ b/libavfilter/lswsutils.c
@@ -0,0 +1,50 @@
+/*
+ * 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 "lswsutils.h"
+
+int ff_scale_image(uint8_t *dst_data[4], int dst_linesize[4],
+                   int dst_w, int dst_h, enum AVPixelFormat dst_pix_fmt,
+                   uint8_t * const src_data[4], int src_linesize[4],
+                   int src_w, int src_h, enum AVPixelFormat src_pix_fmt,
+                   void *log_ctx)
+{
+    int ret;
+    struct SwsContext *sws_ctx = sws_getContext(src_w, src_h, src_pix_fmt,
+                                                dst_w, dst_h, dst_pix_fmt,
+                                                SWS_BILINEAR, NULL, NULL, NULL);
+    if (!sws_ctx) {
+        av_log(log_ctx, AV_LOG_ERROR,
+               "Impossible to create scale context for the conversion "
+               "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
+               av_get_pix_fmt_name(src_pix_fmt), src_w, src_h,
+               av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h);
+        ret = AVERROR(EINVAL);
+        goto end;
+    }
+
+    if ((ret = av_image_alloc(dst_data, dst_linesize, dst_w, dst_h, dst_pix_fmt, 16)) < 0)
+        goto end;
+    ret = 0;
+    sws_scale(sws_ctx, (const uint8_t * const*)src_data, src_linesize, 0, src_h, dst_data, dst_linesize);
+
+end:
+    sws_freeContext(sws_ctx);
+    return ret;
+}
diff --git a/libavfilter/lswsutils.h b/libavfilter/lswsutils.h
new file mode 100644
index 0000000..f5f5320
--- /dev/null
+++ b/libavfilter/lswsutils.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
+ */
+
+/**
+ * @file
+ * Miscellaneous utilities which make use of the libswscale library
+ */
+
+#ifndef AVFILTER_LSWSUTILS_H
+#define AVFILTER_LSWSUTILS_H
+
+#include "libswscale/swscale.h"
+
+/**
+ * Scale image using libswscale.
+ */
+int ff_scale_image(uint8_t *dst_data[4], int dst_linesize[4],
+                   int dst_w, int dst_h, enum AVPixelFormat dst_pix_fmt,
+                   uint8_t *const src_data[4], int src_linesize[4],
+                   int src_w, int src_h, enum AVPixelFormat src_pix_fmt,
+                   void *log_ctx);
+
+#endif  /* AVFILTER_LSWSUTILS_H */
diff --git a/libavfilter/sink_buffer.c b/libavfilter/sink_buffer.c
new file mode 100644
index 0000000..7d39588
--- /dev/null
+++ b/libavfilter/sink_buffer.c
@@ -0,0 +1,452 @@
+/*
+ * 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
+ * buffer sink
+ */
+
+#include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
+#include "libavutil/fifo.h"
+#include "avfilter.h"
+#include "buffersink.h"
+#include "audio.h"
+#include "internal.h"
+
+AVBufferSinkParams *av_buffersink_params_alloc(void)
+{
+    static const int pixel_fmts[] = { -1 };
+    AVBufferSinkParams *params = av_malloc(sizeof(AVBufferSinkParams));
+    if (!params)
+        return NULL;
+
+    params->pixel_fmts = pixel_fmts;
+    return params;
+}
+
+AVABufferSinkParams *av_abuffersink_params_alloc(void)
+{
+    static const int sample_fmts[] = { -1 };
+    static const int64_t channel_layouts[] = { -1 };
+    AVABufferSinkParams *params = av_malloc(sizeof(AVABufferSinkParams));
+
+    if (!params)
+        return NULL;
+
+    params->sample_fmts = sample_fmts;
+    params->channel_layouts = channel_layouts;
+    return params;
+}
+
+typedef struct {
+    AVFifoBuffer *fifo;                      ///< FIFO buffer of video frame references
+    unsigned warning_limit;
+
+    /* only used for video */
+    enum AVPixelFormat *pixel_fmts;           ///< list of accepted pixel formats, must be terminated with -1
+
+    /* 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
+} BufferSinkContext;
+
+#define FIFO_INIT_SIZE 8
+
+static av_cold int common_init(AVFilterContext *ctx)
+{
+    BufferSinkContext *buf = ctx->priv;
+
+    buf->fifo = av_fifo_alloc(FIFO_INIT_SIZE*sizeof(AVFilterBufferRef *));
+    if (!buf->fifo) {
+        av_log(ctx, AV_LOG_ERROR, "Failed to allocate fifo\n");
+        return AVERROR(ENOMEM);
+    }
+    buf->warning_limit = 100;
+    return 0;
+}
+
+static av_cold void common_uninit(AVFilterContext *ctx)
+{
+    BufferSinkContext *buf = ctx->priv;
+    AVFilterBufferRef *picref;
+
+    if (buf->fifo) {
+        while (av_fifo_size(buf->fifo) >= sizeof(AVFilterBufferRef *)) {
+            av_fifo_generic_read(buf->fifo, &picref, sizeof(picref), NULL);
+            avfilter_unref_buffer(picref);
+        }
+        av_fifo_free(buf->fifo);
+        buf->fifo = NULL;
+    }
+}
+
+static int add_buffer_ref(AVFilterContext *ctx, AVFilterBufferRef *ref)
+{
+    BufferSinkContext *buf = ctx->priv;
+
+    if (av_fifo_space(buf->fifo) < sizeof(AVFilterBufferRef *)) {
+        /* realloc fifo size */
+        if (av_fifo_realloc2(buf->fifo, av_fifo_size(buf->fifo) * 2) < 0) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Cannot buffer more frames. Consume some available frames "
+                   "before adding new ones.\n");
+            return AVERROR(ENOMEM);
+        }
+    }
+
+    /* cache frame */
+    av_fifo_generic_write(buf->fifo, &ref, sizeof(AVFilterBufferRef *), NULL);
+    return 0;
+}
+
+static int end_frame(AVFilterLink *inlink)
+{
+    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)
+        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,
+               "%d buffers queued in %s, something may be wrong.\n",
+               buf->warning_limit,
+               (char *)av_x_if_null(ctx->name, ctx->filter->name));
+        buf->warning_limit *= 10;
+    }
+    return 0;
+}
+
+void av_buffersink_set_frame_size(AVFilterContext *ctx, unsigned frame_size)
+{
+    AVFilterLink *inlink = ctx->inputs[0];
+
+    inlink->min_samples = inlink->max_samples =
+    inlink->partial_buf_size = frame_size;
+}
+
+int av_buffersink_get_buffer_ref(AVFilterContext *ctx,
+                                  AVFilterBufferRef **bufref, int flags)
+{
+    BufferSinkContext *buf = ctx->priv;
+    AVFilterLink *inlink = ctx->inputs[0];
+    int ret;
+    *bufref = NULL;
+
+    av_assert0(    !strcmp(ctx->filter->name, "buffersink")
+                || !strcmp(ctx->filter->name, "abuffersink")
+                || !strcmp(ctx->filter->name, "ffbuffersink")
+                || !strcmp(ctx->filter->name, "ffabuffersink"));
+
+    /* no picref available, fetch it from the filterchain */
+    if (!av_fifo_size(buf->fifo)) {
+        if (flags & AV_BUFFERSINK_FLAG_NO_REQUEST)
+            return AVERROR(EAGAIN);
+        if ((ret = ff_request_frame(inlink)) < 0)
+            return ret;
+    }
+
+    if (!av_fifo_size(buf->fifo))
+        return AVERROR(EINVAL);
+
+    if (flags & AV_BUFFERSINK_FLAG_PEEK)
+        *bufref = *((AVFilterBufferRef **)av_fifo_peek2(buf->fifo, 0));
+    else
+        av_fifo_generic_read(buf->fifo, bufref, sizeof(*bufref), NULL);
+
+    return 0;
+}
+
+AVRational av_buffersink_get_frame_rate(AVFilterContext *ctx)
+{
+    av_assert0(   !strcmp(ctx->filter->name, "buffersink")
+               || !strcmp(ctx->filter->name, "ffbuffersink"));
+
+    return ctx->inputs[0]->frame_rate;
+}
+
+int av_buffersink_poll_frame(AVFilterContext *ctx)
+{
+    BufferSinkContext *buf = ctx->priv;
+    AVFilterLink *inlink = ctx->inputs[0];
+
+    av_assert0(   !strcmp(ctx->filter->name, "buffersink")
+               || !strcmp(ctx->filter->name, "abuffersink")
+               || !strcmp(ctx->filter->name, "ffbuffersink")
+               || !strcmp(ctx->filter->name, "ffabuffersink"));
+
+    return av_fifo_size(buf->fifo)/sizeof(AVFilterBufferRef *) + ff_poll_frame(inlink);
+}
+
+static av_cold int vsink_init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+    BufferSinkContext *buf = ctx->priv;
+    AVBufferSinkParams *params = opaque;
+
+    if (params && params->pixel_fmts) {
+        const int *pixel_fmts = params->pixel_fmts;
+
+        buf->pixel_fmts = ff_copy_int_list(pixel_fmts);
+        if (!buf->pixel_fmts)
+            return AVERROR(ENOMEM);
+    }
+
+    return common_init(ctx);
+}
+
+static av_cold void vsink_uninit(AVFilterContext *ctx)
+{
+    BufferSinkContext *buf = ctx->priv;
+    av_freep(&buf->pixel_fmts);
+    common_uninit(ctx);
+}
+
+static int vsink_query_formats(AVFilterContext *ctx)
+{
+    BufferSinkContext *buf = ctx->priv;
+
+    if (buf->pixel_fmts)
+        ff_set_common_formats(ctx, ff_make_format_list(buf->pixel_fmts));
+    else
+        ff_default_query_formats(ctx);
+
+    return 0;
+}
+
+AVFilter avfilter_vsink_ffbuffersink = {
+    .name      = "ffbuffersink",
+    .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
+    .priv_size = sizeof(BufferSinkContext),
+    .init_opaque = vsink_init,
+    .uninit    = vsink_uninit,
+
+    .query_formats = vsink_query_formats,
+
+    .inputs    = (const AVFilterPad[]) {{ .name    = "default",
+                                    .type          = AVMEDIA_TYPE_VIDEO,
+                                    .end_frame     = end_frame,
+                                    .min_perms     = AV_PERM_READ | AV_PERM_PRESERVE, },
+                                  { .name = NULL }},
+    .outputs   = (const AVFilterPad[]) {{ .name = NULL }},
+};
+
+AVFilter avfilter_vsink_buffersink = {
+    .name      = "buffersink",
+    .description = NULL_IF_CONFIG_SMALL("Buffer video frames, and make them available to the end of the filter graph."),
+    .priv_size = sizeof(BufferSinkContext),
+    .init_opaque = vsink_init,
+    .uninit    = vsink_uninit,
+
+    .query_formats = vsink_query_formats,
+
+    .inputs    = (const AVFilterPad[]) {{ .name    = "default",
+                                    .type          = AVMEDIA_TYPE_VIDEO,
+                                    .end_frame     = end_frame,
+                                    .min_perms     = AV_PERM_READ | AV_PERM_PRESERVE, },
+                                  { .name = NULL }},
+    .outputs   = (const AVFilterPad[]) {{ .name = NULL }},
+};
+
+static int filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref)
+{
+    end_frame(link);
+    return 0;
+}
+
+static av_cold int asink_init(AVFilterContext *ctx, const char *args, void *opaque)
+{
+    BufferSinkContext *buf = ctx->priv;
+    AVABufferSinkParams *params = opaque;
+
+    if (params && params->sample_fmts) {
+        buf->sample_fmts     = ff_copy_int_list  (params->sample_fmts);
+        if (!buf->sample_fmts)
+            goto fail_enomem;
+    }
+    if (params && params->channel_layouts) {
+        buf->channel_layouts = ff_copy_int64_list(params->channel_layouts);
+        if (!buf->channel_layouts)
+            goto fail_enomem;
+    }
+    if (!common_init(ctx))
+        return 0;
+
+fail_enomem:
+    av_freep(&buf->sample_fmts);
+    av_freep(&buf->channel_layouts);
+    return AVERROR(ENOMEM);
+}
+
+static av_cold void asink_uninit(AVFilterContext *ctx)
+{
+    BufferSinkContext *buf = ctx->priv;
+
+    av_freep(&buf->sample_fmts);
+    av_freep(&buf->channel_layouts);
+    common_uninit(ctx);
+}
+
+static int asink_query_formats(AVFilterContext *ctx)
+{
+    BufferSinkContext *buf = ctx->priv;
+    AVFilterFormats *formats = NULL;
+    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 (buf->channel_layouts) {
+    if (!(layouts = avfilter_make_format64_list(buf->channel_layouts)))
+        return AVERROR(ENOMEM);
+    ff_set_common_channel_layouts(ctx, layouts);
+    }
+
+    return 0;
+}
+
+AVFilter avfilter_asink_ffabuffersink = {
+    .name      = "ffabuffersink",
+    .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
+    .init_opaque = asink_init,
+    .uninit    = asink_uninit,
+    .priv_size = sizeof(BufferSinkContext),
+    .query_formats = asink_query_formats,
+
+    .inputs    = (const AVFilterPad[]) {{ .name     = "default",
+                                    .type           = AVMEDIA_TYPE_AUDIO,
+                                    .filter_samples = filter_samples,
+                                    .min_perms      = AV_PERM_READ | AV_PERM_PRESERVE, },
+                                  { .name = NULL }},
+    .outputs   = (const AVFilterPad[]) {{ .name = NULL }},
+};
+
+AVFilter avfilter_asink_abuffersink = {
+    .name      = "abuffersink",
+    .description = NULL_IF_CONFIG_SMALL("Buffer audio frames, and make them available to the end of the filter graph."),
+    .init_opaque = asink_init,
+    .uninit    = asink_uninit,
+    .priv_size = sizeof(BufferSinkContext),
+    .query_formats = asink_query_formats,
+
+    .inputs    = (const AVFilterPad[]) {{ .name     = "default",
+                                    .type           = AVMEDIA_TYPE_AUDIO,
+                                    .filter_samples = filter_samples,
+                                    .min_perms      = AV_PERM_READ | AV_PERM_PRESERVE, },
+                                  { .name = NULL }},
+    .outputs   = (const AVFilterPad[]) {{ .name = NULL }},
+};
+
+/* Libav compatibility API */
+
+extern AVFilter avfilter_vsink_buffer;
+extern AVFilter avfilter_asink_abuffer;
+
+int av_buffersink_read(AVFilterContext *ctx, AVFilterBufferRef **buf)
+{
+    AVFilterBufferRef *tbuf;
+    int ret;
+
+    if (ctx->filter->          inputs[0].start_frame ==
+        avfilter_vsink_buffer. inputs[0].start_frame ||
+        ctx->filter->          inputs[0].filter_samples ==
+        avfilter_asink_abuffer.inputs[0].filter_samples)
+        return ff_buffersink_read_compat(ctx, buf);
+    av_assert0(ctx->filter->                inputs[0].end_frame ==
+               avfilter_vsink_ffbuffersink. inputs[0].end_frame ||
+               ctx->filter->                inputs[0].filter_samples ==
+               avfilter_asink_ffabuffersink.inputs[0].filter_samples);
+
+    ret = av_buffersink_get_buffer_ref(ctx, &tbuf,
+                                       buf ? 0 : AV_BUFFERSINK_FLAG_PEEK);
+    if (!buf)
+        return ret >= 0;
+    if (ret < 0)
+        return ret;
+    *buf = tbuf;
+    return 0;
+}
+
+int av_buffersink_read_samples(AVFilterContext *ctx, AVFilterBufferRef **buf,
+                               int nb_samples)
+{
+    BufferSinkContext *sink = ctx->priv;
+    int ret = 0, have_samples = 0, need_samples;
+    AVFilterBufferRef *tbuf, *in_buf;
+    AVFilterLink *link = ctx->inputs[0];
+    int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);
+
+    if (ctx->filter->          inputs[0].filter_samples ==
+        avfilter_asink_abuffer.inputs[0].filter_samples)
+        return ff_buffersink_read_samples_compat(ctx, buf, nb_samples);
+    av_assert0(ctx->filter->                inputs[0].filter_samples ==
+               avfilter_asink_ffabuffersink.inputs[0].filter_samples);
+
+    tbuf = ff_get_audio_buffer(link, AV_PERM_WRITE, nb_samples);
+    if (!tbuf)
+        return AVERROR(ENOMEM);
+
+    while (have_samples < nb_samples) {
+        ret = av_buffersink_get_buffer_ref(ctx, &in_buf,
+                                           AV_BUFFERSINK_FLAG_PEEK);
+        if (ret < 0) {
+            if (ret == AVERROR_EOF && have_samples) {
+                nb_samples = have_samples;
+                ret = 0;
+            }
+            break;
+        }
+
+        need_samples = FFMIN(in_buf->audio->nb_samples,
+                             nb_samples - have_samples);
+        av_samples_copy(tbuf->extended_data, in_buf->extended_data,
+                        have_samples, 0, need_samples,
+                        nb_channels, in_buf->format);
+        have_samples += need_samples;
+        if (need_samples < in_buf->audio->nb_samples) {
+            in_buf->audio->nb_samples -= need_samples;
+            av_samples_copy(in_buf->extended_data, in_buf->extended_data,
+                            0, need_samples, in_buf->audio->nb_samples,
+                            nb_channels, in_buf->format);
+        } else {
+            av_buffersink_get_buffer_ref(ctx, &in_buf, 0);
+            avfilter_unref_buffer(in_buf);
+        }
+    }
+    tbuf->audio->nb_samples = have_samples;
+
+    if (ret < 0) {
+        av_assert0(!av_fifo_size(sink->fifo));
+        if (have_samples)
+            add_buffer_ref(ctx, tbuf);
+        else
+            avfilter_unref_buffer(tbuf);
+        return ret;
+    }
+
+    *buf = tbuf;
+    return 0;
+}
diff --git a/libavfilter/split.c b/libavfilter/split.c
index 01bb448..30cc3e5 100644
--- a/libavfilter/split.c
+++ b/libavfilter/split.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -52,6 +52,7 @@
         snprintf(name, sizeof(name), "output%d", i);
         pad.type = ctx->filter->inputs[0].type;
         pad.name = av_strdup(name);
+        pad.rej_perms = AV_PERM_WRITE;
 
         ff_insert_outpad(ctx, i, &pad);
     }
@@ -70,10 +71,14 @@
 static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
 {
     AVFilterContext *ctx = inlink->dst;
-    int i, ret = 0;
+    int i, ret = AVERROR_EOF;
 
     for (i = 0; i < ctx->nb_outputs; i++) {
-        AVFilterBufferRef *buf_out = avfilter_ref_buffer(picref, ~AV_PERM_WRITE);
+        AVFilterBufferRef *buf_out;
+
+        if (ctx->outputs[i]->closed)
+            continue;
+        buf_out = avfilter_ref_buffer(picref, ~AV_PERM_WRITE);
         if (!buf_out)
             return AVERROR(ENOMEM);
 
@@ -87,9 +92,11 @@
 static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
 {
     AVFilterContext *ctx = inlink->dst;
-    int i, ret = 0;
+    int i, ret = AVERROR_EOF;
 
     for (i = 0; i < ctx->nb_outputs; i++) {
+        if (ctx->outputs[i]->closed)
+            continue;
         ret = ff_draw_slice(ctx->outputs[i], y, h, slice_dir);
         if (ret < 0)
             break;
@@ -100,9 +107,11 @@
 static int end_frame(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
-    int i, ret = 0;
+    int i, ret = AVERROR_EOF;
 
     for (i = 0; i < ctx->nb_outputs; i++) {
+        if (ctx->outputs[i]->closed)
+            continue;
         ret = ff_end_frame(ctx->outputs[i]);
         if (ret < 0)
             break;
@@ -124,7 +133,7 @@
 
 AVFilter avfilter_vf_split = {
     .name      = "split",
-    .description = NULL_IF_CONFIG_SMALL("Pass on the input to two outputs."),
+    .description = NULL_IF_CONFIG_SMALL("Pass on the input video to N outputs."),
 
     .init   = split_init,
     .uninit = split_uninit,
diff --git a/libavfilter/src_buffer.c b/libavfilter/src_buffer.c
new file mode 100644
index 0000000..354a516
--- /dev/null
+++ b/libavfilter/src_buffer.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2008 Vitor Sessak
+ * Copyright (c) 2010 S.N. Hemanth Meenakshisundaram
+ * Copyright (c) 2011 Mina Nagy Zaki
+ *
+ * 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
+ * memory buffer source filter
+ */
+
+#include "avfilter.h"
+#include "internal.h"
+#include "audio.h"
+#include "avcodec.h"
+#include "buffersrc.h"
+#include "asrc_abuffer.h"
+#include "libavutil/audioconvert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/fifo.h"
+#include "libavutil/imgutils.h"
+
+typedef struct {
+    AVFifoBuffer     *fifo;
+    AVRational        time_base;     ///< time_base to set in the output link
+    int eof;
+    unsigned          nb_failed_requests;
+
+    /* Video only */
+    AVFilterContext  *scale;
+    int               h, w;
+    enum AVPixelFormat  pix_fmt;
+    AVRational        sample_aspect_ratio;
+    char              sws_param[256];
+
+    /* Audio only */
+    // Audio format of incoming buffers
+    int sample_rate;
+    unsigned int sample_format;
+    int64_t channel_layout;
+
+    // Normalization filters
+    AVFilterContext *aconvert;
+    AVFilterContext *aresample;
+} BufferSourceContext;
+
+static void buf_free(AVFilterBuffer *ptr)
+{
+    av_free(ptr);
+    return;
+}
+
+int av_asrc_buffer_add_audio_buffer_ref(AVFilterContext *ctx,
+                                        AVFilterBufferRef *samplesref,
+                                        int av_unused flags)
+{
+    return av_buffersrc_add_ref(ctx, samplesref, AV_BUFFERSRC_FLAG_NO_COPY);
+}
+
+int av_asrc_buffer_add_samples(AVFilterContext *ctx,
+                               uint8_t *data[8], int linesize[8],
+                               int nb_samples, int sample_rate,
+                               int sample_fmt, int64_t channel_layout, int planar,
+                               int64_t pts, int av_unused flags)
+{
+    AVFilterBufferRef *samplesref;
+
+    samplesref = avfilter_get_audio_buffer_ref_from_arrays(
+                     data, linesize[0], AV_PERM_WRITE,
+                     nb_samples,
+                     sample_fmt, channel_layout);
+    if (!samplesref)
+        return AVERROR(ENOMEM);
+
+    samplesref->buf->free  = buf_free;
+    samplesref->pts = pts;
+    samplesref->audio->sample_rate = sample_rate;
+
+    AV_NOWARN_DEPRECATED(
+    return av_asrc_buffer_add_audio_buffer_ref(ctx, samplesref, 0);
+    )
+}
+
+int av_asrc_buffer_add_buffer(AVFilterContext *ctx,
+                              uint8_t *buf, int buf_size, int sample_rate,
+                              int sample_fmt, int64_t channel_layout, int planar,
+                              int64_t pts, int av_unused flags)
+{
+    uint8_t *data[8] = {0};
+    int linesize[8];
+    int nb_channels = av_get_channel_layout_nb_channels(channel_layout),
+        nb_samples  = buf_size / nb_channels / av_get_bytes_per_sample(sample_fmt);
+
+    av_samples_fill_arrays(data, linesize,
+                           buf, nb_channels, nb_samples,
+                           sample_fmt, 16);
+
+    AV_NOWARN_DEPRECATED(
+    return av_asrc_buffer_add_samples(ctx,
+                                      data, linesize, nb_samples,
+                                      sample_rate,
+                                      sample_fmt, channel_layout, planar,
+                                      pts, flags);
+    )
+}
diff --git a/libavfilter/src_movie.c b/libavfilter/src_movie.c
new file mode 100644
index 0000000..8ebad6d
--- /dev/null
+++ b/libavfilter/src_movie.c
@@ -0,0 +1,644 @@
+/*
+ * Copyright (c) 2010 Stefano Sabatini
+ * Copyright (c) 2008 Victor Paesa
+ *
+ * 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
+ * movie video source
+ *
+ * @todo use direct rendering (no allocation of a new frame)
+ * @todo support a PTS correction mechanism
+ */
+
+/* #define DEBUG */
+
+#include <float.h>
+#include "libavutil/avstring.h"
+#include "libavutil/avassert.h"
+#include "libavutil/opt.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/timestamp.h"
+#include "libavformat/avformat.h"
+#include "audio.h"
+#include "avcodec.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+typedef struct {
+    AVStream *st;
+    int done;
+} MovieStream;
+
+typedef struct {
+    /* common A/V fields */
+    const AVClass *class;
+    int64_t seek_point;   ///< seekpoint in microseconds
+    double seek_point_d;
+    char *format_name;
+    char *file_name;
+    char *stream_specs; /**< user-provided list of streams, separated by + */
+    int stream_index; /**< for compatibility */
+    int loop_count;
+
+    AVFormatContext *format_ctx;
+    int eof;
+    AVPacket pkt, pkt0;
+    AVFrame *frame;   ///< video frame to store the decoded images in
+
+    int max_stream_index; /**< max stream # actually used for output */
+    MovieStream *st; /**< array of all streams, one per output */
+    int *out_index; /**< stream number -> output number map, or -1 */
+} MovieContext;
+
+#define OFFSET(x) offsetof(MovieContext, x)
+#define F AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption movie_options[]= {
+{"format_name",  "set format name",         OFFSET(format_name),  AV_OPT_TYPE_STRING, {.str =  0},  CHAR_MIN, CHAR_MAX, F },
+{"f",            "set format name",         OFFSET(format_name),  AV_OPT_TYPE_STRING, {.str =  0},  CHAR_MIN, CHAR_MAX, F },
+{"streams",      "set streams",             OFFSET(stream_specs), AV_OPT_TYPE_STRING, {.str =  0},  CHAR_MAX, CHAR_MAX, F },
+{"s",            "set streams",             OFFSET(stream_specs), AV_OPT_TYPE_STRING, {.str =  0},  CHAR_MAX, CHAR_MAX, F },
+{"si",           "set stream index",        OFFSET(stream_index), AV_OPT_TYPE_INT,    {.i64 = -1},  -1,       INT_MAX, F },
+{"stream_index", "set stream index",        OFFSET(stream_index), AV_OPT_TYPE_INT,    {.i64 = -1},  -1,       INT_MAX, F },
+{"seek_point",   "set seekpoint (seconds)", OFFSET(seek_point_d), AV_OPT_TYPE_DOUBLE, {.dbl =  0},  0,        (INT64_MAX-1) / 1000000, F },
+{"sp",           "set seekpoint (seconds)", OFFSET(seek_point_d), AV_OPT_TYPE_DOUBLE, {.dbl =  0},  0,        (INT64_MAX-1) / 1000000, F },
+{"loop",         "set loop count",          OFFSET(loop_count),   AV_OPT_TYPE_INT,    {.i64 =  1},  0,        INT_MAX, F },
+{NULL},
+};
+
+static int movie_config_output_props(AVFilterLink *outlink);
+static int movie_request_frame(AVFilterLink *outlink);
+
+static AVStream *find_stream(void *log, AVFormatContext *avf, const char *spec)
+{
+    int i, ret, already = 0, stream_id = -1;
+    char type_char, dummy;
+    AVStream *found = NULL;
+    enum AVMediaType type;
+
+    ret = sscanf(spec, "d%[av]%d%c", &type_char, &stream_id, &dummy);
+    if (ret >= 1 && ret <= 2) {
+        type = type_char == 'v' ? AVMEDIA_TYPE_VIDEO : AVMEDIA_TYPE_AUDIO;
+        ret = av_find_best_stream(avf, type, stream_id, -1, NULL, 0);
+        if (ret < 0) {
+            av_log(log, AV_LOG_ERROR, "No %s stream with index '%d' found\n",
+                   av_get_media_type_string(type), stream_id);
+            return NULL;
+        }
+        return avf->streams[ret];
+    }
+    for (i = 0; i < avf->nb_streams; i++) {
+        ret = avformat_match_stream_specifier(avf, avf->streams[i], spec);
+        if (ret < 0) {
+            av_log(log, AV_LOG_ERROR,
+                   "Invalid stream specifier \"%s\"\n", spec);
+            return NULL;
+        }
+        if (!ret)
+            continue;
+        if (avf->streams[i]->discard != AVDISCARD_ALL) {
+            already++;
+            continue;
+        }
+        if (found) {
+            av_log(log, AV_LOG_WARNING,
+                   "Ambiguous stream specifier \"%s\", using #%d\n", spec, i);
+            break;
+        }
+        found = avf->streams[i];
+    }
+    if (!found) {
+        av_log(log, AV_LOG_WARNING, "Stream specifier \"%s\" %s\n", spec,
+               already ? "matched only already used streams" :
+                         "did not match any stream");
+        return NULL;
+    }
+    if (found->codec->codec_type != AVMEDIA_TYPE_VIDEO &&
+        found->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
+        av_log(log, AV_LOG_ERROR, "Stream specifier \"%s\" matched a %s stream,"
+               "currently unsupported by libavfilter\n", spec,
+               av_get_media_type_string(found->codec->codec_type));
+        return NULL;
+    }
+    return found;
+}
+
+static int open_stream(void *log, MovieStream *st)
+{
+    AVCodec *codec;
+    int ret;
+
+    codec = avcodec_find_decoder(st->st->codec->codec_id);
+    if (!codec) {
+        av_log(log, AV_LOG_ERROR, "Failed to find any codec\n");
+        return AVERROR(EINVAL);
+    }
+
+    if ((ret = avcodec_open2(st->st->codec, codec, NULL)) < 0) {
+        av_log(log, AV_LOG_ERROR, "Failed to open codec\n");
+        return ret;
+    }
+
+    return 0;
+}
+
+static int guess_channel_layout(MovieStream *st, int st_index, void *log_ctx)
+{
+    AVCodecContext *dec_ctx = st->st->codec;
+    char buf[256];
+    int64_t chl = av_get_default_channel_layout(dec_ctx->channels);
+
+    if (!chl) {
+        av_log(log_ctx, AV_LOG_ERROR,
+               "Channel layout is not set in stream %d, and could not "
+               "be guessed from the number of channels (%d)\n",
+               st_index, dec_ctx->channels);
+        return AVERROR(EINVAL);
+    }
+
+    av_get_channel_layout_string(buf, sizeof(buf), dec_ctx->channels, chl);
+    av_log(log_ctx, AV_LOG_WARNING,
+           "Channel layout is not set in output stream %d, "
+           "guessed channel layout is '%s'\n",
+           st_index, buf);
+    dec_ctx->channel_layout = chl;
+    return 0;
+}
+
+static av_cold int movie_common_init(AVFilterContext *ctx, const char *args, const AVClass *class)
+{
+    MovieContext *movie = ctx->priv;
+    AVInputFormat *iformat = NULL;
+    int64_t timestamp;
+    int nb_streams, ret, i;
+    char default_streams[16], *stream_specs, *spec, *cursor;
+    char name[16];
+    AVStream *st;
+
+    movie->class = class;
+    av_opt_set_defaults(movie);
+
+    if (args)
+        movie->file_name = av_get_token(&args, ":");
+    if (!movie->file_name || !*movie->file_name) {
+        av_log(ctx, AV_LOG_ERROR, "No filename provided!\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (*args++ == ':' && (ret = av_set_options_string(movie, args, "=", ":")) < 0)
+        return ret;
+
+    movie->seek_point = movie->seek_point_d * 1000000 + 0.5;
+
+    stream_specs = movie->stream_specs;
+    if (!stream_specs) {
+        snprintf(default_streams, sizeof(default_streams), "d%c%d",
+                 !strcmp(ctx->filter->name, "amovie") ? 'a' : 'v',
+                 movie->stream_index);
+        stream_specs = default_streams;
+    }
+    for (cursor = stream_specs, nb_streams = 1; *cursor; cursor++)
+        if (*cursor == '+')
+            nb_streams++;
+
+    if (movie->loop_count != 1 && nb_streams != 1) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Loop with several streams is currently unsupported\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    av_register_all();
+
+    // Try to find the movie format (container)
+    iformat = movie->format_name ? av_find_input_format(movie->format_name) : NULL;
+
+    movie->format_ctx = NULL;
+    if ((ret = avformat_open_input(&movie->format_ctx, movie->file_name, iformat, NULL)) < 0) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Failed to avformat_open_input '%s'\n", movie->file_name);
+        return ret;
+    }
+    if ((ret = avformat_find_stream_info(movie->format_ctx, NULL)) < 0)
+        av_log(ctx, AV_LOG_WARNING, "Failed to find stream info\n");
+
+    // if seeking requested, we execute it
+    if (movie->seek_point > 0) {
+        timestamp = movie->seek_point;
+        // add the stream start time, should it exist
+        if (movie->format_ctx->start_time != AV_NOPTS_VALUE) {
+            if (timestamp > INT64_MAX - movie->format_ctx->start_time) {
+                av_log(ctx, AV_LOG_ERROR,
+                       "%s: seek value overflow with start_time:%"PRId64" seek_point:%"PRId64"\n",
+                       movie->file_name, movie->format_ctx->start_time, movie->seek_point);
+                return AVERROR(EINVAL);
+            }
+            timestamp += movie->format_ctx->start_time;
+        }
+        if ((ret = av_seek_frame(movie->format_ctx, -1, timestamp, AVSEEK_FLAG_BACKWARD)) < 0) {
+            av_log(ctx, AV_LOG_ERROR, "%s: could not seek to position %"PRId64"\n",
+                   movie->file_name, timestamp);
+            return ret;
+        }
+    }
+
+    for (i = 0; i < movie->format_ctx->nb_streams; i++)
+        movie->format_ctx->streams[i]->discard = AVDISCARD_ALL;
+
+    movie->st = av_calloc(nb_streams, sizeof(*movie->st));
+    if (!movie->st)
+        return AVERROR(ENOMEM);
+
+    for (i = 0; i < nb_streams; i++) {
+        spec = av_strtok(stream_specs, "+", &cursor);
+        if (!spec)
+            return AVERROR_BUG;
+        stream_specs = NULL; /* for next strtok */
+        st = find_stream(ctx, movie->format_ctx, spec);
+        if (!st)
+            return AVERROR(EINVAL);
+        st->discard = AVDISCARD_DEFAULT;
+        movie->st[i].st = st;
+        movie->max_stream_index = FFMAX(movie->max_stream_index, st->index);
+    }
+    if (av_strtok(NULL, "+", &cursor))
+        return AVERROR_BUG;
+
+    movie->out_index = av_calloc(movie->max_stream_index + 1,
+                                 sizeof(*movie->out_index));
+    if (!movie->out_index)
+        return AVERROR(ENOMEM);
+    for (i = 0; i <= movie->max_stream_index; i++)
+        movie->out_index[i] = -1;
+    for (i = 0; i < nb_streams; i++)
+        movie->out_index[movie->st[i].st->index] = i;
+
+    for (i = 0; i < nb_streams; i++) {
+        AVFilterPad pad = { 0 };
+        snprintf(name, sizeof(name), "out%d", i);
+        pad.type          = movie->st[i].st->codec->codec_type;
+        pad.name          = av_strdup(name);
+        pad.config_props  = movie_config_output_props;
+        pad.request_frame = movie_request_frame;
+        ff_insert_outpad(ctx, i, &pad);
+        ret = open_stream(ctx, &movie->st[i]);
+        if (ret < 0)
+            return ret;
+        if ( movie->st[i].st->codec->codec->type == AVMEDIA_TYPE_AUDIO &&
+            !movie->st[i].st->codec->channel_layout) {
+            ret = guess_channel_layout(&movie->st[i], i, ctx);
+            if (ret < 0)
+                return ret;
+        }
+    }
+
+    if (!(movie->frame = avcodec_alloc_frame()) ) {
+        av_log(log, AV_LOG_ERROR, "Failed to alloc frame\n");
+        return AVERROR(ENOMEM);
+    }
+
+    av_log(ctx, AV_LOG_VERBOSE, "seek_point:%"PRIi64" format_name:%s file_name:%s stream_index:%d\n",
+           movie->seek_point, movie->format_name, movie->file_name,
+           movie->stream_index);
+
+    return 0;
+}
+
+static av_cold void movie_uninit(AVFilterContext *ctx)
+{
+    MovieContext *movie = ctx->priv;
+    int i;
+
+    for (i = 0; i < ctx->nb_outputs; i++) {
+        av_freep(&ctx->output_pads[i].name);
+        if (movie->st[i].st)
+            avcodec_close(movie->st[i].st->codec);
+    }
+    av_opt_free(movie);
+    av_freep(&movie->file_name);
+    av_freep(&movie->st);
+    av_freep(&movie->out_index);
+    avcodec_free_frame(&movie->frame);
+    if (movie->format_ctx)
+        avformat_close_input(&movie->format_ctx);
+}
+
+static int movie_query_formats(AVFilterContext *ctx)
+{
+    MovieContext *movie = ctx->priv;
+    int list[] = { 0, -1 };
+    int64_t list64[] = { 0, -1 };
+    int i;
+
+    for (i = 0; i < ctx->nb_outputs; i++) {
+        MovieStream *st = &movie->st[i];
+        AVCodecContext *c = st->st->codec;
+        AVFilterLink *outlink = ctx->outputs[i];
+
+        switch (c->codec_type) {
+        case AVMEDIA_TYPE_VIDEO:
+            list[0] = c->pix_fmt;
+            ff_formats_ref(ff_make_format_list(list), &outlink->in_formats);
+            break;
+        case AVMEDIA_TYPE_AUDIO:
+            list[0] = c->sample_fmt;
+            ff_formats_ref(ff_make_format_list(list), &outlink->in_formats);
+            list[0] = c->sample_rate;
+            ff_formats_ref(ff_make_format_list(list), &outlink->in_samplerates);
+            list64[0] = c->channel_layout;
+            ff_channel_layouts_ref(avfilter_make_format64_list(list64),
+                                   &outlink->in_channel_layouts);
+            break;
+        }
+    }
+
+    return 0;
+}
+
+static int movie_config_output_props(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    MovieContext *movie  = ctx->priv;
+    unsigned out_id = FF_OUTLINK_IDX(outlink);
+    MovieStream *st = &movie->st[out_id];
+    AVCodecContext *c = st->st->codec;
+
+    outlink->time_base = st->st->time_base;
+
+    switch (c->codec_type) {
+    case AVMEDIA_TYPE_VIDEO:
+        outlink->w          = c->width;
+        outlink->h          = c->height;
+        outlink->frame_rate = st->st->r_frame_rate;
+        break;
+    case AVMEDIA_TYPE_AUDIO:
+        break;
+    }
+
+    return 0;
+}
+
+static AVFilterBufferRef *frame_to_buf(enum AVMediaType type, AVFrame *frame,
+                                       AVFilterLink *outlink)
+{
+    AVFilterBufferRef *buf, *copy;
+
+    buf = avfilter_get_buffer_ref_from_frame(type, frame,
+                                             AV_PERM_WRITE |
+                                             AV_PERM_PRESERVE |
+                                             AV_PERM_REUSE2);
+    if (!buf)
+        return NULL;
+    buf->pts = av_frame_get_best_effort_timestamp(frame);
+    copy = ff_copy_buffer_ref(outlink, buf);
+    if (!copy)
+        return NULL;
+    buf->buf->data[0] = NULL; /* it belongs to the frame */
+    avfilter_unref_buffer(buf);
+    return copy;
+}
+
+static char *describe_bufref_to_str(char *dst, size_t dst_size,
+                                    AVFilterBufferRef *buf,
+                                    AVFilterLink *link)
+{
+    switch (buf->type) {
+    case AVMEDIA_TYPE_VIDEO:
+        snprintf(dst, dst_size,
+                 "video pts:%s time:%s pos:%"PRId64" size:%dx%d aspect:%d/%d",
+                 av_ts2str(buf->pts), av_ts2timestr(buf->pts, &link->time_base),
+                 buf->pos, buf->video->w, buf->video->h,
+                 buf->video->sample_aspect_ratio.num,
+                 buf->video->sample_aspect_ratio.den);
+                 break;
+    case AVMEDIA_TYPE_AUDIO:
+        snprintf(dst, dst_size,
+                 "audio pts:%s time:%s pos:%"PRId64" samples:%d",
+                 av_ts2str(buf->pts), av_ts2timestr(buf->pts, &link->time_base),
+                 buf->pos, buf->audio->nb_samples);
+                 break;
+    default:
+        snprintf(dst, dst_size, "%s BUG", av_get_media_type_string(buf->type));
+        break;
+    }
+    return dst;
+}
+
+#define describe_bufref(buf, link) \
+    describe_bufref_to_str((char[1024]){0}, 1024, buf, link)
+
+static int rewind_file(AVFilterContext *ctx)
+{
+    MovieContext *movie = ctx->priv;
+    int64_t timestamp = movie->seek_point;
+    int ret, i;
+
+    if (movie->format_ctx->start_time != AV_NOPTS_VALUE)
+        timestamp += movie->format_ctx->start_time;
+    ret = av_seek_frame(movie->format_ctx, -1, timestamp, AVSEEK_FLAG_BACKWARD);
+    if (ret < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Unable to loop: %s\n", av_err2str(ret));
+        movie->loop_count = 1; /* do not try again */
+        return ret;
+    }
+
+    for (i = 0; i < ctx->nb_outputs; i++) {
+        avcodec_flush_buffers(movie->st[i].st->codec);
+        movie->st[i].done = 0;
+    }
+    movie->eof = 0;
+    return 0;
+}
+
+/**
+ * Try to push a frame to the requested output.
+ *
+ * @param ctx     filter context
+ * @param out_id  number of output where a frame is wanted;
+ *                if the frame is read from file, used to set the return value;
+ *                if the codec is being flushed, flush the corresponding stream
+ * @return  1 if a frame was pushed on the requested output,
+ *          0 if another attempt is possible,
+ *          <0 AVERROR code
+ */
+static int movie_push_frame(AVFilterContext *ctx, unsigned out_id)
+{
+    MovieContext *movie = ctx->priv;
+    AVPacket *pkt = &movie->pkt;
+    MovieStream *st;
+    int ret, got_frame = 0, pkt_out_id;
+    AVFilterLink *outlink;
+    AVFilterBufferRef *buf;
+
+    if (!pkt->size) {
+        if (movie->eof) {
+            if (movie->st[out_id].done) {
+                if (movie->loop_count != 1) {
+                    ret = rewind_file(ctx);
+                    if (ret < 0)
+                        return ret;
+                    movie->loop_count -= movie->loop_count > 1;
+                    av_log(ctx, AV_LOG_VERBOSE, "Stream finished, looping.\n");
+                    return 0; /* retry */
+                }
+                return AVERROR_EOF;
+            }
+            pkt->stream_index = movie->st[out_id].st->index;
+            /* packet is already ready for flushing */
+        } else {
+            ret = av_read_frame(movie->format_ctx, &movie->pkt0);
+            if (ret < 0) {
+                av_init_packet(&movie->pkt0); /* ready for flushing */
+                *pkt = movie->pkt0;
+                if (ret == AVERROR_EOF) {
+                    movie->eof = 1;
+                    return 0; /* start flushing */
+                }
+                return ret;
+            }
+            *pkt = movie->pkt0;
+        }
+    }
+
+    pkt_out_id = pkt->stream_index > movie->max_stream_index ? -1 :
+                 movie->out_index[pkt->stream_index];
+    if (pkt_out_id < 0) {
+        av_free_packet(&movie->pkt0);
+        pkt->size = 0; /* ready for next run */
+        pkt->data = NULL;
+        return 0;
+    }
+    st = &movie->st[pkt_out_id];
+    outlink = ctx->outputs[pkt_out_id];
+
+    switch (st->st->codec->codec_type) {
+    case AVMEDIA_TYPE_VIDEO:
+        ret = avcodec_decode_video2(st->st->codec, movie->frame, &got_frame, pkt);
+        break;
+    case AVMEDIA_TYPE_AUDIO:
+        ret = avcodec_decode_audio4(st->st->codec, movie->frame, &got_frame, pkt);
+        break;
+    default:
+        ret = AVERROR(ENOSYS);
+        break;
+    }
+    if (ret < 0) {
+        av_log(ctx, AV_LOG_WARNING, "Decode error: %s\n", av_err2str(ret));
+        return 0;
+    }
+    if (!ret)
+        ret = pkt->size;
+
+    pkt->data += ret;
+    pkt->size -= ret;
+    if (pkt->size <= 0) {
+        av_free_packet(&movie->pkt0);
+        pkt->size = 0; /* ready for next run */
+        pkt->data = NULL;
+    }
+    if (!got_frame) {
+        if (!ret)
+            st->done = 1;
+        return 0;
+    }
+
+    buf = frame_to_buf(st->st->codec->codec_type, movie->frame, outlink);
+    if (!buf)
+        return AVERROR(ENOMEM);
+    av_dlog(ctx, "movie_push_frame(): file:'%s' %s\n", movie->file_name,
+            describe_bufref(buf, outlink));
+    switch (st->st->codec->codec_type) {
+    case AVMEDIA_TYPE_VIDEO:
+        if (!movie->frame->sample_aspect_ratio.num)
+            buf->video->sample_aspect_ratio = st->st->sample_aspect_ratio;
+        ff_start_frame(outlink, buf);
+        ff_draw_slice(outlink, 0, outlink->h, 1);
+        ff_end_frame(outlink);
+        break;
+    case AVMEDIA_TYPE_AUDIO:
+        ff_filter_samples(outlink, buf);
+        break;
+    }
+
+    return pkt_out_id == out_id;
+}
+
+static int movie_request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    unsigned out_id = FF_OUTLINK_IDX(outlink);
+    int ret;
+
+    while (1) {
+        ret = movie_push_frame(ctx, out_id);
+        if (ret)
+            return FFMIN(ret, 0);
+    }
+}
+
+#if CONFIG_MOVIE_FILTER
+
+AVFILTER_DEFINE_CLASS(movie);
+
+static av_cold int movie_init(AVFilterContext *ctx, const char *args)
+{
+    return movie_common_init(ctx, args, &movie_class);
+}
+
+AVFilter avfilter_avsrc_movie = {
+    .name          = "movie",
+    .description   = NULL_IF_CONFIG_SMALL("Read from a movie source."),
+    .priv_size     = sizeof(MovieContext),
+    .init          = movie_init,
+    .uninit        = movie_uninit,
+    .query_formats = movie_query_formats,
+
+    .inputs    = NULL,
+    .outputs   = (const AVFilterPad[]) {{ .name = NULL }},
+    .priv_class = &movie_class,
+};
+
+#endif  /* CONFIG_MOVIE_FILTER */
+
+#if CONFIG_AMOVIE_FILTER
+
+#define amovie_options movie_options
+AVFILTER_DEFINE_CLASS(amovie);
+
+static av_cold int amovie_init(AVFilterContext *ctx, const char *args)
+{
+    return movie_common_init(ctx, args, &amovie_class);
+}
+
+AVFilter avfilter_avsrc_amovie = {
+    .name          = "amovie",
+    .description   = NULL_IF_CONFIG_SMALL("Read audio from a movie source."),
+    .priv_size     = sizeof(MovieContext),
+    .init          = amovie_init,
+    .uninit        = movie_uninit,
+    .query_formats = movie_query_formats,
+
+    .inputs    = (const AVFilterPad[]) {{ .name = NULL }},
+    .outputs   = (const AVFilterPad[]) {{ .name = NULL }},
+    .priv_class = &amovie_class,
+};
+
+#endif /* CONFIG_AMOVIE_FILTER */
diff --git a/libavfilter/transform.c b/libavfilter/transform.c
new file mode 100644
index 0000000..b3f85dd
--- /dev/null
+++ b/libavfilter/transform.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2010 Georg Martius <georg.martius@web.de>
+ * Copyright (C) 2010 Daniel G. Taylor <dan@programmer-art.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
+ * transform input video
+ */
+
+#include "libavutil/common.h"
+#include "libavutil/avassert.h"
+
+#include "transform.h"
+
+#define INTERPOLATE_METHOD(name) \
+    static uint8_t name(float x, float y, const uint8_t *src, \
+                        int width, int height, int stride, uint8_t def)
+
+#define PIXEL(img, x, y, w, h, stride, def) \
+    ((x) < 0 || (y) < 0) ? (def) : \
+    (((x) >= (w) || (y) >= (h)) ? (def) : \
+    img[(x) + (y) * (stride)])
+
+/**
+ * Nearest neighbor interpolation
+ */
+INTERPOLATE_METHOD(interpolate_nearest)
+{
+    return PIXEL(src, (int)(x + 0.5), (int)(y + 0.5), width, height, stride, def);
+}
+
+/**
+ * Bilinear interpolation
+ */
+INTERPOLATE_METHOD(interpolate_bilinear)
+{
+    int x_c, x_f, y_c, y_f;
+    int v1, v2, v3, v4;
+
+    if (x < -1 || x > width || y < -1 || y > height) {
+        return def;
+    } else {
+        x_f = (int)x;
+        x_c = x_f + 1;
+
+        y_f = (int)y;
+        y_c = y_f + 1;
+
+        v1 = PIXEL(src, x_c, y_c, width, height, stride, def);
+        v2 = PIXEL(src, x_c, y_f, width, height, stride, def);
+        v3 = PIXEL(src, x_f, y_c, width, height, stride, def);
+        v4 = PIXEL(src, x_f, y_f, width, height, stride, def);
+
+        return (v1*(x - x_f)*(y - y_f) + v2*((x - x_f)*(y_c - y)) +
+                v3*(x_c - x)*(y - y_f) + v4*((x_c - x)*(y_c - y)));
+    }
+}
+
+/**
+ * Biquadratic interpolation
+ */
+INTERPOLATE_METHOD(interpolate_biquadratic)
+{
+    int     x_c, x_f, y_c, y_f;
+    uint8_t v1,  v2,  v3,  v4;
+    float   f1,  f2,  f3,  f4;
+
+    if (x < - 1 || x > width || y < -1 || y > height)
+        return def;
+    else {
+        x_f = (int)x;
+        x_c = x_f + 1;
+        y_f = (int)y;
+        y_c = y_f + 1;
+
+        v1 = PIXEL(src, x_c, y_c, width, height, stride, def);
+        v2 = PIXEL(src, x_c, y_f, width, height, stride, def);
+        v3 = PIXEL(src, x_f, y_c, width, height, stride, def);
+        v4 = PIXEL(src, x_f, y_f, width, height, stride, def);
+
+        f1 = 1 - sqrt((x_c - x) * (y_c - y));
+        f2 = 1 - sqrt((x_c - x) * (y - y_f));
+        f3 = 1 - sqrt((x - x_f) * (y_c - y));
+        f4 = 1 - sqrt((x - x_f) * (y - y_f));
+        return (v1 * f1 + v2 * f2 + v3 * f3 + v4 * f4) / (f1 + f2 + f3 + f4);
+    }
+}
+
+void avfilter_get_matrix(float x_shift, float y_shift, float angle, float zoom, float *matrix) {
+    matrix[0] = zoom * cos(angle);
+    matrix[1] = -sin(angle);
+    matrix[2] = x_shift;
+    matrix[3] = -matrix[1];
+    matrix[4] = matrix[0];
+    matrix[5] = y_shift;
+    matrix[6] = 0;
+    matrix[7] = 0;
+    matrix[8] = 1;
+}
+
+void avfilter_add_matrix(const float *m1, const float *m2, float *result)
+{
+    int i;
+    for (i = 0; i < 9; i++)
+        result[i] = m1[i] + m2[i];
+}
+
+void avfilter_sub_matrix(const float *m1, const float *m2, float *result)
+{
+    int i;
+    for (i = 0; i < 9; i++)
+        result[i] = m1[i] - m2[i];
+}
+
+void avfilter_mul_matrix(const float *m1, float scalar, float *result)
+{
+    int i;
+    for (i = 0; i < 9; i++)
+        result[i] = m1[i] * scalar;
+}
+
+static inline int mirror(int v, int m)
+{
+    while ((unsigned)v > (unsigned)m) {
+        v = -v;
+        if (v < 0)
+            v += 2 * m;
+    }
+    return v;
+}
+
+void avfilter_transform(const uint8_t *src, uint8_t *dst,
+                        int src_stride, int dst_stride,
+                        int width, int height, const float *matrix,
+                        enum InterpolateMethod interpolate,
+                        enum FillMethod fill)
+{
+    int x, y;
+    float x_s, y_s;
+    uint8_t def = 0;
+    uint8_t (*func)(float, float, const uint8_t *, int, int, int, uint8_t) = NULL;
+
+    switch(interpolate) {
+        case INTERPOLATE_NEAREST:
+            func = interpolate_nearest;
+            break;
+        case INTERPOLATE_BILINEAR:
+            func = interpolate_bilinear;
+            break;
+        case INTERPOLATE_BIQUADRATIC:
+            func = interpolate_biquadratic;
+            break;
+    }
+
+    for (y = 0; y < height; y++) {
+        for(x = 0; x < width; x++) {
+            x_s = x * matrix[0] + y * matrix[1] + matrix[2];
+            y_s = x * matrix[3] + y * matrix[4] + matrix[5];
+
+            switch(fill) {
+                case FILL_ORIGINAL:
+                    def = src[y * src_stride + x];
+                    break;
+                case FILL_CLAMP:
+                    y_s = av_clipf(y_s, 0, height - 1);
+                    x_s = av_clipf(x_s, 0, width - 1);
+                    def = src[(int)y_s * src_stride + (int)x_s];
+                    break;
+                case FILL_MIRROR:
+                    x_s = mirror(x_s,  width-1);
+                    y_s = mirror(y_s, height-1);
+
+                    av_assert2(x_s >= 0 && y_s >= 0);
+                    av_assert2(x_s < width && y_s < height);
+                    def = src[(int)y_s * src_stride + (int)x_s];
+            }
+
+            dst[y * dst_stride + x] = func(x_s, y_s, src, width, height, src_stride, def);
+        }
+    }
+}
+
diff --git a/libavfilter/transform.h b/libavfilter/transform.h
new file mode 100644
index 0000000..edd0cf2
--- /dev/null
+++ b/libavfilter/transform.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2010 Georg Martius <georg.martius@web.de>
+ * Copyright (C) 2010 Daniel G. Taylor <dan@programmer-art.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 AVFILTER_TRANSFORM_H
+#define AVFILTER_TRANSFORM_H
+
+#include <stdint.h>
+
+/**
+ * @file
+ * transform input video
+ *
+ * All matrices are defined as a single 9-item block of contiguous memory. For
+ * example, the identity matrix would be:
+ *
+ *     float *matrix = {1, 0, 0,
+ *                      0, 1, 0,
+ *                      0, 0, 1};
+ */
+
+enum InterpolateMethod {
+    INTERPOLATE_NEAREST,        //< Nearest-neighbor (fast)
+    INTERPOLATE_BILINEAR,       //< Bilinear
+    INTERPOLATE_BIQUADRATIC,    //< Biquadratic (best)
+    INTERPOLATE_COUNT,          //< Number of interpolation methods
+};
+
+// Shortcuts for the fastest and best interpolation methods
+#define INTERPOLATE_DEFAULT INTERPOLATE_BILINEAR
+#define INTERPOLATE_FAST    INTERPOLATE_NEAREST
+#define INTERPOLATE_BEST    INTERPOLATE_BIQUADRATIC
+
+enum FillMethod {
+    FILL_BLANK,         //< Fill zeroes at blank locations
+    FILL_ORIGINAL,      //< Original image at blank locations
+    FILL_CLAMP,         //< Extruded edge value at blank locations
+    FILL_MIRROR,        //< Mirrored edge at blank locations
+    FILL_COUNT,         //< Number of edge fill methods
+};
+
+// Shortcuts for fill methods
+#define FILL_DEFAULT FILL_ORIGINAL
+
+/**
+ * Get an affine transformation matrix from a given translation, rotation, and
+ * zoom factor. The matrix will look like:
+ *
+ * [ zoom * cos(angle),           -sin(angle),     x_shift,
+ *          sin(angle),     zoom * cos(angle),     y_shift,
+ *                   0,                     0,           1 ]
+ *
+ * @param x_shift horizontal translation
+ * @param y_shift vertical translation
+ * @param angle   rotation in radians
+ * @param zoom    scale percent (1.0 = 100%)
+ * @param matrix  9-item affine transformation matrix
+ */
+void avfilter_get_matrix(float x_shift, float y_shift, float angle, float zoom, float *matrix);
+
+/**
+ * Add two matrices together. result = m1 + m2.
+ *
+ * @param m1     9-item transformation matrix
+ * @param m2     9-item transformation matrix
+ * @param result 9-item transformation matrix
+ */
+void avfilter_add_matrix(const float *m1, const float *m2, float *result);
+
+/**
+ * Subtract one matrix from another. result = m1 - m2.
+ *
+ * @param m1     9-item transformation matrix
+ * @param m2     9-item transformation matrix
+ * @param result 9-item transformation matrix
+ */
+void avfilter_sub_matrix(const float *m1, const float *m2, float *result);
+
+/**
+ * Multiply a matrix by a scalar value. result = m1 * scalar.
+ *
+ * @param m1     9-item transformation matrix
+ * @param scalar a number
+ * @param result 9-item transformation matrix
+ */
+void avfilter_mul_matrix(const float *m1, float scalar, float *result);
+
+/**
+ * Do an affine transformation with the given interpolation method. This
+ * multiplies each vector [x,y,1] by the matrix and then interpolates to
+ * get the final value.
+ *
+ * @param src         source image
+ * @param dst         destination image
+ * @param src_stride  source image line size in bytes
+ * @param dst_stride  destination image line size in bytes
+ * @param width       image width in pixels
+ * @param height      image height in pixels
+ * @param matrix      9-item affine transformation matrix
+ * @param interpolate pixel interpolation method
+ * @param fill        edge fill method
+ */
+void avfilter_transform(const uint8_t *src, uint8_t *dst,
+                        int src_stride, int dst_stride,
+                        int width, int height, const float *matrix,
+                        enum InterpolateMethod interpolate,
+                        enum FillMethod fill);
+
+#endif /* AVFILTER_TRANSFORM_H */
diff --git a/libavfilter/version.h b/libavfilter/version.h
index 0e72a47..212010b 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -1,20 +1,20 @@
 /*
  * Version macros.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,8 +29,8 @@
 #include "libavutil/avutil.h"
 
 #define LIBAVFILTER_VERSION_MAJOR  3
-#define LIBAVFILTER_VERSION_MINOR  1
-#define LIBAVFILTER_VERSION_MICRO  0
+#define LIBAVFILTER_VERSION_MINOR  19
+#define LIBAVFILTER_VERSION_MICRO 102
 
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
                                                LIBAVFILTER_VERSION_MINOR, \
@@ -40,17 +40,28 @@
                                            LIBAVFILTER_VERSION_MICRO)
 #define LIBAVFILTER_BUILD       LIBAVFILTER_VERSION_INT
 
+#define LIBAVFILTER_IDENT       "Lavfi" AV_STRINGIFY(LIBAVFILTER_VERSION)
+
 /**
  * FF_API_* defines may be placed below to indicate public API that will be
  * dropped at a future version bump. The defines themselves are not part of
  * 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
 #ifndef FF_API_FOO_COUNT
 #define FF_API_FOO_COUNT                    (LIBAVFILTER_VERSION_MAJOR < 4)
 #endif
+#ifndef FF_API_FILL_FRAME
+#define FF_API_FILL_FRAME                   (LIBAVFILTER_VERSION_MAJOR < 4)
+#endif
+#ifndef FF_API_BUFFERSRC_BUFFER
+#define FF_API_BUFFERSRC_BUFFER             (LIBAVFILTER_VERSION_MAJOR < 4)
+#endif
 
 #endif /* AVFILTER_VERSION_H */
diff --git a/libavfilter/vf_alphaextract.c b/libavfilter/vf_alphaextract.c
new file mode 100644
index 0000000..102af9d
--- /dev/null
+++ b/libavfilter/vf_alphaextract.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2012 Steven Robertson
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * simple channel-swapping filter to get at the alpha component
+ */
+
+#include <string.h>
+
+#include "libavutil/pixfmt.h"
+#include "avfilter.h"
+#include "drawutils.h"
+#include "formats.h"
+#include "video.h"
+
+enum { Y, U, V, A };
+
+typedef struct {
+    int is_packed_rgb;
+    uint8_t rgba_map[4];
+} AlphaExtractContext;
+
+static int query_formats(AVFilterContext *ctx)
+{
+    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 };
+    ff_formats_ref(ff_make_format_list(in_fmts), &ctx->inputs[0]->out_formats);
+    ff_formats_ref(ff_make_format_list(out_fmts), &ctx->outputs[0]->in_formats);
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    AlphaExtractContext *extract = inlink->dst->priv;
+    extract->is_packed_rgb =
+        ff_fill_rgba_map(extract->rgba_map, inlink->format) >= 0;
+    return 0;
+}
+
+static int draw_slice(AVFilterLink *inlink, int y0, int h, int slice_dir)
+{
+    AlphaExtractContext *extract = inlink->dst->priv;
+    AVFilterBufferRef *cur_buf = inlink->cur_buf;
+    AVFilterBufferRef *out_buf = inlink->dst->outputs[0]->out_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];
+            pout = out_buf->data[0] + y * out_buf->linesize[0];
+            for (x = 0; x < out_buf->video->w; x++) {
+                *pout = *pin;
+                pout += 1;
+                pin += 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]);
+        int y;
+        for (y = y0; y < (y0 + 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);
+}
+
+AVFilter avfilter_vf_alphaextract = {
+    .name           = "alphaextract",
+    .description    = NULL_IF_CONFIG_SMALL("Extract an alpha channel as a "
+                      "grayscale image component."),
+    .priv_size      = sizeof(AlphaExtractContext),
+    .query_formats  = query_formats,
+
+    .inputs    = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_VIDEO,
+          .config_props     = config_input,
+          .draw_slice       = draw_slice,
+          .min_perms        = AV_PERM_READ },
+        { .name = NULL }
+    },
+    .outputs   = (const AVFilterPad[]) {
+      { .name               = "default",
+        .type               = AVMEDIA_TYPE_VIDEO, },
+      { .name = NULL }
+    },
+};
diff --git a/libavfilter/vf_alphamerge.c b/libavfilter/vf_alphamerge.c
new file mode 100644
index 0000000..51868de
--- /dev/null
+++ b/libavfilter/vf_alphamerge.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2012 Steven Robertson
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * copy an alpha component from another video's luma
+ */
+
+#include <string.h>
+
+#include "libavutil/pixfmt.h"
+#include "avfilter.h"
+#include "bufferqueue.h"
+#include "drawutils.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+enum { Y, U, V, A };
+
+typedef struct {
+    int frame_requested;
+    int is_packed_rgb;
+    uint8_t rgba_map[4];
+    struct FFBufQueue queue_main;
+    struct FFBufQueue queue_alpha;
+} AlphaMergeContext;
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    AlphaMergeContext *merge = ctx->priv;
+    ff_bufqueue_discard_all(&merge->queue_main);
+    ff_bufqueue_discard_all(&merge->queue_alpha);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    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 };
+    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);
+    ff_formats_ref(alpha_formats, &ctx->inputs[1]->out_formats);
+    ff_formats_ref(main_formats, &ctx->outputs[0]->in_formats);
+    return 0;
+}
+
+static int config_input_main(AVFilterLink *inlink)
+{
+    AlphaMergeContext *merge = inlink->dst->priv;
+    merge->is_packed_rgb =
+        ff_fill_rgba_map(merge->rgba_map, inlink->format) >= 0;
+    return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    AVFilterLink *mainlink = ctx->inputs[0];
+    AVFilterLink *alphalink = ctx->inputs[1];
+    if (mainlink->w != alphalink->w || mainlink->h != alphalink->h) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Input frame sizes do not match (%dx%d vs %dx%d).\n",
+               mainlink->w, mainlink->h,
+               alphalink->w, alphalink->h);
+        return AVERROR(EINVAL);
+    }
+
+    outlink->w = mainlink->w;
+    outlink->h = mainlink->h;
+    outlink->time_base = mainlink->time_base;
+    outlink->sample_aspect_ratio = mainlink->sample_aspect_ratio;
+    outlink->frame_rate = mainlink->frame_rate;
+    return 0;
+}
+
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) {return 0;}
+static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) {return 0;}
+
+static void draw_frame(AVFilterContext *ctx,
+                       AVFilterBufferRef *main_buf,
+                       AVFilterBufferRef *alpha_buf)
+{
+    AlphaMergeContext *merge = ctx->priv;
+    int h = main_buf->video->h;
+
+    if (merge->is_packed_rgb) {
+        int x, y;
+        uint8_t *pin, *pout;
+        for (y = 0; y < h; y++) {
+            pin = alpha_buf->data[0] + y * alpha_buf->linesize[0];
+            pout = main_buf->data[0] + y * main_buf->linesize[0] + merge->rgba_map[A];
+            for (x = 0; x < main_buf->video->w; x++) {
+                *pout = *pin;
+                pin += 1;
+                pout += 4;
+            }
+        }
+    } else {
+        int y;
+        const int main_linesize = main_buf->linesize[A];
+        const int alpha_linesize = alpha_buf->linesize[Y];
+        for (y = 0; y < h && y < alpha_buf->video->h; y++) {
+            memcpy(main_buf->data[A] + y * main_linesize,
+                   alpha_buf->data[Y] + y * alpha_linesize,
+                   FFMIN(main_linesize, alpha_linesize));
+        }
+    }
+    ff_draw_slice(ctx->outputs[0], 0, h, 1);
+}
+
+static int end_frame(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AlphaMergeContext *merge = ctx->priv;
+
+    int is_alpha = (inlink == ctx->inputs[1]);
+    struct FFBufQueue *queue =
+        (is_alpha ? &merge->queue_alpha : &merge->queue_main);
+    ff_bufqueue_add(ctx, queue, inlink->cur_buf);
+    inlink->cur_buf = NULL;
+
+    while (1) {
+        AVFilterBufferRef *main_buf, *alpha_buf;
+
+        if (!ff_bufqueue_peek(&merge->queue_main, 0) ||
+            !ff_bufqueue_peek(&merge->queue_alpha, 0)) break;
+
+        main_buf = ff_bufqueue_get(&merge->queue_main);
+        alpha_buf = ff_bufqueue_get(&merge->queue_alpha);
+
+        ctx->outputs[0]->out_buf = main_buf;
+        ff_start_frame(ctx->outputs[0], avfilter_ref_buffer(main_buf, ~0));
+        merge->frame_requested = 0;
+        draw_frame(ctx, main_buf, alpha_buf);
+        ff_end_frame(ctx->outputs[0]);
+        avfilter_unref_buffer(alpha_buf);
+    }
+    return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    AlphaMergeContext *merge = ctx->priv;
+    int in, ret;
+
+    merge->frame_requested = 1;
+    while (merge->frame_requested) {
+        in = ff_bufqueue_peek(&merge->queue_main, 0) ? 1 : 0;
+        ret = ff_request_frame(ctx->inputs[in]);
+        if (ret < 0)
+            return ret;
+    }
+    return 0;
+}
+
+AVFilter avfilter_vf_alphamerge = {
+    .name           = "alphamerge",
+    .description    = NULL_IF_CONFIG_SMALL("Copy the luma value of the second "
+                      "input into the alpha channel of the first input."),
+    .uninit         = uninit,
+    .priv_size      = sizeof(AlphaMergeContext),
+    .query_formats  = query_formats,
+
+    .inputs    = (const AVFilterPad[]) {
+        { .name             = "main",
+          .type             = AVMEDIA_TYPE_VIDEO,
+          .config_props     = config_input_main,
+          .get_video_buffer = ff_null_get_video_buffer,
+          .start_frame      = start_frame,
+          .draw_slice       = draw_slice,
+          .end_frame        = end_frame,
+          .min_perms        = AV_PERM_READ | AV_PERM_WRITE | AV_PERM_PRESERVE },
+        { .name             = "alpha",
+          .type             = AVMEDIA_TYPE_VIDEO,
+          .start_frame      = start_frame,
+          .draw_slice       = draw_slice,
+          .end_frame        = end_frame,
+          .min_perms        = AV_PERM_READ | AV_PERM_PRESERVE },
+        { .name = NULL }
+    },
+    .outputs   = (const AVFilterPad[]) {
+      { .name               = "default",
+        .type               = AVMEDIA_TYPE_VIDEO,
+        .config_props       = config_output,
+        .request_frame      = request_frame },
+      { .name = NULL }
+    },
+};
diff --git a/libavfilter/vf_aspect.c b/libavfilter/vf_aspect.c
index 9f0c0c0..4e5ba77 100644
--- a/libavfilter/vf_aspect.c
+++ b/libavfilter/vf_aspect.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Bobby Bingham
 
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,43 +25,30 @@
 
 #include "libavutil/common.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/parseutils.h"
 #include "avfilter.h"
 #include "internal.h"
 #include "video.h"
 
 typedef struct {
-    AVRational aspect;
+    AVRational ratio;
 } AspectContext;
 
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     AspectContext *aspect = ctx->priv;
-    double  ratio;
-    int64_t gcd;
-    char c = 0;
+    aspect->ratio = (AVRational) {0, 1};
 
     if (args) {
-        if (sscanf(args, "%d:%d%c", &aspect->aspect.num, &aspect->aspect.den, &c) != 2)
-            if (sscanf(args, "%lf%c", &ratio, &c) == 1)
-                aspect->aspect = av_d2q(ratio, 100);
-
-        if (c || aspect->aspect.num <= 0 || aspect->aspect.den <= 0) {
+        if (av_parse_ratio(&aspect->ratio, args, 100, 0, ctx) < 0 ||
+            aspect->ratio.num < 0 || aspect->ratio.den <= 0) {
             av_log(ctx, AV_LOG_ERROR,
                    "Invalid string '%s' for aspect ratio.\n", args);
             return AVERROR(EINVAL);
         }
-
-        gcd = av_gcd(FFABS(aspect->aspect.num), FFABS(aspect->aspect.den));
-        if (gcd) {
-            aspect->aspect.num /= gcd;
-            aspect->aspect.den /= gcd;
-        }
     }
 
-    if (aspect->aspect.den == 0)
-        aspect->aspect = (AVRational) {0, 1};
-
-    av_log(ctx, AV_LOG_VERBOSE, "a:%d/%d\n", aspect->aspect.num, aspect->aspect.den);
+    av_log(ctx, AV_LOG_VERBOSE, "a:%d/%d\n", aspect->ratio.num, aspect->ratio.den);
     return 0;
 }
 
@@ -69,26 +56,25 @@
 {
     AspectContext *aspect = link->dst->priv;
 
-    picref->video->pixel_aspect = aspect->aspect;
+    picref->video->sample_aspect_ratio = aspect->ratio;
     link->cur_buf = NULL;
     return ff_start_frame(link->dst->outputs[0], picref);
 }
 
 #if CONFIG_SETDAR_FILTER
-/* for setdar filter, convert from frame aspect ratio to pixel aspect ratio */
 static int setdar_config_props(AVFilterLink *inlink)
 {
     AspectContext *aspect = inlink->dst->priv;
-    AVRational dar = aspect->aspect;
+    AVRational dar = aspect->ratio;
 
-    av_reduce(&aspect->aspect.num, &aspect->aspect.den,
-               aspect->aspect.num * inlink->h,
-               aspect->aspect.den * inlink->w, 100);
+    av_reduce(&aspect->ratio.num, &aspect->ratio.den,
+               aspect->ratio.num * inlink->h,
+               aspect->ratio.den * inlink->w, 100);
 
     av_log(inlink->dst, AV_LOG_VERBOSE, "w:%d h:%d -> dar:%d/%d sar:%d/%d\n",
-           inlink->w, inlink->h, dar.num, dar.den, aspect->aspect.num, aspect->aspect.den);
+           inlink->w, inlink->h, dar.num, dar.den, aspect->ratio.num, aspect->ratio.den);
 
-    inlink->sample_aspect_ratio = aspect->aspect;
+    inlink->sample_aspect_ratio = aspect->ratio;
 
     return 0;
 }
@@ -128,12 +114,11 @@
 #endif /* CONFIG_SETDAR_FILTER */
 
 #if CONFIG_SETSAR_FILTER
-/* for setdar filter, convert from frame aspect ratio to pixel aspect ratio */
 static int setsar_config_props(AVFilterLink *inlink)
 {
     AspectContext *aspect = inlink->dst->priv;
 
-    inlink->sample_aspect_ratio = aspect->aspect;
+    inlink->sample_aspect_ratio = aspect->ratio;
 
     return 0;
 }
diff --git a/libavfilter/vf_ass.c b/libavfilter/vf_ass.c
new file mode 100644
index 0000000..6b20631
--- /dev/null
+++ b/libavfilter/vf_ass.c
@@ -0,0 +1,227 @@
+/*
+ * 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[] = {
+    {"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;
+    int ret;
+
+    ass->class = &ass_class;
+    av_opt_set_defaults(ass);
+
+    if (args)
+        ass->filename = av_get_token(&args, ":");
+    if (!ass->filename || !*ass->filename) {
+        av_log(ctx, AV_LOG_ERROR, "No filename provided!\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (*args++ == ':' && (ret = av_set_options_string(ass, args, "=", ":")) < 0)
+        return ret;
+
+    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_freep(&ass->filename);
+    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;
+}
+
+static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { 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 end_frame(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    AVFilterLink *outlink = ctx->outputs[0];
+    AssContext *ass = ctx->priv;
+    AVFilterBufferRef *picref = inlink->cur_buf;
+    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);
+
+    ff_draw_slice(outlink, 0, picref->video->h, 1);
+    return ff_end_frame(outlink);
+}
+
+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 = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_VIDEO,
+          .get_video_buffer = ff_null_get_video_buffer,
+          .start_frame      = ff_null_start_frame,
+          .draw_slice       = null_draw_slice,
+          .end_frame        = end_frame,
+          .config_props     = config_input,
+          .min_perms        = AV_PERM_WRITE | AV_PERM_READ },
+        { .name = NULL}
+    },
+    .outputs = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_VIDEO, },
+        { .name = NULL}
+    },
+    .priv_class = &ass_class,
+};
diff --git a/libavfilter/vf_bbox.c b/libavfilter/vf_bbox.c
new file mode 100644
index 0000000..07ac550
--- /dev/null
+++ b/libavfilter/vf_bbox.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2012 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
+ * bounding box detection filter
+ */
+
+#include "libavutil/pixdesc.h"
+#include "libavutil/timestamp.h"
+#include "avfilter.h"
+#include "bbox.h"
+#include "internal.h"
+
+typedef struct {
+    unsigned int frame;
+    int vsub, hsub;
+} BBoxContext;
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    BBoxContext *bbox = ctx->priv;
+    bbox->frame = 0;
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_YUV420P,
+        AV_PIX_FMT_YUV444P,
+        AV_PIX_FMT_YUV440P,
+        AV_PIX_FMT_YUV422P,
+        AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_NONE,
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static int end_frame(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    BBoxContext *bbox = ctx->priv;
+    AVFilterBufferRef *picref = inlink->cur_buf;
+    FFBoundingBox box;
+    int has_bbox, w, h;
+
+    has_bbox =
+        ff_calculate_bounding_box(&box,
+                                  picref->data[0], picref->linesize[0],
+                                  inlink->w, inlink->h, 16);
+    w = box.x2 - box.x1 + 1;
+    h = box.y2 - box.y1 + 1;
+
+    av_log(ctx, AV_LOG_INFO,
+           "n:%d pts:%s pts_time:%s", bbox->frame,
+           av_ts2str(picref->pts), av_ts2timestr(picref->pts, &inlink->time_base));
+
+    if (has_bbox) {
+        av_log(ctx, AV_LOG_INFO,
+               " x1:%d x2:%d y1:%d y2:%d w:%d h:%d"
+               " crop=%d:%d:%d:%d drawbox=%d:%d:%d:%d",
+               box.x1, box.x2, box.y1, box.y2, w, h,
+               w, h, box.x1, box.y1,    /* crop params */
+               box.x1, box.y1, w, h);   /* drawbox params */
+    }
+    av_log(ctx, AV_LOG_INFO, "\n");
+
+    bbox->frame++;
+    return ff_end_frame(inlink->dst->outputs[0]);
+}
+
+AVFilter avfilter_vf_bbox = {
+    .name          = "bbox",
+    .description   = NULL_IF_CONFIG_SMALL("Compute bounding box for each frame."),
+    .priv_size     = sizeof(BBoxContext),
+    .query_formats = query_formats,
+    .init          = init,
+
+    .inputs = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_VIDEO,
+          .get_video_buffer = ff_null_get_video_buffer,
+          .start_frame      = ff_null_start_frame,
+          .end_frame        = end_frame,
+          .min_perms        = AV_PERM_READ, },
+        { .name = NULL }
+    },
+
+    .outputs = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_VIDEO },
+        { .name = NULL }
+    },
+};
diff --git a/libavfilter/vf_blackdetect.c b/libavfilter/vf_blackdetect.c
new file mode 100644
index 0000000..17f5acb
--- /dev/null
+++ b/libavfilter/vf_blackdetect.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2012 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
+ * Video black detector, loosely based on blackframe with extended
+ * syntax and features
+ */
+
+#include <float.h>
+#include "libavutil/opt.h"
+#include "libavutil/timestamp.h"
+#include "avfilter.h"
+#include "internal.h"
+
+typedef struct {
+    const AVClass *class;
+    double  black_min_duration_time; ///< minimum duration of detected black, in seconds
+    int64_t black_min_duration;      ///< minimum duration of detected black, expressed in timebase units
+    int64_t black_start;             ///< pts start time of the first black picture
+    int64_t black_end;               ///< pts end time of the last black picture
+    int64_t last_picref_pts;         ///< pts of the last input picture
+    int black_started;
+
+    double       picture_black_ratio_th;
+    double       pixel_black_th;
+    unsigned int pixel_black_th_i;
+
+    unsigned int frame_count;       ///< frame number
+    unsigned int nb_black_pixels;   ///< number of black pixels counted so far
+} BlackDetectContext;
+
+#define OFFSET(x) offsetof(BlackDetectContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption blackdetect_options[] = {
+    { "d",                  "set minimum detected black duration in seconds", OFFSET(black_min_duration_time), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, DBL_MAX, FLAGS },
+    { "black_min_duration", "set minimum detected black duration in seconds", OFFSET(black_min_duration_time), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, DBL_MAX, FLAGS },
+    { "picture_black_ratio_th", "set the picture black ratio threshold", OFFSET(picture_black_ratio_th), AV_OPT_TYPE_DOUBLE, {.dbl=.98}, 0, 1, FLAGS },
+    { "pic_th",                 "set the picture black ratio threshold", OFFSET(picture_black_ratio_th), AV_OPT_TYPE_DOUBLE, {.dbl=.98}, 0, 1, FLAGS },
+    { "pixel_black_th", "set the pixel black threshold", OFFSET(pixel_black_th), AV_OPT_TYPE_DOUBLE, {.dbl=.10}, 0, 1, FLAGS },
+    { "pix_th",         "set the pixel black threshold", OFFSET(pixel_black_th), AV_OPT_TYPE_DOUBLE, {.dbl=.10}, 0, 1, FLAGS },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(blackdetect);
+
+#define YUVJ_FORMATS \
+    AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P
+
+static enum AVPixelFormat yuvj_formats[] = {
+    YUVJ_FORMATS, AV_PIX_FMT_NONE
+};
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NV12,
+        AV_PIX_FMT_NV21, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P,
+        YUVJ_FORMATS,
+        AV_PIX_FMT_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    int ret;
+    BlackDetectContext *blackdetect = ctx->priv;
+
+    blackdetect->class = &blackdetect_class;
+    av_opt_set_defaults(blackdetect);
+
+    if ((ret = av_set_options_string(blackdetect, args, "=", ":")) < 0)
+        return ret;
+
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    BlackDetectContext *blackdetect = ctx->priv;
+
+    blackdetect->black_min_duration =
+        blackdetect->black_min_duration_time / av_q2d(inlink->time_base);
+
+    blackdetect->pixel_black_th_i = ff_fmt_is_in(inlink->format, yuvj_formats) ?
+        // luminance_minimum_value + pixel_black_th * luminance_range_size
+             blackdetect->pixel_black_th *  255 :
+        16 + blackdetect->pixel_black_th * (235 - 16);
+
+    av_log(blackdetect, AV_LOG_VERBOSE,
+           "black_min_duration:%s pixel_black_th:%f pixel_black_th_i:%d picture_black_ratio_th:%f\n",
+           av_ts2timestr(blackdetect->black_min_duration, &inlink->time_base),
+           blackdetect->pixel_black_th, blackdetect->pixel_black_th_i,
+           blackdetect->picture_black_ratio_th);
+    return 0;
+}
+
+static void check_black_end(AVFilterContext *ctx)
+{
+    BlackDetectContext *blackdetect = ctx->priv;
+    AVFilterLink *inlink = ctx->inputs[0];
+
+    if ((blackdetect->black_end - blackdetect->black_start) >= blackdetect->black_min_duration) {
+        av_log(blackdetect, AV_LOG_INFO,
+               "black_start:%s black_end:%s black_duration:%s\n",
+               av_ts2timestr(blackdetect->black_start, &inlink->time_base),
+               av_ts2timestr(blackdetect->black_end,   &inlink->time_base),
+               av_ts2timestr(blackdetect->black_end - blackdetect->black_start, &inlink->time_base));
+    }
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    BlackDetectContext *blackdetect = ctx->priv;
+    AVFilterLink *inlink = ctx->inputs[0];
+    int ret = ff_request_frame(inlink);
+
+    if (ret == AVERROR_EOF && blackdetect->black_started) {
+        // FIXME: black_end should be set to last_picref_pts + last_picref_duration
+        blackdetect->black_end = blackdetect->last_picref_pts;
+        check_black_end(ctx);
+    }
+    return ret;
+}
+
+static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
+{
+    AVFilterContext *ctx = inlink->dst;
+    BlackDetectContext *blackdetect = ctx->priv;
+    AVFilterBufferRef *picref = inlink->cur_buf;
+    int x, i;
+    const uint8_t *p = picref->data[0] + y * picref->linesize[0];
+
+    for (i = 0; i < h; i++) {
+        for (x = 0; x < inlink->w; x++)
+            blackdetect->nb_black_pixels += p[x] <= blackdetect->pixel_black_th_i;
+        p += picref->linesize[0];
+    }
+
+    return ff_draw_slice(ctx->outputs[0], y, h, slice_dir);
+}
+
+static int end_frame(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    BlackDetectContext *blackdetect = ctx->priv;
+    AVFilterBufferRef *picref = inlink->cur_buf;
+    double picture_black_ratio = 0;
+
+    picture_black_ratio = (double)blackdetect->nb_black_pixels / (inlink->w * inlink->h);
+
+    av_log(ctx, AV_LOG_DEBUG,
+           "frame:%u picture_black_ratio:%f pos:%"PRId64" pts:%s t:%s type:%c\n",
+           blackdetect->frame_count, picture_black_ratio,
+           picref->pos, av_ts2str(picref->pts), av_ts2timestr(picref->pts, &inlink->time_base),
+           av_get_picture_type_char(picref->video->pict_type));
+
+    if (picture_black_ratio >= blackdetect->picture_black_ratio_th) {
+        if (!blackdetect->black_started) {
+            /* black starts here */
+            blackdetect->black_started = 1;
+            blackdetect->black_start = picref->pts;
+        }
+    } else if (blackdetect->black_started) {
+        /* black ends here */
+        blackdetect->black_started = 0;
+        blackdetect->black_end = picref->pts;
+        check_black_end(ctx);
+    }
+
+    blackdetect->last_picref_pts = picref->pts;
+    blackdetect->frame_count++;
+    blackdetect->nb_black_pixels = 0;
+    return ff_end_frame(inlink->dst->outputs[0]);
+}
+
+AVFilter avfilter_vf_blackdetect = {
+    .name          = "blackdetect",
+    .description   = NULL_IF_CONFIG_SMALL("Detect video intervals that are (almost) black."),
+    .priv_size     = sizeof(BlackDetectContext),
+    .init          = init,
+    .query_formats = query_formats,
+
+    .inputs = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_VIDEO,
+          .config_props     = config_input,
+          .draw_slice       = draw_slice,
+          .get_video_buffer = ff_null_get_video_buffer,
+          .start_frame      = ff_null_start_frame,
+          .end_frame        = end_frame, },
+        { .name = NULL }
+    },
+
+    .outputs = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_VIDEO,
+          .request_frame    = request_frame, },
+        { .name = NULL }
+    },
+    .priv_class = &blackdetect_class,
+};
diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c
index 9a27b69..fbc5978 100644
--- a/libavfilter/vf_blackframe.c
+++ b/libavfilter/vf_blackframe.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2006 Julian Hall
  * Copyright (c) 2002-2003 Brian J. Murrell
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or modify
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License along
- * with Libav; if not, write to the Free Software Foundation, Inc.,
+ * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
@@ -32,6 +32,7 @@
 
 #include "libavutil/internal.h"
 #include "avfilter.h"
+#include "internal.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
@@ -41,6 +42,7 @@
     unsigned int bthresh; ///< black threshold
     unsigned int frame;   ///< frame number
     unsigned int nblack;  ///< number of black pixels counted so far
+    unsigned int last_keyframe; ///< frame number of the last received key-frame
 } BlackFrameContext;
 
 static int query_formats(AVFilterContext *ctx)
@@ -63,6 +65,7 @@
     blackframe->bthresh = 32;
     blackframe->nblack = 0;
     blackframe->frame = 0;
+    blackframe->last_keyframe = 0;
 
     if (args)
         sscanf(args, "%u:%u", &blackframe->bamount, &blackframe->bthresh);
@@ -102,11 +105,16 @@
     AVFilterBufferRef *picref = inlink->cur_buf;
     int pblack = 0;
 
+    if (picref->video->key_frame)
+        blackframe->last_keyframe = blackframe->frame;
+
     pblack = blackframe->nblack * 100 / (inlink->w * inlink->h);
     if (pblack >= blackframe->bamount)
-        av_log(ctx, AV_LOG_INFO, "frame:%u pblack:%u pos:%"PRId64" pts:%"PRId64" t:%f\n",
+        av_log(ctx, AV_LOG_INFO, "frame:%u pblack:%u pos:%"PRId64" pts:%"PRId64" t:%f "
+               "type:%c last_keyframe:%d\n",
                blackframe->frame, pblack, picref->pos, picref->pts,
-               picref->pts == AV_NOPTS_VALUE ? -1 : picref->pts * av_q2d(inlink->time_base));
+               picref->pts == AV_NOPTS_VALUE ? -1 : picref->pts * av_q2d(inlink->time_base),
+               av_get_picture_type_char(picref->video->pict_type), blackframe->last_keyframe);
 
     blackframe->frame++;
     blackframe->nblack = 0;
diff --git a/libavfilter/vf_boxblur.c b/libavfilter/vf_boxblur.c
index 755d98e..0989d16 100644
--- a/libavfilter/vf_boxblur.c
+++ b/libavfilter/vf_boxblur.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2011 Stefano Sabatini
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or modify
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License along
- * with Libav; if not, write to the Free Software Foundation, Inc.,
+ * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
@@ -148,24 +148,19 @@
     char *expr;
     int ret;
 
-    av_freep(&boxblur->temp[0]);
-    av_freep(&boxblur->temp[1]);
-    if (!(boxblur->temp[0] = av_malloc(FFMAX(w, h))))
-       return AVERROR(ENOMEM);
-    if (!(boxblur->temp[1] = av_malloc(FFMAX(w, h)))) {
-        av_freep(&boxblur->temp[0]);
+    if (!(boxblur->temp[0] = av_malloc(FFMAX(w, h))) ||
+        !(boxblur->temp[1] = av_malloc(FFMAX(w, h))))
         return AVERROR(ENOMEM);
-    }
 
     boxblur->hsub = desc->log2_chroma_w;
     boxblur->vsub = desc->log2_chroma_h;
 
-    var_values[VAR_W]       = inlink->w;
-    var_values[VAR_H]       = inlink->h;
+    var_values[VAR_W]  = inlink->w;
+    var_values[VAR_H]  = inlink->h;
     var_values[VAR_CW] = cw = w>>boxblur->hsub;
     var_values[VAR_CH] = ch = h>>boxblur->vsub;
-    var_values[VAR_HSUB]    = 1<<boxblur->hsub;
-    var_values[VAR_VSUB]    = 1<<boxblur->vsub;
+    var_values[VAR_HSUB] = 1<<boxblur->hsub;
+    var_values[VAR_VSUB] = 1<<boxblur->vsub;
 
 #define EVAL_RADIUS_EXPR(comp)                                          \
     expr = boxblur->comp##_radius_expr;                                 \
@@ -181,7 +176,7 @@
     EVAL_RADIUS_EXPR(chroma);
     EVAL_RADIUS_EXPR(alpha);
 
-    av_log(ctx, AV_LOG_DEBUG,
+    av_log(ctx, AV_LOG_VERBOSE,
            "luma_radius:%d luma_power:%d "
            "chroma_radius:%d chroma_power:%d "
            "alpha_radius:%d alpha_power:%d "
@@ -231,9 +226,9 @@
      * and subtracting 1 input pixel.
      * The following code adopts this faster variant.
      */
+    int x, sum = 0;
     const int length = radius*2 + 1;
     const int inv = ((1<<16) + length/2)/length;
-    int x, sum = 0;
 
     for (x = 0; x < radius; x++)
         sum += src[x*src_step]<<1;
@@ -307,7 +302,9 @@
                    h, radius, power, temp);
 }
 
-static int draw_slice(AVFilterLink *inlink, int y0, int h0, int slice_dir)
+static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { return 0; }
+
+static int end_frame(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
     BoxBlurContext *boxblur = ctx->priv;
@@ -315,9 +312,9 @@
     AVFilterBufferRef *inpicref  = inlink ->cur_buf;
     AVFilterBufferRef *outpicref = outlink->out_buf;
     int plane;
-    int cw = inlink->w >> boxblur->hsub, ch = h0 >> boxblur->vsub;
+    int cw = inlink->w >> boxblur->hsub, ch = inlink->h >> boxblur->vsub;
     int w[4] = { inlink->w, cw, cw, inlink->w };
-    int h[4] = { h0, ch, ch, h0 };
+    int h[4] = { inlink->h, ch, ch, inlink->h };
 
     for (plane = 0; inpicref->data[plane] && plane < 4; plane++)
         hblur(outpicref->data[plane], outpicref->linesize[plane],
@@ -331,7 +328,8 @@
               w[plane], h[plane], boxblur->radius[plane], boxblur->power[plane],
               boxblur->temp);
 
-    return ff_draw_slice(outlink, y0, h0, slice_dir);
+    ff_draw_slice(outlink, 0, inlink->h, 1);
+    return ff_end_frame(outlink);
 }
 
 static const AVFilterPad avfilter_vf_boxblur_inputs[] = {
@@ -339,7 +337,8 @@
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
         .config_props = config_input,
-        .draw_slice   = draw_slice,
+        .draw_slice   = null_draw_slice,
+        .end_frame    = end_frame,
         .min_perms    = AV_PERM_READ
     },
     { NULL }
diff --git a/libavfilter/vf_colormatrix.c b/libavfilter/vf_colormatrix.c
new file mode 100644
index 0000000..f331204
--- /dev/null
+++ b/libavfilter/vf_colormatrix.c
@@ -0,0 +1,393 @@
+/*
+ * ColorMatrix v2.2 for Avisynth 2.5.x
+ *
+ * Copyright (C) 2006-2007 Kevin Stone
+ *
+ * ColorMatrix 1.x is Copyright (C) Wilbert Dijkhof
+ *
+ * This program 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * OUT 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/**
+ * @file
+ * ColorMatrix 2.0 is based on the original ColorMatrix filter by Wilbert
+ * Dijkhof.  It adds the ability to convert between any of: Rec.709, FCC,
+ * Rec.601, and SMPTE 240M. It also makes pre and post clipping optional,
+ * adds an option to use scaled or non-scaled coefficients, and more...
+ */
+
+#include <float.h>
+#include "avfilter.h"
+#include "formats.h"
+#include "video.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/avstring.h"
+
+#define NS(n) n < 0 ? (int)(n*65536.0-0.5+DBL_EPSILON) : (int)(n*65536.0+0.5)
+#define CB(n) av_clip_uint8(n)
+
+static const double yuv_coeff[4][3][3] = {
+    { { +0.7152, +0.0722, +0.2126 }, // Rec.709 (0)
+      { -0.3850, +0.5000, -0.1150 },
+      { -0.4540, -0.0460, +0.5000 } },
+    { { +0.5900, +0.1100, +0.3000 }, // FCC (1)
+      { -0.3310, +0.5000, -0.1690 },
+      { -0.4210, -0.0790, +0.5000 } },
+    { { +0.5870, +0.1140, +0.2990 }, // Rec.601 (ITU-R BT.470-2/SMPTE 170M) (2)
+      { -0.3313, +0.5000, -0.1687 },
+      { -0.4187, -0.0813, +0.5000 } },
+    { { +0.7010, +0.0870, +0.2120 }, // SMPTE 240M (3)
+      { -0.3840, +0.5000, -0.1160 },
+      { -0.4450, -0.0550, +0.5000 } },
+};
+
+typedef struct {
+    int yuv_convert[16][3][3];
+    int interlaced;
+    int source, dest, mode;
+    char src[256];
+    char dst[256];
+    int hsub, vsub;
+    AVFilterBufferRef *outpicref;
+} ColorMatrixContext;
+
+#define ma m[0][0]
+#define mb m[0][1]
+#define mc m[0][2]
+#define md m[1][0]
+#define me m[1][1]
+#define mf m[1][2]
+#define mg m[2][0]
+#define mh m[2][1]
+#define mi m[2][2]
+
+#define ima im[0][0]
+#define imb im[0][1]
+#define imc im[0][2]
+#define imd im[1][0]
+#define ime im[1][1]
+#define imf im[1][2]
+#define img im[2][0]
+#define imh im[2][1]
+#define imi im[2][2]
+
+static void inverse3x3(double im[3][3], const double m[3][3])
+{
+    double det = ma * (me * mi - mf * mh) - mb * (md * mi - mf * mg) + mc * (md * mh - me * mg);
+    det = 1.0 / det;
+    ima = det * (me * mi - mf * mh);
+    imb = det * (mc * mh - mb * mi);
+    imc = det * (mb * mf - mc * me);
+    imd = det * (mf * mg - md * mi);
+    ime = det * (ma * mi - mc * mg);
+    imf = det * (mc * md - ma * mf);
+    img = det * (md * mh - me * mg);
+    imh = det * (mb * mg - ma * mh);
+    imi = det * (ma * me - mb * md);
+}
+
+static void solve_coefficients(double cm[3][3], double rgb[3][3], const double yuv[3][3])
+{
+    int i, j;
+    for (i = 0; i < 3; i++)
+        for (j = 0; j < 3; j++)
+            cm[i][j] = yuv[i][0] * rgb[0][j] + yuv[i][1] * rgb[1][j] + yuv[i][2] * rgb[2][j];
+}
+
+static void calc_coefficients(AVFilterContext *ctx)
+{
+    ColorMatrixContext *color = ctx->priv;
+    double rgb_coeffd[4][3][3];
+    double yuv_convertd[16][3][3];
+    int v = 0;
+    int i, j, k;
+
+    for (i = 0; i < 4; i++)
+        inverse3x3(rgb_coeffd[i], yuv_coeff[i]);
+    for (i = 0; i < 4; i++) {
+        for (j = 0; j < 4; j++) {
+            solve_coefficients(yuv_convertd[v], rgb_coeffd[i], yuv_coeff[j]);
+            for (k = 0; k < 3; k++) {
+                color->yuv_convert[v][k][0] = NS(yuv_convertd[v][k][0]);
+                color->yuv_convert[v][k][1] = NS(yuv_convertd[v][k][1]);
+                color->yuv_convert[v][k][2] = NS(yuv_convertd[v][k][2]);
+            }
+            if (color->yuv_convert[v][0][0] != 65536 || color->yuv_convert[v][1][0] != 0 ||
+                color->yuv_convert[v][2][0] != 0) {
+                av_log(ctx, AV_LOG_ERROR, "error calculating conversion coefficients\n");
+            }
+            v++;
+        }
+    }
+}
+
+static const char *color_modes[] = {"bt709", "FCC", "bt601", "smpte240m"};
+
+static int get_color_mode_index(const char *name)
+{
+    int i;
+
+    for (i = 0; i < FF_ARRAY_ELEMS(color_modes); i++)
+        if (!av_strcasecmp(color_modes[i], name))
+            return i;
+    return -1;
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    ColorMatrixContext *color = ctx->priv;
+
+    if (!args)
+        goto usage;
+    if (sscanf(args, "%255[^:]:%255[^:]", color->src, color->dst) != 2) {
+    usage:
+        av_log(ctx, AV_LOG_ERROR, "usage: <src>:<dst>\n");
+        av_log(ctx, AV_LOG_ERROR, "possible options: bt709,bt601,smpte240m,fcc\n");
+        return -1;
+    }
+
+    color->source = get_color_mode_index(color->src);
+    if (color->source < 0) {
+        av_log(ctx, AV_LOG_ERROR, "unknown color space %s\n", color->src);
+        return AVERROR(EINVAL);
+    }
+
+    color->dest = get_color_mode_index(color->dst);
+    if (color->dest < 0) {
+        av_log(ctx, AV_LOG_ERROR, "unknown color space %s\n", color->dst);
+        return AVERROR(EINVAL);
+    }
+
+    if (color->source == color->dest) {
+        av_log(ctx, AV_LOG_ERROR, "source and destination color space are identical\n");
+        return AVERROR(EINVAL);
+    }
+
+    color->mode = color->source * 4 + color->dest;
+
+    calc_coefficients(ctx);
+
+    return 0;
+}
+
+static void process_frame_uyvy422(ColorMatrixContext *color,
+                                  AVFilterBufferRef *dst, AVFilterBufferRef *src)
+{
+    const unsigned char *srcp = src->data[0];
+    const int src_pitch = src->linesize[0];
+    const int height = src->video->h;
+    const int width = src->video->w*2;
+    unsigned char *dstp = dst->data[0];
+    const int dst_pitch = dst->linesize[0];
+    const int c2 = color->yuv_convert[color->mode][0][1];
+    const int c3 = color->yuv_convert[color->mode][0][2];
+    const int c4 = color->yuv_convert[color->mode][1][1];
+    const int c5 = color->yuv_convert[color->mode][1][2];
+    const int c6 = color->yuv_convert[color->mode][2][1];
+    const int c7 = color->yuv_convert[color->mode][2][2];
+    int x, y;
+
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x += 4) {
+            const int u = srcp[x + 0] - 128;
+            const int v = srcp[x + 2] - 128;
+            const int uvval = c2 * u + c3 * v + 1081344;
+            dstp[x + 0] = CB((c4 * u + c5 * v + 8421376) >> 16);
+            dstp[x + 1] = CB((65536 * (srcp[x + 1] - 16) + uvval) >> 16);
+            dstp[x + 2] = CB((c6 * u + c7 * v + 8421376) >> 16);
+            dstp[x + 3] = CB((65536 * (srcp[x + 3] - 16) + uvval) >> 16);
+        }
+        srcp += src_pitch;
+        dstp += dst_pitch;
+    }
+}
+
+static void process_frame_yuv422p(ColorMatrixContext *color,
+                                  AVFilterBufferRef *dst, AVFilterBufferRef *src)
+{
+    const unsigned char *srcpU = src->data[1];
+    const unsigned char *srcpV = src->data[2];
+    const unsigned char *srcpY = src->data[0];
+    const int src_pitchY  = src->linesize[0];
+    const int src_pitchUV = src->linesize[1];
+    const int height = src->video->h;
+    const int width = src->video->w;
+    unsigned char *dstpU = dst->data[1];
+    unsigned char *dstpV = dst->data[2];
+    unsigned char *dstpY = dst->data[0];
+    const int dst_pitchY  = dst->linesize[0];
+    const int dst_pitchUV = dst->linesize[1];
+    const int c2 = color->yuv_convert[color->mode][0][1];
+    const int c3 = color->yuv_convert[color->mode][0][2];
+    const int c4 = color->yuv_convert[color->mode][1][1];
+    const int c5 = color->yuv_convert[color->mode][1][2];
+    const int c6 = color->yuv_convert[color->mode][2][1];
+    const int c7 = color->yuv_convert[color->mode][2][2];
+    int x, y;
+
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x += 2) {
+            const int u = srcpU[x >> 1] - 128;
+            const int v = srcpV[x >> 1] - 128;
+            const int uvval = c2 * u + c3 * v + 1081344;
+            dstpY[x + 0] = CB((65536 * (srcpY[x + 0] - 16) + uvval) >> 16);
+            dstpY[x + 1] = CB((65536 * (srcpY[x + 1] - 16) + uvval) >> 16);
+            dstpU[x >> 1] = CB((c4 * u + c5 * v + 8421376) >> 16);
+            dstpV[x >> 1] = CB((c6 * u + c7 * v + 8421376) >> 16);
+        }
+        srcpY += src_pitchY;
+        dstpY += dst_pitchY;
+        srcpU += src_pitchUV;
+        srcpV += src_pitchUV;
+        dstpU += dst_pitchUV;
+        dstpV += dst_pitchUV;
+    }
+}
+
+static void process_frame_yuv420p(ColorMatrixContext *color,
+                                  AVFilterBufferRef *dst, AVFilterBufferRef *src)
+{
+    const unsigned char *srcpU = src->data[1];
+    const unsigned char *srcpV = src->data[2];
+    const unsigned char *srcpY = src->data[0];
+    const unsigned char *srcpN = src->data[0] + src->linesize[0];
+    const int src_pitchY  = src->linesize[0];
+    const int src_pitchUV = src->linesize[1];
+    const int height = src->video->h;
+    const int width = src->video->w;
+    unsigned char *dstpU = dst->data[1];
+    unsigned char *dstpV = dst->data[2];
+    unsigned char *dstpY = dst->data[0];
+    unsigned char *dstpN = dst->data[0] + dst->linesize[0];
+    const int dst_pitchY  = dst->linesize[0];
+    const int dst_pitchUV = dst->linesize[1];
+    const int c2 = color->yuv_convert[color->mode][0][1];
+    const int c3 = color->yuv_convert[color->mode][0][2];
+    const int c4 = color->yuv_convert[color->mode][1][1];
+    const int c5 = color->yuv_convert[color->mode][1][2];
+    const int c6 = color->yuv_convert[color->mode][2][1];
+    const int c7 = color->yuv_convert[color->mode][2][2];
+    int x, y;
+
+    for (y = 0; y < height; y += 2) {
+        for (x = 0; x < width; x += 2) {
+            const int u = srcpU[x >> 1] - 128;
+            const int v = srcpV[x >> 1] - 128;
+            const int uvval = c2 * u + c3 * v + 1081344;
+            dstpY[x + 0] = CB((65536 * (srcpY[x + 0] - 16) + uvval) >> 16);
+            dstpY[x + 1] = CB((65536 * (srcpY[x + 1] - 16) + uvval) >> 16);
+            dstpN[x + 0] = CB((65536 * (srcpN[x + 0] - 16) + uvval) >> 16);
+            dstpN[x + 1] = CB((65536 * (srcpN[x + 1] - 16) + uvval) >> 16);
+            dstpU[x >> 1] = CB((c4 * u + c5 * v + 8421376) >> 16);
+            dstpV[x >> 1] = CB((c6 * u + c7 * v + 8421376) >> 16);
+        }
+        srcpY += src_pitchY << 1;
+        dstpY += dst_pitchY << 1;
+        srcpN += src_pitchY << 1;
+        dstpN += dst_pitchY << 1;
+        srcpU += src_pitchUV;
+        srcpV += src_pitchUV;
+        dstpU += dst_pitchUV;
+        dstpV += dst_pitchUV;
+    }
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    ColorMatrixContext *color = ctx->priv;
+    const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[inlink->format];
+
+    color->hsub = pix_desc->log2_chroma_w;
+    color->vsub = pix_desc->log2_chroma_h;
+
+    av_log(ctx, AV_LOG_VERBOSE, "%s -> %s\n", color->src, color->dst);
+
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_YUV422P,
+        AV_PIX_FMT_YUV420P,
+        AV_PIX_FMT_UYVY422,
+        AV_PIX_FMT_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+
+    return 0;
+}
+
+static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int w, int h)
+{
+    AVFilterBufferRef *picref =
+        ff_get_video_buffer(inlink->dst->outputs[0], perms, w, h);
+    return picref;
+}
+
+static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
+{
+    AVFilterContext *ctx = link->dst;
+    ColorMatrixContext *color = ctx->priv;
+    AVFilterBufferRef *outpicref = avfilter_ref_buffer(picref, ~0);
+
+    color->outpicref = outpicref;
+
+    return ff_start_frame(link->dst->outputs[0], outpicref);
+}
+
+static int end_frame(AVFilterLink *link)
+{
+    AVFilterContext *ctx = link->dst;
+    ColorMatrixContext *color = ctx->priv;
+    AVFilterBufferRef *out = color->outpicref;
+
+    if (link->cur_buf->format == AV_PIX_FMT_YUV422P)
+        process_frame_yuv422p(color, out, link->cur_buf);
+    else if (link->cur_buf->format == AV_PIX_FMT_YUV420P)
+        process_frame_yuv420p(color, out, link->cur_buf);
+    else
+        process_frame_uyvy422(color, out, link->cur_buf);
+
+    ff_draw_slice(ctx->outputs[0], 0, link->dst->outputs[0]->h, 1);
+    return ff_end_frame(ctx->outputs[0]);
+}
+
+static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { return 0; }
+
+AVFilter avfilter_vf_colormatrix = {
+    .name          = "colormatrix",
+    .description   = NULL_IF_CONFIG_SMALL("Color matrix conversion"),
+
+    .priv_size     = sizeof(ColorMatrixContext),
+    .init          = init,
+    .query_formats = query_formats,
+
+    .inputs    = (AVFilterPad[]) {{ .name             = "default",
+                                    .type             = AVMEDIA_TYPE_VIDEO,
+                                    .config_props     = config_input,
+                                    .min_perms        = AV_PERM_READ | AV_PERM_WRITE,
+                                    .start_frame      = start_frame,
+                                    .get_video_buffer = get_video_buffer,
+                                    .draw_slice       = null_draw_slice,
+                                    .end_frame        = end_frame, },
+                                  { .name = NULL }},
+
+    .outputs   = (AVFilterPad[]) {{ .name             = "default",
+                                    .type             = AVMEDIA_TYPE_VIDEO, },
+                                  { .name = NULL }},
+};
diff --git a/libavfilter/vf_copy.c b/libavfilter/vf_copy.c
index a20da93..43fdc9a 100644
--- a/libavfilter/vf_copy.c
+++ b/libavfilter/vf_copy.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c
index f79f574..17b24c4 100644
--- a/libavfilter/vf_crop.c
+++ b/libavfilter/vf_crop.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -39,13 +39,15 @@
 #include "libavutil/mathematics.h"
 
 static const char *const var_names[] = {
-    "E",
-    "PHI",
-    "PI",
     "in_w", "iw",   ///< width  of the input video
     "in_h", "ih",   ///< height of the input video
     "out_w", "ow",  ///< width  of the cropped video
     "out_h", "oh",  ///< height of the cropped video
+    "a",
+    "sar",
+    "dar",
+    "hsub",
+    "vsub",
     "x",
     "y",
     "n",            ///< number of frame
@@ -55,13 +57,15 @@
 };
 
 enum var_name {
-    VAR_E,
-    VAR_PHI,
-    VAR_PI,
     VAR_IN_W,  VAR_IW,
     VAR_IN_H,  VAR_IH,
     VAR_OUT_W, VAR_OW,
     VAR_OUT_H, VAR_OH,
+    VAR_A,
+    VAR_SAR,
+    VAR_DAR,
+    VAR_HSUB,
+    VAR_VSUB,
     VAR_X,
     VAR_Y,
     VAR_N,
@@ -76,6 +80,9 @@
     int  w;             ///< width of the cropped area
     int  h;             ///< height of the cropped area
 
+    AVRational out_sar; ///< output sample aspect ratio
+    int keep_aspect;    ///< keep display aspect ratio when cropping
+
     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];
@@ -126,7 +133,7 @@
     av_strlcpy(crop->y_expr, "(in_h-out_h)/2", sizeof(crop->y_expr));
 
     if (args)
-        sscanf(args, "%255[^:]:%255[^:]:%255[^:]:%255[^:]", crop->ow_expr, crop->oh_expr, crop->x_expr, crop->y_expr);
+        sscanf(args, "%255[^:]:%255[^:]:%255[^:]:%255[^:]:%d", crop->ow_expr, crop->oh_expr, crop->x_expr, crop->y_expr, &crop->keep_aspect);
 
     return 0;
 }
@@ -163,11 +170,13 @@
     const char *expr;
     double res;
 
-    crop->var_values[VAR_E]     = M_E;
-    crop->var_values[VAR_PHI]   = M_PHI;
-    crop->var_values[VAR_PI]    = M_PI;
     crop->var_values[VAR_IN_W]  = crop->var_values[VAR_IW] = ctx->inputs[0]->w;
     crop->var_values[VAR_IN_H]  = crop->var_values[VAR_IH] = ctx->inputs[0]->h;
+    crop->var_values[VAR_A]     = (float) link->w / link->h;
+    crop->var_values[VAR_SAR]   = link->sample_aspect_ratio.num ? av_q2d(link->sample_aspect_ratio) : 1;
+    crop->var_values[VAR_DAR]   = crop->var_values[VAR_A] * crop->var_values[VAR_SAR];
+    crop->var_values[VAR_HSUB]  = 1<<pix_desc->log2_chroma_w;
+    crop->var_values[VAR_VSUB]  = 1<<pix_desc->log2_chroma_h;
     crop->var_values[VAR_X]     = NAN;
     crop->var_values[VAR_Y]     = NAN;
     crop->var_values[VAR_OUT_W] = crop->var_values[VAR_OW] = NAN;
@@ -210,8 +219,17 @@
                              NULL, NULL, NULL, NULL, 0, ctx)) < 0)
         return AVERROR(EINVAL);
 
-    av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d\n",
-           link->w, link->h, crop->w, crop->h);
+    if (crop->keep_aspect) {
+        AVRational dar = av_mul_q(link->sample_aspect_ratio,
+                                  (AVRational){ link->w, link->h });
+        av_reduce(&crop->out_sar.num, &crop->out_sar.den,
+                  dar.num * crop->h, dar.den * crop->w, INT_MAX);
+    } else
+        crop->out_sar = link->sample_aspect_ratio;
+
+    av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d sar:%d/%d -> w:%d h:%d sar:%d/%d\n",
+           link->w, link->h, link->sample_aspect_ratio.num, link->sample_aspect_ratio.den,
+           crop->w, crop->h, crop->out_sar.num, crop->out_sar.den);
 
     if (crop->w <= 0 || crop->h <= 0 ||
         crop->w > link->w || crop->h > link->h) {
@@ -239,6 +257,7 @@
 
     link->w = crop->w;
     link->h = crop->h;
+    link->sample_aspect_ratio = crop->out_sar;
 
     return 0;
 }
diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c
index 63a72cb..e40609d 100644
--- a/libavfilter/vf_cropdetect.c
+++ b/libavfilter/vf_cropdetect.c
@@ -1,19 +1,19 @@
 /*
  * Copyright (c) 2002 A'rpi
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or modify
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License along
- * with Libav; if not, write to the Free Software Foundation, Inc.,
+ * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
diff --git a/libavfilter/vf_decimate.c b/libavfilter/vf_decimate.c
new file mode 100644
index 0000000..b4abfa3
--- /dev/null
+++ b/libavfilter/vf_decimate.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2003 Rich Felker
+ * Copyright (c) 2012 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 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 decimate filter, ported from libmpcodecs/vf_decimate.c by
+ * Rich Felker.
+ */
+
+#include "libavutil/pixdesc.h"
+#include "libavutil/timestamp.h"
+#include "libavcodec/dsputil.h"
+#include "avfilter.h"
+#include "internal.h"
+#include "formats.h"
+#include "video.h"
+
+typedef struct {
+    int lo, hi;                    ///< lower and higher threshold number of differences
+                                   ///< values for 8x8 blocks
+
+    float frac;                    ///< threshold of changed pixels over the total fraction
+
+    int max_drop_count;            ///< if positive: maximum number of sequential frames to drop
+                                   ///< if negative: minimum number of frames between two drops
+
+    int drop_count;                ///< if positive: number of frames sequentially dropped
+                                   ///< if negative: number of sequential frames which were not dropped
+
+    int hsub, vsub;                ///< chroma subsampling values
+    AVFilterBufferRef *ref;        ///< reference picture
+    DSPContext dspctx;             ///< context providing optimized diff routines
+    AVCodecContext *avctx;         ///< codec context required for the DSPContext
+} DecimateContext;
+
+/**
+ * Return 1 if the two planes are different, 0 otherwise.
+ */
+static int diff_planes(AVFilterContext *ctx,
+                       uint8_t *cur, uint8_t *ref, int linesize,
+                       int w, int h)
+{
+    DecimateContext *decimate = ctx->priv;
+    DSPContext *dspctx = &decimate->dspctx;
+
+    int x, y;
+    int d, c = 0;
+    int t = (w/16)*(h/16)*decimate->frac;
+    DCTELEM block[8*8];
+
+    /* compute difference for blocks of 8x8 bytes */
+    for (y = 0; y < h-7; y += 4) {
+        for (x = 8; x < w-7; x += 4) {
+            dspctx->diff_pixels(block,
+                                cur+x+y*linesize,
+                                ref+x+y*linesize, linesize);
+            d = dspctx->sum_abs_dctelem(block);
+            if (d > decimate->hi)
+                return 1;
+            if (d > decimate->lo) {
+                c++;
+                if (c > t)
+                    return 1;
+            }
+        }
+    }
+    return 0;
+}
+
+/**
+ * Tell if the frame should be decimated, for example if it is no much
+ * different with respect to the reference frame ref.
+ */
+static int decimate_frame(AVFilterContext *ctx,
+                          AVFilterBufferRef *cur, AVFilterBufferRef *ref)
+{
+    DecimateContext *decimate = ctx->priv;
+    int plane;
+
+    if (decimate->max_drop_count > 0 &&
+        decimate->drop_count >= decimate->max_drop_count)
+        return 0;
+    if (decimate->max_drop_count < 0 &&
+        (decimate->drop_count-1) > decimate->max_drop_count)
+        return 0;
+
+    for (plane = 0; ref->data[plane] && ref->linesize[plane]; plane++) {
+        int vsub = plane == 1 || plane == 2 ? decimate->vsub : 0;
+        int hsub = plane == 1 || plane == 2 ? decimate->hsub : 0;
+        if (diff_planes(ctx,
+                        cur->data[plane], ref->data[plane], ref->linesize[plane],
+                        ref->video->w>>hsub, ref->video->h>>vsub))
+            return 0;
+    }
+
+    return 1;
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    DecimateContext *decimate = ctx->priv;
+
+    /* set default values */
+    decimate->drop_count = decimate->max_drop_count = 0;
+    decimate->lo = 64*5;
+    decimate->hi = 64*12;
+    decimate->frac = 0.33;
+
+    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);
+        }
+    }
+
+    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);
+
+    decimate->avctx = avcodec_alloc_context3(NULL);
+    if (!decimate->avctx)
+        return AVERROR(ENOMEM);
+    dsputil_init(&decimate->dspctx, decimate->avctx);
+
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    DecimateContext *decimate = ctx->priv;
+    avfilter_unref_bufferp(&decimate->ref);
+    avcodec_close(decimate->avctx);
+    av_freep(&decimate->avctx);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_YUV444P,      AV_PIX_FMT_YUV422P,
+        AV_PIX_FMT_YUV420P,      AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_YUV410P,      AV_PIX_FMT_YUV440P,
+        AV_PIX_FMT_YUVJ444P,     AV_PIX_FMT_YUVJ422P,
+        AV_PIX_FMT_YUVJ420P,     AV_PIX_FMT_YUVJ440P,
+        AV_PIX_FMT_YUVA420P,
+        AV_PIX_FMT_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    DecimateContext *decimate = ctx->priv;
+    const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[inlink->format];
+    decimate->hsub = pix_desc->log2_chroma_w;
+    decimate->vsub = pix_desc->log2_chroma_h;
+
+    return 0;
+}
+
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref) { return 0; }
+
+static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { return 0; }
+
+static int end_frame(AVFilterLink *inlink)
+{
+    DecimateContext *decimate = inlink->dst->priv;
+    AVFilterBufferRef *cur = inlink->cur_buf;
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    int ret;
+
+    if (decimate->ref && decimate_frame(inlink->dst, cur, decimate->ref)) {
+        decimate->drop_count = FFMAX(1, decimate->drop_count+1);
+    } 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_start_frame(outlink,
+                                  avfilter_ref_buffer(cur, ~AV_PERM_WRITE)) < 0) ||
+            (ret = ff_draw_slice(outlink, 0, inlink->h, 1)) < 0 ||
+            (ret = ff_end_frame(outlink)) < 0)
+            return ret;
+    }
+
+    av_log(inlink->dst, AV_LOG_DEBUG,
+           "%s pts:%s pts_time:%s drop_count:%d\n",
+           decimate->drop_count > 0 ? "drop" : "keep",
+           av_ts2str(cur->pts), av_ts2timestr(cur->pts, &inlink->time_base),
+           decimate->drop_count);
+
+    return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    DecimateContext *decimate = outlink->src->priv;
+    AVFilterLink *inlink = outlink->src->inputs[0];
+    int ret;
+
+    do {
+        ret = ff_request_frame(inlink);
+    } while (decimate->drop_count > 0 && ret >= 0);
+
+    return ret;
+}
+
+AVFilter avfilter_vf_decimate = {
+    .name        = "decimate",
+    .description = NULL_IF_CONFIG_SMALL("Remove near-duplicate frames."),
+    .init        = init,
+    .uninit      = uninit,
+
+    .priv_size = sizeof(DecimateContext),
+    .query_formats = query_formats,
+
+    .inputs = (const AVFilterPad[]) {
+        {
+            .name             = "default",
+            .type             = AVMEDIA_TYPE_VIDEO,
+            .get_video_buffer = ff_null_get_video_buffer,
+            .config_props     = config_input,
+            .start_frame      = start_frame,
+            .draw_slice       = draw_slice,
+            .end_frame        = end_frame,
+            .min_perms        = AV_PERM_READ | AV_PERM_PRESERVE,
+        },
+        { .name = NULL }
+    },
+    .outputs = (const AVFilterPad[]) {
+        {
+            .name          = "default",
+            .type          = AVMEDIA_TYPE_VIDEO,
+            .request_frame = request_frame,
+        },
+        { .name = NULL }
+    },
+};
diff --git a/libavfilter/vf_delogo.c b/libavfilter/vf_delogo.c
index 361e0b7..1d5ab66 100644
--- a/libavfilter/vf_delogo.c
+++ b/libavfilter/vf_delogo.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2002 Jindrich Makovicka <makovick@gmail.com>
  * Copyright (c) 2011 Stefano Sabatini
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or modify
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License along
- * with Libav; if not, write to the Free Software Foundation, Inc.,
+ * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
@@ -90,18 +90,22 @@
         for (x = logo_x1+1,
              xdst = dst+logo_x1+1,
              xsrc = src+logo_x1+1; x < logo_x2-1; x++, xdst++, xsrc++) {
-            interp = (topleft[src_linesize*(y-logo_y  -yclipt)]   +
-                      topleft[src_linesize*(y-logo_y-1-yclipt)]   +
-                      topleft[src_linesize*(y-logo_y+1-yclipt)])  * (logo_w-(x-logo_x))/logo_w
-                   + (topright[src_linesize*(y-logo_y-yclipt)]    +
-                      topright[src_linesize*(y-logo_y-1-yclipt)]  +
-                      topright[src_linesize*(y-logo_y+1-yclipt)]) * (x-logo_x)/logo_w
-                   + (topleft[x-logo_x-xclipl]                    +
-                      topleft[x-logo_x-1-xclipl]                  +
-                      topleft[x-logo_x+1-xclipl])                 * (logo_h-(y-logo_y))/logo_h
-                   + (botleft[x-logo_x-xclipl]                    +
-                      botleft[x-logo_x-1-xclipl]                  +
-                      botleft[x-logo_x+1-xclipl])                 * (y-logo_y)/logo_h;
+            interp =
+                (topleft[src_linesize*(y-logo_y  -yclipt)]   +
+                 topleft[src_linesize*(y-logo_y-1-yclipt)]   +
+                 topleft[src_linesize*(y-logo_y+1-yclipt)])  * (logo_w-(x-logo_x))/logo_w
+                +
+                (topright[src_linesize*(y-logo_y-yclipt)]    +
+                 topright[src_linesize*(y-logo_y-1-yclipt)]  +
+                 topright[src_linesize*(y-logo_y+1-yclipt)]) * (x-logo_x)/logo_w
+                +
+                (topleft[x-logo_x-xclipl]    +
+                 topleft[x-logo_x-1-xclipl]  +
+                 topleft[x-logo_x+1-xclipl]) * (logo_h-(y-logo_y))/logo_h
+                +
+                (botleft[x-logo_x-xclipl]    +
+                 botleft[x-logo_x-1-xclipl]  +
+                 botleft[x-logo_x+1-xclipl]) * (y-logo_y)/logo_h;
             interp /= 6;
 
             if (y >= logo_y+band && y < logo_y+logo_h-band &&
@@ -136,28 +140,20 @@
 }  DelogoContext;
 
 #define OFFSET(x) offsetof(DelogoContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 
 static const AVOption delogo_options[]= {
-    {"x",    "set logo x position",       OFFSET(x),    AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX },
-    {"y",    "set logo y position",       OFFSET(y),    AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX },
-    {"w",    "set logo width",            OFFSET(w),    AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX },
-    {"h",    "set logo height",           OFFSET(h),    AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX },
-    {"band", "set delogo area band size", OFFSET(band), AV_OPT_TYPE_INT, {.i64 =  4}, -1, INT_MAX },
-    {"t",    "set delogo area band size", OFFSET(band), AV_OPT_TYPE_INT, {.i64 =  4}, -1, INT_MAX },
-    {"show", "show delogo area",          OFFSET(show), AV_OPT_TYPE_INT, {.i64 =  0},  0, 1       },
+    {"x",    "set logo x position",       OFFSET(x),    AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS},
+    {"y",    "set logo y position",       OFFSET(y),    AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS},
+    {"w",    "set logo width",            OFFSET(w),    AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS},
+    {"h",    "set logo height",           OFFSET(h),    AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, FLAGS},
+    {"band", "set delogo area band size", OFFSET(band), AV_OPT_TYPE_INT, {.i64 =  4}, -1, INT_MAX, FLAGS},
+    {"t",    "set delogo area band size", OFFSET(band), AV_OPT_TYPE_INT, {.i64 =  4}, -1, INT_MAX, FLAGS},
+    {"show", "show delogo area",          OFFSET(show), AV_OPT_TYPE_INT, {.i64 =  0},  0,       1, FLAGS},
     {NULL},
 };
 
-static const char *delogo_get_name(void *ctx)
-{
-    return "delogo";
-}
-
-static const AVClass delogo_class = {
-    .class_name = "DelogoContext",
-    .item_name  = delogo_get_name,
-    .option     = delogo_options,
-};
+AVFILTER_DEFINE_CLASS(delogo);
 
 static int query_formats(AVFilterContext *ctx)
 {
@@ -186,10 +182,8 @@
     if (ret == 5) {
         if (delogo->band < 0)
             delogo->show = 1;
-    } else if ((ret = (av_set_options_string(delogo, args, "=", ":"))) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
+    } else if ((ret = (av_set_options_string(delogo, args, "=", ":"))) < 0)
         return ret;
-    }
 
 #define CHECK_UNSET_OPT(opt)                                            \
     if (delogo->opt == -1) {                                            \
@@ -204,7 +198,7 @@
     if (delogo->show)
         delogo->band = 4;
 
-    av_log(ctx, AV_LOG_DEBUG, "x:%d y:%d, w:%d h:%d band:%d show:%d\n",
+    av_log(ctx, AV_LOG_VERBOSE, "x:%d y:%d, w:%d h:%d band:%d show:%d\n",
            delogo->x, delogo->y, delogo->w, delogo->h, delogo->band, delogo->show);
 
     delogo->w += delogo->band*2;
@@ -261,7 +255,6 @@
         .draw_slice       = null_draw_slice,
         .end_frame        = end_frame,
         .min_perms        = AV_PERM_WRITE | AV_PERM_READ,
-        .rej_perms        = AV_PERM_PRESERVE
     },
     { NULL }
 };
diff --git a/libavfilter/vf_deshake.c b/libavfilter/vf_deshake.c
new file mode 100644
index 0000000..e86d5bc
--- /dev/null
+++ b/libavfilter/vf_deshake.c
@@ -0,0 +1,562 @@
+/*
+ * Copyright (C) 2010 Georg Martius <georg.martius@web.de>
+ * Copyright (C) 2010 Daniel G. Taylor <dan@programmer-art.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
+ * fast deshake / depan video filter
+ *
+ * SAD block-matching motion compensation to fix small changes in
+ * horizontal and/or vertical shift. This filter helps remove camera shake
+ * from hand-holding a camera, bumping a tripod, moving on a vehicle, etc.
+ *
+ * Algorithm:
+ *   - For each frame with one previous reference frame
+ *       - For each block in the frame
+ *           - If contrast > threshold then find likely motion vector
+ *       - For all found motion vectors
+ *           - Find most common, store as global motion vector
+ *       - Find most likely rotation angle
+ *       - Transform image along global motion
+ *
+ * TODO:
+ *   - Fill frame edges based on previous/next reference frames
+ *   - Fill frame edges by stretching image near the edges?
+ *       - Can this be done quickly and look decent?
+ *
+ * Dark Shikari links to http://wiki.videolan.org/SoC_x264_2010#GPU_Motion_Estimation_2
+ * for an algorithm similar to what could be used here to get the gmv
+ * It requires only a couple diamond searches + fast downscaling
+ *
+ * Special thanks to Jason Kotenko for his help with the algorithm and my
+ * inability to see simple errors in C code.
+ */
+
+#include "avfilter.h"
+#include "formats.h"
+#include "video.h"
+#include "libavutil/common.h"
+#include "libavutil/mem.h"
+#include "libavutil/pixdesc.h"
+#include "libavcodec/dsputil.h"
+
+#include "transform.h"
+
+#define CHROMA_WIDTH(link)  -((-link->w) >> av_pix_fmt_descriptors[link->format].log2_chroma_w)
+#define CHROMA_HEIGHT(link) -((-link->h) >> av_pix_fmt_descriptors[link->format].log2_chroma_h)
+
+enum SearchMethod {
+    EXHAUSTIVE,        ///< Search all possible positions
+    SMART_EXHAUSTIVE,  ///< Search most possible positions (faster)
+    SEARCH_COUNT
+};
+
+typedef struct {
+    int x;             ///< Horizontal shift
+    int y;             ///< Vertical shift
+} IntMotionVector;
+
+typedef struct {
+    double x;             ///< Horizontal shift
+    double y;             ///< Vertical shift
+} MotionVector;
+
+typedef struct {
+    MotionVector vector;  ///< Motion vector
+    double angle;         ///< Angle of rotation
+    double zoom;          ///< Zoom percentage
+} Transform;
+
+typedef struct {
+    AVClass av_class;
+    AVFilterBufferRef *ref;    ///< Previous frame
+    int rx;                    ///< Maximum horizontal shift
+    int ry;                    ///< Maximum vertical shift
+    enum FillMethod edge;      ///< Edge fill method
+    int blocksize;             ///< Size of blocks to compare
+    int contrast;              ///< Contrast threshold
+    enum SearchMethod search;  ///< Motion search method
+    AVCodecContext *avctx;
+    DSPContext c;              ///< Context providing optimized SAD methods
+    Transform last;            ///< Transform from last frame
+    int refcount;              ///< Number of reference frames (defines averaging window)
+    FILE *fp;
+    Transform avg;
+    int cw;                    ///< Crop motion search to this box
+    int ch;
+    int cx;
+    int cy;
+} DeshakeContext;
+
+static int cmp(const double *a, const double *b)
+{
+    return *a < *b ? -1 : ( *a > *b ? 1 : 0 );
+}
+
+/**
+ * Cleaned mean (cuts off 20% of values to remove outliers and then averages)
+ */
+static double clean_mean(double *values, int count)
+{
+    double mean = 0;
+    int cut = count / 5;
+    int x;
+
+    qsort(values, count, sizeof(double), (void*)cmp);
+
+    for (x = cut; x < count - cut; x++) {
+        mean += values[x];
+    }
+
+    return mean / (count - cut * 2);
+}
+
+/**
+ * Find the most likely shift in motion between two frames for a given
+ * macroblock. Test each block against several shifts given by the rx
+ * and ry attributes. Searches using a simple matrix of those shifts and
+ * chooses the most likely shift by the smallest difference in blocks.
+ */
+static void find_block_motion(DeshakeContext *deshake, uint8_t *src1,
+                              uint8_t *src2, int cx, int cy, int stride,
+                              IntMotionVector *mv)
+{
+    int x, y;
+    int diff;
+    int smallest = INT_MAX;
+    int tmp, tmp2;
+
+    #define CMP(i, j) deshake->c.sad[0](deshake, src1 + cy * stride + cx, \
+                                        src2 + (j) * stride + (i), stride, \
+                                        deshake->blocksize)
+
+    if (deshake->search == EXHAUSTIVE) {
+        // Compare every possible position - this is sloooow!
+        for (y = -deshake->ry; y <= deshake->ry; y++) {
+            for (x = -deshake->rx; x <= deshake->rx; x++) {
+                diff = CMP(cx - x, cy - y);
+                if (diff < smallest) {
+                    smallest = diff;
+                    mv->x = x;
+                    mv->y = y;
+                }
+            }
+        }
+    } else if (deshake->search == SMART_EXHAUSTIVE) {
+        // Compare every other possible position and find the best match
+        for (y = -deshake->ry + 1; y < deshake->ry - 2; y += 2) {
+            for (x = -deshake->rx + 1; x < deshake->rx - 2; x += 2) {
+                diff = CMP(cx - x, cy - y);
+                if (diff < smallest) {
+                    smallest = diff;
+                    mv->x = x;
+                    mv->y = y;
+                }
+            }
+        }
+
+        // Hone in on the specific best match around the match we found above
+        tmp = mv->x;
+        tmp2 = mv->y;
+
+        for (y = tmp2 - 1; y <= tmp2 + 1; y++) {
+            for (x = tmp - 1; x <= tmp + 1; x++) {
+                if (x == tmp && y == tmp2)
+                    continue;
+
+                diff = CMP(cx - x, cy - y);
+                if (diff < smallest) {
+                    smallest = diff;
+                    mv->x = x;
+                    mv->y = y;
+                }
+            }
+        }
+    }
+
+    if (smallest > 512) {
+        mv->x = -1;
+        mv->y = -1;
+    }
+    emms_c();
+    //av_log(NULL, AV_LOG_ERROR, "%d\n", smallest);
+    //av_log(NULL, AV_LOG_ERROR, "Final: (%d, %d) = %d x %d\n", cx, cy, mv->x, mv->y);
+}
+
+/**
+ * Find the contrast of a given block. When searching for global motion we
+ * really only care about the high contrast blocks, so using this method we
+ * can actually skip blocks we don't care much about.
+ */
+static int block_contrast(uint8_t *src, int x, int y, int stride, int blocksize)
+{
+    int highest = 0;
+    int lowest = 0;
+    int i, j, pos;
+
+    for (i = 0; i <= blocksize * 2; i++) {
+        // We use a width of 16 here to match the libavcodec sad functions
+        for (j = 0; i <= 15; i++) {
+            pos = (y - i) * stride + (x - j);
+            if (src[pos] < lowest)
+                lowest = src[pos];
+            else if (src[pos] > highest) {
+                highest = src[pos];
+            }
+        }
+    }
+
+    return highest - lowest;
+}
+
+/**
+ * Find the rotation for a given block.
+ */
+static double block_angle(int x, int y, int cx, int cy, IntMotionVector *shift)
+{
+    double a1, a2, diff;
+
+    a1 = atan2(y - cy, x - cx);
+    a2 = atan2(y - cy + shift->y, x - cx + shift->x);
+
+    diff = a2 - a1;
+
+    return (diff > M_PI)  ? diff - 2 * M_PI :
+           (diff < -M_PI) ? diff + 2 * M_PI :
+           diff;
+}
+
+/**
+ * Find the estimated global motion for a scene given the most likely shift
+ * for each block in the frame. The global motion is estimated to be the
+ * same as the motion from most blocks in the frame, so if most blocks
+ * move one pixel to the right and two pixels down, this would yield a
+ * motion vector (1, -2).
+ */
+static void find_motion(DeshakeContext *deshake, uint8_t *src1, uint8_t *src2,
+                        int width, int height, int stride, Transform *t)
+{
+    int x, y;
+    IntMotionVector mv = {0, 0};
+    int counts[128][128];
+    int count_max_value = 0;
+    int contrast;
+
+    int pos;
+    double *angles = av_malloc(sizeof(*angles) * width * height / (16 * deshake->blocksize));
+    int center_x = 0, center_y = 0;
+    double p_x, p_y;
+
+    // Reset counts to zero
+    for (x = 0; x < deshake->rx * 2 + 1; x++) {
+        for (y = 0; y < deshake->ry * 2 + 1; y++) {
+            counts[x][y] = 0;
+        }
+    }
+
+    pos = 0;
+    // Find motion for every block and store the motion vector in the counts
+    for (y = deshake->ry; y < height - deshake->ry - (deshake->blocksize * 2); y += deshake->blocksize * 2) {
+        // We use a width of 16 here to match the libavcodec sad functions
+        for (x = deshake->rx; x < width - deshake->rx - 16; x += 16) {
+            // If the contrast is too low, just skip this block as it probably
+            // won't be very useful to us.
+            contrast = block_contrast(src2, x, y, stride, deshake->blocksize);
+            if (contrast > deshake->contrast) {
+                //av_log(NULL, AV_LOG_ERROR, "%d\n", contrast);
+                find_block_motion(deshake, src1, src2, x, y, stride, &mv);
+                if (mv.x != -1 && mv.y != -1) {
+                    counts[mv.x + deshake->rx][mv.y + deshake->ry] += 1;
+                    if (x > deshake->rx && y > deshake->ry)
+                        angles[pos++] = block_angle(x, y, 0, 0, &mv);
+
+                    center_x += mv.x;
+                    center_y += mv.y;
+                }
+            }
+        }
+    }
+
+    if (pos) {
+         center_x /= pos;
+         center_y /= pos;
+         t->angle = clean_mean(angles, pos);
+         if (t->angle < 0.001)
+              t->angle = 0;
+    } else {
+         t->angle = 0;
+    }
+
+    // Find the most common motion vector in the frame and use it as the gmv
+    for (y = deshake->ry * 2; y >= 0; y--) {
+        for (x = 0; x < deshake->rx * 2 + 1; x++) {
+            //av_log(NULL, AV_LOG_ERROR, "%5d ", counts[x][y]);
+            if (counts[x][y] > count_max_value) {
+                t->vector.x = x - deshake->rx;
+                t->vector.y = y - deshake->ry;
+                count_max_value = counts[x][y];
+            }
+        }
+        //av_log(NULL, AV_LOG_ERROR, "\n");
+    }
+
+    p_x = (center_x - width / 2);
+    p_y = (center_y - height / 2);
+    t->vector.x += (cos(t->angle)-1)*p_x  - sin(t->angle)*p_y;
+    t->vector.y += sin(t->angle)*p_x  + (cos(t->angle)-1)*p_y;
+
+    // Clamp max shift & rotation?
+    t->vector.x = av_clipf(t->vector.x, -deshake->rx * 2, deshake->rx * 2);
+    t->vector.y = av_clipf(t->vector.y, -deshake->ry * 2, deshake->ry * 2);
+    t->angle = av_clipf(t->angle, -0.1, 0.1);
+
+    //av_log(NULL, AV_LOG_ERROR, "%d x %d\n", avg->x, avg->y);
+    av_free(angles);
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    DeshakeContext *deshake = ctx->priv;
+    char filename[256] = {0};
+
+    deshake->rx = 16;
+    deshake->ry = 16;
+    deshake->edge = FILL_MIRROR;
+    deshake->blocksize = 8;
+    deshake->contrast = 125;
+    deshake->search = EXHAUSTIVE;
+    deshake->refcount = 20;
+
+    deshake->cw = -1;
+    deshake->ch = -1;
+    deshake->cx = -1;
+    deshake->cy = -1;
+
+    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->blocksize /= 2;
+
+        deshake->rx = av_clip(deshake->rx, 0, 64);
+        deshake->ry = av_clip(deshake->ry, 0, 64);
+        deshake->edge = av_clip(deshake->edge, FILL_BLANK, FILL_COUNT - 1);
+        deshake->blocksize = av_clip(deshake->blocksize, 4, 128);
+        deshake->contrast = av_clip(deshake->contrast, 1, 255);
+        deshake->search = av_clip(deshake->search, EXHAUSTIVE, SEARCH_COUNT - 1);
+
+    }
+    if (*filename)
+        deshake->fp = fopen(filename, "w");
+    if (deshake->fp)
+        fwrite("Ori x, Avg x, Fin x, Ori y, Avg y, Fin y, Ori angle, Avg angle, Fin angle, Ori zoom, Avg zoom, Fin zoom\n", sizeof(char), 104, deshake->fp);
+
+    // Quadword align left edge of box for MMX code, adjust width if necessary
+    // to keep right margin
+    if (deshake->cx > 0) {
+        deshake->cw += deshake->cx - (deshake->cx & ~15);
+        deshake->cx &= ~15;
+    }
+
+    av_log(ctx, AV_LOG_VERBOSE, "cx: %d, cy: %d, cw: %d, ch: %d, rx: %d, ry: %d, edge: %d blocksize: %d contrast: %d search: %d\n",
+           deshake->cx, deshake->cy, deshake->cw, deshake->ch,
+           deshake->rx, deshake->ry, deshake->edge, deshake->blocksize * 2, deshake->contrast, deshake->search);
+
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    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
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+
+    return 0;
+}
+
+static int config_props(AVFilterLink *link)
+{
+    DeshakeContext *deshake = link->dst->priv;
+
+    deshake->ref = NULL;
+    deshake->last.vector.x = 0;
+    deshake->last.vector.y = 0;
+    deshake->last.angle = 0;
+    deshake->last.zoom = 0;
+
+    deshake->avctx = avcodec_alloc_context3(NULL);
+    dsputil_init(&deshake->c, deshake->avctx);
+
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    DeshakeContext *deshake = ctx->priv;
+
+    avfilter_unref_buffer(deshake->ref);
+    if (deshake->fp)
+        fclose(deshake->fp);
+    if (deshake->avctx)
+        avcodec_close(deshake->avctx);
+    av_freep(&deshake->avctx);
+}
+
+static int end_frame(AVFilterLink *link)
+{
+    DeshakeContext *deshake = link->dst->priv;
+    AVFilterBufferRef *in  = link->cur_buf;
+    AVFilterBufferRef *out = link->dst->outputs[0]->out_buf;
+    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 */
+    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);
+    } else {
+        uint8_t *src1 = (deshake->ref == NULL) ? in->data[0] : deshake->ref->data[0];
+        uint8_t *src2 = in->data[0];
+
+        deshake->cx = FFMIN(deshake->cx, link->w);
+        deshake->cy = FFMIN(deshake->cy, link->h);
+
+        if ((unsigned)deshake->cx + (unsigned)deshake->cw > link->w) deshake->cw = link->w - deshake->cx;
+        if ((unsigned)deshake->cy + (unsigned)deshake->ch > link->h) deshake->ch = link->h - deshake->cy;
+
+        // Quadword align right margin
+        deshake->cw &= ~15;
+
+        src1 += deshake->cy * in->linesize[0] + deshake->cx;
+        src2 += deshake->cy * in->linesize[0] + deshake->cx;
+
+        find_motion(deshake, src1, src2, deshake->cw, deshake->ch, in->linesize[0], &t);
+    }
+
+
+    // Copy transform so we can output it later to compare to the smoothed value
+    orig.vector.x = t.vector.x;
+    orig.vector.y = t.vector.y;
+    orig.angle = t.angle;
+    orig.zoom = t.zoom;
+
+    // Generate a one-sided moving exponential average
+    deshake->avg.vector.x = alpha * t.vector.x + (1.0 - alpha) * deshake->avg.vector.x;
+    deshake->avg.vector.y = alpha * t.vector.y + (1.0 - alpha) * deshake->avg.vector.y;
+    deshake->avg.angle = alpha * t.angle + (1.0 - alpha) * deshake->avg.angle;
+    deshake->avg.zoom = alpha * t.zoom + (1.0 - alpha) * deshake->avg.zoom;
+
+    // Remove the average from the current motion to detect the motion that
+    // is not on purpose, just as jitter from bumping the camera
+    t.vector.x -= deshake->avg.vector.x;
+    t.vector.y -= deshake->avg.vector.y;
+    t.angle -= deshake->avg.angle;
+    t.zoom -= deshake->avg.zoom;
+
+    // Invert the motion to undo it
+    t.vector.x *= -1;
+    t.vector.y *= -1;
+    t.angle *= -1;
+
+    // Write statistics to file
+    if (deshake->fp) {
+        snprintf(tmp, 256, "%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f\n", orig.vector.x, deshake->avg.vector.x, t.vector.x, orig.vector.y, deshake->avg.vector.y, t.vector.y, orig.angle, deshake->avg.angle, t.angle, orig.zoom, deshake->avg.zoom, t.zoom);
+        fwrite(tmp, sizeof(char), strlen(tmp), deshake->fp);
+    }
+
+    // Turn relative current frame motion into absolute by adding it to the
+    // last absolute motion
+    t.vector.x += deshake->last.vector.x;
+    t.vector.y += deshake->last.vector.y;
+    t.angle += deshake->last.angle;
+    t.zoom += deshake->last.zoom;
+
+    // Shrink motion by 10% to keep things centered in the camera frame
+    t.vector.x *= 0.9;
+    t.vector.y *= 0.9;
+    t.angle *= 0.9;
+
+    // Store the last absolute motion information
+    deshake->last.vector.x = t.vector.x;
+    deshake->last.vector.y = t.vector.y;
+    deshake->last.angle = t.angle;
+    deshake->last.zoom = t.zoom;
+
+    // Generate a luma transformation matrix
+    avfilter_get_matrix(t.vector.x, t.vector.y, t.angle, 1.0 + t.zoom / 100.0, matrix);
+
+    // Transform the luma plane
+    avfilter_transform(in->data[0], out->data[0], in->linesize[0], out->linesize[0], link->w, link->h, matrix, INTERPOLATE_BILINEAR, deshake->edge);
+
+    // Generate a chroma transformation matrix
+    avfilter_get_matrix(t.vector.x / (link->w / CHROMA_WIDTH(link)), t.vector.y / (link->h / CHROMA_HEIGHT(link)), t.angle, 1.0 + t.zoom / 100.0, matrix);
+
+    // Transform the chroma planes
+    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);
+
+    // 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;
+}
+
+AVFilter avfilter_vf_deshake = {
+    .name      = "deshake",
+    .description = NULL_IF_CONFIG_SMALL("Stabilize shaky video."),
+
+    .priv_size = sizeof(DeshakeContext),
+
+    .init = init,
+    .uninit = uninit,
+    .query_formats = query_formats,
+
+    .inputs    = (const AVFilterPad[]) {{ .name       = "default",
+                                    .type             = AVMEDIA_TYPE_VIDEO,
+                                    .draw_slice       = draw_slice,
+                                    .end_frame        = end_frame,
+                                    .config_props     = config_props,
+                                    .min_perms        = AV_PERM_READ | AV_PERM_PRESERVE, },
+                                  { .name = NULL}},
+
+    .outputs   = (const AVFilterPad[]) {{ .name       = "default",
+                                    .type             = AVMEDIA_TYPE_VIDEO, },
+                                  { .name = NULL}},
+};
diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c
index fbae0ee..8e2b48e 100644
--- a/libavfilter/vf_drawbox.c
+++ b/libavfilter/vf_drawbox.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Affine Systems, Inc (Michael Sullivan, Bobby Impollonia)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -90,7 +90,7 @@
     if (drawbox->h == 0) drawbox->h = inlink->h;
 
     av_log(inlink->dst, AV_LOG_VERBOSE, "x:%d y:%d w:%d h:%d color:0x%02X%02X%02X%02X\n",
-           drawbox->w, drawbox->y, drawbox->w, drawbox->h,
+           drawbox->x, drawbox->y, drawbox->w, drawbox->h,
            drawbox->yuv_color[Y], drawbox->yuv_color[U], drawbox->yuv_color[V], drawbox->yuv_color[A]);
 
     return 0;
@@ -135,7 +135,6 @@
         .draw_slice       = draw_slice,
         .end_frame        = ff_null_end_frame,
         .min_perms        = AV_PERM_WRITE | AV_PERM_READ,
-        .rej_perms        = AV_PERM_PRESERVE
     },
     { NULL }
 };
diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c
index ecc789c..7b67271 100644
--- a/libavfilter/vf_drawtext.c
+++ b/libavfilter/vf_drawtext.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2010 S.N. Hemanth Meenakshisundaram
  * Copyright (c) 2003 Gustavo Sverzut Barbieri <gsbarbieri@yahoo.com.br>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,15 +29,15 @@
 #include <sys/time.h>
 #include <time.h>
 
-#include "libavutil/colorspace.h"
+#include "config.h"
+#include "libavutil/avstring.h"
 #include "libavutil/common.h"
 #include "libavutil/file.h"
 #include "libavutil/eval.h"
 #include "libavutil/opt.h"
-#include "libavutil/mathematics.h"
 #include "libavutil/random_seed.h"
 #include "libavutil/parseutils.h"
-#include "libavutil/pixdesc.h"
+#include "libavutil/timecode.h"
 #include "libavutil/tree.h"
 #include "libavutil/lfg.h"
 #include "avfilter.h"
@@ -52,19 +52,27 @@
 #include <freetype/config/ftheader.h>
 #include FT_FREETYPE_H
 #include FT_GLYPH_H
+#if CONFIG_FONTCONFIG
+#include <fontconfig/fontconfig.h>
+#endif
 
 static const char *const var_names[] = {
-    "E",
-    "PHI",
-    "PI",
-    "main_w",    "W", ///< width  of the main    video
-    "main_h",    "H", ///< height of the main    video
-    "text_w",    "w", ///< width  of the overlay text
-    "text_h",    "h", ///< height of the overlay text
+    "dar",
+    "hsub", "vsub",
+    "line_h", "lh",           ///< line height, same as max_glyph_h
+    "main_h", "h", "H",       ///< height of the input video
+    "main_w", "w", "W",       ///< width  of the input video
+    "max_glyph_a", "ascent",  ///< max glyph ascent
+    "max_glyph_d", "descent", ///< min glyph descent
+    "max_glyph_h",            ///< max glyph height
+    "max_glyph_w",            ///< max glyph width
+    "n",                      ///< number of frame
+    "sar",
+    "t",                      ///< timestamp expressed in seconds
+    "text_h", "th",           ///< height of the rendered text
+    "text_w", "tw",           ///< width  of the rendered text
     "x",
     "y",
-    "n",              ///< number of processed frames
-    "t",              ///< timestamp expressed in seconds
     NULL
 };
 
@@ -85,22 +93,28 @@
 };
 
 enum var_name {
-    VAR_E,
-    VAR_PHI,
-    VAR_PI,
-    VAR_MAIN_W, VAR_MW,
-    VAR_MAIN_H, VAR_MH,
-    VAR_TEXT_W, VAR_TW,
+    VAR_DAR,
+    VAR_HSUB, VAR_VSUB,
+    VAR_LINE_H, VAR_LH,
+    VAR_MAIN_H, VAR_h, VAR_H,
+    VAR_MAIN_W, VAR_w, VAR_W,
+    VAR_MAX_GLYPH_A, VAR_ASCENT,
+    VAR_MAX_GLYPH_D, VAR_DESCENT,
+    VAR_MAX_GLYPH_H,
+    VAR_MAX_GLYPH_W,
+    VAR_N,
+    VAR_SAR,
+    VAR_T,
     VAR_TEXT_H, VAR_TH,
+    VAR_TEXT_W, VAR_TW,
     VAR_X,
     VAR_Y,
-    VAR_N,
-    VAR_T,
     VAR_VARS_NB
 };
 
 typedef struct {
     const AVClass *class;
+    int reinit;                     ///< tells if the filter is being reinited
     uint8_t *fontfile;              ///< font to be used
     uint8_t *text;                  ///< text to be drawn
     uint8_t *expanded_text;         ///< used to contain the strftime()-expanded text
@@ -109,92 +123,92 @@
     FT_Vector *positions;           ///< positions for each element in the text
     size_t nb_positions;            ///< number of elements of positions array
     char *textfile;                 ///< file with text to be drawn
-    int x, y;                       ///< position to start drawing text
-    int w, h;                       ///< dimension of the text block
+    int x;                          ///< x position to start drawing text
+    int y;                          ///< y position to start drawing text
+    int max_glyph_w;                ///< max glyph width
+    int max_glyph_h;                ///< max glyph height
     int shadowx, shadowy;
     unsigned int fontsize;          ///< font size to use
     char *fontcolor_string;         ///< font color as string
     char *boxcolor_string;          ///< box color as string
     char *shadowcolor_string;       ///< shadow color as string
-    uint8_t fontcolor[4];           ///< foreground color
-    uint8_t boxcolor[4];            ///< background color
-    uint8_t shadowcolor[4];         ///< shadow color
-    uint8_t fontcolor_rgba[4];      ///< foreground color in RGBA
-    uint8_t boxcolor_rgba[4];       ///< background color in RGBA
-    uint8_t shadowcolor_rgba[4];    ///< shadow color in RGBA
 
     short int draw_box;             ///< draw box around text - true or false
     int use_kerning;                ///< font kerning is used - true/false
     int tabsize;                    ///< tab size
     int fix_bounds;                 ///< do we let it go out of frame bounds - t/f
 
+    FFDrawContext dc;
+    FFDrawColor fontcolor;          ///< foreground color
+    FFDrawColor shadowcolor;        ///< shadow color
+    FFDrawColor boxcolor;           ///< background color
+
     FT_Library library;             ///< freetype font library handle
     FT_Face face;                   ///< freetype font face handle
     struct AVTreeNode *glyphs;      ///< rendered glyphs, stored using the UTF-32 char code
-    int hsub, vsub;                 ///< chroma subsampling values
-    int is_packed_rgb;
-    int pixel_step[4];              ///< distance in bytes between the component of each pixel
-    uint8_t rgba_map[4];            ///< map RGBA offsets to the positions in the packed RGBA format
-    uint8_t *box_line[4];           ///< line used for filling the box background
-    char   *x_expr, *y_expr;
+    char *x_expr;                   ///< expression for x position
+    char *y_expr;                   ///< expression for y position
     AVExpr *x_pexpr, *y_pexpr;      ///< parsed expressions for x and y
+    int64_t basetime;               ///< base pts time in the real world for display
     double var_values[VAR_VARS_NB];
-    char   *d_expr;
-    AVExpr *d_pexpr;
+    char   *draw_expr;              ///< expression for draw
+    AVExpr *draw_pexpr;             ///< parsed expression for draw
     int draw;                       ///< set to zero to prevent drawing
     AVLFG  prng;                    ///< random
+    char       *tc_opt_string;      ///< specified timecode option string
+    AVRational  tc_rate;            ///< frame rate for timecode
+    AVTimecode  tc;                 ///< timecode context
+    int tc24hmax;                   ///< 1 if timecode is wrapped to 24 hours, 0 otherwise
+    int frame_id;
 } DrawTextContext;
 
 #define OFFSET(x) offsetof(DrawTextContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 
 static const AVOption drawtext_options[]= {
-{"fontfile", "set font file",        OFFSET(fontfile),           AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX },
-{"text",     "set text",             OFFSET(text),               AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX },
-{"textfile", "set text file",        OFFSET(textfile),           AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX },
-{"fontcolor","set foreground color", OFFSET(fontcolor_string),   AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX },
-{"boxcolor", "set box color",        OFFSET(boxcolor_string),    AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX },
-{"shadowcolor", "set shadow color",  OFFSET(shadowcolor_string), AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX },
-{"box",      "set box",              OFFSET(draw_box),           AV_OPT_TYPE_INT,    {.i64=0},     0,        1        },
-{"fontsize", "set font size",        OFFSET(fontsize),           AV_OPT_TYPE_INT,    {.i64=16},    1,        72       },
-{"x",        "set x",                OFFSET(x_expr),             AV_OPT_TYPE_STRING, {.str="0"},   CHAR_MIN, CHAR_MAX },
-{"y",        "set y",                OFFSET(y_expr),             AV_OPT_TYPE_STRING, {.str="0"},   CHAR_MIN, CHAR_MAX },
-{"shadowx",  "set x",                OFFSET(shadowx),            AV_OPT_TYPE_INT,    {.i64=0},     INT_MIN,  INT_MAX  },
-{"shadowy",  "set y",                OFFSET(shadowy),            AV_OPT_TYPE_INT,    {.i64=0},     INT_MIN,  INT_MAX  },
-{"tabsize",  "set tab size",         OFFSET(tabsize),            AV_OPT_TYPE_INT,    {.i64=4},     0,        INT_MAX  },
-{"draw",     "if false do not draw", OFFSET(d_expr),             AV_OPT_TYPE_STRING, {.str="1"},   CHAR_MIN, CHAR_MAX },
-{"fix_bounds", "if true, check and fix text coords to avoid clipping",
-                                     OFFSET(fix_bounds),         AV_OPT_TYPE_INT,    {.i64=1},     0,        1        },
+{"fontfile", "set font file",        OFFSET(fontfile),           AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX, FLAGS},
+{"text",     "set text",             OFFSET(text),               AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX, FLAGS},
+{"textfile", "set text file",        OFFSET(textfile),           AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX, FLAGS},
+{"fontcolor",   "set foreground color", OFFSET(fontcolor_string),   AV_OPT_TYPE_STRING, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS},
+{"boxcolor",    "set box color",        OFFSET(boxcolor_string),    AV_OPT_TYPE_STRING, {.str="white"}, CHAR_MIN, CHAR_MAX, FLAGS},
+{"shadowcolor", "set shadow color",     OFFSET(shadowcolor_string), AV_OPT_TYPE_STRING, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS},
+{"box",      "set box",              OFFSET(draw_box),           AV_OPT_TYPE_INT,    {.i64=0},     0,        1       , FLAGS},
+{"fontsize", "set font size",        OFFSET(fontsize),           AV_OPT_TYPE_INT,    {.i64=0},     0,        INT_MAX , FLAGS},
+{"x",        "set x expression",     OFFSET(x_expr),             AV_OPT_TYPE_STRING, {.str="0"},   CHAR_MIN, CHAR_MAX, FLAGS},
+{"y",        "set y expression",     OFFSET(y_expr),             AV_OPT_TYPE_STRING, {.str="0"},   CHAR_MIN, CHAR_MAX, FLAGS},
+{"shadowx",  "set x",                OFFSET(shadowx),            AV_OPT_TYPE_INT,    {.i64=0},     INT_MIN,  INT_MAX , FLAGS},
+{"shadowy",  "set y",                OFFSET(shadowy),            AV_OPT_TYPE_INT,    {.i64=0},     INT_MIN,  INT_MAX , FLAGS},
+{"tabsize",  "set tab size",         OFFSET(tabsize),            AV_OPT_TYPE_INT,    {.i64=4},     0,        INT_MAX , FLAGS},
+{"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},
+{"timecode", "set initial timecode", OFFSET(tc_opt_string),      AV_OPT_TYPE_STRING, {.str=NULL},  CHAR_MIN, CHAR_MAX, FLAGS},
+{"tc24hmax", "set 24 hours max (timecode only)", OFFSET(tc24hmax), AV_OPT_TYPE_INT,  {.i64=0},            0,        1, FLAGS},
+{"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},
+{"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 */
-{"ft_load_flags", "set font loading flags for libfreetype",   OFFSET(ft_load_flags),  AV_OPT_TYPE_FLAGS,  {.i64=FT_LOAD_DEFAULT|FT_LOAD_RENDER}, 0, INT_MAX, 0, "ft_load_flags" },
-{"default",                     "set default",                     0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_DEFAULT},                     INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"no_scale",                    "set no_scale",                    0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_NO_SCALE},                    INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"no_hinting",                  "set no_hinting",                  0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_NO_HINTING},                  INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"render",                      "set render",                      0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_RENDER},                      INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"no_bitmap",                   "set no_bitmap",                   0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_NO_BITMAP},                   INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"vertical_layout",             "set vertical_layout",             0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_VERTICAL_LAYOUT},             INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"force_autohint",              "set force_autohint",              0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_FORCE_AUTOHINT},              INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"crop_bitmap",                 "set crop_bitmap",                 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_CROP_BITMAP},                 INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"pedantic",                    "set pedantic",                    0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_PEDANTIC},                    INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"ignore_global_advance_width", "set ignore_global_advance_width", 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH}, INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"no_recurse",                  "set no_recurse",                  0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_NO_RECURSE},                  INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"ignore_transform",            "set ignore_transform",            0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_IGNORE_TRANSFORM},            INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"monochrome",                  "set monochrome",                  0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_MONOCHROME},                  INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"linear_design",               "set linear_design",               0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_LINEAR_DESIGN},               INT_MIN, INT_MAX, 0, "ft_load_flags" },
-{"no_autohint",                 "set no_autohint",                 0, AV_OPT_TYPE_CONST, {.i64 = FT_LOAD_NO_AUTOHINT},                 INT_MIN, INT_MAX, 0, "ft_load_flags" },
+{"ft_load_flags", "set font loading flags for libfreetype",   OFFSET(ft_load_flags),  AV_OPT_TYPE_FLAGS,  {.i64=FT_LOAD_DEFAULT|FT_LOAD_RENDER}, 0, INT_MAX, FLAGS, "ft_load_flags"},
+{"default",                     "set default",                     0, AV_OPT_TYPE_CONST, {.i64=FT_LOAD_DEFAULT},                     INT_MIN, INT_MAX, FLAGS, "ft_load_flags"},
+{"no_scale",                    "set no_scale",                    0, AV_OPT_TYPE_CONST, {.i64=FT_LOAD_NO_SCALE},                    INT_MIN, INT_MAX, FLAGS, "ft_load_flags"},
+{"no_hinting",                  "set no_hinting",                  0, AV_OPT_TYPE_CONST, {.i64=FT_LOAD_NO_HINTING},                  INT_MIN, INT_MAX, FLAGS, "ft_load_flags"},
+{"render",                      "set render",                      0, AV_OPT_TYPE_CONST, {.i64=FT_LOAD_RENDER},                      INT_MIN, INT_MAX, FLAGS, "ft_load_flags"},
+{"no_bitmap",                   "set no_bitmap",                   0, AV_OPT_TYPE_CONST, {.i64=FT_LOAD_NO_BITMAP},                   INT_MIN, INT_MAX, FLAGS, "ft_load_flags"},
+{"vertical_layout",             "set vertical_layout",             0, AV_OPT_TYPE_CONST, {.i64=FT_LOAD_VERTICAL_LAYOUT},             INT_MIN, INT_MAX, FLAGS, "ft_load_flags"},
+{"force_autohint",              "set force_autohint",              0, AV_OPT_TYPE_CONST, {.i64=FT_LOAD_FORCE_AUTOHINT},              INT_MIN, INT_MAX, FLAGS, "ft_load_flags"},
+{"crop_bitmap",                 "set crop_bitmap",                 0, AV_OPT_TYPE_CONST, {.i64=FT_LOAD_CROP_BITMAP},                 INT_MIN, INT_MAX, FLAGS, "ft_load_flags"},
+{"pedantic",                    "set pedantic",                    0, AV_OPT_TYPE_CONST, {.i64=FT_LOAD_PEDANTIC},                    INT_MIN, INT_MAX, FLAGS, "ft_load_flags"},
+{"ignore_global_advance_width", "set ignore_global_advance_width", 0, AV_OPT_TYPE_CONST, {.i64=FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH}, INT_MIN, INT_MAX, FLAGS, "ft_load_flags"},
+{"no_recurse",                  "set no_recurse",                  0, AV_OPT_TYPE_CONST, {.i64=FT_LOAD_NO_RECURSE},                  INT_MIN, INT_MAX, FLAGS, "ft_load_flags"},
+{"ignore_transform",            "set ignore_transform",            0, AV_OPT_TYPE_CONST, {.i64=FT_LOAD_IGNORE_TRANSFORM},            INT_MIN, INT_MAX, FLAGS, "ft_load_flags"},
+{"monochrome",                  "set monochrome",                  0, AV_OPT_TYPE_CONST, {.i64=FT_LOAD_MONOCHROME},                  INT_MIN, INT_MAX, FLAGS, "ft_load_flags"},
+{"linear_design",               "set linear_design",               0, AV_OPT_TYPE_CONST, {.i64=FT_LOAD_LINEAR_DESIGN},               INT_MIN, INT_MAX, FLAGS, "ft_load_flags"},
+{"no_autohint",                 "set no_autohint",                 0, AV_OPT_TYPE_CONST, {.i64=FT_LOAD_NO_AUTOHINT},                 INT_MIN, INT_MAX, FLAGS, "ft_load_flags"},
 {NULL},
 };
 
-static const char *drawtext_get_name(void *ctx)
-{
-    return "drawtext";
-}
-
-static const AVClass drawtext_class = {
-    "DrawTextContext",
-    drawtext_get_name,
-    drawtext_options
-};
+AVFILTER_DEFINE_CLASS(drawtext);
 
 #undef __FTERRORS_H__
 #define FT_ERROR_START_LIST {
@@ -281,6 +295,91 @@
     return ret;
 }
 
+static int load_font_file(AVFilterContext *ctx, const char *path, int index,
+                          const char **error)
+{
+    DrawTextContext *dtext = ctx->priv;
+    int err;
+
+    err = FT_New_Face(dtext->library, path, index, &dtext->face);
+    if (err) {
+        *error = FT_ERRMSG(err);
+        return AVERROR(EINVAL);
+    }
+    return 0;
+}
+
+#if CONFIG_FONTCONFIG
+static int load_font_fontconfig(AVFilterContext *ctx, const char **error)
+{
+    DrawTextContext *dtext = ctx->priv;
+    FcConfig *fontconfig;
+    FcPattern *pattern, *fpat;
+    FcResult result = FcResultMatch;
+    FcChar8 *filename;
+    int err, index;
+    double size;
+
+    fontconfig = FcInitLoadConfigAndFonts();
+    if (!fontconfig) {
+        *error = "impossible to init fontconfig\n";
+        return AVERROR(EINVAL);
+    }
+    pattern = FcNameParse(dtext->fontfile ? dtext->fontfile :
+                          (uint8_t *)(intptr_t)"default");
+    if (!pattern) {
+        *error = "could not parse fontconfig pattern";
+        return AVERROR(EINVAL);
+    }
+    if (!FcConfigSubstitute(fontconfig, pattern, FcMatchPattern)) {
+        *error = "could not substitue fontconfig options"; /* very unlikely */
+        return AVERROR(EINVAL);
+    }
+    FcDefaultSubstitute(pattern);
+    fpat = FcFontMatch(fontconfig, pattern, &result);
+    if (!fpat || result != FcResultMatch) {
+        *error = "impossible to find a matching font";
+        return AVERROR(EINVAL);
+    }
+    if (FcPatternGetString (fpat, FC_FILE,  0, &filename) != FcResultMatch ||
+        FcPatternGetInteger(fpat, FC_INDEX, 0, &index   ) != FcResultMatch ||
+        FcPatternGetDouble (fpat, FC_SIZE,  0, &size    ) != FcResultMatch) {
+        *error = "impossible to find font information";
+        return AVERROR(EINVAL);
+    }
+    av_log(ctx, AV_LOG_INFO, "Using \"%s\"\n", filename);
+    if (!dtext->fontsize)
+        dtext->fontsize = size + 0.5;
+    err = load_font_file(ctx, filename, index, error);
+    if (err)
+        return err;
+    FcPatternDestroy(fpat);
+    FcPatternDestroy(pattern);
+    FcConfigDestroy(fontconfig);
+    return 0;
+}
+#endif
+
+static int load_font(AVFilterContext *ctx)
+{
+    DrawTextContext *dtext = ctx->priv;
+    int err;
+    const char *error = "unknown error\n";
+
+    /* load the face, and set up the encoding, which is by default UTF-8 */
+    err = load_font_file(ctx, dtext->fontfile, 0, &error);
+    if (!err)
+        return 0;
+#if CONFIG_FONTCONFIG
+    err = load_font_fontconfig(ctx, &error);
+    if (!err)
+        return 0;
+#endif
+    av_log(ctx, AV_LOG_ERROR, "Could not load font \"%s\": %s\n",
+           dtext->fontfile, error);
+    return err;
+}
+
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     int err;
@@ -289,16 +388,11 @@
 
     dtext->class = &drawtext_class;
     av_opt_set_defaults(dtext);
-    dtext->fontcolor_string = av_strdup("black");
-    dtext->boxcolor_string = av_strdup("white");
-    dtext->shadowcolor_string = av_strdup("black");
 
-    if ((err = (av_set_options_string(dtext, args, "=", ":"))) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
+    if ((err = av_set_options_string(dtext, args, "=", ":")) < 0)
         return err;
-    }
 
-    if (!dtext->fontfile) {
+    if (!dtext->fontfile && !CONFIG_FONTCONFIG) {
         av_log(ctx, AV_LOG_ERROR, "No font filename provided\n");
         return AVERROR(EINVAL);
     }
@@ -326,25 +420,36 @@
         av_file_unmap(textbuf, textbuf_size);
     }
 
+    if (dtext->tc_opt_string) {
+        int ret = av_timecode_init_from_string(&dtext->tc, dtext->tc_rate,
+                                               dtext->tc_opt_string, ctx);
+        if (ret < 0)
+            return ret;
+        if (dtext->tc24hmax)
+            dtext->tc.flags |= AV_TIMECODE_FLAG_24HOURSMAX;
+        if (!dtext->text)
+            dtext->text = av_strdup("");
+    }
+
     if (!dtext->text) {
         av_log(ctx, AV_LOG_ERROR,
-               "Either text or a valid file must be provided\n");
+               "Either text, a valid file or a timecode must be provided\n");
         return AVERROR(EINVAL);
     }
 
-    if ((err = av_parse_color(dtext->fontcolor_rgba, dtext->fontcolor_string, -1, ctx))) {
+    if ((err = av_parse_color(dtext->fontcolor.rgba, dtext->fontcolor_string, -1, ctx))) {
         av_log(ctx, AV_LOG_ERROR,
                "Invalid font color '%s'\n", dtext->fontcolor_string);
         return err;
     }
 
-    if ((err = av_parse_color(dtext->boxcolor_rgba, dtext->boxcolor_string, -1, ctx))) {
+    if ((err = av_parse_color(dtext->boxcolor.rgba, dtext->boxcolor_string, -1, ctx))) {
         av_log(ctx, AV_LOG_ERROR,
                "Invalid box color '%s'\n", dtext->boxcolor_string);
         return err;
     }
 
-    if ((err = av_parse_color(dtext->shadowcolor_rgba, dtext->shadowcolor_string, -1, ctx))) {
+    if ((err = av_parse_color(dtext->shadowcolor.rgba, dtext->shadowcolor_string, -1, ctx))) {
         av_log(ctx, AV_LOG_ERROR,
                "Invalid shadow color '%s'\n", dtext->shadowcolor_string);
         return err;
@@ -356,12 +461,11 @@
         return AVERROR(EINVAL);
     }
 
-    /* load the face, and set up the encoding, which is by default UTF-8 */
-    if ((err = FT_New_Face(dtext->library, dtext->fontfile, 0, &dtext->face))) {
-        av_log(ctx, AV_LOG_ERROR, "Could not load fontface from file '%s': %s\n",
-               dtext->fontfile, FT_ERRMSG(err));
-        return AVERROR(EINVAL);
-    }
+    err = load_font(ctx);
+    if (err)
+        return err;
+    if (!dtext->fontsize)
+        dtext->fontsize = 16;
     if ((err = FT_Set_Pixel_Sizes(dtext->face, 0, dtext->fontsize))) {
         av_log(ctx, AV_LOG_ERROR, "Could not set font size to %d pixels: %s\n",
                dtext->fontsize, FT_ERRMSG(err));
@@ -374,37 +478,27 @@
     load_glyph(ctx, NULL, 0);
 
     /* set the tabsize in pixels */
-    if ((err = load_glyph(ctx, &glyph, ' ') < 0)) {
+    if ((err = load_glyph(ctx, &glyph, ' ')) < 0) {
         av_log(ctx, AV_LOG_ERROR, "Could not set tabsize.\n");
         return err;
     }
     dtext->tabsize *= glyph->advance;
 
-#if !HAVE_LOCALTIME_R
-    av_log(ctx, AV_LOG_WARNING, "strftime() expansion unavailable!\n");
-#endif
-
     return 0;
 }
 
 static int query_formats(AVFilterContext *ctx)
 {
-    static const 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_YUV420P, AV_PIX_FMT_YUV444P,
-        AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P,
-        AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV440P,
-        AV_PIX_FMT_NONE
-    };
-
-    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0));
     return 0;
 }
 
 static int glyph_enu_free(void *opaque, void *elem)
 {
+    Glyph *glyph = elem;
+
+    FT_Done_Glyph(*glyph->glyph);
+    av_freep(&glyph->glyph);
     av_free(elem);
     return 0;
 }
@@ -412,26 +506,21 @@
 static av_cold void uninit(AVFilterContext *ctx)
 {
     DrawTextContext *dtext = ctx->priv;
-    int i;
 
-    av_freep(&dtext->fontfile);
-    av_freep(&dtext->text);
-    av_freep(&dtext->expanded_text);
-    av_freep(&dtext->fontcolor_string);
-    av_freep(&dtext->boxcolor_string);
+    av_expr_free(dtext->x_pexpr); dtext->x_pexpr = NULL;
+    av_expr_free(dtext->y_pexpr); dtext->y_pexpr = NULL;
+    av_expr_free(dtext->draw_pexpr); dtext->draw_pexpr = NULL;
+    av_opt_free(dtext);
+
     av_freep(&dtext->positions);
-    av_freep(&dtext->shadowcolor_string);
+    dtext->nb_positions = 0;
+
     av_tree_enumerate(dtext->glyphs, NULL, NULL, glyph_enu_free);
     av_tree_destroy(dtext->glyphs);
-    dtext->glyphs = 0;
+    dtext->glyphs = NULL;
+
     FT_Done_Face(dtext->face);
     FT_Done_FreeType(dtext->library);
-
-    for (i = 0; i < 4; i++) {
-        av_freep(&dtext->box_line[i]);
-        dtext->pixel_step[i] = 0;
-    }
-
 }
 
 static inline int is_newline(uint32_t c)
@@ -439,155 +528,28 @@
     return c == '\n' || c == '\r' || c == '\f' || c == '\v';
 }
 
-static int dtext_prepare_text(AVFilterContext *ctx)
-{
-    DrawTextContext *dtext = ctx->priv;
-    uint32_t code = 0, prev_code = 0;
-    int x = 0, y = 0, i = 0, ret;
-    int text_height, baseline;
-    char *text = dtext->text;
-    uint8_t *p;
-    int str_w = 0, len;
-    int y_min = 32000, y_max = -32000;
-    FT_Vector delta;
-    Glyph *glyph = NULL, *prev_glyph = NULL;
-    Glyph dummy = { 0 };
-    int width  = ctx->inputs[0]->w;
-    int height = ctx->inputs[0]->h;
-
-#if HAVE_LOCALTIME_R
-    time_t now = time(0);
-    struct tm ltime;
-    uint8_t *buf = dtext->expanded_text;
-    int buf_size = dtext->expanded_text_size;
-
-    if (!buf)
-        buf_size = 2*strlen(dtext->text)+1;
-
-    localtime_r(&now, &ltime);
-
-    while ((buf = av_realloc(buf, buf_size))) {
-        *buf = 1;
-        if (strftime(buf, buf_size, dtext->text, &ltime) != 0 || *buf == 0)
-            break;
-        buf_size *= 2;
-    }
-
-    if (!buf)
-        return AVERROR(ENOMEM);
-    text = dtext->expanded_text = buf;
-    dtext->expanded_text_size = buf_size;
-#endif
-
-    if ((len = strlen(text)) > dtext->nb_positions) {
-        FT_Vector *p = av_realloc(dtext->positions,
-                                  len * sizeof(*dtext->positions));
-        if (!p) {
-            av_freep(dtext->positions);
-            dtext->nb_positions = 0;
-            return AVERROR(ENOMEM);
-        } else {
-            dtext->positions = p;
-            dtext->nb_positions = len;
-        }
-    }
-
-    /* load and cache glyphs */
-    for (i = 0, p = text; *p; i++) {
-        GET_UTF8(code, *p++, continue;);
-
-        /* get glyph */
-        dummy.code = code;
-        glyph = av_tree_find(dtext->glyphs, &dummy, glyph_cmp, NULL);
-        if (!glyph) {
-            ret = load_glyph(ctx, &glyph, code);
-            if (ret)
-                return ret;
-        }
-
-        y_min = FFMIN(glyph->bbox.yMin, y_min);
-        y_max = FFMAX(glyph->bbox.yMax, y_max);
-    }
-    text_height = y_max - y_min;
-    baseline    = y_max;
-
-    /* compute and save position for each glyph */
-    glyph = NULL;
-    for (i = 0, p = text; *p; i++) {
-        GET_UTF8(code, *p++, continue;);
-
-        /* skip the \n in the sequence \r\n */
-        if (prev_code == '\r' && code == '\n')
-            continue;
-
-        prev_code = code;
-        if (is_newline(code)) {
-            str_w = FFMAX(str_w, x - dtext->x);
-            y += text_height;
-            x = 0;
-            continue;
-        }
-
-        /* get glyph */
-        prev_glyph = glyph;
-        dummy.code = code;
-        glyph = av_tree_find(dtext->glyphs, &dummy, glyph_cmp, NULL);
-
-        /* kerning */
-        if (dtext->use_kerning && prev_glyph && glyph->code) {
-            FT_Get_Kerning(dtext->face, prev_glyph->code, glyph->code,
-                           ft_kerning_default, &delta);
-            x += delta.x >> 6;
-        }
-
-        if (x + glyph->bbox.xMax >= width) {
-            str_w = FFMAX(str_w, x);
-            y += text_height;
-            x = 0;
-        }
-
-        /* save position */
-        dtext->positions[i].x = x + glyph->bitmap_left;
-        dtext->positions[i].y = y - glyph->bitmap_top + baseline;
-        if (code == '\t') x  = (x / dtext->tabsize + 1)*dtext->tabsize;
-        else              x += glyph->advance;
-    }
-
-    str_w = FFMIN(width - 1, FFMAX(str_w, x));
-    y     = FFMIN(y + text_height, height - 1);
-
-    dtext->w = str_w;
-    dtext->var_values[VAR_TEXT_W] = dtext->var_values[VAR_TW] = dtext->w;
-    dtext->h = y;
-    dtext->var_values[VAR_TEXT_H] = dtext->var_values[VAR_TH] = dtext->h;
-
-    return 0;
-}
-
-
 static int config_input(AVFilterLink *inlink)
 {
-    AVFilterContext *ctx  = inlink->dst;
+    AVFilterContext *ctx = inlink->dst;
     DrawTextContext *dtext = ctx->priv;
-    const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
     int ret;
 
-    dtext->hsub = pix_desc->log2_chroma_w;
-    dtext->vsub = pix_desc->log2_chroma_h;
+    ff_draw_init(&dtext->dc, inlink->format, 0);
+    ff_draw_color(&dtext->dc, &dtext->fontcolor,   dtext->fontcolor.rgba);
+    ff_draw_color(&dtext->dc, &dtext->shadowcolor, dtext->shadowcolor.rgba);
+    ff_draw_color(&dtext->dc, &dtext->boxcolor,    dtext->boxcolor.rgba);
 
-    dtext->var_values[VAR_E  ] = M_E;
-    dtext->var_values[VAR_PHI] = M_PHI;
-    dtext->var_values[VAR_PI ] = M_PI;
-
-    dtext->var_values[VAR_MAIN_W] =
-        dtext->var_values[VAR_MW] = ctx->inputs[0]->w;
-    dtext->var_values[VAR_MAIN_H] =
-        dtext->var_values[VAR_MH] = ctx->inputs[0]->h;
-
-    dtext->var_values[VAR_X] = 0;
-    dtext->var_values[VAR_Y] = 0;
-    dtext->var_values[VAR_N] = 0;
-    dtext->var_values[VAR_T] = NAN;
+    dtext->var_values[VAR_w]     = dtext->var_values[VAR_W]     = dtext->var_values[VAR_MAIN_W] = inlink->w;
+    dtext->var_values[VAR_h]     = dtext->var_values[VAR_H]     = dtext->var_values[VAR_MAIN_H] = inlink->h;
+    dtext->var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ? av_q2d(inlink->sample_aspect_ratio) : 1;
+    dtext->var_values[VAR_DAR]   = (double)inlink->w / inlink->h * dtext->var_values[VAR_SAR];
+    dtext->var_values[VAR_HSUB]  = 1 << dtext->dc.hsub_max;
+    dtext->var_values[VAR_VSUB]  = 1 << dtext->dc.vsub_max;
+    dtext->var_values[VAR_X]     = NAN;
+    dtext->var_values[VAR_Y]     = NAN;
+    if (!dtext->reinit)
+        dtext->var_values[VAR_N] = 0;
+    dtext->var_values[VAR_T]     = NAN;
 
     av_lfg_init(&dtext->prng, av_get_random_seed());
 
@@ -595,139 +557,36 @@
                              NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 ||
         (ret = av_expr_parse(&dtext->y_pexpr, dtext->y_expr, var_names,
                              NULL, NULL, fun2_names, fun2, 0, ctx)) < 0 ||
-        (ret = av_expr_parse(&dtext->d_pexpr, dtext->d_expr, var_names,
+        (ret = av_expr_parse(&dtext->draw_pexpr, dtext->draw_expr, var_names,
                              NULL, NULL, fun2_names, fun2, 0, ctx)) < 0)
+
         return AVERROR(EINVAL);
 
-    if ((ret =
-         ff_fill_line_with_color(dtext->box_line, dtext->pixel_step,
-                                 inlink->w, dtext->boxcolor,
-                                 inlink->format, dtext->boxcolor_rgba,
-                                 &dtext->is_packed_rgb, dtext->rgba_map)) < 0)
-        return ret;
-
-    if (!dtext->is_packed_rgb) {
-        uint8_t *rgba = dtext->fontcolor_rgba;
-        dtext->fontcolor[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
-        dtext->fontcolor[1] = RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0);
-        dtext->fontcolor[2] = RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0);
-        dtext->fontcolor[3] = rgba[3];
-        rgba = dtext->shadowcolor_rgba;
-        dtext->shadowcolor[0] = RGB_TO_Y_CCIR(rgba[0], rgba[1], rgba[2]);
-        dtext->shadowcolor[1] = RGB_TO_U_CCIR(rgba[0], rgba[1], rgba[2], 0);
-        dtext->shadowcolor[2] = RGB_TO_V_CCIR(rgba[0], rgba[1], rgba[2], 0);
-        dtext->shadowcolor[3] = rgba[3];
-    }
-
-    dtext->draw = 1;
-
-    return dtext_prepare_text(ctx);
-}
-
-#define GET_BITMAP_VAL(r, c)                                            \
-    bitmap->pixel_mode == FT_PIXEL_MODE_MONO ?                          \
-        (bitmap->buffer[(r) * bitmap->pitch + ((c)>>3)] & (0x80 >> ((c)&7))) * 255 : \
-         bitmap->buffer[(r) * bitmap->pitch +  (c)]
-
-#define SET_PIXEL_YUV(picref, yuva_color, val, x, y, hsub, vsub) {           \
-    luma_pos    = ((x)          ) + ((y)          ) * picref->linesize[0]; \
-    alpha = yuva_color[3] * (val) * 129;                               \
-    picref->data[0][luma_pos]    = (alpha * yuva_color[0] + (255*255*129 - alpha) * picref->data[0][luma_pos]   ) >> 23; \
-    if (((x) & ((1<<(hsub)) - 1)) == 0 && ((y) & ((1<<(vsub)) - 1)) == 0) {\
-        chroma_pos1 = ((x) >> (hsub)) + ((y) >> (vsub)) * picref->linesize[1]; \
-        chroma_pos2 = ((x) >> (hsub)) + ((y) >> (vsub)) * picref->linesize[2]; \
-        picref->data[1][chroma_pos1] = (alpha * yuva_color[1] + (255*255*129 - alpha) * picref->data[1][chroma_pos1]) >> 23; \
-        picref->data[2][chroma_pos2] = (alpha * yuva_color[2] + (255*255*129 - alpha) * picref->data[2][chroma_pos2]) >> 23; \
-    }\
-}
-
-static inline int draw_glyph_yuv(AVFilterBufferRef *picref, FT_Bitmap *bitmap, unsigned int x,
-                                 unsigned int y, unsigned int width, unsigned int height,
-                                 const uint8_t yuva_color[4], int hsub, int vsub)
-{
-    int r, c, alpha;
-    unsigned int luma_pos, chroma_pos1, chroma_pos2;
-    uint8_t src_val;
-
-    for (r = 0; r < bitmap->rows && r+y < height; r++) {
-        for (c = 0; c < bitmap->width && c+x < width; c++) {
-            /* get intensity value in the glyph bitmap (source) */
-            src_val = GET_BITMAP_VAL(r, c);
-            if (!src_val)
-                continue;
-
-            SET_PIXEL_YUV(picref, yuva_color, src_val, c+x, y+r, hsub, vsub);
-        }
-    }
-
     return 0;
 }
 
-#define SET_PIXEL_RGB(picref, rgba_color, val, x, y, pixel_step, r_off, g_off, b_off, a_off) { \
-    p   = picref->data[0] + (x) * pixel_step + ((y) * picref->linesize[0]); \
-    alpha = rgba_color[3] * (val) * 129;                              \
-    *(p+r_off) = (alpha * rgba_color[0] + (255*255*129 - alpha) * *(p+r_off)) >> 23; \
-    *(p+g_off) = (alpha * rgba_color[1] + (255*255*129 - alpha) * *(p+g_off)) >> 23; \
-    *(p+b_off) = (alpha * rgba_color[2] + (255*255*129 - alpha) * *(p+b_off)) >> 23; \
-}
-
-static inline int draw_glyph_rgb(AVFilterBufferRef *picref, FT_Bitmap *bitmap,
-                                 unsigned int x, unsigned int y,
-                                 unsigned int width, unsigned int height, int pixel_step,
-                                 const uint8_t rgba_color[4], const uint8_t rgba_map[4])
+static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
 {
-    int r, c, alpha;
-    uint8_t *p;
-    uint8_t src_val;
+    DrawTextContext *dtext = ctx->priv;
 
-    for (r = 0; r < bitmap->rows && r+y < height; r++) {
-        for (c = 0; c < bitmap->width && c+x < width; c++) {
-            /* get intensity value in the glyph bitmap (source) */
-            src_val = GET_BITMAP_VAL(r, c);
-            if (!src_val)
-                continue;
-
-            SET_PIXEL_RGB(picref, rgba_color, src_val, c+x, y+r, pixel_step,
-                          rgba_map[0], rgba_map[1], rgba_map[2], rgba_map[3]);
-        }
+    if (!strcmp(cmd, "reinit")) {
+        int ret;
+        uninit(ctx);
+        dtext->reinit = 1;
+        if ((ret = init(ctx, arg)) < 0)
+            return ret;
+        return config_input(ctx->inputs[0]);
     }
 
-    return 0;
-}
-
-static inline void drawbox(AVFilterBufferRef *picref, unsigned int x, unsigned int y,
-                           unsigned int width, unsigned int height,
-                           uint8_t *line[4], int pixel_step[4], uint8_t color[4],
-                           int hsub, int vsub, int is_rgba_packed, uint8_t rgba_map[4])
-{
-    int i, j, alpha;
-
-    if (color[3] != 0xFF) {
-        if (is_rgba_packed) {
-            uint8_t *p;
-            for (j = 0; j < height; j++)
-                for (i = 0; i < width; i++)
-                    SET_PIXEL_RGB(picref, color, 255, i+x, y+j, pixel_step[0],
-                                  rgba_map[0], rgba_map[1], rgba_map[2], rgba_map[3]);
-        } else {
-            unsigned int luma_pos, chroma_pos1, chroma_pos2;
-            for (j = 0; j < height; j++)
-                for (i = 0; i < width; i++)
-                    SET_PIXEL_YUV(picref, color, 255, i+x, y+j, hsub, vsub);
-        }
-    } else {
-        ff_draw_rectangle(picref->data, picref->linesize,
-                          line, pixel_step, hsub, vsub,
-                          x, y, width, height);
-    }
+    return AVERROR(ENOSYS);
 }
 
 static int draw_glyphs(DrawTextContext *dtext, AVFilterBufferRef *picref,
-                       int width, int height, const uint8_t rgbcolor[4], const uint8_t yuvcolor[4], int x, int y)
+                       int width, int height, const uint8_t rgbcolor[4], FFDrawColor *color, int x, int y)
 {
-    char *text = HAVE_LOCALTIME_R ? dtext->expanded_text : dtext->text;
+    char *text = dtext->expanded_text;
     uint32_t code = 0;
-    int i;
+    int i, x1, y1;
     uint8_t *p;
     Glyph *glyph = NULL;
 
@@ -746,15 +605,15 @@
             glyph->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY)
             return AVERROR(EINVAL);
 
-        if (dtext->is_packed_rgb) {
-            draw_glyph_rgb(picref, &glyph->bitmap,
-                           dtext->positions[i].x+x, dtext->positions[i].y+y, width, height,
-                           dtext->pixel_step[0], rgbcolor, dtext->rgba_map);
-        } else {
-            draw_glyph_yuv(picref, &glyph->bitmap,
-                           dtext->positions[i].x+x, dtext->positions[i].y+y, width, height,
-                           yuvcolor, dtext->hsub, dtext->vsub);
-        }
+        x1 = dtext->positions[i].x+dtext->x+x;
+        y1 = dtext->positions[i].y+dtext->y+y;
+
+        ff_blend_mask(&dtext->dc, color,
+                      picref->data, picref->linesize, width, height,
+                      glyph->bitmap.buffer, glyph->bitmap.pitch,
+                      glyph->bitmap.width, glyph->bitmap.rows,
+                      glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO ? 0 : 3,
+                      0, x1, y1);
     }
 
     return 0;
@@ -764,29 +623,158 @@
                      int width, int height)
 {
     DrawTextContext *dtext = ctx->priv;
-    int ret;
+    uint32_t code = 0, prev_code = 0;
+    int x = 0, y = 0, i = 0, ret;
+    int max_text_line_w = 0, len;
+    int box_w, box_h;
+    char *text = dtext->text;
+    uint8_t *p;
+    int y_min = 32000, y_max = -32000;
+    int x_min = 32000, x_max = -32000;
+    FT_Vector delta;
+    Glyph *glyph = NULL, *prev_glyph = NULL;
+    Glyph dummy = { 0 };
+
+    time_t now = time(0);
+    struct tm ltime;
+    uint8_t *buf = dtext->expanded_text;
+    int buf_size = dtext->expanded_text_size;
+
+    if(dtext->basetime != AV_NOPTS_VALUE)
+        now= picref->pts*av_q2d(ctx->inputs[0]->time_base) + dtext->basetime/1000000;
+
+    if (!buf) {
+        buf_size = 2*strlen(dtext->text)+1;
+        buf = av_malloc(buf_size);
+    }
+
+#if HAVE_LOCALTIME_R
+    localtime_r(&now, &ltime);
+#else
+    if(strchr(dtext->text, '%'))
+        ltime= *localtime(&now);
+#endif
+
+    do {
+        *buf = 1;
+        if (strftime(buf, buf_size, dtext->text, &ltime) != 0 || *buf == 0)
+            break;
+        buf_size *= 2;
+    } while ((buf = av_realloc(buf, buf_size)));
+
+    if (dtext->tc_opt_string) {
+        char tcbuf[AV_TIMECODE_STR_SIZE];
+        av_timecode_make_string(&dtext->tc, tcbuf, dtext->frame_id++);
+        av_free(buf);
+        buf = av_asprintf("%s%s", dtext->text, tcbuf);
+    }
+
+    if (!buf)
+        return AVERROR(ENOMEM);
+    text = dtext->expanded_text = buf;
+    dtext->expanded_text_size = buf_size;
+    if ((len = strlen(text)) > dtext->nb_positions) {
+        if (!(dtext->positions =
+              av_realloc(dtext->positions, len*sizeof(*dtext->positions))))
+            return AVERROR(ENOMEM);
+        dtext->nb_positions = len;
+    }
+
+    x = 0;
+    y = 0;
+
+    /* load and cache glyphs */
+    for (i = 0, p = text; *p; i++) {
+        GET_UTF8(code, *p++, continue;);
+
+        /* get glyph */
+        dummy.code = code;
+        glyph = av_tree_find(dtext->glyphs, &dummy, glyph_cmp, NULL);
+        if (!glyph) {
+            load_glyph(ctx, &glyph, code);
+        }
+
+        y_min = FFMIN(glyph->bbox.yMin, y_min);
+        y_max = FFMAX(glyph->bbox.yMax, y_max);
+        x_min = FFMIN(glyph->bbox.xMin, x_min);
+        x_max = FFMAX(glyph->bbox.xMax, x_max);
+    }
+    dtext->max_glyph_h = y_max - y_min;
+    dtext->max_glyph_w = x_max - x_min;
+
+    /* compute and save position for each glyph */
+    glyph = NULL;
+    for (i = 0, p = text; *p; i++) {
+        GET_UTF8(code, *p++, continue;);
+
+        /* skip the \n in the sequence \r\n */
+        if (prev_code == '\r' && code == '\n')
+            continue;
+
+        prev_code = code;
+        if (is_newline(code)) {
+            max_text_line_w = FFMAX(max_text_line_w, x);
+            y += dtext->max_glyph_h;
+            x = 0;
+            continue;
+        }
+
+        /* get glyph */
+        prev_glyph = glyph;
+        dummy.code = code;
+        glyph = av_tree_find(dtext->glyphs, &dummy, glyph_cmp, NULL);
+
+        /* kerning */
+        if (dtext->use_kerning && prev_glyph && glyph->code) {
+            FT_Get_Kerning(dtext->face, prev_glyph->code, glyph->code,
+                           ft_kerning_default, &delta);
+            x += delta.x >> 6;
+        }
+
+        /* save position */
+        dtext->positions[i].x = x + glyph->bitmap_left;
+        dtext->positions[i].y = y - glyph->bitmap_top + y_max;
+        if (code == '\t') x  = (x / dtext->tabsize + 1)*dtext->tabsize;
+        else              x += glyph->advance;
+    }
+
+    max_text_line_w = FFMAX(x, max_text_line_w);
+
+    dtext->var_values[VAR_TW] = dtext->var_values[VAR_TEXT_W] = max_text_line_w;
+    dtext->var_values[VAR_TH] = dtext->var_values[VAR_TEXT_H] = y + dtext->max_glyph_h;
+
+    dtext->var_values[VAR_MAX_GLYPH_W] = dtext->max_glyph_w;
+    dtext->var_values[VAR_MAX_GLYPH_H] = dtext->max_glyph_h;
+    dtext->var_values[VAR_MAX_GLYPH_A] = dtext->var_values[VAR_ASCENT ] = y_max;
+    dtext->var_values[VAR_MAX_GLYPH_D] = dtext->var_values[VAR_DESCENT] = y_min;
+
+    dtext->var_values[VAR_LINE_H] = dtext->var_values[VAR_LH] = dtext->max_glyph_h;
+
+    dtext->x = dtext->var_values[VAR_X] = av_expr_eval(dtext->x_pexpr, dtext->var_values, &dtext->prng);
+    dtext->y = dtext->var_values[VAR_Y] = av_expr_eval(dtext->y_pexpr, dtext->var_values, &dtext->prng);
+    dtext->x = dtext->var_values[VAR_X] = av_expr_eval(dtext->x_pexpr, dtext->var_values, &dtext->prng);
+    dtext->draw = av_expr_eval(dtext->draw_pexpr, dtext->var_values, &dtext->prng);
+
+    if(!dtext->draw)
+        return 0;
+
+    box_w = FFMIN(width - 1 , max_text_line_w);
+    box_h = FFMIN(height - 1, y + dtext->max_glyph_h);
 
     /* draw box */
     if (dtext->draw_box)
-        drawbox(picref, dtext->x, dtext->y, dtext->w, dtext->h,
-                dtext->box_line, dtext->pixel_step, dtext->boxcolor,
-                dtext->hsub, dtext->vsub, dtext->is_packed_rgb,
-                dtext->rgba_map);
+        ff_blend_rectangle(&dtext->dc, &dtext->boxcolor,
+                           picref->data, picref->linesize, width, height,
+                           dtext->x, dtext->y, box_w, box_h);
 
     if (dtext->shadowx || dtext->shadowy) {
-        if ((ret = draw_glyphs(dtext, picref, width, height,
-                               dtext->shadowcolor_rgba,
-                               dtext->shadowcolor,
-                               dtext->x + dtext->shadowx,
-                               dtext->y + dtext->shadowy)) < 0)
+        if ((ret = draw_glyphs(dtext, picref, width, height, dtext->shadowcolor.rgba,
+                               &dtext->shadowcolor, dtext->shadowx, dtext->shadowy)) < 0)
             return ret;
     }
 
-    if ((ret = draw_glyphs(dtext, picref, width, height,
-                           dtext->fontcolor_rgba,
-                           dtext->fontcolor,
-                           dtext->x,
-                           dtext->y)) < 0)
+    if ((ret = draw_glyphs(dtext, picref, width, height, dtext->fontcolor.rgba,
+                           &dtext->fontcolor, 0, 0)) < 0)
         return ret;
 
     return 0;
@@ -797,79 +785,23 @@
     return 0;
 }
 
-static inline int normalize_double(int *n, double d)
-{
-    int ret = 0;
-
-    if (isnan(d)) {
-        ret = AVERROR(EINVAL);
-    } else if (d > INT_MAX || d < INT_MIN) {
-        *n = d > INT_MAX ? INT_MAX : INT_MIN;
-        ret = AVERROR(EINVAL);
-    } else
-        *n = round(d);
-
-    return ret;
-}
-
-static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
-{
-    AVFilterContext *ctx = inlink->dst;
-    DrawTextContext *dtext = ctx->priv;
-    AVFilterBufferRef *buf_out;
-    int ret = 0;
-
-    if ((ret = dtext_prepare_text(ctx)) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Can't draw text\n");
-        return ret;
-    }
-
-    dtext->var_values[VAR_T] = inpicref->pts == AV_NOPTS_VALUE ?
-        NAN : inpicref->pts * av_q2d(inlink->time_base);
-    dtext->var_values[VAR_X] =
-        av_expr_eval(dtext->x_pexpr, dtext->var_values, &dtext->prng);
-    dtext->var_values[VAR_Y] =
-        av_expr_eval(dtext->y_pexpr, dtext->var_values, &dtext->prng);
-    dtext->var_values[VAR_X] =
-        av_expr_eval(dtext->x_pexpr, dtext->var_values, &dtext->prng);
-
-    dtext->draw = av_expr_eval(dtext->d_pexpr, dtext->var_values, &dtext->prng);
-
-    normalize_double(&dtext->x, dtext->var_values[VAR_X]);
-    normalize_double(&dtext->y, dtext->var_values[VAR_Y]);
-
-    if (dtext->fix_bounds) {
-        if (dtext->x < 0) dtext->x = 0;
-        if (dtext->y < 0) dtext->y = 0;
-        if ((unsigned)dtext->x + (unsigned)dtext->w > inlink->w)
-            dtext->x = inlink->w - dtext->w;
-        if ((unsigned)dtext->y + (unsigned)dtext->h > inlink->h)
-            dtext->y = inlink->h - dtext->h;
-    }
-
-    dtext->x &= ~((1 << dtext->hsub) - 1);
-    dtext->y &= ~((1 << dtext->vsub) - 1);
-
-    av_dlog(ctx, "n:%d t:%f x:%d y:%d x+w:%d y+h:%d\n",
-            (int)dtext->var_values[VAR_N], dtext->var_values[VAR_T],
-            dtext->x, dtext->y, dtext->x+dtext->w, dtext->y+dtext->h);
-
-    buf_out = avfilter_ref_buffer(inpicref, ~0);
-    if (!buf_out)
-        return AVERROR(ENOMEM);
-
-    return ff_start_frame(inlink->dst->outputs[0], buf_out);
-}
-
 static int end_frame(AVFilterLink *inlink)
 {
-    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFilterContext *ctx = inlink->dst;
+    AVFilterLink *outlink = ctx->outputs[0];
+    DrawTextContext *dtext = ctx->priv;
     AVFilterBufferRef *picref = inlink->cur_buf;
-    DrawTextContext *dtext = inlink->dst->priv;
     int ret;
 
-    if (dtext->draw)
-        draw_text(inlink->dst, picref, picref->video->w, picref->video->h);
+    dtext->var_values[VAR_T] = picref->pts == AV_NOPTS_VALUE ?
+        NAN : picref->pts * av_q2d(inlink->time_base);
+
+    draw_text(ctx, picref, picref->video->w, picref->video->h);
+
+    av_log(ctx, AV_LOG_DEBUG, "n:%d t:%f text_w:%d text_h:%d x:%d y:%d\n",
+           (int)dtext->var_values[VAR_N], dtext->var_values[VAR_T],
+           (int)dtext->var_values[VAR_TEXT_W], (int)dtext->var_values[VAR_TEXT_H],
+           dtext->x, dtext->y);
 
     dtext->var_values[VAR_N] += 1.0;
 
@@ -884,13 +816,12 @@
         .name             = "default",
         .type             = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = ff_null_get_video_buffer,
-        .start_frame      = start_frame,
+        .start_frame      = ff_null_start_frame,
         .draw_slice       = null_draw_slice,
         .end_frame        = end_frame,
         .config_props     = config_input,
         .min_perms        = AV_PERM_WRITE |
                             AV_PERM_READ,
-        .rej_perms = AV_PERM_PRESERVE
     },
     { NULL }
 };
@@ -913,4 +844,6 @@
 
     .inputs    = avfilter_vf_drawtext_inputs,
     .outputs   = avfilter_vf_drawtext_outputs,
+    .process_command = command,
+    .priv_class = &drawtext_class,
 };
diff --git a/libavfilter/vf_edgedetect.c b/libavfilter/vf_edgedetect.c
new file mode 100644
index 0000000..d3d8ca1
--- /dev/null
+++ b/libavfilter/vf_edgedetect.c
@@ -0,0 +1,324 @@
+/*
+ * 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
+ * Edge detection filter
+ *
+ * @see https://en.wikipedia.org/wiki/Canny_edge_detector
+ */
+
+#include "libavutil/opt.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+typedef struct {
+    const AVClass *class;
+    uint8_t  *tmpbuf;
+    uint16_t *gradients;
+    char     *directions;
+    double   low, high;
+    uint8_t  low_u8, high_u8;
+} EdgeDetectContext;
+
+#define OFFSET(x) offsetof(EdgeDetectContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption edgedetect_options[] = {
+    { "high", "set high threshold", OFFSET(high), AV_OPT_TYPE_DOUBLE, {.dbl=50/255.}, 0, 1, FLAGS },
+    { "low",  "set low threshold",  OFFSET(low),  AV_OPT_TYPE_DOUBLE, {.dbl=20/255.}, 0, 1, FLAGS },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(edgedetect);
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    int ret;
+    EdgeDetectContext *edgedetect = ctx->priv;
+
+    edgedetect->class = &edgedetect_class;
+    av_opt_set_defaults(edgedetect);
+
+    if ((ret = av_set_options_string(edgedetect, args, "=", ":")) < 0)
+        return ret;
+
+    edgedetect->low_u8  = edgedetect->low  * 255. + .5;
+    edgedetect->high_u8 = edgedetect->high * 255. + .5;
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE};
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static int config_props(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    EdgeDetectContext *edgedetect = ctx->priv;
+
+    edgedetect->tmpbuf     = av_malloc(inlink->w * inlink->h);
+    edgedetect->gradients  = av_calloc(inlink->w * inlink->h, sizeof(*edgedetect->gradients));
+    edgedetect->directions = av_malloc(inlink->w * inlink->h);
+    if (!edgedetect->tmpbuf || !edgedetect->gradients || !edgedetect->directions)
+        return AVERROR(ENOMEM);
+    return 0;
+}
+
+static void gaussian_blur(AVFilterContext *ctx, int w, int h,
+                                uint8_t *dst, int dst_linesize,
+                          const uint8_t *src, int src_linesize)
+{
+    int i, j;
+
+    memcpy(dst, src, w); dst += dst_linesize; src += src_linesize;
+    memcpy(dst, src, w); dst += dst_linesize; src += src_linesize;
+    for (j = 2; j < h - 2; j++) {
+        dst[0] = src[0];
+        dst[1] = src[1];
+        for (i = 2; i < w - 2; i++) {
+            /* Gaussian mask of size 5x5 with sigma = 1.4 */
+            dst[i] = ((src[-2*src_linesize + i-2] + src[2*src_linesize + i-2]) * 2
+                    + (src[-2*src_linesize + i-1] + src[2*src_linesize + i-1]) * 4
+                    + (src[-2*src_linesize + i  ] + src[2*src_linesize + i  ]) * 5
+                    + (src[-2*src_linesize + i+1] + src[2*src_linesize + i+1]) * 4
+                    + (src[-2*src_linesize + i+2] + src[2*src_linesize + i+2]) * 2
+
+                    + (src[  -src_linesize + i-2] + src[  src_linesize + i-2]) *  4
+                    + (src[  -src_linesize + i-1] + src[  src_linesize + i-1]) *  9
+                    + (src[  -src_linesize + i  ] + src[  src_linesize + i  ]) * 12
+                    + (src[  -src_linesize + i+1] + src[  src_linesize + i+1]) *  9
+                    + (src[  -src_linesize + i+2] + src[  src_linesize + i+2]) *  4
+
+                    + src[i-2] *  5
+                    + src[i-1] * 12
+                    + src[i  ] * 15
+                    + src[i+1] * 12
+                    + src[i+2] *  5) / 159;
+        }
+        dst[i    ] = src[i    ];
+        dst[i + 1] = src[i + 1];
+
+        dst += dst_linesize;
+        src += src_linesize;
+    }
+    memcpy(dst, src, w); dst += dst_linesize; src += src_linesize;
+    memcpy(dst, src, w);
+}
+
+enum {
+    DIRECTION_45UP,
+    DIRECTION_45DOWN,
+    DIRECTION_HORIZONTAL,
+    DIRECTION_VERTICAL,
+};
+
+static int get_rounded_direction(int gx, int gy)
+{
+    /* reference angles:
+     *   tan( pi/8) = sqrt(2)-1
+     *   tan(3pi/8) = sqrt(2)+1
+     * Gy/Gx is the tangent of the angle (theta), so Gy/Gx is compared against
+     * <ref-angle>, or more simply Gy against <ref-angle>*Gx
+     *
+     * Gx and Gy bounds = [-1020;1020], using 16-bit arithmetic:
+     *   round((sqrt(2)-1) * (1<<16)) =  27146
+     *   round((sqrt(2)+1) * (1<<16)) = 158218
+     */
+    if (gx) {
+        int tanpi8gx, tan3pi8gx;
+
+        if (gx < 0)
+            gx = -gx, gy = -gy;
+        gy <<= 16;
+        tanpi8gx  =  27146 * gx;
+        tan3pi8gx = 158218 * gx;
+        if (gy > -tan3pi8gx && gy < -tanpi8gx)  return DIRECTION_45UP;
+        if (gy > -tanpi8gx  && gy <  tanpi8gx)  return DIRECTION_HORIZONTAL;
+        if (gy >  tanpi8gx  && gy <  tan3pi8gx) return DIRECTION_45DOWN;
+    }
+    return DIRECTION_VERTICAL;
+}
+
+static void sobel(AVFilterContext *ctx, int w, int h,
+                        uint16_t *dst, int dst_linesize,
+                  const uint8_t  *src, int src_linesize)
+{
+    int i, j;
+    EdgeDetectContext *edgedetect = ctx->priv;
+
+    for (j = 1; j < h - 1; j++) {
+        dst += dst_linesize;
+        src += src_linesize;
+        for (i = 1; i < w - 1; i++) {
+            const int gx =
+                -1*src[-src_linesize + i-1] + 1*src[-src_linesize + i+1]
+                -2*src[                i-1] + 2*src[                i+1]
+                -1*src[ src_linesize + i-1] + 1*src[ src_linesize + i+1];
+            const int gy =
+                -1*src[-src_linesize + i-1] + 1*src[ src_linesize + i-1]
+                -2*src[-src_linesize + i  ] + 2*src[ src_linesize + i  ]
+                -1*src[-src_linesize + i+1] + 1*src[ src_linesize + i+1];
+
+            dst[i] = FFABS(gx) + FFABS(gy);
+            edgedetect->directions[j*w + i] = get_rounded_direction(gx, gy);
+        }
+    }
+}
+
+static void non_maximum_suppression(AVFilterContext *ctx, int w, int h,
+                                          uint8_t  *dst, int dst_linesize,
+                                    const uint16_t *src, int src_linesize)
+{
+    int i, j;
+    EdgeDetectContext *edgedetect = ctx->priv;
+
+#define COPY_MAXIMA(ay, ax, by, bx) do {                \
+    if (src[i] > src[(ay)*src_linesize + i+(ax)] &&     \
+        src[i] > src[(by)*src_linesize + i+(bx)])       \
+        dst[i] = av_clip_uint8(src[i]);                 \
+} while (0)
+
+    for (j = 1; j < h - 1; j++) {
+        dst += dst_linesize;
+        src += src_linesize;
+        for (i = 1; i < w - 1; i++) {
+            switch (edgedetect->directions[j*w + i]) {
+            case DIRECTION_45UP:        COPY_MAXIMA( 1, -1, -1,  1); break;
+            case DIRECTION_45DOWN:      COPY_MAXIMA(-1, -1,  1,  1); break;
+            case DIRECTION_HORIZONTAL:  COPY_MAXIMA( 0, -1,  0,  1); break;
+            case DIRECTION_VERTICAL:    COPY_MAXIMA(-1,  0,  1,  0); break;
+            }
+        }
+    }
+}
+
+static void double_threshold(AVFilterContext *ctx, int w, int h,
+                                   uint8_t *dst, int dst_linesize,
+                             const uint8_t *src, int src_linesize)
+{
+    int i, j;
+    EdgeDetectContext *edgedetect = ctx->priv;
+    const int low  = edgedetect->low_u8;
+    const int high = edgedetect->high_u8;
+
+    for (j = 0; j < h; j++) {
+        for (i = 0; i < w; i++) {
+            if (src[i] > high) {
+                dst[i] = src[i];
+                continue;
+            }
+
+            if ((!i || i == w - 1 || !j || j == h - 1) &&
+                src[i] > low &&
+                (src[-src_linesize + i-1] > high ||
+                 src[-src_linesize + i  ] > high ||
+                 src[-src_linesize + i+1] > high ||
+                 src[                i-1] > high ||
+                 src[                i+1] > high ||
+                 src[ src_linesize + i-1] > high ||
+                 src[ src_linesize + i  ] > high ||
+                 src[ src_linesize + i+1] > high))
+                dst[i] = src[i];
+            else
+                dst[i] = 0;
+        }
+        dst += dst_linesize;
+        src += src_linesize;
+    }
+}
+
+static int end_frame(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    EdgeDetectContext *edgedetect = ctx->priv;
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFilterBufferRef  *inpicref = inlink->cur_buf;
+    AVFilterBufferRef *outpicref = outlink->out_buf;
+    uint8_t  *tmpbuf    = edgedetect->tmpbuf;
+    uint16_t *gradients = edgedetect->gradients;
+
+    /* gaussian filter to reduce noise  */
+    gaussian_blur(ctx, inlink->w, inlink->h,
+                  tmpbuf,            inlink->w,
+                  inpicref->data[0], inpicref->linesize[0]);
+
+    /* compute the 16-bits gradients and directions for the next step */
+    sobel(ctx, inlink->w, inlink->h,
+          gradients, inlink->w,
+          tmpbuf,    inlink->w);
+
+    /* non_maximum_suppression() will actually keep & clip what's necessary and
+     * ignore the rest, so we need a clean output buffer */
+    memset(tmpbuf, 0, inlink->w * inlink->h);
+    non_maximum_suppression(ctx, inlink->w, inlink->h,
+                            tmpbuf,    inlink->w,
+                            gradients, inlink->w);
+
+    /* keep high values, or low values surrounded by high values */
+    double_threshold(ctx, inlink->w, inlink->h,
+                     outpicref->data[0], outpicref->linesize[0],
+                     tmpbuf,             inlink->w);
+
+    ff_draw_slice(outlink, 0, outlink->h, 1);
+    return ff_end_frame(outlink);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    EdgeDetectContext *edgedetect = ctx->priv;
+    av_freep(&edgedetect->tmpbuf);
+    av_freep(&edgedetect->gradients);
+    av_freep(&edgedetect->directions);
+}
+
+static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { return 0; }
+
+AVFilter avfilter_vf_edgedetect = {
+    .name          = "edgedetect",
+    .description   = NULL_IF_CONFIG_SMALL("Detect and draw edge."),
+    .priv_size     = sizeof(EdgeDetectContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+
+    .inputs    = (const AVFilterPad[]) {
+       {
+           .name             = "default",
+           .type             = AVMEDIA_TYPE_VIDEO,
+           .draw_slice       = null_draw_slice,
+           .config_props     = config_props,
+           .end_frame        = end_frame,
+           .min_perms        = AV_PERM_READ
+        },
+        { .name = NULL }
+    },
+    .outputs   = (const AVFilterPad[]) {
+        {
+            .name            = "default",
+            .type            = AVMEDIA_TYPE_VIDEO,
+        },
+        { .name = NULL }
+    },
+};
diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c
index 8555798..f1e7c6e 100644
--- a/libavfilter/vf_fade.c
+++ b/libavfilter/vf_fade.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2010 Brandon Mintern
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,50 +25,123 @@
  * based heavily on vf_negate.c by Bobby Bingham
  */
 
+#include "libavutil/avstring.h"
 #include "libavutil/common.h"
+#include "libavutil/eval.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
+#include "drawutils.h"
+#include "internal.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
 
+#define R 0
+#define G 1
+#define B 2
+#define A 3
+
+#define Y 0
+#define U 1
+#define V 2
+
 typedef struct {
+    const AVClass *class;
     int factor, fade_per_frame;
-    unsigned int frame_index, start_frame, stop_frame;
+    unsigned int frame_index, start_frame, stop_frame, nb_frames;
     int hsub, vsub, bpp;
+    unsigned int black_level, black_level_scaled;
+    uint8_t is_packed_rgb;
+    uint8_t rgba_map[4];
+    int alpha;
+
+    char *type;
 } FadeContext;
 
+#define OFFSET(x) offsetof(FadeContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption fade_options[] = {
+    { "type",        "set the fade direction",                     OFFSET(type),        AV_OPT_TYPE_STRING, {.str = "in" }, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "t",           "set the fade direction",                     OFFSET(type),        AV_OPT_TYPE_STRING, {.str = "in" }, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "start_frame", "set expression of frame to start fading",    OFFSET(start_frame), AV_OPT_TYPE_INT, {.i64 = 0    }, 0, INT_MAX, FLAGS },
+    { "s",           "set expression of frame to start fading",    OFFSET(start_frame), AV_OPT_TYPE_INT, {.i64 = 0    }, 0, INT_MAX, FLAGS },
+    { "nb_frames",   "set expression for fade duration in frames", OFFSET(nb_frames),   AV_OPT_TYPE_INT, {.i64 = 25   }, 0, INT_MAX, FLAGS },
+    { "n",           "set expression for fade duration in frames", OFFSET(nb_frames),   AV_OPT_TYPE_INT, {.i64 = 25   }, 0, INT_MAX, FLAGS },
+    { "alpha",       "fade alpha if it is available on the input", OFFSET(alpha),       AV_OPT_TYPE_INT, {.i64 = 0    }, 0,       1, FLAGS },
+    {NULL},
+};
+
+AVFILTER_DEFINE_CLASS(fade);
+
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     FadeContext *fade = ctx->priv;
-    unsigned int nb_frames;
-    char in_out[4];
+    int ret = 0;
+    char *args1, *expr, *bufptr = NULL;
 
-    if (!args ||
-        sscanf(args, " %3[^:]:%u:%u", in_out, &fade->start_frame, &nb_frames) != 3) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Expected 3 arguments '(in|out):#:#':'%s'\n", args);
-        return AVERROR(EINVAL);
+    fade->class = &fade_class;
+    av_opt_set_defaults(fade);
+
+    if (!(args1 = av_strdup(args))) {
+        ret = AVERROR(ENOMEM);
+        goto end;
     }
 
-    nb_frames = nb_frames ? nb_frames : 1;
-    fade->fade_per_frame = (1 << 16) / nb_frames;
-    if (!strcmp(in_out, "in"))
+    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;
+
+    fade->fade_per_frame = (1 << 16) / fade->nb_frames;
+    if (!strcmp(fade->type, "in"))
         fade->factor = 0;
-    else if (!strcmp(in_out, "out")) {
+    else if (!strcmp(fade->type, "out")) {
         fade->fade_per_frame = -fade->fade_per_frame;
         fade->factor = (1 << 16);
     } else {
         av_log(ctx, AV_LOG_ERROR,
-               "first argument must be 'in' or 'out':'%s'\n", in_out);
-        return AVERROR(EINVAL);
+               "Type argument must be 'in' or 'out' but '%s' was specified\n", fade->type);
+        ret = AVERROR(EINVAL);
+        goto end;
     }
-    fade->stop_frame = fade->start_frame + nb_frames;
+    fade->stop_frame = fade->start_frame + fade->nb_frames;
 
     av_log(ctx, AV_LOG_VERBOSE,
-           "type:%s start_frame:%d nb_frames:%d\n",
-           in_out, fade->start_frame, nb_frames);
-    return 0;
+           "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;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    FadeContext *fade = ctx->priv;
+
+    av_freep(&fade->type);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -78,7 +151,10 @@
         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_RGB24,    AV_PIX_FMT_BGR24,
+        AV_PIX_FMT_ARGB,     AV_PIX_FMT_ABGR,
+        AV_PIX_FMT_RGBA,     AV_PIX_FMT_BGRA,
         AV_PIX_FMT_NONE
     };
 
@@ -86,6 +162,20 @@
     return 0;
 }
 
+const static enum AVPixelFormat studio_level_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_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;
@@ -95,9 +185,37 @@
     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->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 */
+    fade->black_level =
+            ff_fmt_is_in(inlink->format, studio_level_pix_fmts) && !fade->alpha ? 16 : 0;
+    /* 32768 = 1 << 15, it is an integer representation
+     * of 0.5 and is for rounding. */
+    fade->black_level_scaled = (fade->black_level << 16) + 32768;
     return 0;
 }
 
+static void fade_plane(int y, int h, int w,
+                       int fade_factor, int black_level, int black_level_scaled,
+                       uint8_t offset, uint8_t step, int bytes_per_plane,
+                       uint8_t *data, int line_size)
+{
+    uint8_t *p;
+    int i, j;
+
+    /* luma, alpha or rgb plane */
+    for (i = 0; i < h; i++) {
+        p = data + offset + (y+i) * line_size;
+        for (j = 0; j < w * bytes_per_plane; j++) {
+            /* fade->factor is using 16 lower-order bits for decimal places. */
+            *p = ((*p - black_level) * fade_factor + black_level_scaled) >> 16;
+            p+=step;
+        }
+    }
+}
+
 static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
 {
     FadeContext *fade = inlink->dst->priv;
@@ -106,29 +224,33 @@
     int i, j, plane;
 
     if (fade->factor < UINT16_MAX) {
-        /* luma or rgb plane */
-        for (i = 0; i < h; i++) {
-            p = outpic->data[0] + (y+i) * outpic->linesize[0];
-            for (j = 0; j < inlink->w * fade->bpp; j++) {
-                /* fade->factor is using 16 lower-order bits for decimal
-                 * places. 32768 = 1 << 15, it is an integer representation
-                 * of 0.5 and is for rounding. */
-                *p = (*p * fade->factor + 32768) >> 16;
-                p++;
-            }
-        }
-
-        if (outpic->data[1] && outpic->data[2]) {
-            /* chroma planes */
-            for (plane = 1; plane < 3; plane++) {
-                for (i = 0; i < h; i++) {
-                    p = outpic->data[plane] + ((y+i) >> fade->vsub) * outpic->linesize[plane];
-                    for (j = 0; j < inlink->w >> fade->hsub; j++) {
-                        /* 8421367 = ((128 << 1) + 1) << 15. It is an integer
-                         * representation of 128.5. The .5 is for rounding
-                         * purposes. */
-                        *p = ((*p - 128) * fade->factor + 8421367) >> 16;
-                        p++;
+        if (fade->alpha) {
+            // alpha only
+            plane = fade->is_packed_rgb ? 0 : A; // alpha is on plane 0 for packed formats
+                                                 // or plane 3 for planar formats
+            fade_plane(y, h, inlink->w,
+                       fade->factor, fade->black_level, fade->black_level_scaled,
+                       fade->is_packed_rgb ? fade->rgba_map[A] : 0, // alpha offset for packed formats
+                       fade->is_packed_rgb ? 4 : 1,                 // pixstep for 8 bit packed formats
+                       1, outpic->data[plane], outpic->linesize[plane]);
+        } else {
+            /* luma or rgb plane */
+            fade_plane(y, h, inlink->w,
+                       fade->factor, fade->black_level, fade->black_level_scaled,
+                       0, 1, // offset & pixstep for Y plane or RGB packed format
+                       fade->bpp, outpic->data[0], outpic->linesize[0]);
+            if (outpic->data[1] && outpic->data[2]) {
+                /* chroma planes */
+                for (plane = 1; plane < 3; plane++) {
+                    for (i = 0; i < h; i++) {
+                        p = outpic->data[plane] + ((y+i) >> fade->vsub) * outpic->linesize[plane];
+                        for (j = 0; j < inlink->w >> fade->hsub; j++) {
+                            /* 8421367 = ((128 << 1) + 1) << 15. It is an integer
+                             * representation of 128.5. The .5 is for rounding
+                             * purposes. */
+                            *p = ((*p - 128) * fade->factor + 8421367) >> 16;
+                            p++;
+                        }
                     }
                 }
             }
@@ -164,7 +286,6 @@
         .draw_slice       = draw_slice,
         .end_frame        = end_frame,
         .min_perms        = AV_PERM_READ | AV_PERM_WRITE,
-        .rej_perms        = AV_PERM_PRESERVE,
     },
     { NULL }
 };
@@ -179,11 +300,13 @@
 
 AVFilter avfilter_vf_fade = {
     .name          = "fade",
-    .description   = NULL_IF_CONFIG_SMALL("Fade in/out input video"),
+    .description   = NULL_IF_CONFIG_SMALL("Fade in/out input video."),
     .init          = init,
+    .uninit        = uninit,
     .priv_size     = sizeof(FadeContext),
     .query_formats = query_formats,
 
     .inputs    = avfilter_vf_fade_inputs,
     .outputs   = avfilter_vf_fade_outputs,
+    .priv_class = &fade_class,
 };
diff --git a/libavfilter/vf_fieldorder.c b/libavfilter/vf_fieldorder.c
index 5e084ac..cc47e5b 100644
--- a/libavfilter/vf_fieldorder.c
+++ b/libavfilter/vf_fieldorder.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2011 Mark Himsley
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -244,8 +244,7 @@
         .get_video_buffer = get_video_buffer,
         .draw_slice       = draw_slice,
         .end_frame        = end_frame,
-        .min_perms        = AV_PERM_READ,
-        .rej_perms        = AV_PERM_REUSE2 | AV_PERM_PRESERVE,
+        .min_perms        = AV_PERM_READ | AV_PERM_PRESERVE,
     },
     { NULL }
 };
diff --git a/libavfilter/vf_format.c b/libavfilter/vf_format.c
index 72d6348..e33c25e 100644
--- a/libavfilter/vf_format.c
+++ b/libavfilter/vf_format.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,6 +29,7 @@
 #include "libavutil/mem.h"
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
+#include "internal.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
@@ -48,7 +49,7 @@
     FormatContext *format = ctx->priv;
     const char *cur, *sep;
     char             pix_fmt_name[AV_PIX_FMT_NAME_MAXSIZE];
-    int              pix_fmt_name_len;
+    int              pix_fmt_name_len, ret;
     enum AVPixelFormat pix_fmt;
 
     /* parse the list of formats */
@@ -64,12 +65,9 @@
 
         memcpy(pix_fmt_name, cur, pix_fmt_name_len);
         pix_fmt_name[pix_fmt_name_len] = 0;
-        pix_fmt = av_get_pix_fmt(pix_fmt_name);
 
-        if (pix_fmt == AV_PIX_FMT_NONE) {
-            av_log(ctx, AV_LOG_ERROR, "Unknown pixel format: %s\n", pix_fmt_name);
-            return -1;
-        }
+        if ((ret = ff_parse_pixel_format(&pix_fmt, pix_fmt_name, ctx)) < 0)
+            return ret;
 
         format->listed_pix_fmt_flags[pix_fmt] = 1;
     }
diff --git a/libavfilter/vf_fps.c b/libavfilter/vf_fps.c
index 45b8225..114b062 100644
--- a/libavfilter/vf_fps.c
+++ b/libavfilter/vf_fps.c
@@ -1,18 +1,22 @@
 /*
- * This file is part of Libav.
+ * Copyright 2007 Bobby Bingham
+ * Copyright 2012 Robert Nagy <ronag89 gmail com>
+ * Copyright 2012 Anton Khirnov <anton khirnov net>
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -52,24 +56,20 @@
 
 #define OFFSET(x) offsetof(FPSContext, x)
 #define V AV_OPT_FLAG_VIDEO_PARAM
-static const AVOption options[] = {
-    { "fps", "A string describing desired output framerate", OFFSET(fps), AV_OPT_TYPE_STRING, { .str = "25" }, .flags = V },
+#define F AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption fps_options[] = {
+    { "fps", "A string describing desired output framerate", OFFSET(fps), AV_OPT_TYPE_STRING, { .str = "25" }, .flags = V|F },
     { NULL },
 };
 
-static const AVClass class = {
-    .class_name = "FPS filter",
-    .item_name  = av_default_item_name,
-    .option     = options,
-    .version    = LIBAVUTIL_VERSION_INT,
-};
+AVFILTER_DEFINE_CLASS(fps);
 
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     FPSContext *s = ctx->priv;
     int ret;
 
-    s->class = &class;
+    s->class = &fps_class;
     av_opt_set_defaults(s);
 
     if ((ret = av_set_options_string(s, args, "=", ":")) < 0) {
@@ -116,7 +116,8 @@
 {
     FPSContext   *s = link->src->priv;
 
-    link->time_base = (AVRational){ s->framerate.den, s->framerate.num };
+    link->time_base = av_inv_q(s->framerate);
+    link->frame_rate= s->framerate;
     link->w         = link->src->inputs[0]->w;
     link->h         = link->src->inputs[0]->h;
     s->pts          = AV_NOPTS_VALUE;
@@ -231,7 +232,7 @@
 
         /* duplicate the frame if needed */
         if (!av_fifo_size(s->fifo) && i < delta - 1) {
-            AVFilterBufferRef *dup = avfilter_ref_buffer(buf_out, AV_PERM_READ);
+            AVFilterBufferRef *dup = avfilter_ref_buffer(buf_out, ~0);
 
             av_log(ctx, AV_LOG_DEBUG, "Duplicating frame.\n");
             if (dup)
@@ -282,6 +283,7 @@
     {
         .name        = "default",
         .type        = AVMEDIA_TYPE_VIDEO,
+        .min_perms   = AV_PERM_READ | AV_PERM_PRESERVE,
         .start_frame = null_start_frame,
         .draw_slice  = null_draw_slice,
         .end_frame   = end_frame,
@@ -293,6 +295,7 @@
     {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
+        .rej_perms     = AV_PERM_WRITE,
         .request_frame = request_frame,
         .config_props  = config_props
     },
@@ -310,4 +313,5 @@
 
     .inputs    = avfilter_vf_fps_inputs,
     .outputs   = avfilter_vf_fps_outputs,
+    .priv_class = &fps_class,
 };
diff --git a/libavfilter/vf_framestep.c b/libavfilter/vf_framestep.c
new file mode 100644
index 0000000..dcb2665
--- /dev/null
+++ b/libavfilter/vf_framestep.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2012 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 framestep filter, inspired on libmpcodecs/vf_framestep.c by
+ * Daniele Fornighieri <guru AT digitalfantasy it>.
+ */
+
+#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
+
+typedef struct {
+    int frame_step, frame_count, frame_selected;
+} FrameStepContext;
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    FrameStepContext *framestep = ctx->priv;
+    char *tailptr;
+    long int n = 1;
+
+    if (args) {
+        n = strtol(args, &tailptr, 10);
+        if (*tailptr || n <= 0 || n >= INT_MAX) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "Invalid argument '%s', must be a positive integer <= INT_MAX\n", args);
+            return AVERROR(EINVAL);
+        }
+    }
+
+    framestep->frame_step = n;
+    return 0;
+}
+
+static int config_output_props(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    FrameStepContext *framestep = ctx->priv;
+    AVFilterLink *inlink = ctx->inputs[0];
+
+    outlink->frame_rate =
+        av_div_q(inlink->frame_rate, (AVRational){framestep->frame_step, 1});
+
+    av_log(ctx, AV_LOG_VERBOSE, "step:%d frame_rate:%d/%d(%f) -> frame_rate:%d/%d(%f)\n",
+           framestep->frame_step,
+           inlink->frame_rate.num, inlink->frame_rate.den, av_q2d(inlink->frame_rate),
+           outlink->frame_rate.num, outlink->frame_rate.den, av_q2d(outlink->frame_rate));
+    return 0;
+}
+
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *ref)
+{
+    FrameStepContext *framestep = inlink->dst->priv;
+
+    framestep->frame_selected = 0;
+    if (!(framestep->frame_count++ % framestep->frame_step)) {
+        inlink->cur_buf = NULL;
+        framestep->frame_selected = 1;
+        return ff_start_frame(inlink->dst->outputs[0], ref);
+    }
+    return 0;
+}
+
+static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
+{
+    FrameStepContext *framestep = inlink->dst->priv;
+
+    if (framestep->frame_selected)
+        return ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
+    return 0;
+}
+
+static int end_frame(AVFilterLink *inlink)
+{
+    FrameStepContext *framestep = inlink->dst->priv;
+
+    if (framestep->frame_selected)
+        return ff_end_frame(inlink->dst->outputs[0]);
+    return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    FrameStepContext *framestep = outlink->src->priv;
+    AVFilterLink *inlink = outlink->src->inputs[0];
+    int ret;
+
+    framestep->frame_selected = 0;
+    do {
+        ret = ff_request_frame(inlink);
+    } while (!framestep->frame_selected && ret >= 0);
+
+    return ret;
+}
+
+AVFilter avfilter_vf_framestep = {
+    .name      = "framestep",
+    .description = NULL_IF_CONFIG_SMALL("Select one frame every N frames."),
+    .init      = init,
+    .priv_size = sizeof(FrameStepContext),
+
+    .inputs = (const AVFilterPad[]) {
+        {
+            .name             = "default",
+            .type             = AVMEDIA_TYPE_VIDEO,
+            .get_video_buffer = ff_null_get_video_buffer,
+            .start_frame      = start_frame,
+            .draw_slice       = draw_slice,
+            .end_frame        = end_frame,
+        },
+        { .name = NULL }
+    },
+    .outputs = (const AVFilterPad[]) {
+        {
+            .name             = "default",
+            .type             = AVMEDIA_TYPE_VIDEO,
+            .config_props     = config_output_props,
+            .request_frame    = request_frame,
+        },
+        { .name = NULL }
+    },
+};
diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c
index 471e6fc..119e7f3 100644
--- a/libavfilter/vf_frei0r.c
+++ b/libavfilter/vf_frei0r.c
@@ -1,19 +1,19 @@
 /*
  * Copyright (c) 2010 Stefano Sabatini
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -225,7 +225,7 @@
     /* see: http://piksel.org/frei0r/1.2/spec/1.2/spec/group__pluglocations.html */
     if ((path = av_strdup(getenv("FREI0R_PATH")))) {
         char *p, *ptr = NULL;
-        for (p = path; p = strtok_r(p, ":", &ptr); p = NULL)
+        for (p = path; p = av_strtok(p, ":", &ptr); p = NULL)
             if (frei0r->dl_handle = load_path(ctx, p, dl_name))
                 break;
         av_free(path);
@@ -256,7 +256,7 @@
         return AVERROR(EINVAL);
 
     if (f0r_init() < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Could not init the frei0r module");
+        av_log(ctx, AV_LOG_ERROR, "Could not init the frei0r module\n");
         return AVERROR(EINVAL);
     }
 
@@ -316,7 +316,7 @@
     Frei0rContext *frei0r = ctx->priv;
 
     if (!(frei0r->instance = frei0r->construct(inlink->w, inlink->h))) {
-        av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance");
+        av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance\n");
         return AVERROR(EINVAL);
     }
 
@@ -422,8 +422,7 @@
         return AVERROR(EINVAL);
     }
 
-    if (av_parse_video_rate(&frame_rate_q, frame_rate) < 0 ||
-        frame_rate_q.den <= 0 || frame_rate_q.num <= 0) {
+    if (av_parse_video_rate(&frame_rate_q, frame_rate) < 0) {
         av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", frame_rate);
         return AVERROR(EINVAL);
     }
@@ -443,9 +442,10 @@
     outlink->w = frei0r->w;
     outlink->h = frei0r->h;
     outlink->time_base = frei0r->time_base;
+    outlink->sample_aspect_ratio = (AVRational){1,1};
 
     if (!(frei0r->instance = frei0r->construct(outlink->w, outlink->h))) {
-        av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance");
+        av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance\n");
         return AVERROR(EINVAL);
     }
 
@@ -462,7 +462,7 @@
     if (!picref)
         return AVERROR(ENOMEM);
 
-    picref->video->pixel_aspect = (AVRational) {1, 1};
+    picref->video->sample_aspect_ratio = (AVRational) {1, 1};
     picref->pts = frei0r->pts++;
     picref->pos = -1;
 
diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c
index 2ee8b5d..3f8b221 100644
--- a/libavfilter/vf_gradfun.c
+++ b/libavfilter/vf_gradfun.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2010 Nolan Lum <nol888@gmail.com>
  * Copyright (c) 2009 Loren Merritt <lorenm@u.washignton.edu>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -53,7 +53,7 @@
     {0x54,0x34,0x4C,0x2C,0x52,0x32,0x4A,0x2A},
 };
 
-void ff_gradfun_filter_line_c(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers)
+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) {
@@ -67,7 +67,7 @@
     }
 }
 
-void ff_gradfun_blur_line_c(uint16_t *dc, uint16_t *buf, uint16_t *buf1, uint8_t *src, int src_linesize, int width)
+void ff_gradfun_blur_line_c(uint16_t *dc, uint16_t *buf, const uint16_t *buf1, const uint8_t *src, int src_linesize, int width)
 {
     int x, v, old;
     for (x = 0; x < width; x++) {
@@ -78,7 +78,7 @@
     }
 }
 
-static void filter(GradFunContext *ctx, uint8_t *dst, uint8_t *src, int width, int height, int dst_linesize, int src_linesize, int r)
+static void filter(GradFunContext *ctx, uint8_t *dst, const uint8_t *src, int width, int height, int dst_linesize, int src_linesize, int r)
 {
     int bstride = FFALIGN(width, 16) / 2;
     int y;
diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c
index 3ae0fc6..70bf5c9 100644
--- a/libavfilter/vf_hflip.c
+++ b/libavfilter/vf_hflip.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2007 Benoit Fouet
  * Copyright (c) 2010 Stefano Sabatini
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -50,8 +50,10 @@
         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,
@@ -84,6 +86,21 @@
     return 0;
 }
 
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+{
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+
+    outlink->out_buf =
+        ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+    avfilter_copy_buffer_ref_props(outlink->out_buf, picref);
+
+    /* copy palette if required */
+    if (av_pix_fmt_descriptors[inlink->format].flags & PIX_FMT_PAL)
+        memcpy(inlink->dst->outputs[0]->out_buf->data[1], picref->data[1], AVPALETTE_SIZE);
+
+    return ff_start_frame(outlink, avfilter_ref_buffer(outlink->out_buf, ~0));
+}
+
 static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
 {
     FlipContext *flip = inlink->dst->priv;
@@ -152,6 +169,7 @@
     {
         .name         = "default",
         .type         = AVMEDIA_TYPE_VIDEO,
+        .start_frame  = start_frame,
         .draw_slice   = draw_slice,
         .config_props = config_props,
         .min_perms    = AV_PERM_READ,
diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c
index 4ed8905..f7311df 100644
--- a/libavfilter/vf_hqdn3d.c
+++ b/libavfilter/vf_hqdn3d.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2010 Baptiste Coudurier
  * Copyright (c) 2012 Loren Merritt
  *
- * This file is part of Libav, ported from MPlayer.
+ * This file is part of FFmpeg, ported from MPlayer.
  *
- * Libav is free software; you can redistribute it and/or modify
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License along
- * with Libav; if not, write to the Free Software Foundation, Inc.,
+ * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
@@ -50,10 +50,9 @@
 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);
 
 #define LUT_BITS (depth==16 ? 8 : 4)
-#define RIGHTSHIFT(a,b) (((a)+(((1<<(b))-1)>>1))>>(b))
-#define LOAD(x) ((depth==8 ? src[x] : AV_RN16A(src+(x)*2)) << (16-depth))
-#define STORE(x,val) (depth==8 ? dst[x] = RIGHTSHIFT(val, 16-depth)\
-                    : AV_WN16A(dst+(x)*2, RIGHTSHIFT(val, 16-depth)))
+#define LOAD(x) (((depth==8 ? src[x] : AV_RN16A(src+(x)*2)) << (16-depth)) + (((1<<(16-depth))-1)>>1))
+#define STORE(x,val) (depth==8 ? dst[x] = (val) >> (16-depth)\
+                    : AV_WN16A(dst+(x)*2, (val) >> (16-depth)))
 
 av_always_inline
 static uint32_t lowpass(int prev, int cur, int16_t *coef, int depth)
diff --git a/libavfilter/vf_hue.c b/libavfilter/vf_hue.c
new file mode 100644
index 0000000..71d5cc8
--- /dev/null
+++ b/libavfilter/vf_hue.c
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2003 Michael Niedermayer
+ * Copyright (c) 2012 Jeremy Tran
+ *
+ * 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
+ * Apply a hue/saturation filter to the input video
+ * Ported from MPlayer libmpcodecs/vf_hue.c.
+ */
+
+#include <float.h>
+#include "libavutil/eval.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+#define HUE_DEFAULT_VAL 0
+#define SAT_DEFAULT_VAL 1
+
+#define HUE_DEFAULT_VAL_STRING AV_STRINGIFY(HUE_DEFAULT_VAL)
+#define SAT_DEFAULT_VAL_STRING AV_STRINGIFY(SAT_DEFAULT_VAL)
+
+#define SAT_MIN_VAL -10
+#define SAT_MAX_VAL 10
+
+static const char *const var_names[] = {
+    "n",   // frame count
+    "pts", // presentation timestamp expressed in AV_TIME_BASE units
+    "r",   // frame rate
+    "t",   // timestamp expressed in seconds
+    "tb",  // timebase
+    NULL
+};
+
+enum var_name {
+    VAR_N,
+    VAR_PTS,
+    VAR_R,
+    VAR_T,
+    VAR_TB,
+    VAR_NB
+};
+
+typedef struct {
+    const    AVClass *class;
+    float    hue_deg; /* hue expressed in degrees */
+    float    hue; /* hue expressed in radians */
+    char     *hue_deg_expr;
+    char     *hue_expr;
+    AVExpr   *hue_deg_pexpr;
+    AVExpr   *hue_pexpr;
+    float    saturation;
+    char     *saturation_expr;
+    AVExpr   *saturation_pexpr;
+    int      hsub;
+    int      vsub;
+    int32_t hue_sin;
+    int32_t hue_cos;
+    int      flat_syntax;
+    double   var_values[VAR_NB];
+} HueContext;
+
+#define OFFSET(x) offsetof(HueContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption hue_options[] = {
+    { "h", "set the hue angle degrees expression", OFFSET(hue_deg_expr), AV_OPT_TYPE_STRING,
+      { .str = NULL }, .flags = FLAGS },
+    { "H", "set the hue angle radians expression", OFFSET(hue_expr), AV_OPT_TYPE_STRING,
+      { .str = NULL }, .flags = FLAGS },
+    { "s", "set the saturation expression", OFFSET(saturation_expr), AV_OPT_TYPE_STRING,
+      { .str = NULL }, .flags = FLAGS },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(hue);
+
+static inline void compute_sin_and_cos(HueContext *hue)
+{
+    /*
+     * Scale the value to the norm of the resulting (U,V) vector, that is
+     * the saturation.
+     * This will be useful in the process_chrominance function.
+     */
+    hue->hue_sin = rint(sin(hue->hue) * (1 << 16) * hue->saturation);
+    hue->hue_cos = rint(cos(hue->hue) * (1 << 16) * hue->saturation);
+}
+
+#define SET_EXPRESSION(attr, name) do {                                           \
+    if (hue->attr##_expr) {                                                       \
+        if ((ret = av_expr_parse(&hue->attr##_pexpr, hue->attr##_expr, var_names, \
+                                 NULL, NULL, NULL, NULL, 0, ctx)) < 0) {          \
+            av_log(ctx, AV_LOG_ERROR,                                             \
+                   "Parsing failed for expression " #name "='%s'",                \
+                   hue->attr##_expr);                                             \
+            hue->attr##_expr  = old_##attr##_expr;                                \
+            hue->attr##_pexpr = old_##attr##_pexpr;                               \
+            return AVERROR(EINVAL);                                               \
+        } else if (old_##attr##_pexpr) {                                          \
+            av_freep(&old_##attr##_expr);                                         \
+            av_expr_free(old_##attr##_pexpr);                                     \
+            old_##attr##_pexpr = NULL;                                            \
+        }                                                                         \
+    } else {                                                                      \
+        hue->attr##_expr = old_##attr##_expr;                                     \
+    }                                                                             \
+} while (0)
+
+static inline int set_options(AVFilterContext *ctx, const char *args)
+{
+    HueContext *hue = ctx->priv;
+    int n, ret;
+    char c1 = 0, c2 = 0;
+    char   *old_hue_expr,  *old_hue_deg_expr,  *old_saturation_expr;
+    AVExpr *old_hue_pexpr, *old_hue_deg_pexpr, *old_saturation_pexpr;
+
+    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;
+
+            hue->hue_expr     = NULL;
+            hue->hue_deg_expr = NULL;
+            hue->saturation_expr = NULL;
+
+            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);
+        }
+    }
+
+    compute_sin_and_cos(hue);
+
+    return 0;
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    HueContext *hue = ctx->priv;
+
+    hue->class = &hue_class;
+    av_opt_set_defaults(hue);
+
+    hue->saturation    = SAT_DEFAULT_VAL;
+    hue->hue           = HUE_DEFAULT_VAL;
+    hue->hue_deg_pexpr = NULL;
+    hue->hue_pexpr     = NULL;
+    hue->flat_syntax   = 1;
+
+    return set_options(ctx, args);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    HueContext *hue = ctx->priv;
+
+    av_opt_free(hue);
+
+    av_free(hue->hue_deg_expr);
+    av_expr_free(hue->hue_deg_pexpr);
+    av_free(hue->hue_expr);
+    av_expr_free(hue->hue_pexpr);
+    av_free(hue->saturation_expr);
+    av_expr_free(hue->saturation_pexpr);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_YUV444P,      AV_PIX_FMT_YUV422P,
+        AV_PIX_FMT_YUV420P,      AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_YUV410P,      AV_PIX_FMT_YUV440P,
+        AV_PIX_FMT_YUVA420P,
+        AV_PIX_FMT_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+
+    return 0;
+}
+
+static int config_props(AVFilterLink *inlink)
+{
+    HueContext *hue = inlink->dst->priv;
+    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[inlink->format];
+
+    hue->hsub = desc->log2_chroma_w;
+    hue->vsub = desc->log2_chroma_h;
+
+    hue->var_values[VAR_N]  = 0;
+    hue->var_values[VAR_TB] = av_q2d(inlink->time_base);
+    hue->var_values[VAR_R]  = inlink->frame_rate.num == 0 || inlink->frame_rate.den == 0 ?
+        NAN : av_q2d(inlink->frame_rate);
+
+    return 0;
+}
+
+static void process_chrominance(uint8_t *udst, uint8_t *vdst, const int dst_linesize,
+                                uint8_t *usrc, uint8_t *vsrc, const int src_linesize,
+                                int w, int h,
+                                const int32_t c, const int32_t s)
+{
+    int32_t u, v, new_u, new_v;
+    int i;
+
+    /*
+     * If we consider U and V as the components of a 2D vector then its angle
+     * is the hue and the norm is the saturation
+     */
+    while (h--) {
+        for (i = 0; i < w; i++) {
+            /* Normalize the components from range [16;140] to [-112;112] */
+            u = usrc[i] - 128;
+            v = vsrc[i] - 128;
+            /*
+             * Apply the rotation of the vector : (c * u) - (s * v)
+             *                                    (s * u) + (c * v)
+             * De-normalize the components (without forgetting to scale 128
+             * by << 16)
+             * Finally scale back the result by >> 16
+             */
+            new_u = ((c * u) - (s * v) + (1 << 15) + (128 << 16)) >> 16;
+            new_v = ((s * u) + (c * v) + (1 << 15) + (128 << 16)) >> 16;
+
+            /* Prevent a potential overflow */
+            udst[i] = av_clip_uint8_c(new_u);
+            vdst[i] = av_clip_uint8_c(new_v);
+        }
+
+        usrc += src_linesize;
+        vsrc += src_linesize;
+        udst += dst_linesize;
+        vdst += dst_linesize;
+    }
+}
+
+#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
+#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb))
+
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpic)
+{
+    HueContext *hue = inlink->dst->priv;
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    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, inpic);
+    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);
+
+    if (!hue->flat_syntax) {
+        hue->var_values[VAR_T]   = TS2T(inpic->pts, inlink->time_base);
+        hue->var_values[VAR_PTS] = TS2D(inpic->pts);
+
+        if (hue->saturation_expr) {
+            hue->saturation = av_expr_eval(hue->saturation_pexpr, hue->var_values, NULL);
+
+            if (hue->saturation < SAT_MIN_VAL || hue->saturation > SAT_MAX_VAL) {
+                hue->saturation = av_clip(hue->saturation, SAT_MIN_VAL, SAT_MAX_VAL);
+                av_log(inlink->dst, AV_LOG_WARNING,
+                       "Saturation value not in range [%d,%d]: clipping value to %0.1f\n",
+                       SAT_MIN_VAL, SAT_MAX_VAL, hue->saturation);
+            }
+        }
+
+        if (hue->hue_deg_expr) {
+            hue->hue_deg = av_expr_eval(hue->hue_deg_pexpr, hue->var_values, NULL);
+            hue->hue = hue->hue_deg * M_PI / 180;
+        } else if (hue->hue_expr) {
+            hue->hue = av_expr_eval(hue->hue_pexpr, hue->var_values, NULL);
+        }
+
+        av_log(inlink->dst, AV_LOG_DEBUG,
+               "H:%0.1f s:%0.f t:%0.1f n:%d\n",
+               hue->hue, hue->saturation,
+               hue->var_values[VAR_T], (int)hue->var_values[VAR_N]);
+
+        compute_sin_and_cos(hue);
+    }
+
+    hue->var_values[VAR_N] += 1;
+
+    return ff_start_frame(outlink, buf_out);
+}
+
+static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
+{
+    HueContext        *hue    = inlink->dst->priv;
+    AVFilterBufferRef *inpic  = inlink->cur_buf;
+    AVFilterBufferRef *outpic = inlink->dst->outputs[0]->out_buf;
+    uint8_t *inrow[3], *outrow[3]; // 0 : Y, 1 : U, 2 : V
+    int plane;
+
+    inrow[0]  = inpic->data[0]  + y * inpic->linesize[0];
+    outrow[0] = outpic->data[0] + y * outpic->linesize[0];
+
+    for (plane = 1; plane < 3; plane++) {
+        inrow[plane]  = inpic->data[plane]  + (y >> hue->vsub) * inpic->linesize[plane];
+        outrow[plane] = outpic->data[plane] + (y >> hue->vsub) * outpic->linesize[plane];
+    }
+
+    av_image_copy_plane(outrow[0], outpic->linesize[0],
+                        inrow[0],  inpic->linesize[0],
+                        inlink->w, inlink->h);
+
+    process_chrominance(outrow[1], outrow[2], outpic->linesize[1],
+                        inrow[1], inrow[2], inpic->linesize[1],
+                        inlink->w >> hue->hsub, inlink->h >> hue->vsub,
+                        hue->hue_cos, hue->hue_sin);
+
+    return ff_draw_slice(inlink->dst->outputs[0], y, h, slice_dir);
+}
+
+static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
+                           char *res, int res_len, int flags)
+{
+    if (!strcmp(cmd, "reinit"))
+        return set_options(ctx, args);
+    else
+        return AVERROR(ENOSYS);
+}
+
+AVFilter avfilter_vf_hue = {
+    .name        = "hue",
+    .description = NULL_IF_CONFIG_SMALL("Adjust the hue and saturation of the input video."),
+
+    .priv_size = sizeof(HueContext),
+
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .process_command = process_command,
+
+    .inputs = (const AVFilterPad[]) {
+        {
+            .name         = "default",
+            .type         = AVMEDIA_TYPE_VIDEO,
+            .start_frame  = start_frame,
+            .draw_slice   = draw_slice,
+            .config_props = config_props,
+            .min_perms    = AV_PERM_READ,
+        },
+        { .name = NULL }
+    },
+    .outputs = (const AVFilterPad[]) {
+        {
+            .name         = "default",
+            .type         = AVMEDIA_TYPE_VIDEO,
+        },
+        { .name = NULL }
+    },
+    .priv_class = &hue_class,
+};
diff --git a/libavfilter/vf_idet.c b/libavfilter/vf_idet.c
new file mode 100644
index 0000000..1e067ef
--- /dev/null
+++ b/libavfilter/vf_idet.c
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2012 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/cpu.h"
+#include "libavutil/common.h"
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+#include "internal.h"
+
+#undef NDEBUG
+#include <assert.h>
+
+#define HIST_SIZE 4
+
+typedef enum {
+    TFF,
+    BFF,
+    PROGRSSIVE,
+    UNDETERMINED,
+} Type;
+
+typedef struct {
+    float interlace_threshold;
+    float progressive_threshold;
+
+    Type last_type;
+    Type prestat[4];
+    Type poststat[4];
+
+    uint8_t history[HIST_SIZE];
+
+    AVFilterBufferRef *cur;
+    AVFilterBufferRef *next;
+    AVFilterBufferRef *prev;
+    int (*filter_line)(const uint8_t *prev, const uint8_t *cur, const uint8_t *next, int w);
+
+    const AVPixFmtDescriptor *csp;
+} IDETContext;
+
+static const char *type2str(Type type)
+{
+    switch(type) {
+        case TFF         : return "Top Field First   ";
+        case BFF         : return "Bottom Field First";
+        case PROGRSSIVE  : return "Progressive       ";
+        case UNDETERMINED: return "Undetermined      ";
+    }
+    return NULL;
+}
+
+static int filter_line_c(const uint8_t *a, const uint8_t *b, const uint8_t *c, int w)
+{
+    int x;
+    int ret=0;
+
+    for(x=0; x<w; x++){
+        ret += FFABS((*a++ + *c++) - 2 * *b++);
+    }
+
+    return ret;
+}
+
+static int filter_line_c_16bit(const uint16_t *a, const uint16_t *b, const uint16_t *c, int w)
+{
+    int x;
+    int ret=0;
+
+    for(x=0; x<w; x++){
+        ret += FFABS((*a++ + *c++) - 2 * *b++);
+    }
+
+    return ret;
+}
+
+static void filter(AVFilterContext *ctx)
+{
+    IDETContext *idet = ctx->priv;
+    int y, i;
+    int64_t alpha[2]={0};
+    int64_t delta=0;
+    Type type, best_type;
+    int match = 0;
+
+    for (i = 0; i < idet->csp->nb_components; i++) {
+        int w = idet->cur->video->w;
+        int h = idet->cur->video->h;
+        int refs = idet->cur->linesize[i];
+
+        if (i && i<3) {
+            w >>= idet->csp->log2_chroma_w;
+            h >>= idet->csp->log2_chroma_h;
+        }
+
+        for (y = 2; y < h - 2; y++) {
+            uint8_t *prev = &idet->prev->data[i][y*refs];
+            uint8_t *cur  = &idet->cur ->data[i][y*refs];
+            uint8_t *next = &idet->next->data[i][y*refs];
+            alpha[ y   &1] += idet->filter_line(cur-refs, prev, cur+refs, w);
+            alpha[(y^1)&1] += idet->filter_line(cur-refs, next, cur+refs, w);
+            delta          += idet->filter_line(cur-refs,  cur, cur+refs, w);
+        }
+    }
+
+    if      (alpha[0] / (float)alpha[1] > idet->interlace_threshold){
+        type = TFF;
+    }else if(alpha[1] / (float)alpha[0] > idet->interlace_threshold){
+        type = BFF;
+    }else if(alpha[1] / (float)delta    > idet->progressive_threshold){
+        type = PROGRSSIVE;
+    }else{
+        type = UNDETERMINED;
+    }
+
+    memmove(idet->history+1, idet->history, HIST_SIZE-1);
+    idet->history[0] = type;
+    best_type = UNDETERMINED;
+    for(i=0; i<HIST_SIZE; i++){
+        if(idet->history[i] != UNDETERMINED){
+            if(best_type == UNDETERMINED)
+                best_type = idet->history[i];
+
+            if(idet->history[i] == best_type) {
+                match++;
+            }else{
+                match=0;
+                break;
+            }
+        }
+    }
+    if(idet->last_type == UNDETERMINED){
+        if(match  ) idet->last_type = best_type;
+    }else{
+        if(match>2) idet->last_type = best_type;
+    }
+
+    if      (idet->last_type == TFF){
+        idet->cur->video->top_field_first = 1;
+        idet->cur->video->interlaced = 1;
+    }else if(idet->last_type == BFF){
+        idet->cur->video->top_field_first = 0;
+        idet->cur->video->interlaced = 1;
+    }else if(idet->last_type == PROGRSSIVE){
+        idet->cur->video->interlaced = 0;
+    }
+
+    idet->prestat [           type] ++;
+    idet->poststat[idet->last_type] ++;
+    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)
+{
+    AVFilterContext *ctx = link->dst;
+    IDETContext *idet = ctx->priv;
+
+    if (idet->prev)
+        avfilter_unref_buffer(idet->prev);
+    idet->prev = idet->cur;
+    idet->cur  = idet->next;
+    idet->next = picref;
+    link->cur_buf = NULL;
+
+    if (!idet->cur)
+        return 0;
+
+    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_descriptors[link->format];
+    if (idet->csp->comp[0].depth_minus1 / 8 == 1)
+        idet->filter_line = (void*)filter_line_c_16bit;
+
+    filter(ctx);
+
+    ff_draw_slice(ctx->outputs[0], 0, link->h, 1);
+    return ff_end_frame(ctx->outputs[0]);
+}
+
+static int request_frame(AVFilterLink *link)
+{
+    AVFilterContext *ctx = link->src;
+    IDETContext *idet = ctx->priv;
+
+    do {
+        int ret;
+
+        if ((ret = ff_request_frame(link->src->inputs[0])))
+            return ret;
+    } while (!idet->cur);
+
+    return 0;
+}
+
+static 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;
+
+    av_log(ctx, AV_LOG_INFO, "Single frame detection: TFF:%d BFF:%d Progressive:%d Undetermined:%d\n",
+           idet->prestat[TFF],
+           idet->prestat[BFF],
+           idet->prestat[PROGRSSIVE],
+           idet->prestat[UNDETERMINED]
+    );
+    av_log(ctx, AV_LOG_INFO, "Multi frame detection: TFF:%d BFF:%d Progressive:%d Undetermined:%d\n",
+           idet->poststat[TFF],
+           idet->poststat[BFF],
+           idet->poststat[PROGRSSIVE],
+           idet->poststat[UNDETERMINED]
+    );
+
+    avfilter_unref_bufferp(&idet->prev);
+    avfilter_unref_bufferp(&idet->cur );
+    avfilter_unref_bufferp(&idet->next);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    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_GRAY8,
+        AV_PIX_FMT_YUVJ420P,
+        AV_PIX_FMT_YUVJ422P,
+        AV_PIX_FMT_YUVJ444P,
+        AV_NE( AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_GRAY16LE ),
+        AV_PIX_FMT_YUV440P,
+        AV_PIX_FMT_YUVJ440P,
+        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_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 ),
+        AV_PIX_FMT_YUVA420P,
+        AV_PIX_FMT_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+
+    return 0;
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    IDETContext *idet = ctx->priv;
+
+    idet->csp = NULL;
+
+    idet->interlace_threshold   = 1.01;
+    idet->progressive_threshold = 2.5;
+
+    if (args) sscanf(args, "%f:%f", &idet->interlace_threshold, &idet->progressive_threshold);
+
+    idet->last_type = UNDETERMINED;
+    memset(idet->history, UNDETERMINED, HIST_SIZE);
+
+    idet->filter_line = filter_line_c;
+
+    return 0;
+}
+
+static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { return 0; }
+
+AVFilter avfilter_vf_idet = {
+    .name          = "idet",
+    .description   = NULL_IF_CONFIG_SMALL("Interlace detect Filter."),
+
+    .priv_size     = sizeof(IDETContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+
+    .inputs    = (const AVFilterPad[]) {{ .name       = "default",
+                                          .type             = AVMEDIA_TYPE_VIDEO,
+                                          .start_frame      = start_frame,
+                                          .draw_slice       = null_draw_slice,
+                                          .end_frame        = end_frame,
+                                          .min_perms        = AV_PERM_PRESERVE },
+                                        { .name = NULL}},
+
+    .outputs   = (const AVFilterPad[]) {{ .name       = "default",
+                                          .type             = AVMEDIA_TYPE_VIDEO,
+                                          .rej_perms        = AV_PERM_WRITE,
+                                          .poll_frame       = poll_frame,
+                                          .request_frame    = request_frame, },
+                                        { .name = NULL}},
+};
diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c
index 3e802cd..8192007 100644
--- a/libavfilter/vf_libopencv.c
+++ b/libavfilter/vf_libopencv.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Stefano Sabatini
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c
index c54d6d5..2324608 100644
--- a/libavfilter/vf_lut.c
+++ b/libavfilter/vf_lut.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2011 Stefano Sabatini
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,7 +26,6 @@
 
 #include "libavutil/common.h"
 #include "libavutil/eval.h"
-#include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "avfilter.h"
@@ -35,9 +34,6 @@
 #include "video.h"
 
 static const char *const var_names[] = {
-    "E",
-    "PHI",
-    "PI",
     "w",        ///< width of the input video
     "h",        ///< height of the input video
     "val",      ///< input value for the pixel
@@ -49,9 +45,6 @@
 };
 
 enum var_name {
-    VAR_E,
-    VAR_PHI,
-    VAR_PI,
     VAR_W,
     VAR_H,
     VAR_VAL,
@@ -70,7 +63,6 @@
     int hsub, vsub;
     double var_values[VAR_VARS_NB];
     int is_rgb, is_yuv;
-    int rgba_map[4];
     int step;
     int negate_alpha; /* only used by negate */
 } LutContext;
@@ -84,53 +76,23 @@
 #define A 3
 
 #define OFFSET(x) offsetof(LutContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 
-static const AVOption lut_options[] = {
-    {"c0", "set component #0 expression", OFFSET(comp_expr_str[0]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
-    {"c1", "set component #1 expression", OFFSET(comp_expr_str[1]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
-    {"c2", "set component #2 expression", OFFSET(comp_expr_str[2]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
-    {"c3", "set component #3 expression", OFFSET(comp_expr_str[3]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
-    {"y",  "set Y expression", OFFSET(comp_expr_str[Y]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
-    {"u",  "set U expression", OFFSET(comp_expr_str[U]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
-    {"v",  "set V expression", OFFSET(comp_expr_str[V]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
-    {"r",  "set R expression", OFFSET(comp_expr_str[R]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
-    {"g",  "set G expression", OFFSET(comp_expr_str[G]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
-    {"b",  "set B expression", OFFSET(comp_expr_str[B]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
-    {"a",  "set A expression", OFFSET(comp_expr_str[A]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX},
+static const AVOption options[] = {
+    {"c0", "set component #0 expression", OFFSET(comp_expr_str[0]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX, FLAGS},
+    {"c1", "set component #1 expression", OFFSET(comp_expr_str[1]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX, FLAGS},
+    {"c2", "set component #2 expression", OFFSET(comp_expr_str[2]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX, FLAGS},
+    {"c3", "set component #3 expression", OFFSET(comp_expr_str[3]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX, FLAGS},
+    {"y",  "set Y expression", OFFSET(comp_expr_str[Y]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX, FLAGS},
+    {"u",  "set U expression", OFFSET(comp_expr_str[U]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX, FLAGS},
+    {"v",  "set V expression", OFFSET(comp_expr_str[V]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX, FLAGS},
+    {"r",  "set R expression", OFFSET(comp_expr_str[R]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX, FLAGS},
+    {"g",  "set G expression", OFFSET(comp_expr_str[G]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX, FLAGS},
+    {"b",  "set B expression", OFFSET(comp_expr_str[B]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX, FLAGS},
+    {"a",  "set A expression", OFFSET(comp_expr_str[A]),  AV_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX, FLAGS},
     {NULL},
 };
 
-static const char *lut_get_name(void *ctx)
-{
-    return "lut";
-}
-
-static const AVClass lut_class = {
-    "LutContext",
-    lut_get_name,
-    lut_options
-};
-
-static int init(AVFilterContext *ctx, const char *args)
-{
-    LutContext *lut = ctx->priv;
-    int ret;
-
-    lut->class = &lut_class;
-    av_opt_set_defaults(lut);
-
-    lut->var_values[VAR_PHI] = M_PHI;
-    lut->var_values[VAR_PI]  = M_PI;
-    lut->var_values[VAR_E ]  = M_E;
-
-    lut->is_rgb = !strcmp(ctx->filter->name, "lutrgb");
-    lut->is_yuv = !strcmp(ctx->filter->name, "lutyuv");
-    if (args && (ret = av_set_options_string(lut, args, "=", ":")) < 0)
-        return ret;
-
-    return 0;
-}
-
 static av_cold void uninit(AVFilterContext *ctx)
 {
     LutContext *lut = ctx->priv;
@@ -155,16 +117,16 @@
     AV_PIX_FMT_ABGR,         AV_PIX_FMT_BGRA,         \
     AV_PIX_FMT_RGB24,        AV_PIX_FMT_BGR24
 
-static enum AVPixelFormat yuv_pix_fmts[] = { YUV_FORMATS, AV_PIX_FMT_NONE };
-static enum AVPixelFormat rgb_pix_fmts[] = { RGB_FORMATS, AV_PIX_FMT_NONE };
-static enum AVPixelFormat all_pix_fmts[] = { RGB_FORMATS, YUV_FORMATS, AV_PIX_FMT_NONE };
+static const enum AVPixelFormat yuv_pix_fmts[] = { YUV_FORMATS, AV_PIX_FMT_NONE };
+static const enum AVPixelFormat rgb_pix_fmts[] = { RGB_FORMATS, AV_PIX_FMT_NONE };
+static const enum AVPixelFormat all_pix_fmts[] = { RGB_FORMATS, YUV_FORMATS, AV_PIX_FMT_NONE };
 
 static int query_formats(AVFilterContext *ctx)
 {
     LutContext *lut = ctx->priv;
 
-    enum AVPixelFormat *pix_fmts = lut->is_rgb ? rgb_pix_fmts :
-                                 lut->is_yuv ? yuv_pix_fmts : all_pix_fmts;
+    const enum AVPixelFormat *pix_fmts = lut->is_rgb ? rgb_pix_fmts :
+                                       lut->is_yuv ? yuv_pix_fmts : all_pix_fmts;
 
     ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
     return 0;
@@ -197,8 +159,8 @@
 }
 
 static double (* const funcs1[])(void *, double) = {
-    clip,
-    compute_gammaval,
+    (void *)clip,
+    (void *)compute_gammaval,
     NULL
 };
 
@@ -213,6 +175,7 @@
     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 */
     int min[4], max[4];
     int val, comp, ret;
 
@@ -246,48 +209,49 @@
 
     if (lut->is_rgb) {
         switch (inlink->format) {
-        case AV_PIX_FMT_ARGB:  lut->rgba_map[A] = 0; lut->rgba_map[R] = 1; lut->rgba_map[G] = 2; lut->rgba_map[B] = 3; break;
-        case AV_PIX_FMT_ABGR:  lut->rgba_map[A] = 0; lut->rgba_map[B] = 1; lut->rgba_map[G] = 2; lut->rgba_map[R] = 3; break;
+        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: lut->rgba_map[R] = 0; lut->rgba_map[G] = 1; lut->rgba_map[B] = 2; lut->rgba_map[A] = 3; break;
+        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: lut->rgba_map[B] = 0; lut->rgba_map[G] = 1; lut->rgba_map[R] = 2; lut->rgba_map[A] = 3; break;
+        case AV_PIX_FMT_BGR24: rgba_map[0] = B; rgba_map[1] = G; rgba_map[2] = R; rgba_map[3] = A; break;
         }
         lut->step = av_get_bits_per_pixel(desc) >> 3;
     }
 
     for (comp = 0; comp < desc->nb_components; comp++) {
         double res;
+        int color = lut->is_rgb ? rgba_map[comp] : comp;
 
         /* create the parsed expression */
-        ret = av_expr_parse(&lut->comp_expr[comp], lut->comp_expr_str[comp],
+        ret = av_expr_parse(&lut->comp_expr[color], lut->comp_expr_str[color],
                             var_names, funcs1_names, funcs1, NULL, NULL, 0, ctx);
         if (ret < 0) {
             av_log(ctx, AV_LOG_ERROR,
-                   "Error when parsing the expression '%s' for the component %d.\n",
-                   lut->comp_expr_str[comp], comp);
+                   "Error when parsing the expression '%s' for the component %d and color %d.\n",
+                   lut->comp_expr_str[comp], comp, color);
             return AVERROR(EINVAL);
         }
 
         /* compute the lut */
-        lut->var_values[VAR_MAXVAL] = max[comp];
-        lut->var_values[VAR_MINVAL] = min[comp];
+        lut->var_values[VAR_MAXVAL] = max[color];
+        lut->var_values[VAR_MINVAL] = min[color];
 
         for (val = 0; val < 256; val++) {
             lut->var_values[VAR_VAL] = val;
-            lut->var_values[VAR_CLIPVAL] = av_clip(val, min[comp], max[comp]);
+            lut->var_values[VAR_CLIPVAL] = av_clip(val, min[color], max[color]);
             lut->var_values[VAR_NEGVAL] =
-                av_clip(min[comp] + max[comp] - lut->var_values[VAR_VAL],
-                        min[comp], max[comp]);
+                av_clip(min[color] + max[color] - lut->var_values[VAR_VAL],
+                        min[color], max[color]);
 
-            res = av_expr_eval(lut->comp_expr[comp], lut->var_values, lut);
+            res = av_expr_eval(lut->comp_expr[color], lut->var_values, lut);
             if (isnan(res)) {
                 av_log(ctx, AV_LOG_ERROR,
-                       "Error when evaluating the expression '%s' for the value %d for the component #%d.\n",
-                       lut->comp_expr_str[comp], val, comp);
+                       "Error when evaluating the expression '%s' for the value %d for the component %d.\n",
+                       lut->comp_expr_str[color], val, comp);
                 return AVERROR(EINVAL);
             }
-            lut->lut[comp][val] = av_clip((int)res, min[comp], max[comp]);
+            lut->lut[comp][val] = av_clip((int)res, min[color], max[color]);
             av_log(ctx, AV_LOG_DEBUG, "val[%d][%d] = %d\n", comp, val, lut->lut[comp][val]);
         }
     }
@@ -303,7 +267,7 @@
     AVFilterBufferRef *inpic  = inlink ->cur_buf;
     AVFilterBufferRef *outpic = outlink->out_buf;
     uint8_t *inrow, *outrow, *inrow0, *outrow0;
-    int i, j, k, plane;
+    int i, j, plane;
 
     if (lut->is_rgb) {
         /* packed */
@@ -311,11 +275,21 @@
         outrow0 = outpic->data[0] + y * outpic->linesize[0];
 
         for (i = 0; i < h; i ++) {
+            int w = inlink->w;
+            const uint8_t (*tab)[256] = (const uint8_t (*)[256])lut->lut;
             inrow  = inrow0;
             outrow = outrow0;
-            for (j = 0; j < inlink->w; j++) {
-                for (k = 0; k < lut->step; k++)
-                    outrow[k] = lut->lut[lut->rgba_map[k]][inrow[k]];
+            for (j = 0; j < w; j++) {
+                outrow[0] = tab[0][inrow[0]];
+                if (lut->step>1) {
+                    outrow[1] = tab[1][inrow[1]];
+                    if (lut->step>2) {
+                        outrow[2] = tab[2][inrow[2]];
+                        if (lut->step>3) {
+                            outrow[3] = tab[3][inrow[3]];
+                        }
+                    }
+                }
                 outrow += lut->step;
                 inrow  += lut->step;
             }
@@ -331,9 +305,11 @@
             inrow  = inpic ->data[plane] + (y>>vsub) * inpic ->linesize[plane];
             outrow = outpic->data[plane] + (y>>vsub) * outpic->linesize[plane];
 
-            for (i = 0; i < h>>vsub; i ++) {
-                for (j = 0; j < inlink->w>>hsub; j++)
-                    outrow[j] = lut->lut[plane][inrow[j]];
+            for (i = 0; i < (h + (1<<vsub) - 1)>>vsub; i ++) {
+                const uint8_t *tab = lut->lut[plane];
+                int w = (inlink->w + (1<<hsub) - 1)>>hsub;
+                for (j = 0; j < w; j++)
+                    outrow[j] = tab[inrow[j]];
                 inrow  += inpic ->linesize[plane];
                 outrow += outpic->linesize[plane];
             }
@@ -356,32 +332,94 @@
       .type            = AVMEDIA_TYPE_VIDEO, },
     { .name = NULL}
 };
-#define DEFINE_LUT_FILTER(name_, description_, init_)                   \
+#define DEFINE_LUT_FILTER(name_, description_)                          \
     AVFilter avfilter_vf_##name_ = {                                    \
         .name          = #name_,                                        \
         .description   = NULL_IF_CONFIG_SMALL(description_),            \
         .priv_size     = sizeof(LutContext),                            \
                                                                         \
-        .init          = init_,                                         \
+        .init          = name_##_init,                                  \
         .uninit        = uninit,                                        \
         .query_formats = query_formats,                                 \
                                                                         \
         .inputs        = inputs,                                        \
         .outputs       = outputs,                                       \
+        .priv_class    = &name_##_class,                                \
     }
 
 #if CONFIG_LUT_FILTER
-DEFINE_LUT_FILTER(lut,    "Compute and apply a lookup table to the RGB/YUV input video.", init);
+
+#define lut_options options
+AVFILTER_DEFINE_CLASS(lut);
+
+static int lut_init(AVFilterContext *ctx, const char *args)
+{
+    LutContext *lut = ctx->priv;
+    int ret;
+
+    lut->class = &lut_class;
+    av_opt_set_defaults(lut);
+
+    if (args && (ret = av_set_options_string(lut, args, "=", ":")) < 0)
+        return ret;
+
+    return 0;
+}
+
+DEFINE_LUT_FILTER(lut, "Compute and apply a lookup table to the RGB/YUV input video.");
 #endif
+
 #if CONFIG_LUTYUV_FILTER
-DEFINE_LUT_FILTER(lutyuv, "Compute and apply a lookup table to the YUV input video.",     init);
+
+#define lutyuv_options options
+AVFILTER_DEFINE_CLASS(lutyuv);
+
+static int lutyuv_init(AVFilterContext *ctx, const char *args)
+{
+    LutContext *lut = ctx->priv;
+    int ret;
+
+    lut->class = &lutyuv_class;
+    lut->is_yuv = 1;
+    av_opt_set_defaults(lut);
+
+    if (args && (ret = av_set_options_string(lut, args, "=", ":")) < 0)
+        return ret;
+
+    return 0;
+}
+
+DEFINE_LUT_FILTER(lutyuv, "Compute and apply a lookup table to the YUV input video.");
 #endif
+
 #if CONFIG_LUTRGB_FILTER
-DEFINE_LUT_FILTER(lutrgb, "Compute and apply a lookup table to the RGB input video.",     init);
+
+#define lutrgb_options options
+AVFILTER_DEFINE_CLASS(lutrgb);
+
+static int lutrgb_init(AVFilterContext *ctx, const char *args)
+{
+    LutContext *lut = ctx->priv;
+    int ret;
+
+    lut->class = &lutrgb_class;
+    lut->is_rgb = 1;
+    av_opt_set_defaults(lut);
+
+    if (args && (ret = av_set_options_string(lut, args, "=", ":")) < 0)
+        return ret;
+
+    return 0;
+}
+
+DEFINE_LUT_FILTER(lutrgb, "Compute and apply a lookup table to the RGB input video.");
 #endif
 
 #if CONFIG_NEGATE_FILTER
 
+#define negate_options options
+AVFILTER_DEFINE_CLASS(negate);
+
 static int negate_init(AVFilterContext *ctx, const char *args)
 {
     LutContext *lut = ctx->priv;
@@ -395,9 +433,12 @@
     snprintf(lut_params, sizeof(lut_params), "c0=negval:c1=negval:c2=negval:a=%s",
              lut->negate_alpha ? "negval" : "val");
 
-    return init(ctx, lut_params);
+    lut->class = &negate_class;
+    av_opt_set_defaults(lut);
+
+    return av_set_options_string(lut, lut_params, "=", ":");
 }
 
-DEFINE_LUT_FILTER(negate, "Negate input video.", negate_init);
+DEFINE_LUT_FILTER(negate, "Negate input video.");
 
 #endif
diff --git a/libavfilter/vf_mp.c b/libavfilter/vf_mp.c
new file mode 100644
index 0000000..377a8b5
--- /dev/null
+++ b/libavfilter/vf_mp.c
@@ -0,0 +1,902 @@
+/*
+ * Copyright (c) 2011 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 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
+ *
+ * Parts of this file have been stolen from mplayer
+ */
+
+/**
+ * @file
+ */
+
+#include "avfilter.h"
+#include "video.h"
+#include "formats.h"
+#include "internal.h"
+#include "libavutil/avassert.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/imgutils.h"
+
+#include "libmpcodecs/vf.h"
+#include "libmpcodecs/img_format.h"
+#include "libmpcodecs/cpudetect.h"
+#include "libmpcodecs/vd_ffmpeg.h"
+#include "libmpcodecs/vf_scale.h"
+#include "libmpcodecs/libvo/fastmemcpy.h"
+
+#include "libswscale/swscale.h"
+
+
+//FIXME maybe link the orig in
+//XXX: identical pix_fmt must be following with each others
+static const struct {
+    int fmt;
+    enum AVPixelFormat pix_fmt;
+} conversion_map[] = {
+    {IMGFMT_ARGB, AV_PIX_FMT_ARGB},
+    {IMGFMT_BGRA, AV_PIX_FMT_BGRA},
+    {IMGFMT_BGR24, AV_PIX_FMT_BGR24},
+    {IMGFMT_BGR16BE, AV_PIX_FMT_RGB565BE},
+    {IMGFMT_BGR16LE, AV_PIX_FMT_RGB565LE},
+    {IMGFMT_BGR15BE, AV_PIX_FMT_RGB555BE},
+    {IMGFMT_BGR15LE, AV_PIX_FMT_RGB555LE},
+    {IMGFMT_BGR12BE, AV_PIX_FMT_RGB444BE},
+    {IMGFMT_BGR12LE, AV_PIX_FMT_RGB444LE},
+    {IMGFMT_BGR8,  AV_PIX_FMT_RGB8},
+    {IMGFMT_BGR4,  AV_PIX_FMT_RGB4},
+    {IMGFMT_BGR1,  AV_PIX_FMT_MONOBLACK},
+    {IMGFMT_RGB1,  AV_PIX_FMT_MONOBLACK},
+    {IMGFMT_RG4B,  AV_PIX_FMT_BGR4_BYTE},
+    {IMGFMT_BG4B,  AV_PIX_FMT_RGB4_BYTE},
+    {IMGFMT_RGB48LE, AV_PIX_FMT_RGB48LE},
+    {IMGFMT_RGB48BE, AV_PIX_FMT_RGB48BE},
+    {IMGFMT_ABGR, AV_PIX_FMT_ABGR},
+    {IMGFMT_RGBA, AV_PIX_FMT_RGBA},
+    {IMGFMT_RGB24, AV_PIX_FMT_RGB24},
+    {IMGFMT_RGB16BE, AV_PIX_FMT_BGR565BE},
+    {IMGFMT_RGB16LE, AV_PIX_FMT_BGR565LE},
+    {IMGFMT_RGB15BE, AV_PIX_FMT_BGR555BE},
+    {IMGFMT_RGB15LE, AV_PIX_FMT_BGR555LE},
+    {IMGFMT_RGB12BE, AV_PIX_FMT_BGR444BE},
+    {IMGFMT_RGB12LE, AV_PIX_FMT_BGR444LE},
+    {IMGFMT_RGB8,  AV_PIX_FMT_BGR8},
+    {IMGFMT_RGB4,  AV_PIX_FMT_BGR4},
+    {IMGFMT_BGR8,  AV_PIX_FMT_PAL8},
+    {IMGFMT_YUY2,  AV_PIX_FMT_YUYV422},
+    {IMGFMT_UYVY,  AV_PIX_FMT_UYVY422},
+    {IMGFMT_NV12,  AV_PIX_FMT_NV12},
+    {IMGFMT_NV21,  AV_PIX_FMT_NV21},
+    {IMGFMT_Y800,  AV_PIX_FMT_GRAY8},
+    {IMGFMT_Y8,    AV_PIX_FMT_GRAY8},
+    {IMGFMT_YVU9,  AV_PIX_FMT_YUV410P},
+    {IMGFMT_IF09,  AV_PIX_FMT_YUV410P},
+    {IMGFMT_YV12,  AV_PIX_FMT_YUV420P},
+    {IMGFMT_I420,  AV_PIX_FMT_YUV420P},
+    {IMGFMT_IYUV,  AV_PIX_FMT_YUV420P},
+    {IMGFMT_411P,  AV_PIX_FMT_YUV411P},
+    {IMGFMT_422P,  AV_PIX_FMT_YUV422P},
+    {IMGFMT_444P,  AV_PIX_FMT_YUV444P},
+    {IMGFMT_440P,  AV_PIX_FMT_YUV440P},
+
+    {IMGFMT_420A,  AV_PIX_FMT_YUVA420P},
+
+    {IMGFMT_420P16_LE,  AV_PIX_FMT_YUV420P16LE},
+    {IMGFMT_420P16_BE,  AV_PIX_FMT_YUV420P16BE},
+    {IMGFMT_422P16_LE,  AV_PIX_FMT_YUV422P16LE},
+    {IMGFMT_422P16_BE,  AV_PIX_FMT_YUV422P16BE},
+    {IMGFMT_444P16_LE,  AV_PIX_FMT_YUV444P16LE},
+    {IMGFMT_444P16_BE,  AV_PIX_FMT_YUV444P16BE},
+
+    // YUVJ are YUV formats that use the full Y range and not just
+    // 16 - 235 (see colorspaces.txt).
+    // Currently they are all treated the same way.
+    {IMGFMT_YV12,  AV_PIX_FMT_YUVJ420P},
+    {IMGFMT_422P,  AV_PIX_FMT_YUVJ422P},
+    {IMGFMT_444P,  AV_PIX_FMT_YUVJ444P},
+    {IMGFMT_440P,  AV_PIX_FMT_YUVJ440P},
+
+    {IMGFMT_XVMC_MOCO_MPEG2, AV_PIX_FMT_XVMC_MPEG2_MC},
+    {IMGFMT_XVMC_IDCT_MPEG2, AV_PIX_FMT_XVMC_MPEG2_IDCT},
+    {IMGFMT_VDPAU_MPEG1,     AV_PIX_FMT_VDPAU_MPEG1},
+    {IMGFMT_VDPAU_MPEG2,     AV_PIX_FMT_VDPAU_MPEG2},
+    {IMGFMT_VDPAU_H264,      AV_PIX_FMT_VDPAU_H264},
+    {IMGFMT_VDPAU_WMV3,      AV_PIX_FMT_VDPAU_WMV3},
+    {IMGFMT_VDPAU_VC1,       AV_PIX_FMT_VDPAU_VC1},
+    {IMGFMT_VDPAU_MPEG4,     AV_PIX_FMT_VDPAU_MPEG4},
+    {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_field;
+extern const vf_info_t vf_info_fil;
+extern const vf_info_t vf_info_filmdint;
+extern const vf_info_t vf_info_fixpts;
+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_geq;
+extern const vf_info_t vf_info_halfpack;
+extern const vf_info_t vf_info_harddup;
+extern const vf_info_t vf_info_hqdn3d;
+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_palette;
+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_rectangle;
+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_tile;
+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_yuvcsp;
+extern const vf_info_t vf_info_yvu9;
+extern const vf_info_t vf_info_zrmjpeg;
+
+
+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_field,
+    &vf_info_fil,
+//    &vf_info_filmdint, cmmx.h vd.h ‘opt_screen_size_x’
+    &vf_info_fixpts,
+    &vf_info_fspp,
+    &vf_info_geq,
+    &vf_info_harddup,
+    &vf_info_hqdn3d,
+    &vf_info_il,
+    &vf_info_ilpack,
+    &vf_info_ivtc,
+    &vf_info_kerndeint,
+    &vf_info_mcdeint,
+    &vf_info_noise,
+    &vf_info_ow,
+    &vf_info_palette,
+    &vf_info_perspective,
+    &vf_info_phase,
+    &vf_info_pp,
+    &vf_info_pp7,
+    &vf_info_pullup,
+    &vf_info_qp,
+    &vf_info_rectangle,
+    &vf_info_sab,
+    &vf_info_softpulldown,
+    &vf_info_softskip,
+    &vf_info_spp,
+    &vf_info_stereo3d,
+    &vf_info_telecine,
+    &vf_info_tile,
+    &vf_info_tinterlace,
+    &vf_info_unsharp,
+    &vf_info_uspp,
+    &vf_info_yuvcsp,
+    &vf_info_yvu9,
+
+    NULL
+};
+
+/*
+Unsupported filters
+1bpp
+ass
+bmovl
+crop
+dvbscale
+flip
+expand
+format
+halfpack
+lavc
+lavcdeint
+noformat
+pp
+scale
+tfields
+vo
+yadif
+zrmjpeg
+*/
+
+CpuCaps gCpuCaps; //FIXME initialize this so optims work
+
+
+static void sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam)
+{
+        static int firstTime=1;
+        *flags=0;
+
+#if ARCH_X86
+        if(gCpuCaps.hasMMX)
+                __asm__ volatile("emms\n\t"::: "memory"); //FIXME this should not be required but it IS (even for non-MMX versions)
+#endif
+        if(firstTime)
+        {
+                firstTime=0;
+                *flags= SWS_PRINT_INFO;
+        }
+        else if( mp_msg_test(MSGT_VFILTER,MSGL_DBG2) ) *flags= SWS_PRINT_INFO;
+
+        switch(SWS_BILINEAR)
+        {
+                case 0: *flags|= SWS_FAST_BILINEAR; break;
+                case 1: *flags|= SWS_BILINEAR; break;
+                case 2: *flags|= SWS_BICUBIC; break;
+                case 3: *flags|= SWS_X; break;
+                case 4: *flags|= SWS_POINT; break;
+                case 5: *flags|= SWS_AREA; break;
+                case 6: *flags|= SWS_BICUBLIN; break;
+                case 7: *flags|= SWS_GAUSS; break;
+                case 8: *flags|= SWS_SINC; break;
+                case 9: *flags|= SWS_LANCZOS; break;
+                case 10:*flags|= SWS_SPLINE; break;
+                default:*flags|= SWS_BILINEAR; break;
+        }
+
+        *srcFilterParam= NULL;
+        *dstFilterParam= NULL;
+}
+
+//exact copy from vf_scale.c
+// will use sws_flags & src_filter (from cmd line)
+struct SwsContext *sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat)
+{
+        int flags, i;
+        SwsFilter *dstFilterParam, *srcFilterParam;
+        enum AVPixelFormat dfmt, sfmt;
+
+        for(i=0; conversion_map[i].fmt && dstFormat != conversion_map[i].fmt; i++);
+        dfmt= conversion_map[i].pix_fmt;
+        for(i=0; conversion_map[i].fmt && srcFormat != conversion_map[i].fmt; i++);
+        sfmt= conversion_map[i].pix_fmt;
+
+        if (srcFormat == IMGFMT_RGB8 || srcFormat == IMGFMT_BGR8) sfmt = AV_PIX_FMT_PAL8;
+        sws_getFlagsAndFilterFromCmdLine(&flags, &srcFilterParam, &dstFilterParam);
+
+        return sws_getContext(srcW, srcH, sfmt, dstW, dstH, dfmt, flags , srcFilterParam, dstFilterParam, NULL);
+}
+
+typedef struct {
+    vf_instance_t vf;
+    vf_instance_t next_vf;
+    AVFilterContext *avfctx;
+    int frame_returned;
+} MPContext;
+
+void mp_msg(int mod, int lev, const char *format, ... ){
+    va_list va;
+    va_start(va, format);
+    //FIXME convert lev/mod
+    av_vlog(NULL, AV_LOG_DEBUG, format, va);
+    va_end(va);
+}
+
+int mp_msg_test(int mod, int lev){
+    return 123;
+}
+
+void 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){
+    dst->pict_type= src->pict_type;
+    dst->fields = src->fields;
+    dst->qscale_type= src->qscale_type;
+    if(dst->width == src->width && dst->height == src->height){
+        dst->qstride= src->qstride;
+        dst->qscale= src->qscale;
+    }
+}
+
+//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){
+    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);
+        return;
+    }
+    if (!(vf->dmpi->flags & MP_IMGFLAG_PLANAR)) {
+        memcpy_pic(vf->dmpi->planes[0]+y*vf->dmpi->stride[0]+vf->dmpi->bpp/8*x,
+            src[0], vf->dmpi->bpp/8*w, h, vf->dmpi->stride[0], stride[0]);
+        return;
+    }
+    memcpy_pic(vf->dmpi->planes[0]+y*vf->dmpi->stride[0]+x, src[0],
+        w, h, vf->dmpi->stride[0], stride[0]);
+    memcpy_pic(vf->dmpi->planes[1]+(y>>vf->dmpi->chroma_y_shift)*vf->dmpi->stride[1]+(x>>vf->dmpi->chroma_x_shift),
+        src[1], w>>vf->dmpi->chroma_x_shift, h>>vf->dmpi->chroma_y_shift, vf->dmpi->stride[1], stride[1]);
+    memcpy_pic(vf->dmpi->planes[2]+(y>>vf->dmpi->chroma_y_shift)*vf->dmpi->stride[2]+(x>>vf->dmpi->chroma_x_shift),
+        src[2], w>>vf->dmpi->chroma_x_shift, h>>vf->dmpi->chroma_y_shift, vf->dmpi->stride[2], stride[2]);
+}
+
+//Exact copy of vf.c
+void 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;
+        if(x0==0 && w==mpi->width){
+            // full width clear:
+            memset(mpi->planes[0]+mpi->stride[0]*y0,0,mpi->stride[0]*h);
+            memset(mpi->planes[1]+mpi->stride[1]*(y0>>mpi->chroma_y_shift),128,mpi->stride[1]*(h>>mpi->chroma_y_shift));
+            memset(mpi->planes[2]+mpi->stride[2]*(y0>>mpi->chroma_y_shift),128,mpi->stride[2]*(h>>mpi->chroma_y_shift));
+        } else
+        for(y=y0;y<y0+h;y+=2){
+            memset(mpi->planes[0]+x0+mpi->stride[0]*y,0,w);
+            memset(mpi->planes[0]+x0+mpi->stride[0]*(y+1),0,w);
+            memset(mpi->planes[1]+(x0>>mpi->chroma_x_shift)+mpi->stride[1]*(y>>mpi->chroma_y_shift),128,(w>>mpi->chroma_x_shift));
+            memset(mpi->planes[2]+(x0>>mpi->chroma_x_shift)+mpi->stride[2]*(y>>mpi->chroma_y_shift),128,(w>>mpi->chroma_x_shift));
+        }
+        return;
+    }
+    // packed:
+    for(y=y0;y<y0+h;y++){
+        unsigned char* dst=mpi->planes[0]+mpi->stride[0]*y+(mpi->bpp>>3)*x0;
+        if(mpi->flags&MP_IMGFLAG_YUV){
+            unsigned int* p=(unsigned int*) dst;
+            int size=(mpi->bpp>>3)*w/4;
+            int i;
+#if HAVE_BIGENDIAN
+#define CLEAR_PACKEDYUV_PATTERN 0x00800080
+#define CLEAR_PACKEDYUV_PATTERN_SWAPPED 0x80008000
+#else
+#define CLEAR_PACKEDYUV_PATTERN 0x80008000
+#define CLEAR_PACKEDYUV_PATTERN_SWAPPED 0x00800080
+#endif
+            if(mpi->flags&MP_IMGFLAG_SWAPPED){
+                for(i=0;i<size-3;i+=4) p[i]=p[i+1]=p[i+2]=p[i+3]=CLEAR_PACKEDYUV_PATTERN_SWAPPED;
+                for(;i<size;i++) p[i]=CLEAR_PACKEDYUV_PATTERN_SWAPPED;
+            } else {
+                for(i=0;i<size-3;i+=4) p[i]=p[i+1]=p[i+2]=p[i+3]=CLEAR_PACKEDYUV_PATTERN;
+                for(;i<size;i++) p[i]=CLEAR_PACKEDYUV_PATTERN;
+            }
+        } else
+            memset(dst,0,(mpi->bpp>>3)*w);
+    }
+}
+
+int 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){
+    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){
+    MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, next_vf));
+  mp_image_t* mpi=NULL;
+  int w2;
+  int number = mp_imgtype >> 16;
+
+  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
+  if(vf->w==0 && w>0) vf->w=w;
+  if(vf->h==0 && h>0) vf->h=h;
+
+  av_assert0(w == -1 || w >= vf->w);
+  av_assert0(h == -1 || h >= vf->h);
+  av_assert0(vf->w > 0);
+  av_assert0(vf->h > 0);
+
+  av_log(m->avfctx, AV_LOG_DEBUG, "get_image: %d:%d, vf: %d:%d\n", w,h,vf->w,vf->h);
+
+  if (w == -1) w = vf->w;
+  if (h == -1) h = vf->h;
+
+  w2=(mp_imgflag&MP_IMGFLAG_ACCEPT_ALIGNED_STRIDE)?((w+15)&(~15)):w;
+
+  // Note: we should call libvo first to check if it supports direct rendering
+  // 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);
+    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);
+    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);
+    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);
+      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);
+    mpi=vf->imgctx.static_images[vf->imgctx.static_idx];
+    vf->imgctx.static_idx^=1;
+    break;
+  case MP_IMGTYPE_NUMBERED:
+    if (number == -1) {
+      int i;
+      for (i = 0; i < NUM_NUMBERED_MPI; i++)
+        if (!vf->imgctx.numbered_images[i] || !vf->imgctx.numbered_images[i]->usage_count)
+          break;
+      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);
+    mpi = vf->imgctx.numbered_images[number];
+    mpi->number = number;
+    break;
+  }
+  if(mpi){
+    mpi->type=mp_imgtype;
+    mpi->w=vf->w; mpi->h=vf->h;
+    // keep buffer allocation status & color flags only:
+//    mpi->flags&=~(MP_IMGFLAG_PRESERVE|MP_IMGFLAG_READABLE|MP_IMGFLAG_DIRECT);
+    mpi->flags&=MP_IMGFLAG_ALLOCATED|MP_IMGFLAG_TYPE_DISPLAYED|MP_IMGFLAGMASK_COLORS;
+    // accept restrictions, draw_slice and palette flags only:
+    mpi->flags|=mp_imgflag&(MP_IMGFLAGMASK_RESTRICTIONS|MP_IMGFLAG_DRAW_CALLBACK|MP_IMGFLAG_RGB_PALETTE);
+    if(!vf->draw_slice) mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;
+    if(mpi->width!=w2 || mpi->height!=h){
+//      printf("vf.c: MPI parameters changed!  %dx%d -> %dx%d   \n", mpi->width,mpi->height,w2,h);
+        if(mpi->flags&MP_IMGFLAG_ALLOCATED){
+            if(mpi->width<w2 || mpi->height<h){
+                // 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");
+            }
+//      } else {
+        } {
+            mpi->width=w2; mpi->chroma_width=(w2 + (1<<mpi->chroma_x_shift) - 1)>>mpi->chroma_x_shift;
+            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->flags&MP_IMGFLAG_ALLOCATED) && mpi->type>MP_IMGTYPE_EXPORT){
+
+        av_assert0(!vf->get_image);
+        // check libvo first!
+        if(vf->get_image) vf->get_image(vf,mpi);
+
+        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");
+              return NULL;
+          }
+
+          // check if codec prefer aligned stride:
+          if(mp_imgflag&MP_IMGFLAG_PREFER_ALIGNED_STRIDE){
+              int align=(mpi->flags&MP_IMGFLAG_PLANAR &&
+                         mpi->flags&MP_IMGFLAG_YUV) ?
+                         (8<<mpi->chroma_x_shift)-1 : 15; // -- maybe FIXME
+              w2=((w+align)&(~align));
+              if(mpi->width!=w2){
+#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");
+//                printf("query -> 0x%X    \n",flags);
+                  if(flags&VFCAP_ACCEPT_STRIDE){
+#endif
+                      mpi->width=w2;
+                      mpi->chroma_width=(w2 + (1<<mpi->chroma_x_shift) - 1)>>mpi->chroma_x_shift;
+//                  }
+              }
+          }
+
+          mp_image_alloc_planes(mpi);
+//        printf("clearing img!\n");
+          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",
+                  "NULL"/*vf->info->name*/,
+                  (mpi->type==MP_IMGTYPE_EXPORT)?"Exporting":
+                  ((mpi->flags&MP_IMGFLAG_DIRECT)?"Direct Rendering":"Allocating"),
+                  (mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)?" (slices)":"",
+                  mpi->width,mpi->height,mpi->bpp,
+                  (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",
+                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);
+            mpi->flags|=MP_IMGFLAG_TYPE_DISPLAYED;
+    }
+
+  mpi->qscale = NULL;
+  }
+  mpi->usage_count++;
+//    printf("\rVF_MPI: %p %p %p %d %d %d    \n",
+//      mpi->planes[0],mpi->planes[1],mpi->planes[2],
+//      mpi->stride[0],mpi->stride[1],mpi->stride[2]);
+  return mpi;
+}
+
+
+int 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));
+    AVFilterBufferRef *picref = av_mallocz(sizeof(AVFilterBufferRef));
+    int i;
+
+    av_assert0(vf->next);
+
+    av_log(m->avfctx, AV_LOG_DEBUG, "vf_next_put_image\n");
+
+    if (!pic || !picref)
+        goto fail;
+
+    picref->buf = pic;
+    picref->buf->please_use_av_free= (void*)av_free;
+    if (!(picref->video = av_mallocz(sizeof(AVFilterBufferRefVideoProps))))
+        goto fail;
+
+    pic->w = picref->video->w = mpi->w;
+    pic->h = picref->video->h = mpi->h;
+
+    /* make sure the buffer gets read permission or it's useless for output */
+    picref->perms = AV_PERM_READ | AV_PERM_REUSE2;
+//    av_assert0(mpi->flags&MP_IMGFLAG_READABLE);
+    if(!(mpi->flags&MP_IMGFLAG_PRESERVE))
+        picref->perms |= AV_PERM_WRITE;
+
+    pic->refcount = 1;
+    picref->type = AVMEDIA_TYPE_VIDEO;
+
+    for(i=0; conversion_map[i].fmt && mpi->imgfmt != conversion_map[i].fmt; i++);
+    pic->format = picref->format = conversion_map[i].pix_fmt;
+
+    memcpy(pic->data,        mpi->planes,   FFMIN(sizeof(pic->data)    , sizeof(mpi->planes)));
+    memcpy(pic->linesize,    mpi->stride,   FFMIN(sizeof(pic->linesize), sizeof(mpi->stride)));
+    memcpy(picref->data,     pic->data,     sizeof(picref->data));
+    memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
+
+    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);
+    m->frame_returned++;
+
+    return 1;
+fail:
+    if (picref && picref->video)
+        av_free(picref->video);
+    av_free(picref);
+    av_free(pic);
+    return 0;
+}
+
+int vf_next_config(struct vf_instance *vf,
+        int width, int height, int d_width, int d_height,
+        unsigned int voflags, unsigned int outfmt){
+
+    av_assert0(width>0 && height>0);
+    vf->next->w = width; vf->next->h = height;
+
+    return 1;
+#if 0
+    int flags=vf->next->query_format(vf->next,outfmt);
+    if(!flags){
+        // hmm. colorspace mismatch!!!
+        //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);
+    miss=vf->default_reqs - (flags&vf->default_reqs);
+    if(miss&VFCAP_ACCEPT_STRIDE){
+        // vf requires stride support but vf->next doesn't support it!
+        // let's insert the 'expand' filter, it does the job for us:
+        vf_instance_t* vf2=vf_open_filter(vf->next,"expand",NULL);
+        if(!vf2) return 0; // shouldn't happen!
+        vf->next=vf2;
+    }
+    vf->next->w = width; vf->next->h = height;
+    return 1;
+#endif
+}
+
+int 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;
+}
+
+static int vf_default_query_format(struct vf_instance *vf, unsigned int fmt){
+    MPContext *m= (void*)vf;
+    int i;
+    av_log(m->avfctx, AV_LOG_DEBUG, "query %X\n", fmt);
+
+    for(i=0; conversion_map[i].fmt; i++){
+        if(fmt==conversion_map[i].fmt)
+            return 1; //we suport all
+    }
+    return 0;
+}
+
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    MPContext *m = ctx->priv;
+    char name[256];
+    int i;
+
+    m->avfctx= ctx;
+
+    if(!args || 1!=sscanf(args, "%255[^:=]", name)){
+        av_log(ctx, AV_LOG_ERROR, "Invalid parameter.\n");
+        return AVERROR(EINVAL);
+    }
+    args+= strlen(name)+1;
+
+    for(i=0; ;i++){
+        if(!filters[i] || !strcmp(name, filters[i]->name))
+            break;
+    }
+
+    if(!filters[i]){
+        av_log(ctx, AV_LOG_ERROR, "Unknown filter %s\n", name);
+        return AVERROR(EINVAL);
+    }
+
+    av_log(ctx, AV_LOG_WARNING,
+           "'%s' is a wrapped MPlayer filter (libmpcodecs). This filter may be removed\n"
+           "once it has been ported to a native libavfilter.\n", name);
+
+    memset(&m->vf,0,sizeof(m->vf));
+    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.query_format= vf_default_query_format;
+    m->vf.control     = vf_next_control;
+    m->vf.default_caps=VFCAP_ACCEPT_STRIDE;
+    m->vf.default_reqs=0;
+    if(m->vf.info->opts)
+        av_log(ctx, AV_LOG_ERROR, "opts / m_struct_set is unsupported\n");
+#if 0
+    if(vf->info->opts) { // vf_vo get some special argument
+      const m_struct_t* st = vf->info->opts;
+      void* vf_priv = m_struct_alloc(st);
+      int n;
+      for(n = 0 ; args && args[2*n] ; n++)
+        m_struct_set(st,vf_priv,args[2*n],args[2*n+1]);
+      vf->priv = vf_priv;
+      args = NULL;
+    } else // Otherwise we should have the '_oldargs_'
+      if(args && !strcmp(args[0],"_oldargs_"))
+        args = (char**)args[1];
+      else
+        args = NULL;
+#endif
+    if(m->vf.info->vf_open(&m->vf, args)<=0){
+        av_log(ctx, AV_LOG_ERROR, "vf_open() of %s with arg=%s failed\n", name, args);
+        return -1;
+    }
+
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    MPContext *m = ctx->priv;
+    vf_instance_t *vf = &m->vf;
+
+    while(vf){
+        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]);
+        vf = next;
+    }
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    AVFilterFormats *avfmts=NULL;
+    MPContext *m = ctx->priv;
+    enum AVPixelFormat lastpixfmt = AV_PIX_FMT_NONE;
+    int i;
+
+    for(i=0; conversion_map[i].fmt; i++){
+        av_log(ctx, AV_LOG_DEBUG, "query: %X\n", conversion_map[i].fmt);
+        if(m->vf.query_format(&m->vf, conversion_map[i].fmt)){
+            av_log(ctx, AV_LOG_DEBUG, "supported,adding\n");
+            if (conversion_map[i].pix_fmt != lastpixfmt) {
+                ff_add_format(&avfmts, conversion_map[i].pix_fmt);
+                lastpixfmt = conversion_map[i].pix_fmt;
+            }
+        }
+    }
+
+    //We assume all allowed input formats are also allowed output formats
+    ff_set_common_formats(ctx, avfmts);
+    return 0;
+}
+
+static int config_inprops(AVFilterLink *inlink)
+{
+    MPContext *m = inlink->dst->priv;
+    int i;
+    for(i=0; conversion_map[i].fmt && conversion_map[i].pix_fmt != inlink->format; i++);
+
+    av_assert0(conversion_map[i].fmt && inlink->w && inlink->h);
+
+    m->vf.fmt.have_configured = 1;
+    m->vf.fmt.orig_height     = inlink->h;
+    m->vf.fmt.orig_width      = inlink->w;
+    m->vf.fmt.orig_fmt        = conversion_map[i].fmt;
+
+    if(m->vf.config(&m->vf, inlink->w, inlink->h, inlink->w, inlink->h, 0, conversion_map[i].fmt)<=0)
+        return -1;
+
+    return 0;
+}
+
+static int config_outprops(AVFilterLink *outlink)
+{
+    MPContext *m = outlink->src->priv;
+
+    outlink->w = m->next_vf.w;
+    outlink->h = m->next_vf.h;
+
+    return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    MPContext *m = outlink->src->priv;
+    int ret;
+
+    av_log(m->avfctx, AV_LOG_DEBUG, "mp request_frame\n");
+
+    for(m->frame_returned=0; !m->frame_returned;){
+        ret=ff_request_frame(outlink->src->inputs[0]);
+        if(ret<0)
+            break;
+    }
+
+    av_log(m->avfctx, AV_LOG_DEBUG, "mp request_frame ret=%d\n", ret);
+    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)
+{
+    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);
+
+    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);
+
+    memcpy(mpi->planes, inpic->data,     FFMIN(sizeof(inpic->data)    , sizeof(mpi->planes)));
+    memcpy(mpi->stride, inpic->linesize, FFMIN(sizeof(inpic->linesize), sizeof(mpi->stride)));
+
+    //FIXME pass interleced & tff flags around
+
+    // mpi->flags|=MP_IMGFLAG_ALLOCATED; ?
+    mpi->flags |= MP_IMGFLAG_READABLE;
+    if(!(inpic->perms & AV_PERM_WRITE))
+        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");
+    }
+    free_mp_image(mpi);
+    return 0;
+}
+
+AVFilter avfilter_vf_mp = {
+    .name      = "mp",
+    .description = NULL_IF_CONFIG_SMALL("Apply a libmpcodecs filter to the input video."),
+    .init = init,
+    .uninit = uninit,
+    .priv_size = sizeof(MPContext),
+    .query_formats = query_formats,
+
+    .inputs    = (const AVFilterPad[]) {{ .name      = "default",
+                                    .type            = AVMEDIA_TYPE_VIDEO,
+                                    .start_frame     = start_frame,
+                                    .draw_slice      = null_draw_slice,
+                                    .end_frame       = end_frame,
+                                    .config_props    = config_inprops,
+                                    .min_perms       = AV_PERM_READ, },
+                                  { .name = NULL}},
+    .outputs   = (const AVFilterPad[]) {{ .name      = "default",
+                                    .type            = AVMEDIA_TYPE_VIDEO,
+                                    .request_frame   = request_frame,
+                                    .config_props    = config_outprops, },
+                                  { .name = NULL}},
+};
diff --git a/libavfilter/vf_null.c b/libavfilter/vf_null.c
index 87e4820..b22779d 100644
--- a/libavfilter/vf_null.c
+++ b/libavfilter/vf_null.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index 8fb44e3..4f2f423 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2010 Baptiste Coudurier
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,22 +25,24 @@
  * overlay one video on top of another
  */
 
+/* #define DEBUG */
+
 #include "avfilter.h"
 #include "formats.h"
 #include "libavutil/common.h"
 #include "libavutil/eval.h"
 #include "libavutil/avstring.h"
-#include "libavutil/avassert.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/timestamp.h"
 #include "internal.h"
+#include "bufferqueue.h"
+#include "drawutils.h"
 #include "video.h"
 
 static const char *const var_names[] = {
-    "E",
-    "PHI",
-    "PI",
     "main_w",    "W", ///< width  of the main    video
     "main_h",    "H", ///< height of the main    video
     "overlay_w", "w", ///< width  of the overlay video
@@ -49,9 +51,6 @@
 };
 
 enum var_name {
-    VAR_E,
-    VAR_PHI,
-    VAR_PI,
     VAR_MAIN_W,    VAR_MW,
     VAR_MAIN_H,    VAR_MH,
     VAR_OVERLAY_W, VAR_OW,
@@ -62,63 +61,152 @@
 #define MAIN    0
 #define OVERLAY 1
 
+#define R 0
+#define G 1
+#define B 2
+#define A 3
+
+#define Y 0
+#define U 1
+#define V 2
+
 typedef struct {
+    const AVClass *class;
     int x, y;                   ///< position of overlayed picture
 
-    int max_plane_step[4];      ///< steps per pixel for each plane
+    int allow_packed_rgb;
+    uint8_t frame_requested;
+    uint8_t overlay_eof;
+    uint8_t main_is_packed_rgb;
+    uint8_t main_rgba_map[4];
+    uint8_t main_has_alpha;
+    uint8_t overlay_is_packed_rgb;
+    uint8_t overlay_rgba_map[4];
+    uint8_t overlay_has_alpha;
+
+    AVFilterBufferRef *overpicref;
+    struct FFBufQueue queue_main;
+    struct FFBufQueue queue_over;
+
+    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
 
-    char x_expr[256], y_expr[256];
-
-    AVFilterBufferRef *main;
-    AVFilterBufferRef *over_prev, *over_next;
+    char *x_expr, *y_expr;
 } OverlayContext;
 
+#define OFFSET(x) offsetof(OverlayContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+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},
+};
+
+AVFILTER_DEFINE_CLASS(overlay);
+
 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;
 
-    av_strlcpy(over->x_expr, "0", sizeof(over->x_expr));
-    av_strlcpy(over->y_expr, "0", sizeof(over->y_expr));
+    over->class = &overlay_class;
+    av_opt_set_defaults(over);
 
-    if (args)
-        sscanf(args, "%255[^:]:%255[^:]", over->x_expr, over->y_expr);
+    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;
+        }
+    }
 
-    return 0;
+    if (bufptr && (ret = av_set_options_string(over, bufptr, "=", ":")) < 0)
+        goto end;
+
+end:
+    av_free(args1);
+    return ret;
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
 {
-    OverlayContext *s = ctx->priv;
+    OverlayContext *over = ctx->priv;
 
-    avfilter_unref_bufferp(&s->main);
-    avfilter_unref_bufferp(&s->over_prev);
-    avfilter_unref_bufferp(&s->over_next);
+    av_freep(&over->x_expr);
+    av_freep(&over->y_expr);
+
+    avfilter_unref_bufferp(&over->overpicref);
+    ff_bufqueue_discard_all(&over->queue_main);
+    ff_bufqueue_discard_all(&over->queue_over);
 }
 
 static int query_formats(AVFilterContext *ctx)
 {
-    const enum AVPixelFormat inout_pix_fmts[] = { AV_PIX_FMT_YUV420P,  AV_PIX_FMT_NONE };
-    const enum AVPixelFormat blend_pix_fmts[] = { AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE };
-    AVFilterFormats *inout_formats = ff_make_format_list(inout_pix_fmts);
-    AVFilterFormats *blend_formats = ff_make_format_list(blend_pix_fmts);
+    OverlayContext *over = ctx->priv;
 
-    ff_formats_ref(inout_formats, &ctx->inputs [MAIN   ]->out_formats);
-    ff_formats_ref(blend_formats, &ctx->inputs [OVERLAY]->out_formats);
-    ff_formats_ref(inout_formats, &ctx->outputs[MAIN   ]->in_formats );
+    /* 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_NONE };
+    const enum AVPixelFormat overlay_pix_fmts_yuv[] = { AV_PIX_FMT_YUVA420P, AV_PIX_FMT_NONE };
+    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[] = {
+        AV_PIX_FMT_ARGB,  AV_PIX_FMT_RGBA,
+        AV_PIX_FMT_ABGR,  AV_PIX_FMT_BGRA,
+        AV_PIX_FMT_NONE
+    };
+
+    AVFilterFormats *main_formats;
+    AVFilterFormats *overlay_formats;
+
+    if (over->allow_packed_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);
+    }
+
+    ff_formats_ref(main_formats,    &ctx->inputs [MAIN   ]->out_formats);
+    ff_formats_ref(overlay_formats, &ctx->inputs [OVERLAY]->out_formats);
+    ff_formats_ref(main_formats,    &ctx->outputs[MAIN   ]->in_formats );
 
     return 0;
 }
 
+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_BGRA, AV_PIX_FMT_NONE
+};
+
 static int config_input_main(AVFilterLink *inlink)
 {
     OverlayContext *over = inlink->dst->priv;
     const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
 
-    av_image_fill_max_pixsteps(over->max_plane_step, NULL, pix_desc);
+    av_image_fill_max_pixsteps(over->main_pix_step,    NULL, pix_desc);
+
     over->hsub = pix_desc->log2_chroma_w;
     over->vsub = pix_desc->log2_chroma_h;
 
+    over->main_is_packed_rgb =
+        ff_fill_rgba_map(over->main_rgba_map, inlink->format) >= 0;
+    over->main_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
     return 0;
 }
 
@@ -129,13 +217,12 @@
     char *expr;
     double var_values[VAR_VARS_NB], res;
     int ret;
+    const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[inlink->format];
+
+    av_image_fill_max_pixsteps(over->overlay_pix_step, NULL, pix_desc);
 
     /* Finish the configuration by evaluating the expressions
        now when both inputs are configured. */
-    var_values[VAR_E  ] = M_E;
-    var_values[VAR_PHI] = M_PHI;
-    var_values[VAR_PI ] = M_PI;
-
     var_values[VAR_MAIN_W   ] = var_values[VAR_MW] = ctx->inputs[MAIN   ]->w;
     var_values[VAR_MAIN_H   ] = var_values[VAR_MH] = ctx->inputs[MAIN   ]->h;
     var_values[VAR_OVERLAY_W] = var_values[VAR_OW] = ctx->inputs[OVERLAY]->w;
@@ -155,6 +242,10 @@
         goto fail;
     over->x = res;
 
+    over->overlay_is_packed_rgb =
+        ff_fill_rgba_map(over->overlay_rgba_map, inlink->format) >= 0;
+    over->overlay_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);
+
     av_log(ctx, AV_LOG_VERBOSE,
            "main w:%d h:%d fmt:%s overlay x:%d y:%d w:%d h:%d fmt:%s\n",
            ctx->inputs[MAIN]->w, ctx->inputs[MAIN]->h,
@@ -193,36 +284,98 @@
     return 0;
 }
 
-static void blend_frame(AVFilterContext *ctx,
+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)
+
+static void blend_slice(AVFilterContext *ctx,
                         AVFilterBufferRef *dst, AVFilterBufferRef *src,
-                        int x, int y)
+                        int x, int y, int w, int h,
+                        int slice_y, int slice_w, int slice_h)
 {
     OverlayContext *over = ctx->priv;
     int i, j, k;
     int width, height;
-    int overlay_end_y = y + src->video->h;
+    int overlay_end_y = y+h;
+    int slice_end_y = slice_y+slice_h;
     int end_y, start_y;
 
-    width = FFMIN(dst->video->w - x, src->video->w);
-    end_y = FFMIN(dst->video->h, overlay_end_y);
-    start_y = FFMAX(y, 0);
+    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;
 
-    if (dst->format == AV_PIX_FMT_BGR24 || dst->format == AV_PIX_FMT_RGB24) {
-        uint8_t *dp = dst->data[0] + x * 3 + start_y * dst->linesize[0];
+    if (over->main_is_packed_rgb) {
+        uint8_t *dp = dst->data[0] + x * over->main_pix_step[0] +
+                      start_y * dst->linesize[0];
         uint8_t *sp = src->data[0];
-        int b = dst->format == AV_PIX_FMT_BGR24 ? 2 : 0;
-        int r = dst->format == AV_PIX_FMT_BGR24 ? 0 : 2;
-        if (y < 0)
-            sp += -y * src->linesize[0];
+        uint8_t alpha;          ///< the amount of overlay to blend on to main
+        const int dr = over->main_rgba_map[R];
+        const int dg = over->main_rgba_map[G];
+        const int db = over->main_rgba_map[B];
+        const int da = over->main_rgba_map[A];
+        const int dstep = over->main_pix_step[0];
+        const int sr = over->overlay_rgba_map[R];
+        const int sg = over->overlay_rgba_map[G];
+        const int sb = over->overlay_rgba_map[B];
+        const int sa = over->overlay_rgba_map[A];
+        const int sstep = over->overlay_pix_step[0];
+        const int main_has_alpha = over->main_has_alpha;
+        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++) {
-                d[r] = (d[r] * (0xff - s[3]) + s[0] * s[3] + 128) >> 8;
-                d[1] = (d[1] * (0xff - s[3]) + s[1] * s[3] + 128) >> 8;
-                d[b] = (d[b] * (0xff - s[3]) + s[2] * s[3] + 128) >> 8;
-                d += 3;
-                s += 4;
+                alpha = s[sa];
+
+                // if the main channel has an alpha channel, alpha has to be calculated
+                // to create an un-premultiplied (straight) alpha value
+                if (main_has_alpha && alpha != 0 && alpha != 255) {
+                    // apply the general equation:
+                    // alpha = alpha_overlay / ( (alpha_main + alpha_overlay) - (alpha_main * alpha_overlay) )
+                    alpha =
+                        // the next line is a faster version of: 255 * 255 * alpha
+                        ( (alpha << 16) - (alpha << 9) + alpha )
+                        /
+                        // the next line is a faster version of: 255 * (alpha + d[da])
+                        ( ((alpha + d[da]) << 8 ) - (alpha + d[da])
+                          - d[da] * alpha );
+                }
+
+                switch (alpha) {
+                case 0:
+                    break;
+                case 255:
+                    d[dr] = s[sr];
+                    d[dg] = s[sg];
+                    d[db] = s[sb];
+                    break;
+                default:
+                    // main_value = main_value * (1 - alpha) + overlay_value * alpha
+                    // since alpha is in the range 0-255, the result must divided by 255
+                    d[dr] = FAST_DIV255(d[dr] * (255 - alpha) + s[sr] * alpha);
+                    d[dg] = FAST_DIV255(d[dg] * (255 - alpha) + s[sg] * alpha);
+                    d[db] = FAST_DIV255(d[db] * (255 - alpha) + s[sb] * alpha);
+                }
+                if (main_has_alpha) {
+                    switch (alpha) {
+                    case 0:
+                        break;
+                    case 255:
+                        d[da] = s[sa];
+                        break;
+                    default:
+                        // apply alpha compositing: main_alpha += (1-main_alpha) * overlay_alpha
+                        d[da] += FAST_DIV255((255 - d[da]) * s[sa]);
+                    }
+                }
+                d += dstep;
+                s += sstep;
             }
             dp += dst->linesize[0];
             sp += src->linesize[0];
@@ -237,9 +390,9 @@
             uint8_t *ap = src->data[3];
             int wp = FFALIGN(width, 1<<hsub) >> hsub;
             int hp = FFALIGN(height, 1<<vsub) >> vsub;
-            if (y < 0) {
-                sp += ((-y) >> vsub) * src->linesize[i];
-                ap += -y * src->linesize[3];
+            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;
@@ -257,7 +410,8 @@
                         alpha = (alpha_v + alpha_h) >> 1;
                     } else
                         alpha = a[0];
-                    *d = (*d * (0xff - alpha) + *s++ * alpha + 128) >> 8;
+                    *d = FAST_DIV255(*d * (255 - alpha) + *s * alpha);
+                    s++;
                     d++;
                     a += 1 << hsub;
                 }
@@ -269,8 +423,182 @@
     }
 }
 
-static int null_start_frame(AVFilterLink *inlink, AVFilterBufferRef *buf)
+static int try_start_frame(AVFilterContext *ctx, AVFilterBufferRef *mainpic)
 {
+    OverlayContext *over = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
+    AVFilterBufferRef *next_overpic, *outpicref;
+    int ret;
+
+    /* Discard obsolete overlay frames: if there is a next frame with pts is
+     * before the main frame, we can drop the current overlay. */
+    while (1) {
+        next_overpic = ff_bufqueue_peek(&over->queue_over, 0);
+        if (!next_overpic || av_compare_ts(next_overpic->pts, ctx->inputs[OVERLAY]->time_base,
+                                           mainpic->pts     , ctx->inputs[MAIN]->time_base) > 0)
+            break;
+        ff_bufqueue_get(&over->queue_over);
+        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));
+    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));
+    over->frame_requested = 0;
+    return ret;
+}
+
+static int try_start_next_frame(AVFilterContext *ctx)
+{
+    OverlayContext *over = ctx->priv;
+    AVFilterBufferRef *next_mainpic = ff_bufqueue_peek(&over->queue_main, 0);
+    int ret;
+
+    if (!next_mainpic)
+        return AVERROR(EAGAIN);
+    if ((ret = try_start_frame(ctx, next_mainpic)) == AVERROR(EAGAIN))
+        return ret;
+    avfilter_unref_buffer(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)));
+    return ret == AVERROR(EAGAIN) ? 0 : ret;
+}
+
+static int start_frame_main(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+{
+    AVFilterContext *ctx = inlink->dst;
+    OverlayContext *over = ctx->priv;
+    int ret;
+
+    if ((ret = flush_frames(ctx)) < 0)
+        return ret;
+    if ((ret = try_start_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)
+        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)
+{
+    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);
+    return ret == AVERROR(EAGAIN) ? 0 : ret;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    OverlayContext *over = ctx->priv;
+    int input, ret;
+
+    if (!try_push_frame(ctx))
+        return 0;
+    over->frame_requested = 1;
+    while (over->frame_requested) {
+        /* TODO if we had a frame duration, we could guess more accurately */
+        input = !over->overlay_eof && (over->queue_main.available ||
+                                       over->queue_over.available < 2) ?
+                OVERLAY : MAIN;
+        ret = ff_request_frame(ctx->inputs[input]);
+        /* EOF on main is reported immediately */
+        if (ret == AVERROR_EOF && input == OVERLAY) {
+            over->overlay_eof = 1;
+            if ((ret = try_start_next_frame(ctx)) != AVERROR(EAGAIN))
+                return ret;
+            ret = 0; /* continue requesting frames on main */
+        }
+        if (ret < 0)
+            return ret;
+    }
     return 0;
 }
 
@@ -279,123 +607,25 @@
     return 0;
 }
 
-static int end_frame_main(AVFilterLink *inlink)
-{
-    OverlayContext *s = inlink->dst->priv;
-
-    av_assert0(!s->main);
-    s->main         = inlink->cur_buf;
-    inlink->cur_buf = NULL;
-
-    return 0;
-}
-
-static int end_frame_overlay(AVFilterLink *inlink)
-{
-    OverlayContext *s = inlink->dst->priv;
-
-    av_assert0(!s->over_next);
-    s->over_next    = inlink->cur_buf;
-    inlink->cur_buf = NULL;
-
-    return 0;
-}
-
-static int output_frame(AVFilterContext *ctx)
-{
-    OverlayContext *s = ctx->priv;
-    AVFilterLink *outlink = ctx->outputs[0];
-    int ret = ff_start_frame(outlink, s->main);
-    if (ret >= 0)
-        ret = ff_draw_slice(outlink, 0, outlink->h, 1);
-    if (ret >= 0)
-        ret = ff_end_frame(outlink);
-    s->main = NULL;
-
-    return ret;
-}
-
-static int handle_overlay_eof(AVFilterContext *ctx)
-{
-    OverlayContext *s = ctx->priv;
-    if (s->over_prev)
-        blend_frame(ctx, s->main, s->over_prev, s->x, s->y);
-    return output_frame(ctx);
-}
-
-static int request_frame(AVFilterLink *outlink)
-{
-    AVFilterContext *ctx = outlink->src;
-    OverlayContext    *s = ctx->priv;
-    AVRational tb_main = ctx->inputs[MAIN]->time_base;
-    AVRational tb_over = ctx->inputs[OVERLAY]->time_base;
-    int ret = 0;
-
-    /* get a frame on the main input */
-    if (!s->main) {
-        ret = ff_request_frame(ctx->inputs[MAIN]);
-        if (ret < 0)
-            return ret;
-    }
-
-    /* get a new frame on the overlay input, on EOF
-     * reuse previous */
-    if (!s->over_next) {
-        ret = ff_request_frame(ctx->inputs[OVERLAY]);
-        if (ret == AVERROR_EOF)
-           return handle_overlay_eof(ctx);
-        else if (ret < 0)
-            return ret;
-    }
-
-    while (s->main->pts != AV_NOPTS_VALUE &&
-           s->over_next->pts != AV_NOPTS_VALUE &&
-           av_compare_ts(s->over_next->pts, tb_over, s->main->pts, tb_main) < 0) {
-        avfilter_unref_bufferp(&s->over_prev);
-        FFSWAP(AVFilterBufferRef*, s->over_prev, s->over_next);
-
-        ret = ff_request_frame(ctx->inputs[OVERLAY]);
-        if (ret == AVERROR_EOF)
-            return handle_overlay_eof(ctx);
-        else if (ret < 0)
-            return ret;
-    }
-
-    if (s->main->pts == AV_NOPTS_VALUE ||
-        s->over_next->pts == AV_NOPTS_VALUE ||
-        !av_compare_ts(s->over_next->pts, tb_over, s->main->pts, tb_main)) {
-        blend_frame(ctx, s->main, s->over_next, s->x, s->y);
-        avfilter_unref_bufferp(&s->over_prev);
-        FFSWAP(AVFilterBufferRef*, s->over_prev, s->over_next);
-    } else if (s->over_prev) {
-        blend_frame(ctx, s->main, s->over_prev, s->x, s->y);
-    }
-
-    return output_frame(ctx);
-}
-
 static const AVFilterPad avfilter_vf_overlay_inputs[] = {
     {
         .name         = "main",
         .type         = AVMEDIA_TYPE_VIDEO,
-        .start_frame  = null_start_frame,
+        .get_video_buffer= get_video_buffer,
         .config_props = config_input_main,
-        .draw_slice   = null_draw_slice,
+        .start_frame  = start_frame_main,
+        .draw_slice   = draw_slice_main,
         .end_frame    = end_frame_main,
-        .min_perms    = AV_PERM_READ,
-        .rej_perms    = AV_PERM_REUSE2 | AV_PERM_PRESERVE,
-        .needs_fifo   = 1,
+        .min_perms    = AV_PERM_READ | AV_PERM_WRITE | AV_PERM_PRESERVE,
     },
     {
         .name         = "overlay",
         .type         = AVMEDIA_TYPE_VIDEO,
-        .start_frame  = null_start_frame,
         .config_props = config_input_overlay,
+        .start_frame  = start_frame_over,
         .draw_slice   = null_draw_slice,
-        .end_frame    = end_frame_overlay,
-        .min_perms    = AV_PERM_READ,
-        .rej_perms    = AV_PERM_REUSE2,
-        .needs_fifo   = 1,
+        .end_frame    = end_frame_over,
+        .min_perms    = AV_PERM_READ | AV_PERM_PRESERVE,
     },
     { NULL }
 };
@@ -404,6 +634,7 @@
     {
         .name          = "default",
         .type          = AVMEDIA_TYPE_VIDEO,
+        .rej_perms     = AV_PERM_WRITE,
         .config_props  = config_output,
         .request_frame = request_frame,
     },
@@ -423,4 +654,5 @@
 
     .inputs    = avfilter_vf_overlay_inputs,
     .outputs   = avfilter_vf_overlay_outputs,
+    .priv_class = &overlay_class,
 };
diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c
index c14835d..059ca5b 100644
--- a/libavfilter/vf_pad.c
+++ b/libavfilter/vf_pad.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2008 vmrsss
  * Copyright (c) 2009 Stefano Sabatini
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -40,9 +40,6 @@
 #include "drawutils.h"
 
 static const char *const var_names[] = {
-    "PI",
-    "PHI",
-    "E",
     "in_w",   "iw",
     "in_h",   "ih",
     "out_w",  "ow",
@@ -50,15 +47,14 @@
     "x",
     "y",
     "a",
+    "sar",
+    "dar",
     "hsub",
     "vsub",
     NULL
 };
 
 enum var_name {
-    VAR_PI,
-    VAR_PHI,
-    VAR_E,
     VAR_IN_W,   VAR_IW,
     VAR_IN_H,   VAR_IH,
     VAR_OUT_W,  VAR_OW,
@@ -66,6 +62,8 @@
     VAR_X,
     VAR_Y,
     VAR_A,
+    VAR_SAR,
+    VAR_DAR,
     VAR_HSUB,
     VAR_VSUB,
     VARS_NB
@@ -73,22 +71,7 @@
 
 static int query_formats(AVFilterContext *ctx)
 {
-    static const 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_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_NONE
-    };
-
-    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0));
     return 0;
 }
 
@@ -102,10 +85,9 @@
     char x_expr[256];       ///< width  expression string
     char y_expr[256];       ///< height expression string
 
-    uint8_t color[4];       ///< color expressed either in YUVA or RGBA colorspace for the padding area
-    uint8_t *line[4];
-    int      line_step[4];
-    int hsub, vsub;         ///< chroma subsampling values
+    uint8_t rgba_color[4];  ///< color for the padding area
+    FFDrawContext draw;
+    FFDrawColor color;
     int needs_copy;
 } PadContext;
 
@@ -120,49 +102,36 @@
     av_strlcpy(pad->y_expr, "0" , sizeof(pad->h_expr));
 
     if (args)
-        sscanf(args, "%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255s",
+        sscanf(args, "%255[^:]:%255[^:]:%255[^:]:%255[^:]:%127s",
                pad->w_expr, pad->h_expr, pad->x_expr, pad->y_expr, color_string);
 
-    if (av_parse_color(pad->color, color_string, -1, ctx) < 0)
+    if (av_parse_color(pad->rgba_color, color_string, -1, ctx) < 0)
         return AVERROR(EINVAL);
 
     return 0;
 }
 
-static av_cold void uninit(AVFilterContext *ctx)
-{
-    PadContext *pad = ctx->priv;
-    int i;
-
-    for (i = 0; i < 4; i++) {
-        av_freep(&pad->line[i]);
-        pad->line_step[i] = 0;
-    }
-}
-
 static int config_input(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
     PadContext *pad = ctx->priv;
-    const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
-    uint8_t rgba_color[4];
-    int ret, is_packed_rgba;
+    int ret;
     double var_values[VARS_NB], res;
     char *expr;
 
-    pad->hsub = pix_desc->log2_chroma_w;
-    pad->vsub = pix_desc->log2_chroma_h;
+    ff_draw_init(&pad->draw, inlink->format, 0);
+    ff_draw_color(&pad->draw, &pad->color, pad->rgba_color);
 
-    var_values[VAR_PI]    = M_PI;
-    var_values[VAR_PHI]   = M_PHI;
-    var_values[VAR_E]     = M_E;
     var_values[VAR_IN_W]  = var_values[VAR_IW] = inlink->w;
     var_values[VAR_IN_H]  = var_values[VAR_IH] = inlink->h;
     var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN;
     var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN;
     var_values[VAR_A]     = (double) inlink->w / inlink->h;
-    var_values[VAR_HSUB]  = 1<<pad->hsub;
-    var_values[VAR_VSUB]  = 1<<pad->vsub;
+    var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ?
+        (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
+    var_values[VAR_DAR]   = var_values[VAR_A] * var_values[VAR_SAR];
+    var_values[VAR_HSUB]  = 1 << pad->draw.hsub_max;
+    var_values[VAR_VSUB]  = 1 << pad->draw.vsub_max;
 
     /* evaluate width and height */
     av_expr_parse_and_eval(&res, (expr = pad->w_expr),
@@ -209,22 +178,16 @@
     if (!pad->h)
         pad->h = inlink->h;
 
-    pad->w &= ~((1 << pad->hsub) - 1);
-    pad->h &= ~((1 << pad->vsub) - 1);
-    pad->x &= ~((1 << pad->hsub) - 1);
-    pad->y &= ~((1 << pad->vsub) - 1);
+    pad->w    = ff_draw_round_to_sub(&pad->draw, 0, -1, pad->w);
+    pad->h    = ff_draw_round_to_sub(&pad->draw, 1, -1, pad->h);
+    pad->x    = ff_draw_round_to_sub(&pad->draw, 0, -1, pad->x);
+    pad->y    = ff_draw_round_to_sub(&pad->draw, 1, -1, pad->y);
+    pad->in_w = ff_draw_round_to_sub(&pad->draw, 0, -1, inlink->w);
+    pad->in_h = ff_draw_round_to_sub(&pad->draw, 1, -1, inlink->h);
 
-    pad->in_w = inlink->w & ~((1 << pad->hsub) - 1);
-    pad->in_h = inlink->h & ~((1 << pad->vsub) - 1);
-
-    memcpy(rgba_color, pad->color, sizeof(rgba_color));
-    ff_fill_line_with_color(pad->line, pad->line_step, pad->w, pad->color,
-                            inlink->format, rgba_color, &is_packed_rgba, NULL);
-
-    av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d x:%d y:%d color:0x%02X%02X%02X%02X[%s]\n",
+    av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d x:%d y:%d color:0x%02X%02X%02X%02X\n",
            inlink->w, inlink->h, pad->w, pad->h, pad->x, pad->y,
-           pad->color[0], pad->color[1], pad->color[2], pad->color[3],
-           is_packed_rgba ? "rgba" : "yuva");
+           pad->rgba_color[0], pad->rgba_color[1], pad->rgba_color[2], pad->rgba_color[3]);
 
     if (pad->x <  0 || pad->y <  0                      ||
         pad->w <= 0 || pad->h <= 0                      ||
@@ -257,9 +220,10 @@
 static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int w, int h)
 {
     PadContext *pad = inlink->dst->priv;
+    int align = (perms&AV_PERM_ALIGN) ? AVFILTER_ALIGN : 1;
 
     AVFilterBufferRef *picref = ff_get_video_buffer(inlink->dst->outputs[0], perms,
-                                                    w + (pad->w - pad->in_w),
+                                                    w + (pad->w - pad->in_w) + 4*align,
                                                     h + (pad->h - pad->in_h));
     int plane;
 
@@ -269,13 +233,9 @@
     picref->video->w = w;
     picref->video->h = h;
 
-    for (plane = 0; plane < 4 && picref->data[plane]; plane++) {
-        int hsub = (plane == 1 || plane == 2) ? pad->hsub : 0;
-        int vsub = (plane == 1 || plane == 2) ? pad->vsub : 0;
-
-        picref->data[plane] += (pad->x >> hsub) * pad->line_step[plane] +
-            (pad->y >> vsub) * picref->linesize[plane];
-    }
+    for (plane = 0; plane < 4 && picref->data[plane]; plane++)
+        picref->data[plane] += FFALIGN(pad->x >> pad->draw.hsub[plane], align) * pad->draw.pixelstep[plane] +
+                                      (pad->y >> pad->draw.vsub[plane])        * picref->linesize[plane];
 
     return picref;
 }
@@ -285,12 +245,12 @@
     int64_t x_in_buf, y_in_buf;
 
     x_in_buf =  outpicref->data[plane] - outpicref->buf->data[plane]
-             +  (x >> hsub) * pad      ->line_step[plane]
-             +  (y >> vsub) * outpicref->linesize [plane];
+             +  (x >> hsub) * pad->draw.pixelstep[plane]
+             +  (y >> vsub) * outpicref->linesize[plane];
 
-    if(x_in_buf < 0 || x_in_buf % pad->line_step[plane])
+    if(x_in_buf < 0 || x_in_buf % pad->draw.pixelstep[plane])
         return 1;
-    x_in_buf /= pad->line_step[plane];
+    x_in_buf /= pad->draw.pixelstep[plane];
 
     av_assert0(outpicref->buf->linesize[plane]>0); //while reference can use negative linesize the main buffer should not
 
@@ -313,17 +273,17 @@
     if (!outpicref)
         return AVERROR(ENOMEM);
 
-    for (plane = 0; plane < 4 && outpicref->data[plane]; plane++) {
-        int hsub = (plane == 1 || plane == 2) ? pad->hsub : 0;
-        int vsub = (plane == 1 || plane == 2) ? pad->vsub : 0;
+    for (plane = 0; plane < 4 && outpicref->data[plane] && pad->draw.pixelstep[plane]; plane++) {
+        int hsub = pad->draw.hsub[plane];
+        int vsub = pad->draw.vsub[plane];
 
         av_assert0(outpicref->buf->w>0 && outpicref->buf->h>0);
 
         if(outpicref->format != outpicref->buf->format) //unsupported currently
             break;
 
-        outpicref->data[plane] -=   (pad->x  >> hsub) * pad      ->line_step[plane]
-                                  + (pad->y  >> vsub) * outpicref->linesize [plane];
+        outpicref->data[plane] -=   (pad->x  >> hsub) * pad->draw.pixelstep[plane]
+                                  + (pad->y  >> vsub) * outpicref->linesize[plane];
 
         if(   does_clip(pad, outpicref, plane, hsub, vsub, 0, 0)
            || does_clip(pad, outpicref, plane, hsub, vsub, 0, pad->h-1)
@@ -332,7 +292,7 @@
           )
             break;
     }
-    pad->needs_copy= plane < 4 && outpicref->data[plane];
+    pad->needs_copy= plane < 4 && outpicref->data[plane] || !(outpicref->perms & AV_PERM_WRITE);
     if(pad->needs_copy){
         av_log(inlink->dst, AV_LOG_DEBUG, "Direct padding impossible allocating new frame\n");
         avfilter_unref_buffer(outpicref);
@@ -366,11 +326,6 @@
     return ret;
 }
 
-static int end_frame(AVFilterLink *link)
-{
-    return ff_end_frame(link->dst->outputs[0]);
-}
-
 static int draw_send_bar_slice(AVFilterLink *link, int y, int h, int slice_dir, int before_slice)
 {
     PadContext *pad = link->dst->priv;
@@ -387,9 +342,9 @@
     }
 
     if (bar_h) {
-        ff_draw_rectangle(link->dst->outputs[0]->out_buf->data,
+        ff_fill_rectangle(&pad->draw, &pad->color,
+                          link->dst->outputs[0]->out_buf->data,
                           link->dst->outputs[0]->out_buf->linesize,
-                          pad->line, pad->line_step, pad->hsub, pad->vsub,
                           0, bar_y, pad->w, bar_h);
         ret = ff_draw_slice(link->dst->outputs[0], bar_y, bar_h, slice_dir);
     }
@@ -405,27 +360,26 @@
 
     y += pad->y;
 
-    y &= ~((1 << pad->vsub) - 1);
-    h &= ~((1 << pad->vsub) - 1);
+    y = ff_draw_round_to_sub(&pad->draw, 1, -1, y);
+    h = ff_draw_round_to_sub(&pad->draw, 1, -1, h);
 
     if (!h)
         return 0;
     draw_send_bar_slice(link, y, h, slice_dir, 1);
 
     /* left border */
-    ff_draw_rectangle(outpic->data, outpic->linesize, pad->line, pad->line_step,
-                      pad->hsub, pad->vsub, 0, y, pad->x, h);
+    ff_fill_rectangle(&pad->draw, &pad->color, outpic->data, outpic->linesize,
+                      0, y, pad->x, h);
 
     if(pad->needs_copy){
-        ff_copy_rectangle(outpic->data, outpic->linesize,
-                          inpic->data, inpic->linesize, pad->line_step,
-                          pad->hsub, pad->vsub,
-                          pad->x, y, y-pad->y, inpic->video->w, h);
+        ff_copy_rectangle2(&pad->draw,
+                           outpic->data, outpic->linesize,
+                           inpic ->data, inpic ->linesize,
+                           pad->x, y, 0, y - pad->y, inpic->video->w, h);
     }
 
     /* right border */
-    ff_draw_rectangle(outpic->data, outpic->linesize,
-                      pad->line, pad->line_step, pad->hsub, pad->vsub,
+    ff_fill_rectangle(&pad->draw, &pad->color, outpic->data, outpic->linesize,
                       pad->x + pad->in_w, y, pad->w - pad->x - pad->in_w, h);
     ret = ff_draw_slice(link->dst->outputs[0], y, h, slice_dir);
     if (ret < 0)
@@ -442,7 +396,6 @@
         .get_video_buffer = get_video_buffer,
         .start_frame      = start_frame,
         .draw_slice       = draw_slice,
-        .end_frame        = end_frame,
     },
     { NULL }
 };
@@ -462,7 +415,6 @@
 
     .priv_size     = sizeof(PadContext),
     .init          = init,
-    .uninit        = uninit,
     .query_formats = query_formats,
 
     .inputs    = avfilter_vf_pad_inputs,
diff --git a/libavfilter/vf_pixdesctest.c b/libavfilter/vf_pixdesctest.c
index 09decea..15380c9 100644
--- a/libavfilter/vf_pixdesctest.c
+++ b/libavfilter/vf_pixdesctest.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Stefano Sabatini
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -79,7 +79,7 @@
     /* copy palette */
     if (priv->pix_desc->flags & PIX_FMT_PAL ||
         priv->pix_desc->flags & PIX_FMT_PSEUDOPAL)
-        memcpy(outpicref->data[1], outpicref->data[1], 256*4);
+        memcpy(outpicref->data[1], picref->data[1], AVPALETTE_SIZE);
 
     for_next_filter = avfilter_ref_buffer(outpicref, ~0);
     if (for_next_filter)
@@ -110,7 +110,7 @@
 
         for (i = y1; i < y1 + h1; i++) {
             av_read_image_line(priv->line,
-                               inpic->data,
+                               (void*)inpic->data,
                                inpic->linesize,
                                priv->pix_desc,
                                0, i, c, w1, 0);
diff --git a/libavfilter/vf_removelogo.c b/libavfilter/vf_removelogo.c
new file mode 100644
index 0000000..1b02018
--- /dev/null
+++ b/libavfilter/vf_removelogo.c
@@ -0,0 +1,562 @@
+/*
+ * Copyright (c) 2005 Robert Edele <yartrebo@earthlink.net>
+ * Copyright (c) 2012 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
+ * Advanced blur-based logo removing filter
+ *
+ * This filter loads an image mask file showing where a logo is and
+ * uses a blur transform to remove the logo.
+ *
+ * Based on the libmpcodecs remove-logo filter by Robert Edele.
+ */
+
+/**
+ * This code implements a filter to remove annoying TV logos and other annoying
+ * images placed onto a video stream. It works by filling in the pixels that
+ * comprise the logo with neighboring pixels. The transform is very loosely
+ * based on a gaussian blur, but it is different enough to merit its own
+ * paragraph later on. It is a major improvement on the old delogo filter as it
+ * both uses a better blurring algorithm and uses a bitmap to use an arbitrary
+ * and generally much tighter fitting shape than a rectangle.
+ *
+ * The logo removal algorithm has two key points. The first is that it
+ * distinguishes between pixels in the logo and those not in the logo by using
+ * the passed-in bitmap. Pixels not in the logo are copied over directly without
+ * being modified and they also serve as source pixels for the logo
+ * fill-in. Pixels inside the logo have the mask applied.
+ *
+ * At init-time the bitmap is reprocessed internally, and the distance to the
+ * nearest edge of the logo (Manhattan distance), along with a little extra to
+ * remove rough edges, is stored in each pixel. This is done using an in-place
+ * erosion algorithm, and incrementing each pixel that survives any given
+ * erosion.  Once every pixel is eroded, the maximum value is recorded, and a
+ * set of masks from size 0 to this size are generaged. The masks are circular
+ * binary masks, where each pixel within a radius N (where N is the size of the
+ * mask) is a 1, and all other pixels are a 0. Although a gaussian mask would be
+ * more mathematically accurate, a binary mask works better in practice because
+ * we generally do not use the central pixels in the mask (because they are in
+ * the logo region), and thus a gaussian mask will cause too little blur and
+ * thus a very unstable image.
+ *
+ * The mask is applied in a special way. Namely, only pixels in the mask that
+ * line up to pixels outside the logo are used. The dynamic mask size means that
+ * the mask is just big enough so that the edges touch pixels outside the logo,
+ * so the blurring is kept to a minimum and at least the first boundary
+ * condition is met (that the image function itself is continuous), even if the
+ * second boundary condition (that the derivative of the image function is
+ * continuous) is not met. A masking algorithm that does preserve the second
+ * boundary coundition (perhaps something based on a highly-modified bi-cubic
+ * algorithm) should offer even better results on paper, but the noise in a
+ * typical TV signal should make anything based on derivatives hopelessly noisy.
+ */
+
+#include "libavutil/imgutils.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "video.h"
+#include "bbox.h"
+#include "lavfutils.h"
+#include "lswsutils.h"
+
+typedef struct {
+    /* Stores our collection of masks. The first is for an array of
+       the second for the y axis, and the third for the x axis. */
+    int ***mask;
+    int max_mask_size;
+    int mask_w, mask_h;
+
+    uint8_t      *full_mask_data;
+    FFBoundingBox full_mask_bbox;
+    uint8_t      *half_mask_data;
+    FFBoundingBox half_mask_bbox;
+} RemovelogoContext;
+
+/**
+ * Choose a slightly larger mask size to improve performance.
+ *
+ * This function maps the absolute minimum mask size needed to the
+ * mask size we'll actually use. f(x) = x (the smallest that will
+ * work) will produce the sharpest results, but will be quite
+ * jittery. f(x) = 1.25x (what I'm using) is a good tradeoff in my
+ * opinion. This will calculate only at init-time, so you can put a
+ * long expression here without effecting performance.
+ */
+#define apply_mask_fudge_factor(x) (((x) >> 2) + x)
+
+/**
+ * Pre-process an image to give distance information.
+ *
+ * This function takes a bitmap image and converts it in place into a
+ * distance image. A distance image is zero for pixels outside of the
+ * logo and is the Manhattan distance (|dx| + |dy|) from the logo edge
+ * for pixels inside of the logo. This will overestimate the distance,
+ * but that is safe, and is far easier to implement than a proper
+ * pythagorean distance since I'm using a modified erosion algorithm
+ * to compute the distances.
+ *
+ * @param mask image which will be converted from a greyscale image
+ * into a distance image.
+ */
+static void convert_mask_to_strength_mask(uint8_t *data, int linesize,
+                                          int w, int h, int min_val,
+                                          int *max_mask_size)
+{
+    int x, y;
+
+    /* How many times we've gone through the loop. Used in the
+       in-place erosion algorithm and to get us max_mask_size later on. */
+    int current_pass = 0;
+
+    /* set all non-zero values to 1 */
+    for (y = 0; y < h; y++)
+        for (x = 0; x < w; x++)
+            data[y*linesize + x] = data[y*linesize + x] > min_val;
+
+    /* For each pass, if a pixel is itself the same value as the
+       current pass, and its four neighbors are too, then it is
+       incremented. If no pixels are incremented by the end of the
+       pass, then we go again. Edge pixels are counted as always
+       excluded (this should be true anyway for any sane mask, but if
+       it isn't this will ensure that we eventually exit). */
+    while (1) {
+        /* If this doesn't get set by the end of this pass, then we're done. */
+        int has_anything_changed = 0;
+        uint8_t *current_pixel0 = data, *current_pixel;
+        current_pass++;
+
+        for (y = 1; y < h-1; y++) {
+            current_pixel = current_pixel0;
+            for (x = 1; x < w-1; x++) {
+                /* Apply the in-place erosion transform. It is based
+                   on the following two premises:
+                   1 - Any pixel that fails 1 erosion will fail all
+                       future erosions.
+
+                   2 - Only pixels having survived all erosions up to
+                       the present will be >= to current_pass.
+                   It doesn't matter if it survived the current pass,
+                   failed it, or hasn't been tested yet.  By using >=
+                   instead of ==, we allow the algorithm to work in
+                   place. */
+                if ( *current_pixel      >= current_pass &&
+                    *(current_pixel + 1) >= current_pass &&
+                    *(current_pixel - 1) >= current_pass &&
+                    *(current_pixel + w) >= current_pass &&
+                    *(current_pixel - w) >= current_pass) {
+                    /* Increment the value since it still has not been
+                     * eroded, as evidenced by the if statement that
+                     * just evaluated to true. */
+                    (*current_pixel)++;
+                    has_anything_changed = 1;
+                }
+                current_pixel++;
+            }
+            current_pixel0 += linesize;
+        }
+        if (!has_anything_changed)
+            break;
+    }
+
+    /* Apply the fudge factor, which will increase the size of the
+     * mask a little to reduce jitter at the cost of more blur. */
+    for (y = 1; y < h - 1; y++)
+        for (x = 1; x < w - 1; x++)
+            data[(y * linesize) + x] = apply_mask_fudge_factor(data[(y * linesize) + x]);
+
+    /* As a side-effect, we now know the maximum mask size, which
+     * we'll use to generate our masks. */
+    /* Apply the fudge factor to this number too, since we must ensure
+     * that enough masks are generated. */
+    *max_mask_size = apply_mask_fudge_factor(current_pass + 1);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    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;
+}
+
+static int load_mask(uint8_t **mask, int *w, int *h,
+                     const char *filename, void *log_ctx)
+{
+    int ret;
+    enum AVPixelFormat pix_fmt;
+    uint8_t *src_data[4], *gray_data[4];
+    int src_linesize[4], gray_linesize[4];
+
+    /* load image from file */
+    if ((ret = ff_load_image(src_data, src_linesize, w, h, &pix_fmt, filename, log_ctx)) < 0)
+        return ret;
+
+    /* convert the image to GRAY8 */
+    if ((ret = ff_scale_image(gray_data, gray_linesize, *w, *h, AV_PIX_FMT_GRAY8,
+                              src_data, src_linesize, *w, *h, pix_fmt,
+                              log_ctx)) < 0)
+        goto end;
+
+    /* copy mask to a newly allocated array */
+    *mask = av_malloc(*w * *h);
+    if (!*mask)
+        ret = AVERROR(ENOMEM);
+    av_image_copy_plane(*mask, *w, gray_data[0], gray_linesize[0], *w, *h);
+
+end:
+    av_free(src_data[0]);
+    av_free(gray_data[0]);
+    return ret;
+}
+
+/**
+ * Generate a scaled down image with half width, height, and intensity.
+ *
+ * This function not only scales down an image, but halves the value
+ * in each pixel too. The purpose of this is to produce a chroma
+ * filter image out of a luma filter image. The pixel values store the
+ * distance to the edge of the logo and halving the dimensions halves
+ * the distance. This function rounds up, because a downwards rounding
+ * error could cause the filter to fail, but an upwards rounding error
+ * will only cause a minor amount of excess blur in the chroma planes.
+ */
+static void generate_half_size_image(const uint8_t *src_data, int src_linesize,
+                                     uint8_t *dst_data, int dst_linesize,
+                                     int src_w, int src_h,
+                                     int *max_mask_size)
+{
+    int x, y;
+
+    /* Copy over the image data, using the average of 4 pixels for to
+     * calculate each downsampled pixel. */
+    for (y = 0; y < src_h/2; y++) {
+        for (x = 0; x < src_w/2; x++) {
+            /* Set the pixel if there exists a non-zero value in the
+             * source pixels, else clear it. */
+            dst_data[(y * dst_linesize) + x] =
+                src_data[((y << 1) * src_linesize) + (x << 1)] ||
+                src_data[((y << 1) * src_linesize) + (x << 1) + 1] ||
+                src_data[(((y << 1) + 1) * src_linesize) + (x << 1)] ||
+                src_data[(((y << 1) + 1) * src_linesize) + (x << 1) + 1];
+            dst_data[(y * dst_linesize) + x] = FFMIN(1, dst_data[(y * dst_linesize) + x]);
+        }
+    }
+
+    convert_mask_to_strength_mask(dst_data, dst_linesize,
+                                  src_w/2, src_h/2, 0, max_mask_size);
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    RemovelogoContext *removelogo = ctx->priv;
+    int ***mask;
+    int ret = 0;
+    int a, b, c, w, h;
+    int full_max_mask_size, half_max_mask_size;
+
+    if (!args) {
+        av_log(ctx, AV_LOG_ERROR, "An image file must be specified as argument\n");
+        return AVERROR(EINVAL);
+    }
+
+    /* Load our mask image. */
+    if ((ret = load_mask(&removelogo->full_mask_data, &w, &h, args, ctx)) < 0)
+        return ret;
+    removelogo->mask_w = w;
+    removelogo->mask_h = h;
+
+    convert_mask_to_strength_mask(removelogo->full_mask_data, w, w, h,
+                                  16, &full_max_mask_size);
+
+    /* Create the scaled down mask image for the chroma planes. */
+    if (!(removelogo->half_mask_data = av_mallocz(w/2 * h/2)))
+        return AVERROR(ENOMEM);
+    generate_half_size_image(removelogo->full_mask_data, w,
+                             removelogo->half_mask_data, w/2,
+                             w, h, &half_max_mask_size);
+
+    removelogo->max_mask_size = FFMAX(full_max_mask_size, half_max_mask_size);
+
+    /* Create a circular mask for each size up to max_mask_size. When
+       the filter is applied, the mask size is determined on a pixel
+       by pixel basis, with pixels nearer the edge of the logo getting
+       smaller mask sizes. */
+    mask = (int ***)av_malloc(sizeof(int **) * (removelogo->max_mask_size + 1));
+    if (!mask)
+        return AVERROR(ENOMEM);
+
+    for (a = 0; a <= removelogo->max_mask_size; a++) {
+        mask[a] = (int **)av_malloc(sizeof(int *) * ((a * 2) + 1));
+        if (!mask[a])
+            return AVERROR(ENOMEM);
+        for (b = -a; b <= a; b++) {
+            mask[a][b + a] = (int *)av_malloc(sizeof(int) * ((a * 2) + 1));
+            if (!mask[a][b + a])
+                return AVERROR(ENOMEM);
+            for (c = -a; c <= a; c++) {
+                if ((b * b) + (c * c) <= (a * a)) /* Circular 0/1 mask. */
+                    mask[a][b + a][c + a] = 1;
+                else
+                    mask[a][b + a][c + a] = 0;
+            }
+        }
+    }
+    removelogo->mask = mask;
+
+    /* Calculate our bounding rectangles, which determine in what
+     * region the logo resides for faster processing. */
+    ff_calculate_bounding_box(&removelogo->full_mask_bbox, removelogo->full_mask_data, w, w, h, 0);
+    ff_calculate_bounding_box(&removelogo->half_mask_bbox, removelogo->half_mask_data, w/2, w/2, h/2, 0);
+
+#define SHOW_LOGO_INFO(mask_type)                                       \
+    av_log(ctx, AV_LOG_VERBOSE, #mask_type " x1:%d x2:%d y1:%d y2:%d max_mask_size:%d\n", \
+           removelogo->mask_type##_mask_bbox.x1, removelogo->mask_type##_mask_bbox.x2, \
+           removelogo->mask_type##_mask_bbox.y1, removelogo->mask_type##_mask_bbox.y2, \
+           mask_type##_max_mask_size);
+    SHOW_LOGO_INFO(full);
+    SHOW_LOGO_INFO(half);
+
+    return 0;
+}
+
+static int config_props_input(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->dst;
+    RemovelogoContext *removelogo = ctx->priv;
+
+    if (inlink->w != removelogo->mask_w || inlink->h != removelogo->mask_h) {
+        av_log(ctx, AV_LOG_INFO,
+               "Mask image size %dx%d does not match with the input video size %dx%d\n",
+               removelogo->mask_w, removelogo->mask_h, inlink->w, inlink->h);
+        return AVERROR(EINVAL);
+    }
+
+    return 0;
+}
+
+/**
+ * Blur image.
+ *
+ * It takes a pixel that is inside the mask and blurs it. It does so
+ * by finding the average of all the pixels within the mask and
+ * outside of the mask.
+ *
+ * @param mask_data  the mask plane to use for averaging
+ * @param image_data the image plane to blur
+ * @param w width of the image
+ * @param h height of the image
+ * @param x x-coordinate of the pixel to blur
+ * @param y y-coordinate of the pixel to blur
+ */
+static unsigned int blur_pixel(int ***mask,
+                               const uint8_t *mask_data, int mask_linesize,
+                               uint8_t       *image_data, int image_linesize,
+                               int w, int h, int x, int y)
+{
+    /* Mask size tells how large a circle to use. The radius is about
+     * (slightly larger than) mask size. */
+    int mask_size;
+    int start_posx, start_posy, end_posx, end_posy;
+    int i, j;
+    unsigned int accumulator = 0, divisor = 0;
+    /* What pixel we are reading out of the circular blur mask. */
+    const uint8_t *image_read_position;
+    /* What pixel we are reading out of the filter image. */
+    const uint8_t *mask_read_position;
+
+    /* Prepare our bounding rectangle and clip it if need be. */
+    mask_size  = mask_data[y * mask_linesize + x];
+    start_posx = FFMAX(0, x - mask_size);
+    start_posy = FFMAX(0, y - mask_size);
+    end_posx   = FFMIN(w - 1, x + mask_size);
+    end_posy   = FFMIN(h - 1, y + mask_size);
+
+    image_read_position = image_data + image_linesize * start_posy + start_posx;
+    mask_read_position  = mask_data  + mask_linesize  * start_posy + start_posx;
+
+    for (j = start_posy; j <= end_posy; j++) {
+        for (i = start_posx; i <= end_posx; i++) {
+            /* Check if this pixel is in the mask or not. Only use the
+             * pixel if it is not. */
+            if (!(*mask_read_position) && mask[mask_size][i - start_posx][j - start_posy]) {
+                accumulator += *image_read_position;
+                divisor++;
+            }
+
+            image_read_position++;
+            mask_read_position++;
+        }
+
+        image_read_position += (image_linesize - ((end_posx + 1) - start_posx));
+        mask_read_position  += (mask_linesize - ((end_posx + 1) - start_posx));
+    }
+
+    /* If divisor is 0, it means that not a single pixel is outside of
+       the logo, so we have no data.  Else we need to normalise the
+       data using the divisor. */
+    return divisor == 0 ? 255:
+        (accumulator + (divisor / 2)) / divisor;  /* divide, taking into account average rounding error */
+}
+
+/**
+ * Blur image plane using a mask.
+ *
+ * @param source The image to have it's logo removed.
+ * @param destination Where the output image will be stored.
+ * @param source_stride How far apart (in memory) two consecutive lines are.
+ * @param destination Same as source_stride, but for the destination image.
+ * @param width Width of the image. This is the same for source and destination.
+ * @param height Height of the image. This is the same for source and destination.
+ * @param is_image_direct If the image is direct, then source and destination are
+ *        the same and we can save a lot of time by not copying pixels that
+ *        haven't changed.
+ * @param filter The image that stores the distance to the edge of the logo for
+ *        each pixel.
+ * @param logo_start_x smallest x-coordinate that contains at least 1 logo pixel.
+ * @param logo_start_y smallest y-coordinate that contains at least 1 logo pixel.
+ * @param logo_end_x   largest x-coordinate that contains at least 1 logo pixel.
+ * @param logo_end_y   largest y-coordinate that contains at least 1 logo pixel.
+ *
+ * This function processes an entire plane. Pixels outside of the logo are copied
+ * to the output without change, and pixels inside the logo have the de-blurring
+ * function applied.
+ */
+static void blur_image(int ***mask,
+                       const uint8_t *src_data,  int src_linesize,
+                             uint8_t *dst_data,  int dst_linesize,
+                       const uint8_t *mask_data, int mask_linesize,
+                       int w, int h, int direct,
+                       FFBoundingBox *bbox)
+{
+    int x, y;
+    uint8_t *dst_line;
+    const uint8_t *src_line;
+
+    if (!direct)
+        av_image_copy_plane(dst_data, dst_linesize, src_data, src_linesize, w, h);
+
+    for (y = bbox->y1; y <= bbox->y2; y++) {
+        src_line = src_data + src_linesize * y;
+        dst_line = dst_data + dst_linesize * y;
+
+        for (x = bbox->x1; x <= bbox->x2; x++) {
+             if (mask_data[y * mask_linesize + x]) {
+                /* Only process if we are in the mask. */
+                 dst_line[x] = blur_pixel(mask,
+                                          mask_data, mask_linesize,
+                                          dst_data, dst_linesize,
+                                          w, h, x, y);
+            } else {
+                /* Else just copy the data. */
+                if (!direct)
+                    dst_line[x] = src_line[x];
+            }
+        }
+    }
+}
+
+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)
+{
+    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;
+
+    blur_image(removelogo->mask,
+               inpicref ->data[0], inpicref ->linesize[0],
+               outpicref->data[0], outpicref->linesize[0],
+               removelogo->full_mask_data, inlink->w,
+               inlink->w, inlink->h, direct, &removelogo->full_mask_bbox);
+    blur_image(removelogo->mask,
+               inpicref ->data[1], inpicref ->linesize[1],
+               outpicref->data[1], outpicref->linesize[1],
+               removelogo->half_mask_data, inlink->w/2,
+               inlink->w/2, inlink->h/2, direct, &removelogo->half_mask_bbox);
+    blur_image(removelogo->mask,
+               inpicref ->data[2], inpicref ->linesize[2],
+               outpicref->data[2], outpicref->linesize[2],
+               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);
+}
+
+static void uninit(AVFilterContext *ctx)
+{
+    RemovelogoContext *removelogo = ctx->priv;
+    int a, b;
+
+    av_freep(&removelogo->full_mask_data);
+    av_freep(&removelogo->half_mask_data);
+
+    if (removelogo->mask) {
+        /* Loop through each mask. */
+        for (a = 0; a <= removelogo->max_mask_size; a++) {
+            /* Loop through each scanline in a mask. */
+            for (b = -a; b <= a; b++) {
+                av_free(removelogo->mask[a][b + a]); /* Free a scanline. */
+            }
+            av_free(removelogo->mask[a]);
+        }
+        /* Free the array of pointers pointing to the masks. */
+        av_freep(&removelogo->mask);
+    }
+}
+
+static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { return 0; }
+
+AVFilter avfilter_vf_removelogo = {
+    .name          = "removelogo",
+    .description   = NULL_IF_CONFIG_SMALL("Remove a TV logo based on a mask image."),
+    .priv_size     = sizeof(RemovelogoContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+
+    .inputs = (const AVFilterPad[]) {
+        { .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 },
+        { .name = NULL }
+    },
+    .outputs = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_VIDEO, },
+        { .name = NULL }
+    },
+};
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index cbc1081..bc7f20c 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,33 +36,31 @@
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/avassert.h"
 #include "libswscale/swscale.h"
 
 static const char *const var_names[] = {
-    "PI",
-    "PHI",
-    "E",
     "in_w",   "iw",
     "in_h",   "ih",
     "out_w",  "ow",
     "out_h",  "oh",
-    "a", "dar",
+    "a",
     "sar",
+    "dar",
     "hsub",
     "vsub",
     NULL
 };
 
 enum var_name {
-    VAR_PI,
-    VAR_PHI,
-    VAR_E,
     VAR_IN_W,   VAR_IW,
     VAR_IN_H,   VAR_IH,
     VAR_OUT_W,  VAR_OW,
     VAR_OUT_H,  VAR_OH,
-    VAR_A, VAR_DAR,
+    VAR_A,
     VAR_SAR,
+    VAR_DAR,
     VAR_HSUB,
     VAR_VSUB,
     VARS_NB
@@ -70,6 +68,7 @@
 
 typedef struct {
     struct SwsContext *sws;     ///< software scaler context
+    struct SwsContext *isws[2]; ///< software scaler context for interlaced material
 
     /**
      * New dimensions. Special values are:
@@ -82,6 +81,8 @@
     int hsub, vsub;             ///< chroma subsampling
     int slice_y;                ///< top of current output slice
     int input_is_pal;           ///< set to 1 if the input format is paletted
+    int output_is_pal;          ///< set to 1 if the output format is paletted
+    int interlaced;
 
     char w_expr[256];           ///< width  expression string
     char h_expr[256];           ///< height expression string
@@ -108,6 +109,10 @@
             if (ret < 0)
                 return ret;
         }
+        if(strstr(args,"interl=1")){
+            scale->interlaced=1;
+        }else if(strstr(args,"interl=-1"))
+            scale->interlaced=-1;
     }
 
     return 0;
@@ -117,6 +122,8 @@
 {
     ScaleContext *scale = ctx->priv;
     sws_freeContext(scale->sws);
+    sws_freeContext(scale->isws[0]);
+    sws_freeContext(scale->isws[1]);
     scale->sws = NULL;
 }
 
@@ -139,7 +146,7 @@
     if (ctx->outputs[0]) {
         formats = NULL;
         for (pix_fmt = 0; pix_fmt < AV_PIX_FMT_NB; pix_fmt++)
-            if (    sws_isSupportedOutput(pix_fmt)
+            if (   (sws_isSupportedOutput(pix_fmt) || pix_fmt == AV_PIX_FMT_PAL8)
                 && (ret = ff_add_format(&formats, pix_fmt)) < 0) {
                 ff_formats_unref(&formats);
                 return ret;
@@ -154,6 +161,7 @@
 {
     AVFilterContext *ctx = outlink->src;
     AVFilterLink *inlink = outlink->src->inputs[0];
+    enum AVPixelFormat outfmt = outlink->format;
     ScaleContext *scale = ctx->priv;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
     int64_t w, h;
@@ -161,16 +169,14 @@
     char *expr;
     int ret;
 
-    var_values[VAR_PI]    = M_PI;
-    var_values[VAR_PHI]   = M_PHI;
-    var_values[VAR_E]     = M_E;
     var_values[VAR_IN_W]  = var_values[VAR_IW] = inlink->w;
     var_values[VAR_IN_H]  = var_values[VAR_IH] = inlink->h;
     var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN;
     var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN;
-    var_values[VAR_DAR]   = var_values[VAR_A]  = (double) inlink->w / inlink->h;
+    var_values[VAR_A]     = (double) inlink->w / inlink->h;
     var_values[VAR_SAR]   = inlink->sample_aspect_ratio.num ?
         (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1;
+    var_values[VAR_DAR]   = var_values[VAR_A] * var_values[VAR_SAR];
     var_values[VAR_HSUB]  = 1 << desc->log2_chroma_w;
     var_values[VAR_VSUB]  = 1 << desc->log2_chroma_h;
 
@@ -220,13 +226,12 @@
     outlink->h = h;
 
     /* TODO: make algorithm configurable */
-    av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d fmt:%s -> w:%d h:%d fmt:%s flags:0x%0x\n",
-           inlink ->w, inlink ->h, av_get_pix_fmt_name(inlink->format),
-           outlink->w, outlink->h, av_get_pix_fmt_name(outlink->format),
-           scale->flags);
 
     scale->input_is_pal = desc->flags & PIX_FMT_PAL ||
                           desc->flags & PIX_FMT_PSEUDOPAL;
+    if (outfmt == AV_PIX_FMT_PAL8) outfmt = AV_PIX_FMT_BGR8;
+    scale->output_is_pal = av_pix_fmt_desc_get(outfmt)->flags & PIX_FMT_PAL ||
+                           av_pix_fmt_desc_get(outfmt)->flags & PIX_FMT_PSEUDOPAL;
 
     if (scale->sws)
         sws_freeContext(scale->sws);
@@ -235,25 +240,40 @@
         scale->sws = NULL;
     else {
         scale->sws = sws_getContext(inlink ->w, inlink ->h, inlink ->format,
-                                    outlink->w, outlink->h, outlink->format,
+                                    outlink->w, outlink->h, outfmt,
                                     scale->flags, NULL, NULL, NULL);
-        if (!scale->sws)
+        if (scale->isws[0])
+            sws_freeContext(scale->isws[0]);
+        scale->isws[0] = sws_getContext(inlink ->w, inlink ->h/2, inlink ->format,
+                                        outlink->w, outlink->h/2, outfmt,
+                                        scale->flags, NULL, NULL, NULL);
+        if (scale->isws[1])
+            sws_freeContext(scale->isws[1]);
+        scale->isws[1] = sws_getContext(inlink ->w, inlink ->h/2, inlink ->format,
+                                        outlink->w, outlink->h/2, outfmt,
+                                        scale->flags, NULL, NULL, NULL);
+        if (!scale->sws || !scale->isws[0] || !scale->isws[1])
             return AVERROR(EINVAL);
     }
 
-
-    if (inlink->sample_aspect_ratio.num)
-        outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h*inlink->w,
-                                                             outlink->w*inlink->h},
-                                                inlink->sample_aspect_ratio);
-    else
+    if (inlink->sample_aspect_ratio.num){
+        outlink->sample_aspect_ratio = av_mul_q((AVRational){outlink->h * inlink->w, outlink->w * inlink->h}, inlink->sample_aspect_ratio);
+    } else
         outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
 
+    av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d fmt:%s sar:%d/%d -> w:%d h:%d fmt:%s sar:%d/%d flags:0x%0x\n",
+           inlink ->w, inlink ->h, av_get_pix_fmt_name( inlink->format),
+           inlink->sample_aspect_ratio.num, inlink->sample_aspect_ratio.den,
+           outlink->w, outlink->h, av_get_pix_fmt_name(outlink->format),
+           outlink->sample_aspect_ratio.num, outlink->sample_aspect_ratio.den,
+           scale->flags);
     return 0;
 
 fail:
     av_log(NULL, AV_LOG_ERROR,
-           "Error when evaluating the expression '%s'\n", expr);
+           "Error when evaluating the expression '%s'.\n"
+           "Maybe the expression for out_w:'%s' or for out_h:'%s' is self-referencing.\n",
+           expr, scale->w_expr, scale->h_expr);
     return ret;
 }
 
@@ -265,6 +285,22 @@
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
     int ret = 0;
 
+    if(   picref->video->w != link->w
+       || picref->video->h != link->h
+       || picref->format   != link->format) {
+        int ret;
+        snprintf(scale->w_expr, sizeof(scale->w_expr)-1, "%d", outlink->w);
+        snprintf(scale->h_expr, sizeof(scale->h_expr)-1, "%d", outlink->h);
+
+        link->dst->inputs[0]->format = picref->format;
+        link->dst->inputs[0]->w      = picref->video->w;
+        link->dst->inputs[0]->h      = picref->video->h;
+
+        if ((ret = config_props(outlink)) < 0)
+            av_assert0(0); //what to do here ?
+    }
+
+
     if (!scale->sws) {
         outpicref = avfilter_ref_buffer(picref, ~0);
         if (!outpicref)
@@ -275,7 +311,7 @@
     scale->hsub = desc->log2_chroma_w;
     scale->vsub = desc->log2_chroma_h;
 
-    outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+    outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_ALIGN, outlink->w, outlink->h);
     if (!outpicref)
         return AVERROR(ENOMEM);
 
@@ -283,10 +319,12 @@
     outpicref->video->w = outlink->w;
     outpicref->video->h = outlink->h;
 
+    if(scale->output_is_pal)
+        ff_set_systematic_pal2((uint32_t*)outpicref->data[1], outlink->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : outlink->format);
 
-    av_reduce(&outpicref->video->pixel_aspect.num, &outpicref->video->pixel_aspect.den,
-              (int64_t)picref->video->pixel_aspect.num * outlink->h * link->w,
-              (int64_t)picref->video->pixel_aspect.den * outlink->w * link->h,
+    av_reduce(&outpicref->video->sample_aspect_ratio.num, &outpicref->video->sample_aspect_ratio.den,
+              (int64_t)picref->video->sample_aspect_ratio.num * outlink->h * link->w,
+              (int64_t)picref->video->sample_aspect_ratio.den * outlink->w * link->h,
               INT_MAX);
 
     scale->slice_y = 0;
@@ -305,12 +343,36 @@
     return 0;
 }
 
+static int scale_slice(AVFilterLink *link, struct SwsContext *sws, int y, int h, int mul, int field)
+{
+    ScaleContext *scale = link->dst->priv;
+    AVFilterBufferRef *cur_pic = link->cur_buf;
+    AVFilterBufferRef *out_buf = link->dst->outputs[0]->out_buf;
+    const uint8_t *in[4];
+    uint8_t *out[4];
+    int in_stride[4],out_stride[4];
+    int i;
+
+    for(i=0; i<4; i++){
+        int vsub= ((i+1)&2) ? scale->vsub : 0;
+         in_stride[i] = cur_pic->linesize[i] * mul;
+        out_stride[i] = out_buf->linesize[i] * mul;
+         in[i] = cur_pic->data[i] + ((y>>vsub)+field) * cur_pic->linesize[i];
+        out[i] = out_buf->data[i] +            field  * out_buf->linesize[i];
+    }
+    if(scale->input_is_pal)
+         in[1] = cur_pic->data[1];
+    if(scale->output_is_pal)
+        out[1] = out_buf->data[1];
+
+    return sws_scale(sws, in, in_stride, y/mul, h,
+                         out,out_stride);
+}
+
 static int draw_slice(AVFilterLink *link, int y, int h, int slice_dir)
 {
     ScaleContext *scale = link->dst->priv;
     int out_h, ret;
-    AVFilterBufferRef *cur_pic = link->cur_buf;
-    const uint8_t *data[4];
 
     if (!scale->sws) {
         return ff_draw_slice(link->dst->outputs[0], y, h, slice_dir);
@@ -319,16 +381,13 @@
     if (scale->slice_y == 0 && slice_dir == -1)
         scale->slice_y = link->dst->outputs[0]->h;
 
-    data[0] = cur_pic->data[0] +  y               * cur_pic->linesize[0];
-    data[1] = scale->input_is_pal ?
-              cur_pic->data[1] :
-              cur_pic->data[1] + (y>>scale->vsub) * cur_pic->linesize[1];
-    data[2] = cur_pic->data[2] + (y>>scale->vsub) * cur_pic->linesize[2];
-    data[3] = cur_pic->data[3] +  y               * cur_pic->linesize[3];
-
-    out_h = sws_scale(scale->sws, data, cur_pic->linesize, y, h,
-                      link->dst->outputs[0]->out_buf->data,
-                      link->dst->outputs[0]->out_buf->linesize);
+    if(scale->interlaced>0 || (scale->interlaced<0 && link->cur_buf->video->interlaced)){
+        av_assert0(y%(2<<scale->vsub) == 0);
+        out_h = scale_slice(link, scale->isws[0], y, (h+1)/2, 2, 0);
+        out_h+= scale_slice(link, scale->isws[1], y,  h   /2, 2, 1);
+    }else{
+        out_h = scale_slice(link, scale->sws, y, h, 1, 0);
+    }
 
     if (slice_dir == -1)
         scale->slice_y -= out_h;
diff --git a/libavfilter/vf_select.c b/libavfilter/vf_select.c
index 25c6a14..143e8cc 100644
--- a/libavfilter/vf_select.c
+++ b/libavfilter/vf_select.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2011 Stefano Sabatini
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,16 +26,16 @@
 #include "libavutil/eval.h"
 #include "libavutil/fifo.h"
 #include "libavutil/internal.h"
-#include "libavutil/mathematics.h"
 #include "avfilter.h"
+#include "formats.h"
 #include "internal.h"
 #include "video.h"
 
-static const char *const var_names[] = {
-    "E",                 ///< Euler number
-    "PHI",               ///< golden ratio
-    "PI",                ///< greek pi
+#if CONFIG_AVCODEC
+#include "libavcodec/dsputil.h"
+#endif
 
+static const char *const var_names[] = {
     "TB",                ///< timebase
 
     "pts",               ///< original pts in the file of the frame
@@ -69,14 +69,12 @@
     "key",               ///< tell if the frame is a key frame
     "pos",               ///< original position in the file of the frame
 
+    "scene",
+
     NULL
 };
 
 enum var_name {
-    VAR_E,
-    VAR_PHI,
-    VAR_PI,
-
     VAR_TB,
 
     VAR_PTS,
@@ -110,6 +108,8 @@
     VAR_KEY,
     VAR_POS,
 
+    VAR_SCENE,
+
     VAR_VARS_NB
 };
 
@@ -118,6 +118,13 @@
 typedef struct {
     AVExpr *expr;
     double var_values[VAR_VARS_NB];
+    int do_scene_detect;            ///< 1 if the expression requires scene detection variables, 0 otherwise
+#if CONFIG_AVCODEC
+    AVCodecContext *avctx;          ///< codec context required for the DSPContext (scene detect only)
+    DSPContext c;                   ///< context providing optimized SAD methods   (scene detect only)
+    double prev_mafd;               ///< previous MAFD                             (scene detect only)
+#endif
+    AVFilterBufferRef *prev_picref; ///< previous frame                            (scene detect only)
     double select;
     int cache_frames;
     AVFifoBuffer *pending_frames; ///< FIFO buffer of video frames
@@ -139,6 +146,12 @@
         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;
 }
 
@@ -150,10 +163,6 @@
 {
     SelectContext *select = inlink->dst->priv;
 
-    select->var_values[VAR_E]   = M_E;
-    select->var_values[VAR_PHI] = M_PHI;
-    select->var_values[VAR_PI]  = M_PI;
-
     select->var_values[VAR_N]          = 0.0;
     select->var_values[VAR_SELECTED_N] = 0.0;
 
@@ -173,11 +182,53 @@
 
     select->var_values[VAR_INTERLACE_TYPE_P] = INTERLACE_TYPE_P;
     select->var_values[VAR_INTERLACE_TYPE_T] = INTERLACE_TYPE_T;
-    select->var_values[VAR_INTERLACE_TYPE_B] = INTERLACE_TYPE_B;;
+    select->var_values[VAR_INTERLACE_TYPE_B] = INTERLACE_TYPE_B;
 
+    if (CONFIG_AVCODEC && select->do_scene_detect) {
+        select->avctx = avcodec_alloc_context3(NULL);
+        if (!select->avctx)
+            return AVERROR(ENOMEM);
+        dsputil_init(&select->c, select->avctx);
+    }
     return 0;
 }
 
+#if CONFIG_AVCODEC
+static double get_scene_score(AVFilterContext *ctx, AVFilterBufferRef *picref)
+{
+    double ret = 0;
+    SelectContext *select = ctx->priv;
+    AVFilterBufferRef *prev_picref = select->prev_picref;
+
+    if (prev_picref &&
+        picref->video->h    == prev_picref->video->h &&
+        picref->video->w    == prev_picref->video->w &&
+        picref->linesize[0] == prev_picref->linesize[0]) {
+        int x, y;
+        int64_t sad;
+        double mafd, diff;
+        uint8_t *p1 =      picref->data[0];
+        uint8_t *p2 = prev_picref->data[0];
+        const int linesize = picref->linesize[0];
+
+        for (sad = y = 0; y < picref->video->h; y += 8)
+            for (x = 0; x < linesize; x += 8)
+                sad += select->c.sad[1](select,
+                                        p1 + y * linesize + x,
+                                        p2 + y * linesize + x,
+                                        linesize, 8);
+        emms_c();
+        mafd = sad / (picref->video->h * picref->video->w * 3);
+        diff = fabs(mafd - select->prev_mafd);
+        ret  = av_clipf(FFMIN(mafd, diff) / 100., 0, 1);
+        select->prev_mafd = mafd;
+        avfilter_unref_buffer(prev_picref);
+    }
+    select->prev_picref = avfilter_ref_buffer(picref, ~0);
+    return ret;
+}
+#endif
+
 #define D2TS(d)  (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
 #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
 
@@ -187,6 +238,8 @@
     AVFilterLink *inlink = ctx->inputs[0];
     double res;
 
+    if (CONFIG_AVCODEC && select->do_scene_detect)
+        select->var_values[VAR_SCENE] = get_scene_score(ctx, picref);
     if (isnan(select->var_values[VAR_START_PTS]))
         select->var_values[VAR_START_PTS] = TS2D(picref->pts);
     if (isnan(select->var_values[VAR_START_T]))
@@ -338,6 +391,30 @@
         avfilter_unref_buffer(picref);
     av_fifo_free(select->pending_frames);
     select->pending_frames = NULL;
+
+    if (select->do_scene_detect) {
+        avfilter_unref_bufferp(&select->prev_picref);
+        if (select->avctx) {
+            avcodec_close(select->avctx);
+            av_freep(&select->avctx);
+        }
+    }
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    SelectContext *select = ctx->priv;
+
+    if (!select->do_scene_detect) {
+        return ff_default_query_formats(ctx);
+    } else {
+        static const enum AVPixelFormat pix_fmts[] = {
+            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 const AVFilterPad avfilter_vf_select_inputs[] = {
@@ -345,6 +422,7 @@
         .name             = "default",
         .type             = AVMEDIA_TYPE_VIDEO,
         .get_video_buffer = ff_null_get_video_buffer,
+        .min_perms        = AV_PERM_PRESERVE,
         .config_props     = config_input,
         .start_frame      = start_frame,
         .draw_slice       = draw_slice,
@@ -368,6 +446,7 @@
     .description = NULL_IF_CONFIG_SMALL("Select frames to pass in output."),
     .init      = init,
     .uninit    = uninit,
+    .query_formats = query_formats,
 
     .priv_size = sizeof(SelectContext),
 
diff --git a/libavfilter/vf_setfield.c b/libavfilter/vf_setfield.c
new file mode 100644
index 0000000..93d30c7
--- /dev/null
+++ b/libavfilter/vf_setfield.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2012 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
+ * set field order
+ */
+
+#include "avfilter.h"
+#include "video.h"
+
+enum SetFieldMode {
+    MODE_AUTO = -1,
+    MODE_BFF,
+    MODE_TFF,
+    MODE_PROG,
+};
+
+typedef struct {
+    enum SetFieldMode mode;
+} SetFieldContext;
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    SetFieldContext *setfield = ctx->priv;
+
+    setfield->mode = MODE_AUTO;
+
+    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;
+}
+
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
+{
+    SetFieldContext *setfield = inlink->dst->priv;
+    AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
+
+    if (setfield->mode == MODE_PROG) {
+        outpicref->video->interlaced = 0;
+    } else if (setfield->mode != MODE_AUTO) {
+        outpicref->video->interlaced = 1;
+        outpicref->video->top_field_first = setfield->mode;
+    }
+    return ff_start_frame(inlink->dst->outputs[0], outpicref);
+}
+
+AVFilter avfilter_vf_setfield = {
+    .name      = "setfield",
+    .description = NULL_IF_CONFIG_SMALL("Force field for the output video frame."),
+    .init      = init,
+
+    .priv_size = sizeof(SetFieldContext),
+
+    .inputs = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_VIDEO,
+          .get_video_buffer = ff_null_get_video_buffer,
+          .start_frame      = start_frame, },
+        { .name = NULL }
+    },
+    .outputs = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_VIDEO, },
+        { .name = NULL }
+    },
+};
diff --git a/libavfilter/vf_setpts.c b/libavfilter/vf_setpts.c
deleted file mode 100644
index f2b86a1..0000000
--- a/libavfilter/vf_setpts.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2010 Stefano Sabatini
- * Copyright (c) 2008 Victor Paesa
- *
- * 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
- * video presentation timestamp (PTS) modification filter
- */
-
-/* #define DEBUG */
-
-#include "libavutil/eval.h"
-#include "libavutil/internal.h"
-#include "libavutil/mathematics.h"
-#include "avfilter.h"
-#include "internal.h"
-#include "video.h"
-
-static const char *const var_names[] = {
-    "E",           ///< Euler number
-    "INTERLACED",  ///< tell if the current frame is interlaced
-    "N",           ///< frame number (starting at zero)
-    "PHI",         ///< golden ratio
-    "PI",          ///< greek pi
-    "POS",         ///< original position in the file of the frame
-    "PREV_INPTS",  ///< previous  input PTS
-    "PREV_OUTPTS", ///< previous output PTS
-    "PTS",         ///< original pts in the file of the frame
-    "STARTPTS",   ///< PTS at start of movie
-    "TB",          ///< timebase
-    NULL
-};
-
-enum var_name {
-    VAR_E,
-    VAR_INTERLACED,
-    VAR_N,
-    VAR_PHI,
-    VAR_PI,
-    VAR_POS,
-    VAR_PREV_INPTS,
-    VAR_PREV_OUTPTS,
-    VAR_PTS,
-    VAR_STARTPTS,
-    VAR_TB,
-    VAR_VARS_NB
-};
-
-typedef struct {
-    AVExpr *expr;
-    double var_values[VAR_VARS_NB];
-} SetPTSContext;
-
-static av_cold int init(AVFilterContext *ctx, const char *args)
-{
-    SetPTSContext *setpts = ctx->priv;
-    int ret;
-
-    if ((ret = av_expr_parse(&setpts->expr, args ? args : "PTS",
-                             var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error while parsing expression '%s'\n", args);
-        return ret;
-    }
-
-    setpts->var_values[VAR_E          ] = M_E;
-    setpts->var_values[VAR_N          ] = 0.0;
-    setpts->var_values[VAR_PHI        ] = M_PHI;
-    setpts->var_values[VAR_PI         ] = M_PI;
-    setpts->var_values[VAR_PREV_INPTS ] = NAN;
-    setpts->var_values[VAR_PREV_OUTPTS] = NAN;
-    setpts->var_values[VAR_STARTPTS   ] = NAN;
-    return 0;
-}
-
-static int config_input(AVFilterLink *inlink)
-{
-    SetPTSContext *setpts = inlink->dst->priv;
-
-    setpts->var_values[VAR_TB] = av_q2d(inlink->time_base);
-
-    av_log(inlink->src, AV_LOG_VERBOSE, "TB:%f\n", setpts->var_values[VAR_TB]);
-    return 0;
-}
-
-#define D2TS(d)  (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
-#define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
-
-static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref)
-{
-    SetPTSContext *setpts = inlink->dst->priv;
-    double d;
-    AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
-
-    if (!outpicref)
-        return AVERROR(ENOMEM);
-
-    if (isnan(setpts->var_values[VAR_STARTPTS]))
-        setpts->var_values[VAR_STARTPTS] = TS2D(inpicref->pts);
-
-    setpts->var_values[VAR_INTERLACED] = inpicref->video->interlaced;
-    setpts->var_values[VAR_PTS       ] = TS2D(inpicref->pts);
-    setpts->var_values[VAR_POS       ] = inpicref->pos == -1 ? NAN : inpicref->pos;
-
-    d = av_expr_eval(setpts->expr, setpts->var_values, NULL);
-    outpicref->pts = D2TS(d);
-
-#ifdef DEBUG
-    av_log(inlink->dst, AV_LOG_DEBUG,
-           "n:%"PRId64" interlaced:%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],
-           inpicref ->pos,
-           inpicref ->pts, inpicref ->pts * av_q2d(inlink->time_base),
-           outpicref->pts, outpicref->pts * av_q2d(inlink->time_base));
-#endif
-
-    setpts->var_values[VAR_N] += 1.0;
-    setpts->var_values[VAR_PREV_INPTS ] = TS2D(inpicref ->pts);
-    setpts->var_values[VAR_PREV_OUTPTS] = TS2D(outpicref->pts);
-    return ff_start_frame(inlink->dst->outputs[0], outpicref);
-}
-
-static av_cold void uninit(AVFilterContext *ctx)
-{
-    SetPTSContext *setpts = ctx->priv;
-    av_expr_free(setpts->expr);
-    setpts->expr = NULL;
-}
-
-static const AVFilterPad avfilter_vf_setpts_inputs[] = {
-    {
-        .name             = "default",
-        .type             = AVMEDIA_TYPE_VIDEO,
-        .get_video_buffer = ff_null_get_video_buffer,
-        .config_props     = config_input,
-        .start_frame      = start_frame,
-    },
-    { NULL }
-};
-
-static const AVFilterPad avfilter_vf_setpts_outputs[] = {
-    {
-        .name = "default",
-        .type = AVMEDIA_TYPE_VIDEO,
-    },
-    { NULL }
-};
-
-AVFilter avfilter_vf_setpts = {
-    .name      = "setpts",
-    .description = NULL_IF_CONFIG_SMALL("Set PTS for the output video frame."),
-    .init      = init,
-    .uninit    = uninit,
-
-    .priv_size = sizeof(SetPTSContext),
-
-    .inputs    = avfilter_vf_setpts_inputs,
-    .outputs   = avfilter_vf_setpts_outputs,
-};
diff --git a/libavfilter/vf_settb.c b/libavfilter/vf_settb.c
deleted file mode 100644
index 0b68b34..0000000
--- a/libavfilter/vf_settb.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 2010 Stefano Sabatini
- *
- * 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
- * Set timebase for the output link.
- */
-
-#include <inttypes.h>
-#include <stdio.h>
-
-#include "libavutil/avstring.h"
-#include "libavutil/eval.h"
-#include "libavutil/internal.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/rational.h"
-#include "avfilter.h"
-#include "internal.h"
-#include "video.h"
-
-static const char *const var_names[] = {
-    "E",
-    "PHI",
-    "PI",
-    "AVTB",   /* default timebase 1/AV_TIME_BASE */
-    "intb",   /* input timebase */
-    NULL
-};
-
-enum var_name {
-    VAR_E,
-    VAR_PHI,
-    VAR_PI,
-    VAR_AVTB,
-    VAR_INTB,
-    VAR_VARS_NB
-};
-
-typedef struct {
-    char tb_expr[256];
-    double var_values[VAR_VARS_NB];
-} SetTBContext;
-
-static av_cold int init(AVFilterContext *ctx, const char *args)
-{
-    SetTBContext *settb = ctx->priv;
-    av_strlcpy(settb->tb_expr, "intb", sizeof(settb->tb_expr));
-
-    if (args)
-        sscanf(args, "%255[^:]", settb->tb_expr);
-
-    return 0;
-}
-
-static int config_output_props(AVFilterLink *outlink)
-{
-    AVFilterContext *ctx = outlink->src;
-    SetTBContext *settb = ctx->priv;
-    AVFilterLink *inlink = ctx->inputs[0];
-    AVRational time_base;
-    int ret;
-    double res;
-
-    settb->var_values[VAR_E]    = M_E;
-    settb->var_values[VAR_PHI]  = M_PHI;
-    settb->var_values[VAR_PI]   = M_PI;
-    settb->var_values[VAR_AVTB] = av_q2d(AV_TIME_BASE_Q);
-    settb->var_values[VAR_INTB] = av_q2d(inlink->time_base);
-
-    outlink->w = inlink->w;
-    outlink->h = inlink->h;
-
-    if ((ret = av_expr_parse_and_eval(&res, settb->tb_expr, var_names, settb->var_values,
-                                      NULL, NULL, NULL, NULL, NULL, 0, NULL)) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid expression '%s' for timebase.\n", settb->tb_expr);
-        return ret;
-    }
-    time_base = av_d2q(res, INT_MAX);
-    if (time_base.num <= 0 || time_base.den <= 0) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Invalid non-positive values for the timebase num:%d or den:%d.\n",
-               time_base.num, time_base.den);
-        return AVERROR(EINVAL);
-    }
-
-    outlink->time_base = time_base;
-    av_log(outlink->src, AV_LOG_VERBOSE, "tb:%d/%d -> tb:%d/%d\n",
-           inlink ->time_base.num, inlink ->time_base.den,
-           outlink->time_base.num, outlink->time_base.den);
-
-    return 0;
-}
-
-static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
-{
-    AVFilterContext *ctx = inlink->dst;
-    AVFilterLink *outlink = ctx->outputs[0];
-
-    if (av_cmp_q(inlink->time_base, outlink->time_base)) {
-        int64_t orig_pts = picref->pts;
-        picref->pts = av_rescale_q(picref->pts, inlink->time_base, outlink->time_base);
-        av_log(ctx, AV_LOG_DEBUG, "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n",
-               inlink ->time_base.num, inlink ->time_base.den, orig_pts,
-               outlink->time_base.num, outlink->time_base.den, picref->pts);
-    }
-    inlink->cur_buf = NULL;
-
-    return ff_start_frame(outlink, picref);
-}
-
-static const AVFilterPad avfilter_vf_settb_inputs[] = {
-    {
-        .name             = "default",
-        .type             = AVMEDIA_TYPE_VIDEO,
-        .get_video_buffer = ff_null_get_video_buffer,
-        .start_frame      = start_frame,
-        .end_frame        = ff_null_end_frame
-    },
-    { NULL }
-};
-
-static const AVFilterPad avfilter_vf_settb_outputs[] = {
-    {
-        .name         = "default",
-        .type         = AVMEDIA_TYPE_VIDEO,
-        .config_props = config_output_props,
-    },
-    { NULL }
-};
-
-AVFilter avfilter_vf_settb = {
-    .name      = "settb",
-    .description = NULL_IF_CONFIG_SMALL("Set timebase for the output link."),
-    .init      = init,
-
-    .priv_size = sizeof(SetTBContext),
-
-    .inputs    = avfilter_vf_settb_inputs,
-
-    .outputs   = avfilter_vf_settb_outputs,
-};
diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c
index 4b78276..297e8f1 100644
--- a/libavfilter/vf_showinfo.c
+++ b/libavfilter/vf_showinfo.c
@@ -1,19 +1,19 @@
 /*
  * Copyright (c) 2011 Stefano Sabatini
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,6 +26,7 @@
 #include "libavutil/imgutils.h"
 #include "libavutil/internal.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/timestamp.h"
 #include "avfilter.h"
 #include "internal.h"
 #include "video.h"
@@ -63,19 +64,23 @@
     }
 
     av_log(ctx, AV_LOG_INFO,
-           "n:%d pts:%"PRId64" pts_time:%f pos:%"PRId64" "
+           "n:%d pts:%s pts_time:%s pos:%"PRId64" "
            "fmt:%s sar:%d/%d s:%dx%d i:%c iskey:%d type:%c "
-           "checksum:%u plane_checksum:[%u %u %u %u]\n",
+           "checksum:%08X plane_checksum:[%08X",
            showinfo->frame,
-           picref->pts, picref->pts * av_q2d(inlink->time_base), picref->pos,
+           av_ts2str(picref->pts), av_ts2timestr(picref->pts, &inlink->time_base), picref->pos,
            desc->name,
-           picref->video->pixel_aspect.num, picref->video->pixel_aspect.den,
+           picref->video->sample_aspect_ratio.num, picref->video->sample_aspect_ratio.den,
            picref->video->w, picref->video->h,
            !picref->video->interlaced     ? 'P' :         /* Progressive  */
            picref->video->top_field_first ? 'T' : 'B',    /* Top / Bottom */
            picref->video->key_frame,
            av_get_picture_type_char(picref->video->pict_type),
-           checksum, plane_checksum[0], plane_checksum[1], plane_checksum[2], plane_checksum[3]);
+           checksum, plane_checksum[0]);
+
+    for (plane = 1; picref->data[plane] && plane < 4; plane++)
+        av_log(ctx, AV_LOG_INFO, " %08X", plane_checksum[plane]);
+    av_log(ctx, AV_LOG_INFO, "]\n");
 
     showinfo->frame++;
     return ff_end_frame(inlink->dst->outputs[0]);
diff --git a/libavfilter/vf_slicify.c b/libavfilter/vf_slicify.c
index f81ab0d..d010cc5 100644
--- a/libavfilter/vf_slicify.c
+++ b/libavfilter/vf_slicify.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavfilter/vf_smartblur.c b/libavfilter/vf_smartblur.c
new file mode 100644
index 0000000..e1f27ec
--- /dev/null
+++ b/libavfilter/vf_smartblur.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2012 Jeremy Tran
+ *
+ * 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
+ * Apply a smartblur filter to the input video
+ * Ported from MPlayer libmpcodecs/vf_smartblur.c by Michael Niedermayer.
+ */
+
+#include "libavutil/pixdesc.h"
+#include "libswscale/swscale.h"
+
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+
+#define RADIUS_MIN 0.1
+#define RADIUS_MAX 5.0
+
+#define STRENGTH_MIN -1.0
+#define STRENGTH_MAX 1.0
+
+#define THRESHOLD_MIN -30
+#define THRESHOLD_MAX 30
+
+typedef struct {
+    float              radius;
+    float              strength;
+    int                threshold;
+    float              quality;
+    struct SwsContext *filter_context;
+} FilterParam;
+
+typedef struct {
+    FilterParam  luma;
+    FilterParam  chroma;
+    int          hsub;
+    int          vsub;
+    unsigned int sws_flags;
+} SmartblurContext;
+
+#define CHECK_PARAM(param, name, min, max, format, ret)                       \
+    if (param < min || param > max) {                                         \
+        av_log(ctx, AV_LOG_ERROR,                                             \
+               "Invalid " #name " value " #format ": "                        \
+               "must be included between range " #format " and " #format "\n",\
+               param, min, max);                                              \
+        ret = AVERROR(EINVAL);                                                \
+    }
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    SmartblurContext *sblur = ctx->priv;
+    int n = 0, ret = 0;
+    float lradius, lstrength, cradius, cstrength;
+    int lthreshold, cthreshold;
+
+    if (args)
+        n = sscanf(args, "%f:%f:%d:%f:%f:%d",
+                   &lradius, &lstrength, &lthreshold,
+                   &cradius, &cstrength, &cthreshold);
+
+    if (n != 3 && n != 6) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Incorrect number of parameters or invalid syntax: "
+               "must be luma_radius:luma_strength:luma_threshold"
+               "[:chroma_radius:chroma_strength:chroma_threshold]\n");
+        return AVERROR(EINVAL);
+    }
+
+    sblur->luma.radius    = lradius;
+    sblur->luma.strength  = lstrength;
+    sblur->luma.threshold = lthreshold;
+
+    if (n == 3) {
+        sblur->chroma.radius    = sblur->luma.radius;
+        sblur->chroma.strength  = sblur->luma.strength;
+        sblur->chroma.threshold = sblur->luma.threshold;
+    } else {
+        sblur->chroma.radius    = cradius;
+        sblur->chroma.strength  = cstrength;
+        sblur->chroma.threshold = cthreshold;
+    }
+
+    sblur->luma.quality = sblur->chroma.quality = 3.0;
+    sblur->sws_flags = SWS_BICUBIC;
+
+    CHECK_PARAM(lradius,    luma radius,    RADIUS_MIN,    RADIUS_MAX,    %0.1f, ret)
+    CHECK_PARAM(lstrength,  luma strength,  STRENGTH_MIN,  STRENGTH_MAX,  %0.1f, ret)
+    CHECK_PARAM(lthreshold, luma threshold, THRESHOLD_MIN, THRESHOLD_MAX, %d,    ret)
+
+    if (n != 3) {
+        CHECK_PARAM(sblur->chroma.radius,    chroma radius,    RADIUS_MIN,   RADIUS_MAX,    %0.1f, ret)
+        CHECK_PARAM(sblur->chroma.strength,  chroma strength,  STRENGTH_MIN, STRENGTH_MAX,  %0.1f, ret)
+        CHECK_PARAM(sblur->chroma.threshold, chroma threshold, THRESHOLD_MIN,THRESHOLD_MAX, %d,    ret)
+    }
+
+    return ret;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    SmartblurContext *sblur = ctx->priv;
+
+    sws_freeContext(sblur->luma.filter_context);
+    sws_freeContext(sblur->chroma.filter_context);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_YUV444P,      AV_PIX_FMT_YUV422P,
+        AV_PIX_FMT_YUV420P,      AV_PIX_FMT_YUV411P,
+        AV_PIX_FMT_YUV410P,      AV_PIX_FMT_YUV440P,
+        AV_PIX_FMT_GRAY8,
+        AV_PIX_FMT_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+
+    return 0;
+}
+
+static int alloc_sws_context(FilterParam *f, int width, int height, unsigned int flags)
+{
+    SwsVector *vec;
+    SwsFilter sws_filter;
+
+    vec = sws_getGaussianVec(f->radius, f->quality);
+
+    if (!vec)
+        return AVERROR(EINVAL);
+
+    sws_scaleVec(vec, f->strength);
+    vec->coeff[vec->length / 2] += 1.0 - f->strength;
+    sws_filter.lumH = sws_filter.lumV = vec;
+    sws_filter.chrH = sws_filter.chrV = NULL;
+    f->filter_context = sws_getCachedContext(NULL,
+                                             width, height, AV_PIX_FMT_GRAY8,
+                                             width, height, AV_PIX_FMT_GRAY8,
+                                             flags, &sws_filter, NULL, NULL);
+
+    sws_freeVec(vec);
+
+    if (!f->filter_context)
+        return AVERROR(EINVAL);
+
+    return 0;
+}
+
+static int config_props(AVFilterLink *inlink)
+{
+    SmartblurContext *sblur = inlink->dst->priv;
+    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[inlink->format];
+
+    sblur->hsub = desc->log2_chroma_w;
+    sblur->vsub = desc->log2_chroma_h;
+
+    alloc_sws_context(&sblur->luma, inlink->w, inlink->h, sblur->sws_flags);
+    alloc_sws_context(&sblur->chroma,
+                      inlink->w >> sblur->hsub, inlink->h >> sblur->vsub,
+                      sblur->sws_flags);
+
+    return 0;
+}
+
+static void blur(uint8_t       *dst, const int dst_linesize,
+                 const uint8_t *src, const int src_linesize,
+                 const int w, const int h, const int threshold,
+                 struct SwsContext *filter_context)
+{
+    int x, y;
+    int orig, filtered;
+    int diff;
+    /* Declare arrays of 4 to get aligned data */
+    const uint8_t* const src_array[4] = {src};
+    uint8_t *dst_array[4]             = {dst};
+    int src_linesize_array[4] = {src_linesize};
+    int dst_linesize_array[4] = {dst_linesize};
+
+    sws_scale(filter_context, src_array, src_linesize_array,
+              0, h, dst_array, dst_linesize_array);
+
+    if (threshold > 0) {
+        for (y = 0; y < h; ++y) {
+            for (x = 0; x < w; ++x) {
+                orig     = src[x + y * src_linesize];
+                filtered = dst[x + y * dst_linesize];
+                diff     = orig - filtered;
+
+                if (diff > 0) {
+                    if (diff > 2 * threshold)
+                        dst[x + y * dst_linesize] = orig;
+                    else if (diff > threshold)
+                        /* add 'diff' and substract 'threshold' from 'filtered' */
+                        dst[x + y * dst_linesize] = orig - threshold;
+                } else {
+                    if (-diff > 2 * threshold)
+                        dst[x + y * dst_linesize] = orig;
+                    else if (-diff > threshold)
+                        /* add 'diff' and 'threshold' to 'filtered' */
+                        dst[x + y * dst_linesize] = orig + threshold;
+                }
+            }
+        }
+    } else if (threshold < 0) {
+        for (y = 0; y < h; ++y) {
+            for (x = 0; x < w; ++x) {
+                orig     = src[x + y * src_linesize];
+                filtered = dst[x + y * dst_linesize];
+                diff     = orig - filtered;
+
+                if (diff > 0) {
+                    if (diff <= -threshold)
+                        dst[x + y * dst_linesize] = orig;
+                    else if (diff <= -2 * threshold)
+                        /* substract 'diff' and 'threshold' from 'orig' */
+                        dst[x + y * dst_linesize] = filtered - threshold;
+                } else {
+                    if (diff >= threshold)
+                        dst[x + y * dst_linesize] = orig;
+                    else if (diff >= 2 * threshold)
+                        /* add 'threshold' and substract 'diff' from 'orig' */
+                        dst[x + y * dst_linesize] = filtered + threshold;
+                }
+            }
+        }
+    }
+}
+
+static int end_frame(AVFilterLink *inlink)
+{
+    SmartblurContext  *sblur  = inlink->dst->priv;
+    AVFilterBufferRef *inpic  = inlink->cur_buf;
+    AVFilterBufferRef *outpic = inlink->dst->outputs[0]->out_buf;
+    int cw = inlink->w >> sblur->hsub;
+    int ch = inlink->h >> sblur->vsub;
+
+    blur(outpic->data[0], outpic->linesize[0],
+         inpic->data[0],  inpic->linesize[0],
+         inlink->w, inlink->h, sblur->luma.threshold,
+         sblur->luma.filter_context);
+
+    if (inpic->data[2]) {
+        blur(outpic->data[1], outpic->linesize[1],
+             inpic->data[1],  inpic->linesize[1],
+             cw, ch, sblur->chroma.threshold,
+             sblur->chroma.filter_context);
+        blur(outpic->data[2], outpic->linesize[2],
+             inpic->data[2],  inpic->linesize[2],
+             cw, ch, sblur->chroma.threshold,
+             sblur->chroma.filter_context);
+    }
+
+    return ff_end_frame(inlink->dst->outputs[0]);
+}
+
+AVFilter avfilter_vf_smartblur = {
+    .name        = "smartblur",
+    .description = NULL_IF_CONFIG_SMALL("Blur the input video without impacting the outlines."),
+
+    .priv_size = sizeof(SmartblurContext),
+
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+
+    .inputs = (const AVFilterPad[]) {
+        {
+            .name         = "default",
+            .type         = AVMEDIA_TYPE_VIDEO,
+            .end_frame    = end_frame,
+            .config_props = config_props,
+            .min_perms    = AV_PERM_READ,
+        },
+        { .name = NULL }
+    },
+    .outputs = (const AVFilterPad[]) {
+        {
+            .name         = "default",
+            .type         = AVMEDIA_TYPE_VIDEO,
+        },
+        { .name = NULL }
+    }
+};
diff --git a/libavfilter/vf_super2xsai.c b/libavfilter/vf_super2xsai.c
new file mode 100644
index 0000000..f85674c
--- /dev/null
+++ b/libavfilter/vf_super2xsai.c
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2010 Niel van der Westhuizen <nielkie@gmail.com>
+ * Copyright (c) 2002 A'rpi
+ * Copyright (c) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com )
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * @file
+ * Super 2xSaI video filter
+ * Ported from MPlayer libmpcodecs/vf_2xsai.c.
+ */
+
+#include "libavutil/pixdesc.h"
+#include "libavutil/intreadwrite.h"
+#include "avfilter.h"
+#include "formats.h"
+#include "video.h"
+
+typedef struct {
+    /* masks used for two pixels interpolation */
+    uint32_t hi_pixel_mask;
+    uint32_t lo_pixel_mask;
+
+    /* masks used for four pixels interpolation */
+    uint32_t q_hi_pixel_mask;
+    uint32_t q_lo_pixel_mask;
+
+    int bpp; ///< bytes per pixel, pixel stride for each (packed) pixel
+    int is_be;
+} Super2xSaIContext;
+
+#define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D))
+
+#define INTERPOLATE(A, B) (((A & hi_pixel_mask) >> 1) + ((B & hi_pixel_mask) >> 1) + (A & B & lo_pixel_mask))
+
+#define Q_INTERPOLATE(A, B, C, D) ((A & q_hi_pixel_mask) >> 2) + ((B & q_hi_pixel_mask) >> 2) + ((C & q_hi_pixel_mask) >> 2) + ((D & q_hi_pixel_mask) >> 2) \
+    + ((((A & q_lo_pixel_mask) + (B & q_lo_pixel_mask) + (C & q_lo_pixel_mask) + (D & q_lo_pixel_mask)) >> 2) & q_lo_pixel_mask)
+
+static void super2xsai(AVFilterContext *ctx,
+                       uint8_t *src, int src_linesize,
+                       uint8_t *dst, int dst_linesize,
+                       int width, int height)
+{
+    Super2xSaIContext *sai = ctx->priv;
+    unsigned int x, y;
+    uint32_t color[4][4];
+    unsigned char *src_line[4];
+    const int bpp = sai->bpp;
+    const uint32_t hi_pixel_mask = sai->hi_pixel_mask;
+    const uint32_t lo_pixel_mask = sai->lo_pixel_mask;
+    const uint32_t q_hi_pixel_mask = sai->q_hi_pixel_mask;
+    const uint32_t q_lo_pixel_mask = sai->q_lo_pixel_mask;
+
+    /* Point to the first 4 lines, first line is duplicated */
+    src_line[0] = src;
+    src_line[1] = src;
+    src_line[2] = src + src_linesize*FFMIN(1, height-1);
+    src_line[3] = src + src_linesize*FFMIN(2, height-1);
+
+#define READ_COLOR4(dst, src_line, off) dst = *((const uint32_t *)src_line + off)
+#define READ_COLOR3(dst, src_line, off) dst = AV_RL24 (src_line + 3*off)
+#define READ_COLOR2(dst, src_line, off) dst = sai->is_be ? AV_RB16(src_line + 2 * off) : AV_RL16(src_line + 2 * off)
+
+    for (y = 0; y < height; y++) {
+        uint8_t *dst_line[2];
+
+        dst_line[0] = dst + dst_linesize*2*y;
+        dst_line[1] = dst + dst_linesize*(2*y+1);
+
+        switch (bpp) {
+        case 4:
+            READ_COLOR4(color[0][0], src_line[0], 0); color[0][1] = color[0][0]; READ_COLOR4(color[0][2], src_line[0], 1); READ_COLOR4(color[0][3], src_line[0], 2);
+            READ_COLOR4(color[1][0], src_line[1], 0); color[1][1] = color[1][0]; READ_COLOR4(color[1][2], src_line[1], 1); READ_COLOR4(color[1][3], src_line[1], 2);
+            READ_COLOR4(color[2][0], src_line[2], 0); color[2][1] = color[2][0]; READ_COLOR4(color[2][2], src_line[2], 1); READ_COLOR4(color[2][3], src_line[2], 2);
+            READ_COLOR4(color[3][0], src_line[3], 0); color[3][1] = color[3][0]; READ_COLOR4(color[3][2], src_line[3], 1); READ_COLOR4(color[3][3], src_line[3], 2);
+            break;
+        case 3:
+            READ_COLOR3(color[0][0], src_line[0], 0); color[0][1] = color[0][0]; READ_COLOR3(color[0][2], src_line[0], 1); READ_COLOR3(color[0][3], src_line[0], 2);
+            READ_COLOR3(color[1][0], src_line[1], 0); color[1][1] = color[1][0]; READ_COLOR3(color[1][2], src_line[1], 1); READ_COLOR3(color[1][3], src_line[1], 2);
+            READ_COLOR3(color[2][0], src_line[2], 0); color[2][1] = color[2][0]; READ_COLOR3(color[2][2], src_line[2], 1); READ_COLOR3(color[2][3], src_line[2], 2);
+            READ_COLOR3(color[3][0], src_line[3], 0); color[3][1] = color[3][0]; READ_COLOR3(color[3][2], src_line[3], 1); READ_COLOR3(color[3][3], src_line[3], 2);
+            break;
+        default:
+            READ_COLOR2(color[0][0], src_line[0], 0); color[0][1] = color[0][0]; READ_COLOR2(color[0][2], src_line[0], 1); READ_COLOR2(color[0][3], src_line[0], 2);
+            READ_COLOR2(color[1][0], src_line[1], 0); color[1][1] = color[1][0]; READ_COLOR2(color[1][2], src_line[1], 1); READ_COLOR2(color[1][3], src_line[1], 2);
+            READ_COLOR2(color[2][0], src_line[2], 0); color[2][1] = color[2][0]; READ_COLOR2(color[2][2], src_line[2], 1); READ_COLOR2(color[2][3], src_line[2], 2);
+            READ_COLOR2(color[3][0], src_line[3], 0); color[3][1] = color[3][0]; READ_COLOR2(color[3][2], src_line[3], 1); READ_COLOR2(color[3][3], src_line[3], 2);
+        }
+
+        for (x = 0; x < width; x++) {
+            uint32_t product1a, product1b, product2a, product2b;
+
+//---------------------------------------  B0 B1 B2 B3    0  1  2  3
+//                                         4  5* 6  S2 -> 4  5* 6  7
+//                                         1  2  3  S1    8  9 10 11
+//                                         A0 A1 A2 A3   12 13 14 15
+//--------------------------------------
+            if (color[2][1] == color[1][2] && color[1][1] != color[2][2]) {
+                product2b = color[2][1];
+                product1b = product2b;
+            } else if (color[1][1] == color[2][2] && color[2][1] != color[1][2]) {
+                product2b = color[1][1];
+                product1b = product2b;
+            } else if (color[1][1] == color[2][2] && color[2][1] == color[1][2]) {
+                int r = 0;
+
+                r += GET_RESULT(color[1][2], color[1][1], color[1][0], color[3][1]);
+                r += GET_RESULT(color[1][2], color[1][1], color[2][0], color[0][1]);
+                r += GET_RESULT(color[1][2], color[1][1], color[3][2], color[2][3]);
+                r += GET_RESULT(color[1][2], color[1][1], color[0][2], color[1][3]);
+
+                if (r > 0)
+                    product1b = color[1][2];
+                else if (r < 0)
+                    product1b = color[1][1];
+                else
+                    product1b = INTERPOLATE(color[1][1], color[1][2]);
+
+                product2b = product1b;
+            } else {
+                if (color[1][2] == color[2][2] && color[2][2] == color[3][1] && color[2][1] != color[3][2] && color[2][2] != color[3][0])
+                    product2b = Q_INTERPOLATE(color[2][2], color[2][2], color[2][2], color[2][1]);
+                else if (color[1][1] == color[2][1] && color[2][1] == color[3][2] && color[3][1] != color[2][2] && color[2][1] != color[3][3])
+                    product2b = Q_INTERPOLATE(color[2][1], color[2][1], color[2][1], color[2][2]);
+                else
+                    product2b = INTERPOLATE(color[2][1], color[2][2]);
+
+                if (color[1][2] == color[2][2] && color[1][2] == color[0][1] && color[1][1] != color[0][2] && color[1][2] != color[0][0])
+                    product1b = Q_INTERPOLATE(color[1][2], color[1][2], color[1][2], color[1][1]);
+                else if (color[1][1] == color[2][1] && color[1][1] == color[0][2] && color[0][1] != color[1][2] && color[1][1] != color[0][3])
+                    product1b = Q_INTERPOLATE(color[1][2], color[1][1], color[1][1], color[1][1]);
+                else
+                    product1b = INTERPOLATE(color[1][1], color[1][2]);
+            }
+
+            if (color[1][1] == color[2][2] && color[2][1] != color[1][2] && color[1][0] == color[1][1] && color[1][1] != color[3][2])
+                product2a = INTERPOLATE(color[2][1], color[1][1]);
+            else if (color[1][1] == color[2][0] && color[1][2] == color[1][1] && color[1][0] != color[2][1] && color[1][1] != color[3][0])
+                product2a = INTERPOLATE(color[2][1], color[1][1]);
+            else
+                product2a = color[2][1];
+
+            if (color[2][1] == color[1][2] && color[1][1] != color[2][2] && color[2][0] == color[2][1] && color[2][1] != color[0][2])
+                product1a = INTERPOLATE(color[2][1], color[1][1]);
+            else if (color[1][0] == color[2][1] && color[2][2] == color[2][1] && color[2][0] != color[1][1] && color[2][1] != color[0][0])
+                product1a = INTERPOLATE(color[2][1], color[1][1]);
+            else
+                product1a = color[1][1];
+
+            /* Set the calculated pixels */
+            switch (bpp) {
+            case 4:
+                AV_WN32A(dst_line[0] + x * 8,     product1a);
+                AV_WN32A(dst_line[0] + x * 8 + 4, product1b);
+                AV_WN32A(dst_line[1] + x * 8,     product2a);
+                AV_WN32A(dst_line[1] + x * 8 + 4, product2b);
+                break;
+            case 3:
+                AV_WL24(dst_line[0] + x * 6,     product1a);
+                AV_WL24(dst_line[0] + x * 6 + 3, product1b);
+                AV_WL24(dst_line[1] + x * 6,     product2a);
+                AV_WL24(dst_line[1] + x * 6 + 3, product2b);
+                break;
+            default: // bpp = 2
+                if (sai->is_be) {
+                    AV_WB32(dst_line[0] + x * 4, product1a | (product1b << 16));
+                    AV_WB32(dst_line[1] + x * 4, product2a | (product2b << 16));
+                } else {
+                    AV_WL32(dst_line[0] + x * 4, product1a | (product1b << 16));
+                    AV_WL32(dst_line[1] + x * 4, product2a | (product2b << 16));
+                }
+            }
+
+            /* Move color matrix forward */
+            color[0][0] = color[0][1]; color[0][1] = color[0][2]; color[0][2] = color[0][3];
+            color[1][0] = color[1][1]; color[1][1] = color[1][2]; color[1][2] = color[1][3];
+            color[2][0] = color[2][1]; color[2][1] = color[2][2]; color[2][2] = color[2][3];
+            color[3][0] = color[3][1]; color[3][1] = color[3][2]; color[3][2] = color[3][3];
+
+            if (x < width - 3) {
+                x += 3;
+                switch (bpp) {
+                case 4:
+                    READ_COLOR4(color[0][3], src_line[0], x);
+                    READ_COLOR4(color[1][3], src_line[1], x);
+                    READ_COLOR4(color[2][3], src_line[2], x);
+                    READ_COLOR4(color[3][3], src_line[3], x);
+                    break;
+                case 3:
+                    READ_COLOR3(color[0][3], src_line[0], x);
+                    READ_COLOR3(color[1][3], src_line[1], x);
+                    READ_COLOR3(color[2][3], src_line[2], x);
+                    READ_COLOR3(color[3][3], src_line[3], x);
+                    break;
+                default:        /* case 2 */
+                    READ_COLOR2(color[0][3], src_line[0], x);
+                    READ_COLOR2(color[1][3], src_line[1], x);
+                    READ_COLOR2(color[2][3], src_line[2], x);
+                    READ_COLOR2(color[3][3], src_line[3], x);
+                }
+                x -= 3;
+            }
+        }
+
+        /* We're done with one line, so we shift the source lines up */
+        src_line[0] = src_line[1];
+        src_line[1] = src_line[2];
+        src_line[2] = src_line[3];
+
+        /* Read next line */
+        src_line[3] = src_line[2];
+        if (y < height - 3)
+            src_line[3] += src_linesize;
+    } // y loop
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_RGBA, AV_PIX_FMT_BGRA, AV_PIX_FMT_ARGB, AV_PIX_FMT_ABGR,
+        AV_PIX_FMT_RGB24, AV_PIX_FMT_BGR24,
+        AV_PIX_FMT_RGB565BE, AV_PIX_FMT_BGR565BE, AV_PIX_FMT_RGB555BE, AV_PIX_FMT_BGR555BE,
+        AV_PIX_FMT_RGB565LE, AV_PIX_FMT_BGR565LE, AV_PIX_FMT_RGB555LE, AV_PIX_FMT_BGR555LE,
+        AV_PIX_FMT_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static int config_input(AVFilterLink *inlink)
+{
+    Super2xSaIContext *sai = inlink->dst->priv;
+
+    sai->hi_pixel_mask   = 0xFEFEFEFE;
+    sai->lo_pixel_mask   = 0x01010101;
+    sai->q_hi_pixel_mask = 0xFCFCFCFC;
+    sai->q_lo_pixel_mask = 0x03030303;
+    sai->bpp  = 4;
+
+    switch (inlink->format) {
+    case AV_PIX_FMT_RGB24:
+    case AV_PIX_FMT_BGR24:
+        sai->bpp = 3;
+        break;
+
+    case AV_PIX_FMT_RGB565BE:
+    case AV_PIX_FMT_BGR565BE:
+        sai->is_be = 1;
+    case AV_PIX_FMT_RGB565LE:
+    case AV_PIX_FMT_BGR565LE:
+        sai->hi_pixel_mask   = 0xF7DEF7DE;
+        sai->lo_pixel_mask   = 0x08210821;
+        sai->q_hi_pixel_mask = 0xE79CE79C;
+        sai->q_lo_pixel_mask = 0x18631863;
+        sai->bpp = 2;
+        break;
+
+    case AV_PIX_FMT_BGR555BE:
+    case AV_PIX_FMT_RGB555BE:
+        sai->is_be = 1;
+    case AV_PIX_FMT_BGR555LE:
+    case AV_PIX_FMT_RGB555LE:
+        sai->hi_pixel_mask   = 0x7BDE7BDE;
+        sai->lo_pixel_mask   = 0x04210421;
+        sai->q_hi_pixel_mask = 0x739C739C;
+        sai->q_lo_pixel_mask = 0x0C630C63;
+        sai->bpp = 2;
+        break;
+    }
+
+    return 0;
+}
+
+static int config_output(AVFilterLink *outlink)
+{
+    AVFilterLink *inlink = outlink->src->inputs[0];
+
+    outlink->w = inlink->w*2;
+    outlink->h = inlink->h*2;
+
+    av_log(inlink->dst, AV_LOG_VERBOSE, "fmt:%s size:%dx%d -> size:%dx%d\n",
+           av_get_pix_fmt_name(inlink->format),
+           inlink->w, inlink->h, outlink->w, outlink->h);
+
+    return 0;
+}
+
+static int null_draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) { return 0; }
+
+static int end_frame(AVFilterLink *inlink)
+{
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    AVFilterBufferRef  *inpicref =  inlink->cur_buf;
+    AVFilterBufferRef *outpicref = outlink->out_buf;
+
+    super2xsai(inlink->dst, inpicref->data[0], inpicref->linesize[0],
+               outpicref->data[0], outpicref->linesize[0],
+               inlink->w, inlink->h);
+
+    ff_draw_slice(outlink, 0, outlink->h, 1);
+    return ff_end_frame(outlink);
+}
+
+AVFilter avfilter_vf_super2xsai = {
+    .name        = "super2xsai",
+    .description = NULL_IF_CONFIG_SMALL("Scale the input by 2x using the Super2xSaI pixel art algorithm."),
+    .priv_size   = sizeof(Super2xSaIContext),
+    .query_formats = query_formats,
+
+    .inputs = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_VIDEO,
+          .config_props     = config_input,
+          .draw_slice       = null_draw_slice,
+          .end_frame        = end_frame,
+          .min_perms        = AV_PERM_READ },
+        { .name = NULL }
+    },
+    .outputs = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_VIDEO,
+          .config_props     = config_output },
+        { .name = NULL }
+    },
+};
diff --git a/libavfilter/vf_swapuv.c b/libavfilter/vf_swapuv.c
new file mode 100644
index 0000000..bfe71e8
--- /dev/null
+++ b/libavfilter/vf_swapuv.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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
+ * swap UV filter
+ */
+
+#include "avfilter.h"
+#include "formats.h"
+#include "video.h"
+
+static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms,
+                                           int w, int h)
+{
+    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;
+
+    return picref;
+}
+
+static int start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref)
+{
+    AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0);
+
+    outpicref->data[1] = inpicref->data[2];
+    outpicref->data[2] = inpicref->data[1];
+
+    outpicref->linesize[1] = inpicref->linesize[2];
+    outpicref->linesize[2] = inpicref->linesize[1];
+
+    return ff_start_frame(link->dst->outputs[0], outpicref);
+}
+
+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,
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+AVFilter avfilter_vf_swapuv = {
+    .name      = "swapuv",
+    .description = NULL_IF_CONFIG_SMALL("Swap U and V components."),
+    .priv_size = 0,
+    .query_formats = query_formats,
+
+    .inputs = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_VIDEO,
+          .get_video_buffer = get_video_buffer,
+          .start_frame      = start_frame, },
+        { .name = NULL }
+    },
+    .outputs = (const AVFilterPad[]) {
+        { .name             = "default",
+          .type             = AVMEDIA_TYPE_VIDEO, },
+        { .name             = NULL }
+    },
+};
diff --git a/libavfilter/vf_thumbnail.c b/libavfilter/vf_thumbnail.c
new file mode 100644
index 0000000..5936a19
--- /dev/null
+++ b/libavfilter/vf_thumbnail.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2011 Smartjog S.A.S, Clément Bœsch <clement.boesch@smartjog.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
+ * Potential thumbnail lookup filter to reduce the risk of an inappropriate
+ * selection (such as a black frame) we could get with an absolute seek.
+ *
+ * Simplified version of algorithm by Vadim Zaliva <lord@crocodile.org>.
+ * @see http://notbrainsurgery.livejournal.com/29773.html
+ */
+
+#include "avfilter.h"
+#include "internal.h"
+
+#define HIST_SIZE (3*256)
+
+struct thumb_frame {
+    AVFilterBufferRef *buf;     ///< cached frame
+    int histogram[HIST_SIZE];   ///< RGB color distribution histogram of the frame
+};
+
+typedef struct {
+    int n;                      ///< current frame
+    int n_frames;               ///< number of frames for analysis
+    struct thumb_frame *frames; ///< the n_frames frames
+} ThumbContext;
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    ThumbContext *thumb = ctx->priv;
+
+    if (!args) {
+        thumb->n_frames = 100;
+    } else {
+        int n = sscanf(args, "%d", &thumb->n_frames);
+        if (n != 1 || thumb->n_frames < 2) {
+            thumb->n_frames = 0;
+            av_log(ctx, AV_LOG_ERROR,
+                   "Invalid number of frames specified (minimum is 2).\n");
+            return AVERROR(EINVAL);
+        }
+    }
+    thumb->frames = av_calloc(thumb->n_frames, sizeof(*thumb->frames));
+    if (!thumb->frames) {
+        av_log(ctx, AV_LOG_ERROR,
+               "Allocation failure, try to lower the number of frames\n");
+        return AVERROR(ENOMEM);
+    }
+    av_log(ctx, AV_LOG_VERBOSE, "batch size: %d frames\n", thumb->n_frames);
+    return 0;
+}
+
+static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
+{
+    int i, j;
+    AVFilterContext *ctx = inlink->dst;
+    ThumbContext *thumb = ctx->priv;
+    int *hist = thumb->frames[thumb->n].histogram;
+    AVFilterBufferRef *picref = inlink->cur_buf;
+    const uint8_t *p = picref->data[0] + y * picref->linesize[0];
+
+    // update current frame RGB histogram
+    for (j = 0; j < h; j++) {
+        for (i = 0; i < inlink->w; i++) {
+            hist[0*256 + p[i*3    ]]++;
+            hist[1*256 + p[i*3 + 1]]++;
+            hist[2*256 + p[i*3 + 2]]++;
+        }
+        p += picref->linesize[0];
+    }
+    return 0;
+}
+
+/**
+ * @brief        Compute Sum-square deviation to estimate "closeness".
+ * @param hist   color distribution histogram
+ * @param median average color distribution histogram
+ * @return       sum of squared errors
+ */
+static double frame_sum_square_err(const int *hist, const double *median)
+{
+    int i;
+    double err, sum_sq_err = 0;
+
+    for (i = 0; i < HIST_SIZE; i++) {
+        err = median[i] - (double)hist[i];
+        sum_sq_err += err*err;
+    }
+    return sum_sq_err;
+}
+
+static int  end_frame(AVFilterLink *inlink)
+{
+    int i, j, best_frame_idx = 0;
+    double avg_hist[HIST_SIZE] = {0}, sq_err, min_sq_err = -1;
+    AVFilterLink *outlink = inlink->dst->outputs[0];
+    ThumbContext *thumb   = inlink->dst->priv;
+    AVFilterContext *ctx  = inlink->dst;
+    AVFilterBufferRef *picref;
+
+    // keep a reference of each frame
+    thumb->frames[thumb->n].buf = inlink->cur_buf;
+    inlink->cur_buf = NULL;
+
+    // no selection until the buffer of N frames is filled up
+    if (thumb->n < thumb->n_frames - 1) {
+        thumb->n++;
+        return 0;
+    }
+
+    // average histogram of the N frames
+    for (j = 0; j < FF_ARRAY_ELEMS(avg_hist); j++) {
+        for (i = 0; i < thumb->n_frames; i++)
+            avg_hist[j] += (double)thumb->frames[i].histogram[j];
+        avg_hist[j] /= thumb->n_frames;
+    }
+
+    // find the frame closer to the average using the sum of squared errors
+    for (i = 0; i < thumb->n_frames; i++) {
+        sq_err = frame_sum_square_err(thumb->frames[i].histogram, avg_hist);
+        if (i == 0 || sq_err < min_sq_err)
+            best_frame_idx = i, min_sq_err = sq_err;
+    }
+
+    // free and reset everything (except the best frame buffer)
+    for (i = 0; i < thumb->n_frames; i++) {
+        memset(thumb->frames[i].histogram, 0, sizeof(thumb->frames[i].histogram));
+        if (i == best_frame_idx)
+            continue;
+        avfilter_unref_buffer(thumb->frames[i].buf);
+        thumb->frames[i].buf = NULL;
+    }
+    thumb->n = 0;
+
+    // raise the chosen one
+    picref = thumb->frames[best_frame_idx].buf;
+    av_log(ctx, AV_LOG_INFO, "frame id #%d (pts_time=%f) selected\n",
+           best_frame_idx, picref->pts * av_q2d(inlink->time_base));
+    ff_start_frame(outlink, picref);
+    thumb->frames[best_frame_idx].buf = NULL;
+    ff_draw_slice(outlink, 0, inlink->h, 1);
+    return ff_end_frame(outlink);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    int i;
+    ThumbContext *thumb = ctx->priv;
+    for (i = 0; i < thumb->n_frames && thumb->frames[i].buf; i++) {
+        avfilter_unref_buffer(thumb->frames[i].buf);
+        thumb->frames[i].buf = NULL;
+    }
+    av_freep(&thumb->frames);
+}
+
+static int null_start_frame(AVFilterLink *link, AVFilterBufferRef *picref) { return 0; }
+
+static int request_frame(AVFilterLink *link)
+{
+    ThumbContext *thumb = link->src->priv;
+
+    /* loop until a frame thumbnail is available (when a frame is queued,
+     * thumb->n is reset to zero) */
+    do {
+        int ret = ff_request_frame(link->src->inputs[0]);
+        if (ret < 0)
+            return ret;
+    } while (thumb->n);
+    return 0;
+}
+
+static int poll_frame(AVFilterLink *link)
+{
+    ThumbContext *thumb  = link->src->priv;
+    AVFilterLink *inlink = link->src->inputs[0];
+    int ret, available_frames = ff_poll_frame(inlink);
+
+    /* If the input link is not able to provide any frame, we can't do anything
+     * at the moment and thus have zero thumbnail available. */
+    if (!available_frames)
+        return 0;
+
+    /* Since at least one frame is available and the next frame will allow us
+     * to compute a thumbnail, we can return 1 frame. */
+    if (thumb->n == thumb->n_frames - 1)
+        return 1;
+
+    /* we have some frame(s) available in the input link, but not yet enough to
+     * output a thumbnail, so we request more */
+    ret = ff_request_frame(inlink);
+    return ret < 0 ? ret : 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        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;
+}
+
+AVFilter avfilter_vf_thumbnail = {
+    .name          = "thumbnail",
+    .description   = NULL_IF_CONFIG_SMALL("Select the most representative frame in a given sequence of consecutive frames."),
+    .priv_size     = sizeof(ThumbContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+    .inputs        = (const AVFilterPad[]) {
+        {   .name             = "default",
+            .type             = AVMEDIA_TYPE_VIDEO,
+            .get_video_buffer = ff_null_get_video_buffer,
+            .min_perms        = AV_PERM_PRESERVE,
+            .start_frame      = null_start_frame,
+            .draw_slice       = draw_slice,
+            .end_frame        = end_frame,
+        },{ .name = NULL }
+    },
+    .outputs       = (const AVFilterPad[]) {
+        {   .name             = "default",
+            .type             = AVMEDIA_TYPE_VIDEO,
+            .request_frame    = request_frame,
+            .poll_frame       = poll_frame,
+        },{ .name = NULL }
+    },
+};
diff --git a/libavfilter/vf_tile.c b/libavfilter/vf_tile.c
new file mode 100644
index 0000000..52d53eb
--- /dev/null
+++ b/libavfilter/vf_tile.c
@@ -0,0 +1,215 @@
+/*
+ * 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
+ */
+
+/**
+ * @file
+ * tile video filter
+ */
+
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+#include "drawutils.h"
+#include "formats.h"
+#include "video.h"
+#include "internal.h"
+
+typedef struct {
+    unsigned w, h;
+    unsigned current;
+    FFDrawContext draw;
+    FFDrawColor blank;
+} TileContext;
+
+#define REASONABLE_SIZE 1024
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    TileContext *tile = ctx->priv;
+    int r;
+    char dummy;
+
+    if (!args)
+        args = "6x5";
+    r = sscanf(args, "%ux%u%c", &tile->w, &tile->h, &dummy);
+    if (r != 2 || !tile->w || !tile->h)
+        return AVERROR(EINVAL);
+    if (tile->w > REASONABLE_SIZE || tile->h > REASONABLE_SIZE) {
+        av_log(ctx, AV_LOG_ERROR, "Tile size %ux%u is insane.\n",
+               tile->w, tile->h);
+        return AVERROR(EINVAL);
+    }
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0));
+    return 0;
+}
+
+static int config_props(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    TileContext *tile   = ctx->priv;
+    AVFilterLink *inlink = ctx->inputs[0];
+
+    if (inlink->w > INT_MAX / tile->w) {
+        av_log(ctx, AV_LOG_ERROR, "Total width %ux%u is too much.\n",
+               tile->w, inlink->w);
+        return AVERROR(EINVAL);
+    }
+    if (inlink->h > INT_MAX / tile->h) {
+        av_log(ctx, AV_LOG_ERROR, "Total height %ux%u is too much.\n",
+               tile->h, inlink->h);
+        return AVERROR(EINVAL);
+    }
+    outlink->w = tile->w * inlink->w;
+    outlink->h = tile->h * inlink->h;
+    outlink->sample_aspect_ratio = inlink->sample_aspect_ratio;
+    outlink->frame_rate = av_mul_q(inlink->frame_rate,
+                                   (AVRational){ 1, tile->w * tile->h });
+    ff_draw_init(&tile->draw, inlink->format, 0);
+    /* TODO make the color an option, or find an unified way of choosing it */
+    ff_draw_color(&tile->draw, &tile->blank, (uint8_t[]){ 0, 0, 0, -1 });
+
+    return 0;
+}
+
+/* Note: direct rendering is not possible since there is no guarantee that
+ * buffers are fed to start_frame in the order they were obtained from
+ * get_buffer (think B-frames). */
+
+static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
+{
+    AVFilterContext *ctx  = inlink->dst;
+    TileContext *tile    = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
+
+    if (tile->current)
+        return 0;
+    outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE,
+                                                 outlink->w, outlink->h);
+    avfilter_copy_buffer_ref_props(outlink->out_buf, picref);
+    outlink->out_buf->video->w = outlink->w;
+    outlink->out_buf->video->h = outlink->h;
+    return 0;
+}
+
+static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
+{
+    AVFilterContext *ctx  = inlink->dst;
+    TileContext *tile    = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
+    unsigned x0 = inlink->w * (tile->current % tile->w);
+    unsigned y0 = inlink->h * (tile->current / tile->w);
+
+    ff_copy_rectangle2(&tile->draw,
+                       outlink->out_buf->data, outlink->out_buf->linesize,
+                       inlink ->cur_buf->data, inlink ->cur_buf->linesize,
+                       x0, y0 + y, 0, y, inlink->cur_buf->video->w, h);
+    /* TODO if tile->w == 1 && slice_dir is always 1, we could draw_slice
+     * immediately. */
+    return 0;
+}
+
+static void draw_blank_frame(AVFilterContext *ctx, AVFilterBufferRef *out_buf)
+{
+    TileContext *tile    = ctx->priv;
+    AVFilterLink *inlink  = ctx->inputs[0];
+    unsigned x0 = inlink->w * (tile->current % tile->w);
+    unsigned y0 = inlink->h * (tile->current / tile->w);
+
+    ff_fill_rectangle(&tile->draw, &tile->blank,
+                      out_buf->data, out_buf->linesize,
+                      x0, y0, inlink->w, inlink->h);
+    tile->current++;
+}
+static void end_last_frame(AVFilterContext *ctx)
+{
+    TileContext *tile    = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
+    AVFilterBufferRef *out_buf = outlink->out_buf;
+
+    outlink->out_buf = NULL;
+    ff_start_frame(outlink, out_buf);
+    while (tile->current < tile->w * tile->h)
+        draw_blank_frame(ctx, out_buf);
+    ff_draw_slice(outlink, 0, out_buf->video->h, 1);
+    ff_end_frame(outlink);
+    tile->current = 0;
+}
+
+static int end_frame(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx  = inlink->dst;
+    TileContext *tile    = ctx->priv;
+
+    avfilter_unref_bufferp(&inlink->cur_buf);
+    if (++tile->current == tile->w * tile->h)
+        end_last_frame(ctx);
+    return 0;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    TileContext *tile   = ctx->priv;
+    AVFilterLink *inlink = ctx->inputs[0];
+    int r;
+
+    while (1) {
+        r = ff_request_frame(inlink);
+        if (r < 0) {
+            if (r == AVERROR_EOF && tile->current)
+                end_last_frame(ctx);
+            else
+                return r;
+            break;
+        }
+        if (!tile->current) /* done */
+            break;
+    }
+    return 0;
+}
+
+
+AVFilter avfilter_vf_tile = {
+    .name          = "tile",
+    .description   = NULL_IF_CONFIG_SMALL("Tile several successive frames together."),
+    .init          = init,
+    .query_formats = query_formats,
+    .priv_size     = sizeof(TileContext),
+    .inputs = (const AVFilterPad[]) {
+        { .name        = "default",
+          .type        = AVMEDIA_TYPE_VIDEO,
+          .start_frame = start_frame,
+          .draw_slice  = draw_slice,
+          .end_frame   = end_frame,
+          .min_perms   = AV_PERM_READ, },
+        { .name = NULL }
+    },
+    .outputs = (const AVFilterPad[]) {
+        { .name          = "default",
+          .type          = AVMEDIA_TYPE_VIDEO,
+          .config_props  = config_props,
+          .request_frame = request_frame },
+        { .name = NULL }
+    },
+};
diff --git a/libavfilter/vf_tinterlace.c b/libavfilter/vf_tinterlace.c
new file mode 100644
index 0000000..0bfccfb
--- /dev/null
+++ b/libavfilter/vf_tinterlace.c
@@ -0,0 +1,392 @@
+/*
+ * Copyright (c) 2011 Stefano Sabatini
+ * Copyright (c) 2010 Baptiste Coudurier
+ * Copyright (c) 2003 Michael Zucchi <notzed@ximian.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with FFmpeg if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * @file
+ * temporal field interlace filter, ported from MPlayer/libmpcodecs
+ */
+
+#include "libavutil/imgutils.h"
+#include "libavutil/avassert.h"
+#include "avfilter.h"
+#include "internal.h"
+
+enum TInterlaceMode {
+    MODE_MERGE = 0,
+    MODE_DROP_EVEN,
+    MODE_DROP_ODD,
+    MODE_PAD,
+    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
+};
+
+typedef struct {
+    enum TInterlaceMode mode;   ///< interlace mode selected
+    int frame;                  ///< number of the output frame
+    int vsub;                   ///< chroma vertical subsampling
+    AVFilterBufferRef *cur;
+    AVFilterBufferRef *next;
+    uint8_t *black_data[4];     ///< buffer used to fill padded lines
+    int black_linesize[4];
+} TInterlaceContext;
+
+#define FULL_SCALE_YUVJ_FORMATS \
+    AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ440P
+
+static enum AVPixelFormat full_scale_yuvj_pix_fmts[] = {
+    FULL_SCALE_YUVJ_FORMATS, AV_PIX_FMT_NONE
+};
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_YUV420P,  AV_PIX_FMT_YUV422P,  AV_PIX_FMT_YUV444P,
+        AV_PIX_FMT_YUV444P,  AV_PIX_FMT_YUV410P,  AV_PIX_FMT_YUVA420P,
+        AV_PIX_FMT_GRAY8, FULL_SCALE_YUVJ_FORMATS,
+        AV_PIX_FMT_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    TInterlaceContext *tinterlace = ctx->priv;
+    int i;
+    char c;
+
+    tinterlace->mode = MODE_MERGE;
+
+    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;
+}
+
+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);
+
+    av_freep(&tinterlace->black_data[0]);
+}
+
+static int config_out_props(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    AVFilterLink *inlink = outlink->src->inputs[0];
+    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[outlink->format];
+    TInterlaceContext *tinterlace = ctx->priv;
+
+    tinterlace->vsub = desc->log2_chroma_h;
+    outlink->w = inlink->w;
+    outlink->h = tinterlace->mode == MODE_MERGE || tinterlace->mode == MODE_PAD ?
+        inlink->h*2 : inlink->h;
+
+    if (tinterlace->mode == MODE_PAD) {
+        uint8_t black[4] = { 16, 128, 128, 16 };
+        int i, ret;
+        if (ff_fmt_is_in(outlink->format, full_scale_yuvj_pix_fmts))
+            black[0] = black[3] = 0;
+        ret = av_image_alloc(tinterlace->black_data, tinterlace->black_linesize,
+                             outlink->w, outlink->h, outlink->format, 1);
+        if (ret < 0)
+            return ret;
+
+        /* fill black picture with black */
+        for (i = 0; i < 4 && tinterlace->black_data[i]; i++) {
+            int h = i == 1 || i == 2 ? outlink->h >> desc->log2_chroma_h : outlink->h;
+            memset(tinterlace->black_data[i], black[i],
+                   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);
+
+    return 0;
+}
+
+#define FIELD_UPPER           0
+#define FIELD_LOWER           1
+#define FIELD_UPPER_AND_LOWER 2
+
+/**
+ * Copy picture field from src to dst.
+ *
+ * @param src_field copy from upper, lower field or both
+ * @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
+ */
+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)
+{
+    const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[format];
+    int plane, vsub = desc->log2_chroma_h;
+    int k = src_field == FIELD_UPPER_AND_LOWER ? 1 : 2;
+
+    for (plane = 0; plane < desc->nb_components; plane++) {
+        int lines = plane == 1 || plane == 2 ? src_h >> vsub : src_h;
+        int linesize = av_image_get_linesize(format, w, plane);
+        uint8_t *dstp = dst[plane];
+        const uint8_t *srcp = src[plane];
+        lines /= k;
+        if (src_field == FIELD_LOWER)
+            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),
+                            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)
+{
+    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;
+
+    /* we need at least two frames */
+    if (!tinterlace->cur)
+        return 0;
+
+    switch (tinterlace->mode) {
+    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);
+        avfilter_copy_buffer_ref_props(out, cur);
+        out->video->h = outlink->h;
+        out->video->interlaced = 1;
+        out->video->top_field_first = 1;
+
+        /* write odd frame lines into the upper field of the new frame */
+        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);
+        /* 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);
+        avfilter_unref_bufferp(&tinterlace->next);
+        break;
+
+    case MODE_DROP_ODD:  /* only output even frames, odd  frames are dropped; height unchanged, half framerate */
+    case MODE_DROP_EVEN: /* only output odd  frames, even frames are dropped; height unchanged, half framerate */
+        out = avfilter_ref_buffer(tinterlace->mode == MODE_DROP_EVEN ? cur : next, AV_PERM_READ);
+        avfilter_unref_bufferp(&tinterlace->next);
+        break;
+
+    case MODE_PAD: /* expand each frame to double height, but pad alternate
+                    * lines with black; framerate unchanged */
+        out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
+        avfilter_copy_buffer_ref_props(out, cur);
+        out->video->h = outlink->h;
+
+        field = (1 + tinterlace->frame) & 1 ? FIELD_UPPER : FIELD_LOWER;
+        /* copy upper and lower fields */
+        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);
+        /* 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);
+        break;
+
+        /* interleave upper/lower lines from odd frames with lower/upper lines from even frames,
+         * halving the frame rate and preserving image height */
+    case MODE_INTERLEAVE_TOP:    /* top    field first */
+    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);
+        avfilter_copy_buffer_ref_props(out, cur);
+        out->video->interlaced = 1;
+        out->video->top_field_first = tff;
+
+        /* copy upper/lower field from cur */
+        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);
+        /* 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);
+        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);
+        out->video->interlaced = 1;
+
+        ff_start_frame(outlink, out);
+        ff_draw_slice(outlink, 0, outlink->h, 1);
+        ff_end_frame(outlink);
+
+        /* 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);
+        avfilter_copy_buffer_ref_props(out, next);
+        out->video->interlaced = 1;
+
+        /* write current frame second field lines into the second field of the new frame */
+        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);
+        /* 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);
+        break;
+    }
+
+    ff_start_frame(outlink, out);
+    ff_draw_slice(outlink, 0, outlink->h, 1);
+    ff_end_frame(outlink);
+
+    tinterlace->frame++;
+
+    return 0;
+}
+
+static int poll_frame(AVFilterLink *outlink)
+{
+    TInterlaceContext *tinterlace = outlink->src->priv;
+    AVFilterLink *inlink = outlink->src->inputs[0];
+    int ret, val;
+
+    val = ff_poll_frame(inlink);
+
+    if (val == 1 && !tinterlace->next) {
+        if ((ret = ff_request_frame(inlink)) < 0)
+            return ret;
+        val = ff_poll_frame(inlink);
+    }
+    av_assert0(tinterlace->next);
+
+    return val;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    TInterlaceContext *tinterlace = outlink->src->priv;
+    AVFilterLink *inlink = outlink->src->inputs[0];
+
+    do {
+        int ret;
+
+        if ((ret = ff_request_frame(inlink)) < 0)
+            return ret;
+    } while (!tinterlace->cur);
+
+    return 0;
+}
+
+static int null_draw_slice(AVFilterLink *link, int y, int h, int slice_dir) { return 0; }
+
+AVFilter avfilter_vf_tinterlace = {
+    .name          = "tinterlace",
+    .description   = NULL_IF_CONFIG_SMALL("Perform temporal field interlacing."),
+    .priv_size     = sizeof(TInterlaceContext),
+    .init          = init,
+    .uninit        = uninit,
+    .query_formats = query_formats,
+
+    .inputs = (const AVFilterPad[]) {
+        { .name          = "default",
+          .type          = AVMEDIA_TYPE_VIDEO,
+          .start_frame   = start_frame,
+          .draw_slice    = null_draw_slice,
+          .end_frame     = end_frame, },
+        { .name = NULL}
+    },
+    .outputs = (const AVFilterPad[]) {
+        { .name          = "default",
+          .type          = AVMEDIA_TYPE_VIDEO,
+          .config_props  = config_out_props,
+          .poll_frame    = poll_frame,
+          .request_frame = request_frame },
+        { .name = NULL}
+    },
+};
diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c
index 1ee645f..dc2ee21 100644
--- a/libavfilter/vf_transpose.c
+++ b/libavfilter/vf_transpose.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2010 Stefano Sabatini
  * Copyright (c) 2008 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -28,6 +28,7 @@
 #include <stdio.h>
 
 #include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/internal.h"
@@ -36,7 +37,14 @@
 #include "internal.h"
 #include "video.h"
 
+typedef enum {
+    TRANSPOSE_PT_TYPE_NONE,
+    TRANSPOSE_PT_TYPE_LANDSCAPE,
+    TRANSPOSE_PT_TYPE_PORTRAIT,
+} PassthroughType;
+
 typedef struct {
+    const AVClass *class;
     int hsub, vsub;
     int pixsteps[4];
 
@@ -45,22 +53,35 @@
     /* 2    Rotate by 90 degrees counterclockwise.           */
     /* 3    Rotate by 90 degrees clockwise and vflip.        */
     int dir;
+    PassthroughType passthrough; ///< landscape passthrough mode enabled
 } TransContext;
 
+#define OFFSET(x) offsetof(TransContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption transpose_options[] = {
+    { "dir", "set transpose direction", OFFSET(dir), AV_OPT_TYPE_INT, {.i64=0},  0, 7, FLAGS },
+
+    { "passthrough", "do not apply transposition if the input matches the specified geometry",
+      OFFSET(passthrough), AV_OPT_TYPE_INT, {.i64=TRANSPOSE_PT_TYPE_NONE},  0, INT_MAX, FLAGS, "passthrough" },
+    { "none",      "always apply transposition",   0, AV_OPT_TYPE_CONST, {.i64=TRANSPOSE_PT_TYPE_NONE},      INT_MIN, INT_MAX, FLAGS, "passthrough" },
+    { "portrait",  "preserve portrait geometry",   0, AV_OPT_TYPE_CONST, {.i64=TRANSPOSE_PT_TYPE_PORTRAIT},  INT_MIN, INT_MAX, FLAGS, "passthrough" },
+    { "landscape", "preserve landscape geometry",  0, AV_OPT_TYPE_CONST, {.i64=TRANSPOSE_PT_TYPE_LANDSCAPE}, INT_MIN, INT_MAX, FLAGS, "passthrough" },
+
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(transpose);
+
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     TransContext *trans = ctx->priv;
-    trans->dir = 0;
+    const char *shorthand[] = { "dir", "passthrough", NULL };
 
-    if (args)
-        sscanf(args, "%d", &trans->dir);
+    trans->class = &transpose_class;
+    av_opt_set_defaults(trans);
 
-    if (trans->dir < 0 || trans->dir > 3) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid value %d not between 0 and 3.\n",
-               trans->dir);
-        return AVERROR(EINVAL);
-    }
-    return 0;
+    return av_opt_set_from_string(trans, args, shorthand, "=", ":");
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -75,16 +96,13 @@
         AV_PIX_FMT_BGR555BE,     AV_PIX_FMT_BGR555LE,
         AV_PIX_FMT_GRAY16BE,     AV_PIX_FMT_GRAY16LE,
         AV_PIX_FMT_YUV420P16LE,  AV_PIX_FMT_YUV420P16BE,
-        AV_PIX_FMT_YUV422P16LE,  AV_PIX_FMT_YUV422P16BE,
         AV_PIX_FMT_YUV444P16LE,  AV_PIX_FMT_YUV444P16BE,
         AV_PIX_FMT_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_YUV422P,
+        AV_PIX_FMT_YUV444P,      AV_PIX_FMT_YUVJ444P,
         AV_PIX_FMT_YUV420P,      AV_PIX_FMT_YUVJ420P,
-        AV_PIX_FMT_YUV411P,      AV_PIX_FMT_YUV410P,
-        AV_PIX_FMT_YUVJ444P,     AV_PIX_FMT_YUVJ422P,
-        AV_PIX_FMT_YUV440P,      AV_PIX_FMT_YUVJ440P,
+        AV_PIX_FMT_YUV410P,
         AV_PIX_FMT_YUVA420P,     AV_PIX_FMT_GRAY8,
         AV_PIX_FMT_NONE
     };
@@ -101,6 +119,23 @@
     const AVPixFmtDescriptor *desc_out = av_pix_fmt_desc_get(outlink->format);
     const AVPixFmtDescriptor *desc_in  = av_pix_fmt_desc_get(inlink->format);
 
+    if (trans->dir&4) {
+        av_log(ctx, AV_LOG_WARNING,
+               "dir values greater than 3 are deprecated, use the passthrough option instead\n");
+        trans->dir &= 3;
+        trans->passthrough = TRANSPOSE_PT_TYPE_LANDSCAPE;
+    }
+
+    if ((inlink->w >= inlink->h && trans->passthrough == TRANSPOSE_PT_TYPE_LANDSCAPE) ||
+        (inlink->w <= inlink->h && trans->passthrough == TRANSPOSE_PT_TYPE_PORTRAIT)) {
+        av_log(ctx, AV_LOG_VERBOSE,
+               "w:%d h:%d -> w:%d h:%d (passthrough mode)\n",
+               inlink->w, inlink->h, inlink->w, inlink->h);
+        return 0;
+    } else {
+        trans->passthrough = TRANSPOSE_PT_TYPE_NONE;
+    }
+
     trans->hsub = desc_in->log2_chroma_w;
     trans->vsub = desc_in->log2_chroma_h;
 
@@ -121,11 +156,24 @@
     return 0;
 }
 
+static AVFilterBufferRef *get_video_buffer(AVFilterLink *inlink, int perms, int w, int h)
+{
+    TransContext *trans = inlink->dst->priv;
+
+    return trans->passthrough ?
+        ff_null_get_video_buffer   (inlink, perms, w, h) :
+        ff_default_get_video_buffer(inlink, perms, w, h);
+}
+
 static int start_frame(AVFilterLink *inlink, AVFilterBufferRef *picref)
 {
+    TransContext *trans = inlink->dst->priv;
     AVFilterLink *outlink = inlink->dst->outputs[0];
     AVFilterBufferRef *buf_out;
 
+    if (trans->passthrough)
+        return ff_null_start_frame(inlink, picref);
+
     outlink->out_buf = ff_get_video_buffer(outlink, AV_PERM_WRITE,
                                            outlink->w, outlink->h);
     if (!outlink->out_buf)
@@ -133,11 +181,11 @@
 
     outlink->out_buf->pts = picref->pts;
 
-    if (picref->video->pixel_aspect.num == 0) {
-        outlink->out_buf->video->pixel_aspect = picref->video->pixel_aspect;
+    if (picref->video->sample_aspect_ratio.num == 0) {
+        outlink->out_buf->video->sample_aspect_ratio = picref->video->sample_aspect_ratio;
     } else {
-        outlink->out_buf->video->pixel_aspect.num = picref->video->pixel_aspect.den;
-        outlink->out_buf->video->pixel_aspect.den = picref->video->pixel_aspect.num;
+        outlink->out_buf->video->sample_aspect_ratio.num = picref->video->sample_aspect_ratio.den;
+        outlink->out_buf->video->sample_aspect_ratio.den = picref->video->sample_aspect_ratio.num;
     }
 
     buf_out = avfilter_ref_buffer(outlink->out_buf, ~0);
@@ -154,6 +202,9 @@
     AVFilterLink *outlink = inlink->dst->outputs[0];
     int plane, ret;
 
+    if (trans->passthrough)
+        return ff_null_end_frame(inlink);
+
     for (plane = 0; outpic->data[plane]; plane++) {
         int hsub = plane == 1 || plane == 2 ? trans->hsub : 0;
         int vsub = plane == 1 || plane == 2 ? trans->vsub : 0;
@@ -209,11 +260,20 @@
     return 0;
 }
 
+static int draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
+{
+    TransContext *trans = inlink->dst->priv;
+
+    return trans->passthrough ? ff_null_draw_slice(inlink, y, h, slice_dir) : 0;
+}
+
 static const AVFilterPad avfilter_vf_transpose_inputs[] = {
     {
         .name        = "default",
         .type        = AVMEDIA_TYPE_VIDEO,
+        .get_video_buffer= get_video_buffer,
         .start_frame = start_frame,
+        .draw_slice  = draw_slice,
         .end_frame   = end_frame,
         .min_perms   = AV_PERM_READ,
     },
@@ -240,4 +300,5 @@
 
     .inputs    = avfilter_vf_transpose_inputs,
     .outputs   = avfilter_vf_transpose_outputs,
+    .priv_class = &transpose_class,
 };
diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c
index 7e50bb8..6635ca4 100644
--- a/libavfilter/vf_unsharp.c
+++ b/libavfilter/vf_unsharp.c
@@ -3,26 +3,26 @@
  * Port copyright (c) 2010 Daniel G. Taylor <dan@programmer-art.org>
  * Relicensed to the LGPL with permission from Remi Guyomarch.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
  * @file
- * blur / sharpen filter, ported to Libav from MPlayer
+ * blur / sharpen filter, ported to FFmpeg from MPlayer
  * libmpcodecs/unsharp.c.
  *
  * This code is based on:
@@ -76,7 +76,7 @@
 
     int32_t res;
     int x, y, z;
-    const uint8_t *src2;
+    const uint8_t *src2 = NULL;  //silence a warning
 
     if (!fp->amount) {
         if (dst_stride == src_stride)
diff --git a/libavfilter/vf_vflip.c b/libavfilter/vf_vflip.c
index f12290a..bec449f 100644
--- a/libavfilter/vf_vflip.c
+++ b/libavfilter/vf_vflip.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2007 Bobby Bingham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -61,7 +61,7 @@
         int vsub = i == 1 || i == 2 ? flip->vsub : 0;
 
         if (picref->data[i]) {
-            picref->data[i] += ((h >> vsub)-1) * picref->linesize[i];
+            picref->data[i] += (((h + (1<<vsub)-1) >> vsub)-1) * picref->linesize[i];
             picref->linesize[i] = -picref->linesize[i];
         }
     }
@@ -82,7 +82,7 @@
         int vsub = i == 1 || i == 2 ? flip->vsub : 0;
 
         if (outpicref->data[i]) {
-            outpicref->data[i] += ((link->h >> vsub)-1) * outpicref->linesize[i];
+            outpicref->data[i] += (((link->h + (1<<vsub)-1)>> vsub)-1) * outpicref->linesize[i];
             outpicref->linesize[i] = -outpicref->linesize[i];
         }
     }
diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c
index 1c605d9..cbbe761 100644
--- a/libavfilter/vf_yadif.c
+++ b/libavfilter/vf_yadif.c
@@ -1,24 +1,23 @@
 /*
- * Copyright (C) 2006-2010 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2006-2011 Michael Niedermayer <michaelni@gmx.at>
  *               2010      James Darnley <james.darnley@gmail.com>
  *
- * This file is part of Libav.
- *
- * Libav is free software; you can redistribute it and/or modify
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License along
- * with Libav; if not, write to the Free Software Foundation, Inc.,
+ * 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/cpu.h"
 #include "libavutil/common.h"
 #include "libavutil/pixdesc.h"
@@ -116,6 +115,7 @@
         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;
 
         if (i == 1 || i == 2) {
@@ -124,6 +124,12 @@
             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;
+        }
+
         for (y = 0; y < h; y++) {
             if ((y ^ parity) & 1) {
                 uint8_t *prev = &yadif->prev->data[i][y * refs];
@@ -131,9 +137,25 @@
                 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;
+                }
+
                 yadif->filter_line(dst, prev, cur, next, w,
-                                   y + 1 < h ? refs : -refs,
-                                   y ? -refs : refs,
+                                   prefs, mrefs,
                                    parity ^ tff, mode);
             } else {
                 memcpy(&dstpic->data[i][y * dstpic->linesize[i]],
@@ -145,25 +167,6 @@
     emms_c();
 }
 
-static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms,
-                                           int w, int h)
-{
-    AVFilterBufferRef *picref;
-    int width  = FFALIGN(w, 32);
-    int height = FFALIGN(h + 2, 32);
-    int i;
-
-    picref = ff_default_get_video_buffer(link, perms, width, height);
-
-    picref->video->w = w;
-    picref->video->h = h;
-
-    for (i = 0; i < 3; i++)
-        picref->data[i] += picref->linesize[i];
-
-    return picref;
-}
-
 static int return_frame(AVFilterContext *ctx, int is_second)
 {
     YADIFContext *yadif = ctx->priv;
@@ -189,7 +192,7 @@
     if (!yadif->csp)
         yadif->csp = av_pix_fmt_desc_get(link->format);
     if (yadif->csp->comp[0].depth_minus1 / 8 == 1)
-        yadif->filter_line = filter_line_c_16bit;
+        yadif->filter_line = (void*)filter_line_c_16bit;
 
     filter(ctx, yadif->out, tff ^ !is_second, tff);
 
@@ -219,6 +222,13 @@
     AVFilterContext *ctx = link->dst;
     YADIFContext *yadif = ctx->priv;
 
+    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);
 
@@ -233,7 +243,7 @@
         return 0;
 
     if (yadif->auto_enable && !yadif->cur->video->interlaced) {
-        yadif->out  = avfilter_ref_buffer(yadif->cur, AV_PERM_READ);
+        yadif->out  = avfilter_ref_buffer(yadif->cur, ~AV_PERM_WRITE);
         if (!yadif->out)
             return AVERROR(ENOMEM);
 
@@ -244,7 +254,7 @@
     }
 
     if (!yadif->prev &&
-        !(yadif->prev = avfilter_ref_buffer(yadif->cur, AV_PERM_READ)))
+        !(yadif->prev = avfilter_ref_buffer(yadif->cur, ~AV_PERM_WRITE)))
         return AVERROR(ENOMEM);
 
     yadif->out = ff_get_video_buffer(ctx->outputs[0], PERM_RWP,
@@ -298,9 +308,8 @@
 
         ret  = ff_request_frame(link->src->inputs[0]);
 
-        if (ret == AVERROR_EOF && yadif->next) {
-            AVFilterBufferRef *next =
-                avfilter_ref_buffer(yadif->next, AV_PERM_READ);
+        if (ret == AVERROR_EOF && yadif->cur) {
+            AVFilterBufferRef *next = avfilter_ref_buffer(yadif->next, ~AV_PERM_WRITE);
 
             if (!next)
                 return AVERROR(ENOMEM);
@@ -331,7 +340,7 @@
         return val;
 
     //FIXME change API to not requre this red tape
-    if (val == 1 && !yadif->next) {
+    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]);
@@ -353,6 +362,7 @@
     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;
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -377,6 +387,8 @@
         AV_NE( AV_PIX_FMT_YUV422P16BE, AV_PIX_FMT_YUV422P16LE ),
         AV_NE( AV_PIX_FMT_YUV444P16BE, AV_PIX_FMT_YUV444P16LE ),
         AV_PIX_FMT_YUVA420P,
+        AV_PIX_FMT_YUVA422P,
+        AV_PIX_FMT_YUVA444P,
         AV_PIX_FMT_NONE
     };
 
@@ -416,11 +428,16 @@
 
 static int config_props(AVFilterLink *link)
 {
+    YADIFContext *yadif = 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)
+        link->frame_rate = av_mul_q(link->src->inputs[0]->frame_rate, (AVRational){2,1});
+
     return 0;
 }
 
@@ -429,9 +446,9 @@
         .name             = "default",
         .type             = AVMEDIA_TYPE_VIDEO,
         .start_frame      = start_frame,
-        .get_video_buffer = get_video_buffer,
         .draw_slice       = null_draw_slice,
         .end_frame        = end_frame,
+        .min_perms        = AV_PERM_PRESERVE,
     },
     { NULL }
 };
@@ -449,7 +466,7 @@
 
 AVFilter avfilter_vf_yadif = {
     .name          = "yadif",
-    .description   = NULL_IF_CONFIG_SMALL("Deinterlace the input image"),
+    .description   = NULL_IF_CONFIG_SMALL("Deinterlace the input image."),
 
     .priv_size     = sizeof(YADIFContext),
     .init          = init,
diff --git a/libavfilter/video.c b/libavfilter/video.c
index 49091ad..ebc8cf4 100644
--- a/libavfilter/video.c
+++ b/libavfilter/video.c
@@ -1,24 +1,29 @@
 /*
- * This file is part of Libav.
+ * Copyright 2007 Bobby Bingham
+ * Copyright Stefano Sabatini <stefasab gmail com>
+ * Copyright Vitor Sessak <vitor1001 gmail com>
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <string.h>
 #include <stdio.h>
 
+#include "libavutil/avassert.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/mem.h"
 
@@ -26,79 +31,69 @@
 #include "internal.h"
 #include "video.h"
 
-#ifdef DEBUG
-static char *ff_get_ref_perms_string(char *buf, size_t buf_size, int perms)
-{
-    snprintf(buf, buf_size, "%s%s%s%s%s%s",
-             perms & AV_PERM_READ      ? "r" : "",
-             perms & AV_PERM_WRITE     ? "w" : "",
-             perms & AV_PERM_PRESERVE  ? "p" : "",
-             perms & AV_PERM_REUSE     ? "u" : "",
-             perms & AV_PERM_REUSE2    ? "U" : "",
-             perms & AV_PERM_NEG_LINESIZES ? "n" : "");
-    return buf;
-}
-#endif
-
-static void ff_dlog_ref(void *ctx, AVFilterBufferRef *ref, int end)
-{
-    av_unused char buf[16];
-    av_dlog(ctx,
-            "ref[%p buf:%p refcount:%d perms:%s data:%p linesize[%d, %d, %d, %d] pts:%"PRId64" pos:%"PRId64,
-            ref, ref->buf, ref->buf->refcount, ff_get_ref_perms_string(buf, sizeof(buf), ref->perms), ref->data[0],
-            ref->linesize[0], ref->linesize[1], ref->linesize[2], ref->linesize[3],
-            ref->pts, ref->pos);
-
-    if (ref->video) {
-        av_dlog(ctx, " a:%d/%d s:%dx%d i:%c iskey:%d type:%c",
-                ref->video->pixel_aspect.num, ref->video->pixel_aspect.den,
-                ref->video->w, ref->video->h,
-                !ref->video->interlaced     ? 'P' :         /* Progressive  */
-                ref->video->top_field_first ? 'T' : 'B',    /* Top / Bottom */
-                ref->video->key_frame,
-                av_get_picture_type_char(ref->video->pict_type));
-    }
-    if (ref->audio) {
-        av_dlog(ctx, " cl:%"PRId64"d n:%d r:%d p:%d",
-                ref->audio->channel_layout,
-                ref->audio->nb_samples,
-                ref->audio->sample_rate,
-                ref->audio->planar);
-    }
-
-    av_dlog(ctx, "]%s", end ? "\n" : "");
-}
-
 AVFilterBufferRef *ff_null_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
 {
     return ff_get_video_buffer(link->dst->outputs[0], perms, w, h);
 }
 
-/* TODO: set the buffer's priv member to a context structure for the whole
- * filter chain.  This will allow for a buffer pool instead of the constant
- * alloc & free cycle currently implemented. */
 AVFilterBufferRef *ff_default_get_video_buffer(AVFilterLink *link, int perms, int w, int h)
 {
     int linesize[4];
     uint8_t *data[4];
+    int i;
     AVFilterBufferRef *picref = NULL;
+    AVFilterPool *pool = link->pool;
+    int full_perms = AV_PERM_READ | AV_PERM_WRITE | AV_PERM_PRESERVE |
+                     AV_PERM_REUSE | AV_PERM_REUSE2 | AV_PERM_ALIGN;
 
-    // +2 is needed for swscaler, +16 to be SIMD-friendly
-    if (av_image_alloc(data, linesize, w, h, link->format, 16) < 0)
+    av_assert1(!(perms & ~(full_perms | AV_PERM_NEG_LINESIZES)));
+
+    if (pool) {
+        for (i = 0; i < POOL_SIZE; i++) {
+            picref = pool->pic[i];
+            if (picref && picref->buf->format == link->format && picref->buf->w == w && picref->buf->h == h) {
+                AVFilterBuffer *pic = picref->buf;
+                pool->pic[i] = NULL;
+                pool->count--;
+                av_assert0(!picref->video->qp_table);
+                picref->video->w = w;
+                picref->video->h = h;
+                picref->perms = full_perms;
+                picref->format = link->format;
+                pic->refcount = 1;
+                memcpy(picref->data,     pic->data,     sizeof(picref->data));
+                memcpy(picref->linesize, pic->linesize, sizeof(picref->linesize));
+                pool->refcount++;
+                return picref;
+            }
+        }
+    } else {
+        pool = link->pool = av_mallocz(sizeof(AVFilterPool));
+        pool->refcount = 1;
+    }
+
+    // align: +2 is needed for swscaler, +16 to be SIMD-friendly
+    if ((i = av_image_alloc(data, linesize, w, h, link->format, 32)) < 0)
         return NULL;
 
     picref = avfilter_get_video_buffer_ref_from_arrays(data, linesize,
-                                                       perms, w, h, link->format);
+                                                       full_perms, w, h, link->format);
     if (!picref) {
         av_free(data[0]);
         return NULL;
     }
 
+    memset(data[0], 128, i);
+
+    picref->buf->priv = pool;
+    picref->buf->free = NULL;
+    pool->refcount++;
+
     return picref;
 }
 
 AVFilterBufferRef *
-avfilter_get_video_buffer_ref_from_arrays(uint8_t *data[4], int linesize[4], int perms,
+avfilter_get_video_buffer_ref_from_arrays(uint8_t * const data[4], const int linesize[4], int perms,
                                           int w, int h, enum AVPixelFormat format)
 {
     AVFilterBuffer *pic = av_mallocz(sizeof(AVFilterBuffer));
@@ -147,8 +142,8 @@
     AVFilterBufferRef *ret = NULL;
 
     av_unused char buf[16];
-    FF_DPRINTF_START(NULL, get_video_buffer); ff_dlog_link(NULL, link, 0);
-    av_dlog(NULL, " perms:%s w:%d h:%d\n", ff_get_ref_perms_string(buf, sizeof(buf), perms), w, h);
+    FF_TPRINTF_START(NULL, get_video_buffer); ff_tlog_link(NULL, link, 0);
+    ff_tlog(NULL, " perms:%s w:%d h:%d\n", ff_get_ref_perms_string(buf, sizeof(buf), perms), w, h);
 
     if (link->dstpad->get_video_buffer)
         ret = link->dstpad->get_video_buffer(link, perms, w, h);
@@ -159,7 +154,7 @@
     if (ret)
         ret->type = AVMEDIA_TYPE_VIDEO;
 
-    FF_DPRINTF_START(NULL, get_video_buffer); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " returning "); ff_dlog_ref(NULL, ret, 1);
+    FF_TPRINTF_START(NULL, get_video_buffer); ff_tlog_link(NULL, link, 0); ff_tlog(NULL, " returning "); ff_tlog_ref(NULL, ret, 1);
 
     return ret;
 }
@@ -179,7 +174,7 @@
     AVFilterBufferRef *outpicref = NULL, *for_next_filter;
     int ret = 0;
 
-    if ((inpicref->perms & AV_PERM_WRITE) && !(inpicref->perms & AV_PERM_PRESERVE)) {
+    if (inpicref->perms & AV_PERM_WRITE) {
         outpicref = avfilter_ref_buffer(inpicref, ~0);
         if (!outpicref)
             return AVERROR(ENOMEM);
@@ -222,6 +217,8 @@
             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);
@@ -236,6 +233,7 @@
     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
@@ -243,14 +241,30 @@
 int ff_start_frame(AVFilterLink *link, AVFilterBufferRef *picref)
 {
     int (*start_frame)(AVFilterLink *, AVFilterBufferRef *);
+    AVFilterPad *src = link->srcpad;
     AVFilterPad *dst = link->dstpad;
-    int ret, perms = picref->perms;
+    int ret, perms;
+    AVFilterCommand *cmd= link->dst->command_queue;
+    int64_t pts;
 
-    FF_DPRINTF_START(NULL, start_frame); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " "); ff_dlog_ref(NULL, picref, 1);
+    FF_TPRINTF_START(NULL, start_frame); ff_tlog_link(NULL, link, 0); ff_tlog(NULL, " "); ff_tlog_ref(NULL, picref, 1);
+
+    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 */
@@ -268,13 +282,33 @@
 
         link->src_buf = picref;
         avfilter_copy_buffer_ref_props(link->cur_buf, link->src_buf);
+
+        /* copy palette if required */
+        if (av_pix_fmt_descriptors[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;
 }
@@ -335,7 +369,7 @@
     int i, j, vsub, ret;
     int (*draw_slice)(AVFilterLink *, int, int, int);
 
-    FF_DPRINTF_START(NULL, draw_slice); ff_dlog_link(NULL, link, 0); av_dlog(NULL, " y:%d h:%d dir:%d\n", y, h, slice_dir);
+    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) {
@@ -346,22 +380,22 @@
             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->data[i] +
-                    (y >> (i==1 || i==2 ? vsub : 0)) * link->cur_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->video->w, i);
+                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->linesize[i];
+                dst[i] += link->cur_buf_copy->linesize[i];
             }
         }
     }
@@ -371,5 +405,9 @@
     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 348240c..c677f30 100644
--- a/libavfilter/video.h
+++ b/libavfilter/video.h
@@ -1,21 +1,24 @@
 /*
- * This file is part of Libav.
+ * Copyright (c) 2007 Bobby Bingham
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+
 #ifndef AVFILTER_VIDEO_H
 #define AVFILTER_VIDEO_H
 
@@ -59,6 +62,11 @@
 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
diff --git a/libavfilter/vsink_nullsink.c b/libavfilter/vsink_nullsink.c
index b10ee62..89bf29a 100644
--- a/libavfilter/vsink_nullsink.c
+++ b/libavfilter/vsink_nullsink.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavfilter/vsrc_cellauto.c b/libavfilter/vsrc_cellauto.c
new file mode 100644
index 0000000..3a4726b
--- /dev/null
+++ b/libavfilter/vsrc_cellauto.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) Stefano Sabatini 2011
+ *
+ * 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
+ * cellular automaton video source, based on Stephen Wolfram "experimentus crucis"
+ */
+
+/* #define DEBUG */
+
+#include "libavutil/file.h"
+#include "libavutil/lfg.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/random_seed.h"
+#include "avfilter.h"
+#include "internal.h"
+#include "formats.h"
+#include "video.h"
+
+typedef struct {
+    const AVClass *class;
+    int w, h;
+    char *filename;
+    char *rule_str;
+    uint8_t *file_buf;
+    size_t file_bufsize;
+    uint8_t *buf;
+    int buf_prev_row_idx, buf_row_idx;
+    uint8_t rule;
+    uint64_t pts;
+    AVRational time_base;
+    char *rate;                 ///< video frame rate
+    double   random_fill_ratio;
+    uint32_t random_seed;
+    int stitch, scroll, start_full;
+    int64_t generation;         ///< the generation number, starting from 0
+    AVLFG lfg;
+    char *pattern;
+} CellAutoContext;
+
+#define OFFSET(x) offsetof(CellAutoContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+
+static const AVOption cellauto_options[] = {
+    { "filename", "read initial pattern from file", OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+    { "f",        "read initial pattern from file", OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+    { "pattern",  "set initial pattern", OFFSET(pattern), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+    { "p",        "set initial pattern", OFFSET(pattern), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+    { "rate",     "set video rate", OFFSET(rate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, FLAGS },
+    { "r",        "set video rate", OFFSET(rate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, FLAGS },
+    { "size",     "set video size", OFFSET(w),    AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, FLAGS },
+    { "s",        "set video size", OFFSET(w),    AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, FLAGS },
+    { "rule",     "set rule",       OFFSET(rule), AV_OPT_TYPE_INT,    {.i64 = 110},  0, 255, FLAGS },
+    { "random_fill_ratio", "set fill ratio for filling initial grid randomly", OFFSET(random_fill_ratio), AV_OPT_TYPE_DOUBLE, {.dbl = 1/M_PHI}, 0, 1, FLAGS },
+    { "ratio",             "set fill ratio for filling initial grid randomly", OFFSET(random_fill_ratio), AV_OPT_TYPE_DOUBLE, {.dbl = 1/M_PHI}, 0, 1, FLAGS },
+    { "random_seed", "set the seed for filling the initial grid randomly", OFFSET(random_seed), AV_OPT_TYPE_INT, {.i64 = -1}, -1, UINT32_MAX, FLAGS },
+    { "seed",        "set the seed for filling the initial grid randomly", OFFSET(random_seed), AV_OPT_TYPE_INT, {.i64 = -1}, -1, UINT32_MAX, FLAGS },
+    { "scroll",      "scroll pattern downward", OFFSET(scroll), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, FLAGS },
+    { "start_full",  "start filling the whole video", OFFSET(start_full), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS },
+    { "full",        "start filling the whole video", OFFSET(start_full), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, FLAGS },
+    { "stitch",      "stitch boundaries", OFFSET(stitch), AV_OPT_TYPE_INT,    {.i64 = 1},   0, 1, FLAGS },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(cellauto);
+
+#ifdef DEBUG
+static void show_cellauto_row(AVFilterContext *ctx)
+{
+    CellAutoContext *cellauto = ctx->priv;
+    int i;
+    uint8_t *row = cellauto->buf + cellauto->w * cellauto->buf_row_idx;
+    char *line = av_malloc(cellauto->w + 1);
+    if (!line)
+        return;
+
+    for (i = 0; i < cellauto->w; i++)
+        line[i] = row[i] ? '@' : ' ';
+    line[i] = 0;
+    av_log(ctx, AV_LOG_DEBUG, "generation:%"PRId64" row:%s|\n", cellauto->generation, line);
+    av_free(line);
+}
+#endif
+
+static int init_pattern_from_string(AVFilterContext *ctx)
+{
+    CellAutoContext *cellauto = ctx->priv;
+    char *p;
+    int i, w = 0;
+
+    w = strlen(cellauto->pattern);
+    av_log(ctx, AV_LOG_DEBUG, "w:%d\n", w);
+
+    if (cellauto->w) {
+        if (w > cellauto->w) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "The specified width is %d which cannot contain the provided string width of %d\n",
+                   cellauto->w, w);
+            return AVERROR(EINVAL);
+        }
+    } else {
+        /* width was not specified, set it to width of the provided row */
+        cellauto->w = w;
+        cellauto->h = (double)cellauto->w * M_PHI;
+    }
+
+    cellauto->buf = av_mallocz(sizeof(uint8_t) * cellauto->w * cellauto->h);
+    if (!cellauto->buf)
+        return AVERROR(ENOMEM);
+
+    /* fill buf */
+    p = cellauto->pattern;
+    for (i = (cellauto->w - w)/2;; i++) {
+        av_log(ctx, AV_LOG_DEBUG, "%d %c\n", i, *p == '\n' ? 'N' : *p);
+        if (*p == '\n' || !*p)
+            break;
+        else
+            cellauto->buf[i] = !!isgraph(*(p++));
+    }
+
+    return 0;
+}
+
+static int init_pattern_from_file(AVFilterContext *ctx)
+{
+    CellAutoContext *cellauto = ctx->priv;
+    int ret;
+
+    ret = av_file_map(cellauto->filename,
+                      &cellauto->file_buf, &cellauto->file_bufsize, 0, ctx);
+    if (ret < 0)
+        return ret;
+
+    /* create a string based on the read file */
+    cellauto->pattern = av_malloc(cellauto->file_bufsize + 1);
+    if (!cellauto->pattern)
+        return AVERROR(ENOMEM);
+    memcpy(cellauto->pattern, cellauto->file_buf, cellauto->file_bufsize);
+    cellauto->pattern[cellauto->file_bufsize] = 0;
+
+    return init_pattern_from_string(ctx);
+}
+
+static int init(AVFilterContext *ctx, const char *args)
+{
+    CellAutoContext *cellauto = ctx->priv;
+    AVRational frame_rate;
+    int ret;
+
+    cellauto->class = &cellauto_class;
+    av_opt_set_defaults(cellauto);
+
+    if ((ret = av_set_options_string(cellauto, args, "=", ":")) < 0)
+        return ret;
+
+    if ((ret = av_parse_video_rate(&frame_rate, cellauto->rate)) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: %s\n", cellauto->rate);
+        return AVERROR(EINVAL);
+    }
+
+    if (!cellauto->w && !cellauto->filename && !cellauto->pattern)
+        av_opt_set(cellauto, "size", "320x518", 0);
+
+    cellauto->time_base.num = frame_rate.den;
+    cellauto->time_base.den = frame_rate.num;
+
+    if (cellauto->filename && cellauto->pattern) {
+        av_log(ctx, AV_LOG_ERROR, "Only one of the filename or pattern options can be used\n");
+        return AVERROR(EINVAL);
+    }
+
+    if (cellauto->filename) {
+        if ((ret = init_pattern_from_file(ctx)) < 0)
+            return ret;
+    } else if (cellauto->pattern) {
+        if ((ret = init_pattern_from_string(ctx)) < 0)
+            return ret;
+    } else {
+        /* fill the first row randomly */
+        int i;
+
+        cellauto->buf = av_mallocz(sizeof(uint8_t) * cellauto->w * cellauto->h);
+        if (!cellauto->buf)
+            return AVERROR(ENOMEM);
+        if (cellauto->random_seed == -1)
+            cellauto->random_seed = av_get_random_seed();
+
+        av_lfg_init(&cellauto->lfg, cellauto->random_seed);
+
+        for (i = 0; i < cellauto->w; i++) {
+            double r = (double)av_lfg_get(&cellauto->lfg) / UINT32_MAX;
+            if (r <= cellauto->random_fill_ratio)
+                cellauto->buf[i] = 1;
+        }
+    }
+
+    av_log(ctx, AV_LOG_VERBOSE,
+           "s:%dx%d r:%d/%d rule:%d stitch:%d scroll:%d full:%d seed:%u\n",
+           cellauto->w, cellauto->h, frame_rate.num, frame_rate.den,
+           cellauto->rule, cellauto->stitch, cellauto->scroll, cellauto->start_full,
+           cellauto->random_seed);
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    CellAutoContext *cellauto = ctx->priv;
+
+    av_file_unmap(cellauto->file_buf, cellauto->file_bufsize);
+    av_freep(&cellauto->buf);
+    av_freep(&cellauto->pattern);
+}
+
+static int config_props(AVFilterLink *outlink)
+{
+    CellAutoContext *cellauto = outlink->src->priv;
+
+    outlink->w = cellauto->w;
+    outlink->h = cellauto->h;
+    outlink->time_base = cellauto->time_base;
+
+    return 0;
+}
+
+static void evolve(AVFilterContext *ctx)
+{
+    CellAutoContext *cellauto = ctx->priv;
+    int i, v, pos[3];
+    uint8_t *row, *prev_row = cellauto->buf + cellauto->buf_row_idx * cellauto->w;
+    enum { NW, N, NE };
+
+    cellauto->buf_prev_row_idx = cellauto->buf_row_idx;
+    cellauto->buf_row_idx      = cellauto->buf_row_idx == cellauto->h-1 ? 0 : cellauto->buf_row_idx+1;
+    row = cellauto->buf + cellauto->w * cellauto->buf_row_idx;
+
+    for (i = 0; i < cellauto->w; i++) {
+        if (cellauto->stitch) {
+            pos[NW] = i-1 < 0 ? cellauto->w-1 : i-1;
+            pos[N]  = i;
+            pos[NE] = i+1 == cellauto->w ? 0  : i+1;
+            v = prev_row[pos[NW]]<<2 | prev_row[pos[N]]<<1 | prev_row[pos[NE]];
+        } else {
+            v = 0;
+            v|= i-1 >= 0          ? prev_row[i-1]<<2 : 0;
+            v|=                     prev_row[i  ]<<1    ;
+            v|= i+1 < cellauto->w ? prev_row[i+1]    : 0;
+        }
+        row[i] = !!(cellauto->rule & (1<<v));
+        av_dlog(ctx, "i:%d context:%c%c%c -> cell:%d\n", i,
+                v&4?'@':' ', v&2?'@':' ', v&1?'@':' ', row[i]);
+    }
+
+    cellauto->generation++;
+}
+
+static void fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
+{
+    CellAutoContext *cellauto = ctx->priv;
+    int i, j, k, row_idx = 0;
+    uint8_t *p0 = picref->data[0];
+
+    if (cellauto->scroll && cellauto->generation >= cellauto->h)
+        /* show on top the oldest row */
+        row_idx = (cellauto->buf_row_idx + 1) % cellauto->h;
+
+    /* fill the output picture with the whole buffer */
+    for (i = 0; i < cellauto->h; i++) {
+        uint8_t byte = 0;
+        uint8_t *row = cellauto->buf + row_idx*cellauto->w;
+        uint8_t *p = p0;
+        for (k = 0, j = 0; j < cellauto->w; j++) {
+            byte |= row[j]<<(7-k++);
+            if (k==8 || j == cellauto->w-1) {
+                k = 0;
+                *p++ = byte;
+                byte = 0;
+            }
+        }
+        row_idx = (row_idx + 1) % cellauto->h;
+        p0 += picref->linesize[0];
+    }
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    CellAutoContext *cellauto = outlink->src->priv;
+    AVFilterBufferRef *picref =
+        ff_get_video_buffer(outlink, AV_PERM_WRITE, cellauto->w, cellauto->h);
+    picref->video->sample_aspect_ratio = (AVRational) {1, 1};
+    if (cellauto->generation == 0 && cellauto->start_full) {
+        int i;
+        for (i = 0; i < cellauto->h-1; i++)
+            evolve(outlink->src);
+    }
+    fill_picture(outlink->src, picref);
+    evolve(outlink->src);
+
+    picref->pts = cellauto->pts++;
+    picref->pos = -1;
+
+#ifdef DEBUG
+    show_cellauto_row(outlink->src);
+#endif
+
+    ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
+    ff_draw_slice(outlink, 0, cellauto->h, 1);
+    ff_end_frame(outlink);
+    avfilter_unref_buffer(picref);
+
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_NONE };
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+AVFilter avfilter_vsrc_cellauto = {
+    .name        = "cellauto",
+    .description = NULL_IF_CONFIG_SMALL("Create pattern generated by an elementary cellular automaton."),
+    .priv_size = sizeof(CellAutoContext),
+    .init      = init,
+    .uninit    = uninit,
+    .query_formats = query_formats,
+
+    .inputs    = (const AVFilterPad[]) {
+        { .name = NULL}
+    },
+    .outputs   = (const AVFilterPad[]) {
+        { .name            = "default",
+          .type            = AVMEDIA_TYPE_VIDEO,
+          .request_frame   = request_frame,
+          .config_props    = config_props },
+        { .name = NULL}
+    },
+    .priv_class = &cellauto_class,
+};
diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c
deleted file mode 100644
index 2bb07bf..0000000
--- a/libavfilter/vsrc_color.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) 2010 Stefano Sabatini
- *
- * 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
- * color source
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "avfilter.h"
-#include "formats.h"
-#include "internal.h"
-#include "video.h"
-#include "libavutil/pixdesc.h"
-#include "libavutil/colorspace.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/internal.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/mem.h"
-#include "libavutil/parseutils.h"
-#include "drawutils.h"
-
-typedef struct {
-    int w, h;
-    uint8_t color[4];
-    AVRational time_base;
-    uint8_t *line[4];
-    int      line_step[4];
-    int hsub, vsub;         ///< chroma subsampling values
-    uint64_t pts;
-} ColorContext;
-
-static av_cold int color_init(AVFilterContext *ctx, const char *args)
-{
-    ColorContext *color = ctx->priv;
-    char color_string[128] = "black";
-    char frame_size  [128] = "320x240";
-    char frame_rate  [128] = "25";
-    AVRational frame_rate_q;
-    int ret;
-
-    if (args)
-        sscanf(args, "%127[^:]:%127[^:]:%127s", color_string, frame_size, frame_rate);
-
-    if (av_parse_video_size(&color->w, &color->h, frame_size) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid frame size: %s\n", frame_size);
-        return AVERROR(EINVAL);
-    }
-
-    if (av_parse_video_rate(&frame_rate_q, frame_rate) < 0 ||
-        frame_rate_q.den <= 0 || frame_rate_q.num <= 0) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: %s\n", frame_rate);
-        return AVERROR(EINVAL);
-    }
-    color->time_base.num = frame_rate_q.den;
-    color->time_base.den = frame_rate_q.num;
-
-    if ((ret = av_parse_color(color->color, color_string, -1, ctx)) < 0)
-        return ret;
-
-    return 0;
-}
-
-static av_cold void color_uninit(AVFilterContext *ctx)
-{
-    ColorContext *color = ctx->priv;
-    int i;
-
-    for (i = 0; i < 4; i++) {
-        av_freep(&color->line[i]);
-        color->line_step[i] = 0;
-    }
-}
-
-static int query_formats(AVFilterContext *ctx)
-{
-    static const 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_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_NONE
-    };
-
-    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
-    return 0;
-}
-
-static int color_config_props(AVFilterLink *inlink)
-{
-    AVFilterContext *ctx = inlink->src;
-    ColorContext *color = ctx->priv;
-    uint8_t rgba_color[4];
-    int is_packed_rgba;
-    const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);
-
-    color->hsub = pix_desc->log2_chroma_w;
-    color->vsub = pix_desc->log2_chroma_h;
-
-    color->w &= ~((1 << color->hsub) - 1);
-    color->h &= ~((1 << color->vsub) - 1);
-    if (av_image_check_size(color->w, color->h, 0, ctx) < 0)
-        return AVERROR(EINVAL);
-
-    memcpy(rgba_color, color->color, sizeof(rgba_color));
-    ff_fill_line_with_color(color->line, color->line_step, color->w, color->color,
-                            inlink->format, rgba_color, &is_packed_rgba, NULL);
-
-    av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d r:%d/%d color:0x%02x%02x%02x%02x[%s]\n",
-           color->w, color->h, color->time_base.den, color->time_base.num,
-           color->color[0], color->color[1], color->color[2], color->color[3],
-           is_packed_rgba ? "rgba" : "yuva");
-    inlink->w = color->w;
-    inlink->h = color->h;
-    inlink->time_base = color->time_base;
-
-    return 0;
-}
-
-static int color_request_frame(AVFilterLink *link)
-{
-    ColorContext *color = link->src->priv;
-    AVFilterBufferRef *picref = ff_get_video_buffer(link, AV_PERM_WRITE, color->w, color->h);
-    AVFilterBufferRef *buf_out;
-    int ret;
-
-    if (!picref)
-        return AVERROR(ENOMEM);
-
-    picref->video->pixel_aspect = (AVRational) {1, 1};
-    picref->pts                 = color->pts++;
-    picref->pos                 = -1;
-
-    buf_out = avfilter_ref_buffer(picref, ~0);
-    if (!buf_out) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
-
-    ret = ff_start_frame(link, buf_out);
-    if (ret < 0)
-        goto fail;
-
-    ff_draw_rectangle(picref->data, picref->linesize,
-                      color->line, color->line_step, color->hsub, color->vsub,
-                      0, 0, color->w, color->h);
-    ret = ff_draw_slice(link, 0, color->h, 1);
-    if (ret < 0)
-        goto fail;
-
-    ret = ff_end_frame(link);
-
-fail:
-    avfilter_unref_buffer(picref);
-
-    return ret;
-}
-
-static const AVFilterPad avfilter_vsrc_color_outputs[] = {
-    {
-        .name          = "default",
-        .type          = AVMEDIA_TYPE_VIDEO,
-        .request_frame = color_request_frame,
-        .config_props  = color_config_props
-    },
-    { NULL }
-};
-
-AVFilter avfilter_vsrc_color = {
-    .name        = "color",
-    .description = NULL_IF_CONFIG_SMALL("Provide an uniformly colored input, syntax is: [color[:size[:rate]]]"),
-
-    .priv_size = sizeof(ColorContext),
-    .init      = color_init,
-    .uninit    = color_uninit,
-
-    .query_formats = query_formats,
-
-    .inputs    = NULL,
-
-    .outputs   = avfilter_vsrc_color_outputs,
-};
diff --git a/libavfilter/vsrc_life.c b/libavfilter/vsrc_life.c
new file mode 100644
index 0000000..9ea4147
--- /dev/null
+++ b/libavfilter/vsrc_life.c
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) Stefano Sabatini 2010
+ *
+ * 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
+ * life video source, based on John Conways' Life Game
+ */
+
+/* #define DEBUG */
+
+#include "libavutil/file.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/lfg.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/random_seed.h"
+#include "avfilter.h"
+#include "internal.h"
+#include "formats.h"
+#include "video.h"
+
+typedef struct {
+    const AVClass *class;
+    int w, h;
+    char *filename;
+    char *rule_str;
+    uint8_t *file_buf;
+    size_t file_bufsize;
+
+    /**
+     * The two grid state buffers.
+     *
+     * A 0xFF (ALIVE_CELL) value means the cell is alive (or new born), while
+     * the decreasing values from 0xFE to 0 means the cell is dead; the range
+     * of values is used for the slow death effect, or mold (0xFE means dead,
+     * 0xFD means very dead, 0xFC means very very dead... and 0x00 means
+     * definitely dead/mold).
+     */
+    uint8_t *buf[2];
+
+    uint8_t  buf_idx;
+    uint16_t stay_rule;         ///< encode the behavior for filled cells
+    uint16_t born_rule;         ///< encode the behavior for empty cells
+    uint64_t pts;
+    AVRational time_base;
+    char *rate;                 ///< video frame rate
+    double   random_fill_ratio;
+    uint32_t random_seed;
+    int stitch;
+    int mold;
+    char  *life_color_str;
+    char *death_color_str;
+    char  *mold_color_str;
+    uint8_t  life_color[4];
+    uint8_t death_color[4];
+    uint8_t  mold_color[4];
+    AVLFG lfg;
+    void (*draw)(AVFilterContext*, AVFilterBufferRef*);
+} LifeContext;
+
+#define ALIVE_CELL 0xFF
+#define OFFSET(x) offsetof(LifeContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption life_options[] = {
+    { "filename", "set source file",  OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+    { "f",        "set source file",  OFFSET(filename), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+    { "size",     "set video size",   OFFSET(w),        AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, FLAGS },
+    { "s",        "set video size",   OFFSET(w),        AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, FLAGS },
+    { "rate",     "set video rate",   OFFSET(rate),     AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, FLAGS },
+    { "r",        "set video rate",   OFFSET(rate),     AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, FLAGS },
+    { "rule",     "set rule",         OFFSET(rule_str), AV_OPT_TYPE_STRING, {.str = "B3/S23"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "random_fill_ratio", "set fill ratio for filling initial grid randomly", OFFSET(random_fill_ratio), AV_OPT_TYPE_DOUBLE, {.dbl=1/M_PHI}, 0, 1, FLAGS },
+    { "ratio",             "set fill ratio for filling initial grid randomly", OFFSET(random_fill_ratio), AV_OPT_TYPE_DOUBLE, {.dbl=1/M_PHI}, 0, 1, FLAGS },
+    { "random_seed", "set the seed for filling the initial grid randomly", OFFSET(random_seed), AV_OPT_TYPE_INT, {.i64=-1}, -1, UINT32_MAX, FLAGS },
+    { "seed",        "set the seed for filling the initial grid randomly", OFFSET(random_seed), AV_OPT_TYPE_INT, {.i64=-1}, -1, UINT32_MAX, FLAGS },
+    { "stitch",      "stitch boundaries", OFFSET(stitch), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS },
+    { "mold",        "set mold speed for dead cells", OFFSET(mold), AV_OPT_TYPE_INT, {.i64=0}, 0, 0xFF, FLAGS },
+    { "life_color",  "set life color",  OFFSET( life_color_str), AV_OPT_TYPE_STRING, {.str="white"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "death_color", "set death color", OFFSET(death_color_str), AV_OPT_TYPE_STRING, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "mold_color",  "set mold color",  OFFSET( mold_color_str), AV_OPT_TYPE_STRING, {.str="black"}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(life);
+
+static int parse_rule(uint16_t *born_rule, uint16_t *stay_rule,
+                      const char *rule_str, void *log_ctx)
+{
+    char *tail;
+    const char *p = rule_str;
+    *born_rule = 0;
+    *stay_rule = 0;
+
+    if (strchr("bBsS", *p)) {
+        /* parse rule as a Born / Stay Alive code, see
+         * http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life */
+        do {
+            uint16_t *rule = (*p == 'b' || *p == 'B') ? born_rule : stay_rule;
+            p++;
+            while (*p >= '0' && *p <= '8') {
+                *rule += 1<<(*p - '0');
+                p++;
+            }
+            if (*p != '/')
+                break;
+            p++;
+        } while (strchr("bBsS", *p));
+
+        if (*p)
+            goto error;
+    } else {
+        /* parse rule as a number, expressed in the form STAY|(BORN<<9),
+         * where STAY and BORN encode the corresponding 9-bits rule */
+        long int rule = strtol(rule_str, &tail, 10);
+        if (*tail)
+            goto error;
+        *born_rule  = ((1<<9)-1) & rule;
+        *stay_rule = rule >> 9;
+    }
+
+    return 0;
+
+error:
+    av_log(log_ctx, AV_LOG_ERROR, "Invalid rule code '%s' provided\n", rule_str);
+    return AVERROR(EINVAL);
+}
+
+#ifdef DEBUG
+static void show_life_grid(AVFilterContext *ctx)
+{
+    LifeContext *life = ctx->priv;
+    int i, j;
+
+    char *line = av_malloc(life->w + 1);
+    if (!line)
+        return;
+    for (i = 0; i < life->h; i++) {
+        for (j = 0; j < life->w; j++)
+            line[j] = life->buf[life->buf_idx][i*life->w + j] == ALIVE_CELL ? '@' : ' ';
+        line[j] = 0;
+        av_log(ctx, AV_LOG_DEBUG, "%3d: %s\n", i, line);
+    }
+    av_free(line);
+}
+#endif
+
+static int init_pattern_from_file(AVFilterContext *ctx)
+{
+    LifeContext *life = ctx->priv;
+    char *p;
+    int ret, i, i0, j, h = 0, w, max_w = 0;
+
+    if ((ret = av_file_map(life->filename, &life->file_buf, &life->file_bufsize,
+                           0, ctx)) < 0)
+        return ret;
+    av_freep(&life->filename);
+
+    /* prescan file to get the number of lines and the maximum width */
+    w = 0;
+    for (i = 0; i < life->file_bufsize; i++) {
+        if (life->file_buf[i] == '\n') {
+            h++; max_w = FFMAX(w, max_w); w = 0;
+        } else {
+            w++;
+        }
+    }
+    av_log(ctx, AV_LOG_DEBUG, "h:%d max_w:%d\n", h, max_w);
+
+    if (life->w) {
+        if (max_w > life->w || h > life->h) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "The specified size is %dx%d which cannot contain the provided file size of %dx%d\n",
+                   life->w, life->h, max_w, h);
+            return AVERROR(EINVAL);
+        }
+    } else {
+        /* size was not specified, set it to size of the grid */
+        life->w = max_w;
+        life->h = h;
+    }
+
+    if (!(life->buf[0] = av_mallocz(sizeof(char) * life->h * life->w)) ||
+        !(life->buf[1] = av_mallocz(sizeof(char) * life->h * life->w))) {
+        av_free(life->buf[0]);
+        av_free(life->buf[1]);
+        return AVERROR(ENOMEM);
+    }
+
+    /* fill buf[0] */
+    p = life->file_buf;
+    for (i0 = 0, i = (life->h - h)/2; i0 < h; i0++, i++) {
+        for (j = (life->w - max_w)/2;; j++) {
+            av_log(ctx, AV_LOG_DEBUG, "%d:%d %c\n", i, j, *p == '\n' ? 'N' : *p);
+            if (*p == '\n') {
+                p++; break;
+            } else
+                life->buf[0][i*life->w + j] = isgraph(*(p++)) ? ALIVE_CELL : 0;
+        }
+    }
+    life->buf_idx = 0;
+
+    return 0;
+}
+
+static int init(AVFilterContext *ctx, const char *args)
+{
+    LifeContext *life = ctx->priv;
+    AVRational frame_rate;
+    int ret;
+
+    life->class = &life_class;
+    av_opt_set_defaults(life);
+
+    if ((ret = av_set_options_string(life, args, "=", ":")) < 0)
+        return ret;
+
+    if ((ret = av_parse_video_rate(&frame_rate, life->rate)) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: %s\n", life->rate);
+        return AVERROR(EINVAL);
+    }
+    av_freep(&life->rate);
+
+    if (!life->w && !life->filename)
+        av_opt_set(life, "size", "320x240", 0);
+
+    if ((ret = parse_rule(&life->born_rule, &life->stay_rule, life->rule_str, ctx)) < 0)
+        return ret;
+
+#define PARSE_COLOR(name) do { \
+    if ((ret = av_parse_color(life->name ## _color, life->name ## _color_str, -1, ctx))) { \
+        av_log(ctx, AV_LOG_ERROR, "Invalid " #name " color '%s'\n", \
+               life->name ## _color_str); \
+        return ret; \
+    } \
+    av_freep(&life->name ## _color_str); \
+} while (0)
+
+    PARSE_COLOR(life);
+    PARSE_COLOR(death);
+    PARSE_COLOR(mold);
+
+    if (!life->mold && memcmp(life->mold_color, "\x00\x00\x00", 3))
+        av_log(ctx, AV_LOG_WARNING,
+               "Mold color is set while mold isn't, ignoring the color.\n");
+
+    life->time_base.num = frame_rate.den;
+    life->time_base.den = frame_rate.num;
+
+    if (!life->filename) {
+        /* fill the grid randomly */
+        int i;
+
+        if (!(life->buf[0] = av_mallocz(sizeof(char) * life->h * life->w)) ||
+            !(life->buf[1] = av_mallocz(sizeof(char) * life->h * life->w))) {
+            av_free(life->buf[0]);
+            av_free(life->buf[1]);
+            return AVERROR(ENOMEM);
+        }
+        if (life->random_seed == -1)
+            life->random_seed = av_get_random_seed();
+
+        av_lfg_init(&life->lfg, life->random_seed);
+
+        for (i = 0; i < life->w * life->h; i++) {
+            double r = (double)av_lfg_get(&life->lfg) / UINT32_MAX;
+            if (r <= life->random_fill_ratio)
+                life->buf[0][i] = ALIVE_CELL;
+        }
+        life->buf_idx = 0;
+    } else {
+        if ((ret = init_pattern_from_file(ctx)) < 0)
+            return ret;
+    }
+
+    av_log(ctx, AV_LOG_VERBOSE,
+           "s:%dx%d r:%d/%d rule:%s stay_rule:%d born_rule:%d stitch:%d seed:%u\n",
+           life->w, life->h, frame_rate.num, frame_rate.den,
+           life->rule_str, life->stay_rule, life->born_rule, life->stitch,
+           life->random_seed);
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    LifeContext *life = ctx->priv;
+
+    av_file_unmap(life->file_buf, life->file_bufsize);
+    av_freep(&life->rule_str);
+    av_freep(&life->buf[0]);
+    av_freep(&life->buf[1]);
+}
+
+static int config_props(AVFilterLink *outlink)
+{
+    LifeContext *life = outlink->src->priv;
+
+    outlink->w = life->w;
+    outlink->h = life->h;
+    outlink->time_base = life->time_base;
+
+    return 0;
+}
+
+static void evolve(AVFilterContext *ctx)
+{
+    LifeContext *life = ctx->priv;
+    int i, j;
+    uint8_t *oldbuf = life->buf[ life->buf_idx];
+    uint8_t *newbuf = life->buf[!life->buf_idx];
+
+    enum { NW, N, NE, W, E, SW, S, SE };
+
+    /* evolve the grid */
+    for (i = 0; i < life->h; i++) {
+        for (j = 0; j < life->w; j++) {
+            int pos[8][2], n, alive, cell;
+            if (life->stitch) {
+                pos[NW][0] = (i-1) < 0 ? life->h-1 : i-1; pos[NW][1] = (j-1) < 0 ? life->w-1 : j-1;
+                pos[N ][0] = (i-1) < 0 ? life->h-1 : i-1; pos[N ][1] =                         j  ;
+                pos[NE][0] = (i-1) < 0 ? life->h-1 : i-1; pos[NE][1] = (j+1) == life->w ?  0 : j+1;
+                pos[W ][0] =                         i  ; pos[W ][1] = (j-1) < 0 ? life->w-1 : j-1;
+                pos[E ][0] =                         i  ; pos[E ][1] = (j+1) == life->w ? 0  : j+1;
+                pos[SW][0] = (i+1) == life->h ?  0 : i+1; pos[SW][1] = (j-1) < 0 ? life->w-1 : j-1;
+                pos[S ][0] = (i+1) == life->h ?  0 : i+1; pos[S ][1] =                         j  ;
+                pos[SE][0] = (i+1) == life->h ?  0 : i+1; pos[SE][1] = (j+1) == life->w ?  0 : j+1;
+            } else {
+                pos[NW][0] = (i-1) < 0 ? -1        : i-1; pos[NW][1] = (j-1) < 0 ? -1        : j-1;
+                pos[N ][0] = (i-1) < 0 ? -1        : i-1; pos[N ][1] =                         j  ;
+                pos[NE][0] = (i-1) < 0 ? -1        : i-1; pos[NE][1] = (j+1) == life->w ? -1 : j+1;
+                pos[W ][0] =                         i  ; pos[W ][1] = (j-1) < 0 ? -1        : j-1;
+                pos[E ][0] =                         i  ; pos[E ][1] = (j+1) == life->w ? -1 : j+1;
+                pos[SW][0] = (i+1) == life->h ? -1 : i+1; pos[SW][1] = (j-1) < 0 ? -1        : j-1;
+                pos[S ][0] = (i+1) == life->h ? -1 : i+1; pos[S ][1] =                         j  ;
+                pos[SE][0] = (i+1) == life->h ? -1 : i+1; pos[SE][1] = (j+1) == life->w ? -1 : j+1;
+            }
+
+            /* compute the number of live neighbor cells */
+            n = (pos[NW][0] == -1 || pos[NW][1] == -1 ? 0 : oldbuf[pos[NW][0]*life->w + pos[NW][1]] == ALIVE_CELL) +
+                (pos[N ][0] == -1 || pos[N ][1] == -1 ? 0 : oldbuf[pos[N ][0]*life->w + pos[N ][1]] == ALIVE_CELL) +
+                (pos[NE][0] == -1 || pos[NE][1] == -1 ? 0 : oldbuf[pos[NE][0]*life->w + pos[NE][1]] == ALIVE_CELL) +
+                (pos[W ][0] == -1 || pos[W ][1] == -1 ? 0 : oldbuf[pos[W ][0]*life->w + pos[W ][1]] == ALIVE_CELL) +
+                (pos[E ][0] == -1 || pos[E ][1] == -1 ? 0 : oldbuf[pos[E ][0]*life->w + pos[E ][1]] == ALIVE_CELL) +
+                (pos[SW][0] == -1 || pos[SW][1] == -1 ? 0 : oldbuf[pos[SW][0]*life->w + pos[SW][1]] == ALIVE_CELL) +
+                (pos[S ][0] == -1 || pos[S ][1] == -1 ? 0 : oldbuf[pos[S ][0]*life->w + pos[S ][1]] == ALIVE_CELL) +
+                (pos[SE][0] == -1 || pos[SE][1] == -1 ? 0 : oldbuf[pos[SE][0]*life->w + pos[SE][1]] == ALIVE_CELL);
+            cell  = oldbuf[i*life->w + j];
+            alive = 1<<n & (cell == ALIVE_CELL ? life->stay_rule : life->born_rule);
+            if (alive)     *newbuf = ALIVE_CELL; // new cell is alive
+            else if (cell) *newbuf = cell - 1;   // new cell is dead and in the process of mold
+            else           *newbuf = 0;          // new cell is definitely dead
+            av_dlog(ctx, "i:%d j:%d live_neighbors:%d cell:%d -> cell:%d\n", i, j, n, cell, *newbuf);
+            newbuf++;
+        }
+    }
+
+    life->buf_idx = !life->buf_idx;
+}
+
+static void fill_picture_monoblack(AVFilterContext *ctx, AVFilterBufferRef *picref)
+{
+    LifeContext *life = ctx->priv;
+    uint8_t *buf = life->buf[life->buf_idx];
+    int i, j, k;
+
+    /* fill the output picture with the old grid buffer */
+    for (i = 0; i < life->h; i++) {
+        uint8_t byte = 0;
+        uint8_t *p = picref->data[0] + i * picref->linesize[0];
+        for (k = 0, j = 0; j < life->w; j++) {
+            byte |= (buf[i*life->w+j] == ALIVE_CELL)<<(7-k++);
+            if (k==8 || j == life->w-1) {
+                k = 0;
+                *p++ = byte;
+                byte = 0;
+            }
+        }
+    }
+}
+
+// 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)
+
+static void fill_picture_rgb(AVFilterContext *ctx, AVFilterBufferRef *picref)
+{
+    LifeContext *life = ctx->priv;
+    uint8_t *buf = life->buf[life->buf_idx];
+    int i, j;
+
+    /* fill the output picture with the old grid buffer */
+    for (i = 0; i < life->h; i++) {
+        uint8_t *p = picref->data[0] + i * picref->linesize[0];
+        for (j = 0; j < life->w; j++) {
+            uint8_t v = buf[i*life->w + j];
+            if (life->mold && v != ALIVE_CELL) {
+                const uint8_t *c1 = life-> mold_color;
+                const uint8_t *c2 = life->death_color;
+                int death_age = FFMIN((0xff - v) * life->mold, 0xff);
+                *p++ = FAST_DIV255((c2[0] << 8) + ((int)c1[0] - (int)c2[0]) * death_age);
+                *p++ = FAST_DIV255((c2[1] << 8) + ((int)c1[1] - (int)c2[1]) * death_age);
+                *p++ = FAST_DIV255((c2[2] << 8) + ((int)c1[2] - (int)c2[2]) * death_age);
+            } else {
+                const uint8_t *c = v == ALIVE_CELL ? life->life_color : life->death_color;
+                AV_WB24(p, c[0]<<16 | c[1]<<8 | c[2]);
+                p += 3;
+            }
+        }
+    }
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    LifeContext *life = outlink->src->priv;
+    AVFilterBufferRef *picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, life->w, life->h);
+    picref->video->sample_aspect_ratio = (AVRational) {1, 1};
+    picref->pts = life->pts++;
+    picref->pos = -1;
+
+    life->draw(outlink->src, picref);
+    evolve(outlink->src);
+#ifdef DEBUG
+    show_life_grid(outlink->src);
+#endif
+
+    ff_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
+    ff_draw_slice(outlink, 0, life->h, 1);
+    ff_end_frame(outlink);
+    avfilter_unref_buffer(picref);
+
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    LifeContext *life = ctx->priv;
+    enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_NONE, AV_PIX_FMT_NONE };
+    if (life->mold || memcmp(life-> life_color, "\xff\xff\xff", 3)
+                   || memcmp(life->death_color, "\x00\x00\x00", 3)) {
+        pix_fmts[0] = AV_PIX_FMT_RGB24;
+        life->draw = fill_picture_rgb;
+    } else {
+        pix_fmts[0] = AV_PIX_FMT_MONOBLACK;
+        life->draw = fill_picture_monoblack;
+    }
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+AVFilter avfilter_vsrc_life = {
+    .name        = "life",
+    .description = NULL_IF_CONFIG_SMALL("Create life."),
+    .priv_size = sizeof(LifeContext),
+    .init      = init,
+    .uninit    = uninit,
+    .query_formats = query_formats,
+
+    .inputs    = (const AVFilterPad[]) {
+        { .name = NULL}
+    },
+    .outputs   = (const AVFilterPad[]) {
+        { .name            = "default",
+          .type            = AVMEDIA_TYPE_VIDEO,
+          .request_frame   = request_frame,
+          .config_props    = config_props },
+        { .name = NULL}
+    },
+    .priv_class = &life_class,
+};
diff --git a/libavfilter/vsrc_mandelbrot.c b/libavfilter/vsrc_mandelbrot.c
new file mode 100644
index 0000000..1fbf828
--- /dev/null
+++ b/libavfilter/vsrc_mandelbrot.c
@@ -0,0 +1,416 @@
+/*
+ * Copyright (c) 2011 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
+ *
+ * The vsrc_color filter from Stefano Sabatini was used as template to create
+ * this
+ */
+
+/**
+ * @file
+ * Mandelbrot fraktal renderer
+ */
+
+#include "avfilter.h"
+#include "formats.h"
+#include "video.h"
+#include "internal.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include <float.h>
+#include <math.h>
+
+#define SQR(a) ((a)*(a))
+
+enum Outer{
+    ITERATION_COUNT,
+    NORMALIZED_ITERATION_COUNT,
+};
+
+enum Inner{
+    BLACK,
+    PERIOD,
+    CONVTIME,
+    MINCOL,
+};
+
+typedef struct Point {
+    double p[2];
+    uint32_t val;
+} Point;
+
+typedef struct {
+    const AVClass *class;
+    int w, h;
+    AVRational time_base;
+    uint64_t pts;
+    char *rate;
+    int maxiter;
+    double start_x;
+    double start_y;
+    double start_scale;
+    double end_scale;
+    double end_pts;
+    double bailout;
+    enum Outer outer;
+    enum Inner inner;
+    int cache_allocated;
+    int cache_used;
+    Point *point_cache;
+    Point *next_cache;
+    double (*zyklus)[2];
+    uint32_t dither;
+} MBContext;
+
+#define OFFSET(x) offsetof(MBContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+
+static const AVOption mandelbrot_options[] = {
+    {"size",        "set frame size",                OFFSET(w),       AV_OPT_TYPE_IMAGE_SIZE, {.str="640x480"},  CHAR_MIN, CHAR_MAX, FLAGS },
+    {"s",           "set frame size",                OFFSET(w),       AV_OPT_TYPE_IMAGE_SIZE, {.str="640x480"},  CHAR_MIN, CHAR_MAX, FLAGS },
+    {"rate",        "set frame rate",                OFFSET(rate),    AV_OPT_TYPE_STRING,     {.str="25"},  CHAR_MIN, CHAR_MAX, FLAGS },
+    {"r",           "set frame rate",                OFFSET(rate),    AV_OPT_TYPE_STRING,     {.str="25"},  CHAR_MIN, CHAR_MAX, FLAGS },
+    {"maxiter",     "set max iterations number",     OFFSET(maxiter), AV_OPT_TYPE_INT,        {.i64=7189},  1,        INT_MAX, FLAGS },
+    {"start_x",     "set the initial x position",    OFFSET(start_x), AV_OPT_TYPE_DOUBLE,     {.dbl=-0.743643887037158704752191506114774}, -100, 100, FLAGS },
+    {"start_y",     "set the initial y position",    OFFSET(start_y), AV_OPT_TYPE_DOUBLE,     {.dbl=-0.131825904205311970493132056385139}, -100, 100, FLAGS },
+    {"start_scale", "set the initial scale value",   OFFSET(start_scale), AV_OPT_TYPE_DOUBLE, {.dbl=3.0},  0, FLT_MAX, FLAGS },
+    {"end_scale",   "set the terminal scale value",  OFFSET(end_scale), AV_OPT_TYPE_DOUBLE,   {.dbl=0.3},  0, FLT_MAX, FLAGS },
+    {"end_pts",     "set the terminal pts value",    OFFSET(end_pts), AV_OPT_TYPE_DOUBLE,     {.dbl=400},  0, INT64_MAX, FLAGS },
+    {"bailout",     "set the bailout value",         OFFSET(bailout), AV_OPT_TYPE_DOUBLE,     {.dbl=10},   0, FLT_MAX, FLAGS },
+
+    {"outer",       "set outer coloring mode",       OFFSET(outer), AV_OPT_TYPE_INT, {.i64=NORMALIZED_ITERATION_COUNT}, 0, INT_MAX, FLAGS, "outer" },
+    {"iteration_count", "set iteration count mode",  0, AV_OPT_TYPE_CONST, {.i64=ITERATION_COUNT}, INT_MIN, INT_MAX, FLAGS, "outer" },
+    {"normalized_iteration_count", "set normalized iteration count mode",   0, AV_OPT_TYPE_CONST, {.i64=NORMALIZED_ITERATION_COUNT}, INT_MIN, INT_MAX, FLAGS, "outer" },
+
+    {"inner",       "set inner coloring mode",       OFFSET(inner), AV_OPT_TYPE_INT, {.i64=MINCOL}, 0, INT_MAX, FLAGS, "inner" },
+    {"black",       "set black mode",                0, AV_OPT_TYPE_CONST, {.i64=BLACK}, INT_MIN, INT_MAX, FLAGS, "inner"},
+    {"period",      "set period mode",               0, AV_OPT_TYPE_CONST, {.i64=PERIOD}, INT_MIN, INT_MAX, FLAGS, "inner"},
+    {"convergence", "show time until convergence",   0, AV_OPT_TYPE_CONST, {.i64=CONVTIME}, INT_MIN, INT_MAX, FLAGS, "inner"},
+    {"mincol",      "color based on point closest to the origin of the iterations",   0, AV_OPT_TYPE_CONST, {.i64=MINCOL}, INT_MIN, INT_MAX, FLAGS, "inner"},
+
+    {NULL},
+};
+
+AVFILTER_DEFINE_CLASS(mandelbrot);
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    MBContext *mb = ctx->priv;
+    AVRational rate_q;
+    int err;
+
+    mb->class = &mandelbrot_class;
+    av_opt_set_defaults(mb);
+
+    if ((err = (av_set_options_string(mb, args, "=", ":"))) < 0)
+        return err;
+    mb->bailout *= mb->bailout;
+
+    mb->start_scale /=mb->h;
+    mb->end_scale /=mb->h;
+
+    if (av_parse_video_rate(&rate_q, mb->rate) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: %s\n", mb->rate);
+        return AVERROR(EINVAL);
+    }
+    mb->time_base.num = rate_q.den;
+    mb->time_base.den = rate_q.num;
+
+    mb->cache_allocated = mb->w * mb->h * 3;
+    mb->cache_used = 0;
+    mb->point_cache= av_malloc(sizeof(*mb->point_cache)*mb->cache_allocated);
+    mb-> next_cache= av_malloc(sizeof(*mb-> next_cache)*mb->cache_allocated);
+    mb-> zyklus    = av_malloc(sizeof(*mb->zyklus) * (mb->maxiter+16));
+
+    return 0;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    MBContext *mb = ctx->priv;
+
+    av_freep(&mb->rate);
+    av_freep(&mb->point_cache);
+    av_freep(&mb-> next_cache);
+    av_freep(&mb->zyklus);
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    static const enum AVPixelFormat pix_fmts[] = {
+        AV_PIX_FMT_BGR32,
+        AV_PIX_FMT_NONE
+    };
+
+    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
+    return 0;
+}
+
+static int config_props(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->src;
+    MBContext *mb = ctx->priv;
+
+    if (av_image_check_size(mb->w, mb->h, 0, ctx) < 0)
+        return AVERROR(EINVAL);
+
+    inlink->w = mb->w;
+    inlink->h = mb->h;
+    inlink->time_base = mb->time_base;
+
+    return 0;
+}
+
+static void fill_from_cache(AVFilterContext *ctx, uint32_t *color, int *in_cidx, int *out_cidx, double py, double scale){
+    MBContext *mb = ctx->priv;
+    for(; *in_cidx < mb->cache_used; (*in_cidx)++){
+        Point *p= &mb->point_cache[*in_cidx];
+        int x;
+        if(p->p[1] > py)
+            break;
+        x= round((p->p[0] - mb->start_x) / scale + mb->w/2);
+        if(x<0 || x >= mb->w)
+            continue;
+        if(color) color[x] = p->val;
+        if(out_cidx && *out_cidx < mb->cache_allocated)
+            mb->next_cache[(*out_cidx)++]= *p;
+    }
+}
+
+static int interpol(MBContext *mb, uint32_t *color, int x, int y, int linesize)
+{
+    uint32_t a,b,c,d, i;
+    uint32_t ipol=0xFF000000;
+    int dist;
+
+    if(!x || !y || x+1==mb->w || y+1==mb->h)
+        return 0;
+
+    dist= FFMAX(FFABS(x-(mb->w>>1))*mb->h, FFABS(y-(mb->h>>1))*mb->w);
+
+    if(dist<(mb->w*mb->h>>3))
+        return 0;
+
+    a=color[(x+1) + (y+0)*linesize];
+    b=color[(x-1) + (y+1)*linesize];
+    c=color[(x+0) + (y+1)*linesize];
+    d=color[(x+1) + (y+1)*linesize];
+
+    if(a&&c){
+        b= color[(x-1) + (y+0)*linesize];
+        d= color[(x+0) + (y-1)*linesize];
+    }else if(b&&d){
+        a= color[(x+1) + (y-1)*linesize];
+        c= color[(x-1) + (y-1)*linesize];
+    }else if(c){
+        d= color[(x+0) + (y-1)*linesize];
+        a= color[(x-1) + (y+0)*linesize];
+        b= color[(x+1) + (y-1)*linesize];
+    }else if(d){
+        c= color[(x-1) + (y-1)*linesize];
+        a= color[(x-1) + (y+0)*linesize];
+        b= color[(x+1) + (y-1)*linesize];
+    }else
+        return 0;
+
+    for(i=0; i<3; i++){
+        int s= 8*i;
+        uint8_t ac= a>>s;
+        uint8_t bc= b>>s;
+        uint8_t cc= c>>s;
+        uint8_t dc= d>>s;
+        int ipolab= (ac + bc);
+        int ipolcd= (cc + dc);
+        if(FFABS(ipolab - ipolcd) > 5)
+            return 0;
+        if(FFABS(ac-bc)+FFABS(cc-dc) > 20)
+            return 0;
+        ipol |= ((ipolab + ipolcd + 2)/4)<<s;
+    }
+    color[x + y*linesize]= ipol;
+    return 1;
+}
+
+static void draw_mandelbrot(AVFilterContext *ctx, uint32_t *color, int linesize, int64_t pts)
+{
+    MBContext *mb = ctx->priv;
+    int x,y,i, in_cidx=0, next_cidx=0, tmp_cidx;
+    double scale= mb->start_scale*pow(mb->end_scale/mb->start_scale, pts/mb->end_pts);
+    int use_zyklus=0;
+    fill_from_cache(ctx, NULL, &in_cidx, NULL, mb->start_y+scale*(-mb->h/2-0.5), scale);
+    tmp_cidx= in_cidx;
+    memset(color, 0, sizeof(*color)*mb->w);
+    for(y=0; y<mb->h; y++){
+        int y1= y+1;
+        const double ci=mb->start_y+scale*(y-mb->h/2);
+        fill_from_cache(ctx, NULL, &in_cidx, &next_cidx, ci, scale);
+        if(y1<mb->h){
+            memset(color+linesize*y1, 0, sizeof(*color)*mb->w);
+            fill_from_cache(ctx, color+linesize*y1, &tmp_cidx, NULL, ci + 3*scale/2, scale);
+        }
+
+        for(x=0; x<mb->w; x++){
+            float av_uninit(epsilon);
+            const double cr=mb->start_x+scale*(x-mb->w/2);
+            double zr=cr;
+            double zi=ci;
+            uint32_t c=0;
+            double dv= mb->dither / (double)(1LL<<32);
+            mb->dither= mb->dither*1664525+1013904223;
+
+            if(color[x + y*linesize] & 0xFF000000)
+                continue;
+            if(interpol(mb, color, x, y, linesize)){
+                if(next_cidx < mb->cache_allocated){
+                    mb->next_cache[next_cidx  ].p[0]= cr;
+                    mb->next_cache[next_cidx  ].p[1]= ci;
+                    mb->next_cache[next_cidx++].val = color[x + y*linesize];
+                }
+                continue;
+            }
+
+            use_zyklus= (x==0 || mb->inner!=BLACK ||color[x-1 + y*linesize] == 0xFF000000);
+            if(use_zyklus)
+                epsilon= scale*1*sqrt(SQR(x-mb->w/2) + SQR(y-mb->h/2))/mb->w;
+
+#define Z_Z2_C(outr,outi,inr,ini)\
+            outr= inr*inr - ini*ini + cr;\
+            outi= 2*inr*ini + ci;
+
+#define Z_Z2_C_ZYKLUS(outr,outi,inr,ini, Z)\
+            Z_Z2_C(outr,outi,inr,ini)\
+            if(use_zyklus){\
+                if(Z && fabs(mb->zyklus[i>>1][0]-outr)+fabs(mb->zyklus[i>>1][1]-outi) <= epsilon)\
+                    break;\
+            }\
+            mb->zyklus[i][0]= outr;\
+            mb->zyklus[i][1]= outi;\
+
+
+
+            for(i=0; i<mb->maxiter-8; i++){
+                double t;
+                Z_Z2_C_ZYKLUS(t, zi, zr, zi, 0)
+                i++;
+                Z_Z2_C_ZYKLUS(zr, zi, t, zi, 1)
+                i++;
+                Z_Z2_C_ZYKLUS(t, zi, zr, zi, 0)
+                i++;
+                Z_Z2_C_ZYKLUS(zr, zi, t, zi, 1)
+                i++;
+                Z_Z2_C_ZYKLUS(t, zi, zr, zi, 0)
+                i++;
+                Z_Z2_C_ZYKLUS(zr, zi, t, zi, 1)
+                i++;
+                Z_Z2_C_ZYKLUS(t, zi, zr, zi, 0)
+                i++;
+                Z_Z2_C_ZYKLUS(zr, zi, t, zi, 1)
+                if(zr*zr + zi*zi > mb->bailout){
+                    i-= FFMIN(7, i);
+                    for(; i<mb->maxiter; i++){
+                        zr= mb->zyklus[i][0];
+                        zi= mb->zyklus[i][1];
+                        if(zr*zr + zi*zi > mb->bailout){
+                            switch(mb->outer){
+                            case            ITERATION_COUNT: zr = i; break;
+                            case NORMALIZED_ITERATION_COUNT: zr= i + log2(log(mb->bailout) / log(zr*zr + zi*zi)); break;
+                            }
+                            c= lrintf((sin(zr)+1)*127) + lrintf((sin(zr/1.234)+1)*127)*256*256 + lrintf((sin(zr/100)+1)*127)*256;
+                            break;
+                        }
+                    }
+                    break;
+                }
+            }
+            if(!c){
+                if(mb->inner==PERIOD){
+                int j;
+                for(j=i-1; j; j--)
+                    if(SQR(mb->zyklus[j][0]-zr) + SQR(mb->zyklus[j][1]-zi) < epsilon*epsilon*10)
+                        break;
+                if(j){
+                    c= i-j;
+                    c= ((c<<5)&0xE0) + ((c<<16)&0xE000) + ((c<<27)&0xE00000);
+                }
+                }else if(mb->inner==CONVTIME){
+                    c= floor(i*255.0/mb->maxiter+dv)*0x010101;
+                } else if(mb->inner==MINCOL){
+                    int j;
+                    double closest=9999;
+                    int closest_index=0;
+                    for(j=i-1; j>=0; j--)
+                        if(SQR(mb->zyklus[j][0]) + SQR(mb->zyklus[j][1]) < closest){
+                            closest= SQR(mb->zyklus[j][0]) + SQR(mb->zyklus[j][1]);
+                            closest_index= j;
+                        }
+                    closest = sqrt(closest);
+                    c= lrintf((mb->zyklus[closest_index][0]/closest+1)*127+dv) + lrintf((mb->zyklus[closest_index][1]/closest+1)*127+dv)*256;
+                }
+            }
+            c |= 0xFF000000;
+            color[x + y*linesize]= c;
+            if(next_cidx < mb->cache_allocated){
+                mb->next_cache[next_cidx  ].p[0]= cr;
+                mb->next_cache[next_cidx  ].p[1]= ci;
+                mb->next_cache[next_cidx++].val = c;
+            }
+        }
+        fill_from_cache(ctx, NULL, &in_cidx, &next_cidx, ci + scale/2, scale);
+    }
+    FFSWAP(void*, mb->next_cache, mb->point_cache);
+    mb->cache_used = next_cidx;
+    if(mb->cache_used == mb->cache_allocated)
+        av_log(0, AV_LOG_INFO, "Mandelbrot cache is too small!\n");
+}
+
+static int request_frame(AVFilterLink *link)
+{
+    MBContext *mb = link->src->priv;
+    AVFilterBufferRef *picref = ff_get_video_buffer(link, AV_PERM_WRITE, mb->w, mb->h);
+    picref->video->sample_aspect_ratio = (AVRational) {1, 1};
+    picref->pts = mb->pts++;
+    picref->pos = -1;
+
+    ff_start_frame(link, avfilter_ref_buffer(picref, ~0));
+    draw_mandelbrot(link->src, (uint32_t*)picref->data[0], picref->linesize[0]/4, picref->pts);
+    ff_draw_slice(link, 0, mb->h, 1);
+    ff_end_frame(link);
+    avfilter_unref_buffer(picref);
+
+    return 0;
+}
+
+AVFilter avfilter_vsrc_mandelbrot = {
+    .name        = "mandelbrot",
+    .description = NULL_IF_CONFIG_SMALL("Render a Mandelbrot fractal."),
+
+    .priv_size = sizeof(MBContext),
+    .init      = init,
+    .uninit    = uninit,
+
+    .query_formats = query_formats,
+
+    .inputs    = (const AVFilterPad[]) {{ .name = NULL}},
+
+    .outputs   = (const AVFilterPad[]) {{ .name      = "default",
+                                    .type            = AVMEDIA_TYPE_VIDEO,
+                                    .request_frame   = request_frame,
+                                    .config_props    = config_props },
+                                  { .name = NULL}},
+};
diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c
deleted file mode 100644
index 7918676..0000000
--- a/libavfilter/vsrc_movie.c
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (c) 2010 Stefano Sabatini
- * Copyright (c) 2008 Victor Paesa
- *
- * 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
- * movie video source
- *
- * @todo use direct rendering (no allocation of a new frame)
- * @todo support a PTS correction mechanism
- * @todo support more than one output stream
- */
-
-/* #define DEBUG */
-
-#include <float.h>
-#include "libavutil/avstring.h"
-#include "libavutil/opt.h"
-#include "libavutil/imgutils.h"
-#include "libavformat/avformat.h"
-#include "avfilter.h"
-#include "formats.h"
-#include "internal.h"
-#include "video.h"
-
-typedef struct {
-    const AVClass *class;
-    int64_t seek_point;   ///< seekpoint in microseconds
-    double seek_point_d;
-    char *format_name;
-    char *file_name;
-    int stream_index;
-
-    AVFormatContext *format_ctx;
-    AVCodecContext *codec_ctx;
-    int is_done;
-    AVFrame *frame;   ///< video frame to store the decoded images in
-
-    int w, h;
-    AVFilterBufferRef *picref;
-} MovieContext;
-
-#define OFFSET(x) offsetof(MovieContext, x)
-
-static const AVOption movie_options[]= {
-{"format_name",  "set format name",         OFFSET(format_name),  AV_OPT_TYPE_STRING, {.str =  0},  CHAR_MIN, CHAR_MAX },
-{"f",            "set format name",         OFFSET(format_name),  AV_OPT_TYPE_STRING, {.str =  0},  CHAR_MIN, CHAR_MAX },
-{"stream_index", "set stream index",        OFFSET(stream_index), AV_OPT_TYPE_INT,    {.i64 = -1},  -1,       INT_MAX  },
-{"si",           "set stream index",        OFFSET(stream_index), AV_OPT_TYPE_INT,    {.i64 = -1},  -1,       INT_MAX  },
-{"seek_point",   "set seekpoint (seconds)", OFFSET(seek_point_d), AV_OPT_TYPE_DOUBLE, {.dbl =  0},  0,        (INT64_MAX-1) / 1000000 },
-{"sp",           "set seekpoint (seconds)", OFFSET(seek_point_d), AV_OPT_TYPE_DOUBLE, {.dbl =  0},  0,        (INT64_MAX-1) / 1000000 },
-{NULL},
-};
-
-static const char *movie_get_name(void *ctx)
-{
-    return "movie";
-}
-
-static const AVClass movie_class = {
-    "MovieContext",
-    movie_get_name,
-    movie_options
-};
-
-static int movie_init(AVFilterContext *ctx)
-{
-    MovieContext *movie = ctx->priv;
-    AVInputFormat *iformat = NULL;
-    AVCodec *codec;
-    int ret;
-    int64_t timestamp;
-
-    av_register_all();
-
-    // Try to find the movie format (container)
-    iformat = movie->format_name ? av_find_input_format(movie->format_name) : NULL;
-
-    movie->format_ctx = NULL;
-    if ((ret = avformat_open_input(&movie->format_ctx, movie->file_name, iformat, NULL)) < 0) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Failed to avformat_open_input '%s'\n", movie->file_name);
-        return ret;
-    }
-    if ((ret = avformat_find_stream_info(movie->format_ctx, NULL)) < 0)
-        av_log(ctx, AV_LOG_WARNING, "Failed to find stream info\n");
-
-    // if seeking requested, we execute it
-    if (movie->seek_point > 0) {
-        timestamp = movie->seek_point;
-        // add the stream start time, should it exist
-        if (movie->format_ctx->start_time != AV_NOPTS_VALUE) {
-            if (timestamp > INT64_MAX - movie->format_ctx->start_time) {
-                av_log(ctx, AV_LOG_ERROR,
-                       "%s: seek value overflow with start_time:%"PRId64" seek_point:%"PRId64"\n",
-                       movie->file_name, movie->format_ctx->start_time, movie->seek_point);
-                return AVERROR(EINVAL);
-            }
-            timestamp += movie->format_ctx->start_time;
-        }
-        if ((ret = av_seek_frame(movie->format_ctx, -1, timestamp, AVSEEK_FLAG_BACKWARD)) < 0) {
-            av_log(ctx, AV_LOG_ERROR, "%s: could not seek to position %"PRId64"\n",
-                   movie->file_name, timestamp);
-            return ret;
-        }
-    }
-
-    /* select the video stream */
-    if ((ret = av_find_best_stream(movie->format_ctx, AVMEDIA_TYPE_VIDEO,
-                                   movie->stream_index, -1, NULL, 0)) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "No video stream with index '%d' found\n",
-               movie->stream_index);
-        return ret;
-    }
-    movie->stream_index = ret;
-    movie->codec_ctx = movie->format_ctx->streams[movie->stream_index]->codec;
-
-    /*
-     * So now we've got a pointer to the so-called codec context for our video
-     * stream, but we still have to find the actual codec and open it.
-     */
-    codec = avcodec_find_decoder(movie->codec_ctx->codec_id);
-    if (!codec) {
-        av_log(ctx, AV_LOG_ERROR, "Failed to find any codec\n");
-        return AVERROR(EINVAL);
-    }
-
-    if ((ret = avcodec_open2(movie->codec_ctx, codec, NULL)) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Failed to open codec\n");
-        return ret;
-    }
-
-    if (!(movie->frame = avcodec_alloc_frame()) ) {
-        av_log(ctx, AV_LOG_ERROR, "Failed to alloc frame\n");
-        return AVERROR(ENOMEM);
-    }
-
-    movie->w = movie->codec_ctx->width;
-    movie->h = movie->codec_ctx->height;
-
-    av_log(ctx, AV_LOG_VERBOSE, "seek_point:%"PRIi64" format_name:%s file_name:%s stream_index:%d\n",
-           movie->seek_point, movie->format_name, movie->file_name,
-           movie->stream_index);
-
-    return 0;
-}
-
-static av_cold int init(AVFilterContext *ctx, const char *args)
-{
-    MovieContext *movie = ctx->priv;
-    int ret;
-    movie->class = &movie_class;
-    av_opt_set_defaults(movie);
-
-    if (args)
-        movie->file_name = av_get_token(&args, ":");
-    if (!movie->file_name || !*movie->file_name) {
-        av_log(ctx, AV_LOG_ERROR, "No filename provided!\n");
-        return AVERROR(EINVAL);
-    }
-
-    if (*args++ == ':' && (ret = av_set_options_string(movie, args, "=", ":")) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
-        return ret;
-    }
-
-    movie->seek_point = movie->seek_point_d * 1000000 + 0.5;
-
-    return movie_init(ctx);
-}
-
-static av_cold void uninit(AVFilterContext *ctx)
-{
-    MovieContext *movie = ctx->priv;
-
-    av_free(movie->file_name);
-    av_free(movie->format_name);
-    if (movie->codec_ctx)
-        avcodec_close(movie->codec_ctx);
-    if (movie->format_ctx)
-        avformat_close_input(&movie->format_ctx);
-    avfilter_unref_buffer(movie->picref);
-    avcodec_free_frame(&movie->frame);
-}
-
-static int query_formats(AVFilterContext *ctx)
-{
-    MovieContext *movie = ctx->priv;
-    enum AVPixelFormat pix_fmts[] = { movie->codec_ctx->pix_fmt, AV_PIX_FMT_NONE };
-
-    ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
-    return 0;
-}
-
-static int config_output_props(AVFilterLink *outlink)
-{
-    MovieContext *movie = outlink->src->priv;
-
-    outlink->w = movie->w;
-    outlink->h = movie->h;
-    outlink->time_base = movie->format_ctx->streams[movie->stream_index]->time_base;
-
-    return 0;
-}
-
-static int movie_get_frame(AVFilterLink *outlink)
-{
-    MovieContext *movie = outlink->src->priv;
-    AVPacket pkt;
-    int ret, frame_decoded;
-    AVStream *st = movie->format_ctx->streams[movie->stream_index];
-
-    if (movie->is_done == 1)
-        return 0;
-
-    while ((ret = av_read_frame(movie->format_ctx, &pkt)) >= 0) {
-        // Is this a packet from the video stream?
-        if (pkt.stream_index == movie->stream_index) {
-            movie->codec_ctx->reordered_opaque = pkt.pos;
-            avcodec_decode_video2(movie->codec_ctx, movie->frame, &frame_decoded, &pkt);
-
-            if (frame_decoded) {
-                /* FIXME: avoid the memcpy */
-                movie->picref = ff_get_video_buffer(outlink, AV_PERM_WRITE | AV_PERM_PRESERVE |
-                                                    AV_PERM_REUSE2, outlink->w, outlink->h);
-                av_image_copy(movie->picref->data, movie->picref->linesize,
-                              movie->frame->data,  movie->frame->linesize,
-                              movie->picref->format, outlink->w, outlink->h);
-                avfilter_copy_frame_props(movie->picref, movie->frame);
-
-                /* FIXME: use a PTS correction mechanism as that in
-                 * ffplay.c when some API will be available for that */
-                /* use pkt_dts if pkt_pts is not available */
-                movie->picref->pts = movie->frame->pkt_pts == AV_NOPTS_VALUE ?
-                    movie->frame->pkt_dts : movie->frame->pkt_pts;
-
-                movie->picref->pos                    = movie->frame->reordered_opaque;
-                if (!movie->frame->sample_aspect_ratio.num)
-                    movie->picref->video->pixel_aspect = st->sample_aspect_ratio;
-                av_dlog(outlink->src,
-                        "movie_get_frame(): file:'%s' pts:%"PRId64" time:%lf pos:%"PRId64" aspect:%d/%d\n",
-                        movie->file_name, movie->picref->pts,
-                        (double)movie->picref->pts * av_q2d(st->time_base),
-                        movie->picref->pos,
-                        movie->picref->video->pixel_aspect.num, movie->picref->video->pixel_aspect.den);
-                // We got it. Free the packet since we are returning
-                av_free_packet(&pkt);
-
-                return 0;
-            }
-        }
-        // Free the packet that was allocated by av_read_frame
-        av_free_packet(&pkt);
-    }
-
-    // On multi-frame source we should stop the mixing process when
-    // the movie source does not have more frames
-    if (ret == AVERROR_EOF)
-        movie->is_done = 1;
-    return ret;
-}
-
-static int request_frame(AVFilterLink *outlink)
-{
-    AVFilterBufferRef *outpicref;
-    MovieContext *movie = outlink->src->priv;
-    int ret;
-
-    if (movie->is_done)
-        return AVERROR_EOF;
-    if ((ret = movie_get_frame(outlink)) < 0)
-        return ret;
-
-    outpicref = avfilter_ref_buffer(movie->picref, ~0);
-    if (!outpicref) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
-
-    ret = ff_start_frame(outlink, outpicref);
-    if (ret < 0)
-        goto fail;
-
-    ret = ff_draw_slice(outlink, 0, outlink->h, 1);
-    if (ret < 0)
-        goto fail;
-
-    ret = ff_end_frame(outlink);
-fail:
-    avfilter_unref_bufferp(&movie->picref);
-
-    return ret;
-}
-
-static const AVFilterPad avfilter_vsrc_movie_outputs[] = {
-    {
-        .name          = "default",
-        .type          = AVMEDIA_TYPE_VIDEO,
-        .request_frame = request_frame,
-        .config_props  = config_output_props,
-    },
-    { NULL }
-};
-
-AVFilter avfilter_vsrc_movie = {
-    .name          = "movie",
-    .description   = NULL_IF_CONFIG_SMALL("Read from a movie source."),
-    .priv_size     = sizeof(MovieContext),
-    .init          = init,
-    .uninit        = uninit,
-    .query_formats = query_formats,
-
-    .inputs    = NULL,
-    .outputs   = avfilter_vsrc_movie_outputs,
-};
diff --git a/libavfilter/vsrc_mptestsrc.c b/libavfilter/vsrc_mptestsrc.c
new file mode 100644
index 0000000..9589b51
--- /dev/null
+++ b/libavfilter/vsrc_mptestsrc.c
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * @file
+ * MP test source, ported from MPlayer libmpcodecs/vf_test.c
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
+#include "avfilter.h"
+#include "internal.h"
+#include "formats.h"
+#include "video.h"
+
+#define WIDTH 512
+#define HEIGHT 512
+
+enum test_type {
+    TEST_DC_LUMA,
+    TEST_DC_CHROMA,
+    TEST_FREQ_LUMA,
+    TEST_FREQ_CHROMA,
+    TEST_AMP_LUMA,
+    TEST_AMP_CHROMA,
+    TEST_CBP,
+    TEST_MV,
+    TEST_RING1,
+    TEST_RING2,
+    TEST_ALL,
+    TEST_NB
+};
+
+typedef struct MPTestContext {
+    const AVClass *class;
+    unsigned int frame_nb;
+    AVRational time_base;
+    int64_t pts, max_pts;
+    int hsub, vsub;
+    char *size, *rate, *duration;
+    enum test_type test;
+} MPTestContext;
+
+#define OFFSET(x) offsetof(MPTestContext, x)
+
+static const AVOption mptestsrc_options[]= {
+    { "rate",     "set video rate",     OFFSET(rate),     AV_OPT_TYPE_STRING, {.str = "25"},      0, 0 },
+    { "r",        "set video rate",     OFFSET(rate),     AV_OPT_TYPE_STRING, {.str = "25"},      0, 0 },
+    { "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_STRING, {.str = NULL},      0, 0 },
+    { "d",        "set video duration", OFFSET(duration), AV_OPT_TYPE_STRING, {.str = NULL},      0, 0 },
+
+    { "test", "set test to perform", OFFSET(test),  AV_OPT_TYPE_INT,   {.i64=TEST_ALL}, 0, INT_MAX, 0, "test" },
+    { "t",    "set test to perform", OFFSET(test),  AV_OPT_TYPE_INT,   {.i64=TEST_ALL}, 0, INT_MAX, 0, "test" },
+    { "dc_luma",     "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_DC_LUMA},     INT_MIN, INT_MAX, 0, "test" },
+    { "dc_chroma",   "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_DC_CHROMA},   INT_MIN, INT_MAX, 0, "test" },
+    { "freq_luma",   "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_FREQ_LUMA},   INT_MIN, INT_MAX, 0, "test" },
+    { "freq_chroma", "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_FREQ_CHROMA}, INT_MIN, INT_MAX, 0, "test" },
+    { "amp_luma",    "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_AMP_LUMA},    INT_MIN, INT_MAX, 0, "test" },
+    { "amp_chroma",  "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_AMP_CHROMA},  INT_MIN, INT_MAX, 0, "test" },
+    { "cbp",         "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_CBP},         INT_MIN, INT_MAX, 0, "test" },
+    { "mv",          "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_MV},          INT_MIN, INT_MAX, 0, "test" },
+    { "ring1",       "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_RING1},       INT_MIN, INT_MAX, 0, "test" },
+    { "ring2",       "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_RING2},       INT_MIN, INT_MAX, 0, "test" },
+    { "all",         "", 0, AV_OPT_TYPE_CONST, {.i64=TEST_ALL},         INT_MIN, INT_MAX, 0, "test" },
+
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(mptestsrc);
+
+static double c[64];
+
+static void init_idct(void)
+{
+    int i, j;
+
+    for (i = 0; i < 8; i++) {
+        double s = i == 0 ? sqrt(0.125) : 0.5;
+
+        for (j = 0; j < 8; j++)
+            c[i*8+j] = s*cos((M_PI/8.0)*i*(j+0.5));
+    }
+}
+
+static void idct(uint8_t *dst, int dst_linesize, int src[64])
+{
+    int i, j, k;
+    double tmp[64];
+
+    for (i = 0; i < 8; i++) {
+        for (j = 0; j < 8; j++) {
+            double sum = 0.0;
+
+            for (k = 0; k < 8; k++)
+                sum += c[k*8+j] * src[8*i+k];
+
+            tmp[8*i+j] = sum;
+        }
+    }
+
+    for (j = 0; j < 8; j++) {
+        for (i = 0; i < 8; i++) {
+            double sum = 0.0;
+
+            for (k = 0; k < 8; k++)
+                sum += c[k*8+i]*tmp[8*k+j];
+
+            dst[dst_linesize*i + j] = av_clip((int)floor(sum+0.5), 0, 255);
+        }
+    }
+}
+
+static void draw_dc(uint8_t *dst, int dst_linesize, int color, int w, int h)
+{
+    int x, y;
+
+    for (y = 0; y < h; y++)
+        for (x = 0; x < w; x++)
+            dst[x + y*dst_linesize] = color;
+}
+
+static void draw_basis(uint8_t *dst, int dst_linesize, int amp, int freq, int dc)
+{
+    int src[64];
+
+    memset(src, 0, 64*sizeof(int));
+    src[0] = dc;
+    if (amp)
+        src[freq] = amp;
+    idct(dst, dst_linesize, src);
+}
+
+static void draw_cbp(uint8_t *dst[3], int dst_linesize[3], int cbp, int amp, int dc)
+{
+    if (cbp&1)  draw_basis(dst[0]                    , dst_linesize[0], amp, 1, dc);
+    if (cbp&2)  draw_basis(dst[0]+8                  , dst_linesize[0], amp, 1, dc);
+    if (cbp&4)  draw_basis(dst[0]+  8*dst_linesize[0], dst_linesize[0], amp, 1, dc);
+    if (cbp&8)  draw_basis(dst[0]+8+8*dst_linesize[0], dst_linesize[0], amp, 1, dc);
+    if (cbp&16) draw_basis(dst[1]                    , dst_linesize[1], amp, 1, dc);
+    if (cbp&32) draw_basis(dst[2]                    , dst_linesize[2], amp, 1, dc);
+}
+
+static void dc_test(uint8_t *dst, int dst_linesize, int w, int h, int off)
+{
+    const int step = FFMAX(256/(w*h/256), 1);
+    int x, y, color = off;
+
+    for (y = 0; y < h; y += 16) {
+        for (x = 0; x < w; x += 16) {
+            draw_dc(dst + x + y*dst_linesize, dst_linesize, color, 8, 8);
+            color += step;
+        }
+    }
+}
+
+static void freq_test(uint8_t *dst, int dst_linesize, int off)
+{
+    int x, y, freq = 0;
+
+    for (y = 0; y < 8*16; y += 16) {
+        for (x = 0; x < 8*16; x += 16) {
+            draw_basis(dst + x + y*dst_linesize, dst_linesize, 4*(96+off), freq, 128*8);
+            freq++;
+        }
+    }
+}
+
+static void amp_test(uint8_t *dst, int dst_linesize, int off)
+{
+    int x, y, amp = off;
+
+    for (y = 0; y < 16*16; y += 16) {
+        for (x = 0; x < 16*16; x += 16) {
+            draw_basis(dst + x + y*dst_linesize, dst_linesize, 4*amp, 1, 128*8);
+            amp++;
+        }
+    }
+}
+
+static void cbp_test(uint8_t *dst[3], int dst_linesize[3], int off)
+{
+    int x, y, cbp = 0;
+
+    for (y = 0; y < 16*8; y += 16) {
+        for (x = 0; x < 16*8; x += 16) {
+            uint8_t *dst1[3];
+            dst1[0] = dst[0] + x*2 + y*2*dst_linesize[0];
+            dst1[1] = dst[1] + x   + y*  dst_linesize[1];
+            dst1[2] = dst[2] + x   + y*  dst_linesize[2];
+
+            draw_cbp(dst1, dst_linesize, cbp, (64+off)*4, 128*8);
+            cbp++;
+        }
+    }
+}
+
+static void mv_test(uint8_t *dst, int dst_linesize, int off)
+{
+    int x, y;
+
+    for (y = 0; y < 16*16; y++) {
+        if (y&16)
+            continue;
+        for (x = 0; x < 16*16; x++)
+            dst[x + y*dst_linesize] = x + off*8/(y/32+1);
+    }
+}
+
+static void ring1_test(uint8_t *dst, int dst_linesize, int off)
+{
+    int x, y, color = 0;
+
+    for (y = off; y < 16*16; y += 16) {
+        for (x = off; x < 16*16; x += 16) {
+            draw_dc(dst + x + y*dst_linesize, dst_linesize, ((x+y)&16) ? color : -color, 16, 16);
+            color++;
+        }
+    }
+}
+
+static void ring2_test(uint8_t *dst, int dst_linesize, int off)
+{
+    int x, y;
+
+    for (y = 0; y < 16*16; y++) {
+        for (x = 0; x < 16*16; x++) {
+            double d = sqrt((x-8*16)*(x-8*16) + (y-8*16)*(y-8*16));
+            double r = d/20 - (int)(d/20);
+            if (r < off/30.0) {
+                dst[x + y*dst_linesize]     = 255;
+                dst[x + y*dst_linesize+256] = 0;
+            } else {
+                dst[x + y*dst_linesize]     = x;
+                dst[x + y*dst_linesize+256] = x;
+            }
+        }
+    }
+}
+
+static av_cold int init(AVFilterContext *ctx, const char *args)
+{
+    MPTestContext *test = ctx->priv;
+    AVRational frame_rate_q;
+    int64_t duration = -1;
+    int ret;
+
+    test->class = &mptestsrc_class;
+    av_opt_set_defaults(test);
+
+    if ((ret = (av_set_options_string(test, args, "=", ":"))) < 0)
+        return ret;
+
+    if ((ret = av_parse_video_rate(&frame_rate_q, test->rate)) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", test->rate);
+        return ret;
+    }
+
+    if ((test->duration) && (ret = av_parse_time(&duration, test->duration, 1)) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid duration: '%s'\n", test->duration);
+        return ret;
+    }
+
+    test->time_base.num = frame_rate_q.den;
+    test->time_base.den = frame_rate_q.num;
+    test->max_pts = duration >= 0 ?
+        av_rescale_q(duration, AV_TIME_BASE_Q, test->time_base) : -1;
+    test->frame_nb = 0;
+    test->pts = 0;
+
+    av_log(ctx, AV_LOG_VERBOSE, "rate:%d/%d duration:%f\n",
+           frame_rate_q.num, frame_rate_q.den,
+           duration < 0 ? -1 : test->max_pts * av_q2d(test->time_base));
+    init_idct();
+
+    return 0;
+}
+
+static int config_props(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    MPTestContext *test = ctx->priv;
+    const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[outlink->format];
+
+    test->hsub = pix_desc->log2_chroma_w;
+    test->vsub = pix_desc->log2_chroma_h;
+
+    outlink->w = WIDTH;
+    outlink->h = HEIGHT;
+    outlink->time_base = test->time_base;
+
+    return 0;
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+    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;
+}
+
+static int request_frame(AVFilterLink *outlink)
+{
+    MPTestContext *test = outlink->src->priv;
+    AVFilterBufferRef *picref;
+    int w = WIDTH, h = HEIGHT, ch = h>>test->vsub;
+    unsigned int frame = test->frame_nb;
+    enum test_type tt = test->test;
+
+    if (test->max_pts >= 0 && test->pts > test->max_pts)
+        return AVERROR_EOF;
+    picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, w, h);
+    picref->pts = test->pts++;
+
+    // clean image
+    memset(picref->data[0], 0,   picref->linesize[0] * h);
+    memset(picref->data[1], 128, picref->linesize[1] * ch);
+    memset(picref->data[2], 128, picref->linesize[2] * ch);
+
+    if (tt == TEST_ALL && frame%30) /* draw a black frame at the beginning of each test */
+        tt = (frame/30)%(TEST_NB-1);
+
+    switch (tt) {
+    case TEST_DC_LUMA:       dc_test(picref->data[0], picref->linesize[0], 256, 256, frame%30); break;
+    case TEST_DC_CHROMA:     dc_test(picref->data[1], picref->linesize[1], 256, 256, frame%30); break;
+    case TEST_FREQ_LUMA:   freq_test(picref->data[0], picref->linesize[0], frame%30); break;
+    case TEST_FREQ_CHROMA: freq_test(picref->data[1], picref->linesize[1], frame%30); break;
+    case TEST_AMP_LUMA:     amp_test(picref->data[0], picref->linesize[0], frame%30); break;
+    case TEST_AMP_CHROMA:   amp_test(picref->data[1], picref->linesize[1], frame%30); break;
+    case TEST_CBP:          cbp_test(picref->data   , picref->linesize   , frame%30); break;
+    case TEST_MV:            mv_test(picref->data[0], picref->linesize[0], frame%30); break;
+    case TEST_RING1:      ring1_test(picref->data[0], picref->linesize[0], frame%30); break;
+    case TEST_RING2:      ring2_test(picref->data[0], picref->linesize[0], frame%30); break;
+    }
+
+    test->frame_nb++;
+
+    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);
+
+    return 0;
+}
+
+AVFilter avfilter_vsrc_mptestsrc = {
+    .name      = "mptestsrc",
+    .description = NULL_IF_CONFIG_SMALL("Generate various test pattern."),
+    .priv_size = sizeof(MPTestContext),
+    .init      = init,
+
+    .query_formats   = query_formats,
+
+    .inputs    = (const AVFilterPad[]) {{ .name = NULL}},
+
+    .outputs   = (const AVFilterPad[]) {{ .name = "default",
+                                    .type = AVMEDIA_TYPE_VIDEO,
+                                    .request_frame = request_frame,
+                                    .config_props  = config_props, },
+                                  { .name = NULL }},
+};
diff --git a/libavfilter/vsrc_nullsrc.c b/libavfilter/vsrc_nullsrc.c
deleted file mode 100644
index 79f6d4b..0000000
--- a/libavfilter/vsrc_nullsrc.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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
- * null video source
- */
-
-#include <stdio.h>
-
-#include "libavutil/avstring.h"
-#include "libavutil/eval.h"
-#include "libavutil/internal.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/parseutils.h"
-#include "avfilter.h"
-#include "formats.h"
-#include "internal.h"
-
-static const char *const var_names[] = {
-    "E",
-    "PHI",
-    "PI",
-    "AVTB",   /* default timebase 1/AV_TIME_BASE */
-    NULL
-};
-
-enum var_name {
-    VAR_E,
-    VAR_PHI,
-    VAR_PI,
-    VAR_AVTB,
-    VAR_VARS_NB
-};
-
-typedef struct {
-    int w, h;
-    char tb_expr[256];
-    double var_values[VAR_VARS_NB];
-} NullContext;
-
-static int init(AVFilterContext *ctx, const char *args)
-{
-    NullContext *priv = ctx->priv;
-
-    priv->w = 352;
-    priv->h = 288;
-    av_strlcpy(priv->tb_expr, "AVTB", sizeof(priv->tb_expr));
-
-    if (args)
-        sscanf(args, "%d:%d:%255[^:]", &priv->w, &priv->h, priv->tb_expr);
-
-    if (priv->w <= 0 || priv->h <= 0) {
-        av_log(ctx, AV_LOG_ERROR, "Non-positive size values are not acceptable.\n");
-        return AVERROR(EINVAL);
-    }
-
-    return 0;
-}
-
-static int config_props(AVFilterLink *outlink)
-{
-    AVFilterContext *ctx = outlink->src;
-    NullContext *priv = ctx->priv;
-    AVRational tb;
-    int ret;
-    double res;
-
-    priv->var_values[VAR_E]    = M_E;
-    priv->var_values[VAR_PHI]  = M_PHI;
-    priv->var_values[VAR_PI]   = M_PI;
-    priv->var_values[VAR_AVTB] = av_q2d(AV_TIME_BASE_Q);
-
-    if ((ret = av_expr_parse_and_eval(&res, priv->tb_expr, var_names, priv->var_values,
-                                      NULL, NULL, NULL, NULL, NULL, 0, NULL)) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid expression '%s' for timebase.\n", priv->tb_expr);
-        return ret;
-    }
-    tb = av_d2q(res, INT_MAX);
-    if (tb.num <= 0 || tb.den <= 0) {
-        av_log(ctx, AV_LOG_ERROR,
-               "Invalid non-positive value for the timebase %d/%d.\n",
-               tb.num, tb.den);
-        return AVERROR(EINVAL);
-    }
-
-    outlink->w = priv->w;
-    outlink->h = priv->h;
-    outlink->time_base = tb;
-
-    av_log(outlink->src, AV_LOG_VERBOSE, "w:%d h:%d tb:%d/%d\n", priv->w, priv->h,
-           tb.num, tb.den);
-
-    return 0;
-}
-
-static int request_frame(AVFilterLink *link)
-{
-    return -1;
-}
-
-static const AVFilterPad avfilter_vsrc_nullsrc_outputs[] = {
-    {
-        .name          = "default",
-        .type          = AVMEDIA_TYPE_VIDEO,
-        .config_props  = config_props,
-        .request_frame = request_frame,
-    },
-    { NULL }
-};
-
-AVFilter avfilter_vsrc_nullsrc = {
-    .name        = "nullsrc",
-    .description = NULL_IF_CONFIG_SMALL("Null video source, never return images."),
-
-    .init       = init,
-    .priv_size = sizeof(NullContext),
-
-    .inputs    = NULL,
-
-    .outputs   = avfilter_vsrc_nullsrc_outputs,
-};
diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c
index b81611d..6ba55a7 100644
--- a/libavfilter/vsrc_testsrc.c
+++ b/libavfilter/vsrc_testsrc.c
@@ -1,21 +1,22 @@
 /*
  * Copyright (c) 2007 Nicolas George <nicolas.george@normalesup.org>
  * Copyright (c) 2011 Stefano Sabatini
+ * Copyright (c) 2012 Paul B Mahol
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -28,93 +29,130 @@
  *
  * rgbtestsrc is ported from MPlayer libmpcodecs/vf_rgbtest.c by
  * Michael Niedermayer.
+ *
+ * smptebars is by Paul B Mahol.
  */
 
 #include <float.h>
 
 #include "libavutil/common.h"
-#include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
+#include "libavutil/imgutils.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/parseutils.h"
 #include "avfilter.h"
+#include "drawutils.h"
 #include "formats.h"
 #include "internal.h"
 #include "video.h"
 
 typedef struct {
     const AVClass *class;
-    int h, w;
+    int w, h;
     unsigned int nb_frame;
-    AVRational time_base;
-    int64_t pts, max_pts;
-    char *size;                 ///< video frame size
-    char *rate;                 ///< video frame rate
-    char *duration;             ///< total duration of the generated video
+    AVRational time_base, frame_rate;
+    int64_t pts;
+    char *frame_rate_str;       ///< video frame rate
+    char *duration_str;         ///< total duration of the generated video
+    int64_t duration;           ///< duration expressed in microseconds
     AVRational sar;             ///< sample aspect ratio
+    int nb_decimals;
+    int draw_once;              ///< draw only the first frame, always put out the same picture
+    AVFilterBufferRef *picref;  ///< cached reference containing the painted picture
 
     void (* fill_picture_fn)(AVFilterContext *ctx, AVFilterBufferRef *picref);
 
+    /* only used by color */
+    char *color_str;
+    FFDrawContext draw;
+    FFDrawColor color;
+    uint8_t color_rgba[4];
+
     /* only used by rgbtest */
-    int rgba_map[4];
+    uint8_t rgba_map[4];
 } TestSourceContext;
 
 #define OFFSET(x) offsetof(TestSourceContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
 
-static const AVOption testsrc_options[] = {
-    { "size",     "set video size",     OFFSET(size),     AV_OPT_TYPE_STRING, {.str = "320x240"}},
-    { "s",        "set video size",     OFFSET(size),     AV_OPT_TYPE_STRING, {.str = "320x240"}},
-    { "rate",     "set video rate",     OFFSET(rate),     AV_OPT_TYPE_STRING, {.str = "25"},    },
-    { "r",        "set video rate",     OFFSET(rate),     AV_OPT_TYPE_STRING, {.str = "25"},    },
-    { "duration", "set video duration", OFFSET(duration), AV_OPT_TYPE_STRING, {.str = NULL},    },
-    { "sar",      "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl = 1},  0, INT_MAX },
+static const AVOption options[] = {
+    { "size",     "set video size",     OFFSET(w),        AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },
+    { "s",        "set video size",     OFFSET(w),        AV_OPT_TYPE_IMAGE_SIZE, {.str = "320x240"}, 0, 0, FLAGS },
+    { "rate",     "set video rate",     OFFSET(frame_rate_str), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, FLAGS },
+    { "r",        "set video rate",     OFFSET(frame_rate_str), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, FLAGS },
+    { "duration", "set video duration", OFFSET(duration_str), AV_OPT_TYPE_STRING, {.str = NULL},   0, 0, FLAGS },
+    { "d",        "set video duration", OFFSET(duration_str), AV_OPT_TYPE_STRING, {.str = NULL},   0, 0, FLAGS },
+    { "sar",      "set video sample aspect ratio", OFFSET(sar), AV_OPT_TYPE_RATIONAL, {.dbl= 1},  0, INT_MAX, FLAGS },
+
+    /* only used by color */
+    { "color", "set color", OFFSET(color_str), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+    { "c",     "set color", OFFSET(color_str), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
+
+    /* only used by testsrc */
+    { "decimals", "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.i64=0},  INT_MIN, INT_MAX, FLAGS },
+    { "n",        "set number of decimals to show", OFFSET(nb_decimals), AV_OPT_TYPE_INT, {.i64=0},  INT_MIN, INT_MAX, FLAGS },
     { NULL },
 };
 
-static av_cold int init_common(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     TestSourceContext *test = ctx->priv;
-    AVRational frame_rate_q;
-    int64_t duration = -1;
     int ret = 0;
 
     av_opt_set_defaults(test);
 
-    if ((ret = (av_set_options_string(test, args, "=", ":"))) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Error parsing options string: '%s'\n", args);
+    if ((ret = (av_set_options_string(test, args, "=", ":"))) < 0)
+        return ret;
+
+    if ((ret = av_parse_video_rate(&test->frame_rate, test->frame_rate_str)) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", test->frame_rate_str);
         return ret;
     }
 
-    if ((ret = av_parse_video_size(&test->w, &test->h, test->size)) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid frame size: '%s'\n", test->size);
+    test->duration = -1;
+    if (test->duration_str &&
+        (ret = av_parse_time(&test->duration, test->duration_str, 1)) < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Invalid duration: '%s'\n", test->duration_str);
         return ret;
     }
 
-    if ((ret = av_parse_video_rate(&frame_rate_q, test->rate)) < 0 ||
-        frame_rate_q.den <= 0 || frame_rate_q.num <= 0) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", test->rate);
-        return ret;
+    if (test->nb_decimals && strcmp(ctx->filter->name, "testsrc")) {
+        av_log(ctx, AV_LOG_WARNING,
+               "Option 'decimals' is ignored with source '%s'\n",
+               ctx->filter->name);
     }
 
-    if ((test->duration) && (ret = av_parse_time(&duration, test->duration, 1)) < 0) {
-        av_log(ctx, AV_LOG_ERROR, "Invalid duration: '%s'\n", test->duration);
-        return ret;
+    if (test->color_str) {
+        if (!strcmp(ctx->filter->name, "color")) {
+            ret = av_parse_color(test->color_rgba, test->color_str, -1, ctx);
+            if (ret < 0)
+                return ret;
+        } else {
+            av_log(ctx, AV_LOG_WARNING,
+                   "Option 'color' is ignored with source '%s'\n",
+                   ctx->filter->name);
+        }
     }
 
-    test->time_base.num = frame_rate_q.den;
-    test->time_base.den = frame_rate_q.num;
-    test->max_pts = duration >= 0 ?
-        av_rescale_q(duration, AV_TIME_BASE_Q, test->time_base) : -1;
+    test->time_base = av_inv_q(test->frame_rate);
     test->nb_frame = 0;
     test->pts = 0;
 
-    av_log(ctx, AV_LOG_DEBUG, "size:%dx%d rate:%d/%d duration:%f sar:%d/%d\n",
-           test->w, test->h, frame_rate_q.num, frame_rate_q.den,
-           duration < 0 ? -1 : test->max_pts * av_q2d(test->time_base),
+    av_log(ctx, AV_LOG_VERBOSE, "size:%dx%d rate:%d/%d duration:%f sar:%d/%d\n",
+           test->w, test->h, test->frame_rate.num, test->frame_rate.den,
+           test->duration < 0 ? -1 : (double)test->duration/1000000,
            test->sar.num, test->sar.den);
     return 0;
 }
 
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    TestSourceContext *test = ctx->priv;
+
+    av_opt_free(test);
+    avfilter_unref_bufferp(&test->picref);
+}
+
 static int config_props(AVFilterLink *outlink)
 {
     TestSourceContext *test = outlink->src->priv;
@@ -122,7 +160,8 @@
     outlink->w = test->w;
     outlink->h = test->h;
     outlink->sample_aspect_ratio = test->sar;
-    outlink->time_base = test->time_base;
+    outlink->frame_rate = test->frame_rate;
+    outlink->time_base  = test->time_base;
 
     return 0;
 }
@@ -130,25 +169,41 @@
 static int request_frame(AVFilterLink *outlink)
 {
     TestSourceContext *test = outlink->src->priv;
-    AVFilterBufferRef *picref;
-    int ret;
+    AVFilterBufferRef *outpicref;
+    int ret = 0;
 
-    if (test->max_pts >= 0 && test->pts > test->max_pts)
+    if (test->duration >= 0 &&
+        av_rescale_q(test->pts, test->time_base, AV_TIME_BASE_Q) >= test->duration)
         return AVERROR_EOF;
-    picref = ff_get_video_buffer(outlink, AV_PERM_WRITE, test->w, test->h);
-    if (!picref)
+
+    if (test->draw_once) {
+        if (!test->picref) {
+            test->picref =
+                ff_get_video_buffer(outlink, AV_PERM_WRITE|AV_PERM_PRESERVE|AV_PERM_REUSE,
+                                    test->w, test->h);
+            if (!test->picref)
+                return AVERROR(ENOMEM);
+            test->fill_picture_fn(outlink->src, test->picref);
+        }
+        outpicref = avfilter_ref_buffer(test->picref, ~AV_PERM_WRITE);
+    } else
+        outpicref = ff_get_video_buffer(outlink, AV_PERM_WRITE, test->w, test->h);
+
+    if (!outpicref)
         return AVERROR(ENOMEM);
+    outpicref->pts = test->pts;
+    outpicref->pos = -1;
+    outpicref->video->key_frame = 1;
+    outpicref->video->interlaced = 0;
+    outpicref->video->pict_type = AV_PICTURE_TYPE_I;
+    outpicref->video->sample_aspect_ratio = test->sar;
+    if (!test->draw_once)
+        test->fill_picture_fn(outlink->src, outpicref);
 
-    picref->pts = test->pts++;
-    picref->pos = -1;
-    picref->video->key_frame = 1;
-    picref->video->interlaced = 0;
-    picref->video->pict_type = AV_PICTURE_TYPE_I;
-    picref->video->pixel_aspect = test->sar;
+    test->pts++;
     test->nb_frame++;
-    test->fill_picture_fn(outlink->src, picref);
 
-    if ((ret = ff_start_frame(outlink, picref)) < 0 ||
+    if ((ret = ff_start_frame(outlink, outpicref)) < 0 ||
         (ret = ff_draw_slice(outlink, 0, test->h, 1)) < 0 ||
         (ret = ff_end_frame(outlink)) < 0)
         return ret;
@@ -156,19 +211,125 @@
     return 0;
 }
 
-#if CONFIG_TESTSRC_FILTER
+#if CONFIG_COLOR_FILTER
 
-static const char *testsrc_get_name(void *ctx)
+#define color_options options
+AVFILTER_DEFINE_CLASS(color);
+
+static void color_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
 {
-    return "testsrc";
+    TestSourceContext *test = ctx->priv;
+    ff_fill_rectangle(&test->draw, &test->color,
+                      picref->data, picref->linesize,
+                      0, 0, test->w, test->h);
 }
 
-static const AVClass testsrc_class = {
-    .class_name = "TestSourceContext",
-    .item_name  = testsrc_get_name,
-    .option     = testsrc_options,
+static av_cold int color_init(AVFilterContext *ctx, const char *args)
+{
+    TestSourceContext *test = ctx->priv;
+    test->class = &color_class;
+    test->fill_picture_fn = color_fill_picture;
+    test->draw_once = 1;
+    av_opt_set(test, "color", "black", 0);
+    return init(ctx, args);
+}
+
+static int color_query_formats(AVFilterContext *ctx)
+{
+    ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0));
+    return 0;
+}
+
+static int color_config_props(AVFilterLink *inlink)
+{
+    AVFilterContext *ctx = inlink->src;
+    TestSourceContext *test = ctx->priv;
+    int ret;
+
+    ff_draw_init(&test->draw, inlink->format, 0);
+    ff_draw_color(&test->draw, &test->color, test->color_rgba);
+
+    test->w = ff_draw_round_to_sub(&test->draw, 0, -1, test->w);
+    test->h = ff_draw_round_to_sub(&test->draw, 1, -1, test->h);
+    if (av_image_check_size(test->w, test->h, 0, ctx) < 0)
+        return AVERROR(EINVAL);
+
+    if (ret = config_props(inlink) < 0)
+        return ret;
+
+    av_log(ctx, AV_LOG_VERBOSE, "color:0x%02x%02x%02x%02x\n",
+           test->color_rgba[0], test->color_rgba[1], test->color_rgba[2], test->color_rgba[3]);
+    return 0;
+}
+
+AVFilter avfilter_vsrc_color = {
+    .name        = "color",
+    .description = NULL_IF_CONFIG_SMALL("Provide an uniformly colored input."),
+
+    .priv_size = sizeof(TestSourceContext),
+    .init      = color_init,
+    .uninit    = uninit,
+
+    .query_formats = color_query_formats,
+
+    .inputs = (const AVFilterPad[]) {
+        { .name = NULL }
+    },
+
+    .outputs = (const AVFilterPad[]) {
+        {
+            .name            = "default",
+            .type            = AVMEDIA_TYPE_VIDEO,
+            .request_frame   = request_frame,
+            .config_props    = color_config_props,
+        },
+        { .name = NULL }
+    },
+
+    .priv_class = &color_class,
 };
 
+#endif /* CONFIG_COLOR_FILTER */
+
+#if CONFIG_NULLSRC_FILTER
+
+#define nullsrc_options options
+AVFILTER_DEFINE_CLASS(nullsrc);
+
+static void nullsrc_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref) { }
+
+static av_cold int nullsrc_init(AVFilterContext *ctx, const char *args)
+{
+    TestSourceContext *test = ctx->priv;
+
+    test->class = &nullsrc_class;
+    test->fill_picture_fn = nullsrc_fill_picture;
+    return init(ctx, args);
+}
+
+AVFilter avfilter_vsrc_nullsrc = {
+    .name        = "nullsrc",
+    .description = NULL_IF_CONFIG_SMALL("Null video source, return unprocessed video frames."),
+    .init       = nullsrc_init,
+    .uninit     = uninit,
+    .priv_size  = sizeof(TestSourceContext),
+
+    .inputs    = (const AVFilterPad[]) {{ .name = NULL}},
+    .outputs   = (const AVFilterPad[]) {{ .name = "default",
+                                    .type = AVMEDIA_TYPE_VIDEO,
+                                    .request_frame = request_frame,
+                                    .config_props  = config_props, },
+                                  { .name = NULL}},
+    .priv_class = &nullsrc_class,
+};
+
+#endif /* CONFIG_NULLSRC_FILTER */
+
+#if CONFIG_TESTSRC_FILTER
+
+#define testsrc_options options
+AVFILTER_DEFINE_CLASS(testsrc);
+
 /**
  * Fill a rectangle with value val.
  *
@@ -291,7 +452,7 @@
     }
 
     /* draw sliding color line */
-    p = data + picref->linesize[0] * height * 3/4;
+    p0 = p = data + picref->linesize[0] * height * 3/4;
     grad = (256 * test->nb_frame * test->time_base.num / test->time_base.den) %
         GRADIENT_SIZE;
     rgrad = 0;
@@ -319,15 +480,20 @@
         if (grad >= GRADIENT_SIZE)
             grad -= GRADIENT_SIZE;
     }
+    p = p0;
     for (y = height / 8; y > 0; y--) {
-        memcpy(p, p - picref->linesize[0], 3 * width);
+        memcpy(p+picref->linesize[0], p, 3 * width);
         p += picref->linesize[0];
     }
 
     /* draw digits */
     seg_size = width / 80;
     if (seg_size >= 1 && height >= 13 * seg_size) {
-        second = test->nb_frame * test->time_base.num / test->time_base.den;
+        double time = av_q2d(test->time_base) * test->nb_frame *
+                      pow(10, test->nb_decimals);
+        if (time > INT_MAX)
+            return;
+        second = (int)time;
         x = width - (width - seg_size * 64) / 2;
         y = (height - seg_size * 13) / 2;
         p = data + (x*3 + y * picref->linesize[0]);
@@ -347,7 +513,7 @@
 
     test->class = &testsrc_class;
     test->fill_picture_fn = test_fill_picture;
-    return init_common(ctx, args);
+    return init(ctx, args);
 }
 
 static int test_query_formats(AVFilterContext *ctx)
@@ -370,32 +536,25 @@
 };
 
 AVFilter avfilter_vsrc_testsrc = {
-    .name          = "testsrc",
-    .description   = NULL_IF_CONFIG_SMALL("Generate test pattern."),
-    .priv_size     = sizeof(TestSourceContext),
-    .init          = test_init,
+    .name      = "testsrc",
+    .description = NULL_IF_CONFIG_SMALL("Generate test pattern."),
+    .priv_size = sizeof(TestSourceContext),
+    .init      = test_init,
+    .uninit    = uninit,
 
-    .query_formats = test_query_formats,
+    .query_formats   = test_query_formats,
 
     .inputs    = NULL,
-
     .outputs   = avfilter_vsrc_testsrc_outputs,
+    .priv_class = &testsrc_class,
 };
 
 #endif /* CONFIG_TESTSRC_FILTER */
 
 #if CONFIG_RGBTESTSRC_FILTER
 
-static const char *rgbtestsrc_get_name(void *ctx)
-{
-    return "rgbtestsrc";
-}
-
-static const AVClass rgbtestsrc_class = {
-    .class_name = "RGBTestSourceContext",
-    .item_name  = rgbtestsrc_get_name,
-    .option     = testsrc_options,
-};
+#define rgbtestsrc_options options
+AVFILTER_DEFINE_CLASS(rgbtestsrc);
 
 #define R 0
 #define G 1
@@ -404,7 +563,7 @@
 
 static void rgbtest_put_pixel(uint8_t *dst, int dst_linesize,
                               int x, int y, int r, int g, int b, enum AVPixelFormat fmt,
-                              int rgba_map[4])
+                              uint8_t rgba_map[4])
 {
     int32_t v;
     uint8_t *p;
@@ -426,7 +585,7 @@
     case AV_PIX_FMT_BGRA:
     case AV_PIX_FMT_ARGB:
     case AV_PIX_FMT_ABGR:
-        v = (r << (rgba_map[R]*8)) + (g << (rgba_map[G]*8)) + (b << (rgba_map[B]*8));
+        v = (r << (rgba_map[R]*8)) + (g << (rgba_map[G]*8)) + (b << (rgba_map[B]*8)) + (255 << (rgba_map[A]*8));
         p = dst + 4*x + y*dst_linesize;
         AV_WL32(p, v);
         break;
@@ -457,9 +616,10 @@
 {
     TestSourceContext *test = ctx->priv;
 
+    test->draw_once = 1;
     test->class = &rgbtestsrc_class;
     test->fill_picture_fn = rgbtest_fill_picture;
-    return init_common(ctx, args);
+    return init(ctx, args);
 }
 
 static int rgbtest_query_formats(AVFilterContext *ctx)
@@ -480,15 +640,7 @@
 {
     TestSourceContext *test = outlink->src->priv;
 
-    switch (outlink->format) {
-    case AV_PIX_FMT_ARGB:  test->rgba_map[A] = 0; test->rgba_map[R] = 1; test->rgba_map[G] = 2; test->rgba_map[B] = 3; break;
-    case AV_PIX_FMT_ABGR:  test->rgba_map[A] = 0; test->rgba_map[B] = 1; test->rgba_map[G] = 2; test->rgba_map[R] = 3; break;
-    case AV_PIX_FMT_RGBA:
-    case AV_PIX_FMT_RGB24: test->rgba_map[R] = 0; test->rgba_map[G] = 1; test->rgba_map[B] = 2; test->rgba_map[A] = 3; break;
-    case AV_PIX_FMT_BGRA:
-    case AV_PIX_FMT_BGR24: test->rgba_map[B] = 0; test->rgba_map[G] = 1; test->rgba_map[R] = 2; test->rgba_map[A] = 3; break;
-    }
-
+    ff_fill_rgba_map(test->rgba_map, outlink->format);
     return config_props(outlink);
 }
 
@@ -503,16 +655,148 @@
 };
 
 AVFilter avfilter_vsrc_rgbtestsrc = {
-    .name          = "rgbtestsrc",
-    .description   = NULL_IF_CONFIG_SMALL("Generate RGB test pattern."),
-    .priv_size     = sizeof(TestSourceContext),
-    .init          = rgbtest_init,
+    .name      = "rgbtestsrc",
+    .description = NULL_IF_CONFIG_SMALL("Generate RGB test pattern."),
+    .priv_size = sizeof(TestSourceContext),
+    .init      = rgbtest_init,
+    .uninit    = uninit,
 
-    .query_formats = rgbtest_query_formats,
+    .query_formats   = rgbtest_query_formats,
 
     .inputs    = NULL,
 
     .outputs   = avfilter_vsrc_rgbtestsrc_outputs,
+    .priv_class = &rgbtestsrc_class,
 };
 
 #endif /* CONFIG_RGBTESTSRC_FILTER */
+
+#if CONFIG_SMPTEBARS_FILTER
+
+#define smptebars_options options
+AVFILTER_DEFINE_CLASS(smptebars);
+
+static const uint8_t rainbow[7][4] = {
+    { 191, 191, 191, 255 },     /* gray */
+    { 191, 191,   0, 255 },     /* yellow */
+    {   0, 191, 191, 255 },     /* cyan */
+    {   0, 191,   0, 255 },     /* green */
+    { 191,   0, 191, 255 },     /* magenta */
+    { 191,   0,   0, 255 },     /* red */
+    {   0,   0, 191, 255 },     /* blue */
+};
+
+static const uint8_t wobnair[7][4] = {
+    {   0,   0, 191, 255 },     /* blue */
+    {  19,  19,  19, 255 },     /* 7.5% intensity black */
+    { 191,   0, 191, 255 },     /* magenta */
+    {  19,  19,  19, 255 },     /* 7.5% intensity black */
+    {   0, 191, 191, 255 },     /* cyan */
+    {  19,  19,  19, 255 },     /* 7.5% intensity black */
+    { 191, 191, 191, 255 },     /* gray */
+};
+
+static const uint8_t white[4] = { 255, 255, 255, 255 };
+static const uint8_t black[4] = {  19,  19,  19, 255 }; /* 7.5% intensity black */
+
+/* pluge pulses */
+static const uint8_t neg4ire[4] = {   9,   9,   9, 255 }; /*  3.5% intensity black */
+static const uint8_t pos4ire[4] = {  29,  29,  29, 255 }; /* 11.5% intensity black */
+
+/* fudged Q/-I */
+static const uint8_t i_pixel[4] = {   0,  68, 130, 255 };
+static const uint8_t q_pixel[4] = {  67,   0, 130, 255 };
+
+static void smptebars_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref)
+{
+    TestSourceContext *test = ctx->priv;
+    FFDrawColor color;
+    int r_w, r_h, w_h, p_w, p_h, i, x = 0;
+
+    r_w = (test->w + 6) / 7;
+    r_h = test->h * 2 / 3;
+    w_h = test->h * 3 / 4 - r_h;
+    p_w = r_w * 5 / 4;
+    p_h = test->h - w_h - r_h;
+
+#define DRAW_COLOR(rgba, x, y, w, h)                                    \
+    ff_draw_color(&test->draw, &color, rgba);                           \
+    ff_fill_rectangle(&test->draw, &color,                              \
+                      picref->data, picref->linesize, x, y, w, h)       \
+
+    for (i = 0; i < 7; i++) {
+        DRAW_COLOR(rainbow[i], x, 0,   FFMIN(r_w, test->w - x), r_h);
+        DRAW_COLOR(wobnair[i], x, r_h, FFMIN(r_w, test->w - x), w_h);
+        x += r_w;
+    }
+    x = 0;
+    DRAW_COLOR(i_pixel, x, r_h + w_h, p_w, p_h);
+    x += p_w;
+    DRAW_COLOR(white, x, r_h + w_h, p_w, p_h);
+    x += p_w;
+    DRAW_COLOR(q_pixel, x, r_h + w_h, p_w, p_h);
+    x += p_w;
+    DRAW_COLOR(black, x, r_h + w_h, 5 * r_w - x, p_h);
+    x += 5 * r_w - x;
+    DRAW_COLOR(neg4ire, x, r_h + w_h, r_w / 3, p_h);
+    x += r_w / 3;
+    DRAW_COLOR(black, x, r_h + w_h, r_w / 3, p_h);
+    x += r_w / 3;
+    DRAW_COLOR(pos4ire, x, r_h + w_h, r_w / 3, p_h);
+    x += r_w / 3;
+    DRAW_COLOR(black, x, r_h + w_h, test->w - x, p_h);
+}
+
+static av_cold int smptebars_init(AVFilterContext *ctx, const char *args)
+{
+    TestSourceContext *test = ctx->priv;
+
+    test->class = &smptebars_class;
+    test->fill_picture_fn = smptebars_fill_picture;
+    test->draw_once = 1;
+    return init(ctx, args);
+}
+
+static int smptebars_query_formats(AVFilterContext *ctx)
+{
+    ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0));
+    return 0;
+}
+
+static int smptebars_config_props(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    TestSourceContext *test = ctx->priv;
+
+    ff_draw_init(&test->draw, outlink->format, 0);
+
+    return config_props(outlink);
+}
+
+AVFilter avfilter_vsrc_smptebars = {
+    .name      = "smptebars",
+    .description = NULL_IF_CONFIG_SMALL("Generate SMPTE color bars."),
+    .priv_size = sizeof(TestSourceContext),
+    .init      = smptebars_init,
+    .uninit    = uninit,
+
+    .query_formats = smptebars_query_formats,
+
+    .inputs = (const AVFilterPad[]) {
+        { .name = NULL }
+    },
+
+    .outputs = (const AVFilterPad[]) {
+        {
+            .name = "default",
+            .type = AVMEDIA_TYPE_VIDEO,
+            .request_frame = request_frame,
+            .config_props  = smptebars_config_props,
+        },
+        { .name = NULL }
+    },
+
+    .priv_class = &smptebars_class,
+};
+
+#endif  /* CONFIG_SMPTEBARS_FILTER */
diff --git a/libavfilter/x86/gradfun.c b/libavfilter/x86/gradfun.c
index 424a031..6faf7d1 100644
--- a/libavfilter/x86/gradfun.c
+++ b/libavfilter/x86/gradfun.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2009 Loren Merritt <lorenm@u.washignton.edu>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,7 +30,7 @@
 DECLARE_ALIGNED(16, static const uint16_t, pw_ff)[8] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
 
 #if HAVE_MMXEXT_INLINE
-static void gradfun_filter_line_mmx2(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers)
+static void gradfun_filter_line_mmx2(uint8_t *dst, const uint8_t *src, const uint16_t *dc, int width, int thresh, const uint16_t *dithers)
 {
     intptr_t x;
     if (width & 3) {
@@ -78,7 +78,7 @@
 #endif
 
 #if HAVE_SSSE3_INLINE
-static void gradfun_filter_line_ssse3(uint8_t *dst, uint8_t *src, uint16_t *dc, int width, int thresh, const uint16_t *dithers)
+static void gradfun_filter_line_ssse3(uint8_t *dst, const uint8_t *src, const uint16_t *dc, int width, int thresh, const uint16_t *dithers)
 {
     intptr_t x;
     if (width & 7) {
@@ -125,7 +125,7 @@
 #endif /* HAVE_SSSE3_INLINE */
 
 #if HAVE_SSE2_INLINE
-static void gradfun_blur_line_sse2(uint16_t *dc, uint16_t *buf, uint16_t *buf1, uint8_t *src, int src_linesize, int width)
+static void gradfun_blur_line_sse2(uint16_t *dc, uint16_t *buf, const uint16_t *buf1, const uint8_t *src, int src_linesize, int width)
 {
 #define BLURV(load)\
     intptr_t x = -2*width;\
diff --git a/libavfilter/x86/hqdn3d.asm b/libavfilter/x86/hqdn3d.asm
index 7254194..d36ce37 100644
--- a/libavfilter/x86/hqdn3d.asm
+++ b/libavfilter/x86/hqdn3d.asm
@@ -1,20 +1,20 @@
 ;******************************************************************************
 ;* Copyright (c) 2012 Loren Merritt
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
@@ -39,6 +39,7 @@
 %endif
 %if %3 != 16
     shl    %1, 16-%3
+    add    %1, (1<<(15-%3))-1
 %endif
 %endmacro
 
@@ -86,7 +87,6 @@
     mov       [frameantq+xq*2], t0w
     movifnidn dstq, dstmp
 %if %1 != 16
-    add    t0d, (1<<(15-%1))-1
     shr    t0d, 16-%1 ; could eliminate this by storing from t0h, but only with some contraints on register allocation
 %endif
 %if %1 == 8
diff --git a/libavfilter/x86/yadif.c b/libavfilter/x86/yadif.c
index f178b32..881be5a 100644
--- a/libavfilter/x86/yadif.c
+++ b/libavfilter/x86/yadif.c
@@ -1,26 +1,25 @@
 /*
  * Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or modify
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License along
- * with Libav; if not, write to the Free Software Foundation, Inc.,
+ * 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/internal.h"
 #include "libavutil/mem.h"
 #include "libavutil/x86/asm.h"
 #include "libavcodec/x86/dsputil_mmx.h"
diff --git a/libavfilter/x86/yadif_template.c b/libavfilter/x86/yadif_template.c
index 02b0c9f..674c088 100644
--- a/libavfilter/x86/yadif_template.c
+++ b/libavfilter/x86/yadif_template.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or modify
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License along
- * with Libav; if not, write to the Free Software Foundation, Inc.,
+ * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
@@ -107,7 +107,8 @@
                                       uint8_t *next, int w, int prefs,
                                       int mrefs, int parity, int mode)
 {
-    DECLARE_ALIGNED(16, uint8_t, tmp)[16*4];
+    uint8_t tmpU[5*16];
+    uint8_t *tmp= (uint8_t*)(((uint64_t)(tmpU+15)) & ~15);
     int x;
 
 #define FILTER\
diff --git a/libavfilter/yadif.h b/libavfilter/yadif.h
index 06b39c6..41691de 100644
--- a/libavfilter/yadif.h
+++ b/libavfilter/yadif.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or modify
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License along
- * with Libav; if not, write to the Free Software Foundation, Inc.,
+ * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
@@ -56,6 +56,8 @@
 
     const AVPixFmtDescriptor *csp;
     int eof;
+    uint8_t *temp_line;
+    int temp_line_size;
 } YADIFContext;
 
 void ff_yadif_init_x86(YADIFContext *yadif);
diff --git a/libavformat/4xm.c b/libavformat/4xm.c
index e530c34..0a003d4 100644
--- a/libavformat/4xm.c
+++ b/libavformat/4xm.c
@@ -2,20 +2,20 @@
  * 4X Technologies .4xm File Demuxer (no muxer)
  * Copyright (c) 2003  The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -128,6 +128,10 @@
     for (i = 0; i < header_size - 8; i++) {
         fourcc_tag = AV_RL32(&header[i]);
         size = AV_RL32(&header[i + 4]);
+        if (size > header_size - i - 8 && (fourcc_tag == vtrk_TAG || fourcc_tag == strk_TAG)) {
+            av_log(s, AV_LOG_ERROR, "chunk larger than array %d>%d\n", size, header_size - i - 8);
+            return AVERROR_INVALIDDATA;
+        }
 
         if (fourcc_tag == std__TAG) {
             fourxm->fps = av_int2float(AV_RL32(&header[i + 12]));
@@ -169,12 +173,13 @@
             current_track = AV_RL32(&header[i + 8]);
             if((unsigned)current_track >= UINT_MAX / sizeof(AudioTrack) - 1){
                 av_log(s, AV_LOG_ERROR, "current_track too large\n");
-                ret= -1;
+                ret = AVERROR_INVALIDDATA;
                 goto fail;
             }
             if (current_track + 1 > fourxm->track_count) {
-                fourxm->tracks = av_realloc(fourxm->tracks,
-                    (current_track + 1) * sizeof(AudioTrack));
+                fourxm->tracks = av_realloc_f(fourxm->tracks,
+                                              sizeof(AudioTrack),
+                                              current_track + 1);
                 if (!fourxm->tracks) {
                     ret = AVERROR(ENOMEM);
                     goto fail;
@@ -192,7 +197,12 @@
                || fourxm->tracks[current_track].sample_rate <= 0
                || fourxm->tracks[current_track].bits        <  0){
                 av_log(s, AV_LOG_ERROR, "audio header invalid\n");
-                ret= -1;
+                ret = AVERROR_INVALIDDATA;
+                goto fail;
+            }
+            if(!fourxm->tracks[current_track].adpcm && fourxm->tracks[current_track].bits<8){
+                av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n");
+                ret = AVERROR_INVALIDDATA;
                 goto fail;
             }
             i += 8 + size;
@@ -263,7 +273,7 @@
             return ret;
         fourcc_tag = AV_RL32(&header[0]);
         size = AV_RL32(&header[4]);
-        if (pb->eof_reached)
+        if (url_feof(pb))
             return AVERROR(EIO);
         switch (fourcc_tag) {
 
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 5d89a2e..8a0e129 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -1,3 +1,5 @@
+include $(SUBDIR)../config.mak
+
 NAME = avformat
 FFLIBS = avcodec avutil
 
@@ -19,6 +21,7 @@
        riff.o               \
        sdp.o                \
        seek.o               \
+       subtitles.o          \
        utils.o              \
 
 OBJS-$(CONFIG_NETWORK)                   += network.o
@@ -28,12 +31,15 @@
 OBJS-$(CONFIG_AAC_DEMUXER)               += aacdec.o rawdec.o
 OBJS-$(CONFIG_AC3_DEMUXER)               += ac3dec.o rawdec.o
 OBJS-$(CONFIG_AC3_MUXER)                 += rawenc.o
+OBJS-$(CONFIG_ACT_DEMUXER)               += act.o
+OBJS-$(CONFIG_ADF_DEMUXER)               += bintext.o sauce.o
 OBJS-$(CONFIG_ADX_DEMUXER)               += adxdec.o
 OBJS-$(CONFIG_ADX_MUXER)                 += rawenc.o
 OBJS-$(CONFIG_ADTS_MUXER)                += adtsenc.o
 OBJS-$(CONFIG_AEA_DEMUXER)               += aea.o pcm.o
-OBJS-$(CONFIG_AIFF_DEMUXER)              += aiffdec.o pcm.o
-OBJS-$(CONFIG_AIFF_MUXER)                += aiffenc.o
+OBJS-$(CONFIG_AIFF_DEMUXER)              += aiffdec.o pcm.o isom.o \
+                                            mov_chan.o
+OBJS-$(CONFIG_AIFF_MUXER)                += aiffenc.o isom.o
 OBJS-$(CONFIG_AMR_DEMUXER)               += amr.o
 OBJS-$(CONFIG_AMR_MUXER)                 += amr.o
 OBJS-$(CONFIG_ANM_DEMUXER)               += anm.o
@@ -54,10 +60,14 @@
 OBJS-$(CONFIG_BETHSOFTVID_DEMUXER)       += bethsoftvid.o
 OBJS-$(CONFIG_BFI_DEMUXER)               += bfi.o
 OBJS-$(CONFIG_BINK_DEMUXER)              += bink.o
+OBJS-$(CONFIG_BINTEXT_DEMUXER)           += bintext.o sauce.o
+OBJS-$(CONFIG_BIT_DEMUXER)               += bit.o
+OBJS-$(CONFIG_BIT_MUXER)                 += bit.o
 OBJS-$(CONFIG_BMV_DEMUXER)               += bmv.o
 OBJS-$(CONFIG_C93_DEMUXER)               += c93.o vocdec.o voc.o
 OBJS-$(CONFIG_CAF_DEMUXER)               += cafdec.o caf.o mov.o mov_chan.o \
                                             isom.o
+OBJS-$(CONFIG_CAF_MUXER)                 += cafenc.o caf.o riff.o isom.o
 OBJS-$(CONFIG_CAVSVIDEO_DEMUXER)         += cavsvideodec.o rawdec.o
 OBJS-$(CONFIG_CAVSVIDEO_MUXER)           += rawenc.o
 OBJS-$(CONFIG_CDG_DEMUXER)               += cdg.o
@@ -71,6 +81,7 @@
 OBJS-$(CONFIG_DNXHD_DEMUXER)             += dnxhddec.o rawdec.o
 OBJS-$(CONFIG_DNXHD_MUXER)               += rawenc.o
 OBJS-$(CONFIG_DSICIN_DEMUXER)            += dsicin.o
+OBJS-$(CONFIG_DTSHD_DEMUXER)             += dtshddec.o
 OBJS-$(CONFIG_DTS_DEMUXER)               += dtsdec.o rawdec.o
 OBJS-$(CONFIG_DTS_MUXER)                 += rawenc.o
 OBJS-$(CONFIG_DV_DEMUXER)                += dv.o
@@ -104,6 +115,8 @@
 OBJS-$(CONFIG_G722_DEMUXER)              += rawdec.o
 OBJS-$(CONFIG_G722_MUXER)                += rawenc.o
 OBJS-$(CONFIG_G723_1_DEMUXER)            += g723_1.o
+OBJS-$(CONFIG_G723_1_MUXER)              += rawenc.o
+OBJS-$(CONFIG_G729_DEMUXER)              += g729dec.o
 OBJS-$(CONFIG_H261_DEMUXER)              += h261dec.o rawdec.o
 OBJS-$(CONFIG_H261_MUXER)                += rawenc.o
 OBJS-$(CONFIG_H263_DEMUXER)              += h263dec.o rawdec.o
@@ -111,7 +124,10 @@
 OBJS-$(CONFIG_H264_DEMUXER)              += h264dec.o rawdec.o
 OBJS-$(CONFIG_H264_MUXER)                += rawenc.o
 OBJS-$(CONFIG_HLS_DEMUXER)               += hls.o
+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_IFF_DEMUXER)               += iff.o
 OBJS-$(CONFIG_ILBC_DEMUXER)              += ilbc.o
 OBJS-$(CONFIG_ILBC_MUXER)                += ilbc.o
@@ -128,10 +144,13 @@
 OBJS-$(CONFIG_IV8_DEMUXER)               += iv8.o
 OBJS-$(CONFIG_IVF_DEMUXER)               += ivfdec.o
 OBJS-$(CONFIG_IVF_MUXER)                 += ivfenc.o
+OBJS-$(CONFIG_JACOSUB_DEMUXER)           += jacosubdec.o
+OBJS-$(CONFIG_JACOSUB_MUXER)             += jacosubenc.o rawenc.o
 OBJS-$(CONFIG_JV_DEMUXER)                += jvdec.o
 OBJS-$(CONFIG_LATM_DEMUXER)              += rawdec.o
-OBJS-$(CONFIG_LATM_MUXER)                += latmenc.o
+OBJS-$(CONFIG_LATM_MUXER)                += latmenc.o rawenc.o
 OBJS-$(CONFIG_LMLM4_DEMUXER)             += lmlm4.o
+OBJS-$(CONFIG_LOAS_DEMUXER)              += loasdec.o
 OBJS-$(CONFIG_LXF_DEMUXER)               += lxfdec.o
 OBJS-$(CONFIG_M4V_DEMUXER)               += m4vdec.o rawdec.o
 OBJS-$(CONFIG_M4V_MUXER)                 += rawenc.o
@@ -141,6 +160,9 @@
                                             isom.o avc.o \
                                             flacenc_header.o avlanguage.o
 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_MJPEG_DEMUXER)             += rawdec.o
 OBJS-$(CONFIG_MJPEG_MUXER)               += rawenc.o
 OBJS-$(CONFIG_MLP_DEMUXER)               += rawdec.o
@@ -186,6 +208,7 @@
                                             oggparsedirac.o  \
                                             oggparseflac.o   \
                                             oggparseogm.o    \
+                                            oggparseopus.o   \
                                             oggparseskeleton.o \
                                             oggparsespeex.o  \
                                             oggparsetheora.o \
@@ -195,6 +218,7 @@
                                             vorbiscomment.o
 OBJS-$(CONFIG_OMA_DEMUXER)               += omadec.o pcm.o oma.o
 OBJS-$(CONFIG_OMA_MUXER)                 += omaenc.o rawenc.o oma.o id3v2enc.o
+OBJS-$(CONFIG_PAF_DEMUXER)               += paf.o
 OBJS-$(CONFIG_PCM_ALAW_DEMUXER)          += pcmdec.o pcm.o rawdec.o
 OBJS-$(CONFIG_PCM_ALAW_MUXER)            += pcmenc.o rawenc.o
 OBJS-$(CONFIG_PCM_F32BE_DEMUXER)         += pcmdec.o pcm.o rawdec.o
@@ -241,6 +265,7 @@
 OBJS-$(CONFIG_R3D_DEMUXER)               += r3d.o
 OBJS-$(CONFIG_RAWVIDEO_DEMUXER)          += rawvideodec.o rawdec.o
 OBJS-$(CONFIG_RAWVIDEO_MUXER)            += rawenc.o
+OBJS-$(CONFIG_REALTEXT_DEMUXER)          += realtextdec.o
 OBJS-$(CONFIG_RL2_DEMUXER)               += rl2.o
 OBJS-$(CONFIG_RM_DEMUXER)                += rmdec.o rm.o
 OBJS-$(CONFIG_RM_MUXER)                  += rmenc.o rm.o
@@ -285,8 +310,10 @@
                                             urldecode.o
 OBJS-$(CONFIG_RTSP_MUXER)                += rtsp.o rtspenc.o httpauth.o \
                                             rtpenc_chain.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_SBG_DEMUXER)               += sbgdec.o
 OBJS-$(CONFIG_SDP_DEMUXER)               += rtsp.o
 OBJS-$(CONFIG_SEGAFILM_DEMUXER)          += segafilm.o
 OBJS-$(CONFIG_SEGMENT_MUXER)             += segment.o
@@ -296,18 +323,22 @@
 OBJS-$(CONFIG_SMJPEG_DEMUXER)            += smjpegdec.o smjpeg.o
 OBJS-$(CONFIG_SMJPEG_MUXER)              += smjpegenc.o smjpeg.o
 OBJS-$(CONFIG_SMOOTHSTREAMING_MUXER)     += smoothstreamingenc.o isom.o
+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_SPDIF_DEMUXER)             += spdif.o spdifdec.o
 OBJS-$(CONFIG_SPDIF_MUXER)               += spdif.o spdifenc.o
 OBJS-$(CONFIG_SRT_DEMUXER)               += srtdec.o
-OBJS-$(CONFIG_SRT_MUXER)                 += rawenc.o
+OBJS-$(CONFIG_SRT_MUXER)                 += srtenc.o
 OBJS-$(CONFIG_STR_DEMUXER)               += psxstr.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_THP_DEMUXER)               += thp.o
 OBJS-$(CONFIG_TIERTEXSEQ_DEMUXER)        += tiertexseq.o
+OBJS-$(CONFIG_MKVTIMESTAMP_V2_MUXER)     += mkvtimestamp_v2.o
 OBJS-$(CONFIG_TMV_DEMUXER)               += tmv.o
 OBJS-$(CONFIG_TRUEHD_DEMUXER)            += rawdec.o
 OBJS-$(CONFIG_TRUEHD_MUXER)              += rawenc.o
@@ -328,12 +359,16 @@
 OBJS-$(CONFIG_WEBM_MUXER)                += matroskaenc.o matroska.o \
                                             isom.o avc.o \
                                             flacenc_header.o avlanguage.o
+OBJS-$(CONFIG_WEBVTT_DEMUXER)            += webvttdec.o
 OBJS-$(CONFIG_WSAUD_DEMUXER)             += westwood_aud.o
 OBJS-$(CONFIG_WSVQA_DEMUXER)             += westwood_vqa.o
-OBJS-$(CONFIG_WTV_DEMUXER)               += wtv.o asfdec.o asf.o asfcrypt.o \
+OBJS-$(CONFIG_WTV_DEMUXER)               += wtvdec.o wtv.o asfdec.o asf.o asfcrypt.o \
                                             avlanguage.o mpegts.o isom.o
+OBJS-$(CONFIG_WTV_MUXER)                 += wtvenc.o wtv.o asf.o asfenc.o
 OBJS-$(CONFIG_WV_DEMUXER)                += wv.o apetag.o img2.o
+OBJS-$(CONFIG_WV_MUXER)                  += wvenc.o apetagenc.o
 OBJS-$(CONFIG_XA_DEMUXER)                += xa.o
+OBJS-$(CONFIG_XBIN_DEMUXER)              += bintext.o sauce.o
 OBJS-$(CONFIG_XMV_DEMUXER)               += xmv.o
 OBJS-$(CONFIG_XWMA_DEMUXER)              += xwma.o
 OBJS-$(CONFIG_YOP_DEMUXER)               += yop.o
@@ -341,10 +376,15 @@
 OBJS-$(CONFIG_YUV4MPEGPIPE_DEMUXER)      += yuv4mpeg.o
 
 # external libraries
+OBJS-$(CONFIG_LIBMODPLUG_DEMUXER)        += libmodplug.o
+OBJS-$(CONFIG_LIBNUT_DEMUXER)            += libnut.o
+OBJS-$(CONFIG_LIBNUT_MUXER)              += libnut.o
 OBJS-$(CONFIG_LIBRTMP)                   += librtmp.o
 
 # protocols I/O
 OBJS-$(CONFIG_APPLEHTTP_PROTOCOL)        += hlsproto.o
+OBJS-$(CONFIG_BLURAY_PROTOCOL)           += bluray.o
+OBJS-$(CONFIG_CACHE_PROTOCOL)            += cache.o
 OBJS-$(CONFIG_CONCAT_PROTOCOL)           += concat.o
 OBJS-$(CONFIG_CRYPTO_PROTOCOL)           += crypto.o
 OBJS-$(CONFIG_FFRTMPCRYPT_PROTOCOL)      += rtmpcrypt.o rtmpdh.o
@@ -373,10 +413,6 @@
 
 SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h
 SKIPHEADERS-$(CONFIG_NETWORK)            += network.h rtsp.h
-
-EXAMPLES  = metadata                                                    \
-            output                                                      \
-
 TESTPROGS = seek                                                        \
             url                                                         \
 
@@ -384,5 +420,3 @@
             ismindex                                                    \
             pktdumper                                                   \
             probetest                                                   \
-
-$(SUBDIR)output-example$(EXESUF): ELIBS = $(patsubst %,$(LD_LIB),swscale)
diff --git a/libavformat/a64.c b/libavformat/a64.c
index 56b9a44..c1f6b67 100644
--- a/libavformat/a64.c
+++ b/libavformat/a64.c
@@ -2,20 +2,20 @@
  * a64 muxer
  * Copyright (c) 2009 Tobias Bindhammer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/aacdec.c b/libavformat/aacdec.c
index 6f9763f..e165959 100644
--- a/libavformat/aacdec.c
+++ b/libavformat/aacdec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2009 Robert Swain ( rob opendot cl )
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -48,6 +48,7 @@
             fsize = (AV_RB32(buf2 + 3) >> 13) & 0x1FFF;
             if(fsize < 7)
                 break;
+            fsize = FFMIN(fsize, end - buf2);
             buf2 += fsize;
         }
         max_frames = FFMAX(max_frames, frames);
@@ -71,7 +72,7 @@
 
     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codec->codec_id = s->iformat->raw_codec_id;
-    st->need_parsing = AVSTREAM_PARSE_FULL;
+    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
 
     ff_id3v1_read(s);
 
diff --git a/libavformat/ac3dec.c b/libavformat/ac3dec.c
index d3f2ec2..7a34ea8 100644
--- a/libavformat/ac3dec.c
+++ b/libavformat/ac3dec.c
@@ -2,20 +2,20 @@
  * RAW AC-3 and E-AC-3 demuxer
  * Copyright (c) 2007 Justin Ruggles <justin.ruggles@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -37,14 +37,36 @@
     end = buf + p->buf_size;
 
     for(; buf < end; buf++) {
+        if(buf > p->buf && !(buf[0] == 0x0B && buf[1] == 0x77)
+                        && !(buf[0] == 0x77 && buf[1] == 0x0B) )
+            continue;
         buf2 = buf;
 
         for(frames = 0; buf2 < end; frames++) {
-            init_get_bits(&gbc, buf2, 54);
+            uint8_t buf3[4096];
+            int i;
+            if(!memcmp(buf2, "\x1\x10\0\0\0\0\0\0", 8))
+                buf2+=16;
+            if (buf[0] == 0x77 && buf[1] == 0x0B) {
+                for(i=0; i<8; i+=2) {
+                    buf3[i  ] = buf[i+1];
+                    buf3[i+1] = buf[i  ];
+                }
+                init_get_bits(&gbc, buf3, 54);
+            }else
+                init_get_bits(&gbc, buf2, 54);
             if(avpriv_ac3_parse_header(&gbc, &hdr) < 0)
                 break;
-            if(buf2 + hdr.frame_size > end ||
-               av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf2 + 2, hdr.frame_size - 2))
+            if(buf2 + hdr.frame_size > end)
+                break;
+            if (buf[0] == 0x77 && buf[1] == 0x0B) {
+                av_assert0(hdr.frame_size <= sizeof(buf3));
+                for(i=8; i<hdr.frame_size; i+=2) {
+                    buf3[i  ] = buf[i+1];
+                    buf3[i+1] = buf[i  ];
+                }
+            }
+            if(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, gbc.buffer + 2, hdr.frame_size - 2))
                 break;
             if (hdr.bitstream_id > 10)
                 codec_id = AV_CODEC_ID_EAC3;
@@ -57,31 +79,11 @@
     if(codec_id != expected_codec_id) return 0;
     // keep this in sync with mp3 probe, both need to avoid
     // issues with MPEG-files!
-    if (first_frames >= 4) return AVPROBE_SCORE_MAX / 2 + 1;
-
-    if (max_frames) {
-        int pes = 0, i;
-        unsigned int code = -1;
-
-#define VIDEO_ID 0x000001e0
-#define AUDIO_ID 0x000001c0
-        /* do a search for mpegps headers to be able to properly bias
-         * towards mpegps if we detect this stream as both. */
-        for (i = 0; i<p->buf_size; i++) {
-            code = (code << 8) + p->buf[i];
-            if ((code & 0xffffff00) == 0x100) {
-                if     ((code & 0x1f0) == VIDEO_ID) pes++;
-                else if((code & 0x1e0) == AUDIO_ID) pes++;
-            }
-        }
-
-        if (pes)
-            max_frames = (max_frames + pes - 1) / pes;
-    }
-    if      (max_frames >  500) return AVPROBE_SCORE_MAX / 2;
-    else if (max_frames >= 4)   return AVPROBE_SCORE_MAX / 4;
-    else if (max_frames >= 1)   return 1;
-    else                        return 0;
+    if   (first_frames>=4) return AVPROBE_SCORE_MAX/2+1;
+    else if(max_frames>200)return AVPROBE_SCORE_MAX/2;
+    else if(max_frames>=4) return AVPROBE_SCORE_MAX/4;
+    else if(max_frames>=1) return 1;
+    else                   return 0;
 }
 
 #if CONFIG_AC3_DEMUXER
diff --git a/libavformat/act.c b/libavformat/act.c
new file mode 100644
index 0000000..78f1d3b
--- /dev/null
+++ b/libavformat/act.c
@@ -0,0 +1,207 @@
+/*
+ * ACT file format demuxer
+ * Copyright (c) 2007-2008 Vladimir Voroshilov
+ *
+ * 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 "riff.h"
+#include "internal.h"
+#include "libavcodec/get_bits.h"
+
+#define CHUNK_SIZE 512
+#define RIFF_TAG MKTAG('R','I','F','F')
+#define WAVE_TAG MKTAG('W','A','V','E')
+
+typedef struct{
+    int bytes_left_in_chunk;
+    uint8_t audio_buffer[22];///< temporary buffer for ACT frame
+    char second_packet;      ///< 1 - if temporary buffer contains valid (second) G.729 packet
+} ACTContext;
+
+static int probe(AVProbeData *p)
+{
+    int i;
+
+    if ((AV_RL32(&p->buf[0]) != RIFF_TAG) ||
+        (AV_RL32(&p->buf[8]) != WAVE_TAG) ||
+        (AV_RL32(&p->buf[16]) != 16))
+    return 0;
+
+    //We cant be sure that this is ACT and not regular WAV
+    if (p->buf_size<512)
+        return 0;
+
+    for(i=44; i<256; i++)
+        if(p->buf[i])
+            return 0;
+
+    if(p->buf[256]!=0x84)
+        return 0;
+
+    for(i=264; i<512; i++)
+        if(p->buf[i])
+            return 0;
+
+    return AVPROBE_SCORE_MAX;
+}
+
+static int read_header(AVFormatContext *s)
+{
+    ACTContext* ctx = s->priv_data;
+    AVIOContext *pb = s->pb;
+    int size;
+    AVStream* st;
+
+    int min,sec,msec;
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    avio_skip(pb, 16);
+    size=avio_rl32(pb);
+    ff_get_wav_header(pb, st->codec, size);
+
+    /*
+      8000Hz (Fine-rec) file format has 10 bytes long
+      packets with 10ms of sound data in them
+    */
+    if (st->codec->sample_rate != 8000) {
+        av_log(s, AV_LOG_ERROR, "Sample rate %d is not supported.\n", st->codec->sample_rate);
+        return AVERROR_INVALIDDATA;
+    }
+
+    st->codec->frame_size=80;
+    st->codec->channels=1;
+    avpriv_set_pts_info(st, 64, 1, 100);
+
+    st->codec->codec_id=AV_CODEC_ID_G729;
+
+    avio_seek(pb, 257, SEEK_SET);
+    msec=avio_rl16(pb);
+    sec=avio_r8(pb);
+    min=avio_rl32(pb);
+
+    st->duration = av_rescale(1000*(min*60+sec)+msec, st->codec->sample_rate, 1000 * st->codec->frame_size);
+
+    ctx->bytes_left_in_chunk=CHUNK_SIZE;
+
+    avio_seek(pb, 512, SEEK_SET);
+
+    return 0;
+}
+
+
+static int read_packet(AVFormatContext *s,
+                          AVPacket *pkt)
+{
+    ACTContext *ctx = s->priv_data;
+    AVIOContext *pb = s->pb;
+    int ret;
+    int frame_size=s->streams[0]->codec->sample_rate==8000?10:22;
+
+
+    if(s->streams[0]->codec->sample_rate==8000)
+        ret=av_new_packet(pkt, 10);
+    else
+        ret=av_new_packet(pkt, 11);
+
+    if(ret)
+        return ret;
+
+    if(s->streams[0]->codec->sample_rate==4400 && !ctx->second_packet)
+    {
+        ret = avio_read(pb, ctx->audio_buffer, frame_size);
+
+        if(ret<0)
+            return ret;
+        if(ret!=frame_size)
+            return AVERROR(EIO);
+
+        pkt->data[0]=ctx->audio_buffer[11];
+        pkt->data[1]=ctx->audio_buffer[0];
+        pkt->data[2]=ctx->audio_buffer[12];
+        pkt->data[3]=ctx->audio_buffer[1];
+        pkt->data[4]=ctx->audio_buffer[13];
+        pkt->data[5]=ctx->audio_buffer[2];
+        pkt->data[6]=ctx->audio_buffer[14];
+        pkt->data[7]=ctx->audio_buffer[3];
+        pkt->data[8]=ctx->audio_buffer[15];
+        pkt->data[9]=ctx->audio_buffer[4];
+        pkt->data[10]=ctx->audio_buffer[16];
+
+        ctx->second_packet=1;
+    }
+    else if(s->streams[0]->codec->sample_rate==4400 && ctx->second_packet)
+    {
+        pkt->data[0]=ctx->audio_buffer[5];
+        pkt->data[1]=ctx->audio_buffer[17];
+        pkt->data[2]=ctx->audio_buffer[6];
+        pkt->data[3]=ctx->audio_buffer[18];
+        pkt->data[4]=ctx->audio_buffer[7];
+        pkt->data[5]=ctx->audio_buffer[19];
+        pkt->data[6]=ctx->audio_buffer[8];
+        pkt->data[7]=ctx->audio_buffer[20];
+        pkt->data[8]=ctx->audio_buffer[9];
+        pkt->data[9]=ctx->audio_buffer[21];
+        pkt->data[10]=ctx->audio_buffer[10];
+
+        ctx->second_packet=0;
+    }
+    else // 8000 Hz
+    {
+        ret = avio_read(pb, ctx->audio_buffer, frame_size);
+
+        if(ret<0)
+            return ret;
+        if(ret!=frame_size)
+            return AVERROR(EIO);
+
+        pkt->data[0]=ctx->audio_buffer[5];
+        pkt->data[1]=ctx->audio_buffer[0];
+        pkt->data[2]=ctx->audio_buffer[6];
+        pkt->data[3]=ctx->audio_buffer[1];
+        pkt->data[4]=ctx->audio_buffer[7];
+        pkt->data[5]=ctx->audio_buffer[2];
+        pkt->data[6]=ctx->audio_buffer[8];
+        pkt->data[7]=ctx->audio_buffer[3];
+        pkt->data[8]=ctx->audio_buffer[9];
+        pkt->data[9]=ctx->audio_buffer[4];
+    }
+
+    ctx->bytes_left_in_chunk -= frame_size;
+
+    if(ctx->bytes_left_in_chunk < frame_size)
+    {
+        avio_skip(pb, ctx->bytes_left_in_chunk);
+        ctx->bytes_left_in_chunk=CHUNK_SIZE;
+    }
+
+    pkt->duration=1;
+
+    return ret;
+}
+
+AVInputFormat ff_act_demuxer = {
+    .name           = "act",
+    .long_name      = "ACT Voice file format",
+    .priv_data_size = sizeof(ACTContext),
+    .read_probe     = probe,
+    .read_header    = read_header,
+    .read_packet    = read_packet,
+};
diff --git a/libavformat/adtsenc.c b/libavformat/adtsenc.c
index 0c91944..14c72a8 100644
--- a/libavformat/adtsenc.c
+++ b/libavformat/adtsenc.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@smartjog.com>
  *                    Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/aea.c b/libavformat/aea.c
index 4b6bf32..6aa7ae3 100644
--- a/libavformat/aea.c
+++ b/libavformat/aea.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Benjamin Larsson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/aiff.h b/libavformat/aiff.h
index a30e33e..6ece0e0 100644
--- a/libavformat/aiff.h
+++ b/libavformat/aiff.h
@@ -2,20 +2,20 @@
  * AIFF/AIFF-C muxer/demuxer common header
  * Copyright (c) 2006  Patrick Guimond
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c
index 6243bcb..2c2b693 100644
--- a/libavformat/aiffdec.c
+++ b/libavformat/aiffdec.c
@@ -2,29 +2,33 @@
  * AIFF/AIFF-C demuxer
  * Copyright (c) 2006  Patrick Guimond
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/dict.h"
 #include "avformat.h"
 #include "internal.h"
 #include "pcm.h"
 #include "aiff.h"
+#include "isom.h"
+#include "id3v2.h"
+#include "mov_chan.h"
 
 #define AIFF                    0
 #define AIFF_C_VERSION1         0xA2805140
@@ -54,7 +58,7 @@
 {
     int size;
 
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return AVERROR(EIO);
 
     *tag = avio_rl32(pb);
@@ -70,19 +74,20 @@
 static void get_meta(AVFormatContext *s, const char *key, int size)
 {
     uint8_t *str = av_malloc(size+1);
-    int res;
 
-    if (!str) {
-        avio_skip(s->pb, size);
-        return;
-    }
+    if (str) {
+        int res = avio_read(s->pb, str, size);
+        if (res < 0){
+            av_free(str);
+            return;
+        }
+        size += (size&1)-res;
+        str[res] = 0;
+        av_dict_set(&s->metadata, key, str, AV_DICT_DONT_STRDUP_VAL);
+    }else
+        size+= size&1;
 
-    res = avio_read(s->pb, str, size);
-    if (res < 0)
-        return;
-
-    str[res] = 0;
-    av_dict_set(&s->metadata, key, str, AV_DICT_DONT_STRDUP_VAL);
+    avio_skip(s->pb, size);
 }
 
 /* Returns the number of sound data frames or negative on error */
@@ -146,6 +151,7 @@
             codec->block_align = 35;
             break;
         default:
+            aiff->block_duration = 1;
             break;
         }
         if (codec->block_align > 0)
@@ -156,7 +162,7 @@
     /* Block align needs to be computed in all cases, as the definition
      * is specific to applications -> here we use the WAVE format definition */
     if (!codec->block_align)
-        codec->block_align = (codec->bits_per_coded_sample * codec->channels) >> 3;
+        codec->block_align = (av_get_bits_per_sample(codec->codec_id) * codec->channels) >> 3;
 
     if (aiff->block_duration) {
         codec->bit_rate = codec->sample_rate * (codec->block_align << 3) /
@@ -192,6 +198,7 @@
     AVIOContext *pb = s->pb;
     AVStream * st;
     AIFFInputContext *aiff = s->priv_data;
+    ID3v2ExtraMeta *id3v2_extra_meta = NULL;
 
     /* check FORM header */
     filesize = get_tag(pb, &tag);
@@ -228,6 +235,10 @@
             if (offset > 0) // COMM is after SSND
                 goto got_sound;
             break;
+        case MKTAG('I', 'D', '3', ' '):
+            ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
+            ff_id3v2_free_extra_meta(&id3v2_extra_meta);
+            break;
         case MKTAG('F', 'V', 'E', 'R'):     /* Version chunk */
             version = avio_rb32(pb);
             break;
@@ -264,6 +275,12 @@
                 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)
+                st->codec->block_align = AV_RB32(st->codec->extradata+11*4);
+            break;
+        case MKTAG('C','H','A','N'):
+            if(ff_mov_read_chan(s, pb, st, size) < 0)
+                return AVERROR_INVALIDDATA;
             break;
         default: /* Jump */
             if (size & 1)   /* Always even aligned */
@@ -314,6 +331,8 @@
     if (res < 0)
         return res;
 
+    if (size >= st->codec->block_align)
+        pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
     /* Only one stream in an AIFF file */
     pkt->stream_index = 0;
     pkt->duration     = (res / st->codec->block_align) * aiff->block_duration;
diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c
index abcc424..8cdb261 100644
--- a/libavformat/aiffenc.c
+++ b/libavformat/aiffenc.c
@@ -2,20 +2,20 @@
  * AIFF/AIFF-C muxer
  * Copyright (c) 2006  Patrick Guimond
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,6 +24,7 @@
 #include "internal.h"
 #include "aiff.h"
 #include "avio_internal.h"
+#include "isom.h"
 
 typedef struct {
     int64_t form;
@@ -63,6 +64,12 @@
         avio_wb32(pb, 0xA2805140);
     }
 
+    if (enc->channels > 2 && enc->channel_layout) {
+        ffio_wfourcc(pb, "CHAN");
+        avio_wb32(pb, 12);
+        ff_mov_write_chan(pb, enc->channel_layout);
+    }
+
     /* Common chunk */
     ffio_wfourcc(pb, "COMM");
     avio_wb32(pb, aifc ? 24 : 18); /* size */
@@ -91,6 +98,12 @@
         avio_wb16(pb, 0);
     }
 
+    if (enc->codec_tag == MKTAG('Q','D','M','2') && enc->extradata_size) {
+        ffio_wfourcc(pb, "wave");
+        avio_wb32(pb, enc->extradata_size);
+        avio_write(pb, enc->extradata, enc->extradata_size);
+    }
+
     /* Sound data chunk */
     ffio_wfourcc(pb, "SSND");
     aiff->ssnd = avio_tell(pb);         /* Sound chunk size */
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 39daec7..00f11f4 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -2,20 +2,20 @@
  * Register all the formats and protocols
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
@@ -52,6 +52,8 @@
     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);
@@ -70,10 +72,12 @@
     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  (C93, c93);
-    REGISTER_DEMUXER  (CAF, caf);
+    REGISTER_MUXDEMUX (CAF, caf);
     REGISTER_MUXDEMUX (CAVSVIDEO, cavsvideo);
     REGISTER_DEMUXER  (CDG, cdg);
     REGISTER_DEMUXER  (CDXL, cdxl);
@@ -84,11 +88,13 @@
     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);
@@ -99,7 +105,8 @@
     REGISTER_MUXER    (FRAMECRC, framecrc);
     REGISTER_MUXER    (FRAMEMD5, framemd5);
     REGISTER_MUXDEMUX (G722, g722);
-    REGISTER_DEMUXER  (G723_1, g723_1);
+    REGISTER_MUXDEMUX (G723_1, g723_1);
+    REGISTER_DEMUXER  (G729, g729);
     REGISTER_MUXER    (GIF, gif);
     REGISTER_DEMUXER  (GSM, gsm);
     REGISTER_MUXDEMUX (GXF, gxf);
@@ -107,7 +114,9 @@
     REGISTER_MUXDEMUX (H263, h263);
     REGISTER_MUXDEMUX (H264, h264);
     REGISTER_DEMUXER  (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);
@@ -119,14 +128,18 @@
     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  (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);
@@ -162,6 +175,7 @@
     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);
@@ -188,6 +202,7 @@
     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);
@@ -195,7 +210,9 @@
     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();
@@ -203,21 +220,26 @@
 #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);
@@ -232,20 +254,28 @@
     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_DEMUXER  (WTV, wtv);
-    REGISTER_DEMUXER  (WV, wv);
+    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);
 
+    /* external libraries */
+#if CONFIG_LIBMODPLUG
+    REGISTER_DEMUXER  (LIBMODPLUG, libmodplug);
+#endif
     /* protocols */
 #if FF_API_APPLEHTTP_PROTO
     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);
@@ -273,6 +303,7 @@
     REGISTER_PROTOCOL (UDP, udp);
 
     /* external libraries */
+    REGISTER_MUXDEMUX (LIBNUT, libnut);
     REGISTER_PROTOCOL (LIBRTMP, librtmp);
     REGISTER_PROTOCOL (LIBRTMPE, librtmpe);
     REGISTER_PROTOCOL (LIBRTMPS, librtmps);
diff --git a/libavformat/amr.c b/libavformat/amr.c
index cc4842e..36ff9b0 100644
--- a/libavformat/amr.c
+++ b/libavformat/amr.c
@@ -2,20 +2,20 @@
  * amr file format
  * Copyright (c) 2001 ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,7 @@
 Only mono files are supported.
 
 */
+#include "libavutil/avassert.h"
 #include "avformat.h"
 #include "internal.h"
 
@@ -109,7 +110,7 @@
     int read, size = 0, toc, mode;
     int64_t pos = avio_tell(s->pb);
 
-    if (s->pb->eof_reached) {
+    if (url_feof(s->pb)) {
         return AVERROR(EIO);
     }
 
@@ -130,7 +131,7 @@
 
         size = packed_size[mode];
     } else {
-        assert(0);
+        av_assert0(0);
     }
 
     if (!size || av_new_packet(pkt, size))
diff --git a/libavformat/anm.c b/libavformat/anm.c
index c7bc843..69a5dda 100644
--- a/libavformat/anm.c
+++ b/libavformat/anm.c
@@ -2,20 +2,20 @@
  * Deluxe Paint Animation demuxer
  * Copyright (c) 2009 Peter Ross
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -134,18 +134,17 @@
     /* color cycling and palette data */
     st->codec->extradata_size = 16*8 + 4*256;
     st->codec->extradata      = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
-    if (!st->codec->extradata) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
+    if (!st->codec->extradata)
+        return AVERROR(ENOMEM);
+
     ret = avio_read(pb, st->codec->extradata, st->codec->extradata_size);
     if (ret < 0)
-        goto fail;
+        return ret;
 
     /* read page table */
     ret = avio_seek(pb, anm->page_table_offset, SEEK_SET);
     if (ret < 0)
-        goto fail;
+        return ret;
 
     for (i = 0; i < MAX_PAGES; i++) {
         Page *p = &anm->pt[i];
@@ -156,20 +155,15 @@
 
     /* find page of first frame */
     anm->page = find_record(anm, 0);
-    if (anm->page < 0) {
-        ret = anm->page;
-        goto fail;
-    }
+    if (anm->page < 0)
+        return anm->page;
 
     anm->record = -1;
     return 0;
 
 invalid:
     av_log_ask_for_sample(s, NULL);
-    ret = AVERROR_INVALIDDATA;
-
-fail:
-    return ret;
+    return AVERROR_INVALIDDATA;
 }
 
 static int read_packet(AVFormatContext *s,
@@ -180,7 +174,7 @@
     Page *p;
     int tmp, record_size;
 
-    if (s->pb->eof_reached)
+    if (url_feof(s->pb))
         return AVERROR(EIO);
 
     if (anm->page < 0)
diff --git a/libavformat/apc.c b/libavformat/apc.c
index 7ae2423..2ccf794 100644
--- a/libavformat/apc.c
+++ b/libavformat/apc.c
@@ -2,20 +2,20 @@
  * CRYO APC audio format demuxer
  * Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -76,6 +76,7 @@
 {
     if (av_get_packet(s->pb, pkt, MAX_READ_SIZE) <= 0)
         return AVERROR(EIO);
+    pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
     pkt->stream_index = 0;
     return 0;
 }
diff --git a/libavformat/ape.c b/libavformat/ape.c
index d67e684..c4a390b 100644
--- a/libavformat/ape.c
+++ b/libavformat/ape.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>
  *  based upon libdemac from Dave Chapman.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -38,8 +38,6 @@
 #define MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS    16 // has the number of seek elements after the peak level
 #define MAC_FORMAT_FLAG_CREATE_WAV_HEADER    32 // create the wave header on decompression (not stored)
 
-#define MAC_SUBFRAME_SIZE 4608
-
 #define APE_EXTRADATA_SIZE 6
 
 typedef struct {
@@ -278,6 +276,9 @@
             return AVERROR(ENOMEM);
         for (i = 0; i < ape->seektablelength / sizeof(uint32_t); i++)
             ape->seektable[i] = avio_rl32(pb);
+    }else{
+        av_log(s, AV_LOG_ERROR, "Missing seektable\n");
+        return -1;
     }
 
     ape->frames[0].pos     = ape->firstframe;
@@ -332,8 +333,8 @@
 
     st->nb_frames = ape->totalframes;
     st->start_time = 0;
-    st->duration  = total_blocks / MAC_SUBFRAME_SIZE;
-    avpriv_set_pts_info(st, 64, MAC_SUBFRAME_SIZE, ape->samplerate);
+    st->duration  = total_blocks;
+    avpriv_set_pts_info(st, 64, 1, ape->samplerate);
 
     st->codec->extradata = av_malloc(APE_EXTRADATA_SIZE);
     st->codec->extradata_size = APE_EXTRADATA_SIZE;
@@ -345,7 +346,7 @@
     for (i = 0; i < ape->totalframes; i++) {
         ape->frames[i].pts = pts;
         av_add_index_entry(st, ape->frames[i].pos, ape->frames[i].pts, 0, 0, AVINDEX_KEYFRAME);
-        pts += ape->blocksperframe / MAC_SUBFRAME_SIZE;
+        pts += ape->blocksperframe;
     }
 
     /* try to read APE tags */
@@ -364,7 +365,7 @@
     APEContext *ape = s->priv_data;
     uint32_t extra_size = 8;
 
-    if (s->pb->eof_reached)
+    if (url_feof(s->pb))
         return AVERROR_EOF;
     if (ape->currentframe >= ape->totalframes)
         return AVERROR_EOF;
diff --git a/libavformat/apetag.c b/libavformat/apetag.c
index 28a3ff7..bf9918a 100644
--- a/libavformat/apetag.c
+++ b/libavformat/apetag.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>
  *  based upon libdemac from Dave Chapman.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,8 +26,6 @@
 #include "apetag.h"
 #include "internal.h"
 
-#define APE_TAG_VERSION               2000
-#define APE_TAG_FOOTER_BYTES          32
 #define APE_TAG_FLAG_CONTAINS_HEADER  (1 << 31)
 #define APE_TAG_FLAG_IS_HEADER        (1 << 29)
 #define APE_TAG_FLAG_IS_BINARY        (1 << 1)
@@ -128,7 +126,7 @@
     avio_seek(pb, file_size - APE_TAG_FOOTER_BYTES, SEEK_SET);
 
     avio_read(pb, buf, 8);     /* APETAGEX */
-    if (strncmp(buf, "APETAGEX", 8)) {
+    if (strncmp(buf, APE_TAG_PREAMBLE, 8)) {
         return 0;
     }
 
diff --git a/libavformat/apetag.h b/libavformat/apetag.h
index 279972f..0330c89 100644
--- a/libavformat/apetag.h
+++ b/libavformat/apetag.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>
  *  based upon libdemac from Dave Chapman.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,10 @@
 
 #include "avformat.h"
 
+#define APE_TAG_PREAMBLE        "APETAGEX"
+#define APE_TAG_VERSION         2000
+#define APE_TAG_FOOTER_BYTES    32
+
 /**
  * Read and parse an APE tag
  *
@@ -32,4 +36,9 @@
  */
 int64_t ff_ape_parse_tag(AVFormatContext *s);
 
+/**
+ * Write an APEv2 tag
+ */
+void ff_ape_write(AVFormatContext *s);
+
 #endif /* AVFORMAT_APETAG_H */
diff --git a/libavformat/apetagenc.c b/libavformat/apetagenc.c
new file mode 100644
index 0000000..42f5836
--- /dev/null
+++ b/libavformat/apetagenc.c
@@ -0,0 +1,65 @@
+/*
+ * APE tag writer
+ * Copyright (c) 2012 Paul B Mahol
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/dict.h"
+#include "avio_internal.h"
+#include "avformat.h"
+#include "apetag.h"
+
+static int string_is_ascii(const uint8_t *str)
+{
+    while (*str && *str >= 0x20 && *str <= 0x7e ) str++;
+    return !*str;
+}
+
+void ff_ape_write(AVFormatContext *s)
+{
+    int64_t tag_bytes;
+    AVDictionaryEntry *t = NULL;
+    AVIOContext *pb = s->pb;
+    int tags = 0, vlen;
+
+    tag_bytes = avio_tell(s->pb);
+    while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
+        if (!string_is_ascii(t->key)) {
+            av_log(s, AV_LOG_WARNING, "Non ASCII keys are not allowed\n");
+            continue;
+        }
+
+        vlen = strlen(t->value);
+        avio_wl32(pb, vlen + 1);
+        avio_wl32(pb, 0); // flags
+        avio_put_str(pb, t->key);
+        avio_put_str(pb, t->value);
+        tags++;
+    }
+    tag_bytes = avio_tell(s->pb) - tag_bytes;
+
+    if (!tags)
+        return;
+
+    avio_write(pb, APE_TAG_PREAMBLE, 8);
+    avio_wl32(pb, APE_TAG_VERSION);
+    avio_wl32(pb, tag_bytes + APE_TAG_FOOTER_BYTES);
+    avio_wl32(pb, tags); // item count
+    avio_wl32(pb, 0); // global flags
+    ffio_fill(pb, 0, 8); // reserved
+}
diff --git a/libavformat/asf.c b/libavformat/asf.c
index cc2833d..8e360d3 100644
--- a/libavformat/asf.c
+++ b/libavformat/asf.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2000, 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -152,7 +152,6 @@
     { "WM/Publisher"       , "publisher"   },
     { "WM/Tool"            , "encoder"     },
     { "WM/TrackNumber"     , "track"       },
-    { "WM/Track"           , "track"       },
     { "WM/MediaStationCallSign", "service_provider" },
     { "WM/MediaStationName", "service_name" },
 //  { "Year"               , "date"        }, TODO: conversion year<->date
diff --git a/libavformat/asf.h b/libavformat/asf.h
index 1d94a2c..822cd6b 100644
--- a/libavformat/asf.h
+++ b/libavformat/asf.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2000, 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,6 +24,7 @@
 #include <stdint.h>
 #include "avformat.h"
 #include "metadata.h"
+#include "riff.h"
 
 #define PACKET_SIZE 3200
 
@@ -48,8 +49,6 @@
     uint32_t palette[256];
 } ASFStream;
 
-typedef uint8_t ff_asf_guid[16];
-
 typedef struct ASFMainHeader {
     ff_asf_guid guid;                  ///< generated by client computer
     uint64_t file_size;         /**< in bytes
@@ -175,11 +174,6 @@
 
 extern AVInputFormat ff_asf_demuxer;
 
-static av_always_inline int ff_guidcmp(const void *g1, const void *g2)
-{
-    return memcmp(g1, g2, sizeof(ff_asf_guid));
-}
-
-void ff_get_guid(AVIOContext *s, ff_asf_guid *g);
+void ff_put_guid(AVIOContext *s, const ff_asf_guid *g);
 
 #endif /* AVFORMAT_ASF_H */
diff --git a/libavformat/asfcrypt.c b/libavformat/asfcrypt.c
index 6c48a19..6a51c04 100644
--- a/libavformat/asfcrypt.c
+++ b/libavformat/asfcrypt.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2007 Reimar Doeffinger
  * This is a rewrite of code contained in freeme/freeme2
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/asfcrypt.h b/libavformat/asfcrypt.h
index 53388b4..8b80d63 100644
--- a/libavformat/asfcrypt.h
+++ b/libavformat/asfcrypt.h
@@ -2,20 +2,20 @@
  * ASF decryption
  * Copyright (c) 2007 Reimar Doeffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index 5fe8e96..b58cf28 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -2,20 +2,20 @@
  * ASF compatible demuxer
  * Copyright (c) 2000, 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -96,12 +96,8 @@
 #include <assert.h>
 
 #define ASF_MAX_STREAMS 127
-#define FRAME_HEADER_SIZE 17
-// Fix Me! FRAME_HEADER_SIZE may be different.
-
-static const ff_asf_guid index_guid = {
-    0x90, 0x08, 0x00, 0x33, 0xb1, 0xe5, 0xcf, 0x11, 0x89, 0xf4, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb
-};
+#define FRAME_HEADER_SIZE 16
+// Fix Me! FRAME_HEADER_SIZE may be different. (17 is known to be too large)
 
 #ifdef DEBUG
 static const ff_asf_guid stream_bitrate_guid = { /* (http://get.to/sdp) */
@@ -127,7 +123,7 @@
     else PRINT_IF_GUID(g, ff_asf_codec_comment_header);
     else PRINT_IF_GUID(g, ff_asf_codec_comment1_header);
     else PRINT_IF_GUID(g, ff_asf_data_header);
-    else PRINT_IF_GUID(g, index_guid);
+    else PRINT_IF_GUID(g, ff_asf_simple_index_header);
     else PRINT_IF_GUID(g, ff_asf_head1_guid);
     else PRINT_IF_GUID(g, ff_asf_head2_guid);
     else PRINT_IF_GUID(g, ff_asf_my_guid);
@@ -150,12 +146,6 @@
 #define print_guid(g)
 #endif
 
-void ff_get_guid(AVIOContext *s, ff_asf_guid *g)
-{
-    assert(sizeof(*g) == 16);
-    avio_read(s, *g, sizeof(*g));
-}
-
 static int asf_probe(AVProbeData *pd)
 {
     /* check file header */
@@ -284,6 +274,9 @@
 
     if (type == 0) {         // UTF16-LE
         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 && type <= 5) {  // boolean or DWORD or QWORD or WORD
         uint64_t num = get_value(s->pb, type);
         snprintf(value, len, "%"PRIu64, num);
@@ -353,7 +346,6 @@
     if (!asf_st)
         return AVERROR(ENOMEM);
     st->priv_data = asf_st;
-    st->start_time = 0;
     start_time = asf->hdr.preroll;
 
     asf_st->stream_language_index = 128; // invalid stream index means no language info
@@ -412,7 +404,7 @@
         if (is_dvr_ms_audio) {
             // codec_id and codec_tag are unreliable in dvr_ms
             // files. Set them later by probing stream.
-            st->codec->codec_id = AV_CODEC_ID_PROBE;
+            st->request_probe= 1;
             st->codec->codec_tag = 0;
         }
         if (st->codec->codec_id == AV_CODEC_ID_AAC) {
@@ -686,7 +678,7 @@
 
     ff_get_guid(pb, &g);
     if (ff_guidcmp(&g, &ff_asf_header))
-        return -1;
+        return AVERROR_INVALIDDATA;
     avio_rl64(pb);
     avio_rl32(pb);
     avio_r8(pb);
@@ -708,7 +700,7 @@
             break;
         }
         if (gsize < 24)
-            return -1;
+            return AVERROR_INVALIDDATA;
         if (!ff_guidcmp(&g, &ff_asf_file_header)) {
             int ret = asf_read_file_properties(s, gsize);
             if (ret < 0)
@@ -735,16 +727,28 @@
             continue;
         } else if (!ff_guidcmp(&g, &ff_asf_marker_header)) {
             asf_read_marker(s, gsize);
-        } else if (pb->eof_reached) {
-            return -1;
+        } else if (url_feof(pb)) {
+            return AVERROR_EOF;
         } else {
             if (!s->keylen) {
                 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");
+                    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);
+                    len= avio_rl32(pb);
+                    get_tag(s, "ASF_Key_ID", -1, len);
+                    len= avio_rl32(pb);
+                    get_tag(s, "ASF_License_URL", -1, len);
                 } 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_dict_set(&s->metadata, "encryption", "ASF Extended Content Encryption", 0);
                 } else if (!ff_guidcmp(&g, &ff_asf_digital_signature)) {
-                    av_log(s, AV_LOG_WARNING, "Digital signature detected, decoding will likely fail!\n");
+                    av_log(s, AV_LOG_INFO, "Digital signature detected!\n");
                 }
             }
         }
@@ -756,8 +760,8 @@
     avio_rl64(pb);
     avio_r8(pb);
     avio_r8(pb);
-    if (pb->eof_reached)
-        return -1;
+    if (url_feof(pb))
+        return AVERROR_EOF;
     asf->data_offset = avio_tell(pb);
     asf->packet_size_left = 0;
 
@@ -769,12 +773,12 @@
             if (!st->codec->bit_rate)
                 st->codec->bit_rate = asf->stream_bitrates[i];
             if (asf->dar[i].num > 0 && asf->dar[i].den > 0){
-                av_reduce(&st->sample_aspect_ratio.num,
-                          &st->sample_aspect_ratio.den,
+                av_reduce(&st->sample_aspect_ratio.den,
+                          &st->sample_aspect_ratio.num,
                           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.
-                av_reduce(&st->sample_aspect_ratio.num,
-                          &st->sample_aspect_ratio.den,
+                av_reduce(&st->sample_aspect_ratio.den,
+                          &st->sample_aspect_ratio.num,
                           asf->dar[0].num, asf->dar[0].den, INT_MAX);
 
             av_dlog(s, "i=%d, st->codec->codec_type:%d, asf->dar %d:%d sar=%d:%d\n",
@@ -845,19 +849,19 @@
          */
         if (pb->error == AVERROR(EAGAIN))
             return AVERROR(EAGAIN);
-        if (!pb->eof_reached)
+        if (!url_feof(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) {
-            if (!pb->eof_reached)
+            if (!url_feof(pb))
                 av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         c= avio_r8(pb);
         d= avio_r8(pb);
         rsize+=3;
-    } else if (!pb->eof_reached) {
+    }else if(!url_feof(pb)){
         avio_seek(pb, -1, SEEK_CUR); //FIXME
     }
 
@@ -871,11 +875,11 @@
     //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 -1;
+        return AVERROR_INVALIDDATA;
     }
     if(padsize >= packet_length){
         av_log(s, AV_LOG_ERROR, "invalid padsize %d at:%"PRId64"\n", padsize, avio_tell(pb));
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     asf->packet_timestamp = avio_rl32(pb);
@@ -894,7 +898,7 @@
         av_log(s, AV_LOG_ERROR,
                "invalid packet header length %d for pktlen %d-%d at %"PRId64"\n",
                rsize, packet_length, padsize, avio_tell(pb));
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     asf->packet_size_left = packet_length - padsize - rsize;
     if (packet_length < asf->hdr.min_pktsize)
@@ -912,7 +916,7 @@
     ASFContext *asf = s->priv_data;
     int rsize = 1;
     int num = avio_r8(pb);
-    int64_t ts0;
+    int64_t ts0, ts1 av_unused;
 
     asf->packet_segments--;
     asf->packet_key_frame = num >> 7;
@@ -924,17 +928,21 @@
     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) {
+        av_log(s, AV_LOG_ERROR, "packet_replic_size %d is invalid\n", asf->packet_replic_size);
+        return AVERROR_INVALIDDATA;
+    }
     if (asf->packet_replic_size >= 8) {
         asf->packet_obj_size = avio_rl32(pb);
         if(asf->packet_obj_size >= (1<<24) || asf->packet_obj_size <= 0){
             av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         }
         asf->packet_frag_timestamp = avio_rl32(pb); // timestamp
         if(asf->packet_replic_size >= 8+38+4){
             avio_skip(pb, 10);
             ts0= avio_rl64(pb);
-            avio_skip(pb, 8);;
+            ts1= avio_rl64(pb);
             avio_skip(pb, 12);
             avio_rl32(pb);
             avio_skip(pb, asf->packet_replic_size - 8 - 38 - 4);
@@ -953,17 +961,17 @@
         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);
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     if (asf->packet_flags & 0x01) {
         DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0); // 0 is illegal
         if (rsize > asf->packet_size_left) {
             av_log(s, AV_LOG_ERROR, "packet_replic_size is invalid\n");
-            return -1;
+            return AVERROR_INVALIDDATA;
         } 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);
-                return -1;
+                return AVERROR_INVALIDDATA;
             } else {
                 int diff = asf->packet_frag_size - (asf->packet_size_left - rsize);
                 asf->packet_size_left += diff;
@@ -971,16 +979,12 @@
             }
         }
     } else {
-        if (rsize > asf->packet_size_left) {
-            av_log(s, AV_LOG_ERROR, "packet_replic_size is invalid\n");
-            return -1;
-        }
         asf->packet_frag_size = asf->packet_size_left - rsize;
     }
     if (asf->packet_replic_size == 1) {
         asf->packet_multi_size = asf->packet_frag_size;
         if (asf->packet_multi_size > asf->packet_size_left)
-            return -1;
+            return AVERROR_INVALIDDATA;
     }
     asf->packet_size_left -= rsize;
 
@@ -1002,7 +1006,7 @@
     ASFStream *asf_st = 0;
     for (;;) {
         int ret;
-        if(pb->eof_reached)
+        if(url_feof(pb))
             return AVERROR_EOF;
         if (asf->packet_size_left < FRAME_HEADER_SIZE
             || asf->packet_segments < 1) {
@@ -1265,11 +1269,12 @@
     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;
-    avio_seek(s->pb, pos, SEEK_SET);
+    if (avio_seek(s->pb, pos, SEEK_SET) < 0)
+        return AV_NOPTS_VALUE;
 
     asf_reset_header(s);
     for(;;){
-        if (asf_read_packet(s, pkt) < 0){
+        if (av_read_frame(s, pkt) < 0){
             av_log(s, AV_LOG_INFO, "asf_read_pts failed\n");
             return AV_NOPTS_VALUE;
         }
@@ -1302,17 +1307,21 @@
     ff_asf_guid g;
     ASFContext *asf = s->priv_data;
     int64_t current_pos= avio_tell(s->pb);
-    int i;
 
-    avio_seek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET);
+    if(avio_seek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET) < 0) {
+        asf->index_read= -1;
+        return;
+    }
+
     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 */
-    while (ff_guidcmp(&g, &index_guid)) {
+    while (ff_guidcmp(&g, &ff_asf_simple_index_header)) {
         int64_t gsize= avio_rl64(s->pb);
-        if (gsize < 24 || s->pb->eof_reached) {
+        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);
@@ -1322,6 +1331,7 @@
     {
         int64_t itime, last_pos=-1;
         int pct, ict;
+        int i;
         int64_t av_unused gsize= avio_rl64(s->pb);
         ff_get_guid(s->pb, &g);
         itime=avio_rl64(s->pb);
@@ -1341,7 +1351,7 @@
             last_pos=pos;
             }
         }
-        asf->index_read= ict > 0;
+        asf->index_read= ict > 1;
     }
     avio_seek(s->pb, current_pos, SEEK_SET);
 }
@@ -1350,8 +1360,6 @@
 {
     ASFContext *asf = s->priv_data;
     AVStream *st = s->streams[stream_index];
-    int64_t pos;
-    int index;
 
     if (s->packet_size <= 0)
         return -1;
@@ -1368,15 +1376,16 @@
     if (!asf->index_read)
         asf_build_simple_index(s, stream_index);
 
-    if((asf->index_read && st->index_entries)){
-        index= av_index_search_timestamp(st, pts, flags);
+    if((asf->index_read > 0 && st->index_entries)){
+        int index= av_index_search_timestamp(st, pts, flags);
         if(index >= 0) {
             /* find the position */
-            pos = st->index_entries[index].pos;
+            uint64_t pos = st->index_entries[index].pos;
 
             /* do the seek */
             av_log(s, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos);
-            avio_seek(s->pb, pos, SEEK_SET);
+            if(avio_seek(s->pb, pos, SEEK_SET) < 0)
+                return -1;
             asf_reset_header(s);
             return 0;
         }
diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c
index 5c820be..82681d2 100644
--- a/libavformat/asfenc.c
+++ b/libavformat/asfenc.c
@@ -2,20 +2,20 @@
  * ASF muxer
  * Copyright (c) 2000, 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
@@ -30,7 +30,7 @@
 
 
 #define ASF_INDEXED_INTERVAL    10000000
-#define ASF_INDEX_BLOCK         600
+#define ASF_INDEX_BLOCK         (1<<9)
 
 #define ASF_PACKET_ERROR_CORRECTION_DATA_SIZE 0x2
 #define ASF_PACKET_ERROR_CORRECTION_FLAGS (\
@@ -200,31 +200,33 @@
     /* packet filling */
     unsigned char multi_payloads_present;
     int packet_size_left;
-    int packet_timestamp_start;
-    int packet_timestamp_end;
+    int64_t packet_timestamp_start;
+    int64_t packet_timestamp_end;
     unsigned int packet_nb_payloads;
     uint8_t packet_buf[PACKET_SIZE];
     AVIOContext pb;
     /* only for reading */
     uint64_t data_offset;                ///< beginning of the first data packet
 
-    int64_t last_indexed_pts;
     ASFIndex* index_ptr;
-    uint32_t nb_index_count;
     uint32_t nb_index_memory_alloc;
     uint16_t maximum_packet;
+    uint32_t next_packet_number;
+    uint16_t next_packet_count;
+    int      next_start_sec;
+    int      end_sec;
 } ASFContext;
 
 static const AVCodecTag codec_asf_bmp_tags[] = {
-    { 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 },
 };
 
 #define PREROLL_TIME 3100
 
-static void put_guid(AVIOContext *s, const ff_asf_guid *g)
+void ff_put_guid(AVIOContext *s, const ff_asf_guid *g)
 {
     assert(sizeof(*g) == 16);
     avio_write(s, *g, sizeof(*g));
@@ -250,7 +252,7 @@
     int64_t pos;
 
     pos = avio_tell(pb);
-    put_guid(pb, g);
+    ff_put_guid(pb, g);
     avio_wl64(pb, 24);
     return pos;
 }
@@ -331,7 +333,7 @@
         put_chunk(s, 0x4824, 0, 0xc00); /* start of stream (length will be patched later) */
     }
 
-    put_guid(pb, &ff_asf_header);
+    ff_put_guid(pb, &ff_asf_header);
     avio_wl64(pb, -1); /* header length, will be patched after */
     avio_wl32(pb, 3 + has_title + !!metadata_count + s->nb_streams); /* number of chunks in header */
     avio_w8(pb, 1); /* ??? */
@@ -340,7 +342,7 @@
     /* file header */
     header_offset = avio_tell(pb);
     hpos = put_header(pb, &ff_asf_file_header);
-    put_guid(pb, &ff_asf_my_guid);
+    ff_put_guid(pb, &ff_asf_my_guid);
     avio_wl64(pb, file_size);
     file_time = 0;
     avio_wl64(pb, unix_to_file_time(file_time));
@@ -356,7 +358,7 @@
 
     /* unknown headers */
     hpos = put_header(pb, &ff_asf_head1_guid);
-    put_guid(pb, &ff_asf_head2_guid);
+    ff_put_guid(pb, &ff_asf_head2_guid);
     avio_wl32(pb, 6);
     avio_wl16(pb, 0);
     end_header(pb, hpos);
@@ -400,7 +402,7 @@
 
         enc = s->streams[n]->codec;
         asf->streams[n].num = n + 1;
-        asf->streams[n].seq = 0;
+        asf->streams[n].seq = 1;
 
 
         switch(enc->codec_type) {
@@ -419,11 +421,11 @@
 
         hpos = put_header(pb, &ff_asf_stream_header);
         if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
-            put_guid(pb, &ff_asf_audio_stream);
-            put_guid(pb, &ff_asf_audio_conceal_spread);
+            ff_put_guid(pb, &ff_asf_audio_stream);
+            ff_put_guid(pb, &ff_asf_audio_conceal_spread);
         } else {
-            put_guid(pb, &ff_asf_video_stream);
-            put_guid(pb, &ff_asf_video_conceal_none);
+            ff_put_guid(pb, &ff_asf_video_stream);
+            ff_put_guid(pb, &ff_asf_video_conceal_none);
         }
         avio_wl64(pb, 0); /* ??? */
         es_pos = avio_tell(pb);
@@ -470,7 +472,7 @@
     /* media comments */
 
     hpos = put_header(pb, &ff_asf_codec_comment_header);
-    put_guid(pb, &ff_asf_codec_comment1_header);
+    ff_put_guid(pb, &ff_asf_codec_comment1_header);
     avio_wl32(pb, s->nb_streams);
     for(n=0;n<s->nb_streams;n++) {
         AVCodec *p;
@@ -541,9 +543,9 @@
 
     /* movie chunk, followed by packets of packet_size */
     asf->data_offset = cur_pos;
-    put_guid(pb, &ff_asf_data_header);
+    ff_put_guid(pb, &ff_asf_data_header);
     avio_wl64(pb, data_chunk_size);
-    put_guid(pb, &ff_asf_my_guid);
+    ff_put_guid(pb, &ff_asf_my_guid);
     avio_wl64(pb, asf->nb_packets); /* nb packets */
     avio_w8(pb, 1); /* ??? */
     avio_w8(pb, 1); /* ??? */
@@ -557,10 +559,8 @@
     s->packet_size  = PACKET_SIZE;
     asf->nb_packets = 0;
 
-    asf->last_indexed_pts = 0;
     asf->index_ptr = av_malloc( sizeof(ASFIndex) * ASF_INDEX_BLOCK );
     asf->nb_index_memory_alloc = ASF_INDEX_BLOCK;
-    asf->nb_index_count = 0;
     asf->maximum_packet = 0;
 
     /* the data-chunk-size has to be 50, which is data_size - asf->data_offset
@@ -579,6 +579,9 @@
     ffio_init_context(&asf->pb, asf->packet_buf, s->packet_size, 1,
                   NULL, NULL, NULL, NULL);
 
+    if (s->avoid_negative_ts < 0)
+        s->avoid_negative_ts = 1;
+
     return 0;
 }
 
@@ -681,7 +684,7 @@
 static void put_payload_header(
                                 AVFormatContext *s,
                                 ASFStream       *stream,
-                                int             presentation_time,
+                                int64_t         presentation_time,
                                 int             m_obj_size,
                                 int             m_obj_offset,
                                 int             payload_len,
@@ -708,7 +711,7 @@
     avio_w8(pb, ASF_PAYLOAD_REPLICATED_DATA_LENGTH);
 
     avio_wl32(pb, m_obj_size);       //Replicated Data - Media Object Size
-    avio_wl32(pb, presentation_time);//Replicated Data - Presentation Time
+    avio_wl32(pb, (uint32_t) presentation_time);//Replicated Data - Presentation Time
 
     if (asf->multi_payloads_present){
         avio_wl16(pb, payload_len);   //payload length
@@ -719,7 +722,7 @@
                     AVFormatContext *s,
                     ASFStream       *stream,
                     AVStream        *avst,
-                    int             timestamp,
+                    int64_t         timestamp,
                     const uint8_t   *buf,
                     int             m_obj_size,
                     int             flags
@@ -782,14 +785,42 @@
     stream->seq++;
 }
 
+static void update_index(AVFormatContext *s, int start_sec,
+                         uint32_t packet_number, uint16_t packet_count)
+{
+    ASFContext *asf = s->priv_data;
+
+    if (start_sec > asf->next_start_sec) {
+        int i;
+
+        if (!asf->next_start_sec) {
+            asf->next_packet_number = packet_number;
+            asf->next_packet_count  = packet_count;
+        }
+
+        if (start_sec > asf->nb_index_memory_alloc) {
+            asf->nb_index_memory_alloc = (start_sec + ASF_INDEX_BLOCK) & ~(ASF_INDEX_BLOCK - 1);
+            asf->index_ptr = av_realloc( asf->index_ptr, sizeof(ASFIndex) * asf->nb_index_memory_alloc );
+        }
+        for (i = asf->next_start_sec; i < start_sec; i++) {
+            asf->index_ptr[i].packet_number = asf->next_packet_number;
+            asf->index_ptr[i].packet_count  = asf->next_packet_count;
+        }
+    }
+    asf->maximum_packet     = FFMAX(asf->maximum_packet, packet_count);
+    asf->next_packet_number = packet_number;
+    asf->next_packet_count  = packet_count;
+    asf->next_start_sec     = start_sec;
+}
+
 static int asf_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     ASFContext *asf = s->priv_data;
     ASFStream *stream;
-    int64_t duration;
     AVCodecContext *codec;
-    int64_t packet_st,pts;
-    int start_sec,i;
+    uint32_t packet_number;
+    int64_t pts;
+    int start_sec;
     int flags= pkt->flags;
 
     codec = s->streams[pkt->stream_index]->codec;
@@ -800,30 +831,22 @@
 
     pts = (pkt->pts != AV_NOPTS_VALUE) ? pkt->pts : pkt->dts;
     assert(pts != AV_NOPTS_VALUE);
-    duration = pts * 10000;
-    asf->duration= FFMAX(asf->duration, duration + pkt->duration * 10000);
+    pts *= 10000;
+    asf->duration= FFMAX(asf->duration, pts + pkt->duration * 10000);
 
-    packet_st = asf->nb_packets;
+    packet_number = asf->nb_packets;
     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);
+
     /* check index */
     if ((!asf->is_streamed) && (flags & AV_PKT_FLAG_KEY)) {
-        start_sec = (int)(duration / INT64_C(10000000));
-        if (start_sec != (int)(asf->last_indexed_pts / INT64_C(10000000))) {
-            for(i=asf->nb_index_count;i<start_sec;i++) {
-                if (i>=asf->nb_index_memory_alloc) {
-                    asf->nb_index_memory_alloc += ASF_INDEX_BLOCK;
-                    asf->index_ptr = (ASFIndex*)av_realloc( asf->index_ptr, sizeof(ASFIndex) * asf->nb_index_memory_alloc );
-                }
-                // store
-                asf->index_ptr[i].packet_number = (uint32_t)packet_st;
-                asf->index_ptr[i].packet_count  = (uint16_t)(asf->nb_packets-packet_st);
-                asf->maximum_packet = FFMAX(asf->maximum_packet, (uint16_t)(asf->nb_packets-packet_st));
-            }
-            asf->nb_index_count = start_sec;
-            asf->last_indexed_pts = duration;
-        }
+        uint16_t packet_count = asf->nb_packets - packet_number;
+        update_index(s, start_sec, packet_number, packet_count);
     }
+    asf->end_sec = start_sec;
+
     return 0;
 }
 
@@ -833,9 +856,9 @@
     AVIOContext *pb = s->pb;
     int i;
 
-    put_guid(pb, &ff_asf_simple_index_header);
+    ff_put_guid(pb, &ff_asf_simple_index_header);
     avio_wl64(pb, 24 + 16 + 8 + 4 + 4 + (4 + 2)*count);
-    put_guid(pb, &ff_asf_my_guid);
+    ff_put_guid(pb, &ff_asf_my_guid);
     avio_wl64(pb, ASF_INDEXED_INTERVAL);
     avio_wl32(pb, max);
     avio_wl32(pb, count);
@@ -858,8 +881,9 @@
 
     /* write index */
     data_size = avio_tell(s->pb);
-    if ((!asf->is_streamed) && (asf->nb_index_count != 0)) {
-        asf_write_index(s, asf->index_ptr, asf->maximum_packet, asf->nb_index_count);
+    if (!asf->is_streamed && asf->next_start_sec) {
+        update_index(s, asf->end_sec + 1, 0, 0);
+        asf_write_index(s, asf->index_ptr, asf->maximum_packet, asf->next_start_sec);
     }
     avio_flush(s->pb);
 
@@ -883,7 +907,7 @@
     .mime_type      = "video/x-ms-asf",
     .extensions     = "asf,wmv,wma",
     .priv_data_size = sizeof(ASFContext),
-    .audio_codec    = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_MP2,
+    .audio_codec    = AV_CODEC_ID_WMAV2,
     .video_codec    = AV_CODEC_ID_MSMPEG4V3,
     .write_header   = asf_write_header,
     .write_packet   = asf_write_packet,
@@ -902,7 +926,7 @@
     .mime_type      = "video/x-ms-asf",
     .extensions     = "asf,wmv,wma",
     .priv_data_size = sizeof(ASFContext),
-    .audio_codec    = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_MP2,
+    .audio_codec    = AV_CODEC_ID_WMAV2,
     .video_codec    = AV_CODEC_ID_MSMPEG4V3,
     .write_header   = asf_write_stream_header,
     .write_packet   = asf_write_packet,
diff --git a/libavformat/assdec.c b/libavformat/assdec.c
index 3d39845..835fd8a 100644
--- a/libavformat/assdec.c
+++ b/libavformat/assdec.c
@@ -2,20 +2,20 @@
  * SSA/ASS demuxer
  * Copyright (c) 2008 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -93,7 +93,7 @@
     header_remaining= INT_MAX;
     dst[0] = &st->codec->extradata;
     dst[1] = &ass->event_buffer;
-    while(!pb->eof_reached){
+    while(!url_feof(pb)){
         uint8_t line[MAX_LINESIZE];
 
         len = ff_get_line(pb, line, sizeof(line));
@@ -147,7 +147,7 @@
     uint8_t *p, *end;
 
     if(ass->event_index >= ass->event_count)
-        return AVERROR(EIO);
+        return AVERROR_EOF;
 
     p= ass->event[ ass->event_index ];
 
diff --git a/libavformat/assenc.c b/libavformat/assenc.c
index 5bf2e20..6b98886 100644
--- a/libavformat/assenc.c
+++ b/libavformat/assenc.c
@@ -2,20 +2,20 @@
  * SSA/ASS muxer
  * Copyright (c) 2008 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/au.c b/libavformat/au.c
index e09d7ac..788e261 100644
--- a/libavformat/au.c
+++ b/libavformat/au.c
@@ -2,20 +2,20 @@
  * AU muxer and demuxer
  * Copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -120,7 +120,7 @@
 /* au input */
 static int au_read_header(AVFormatContext *s)
 {
-    int size;
+    int size, bps, data_size = 0;
     unsigned int tag;
     AVIOContext *pb = s->pb;
     unsigned int id, channels, rate;
@@ -132,7 +132,12 @@
     if (tag != MKTAG('.', 's', 'n', 'd'))
         return -1;
     size = avio_rb32(pb); /* header size */
-    avio_rb32(pb); /* data size */
+    data_size = avio_rb32(pb); /* data size in bytes */
+
+    if (data_size < 0 && data_size != AU_UNKNOWN_SIZE) {
+        av_log(s, AV_LOG_ERROR, "Invalid negative data size '%d' found\n", data_size);
+        return AVERROR_INVALIDDATA;
+    }
 
     id = avio_rb32(pb);
     rate = avio_rb32(pb);
@@ -140,7 +145,7 @@
 
     codec = ff_codec_get_id(codec_au_tags, id);
 
-    if (!av_get_bits_per_sample(codec)) {
+    if (!(bps = av_get_bits_per_sample(codec))) {
         av_log_ask_for_sample(s, "could not determine bits per sample\n");
         return AVERROR_INVALIDDATA;
     }
@@ -164,6 +169,8 @@
     st->codec->codec_id = codec;
     st->codec->channels = channels;
     st->codec->sample_rate = rate;
+    if (data_size != AU_UNKNOWN_SIZE)
+    st->duration = (((int64_t)data_size)<<3) / (st->codec->channels * (int64_t)bps);
     avpriv_set_pts_info(st, 64, 1, rate);
     return 0;
 }
@@ -174,17 +181,17 @@
                           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 *
-                       av_get_bits_per_sample(s->streams[0]->codec->codec_id) >> 3);
+                       bpcs >> 3);
     if (ret < 0)
         return ret;
+    pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
     pkt->stream_index = 0;
-
-    /* note: we need to modify the packet size here to handle the last
-       packet */
-    pkt->size = ret;
     return 0;
 }
 
diff --git a/libavformat/audiointerleave.c b/libavformat/audiointerleave.c
index e48f826..609a511 100644
--- a/libavformat/audiointerleave.c
+++ b/libavformat/audiointerleave.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -47,6 +47,10 @@
     if (!samples_per_frame)
         return -1;
 
+    if (!time_base.num) {
+        av_log(s, AV_LOG_ERROR, "timebase not set for audio interleave\n");
+        return -1;
+    }
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
         AudioInterleaveContext *aic = st->priv_data;
@@ -113,10 +117,13 @@
             }
             av_fifo_generic_write(aic->fifo, pkt->data, pkt->size, NULL);
         } else {
+            int ret;
             // rewrite pts and dts to be decoded time line position
             pkt->pts = pkt->dts = aic->dts;
             aic->dts += pkt->duration;
-            ff_interleave_add_packet(s, pkt, compare_ts);
+            ret = ff_interleave_add_packet(s, pkt, compare_ts);
+            if (ret < 0)
+                return ret;
         }
         pkt = NULL;
     }
@@ -125,8 +132,12 @@
         AVStream *st = s->streams[i];
         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
             AVPacket new_pkt;
-            while (ff_interleave_new_audio_packet(s, &new_pkt, i, flush))
-                ff_interleave_add_packet(s, &new_pkt, compare_ts);
+            int ret;
+            while (ff_interleave_new_audio_packet(s, &new_pkt, i, flush)) {
+                ret = ff_interleave_add_packet(s, &new_pkt, compare_ts);
+                if (ret < 0)
+                    return ret;
+            }
         }
     }
 
diff --git a/libavformat/audiointerleave.h b/libavformat/audiointerleave.h
index 9c7b548..4d77832 100644
--- a/libavformat/audiointerleave.h
+++ b/libavformat/audiointerleave.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/avc.c b/libavformat/avc.c
index 2fd5ac8..f5c513b 100644
--- a/libavformat/avc.c
+++ b/libavformat/avc.c
@@ -2,20 +2,20 @@
  * AVC helper functions for muxers
  * Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@smartjog.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/avc.h b/libavformat/avc.h
index 579756e..972e19b 100644
--- a/libavformat/avc.h
+++ b/libavformat/avc.h
@@ -2,20 +2,20 @@
  * AVC helper functions for muxers
  * Copyright (c) 2008 Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index f9f39a6..ccbbf42 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -50,7 +50,7 @@
  *
  * Main lavf structure used for both muxing and demuxing is AVFormatContext,
  * which exports all information about the file being read or written. As with
- * most Libav structures, its size is not part of public ABI, so it cannot be
+ * most Libavformat structures, its size is not part of public ABI, so it cannot be
  * allocated on stack or directly with av_malloc(). To create an
  * AVFormatContext, use avformat_alloc_context() (some functions, like
  * avformat_open_input() might do that for you).
@@ -218,7 +218,7 @@
  *
  * Metadata is exported or set as pairs of key/value strings in the 'metadata'
  * fields of the AVFormatContext, AVStream, AVChapter and AVProgram structs
- * using the @ref lavu_dict "AVDictionary" API. Like all strings in Libav,
+ * using the @ref lavu_dict "AVDictionary" API. Like all strings in FFmpeg,
  * metadata is assumed to be UTF-8 encoded Unicode. Note that metadata
  * exported by demuxers isn't checked to be valid UTF-8 in most cases.
  *
@@ -336,6 +336,7 @@
 } AVProbeData;
 
 #define AVPROBE_SCORE_MAX 100               ///< maximum score, half of that is used for file-extension-based detection
+#define AVPROBE_SCORE_RETRY (AVPROBE_SCORE_MAX/4)
 #define AVPROBE_PADDING_SIZE 32             ///< extra allocated bytes at the end of the probe buffer
 
 /// Demuxer will use avio_open, no opened file should be provided by the caller.
@@ -355,10 +356,17 @@
 #define AVFMT_NOGENSEARCH   0x4000 /**< Format does not allow to fallback to generic search */
 #define AVFMT_NO_BYTE_SEEK  0x8000 /**< Format does not allow seeking by bytes */
 #define AVFMT_ALLOW_FLUSH  0x10000 /**< Format allows flushing. If not set, the muxer will not receive a NULL packet in the write_packet function. */
-#define AVFMT_TS_NONSTRICT 0x20000 /**< Format does not require strictly
+#if LIBAVFORMAT_VERSION_MAJOR <= 54
+#define AVFMT_TS_NONSTRICT 0x8020000 //we try to be compatible to the ABIs of ffmpeg and major forks
+#else
+#define AVFMT_TS_NONSTRICT 0x20000
+#endif
+                                   /**< Format does not require strictly
                                         increasing timestamps, but they must
                                         still be monotonic */
 
+#define AVFMT_SEEK_TO_PTS   0x4000000 /**< Seeking is based on PTS */
+
 /**
  * @addtogroup lavf_encoding
  * @{
@@ -427,8 +435,12 @@
      *
      * @return 1 if the codec is supported, 0 if it is not.
      *         A negative number if unknown.
+     *         MKTAG('A', 'P', 'I', 'C') if the codec is only supported as AV_DISPOSITION_ATTACHED_PIC
      */
     int (*query_codec)(enum AVCodecID id, int std_compliance);
+
+    void (*get_output_timestamp)(struct AVFormatContext *s, int stream,
+                                 int64_t *dts, int64_t *wall);
 } AVOutputFormat;
 /**
  * @}
@@ -455,7 +467,7 @@
     /**
      * Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS,
      * AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH,
-     * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK.
+     * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS.
      */
     int flags;
 
@@ -568,11 +580,19 @@
     AVSTREAM_PARSE_HEADERS,    /**< Only parse headers, do not repack. */
     AVSTREAM_PARSE_TIMESTAMPS, /**< full parsing and interpolation of timestamps for frames not starting on a packet boundary */
     AVSTREAM_PARSE_FULL_ONCE,  /**< full parsing and repack of the first frame only, only implemented for H.264 currently */
+    AVSTREAM_PARSE_FULL_RAW=MKTAG(0,'R','A','W'),       /**< full parsing and repack with timestamp and position generation by parser for raw
+                                                             this assumes that each packet in the file contains no demuxer level headers and
+                                                             just codec level data, otherwise position generation would fail */
 };
 
 typedef struct AVIndexEntry {
     int64_t pos;
-    int64_t timestamp;
+    int64_t timestamp;        /**<
+                               * Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are available
+                               * when seeking to this entry. That means preferable PTS on keyframe based formats.
+                               * But demuxers can choose to store a different timestamp, if it is more convenient for the implementation or nothing better
+                               * is known
+                               */
 #define AVINDEX_KEYFRAME 0x0001
     int flags:2;
     int size:30; //Yeah, trying to keep the size of this small to reduce memory requirements (it is 24 vs. 32 bytes due to possible 8-byte alignment).
@@ -660,10 +680,12 @@
     AVRational time_base;
 
     /**
-     * Decoding: pts of the first frame of the stream, in stream time base.
+     * Decoding: pts of the first frame of the stream in presentation order, in stream time base.
      * Only set this if you are absolutely 100% sure that the value you set
      * it to really is the pts of the first frame.
      * This may be undefined (AV_NOPTS_VALUE).
+     * @note The ASF header does NOT contain a correct start_time the ASF
+     * demuxer must NOT set this.
      */
     int64_t start_time;
 
@@ -714,15 +736,13 @@
     /**
      * Stream information used internally by av_find_stream_info()
      */
-#define MAX_STD_TIMEBASES (60*12+5)
+#define MAX_STD_TIMEBASES (60*12+6)
     struct {
-#if FF_API_R_FRAME_RATE
         int64_t last_dts;
         int64_t duration_gcd;
         int duration_count;
-        double duration_error[MAX_STD_TIMEBASES];
-#endif
-        int nb_decoded_frames;
+        double duration_error[2][2][MAX_STD_TIMEBASES];
+        int64_t codec_info_duration;
         int found_decoder;
 
         /**
@@ -762,6 +782,16 @@
      */
     int codec_info_nb_frames;
 
+    /**
+     * Stream Identifier
+     * This is the MPEG-TS stream identifier +1
+     * 0 means unknown
+     */
+    int stream_identifier;
+
+    int64_t interleaver_chunk_size;
+    int64_t interleaver_chunk_duration;
+
     /* av_read_frame() support */
     enum AVStreamParseType need_parsing;
     struct AVCodecParserContext *parser;
@@ -778,6 +808,38 @@
                                     support seeking natively. */
     int nb_index_entries;
     unsigned int index_entries_allocated_size;
+
+    /**
+     * stream probing state
+     * -1   -> probing finished
+     *  0   -> no probing requested
+     * rest -> perform probing with request_probe being the minimum score to accept.
+     * NOT PART OF PUBLIC API
+     */
+    int request_probe;
+    /**
+     * Indicates that everything up to the next keyframe
+     * should be discarded.
+     */
+    int skip_to_keyframe;
+
+    /**
+     * Number of samples to skip at the start of the frame decoded from the next packet.
+     */
+    int skip_samples;
+
+    /**
+     * 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.
+     */
+    int nb_decoded_frames;
+
+    /**
+     * Timestamp offset added to timestamps before muxing
+     * NOT PART OF PUBLIC API
+     */
+    int64_t mux_ts_offset;
+
 } AVStream;
 
 #define AV_PROGRAM_RUNNING 1
@@ -795,6 +857,10 @@
     unsigned int   *stream_index;
     unsigned int   nb_stream_indexes;
     AVDictionary *metadata;
+
+    int program_num;
+    int pmt_pid;
+    int pcr_pid;
 } AVProgram;
 
 #define AVFMTCTX_NOHEADER      0x0001 /**< signal that no header is present
@@ -807,6 +873,17 @@
     AVDictionary *metadata;
 } AVChapter;
 
+
+/**
+ * The duration of a video can be estimated through various ways, and this enum can be used
+ * to know how the duration was estimated.
+ */
+enum AVDurationEstimationMethod {
+    AVFMT_DURATION_FROM_PTS,    ///< Duration accurately estimated from PTSes
+    AVFMT_DURATION_FROM_STREAM, ///< Duration estimated from a stream with a known duration
+    AVFMT_DURATION_FROM_BITRATE ///< Duration estimated from bitrate (less accurate)
+};
+
 /**
  * Format I/O context.
  * New fields can be added to the end with minor version bumps.
@@ -885,7 +962,7 @@
     /**
      * Decoding: total stream bitrate in bit/s, 0 if not
      * available. Never set it directly if the file_size and the
-     * duration are known as Libav can compute it automatically.
+     * duration are known as FFmpeg can compute it automatically.
      */
     int bit_rate;
 
@@ -902,6 +979,10 @@
 #define AVFMT_FLAG_NOBUFFER     0x0040 ///< Do not buffer frames when possible
 #define AVFMT_FLAG_CUSTOM_IO    0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it.
 #define AVFMT_FLAG_DISCARD_CORRUPT  0x0100 ///< Discard frames marked corrupted
+#define AVFMT_FLAG_MP4A_LATM    0x8000 ///< Enable RTP MP4A-LATM payload
+#define AVFMT_FLAG_SORT_DTS    0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down)
+#define AVFMT_FLAG_PRIV_OPT    0x20000 ///< Enable use of private options by delaying codec open (this could be made default once all code is converted)
+#define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Don't merge side data but keep it separate.
 
     /**
      * decoding: size of data to probe; encoding: unused.
@@ -999,6 +1080,71 @@
      */
     int debug;
 #define FF_FDEBUG_TS        0x0001
+
+    /**
+     * Transport stream id.
+     * This will be moved into demuxer private options. Thus no API/ABI compatibility
+     */
+    int ts_id;
+
+    /**
+     * Audio preload in microseconds.
+     * Note, not all formats support this and unpredictable things may happen if it is used when not supported.
+     * - encoding: Set by user via AVOptions (NO direct access)
+     * - decoding: unused
+     */
+    int audio_preload;
+
+    /**
+     * Max chunk time in microseconds.
+     * Note, not all formats support this and unpredictable things may happen if it is used when not supported.
+     * - encoding: Set by user via AVOptions (NO direct access)
+     * - decoding: unused
+     */
+    int max_chunk_duration;
+
+    /**
+     * Max chunk size in bytes
+     * Note, not all formats support this and unpredictable things may happen if it is used when not supported.
+     * - encoding: Set by user via AVOptions (NO direct access)
+     * - decoding: unused
+     */
+    int max_chunk_size;
+
+    /**
+     * forces the use of wallclock timestamps as pts/dts of packets
+     * This has undefined results in the presence of B frames.
+     * - encoding: unused
+     * - decoding: Set by user via AVOptions (NO direct access)
+     */
+    int use_wallclock_as_timestamps;
+
+    /**
+     * Avoids negative timestamps during muxing
+     *  0 -> allow negative timestamps
+     *  1 -> avoid negative timestamps
+     * -1 -> choose automatically (default)
+     * Note, this is only works when interleave_packet_per_dts is in use
+     * - encoding: Set by user via AVOptions (NO direct access)
+     * - decoding: unused
+     */
+    int avoid_negative_ts;
+
+    /**
+     * avio flags, used to force AVIO_FLAG_DIRECT.
+     * - encoding: unused
+     * - decoding: Set by user via AVOptions (NO direct access)
+     */
+    int avio_flags;
+
+    /**
+     * The duration field can be estimated through various ways, and this field can be used
+     * to know how the duration was estimated.
+     * - encoding: unused
+     * - decoding: Read by user via AVOptions (NO direct access)
+     */
+    enum AVDurationEstimationMethod duration_estimation_method;
+
     /*****************************************************************
      * 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
@@ -1038,6 +1184,13 @@
     int raw_packet_buffer_remaining_size;
 } AVFormatContext;
 
+/**
+ * Returns the method used to set ctx->duration.
+ *
+ * @return AVFMT_DURATION_FROM_PTS, AVFMT_DURATION_FROM_STREAM, or AVFMT_DURATION_FROM_BITRATE.
+ */
+enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method(const AVFormatContext* ctx);
+
 typedef struct AVPacketList {
     AVPacket pkt;
     struct AVPacketList *next;
@@ -1156,6 +1309,41 @@
  */
 
 
+#if FF_API_PKT_DUMP
+attribute_deprecated void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload);
+attribute_deprecated void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt,
+                                          int dump_payload);
+#endif
+
+#if FF_API_ALLOC_OUTPUT_CONTEXT
+/**
+ * @deprecated deprecated in favor of avformat_alloc_output_context2()
+ */
+attribute_deprecated
+AVFormatContext *avformat_alloc_output_context(const char *format,
+                                               AVOutputFormat *oformat,
+                                               const char *filename);
+#endif
+
+/**
+ * Allocate an AVFormatContext for an output format.
+ * avformat_free_context() can be used to free the context and
+ * everything allocated by the framework within it.
+ *
+ * @param *ctx is set to the created format context, or to NULL in
+ * case of failure
+ * @param oformat format to use for allocating the context, if NULL
+ * format_name and filename are used instead
+ * @param format_name the name of output format to use for allocating the
+ * context, if NULL filename is used instead
+ * @param filename the name of the filename to use for allocating the
+ * context, may be NULL
+ * @return >= 0 in case of success, a negative AVERROR code in case of
+ * failure
+ */
+int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat,
+                                   const char *format_name, const char *filename);
+
 /**
  * @addtogroup lavf_decoding
  * @{
@@ -1188,6 +1376,15 @@
 AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max);
 
 /**
+ * Guess the file format.
+ *
+ * @param is_opened Whether the file is already opened; determines whether
+ *                  demuxers with or without AVFMT_NOFILE are probed.
+ * @param score_ret The score of the best detection.
+ */
+AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score_ret);
+
+/**
  * Probe a bytestream to determine the input format. Each time a probe returns
  * with a score that is too low, the probe buffer size is increased and another
  * attempt is made. When the maximum probe size is reached, the input format
@@ -1227,6 +1424,29 @@
  */
 int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);
 
+attribute_deprecated
+int av_demuxer_open(AVFormatContext *ic);
+
+#if FF_API_FORMAT_PARAMETERS
+/**
+ * Read packets of a media file to get stream information. This
+ * is useful for file formats with no headers such as MPEG. This
+ * function also computes the real framerate in case of MPEG-2 repeat
+ * frame mode.
+ * The logical file position is not changed by this function;
+ * examined packets may be buffered for later processing.
+ *
+ * @param ic media file handle
+ * @return >=0 if OK, AVERROR_xxx on error
+ * @todo Let the user decide somehow what information is needed so that
+ *       we do not waste time getting stuff the user does not need.
+ *
+ * @deprecated use avformat_find_stream_info.
+ */
+attribute_deprecated
+int av_find_stream_info(AVFormatContext *ic);
+#endif
+
 /**
  * Read packets of a media file to get stream information. This
  * is useful for file formats with no headers such as MPEG. This
@@ -1251,6 +1471,18 @@
 int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
 
 /**
+ * Find the programs which belong to a given stream.
+ *
+ * @param ic    media file handle
+ * @param last  the last found program, the search will start after this
+ *              program, or from the beginning if it is NULL
+ * @param s     stream index
+ * @return the next program which belongs to s, NULL if no program is found or
+ *         the last program is not among the programs of ic.
+ */
+AVProgram *av_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int s);
+
+/**
  * Find the "best" stream in the file.
  * The best stream is determined according to various heuristics as the most
  * likely to be what the user expects.
@@ -1400,6 +1632,30 @@
  * @}
  */
 
+#if FF_API_NEW_STREAM
+/**
+ * Add a new stream to a media file.
+ *
+ * Can only be called in the read_header() function. If the flag
+ * AVFMTCTX_NOHEADER is in the format context, then new streams
+ * can be added in read_packet too.
+ *
+ * @param s media file handle
+ * @param id file-format-dependent stream ID
+ */
+attribute_deprecated
+AVStream *av_new_stream(AVFormatContext *s, int id);
+#endif
+
+#if FF_API_SET_PTS_INFO
+/**
+ * @deprecated this function is not supposed to be called outside of lavf
+ */
+attribute_deprecated
+void av_set_pts_info(AVStream *s, int pts_wrap_bits,
+                     unsigned int pts_num, unsigned int pts_den);
+#endif
+
 #define AVSEEK_FLAG_BACKWARD 1 ///< seek backward
 #define AVSEEK_FLAG_BYTE     2 ///< seeking based on position in bytes
 #define AVSEEK_FLAG_ANY      4 ///< seek to any frame, even non-keyframes
@@ -1517,6 +1773,25 @@
                             enum AVMediaType type);
 
 /**
+ * Get timing information for the data currently output.
+ * The exact meaning of "currently output" depends on the format.
+ * It is mostly relevant for devices that have an internal buffer and/or
+ * work in real time.
+ * @param s          media file handle
+ * @param stream     stream in the media file
+ * @param dts[out]   DTS of the last packet output for the stream, in stream
+ *                   time_base units
+ * @param wall[out]  absolute time when that packet whas output,
+ *                   in microsecond
+ * @return  0 if OK, AVERROR(ENOSYS) if the format does not support it
+ * Note: some formats or devices may not allow to measure dts and wall
+ * atomically.
+ */
+int av_get_output_timestamp(struct AVFormatContext *s, int stream,
+                            int64_t *dts, int64_t *wall);
+
+
+/**
  * @}
  */
 
@@ -1526,7 +1801,7 @@
  * @ingroup libavf
  * @{
  *
- * Miscelaneous utility functions related to both muxing and demuxing
+ * Miscellaneous utility functions related to both muxing and demuxing
  * (or neither).
  */
 
@@ -1729,11 +2004,50 @@
  * @return the table mapping RIFF FourCCs for audio to AVCodecID.
  */
 const struct AVCodecTag *avformat_get_riff_audio_tags(void);
+
 /**
  * @}
  */
 
 /**
+ * Guess the sample aspect ratio of a frame, based on both the stream and the
+ * frame aspect ratio.
+ *
+ * Since the frame aspect ratio is set by the codec but the stream aspect ratio
+ * is set by the demuxer, these two may not be equal. This function tries to
+ * return the value that you should use if you would like to display the frame.
+ *
+ * Basic logic is to use the stream aspect ratio if it is set to something sane
+ * otherwise use the frame aspect ratio. This way a container setting, which is
+ * usually easy to modify can override the coded value in the frames.
+ *
+ * @param format the format context which the stream is part of
+ * @param stream the stream which the frame is part of
+ * @param frame the frame with the aspect ratio to be determined
+ * @return the guessed (valid) sample_aspect_ratio, 0/1 if no idea
+ */
+AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame);
+
+/**
+ * Check if the stream st contained in s is matched by the stream specifier
+ * spec.
+ *
+ * See the "stream specifiers" chapter in the documentation for the syntax
+ * of spec.
+ *
+ * @return  >0 if st is matched by spec;
+ *          0  if st is not matched by spec;
+ *          AVERROR code if spec is invalid
+ *
+ * @note  A stream specifier can match several streams in the format.
+ */
+int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
+                                    const char *spec);
+
+void avformat_queue_attached_pictures(AVFormatContext *s);
+
+
+/**
  * @}
  */
 
diff --git a/libavformat/avi.h b/libavformat/avi.h
index e05db9c..34da76f 100644
--- a/libavformat/avi.h
+++ b/libavformat/avi.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index a3af5cf..835c36d 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -2,37 +2,36 @@
  * AVI demuxer
  * Copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/bswap.h"
+#include "libavutil/opt.h"
 #include "libavutil/dict.h"
 #include "libavutil/avstring.h"
+#include "libavutil/avassert.h"
 #include "avformat.h"
 #include "internal.h"
 #include "avi.h"
 #include "dv.h"
 #include "riff.h"
 
-#undef NDEBUG
-#include <assert.h>
-
 typedef struct AVIStream {
     int64_t frame_offset; /* current frame (video) or byte (audio) counter
                          (used to compute the pts) */
@@ -54,9 +53,12 @@
     AVFormatContext *sub_ctx;
     AVPacket sub_pkt;
     uint8_t *sub_buffer;
+
+    int64_t seek_pos;
 } AVIStream;
 
 typedef struct {
+    const AVClass *class;
     int64_t  riff_end;
     int64_t  movi_end;
     int64_t  fsize;
@@ -68,9 +70,26 @@
     int stream_index;
     DVDemuxContext* dv_demux;
     int odml_depth;
+    int use_odml;
 #define MAX_ODML_DEPTH 1000
+    int64_t dts_max;
 } AVIContext;
 
+
+static const AVOption options[] = {
+    { "use_odml", "use odml index", offsetof(AVIContext, use_odml), AV_OPT_TYPE_INT, {.i64 = 1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM},
+    { NULL },
+};
+
+static const AVClass demuxer_class = {
+    .class_name = "avi",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+    .category   = AV_CLASS_CATEGORY_DEMUXER,
+};
+
+
 static const char avi_headers[][8] = {
     { 'R', 'I', 'F', 'F',    'A', 'V', 'I', ' ' },
     { 'R', 'I', 'F', 'F',    'A', 'V', 'I', 'X' },
@@ -143,7 +162,7 @@
     AVIStream *ast;
     int i;
     int64_t last_pos= -1;
-    int64_t filesize= avio_size(s->pb);
+    int64_t filesize= avi->fsize;
 
     av_dlog(s, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n",
             longs_pre_entry,index_type, entries_in_use, chunk_id, base);
@@ -178,9 +197,10 @@
             int key= len >= 0;
             len &= 0x7FFFFFFF;
 
-            av_dlog(s, "pos:%"PRId64", len:%X\n", pos, len);
-
-            if(pb->eof_reached)
+#ifdef DEBUG_SEEK
+            av_log(s, AV_LOG_ERROR, "pos:%"PRId64", len:%X\n", pos, len);
+#endif
+            if(url_feof(pb))
                 return -1;
 
             if(last_pos == pos || pos == base - 8)
@@ -197,7 +217,7 @@
             avio_rl32(pb);       /* size */
             duration = avio_rl32(pb);
 
-            if(pb->eof_reached)
+            if(url_feof(pb))
                 return -1;
 
             pos = avio_tell(pb);
@@ -207,16 +227,21 @@
                 return -1;
             }
 
-            avio_seek(pb, offset+8, SEEK_SET);
+            if(avio_seek(pb, offset+8, SEEK_SET) < 0)
+                return -1;
             avi->odml_depth++;
             read_braindead_odml_indx(s, frame_num);
             avi->odml_depth--;
             frame_num += duration;
 
-            avio_seek(pb, pos, SEEK_SET);
+            if(avio_seek(pb, pos, SEEK_SET) < 0) {
+                av_log(s, AV_LOG_ERROR, "Failed to restore position after reading index\n");
+                return -1;
+            }
+
         }
     }
-    avi->index_loaded=1;
+    avi->index_loaded=2;
     return 0;
 }
 
@@ -345,8 +370,10 @@
     if (get_riff(s, pb) < 0)
         return -1;
 
+    av_log(avi, AV_LOG_DEBUG, "use odml:%d\n", avi->use_odml);
+
     avi->fsize = avio_size(pb);
-    if(avi->fsize<=0)
+    if(avi->fsize<=0 || avi->fsize < avi->riff_end)
         avi->fsize= avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
 
     /* first list tag */
@@ -354,7 +381,7 @@
     codec_type = -1;
     frame_period = 0;
     for(;;) {
-        if (pb->eof_reached)
+        if (url_feof(pb))
             goto fail;
         tag = avio_rl32(pb);
         size = avio_rl32(pb);
@@ -372,7 +399,7 @@
             if (tag1 == MKTAG('m', 'o', 'v', 'i')) {
                 avi->movi_list = avio_tell(pb) - 4;
                 if(size) avi->movi_end = avi->movi_list + size + (size & 1);
-                else     avi->movi_end = avio_size(pb);
+                else     avi->movi_end = avi->fsize;
                 av_dlog(NULL, "movi end=%"PRIx64"\n", avi->movi_end);
                 goto end_of_header;
             }
@@ -400,7 +427,7 @@
             /* AVI header */
             /* using frame_period is bad idea */
             frame_period = avio_rl32(pb);
-            avio_skip(pb, 4);
+            avio_rl32(pb); /* max. bytes per second */
             avio_rl32(pb);
             avi->non_interleaved |= avio_rl32(pb) & AVIF_MUSTUSEINDEX;
 
@@ -456,6 +483,7 @@
                 ast = s->streams[0]->priv_data;
                 av_freep(&s->streams[0]->codec->extradata);
                 av_freep(&s->streams[0]->codec);
+                av_freep(&s->streams[0]->info);
                 av_freep(&s->streams[0]);
                 s->nb_streams = 0;
                 if (CONFIG_DV_DEMUXER) {
@@ -484,7 +512,7 @@
                 break;
             }
 
-            assert(stream_index < s->nb_streams);
+            av_assert0(stream_index < s->nb_streams);
             st->codec->stream_codec_tag= handler;
 
             avio_rl32(pb); /* flags */
@@ -511,6 +539,10 @@
             st->start_time = 0;
             avio_rl32(pb); /* buffer size */
             avio_rl32(pb); /* quality */
+            if (ast->cum_len*ast->scale/ast->rate > 3600) {
+                av_log(s, AV_LOG_ERROR, "crazy start time, iam scared, giving up\n");
+                return AVERROR_INVALIDDATA;
+            }
             ast->sample_size = avio_rl32(pb); /* sample ssize */
             ast->cum_len *= FFMAX(1, ast->sample_size);
             av_dlog(s, "%"PRIu32" %"PRIu32" %d\n",
@@ -532,8 +564,7 @@
                 codec_type = AVMEDIA_TYPE_DATA;
                 break;
             default:
-                av_log(s, AV_LOG_ERROR, "unknown stream type %X\n", tag1);
-                goto fail;
+                av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1);
             }
             if(ast->sample_size == 0)
                 st->duration = st->nb_frames;
@@ -542,10 +573,13 @@
             break;
         case MKTAG('s', 't', 'r', 'f'):
             /* stream header */
+            if (!size)
+                break;
             if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) {
                 avio_skip(pb, size);
             } else {
                 uint64_t cur_pos = avio_tell(pb);
+                unsigned esize;
                 if (cur_pos < list_end)
                     size = FFMIN(size, list_end - cur_pos);
                 st = s->streams[stream_index];
@@ -559,7 +593,7 @@
                         avio_skip(pb, size);
                         break;
                     }
-                    tag1 = ff_get_bmp_header(pb, st);
+                    tag1 = ff_get_bmp_header(pb, st, &esize);
 
                     if (tag1 == MKTAG('D', 'X', 'S', 'B') || tag1 == MKTAG('D','X','S','A')) {
                         st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
@@ -568,8 +602,9 @@
                         break;
                     }
 
-                    if(size > 10*4 && size<(1<<30)){
-                        st->codec->extradata_size= size - 10*4;
+                    if(size > 10*4 && size<(1<<30) && size < avi->fsize){
+                        if(esize == size-1 && (esize&1)) st->codec->extradata_size= esize - 10*4;
+                        else                             st->codec->extradata_size=  size - 10*4;
                         st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
                         if (!st->codec->extradata) {
                             st->codec->extradata_size= 0;
@@ -583,19 +618,15 @@
 
                     /* Extract palette from extradata if bpp <= 8. */
                     /* This code assumes that extradata contains only palette. */
-                    /* This is true for all paletted codecs implemented in Libav. */
+                    /* This is true for all paletted codecs implemented in FFmpeg. */
                     if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
                         int pal_size = (1 << st->codec->bits_per_coded_sample) << 2;
                         const uint8_t *pal_src;
 
                         pal_size = FFMIN(pal_size, st->codec->extradata_size);
                         pal_src = st->codec->extradata + st->codec->extradata_size - pal_size;
-#if HAVE_BIGENDIAN
                         for (i = 0; i < pal_size/4; i++)
-                            ast->pal[i] = av_bswap32(((uint32_t*)pal_src)[i]);
-#else
-                        memcpy(ast->pal, pal_src, pal_size);
-#endif
+                            ast->pal[i] = 0xFF<<24 | AV_RL32(pal_src+4*i);
                         ast->has_pal = 1;
                     }
 
@@ -605,15 +636,10 @@
                     st->codec->codec_tag = tag1;
                     st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
                     st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts.
-                    // Support "Resolution 1:1" for Avid AVI Codec
-                    if(tag1 == MKTAG('A', 'V', 'R', 'n') &&
-                       st->codec->extradata_size >= 31 &&
-                       !memcmp(&st->codec->extradata[28], "1:1", 3))
-                        st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
 
                     if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){
                         st->codec->extradata_size+= 9;
-                        st->codec->extradata= av_realloc(st->codec->extradata, st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+                        st->codec->extradata= av_realloc_f(st->codec->extradata, 1, st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
                         if(st->codec->extradata)
                             memcpy(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9);
                     }
@@ -645,15 +671,26 @@
                     if (st->codec->stream_codec_tag == AV_RL32("Axan")){
                         st->codec->codec_id  = AV_CODEC_ID_XAN_DPCM;
                         st->codec->codec_tag = 0;
+                        ast->dshow_block_align = 0;
                     }
                     if (amv_file_format){
                         st->codec->codec_id  = AV_CODEC_ID_ADPCM_IMA_AMV;
                         ast->dshow_block_align = 0;
                     }
+                    if(st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align <= 4 && ast->dshow_block_align) {
+                        av_log(s, AV_LOG_DEBUG, "overriding invalid dshow_block_align of %d\n", ast->dshow_block_align);
+                        ast->dshow_block_align = 0;
+                    }
+                    if(st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 1024 && ast->sample_size == 1024 ||
+                       st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 4096 && ast->sample_size == 4096 ||
+                       st->codec->codec_id == AV_CODEC_ID_MP3 && ast->dshow_block_align == 1152 && ast->sample_size == 1152) {
+                        av_log(s, AV_LOG_DEBUG, "overriding sample_size\n");
+                        ast->sample_size = 0;
+                    }
                     break;
                 case AVMEDIA_TYPE_SUBTITLE:
                     st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
-                    st->codec->codec_id   = AV_CODEC_ID_PROBE;
+                    st->request_probe= 1;
                     break;
                 default:
                     st->codec->codec_type = AVMEDIA_TYPE_DATA;
@@ -664,11 +701,33 @@
                 }
             }
             break;
+        case MKTAG('s', 't', 'r', 'd'):
+            if (stream_index >= (unsigned)s->nb_streams || s->streams[stream_index]->codec->extradata_size) {
+                avio_skip(pb, size);
+            } else {
+                uint64_t cur_pos = avio_tell(pb);
+                if (cur_pos < list_end)
+                    size = FFMIN(size, list_end - cur_pos);
+                st = s->streams[stream_index];
+
+                if(size<(1<<30)){
+                    st->codec->extradata_size= size;
+                    st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+                    if (!st->codec->extradata) {
+                        st->codec->extradata_size= 0;
+                        return AVERROR(ENOMEM);
+                    }
+                    avio_read(pb, st->codec->extradata, st->codec->extradata_size);
+                }
+
+                if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
+                    avio_r8(pb);
+            }
+            break;
         case MKTAG('i', 'n', 'd', 'x'):
             i= avio_tell(pb);
-            if(pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) &&
-               read_braindead_odml_indx(s, 0) < 0 &&
-               (s->error_recognition & AV_EF_EXPLODE))
+            if(pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) && avi->use_odml &&
+               read_braindead_odml_indx(s, 0) < 0 && (s->error_recognition & AV_EF_EXPLODE))
                 goto fail;
             avio_seek(pb, i+size, SEEK_SET);
             break;
@@ -711,7 +770,7 @@
                 if (s->error_recognition & AV_EF_EXPLODE)
                     goto fail;
                 avi->movi_list = avio_tell(pb) - 4;
-                avi->movi_end  = avio_size(pb);
+                avi->movi_end  = avi->fsize;
                 goto end_of_header;
             }
             /* skip tag */
@@ -729,13 +788,17 @@
 
     if(!avi->index_loaded && pb->seekable)
         avi_load_index(s);
-    avi->index_loaded = 1;
-    avi->non_interleaved |= guess_ni_flag(s);
+    avi->index_loaded |= 1;
+    avi->non_interleaved |= guess_ni_flag(s) | (s->flags & AVFMT_FLAG_SORT_DTS);
     for(i=0; i<s->nb_streams; i++){
         AVStream *st = s->streams[i];
         if(st->nb_index_entries)
             break;
     }
+    // DV-in-AVI cannot be non-interleaved, if set this must be
+    // a mis-detection.
+    if(avi->dv_demux)
+        avi->non_interleaved=0;
     if(i==s->nb_streams && avi->non_interleaved) {
         av_log(s, AV_LOG_WARNING, "non-interleaved AVI without index, switching to interleaved\n");
         avi->non_interleaved=0;
@@ -842,6 +905,10 @@
     }
 }
 
+/**
+ *
+ * @param exit_early set to 1 to just gather packet position without making the changes needed to actually read & return the packet
+ */
 static int avi_sync(AVFormatContext *s, int exit_early)
 {
     AVIContext *avi = s->priv_data;
@@ -853,7 +920,7 @@
 
 start_sync:
     memset(d, -1, sizeof(d));
-    for(i=sync=avio_tell(pb); !pb->eof_reached; i++) {
+    for(i=sync=avio_tell(pb); !url_feof(pb); i++) {
         int j;
 
         for(j=0; j<7; j++)
@@ -901,6 +968,11 @@
             st = s->streams[n];
             ast = st->priv_data;
 
+            if (!ast) {
+                av_log(s, AV_LOG_WARNING, "Skiping foreign stream %d packet\n", n);
+                continue;
+            }
+
             if(s->nb_streams>=2){
                 AVStream *st1  = s->streams[1];
                 AVIStream *ast1= st1->priv_data;
@@ -937,7 +1009,7 @@
                 avio_rl16(pb); //flags
 
                 for (; k <= last; k++)
-                    ast->pal[k] = avio_rb32(pb)>>8;// b + (g << 8) + (r << 16);
+                    ast->pal[k] = 0xFF<<24 | avio_rb32(pb)>>8;// b + (g << 8) + (r << 16);
                 ast->has_pal= 1;
                 goto start_sync;
             } else if(   ((ast->prefix_count<5 || sync+9 > i) && d[2]<128 && d[3]<128) ||
@@ -969,6 +1041,8 @@
         }
     }
 
+    if(pb->error)
+        return pb->error;
     return AVERROR_EOF;
 }
 
@@ -1016,10 +1090,10 @@
             }
         }
         if(!best_st)
-            return -1;
+            return AVERROR_EOF;
 
         best_ast = best_st->priv_data;
-        best_ts = av_rescale_q(best_ts, (AVRational){FFMAX(1, best_ast->sample_size), AV_TIME_BASE}, best_st->time_base);
+        best_ts = best_ast->frame_offset;
         if(best_ast->remaining)
             i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
         else{
@@ -1031,15 +1105,18 @@
         if(i>=0){
             int64_t pos= best_st->index_entries[i].pos;
             pos += best_ast->packet_size - best_ast->remaining;
-            avio_seek(s->pb, pos + 8, SEEK_SET);
+            if(avio_seek(s->pb, pos + 8, SEEK_SET) < 0)
+              return AVERROR_EOF;
 
-            assert(best_ast->remaining <= best_ast->packet_size);
+            av_assert0(best_ast->remaining <= best_ast->packet_size);
 
             avi->stream_index= best_stream_index;
             if(!best_ast->remaining)
                 best_ast->packet_size=
                 best_ast->remaining= best_st->index_entries[i].size;
         }
+        else
+          return AVERROR_EOF;
     }
 
 resync:
@@ -1065,6 +1142,7 @@
         err= av_get_packet(pb, pkt, size);
         if(err<0)
             return err;
+        size = err;
 
         if(ast->has_pal && pkt->data && pkt->size<(unsigned)INT_MAX/2){
             uint8_t *pal;
@@ -1080,7 +1158,7 @@
         if (CONFIG_DV_DEMUXER && avi->dv_demux) {
             dstr = pkt->destruct;
             size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
-                                    pkt->data, pkt->size);
+                                    pkt->data, pkt->size, pkt->pos);
             pkt->destruct = dstr;
             pkt->flags |= AV_PKT_FLAG_KEY;
             if (size < 0)
@@ -1105,12 +1183,29 @@
             if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
                 AVIndexEntry *e;
                 int index;
-                assert(st->index_entries);
+                av_assert0(st->index_entries);
 
                 index= av_index_search_timestamp(st, ast->frame_offset, 0);
                 e= &st->index_entries[index];
 
                 if(index >= 0 && e->timestamp == ast->frame_offset){
+                    if (index == st->nb_index_entries-1){
+                        int key=1;
+                        int i;
+                        uint32_t state=-1;
+                        for(i=0; i<FFMIN(size,256); i++){
+                            if(st->codec->codec_id == AV_CODEC_ID_MPEG4){
+                                if(state == 0x1B6){
+                                    key= !(pkt->data[i]&0xC0);
+                                    break;
+                                }
+                            }else
+                                break;
+                            state= (state<<8) + pkt->data[i];
+                        }
+                        if(!key)
+                            e->flags &= ~AVINDEX_KEYFRAME;
+                    }
                     if (e->flags & AVINDEX_KEYFRAME)
                         pkt->flags |= AV_PKT_FLAG_KEY;
                 }
@@ -1125,6 +1220,22 @@
             ast->packet_size= 0;
         }
 
+        if(!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos){
+            av_free_packet(pkt);
+            goto resync;
+        }
+        ast->seek_pos= 0;
+
+        if(!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1){
+            int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);
+
+            if(avi->dts_max - dts > 2*AV_TIME_BASE){
+                avi->non_interleaved= 1;
+                av_log(s, AV_LOG_INFO, "Switching to NI mode, due to poor interleaving\n");
+            }else if(avi->dts_max < dts)
+                avi->dts_max = dts;
+        }
+
         return 0;
     }
 
@@ -1144,7 +1255,9 @@
     AVIStream *ast;
     unsigned int index, tag, flags, pos, len, first_packet = 1;
     unsigned last_pos= -1;
+    unsigned last_idx= -1;
     int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
+    int anykey = 0;
 
     nb_index_entries = size / 16;
     if (nb_index_entries <= 0)
@@ -1160,6 +1273,9 @@
 
     /* Read the entries and sort them in each stream component. */
     for(i = 0; i < nb_index_entries; i++) {
+        if(url_feof(pb))
+            return -1;
+
         tag = avio_rl32(pb);
         flags = avio_rl32(pb);
         pos = avio_rl32(pb);
@@ -1182,15 +1298,25 @@
 
         av_dlog(s, "%d cum_len=%"PRId64"\n", len, ast->cum_len);
 
-        if(pb->eof_reached)
-            return -1;
 
+        // even if we have only a single stream, we should
+        // switch to non-interleaved to get correct timestamps
         if(last_pos == pos)
             avi->non_interleaved= 1;
-        else if(len || !ast->sample_size)
+        if(last_idx != pos && len) {
             av_add_index_entry(st, pos, ast->cum_len, len, 0, (flags&AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
+            last_idx= pos;
+        }
         ast->cum_len += get_duration(ast, len);
         last_pos= pos;
+        anykey |= flags&AVIIF_INDEX;
+    }
+    if (!anykey) {
+        for (index = 0; index < s->nb_streams; index++) {
+            st = s->streams[index];
+            if (st->nb_index_entries)
+                st->index_entries[0].flags |= AVINDEX_KEYFRAME;
+        }
     }
     return 0;
 }
@@ -1200,6 +1326,8 @@
     int64_t last_start=0;
     int64_t first_end= INT64_MAX;
     int64_t oldpos= avio_tell(s->pb);
+    int *idx;
+    int64_t min_pos, pos;
 
     for(i=0; i<s->nb_streams; i++){
         AVStream *st = s->streams[i];
@@ -1223,7 +1351,32 @@
             first_end= st->index_entries[n-1].pos;
     }
     avio_seek(s->pb, oldpos, SEEK_SET);
-    return last_start > first_end;
+    if (last_start > first_end)
+        return 1;
+    idx= av_mallocz(sizeof(*idx) * s->nb_streams);
+    for (min_pos=pos=0; min_pos!=INT64_MAX; pos= min_pos+1LU) {
+        int64_t max_dts = INT64_MIN/2, min_dts= INT64_MAX/2;
+        min_pos = INT64_MAX;
+
+        for (i=0; i<s->nb_streams; i++) {
+            AVStream *st = s->streams[i];
+            int n= st->nb_index_entries;
+            while (idx[i]<n && st->index_entries[idx[i]].pos < pos)
+                idx[i]++;
+            if (idx[i] < n) {
+                min_dts = FFMIN(min_dts, av_rescale_q(st->index_entries[idx[i]].timestamp, st->time_base, AV_TIME_BASE_Q));
+                min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos);
+            }
+            if (idx[i])
+                max_dts = FFMAX(max_dts, av_rescale_q(st->index_entries[idx[i]-1].timestamp, st->time_base, AV_TIME_BASE_Q));
+        }
+        if(max_dts - min_dts > 2*AV_TIME_BASE) {
+            av_free(idx);
+            return 1;
+        }
+    }
+    av_free(idx);
+    return 0;
 }
 
 static int avi_load_index(AVFormatContext *s)
@@ -1232,16 +1385,19 @@
     AVIOContext *pb = s->pb;
     uint32_t tag, size;
     int64_t pos= avio_tell(pb);
+    int64_t next;
     int ret = -1;
 
     if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0)
         goto the_end; // maybe truncated file
     av_dlog(s, "movi_end=0x%"PRIx64"\n", avi->movi_end);
     for(;;) {
-        if (pb->eof_reached)
-            break;
         tag = avio_rl32(pb);
         size = avio_rl32(pb);
+        if (url_feof(pb))
+            break;
+        next = avio_tell(pb) + size + (size & 1);
+
         av_dlog(s, "tag=%c%c%c%c size=0x%x\n",
                  tag        & 0xff,
                 (tag >>  8) & 0xff,
@@ -1251,12 +1407,17 @@
 
         if (tag == MKTAG('i', 'd', 'x', '1') &&
             avi_read_idx1(s, size) >= 0) {
+            avi->index_loaded=2;
             ret = 0;
-            break;
-        }
+        }else if(tag == MKTAG('L', 'I', 'S', 'T')) {
+            uint32_t tag1 = avio_rl32(pb);
 
-        size += (size & 1);
-        if (avio_skip(pb, size) < 0)
+            if (tag1 == MKTAG('I', 'N', 'F', 'O'))
+                ff_read_riff_info(s, size - 4);
+        }else if(!ret)
+            break;
+
+        if (avio_seek(pb, next, SEEK_SET) < 0)
             break; // something is wrong here
     }
  the_end:
@@ -1279,21 +1440,27 @@
     AVIContext *avi = s->priv_data;
     AVStream *st;
     int i, index;
-    int64_t pos;
+    int64_t pos, pos_min;
     AVIStream *ast;
 
     if (!avi->index_loaded) {
         /* we only load the index on demand */
         avi_load_index(s);
-        avi->index_loaded = 1;
+        avi->index_loaded |= 1;
     }
-    assert(stream_index>= 0);
+    av_assert0(stream_index>= 0);
 
     st = s->streams[stream_index];
     ast= st->priv_data;
     index= av_index_search_timestamp(st, timestamp * FFMAX(ast->sample_size, 1), flags);
-    if(index<0)
+    if (index<0) {
+        if (st->nb_index_entries > 0)
+            av_log(s, AV_LOG_DEBUG, "Failed to find timestamp %"PRId64 " in index %"PRId64 " .. %"PRId64 "\n",
+                   timestamp * FFMAX(ast->sample_size, 1),
+                   st->index_entries[0].timestamp,
+                   st->index_entries[st->nb_index_entries - 1].timestamp);
         return -1;
+    }
 
     /* find the position */
     pos = st->index_entries[index].pos;
@@ -1306,17 +1473,20 @@
         /* One and only one real stream for DV in AVI, and it has video  */
         /* offsets. Calling with other stream indexes should have failed */
         /* the av_index_search_timestamp call above.                     */
-        assert(stream_index == 0);
+        av_assert0(stream_index == 0);
+
+        if(avio_seek(s->pb, pos, SEEK_SET) < 0)
+            return -1;
 
         /* Feed the DV video stream version of the timestamp to the */
         /* DV demux so it can synthesize correct timestamps.        */
         ff_dv_offset_reset(avi->dv_demux, timestamp);
 
-        avio_seek(s->pb, pos, SEEK_SET);
         avi->stream_index= -1;
         return 0;
     }
 
+    pos_min= pos;
     for(i = 0; i < s->nb_streams; i++) {
         AVStream *st2 = s->streams[i];
         AVIStream *ast2 = st2->priv_data;
@@ -1332,31 +1502,42 @@
         if (st2->nb_index_entries <= 0)
             continue;
 
-//        assert(st2->codec->block_align);
-        assert((int64_t)st2->time_base.num*ast2->rate == (int64_t)st2->time_base.den*ast2->scale);
+//        av_assert1(st2->codec->block_align);
+        av_assert0((int64_t)st2->time_base.num*ast2->rate == (int64_t)st2->time_base.den*ast2->scale);
         index = av_index_search_timestamp(
                 st2,
                 av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
-                flags | AVSEEK_FLAG_BACKWARD);
+                flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
         if(index<0)
             index=0;
+        ast2->seek_pos= st2->index_entries[index].pos;
+        pos_min= FFMIN(pos_min,ast2->seek_pos);
+    }
+    for(i = 0; i < s->nb_streams; i++) {
+        AVStream *st2 = s->streams[i];
+        AVIStream *ast2 = st2->priv_data;
 
-        if(!avi->non_interleaved){
-            while(index>0 && st2->index_entries[index].pos > pos)
-                index--;
-            while(index+1 < st2->nb_index_entries && st2->index_entries[index].pos < pos)
-                index++;
-        }
+        if (ast2->sub_ctx || st2->nb_index_entries <= 0)
+            continue;
 
-        av_dlog(s, "%"PRId64" %d %"PRId64"\n",
-                timestamp, index, st2->index_entries[index].timestamp);
-        /* extract the current frame number */
+        index = av_index_search_timestamp(
+                st2,
+                av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
+                flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
+        if(index<0)
+            index=0;
+        while(!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min)
+            index--;
         ast2->frame_offset = st2->index_entries[index].timestamp;
     }
 
     /* do the seek */
-    avio_seek(s->pb, pos, SEEK_SET);
+    if (avio_seek(s->pb, pos_min, SEEK_SET) < 0) {
+        av_log(s, AV_LOG_ERROR, "Seek failed\n");
+        return -1;
+    }
     avi->stream_index= -1;
+    avi->dts_max= INT_MIN;
     return 0;
 }
 
@@ -1405,4 +1586,5 @@
     .read_packet    = avi_read_packet,
     .read_close     = avi_read_close,
     .read_seek      = avi_read_seek,
+    .priv_class = &demuxer_class,
 };
diff --git a/libavformat/avienc.c b/libavformat/avienc.c
index fa63212..0352f8b 100644
--- a/libavformat/avienc.c
+++ b/libavformat/avienc.c
@@ -2,20 +2,20 @@
  * AVI muxer
  * Copyright (c) 2000 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
@@ -25,6 +25,7 @@
 #include "riff.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
+#include "libavutil/avassert.h"
 
 /*
  * TODO:
@@ -130,7 +131,7 @@
     for(n = 0; n < s->nb_streams; n++) {
         AVIStream *avist= s->streams[n]->priv_data;
 
-        assert(avist->frames_hdr_strm);
+        av_assert0(avist->frames_hdr_strm);
         stream = s->streams[n]->codec;
         avio_seek(pb, avist->frames_hdr_strm, SEEK_SET);
         ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale);
@@ -143,7 +144,7 @@
             nb_frames = FFMAX(nb_frames, avist->packet_count);
     }
     if(riff_id == 1) {
-        assert(avi->frames_hdr_all);
+        av_assert0(avi->frames_hdr_all);
         avio_seek(pb, avi->frames_hdr_all, SEEK_SET);
         avio_wl32(pb, nb_frames);
     }
@@ -255,9 +256,12 @@
 
         ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale);
 
+        avpriv_set_pts_info(s->streams[i], 64, au_scale, au_byterate);
+        if(stream->codec_id == AV_CODEC_ID_XSUB)
+            au_scale = au_byterate = 0;
+
         avio_wl32(pb, au_scale); /* scale */
         avio_wl32(pb, au_byterate); /* rate */
-        avpriv_set_pts_info(s->streams[i], 64, au_scale, au_byterate);
 
         avio_wl32(pb, 0); /* start */
         avist->frames_hdr_strm = avio_tell(pb); /* remember this offset to fill later */
@@ -408,7 +412,7 @@
     char ix_tag[] = "ix00";
     int i, j;
 
-    assert(pb->seekable);
+    av_assert0(pb->seekable);
 
     if (avi->riff_id > AVI_MASTER_INDEX_SIZE)
         return -1;
@@ -520,14 +524,21 @@
     AVCodecContext *enc= s->streams[stream_index]->codec;
     int size= pkt->size;
 
-    while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count){
+//    av_log(s, AV_LOG_DEBUG, "%"PRId64" %d %d\n", pkt->dts, avist->packet_count, stream_index);
+    while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count && enc->codec_id != AV_CODEC_ID_XSUB){
         AVPacket empty_packet;
 
+        if(pkt->dts - avist->packet_count > 60000){
+            av_log(s, AV_LOG_ERROR, "Too large number of skiped frames %"PRId64"\n", pkt->dts - avist->packet_count);
+            return AVERROR(EINVAL);
+        }
+
         av_init_packet(&empty_packet);
         empty_packet.size= 0;
         empty_packet.data= NULL;
         empty_packet.stream_index= stream_index;
         avi_write_packet(s, &empty_packet);
+//        av_log(s, AV_LOG_DEBUG, "dup %"PRId64" %d\n", pkt->dts, avist->packet_count);
     }
     avist->packet_count++;
 
@@ -557,7 +568,7 @@
         int cl = idx->entry / AVI_INDEX_CLUSTER_SIZE;
         int id = idx->entry % AVI_INDEX_CLUSTER_SIZE;
         if (idx->ents_allocated <= idx->entry) {
-            idx->cluster = av_realloc(idx->cluster, (cl+1)*sizeof(void*));
+            idx->cluster = av_realloc_f(idx->cluster, sizeof(void*), cl+1);
             if (!idx->cluster)
                 return -1;
             idx->cluster[cl] = av_malloc(AVI_INDEX_CLUSTER_SIZE*sizeof(AVIIentry));
diff --git a/libavformat/avio.c b/libavformat/avio.c
index 45ee866..abc7072 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -2,20 +2,20 @@
  * unbuffered I/O
  * Copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -85,7 +85,7 @@
 
 const char *avio_enum_protocols(void **opaque, int output)
 {
-    URLProtocol **p = opaque;
+    URLProtocol **p = (URLProtocol **)opaque;
     *p = ffurl_protocol_next(*p);
     if (!*p) return NULL;
     if ((output && (*p)->url_write) || (!output && (*p)->url_read))
@@ -134,8 +134,32 @@
     if (up->priv_data_size) {
         uc->priv_data = av_mallocz(up->priv_data_size);
         if (up->priv_data_class) {
+            int proto_len= strlen(up->name);
+            char *start = strchr(uc->filename, ',');
             *(const AVClass**)uc->priv_data = up->priv_data_class;
             av_opt_set_defaults(uc->priv_data);
+            if(!strncmp(up->name, uc->filename, proto_len) && uc->filename + proto_len == start){
+                int ret= 0;
+                char *p= start;
+                char sep= *++p;
+                char *key, *val;
+                p++;
+                while(ret >= 0 && (key= strchr(p, sep)) && p<key && (val = strchr(key+1, sep))){
+                    *val= *key= 0;
+                    ret= av_opt_set(uc->priv_data, p, key+1, 0);
+                    if (ret == AVERROR_OPTION_NOT_FOUND)
+                        av_log(uc, AV_LOG_ERROR, "Key '%s' not found.\n", p);
+                    *val= *key= sep;
+                    p= val+1;
+                }
+                if(ret<0 || p!=key){
+                    av_log(uc, AV_LOG_ERROR, "Error parsing options string %s\n", start);
+                    av_freep(&uc->priv_data);
+                    av_freep(&uc);
+                    goto fail;
+                }
+                memmove(start, key+1, strlen(key));
+            }
         }
     }
     if (int_cb)
@@ -180,11 +204,18 @@
     char proto_str[128], proto_nested[128], *ptr;
     size_t proto_len = strspn(filename, URL_SCHEME_CHARS);
 
-    if (filename[proto_len] != ':' || is_dos_path(filename))
+    if (!first_protocol) {
+        av_log(NULL, AV_LOG_WARNING, "No URL Protocols are registered. "
+                                     "Missing call to av_register_all()?\n");
+    }
+
+    if (filename[proto_len] != ':' &&  filename[proto_len] != ',' || is_dos_path(filename))
         strcpy(proto_str, "file");
     else
         av_strlcpy(proto_str, filename, FFMIN(proto_len+1, sizeof(proto_str)));
 
+    if ((ptr = strchr(proto_str, ',')))
+        *ptr = '\0';
     av_strlcpy(proto_nested, proto_str, sizeof(proto_nested));
     if ((ptr = strchr(proto_nested, '+')))
         *ptr = '\0';
@@ -197,7 +228,7 @@
             return url_alloc_for_protocol (puc, up, filename, flags, int_cb);
     }
     *puc = NULL;
-    return AVERROR(ENOENT);
+    return AVERROR_PROTOCOL_NOT_FOUND;
 }
 
 int ffurl_open(URLContext **puc, const char *filename, int flags,
@@ -223,6 +254,7 @@
 {
     int ret, len;
     int fast_retries = 5;
+    int64_t wait_since = 0;
 
     len = 0;
     while (len < size_min) {
@@ -233,16 +265,23 @@
             return ret;
         if (ret == AVERROR(EAGAIN)) {
             ret = 0;
-            if (fast_retries)
+            if (fast_retries) {
                 fast_retries--;
-            else
+            } else {
+                if (h->rw_timeout) {
+                    if (!wait_since)
+                        wait_since = av_gettime();
+                    else if (av_gettime() > wait_since + h->rw_timeout)
+                        return AVERROR(EIO);
+                }
                 av_usleep(1000);
+            }
         } else if (ret < 1)
             return ret < 0 ? ret : len;
         if (ret)
            fast_retries = FFMAX(fast_retries, 2);
         len += ret;
-        if (ff_check_interrupt(&h->interrupt_callback))
+        if (len < size && ff_check_interrupt(&h->interrupt_callback))
             return AVERROR_EXIT;
     }
     return len;
@@ -270,7 +309,7 @@
     if (h->max_packet_size && size > h->max_packet_size)
         return AVERROR(EIO);
 
-    return retry_transfer_wrapper(h, buf, size, size, h->prot->url_write);
+    return retry_transfer_wrapper(h, (unsigned char *)buf, size, size, (void*)h->prot->url_write);
 }
 
 int64_t ffurl_seek(URLContext *h, int64_t pos, int whence)
@@ -283,8 +322,9 @@
     return ret;
 }
 
-int ffurl_close(URLContext *h)
+int ffurl_closep(URLContext **hh)
 {
+    URLContext *h= *hh;
     int ret = 0;
     if (!h) return 0; /* can happen when ffurl_open fails */
 
@@ -297,12 +337,18 @@
     if (h->prot->priv_data_size) {
         if (h->prot->priv_data_class)
             av_opt_free(h->priv_data);
-        av_free(h->priv_data);
+        av_freep(&h->priv_data);
     }
-    av_free(h);
+    av_freep(hh);
     return ret;
 }
 
+int ffurl_close(URLContext *h)
+{
+    return ffurl_closep(&h);
+}
+
+
 int avio_check(const char *url, int flags)
 {
     URLContext *h;
diff --git a/libavformat/avio.h b/libavformat/avio.h
index b6d3cb3..17b341d 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #ifndef AVFORMAT_AVIO_H
@@ -115,6 +115,31 @@
      * A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
      */
     int seekable;
+
+    /**
+     * max filesize, used to limit allocations
+     * This field is internal to libavformat and access from outside is not allowed.
+     */
+     int64_t maxsize;
+
+     /**
+      * avio_read and avio_write should if possible be satisfied directly
+      * instead of going through a buffer, and avio_seek will always
+      * call the underlying seek function directly.
+      */
+     int direct;
+
+    /**
+     * Bytes read statistic
+     * This field is internal to libavformat and access from outside is not allowed.
+     */
+     int64_t bytes_read;
+
+    /**
+     * seek statistic
+     * This field is internal to libavformat and access from outside is not allowed.
+     */
+     int seek_count;
 } AVIOContext;
 
 /* unbuffered I/O */
@@ -146,6 +171,7 @@
  * @param opaque An opaque pointer to user-specific data.
  * @param read_packet  A function for refilling the buffer, may be NULL.
  * @param write_packet A function for writing the buffer contents, may be NULL.
+ *        The function may not change the input buffers content.
  * @param seek A function for seeking to specified byte position, may be NULL.
  *
  * @return Allocated AVIOContext or NULL on failure.
@@ -207,10 +233,7 @@
  * Skip given number of bytes forward
  * @return new position or AVERROR.
  */
-static av_always_inline int64_t avio_skip(AVIOContext *s, int64_t offset)
-{
-    return avio_seek(s, offset, SEEK_CUR);
-}
+int64_t avio_skip(AVIOContext *s, int64_t offset);
 
 /**
  * ftell() equivalent for AVIOContext.
@@ -227,12 +250,23 @@
  */
 int64_t avio_size(AVIOContext *s);
 
+/**
+ * feof() equivalent for AVIOContext.
+ * @return non zero if and only if end of file
+ */
+int url_feof(AVIOContext *s);
+
 /** @warning currently size is limited */
 int avio_printf(AVIOContext *s, const char *fmt, ...) av_printf_format(2, 3);
 
+/**
+ * Force flushing of buffered data to the output s.
+ *
+ * Force the buffered data to be immediately written to the output,
+ * without to wait to fill the internal buffer.
+ */
 void avio_flush(AVIOContext *s);
 
-
 /**
  * Read size bytes from AVIOContext into buf.
  * @return number of bytes read or AVERROR
@@ -311,6 +345,14 @@
 #define AVIO_FLAG_NONBLOCK 8
 
 /**
+ * Use direct mode.
+ * avio_read and avio_write should if possible be satisfied directly
+ * instead of going through a buffer, and avio_seek will always
+ * call the underlying seek function directly.
+ */
+#define AVIO_FLAG_DIRECT 0x8000
+
+/**
  * Create and initialize a AVIOContext for accessing the
  * resource indicated by url.
  * @note When the resource indicated by url has been opened in
@@ -417,13 +459,13 @@
  *        If stream_index is (-1) the timestamp should be in AV_TIME_BASE
  *        units from the beginning of the presentation.
  *        If a stream_index >= 0 is used and the protocol does not support
- *        seeking based on component streams, the call will fail with ENOTSUP.
+ *        seeking based on component streams, the call will fail.
  * @param timestamp timestamp in AVStream.time_base units
  *        or if there is no stream specified then in AV_TIME_BASE units.
  * @param flags Optional combination of AVSEEK_FLAG_BACKWARD, AVSEEK_FLAG_BYTE
  *        and AVSEEK_FLAG_ANY. The protocol may silently ignore
  *        AVSEEK_FLAG_BACKWARD and AVSEEK_FLAG_ANY, but AVSEEK_FLAG_BYTE will
- *        fail with ENOTSUP if used and not supported.
+ *        fail if used and not supported.
  * @return >= 0 on success
  * @see AVInputFormat::read_seek
  */
diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h
index f2ccc36..3c0fc93 100644
--- a/libavformat/avio_internal.h
+++ b/libavformat/avio_internal.h
@@ -1,19 +1,19 @@
 /*
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -64,13 +64,15 @@
  * @return 0 in case of success, a negative value corresponding to an
  * AVERROR code in case of failure
  */
-int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char *buf, int buf_size);
+int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **buf, int buf_size);
 
 uint64_t ffio_read_varlen(AVIOContext *bc);
 
 /** @warning must be called before any I/O */
 int ffio_set_buf_size(AVIOContext *s, int buf_size);
 
+int ffio_limit(AVIOContext *s, int size);
+
 void ffio_init_checksum(AVIOContext *s,
                         unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len),
                         unsigned long checksum);
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index da836c6..6e060ba 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -2,20 +2,20 @@
  * buffered I/O
  * Copyright (c) 2000,2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,6 +24,7 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
+#include "libavutil/avassert.h"
 #include "avformat.h"
 #include "avio.h"
 #include "avio_internal.h"
@@ -80,6 +81,7 @@
     s->buffer_size = buffer_size;
     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;
@@ -117,20 +119,25 @@
     return s;
 }
 
+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){
+            s->error = ret;
+        }
+    }
+    s->pos += len;
+}
+
 static void flush_buffer(AVIOContext *s)
 {
     if (s->buf_ptr > s->buffer) {
-        if (s->write_packet && !s->error){
-            int ret= s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer);
-            if(ret < 0){
-                s->error = ret;
-            }
-        }
+        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;
         }
-        s->pos += s->buf_ptr - s->buffer;
     }
     s->buf_ptr = s->buffer;
 }
@@ -158,6 +165,11 @@
 
 void avio_write(AVIOContext *s, const unsigned char *buf, int size)
 {
+    if (s->direct && !s->update_checksum) {
+        avio_flush(s);
+        writeout(s, buf, size);
+        return;
+    }
     while (size > 0) {
         int len = FFMIN(s->buf_end - s->buf_ptr, size);
         memcpy(s->buf_ptr, buf, len);
@@ -199,13 +211,14 @@
         offset += offset1;
     }
     offset1 = offset - pos;
-    if (!s->must_flush &&
+    if (!s->must_flush && (!s->direct || !s->seek) &&
         offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) {
         /* can do the seek inside the buffer */
         s->buf_ptr = s->buffer + offset1;
     } else if ((!s->seekable ||
                offset1 <= s->buf_end + SHORT_SEEK_THRESHOLD - s->buffer) &&
                !s->write_flag && offset1 >= 0 &&
+               (!s->direct || !s->seek) &&
               (whence != SEEK_END || force)) {
         while(s->pos < offset && !s->eof_reached)
             fill_buffer(s);
@@ -225,6 +238,7 @@
             return AVERROR(EPIPE);
         if ((res = s->seek(s->opaque, offset, SEEK_SET)) < 0)
             return res;
+        s->seek_count ++;
         if (!s->write_flag)
             s->buf_end = s->buffer;
         s->buf_ptr = s->buffer;
@@ -234,6 +248,11 @@
     return offset;
 }
 
+int64_t avio_skip(AVIOContext *s, int64_t offset)
+{
+    return avio_seek(s, offset, SEEK_CUR);
+}
+
 int64_t avio_size(AVIOContext *s)
 {
     int64_t size;
@@ -253,6 +272,17 @@
     return size;
 }
 
+int url_feof(AVIOContext *s)
+{
+    if(!s)
+        return 0;
+    if(s->eof_reached){
+        s->eof_reached=0;
+        fill_buffer(s);
+    }
+    return s->eof_reached;
+}
+
 void avio_wl32(AVIOContext *s, unsigned int val)
 {
     avio_w8(s, val);
@@ -359,7 +389,7 @@
     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 appropiate */
+    /* can't fill the buffer without read_packet, just set EOF if appropriate */
     if (!s->read_packet && s->buf_ptr >= s->buf_end)
         s->eof_reached = 1;
 
@@ -374,7 +404,7 @@
     }
 
     /* make buffer smaller in case it ended up large after probing */
-    if (s->buffer_size > max_buffer_size) {
+    if (s->read_packet && s->buffer_size > max_buffer_size) {
         ffio_set_buf_size(s, max_buffer_size);
 
         s->checksum_ptr = dst = s->buffer;
@@ -395,6 +425,7 @@
         s->pos += len;
         s->buf_ptr = dst;
         s->buf_end = dst + len;
+        s->bytes_read += len;
     }
 }
 
@@ -442,7 +473,7 @@
         if (len > size)
             len = size;
         if (len == 0) {
-            if(size > s->buffer_size && !s->update_checksum){
+            if((s->direct || size > s->buffer_size) && !s->update_checksum){
                 if(s->read_packet)
                     len = s->read_packet(s->opaque, buf, size);
                 if (len <= 0) {
@@ -454,6 +485,7 @@
                     break;
                 } else {
                     s->pos += len;
+                    s->bytes_read += len;
                     size -= len;
                     buf += len;
                     s->buf_ptr = s->buffer;
@@ -473,8 +505,8 @@
         }
     }
     if (size1 == size) {
-        if (s->error)         return s->error;
-        if (s->eof_reached)   return AVERROR_EOF;
+        if (s->error)      return s->error;
+        if (url_feof(s))   return AVERROR_EOF;
     }
     return size1 - size;
 }
@@ -496,8 +528,8 @@
     memcpy(buf, s->buf_ptr, len);
     s->buf_ptr += len;
     if (!len) {
-        if (s->error)         return s->error;
-        if (s->eof_reached)   return AVERROR_EOF;
+        if (s->error)      return s->error;
+        if (url_feof(s))   return AVERROR_EOF;
     }
     return len;
 }
@@ -649,11 +681,12 @@
         return AVERROR(ENOMEM);
 
     *s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h,
-                            ffurl_read, ffurl_write, ffurl_seek);
+                            (void*)ffurl_read, (void*)ffurl_write, (void*)ffurl_seek);
     if (!*s) {
         av_free(buffer);
         return AVERROR(ENOMEM);
     }
+    (*s)->direct = h->flags & AVIO_FLAG_DIRECT;
     (*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL;
     (*s)->max_packet_size = max_packet_size;
     if(h->prot) {
@@ -681,7 +714,7 @@
 
 static int url_resetbuf(AVIOContext *s, int flags)
 {
-    assert(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ);
+    av_assert1(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ);
 
     if (flags & AVIO_FLAG_WRITE) {
         s->buf_end = s->buffer + s->buffer_size;
@@ -693,27 +726,32 @@
     return 0;
 }
 
-int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char *buf, int buf_size)
+int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **bufp, int buf_size)
 {
     int64_t buffer_start;
     int buffer_size;
     int overlap, new_size, alloc_size;
+    uint8_t *buf = *bufp;
 
-    if (s->write_flag)
+    if (s->write_flag) {
+        av_freep(bufp);
         return AVERROR(EINVAL);
+    }
 
     buffer_size = s->buf_end - s->buffer;
 
     /* the buffers must touch or overlap */
-    if ((buffer_start = s->pos - buffer_size) > buf_size)
+    if ((buffer_start = s->pos - buffer_size) > buf_size) {
+        av_freep(bufp);
         return AVERROR(EINVAL);
+    }
 
     overlap = buf_size - buffer_start;
     new_size = buf_size + buffer_size - overlap;
 
     alloc_size = FFMAX(s->buffer_size, new_size);
     if (alloc_size > buf_size)
-        if (!(buf = av_realloc(buf, alloc_size)))
+        if (!(buf = (*bufp) = av_realloc_f(buf, 1, alloc_size)))
             return AVERROR(ENOMEM);
 
     if (new_size > buf_size) {
@@ -764,6 +802,8 @@
     avio_flush(s);
     h = s->opaque;
     av_freep(&s->buffer);
+    if (!s->write_flag)
+        av_log(s, AV_LOG_DEBUG, "Statistics: %"PRId64" bytes read, %d seeks\n", s->bytes_read, s->seek_count);
     av_free(s);
     return ffurl_close(h);
 }
@@ -842,7 +882,7 @@
     }
 
     if (new_allocated_size > d->allocated_size) {
-        d->buffer = av_realloc(d->buffer, new_allocated_size);
+        d->buffer = av_realloc_f(d->buffer, 1, new_allocated_size);
         if(d->buffer == NULL)
              return AVERROR(ENOMEM);
         d->allocated_size = new_allocated_size;
diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c
index d31c427..e5d9b76 100644
--- a/libavformat/avisynth.c
+++ b/libavformat/avisynth.c
@@ -2,20 +2,20 @@
  * AVISynth support
  * Copyright (c) 2006 DivX, Inc.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -60,7 +60,7 @@
   res = AVIFileOpen(&avs->file, filename_char, OF_READ|OF_SHARE_DENY_WRITE, NULL);
   if (res != S_OK)
     {
-      av_log(s, AV_LOG_ERROR, "AVIFileOpen failed with error %ld", res);
+      av_log(s, AV_LOG_ERROR, "AVIFileOpen failed with error %ld\n", res);
       AVIFileExit();
       return -1;
     }
@@ -68,7 +68,7 @@
   res = AVIFileInfo(avs->file, &info, sizeof(info));
   if (res != S_OK)
     {
-      av_log(s, AV_LOG_ERROR, "AVIFileInfo failed with error %ld", res);
+      av_log(s, AV_LOG_ERROR, "AVIFileInfo failed with error %ld\n", res);
       AVIFileExit();
       return -1;
     }
@@ -133,6 +133,14 @@
                   st->codec->bit_rate = (uint64_t)stream->info.dwSampleSize * (uint64_t)stream->info.dwRate * 8 / (uint64_t)stream->info.dwScale;
                   st->codec->codec_tag = imgfmt.bmiHeader.biCompression;
                   st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, imgfmt.bmiHeader.biCompression);
+                  if (st->codec->codec_id == AV_CODEC_ID_RAWVIDEO && imgfmt.bmiHeader.biCompression== BI_RGB) {
+                    st->codec->extradata = av_malloc(9 + FF_INPUT_BUFFER_PADDING_SIZE);
+                    if (st->codec->extradata) {
+                      st->codec->extradata_size = 9;
+                      memcpy(st->codec->extradata, "BottomUp", 9);
+                    }
+                  }
+
 
                   st->duration = stream->info.dwLength;
                 }
@@ -176,7 +184,6 @@
 
   res = AVIStreamRead(stream->handle, stream->read, stream->chunck_samples, pkt->data, stream->chunck_size, &read_size, NULL);
 
-  pkt->pts = stream->read;
   pkt->size = read_size;
 
   stream->read += stream->chunck_samples;
diff --git a/libavformat/avlanguage.c b/libavformat/avlanguage.c
index e606ef2..39f2560 100644
--- a/libavformat/avlanguage.c
+++ b/libavformat/avlanguage.c
@@ -1,20 +1,20 @@
 /*
  * Cyril Comparon, Larbi Joubala, Resonate-MP4 2009
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/avlanguage.h b/libavformat/avlanguage.h
index 2ec3e2d..7fb8968 100644
--- a/libavformat/avlanguage.h
+++ b/libavformat/avlanguage.h
@@ -1,20 +1,20 @@
 /*
  * Cyril Comparon, Larbi Joubala, Resonate-MP4 2009
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/avs.c b/libavformat/avs.c
index a6a90dd..5a1eb2e 100644
--- a/libavformat/avs.c
+++ b/libavformat/avs.c
@@ -2,20 +2,20 @@
  * AVS demuxer.
  * Copyright (c) 2006  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/bethsoftvid.c b/libavformat/bethsoftvid.c
index ece230c..191f029 100644
--- a/libavformat/bethsoftvid.c
+++ b/libavformat/bethsoftvid.c
@@ -2,20 +2,20 @@
  * Bethsoft VID format Demuxer
  * Copyright (c) 2007 Nicholas Tung
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -187,7 +187,8 @@
     if (vid->palette) {
         uint8_t *pdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,
                                                  BVID_PALETTE_SIZE);
-        memcpy(pdata, vid->palette, BVID_PALETTE_SIZE);
+        if (pdata)
+            memcpy(pdata, vid->palette, BVID_PALETTE_SIZE);
         av_freep(&vid->palette);
     }
 
@@ -207,7 +208,7 @@
     int audio_length;
     int ret_value;
 
-    if(vid->is_finished || pb->eof_reached)
+    if(vid->is_finished || url_feof(pb))
         return AVERROR(EIO);
 
     block_type = avio_r8(pb);
diff --git a/libavformat/bfi.c b/libavformat/bfi.c
index c520bea..446ef57 100644
--- a/libavformat/bfi.c
+++ b/libavformat/bfi.c
@@ -2,20 +2,20 @@
  * Brute Force & Ignorance (BFI) demuxer
  * Copyright (c) 2008 Sisir Koppaka
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -110,7 +110,7 @@
     BFIContext *bfi = s->priv_data;
     AVIOContext *pb = s->pb;
     int ret, audio_offset, video_offset, chunk_size, audio_size = 0;
-    if (bfi->nframes == 0 || pb->eof_reached) {
+    if (bfi->nframes == 0 || url_feof(pb)) {
         return AVERROR(EIO);
     }
 
@@ -118,7 +118,7 @@
     if (!bfi->avflag) {
         uint32_t state = 0;
         while(state != MKTAG('S','A','V','I')){
-            if (pb->eof_reached)
+            if (url_feof(pb))
                 return AVERROR(EIO);
             state = 256*state + avio_r8(pb);
         }
diff --git a/libavformat/bink.c b/libavformat/bink.c
index 7254caf..9c90480 100644
--- a/libavformat/bink.c
+++ b/libavformat/bink.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2008-2010 Peter Ross (pross@xvid.org)
  * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -115,6 +115,8 @@
     vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     vst->codec->codec_id   = AV_CODEC_ID_BINKVIDEO;
     vst->codec->extradata  = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!vst->codec->extradata)
+        return AVERROR(ENOMEM);
     vst->codec->extradata_size = 4;
     avio_read(pb, vst->codec->extradata, 4);
 
diff --git a/libavformat/bintext.c b/libavformat/bintext.c
new file mode 100644
index 0000000..91f95f3
--- /dev/null
+++ b/libavformat/bintext.c
@@ -0,0 +1,409 @@
+/*
+ * Binary text demuxer
+ * eXtended BINary text (XBIN) demuxer
+ * Artworx Data Format demuxer
+ * iCEDraw File 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
+ * Binary text demuxer
+ * eXtended BINary text (XBIN) demuxer
+ * Artworx Data Format demuxer
+ * iCEDraw File demuxer
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "avformat.h"
+#include "internal.h"
+#include "sauce.h"
+#include "libavcodec/bintext.h"
+
+typedef struct {
+    const AVClass *class;
+    int chars_per_frame; /**< characters to send decoder per frame;
+                              set by private options as characters per second, and then
+                              converted to characters per frame at runtime */
+    char *video_size;    /**< video size (WxH pixels) (private option) */
+    char *framerate;     /**< frames per second (private option) */
+    uint64_t fsize;  /**< file size less metadata buffer */
+} BinDemuxContext;
+
+static AVStream * init_stream(AVFormatContext *s)
+{
+    BinDemuxContext *bin = s->priv_data;
+    AVStream *st = avformat_new_stream(s, NULL);
+    if (!st)
+        return NULL;
+    st->codec->codec_tag   = 0;
+    st->codec->codec_type  = AVMEDIA_TYPE_VIDEO;
+
+    if (bin->video_size) {
+        if (av_parse_video_size(&st->codec->width, &st->codec->height, bin->video_size) < 0) {
+            av_log(s, AV_LOG_ERROR, "Could not parse video size: '%s'\n", bin->video_size);
+            return NULL;
+        }
+    } else {
+        st->codec->width  = (80<<3);
+        st->codec->height = (25<<4);
+    }
+
+    if (bin->framerate) {
+        AVRational framerate;
+        if (av_parse_video_rate(&framerate, bin->framerate) < 0) {
+            av_log(s, AV_LOG_ERROR, "Could not parse framerate: '%s'\n", bin->framerate);
+            return NULL;
+        }
+        avpriv_set_pts_info(st, 60, framerate.den, framerate.num);
+    } else {
+        avpriv_set_pts_info(st, 60, 1, 25);
+    }
+
+    /* simulate tty display speed */
+    bin->chars_per_frame = FFMAX(av_q2d(st->time_base) * bin->chars_per_frame, 1);
+
+    return st;
+}
+
+#if CONFIG_BINTEXT_DEMUXER | CONFIG_ADF_DEMUXER | CONFIG_IDF_DEMUXER
+/**
+ * Given filesize and width, calculate height (assume font_height of 16)
+ */
+static void calculate_height(AVCodecContext *avctx, uint64_t fsize)
+{
+    avctx->height = (fsize / ((avctx->width>>3)*2)) << 4;
+}
+#endif
+
+#if CONFIG_BINTEXT_DEMUXER
+static const uint8_t next_magic[]={
+    0x1A, 0x1B, '[', '0', ';', '3', '0', ';', '4', '0', 'm', 'N', 'E', 'X', 'T', 0x00
+};
+
+static int next_tag_read(AVFormatContext *avctx, uint64_t *fsize)
+{
+    AVIOContext *pb = avctx->pb;
+    char buf[36];
+    int len;
+    uint64_t start_pos = avio_size(pb) - 256;
+
+    avio_seek(pb, start_pos, SEEK_SET);
+    if (avio_read(pb, buf, sizeof(next_magic)) != sizeof(next_magic))
+        return -1;
+    if (memcmp(buf, next_magic, sizeof(next_magic)))
+        return -1;
+    if (avio_r8(pb) != 0x01)
+        return -1;
+
+    *fsize -= 256;
+
+#define GET_EFI2_META(name,size) \
+    len = avio_r8(pb); \
+    if (len < 1 || len > size) \
+        return -1; \
+    if (avio_read(pb, buf, size) == size && *buf) { \
+        buf[len] = 0; \
+        av_dict_set(&avctx->metadata, name, buf, 0); \
+    }
+
+    GET_EFI2_META("filename",  12)
+    GET_EFI2_META("author",    20)
+    GET_EFI2_META("publisher", 20)
+    GET_EFI2_META("title",     35)
+
+    return 0;
+}
+
+static void predict_width(AVCodecContext *avctx, uint64_t fsize, int got_width)
+{
+    /** attempt to guess width */
+    if (!got_width)
+        avctx->width = fsize > 4000 ? (160<<3) : (80<<3);
+}
+
+static int bintext_read_header(AVFormatContext *s)
+{
+    BinDemuxContext *bin = s->priv_data;
+    AVIOContext *pb = s->pb;
+
+    AVStream *st = init_stream(s);
+    if (!st)
+        return AVERROR(ENOMEM);
+    st->codec->codec_id    = AV_CODEC_ID_BINTEXT;
+
+    st->codec->extradata_size = 2;
+    st->codec->extradata = av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!st->codec->extradata)
+        return AVERROR(ENOMEM);
+    st->codec->extradata[0] = 16;
+    st->codec->extradata[1] = 0;
+
+    if (pb->seekable) {
+        int got_width = 0;
+        bin->fsize = avio_size(pb);
+        if (ff_sauce_read(s, &bin->fsize, &got_width, 0) < 0)
+            next_tag_read(s, &bin->fsize);
+        if (!bin->video_size) {
+            predict_width(st->codec, bin->fsize, got_width);
+            calculate_height(st->codec, bin->fsize);
+        }
+        avio_seek(pb, 0, SEEK_SET);
+    }
+    return 0;
+}
+#endif /* CONFIG_BINTEXT_DEMUXER */
+
+#if CONFIG_XBIN_DEMUXER
+static int xbin_probe(AVProbeData *p)
+{
+    const uint8_t *d = p->buf;
+
+    if (AV_RL32(d) == MKTAG('X','B','I','N') && d[4] == 0x1A &&
+        AV_RL16(d+5) > 0 && AV_RL16(d+5) <= 160 &&
+        d[9] > 0 && d[9] <= 32)
+        return AVPROBE_SCORE_MAX;
+    return 0;
+}
+
+static int xbin_read_header(AVFormatContext *s)
+{
+    BinDemuxContext *bin = s->priv_data;
+    AVIOContext *pb = s->pb;
+    char fontheight, flags;
+
+    AVStream *st = init_stream(s);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    avio_skip(pb, 5);
+    st->codec->width   = avio_rl16(pb)<<3;
+    st->codec->height  = avio_rl16(pb);
+    fontheight         = avio_r8(pb);
+    st->codec->height *= fontheight;
+    flags              = avio_r8(pb);
+
+    st->codec->extradata_size = 2;
+    if ((flags & BINTEXT_PALETTE))
+        st->codec->extradata_size += 48;
+    if ((flags & BINTEXT_FONT))
+        st->codec->extradata_size += fontheight * (flags & 0x10 ? 512 : 256);
+    st->codec->codec_id    = flags & 4 ? AV_CODEC_ID_XBIN : AV_CODEC_ID_BINTEXT;
+
+    st->codec->extradata = av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!st->codec->extradata)
+        return AVERROR(ENOMEM);
+    st->codec->extradata[0] = fontheight;
+    st->codec->extradata[1] = flags;
+    if (avio_read(pb, st->codec->extradata + 2, st->codec->extradata_size - 2) < 0)
+        return AVERROR(EIO);
+
+    if (pb->seekable) {
+        bin->fsize = avio_size(pb) - 9 - st->codec->extradata_size;
+        ff_sauce_read(s, &bin->fsize, NULL, 0);
+        avio_seek(pb, 9 + st->codec->extradata_size, SEEK_SET);
+    }
+
+    return 0;
+}
+#endif /* CONFIG_XBIN_DEMUXER */
+
+#if CONFIG_ADF_DEMUXER
+static int adf_read_header(AVFormatContext *s)
+{
+    BinDemuxContext *bin = s->priv_data;
+    AVIOContext *pb = s->pb;
+    AVStream *st;
+
+    if (avio_r8(pb) != 1)
+        return AVERROR_INVALIDDATA;
+
+    st = init_stream(s);
+    if (!st)
+        return AVERROR(ENOMEM);
+    st->codec->codec_id    = AV_CODEC_ID_BINTEXT;
+
+    st->codec->extradata_size = 2 + 48 + 4096;
+    st->codec->extradata = av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!st->codec->extradata)
+        return AVERROR(ENOMEM);
+    st->codec->extradata[0] = 16;
+    st->codec->extradata[1] = BINTEXT_PALETTE|BINTEXT_FONT;
+
+    if (avio_read(pb, st->codec->extradata + 2, 24) < 0)
+        return AVERROR(EIO);
+    avio_skip(pb, 144);
+    if (avio_read(pb, st->codec->extradata + 2 + 24, 24) < 0)
+        return AVERROR(EIO);
+    if (avio_read(pb, st->codec->extradata + 2 + 48, 4096) < 0)
+        return AVERROR(EIO);
+
+    if (pb->seekable) {
+        int got_width = 0;
+        bin->fsize = avio_size(pb) - 1 - 192 - 4096;
+        st->codec->width = 80<<3;
+        ff_sauce_read(s, &bin->fsize, &got_width, 0);
+        if (!bin->video_size)
+            calculate_height(st->codec, bin->fsize);
+        avio_seek(pb, 1 + 192 + 4096, SEEK_SET);
+    }
+    return 0;
+}
+#endif /* CONFIG_ADF_DEMUXER */
+
+#if CONFIG_IDF_DEMUXER
+static const uint8_t idf_magic[] = {
+    0x04, 0x31, 0x2e, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x15, 0x00
+};
+
+static int idf_probe(AVProbeData *p)
+{
+    if (p->buf_size < sizeof(idf_magic))
+        return 0;
+    if (!memcmp(p->buf, idf_magic, sizeof(idf_magic)))
+        return AVPROBE_SCORE_MAX;
+    return 0;
+}
+
+static int idf_read_header(AVFormatContext *s)
+{
+    BinDemuxContext *bin = s->priv_data;
+    AVIOContext *pb = s->pb;
+    AVStream *st;
+    int got_width = 0;
+
+    if (!pb->seekable)
+        return AVERROR(EIO);
+
+    st = init_stream(s);
+    if (!st)
+        return AVERROR(ENOMEM);
+    st->codec->codec_id    = AV_CODEC_ID_IDF;
+
+    st->codec->extradata_size = 2 + 48 + 4096;
+    st->codec->extradata = av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+    if (!st->codec->extradata)
+        return AVERROR(ENOMEM);
+    st->codec->extradata[0] = 16;
+    st->codec->extradata[1] = BINTEXT_PALETTE|BINTEXT_FONT;
+
+    avio_seek(pb, avio_size(pb) - 4096 - 48, SEEK_SET);
+
+    if (avio_read(pb, st->codec->extradata + 2 + 48, 4096) < 0)
+        return AVERROR(EIO);
+    if (avio_read(pb, st->codec->extradata + 2, 48) < 0)
+        return AVERROR(EIO);
+
+    bin->fsize = avio_size(pb) - 12 - 4096 - 48;
+    ff_sauce_read(s, &bin->fsize, &got_width, 0);
+    if (!bin->video_size)
+        calculate_height(st->codec, bin->fsize);
+    avio_seek(pb, 12, SEEK_SET);
+    return 0;
+}
+#endif /* CONFIG_IDF_DEMUXER */
+
+static int read_packet(AVFormatContext *s,
+                           AVPacket *pkt)
+{
+    BinDemuxContext *bin = s->priv_data;
+
+    if (bin->fsize > 0) {
+        if (av_get_packet(s->pb, pkt, bin->fsize) < 0)
+            return AVERROR(EIO);
+        bin->fsize = -1; /* done */
+    } else if (!bin->fsize) {
+        if (url_feof(s->pb))
+            return AVERROR(EIO);
+        if (av_get_packet(s->pb, pkt, bin->chars_per_frame) < 0)
+            return AVERROR(EIO);
+    } else {
+        return AVERROR(EIO);
+    }
+
+    pkt->flags |= AV_PKT_FLAG_KEY;
+    return 0;
+}
+
+#define OFFSET(x) offsetof(BinDemuxContext, x)
+static const AVOption options[] = {
+    { "linespeed", "set simulated line speed (bytes per second)", OFFSET(chars_per_frame), AV_OPT_TYPE_INT, {.i64 = 6000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM},
+    { "video_size", "set video size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
+    { "framerate", "set framerate (frames per second)", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
+    { NULL },
+};
+
+#define CLASS(name) \
+(const AVClass[1]){{ \
+    .class_name     = name, \
+    .item_name      = av_default_item_name, \
+    .option         = options, \
+    .version        = LIBAVUTIL_VERSION_INT, \
+}}
+
+#if CONFIG_BINTEXT_DEMUXER
+AVInputFormat ff_bintext_demuxer = {
+    .name           = "bin",
+    .long_name      = NULL_IF_CONFIG_SMALL("Binary text"),
+    .priv_data_size = sizeof(BinDemuxContext),
+    .read_header    = bintext_read_header,
+    .read_packet    = read_packet,
+    .extensions     = "bin",
+    .priv_class     = CLASS("Binary text demuxer"),
+};
+#endif
+
+#if CONFIG_XBIN_DEMUXER
+AVInputFormat ff_xbin_demuxer = {
+    .name           = "xbin",
+    .long_name      = NULL_IF_CONFIG_SMALL("eXtended BINary text (XBIN)"),
+    .priv_data_size = sizeof(BinDemuxContext),
+    .read_probe     = xbin_probe,
+    .read_header    = xbin_read_header,
+    .read_packet    = read_packet,
+    .priv_class     = CLASS("eXtended BINary text (XBIN) demuxer"),
+};
+#endif
+
+#if CONFIG_ADF_DEMUXER
+AVInputFormat ff_adf_demuxer = {
+    .name           = "adf",
+    .long_name      = NULL_IF_CONFIG_SMALL("Artworx Data Format"),
+    .priv_data_size = sizeof(BinDemuxContext),
+    .read_header    = adf_read_header,
+    .read_packet    = read_packet,
+    .extensions     = "adf",
+    .priv_class     = CLASS("Artworx Data Format demuxer"),
+};
+#endif
+
+#if CONFIG_IDF_DEMUXER
+AVInputFormat ff_idf_demuxer = {
+    .name           = "idf",
+    .long_name      = NULL_IF_CONFIG_SMALL("iCE Draw File"),
+    .priv_data_size = sizeof(BinDemuxContext),
+    .read_probe     = idf_probe,
+    .read_header    = idf_read_header,
+    .read_packet    = read_packet,
+    .extensions     = "idf",
+    .priv_class     = CLASS("iCE Draw File demuxer"),
+};
+#endif
diff --git a/libavformat/bit.c b/libavformat/bit.c
new file mode 100644
index 0000000..03c6152
--- /dev/null
+++ b/libavformat/bit.c
@@ -0,0 +1,156 @@
+/*
+ * G.729 bit format muxer and demuxer
+ * Copyright (c) 2007-2008 Vladimir Voroshilov
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "avformat.h"
+#include "internal.h"
+#include "libavcodec/get_bits.h"
+#include "libavcodec/put_bits.h"
+
+#define MAX_FRAME_SIZE 10
+
+#define SYNC_WORD  0x6b21
+#define BIT_0      0x7f
+#define BIT_1      0x81
+
+static int probe(AVProbeData *p)
+{
+    int i, j;
+
+    if(p->buf_size < 0x40)
+        return 0;
+
+    for(i=0; i+3<p->buf_size && i< 10*0x50; ){
+        if(AV_RL16(&p->buf[0]) != SYNC_WORD)
+            return 0;
+        j=AV_RL16(&p->buf[2]);
+        if(j!=0x40 && j!=0x50)
+            return 0;
+        i+=j;
+    }
+    return AVPROBE_SCORE_MAX/2;
+}
+
+static int read_header(AVFormatContext *s)
+{
+    AVStream* st;
+
+    st=avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id=AV_CODEC_ID_G729;
+    st->codec->sample_rate=8000;
+    st->codec->block_align = 16;
+    st->codec->channels=1;
+
+    avpriv_set_pts_info(st, 64, 1, 100);
+    return 0;
+}
+
+static int read_packet(AVFormatContext *s,
+                          AVPacket *pkt)
+{
+    AVIOContext *pb = s->pb;
+    PutBitContext pbo;
+    uint16_t buf[8 * MAX_FRAME_SIZE + 2];
+    int packet_size;
+    uint16_t* src=buf;
+    int i, j, ret;
+    int64_t pos= avio_tell(pb);
+
+    if(url_feof(pb))
+        return AVERROR_EOF;
+
+    avio_rl16(pb); // sync word
+    packet_size = avio_rl16(pb) / 8;
+    if(packet_size > MAX_FRAME_SIZE)
+        return AVERROR_INVALIDDATA;
+
+    ret = avio_read(pb, (uint8_t*)buf, (8 * packet_size) * sizeof(uint16_t));
+    if(ret<0)
+        return ret;
+    if(ret != 8 * packet_size * sizeof(uint16_t))
+        return AVERROR(EIO);
+
+    av_new_packet(pkt, packet_size);
+
+    init_put_bits(&pbo, pkt->data, packet_size);
+    for(j=0; j < packet_size; j++)
+        for(i=0; i<8;i++)
+            put_bits(&pbo,1, AV_RL16(src++) == BIT_1 ? 1 : 0);
+
+    flush_put_bits(&pbo);
+
+    pkt->duration=1;
+    pkt->pos = pos;
+    return 0;
+}
+
+AVInputFormat ff_bit_demuxer = {
+    .name        = "bit",
+    .long_name   = NULL_IF_CONFIG_SMALL("G.729 BIT file format"),
+    .read_probe  = probe,
+    .read_header = read_header,
+    .read_packet = read_packet,
+    .extensions  = "bit",
+};
+
+#if CONFIG_MUXERS
+static int write_header(AVFormatContext *s)
+{
+    AVCodecContext *enc = s->streams[0]->codec;
+
+    enc->codec_id = AV_CODEC_ID_G729;
+    enc->channels = 1;
+    enc->bits_per_coded_sample = 16;
+    enc->block_align = (enc->bits_per_coded_sample * enc->channels) >> 3;
+
+    return 0;
+}
+
+static int write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    AVIOContext *pb = s->pb;
+    GetBitContext gb;
+    int i;
+
+    avio_wl16(pb, SYNC_WORD);
+    avio_wl16(pb, 8 * 10);
+
+    init_get_bits(&gb, pkt->data, 8*10);
+    for(i=0; i< 8 * 10; i++)
+        avio_wl16(pb, get_bits1(&gb) ? BIT_1 : BIT_0);
+    avio_flush(pb);
+
+    return 0;
+}
+
+AVOutputFormat ff_bit_muxer = {
+    .name         = "bit",
+    .long_name    = NULL_IF_CONFIG_SMALL("G.729 BIT file format"),
+    .mime_type    = "audio/bit",
+    .extensions   = "bit",
+    .audio_codec  = AV_CODEC_ID_G729,
+    .video_codec  = AV_CODEC_ID_NONE,
+    .write_header = write_header,
+    .write_packet = write_packet,
+};
+#endif
diff --git a/libavformat/bluray.c b/libavformat/bluray.c
new file mode 100644
index 0000000..d2c57aa
--- /dev/null
+++ b/libavformat/bluray.c
@@ -0,0 +1,235 @@
+/*
+ * BluRay (libbluray) protocol
+ *
+ * Copyright (c) 2012 Petri Hintukainen <phintuka <at> 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 <libbluray/bluray.h>
+
+#include "libavutil/avstring.h"
+#include "libavformat/avformat.h"
+#include "libavformat/url.h"
+#include "libavutil/opt.h"
+
+#define BLURAY_PROTO_PREFIX     "bluray:"
+#define MIN_PLAYLIST_LENGTH     180     /* 3 min */
+
+typedef struct {
+    const AVClass *class;
+
+    BLURAY *bd;
+
+    int playlist;
+    int angle;
+    int chapter;
+    /*int region;*/
+} BlurayContext;
+
+#define OFFSET(x) offsetof(BlurayContext, x)
+static const AVOption options[] = {
+{"playlist", "", OFFSET(playlist), AV_OPT_TYPE_INT, { .i64=-1 }, -1,  99999, AV_OPT_FLAG_DECODING_PARAM },
+{"angle",    "", OFFSET(angle),    AV_OPT_TYPE_INT, { .i64=0 },   0,   0xfe, AV_OPT_FLAG_DECODING_PARAM },
+{"chapter",  "", OFFSET(chapter),  AV_OPT_TYPE_INT, { .i64=1 },   1, 0xfffe, AV_OPT_FLAG_DECODING_PARAM },
+/*{"region",   "bluray player region code (1 = region A, 2 = region B, 4 = region C)", OFFSET(region), AV_OPT_TYPE_INT, { .i64=0 }, 0, 3, AV_OPT_FLAG_DECODING_PARAM },*/
+{NULL}
+};
+
+static const AVClass bluray_context_class = {
+    .class_name     = "bluray",
+    .item_name      = av_default_item_name,
+    .option         = options,
+    .version        = LIBAVUTIL_VERSION_INT,
+};
+
+
+static int check_disc_info(URLContext *h)
+{
+    BlurayContext *bd = h->priv_data;
+    const BLURAY_DISC_INFO *disc_info;
+
+    disc_info = bd_get_disc_info(bd->bd);
+    if (!disc_info) {
+        av_log(h, AV_LOG_ERROR, "bd_get_disc_info() failed\n");
+        return -1;
+    }
+
+    if (!disc_info->bluray_detected) {
+        av_log(h, AV_LOG_ERROR, "BluRay disc not detected\n");
+        return -1;
+    }
+
+    /* AACS */
+    if (disc_info->aacs_detected && !disc_info->aacs_handled) {
+        if (!disc_info->libaacs_detected) {
+            av_log(h, AV_LOG_ERROR,
+                   "Media stream encrypted with AACS, install and configure libaacs\n");
+        } else {
+            av_log(h, AV_LOG_ERROR, "Your libaacs can't decrypt this media\n");
+        }
+        return -1;
+    }
+
+    /* BD+ */
+    if (disc_info->bdplus_detected && !disc_info->bdplus_handled) {
+        /*
+        if (!disc_info->libbdplus_detected) {
+            av_log(h, AV_LOG_ERROR,
+                   "Media stream encrypted with BD+, install and configure libbdplus");
+        } else {
+        */
+            av_log(h, AV_LOG_ERROR, "Unable to decrypt BD+ encrypted media\n");
+        /*}*/
+        return -1;
+    }
+
+    return 0;
+}
+
+static int bluray_close(URLContext *h)
+{
+    BlurayContext *bd = h->priv_data;
+    if (bd->bd) {
+        bd_close(bd->bd);
+    }
+
+    return 0;
+}
+
+static int bluray_open(URLContext *h, const char *path, int flags)
+{
+    BlurayContext *bd = h->priv_data;
+    int num_title_idx;
+    const char *diskname = path;
+
+    av_strstart(path, BLURAY_PROTO_PREFIX, &diskname);
+
+    bd->bd = bd_open(diskname, NULL);
+    if (!bd->bd) {
+        av_log(h, AV_LOG_ERROR, "bd_open() failed\n");
+        return AVERROR(EIO);
+    }
+
+    /* check if disc can be played */
+    if (check_disc_info(h) < 0) {
+        return AVERROR(EIO);
+    }
+
+    /* setup player registers */
+    /* region code has no effect without menus
+    if (bd->region > 0 && bd->region < 5) {
+        av_log(h, AV_LOG_INFO, "setting region code to %d (%c)\n", bd->region, 'A' + (bd->region - 1));
+        bd_set_player_setting(bd->bd, BLURAY_PLAYER_SETTING_REGION_CODE, bd->region);
+    }
+    */
+
+    /* load title list */
+    num_title_idx = bd_get_titles(bd->bd, TITLES_RELEVANT, MIN_PLAYLIST_LENGTH);
+    av_log(h, AV_LOG_INFO, "%d usable playlists:\n", num_title_idx);
+    if (num_title_idx < 1) {
+        return AVERROR(EIO);
+    }
+
+    /* if playlist was not given, select longest playlist */
+    if (bd->playlist < 0) {
+        uint64_t duration = 0;
+        int i;
+        for (i = 0; i < num_title_idx; i++) {
+            BLURAY_TITLE_INFO *info = bd_get_title_info(bd->bd, i, 0);
+
+            av_log(h, AV_LOG_INFO, "playlist %05d.mpls (%d:%02d:%02d)\n",
+                   info->playlist,
+                   ((int)(info->duration / 90000) / 3600),
+                   ((int)(info->duration / 90000) % 3600) / 60,
+                   ((int)(info->duration / 90000) % 60));
+
+            if (info->duration > duration) {
+                bd->playlist = info->playlist;
+                duration = info->duration;
+            }
+
+            bd_free_title_info(info);
+        }
+        av_log(h, AV_LOG_INFO, "selected %05d.mpls\n", bd->playlist);
+    }
+
+    /* select playlist */
+    if (bd_select_playlist(bd->bd, bd->playlist) <= 0) {
+        av_log(h, AV_LOG_ERROR, "bd_select_playlist(%05d.mpls) failed\n", bd->playlist);
+        return AVERROR(EIO);
+    }
+
+    /* select angle */
+    if (bd->angle >= 0) {
+        bd_select_angle(bd->bd, bd->angle);
+    }
+
+    /* select chapter */
+    if (bd->chapter > 1) {
+        bd_seek_chapter(bd->bd, bd->chapter - 1);
+    }
+
+    return 0;
+}
+
+static int bluray_read(URLContext *h, unsigned char *buf, int size)
+{
+    BlurayContext *bd = h->priv_data;
+    int len;
+
+    if (!bd || !bd->bd) {
+        return AVERROR(EFAULT);
+    }
+
+    len = bd_read(bd->bd, buf, size);
+
+    return len;
+}
+
+static int64_t bluray_seek(URLContext *h, int64_t pos, int whence)
+{
+    BlurayContext *bd = h->priv_data;
+
+    if (!bd || !bd->bd) {
+        return AVERROR(EFAULT);
+    }
+
+    switch (whence) {
+    case SEEK_SET:
+    case SEEK_CUR:
+    case SEEK_END:
+        return bd_seek(bd->bd, pos);
+
+    case AVSEEK_SIZE:
+        return bd_get_title_size(bd->bd);
+    }
+
+    av_log(h, AV_LOG_ERROR, "Unsupported whence operation %d\n", whence);
+    return AVERROR(EINVAL);
+}
+
+
+URLProtocol ff_bluray_protocol = {
+    .name            = "bluray",
+    .url_close       = bluray_close,
+    .url_open        = bluray_open,
+    .url_read        = bluray_read,
+    .url_seek        = bluray_seek,
+    .priv_data_size  = sizeof(BlurayContext),
+    .priv_data_class = &bluray_context_class,
+};
diff --git a/libavformat/c93.c b/libavformat/c93.c
index 3f2a98f..66516e9 100644
--- a/libavformat/c93.c
+++ b/libavformat/c93.c
@@ -2,20 +2,20 @@
  * Interplay C93 demuxer
  * Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/cache.c b/libavformat/cache.c
new file mode 100644
index 0000000..2cfc396
--- /dev/null
+++ b/libavformat/cache.c
@@ -0,0 +1,138 @@
+/*
+ * Input cache protocol.
+ * Copyright (c) 2011 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
+ *
+ * Based on file.c by Fabrice Bellard
+ */
+
+/**
+ * @TODO
+ *      support non continuous caching
+ *      support keeping files
+ *      support filling with a background thread
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/file.h"
+#include "avformat.h"
+#include <fcntl.h>
+#if HAVE_IO_H
+#include <io.h>
+#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <sys/stat.h>
+#include <stdlib.h>
+#include "os_support.h"
+#include "url.h"
+
+typedef struct Context {
+    int fd;
+    int64_t end;
+    int64_t pos;
+    URLContext *inner;
+} Context;
+
+static int cache_open(URLContext *h, const char *arg, int flags)
+{
+    char *buffername;
+    Context *c= h->priv_data;
+
+    av_strstart(arg, "cache:", &arg);
+
+    c->fd = av_tempfile("ffcache", &buffername, 0, h);
+    if (c->fd < 0){
+        av_log(h, AV_LOG_ERROR, "Failed to create tempfile\n");
+        return c->fd;
+    }
+
+    unlink(buffername);
+    av_freep(&buffername);
+
+    return ffurl_open(&c->inner, arg, flags, &h->interrupt_callback, NULL);
+}
+
+static int cache_read(URLContext *h, unsigned char *buf, int size)
+{
+    Context *c= h->priv_data;
+    int r;
+
+    if(c->pos<c->end){
+        r = read(c->fd, buf, FFMIN(size, c->end - c->pos));
+        if(r>0)
+            c->pos += r;
+        return (-1 == r)?AVERROR(errno):r;
+    }else{
+        r = ffurl_read(c->inner, buf, size);
+        if(r > 0){
+            int r2= write(c->fd, buf, r);
+            av_assert0(r2==r); // FIXME handle cache failure
+            c->pos += r;
+            c->end += r;
+        }
+        return r;
+    }
+}
+
+static int64_t cache_seek(URLContext *h, int64_t pos, int whence)
+{
+    Context *c= h->priv_data;
+
+    if (whence == AVSEEK_SIZE) {
+        pos= ffurl_seek(c->inner, pos, whence);
+        if(pos <= 0){
+            pos= ffurl_seek(c->inner, -1, SEEK_END);
+            ffurl_seek(c->inner, c->end, SEEK_SET);
+            if(pos <= 0)
+                return c->end;
+        }
+        return pos;
+    }
+
+    pos= lseek(c->fd, pos, whence);
+    if(pos<0){
+        return pos;
+    }else if(pos <= c->end){
+        c->pos= pos;
+        return pos;
+    }else{
+        lseek(c->fd, c->pos, SEEK_SET);
+        return AVERROR(EPIPE);
+    }
+}
+
+static int cache_close(URLContext *h)
+{
+    Context *c= h->priv_data;
+    close(c->fd);
+    ffurl_close(c->inner);
+
+    return 0;
+}
+
+URLProtocol ff_cache_protocol = {
+    .name                = "cache",
+    .url_open            = cache_open,
+    .url_read            = cache_read,
+    .url_seek            = cache_seek,
+    .url_close           = cache_close,
+    .priv_data_size      = sizeof(Context),
+};
diff --git a/libavformat/caf.c b/libavformat/caf.c
index cf128d5..5f490d8 100644
--- a/libavformat/caf.c
+++ b/libavformat/caf.c
@@ -2,20 +2,20 @@
  * CAF common code
  * Copyright (c) 2007  Justin Ruggles
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -32,27 +32,34 @@
  * Known codec tags for CAF
  */
 const AVCodecTag ff_codec_caf_tags[] = {
-    { AV_CODEC_ID_AAC,             MKBETAG('a','a','c',' ') },
-    { AV_CODEC_ID_AC3,             MKBETAG('a','c','-','3') },
-    { AV_CODEC_ID_ALAC,            MKBETAG('a','l','a','c') },
+    { AV_CODEC_ID_AAC,             MKTAG('a','a','c',' ') },
+    { AV_CODEC_ID_AC3,             MKTAG('a','c','-','3') },
+    { AV_CODEC_ID_ADPCM_IMA_QT,    MKTAG('i','m','a','4') },
+    { AV_CODEC_ID_ADPCM_IMA_WAV,   MKTAG('m','s', 0, 17 ) },
+    { AV_CODEC_ID_ADPCM_MS,        MKTAG('m','s', 0,  2 ) },
+    { AV_CODEC_ID_ALAC,            MKTAG('a','l','a','c') },
+    { AV_CODEC_ID_AMR_NB,          MKTAG('s','a','m','r') },
   /* FIXME: use DV demuxer, as done in MOV */
-  /*{ AV_CODEC_ID_DVAUDIO,         MKBETAG('v','d','v','a') },*/
-  /*{ AV_CODEC_ID_DVAUDIO,         MKBETAG('d','v','c','a') },*/
-    { AV_CODEC_ID_ADPCM_IMA_QT,    MKBETAG('i','m','a','4') },
-    { AV_CODEC_ID_MACE3,           MKBETAG('M','A','C','3') },
-    { AV_CODEC_ID_MACE6,           MKBETAG('M','A','C','6') },
-    { AV_CODEC_ID_MP3,             MKBETAG('.','m','p','3') },
-    { AV_CODEC_ID_MP2,             MKBETAG('.','m','p','2') },
-    { AV_CODEC_ID_MP1,             MKBETAG('.','m','p','1') },
-    { AV_CODEC_ID_PCM_ALAW,        MKBETAG('a','l','a','w') },
-    { AV_CODEC_ID_PCM_MULAW,       MKBETAG('u','l','a','w') },
-    { AV_CODEC_ID_QCELP,           MKBETAG('Q','c','l','p') },
-    { AV_CODEC_ID_QDM2,            MKBETAG('Q','D','M','2') },
-    { AV_CODEC_ID_QDM2,            MKBETAG('Q','D','M','C') },
+  /*{ AV_CODEC_ID_DVAUDIO,         MKTAG('v','d','v','a') },*/
+  /*{ AV_CODEC_ID_DVAUDIO,         MKTAG('d','v','c','a') },*/
+    { AV_CODEC_ID_GSM,             MKTAG('a','g','s','m') },
+    { AV_CODEC_ID_GSM_MS,          MKTAG('m','s', 0, '1') },
+    { AV_CODEC_ID_MACE3,           MKTAG('M','A','C','3') },
+    { AV_CODEC_ID_MACE6,           MKTAG('M','A','C','6') },
+    { AV_CODEC_ID_MP1,             MKTAG('.','m','p','1') },
+    { AV_CODEC_ID_MP2,             MKTAG('.','m','p','2') },
+    { AV_CODEC_ID_MP3,             MKTAG('.','m','p','3') },
+    { AV_CODEC_ID_MP3,             MKTAG('m','s', 0 ,'U') },
+    { AV_CODEC_ID_PCM_ALAW,        MKTAG('a','l','a','w') },
+    { AV_CODEC_ID_PCM_MULAW,       MKTAG('u','l','a','w') },
+    { AV_CODEC_ID_QCELP,           MKTAG('Q','c','l','p') },
+    { AV_CODEC_ID_QDM2,            MKTAG('Q','D','M','2') },
+    { AV_CODEC_ID_QDM2,            MKTAG('Q','D','M','C') },
   /* currently unsupported codecs */
-  /*{ AC-3 over S/PDIF          MKBETAG('c','a','c','3') },*/
-  /*{ MPEG4CELP                 MKBETAG('c','e','l','p') },*/
-  /*{ MPEG4HVXC                 MKBETAG('h','v','x','c') },*/
-  /*{ MPEG4TwinVQ               MKBETAG('t','w','v','q') },*/
+  /*{ AC-3 over S/PDIF          MKTAG('c','a','c','3') },*/
+  /*{ MPEG4CELP                 MKTAG('c','e','l','p') },*/
+  /*{ MPEG4HVXC                 MKTAG('h','v','x','c') },*/
+  /*{ MPEG4TwinVQ               MKTAG('t','w','v','q') },*/
     { AV_CODEC_ID_NONE,            0 },
 };
+
diff --git a/libavformat/caf.h b/libavformat/caf.h
index 7ca4dc5..9c25f2c 100644
--- a/libavformat/caf.h
+++ b/libavformat/caf.h
@@ -2,20 +2,20 @@
  * CAF common code
  * Copyright (c) 2007  Justin Ruggles
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c
index b3cbb39..a576dac 100644
--- a/libavformat/cafdec.c
+++ b/libavformat/cafdec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2007 Justin Ruggles
  * Copyright (c) 2009 Peter Ross
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -70,7 +70,7 @@
     /* parse format description */
     st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
     st->codec->sample_rate = av_int2double(avio_rb64(pb));
-    st->codec->codec_tag   = avio_rb32(pb);
+    st->codec->codec_tag   = avio_rl32(pb);
     flags = avio_rb32(pb);
     caf->bytes_per_packet  = avio_rb32(pb);
     st->codec->block_align = caf->bytes_per_packet;
@@ -87,7 +87,7 @@
     }
 
     /* determine codec */
-    if (st->codec->codec_tag == MKBETAG('l','p','c','m'))
+    if (st->codec->codec_tag == MKTAG('l','p','c','m'))
         st->codec->codec_id = ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, (flags ^ 0x2) | 0x4);
     else
         st->codec->codec_id = ff_codec_get_id(ff_codec_caf_tags, st->codec->codec_tag);
@@ -212,7 +212,7 @@
     for (i = 0; i < nb_entries; i++) {
         char key[32];
         char value[1024];
-        avio_get_str(pb, INT_MAX, key,   sizeof(key));
+        avio_get_str(pb, INT_MAX, key, sizeof(key));
         avio_get_str(pb, INT_MAX, value, sizeof(value));
         av_dict_set(&s->metadata, key, value, 0);
     }
@@ -245,7 +245,7 @@
 
     /* parse each chunk */
     found_data = 0;
-    while (!pb->eof_reached) {
+    while (!url_feof(pb)) {
 
         /* stop at data chunk if seeking is not supported or
            data chunk size is unknown */
@@ -254,7 +254,7 @@
 
         tag  = avio_rb32(pb);
         size = avio_rb64(pb);
-        if (pb->eof_reached)
+        if (url_feof(pb))
             break;
 
         switch (tag) {
@@ -290,8 +290,8 @@
 
         default:
 #define _(x) ((x) >= ' ' ? (x) : ' ')
-            av_log(s, AV_LOG_WARNING, "skipping CAF chunk: %08X (%c%c%c%c)\n",
-                tag, _(tag>>24), _((tag>>16)&0xFF), _((tag>>8)&0xFF), _(tag&0xFF));
+            av_log(s, AV_LOG_WARNING, "skipping CAF chunk: %08X (%c%c%c%c), size %"PRId64"\n",
+                tag, _(tag>>24), _((tag>>16)&0xFF), _((tag>>8)&0xFF), _(tag&0xFF), size);
 #undef _
         case MKBETAG('f','r','e','e'):
             if (size < 0)
@@ -336,7 +336,7 @@
     int res, pkt_size = 0, pkt_frames = 0;
     int64_t left      = CAF_MAX_PKT_SIZE;
 
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return AVERROR(EIO);
 
     /* don't read past end of data chunk */
diff --git a/libavformat/cafenc.c b/libavformat/cafenc.c
new file mode 100644
index 0000000..fa8d583
--- /dev/null
+++ b/libavformat/cafenc.c
@@ -0,0 +1,262 @@
+/*
+ * Core Audio Format muxer
+ * Copyright (c) 2011 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 "avformat.h"
+#include "caf.h"
+#include "riff.h"
+#include "isom.h"
+#include "avio_internal.h"
+#include "libavutil/intfloat.h"
+
+typedef struct {
+    int64_t data;
+    uint8_t *pkt_sizes;
+    int size_buffer_size;
+    int size_entries_used;
+    int packets;
+} CAFContext;
+
+static uint32_t codec_flags(enum AVCodecID codec_id) {
+    switch (codec_id) {
+    case AV_CODEC_ID_PCM_F32BE:
+    case AV_CODEC_ID_PCM_F64BE:
+        return 1; //< kCAFLinearPCMFormatFlagIsFloat
+    case AV_CODEC_ID_PCM_S16LE:
+    case AV_CODEC_ID_PCM_S24LE:
+    case AV_CODEC_ID_PCM_S32LE:
+        return 2; //< kCAFLinearPCMFormatFlagIsLittleEndian
+    case AV_CODEC_ID_PCM_F32LE:
+    case AV_CODEC_ID_PCM_F64LE:
+        return 3; //< kCAFLinearPCMFormatFlagIsFloat | kCAFLinearPCMFormatFlagIsLittleEndian
+    default:
+        return 0;
+    }
+}
+
+static uint32_t samples_per_packet(enum AVCodecID codec_id, int channels) {
+    switch (codec_id) {
+    case AV_CODEC_ID_PCM_S8:
+    case AV_CODEC_ID_PCM_S16LE:
+    case AV_CODEC_ID_PCM_S16BE:
+    case AV_CODEC_ID_PCM_S24LE:
+    case AV_CODEC_ID_PCM_S24BE:
+    case AV_CODEC_ID_PCM_S32LE:
+    case AV_CODEC_ID_PCM_S32BE:
+    case AV_CODEC_ID_PCM_F32LE:
+    case AV_CODEC_ID_PCM_F32BE:
+    case AV_CODEC_ID_PCM_F64LE:
+    case AV_CODEC_ID_PCM_F64BE:
+    case AV_CODEC_ID_PCM_ALAW:
+    case AV_CODEC_ID_PCM_MULAW:
+        return 1;
+    case AV_CODEC_ID_MACE3:
+    case AV_CODEC_ID_MACE6:
+        return 6;
+    case AV_CODEC_ID_ADPCM_IMA_QT:
+        return 64;
+    case AV_CODEC_ID_AMR_NB:
+    case AV_CODEC_ID_GSM:
+    case AV_CODEC_ID_QCELP:
+        return 160;
+    case AV_CODEC_ID_GSM_MS:
+        return 320;
+    case AV_CODEC_ID_MP1:
+        return 384;
+    case AV_CODEC_ID_MP2:
+    case AV_CODEC_ID_MP3:
+        return 1152;
+    case AV_CODEC_ID_AC3:
+        return 1536;
+    case AV_CODEC_ID_ALAC:
+    case AV_CODEC_ID_QDM2:
+        return 4096;
+    case AV_CODEC_ID_ADPCM_IMA_WAV:
+        return (1024 - 4 * channels) * 8 / (4 * channels) + 1;
+    case AV_CODEC_ID_ADPCM_MS:
+        return (1024 - 7 * channels) * 2 / channels + 2;
+    default:
+        return 0;
+    }
+}
+
+static int caf_write_header(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    AVCodecContext *enc = s->streams[0]->codec;
+    CAFContext *caf = s->priv_data;
+    unsigned int codec_tag = ff_codec_get_tag(ff_codec_caf_tags, enc->codec_id);
+
+    switch (enc->codec_id) {
+    case AV_CODEC_ID_AAC:
+    case AV_CODEC_ID_AC3:
+        av_log(s, AV_LOG_ERROR, "muxing codec currently unsupported\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
+    switch (enc->codec_id) {
+    case AV_CODEC_ID_PCM_S8:
+    case AV_CODEC_ID_PCM_S16LE:
+    case AV_CODEC_ID_PCM_S16BE:
+    case AV_CODEC_ID_PCM_S24LE:
+    case AV_CODEC_ID_PCM_S24BE:
+    case AV_CODEC_ID_PCM_S32LE:
+    case AV_CODEC_ID_PCM_S32BE:
+    case AV_CODEC_ID_PCM_F32LE:
+    case AV_CODEC_ID_PCM_F32BE:
+    case AV_CODEC_ID_PCM_F64LE:
+    case AV_CODEC_ID_PCM_F64BE:
+    case AV_CODEC_ID_PCM_ALAW:
+    case AV_CODEC_ID_PCM_MULAW:
+        codec_tag = MKTAG('l','p','c','m');
+    }
+
+    if (!codec_tag) {
+        av_log(s, AV_LOG_ERROR, "unsupported codec\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (!enc->block_align && !pb->seekable) {
+        av_log(s, AV_LOG_ERROR, "Muxing variable packet size not supported on non seekable output\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    ffio_wfourcc(pb, "caff"); //< mFileType
+    avio_wb16(pb, 1);         //< mFileVersion
+    avio_wb16(pb, 0);         //< mFileFlags
+
+    ffio_wfourcc(pb, "desc");                         //< Audio Description chunk
+    avio_wb64(pb, 32);                                //< mChunkSize
+    avio_wb64(pb, av_double2int(enc->sample_rate));   //< mSampleRate
+    avio_wl32(pb, codec_tag);                         //< mFormatID
+    avio_wb32(pb, codec_flags(enc->codec_id));        //< mFormatFlags
+    avio_wb32(pb, enc->block_align);                  //< mBytesPerPacket
+    avio_wb32(pb, samples_per_packet(enc->codec_id, enc->channels)); //< mFramesPerPacket
+    avio_wb32(pb, enc->channels);                     //< mChannelsPerFrame
+    avio_wb32(pb, av_get_bits_per_sample(enc->codec_id)); //< mBitsPerChannel
+
+    if (enc->channel_layout) {
+        ffio_wfourcc(pb, "chan");
+        avio_wb64(pb, 12);
+        ff_mov_write_chan(pb, enc->channel_layout);
+    }
+
+    if (enc->codec_id == AV_CODEC_ID_ALAC) {
+        ffio_wfourcc(pb, "kuki");
+        avio_wb64(pb, 12 + enc->extradata_size);
+        avio_write(pb, "\0\0\0\14frmaalac", 12);
+        avio_write(pb, enc->extradata, enc->extradata_size);
+    } else if (enc->codec_id == AV_CODEC_ID_AMR_NB) {
+        ffio_wfourcc(pb, "kuki");
+        avio_wb64(pb, 29);
+        avio_write(pb, "\0\0\0\14frmasamr", 12);
+        avio_wb32(pb, 0x11); /* size */
+        avio_write(pb, "samrFFMP", 8);
+        avio_w8(pb, 0); /* decoder version */
+
+        avio_wb16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */
+        avio_w8(pb, 0x00); /* Mode change period (no restriction) */
+        avio_w8(pb, 0x01); /* Frames per sample */
+    } else if (enc->codec_id == AV_CODEC_ID_QDM2) {
+        ffio_wfourcc(pb, "kuki");
+        avio_wb64(pb, enc->extradata_size);
+        avio_write(pb, enc->extradata, enc->extradata_size);
+    }
+
+    ffio_wfourcc(pb, "data"); //< Audio Data chunk
+    caf->data = avio_tell(pb);
+    avio_wb64(pb, -1);        //< mChunkSize
+    avio_wb32(pb, 0);         //< mEditCount
+
+    avio_flush(pb);
+    return 0;
+}
+
+static int caf_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    CAFContext *caf = s->priv_data;
+
+    avio_write(s->pb, pkt->data, pkt->size);
+    if (!s->streams[0]->codec->block_align) {
+        void *pkt_sizes = caf->pkt_sizes;
+        int i, alloc_size = caf->size_entries_used + 5;
+        if (alloc_size < 0) {
+            caf->pkt_sizes = NULL;
+        } else {
+            caf->pkt_sizes = av_fast_realloc(caf->pkt_sizes,
+                                             &caf->size_buffer_size,
+                                             alloc_size);
+        }
+        if (!caf->pkt_sizes) {
+            av_free(pkt_sizes);
+            return AVERROR(ENOMEM);
+        }
+        for (i = 4; i > 0; i--) {
+            unsigned top = pkt->size >> i * 7;
+            if (top)
+                caf->pkt_sizes[caf->size_entries_used++] = 128 | top;
+        }
+        caf->pkt_sizes[caf->size_entries_used++] = pkt->size & 127;
+        caf->packets++;
+    }
+    return 0;
+}
+
+static int caf_write_trailer(AVFormatContext *s)
+{
+    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);
+        avio_wb64(pb, file_size - caf->data - 8);
+        avio_seek(pb, file_size, SEEK_SET);
+        if (!enc->block_align) {
+            ffio_wfourcc(pb, "pakt");
+            avio_wb64(pb, caf->size_entries_used + 24);
+            avio_wb64(pb, caf->packets); ///< mNumberPackets
+            avio_wb64(pb, caf->packets * samples_per_packet(enc->codec_id, enc->channels)); ///< mNumberValidFrames
+            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);
+    }
+    return 0;
+}
+
+AVOutputFormat ff_caf_muxer = {
+    .name           = "caf",
+    .long_name      = NULL_IF_CONFIG_SMALL("Apple Core Audio Format"),
+    .mime_type      = "audio/x-caf",
+    .extensions     = "caf",
+    .priv_data_size = sizeof(CAFContext),
+    .audio_codec    = AV_CODEC_ID_PCM_S16BE,
+    .video_codec    = AV_CODEC_ID_NONE,
+    .write_header   = caf_write_header,
+    .write_packet   = caf_write_packet,
+    .write_trailer  = caf_write_trailer,
+    .codec_tag= (const AVCodecTag* const []){ff_codec_caf_tags, 0},
+};
diff --git a/libavformat/cavsvideodec.c b/libavformat/cavsvideodec.c
index ed9cdb2..c035128 100644
--- a/libavformat/cavsvideodec.c
+++ b/libavformat/cavsvideodec.c
@@ -2,20 +2,20 @@
  * RAW Chinese AVS video demuxer
  * Copyright (c) 2009  Stefan Gehrer <stefan.gehrer@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/cdg.c b/libavformat/cdg.c
index 974880a..2d40d3d 100644
--- a/libavformat/cdg.c
+++ b/libavformat/cdg.c
@@ -2,20 +2,20 @@
  * CD Graphics Demuxer
  * Copyright (c) 2009 Michael Tison
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -60,6 +60,12 @@
     }
 
     pkt->stream_index = 0;
+    pkt->dts=
+    pkt->pts= pkt->pos / CDG_PACKET_SIZE;
+
+    if(ret>5 && (pkt->data[0]&0x3F) == 9 && (pkt->data[1]&0x3F)==1 && !(pkt->data[2+2+1] & 0x0F)){
+        pkt->flags = AV_PKT_FLAG_KEY;
+    }
     return ret;
 }
 
@@ -68,5 +74,6 @@
     .long_name      = NULL_IF_CONFIG_SMALL("CD Graphics"),
     .read_header    = read_header,
     .read_packet    = read_packet,
+    .flags          = AVFMT_GENERIC_INDEX,
     .extensions     = "cdg",
 };
diff --git a/libavformat/cdxl.c b/libavformat/cdxl.c
index d61cbd9..b65011a 100644
--- a/libavformat/cdxl.c
+++ b/libavformat/cdxl.c
@@ -2,20 +2,20 @@
  * CDXL demuxer
  * Copyright (c) 2011-2012 Paul B Mahol
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/concat.c b/libavformat/concat.c
index 24c50c1..f97354c 100644
--- a/libavformat/concat.c
+++ b/libavformat/concat.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2007 Wolfram Gloger
  * Copyright (c) 2010 Michele Orrù
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/crcenc.c b/libavformat/crcenc.c
index 3b30cc9..ac06380 100644
--- a/libavformat/crcenc.c
+++ b/libavformat/crcenc.c
@@ -2,20 +2,20 @@
  * CRC encoder (for codec/format testing)
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -57,7 +57,6 @@
 AVOutputFormat ff_crc_muxer = {
     .name              = "crc",
     .long_name         = NULL_IF_CONFIG_SMALL("CRC testing"),
-    .extensions        = "",
     .priv_data_size    = sizeof(CRCState),
     .audio_codec       = AV_CODEC_ID_PCM_S16LE,
     .video_codec       = AV_CODEC_ID_RAWVIDEO,
diff --git a/libavformat/crypto.c b/libavformat/crypto.c
index 3bc33f2..5d518be 100644
--- a/libavformat/crypto.c
+++ b/libavformat/crypto.c
@@ -59,7 +59,7 @@
     .version        = LIBAVUTIL_VERSION_INT,
 };
 
-static int crypto_open(URLContext *h, const char *uri, int flags)
+static int crypto_open2(URLContext *h, const char *uri, int flags, AVDictionary **options)
 {
     const char *nested_url;
     int ret = 0;
@@ -83,7 +83,7 @@
         goto err;
     }
     if ((ret = ffurl_open(&c->hd, nested_url, AVIO_FLAG_READ,
-                          &h->interrupt_callback, NULL)) < 0) {
+                          &h->interrupt_callback, options)) < 0) {
         av_log(h, AV_LOG_ERROR, "Unable to open input\n");
         goto err;
     }
@@ -161,7 +161,7 @@
 
 URLProtocol ff_crypto_protocol = {
     .name            = "crypto",
-    .url_open        = crypto_open,
+    .url_open2       = crypto_open2,
     .url_read        = crypto_read,
     .url_close       = crypto_close,
     .priv_data_size  = sizeof(CryptoContext),
diff --git a/libavformat/cutils.c b/libavformat/cutils.c
index f58e152..0458a2d 100644
--- a/libavformat/cutils.c
+++ b/libavformat/cutils.c
@@ -2,46 +2,25 @@
  * various simple utilities for libavformat
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
 #include "internal.h"
 
-/* add one element to a dynamic array */
-void ff_dynarray_add(intptr_t **tab_ptr, int *nb_ptr, intptr_t elem)
-{
-    /* see similar avconv.c:grow_array() */
-    int nb, nb_alloc;
-    intptr_t *tab;
-
-    nb = *nb_ptr;
-    tab = *tab_ptr;
-    if ((nb & (nb - 1)) == 0) {
-        if (nb == 0)
-            nb_alloc = 1;
-        else
-            nb_alloc = nb * 2;
-        tab = av_realloc(tab, nb_alloc * sizeof(intptr_t));
-        *tab_ptr = tab;
-    }
-    tab[nb++] = elem;
-    *nb_ptr = nb;
-}
-
 #define ISLEAP(y) (((y) % 4 == 0) && (((y) % 100) != 0 || ((y) % 400) == 0))
 #define LEAPS_COUNT(y) ((y)/4 - (y)/100 + (y)/400)
 
diff --git a/libavformat/daud.c b/libavformat/daud.c
index dda83f9..bfbcf0a 100644
--- a/libavformat/daud.c
+++ b/libavformat/daud.c
@@ -2,20 +2,20 @@
  * D-Cinema audio demuxer
  * Copyright (c) 2005 Reimar Döffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
@@ -38,7 +38,7 @@
 static int daud_packet(AVFormatContext *s, AVPacket *pkt) {
     AVIOContext *pb = s->pb;
     int ret, size;
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return AVERROR(EIO);
     size = avio_rb16(pb);
     avio_rb16(pb); // unknown
@@ -75,7 +75,7 @@
     .long_name      = NULL_IF_CONFIG_SMALL("D-Cinema audio"),
     .read_header    = daud_header,
     .read_packet    = daud_packet,
-    .extensions     = "302",
+    .extensions     = "302,daud",
 };
 #endif
 
diff --git a/libavformat/dfa.c b/libavformat/dfa.c
index fa32d1f..8cf2f24 100644
--- a/libavformat/dfa.c
+++ b/libavformat/dfa.c
@@ -2,20 +2,20 @@
  * Chronomaster DFA Format Demuxer
  * Copyright (c) 2011 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/diracdec.c b/libavformat/diracdec.c
index f275212..6636ead 100644
--- a/libavformat/diracdec.c
+++ b/libavformat/diracdec.c
@@ -2,20 +2,20 @@
  * RAW Dirac demuxer
  * Copyright (c) 2007 Marco Gerards <marco@gnu.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/dnxhddec.c b/libavformat/dnxhddec.c
index 8bb6814..7b55400 100644
--- a/libavformat/dnxhddec.c
+++ b/libavformat/dnxhddec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@gmail.com>
  * Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -37,7 +37,7 @@
     if (!w || !h)
         return 0;
     compression_id = AV_RB32(p->buf + 0x28);
-    if (compression_id < 1237 || compression_id > 1253)
+    if (compression_id < 1235 || compression_id > 1253)
         return 0;
     return AVPROBE_SCORE_MAX;
 }
diff --git a/libavformat/dsicin.c b/libavformat/dsicin.c
index 8cba461..afc010a 100644
--- a/libavformat/dsicin.c
+++ b/libavformat/dsicin.c
@@ -2,20 +2,20 @@
  * Delphine Software International CIN File Demuxer
  * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -27,6 +27,7 @@
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "internal.h"
+#include "avio_internal.h"
 
 
 typedef struct CinFileHeader {
@@ -147,7 +148,7 @@
     hdr->video_frame_size = avio_rl32(pb);
     hdr->audio_frame_size = avio_rl32(pb);
 
-    if (pb->eof_reached || pb->error)
+    if (url_feof(pb) || pb->error)
         return AVERROR(EIO);
 
     if (avio_rl32(pb) != 0xAA55AA55)
@@ -179,6 +180,8 @@
         /* palette and video packet */
         pkt_size = (palette_type + 3) * hdr->pal_colors_count + hdr->video_frame_size;
 
+        pkt_size = ffio_limit(pb, pkt_size);
+
         ret = av_new_packet(pkt, 4 + pkt_size);
         if (ret < 0)
             return ret;
diff --git a/libavformat/dtsdec.c b/libavformat/dtsdec.c
index 28cccd3..5c05758 100644
--- a/libavformat/dtsdec.c
+++ b/libavformat/dtsdec.c
@@ -2,20 +2,20 @@
  * RAW DTS demuxer
  * Copyright (c) 2008 Benjamin Larsson
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/dtshddec.c b/libavformat/dtshddec.c
new file mode 100644
index 0000000..55c4ca6
--- /dev/null
+++ b/libavformat/dtshddec.c
@@ -0,0 +1,139 @@
+/*
+ * Raw DTS-HD 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 "libavutil/dict.h"
+#include "avformat.h"
+
+#define AUPR_HDR 0x415550522D484452
+#define AUPRINFO 0x41555052494E464F
+#define BITSHVTB 0x4249545348565442
+#define BLACKOUT 0x424C41434B4F5554
+#define BRANCHPT 0x4252414E43485054
+#define BUILDVER 0x4255494C44564552
+#define CORESSMD 0x434F524553534D44
+#define DTSHDHDR 0x4454534844484452
+#define EXTSS_MD 0x45585453535f4d44
+#define FILEINFO 0x46494C45494E464F
+#define NAVI_TBL 0x4E4156492D54424C
+#define STRMDATA 0x5354524D44415441
+#define TIMECODE 0x54494D45434F4445
+
+typedef struct DTSHDDemuxContext {
+    uint64_t    data_end;
+} DTSHDDemuxContext;
+
+static int dtshd_probe(AVProbeData *p)
+{
+    if (AV_RB64(p->buf) == DTSHDHDR)
+        return AVPROBE_SCORE_MAX;
+    return 0;
+}
+
+static int dtshd_read_header(AVFormatContext *s)
+{
+    DTSHDDemuxContext *dtshd = s->priv_data;
+    AVIOContext *pb = s->pb;
+    uint64_t chunk_type, chunk_size;
+    AVStream *st;
+    int ret;
+    char *value;
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id   = AV_CODEC_ID_DTS;
+    st->need_parsing      = AVSTREAM_PARSE_FULL_RAW;
+
+    while (!url_feof(pb)) {
+        chunk_type = avio_rb64(pb);
+        chunk_size = avio_rb64(pb);
+
+        if (chunk_size < 4) {
+            av_log(s, AV_LOG_ERROR, "chunk size too small\n");
+            return AVERROR_INVALIDDATA;
+        }
+        if (chunk_size > ((uint64_t)1 << 61)) {
+            av_log(s, AV_LOG_ERROR, "chunk size too big\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        switch (chunk_type) {
+        case STRMDATA:
+            dtshd->data_end = chunk_size + avio_tell(pb);
+            if (dtshd->data_end <= chunk_size)
+                return AVERROR_INVALIDDATA;
+            return 0;
+            break;
+        case FILEINFO:
+            if (chunk_size > INT_MAX)
+                goto skip;
+            value = av_malloc(chunk_size);
+            if (!value)
+                goto skip;
+            avio_read(pb, value, chunk_size);
+            value[chunk_size - 1] = 0;
+            av_dict_set(&s->metadata, "fileinfo", value,
+                        AV_DICT_DONT_STRDUP_VAL);
+            break;
+        default:
+skip:
+            ret = avio_skip(pb, chunk_size);
+            if (ret < 0)
+                return ret;
+        };
+    }
+
+    return AVERROR_EOF;
+}
+
+static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    DTSHDDemuxContext *dtshd = s->priv_data;
+    int64_t size, left;
+    int ret;
+
+    left = dtshd->data_end - avio_tell(s->pb);
+    size = FFMIN(left, 1024);
+    if (size <= 0)
+        return AVERROR_EOF;
+
+    ret = av_get_packet(s->pb, pkt, size);
+    if (ret < 0)
+        return ret;
+
+    pkt->stream_index = 0;
+
+    return ret;
+}
+
+AVInputFormat ff_dtshd_demuxer = {
+    .name           = "dtshd",
+    .long_name      = NULL_IF_CONFIG_SMALL("raw DTS-HD"),
+    .priv_data_size = sizeof(DTSHDDemuxContext),
+    .read_probe     = dtshd_probe,
+    .read_header    = dtshd_read_header,
+    .read_packet    = raw_read_packet,
+    .flags          = AVFMT_GENERIC_INDEX,
+    .extensions     = "dtshd",
+    .raw_codec_id   = AV_CODEC_ID_DTS,
+};
diff --git a/libavformat/dv.c b/libavformat/dv.c
index 70786b1..01665c2 100644
--- a/libavformat/dv.c
+++ b/libavformat/dv.c
@@ -12,20 +12,20 @@
  * Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com>
  * Funded by BBC Research & Development
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include <time.h>
@@ -35,7 +35,9 @@
 #include "libavcodec/dvdata.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/timecode.h"
 #include "dv.h"
+#include "libavutil/avassert.h"
 
 struct DVDemuxContext {
     const DVprofile*  sys;    /* Current DV profile. E.g.: 525/60, 625/50 */
@@ -88,6 +90,9 @@
     case dv_video_control:
         offs = (80*5 + 48 + 5);
         break;
+    case dv_timecode:
+        offs = (80*1 + 3 + 3);
+        break;
     default:
         return NULL;
     }
@@ -138,7 +143,7 @@
 
     /* for each DIF channel */
     for (chan = 0; chan < sys->n_difchan; chan++) {
-        /* next stereo channel (50Mbps and 100Mbps only) */
+        av_assert0(ipcm<4);
         pcm = ppcm[ipcm++];
         if (!pcm)
             break;
@@ -148,6 +153,7 @@
             frame += 6 * 80; /* skip DIF segment header */
             if (quant == 1 && i == half_ch) {
                 /* next stereo channel (12bit mode only) */
+                av_assert0(ipcm<4);
                 pcm = ppcm[ipcm++];
                 if (!pcm)
                     break;
@@ -267,11 +273,6 @@
         avpriv_set_pts_info(c->vst, 64, c->sys->time_base.num,
                         c->sys->time_base.den);
         avctx->time_base= c->sys->time_base;
-        if (!avctx->width){
-            avctx->width = c->sys->width;
-            avctx->height = c->sys->height;
-        }
-        avctx->pix_fmt = c->sys->pix_fmt;
 
         /* finding out SAR is a little bit messy */
         vsc_pack = dv_extract_pack(frame, dv_video_control);
@@ -286,6 +287,22 @@
     return size;
 }
 
+static int dv_extract_timecode(DVDemuxContext* c, uint8_t* frame, char *tc)
+{
+    const uint8_t *tc_pack;
+
+    // For PAL systems, drop frame bit is replaced by an arbitrary
+    // bit so its value should not be considered. Drop frame timecode
+    // is only relevant for NTSC systems.
+    int prevent_df = c->sys->ltc_divisor == 25 || c->sys->ltc_divisor == 50;
+
+    tc_pack = dv_extract_pack(frame, dv_timecode);
+    if (!tc_pack)
+        return 0;
+    av_timecode_make_smpte_tc_string(tc, AV_RB32(tc_pack + 1), prevent_df);
+    return 1;
+}
+
 /*
  * The following 3 functions constitute our interface to the world
  */
@@ -331,7 +348,7 @@
 }
 
 int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
-                      uint8_t* buf, int buf_size)
+                      uint8_t* buf, int buf_size, int64_t pos)
 {
     int size, i;
     uint8_t *ppcm[4] = {0};
@@ -346,6 +363,7 @@
     /* FIXME: in case of no audio/bad audio we have to do something */
     size = dv_extract_audio_info(c, buf);
     for (i = 0; i < c->ach; i++) {
+       c->audio_pkt[i].pos  = pos;
        c->audio_pkt[i].size = size;
        c->audio_pkt[i].pts  = c->abytes * 30000*8 / c->ast[i]->codec->bit_rate;
        ppcm[i] = c->audio_buf[i];
@@ -370,6 +388,7 @@
     size = dv_extract_video_info(c, buf);
     av_init_packet(pkt);
     pkt->data         = buf;
+    pkt->pos          = pos;
     pkt->size         = size;
     pkt->flags       |= AV_PKT_FLAG_KEY;
     pkt->stream_index = c->vst->id;
@@ -400,9 +419,13 @@
 void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)
 {
     c->frames= frame_offset;
-    if (c->ach)
+    if (c->ach) {
+        if (c->sys) {
         c->abytes= av_rescale_q(c->frames, c->sys->time_base,
                                 (AVRational){8, c->ast[0]->codec->bit_rate});
+        }else
+            av_log(c->fctx, AV_LOG_ERROR, "cannot adjust audio bytes\n");
+    }
     c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
     c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
 }
@@ -416,6 +439,38 @@
     uint8_t         buf[DV_MAX_FRAME_SIZE];
 } RawDVContext;
 
+static int dv_read_timecode(AVFormatContext *s) {
+    int ret;
+    char timecode[AV_TIMECODE_STR_SIZE];
+    int64_t pos = avio_tell(s->pb);
+
+    // Read 3 DIF blocks: Header block and 2 Subcode blocks.
+    int partial_frame_size = 3 * 80;
+    uint8_t *partial_frame = av_mallocz(sizeof(*partial_frame) *
+                                        partial_frame_size);
+
+    RawDVContext *c = s->priv_data;
+    ret = avio_read(s->pb, partial_frame, partial_frame_size);
+    if (ret < 0)
+        goto finish;
+
+    if (ret < partial_frame_size) {
+        ret = -1;
+        goto finish;
+    }
+
+    ret = dv_extract_timecode(c->dv_demux, partial_frame, timecode);
+    if (ret)
+        av_dict_set(&s->metadata, "timecode", timecode, 0);
+    else if (ret < 0)
+        av_log(s, AV_LOG_ERROR, "Detected timecode is invalid\n");
+
+finish:
+    av_free(partial_frame);
+    avio_seek(s->pb, pos, SEEK_SET);
+    return ret;
+}
+
 static int dv_read_header(AVFormatContext *s)
 {
     unsigned state, marker_pos = 0;
@@ -427,7 +482,7 @@
 
     state = avio_rb32(s->pb);
     while ((state & 0xffffff7f) != 0x1f07003f) {
-        if (s->pb->eof_reached) {
+        if (url_feof(s->pb)) {
             av_log(s, AV_LOG_ERROR, "Cannot find DV header.\n");
             return -1;
         }
@@ -442,7 +497,7 @@
     }
     AV_WB32(c->buf, state);
 
-    if (avio_read(s->pb, c->buf + 4, DV_PROFILE_BYTES - 4) <= 0 ||
+    if (avio_read(s->pb, c->buf + 4, DV_PROFILE_BYTES - 4) != DV_PROFILE_BYTES - 4 ||
         avio_seek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0)
         return AVERROR(EIO);
 
@@ -455,6 +510,9 @@
     s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size, (AVRational){8,1},
                                c->dv_demux->sys->time_base);
 
+    if (s->pb->seekable)
+        dv_read_timecode(s);
+
     return 0;
 }
 
@@ -467,13 +525,14 @@
     size = avpriv_dv_get_packet(c->dv_demux, pkt);
 
     if (size < 0) {
+        int64_t pos = avio_tell(s->pb);
         if (!c->dv_demux->sys)
             return AVERROR(EIO);
         size = c->dv_demux->sys->frame_size;
         if (avio_read(s->pb, c->buf, size) <= 0)
             return AVERROR(EIO);
 
-        size = avpriv_dv_produce_packet(c->dv_demux, pkt, c->buf, size);
+        size = avpriv_dv_produce_packet(c->dv_demux, pkt, c->buf, size, pos);
     }
 
     return size;
diff --git a/libavformat/dv.h b/libavformat/dv.h
index e8b2d37..160c6ab 100644
--- a/libavformat/dv.h
+++ b/libavformat/dv.h
@@ -8,20 +8,20 @@
  * Raw DV format
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -33,7 +33,7 @@
 typedef struct DVDemuxContext DVDemuxContext;
 DVDemuxContext* avpriv_dv_init_demux(AVFormatContext* s);
 int avpriv_dv_get_packet(DVDemuxContext*, AVPacket *);
-int avpriv_dv_produce_packet(DVDemuxContext*, AVPacket*, uint8_t*, int);
+int avpriv_dv_produce_packet(DVDemuxContext*, AVPacket*, uint8_t*, int, int64_t);
 void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset);
 
 typedef struct DVMuxContext DVMuxContext;
diff --git a/libavformat/dvenc.c b/libavformat/dvenc.c
index 27a444e..a132edb 100644
--- a/libavformat/dvenc.c
+++ b/libavformat/dvenc.c
@@ -11,20 +11,20 @@
  * 50 Mbps (DVCPRO50) support
  * Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include <time.h>
@@ -37,10 +37,14 @@
 #include "dv.h"
 #include "libavutil/fifo.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
+#include "libavutil/timecode.h"
 
 #define MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
 
 struct DVMuxContext {
+    AVClass          *av_class;
     const DVprofile*  sys;           /* current DV profile, e.g.: 525/60, 625/50 */
     int               n_ast;         /* number of stereo audio streams (up to 2) */
     AVStream         *ast[2];        /* stereo audio streams */
@@ -50,6 +54,7 @@
     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 */
+    AVTimecode        tc;            /* timecode context */
 };
 
 static const int dv_aaux_packs_dist[12][9] = {
@@ -77,34 +82,15 @@
 {
     struct tm tc;
     time_t ct;
-    int ltc_frame;
+    uint32_t timecode;
     va_list ap;
 
     buf[0] = (uint8_t)pack_id;
     switch (pack_id) {
     case dv_timecode:
-        ct = (time_t)av_rescale_rnd(c->frames, c->sys->time_base.num,
-                                    c->sys->time_base.den, AV_ROUND_DOWN);
-        ff_brktimegm(ct, &tc);
-        /*
-         * LTC drop-frame frame counter drops two frames (0 and 1) every
-         * minute, unless it is exactly divisible by 10
-         */
-        ltc_frame = (c->frames + 2 * ct / 60 - 2 * ct / 600) % c->sys->ltc_divisor;
-        buf[1] = (0                 << 7) | /* color frame: 0 - unsync; 1 - sync mode */
-                 (1                 << 6) | /* drop frame timecode: 0 - nondrop; 1 - drop */
-                 ((ltc_frame / 10)  << 4) | /* tens of frames */
-                 (ltc_frame % 10);          /* units of frames */
-        buf[2] = (1                 << 7) | /* biphase mark polarity correction: 0 - even; 1 - odd */
-                 ((tc.tm_sec / 10)  << 4) | /* tens of seconds */
-                 (tc.tm_sec % 10);          /* units of seconds */
-        buf[3] = (1                 << 7) | /* binary group flag BGF0 */
-                 ((tc.tm_min / 10)  << 4) | /* tens of minutes */
-                 (tc.tm_min % 10);          /* units of minutes */
-        buf[4] = (1                 << 7) | /* binary group flag BGF2 */
-                 (1                 << 6) | /* binary group flag BGF1 */
-                 ((tc.tm_hour / 10) << 4) | /* tens of hours */
-                 (tc.tm_hour % 10);         /* units of hours */
+        timecode  = av_timecode_get_smpte_from_framenum(&c->tc, c->frames);
+        timecode |= 1<<23 | 1<<15 | 1<<7 | 1<<6; // biphase and binary group flags
+        AV_WB32(buf + 1, timecode);
         break;
     case dv_audio_source:  /* AAUX source pack */
         va_start(ap, buf);
@@ -369,6 +355,10 @@
 
 static int dv_write_header(AVFormatContext *s)
 {
+    AVRational rate;
+    DVMuxContext *dvc = s->priv_data;
+    AVDictionaryEntry *tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
+
     if (!dv_init_mux(s)) {
         av_log(s, AV_LOG_ERROR, "Can't initialize DV format!\n"
                     "Make sure that you supply exactly two streams:\n"
@@ -376,7 +366,19 @@
                     "     (50Mbps allows an optional second audio stream)\n");
         return -1;
     }
-    return 0;
+    rate.num = dvc->sys->ltc_divisor;
+    rate.den = 1;
+    if (!tcr) { // no global timecode, look into the streams
+        int i;
+        for (i = 0; i < s->nb_streams; i++) {
+            tcr = av_dict_get(s->streams[i]->metadata, "timecode", NULL, 0);
+            if (tcr)
+                break;
+        }
+    }
+    if (tcr)
+        return av_timecode_init_from_string(&dvc->tc, rate, tcr->value, s);
+    return av_timecode_init(&dvc->tc, rate, 0, 0, s);
 }
 
 static int dv_write_packet(struct AVFormatContext *s, AVPacket *pkt)
diff --git a/libavformat/dxa.c b/libavformat/dxa.c
index a1b85fe..30d1e02 100644
--- a/libavformat/dxa.c
+++ b/libavformat/dxa.c
@@ -2,20 +2,20 @@
  * DXA demuxer
  * Copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -110,7 +110,7 @@
         if (ast->codec->sample_rate > 0)
             avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
         // find 'data' chunk
-        while(avio_tell(pb) < c->vidpos && !pb->eof_reached){
+        while(avio_tell(pb) < c->vidpos && !url_feof(pb)){
             tag = avio_rl32(pb);
             fsize = avio_rl32(pb);
             if(tag == MKTAG('d', 'a', 't', 'a')) break;
@@ -168,7 +168,7 @@
         return 0;
     }
     avio_seek(s->pb, c->vidpos, SEEK_SET);
-    while(!s->pb->eof_reached && c->frames){
+    while(!url_feof(s->pb) && c->frames){
         avio_read(s->pb, buf, 4);
         switch(AV_RL32(buf)){
         case MKTAG('N', 'U', 'L', 'L'):
diff --git a/libavformat/eacdata.c b/libavformat/eacdata.c
index b56ba1c..be31d00 100644
--- a/libavformat/eacdata.c
+++ b/libavformat/eacdata.c
@@ -2,20 +2,20 @@
  * Electronic Arts .cdata file Demuxer
  * Copyright (c) 2007 Peter Ross
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -40,7 +40,7 @@
 {
     const uint8_t *b = p->buf;
 
-    if (b[0] == 0x04 && (b[1] == 0x00 || b[1] == 0x04 || b[1] == 0x0C))
+    if (b[0] == 0x04 && (b[1] == 0x00 || b[1] == 0x04 || b[1] == 0x0C || b[1] == 0x14))
         return AVPROBE_SCORE_MAX/8;
     return 0;
 }
@@ -51,19 +51,21 @@
     AVIOContext *pb = s->pb;
     unsigned int sample_rate, header;
     AVStream *st;
+    int64_t channel_layout = 0;
 
     header = avio_rb16(pb);
     switch (header) {
         case 0x0400: cdata->channels = 1; break;
         case 0x0404: cdata->channels = 2; break;
-        case 0x040C: cdata->channels = 4; break;
+        case 0x040C: cdata->channels = 4; channel_layout = AV_CH_LAYOUT_QUAD;         break;
+        case 0x0414: cdata->channels = 6; channel_layout = AV_CH_LAYOUT_5POINT1_BACK; break;
         default:
             av_log(s, AV_LOG_INFO, "unknown header 0x%04x\n", header);
             return -1;
     };
 
     sample_rate = avio_rb16(pb);
-    avio_skip(pb, 12);
+    avio_skip(pb, (avio_r8(pb) & 0x20) ? 15 : 11);
 
     st = avformat_new_stream(s, NULL);
     if (!st)
@@ -72,7 +74,9 @@
     st->codec->codec_tag = 0; /* no fourcc */
     st->codec->codec_id = AV_CODEC_ID_ADPCM_EA_XAS;
     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/electronicarts.c b/libavformat/electronicarts.c
index ae2fda0..c5533f2 100644
--- a/libavformat/electronicarts.c
+++ b/libavformat/electronicarts.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2004  The ffmpeg Project
  * Copyright (c) 2006-2008 Peter Ross
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -66,6 +66,7 @@
     enum AVCodecID video_codec;
     AVRational time_base;
     int width, height;
+    int nb_frames;
     int video_stream_index;
 
     enum AVCodecID audio_codec;
@@ -109,7 +110,7 @@
     ea->sample_rate = -1;
     ea->num_channels = 1;
 
-    while (!pb->eof_reached && inHeader) {
+    while (!url_feof(pb) && inHeader) {
         int inSubheader;
         uint8_t byte;
         byte = avio_r8(pb);
@@ -118,7 +119,7 @@
         case 0xFD:
             av_log (s, AV_LOG_DEBUG, "entered audio subheader\n");
             inSubheader = 1;
-            while (!pb->eof_reached && inSubheader) {
+            while (!url_feof(pb) && inSubheader) {
                 uint8_t subbyte;
                 subbyte = avio_r8(pb);
 
@@ -274,7 +275,9 @@
     EaDemuxContext *ea = s->priv_data;
     AVIOContext *pb = s->pb;
 
-    avio_skip(pb, 16);
+    avio_skip(pb, 8);
+    ea->nb_frames = avio_rl32(pb);
+    avio_skip(pb, 4);
     ea->time_base.den = avio_rl32(pb);
     ea->time_base.num = avio_rl32(pb);
     ea->video_codec = AV_CODEC_ID_VP6;
@@ -348,7 +351,6 @@
 
             case kVGT_TAG:
                 ea->video_codec = AV_CODEC_ID_TGV;
-                ea->time_base = (AVRational){1, 15};
                 break;
 
             case mTCD_TAG :
@@ -417,7 +419,7 @@
     EaDemuxContext *ea = s->priv_data;
     AVStream *st;
 
-    if (!process_ea_header(s))
+    if (process_ea_header(s)<=0)
         return AVERROR(EIO);
 
     if (ea->video_codec) {
@@ -428,14 +430,17 @@
         ea->video_stream_index = st->index;
         st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
         st->codec->codec_id = ea->video_codec;
+        // parsing is necessary to make FFmpeg generate correct timestamps
+        if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO)
+            st->need_parsing = AVSTREAM_PARSE_HEADERS;
         st->codec->codec_tag = 0;  /* no fourcc */
         st->codec->width = ea->width;
         st->codec->height = ea->height;
-        avpriv_set_pts_info(st, 33, ea->time_base.num, ea->time_base.den);
-#if FF_API_R_FRAME_RATE
+        st->duration = st->nb_frames = ea->nb_frames;
+        if (ea->time_base.num)
+            avpriv_set_pts_info(st, 64, ea->time_base.num, ea->time_base.den);
         st->r_frame_rate =
-#endif
-        st->avg_frame_rate = (AVRational){ea->time_base.den, ea->time_base.num};
+        st->avg_frame_rate = av_inv_q(ea->time_base);
     }
 
     if (ea->audio_codec) {
@@ -483,11 +488,12 @@
     AVIOContext *pb = s->pb;
     int ret = 0;
     int packet_read = 0;
+    int partial_packet = 0;
     unsigned int chunk_type, chunk_size;
     int key = 0;
     int av_uninit(num_samples);
 
-    while (!packet_read) {
+    while (!packet_read || partial_packet) {
         chunk_type = avio_rl32(pb);
         chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);
         if (chunk_size <= 8)
@@ -515,6 +521,11 @@
                 avio_skip(pb, 8);
                 chunk_size -= 12;
             }
+            if (partial_packet) {
+                av_log_ask_for_sample(s, "video header followed by audio packet not supported.\n");
+                av_free_packet(pkt);
+                partial_packet = 0;
+            }
             ret = av_get_packet(pb, pkt, chunk_size);
             if (ret < 0)
                 return ret;
@@ -579,9 +590,15 @@
             key = AV_PKT_FLAG_KEY;
         case MV0F_TAG:
 get_video_packet:
-            ret = av_get_packet(pb, pkt, chunk_size);
-            if (ret < 0)
-                return ret;
+            if (partial_packet) {
+                ret = av_append_packet(pb, pkt, chunk_size);
+            } else
+                ret = av_get_packet(pb, pkt, chunk_size);
+            if (ret < 0) {
+                packet_read = 1;
+                break;
+            }
+            partial_packet = chunk_type == MVIh_TAG;
             pkt->stream_index = ea->video_stream_index;
             pkt->flags |= key;
             packet_read = 1;
@@ -593,6 +610,8 @@
         }
     }
 
+    if (ret < 0 && partial_packet)
+        av_free_packet(pkt);
     return ret;
 }
 
diff --git a/libavformat/ffm.h b/libavformat/ffm.h
index 6ce5e04..4940235 100644
--- a/libavformat/ffm.h
+++ b/libavformat/ffm.h
@@ -1,21 +1,21 @@
 /*
- * FFM (avserver live feed) common header
+ * FFM (ffserver live feed) common header
  * Copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -54,6 +54,7 @@
     int64_t dts;
     uint8_t *packet_ptr, *packet_end;
     uint8_t packet[FFM_PACKET_SIZE];
+    int64_t start_time;
 } FFMContext;
 
 int64_t ffm_read_write_index(int fd);
diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c
index 50c7416..f151f9c1 100644
--- a/libavformat/ffmdec.c
+++ b/libavformat/ffmdec.c
@@ -1,21 +1,21 @@
 /*
- * FFM (avserver live feed) demuxer
+ * FFM (ffserver live feed) demuxer
  * Copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,7 +24,8 @@
 #include "avformat.h"
 #include "internal.h"
 #include "ffm.h"
-#if CONFIG_AVSERVER
+#include "avio_internal.h"
+#if CONFIG_FFSERVER
 #include <unistd.h>
 
 int64_t ffm_read_write_index(int fd)
@@ -56,7 +57,7 @@
     ffm->write_index = pos;
     ffm->file_size = file_size;
 }
-#endif // CONFIG_AVSERVER
+#endif // CONFIG_FFSERVER
 
 static int ffm_is_avail_data(AVFormatContext *s, int size)
 {
@@ -93,7 +94,7 @@
 {
     av_log(s, AV_LOG_ERROR, "resyncing\n");
     while (state != PACKET_ID) {
-        if (s->pb->eof_reached) {
+        if (url_feof(s->pb)) {
             av_log(s, AV_LOG_ERROR, "cannot find FFM syncword\n");
             return -1;
         }
@@ -122,6 +123,11 @@
             if (avio_tell(pb) == ffm->file_size)
                 avio_seek(pb, ffm->packet_size, SEEK_SET);
     retry_read:
+            if (pb->buffer_size != ffm->packet_size) {
+                int64_t tell = avio_tell(pb);
+                ffio_set_buf_size(pb, ffm->packet_size);
+                avio_seek(pb, tell, SEEK_SET);
+            }
             id = avio_rb16(pb); /* PACKET_ID */
             if (id != PACKET_ID)
                 if (ffm_resync(s, id) < 0)
@@ -276,7 +282,7 @@
     /* get also filesize */
     if (pb->seekable) {
         ffm->file_size = avio_size(pb);
-        if (ffm->write_index)
+        if (ffm->write_index && 0)
             adjust_write_index(s);
     } else {
         ffm->file_size = (UINT64_C(1) << 63) - 1;
@@ -455,11 +461,25 @@
     av_dlog(s, "wanted_pts=%0.6f\n", wanted_pts / 1000000.0);
     /* find the position using linear interpolation (better than
        dichotomy in typical cases) */
-    pos_min = FFM_PACKET_SIZE;
-    pos_max = ffm->file_size - FFM_PACKET_SIZE;
+    if (ffm->write_index && ffm->write_index < ffm->file_size) {
+        if (get_dts(s, FFM_PACKET_SIZE) < wanted_pts) {
+            pos_min = FFM_PACKET_SIZE;
+            pos_max = ffm->write_index - FFM_PACKET_SIZE;
+        } else {
+            pos_min = ffm->write_index;
+            pos_max = ffm->file_size - FFM_PACKET_SIZE;
+        }
+    } else {
+        pos_min = FFM_PACKET_SIZE;
+        pos_max = ffm->file_size - FFM_PACKET_SIZE;
+    }
     while (pos_min <= pos_max) {
         pts_min = get_dts(s, pos_min);
         pts_max = get_dts(s, pos_max);
+        if (pts_min > wanted_pts || pts_max < wanted_pts) {
+            pos = pts_min > wanted_pts ? pos_min : pos_max;
+            goto found;
+        }
         /* linear interpolation */
         pos1 = (double)(pos_max - pos_min) * (double)(wanted_pts - pts_min) /
             (double)(pts_max - pts_min);
@@ -504,7 +524,7 @@
 
 AVInputFormat ff_ffm_demuxer = {
     .name           = "ffm",
-    .long_name      = NULL_IF_CONFIG_SMALL("FFM (AVserver live feed)"),
+    .long_name      = NULL_IF_CONFIG_SMALL("FFM (FFserver live feed)"),
     .priv_data_size = sizeof(FFMContext),
     .read_probe     = ffm_probe,
     .read_header    = ffm_read_header,
diff --git a/libavformat/ffmenc.c b/libavformat/ffmenc.c
index 386487f..d43b7d4 100644
--- a/libavformat/ffmenc.c
+++ b/libavformat/ffmenc.c
@@ -1,28 +1,28 @@
 /*
- * FFM (avserver live feed) muxer
+ * FFM (ffserver live feed) muxer
  * Copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <assert.h>
-
 #include "libavutil/intreadwrite.h"
 #include "libavutil/intfloat.h"
+#include "libavutil/avassert.h"
+#include "libavutil/parseutils.h"
 #include "avformat.h"
 #include "internal.h"
 #include "ffm.h"
@@ -36,7 +36,7 @@
     fill_size = ffm->packet_end - ffm->packet_ptr;
     memset(ffm->packet_ptr, 0, fill_size);
 
-    assert(avio_tell(pb) % ffm->packet_size == 0);
+    av_assert1(avio_tell(pb) % ffm->packet_size == 0);
 
     /* put header */
     avio_wb16(pb, PACKET_ID);
@@ -86,11 +86,18 @@
 static int ffm_write_header(AVFormatContext *s)
 {
     FFMContext *ffm = s->priv_data;
+    AVDictionaryEntry *t;
     AVStream *st;
     AVIOContext *pb = s->pb;
     AVCodecContext *codec;
     int bit_rate, i;
 
+    if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) {
+        int ret = av_parse_time(&ffm->start_time, t->value, 0);
+        if (ret < 0)
+            return ret;
+    }
+
     ffm->packet_size = FFM_PACKET_SIZE;
 
     /* header */
@@ -189,7 +196,7 @@
     /* init packet mux */
     ffm->packet_ptr = ffm->packet;
     ffm->packet_end = ffm->packet + ffm->packet_size - FFM_HEADER_SIZE;
-    assert(ffm->packet_end >= ffm->packet);
+    av_assert0(ffm->packet_end >= ffm->packet);
     ffm->frame_offset = 0;
     ffm->dts = 0;
     ffm->first_packet = 1;
@@ -199,11 +206,12 @@
 
 static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
+    FFMContext *ffm = s->priv_data;
     int64_t dts;
     uint8_t header[FRAME_HEADER_SIZE+4];
     int header_size = FRAME_HEADER_SIZE;
 
-    dts = pkt->dts;
+    dts = ffm->start_time + pkt->dts;
     /* packet size & key_frame */
     header[0] = pkt->stream_index;
     header[1] = 0;
@@ -211,7 +219,7 @@
         header[1] |= FLAG_KEY_FRAME;
     AV_WB24(header+2, pkt->size);
     AV_WB24(header+5, pkt->duration);
-    AV_WB64(header+8, pkt->pts);
+    AV_WB64(header+8, ffm->start_time + pkt->pts);
     if (pkt->pts != pkt->dts) {
         header[1] |= FLAG_DTS;
         AV_WB32(header+16, pkt->pts - pkt->dts);
@@ -236,8 +244,7 @@
 
 AVOutputFormat ff_ffm_muxer = {
     .name              = "ffm",
-    .long_name         = NULL_IF_CONFIG_SMALL("FFM (AVserver live feed)"),
-    .mime_type         = "",
+    .long_name         = NULL_IF_CONFIG_SMALL("FFM (FFserver live feed)"),
     .extensions        = "ffm",
     .priv_data_size    = sizeof(FFMContext),
     .audio_codec       = AV_CODEC_ID_MP2,
diff --git a/libavformat/ffmeta.h b/libavformat/ffmeta.h
index a5380ca..ae8778d 100644
--- a/libavformat/ffmeta.h
+++ b/libavformat/ffmeta.h
@@ -2,20 +2,20 @@
  * Common data for metadata muxer/demuxer
  * Copyright (c) 2010 Anton Khirnov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/ffmetadec.c b/libavformat/ffmetadec.c
index 7dbf7ed..4bdc98a 100644
--- a/libavformat/ffmetadec.c
+++ b/libavformat/ffmetadec.c
@@ -2,20 +2,20 @@
  * Metadata demuxer
  * Copyright (c) 2010 Anton Khirnov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -50,7 +50,7 @@
                 buf[i++] = c;
         }
         buf[i] = 0;
-    } while (!s->eof_reached && (buf[0] == ';' || buf[0] == '#' || buf[0] == 0));
+    } while (!url_feof(s) && (buf[0] == ';' || buf[0] == '#' || buf[0] == 0));
 }
 
 static AVChapter *read_chapter(AVFormatContext *s)
@@ -128,7 +128,7 @@
     AVDictionary **m = &s->metadata;
     uint8_t line[1024];
 
-    while(!s->pb->eof_reached) {
+    while(!url_feof(s->pb)) {
         get_line(s->pb, line, sizeof(line));
 
         if (!memcmp(line, ID_STREAM, strlen(ID_STREAM))) {
diff --git a/libavformat/ffmetaenc.c b/libavformat/ffmetaenc.c
index 19fe6c9..a9adbb1 100644
--- a/libavformat/ffmetaenc.c
+++ b/libavformat/ffmetaenc.c
@@ -2,20 +2,20 @@
  * Metadata muxer
  * Copyright (c) 2010 Anton Khirnov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/file.c b/libavformat/file.c
index c552a9e..209957b 100644
--- a/libavformat/file.c
+++ b/libavformat/file.c
@@ -2,20 +2,20 @@
  * buffered file I/O
  * Copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -34,6 +34,14 @@
 #include "os_support.h"
 #include "url.h"
 
+/* Some systems may not have S_ISFIFO */
+#ifndef S_ISFIFO
+#  ifdef S_IFIFO
+#    define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#  else
+#    define S_ISFIFO(m) 0
+#  endif
+#endif
 
 /* standard file protocol */
 
@@ -58,13 +66,15 @@
 static int file_read(URLContext *h, unsigned char *buf, int size)
 {
     FileContext *c = h->priv_data;
-    return read(c->fd, buf, size);
+    int r = read(c->fd, buf, size);
+    return (-1 == r)?AVERROR(errno):r;
 }
 
 static int file_write(URLContext *h, const unsigned char *buf, int size)
 {
     FileContext *c = h->priv_data;
-    return write(c->fd, buf, size);
+    int r = write(c->fd, buf, size);
+    return (-1 == r)?AVERROR(errno):r;
 }
 
 static int file_get_handle(URLContext *h)
@@ -93,6 +103,7 @@
     FileContext *c = h->priv_data;
     int access;
     int fd;
+    struct stat st;
 
     av_strstart(filename, "file:", &filename);
 
@@ -114,6 +125,9 @@
     if (fd == -1)
         return AVERROR(errno);
     c->fd = fd;
+
+    h->is_streamed = !fstat(fd, &st) && S_ISFIFO(st.st_mode);
+
     return 0;
 }
 
@@ -125,9 +139,8 @@
 
     if (whence == AVSEEK_SIZE) {
         struct stat st;
-
         ret = fstat(c->fd, &st);
-        return ret < 0 ? AVERROR(errno) : st.st_size;
+        return ret < 0 ? AVERROR(errno) : (S_ISFIFO(st.st_mode) ? 0 : st.st_size);
     }
 
     ret = lseek(c->fd, pos, whence);
diff --git a/libavformat/filmstripdec.c b/libavformat/filmstripdec.c
index 7c327e9..b41fdb7 100644
--- a/libavformat/filmstripdec.c
+++ b/libavformat/filmstripdec.c
@@ -2,20 +2,20 @@
  * Adobe Filmstrip demuxer
  * Copyright (c) 2010 Peter Ross
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -45,7 +45,7 @@
 
     avio_seek(pb, avio_size(pb) - 36, SEEK_SET);
     if (avio_rb32(pb) != RAND_TAG) {
-        av_log(s, AV_LOG_ERROR, "magic number not found");
+        av_log(s, AV_LOG_ERROR, "magic number not found\n");
         return AVERROR_INVALIDDATA;
     }
 
@@ -80,7 +80,7 @@
     FilmstripDemuxContext *film = s->priv_data;
     AVStream *st = s->streams[0];
 
-    if (s->pb->eof_reached)
+    if (url_feof(s->pb))
         return AVERROR(EIO);
     pkt->dts = avio_tell(s->pb) / (st->codec->width * (st->codec->height + film->leading) * 4);
     pkt->size = av_get_packet(s->pb, pkt, st->codec->width * st->codec->height * 4);
diff --git a/libavformat/filmstripenc.c b/libavformat/filmstripenc.c
index 90d9a76..99fbf0b 100644
--- a/libavformat/filmstripenc.c
+++ b/libavformat/filmstripenc.c
@@ -2,20 +2,20 @@
  * Adobe Filmstrip muxer
  * Copyright (c) 2010 Peter Ross
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c
index f19f95d..bbb28f4 100644
--- a/libavformat/flacdec.c
+++ b/libavformat/flacdec.c
@@ -2,20 +2,20 @@
  * Raw FLAC demuxer
  * Copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -28,6 +28,8 @@
 #include "vorbiscomment.h"
 #include "libavcodec/bytestream.h"
 
+#define RETURN_ERROR(code) do { ret = (code); goto fail; } while (0)
+
 static int parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size)
 {
     const CodecMime *mime = ff_id3v2_mime_tags;
@@ -47,8 +49,7 @@
     if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) {
         av_log(s, AV_LOG_ERROR, "Invalid picture type: %d.\n", type);
         if (s->error_recognition & AV_EF_EXPLODE) {
-            ret = AVERROR_INVALIDDATA;
-            goto fail;
+            RETURN_ERROR(AVERROR_INVALIDDATA);
         }
         type = 0;
     }
@@ -84,8 +85,7 @@
     len = avio_rb32(pb);
     if (len > 0) {
         if (!(desc = av_malloc(len + 1))) {
-            ret = AVERROR(ENOMEM);
-            goto fail;
+            RETURN_ERROR(AVERROR(ENOMEM));
         }
 
         if (avio_read(pb, desc, len) != len) {
@@ -111,8 +111,7 @@
         goto fail;
     }
     if (!(data = av_malloc(len))) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
+        RETURN_ERROR(AVERROR(ENOMEM));
     }
     if (avio_read(pb, data, len) != len) {
         av_log(s, AV_LOG_ERROR, "Error reading attached picture data.\n");
@@ -123,8 +122,7 @@
 
     st = avformat_new_stream(s, NULL);
     if (!st) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
+        RETURN_ERROR(AVERROR(ENOMEM));
     }
 
     av_init_packet(&st->attached_pic);
@@ -165,7 +163,7 @@
         return AVERROR(ENOMEM);
     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codec->codec_id = AV_CODEC_ID_FLAC;
-    st->need_parsing = AVSTREAM_PARSE_FULL;
+    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
     /* the parameters will be extracted from the compressed bitstream */
 
     /* if fLaC marker is not found, assume there is no header */
@@ -175,7 +173,7 @@
     }
 
     /* process metadata blocks */
-    while (!s->pb->eof_reached && !metadata_last) {
+    while (!url_feof(s->pb) && !metadata_last) {
         avio_read(s->pb, header, 4);
         avpriv_flac_parse_block_header(header, &metadata_last, &metadata_type,
                                    &metadata_size);
@@ -190,8 +188,7 @@
                 return AVERROR(ENOMEM);
             }
             if (avio_read(s->pb, buffer, metadata_size) != metadata_size) {
-                av_freep(&buffer);
-                return AVERROR(EIO);
+                RETURN_ERROR(AVERROR(EIO));
             }
             break;
         /* skip metadata block for unsupported types */
@@ -205,12 +202,10 @@
             FLACStreaminfo si;
             /* STREAMINFO can only occur once */
             if (found_streaminfo) {
-                av_freep(&buffer);
-                return AVERROR_INVALIDDATA;
+                RETURN_ERROR(AVERROR_INVALIDDATA);
             }
             if (metadata_size != FLAC_STREAMINFO_SIZE) {
-                av_freep(&buffer);
-                return AVERROR_INVALIDDATA;
+                RETURN_ERROR(AVERROR_INVALIDDATA);
             }
             found_streaminfo = 1;
             st->codec->extradata      = buffer;
@@ -232,24 +227,25 @@
             const uint8_t *offset;
             int i, chapters, track, ti;
             if (metadata_size < 431)
-                return AVERROR_INVALIDDATA;
+                RETURN_ERROR(AVERROR_INVALIDDATA);
             offset = buffer + 395;
             chapters = bytestream_get_byte(&offset) - 1;
             if (chapters <= 0)
-                return AVERROR_INVALIDDATA;
+                RETURN_ERROR(AVERROR_INVALIDDATA);
             for (i = 0; i < chapters; i++) {
                 if (offset + 36 - buffer > metadata_size)
-                    return AVERROR_INVALIDDATA;
+                    RETURN_ERROR(AVERROR_INVALIDDATA);
                 start = bytestream_get_be64(&offset);
                 track = bytestream_get_byte(&offset);
                 bytestream_get_buffer(&offset, isrc, 12);
                 isrc[12] = 0;
                 offset += 14;
                 ti = bytestream_get_byte(&offset);
-                if (ti <= 0) return AVERROR_INVALIDDATA;
+                if (ti <= 0) RETURN_ERROR(AVERROR_INVALIDDATA);
                 offset += ti * 12;
                 avpriv_new_chapter(s, track, st->time_base, start, AV_NOPTS_VALUE, isrc);
             }
+            av_freep(&buffer);
         } else if (metadata_type == FLAC_METADATA_TYPE_PICTURE) {
             ret = parse_picture(s, buffer, metadata_size);
             av_freep(&buffer);
@@ -260,8 +256,7 @@
         } else {
             /* STREAMINFO must be the first block */
             if (!found_streaminfo) {
-                av_freep(&buffer);
-                return AVERROR_INVALIDDATA;
+                RETURN_ERROR(AVERROR_INVALIDDATA);
             }
             /* process supported blocks other than STREAMINFO */
             if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
@@ -274,6 +269,10 @@
     }
 
     return 0;
+
+fail:
+    av_free(buffer);
+    return ret;
 }
 
 static int flac_probe(AVProbeData *p)
diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c
index b770623..8c270ee 100644
--- a/libavformat/flacenc.c
+++ b/libavformat/flacenc.c
@@ -2,20 +2,20 @@
  * raw FLAC muxer
  * Copyright (c) 2006-2009 Justin Ruggles
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -41,7 +41,7 @@
 static int flac_write_block_comment(AVIOContext *pb, AVDictionary **m,
                                     int last_block, int bitexact)
 {
-    const char *vendor = bitexact ? "Libav" : LIBAVFORMAT_IDENT;
+    const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
     unsigned int len, count;
     uint8_t *p, *p0;
 
diff --git a/libavformat/flacenc.h b/libavformat/flacenc.h
index 2edda67..e83ee32 100644
--- a/libavformat/flacenc.h
+++ b/libavformat/flacenc.h
@@ -2,20 +2,20 @@
  * raw FLAC muxer
  * Copyright (C) 2009 Justin Ruggles
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/flacenc_header.c b/libavformat/flacenc_header.c
index c1f7c86..e16c14b 100644
--- a/libavformat/flacenc_header.c
+++ b/libavformat/flacenc_header.c
@@ -2,20 +2,20 @@
  * raw FLAC muxer
  * Copyright (C) 2009 Justin Ruggles
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/flic.c b/libavformat/flic.c
index 6019763..db3f5d8 100644
--- a/libavformat/flic.c
+++ b/libavformat/flic.c
@@ -2,20 +2,20 @@
  * FLI/FLC Animation File Demuxer
  * Copyright (c) 2003 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -117,7 +117,7 @@
 
     if (!st->codec->width || !st->codec->height) {
         /* Ugly hack needed for the following sample: */
-        /* http://samples.libav.org/fli-flc/fli-bugs/specular.flc */
+        /* http://samples.mplayerhq.hu/fli-flc/fli-bugs/specular.flc */
         av_log(s, AV_LOG_WARNING,
                "File with no specified width/height. Trying 640x480.\n");
         st->codec->width  = 640;
@@ -187,7 +187,7 @@
                (magic_number == FLIC_FILE_MAGIC_3)) {
         avpriv_set_pts_info(st, 64, speed, 1000);
     } else {
-        av_log(s, AV_LOG_INFO, "Invalid or unsupported magic chunk in file\n");
+        av_log(s, AV_LOG_ERROR, "Invalid or unsupported magic chunk in file\n");
         return AVERROR_INVALIDDATA;
     }
 
diff --git a/libavformat/flv.h b/libavformat/flv.h
index fe0fc90..db9468f 100644
--- a/libavformat/flv.h
+++ b/libavformat/flv.h
@@ -1,22 +1,22 @@
 /*
  * FLV common header
  *
- * Copyright (c) 2006 The Libav Project
+ * Copyright (c) 2006 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -46,6 +46,11 @@
 
 #define AMF_END_OF_OBJECT         0x09
 
+#define KEYFRAMES_TAG            "keyframes"
+#define KEYFRAMES_TIMESTAMP_TAG  "times"
+#define KEYFRAMES_BYTEOFFSET_TAG "filepositions"
+
+
 enum {
     FLV_HEADER_FLAG_HASVIDEO = 1,
     FLV_HEADER_FLAG_HASAUDIO = 4,
@@ -58,6 +63,13 @@
 };
 
 enum {
+    FLV_STREAM_TYPE_VIDEO,
+    FLV_STREAM_TYPE_AUDIO,
+    FLV_STREAM_TYPE_DATA,
+    FLV_STREAM_TYPE_NB,
+};
+
+enum {
     FLV_MONO   = 0,
     FLV_STEREO = 1,
 };
@@ -95,12 +107,16 @@
     FLV_CODECID_VP6A    = 5,
     FLV_CODECID_SCREEN2 = 6,
     FLV_CODECID_H264    = 7,
+    FLV_CODECID_REALH263= 8,
+    FLV_CODECID_MPEG4   = 9,
 };
 
 enum {
-    FLV_FRAME_KEY        = 1 << FLV_VIDEO_FRAMETYPE_OFFSET,
-    FLV_FRAME_INTER      = 2 << FLV_VIDEO_FRAMETYPE_OFFSET,
-    FLV_FRAME_DISP_INTER = 3 << FLV_VIDEO_FRAMETYPE_OFFSET,
+    FLV_FRAME_KEY            = 1 << FLV_VIDEO_FRAMETYPE_OFFSET, ///< key frame (for AVC, a seekable frame)
+    FLV_FRAME_INTER          = 2 << FLV_VIDEO_FRAMETYPE_OFFSET, ///< inter frame (for AVC, a non-seekable frame)
+    FLV_FRAME_DISP_INTER     = 3 << FLV_VIDEO_FRAMETYPE_OFFSET, ///< disposable inter frame (H.263 only)
+    FLV_FRAME_GENERATED_KEY  = 4 << FLV_VIDEO_FRAMETYPE_OFFSET, ///< generated key frame (reserved for server use only)
+    FLV_FRAME_VIDEO_INFO_CMD = 5 << FLV_VIDEO_FRAMETYPE_OFFSET, ///< video info/command frame
 };
 
 typedef enum {
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 868cc6b..8c6807a 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -1,26 +1,26 @@
 /*
  * FLV demuxer
- * Copyright (c) 2003 The Libav Project
+ * Copyright (c) 2003 The FFmpeg Project
  *
  * This demuxer will generate a 1 byte extradata for VP6F content.
  * It is composed of:
  *  - upper 4bits: difference between encoded width and visible width
  *  - lower 4bits: difference between encoded height and visible height
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,18 +36,14 @@
 #include "avio_internal.h"
 #include "flv.h"
 
-#define KEYFRAMES_TAG            "keyframes"
-#define KEYFRAMES_TIMESTAMP_TAG  "times"
-#define KEYFRAMES_BYTEOFFSET_TAG "filepositions"
-
 #define VALIDATE_INDEX_TS_THRESH 2500
 
 typedef struct {
     const AVClass *class; ///< Class for private options.
     int trust_metadata; ///< configure streams according onMetaData
     int wrong_dts; ///< wrong dts due to negative cts
-    uint8_t *new_extradata[2];
-    int      new_extradata_size[2];
+    uint8_t *new_extradata[FLV_STREAM_TYPE_NB];
+    int      new_extradata_size[FLV_STREAM_TYPE_NB];
     int      last_sample_rate;
     int      last_channels;
     struct {
@@ -56,6 +52,7 @@
     } validate_index[2];
     int validate_next;
     int validate_count;
+    int searched_for_end;
 } FLVContext;
 
 static int flv_probe(AVProbeData *p)
@@ -75,6 +72,11 @@
     if (!st)
         return NULL;
     st->codec->codec_type = codec_type;
+    if(s->nb_streams>=3 ||(   s->nb_streams==2
+                           && s->streams[0]->codec->codec_type != AVMEDIA_TYPE_DATA
+                           && s->streams[1]->codec->codec_type != AVMEDIA_TYPE_DATA))
+        s->ctx_flags &= ~AVFMTCTX_NOHEADER;
+
     avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
     return st;
 }
@@ -124,8 +126,6 @@
     default:
         return acodec->codec_tag == (flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
     }
-
-    return 0;
 }
 
 static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, AVCodecContext *acodec, int flv_codecid) {
@@ -196,14 +196,13 @@
         default:
             return vcodec->codec_tag == flv_codecid;
     }
-
-    return 0;
 }
 
 static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid) {
     AVCodecContext *vcodec = vstream->codec;
     switch(flv_codecid) {
         case FLV_CODECID_H263  : vcodec->codec_id = AV_CODEC_ID_FLV1   ; break;
+        case FLV_CODECID_REALH263: vcodec->codec_id = AV_CODEC_ID_H263 ; break; // Really mean it this time
         case FLV_CODECID_SCREEN: vcodec->codec_id = AV_CODEC_ID_FLASHSV; break;
         case FLV_CODECID_SCREEN2: vcodec->codec_id = AV_CODEC_ID_FLASHSV2; break;
         case FLV_CODECID_VP6   : vcodec->codec_id = AV_CODEC_ID_VP6F   ;
@@ -212,13 +211,16 @@
                 vcodec->codec_id = AV_CODEC_ID_VP6A;
             if(vcodec->extradata_size != 1) {
                 vcodec->extradata_size = 1;
-                vcodec->extradata = av_malloc(1);
+                vcodec->extradata = av_malloc(1 + FF_INPUT_BUFFER_PADDING_SIZE);
             }
             vcodec->extradata[0] = avio_r8(s->pb);
             return 1; // 1 byte body size adjustment for flv_read_packet()
         case FLV_CODECID_H264:
             vcodec->codec_id = AV_CODEC_ID_H264;
             return 3; // not 4, reading packet type will consume one byte
+        case FLV_CODECID_MPEG4:
+            vcodec->codec_id = AV_CODEC_ID_MPEG4;
+            return 3;
         default:
             av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid);
             vcodec->codec_tag = flv_codecid;
@@ -243,54 +245,51 @@
 
 static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream *vstream, int64_t max_pos) {
     FLVContext *flv = s->priv_data;
-    unsigned int arraylen = 0, timeslen = 0, fileposlen = 0, i;
-    double num_val;
+    unsigned int timeslen = 0, fileposlen = 0, i;
     char str_val[256];
     int64_t *times = NULL;
     int64_t *filepositions = NULL;
     int ret = AVERROR(ENOSYS);
     int64_t initial_pos = avio_tell(ioc);
 
+    if(vstream->nb_index_entries>0){
+        av_log(s, AV_LOG_WARNING, "Skiping duplicate index\n");
+        return 0;
+    }
+
     if (s->flags & AVFMT_FLAG_IGNIDX)
         return 0;
 
     while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
-        int64_t* current_array;
+        int64_t** current_array;
+        unsigned int arraylen;
 
         // Expect array object in context
         if (avio_r8(ioc) != AMF_DATA_TYPE_ARRAY)
             break;
 
         arraylen = avio_rb32(ioc);
-        if (arraylen >> 28)
+        if(arraylen>>28)
             break;
 
-        /*
-         * Expect only 'times' or 'filepositions' sub-arrays in other case refuse to use such metadata
-         * for indexing
-         */
-        if (!strcmp(KEYFRAMES_TIMESTAMP_TAG, str_val) && !times) {
-            if (!(times = av_mallocz(sizeof(*times) * arraylen))) {
-                ret = AVERROR(ENOMEM);
-                goto finish;
-            }
-            timeslen = arraylen;
-            current_array = times;
-        } else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) && !filepositions) {
-            if (!(filepositions = av_mallocz(sizeof(*filepositions) * arraylen))) {
-                ret = AVERROR(ENOMEM);
-                goto finish;
-            }
-            fileposlen = arraylen;
-            current_array = filepositions;
-        } else // unexpected metatag inside keyframes, will not use such metadata for indexing
+        if       (!strcmp(KEYFRAMES_TIMESTAMP_TAG , str_val) && !times){
+            current_array= &times;
+            timeslen= arraylen;
+        }else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) && !filepositions){
+            current_array= &filepositions;
+            fileposlen= arraylen;
+        }else // unexpected metatag inside keyframes, will not use such metadata for indexing
             break;
 
+        if (!(*current_array = av_mallocz(sizeof(**current_array) * arraylen))) {
+            ret = AVERROR(ENOMEM);
+            goto finish;
+        }
+
         for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) {
             if (avio_r8(ioc) != AMF_DATA_TYPE_NUMBER)
-                goto finish;
-            num_val = av_int2double(avio_rb64(ioc));
-            current_array[i] = num_val;
+                goto invalid;
+            current_array[0][i] = av_int2double(avio_rb64(ioc));
         }
         if (times && filepositions) {
             // All done, exiting at a position allowing amf_parse_object
@@ -300,7 +299,7 @@
         }
     }
 
-    if (!ret && timeslen == fileposlen) {
+    if (timeslen == fileposlen && fileposlen>1 && max_pos <= filepositions[0]) {
         for (i = 0; i < fileposlen; i++) {
             av_add_index_entry(vstream, filepositions[i], times[i]*1000,
                                0, 0, AVINDEX_KEYFRAME);
@@ -310,16 +309,15 @@
                 flv->validate_count = i + 1;
             }
         }
-    } else
+    } else {
+invalid:
         av_log(s, AV_LOG_WARNING, "Invalid keyframes object, skipping.\n");
+    }
 
 finish:
     av_freep(&times);
     av_freep(&filepositions);
-    // If we got unexpected data, but successfully reset back to
-    // the start pos, the caller can continue parsing
-    if (ret < 0 && avio_seek(ioc, initial_pos, SEEK_SET) > 0)
-        return 0;
+    avio_seek(ioc, initial_pos, SEEK_SET);
     return ret;
 }
 
@@ -346,10 +344,10 @@
                 return -1;
             break;
         case AMF_DATA_TYPE_OBJECT:
-            if ((vstream || astream) && key && !strcmp(KEYFRAMES_TAG, key) && depth == 1)
+            if ((vstream || astream) && ioc->seekable && key && !strcmp(KEYFRAMES_TAG, key) && depth == 1)
                 if (parse_keyframes_index(s, ioc, vstream ? vstream : astream,
                                           max_pos) < 0)
-                    return -1;
+                    av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n");
 
             while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
                 if (amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0)
@@ -424,6 +422,11 @@
             }
         }
 
+        if (amf_type == AMF_DATA_TYPE_OBJECT && s->nb_streams == 1 &&
+           ((!acodec && !strcmp(key, "audiocodecid")) ||
+            (!vcodec && !strcmp(key, "videocodecid"))))
+                s->ctx_flags &= ~AVFMTCTX_NOHEADER; //If there is either audio/video missing, codecid will be an empty object
+
         if (!strcmp(key, "duration")        ||
             !strcmp(key, "filesize")        ||
             !strcmp(key, "width")           ||
@@ -453,13 +456,12 @@
 
 static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) {
     AMFDataType type;
-    AVStream *stream, *astream, *vstream;
+    AVStream *stream, *astream, *vstream, *dstream;
     AVIOContext *ioc;
     int i;
     char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want.
 
-    astream = NULL;
-    vstream = NULL;
+    vstream = astream = dstream = NULL;
     ioc = s->pb;
 
     //first object needs to be "onMetaData" string
@@ -477,8 +479,9 @@
     //find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called.
     for(i = 0; i < s->nb_streams; i++) {
         stream = s->streams[i];
-        if     (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) astream = stream;
-        else if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) vstream = stream;
+        if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) vstream = stream;
+        else if(stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) astream = stream;
+        else if(stream->codec->codec_type == AVMEDIA_TYPE_DATA) dstream = stream;
     }
 
     //parse the second object (we want a mixed array)
@@ -511,6 +514,8 @@
         if(!create_stream(s, AVMEDIA_TYPE_AUDIO))
             return AVERROR(ENOMEM);
     }
+    // Flag doesn't indicate whether or not there is script-data present. Must
+    // create that stream if it's encountered.
 
     offset = avio_rb32(s->pb);
     avio_seek(s->pb, offset, SEEK_SET);
@@ -523,9 +528,10 @@
 
 static int flv_read_close(AVFormatContext *s)
 {
+    int i;
     FLVContext *flv = s->priv_data;
-    av_freep(&flv->new_extradata[0]);
-    av_freep(&flv->new_extradata[1]);
+    for(i=0; i<FLV_STREAM_TYPE_NB; i++)
+        av_freep(&flv->new_extradata[i]);
     return 0;
 }
 
@@ -630,10 +636,12 @@
 static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     FLVContext *flv = s->priv_data;
-    int ret, i, type, size, flags, is_audio;
+    int ret, i, type, size, flags;
+    int stream_type=-1;
     int64_t next, pos;
     int64_t dts, pts = AV_NOPTS_VALUE;
-    int sample_rate = 0, channels = 0;
+    int av_uninit(channels);
+    int av_uninit(sample_rate);
     AVStream *st = NULL;
 
  for(;;avio_skip(s->pb, 4)){ /* pkt size is repeated at end. skip it */
@@ -643,7 +651,7 @@
     dts = avio_rb24(s->pb);
     dts |= avio_r8(s->pb) << 24;
     av_dlog(s, "type:%d, size:%d, dts:%"PRId64"\n", type, size, dts);
-    if (s->pb->eof_reached)
+    if (url_feof(s->pb))
         return AVERROR_EOF;
     avio_skip(s->pb, 3); /* stream id, always 0 */
     flags = 0;
@@ -670,22 +678,26 @@
     next= size + avio_tell(s->pb);
 
     if (type == FLV_TAG_TYPE_AUDIO) {
-        is_audio=1;
+        stream_type=FLV_STREAM_TYPE_AUDIO;
         flags = avio_r8(s->pb);
         size--;
     } else if (type == FLV_TAG_TYPE_VIDEO) {
-        is_audio=0;
+        stream_type=FLV_STREAM_TYPE_VIDEO;
         flags = avio_r8(s->pb);
         size--;
-        if ((flags & 0xf0) == 0x50) /* video info / command frame */
+        if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD)
             goto skip;
+    } else if (type == FLV_TAG_TYPE_META) {
+        if (size > 13+1+4 && dts == 0) { // Header-type metadata stuff
+            flv_read_metabody(s, next);
+            goto skip;
+        } else if (dts != 0) { // Script-data "special" metadata frames - don't skip
+            stream_type=FLV_STREAM_TYPE_DATA;
+        } else {
+            goto skip;
+        }
     } else {
-        if (type == FLV_TAG_TYPE_META && size > 13+1+4)
-            if (flv_read_metabody(s, next) > 0) {
-                return flv_data_packet(s, pkt, dts, next);
-            }
-        else /* skip packet */
-            av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags);
+        av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags);
     skip:
         avio_seek(s->pb, next, SEEK_SET);
         continue;
@@ -698,24 +710,31 @@
     /* now find stream */
     for(i=0;i<s->nb_streams;i++) {
         st = s->streams[i];
-        if (is_audio && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
-            if (flv_same_audio_codec(st->codec, flags)) {
+        if (stream_type == FLV_STREAM_TYPE_AUDIO) {
+            if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
+                flv_same_audio_codec(st->codec, flags)) {
                 break;
             }
         } else
-        if (!is_audio && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
-            if (flv_same_video_codec(st->codec, flags)) {
+        if (stream_type == FLV_STREAM_TYPE_VIDEO) {
+            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+                flv_same_video_codec(st->codec, flags)) {
                 break;
             }
+        } else if (stream_type == FLV_STREAM_TYPE_DATA) {
+            if (st->codec->codec_type == AVMEDIA_TYPE_DATA)
+                break;
         }
     }
     if(i == s->nb_streams){
+        av_log(s, AV_LOG_WARNING, "Stream discovered after head already parsed\n");
         st = create_stream(s,
-            is_audio ? AVMEDIA_TYPE_AUDIO : AVMEDIA_TYPE_VIDEO);
+             (int[]){AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_DATA}[stream_type]);
+
     }
-    av_dlog(s, "%d %X %d \n", is_audio, flags, st->discard);
-    if(  (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ||         is_audio))
-       ||(st->discard >= AVDISCARD_BIDIR  &&  ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && !is_audio))
+    av_dlog(s, "%d %X %d \n", stream_type, flags, st->discard);
+    if(  (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO)))
+       ||(st->discard >= AVDISCARD_BIDIR  &&  ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO)))
        || st->discard >= AVDISCARD_ALL
        ){
         avio_seek(s->pb, next, SEEK_SET);
@@ -727,22 +746,30 @@
  }
 
     // if not streamed and no duration from metadata then seek to end to find the duration from the timestamps
-    if(s->pb->seekable && (!s->duration || s->duration==AV_NOPTS_VALUE)){
+    if(s->pb->seekable && (!s->duration || s->duration==AV_NOPTS_VALUE) && !flv->searched_for_end){
         int size;
         const int64_t pos= avio_tell(s->pb);
-        const int64_t fsize= avio_size(s->pb);
+        int64_t fsize= avio_size(s->pb);
+retry_duration:
         avio_seek(s->pb, fsize-4, SEEK_SET);
         size= avio_rb32(s->pb);
         avio_seek(s->pb, fsize-3-size, SEEK_SET);
         if(size == avio_rb24(s->pb) + 11){
             uint32_t ts = avio_rb24(s->pb);
             ts |= avio_r8(s->pb) << 24;
-            s->duration = ts * (int64_t)AV_TIME_BASE / 1000;
+            if(ts)
+                s->duration = ts * (int64_t)AV_TIME_BASE / 1000;
+            else if (fsize >= 8 && fsize - 8 >= size){
+                fsize -= size+4;
+                goto retry_duration;
+            }
         }
+
         avio_seek(s->pb, pos, SEEK_SET);
+        flv->searched_for_end = 1;
     }
 
-    if(is_audio){
+    if(stream_type == FLV_STREAM_TYPE_AUDIO){
         int bits_per_coded_sample;
         channels    = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;
         sample_rate = (44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3);
@@ -762,15 +789,16 @@
             flv_set_audio_codec(s, st, &ctx, flags & FLV_AUDIO_CODECID_MASK);
             sample_rate = ctx.sample_rate;
         }
-    }else{
+    } else if(stream_type == FLV_STREAM_TYPE_VIDEO) {
         size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK);
     }
 
     if (st->codec->codec_id == AV_CODEC_ID_AAC ||
-        st->codec->codec_id == AV_CODEC_ID_H264) {
+        st->codec->codec_id == AV_CODEC_ID_H264 ||
+        st->codec->codec_id == AV_CODEC_ID_MPEG4) {
         int type = avio_r8(s->pb);
         size--;
-        if (st->codec->codec_id == AV_CODEC_ID_H264) {
+        if (st->codec->codec_id == AV_CODEC_ID_H264 || st->codec->codec_id == AV_CODEC_ID_MPEG4) {
             int32_t cts = (avio_rb24(s->pb)+0xff800000)^0xff800000; // sign extension
             pts = dts + cts;
             if (cts < 0) { // dts are wrong
@@ -780,9 +808,9 @@
             if (flv->wrong_dts)
                 dts = AV_NOPTS_VALUE;
         }
-        if (type == 0) {
+        if (type == 0 && (!st->codec->extradata || st->codec->codec_id == AV_CODEC_ID_AAC)) {
             if (st->codec->extradata) {
-                if ((ret = flv_queue_extradata(flv, s->pb, is_audio, size)) < 0)
+                if ((ret = flv_queue_extradata(flv, s->pb, stream_type, size)) < 0)
                     return ret;
                 ret = AVERROR(EAGAIN);
                 goto leave;
@@ -791,8 +819,8 @@
                 return ret;
             if (st->codec->codec_id == AV_CODEC_ID_AAC) {
                 MPEG4AudioConfig cfg;
-                avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata,
-                                             st->codec->extradata_size * 8, 1);
+                if (avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata,
+                                             st->codec->extradata_size * 8, 1) >= 0) {
                 st->codec->channels = cfg.channels;
                 if (cfg.ext_sample_rate)
                     st->codec->sample_rate = cfg.ext_sample_rate;
@@ -800,6 +828,7 @@
                     st->codec->sample_rate = cfg.sample_rate;
                 av_dlog(s, "mp4a config channels %d sample rate %d\n",
                         st->codec->channels, st->codec->sample_rate);
+                }
             }
 
             ret = AVERROR(EAGAIN);
@@ -814,33 +843,31 @@
     }
 
     ret= av_get_packet(s->pb, pkt, size);
-    if (ret < 0) {
-        return AVERROR(EIO);
-    }
-    /* note: we need to modify the packet size here to handle the last
-       packet */
-    pkt->size = ret;
+    if (ret < 0)
+        return ret;
     pkt->dts = dts;
     pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts;
     pkt->stream_index = st->index;
-    if (flv->new_extradata[is_audio]) {
+    if (flv->new_extradata[stream_type]) {
         uint8_t *side = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
-                                                flv->new_extradata_size[is_audio]);
+                                                flv->new_extradata_size[stream_type]);
         if (side) {
-            memcpy(side, flv->new_extradata[is_audio],
-                   flv->new_extradata_size[is_audio]);
-            av_freep(&flv->new_extradata[is_audio]);
-            flv->new_extradata_size[is_audio] = 0;
+            memcpy(side, flv->new_extradata[stream_type],
+                   flv->new_extradata_size[stream_type]);
+            av_freep(&flv->new_extradata[stream_type]);
+            flv->new_extradata_size[stream_type] = 0;
         }
     }
-    if (is_audio && (sample_rate != flv->last_sample_rate ||
+    if (stream_type == FLV_STREAM_TYPE_AUDIO && (sample_rate != flv->last_sample_rate ||
                      channels != flv->last_channels)) {
         flv->last_sample_rate = sample_rate;
         flv->last_channels    = channels;
         ff_add_param_change(pkt, channels, 0, sample_rate, 0, 0);
     }
 
-    if (is_audio || ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY))
+    if (    stream_type == FLV_STREAM_TYPE_AUDIO ||
+            ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) ||
+            stream_type == FLV_STREAM_TYPE_DATA)
         pkt->flags |= AV_PKT_FLAG_KEY;
 
 leave:
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index 8aeea96..c528bf5 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -1,41 +1,44 @@
 /*
  * FLV muxer
- * Copyright (c) 2003 The Libav Project
+ * Copyright (c) 2003 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
 #include "libavutil/intfloat.h"
+#include "libavutil/avassert.h"
 #include "avc.h"
 #include "avformat.h"
 #include "flv.h"
 #include "internal.h"
 #include "metadata.h"
 
-#undef NDEBUG
-#include <assert.h>
 
 static const AVCodecTag flv_video_codec_ids[] = {
     { AV_CODEC_ID_FLV1,     FLV_CODECID_H263 },
+    { AV_CODEC_ID_H263,     FLV_CODECID_REALH263 },
+    { AV_CODEC_ID_MPEG4,    FLV_CODECID_MPEG4 },
     { AV_CODEC_ID_FLASHSV,  FLV_CODECID_SCREEN },
     { AV_CODEC_ID_FLASHSV2, FLV_CODECID_SCREEN2 },
     { AV_CODEC_ID_VP6F,     FLV_CODECID_VP6 },
     { AV_CODEC_ID_VP6,      FLV_CODECID_VP6 },
+    { AV_CODEC_ID_VP6A,     FLV_CODECID_VP6A },
     { AV_CODEC_ID_H264,     FLV_CODECID_H264 },
     { AV_CODEC_ID_NONE,     0 }
 };
@@ -77,12 +80,12 @@
     else if (enc->codec_id == AV_CODEC_ID_SPEEX) {
         if (enc->sample_rate != 16000) {
             av_log(s, AV_LOG_ERROR,
-                   "flv only supports wideband (16kHz) Speex audio\n");
-            return -1;
+                   "FLV only supports wideband (16kHz) Speex audio\n");
+            return AVERROR(EINVAL);
         }
         if (enc->channels != 1) {
-            av_log(s, AV_LOG_ERROR, "flv only supports mono Speex audio\n");
-            return -1;
+            av_log(s, AV_LOG_ERROR, "FLV only supports mono Speex audio\n");
+            return AVERROR(EINVAL);
         }
         return FLV_CODECID_SPEEX | FLV_SAMPLERATE_11025HZ | FLV_SAMPLESSIZE_16BIT;
     } else {
@@ -105,9 +108,9 @@
             }
         default:
             av_log(s, AV_LOG_ERROR,
-                   "flv does not support that sample rate, "
-                   "choose from (44100, 22050, 11025).\n");
-            return -1;
+                   "FLV does not support sample rate %d, "
+                   "choose from (44100, 22050, 11025)\n", enc->sample_rate);
+            return AVERROR(EINVAL);
         }
     }
 
@@ -148,8 +151,9 @@
         flags |= enc->codec_tag << 4;
         break;
     default:
-        av_log(s, AV_LOG_ERROR, "codec not compatible with flv\n");
-        return -1;
+        av_log(s, AV_LOG_ERROR, "Audio codec '%s' not compatible with FLV\n",
+               avcodec_get_name(enc->codec_id));
+        return AVERROR(EINVAL);
     }
 
     return flags;
@@ -210,8 +214,9 @@
             }
             video_enc = enc;
             if (enc->codec_tag == 0) {
-                av_log(s, AV_LOG_ERROR, "video codec not compatible with flv\n");
-                return -1;
+                av_log(s, AV_LOG_ERROR, "Video codec '%s' for stream %d is not compatible with FLV\n",
+                       avcodec_get_name(enc->codec_id), i);
+                return AVERROR(EINVAL);
             }
             break;
         case AVMEDIA_TYPE_AUDIO:
@@ -221,14 +226,16 @@
             break;
         case AVMEDIA_TYPE_DATA:
             if (enc->codec_id != AV_CODEC_ID_TEXT) {
-                av_log(s, AV_LOG_ERROR, "codec not compatible with flv\n");
+                av_log(s, AV_LOG_ERROR, "Data codec '%s' for stream %d is not compatible with FLV\n",
+                       avcodec_get_name(enc->codec_id), i);
                 return AVERROR_INVALIDDATA;
             }
             data_enc = enc;
             break;
         default:
-            av_log(s, AV_LOG_ERROR, "codec not compatible with flv\n");
-            return -1;
+            av_log(s, AV_LOG_ERROR, "Codec type '%s' for stream %d is not compatible with FLV\n",
+                   av_get_media_type_string(enc->codec_type), i);
+            return AVERROR(EINVAL);
         }
         avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */
 
@@ -327,6 +334,22 @@
     }
 
     while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
+        if(   !strcmp(tag->key, "width")
+            ||!strcmp(tag->key, "height")
+            ||!strcmp(tag->key, "videodatarate")
+            ||!strcmp(tag->key, "framerate")
+            ||!strcmp(tag->key, "videocodecid")
+            ||!strcmp(tag->key, "audiodatarate")
+            ||!strcmp(tag->key, "audiosamplerate")
+            ||!strcmp(tag->key, "audiosamplesize")
+            ||!strcmp(tag->key, "stereo")
+            ||!strcmp(tag->key, "audiocodecid")
+            ||!strcmp(tag->key, "duration")
+            ||!strcmp(tag->key, "onMetaData")
+        ){
+            av_log(s, AV_LOG_DEBUG, "Ignoring metadata for %s\n", tag->key);
+            continue;
+        }
         put_amf_string(pb, tag->key);
         avio_w8(pb, AMF_DATA_TYPE_STRING);
         put_amf_string(pb, tag->value);
@@ -353,7 +376,7 @@
 
     for (i = 0; i < s->nb_streams; i++) {
         AVCodecContext *enc = s->streams[i]->codec;
-        if (enc->codec_id == AV_CODEC_ID_AAC || enc->codec_id == AV_CODEC_ID_H264) {
+        if (enc->codec_id == AV_CODEC_ID_AAC || enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) {
             int64_t pos;
             avio_w8(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ?
                     FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO);
@@ -396,7 +419,7 @@
         AVCodecContext *enc = s->streams[i]->codec;
         FLVStreamContext *sc = s->streams[i]->priv_data;
         if (enc->codec_type == AVMEDIA_TYPE_VIDEO &&
-            enc->codec_id == AV_CODEC_ID_H264)
+                (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4))
             put_avc_eos_tag(pb, sc->last_ts);
     }
 
@@ -421,12 +444,12 @@
     unsigned ts;
     int size = pkt->size;
     uint8_t *data = NULL;
-    int flags = 0, flags_size;
+    int flags = -1, flags_size, ret;
 
     if (enc->codec_id == AV_CODEC_ID_VP6 || enc->codec_id == AV_CODEC_ID_VP6F ||
-        enc->codec_id == AV_CODEC_ID_AAC)
+        enc->codec_id == AV_CODEC_ID_VP6A || enc->codec_id == AV_CODEC_ID_AAC)
         flags_size = 2;
-    else if (enc->codec_id == AV_CODEC_ID_H264)
+    else if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4)
         flags_size = 5;
     else
         flags_size = 1;
@@ -438,9 +461,9 @@
         flags = enc->codec_tag;
         if (flags == 0) {
             av_log(s, AV_LOG_ERROR,
-                   "video codec %X not compatible with flv\n",
-                   enc->codec_id);
-            return -1;
+                   "Video codec '%s' is not compatible with FLV\n",
+                   avcodec_get_name(enc->codec_id));
+            return AVERROR(EINVAL);
         }
 
         flags |= pkt->flags & AV_PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER;
@@ -448,7 +471,7 @@
     case AVMEDIA_TYPE_AUDIO:
         flags = get_audio_flags(s, enc);
 
-        assert(size);
+        av_assert0(size);
 
         avio_w8(pb, FLV_TAG_TYPE_AUDIO);
         break;
@@ -459,11 +482,18 @@
         return AVERROR(EINVAL);
     }
 
-    if (enc->codec_id == AV_CODEC_ID_H264)
-        /* check if extradata looks like MP4 */
+    if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) {
+        /* check if extradata looks like mp4 formated */
         if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1)
-            if (ff_avc_parse_nal_units_buf(pkt->data, &data, &size) < 0)
-                return -1;
+            if ((ret = ff_avc_parse_nal_units_buf(pkt->data, &data, &size)) < 0)
+                return ret;
+    } 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 "
+               "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
+        return AVERROR_INVALIDDATA;
+    }
 
     if (flv->delay == AV_NOPTS_VALUE)
         flv->delay = -pkt->dts;
@@ -512,16 +542,17 @@
         avio_seek(pb, data_size + 10 - 3, SEEK_CUR);
         avio_wb32(pb, data_size + 11);
     } else {
+        av_assert1(flags>=0);
         avio_w8(pb,flags);
         if (enc->codec_id == AV_CODEC_ID_VP6)
-            avio_w8(pb, 0);
-        if (enc->codec_id == AV_CODEC_ID_VP6F)
+            avio_w8(pb,0);
+        if (enc->codec_id == AV_CODEC_ID_VP6F || enc->codec_id == AV_CODEC_ID_VP6A)
             avio_w8(pb, enc->extradata_size ? enc->extradata[0] : 0);
         else if (enc->codec_id == AV_CODEC_ID_AAC)
-            avio_w8(pb, 1); // AAC raw
-        else if (enc->codec_id == AV_CODEC_ID_H264) {
-            avio_w8(pb, 1); // AVC NALU
-            avio_wb24(pb, pkt->pts - pkt->dts);
+            avio_w8(pb,1); // AAC raw
+        else if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) {
+            avio_w8(pb,1); // AVC NALU
+            avio_wb24(pb,pkt->pts - pkt->dts);
         }
 
         avio_write(pb, data ? data : pkt->data, size);
diff --git a/libavformat/framecrcenc.c b/libavformat/framecrcenc.c
index de6fa2b..8a69748 100644
--- a/libavformat/framecrcenc.c
+++ b/libavformat/framecrcenc.c
@@ -2,24 +2,25 @@
  * frame CRC encoder (for codec/format testing)
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/adler32.h"
+#include "libavutil/avstring.h"
 #include "avformat.h"
 #include "internal.h"
 
@@ -28,8 +29,13 @@
     uint32_t crc = av_adler32_update(0, pkt->data, pkt->size);
     char buf[256];
 
-    snprintf(buf, sizeof(buf), "%d, %10"PRId64", %10"PRId64", %8d, %8d, 0x%08x\n",
+    snprintf(buf, sizeof(buf), "%d, %10"PRId64", %10"PRId64", %8d, %8d, 0x%08x",
              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)
+        av_strlcatf(buf, sizeof(buf), ", S=%d", pkt->side_data_elems);
+    av_strlcatf(buf, sizeof(buf), "\n");
     avio_write(s->pb, buf, strlen(buf));
     avio_flush(s->pb);
     return 0;
@@ -38,7 +44,6 @@
 AVOutputFormat ff_framecrc_muxer = {
     .name              = "framecrc",
     .long_name         = NULL_IF_CONFIG_SMALL("framecrc testing"),
-    .extensions        = "",
     .audio_codec       = AV_CODEC_ID_PCM_S16LE,
     .video_codec       = AV_CODEC_ID_RAWVIDEO,
     .write_header      = ff_framehash_write_header,
diff --git a/libavformat/g723_1.c b/libavformat/g723_1.c
index 2674ce5..7d97a4b 100644
--- a/libavformat/g723_1.c
+++ b/libavformat/g723_1.c
@@ -2,20 +2,20 @@
  * G.723.1 demuxer
  * Copyright (c) 2010 Mohamed Naufal Basheer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -80,6 +80,6 @@
     .long_name   = NULL_IF_CONFIG_SMALL("G.723.1"),
     .read_header = g723_1_init,
     .read_packet = g723_1_read_packet,
-    .extensions  = "tco",
+    .extensions  = "tco,rco,g723_1",
     .flags       = AVFMT_GENERIC_INDEX
 };
diff --git a/libavformat/g729dec.c b/libavformat/g729dec.c
new file mode 100644
index 0000000..794558e
--- /dev/null
+++ b/libavformat/g729dec.c
@@ -0,0 +1,103 @@
+/*
+ * G.729 raw format demuxer
+ * Copyright (c) 2011 Vladimir Voroshilov
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+
+typedef struct G729DemuxerContext {
+    AVClass *class;
+    int bit_rate;
+} G729DemuxerContext;
+
+static int g729_read_header(AVFormatContext *s)
+{
+    AVStream* st;
+    G729DemuxerContext *s1 = s->priv_data;
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id = AV_CODEC_ID_G729;
+    st->codec->sample_rate = 8000;
+    st->codec->channels = 1;
+
+    if (s1 && s1->bit_rate) {
+        s->bit_rate = s1->bit_rate;
+    }
+
+    if (s->bit_rate == 0) {
+        av_log(s, AV_LOG_DEBUG, "No bitrate specified. Assuming 8000 b/s\n");
+        s->bit_rate = 8000;
+    }
+
+    if (s->bit_rate == 6400) {
+        st->codec->block_align = 8;
+    } else if (s->bit_rate == 8000) {
+        st->codec->block_align = 10;
+    } else {
+        av_log(s, AV_LOG_ERROR, "Only 8000 b/s and 6400 b/s bitrates are supported. Provided: %d b/s\n", s->bit_rate);
+        return AVERROR_INVALIDDATA;
+    }
+
+    avpriv_set_pts_info(st, st->codec->block_align << 3, 1, st->codec->sample_rate);
+    return 0;
+}
+static int g729_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    int ret;
+
+    ret = av_get_packet(s->pb, pkt, s->streams[0]->codec->block_align);
+
+    pkt->stream_index = 0;
+    if (ret < 0)
+        return ret;
+
+    pkt->dts = pkt->pts = pkt->pos / s->streams[0]->codec->block_align;
+
+    return ret;
+}
+
+static const AVOption g729_options[] = {
+    { "bit_rate", "", offsetof(G729DemuxerContext, bit_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+    { NULL },
+};
+
+static const AVClass g729_demuxer_class = {
+    .class_name = "g729 demuxer",
+    .item_name  = av_default_item_name,
+    .option     = g729_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_g729_demuxer = {
+    .name           = "g729",
+    .long_name      = NULL_IF_CONFIG_SMALL("G.729 raw format demuxer"),
+    .priv_data_size = sizeof(G729DemuxerContext),
+    .read_header    = g729_read_header,
+    .read_packet    = g729_read_packet,
+    .flags          = AVFMT_GENERIC_INDEX,
+    .extensions     = "g729",
+    .priv_class     = &g729_demuxer_class,
+};
diff --git a/libavformat/gif.c b/libavformat/gif.c
index eb2db46..31b0101 100644
--- a/libavformat/gif.c
+++ b/libavformat/gif.c
@@ -2,20 +2,20 @@
  * Animated GIF muxer
  * Copyright (c) 2000 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/gopher.c b/libavformat/gopher.c
index a149f7f..9dc155a 100644
--- a/libavformat/gopher.c
+++ b/libavformat/gopher.c
@@ -5,20 +5,20 @@
  *
  * based on libavformat/http.c, Copyright (c) 2000, 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/gsmdec.c b/libavformat/gsmdec.c
index f0cb279..7ec3df5 100644
--- a/libavformat/gsmdec.c
+++ b/libavformat/gsmdec.c
@@ -47,7 +47,6 @@
         av_free_packet(pkt);
         return ret < 0 ? ret : AVERROR(EIO);
     }
-    pkt->size     = ret;
     pkt->duration = 1;
     pkt->pts      = pkt->pos / GSM_BLOCK_SIZE;
 
diff --git a/libavformat/gxf.c b/libavformat/gxf.c
index 04d75bd..c63cafb 100644
--- a/libavformat/gxf.c
+++ b/libavformat/gxf.c
@@ -2,20 +2,20 @@
  * GXF demuxer.
  * Copyright (c) 2006 Reimar Doeffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,9 +30,31 @@
     int64_t last_field;
     AVRational frames_per_second;
     int32_t fields_per_frame;
+    int64_t track_aux_data;
 };
 
 /**
+ * @brief parse gxf timecode and add it to metadata
+ */
+static int add_timecode_metadata(AVDictionary **pm, const char *key, uint32_t timecode, int fields_per_frame)
+{
+   char tmp[128];
+   int field  = timecode & 0xff;
+   int frame  = fields_per_frame ? field / fields_per_frame : field;
+   int second = (timecode >>  8) & 0xff;
+   int minute = (timecode >> 16) & 0xff;
+   int hour   = (timecode >> 24) & 0x1f;
+   int drop   = (timecode >> 29) & 1;
+   // bit 30: color_frame, unused
+   // ignore invalid time code
+   if (timecode >> 31)
+       return 0;
+   snprintf(tmp, sizeof(tmp), "%02d:%02d:%02d%c%02d",
+       hour, minute, second, drop ? ';' : ':', frame);
+   return av_dict_set(pm, key, tmp, 0);
+}
+
+/**
  * @brief parses a packet header, extracting type and length
  * @param pb AVIOContext to read header from
  * @param type detected packet type is stored here
@@ -210,6 +232,7 @@
 static void gxf_track_tags(AVIOContext *pb, int *len, struct gxf_stream_info *si) {
     si->frames_per_second = (AVRational){0, 0};
     si->fields_per_frame = 0;
+    si->track_aux_data = 0x80000000;
     while (*len >= 2) {
         GXFTrackTag tag = avio_r8(pb);
         int tlen = avio_r8(pb);
@@ -223,7 +246,9 @@
                 si->frames_per_second = fps_tag2avr(value);
             else if (tag == TRACK_FPF && (value == 1 || value == 2))
                 si->fields_per_frame = value;
-        } else
+        } else if (tlen == 8 && tag == TRACK_AUX)
+            si->track_aux_data = avio_rl64(pb);
+        else
             avio_skip(pb, tlen);
     }
 }
@@ -301,8 +326,6 @@
         track_id = avio_r8(pb);
         track_len = avio_rb16(pb);
         len -= track_len;
-        gxf_track_tags(pb, &track_len, si);
-        avio_skip(pb, track_len);
         if (!(track_type & 0x80)) {
            av_log(s, AV_LOG_ERROR, "invalid track type %x\n", track_type);
            continue;
@@ -313,6 +336,16 @@
            continue;
         }
         track_id &= 0x3f;
+        gxf_track_tags(pb, &track_len, si);
+        // check for timecode tracks
+        if (track_type == 7 || track_type == 8 || track_type == 24) {
+            add_timecode_metadata(&s->metadata, "timecode",
+                                  si->track_aux_data & 0xffffffff,
+                                  si->fields_per_frame);
+
+        }
+        avio_skip(pb, track_len);
+
         idx = get_sindex(s, track_id, track_type);
         if (idx < 0) continue;
         st = s->streams[idx];
@@ -347,10 +380,21 @@
             avio_skip(pb, 0x30); // payload description
             fps = fps_umf2avr(avio_rl32(pb));
             if (!main_timebase.num || !main_timebase.den) {
+                av_log(s, AV_LOG_WARNING, "No FPS track tag, using UMF fps tag."
+                                          " This might give wrong results.\n");
                 // this may not always be correct, but simply the best we can get
                 main_timebase.num = fps.den;
                 main_timebase.den = fps.num * 2;
             }
+
+            if (len >= 0x18) {
+                len -= 0x18;
+                avio_skip(pb, 0x10);
+                add_timecode_metadata(&s->metadata, "timecode_at_mark_in",
+                                      avio_rl32(pb), si->fields_per_frame);
+                add_timecode_metadata(&s->metadata, "timecode_at_mark_out",
+                                      avio_rl32(pb), si->fields_per_frame);
+            }
         } else
             av_log(s, AV_LOG_INFO, "UMF packet too short\n");
     } else
@@ -369,7 +413,7 @@
 
 #define READ_ONE() \
     { \
-        if (!max_interval-- || pb->eof_reached) \
+        if (!max_interval-- || url_feof(pb)) \
             goto out; \
         tmp = tmp << 8 | avio_r8(pb); \
     }
@@ -431,7 +475,7 @@
         int field_nr, field_info, skip = 0;
         int stream_index;
         if (!parse_packet_header(pb, &pkt_type, &pkt_len)) {
-            if (!pb->eof_reached)
+            if (!url_feof(pb))
                 av_log(s, AV_LOG_ERROR, "sync lost\n");
             return -1;
         }
@@ -483,7 +527,7 @@
 
         return ret;
     }
-    return AVERROR(EIO);
+    return AVERROR_EOF;
 }
 
 static int gxf_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) {
diff --git a/libavformat/gxf.h b/libavformat/gxf.h
index c1ac399..dcdcdef 100644
--- a/libavformat/gxf.h
+++ b/libavformat/gxf.h
@@ -2,20 +2,20 @@
  * GXF demuxer
  * copyright (c) 2006 Reimar Doeffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/gxfenc.c b/libavformat/gxfenc.c
index c5fb0ae..1c2ff5d 100644
--- a/libavformat/gxfenc.c
+++ b/libavformat/gxfenc.c
@@ -2,25 +2,28 @@
  * GXF muxer.
  * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/intfloat.h"
+#include "libavutil/opt.h"
 #include "libavutil/mathematics.h"
+#include "libavutil/timecode.h"
 #include "avformat.h"
 #include "internal.h"
 #include "gxf.h"
@@ -29,6 +32,18 @@
 
 #define GXF_AUDIO_PACKET_SIZE 65536
 
+#define GXF_TIMECODE(c, d, h, m, s, f) \
+    ((c) << 30 | (d) << 29 | (h) << 24 | (m) << 16 | (s) << 8 | (f))
+
+typedef struct GXFTimecode{
+    int hh;
+    int mm;
+    int ss;
+    int ff;
+    int color;
+    int drop;
+} GXFTimecode;
+
 typedef struct GXFStreamContext {
     AudioInterleaveContext aic;
     uint32_t track_type;
@@ -49,6 +64,7 @@
 } GXFStreamContext;
 
 typedef struct GXFContext {
+    AVClass *av_class;
     uint32_t nb_fields;
     uint16_t audio_tracks;
     uint16_t mpeg_tracks;
@@ -67,6 +83,7 @@
     uint64_t *map_offsets;    ///< offset of map packets
     unsigned map_offsets_nb;
     unsigned packet_count;
+    GXFTimecode tc;
 } GXFContext;
 
 static const struct {
@@ -189,30 +206,33 @@
     else
         starting_line = 23; // default PAL
 
-    size = snprintf(buffer, 1024, "Ver 1\nBr %.6f\nIpg 1\nPpi %d\nBpiop %d\n"
+    size = snprintf(buffer, sizeof(buffer), "Ver 1\nBr %.6f\nIpg 1\nPpi %d\nBpiop %d\n"
                     "Pix 0\nCf %d\nCg %d\nSl %d\nnl16 %d\nVi 1\nf1 1\n",
                     (float)st->codec->bit_rate, sc->p_per_gop, sc->b_per_i_or_p,
                     st->codec->pix_fmt == AV_PIX_FMT_YUV422P ? 2 : 1, sc->first_gop_closed == 1,
                     starting_line, (st->codec->height + 15) / 16);
+    av_assert0(size < sizeof(buffer));
     avio_w8(pb, TRACK_MPG_AUX);
     avio_w8(pb, size + 1);
     avio_write(pb, (uint8_t *)buffer, size + 1);
     return size + 3;
 }
 
-static int gxf_write_timecode_auxiliary(AVIOContext *pb, GXFStreamContext *sc)
+static int gxf_write_timecode_auxiliary(AVIOContext *pb, GXFContext *gxf)
 {
-    avio_w8(pb, 0); /* fields */
-    avio_w8(pb, 0); /* seconds */
-    avio_w8(pb, 0); /* minutes */
-    avio_w8(pb, 0); /* flags + hours */
+    uint32_t timecode = GXF_TIMECODE(gxf->tc.color, gxf->tc.drop,
+                                     gxf->tc.hh, gxf->tc.mm,
+                                     gxf->tc.ss, gxf->tc.ff);
+
+    avio_wl32(pb, timecode);
     /* reserved */
-    avio_wb32(pb, 0);
+    avio_wl32(pb, 0);
     return 8;
 }
 
 static int gxf_write_track_description(AVFormatContext *s, GXFStreamContext *sc, int index)
 {
+    GXFContext *gxf = s->priv_data;
     AVIOContext *pb = s->pb;
     int64_t pos;
     int mpeg = sc->track_type == 4 || sc->track_type == 9;
@@ -236,7 +256,7 @@
         avio_w8(pb, TRACK_AUX);
         avio_w8(pb, 8);
         if (sc->track_type == 3)
-            gxf_write_timecode_auxiliary(pb, sc);
+            gxf_write_timecode_auxiliary(pb, gxf);
         else
             avio_wl64(pb, 0);
     }
@@ -343,8 +363,9 @@
 
     if (!rewrite) {
         if (!(gxf->map_offsets_nb % 30)) {
-            gxf->map_offsets = av_realloc(gxf->map_offsets,
-                                          (gxf->map_offsets_nb+30)*sizeof(*gxf->map_offsets));
+            gxf->map_offsets = av_realloc_f(gxf->map_offsets,
+                                            sizeof(*gxf->map_offsets),
+                                            gxf->map_offsets_nb+30);
             if (!gxf->map_offsets) {
                 av_log(s, AV_LOG_ERROR, "could not realloc map offsets\n");
                 return -1;
@@ -397,25 +418,36 @@
     int timecode_base = gxf->time_base.den == 60000 ? 60 : 50;
     int64_t timestamp = 0;
     AVDictionaryEntry *t;
-    uint32_t timecode;
+    uint64_t nb_fields;
+    uint32_t timecode_in; // timecode at mark in
+    uint32_t timecode_out; // timecode at mark out
 
     if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
         timestamp = ff_iso8601_to_unix_time(t->value);
 
-    // XXX drop frame
-    timecode =
-        gxf->nb_fields / (timecode_base * 3600) % 24 << 24 | // hours
-        gxf->nb_fields / (timecode_base * 60) % 60   << 16 | // minutes
-        gxf->nb_fields /  timecode_base % 60         <<  8 | // seconds
-        gxf->nb_fields %  timecode_base;                     // fields
+    timecode_in = GXF_TIMECODE(gxf->tc.color, gxf->tc.drop,
+                               gxf->tc.hh, gxf->tc.mm,
+                               gxf->tc.ss, gxf->tc.ff);
+
+    nb_fields = gxf->nb_fields +
+                gxf->tc.hh * (timecode_base * 3600) +
+                gxf->tc.mm * (timecode_base * 60)   +
+                gxf->tc.ss * timecode_base          +
+                gxf->tc.ff;
+
+    timecode_out = GXF_TIMECODE(gxf->tc.color, gxf->tc.drop,
+                                nb_fields / (timecode_base * 3600) % 24,
+                                nb_fields / (timecode_base * 60)   % 60,
+                                nb_fields /  timecode_base % 60,
+                                nb_fields %  timecode_base);
 
     avio_wl32(pb, gxf->flags);
     avio_wl32(pb, gxf->nb_fields); /* length of the longest track */
     avio_wl32(pb, gxf->nb_fields); /* length of the shortest track */
     avio_wl32(pb, 0); /* mark in */
     avio_wl32(pb, gxf->nb_fields); /* mark out */
-    avio_wl32(pb, 0); /* timecode mark in */
-    avio_wl32(pb, timecode); /* timecode mark out */
+    avio_wl32(pb, timecode_in); /* timecode mark in */
+    avio_wl32(pb, timecode_out); /* timecode mark out */
     avio_wl64(pb, timestamp); /* modification time */
     avio_wl64(pb, timestamp); /* creation time */
     avio_wl16(pb, 0); /* reserved */
@@ -490,9 +522,9 @@
     return 32;
 }
 
-static int gxf_write_umf_media_timecode(AVIOContext *pb, GXFStreamContext *sc)
+static int gxf_write_umf_media_timecode(AVIOContext *pb, int drop)
 {
-    avio_wl32(pb, 1); /* non drop frame */
+    avio_wl32(pb, drop); /* drop frame */
     avio_wl32(pb, 0); /* reserved */
     avio_wl32(pb, 0); /* reserved */
     avio_wl32(pb, 0); /* reserved */
@@ -561,7 +593,7 @@
         avio_wl32(pb, 0); /* reserved */
 
         if (sc == &gxf->timecode_track)
-            gxf_write_umf_media_timecode(pb, sc); /* 8 0bytes */
+            gxf_write_umf_media_timecode(pb, gxf->tc.drop);
         else {
             AVStream *st = s->streams[i];
             switch (st->codec->codec_id) {
@@ -624,6 +656,25 @@
     sc->fields = vsc->fields;
 }
 
+static int gxf_init_timecode(AVFormatContext *s, GXFTimecode *tc, const char *tcstr, int fields)
+{
+    char c;
+
+    if (sscanf(tcstr, "%d:%d:%d%c%d", &tc->hh, &tc->mm, &tc->ss, &c, &tc->ff) != 5) {
+        av_log(s, AV_LOG_ERROR, "unable to parse timecode, "
+                                "syntax: hh:mm:ss[:;.]ff\n");
+        return -1;
+    }
+
+    tc->color = 0;
+    tc->drop = c != ':';
+
+    if (fields == 2)
+        tc->ff = tc->ff * 2;
+
+    return 0;
+}
+
 static int gxf_write_header(AVFormatContext *s)
 {
     AVIOContext *pb = s->pb;
@@ -631,9 +682,10 @@
     GXFStreamContext *vsc = NULL;
     uint8_t tracks[255] = {0};
     int i, media_info = 0;
+    AVDictionaryEntry *tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
 
     if (!pb->seekable) {
-        av_log(s, AV_LOG_ERROR, "gxf muxer does not support streamed output, patch welcome");
+        av_log(s, AV_LOG_ERROR, "gxf muxer does not support streamed output, patch welcome\n");
         return -1;
     }
 
@@ -691,6 +743,8 @@
                        "gxf muxer only accepts PAL or NTSC resolutions currently\n");
                 return -1;
             }
+            if (!tcr)
+                tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
             avpriv_set_pts_info(st, 64, gxf->time_base.num, gxf->time_base.den);
             if (gxf_find_lines_index(st) < 0)
                 sc->lines_index = -1;
@@ -742,6 +796,9 @@
     if (ff_audio_interleave_init(s, GXF_samples_per_frame, (AVRational){ 1, 48000 }) < 0)
         return -1;
 
+    if (tcr)
+        gxf_init_timecode(s, &gxf->tc, tcr->value, vsc->fields);
+
     gxf_init_timecode_track(&gxf->timecode_track, vsc);
     gxf->flags |= 0x200000; // time code track is non-drop frame
 
@@ -874,8 +931,9 @@
 
     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
         if (!(gxf->flt_entries_nb % 500)) {
-            gxf->flt_entries = av_realloc(gxf->flt_entries,
-                                          (gxf->flt_entries_nb+500)*sizeof(*gxf->flt_entries));
+            gxf->flt_entries = av_realloc_f(gxf->flt_entries,
+                                            sizeof(*gxf->flt_entries),
+                                            gxf->flt_entries_nb+500);
             if (!gxf->flt_entries) {
                 av_log(s, AV_LOG_ERROR, "could not reallocate flt entries\n");
                 return -1;
diff --git a/libavformat/h261dec.c b/libavformat/h261dec.c
index 9b9e3f4..1b254d6 100644
--- a/libavformat/h261dec.c
+++ b/libavformat/h261dec.c
@@ -2,20 +2,20 @@
  * RAW H.261 video demuxer
  * Copyright (c) 2009 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/h263dec.c b/libavformat/h263dec.c
index 101ef51..667fdbd 100644
--- a/libavformat/h263dec.c
+++ b/libavformat/h263dec.c
@@ -2,20 +2,20 @@
  * RAW H.263 video demuxer
  * Copyright (c) 2009 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/h264dec.c b/libavformat/h264dec.c
index 0c85bae..9c67ab9 100644
--- a/libavformat/h264dec.c
+++ b/libavformat/h264dec.c
@@ -2,20 +2,20 @@
  * RAW H.264 video demuxer
  * Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 1f6b7d5..6675a1a 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -2,20 +2,20 @@
  * Apple HTTP Live Streaming demuxer
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -42,7 +42,7 @@
  * An apple http stream consists of a playlist with media segment files,
  * played sequentially. There may be several playlists with the same
  * video content, in different bandwidth variants, that are played in
- * parallel (preferrably only one bandwidth variant at a time). In this case,
+ * parallel (preferably only one bandwidth variant at a time). In this case,
  * the user supplied the url to a main playlist that only lists the variant
  * playlists.
  *
@@ -212,9 +212,14 @@
     int close_in = 0;
 
     if (!in) {
+        AVDictionary *opts = NULL;
         close_in = 1;
-        if ((ret = avio_open2(&in, url, AVIO_FLAG_READ,
-                              c->interrupt_callback, NULL)) < 0)
+        /* Some HLS servers dont like being sent the range header */
+        av_dict_set(&opts, "seekable", "0", 0);
+        ret = avio_open2(&in, url, AVIO_FLAG_READ,
+                         c->interrupt_callback, &opts);
+        av_dict_free(&opts);
+        if (ret < 0)
             return ret;
     }
 
@@ -228,7 +233,7 @@
         free_segment_list(var);
         var->finished = 0;
     }
-    while (!in->eof_reached) {
+    while (!url_feof(in)) {
         read_chomp_line(in, line, sizeof(line));
         if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
             struct variant_info info = {{0}};
@@ -325,17 +330,20 @@
 
 static int open_input(struct variant *var)
 {
+    AVDictionary *opts = NULL;
+    int ret;
     struct segment *seg = var->segments[var->cur_seq_no - var->start_seq_no];
+    av_dict_set(&opts, "seekable", "0", 0);
     if (seg->key_type == KEY_NONE) {
-        return ffurl_open(&var->input, seg->url, AVIO_FLAG_READ,
-                          &var->parent->interrupt_callback, NULL);
+        ret = ffurl_open(&var->input, seg->url, AVIO_FLAG_READ,
+                          &var->parent->interrupt_callback, &opts);
+        goto cleanup;
     } else if (seg->key_type == KEY_AES_128) {
         char iv[33], key[33], url[MAX_URL_SIZE];
-        int ret;
         if (strcmp(seg->key, var->key_url)) {
             URLContext *uc;
             if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ,
-                           &var->parent->interrupt_callback, NULL) == 0) {
+                           &var->parent->interrupt_callback, &opts) == 0) {
                 if (ffurl_read_complete(uc, var->key, sizeof(var->key))
                     != sizeof(var->key)) {
                     av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
@@ -357,17 +365,25 @@
             snprintf(url, sizeof(url), "crypto:%s", seg->url);
         if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ,
                                &var->parent->interrupt_callback)) < 0)
-            return ret;
+            goto cleanup;
         av_opt_set(var->input->priv_data, "key", key, 0);
         av_opt_set(var->input->priv_data, "iv", iv, 0);
-        if ((ret = ffurl_connect(var->input, NULL)) < 0) {
+        /* Need to repopulate options */
+        av_dict_free(&opts);
+        av_dict_set(&opts, "seekable", "0", 0);
+        if ((ret = ffurl_connect(var->input, &opts)) < 0) {
             ffurl_close(var->input);
             var->input = NULL;
-            return ret;
+            goto cleanup;
         }
-        return 0;
+        ret = 0;
     }
-    return AVERROR(ENOSYS);
+    else
+      ret = AVERROR(ENOSYS);
+
+cleanup:
+    av_dict_free(&opts);
+    return ret;
 }
 
 static int read_data(void *opaque, uint8_t *buf, int buf_size)
@@ -427,7 +443,7 @@
     c->end_of_segment = 1;
     c->cur_seq_no = v->cur_seq_no;
 
-    if (v->ctx && v->ctx->nb_streams) {
+    if (v->ctx && v->ctx->nb_streams && v->parent->nb_streams >= v->stream_offset + v->ctx->nb_streams) {
         v->needed = 0;
         for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams;
              i++) {
@@ -517,6 +533,7 @@
              * so avformat_close_input shouldn't be called. If
              * avformat_open_input fails below, it frees and zeros the
              * context, so it doesn't need any special treatment like this. */
+            av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", v->segments[0]->url);
             avformat_free_context(v->ctx);
             v->ctx = NULL;
             goto fail;
@@ -525,7 +542,12 @@
         ret = avformat_open_input(&v->ctx, v->segments[0]->url, in_fmt, NULL);
         if (ret < 0)
             goto fail;
+
         v->stream_offset = stream_offset;
+        v->ctx->ctx_flags &= ~AVFMTCTX_NOHEADER;
+        ret = avformat_find_stream_info(v->ctx, NULL);
+        if (ret < 0)
+            goto fail;
         snprintf(bitrate_str, sizeof(bitrate_str), "%d", v->bandwidth);
         /* Create new AVStreams for each stream in this variant */
         for (j = 0; j < v->ctx->nb_streams; j++) {
@@ -560,7 +582,7 @@
 
     /* Check if any new streams are needed */
     for (i = 0; i < c->n_variants; i++)
-        c->variants[i]->cur_needed = 0;;
+        c->variants[i]->cur_needed = 0;
 
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st = s->streams[i];
@@ -610,7 +632,7 @@
                 AVStream *st;
                 ret = av_read_frame(var->ctx, &var->pkt);
                 if (ret < 0) {
-                    if (!var->pb.eof_reached)
+                    if (!url_feof(&var->pb) && ret != AVERROR_EOF)
                         return ret;
                     reset_packet(&var->pkt);
                     break;
@@ -640,9 +662,21 @@
         }
         /* Check if this stream has the packet with the lowest dts */
         if (var->pkt.data) {
-            if (minvariant < 0 ||
-                var->pkt.dts < c->variants[minvariant]->pkt.dts)
+            if(minvariant < 0) {
                 minvariant = i;
+            } else {
+                struct variant *minvar = c->variants[minvariant];
+                int64_t dts    =    var->pkt.dts;
+                int64_t mindts = minvar->pkt.dts;
+                AVStream *st   =    var->ctx->streams[   var->pkt.stream_index];
+                AVStream *minst= minvar->ctx->streams[minvar->pkt.stream_index];
+
+                if(   st->start_time != AV_NOPTS_VALUE)    dts -=    st->start_time;
+                if(minst->start_time != AV_NOPTS_VALUE) mindts -= minst->start_time;
+
+                if (av_compare_ts(dts, st->time_base, mindts, minst->time_base) < 0)
+                    minvariant = i;
+            }
         }
     }
     if (c->end_of_segment) {
@@ -696,10 +730,11 @@
         /* Reset reading */
         struct variant *var = c->variants[i];
         int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? 0 :
-                      av_rescale_rnd(c->first_timestamp, 1,
-                          stream_index >= 0 ? s->streams[stream_index]->time_base.den : AV_TIME_BASE,
-                          flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP);
-        if (var->input) {
+                      av_rescale_rnd(c->first_timestamp, 1, stream_index >= 0 ?
+                               s->streams[stream_index]->time_base.den :
+                               AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ?
+                               AV_ROUND_DOWN : AV_ROUND_UP);
+         if (var->input) {
             ffurl_close(var->input);
             var->input = NULL;
         }
diff --git a/libavformat/hlsproto.c b/libavformat/hlsproto.c
index 179bdf1..a290c88 100644
--- a/libavformat/hlsproto.c
+++ b/libavformat/hlsproto.c
@@ -2,20 +2,20 @@
  * Apple HTTP Live Streaming Protocol Handler
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,7 +36,7 @@
  * An apple http stream consists of a playlist with media segment files,
  * played sequentially. There may be several playlists with the same
  * video content, in different bandwidth variants, that are played in
- * parallel (preferrably only one bandwidth variant at a time). In this case,
+ * parallel (preferably only one bandwidth variant at a time). In this case,
  * the user supplied the url to a main playlist that only lists the variant
  * playlists.
  *
@@ -125,7 +125,7 @@
 
     free_segment_list(s);
     s->finished = 0;
-    while (!in->eof_reached) {
+    while (!url_feof(in)) {
         read_chomp_line(in, line, sizeof(line));
         if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
             struct variant_info info = {{0}};
diff --git a/libavformat/http.c b/libavformat/http.c
index 9666ca3..8665452 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -1,21 +1,21 @@
 /*
- * HTTP protocol for avconv client
+ * HTTP protocol for ffmpeg client
  * Copyright (c) 2000, 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,7 +29,7 @@
 #include "url.h"
 #include "libavutil/opt.h"
 
-/* XXX: POST protocol is not completely implemented because avconv uses
+/* XXX: POST protocol is not completely implemented because ffmpeg uses
    only a subset of it. */
 
 /* The IO buffer size is unrelated to the max URL size in itself, but needs
@@ -46,28 +46,36 @@
     int line_count;
     int http_code;
     int64_t chunksize;      /**< Used if "Transfer-Encoding: chunked" otherwise -1. */
+    char *user_agent;
     int64_t off, filesize;
     char location[MAX_URL_SIZE];
     HTTPAuthState auth_state;
     HTTPAuthState proxy_auth_state;
     char *headers;
     int willclose;          /**< Set if the server correctly handles Connection: close and will close the connection after feeding us the content. */
+    int seekable;           /**< Control seekability, 0 = disable, 1 = enable, -1 = probe. */
     int chunked_post;
     int end_chunked_post;   /**< A flag which indicates if the end of chunked encoding has been sent. */
     int end_header;         /**< A flag which indicates we have finished to read POST reply. */
     int multiple_requests;  /**< A flag which indicates if we use persistent connections. */
     uint8_t *post_data;
     int post_datalen;
+    int is_akamai;
+    int rw_timeout;
 } HTTPContext;
 
 #define OFFSET(x) offsetof(HTTPContext, x)
 #define D AV_OPT_FLAG_DECODING_PARAM
 #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 },
 {"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 },
+{"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 },
 {NULL}
 };
 #define HTTP_CLASS(flavor)\
@@ -145,8 +153,15 @@
     ff_url_join(buf, sizeof(buf), lower_proto, NULL, hostname, port, NULL);
 
     if (!s->hd) {
+        AVDictionary *opts = NULL;
+        char opts_format[20];
+        if (s->rw_timeout != -1) {
+            snprintf(opts_format, sizeof(opts_format), "%d", s->rw_timeout);
+            av_dict_set(&opts, "timeout", opts_format, 0);
+        } /* if option is not given, don't pass it and let tcp use its own default */
         err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE,
-                         &h->interrupt_callback, NULL);
+                         &h->interrupt_callback, &opts);
+        av_dict_free(&opts);
         if (err < 0)
             goto fail;
     }
@@ -159,8 +174,7 @@
     if (s->http_code == 401) {
         if ((cur_auth_type == HTTP_AUTH_NONE || s->auth_state.stale) &&
             s->auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) {
-            ffurl_close(s->hd);
-            s->hd = NULL;
+            ffurl_closep(&s->hd);
             goto redo;
         } else
             goto fail;
@@ -168,8 +182,7 @@
     if (s->http_code == 407) {
         if ((cur_proxy_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) &&
             s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) {
-            ffurl_close(s->hd);
-            s->hd = NULL;
+            ffurl_closep(&s->hd);
             goto redo;
         } else
             goto fail;
@@ -177,8 +190,7 @@
     if ((s->http_code == 301 || s->http_code == 302 || s->http_code == 303 || s->http_code == 307)
         && location_changed == 1) {
         /* url moved, get next */
-        ffurl_close(s->hd);
-        s->hd = NULL;
+        ffurl_closep(&s->hd);
         if (redirects++ >= MAX_REDIRECTS)
             return AVERROR(EIO);
         /* Restart the authentication process with the new target, which
@@ -191,8 +203,7 @@
     return 0;
  fail:
     if (s->hd)
-        ffurl_close(s->hd);
-    s->hd = NULL;
+        ffurl_closep(&s->hd);
     return AVERROR(EIO);
 }
 
@@ -210,7 +221,10 @@
 {
     HTTPContext *s = h->priv_data;
 
-    h->is_streamed = 1;
+    if( s->seekable == 1 )
+        h->is_streamed = 0;
+    else
+        h->is_streamed = 1;
 
     s->filesize = -1;
     av_strlcpy(s->location, uri, sizeof(s->location));
@@ -321,8 +335,9 @@
                 if ((slash = strchr(p, '/')) && strlen(slash) > 0)
                     s->filesize = strtoll(slash+1, NULL, 10);
             }
-            h->is_streamed = 0; /* we _can_ in fact seek */
-        } else if (!av_strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5)) {
+            if (s->seekable == -1 && (!s->is_akamai || s->filesize != 2147483647))
+                h->is_streamed = 0; /* we _can_ in fact seek */
+        } else if (!av_strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5) && s->seekable == -1) {
             h->is_streamed = 0;
         } else if (!av_strcasecmp (tag, "Transfer-Encoding") && !av_strncasecmp(p, "chunked", 7)) {
             s->filesize = -1;
@@ -336,6 +351,8 @@
         } else if (!av_strcasecmp (tag, "Connection")) {
             if (!strcmp(p, "close"))
                 s->willclose = 1;
+        } else if (!av_strcasecmp (tag, "Server") && !av_strcasecmp (p, "AkamaiGHost")) {
+            s->is_akamai = 1;
         }
     }
     return 1;
@@ -380,7 +397,7 @@
 {
     HTTPContext *s = h->priv_data;
     int post, err;
-    char headers[1024] = "";
+    char headers[4096] = "";
     char *authstr = NULL, *proxyauthstr = NULL;
     int64_t off = s->off;
     int len = 0;
@@ -405,12 +422,16 @@
 
     /* set default headers if needed */
     if (!has_header(s->headers, "\r\nUser-Agent: "))
-       len += av_strlcatf(headers + len, sizeof(headers) - len,
-                          "User-Agent: %s\r\n", LIBAVFORMAT_IDENT);
+        len += av_strlcatf(headers + len, sizeof(headers) - len,
+                           "User-Agent: %s\r\n",
+                           s->user_agent ? s->user_agent : LIBAVFORMAT_IDENT);
     if (!has_header(s->headers, "\r\nAccept: "))
         len += av_strlcpy(headers + len, "Accept: */*\r\n",
                           sizeof(headers) - len);
-    if (!has_header(s->headers, "\r\nRange: ") && !post)
+    // Note: we send this on purpose even when s->off is 0 when we're probing,
+    // since it allows us to detect more reliably if a (non-conforming)
+    // server supports seeking by analysing the reply headers.
+    if (!has_header(s->headers, "\r\nRange: ") && !post && (s->off > 0 || s->seekable == -1))
         len += av_strlcatf(headers + len, sizeof(headers) - len,
                            "Range: bytes=%"PRId64"-\r\n", s->off);
 
@@ -600,7 +621,7 @@
     }
 
     if (s->hd)
-        ffurl_close(s->hd);
+        ffurl_closep(&s->hd);
     return ret;
 }
 
@@ -683,7 +704,7 @@
 {
     HTTPContext *s = h->priv_data;
     if (s->hd)
-        ffurl_close(s->hd);
+        ffurl_closep(&s->hd);
     return 0;
 }
 
@@ -697,8 +718,13 @@
     HTTPAuthType cur_auth_type;
     char *authstr;
     int new_loc;
+    AVDictionary *opts = NULL;
+    char opts_format[20];
 
-    h->is_streamed = 1;
+    if( s->seekable == 1 )
+        h->is_streamed = 0;
+    else
+        h->is_streamed = 1;
 
     av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port,
                  pathbuf, sizeof(pathbuf), uri);
@@ -710,8 +736,13 @@
     ff_url_join(lower_url, sizeof(lower_url), "tcp", NULL, hostname, port,
                 NULL);
 redo:
+    if (s->rw_timeout != -1) {
+        snprintf(opts_format, sizeof(opts_format), "%d", s->rw_timeout);
+        av_dict_set(&opts, "timeout", opts_format, 0);
+    } /* if option is not given, don't pass it and let tcp use its own default */
     ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE,
-                     &h->interrupt_callback, NULL);
+                     &h->interrupt_callback, &opts);
+    av_dict_free(&opts);
     if (ret < 0)
         return ret;
 
@@ -754,8 +785,7 @@
     if (s->http_code == 407 &&
         (cur_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) &&
         s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 2) {
-        ffurl_close(s->hd);
-        s->hd = NULL;
+        ffurl_closep(&s->hd);
         goto redo;
     }
 
diff --git a/libavformat/http.h b/libavformat/http.h
index 3579ad7..a19ad8e 100644
--- a/libavformat/http.h
+++ b/libavformat/http.h
@@ -2,20 +2,20 @@
  * HTTP definitions
  * Copyright (c) 2010 Josh Allmann
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -38,9 +38,9 @@
 /**
  * Send a new HTTP request, reusing the old connection.
  *
- * @param h pointer to the ressource
+ * @param h pointer to the resource
  * @param uri uri used to perform the request
- * @return a negative value if an error condition occured, 0
+ * @return a negative value if an error condition occurred, 0
  * otherwise
  */
 int ff_http_do_new_request(URLContext *h, const char *uri);
diff --git a/libavformat/httpauth.c b/libavformat/httpauth.c
index 774ee21..e97aee1 100644
--- a/libavformat/httpauth.c
+++ b/libavformat/httpauth.c
@@ -2,20 +2,20 @@
  * HTTP authentication
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/httpauth.h b/libavformat/httpauth.h
index 99bf43f..fc17c94 100644
--- a/libavformat/httpauth.h
+++ b/libavformat/httpauth.h
@@ -2,20 +2,20 @@
  * HTTP authentication
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/icodec.c b/libavformat/icodec.c
new file mode 100644
index 0000000..37909aa
--- /dev/null
+++ b/libavformat/icodec.c
@@ -0,0 +1,181 @@
+/*
+ * Microsoft Windows ICO demuxer
+ * Copyright (c) 2011 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
+ * Microsoft Windows ICO demuxer
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "libavcodec/bytestream.h"
+#include "libavcodec/bmp.h"
+#include "avformat.h"
+#include "internal.h"
+
+typedef struct {
+    int offset;
+    int size;
+    int nb_pal;
+} IcoImage;
+
+typedef struct {
+    int current_image;
+    int nb_images;
+    IcoImage * images;
+} IcoDemuxContext;
+
+static int probe(AVProbeData *p)
+{
+    if (AV_RL16(p->buf) == 0 && AV_RL16(p->buf + 2) == 1 && AV_RL16(p->buf + 4))
+        return AVPROBE_SCORE_MAX / 3;
+    return 0;
+}
+
+static int read_header(AVFormatContext *s)
+{
+    IcoDemuxContext *ico = s->priv_data;
+    AVIOContext *pb = s->pb;
+    int i;
+
+    avio_skip(pb, 4);
+    ico->nb_images = avio_rl16(pb);
+
+    ico->images = av_malloc(ico->nb_images * sizeof(IcoImage));
+    if (!ico->images)
+        return AVERROR(ENOMEM);
+
+    for (i = 0; i < ico->nb_images; i++) {
+        AVStream *st;
+        int tmp;
+
+        if (avio_seek(pb, 6 + i * 16, SEEK_SET) < 0)
+            break;
+
+        st = avformat_new_stream(s, NULL);
+        if (!st)
+            return AVERROR(ENOMEM);
+
+        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+        st->codec->width      = avio_r8(pb);
+        st->codec->height     = avio_r8(pb);
+        ico->images[i].nb_pal = avio_r8(pb);
+        if (ico->images[i].nb_pal == 255)
+            ico->images[i].nb_pal = 0;
+
+        avio_skip(pb, 5);
+
+        ico->images[i].size   = avio_rl32(pb);
+        ico->images[i].offset = avio_rl32(pb);
+
+        if (avio_seek(pb, ico->images[i].offset, SEEK_SET) < 0)
+            break;
+
+        switch(avio_rl32(pb)) {
+        case MKTAG(0x89, 'P', 'N', 'G'):
+            st->codec->codec_id = AV_CODEC_ID_PNG;
+            st->codec->width    = 0;
+            st->codec->height   = 0;
+            break;
+        case 40:
+            if (ico->images[i].size < 40)
+                return AVERROR_INVALIDDATA;
+            st->codec->codec_id = AV_CODEC_ID_BMP;
+            tmp = avio_rl32(pb);
+            if (tmp)
+                st->codec->width = tmp;
+            tmp = avio_rl32(pb);
+            if (tmp)
+                st->codec->height = tmp / 2;
+            break;
+        default:
+            av_log_ask_for_sample(s, "unsupported codec\n");
+            return AVERROR_INVALIDDATA;
+        }
+    }
+
+    return 0;
+}
+
+static int read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    IcoDemuxContext *ico = s->priv_data;
+    IcoImage *image;
+    AVIOContext *pb = s->pb;
+    AVStream *st = s->streams[0];
+    int ret;
+
+    if (ico->current_image >= ico->nb_images)
+        return AVERROR(EIO);
+
+    image = &ico->images[ico->current_image];
+
+    if ((ret = avio_seek(pb, image->offset, SEEK_SET)) < 0)
+        return ret;
+
+    if (s->streams[ico->current_image]->codec->codec_id == AV_CODEC_ID_PNG) {
+        if ((ret = av_get_packet(pb, pkt, image->size)) < 0)
+            return ret;
+    } else {
+        uint8_t *buf;
+        if ((ret = av_new_packet(pkt, 14 + image->size)) < 0)
+            return ret;
+        buf = pkt->data;
+
+        /* add BMP header */
+        bytestream_put_byte(&buf, 'B');
+        bytestream_put_byte(&buf, 'M');
+        bytestream_put_le32(&buf, pkt->size);
+        bytestream_put_le16(&buf, 0);
+        bytestream_put_le16(&buf, 0);
+        bytestream_put_le32(&buf, 0);
+
+        if ((ret = avio_read(pb, buf, image->size)) < 0)
+            return ret;
+
+        st->codec->bits_per_coded_sample = AV_RL16(buf + 14);
+
+        if (AV_RL32(buf + 32))
+            image->nb_pal = AV_RL32(buf + 32);
+
+        if (st->codec->bits_per_coded_sample <= 8 && !image->nb_pal) {
+            image->nb_pal = 1 << st->codec->bits_per_coded_sample;
+            AV_WL32(buf + 32, image->nb_pal);
+        }
+
+        AV_WL32(buf - 4, 14 + 40 + image->nb_pal * 4);
+        AV_WL32(buf + 8, AV_RL32(buf + 8) / 2);
+    }
+
+    pkt->stream_index = ico->current_image++;
+    pkt->flags |= AV_PKT_FLAG_KEY;
+
+    return 0;
+}
+
+AVInputFormat ff_ico_demuxer = {
+    .name           = "ico",
+    .long_name      = NULL_IF_CONFIG_SMALL("Microsoft Windows ICO"),
+    .priv_data_size = sizeof(IcoDemuxContext),
+    .read_probe     = probe,
+    .read_header    = read_header,
+    .read_packet    = read_packet,
+    .flags          = AVFMT_NOTIMESTAMPS,
+};
diff --git a/libavformat/icoenc.c b/libavformat/icoenc.c
new file mode 100644
index 0000000..12f959e
--- /dev/null
+++ b/libavformat/icoenc.c
@@ -0,0 +1,204 @@
+/*
+ * Microsoft Windows ICO muxer
+ * Copyright (c) 2012 Michael Bradshaw <mbradshaw@sorensonmedia.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
+ * Microsoft Windows ICO muxer
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "libavutil/pixdesc.h"
+#include "avformat.h"
+
+typedef struct {
+    int offset;
+    int size;
+    unsigned char width;
+    unsigned char height;
+    short bits;
+} IcoImage;
+
+typedef struct {
+    int current_image;
+    int nb_images;
+    IcoImage *images;
+} IcoMuxContext;
+
+static int ico_check_attributes(AVFormatContext *s, const AVCodecContext *c)
+{
+    if (c->codec_id == 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);
+        } else if (c->pix_fmt != AV_PIX_FMT_PAL8 &&
+                   c->pix_fmt != AV_PIX_FMT_RGB555LE &&
+                   c->pix_fmt != AV_PIX_FMT_BGR24 &&
+                   c->pix_fmt != AV_PIX_FMT_BGRA) {
+            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) {
+        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);
+        }
+    } else {
+        av_log(s, AV_LOG_ERROR, "Unsupported codec %s\n", c->codec_name);
+        return AVERROR(EINVAL);
+    }
+
+    if (c->width > 256 ||
+        c->height > 256) {
+        av_log(s, AV_LOG_ERROR, "Unsupported dimensions %dx%d (dimensions cannot exceed 256x256)\n", c->width, c->height);
+        return AVERROR(EINVAL);
+    }
+
+    return 0;
+}
+
+static int ico_write_header(AVFormatContext *s)
+{
+    IcoMuxContext *ico = s->priv_data;
+    AVIOContext *pb = s->pb;
+    int ret;
+    int i;
+
+    if (!pb->seekable) {
+        av_log(s, AV_LOG_ERROR, "Output is not seekable\n");
+        return AVERROR(EINVAL);
+    }
+
+    ico->current_image = 0;
+    ico->nb_images = s->nb_streams;
+
+    avio_wl16(pb, 0); // reserved
+    avio_wl16(pb, 1); // 1 == icon
+    avio_skip(pb, 2); // skip the number of images
+
+    for (i = 0; i < s->nb_streams; i++) {
+        if (ret = ico_check_attributes(s, s->streams[i]->codec))
+            return ret;
+
+        // Fill in later when writing trailer...
+        avio_skip(pb, 16);
+    }
+
+    ico->images = av_mallocz(ico->nb_images * sizeof(IcoMuxContext));
+    if (!ico->images)
+        return AVERROR(ENOMEM);
+
+    avio_flush(pb);
+
+    return 0;
+}
+
+static int ico_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    IcoMuxContext *ico = s->priv_data;
+    IcoImage *image;
+    AVIOContext *pb = s->pb;
+    AVCodecContext *c = s->streams[pkt->stream_index]->codec;
+    int i;
+
+    if (ico->current_image >= ico->nb_images) {
+        av_log(s, AV_LOG_ERROR, "ICO already contains %d images\n", ico->current_image);
+        return AVERROR(EIO);
+    }
+
+    image = &ico->images[ico->current_image++];
+
+    image->offset = avio_tell(pb);
+    image->width = (c->width == 256) ? 0 : c->width;
+    image->height = (c->height == 256) ? 0 : c->height;
+
+    if (c->codec_id == CODEC_ID_PNG) {
+        image->bits = c->bits_per_coded_sample;
+        image->size = pkt->size;
+
+        avio_write(pb, pkt->data, pkt->size);
+    } else { // BMP
+        if (AV_RL32(pkt->data + 14) != 40) { // must be BITMAPINFOHEADER
+            av_log(s, AV_LOG_ERROR, "Invalid BMP\n");
+            return AVERROR(EINVAL);
+        }
+
+        image->bits = AV_RL16(pkt->data + 28); // allows things like 1bit and 4bit images to be preserved
+        image->size = pkt->size - 14 + c->height * (c->width + 7) / 8;
+
+        avio_write(pb, pkt->data + 14, 8); // Skip the BITMAPFILEHEADER header
+        avio_wl32(pb, AV_RL32(pkt->data + 22) * 2); // rewrite height as 2 * height
+        avio_write(pb, pkt->data + 26, pkt->size - 26);
+
+        for (i = 0; i < c->height * (c->width + 7) / 8; ++i)
+            avio_w8(pb, 0x00); // Write bitmask (opaque)
+    }
+
+    avio_flush(pb);
+
+    return 0;
+}
+
+static int ico_write_trailer(AVFormatContext *s)
+{
+    IcoMuxContext *ico = s->priv_data;
+    AVIOContext *pb = s->pb;
+    int i;
+
+    avio_seek(pb, 4, SEEK_SET);
+
+    avio_wl16(pb, ico->current_image);
+
+    for (i = 0; i < ico->nb_images; i++) {
+        avio_w8(pb, ico->images[i].width);
+        avio_w8(pb, ico->images[i].height);
+
+        if (s->streams[i]->codec->codec_id == 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 {
+            avio_w8(pb, 0);
+        }
+
+        avio_w8(pb, 0); // reserved
+        avio_wl16(pb, 1); // color planes
+        avio_wl16(pb, ico->images[i].bits);
+        avio_wl32(pb, ico->images[i].size);
+        avio_wl32(pb, ico->images[i].offset);
+    }
+
+    av_freep(&ico->images);
+
+    return 0;
+}
+
+AVOutputFormat ff_ico_muxer = {
+    .name           = "ico",
+    .long_name      = NULL_IF_CONFIG_SMALL("Microsoft Windows ICO"),
+    .priv_data_size = sizeof(IcoMuxContext),
+    .mime_type      = "image/vnd.microsoft.icon",
+    .extensions     = "ico",
+    .audio_codec    = CODEC_ID_NONE,
+    .video_codec    = CODEC_ID_BMP,
+    .write_header   = ico_write_header,
+    .write_packet   = ico_write_packet,
+    .write_trailer  = ico_write_trailer,
+    .flags          = AVFMT_NOTIMESTAMPS,
+};
diff --git a/libavformat/id3v1.c b/libavformat/id3v1.c
index 87930ff..2d1e806 100644
--- a/libavformat/id3v1.c
+++ b/libavformat/id3v1.c
@@ -2,20 +2,20 @@
  * ID3v1 header parser
  * Copyright (c) 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/id3v1.h b/libavformat/id3v1.h
index 7107073..d5dca35 100644
--- a/libavformat/id3v1.h
+++ b/libavformat/id3v1.h
@@ -2,20 +2,20 @@
  * ID3v1 header parser
  * Copyright (c) 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 012d793..9c20287 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -1,24 +1,37 @@
 /*
- * ID3v2 header parser
  * Copyright (c) 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+/**
+ * @file
+ * ID3v2 header parser
+ *
+ * Specifications available at:
+ * http://id3.org/Developer_Information
+ */
+
+#include "config.h"
+
+#if CONFIG_ZLIB
+#include <zlib.h>
+#endif
+
 #include "id3v2.h"
 #include "id3v1.h"
 #include "libavutil/avstring.h"
@@ -478,7 +491,7 @@
 
     apic->len   = taglen;
     apic->data  = av_malloc(taglen);
-    if (!apic->data || avio_read(pb, apic->data, taglen) != taglen)
+    if (!apic->data || !apic->len || avio_read(pb, apic->data, taglen) != taglen)
         goto fail;
 
     new_extra->tag    = "APIC";
@@ -517,7 +530,7 @@
 {
     int i = 0;
     while (id3v2_extra_meta_funcs[i].tag3) {
-        if (!memcmp(tag,
+        if (tag && !memcmp(tag,
                     (isv34 ? id3v2_extra_meta_funcs[i].tag4 :
                              id3v2_extra_meta_funcs[i].tag3),
                     (isv34 ? 4 : 3)))
@@ -529,7 +542,8 @@
 
 static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags, ID3v2ExtraMeta **extra_meta)
 {
-    int isv34, tlen, unsync;
+    int isv34, unsync;
+    unsigned tlen;
     char tag[5];
     int64_t next, end = avio_tell(s->pb) + len;
     int taghdrlen;
@@ -538,7 +552,9 @@
     AVIOContext *pbx;
     unsigned char *buffer = NULL;
     int buffer_size = 0;
-    const ID3v2EMFunc *extra_func;
+    const ID3v2EMFunc *extra_func = NULL;
+    unsigned char *compressed_buffer = NULL;
+    int compressed_buffer_size = 0;
 
     switch (version) {
     case 2:
@@ -573,11 +589,19 @@
             goto error;
         }
         avio_skip(s->pb, extlen);
+        len -= extlen + 4;
+        if (len < 0) {
+            reason = "extended header too long.";
+            goto error;
+        }
     }
 
     while (len >= taghdrlen) {
         unsigned int tflags = 0;
         int tunsync = 0;
+        int tcomp = 0;
+        int tencr = 0;
+        unsigned long dlen;
 
         if (isv34) {
             avio_read(s->pb, tag, 4);
@@ -593,11 +617,13 @@
             tag[3] = 0;
             tlen = avio_rb24(s->pb);
         }
-        if (tlen < 0 || tlen > len - taghdrlen) {
-            av_log(s, AV_LOG_WARNING, "Invalid size in frame %s, skipping the rest of tag.\n", tag);
+        if (tlen > (1<<28))
             break;
-        }
         len -= taghdrlen + tlen;
+
+        if (len < 0)
+            break;
+
         next = avio_tell(s->pb) + tlen;
 
         if (!tlen) {
@@ -607,24 +633,67 @@
         }
 
         if (tflags & ID3v2_FLAG_DATALEN) {
-            avio_rb32(s->pb);
+            if (tlen < 4)
+                break;
+            dlen = avio_rb32(s->pb);
             tlen -= 4;
-        }
+        } else
+            dlen = tlen;
 
-        if (tflags & (ID3v2_FLAG_ENCRYPTION | ID3v2_FLAG_COMPRESSION)) {
-            av_log(s, AV_LOG_WARNING, "Skipping encrypted/compressed ID3v2 frame %s.\n", tag);
+        tcomp = tflags & ID3v2_FLAG_COMPRESSION;
+        tencr = tflags & ID3v2_FLAG_ENCRYPTION;
+
+        /* skip encrypted tags and, if no zlib, compressed tags */
+        if (tencr || (!CONFIG_ZLIB && tcomp)) {
+            const char *type;
+            if (!tcomp)
+                type = "encrypted";
+            else if (!tencr)
+                type = "compressed";
+            else
+                type = "encrypted and compressed";
+
+            av_log(s, AV_LOG_WARNING, "Skipping %s ID3v2 frame %s.\n", type, tag);
             avio_skip(s->pb, tlen);
         /* check for text tag or supported special meta tag */
         } else if (tag[0] == 'T' || (extra_meta && (extra_func = get_extra_meta_func(tag, isv34)))) {
-            if (unsync || tunsync) {
+            if (unsync || tunsync || tcomp) {
                 int i, j;
-                av_fast_malloc(&buffer, &buffer_size, tlen);
+
+                av_fast_malloc(&buffer, &buffer_size, dlen);
                 if (!buffer) {
-                    av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", tlen);
+                    av_log(s, AV_LOG_ERROR, "Failed to alloc %ld bytes\n", dlen);
                     goto seek;
                 }
-                for (i = 0, j = 0; i < tlen; i++, j++) {
-                    buffer[j] = avio_r8(s->pb);
+#if CONFIG_ZLIB
+                if (tcomp) {
+                    int n, err;
+
+                    av_log(s, AV_LOG_DEBUG, "Compresssed frame %s tlen=%d dlen=%ld\n", tag, tlen, dlen);
+
+                    av_fast_malloc(&compressed_buffer, &compressed_buffer_size, tlen);
+                    if (!compressed_buffer) {
+                        av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", tlen);
+                        goto seek;
+                    }
+
+                    n = avio_read(s->pb, compressed_buffer, tlen);
+                    if (n < 0) {
+                        av_log(s, AV_LOG_ERROR, "Failed to read compressed tag\n");
+                        goto seek;
+                    }
+
+                    err = uncompress(buffer, &dlen, compressed_buffer, n);
+                    if (err != Z_OK) {
+                        av_log(s, AV_LOG_ERROR, "Failed to uncompress tag: %d\n", err);
+                        goto seek;
+                    }
+                }
+#endif
+
+                for (i = 0, j = 0; i < dlen; i++, j++) {
+                    if (!tcomp)
+                        buffer[j] = avio_r8(s->pb);
                     if (j > 0 && !buffer[j] && buffer[j - 1] == 0xff) {
                         /* Unsynchronised byte, skip it */
                         j--;
@@ -645,7 +714,7 @@
         }
         else if (!tag[0]) {
             if (tag[1])
-                av_log(s, AV_LOG_WARNING, "invalid frame id, assuming padding");
+                av_log(s, AV_LOG_WARNING, "invalid frame id, assuming padding\n");
             avio_skip(s->pb, tlen);
             break;
         }
@@ -662,6 +731,7 @@
         av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n", version, reason);
     avio_seek(s->pb, end, SEEK_SET);
     av_free(buffer);
+    av_free(compressed_buffer);
     return;
 }
 
diff --git a/libavformat/id3v2.h b/libavformat/id3v2.h
index cb2fb02..f727010 100644
--- a/libavformat/id3v2.h
+++ b/libavformat/id3v2.h
@@ -2,20 +2,20 @@
  * ID3v2 header parser
  * Copyright (c) 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/id3v2enc.c b/libavformat/id3v2enc.c
index df00f05..a10d679 100644
--- a/libavformat/id3v2enc.c
+++ b/libavformat/id3v2enc.c
@@ -1,26 +1,27 @@
 /*
  * ID3v2 header writer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <stdint.h>
 #include <string.h>
 
+#include "libavutil/avstring.h"
 #include "libavutil/dict.h"
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
@@ -109,6 +110,44 @@
     return -1;
 }
 
+static void id3v2_3_metadata_split_date(AVDictionary **pm)
+{
+    AVDictionaryEntry *mtag = NULL;
+    AVDictionary *dst = NULL;
+    const char *key, *value;
+    char year[5] = {0}, day_month[5] = {0};
+    int i;
+
+    while ((mtag = av_dict_get(*pm, "", mtag, AV_DICT_IGNORE_SUFFIX))) {
+        key = mtag->key;
+        if (!av_strcasecmp(key, "date")) {
+            /* split date tag using "YYYY-MM-DD" format into year and month/day segments */
+            value = mtag->value;
+            i = 0;
+            while (value[i] >= '0' && value[i] <= '9') i++;
+            if (value[i] == '\0' || value[i] == '-') {
+                av_strlcpy(year, value, sizeof(year));
+                av_dict_set(&dst, "TYER", year, 0);
+
+                if (value[i] == '-' &&
+                    value[i+1] >= '0' && value[i+1] <= '1' &&
+                    value[i+2] >= '0' && value[i+2] <= '9' &&
+                    value[i+3] == '-' &&
+                    value[i+4] >= '0' && value[i+4] <= '3' &&
+                    value[i+5] >= '0' && value[i+5] <= '9' &&
+                    (value[i+6] == '\0' || value[i+6] == ' ')) {
+                    snprintf(day_month, sizeof(day_month), "%.2s%.2s", value + i + 4, value + i + 1);
+                    av_dict_set(&dst, "TDAT", day_month, 0);
+                }
+            } else
+                av_dict_set(&dst, key, value, 0);
+        } else
+            av_dict_set(&dst, key, mtag->value, 0);
+    }
+    av_dict_free(pm);
+    *pm = dst;
+}
+
 void ff_id3v2_start(ID3v2EncContext *id3, AVIOContext *pb, int id3v2_version,
                     const char *magic)
 {
@@ -130,7 +169,9 @@
                                   ID3v2_ENCODING_UTF8;
 
     ff_metadata_conv(&s->metadata, ff_id3v2_34_metadata_conv, NULL);
-    if (id3->version == 4)
+    if (id3->version == 3)
+        id3v2_3_metadata_split_date(&s->metadata);
+    else if (id3->version == 4)
         ff_metadata_conv(&s->metadata, ff_id3v2_4_metadata_conv, NULL);
 
     while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) {
diff --git a/libavformat/idcin.c b/libavformat/idcin.c
index fde8666..f1df002 100644
--- a/libavformat/idcin.c
+++ b/libavformat/idcin.c
@@ -2,20 +2,20 @@
  * id Quake II CIN File Demuxer
  * Copyright (c) 2003 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -224,7 +224,7 @@
     unsigned char palette_buffer[768];
     uint32_t palette[256];
 
-    if (s->pb->eof_reached)
+    if (url_feof(s->pb))
         return AVERROR(EIO);
 
     if (idcin->next_chunk_is_video) {
@@ -247,7 +247,9 @@
                 r = palette_buffer[i * 3    ] << palette_scale;
                 g = palette_buffer[i * 3 + 1] << palette_scale;
                 b = palette_buffer[i * 3 + 2] << palette_scale;
-                palette[i] = (r << 16) | (g << 8) | (b);
+                palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | (b);
+                if (palette_scale == 2)
+                    palette[i] |= palette[i] >> 6 & 0x30303;
             }
         }
 
@@ -263,8 +265,8 @@
 
             pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,
                                           AVPALETTE_SIZE);
-            if (ret < 0)
-                return ret;
+            if (!pal)
+                return AVERROR(ENOMEM);
             memcpy(pal, palette, AVPALETTE_SIZE);
         }
         pkt->stream_index = idcin->video_stream_index;
diff --git a/libavformat/idroqdec.c b/libavformat/idroqdec.c
index 521f586..3b17ff4 100644
--- a/libavformat/idroqdec.c
+++ b/libavformat/idroqdec.c
@@ -2,20 +2,20 @@
  * id RoQ (.roq) File Demuxer
  * Copyright (c) 2003 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,6 +30,7 @@
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "internal.h"
+#include "avio_internal.h"
 
 #define RoQ_MAGIC_NUMBER 0x1084
 #define RoQ_CHUNK_PREAMBLE_SIZE 8
@@ -104,7 +105,7 @@
 
     while (!packet_read) {
 
-        if (s->pb->eof_reached)
+        if (url_feof(s->pb))
             return AVERROR(EIO);
 
         /* get the next chunk preamble */
@@ -117,6 +118,8 @@
         if(chunk_size > INT_MAX)
             return AVERROR_INVALIDDATA;
 
+        chunk_size = ffio_limit(pb, chunk_size);
+
         switch (chunk_type) {
 
         case RoQ_INFO:
diff --git a/libavformat/idroqenc.c b/libavformat/idroqenc.c
index 2ce4d7d..50c4280 100644
--- a/libavformat/idroqenc.c
+++ b/libavformat/idroqenc.c
@@ -2,20 +2,20 @@
  * id RoQ (.roq) File muxer
  * Copyright (c) 2007 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/iff.c b/libavformat/iff.c
index c2bc283..d559ad3 100644
--- a/libavformat/iff.c
+++ b/libavformat/iff.c
@@ -1,23 +1,22 @@
 /*
- * IFF (.iff) file demuxer
  * Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net>
  * Copyright (c) 2010 Peter Ross <pross@xvid.org>
  * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,6 +28,8 @@
  * http://wiki.multimedia.cx/index.php?title=IFF
  */
 
+#include "libavcodec/bytestream.h"
+#include "libavutil/avassert.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/dict.h"
 #include "avformat.h"
@@ -42,7 +43,11 @@
 #define ID_PBM        MKTAG('P','B','M',' ')
 #define ID_ILBM       MKTAG('I','L','B','M')
 #define ID_BMHD       MKTAG('B','M','H','D')
+#define ID_DGBL       MKTAG('D','G','B','L')
+#define ID_CAMG       MKTAG('C','A','M','G')
 #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_FORM       MKTAG('F','O','R','M')
 #define ID_ANNO       MKTAG('A','N','N','O')
@@ -53,13 +58,25 @@
 #define ID_FVER       MKTAG('F','V','E','R')
 #define ID_NAME       MKTAG('N','A','M','E')
 #define ID_TEXT       MKTAG('T','E','X','T')
+#define ID_ABIT       MKTAG('A','B','I','T')
 #define ID_BODY       MKTAG('B','O','D','Y')
-#define ID_ANNO       MKTAG('A','N','N','O')
+#define ID_DBOD       MKTAG('D','B','O','D')
+#define ID_DPEL       MKTAG('D','P','E','L')
 
 #define LEFT    2
 #define RIGHT   4
 #define STEREO  6
 
+/**
+ * This number of bytes if added at the beginning of each AVPacket
+ * which contain additional information about video properties
+ * which has to be shared between demuxer and decoder.
+ * This number may change between frames, e.g. the demuxer might
+ * 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
+
 typedef enum {
     COMP_NONE,
     COMP_FIB,
@@ -75,9 +92,15 @@
     uint64_t  body_pos;
     uint32_t  body_size;
     uint32_t  sent_bytes;
+    svx8_compression_type   svx8_compression;
+    bitmap_compression_type bitmap_compression;  ///< delta compression method used
+    unsigned  bpp;          ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
+    unsigned  ham;          ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
+    unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
+    unsigned  transparency; ///< transparency color index in palette
+    unsigned  masking;      ///< masking method used
 } IffDemuxContext;
 
-
 /* Metadata string read */
 static int get_metadata(AVFormatContext *s,
                         const char *const tag,
@@ -101,19 +124,31 @@
 {
     const uint8_t *d = p->buf;
 
-    if ( AV_RL32(d)   == ID_FORM &&
-         (AV_RL32(d+8) == ID_8SVX || AV_RL32(d+8) == ID_PBM || AV_RL32(d+8) == ID_ILBM) )
+    if (  AV_RL32(d)   == ID_FORM &&
+         (AV_RL32(d+8) == ID_8SVX ||
+          AV_RL32(d+8) == ID_PBM  ||
+          AV_RL32(d+8) == ID_ACBM ||
+          AV_RL32(d+8) == ID_DEEP ||
+          AV_RL32(d+8) == ID_ILBM) )
         return AVPROBE_SCORE_MAX;
     return 0;
 }
 
+static const uint8_t deep_rgb24[] = {0, 0, 0, 3, 0, 1, 0, 8, 0, 2, 0, 8, 0, 3, 0, 8};
+static const uint8_t deep_rgba[]  = {0, 0, 0, 4, 0, 1, 0, 8, 0, 2, 0, 8, 0, 3, 0, 8};
+
 static int iff_read_header(AVFormatContext *s)
 {
     IffDemuxContext *iff = s->priv_data;
     AVIOContext *pb = s->pb;
     AVStream *st;
+    uint8_t *buf;
     uint32_t chunk_id, data_size;
-    int compression = -1;
+    uint32_t screenmode = 0;
+    unsigned transparency = 0;
+    unsigned masking = 0; // no mask
+    uint8_t fmt[16];
+    int fmt_size;
 
     st = avformat_new_stream(s, NULL);
     if (!st)
@@ -124,7 +159,7 @@
     // codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content
     st->codec->codec_tag = avio_rl32(pb);
 
-    while(!pb->eof_reached) {
+    while(!url_feof(pb)) {
         uint64_t orig_pos;
         int res;
         const char *metadata_tag = NULL;
@@ -142,11 +177,13 @@
             st->codec->sample_rate = avio_rb16(pb);
             if (data_size >= 16) {
                 avio_skip(pb, 1);
-                compression        = avio_r8(pb);
+                iff->svx8_compression = avio_r8(pb);
             }
             break;
 
+        case ID_ABIT:
         case ID_BODY:
+        case ID_DBOD:
             iff->body_pos = avio_tell(pb);
             iff->body_size = data_size;
             break;
@@ -157,16 +194,23 @@
             st->codec->channels = (avio_rb32(pb) < 6) ? 1 : 2;
             break;
 
+        case ID_CAMG:
+            if (data_size < 4)
+                return AVERROR_INVALIDDATA;
+            screenmode                = avio_rb32(pb);
+            break;
+
         case ID_CMAP:
-            st->codec->extradata_size = data_size;
-            st->codec->extradata      = av_malloc(data_size);
+            st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE;
+            st->codec->extradata      = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
             if (!st->codec->extradata)
                 return AVERROR(ENOMEM);
-            if (avio_read(pb, st->codec->extradata, data_size) < 0)
+            if (avio_read(pb, st->codec->extradata + IFF_EXTRA_VIDEO_SIZE, data_size) < 0)
                 return AVERROR(EIO);
             break;
 
         case ID_BMHD:
+            iff->bitmap_compression = -1;
             st->codec->codec_type            = AVMEDIA_TYPE_VIDEO;
             if (data_size <= 8)
                 return AVERROR_INVALIDDATA;
@@ -174,38 +218,62 @@
             st->codec->height                = avio_rb16(pb);
             avio_skip(pb, 4); // x, y offset
             st->codec->bits_per_coded_sample = avio_r8(pb);
-            if (data_size >= 11) {
-                avio_skip(pb, 1); // masking
-                compression                  = avio_r8(pb);
+            if (data_size >= 10)
+                masking                      = avio_r8(pb);
+            if (data_size >= 11)
+                iff->bitmap_compression      = avio_r8(pb);
+            if (data_size >= 14) {
+                avio_skip(pb, 1); // padding
+                transparency                 = avio_rb16(pb);
             }
             if (data_size >= 16) {
-                avio_skip(pb, 3); // paddding, transparent
                 st->sample_aspect_ratio.num  = avio_r8(pb);
                 st->sample_aspect_ratio.den  = avio_r8(pb);
             }
             break;
 
+        case ID_DPEL:
+            if (data_size < 4 || (data_size & 3))
+                return AVERROR_INVALIDDATA;
+            if ((fmt_size = avio_read(pb, fmt, sizeof(fmt))) < 0)
+                return fmt_size;
+            if (fmt_size == sizeof(deep_rgb24) && !memcmp(fmt, deep_rgb24, sizeof(deep_rgb24)))
+                st->codec->pix_fmt = AV_PIX_FMT_RGB24;
+            else if (fmt_size == sizeof(deep_rgba) && !memcmp(fmt, deep_rgba, sizeof(deep_rgba)))
+                st->codec->pix_fmt = AV_PIX_FMT_RGBA;
+            else {
+                av_log_ask_for_sample(s, "unsupported color format\n");
+                return AVERROR_PATCHWELCOME;
+            }
+            break;
+
+        case ID_DGBL:
+            st->codec->codec_type            = AVMEDIA_TYPE_VIDEO;
+            if (data_size < 8)
+                return AVERROR_INVALIDDATA;
+            st->codec->width                 = avio_rb16(pb);
+            st->codec->height                = avio_rb16(pb);
+            iff->bitmap_compression          = avio_rb16(pb);
+            if (iff->bitmap_compression != 0) {
+                av_log(s, AV_LOG_ERROR,
+                       "compression %i not supported\n", iff->bitmap_compression);
+                return AVERROR_PATCHWELCOME;
+            }
+            st->sample_aspect_ratio.num      = avio_r8(pb);
+            st->sample_aspect_ratio.den      = avio_r8(pb);
+            st->codec->bits_per_coded_sample = 24;
+            break;
+
         case ID_ANNO:
-        case ID_TEXT:
-            metadata_tag = "comment";
-            break;
-
-        case ID_AUTH:
-            metadata_tag = "artist";
-            break;
-
-        case ID_COPYRIGHT:
-            metadata_tag = "copyright";
-            break;
-
-        case ID_NAME:
-            metadata_tag = "title";
-            break;
+        case ID_TEXT:      metadata_tag = "comment";   break;
+        case ID_AUTH:      metadata_tag = "artist";    break;
+        case ID_COPYRIGHT: metadata_tag = "copyright"; break;
+        case ID_NAME:      metadata_tag = "title";     break;
         }
 
         if (metadata_tag) {
             if ((res = get_metadata(s, metadata_tag, data_size)) < 0) {
-                av_log(s, AV_LOG_ERROR, "cannot allocate metadata tag %s!", metadata_tag);
+                av_log(s, AV_LOG_ERROR, "cannot allocate metadata tag %s!\n", metadata_tag);
                 return res;
             }
         }
@@ -218,7 +286,7 @@
     case AVMEDIA_TYPE_AUDIO:
         avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate);
 
-        switch(compression) {
+        switch (iff->svx8_compression) {
         case COMP_NONE:
             st->codec->codec_id = AV_CODEC_ID_PCM_S8_PLANAR;
             break;
@@ -229,17 +297,42 @@
             st->codec->codec_id = AV_CODEC_ID_8SVX_EXP;
             break;
         default:
-            av_log(s, AV_LOG_ERROR, "unknown compression method\n");
+            av_log(s, AV_LOG_ERROR,
+                   "Unknown SVX8 compression method '%d'\n", iff->svx8_compression);
             return -1;
         }
 
-        st->codec->bits_per_coded_sample = 8;
+        st->codec->bits_per_coded_sample = iff->svx8_compression == COMP_NONE ? 8 : 4;
         st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample;
         st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
         break;
 
     case AVMEDIA_TYPE_VIDEO:
-        switch (compression) {
+        iff->bpp          = st->codec->bits_per_coded_sample;
+        if ((screenmode & 0x800 /* Hold And Modify */) && iff->bpp <= 8) {
+            iff->ham      = iff->bpp > 6 ? 6 : 4;
+            st->codec->bits_per_coded_sample = 24;
+        }
+        iff->flags        = (screenmode & 0x80 /* Extra HalfBrite */) && iff->bpp <= 8;
+        iff->masking      = masking;
+        iff->transparency = transparency;
+
+        if (!st->codec->extradata) {
+            st->codec->extradata_size = IFF_EXTRA_VIDEO_SIZE;
+            st->codec->extradata      = av_malloc(IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
+            if (!st->codec->extradata)
+                return AVERROR(ENOMEM);
+        }
+        buf = st->codec->extradata;
+        bytestream_put_be16(&buf, IFF_EXTRA_VIDEO_SIZE);
+        bytestream_put_byte(&buf, iff->bitmap_compression);
+        bytestream_put_byte(&buf, iff->bpp);
+        bytestream_put_byte(&buf, iff->ham);
+        bytestream_put_byte(&buf, iff->flags);
+        bytestream_put_be16(&buf, iff->transparency);
+        bytestream_put_byte(&buf, iff->masking);
+
+        switch (iff->bitmap_compression) {
         case BITMAP_RAW:
             st->codec->codec_id = AV_CODEC_ID_IFF_ILBM;
             break;
@@ -247,7 +340,8 @@
             st->codec->codec_id = AV_CODEC_ID_IFF_BYTERUN1;
             break;
         default:
-            av_log(s, AV_LOG_ERROR, "unknown compression method\n");
+            av_log(s, AV_LOG_ERROR,
+                   "Unknown bitmap compression method '%d'\n", iff->bitmap_compression);
             return AVERROR_INVALIDDATA;
         }
         break;
@@ -263,14 +357,27 @@
 {
     IffDemuxContext *iff = s->priv_data;
     AVIOContext *pb = s->pb;
+    AVStream *st = s->streams[0];
     int ret;
 
     if(iff->sent_bytes >= iff->body_size)
         return AVERROR_EOF;
 
-    ret = av_get_packet(pb, pkt, iff->body_size);
-    if (ret < 0)
-        return ret;
+    if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+        ret = av_get_packet(pb, pkt, iff->body_size);
+    } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+        uint8_t *buf;
+
+        if (av_new_packet(pkt, iff->body_size + 2) < 0) {
+            return AVERROR(ENOMEM);
+        }
+
+        buf = pkt->data;
+        bytestream_put_be16(&buf, 2);
+        ret = avio_read(pb, buf, iff->body_size);
+    } else {
+        av_assert0(0);
+    }
 
     if(iff->sent_bytes == 0)
         pkt->flags |= AV_PKT_FLAG_KEY;
diff --git a/libavformat/ilbc.c b/libavformat/ilbc.c
index c01eb6f..7a23b2f 100644
--- a/libavformat/ilbc.c
+++ b/libavformat/ilbc.c
@@ -2,20 +2,20 @@
  * iLBC storage file format
  * Copyright (c) 2012 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/img2.c b/libavformat/img2.c
index 14bb3d0..ed4b39a 100644
--- a/libavformat/img2.c
+++ b/libavformat/img2.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  * Copyright (c) 2004 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -31,8 +31,11 @@
 static const IdStrMap img_tags[] = {
     { AV_CODEC_ID_MJPEG     , "jpeg"},
     { AV_CODEC_ID_MJPEG     , "jpg"},
+    { AV_CODEC_ID_MJPEG     , "jps"},
     { AV_CODEC_ID_LJPEG     , "ljpg"},
+    { AV_CODEC_ID_JPEGLS    , "jls"},
     { AV_CODEC_ID_PNG       , "png"},
+    { AV_CODEC_ID_PNG       , "pns"},
     { AV_CODEC_ID_PNG       , "mng"},
     { AV_CODEC_ID_PPM       , "ppm"},
     { AV_CODEC_ID_PPM       , "pnm"},
@@ -45,6 +48,7 @@
     { AV_CODEC_ID_MPEG4     , "mpg4-img"},
     { AV_CODEC_ID_FFV1      , "ffv1-img"},
     { AV_CODEC_ID_RAWVIDEO  , "y"},
+    { AV_CODEC_ID_RAWVIDEO  , "raw"},
     { AV_CODEC_ID_BMP       , "bmp"},
     { AV_CODEC_ID_GIF       , "gif"},
     { AV_CODEC_ID_TARGA     , "tga"},
@@ -59,11 +63,16 @@
     { AV_CODEC_ID_SUNRAST   , "im1"},
     { AV_CODEC_ID_SUNRAST   , "im8"},
     { AV_CODEC_ID_SUNRAST   , "im24"},
+    { AV_CODEC_ID_SUNRAST   , "im32"},
     { AV_CODEC_ID_SUNRAST   , "sunras"},
+    { AV_CODEC_ID_JPEG2000  , "j2c"},
+    { AV_CODEC_ID_JPEG2000  , "j2k"},
     { AV_CODEC_ID_JPEG2000  , "jp2"},
     { AV_CODEC_ID_JPEG2000  , "jpc"},
     { AV_CODEC_ID_DPX       , "dpx"},
+    { AV_CODEC_ID_EXR       , "exr"},
     { AV_CODEC_ID_PICTOR    , "pic"},
+    { AV_CODEC_ID_V210X     , "yuv10"},
     { AV_CODEC_ID_XBM       , "xbm"},
     { AV_CODEC_ID_XWD       , "xwd"},
     { AV_CODEC_ID_NONE      , NULL}
diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c
index 14f7785..79f10b9 100644
--- a/libavformat/img2dec.c
+++ b/libavformat/img2dec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  * Copyright (c) 2004 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -27,6 +27,19 @@
 #include "libavutil/parseutils.h"
 #include "avformat.h"
 #include "internal.h"
+#if HAVE_GLOB
+#include <glob.h>
+
+/* Locally define as 0 (bitwise-OR no-op) any missing glob options that
+   are non-posix glibc/bsd extensions. */
+#ifndef GLOB_NOMAGIC
+#define GLOB_NOMAGIC 0
+#endif
+#ifndef GLOB_BRACE
+#define GLOB_BRACE 0
+#endif
+
+#endif /* HAVE_GLOB */
 
 typedef struct {
     const AVClass *class;  /**< Class for private options. */
@@ -35,12 +48,19 @@
     int img_number;
     int img_count;
     int is_pipe;
+    int split_planes;       /**< use independent file for each Y, U, V plane */
     char path[1024];
     char *pixel_format;     /**< Set by a private option. */
     char *video_size;       /**< Set by a private option. */
     char *framerate;        /**< Set by a private option. */
     int loop;
+    enum { PT_GLOB_SEQUENCE, PT_GLOB, PT_SEQUENCE } pattern_type;
+    int use_glob;
+#if HAVE_GLOB
+    glob_t globstate;
+#endif
     int start_number;
+    int start_number_range;
 } VideoDemuxData;
 
 static const int sizes[][2] = {
@@ -69,15 +89,44 @@
     return -1;
 }
 
-/* return -1 if no image found */
+static int is_glob(const char *path)
+{
+#if HAVE_GLOB
+    size_t span = 0;
+    const char *p = path;
+
+    while (p = strchr(p, '%')) {
+        if (*(++p) == '%') {
+            ++p;
+            continue;
+        }
+        if (span = strspn(p, "*?[]{}"))
+            break;
+    }
+    /* Did we hit a glob char or get to the end? */
+    return span != 0;
+#else
+    return 0;
+#endif
+}
+
+/**
+ * Get index range of image files matched by path.
+ *
+ * @param pfirst_index pointer to index updated with the first number in the range
+ * @param plast_index  pointer to index updated with the last number in the range
+ * @param path         path which has to be matched by the image files in the range
+ * @param start_index  minimum accepted value for the first index in the range
+ * @return -1 if no image file could be found
+ */
 static int find_image_range(int *pfirst_index, int *plast_index,
-                            const char *path, int max_start)
+                            const char *path, int start_index, int start_index_range)
 {
     char buf[1024];
     int range, last_index, range1, first_index;
 
     /* find the first image */
-    for (first_index = 0; first_index < max_start; first_index++) {
+    for (first_index = start_index; first_index < start_index + start_index_range; first_index++) {
         if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0){
             *pfirst_index =
             *plast_index = 1;
@@ -88,7 +137,7 @@
         if (avio_check(buf, AVIO_FLAG_READ) > 0)
             break;
     }
-    if (first_index == 5)
+    if (first_index == start_index + start_index_range)
         goto fail;
 
     /* find the last image */
@@ -128,6 +177,10 @@
     if (p->filename && ff_guess_image2_codec(p->filename)) {
         if (av_filename_number_test(p->filename))
             return AVPROBE_SCORE_MAX;
+        else if (is_glob(p->filename))
+            return AVPROBE_SCORE_MAX;
+        else if(av_match_ext(p->filename, "raw"))
+            return 5;
         else
             return AVPROBE_SCORE_MAX/2;
     }
@@ -183,9 +236,67 @@
     }
 
     if (!s->is_pipe) {
-        if (find_image_range(&first_index, &last_index, s->path,
-                             FFMAX(s->start_number, 5)) < 0)
-            return AVERROR(ENOENT);
+        if (s->pattern_type == PT_GLOB_SEQUENCE) {
+        s->use_glob = is_glob(s->path);
+        if (s->use_glob) {
+            char *p = s->path, *q, *dup;
+            int gerr;
+
+            av_log(s1, AV_LOG_WARNING, "Pattern type 'glob_sequence' is deprecated: "
+                   "use pattern_type 'glob' instead\n");
+#if HAVE_GLOB
+            dup = q = av_strdup(p);
+            while (*q) {
+                /* Do we have room for the next char and a \ insertion? */
+                if ((p - s->path) >= (sizeof(s->path) - 2))
+                  break;
+                if (*q == '%' && strspn(q + 1, "%*?[]{}"))
+                    ++q;
+                else if (strspn(q, "\\*?[]{}"))
+                    *p++ = '\\';
+                *p++ = *q++;
+            }
+            *p = 0;
+            av_free(dup);
+
+            gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate);
+            if (gerr != 0) {
+                return AVERROR(ENOENT);
+            }
+            first_index = 0;
+            last_index = s->globstate.gl_pathc - 1;
+#endif
+        }
+        }
+        if ((s->pattern_type == PT_GLOB_SEQUENCE && !s->use_glob) || s->pattern_type == PT_SEQUENCE) {
+            if (find_image_range(&first_index, &last_index, s->path,
+                                 s->start_number, s->start_number_range) < 0) {
+                av_log(s1, AV_LOG_ERROR,
+                       "Could find no file with with path '%s' and index in the range %d-%d\n",
+                       s->path, s->start_number, s->start_number + s->start_number_range - 1);
+                return AVERROR(ENOENT);
+            }
+        } else if (s->pattern_type == PT_GLOB) {
+#if HAVE_GLOB
+            int gerr;
+            gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate);
+            if (gerr != 0) {
+                return AVERROR(ENOENT);
+            }
+            first_index = 0;
+            last_index = s->globstate.gl_pathc - 1;
+            s->use_glob = 1;
+#else
+            av_log(s1, AV_LOG_ERROR,
+                   "Pattern type 'glob' was selected but globbing "
+                   "is not supported by this libavformat build\n");
+            return AVERROR(ENOSYS);
+#endif
+        } else if (s->pattern_type != PT_GLOB_SEQUENCE) {
+            av_log(s1, AV_LOG_ERROR,
+                   "Unknown value '%d' for pattern_type option\n", s->pattern_type);
+            return AVERROR(EINVAL);
+        }
         s->img_first = first_index;
         s->img_last = last_index;
         s->img_number = first_index;
@@ -201,8 +312,12 @@
         st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
         st->codec->codec_id = s1->audio_codec_id;
     }else{
+        const char *str= strrchr(s->path, '.');
+        s->split_planes = str && !av_strcasecmp(str + 1, "y");
         st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
         st->codec->codec_id = ff_guess_image2_codec(s->path);
+        if (st->codec->codec_id == AV_CODEC_ID_LJPEG)
+            st->codec->codec_id = AV_CODEC_ID_MJPEG;
     }
     if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO && pix_fmt != AV_PIX_FMT_NONE)
         st->codec->pix_fmt = pix_fmt;
@@ -213,7 +328,8 @@
 static int read_packet(AVFormatContext *s1, AVPacket *pkt)
 {
     VideoDemuxData *s = s1->priv_data;
-    char filename[1024];
+    char filename_bytes[1024];
+    char *filename = filename_bytes;
     int i;
     int size[3]={0}, ret[3]={0};
     AVIOContext *f[3] = {NULL};
@@ -226,9 +342,15 @@
         }
         if (s->img_number > s->img_last)
             return AVERROR_EOF;
-        if (av_get_frame_filename(filename, sizeof(filename),
+        if (s->use_glob) {
+#if HAVE_GLOB
+            filename = s->globstate.gl_pathv[s->img_number];
+#endif
+        } else {
+        if (av_get_frame_filename(filename_bytes, sizeof(filename_bytes),
                                   s->path, s->img_number)<0 && s->img_number > 1)
             return AVERROR(EIO);
+        }
         for(i=0; i<3; i++){
             if (avio_open2(&f[i], filename, AVIO_FLAG_READ,
                            &s1->interrupt_callback, NULL) < 0) {
@@ -239,7 +361,7 @@
             }
             size[i]= avio_size(f[i]);
 
-            if(codec->codec_id != AV_CODEC_ID_RAWVIDEO)
+            if(!s->split_planes)
                 break;
             filename[ strlen(filename) - 1 ]= 'U' + i;
         }
@@ -248,7 +370,7 @@
             infer_size(&codec->width, &codec->height, size[0]);
     } else {
         f[0] = s1->pb;
-        if (f[0]->eof_reached)
+        if (url_feof(f[0]))
             return AVERROR(EIO);
         size[0]= 4096;
     }
@@ -278,14 +400,32 @@
     }
 }
 
+static int read_close(struct AVFormatContext* s1)
+{
+    VideoDemuxData *s = s1->priv_data;
+#if HAVE_GLOB
+    if (s->use_glob) {
+        globfree(&s->globstate);
+    }
+#endif
+    return 0;
+}
+
 #define OFFSET(x) offsetof(VideoDemuxData, x)
 #define DEC AV_OPT_FLAG_DECODING_PARAM
 static const AVOption options[] = {
-    { "pixel_format", "", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
-    { "video_size",   "", OFFSET(video_size),   AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
-    { "framerate",    "", OFFSET(framerate),    AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
-    { "loop",         "", OFFSET(loop),         AV_OPT_TYPE_INT,    {.i64 = 0},    0, 1, DEC },
-    { "start_number", "first number in the sequence", OFFSET(start_number), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, DEC },
+    { "framerate",    "set the video framerate",             OFFSET(framerate),    AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC },
+    { "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" },
+
+    { "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 },
+    { "start_number_range", "set range for looking at the first sequence number", OFFSET(start_number_range), AV_OPT_TYPE_INT, {.i64 = 5}, 1, INT_MAX, DEC },
+    { "video_size",   "set video size",                      OFFSET(video_size),   AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC },
     { NULL },
 };
 
@@ -303,6 +443,7 @@
     .read_probe     = read_probe,
     .read_header    = read_header,
     .read_packet    = read_packet,
+    .read_close     = read_close,
     .flags          = AVFMT_NOFILE,
     .priv_class     = &img2_class,
 };
diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c
index bf18356..2956ca0 100644
--- a/libavformat/img2enc.c
+++ b/libavformat/img2enc.c
@@ -3,26 +3,27 @@
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  * Copyright (c) 2004 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/intreadwrite.h"
 #include "libavutil/avstring.h"
 #include "libavutil/log.h"
+#include "libavutil/opt.h"
 #include "avformat.h"
 #include "avio_internal.h"
 #include "internal.h"
@@ -32,12 +33,15 @@
     const AVClass *class;  /**< Class for private options. */
     int img_number;
     int is_pipe;
+    int split_planes;       /**< use independent file for each Y, U, V plane */
     char path[1024];
+    int updatefirst;
 } VideoMuxData;
 
 static int write_header(AVFormatContext *s)
 {
     VideoMuxData *img = s->priv_data;
+    const char *str;
 
     av_strlcpy(img->path, s->filename, sizeof(img->path));
 
@@ -47,6 +51,8 @@
     else
         img->is_pipe = 1;
 
+    str = strrchr(img->path, '.');
+    img->split_planes = str && !av_strcasecmp(str + 1, "y");
     return 0;
 }
 
@@ -60,11 +66,11 @@
 
     if (!img->is_pipe) {
         if (av_get_frame_filename(filename, sizeof(filename),
-                                  img->path, img->img_number) < 0 && img->img_number>1) {
+                                  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",
                    img->img_number, img->path);
-            return AVERROR(EIO);
+            return AVERROR(EINVAL);
         }
         for(i=0; i<3; i++){
             if (avio_open2(&pb[i], filename, AVIO_FLAG_WRITE,
@@ -73,7 +79,7 @@
                 return AVERROR(EIO);
             }
 
-            if(codec->codec_id != AV_CODEC_ID_RAWVIDEO)
+            if(!img->split_planes)
                 break;
             filename[ strlen(filename) - 1 ]= 'U' + i;
         }
@@ -81,7 +87,7 @@
         pb[0] = s->pb;
     }
 
-    if(codec->codec_id == AV_CODEC_ID_RAWVIDEO){
+    if(img->split_planes){
         int ysize = codec->width * codec->height;
         avio_write(pb[0], pkt->data        , ysize);
         avio_write(pb[1], pkt->data + ysize, (pkt->size - ysize)/2);
@@ -104,11 +110,13 @@
                 avio_wb32(pb[0], 0);
                 ffio_wfourcc(pb[0], "jp2 ");
                 avio_write(pb[0], st->codec->extradata, st->codec->extradata_size);
+            }else if(pkt->size >= 8 && AV_RB32(pkt->data) == 0xFF4FFF51){
+                //jpeg2000 codestream
             }else if(pkt->size < 8 ||
                      (!st->codec->extradata_size &&
                       AV_RL32(pkt->data+4) != MKTAG('j','P',' ',' '))){ // signature
             error:
-                av_log(s, AV_LOG_ERROR, "malformed JPEG 2000 codestream\n");
+                av_log(s, AV_LOG_ERROR, "malformed JPEG 2000 codestream %X\n", AV_RB32(pkt->data));
                 return -1;
             }
         }
@@ -126,6 +134,7 @@
 #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 },
     { NULL },
 };
@@ -141,8 +150,8 @@
 AVOutputFormat ff_image2_muxer = {
     .name           = "image2",
     .long_name      = NULL_IF_CONFIG_SMALL("image2 sequence"),
-    .extensions     = "bmp,dpx,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,"
-                      "ppm,sgi,tga,tif,tiff,jp2,xwd,sun,ras,rs,im1,im8,im24,"
+    .extensions     = "bmp,dpx,jls,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,"
+                      "ppm,sgi,tga,tif,tiff,jp2,j2c,xwd,sun,ras,rs,im1,im8,im24,"
                       "sunras,xbm",
     .priv_data_size = sizeof(VideoMuxData),
     .video_codec    = AV_CODEC_ID_MJPEG,
diff --git a/libavformat/ingenientdec.c b/libavformat/ingenientdec.c
index 42b29ef..94c549c 100644
--- a/libavformat/ingenientdec.c
+++ b/libavformat/ingenientdec.c
@@ -2,20 +2,20 @@
  * RAW Ingenient MJPEG demuxer
  * Copyright (c) 2005 Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -44,17 +44,10 @@
     av_log(s, AV_LOG_DEBUG, "Ingenient packet: size=%d, width=%d, height=%d, unk1=%d unk2=%d\n",
         size, w, h, unk1, unk2);
 
-    if (av_new_packet(pkt, size) < 0)
-        return AVERROR(ENOMEM);
-
-    pkt->pos = avio_tell(s->pb);
-    pkt->stream_index = 0;
-    ret = avio_read(s->pb, pkt->data, size);
-    if (ret < 0) {
-        av_free_packet(pkt);
+    ret = av_get_packet(s->pb, pkt, size);
+    if (ret < 0)
         return ret;
-    }
-    pkt->size = ret;
+    pkt->stream_index = 0;
     return ret;
 }
 
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 3ef46ea..2689b2f 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -42,20 +42,18 @@
     enum AVCodecID id;
 } CodecMime;
 
-void ff_dynarray_add(intptr_t **tab_ptr, int *nb_ptr, intptr_t elem);
-
 #ifdef __GNUC__
 #define dynarray_add(tab, nb_ptr, elem)\
 do {\
     __typeof__(tab) _tab = (tab);\
     __typeof__(elem) _elem = (elem);\
     (void)sizeof(**_tab == _elem); /* check that types are compatible */\
-    ff_dynarray_add((intptr_t **)_tab, nb_ptr, (intptr_t)_elem);\
+    av_dynarray_add(_tab, nb_ptr, _elem);\
 } while(0)
 #else
 #define dynarray_add(tab, nb_ptr, elem)\
 do {\
-    ff_dynarray_add((intptr_t **)(tab), nb_ptr, (intptr_t)(elem));\
+    av_dynarray_add((tab), nb_ptr, (elem));\
 } while(0)
 #endif
 
@@ -78,8 +76,9 @@
 /**
  * Add packet to AVFormatContext->packet_buffer list, determining its
  * interleaved position using compare() function argument.
+ * @return 0, or < 0 on error
  */
-void ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
+int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
                               int (*compare)(AVFormatContext *, AVPacket *, AVPacket *));
 
 void ff_read_frame_flush(AVFormatContext *s);
@@ -345,6 +344,8 @@
 int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
                                  AVPacket *pkt, int flush);
 
+void ff_free_stream(AVFormatContext *s, AVStream *st);
+
 /**
  * Return the frame duration in seconds. Return 0 if not available.
  */
@@ -353,5 +354,13 @@
 
 int ff_get_audio_frame_size(AVCodecContext *enc, int size, int mux);
 
+/**
+ * Chooses a timebase for muxing the specified stream.
+ *
+ * The choosen timebase allows sample accurate timestamps based
+ * on the framerate or sample rate for audio streams. It also is
+ * at least as precisse as 1/min_precission would be.
+ */
+AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precission);
 
 #endif /* AVFORMAT_INTERNAL_H */
diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c
index b567fb2..748f4a4 100644
--- a/libavformat/ipmovie.c
+++ b/libavformat/ipmovie.c
@@ -2,20 +2,20 @@
  * Interplay MVE File Demuxer
  * Copyright (c) 2003 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -116,7 +116,7 @@
 
     int chunk_type;
 
-    if (s->audio_chunk_offset) {
+    if (s->audio_chunk_offset && s->audio_channels && s->audio_bits) {
         if (s->audio_type == AV_CODEC_ID_NONE) {
             av_log(NULL, AV_LOG_ERROR, "Can not read audio packet before"
                    "audio codec is known\n");
@@ -236,7 +236,7 @@
         return chunk_type;
 
     /* read the next chunk, wherever the file happens to be pointing */
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return CHUNK_EOF;
     if (avio_read(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) !=
         CHUNK_PREAMBLE_SIZE)
@@ -282,7 +282,7 @@
     while ((chunk_size > 0) && (chunk_type != CHUNK_BAD)) {
 
         /* read the next chunk, wherever the file happens to be pointing */
-        if (pb->eof_reached) {
+        if (url_feof(pb)) {
             chunk_type = CHUNK_EOF;
             break;
         }
@@ -475,7 +475,8 @@
                 r = scratch[j++] * 4;
                 g = scratch[j++] * 4;
                 b = scratch[j++] * 4;
-                s->palette[i] = (r << 16) | (g << 8) | (b);
+                s->palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | (b);
+                s->palette[i] |= s->palette[i] >> 6 & 0x30303;
             }
             s->has_palette = 1;
             break;
@@ -528,8 +529,9 @@
     uint8_t *b = p->buf;
     uint8_t *b_end = p->buf + p->buf_size - sizeof(signature);
     do {
-        if (memcmp(b++, signature, sizeof(signature)) == 0)
+        if (b[0] == signature[0] && memcmp(b, signature, sizeof(signature)) == 0)
             return AVPROBE_SCORE_MAX;
+        b++;
     } while (b < b_end);
 
     return 0;
@@ -542,14 +544,14 @@
     AVPacket pkt;
     AVStream *st;
     unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE];
-    int chunk_type;
+    int chunk_type, i;
     uint8_t signature_buffer[sizeof(signature)];
 
     avio_read(pb, signature_buffer, sizeof(signature_buffer));
     while (memcmp(signature_buffer, signature, sizeof(signature))) {
         memmove(signature_buffer, signature_buffer + 1, sizeof(signature_buffer) - 1);
         signature_buffer[sizeof(signature_buffer) - 1] = avio_r8(pb);
-        if (pb->eof_reached)
+        if (url_feof(pb))
             return AVERROR_EOF;
     }
     /* initialize private context members */
@@ -560,6 +562,9 @@
     /* on the first read, this will position the stream at the first chunk */
     ipmovie->next_chunk_offset = avio_tell(pb) + 4;
 
+    for (i = 0; i < 256; i++)
+        ipmovie->palette[i] = 0xFFU << 24;
+
     /* process the first chunk which should be CHUNK_INIT_VIDEO */
     if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_VIDEO)
         return AVERROR_INVALIDDATA;
@@ -619,6 +624,7 @@
     AVIOContext *pb = s->pb;
     int ret;
 
+    for (;;) {
     ret = process_ipmovie_chunk(ipmovie, pb, pkt);
     if (ret == CHUNK_BAD)
         ret = AVERROR_INVALIDDATA;
@@ -628,10 +634,13 @@
         ret = AVERROR(ENOMEM);
     else if (ret == CHUNK_VIDEO)
         ret = 0;
+    else if (ret == CHUNK_INIT_VIDEO || ret == CHUNK_INIT_AUDIO)
+        continue;
     else
         ret = -1;
 
     return ret;
+    }
 }
 
 AVInputFormat ff_ipmovie_demuxer = {
diff --git a/libavformat/isom.c b/libavformat/isom.c
index ad87129..3271056 100644
--- a/libavformat/isom.c
+++ b/libavformat/isom.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2002 Francois Revol <revol@free.fr>
  * Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@free.fr>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -71,7 +71,6 @@
 
     { AV_CODEC_ID_RAWVIDEO, MKTAG('r', 'a', 'w', ' ') }, /* Uncompressed RGB */
     { AV_CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', '2') }, /* Uncompressed YUV422 */
-    { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'U', 'I') }, /* YUV with alpha-channel (AVID Uncompressed) */
     { AV_CODEC_ID_RAWVIDEO, MKTAG('2', 'v', 'u', 'y') }, /* UNCOMPRESSED 8BIT 4:2:2 */
     { AV_CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', 's') }, /* same as 2vuy but byte swapped */
 
@@ -84,13 +83,28 @@
     { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'B', 'G', 'R') },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('b', '1', '6', 'g') },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('b', '4', '8', 'r') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('b', 'x', 'b', 'g') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('b', 'x', 'r', 'g') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('b', 'x', 'y', 'v') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('N', 'O', '1', '6') },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('D', 'V', 'O', 'O') }, /* Digital Voodoo SD 8 Bit */
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', '4', '2', '0') }, /* Radius DV YUV PAL */
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', '4', '1', '1') }, /* Radius DV YUV NTSC */
 
     { AV_CODEC_ID_R10K,   MKTAG('R', '1', '0', 'k') }, /* UNCOMPRESSED 10BIT RGB */
     { AV_CODEC_ID_R10K,   MKTAG('R', '1', '0', 'g') }, /* UNCOMPRESSED 10BIT RGB */
     { AV_CODEC_ID_R210,   MKTAG('r', '2', '1', '0') }, /* UNCOMPRESSED 10BIT RGB */
+    { AV_CODEC_ID_AVUI,   MKTAG('A', 'V', 'U', 'I') }, /* AVID Uncompressed deinterleaved UYVY422 */
+    { AV_CODEC_ID_AVRP,   MKTAG('A', 'V', 'r', 'p') }, /* Avid 1:1 10-bit RGB Packer */
+    { AV_CODEC_ID_AVRP,   MKTAG('S', 'U', 'D', 'S') }, /* Avid DS Uncompressed */
     { AV_CODEC_ID_V210,   MKTAG('v', '2', '1', '0') }, /* UNCOMPRESSED 10BIT 4:2:2 */
+    { AV_CODEC_ID_V210,   MKTAG('b', 'x', 'y', '2') }, /* BOXX 10BIT 4:2:2 */
+    { AV_CODEC_ID_V308,   MKTAG('v', '3', '0', '8') }, /* UNCOMPRESSED  8BIT 4:4:4 */
+    { AV_CODEC_ID_V408,   MKTAG('v', '4', '0', '8') }, /* UNCOMPRESSED  8BIT 4:4:4:4 */
     { AV_CODEC_ID_V410,   MKTAG('v', '4', '1', '0') }, /* UNCOMPRESSED 10BIT 4:4:4 */
+    { AV_CODEC_ID_Y41P,   MKTAG('Y', '4', '1', 'P') }, /* UNCOMPRESSED 12BIT 4:1:1 */
+    { AV_CODEC_ID_YUV4,   MKTAG('y', 'u', 'v', '4') }, /* libquicktime packed yuv420p */
+    { AV_CODEC_ID_TARGA_Y216, MKTAG('Y', '2', '1', '6') },
 
     { AV_CODEC_ID_MJPEG,  MKTAG('j', 'p', 'e', 'g') }, /* PhotoJPEG */
     { AV_CODEC_ID_MJPEG,  MKTAG('m', 'j', 'p', 'a') }, /* Motion-JPEG (format A) */
@@ -155,6 +169,7 @@
 
     { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', '1') }, /* Apple MPEG-1 Camcorder */
     { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') }, /* MPEG */
+    { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', ' ') },
     { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', '2', 'v', '1') }, /* Apple MPEG-2 Camcorder */
     { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '1') }, /* MPEG2 HDV 720p30 */
     { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '2') }, /* MPEG2 HDV 1080i60 */
@@ -206,24 +221,27 @@
     { AV_CODEC_ID_TIFF,  MKTAG('t', 'i', 'f', 'f') }, /* TIFF embedded in MOV */
     { AV_CODEC_ID_GIF,   MKTAG('g', 'i', 'f', ' ') }, /* embedded gif files as frames (usually one "click to play movie" frame) */
     { AV_CODEC_ID_PNG,   MKTAG('p', 'n', 'g', ' ') },
+    { AV_CODEC_ID_PNG,   MKTAG('M', 'N', 'G', ' ') },
 
     { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') }, /* SMPTE RP 2025 */
     { AV_CODEC_ID_CAVS, MKTAG('a', 'v', 's', '2') },
 
     { 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 */
+//  { AV_CODEC_ID_FLV1,      MKTAG('H', '2', '6', '3') }, /* Flash Media Server */
     { 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') },
     { AV_CODEC_ID_SGI,       MKTAG('s', 'g', 'i', ' ') }, /* SGI  */
     { AV_CODEC_ID_DPX,       MKTAG('d', 'p', 'x', ' ') }, /* DPX */
+    { AV_CODEC_ID_EXR,       MKTAG('e', 'x', 'r', ' ') }, /* OpenEXR */
 
     { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'h') }, /* Apple ProRes 422 High Quality */
     { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'n') }, /* Apple ProRes 422 Standard Definition */
     { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 's') }, /* Apple ProRes 422 LT */
     { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'o') }, /* Apple ProRes 422 Proxy */
     { AV_CODEC_ID_PRORES, MKTAG('a', 'p', '4', 'h') }, /* Apple ProRes 4444 */
+    { AV_CODEC_ID_FLIC,   MKTAG('f', 'l', 'i', 'c') },
 
     { AV_CODEC_ID_NONE, 0 },
 };
@@ -281,6 +299,7 @@
 const AVCodecTag ff_codec_movsubtitle_tags[] = {
     { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'e', 'x', 't') },
     { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') },
+    { AV_CODEC_ID_EIA_608,  MKTAG('c', '6', '0', '8') },
     { AV_CODEC_ID_NONE, 0 },
 };
 
@@ -343,7 +362,7 @@
     memset(to, 0, 4);
     /* is it the mangled iso code? */
     /* see http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt */
-    if (code > 138) {
+    if (code >= 0x400 && code != 0x7fff) {
         for (i = 2; i >= 0; i--) {
             to[i] = 0x60 + (code & 0x1f);
             code >>= 5;
@@ -450,3 +469,95 @@
     }
     return 0;
 }
+
+typedef struct MovChannelLayout {
+    int64_t  channel_layout;
+    uint32_t layout_tag;
+} MovChannelLayout;
+
+static const MovChannelLayout mov_channel_layout[] = {
+    { AV_CH_LAYOUT_MONO,                         (100<<16) | 1}, // kCAFChannelLayoutTag_Mono
+    { AV_CH_LAYOUT_STEREO,                       (101<<16) | 2}, // kCAFChannelLayoutTag_Stereo
+    { AV_CH_LAYOUT_STEREO,                       (102<<16) | 2}, // kCAFChannelLayoutTag_StereoHeadphones
+    { AV_CH_LAYOUT_2_1,                          (131<<16) | 3}, // kCAFChannelLayoutTag_ITU_2_1
+    { AV_CH_LAYOUT_QUAD,                         (132<<16) | 4}, // kCAFChannelLayoutTag_ITU_2_2
+    { AV_CH_LAYOUT_2_2,                          (132<<16) | 4}, // kCAFChannelLayoutTag_ITU_2_2
+    { AV_CH_LAYOUT_QUAD,                         (108<<16) | 4}, // kCAFChannelLayoutTag_Quadraphonic
+    { AV_CH_LAYOUT_SURROUND,                     (113<<16) | 3}, // kCAFChannelLayoutTag_MPEG_3_0_A
+    { AV_CH_LAYOUT_4POINT0,                      (115<<16) | 4}, // kCAFChannelLayoutTag_MPEG_4_0_A
+    { AV_CH_LAYOUT_5POINT0_BACK,                 (117<<16) | 5}, // kCAFChannelLayoutTag_MPEG_5_0_A
+    { AV_CH_LAYOUT_5POINT0,                      (117<<16) | 5}, // kCAFChannelLayoutTag_MPEG_5_0_A
+    { AV_CH_LAYOUT_5POINT1_BACK,                 (121<<16) | 6}, // kCAFChannelLayoutTag_MPEG_5_1_A
+    { AV_CH_LAYOUT_5POINT1,                      (121<<16) | 6}, // kCAFChannelLayoutTag_MPEG_5_1_A
+    { AV_CH_LAYOUT_7POINT1,                      (128<<16) | 8}, // kCAFChannelLayoutTag_MPEG_7_1_C
+    { AV_CH_LAYOUT_7POINT1_WIDE,                 (126<<16) | 8}, // kCAFChannelLayoutTag_MPEG_7_1_A
+    { AV_CH_LAYOUT_5POINT1_BACK|AV_CH_LAYOUT_STEREO_DOWNMIX, (130<<16) | 8}, // kCAFChannelLayoutTag_SMPTE_DTV
+    { AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY,   (133<<16) | 3}, // kCAFChannelLayoutTag_DVD_4
+    { AV_CH_LAYOUT_2_1|AV_CH_LOW_FREQUENCY,      (134<<16) | 4}, // kCAFChannelLayoutTag_DVD_5
+    { AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY,     (135<<16) | 4}, // kCAFChannelLayoutTag_DVD_6
+    { AV_CH_LAYOUT_2_2|AV_CH_LOW_FREQUENCY,      (135<<16) | 4}, // kCAFChannelLayoutTag_DVD_6
+    { AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY, (136<<16) | 4}, // kCAFChannelLayoutTag_DVD_10
+    { AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY,  (137<<16) | 5}, // kCAFChannelLayoutTag_DVD_11
+    { 0, 0},
+};
+#if 0
+int ff_mov_read_chan(AVFormatContext *s, AVStream *st, int64_t size)
+{
+    AVCodecContext *codec= st->codec;
+    uint32_t layout_tag;
+    AVIOContext *pb = s->pb;
+    const MovChannelLayout *layouts = mov_channel_layout;
+
+    if (size < 12)
+        return AVERROR_INVALIDDATA;
+
+    layout_tag = avio_rb32(pb);
+    size -= 4;
+    if (layout_tag == 0) { // kCAFChannelLayoutTag_UseChannelDescriptions
+        // Channel descriptions not implemented
+        av_log_ask_for_sample(s, "Unimplemented container channel layout.\n");
+        avio_skip(pb, size);
+        return 0;
+    }
+    if (layout_tag == 0x10000) { // kCAFChannelLayoutTag_UseChannelBitmap
+        codec->channel_layout = avio_rb32(pb);
+        size -= 4;
+        avio_skip(pb, size);
+        return 0;
+    }
+    while (layouts->channel_layout) {
+        if (layout_tag == layouts->layout_tag) {
+            codec->channel_layout = layouts->channel_layout;
+            break;
+        }
+        layouts++;
+    }
+    if (!codec->channel_layout)
+        av_log(s, AV_LOG_WARNING, "Unknown container channel layout.\n");
+    avio_skip(pb, size);
+
+    return 0;
+}
+#endif
+
+void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout)
+{
+    const MovChannelLayout *layouts;
+    uint32_t layout_tag = 0;
+
+    for (layouts = mov_channel_layout; layouts->channel_layout; layouts++)
+        if (channel_layout == layouts->channel_layout) {
+            layout_tag = layouts->layout_tag;
+            break;
+        }
+
+    if (layout_tag) {
+        avio_wb32(pb, layout_tag); // mChannelLayoutTag
+        avio_wb32(pb, 0);          // mChannelBitmap
+    } else {
+        avio_wb32(pb, 0x10000);    // kCAFChannelLayoutTag_UseChannelBitmap
+        avio_wb32(pb, channel_layout);
+    }
+    avio_wb32(pb, 0);              // mNumberChannelDescriptions
+}
+
diff --git a/libavformat/isom.h b/libavformat/isom.h
index 932b1d0..f6eba56 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -4,20 +4,20 @@
  * copyright (c) 2002 Francois Revol <revol@free.fr>
  * copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@free.fr>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -108,14 +108,17 @@
     unsigned *stps_data;  ///< partial sync sample for mpeg-2 open gop
     int ctts_index;
     int ctts_sample;
-    unsigned int sample_size;
+    unsigned int sample_size; ///< may contain value calculated from stsd or value from stsz atom
+    unsigned int alt_sample_size; ///< always contains sample size from stsz atom
     unsigned int sample_count;
     int *sample_sizes;
     int keyframe_absent;
     unsigned int keyframe_count;
     int *keyframes;
     int time_scale;
-    int64_t time_offset;  ///< time offset of the first edit list entry
+    int64_t empty_duration; ///< empty duration of the first edit list entry
+    int64_t start_time;   ///< start time of the media
+    int64_t time_offset;  ///< time offset of the edit list entries
     int current_sample;
     unsigned int bytes_per_frame;
     unsigned int samples_per_frame;
@@ -125,6 +128,9 @@
     unsigned drefs_count;
     MOVDref *drefs;
     int dref_id;
+    unsigned tref_type;
+    unsigned trefs_count;
+    uint32_t *trefs;
     int wrong_dts;        ///< dts are wrong due to huge ctts offset (iMovie files)
     int width;            ///< tkhd width
     int height;           ///< tkhd height
@@ -132,12 +138,15 @@
     uint32_t palette[256];
     int has_palette;
     int64_t data_size;
+    uint32_t tmcd_flags;  ///< tmcd track flags
     int64_t track_end;    ///< used for dts generation in fragmented movie files
+    int start_pad;        ///< amount of samples to skip due to enc-dec delay
     unsigned int rap_group_count;
     MOVSbgp *rap_group;
 } MOVStreamContext;
 
 typedef struct MOVContext {
+    AVClass *avclass;
     AVFormatContext *fc;
     int time_scale;
     int64_t duration;     ///< duration of the longest track
@@ -151,6 +160,8 @@
     unsigned trex_count;
     int itunes_metadata;  ///< metadata are itunes style
     int chapter_track;
+    int use_absolute_path;
+    int ignore_editlist;
     int64_t next_root_atom; ///< offset of the next root atom
 } MOVContext;
 
@@ -194,5 +205,6 @@
 enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags);
 
 int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries);
+void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout);
 
 #endif /* AVFORMAT_ISOM_H */
diff --git a/libavformat/iss.c b/libavformat/iss.c
index 14f64d2..4268900 100644
--- a/libavformat/iss.c
+++ b/libavformat/iss.c
@@ -2,20 +2,20 @@
  * ISS (.iss) file demuxer
  * Copyright (c) 2008 Jaikrishnan Menon <realityman@gmx.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -87,6 +87,11 @@
     get_token(pb, token, sizeof(token)); //Version ID
     get_token(pb, token, sizeof(token)); //Size
 
+    if (iss->packet_size <= 0) {
+        av_log(s, AV_LOG_ERROR, "packet_size %d is invalid\n", iss->packet_size);
+        return AVERROR_INVALIDDATA;
+    }
+
     iss->sample_start_pos = avio_tell(pb);
 
     st = avformat_new_stream(s, NULL);
diff --git a/libavformat/iv8.c b/libavformat/iv8.c
index 56909e3..38b7960 100644
--- a/libavformat/iv8.c
+++ b/libavformat/iv8.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/ivfdec.c b/libavformat/ivfdec.c
index b3555f4..c0fdafb 100644
--- a/libavformat/ivfdec.c
+++ b/libavformat/ivfdec.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 David Conrad
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/ivfenc.c b/libavformat/ivfenc.c
index e045597..ddb205b 100644
--- a/libavformat/ivfenc.c
+++ b/libavformat/ivfenc.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Reimar Döffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
diff --git a/libavformat/jacosubdec.c b/libavformat/jacosubdec.c
new file mode 100644
index 0000000..f9defd2
--- /dev/null
+++ b/libavformat/jacosubdec.c
@@ -0,0 +1,260 @@
+/*
+ * 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
+ * JACOsub subtitle demuxer
+ * @see http://unicorn.us.com/jacosub/jscripts.html
+ * @todo Support P[ALETTE] directive.
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+#include "libavcodec/jacosub.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+#include "libavutil/intreadwrite.h"
+
+typedef struct {
+    int shift;
+    unsigned timeres;
+    FFDemuxSubtitlesQueue q;
+} JACOsubContext;
+
+static int timed_line(const char *ptr)
+{
+    char c;
+    return (sscanf(ptr, "%*u:%*u:%*u.%*u %*u:%*u:%*u.%*u %c", &c) == 1 ||
+            sscanf(ptr, "@%*u @%*u %c",                       &c) == 1);
+}
+
+static int jacosub_probe(AVProbeData *p)
+{
+    const char *ptr     = p->buf;
+    const char *ptr_end = p->buf + p->buf_size;
+
+    if (AV_RB24(ptr) == 0xEFBBBF)
+        ptr += 3; /* skip UTF-8 BOM */
+
+    while (ptr < ptr_end) {
+        while (jss_whitespace(*ptr))
+            ptr++;
+        if (*ptr != '#' && *ptr != '\n') {
+            if (timed_line(ptr))
+                return AVPROBE_SCORE_MAX/2 + 1;
+            return 0;
+        }
+        ptr += strcspn(ptr, "\n") + 1;
+    }
+    return 0;
+}
+
+static const char * const cmds[] = {
+    "CLOCKPAUSE",
+    "DIRECTIVE",
+    "FONT",
+    "HRES",
+    "INCLUDE",
+    "PALETTE",
+    "QUANTIZE",
+    "RAMP",
+    "SHIFT",
+    "TIMERES",
+};
+
+static int get_jss_cmd(char k)
+{
+    int i;
+
+    k = av_toupper(k);
+    for (i = 0; i < FF_ARRAY_ELEMS(cmds); i++)
+        if (k == cmds[i][0])
+            return i;
+    return -1;
+}
+
+static int jacosub_read_close(AVFormatContext *s)
+{
+    JACOsubContext *jacosub = s->priv_data;
+    ff_subtitles_queue_clean(&jacosub->q);
+    return 0;
+}
+
+static const char *read_ts(JACOsubContext *jacosub, const char *buf,
+                           int64_t *start, int *duration)
+{
+    int len;
+    unsigned hs, ms, ss, fs; // hours, minutes, seconds, frame start
+    unsigned he, me, se, fe; // hours, minutes, seconds, frame end
+    int ts_start, ts_end;
+
+    /* timed format */
+    if (sscanf(buf, "%u:%u:%u.%u %u:%u:%u.%u %n",
+               &hs, &ms, &ss, &fs,
+               &he, &me, &se, &fe, &len) == 8) {
+        ts_start = (hs*3600 + ms*60 + ss) * jacosub->timeres + fs;
+        ts_end   = (he*3600 + me*60 + se) * jacosub->timeres + fe;
+        goto shift_and_ret;
+    }
+
+    /* timestamps format */
+    if (sscanf(buf, "@%u @%u %n", &ts_start, &ts_end, &len) == 2)
+        goto shift_and_ret;
+
+    return NULL;
+
+shift_and_ret:
+    ts_start  = (ts_start + jacosub->shift) * 100 / jacosub->timeres;
+    ts_end    = (ts_end   + jacosub->shift) * 100 / jacosub->timeres;
+    *start    = ts_start;
+    *duration = ts_start + ts_end;
+    return buf + len;
+}
+
+static int get_shift(int timeres, const char *buf)
+{
+    int sign = 1;
+    int a = 0, b = 0, c = 0, d = 0;
+#define SSEP "%*1[.:]"
+    int n = sscanf(buf, "%d"SSEP"%d"SSEP"%d"SSEP"%d", &a, &b, &c, &d);
+#undef SSEP
+
+    if (*buf == '-' || a < 0) {
+        sign = -1;
+        a = FFABS(a);
+    }
+
+    switch (n) {
+    case 4: return sign * ((a*3600 + b*60 + c) * timeres + d);
+    case 3: return sign * ((         a*60 + b) * timeres + c);
+    case 2: return sign * ((                a) * timeres + b);
+    }
+
+    return 0;
+}
+
+static int jacosub_read_header(AVFormatContext *s)
+{
+    AVBPrint header;
+    AVIOContext *pb = s->pb;
+    char line[JSS_MAX_LINESIZE];
+    JACOsubContext *jacosub = s->priv_data;
+    int shift_set = 0; // only the first shift matters
+    int merge_line = 0;
+    int i;
+
+    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_JACOSUB;
+
+    jacosub->timeres = 30;
+
+    av_bprint_init(&header, 1024+FF_INPUT_BUFFER_PADDING_SIZE, 4096);
+
+    while (!url_feof(pb)) {
+        int cmd_len;
+        const char *p = line;
+        int64_t pos = avio_tell(pb);
+        int len = ff_get_line(pb, line, sizeof(line));
+
+        p = jss_skip_whitespace(p);
+
+        /* queue timed line */
+        if (merge_line || timed_line(p)) {
+            AVPacket *sub;
+
+            sub = ff_subtitles_queue_insert(&jacosub->q, line, len, merge_line);
+            if (!sub)
+                return AVERROR(ENOMEM);
+            sub->pos = pos;
+            merge_line = len > 1 && !strcmp(&line[len - 2], "\\\n");
+            continue;
+        }
+
+        /* skip all non-compiler commands and focus on the command */
+        if (*p != '#')
+            continue;
+        p++;
+        i = get_jss_cmd(p[0]);
+        if (i == -1)
+            continue;
+
+        /* trim command + spaces */
+        cmd_len = strlen(cmds[i]);
+        if (av_strncasecmp(p, cmds[i], cmd_len) == 0)
+            p += cmd_len;
+        else
+            p++;
+        p = jss_skip_whitespace(p);
+
+        /* handle commands which affect the whole script */
+        switch (cmds[i][0]) {
+        case 'S': // SHIFT command affect the whole script...
+            if (!shift_set) {
+                jacosub->shift = get_shift(jacosub->timeres, p);
+                shift_set = 1;
+            }
+            av_bprintf(&header, "#S %s", p);
+            break;
+        case 'T': // ...but must be placed after TIMERES
+            jacosub->timeres = strtol(p, NULL, 10);
+            if (!jacosub->timeres)
+                jacosub->timeres = 30;
+            else
+                av_bprintf(&header, "#T %s", p);
+            break;
+        }
+    }
+
+    /* general/essential directives in the extradata */
+    av_bprint_finalize(&header, (char **)&st->codec->extradata);
+    st->codec->extradata_size = header.len + 1;
+
+    /* SHIFT and TIMERES affect the whole script so packet timing can only be
+     * done in a second pass */
+    for (i = 0; i < jacosub->q.nb_subs; i++) {
+        AVPacket *sub = &jacosub->q.subs[i];
+        read_ts(jacosub, sub->data, &sub->pts, &sub->duration);
+    }
+    ff_subtitles_queue_finalize(&jacosub->q);
+
+    return 0;
+}
+
+static int jacosub_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    JACOsubContext *jacosub = s->priv_data;
+    return ff_subtitles_queue_read_packet(&jacosub->q, pkt);
+}
+
+AVInputFormat ff_jacosub_demuxer = {
+    .name           = "jacosub",
+    .long_name      = NULL_IF_CONFIG_SMALL("JACOsub subtitle format"),
+    .priv_data_size = sizeof(JACOsubContext),
+    .read_probe     = jacosub_probe,
+    .read_header    = jacosub_read_header,
+    .read_packet    = jacosub_read_packet,
+    .read_close     = jacosub_read_close,
+    .flags          = AVFMT_GENERIC_INDEX,
+};
diff --git a/libavformat/jacosubenc.c b/libavformat/jacosubenc.c
new file mode 100644
index 0000000..a11e45a
--- /dev/null
+++ b/libavformat/jacosubenc.c
@@ -0,0 +1,42 @@
+/*
+ * 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 "rawenc.h"
+
+static int jacosub_write_header(AVFormatContext *s)
+{
+    const AVCodecContext *avctx = s->streams[0]->codec;
+
+    if (avctx->extradata_size) {
+        avio_write(s->pb, avctx->extradata, avctx->extradata_size - 1);
+        avio_flush(s->pb);
+    }
+    return 0;
+}
+
+AVOutputFormat ff_jacosub_muxer = {
+    .name           = "jacosub",
+    .long_name      = NULL_IF_CONFIG_SMALL("JACOsub subtitle format"),
+    .mime_type      = "text/x-jacosub",
+    .extensions     = "jss,js",
+    .write_header   = jacosub_write_header,
+    .write_packet   = ff_raw_write_packet,
+    .flags          = AVFMT_TS_NONSTRICT,
+    .subtitle_codec = AV_CODEC_ID_JACOSUB,
+};
diff --git a/libavformat/jvdec.c b/libavformat/jvdec.c
index 47a6142..2eac265 100644
--- a/libavformat/jvdec.c
+++ b/libavformat/jvdec.c
@@ -2,20 +2,20 @@
  * Bitmap Brothers JV demuxer
  * Copyright (c) 2005, 2011 Peter Ross <pross@xvid.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -52,8 +52,8 @@
 
 static int read_probe(AVProbeData *pd)
 {
-    if (pd->buf[0] == 'J' && pd->buf[1] == 'V' &&
-        !memcmp(pd->buf + 4, MAGIC, FFMIN(strlen(MAGIC), pd->buf_size - 4)))
+    if (pd->buf[0] == 'J' && pd->buf[1] == 'V' && strlen(MAGIC) <= pd->buf_size - 4 &&
+        !memcmp(pd->buf + 4, MAGIC, strlen(MAGIC)))
         return AVPROBE_SCORE_MAX;
     return 0;
 }
@@ -140,7 +140,7 @@
     AVIOContext *pb = s->pb;
     AVStream *ast = s->streams[0];
 
-    while (!s->pb->eof_reached && jv->pts < ast->nb_index_entries) {
+    while (!url_feof(s->pb) && jv->pts < ast->nb_index_entries) {
         const AVIndexEntry *e   = ast->index_entries + jv->pts;
         const JVFrame      *jvf = jv->frames + jv->pts;
 
@@ -164,7 +164,7 @@
 
                 AV_WL32(pkt->data, jvf->video_size);
                 pkt->data[4]      = jvf->video_type;
-                if (avio_read(pb, pkt->data + JV_PREAMBLE_SIZE, size) < 0)
+                if ((size = avio_read(pb, pkt->data + JV_PREAMBLE_SIZE, size)) < 0)
                     return AVERROR(EIO);
 
                 pkt->size         = size + JV_PREAMBLE_SIZE;
@@ -216,6 +216,15 @@
     return 0;
 }
 
+static int read_close(AVFormatContext *s)
+{
+    JVDemuxContext *jv = s->priv_data;
+
+    av_freep(&jv->frames);
+
+    return 0;
+}
+
 AVInputFormat ff_jv_demuxer = {
     .name           = "jv",
     .long_name      = NULL_IF_CONFIG_SMALL("Bitmap Brothers JV"),
@@ -224,4 +233,5 @@
     .read_header    = read_header,
     .read_packet    = read_packet,
     .read_seek      = read_seek,
+    .read_close     = read_close,
 };
diff --git a/libavformat/latmenc.c b/libavformat/latmenc.c
index 7270292..233eab8 100644
--- a/libavformat/latmenc.c
+++ b/libavformat/latmenc.c
@@ -25,6 +25,9 @@
 #include "libavcodec/mpeg4audio.h"
 #include "libavutil/opt.h"
 #include "avformat.h"
+#include "rawenc.h"
+
+#define MAX_EXTRADATA_SIZE 1024
 
 typedef struct {
     AVClass *av_class;
@@ -33,6 +36,7 @@
     int object_type;
     int counter;
     int mod;
+    uint8_t buffer[0x1fff + MAX_EXTRADATA_SIZE + 1024];
 } LATMContext;
 
 static const AVOption options[] = {
@@ -50,15 +54,21 @@
 
 static int latm_decode_extradata(LATMContext *ctx, uint8_t *buf, int size)
 {
-    GetBitContext gb;
     MPEG4AudioConfig m4ac;
 
-    init_get_bits(&gb, buf, size * 8);
+    if (size > MAX_EXTRADATA_SIZE) {
+        av_log(ctx, AV_LOG_ERROR, "Extradata is larger than currently supported.\n");
+        return AVERROR_INVALIDDATA;
+    }
     ctx->off = avpriv_mpeg4audio_get_config(&m4ac, buf, size * 8, 1);
     if (ctx->off < 0)
         return ctx->off;
-    skip_bits_long(&gb, ctx->off);
 
+    if (ctx->object_type == AOT_ALS && (ctx->off & 7)) {
+        // as long as avpriv_mpeg4audio_get_config works correctly this is impossible
+        av_log(ctx, AV_LOG_ERROR, "BUG: ALS offset is not byte-aligned\n");
+        return AVERROR_INVALIDDATA;
+    }
     /* FIXME: are any formats not allowed in LATM? */
 
     if (m4ac.object_type > AOT_SBR && m4ac.object_type != AOT_ALS) {
@@ -76,6 +86,9 @@
     LATMContext *ctx = s->priv_data;
     AVCodecContext *avctx = s->streams[0]->codec;
 
+    if (avctx->codec_id == AV_CODEC_ID_AAC_LATM)
+        return 0;
+
     if (avctx->extradata_size > 0 &&
         latm_decode_extradata(ctx, avctx->extradata, avctx->extradata_size) < 0)
         return AVERROR_INVALIDDATA;
@@ -83,19 +96,16 @@
     return 0;
 }
 
-static int latm_write_frame_header(AVFormatContext *s, PutBitContext *bs)
+static void latm_write_frame_header(AVFormatContext *s, PutBitContext *bs)
 {
     LATMContext *ctx = s->priv_data;
     AVCodecContext *avctx = s->streams[0]->codec;
-    GetBitContext gb;
     int header_size;
 
     /* AudioMuxElement */
     put_bits(bs, 1, !!ctx->counter);
 
     if (!ctx->counter) {
-        init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8);
-
         /* StreamMuxConfig */
         put_bits(bs, 1, 0); /* audioMuxVersion */
         put_bits(bs, 1, 1); /* allStreamsSameTimeFraming */
@@ -105,12 +115,17 @@
 
         /* AudioSpecificConfig */
         if (ctx->object_type == AOT_ALS) {
-            header_size = avctx->extradata_size-(ctx->off + 7) >> 3;
-            avpriv_copy_bits(bs, &avctx->extradata[ctx->off], header_size);
+            header_size = avctx->extradata_size-(ctx->off >> 3);
+            avpriv_copy_bits(bs, &avctx->extradata[ctx->off >> 3], header_size);
         } else {
+            // + 3 assumes not scalable and dependsOnCoreCoder == 0,
+            // see decode_ga_specific_config in libavcodec/aacdec.c
             avpriv_copy_bits(bs, avctx->extradata, ctx->off + 3);
 
             if (!ctx->channel_conf) {
+                GetBitContext gb;
+                init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8);
+                skip_bits_long(&gb, ctx->off + 3);
                 avpriv_copy_pce_data(bs, &gb);
             }
         }
@@ -124,28 +139,27 @@
 
     ctx->counter++;
     ctx->counter %= ctx->mod;
-
-    return 0;
 }
 
 static int latm_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
+    LATMContext *ctx = s->priv_data;
     AVIOContext *pb = s->pb;
     PutBitContext bs;
     int i, len;
     uint8_t loas_header[] = "\x56\xe0\x00";
-    uint8_t *buf;
+
+    if (s->streams[0]->codec->codec_id == AV_CODEC_ID_AAC_LATM)
+        return ff_raw_write_packet(s, pkt);
 
     if (pkt->size > 2 && pkt->data[0] == 0xff && (pkt->data[1] >> 4) == 0xf) {
         av_log(s, AV_LOG_ERROR, "ADTS header detected - ADTS will not be incorrectly muxed into LATM\n");
         return AVERROR_INVALIDDATA;
     }
+    if (pkt->size > 0x1fff)
+        goto too_large;
 
-    buf = av_malloc(pkt->size+1024);
-    if (!buf)
-        return AVERROR(ENOMEM);
-
-    init_put_bits(&bs, buf, pkt->size+1024);
+    init_put_bits(&bs, ctx->buffer, pkt->size+1024+MAX_EXTRADATA_SIZE);
 
     latm_write_frame_header(s, &bs);
 
@@ -158,30 +172,46 @@
     /* The LATM payload is written unaligned */
 
     /* PayloadMux() */
-    for (i = 0; i < pkt->size; i++)
-        put_bits(&bs, 8, pkt->data[i]);
+    if (pkt->size && (pkt->data[0] & 0xe1) == 0x81) {
+        // Convert byte-aligned DSE to non-aligned.
+        // Due to the input format encoding we know that
+        // it is naturally byte-aligned in the input stream,
+        // so there are no padding bits to account for.
+        // To avoid having to add padding bits and rearrange
+        // the whole stream we just remove the byte-align flag.
+        // This allows us to remux our FATE AAC samples into latm
+        // files that are still playable with minimal effort.
+        put_bits(&bs, 8, pkt->data[0] & 0xfe);
+        avpriv_copy_bits(&bs, pkt->data + 1, 8*pkt->size - 8);
+    } else
+        avpriv_copy_bits(&bs, pkt->data, 8*pkt->size);
 
     avpriv_align_put_bits(&bs);
     flush_put_bits(&bs);
 
     len = put_bits_count(&bs) >> 3;
 
+    if (len > 0x1fff)
+        goto too_large;
+
     loas_header[1] |= (len >> 8) & 0x1f;
     loas_header[2] |= len & 0xff;
 
     avio_write(pb, loas_header, 3);
-    avio_write(pb, buf, len);
-
-    av_free(buf);
+    avio_write(pb, ctx->buffer, len);
 
     return 0;
+
+too_large:
+    av_log(s, AV_LOG_ERROR, "LATM packet size larger than maximum size 0x1fff\n");
+    return AVERROR_INVALIDDATA;
 }
 
 AVOutputFormat ff_latm_muxer = {
     .name           = "latm",
     .long_name      = NULL_IF_CONFIG_SMALL("LOAS/LATM"),
     .mime_type      = "audio/MP4A-LATM",
-    .extensions     = "latm",
+    .extensions     = "latm,loas",
     .priv_data_size = sizeof(LATMContext),
     .audio_codec    = AV_CODEC_ID_AAC,
     .video_codec    = AV_CODEC_ID_NONE,
diff --git a/libavformat/libavformat.v b/libavformat/libavformat.v
index 6f11d60..5f86d62 100644
--- a/libavformat/libavformat.v
+++ b/libavformat/libavformat.v
@@ -1,4 +1,44 @@
 LIBAVFORMAT_$MAJOR {
         global: av*;
+                #FIXME those are for ffserver
+                ff_inet_aton;
+                ff_socket_nonblock;
+                ffm_set_write_index;
+                ffm_read_write_index;
+                ffm_write_write_index;
+                ff_mpegts_parse_close;
+                ff_mpegts_parse_open;
+                ff_mpegts_parse_packet;
+                ff_rtsp_parse_line;
+                ff_rtp_get_local_rtp_port;
+                ff_rtp_get_local_rtcp_port;
+                ffio_open_dyn_packet_buf;
+                ffio_set_buf_size;
+                ffurl_close;
+                ffurl_open;
+                ffurl_read_complete;
+                ffurl_seek;
+                ffurl_size;
+                ffurl_write;
+                ffurl_protocol_next;
+                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;
+                ff_timefilter_update;
+                ff_timefilter_reset;
+                get_*;
+                put_*;
+                udp_set_remote_url;
+                udp_get_local_port;
+                init_checksum;
+                init_put_byte;
         local: *;
 };
diff --git a/libavformat/libmodplug.c b/libavformat/libmodplug.c
new file mode 100644
index 0000000..aa8edcc
--- /dev/null
+++ b/libavformat/libmodplug.c
@@ -0,0 +1,368 @@
+/*
+ * 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
+* ModPlug demuxer
+* @todo better probing than extensions matching
+*/
+
+#include <libmodplug/modplug.h>
+#include "libavutil/avstring.h"
+#include "libavutil/eval.h"
+#include "libavutil/opt.h"
+#include "avformat.h"
+#include "internal.h"
+
+typedef struct ModPlugContext {
+    const AVClass *class;
+    ModPlugFile *f;
+    uint8_t *buf; ///< input file content
+
+    /* options */
+    int noise_reduction;
+    int reverb_depth;
+    int reverb_delay;
+    int bass_amount;
+    int bass_range;
+    int surround_depth;
+    int surround_delay;
+
+    int max_size; ///< max file size to allocate
+
+    /* optional video stream */
+    double ts_per_packet; ///< used to define the pts/dts using packet_count;
+    int packet_count;     ///< total number of audio packets
+    int print_textinfo;   ///< bool flag for printing speed, tempo, order, ...
+    int video_stream;     ///< 1 if the user want a video stream, otherwise 0
+    int w;                ///< video stream width  in char (one char = 8x8px)
+    int h;                ///< video stream height in char (one char = 8x8px)
+    int video_switch;     ///< 1 if current packet is video, otherwise 0
+    int fsize;            ///< constant frame size
+    int linesize;         ///< line size in bytes
+    char *color_eval;     ///< color eval user input expression
+    AVExpr *expr;         ///< parsed color eval expression
+} ModPlugContext;
+
+static const char *var_names[] = {
+    "x", "y",
+    "w", "h",
+    "t",
+    "speed", "tempo", "order", "pattern", "row",
+    NULL
+};
+
+enum var_name {
+    VAR_X, VAR_Y,
+    VAR_W, VAR_H,
+    VAR_TIME,
+    VAR_SPEED, VAR_TEMPO, VAR_ORDER, VAR_PATTERN, VAR_ROW,
+    VAR_VARS_NB
+};
+
+#define FF_MODPLUG_MAX_FILE_SIZE (100 * 1<<20) // 100M
+#define FF_MODPLUG_DEF_FILE_SIZE (  5 * 1<<20) //   5M
+
+#define OFFSET(x) offsetof(ModPlugContext, x)
+#define D AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+    {"noise_reduction", "Enable noise reduction 0(off)-1(on)",  OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = 0}, 0,       1, D},
+    {"reverb_depth",    "Reverb level 0(quiet)-100(loud)",      OFFSET(reverb_depth),    AV_OPT_TYPE_INT, {.i64 = 0}, 0,     100, D},
+    {"reverb_delay",    "Reverb delay in ms, usually 40-200ms", OFFSET(reverb_delay),    AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D},
+    {"bass_amount",     "XBass level 0(quiet)-100(loud)",       OFFSET(bass_amount),     AV_OPT_TYPE_INT, {.i64 = 0}, 0,     100, D},
+    {"bass_range",      "XBass cutoff in Hz 10-100",            OFFSET(bass_range),      AV_OPT_TYPE_INT, {.i64 = 0}, 0,     100, D},
+    {"surround_depth",  "Surround level 0(quiet)-100(heavy)",   OFFSET(surround_depth),  AV_OPT_TYPE_INT, {.i64 = 0}, 0,     100, D},
+    {"surround_delay",  "Surround delay in ms, usually 5-40ms", OFFSET(surround_delay),  AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D},
+    {"max_size",        "Max file size supported (in bytes). Default is 5MB. Set to 0 for no limit (not recommended)",
+     OFFSET(max_size), AV_OPT_TYPE_INT, {.i64 = FF_MODPLUG_DEF_FILE_SIZE}, 0, FF_MODPLUG_MAX_FILE_SIZE, D},
+    {"video_stream_expr", "Color formula",                                  OFFSET(color_eval),     AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, D},
+    {"video_stream",      "Make demuxer output a video stream",             OFFSET(video_stream),   AV_OPT_TYPE_INT, {.i64 = 0},   0,   1, D},
+    {"video_stream_w",    "Video stream width in char (one char = 8x8px)",  OFFSET(w),              AV_OPT_TYPE_INT, {.i64 = 30}, 20, 512, D},
+    {"video_stream_h",    "Video stream height in char (one char = 8x8px)", OFFSET(h),              AV_OPT_TYPE_INT, {.i64 = 30}, 20, 512, D},
+    {"video_stream_ptxt", "Print speed, tempo, order, ... in video stream", OFFSET(print_textinfo), AV_OPT_TYPE_INT, {.i64 = 1},   0,   1, D},
+    {NULL},
+};
+
+#define SET_OPT_IF_REQUESTED(libopt, opt, flag) do {        \
+    if (modplug->opt) {                                     \
+        settings.libopt  = modplug->opt;                    \
+        settings.mFlags |= flag;                            \
+    }                                                       \
+} while (0)
+
+#define ADD_META_MULTIPLE_ENTRIES(entry_name, fname) do {                      \
+    if (n_## entry_name ##s) {                                                 \
+        unsigned i, n = 0;                                                     \
+                                                                               \
+        for (i = 0; i < n_## entry_name ##s; i++) {                            \
+            char item_name[64] = {0};                                          \
+            fname(f, i, item_name);                                            \
+            if (!*item_name)                                                   \
+                continue;                                                      \
+            if (n)                                                             \
+                av_dict_set(&s->metadata, #entry_name, "\n", AV_DICT_APPEND);  \
+            av_dict_set(&s->metadata, #entry_name, item_name, AV_DICT_APPEND); \
+            n++;                                                               \
+        }                                                                      \
+                                                                               \
+        extra = av_asprintf(", %u/%u " #entry_name "%s",                       \
+                            n, n_## entry_name ##s, n > 1 ? "s" : "");         \
+        if (!extra)                                                            \
+            return AVERROR(ENOMEM);                                            \
+        av_dict_set(&s->metadata, "extra info", extra, AV_DICT_APPEND);        \
+        av_free(extra);                                                        \
+    }                                                                          \
+} while (0)
+
+static int modplug_load_metadata(AVFormatContext *s)
+{
+    ModPlugContext *modplug = s->priv_data;
+    ModPlugFile *f = modplug->f;
+    char *extra;
+    const char *name = ModPlug_GetName(f);
+    const char *msg  = ModPlug_GetMessage(f);
+
+    unsigned n_instruments = ModPlug_NumInstruments(f);
+    unsigned n_samples     = ModPlug_NumSamples(f);
+    unsigned n_patterns    = ModPlug_NumPatterns(f);
+    unsigned n_channels    = ModPlug_NumChannels(f);
+
+    if (name && *name) av_dict_set(&s->metadata, "name",    name, 0);
+    if (msg  && *msg)  av_dict_set(&s->metadata, "message", msg,  0);
+
+    extra = av_asprintf("%u pattern%s, %u channel%s",
+                        n_patterns, n_patterns > 1 ? "s" : "",
+                        n_channels, n_channels > 1 ? "s" : "");
+    if (!extra)
+        return AVERROR(ENOMEM);
+    av_dict_set(&s->metadata, "extra info", extra, AV_DICT_DONT_STRDUP_VAL);
+
+    ADD_META_MULTIPLE_ENTRIES(instrument, ModPlug_InstrumentName);
+    ADD_META_MULTIPLE_ENTRIES(sample,     ModPlug_SampleName);
+
+    return 0;
+}
+
+#define AUDIO_PKT_SIZE 512
+
+static int modplug_read_header(AVFormatContext *s)
+{
+    AVStream *st;
+    AVIOContext *pb = s->pb;
+    ModPlug_Settings settings;
+    ModPlugContext *modplug = s->priv_data;
+    int sz = avio_size(pb);
+
+    if (sz < 0) {
+        av_log(s, AV_LOG_WARNING, "Could not determine file size\n");
+        sz = modplug->max_size;
+    } else if (modplug->max_size && sz > modplug->max_size) {
+        sz = modplug->max_size;
+        av_log(s, AV_LOG_WARNING, "Max file size reach%s, allocating %dB "
+               "but demuxing is likely to fail due to incomplete buffer\n",
+               sz == FF_MODPLUG_DEF_FILE_SIZE ? " (see -max_size)" : "", sz);
+    }
+
+    if (modplug->color_eval) {
+        int r = av_expr_parse(&modplug->expr, modplug->color_eval, var_names,
+                              NULL, NULL, NULL, NULL, 0, s);
+        if (r < 0)
+            return r;
+    }
+
+    modplug->buf = av_malloc(modplug->max_size);
+    if (!modplug->buf)
+        return AVERROR(ENOMEM);
+    sz = avio_read(pb, modplug->buf, sz);
+
+    ModPlug_GetSettings(&settings);
+    settings.mChannels       = 2;
+    settings.mBits           = 16;
+    settings.mFrequency      = 44100;
+    settings.mResamplingMode = MODPLUG_RESAMPLE_FIR; // best quality
+    settings.mLoopCount      = 0; // prevents looping forever
+
+    if (modplug->noise_reduction) settings.mFlags     |= MODPLUG_ENABLE_NOISE_REDUCTION;
+    SET_OPT_IF_REQUESTED(mReverbDepth,   reverb_depth,   MODPLUG_ENABLE_REVERB);
+    SET_OPT_IF_REQUESTED(mReverbDelay,   reverb_delay,   MODPLUG_ENABLE_REVERB);
+    SET_OPT_IF_REQUESTED(mBassAmount,    bass_amount,    MODPLUG_ENABLE_MEGABASS);
+    SET_OPT_IF_REQUESTED(mBassRange,     bass_range,     MODPLUG_ENABLE_MEGABASS);
+    SET_OPT_IF_REQUESTED(mSurroundDepth, surround_depth, MODPLUG_ENABLE_SURROUND);
+    SET_OPT_IF_REQUESTED(mSurroundDelay, surround_delay, MODPLUG_ENABLE_SURROUND);
+
+    if (modplug->reverb_depth)   settings.mReverbDepth   = modplug->reverb_depth;
+    if (modplug->reverb_delay)   settings.mReverbDelay   = modplug->reverb_delay;
+    if (modplug->bass_amount)    settings.mBassAmount    = modplug->bass_amount;
+    if (modplug->bass_range)     settings.mBassRange     = modplug->bass_range;
+    if (modplug->surround_depth) settings.mSurroundDepth = modplug->surround_depth;
+    if (modplug->surround_delay) settings.mSurroundDelay = modplug->surround_delay;
+
+    ModPlug_SetSettings(&settings);
+
+    modplug->f = ModPlug_Load(modplug->buf, sz);
+    if (!modplug->f)
+        return AVERROR_INVALIDDATA;
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+    avpriv_set_pts_info(st, 64, 1, 1000);
+    st->duration = ModPlug_GetLength(modplug->f);
+    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id    = AV_CODEC_ID_PCM_S16LE;
+    st->codec->channels    = settings.mChannels;
+    st->codec->sample_rate = settings.mFrequency;
+
+    // timebase = 1/1000, 2ch 16bits 44.1kHz-> 2*2*44100
+    modplug->ts_per_packet = 1000*AUDIO_PKT_SIZE / (4*44100.);
+
+    if (modplug->video_stream) {
+        AVStream *vst = avformat_new_stream(s, NULL);
+        if (!vst)
+            return AVERROR(ENOMEM);
+        avpriv_set_pts_info(vst, 64, 1, 1000);
+        vst->duration = st->duration;
+        vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+        vst->codec->codec_id   = AV_CODEC_ID_XBIN;
+        vst->codec->width      = modplug->w << 3;
+        vst->codec->height     = modplug->h << 3;
+        modplug->linesize = modplug->w * 3;
+        modplug->fsize    = modplug->linesize * modplug->h;
+    }
+
+    return modplug_load_metadata(s);
+}
+
+static void write_text(uint8_t *dst, const char *s, int linesize, int x, int y)
+{
+    int i;
+    dst += y*linesize + x*3;
+    for (i = 0; s[i]; i++, dst += 3) {
+        dst[0] = 0x0;   // count - 1
+        dst[1] = s[i];  // char
+        dst[2] = 0x0f;  // background / foreground
+    }
+}
+
+#define PRINT_INFO(line, name, idvalue) do {                            \
+    snprintf(intbuf, sizeof(intbuf), "%.0f", var_values[idvalue]);      \
+    write_text(pkt->data, name ":", modplug->linesize,  0+1, line+1);   \
+    write_text(pkt->data, intbuf,   modplug->linesize, 10+1, line+1);   \
+} while (0)
+
+static int modplug_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    ModPlugContext *modplug = s->priv_data;
+
+    if (modplug->video_stream) {
+        modplug->video_switch ^= 1; // one video packet for one audio packet
+        if (modplug->video_switch) {
+            double var_values[VAR_VARS_NB];
+
+            var_values[VAR_W      ] = modplug->w;
+            var_values[VAR_H      ] = modplug->h;
+            var_values[VAR_TIME   ] = modplug->packet_count * modplug->ts_per_packet;
+            var_values[VAR_SPEED  ] = ModPlug_GetCurrentSpeed  (modplug->f);
+            var_values[VAR_TEMPO  ] = ModPlug_GetCurrentTempo  (modplug->f);
+            var_values[VAR_ORDER  ] = ModPlug_GetCurrentOrder  (modplug->f);
+            var_values[VAR_PATTERN] = ModPlug_GetCurrentPattern(modplug->f);
+            var_values[VAR_ROW    ] = ModPlug_GetCurrentRow    (modplug->f);
+
+            if (av_new_packet(pkt, modplug->fsize) < 0)
+                return AVERROR(ENOMEM);
+            pkt->stream_index = 1;
+            memset(pkt->data, 0, modplug->fsize);
+
+            if (modplug->print_textinfo) {
+                char intbuf[32];
+                PRINT_INFO(0, "speed",   VAR_SPEED);
+                PRINT_INFO(1, "tempo",   VAR_TEMPO);
+                PRINT_INFO(2, "order",   VAR_ORDER);
+                PRINT_INFO(3, "pattern", VAR_PATTERN);
+                PRINT_INFO(4, "row",     VAR_ROW);
+                PRINT_INFO(5, "ts",      VAR_TIME);
+            }
+
+            if (modplug->expr) {
+                int x, y;
+                for (y = 0; y < modplug->h; y++) {
+                    for (x = 0; x < modplug->w; x++) {
+                        double color;
+                        var_values[VAR_X] = x;
+                        var_values[VAR_Y] = y;
+                        color = av_expr_eval(modplug->expr, var_values, NULL);
+                        pkt->data[y*modplug->linesize + x*3 + 2] |= av_clip((int)color, 0, 0xf)<<4;
+                    }
+                }
+            }
+            pkt->pts = pkt->dts = var_values[VAR_TIME];
+            pkt->flags |= AV_PKT_FLAG_KEY;
+            return 0;
+        }
+    }
+
+    if (av_new_packet(pkt, AUDIO_PKT_SIZE) < 0)
+        return AVERROR(ENOMEM);
+
+    if (modplug->video_stream)
+        pkt->pts = pkt->dts = modplug->packet_count++ * modplug->ts_per_packet;
+
+    pkt->size = ModPlug_Read(modplug->f, pkt->data, AUDIO_PKT_SIZE);
+    if (pkt->size <= 0) {
+        av_free_packet(pkt);
+        return pkt->size == 0 ? AVERROR_EOF : AVERROR(EIO);
+    }
+    return 0;
+}
+
+static int modplug_read_close(AVFormatContext *s)
+{
+    ModPlugContext *modplug = s->priv_data;
+    ModPlug_Unload(modplug->f);
+    av_freep(&modplug->buf);
+    return 0;
+}
+
+static int modplug_read_seek(AVFormatContext *s, int stream_idx, int64_t ts, int flags)
+{
+    ModPlugContext *modplug = s->priv_data;
+    ModPlug_Seek(modplug->f, (int)ts);
+    if (modplug->video_stream)
+        modplug->packet_count = ts / modplug->ts_per_packet;
+    return 0;
+}
+
+static const AVClass modplug_class = {
+    .class_name = "ModPlug demuxer",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_libmodplug_demuxer = {
+    .name           = "libmodplug",
+    .long_name      = NULL_IF_CONFIG_SMALL("ModPlug demuxer"),
+    .priv_data_size = sizeof(ModPlugContext),
+    .read_header    = modplug_read_header,
+    .read_packet    = modplug_read_packet,
+    .read_close     = modplug_read_close,
+    .read_seek      = modplug_read_seek,
+    .extensions     = "669,abc,amf,ams,dbm,dmf,dsm,far,it,mdl,med,mid,mod,mt2,mtm,okt,psm,ptm,s3m,stm,ult,umx,xm"
+                      ",itgz,itr,itz,mdgz,mdr,mdz,s3gz,s3r,s3z,xmgz,xmr,xmz", // compressed mods
+    .priv_class     = &modplug_class,
+};
diff --git a/libavformat/libnut.c b/libavformat/libnut.c
new file mode 100644
index 0000000..838c55a
--- /dev/null
+++ b/libavformat/libnut.c
@@ -0,0 +1,322 @@
+/*
+ * NUT (de)muxing via libnut
+ * copyright (c) 2006 Oded Shimon <ods15@ods15.dyndns.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
+ * NUT demuxing and muxing via libnut.
+ * @author Oded Shimon <ods15@ods15.dyndns.org>
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "riff.h"
+#include <libnut.h>
+
+#define ID_STRING "nut/multimedia container"
+#define ID_LENGTH (strlen(ID_STRING) + 1)
+
+typedef struct {
+    nut_context_tt * nut;
+    nut_stream_header_tt * s;
+} NUTContext;
+
+static const AVCodecTag nut_tags[] = {
+    { AV_CODEC_ID_MPEG4,  MKTAG('m', 'p', '4', 'v') },
+    { AV_CODEC_ID_MP3,    MKTAG('m', 'p', '3', ' ') },
+    { AV_CODEC_ID_VORBIS, MKTAG('v', 'r', 'b', 's') },
+    { 0, 0 },
+};
+
+#if CONFIG_LIBNUT_MUXER
+static int av_write(void * h, size_t len, const uint8_t * buf) {
+    AVIOContext * bc = h;
+    avio_write(bc, buf, len);
+    //avio_flush(bc);
+    return len;
+}
+
+static int nut_write_header(AVFormatContext * avf) {
+    NUTContext * priv = avf->priv_data;
+    AVIOContext * bc = avf->pb;
+    nut_muxer_opts_tt mopts = {
+        .output = {
+            .priv = bc,
+            .write = av_write,
+        },
+        .alloc = { av_malloc, av_realloc, av_free },
+        .write_index = 1,
+        .realtime_stream = 0,
+        .max_distance = 32768,
+        .fti = NULL,
+    };
+    nut_stream_header_tt * s;
+    int i;
+
+    priv->s = s = av_mallocz((avf->nb_streams + 1) * sizeof*s);
+    if(!s)
+        return AVERROR(ENOMEM);
+
+    for (i = 0; i < avf->nb_streams; i++) {
+        AVCodecContext * codec = avf->streams[i]->codec;
+        int j;
+        int fourcc = 0;
+        int num, denom, ssize;
+
+        s[i].type = codec->codec_type == AVMEDIA_TYPE_VIDEO ? NUT_VIDEO_CLASS : NUT_AUDIO_CLASS;
+
+        if (codec->codec_tag) fourcc = codec->codec_tag;
+        else fourcc = ff_codec_get_tag(nut_tags, codec->codec_id);
+
+        if (!fourcc) {
+            if (codec->codec_type == AVMEDIA_TYPE_VIDEO) fourcc = ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id);
+            if (codec->codec_type == AVMEDIA_TYPE_AUDIO) fourcc = ff_codec_get_tag(ff_codec_wav_tags, codec->codec_id);
+        }
+
+        s[i].fourcc_len = 4;
+        s[i].fourcc = av_malloc(s[i].fourcc_len);
+        for (j = 0; j < s[i].fourcc_len; j++) s[i].fourcc[j] = (fourcc >> (j*8)) & 0xFF;
+
+        ff_parse_specific_params(codec, &num, &ssize, &denom);
+        avpriv_set_pts_info(avf->streams[i], 60, denom, num);
+
+        s[i].time_base.num = denom;
+        s[i].time_base.den = num;
+
+        s[i].fixed_fps = 0;
+        s[i].decode_delay = codec->has_b_frames;
+        s[i].codec_specific_len = codec->extradata_size;
+        s[i].codec_specific = codec->extradata;
+
+        if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+            s[i].width = codec->width;
+            s[i].height = codec->height;
+            s[i].sample_width = 0;
+            s[i].sample_height = 0;
+            s[i].colorspace_type = 0;
+        } else {
+            s[i].samplerate_num = codec->sample_rate;
+            s[i].samplerate_denom = 1;
+            s[i].channel_count = codec->channels;
+        }
+    }
+
+    s[avf->nb_streams].type = -1;
+    priv->nut = nut_muxer_init(&mopts, s, NULL);
+
+    return 0;
+}
+
+static int nut_write_packet(AVFormatContext * avf, AVPacket * pkt) {
+    NUTContext * priv = avf->priv_data;
+    nut_packet_tt p;
+
+    p.len = pkt->size;
+    p.stream = pkt->stream_index;
+    p.pts = pkt->pts;
+    p.flags = pkt->flags & AV_PKT_FLAG_KEY ? NUT_FLAG_KEY : 0;
+    p.next_pts = 0;
+
+    nut_write_frame_reorder(priv->nut, &p, pkt->data);
+
+    return 0;
+}
+
+static int nut_write_trailer(AVFormatContext * avf) {
+    AVIOContext * bc = avf->pb;
+    NUTContext * priv = avf->priv_data;
+    int i;
+
+    nut_muxer_uninit_reorder(priv->nut);
+    avio_flush(bc);
+
+    for(i = 0; priv->s[i].type != -1; i++ ) av_freep(&priv->s[i].fourcc);
+    av_freep(&priv->s);
+
+    return 0;
+}
+
+AVOutputFormat ff_libnut_muxer = {
+    .name              = "libnut",
+    .long_name         = "nut format",
+    .mime_type         = "video/x-nut",
+    .extensions        = "nut",
+    .priv_data_size    = sizeof(NUTContext),
+    .audio_codec       = AV_CODEC_ID_VORBIS,
+    .video_codec       = AV_CODEC_ID_MPEG4,
+    .write_header      = nut_write_header,
+    .write_packet      = nut_write_packet,
+    .write_trailer     = nut_write_trailer,
+    .flags             = AVFMT_GLOBALHEADER,
+};
+#endif /* CONFIG_LIBNUT_MUXER */
+
+static int nut_probe(AVProbeData *p) {
+    if (!memcmp(p->buf, ID_STRING, ID_LENGTH)) return AVPROBE_SCORE_MAX;
+
+    return 0;
+}
+
+static size_t av_read(void * h, size_t len, uint8_t * buf) {
+    AVIOContext * bc = h;
+    return avio_read(bc, buf, len);
+}
+
+static off_t av_seek(void * h, long long pos, int whence) {
+    AVIOContext * bc = h;
+    if (whence == SEEK_END) {
+        pos = avio_size(bc) + pos;
+        whence = SEEK_SET;
+    }
+    return avio_seek(bc, pos, whence);
+}
+
+static int nut_read_header(AVFormatContext * avf) {
+    NUTContext * priv = avf->priv_data;
+    AVIOContext * bc = avf->pb;
+    nut_demuxer_opts_tt dopts = {
+        .input = {
+            .priv = bc,
+            .seek = av_seek,
+            .read = av_read,
+            .eof = NULL,
+            .file_pos = 0,
+        },
+        .alloc = { av_malloc, av_realloc, av_free },
+        .read_index = 1,
+        .cache_syncpoints = 1,
+    };
+    nut_context_tt * nut = priv->nut = nut_demuxer_init(&dopts);
+    nut_stream_header_tt * s;
+    int ret, i;
+
+    if(!nut)
+        return -1;
+
+    if ((ret = nut_read_headers(nut, &s, NULL))) {
+        av_log(avf, AV_LOG_ERROR, " NUT error: %s\n", nut_error(ret));
+        nut_demuxer_uninit(nut);
+        priv->nut = NULL;
+        return -1;
+    }
+
+    priv->s = s;
+
+    for (i = 0; s[i].type != -1 && i < 2; i++) {
+        AVStream * st = avformat_new_stream(avf, NULL);
+        int j;
+
+        for (j = 0; j < s[i].fourcc_len && j < 8; j++) st->codec->codec_tag |= s[i].fourcc[j]<<(j*8);
+
+        st->codec->has_b_frames = s[i].decode_delay;
+
+        st->codec->extradata_size = s[i].codec_specific_len;
+        if (st->codec->extradata_size) {
+            st->codec->extradata = av_mallocz(st->codec->extradata_size);
+            if(!st->codec->extradata){
+                nut_demuxer_uninit(nut);
+                priv->nut = NULL;
+                return AVERROR(ENOMEM);
+            }
+            memcpy(st->codec->extradata, s[i].codec_specific, st->codec->extradata_size);
+        }
+
+        avpriv_set_pts_info(avf->streams[i], 60, s[i].time_base.num, s[i].time_base.den);
+        st->start_time = 0;
+        st->duration = s[i].max_pts;
+
+        st->codec->codec_id = ff_codec_get_id(nut_tags, st->codec->codec_tag);
+
+        switch(s[i].type) {
+        case NUT_AUDIO_CLASS:
+            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+            if (st->codec->codec_id == AV_CODEC_ID_NONE) st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, st->codec->codec_tag);
+
+            st->codec->channels = s[i].channel_count;
+            st->codec->sample_rate = s[i].samplerate_num / s[i].samplerate_denom;
+            break;
+        case NUT_VIDEO_CLASS:
+            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+            if (st->codec->codec_id == AV_CODEC_ID_NONE) st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, st->codec->codec_tag);
+
+            st->codec->width = s[i].width;
+            st->codec->height = s[i].height;
+            st->sample_aspect_ratio.num = s[i].sample_width;
+            st->sample_aspect_ratio.den = s[i].sample_height;
+            break;
+        }
+        if (st->codec->codec_id == AV_CODEC_ID_NONE) av_log(avf, AV_LOG_ERROR, "Unknown codec?!\n");
+    }
+
+    return 0;
+}
+
+static int nut_read_packet(AVFormatContext * avf, AVPacket * pkt) {
+    NUTContext * priv = avf->priv_data;
+    nut_packet_tt pd;
+    int ret;
+
+    ret = nut_read_next_packet(priv->nut, &pd);
+
+    if (ret || av_new_packet(pkt, pd.len) < 0) {
+        if (ret != NUT_ERR_EOF)
+            av_log(avf, AV_LOG_ERROR, " NUT error: %s\n", nut_error(ret));
+        return -1;
+    }
+
+    if (pd.flags & NUT_FLAG_KEY) pkt->flags |= AV_PKT_FLAG_KEY;
+    pkt->pts = pd.pts;
+    pkt->stream_index = pd.stream;
+    pkt->pos = avio_tell(avf->pb);
+
+    ret = nut_read_frame(priv->nut, &pd.len, pkt->data);
+
+    return ret;
+}
+
+static int nut_read_seek(AVFormatContext * avf, int stream_index, int64_t target_ts, int flags) {
+    NUTContext * priv = avf->priv_data;
+    int active_streams[] = { stream_index, -1 };
+    double time_pos = target_ts * priv->s[stream_index].time_base.num / (double)priv->s[stream_index].time_base.den;
+
+    if (nut_seek(priv->nut, time_pos, 2*!(flags & AVSEEK_FLAG_BACKWARD), active_streams)) return -1;
+
+    return 0;
+}
+
+static int nut_read_close(AVFormatContext *s) {
+    NUTContext * priv = s->priv_data;
+
+    nut_demuxer_uninit(priv->nut);
+
+    return 0;
+}
+
+AVInputFormat ff_libnut_demuxer = {
+    .name           = "libnut",
+    .long_name      = NULL_IF_CONFIG_SMALL("NUT format"),
+    .priv_data_size = sizeof(NUTContext),
+    .read_probe     = nut_probe,
+    .read_header    = nut_read_header,
+    .read_packet    = nut_read_packet,
+    .read_close     = nut_read_close,
+    .read_seek      = nut_read_seek,
+    .extensions     = "nut",
+};
diff --git a/libavformat/librtmp.c b/libavformat/librtmp.c
index 7133bd6..5b4c39d 100644
--- a/libavformat/librtmp.c
+++ b/libavformat/librtmp.c
@@ -2,20 +2,20 @@
  * RTMP network protocol
  * Copyright (c) 2010 Howard Chu
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/lmlm4.c b/libavformat/lmlm4.c
index b67b68e..c3eec02 100644
--- a/libavformat/lmlm4.c
+++ b/libavformat/lmlm4.c
@@ -5,20 +5,20 @@
  * Due to a lack of sample files, only files with one channel are supported.
  * u-law and ADPCM audio are unsupported for the same reason.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/loasdec.c b/libavformat/loasdec.c
new file mode 100644
index 0000000..ccb9464
--- /dev/null
+++ b/libavformat/loasdec.c
@@ -0,0 +1,88 @@
+/*
+ * LOAS AudioSyncStream demuxer
+ * Copyright (c) 2008 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/intreadwrite.h"
+#include "libavutil/internal.h"
+#include "avformat.h"
+#include "internal.h"
+#include "rawdec.h"
+
+static int loas_probe(AVProbeData *p)
+{
+    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;
+    buf = buf0;
+
+    for(; buf < end; buf= buf2+1) {
+        buf2 = buf;
+
+        for(frames = 0; buf2 < end; frames++) {
+            uint32_t header = AV_RB24(buf2);
+            if((header >> 13) != 0x2B7)
+                break;
+            fsize = (header & 0x1FFF) + 3;
+            if(fsize < 7)
+                break;
+            fsize = FFMIN(fsize, end - buf2);
+            buf2 += fsize;
+        }
+        max_frames = FFMAX(max_frames, frames);
+        if(buf == buf0)
+            first_frames= frames;
+    }
+    if   (first_frames>=3) return AVPROBE_SCORE_MAX/2+1;
+    else if(max_frames>100)return AVPROBE_SCORE_MAX/2;
+    else if(max_frames>=3) return AVPROBE_SCORE_MAX/4;
+    else if(max_frames>=1) return 1;
+    else                   return 0;
+}
+
+static int loas_read_header(AVFormatContext *s)
+{
+    AVStream *st;
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id = s->iformat->raw_codec_id;
+    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+
+    //LCM of all possible AAC sample rates
+    avpriv_set_pts_info(st, 64, 1, 28224000);
+
+    return 0;
+}
+
+AVInputFormat ff_loas_demuxer = {
+    .name           = "loas",
+    .long_name      = NULL_IF_CONFIG_SMALL("LOAS AudioSyncStream"),
+    .read_probe     = loas_probe,
+    .read_header    = loas_read_header,
+    .read_packet    = ff_raw_read_partial_packet,
+    .flags= AVFMT_GENERIC_INDEX,
+    .raw_codec_id = AV_CODEC_ID_AAC_LATM,
+};
diff --git a/libavformat/lxfdec.c b/libavformat/lxfdec.c
index e0eb935..bf17d87 100644
--- a/libavformat/lxfdec.c
+++ b/libavformat/lxfdec.c
@@ -2,29 +2,30 @@
  * LXF demuxer
  * Copyright (c) 2010 Tomas Härdin
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/intreadwrite.h"
+#include "libavcodec/bytestream.h"
 #include "avformat.h"
 #include "internal.h"
 #include "riff.h"
 
-#define LXF_PACKET_HEADER_SIZE  60
+#define LXF_MAX_PACKET_HEADER_SIZE 256
 #define LXF_HEADER_DATA_SIZE    120
 #define LXF_IDENT               "LEITCH\0"
 #define LXF_IDENT_LENGTH        8
@@ -49,6 +50,7 @@
     int channels;                       ///< number of audio channels. zero means no audio
     uint8_t temp[LXF_MAX_AUDIO_PACKET]; ///< temp buffer for de-planarizing the audio data
     int frame_number;                   ///< current video frame
+    uint32_t video_format, packet_type, extended_size;
 } LXFDemuxContext;
 
 static int lxf_probe(AVProbeData *p)
@@ -65,12 +67,12 @@
  * @param[in] header the packet header to check
  * @return zero if the checksum is OK, non-zero otherwise
  */
-static int check_checksum(const uint8_t *header)
+static int check_checksum(const uint8_t *header, int size)
 {
     int x;
     uint32_t sum = 0;
 
-    for (x = 0; x < LXF_PACKET_HEADER_SIZE; x += 4)
+    for (x = 0; x < size; x += 4)
         sum += AV_RL32(&header[x]);
 
     return sum;
@@ -91,7 +93,7 @@
         return ret < 0 ? ret : AVERROR_EOF;
 
     while (memcmp(buf, LXF_IDENT, LXF_IDENT_LENGTH)) {
-        if (s->pb->eof_reached)
+        if (url_feof(s->pb))
             return AVERROR_EOF;
 
         memmove(buf, &buf[1], LXF_IDENT_LENGTH-1);
@@ -106,40 +108,60 @@
 /**
  * Read and checksum the next packet header
  *
- * @param[out] header the read packet header
- * @param[out] format context dependent format information
  * @return the size of the payload following the header or < 0 on failure
  */
-static int get_packet_header(AVFormatContext *s, uint8_t *header, uint32_t *format)
+static int get_packet_header(AVFormatContext *s)
 {
+    LXFDemuxContext *lxf = s->priv_data;
     AVIOContext   *pb  = s->pb;
     int track_size, samples, ret;
+    uint32_t version, audio_format, header_size, channels, tmp;
     AVStream *st;
+    uint8_t header[LXF_MAX_PACKET_HEADER_SIZE];
+    const uint8_t *p;
 
     //find and read the ident
     if ((ret = sync(s, header)) < 0)
         return ret;
 
+    ret = avio_read(pb, header + LXF_IDENT_LENGTH, 8);
+    if (ret != 8)
+        return ret < 0 ? ret : AVERROR_EOF;
+
+    p = header + LXF_IDENT_LENGTH;
+    version     = bytestream_get_le32(&p);
+    header_size = bytestream_get_le32(&p);
+    if (version > 1)
+        av_log_ask_for_sample(s, "Unknown format version %i\n", version);
+    if (header_size < (version ? 72 : 60) ||
+        header_size > LXF_MAX_PACKET_HEADER_SIZE ||
+        (header_size & 3)) {
+        av_log(s, AV_LOG_ERROR, "Invalid header size 0x%x\n", header_size);
+        return AVERROR_INVALIDDATA;
+    }
+
     //read the rest of the packet header
-    if ((ret = avio_read(pb, header + LXF_IDENT_LENGTH,
-                          LXF_PACKET_HEADER_SIZE - LXF_IDENT_LENGTH)) !=
-                          LXF_PACKET_HEADER_SIZE - LXF_IDENT_LENGTH) {
+    if ((ret = avio_read(pb, header + (p - header),
+                          header_size - (p - header))) !=
+                          header_size - (p - header)) {
         return ret < 0 ? ret : AVERROR_EOF;
     }
 
-    if (check_checksum(header))
+    if (check_checksum(header, header_size))
         av_log(s, AV_LOG_ERROR, "checksum error\n");
 
-    *format = AV_RL32(&header[32]);
-    ret     = AV_RL32(&header[36]);
+    lxf->packet_type = bytestream_get_le32(&p);
+    p += version ? 20 : 12;
 
-    //type
-    switch (AV_RL32(&header[16])) {
+    lxf->extended_size = 0;
+    switch (lxf->packet_type) {
     case 0:
         //video
+        lxf->video_format = bytestream_get_le32(&p);
+        ret               = bytestream_get_le32(&p);
         //skip VBI data and metadata
-        avio_skip(pb, (int64_t)(uint32_t)AV_RL32(&header[44]) +
-                      (int64_t)(uint32_t)AV_RL32(&header[52]));
+        avio_skip(pb, (int64_t)(uint32_t)AV_RL32(p + 4) +
+                      (int64_t)(uint32_t)AV_RL32(p + 12));
         break;
     case 1:
         //audio
@@ -148,12 +170,16 @@
             break;
         }
 
+        if (version == 0) p += 8;
+        audio_format = bytestream_get_le32(&p);
+        channels     = bytestream_get_le32(&p);
+        track_size   = bytestream_get_le32(&p);
+
         //set codec based on specified audio bitdepth
         //we only support tightly packed 16-, 20-, 24- and 32-bit PCM at the moment
-        *format                          = AV_RL32(&header[40]);
-        st->codec->bits_per_coded_sample = (*format >> 6) & 0x3F;
+        st->codec->bits_per_coded_sample = (audio_format >> 6) & 0x3F;
 
-        if (st->codec->bits_per_coded_sample != (*format & 0x3F)) {
+        if (st->codec->bits_per_coded_sample != (audio_format & 0x3F)) {
             av_log(s, AV_LOG_WARNING, "only tightly packed PCM currently supported\n");
             return AVERROR_PATCHWELCOME;
         }
@@ -169,7 +195,6 @@
             return AVERROR_PATCHWELCOME;
         }
 
-        track_size = AV_RL32(&header[48]);
         samples = track_size * 8 / st->codec->bits_per_coded_sample;
 
         //use audio packet size to determine video standard
@@ -186,10 +211,14 @@
         }
 
         //TODO: warning if track mask != (1 << channels) - 1?
-        ret = av_popcount(AV_RL32(&header[44])) * track_size;
+        ret = av_popcount(channels) * track_size;
 
         break;
     default:
+        tmp = bytestream_get_le32(&p);
+        ret = bytestream_get_le32(&p);
+        if (tmp == 1)
+            lxf->extended_size = bytestream_get_le32(&p);
         break;
     }
 
@@ -200,13 +229,13 @@
 {
     LXFDemuxContext *lxf = s->priv_data;
     AVIOContext   *pb  = s->pb;
-    uint8_t header[LXF_PACKET_HEADER_SIZE], header_data[LXF_HEADER_DATA_SIZE];
+    uint8_t header_data[LXF_HEADER_DATA_SIZE];
     int ret;
     AVStream *st;
-    uint32_t format, video_params, disk_params;
+    uint32_t video_params, disk_params;
     uint16_t record_date, expiration_date;
 
-    if ((ret = get_packet_header(s, header, &format)) < 0)
+    if ((ret = get_packet_header(s)) < 0)
         return ret;
 
     if (ret != LXF_HEADER_DATA_SIZE) {
@@ -243,7 +272,7 @@
     if ((video_params >> 22) & 1)
         av_log(s, AV_LOG_WARNING, "VBI data not yet supported\n");
 
-    if ((lxf->channels = (disk_params >> 2) & 0xF)) {
+    if ((lxf->channels = 1 << (disk_params >> 4 & 3) + 1)) {
         if (!(st = avformat_new_stream(s, NULL)))
             return AVERROR(ENOMEM);
 
@@ -254,10 +283,7 @@
         avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
     }
 
-    if (format == 1) {
-        //skip extended field data
-        avio_skip(s->pb, (uint32_t)AV_RL32(&header[40]));
-    }
+    avio_skip(s->pb, lxf->extended_size);
 
     return 0;
 }
@@ -283,15 +309,15 @@
 {
     LXFDemuxContext *lxf = s->priv_data;
     AVIOContext   *pb  = s->pb;
-    uint8_t header[LXF_PACKET_HEADER_SIZE], *buf;
+    uint8_t *buf;
     AVStream *ast = NULL;
-    uint32_t stream, format;
+    uint32_t stream;
     int ret, ret2;
 
-    if ((ret = get_packet_header(s, header, &format)) < 0)
+    if ((ret = get_packet_header(s)) < 0)
         return ret;
 
-    stream = AV_RL32(&header[16]);
+    stream = lxf->packet_type;
 
     if (stream > 1) {
         av_log(s, AV_LOG_WARNING, "got packet with illegal stream index %u\n", stream);
@@ -328,7 +354,7 @@
             deplanarize(lxf, ast, pkt->data, ret);
     } else {
         //picture type (0 = closed I, 1 = open I, 2 = P, 3 = B)
-        if (((format >> 22) & 0x3) < 2)
+        if (((lxf->video_format >> 22) & 0x3) < 2)
             pkt->flags |= AV_PKT_FLAG_KEY;
 
         pkt->dts = lxf->frame_number++;
diff --git a/libavformat/m4vdec.c b/libavformat/m4vdec.c
index 4bee058..e72fb42 100644
--- a/libavformat/m4vdec.c
+++ b/libavformat/m4vdec.c
@@ -2,20 +2,20 @@
  * RAW MPEG-4 video demuxer
  * Copyright (c) 2006  Thijs Vermeir <thijs.vermeir@barco.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -45,7 +45,7 @@
     }
 
     if (VOP >= VISO && VOP >= VOL && VO >= VOL && VOL > 0 && res==0)
-        return AVPROBE_SCORE_MAX/2;
+        return VOP+VO > 3 ? AVPROBE_SCORE_MAX/2 : AVPROBE_SCORE_MAX/4;
     return 0;
 }
 
diff --git a/libavformat/matroska.c b/libavformat/matroska.c
index edb7ab7..64d0a45 100644
--- a/libavformat/matroska.c
+++ b/libavformat/matroska.c
@@ -2,20 +2,20 @@
  * Matroska common data
  * Copyright (c) 2003-2004 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -32,6 +32,7 @@
     {"A_MPEG/L2"        , AV_CODEC_ID_MP2},
     {"A_MPEG/L1"        , AV_CODEC_ID_MP2},
     {"A_MPEG/L3"        , AV_CODEC_ID_MP3},
+    {"A_OPUS",            AV_CODEC_ID_OPUS},
     {"A_PCM/FLOAT/IEEE" , AV_CODEC_ID_PCM_F32LE},
     {"A_PCM/FLOAT/IEEE" , AV_CODEC_ID_PCM_F64LE},
     {"A_PCM/INT/BIG"    , AV_CODEC_ID_PCM_S16BE},
@@ -52,6 +53,7 @@
     {"A_VORBIS"         , AV_CODEC_ID_VORBIS},
     {"A_WAVPACK4"       , AV_CODEC_ID_WAVPACK},
 
+    {"S_TEXT/UTF8"      , AV_CODEC_ID_SUBRIP},
     {"S_TEXT/UTF8"      , AV_CODEC_ID_TEXT},
     {"S_TEXT/UTF8"      , AV_CODEC_ID_SRT},
     {"S_TEXT/ASCII"     , AV_CODEC_ID_TEXT},
@@ -92,6 +94,7 @@
     {"image/tiff"                 , AV_CODEC_ID_TIFF},
     {"application/x-truetype-font", AV_CODEC_ID_TTF},
     {"application/x-font"         , AV_CODEC_ID_TTF},
+    {"application/vnd.ms-opentype", AV_CODEC_ID_OTF},
 
     {""                           , AV_CODEC_ID_NONE}
 };
@@ -101,3 +104,27 @@
     { "PART_NUMBER"   , "track"  },
     { 0 }
 };
+
+const char * const ff_matroska_video_stereo_mode[MATROSKA_VIDEO_STEREO_MODE_COUNT] = {
+    "mono",
+    "left_right",
+    "bottom_top",
+    "top_bottom",
+    "checkerboard_rl",
+    "checkerboard_lr"
+    "row_interleaved_rl",
+    "row_interleaved_lr",
+    "col_interleaved_rl",
+    "col_interleaved_lr",
+    "anaglyph_cyan_red",
+    "right_left",
+    "anaglyph_green_magenta",
+    "block_lr",
+    "block_rl",
+};
+
+const char * const ff_matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_PLANE_COUNT] = {
+    "left",
+    "right",
+    "background",
+};
diff --git a/libavformat/matroska.h b/libavformat/matroska.h
index b1f7ae4..8411633 100644
--- a/libavformat/matroska.h
+++ b/libavformat/matroska.h
@@ -2,20 +2,20 @@
  * Matroska constants
  * Copyright (c) 2003-2004 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -78,8 +78,13 @@
 #define MATROSKA_ID_TRACKNUMBER 0xD7
 #define MATROSKA_ID_TRACKUID   0x73C5
 #define MATROSKA_ID_TRACKTYPE  0x83
-#define MATROSKA_ID_TRACKAUDIO 0xE1
-#define MATROSKA_ID_TRACKVIDEO 0xE0
+#define MATROSKA_ID_TRACKVIDEO     0xE0
+#define MATROSKA_ID_TRACKAUDIO     0xE1
+#define MATROSKA_ID_TRACKOPERATION 0xE2
+#define MATROSKA_ID_TRACKCOMBINEPLANES 0xE3
+#define MATROSKA_ID_TRACKPLANE         0xE4
+#define MATROSKA_ID_TRACKPLANEUID      0xE5
+#define MATROSKA_ID_TRACKPLANETYPE     0xE6
 #define MATROSKA_ID_CODECID    0x86
 #define MATROSKA_ID_CODECPRIVATE 0x63A2
 #define MATROSKA_ID_CODECNAME  0x258688
@@ -249,8 +254,13 @@
 /* max. depth in the EBML tree structure */
 #define EBML_MAX_DEPTH 16
 
+#define MATROSKA_VIDEO_STEREO_MODE_COUNT  15
+#define MATROSKA_VIDEO_STEREO_PLANE_COUNT  3
+
 extern const CodecTags ff_mkv_codec_tags[];
 extern const CodecMime ff_mkv_mime_tags[];
 extern const AVMetadataConv ff_mkv_metadata_conv[];
+extern const char * const ff_matroska_video_stereo_mode[MATROSKA_VIDEO_STEREO_MODE_COUNT];
+extern const char * const ff_matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_PLANE_COUNT];
 
 #endif /* AVFORMAT_MATROSKA_H */
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 094b055..a270f0d 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -1,21 +1,21 @@
 /*
  * Matroska file demuxer
- * Copyright (c) 2003-2008 The Libav Project
+ * Copyright (c) 2003-2008 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -113,7 +113,8 @@
     uint64_t display_height;
     uint64_t pixel_width;
     uint64_t pixel_height;
-    uint64_t fourcc;
+    EbmlBin color_space;
+    uint64_t stereo_mode;
 } MatroskaTrackVideo;
 
 typedef struct {
@@ -134,6 +135,15 @@
 } MatroskaTrackAudio;
 
 typedef struct {
+    uint64_t uid;
+    uint64_t type;
+} MatroskaTrackPlane;
+
+typedef struct {
+    EbmlList combine_planes;
+} MatroskaTrackOperation;
+
+typedef struct {
     uint64_t num;
     uint64_t uid;
     uint64_t type;
@@ -147,6 +157,7 @@
     uint64_t flag_forced;
     MatroskaTrackVideo video;
     MatroskaTrackAudio audio;
+    MatroskaTrackOperation operation;
     EbmlList encodings;
 
     AVStream *stream;
@@ -230,6 +241,7 @@
     uint64_t time_scale;
     double   duration;
     char    *title;
+    EbmlBin date_utc;
     EbmlList tracks;
     EbmlList attachments;
     EbmlList chapters;
@@ -291,7 +303,7 @@
     { MATROSKA_ID_TITLE,              EBML_UTF8,  0, offsetof(MatroskaDemuxContext,title) },
     { MATROSKA_ID_WRITINGAPP,         EBML_NONE },
     { MATROSKA_ID_MUXINGAPP,          EBML_NONE },
-    { MATROSKA_ID_DATEUTC,            EBML_NONE },
+    { MATROSKA_ID_DATEUTC,            EBML_BIN,  0, offsetof(MatroskaDemuxContext,date_utc) },
     { MATROSKA_ID_SEGMENTUID,         EBML_NONE },
     { 0 }
 };
@@ -302,14 +314,14 @@
     { MATROSKA_ID_VIDEODISPLAYHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo,display_height) },
     { MATROSKA_ID_VIDEOPIXELWIDTH,    EBML_UINT, 0, offsetof(MatroskaTrackVideo,pixel_width) },
     { MATROSKA_ID_VIDEOPIXELHEIGHT,   EBML_UINT, 0, offsetof(MatroskaTrackVideo,pixel_height) },
-    { MATROSKA_ID_VIDEOCOLORSPACE,    EBML_UINT, 0, offsetof(MatroskaTrackVideo,fourcc) },
+    { MATROSKA_ID_VIDEOCOLORSPACE,    EBML_BIN,  0, offsetof(MatroskaTrackVideo,color_space) },
+    { MATROSKA_ID_VIDEOSTEREOMODE,    EBML_UINT, 0, offsetof(MatroskaTrackVideo,stereo_mode) },
     { MATROSKA_ID_VIDEOPIXELCROPB,    EBML_NONE },
     { MATROSKA_ID_VIDEOPIXELCROPT,    EBML_NONE },
     { MATROSKA_ID_VIDEOPIXELCROPL,    EBML_NONE },
     { MATROSKA_ID_VIDEOPIXELCROPR,    EBML_NONE },
     { MATROSKA_ID_VIDEODISPLAYUNIT,   EBML_NONE },
     { MATROSKA_ID_VIDEOFLAGINTERLACED,EBML_NONE },
-    { MATROSKA_ID_VIDEOSTEREOMODE,    EBML_NONE },
     { MATROSKA_ID_VIDEOASPECTRATIO,   EBML_NONE },
     { 0 }
 };
@@ -341,6 +353,22 @@
     { 0 }
 };
 
+static EbmlSyntax matroska_track_plane[] = {
+    { MATROSKA_ID_TRACKPLANEUID,  EBML_UINT, 0, offsetof(MatroskaTrackPlane,uid) },
+    { MATROSKA_ID_TRACKPLANETYPE, EBML_UINT, 0, offsetof(MatroskaTrackPlane,type) },
+    { 0 }
+};
+
+static EbmlSyntax matroska_track_combine_planes[] = {
+    { MATROSKA_ID_TRACKPLANE, EBML_NEST, sizeof(MatroskaTrackPlane), offsetof(MatroskaTrackOperation,combine_planes), {.n=matroska_track_plane} },
+    { 0 }
+};
+
+static EbmlSyntax matroska_track_operation[] = {
+    { MATROSKA_ID_TRACKCOMBINEPLANES, EBML_NEST, 0, 0, {.n=matroska_track_combine_planes} },
+    { 0 }
+};
+
 static EbmlSyntax matroska_track[] = {
     { MATROSKA_ID_TRACKNUMBER,          EBML_UINT, 0, offsetof(MatroskaTrack,num) },
     { MATROSKA_ID_TRACKNAME,            EBML_UTF8, 0, offsetof(MatroskaTrack,name) },
@@ -355,6 +383,7 @@
     { MATROSKA_ID_TRACKFLAGFORCED,      EBML_UINT, 0, offsetof(MatroskaTrack,flag_forced), {.u=0} },
     { MATROSKA_ID_TRACKVIDEO,           EBML_NEST, 0, offsetof(MatroskaTrack,video), {.n=matroska_track_video} },
     { 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_TRACKFLAGENABLED,     EBML_NONE },
     { MATROSKA_ID_TRACKFLAGLACING,      EBML_NONE },
@@ -498,7 +527,7 @@
 static EbmlSyntax matroska_blockgroup[] = {
     { MATROSKA_ID_BLOCK,          EBML_BIN,  0, offsetof(MatroskaBlock,bin) },
     { MATROSKA_ID_SIMPLEBLOCK,    EBML_BIN,  0, offsetof(MatroskaBlock,bin) },
-    { MATROSKA_ID_BLOCKDURATION,  EBML_UINT, 0, offsetof(MatroskaBlock,duration), {.u=AV_NOPTS_VALUE} },
+    { MATROSKA_ID_BLOCKDURATION,  EBML_UINT, 0, offsetof(MatroskaBlock,duration) },
     { MATROSKA_ID_BLOCKREFERENCE, EBML_UINT, 0, offsetof(MatroskaBlock,reference) },
     { 1,                          EBML_UINT, 0, offsetof(MatroskaBlock,non_simple), {.u=1} },
     { 0 }
@@ -556,6 +585,36 @@
 
 static const char *const matroska_doctypes[] = { "matroska", "webm" };
 
+static int matroska_resync(MatroskaDemuxContext *matroska, int64_t last_pos)
+{
+    AVIOContext *pb = matroska->ctx->pb;
+    uint32_t id;
+    matroska->current_id = 0;
+    matroska->num_levels = 0;
+
+    // seek to next position to resync from
+    if (avio_seek(pb, last_pos + 1, SEEK_SET) < 0 || avio_tell(pb) <= last_pos)
+        goto eof;
+
+    id = avio_rb32(pb);
+
+    // try to find a toplevel element
+    while (!url_feof(pb)) {
+        if (id == MATROSKA_ID_INFO || id == MATROSKA_ID_TRACKS ||
+            id == MATROSKA_ID_CUES || id == MATROSKA_ID_TAGS ||
+            id == MATROSKA_ID_SEEKHEAD || id == MATROSKA_ID_ATTACHMENTS ||
+            id == MATROSKA_ID_CLUSTER || id == MATROSKA_ID_CHAPTERS)
+        {
+            matroska->current_id = id;
+            return 0;
+        }
+        id = (id << 8) | avio_r8(pb);
+    }
+eof:
+    matroska->done = 1;
+    return AVERROR_EOF;
+}
+
 /*
  * Return: Whether we reached the end of a level in the hierarchy or not.
  */
@@ -593,7 +652,7 @@
      * use it safely here to catch EOS. */
     if (!(total = avio_r8(pb))) {
         /* we might encounter EOS here */
-        if (!pb->eof_reached) {
+        if (!url_feof(pb)) {
             int64_t pos = avio_tell(pb);
             av_log(matroska->ctx, AV_LOG_ERROR,
                    "Read error at pos. %"PRIu64" (0x%"PRIx64")\n",
@@ -887,7 +946,10 @@
                      return ebml_parse_nest(matroska, syntax->def.n, data);
     case EBML_PASS:  return ebml_parse_id(matroska, syntax->def.n, id, data);
     case EBML_STOP:  return 1;
-    default:         return avio_skip(pb,length)<0 ? AVERROR(EIO) : 0;
+    default:
+        if(ffio_limit(pb, length) != length)
+            return AVERROR(EIO);
+        return avio_skip(pb,length)<0 ? AVERROR(EIO) : 0;
     }
     if (res == AVERROR_INVALIDDATA)
         av_log(matroska->ctx, AV_LOG_ERROR, "Invalid element\n");
@@ -991,7 +1053,7 @@
     int result = 0;
     int olen;
 
-    if (pkt_size >= 10000000)
+    if (pkt_size >= 10000000U)
         return AVERROR_INVALIDDATA;
 
     switch (encodings[0].compression.algo) {
@@ -999,6 +1061,11 @@
         int header_size = encodings[0].compression.settings.size;
         uint8_t *header = encodings[0].compression.settings.data;
 
+        if (header_size && !header) {
+            av_log(0, AV_LOG_ERROR, "Compression size but no data in headerstrip\n");
+            return -1;
+        }
+
         if (!header_size)
             return 0;
 
@@ -1045,7 +1112,10 @@
             pkt_data = newpktdata;
             zstream.avail_out = pkt_size - zstream.total_out;
             zstream.next_out = pkt_data + zstream.total_out;
-            result = inflate(&zstream, Z_NO_FLUSH);
+            if (pkt_data) {
+                result = inflate(&zstream, Z_NO_FLUSH);
+            } else
+                result = Z_MEM_ERROR;
         } while (result==Z_OK && pkt_size<10000000);
         pkt_size = zstream.total_out;
         inflateEnd(&zstream);
@@ -1076,7 +1146,10 @@
             pkt_data = newpktdata;
             bzstream.avail_out = pkt_size - bzstream.total_out_lo32;
             bzstream.next_out = pkt_data + bzstream.total_out_lo32;
-            result = BZ2_bzDecompress(&bzstream);
+            if (pkt_data) {
+                result = BZ2_bzDecompress(&bzstream);
+            } else
+                result = BZ_MEM_ERROR;
         } while (result==BZ_OK && pkt_size<10000000);
         pkt_size = bzstream.total_out_lo32;
         BZ2_bzDecompressEnd(&bzstream);
@@ -1108,7 +1181,8 @@
     char *line, *layer, *ptr = pkt->data, *end = ptr+pkt->size;
     for (; *ptr!=',' && ptr<end-1; ptr++);
     if (*ptr == ',')
-        layer = ++ptr;
+        ptr++;
+    layer = ptr;
     for (; *ptr!=',' && ptr<end-1; ptr++);
     if (*ptr == ',') {
         int64_t end_pts = pkt->pts + display_duration;
@@ -1135,12 +1209,10 @@
 
 static int matroska_merge_packets(AVPacket *out, AVPacket *in)
 {
-    void *newdata = av_realloc(out->data, out->size+in->size);
-    if (!newdata)
-        return AVERROR(ENOMEM);
-    out->data = newdata;
-    memcpy(out->data+out->size, in->data, in->size);
-    out->size += in->size;
+    int ret = av_grow_packet(out, in->size);
+    if (ret < 0)
+        return ret;
+    memcpy(out->data + out->size - in->size, in->data, in->size);
     av_destruct_packet(in);
     av_free(in);
     return 0;
@@ -1154,7 +1226,7 @@
     int i;
 
     for (i=0; i < list->nb_elem; i++) {
-        const char *lang = strcmp(tags[i].lang, "und") ? tags[i].lang : NULL;
+        const char *lang= (tags[i].lang && strcmp(tags[i].lang, "und")) ? tags[i].lang : NULL;
 
         if (!tags[i].name) {
             av_log(s, AV_LOG_WARNING, "Skipping invalid tag with no TagName.\n");
@@ -1285,26 +1357,20 @@
             continue;
         }
 
-        if (matroska_parse_seekhead_entry(matroska, i) < 0)
+        if (matroska_parse_seekhead_entry(matroska, i) < 0) {
+            // mark index as broken
+            matroska->cues_parsing_deferred = -1;
             break;
+        }
     }
 }
 
-static void matroska_parse_cues(MatroskaDemuxContext *matroska) {
-    EbmlList *seekhead_list = &matroska->seekhead;
-    MatroskaSeekhead *seekhead = seekhead_list->elem;
+static void matroska_add_index_entries(MatroskaDemuxContext *matroska) {
     EbmlList *index_list;
     MatroskaIndex *index;
     int index_scale = 1;
     int i, j;
 
-    for (i = 0; i < seekhead_list->nb_elem; i++)
-        if (seekhead[i].id == MATROSKA_ID_CUES)
-            break;
-    assert(i <= seekhead_list->nb_elem);
-
-    matroska_parse_seekhead_entry(matroska, i);
-
     index_list = &matroska->index;
     index = index_list->elem;
     if (index_list->nb_elem
@@ -1326,6 +1392,21 @@
     }
 }
 
+static void matroska_parse_cues(MatroskaDemuxContext *matroska) {
+    EbmlList *seekhead_list = &matroska->seekhead;
+    MatroskaSeekhead *seekhead = seekhead_list->elem;
+    int i;
+
+    for (i = 0; i < seekhead_list->nb_elem; i++)
+        if (seekhead[i].id == MATROSKA_ID_CUES)
+            break;
+    assert(i <= seekhead_list->nb_elem);
+
+    if (matroska_parse_seekhead_entry(matroska, i) < 0)
+       matroska->cues_parsing_deferred = -1;
+    matroska_add_index_entries(matroska);
+}
+
 static int matroska_aac_profile(char *codec_id)
 {
     static const char * const aac_profiles[] = { "MAIN", "LC", "SSR" };
@@ -1347,6 +1428,17 @@
     return sri;
 }
 
+static void matroska_metadata_creation_time(AVDictionary **metadata, int64_t date_utc)
+{
+    char buffer[32];
+    /* Convert to seconds and adjust by number of seconds between 2001-01-01 and Epoch */
+    time_t creation_time = date_utc / 1000000000 + 978307200;
+    struct tm *ptm = gmtime(&creation_time);
+    if (!ptm) return;
+    strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm);
+    av_dict_set(metadata, "creation_time", buffer, 0);
+}
+
 static int matroska_read_header(AVFormatContext *s)
 {
     MatroskaDemuxContext *matroska = s->priv_data;
@@ -1356,22 +1448,28 @@
     MatroskaChapter *chapters;
     MatroskaTrack *tracks;
     uint64_t max_start = 0;
+    int64_t pos;
     Ebml ebml = { 0 };
     AVStream *st;
-    int i, j, res;
+    int i, j, k, res;
 
     matroska->ctx = s;
 
     /* First read the EBML header. */
     if (ebml_parse(matroska, ebml_syntax, &ebml)
         || ebml.version > EBML_VERSION       || ebml.max_size > sizeof(uint64_t)
-        || ebml.id_length > sizeof(uint32_t) || ebml.doctype_version > 2) {
+        || ebml.id_length > sizeof(uint32_t) || ebml.doctype_version > 3 || !ebml.doctype) {
         av_log(matroska->ctx, AV_LOG_ERROR,
                "EBML header using unsupported features\n"
                "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n",
                ebml.version, ebml.doctype, ebml.doctype_version);
         ebml_free(ebml_syntax, &ebml);
         return AVERROR_PATCHWELCOME;
+    } else if (ebml.doctype_version == 3) {
+        av_log(matroska->ctx, AV_LOG_WARNING,
+               "EBML header using unsupported features\n"
+               "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n",
+               ebml.version, ebml.doctype, ebml.doctype_version);
     }
     for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++)
         if (!strcmp(ebml.doctype, matroska_doctypes[i]))
@@ -1386,8 +1484,16 @@
     ebml_free(ebml_syntax, &ebml);
 
     /* The next thing is a segment. */
-    if ((res = ebml_parse(matroska, matroska_segments, matroska)) < 0)
-        return res;
+    pos = avio_tell(matroska->ctx->pb);
+    res = ebml_parse(matroska, matroska_segments, matroska);
+    // try resyncing until we find a EBML_STOP type element.
+    while (res != 1) {
+        res = matroska_resync(matroska, pos);
+        if (res < 0)
+            return res;
+        pos = avio_tell(matroska->ctx->pb);
+        res = ebml_parse(matroska, matroska_segment, matroska);
+    }
     matroska_execute_seekhead(matroska);
 
     if (!matroska->time_scale)
@@ -1397,15 +1503,19 @@
                                   * 1000 / AV_TIME_BASE;
     av_dict_set(&s->metadata, "title", matroska->title, 0);
 
+    if (matroska->date_utc.size == 8)
+        matroska_metadata_creation_time(&s->metadata, AV_RB64(matroska->date_utc.data));
+
     tracks = matroska->tracks.elem;
     for (i=0; i < matroska->tracks.nb_elem; i++) {
         MatroskaTrack *track = &tracks[i];
         enum AVCodecID codec_id = AV_CODEC_ID_NONE;
-        EbmlList *encodings_list = &tracks->encodings;
+        EbmlList *encodings_list = &track->encodings;
         MatroskaTrackEncoding *encodings = encodings_list->elem;
         uint8_t *extradata = NULL;
         int extradata_size = 0;
         int extradata_offset = 0;
+        uint32_t fourcc = 0;
         AVIOContext b;
 
         /* Apply some sanity checks. */
@@ -1427,6 +1537,8 @@
                 track->video.display_width = track->video.pixel_width;
             if (!track->video.display_height)
                 track->video.display_height = track->video.pixel_height;
+            if (track->video.color_space.size == 4)
+                fourcc = AV_RL32(track->video.color_space.data);
         } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
             if (!track->audio.out_samplerate)
                 track->audio.out_samplerate = track->audio.samplerate;
@@ -1480,8 +1592,8 @@
             && track->codec_priv.size >= 40
             && track->codec_priv.data != NULL) {
             track->ms_compat = 1;
-            track->video.fourcc = AV_RL32(track->codec_priv.data + 16);
-            codec_id = ff_codec_get_id(ff_codec_bmp_tags, track->video.fourcc);
+            fourcc = AV_RL32(track->codec_priv.data + 16);
+            codec_id = ff_codec_get_id(ff_codec_bmp_tags, fourcc);
             extradata_offset = 40;
         } else if (!strcmp(track->codec_id, "A_MS/ACM")
                    && track->codec_priv.size >= 14
@@ -1497,8 +1609,20 @@
         } else if (!strcmp(track->codec_id, "V_QUICKTIME")
                    && (track->codec_priv.size >= 86)
                    && (track->codec_priv.data != NULL)) {
-            track->video.fourcc = AV_RL32(track->codec_priv.data);
-            codec_id=ff_codec_get_id(ff_codec_movvideo_tags, track->video.fourcc);
+            fourcc = AV_RL32(track->codec_priv.data);
+            codec_id = ff_codec_get_id(ff_codec_movvideo_tags, fourcc);
+        } else if (codec_id == AV_CODEC_ID_ALAC && track->codec_priv.size && track->codec_priv.size < INT_MAX-12) {
+            /* Only ALAC's magic cookie is stored in Matroska's track headers.
+               Create the "atom size", "tag", and "tag version" fields the
+               decoder expects manually. */
+            extradata_size = 12 + track->codec_priv.size;
+            extradata = av_mallocz(extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+            if (extradata == NULL)
+                return AVERROR(ENOMEM);
+            AV_WB32(extradata, extradata_size);
+            memcpy(&extradata[4], "alac", 4);
+            AV_WB32(&extradata[8], 0);
+            memcpy(&extradata[12], track->codec_priv.data, track->codec_priv.size);
         } else if (codec_id == AV_CODEC_ID_PCM_S16BE) {
             switch (track->audio.bitdepth) {
             case  8:  codec_id = AV_CODEC_ID_PCM_U8;     break;
@@ -1529,22 +1653,9 @@
                 extradata_size = 5;
             } else
                 extradata_size = 2;
-        } else if (codec_id == AV_CODEC_ID_ALAC && track->codec_priv.size) {
-            /* Only ALAC's magic cookie is stored in Matroska's track headers.
-               Create the "atom size", "tag", and "tag version" fields the
-               decoder expects manually. */
-            extradata_size = 12 + track->codec_priv.size;
-            extradata = av_mallocz(extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
-            if (extradata == NULL)
-                return AVERROR(ENOMEM);
-            AV_WB32(extradata, extradata_size);
-            memcpy(&extradata[4], "alac", 4);
-            AV_WB32(&extradata[8], 0);
-            memcpy(&extradata[12], track->codec_priv.data,
-                                   track->codec_priv.size);
         } else if (codec_id == AV_CODEC_ID_TTA) {
             extradata_size = 30;
-            extradata = av_mallocz(extradata_size);
+            extradata = av_mallocz(extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
             if (extradata == NULL)
                 return AVERROR(ENOMEM);
             ffio_init_context(&b, extradata, extradata_size, 1,
@@ -1561,9 +1672,11 @@
         } else if (codec_id == AV_CODEC_ID_RA_144) {
             track->audio.out_samplerate = 8000;
             track->audio.channels = 1;
-        } 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) {
+        } 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) {
             int flavor;
+
             ffio_init_context(&b, track->codec_priv.data,track->codec_priv.size,
                           0, NULL, NULL, NULL, NULL);
             avio_skip(&b, 22);
@@ -1625,8 +1738,10 @@
         }
 
         if (track->type == MATROSKA_TRACK_TYPE_VIDEO) {
+            MatroskaTrackPlane *planes = track->operation.combine_planes.elem;
+
             st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-            st->codec->codec_tag  = track->video.fourcc;
+            st->codec->codec_tag  = fourcc;
             st->codec->width  = track->video.pixel_width;
             st->codec->height = track->video.pixel_height;
             av_reduce(&st->sample_aspect_ratio.num,
@@ -1634,7 +1749,6 @@
                       st->codec->height * track->video.display_width,
                       st->codec-> width * track->video.display_height,
                       255);
-            if (st->codec->codec_id != AV_CODEC_ID_H264)
             st->need_parsing = AVSTREAM_PARSE_HEADERS;
             if (track->default_duration) {
                 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
@@ -1643,6 +1757,25 @@
                 st->r_frame_rate = st->avg_frame_rate;
 #endif
             }
+
+            /* export stereo mode flag as metadata tag */
+            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);
+
+            /* if we have virtual track, mark the real tracks */
+            for (j=0; j < track->operation.combine_planes.nb_elem; j++) {
+                char buf[32];
+                if (planes[j].type >= MATROSKA_VIDEO_STEREO_PLANE_COUNT)
+                    continue;
+                snprintf(buf, sizeof(buf), "%s_%d",
+                         ff_matroska_video_stereo_plane[planes[j].type], i);
+                for (k=0; k < matroska->tracks.nb_elem; k++)
+                    if (planes[j].uid == tracks[k].uid) {
+                        av_dict_set(&s->streams[k]->metadata,
+                                    "stereo_mode", buf, 0);
+                        break;
+                    }
+            }
         } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
             st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
             st->codec->sample_rate = track->audio.out_samplerate;
@@ -1669,7 +1802,7 @@
             av_dict_set(&st->metadata, "mimetype", attachements[j].mime, 0);
             st->codec->codec_id = AV_CODEC_ID_NONE;
             st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
-            st->codec->extradata  = av_malloc(attachements[j].bin.size);
+            st->codec->extradata  = av_malloc(attachements[j].bin.size + FF_INPUT_BUFFER_PADDING_SIZE);
             if(st->codec->extradata == NULL)
                 break;
             st->codec->extradata_size = attachements[j].bin.size;
@@ -1699,6 +1832,8 @@
             max_start = chapters[i].start;
         }
 
+    matroska_add_index_entries(matroska);
+
     matroska_convert_tags(s);
 
     return 0;
@@ -1767,7 +1902,7 @@
         return 0;
     }
 
-    assert(size > 0);
+    av_assert0(size > 0);
     *laces = *data + 1;
     data += 1;
     size -= 1;
@@ -1859,7 +1994,7 @@
                                    MatroskaTrack *track,
                                    AVStream *st,
                                    uint8_t *data, int size,
-                                   uint64_t timecode, uint64_t duration,
+                                   uint64_t timecode,
                                    int64_t pos)
 {
     int a = st->codec->block_align;
@@ -1925,7 +2060,7 @@
                                 MatroskaTrack *track,
                                 AVStream *st,
                                 uint8_t *data, int pkt_size,
-                                uint64_t timecode, uint64_t duration,
+                                uint64_t timecode, uint64_t lace_duration,
                                 int64_t pos, int is_keyframe)
 {
     MatroskaTrackEncoding *encodings = track->encodings.elem;
@@ -1968,13 +2103,32 @@
     else
         pkt->pts = timecode;
     pkt->pos = pos;
-    if (st->codec->codec_id == AV_CODEC_ID_TEXT)
-        pkt->convergence_duration = duration;
-    else if (track->type != MATROSKA_TRACK_TYPE_SUBTITLE)
-        pkt->duration = duration;
+    if (st->codec->codec_id == AV_CODEC_ID_SUBRIP) {
+        /*
+         * For backward compatibility.
+         * Historically, we have put subtitle duration
+         * in convergence_duration, on the off chance
+         * that the time_scale is less than 1us, which
+         * could result in a 32bit overflow on the
+         * normal duration field.
+         */
+        pkt->convergence_duration = lace_duration;
+    }
+
+    if (track->type != MATROSKA_TRACK_TYPE_SUBTITLE ||
+        lace_duration <= INT_MAX) {
+        /*
+         * For non subtitle tracks, just store the duration
+         * as normal.
+         *
+         * If it's a subtitle track and duration value does
+         * not overflow a uint32, then also store it normally.
+         */
+        pkt->duration = lace_duration;
+    }
 
     if (st->codec->codec_id == AV_CODEC_ID_SSA)
-        matroska_fix_ass_packet(matroska, pkt, duration);
+        matroska_fix_ass_packet(matroska, pkt, lace_duration);
 
     if (matroska->prev_pkt &&
         timecode != AV_NOPTS_VALUE &&
@@ -2002,7 +2156,7 @@
     int16_t block_time;
     uint32_t *lace_size = NULL;
     int n, flags, laces = 0;
-    uint64_t num, duration;
+    uint64_t num;
 
     if ((n = matroska_ebmlnum_uint(matroska, data, size, &num)) < 0) {
         av_log(matroska->ctx, AV_LOG_ERROR, "EBML block data error\n");
@@ -2021,6 +2175,7 @@
     st = track->stream;
     if (st->discard >= AVDISCARD_ALL)
         return res;
+    av_assert1(block_duration != AV_NOPTS_VALUE);
 
     block_time = AV_RB16(data);
     data += 2;
@@ -2040,9 +2195,14 @@
     }
 
     if (matroska->skip_to_keyframe && track->type != MATROSKA_TRACK_TYPE_SUBTITLE) {
-        if (!is_keyframe || timecode < matroska->skip_to_timecode)
+        if (timecode < matroska->skip_to_timecode)
             return res;
-        matroska->skip_to_keyframe = 0;
+        if (!st->skip_to_keyframe) {
+            av_log(matroska->ctx, AV_LOG_ERROR, "File is broken, keyframes not correctly marked!\n");
+            matroska->skip_to_keyframe = 0;
+        }
+        if (is_keyframe)
+            matroska->skip_to_keyframe = 0;
     }
 
     res = matroska_parse_laces(matroska, &data, size, (flags & 0x06) >> 1,
@@ -2051,22 +2211,21 @@
     if (res)
         goto end;
 
-    if (block_duration != AV_NOPTS_VALUE) {
-        duration = block_duration / laces;
-        if (block_duration != duration * laces) {
-            av_log(matroska->ctx, AV_LOG_WARNING,
-                   "Incorrect block_duration, possibly corrupted container");
-        }
-    } else {
-        duration = track->default_duration / matroska->time_scale;
-        block_duration = duration * laces;
-    }
+    if (!block_duration)
+        block_duration = track->default_duration * laces / matroska->time_scale;
 
-    if (timecode != AV_NOPTS_VALUE)
+    if (cluster_time != (uint64_t)-1 && (block_time >= 0 || cluster_time >= -block_time))
         track->end_timecode =
             FFMAX(track->end_timecode, timecode + block_duration);
 
     for (n = 0; n < laces; n++) {
+        int64_t lace_duration = block_duration*(n+1) / laces - block_duration*n / laces;
+
+        if (lace_size[n] > size) {
+            av_log(matroska->ctx, AV_LOG_ERROR, "Invalid packet size\n");
+            break;
+        }
+
         if ((st->codec->codec_id == AV_CODEC_ID_RA_288 ||
              st->codec->codec_id == AV_CODEC_ID_COOK ||
              st->codec->codec_id == AV_CODEC_ID_SIPR ||
@@ -2074,20 +2233,20 @@
              st->codec->block_align && track->audio.sub_packet_size) {
 
             res = matroska_parse_rm_audio(matroska, track, st, data, size,
-                                          timecode, duration, pos);
+                                          timecode, pos);
             if (res)
                 goto end;
 
         } else {
             res = matroska_parse_frame(matroska, track, st, data, lace_size[n],
-                                      timecode, duration,
+                                      timecode, lace_duration,
                                       pos, !n? is_keyframe : 0);
             if (res)
                 goto end;
         }
 
         if (timecode != AV_NOPTS_VALUE)
-            timecode = duration ? timecode + duration : AV_NOPTS_VALUE;
+            timecode = lace_duration ? timecode + lace_duration : AV_NOPTS_VALUE;
         data += lace_size[n];
         size -= lace_size[n];
     }
@@ -2138,7 +2297,7 @@
         if (blocks[i].bin.size > 0 && blocks[i].bin.data) {
             int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
             if (!blocks[i].non_simple)
-                blocks[i].duration = AV_NOPTS_VALUE;
+                blocks[i].duration = 0;
             res = matroska_parse_block(matroska,
                                        blocks[i].bin.data, blocks[i].bin.size,
                                        blocks[i].bin.pos,
@@ -2168,11 +2327,9 @@
     res = ebml_parse(matroska, matroska_clusters, &cluster);
     blocks_list = &cluster.blocks;
     blocks = blocks_list->elem;
-    for (i=0; i<blocks_list->nb_elem && !res; i++)
+    for (i=0; i<blocks_list->nb_elem; i++)
         if (blocks[i].bin.size > 0 && blocks[i].bin.data) {
             int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
-            if (!blocks[i].non_simple)
-                blocks[i].duration = AV_NOPTS_VALUE;
             res=matroska_parse_block(matroska,
                                      blocks[i].bin.data, blocks[i].bin.size,
                                      blocks[i].bin.pos,  cluster.timecode,
@@ -2180,27 +2337,22 @@
                                      pos);
         }
     ebml_free(matroska_cluster, &cluster);
-    if (res < 0)  matroska->done = 1;
     return res;
 }
 
 static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     MatroskaDemuxContext *matroska = s->priv_data;
-    int ret = 0;
 
-    while (!ret && matroska_deliver_packet(matroska, pkt)) {
+    while (matroska_deliver_packet(matroska, pkt)) {
+        int64_t pos = avio_tell(matroska->ctx->pb);
         if (matroska->done)
             return AVERROR_EOF;
-        ret = matroska_parse_cluster(matroska);
+        if (matroska_parse_cluster(matroska) < 0)
+            matroska_resync(matroska, pos);
     }
 
-    if (ret == AVERROR_INVALIDDATA && pkt->data) {
-        pkt->flags |= AV_PKT_FLAG_CORRUPT;
-        return 0;
-    }
-
-    return ret;
+    return 0;
 }
 
 static int matroska_read_seek(AVFormatContext *s, int stream_index,
@@ -2212,13 +2364,13 @@
     int i, index, index_sub, index_min;
 
     /* Parse the CUES now since we need the index data to seek. */
-    if (matroska->cues_parsing_deferred) {
-        matroska_parse_cues(matroska);
+    if (matroska->cues_parsing_deferred > 0) {
         matroska->cues_parsing_deferred = 0;
+        matroska_parse_cues(matroska);
     }
 
     if (!st->nb_index_entries)
-        return 0;
+        goto err;
     timestamp = FFMAX(timestamp, st->index_entries[0].timestamp);
 
     if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) {
@@ -2233,8 +2385,8 @@
     }
 
     matroska_clear_queue(matroska);
-    if (index < 0)
-        return 0;
+    if (index < 0 || (matroska->cues_parsing_deferred < 0 && index == st->nb_index_entries - 1))
+        goto err;
 
     index_min = index;
     for (i=0; i < matroska->tracks.nb_elem; i++) {
@@ -2254,11 +2406,23 @@
 
     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;
     matroska->done = 0;
+    matroska->num_levels = 0;
     ff_update_cur_dts(s, st, st->index_entries[index].timestamp);
     return 0;
+err:
+    // slightly hackish but allows proper fallback to
+    // the generic seeking code.
+    matroska_clear_queue(matroska);
+    matroska->current_id = 0;
+    st->skip_to_keyframe =
+    matroska->skip_to_keyframe = 0;
+    matroska->done = 0;
+    matroska->num_levels = 0;
+    return -1;
 }
 
 static int matroska_read_close(AVFormatContext *s)
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index b37d10c..375f728 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -2,20 +2,20 @@
  * Matroska muxer
  * Copyright (c) 2007 David Conrad
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -128,7 +128,7 @@
  */
 static void put_ebml_size_unknown(AVIOContext *pb, int bytes)
 {
-    assert(bytes <= 8);
+    av_assert0(bytes <= 8);
     avio_w8(pb, 0x1ff >> bytes);
     while (--bytes)
         avio_w8(pb, 0xff);
@@ -155,14 +155,14 @@
     int i, needed_bytes = ebml_num_size(num);
 
     // sizes larger than this are currently undefined in EBML
-    assert(num < (1ULL<<56)-1);
+    av_assert0(num < (1ULL<<56)-1);
 
     if (bytes == 0)
         // don't care how many bytes are used, so use the min
         bytes = needed_bytes;
     // the bytes needed to write the given size would exceed the bytes
     // that we need to use, so write unknown size. This shouldn't happen.
-    assert(bytes >= needed_bytes);
+    av_assert0(bytes >= needed_bytes);
 
     num |= 1ULL << bytes*7;
     for (i = bytes - 1; i >= 0; i--)
@@ -211,7 +211,7 @@
 {
     int64_t currentpos = avio_tell(pb);
 
-    assert(size >= 2);
+    av_assert0(size >= 2);
 
     put_ebml_id(pb, EBML_ID_VOID);
     // we need to subtract the length needed to store the size from the
@@ -590,7 +590,10 @@
         switch (codec->codec_type) {
             case AVMEDIA_TYPE_VIDEO:
                 put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_VIDEO);
-                put_ebml_uint(pb, MATROSKA_ID_TRACKDEFAULTDURATION, av_q2d(codec->time_base)*1E9);
+                if(st->avg_frame_rate.num && st->avg_frame_rate.den && 1.0/av_q2d(st->avg_frame_rate) > av_q2d(codec->time_base))
+                    put_ebml_uint(pb, MATROSKA_ID_TRACKDEFAULTDURATION, 1E9/av_q2d(st->avg_frame_rate));
+                else
+                    put_ebml_uint(pb, MATROSKA_ID_TRACKDEFAULTDURATION, av_q2d(codec->time_base)*1E9);
 
                 if (!native_id &&
                       ff_codec_get_tag(ff_codec_movvideo_tags, codec->codec_id) &&
@@ -612,30 +615,36 @@
                 // XXX: interlace flag?
                 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELWIDTH , codec->width);
                 put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELHEIGHT, codec->height);
-                if ((tag = av_dict_get(s->metadata, "stereo_mode", NULL, 0))) {
-                    uint8_t stereo_fmt = atoi(tag->value);
-                    int valid_fmt = 0;
 
-                    switch (mkv->mode) {
-                    case MODE_WEBM:
-                        if (stereo_fmt <= MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM
-                            || stereo_fmt == MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT)
-                            valid_fmt = 1;
-                        break;
-                    case MODE_MATROSKAv2:
-                        if (stereo_fmt <= MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_RL)
-                            valid_fmt = 1;
-                        break;
-                    }
+                if ((tag = av_dict_get(st->metadata, "stereo_mode", NULL, 0)) ||
+                    (tag = av_dict_get( s->metadata, "stereo_mode", NULL, 0))) {
+                    // save stereo mode flag
+                    uint64_t st_mode = MATROSKA_VIDEO_STEREO_MODE_COUNT;
 
-                    if (valid_fmt)
-                        put_ebml_uint (pb, MATROSKA_ID_VIDEOSTEREOMODE, stereo_fmt);
+                    for (j=0; j<MATROSKA_VIDEO_STEREO_MODE_COUNT; j++)
+                        if (!strcmp(tag->value, ff_matroska_video_stereo_mode[j])){
+                            st_mode = j;
+                            break;
+                        }
+
+                    if ((mkv->mode == MODE_WEBM && st_mode > 3 && st_mode != 11)
+                        || st_mode >= MATROSKA_VIDEO_STEREO_MODE_COUNT) {
+                        av_log(s, AV_LOG_ERROR,
+                               "The specified stereo mode is not valid.\n");
+                        return AVERROR(EINVAL);
+                    } else
+                        put_ebml_uint(pb, MATROSKA_ID_VIDEOSTEREOMODE, st_mode);
                 }
+
                 if (st->sample_aspect_ratio.num) {
                     int d_width = codec->width*av_q2d(st->sample_aspect_ratio);
                     put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , d_width);
                     put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, codec->height);
-                    put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYUNIT, 3);
+                }
+
+                if (codec->codec_id == AV_CODEC_ID_RAWVIDEO) {
+                    uint32_t color_space = av_le2ne32(codec->codec_tag);
+                    put_ebml_binary(pb, MATROSKA_ID_VIDEOCOLORSPACE, &color_space, sizeof(color_space));
                 }
                 end_ebml_master(pb, subinfo);
                 break;
@@ -776,7 +785,7 @@
     end_ebml_master(s->pb, targets);
 
     while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX)))
-        if (av_strcasecmp(t->key, "title"))
+        if (av_strcasecmp(t->key, "title") && av_strcasecmp(t->key, "stereo_mode"))
             mkv_write_simpletag(s->pb, t);
 
     end_ebml_master(s->pb, tag);
@@ -940,6 +949,14 @@
         put_ebml_binary(pb, MATROSKA_ID_SEGMENTUID, segment_uid, 16);
     }
 
+    if (tag = av_dict_get(s->metadata, "creation_time", NULL, 0)) {
+        // Adjust time so it's relative to 2001-01-01 and convert to nanoseconds.
+        int64_t date_utc = (ff_iso8601_to_unix_time(tag->value) - 978307200) * 1000000000;
+        uint8_t date_utc_buf[8];
+        AV_WB64(date_utc_buf, date_utc);
+        put_ebml_binary(pb, MATROSKA_ID_DATEUTC, date_utc_buf, 8);
+    }
+
     // reserve space for the duration
     mkv->duration = 0;
     mkv->duration_offset = avio_tell(pb);
@@ -970,6 +987,7 @@
     av_init_packet(&mkv->cur_audio_pkt);
     mkv->cur_audio_pkt.size = 0;
     mkv->audio_buffer_size  = 0;
+    mkv->cluster_pos = -1;
 
     avio_flush(pb);
     return 0;
@@ -1150,7 +1168,7 @@
         pb = mkv->dyn_bc;
     }
 
-    if (!mkv->cluster_pos) {
+    if (mkv->cluster_pos == -1) {
         mkv->cluster_pos = avio_tell(s->pb);
         mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER, 0);
         put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, FFMAX(0, ts));
@@ -1165,7 +1183,10 @@
         duration = mkv_write_srt_blocks(s, pb, pkt);
     } else {
         ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(pkt->size));
-        duration = pkt->convergence_duration;
+        /* For backward compatibility, prefer convergence_duration. */
+        if (pkt->convergence_duration > 0) {
+            duration = pkt->convergence_duration;
+        }
         mkv_write_block(s, pb, MATROSKA_ID_BLOCK, pkt, 0);
         put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration);
         end_ebml_master(pb, blockgroup);
@@ -1204,14 +1225,14 @@
 
     // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or
     // after 4k and on a keyframe
-    if (mkv->cluster_pos &&
+    if (mkv->cluster_pos != -1 &&
         ((!s->pb->seekable && (cluster_size > 32*1024 || ts > mkv->cluster_pts + 1000))
          ||                      cluster_size > 5*1024*1024 || ts > mkv->cluster_pts + 5000
          || (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe && cluster_size > 4*1024))) {
         av_log(s, AV_LOG_DEBUG, "Starting new cluster at offset %" PRIu64
                " bytes, pts %" PRIu64 "\n", avio_tell(pb), ts);
         end_ebml_master(pb, mkv->cluster);
-        mkv->cluster_pos = 0;
+        mkv->cluster_pos = -1;
         if (mkv->dyn_bc)
             mkv_flush_dynbuf(s);
     }
@@ -1255,7 +1276,7 @@
     if (mkv->dyn_bc) {
         end_ebml_master(mkv->dyn_bc, mkv->cluster);
         mkv_flush_dynbuf(s);
-    } else if (mkv->cluster_pos) {
+    } else if (mkv->cluster_pos != -1) {
         end_ebml_master(pb, mkv->cluster);
     }
 
@@ -1319,9 +1340,6 @@
     .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, 0
-    },
     .subtitle_codec    = AV_CODEC_ID_SSA,
     .query_codec       = mkv_query_codec,
 };
@@ -1358,6 +1376,5 @@
     .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, 0 },
 };
 #endif
diff --git a/libavformat/md5enc.c b/libavformat/md5enc.c
index 16412c9..050efb1 100644
--- a/libavformat/md5enc.c
+++ b/libavformat/md5enc.c
@@ -2,20 +2,20 @@
  * MD5 encoder (for codec/format testing)
  * Copyright (c) 2009 Reimar Döffinger, based on crcenc (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -76,7 +76,6 @@
 AVOutputFormat ff_md5_muxer = {
     .name              = "md5",
     .long_name         = NULL_IF_CONFIG_SMALL("MD5 testing"),
-    .extensions        = "",
     .priv_data_size    = sizeof(struct MD5Context),
     .audio_codec       = AV_CODEC_ID_PCM_S16LE,
     .video_codec       = AV_CODEC_ID_RAWVIDEO,
@@ -120,7 +119,6 @@
 AVOutputFormat ff_framemd5_muxer = {
     .name              = "framemd5",
     .long_name         = NULL_IF_CONFIG_SMALL("Per-frame MD5 testing"),
-    .extensions        = "",
     .priv_data_size    = sizeof(struct MD5Context),
     .audio_codec       = AV_CODEC_ID_PCM_S16LE,
     .video_codec       = AV_CODEC_ID_RAWVIDEO,
diff --git a/libavformat/md5proto.c b/libavformat/md5proto.c
index 12ddde3..6af0a6e 100644
--- a/libavformat/md5proto.c
+++ b/libavformat/md5proto.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Mans Rullgard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/metadata-example.c b/libavformat/metadata-example.c
deleted file mode 100644
index 7bf77e7..0000000
--- a/libavformat/metadata-example.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2011 Reinhard Tartler
- *
- * 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.
- */
-
-/**
- * @file
- * @example libavformat/metadata-example.c
- * Shows how the metadata API can be used in application programs.
- */
-
-#include <stdio.h>
-
-#include <libavformat/avformat.h>
-#include <libavutil/dict.h>
-
-int main (int argc, char **argv)
-{
-    AVFormatContext *fmt_ctx = NULL;
-    AVDictionaryEntry *tag = NULL;
-    int ret;
-
-    if (argc != 2) {
-        printf("usage: %s <input_file>\n"
-               "example program to demonstrate the use of the libavformat metadata API.\n"
-               "\n", argv[0]);
-        return 1;
-    }
-
-    av_register_all();
-    if ((ret = avformat_open_input(&fmt_ctx, argv[1], NULL, NULL)))
-        return ret;
-
-    while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
-        printf("%s=%s\n", tag->key, tag->value);
-
-    avformat_free_context(fmt_ctx);
-    return 0;
-}
diff --git a/libavformat/metadata.c b/libavformat/metadata.c
index 77fb298..fc3a9d7 100644
--- a/libavformat/metadata.c
+++ b/libavformat/metadata.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2009 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/metadata.h b/libavformat/metadata.h
index eee3ee4..6586094 100644
--- a/libavformat/metadata.h
+++ b/libavformat/metadata.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2009 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/mgsts.c b/libavformat/mgsts.c
new file mode 100644
index 0000000..dec6bfc
--- /dev/null
+++ b/libavformat/mgsts.c
@@ -0,0 +1,106 @@
+/*
+ * Metar Gear Solid: The Twin Snakes 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 "libavutil/intfloat.h"
+#include "avformat.h"
+#include "riff.h"
+
+static int read_probe(AVProbeData *p)
+{
+    if (AV_RB32(p->buf     ) != 0x000E ||
+        AV_RB32(p->buf +  4) != 0x0050 ||
+        AV_RB32(p->buf + 12) != 0x0034)
+        return 0;
+    return AVPROBE_SCORE_MAX;
+}
+
+static int read_header(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    AVStream    *st;
+    AVRational  fps;
+    uint32_t chunk_size;
+
+    avio_skip(pb, 4);
+    chunk_size = avio_rb32(pb);
+    if (chunk_size != 80)
+        return AVERROR(EIO);
+    avio_skip(pb, 20);
+
+    st = avformat_new_stream(s, 0);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    st->need_parsing = AVSTREAM_PARSE_HEADERS;
+    st->start_time = 0;
+    st->nb_frames  =
+    st->duration   = avio_rb32(pb);
+    fps = av_d2q(av_int2float(avio_rb32(pb)), INT_MAX);
+    st->codec->width  = avio_rb32(pb);
+    st->codec->height = avio_rb32(pb);
+    avio_skip(pb, 12);
+    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+    st->codec->codec_tag  = avio_rb32(pb);
+    st->codec->codec_id   = ff_codec_get_id(ff_codec_bmp_tags,
+                                            st->codec->codec_tag);
+    avpriv_set_pts_info(st, 64, fps.den, fps.num);
+    avio_skip(pb, 20);
+
+    return 0;
+}
+
+static int read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    AVIOContext *pb = s->pb;
+    uint32_t chunk_size, payload_size;
+    int ret;
+
+    if (url_feof(pb))
+        return AVERROR_EOF;
+
+    avio_skip(pb, 4);
+    chunk_size = avio_rb32(pb);
+    avio_skip(pb, 4);
+    payload_size = avio_rb32(pb);
+
+    if (chunk_size < payload_size + 16)
+        return AVERROR(EIO);
+
+    ret = av_get_packet(pb, pkt, payload_size);
+    if (ret < 0)
+        return ret;
+
+    pkt->pos -= 16;
+    pkt->duration = 1;
+    avio_skip(pb, chunk_size - (ret + 16));
+
+    return ret;
+}
+
+AVInputFormat ff_mgsts_demuxer = {
+    .name        = "mgsts",
+    .long_name   = NULL_IF_CONFIG_SMALL("Metal Gear Solid: The Twin Snakes"),
+    .read_probe  = read_probe,
+    .read_header = read_header,
+    .read_packet = read_packet,
+    .flags       = AVFMT_GENERIC_INDEX,
+};
diff --git a/libavformat/microdvddec.c b/libavformat/microdvddec.c
new file mode 100644
index 0000000..ecc2819
--- /dev/null
+++ b/libavformat/microdvddec.c
@@ -0,0 +1,145 @@
+/*
+ * MicroDVD subtitle demuxer
+ * Copyright (c) 2010  Aurelien Jacobs <aurel@gnuage.org>
+ * Copyright (c) 2012  Clément Bœsch <ubitux@gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+#include "libavutil/intreadwrite.h"
+
+#define MAX_LINESIZE 2048
+
+
+typedef struct {
+    FFDemuxSubtitlesQueue q;
+} MicroDVDContext;
+
+
+static int microdvd_probe(AVProbeData *p)
+{
+    unsigned char c, *ptr = p->buf;
+    int i;
+
+    if (AV_RB24(ptr) == 0xEFBBBF)
+        ptr += 3;  /* skip UTF-8 BOM */
+
+    for (i=0; i<3; i++) {
+        if (sscanf(ptr, "{%*d}{}%c",     &c) != 1 &&
+            sscanf(ptr, "{%*d}{%*d}%c",  &c) != 1 &&
+            sscanf(ptr, "{DEFAULT}{}%c", &c) != 1)
+            return 0;
+        ptr += strcspn(ptr, "\n") + 1;
+    }
+    return AVPROBE_SCORE_MAX;
+}
+
+static int64_t get_pts(const char *buf)
+{
+    int frame;
+    char c;
+
+    if (sscanf(buf, "{%d}{%c", &frame, &c) == 2)
+        return frame;
+    return AV_NOPTS_VALUE;
+}
+
+static int get_duration(const char *buf)
+{
+    int frame_start, frame_end;
+
+    if (sscanf(buf, "{%d}{%d}", &frame_start, &frame_end) == 2)
+        return frame_end - frame_start;
+    return -1;
+}
+
+static int microdvd_read_header(AVFormatContext *s)
+{
+    AVRational pts_info = (AVRational){ 2997, 125 };  /* default: 23.976 fps */
+    MicroDVDContext *microdvd = s->priv_data;
+    AVStream *st = avformat_new_stream(s, NULL);
+    int i = 0;
+    char line[MAX_LINESIZE];
+
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    while (!url_feof(s->pb)) {
+        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) {
+            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)
+                pts_info = av_d2q(fps, 100000);
+            if (!st->codec->extradata && sscanf(line, "{DEFAULT}{}%c", &c) == 1) {
+                st->codec->extradata = av_strdup(line + 11);
+                if (!st->codec->extradata)
+                    return AVERROR(ENOMEM);
+                st->codec->extradata_size = strlen(st->codec->extradata) + 1;
+                continue;
+            }
+        }
+        sub = ff_subtitles_queue_insert(&microdvd->q, line, len, 0);
+        if (!sub)
+            return AVERROR(ENOMEM);
+        sub->pos = pos;
+        sub->pts = get_pts(sub->data);
+        sub->duration = get_duration(sub->data);
+    }
+    ff_subtitles_queue_finalize(&microdvd->q);
+    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_MICRODVD;
+    return 0;
+}
+
+static int microdvd_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    MicroDVDContext *microdvd = s->priv_data;
+    return ff_subtitles_queue_read_packet(&microdvd->q, pkt);
+}
+
+static int microdvd_read_close(AVFormatContext *s)
+{
+    MicroDVDContext *microdvd = s->priv_data;
+    ff_subtitles_queue_clean(&microdvd->q);
+    return 0;
+}
+
+AVInputFormat ff_microdvd_demuxer = {
+    .name           = "microdvd",
+    .long_name      = NULL_IF_CONFIG_SMALL("MicroDVD subtitle format"),
+    .priv_data_size = sizeof(MicroDVDContext),
+    .read_probe     = microdvd_probe,
+    .read_header    = microdvd_read_header,
+    .read_packet    = microdvd_read_packet,
+    .read_close     = microdvd_read_close,
+    .flags          = AVFMT_GENERIC_INDEX,
+};
diff --git a/libavformat/microdvdenc.c b/libavformat/microdvdenc.c
new file mode 100644
index 0000000..ba97444
--- /dev/null
+++ b/libavformat/microdvdenc.c
@@ -0,0 +1,51 @@
+/*
+ * MicroDVD subtitle muxer
+ * Copyright (c) 2010  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
+ */
+
+#include "avformat.h"
+#include "rawenc.h"
+
+static int microdvd_write_header(struct AVFormatContext *s)
+{
+    AVCodecContext *avctx = s->streams[0]->codec;
+
+    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");
+        return -1;
+    }
+
+    if (avctx->extradata && avctx->extradata_size > 0) {
+        avio_write(s->pb, "{DEFAULT}{}", 11);
+        avio_write(s->pb, avctx->extradata, avctx->extradata_size);
+        avio_flush(s->pb);
+    }
+    return 0;
+}
+
+AVOutputFormat ff_microdvd_muxer = {
+    .name           = "microdvd",
+    .long_name      = NULL_IF_CONFIG_SMALL("MicroDVD subtitle format"),
+    .mime_type      = "text/x-microdvd",
+    .extensions     = "sub",
+    .write_header   = microdvd_write_header,
+    .write_packet   = ff_raw_write_packet,
+    .flags          = AVFMT_NOTIMESTAMPS,
+    .subtitle_codec = AV_CODEC_ID_MICRODVD,
+};
diff --git a/libavformat/mkvtimestamp_v2.c b/libavformat/mkvtimestamp_v2.c
new file mode 100644
index 0000000..3ed195a
--- /dev/null
+++ b/libavformat/mkvtimestamp_v2.c
@@ -0,0 +1,51 @@
+/*
+ * extract pts as timecode v2, as defined by mkvtoolnix
+ * Copyright (c) 2009 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 "avformat.h"
+#include "internal.h"
+
+static int write_header(AVFormatContext *s)
+{
+    static const char *header = "# timecode format v2\n";
+    avio_write(s->pb, header, strlen(header));
+    avpriv_set_pts_info(s->streams[0], 64, 1, 1000);
+    return 0;
+}
+
+static int write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    char buf[256];
+    if (pkt->stream_index)
+        av_log(s, AV_LOG_WARNING, "More than one stream unsupported\n");
+    snprintf(buf, sizeof(buf), "%" PRId64 "\n", pkt->dts);
+    avio_write(s->pb, buf, strlen(buf));
+    avio_flush(s->pb);
+    return 0;
+}
+
+AVOutputFormat ff_mkvtimestamp_v2_muxer = {
+    .name         = "mkvtimestamp_v2",
+    .long_name    = NULL_IF_CONFIG_SMALL("extract pts as timecode v2 format, as defined by mkvtoolnix"),
+    .audio_codec  = AV_CODEC_ID_NONE,
+    .video_codec  = AV_CODEC_ID_RAWVIDEO,
+    .write_header = write_header,
+    .write_packet = write_packet,
+};
diff --git a/libavformat/mm.c b/libavformat/mm.c
index 13f33a2..125a677 100644
--- a/libavformat/mm.c
+++ b/libavformat/mm.c
@@ -2,20 +2,20 @@
  * American Laser Games MM Format Demuxer
  * Copyright (c) 2006 Peter Ross
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -174,7 +174,6 @@
         case MM_TYPE_AUDIO :
             if (av_get_packet(s->pb, pkt, length)<0)
                 return AVERROR(ENOMEM);
-            pkt->size = length;
             pkt->stream_index = 1;
             pkt->pts = mm->audio_pts++;
             return 0;
diff --git a/libavformat/mmf.c b/libavformat/mmf.c
index 06d4a2b..18b69d4 100644
--- a/libavformat/mmf.c
+++ b/libavformat/mmf.c
@@ -2,20 +2,20 @@
  * Yamaha SMAF format
  * Copyright (c) 2005 Vidar Madsen
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
@@ -68,7 +68,7 @@
 
     rate = mmf_rate_code(s->streams[0]->codec->sample_rate);
     if(rate < 0) {
-        av_log(s, AV_LOG_ERROR, "Unsupported sample rate %d\n", s->streams[0]->codec->sample_rate);
+        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;
     }
 
@@ -76,8 +76,8 @@
     avio_wb32(pb, 0);
     pos = ff_start_tag(pb, "CNTI");
     avio_w8(pb, 0); /* class */
-    avio_w8(pb, 0); /* type */
-    avio_w8(pb, 0); /* code type */
+    avio_w8(pb, 1); /* type */
+    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,...") */
@@ -265,7 +265,7 @@
     MMFContext *mmf = s->priv_data;
     int ret, size;
 
-    if (s->pb->eof_reached)
+    if (url_feof(s->pb))
         return AVERROR(EIO);
 
     size = MAX_SIZE;
@@ -275,17 +275,13 @@
     if(!size)
         return AVERROR(EIO);
 
-    if (av_new_packet(pkt, size))
-        return AVERROR(EIO);
-    pkt->stream_index = 0;
-
-    ret = avio_read(s->pb, pkt->data, pkt->size);
+    ret = av_get_packet(s->pb, pkt, size);
     if (ret < 0)
-        av_free_packet(pkt);
+        return ret;
 
+    pkt->stream_index = 0;
     mmf->data_size -= ret;
 
-    pkt->size = ret;
     return ret;
 }
 
diff --git a/libavformat/mms.c b/libavformat/mms.c
index 192e703..46fbede 100644
--- a/libavformat/mms.c
+++ b/libavformat/mms.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2007 Björn Axelsson
  * Copyright (c) 2010 Zhentan Feng <spyfeng at gmail dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "mms.h"
diff --git a/libavformat/mms.h b/libavformat/mms.h
index e89da41..57e3d7e 100644
--- a/libavformat/mms.h
+++ b/libavformat/mms.h
@@ -2,20 +2,20 @@
  * MMS protocol common definitions.
  * Copyright (c) 2010 Zhentan Feng <spyfeng at gmail dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #ifndef AVFORMAT_MMS_H
diff --git a/libavformat/mmsh.c b/libavformat/mmsh.c
index 5e9d0bc..d6e3982 100644
--- a/libavformat/mmsh.c
+++ b/libavformat/mmsh.c
@@ -2,20 +2,20 @@
  * MMS protocol over HTTP
  * Copyright (c) 2010 Zhentan Feng <spyfeng at gmail dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -56,6 +56,7 @@
 
 typedef struct {
     MMSContext mms;
+    uint8_t location[1024];
     int request_seq;  ///< request packet sequence
     int chunk_seq;    ///< data packet sequence
 } MMSHContext;
@@ -210,10 +211,10 @@
     }
 }
 
-static int mmsh_open(URLContext *h, const char *uri, int flags)
+static int mmsh_open_internal(URLContext *h, const char *uri, int flags, int timestamp, int64_t pos)
 {
     int i, port, err;
-    char httpname[256], path[256], host[128], location[1024];
+    char httpname[256], path[256], host[128];
     char *stream_selection = NULL;
     char headers[1024];
     MMSHContext *mmsh = h->priv_data;
@@ -221,10 +222,10 @@
 
     mmsh->request_seq = h->is_streamed = 1;
     mms = &mmsh->mms;
-    av_strlcpy(location, uri, sizeof(location));
+    av_strlcpy(mmsh->location, uri, sizeof(mmsh->location));
 
     av_url_split(NULL, 0, NULL, 0,
-        host, sizeof(host), &port, path, sizeof(path), location);
+        host, sizeof(host), &port, path, sizeof(path), mmsh->location);
     if (port<0)
         port = 80; // default mmsh protocol port
     ff_url_join(httpname, sizeof(httpname), "http", NULL, host, port, "%s", path);
@@ -241,7 +242,7 @@
              "Pragma: no-cache,rate=1.000000,stream-time=0,"
              "stream-offset=0:0,request-context=%u,max-duration=0\r\n"
              CLIENTGUID
-             "Connection: Close\r\n\r\n",
+             "Connection: Close\r\n",
              host, port, mmsh->request_seq++);
     av_opt_set(mms->mms_hd->priv_data, "headers", headers, 0);
 
@@ -282,8 +283,9 @@
                    CLIENTGUID
                    "Pragma: stream-switch-count=%d\r\n"
                    "Pragma: stream-switch-entry=%s\r\n"
-                   "Connection: Close\r\n\r\n",
-                   host, port, mmsh->request_seq++, mms->stream_num, stream_selection);
+                   "Pragma: no-cache,rate=1.000000,stream-time=%u"
+                   "Connection: Close\r\n",
+                   host, port, mmsh->request_seq++, mms->stream_num, stream_selection, timestamp);
     av_freep(&stream_selection);
     if (err < 0) {
         av_log(NULL, AV_LOG_ERROR, "Build play request failed!\n");
@@ -312,6 +314,11 @@
     return err;
 }
 
+static int mmsh_open(URLContext *h, const char *uri, int flags)
+{
+    return mmsh_open_internal(h, uri, flags, 0, 0);
+}
+
 static int handle_chunk_type(MMSHContext *mmsh)
 {
     MMSContext *mms = &mmsh->mms;
@@ -358,11 +365,46 @@
     return res;
 }
 
+static int64_t mmsh_read_seek(URLContext *h, int stream_index,
+                        int64_t timestamp, int flags)
+{
+    MMSHContext *mmsh = h->priv_data;
+    MMSContext *mms   = &mmsh->mms;
+    int ret;
+
+    ret= mmsh_open_internal(h, mmsh->location, 0, FFMAX(timestamp, 0), 0);
+
+    if(ret>=0){
+        if (mms->mms_hd)
+            ffurl_close(mms->mms_hd);
+        av_freep(&mms->streams);
+        av_freep(&mms->asf_header);
+        av_free(mmsh);
+        mmsh = h->priv_data;
+        mms   = &mmsh->mms;
+        mms->asf_header_read_size= mms->asf_header_size;
+    }else
+        h->priv_data= mmsh;
+    return ret;
+}
+
+static int64_t mmsh_seek(URLContext *h, int64_t pos, int whence)
+{
+    MMSHContext *mmsh = h->priv_data;
+    MMSContext *mms   = &mmsh->mms;
+
+    if(pos == 0 && whence == SEEK_CUR)
+        return mms->asf_header_read_size + mms->remaining_in_len + mmsh->chunk_seq * mms->asf_packet_len;
+    return AVERROR(ENOSYS);
+}
+
 URLProtocol ff_mmsh_protocol = {
     .name           = "mmsh",
     .url_open       = mmsh_open,
     .url_read       = mmsh_read,
+    .url_seek       = mmsh_seek,
     .url_close      = mmsh_close,
+    .url_read_seek  = mmsh_read_seek,
     .priv_data_size = sizeof(MMSHContext),
     .flags          = URL_PROTOCOL_FLAG_NETWORK,
 };
diff --git a/libavformat/mmst.c b/libavformat/mmst.c
index 4b96f5d..c3d2ebb 100644
--- a/libavformat/mmst.c
+++ b/libavformat/mmst.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2007 Björn Axelsson
  * Copyright (c) 2010 Zhentan Feng <spyfeng at gmail dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -152,7 +152,7 @@
     return 0;
 }
 
-static void mms_put_utf16(MMSContext *mms, uint8_t *src)
+static void mms_put_utf16(MMSContext *mms, const uint8_t *src)
 {
     AVIOContext bic;
     int size = mms->write_out_ptr - mms->out_buffer;
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 63049f5..bf695e7 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2001 Fabrice Bellard
  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -32,6 +32,8 @@
 #include "libavutil/mathematics.h"
 #include "libavutil/avstring.h"
 #include "libavutil/dict.h"
+#include "libavutil/opt.h"
+#include "libavutil/timecode.h"
 #include "libavcodec/ac3tab.h"
 #include "avformat.h"
 #include "internal.h"
@@ -129,6 +131,74 @@
     return 0;
 }
 
+static int mov_read_custom_metadata(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    char key[1024]={0}, data[1024]={0};
+    int i;
+    AVStream *st;
+    MOVStreamContext *sc;
+
+    if (c->fc->nb_streams < 1)
+        return 0;
+    st = c->fc->streams[c->fc->nb_streams-1];
+    sc = st->priv_data;
+
+    if (atom.size <= 8) return 0;
+
+    for (i = 0; i < 3; i++) { // Parse up to three sub-atoms looking for name and data.
+        int data_size = avio_rb32(pb);
+        int tag = avio_rl32(pb);
+        int str_size = 0, skip_size = 0;
+        char *target = NULL;
+
+        switch (tag) {
+        case MKTAG('n','a','m','e'):
+            avio_rb32(pb); // version/flags
+            str_size = skip_size = data_size - 12;
+            atom.size -= 12;
+            target = key;
+            break;
+        case MKTAG('d','a','t','a'):
+            avio_rb32(pb); // version/flags
+            avio_rb32(pb); // reserved (zero)
+            str_size = skip_size = data_size - 16;
+            atom.size -= 16;
+            target = data;
+            break;
+        default:
+            skip_size = data_size - 8;
+            str_size = 0;
+            break;
+        }
+
+        if (target) {
+            str_size = FFMIN3(sizeof(data)-1, str_size, atom.size);
+            avio_read(pb, target, str_size);
+            target[str_size] = 0;
+        }
+        atom.size -= skip_size;
+
+        // If we didn't read the full data chunk for the sub-atom, skip to the end of it.
+        if (skip_size > str_size) avio_skip(pb, skip_size - str_size);
+    }
+
+    if (*key && *data) {
+        if (strcmp(key, "iTunSMPB") == 0) {
+            int priming, remainder, samples;
+            if(sscanf(data, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
+                if(priming>0 && priming<16384)
+                    sc->start_pad = priming;
+                return 1;
+            }
+        }
+        if (strcmp(key, "cdec") == 0) {
+//             av_dict_set(&st->metadata, key, data, 0);
+            return 1;
+        }
+    }
+    return 0;
+}
+
 static const uint32_t mac_to_unicode[128] = {
     0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
     0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
@@ -159,7 +229,7 @@
         uint8_t t, c = avio_r8(pb);
         if (c < 0x80 && p < end)
             *p++ = c;
-        else
+        else if (p < end)
             PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
     }
     *p = 0;
@@ -219,6 +289,9 @@
     uint32_t data_type = 0, str_size;
     int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
 
+    if (c->itunes_metadata && atom.type == MKTAG('-','-','-','-'))
+        return mov_read_custom_metadata(c, pb, atom);
+
     switch (atom.type) {
     case MKTAG(0xa9,'n','a','m'): key = "title";     break;
     case MKTAG(0xa9,'a','u','t'):
@@ -227,6 +300,8 @@
     case MKTAG(0xa9,'w','r','t'): key = "composer";  break;
     case MKTAG( 'c','p','r','t'):
     case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
+    case MKTAG(0xa9,'g','r','p'): key = "grouping"; break;
+    case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break;
     case MKTAG(0xa9,'c','m','t'):
     case MKTAG(0xa9,'i','n','f'): key = "comment";   break;
     case MKTAG(0xa9,'a','l','b'): key = "album";     break;
@@ -300,7 +375,7 @@
     if (parse)
         parse(c, pb, str_size, key);
     else {
-        if (data_type == 3 || (data_type == 0 && langcode < 0x800)) { // MAC Encoded
+        if (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff))) { // MAC Encoded
             mov_read_mac_string(c, pb, str_size, str, sizeof(str));
         } else {
             avio_read(pb, str, str_size);
@@ -367,6 +442,7 @@
     if (entries >= UINT_MAX / sizeof(*sc->drefs))
         return AVERROR_INVALIDDATA;
     av_free(sc->drefs);
+    sc->drefs_count = 0;
     sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
     if (!sc->drefs)
         return AVERROR(ENOMEM);
@@ -416,7 +492,7 @@
             avio_skip(pb, 16);
 
             for (type = 0; type != -1 && avio_tell(pb) < next; ) {
-                if (pb->eof_reached)
+                if(url_feof(pb))
                     return AVERROR_EOF;
                 type = avio_rb16(pb);
                 len = avio_rb16(pb);
@@ -463,6 +539,8 @@
     AVStream *st;
     uint32_t type;
     uint32_t av_unused ctype;
+    int title_size;
+    char *title_str;
 
     if (c->fc->nb_streams < 1) // meta before first trak
         return 0;
@@ -492,6 +570,19 @@
     avio_rb32(pb); /* component flags */
     avio_rb32(pb); /* component flags mask */
 
+    title_size = atom.size - 24;
+    if (title_size > 0) {
+        title_str = av_malloc(title_size + 1); /* Add null terminator */
+        if (!title_str)
+            return AVERROR(ENOMEM);
+        avio_read(pb, title_str, title_size);
+        title_str[title_size] = 0;
+        if (title_str[0])
+            av_dict_set(&st->metadata, "handler_name", title_str +
+                        (!c->isom && title_str[0] == title_size - 1), 0);
+        av_freep(&title_str);
+    }
+
     return 0;
 }
 
@@ -692,7 +783,8 @@
     char buffer[32];
     if (time) {
         struct tm *ptm;
-        time -= 2082844800;  /* seconds between 1904-01-01 and Epoch */
+        if(time >= 2082844800)
+            time -= 2082844800;  /* seconds between 1904-01-01 and Epoch */
         ptm = gmtime(&time);
         if (!ptm) return;
         strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm);
@@ -759,6 +851,10 @@
     av_dlog(c->fc, "time scale = %i\n", c->time_scale);
 
     c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
+    // set the AVCodecContext duration because the duration of individual tracks
+    // may be inaccurate
+    if (c->time_scale > 0)
+        c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
     avio_rb32(pb); /* preferred scale */
 
     avio_rb16(pb); /* preferred volume */
@@ -774,31 +870,6 @@
     avio_rb32(pb); /* selection duration */
     avio_rb32(pb); /* current time */
     avio_rb32(pb); /* next track ID */
-
-    return 0;
-}
-
-static int mov_read_smi(MOVContext *c, AVIOContext *pb, MOVAtom atom)
-{
-    AVStream *st;
-
-    if (c->fc->nb_streams < 1)
-        return 0;
-    st = c->fc->streams[c->fc->nb_streams-1];
-
-    if ((uint64_t)atom.size > (1<<30))
-        return AVERROR_INVALIDDATA;
-
-    // currently SVQ3 decoder expect full STSD header - so let's fake it
-    // this should be fixed and just SMI header should be passed
-    av_free(st->codec->extradata);
-    st->codec->extradata = av_mallocz(atom.size + 0x5a + FF_INPUT_BUFFER_PADDING_SIZE);
-    if (!st->codec->extradata)
-        return AVERROR(ENOMEM);
-    st->codec->extradata_size = 0x5a + atom.size;
-    memcpy(st->codec->extradata, "SVQ3", 4); // fake
-    avio_read(pb, st->codec->extradata + 0x5a, atom.size);
-    av_dlog(c->fc, "Reading SMI %"PRId64"  %s\n", atom.size, st->codec->extradata + 0x5a);
     return 0;
 }
 
@@ -811,7 +882,7 @@
         return 0;
     st = c->fc->streams[c->fc->nb_streams-1];
 
-    little_endian = avio_rb16(pb);
+    little_endian = avio_rb16(pb) & 0xFF;
     av_dlog(c->fc, "enda %d\n", little_endian);
     if (little_endian == 1) {
         switch (st->codec->codec_id) {
@@ -869,7 +940,8 @@
 }
 
 /* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */
-static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
+                              enum AVCodecID codec_id)
 {
     AVStream *st;
     uint64_t size;
@@ -878,6 +950,10 @@
     if (c->fc->nb_streams < 1) // will happen with jp2 files
         return 0;
     st= c->fc->streams[c->fc->nb_streams-1];
+
+    if (st->codec->codec_id != codec_id)
+        return 0; /* unexpected codec_id - don't mess with extradata */
+
     size= (uint64_t)st->codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE;
     if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
         return AVERROR_INVALIDDATA;
@@ -893,6 +969,32 @@
     return 0;
 }
 
+/* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
+static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
+}
+
+static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
+}
+
+static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
+}
+
+static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
+}
+
+static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+    return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
+}
+
 static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     AVStream *st;
@@ -907,6 +1009,7 @@
     if (st->codec->codec_id == AV_CODEC_ID_QDM2 || st->codec->codec_id == AV_CODEC_ID_QDMC) {
         // pass all frma atom to codec, needed at least for QDMC and QDM2
         av_free(st->codec->extradata);
+        st->codec->extradata_size = 0;
         st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE);
         if (!st->codec->extradata)
             return AVERROR(ENOMEM);
@@ -946,6 +1049,7 @@
             return mov_read_default(c, pb, atom);
     }
     av_free(st->codec->extradata);
+    st->codec->extradata_size = 0;
     st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE);
     if (!st->codec->extradata)
         return AVERROR(ENOMEM);
@@ -971,6 +1075,7 @@
         return 0;
 
     av_free(st->codec->extradata);
+    st->codec->extradata_size = 0;
     st->codec->extradata = av_mallocz(atom.size - 7 + FF_INPUT_BUFFER_PADDING_SIZE);
     if (!st->codec->extradata)
         return AVERROR(ENOMEM);
@@ -999,6 +1104,7 @@
         return AVERROR_INVALIDDATA;
 
     av_free(st->codec->extradata);
+    st->codec->extradata_size = 0;
     st->codec->extradata = av_mallocz(atom.size - 40 + FF_INPUT_BUFFER_PADDING_SIZE);
     if (!st->codec->extradata)
         return AVERROR(ENOMEM);
@@ -1105,15 +1211,15 @@
         int dref_id = 1;
         MOVAtom a = { AV_RL32("stsd") };
         int64_t start_pos = avio_tell(pb);
-        uint32_t size = avio_rb32(pb); /* size */
+        int64_t size = avio_rb32(pb); /* size */
         uint32_t format = avio_rl32(pb); /* data format */
 
         if (size >= 16) {
             avio_rb32(pb); /* reserved */
             avio_rb16(pb); /* reserved */
             dref_id = avio_rb16(pb);
-        } else {
-            av_log(c->fc, AV_LOG_ERROR, "invalid size %d in stsd\n", size);
+        }else if (size <= 7){
+            av_log(c->fc, AV_LOG_ERROR, "invalid size %"PRId64" in stsd\n", size);
             return AVERROR_INVALIDDATA;
         }
 
@@ -1125,14 +1231,13 @@
             /* Multiple fourcc, we skip JPEG. This is not correct, we should
              * export it as a separate AVStream but this needs a few changes
              * in the MOV demuxer, patch welcome. */
-        multiple_stsd:
             av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
             avio_skip(pb, size - (avio_tell(pb) - start_pos));
             continue;
         }
         /* we cannot demux concatenated h264 streams because of different extradata */
         if (st->codec->codec_tag && st->codec->codec_tag == AV_RL32("avc1"))
-            goto multiple_stsd;
+            av_log(c->fc, AV_LOG_WARNING, "Concatenated H.264 might not play corrently.\n");
         sc->pseudo_stream_id = st->codec->codec_tag ? -1 : pseudo_stream_id;
         sc->dref_id= dref_id;
 
@@ -1150,14 +1255,16 @@
                 id = ff_codec_get_id(ff_codec_bmp_tags, format);
             if (id > 0)
                 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
-            else if (st->codec->codec_type == AVMEDIA_TYPE_DATA){
+            else if (st->codec->codec_type == AVMEDIA_TYPE_DATA ||
+                     (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE &&
+                      st->codec->codec_id == AV_CODEC_ID_NONE)){
                 id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
                 if (id > 0)
                     st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
             }
         }
 
-        av_dlog(c->fc, "size=%d 4CC= %c%c%c%c codec_type=%d\n", size,
+        av_dlog(c->fc, "size=%"PRId64" 4CC= %c%c%c%c codec_type=%d\n", size,
                 (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff,
                 (format >> 24) & 0xff, st->codec->codec_type);
 
@@ -1204,7 +1311,7 @@
                 (color_depth == 8)) {
                 /* for palette traversal */
                 unsigned int color_start, color_count, color_end;
-                unsigned char r, g, b;
+                unsigned char a, r, g, b;
 
                 if (color_greyscale) {
                     int color_index, color_dec;
@@ -1214,9 +1321,12 @@
                     color_index = 255;
                     color_dec = 256 / (color_count - 1);
                     for (j = 0; j < color_count; j++) {
+                        if (id == AV_CODEC_ID_CINEPAK){
+                            r = g = b = color_count - 1 - color_index;
+                        }else
                         r = g = b = color_index;
                         sc->palette[j] =
-                            (r << 16) | (g << 8) | (b);
+                            (0xFFU << 24) | (r << 16) | (g << 8) | (b);
                         color_index -= color_dec;
                         if (color_index < 0)
                             color_index = 0;
@@ -1237,7 +1347,7 @@
                         g = color_table[j * 3 + 1];
                         b = color_table[j * 3 + 2];
                         sc->palette[j] =
-                            (r << 16) | (g << 8) | (b);
+                            (0xFFU << 24) | (r << 16) | (g << 8) | (b);
                     }
                 } else {
                     /* load the palette from the file */
@@ -1247,10 +1357,9 @@
                     if ((color_start <= 255) &&
                         (color_end <= 255)) {
                         for (j = color_start; j <= color_end; j++) {
-                            /* each R, G, or B component is 16 bits;
-                             * only use the top 8 bits; skip alpha bytes
-                             * up front */
-                            avio_r8(pb);
+                            /* each A, R, G, or B component is 16 bits;
+                             * only use the top 8 bits */
+                            a = avio_r8(pb);
                             avio_r8(pb);
                             r = avio_r8(pb);
                             avio_r8(pb);
@@ -1259,7 +1368,7 @@
                             b = avio_r8(pb);
                             avio_r8(pb);
                             sc->palette[j] =
-                                (r << 16) | (g << 8) | (b);
+                                (a << 24 ) | (r << 16) | (g << 8) | (b);
                         }
                     }
                 }
@@ -1355,7 +1464,20 @@
             st->codec->width = sc->width;
             st->codec->height = sc->height;
         } else {
-            /* other codec type, just skip (rtp, mp4s, tmcd ...) */
+            if (st->codec->codec_tag == MKTAG('t','m','c','d')) {
+                MOVStreamContext *tmcd_ctx = st->priv_data;
+                int val;
+                avio_rb32(pb);       /* reserved */
+                val = avio_rb32(pb); /* flags */
+                tmcd_ctx->tmcd_flags = val;
+                if (val & 1)
+                    st->codec->flags2 |= CODEC_FLAG2_DROP_FRAME_TIMECODE;
+                avio_rb32(pb); /* time scale */
+                avio_rb32(pb); /* frame duration */
+                st->codec->time_base.den = avio_r8(pb); /* number of frame */
+                st->codec->time_base.num = 1;
+            }
+            /* other codec type, just skip (rtp, mp4s, ...) */
             avio_skip(pb, size - (avio_tell(pb) - start_pos));
         }
         /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */
@@ -1421,6 +1543,12 @@
             st->codec->sample_rate = AV_RB32(st->codec->extradata+32);
         }
         break;
+    case AV_CODEC_ID_AC3:
+        st->need_parsing = AVSTREAM_PARSE_FULL;
+        break;
+    case AV_CODEC_ID_MPEG1VIDEO:
+        st->need_parsing = AVSTREAM_PARSE_FULL;
+        break;
     case AV_CODEC_ID_VC1:
         st->need_parsing = AVSTREAM_PARSE_FULL;
         break;
@@ -1577,6 +1705,7 @@
         sample_size = avio_rb32(pb);
         if (!sc->sample_size) /* do not overwrite value computed in stsd */
             sc->sample_size = sample_size;
+        sc->alt_sample_size = sample_size;
         field_size = 32;
     } else {
         sample_size = 0;
@@ -1654,10 +1783,8 @@
     av_dlog(c->fc, "track[%i].stts.entries = %i\n",
             c->fc->nb_streams-1, entries);
 
-    if (!entries)
-        return 0;
     if (entries >= UINT_MAX / sizeof(*sc->stts_data))
-        return AVERROR(EINVAL);
+        return -1;
 
     sc->stts_data = av_malloc(entries * sizeof(*sc->stts_data));
     if (!sc->stts_data)
@@ -1669,6 +1796,11 @@
 
         sample_count=avio_rb32(pb);
         sample_duration = avio_rb32(pb);
+        /* sample_duration < 0 is invalid based on the spec */
+        if (sample_duration < 0) {
+            av_log(c->fc, AV_LOG_ERROR, "Invalid SampleDelta in STTS %d\n", sample_duration);
+            sample_duration = 1;
+        }
         sc->stts_data[i].count= sample_count;
         sc->stts_data[i].duration= sample_duration;
 
@@ -1722,7 +1854,18 @@
 
         sc->ctts_data[i].count   = count;
         sc->ctts_data[i].duration= duration;
-        if (duration < 0)
+
+        av_dlog(c->fc, "count=%d, duration=%d\n",
+                count, duration);
+
+        if (FFABS(duration) > (1<<28) && i+2<entries) {
+            av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
+            av_freep(&sc->ctts_data);
+            sc->ctts_count = 0;
+            return 0;
+        }
+
+        if (duration < 0 && i+2<entries)
             sc->dts_shift = FFMAX(sc->dts_shift, -duration);
     }
 
@@ -1790,12 +1933,13 @@
     AVIndexEntry *mem;
 
     /* adjust first dts according to edit list */
-    if (sc->time_offset && mov->time_scale > 0) {
-        if (sc->time_offset < 0)
-            sc->time_offset = av_rescale(sc->time_offset, sc->time_scale, mov->time_scale);
+    if ((sc->empty_duration || sc->start_time) && mov->time_scale > 0) {
+        if (sc->empty_duration)
+            sc->empty_duration = av_rescale(sc->empty_duration, sc->time_scale, mov->time_scale);
+        sc->time_offset = sc->start_time - sc->empty_duration;
         current_dts = -sc->time_offset;
-        if (sc->ctts_data && sc->stts_data && sc->stts_data[0].duration &&
-            sc->ctts_data[0].duration / sc->stts_data[0].duration > 16) {
+        if (sc->ctts_count>0 && sc->stts_count>0 &&
+            sc->ctts_data[0].duration / FFMAX(sc->stts_data[0].duration, 1) > 16) {
             /* more than 16 frames delay, dts are likely wrong
                this happens with files created by iMovie */
             sc->wrong_dts = 1;
@@ -1813,11 +1957,11 @@
         unsigned int rap_group_index = 0;
         unsigned int rap_group_sample = 0;
         int rap_group_present = sc->rap_group_count && sc->rap_group;
-        int key_off = (sc->keyframes && sc->keyframes[0] > 0) || (sc->stps_data && sc->stps_data[0] > 0);
+        int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_data && sc->stps_data[0] > 0);
 
         current_dts -= sc->dts_shift;
 
-        if (!sc->sample_count)
+        if (!sc->sample_count || st->nb_index_entries)
             return;
         if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
             return;
@@ -1858,7 +2002,7 @@
                 }
                 if (keyframe)
                     distance = 0;
-                sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];
+                sample_size = sc->alt_sample_size > 0 ? sc->alt_sample_size : sc->sample_sizes[current_sample];
                 if (sc->pseudo_stream_id == -1 ||
                    sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
                     AVIndexEntry *e = &st->index_entries[st->nb_index_entries++];
@@ -1973,14 +2117,14 @@
     }
 }
 
-static int mov_open_dref(AVIOContext **pb, char *src, MOVDref *ref,
-                         AVIOInterruptCB *int_cb)
+static int mov_open_dref(AVIOContext **pb, const char *src, MOVDref *ref,
+                         AVIOInterruptCB *int_cb, int use_absolute_path, AVFormatContext *fc)
 {
     /* try relative path, we do not try the absolute because it can leak information about our
        system to an attacker */
     if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
         char filename[1024];
-        char *src_path;
+        const char *src_path;
         int i, l;
 
         /* find a source dir */
@@ -2012,6 +2156,11 @@
             if (!avio_open2(pb, filename, AVIO_FLAG_READ, int_cb, NULL))
                 return 0;
         }
+    } else if (use_absolute_path) {
+        av_log(fc, AV_LOG_WARNING, "Using absolute path on user request, "
+               "this is a possible security issue\n");
+        if (!avio_open2(pb, ref->path, AVIO_FLAG_READ, int_cb, NULL))
+            return 0;
     }
 
     return AVERROR(ENOENT);
@@ -2057,7 +2206,8 @@
 
     if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
         MOVDref *dref = &sc->drefs[sc->dref_id - 1];
-        if (mov_open_dref(&sc->pb, c->fc->filename, dref, &c->fc->interrupt_callback) < 0)
+        if (mov_open_dref(&sc->pb, c->fc->filename, dref, &c->fc->interrupt_callback,
+            c->use_absolute_path, c->fc) < 0)
             av_log(c->fc, AV_LOG_ERROR,
                    "stream %d, error opening alias: path='%s', dir='%s', "
                    "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
@@ -2192,6 +2342,21 @@
     sc->width = width >> 16;
     sc->height = height >> 16;
 
+    //Assign clockwise rotate values based on transform matrix so that
+    //we can compensate for iPhone orientation during capture.
+
+    if (display_matrix[1][0] == -65536 && display_matrix[0][1] == 65536) {
+         av_dict_set(&st->metadata, "rotate", "90", 0);
+    }
+
+    if (display_matrix[0][0] == -65536 && display_matrix[1][1] == -65536) {
+         av_dict_set(&st->metadata, "rotate", "180", 0);
+    }
+
+    if (display_matrix[1][0] == 65536 && display_matrix[0][1] == -65536) {
+         av_dict_set(&st->metadata, "rotate", "270", 0);
+    }
+
     // transform the display width/height according to the matrix
     // skip this if the display matrix is the default identity matrix
     // or if it is rotating the picture, ex iPhone 3GS
@@ -2268,6 +2433,9 @@
     trex = av_realloc(c->trex_data, (c->trex_count+1)*sizeof(*c->trex_data));
     if (!trex)
         return AVERROR(ENOMEM);
+
+    c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.
+
     c->trex_data = trex;
     trex = &c->trex_data[c->trex_count++];
     avio_r8(pb); /* version */
@@ -2416,7 +2584,7 @@
     if (avio_rl32(pb) != MKTAG('d','c','o','m'))
         return AVERROR_INVALIDDATA;
     if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
-        av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !");
+        av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
         return AVERROR_INVALIDDATA;
     }
     avio_rb32(pb); /* cmvd atom */
@@ -2455,9 +2623,10 @@
 static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 {
     MOVStreamContext *sc;
-    int i, edit_count, version;
+    int i, edit_count, version, edit_start_index = 0;
+    int unsupported = 0;
 
-    if (c->fc->nb_streams < 1)
+    if (c->fc->nb_streams < 1 || c->ignore_editlist)
         return 0;
     sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
 
@@ -2468,9 +2637,11 @@
     if ((uint64_t)edit_count*12+8 > atom.size)
         return AVERROR_INVALIDDATA;
 
+    av_dlog(c->fc, "track[%i].edit_count = %i\n", c->fc->nb_streams-1, edit_count);
     for (i=0; i<edit_count; i++){
         int64_t time;
         int64_t duration;
+        int rate;
         if (version == 1) {
             duration = avio_rb64(pb);
             time     = avio_rb64(pb);
@@ -2478,22 +2649,65 @@
             duration = avio_rb32(pb); /* segment duration */
             time     = (int32_t)avio_rb32(pb); /* media time */
         }
-        avio_rb32(pb); /* Media rate */
-        if (i == 0 && time >= -1) {
-            sc->time_offset = time != -1 ? time : -duration;
-        }
+        rate = avio_rb32(pb);
+        if (i == 0 && time == -1) {
+            sc->empty_duration = duration;
+            edit_start_index = 1;
+        } else if (i == edit_start_index && time >= 0)
+            sc->start_time = time;
+        else
+            unsupported = 1;
+
+        av_dlog(c->fc, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
+                duration, time, rate / 65536.0);
     }
 
-    if (edit_count > 1)
+    if (unsupported)
         av_log(c->fc, AV_LOG_WARNING, "multiple edit list entries, "
                "a/v desync might occur, patch welcome\n");
 
-    av_dlog(c->fc, "track[%i].edit_count = %i\n", c->fc->nb_streams-1, edit_count);
+    return 0;
+}
+
+static int mov_read_chan2(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);
     return 0;
 }
 
 static const MOVParseTableEntry mov_default_parse_table[] = {
-{ MKTAG('a','v','s','s'), mov_read_extradata },
+{ MKTAG('A','C','L','R'), mov_read_avid },
+{ MKTAG('A','P','R','G'), mov_read_avid },
+{ MKTAG('A','A','L','P'), mov_read_avid },
+{ MKTAG('A','R','E','S'), mov_read_avid },
+{ MKTAG('a','v','s','s'), mov_read_avss },
 { MKTAG('c','h','p','l'), mov_read_chpl },
 { MKTAG('c','o','6','4'), mov_read_stco },
 { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
@@ -2507,7 +2721,7 @@
 { MKTAG('g','l','b','l'), mov_read_glbl },
 { MKTAG('h','d','l','r'), mov_read_hdlr },
 { MKTAG('i','l','s','t'), mov_read_ilst },
-{ MKTAG('j','p','2','h'), mov_read_extradata },
+{ MKTAG('j','p','2','h'), mov_read_jp2h },
 { MKTAG('m','d','a','t'), mov_read_mdat },
 { MKTAG('m','d','h','d'), mov_read_mdhd },
 { MKTAG('m','d','i','a'), mov_read_default },
@@ -2517,8 +2731,8 @@
 { MKTAG('m','o','o','v'), mov_read_moov },
 { MKTAG('m','v','e','x'), mov_read_default },
 { MKTAG('m','v','h','d'), mov_read_mvhd },
-{ MKTAG('S','M','I',' '), mov_read_smi }, /* Sorenson extension ??? */
-{ MKTAG('a','l','a','c'), mov_read_extradata }, /* alac specific atom */
+{ MKTAG('S','M','I',' '), mov_read_svq3 },
+{ MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
 { MKTAG('a','v','c','C'), mov_read_glbl },
 { MKTAG('p','a','s','p'), mov_read_pasp },
 { MKTAG('s','t','b','l'), mov_read_default },
@@ -2535,7 +2749,7 @@
 { 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_default },
+{ MKTAG('t','r','e','f'), mov_read_tref },
 { MKTAG('c','h','a','p'), mov_read_chap },
 { MKTAG('t','r','e','x'), mov_read_trex },
 { MKTAG('t','r','u','n'), mov_read_trun },
@@ -2561,25 +2775,33 @@
 
     if (atom.size < 0)
         atom.size = INT64_MAX;
-    while (total_size + 8 < atom.size && !pb->eof_reached) {
+    while (total_size + 8 <= atom.size && !url_feof(pb)) {
         int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
         a.size = atom.size;
         a.type=0;
         if (atom.size >= 8) {
             a.size = avio_rb32(pb);
             a.type = avio_rl32(pb);
+            if (atom.type != MKTAG('r','o','o','t') &&
+                atom.type != MKTAG('m','o','o','v'))
+            {
+                if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
+                {
+                    av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
+                    avio_skip(pb, -8);
+                    return 0;
+                }
+            }
+            total_size += 8;
+            if (a.size == 1) { /* 64 bit extended size */
+                a.size = avio_rb64(pb) - 8;
+                total_size += 8;
+            }
         }
         av_dlog(c->fc, "type: %08x '%.4s' parent:'%.4s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
                 a.type, (char*)&a.type, (char*)&atom.type, a.size, total_size, atom.size);
-        total_size += 8;
-        if (a.size == 1) { /* 64 bit extended size */
-            a.size = avio_rb64(pb) - 8;
-            total_size += 8;
-        }
         if (a.size == 0) {
-            a.size = atom.size - total_size;
-            if (a.size <= 8)
-                break;
+            a.size = atom.size - total_size + 8;
         }
         a.size -= 8;
         if (a.size < 0)
@@ -2615,6 +2837,10 @@
             left = a.size - avio_tell(pb) + start_pos;
             if (left > 0) /* skip garbage at atom end */
                 avio_skip(pb, left);
+            else if(left < 0) {
+                av_log(c->fc, AV_LOG_DEBUG, "undoing overread of %"PRId64" in '%.4s'\n", -left, (char*)&a.type);
+                avio_seek(pb, left, SEEK_CUR);
+            }
         }
 
         total_size += a.size;
@@ -2729,7 +2955,7 @@
                 if (len == 1 || len == 2)
                     title[len] = 0;
                 else
-                    avio_get_str(sc->pb, len - 2, title + 2, title_len - 2);
+                    avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
             }
         }
 
@@ -2740,6 +2966,49 @@
     avio_seek(sc->pb, cur_pos, SEEK_SET);
 }
 
+static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
+                                             uint32_t value, int flags)
+{
+    AVTimecode tc;
+    char buf[AV_TIMECODE_STR_SIZE];
+    AVRational rate = {st->codec->time_base.den,
+                       st->codec->time_base.num};
+    int ret = av_timecode_init(&tc, rate, flags, 0, s);
+    if (ret < 0)
+        return ret;
+    av_dict_set(&st->metadata, "timecode",
+                av_timecode_make_string(&tc, buf, value), 0);
+    return 0;
+}
+
+static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
+{
+    MOVStreamContext *sc = st->priv_data;
+    int flags = 0;
+    int64_t cur_pos = avio_tell(sc->pb);
+    uint32_t value;
+
+    if (!st->nb_index_entries)
+        return -1;
+
+    avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
+    value = avio_rb32(s->pb);
+
+    if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
+    if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
+    if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;
+
+    /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
+     * not the case) and thus assume "frame number format" instead of QT one.
+     * No sample with tmcd track can be found with a QT timecode at the moment,
+     * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
+     * format). */
+    parse_timecode_in_framenum_format(s, st, value, flags);
+
+    avio_seek(sc->pb, cur_pos, SEEK_SET);
+    return 0;
+}
+
 static int mov_read_close(AVFormatContext *s)
 {
     MOVContext *mov = s->priv_data;
@@ -2755,8 +3024,16 @@
             av_freep(&sc->drefs[j].dir);
         }
         av_freep(&sc->drefs);
+        av_freep(&sc->trefs);
         if (sc->pb && sc->pb != s->pb)
             avio_close(sc->pb);
+        sc->pb = NULL;
+        av_freep(&sc->chunk_offsets);
+        av_freep(&sc->keyframes);
+        av_freep(&sc->sample_sizes);
+        av_freep(&sc->stps_data);
+        av_freep(&sc->stsc_data);
+        av_freep(&sc->stts_data);
     }
 
     if (mov->dv_demux) {
@@ -2773,11 +3050,47 @@
     return 0;
 }
 
+static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
+{
+    int i, j;
+
+    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;
+    }
+    return 0;
+}
+
+/* look for a tmcd track not referenced by any video track, and export it globally */
+static void export_orphan_timecode(AVFormatContext *s)
+{
+    int i;
+
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st = s->streams[i];
+
+        if (st->codec->codec_tag  == MKTAG('t','m','c','d') &&
+            !tmcd_is_referenced(s, i + 1)) {
+            AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
+            if (tcr) {
+                av_dict_set(&s->metadata, "timecode", tcr->value, 0);
+                break;
+            }
+        }
+    }
+}
+
 static int mov_read_header(AVFormatContext *s)
 {
     MOVContext *mov = s->priv_data;
     AVIOContext *pb = s->pb;
-    int err;
+    int i, err;
     MOVAtom atom = { AV_RL32("root") };
 
     mov->fc = s;
@@ -2800,11 +3113,40 @@
     }
     av_dlog(mov->fc, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
 
-    if (pb->seekable && mov->chapter_track > 0)
-        mov_read_chapters(s);
+    if (pb->seekable) {
+        if (mov->chapter_track > 0)
+            mov_read_chapters(s);
+        for (i = 0; i < s->nb_streams; i++)
+            if (s->streams[i]->codec->codec_tag == AV_RL32("tmcd"))
+                mov_read_timecode_track(s, s->streams[i]);
+    }
+
+    /* copy timecode metadata from tmcd tracks to the related video streams */
+    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) {
+            AVDictionaryEntry *tcr;
+            int tmcd_st_id = sc->trefs[0] - 1;
+
+            if (tmcd_st_id < 0 || tmcd_st_id >= s->nb_streams)
+                continue;
+            tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
+            if (tcr)
+                av_dict_set(&st->metadata, "timecode", tcr->value, 0);
+        }
+    }
+    export_orphan_timecode(s);
+
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st = s->streams[i];
+        MOVStreamContext *sc = st->priv_data;
+        if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->codec_id == AV_CODEC_ID_AAC) {
+            st->skip_samples = sc->start_pad;
+        }
+    }
 
     if (mov->trex_data) {
-        int i;
         for (i = 0; i < s->nb_streams; i++) {
             AVStream *st = s->streams[i];
             MOVStreamContext *sc = st->priv_data;
@@ -2849,6 +3191,7 @@
     AVIndexEntry *sample;
     AVStream *st = NULL;
     int ret;
+    mov->fc = s;
  retry:
     sample = mov_find_next_sample(s, &st);
     if (!sample) {
@@ -2858,7 +3201,7 @@
         avio_seek(s->pb, mov->next_root_atom, SEEK_SET);
         mov->next_root_atom = 0;
         if (mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX }) < 0 ||
-            s->pb->eof_reached)
+            url_feof(s->pb))
             return AVERROR_EOF;
         av_dlog(s, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
         goto retry;
@@ -2889,7 +3232,7 @@
         }
 #if CONFIG_DV_DEMUXER
         if (mov->dv_demux && sc->dv_audio_container) {
-            avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size);
+            avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
             av_free(pkt->data);
             pkt->size = 0;
             ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
@@ -2966,8 +3309,6 @@
 
     if (stream_index >= s->nb_streams)
         return AVERROR_INVALIDDATA;
-    if (sample_time < 0)
-        sample_time = 0;
 
     st = s->streams[stream_index];
     sample = mov_seek_stream(s, st, sample_time, flags);
@@ -2978,7 +3319,10 @@
     seek_timestamp = st->index_entries[sample].timestamp;
 
     for (i = 0; i < s->nb_streams; i++) {
+        MOVStreamContext *sc = s->streams[i]->priv_data;
         st = s->streams[i];
+        st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
+
         if (stream_index == i)
             continue;
 
@@ -2988,6 +3332,23 @@
     return 0;
 }
 
+static const AVOption options[] = {
+    {"use_absolute_path",
+        "allow using absolute path when opening alias, this is a possible security issue",
+        offsetof(MOVContext, use_absolute_path), FF_OPT_TYPE_INT, {.i64 = 0},
+        0, 1, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM},
+    {"ignore_editlist", "", offsetof(MOVContext, ignore_editlist), FF_OPT_TYPE_INT, {.i64 = 0},
+        0, 1, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM},
+    {NULL}
+};
+
+static const AVClass class = {
+    .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVInputFormat ff_mov_demuxer = {
     .name           = "mov,mp4,m4a,3gp,3g2,mj2",
     .long_name      = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
@@ -2997,4 +3358,5 @@
     .read_packet    = mov_read_packet,
     .read_close     = mov_read_close,
     .read_seek      = mov_read_seek,
+    .priv_class     = &class,
 };
diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c
index 00a2a4b..58aec57 100644
--- a/libavformat/mov_chan.c
+++ b/libavformat/mov_chan.c
@@ -570,6 +570,7 @@
         avio_rl32(pb);                      // mCoordinates[0]
         avio_rl32(pb);                      // mCoordinates[1]
         avio_rl32(pb);                      // mCoordinates[2]
+        size -= 20;
         if (layout_tag == 0) {
             uint32_t mask_incr = mov_get_channel_label(label);
             if (mask_incr == 0) {
@@ -584,6 +585,7 @@
             st->codec->channel_layout = label_mask;
     } else
         st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap);
+    avio_skip(pb, size - 12);
 
     return 0;
 }
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 50371cd..8316c30 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2004 Gildas Bazin <gbazin at videolan dot org>
  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -46,19 +46,22 @@
 static const AVOption options[] = {
     { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
     { "rtphint", "Add RTP hint tracks", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+    { "moov_size", "maximum moov size so it can be placed at the begin", offsetof(MOVMuxContext, reserved_moov_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 0 },
     { "empty_moov", "Make the initial moov atom empty (not supported by QuickTime)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_EMPTY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
     { "frag_keyframe", "Fragment at video keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_KEYFRAME}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
     { "separate_moof", "Write separate moof/mdat atoms for each track", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SEPARATE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
     { "frag_custom", "Flush fragments on caller requests", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_CUSTOM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
     { "isml", "Create a live smooth streaming feed (for pushing to a publishing point)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_ISML}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
+    { "faststart", "Run a second pass to put the moov at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
     FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
-    { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
+    { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
     { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
     { "iods_video_profile", "iods video profile atom.", offsetof(MOVMuxContext, iods_video_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
     { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
     { "min_frag_duration", "Minimum fragment duration", offsetof(MOVMuxContext, min_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
     { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
     { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
+    { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
     { NULL },
 };
 
@@ -81,21 +84,41 @@
     return curpos - pos;
 }
 
+static int supports_edts(MOVMuxContext *mov)
+{
+    // EDTS with fragments is tricky as we dont know the duration when its written
+    return (mov->use_editlist<0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) || mov->use_editlist>0;
+}
+
+static int is_co64_required(const MOVTrack *track)
+{
+    int i;
+
+    for (i = 0; i < track->entry; i++) {
+        if (!track->cluster[i].chunkNum)
+            continue;
+        if (track->cluster[i].pos + track->data_offset > UINT32_MAX)
+            return 1;
+    }
+    return 0;
+}
+
 /* Chunk offset atom */
 static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
 {
     int i;
-    int mode64 = 0; //   use 32 bit size variant if possible
+    int mode64 = is_co64_required(track); // use 32 bit size variant if possible
     int64_t pos = avio_tell(pb);
     avio_wb32(pb, 0); /* size */
-    if (pos > UINT32_MAX) {
-        mode64 = 1;
+    if (mode64)
         ffio_wfourcc(pb, "co64");
-    } else
+    else
         ffio_wfourcc(pb, "stco");
     avio_wb32(pb, 0); /* version & flags */
-    avio_wb32(pb, track->entry); /* entry count */
+    avio_wb32(pb, track->chunkCount); /* entry count */
     for (i=0; i<track->entry; i++) {
+        if(!track->cluster[i].chunkNum)
+            continue;
         if(mode64 == 1)
             avio_wb64(pb, track->cluster[i].pos + track->data_offset);
         else
@@ -153,11 +176,11 @@
     ffio_wfourcc(pb, "stsc");
     avio_wb32(pb, 0); // version & flags
     entryPos = avio_tell(pb);
-    avio_wb32(pb, track->entry); // entry count
+    avio_wb32(pb, track->chunkCount); // entry count
     for (i=0; i<track->entry; i++) {
-        if (oldval != track->cluster[i].samples_in_chunk)
+        if (oldval != track->cluster[i].samples_in_chunk && track->cluster[i].chunkNum)
         {
-            avio_wb32(pb, i+1); // first chunk
+            avio_wb32(pb, track->cluster[i].chunkNum); // first chunk
             avio_wb32(pb, track->cluster[i].samples_in_chunk); // samples per chunk
             avio_wb32(pb, 0x1); // sample description index
             oldval = track->cluster[i].samples_in_chunk;
@@ -264,6 +287,22 @@
     return track->enc->extradata_size;
 }
 
+static int mov_write_enda_tag(AVIOContext *pb)
+{
+    avio_wb32(pb, 10);
+    ffio_wfourcc(pb, "enda");
+    avio_wb16(pb, 1); /* little endian */
+    return 10;
+}
+
+static int mov_write_enda_tag_be(AVIOContext *pb)
+{
+  avio_wb32(pb, 10);
+  ffio_wfourcc(pb, "enda");
+  avio_wb16(pb, 0); /* big endian */
+  return 10;
+}
+
 static void put_descr(AVIOContext *pb, int tag, unsigned int size)
 {
     int i = 3;
@@ -273,10 +312,22 @@
     avio_w8(pb, size & 0x7F);
 }
 
+static unsigned compute_avg_bitrate(MOVTrack *track)
+{
+    uint64_t size = 0;
+    int i;
+    if (!track->track_duration)
+        return 0;
+    for (i = 0; i < track->entry; i++)
+        size += track->cluster[i].size;
+    return size * 8 * track->timescale / track->track_duration;
+}
+
 static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
 {
     int64_t pos = avio_tell(pb);
     int decoder_specific_info_len = track->vos_len ? 5 + track->vos_len : 0;
+    unsigned avg_bitrate;
 
     avio_wb32(pb, 0); // size
     ffio_wfourcc(pb, "esds");
@@ -308,11 +359,10 @@
     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_wb32(pb, FFMAX(track->enc->bit_rate, track->enc->rc_max_rate)); // maxbitrate (FIXME should be max rate in any 1 sec window)
-    if(track->enc->rc_max_rate != track->enc->rc_min_rate || track->enc->rc_min_rate==0)
-        avio_wb32(pb, 0); // vbr
-    else
-        avio_wb32(pb, track->enc->rc_max_rate); // avg bitrate
+    avg_bitrate = compute_avg_bitrate(track);
+    // maxbitrate (FIXME should be max rate in any 1 sec window)
+    avio_wb32(pb, FFMAX3(track->enc->bit_rate, track->enc->rc_max_rate, avg_bitrate));
+    avio_wb32(pb, avg_bitrate);
 
     if (track->vos_len) {
         // DecoderSpecific info descriptor
@@ -326,6 +376,22 @@
     return update_size(pb, pos);
 }
 
+static int mov_pcm_le_gt16(enum AVCodecID codec_id)
+{
+    return codec_id == AV_CODEC_ID_PCM_S24LE ||
+           codec_id == AV_CODEC_ID_PCM_S32LE ||
+           codec_id == AV_CODEC_ID_PCM_F32LE ||
+           codec_id == AV_CODEC_ID_PCM_F64LE;
+}
+
+static int mov_pcm_be_gt16(enum AVCodecID codec_id)
+{
+    return codec_id == AV_CODEC_ID_PCM_S24BE ||
+           codec_id == AV_CODEC_ID_PCM_S32BE ||
+           codec_id == AV_CODEC_ID_PCM_F32BE ||
+           codec_id == AV_CODEC_ID_PCM_F64BE;
+}
+
 static int mov_write_ms_tag(AVIOContext *pb, MOVTrack *track)
 {
     int64_t pos = avio_tell(pb);
@@ -377,9 +443,11 @@
     avio_wb32(pb, 0);     /* size */
     ffio_wfourcc(pb, "wave");
 
+    if (track->enc->codec_id != AV_CODEC_ID_QDM2) {
     avio_wb32(pb, 12);    /* size */
     ffio_wfourcc(pb, "frma");
     avio_wl32(pb, track->tag);
+    }
 
     if (track->enc->codec_id == AV_CODEC_ID_AAC) {
         /* useless atom needed by mplayer, ipod, not needed by quicktime */
@@ -387,11 +455,16 @@
         ffio_wfourcc(pb, "mp4a");
         avio_wb32(pb, 0);
         mov_write_esds_tag(pb, track);
+    } else if (mov_pcm_le_gt16(track->enc->codec_id))  {
+      mov_write_enda_tag(pb);
+    } else if (mov_pcm_be_gt16(track->enc->codec_id))  {
+      mov_write_enda_tag_be(pb);
     } else if (track->enc->codec_id == AV_CODEC_ID_AMR_NB) {
         mov_write_amr_tag(pb, track);
     } else if (track->enc->codec_id == AV_CODEC_ID_AC3) {
         mov_write_ac3_tag(pb, track);
-    } else if (track->enc->codec_id == AV_CODEC_ID_ALAC) {
+    } else if (track->enc->codec_id == AV_CODEC_ID_ALAC ||
+               track->enc->codec_id == AV_CODEC_ID_QDM2) {
         mov_write_extradata_tag(pb, track);
     } else if (track->enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
                track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
@@ -552,6 +625,8 @@
 {
     int i, first_duration;
 
+// return track->enc->frame_size;
+
     /* use 1 for raw PCM */
     if (!track->audio_vbr)
         return 1;
@@ -574,9 +649,17 @@
     uint32_t tag = track->tag;
 
     if (track->mode == MODE_MOV) {
-        if (mov_get_lpcm_flags(track->enc->codec_id))
-            tag = AV_RL32("lpcm");
-        version = 2;
+        if (track->timescale > UINT16_MAX) {
+            if (mov_get_lpcm_flags(track->enc->codec_id))
+                tag = AV_RL32("lpcm");
+            version = 2;
+        } else if (track->audio_vbr || mov_pcm_le_gt16(track->enc->codec_id) ||
+                   mov_pcm_be_gt16(track->enc->codec_id) ||
+                   track->enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
+                   track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
+                   track->enc->codec_id == AV_CODEC_ID_QDM2) {
+            version = 1;
+        }
     }
 
     avio_wb32(pb, 0); /* size */
@@ -605,10 +688,19 @@
         avio_wb32(pb, track->sample_size);
         avio_wb32(pb, get_samples_per_packet(track));
     } else {
-        /* reserved for mp4/3gp */
-        avio_wb16(pb, 2);
-        avio_wb16(pb, 16);
-        avio_wb16(pb, 0);
+        if (track->mode == MODE_MOV) {
+            avio_wb16(pb, track->enc->channels);
+            if (track->enc->codec_id == AV_CODEC_ID_PCM_U8 ||
+                track->enc->codec_id == AV_CODEC_ID_PCM_S8)
+                avio_wb16(pb, 8); /* bits per sample */
+            else
+                avio_wb16(pb, 16);
+            avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
+        } else { /* reserved for mp4/3gp */
+            avio_wb16(pb, 2);
+            avio_wb16(pb, 16);
+            avio_wb16(pb, 0);
+        }
 
         avio_wb16(pb, 0); /* packet size (= 0) */
         avio_wb16(pb, track->enc->sample_rate <= UINT16_MAX ?
@@ -616,13 +708,27 @@
         avio_wb16(pb, 0); /* Reserved */
     }
 
+    if(version == 1) { /* SoundDescription V1 extended info */
+        if (mov_pcm_le_gt16(track->enc->codec_id) ||
+            mov_pcm_be_gt16(track->enc->codec_id))
+            avio_wb32(pb, 1); /*  must be 1 for  uncompressed formats */
+        else
+            avio_wb32(pb, track->enc->frame_size); /* Samples per packet */
+        avio_wb32(pb, track->sample_size / track->enc->channels); /* Bytes per packet */
+        avio_wb32(pb, track->sample_size); /* Bytes per frame */
+        avio_wb32(pb, 2); /* Bytes per sample */
+    }
+
     if(track->mode == MODE_MOV &&
        (track->enc->codec_id == AV_CODEC_ID_AAC ||
         track->enc->codec_id == AV_CODEC_ID_AC3 ||
         track->enc->codec_id == AV_CODEC_ID_AMR_NB ||
         track->enc->codec_id == AV_CODEC_ID_ALAC ||
         track->enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
-        track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV))
+        track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
+        track->enc->codec_id == AV_CODEC_ID_QDM2 ||
+        (mov_pcm_le_gt16(track->enc->codec_id) && version==1) ||
+        (mov_pcm_be_gt16(track->enc->codec_id) && version==1)))
         mov_write_wave_tag(pb, track);
     else if(track->tag == MKTAG('m','p','4','a'))
         mov_write_esds_tag(pb, track);
@@ -655,19 +761,6 @@
     return 0xf;
 }
 
-/* TODO: No idea about these values */
-static int mov_write_svq3_tag(AVIOContext *pb)
-{
-    avio_wb32(pb, 0x15);
-    ffio_wfourcc(pb, "SMI ");
-    ffio_wfourcc(pb, "SEQH");
-    avio_wb32(pb, 0x5);
-    avio_wb32(pb, 0xe2c0211d);
-    avio_wb32(pb, 0xc0000000);
-    avio_w8(pb, 0);
-    return 0x15;
-}
-
 static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
 {
     int64_t pos = avio_tell(pb);
@@ -802,6 +895,7 @@
     uint32_t tag;
     unsigned bps;
 } mov_pix_fmt_tags[] = {
+    { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','2'),  0 },
     { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','s'),  0 },
     { AV_PIX_FMT_UYVY422, MKTAG('2','v','u','y'),  0 },
     { AV_PIX_FMT_RGB555BE,MKTAG('r','a','w',' '), 16 },
@@ -827,7 +921,8 @@
         if (track->enc->pix_fmt == mov_pix_fmt_tags[i].pix_fmt) {
             tag = mov_pix_fmt_tags[i].tag;
             track->enc->bits_per_coded_sample = mov_pix_fmt_tags[i].bps;
-            break;
+            if (track->enc->codec_tag == mov_pix_fmt_tags[i].tag)
+                break;
         }
     }
 
@@ -883,6 +978,14 @@
     { AV_CODEC_ID_NONE, 0 },
 };
 
+static const AVCodecTag codec_f4v_tags[] = { // XXX: add GIF/PNG/JPEG?
+    { AV_CODEC_ID_MP3,    MKTAG('.','m','p','3') },
+    { AV_CODEC_ID_AAC,    MKTAG('m','p','4','a') },
+    { AV_CODEC_ID_H264,   MKTAG('a','v','c','1') },
+    { AV_CODEC_ID_VP6F,   MKTAG('V','P','6','F') },
+    { AV_CODEC_ID_NONE, 0 },
+};
+
 static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
 {
     int tag;
@@ -897,6 +1000,8 @@
         tag = ipod_get_codec_tag(s, track);
     else if (track->mode & MODE_3GP)
         tag = ff_codec_get_tag(codec_3gp_tags, track->enc->codec_id);
+    else if (track->mode & MODE_F4V)
+        tag = ff_codec_get_tag(codec_f4v_tags, track->enc->codec_id);
     else
         tag = mov_get_codec_tag(s, track);
 
@@ -1013,9 +1118,11 @@
         mov_write_esds_tag(pb, track);
     else if(track->enc->codec_id == AV_CODEC_ID_H263)
         mov_write_d263_tag(pb);
-    else if(track->enc->codec_id == AV_CODEC_ID_SVQ3)
-        mov_write_svq3_tag(pb);
-    else if(track->enc->codec_id == AV_CODEC_ID_DNXHD)
+    else if(track->enc->codec_id == AV_CODEC_ID_AVUI ||
+            track->enc->codec_id == AV_CODEC_ID_SVQ3) {
+        mov_write_extradata_tag(pb, track);
+        avio_wb32(pb, 0);
+    } else if(track->enc->codec_id == AV_CODEC_ID_DNXHD)
         mov_write_avid_tag(pb, track);
     else if(track->enc->codec_id == AV_CODEC_ID_H264) {
         mov_write_avcc_tag(pb, track);
@@ -1036,6 +1143,26 @@
     return update_size(pb, pos);
 }
 
+static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
+{
+    int64_t pos = avio_tell(pb);
+    int frame_duration = track->enc->time_base.num;
+    int nb_frames = (track->timescale + frame_duration/2) / frame_duration;
+
+    avio_wb32(pb, 0); /* size */
+    ffio_wfourcc(pb, "tmcd");               /* Data format */
+    avio_wb32(pb, 0);                       /* Reserved */
+    avio_wb32(pb, 1);                       /* Data reference index */
+    avio_wb32(pb, 0);                       /* Flags */
+    avio_wb32(pb, track->timecode_flags);   /* Flags (timecode) */
+    avio_wb32(pb, track->timescale);        /* Timescale */
+    avio_wb32(pb, frame_duration);          /* Frame duration */
+    avio_w8(pb, nb_frames);                 /* Number of frames */
+    avio_wb24(pb, 0);                       /* Reserved */
+    /* TODO: source reference string */
+    return update_size(pb, pos);
+}
+
 static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
 {
     int64_t pos = avio_tell(pb);
@@ -1071,6 +1198,8 @@
         mov_write_subtitle_tag(pb, track);
     else if (track->enc->codec_tag == MKTAG('r','t','p',' '))
         mov_write_rtp_tag(pb, track);
+    else if (track->enc->codec_tag == MKTAG('t','m','c','d'))
+        mov_write_tmcd_tag(pb, track);
     return update_size(pb, pos);
 }
 
@@ -1157,6 +1286,7 @@
     avio_wb32(pb, 1); /* entry count */
 
     avio_wb32(pb, 0xc); /* size */
+    //FIXME add the alis and rsrc atom
     ffio_wfourcc(pb, "url ");
     avio_wb32(pb, 1); /* version & flags */
 
@@ -1202,9 +1332,32 @@
     return 12;
 }
 
-static int mov_write_gmhd_tag(AVIOContext *pb)
+static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
 {
-    avio_wb32(pb, 0x20);   /* size */
+    int64_t pos = avio_tell(pb);
+    const char *font = "Lucida Grande";
+    avio_wb32(pb, 0);                   /* size */
+    ffio_wfourcc(pb, "tcmi");           /* timecode media information atom */
+    avio_wb32(pb, 0);                   /* version & flags */
+    avio_wb16(pb, 0);                   /* text font */
+    avio_wb16(pb, 0);                   /* text face */
+    avio_wb16(pb, 12);                  /* text size */
+    avio_wb16(pb, 0);                   /* (unknown, not in the QT specs...) */
+    avio_wb16(pb, 0x0000);              /* text color (red) */
+    avio_wb16(pb, 0x0000);              /* text color (green) */
+    avio_wb16(pb, 0x0000);              /* text color (blue) */
+    avio_wb16(pb, 0xffff);              /* background color (red) */
+    avio_wb16(pb, 0xffff);              /* background color (green) */
+    avio_wb16(pb, 0xffff);              /* background color (blue) */
+    avio_w8(pb, strlen(font));          /* font len (part of the pascal string) */
+    avio_write(pb, font, strlen(font)); /* font name */
+    return update_size(pb, pos);
+}
+
+static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
+{
+    int64_t pos = avio_tell(pb);
+    avio_wb32(pb, 0);      /* size */
     ffio_wfourcc(pb, "gmhd");
     avio_wb32(pb, 0x18);   /* gmin size */
     ffio_wfourcc(pb, "gmin");/* generic media info */
@@ -1215,7 +1368,34 @@
     avio_wb16(pb, 0x8000); /* opColor (b?) */
     avio_wb16(pb, 0);      /* balance */
     avio_wb16(pb, 0);      /* reserved */
-    return 0x20;
+
+    /*
+     * This special text atom is required for
+     * Apple Quicktime chapters. The contents
+     * don't appear to be documented, so the
+     * bytes are copied verbatim.
+     */
+    avio_wb32(pb, 0x2C);   /* size */
+    ffio_wfourcc(pb, "text");
+    avio_wb16(pb, 0x01);
+    avio_wb32(pb, 0x00);
+    avio_wb32(pb, 0x00);
+    avio_wb32(pb, 0x00);
+    avio_wb32(pb, 0x01);
+    avio_wb32(pb, 0x00);
+    avio_wb32(pb, 0x00);
+    avio_wb32(pb, 0x00);
+    avio_wb32(pb, 0x00004000);
+    avio_wb16(pb, 0x0000);
+
+    if (track->enc->codec_tag == MKTAG('t','m','c','d')) {
+        int64_t tmcd_pos = avio_tell(pb);
+        avio_wb32(pb, 0); /* size */
+        ffio_wfourcc(pb, "tmcd");
+        mov_write_tcmi_tag(pb, track);
+        update_size(pb, tmcd_pos);
+    }
+    return update_size(pb, pos);
 }
 
 static int mov_write_smhd_tag(AVIOContext *pb)
@@ -1258,9 +1438,16 @@
             if (track->tag == MKTAG('t','x','3','g')) hdlr_type = "sbtl";
             else                                      hdlr_type = "text";
             descr = "SubtitleHandler";
+        } else if (track->enc->codec_tag == MKTAG('t','m','c','d')) {
+            hdlr_type = "tmcd";
+            descr = "TimeCodeHandler";
         } else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) {
             hdlr_type = "hint";
             descr = "HintHandler";
+        } else {
+            hdlr = "dhlr";
+            hdlr_type = "url ";
+            descr = "DataHandler";
         }
     }
 
@@ -1305,8 +1492,10 @@
     else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
         mov_write_smhd_tag(pb);
     else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
-        if (track->tag == MKTAG('t','e','x','t')) mov_write_gmhd_tag(pb);
+        if (track->tag == MKTAG('t','e','x','t')) mov_write_gmhd_tag(pb, track);
         else                                      mov_write_nmhd_tag(pb);
+    } else if (track->tag == MKTAG('t','m','c','d')) {
+        mov_write_gmhd_tag(pb, track);
     } else if (track->tag == MKTAG('r','t','p',' ')) {
         mov_write_hmhd_tag(pb);
     }
@@ -1364,11 +1553,30 @@
     return update_size(pb, pos);
 }
 
+/* transformation matrix
+     |a  b  u|
+     |c  d  v|
+     |tx ty w| */
+static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
+                         int16_t d, int16_t tx, int16_t ty)
+{
+    avio_wb32(pb, a << 16);  /* 16.16 format */
+    avio_wb32(pb, b << 16);  /* 16.16 format */
+    avio_wb32(pb, 0);        /* u in 2.30 format */
+    avio_wb32(pb, c << 16);  /* 16.16 format */
+    avio_wb32(pb, d << 16);  /* 16.16 format */
+    avio_wb32(pb, 0);        /* v in 2.30 format */
+    avio_wb32(pb, tx << 16); /* 16.16 format */
+    avio_wb32(pb, ty << 16); /* 16.16 format */
+    avio_wb32(pb, 1 << 30);  /* w in 2.30 format */
+}
+
 static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
 {
     int64_t duration = av_rescale_rnd(track->track_duration, MOV_TIMESCALE,
                                       track->timescale, AV_ROUND_UP);
     int version = duration < INT32_MAX ? 0 : 1;
+    int rotation = 0;
 
     if (track->mode == MODE_ISM)
         version = 1;
@@ -1403,16 +1611,19 @@
     avio_wb16(pb, 0); /* reserved */
 
     /* Matrix structure */
-    avio_wb32(pb, 0x00010000); /* reserved */
-    avio_wb32(pb, 0x0); /* reserved */
-    avio_wb32(pb, 0x0); /* reserved */
-    avio_wb32(pb, 0x0); /* reserved */
-    avio_wb32(pb, 0x00010000); /* reserved */
-    avio_wb32(pb, 0x0); /* reserved */
-    avio_wb32(pb, 0x0); /* reserved */
-    avio_wb32(pb, 0x0); /* reserved */
-    avio_wb32(pb, 0x40000000); /* reserved */
-
+    if (st && st->metadata) {
+        AVDictionaryEntry *rot = av_dict_get(st->metadata, "rotate", NULL, 0);
+        rotation = (rot && rot->value) ? atoi(rot->value) : 0;
+    }
+    if (rotation == 90) {
+        write_matrix(pb,  0,  1, -1,  0, track->enc->height, 0);
+    } else if (rotation == 180) {
+        write_matrix(pb, -1,  0,  0, -1, track->enc->width, track->enc->height);
+    } else if (rotation == 270) {
+        write_matrix(pb,  0, -1,  1,  0, 0, track->enc->width);
+    } else {
+        write_matrix(pb,  1,  0,  0,  1, 0, 0);
+    }
     /* Track width and height, for visual only */
     if(st && (track->enc->codec_type == AVMEDIA_TYPE_VIDEO ||
               track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
@@ -1493,6 +1704,10 @@
             avio_wb32(pb, -1);
         }
         avio_wb32(pb, 0x00010000);
+    } else {
+        av_assert0(track->cluster[0].dts <= 0);
+        start_ct  = -track->cluster[0].dts;
+        duration += delay;
     }
 
     /* duration */
@@ -1562,11 +1777,8 @@
     avio_wb32(pb, 0); /* size */
     ffio_wfourcc(pb, "trak");
     mov_write_tkhd_tag(pb, track, st);
-    if (track->mode == MODE_PSP || track->flags & MOV_TRACK_CTTS ||
-        (track->entry && track->cluster[0].dts)) {
-        if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
-            mov_write_edts_tag(pb, track);  // PSP Movies require edts box
-    }
+    if (supports_edts(mov))
+        mov_write_edts_tag(pb, track);  // PSP Movies and several other cases require edts box
     if (track->tref_tag)
         mov_write_tref_tag(pb, track);
     mov_write_mdia_tag(pb, track);
@@ -1576,7 +1788,7 @@
         mov_write_udta_sdp(pb, track->rtp_ctx, track->track_id);
     if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO && track->mode == MODE_MOV) {
         double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
-        if (0.0 != sample_aspect_ratio && 1.0 != sample_aspect_ratio)
+        if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio)
             mov_write_tapt_tag(pb, track);
     };
     return update_size(pb, pos);
@@ -1676,15 +1888,7 @@
     avio_wb32(pb, 0); /* reserved */
 
     /* Matrix structure */
-    avio_wb32(pb, 0x00010000); /* reserved */
-    avio_wb32(pb, 0x0); /* reserved */
-    avio_wb32(pb, 0x0); /* reserved */
-    avio_wb32(pb, 0x0); /* reserved */
-    avio_wb32(pb, 0x00010000); /* reserved */
-    avio_wb32(pb, 0x0); /* reserved */
-    avio_wb32(pb, 0x0); /* reserved */
-    avio_wb32(pb, 0x0); /* reserved */
-    avio_wb32(pb, 0x40000000); /* reserved */
+    write_matrix(pb, 1, 0, 0, 1, 0, 0);
 
     avio_wb32(pb, 0); /* reserved (preview time) */
     avio_wb32(pb, 0); /* reserved (preview duration) */
@@ -1768,6 +1972,24 @@
     return mov_write_string_tag(pb, name, t->value, lang, long_style);
 }
 
+/* iTunes bpm number */
+static int mov_write_tmpo_tag(AVIOContext *pb, AVFormatContext *s)
+{
+    AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
+    int size = 0, tmpo = t ? atoi(t->value) : 0;
+    if (tmpo) {
+        size = 26;
+        avio_wb32(pb, size);
+        ffio_wfourcc(pb, "tmpo");
+        avio_wb32(pb, size-8); /* size */
+        ffio_wfourcc(pb, "data");
+        avio_wb32(pb, 0x15);  //type specifier
+        avio_wb32(pb, 0);
+        avio_wb16(pb, tmpo);        // data
+    }
+    return size;
+}
+
 /* iTunes track number */
 static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov,
                               AVFormatContext *s)
@@ -1815,6 +2037,7 @@
     mov_write_string_metadata(s, pb, "tven",    "episode_id",1);
     mov_write_string_metadata(s, pb, "tvnn",    "network"  , 1);
     mov_write_trkn_tag(pb, mov, s);
+    mov_write_tmpo_tag(pb, s);
     return update_size(pb, pos);
 }
 
@@ -1924,32 +2147,35 @@
     if(ret < 0)
         return ret;
 
-        if (mov->mode & MODE_3GP) {
-            mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
-            mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
-            mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
-            mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
-            mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
-            mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
-            mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
-            mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
-        } else if (mov->mode == MODE_MOV) { // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4
-            mov_write_string_metadata(s, pb_buf, "\251ART", "artist"     , 0);
-            mov_write_string_metadata(s, pb_buf, "\251nam", "title"      , 0);
-            mov_write_string_metadata(s, pb_buf, "\251aut", "author"     , 0);
-            mov_write_string_metadata(s, pb_buf, "\251alb", "album"      , 0);
-            mov_write_string_metadata(s, pb_buf, "\251day", "date"       , 0);
-            mov_write_string_metadata(s, pb_buf, "\251swr", "encoder"    , 0);
-            mov_write_string_metadata(s, pb_buf, "\251des", "comment"    , 0);
-            mov_write_string_metadata(s, pb_buf, "\251gen", "genre"      , 0);
-            mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright"  , 0);
-        } else {
-            /* iTunes meta data */
-            mov_write_meta_tag(pb_buf, mov, s);
-        }
+    if (mov->mode & MODE_3GP) {
+        mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
+        mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
+        mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
+        mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
+        mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
+        mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
+        mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
+        mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
+    } else if (mov->mode == MODE_MOV) { // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4
+        mov_write_string_metadata(s, pb_buf, "\251ART", "artist"     , 0);
+        mov_write_string_metadata(s, pb_buf, "\251nam", "title"      , 0);
+        mov_write_string_metadata(s, pb_buf, "\251aut", "author"     , 0);
+        mov_write_string_metadata(s, pb_buf, "\251alb", "album"      , 0);
+        mov_write_string_metadata(s, pb_buf, "\251day", "date"       , 0);
+        mov_write_string_metadata(s, pb_buf, "\251swr", "encoder"    , 0);
+        // currently ignored by mov.c
+        mov_write_string_metadata(s, pb_buf, "\251des", "comment"    , 0);
+        // add support for libquicktime, this atom is also actually read by mov.c
+        mov_write_string_metadata(s, pb_buf, "\251cmt", "comment"    , 0);
+        mov_write_string_metadata(s, pb_buf, "\251gen", "genre"      , 0);
+        mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright"  , 0);
+    } else {
+        /* iTunes meta data */
+        mov_write_meta_tag(pb_buf, mov, s);
+    }
 
-        if (s->nb_chapters)
-            mov_write_chpl_tag(pb_buf, s);
+    if (s->nb_chapters)
+        mov_write_chpl_tag(pb_buf, s);
 
     if ((size = avio_close_dyn_buf(pb_buf, &buf)) > 0) {
         avio_wb32(pb, size+8);
@@ -2011,6 +2237,29 @@
     return 0;
 }
 
+static void build_chunks(MOVTrack *trk)
+{
+    int i;
+    MOVIentry *chunk= &trk->cluster[0];
+    uint64_t chunkSize = chunk->size;
+    chunk->chunkNum= 1;
+    if (trk->chunkCount)
+        return;
+    trk->chunkCount= 1;
+    for(i=1; i<trk->entry; i++){
+        if(chunk->pos + chunkSize == trk->cluster[i].pos &&
+            chunkSize + trk->cluster[i].size < (1<<20)){
+            chunkSize             += trk->cluster[i].size;
+            chunk->samples_in_chunk += trk->cluster[i].entries;
+        }else{
+            trk->cluster[i].chunkNum = chunk->chunkNum+1;
+            chunk=&trk->cluster[i];
+            chunkSize = chunk->size;
+            trk->chunkCount++;
+        }
+    }
+}
+
 static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,
                               AVFormatContext *s)
 {
@@ -2025,6 +2274,9 @@
 
         mov->tracks[i].time = mov->time;
         mov->tracks[i].track_id = i+1;
+
+        if (mov->tracks[i].entry)
+            build_chunks(&mov->tracks[i]);
     }
 
     if (mov->chapter_track)
@@ -2039,6 +2291,14 @@
                 mov->tracks[mov->tracks[i].src_track].track_id;
         }
     }
+    for (i = 0; i < mov->nb_streams; i++) {
+        if (mov->tracks[i].tag == MKTAG('t','m','c','d')) {
+            int src_trk = mov->tracks[i].src_track;
+            mov->tracks[src_trk].tref_tag = mov->tracks[i].tag;
+            mov->tracks[src_trk].tref_id  = mov->tracks[i].track_id;
+            mov->tracks[i].track_duration = mov->tracks[src_trk].track_duration;
+        }
+    }
 
     mov_write_mvhd_tag(pb, mov);
     if (mov->mode != MODE_MOV && !mov->iods_skip)
@@ -2495,6 +2755,8 @@
         ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
     else if (mov->mode == MODE_ISM)
         ffio_wfourcc(pb, "isml");
+    else if (mov->mode == MODE_F4V)
+        ffio_wfourcc(pb, "f4v ");
     else
         ffio_wfourcc(pb, "qt  ");
 
@@ -2662,6 +2924,21 @@
     }
 }
 
+static int get_moov_size(AVFormatContext *s)
+{
+    int ret;
+    uint8_t *buf;
+    AVIOContext *moov_buf;
+    MOVMuxContext *mov = s->priv_data;
+
+    if ((ret = avio_open_dyn_buf(&moov_buf)) < 0)
+        return ret;
+    mov_write_moov_tag(moov_buf, mov, s);
+    ret = avio_close_dyn_buf(moov_buf, &buf);
+    av_free(buf);
+    return ret;
+}
+
 static int mov_flush_fragment(AVFormatContext *s)
 {
     MOVMuxContext *mov = s->priv_data;
@@ -2673,10 +2950,8 @@
 
     if (!(mov->flags & FF_MOV_FLAG_EMPTY_MOOV) && mov->fragments == 0) {
         int64_t pos = avio_tell(s->pb);
-        int ret;
-        AVIOContext *moov_buf;
         uint8_t *buf;
-        int buf_size;
+        int buf_size, moov_size;
 
         for (i = 0; i < mov->nb_streams; i++)
             if (!mov->tracks[i].entry)
@@ -2685,13 +2960,9 @@
         if (i < mov->nb_streams)
             return 0;
 
-        if ((ret = avio_open_dyn_buf(&moov_buf)) < 0)
-            return ret;
-        mov_write_moov_tag(moov_buf, mov, s);
-        buf_size = avio_close_dyn_buf(moov_buf, &buf);
-        av_free(buf);
+        moov_size = get_moov_size(s);
         for (i = 0; i < mov->nb_streams; i++)
-            mov->tracks[i].data_offset = pos + buf_size + 8;
+            mov->tracks[i].data_offset = pos + moov_size + 8;
 
         mov_write_moov_tag(s->pb, mov, s);
 
@@ -2829,6 +3100,9 @@
             av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
             return -1;
         }
+    } else if (enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
+               enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
+        samples_in_chunk = enc->frame_size;
     } else if (trk->sample_size)
         samples_in_chunk = size / trk->sample_size;
     else
@@ -2851,6 +3125,10 @@
         } else {
             size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size);
         }
+    } else if (enc->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
+               (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
+        av_log(s, AV_LOG_ERROR, "malformated aac bitstream, use -absf aac_adtstoasc\n");
+        return -1;
     } else {
         avio_write(pb, pkt->data, size);
     }
@@ -2866,13 +3144,14 @@
     }
 
     if (!(trk->entry % MOV_INDEX_CLUSTER_SIZE)) {
-        trk->cluster = av_realloc(trk->cluster, (trk->entry + MOV_INDEX_CLUSTER_SIZE) * sizeof(*trk->cluster));
+        trk->cluster = av_realloc_f(trk->cluster, sizeof(*trk->cluster), (trk->entry + MOV_INDEX_CLUSTER_SIZE));
         if (!trk->cluster)
             return -1;
     }
 
     trk->cluster[trk->entry].pos = avio_tell(pb) - size;
     trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
+    trk->cluster[trk->entry].chunkNum = 0;
     trk->cluster[trk->entry].size = size;
     trk->cluster[trk->entry].entries = samples_in_chunk;
     trk->cluster[trk->entry].dts = pkt->dts;
@@ -2883,9 +3162,13 @@
          * of this packet to be what the previous packets duration implies. */
         trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
     }
+    if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !supports_edts(mov)) {
+        trk->cluster[trk->entry].dts = trk->start_dts = 0;
+    }
     if (trk->start_dts == AV_NOPTS_VALUE)
         trk->start_dts = pkt->dts;
     trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
+    trk->last_sample_is_subtitle_end = 0;
 
     if (pkt->pts == AV_NOPTS_VALUE) {
         av_log(s, AV_LOG_WARNING, "pts has no value\n");
@@ -2922,12 +3205,8 @@
     return 0;
 }
 
-static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
+static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    if (!pkt) {
-        mov_flush_fragment(s);
-        return 1;
-    } else {
         MOVMuxContext *mov = s->priv_data;
         MOVTrack *trk = &mov->tracks[pkt->stream_index];
         AVCodecContext *enc = trk->enc;
@@ -2936,7 +3215,7 @@
 
         if (!pkt->size) return 0; /* Discard 0 sized packets */
 
-        if (trk->entry)
+        if (trk->entry && pkt->stream_index < s->nb_streams)
             frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
                                          s->streams[pkt->stream_index]->time_base,
                                          AV_TIME_BASE_Q);
@@ -2951,6 +3230,73 @@
         }
 
         return ff_mov_write_packet(s, pkt);
+}
+
+static int mov_write_subtitle_end_packet(AVFormatContext *s,
+                                         int stream_index,
+                                         int64_t dts) {
+    AVPacket end;
+    uint8_t data[2] = {0};
+    int ret;
+
+    av_init_packet(&end);
+    end.size = sizeof(data);
+    end.data = data;
+    end.pts = dts;
+    end.dts = dts;
+    end.duration = 0;
+    end.stream_index = stream_index;
+
+    ret = mov_write_single_packet(s, &end);
+    av_free_packet(&end);
+
+    return ret;
+}
+
+static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    if (!pkt) {
+        mov_flush_fragment(s);
+        return 1;
+    } else {
+        int i;
+        MOVMuxContext *mov = s->priv_data;
+
+        if (!pkt->size) return 0; /* Discard 0 sized packets */
+
+        /*
+         * Subtitles require special handling.
+         *
+         * 1) For full complaince, every track must have a sample at
+         * dts == 0, which is rarely true for subtitles. So, as soon
+         * as we see any packet with dts > 0, write an empty subtitle
+         * at dts == 0 for any subtitle track with no samples in it.
+         *
+         * 2) For each subtitle track, check if the current packet's
+         * dts is past the duration of the last subtitle sample. If
+         * so, we now need to write an end sample for that subtitle.
+         *
+         * This must be done conditionally to allow for subtitles that
+         * immediately replace each other, in which case an end sample
+         * is not needed, and is, in fact, actively harmful.
+         *
+         * 3) See mov_write_trailer for how the final end sample is
+         * handled.
+         */
+        for (i = 0; i < mov->nb_streams; i++) {
+            MOVTrack *trk = &mov->tracks[i];
+            int ret;
+
+            if (trk->enc->codec_id == AV_CODEC_ID_MOV_TEXT &&
+                trk->track_duration < pkt->dts &&
+                (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
+                ret = mov_write_subtitle_end_packet(s, i, trk->track_duration);
+                if (ret < 0) return ret;
+                trk->last_sample_is_subtitle_end = 1;
+            }
+        }
+
+        return mov_write_single_packet(s, pkt);
     }
 }
 
@@ -2958,6 +3304,8 @@
 // as samples, and a tref pointing from the other tracks to the chapter one.
 static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
 {
+    AVIOContext *pb;
+
     MOVMuxContext *mov = s->priv_data;
     MOVTrack *track = &mov->tracks[tracknum];
     AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY };
@@ -2969,6 +3317,50 @@
     track->enc = avcodec_alloc_context3(NULL);
     track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
 
+    if (avio_open_dyn_buf(&pb) >= 0) {
+        int size;
+        uint8_t *buf;
+
+        /* Stub header (usually for Quicktime chapter track) */
+        // TextSampleEntry
+        avio_wb32(pb, 0x01); // displayFlags
+        avio_w8(pb, 0x00);   // horizontal justification
+        avio_w8(pb, 0x00);   // vertical justification
+        avio_w8(pb, 0x00);   // bgColourRed
+        avio_w8(pb, 0x00);   // bgColourGreen
+        avio_w8(pb, 0x00);   // bgColourBlue
+        avio_w8(pb, 0x00);   // bgColourAlpha
+        // BoxRecord
+        avio_wb16(pb, 0x00); // defTextBoxTop
+        avio_wb16(pb, 0x00); // defTextBoxLeft
+        avio_wb16(pb, 0x00); // defTextBoxBottom
+        avio_wb16(pb, 0x00); // defTextBoxRight
+        // StyleRecord
+        avio_wb16(pb, 0x00); // startChar
+        avio_wb16(pb, 0x00); // endChar
+        avio_wb16(pb, 0x01); // fontID
+        avio_w8(pb, 0x00);   // fontStyleFlags
+        avio_w8(pb, 0x00);   // fontSize
+        avio_w8(pb, 0x00);   // fgColourRed
+        avio_w8(pb, 0x00);   // fgColourGreen
+        avio_w8(pb, 0x00);   // fgColourBlue
+        avio_w8(pb, 0x00);   // fgColourAlpha
+        // FontTableBox
+        avio_wb32(pb, 0x0D); // box size
+        ffio_wfourcc(pb, "ftab"); // box atom name
+        avio_wb16(pb, 0x01); // entry count
+        // FontRecord
+        avio_wb16(pb, 0x01); // font ID
+        avio_w8(pb, 0x00);   // font name length
+
+        if ((size = avio_close_dyn_buf(pb, &buf)) > 0) {
+            track->enc->extradata = buf;
+            track->enc->extradata_size = size;
+        } else {
+            av_free(&buf);
+        }
+    }
+
     for (i = 0; i < s->nb_chapters; i++) {
         AVChapter *c = s->chapters[i];
         AVDictionaryEntry *t;
@@ -2989,12 +3381,56 @@
     }
 }
 
+static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, const char *tcstr)
+{
+    int ret;
+    MOVMuxContext *mov  = s->priv_data;
+    MOVTrack *track     = &mov->tracks[index];
+    AVStream *src_st    = s->streams[src_index];
+    AVTimecode tc;
+    AVPacket pkt    = {.stream_index = index, .flags = AV_PKT_FLAG_KEY, .size = 4};
+    AVRational rate = {src_st->codec->time_base.den, src_st->codec->time_base.num};
+
+    /* if the codec time base makes no sense, try to fallback on stream frame rate */
+    if (av_timecode_check_frame_rate(rate) < 0) {
+        av_log(s, AV_LOG_DEBUG, "timecode: tbc=%d/%d invalid, fallback on %d/%d\n",
+               rate.num, rate.den, src_st->avg_frame_rate.num, src_st->avg_frame_rate.den);
+        rate = src_st->avg_frame_rate;
+    }
+
+    /* compute the frame number */
+    ret = av_timecode_init_from_string(&tc, rate, tcstr, s);
+    if (ret < 0)
+        return ret;
+
+    /* tmcd track based on video stream */
+    track->mode      = mov->mode;
+    track->tag       = MKTAG('t','m','c','d');
+    track->src_track = src_index;
+    track->timescale = mov->tracks[src_index].timescale;
+    if (tc.flags & AV_TIMECODE_FLAG_DROPFRAME)
+        track->timecode_flags |= MOV_TIMECODE_FLAG_DROPFRAME;
+
+    /* encode context: tmcd data stream */
+    track->enc = avcodec_alloc_context3(NULL);
+    track->enc->codec_type = AVMEDIA_TYPE_DATA;
+    track->enc->codec_tag  = track->tag;
+    track->enc->time_base  = src_st->codec->time_base;
+
+    /* the tmcd track just contains one packet with the frame number */
+    pkt.data = av_malloc(pkt.size);
+    AV_WB32(pkt.data, tc.start);
+    ret = ff_mov_write_packet(s, &pkt);
+    av_free(pkt.data);
+    return ret;
+}
+
 static int mov_write_header(AVFormatContext *s)
 {
     AVIOContext *pb = s->pb;
     MOVMuxContext *mov = s->priv_data;
-    AVDictionaryEntry *t;
-    int i, hint_track = 0;
+    AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
+    int i, hint_track = 0, tmcd_track = 0;
 
     /* Set the FRAGMENT flag if any of the fragmentation methods are
      * enabled. */
@@ -3004,6 +3440,18 @@
                       FF_MOV_FLAG_FRAG_CUSTOM))
         mov->flags |= FF_MOV_FLAG_FRAGMENT;
 
+    /* faststart: moov at the beginning of the file, if supported */
+    if (mov->flags & FF_MOV_FLAG_FASTSTART) {
+        if (mov->flags & FF_MOV_FLAG_FRAGMENT)
+            mov->flags &= ~FF_MOV_FLAG_FASTSTART;
+        else
+            mov->reserved_moov_size = -1;
+    }
+
+    if (!supports_edts(mov) && s->avoid_negative_ts < 0) {
+        s->avoid_negative_ts = 1;
+    }
+
     /* Non-seekable output is ok if using fragmentation. If ism_lookahead
      * is enabled, we don't support non-seekable output at all. */
     if (!s->pb->seekable &&
@@ -3024,6 +3472,7 @@
         else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
         else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
         else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM;
+        else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;
 
         mov_write_ftyp_tag(pb,s);
         if (mov->mode == MODE_PSP) {
@@ -3051,6 +3500,32 @@
         }
     }
 
+    if (mov->mode == MODE_MOV) {
+        tmcd_track = mov->nb_streams;
+
+        /* +1 tmcd track for each video stream with a timecode */
+        for (i = 0; i < s->nb_streams; i++) {
+            AVStream *st = s->streams[i];
+            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+                (global_tcr || av_dict_get(st->metadata, "timecode", NULL, 0)))
+                mov->nb_meta_tmcd++;
+        }
+
+        /* check if there is already a tmcd track to remux */
+        if (mov->nb_meta_tmcd) {
+            for (i = 0; i < s->nb_streams; i++) {
+                AVStream *st = s->streams[i];
+                if (st->codec->codec_tag == MKTAG('t','m','c','d')) {
+                    av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
+                           "so timecode metadata are now ignored\n");
+                    mov->nb_meta_tmcd = 0;
+                }
+            }
+        }
+
+        mov->nb_streams += mov->nb_meta_tmcd;
+    }
+
     mov->tracks = av_mallocz(mov->nb_streams*sizeof(*mov->tracks));
     if (!mov->tracks)
         return AVERROR(ENOMEM);
@@ -3086,6 +3561,8 @@
                 track->height = track->tag>>24 == 'n' ? 486 : 576;
             }
             track->timescale = st->codec->time_base.den;
+            while(track->timescale < 10000)
+                track->timescale *= 2;
             if (track->mode == MODE_MOV && track->timescale > 100000)
                 av_log(s, AV_LOG_WARNING,
                        "WARNING codec timebase is very high. If duration is too long,\n"
@@ -3093,18 +3570,21 @@
                        "or choose different container.\n");
         }else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO){
             track->timescale = st->codec->sample_rate;
-            /* set sample_size for PCM and ADPCM */
-            if (av_get_bits_per_sample(st->codec->codec_id) ||
-                st->codec->codec_id == AV_CODEC_ID_ILBC) {
+            if(!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) {
+                av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
+                track->audio_vbr = 1;
+            }else if(st->codec->codec_id == AV_CODEC_ID_ADPCM_MS ||
+                     st->codec->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
+                     st->codec->codec_id == AV_CODEC_ID_ILBC){
                 if (!st->codec->block_align) {
-                    av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set\n", i);
+                    av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
                     goto error;
                 }
                 track->sample_size = st->codec->block_align;
-            }
-            /* set audio_vbr for compressed audio */
-            if (av_get_bits_per_sample(st->codec->codec_id) < 8) {
+            }else if(st->codec->frame_size > 1){ /* assume compressed audio */
                 track->audio_vbr = 1;
+            }else{
+                track->sample_size = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels;
             }
             if (track->mode != MODE_MOV &&
                 track->enc->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
@@ -3114,6 +3594,8 @@
             }
         }else if(st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE){
             track->timescale = st->codec->time_base.den;
+        }else{
+            track->timescale = MOV_TIMESCALE;
         }
         if (!track->height)
             track->height = st->codec->height;
@@ -3142,6 +3624,12 @@
                       FF_MOV_FLAG_FRAGMENT;
     }
 
+    if(mov->reserved_moov_size){
+        mov->reserved_moov_pos= avio_tell(pb);
+        if (mov->reserved_moov_size > 0)
+            avio_skip(pb, mov->reserved_moov_size);
+    }
+
     if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
         mov_write_mdat_tag(pb, mov);
 
@@ -3165,6 +3653,24 @@
         }
     }
 
+    if (mov->nb_meta_tmcd) {
+        /* Initialize the tmcd tracks */
+        for (i = 0; i < s->nb_streams; i++) {
+            AVStream *st = s->streams[i];
+            t = global_tcr;
+
+            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+                if (!t)
+                    t = av_dict_get(st->metadata, "timecode", NULL, 0);
+                if (!t)
+                    continue;
+                if (mov_create_timecode_track(s, tmcd_track, i, t->value) < 0)
+                    goto error;
+                tmcd_track++;
+            }
+        }
+    }
+
     avio_flush(pb);
 
     if (mov->flags & FF_MOV_FLAG_ISML)
@@ -3181,14 +3687,122 @@
     return -1;
 }
 
+/**
+ * This function gets the moov size if moved to the top of the file: the chunk
+ * offset table can switch between stco (32-bit entries) to co64 (64-bit
+ * entries) when the moov is moved to the top, so the size of the moov would
+ * change. It also updates the chunk offset tables.
+ */
+static int compute_moov_size(AVFormatContext *s)
+{
+    int i, moov_size, moov_size2;
+    MOVMuxContext *mov = s->priv_data;
+
+    moov_size = get_moov_size(s);
+    if (moov_size < 0)
+        return moov_size;
+
+    for (i = 0; i < mov->nb_streams; i++)
+        mov->tracks[i].data_offset += moov_size;
+
+    moov_size2 = get_moov_size(s);
+    if (moov_size2 < 0)
+        return moov_size2;
+
+    /* if the size changed, we just switched from stco to co64 and needs to
+     * update the offsets */
+    if (moov_size2 != moov_size)
+        for (i = 0; i < mov->nb_streams; i++)
+            mov->tracks[i].data_offset += moov_size2 - moov_size;
+
+    return moov_size2;
+}
+
+static int shift_data(AVFormatContext *s)
+{
+    int ret = 0, moov_size;
+    MOVMuxContext *mov = s->priv_data;
+    int64_t pos, pos_end = avio_tell(s->pb);
+    uint8_t *buf, *read_buf[2];
+    int read_buf_id = 0;
+    int read_size[2];
+    AVIOContext *read_pb;
+
+    moov_size = compute_moov_size(s);
+    if (moov_size < 0)
+        return moov_size;
+
+    buf = av_malloc(moov_size * 2);
+    if (!buf)
+        return AVERROR(ENOMEM);
+    read_buf[0] = buf;
+    read_buf[1] = buf + moov_size;
+
+    /* Shift the data: the AVIO context of the output can only be used for
+     * writing, so we re-open the same output, but for reading. It also avoids
+     * a read/seek/write/seek back and forth. */
+    avio_flush(s->pb);
+    ret = avio_open(&read_pb, s->filename, AVIO_FLAG_READ);
+    if (ret < 0) {
+        av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for "
+               "the second pass (faststart)\n", s->filename);
+        goto end;
+    }
+
+    /* mark the end of the shift to up to the last data we wrote, and get ready
+     * for writing */
+    pos_end = avio_tell(s->pb);
+    avio_seek(s->pb, mov->reserved_moov_pos + moov_size, SEEK_SET);
+
+    /* start reading at where the new moov will be placed */
+    avio_seek(read_pb, mov->reserved_moov_pos, SEEK_SET);
+    pos = avio_tell(read_pb);
+
+#define READ_BLOCK do {                                                             \
+    read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], moov_size);  \
+    read_buf_id ^= 1;                                                               \
+} while (0)
+
+    /* shift data by chunk of at most moov_size */
+    READ_BLOCK;
+    do {
+        int n;
+        READ_BLOCK;
+        n = read_size[read_buf_id];
+        if (n <= 0)
+            break;
+        avio_write(s->pb, read_buf[read_buf_id], n);
+        pos += n;
+    } while (pos < pos_end);
+    avio_close(read_pb);
+
+end:
+    av_free(buf);
+    return ret;
+}
+
 static int mov_write_trailer(AVFormatContext *s)
 {
     MOVMuxContext *mov = s->priv_data;
     AVIOContext *pb = s->pb;
+    int64_t moov_pos;
     int res = 0;
     int i;
 
-    int64_t moov_pos = avio_tell(pb);
+    /*
+     * Before actually writing the trailer, make sure that there are no
+     * dangling subtitles, that need a terminating sample.
+     */
+    for (i = 0; i < mov->nb_streams; i++) {
+        MOVTrack *trk = &mov->tracks[i];
+        if (trk->enc->codec_id == AV_CODEC_ID_MOV_TEXT &&
+            !trk->last_sample_is_subtitle_end) {
+            mov_write_subtitle_end_packet(s, i, trk->track_duration);
+            trk->last_sample_is_subtitle_end = 1;
+        }
+    }
+
+    moov_pos = avio_tell(pb);
 
     if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
         /* Write size of mdat tag */
@@ -3204,9 +3818,31 @@
             ffio_wfourcc(pb, "mdat");
             avio_wb64(pb, mov->mdat_size + 16);
         }
-        avio_seek(pb, moov_pos, SEEK_SET);
+        avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_moov_pos : moov_pos, SEEK_SET);
 
-        mov_write_moov_tag(pb, mov, s);
+        if (mov->reserved_moov_size == -1) {
+            av_log(s, AV_LOG_INFO, "Starting second pass: moving header on top of the file\n");
+            res = shift_data(s);
+            if (res == 0) {
+                avio_seek(s->pb, mov->reserved_moov_pos, SEEK_SET);
+                mov_write_moov_tag(pb, mov, s);
+            }
+        } else if (mov->reserved_moov_size > 0) {
+            int64_t size;
+            mov_write_moov_tag(pb, mov, s);
+            size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_moov_pos);
+            if(size < 8){
+                av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
+                return -1;
+            }
+            avio_wb32(pb, size);
+            ffio_wfourcc(pb, "free");
+            for(i=0; i<size; i++)
+                avio_w8(pb, 0);
+            avio_seek(pb, moov_pos, SEEK_SET);
+        } else {
+            mov_write_moov_tag(pb, mov, s);
+        }
     } else {
         mov_flush_fragment(s);
         mov_write_mfra_tag(pb, mov);
@@ -3218,6 +3854,8 @@
     for (i=0; i<mov->nb_streams; i++) {
         if (mov->tracks[i].tag == MKTAG('r','t','p',' '))
             ff_mov_close_hinting(&mov->tracks[i]);
+        else if (mov->tracks[i].tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
+            av_freep(&mov->tracks[i].enc);
         if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
             mov->tracks[i].vc1_info.struct_offset && s->pb->seekable) {
             int64_t off = avio_tell(pb);
@@ -3368,3 +4006,21 @@
     .priv_class        = &ismv_muxer_class,
 };
 #endif
+#if CONFIG_F4V_MUXER
+MOV_CLASS(f4v)
+AVOutputFormat ff_f4v_muxer = {
+    .name              = "f4v",
+    .long_name         = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
+    .mime_type         = "application/f4v",
+    .extensions        = "f4v",
+    .priv_data_size    = sizeof(MOVMuxContext),
+    .audio_codec       = AV_CODEC_ID_AAC,
+    .video_codec       = AV_CODEC_ID_H264,
+    .write_header      = mov_write_header,
+    .write_packet      = mov_write_packet,
+    .write_trailer     = mov_write_trailer,
+    .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
+    .codec_tag         = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
+    .priv_class        = &f4v_muxer_class,
+};
+#endif
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index e20ef14..b5d066f 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -4,20 +4,20 @@
  * Copyright (c) 2004 Gildas Bazin <gbazin at videolan dot org>
  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -35,16 +35,18 @@
 #define MODE_MOV  0x02
 #define MODE_3GP  0x04
 #define MODE_PSP  0x08 // example working PSP command line:
-// avconv -i testinput.avi  -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4
+// ffmpeg -i testinput.avi  -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4
 #define MODE_3G2  0x10
 #define MODE_IPOD 0x20
 #define MODE_ISM  0x40
+#define MODE_F4V  0x80
 
 typedef struct MOVIentry {
     uint64_t     pos;
     int64_t      dts;
     unsigned int size;
     unsigned int samples_in_chunk;
+    unsigned int chunkNum;              ///< Chunk number if the current entry is a chunk start otherwise 0
     unsigned int entries;
     int          cts;
 #define MOV_SYNC_SAMPLE         0x0001
@@ -79,12 +81,18 @@
     unsigned    timescale;
     uint64_t    time;
     int64_t     track_duration;
+    int         last_sample_is_subtitle_end;
     long        sample_count;
     long        sample_size;
+    long        chunkCount;
     int         has_keyframes;
 #define MOV_TRACK_CTTS         0x0001
 #define MOV_TRACK_STPS         0x0002
     uint32_t    flags;
+#define MOV_TIMECODE_FLAG_DROPFRAME     0x0001
+#define MOV_TIMECODE_FLAG_24HOURSMAX    0x0002
+#define MOV_TIMECODE_FLAG_ALLOWNEGATIVE 0x0004
+    uint32_t    timecode_flags;
     int         language;
     int         track_id;
     int         tag; ///< stsd fourcc
@@ -100,7 +108,7 @@
     int64_t     start_dts;
 
     int         hint_track;   ///< the track that hints this track, -1 if no hint track is set
-    int         src_track;    ///< the track that this hint track describes
+    int         src_track;    ///< the track that this hint (or tmcd) track describes
     AVFormatContext *rtp_ctx; ///< the format context for the hinting rtp muxer
     uint32_t    prev_rtp_ts;
     int64_t     cur_rtp_ts_unwrapped;
@@ -136,6 +144,7 @@
     int     mode;
     int64_t time;
     int     nb_streams;
+    int     nb_meta_tmcd;  ///< number of new created tmcd track based on metadata (aka not data copy)
     int     chapter_track; ///< qt chapter track number
     int64_t mdat_pos;
     uint64_t mdat_size;
@@ -143,6 +152,9 @@
 
     int flags;
     int rtp_flags;
+    int reserved_moov_size; ///< 0 for disabled, -1 for automatic, size otherwise
+    int64_t reserved_moov_pos;
+
     int iods_skip;
     int iods_video_profile;
     int iods_audio_profile;
@@ -153,6 +165,8 @@
     int max_fragment_size;
     int ism_lookahead;
     AVIOContext *mdat_buf;
+
+    int use_editlist;
 } MOVMuxContext;
 
 #define FF_MOV_FLAG_RTP_HINT 1
@@ -162,6 +176,7 @@
 #define FF_MOV_FLAG_SEPARATE_MOOF 16
 #define FF_MOV_FLAG_FRAG_CUSTOM 32
 #define FF_MOV_FLAG_ISML 64
+#define FF_MOV_FLAG_FASTSTART 128
 
 int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);
 
diff --git a/libavformat/movenchint.c b/libavformat/movenchint.c
index 5ef90f1..9c4ddeb 100644
--- a/libavformat/movenchint.c
+++ b/libavformat/movenchint.c
@@ -2,20 +2,20 @@
  * MOV, 3GP, MP4 muxer RTP hinting
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c
index 7d0c2fb..ae54975 100644
--- a/libavformat/mp3dec.c
+++ b/libavformat/mp3dec.c
@@ -2,20 +2,20 @@
  * MP3 demuxer
  * Copyright (c) 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -35,6 +35,13 @@
 
 #define XING_TOC_COUNT 100
 
+typedef struct {
+    int64_t filesize;
+    int xing_toc;
+    int start_pad;
+    int end_pad;
+} MP3Context;
+
 /* mp3 read */
 
 static int mp3_read_probe(AVProbeData *p)
@@ -69,37 +76,20 @@
     }
     // keep this in sync with ac3 probe, both need to avoid
     // issues with MPEG-files!
-    if (first_frames >= 4) return AVPROBE_SCORE_MAX / 2 + 1;
-
-    if (max_frames) {
-        int pes = 0, i;
-        unsigned int code = -1;
-
-#define VIDEO_ID 0x000001e0
-#define AUDIO_ID 0x000001c0
-        /* do a search for mpegps headers to be able to properly bias
-         * towards mpegps if we detect this stream as both. */
-        for (i = 0; i<p->buf_size; i++) {
-            code = (code << 8) + p->buf[i];
-            if ((code & 0xffffff00) == 0x100) {
-                if     ((code & 0x1f0) == VIDEO_ID) pes++;
-                else if((code & 0x1e0) == AUDIO_ID) pes++;
-            }
-        }
-
-        if (pes)
-            max_frames = (max_frames + pes - 1) / pes;
-    }
-    if      (max_frames >  500) return AVPROBE_SCORE_MAX / 2;
-    else if (max_frames >= 4)   return AVPROBE_SCORE_MAX / 4;
-    else if (max_frames >= 1)   return 1;
-    else                        return 0;
+    if   (first_frames>=4) return AVPROBE_SCORE_MAX/2+1;
+    else if(max_frames>200)return AVPROBE_SCORE_MAX/2;
+    else if(max_frames>=4) return AVPROBE_SCORE_MAX/4;
+    else if(ff_id3v2_match(buf0, ID3v2_DEFAULT_MAGIC) && 2*ff_id3v2_tag_len(buf0) >= p->buf_size)
+                           return AVPROBE_SCORE_MAX/8;
+    else if(max_frames>=1) return 1;
+    else                   return 0;
 //mpegps_mp3_unrecognized_format.mpg has max_frames=3
 }
 
 static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration)
 {
     int i;
+    MP3Context *mp3 = s->priv_data;
 
     if (!filesize &&
         !(filesize = avio_size(s->pb))) {
@@ -115,6 +105,7 @@
                            av_rescale(i, duration, XING_TOC_COUNT),
                            0, 0, AVINDEX_KEYFRAME);
     }
+    mp3->xing_toc = 1;
 }
 
 /**
@@ -122,6 +113,7 @@
  */
 static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base)
 {
+    MP3Context *mp3 = s->priv_data;
     uint32_t v, spf;
     unsigned frames = 0; /* Total number of frames in file */
     unsigned size = 0; /* Total number of bytes in the stream */
@@ -152,6 +144,18 @@
         if (v & XING_FLAG_TOC && frames)
             read_xing_toc(s, size, av_rescale_q(frames, (AVRational){spf, c.sample_rate},
                                     st->time_base));
+        if(v & 8)
+            avio_skip(s->pb, 4);
+
+        v = avio_rb32(s->pb);
+        if(v == MKBETAG('L', 'A', 'M', 'E') || v == MKBETAG('L', 'a', 'v', 'f')) {
+            avio_skip(s->pb, 21-4);
+            v= avio_rb24(s->pb);
+            mp3->start_pad = v>>12;
+            mp3->  end_pad = v&4095;
+            st->skip_samples = mp3->start_pad + 528 + 1;
+            av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3->  end_pad);
+        }
     }
 
     /* Check for VBRI tag (always 32 bytes after end of mpegaudio header) */
@@ -184,6 +188,7 @@
 
 static int mp3_read_header(AVFormatContext *s)
 {
+    MP3Context *mp3 = s->priv_data;
     AVStream *st;
     int64_t off;
 
@@ -193,17 +198,21 @@
 
     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codec->codec_id = AV_CODEC_ID_MP3;
-    st->need_parsing = AVSTREAM_PARSE_FULL;
+    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
     st->start_time = 0;
 
     // lcm of all mp3 sample rates
     avpriv_set_pts_info(st, 64, 1, 14112000);
 
+    s->pb->maxsize = -1;
     off = avio_tell(s->pb);
 
     if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
         ff_id3v1_read(s);
 
+    if(s->pb->seekable)
+        mp3->filesize = avio_size(s->pb);
+
     if (mp3_parse_vbr_tags(s, st, off) < 0)
         avio_seek(s->pb, off, SEEK_SET);
 
@@ -215,15 +224,26 @@
 
 static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
-    int ret;
+    MP3Context *mp3 = s->priv_data;
+    int ret, size;
+    int64_t pos;
 
-    ret = av_get_packet(s->pb, pkt, MP3_PACKET_SIZE);
-    if (ret < 0)
-        return ret;
+    size= MP3_PACKET_SIZE;
+    pos = avio_tell(s->pb);
+    if(mp3->filesize > ID3v1_TAG_SIZE && pos < mp3->filesize)
+        size= FFMIN(size, mp3->filesize - pos);
 
+    ret= av_get_packet(s->pb, pkt, size);
+    if (ret <= 0) {
+        if(ret<0)
+            return ret;
+        return AVERROR_EOF;
+    }
+
+    pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
     pkt->stream_index = 0;
 
-    if (ret > ID3v1_TAG_SIZE &&
+    if (ret >= ID3v1_TAG_SIZE &&
         memcmp(&pkt->data[ret - ID3v1_TAG_SIZE], "TAG", 3) == 0)
         ret -= ID3v1_TAG_SIZE;
 
@@ -236,11 +256,18 @@
 static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
                     int flags)
 {
+    MP3Context *mp3 = s->priv_data;
     AVIndexEntry *ie;
     AVStream *st = s->streams[0];
     int64_t ret  = av_index_search_timestamp(st, timestamp, flags);
     uint32_t header = 0;
 
+    if (!mp3->xing_toc) {
+        st->skip_samples = timestamp <= 0 ? mp3->start_pad + 528 + 1 : 0;
+
+        return -1;
+    }
+
     if (ret < 0)
         return ret;
 
@@ -254,6 +281,9 @@
         if (ff_mpa_check_header(header) >= 0) {
             ff_update_cur_dts(s, st, ie->timestamp);
             ret = avio_seek(s->pb, -4, SEEK_CUR);
+
+            st->skip_samples = ie->timestamp <= 0 ? mp3->start_pad + 528 + 1 : 0;
+
             return (ret >= 0) ? 0 : ret;
         }
     }
@@ -264,6 +294,7 @@
 AVInputFormat ff_mp3_demuxer = {
     .name           = "mp3",
     .long_name      = NULL_IF_CONFIG_SMALL("MP2/3 (MPEG audio layer 2/3)"),
+    .priv_data_size = sizeof(MP3Context),
     .read_probe     = mp3_read_probe,
     .read_header    = mp3_read_header,
     .read_packet    = mp3_read_packet,
diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c
index c969777..3c7c4aa 100644
--- a/libavformat/mp3enc.c
+++ b/libavformat/mp3enc.c
@@ -2,20 +2,20 @@
  * MP3 muxer
  * Copyright (c) 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,6 +30,10 @@
 #include "libavcodec/mpegaudiodecheader.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/opt.h"
+#include "libavcodec/mpegaudio.h"
+#include "libavcodec/mpegaudiodata.h"
+#include "libavcodec/mpegaudiodecheader.h"
+#include "libavformat/avio_internal.h"
 #include "libavutil/dict.h"
 #include "libavutil/avassert.h"
 
@@ -51,11 +55,12 @@
     buf[0] = 'T';
     buf[1] = 'A';
     buf[2] = 'G';
-    count += id3v1_set_string(s, "TIT2",    buf +  3, 30);       //title
-    count += id3v1_set_string(s, "TPE1",    buf + 33, 30);       //author|artist
-    count += id3v1_set_string(s, "TALB",    buf + 63, 30);       //album
-    count += id3v1_set_string(s, "TDRL",    buf + 93,  4);       //date
-    count += id3v1_set_string(s, "comment", buf + 97, 30);
+    /* we knowingly overspecify each tag length by one byte to compensate for the mandatory null byte added by av_strlcpy */
+    count += id3v1_set_string(s, "TIT2",    buf +  3, 30 + 1);       //title
+    count += id3v1_set_string(s, "TPE1",    buf + 33, 30 + 1);       //author|artist
+    count += id3v1_set_string(s, "TALB",    buf + 63, 30 + 1);       //album
+    count += id3v1_set_string(s, "TDRL",    buf + 93,  4 + 1);       //date
+    count += id3v1_set_string(s, "comment", buf + 97, 30 + 1);
     if ((tag = av_dict_get(s->metadata, "TRCK", NULL, 0))) { //track
         buf[125] = 0;
         buf[126] = atoi(tag->value);
@@ -110,19 +115,22 @@
 /*
  * Write an empty XING header and initialize respective data.
  */
-static void mp3_write_xing(AVFormatContext *s)
+static int mp3_write_xing(AVFormatContext *s)
 {
     MP3Context       *mp3 = s->priv_data;
     AVCodecContext *codec = s->streams[mp3->audio_stream_idx]->codec;
-    int32_t        header;
-    MPADecodeHeader  mpah;
-    int srate_idx, i, channels;
-    int bitrate_idx;
-    int xing_offset;
-    int ver = 0;
+    int              bitrate_idx;
+    int              best_bitrate_idx = -1;
+    int              best_bitrate_error= INT_MAX;
+    int              xing_offset;
+    int32_t          header, mask;
+    MPADecodeHeader  c;
+    int              srate_idx, ver = 0, i, channels;
+    int              needed;
+    const char      *vendor = (codec->flags & CODEC_FLAG_BITEXACT) ? "Lavf" : LIBAVFORMAT_IDENT;
 
     if (!s->pb->seekable)
-        return;
+        return 0;
 
     for (i = 0; i < FF_ARRAY_ELEMS(avpriv_mpa_freq_tab); i++) {
         const uint16_t base_freq = avpriv_mpa_freq_tab[i];
@@ -136,9 +144,8 @@
         break;
     }
     if (i == FF_ARRAY_ELEMS(avpriv_mpa_freq_tab)) {
-        av_log(s, AV_LOG_WARNING, "Unsupported sample rate, not writing Xing "
-               "header.\n");
-        return;
+        av_log(s, AV_LOG_WARNING, "Unsupported sample rate, not writing Xing header.\n");
+        return -1;
     }
 
     switch (codec->channels) {
@@ -146,41 +153,76 @@
     case 2:  channels = MPA_STEREO;                                        break;
     default: av_log(s, AV_LOG_WARNING, "Unsupported number of channels, "
                     "not writing Xing header.\n");
-             return;
+             return -1;
     }
 
-    /* 64 kbps frame, should be large enough */
-    bitrate_idx = (ver == 3) ? 5 : 8;
-
     /* dummy MPEG audio header */
     header  =  0xff                                  << 24; // sync
     header |= (0x7 << 5 | ver << 3 | 0x1 << 1 | 0x1) << 16; // sync/audio-version/layer 3/no crc*/
-    header |= (bitrate_idx << 4 | srate_idx << 2)    <<  8;
+    header |= (srate_idx << 2) <<  8;
     header |= channels << 6;
+
+    for (bitrate_idx=1; bitrate_idx<15; bitrate_idx++) {
+        int error;
+        avpriv_mpegaudio_decode_header(&c, header | (bitrate_idx << (4+8)));
+        error= FFABS(c.bit_rate - codec->bit_rate);
+        if(error < best_bitrate_error){
+            best_bitrate_error= error;
+            best_bitrate_idx  = bitrate_idx;
+        }
+    }
+    av_assert0(best_bitrate_idx >= 0);
+
+    for (bitrate_idx= best_bitrate_idx;; bitrate_idx++) {
+        if (15 == bitrate_idx)
+            return -1;
+        mask = bitrate_idx << (4+8);
+        header |= mask;
+        avpriv_mpegaudio_decode_header(&c, header);
+        xing_offset=xing_offtbl[c.lsf == 1][c.nb_channels == 1];
+        needed = 4              // header
+               + xing_offset
+               + 4              // xing tag
+               + 4              // frames/size/toc flags
+               + 4              // frames
+               + 4              // size
+               + XING_TOC_SIZE   // toc
+               + 24
+               ;
+
+        if (needed <= c.frame_size)
+            break;
+        header &= ~mask;
+    }
+
     avio_wb32(s->pb, header);
 
-    avpriv_mpegaudio_decode_header(&mpah, header);
-
-    av_assert0(mpah.frame_size >= XING_MAX_SIZE);
-
-    xing_offset = xing_offtbl[ver != 3][codec->channels == 1];
     ffio_fill(s->pb, 0, xing_offset);
     mp3->xing_offset = avio_tell(s->pb);
     ffio_wfourcc(s->pb, "Xing");
     avio_wb32(s->pb, 0x01 | 0x02 | 0x04);  // frames / size / TOC
 
-    mp3->size = mpah.frame_size;
-    mp3->want = 1;
+    mp3->size = c.frame_size;
+    mp3->want=1;
+    mp3->seen=0;
+    mp3->pos=0;
 
     avio_wb32(s->pb, 0);  // frames
     avio_wb32(s->pb, 0);  // size
 
-    // TOC
-    for (i = 0; i < XING_TOC_SIZE; i++)
-        avio_w8(s->pb, 255 * i / XING_TOC_SIZE);
+    // toc
+    for (i = 0; i < XING_TOC_SIZE; ++i)
+        avio_w8(s->pb, (uint8_t)(255 * i / XING_TOC_SIZE));
 
-    mpah.frame_size -= 4 + xing_offset + 4 + 4 + 4 + 4 + XING_TOC_SIZE;
-    ffio_fill(s->pb, 0, mpah.frame_size);
+    for (i = 0; i < strlen(vendor); ++i)
+        avio_w8(s->pb, vendor[i]);
+    for (; i < 21; ++i)
+        avio_w8(s->pb, 0);
+    avio_wb24(s->pb, FFMAX(codec->delay - 528 - 1, 0)<<12);
+
+    ffio_fill(s->pb, 0, c.frame_size - needed);
+
+    return 0;
 }
 
 /*
@@ -201,7 +243,7 @@
         if (XING_NUM_BAGS == ++mp3->pos) {
             /* shrink table to half size by throwing away each second bag. */
             for (i = 1; i < XING_NUM_BAGS; i += 2)
-                mp3->bag[i / 2] = mp3->bag[i];
+                mp3->bag[i >> 1] = mp3->bag[i];
 
             /* double wanted amount per bag. */
             mp3->want *= 2;
@@ -217,8 +259,9 @@
 {
     MP3Context  *mp3 = s->priv_data;
 
-    if (mp3->xing_offset && pkt->size >= 4) {
+    if (pkt && pkt->data && pkt->size >= 4) {
         MPADecodeHeader c;
+        int av_unused base;
 
         avpriv_mpegaudio_decode_header(&c, AV_RB32(pkt->data));
 
@@ -227,7 +270,26 @@
         if ((c.bit_rate == 0) || (mp3->initial_bitrate != c.bit_rate))
             mp3->has_variable_bitrate = 1;
 
-        mp3_xing_add_frame(mp3, pkt);
+#ifdef FILTER_VBR_HEADERS
+        /* filter out XING and INFO headers. */
+        base = 4 + xing_offtbl[c.lsf == 1][c.nb_channels == 1];
+
+        if (base + 4 <= pkt->size) {
+            uint32_t v = AV_RB32(pkt->data + base);
+
+            if (MKBETAG('X','i','n','g') == v || MKBETAG('I','n','f','o') == v)
+                return 0;
+        }
+
+        /* filter out VBRI headers. */
+        base = 4 + 32;
+
+        if (base + 4 <= pkt->size && MKBETAG('V','B','R','I') == AV_RB32(pkt->data + base))
+            return 0;
+#endif
+
+        if (mp3->xing_offset)
+            mp3_xing_add_frame(mp3, pkt);
     }
 
     return ff_raw_write_packet(s, pkt);
@@ -301,6 +363,17 @@
     return 0;
 }
 
+static int query_codec(enum AVCodecID id, int std_compliance)
+{
+    const CodecMime *cm= ff_id3v2_mime_tags;
+    while(cm->id != AV_CODEC_ID_NONE) {
+        if(id == cm->id)
+            return MKTAG('A', 'P', 'I', 'C');
+        cm++;
+    }
+    return -1;
+}
+
 #if CONFIG_MP2_MUXER
 AVOutputFormat ff_mp2_muxer = {
     .name              = "mp2",
@@ -432,6 +505,7 @@
     .write_header      = mp3_write_header,
     .write_packet      = mp3_write_packet,
     .write_trailer     = mp3_write_trailer,
+    .query_codec       = query_codec,
     .flags             = AVFMT_NOTIMESTAMPS,
     .priv_class        = &mp3_muxer_class,
 };
diff --git a/libavformat/mpc.c b/libavformat/mpc.c
index fbf8e92..3b818ed 100644
--- a/libavformat/mpc.c
+++ b/libavformat/mpc.c
@@ -2,20 +2,20 @@
  * Musepack demuxer
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -194,11 +194,11 @@
     MPCContext *c = s->priv_data;
     AVPacket pkt1, *pkt = &pkt1;
     int ret;
-    int index = av_index_search_timestamp(st, timestamp - DELAY_FRAMES, flags);
+    int index = av_index_search_timestamp(st, FFMAX(timestamp - DELAY_FRAMES, 0), flags);
     uint32_t lastframe;
 
     /* if found, seek there */
-    if (index >= 0){
+    if (index >= 0 && st->index_entries[st->nb_index_entries-1].timestamp >= timestamp - DELAY_FRAMES){
         c->curframe = st->index_entries[index].pos;
         return 0;
     }
diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c
index f60a314..56ed7ad 100644
--- a/libavformat/mpc8.c
+++ b/libavformat/mpc8.c
@@ -2,20 +2,20 @@
  * Musepack SV8 demuxer
  * Copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -204,7 +204,7 @@
         return AVERROR_INVALIDDATA;
     }
 
-    while(!pb->eof_reached){
+    while(!url_feof(pb)){
         pos = avio_tell(pb);
         mpc8_get_chunk_header(pb, &tag, &size);
         if(tag == TAG_STREAMHDR)
@@ -242,6 +242,8 @@
     st->start_time = 0;
     st->duration = c->samples / (1152 << (st->codec->extradata[1]&3)*2);
     size -= avio_tell(pb) - pos;
+    if (size > 0)
+        avio_skip(pb, size);
 
     if (pb->seekable) {
         int64_t pos = avio_tell(s->pb);
@@ -258,7 +260,7 @@
     int tag;
     int64_t pos, size;
 
-    while(!s->pb->eof_reached){
+    while(!url_feof(s->pb)){
         pos = avio_tell(s->pb);
 
         /* don't return bogus packets with the ape tag data */
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 2d08b17..22e7869 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -2,20 +2,20 @@
  * MPEG1/2 demuxer
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -74,6 +74,7 @@
             // and audio streams
             else if((code & 0xe0) == AUDIO_ID &&  pes) {audio++; i+=len;}
             else if(code == PRIVATE_STREAM_1  &&  pes) {priv1++; i+=len;}
+            else if(code == 0x1fd             &&  pes) vid++; //VC1
 
             else if((code & 0xf0) == VIDEO_ID && !pes) invalid++;
             else if((code & 0xe0) == AUDIO_ID && !pes) invalid++;
@@ -81,18 +82,19 @@
         }
     }
 
-    if(vid+audio > invalid)     /* invalid VDR files nd short PES streams */
+    if(vid+audio > invalid+1)     /* invalid VDR files nd short PES streams */
         score= AVPROBE_SCORE_MAX/4;
 
     if(sys>invalid && sys*9 <= pspack*10)
-        return pspack > 2 ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
+        return (audio > 12 || vid > 3 || pspack > 2) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
     if(pspack > invalid && (priv1+vid+audio)*10 >= pspack*9)
         return pspack > 2 ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
     if((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys && !pspack && p->buf_size>2048 && vid + audio > invalid) /* PES stream */
-        return (audio > 12 || vid > 3) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4;
+        return (audio > 12 || vid > 3 + 2*invalid) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4;
 
     //02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1
     //mp3_misidentified_2.mp3 has sys:0 priv1:0 pspack:0 vid:0 audio:6
+    //Have\ Yourself\ a\ Merry\ Little\ Christmas.mp3 0 0 0 5 0 1 len:21618
     return score;
 }
 
@@ -108,6 +110,7 @@
     MpegDemuxContext *m = s->priv_data;
     const char *sofdec = "Sofdec";
     int v, i = 0;
+    int64_t last_pos = avio_tell(s->pb);
 
     m->header_state = 0xff;
     s->ctx_flags |= AVFMTCTX_NOHEADER;
@@ -115,12 +118,14 @@
     m->sofdec = -1;
     do {
         v = avio_r8(s->pb);
-        m->header_state = m->header_state << 8 | v;
         m->sofdec++;
     } while (v == sofdec[i] && i++ < 6);
 
     m->sofdec = (m->sofdec == 6) ? 1 : 0;
 
+    if (!m->sofdec)
+       avio_seek(s->pb, last_pos, SEEK_SET);
+
     /* no need to do more */
     return 0;
 }
@@ -144,7 +149,7 @@
     state = *header_state;
     n = *size_ptr;
     while (n > 0) {
-        if (pb->eof_reached)
+        if (url_feof(pb))
             break;
         v = avio_r8(pb);
         n--;
@@ -218,7 +223,7 @@
         startcode = find_next_start_code(s->pb, &size, &m->header_state);
         last_sync = avio_tell(s->pb);
     if (startcode < 0){
-        if(s->pb->eof_reached)
+        if(url_feof(s->pb))
             return AVERROR_EOF;
         //FIXME we should remember header_state
         return AVERROR(EAGAIN);
@@ -339,21 +344,9 @@
     else if( c!= 0xf )
         goto redo;
 
-    if (startcode == PRIVATE_STREAM_1 && !m->psm_es_type[startcode & 0xff]) {
+    if (startcode == PRIVATE_STREAM_1) {
         startcode = avio_r8(s->pb);
         len--;
-        if (startcode >= 0x80 && startcode <= 0xcf) {
-            /* audio: skip header */
-            avio_r8(s->pb);
-            avio_r8(s->pb);
-            avio_r8(s->pb);
-            len -= 3;
-            if (startcode >= 0xb0 && startcode <= 0xbf) {
-                /* MLP/TrueHD audio has a 4-byte header */
-                avio_r8(s->pb);
-                len--;
-            }
-        }
     }
     if(len<0)
         goto error_redo;
@@ -380,20 +373,30 @@
     MpegDemuxContext *m = s->priv_data;
     AVStream *st;
     int len, startcode, i, es_type, ret;
+    int lpcm_header_len;
+    int request_probe= 0;
     enum AVCodecID codec_id = AV_CODEC_ID_NONE;
     enum AVMediaType type;
     int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work
-    uint8_t av_uninit(dvdaudio_substream_type);
 
  redo:
     len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts);
     if (len < 0)
         return len;
 
-    if(startcode == 0x1bd) {
-        dvdaudio_substream_type = avio_r8(s->pb);
-        avio_skip(s->pb, 3);
-        len -= 4;
+    if (startcode >= 0x80 && startcode <= 0xcf) {
+        if(len < 4)
+            goto skip;
+
+        /* audio: skip header */
+        avio_r8(s->pb);
+        lpcm_header_len = avio_rb16(s->pb);
+        len -= 3;
+        if (startcode >= 0xb0 && startcode <= 0xbf) {
+            /* MLP/TrueHD audio has a 4-byte header */
+            avio_r8(s->pb);
+            len--;
+        }
     }
 
     /* now find stream */
@@ -438,7 +441,7 @@
         if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1))
             codec_id = AV_CODEC_ID_CAVS;
         else
-            codec_id = AV_CODEC_ID_PROBE;
+            request_probe= 1;
         type = AVMEDIA_TYPE_VIDEO;
     } else if (startcode >= 0x1c0 && startcode <= 0x1df) {
         type = AVMEDIA_TYPE_AUDIO;
@@ -453,8 +456,12 @@
         codec_id = AV_CODEC_ID_DTS;
     } else if (startcode >= 0xa0 && startcode <= 0xaf) {
         type = AVMEDIA_TYPE_AUDIO;
-        /* 16 bit form will be handled as AV_CODEC_ID_PCM_S16BE */
-        codec_id = AV_CODEC_ID_PCM_DVD;
+        if(lpcm_header_len == 6) {
+            codec_id = AV_CODEC_ID_MLP;
+        } else {
+            /* 16 bit form will be handled as AV_CODEC_ID_PCM_S16BE */
+            codec_id = AV_CODEC_ID_PCM_DVD;
+        }
     } else if (startcode >= 0xb0 && startcode <= 0xbf) {
         type = AVMEDIA_TYPE_AUDIO;
         codec_id = AV_CODEC_ID_TRUEHD;
@@ -468,19 +475,6 @@
     } else if (startcode >= 0xfd55 && startcode <= 0xfd5f) {
         type = AVMEDIA_TYPE_VIDEO;
         codec_id = AV_CODEC_ID_VC1;
-    } else if (startcode == 0x1bd) {
-        // check dvd audio substream type
-        type = AVMEDIA_TYPE_AUDIO;
-        switch(dvdaudio_substream_type & 0xe0) {
-        case 0xa0:  codec_id = AV_CODEC_ID_PCM_DVD;
-                    break;
-        case 0x80:  if((dvdaudio_substream_type & 0xf8) == 0x88)
-                         codec_id = AV_CODEC_ID_DTS;
-                    else codec_id = AV_CODEC_ID_AC3;
-                    break;
-        default:    av_log(s, AV_LOG_ERROR, "Unknown 0x1bd sub-stream\n");
-                    goto skip;
-        }
     } else {
     skip:
         /* skip packet */
@@ -494,13 +488,19 @@
     st->id = startcode;
     st->codec->codec_type = type;
     st->codec->codec_id = codec_id;
+    st->request_probe     = request_probe;
     if (codec_id != AV_CODEC_ID_PCM_S16BE)
         st->need_parsing = AVSTREAM_PARSE_FULL;
  found:
     if(st->discard >= AVDISCARD_ALL)
         goto skip;
-    if ((startcode >= 0xa0 && startcode <= 0xaf) ||
-        (startcode == 0x1bd && ((dvdaudio_substream_type & 0xe0) == 0xa0))) {
+    if (startcode >= 0xa0 && startcode <= 0xaf) {
+      if (lpcm_header_len == 6) {
+            if (len < 6)
+                goto skip;
+            avio_skip(s->pb, 6);
+            len -=6;
+      } else {
         int b1, freq;
 
         /* for LPCM, we just skip the header and consider it is raw
@@ -522,6 +522,7 @@
             st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
         else if (st->codec->bits_per_coded_sample == 28)
             return AVERROR(EINVAL);
+      }
     }
     ret = av_get_packet(s->pb, pkt, len);
     pkt->pts = pts;
diff --git a/libavformat/mpeg.h b/libavformat/mpeg.h
index 75dddf3..ca019c9 100644
--- a/libavformat/mpeg.h
+++ b/libavformat/mpeg.h
@@ -2,20 +2,20 @@
  * MPEG1/2 muxer and demuxer common defines
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c
index 4f7bde8..e2a96bc 100644
--- a/libavformat/mpegenc.c
+++ b/libavformat/mpegenc.c
@@ -2,20 +2,20 @@
  * MPEG1/2 muxer
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -65,6 +65,7 @@
     int pack_header_freq;     /* frequency (in packets^-1) at which we send pack headers */
     int system_header_freq;
     int system_header_size;
+    int user_mux_rate; /* bitrate in units of bits/s */
     int mux_rate; /* bitrate in units of 50 bytes/s */
     /* stream info */
     int audio_bound;
@@ -415,7 +416,9 @@
             video_bitrate += codec_rate;
     }
 
-    if (!s->mux_rate) {
+    if (s->user_mux_rate) {
+        s->mux_rate = (s->user_mux_rate + (8 * 50) - 1) / (8 * 50);
+    } else {
         /* we increase slightly the bitrate to take into account the
            headers. XXX: compute it exactly */
         bitrate += bitrate / 20;
@@ -837,7 +840,7 @@
 
         /* output data */
         assert(payload_size - stuffing_size <= av_fifo_size(stream->fifo));
-        av_fifo_generic_read(stream->fifo, ctx->pb, payload_size - stuffing_size, &avio_write);
+        av_fifo_generic_read(stream->fifo, ctx->pb, payload_size - stuffing_size, (void*)avio_write);
         stream->bytes_to_iframe -= payload_size - stuffing_size;
     }else{
         payload_size=
@@ -934,7 +937,7 @@
         StreamInfo *stream = st->priv_data;
         const int avail_data=  av_fifo_size(stream->fifo);
         const int space= stream->max_buffer_size - stream->buffer_index;
-        int rel_space= 1024*space / stream->max_buffer_size;
+        int rel_space= 1024LL*space / stream->max_buffer_size;
         PacketDesc *next_pkt= stream->premux_packet;
 
         /* for subtitle, a single PES packet must be generated,
@@ -1132,7 +1135,7 @@
 #define OFFSET(x) offsetof(MpegMuxContext, x)
 #define E AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-    { "muxrate", NULL, OFFSET(mux_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
+    { "muxrate", NULL, OFFSET(user_mux_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E },
     { "preload", "Initial demux-decode delay in microseconds.", OFFSET(preload),  AV_OPT_TYPE_INT, {.i64 = 500000}, 0, INT_MAX, E},
     { NULL },
 };
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 4aabcd7..33a0eaf 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -2,20 +2,20 @@
  * MPEG2 transport stream (aka DVB) demuxer
  * Copyright (c) 2002-2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,7 @@
 #include "libavutil/dict.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
+#include "libavutil/avassert.h"
 #include "libavcodec/bytestream.h"
 #include "libavcodec/get_bits.h"
 #include "avformat.h"
@@ -122,6 +123,7 @@
     unsigned int nb_prg;
     struct Program *prg;
 
+    int8_t crc_validity[NB_PID_MAX];
 
     /** filters for various streams specified by PMT + for the PAT and PMT */
     MpegTSFilter *pids[NB_PID_MAX];
@@ -225,6 +227,17 @@
     p->pids[p->nb_pids++] = pid;
 }
 
+static void set_pcr_pid(AVFormatContext *s, unsigned int programid, unsigned int pid)
+{
+    int i;
+    for(i=0; i<s->nb_programs; i++) {
+        if(s->programs[i]->id == programid) {
+            s->programs[i]->pcr_pid = pid;
+            break;
+        }
+    }
+}
+
 /**
  * @brief discard_pid() decides if the pid is to be discarded according
  *                      to caller's programs selection
@@ -265,6 +278,7 @@
 static void write_section_data(AVFormatContext *s, MpegTSFilter *tss1,
                                const uint8_t *buf, int buf_size, int is_start)
 {
+    MpegTSContext *ts = s->priv_data;
     MpegTSSectionFilter *tss = &tss1->u.section_filter;
     int len;
 
@@ -292,10 +306,19 @@
     }
 
     if (tss->section_h_size != -1 && tss->section_index >= tss->section_h_size) {
+        int crc_valid = 1;
         tss->end_of_section_reached = 1;
-        if (!tss->check_crc ||
-            av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1,
-                   tss->section_buf, tss->section_h_size) == 0)
+
+        if (tss->check_crc){
+            crc_valid = !av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, tss->section_buf, tss->section_h_size);
+            if (crc_valid){
+                ts->crc_validity[ tss1->pid ] = 100;
+            }else if(ts->crc_validity[ tss1->pid ] > -10){
+                ts->crc_validity[ tss1->pid ]--;
+            }else
+                crc_valid = 2;
+        }
+        if (crc_valid)
             tss->section_cb(tss1, tss->section_buf, tss->section_h_size);
     }
 }
@@ -385,7 +408,7 @@
     memset(stat, 0, packet_size*sizeof(int));
 
     for(x=i=0; i<size-3; i++){
-        if(buf[i] == 0x47 && !(buf[i+1] & 0x80) && (buf[i+3] & 0x30)){
+        if(buf[i] == 0x47 && !(buf[i+1] & 0x80) && buf[i+3] != 0x47){
             stat[x]++;
             if(stat[x] > best_score){
                 best_score= stat[x];
@@ -520,7 +543,9 @@
     { 0x04, AVMEDIA_TYPE_AUDIO,        AV_CODEC_ID_MP3 },
     { 0x0f, AVMEDIA_TYPE_AUDIO,        AV_CODEC_ID_AAC },
     { 0x10, AVMEDIA_TYPE_VIDEO,      AV_CODEC_ID_MPEG4 },
-    { 0x11, AVMEDIA_TYPE_AUDIO,   AV_CODEC_ID_AAC_LATM }, /* LATM syntax */
+    /* 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 */
     { 0x1b, AVMEDIA_TYPE_VIDEO,       AV_CODEC_ID_H264 },
     { 0xd1, AVMEDIA_TYPE_VIDEO,      AV_CODEC_ID_DIRAC },
     { 0xea, AVMEDIA_TYPE_VIDEO,        AV_CODEC_ID_VC1 },
@@ -535,6 +560,8 @@
     { 0x84, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3 },
     { 0x85, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, /* DTS HD */
     { 0x86, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, /* DTS HD MASTER*/
+    { 0xa1, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3 }, /* E-AC3 Secondary Audio */
+    { 0xa2, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS },  /* DTS Express Secondary Audio */
     { 0x90, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_HDMV_PGS_SUBTITLE },
     { 0 },
 };
@@ -574,6 +601,7 @@
         if (stream_type == types->stream_type) {
             st->codec->codec_type = types->codec_type;
             st->codec->codec_id   = types->codec_id;
+            st->request_probe     = 0;
             return;
         }
     }
@@ -582,6 +610,8 @@
 static int mpegts_set_stream_info(AVStream *st, PESContext *pes,
                                   uint32_t stream_type, uint32_t prog_reg_desc)
 {
+    int old_codec_type= st->codec->codec_type;
+    int old_codec_id  = st->codec->codec_id;
     avpriv_set_pts_info(st, 33, 1, 90000);
     st->priv_data = pes;
     st->codec->codec_type = AVMEDIA_TYPE_DATA;
@@ -597,7 +627,8 @@
     st->codec->codec_tag = pes->stream_type;
 
     mpegts_find_stream_type(st, pes->stream_type, ISO_types);
-    if (prog_reg_desc == AV_RL32("HDMV") &&
+    if ((prog_reg_desc == AV_RL32("HDMV") ||
+         prog_reg_desc == AV_RL32("HDPR")) &&
         st->codec->codec_id == AV_CODEC_ID_NONE) {
         mpegts_find_stream_type(st, pes->stream_type, HDMV_types);
         if (pes->stream_type == 0x83) {
@@ -627,6 +658,10 @@
     }
     if (st->codec->codec_id == AV_CODEC_ID_NONE)
         mpegts_find_stream_type(st, pes->stream_type, MISC_types);
+    if (st->codec->codec_id == AV_CODEC_ID_NONE){
+        st->codec->codec_id  = old_codec_id;
+        st->codec->codec_type= old_codec_type;
+    }
 
     return 0;
 }
@@ -668,6 +703,9 @@
 static uint64_t get_bits64(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);
@@ -685,6 +723,7 @@
     int padding_flag = 0, padding_bits = 0, inst_bitrate_flag = 0;
     int dts_flag = -1, cts_flag = -1;
     int64_t dts = AV_NOPTS_VALUE, cts = AV_NOPTS_VALUE;
+
     init_get_bits(&gb, buf, buf_size*8);
 
     if (sl->use_au_start)
@@ -815,10 +854,10 @@
                         code != 0x1ff && code != 0x1f2 && /* program_stream_directory, DSMCC_stream */
                         code != 0x1f8) {                  /* ITU-T Rec. H.222.1 type E stream */
                         pes->state = MPEGTS_PESHEADER;
-                        if (pes->st->codec->codec_id == AV_CODEC_ID_NONE) {
+                        if (pes->st->codec->codec_id == AV_CODEC_ID_NONE && !pes->st->request_probe) {
                             av_dlog(pes->stream, "pid=%x stream_type=%x probing\n",
                                     pes->pid, pes->stream_type);
-                            pes->st->codec->codec_id = AV_CODEC_ID_PROBE;
+                            pes->st->request_probe= 1;
                         }
                     } else {
                         pes->state = MPEGTS_PAYLOAD;
@@ -1102,7 +1141,7 @@
         descr->sl.au_seq_num_len     = (lengths >> 7) & 0x1f;
         descr->sl.packet_seq_num_len = (lengths >> 2) & 0x1f;
     } else {
-        av_log_missing_feature(d->s, "Predefined SLConfigDescriptor\n", 0);
+        av_log_missing_feature(d->s, "Predefined SLConfigDescriptor", 0);
     }
     return 0;
 }
@@ -1288,15 +1327,17 @@
         break;
     case 0x1F: /* FMC descriptor */
         get16(pp, desc_end);
-        if (mp4_descr_count > 0 && st->codec->codec_id == AV_CODEC_ID_AAC_LATM &&
+        if (mp4_descr_count > 0 && (st->codec->codec_id == AV_CODEC_ID_AAC_LATM || st->request_probe>0) &&
             mp4_descr->dec_config_descr_len && mp4_descr->es_id == pid) {
             AVIOContext pb;
             ffio_init_context(&pb, mp4_descr->dec_config_descr,
                           mp4_descr->dec_config_descr_len, 0, NULL, NULL, NULL, NULL);
             ff_mp4_read_dec_config_descr(fc, st, &pb);
             if (st->codec->codec_id == AV_CODEC_ID_AAC &&
-                st->codec->extradata_size > 0)
-                st->need_parsing = 0;
+                st->codec->extradata_size > 0){
+                st->request_probe= st->need_parsing = 0;
+                st->codec->codec_type= AVMEDIA_TYPE_AUDIO;
+            }
         }
         break;
     case 0x56: /* DVB teletext descriptor */
@@ -1358,6 +1399,9 @@
         if (st->codec->codec_id == AV_CODEC_ID_NONE)
             mpegts_find_stream_type(st, st->codec->codec_tag, REGD_types);
         break;
+    case 0x52: /* stream identifier descriptor */
+        st->stream_identifier = 1 + get8(pp, desc_end);
+        break;
     default:
         break;
     }
@@ -1400,6 +1444,7 @@
         return;
     pcr_pid &= 0x1fff;
     add_pid_to_pmt(ts, h->id, pcr_pid);
+    set_pcr_pid(ts->stream, h->id, pcr_pid);
 
     av_dlog(ts->stream, "pcr_pid=0x%x\n", pcr_pid);
 
@@ -1436,7 +1481,7 @@
 
     // stop parsing after pmt, we found header
     if (!ts->stream->nb_streams)
-        ts->stop_parse = 1;
+        ts->stop_parse = 2;
 
     for(;;) {
         st = 0;
@@ -1516,6 +1561,7 @@
     SectionHeader h1, *h = &h1;
     const uint8_t *p, *p_end;
     int sid, pmt_pid;
+    AVProgram *program;
 
     av_dlog(ts->stream, "PAT:\n");
     hex_dump_debug(ts->stream, section, section_len);
@@ -1527,6 +1573,8 @@
     if (h->tid != PAT_TID)
         return;
 
+    ts->stream->ts_id = h->id;
+
     clear_programs(ts);
     for(;;) {
         sid = get16(&p, p_end);
@@ -1542,7 +1590,9 @@
         if (sid == 0x0000) {
             /* NIT info */
         } else {
-            av_new_program(ts->stream, sid);
+            program = av_new_program(ts->stream, sid);
+            program->program_num = sid;
+            program->pmt_pid = pmt_pid;
             if (ts->pids[pmt_pid])
                 mpegts_close_filter(ts, ts->pids[pmt_pid]);
             mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1);
@@ -1671,7 +1721,7 @@
 
     tss->last_cc = cc;
     if (!cc_ok) {
-        av_log(ts->stream, AV_LOG_WARNING,
+        av_log(ts->stream, AV_LOG_DEBUG,
                "Continuity check failed for pid %d expected %d got %d\n",
                pid, expected_cc, cc);
         if(tss->type == MPEGTS_PES) {
@@ -1740,7 +1790,7 @@
 
     for(i = 0;i < MAX_RESYNC_SIZE; i++) {
         c = avio_r8(pb);
-        if (pb->eof_reached)
+        if (url_feof(pb))
             return -1;
         if (c == 0x47) {
             avio_seek(pb, -1, SEEK_CUR);
@@ -1783,7 +1833,7 @@
 static int handle_packets(MpegTSContext *ts, int nb_packets)
 {
     AVFormatContext *s = ts->stream;
-    uint8_t packet[TS_PACKET_SIZE+FF_INPUT_BUFFER_PADDING_SIZE];
+    uint8_t packet[TS_PACKET_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
     int packet_num, ret = 0;
 
     if (avio_tell(s->pb) != ts->last_pos) {
@@ -1807,11 +1857,15 @@
     packet_num = 0;
     memset(packet + TS_PACKET_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
     for(;;) {
-        if (ts->stop_parse>0)
-            break;
         packet_num++;
-        if (nb_packets != 0 && packet_num >= nb_packets)
+        if (nb_packets != 0 && packet_num >= nb_packets ||
+            ts->stop_parse > 1) {
+            ret = AVERROR(EAGAIN);
             break;
+        }
+        if (ts->stop_parse > 0)
+            break;
+
         ret = read_packet(s, packet, ts->raw_packet_size);
         if (ret != 0)
             break;
@@ -1879,18 +1933,18 @@
 {
     MpegTSContext *ts = s->priv_data;
     AVIOContext *pb = s->pb;
-    uint8_t buf[5*1024];
+    uint8_t buf[8*1024]={0};
     int len;
     int64_t pos;
 
-    /* read the first 1024 bytes to get packet size */
+    /* read the first 8192 bytes to get packet size */
     pos = avio_tell(pb);
     len = avio_read(pb, buf, sizeof(buf));
-    if (len != sizeof(buf))
-        goto fail;
-    ts->raw_packet_size = get_packet_size(buf, sizeof(buf));
-    if (ts->raw_packet_size <= 0)
-        goto fail;
+    ts->raw_packet_size = get_packet_size(buf, len);
+    if (ts->raw_packet_size <= 0) {
+        av_log(s, AV_LOG_WARNING, "Could not detect TS packet size, defaulting to non-FEC/DVHS\n");
+        ts->raw_packet_size = TS_PACKET_SIZE;
+    }
     ts->stream = s;
     ts->auto_guess = 0;
 
@@ -1898,8 +1952,11 @@
         /* normal demux */
 
         /* first do a scan to get all the services */
-        if (avio_seek(pb, pos, SEEK_SET) < 0 && pb->seekable)
-            av_log(s, AV_LOG_ERROR, "Unable to seek back to the start\n");
+        /* NOTE: We attempt to seek on non-seekable files as well, as the
+         * probe buffer usually is big enough. Only warn if the seek failed
+         * on files where the seek should work. */
+        if (avio_seek(pb, pos, SEEK_SET) < 0)
+            av_log(s, pb->seekable ? AV_LOG_ERROR : AV_LOG_INFO, "Unable to seek back to the start\n");
 
         mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1);
 
@@ -2023,6 +2080,7 @@
     ts->pkt = pkt;
     ret = handle_packets(ts, 0);
     if (ret < 0) {
+        av_free_packet(ts->pkt);
         /* flush pes data left */
         for (i = 0; i < NB_PID_MAX; i++) {
             if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) {
@@ -2055,66 +2113,65 @@
     return 0;
 }
 
-static int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index,
+static av_unused int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index,
                               int64_t *ppos, int64_t pos_limit)
 {
     MpegTSContext *ts = s->priv_data;
     int64_t pos, timestamp;
     uint8_t buf[TS_PACKET_SIZE];
     int pcr_l, pcr_pid = ((PESContext*)s->streams[stream_index]->priv_data)->pcr_pid;
-    const int find_next= 1;
     pos = ((*ppos  + ts->raw_packet_size - 1 - ts->pos47) / ts->raw_packet_size) * ts->raw_packet_size + ts->pos47;
-    if (find_next) {
-        for(;;) {
-            avio_seek(s->pb, pos, SEEK_SET);
-            if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
-                return AV_NOPTS_VALUE;
-            if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) &&
-                parse_pcr(&timestamp, &pcr_l, buf) == 0) {
-                break;
-            }
-            pos += ts->raw_packet_size;
-        }
-    } else {
-        for(;;) {
-            pos -= ts->raw_packet_size;
-            if (pos < 0)
-                return AV_NOPTS_VALUE;
-            avio_seek(s->pb, pos, SEEK_SET);
-            if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
-                return AV_NOPTS_VALUE;
-            if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) &&
-                parse_pcr(&timestamp, &pcr_l, buf) == 0) {
-                break;
-            }
-        }
-    }
-    *ppos = pos;
-
-    return timestamp;
-}
-
-static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){
-    MpegTSContext *ts = s->priv_data;
-    uint8_t buf[TS_PACKET_SIZE];
-    int64_t pos;
-
-    if (ff_seek_frame_binary(s, stream_index, target_ts, flags) < 0)
-        return -1;
-
-    pos= avio_tell(s->pb);
-
-    for(;;) {
-        avio_seek(s->pb, pos, SEEK_SET);
+    while(pos < pos_limit) {
+        if (avio_seek(s->pb, pos, SEEK_SET) < 0)
+            return AV_NOPTS_VALUE;
         if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE)
-            return -1;
-//        pid = AV_RB16(buf + 1) & 0x1fff;
-        if(buf[1] & 0x40) break;
+            return AV_NOPTS_VALUE;
+        if (buf[0] != 0x47) {
+            if (mpegts_resync(s) < 0)
+                return AV_NOPTS_VALUE;
+            pos = avio_tell(s->pb);
+            continue;
+        }
+        if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) &&
+            parse_pcr(&timestamp, &pcr_l, buf) == 0) {
+            *ppos = pos;
+            return timestamp;
+        }
         pos += ts->raw_packet_size;
     }
-    avio_seek(s->pb, pos, SEEK_SET);
 
-    return 0;
+    return AV_NOPTS_VALUE;
+}
+
+static int64_t mpegts_get_dts(AVFormatContext *s, int stream_index,
+                              int64_t *ppos, int64_t pos_limit)
+{
+    MpegTSContext *ts = s->priv_data;
+    int64_t pos;
+    pos = ((*ppos  + ts->raw_packet_size - 1 - ts->pos47) / ts->raw_packet_size) * ts->raw_packet_size + ts->pos47;
+    ff_read_frame_flush(s);
+    if (avio_seek(s->pb, pos, SEEK_SET) < 0)
+        return AV_NOPTS_VALUE;
+    while(pos < pos_limit) {
+        int ret;
+        AVPacket pkt;
+        av_init_packet(&pkt);
+        ret= av_read_frame(s, &pkt);
+        if(ret < 0)
+            return AV_NOPTS_VALUE;
+        av_free_packet(&pkt);
+        if(pkt.dts != AV_NOPTS_VALUE && pkt.pos >= 0){
+            ff_reduce_index(s, pkt.stream_index);
+            av_add_index_entry(s->streams[pkt.stream_index], pkt.pos, pkt.dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */);
+            if(pkt.stream_index == stream_index){
+                *ppos= pkt.pos;
+                return pkt.dts;
+            }
+        }
+        pos = pkt.pos;
+    }
+
+    return AV_NOPTS_VALUE;
 }
 
 /**************************************************************/
@@ -2131,6 +2188,9 @@
     ts->raw_packet_size = TS_PACKET_SIZE;
     ts->stream = s;
     ts->auto_guess = 1;
+    mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1);
+    mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1);
+
     return ts;
 }
 
@@ -2143,10 +2203,8 @@
 
     len1 = len;
     ts->pkt = pkt;
-    ts->stop_parse = 0;
     for(;;) {
-        if (ts->stop_parse>0)
-            break;
+        ts->stop_parse = 0;
         if (len < TS_PACKET_SIZE)
             return -1;
         if (buf[0] != 0x47) {
@@ -2156,6 +2214,8 @@
             handle_packet(ts, buf);
             buf += TS_PACKET_SIZE;
             len -= TS_PACKET_SIZE;
+            if (ts->stop_parse == 1)
+                break;
         }
     }
     return len1 - len;
@@ -2178,8 +2238,7 @@
     .read_header    = mpegts_read_header,
     .read_packet    = mpegts_read_packet,
     .read_close     = mpegts_read_close,
-    .read_seek      = read_seek,
-    .read_timestamp = mpegts_get_pcr,
+    .read_timestamp = mpegts_get_dts,
     .flags          = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
 };
 
@@ -2190,8 +2249,7 @@
     .read_header    = mpegts_read_header,
     .read_packet    = mpegts_raw_read_packet,
     .read_close     = mpegts_read_close,
-    .read_seek      = read_seek,
-    .read_timestamp = mpegts_get_pcr,
+    .read_timestamp = mpegts_get_dts,
     .flags          = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
     .priv_class     = &mpegtsraw_class,
 };
diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h
index 89544f0..98c4b93 100644
--- a/libavformat/mpegts.h
+++ b/libavformat/mpegts.h
@@ -2,20 +2,20 @@
  * MPEG2 transport stream defines
  * Copyright (c) 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index 29d83c6..1b66bab 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -2,20 +2,20 @@
  * MPEG2 transport stream (aka DVB) muxer
  * Copyright (c) 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,6 +24,7 @@
 #include "libavutil/dict.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
+#include "libavutil/avassert.h"
 #include "libavcodec/mpegvideo.h"
 #include "avformat.h"
 #include "internal.h"
@@ -75,12 +76,14 @@
 
     int pmt_start_pid;
     int start_pid;
+    int m2ts_mode;
 
     int reemit_pat_pmt; // backward compatibility
 
 #define MPEGTS_FLAG_REEMIT_PAT_PMT  0x01
 #define MPEGTS_FLAG_AAC_LATM        0x02
     int flags;
+    int copyts;
 } MpegTSWrite;
 
 /* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */
@@ -95,9 +98,12 @@
     { "mpegts_service_id", "Set service_id field.",
       offsetof(MpegTSWrite, service_id), AV_OPT_TYPE_INT, {.i64 = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM},
     { "mpegts_pmt_start_pid", "Set the first pid of the PMT.",
-      offsetof(MpegTSWrite, pmt_start_pid), AV_OPT_TYPE_INT, {.i64 = 0x1000 }, 0x1000, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM},
+      offsetof(MpegTSWrite, pmt_start_pid), AV_OPT_TYPE_INT, {.i64 = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM},
     { "mpegts_start_pid", "Set the first pid.",
       offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT, {.i64 = 0x0100 }, 0x0100, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM},
+    {"mpegts_m2ts_mode", "Enable m2ts mode.",
+        offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_INT, {.i64 = -1 },
+        -1,1, AV_OPT_FLAG_ENCODING_PARAM},
     { "muxrate", NULL, offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT, {.i64 = 1}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
     { "pes_payload_size", "Minimum PES packet payload in bytes",
       offsetof(MpegTSWrite, pes_payload_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT_PES_PAYLOAD_SIZE}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
@@ -112,6 +118,8 @@
     // backward compatibility
     { "resend_headers", "Reemit PAT/PMT before writing the next packet",
       offsetof(MpegTSWrite, reemit_pat_pmt), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
+    { "mpegts_copyts", "dont offset dts/pts",
+      offsetof(MpegTSWrite, copyts), AV_OPT_TYPE_INT, {.i64=-1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
     { NULL },
 };
 
@@ -190,7 +198,7 @@
     tot_len = 3 + 5 + len + 4;
     /* check if not too big */
     if (tot_len > 1024)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     q = section;
     *q++ = tid;
@@ -208,7 +216,7 @@
 /*********************************************/
 /* mpegts writer */
 
-#define DEFAULT_PROVIDER_NAME   "Libav"
+#define DEFAULT_PROVIDER_NAME   "FFmpeg"
 #define DEFAULT_SERVICE_NAME    "Service01"
 
 /* we retransmit the SI info at this rate */
@@ -222,6 +230,7 @@
     int cc;
     int payload_size;
     int first_pts_check; ///< first pts check needed
+    int prev_payload_key;
     int64_t payload_pts;
     int64_t payload_dts;
     int payload_flags;
@@ -307,6 +316,20 @@
         /* write optional descriptors here */
         switch(st->codec->codec_type) {
         case AVMEDIA_TYPE_AUDIO:
+            if(st->codec->codec_id==AV_CODEC_ID_EAC3){
+                *q++=0x7a; // EAC3 descriptor see A038 DVB SI
+                *q++=1; // 1 byte, all flags sets to 0
+                *q++=0; // omit all fields...
+            }
+            if(st->codec->codec_id==AV_CODEC_ID_S302M){
+                *q++ = 0x05; /* MPEG-2 registration descriptor*/
+                *q++ = 4;
+                *q++ = 'B';
+                *q++ = 'S';
+                *q++ = 'S';
+                *q++ = 'D';
+            }
+
             if (lang) {
                 char *p;
                 char *next = lang->value;
@@ -454,9 +477,28 @@
     return service;
 }
 
+static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb)
+{
+    return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) +
+           ts->first_pcr;
+}
+
+static void mpegts_prefix_m2ts_header(AVFormatContext *s)
+{
+    MpegTSWrite *ts = s->priv_data;
+    if (ts->m2ts_mode) {
+        int64_t pcr = get_pcr(s->priv_data, s->pb);
+        uint32_t tp_extra_header = pcr % 0x3fffffff;
+        tp_extra_header = AV_RB32(&tp_extra_header);
+        avio_write(s->pb, (unsigned char *) &tp_extra_header,
+                sizeof(tp_extra_header));
+    }
+}
+
 static void section_write_packet(MpegTSSection *s, const uint8_t *packet)
 {
     AVFormatContext *ctx = s->opaque;
+    mpegts_prefix_m2ts_header(ctx);
     avio_write(ctx->pb, packet, TS_PACKET_SIZE);
 }
 
@@ -597,9 +639,10 @@
         ts->pat_packet_period      = (ts->mux_rate * PAT_RETRANS_TIME) /
             (TS_PACKET_SIZE * 8 * 1000);
 
-        ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE);
+        if(ts->copyts < 1)
+            ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE);
     } else {
-        /* Arbitrary values, PAT/PMT could be written on key frames */
+        /* Arbitrary values, PAT/PMT will also be written on video key frames */
         ts->sdt_packet_period = 200;
         ts->pat_packet_period = 40;
         if (pcr_st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
@@ -616,6 +659,8 @@
             service->pcr_packet_period =
                 pcr_st->codec->time_base.den/(10*pcr_st->codec->time_base.num);
         }
+        if(!service->pcr_packet_period)
+            service->pcr_packet_period = 1;
     }
 
     // output a PCR as soon as possible
@@ -632,6 +677,14 @@
            service->pcr_packet_period,
            ts->sdt_packet_period, ts->pat_packet_period);
 
+    if (ts->m2ts_mode == -1) {
+        if (av_match_ext(s->filename, "m2ts")) {
+            ts->m2ts_mode = 1;
+        } else {
+            ts->m2ts_mode = 0;
+        }
+    }
+
     avio_flush(s->pb);
 
     return 0;
@@ -655,7 +708,7 @@
 }
 
 /* send SDT, PAT and PMT tables regulary */
-static void retransmit_si_info(AVFormatContext *s)
+static void retransmit_si_info(AVFormatContext *s, int force_pat)
 {
     MpegTSWrite *ts = s->priv_data;
     int i;
@@ -664,7 +717,7 @@
         ts->sdt_packet_count = 0;
         mpegts_write_sdt(s);
     }
-    if (++ts->pat_packet_count == ts->pat_packet_period) {
+    if (++ts->pat_packet_count == ts->pat_packet_period || force_pat) {
         ts->pat_packet_count = 0;
         mpegts_write_pat(s);
         for(i = 0; i < ts->nb_services; i++) {
@@ -673,12 +726,6 @@
     }
 }
 
-static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb)
-{
-    return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) +
-           ts->first_pcr;
-}
-
 static int write_pcr_bits(uint8_t *buf, int64_t pcr)
 {
     int64_t pcr_low = pcr % 300, pcr_high = pcr / 300;
@@ -705,6 +752,7 @@
     *q++ = 0xff;
     *q++ = 0x10;
     memset(q, 0x0FF, TS_PACKET_SIZE - (q - buf));
+    mpegts_prefix_m2ts_header(s);
     avio_write(s->pb, buf, TS_PACKET_SIZE);
 }
 
@@ -730,6 +778,7 @@
 
     /* stuffing bytes */
     memset(q, 0xFF, TS_PACKET_SIZE - (q - buf));
+    mpegts_prefix_m2ts_header(s);
     avio_write(s->pb, buf, TS_PACKET_SIZE);
 }
 
@@ -751,7 +800,7 @@
 static void set_af_flag(uint8_t *pkt, int flag)
 {
     // expect at least one flag to set
-    assert(flag);
+    av_assert0(flag);
 
     if ((pkt[3] & 0x20) == 0) {
         // no AF yet, set adaptation field flag
@@ -767,7 +816,7 @@
 static void extend_af(uint8_t *pkt, int size)
 {
     // expect already existing adaptation field
-    assert(pkt[3] & 0x20);
+    av_assert0(pkt[3] & 0x20);
     pkt[4] += size;
 }
 
@@ -797,10 +846,12 @@
     int afc_len, stuffing_len;
     int64_t pcr = -1; /* avoid warning */
     int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
+    int force_pat = st->codec->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key;
 
     is_start = 1;
     while (payload_size > 0) {
-        retransmit_si_info(s);
+        retransmit_si_info(s, force_pat);
+        force_pat = 0;
 
         write_pcr = 0;
         if (ts_st->pid == ts_st->service->pcr_pid) {
@@ -870,6 +921,10 @@
                         st->codec->codec_id == AV_CODEC_ID_MP3 ||
                         st->codec->codec_id == AV_CODEC_ID_AAC)) {
                 *q++ = 0xc0;
+            } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
+                        st->codec->codec_id == AV_CODEC_ID_AC3 &&
+                        ts->m2ts_mode) {
+                *q++ = 0xfd;
             } else {
                 *q++ = 0xbd;
                 if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
@@ -899,6 +954,17 @@
                 */
                 header_len += 3;
             }
+            /* for Blu-ray AC3 Audio the PES Extension flag should be as follow
+             * otherwise it will not play sound on blu-ray
+             */
+            if (ts->m2ts_mode &&
+                st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
+                st->codec->codec_id == AV_CODEC_ID_AC3) {
+                        /* set PES_extension_flag */
+                        pes_extension = 1;
+                        flags |= 0x01;
+                        header_len += 3;
+            }
             len = payload_size + header_len + 3;
             if (private_code != 0)
                 len++;
@@ -931,6 +997,17 @@
                 */
                 *q++ = 0x00 | 0x60;
             }
+            /* For Blu-ray AC3 Audio Setting extended flags */
+          if (ts->m2ts_mode &&
+              pes_extension &&
+              st->codec->codec_id == AV_CODEC_ID_AC3) {
+                      flags = 0x01; /* set PES_extension_flag_2 */
+                      *q++ = flags;
+                      *q++ = 0x80 | 0x01; /* marker bit + extension length */
+                      *q++ = 0x00 | 0x71; /* for AC3 Audio (specifically on blue-rays) */
+              }
+
+
             if (private_code != 0)
                 *q++ = private_code;
             is_start = 0;
@@ -966,9 +1043,11 @@
         memcpy(buf + TS_PACKET_SIZE - len, payload, len);
         payload += len;
         payload_size -= len;
+        mpegts_prefix_m2ts_header(s);
         avio_write(s->pb, buf, TS_PACKET_SIZE);
     }
     avio_flush(s->pb);
+    ts_st->prev_payload_key = key;
 }
 
 static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
@@ -979,8 +1058,8 @@
     uint8_t *data= NULL;
     MpegTSWrite *ts = s->priv_data;
     MpegTSWriteStream *ts_st = st->priv_data;
-    const uint64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE)*2;
-    int64_t dts = AV_NOPTS_VALUE, pts = AV_NOPTS_VALUE;
+    const int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE)*2;
+    int64_t dts = pkt->dts, pts = pkt->pts;
 
     if (ts->reemit_pat_pmt) {
         av_log(s, AV_LOG_WARNING, "resend_headers option is deprecated, use -mpegts_flags resend_headers\n");
@@ -994,14 +1073,16 @@
         ts->flags &= ~MPEGTS_FLAG_REEMIT_PAT_PMT;
     }
 
-    if (pkt->pts != AV_NOPTS_VALUE)
-        pts = pkt->pts + delay;
-    if (pkt->dts != AV_NOPTS_VALUE)
-        dts = pkt->dts + delay;
+    if(ts->copyts < 1){
+        if (pts != AV_NOPTS_VALUE)
+            pts += delay;
+        if (dts != AV_NOPTS_VALUE)
+            dts += delay;
+    }
 
     if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) {
         av_log(s, AV_LOG_ERROR, "first pts value must set\n");
-        return AVERROR(EINVAL);
+        return AVERROR_INVALIDDATA;
     }
     ts_st->first_pts_check = 0;
 
@@ -1011,7 +1092,7 @@
 
         if (pkt->size < 5 || AV_RB32(pkt->data) != 0x0000001) {
             av_log(s, AV_LOG_ERROR, "H.264 bitstream malformed, "
-                   "no startcode found, use -bsf h264_mp4toannexb\n");
+                   "no startcode found, use the h264_mp4toannexb bitstream filter (-bsf h264_mp4toannexb)\n");
             return AVERROR(EINVAL);
         }
 
@@ -1035,7 +1116,7 @@
     } else if (st->codec->codec_id == AV_CODEC_ID_AAC) {
         if (pkt->size < 2) {
             av_log(s, AV_LOG_ERROR, "AAC packet too short\n");
-            return AVERROR(EINVAL);
+            return AVERROR_INVALIDDATA;
         }
         if ((AV_RB16(pkt->data) & 0xfff0) != 0xfff0) {
             int ret;
@@ -1044,7 +1125,7 @@
             if (!ts_st->amux) {
                 av_log(s, AV_LOG_ERROR, "AAC bitstream not in ADTS format "
                        "and extradata missing\n");
-                return AVERROR(EINVAL);
+                return AVERROR_INVALIDDATA;
             }
 
             av_init_packet(&pkt2);
@@ -1067,28 +1148,36 @@
         }
     }
 
-    if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
+    if (pkt->dts != AV_NOPTS_VALUE) {
+        int i;
+        for(i=0; i<s->nb_streams; i++){
+            AVStream *st2 = s->streams[i];
+            MpegTSWriteStream *ts_st2 = st2->priv_data;
+            if(   ts_st2->payload_size
+               && (ts_st2->payload_dts == AV_NOPTS_VALUE || dts - ts_st2->payload_dts > delay/2)){
+                mpegts_write_pes(s, st2, ts_st2->payload, ts_st2->payload_size,
+                                ts_st2->payload_pts, ts_st2->payload_dts,
+                                ts_st2->payload_flags & AV_PKT_FLAG_KEY);
+                ts_st2->payload_size = 0;
+            }
+        }
+    }
+
+    if (ts_st->payload_size && ts_st->payload_size + size > ts->pes_payload_size) {
+        mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size,
+                         ts_st->payload_pts, ts_st->payload_dts,
+                         ts_st->payload_flags & AV_PKT_FLAG_KEY);
+        ts_st->payload_size = 0;
+    }
+
+    if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO || size > ts->pes_payload_size) {
+        av_assert0(!ts_st->payload_size);
         // for video and subtitle, write a single pes packet
         mpegts_write_pes(s, st, buf, size, pts, dts, pkt->flags & AV_PKT_FLAG_KEY);
         av_free(data);
         return 0;
     }
 
-    if (ts_st->payload_size + size > ts->pes_payload_size) {
-        if (ts_st->payload_size) {
-            mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size,
-                             ts_st->payload_pts, ts_st->payload_dts,
-                             ts_st->payload_flags & AV_PKT_FLAG_KEY);
-            ts_st->payload_size = 0;
-        }
-        if (size > ts->pes_payload_size) {
-            mpegts_write_pes(s, st, buf, size, pts, dts,
-                             pkt->flags & AV_PKT_FLAG_KEY);
-            av_free(data);
-            return 0;
-        }
-    }
-
     if (!ts_st->payload_size) {
         ts_st->payload_pts = pts;
         ts_st->payload_dts = dts;
@@ -1164,7 +1253,7 @@
     .name              = "mpegts",
     .long_name         = NULL_IF_CONFIG_SMALL("MPEG-TS (MPEG-2 Transport Stream)"),
     .mime_type         = "video/x-mpegts",
-    .extensions        = "ts,m2t",
+    .extensions        = "ts,m2t,m2ts,mts",
     .priv_data_size    = sizeof(MpegTSWrite),
     .audio_codec       = AV_CODEC_ID_MP2,
     .video_codec       = AV_CODEC_ID_MPEG2VIDEO,
diff --git a/libavformat/mpegvideodec.c b/libavformat/mpegvideodec.c
index 87e5e03..f9c4062 100644
--- a/libavformat/mpegvideodec.c
+++ b/libavformat/mpegvideodec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2002-2003 Fabrice Bellard
  * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -34,7 +34,7 @@
 static int mpegvideo_probe(AVProbeData *p)
 {
     uint32_t code= -1;
-    int pic=0, seq=0, slice=0, pspack=0, pes=0;
+    int pic=0, seq=0, slice=0, pspack=0, vpes=0, apes=0, res=0;
     int i;
 
     for(i=0; i<p->buf_size; i++){
@@ -43,15 +43,18 @@
             switch(code){
             case     SEQ_START_CODE:   seq++; break;
             case PICTURE_START_CODE:   pic++; break;
-            case   SLICE_START_CODE: slice++; break;
             case    PACK_START_CODE: pspack++; break;
+            case              0x1b6:
+                                        res++; break;
             }
-            if     ((code & 0x1f0) == VIDEO_ID)   pes++;
-            else if((code & 0x1e0) == AUDIO_ID)   pes++;
+            if (code >= SLICE_START_CODE && code <= 0x1af) slice++;
+            if     ((code & 0x1f0) == VIDEO_ID)   vpes++;
+            else if((code & 0x1e0) == AUDIO_ID)   apes++;
         }
     }
-    if(seq && seq*9<=pic*10 && pic*9<=slice*10 && !pspack && !pes)
-        return pic>1 ? AVPROBE_SCORE_MAX/2+1 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
+    if(seq && seq*9<=pic*10 && pic*9<=slice*10 && !pspack && !apes && !res)
+        if(vpes) return AVPROBE_SCORE_MAX/8;
+        else     return pic>1 ? AVPROBE_SCORE_MAX/2+1 : AVPROBE_SCORE_MAX/4; // +1 for .mpg
     return 0;
 }
 
diff --git a/libavformat/mpjpeg.c b/libavformat/mpjpeg.c
index 6c8bd0c..916938f 100644
--- a/libavformat/mpjpeg.c
+++ b/libavformat/mpjpeg.c
@@ -2,33 +2,33 @@
  * Multipart JPEG format
  * Copyright (c) 2000, 2001, 2002, 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
 
 /* Multipart JPEG */
 
-#define BOUNDARY_TAG "avserver"
+#define BOUNDARY_TAG "ffserver"
 
 static int mpjpeg_write_header(AVFormatContext *s)
 {
     uint8_t buf1[256];
 
-    snprintf(buf1, sizeof(buf1), "--%s\n", BOUNDARY_TAG);
+    snprintf(buf1, sizeof(buf1), "--%s\r\n", BOUNDARY_TAG);
     avio_write(s->pb, buf1, strlen(buf1));
     avio_flush(s->pb);
     return 0;
@@ -38,11 +38,14 @@
 {
     uint8_t buf1[256];
 
-    snprintf(buf1, sizeof(buf1), "Content-type: image/jpeg\n\n");
+    snprintf(buf1, sizeof(buf1), "Content-type: image/jpeg\r\n");
+    avio_write(s->pb, buf1, strlen(buf1));
+
+    snprintf(buf1, sizeof(buf1), "Content-length: %d\r\n\r\n", pkt->size);
     avio_write(s->pb, buf1, strlen(buf1));
     avio_write(s->pb, pkt->data, pkt->size);
 
-    snprintf(buf1, sizeof(buf1), "\n--%s\n", BOUNDARY_TAG);
+    snprintf(buf1, sizeof(buf1), "\r\n--%s\r\n", BOUNDARY_TAG);
     avio_write(s->pb, buf1, strlen(buf1));
     avio_flush(s->pb);
     return 0;
diff --git a/libavformat/msnwc_tcp.c b/libavformat/msnwc_tcp.c
index b6d30fe..0ac1c30 100644
--- a/libavformat/msnwc_tcp.c
+++ b/libavformat/msnwc_tcp.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2008  Ramiro Polla
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -89,10 +89,10 @@
 
     /* Some files start with "connected\r\n\r\n".
      * So skip until we find the first byte of struct size */
-    while(avio_r8(pb) != HEADER_SIZE && !pb->eof_reached);
+    while(avio_r8(pb) != HEADER_SIZE && !url_feof(pb));
 
-    if(pb->eof_reached) {
-        av_log(ctx, AV_LOG_ERROR, "Could not find valid start.");
+    if(url_feof(pb)) {
+        av_log(ctx, AV_LOG_ERROR, "Could not find valid start.\n");
         return -1;
     }
 
diff --git a/libavformat/mtv.c b/libavformat/mtv.c
index 5722888..622a9b8 100644
--- a/libavformat/mtv.c
+++ b/libavformat/mtv.c
@@ -2,20 +2,20 @@
  * mtv demuxer
  * Copyright (c) 2006 Reynaldo H. Verdejo Pinochet
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -57,7 +57,7 @@
         return 0;
 
     /* Check for nonzero in bpp and (width|height) header fields */
-    if(!(p->buf[51] && AV_RL16(&p->buf[52]) | AV_RL16(&p->buf[54])))
+    if(p->buf_size < 57 || !(p->buf[51] && AV_RL16(&p->buf[52]) | AV_RL16(&p->buf[54])))
         return 0;
 
     /* If width or height are 0 then imagesize header field should not */
@@ -96,13 +96,19 @@
 
     /* Calculate width and height if missing from header */
 
-    if(!mtv->img_width)
+    if(mtv->img_bpp>>3){
+    if(!mtv->img_width && mtv->img_height)
         mtv->img_width=mtv->img_segment_size / (mtv->img_bpp>>3)
                         / mtv->img_height;
 
-    if(!mtv->img_height)
+    if(!mtv->img_height && mtv->img_width)
         mtv->img_height=mtv->img_segment_size / (mtv->img_bpp>>3)
                         / mtv->img_width;
+    }
+    if(!mtv->img_height || !mtv->img_width){
+        av_log(s, AV_LOG_ERROR, "width or height is invalid and I cannot calculate them from other information\n");
+        return AVERROR(EINVAL);
+    }
 
     avio_skip(pb, 4);
     audio_subsegments = avio_rl16(pb);
diff --git a/libavformat/mux.c b/libavformat/mux.c
index 96eecb5..9bcee99 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -1,21 +1,21 @@
 /*
- * muxing functions for use within Libav
+ * muxing functions for use within FFmpeg
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,6 +29,7 @@
 #include "libavutil/opt.h"
 #include "libavutil/dict.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/timestamp.h"
 #include "metadata.h"
 #include "id3v2.h"
 #include "libavutil/avassert.h"
@@ -49,7 +50,7 @@
 
 /**
  * @file
- * muxing functions for use within Libav
+ * muxing functions for use within libavformat
  */
 
 /* fraction handling */
@@ -102,6 +103,88 @@
     f->num = num;
 }
 
+AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precission)
+{
+    AVRational q;
+    int j;
+
+    if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+        q = (AVRational){1, st->codec->sample_rate};
+    } else {
+        q = st->codec->time_base;
+    }
+    for (j=2; j<14; j+= 1+(j>2))
+        while (q.den / q.num < min_precission && q.num % j == 0)
+            q.num /= j;
+    while (q.den / q.num < min_precission && q.den < (1<<24))
+        q.den <<= 1;
+
+    return q;
+}
+
+int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat,
+                                   const char *format, const char *filename)
+{
+    AVFormatContext *s = avformat_alloc_context();
+    int ret = 0;
+
+    *avctx = NULL;
+    if (!s)
+        goto nomem;
+
+    if (!oformat) {
+        if (format) {
+            oformat = av_guess_format(format, NULL, NULL);
+            if (!oformat) {
+                av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format);
+                ret = AVERROR(EINVAL);
+                goto error;
+            }
+        } else {
+            oformat = av_guess_format(NULL, filename, NULL);
+            if (!oformat) {
+                ret = AVERROR(EINVAL);
+                av_log(s, AV_LOG_ERROR, "Unable to find a suitable output format for '%s'\n",
+                       filename);
+                goto error;
+            }
+        }
+    }
+
+    s->oformat = oformat;
+    if (s->oformat->priv_data_size > 0) {
+        s->priv_data = av_mallocz(s->oformat->priv_data_size);
+        if (!s->priv_data)
+            goto nomem;
+        if (s->oformat->priv_class) {
+            *(const AVClass**)s->priv_data= s->oformat->priv_class;
+            av_opt_set_defaults(s->priv_data);
+        }
+    } else
+        s->priv_data = NULL;
+
+    if (filename)
+        av_strlcpy(s->filename, filename, sizeof(s->filename));
+    *avctx = s;
+    return 0;
+nomem:
+    av_log(s, AV_LOG_ERROR, "Out of memory\n");
+    ret = AVERROR(ENOMEM);
+error:
+    avformat_free_context(s);
+    return ret;
+}
+
+#if FF_API_ALLOC_OUTPUT_CONTEXT
+AVFormatContext *avformat_alloc_output_context(const char *format,
+                                               AVOutputFormat *oformat, const char *filename)
+{
+    AVFormatContext *avctx;
+    int ret = avformat_alloc_output_context2(&avctx, oformat, format, filename);
+    return ret < 0 ? NULL : avctx;
+}
+#endif
+
 static int validate_codec_tag(AVFormatContext *s, AVStream *st)
 {
     const AVCodecTag *avctag;
@@ -149,6 +232,9 @@
 
     if ((ret = av_opt_set_dict(s, &tmp)) < 0)
         goto fail;
+    if (s->priv_data && s->oformat->priv_class && *(const AVClass**)s->priv_data==s->oformat->priv_class &&
+        (ret = av_opt_set_dict(s->priv_data, &tmp)) < 0)
+        goto fail;
 
     // some sanity checks
     if (s->nb_streams == 0 && !(of->flags & AVFMT_NOSTREAMS)) {
@@ -186,9 +272,9 @@
                 ret = AVERROR(EINVAL);
                 goto fail;
             }
-
-            if (av_cmp_q(st->sample_aspect_ratio,
-                         codec->sample_aspect_ratio)) {
+            if (av_cmp_q(st->sample_aspect_ratio, codec->sample_aspect_ratio)
+                && FFABS(av_q2d(st->sample_aspect_ratio) - av_q2d(codec->sample_aspect_ratio)) > 0.004*av_q2d(st->sample_aspect_ratio)
+            ) {
                 av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer "
                                         "(%d/%d) and encoder layer (%d/%d)\n",
                        st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
@@ -201,21 +287,23 @@
         }
 
         if (of->codec_tag) {
-            if (codec->codec_tag &&
-                codec->codec_id == AV_CODEC_ID_RAWVIDEO &&
-                !av_codec_get_tag(of->codec_tag, codec->codec_id) &&
-                !validate_codec_tag(s, st)) {
+            if (   codec->codec_tag
+                && codec->codec_id == AV_CODEC_ID_RAWVIDEO
+                && (   av_codec_get_tag(of->codec_tag, codec->codec_id) == 0
+                    || av_codec_get_tag(of->codec_tag, codec->codec_id) == MKTAG('r', 'a', 'w', ' '))
+                && !validate_codec_tag(s, st)) {
                 // the current rawvideo encoding system ends up setting
-                // the wrong codec_tag for avi, we override it here
+                // the wrong codec_tag for avi/mov, we override it here
                 codec->codec_tag = 0;
             }
             if (codec->codec_tag) {
                 if (!validate_codec_tag(s, st)) {
-                    char tagbuf[32];
+                    char tagbuf[32], cortag[32];
                     av_get_codec_tag_string(tagbuf, sizeof(tagbuf), codec->codec_tag);
+                    av_get_codec_tag_string(cortag, sizeof(cortag), av_codec_get_tag(s->oformat->codec_tag, codec->codec_id));
                     av_log(s, AV_LOG_ERROR,
-                           "Tag %s/0x%08x incompatible with output codec id '%d'\n",
-                           tagbuf, codec->codec_tag, codec->codec_id);
+                           "Tag %s/0x%08x incompatible with output codec id '%d' (%s)\n",
+                           tagbuf, codec->codec_tag, codec->codec_id, cortag);
                     ret = AVERROR_INVALIDDATA;
                     goto fail;
                 }
@@ -301,6 +389,8 @@
 
     if (s->oformat->write_header) {
         ret = s->oformat->write_header(s);
+        if (ret >= 0 && s->pb && s->pb->error < 0)
+            ret = s->pb->error;
         if (ret < 0)
             return ret;
     }
@@ -314,14 +404,11 @@
 //FIXME merge with compute_pkt_fields
 static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt)
 {
-    int delay = FFMAX(st->codec->has_b_frames, !!st->codec->max_b_frames);
+    int delay = FFMAX(st->codec->has_b_frames, st->codec->max_b_frames > 0);
     int num, den, frame_size, i;
 
-    av_dlog(s, "compute_pkt_fields2: pts:%" PRId64 " dts:%" PRId64 " cur_dts:%" PRId64 " b:%d size:%d st:%d\n",
-            pkt->pts, pkt->dts, st->cur_dts, delay, pkt->size, pkt->stream_index);
-
-/*    if(pkt->pts == AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE)
- *      return AVERROR(EINVAL);*/
+    av_dlog(s, "compute_pkt_fields2: pts:%s dts:%s cur_dts:%s b:%d size:%d st:%d\n",
+            av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts), delay, pkt->size, pkt->stream_index);
 
     /* duration field */
     if (pkt->duration == 0) {
@@ -336,6 +423,11 @@
 
     //XXX/FIXME this is a temporary hack until all encoders output pts
     if ((pkt->pts == 0 || pkt->pts == AV_NOPTS_VALUE) && pkt->dts == AV_NOPTS_VALUE && !delay) {
+        static int warned;
+        if (!warned) {
+            av_log(s, AV_LOG_WARNING, "Encoder did not produce proper pts, making some up.\n");
+            warned = 1;
+        }
         pkt->dts =
 //        pkt->pts= st->cur_dts;
             pkt->pts = st->pts.val;
@@ -356,17 +448,18 @@
         ((!(s->oformat->flags & AVFMT_TS_NONSTRICT) &&
           st->cur_dts >= pkt->dts) || st->cur_dts > pkt->dts)) {
         av_log(s, AV_LOG_ERROR,
-               "Application provided invalid, non monotonically increasing dts to muxer in stream %d: %" PRId64 " >= %" PRId64 "\n",
-               st->index, st->cur_dts, pkt->dts);
+               "Application provided invalid, non monotonically increasing dts to muxer in stream %d: %s >= %s\n",
+               st->index, av_ts2str(st->cur_dts), av_ts2str(pkt->dts));
         return AVERROR(EINVAL);
     }
     if (pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts) {
-        av_log(s, AV_LOG_ERROR, "pts < dts in stream %d\n", st->index);
+        av_log(s, AV_LOG_ERROR, "pts (%s) < dts (%s) in stream %d\n",
+               av_ts2str(pkt->pts), av_ts2str(pkt->dts), st->index);
         return AVERROR(EINVAL);
     }
 
-    av_dlog(s, "av_write_frame: pts2:%"PRId64" dts2:%"PRId64"\n",
-            pkt->pts, pkt->dts);
+    av_dlog(s, "av_write_frame: pts2:%s dts2:%s\n",
+            av_ts2str(pkt->pts), av_ts2str(pkt->dts));
     st->cur_dts = pkt->dts;
     st->pts.val = pkt->dts;
 
@@ -396,8 +489,12 @@
     int ret;
 
     if (!pkt) {
-        if (s->oformat->flags & AVFMT_ALLOW_FLUSH)
-            return s->oformat->write_packet(s, pkt);
+        if (s->oformat->flags & AVFMT_ALLOW_FLUSH) {
+            ret = s->oformat->write_packet(s, pkt);
+            if (ret >= 0 && s->pb && s->pb->error < 0)
+                ret = s->pb->error;
+            return ret;
+        }
         return 1;
     }
 
@@ -407,37 +504,63 @@
         return ret;
 
     ret = s->oformat->write_packet(s, pkt);
+    if (ret >= 0 && s->pb && s->pb->error < 0)
+        ret = s->pb->error;
 
     if (ret >= 0)
         s->streams[pkt->stream_index]->nb_frames++;
     return ret;
 }
 
-void ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
+#define CHUNK_START 0x1000
+
+int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
                               int (*compare)(AVFormatContext *, AVPacket *, AVPacket *))
 {
     AVPacketList **next_point, *this_pktl;
+    AVStream *st   = s->streams[pkt->stream_index];
+    int chunked    = s->max_chunk_size || s->max_chunk_duration;
 
     this_pktl      = av_mallocz(sizeof(AVPacketList));
+    if (!this_pktl)
+        return AVERROR(ENOMEM);
     this_pktl->pkt = *pkt;
     pkt->destruct  = NULL;           // do not free original but only the copy
-    av_dup_packet(&this_pktl->pkt);  // duplicate the packet if it uses non-alloced memory
+    av_dup_packet(&this_pktl->pkt);  // duplicate the packet if it uses non-allocated memory
 
     if (s->streams[pkt->stream_index]->last_in_packet_buffer) {
-        next_point = &(s->streams[pkt->stream_index]->last_in_packet_buffer->next);
-    } else
+        next_point = &(st->last_in_packet_buffer->next);
+    } else {
         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     =
+                st->interleaver_chunk_duration = 0;
+                this_pktl->pkt.flags |= CHUNK_START;
+            }
+        }
+
         if (compare(s, &s->packet_buffer_end->pkt, pkt)) {
-            while (!compare(s, &(*next_point)->pkt, pkt))
+            while (   *next_point
+                   && ((chunked && !((*next_point)->pkt.flags&CHUNK_START))
+                       || !compare(s, &(*next_point)->pkt, pkt)))
                 next_point = &(*next_point)->next;
-            goto next_non_null;
+            if (*next_point)
+                goto next_non_null;
         } else {
             next_point = &(s->packet_buffer_end->next);
         }
     }
-    assert(!*next_point);
+    av_assert1(!*next_point);
 
     s->packet_buffer_end = this_pktl;
 next_non_null:
@@ -446,6 +569,7 @@
 
     s->streams[pkt->stream_index]->last_in_packet_buffer =
         *next_point                                      = this_pktl;
+    return 0;
 }
 
 static int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt)
@@ -454,6 +578,16 @@
     AVStream *st2 = s->streams[next->stream_index];
     int comp      = av_compare_ts(next->dts, st2->time_base, pkt->dts,
                                   st->time_base);
+    if (s->audio_preload && ((st->codec->codec_type == AVMEDIA_TYPE_AUDIO) != (st2->codec->codec_type == AVMEDIA_TYPE_AUDIO))) {
+        int64_t ts = av_rescale_q(pkt ->dts, st ->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st ->codec->codec_type == AVMEDIA_TYPE_AUDIO);
+        int64_t ts2= av_rescale_q(next->dts, st2->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st2->codec->codec_type == AVMEDIA_TYPE_AUDIO);
+        if (ts == ts2) {
+            ts= ( pkt ->dts* st->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st ->codec->codec_type == AVMEDIA_TYPE_AUDIO)* st->time_base.den)*st2->time_base.den
+               -( next->dts*st2->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st2->codec->codec_type == AVMEDIA_TYPE_AUDIO)*st2->time_base.den)* st->time_base.den;
+            ts2=0;
+        }
+        comp= (ts>ts2) - (ts<ts2);
+    }
 
     if (comp == 0)
         return pkt->stream_index < next->stream_index;
@@ -464,27 +598,76 @@
                                  AVPacket *pkt, int flush)
 {
     AVPacketList *pktl;
-    int stream_count = 0;
-    int i;
+    int stream_count = 0, noninterleaved_count = 0;
+    int64_t delta_dts_max = 0;
+    int i, ret;
 
     if (pkt) {
-        ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
+        ret = ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts);
+        if (ret < 0)
+            return ret;
     }
 
-    for (i = 0; i < s->nb_streams; i++)
-        stream_count += !!s->streams[i]->last_in_packet_buffer;
+    for (i = 0; i < s->nb_streams; i++) {
+        if (s->streams[i]->last_in_packet_buffer) {
+            ++stream_count;
+        } else if (s->streams[i]->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+            ++noninterleaved_count;
+        }
+    }
 
-    if (stream_count && (s->nb_streams == stream_count || flush)) {
+    if (s->nb_streams == stream_count) {
+        flush = 1;
+    } else if (!flush) {
+        for (i=0; i < s->nb_streams; i++) {
+            if (s->streams[i]->last_in_packet_buffer) {
+                int64_t delta_dts =
+                    av_rescale_q(s->streams[i]->last_in_packet_buffer->pkt.dts,
+                                s->streams[i]->time_base,
+                                AV_TIME_BASE_Q) -
+                    av_rescale_q(s->packet_buffer->pkt.dts,
+                                s->streams[s->packet_buffer->pkt.stream_index]->time_base,
+                                AV_TIME_BASE_Q);
+                delta_dts_max= FFMAX(delta_dts_max, delta_dts);
+            }
+        }
+        if (s->nb_streams == stream_count+noninterleaved_count &&
+           delta_dts_max > 20*AV_TIME_BASE) {
+            av_log(s, AV_LOG_DEBUG, "flushing with %d noninterleaved\n", noninterleaved_count);
+            flush = 1;
+        }
+    }
+    if (stream_count && flush) {
+        AVStream *st;
         pktl = s->packet_buffer;
         *out = pktl->pkt;
+        st   = s->streams[out->stream_index];
 
         s->packet_buffer = pktl->next;
         if (!s->packet_buffer)
             s->packet_buffer_end = NULL;
 
-        if (s->streams[out->stream_index]->last_in_packet_buffer == pktl)
-            s->streams[out->stream_index]->last_in_packet_buffer = NULL;
+        if (st->last_in_packet_buffer == pktl)
+            st->last_in_packet_buffer = NULL;
         av_freep(&pktl);
+
+        if (s->avoid_negative_ts > 0) {
+            if (out->dts != AV_NOPTS_VALUE) {
+                if (!st->mux_ts_offset && out->dts < 0) {
+                    for (i = 0; i < s->nb_streams; i++) {
+                        s->streams[i]->mux_ts_offset =
+                            av_rescale_q_rnd(-out->dts,
+                                             st->time_base,
+                                             s->streams[i]->time_base,
+                                             AV_ROUND_UP);
+                    }
+                }
+                out->dts += st->mux_ts_offset;
+            }
+            if (out->pts != AV_NOPTS_VALUE)
+                out->pts += st->mux_ts_offset;
+        }
+
         return 1;
     } else {
         av_init_packet(out);
@@ -532,8 +715,8 @@
         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->size == 0)
             return 0;
 
-        av_dlog(s, "av_interleaved_write_frame size:%d dts:%" PRId64 " pts:%" PRId64 "\n",
-                pkt->size, pkt->dts, pkt->pts);
+        av_dlog(s, "av_interleaved_write_frame size:%d dts:%s pts:%s\n",
+                pkt->size, av_ts2str(pkt->dts), av_ts2str(pkt->pts));
         if ((ret = compute_pkt_fields2(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
             return ret;
 
@@ -559,6 +742,8 @@
 
         if (ret < 0)
             return ret;
+        if(s->pb && s->pb->error)
+            return s->pb->error;
     }
 }
 
@@ -582,15 +767,18 @@
 
         if (ret < 0)
             goto fail;
+        if(s->pb && s->pb->error)
+            goto fail;
     }
 
     if (s->oformat->write_trailer)
         ret = s->oformat->write_trailer(s);
 
-    if (!(s->oformat->flags & AVFMT_NOFILE))
-        avio_flush(s->pb);
-
 fail:
+    if (s->pb)
+       avio_flush(s->pb);
+    if (ret == 0)
+       ret = s->pb ? s->pb->error : 0;
     for (i = 0; i < s->nb_streams; i++) {
         av_freep(&s->streams[i]->priv_data);
         av_freep(&s->streams[i]->index_entries);
@@ -600,3 +788,12 @@
     av_freep(&s->priv_data);
     return ret;
 }
+
+int av_get_output_timestamp(struct AVFormatContext *s, int stream,
+                            int64_t *dts, int64_t *wall)
+{
+    if (!s->oformat || !s->oformat->get_output_timestamp)
+        return AVERROR(ENOSYS);
+    s->oformat->get_output_timestamp(s, stream, dts, wall);
+    return 0;
+}
diff --git a/libavformat/mvi.c b/libavformat/mvi.c
index c5aee5a..0833e11 100644
--- a/libavformat/mvi.c
+++ b/libavformat/mvi.c
@@ -2,20 +2,20 @@
  * Motion Pixels MVI Demuxer
  * Copyright (c) 2008 Gregory Montoir (cyx@users.sourceforge.net)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/mxf.c b/libavformat/mxf.c
index 040d8a2..4a4158a 100644
--- a/libavformat/mxf.c
+++ b/libavformat/mxf.c
@@ -2,20 +2,20 @@
  * MXF
  * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -41,9 +41,11 @@
     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 }, 13,    AV_CODEC_ID_DVVIDEO }, /* DV25 IEC PAL */
     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14,   AV_CODEC_ID_JPEG2000 }, /* JPEG2000 Codestream */
     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13,   AV_CODEC_ID_RAWVIDEO }, /* Uncompressed */
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }, 15,   AV_CODEC_ID_RAWVIDEO }, /* Uncompressed 422 8-bit */
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x71,0x00,0x00,0x00 }, 13,      AV_CODEC_ID_DNXHD }, /* SMPTE VC-3/DNxHD */
     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x03,0x02,0x00,0x00 }, 14,      AV_CODEC_ID_DNXHD }, /* SMPTE VC-3/DNxHD */
     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x00,0x00 }, 14,       AV_CODEC_ID_H264 }, /* H.264/MPEG-4 AVC Intra */
-    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x02,0x00 }, 15,       AV_CODEC_ID_V210 }, /* V210 */
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x02,0x01 }, 16,       AV_CODEC_ID_V210 }, /* V210 */
     /* SoundEssenceCompression */
     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, 13,  AV_CODEC_ID_PCM_S16LE }, /* Uncompressed */
     { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13,  AV_CODEC_ID_PCM_S16LE },
@@ -104,3 +106,32 @@
 
     return -1;
 }
+
+static const MXFSamplesPerFrame mxf_samples_per_frames[] = {
+    { { 1001, 24000 }, { 2002, 0,    0,    0,    0,    0 } }, // FILM 23.976
+    { { 1, 24},        { 2000, 0,    0,    0,    0,    0 } }, // FILM 24
+    { { 1001, 30000 }, { 1602, 1601, 1602, 1601, 1602, 0 } }, // NTSC 29.97
+    { { 1001, 60000 }, { 801,  801,  801,  801,  800,  0 } }, // NTSC 59.94
+    { { 1, 25 },       { 1920, 0,    0,    0,    0,    0 } }, // PAL 25
+    { { 1, 50 },       { 960,  0,    0,    0,    0,    0 } }, // PAL 50
+};
+
+const MXFSamplesPerFrame *ff_mxf_get_samples_per_frame(AVFormatContext *s, AVRational time_base)
+{
+    int i;
+    for (i = 0; i < FF_ARRAY_ELEMS(mxf_samples_per_frames); i++) {
+        if (!av_cmp_q(mxf_samples_per_frames[i].time_base, time_base))
+            return &mxf_samples_per_frames[i];
+    }
+
+    // Find closest container time base for approximative codec time base like 1/29.97, 1/30, ...
+    for (i = 0; i < FF_ARRAY_ELEMS(mxf_samples_per_frames); i++) {
+        if (fabs(av_q2d(mxf_samples_per_frames[i].time_base) - av_q2d(time_base)) < 0.0001) {
+            av_log(s, AV_LOG_WARNING, "%d/%d input time base matched %d/%d container time base\n",
+                   time_base.num, time_base.den,
+                   mxf_samples_per_frames[i].time_base.num, mxf_samples_per_frames[i].time_base.den);
+            return &mxf_samples_per_frames[i];
+        }
+    }
+    return NULL;
+}
diff --git a/libavformat/mxf.h b/libavformat/mxf.h
index 773f30f..4c751e8 100644
--- a/libavformat/mxf.h
+++ b/libavformat/mxf.h
@@ -2,25 +2,26 @@
  * MXF
  * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #ifndef AVFORMAT_MXF_H
 #define AVFORMAT_MXF_H
 
+#include "avformat.h"
 #include "libavcodec/avcodec.h"
 #include <stdint.h>
 
@@ -47,11 +48,11 @@
 };
 
 enum MXFFrameLayout {
-     FullFrame = 0,
-     MixedFields,
-     OneField,
-     SegmentedFrame,
-     SeparateFields
+    FullFrame = 0,
+    SeparateFields,
+    OneField,
+    MixedFields,
+    SegmentedFrame,
 };
 
 typedef struct KLVPacket {
@@ -66,11 +67,17 @@
     int id;
 } MXFCodecUL;
 
+typedef struct {
+    struct AVRational time_base;
+    int samples_per_frame[6];
+} MXFSamplesPerFrame;
+
 extern const MXFCodecUL ff_mxf_data_definition_uls[];
 extern const MXFCodecUL ff_mxf_codec_uls[];
 extern const MXFCodecUL ff_mxf_pixel_format_uls[];
 
 int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum AVPixelFormat *pix_fmt);
+const MXFSamplesPerFrame *ff_mxf_get_samples_per_frame(AVFormatContext *s, AVRational time_base);
 
 #define PRINT_KEY(pc, s, x) av_dlog(pc, "%s %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", s, \
                              (x)[0], (x)[1], (x)[2], (x)[3], (x)[4], (x)[5], (x)[6], (x)[7], (x)[8], (x)[9], (x)[10], (x)[11], (x)[12], (x)[13], (x)[14], (x)[15])
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index 8595d72..1f583b8 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -2,20 +2,20 @@
  * MXF demuxer.
  * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -48,6 +48,7 @@
 #include "libavutil/aes.h"
 #include "libavutil/mathematics.h"
 #include "libavcodec/bytestream.h"
+#include "libavutil/timecode.h"
 #include "avformat.h"
 #include "internal.h"
 #include "mxf.h"
@@ -69,7 +70,7 @@
     OP3b,
     OP3c,
     OPAtom,
-    OPSonyOpt,  /* FATE sample, violates the spec in places */
+    OPSONYOpt,  /* FATE sample, violates the spec in places */
 } MXFOP;
 
 typedef struct {
@@ -116,6 +117,15 @@
 typedef struct {
     UID uid;
     enum MXFMetadataSetType type;
+    int drop_frame;
+    int start_frame;
+    struct AVRational rate;
+    AVTimecode tc;
+} MXFTimecodeComponent;
+
+typedef struct {
+    UID uid;
+    enum MXFMetadataSetType type;
     MXFSequence *sequence; /* mandatory, and only one */
     UID sequence_ref;
     int track_id;
@@ -262,7 +272,7 @@
 static int mxf_read_sync(AVIOContext *pb, const uint8_t *key, unsigned size)
 {
     int i, b;
-    for (i = 0; i < size && !pb->eof_reached; i++) {
+    for (i = 0; i < size && !url_feof(pb); i++) {
         b = avio_r8(pb);
         if (b == key[0])
             i = 0;
@@ -312,7 +322,7 @@
     data_ptr = pkt->data;
     end_ptr = pkt->data + length;
     buf_ptr = pkt->data + 4; /* skip SMPTE 331M header */
-    for (; buf_ptr + st->codec->channels*4 < end_ptr; ) {
+    for (; buf_ptr + st->codec->channels*4 <= end_ptr; ) {
         for (i = 0; i < st->codec->channels; i++) {
             uint32_t sample = bytestream_get_le32(&buf_ptr);
             if (st->codec->bits_per_coded_sample == 24)
@@ -400,12 +410,14 @@
                               item_len);
         return AVERROR_PATCHWELCOME;
     }
-    if (item_num > UINT_MAX / item_len)
+    if (item_num > 65536) {
+        av_log(mxf->fc, AV_LOG_ERROR, "item_num %d is too large\n", item_num);
         return AVERROR_INVALIDDATA;
-    mxf->local_tags_count = item_num;
-    mxf->local_tags = av_malloc(item_num*item_len);
+    }
+    mxf->local_tags = av_calloc(item_num, item_len);
     if (!mxf->local_tags)
         return AVERROR(ENOMEM);
+    mxf->local_tags_count = item_num;
     avio_read(pb, mxf->local_tags, item_num*item_len);
     return 0;
 }
@@ -509,7 +521,7 @@
     else if (op[12] == 3 && op[13] == 1) mxf->op = OP3a;
     else if (op[12] == 3 && op[13] == 2) mxf->op = OP3b;
     else if (op[12] == 3 && op[13] == 3) mxf->op = OP3c;
-    else if (op[12] == 64&& op[13] == 1) mxf->op = OPSonyOpt;
+    else if (op[12] == 64&& op[13] == 1) mxf->op = OPSONYOpt;
     else if (op[12] == 0x10) {
         /* SMPTE 390m: "There shall be exactly one essence container"
          * The following block deals with files that violate this, namely:
@@ -520,10 +532,8 @@
 
             /* only nag once */
             if (!mxf->op)
-                av_log(mxf->fc, AV_LOG_WARNING,
-                       "\"OPAtom\" with %u ECs - assuming %s\n",
-                       nb_essence_containers,
-                       op == OP1a ? "OP1a" : "OPAtom");
+                av_log(mxf->fc, AV_LOG_WARNING, "\"OPAtom\" with %u ECs - assuming %s\n",
+                       nb_essence_containers, op == OP1a ? "OP1a" : "OPAtom");
 
             mxf->op = op;
         } else
@@ -536,7 +546,7 @@
     if (partition->kag_size <= 0 || partition->kag_size > (1 << 20)) {
         av_log(mxf->fc, AV_LOG_WARNING, "invalid KAGSize %i - guessing ", partition->kag_size);
 
-        if (mxf->op == OPSonyOpt)
+        if (mxf->op == OPSONYOpt)
             partition->kag_size = 512;
         else
             partition->kag_size = 1;
@@ -577,9 +587,7 @@
     switch (tag) {
     case 0x1901:
         mxf->packages_count = avio_rb32(pb);
-        if (mxf->packages_count >= UINT_MAX / sizeof(UID))
-            return AVERROR_INVALIDDATA;
-        mxf->packages_refs = av_malloc(mxf->packages_count * sizeof(UID));
+        mxf->packages_refs = av_calloc(mxf->packages_count, sizeof(UID));
         if (!mxf->packages_refs)
             return AVERROR(ENOMEM);
         avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */
@@ -617,9 +625,7 @@
     switch(tag) {
     case 0x4403:
         package->tracks_count = avio_rb32(pb);
-        if (package->tracks_count >= UINT_MAX / sizeof(UID))
-            return AVERROR_INVALIDDATA;
-        package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID));
+        package->tracks_refs = av_calloc(package->tracks_count, sizeof(UID));
         if (!package->tracks_refs)
             return AVERROR(ENOMEM);
         avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */
@@ -629,6 +635,23 @@
     return 0;
 }
 
+static int mxf_read_timecode_component(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
+{
+    MXFTimecodeComponent *mxf_timecode = arg;
+    switch(tag) {
+    case 0x1501:
+        mxf_timecode->start_frame = avio_rb64(pb);
+        break;
+    case 0x1502:
+        mxf_timecode->rate = (AVRational){avio_rb16(pb), 1};
+        break;
+    case 0x1503:
+        mxf_timecode->drop_frame = avio_r8(pb);
+        break;
+    }
+    return 0;
+}
+
 static int mxf_read_track(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset)
 {
     MXFTrack *track = arg;
@@ -662,9 +685,7 @@
         break;
     case 0x1001:
         sequence->structural_components_count = avio_rb32(pb);
-        if (sequence->structural_components_count >= UINT_MAX / sizeof(UID))
-            return AVERROR_INVALIDDATA;
-        sequence->structural_components_refs = av_malloc(sequence->structural_components_count * sizeof(UID));
+        sequence->structural_components_refs = av_calloc(sequence->structural_components_count, sizeof(UID));
         if (!sequence->structural_components_refs)
             return AVERROR(ENOMEM);
         avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */
@@ -680,9 +701,7 @@
     switch(tag) {
     case 0x4403:
         package->tracks_count = avio_rb32(pb);
-        if (package->tracks_count >= UINT_MAX / sizeof(UID))
-            return AVERROR_INVALIDDATA;
-        package->tracks_refs = av_malloc(package->tracks_count * sizeof(UID));
+        package->tracks_refs = av_calloc(package->tracks_count, sizeof(UID));
         if (!package->tracks_refs)
             return AVERROR(ENOMEM);
         avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */
@@ -705,29 +724,13 @@
     int i, length;
 
     segment->nb_index_entries = avio_rb32(pb);
-    if (!segment->nb_index_entries)
-        return 0;
-    else if (segment->nb_index_entries < 0 ||
-             segment->nb_index_entries >
-             (INT_MAX / sizeof(*segment->stream_offset_entries)))
-        return AVERROR(ENOMEM);
 
     length = avio_rb32(pb);
 
-    segment->temporal_offset_entries = av_mallocz(segment->nb_index_entries *
-                                 sizeof(*segment->temporal_offset_entries));
-    segment->flag_entries            = av_mallocz(segment->nb_index_entries *
-                                 sizeof(*segment->flag_entries));
-    segment->stream_offset_entries   = av_mallocz(segment->nb_index_entries *
-                                 sizeof(*segment->stream_offset_entries));
-
-    if (!segment->flag_entries || !segment->stream_offset_entries ||
-        !segment->temporal_offset_entries) {
-        av_freep(&segment->flag_entries);
-        av_freep(&segment->stream_offset_entries);
-        av_freep(&segment->temporal_offset_entries);
+    if (!(segment->temporal_offset_entries=av_calloc(segment->nb_index_entries, sizeof(*segment->temporal_offset_entries))) ||
+        !(segment->flag_entries          = av_calloc(segment->nb_index_entries, sizeof(*segment->flag_entries))) ||
+        !(segment->stream_offset_entries = av_calloc(segment->nb_index_entries, sizeof(*segment->stream_offset_entries))))
         return AVERROR(ENOMEM);
-    }
 
     for (i = 0; i < segment->nb_index_entries; i++) {
         segment->temporal_offset_entries[i] = avio_r8(pb);
@@ -802,9 +805,7 @@
     switch(tag) {
     case 0x3F01:
         descriptor->sub_descriptors_count = avio_rb32(pb);
-        if (descriptor->sub_descriptors_count >= UINT_MAX / sizeof(UID))
-            return AVERROR_INVALIDDATA;
-        descriptor->sub_descriptors_refs = av_malloc(descriptor->sub_descriptors_count * sizeof(UID));
+        descriptor->sub_descriptors_refs = av_calloc(descriptor->sub_descriptors_count, sizeof(UID));
         if (!descriptor->sub_descriptors_refs)
             return AVERROR(ENOMEM);
         avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */
@@ -953,9 +954,8 @@
     if (!nb_segments)
         return AVERROR_INVALIDDATA;
 
-    *sorted_segments  = av_mallocz(nb_segments * sizeof(**sorted_segments));
-    unsorted_segments = av_mallocz(nb_segments * sizeof(*unsorted_segments));
-    if (!sorted_segments || !unsorted_segments) {
+    if (!(unsorted_segments = av_calloc(nb_segments, sizeof(*unsorted_segments))) ||
+        !(*sorted_segments  = av_calloc(nb_segments, sizeof(**sorted_segments)))) {
         av_freep(sorted_segments);
         av_free(unsorted_segments);
         return AVERROR(ENOMEM);
@@ -970,19 +970,23 @@
     /* sort segments by {BodySID, IndexSID, IndexStartPosition}, remove duplicates while we're at it */
     for (i = 0; i < nb_segments; i++) {
         int best = -1, best_body_sid = -1, best_index_sid = -1, best_index_start = -1;
+        uint64_t best_index_duration = 0;
 
         for (j = 0; j < nb_segments; j++) {
             MXFIndexTableSegment *s = unsorted_segments[j];
 
             /* Require larger BosySID, IndexSID or IndexStartPosition then the previous entry. This removes duplicates.
              * We want the smallest values for the keys than what we currently have, unless this is the first such entry this time around.
+             * If we come across an entry with the same IndexStartPosition but larger IndexDuration, then we'll prefer it over the one we currently have.
              */
             if ((i == 0     || s->body_sid > last_body_sid || s->index_sid > last_index_sid || s->index_start_position > last_index_start) &&
-                (best == -1 || s->body_sid < best_body_sid || s->index_sid < best_index_sid || s->index_start_position < best_index_start)) {
+                (best == -1 || s->body_sid < best_body_sid || s->index_sid < best_index_sid || s->index_start_position < best_index_start ||
+                (s->index_start_position == best_index_start && s->index_duration > best_index_duration))) {
                 best             = j;
                 best_body_sid    = s->body_sid;
                 best_index_sid   = s->index_sid;
                 best_index_start = s->index_start_position;
+                best_index_duration = s->index_duration;
             }
         }
 
@@ -1123,14 +1127,8 @@
     if (index_table->nb_ptses <= 0)
         return 0;
 
-    if (index_table->nb_ptses > INT_MAX / sizeof(AVIndexEntry))
-        return AVERROR(ENOMEM);
-
-    index_table->ptses      = av_mallocz(index_table->nb_ptses *
-                                         sizeof(int64_t));
-    index_table->fake_index = av_mallocz(index_table->nb_ptses *
-                                         sizeof(AVIndexEntry));
-    if (!index_table->ptses || !index_table->fake_index) {
+    if (!(index_table->ptses      = av_calloc(index_table->nb_ptses, sizeof(int64_t))) ||
+        !(index_table->fake_index = av_calloc(index_table->nb_ptses, sizeof(AVIndexEntry)))) {
         av_freep(&index_table->ptses);
         return AVERROR(ENOMEM);
     }
@@ -1235,9 +1233,7 @@
         }
     }
 
-    if (mxf->nb_index_tables > INT_MAX / sizeof(MXFIndexTable) ||
-        !(mxf->index_tables = av_mallocz(mxf->nb_index_tables *
-                                         sizeof(MXFIndexTable)))) {
+    if (!(mxf->index_tables = av_calloc(mxf->nb_index_tables, sizeof(MXFIndexTable)))) {
         av_log(mxf->fc, AV_LOG_ERROR, "failed to allocate index tables\n");
         ret = AVERROR(ENOMEM);
         goto finish_decoding_index;
@@ -1256,12 +1252,8 @@
     for (i = j = 0; j < mxf->nb_index_tables; i += mxf->index_tables[j++].nb_segments) {
         MXFIndexTable *t = &mxf->index_tables[j];
 
-        if (t->nb_segments >
-            (INT_MAX / sizeof(MXFIndexTableSegment *)) ||
-            !(t->segments = av_mallocz(t->nb_segments *
-                                       sizeof(MXFIndexTableSegment*)))) {
-            av_log(mxf->fc, AV_LOG_ERROR, "failed to allocate IndexTableSegment"
-                   " pointer array\n");
+        if (!(t->segments = av_calloc(t->nb_segments, sizeof(MXFIndexTableSegment*)))) {
+            av_log(mxf->fc, AV_LOG_ERROR, "failed to allocate IndexTableSegment pointer array\n");
             ret = AVERROR(ENOMEM);
             goto finish_decoding_index;
         }
@@ -1305,12 +1297,20 @@
     return ret;
 }
 
-static int mxf_is_intra_only(MXFDescriptor *d)
+static int mxf_is_intra_only(MXFDescriptor *descriptor)
 {
     return mxf_get_codec_ul(mxf_intra_only_essence_container_uls,
-                            &d->essence_container_ul)->id != AV_CODEC_ID_NONE ||
+                            &descriptor->essence_container_ul)->id != AV_CODEC_ID_NONE ||
            mxf_get_codec_ul(mxf_intra_only_picture_essence_coding_uls,
-                            &d->essence_codec_ul)->id     != AV_CODEC_ID_NONE;
+                            &descriptor->essence_codec_ul)->id     != AV_CODEC_ID_NONE;
+}
+
+static int mxf_add_timecode_metadata(AVDictionary **pm, const char *key, AVTimecode *tc)
+{
+    char buf[AV_TIMECODE_STR_SIZE];
+    av_dict_set(pm, key, av_timecode_make_string(tc, buf, 0), 0);
+
+    return 0;
 }
 
 static int mxf_parse_structural_metadata(MXFContext *mxf)
@@ -1337,25 +1337,48 @@
         MXFTrack *temp_track = NULL;
         MXFDescriptor *descriptor = NULL;
         MXFStructuralComponent *component = NULL;
+        MXFTimecodeComponent *mxf_tc = NULL;
         UID *essence_container_ul = NULL;
         const MXFCodecUL *codec_ul = NULL;
         const MXFCodecUL *container_ul = NULL;
         const MXFCodecUL *pix_fmt_ul = NULL;
         AVStream *st;
+        AVTimecode tc;
+        int flags;
 
         if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) {
             av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n");
             continue;
         }
 
+        if ((component = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, TimecodeComponent))) {
+            mxf_tc = (MXFTimecodeComponent*)component;
+            flags = mxf_tc->drop_frame == 1 ? AV_TIMECODE_FLAG_DROPFRAME : 0;
+            if (av_timecode_init(&tc, mxf_tc->rate, flags, mxf_tc->start_frame, mxf->fc) == 0) {
+                mxf_add_timecode_metadata(&mxf->fc->metadata, "timecode", &tc);
+            }
+        }
+
         if (!(material_track->sequence = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, Sequence))) {
             av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track sequence strong ref\n");
             continue;
         }
 
+        for (j = 0; j < material_track->sequence->structural_components_count; j++) {
+            component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j], TimecodeComponent);
+            if (!component)
+                continue;
+
+            mxf_tc = (MXFTimecodeComponent*)component;
+            flags = mxf_tc->drop_frame == 1 ? AV_TIMECODE_FLAG_DROPFRAME : 0;
+            if (av_timecode_init(&tc, mxf_tc->rate, flags, mxf_tc->start_frame, mxf->fc) == 0) {
+                mxf_add_timecode_metadata(&mxf->fc->metadata, "timecode", &tc);
+                break;
+            }
+        }
+
         /* TODO: handle multiple source clips */
         for (j = 0; j < material_track->sequence->structural_components_count; j++) {
-            /* TODO: handle timecode component */
             component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j], SourceClip);
             if (!component)
                 continue;
@@ -1474,33 +1497,27 @@
             if (st->codec->codec_id == AV_CODEC_ID_NONE)
                 st->codec->codec_id = container_ul->id;
             st->codec->width = descriptor->width;
-            /* Field height, not frame height */
-            st->codec->height = descriptor->height;
+            st->codec->height = descriptor->height; /* Field height, not frame height */
             switch (descriptor->frame_layout) {
                 case SegmentedFrame:
                     /* This one is a weird layout I don't fully understand. */
-                    av_log(mxf->fc, AV_LOG_INFO,
-                           "SegmentedFrame layout isn't currently supported\n");
+                    av_log(mxf->fc, AV_LOG_INFO, "SegmentedFrame layout isn't currently supported\n");
                     break;
                 case FullFrame:
                     break;
                 case OneField:
                     /* Every other line is stored and needs to be duplicated. */
-                    av_log(mxf->fc, AV_LOG_INFO,
-                           "OneField frame layout isn't currently supported\n");
-                    break;
-                    /* The correct thing to do here is fall through, but by
-                     * breaking we might be able to decode some streams at half
-                     * the vertical resolution, rather than not al all.
-                     * It's also for compatibility with the old behavior. */
-                case SeparateFields:
+                    av_log(mxf->fc, AV_LOG_INFO, "OneField frame layout isn't currently supported\n");
+                    break; /* The correct thing to do here is fall through, but by breaking we might be
+                              able to decode some streams at half the vertical resolution, rather than not al all.
+                              It's also for compatibility with the old behavior. */
                 case MixedFields:
-                    /* Turn field height into frame height. */
-                    st->codec->height *= 2;
+                    break;
+                case SeparateFields:
+                    st->codec->height *= 2; /* Turn field height into frame height. */
+                    break;
                 default:
-                    av_log(mxf->fc, AV_LOG_INFO,
-                           "Unknown frame layout type: %d\n",
-                           descriptor->frame_layout);
+                    av_log(mxf->fc, AV_LOG_INFO, "Unknown frame layout type: %d\n", descriptor->frame_layout);
             }
             if (st->codec->codec_id == AV_CODEC_ID_RAWVIDEO) {
                 st->codec->pix_fmt = descriptor->pix_fmt;
@@ -1522,7 +1539,8 @@
             st->need_parsing = AVSTREAM_PARSE_HEADERS;
         } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
             container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul);
-            if (st->codec->codec_id == AV_CODEC_ID_NONE)
+            /* Only overwrite existing codec ID if it is unset or A-law, which is the default according to SMPTE RP 224. */
+            if (st->codec->codec_id == AV_CODEC_ID_NONE || (st->codec->codec_id == AV_CODEC_ID_PCM_ALAW && container_ul->id != AV_CODEC_ID_NONE))
                 st->codec->codec_id = container_ul->id;
             st->codec->channels = descriptor->channels;
             st->codec->bits_per_coded_sample = descriptor->bits_per_sample;
@@ -1582,6 +1600,7 @@
     { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* AES3 */
     { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Static Track */
     { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Generic Track */
+    { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x14,0x00 }, mxf_read_timecode_component, sizeof(MXFTimecodeComponent), TimecodeComponent },
     { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 }, mxf_read_cryptographic_context, sizeof(MXFCryptoContext), CryptoContext },
     { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 }, mxf_read_index_table_segment, sizeof(MXFIndexTableSegment), IndexTableSegment },
     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType },
@@ -1595,7 +1614,7 @@
 
     if (!ctx)
         return AVERROR(ENOMEM);
-    while (avio_tell(pb) + 4 < klv_end && !pb->eof_reached) {
+    while (avio_tell(pb) + 4 < klv_end && !url_feof(pb)) {
         int ret;
         int tag = avio_rb16(pb);
         int size = avio_rb16(pb); /* KLV specified by 0x53 */
@@ -1709,8 +1728,7 @@
 }
 
 /**
- * Figure out the proper offset and length of the essence container
- * in each partition
+ * Figures out the proper offset and length of the essence container in each partition
  */
 static void mxf_compute_essence_containers(MXFContext *mxf)
 {
@@ -1750,38 +1768,6 @@
     return ret == position ? ret : ret + kag_size;
 }
 
-static inline void compute_partition_essence_offset(AVFormatContext *s,
-                                                    MXFContext *mxf,
-                                                    KLVPacket *klv)
-{
-    MXFPartition *cur_part = mxf->current_partition;
-    /* for OP1a we compute essence_offset
-     * for OPAtom we point essence_offset after the KL
-     *     (usually op1a_essence_offset + 20 or 25)
-     * TODO: for OP1a we could eliminate this entire if statement, always
-     *       stopping parsing at op1a_essence_offset
-     *       for OPAtom we still need the actual essence_offset though
-     *       (the KL's length can vary)
-     */
-    int64_t op1a_essence_offset =
-        round_to_kag(cur_part->this_partition + cur_part->pack_length,
-                     cur_part->kag_size) +
-        round_to_kag(cur_part->header_byte_count, cur_part->kag_size) +
-        round_to_kag(cur_part->index_byte_count, cur_part->kag_size);
-
-    if (mxf->op == OPAtom) {
-        /* point essence_offset to the actual data
-         * OPAtom has all the essence in one big KLV
-         */
-        cur_part->essence_offset = avio_tell(s->pb);
-        cur_part->essence_length = klv->length;
-    } else {
-        /* NOTE: op1a_essence_offset may be less than to klv.offset
-         * (C0023S01.mxf)  */
-        cur_part->essence_offset = op1a_essence_offset;
-    }
-}
-
 static int is_pcm(enum AVCodecID codec_id)
 {
     /* we only care about "normal" PCM codecs until we get samples */
@@ -1836,7 +1822,7 @@
     mxf->fc = s;
     mxf->run_in = avio_tell(s->pb);
 
-    while (!s->pb->eof_reached) {
+    while (!url_feof(s->pb)) {
         const MXFMetadataReadTableEntry *metadata;
 
         if (klv_read_packet(&klv, s->pb) < 0) {
@@ -1855,13 +1841,32 @@
             IS_KLV_KEY(klv.key, mxf_system_item_key)) {
 
             if (!mxf->current_partition) {
-                av_log(mxf->fc, AV_LOG_ERROR,
-                       "found essence prior to first PartitionPack\n");
+                av_log(mxf->fc, AV_LOG_ERROR, "found essence prior to first PartitionPack\n");
                 return AVERROR_INVALIDDATA;
             }
 
             if (!mxf->current_partition->essence_offset) {
-                compute_partition_essence_offset(s, mxf, &klv);
+                /* for OP1a we compute essence_offset
+                 * for OPAtom we point essence_offset after the KL (usually op1a_essence_offset + 20 or 25)
+                 * TODO: for OP1a we could eliminate this entire if statement, always stopping parsing at op1a_essence_offset
+                 *       for OPAtom we still need the actual essence_offset though (the KL's length can vary)
+                 */
+                int64_t op1a_essence_offset =
+                    round_to_kag(mxf->current_partition->this_partition +
+                                 mxf->current_partition->pack_length,       mxf->current_partition->kag_size) +
+                    round_to_kag(mxf->current_partition->header_byte_count, mxf->current_partition->kag_size) +
+                    round_to_kag(mxf->current_partition->index_byte_count,  mxf->current_partition->kag_size);
+
+                if (mxf->op == OPAtom) {
+                    /* point essence_offset to the actual data
+                    * OPAtom has all the essence in one big KLV
+                    */
+                    mxf->current_partition->essence_offset = avio_tell(s->pb);
+                    mxf->current_partition->essence_length = klv.length;
+                } else {
+                    /* NOTE: op1a_essence_offset may be less than to klv.offset (C0023S01.mxf)  */
+                    mxf->current_partition->essence_offset = op1a_essence_offset;
+                }
             }
 
             if (!essence_offset)
@@ -1954,11 +1959,9 @@
     if (mxf->nb_index_tables <= 0)
         return -1;
 
-    /* find mxf->current_edit_unit so that the next edit unit starts ahead
-     * of current_offset */
+    /* find mxf->current_edit_unit so that the next edit unit starts ahead of current_offset */
     while (mxf->current_edit_unit >= 0) {
-        if (mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit + 1,
-                                          NULL, &next_ofs, 0) < 0)
+        if (mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit + 1, NULL, &next_ofs, 0) < 0)
             return -1;
 
         if (next_ofs <= last_ofs) {
@@ -1976,8 +1979,7 @@
         mxf->current_edit_unit++;
     }
 
-    /* not checking mxf->current_edit_unit >= t->nb_ptses here since CBR files
-     * may lack IndexEntryArrays */
+    /* not checking mxf->current_edit_unit >= t->nb_ptses here since CBR files may lack IndexEntryArrays */
     if (mxf->current_edit_unit < 0)
         return -1;
 
@@ -1989,16 +1991,17 @@
     KLVPacket klv;
     MXFContext *mxf = s->priv_data;
 
-    while (!s->pb->eof_reached) {
+    while (!url_feof(s->pb)) {
+        int ret;
         if (klv_read_packet(&klv, s->pb) < 0)
             return -1;
         PRINT_KEY(s, "read packet", klv.key);
         av_dlog(s, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset);
         if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {
-            int res = mxf_decrypt_triplet(s, pkt, &klv);
-            if (res < 0) {
+            ret = mxf_decrypt_triplet(s, pkt, &klv);
+            if (ret < 0) {
                 av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
             return 0;
         }
@@ -2024,14 +2027,11 @@
             next_ofs = mxf_set_current_edit_unit(mxf, klv.offset);
 
             if (next_ofs >= 0 && next_klv > next_ofs) {
-                /* if this check is hit then it's possible OPAtom was treated
-                 * as OP1a truncate the packet since it's probably very large
-                 * (>2 GiB is common) */
+                /* if this check is hit then it's possible OPAtom was treated as OP1a
+                 * truncate the packet since it's probably very large (>2 GiB is common) */
                 av_log_ask_for_sample(s,
-                                      "KLV for edit unit %i extends into next "
-                                      "edit unit - OPAtom misinterpreted as "
-                                      "OP1a?\n",
-                                      mxf->current_edit_unit);
+                    "KLV for edit unit %i extends into next edit unit - OPAtom misinterpreted as OP1a?\n",
+                    mxf->current_edit_unit);
                 klv.length = next_ofs - avio_tell(s->pb);
             }
 
@@ -2039,10 +2039,10 @@
             if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) {
                 if (mxf_get_d10_aes3_packet(s->pb, s->streams[index], pkt, klv.length) < 0) {
                     av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
             } else {
-                int ret = av_get_packet(s->pb, pkt, klv.length);
+                ret = av_get_packet(s->pb, pkt, klv.length);
                 if (ret < 0)
                     return ret;
             }
@@ -2050,18 +2050,15 @@
             pkt->pos = klv.offset;
 
             if (s->streams[index]->codec->codec_type == AVMEDIA_TYPE_VIDEO && next_ofs >= 0) {
-                /* mxf->current_edit_unit good - see if we have an
-                 * index table to derive timestamps from */
+                /* mxf->current_edit_unit good - see if we have an index table to derive timestamps from */
                 MXFIndexTable *t = &mxf->index_tables[0];
 
-                if (mxf->nb_index_tables >= 1 &&
-                    mxf->current_edit_unit < t->nb_ptses) {
+                if (mxf->nb_index_tables >= 1 && mxf->current_edit_unit < t->nb_ptses) {
                     pkt->dts = mxf->current_edit_unit + t->first_dts;
                     pkt->pts = t->ptses[mxf->current_edit_unit];
                 } else if (track->intra_only) {
                     /* intra-only -> PTS = EditUnit.
-                     * let utils.c figure out DTS since it can be
-                     * < PTS if low_delay = 0 (Sony IMX30) */
+                     * let utils.c figure out DTS since it can be < PTS if low_delay = 0 (Sony IMX30) */
                     pkt->pts = mxf->current_edit_unit;
                 }
             }
@@ -2118,8 +2115,8 @@
     if ((ret64 = avio_seek(s->pb, pos, SEEK_SET)) < 0)
         return ret64;
 
-        if ((ret = av_get_packet(s->pb, pkt, size)) != size)
-            return ret < 0 ? ret : AVERROR_EOF;
+    if ((size = av_get_packet(s->pb, pkt, size)) < 0)
+        return size;
 
     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && t->ptses &&
         mxf->current_edit_unit >= 0 && mxf->current_edit_unit < t->nb_ptses) {
@@ -2133,7 +2130,6 @@
     return 0;
 }
 
-
 static int mxf_read_close(AVFormatContext *s)
 {
     MXFContext *mxf = s->priv_data;
@@ -2210,7 +2206,7 @@
     int ret;
     MXFIndexTable *t;
 
-    if (mxf->index_tables <= 0) {
+    if (mxf->nb_index_tables <= 0) {
     if (!s->bit_rate)
         return AVERROR_INVALIDDATA;
     if (sample_time < 0)
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index 995e411..b7e9449 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2008 GUCAS, Zhentan Feng <spyfeng at gmail dot com>
  * Copyright (c) 2008 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -35,15 +35,17 @@
 #include <math.h>
 #include <time.h>
 
+#include "libavutil/opt.h"
 #include "libavutil/random_seed.h"
+#include "libavutil/timecode.h"
+#include "libavutil/avassert.h"
 #include "libavcodec/bytestream.h"
+#include "libavcodec/dnxhddata.h"
 #include "audiointerleave.h"
 #include "avformat.h"
 #include "internal.h"
 #include "mxf.h"
-
-static const int NTSC_samples_per_frame[] = { 1602, 1601, 1602, 1601, 1602, 0 };
-static const int PAL_samples_per_frame[]  = { 1920, 0 };
+#include "config.h"
 
 extern AVOutputFormat ff_mxf_d10_muxer;
 
@@ -69,6 +71,8 @@
     const UID *codec_ul;
     int order;               ///< interleaving order if dts are equal
     int interlaced;          ///< whether picture is interlaced
+    int field_dominance;     ///< tff=1, bff=2
+    int component_depth;
     int temporal_reordering;
     AVRational aspect_ratio; ///< display aspect ratio
     int closed_gop;          ///< gop is closed, used in mpeg-2 frame parsing
@@ -88,6 +92,8 @@
     { AV_CODEC_ID_MPEG2VIDEO, 0 },
     { AV_CODEC_ID_PCM_S24LE,  1 },
     { AV_CODEC_ID_PCM_S16LE,  1 },
+    { AV_CODEC_ID_DVVIDEO,   15 },
+    { AV_CODEC_ID_DNXHD,     24 },
     { AV_CODEC_ID_NONE }
 };
 
@@ -164,6 +170,101 @@
       { 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
+    { { 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 },
+      mxf_write_cdci_desc },
+    // DV25 525/60
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x40,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,0x02,0x01,0x00 },
+      mxf_write_cdci_desc },
+    // DV25 625/50
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x41,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,0x02,0x02,0x00 },
+      mxf_write_cdci_desc },
+    // DV50 525/60
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x50,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,0x02,0x03,0x00 },
+      mxf_write_cdci_desc },
+    // DV50 625/50
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x51,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,0x02,0x04,0x00 },
+      mxf_write_cdci_desc },
+    // DV100 1080/60
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x60,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,0x02,0x05,0x00 },
+      mxf_write_cdci_desc },
+    // DV100 1080/50
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x61,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,0x02,0x06,0x00 },
+      mxf_write_cdci_desc },
+    // DV100 720/60
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x62,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,0x02,0x07,0x00 },
+      mxf_write_cdci_desc },
+    // DV100 720/50
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x63,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,0x02,0x08,0x00 },
+      mxf_write_cdci_desc },
+    // DNxHD 1080p 10bit high
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
+      { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
+      { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x01,0x00,0x00 },
+      mxf_write_cdci_desc },
+    // DNxHD 1080p 8bit medium
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
+      { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
+      { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x03,0x00,0x00 },
+      mxf_write_cdci_desc },
+    // DNxHD 1080p 8bit high
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
+      { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
+      { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x04,0x00,0x00 },
+      mxf_write_cdci_desc },
+    // DNxHD 1080i 10bit high
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
+      { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
+      { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x07,0x00,0x00 },
+      mxf_write_cdci_desc },
+    // DNxHD 1080i 8bit medium
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
+      { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
+      { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x08,0x00,0x00 },
+      mxf_write_cdci_desc },
+    // DNxHD 1080i 8bit high
+    { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
+      { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
+      { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x09,0x00,0x00 },
+      mxf_write_cdci_desc },
+    // DNxHD 720p 10bit
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
+      { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
+      { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x10,0x00,0x00 },
+      mxf_write_cdci_desc },
+    // DNxHD 720p 8bit high
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
+      { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
+      { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x11,0x00,0x00 },
+      mxf_write_cdci_desc },
+    // DNxHD 720p 8bit medium
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
+      { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
+      { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x12,0x00,0x00 },
+      mxf_write_cdci_desc },
+    // DNxHD 720p 8bit low
+    { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 },
+      { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 },
+      { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x13,0x00,0x00 },
+      mxf_write_cdci_desc },
     { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
       { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
       { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
@@ -171,6 +272,7 @@
 };
 
 typedef struct MXFContext {
+    AVClass *av_class;
     int64_t footer_partition_offset;
     int essence_container_count;
     AVRational time_base;
@@ -184,10 +286,9 @@
     unsigned body_partitions_count;
     int last_key_index;  ///< index of last key frame
     uint64_t duration;
+    AVTimecode tc;       ///< timecode context
     AVStream *timecode_track;
     int timecode_base;       ///< rounded time code base (25 or 30)
-    int timecode_start;      ///< frame number computed from mpeg-2 gop header timecode
-    int timecode_drop_frame; ///< time code use drop frame method frop mpeg-2 essence gop header
     int edit_unit_byte_count; ///< fixed edit unit byte count
     uint64_t body_offset;
     uint32_t instance_number;
@@ -280,6 +381,7 @@
     { 0x3208, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0B,0x00,0x00,0x00}}, /* Display Height */
     { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}}, /* Aspect Ratio */
     { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* Picture Essence Coding */
+    { 0x3212, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x01,0x06,0x00,0x00,0x00}}, /* Field Dominance (Opt) */
     // CDCI Picture Essence Descriptor
     { 0x3301, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x03,0x0A,0x00,0x00,0x00}}, /* Component Depth */
     { 0x3302, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x05,0x00,0x00,0x00}}, /* Horizontal Subsampling */
@@ -500,7 +602,7 @@
 {
     MXFContext *mxf = s->priv_data;
     AVIOContext *pb = s->pb;
-    const char *company = "Libav";
+    const char *company = "FFmpeg";
     const char *product = "OP1a Muxer";
     const char *version;
     int length;
@@ -665,7 +767,7 @@
 
     // Start Time Code
     mxf_write_local_tag(pb, 8, 0x1501);
-    avio_wb64(pb, mxf->timecode_start);
+    avio_wb64(pb, mxf->tc.start);
 
     // Rounded Time Code Base
     mxf_write_local_tag(pb, 2, 0x1502);
@@ -673,7 +775,7 @@
 
     // Drop Frame
     mxf_write_local_tag(pb, 1, 0x1503);
-    avio_w8(pb, mxf->timecode_drop_frame);
+    avio_w8(pb, !!(mxf->tc.flags & AV_TIMECODE_FLAG_DROPFRAME));
 }
 
 static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type)
@@ -785,8 +887,11 @@
     int stored_height = (st->codec->height+15)/16*16;
     int display_height;
     int f1, f2;
+    unsigned desc_size = size+8+8+8+8+8+8+5+16+sc->interlaced*4+12+20;
+    if (sc->interlaced && sc->field_dominance)
+        desc_size += 5;
 
-    mxf_write_generic_desc(s, st, key, size+8+8+8+8+8+8+5+16+sc->interlaced*4+12+20);
+    mxf_write_generic_desc(s, st, key, desc_size);
 
     mxf_write_local_tag(pb, 4, 0x3203);
     avio_wb32(pb, st->codec->width);
@@ -809,7 +914,7 @@
 
     // component depth
     mxf_write_local_tag(pb, 4, 0x3301);
-    avio_wb32(pb, 8);
+    avio_wb32(pb, sc->component_depth);
 
     // horizontal subsampling
     mxf_write_local_tag(pb, 4, 0x3302);
@@ -821,9 +926,9 @@
 
     // video line map
     switch (st->codec->height) {
-    case  576: f1 = 23; f2 = 336; break;
+    case  576: f1 = 23; f2 = st->codec->codec_id == AV_CODEC_ID_DVVIDEO ? 335 : 336; break;
     case  608: f1 =  7; f2 = 320; break;
-    case  480: f1 = 20; f2 = 283; break;
+    case  480: f1 = 20; f2 = st->codec->codec_id == AV_CODEC_ID_DVVIDEO ? 285 : 283; break;
     case  512: f1 =  7; f2 = 270; break;
     case  720: f1 = 26; f2 =   0; break; // progressive
     case 1080: f1 = 21; f2 = 584; break;
@@ -848,6 +953,12 @@
 
     mxf_write_local_tag(pb, 16, 0x3201);
     avio_write(pb, *sc->codec_ul, 16);
+
+    if (sc->interlaced && sc->field_dominance) {
+        mxf_write_local_tag(pb, 1, 0x3212);
+        avio_w8(pb, sc->field_dominance);
+    }
+
 }
 
 static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st)
@@ -1179,7 +1290,7 @@
         klv_encode_ber4_length(s->pb, pad);
         for (; pad; pad--)
             avio_w8(s->pb, 0);
-        assert(!(avio_tell(s->pb) & (KAG_SIZE-1)));
+        av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1)));
     }
 }
 
@@ -1276,6 +1387,155 @@
     avio_flush(pb);
 }
 
+static int mxf_parse_dnxhd_frame(AVFormatContext *s, AVStream *st,
+AVPacket *pkt)
+{
+    MXFContext *mxf = s->priv_data;
+    MXFStreamContext *sc = st->priv_data;
+    int i, cid;
+    uint8_t* header_cid;
+    unsigned int frame_size = 0;
+
+    if (mxf->header_written)
+        return 1;
+
+    if (pkt->size < 43)
+        return -1;
+
+    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)
+        return -1;
+
+    switch (cid) {
+    case 1235:
+        sc->index = 24;
+        sc->component_depth = 10;
+        break;
+    case 1237:
+        sc->index = 25;
+        break;
+    case 1238:
+        sc->index = 26;
+        break;
+    case 1241:
+        sc->index = 27;
+        sc->component_depth = 10;
+        break;
+    case 1242:
+        sc->index = 28;
+        break;
+    case 1243:
+        sc->index = 29;
+        break;
+    case 1250:
+        sc->index = 30;
+        sc->component_depth = 10;
+        break;
+    case 1251:
+        sc->index = 31;
+        break;
+    case 1252:
+        sc->index = 32;
+        break;
+    case 1253:
+        sc->index = 33;
+        break;
+    default:
+        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 };
+
+    mxf->edit_unit_byte_count = KAG_SIZE;
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st = s->streams[i];
+        MXFStreamContext *sc = st->priv_data;
+        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+            mxf->edit_unit_byte_count += 16 + 4 + sc->aic.samples[0]*sc->aic.sample_size;
+            mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
+        } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+            mxf->edit_unit_byte_count += 16 + 4 + frame_size;
+            mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
+        }
+    }
+
+    return 1;
+}
+
+static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt)
+{
+    MXFContext *mxf = s->priv_data;
+    MXFStreamContext *sc = st->priv_data;
+    uint8_t *vs_pack, *vsc_pack;
+    int i, ul_index, frame_size, stype, pal;
+
+    if (mxf->header_written)
+        return 1;
+
+    // Check for minimal frame size
+    if (pkt->size < 120000)
+        return -1;
+
+    vs_pack  = pkt->data + 80*5 + 48;
+    vsc_pack = pkt->data + 80*5 + 53;
+    stype    = vs_pack[3] & 0x1f;
+    pal      = (vs_pack[3] >> 5) & 0x1;
+
+    if ((vs_pack[2] & 0x07) == 0x02)
+        sc->aspect_ratio = (AVRational){ 16, 9 };
+    else
+        sc->aspect_ratio = (AVRational){ 4, 3 };
+
+    sc->interlaced = (vsc_pack[3] >> 4) & 0x01;
+    // TODO: fix dv encoder to set proper FF/FS value in VSC pack
+    // and set field dominance accordingly
+    // av_log(s, AV_LOG_DEBUG, "DV vsc pack ff/ss = %x\n", vsc_pack[2] >> 6);
+
+    switch (stype) {
+    case 0x18: // DV100 720p
+        ul_index = 6 + pal;
+        frame_size = pal ? 288000 : 240000;
+        if (sc->interlaced) {
+            av_log(s, AV_LOG_ERROR, "source marked as interlaced but codec profile is progressive\n");
+            sc->interlaced = 0;
+        }
+        break;
+    case 0x14: // DV100 1080i
+        ul_index = 4 + pal;
+        frame_size = pal ? 576000 : 480000;
+        break;
+    case 0x04: // DV50
+        ul_index = 2 + pal;
+        frame_size = pal ? 288000 : 240000;
+        break;
+    default: // DV25
+        ul_index = 0 + pal;
+        frame_size = pal ? 144000 : 120000;
+    }
+
+    sc->index = ul_index + 16;
+    sc->codec_ul =  &mxf_essence_container_uls[sc->index].codec_ul;
+
+    mxf->edit_unit_byte_count = KAG_SIZE;
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st = s->streams[i];
+        MXFStreamContext *sc = st->priv_data;
+        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+            mxf->edit_unit_byte_count += 16 + 4 + sc->aic.samples[0]*sc->aic.sample_size;
+            mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
+        } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+            mxf->edit_unit_byte_count += 16 + 4 + frame_size;
+            mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
+        }
+    }
+
+    return 1;
+}
+
 static const UID mxf_mpeg2_codec_uls[] = {
     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x10,0x00 }, // MP-ML I-Frame
     { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, // MP-ML Long GOP
@@ -1313,7 +1573,6 @@
                                  AVPacket *pkt, MXFIndexEntry *e)
 {
     MXFStreamContext *sc = st->priv_data;
-    MXFContext *mxf = s->priv_data;
     uint32_t c = -1;
     int i;
 
@@ -1325,6 +1584,8 @@
                 st->codec->level   = pkt->data[i+2] >> 4;
             } else if (i + 5 < pkt->size && (pkt->data[i+1] & 0xf0) == 0x80) { // pict coding ext
                 sc->interlaced = !(pkt->data[i+5] & 0x80); // progressive frame
+                if (sc->interlaced)
+                    sc->field_dominance = 1 + !(pkt->data[i+4] & 0x80); // top field first
                 break;
             }
         } else if (c == 0x1b8) { // gop
@@ -1333,21 +1594,6 @@
                 if (e->flags & 0x40) // sequence header present
                     e->flags |= 0x80; // random access
             }
-            if (!mxf->header_written) {
-                unsigned hours   =  (pkt->data[i+1]>>2) & 0x1f;
-                unsigned minutes = ((pkt->data[i+1] & 0x03) << 4) | (pkt->data[i+2]>>4);
-                unsigned seconds = ((pkt->data[i+2] & 0x07) << 3) | (pkt->data[i+3]>>5);
-                unsigned frames  = ((pkt->data[i+3] & 0x1f) << 1) | (pkt->data[i+4]>>7);
-                mxf->timecode_drop_frame = !!(pkt->data[i+1] & 0x80);
-                mxf->timecode_start = (hours*3600 + minutes*60 + seconds) *
-                    mxf->timecode_base + frames;
-                if (mxf->timecode_drop_frame) {
-                    unsigned tminutes = 60 * hours + minutes;
-                    mxf->timecode_start -= 2 * (tminutes - tminutes / 10);
-                }
-                av_log(s, AV_LOG_DEBUG, "frame %d %d:%d:%d%c%d\n", mxf->timecode_start,
-                       hours, minutes, seconds, mxf->timecode_drop_frame ? ';':':', frames);
-            }
         } else if (c == 0x1b3) { // seq
             e->flags |= 0x40;
             switch ((pkt->data[i+4]>>4) & 0xf) {
@@ -1409,11 +1655,12 @@
 static int mxf_write_header(AVFormatContext *s)
 {
     MXFContext *mxf = s->priv_data;
-    int i;
+    int i, ret;
     uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0};
-    const int *samples_per_frame = NULL;
+    const MXFSamplesPerFrame *spf = NULL;
     AVDictionaryEntry *t;
     int64_t timestamp = 0;
+    AVDictionaryEntry *tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
 
     if (!s->nb_streams)
         return -1;
@@ -1425,24 +1672,33 @@
             return AVERROR(ENOMEM);
         st->priv_data = sc;
 
+        if ((i == 0) ^ (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)) {
+            av_log(s, AV_LOG_ERROR, "there must be exactly one video stream and it must be the first one\n");
+            return -1;
+        }
+
         if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
-            if (i != 0) {
-                av_log(s, AV_LOG_ERROR, "video stream must be first track\n");
-                return -1;
+            AVRational rate, tbc = st->codec->time_base;
+            // Default component depth to 8
+            sc->component_depth = 8;
+            mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num;
+            spf = ff_mxf_get_samples_per_frame(s, tbc);
+            if (!spf) {
+                av_log(s, AV_LOG_ERROR, "Unsupported video frame rate %d/%d\n",
+                       tbc.den, tbc.num);
+                return AVERROR(EINVAL);
             }
-            if (fabs(av_q2d(st->codec->time_base) - 1/25.0) < 0.0001) {
-                samples_per_frame = PAL_samples_per_frame;
-                mxf->time_base = (AVRational){ 1, 25 };
-                mxf->timecode_base = 25;
-            } else if (fabs(av_q2d(st->codec->time_base) - 1001/30000.0) < 0.0001) {
-                samples_per_frame = NTSC_samples_per_frame;
-                mxf->time_base = (AVRational){ 1001, 30000 };
-                mxf->timecode_base = 30;
-            } else {
-                av_log(s, AV_LOG_ERROR, "unsupported video frame rate\n");
-                return -1;
-            }
+            mxf->time_base = spf->time_base;
+            rate = av_inv_q(mxf->time_base);
             avpriv_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den);
+            if (!tcr)
+                tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
+            if (tcr)
+                ret = av_timecode_init_from_string(&mxf->tc, rate, tcr->value, s);
+            else
+                ret = av_timecode_init(&mxf->tc, rate, 0, 0, s);
+            if (ret < 0)
+                return ret;
             if (s->oformat == &ff_mxf_d10_muxer) {
                 if (st->codec->bit_rate == 50000000)
                     if (mxf->time_base.den == 25) sc->index = 3;
@@ -1462,7 +1718,7 @@
                 mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)st->codec->bit_rate *
                     mxf->time_base.num / (8*mxf->time_base.den);
                 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
-                mxf->edit_unit_byte_count += 16 + 4 + 4 + samples_per_frame[0]*8*4;
+                mxf->edit_unit_byte_count += 16 + 4 + 4 + spf->samples_per_frame[0]*8*4;
                 mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count);
             }
         } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
@@ -1516,7 +1772,10 @@
         MXFStreamContext *sc = s->streams[i]->priv_data;
         // update element count
         sc->track_essence_element_key[13] = present[sc->index];
-        sc->order = AV_RB32(sc->track_essence_element_key+12);
+        if (!memcmp(sc->track_essence_element_key, mxf_essence_container_uls[15].element_ul, 13)) // DV
+            sc->order = (0x15 << 24) | AV_RB32(sc->track_essence_element_key+13);
+        else
+            sc->order = AV_RB32(sc->track_essence_element_key+12);
     }
 
     if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
@@ -1533,10 +1792,10 @@
         return AVERROR(ENOMEM);
     mxf->timecode_track->index = -1;
 
-    if (!samples_per_frame)
-        samples_per_frame = PAL_samples_per_frame;
+    if (!spf)
+        spf = ff_mxf_get_samples_per_frame(s, (AVRational){ 1, 25 });
 
-    if (ff_audio_interleave_init(s, samples_per_frame, mxf->time_base) < 0)
+    if (ff_audio_interleave_init(s, spf->samples_per_frame, mxf->time_base) < 0)
         return -1;
 
     return 0;
@@ -1545,24 +1804,6 @@
 static const uint8_t system_metadata_pack_key[]        = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x01,0x00 };
 static const uint8_t system_metadata_package_set_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x43,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x02,0x01 };
 
-static uint32_t ff_framenum_to_12m_time_code(unsigned frame, int drop, int fps)
-{
-    return (0                                    << 31) | // color frame flag
-           (drop                                 << 30) | // drop  frame flag
-           ( ((frame % fps) / 10)                << 28) | // tens  of frames
-           ( ((frame % fps) % 10)                << 24) | // units of frames
-           (0                                    << 23) | // field phase (NTSC), b0 (PAL)
-           ((((frame / fps) % 60) / 10)          << 20) | // tens  of seconds
-           ((((frame / fps) % 60) % 10)          << 16) | // units of seconds
-           (0                                    << 15) | // b0 (NTSC), b2 (PAL)
-           ((((frame / (fps * 60)) % 60) / 10)   << 12) | // tens  of minutes
-           ((((frame / (fps * 60)) % 60) % 10)   <<  8) | // units of minutes
-           (0                                    <<  7) | // b1
-           (0                                    <<  6) | // b2 (NTSC), field phase (PAL)
-           ((((frame / (fps * 3600) % 24)) / 10) <<  4) | // tens  of hours
-           (  (frame / (fps * 3600) % 24)) % 10;          // units of hours
-}
-
 static void mxf_write_system_item(AVFormatContext *s)
 {
     MXFContext *mxf = s->priv_data;
@@ -1570,7 +1811,7 @@
     unsigned frame;
     uint32_t time_code;
 
-    frame = mxf->timecode_start + mxf->last_indexed_edit_unit + mxf->edit_units_count;
+    frame = mxf->last_indexed_edit_unit + mxf->edit_units_count;
 
     // write system metadata pack
     avio_write(pb, system_metadata_pack_key, 16);
@@ -1579,7 +1820,7 @@
     avio_w8(pb, 0x04); // content package rate
     avio_w8(pb, 0x00); // content package type
     avio_wb16(pb, 0x00); // channel handle
-    avio_wb16(pb, frame); // continuity count
+    avio_wb16(pb, mxf->tc.start + frame); // continuity count
     if (mxf->essence_container_count > 1)
         avio_write(pb, multiple_desc_ul, 16);
     else {
@@ -1591,7 +1832,7 @@
     avio_wb64(pb, 0); // creation date/time stamp
 
     avio_w8(pb, 0x81); // SMPTE 12M time code
-    time_code = ff_framenum_to_12m_time_code(frame, mxf->timecode_drop_frame, mxf->timecode_base);
+    time_code = av_timecode_get_smpte_from_framenum(&mxf->tc, frame);
     avio_wb32(pb, time_code);
     avio_wb32(pb, 0); // binary group data
     avio_wb64(pb, 0);
@@ -1626,7 +1867,7 @@
         klv_encode_ber4_length(s->pb, pad);
         for (; pad; pad--)
             avio_w8(s->pb, 0);
-        assert(!(avio_tell(s->pb) & (KAG_SIZE-1)));
+        av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1)));
     } else {
         av_log(s, AV_LOG_WARNING, "cannot fill d-10 video packet\n");
         for (; pad > 0; pad--)
@@ -1688,6 +1929,16 @@
             av_log(s, AV_LOG_ERROR, "could not get mpeg2 profile and level\n");
             return -1;
         }
+    } else if (st->codec->codec_id == AV_CODEC_ID_DNXHD) {
+        if (!mxf_parse_dnxhd_frame(s, st, pkt)) {
+            av_log(s, AV_LOG_ERROR, "could not get dnxhd profile\n");
+            return -1;
+        }
+    } else if (st->codec->codec_id == AV_CODEC_ID_DVVIDEO) {
+        if (!mxf_parse_dv_frame(s, st, pkt)) {
+            av_log(s, AV_LOG_ERROR, "could not get dv profile\n");
+            return -1;
+        }
     }
 
     if (!mxf->header_written) {
@@ -1856,7 +2107,7 @@
         }
 
         *out = pktl->pkt;
-        av_dlog(s, "out st:%d dts:%lld\n", (*out).stream_index, (*out).dts);
+        av_dlog(s, "out st:%d dts:%"PRId64"\n", (*out).stream_index, (*out).dts);
         s->packet_buffer = pktl->next;
         if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl)
             s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL;
diff --git a/libavformat/mxg.c b/libavformat/mxg.c
index 09653ee..be7e6db 100644
--- a/libavformat/mxg.c
+++ b/libavformat/mxg.c
@@ -2,20 +2,20 @@
  * MxPEG clip file demuxer
  * Copyright (c) 2010 Anatoly Nenashev
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -104,7 +104,7 @@
     /* reallocate internal buffer */
     if (current_pos > current_pos + cache_size)
         return AVERROR(ENOMEM);
-    if (mxg->soi_ptr) soi_pos = mxg->soi_ptr - mxg->buffer;
+    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);
@@ -131,7 +131,7 @@
     uint8_t *startmarker_ptr, *end, *search_end, marker;
     MXGContext *mxg = s->priv_data;
 
-    while (!s->pb->eof_reached && !s->pb->error){
+    while (!url_feof(s->pb) && !s->pb->error){
         if (mxg->cache_size <= OVERREAD_SIZE) {
             /* update internal buffer */
             ret = mxg_update_cache(s, DEFAULT_PACKET_SIZE + OVERREAD_SIZE);
diff --git a/libavformat/ncdec.c b/libavformat/ncdec.c
index 40d8dac..8cb7ed4 100644
--- a/libavformat/ncdec.c
+++ b/libavformat/ncdec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2009  Nicolas Martin (martinic at iro dot umontreal dot ca)
  *                     Edouard Auvinet
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -67,7 +67,7 @@
 
     uint32_t state=-1;
     while (state != NC_VIDEO_FLAG) {
-        if (s->pb->eof_reached)
+        if (url_feof(s->pb))
             return AVERROR(EIO);
         state = (state<<8) + avio_r8(s->pb);
     }
diff --git a/libavformat/network.c b/libavformat/network.c
index 5b2b958..3e142fc 100644
--- a/libavformat/network.c
+++ b/libavformat/network.c
@@ -18,9 +18,12 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/avutil.h"
 #include "network.h"
 #include "libavcodec/internal.h"
 #include "libavutil/mem.h"
+#include "url.h"
+#include "libavutil/time.h"
 
 #define THREADS (HAVE_PTHREADS || (defined(WIN32) && !defined(__MINGW32CE__)))
 
@@ -149,6 +152,26 @@
     return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 : AVERROR(EAGAIN);
 }
 
+int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb)
+{
+    int ret;
+    int64_t wait_start = 0;
+
+    while (1) {
+        ret = ff_network_wait_fd(fd, write);
+        if (ret != AVERROR(EAGAIN))
+            return ret;
+        if (ff_check_interrupt(int_cb))
+            return AVERROR_EXIT;
+        if (timeout) {
+            if (!wait_start)
+                wait_start = av_gettime();
+            else if (av_gettime() - wait_start > timeout)
+                return AVERROR(ETIMEDOUT);
+        }
+    }
+}
+
 void ff_network_close(void)
 {
 #if HAVE_WINSOCK2_H
diff --git a/libavformat/network.h b/libavformat/network.h
index 19c5a92..51d855d 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -1,20 +1,20 @@
 /*
- * Copyright (c) 2007 The Libav Project
+ * Copyright (c) 2007 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "libavutil/error.h"
 #include "os_support.h"
+#include "avio.h"
 
 #if HAVE_UNISTD_H
 #include <unistd.h>
@@ -80,6 +81,18 @@
 
 int ff_network_wait_fd(int fd, int write);
 
+/**
+ * This works similarly to ff_network_wait_fd, but waits up to 'timeout' microseconds
+ * Uses ff_network_wait_fd in a loop
+ *
+ * @fd Socket descriptor
+ * @write Set 1 to wait for socket able to be read, 0 to be written
+ * @timeout Timeout interval, in microseconds. Actual precision is 100000 mcs, due to ff_network_wait_fd usage
+ * @param int_cb Interrupt callback, is checked after each ff_network_wait_fd call
+ * @return 0 if data can be read/written, AVERROR(ETIMEDOUT) if timeout expired, or negative error code
+ */
+int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb);
+
 int ff_inet_aton (const char * str, struct in_addr * add);
 
 #if !HAVE_STRUCT_SOCKADDR_STORAGE
diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c
index 654a968..e64fffb 100644
--- a/libavformat/nsvdec.c
+++ b/libavformat/nsvdec.c
@@ -1,21 +1,21 @@
 /*
  * NSV demuxer
- * Copyright (c) 2004 The Libav Project
+ * Copyright (c) 2004 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,7 @@
 #include "internal.h"
 #include "riff.h"
 #include "libavutil/dict.h"
+#include "libavutil/intreadwrite.h"
 
 //#define DEBUG_DUMP_INDEX // XXX dumbdriving-271.nsv breaks with it commented!!
 #define CHECK_SUBSEQUENT_NSVS
@@ -73,11 +74,7 @@
  * so the header seems to not be mandatory. (for streaming).
  *
  * index slice duration check (excepts nsvtrailer.nsv):
- * for f in [^n]*.nsv; do
- *     DUR="$(avconv -i "$f" 2> /dev/null | grep 'NSVf duration' | cut -d ' ' -f 4)"
- *     IC="$(avconv -i "$f" 2> /dev/null | grep 'INDEX ENTRIES' | cut -d ' ' -f 2)"
- *     echo "duration $DUR, slite time $(($DUR/$IC))"
- * done
+ * for f in [^n]*.nsv; do DUR="$(ffmpeg -i "$f" 2>/dev/null | grep 'NSVf duration' | cut -d ' ' -f 4)"; IC="$(ffmpeg -i "$f" 2>/dev/null | grep 'INDEX ENTRIES' | cut -d ' ' -f 2)"; echo "duration $DUR, slite time $(($DUR/$IC))"; done
  */
 
 /*
@@ -103,8 +100,8 @@
     uint32_t chunk_tag; /* 'NSVs' */
     uint32_t v4cc;      /* or 'NONE' */
     uint32_t a4cc;      /* or 'NONE' */
-    uint16_t vwidth;    /* assert(vwidth%16==0) */
-    uint16_t vheight;   /* assert(vheight%16==0) */
+    uint16_t vwidth;    /* av_assert(vwidth%16==0) */
+    uint16_t vheight;   /* av_assert(vheight%16==0) */
     uint8_t framerate;  /* value = (framerate&0x80)?frtable[frameratex0x7f]:framerate */
     uint16_t unknown;
 };
@@ -196,6 +193,7 @@
     { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', '0') },
     { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', '1') },
     { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') },
+    { AV_CODEC_ID_VP8, MKTAG('V', 'P', '8', '0') },
 /*
     { AV_CODEC_ID_VP4, MKTAG('V', 'P', '4', ' ') },
     { AV_CODEC_ID_VP4, MKTAG('V', 'P', '4', '0') },
@@ -209,6 +207,7 @@
     { AV_CODEC_ID_MP3,       MKTAG('M', 'P', '3', ' ') },
     { AV_CODEC_ID_AAC,       MKTAG('A', 'A', 'C', ' ') },
     { AV_CODEC_ID_AAC,       MKTAG('A', 'A', 'C', 'P') },
+    { AV_CODEC_ID_AAC,       MKTAG('V', 'L', 'B', ' ') },
     { AV_CODEC_ID_SPEEX,     MKTAG('S', 'P', 'X', ' ') },
     { AV_CODEC_ID_PCM_U16LE, MKTAG('P', 'C', 'M', ' ') },
     { AV_CODEC_ID_NONE,      0 },
@@ -237,7 +236,7 @@
     //nsv->state = NSV_UNSYNC;
 
     for (i = 0; i < NSV_MAX_RESYNC; i++) {
-        if (pb->eof_reached) {
+        if (url_feof(pb)) {
             av_dlog(s, "NSV EOF\n");
             nsv->state = NSV_UNSYNC;
             return -1;
@@ -304,7 +303,7 @@
     table_entries_used = avio_rl32(pb);
     av_dlog(s, "NSV NSVf info-strings size: %d, table entries: %d, bis %d\n",
             strings_size, table_entries, table_entries_used);
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return -1;
 
     av_dlog(s, "NSV got header; filepos %"PRId64"\n", avio_tell(pb));
@@ -341,7 +340,7 @@
         }
         av_free(strings);
     }
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return -1;
 
     av_dlog(s, "NSV got infos; filepos %"PRId64"\n", avio_tell(pb));
@@ -392,7 +391,7 @@
 
     avio_seek(pb, nsv->base_offset + size, SEEK_SET); /* required for dumbdriving-271.nsv (2 extra bytes) */
 
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return -1;
     nsv->state = NSV_HAS_READ_NSVF;
     return 0;
@@ -574,7 +573,7 @@
         return 0; //-1; /* hey! eat what you've in your plate first! */
 
 null_chunk_retry:
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return -1;
 
     for (i = 0; i < NSV_MAX_RESYNC_TRIES && nsv->state < NSV_FOUND_NSVS && !err; i++)
@@ -609,7 +608,7 @@
         vsize -= auxsize + sizeof(uint16_t) + sizeof(uint32_t); /* that's becoming braindead */
     }
 
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return -1;
     if (!vsize && !asize) {
         nsv->state = NSV_UNSYNC;
@@ -759,10 +758,8 @@
 
 static int nsv_probe(AVProbeData *p)
 {
-    int i;
-    int score;
-    int vsize, asize, auxcount;
-    score = 0;
+    int i, score = 0;
+
     av_dlog(NULL, "nsv_probe(), buf_size %d\n", p->buf_size);
     /* check file header */
     /* streamed files might not have any header */
@@ -774,19 +771,14 @@
     /* seems the servers don't bother starting clean chunks... */
     /* sometimes even the first header is at 9KB or something :^) */
     for (i = 1; i < p->buf_size - 3; i++) {
-        if (p->buf[i+0] == 'N' && p->buf[i+1] == 'S' &&
-            p->buf[i+2] == 'V' && p->buf[i+3] == 's') {
-            score = AVPROBE_SCORE_MAX/5;
+        if (AV_RL32(p->buf + i) == AV_RL32("NSVs")) {
             /* Get the chunk size and check if at the end we are getting 0xBEEF */
-            auxcount = p->buf[i+19];
-            vsize = p->buf[i+20]  | p->buf[i+21] << 8;
-            asize = p->buf[i+22]  | p->buf[i+23] << 8;
-            vsize = (vsize << 4) | (auxcount >> 4);
-            if ((asize + vsize + i + 23) <  p->buf_size - 2) {
-                if (p->buf[i+23+asize+vsize+1] == 0xEF &&
-                    p->buf[i+23+asize+vsize+2] == 0xBE)
-                    return AVPROBE_SCORE_MAX-20;
-            }
+            int vsize = AV_RL24(p->buf+i+19) >> 4;
+            int asize = AV_RL16(p->buf+i+22);
+            int offset = i + 23 + asize + vsize + 1;
+            if (offset <= p->buf_size - 2 && AV_RL16(p->buf + offset) == 0xBEEF)
+                return 4*AVPROBE_SCORE_MAX/5;
+            score = AVPROBE_SCORE_MAX/5;
         }
     }
     /* so we'll have more luck on extension... */
diff --git a/libavformat/nullenc.c b/libavformat/nullenc.c
index 829f2a8..7da297b 100644
--- a/libavformat/nullenc.c
+++ b/libavformat/nullenc.c
@@ -2,20 +2,20 @@
  * RAW null muxer
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/nut.c b/libavformat/nut.c
index 6a68e28..02dd122 100644
--- a/libavformat/nut.c
+++ b/libavformat/nut.c
@@ -2,20 +2,20 @@
  * nut
  * Copyright (c) 2004-2007 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,6 +29,7 @@
     { AV_CODEC_ID_SSA         , MKTAG('S', 'S', 'A',  0 ) },
     { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('D', 'V', 'D', 'S') },
     { AV_CODEC_ID_DVB_SUBTITLE, MKTAG('D', 'V', 'B', 'S') },
+    { AV_CODEC_ID_DVB_TELETEXT, MKTAG('D', 'V', 'B', 'T') },
     { AV_CODEC_ID_NONE        , 0                         }
 };
 
@@ -46,9 +47,13 @@
     { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 'B', 'G', 'R') },
     { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 'R', 'G', 'B') },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 'A') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B',  0 ) },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 'A') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R',  0 ) },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'B', 'G', 'R') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG( 0 , 'B', 'G', 'R') },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'R', 'G', 'B') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG( 0 , 'R', 'G', 'B') },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 24 ) },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 24 ) },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '1', '1', 'P') },
@@ -70,12 +75,28 @@
     { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 48 ) },
     { AV_CODEC_ID_RAWVIDEO, MKTAG(48 , 'B', 'G', 'R') },
     { AV_CODEC_ID_RAWVIDEO, MKTAG(48 , 'R', 'G', 'B') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'R', 'A', 64 ) },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'B', 'A', 64 ) },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG(64 , 'B', 'R', 'A') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG(64 , 'R', 'B', 'A') },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 10 ) },
     { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 11 , '3', 'Y') },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 10 ) },
     { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 10 , '3', 'Y') },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3',  0 , 10 ) },
     { AV_CODEC_ID_RAWVIDEO, MKTAG(10 ,  0 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 12 ) },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 11 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 12 ) },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 10 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3',  0 , 12 ) },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG(12 ,  0 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 14 ) },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG(14 , 11 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 14 ) },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG(14 , 10 , '3', 'Y') },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3',  0 , 14 ) },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG(14 ,  0 , '3', 'Y') },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1',  0 , 16 ) },
     { AV_CODEC_ID_RAWVIDEO, MKTAG(16 ,  0 , '1', 'Y') },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 16 ) },
@@ -85,6 +106,8 @@
     { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3',  0 , 16 ) },
     { AV_CODEC_ID_RAWVIDEO, MKTAG(16 ,  0 , '3', 'Y') },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 ,  8 ) },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 ,  8 ) },
+    { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4',  0 ,  8 ) },
     { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '2',  0 ,  8 ) },
     { AV_CODEC_ID_NONE    , 0                         }
 };
@@ -118,6 +141,8 @@
     Syncpoint *sp= av_mallocz(sizeof(Syncpoint));
     struct AVTreeNode *node = av_tree_node_alloc();
 
+    nut->sp_count++;
+
     sp->pos= pos;
     sp->back_ptr= back_ptr;
     sp->ts= ts;
diff --git a/libavformat/nut.h b/libavformat/nut.h
index 3f09689..53b5ebc 100644
--- a/libavformat/nut.h
+++ b/libavformat/nut.h
@@ -2,20 +2,20 @@
  * "NUT" Container Format (de)muxer
  * Copyright (c) 2006 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -79,6 +79,7 @@
     int msb_pts_shift;
     int max_pts_distance;
     int decode_delay; //FIXME duplicate of has_b_frames
+    int64_t *keyframe_pts;
 } StreamContext;
 
 typedef struct ChapterContext {
@@ -101,6 +102,9 @@
     int header_count;
     AVRational *time_base;
     struct AVTreeNode *syncpoints;
+    int sp_count;
+    int64_t max_pts;
+    AVRational *max_pts_tb;
 } NUTContext;
 
 extern const AVCodecTag ff_nut_subtitle_tags[];
diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index dd02aad..b2bbb9a 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -3,24 +3,25 @@
  * Copyright (c) 2004-2006 Michael Niedermayer
  * Copyright (c) 2003 Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/avstring.h"
+#include "libavutil/avassert.h"
 #include "libavutil/bswap.h"
 #include "libavutil/dict.h"
 #include "libavutil/mathematics.h"
@@ -28,11 +29,11 @@
 #include "avio_internal.h"
 #include "nut.h"
 
-#undef NDEBUG
-#include <assert.h>
-
 #define NUT_MAX_STREAMS 256    /* arbitrary sanity check value */
 
+static int64_t nut_read_timestamp(AVFormatContext *s, int stream_index,
+                                  int64_t *pos_arg, int64_t pos_limit);
+
 static int get_str(AVIOContext *bc, char *string, unsigned int maxlen)
 {
     unsigned int len = ffio_read_varlen(bc);
@@ -96,8 +97,18 @@
     return v;
 }
 
+static inline uint64_t get_4cc_trace(AVIOContext *bc, char *file,
+                                    char *func, int line)
+{
+    uint64_t v = get_fourcc(bc);
+
+    av_log(NULL, AV_LOG_DEBUG, "get_fourcc %5"PRId64" / %"PRIX64" in %s %s:%d\n",
+           v, v, file, func, line);
+    return v;
+}
 #define ffio_read_varlen(bc) get_v_trace(bc,  __FILE__, __PRETTY_FUNCTION__, __LINE__)
 #define get_s(bc)            get_s_trace(bc,  __FILE__, __PRETTY_FUNCTION__, __LINE__)
+#define get_fourcc(bc)       get_4cc_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__)
 #endif
 
 static int get_packetheader(NUTContext *nut, AVIOContext *bc,
@@ -129,7 +140,7 @@
         /* Note, this may fail if the stream is not seekable, but that should
          * not matter, as in this case we simply start where we currently are */
         avio_seek(bc, pos, SEEK_SET);
-    while (!bc->eof_reached) {
+    while (!url_feof(bc)) {
         state = (state << 8) | avio_r8(bc);
         if ((state >> 56) != 'N')
             continue;
@@ -290,7 +301,7 @@
             nut->frame_code[i].header_idx     = tmp_head_idx;
         }
     }
-    assert(nut->frame_code['N'].flags == FLAG_INVALID);
+    av_assert0(nut->frame_code['N'].flags == FLAG_INVALID);
 
     if (end > avio_tell(bc) + 4) {
         int rem = 1024;
@@ -310,7 +321,7 @@
             avio_read(bc, hdr, nut->header_len[i]);
             nut->header[i] = hdr;
         }
-        assert(nut->header_len[0] == 0);
+        av_assert0(nut->header_len[0] == 0);
     }
 
     if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {
@@ -501,6 +512,12 @@
                 set_disposition_bits(s, str_value, stream_id_plus1 - 1);
                 continue;
             }
+
+            if (stream_id_plus1 && !strcmp(name, "r_frame_rate")) {
+                sscanf(str_value, "%d/%d", &st->r_frame_rate.num, &st->r_frame_rate.den);
+                continue;
+            }
+
             if (metadata && av_strcasecmp(name, "Uses") &&
                 av_strcasecmp(name, "Depends") && av_strcasecmp(name, "Replaces"))
                 av_dict_set(metadata, name, str_value, 0);
@@ -518,7 +535,8 @@
 {
     AVFormatContext *s = nut->avf;
     AVIOContext *bc    = s->pb;
-    int64_t end, tmp;
+    int64_t end;
+    uint64_t tmp;
 
     nut->last_syncpoint_pos = avio_tell(bc) - 8;
 
@@ -538,13 +556,32 @@
         return -1;
     }
 
-    *ts = tmp / s->nb_streams *
-          av_q2d(nut->time_base[tmp % s->nb_streams]) * AV_TIME_BASE;
+    *ts = tmp / nut->time_base_count *
+          av_q2d(nut->time_base[tmp % nut->time_base_count]) * AV_TIME_BASE;
     ff_nut_add_sp(nut, nut->last_syncpoint_pos, *back_ptr, *ts);
 
     return 0;
 }
 
+//FIXME calculate exactly, this is just a good approximation.
+static int64_t find_duration(NUTContext *nut, int64_t filesize)
+{
+    AVFormatContext *s = nut->avf;
+    int64_t duration = 0;
+
+    int64_t pos = FFMAX(0, filesize - 2*nut->max_distance);
+    for(;;){
+        int64_t ts = nut_read_timestamp(s, -1, &pos, INT64_MAX);
+        if(ts < 0)
+            break;
+        duration = FFMAX(duration, ts);
+        pos++;
+    }
+    if(duration > 0)
+        s->duration_estimation_method = AVFMT_DURATION_FROM_PTS;
+    return duration;
+}
+
 static int find_and_decode_index(NUTContext *nut)
 {
     AVFormatContext *s = nut->avf;
@@ -556,10 +593,16 @@
     int8_t *has_keyframe;
     int ret = -1;
 
+    if(filesize <= 0)
+        return -1;
+
     avio_seek(bc, filesize - 12, SEEK_SET);
     avio_seek(bc, filesize - avio_rb64(bc), SEEK_SET);
     if (avio_rb64(bc) != INDEX_STARTCODE) {
         av_log(s, AV_LOG_ERROR, "no index at the end\n");
+
+        if(s->duration<=0)
+            s->duration = find_duration(nut, filesize);
         return -1;
     }
 
@@ -589,7 +632,7 @@
                 int flag = x & 1;
                 x >>= 1;
                 if (n + x >= syncpoint_count + 1) {
-                    av_log(s, AV_LOG_ERROR, "index overflow A\n");
+                    av_log(s, AV_LOG_ERROR, "index overflow A %d + %"PRIu64" >= %d\n", n, x, syncpoint_count + 1);
                     goto fail;
                 }
                 while (x--)
@@ -609,7 +652,7 @@
                 av_log(s, AV_LOG_ERROR, "keyframe before first syncpoint in index\n");
                 goto fail;
             }
-            assert(n <= syncpoint_count + 1);
+            av_assert0(n <= syncpoint_count + 1);
             for (; j < n && j < syncpoint_count; j++) {
                 if (has_keyframe[j]) {
                     uint64_t B, A = ffio_read_varlen(bc);
@@ -696,7 +739,7 @@
         find_and_decode_index(nut);
         avio_seek(bc, orig_pos, SEEK_SET);
     }
-    assert(nut->next_startcode == SYNCPOINT_STARTCODE);
+    av_assert0(nut->next_startcode == SYNCPOINT_STARTCODE);
 
     ff_metadata_conv_ctx(s, NULL, ff_nut_metadata_conv);
 
@@ -835,7 +878,7 @@
             pos -= 8;
         } else {
             frame_code = avio_r8(bc);
-            if (bc->eof_reached)
+            if (url_feof(bc))
                 return -1;
             if (frame_code == 'N') {
                 tmp = frame_code;
@@ -889,21 +932,18 @@
     do {
         pos = find_startcode(bc, SYNCPOINT_STARTCODE, pos) + 1;
         if (pos < 1) {
-            assert(nut->next_startcode == 0);
             av_log(s, AV_LOG_ERROR, "read_timestamp failed.\n");
             return AV_NOPTS_VALUE;
         }
     } while (decode_syncpoint(nut, &pts, &back_ptr) < 0);
     *pos_arg = pos - 1;
-    assert(nut->last_syncpoint_pos == *pos_arg);
+    av_assert0(nut->last_syncpoint_pos == *pos_arg);
 
     av_log(s, AV_LOG_DEBUG, "return %"PRId64" %"PRId64"\n", pts, back_ptr);
-    if (stream_index == -1)
-        return pts;
-    else if (stream_index == -2)
+    if (stream_index == -2)
         return back_ptr;
-
-    assert(0);
+    av_assert0(stream_index == -1);
+    return pts;
 }
 
 static int read_seek(AVFormatContext *s, int stream_index,
@@ -920,6 +960,8 @@
     if (st->index_entries) {
         int index = av_index_search_timestamp(st, pts, flags);
         if (index < 0)
+            index = av_index_search_timestamp(st, pts, flags ^ AVSEEK_FLAG_BACKWARD);
+        if (index < 0)
             return -1;
 
         pos2 = st->index_entries[index].pos;
@@ -952,7 +994,7 @@
         sp = av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp,
                           NULL);
 
-        assert(sp);
+        av_assert0(sp);
         pos2 = sp->back_ptr - 15;
     }
     av_log(NULL, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos2);
@@ -984,6 +1026,7 @@
 AVInputFormat ff_nut_demuxer = {
     .name           = "nut",
     .long_name      = NULL_IF_CONFIG_SMALL("NUT"),
+    .flags          = AVFMT_SEEK_TO_PTS,
     .priv_data_size = sizeof(NUTContext),
     .read_probe     = nut_probe,
     .read_header    = nut_read_header,
diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c
index 4b1e663..ccd6cb1 100644
--- a/libavformat/nutenc.c
+++ b/libavformat/nutenc.c
@@ -2,20 +2,20 @@
  * nut muxer
  * Copyright (c) 2004-2007 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -23,6 +23,7 @@
 #include "libavutil/mathematics.h"
 #include "libavutil/tree.h"
 #include "libavutil/dict.h"
+#include "libavutil/avassert.h"
 #include "libavcodec/mpegaudiodata.h"
 #include "nut.h"
 #include "internal.h"
@@ -155,6 +156,19 @@
         int is_audio= codec->codec_type == AVMEDIA_TYPE_AUDIO;
         int intra_only= /*codec->intra_only || */is_audio;
         int pred_count;
+        int frame_size = 0;
+
+        if (codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+            frame_size = av_get_audio_frame_duration(codec, 0);
+            if (codec->codec_id == AV_CODEC_ID_VORBIS && !frame_size)
+                frame_size = 64;
+        } else {
+            AVRational f = av_div_q(codec->time_base, *nut->stream[stream_id].time_base);
+            if(f.den == 1 && f.num>0)
+                frame_size = f.num;
+        }
+        if(!frame_size)
+            frame_size = 1;
 
         for(key_frame=0; key_frame<2; key_frame++){
             if(intra_only && keyframe_0_esc && key_frame==0)
@@ -173,6 +187,7 @@
         }
 
         key_frame= intra_only;
+#if 1
         if(is_audio){
             int frame_bytes= codec->frame_size*(int64_t)codec->bit_rate / (8*codec->sample_rate);
             int pts;
@@ -183,7 +198,7 @@
                     ft->stream_id= stream_id;
                     ft->size_mul=frame_bytes + 2;
                     ft->size_lsb=frame_bytes + pred;
-                    ft->pts_delta=pts;
+                    ft->pts_delta=pts * frame_size;
                     ft->header_idx= find_header_idx(s, codec, frame_bytes + pred, key_frame);
                     start2++;
                 }
@@ -193,9 +208,10 @@
             ft->flags= FLAG_KEY | FLAG_SIZE_MSB;
             ft->stream_id= stream_id;
             ft->size_mul=1;
-            ft->pts_delta=1;
+            ft->pts_delta=frame_size;
             start2++;
         }
+#endif
 
         if(codec->has_b_frames){
             pred_count=5;
@@ -218,6 +234,8 @@
             int start3= start2 + (end2-start2)*pred / pred_count;
             int end3  = start2 + (end2-start2)*(pred+1) / pred_count;
 
+            pred_table[pred] *= frame_size;
+
             for(index=start3; index<end3; index++){
                 FrameCode *ft= &nut->frame_code[index];
                 ft->flags= FLAG_KEY*key_frame;
@@ -459,6 +477,7 @@
 static int write_streaminfo(NUTContext *nut, AVIOContext *bc, int stream_id){
     AVFormatContext *s= nut->avf;
     AVStream* st = s->streams[stream_id];
+    AVDictionaryEntry *t = NULL;
     AVIOContext *dyn_bc;
     uint8_t *dyn_buf=NULL;
     int count=0, dyn_size, i;
@@ -466,10 +485,17 @@
     if(ret < 0)
         return ret;
 
+    while ((t = av_dict_get(st->metadata, "", t, AV_DICT_IGNORE_SUFFIX)))
+        count += add_info(dyn_bc, t->key, t->value);
     for (i=0; ff_nut_dispositions[i].flag; ++i) {
         if (st->disposition & ff_nut_dispositions[i].flag)
             count += add_info(dyn_bc, "Disposition", ff_nut_dispositions[i].str);
     }
+    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+        uint8_t buf[256];
+        snprintf(buf, sizeof(buf), "%d/%d", st->codec->time_base.den, st->codec->time_base.num);
+        count += add_info(dyn_bc, "r_frame_rate", buf);
+    }
     dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
 
     if (count) {
@@ -515,6 +541,51 @@
     return 0;
 }
 
+static int write_index(NUTContext *nut, AVIOContext *bc){
+    int i;
+    Syncpoint dummy= { .pos= 0 };
+    Syncpoint *next_node[2] = { NULL };
+    int64_t startpos = avio_tell(bc);
+    int64_t payload_size;
+
+    put_tt(nut, nut->max_pts_tb, bc, nut->max_pts);
+
+    ff_put_v(bc, nut->sp_count);
+
+    for(i=0; i<nut->sp_count; i++){
+        av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp, (void**)next_node);
+        ff_put_v(bc, (next_node[1]->pos >> 4) - (dummy.pos>>4));
+        dummy.pos = next_node[1]->pos;
+    }
+
+    for(i=0; i<nut->avf->nb_streams; i++){
+        StreamContext *nus= &nut->stream[i];
+        int64_t last_pts= -1;
+        int j, k;
+        for(j=0; j<nut->sp_count; j++){
+            int flag = (nus->keyframe_pts[j] != AV_NOPTS_VALUE) ^ (j+1 == nut->sp_count);
+            int n = 0;
+            for(; j<nut->sp_count && (nus->keyframe_pts[j] != AV_NOPTS_VALUE) == flag; j++)
+                n++;
+
+            ff_put_v(bc, 1 + 2*flag + 4*n);
+            for(k= j - n; k<=j && k<nut->sp_count; k++) {
+                if(nus->keyframe_pts[k] == AV_NOPTS_VALUE)
+                    continue;
+                av_assert0(nus->keyframe_pts[k] > last_pts);
+                ff_put_v(bc, nus->keyframe_pts[k] - last_pts);
+                last_pts = nus->keyframe_pts[k];
+            }
+        }
+    }
+
+    payload_size = avio_tell(bc) - startpos + 8 + 4;
+
+    avio_wb64(bc, 8 + payload_size + av_log2(payload_size) / 7 + 1 + 4*(payload_size > 4096));
+
+    return 0;
+}
+
 static int write_headers(AVFormatContext *avctx, AVIOContext *bc){
     NUTContext *nut = avctx->priv_data;
     AVIOContext *dyn_bc;
@@ -586,11 +657,10 @@
     nut->avf= s;
 
     nut->stream   = av_mallocz(sizeof(StreamContext)*s->nb_streams);
-    if (s->nb_chapters)
-        nut->chapter  = av_mallocz(sizeof(ChapterContext)*s->nb_chapters);
+    nut->chapter  = av_mallocz(sizeof(ChapterContext)*s->nb_chapters);
     nut->time_base= av_mallocz(sizeof(AVRational   )*(s->nb_streams +
                                                       s->nb_chapters));
-    if (!nut->stream || (s->nb_chapters && !nut->chapter) || !nut->time_base) {
+    if (!nut->stream || !nut->chapter || !nut->time_base) {
         av_freep(&nut->stream);
         av_freep(&nut->chapter);
         av_freep(&nut->time_base);
@@ -603,6 +673,12 @@
         AVRational time_base;
         ff_parse_specific_params(st->codec, &time_base.den, &ssize, &time_base.num);
 
+        if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->sample_rate) {
+            time_base = (AVRational){1, st->codec->sample_rate};
+        } else {
+            time_base = ff_choose_timebase(s, st, 48000);
+        }
+
         avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
 
         for(j=0; j<nut->time_base_count; j++){
@@ -639,7 +715,7 @@
     nut->max_distance = MAX_DISTANCE;
     build_elision_headers(s);
     build_frame_code(s);
-    assert(nut->frame_code['N'].flags == FLAG_INVALID);
+    av_assert0(nut->frame_code['N'].flags == FLAG_INVALID);
 
     avio_write(bc, ID_STRING, strlen(ID_STRING));
     avio_w8(bc, 0);
@@ -647,9 +723,10 @@
     if ((ret = write_headers(s, bc)) < 0)
         return ret;
 
-    avio_flush(bc);
+    if (s->avoid_negative_ts < 0)
+        s->avoid_negative_ts = 1;
 
-    //FIXME index
+    avio_flush(bc);
 
     return 0;
 }
@@ -702,8 +779,10 @@
     int store_sp=0;
     int ret;
 
-    if(pkt->pts < 0)
-        return -1;
+    if (pkt->pts < 0) {
+        av_log(s, AV_LOG_ERROR, "Invalid negative packet pts %"PRId64" in input\n", pkt->pts);
+        return AVERROR(EINVAL);
+    }
 
     if(1LL<<(20+3*nut->header_count) <= avio_tell(bc))
         write_headers(s, bc);
@@ -743,8 +822,19 @@
         put_packet(nut, bc, dyn_bc, 1, SYNCPOINT_STARTCODE);
 
         ff_nut_add_sp(nut, nut->last_syncpoint_pos, 0/*unused*/, pkt->dts);
+
+        if((1ll<<60) % nut->sp_count == 0)
+            for(i=0; i<s->nb_streams; i++){
+                int j;
+                StreamContext *nus = &nut->stream[i];
+                nus->keyframe_pts = av_realloc(nus->keyframe_pts, 2*nut->sp_count*sizeof(*nus->keyframe_pts));
+                if(!nus->keyframe_pts)
+                    return AVERROR(ENOMEM);
+                for(j=nut->sp_count == 1 ? 0 : nut->sp_count; j<2*nut->sp_count; j++)
+                    nus->keyframe_pts[j] = AV_NOPTS_VALUE;
+        }
     }
-    assert(nus->last_pts != AV_NOPTS_VALUE);
+    av_assert0(nus->last_pts != AV_NOPTS_VALUE);
 
     coded_pts = pkt->pts & ((1<<nus->msb_pts_shift)-1);
     if(ff_lsb2full(nus, coded_pts) != pkt->pts)
@@ -808,7 +898,7 @@
             frame_code=i;
         }
     }
-    assert(frame_code != -1);
+    av_assert0(frame_code != -1);
     fc= &nut->frame_code[frame_code];
     flags= fc->flags;
     needed_flags= get_needed_flags(nut, nus, fc, pkt);
@@ -833,7 +923,7 @@
     nus->last_pts= pkt->pts;
 
     //FIXME just store one per syncpoint
-    if(flags & FLAG_KEY)
+    if(flags & FLAG_KEY) {
         av_add_index_entry(
             s->streams[pkt->stream_index],
             nut->last_syncpoint_pos,
@@ -841,18 +931,36 @@
             0,
             0,
             AVINDEX_KEYFRAME);
+        if(nus->keyframe_pts && nus->keyframe_pts[nut->sp_count] == AV_NOPTS_VALUE)
+            nus->keyframe_pts[nut->sp_count] = pkt->pts;
+    }
+
+    if(!nut->max_pts_tb || av_compare_ts(nut->max_pts, *nut->max_pts_tb, pkt->pts, *nus->time_base) < 0) {
+        nut->max_pts = pkt->pts;
+        nut->max_pts_tb = nus->time_base;
+    }
 
     return 0;
 }
 
 static int nut_write_trailer(AVFormatContext *s){
     NUTContext *nut= s->priv_data;
-    AVIOContext *bc= s->pb;
+    AVIOContext *bc = s->pb, *dyn_bc;
+    int i, ret;
 
     while(nut->header_count<3)
         write_headers(s, bc);
 
+    ret = avio_open_dyn_buf(&dyn_bc);
+    if(ret >= 0) {
+        write_index(nut, dyn_bc);
+        put_packet(nut, bc, dyn_bc, 1, INDEX_STARTCODE);
+    }
+
     ff_nut_free_sp(nut);
+    for(i=0; i<s->nb_streams; i++)
+        av_freep(&nut->stream[i].keyframe_pts);
+
     av_freep(&nut->stream);
     av_freep(&nut->chapter);
     av_freep(&nut->time_base);
diff --git a/libavformat/nuv.c b/libavformat/nuv.c
index fce96b4..c192faa 100644
--- a/libavformat/nuv.c
+++ b/libavformat/nuv.c
@@ -2,20 +2,20 @@
  * NuppelVideo demuxer.
  * Copyright (c) 2006 Reimar Doeffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -62,7 +62,7 @@
     nuv_frametype frametype;
     if (!vst && !myth)
         return 1; // no codec data needed
-    while (!pb->eof_reached) {
+    while (!url_feof(pb)) {
         int size, subtype;
         frametype = avio_r8(pb);
         switch (frametype) {
@@ -200,7 +200,7 @@
     uint8_t hdr[HDRSIZE];
     nuv_frametype frametype;
     int ret, size;
-    while (!pb->eof_reached) {
+    while (!url_feof(pb)) {
         int copyhdrsize = ctx->rtjpg_video ? HDRSIZE : 0;
         uint64_t pos = avio_tell(pb);
         ret = avio_read(pb, hdr, HDRSIZE);
@@ -223,10 +223,9 @@
                 ret = av_new_packet(pkt, copyhdrsize + size);
                 if (ret < 0)
                     return ret;
-                // HACK: we have no idea if it is a keyframe,
-                // but if we mark none seeking will not work at all.
-                pkt->flags |= AV_PKT_FLAG_KEY;
+
                 pkt->pos = pos;
+                pkt->flags |= hdr[2] == 0 ? AV_PKT_FLAG_KEY : 0;
                 pkt->pts = AV_RL32(&hdr[4]);
                 pkt->stream_index = ctx->v_id;
                 memcpy(pkt->data, hdr, copyhdrsize);
@@ -262,6 +261,81 @@
     return AVERROR(EIO);
 }
 
+/**
+ * \brief looks for the string RTjjjjjjjjjj in the stream too resync reading
+ * \return 1 if the syncword is found 0 otherwise.
+ */
+static int nuv_resync(AVFormatContext *s, int64_t pos_limit) {
+    AVIOContext *pb = s->pb;
+    uint32_t tag = 0;
+    while(!url_feof(pb) && avio_tell(pb) < pos_limit) {
+        tag = (tag << 8) | avio_r8(pb);
+        if (tag                  == MKBETAG('R','T','j','j') &&
+           (tag = avio_rb32(pb)) == MKBETAG('j','j','j','j') &&
+           (tag = avio_rb32(pb)) == MKBETAG('j','j','j','j'))
+            return 1;
+    }
+    return 0;
+}
+
+/**
+ * \brief attempts to read a timestamp from stream at the given stream position
+ * \return timestamp if successful and AV_NOPTS_VALUE if failure
+ */
+static int64_t nuv_read_dts(AVFormatContext *s, int stream_index,
+                            int64_t *ppos, int64_t pos_limit)
+{
+    NUVContext *ctx = s->priv_data;
+    AVIOContext *pb = s->pb;
+    uint8_t hdr[HDRSIZE];
+    nuv_frametype frametype;
+    int size, key, idx;
+    int64_t pos, dts;
+
+    if (avio_seek(pb, *ppos, SEEK_SET) < 0)
+        return AV_NOPTS_VALUE;
+
+    if (!nuv_resync(s, pos_limit))
+        return AV_NOPTS_VALUE;
+
+    while (!url_feof(pb) && avio_tell(pb) < pos_limit) {
+        if (avio_read(pb, hdr, HDRSIZE) < HDRSIZE)
+            return AV_NOPTS_VALUE;
+        frametype = hdr[0];
+        size = PKTSIZE(AV_RL32(&hdr[8]));
+        switch (frametype) {
+            case NUV_SEEKP:
+                break;
+            case NUV_AUDIO:
+            case NUV_VIDEO:
+                if (frametype == NUV_VIDEO) {
+                    idx = ctx->v_id;
+                    key = hdr[2] == 0;
+                } else {
+                    idx = ctx->a_id;
+                    key = 1;
+                }
+                if (stream_index == idx) {
+
+                    pos = avio_tell(s->pb) - HDRSIZE;
+                    dts = AV_RL32(&hdr[4]);
+
+                    // TODO - add general support in av_gen_search, so it adds positions after reading timestamps
+                    av_add_index_entry(s->streams[stream_index], pos, dts, size + HDRSIZE, 0,
+                            key ? AVINDEX_KEYFRAME : 0);
+
+                    *ppos = pos;
+                    return dts;
+                }
+            default:
+                avio_skip(pb, size);
+                break;
+        }
+    }
+    return AV_NOPTS_VALUE;
+}
+
+
 AVInputFormat ff_nuv_demuxer = {
     .name           = "nuv",
     .long_name      = NULL_IF_CONFIG_SMALL("NuppelVideo"),
@@ -269,5 +343,6 @@
     .read_probe     = nuv_probe,
     .read_header    = nuv_header,
     .read_packet    = nuv_packet,
+    .read_timestamp = nuv_read_dts,
     .flags          = AVFMT_GENERIC_INDEX,
 };
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 175feb7..a36dfae 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -28,8 +28,8 @@
     DEALINGS IN THE SOFTWARE.
  */
 
-
 #include <stdio.h>
+#include "libavutil/avassert.h"
 #include "oggdec.h"
 #include "avformat.h"
 #include "internal.h"
@@ -46,6 +46,7 @@
     &ff_theora_codec,
     &ff_flac_codec,
     &ff_celt_codec,
+    &ff_opus_codec,
     &ff_old_dirac_codec,
     &ff_old_flac_codec,
     &ff_ogm_video_codec,
@@ -55,6 +56,8 @@
     NULL
 };
 
+static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts);
+
 //FIXME We could avoid some structure duplication
 static int ogg_save(AVFormatContext *s)
 {
@@ -117,9 +120,11 @@
     return 0;
 }
 
-static int ogg_reset(struct ogg *ogg)
+static int ogg_reset(AVFormatContext *s)
 {
+    struct ogg *ogg = s->priv_data;
     int i;
+    int64_t start_pos = avio_tell(s->pb);
 
     for (i = 0; i < ogg->nstreams; i++){
         struct ogg_stream *os = ogg->streams + i;
@@ -134,6 +139,10 @@
         os->nsegs = 0;
         os->segp = 0;
         os->incomplete = 0;
+        os->got_data = 0;
+        if (start_pos <= s->data_offset) {
+            os->lastpts = 0;
+        }
     }
 
     ogg->curidx = -1;
@@ -153,33 +162,81 @@
     return NULL;
 }
 
-static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
+/**
+ * Replace the current stream with a new one. This is a typical webradio
+ * 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)
 {
-
     struct ogg *ogg = s->priv_data;
-    int idx = ogg->nstreams++;
+    struct ogg_stream *os;
+    unsigned bufsize;
+    uint8_t *buf;
+
+    if (ogg->nstreams != 1) {
+        av_log_missing_feature(s, "Changing stream parameters in multistream ogg is", 0);
+        return AVERROR_PATCHWELCOME;
+    }
+
+    os = &ogg->streams[0];
+
+    buf = os->buf;
+    bufsize = os->bufsize;
+
+    if (!ogg->state || ogg->state->streams[0].private != os->private)
+        av_freep(&ogg->streams[0].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->bufsize = bufsize;
+    os->buf = buf;
+    os->header = -1;
+
+    return 0;
+}
+
+static int ogg_new_stream(AVFormatContext *s, uint32_t serial)
+{
+    struct ogg *ogg = s->priv_data;
+    int idx = ogg->nstreams;
     AVStream *st;
     struct ogg_stream *os;
+    size_t size;
 
-    ogg->streams = av_realloc (ogg->streams,
-                               ogg->nstreams * sizeof (*ogg->streams));
-    memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
+    if (ogg->state) {
+        av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added "
+               "in between Ogg context save/restore operations.\n");
+        return AVERROR_BUG;
+    }
+
+    /* Allocate and init a new Ogg Stream */
+    if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 ||
+        !(os = av_realloc(ogg->streams, size)))
+        return AVERROR(ENOMEM);
+    ogg->streams = os;
     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->start_granule = OGG_NOGRANULE_VALUE;
+    if (!os->buf)
+        return AVERROR(ENOMEM);
 
-    if (new_avstream) {
-        st = avformat_new_stream(s, NULL);
-        if (!st)
-            return AVERROR(ENOMEM);
-
-        st->id = idx;
-        avpriv_set_pts_info(st, 64, 1, 1000000);
+    /* Create the associated AVStream */
+    st = avformat_new_stream(s, NULL);
+    if (!st) {
+        av_freep(&os->buf);
+        return AVERROR(ENOMEM);
     }
+    st->id = idx;
+    avpriv_set_pts_info(st, 64, 1, 1000000);
 
+    ogg->nstreams++;
     return idx;
 }
 
@@ -199,7 +256,17 @@
     return 0;
 }
 
-static int ogg_read_page(AVFormatContext *s, int *str)
+static int data_packets_seen(const struct ogg *ogg)
+{
+    int i;
+
+    for (i = 0; i < ogg->nstreams; i++)
+        if (ogg->streams[i].got_data)
+            return 1;
+    return 0;
+}
+
+static int ogg_read_page(AVFormatContext *s, int *sid)
 {
     AVIOContext *bc = s->pb;
     struct ogg *ogg = s->priv_data;
@@ -225,7 +292,7 @@
             break;
 
         c = avio_r8(bc);
-        if (bc->eof_reached)
+        if (url_feof(bc))
             return AVERROR_EOF;
         sync[sp++ & 3] = c;
     }while (i++ < MAX_PAGE_SIZE);
@@ -235,8 +302,10 @@
         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);
@@ -246,22 +315,15 @@
 
     idx = ogg_find_stream (ogg, serial);
     if (idx < 0){
-        if (ogg->headers) {
-            int n;
+        if (data_packets_seen(ogg))
+            idx = ogg_replace_stream(s, serial);
+        else
+            idx = ogg_new_stream(s, serial);
 
-            for (n = 0; n < ogg->nstreams; n++) {
-                av_freep(&ogg->streams[n].buf);
-                if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private)
-                    av_freep(&ogg->streams[n].private);
-            }
-            ogg->curidx   = -1;
-            ogg->nstreams = 0;
-            idx = ogg_new_stream(s, serial, 0);
-        } else {
-            idx = ogg_new_stream(s, serial, 1);
-        }
-        if (idx < 0)
+        if (idx < 0) {
+            av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n");
             return idx;
+        }
     }
 
     os = ogg->streams + idx;
@@ -281,8 +343,14 @@
     for (i = 0; i < nsegs; i++)
         size += os->segments[i];
 
+    if (!(flags & OGG_FLAG_BOS))
+        os->got_data = 1;
+
     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){
                 int seg = os->segments[os->segp++];
                 os->pstart += seg;
@@ -312,13 +380,20 @@
     os->flags = flags;
 
     memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-    if (str)
-        *str = idx;
+    if (sid)
+        *sid = idx;
 
     return 0;
 }
 
-static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
+/**
+ * @brief find the next Ogg packet
+ * @param *sid is set to the stream for the packet or -1 if there is
+ *             no matching stream, in that case assume all other return
+ *             values to be uninitialized.
+ * @return negative value on error or EOF.
+ */
+static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
                       int64_t *fpos)
 {
     struct ogg *ogg = s->priv_data;
@@ -328,6 +403,8 @@
     int segp = 0, psize = 0;
 
     av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
+    if (sid)
+        *sid = -1;
 
     do{
         idx = ogg->curidx;
@@ -370,12 +447,14 @@
 
         if (!complete && os->segp == os->nsegs){
             ogg->curidx = -1;
-            os->incomplete = 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);
 
-    av_dlog(s, "ogg_packet: idx %i, frame size %i, start %i\n",
-            idx, os->psize, os->pstart);
 
     if (os->granule == -1)
         av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
@@ -416,8 +495,8 @@
         os->pduration = 0;
         if (os->codec && os->codec->packet)
             os->codec->packet (s, idx);
-        if (str)
-            *str = idx;
+        if (sid)
+            *sid = idx;
         if (dstart)
             *dstart = os->pstart;
         if (dsize)
@@ -426,6 +505,8 @@
             *fpos = os->sync_pos;
         os->pstart += os->psize;
         os->psize = 0;
+        if(os->pstart == os->bufpos)
+            os->bufpos = os->pstart = 0;
         os->sync_pos = os->page_pos;
     }
 
@@ -444,40 +525,12 @@
     return 0;
 }
 
-static int ogg_get_headers(AVFormatContext *s)
-{
-    struct ogg *ogg = s->priv_data;
-    int ret, i;
-
-    do{
-        ret = ogg_packet(s, NULL, NULL, NULL, NULL);
-        if (ret < 0)
-            return ret;
-    }while (!ogg->headers);
-
-    for (i = 0; i < ogg->nstreams; i++) {
-        struct ogg_stream *os = ogg->streams + i;
-
-        if (os->codec && os->codec->nb_header &&
-            os->nb_header < os->codec->nb_header) {
-            av_log(s, AV_LOG_ERROR,
-                   "Headers mismatch for stream %d\n", i);
-            return AVERROR_INVALIDDATA;
-        }
-        if (os->start_granule != OGG_NOGRANULE_VALUE)
-            os->lastpts = s->streams[i]->start_time =
-                ogg_gptopts(s, i, os->start_granule, NULL);
-    }
-    av_dlog(s, "found headers\n");
-
-    return 0;
-}
-
 static int ogg_get_length(AVFormatContext *s)
 {
     struct ogg *ogg = s->priv_data;
     int i;
     int64_t size, end;
+    int streams_left=0;
 
     if(!s->pb->seekable)
         return 0;
@@ -499,13 +552,37 @@
             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)
+            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){
+                ogg->streams[i].got_start= -1;
+                streams_left++;
+            }
         }
     }
 
     ogg_restore (s, 0);
 
+    ogg_save (s);
+    avio_seek (s->pb, s->data_offset, SEEK_SET);
+    ogg_reset(s);
+    while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) {
+        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){
+            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){
+            ogg->streams[i].got_start= 1;
+            streams_left--;
+        }
+    }
+    ogg_restore (s, 0);
+
     return 0;
 }
 
@@ -513,20 +590,34 @@
 {
     struct ogg *ogg = s->priv_data;
     int ret, i;
-    ogg->curidx = -1;
-    //linear headers seek from start
-    ret = ogg_get_headers(s);
-    if (ret < 0)
-        return ret;
 
-    for (i = 0; i < ogg->nstreams; i++)
-        if (ogg->streams[i].header < 0)
+    ogg->curidx = -1;
+
+    //linear headers seek from start
+    do {
+        ret = ogg_packet(s, NULL, NULL, NULL, NULL);
+        if (ret < 0)
+            return ret;
+    } while (!ogg->headers);
+    av_dlog(s, "found headers\n");
+
+    for (i = 0; i < ogg->nstreams; i++) {
+        struct ogg_stream *os = ogg->streams + i;
+
+        if (ogg->streams[i].header < 0) {
+            av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i);
             ogg->streams[i].codec = NULL;
+        } else if (os->codec && os->nb_header < os->codec->nb_header) {
+            av_log(s, AV_LOG_WARNING, "Number of headers (%d) mismatch for stream %d\n", os->nb_header, i);
+        }
+        if (os->start_granule != OGG_NOGRANULE_VALUE)
+            os->lastpts = s->streams[i]->start_time =
+                ogg_gptopts(s, i, os->start_granule, NULL);
+    }
 
     //linear granulepos seek from end
     ogg_get_length (s);
 
-    //fill the extradata in the per codec callbacks
     return 0;
 }
 
@@ -560,11 +651,24 @@
     return pts;
 }
 
+static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
+{
+    struct ogg *ogg = s->priv_data;
+    struct ogg_stream *os = ogg->streams + idx;
+    if (psize && s->streams[idx]->codec->codec_id == AV_CODEC_ID_THEORA) {
+        if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
+            os->pflags ^= AV_PKT_FLAG_KEY;
+            av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
+                   (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
+        }
+    }
+}
+
 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     struct ogg *ogg;
     struct ogg_stream *os;
-    int idx = -1, ret;
+    int idx, ret;
     int pstart, psize;
     int64_t fpos, pts, dts;
 
@@ -581,6 +685,7 @@
 
     // pflags might not be set until after this
     pts = ogg_calc_pts(s, idx, &dts);
+    ogg_validate_keyframe(s, idx, pstart, psize);
 
     if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
         goto retry;
@@ -621,21 +726,32 @@
     struct ogg *ogg = s->priv_data;
     AVIOContext *bc = s->pb;
     int64_t pts = AV_NOPTS_VALUE;
-    int i = -1;
+    int64_t keypos = -1;
+    int i;
+    int pstart, psize;
     avio_seek(bc, *pos_arg, SEEK_SET);
-    ogg_reset(ogg);
+    ogg_reset(s);
 
-    while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, 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);
-            if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
-                pts = AV_NOPTS_VALUE;
+            ogg_validate_keyframe(s, i, pstart, psize);
+            if (os->pflags & AV_PKT_FLAG_KEY) {
+                keypos = *pos_arg;
+            } else if (os->keyframe_seek) {
+                // if we had a previous keyframe but no pts for it,
+                // return that keyframe with this pts value.
+                if (keypos >= 0)
+                    *pos_arg = keypos;
+                else
+                    pts = AV_NOPTS_VALUE;
+            }
         }
         if (pts != AV_NOPTS_VALUE)
             break;
     }
-    ogg_reset(ogg);
+    ogg_reset(s);
     return pts;
 }
 
@@ -646,6 +762,11 @@
     struct ogg_stream *os = ogg->streams + stream_index;
     int ret;
 
+    av_assert0(stream_index < ogg->nstreams);
+    // Ensure everything is reset even when seeking via
+    // the generated index.
+    ogg_reset(s);
+
     // Try seeking to a keyframe first. If this fails (very possible),
     // av_seek_frame will fall back to ignoring keyframes
     if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h
index bb7b345..febf8cb 100644
--- a/libavformat/oggdec.h
+++ b/libavformat/oggdec.h
@@ -80,6 +80,8 @@
     int incomplete; ///< whether we're expecting a continuation in the next page
     int page_end;   ///< current packet is the last one completed in the page
     int keyframe_seek;
+    int got_start;
+    int got_data;   ///< 1 if the stream got some data (non-initial packets), 0 otherwise
     int nb_header; ///< set to the number of parsed headers
     void *private;
 };
@@ -104,7 +106,7 @@
 #define OGG_FLAG_BOS  2
 #define OGG_FLAG_EOS  4
 
-#define OGG_NOGRANULE_VALUE -1ull
+#define OGG_NOGRANULE_VALUE (-1ull)
 
 extern const struct ogg_codec ff_celt_codec;
 extern const struct ogg_codec ff_dirac_codec;
@@ -115,6 +117,7 @@
 extern const struct ogg_codec ff_ogm_video_codec;
 extern const struct ogg_codec ff_old_dirac_codec;
 extern const struct ogg_codec ff_old_flac_codec;
+extern const struct ogg_codec ff_opus_codec;
 extern const struct ogg_codec ff_skeleton_codec;
 extern const struct ogg_codec ff_speex_codec;
 extern const struct ogg_codec ff_theora_codec;
diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c
index c1f22d1..4871a0e 100644
--- a/libavformat/oggenc.c
+++ b/libavformat/oggenc.c
@@ -2,24 +2,25 @@
  * Ogg muxer
  * Copyright (c) 2007 Baptiste Coudurier <baptiste dot coudurier at free dot fr>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/crc.h"
+#include "libavutil/opt.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 #include "libavutil/random_seed.h"
@@ -73,6 +74,8 @@
 #define PARAM AV_OPT_FLAG_ENCODING_PARAM
 
 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",
         OFFSET(pref_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MAX_PAGE_SIZE, PARAM },
     { NULL },
@@ -133,6 +136,11 @@
     return 0;
 }
 
+static int ogg_key_granule(OGGStreamContext *oggstream, int64_t granule)
+{
+    return oggstream->kfgshift && !(granule & ((1<<oggstream->kfgshift)-1));
+}
+
 static int64_t ogg_granule_to_timestamp(OGGStreamContext *oggstream, int64_t granule)
 {
     if (oggstream->kfgshift)
@@ -202,9 +210,14 @@
     int i, segments, len, flush = 0;
 
     // Handles VFR by flushing page because this frame needs to have a timestamp
+    // For theora, keyframes also need to have a timestamp to correctly mark
+    // them as such, otherwise seeking will not work correctly at the very
+    // least with old libogg versions.
+    // Do not try to flush header packets though, that will create broken files.
     if (st->codec->codec_id == AV_CODEC_ID_THEORA && !header &&
-        ogg_granule_to_timestamp(oggstream, granule) >
-        ogg_granule_to_timestamp(oggstream, oggstream->last_granule) + 1) {
+        (ogg_granule_to_timestamp(oggstream, granule) >
+         ogg_granule_to_timestamp(oggstream, oggstream->last_granule) + 1 ||
+         ogg_key_granule(oggstream, granule))) {
         if (oggstream->page.granule != -1)
             ogg_buffer_page(s, oggstream);
         flush = 1;
@@ -247,7 +260,7 @@
 static uint8_t *ogg_write_vorbiscomment(int offset, int bitexact,
                                         int *header_len, AVDictionary **m, int framing_bit)
 {
-    const char *vendor = bitexact ? "Libav" : LIBAVFORMAT_IDENT;
+    const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
     int size;
     uint8_t *p, *p0;
     unsigned int count;
@@ -565,7 +578,7 @@
         if (st->codec->codec_id == AV_CODEC_ID_FLAC ||
             st->codec->codec_id == AV_CODEC_ID_SPEEX ||
             st->codec->codec_id == AV_CODEC_ID_OPUS) {
-            av_free(oggstream->header[0]);
+            av_freep(&oggstream->header[0]);
         }
         av_freep(&oggstream->header[1]);
         av_freep(&st->priv_data);
diff --git a/libavformat/oggparsecelt.c b/libavformat/oggparsecelt.c
index 0deccc2..afc4392 100644
--- a/libavformat/oggparsecelt.c
+++ b/libavformat/oggparsecelt.c
@@ -1,21 +1,21 @@
 /*
- * Xiph CELT / Opus parser for Ogg
+ * Xiph CELT parser for Ogg
  * Copyright (c) 2011 Nicolas George
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -62,18 +62,18 @@
         overlap          = AV_RL32(p + 48);
         /* unused bytes per packet field skipped */
         extra_headers    = AV_RL32(p + 56);
-        av_free(os->private);
-        av_free(st->codec->extradata);
         st->codec->codec_type     = AVMEDIA_TYPE_AUDIO;
         st->codec->codec_id       = AV_CODEC_ID_CELT;
         st->codec->sample_rate    = sample_rate;
         st->codec->channels       = nb_channels;
         st->codec->frame_size     = frame_size;
+        av_free(st->codec->extradata);
         st->codec->extradata      = extradata;
         st->codec->extradata_size = 2 * sizeof(uint32_t);
         if (sample_rate)
             avpriv_set_pts_info(st, 64, 1, sample_rate);
         priv->extra_headers_left  = 1 + extra_headers;
+        av_free(os->private);
         os->private = priv;
         AV_WL32(extradata + 0, overlap);
         AV_WL32(extradata + 4, version);
diff --git a/libavformat/oggparsedirac.c b/libavformat/oggparsedirac.c
index 55a0b59..73bc495 100644
--- a/libavformat/oggparsedirac.c
+++ b/libavformat/oggparsedirac.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2008  David Conrad
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/oggparseflac.c b/libavformat/oggparseflac.c
index f59b400..3ff594e 100644
--- a/libavformat/oggparseflac.c
+++ b/libavformat/oggparseflac.c
@@ -1,20 +1,20 @@
 /*
  *    Copyright (C) 2005  Matthieu CASTET
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/oggparseogm.c b/libavformat/oggparseogm.c
index 7b3cda2..a3caac0 100644
--- a/libavformat/oggparseogm.c
+++ b/libavformat/oggparseogm.c
@@ -23,6 +23,7 @@
 **/
 
 #include <stdlib.h>
+#include "libavutil/avassert.h"
 #include "libavutil/intreadwrite.h"
 #include "libavcodec/get_bits.h"
 #include "libavcodec/bytestream.h"
@@ -40,6 +41,7 @@
     const uint8_t *p = os->buf + os->pstart;
     uint64_t time_unit;
     uint64_t spu;
+    uint32_t size;
 
     if(!(*p & 1))
         return 0;
@@ -67,11 +69,13 @@
             acid[4] = 0;
             cid = strtol(acid, NULL, 16);
             st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, cid);
-            st->need_parsing = AVSTREAM_PARSE_FULL;
+            // our parser completely breaks AAC in Ogg
+            if (st->codec->codec_id != AV_CODEC_ID_AAC)
+                st->need_parsing = AVSTREAM_PARSE_FULL;
         }
 
-        p += 4;                     /* useless size field */
-
+        size        = bytestream_get_le32(&p);
+        size        = FFMIN(size, os->psize);
         time_unit   = bytestream_get_le64(&p);
         spu         = bytestream_get_le64(&p);
         p += 4;                     /* default_len */
@@ -85,8 +89,19 @@
             st->codec->channels = bytestream_get_le16(&p);
             p += 2;                 /* block_align */
             st->codec->bit_rate = bytestream_get_le32(&p) * 8;
-            st->codec->sample_rate = spu * 10000000 / time_unit;
+            st->codec->sample_rate = time_unit ? spu * 10000000 / time_unit : 0;
             avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+            if (size >= 56 && st->codec->codec_id == AV_CODEC_ID_AAC) {
+                p += 4;
+                size -= 4;
+            }
+            if (size > 52) {
+                av_assert0(FF_INPUT_BUFFER_PADDING_SIZE <= 52);
+                size -= 52;
+                st->codec->extradata_size = size;
+                st->codec->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
+                bytestream_get_buffer(&p, st->codec->extradata, size);
+            }
         }
     } else if (*p == 3) {
         if (os->psize > 8)
diff --git a/libavformat/oggparseopus.c b/libavformat/oggparseopus.c
new file mode 100644
index 0000000..0e8f1ca
--- /dev/null
+++ b/libavformat/oggparseopus.c
@@ -0,0 +1,135 @@
+/*
+ * Opus parser for Ogg
+ * 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/intreadwrite.h"
+#include "avformat.h"
+#include "internal.h"
+#include "oggdec.h"
+
+struct oggopus_private {
+    int need_comments;
+    unsigned pre_skip;
+    int64_t cur_dts;
+};
+
+#define OPUS_HEAD_SIZE 19
+
+static int opus_header(AVFormatContext *avf, int idx)
+{
+    struct ogg *ogg = avf->priv_data;
+    struct ogg_stream *os = &ogg->streams[idx];
+    AVStream *st = avf->streams[idx];
+    struct oggopus_private *priv = os->private;
+    uint8_t *packet = os->buf + os->pstart;
+    uint8_t *extradata;
+
+    if (!priv) {
+        priv = os->private = av_mallocz(sizeof(*priv));
+        if (!priv)
+            return AVERROR(ENOMEM);
+    }
+    if (os->flags & OGG_FLAG_BOS) {
+        if (os->psize < OPUS_HEAD_SIZE || (AV_RL8(packet + 8) & 0xF0) != 0)
+            return AVERROR_INVALIDDATA;
+        st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
+        st->codec->codec_id    = AV_CODEC_ID_OPUS;
+        st->codec->channels    = AV_RL8 (packet + 9);
+        priv->pre_skip         = AV_RL16(packet + 10);
+        /*orig_sample_rate     = AV_RL32(packet + 12);*/
+        /*gain                 = AV_RL16(packet + 16);*/
+        /*channel_map          = AV_RL8 (packet + 18);*/
+
+        extradata = av_malloc(os->psize + FF_INPUT_BUFFER_PADDING_SIZE);
+        if (!extradata)
+            return AVERROR(ENOMEM);
+        memcpy(extradata, packet, os->psize);
+        st->codec->extradata = extradata;
+        st->codec->extradata_size = os->psize;
+
+        st->codec->sample_rate = 48000;
+        avpriv_set_pts_info(st, 64, 1, 48000);
+        priv->need_comments = 1;
+        return 1;
+    }
+
+    if (priv->need_comments) {
+        if (os->psize < 8 || memcmp(packet, "OpusTags", 8))
+            return AVERROR_INVALIDDATA;
+        ff_vorbis_comment(avf, &st->metadata, packet + 8, os->psize - 8);
+        priv->need_comments--;
+        return 1;
+    }
+    return 0;
+}
+
+static int opus_packet(AVFormatContext *avf, int idx)
+{
+    struct ogg *ogg = avf->priv_data;
+    struct ogg_stream *os = &ogg->streams[idx];
+    AVStream *st = avf->streams[idx];
+    struct oggopus_private *priv = os->private;
+    uint8_t *packet = os->buf + os->pstart;
+    unsigned toc, toc_config, toc_count, frame_size, nb_frames = 1;
+
+    if (!os->psize)
+        return AVERROR_INVALIDDATA;
+    toc = *packet;
+    toc_config = toc >> 3;
+    toc_count  = toc & 3;
+    frame_size = toc_config < 12 ? FFMAX(480, 960 * (toc_config & 3)) :
+                 toc_config < 16 ? 480 << (toc_config & 1) :
+                                   120 << (toc_config & 3);
+    if (toc_count == 3) {
+        if (os->psize < 2)
+            return AVERROR_INVALIDDATA;
+        nb_frames = packet[1] & 0x3F;
+    } else if (toc_count) {
+        nb_frames = 2;
+    }
+    os->pduration = frame_size * nb_frames;
+    if (os->lastpts != AV_NOPTS_VALUE) {
+        if (st->start_time == AV_NOPTS_VALUE)
+            st->start_time = os->lastpts;
+        priv->cur_dts = os->lastdts = os->lastpts -= priv->pre_skip;
+    }
+    priv->cur_dts += os->pduration;
+    if ((os->flags & OGG_FLAG_EOS)) {
+        int64_t skip = priv->cur_dts - os->granule + priv->pre_skip;
+        skip = FFMIN(skip, os->pduration);
+        if (skip > 0) {
+            os->pduration = skip < os->pduration ? os->pduration - skip : 1;
+            av_log(avf, AV_LOG_WARNING,
+                   "Last packet must be truncated to %d (unimplemented).\n",
+                   os->pduration);
+        }
+    }
+    return 0;
+}
+
+const struct ogg_codec ff_opus_codec = {
+    .name      = "Opus",
+    .magic     = "OpusHead",
+    .magicsize = 8,
+    .header    = opus_header,
+    .packet    = opus_packet,
+};
diff --git a/libavformat/oggparseskeleton.c b/libavformat/oggparseskeleton.c
index 2cc63d4..d819e0e 100644
--- a/libavformat/oggparseskeleton.c
+++ b/libavformat/oggparseskeleton.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2010 David Conrad
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -47,7 +47,7 @@
         version_major = AV_RL16(buf+8);
         version_minor = AV_RL16(buf+10);
 
-        if (version_major != 3) {
+        if (version_major != 3 && version_major != 4) {
             av_log(s, AV_LOG_WARNING, "Unknown skeleton version %d.%d\n",
                    version_major, version_minor);
             return -1;
diff --git a/libavformat/oggparsetheora.c b/libavformat/oggparsetheora.c
index dfb73c9..6877d1e 100644
--- a/libavformat/oggparsetheora.c
+++ b/libavformat/oggparsetheora.c
@@ -110,16 +110,16 @@
         st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
         st->codec->codec_id = AV_CODEC_ID_THEORA;
         st->need_parsing = AVSTREAM_PARSE_HEADERS;
-
     }
     break;
     case 0x81:
-        ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, os->psize - 8);
+        ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, os->psize - 7);
     case 0x82:
         if (!thp->version)
             return -1;
         break;
     default:
+        av_log(s, AV_LOG_ERROR, "Unknown header type %X\n", os->buf[os->pstart]);
         return -1;
     }
 
@@ -160,10 +160,47 @@
     return iframe + pframe;
 }
 
+static int theora_packet(AVFormatContext *s, int idx)
+{
+    struct ogg *ogg = s->priv_data;
+    struct ogg_stream *os = ogg->streams + idx;
+    int duration;
+
+    /* first packet handling
+       here we parse the duration of each packet in the first page and compare
+       the total duration to the page granule to find the encoder delay and
+       set the first timestamp */
+
+    if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {
+        int seg;
+
+        duration = 1;
+        for (seg = os->segp; seg < os->nsegs; seg++) {
+            if (os->segments[seg] < 255)
+                duration ++;
+        }
+
+        os->lastpts = os->lastdts   = theora_gptopts(s, idx, os->granule, NULL) - duration;
+        if(s->streams[idx]->start_time == AV_NOPTS_VALUE) {
+            s->streams[idx]->start_time = os->lastpts;
+            if (s->streams[idx]->duration)
+                s->streams[idx]->duration -= s->streams[idx]->start_time;
+        }
+    }
+
+    /* parse packet duration */
+    if (os->psize > 0) {
+        os->pduration = 1;
+    }
+
+    return 0;
+}
+
 const struct ogg_codec ff_theora_codec = {
     .magic = "\200theora",
     .magicsize = 7,
     .header = theora_header,
+    .packet = theora_packet,
     .gptopts = theora_gptopts,
     .nb_header = 3,
 };
diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
index 396a3e3..09f5205 100644
--- a/libavformat/oggparsevorbis.c
+++ b/libavformat/oggparsevorbis.c
@@ -203,12 +203,12 @@
     int pkt_type = os->buf[os->pstart];
 
     if (!(pkt_type & 1))
-        return 0;
+        return os->private ? 0 : -1;
 
     if (!os->private) {
         os->private = av_mallocz(sizeof(struct oggvorbis_private));
         if (!os->private)
-            return 0;
+            return -1;
     }
 
     if (os->psize < 1 || pkt_type > 5)
@@ -223,6 +223,8 @@
 
     priv->len[pkt_type >> 1] = os->psize;
     priv->packet[pkt_type >> 1] = av_mallocz(os->psize);
+    if (!priv->packet[pkt_type >> 1])
+        return AVERROR(ENOMEM);
     memcpy(priv->packet[pkt_type >> 1], os->buf + os->pstart, os->psize);
     if (os->buf[os->pstart] == 1) {
         const uint8_t *p = os->buf + os->pstart + 7; /* skip "\001vorbis" tag */
@@ -296,33 +298,39 @@
        here we parse the duration of each packet in the first page and compare
        the total duration to the page granule to find the encoder delay and
        set the first timestamp */
-    if (!os->lastpts) {
-        int seg;
+    if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {
+        int seg, d;
         uint8_t *last_pkt = os->buf + os->pstart;
         uint8_t *next_pkt = last_pkt;
-        int first_duration = 0;
 
         avpriv_vorbis_parse_reset(&priv->vp);
         duration = 0;
-        for (seg = 0; seg < os->nsegs; seg++) {
+        seg = os->segp;
+        d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1);
+        if (d < 0) {
+            os->pflags |= AV_PKT_FLAG_CORRUPT;
+            return 0;
+        }
+        duration += d;
+        last_pkt = next_pkt =  next_pkt + os->psize;
+        for (; seg < os->nsegs; seg++) {
             if (os->segments[seg] < 255) {
                 int d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1);
                 if (d < 0) {
                     duration = os->granule;
                     break;
                 }
-                if (!duration)
-                    first_duration = d;
                 duration += d;
                 last_pkt = next_pkt + os->segments[seg];
             }
             next_pkt += os->segments[seg];
         }
         os->lastpts = os->lastdts   = os->granule - duration;
-        s->streams[idx]->start_time = os->lastpts + first_duration;
-        if (s->streams[idx]->duration)
-            s->streams[idx]->duration -= s->streams[idx]->start_time;
-        s->streams[idx]->cur_dts    = AV_NOPTS_VALUE;
+        if(s->streams[idx]->start_time == AV_NOPTS_VALUE) {
+            s->streams[idx]->start_time = FFMAX(os->lastpts, 0);
+            if (s->streams[idx]->duration)
+                s->streams[idx]->duration -= s->streams[idx]->start_time;
+        }
         priv->final_pts             = AV_NOPTS_VALUE;
         avpriv_vorbis_parse_reset(&priv->vp);
     }
@@ -330,7 +338,7 @@
     /* parse packet duration */
     if (os->psize > 0) {
         duration = avpriv_vorbis_parse_frame(&priv->vp, os->buf + os->pstart, 1);
-        if (duration <= 0) {
+        if (duration < 0) {
             os->pflags |= AV_PKT_FLAG_CORRUPT;
             return 0;
         }
diff --git a/libavformat/oma.c b/libavformat/oma.c
index f6454d9..9e4bfbd 100644
--- a/libavformat/oma.c
+++ b/libavformat/oma.c
@@ -1,20 +1,20 @@
 /*
  * Sony OpenMG (OMA) common data
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -22,7 +22,7 @@
 #include "oma.h"
 #include "libavcodec/avcodec.h"
 
-const uint16_t ff_oma_srate_tab[6] = { 320, 441, 480, 882, 960, 0 };
+const uint16_t ff_oma_srate_tab[8] = { 320, 441, 480, 882, 960, 0, 0, 0};
 
 const AVCodecTag ff_oma_codec_tags[] = {
     { AV_CODEC_ID_ATRAC3,      OMA_CODECID_ATRAC3  },
@@ -31,3 +31,4 @@
     { AV_CODEC_ID_PCM_S16BE,   OMA_CODECID_LPCM    },
     { 0 },
 };
+
diff --git a/libavformat/oma.h b/libavformat/oma.h
index bac8bcb..1f0ddf9 100644
--- a/libavformat/oma.h
+++ b/libavformat/oma.h
@@ -37,7 +37,7 @@
     OMA_CODECID_WMA     = 5,
 };
 
-extern const uint16_t ff_oma_srate_tab[6];
+extern const uint16_t ff_oma_srate_tab[8];
 
 extern const AVCodecTag ff_oma_codec_tags[];
 
diff --git a/libavformat/omadec.c b/libavformat/omadec.c
index 022942d..1e1b980 100644
--- a/libavformat/omadec.c
+++ b/libavformat/omadec.c
@@ -5,20 +5,20 @@
  *               2008 Benjamin Larsson
  *               2011 David Goldwich
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -219,6 +219,12 @@
         av_log(s, AV_LOG_ERROR, "Invalid encryption header\n");
         return -1;
     }
+    if (   OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size + 8 > geob->datasize
+        || OMA_ENC_HEADER_SIZE + 48 > geob->datasize
+    ) {
+        av_log(s, AV_LOG_ERROR, "Too little GEOB data\n");
+        return AVERROR_INVALIDDATA;
+    }
     oc->rid = AV_RB32(&gdata[OMA_ENC_HEADER_SIZE + 28]);
     av_log(s, AV_LOG_DEBUG, "RID: %.8x\n", oc->rid);
 
@@ -242,7 +248,7 @@
             if (!rprobe(s, gdata, oc->r_val) || !nprobe(s, gdata, geob->datasize, oc->n_val))
                 break;
         }
-        if (i >= sizeof(leaf_table)) {
+        if (i >= FF_ARRAY_ELEMS(leaf_table)) {
             av_log(s, AV_LOG_ERROR, "Invalid key\n");
             return -1;
         }
@@ -340,7 +346,7 @@
             av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n");
             break;
         case OMA_CODECID_MP3:
-            st->need_parsing = AVSTREAM_PARSE_FULL;
+            st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
             framesize = 1024;
             break;
         case OMA_CODECID_LPCM:
@@ -377,7 +383,7 @@
 
     if (oc->encrypted) {
         /* previous unencrypted block saved in IV for the next packet (CBC mode) */
-        av_des_crypt(&oc->av_des, pkt->data, pkt->data, (packet_size >> 3), oc->iv, 1);
+        av_des_crypt(&oc->av_des, pkt->data, pkt->data, (ret >> 3), oc->iv, 1);
     }
 
     return ret;
diff --git a/libavformat/omaenc.c b/libavformat/omaenc.c
index ea28e10..ab31d65 100644
--- a/libavformat/omaenc.c
+++ b/libavformat/omaenc.c
@@ -61,7 +61,7 @@
     switch(format->codec_tag) {
     case OMA_CODECID_ATRAC3:
         if (format->channels != 2) {
-            av_log(s, AV_LOG_ERROR, "ATRAC3 in OMA is only supported with 2 channels");
+            av_log(s, AV_LOG_ERROR, "ATRAC3 in OMA is only supported with 2 channels\n");
             return AVERROR(EINVAL);
         }
         if (format->extradata_size == 14) /* WAV format extradata */
diff --git a/libavformat/options.c b/libavformat/options.c
index 3399dd4..42307d1 100644
--- a/libavformat/options.c
+++ b/libavformat/options.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
@@ -76,6 +76,13 @@
     return NULL;
 }
 
+static AVClassCategory get_category(void *ptr)
+{
+    AVFormatContext* s = ptr;
+    if(s->iformat) return AV_CLASS_CATEGORY_DEMUXER;
+    else           return AV_CLASS_CATEGORY_MUXER;
+}
+
 static const AVClass av_format_context_class = {
     .class_name     = "AVFormatContext",
     .item_name      = format_to_name,
@@ -83,6 +90,8 @@
     .version        = LIBAVUTIL_VERSION_INT,
     .child_next     = format_child_next,
     .child_class_next = format_child_class_next,
+    .category       = AV_CLASS_CATEGORY_MUXER,
+    .get_category   = get_category,
 };
 
 static void avformat_get_context_defaults(AVFormatContext *s)
@@ -103,6 +112,11 @@
     return ic;
 }
 
+enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method(const AVFormatContext* ctx)
+{
+    return ctx->duration_estimation_method;
+}
+
 const AVClass *avformat_get_class(void)
 {
     return &av_format_context_class;
diff --git a/libavformat/options_table.h b/libavformat/options_table.h
index 4beee5d..778c740 100644
--- a/libavformat/options_table.h
+++ b/libavformat/options_table.h
@@ -1,18 +1,20 @@
 /*
- * This file is part of Libav.
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -31,6 +33,8 @@
 #define D AV_OPT_FLAG_DECODING_PARAM
 
 static const AVOption options[]={
+{"avioflags", NULL, OFFSET(avio_flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, INT_MIN, INT_MAX, D|E, "avioflags"},
+{"direct", "reduce buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVIO_FLAG_DIRECT }, INT_MIN, INT_MAX, D|E, "avioflags"},
 {"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT, {.i64 = 5000000 }, 32, INT_MAX, D},
 {"packetsize", "set packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, E},
 {"fflags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, INT_MIN, INT_MAX, D|E, "fflags"},
@@ -40,6 +44,9 @@
 {"noparse", "disable AVParsers, this needs nofillin too", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_NOPARSE }, INT_MIN, INT_MAX, D, "fflags"},
 {"igndts", "ignore dts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_IGNDTS }, INT_MIN, INT_MAX, D, "fflags"},
 {"discardcorrupt", "discard corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_DISCARD_CORRUPT }, INT_MIN, INT_MAX, D, "fflags"},
+{"sortdts", "try to interleave outputted packets by dts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_SORT_DTS }, INT_MIN, INT_MAX, D, "fflags"},
+{"keepside", "dont merge side data", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_KEEP_SIDE_DATA }, INT_MIN, INT_MAX, D, "fflags"},
+{"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},
 {"cryptokey", "decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, {.dbl = 0}, 0, 0, D},
@@ -49,6 +56,9 @@
 {"ts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_FDEBUG_TS }, INT_MIN, INT_MAX, E|D, "fdebug"},
 {"max_delay", "maximum muxing or demuxing delay in microseconds", OFFSET(max_delay), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, INT_MAX, E|D},
 {"fpsprobesize", "number of frames used to probe fps", OFFSET(fps_probe_size), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX-1, D},
+{"audio_preload", "microseconds by which audio packets should be interleaved earlier", OFFSET(audio_preload), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, E},
+{"chunk_duration", "microseconds for each chunk", OFFSET(max_chunk_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, E},
+{"chunk_size", "size in bytes for each chunk", OFFSET(max_chunk_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, E},
 /* this is a crutch for avconv, since it cannot deal with identically named options in different contexts.
  * to be removed when avconv is fixed */
 {"f_err_detect", "set error detection flags (deprecated; use err_detect, save via avconv)", OFFSET(error_recognition), AV_OPT_TYPE_FLAGS, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, D, "err_detect"},
@@ -57,6 +67,11 @@
 {"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, D, "err_detect"},
 {"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, D, "err_detect"},
 {"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, D, "err_detect"},
+{"careful",    "consider things that violate the spec and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, D, "err_detect"},
+{"compliant",  "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, D, "err_detect"},
+{"aggressive", "consider things that a sane encoder shouldnt do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, D, "err_detect"},
+{"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},
 {NULL},
 };
 
diff --git a/libavformat/os_support.c b/libavformat/os_support.c
index 7618708..bf6b8f2 100644
--- a/libavformat/os_support.c
+++ b/libavformat/os_support.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  * copyright (c) 2002 Francois Revol
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -32,6 +32,7 @@
 #include <fcntl.h>
 #include <io.h>
 #include <windows.h>
+#include <share.h>
 
 int ff_win32_open(const char *filename_utf8, int oflag, int pmode)
 {
@@ -46,12 +47,12 @@
     filename_w = av_mallocz(sizeof(wchar_t) * num_chars);
     MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, filename_w, num_chars);
 
-    fd = _wopen(filename_w, oflag, pmode);
+    fd = _wsopen(filename_w, oflag, SH_DENYNO, pmode);
     av_freep(&filename_w);
 
     /* filename maybe be in CP_ACP */
     if (fd == -1 && !(oflag & O_CREAT))
-        return open(filename_utf8, oflag, pmode);
+        return _sopen(filename_utf8, oflag, SH_DENYNO, pmode);
 
     return fd;
 }
diff --git a/libavformat/os_support.h b/libavformat/os_support.h
index 1bf79eb..589eb7e 100644
--- a/libavformat/os_support.h
+++ b/libavformat/os_support.h
@@ -2,20 +2,20 @@
  * various OS-feature replacement utilities
  * copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -33,8 +33,17 @@
 
 #if defined(__MINGW32__) && !defined(__MINGW32CE__)
 #  include <fcntl.h>
+#  ifdef lseek
+#   undef lseek
+#  endif
 #  define lseek(f,p,w) _lseeki64((f), (p), (w))
+#  ifdef stat
+#   undef stat
+#  endif
 #  define stat _stati64
+#  ifdef fstat
+#   undef fstat
+#  endif
 #  define fstat(f,s) _fstati64((f), (s))
 #endif /* defined(__MINGW32__) && !defined(__MINGW32CE__) */
 
diff --git a/libavformat/output-example.c b/libavformat/output-example.c
deleted file mode 100644
index e4babb4..0000000
--- a/libavformat/output-example.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * Copyright (c) 2003 Fabrice Bellard
- *
- * 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.
- */
-
-/**
- * @file
- * libavformat API example.
- *
- * @example libavformat/output-example.c
- * Output a media file in any supported libavformat format.
- * The default codecs are used.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-
-#include "libavutil/mathematics.h"
-#include "libavformat/avformat.h"
-#include "libswscale/swscale.h"
-
-#undef exit
-
-/* 5 seconds stream duration */
-#define STREAM_DURATION   5.0
-#define STREAM_FRAME_RATE 25 /* 25 images/s */
-#define STREAM_NB_FRAMES  ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
-#define STREAM_PIX_FMT    AV_PIX_FMT_YUV420P /* default pix_fmt */
-
-static int sws_flags = SWS_BICUBIC;
-
-/**************************************************************/
-/* audio output */
-
-static float t, tincr, tincr2;
-static int16_t *samples;
-static int audio_input_frame_size;
-
-/*
- * add an audio output stream
- */
-static AVStream *add_audio_stream(AVFormatContext *oc, enum AVCodecID codec_id)
-{
-    AVCodecContext *c;
-    AVStream *st;
-    AVCodec *codec;
-
-    /* find the audio encoder */
-    codec = avcodec_find_encoder(codec_id);
-    if (!codec) {
-        fprintf(stderr, "codec not found\n");
-        exit(1);
-    }
-
-    st = avformat_new_stream(oc, codec);
-    if (!st) {
-        fprintf(stderr, "Could not alloc stream\n");
-        exit(1);
-    }
-
-    c = st->codec;
-
-    /* put sample parameters */
-    c->sample_fmt  = AV_SAMPLE_FMT_S16;
-    c->bit_rate    = 64000;
-    c->sample_rate = 44100;
-    c->channels    = 2;
-
-    // some formats want stream headers to be separate
-    if (oc->oformat->flags & AVFMT_GLOBALHEADER)
-        c->flags |= CODEC_FLAG_GLOBAL_HEADER;
-
-    return st;
-}
-
-static void open_audio(AVFormatContext *oc, AVStream *st)
-{
-    AVCodecContext *c;
-
-    c = st->codec;
-
-    /* open it */
-    if (avcodec_open2(c, NULL, NULL) < 0) {
-        fprintf(stderr, "could not open codec\n");
-        exit(1);
-    }
-
-    /* init signal generator */
-    t     = 0;
-    tincr = 2 * M_PI * 110.0 / c->sample_rate;
-    /* increment frequency by 110 Hz per second */
-    tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
-
-    if (c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
-        audio_input_frame_size = 10000;
-    else
-        audio_input_frame_size = c->frame_size;
-    samples = av_malloc(audio_input_frame_size *
-                        av_get_bytes_per_sample(c->sample_fmt) *
-                        c->channels);
-}
-
-/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
- * 'nb_channels' channels. */
-static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels)
-{
-    int j, i, v;
-    int16_t *q;
-
-    q = samples;
-    for (j = 0; j < frame_size; j++) {
-        v = (int)(sin(t) * 10000);
-        for (i = 0; i < nb_channels; i++)
-            *q++ = v;
-        t     += tincr;
-        tincr += tincr2;
-    }
-}
-
-static void write_audio_frame(AVFormatContext *oc, AVStream *st)
-{
-    AVCodecContext *c;
-    AVPacket pkt = { 0 }; // data and size must be 0;
-    AVFrame *frame = avcodec_alloc_frame();
-    int got_packet;
-
-    av_init_packet(&pkt);
-    c = st->codec;
-
-    get_audio_frame(samples, audio_input_frame_size, c->channels);
-    frame->nb_samples = audio_input_frame_size;
-    avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
-                             (uint8_t *)samples,
-                             audio_input_frame_size *
-                             av_get_bytes_per_sample(c->sample_fmt) *
-                             c->channels, 1);
-
-    avcodec_encode_audio2(c, &pkt, frame, &got_packet);
-    if (!got_packet)
-        return;
-
-    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");
-        exit(1);
-    }
-    avcodec_free_frame(&frame);
-}
-
-static void close_audio(AVFormatContext *oc, AVStream *st)
-{
-    avcodec_close(st->codec);
-
-    av_free(samples);
-}
-
-/**************************************************************/
-/* video output */
-
-static AVFrame *picture, *tmp_picture;
-static uint8_t *video_outbuf;
-static int frame_count, video_outbuf_size;
-
-/* Add a video output stream. */
-static AVStream *add_video_stream(AVFormatContext *oc, enum AVCodecID codec_id)
-{
-    AVCodecContext *c;
-    AVStream *st;
-    AVCodec *codec;
-
-    /* find the video encoder */
-    codec = avcodec_find_encoder(codec_id);
-    if (!codec) {
-        fprintf(stderr, "codec not found\n");
-        exit(1);
-    }
-
-    st = avformat_new_stream(oc, codec);
-    if (!st) {
-        fprintf(stderr, "Could not alloc stream\n");
-        exit(1);
-    }
-
-    c = st->codec;
-
-    /* Put sample parameters. */
-    c->bit_rate = 400000;
-    /* Resolution must be a multiple of two. */
-    c->width    = 352;
-    c->height   = 288;
-    /* timebase: This is the fundamental unit of time (in seconds) in terms
-     * of which frame timestamps are represented. For fixed-fps content,
-     * timebase should be 1/framerate and timestamp increments should be
-     * identical to 1. */
-    c->time_base.den = STREAM_FRAME_RATE;
-    c->time_base.num = 1;
-    c->gop_size      = 12; /* emit one intra frame every twelve frames at most */
-    c->pix_fmt       = STREAM_PIX_FMT;
-    if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
-        /* just for testing, we also add B frames */
-        c->max_b_frames = 2;
-    }
-    if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
-        /* Needed to avoid using macroblocks in which some coeffs overflow.
-         * This does not happen with normal video, it just happens here as
-         * the motion of the chroma plane does not match the luma plane. */
-        c->mb_decision = 2;
-    }
-    /* Some formats want stream headers to be separate. */
-    if (oc->oformat->flags & AVFMT_GLOBALHEADER)
-        c->flags |= CODEC_FLAG_GLOBAL_HEADER;
-
-    return st;
-}
-
-static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
-{
-    AVFrame *picture;
-    uint8_t *picture_buf;
-    int size;
-
-    picture = avcodec_alloc_frame();
-    if (!picture)
-        return NULL;
-    size        = avpicture_get_size(pix_fmt, width, height);
-    picture_buf = av_malloc(size);
-    if (!picture_buf) {
-        av_free(picture);
-        return NULL;
-    }
-    avpicture_fill((AVPicture *)picture, picture_buf,
-                   pix_fmt, width, height);
-    return picture;
-}
-
-static void open_video(AVFormatContext *oc, AVStream *st)
-{
-    AVCodecContext *c;
-
-    c = st->codec;
-
-    /* open the codec */
-    if (avcodec_open2(c, NULL, NULL) < 0) {
-        fprintf(stderr, "could not open codec\n");
-        exit(1);
-    }
-
-    video_outbuf = NULL;
-    if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
-        /* Allocate output buffer. */
-        /* XXX: API change will be done. */
-        /* Buffers passed into lav* can be allocated any way you prefer,
-         * as long as they're aligned enough for the architecture, and
-         * they're freed appropriately (such as using av_free for buffers
-         * allocated with av_malloc). */
-        video_outbuf_size = 200000;
-        video_outbuf      = av_malloc(video_outbuf_size);
-    }
-
-    /* Allocate the encoded raw picture. */
-    picture = alloc_picture(c->pix_fmt, c->width, c->height);
-    if (!picture) {
-        fprintf(stderr, "Could not allocate picture\n");
-        exit(1);
-    }
-
-    /* If the output format is not YUV420P, then a temporary YUV420P
-     * picture is needed too. It is then converted to the required
-     * output format. */
-    tmp_picture = NULL;
-    if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
-        tmp_picture = alloc_picture(AV_PIX_FMT_YUV420P, c->width, c->height);
-        if (!tmp_picture) {
-            fprintf(stderr, "Could not allocate temporary picture\n");
-            exit(1);
-        }
-    }
-}
-
-/* Prepare a dummy image. */
-static void fill_yuv_image(AVFrame *pict, int frame_index,
-                           int width, int height)
-{
-    int x, y, i;
-
-    i = frame_index;
-
-    /* Y */
-    for (y = 0; y < height; y++)
-        for (x = 0; x < width; x++)
-            pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3;
-
-    /* Cb and Cr */
-    for (y = 0; y < height / 2; y++) {
-        for (x = 0; x < width / 2; x++) {
-            pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2;
-            pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5;
-        }
-    }
-}
-
-static void write_video_frame(AVFormatContext *oc, AVStream *st)
-{
-    int out_size, ret;
-    AVCodecContext *c;
-    static struct SwsContext *img_convert_ctx;
-
-    c = st->codec;
-
-    if (frame_count >= STREAM_NB_FRAMES) {
-        /* No more frames to compress. The codec has a latency of a few
-         * frames if using B-frames, so we get the last frames by
-         * passing the same picture again. */
-    } else {
-        if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
-            /* as we only generate a YUV420P picture, we must convert it
-             * to the codec pixel format if needed */
-            if (img_convert_ctx == NULL) {
-                img_convert_ctx = sws_getContext(c->width, c->height,
-                                                 AV_PIX_FMT_YUV420P,
-                                                 c->width, c->height,
-                                                 c->pix_fmt,
-                                                 sws_flags, NULL, NULL, NULL);
-                if (img_convert_ctx == NULL) {
-                    fprintf(stderr,
-                            "Cannot initialize the conversion context\n");
-                    exit(1);
-                }
-            }
-            fill_yuv_image(tmp_picture, frame_count, c->width, c->height);
-            sws_scale(img_convert_ctx, tmp_picture->data, tmp_picture->linesize,
-                      0, c->height, picture->data, picture->linesize);
-        } else {
-            fill_yuv_image(picture, frame_count, c->width, c->height);
-        }
-    }
-
-    if (oc->oformat->flags & AVFMT_RAWPICTURE) {
-        /* Raw video case - the API will change slightly in the near
-         * future for that. */
-        AVPacket pkt;
-        av_init_packet(&pkt);
-
-        pkt.flags        |= AV_PKT_FLAG_KEY;
-        pkt.stream_index  = st->index;
-        pkt.data          = (uint8_t *)picture;
-        pkt.size          = sizeof(AVPicture);
-
-        ret = av_interleaved_write_frame(oc, &pkt);
-    } else {
-        /* encode the image */
-        out_size = avcodec_encode_video(c, video_outbuf,
-                                        video_outbuf_size, picture);
-        /* If size is zero, it means the image was buffered. */
-        if (out_size > 0) {
-            AVPacket pkt;
-            av_init_packet(&pkt);
-
-            if (c->coded_frame->pts != AV_NOPTS_VALUE)
-                pkt.pts = av_rescale_q(c->coded_frame->pts,
-                                       c->time_base, st->time_base);
-            if (c->coded_frame->key_frame)
-                pkt.flags |= AV_PKT_FLAG_KEY;
-            pkt.stream_index = st->index;
-            pkt.data         = video_outbuf;
-            pkt.size         = out_size;
-
-            /* Write the compressed frame to the media file. */
-            ret = av_interleaved_write_frame(oc, &pkt);
-        } else {
-            ret = 0;
-        }
-    }
-    if (ret != 0) {
-        fprintf(stderr, "Error while writing video frame\n");
-        exit(1);
-    }
-    frame_count++;
-}
-
-static void close_video(AVFormatContext *oc, AVStream *st)
-{
-    avcodec_close(st->codec);
-    av_free(picture->data[0]);
-    av_free(picture);
-    if (tmp_picture) {
-        av_free(tmp_picture->data[0]);
-        av_free(tmp_picture);
-    }
-    av_free(video_outbuf);
-}
-
-/**************************************************************/
-/* media file output */
-
-int main(int argc, char **argv)
-{
-    const char *filename;
-    AVOutputFormat *fmt;
-    AVFormatContext *oc;
-    AVStream *audio_st, *video_st;
-    double audio_pts, video_pts;
-    int i;
-
-    /* Initialize libavcodec, and register all codecs and formats. */
-    av_register_all();
-
-    if (argc != 2) {
-        printf("usage: %s output_file\n"
-               "API example program to output a media file with libavformat.\n"
-               "The output format is automatically guessed according to the file extension.\n"
-               "Raw images can also be output by using '%%d' in the filename\n"
-               "\n", argv[0]);
-        return 1;
-    }
-
-    filename = argv[1];
-
-    /* Autodetect the output format from the name. default is MPEG. */
-    fmt = av_guess_format(NULL, filename, NULL);
-    if (!fmt) {
-        printf("Could not deduce output format from file extension: using MPEG.\n");
-        fmt = av_guess_format("mpeg", NULL, NULL);
-    }
-    if (!fmt) {
-        fprintf(stderr, "Could not find suitable output format\n");
-        return 1;
-    }
-
-    /* Allocate the output media context. */
-    oc = avformat_alloc_context();
-    if (!oc) {
-        fprintf(stderr, "Memory error\n");
-        return 1;
-    }
-    oc->oformat = fmt;
-    snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
-
-    /* Add the audio and video streams using the default format codecs
-     * and initialize the codecs. */
-    video_st = NULL;
-    audio_st = NULL;
-    if (fmt->video_codec != AV_CODEC_ID_NONE) {
-        video_st = add_video_stream(oc, fmt->video_codec);
-    }
-    if (fmt->audio_codec != AV_CODEC_ID_NONE) {
-        audio_st = add_audio_stream(oc, fmt->audio_codec);
-    }
-
-    /* Now that all the parameters are set, we can open the audio and
-     * video codecs and allocate the necessary encode buffers. */
-    if (video_st)
-        open_video(oc, video_st);
-    if (audio_st)
-        open_audio(oc, audio_st);
-
-    av_dump_format(oc, 0, filename, 1);
-
-    /* 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);
-            return 1;
-        }
-    }
-
-    /* Write the stream header, if any. */
-    avformat_write_header(oc, NULL);
-
-    for (;;) {
-        /* Compute current audio and video time. */
-        if (audio_st)
-            audio_pts = (double)audio_st->pts.val * audio_st->time_base.num / audio_st->time_base.den;
-        else
-            audio_pts = 0.0;
-
-        if (video_st)
-            video_pts = (double)video_st->pts.val * video_st->time_base.num /
-                        video_st->time_base.den;
-        else
-            video_pts = 0.0;
-
-        if ((!audio_st || audio_pts >= STREAM_DURATION) &&
-            (!video_st || video_pts >= STREAM_DURATION))
-            break;
-
-        /* write interleaved audio and video frames */
-        if (!video_st || (video_st && audio_st && audio_pts < video_pts)) {
-            write_audio_frame(oc, audio_st);
-        } else {
-            write_video_frame(oc, video_st);
-        }
-    }
-
-    /* Write the trailer, if any. The trailer must be written before you
-     * close the CodecContexts open when you wrote the header; otherwise
-     * av_write_trailer() may try to use memory that was freed on
-     * av_codec_close(). */
-    av_write_trailer(oc);
-
-    /* Close each codec. */
-    if (video_st)
-        close_video(oc, video_st);
-    if (audio_st)
-        close_audio(oc, audio_st);
-
-    /* Free the streams. */
-    for (i = 0; i < oc->nb_streams; i++) {
-        av_freep(&oc->streams[i]->codec);
-        av_freep(&oc->streams[i]);
-    }
-
-    if (!(fmt->flags & AVFMT_NOFILE))
-        /* Close the output file. */
-        avio_close(oc->pb);
-
-    /* free the stream */
-    av_free(oc);
-
-    return 0;
-}
diff --git a/libavformat/paf.c b/libavformat/paf.c
new file mode 100644
index 0000000..8fe2ac5
--- /dev/null
+++ b/libavformat/paf.c
@@ -0,0 +1,259 @@
+/*
+ * Packed Animation 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 "libavcodec/paf.h"
+#include "avformat.h"
+#include "internal.h"
+
+#define MAGIC "Packed Animation File V1.0\n(c) 1992-96 Amazing Studio\x0a\x1a"
+
+typedef struct {
+    uint32_t buffer_size;
+    uint32_t frame_blks;
+    uint32_t nb_frames;
+    uint32_t start_offset;
+    uint32_t preload_count;
+    uint32_t max_video_blks;
+    uint32_t max_audio_blks;
+
+    uint32_t current_frame;
+    uint32_t current_frame_count;
+    uint32_t current_frame_block;
+
+    uint32_t *blocks_count_table;
+    uint32_t *frames_offset_table;
+    uint32_t *blocks_offset_table;
+
+    uint8_t  *video_frame;
+    int      video_size;
+
+    uint8_t  *audio_frame;
+    uint8_t  *temp_audio_frame;
+    int      audio_size;
+
+    int      got_audio;
+} PAFDemuxContext;
+
+static int read_probe(AVProbeData *p)
+{
+    if ((p->buf_size >= strlen(MAGIC)) &&
+        !memcmp(p->buf, MAGIC, strlen(MAGIC)))
+        return AVPROBE_SCORE_MAX;
+    return 0;
+}
+
+static int read_close(AVFormatContext *s)
+{
+    PAFDemuxContext *p = s->priv_data;
+
+    av_freep(&p->blocks_count_table);
+    av_freep(&p->frames_offset_table);
+    av_freep(&p->blocks_offset_table);
+    av_freep(&p->video_frame);
+    av_freep(&p->audio_frame);
+    av_freep(&p->temp_audio_frame);
+
+    return 0;
+}
+
+static void read_table(AVFormatContext *s, uint32_t *table, uint32_t count)
+{
+    int i;
+
+    for (i = 0; i < count; i++)
+        table[i] = avio_rl32(s->pb);
+
+    avio_skip(s->pb, 4 * (FFALIGN(count, 512) - count));
+}
+
+static int read_header(AVFormatContext *s)
+{
+    PAFDemuxContext *p = s->priv_data;
+    AVIOContext     *pb = s->pb;
+    AVStream        *ast, *vst;
+    int             ret = 0;
+
+    avio_skip(pb, 132);
+
+    vst = avformat_new_stream(s, 0);
+    if (!vst)
+        return AVERROR(ENOMEM);
+
+    vst->start_time = 0;
+    vst->nb_frames  =
+    vst->duration   =
+    p->nb_frames = avio_rl32(pb);
+    avio_skip(pb, 4);
+    vst->codec->width  = avio_rl32(pb);
+    vst->codec->height = avio_rl32(pb);
+    avio_skip(pb, 4);
+    vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+    vst->codec->codec_tag  = 0;
+    vst->codec->codec_id   = AV_CODEC_ID_PAF_VIDEO;
+    avpriv_set_pts_info(vst, 64, 1, 10);
+
+    ast = avformat_new_stream(s, 0);
+    if (!ast)
+        return AVERROR(ENOMEM);
+
+    ast->start_time         = 0;
+    ast->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
+    ast->codec->codec_tag   = 0;
+    ast->codec->codec_id    = AV_CODEC_ID_PAF_AUDIO;
+    ast->codec->channels    = 2;
+    ast->codec->sample_rate = 22050;
+    avpriv_set_pts_info(ast, 64, 1, 22050);
+
+    p->buffer_size    = avio_rl32(pb);
+    p->preload_count  = avio_rl32(pb);
+    p->frame_blks     = avio_rl32(pb);
+    p->start_offset   = avio_rl32(pb);
+    p->max_video_blks = avio_rl32(pb);
+    p->max_audio_blks = avio_rl32(pb);
+    if (p->buffer_size    < 175  ||
+        p->max_audio_blks < 2    ||
+        p->max_video_blks < 1    ||
+        p->frame_blks     < 1    ||
+        p->nb_frames      < 1    ||
+        p->preload_count  < 1    ||
+        p->buffer_size    > 2048 ||
+        p->max_video_blks > 2048 ||
+        p->max_audio_blks > 2048 ||
+        p->nb_frames      > INT_MAX / sizeof(uint32_t) ||
+        p->frame_blks     > INT_MAX / sizeof(uint32_t))
+        return AVERROR_INVALIDDATA;
+
+    p->blocks_count_table  = av_mallocz(p->nb_frames  * sizeof(uint32_t));
+    p->frames_offset_table = av_mallocz(p->nb_frames  * sizeof(uint32_t));
+    p->blocks_offset_table = av_mallocz(p->frame_blks * sizeof(uint32_t));
+
+    p->video_size          = p->max_video_blks * p->buffer_size;
+    p->video_frame         = av_mallocz(p->video_size);
+
+    p->audio_size          = p->max_audio_blks * p->buffer_size;
+    p->audio_frame         = av_mallocz(p->audio_size);
+    p->temp_audio_frame    = av_mallocz(p->audio_size);
+
+    if (!p->blocks_count_table  ||
+        !p->frames_offset_table ||
+        !p->blocks_offset_table ||
+        !p->video_frame         ||
+        !p->audio_frame         ||
+        !p->temp_audio_frame) {
+        ret = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    avio_seek(pb, p->buffer_size, SEEK_SET);
+
+    read_table(s, p->blocks_count_table,  p->nb_frames);
+    read_table(s, p->frames_offset_table, p->nb_frames);
+    read_table(s, p->blocks_offset_table, p->frame_blks);
+
+    p->got_audio = 0;
+    p->current_frame = 0;
+    p->current_frame_block = 0;
+
+    avio_seek(pb, p->start_offset, SEEK_SET);
+
+    return 0;
+
+fail:
+    read_close(s);
+
+    return ret;
+}
+
+static int read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    PAFDemuxContext *p = s->priv_data;
+    AVIOContext     *pb = s->pb;
+    uint32_t        count, offset;
+    int             size, i;
+
+    if (p->current_frame >= p->nb_frames)
+        return AVERROR_EOF;
+
+    if (url_feof(pb))
+        return AVERROR_EOF;
+
+    if (p->got_audio) {
+        if (av_new_packet(pkt, p->audio_size) < 0)
+            return AVERROR(ENOMEM);
+
+        memcpy(pkt->data, p->temp_audio_frame, p->audio_size);
+        pkt->duration     = PAF_SOUND_SAMPLES * (p->audio_size / PAF_SOUND_FRAME_SIZE);
+        pkt->flags       |= AV_PKT_FLAG_KEY;
+        pkt->stream_index = 1;
+        p->got_audio      = 0;
+        return pkt->size;
+    }
+
+    count = (p->current_frame == 0) ? p->preload_count : p->blocks_count_table[p->current_frame - 1];
+    for (i = 0; i < count; i++) {
+        if (p->current_frame_block >= p->frame_blks)
+            return AVERROR_INVALIDDATA;
+
+        offset = p->blocks_offset_table[p->current_frame_block] & ~(1 << 31);
+        if (p->blocks_offset_table[p->current_frame_block] & (1 << 31)) {
+            if (offset > p->audio_size - p->buffer_size)
+                return AVERROR_INVALIDDATA;
+
+            avio_read(pb, p->audio_frame + offset, p->buffer_size);
+            if (offset == (p->max_audio_blks - 2) * p->buffer_size) {
+                memcpy(p->temp_audio_frame, p->audio_frame, p->audio_size);
+                p->got_audio = 1;
+            }
+        } else {
+            if (offset > p->video_size - p->buffer_size)
+                return AVERROR_INVALIDDATA;
+
+            avio_read(pb, p->video_frame + offset, p->buffer_size);
+        }
+        p->current_frame_block++;
+    }
+
+    size = p->video_size - p->frames_offset_table[p->current_frame];
+    if (size < 1)
+        return AVERROR_INVALIDDATA;
+
+    if (av_new_packet(pkt, size) < 0)
+        return AVERROR(ENOMEM);
+
+    pkt->stream_index = 0;
+    pkt->duration     = 1;
+    memcpy(pkt->data, p->video_frame + p->frames_offset_table[p->current_frame], size);
+    if (pkt->data[0] & 0x20)
+        pkt->flags   |= AV_PKT_FLAG_KEY;
+    p->current_frame++;
+
+    return pkt->size;
+}
+
+AVInputFormat ff_paf_demuxer = {
+    .name           = "paf",
+    .long_name      = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File"),
+    .priv_data_size = sizeof(PAFDemuxContext),
+    .read_probe     = read_probe,
+    .read_header    = read_header,
+    .read_packet    = read_packet,
+    .read_close     = read_close,
+};
diff --git a/libavformat/pcm.c b/libavformat/pcm.c
index 892e8ca..bba741d 100644
--- a/libavformat/pcm.c
+++ b/libavformat/pcm.c
@@ -2,20 +2,20 @@
  * PCM common functions
  * Copyright (c) 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/pcm.h b/libavformat/pcm.h
index 30cbc86..60d8eb3 100644
--- a/libavformat/pcm.h
+++ b/libavformat/pcm.h
@@ -2,20 +2,20 @@
  * PCM common functions
  * Copyright (C) 2007  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/pcmdec.c b/libavformat/pcmdec.c
index ad47885..178c251 100644
--- a/libavformat/pcmdec.c
+++ b/libavformat/pcmdec.c
@@ -2,20 +2,20 @@
  * RAW PCM demuxers
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,6 +24,7 @@
 #include "pcm.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
+#include "libavutil/avassert.h"
 
 #define RAW_SAMPLES     1024
 
@@ -36,12 +37,13 @@
 
     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);
-    assert(bps); // if false there IS a bug elsewhere (NOT in this function)
+    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);
 
diff --git a/libavformat/pcmenc.c b/libavformat/pcmenc.c
index e45ab84..3e4f308 100644
--- a/libavformat/pcmenc.c
+++ b/libavformat/pcmenc.c
@@ -2,20 +2,20 @@
  * RAW PCM muxers
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/pmpdec.c b/libavformat/pmpdec.c
index 6cdce10..2ea37ef 100644
--- a/libavformat/pmpdec.c
+++ b/libavformat/pmpdec.c
@@ -1,21 +1,21 @@
 /*
- * PMP demuxer
+ * PMP demuxer.
  * Copyright (c) 2011 Reimar Döffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -23,18 +23,18 @@
 #include "avformat.h"
 #include "internal.h"
 
-typedef struct PMPContext {
-    int       cur_stream;
-    int       num_streams;
-    int       audio_packets;
-    int       current_packet;
+typedef struct {
+    int cur_stream;
+    int num_streams;
+    int audio_packets;
+    int current_packet;
     uint32_t *packet_sizes;
-    int       packet_sizes_alloc;
+    int packet_sizes_alloc;
 } PMPContext;
 
-static int pmp_probe(AVProbeData *p)
-{
-    if (!memcmp(p->buf, "pmpm\1\0\0\0", 8))
+static int pmp_probe(AVProbeData *p) {
+    if (AV_RN32(p->buf) == AV_RN32("pmpm") &&
+        AV_RL32(p->buf + 4) == 1)
         return AVPROBE_SCORE_MAX;
     return 0;
 }
@@ -65,7 +65,7 @@
         av_log(s, AV_LOG_ERROR, "Unsupported video format\n");
         break;
     }
-    index_cnt          = avio_rl32(pb);
+    index_cnt = avio_rl32(pb);
     vst->codec->width  = avio_rl32(pb);
     vst->codec->height = avio_rl32(pb);
 
@@ -73,14 +73,14 @@
     tb_den = avio_rl32(pb);
     avpriv_set_pts_info(vst, 32, tb_num, tb_den);
     vst->nb_frames = index_cnt;
-    vst->duration  = index_cnt;
+    vst->duration = index_cnt;
 
     switch (avio_rl32(pb)) {
     case 0:
         audio_codec_id = AV_CODEC_ID_MP3;
         break;
     case 1:
-        av_log(s, AV_LOG_WARNING, "AAC is not yet correctly supported\n");
+        av_log(s, AV_LOG_ERROR, "AAC not yet correctly supported\n");
         audio_codec_id = AV_CODEC_ID_AAC;
         break;
     default:
@@ -89,21 +89,21 @@
     }
     pmp->num_streams = avio_rl16(pb) + 1;
     avio_skip(pb, 10);
-    srate    = avio_rl32(pb);
+    srate = avio_rl32(pb);
     channels = avio_rl32(pb) + 1;
     for (i = 1; i < pmp->num_streams; i++) {
         AVStream *ast = avformat_new_stream(s, NULL);
         if (!ast)
             return AVERROR(ENOMEM);
-        ast->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
-        ast->codec->codec_id    = audio_codec_id;
-        ast->codec->channels    = channels;
+        ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+        ast->codec->codec_id = audio_codec_id;
+        ast->codec->channels = channels;
         ast->codec->sample_rate = srate;
         avpriv_set_pts_info(ast, 32, 1, srate);
     }
-    pos = avio_tell(pb) + 4 * index_cnt;
+    pos = avio_tell(pb) + 4*index_cnt;
     for (i = 0; i < index_cnt; i++) {
-        int size  = avio_rl32(pb);
+        int size = avio_rl32(pb);
         int flags = size & 1 ? AVINDEX_KEYFRAME : 0;
         size >>= 1;
         av_add_index_entry(vst, pos, i, size, 0, flags);
@@ -119,11 +119,15 @@
     int ret = 0;
     int i;
 
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return AVERROR_EOF;
     if (pmp->cur_stream == 0) {
         int num_packets;
         pmp->audio_packets = avio_r8(pb);
+        if (!pmp->audio_packets) {
+            av_log_ask_for_sample(s, "0 audio packets\n");
+            return AVERROR_PATCHWELCOME;
+        }
         num_packets = (pmp->num_streams - 1) * pmp->audio_packets + 1;
         avio_skip(pb, 8);
         pmp->current_packet = 0;
@@ -138,7 +142,7 @@
             pmp->packet_sizes[i] = avio_rl32(pb);
     }
     ret = av_get_packet(pb, pkt, pmp->packet_sizes[pmp->current_packet]);
-    if (ret > 0) {
+    if (ret >= 0) {
         ret = 0;
         // FIXME: this is a hack that should be removed once
         // compute_pkt_fields() can handle timestamps properly
@@ -146,14 +150,13 @@
             pkt->dts = s->streams[0]->cur_dts++;
         pkt->stream_index = pmp->cur_stream;
     }
-    pmp->current_packet++;
-    if (pmp->current_packet == 1 || pmp->current_packet > pmp->audio_packets)
+    if (pmp->current_packet % pmp->audio_packets == 0)
         pmp->cur_stream = (pmp->cur_stream + 1) % pmp->num_streams;
-
+    pmp->current_packet++;
     return ret;
 }
 
-static int pmp_seek(AVFormatContext *s, int stream_idx, int64_t ts, int flags)
+static int pmp_seek(AVFormatContext *s, int stream_index, int64_t ts, int flags)
 {
     PMPContext *pmp = s->priv_data;
     pmp->cur_stream = 0;
diff --git a/libavformat/psxstr.c b/libavformat/psxstr.c
index 800d9cb..86fba16 100644
--- a/libavformat/psxstr.c
+++ b/libavformat/psxstr.c
@@ -2,20 +2,20 @@
  * Sony Playstation (PSX) STR File Demuxer
  * Copyright (c) 2003 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -64,11 +64,13 @@
     StrChannel channels[32];
 } StrDemuxContext;
 
-static const char sync_header[12] = {0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00};
+static const uint8_t sync_header[12] = {0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00};
 
 static int str_probe(AVProbeData *p)
 {
     uint8_t *sector= p->buf;
+    uint8_t *end= sector + p->buf_size;
+    int aud=0, vid=0;
 
     if (p->buf_size < RAW_CD_SECTOR_SIZE)
         return 0;
@@ -80,20 +82,52 @@
         sector += RIFF_HEADER_SIZE;
     }
 
-    /* look for CD sync header (00, 0xFF x 10, 00) */
-    if (memcmp(sector,sync_header,sizeof(sync_header)))
-        return 0;
+    while (end - sector >= RAW_CD_SECTOR_SIZE) {
+        /* look for CD sync header (00, 0xFF x 10, 00) */
+        if (memcmp(sector,sync_header,sizeof(sync_header)))
+            return 0;
 
-    if(sector[0x11] >= 32)
-        return 0;
-    if(   (sector[0x12] & CDXA_TYPE_MASK) != CDXA_TYPE_VIDEO
-       && (sector[0x12] & CDXA_TYPE_MASK) != CDXA_TYPE_AUDIO
-       && (sector[0x12] & CDXA_TYPE_MASK) != CDXA_TYPE_DATA)
-        return 0;
+        if (sector[0x11] >= 32)
+            return 0;
 
+        switch (sector[0x12] & CDXA_TYPE_MASK) {
+        case CDXA_TYPE_DATA:
+        case CDXA_TYPE_VIDEO: {
+                int current_sector = AV_RL16(&sector[0x1C]);
+                int sector_count   = AV_RL16(&sector[0x1E]);
+                int frame_size = AV_RL32(&sector[0x24]);
+
+                if(!(   frame_size>=0
+                     && current_sector < sector_count
+                     && sector_count*VIDEO_DATA_CHUNK_SIZE >=frame_size)){
+                    return 0;
+                }
+
+                /*st->codec->width      = AV_RL16(&sector[0x28]);
+                st->codec->height     = AV_RL16(&sector[0x2A]);*/
+
+//                 if (current_sector == sector_count-1) {
+                    vid++;
+//                 }
+
+            }
+            break;
+        case CDXA_TYPE_AUDIO:
+            if(sector[0x13]&0x2A)
+                return 0;
+            aud++;
+            break;
+        default:
+            if(sector[0x12] & CDXA_TYPE_MASK)
+                return 0;
+        }
+        sector += RAW_CD_SECTOR_SIZE;
+    }
     /* MPEG files (like those ripped from VCDs) can also look like this;
      * only return half certainty */
-    return 50;
+    if(vid+aud > 3)  return 50;
+    else if(vid+aud) return 1;
+    else             return 0;
 }
 
 static int str_read_header(AVFormatContext *s)
@@ -243,7 +277,7 @@
             break;
         }
 
-        if (pb->eof_reached)
+        if (url_feof(pb))
             return AVERROR(EIO);
     }
 }
diff --git a/libavformat/pva.c b/libavformat/pva.c
index 53041ba..ff8ccee 100644
--- a/libavformat/pva.c
+++ b/libavformat/pva.c
@@ -2,20 +2,20 @@
  * TechnoTrend PVA (.pva) demuxer
  * Copyright (c) 2007, 2008 Ivo van Poorten
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -32,13 +32,26 @@
     int continue_pes;
 } PVAContext;
 
+static int pva_check(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)
+        return -1;
+    return length + 8;
+}
+
 static int pva_probe(AVProbeData * pd) {
     unsigned char *buf = pd->buf;
+    int len = pva_check(buf);
 
-    if (AV_RB16(buf) == PVA_MAGIC && buf[2] && buf[2] < 3 && buf[4] == 0x55)
+    if (len < 0)
+        return 0;
+
+    if (pd->buf_size >= len + 8 &&
+        pva_check(buf + len) >= 0)
         return AVPROBE_SCORE_MAX / 2;
 
-    return 0;
+    return AVPROBE_SCORE_MAX / 4;
 }
 
 static int pva_read_header(AVFormatContext *s) {
diff --git a/libavformat/qcp.c b/libavformat/qcp.c
index bde5990..11fc71a 100644
--- a/libavformat/qcp.c
+++ b/libavformat/qcp.c
@@ -2,20 +2,20 @@
  * QCP format (.qcp) demuxer
  * Copyright (c) 2009 Kenan Gillet
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -139,7 +139,7 @@
     QCPContext    *c  = s->priv_data;
     unsigned int  chunk_size, tag;
 
-    while(!pb->eof_reached) {
+    while(!url_feof(pb)) {
         if (c->data_size) {
             int pkt_size, ret, mode = avio_r8(pb);
 
diff --git a/libavformat/qtpalette.h b/libavformat/qtpalette.h
index ecc85d3..7d6802f 100644
--- a/libavformat/qtpalette.h
+++ b/libavformat/qtpalette.h
@@ -3,20 +3,20 @@
  *  Automatically generated from a utility derived from XAnim:
  *  http://xanim.va.pubnix.com/home.html
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/r3d.c b/libavformat/r3d.c
index a4cb20a..35da81e 100644
--- a/libavformat/r3d.c
+++ b/libavformat/r3d.c
@@ -2,20 +2,20 @@
  * R3D REDCODE demuxer
  * Copyright (c) 2008 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -141,8 +141,7 @@
 
     if (st->avg_frame_rate.num)
         st->duration = av_rescale_q(r3d->video_offsets_count,
-                                    (AVRational){st->avg_frame_rate.den,
-                                                 st->avg_frame_rate.num},
+                                    av_inv_q(st->avg_frame_rate),
                                     st->time_base);
     av_dlog(s, "duration %"PRId64"\n", st->duration);
 
@@ -370,7 +369,7 @@
         return -1;
 
     frame_num = av_rescale_q(sample_time, st->time_base,
-                             (AVRational){st->avg_frame_rate.den, st->avg_frame_rate.num});
+                             av_inv_q(st->avg_frame_rate));
     av_dlog(s, "seek frame num %d timestamp %"PRId64"\n",
             frame_num, sample_time);
 
diff --git a/libavformat/rawdec.c b/libavformat/rawdec.c
index 7ea3d2b..4020666 100644
--- a/libavformat/rawdec.c
+++ b/libavformat/rawdec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2001 Fabrice Bellard
  * Copyright (c) 2005 Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -27,6 +27,7 @@
 #include "libavutil/opt.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/avassert.h"
 
 /* raw input */
 int ff_raw_read_header(AVFormatContext *s)
@@ -57,11 +58,17 @@
 
             if (s1 && s1->sample_rate)
                 st->codec->sample_rate = s1->sample_rate;
+            if (st->codec->sample_rate <= 0) {
+                av_log(s, AV_LOG_WARNING, "Invalid sample rate %d specified using default of 44100\n",
+                       st->codec->sample_rate);
+                st->codec->sample_rate= 44100;
+            }
+
             if (s1 && s1->channels)
                 st->codec->channels    = s1->channels;
 
             st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);
-            assert(st->codec->bits_per_coded_sample > 0);
+            av_assert0(st->codec->bits_per_coded_sample > 0);
             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);
             break;
@@ -116,7 +123,7 @@
         av_free_packet(pkt);
         return ret;
     }
-    pkt->size = ret;
+    av_shrink_packet(pkt, ret);
     return ret;
 }
 
@@ -127,7 +134,7 @@
         return AVERROR(ENOMEM);
     st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
     st->codec->codec_id = s->iformat->raw_codec_id;
-    st->need_parsing = AVSTREAM_PARSE_FULL;
+    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
     st->start_time = 0;
     /* the parameters will be extracted from the compressed bitstream */
 
@@ -151,18 +158,15 @@
 
     st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
     st->codec->codec_id = s->iformat->raw_codec_id;
-    st->need_parsing = AVSTREAM_PARSE_FULL;
+    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
 
     if ((ret = av_parse_video_rate(&framerate, s1->framerate)) < 0) {
         av_log(s, AV_LOG_ERROR, "Could not parse framerate: %s.\n", s1->framerate);
         goto fail;
     }
 
-#if FF_API_R_FRAME_RATE
-    st->r_frame_rate =
-#endif
-    st->avg_frame_rate = framerate;
-    avpriv_set_pts_info(st, 64, framerate.den, framerate.num);
+    st->codec->time_base = av_inv_q(framerate);
+    avpriv_set_pts_info(st, 64, 1, 1200000);
 
 fail:
     return ret;
@@ -202,7 +206,7 @@
 #endif
 
 #if CONFIG_MJPEG_DEMUXER
-FF_DEF_RAWVIDEO_DEMUXER(mjpeg, "raw MJPEG video", NULL, "mjpg,mjpeg", AV_CODEC_ID_MJPEG)
+FF_DEF_RAWVIDEO_DEMUXER(mjpeg, "raw MJPEG video", NULL, "mjpg,mjpeg,mpo", AV_CODEC_ID_MJPEG)
 #endif
 
 #if CONFIG_MLP_DEMUXER
diff --git a/libavformat/rawdec.h b/libavformat/rawdec.h
index 4cce2cf..5812e50 100644
--- a/libavformat/rawdec.h
+++ b/libavformat/rawdec.h
@@ -2,20 +2,20 @@
  * RAW demuxers
  * Copyright (C) 2007  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rawenc.c b/libavformat/rawenc.c
index 171c603..94e68c5 100644
--- a/libavformat/rawenc.c
+++ b/libavformat/rawenc.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2001 Fabrice Bellard
  * Copyright (c) 2005 Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -132,6 +132,19 @@
 };
 #endif
 
+#if CONFIG_G723_1_MUXER
+AVOutputFormat ff_g723_1_muxer = {
+    .name              = "g723_1",
+    .long_name         = NULL_IF_CONFIG_SMALL("raw G.723.1"),
+    .mime_type         = "audio/g723",
+    .extensions        = "tco,rco",
+    .audio_codec       = AV_CODEC_ID_G723_1,
+    .video_codec       = AV_CODEC_ID_NONE,
+    .write_packet      = ff_raw_write_packet,
+    .flags= AVFMT_NOTIMESTAMPS,
+};
+#endif
+
 #if CONFIG_H261_MUXER
 AVOutputFormat ff_h261_muxer = {
     .name              = "h261",
@@ -244,18 +257,6 @@
 };
 #endif
 
-#if CONFIG_SRT_MUXER
-AVOutputFormat ff_srt_muxer = {
-    .name              = "srt",
-    .long_name         = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
-    .mime_type         = "application/x-subrip",
-    .extensions        = "srt",
-    .write_packet      = ff_raw_write_packet,
-    .flags             = AVFMT_NOTIMESTAMPS,
-    .subtitle_codec    = AV_CODEC_ID_SRT,
-};
-#endif
-
 #if CONFIG_TRUEHD_MUXER
 AVOutputFormat ff_truehd_muxer = {
     .name              = "truehd",
diff --git a/libavformat/rawenc.h b/libavformat/rawenc.h
index daa5489..b552309 100644
--- a/libavformat/rawenc.h
+++ b/libavformat/rawenc.h
@@ -2,20 +2,20 @@
  * RAW muxers
  * Copyright (C) 2007  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rawvideodec.c b/libavformat/rawvideodec.c
index f71ea0a..2828c8d 100644
--- a/libavformat/rawvideodec.c
+++ b/libavformat/rawvideodec.c
@@ -2,20 +2,20 @@
  * RAW video demuxer
  * Copyright (c) 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rdt.c b/libavformat/rdt.c
index 35540de..6404a5d 100644
--- a/libavformat/rdt.c
+++ b/libavformat/rdt.c
@@ -2,20 +2,20 @@
  * Realmedia RTSP protocol (RDT) support.
  * Copyright (c) 2007 Ronald S. Bultje
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -176,7 +176,7 @@
         size = rdt->mlti_data_size;
         avio_seek(&pb, 0, SEEK_SET);
     }
-    if (ff_rm_read_mdpr_codecdata(rdt->rmctx, &pb, st, rdt->rmst[st->index], size) < 0)
+    if (ff_rm_read_mdpr_codecdata(rdt->rmctx, &pb, st, rdt->rmst[st->index], size, NULL) < 0)
         return -1;
 
     return 0;
diff --git a/libavformat/rdt.h b/libavformat/rdt.h
index a393299..c2ec94b 100644
--- a/libavformat/rdt.h
+++ b/libavformat/rdt.h
@@ -2,20 +2,20 @@
  * Realmedia RTSP (RDT) definitions
  * Copyright (c) 2007 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/realtextdec.c b/libavformat/realtextdec.c
new file mode 100644
index 0000000..cc7c184
--- /dev/null
+++ b/libavformat/realtextdec.c
@@ -0,0 +1,145 @@
+/*
+ * 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
+ * RealText subtitle demuxer
+ * @see http://service.real.com/help/library/guides/ProductionGuide/prodguide/htmfiles/realtext.htm
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+#include "libavutil/intreadwrite.h"
+
+typedef struct {
+    FFDemuxSubtitlesQueue q;
+} RealTextContext;
+
+static int realtext_probe(AVProbeData *p)
+{
+    const unsigned char *ptr = p->buf;
+
+    if (AV_RB24(ptr) == 0xEFBBBF)
+        ptr += 3;  /* skip UTF-8 BOM */
+    return !av_strncasecmp(ptr, "<window", 7) ? AVPROBE_SCORE_MAX/2 : 0;
+}
+
+static int read_ts(const char *s)
+{
+    int hh, mm, ss, ms;
+
+    if (sscanf(s, "%u:%u:%u.%u", &hh, &mm, &ss, &ms) == 4) return (hh*3600 + mm*60 + ss) * 100 + ms;
+    if (sscanf(s, "%u:%u:%u"   , &hh, &mm, &ss     ) == 3) return (hh*3600 + mm*60 + ss) * 100;
+    if (sscanf(s,    "%u:%u.%u",      &mm, &ss, &ms) == 3) return (          mm*60 + ss) * 100 + ms;
+    if (sscanf(s,    "%u:%u"   ,      &mm, &ss     ) == 2) return (          mm*60 + ss) * 100;
+    if (sscanf(s,       "%u.%u",           &ss, &ms) == 2) return (                  ss) * 100 + ms;
+    return strtol(s, NULL, 10) * 100;
+}
+
+static int realtext_read_header(AVFormatContext *s)
+{
+    RealTextContext *rt = s->priv_data;
+    AVStream *st = avformat_new_stream(s, NULL);
+    AVBPrint buf;
+    char c = 0;
+    int res = 0, duration = read_ts("60"); // default duration is 60 seconds
+
+    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_REALTEXT;
+
+    av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
+
+    while (!url_feof(s->pb)) {
+        AVPacket *sub;
+        const int64_t pos = avio_tell(s->pb) - (c != 0);
+        int n = ff_smil_extract_next_chunk(s->pb, &buf, &c);
+
+        if (n == 0)
+            break;
+
+        if (!av_strncasecmp(buf.str, "<window", 7)) {
+            /* save header to extradata */
+            const char *p = ff_smil_get_attr_ptr(buf.str, "duration");
+
+            if (p)
+                duration = read_ts(p);
+            st->codec->extradata = av_strdup(buf.str);
+            if (!st->codec->extradata) {
+                res = AVERROR(ENOMEM);
+                goto end;
+            }
+            st->codec->extradata_size = buf.len + 1;
+        } else {
+            /* if we just read a <time> tag, introduce a new event, otherwise merge
+             * with the previous one */
+            int merge = !av_strncasecmp(buf.str, "<time", 5) ? 0 : 1;
+            sub = ff_subtitles_queue_insert(&rt->q, buf.str, buf.len, merge);
+            if (!sub) {
+                res = AVERROR(ENOMEM);
+                goto end;
+            }
+            if (!merge) {
+                const char *begin = ff_smil_get_attr_ptr(buf.str, "begin");
+                const char *end   = ff_smil_get_attr_ptr(buf.str, "end");
+
+                sub->pos      = pos;
+                sub->pts      = begin ? read_ts(begin) : 0;
+                sub->duration = end ? (read_ts(end) - sub->pts) : duration;
+            }
+        }
+        av_bprint_clear(&buf);
+    }
+    ff_subtitles_queue_finalize(&rt->q);
+
+end:
+    av_bprint_finalize(&buf, NULL);
+    return res;
+}
+
+static int realtext_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    RealTextContext *rt = s->priv_data;
+    return ff_subtitles_queue_read_packet(&rt->q, pkt);
+}
+
+static int realtext_read_close(AVFormatContext *s)
+{
+    RealTextContext *rt = s->priv_data;
+    ff_subtitles_queue_clean(&rt->q);
+    return 0;
+}
+
+AVInputFormat ff_realtext_demuxer = {
+    .name           = "realtext",
+    .long_name      = NULL_IF_CONFIG_SMALL("RealText subtitle format"),
+    .priv_data_size = sizeof(RealTextContext),
+    .read_probe     = realtext_probe,
+    .read_header    = realtext_read_header,
+    .read_packet    = realtext_read_packet,
+    .read_close     = realtext_read_close,
+    .flags          = AVFMT_GENERIC_INDEX,
+    .extensions     = "rt",
+};
diff --git a/libavformat/riff.c b/libavformat/riff.c
index 2539b23..1c34112 100644
--- a/libavformat/riff.c
+++ b/libavformat/riff.c
@@ -2,20 +2,20 @@
  * RIFF codec tags
  * Copyright (c) 2000 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,9 +25,13 @@
 #include "avio_internal.h"
 #include "riff.h"
 #include "libavcodec/bytestream.h"
+#include "libavutil/avassert.h"
 
 /* Note: when encoding, the first matching tag is used, so order is
-   important if multiple tags possible for a given codec. */
+   important if multiple tags possible for a given codec.
+   Note also that this list is used for more than just riff, other
+   files use it as well.
+*/
 const AVCodecTag ff_codec_bmp_tags[] = {
     { AV_CODEC_ID_H264,         MKTAG('H', '2', '6', '4') },
     { AV_CODEC_ID_H264,         MKTAG('h', '2', '6', '4') },
@@ -36,6 +40,7 @@
     { AV_CODEC_ID_H264,         MKTAG('a', 'v', 'c', '1') },
     { AV_CODEC_ID_H264,         MKTAG('D', 'A', 'V', 'C') },
     { AV_CODEC_ID_H264,         MKTAG('V', 'S', 'S', 'H') },
+    { AV_CODEC_ID_H264,         MKTAG('Q', '2', '6', '4') }, /* QNAP surveillance system */
     { AV_CODEC_ID_H263,         MKTAG('H', '2', '6', '3') },
     { AV_CODEC_ID_H263,         MKTAG('X', '2', '6', '3') },
     { AV_CODEC_ID_H263,         MKTAG('T', '2', '6', '3') },
@@ -46,8 +51,7 @@
     { AV_CODEC_ID_H263P,        MKTAG('H', '2', '6', '3') },
     { AV_CODEC_ID_H263I,        MKTAG('I', '2', '6', '3') }, /* intel h263 */
     { AV_CODEC_ID_H261,         MKTAG('H', '2', '6', '1') },
-    { AV_CODEC_ID_H263P,        MKTAG('U', '2', '6', '3') },
-    { AV_CODEC_ID_H263P,        MKTAG('v', 'i', 'v', '1') },
+    { AV_CODEC_ID_H263,         MKTAG('U', '2', '6', '3') },
     { AV_CODEC_ID_MPEG4,        MKTAG('F', 'M', 'P', '4') },
     { AV_CODEC_ID_MPEG4,        MKTAG('D', 'I', 'V', 'X') },
     { AV_CODEC_ID_MPEG4,        MKTAG('D', 'X', '5', '0') },
@@ -86,8 +90,11 @@
     { AV_CODEC_ID_MPEG4,        MKTAG('U', 'L', 'D', 'X') },
     { AV_CODEC_ID_MPEG4,        MKTAG('G', 'E', 'O', 'V') },
     { AV_CODEC_ID_MPEG4,        MKTAG('S', 'I', 'P', 'P') }, /* Samsung SHR-6040 */
+    { AV_CODEC_ID_MPEG4,        MKTAG('S', 'M', '4', 'V') },
     { AV_CODEC_ID_MPEG4,        MKTAG('X', 'V', 'I', 'X') },
     { AV_CODEC_ID_MPEG4,        MKTAG('D', 'r', 'e', 'X') },
+    { AV_CODEC_ID_MPEG4,        MKTAG('Q', 'M', 'P', '4') }, /* QNAP Systems */
+    { AV_CODEC_ID_MPEG4,        MKTAG('P', 'L', 'V', '1') }, /* Pelco DVR MPEG-4 */
     { AV_CODEC_ID_MSMPEG4V3,    MKTAG('M', 'P', '4', '3') },
     { AV_CODEC_ID_MSMPEG4V3,    MKTAG('D', 'I', 'V', '3') },
     { AV_CODEC_ID_MSMPEG4V3,    MKTAG('M', 'P', 'G', '3') },
@@ -116,6 +123,10 @@
     { AV_CODEC_ID_DVVIDEO,      MKTAG('d', 'v', 'c', ' ') },
     { AV_CODEC_ID_DVVIDEO,      MKTAG('d', 'v', 'c', 's') },
     { AV_CODEC_ID_DVVIDEO,      MKTAG('d', 'v', 'h', '1') },
+    { AV_CODEC_ID_DVVIDEO,      MKTAG('d', 'v', 'i', 's') },
+    { AV_CODEC_ID_DVVIDEO,      MKTAG('p', 'd', 'v', 'c') },
+    { AV_CODEC_ID_DVVIDEO,      MKTAG('S', 'L', '2', '5') },
+    { AV_CODEC_ID_DVVIDEO,      MKTAG('S', 'L', 'D', 'V') },
     { AV_CODEC_ID_MPEG1VIDEO,   MKTAG('m', 'p', 'g', '1') },
     { AV_CODEC_ID_MPEG1VIDEO,   MKTAG('m', 'p', 'g', '2') },
     { AV_CODEC_ID_MPEG2VIDEO,   MKTAG('m', 'p', 'g', '2') },
@@ -133,6 +144,8 @@
     { AV_CODEC_ID_MPEG2VIDEO,   MKTAG('E', 'M', '2', 'V') },
     { AV_CODEC_ID_MPEG2VIDEO,   MKTAG('M', '7', '0', '1') }, /* Matrox MPEG2 intra-only */
     { AV_CODEC_ID_MPEG2VIDEO,   MKTAG('m', 'p', 'g', 'v') },
+    { AV_CODEC_ID_MPEG1VIDEO,   MKTAG('B', 'W', '1', '0') },
+    { AV_CODEC_ID_MPEG1VIDEO,   MKTAG('X', 'M', 'P', 'G') }, /* Xing MPEG intra only */
     { AV_CODEC_ID_MJPEG,        MKTAG('M', 'J', 'P', 'G') },
     { AV_CODEC_ID_MJPEG,        MKTAG('L', 'J', 'P', 'G') },
     { AV_CODEC_ID_MJPEG,        MKTAG('d', 'm', 'b', '1') },
@@ -144,7 +157,7 @@
     { AV_CODEC_ID_MJPEG,        MKTAG('M', 'J', 'L', 'S') }, /* JPEG-LS custom FOURCC for avi - decoder */
     { AV_CODEC_ID_MJPEG,        MKTAG('j', 'p', 'e', 'g') },
     { AV_CODEC_ID_MJPEG,        MKTAG('I', 'J', 'P', 'G') },
-    { AV_CODEC_ID_MJPEG,        MKTAG('A', 'V', 'R', 'n') },
+    { AV_CODEC_ID_AVRN,         MKTAG('A', 'V', 'R', 'n') },
     { AV_CODEC_ID_MJPEG,        MKTAG('A', 'C', 'D', 'V') },
     { AV_CODEC_ID_MJPEG,        MKTAG('Q', 'I', 'V', 'G') },
     { AV_CODEC_ID_MJPEG,        MKTAG('S', 'L', 'M', 'J') }, /* SL M-JPEG */
@@ -193,11 +206,16 @@
     { AV_CODEC_ID_RAWVIDEO,     MKTAG('Y', 'U', 'V', '9') },
     { AV_CODEC_ID_RAWVIDEO,     MKTAG('Y', 'V', 'U', '9') },
     { AV_CODEC_ID_RAWVIDEO,     MKTAG('a', 'u', 'v', '2') },
+    { AV_CODEC_ID_RAWVIDEO,     MKTAG('Y', 'V', 'Y', 'U') },
     { AV_CODEC_ID_FRWU,         MKTAG('F', 'R', 'W', 'U') },
     { AV_CODEC_ID_R10K,         MKTAG('R', '1', '0', 'k') },
     { AV_CODEC_ID_R210,         MKTAG('r', '2', '1', '0') },
     { AV_CODEC_ID_V210,         MKTAG('v', '2', '1', '0') },
+    { AV_CODEC_ID_V308,         MKTAG('v', '3', '0', '8') },
+    { AV_CODEC_ID_V408,         MKTAG('v', '4', '0', '8') },
+    { AV_CODEC_ID_AYUV,         MKTAG('A', 'Y', 'U', 'V') },
     { AV_CODEC_ID_V410,         MKTAG('v', '4', '1', '0') },
+    { AV_CODEC_ID_YUV4,         MKTAG('y', 'u', 'v', '4') },
     { AV_CODEC_ID_INDEO3,       MKTAG('I', 'V', '3', '1') },
     { AV_CODEC_ID_INDEO3,       MKTAG('I', 'V', '3', '2') },
     { AV_CODEC_ID_INDEO4,       MKTAG('I', 'V', '4', '1') },
@@ -234,6 +252,7 @@
     { AV_CODEC_ID_SNOW,         MKTAG('S', 'N', 'O', 'W') },
     { AV_CODEC_ID_4XM,          MKTAG('4', 'X', 'M', 'V') },
     { AV_CODEC_ID_FLV1,         MKTAG('F', 'L', 'V', '1') },
+    { AV_CODEC_ID_FLV1,         MKTAG('S', '2', '6', '3') },
     { AV_CODEC_ID_FLASHSV,      MKTAG('F', 'S', 'V', '1') },
     { AV_CODEC_ID_SVQ1,         MKTAG('s', 'v', 'q', '1') },
     { AV_CODEC_ID_TSCC,         MKTAG('t', 's', 'c', 'c') },
@@ -249,6 +268,8 @@
     { AV_CODEC_ID_VC1IMAGE,     MKTAG('W', 'V', 'P', '2') },
     { AV_CODEC_ID_LOCO,         MKTAG('L', 'O', 'C', 'O') },
     { AV_CODEC_ID_WNV1,         MKTAG('W', 'N', 'V', '1') },
+    { AV_CODEC_ID_WNV1,         MKTAG('Y', 'U', 'V', '8') },
+    { AV_CODEC_ID_AASC,         MKTAG('A', 'A', 'S', '4') },
     { AV_CODEC_ID_AASC,         MKTAG('A', 'A', 'S', 'C') },
     { AV_CODEC_ID_INDEO2,       MKTAG('R', 'T', '2', '1') },
     { AV_CODEC_ID_FRAPS,        MKTAG('F', 'P', 'S', '1') },
@@ -262,6 +283,7 @@
     { AV_CODEC_ID_JPEG2000,     MKTAG('M', 'J', '2', 'C') },
     { AV_CODEC_ID_JPEG2000,     MKTAG('L', 'J', '2', 'C') },
     { AV_CODEC_ID_JPEG2000,     MKTAG('L', 'J', '2', 'K') },
+    { AV_CODEC_ID_JPEG2000,     MKTAG('I', 'P', 'J', '2') },
     { AV_CODEC_ID_VMNC,         MKTAG('V', 'M', 'n', 'c') },
     { AV_CODEC_ID_TARGA,        MKTAG('t', 'g', 'a', ' ') },
     { AV_CODEC_ID_PNG,          MKTAG('M', 'P', 'N', 'G') },
@@ -277,13 +299,21 @@
     { AV_CODEC_ID_DPX,          MKTAG('d', 'p', 'x', ' ') },
     { AV_CODEC_ID_KGV1,         MKTAG('K', 'G', 'V', '1') },
     { AV_CODEC_ID_LAGARITH,     MKTAG('L', 'A', 'G', 'S') },
+    { AV_CODEC_ID_G2M,          MKTAG('G', '2', 'M', '2') },
+    { AV_CODEC_ID_G2M,          MKTAG('G', '2', 'M', '3') },
+    { AV_CODEC_ID_G2M,          MKTAG('G', '2', 'M', '4') },
+    { AV_CODEC_ID_AMV,          MKTAG('A', 'M', 'V', 'F') },
     { AV_CODEC_ID_UTVIDEO,      MKTAG('U', 'L', 'R', 'A') },
     { AV_CODEC_ID_UTVIDEO,      MKTAG('U', 'L', 'R', 'G') },
     { AV_CODEC_ID_UTVIDEO,      MKTAG('U', 'L', 'Y', '0') },
     { AV_CODEC_ID_UTVIDEO,      MKTAG('U', 'L', 'Y', '2') },
     { AV_CODEC_ID_VBLE,         MKTAG('V', 'B', 'L', 'E') },
+    { AV_CODEC_ID_ESCAPE130,    MKTAG('E', '1', '3', '0') },
     { AV_CODEC_ID_DXTORY,       MKTAG('x', 't', 'o', 'r') },
     { AV_CODEC_ID_ZEROCODEC,    MKTAG('Z', 'E', 'C', 'O') },
+    { AV_CODEC_ID_Y41P,         MKTAG('Y', '4', '1', 'P') },
+    { AV_CODEC_ID_FLIC,         MKTAG('A', 'F', 'L', 'C') },
+    { AV_CODEC_ID_EXR,          MKTAG('e', 'x', 'r', ' ') },
     { AV_CODEC_ID_MSS1,         MKTAG('M', 'S', 'S', '1') },
     { AV_CODEC_ID_MSA1,         MKTAG('M', 'S', 'A', '1') },
     { AV_CODEC_ID_TSCC2,        MKTAG('T', 'S', 'C', '2') },
@@ -310,6 +340,8 @@
     { AV_CODEC_ID_ADPCM_YAMAHA,    0x0020 },
     { AV_CODEC_ID_TRUESPEECH,      0x0022 },
     { AV_CODEC_ID_GSM_MS,          0x0031 },
+    { AV_CODEC_ID_AMR_NB,          0x0038 },  /* rogue format number */
+    { AV_CODEC_ID_G723_1,          0x0042 },
     { AV_CODEC_ID_ADPCM_G726,      0x0045 },
     { AV_CODEC_ID_MP2,             0x0050 },
     { AV_CODEC_ID_MP3,             0x0055 },
@@ -336,6 +368,8 @@
     { AV_CODEC_ID_AAC_LATM,        0x1602 },
     { AV_CODEC_ID_AC3,             0x2000 },
     { AV_CODEC_ID_DTS,             0x2001 },
+    { AV_CODEC_ID_SONIC,           0x2048 },
+    { AV_CODEC_ID_SONIC_LS,        0x2048 },
     { AV_CODEC_ID_PCM_MULAW,       0x6c75 },
     { AV_CODEC_ID_AAC,             0x706d },
     { AV_CODEC_ID_AAC,             0x4143 },
@@ -352,6 +386,14 @@
     { AV_CODEC_ID_NONE,      0 },
 };
 
+const AVCodecGuid ff_codec_wav_guids[] = {
+    {AV_CODEC_ID_AC3,        {0x2C,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA}},
+    {AV_CODEC_ID_ATRAC3P,    {0xBF,0xAA,0x23,0xE9,0x58,0xCB,0x71,0x44,0xA1,0x19,0xFF,0xFA,0x01,0xE4,0xCE,0x62}},
+    {AV_CODEC_ID_EAC3,       {0xAF,0x87,0xFB,0xA7,0x02,0x2D,0xFB,0x42,0xA4,0xD4,0x05,0xCD,0x93,0x84,0x3B,0xDD}},
+    {AV_CODEC_ID_MP2,        {0x2B,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA}},
+    {AV_CODEC_ID_NONE}
+};
+
 const AVMetadataConv ff_riff_info_conv[] = {
     { "IART", "artist"    },
     { "ICMT", "comment"   },
@@ -363,6 +405,7 @@
     { "IPRD", "album"     },
     { "IPRT", "track"     },
     { "ISFT", "encoder"   },
+    { "ISMP", "timecode"  },
     { "ITCH", "encoded_by"},
     { 0 },
 };
@@ -370,7 +413,7 @@
 const char ff_riff_tags[][5] = {
     "IARL", "IART", "ICMS", "ICMT", "ICOP", "ICRD", "ICRP", "IDIM", "IDPI",
     "IENG", "IGNR", "IKEY", "ILGT", "ILNG", "IMED", "INAM", "IPLT", "IPRD",
-    "IPRT", "ISBJ", "ISFT", "ISHP", "ISRC", "ISRF", "ITCH",
+    "IPRT", "ISBJ", "ISFT", "ISHP", "ISMP", "ISRC", "ISRF", "ITCH",
     {0}
 };
 
@@ -424,7 +467,11 @@
     }
     avio_wl16(pb, enc->channels);
     avio_wl32(pb, enc->sample_rate);
-    if (enc->codec_id == AV_CODEC_ID_MP2 || enc->codec_id == AV_CODEC_ID_MP3 || enc->codec_id == AV_CODEC_ID_GSM_MS) {
+    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) {
         bps = 0;
     } else {
         if (!(bps = av_get_bits_per_sample(enc->codec_id))) {
@@ -445,6 +492,10 @@
         //blkalign = 144 * enc->bit_rate/enc->sample_rate;
     } else if (enc->codec_id == AV_CODEC_ID_AC3) {
             blkalign = 3840; //maximum bytes per frame
+    } else if (enc->codec_id == AV_CODEC_ID_AAC) {
+            blkalign = 768 * enc->channels; //maximum bytes per frame
+    } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
+            blkalign = 24;
     } else if (enc->block_align != 0) { /* specified by the codec */
         blkalign = enc->block_align;
     } else
@@ -456,6 +507,8 @@
         enc->codec_id == AV_CODEC_ID_PCM_F64LE ||
         enc->codec_id == AV_CODEC_ID_PCM_S16LE) {
         bytespersec = enc->sample_rate * blkalign;
+    } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
+        bytespersec = 800;
     } else {
         bytespersec = enc->bit_rate / 8;
     }
@@ -479,6 +532,11 @@
         bytestream_put_le16(&riff_extradata, 16);                         /* fwHeadFlags */
         bytestream_put_le32(&riff_extradata, 0);                          /* dwPTSLow */
         bytestream_put_le32(&riff_extradata, 0);                          /* dwPTSHigh */
+    } else if (enc->codec_id == AV_CODEC_ID_G723_1) {
+        hdrsize += 20;
+        bytestream_put_le32(&riff_extradata, 0x9ace0002); /* extradata needed for msacm g723.1 codec */
+        bytestream_put_le32(&riff_extradata, 0xaea2f732);
+        bytestream_put_le16(&riff_extradata, 0xacde);
     } else if (enc->codec_id == AV_CODEC_ID_GSM_MS || enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
         hdrsize += 2;
         bytestream_put_le16(&riff_extradata, frame_size); /* wSamplesPerBlock */
@@ -520,7 +578,7 @@
     avio_wl16(pb, enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24); /* depth */
     /* compression type */
     avio_wl32(pb, enc->codec_tag);
-    avio_wl32(pb, enc->width * enc->height * 3);
+    avio_wl32(pb, (enc->width * enc->height * (enc->bits_per_coded_sample ? enc->bits_per_coded_sample : 24)+7) / 8);
     avio_wl32(pb, 0);
     avio_wl32(pb, 0);
     avio_wl32(pb, 0);
@@ -547,7 +605,6 @@
 
     id = avio_rl16(pb);
     codec->codec_type = AVMEDIA_TYPE_AUDIO;
-    codec->codec_tag = id;
     codec->channels = avio_rl16(pb);
     codec->sample_rate = avio_rl32(pb);
     codec->bit_rate = avio_rl32(pb) * 8;
@@ -556,15 +613,31 @@
         codec->bits_per_coded_sample = 8;
     }else
         codec->bits_per_coded_sample = avio_rl16(pb);
+    if (id == 0xFFFE) {
+        codec->codec_tag = 0;
+    } else {
+        codec->codec_tag = id;
+        codec->codec_id = ff_wav_codec_get_id(id, codec->bits_per_coded_sample);
+    }
     if (size >= 18) {  /* We're obviously dealing with WAVEFORMATEX */
         int cbSize = avio_rl16(pb); /* cbSize */
         size -= 18;
         cbSize = FFMIN(size, cbSize);
         if (cbSize >= 22 && id == 0xfffe) { /* WAVEFORMATEXTENSIBLE */
-            codec->bits_per_coded_sample = avio_rl16(pb);
+            ff_asf_guid subformat;
+            int bps = avio_rl16(pb);
+            if (bps)
+                codec->bits_per_coded_sample = bps;
             codec->channel_layout = avio_rl32(pb); /* dwChannelMask */
-            id = avio_rl32(pb); /* 4 first bytes of GUID */
-            avio_skip(pb, 12); /* skip end of GUID */
+            ff_get_guid(pb, &subformat);
+            if (!memcmp(subformat + 4, (const uint8_t[]){FF_MEDIASUBTYPE_BASE_GUID}, 12)) {
+                codec->codec_tag = AV_RL32(subformat);
+                codec->codec_id = ff_wav_codec_get_id(codec->codec_tag, codec->bits_per_coded_sample);
+            } else {
+                codec->codec_id = ff_codec_guid_get_id(ff_codec_wav_guids, subformat);
+                if (!codec->codec_id)
+                    av_log(codec, AV_LOG_WARNING, "unknown subformat:"FF_PRI_GUID"\n", FF_ARG_GUID(subformat));
+            }
             cbSize -= 22;
             size -= 22;
         }
@@ -582,7 +655,6 @@
         if (size > 0)
             avio_skip(pb, size);
     }
-    codec->codec_id = ff_wav_codec_get_id(id, codec->bits_per_coded_sample);
     if (codec->codec_id == AV_CODEC_ID_AAC_LATM) {
         /* channels and sample_rate values are those prior to applying SBR and/or PS */
         codec->channels    = 0;
@@ -616,10 +688,11 @@
     return id;
 }
 
-int ff_get_bmp_header(AVIOContext *pb, AVStream *st)
+int ff_get_bmp_header(AVIOContext *pb, AVStream *st, unsigned *esize)
 {
     int tag1;
-    avio_rl32(pb); /* size */
+    if(esize) *esize = avio_rl32(pb);
+    else               avio_rl32(pb);
     st->codec->width = avio_rl32(pb);
     st->codec->height = (int32_t)avio_rl32(pb);
     avio_rl16(pb); /* planes */
@@ -664,6 +737,23 @@
     *au_rate /= gcd;
 }
 
+void ff_get_guid(AVIOContext *s, ff_asf_guid *g)
+{
+    av_assert0(sizeof(*g) == 16); //compiler will optimize this out
+    if (avio_read(s, *g, sizeof(*g)) < (int)sizeof(*g))
+        memset(*g, 0, sizeof(*g));
+}
+
+enum AVCodecID ff_codec_guid_get_id(const AVCodecGuid *guids, ff_asf_guid guid)
+{
+    int i;
+    for (i = 0; guids[i].id != AV_CODEC_ID_NONE; i++) {
+        if (!ff_guidcmp(guids[i].guid, guid))
+            return guids[i].id;
+    }
+    return AV_CODEC_ID_NONE;
+}
+
 int ff_read_riff_info(AVFormatContext *s, int64_t size)
 {
     int64_t start, end, cur;
@@ -696,7 +786,7 @@
         AV_WL32(key, chunk_code);
 
         if (avio_read(pb, value, chunk_size) != chunk_size) {
-            av_free(value);
+            av_freep(&value);
             av_log(s, AV_LOG_ERROR, "premature end of file while reading INFO tag\n");
             return AVERROR_INVALIDDATA;
         }
diff --git a/libavformat/riff.h b/libavformat/riff.h
index 42a28d1..9126e40 100644
--- a/libavformat/riff.h
+++ b/libavformat/riff.h
@@ -2,20 +2,20 @@
  * RIFF codec tags
  * copyright (c) 2000 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -44,7 +44,7 @@
  * bits_per_encoded_sample fields. Does not read extradata.
  * @return codec tag
  */
-int ff_get_bmp_header(AVIOContext *pb, AVStream *st);
+int ff_get_bmp_header(AVIOContext *pb, AVStream *st, unsigned *esize);
 
 void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *tags, int for_asf);
 int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc);
@@ -58,6 +58,32 @@
 enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag);
 void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, int *au_ssize, int *au_scale);
 
+typedef uint8_t ff_asf_guid[16];
+
 int ff_read_riff_info(AVFormatContext *s, int64_t size);
 
+#define FF_PRI_GUID \
+    "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
+#define FF_ARG_GUID(g) \
+    g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]
+
+static av_always_inline int ff_guidcmp(const void *g1, const void *g2)
+{
+    return memcmp(g1, g2, sizeof(ff_asf_guid));
+}
+
+void ff_get_guid(AVIOContext *s, ff_asf_guid *g);
+
+typedef struct {
+    enum AVCodecID id;
+    ff_asf_guid guid;
+} AVCodecGuid;
+
+enum AVCodecID ff_codec_guid_get_id(const AVCodecGuid *guids, ff_asf_guid guid);
+
+extern const AVCodecGuid ff_codec_wav_guids[];
+
+#define FF_MEDIASUBTYPE_BASE_GUID \
+    0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71
+
 #endif /* AVFORMAT_RIFF_H */
diff --git a/libavformat/rl2.c b/libavformat/rl2.c
index ac0532f..73d6b27 100644
--- a/libavformat/rl2.c
+++ b/libavformat/rl2.c
@@ -2,20 +2,20 @@
  * RL2 Format Demuxer
  * Copyright (c) 2008 Sascha Sommer (saschasommer@freenet.de)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -136,6 +136,9 @@
 
     /** setup audio stream if present */
     if(sound_rate){
+        if(channels <= 0)
+            return AVERROR_INVALIDDATA;
+
         pts_num = def_sound_size;
         pts_den = rate;
 
diff --git a/libavformat/rm.c b/libavformat/rm.c
index 761be3f..0591a17 100644
--- a/libavformat/rm.c
+++ b/libavformat/rm.c
@@ -2,20 +2,20 @@
  * "Real" compatible muxer and demuxer common code.
  * Copyright (c) 2009  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rm.h b/libavformat/rm.h
index 9d104ad..b482c2f 100644
--- a/libavformat/rm.h
+++ b/libavformat/rm.h
@@ -2,20 +2,20 @@
  * "Real" compatible muxer and demuxer.
  * Copyright (c) 2000, 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -51,7 +51,7 @@
  */
 int ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb,
                                AVStream *st, RMStream *rst,
-                               int codec_data_size);
+                               int codec_data_size, const uint8_t *mime);
 
 /**
  * Parse one rm-stream packet from the input bytestream.
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
index eefd2c5..a69017d 100644
--- a/libavformat/rmdec.c
+++ b/libavformat/rmdec.c
@@ -2,20 +2,20 @@
  * "Real" compatible demuxer.
  * Copyright (c) 2000, 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -234,6 +234,7 @@
             }
             if ((ret = rm_read_extradata(pb, st->codec, codecdata_length)) < 0)
                 return ret;
+
             break;
         case AV_CODEC_ID_AAC:
             avio_rb16(pb); avio_r8(pb);
@@ -297,7 +298,7 @@
 
 int
 ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb,
-                           AVStream *st, RMStream *rst, int codec_data_size)
+                           AVStream *st, RMStream *rst, int codec_data_size, const uint8_t *mime)
 {
     unsigned int v;
     int size;
@@ -320,11 +321,38 @@
         st->codec->codec_tag  = AV_RL32(st->codec->extradata);
         st->codec->codec_id   = ff_codec_get_id(ff_rm_codec_tags,
                                                 st->codec->codec_tag);
+    } else if(mime && !strcmp(mime, "logical-fileinfo")){
+        int stream_count, rule_count, property_count, i;
+        ff_free_stream(s, st);
+        if (avio_rb16(pb) != 0) {
+            av_log(s, AV_LOG_WARNING, "Unsupported version\n");
+            goto skip;
+        }
+        stream_count = avio_rb16(pb);
+        avio_skip(pb, 6*stream_count);
+        rule_count = avio_rb16(pb);
+        avio_skip(pb, 2*rule_count);
+        property_count = avio_rb16(pb);
+        for(i=0; i<property_count; i++){
+            uint8_t name[128], val[128];
+            avio_rb32(pb);
+            if (avio_rb16(pb) != 0) {
+                av_log(s, AV_LOG_WARNING, "Unsupported Name value property version\n");
+                goto skip; //FIXME skip just this one
+            }
+            get_str8(pb, name, sizeof(name));
+            switch(avio_rb32(pb)) {
+            case 2: get_strl(pb, val, sizeof(val), avio_rb16(pb));
+                av_dict_set(&s->metadata, name, val, 0);
+                break;
+            default: avio_skip(pb, avio_rb16(pb));
+            }
+        }
     } else {
         int fps;
         if (avio_rl32(pb) != MKTAG('V', 'I', 'D', 'O')) {
         fail1:
-            av_log(st->codec, AV_LOG_ERROR, "Unsupported video codec\n");
+            av_log(s, AV_LOG_WARNING, "Unsupported stream type %08x\n", v);
             goto skip;
         }
         st->codec->codec_tag = avio_rl32(pb);
@@ -439,7 +467,7 @@
     int tag_size;
     unsigned int start_time, duration;
     unsigned int data_off = 0, indx_off = 0;
-    char buf[128];
+    char buf[128], mime[128];
     int flags = 0;
 
     tag = avio_rl32(pb);
@@ -454,7 +482,7 @@
     avio_skip(pb, tag_size - 8);
 
     for(;;) {
-        if (pb->eof_reached)
+        if (url_feof(pb))
             return -1;
         tag = avio_rl32(pb);
         tag_size = avio_rb32(pb);
@@ -476,7 +504,8 @@
             avio_rb32(pb); /* max packet size */
             avio_rb32(pb); /* avg packet size */
             avio_rb32(pb); /* nb packets */
-            avio_rb32(pb); /* duration */
+            duration = avio_rb32(pb); /* duration */
+            s->duration = av_rescale(duration, AV_TIME_BASE, 1000);
             avio_rb32(pb); /* preroll */
             indx_off = avio_rb32(pb); /* index offset */
             data_off = avio_rb32(pb); /* data offset */
@@ -500,12 +529,14 @@
             duration = avio_rb32(pb); /* duration */
             st->start_time = start_time;
             st->duration = duration;
+            if(duration>0)
+                s->duration = AV_NOPTS_VALUE;
             get_str8(pb, buf, sizeof(buf)); /* desc */
-            get_str8(pb, buf, sizeof(buf)); /* mimetype */
+            get_str8(pb, mime, sizeof(mime)); /* mimetype */
             st->codec->codec_type = AVMEDIA_TYPE_DATA;
             st->priv_data = ff_rm_alloc_rmstream();
             if (ff_rm_read_mdpr_codecdata(s, s->pb, st, st->priv_data,
-                                          avio_rb32(pb)) < 0)
+                                          avio_rb32(pb), mime) < 0)
                 return -1;
             break;
         case MKTAG('D', 'A', 'T', 'A'):
@@ -558,7 +589,7 @@
     AVStream *st;
     uint32_t state=0xFFFFFFFF;
 
-    while(!pb->eof_reached){
+    while(!url_feof(pb)){
         int len, num, i;
         *pos= avio_tell(pb) - 3;
         if(rm->remaining_len > 0){
@@ -894,7 +925,7 @@
                     st = s->streams[i];
             }
 
-            if(len<0 || s->pb->eof_reached)
+            if(len<0 || url_feof(s->pb))
                 return AVERROR(EIO);
 
             res = ff_rm_parse_packet (s, s->pb, st, st->priv_data, len, pkt,
@@ -950,7 +981,9 @@
     if(rm->old_format)
         return AV_NOPTS_VALUE;
 
-    avio_seek(s->pb, pos, SEEK_SET);
+    if (avio_seek(s->pb, pos, SEEK_SET) < 0)
+        return AV_NOPTS_VALUE;
+
     rm->remaining_len=0;
     for(;;){
         int seq=1;
diff --git a/libavformat/rmenc.c b/libavformat/rmenc.c
index ed1ba7c..6c05657 100644
--- a/libavformat/rmenc.c
+++ b/libavformat/rmenc.c
@@ -2,20 +2,20 @@
  * "Real" compatible muxer.
  * Copyright (c) 2000, 2001 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
@@ -309,6 +309,11 @@
     int n;
     AVCodecContext *codec;
 
+    if (s->nb_streams > 2) {
+        av_log(s, AV_LOG_ERROR, "At most 2 streams are currently supported for muxing in RM\n");
+        return AVERROR_PATCHWELCOME;
+    }
+
     for(n=0;n<s->nb_streams;n++) {
         s->streams[n]->id = n;
         codec = s->streams[n]->codec;
diff --git a/libavformat/rpl.c b/libavformat/rpl.c
index a5b1e6e..b790597 100644
--- a/libavformat/rpl.c
+++ b/libavformat/rpl.c
@@ -2,20 +2,20 @@
  * ARMovie/RPL demuxer
  * Copyright (c) 2007 Christian Ohm, 2008 Eli Friedman
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -58,7 +58,7 @@
             break;
         if (b == '\n') {
             line[i] = '\0';
-            return 0;
+            return url_feof(pb) ? -1 : 0;
         }
         line[i] = b;
     }
@@ -164,11 +164,9 @@
             // The header is wrong here, at least sometimes
             vst->codec->bits_per_coded_sample = 16;
             break;
-#if 0
         case 130:
             vst->codec->codec_id = AV_CODEC_ID_ESCAPE130;
             break;
-#endif
         default:
             av_log(s, AV_LOG_WARNING,
                    "RPL video format %i not supported yet!\n",
@@ -254,7 +252,7 @@
     // Read the index
     avio_seek(pb, chunk_catalog_offset, SEEK_SET);
     total_audio_size = 0;
-    for (i = 0; i < number_of_chunks; i++) {
+    for (i = 0; !error && i < number_of_chunks; i++) {
         int64_t offset, video_size, audio_size;
         error |= read_line(pb, line, sizeof(line));
         if (3 != sscanf(line, "%"PRId64" , %"PRId64" ; %"PRId64,
diff --git a/libavformat/rso.c b/libavformat/rso.c
index 4ce61e7..7d88f0f 100644
--- a/libavformat/rso.c
+++ b/libavformat/rso.c
@@ -2,20 +2,20 @@
  * RSO format common data
  * Copyright (c) 2010 Rafael Carre
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rso.h b/libavformat/rso.h
index e3e88ea..1f65dd9 100644
--- a/libavformat/rso.h
+++ b/libavformat/rso.h
@@ -2,20 +2,20 @@
  * RSO format common data
  * Copyright (c) 2010 Rafael Carre
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rsodec.c b/libavformat/rsodec.c
index f5bcebb..7a22217 100644
--- a/libavformat/rsodec.c
+++ b/libavformat/rsodec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2001 Fabrice Bellard (original AU code)
  * Copyright (c) 2010 Rafael Carre
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -80,11 +80,9 @@
     if (ret < 0)
         return ret;
 
+    pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
     pkt->stream_index = 0;
 
-    /* note: we need to modify the packet size here to handle the last packet */
-    pkt->size = ret;
-
     return 0;
 }
 
diff --git a/libavformat/rsoenc.c b/libavformat/rsoenc.c
index cc76f9a..ee679b6 100644
--- a/libavformat/rsoenc.c
+++ b/libavformat/rsoenc.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2001 Fabrice Bellard (original AU code)
  * Copyright (c) 2010 Rafael Carre
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtmp.h b/libavformat/rtmp.h
index b9c5f1e..7c9bb6d 100644
--- a/libavformat/rtmp.h
+++ b/libavformat/rtmp.h
@@ -2,20 +2,20 @@
  * RTMP definitions
  * Copyright (c) 2009 Kostya Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtmpcrypt.c b/libavformat/rtmpcrypt.c
index dfdd029..2312527 100644
--- a/libavformat/rtmpcrypt.c
+++ b/libavformat/rtmpcrypt.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2009-2010 Howard Chu
  * Copyright (c) 2012 Samuel Pitoiset
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtmpcrypt.h b/libavformat/rtmpcrypt.h
index 2799433..590a8c8 100644
--- a/libavformat/rtmpcrypt.h
+++ b/libavformat/rtmpcrypt.h
@@ -2,20 +2,20 @@
  * RTMPE encryption utilities
  * Copyright (c) 2012 Samuel Pitoiset
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtmpdh.c b/libavformat/rtmpdh.c
index 38c2f3d..7d6734d 100644
--- a/libavformat/rtmpdh.c
+++ b/libavformat/rtmpdh.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2009-2010 Howard Chu
  * Copyright (c) 2012 Samuel Pitoiset
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtmpdh.h b/libavformat/rtmpdh.h
index 5de8bde..cf262fc 100644
--- a/libavformat/rtmpdh.h
+++ b/libavformat/rtmpdh.h
@@ -2,20 +2,20 @@
  * RTMP Diffie-Hellmann utilities
  * Copyright (c) 2012 Samuel Pitoiset
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtmphttp.c b/libavformat/rtmphttp.c
index 80a983b..d21ac67 100644
--- a/libavformat/rtmphttp.c
+++ b/libavformat/rtmphttp.c
@@ -2,20 +2,20 @@
  * RTMP HTTP network protocol
  * Copyright (c) 2012 Samuel Pitoiset
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c
index f69ce82..b607d5b 100644
--- a/libavformat/rtmppkt.c
+++ b/libavformat/rtmppkt.c
@@ -2,20 +2,20 @@
  * RTMP input format
  * Copyright (c) 2009 Kostya Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtmppkt.h b/libavformat/rtmppkt.h
index 8932cac..7ed3113 100644
--- a/libavformat/rtmppkt.h
+++ b/libavformat/rtmppkt.h
@@ -2,20 +2,20 @@
  * RTMP packet utilities
  * Copyright (c) 2009 Kostya Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c
index 3ab2e57..dbe9870 100644
--- a/libavformat/rtmpproto.c
+++ b/libavformat/rtmpproto.c
@@ -2,20 +2,20 @@
  * RTMP network protocol
  * Copyright (c) 2009 Kostya Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -1135,7 +1135,7 @@
     for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++)
         tosend[i] = av_lfg_get(&rnd) >> 24;
 
-    if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
+    if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
         /* When the client wants to use RTMPE, we have to change the command
          * byte to 0x06 which means to use encrypted data and we have to set
          * the flash version to at least 9.0.115.0. */
@@ -1213,7 +1213,7 @@
         if (ret < 0)
             return ret;
 
-        if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
+        if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
             /* Compute the shared secret key sent by the server and initialize
              * the RC4 encryption. */
             if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
@@ -1243,7 +1243,7 @@
         if (ret < 0)
             return ret;
 
-        if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
+        if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
             /* Encrypt the signature to be send to the server. */
             ff_rtmpe_encrypt_sig(rt->stream, tosend +
                                  RTMP_HANDSHAKE_PACKET_SIZE - 32, digest,
@@ -1255,13 +1255,13 @@
                                RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
             return ret;
 
-        if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
+        if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
             /* Set RC4 keys for encryption and update the keystreams. */
             if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
                 return ret;
         }
     } else {
-        if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
+        if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
             /* Compute the shared secret key sent by the server and initialize
              * the RC4 encryption. */
             if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
@@ -1279,7 +1279,7 @@
                                RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
             return ret;
 
-        if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
+        if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
             /* Set RC4 keys for encryption and update the keystreams. */
             if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
                 return ret;
@@ -1946,7 +1946,7 @@
             }
         }
         rt->bytes_read += ret;
-        if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) {
+        if (rt->bytes_read - rt->last_bytes_read > rt->client_report_size) {
             av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
             if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
                 return ret;
diff --git a/libavformat/rtp.c b/libavformat/rtp.c
index 4314c46..f9e4447 100644
--- a/libavformat/rtp.c
+++ b/libavformat/rtp.c
@@ -2,20 +2,20 @@
  * RTP input/output format
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtp.h b/libavformat/rtp.h
index b01caeb..fa3e1fa 100644
--- a/libavformat/rtp.h
+++ b/libavformat/rtp.h
@@ -2,20 +2,20 @@
  * RTP definitions
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #ifndef AVFORMAT_RTP_H
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index dac367d..a90f005 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -2,20 +2,20 @@
  * RTP input format
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -785,7 +785,7 @@
     int value_size = strlen(p) + 1;
 
     if (!(value = av_malloc(value_size))) {
-        av_log(stream, AV_LOG_ERROR, "Failed to allocate data for FMTP.");
+        av_log(stream, AV_LOG_ERROR, "Failed to allocate data for FMTP.\n");
         return AVERROR(ENOMEM);
     }
 
diff --git a/libavformat/rtpdec.h b/libavformat/rtpdec.h
index 7f14aa2..3d70190 100644
--- a/libavformat/rtpdec.h
+++ b/libavformat/rtpdec.h
@@ -3,20 +3,20 @@
  * Copyright (c) 2002 Fabrice Bellard
  * Copyright (c) 2006 Ryan Martell <rdm4@martellventures.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #ifndef AVFORMAT_RTPDEC_H
diff --git a/libavformat/rtpdec_amr.c b/libavformat/rtpdec_amr.c
index cc43e31..6051dce 100644
--- a/libavformat/rtpdec_amr.c
+++ b/libavformat/rtpdec_amr.c
@@ -2,20 +2,20 @@
  * RTP AMR Depacketizer, RFC 3267
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpdec_asf.c b/libavformat/rtpdec_asf.c
index 7c13b96..e37fde7 100644
--- a/libavformat/rtpdec_asf.c
+++ b/libavformat/rtpdec_asf.c
@@ -2,20 +2,20 @@
  * Microsoft RTP/ASF support.
  * Copyright (c) 2008 Ronald S. Bultje
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpdec_formats.h b/libavformat/rtpdec_formats.h
index c538b93..471888b 100644
--- a/libavformat/rtpdec_formats.h
+++ b/libavformat/rtpdec_formats.h
@@ -2,20 +2,20 @@
  * RTP depacketizer declarations
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpdec_g726.c b/libavformat/rtpdec_g726.c
index adb4ab3..ec37f09 100644
--- a/libavformat/rtpdec_g726.c
+++ b/libavformat/rtpdec_g726.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2011 Miroslav Slugeň <Thunder.m@seznam.cz>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpdec_h263.c b/libavformat/rtpdec_h263.c
index 78773b9..e604dc1 100644
--- a/libavformat/rtpdec_h263.c
+++ b/libavformat/rtpdec_h263.c
@@ -2,20 +2,20 @@
  * RTP H.263 Depacketizer, RFC 4629
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpdec_h264.c b/libavformat/rtpdec_h264.c
index 7408b43..083f8e8 100644
--- a/libavformat/rtpdec_h264.c
+++ b/libavformat/rtpdec_h264.c
@@ -2,20 +2,20 @@
  * RTP H264 Protocol (RFC3984)
  * Copyright (c) 2006 Ryan Martell
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpdec_ilbc.c b/libavformat/rtpdec_ilbc.c
index 2e99734..2bd8614 100644
--- a/libavformat/rtpdec_ilbc.c
+++ b/libavformat/rtpdec_ilbc.c
@@ -2,20 +2,20 @@
  * RTP iLBC Depacketizer, RFC 3952
  * Copyright (c) 2012 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c
index 944758d..fb68de9 100644
--- a/libavformat/rtpdec_jpeg.c
+++ b/libavformat/rtpdec_jpeg.c
@@ -2,20 +2,20 @@
  * RTP JPEG-compressed Video Depacketizer, RFC 2435
  * Copyright (c) 2012 Samuel Pitoiset
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpdec_latm.c b/libavformat/rtpdec_latm.c
index 3fa0468..2ea141b 100644
--- a/libavformat/rtpdec_latm.c
+++ b/libavformat/rtpdec_latm.c
@@ -2,20 +2,20 @@
  * RTP Depacketization of MP4A-LATM, RFC 3016
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c
index cc92c88..a647169 100644
--- a/libavformat/rtpdec_mpeg4.c
+++ b/libavformat/rtpdec_mpeg4.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2010 Fabrice Bellard
  *                    Romain Degez
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -130,7 +130,7 @@
 
     init_get_bits(&getbitcontext, buf, data->au_headers_length_bytes * 8);
 
-    /* XXX: Wrong if optionnal additional sections are present (cts, dts etc...) */
+    /* XXX: Wrong if optional additional sections are present (cts, dts etc...) */
     au_header_size = data->sizelength + data->indexlength;
     if (au_header_size <= 0 || (au_headers_length % au_header_size != 0))
         return -1;
diff --git a/libavformat/rtpdec_qcelp.c b/libavformat/rtpdec_qcelp.c
index 56f3e17..7e1d0b7 100644
--- a/libavformat/rtpdec_qcelp.c
+++ b/libavformat/rtpdec_qcelp.c
@@ -2,20 +2,20 @@
  * RTP Depacketization of QCELP/PureVoice, RFC 2658
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpdec_qdm2.c b/libavformat/rtpdec_qdm2.c
index a2ce510..3a8ffd5 100644
--- a/libavformat/rtpdec_qdm2.c
+++ b/libavformat/rtpdec_qdm2.c
@@ -2,20 +2,20 @@
  * QDesign Music 2 (QDM2) payload for RTP
  * Copyright (c) 2010 Ronald S. Bultje
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,6 +26,7 @@
  */
 
 #include <string.h>
+#include "libavutil/avassert.h"
 #include "libavutil/intreadwrite.h"
 #include "libavcodec/avcodec.h"
 #include "rtp.h"
@@ -193,7 +194,7 @@
     for (n = 0; n < 0x80; n++)
         if (qdm->len[n] > 0)
             break;
-    assert(n < 0x80);
+    av_assert0(n < 0x80);
 
     if ((res = av_new_packet(pkt, qdm->block_size)) < 0)
         return res;
diff --git a/libavformat/rtpdec_qt.c b/libavformat/rtpdec_qt.c
index 5dd1af1..4decdca 100644
--- a/libavformat/rtpdec_qt.c
+++ b/libavformat/rtpdec_qt.c
@@ -2,20 +2,20 @@
  * RTP/Quicktime support.
  * Copyright (c) 2009 Ronald S. Bultje
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpdec_svq3.c b/libavformat/rtpdec_svq3.c
index bfc602e..99c4c52 100644
--- a/libavformat/rtpdec_svq3.c
+++ b/libavformat/rtpdec_svq3.c
@@ -2,20 +2,20 @@
  * Sorenson-3 (SVQ3/SV3V) payload for RTP
  * Copyright (c) 2010 Ronald S. Bultje
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpdec_vp8.c b/libavformat/rtpdec_vp8.c
index a52be4b..aef5f78 100644
--- a/libavformat/rtpdec_vp8.c
+++ b/libavformat/rtpdec_vp8.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2010 Josh Allmann
  * Copyright (c) 2012 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpdec_xiph.c b/libavformat/rtpdec_xiph.c
index dc739ee..ae10c78 100644
--- a/libavformat/rtpdec_xiph.c
+++ b/libavformat/rtpdec_xiph.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2009 Colin McQuillian
  * Copyright (c) 2010 Josh Allmann
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -27,12 +27,11 @@
  * @author Josh Allmann <joshua.allmann@gmail.com>
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/avstring.h"
 #include "libavutil/base64.h"
 #include "libavcodec/bytestream.h"
 
-#include <assert.h>
-
 #include "rtpdec.h"
 #include "rtpdec_formats.h"
 
@@ -183,7 +182,7 @@
         data->timestamp = *timestamp;
 
     } else {
-        assert(fragmented < 4);
+        av_assert1(fragmented < 4);
         if (data->timestamp != *timestamp) {
             // skip if fragmented timestamp is incorrect;
             // a start packet has been lost somewhere
diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c
index b17c465..3a5bbeb 100644
--- a/libavformat/rtpenc.c
+++ b/libavformat/rtpenc.c
@@ -2,20 +2,20 @@
  * RTP output format
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -96,7 +96,7 @@
     }
     st = s1->streams[0];
     if (!is_supported(st->codec->codec_id)) {
-        av_log(s1, AV_LOG_ERROR, "Unsupported codec %x\n", st->codec->codec_id);
+        av_log(s1, AV_LOG_ERROR, "Unsupported codec %s\n", avcodec_get_name(st->codec->codec_id));
 
         return -1;
     }
diff --git a/libavformat/rtpenc.h b/libavformat/rtpenc.h
index 5351b45..bc523b4 100644
--- a/libavformat/rtpenc.h
+++ b/libavformat/rtpenc.h
@@ -2,20 +2,20 @@
  * RTP muxer definitions
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #ifndef AVFORMAT_RTPENC_H
@@ -89,7 +89,7 @@
 void ff_rtp_send_vp8(AVFormatContext *s1, const uint8_t *buff, int size);
 void ff_rtp_send_jpeg(AVFormatContext *s1, const uint8_t *buff, int size);
 
-const uint8_t *ff_h263_find_resync_marker_reverse(const uint8_t *restrict start,
-                                                  const uint8_t *restrict end);
+const uint8_t *ff_h263_find_resync_marker_reverse(const uint8_t *av_restrict start,
+                                                  const uint8_t *av_restrict end);
 
 #endif /* AVFORMAT_RTPENC_H */
diff --git a/libavformat/rtpenc_aac.c b/libavformat/rtpenc_aac.c
index 86318df..e19b286 100644
--- a/libavformat/rtpenc_aac.c
+++ b/libavformat/rtpenc_aac.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2007 Luca Abeni
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpenc_amr.c b/libavformat/rtpenc_amr.c
index 73da8c8..bd1c197 100644
--- a/libavformat/rtpenc_amr.c
+++ b/libavformat/rtpenc_amr.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2007 Luca Abeni
  * Copyright (c) 2009 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c
index 3742099..c0f9530 100644
--- a/libavformat/rtpenc_chain.c
+++ b/libavformat/rtpenc_chain.c
@@ -2,20 +2,20 @@
  * RTP muxer chaining code
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -57,6 +57,7 @@
     rtpctx->max_delay = s->max_delay;
     /* Copy other stream parameters. */
     rtpctx->streams[0]->sample_aspect_ratio = st->sample_aspect_ratio;
+    rtpctx->flags |= s->flags & AVFMT_FLAG_MP4A_LATM;
 
     if (av_opt_get(s, "rtpflags", AV_OPT_SEARCH_CHILDREN, &rtpflags) >= 0)
         av_dict_set(&opts, "rtpflags", rtpflags, AV_DICT_DONT_STRDUP_VAL);
diff --git a/libavformat/rtpenc_chain.h b/libavformat/rtpenc_chain.h
index 66b9e4c..1ba3617 100644
--- a/libavformat/rtpenc_chain.h
+++ b/libavformat/rtpenc_chain.h
@@ -2,20 +2,20 @@
  * RTP muxer chaining code
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpenc_h263.c b/libavformat/rtpenc_h263.c
index 87f0bd7..9cea013 100644
--- a/libavformat/rtpenc_h263.c
+++ b/libavformat/rtpenc_h263.c
@@ -3,28 +3,28 @@
  * Copyright (c) 2009 Luca Abeni
  * Copyright (c) 2009 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "avformat.h"
 #include "rtpenc.h"
 
-const uint8_t *ff_h263_find_resync_marker_reverse(const uint8_t *restrict start,
-                                                  const uint8_t *restrict end)
+const uint8_t *ff_h263_find_resync_marker_reverse(const uint8_t *av_restrict start,
+                                                  const uint8_t *av_restrict end)
 {
     const uint8_t *p = end - 1;
     start += 1; /* Make sure we never return the original start. */
diff --git a/libavformat/rtpenc_h264.c b/libavformat/rtpenc_h264.c
index ac74074..68f4975 100644
--- a/libavformat/rtpenc_h264.c
+++ b/libavformat/rtpenc_h264.c
@@ -2,20 +2,20 @@
  * RTP packetization for H.264 (RFC3984)
  * Copyright (c) 2008 Luca Abeni
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpenc_jpeg.c b/libavformat/rtpenc_jpeg.c
index 04df658..7eb0e23 100644
--- a/libavformat/rtpenc_jpeg.c
+++ b/libavformat/rtpenc_jpeg.c
@@ -2,20 +2,20 @@
  * RTP JPEG-compressed video Packetizer, RFC 2435
  * Copyright (c) 2012 Samuel Pitoiset
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpenc_latm.c b/libavformat/rtpenc_latm.c
index 6467677..7535a0f 100644
--- a/libavformat/rtpenc_latm.c
+++ b/libavformat/rtpenc_latm.c
@@ -2,9 +2,9 @@
  * RTP Packetization of MPEG-4 Audio (RFC 3016)
  * Copyright (c) 2011 Juan Carlos Rodriguez <ing.juancarlosrodriguez@hotmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
diff --git a/libavformat/rtpenc_mpv.c b/libavformat/rtpenc_mpv.c
index 37dedc3..2708dd1 100644
--- a/libavformat/rtpenc_mpv.c
+++ b/libavformat/rtpenc_mpv.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2002 Fabrice Bellard
  * Copyright (c) 2007 Luca Abeni
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpenc_vp8.c b/libavformat/rtpenc_vp8.c
index 1730379..d16e676 100644
--- a/libavformat/rtpenc_vp8.c
+++ b/libavformat/rtpenc_vp8.c
@@ -2,20 +2,20 @@
  * RTP VP8 Packetizer
  * Copyright (c) 2010 Josh Allmann
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtpenc_xiph.c b/libavformat/rtpenc_xiph.c
index 07086b1..bc40cf8 100644
--- a/libavformat/rtpenc_xiph.c
+++ b/libavformat/rtpenc_xiph.c
@@ -2,23 +2,24 @@
  * RTP packetization for Xiph audio and video
  * Copyright (c) 2010 Josh Allmann
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/avassert.h"
 #include "avformat.h"
 #include "rtpenc.h"
 
@@ -72,7 +73,7 @@
         uint8_t *ptr     = s->buf_ptr + 2 + size; // what we're going to write
         int remaining    = end_ptr - ptr;
 
-        assert(s->num_frames <= s->max_frames_per_packet);
+        av_assert1(s->num_frames <= s->max_frames_per_packet);
         if ((s->num_frames > 0 && remaining < 0) ||
             s->num_frames == s->max_frames_per_packet) {
             // send previous packets now; no room for new data
diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c
index aca6a5a..17b0f64 100644
--- a/libavformat/rtpproto.c
+++ b/libavformat/rtpproto.c
@@ -2,20 +2,20 @@
  * RTP network protocol
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -113,6 +113,7 @@
         url_add_option(buf, buf_size, "pkt_size=%d", max_packet_size);
     if (connect)
         url_add_option(buf, buf_size, "connect=1");
+    url_add_option(buf, buf_size, "fifo_size=0");
 }
 
 /**
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index df27218..80f1047 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -2,23 +2,24 @@
  * RTSP/SDP client
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/avassert.h"
 #include "libavutil/base64.h"
 #include "libavutil/avstring.h"
 #include "libavutil/intreadwrite.h"
@@ -615,7 +616,7 @@
         s->ctx_flags |= AVFMTCTX_NOHEADER;
 
     if (s->oformat && CONFIG_RTSP_MUXER) {
-        int ret = ff_rtp_chain_mux_open(&rtsp_st->transport_priv, s, st,
+        int ret = ff_rtp_chain_mux_open((AVFormatContext **)&rtsp_st->transport_priv, s, st,
                                         rtsp_st->rtp_handle,
                                         RTSP_TCP_MAX_PACKET_SIZE);
         /* Ownership of rtp_handle is passed to the rtp mux context */
@@ -1211,10 +1212,6 @@
     /* default timeout: 1 minute */
     rt->timeout = 60;
 
-    /* for each stream, make the setup request */
-    /* XXX: we assume the same server is used for the control of each
-     * RTSP stream */
-
     /* Choose a random starting offset within the first half of the
      * port range, to allow for a number of ports to try even if the offset
      * happens to be at the end of the random range. */
@@ -1268,7 +1265,6 @@
                                &s->interrupt_callback, NULL))
                     goto rtp_opened;
             }
-
             av_log(s, AV_LOG_ERROR, "Unable to open an input RTP port\n");
             err = AVERROR(EIO);
             goto fail;
@@ -1796,7 +1792,8 @@
                 rt->recvbuf_pos += ret;
                 ret = rt->recvbuf_pos < rt->recvbuf_len;
             }
-        }
+        } else
+            av_assert0(0);
         if (ret == 0) {
             rt->cur_transport_priv = NULL;
             return 0;
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index d16c98c..e55073c 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -2,20 +2,20 @@
  * RTSP definitions
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #ifndef AVFORMAT_RTSP_H
@@ -71,7 +71,7 @@
 #define RTSP_DEFAULT_NB_AUDIO_CHANNELS 1
 #define RTSP_DEFAULT_AUDIO_SAMPLERATE 44100
 #define RTSP_RTP_PORT_MIN 5000
-#define RTSP_RTP_PORT_MAX 10000
+#define RTSP_RTP_PORT_MAX 65000
 
 /**
  * This describes a single item in the "Transport:" line of one stream as
diff --git a/libavformat/rtspcodes.h b/libavformat/rtspcodes.h
index 31ab336..4245e48 100644
--- a/libavformat/rtspcodes.h
+++ b/libavformat/rtspcodes.h
@@ -2,20 +2,20 @@
  * RTSP definitions
  * copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index 7e7fb2d..da571a8 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -2,20 +2,20 @@
  * RTSP demuxer
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -737,7 +737,7 @@
     id  = buf[0];
     len = AV_RB16(buf + 1);
     av_dlog(s, "id=%d len=%d\n", id, len);
-    if (len > buf_size || len < 12)
+    if (len > buf_size || len < 8)
         goto redo;
     /* get the data */
     ret = ffurl_read_complete(rt->rtsp_hd, buf, len);
diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c
index 9b3c7c9..bad6fbd 100644
--- a/libavformat/rtspenc.c
+++ b/libavformat/rtspenc.c
@@ -2,20 +2,20 @@
  * RTSP muxer
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/samidec.c b/libavformat/samidec.c
new file mode 100644
index 0000000..5f29364
--- /dev/null
+++ b/libavformat/samidec.c
@@ -0,0 +1,132 @@
+/*
+ * 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
+ * SAMI subtitle demuxer
+ * @see http://msdn.microsoft.com/en-us/library/ms971327.aspx
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+#include "libavutil/intreadwrite.h"
+
+typedef struct {
+    FFDemuxSubtitlesQueue q;
+} SAMIContext;
+
+static int sami_probe(AVProbeData *p)
+{
+    const unsigned char *ptr = p->buf;
+
+    if (AV_RB24(ptr) == 0xEFBBBF)
+        ptr += 3;  /* skip UTF-8 BOM */
+    return !strncmp(ptr, "<SAMI>", 6) ? AVPROBE_SCORE_MAX : 0;
+}
+
+static int sami_read_header(AVFormatContext *s)
+{
+    SAMIContext *sami = s->priv_data;
+    AVStream *st = avformat_new_stream(s, NULL);
+    AVBPrint buf, hdr_buf;
+    char c = 0;
+    int res = 0, got_first_sync_point = 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_SAMI;
+
+    av_bprint_init(&buf,     0, AV_BPRINT_SIZE_UNLIMITED);
+    av_bprint_init(&hdr_buf, 0, AV_BPRINT_SIZE_UNLIMITED);
+
+    while (!url_feof(s->pb)) {
+        AVPacket *sub;
+        const int64_t pos = avio_tell(s->pb) - (c != 0);
+        int is_sync, n = ff_smil_extract_next_chunk(s->pb, &buf, &c);
+
+        if (n == 0)
+            break;
+
+        is_sync = !av_strncasecmp(buf.str, "<SYNC", 5);
+        if (is_sync)
+            got_first_sync_point = 1;
+
+        if (!got_first_sync_point) {
+            av_bprintf(&hdr_buf, "%s", buf.str);
+        } else {
+            sub = ff_subtitles_queue_insert(&sami->q, buf.str, buf.len, !is_sync);
+            if (!sub) {
+                res = AVERROR(ENOMEM);
+                goto end;
+            }
+            if (is_sync) {
+                const char *p = ff_smil_get_attr_ptr(buf.str, "Start");
+                sub->pos      = pos;
+                sub->pts      = p ? strtol(p, NULL, 10) : 0;
+                sub->duration = -1;
+            }
+        }
+        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);
+        goto end;
+    }
+
+    ff_subtitles_queue_finalize(&sami->q);
+
+end:
+    av_bprint_finalize(&buf, NULL);
+    return res;
+}
+
+static int sami_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    SAMIContext *sami = s->priv_data;
+    return ff_subtitles_queue_read_packet(&sami->q, pkt);
+}
+
+static int sami_read_close(AVFormatContext *s)
+{
+    SAMIContext *sami = s->priv_data;
+    ff_subtitles_queue_clean(&sami->q);
+    return 0;
+}
+
+AVInputFormat ff_sami_demuxer = {
+    .name           = "sami",
+    .long_name      = NULL_IF_CONFIG_SMALL("SAMI subtitle format"),
+    .priv_data_size = sizeof(SAMIContext),
+    .read_probe     = sami_probe,
+    .read_header    = sami_read_header,
+    .read_packet    = sami_read_packet,
+    .read_close     = sami_read_close,
+    .flags          = AVFMT_GENERIC_INDEX,
+    .extensions     = "smi,sami",
+};
diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c
index c1cdc8f..ed3e857 100644
--- a/libavformat/sapdec.c
+++ b/libavformat/sapdec.c
@@ -2,20 +2,20 @@
  * Session Announcement Protocol (RFC 2974) demuxer
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c
index 1575848..3de615d 100644
--- a/libavformat/sapenc.c
+++ b/libavformat/sapenc.c
@@ -2,20 +2,20 @@
  * Session Announcement Protocol (RFC 2974) muxer
  * Copyright (c) 2010 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/sauce.c b/libavformat/sauce.c
index a125241..21cc95b 100644
--- a/libavformat/sauce.c
+++ b/libavformat/sauce.c
@@ -2,20 +2,20 @@
  * SAUCE header parser
  * Copyright (c) 2010 Peter Ross <pross@xvid.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/sauce.h b/libavformat/sauce.h
index 62d8e68..0ba9ae5 100644
--- a/libavformat/sauce.h
+++ b/libavformat/sauce.h
@@ -2,20 +2,20 @@
  * SAUCE header parser
  * Copyright (c) 2010 Peter Ross <pross@xvid.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/sbgdec.c b/libavformat/sbgdec.c
new file mode 100644
index 0000000..93c8cb3
--- /dev/null
+++ b/libavformat/sbgdec.c
@@ -0,0 +1,1513 @@
+/*
+ * SBG (SBaGen) file format decoder
+ * Copyright (c) 2011 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 <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "libavutil/intreadwrite.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "avformat.h"
+#include "internal.h"
+
+#define SBG_SCALE (1 << 16)
+#define DAY (24 * 60 * 60)
+#define DAY_TS ((int64_t)DAY * AV_TIME_BASE)
+
+struct sbg_demuxer {
+    AVClass *class;
+    int sample_rate;
+    int frame_size;
+    int max_file_size;
+};
+
+struct sbg_string {
+    char *s;
+    char *e;
+};
+
+enum sbg_fade_type {
+    SBG_FADE_SILENCE = 0,
+    SBG_FADE_SAME    = 1,
+    SBG_FADE_ADAPT   = 3,
+};
+
+struct sbg_fade {
+    int8_t in, out, slide;
+};
+
+enum sbg_synth_type {
+    SBG_TYPE_NONE,
+    SBG_TYPE_SINE,
+    SBG_TYPE_NOISE,
+    SBG_TYPE_BELL,
+    SBG_TYPE_MIX,
+    SBG_TYPE_SPIN,
+};
+
+/* bell: freq constant, ampl decreases exponentially, can be approx lin */
+
+struct sbg_timestamp {
+    int64_t t;
+    char type; /* 0 for relative, 'N' for now, 'T' for absolute */
+};
+
+struct sbg_script_definition {
+    char *name;
+    int name_len;
+    int elements, nb_elements;
+    char type; /* 'S' or 'B' */
+};
+
+struct sbg_script_synth {
+    int carrier;
+    int beat;
+    int vol;
+    enum sbg_synth_type type;
+    struct {
+        int l, r;
+    } ref;
+};
+
+struct sbg_script_tseq {
+    struct sbg_timestamp ts;
+    char *name;
+    int name_len;
+    int lock;
+    struct sbg_fade fade;
+};
+
+struct sbg_script_event {
+    int64_t ts;
+    int64_t ts_int, ts_trans, ts_next;
+    int elements, nb_elements;
+    struct sbg_fade fade;
+};
+
+struct sbg_script {
+    struct sbg_script_definition *def;
+    struct sbg_script_synth *synth;
+    struct sbg_script_tseq *tseq;
+    struct sbg_script_tseq *block_tseq;
+    struct sbg_script_event *events;
+    int nb_def;
+    int nb_tseq;
+    int nb_events;
+    int nb_synth;
+    int64_t start_ts;
+    int64_t end_ts;
+    int64_t opt_fade_time;
+    int64_t opt_duration;
+    char *opt_mix;
+    int sample_rate;
+    uint8_t opt_start_at_first;
+    uint8_t opt_end_at_last;
+};
+
+struct sbg_parser {
+    void *log;
+    char *script, *end;
+    char *cursor;
+    struct sbg_script scs;
+    struct sbg_timestamp current_time;
+    int nb_block_tseq;
+    int nb_def_max, nb_synth_max, nb_tseq_max, nb_block_tseq_max;
+    int line_no;
+    char err_msg[128];
+};
+
+enum ws_interval_type {
+    WS_SINE  = MKTAG('S','I','N','E'),
+    WS_NOISE = MKTAG('N','O','I','S'),
+};
+
+struct ws_interval {
+    int64_t ts1, ts2;
+    enum ws_interval_type type;
+    uint32_t channels;
+    int32_t f1, f2;
+    int32_t a1, a2;
+    uint32_t phi;
+};
+
+struct ws_intervals {
+    struct ws_interval *inter;
+    int nb_inter;
+    int max_inter;
+};
+
+static void *alloc_array_elem(void **array, size_t elsize,
+                              int *size, int *max_size)
+{
+    void *ret;
+
+    if (*size == *max_size) {
+        int m = FFMAX(32, FFMIN(*max_size, INT_MAX / 2) * 2);
+        if (*size >= m)
+            return NULL;
+        *array = av_realloc_f(*array, m, elsize);
+        if (!*array)
+            return NULL;
+        *max_size = m;
+    }
+    ret = (char *)*array + elsize * *size;
+    memset(ret, 0, elsize);
+    (*size)++;
+    return ret;
+}
+
+static int str_to_time(const char *str, int64_t *rtime)
+{
+    const char *cur = str;
+    char *end;
+    int hours, minutes;
+    double seconds = 0;
+
+    if (*cur < '0' || *cur > '9')
+        return 0;
+    hours = strtol(cur, &end, 10);
+    if (end == cur || *end != ':' || end[1] < '0' || end[1] > '9')
+        return 0;
+    cur = end + 1;
+    minutes = strtol(cur, &end, 10);
+    if (end == cur)
+        return 0;
+    cur = end;
+    if (*end == ':'){
+        seconds = strtod(cur + 1, &end);
+        if (end > cur + 1)
+            cur = end;
+    }
+    *rtime = (hours * 3600 + minutes * 60 + seconds) * AV_TIME_BASE;
+    return cur - str;
+}
+
+static inline int is_space(char c)
+{
+    return c == ' '  || c == '\t' || c == '\r';
+}
+
+static inline int scale_double(void *log, double d, double m, int *r)
+{
+    m *= d * SBG_SCALE;
+    if (m < INT_MIN || m >= INT_MAX) {
+        if (log)
+            av_log(log, AV_LOG_ERROR, "%g is too large\n", d);
+        return AVERROR(EDOM);
+    }
+    *r = m;
+    return 0;
+}
+
+static int lex_space(struct sbg_parser *p)
+{
+    char *c = p->cursor;
+
+    while (p->cursor < p->end && is_space(*p->cursor))
+        p->cursor++;
+    return p->cursor > c;
+}
+
+static int lex_char(struct sbg_parser *p, char c)
+{
+    int r = p->cursor < p->end && *p->cursor == c;
+
+    p->cursor += r;
+    return r;
+}
+
+static int lex_double(struct sbg_parser *p, double *r)
+{
+    double d;
+    char *end;
+
+    if (p->cursor == p->end || is_space(*p->cursor) || *p->cursor == '\n')
+        return 0;
+    d = strtod(p->cursor, &end);
+    if (end > p->cursor) {
+        *r = d;
+        p->cursor = end;
+        return 1;
+    }
+    return 0;
+}
+
+static int lex_fixed(struct sbg_parser *p, const char *t, int l)
+{
+    if (p->end - p->cursor < l || memcmp(p->cursor, t, l))
+        return 0;
+    p->cursor += l;
+    return 1;
+}
+
+static int lex_line_end(struct sbg_parser *p)
+{
+    if (p->cursor < p->end && *p->cursor == '#') {
+        p->cursor++;
+        while (p->cursor < p->end && *p->cursor != '\n')
+            p->cursor++;
+    }
+    if (p->cursor == p->end)
+        /* simulate final LF for files lacking it */
+        return 1;
+    if (*p->cursor != '\n')
+        return 0;
+    p->cursor++;
+    p->line_no++;
+    lex_space(p);
+    return 1;
+}
+
+static int lex_wsword(struct sbg_parser *p, struct sbg_string *rs)
+{
+    char *s = p->cursor, *c = s;
+
+    if (s == p->end || *s == '\n')
+        return 0;
+    while (c < p->end && *c != '\n' && !is_space(*c))
+        c++;
+    rs->s = s;
+    rs->e = p->cursor = c;
+    lex_space(p);
+    return 1;
+}
+
+static int lex_name(struct sbg_parser *p, struct sbg_string *rs)
+{
+    char *s = p->cursor, *c = s;
+
+    while (c < p->end && ((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z')
+           || (*c >= '0' && *c <= '9') || *c == '_' || *c == '-'))
+        c++;
+    if (c == s)
+        return 0;
+    rs->s = s;
+    rs->e = p->cursor = c;
+    return 1;
+}
+
+static int lex_time(struct sbg_parser *p, int64_t *rt)
+{
+    int r = str_to_time(p->cursor, rt);
+    p->cursor += r;
+    return r > 0;
+}
+
+#define FORWARD_ERROR(c) \
+    do { \
+        int errcode = c; \
+        if (errcode <= 0) \
+            return errcode ? errcode : AVERROR_INVALIDDATA; \
+    } while(0);
+
+static int parse_immediate(struct sbg_parser *p)
+{
+    snprintf(p->err_msg, sizeof(p->err_msg),
+             "immediate sequences not yet implemented");
+    return AVERROR_PATCHWELCOME;
+}
+
+static int parse_preprogrammed(struct sbg_parser *p)
+{
+    snprintf(p->err_msg, sizeof(p->err_msg),
+             "preprogrammed sequences not yet implemented");
+    return AVERROR_PATCHWELCOME;
+}
+
+static int parse_optarg(struct sbg_parser *p, char o, struct sbg_string *r)
+{
+    if (!lex_wsword(p, r)) {
+        snprintf(p->err_msg, sizeof(p->err_msg),
+                 "option '%c' requires an argument", o);
+        return AVERROR_INVALIDDATA;
+    }
+    return 1;
+}
+
+static int parse_options(struct sbg_parser *p)
+{
+    struct sbg_string ostr, oarg;
+    char mode = 0;
+    int r;
+    char *tptr;
+    double v;
+
+    if (p->cursor == p->end || *p->cursor != '-')
+        return 0;
+    while (lex_char(p, '-') && lex_wsword(p, &ostr)) {
+        for (; ostr.s < ostr.e; ostr.s++) {
+            char opt = *ostr.s;
+            switch (opt) {
+                case 'S':
+                    p->scs.opt_start_at_first = 1;
+                    break;
+                case 'E':
+                    p->scs.opt_end_at_last = 1;
+                    break;
+                case 'i':
+                    mode = 'i';
+                    break;
+                case 'p':
+                    mode = 'p';
+                    break;
+                case 'F':
+                    FORWARD_ERROR(parse_optarg(p, opt, &oarg));
+                    v = strtod(oarg.s, &tptr);
+                    if (oarg.e != tptr) {
+                        snprintf(p->err_msg, sizeof(p->err_msg),
+                                 "syntax error for option -F");
+                        return AVERROR_INVALIDDATA;
+                    }
+                    p->scs.opt_fade_time = v * AV_TIME_BASE / 1000;
+                    break;
+                case 'L':
+                    FORWARD_ERROR(parse_optarg(p, opt, &oarg));
+                    r = str_to_time(oarg.s, &p->scs.opt_duration);
+                    if (oarg.e != oarg.s + r) {
+                        snprintf(p->err_msg, sizeof(p->err_msg),
+                                 "syntax error for option -L");
+                        return AVERROR_INVALIDDATA;
+                    }
+                    break;
+                case 'T':
+                    FORWARD_ERROR(parse_optarg(p, opt, &oarg));
+                    r = str_to_time(oarg.s, &p->scs.start_ts);
+                    if (oarg.e != oarg.s + r) {
+                        snprintf(p->err_msg, sizeof(p->err_msg),
+                                 "syntax error for option -T");
+                        return AVERROR_INVALIDDATA;
+                    }
+                    break;
+                case 'm':
+                    FORWARD_ERROR(parse_optarg(p, opt, &oarg));
+                    tptr = av_malloc(oarg.e - oarg.s + 1);
+                    if (!tptr)
+                        return AVERROR(ENOMEM);
+                    memcpy(tptr, oarg.s, oarg.e - oarg.s);
+                    tptr[oarg.e - oarg.s] = 0;
+                    av_free(p->scs.opt_mix);
+                    p->scs.opt_mix = tptr;
+                    break;
+                case 'q':
+                    FORWARD_ERROR(parse_optarg(p, opt, &oarg));
+                    v = strtod(oarg.s, &tptr);
+                    if (oarg.e != tptr) {
+                        snprintf(p->err_msg, sizeof(p->err_msg),
+                                 "syntax error for option -q");
+                        return AVERROR_INVALIDDATA;
+                    }
+                    if (v != 1) {
+                        snprintf(p->err_msg, sizeof(p->err_msg),
+                                 "speed factor other than 1 not supported");
+                        return AVERROR_PATCHWELCOME;
+                    }
+                    break;
+                case 'r':
+                    FORWARD_ERROR(parse_optarg(p, opt, &oarg));
+                    r = strtol(oarg.s, &tptr, 10);
+                    if (oarg.e != tptr) {
+                        snprintf(p->err_msg, sizeof(p->err_msg),
+                                 "syntax error for option -r");
+                        return AVERROR_INVALIDDATA;
+                    }
+                    if (r < 40) {
+                        snprintf(p->err_msg, sizeof(p->err_msg),
+                                 "invalid sample rate");
+                        return AVERROR_PATCHWELCOME;
+                    }
+                    p->scs.sample_rate = r;
+                    break;
+                default:
+                    snprintf(p->err_msg, sizeof(p->err_msg),
+                             "unknown option: '%c'", *ostr.s);
+                    return AVERROR_INVALIDDATA;
+            }
+        }
+    }
+    switch (mode) {
+        case 'i':
+            return parse_immediate(p);
+        case 'p':
+            return parse_preprogrammed(p);
+        case 0:
+            if (!lex_line_end(p))
+                return AVERROR_INVALIDDATA;
+            return 1;
+    }
+    return AVERROR_BUG;
+}
+
+static int parse_timestamp(struct sbg_parser *p,
+                               struct sbg_timestamp *rts, int64_t *rrel)
+{
+    int64_t abs = 0, rel = 0, dt;
+    char type = 0;
+    int r;
+
+    if (lex_fixed(p, "NOW", 3)) {
+        type = 'N';
+        r = 1;
+    } else {
+        r = lex_time(p, &abs);
+        if (r)
+            type = 'T';
+    }
+    while (lex_char(p, '+')) {
+        if (!lex_time(p, &dt))
+            return AVERROR_INVALIDDATA;
+        rel += dt;
+        r = 1;
+    }
+    if (r) {
+        if (!lex_space(p))
+            return AVERROR_INVALIDDATA;
+        rts->type = type;
+        rts->t    = abs;
+        *rrel     = rel;
+    }
+    return r;
+}
+
+static int parse_fade(struct sbg_parser *p, struct sbg_fade *fr)
+{
+    struct sbg_fade f;
+
+    if (lex_char(p, '<'))
+        f.in = SBG_FADE_SILENCE;
+    else if (lex_char(p, '-'))
+        f.in = SBG_FADE_SAME;
+    else if (lex_char(p, '='))
+        f.in = SBG_FADE_ADAPT;
+    else
+        return 0;
+    if (lex_char(p, '>'))
+        f.out = SBG_FADE_SILENCE;
+    else if (lex_char(p, '-'))
+        f.out = SBG_FADE_SAME;
+    else if (lex_char(p, '='))
+        f.out = SBG_FADE_ADAPT;
+    else
+        return AVERROR_INVALIDDATA;
+    *fr = f;
+    return 1;
+}
+
+static int parse_time_sequence(struct sbg_parser *p, int inblock)
+{
+    struct sbg_timestamp ts;
+    int64_t rel_ts;
+    int r;
+    struct sbg_fade fade = { SBG_FADE_SAME, SBG_FADE_SAME, 0 };
+    struct sbg_string name;
+    struct sbg_script_tseq *tseq;
+
+    r = parse_timestamp(p, &ts, &rel_ts);
+    if (!r)
+        return 0;
+    if (r < 0)
+        return r;
+    if (ts.type) {
+        if (inblock)
+            return AVERROR_INVALIDDATA;
+        p->current_time.type = ts.type;
+        p->current_time.t    = ts.t;
+    } else if(!inblock && !p->current_time.type) {
+        snprintf(p->err_msg, sizeof(p->err_msg),
+                 "relative time without previous absolute time");
+        return AVERROR_INVALIDDATA;
+    }
+    ts.type = p->current_time.type;
+    ts.t    = p->current_time.t + rel_ts;
+    r = parse_fade(p, &fade);
+    if (r < 0)
+        return r;
+    lex_space(p);
+    if (!lex_name(p, &name))
+        return AVERROR_INVALIDDATA;
+    lex_space(p);
+    if (lex_fixed(p, "->", 2)) {
+        fade.slide = SBG_FADE_ADAPT;
+        lex_space(p);
+    }
+    if (!lex_line_end(p))
+        return AVERROR_INVALIDDATA;
+    tseq = inblock ?
+           alloc_array_elem((void **)&p->scs.block_tseq, sizeof(*tseq),
+                            &p->nb_block_tseq, &p->nb_block_tseq_max) :
+           alloc_array_elem((void **)&p->scs.tseq, sizeof(*tseq),
+                            &p->scs.nb_tseq, &p->nb_tseq_max);
+    if (!tseq)
+        return AVERROR(ENOMEM);
+    tseq->ts       = ts;
+    tseq->name     = name.s;
+    tseq->name_len = name.e - name.s;
+    tseq->fade     = fade;
+    return 1;
+}
+
+static int parse_wave_def(struct sbg_parser *p, int wavenum)
+{
+    snprintf(p->err_msg, sizeof(p->err_msg),
+             "waveform definitions not yet implemented");
+    return AVERROR_PATCHWELCOME;
+}
+
+static int parse_block_def(struct sbg_parser *p,
+                           struct sbg_script_definition *def)
+{
+    int r, tseq;
+
+    lex_space(p);
+    if (!lex_line_end(p))
+        return AVERROR_INVALIDDATA;
+    tseq = p->nb_block_tseq;
+    while (1) {
+        r = parse_time_sequence(p, 1);
+        if (r < 0)
+            return r;
+        if (!r)
+            break;
+    }
+    if (!lex_char(p, '}'))
+        return AVERROR_INVALIDDATA;
+    lex_space(p);
+    if (!lex_line_end(p))
+        return AVERROR_INVALIDDATA;
+    def->type        = 'B';
+    def->elements    = tseq;
+    def->nb_elements = p->nb_block_tseq - tseq;
+    if (!def->nb_elements)
+        return AVERROR_INVALIDDATA;
+    return 1;
+}
+
+static int parse_volume(struct sbg_parser *p, int *vol)
+{
+    double v;
+
+    if (!lex_char(p, '/'))
+        return 0;
+    if (!lex_double(p, &v))
+        return AVERROR_INVALIDDATA;
+    if (scale_double(p->log, v, 0.01, vol))
+        return AVERROR(ERANGE);
+    return 1;
+}
+
+static int parse_synth_channel_sine(struct sbg_parser *p,
+                                    struct sbg_script_synth *synth)
+{
+    double carrierf, beatf;
+    int carrier, beat, vol;
+
+    if (!lex_double(p, &carrierf))
+        return 0;
+    if (!lex_double(p, &beatf))
+        beatf = 0;
+    FORWARD_ERROR(parse_volume(p, &vol));
+    if (scale_double(p->log, carrierf, 1, &carrier) < 0 ||
+        scale_double(p->log, beatf, 1, &beat) < 0)
+        return AVERROR(EDOM);
+    synth->type    = SBG_TYPE_SINE;
+    synth->carrier = carrier;
+    synth->beat    = beat;
+    synth->vol     = vol;
+    return 1;
+}
+
+static int parse_synth_channel_pink(struct sbg_parser *p,
+                                    struct sbg_script_synth *synth)
+{
+    int vol;
+
+    if (!lex_fixed(p, "pink", 4))
+        return 0;
+    FORWARD_ERROR(parse_volume(p, &vol));
+    synth->type    = SBG_TYPE_NOISE;
+    synth->vol     = vol;
+    return 1;
+}
+
+static int parse_synth_channel_bell(struct sbg_parser *p,
+                                    struct sbg_script_synth *synth)
+{
+    double carrierf;
+    int carrier, vol;
+
+    if (!lex_fixed(p, "bell", 4))
+        return 0;
+    if (!lex_double(p, &carrierf))
+        return AVERROR_INVALIDDATA;
+    FORWARD_ERROR(parse_volume(p, &vol));
+    if (scale_double(p->log, carrierf, 1, &carrier) < 0)
+        return AVERROR(EDOM);
+    synth->type    = SBG_TYPE_BELL;
+    synth->carrier = carrier;
+    synth->vol     = vol;
+    return 1;
+}
+
+static int parse_synth_channel_mix(struct sbg_parser *p,
+                                   struct sbg_script_synth *synth)
+{
+    int vol;
+
+    if (!lex_fixed(p, "mix", 3))
+        return 0;
+    FORWARD_ERROR(parse_volume(p, &vol));
+    synth->type    = SBG_TYPE_MIX;
+    synth->vol     = vol;
+    return 1;
+}
+
+static int parse_synth_channel_spin(struct sbg_parser *p,
+                                    struct sbg_script_synth *synth)
+{
+    double carrierf, beatf;
+    int carrier, beat, vol;
+
+    if (!lex_fixed(p, "spin:", 5))
+        return 0;
+    if (!lex_double(p, &carrierf))
+        return AVERROR_INVALIDDATA;
+    if (!lex_double(p, &beatf))
+        return AVERROR_INVALIDDATA;
+    FORWARD_ERROR(parse_volume(p, &vol));
+    if (scale_double(p->log, carrierf, 1, &carrier) < 0 ||
+        scale_double(p->log, beatf, 1, &beat) < 0)
+        return AVERROR(EDOM);
+    synth->type    = SBG_TYPE_SPIN;
+    synth->carrier = carrier;
+    synth->beat    = beat;
+    synth->vol     = vol;
+    return 1;
+}
+
+static int parse_synth_channel(struct sbg_parser *p)
+{
+    int r;
+    struct sbg_script_synth *synth;
+
+    synth = alloc_array_elem((void **)&p->scs.synth, sizeof(*synth),
+                             &p->scs.nb_synth, &p->nb_synth_max);
+    if (!synth)
+        return AVERROR(ENOMEM);
+    r = lex_char(p, '-');
+    if (!r)
+        r = parse_synth_channel_pink(p, synth);
+    if (!r)
+        r = parse_synth_channel_bell(p, synth);
+    if (!r)
+        r = parse_synth_channel_mix(p, synth);
+    if (!r)
+        r = parse_synth_channel_spin(p, synth);
+    /* Unimplemented: wave%d:%f%f/vol (carrier, beat) */
+    if (!r)
+        r = parse_synth_channel_sine(p, synth);
+    if (r <= 0)
+        p->scs.nb_synth--;
+    return r;
+}
+
+static int parse_synth_def(struct sbg_parser *p,
+                           struct sbg_script_definition *def)
+{
+    int r, synth;
+
+    synth = p->scs.nb_synth;
+    while (1) {
+        r = parse_synth_channel(p);
+        if (r < 0)
+            return r;
+        if (!r || !lex_space(p))
+            break;
+    }
+    lex_space(p);
+    if (synth == p->scs.nb_synth)
+        return AVERROR_INVALIDDATA;
+    if (!lex_line_end(p))
+        return AVERROR_INVALIDDATA;
+    def->type        = 'S';
+    def->elements    = synth;
+    def->nb_elements = p->scs.nb_synth - synth;
+    return 1;
+}
+
+static int parse_named_def(struct sbg_parser *p)
+{
+    char *cursor_save = p->cursor;
+    struct sbg_string name;
+    struct sbg_script_definition *def;
+
+    if (!lex_name(p, &name) || !lex_char(p, ':') || !lex_space(p)) {
+        p->cursor = cursor_save;
+        return 0;
+    }
+    if (name.e - name.s == 6 && !memcmp(name.s, "wave", 4) &&
+        name.s[4] >= '0' && name.s[4] <= '9' &&
+        name.s[5] >= '0' && name.s[5] <= '9') {
+        int wavenum = (name.s[4] - '0') * 10 + (name.s[5] - '0');
+        return parse_wave_def(p, wavenum);
+    }
+    def = alloc_array_elem((void **)&p->scs.def, sizeof(*def),
+                           &p->scs.nb_def, &p->nb_def_max);
+    if (!def)
+        return AVERROR(ENOMEM);
+    def->name     = name.s;
+    def->name_len = name.e - name.s;
+    if (lex_char(p, '{'))
+        return parse_block_def(p, def);
+    return parse_synth_def(p, def);
+}
+
+static void free_script(struct sbg_script *s)
+{
+    av_freep(&s->def);
+    av_freep(&s->synth);
+    av_freep(&s->tseq);
+    av_freep(&s->block_tseq);
+    av_freep(&s->events);
+    av_freep(&s->opt_mix);
+}
+
+static int parse_script(void *log, char *script, int script_len,
+                            struct sbg_script *rscript)
+{
+    struct sbg_parser sp = {
+        .log     = log,
+        .script  = script,
+        .end     = script + script_len,
+        .cursor  = script,
+        .line_no = 1,
+        .err_msg = "",
+        .scs = {
+            /* default values */
+            .start_ts      = AV_NOPTS_VALUE,
+            .sample_rate   = 44100,
+            .opt_fade_time = 60 * AV_TIME_BASE,
+        },
+    };
+    int r;
+
+    lex_space(&sp);
+    while (sp.cursor < sp.end) {
+        r = parse_options(&sp);
+        if (r < 0)
+            goto fail;
+        if (!r && !lex_line_end(&sp))
+            break;
+    }
+    while (sp.cursor < sp.end) {
+        r = parse_named_def(&sp);
+        if (!r)
+            r = parse_time_sequence(&sp, 0);
+        if (!r)
+            r = lex_line_end(&sp) ? 1 : AVERROR_INVALIDDATA;
+        if (r < 0)
+            goto fail;
+    }
+    *rscript = sp.scs;
+    return 1;
+fail:
+    free_script(&sp.scs);
+    if (!*sp.err_msg)
+        if (r == AVERROR_INVALIDDATA)
+            snprintf(sp.err_msg, sizeof(sp.err_msg), "syntax error");
+    if (log && *sp.err_msg) {
+        const char *ctx = sp.cursor;
+        const char *ectx = av_x_if_null(memchr(ctx, '\n', sp.end - sp.cursor),
+                                        sp.end);
+        int lctx = ectx - ctx;
+        const char *quote = "\"";
+        if (lctx > 0 && ctx[lctx - 1] == '\r')
+            lctx--;
+        if (lctx == 0) {
+            ctx = "the end of line";
+            lctx = strlen(ctx);
+            quote = "";
+        }
+        av_log(log, AV_LOG_ERROR, "Error line %d: %s near %s%.*s%s.\n",
+               sp.line_no, sp.err_msg, quote, lctx, ctx, quote);
+    }
+    return r;
+}
+
+static int read_whole_file(AVIOContext *io, int max_size, char **rbuf)
+{
+    char *buf = NULL;
+    int size = 0, bufsize = 0, r;
+
+    while (1) {
+        if (bufsize - size < 1024) {
+            bufsize = FFMIN(FFMAX(2 * bufsize, 8192), max_size);
+            if (bufsize - size < 2) {
+                size = AVERROR(EFBIG);
+                goto fail;
+            }
+            buf = av_realloc_f(buf, bufsize, 1);
+            if (!buf) {
+                size = AVERROR(ENOMEM);
+                goto fail;
+            }
+        }
+        r = avio_read(io, buf, bufsize - size - 1);
+        if (r == AVERROR_EOF)
+            break;
+        if (r < 0)
+            goto fail;
+        size += r;
+    }
+    buf[size] = 0;
+    *rbuf = buf;
+    return size;
+fail:
+    av_free(buf);
+    return size;
+}
+
+static void expand_timestamps(void *log, struct sbg_script *s)
+{
+    int i, nb_rel = 0;
+    int64_t now, cur_ts, delta = 0;
+
+    for (i = 0; i < s->nb_tseq; i++)
+        nb_rel += s->tseq[i].ts.type == 'N';
+    if (nb_rel == s->nb_tseq) {
+        /* All ts are relative to NOW: consider NOW = 0 */
+        now = 0;
+        if (s->start_ts != AV_NOPTS_VALUE)
+            av_log(log, AV_LOG_WARNING,
+                   "Start time ignored in a purely relative script.\n");
+    } else if (nb_rel == 0 && s->start_ts != AV_NOPTS_VALUE ||
+               s->opt_start_at_first) {
+        /* All ts are absolute and start time is specified */
+        if (s->start_ts == AV_NOPTS_VALUE)
+            s->start_ts = s->tseq[0].ts.t;
+        now = s->start_ts;
+    } else {
+        /* Mixed relative/absolute ts: expand */
+        time_t now0;
+        struct tm *tm;
+
+        av_log(log, AV_LOG_WARNING,
+               "Scripts with mixed absolute and relative timestamps can give "
+               "unexpected results (pause, seeking, time zone change).\n");
+#undef time
+        time(&now0);
+        tm = localtime(&now0);
+        now = tm ? tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec :
+                   now0 % DAY;
+        av_log(log, AV_LOG_INFO, "Using %02d:%02d:%02d as NOW.\n",
+               (int)(now / 3600), (int)(now / 60) % 60, (int)now % 60);
+        now *= AV_TIME_BASE;
+        for (i = 0; i < s->nb_tseq; i++) {
+            if (s->tseq[i].ts.type == 'N') {
+                s->tseq[i].ts.t += now;
+                s->tseq[i].ts.type = 'T'; /* not necessary */
+            }
+        }
+    }
+    if (s->start_ts == AV_NOPTS_VALUE)
+        s->start_ts = s->opt_start_at_first ? s->tseq[0].ts.t : now;
+    s->end_ts = s->opt_duration ? s->start_ts + s->opt_duration :
+                AV_NOPTS_VALUE; /* may be overridden later by -E option */
+    cur_ts = now;
+    for (i = 0; i < s->nb_tseq; i++) {
+        if (s->tseq[i].ts.t + delta < cur_ts)
+            delta += DAY_TS;
+        cur_ts = s->tseq[i].ts.t += delta;
+    }
+}
+
+static int expand_tseq(void *log, struct sbg_script *s, int *nb_ev_max,
+                       int64_t t0, struct sbg_script_tseq *tseq)
+{
+    int i, r;
+    struct sbg_script_definition *def;
+    struct sbg_script_tseq *be;
+    struct sbg_script_event *ev;
+
+    if (tseq->lock++) {
+        av_log(log, 16, "Recursion loop on \"%.*s\"\n",
+               tseq->name_len, tseq->name);
+        return AVERROR(EINVAL);
+    }
+    t0 += tseq->ts.t;
+    for (i = 0; i < s->nb_def; i++) {
+        if (s->def[i].name_len == tseq->name_len &&
+            !memcmp(s->def[i].name, tseq->name, tseq->name_len))
+            break;
+    }
+    if (i >= s->nb_def) {
+        av_log(log, 16, "Tone-set \"%.*s\" not defined\n",
+               tseq->name_len, tseq->name);
+        return AVERROR(EINVAL);
+    }
+    def = &s->def[i];
+    if (def->type == 'B') {
+        be = s->block_tseq + def->elements;
+        for (i = 0; i < def->nb_elements; i++) {
+            r = expand_tseq(log, s, nb_ev_max, t0, &be[i]);
+            if (r < 0)
+                return r;
+        }
+    } else {
+        ev = alloc_array_elem((void **)&s->events, sizeof(*ev),
+                              &s->nb_events, nb_ev_max);
+        ev->ts          = tseq->ts.t;
+        ev->elements    = def->elements;
+        ev->nb_elements = def->nb_elements;
+        ev->fade        = tseq->fade;
+    }
+    tseq->lock--;
+    return 0;
+}
+
+static int expand_script(void *log, struct sbg_script *s)
+{
+    int i, r, nb_events_max = 0;
+
+    expand_timestamps(log, s);
+    for (i = 0; i < s->nb_tseq; i++) {
+        r = expand_tseq(log, s, &nb_events_max, 0, &s->tseq[i]);
+        if (r < 0)
+            return r;
+    }
+    if (!s->nb_events) {
+        av_log(log, AV_LOG_ERROR, "No events in script\n");
+        return AVERROR_INVALIDDATA;
+    }
+    if (s->opt_end_at_last)
+        s->end_ts = s->events[s->nb_events - 1].ts;
+    return 0;
+}
+
+static int add_interval(struct ws_intervals *inter,
+                        enum ws_interval_type type, uint32_t channels, int ref,
+                        int64_t ts1, int32_t f1, int32_t a1,
+                        int64_t ts2, int32_t f2, int32_t a2)
+{
+    struct ws_interval *i, *ri;
+
+    if (ref >= 0) {
+        ri = &inter->inter[ref];
+        /* ref and new intervals are constant, identical and adjacent */
+        if (ri->type == type && ri->channels == channels &&
+            ri->f1 == ri->f2 && ri->f2 == f1 && f1 == f2 &&
+            ri->a1 == ri->a2 && ri->a2 == a1 && a1 == a2 &&
+            ri->ts2 == ts1) {
+            ri->ts2 = ts2;
+            return ref;
+        }
+    }
+    i = alloc_array_elem((void **)&inter->inter, sizeof(*i),
+                         &inter->nb_inter, &inter->max_inter);
+    if (!i)
+        return AVERROR(ENOMEM);
+    i->ts1      = ts1;
+    i->ts2      = ts2;
+    i->type     = type;
+    i->channels = channels;
+    i->f1       = f1;
+    i->f2       = f2;
+    i->a1       = a1;
+    i->a2       = a2;
+    i->phi      = ref >= 0 ? ref | 0x80000000 : 0;
+    return i - inter->inter;
+}
+
+static int add_bell(struct ws_intervals *inter, struct sbg_script *s,
+                    int64_t ts1, int64_t ts2, int32_t f, int32_t a)
+{
+    /* SBaGen uses an exponential decrease every 50ms.
+       We approximate it with piecewise affine segments. */
+    int32_t cpoints[][2] = {
+        {  2, a },
+        {  4, a - a / 4 },
+        {  8, a / 2 },
+        { 16, a / 4 },
+        { 25, a / 10 },
+        { 50, a / 80 },
+        { 75, 0 },
+    };
+    int i, r;
+    int64_t dt = s->sample_rate / 20, ts3 = ts1, ts4;
+    for (i = 0; i < FF_ARRAY_ELEMS(cpoints); i++) {
+        ts4 = FFMIN(ts2, ts1 + cpoints[i][0] * dt);
+        r = add_interval(inter, WS_SINE, 3, -1,
+                         ts3, f, a, ts4, f, cpoints[i][1]);
+        if (r < 0)
+            return r;
+        ts3 = ts4;
+        a = cpoints[i][1];
+    }
+    return 0;
+}
+
+static int generate_interval(void *log, struct sbg_script *s,
+                             struct ws_intervals *inter,
+                             int64_t ts1, int64_t ts2,
+                             struct sbg_script_synth *s1,
+                             struct sbg_script_synth *s2,
+                             int transition)
+{
+    int r;
+
+    if (ts2 <= ts1 || (s1->vol == 0 && s2->vol == 0))
+        return 0;
+    switch (s1->type) {
+        case SBG_TYPE_NONE:
+            break;
+        case SBG_TYPE_SINE:
+            if (s1->beat == 0 && s2->beat == 0) {
+                r = add_interval(inter, WS_SINE, 3, s1->ref.l,
+                                 ts1, s1->carrier, s1->vol,
+                                 ts2, s2->carrier, s2->vol);
+                if (r < 0)
+                    return r;
+                s2->ref.l = s2->ref.r = r;
+            } else {
+                r = add_interval(inter, WS_SINE, 1, s1->ref.l,
+                                 ts1, s1->carrier + s1->beat / 2, s1->vol,
+                                 ts2, s2->carrier + s2->beat / 2, s2->vol);
+                if (r < 0)
+                    return r;
+                s2->ref.l = r;
+                r = add_interval(inter, WS_SINE, 2, s1->ref.r,
+                                 ts1, s1->carrier - s1->beat / 2, s1->vol,
+                                 ts2, s2->carrier - s2->beat / 2, s2->vol);
+                if (r < 0)
+                    return r;
+                s2->ref.r = r;
+            }
+            break;
+
+        case SBG_TYPE_BELL:
+            if (transition == 2) {
+                r = add_bell(inter, s, ts1, ts2, s1->carrier, s2->vol);
+                if (r < 0)
+                    return r;
+            }
+            break;
+
+        case SBG_TYPE_SPIN:
+            av_log(log, AV_LOG_WARNING, "Spinning noise not implemented, "
+                                        "using pink noise instead.\n");
+            /* fall through */
+        case SBG_TYPE_NOISE:
+            /* SBaGen's pink noise generator uses:
+               - 1 band of white noise, mean square: 1/3;
+               - 9 bands of subsampled white noise with linear
+                 interpolation, mean square: 2/3 each;
+               with 1/10 weight each: the total mean square is 7/300.
+               Our pink noise generator uses 8 bands of white noise with
+               rectangular subsampling: the total mean square is 1/24.
+               Therefore, to match SBaGen's volume, we must multiply vol by
+               sqrt((7/300) / (1/24)) = sqrt(14/25) =~ 0.748
+             */
+            r = add_interval(inter, WS_NOISE, 3, s1->ref.l,
+                             ts1, 0, s1->vol - s1->vol / 4,
+                             ts2, 0, s2->vol - s2->vol / 4);
+            if (r < 0)
+                return r;
+            s2->ref.l = s2->ref.r = r;
+            break;
+
+        case SBG_TYPE_MIX:
+            /* Unimplemented: silence; warning present elsewhere */
+        default:
+            av_log(log, AV_LOG_ERROR,
+                   "Type %d is not implemented\n", s1->type);
+            return AVERROR_PATCHWELCOME;
+    }
+    return 0;
+}
+
+static int generate_plateau(void *log, struct sbg_script *s,
+                            struct ws_intervals *inter,
+                            struct sbg_script_event *ev1)
+{
+    int64_t ts1 = ev1->ts_int, ts2 = ev1->ts_trans;
+    int i, r;
+    struct sbg_script_synth *s1;
+
+    for (i = 0; i < ev1->nb_elements; i++) {
+        s1 = &s->synth[ev1->elements + i];
+        r = generate_interval(log, s, inter, ts1, ts2, s1, s1, 0);
+        if (r < 0)
+            return r;
+    }
+    return 0;
+}
+
+/*
+
+   ts1             ts2         ts1    tsmid    ts2
+    |               |           |       |       |
+    v               v           v       |       v
+____                        ____        v       ____
+    ''''....                    ''..        ..''
+            ''''....____            ''....''
+
+  compatible transition      incompatible transition
+ */
+
+static int generate_transition(void *log, struct sbg_script *s,
+                               struct ws_intervals *inter,
+                               struct sbg_script_event *ev1,
+                               struct sbg_script_event *ev2)
+{
+    int64_t ts1 = ev1->ts_trans, ts2 = ev1->ts_next;
+    /* (ts1 + ts2) / 2 without overflow */
+    int64_t tsmid = (ts1 >> 1) + (ts2 >> 1) + (ts1 & ts2 & 1);
+    enum sbg_fade_type type = ev1->fade.slide | (ev1->fade.out & ev2->fade.in);
+    int nb_elements = FFMAX(ev1->nb_elements, ev2->nb_elements);
+    struct sbg_script_synth *s1, *s2, s1mod, s2mod, smid;
+    int pass, i, r;
+
+    for (pass = 0; pass < 2; pass++) {
+        /* pass = 0 -> compatible and first half of incompatible
+           pass = 1 -> second half of incompatible
+           Using two passes like that ensures that the intervals are generated
+           in increasing order according to their start timestamp.
+           Otherwise it would be necessary to sort them
+           while keeping the mutual references.
+         */
+        for (i = 0; i < nb_elements; i++) {
+            s1 = i < ev1->nb_elements ? &s->synth[ev1->elements + i] : &s1mod;
+            s2 = i < ev2->nb_elements ? &s->synth[ev2->elements + i] : &s2mod;
+            s1mod = s1 != &s1mod ? *s1 : (struct sbg_script_synth){ 0 };
+            s2mod = s2 != &s2mod ? *s2 : (struct sbg_script_synth){ 0 };
+            if (ev1->fade.slide) {
+                /* for slides, and only for slides, silence ("-") is equivalent
+                   to anything with volume 0 */
+                if (s1mod.type == SBG_TYPE_NONE) {
+                    s1mod = s2mod;
+                    s1mod.vol = 0;
+                } else if (s2mod.type == SBG_TYPE_NONE) {
+                    s2mod = s1mod;
+                    s2mod.vol = 0;
+                }
+            }
+            if (s1mod.type == s2mod.type &&
+                s1mod.type != SBG_TYPE_BELL &&
+                (type == SBG_FADE_ADAPT ||
+                 (s1mod.carrier == s2mod.carrier &&
+                  s1mod.beat == s2mod.beat))) {
+                /* compatible: single transition */
+                if (!pass) {
+                    r = generate_interval(log, s, inter,
+                                          ts1, ts2, &s1mod, &s2mod, 3);
+                    if (r < 0)
+                        return r;
+                    s2->ref = s2mod.ref;
+                }
+            } else {
+                /* incompatible: silence at midpoint */
+                if (!pass) {
+                    smid = s1mod;
+                    smid.vol = 0;
+                    r = generate_interval(log, s, inter,
+                                          ts1, tsmid, &s1mod, &smid, 1);
+                    if (r < 0)
+                        return r;
+                } else {
+                    smid = s2mod;
+                    smid.vol = 0;
+                    r = generate_interval(log, s, inter,
+                                          tsmid, ts2, &smid, &s2mod, 2);
+                    if (r < 0)
+                        return r;
+                    s2->ref = s2mod.ref;
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+/*
+    ev1                  trats ev2  intts           endts ev3
+     |                     |    |     |               |    |
+     v                     v    v     v               v    v
+                                      ________________
+....                              ....                ....
+    '''....________________....'''                        '''...._______________
+
+\_________/\______________/\_________/\______________/\_________/\_____________/
+  tr x->1        int1        tr 1->2        int2        tr 2->3        int3
+ */
+
+static int generate_intervals(void *log, struct sbg_script *s, int sample_rate,
+                              struct ws_intervals *inter)
+{
+    int64_t trans_time = s->opt_fade_time / 2;
+    struct sbg_script_event ev0, *ev1, *ev2;
+    int64_t period;
+    int i, r;
+
+    /* SBaGen handles the time before and after the extremal events,
+       and the corresponding transitions, as if the sequence were cyclic
+       with a 24-hours period. */
+    period = s->events[s->nb_events - 1].ts - s->events[0].ts;
+    period = (period + (DAY_TS - 1)) / DAY_TS * DAY_TS;
+    period = FFMAX(period, DAY_TS);
+
+    /* Prepare timestamps for transitions */
+    for (i = 0; i < s->nb_events; i++) {
+        ev1 = &s->events[i];
+        ev2 = &s->events[(i + 1) % s->nb_events];
+        ev1->ts_int   = ev1->ts;
+        ev1->ts_trans = ev1->fade.slide ? ev1->ts
+                                        : ev2->ts + (ev1 < ev2 ? 0 : period);
+    }
+    for (i = 0; i < s->nb_events; i++) {
+        ev1 = &s->events[i];
+        ev2 = &s->events[(i + 1) % s->nb_events];
+        if (!ev1->fade.slide) {
+            ev1->ts_trans = FFMAX(ev1->ts_int,   ev1->ts_trans - trans_time);
+            ev2->ts_int   = FFMIN(ev2->ts_trans, ev2->ts_int   + trans_time);
+        }
+        ev1->ts_next  = ev2->ts_int + (ev1 < ev2 ? 0 : period);
+    }
+
+    /* Pseudo event before the first one */
+    ev0 = s->events[s->nb_events - 1];
+    ev0.ts_int   -= period;
+    ev0.ts_trans -= period;
+    ev0.ts_next  -= period;
+
+    /* Convert timestamps */
+    for (i = -1; i < s->nb_events; i++) {
+        ev1 = i < 0 ? &ev0 : &s->events[i];
+        ev1->ts_int   = av_rescale(ev1->ts_int,   sample_rate, AV_TIME_BASE);
+        ev1->ts_trans = av_rescale(ev1->ts_trans, sample_rate, AV_TIME_BASE);
+        ev1->ts_next  = av_rescale(ev1->ts_next,  sample_rate, AV_TIME_BASE);
+    }
+
+    /* Generate intervals */
+    for (i = 0; i < s->nb_synth; i++)
+        s->synth[i].ref.l = s->synth[i].ref.r = -1;
+    for (i = -1; i < s->nb_events; i++) {
+        ev1 = i < 0 ? &ev0 : &s->events[i];
+        ev2 = &s->events[(i + 1) % s->nb_events];
+        r = generate_plateau(log, s, inter, ev1);
+        if (r < 0)
+            return r;
+        r = generate_transition(log, s, inter, ev1, ev2);
+        if (r < 0)
+            return r;
+    }
+    if (!inter->nb_inter)
+        av_log(log, AV_LOG_WARNING, "Completely silent script.\n");
+    return 0;
+}
+
+static int encode_intervals(struct sbg_script *s, AVCodecContext *avc,
+                            struct ws_intervals *inter)
+{
+    int i, edata_size = 4;
+    uint8_t *edata;
+
+    for (i = 0; i < inter->nb_inter; i++) {
+        edata_size += inter->inter[i].type == WS_SINE  ? 44 :
+                      inter->inter[i].type == WS_NOISE ? 32 : 0;
+        if (edata_size < 0)
+            return AVERROR(ENOMEM);
+    }
+    edata = av_malloc(edata_size);
+    if (!edata)
+        return AVERROR(ENOMEM);
+    avc->extradata = edata;
+    avc->extradata_size = edata_size;
+
+#define ADD_EDATA32(v) do { AV_WL32(edata, (v)); edata += 4; } while(0)
+#define ADD_EDATA64(v) do { AV_WL64(edata, (v)); edata += 8; } while(0)
+    ADD_EDATA32(inter->nb_inter);
+    for (i = 0; i < inter->nb_inter; i++) {
+        ADD_EDATA64(inter->inter[i].ts1);
+        ADD_EDATA64(inter->inter[i].ts2);
+        ADD_EDATA32(inter->inter[i].type);
+        ADD_EDATA32(inter->inter[i].channels);
+        switch (inter->inter[i].type) {
+            case WS_SINE:
+                ADD_EDATA32(inter->inter[i].f1);
+                ADD_EDATA32(inter->inter[i].f2);
+                ADD_EDATA32(inter->inter[i].a1);
+                ADD_EDATA32(inter->inter[i].a2);
+                ADD_EDATA32(inter->inter[i].phi);
+                break;
+            case WS_NOISE:
+                ADD_EDATA32(inter->inter[i].a1);
+                ADD_EDATA32(inter->inter[i].a2);
+                break;
+        }
+    }
+    if (edata != avc->extradata + edata_size)
+        return AVERROR_BUG;
+    return 0;
+}
+
+static av_cold int sbg_read_probe(AVProbeData *p)
+{
+    int r, score;
+    struct sbg_script script = { 0 };
+
+    r = parse_script(NULL, p->buf, p->buf_size, &script);
+    score = r < 0 || !script.nb_def || !script.nb_tseq ? 0 :
+            AVPROBE_SCORE_MAX / 3;
+    free_script(&script);
+    return score;
+}
+
+static av_cold int sbg_read_header(AVFormatContext *avf)
+{
+    struct sbg_demuxer *sbg = avf->priv_data;
+    int r;
+    char *buf = NULL;
+    struct sbg_script script = { 0 };
+    AVStream *st;
+    struct ws_intervals inter = { 0 };
+
+    r = read_whole_file(avf->pb, sbg->max_file_size, &buf);
+    if (r < 0)
+        goto fail;
+    r = parse_script(avf, buf, r, &script);
+    if (r < 0)
+        goto fail;
+    if (!sbg->sample_rate)
+        sbg->sample_rate = script.sample_rate;
+    else
+        script.sample_rate = sbg->sample_rate;
+    if (!sbg->frame_size)
+        sbg->frame_size = FFMAX(1, sbg->sample_rate / 10);
+    if (script.opt_mix)
+        av_log(avf, AV_LOG_WARNING, "Mix feature not implemented: "
+               "-m is ignored and mix channels will be silent.\n");
+    r = expand_script(avf, &script);
+    if (r < 0)
+        goto fail;
+    av_freep(&buf);
+    r = generate_intervals(avf, &script, sbg->sample_rate, &inter);
+    if (r < 0)
+        goto fail;
+
+    st = avformat_new_stream(avf, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+    st->codec->codec_type     = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id       = AV_CODEC_ID_FFWAVESYNTH;
+    st->codec->channels       = 2;
+    st->codec->channel_layout = AV_CH_LAYOUT_STEREO;
+    st->codec->sample_rate    = sbg->sample_rate;
+    st->codec->frame_size     = sbg->frame_size;
+    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+    st->probe_packets = 0;
+    st->start_time    = av_rescale(script.start_ts,
+                                   sbg->sample_rate, AV_TIME_BASE);
+    st->duration      = script.end_ts == AV_NOPTS_VALUE ? AV_NOPTS_VALUE :
+                        av_rescale(script.end_ts - script.start_ts,
+                                   sbg->sample_rate, AV_TIME_BASE);
+    st->cur_dts       = st->start_time;
+    r = encode_intervals(&script, st->codec, &inter);
+    if (r < 0)
+        goto fail;
+
+    av_free(inter.inter);
+    free_script(&script);
+    return 0;
+
+fail:
+    av_free(inter.inter);
+    free_script(&script);
+    av_free(buf);
+    return r;
+}
+
+static int sbg_read_packet(AVFormatContext *avf, AVPacket *packet)
+{
+    int64_t ts, end_ts;
+
+    ts = avf->streams[0]->cur_dts;
+    end_ts = ts + avf->streams[0]->codec->frame_size;
+    if (avf->streams[0]->duration != AV_NOPTS_VALUE)
+        end_ts = FFMIN(avf->streams[0]->start_time + avf->streams[0]->duration,
+                       end_ts);
+    if (end_ts <= ts)
+        return AVERROR_EOF;
+    if (av_new_packet(packet, 12) < 0)
+        return AVERROR(ENOMEM);
+    packet->dts = packet->pts = ts;
+    packet->duration = end_ts - ts;
+    AV_WL64(packet->data + 0, ts);
+    AV_WL32(packet->data + 8, packet->duration);
+    return packet->size;
+}
+
+static int sbg_read_seek2(AVFormatContext *avf, int stream_index,
+                          int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+    if (flags || stream_index > 0)
+        return AVERROR(EINVAL);
+    if (stream_index < 0)
+        ts = av_rescale_q(ts, AV_TIME_BASE_Q, avf->streams[0]->time_base);
+    avf->streams[0]->cur_dts = ts;
+    return 0;
+}
+
+static int sbg_read_seek(AVFormatContext *avf, int stream_index,
+                         int64_t ts, int flags)
+{
+    return sbg_read_seek2(avf, stream_index, ts, ts, ts, 0);
+}
+
+static const AVOption sbg_options[] = {
+    { "sample_rate", "", offsetof(struct sbg_demuxer, sample_rate),
+      AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX,
+      AV_OPT_FLAG_DECODING_PARAM },
+    { "frame_size", "", offsetof(struct sbg_demuxer, frame_size),
+      AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX,
+      AV_OPT_FLAG_DECODING_PARAM },
+    { "max_file_size", "", offsetof(struct sbg_demuxer, max_file_size),
+      AV_OPT_TYPE_INT, { .i64 = 5000000 }, 0, INT_MAX,
+      AV_OPT_FLAG_DECODING_PARAM },
+    { NULL },
+};
+
+static const AVClass sbg_demuxer_class = {
+    .class_name = "sbg_demuxer",
+    .item_name  = av_default_item_name,
+    .option     = sbg_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_sbg_demuxer = {
+    .name           = "sbg",
+    .long_name      = NULL_IF_CONFIG_SMALL("SBaGen binaural beats script"),
+    .priv_data_size = sizeof(struct sbg_demuxer),
+    .read_probe     = sbg_read_probe,
+    .read_header    = sbg_read_header,
+    .read_packet    = sbg_read_packet,
+    .read_seek      = sbg_read_seek,
+    .read_seek2     = sbg_read_seek2,
+    .extensions     = "sbg",
+    .priv_class     = &sbg_demuxer_class,
+};
diff --git a/libavformat/sdp.c b/libavformat/sdp.c
index 0f7eb2f..ca8c3df 100644
--- a/libavformat/sdp.c
+++ b/libavformat/sdp.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2007 Luca Abeni
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -438,7 +438,7 @@
                                      payload_type, config ? config : "");
             break;
         case AV_CODEC_ID_AAC:
-            if (fmt && fmt->oformat->priv_class &&
+            if (fmt && fmt->oformat && fmt->oformat->priv_class &&
                 av_opt_flag_is_set(fmt->priv_data, "rtpflags", "latm")) {
                 config = latm_context2config(c);
                 if (!config)
diff --git a/libavformat/seek-test.c b/libavformat/seek-test.c
index 57d3fa4..49ac3ac 100644
--- a/libavformat/seek-test.c
+++ b/libavformat/seek-test.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2003 Fabrice Bellard
  * Copyright (c) 2007 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -48,13 +48,12 @@
 
 static void ts_str(char buffer[60], int64_t ts, AVRational base)
 {
-    double tsval;
     if (ts == AV_NOPTS_VALUE) {
         strcpy(buffer, " NOPTS   ");
         return;
     }
-    tsval = ts * av_q2d(base);
-    snprintf(buffer, 60, "%9f", tsval);
+    ts= av_rescale_q(ts, base, (AVRational){1, 1000000});
+    snprintf(buffer, 60, "%c%"PRId64".%06"PRId64"", ts<0 ? '-' : ' ', FFABS(ts)/1000000, FFABS(ts)%1000000);
 }
 
 int main(int argc, char **argv)
@@ -62,8 +61,25 @@
     const char *filename;
     AVFormatContext *ic = NULL;
     int i, ret, stream_id;
+    int j;
     int64_t timestamp;
     AVDictionary *format_opts = NULL;
+    int64_t seekfirst = AV_NOPTS_VALUE;
+    int firstback=0;
+    int frame_count = 1;
+
+    for(i=2; i<argc; i+=2){
+        if       (!strcmp(argv[i], "-seekforw")){
+            seekfirst = atoi(argv[i+1]);
+        } else if(!strcmp(argv[i], "-seekback")){
+            seekfirst = atoi(argv[i+1]);
+            firstback = 1;
+        } else if(!strcmp(argv[i], "-frames")){
+            frame_count = atoi(argv[i+1]);
+        } else {
+            argc = 1;
+        }
+    }
 
     av_dict_set(&format_opts, "channels", "1", 0);
     av_dict_set(&format_opts, "sample_rate", "22050", 0);
@@ -71,7 +87,7 @@
     /* initialize libavcodec, and register all codecs and formats */
     av_register_all();
 
-    if (argc != 2) {
+    if (argc < 2) {
         printf("usage: %s input_file\n"
                "\n", argv[0]);
         return 1;
@@ -92,12 +108,17 @@
         return 1;
     }
 
+    if(seekfirst != AV_NOPTS_VALUE){
+        if(firstback)   avformat_seek_file(ic, -1, INT64_MIN, seekfirst, seekfirst, 0);
+        else            avformat_seek_file(ic, -1, seekfirst, seekfirst, INT64_MAX, 0);
+    }
     for(i=0; ; i++){
         AVPacket pkt = { 0 };
         AVStream *av_uninit(st);
         char ts_buf[60];
 
         if(ret>=0){
+            for(j=0; j<frame_count; j++) {
             ret= av_read_frame(ic, &pkt);
             if(ret>=0){
                 char dts_buf[60];
@@ -109,6 +130,7 @@
             } else
                 printf("ret:%s", ret_str(ret)); // necessary to avoid trailing whitespace
             printf("\n");
+            }
         }
 
         if(i>25) break;
diff --git a/libavformat/seek.c b/libavformat/seek.c
index 524cd87..0ae99eb 100644
--- a/libavformat/seek.c
+++ b/libavformat/seek.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Ivan Schreter
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/seek.h b/libavformat/seek.h
index e79d7bd..b27cb42 100644
--- a/libavformat/seek.h
+++ b/libavformat/seek.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2009 Ivan Schreter
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c
index 068d432..1be2c5d 100644
--- a/libavformat/segafilm.c
+++ b/libavformat/segafilm.c
@@ -2,20 +2,20 @@
  * Sega FILM Format (CPK) Demuxer
  * Copyright (c) 2003 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,6 +30,7 @@
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "internal.h"
+#include "avio_internal.h"
 
 #define FILM_TAG MKBETAG('F', 'I', 'L', 'M')
 #define FDSC_TAG MKBETAG('F', 'D', 'S', 'C')
@@ -266,6 +267,8 @@
         (film->audio_type != AV_CODEC_ID_ADPCM_ADX)) {
         /* stereo PCM needs to be interleaved */
 
+        if (ffio_limit(pb, sample->sample_size) != sample->sample_size)
+            return AVERROR(EIO);
         if (av_new_packet(pkt, sample->sample_size))
             return AVERROR(ENOMEM);
 
@@ -287,7 +290,7 @@
 
         left = 0;
         right = sample->sample_size / 2;
-        for (i = 0; i < sample->sample_size; ) {
+        for (i = 0; i + 1 + 2*(film->audio_bits != 8) < sample->sample_size; ) {
             if (film->audio_bits == 8) {
                 pkt->data[i++] = film->stereo_buffer[left++];
                 pkt->data[i++] = film->stereo_buffer[right++];
diff --git a/libavformat/segment.c b/libavformat/segment.c
index fd52835..b6697e0 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -1,5 +1,4 @@
 /*
- * Generic segmenter
  * Copyright (c) 2011, Luca Barbato
  *
  * This file is part of Libav.
@@ -19,40 +18,80 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+/**
+ * @file generic segmenter
+ * M3U8 specification can be find here:
+ * @url{http://tools.ietf.org/id/draft-pantos-http-live-streaming-08.txt}
+ */
+
 #include <float.h>
 
 #include "avformat.h"
 #include "internal.h"
 
+#include "libavutil/avassert.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "libavutil/avstring.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/mathematics.h"
 
+typedef enum {
+    LIST_TYPE_UNDEFINED = -1,
+    LIST_TYPE_FLAT = 0,
+    LIST_TYPE_CSV,
+    LIST_TYPE_M3U8,
+    LIST_TYPE_EXT, ///< deprecated
+    LIST_TYPE_NB,
+} ListType;
+
+
+#define SEGMENT_LIST_FLAG_CACHE 1
+#define SEGMENT_LIST_FLAG_LIVE  2
+
 typedef struct {
     const AVClass *class;  /**< Class for private options. */
-    int number;
+    int segment_idx;       ///< index of the segment file to write, starting from 0
+    int segment_idx_wrap;  ///< number after which the index wraps
+    int segment_count;     ///< number of segment files already written
     AVOutputFormat *oformat;
     AVFormatContext *avf;
-    char *format;          /**< Set by a private option. */
-    char *list;            /**< Set by a private option. */
-    int  list_type;        /**< Set by a private option. */
-    float time;            /**< Set by a private option. */
-    int  size;             /**< Set by a private option. */
-    int  wrap;             /**< Set by a private option. */
+    char *format;          ///< format to use for output segment files
+    char *list;            ///< filename for the segment list file
+    int   list_count;      ///< list counter
+    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 *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. */
-    int64_t offset_time;
-    int64_t recording_time;
     int has_video;
-    AVIOContext *pb;
+    double start_time, end_time;
 } SegmentContext;
 
-enum {
-    LIST_FLAT,
-    LIST_HLS
-};
+static void print_csv_escaped_str(AVIOContext *ctx, const char *str)
+{
+    int needs_quoting = !!str[strcspn(str, "\",\n\r")];
+
+    if (needs_quoting)
+        avio_w8(ctx, '"');
+
+    for (; *str; str++) {
+        if (*str == '"')
+            avio_w8(ctx, '"');
+        avio_w8(ctx, *str);
+    }
+    if (needs_quoting)
+        avio_w8(ctx, '"');
+}
 
 static int segment_mux_init(AVFormatContext *s)
 {
@@ -78,36 +117,6 @@
     return 0;
 }
 
-static int segment_hls_window(AVFormatContext *s, int last)
-{
-    SegmentContext *seg = s->priv_data;
-    int i, ret = 0;
-    char buf[1024];
-
-    if ((ret = avio_open2(&seg->pb, seg->list, AVIO_FLAG_WRITE,
-                              &s->interrupt_callback, NULL)) < 0)
-        goto fail;
-
-    avio_printf(seg->pb, "#EXTM3U\n");
-    avio_printf(seg->pb, "#EXT-X-VERSION:3\n");
-    avio_printf(seg->pb, "#EXT-X-TARGETDURATION:%d\n", (int)seg->time);
-    avio_printf(seg->pb, "#EXT-X-MEDIA-SEQUENCE:%d\n",
-                FFMAX(0, seg->number - seg->size));
-
-    for (i = FFMAX(0, seg->number - seg->size);
-         i < seg->number; i++) {
-        avio_printf(seg->pb, "#EXTINF:%d,\n", (int)seg->time);
-        av_get_frame_filename(buf, sizeof(buf), s->filename, i);
-        avio_printf(seg->pb, "%s\n", buf);
-    }
-
-    if (last)
-        avio_printf(seg->pb, "#EXT-X-ENDLIST\n");
-fail:
-    avio_closep(&seg->pb);
-    return ret;
-}
-
 static int segment_start(AVFormatContext *s, int write_header)
 {
     SegmentContext *c = s->priv_data;
@@ -122,12 +131,15 @@
         oc = c->avf;
     }
 
-    if (c->wrap)
-        c->number %= c->wrap;
+    if (c->segment_idx_wrap)
+        c->segment_idx %= c->segment_idx_wrap;
 
     if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
-                              s->filename, c->number++) < 0)
+                              s->filename, c->segment_idx++) < 0) {
+        av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->filename);
         return AVERROR(EINVAL);
+    }
+    c->segment_count++;
 
     if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
                           &s->interrupt_callback, NULL)) < 0)
@@ -144,18 +156,139 @@
     return 0;
 }
 
-static int segment_end(AVFormatContext *oc, int write_trailer)
+static int segment_list_open(AVFormatContext *s)
 {
+    SegmentContext *seg = s->priv_data;
+    int ret;
+
+    ret = avio_open2(&seg->list_pb, seg->list, AVIO_FLAG_WRITE,
+                     &s->interrupt_callback, NULL);
+    if (ret < 0)
+        return ret;
+    seg->list_max_segment_time = 0;
+
+    if (seg->list_type == LIST_TYPE_M3U8) {
+        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->list_count);
+        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);
+    }
+
+    return ret;
+}
+
+static void segment_list_close(AVFormatContext *s)
+{
+    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");
+    }
+    seg->list_count++;
+
+    avio_close(seg->list_pb);
+}
+
+static int segment_end(AVFormatContext *s, int write_trailer)
+{
+    SegmentContext *seg = s->priv_data;
+    AVFormatContext *oc = seg->avf;
     int ret = 0;
 
     av_write_frame(oc, NULL); /* Flush any buffered data (fragmented mp4) */
     if (write_trailer)
-        av_write_trailer(oc);
+        ret = av_write_trailer(oc);
+
+    if (ret < 0)
+        av_log(s, AV_LOG_ERROR, "Failure occurred when ending segment '%s'\n",
+               oc->filename);
+
+    if (seg->list) {
+        if (seg->list_size && !(seg->segment_count % seg->list_size)) {
+            segment_list_close(s);
+            if ((ret = segment_list_open(s)) < 0)
+                goto end;
+        }
+
+        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);
+    }
+
+end:
     avio_close(oc->pb);
 
     return ret;
 }
 
+static int parse_times(void *log_ctx, int64_t **times, int *nb_times,
+                       const char *times_str)
+{
+    char *p;
+    int i, ret = 0;
+    char *times_str1 = av_strdup(times_str);
+    char *saveptr = NULL;
+
+    if (!times_str1)
+        return AVERROR(ENOMEM);
+
+#define FAIL(err) ret = err; goto end
+
+    *nb_times = 1;
+    for (p = times_str1; *p; p++)
+        if (*p == ',')
+            (*nb_times)++;
+
+    *times = av_malloc(sizeof(**times) * *nb_times);
+    if (!*times) {
+        av_log(log_ctx, AV_LOG_ERROR, "Could not allocate forced times array\n");
+        FAIL(AVERROR(ENOMEM));
+    }
+
+    p = times_str1;
+    for (i = 0; i < *nb_times; i++) {
+        int64_t t;
+        char *tstr = av_strtok(p, ",", &saveptr);
+        av_assert0(tstr);
+        p = NULL;
+
+        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);
+            FAIL(AVERROR(EINVAL));
+        }
+        (*times)[i] = t;
+
+        /* check on monotonicity */
+        if (i && (*times)[i-1] > (*times)[i]) {
+            av_log(log_ctx, AV_LOG_ERROR,
+                   "Specified time %f is greater than the following time %f\n",
+                   (float)((*times)[i])/1000000, (float)((*times)[i-1])/1000000);
+            FAIL(AVERROR(EINVAL));
+        }
+    }
+
+end:
+    av_free(times_str1);
+    return ret;
+}
+
 static int open_null_ctx(AVIOContext **ctx)
 {
     int buf_size = 32768;
@@ -182,16 +315,59 @@
     AVFormatContext *oc = NULL;
     int ret, i;
 
-    seg->number = 0;
-    seg->offset_time = 0;
-    seg->recording_time = seg->time * 1000000;
+    seg->segment_count = 0;
     if (!seg->write_header_trailer)
         seg->individual_header_trailer = 0;
 
-    if (seg->list && seg->list_type != LIST_HLS)
-        if ((ret = avio_open2(&seg->pb, seg->list, AVIO_FLAG_WRITE,
-                              &s->interrupt_callback, NULL)) < 0)
+    if (seg->time_str && seg->times_str) {
+        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");
+        return AVERROR(EINVAL);
+    }
+
+    if (seg->times_str) {
+        if ((ret = parse_times(s, &seg->times, &seg->nb_times, seg->times_str)) < 0)
+            return ret;
+    } else {
+        /* set default value if not specified */
+        if (!seg->time_str)
+            seg->time_str = av_strdup("2");
+        if ((ret = av_parse_time(&seg->time, seg->time_str, 1)) < 0) {
+            av_log(s, AV_LOG_ERROR,
+                   "Invalid time duration specification '%s' for segment_time option\n",
+                   seg->time_str);
+            return ret;
+        }
+    }
+
+    if (seg->time_delta_str) {
+        if ((ret = av_parse_time(&seg->time_delta, seg->time_delta_str, 1)) < 0) {
+            av_log(s, AV_LOG_ERROR,
+                   "Invalid time duration specification '%s' for delta option\n",
+                   seg->time_delta_str);
+            return ret;
+        }
+    }
+
+    if (seg->list) {
+        if (seg->list_type == LIST_TYPE_UNDEFINED) {
+            if      (av_match_ext(seg->list, "csv" )) seg->list_type = LIST_TYPE_CSV;
+            else if (av_match_ext(seg->list, "ext" )) seg->list_type = LIST_TYPE_EXT;
+            else if (av_match_ext(seg->list, "m3u8")) seg->list_type = LIST_TYPE_M3U8;
+            else                                      seg->list_type = LIST_TYPE_FLAT;
+        }
+        if ((ret = segment_list_open(s)) < 0)
             goto fail;
+    }
+    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 +=
@@ -220,10 +396,11 @@
     oc = seg->avf;
 
     if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
-                              s->filename, seg->number++) < 0) {
+                              s->filename, seg->segment_idx++) < 0) {
         ret = AVERROR(EINVAL);
         goto fail;
     }
+    seg->segment_count++;
 
     if (seg->write_header_trailer) {
         if ((ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
@@ -239,6 +416,9 @@
         goto fail;
     }
 
+    if (oc->avoid_negative_ts > 0 && s->avoid_negative_ts < 0)
+        s->avoid_negative_ts = 1;
+
     if (!seg->write_header_trailer) {
         close_null_ctx(oc->pb);
         if ((ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE,
@@ -246,20 +426,10 @@
             goto fail;
     }
 
-    if (seg->list) {
-        if (seg->list_type == LIST_HLS) {
-            if ((ret = segment_hls_window(s, 0)) < 0)
-                goto fail;
-        } else {
-            avio_printf(seg->pb, "%s\n", oc->filename);
-            avio_flush(seg->pb);
-        }
-    }
-
 fail:
     if (ret) {
         if (seg->list)
-            avio_close(seg->pb);
+            segment_list_close(s);
         if (seg->avf)
             avformat_free_context(seg->avf);
     }
@@ -271,18 +441,26 @@
     SegmentContext *seg = s->priv_data;
     AVFormatContext *oc = seg->avf;
     AVStream *st = s->streams[pkt->stream_index];
-    int64_t end_pts = seg->recording_time * seg->number;
+    int64_t end_pts;
     int ret;
 
-    if ((seg->has_video && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) &&
+    if (seg->times) {
+        end_pts = seg->segment_count <= seg->nb_times ?
+            seg->times[seg->segment_count-1] : INT64_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, AV_TIME_BASE_Q) >= 0 &&
+                      end_pts-seg->time_delta, AV_TIME_BASE_Q) >= 0 &&
         pkt->flags & AV_PKT_FLAG_KEY) {
 
-        av_log(s, AV_LOG_DEBUG, "Next segment starts at %d %"PRId64"\n",
-               pkt->stream_index, pkt->pts);
+        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(oc, seg->individual_header_trailer);
+        ret = segment_end(s, seg->individual_header_trailer);
 
         if (!ret)
             ret = segment_start(s, seg->individual_header_trailer);
@@ -292,21 +470,10 @@
 
         oc = seg->avf;
 
-        if (seg->list) {
-            if (seg->list_type == LIST_HLS) {
-                if ((ret = segment_hls_window(s, 0)) < 0)
-                    goto fail;
-            } else {
-                avio_printf(seg->pb, "%s\n", oc->filename);
-                avio_flush(seg->pb);
-                if (seg->size && !(seg->number % seg->size)) {
-                    avio_closep(&seg->pb);
-                    if ((ret = avio_open2(&seg->pb, seg->list, AVIO_FLAG_WRITE,
-                                          &s->interrupt_callback, NULL)) < 0)
-                        goto fail;
-                }
-            }
-        }
+        seg->start_time = (double)pkt->pts * av_q2d(st->time_base);
+    } else if (pkt->pts != AV_NOPTS_VALUE) {
+        seg->end_time = FFMAX(seg->end_time,
+                              (double)(pkt->pts + pkt->duration) * av_q2d(st->time_base));
     }
 
     ret = ff_write_chained(oc, pkt->stream_index, pkt, s);
@@ -314,7 +481,7 @@
 fail:
     if (ret < 0) {
         if (seg->list)
-            avio_close(seg->pb);
+            avio_close(seg->list_pb);
         avformat_free_context(oc);
     }
 
@@ -327,25 +494,21 @@
     AVFormatContext *oc = seg->avf;
     int ret;
     if (!seg->write_header_trailer) {
-        if ((ret = segment_end(oc, 0)) < 0)
+        if ((ret = segment_end(s, 0)) < 0)
             goto fail;
         open_null_ctx(&oc->pb);
         ret = av_write_trailer(oc);
         close_null_ctx(oc->pb);
     } else {
-        ret = segment_end(oc, 1);
+        ret = segment_end(s, 1);
     }
-
-    if (ret < 0)
-        goto fail;
-
-    if (seg->list && seg->list_type == LIST_HLS) {
-        if ((ret = segment_hls_window(s, 1) < 0))
-            goto fail;
-    }
-
 fail:
-    avio_close(seg->pb);
+    if (seg->list)
+        segment_list_close(s);
+
+    av_opt_free(seg);
+    av_freep(&seg->times);
+
     avformat_free_context(oc);
     return ret;
 }
@@ -353,14 +516,24 @@
 #define OFFSET(x) offsetof(SegmentContext, x)
 #define E AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-    { "segment_format",    "container format used for the segments",  OFFSET(format),  AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E },
-    { "segment_time",      "segment length in seconds",               OFFSET(time),    AV_OPT_TYPE_FLOAT,  {.dbl = 2},     0, FLT_MAX, E },
-    { "segment_list",      "output the segment list",                 OFFSET(list),    AV_OPT_TYPE_STRING, {.str = NULL},  0, 0,       E },
-    { "segment_list_size", "maximum number of playlist entries",      OFFSET(size),    AV_OPT_TYPE_INT,    {.i64 = 5},     0, INT_MAX, E },
-    { "segment_list_type", "segment list format",                     OFFSET(list_type),    AV_OPT_TYPE_INT,    {.i64 = LIST_FLAT},     0, 2, E, "list_type" },
-    {   "flat",            "plain list (default)",                    0,               AV_OPT_TYPE_CONST,  {.i64 = LIST_FLAT}, 0, 0, E, "list_type" },
-    {   "hls",             "Apple HTTP Live Streaming compatible",    0,               AV_OPT_TYPE_CONST,  {.i64 = LIST_HLS},  0, 0, E, "list_type" },
-    { "segment_wrap",      "number after which the index wraps",      OFFSET(wrap),    AV_OPT_TYPE_INT,    {.i64 = 0},     0, INT_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 },
+
+    { "segment_list_flags","set flags affecting segment list generation", OFFSET(list_flags), AV_OPT_TYPE_FLAGS, {.i64 = SEGMENT_LIST_FLAG_CACHE }, 0, UINT_MAX, E, "list_flags"},
+    { "cache",             "allow list caching",                                    0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_LIST_FLAG_CACHE }, INT_MIN, INT_MAX,   E, "list_flags"},
+    { "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" },
+    { "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_wrap",      "set number after which the index wraps",     OFFSET(segment_idx_wrap), 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 },
     { NULL },
@@ -373,7 +546,6 @@
     .version    = LIBAVUTIL_VERSION_INT,
 };
 
-
 AVOutputFormat ff_segment_muxer = {
     .name           = "segment",
     .long_name      = NULL_IF_CONFIG_SMALL("segment"),
@@ -384,3 +556,21 @@
     .write_trailer  = seg_write_trailer,
     .priv_class     = &seg_class,
 };
+
+static const AVClass sseg_class = {
+    .class_name = "stream_segment muxer",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+AVOutputFormat ff_stream_segment_muxer = {
+    .name           = "stream_segment,ssegment",
+    .long_name      = NULL_IF_CONFIG_SMALL("streaming segment muxer"),
+    .priv_data_size = sizeof(SegmentContext),
+    .flags          = AVFMT_NOFILE,
+    .write_header   = seg_write_header,
+    .write_packet   = seg_write_packet,
+    .write_trailer  = seg_write_trailer,
+    .priv_class     = &sseg_class,
+};
diff --git a/libavformat/sierravmd.c b/libavformat/sierravmd.c
index 6490fdd..98aa5b8 100644
--- a/libavformat/sierravmd.c
+++ b/libavformat/sierravmd.c
@@ -2,20 +2,20 @@
  * Sierra VMD Format Demuxer
  * Copyright (c) 2004 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,6 +30,7 @@
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "internal.h"
+#include "avio_internal.h"
 
 #define VMD_HEADER_SIZE 0x0330
 #define BYTES_PER_FRAME_RECORD 16
@@ -245,6 +246,8 @@
     /* position the stream (will probably be there already) */
     avio_seek(pb, frame->frame_offset, SEEK_SET);
 
+    if(ffio_limit(pb, frame->frame_size) != frame->frame_size)
+        return AVERROR(EIO);
     if (av_new_packet(pkt, frame->frame_size + BYTES_PER_FRAME_RECORD))
         return AVERROR(ENOMEM);
     pkt->pos= avio_tell(pb);
diff --git a/libavformat/siff.c b/libavformat/siff.c
index 02af80b..26c3817 100644
--- a/libavformat/siff.c
+++ b/libavformat/siff.c
@@ -2,26 +2,27 @@
  * Beam Software SIFF demuxer
  * Copyright (c) 2007 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "internal.h"
+#include "avio_internal.h"
 
 enum SIFFTags{
     TAG_SIFF = MKTAG('S', 'I', 'F', 'F'),
@@ -201,13 +202,16 @@
         }
 
         if (!c->curstrm){
-            size = c->pktsize - c->sndsize;
-            if (av_new_packet(pkt, size) < 0)
+            size = c->pktsize - c->sndsize - c->gmcsize - 2;
+            size = ffio_limit(s->pb, size);
+            if(size < 0 || c->pktsize < c->sndsize)
+                return AVERROR_INVALIDDATA;
+            if (av_new_packet(pkt, size + c->gmcsize + 2) < 0)
                 return AVERROR(ENOMEM);
             AV_WL16(pkt->data, c->flags);
             if (c->gmcsize)
                 memcpy(pkt->data + 2, c->gmc, c->gmcsize);
-            avio_read(s->pb, pkt->data + 2 + c->gmcsize, size - c->gmcsize - 2);
+            avio_read(s->pb, pkt->data + 2 + c->gmcsize, size);
             pkt->stream_index = 0;
             c->curstrm = -1;
         }else{
diff --git a/libavformat/smacker.c b/libavformat/smacker.c
index dcca1af..829233f 100644
--- a/libavformat/smacker.c
+++ b/libavformat/smacker.c
@@ -2,20 +2,20 @@
  * Smacker demuxer
  * Copyright (c) 2006 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -203,7 +203,7 @@
 
 
     /* load trees to extradata, they will be unpacked by decoder */
-    st->codec->extradata = av_malloc(smk->treesize + 16);
+    st->codec->extradata = av_malloc(smk->treesize + 16 + FF_INPUT_BUFFER_PADDING_SIZE);
     st->codec->extradata_size = smk->treesize + 16;
     if(!st->codec->extradata){
         av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16);
@@ -238,7 +238,7 @@
     int frame_size = 0;
     int palchange = 0;
 
-    if (s->pb->eof_reached || smk->cur_frame >= smk->frames)
+    if (url_feof(s->pb) || smk->cur_frame >= smk->frames)
         return AVERROR_EOF;
 
     /* if we demuxed all streams, pass another frame */
@@ -255,6 +255,8 @@
             memcpy(oldpal, pal, 768);
             size = avio_r8(s->pb);
             size = size * 4 - 1;
+            if(size + 1 > frame_size)
+                return AVERROR_INVALIDDATA;
             frame_size -= size;
             frame_size--;
             sz = 0;
@@ -296,10 +298,12 @@
         /* if audio chunks are present, put them to stack and retrieve later */
         for(i = 0; i < 7; i++) {
             if(flags & 1) {
-                int size;
+                unsigned int size;
                 uint8_t *tmpbuf;
 
                 size = avio_rl32(s->pb) - 4;
+                if(size + 4L > frame_size)
+                    return AVERROR_INVALIDDATA;
                 frame_size -= size;
                 frame_size -= 4;
                 smk->curstream++;
@@ -359,7 +363,7 @@
 
 AVInputFormat ff_smacker_demuxer = {
     .name           = "smk",
-    .long_name      = NULL_IF_CONFIG_SMALL("Smacker video"),
+    .long_name      = NULL_IF_CONFIG_SMALL("Smacker"),
     .priv_data_size = sizeof(SmackerContext),
     .read_probe     = smacker_probe,
     .read_header    = smacker_read_header,
diff --git a/libavformat/smjpeg.c b/libavformat/smjpeg.c
index 52e45e9..4edf5e8 100644
--- a/libavformat/smjpeg.c
+++ b/libavformat/smjpeg.c
@@ -2,20 +2,20 @@
  * SMJPEG common code
  * Copyright (c) 2011-2012 Paul B Mahol
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/smjpeg.h b/libavformat/smjpeg.h
index c56fe46..995ddf2 100644
--- a/libavformat/smjpeg.h
+++ b/libavformat/smjpeg.h
@@ -2,20 +2,20 @@
  * SMJPEG common code
  * Copyright (c) 2011-2012 Paul B Mahol
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/smjpegdec.c b/libavformat/smjpegdec.c
index 7764c0f..d1aad9f 100644
--- a/libavformat/smjpegdec.c
+++ b/libavformat/smjpegdec.c
@@ -2,20 +2,20 @@
  * SMJPEG demuxer
  * Copyright (c) 2011 Paul B Mahol
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/smjpegenc.c b/libavformat/smjpegenc.c
index 59ede7a..6dbc286 100644
--- a/libavformat/smjpegenc.c
+++ b/libavformat/smjpegenc.c
@@ -2,20 +2,20 @@
  * SMJPEG muxer
  * Copyright (c) 2012 Paul B Mahol
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c
index 69d555f..df7522e 100644
--- a/libavformat/smoothstreamingenc.c
+++ b/libavformat/smoothstreamingenc.c
@@ -2,20 +2,20 @@
  * Live smooth streaming fragmenter
  * Copyright (c) 2012 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/smush.c b/libavformat/smush.c
new file mode 100644
index 0000000..b164c75
--- /dev/null
+++ b/libavformat/smush.c
@@ -0,0 +1,238 @@
+/*
+ * LucasArts Smush demuxer
+ * Copyright (c) 2006 Cyril Zorin
+ *
+ * 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 "avio.h"
+
+typedef struct {
+    int version;
+    int audio_stream_index;
+    int video_stream_index;
+} SMUSHContext;
+
+static int smush_read_probe(AVProbeData *p)
+{
+    if ((AV_RL32(p->buf) == MKTAG('S', 'A', 'N', 'M') ||
+         AV_RL32(p->buf) == MKTAG('A', 'N', 'I', 'M'))) {
+        return AVPROBE_SCORE_MAX;
+    }
+
+    return 0;
+}
+
+static int smush_read_header(AVFormatContext *ctx)
+{
+    SMUSHContext *smush = ctx->priv_data;
+    AVIOContext *pb = ctx->pb;
+    AVStream *vst, *ast;
+    uint32_t magic, nframes, size, subversion, i;
+    uint32_t width = 0, height = 0, got_audio = 0, read = 0;
+    uint32_t sample_rate, channels, palette[256];
+
+    magic = avio_rb32(pb);
+    avio_skip(pb, 4); // skip movie size
+
+    if (magic == MKBETAG('A', 'N', 'I', 'M')) {
+        if (avio_rb32(pb) != MKBETAG('A', 'H', 'D', 'R'))
+            return AVERROR_INVALIDDATA;
+
+        size = avio_rb32(pb);
+        if (size < 3 * 256 + 6)
+            return AVERROR_INVALIDDATA;
+
+        smush->version = 0;
+        subversion     = avio_rl16(pb);
+        nframes        = avio_rl16(pb);
+
+        avio_skip(pb, 2); // skip pad
+
+        for (i = 0; i < 256; i++)
+            palette[i] = avio_rb24(pb);
+
+        avio_skip(pb, size - (3 * 256 + 6));
+    } else if (magic == MKBETAG('S', 'A', 'N', 'M') ) {
+        if (avio_rb32(pb) != MKBETAG('S', 'H', 'D', 'R'))
+            return AVERROR_INVALIDDATA;
+
+        size = avio_rb32(pb);
+        if (size < 14)
+            return AVERROR_INVALIDDATA;
+
+        smush->version = 1;
+        subversion     = avio_rl16(pb);
+        nframes = avio_rl32(pb);
+        avio_skip(pb, 2); // skip pad
+        width  = avio_rl16(pb);
+        height = avio_rl16(pb);
+        avio_skip(pb, 2); // skip pad
+        avio_skip(pb, size - 14);
+
+        if (avio_rb32(pb) != MKBETAG('F', 'L', 'H', 'D'))
+            return AVERROR_INVALIDDATA;
+
+        size = avio_rb32(pb);
+        while (!got_audio && ((read + 8) < size)) {
+            uint32_t sig, chunk_size;
+
+            if (url_feof(pb))
+                return AVERROR_EOF;
+
+            sig        = avio_rb32(pb);
+            chunk_size = avio_rb32(pb);
+            read += 8;
+            switch (sig) {
+            case MKBETAG('W', 'a', 'v', 'e'):
+                got_audio = 1;
+                sample_rate = avio_rl32(pb);
+                channels    = avio_rl32(pb);
+                avio_skip(pb, chunk_size - 8);
+                read += chunk_size;
+                break;
+            case MKBETAG('B', 'l', '1', '6'):
+            case MKBETAG('A', 'N', 'N', 'O'):
+                avio_skip(pb, chunk_size);
+                read += chunk_size;
+                break;
+            default:
+                return AVERROR_INVALIDDATA;
+                break;
+            }
+        }
+
+        avio_skip(pb, size - read);
+    } else {
+        av_log(ctx, AV_LOG_ERROR, "Wrong magic\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    vst = avformat_new_stream(ctx, 0);
+    if (!vst)
+        return AVERROR(ENOMEM);
+
+    smush->video_stream_index = vst->index;
+
+    vst->start_time        = 0;
+    vst->duration          =
+    vst->nb_frames         = nframes;
+    vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+    vst->codec->codec_id   = AV_CODEC_ID_SANM;
+    vst->codec->codec_tag  = 0;
+    vst->codec->width      = width;
+    vst->codec->height     = height;
+
+    avpriv_set_pts_info(vst, 64, 66667, 1000000);
+
+    if (!smush->version) {
+        vst->codec->extradata = av_malloc(1024 + 2 + FF_INPUT_BUFFER_PADDING_SIZE);
+        if (!vst->codec->extradata)
+            return AVERROR(ENOMEM);
+
+        vst->codec->extradata_size = 1024 + 2;
+        AV_WL16(vst->codec->extradata, subversion);
+        for (i = 0; i < 256; i++)
+            AV_WL32(vst->codec->extradata + 2 + i * 4, palette[i]);
+    }
+
+    if (got_audio) {
+        ast = avformat_new_stream(ctx, 0);
+        if (!ast)
+            return AVERROR(ENOMEM);
+
+        smush->audio_stream_index = ast->index;
+
+        ast->start_time         = 0;
+        ast->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
+        ast->codec->codec_id    = AV_CODEC_ID_VIMA;
+        ast->codec->codec_tag   = 0;
+        ast->codec->sample_rate = sample_rate;
+        ast->codec->channels    = channels;
+
+        avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
+    }
+
+    return 0;
+}
+
+static int smush_read_packet(AVFormatContext *ctx, AVPacket *pkt)
+{
+    SMUSHContext *smush = ctx->priv_data;
+    AVIOContext *pb = ctx->pb;
+    int done = 0;
+
+    while (!done) {
+        uint32_t sig, size;
+
+        if (url_feof(pb))
+            return AVERROR_EOF;
+
+        sig    = avio_rb32(pb);
+        size   = avio_rb32(pb);
+
+        switch (sig) {
+        case MKBETAG('F', 'R', 'M', 'E'):
+            if (smush->version)
+                break;
+            if (av_get_packet(pb, pkt, size) < 0)
+                return AVERROR(EIO);
+
+            pkt->stream_index = smush->video_stream_index;
+            done = 1;
+            break;
+        case MKBETAG('B', 'l', '1', '6'):
+            if (av_get_packet(pb, pkt, size) < 0)
+                return AVERROR(EIO);
+
+            pkt->stream_index = smush->video_stream_index;
+            pkt->duration = 1;
+            done = 1;
+            break;
+        case MKBETAG('W', 'a', 'v', 'e'):
+            if (size < 13)
+                return AVERROR_INVALIDDATA;
+            if (av_get_packet(pb, pkt, size) < 0)
+                return AVERROR(EIO);
+
+            pkt->stream_index = smush->audio_stream_index;
+            pkt->flags       |= AV_PKT_FLAG_KEY;
+            pkt->duration = AV_RB32(pkt->data);
+            if (pkt->duration == 0xFFFFFFFFu)
+                pkt->duration = AV_RB32(pkt->data + 8);
+            done = 1;
+            break;
+        default:
+            avio_skip(pb, size);
+            break;
+        }
+    }
+
+    return 0;
+}
+
+AVInputFormat ff_smush_demuxer = {
+    .name           = "smush",
+    .long_name      = NULL_IF_CONFIG_SMALL("LucasArts Smush"),
+    .priv_data_size = sizeof(SMUSHContext),
+    .read_probe     = smush_read_probe,
+    .read_header    = smush_read_header,
+    .read_packet    = smush_read_packet,
+};
diff --git a/libavformat/sol.c b/libavformat/sol.c
index da84600..aca5a86 100644
--- a/libavformat/sol.c
+++ b/libavformat/sol.c
@@ -2,20 +2,20 @@
  * Sierra SOL demuxer
  * Copyright Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -128,16 +128,13 @@
 {
     int ret;
 
-    if (s->pb->eof_reached)
+    if (url_feof(s->pb))
         return AVERROR(EIO);
     ret= av_get_packet(s->pb, pkt, MAX_SIZE);
     if (ret < 0)
         return ret;
+    pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
     pkt->stream_index = 0;
-
-    /* note: we need to modify the packet size here to handle the last
-       packet */
-    pkt->size = ret;
     return 0;
 }
 
diff --git a/libavformat/sox.h b/libavformat/sox.h
index e59531b..f4a12e9 100644
--- a/libavformat/sox.h
+++ b/libavformat/sox.h
@@ -2,20 +2,20 @@
  * SoX native format common data
  * Copyright (c) 2009 Daniel Verkamp <daniel@drv.nu>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/soxdec.c b/libavformat/soxdec.c
index ec94675..4c951bb 100644
--- a/libavformat/soxdec.c
+++ b/libavformat/soxdec.c
@@ -5,20 +5,20 @@
  * Based on libSoX sox-fmt.c
  * Copyright (c) 2008 robs@users.sourceforge.net
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -97,6 +97,8 @@
 
     if (comment_size && comment_size < UINT_MAX) {
         char *comment = av_malloc(comment_size+1);
+        if(!comment)
+            return AVERROR(ENOMEM);
         if (avio_read(pb, comment, comment_size) != comment_size) {
             av_freep(&comment);
             return AVERROR(EIO);
@@ -129,15 +131,15 @@
 {
     int ret, size;
 
-    if (s->pb->eof_reached)
+    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;
-    pkt->size = ret;
 
     return 0;
 }
diff --git a/libavformat/soxenc.c b/libavformat/soxenc.c
index 3e5d2e3..6b4412d 100644
--- a/libavformat/soxenc.c
+++ b/libavformat/soxenc.c
@@ -5,20 +5,20 @@
  * Based on libSoX sox-fmt.c
  * Copyright (c) 2008 robs@users.sourceforge.net
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/spdif.c b/libavformat/spdif.c
index 777ac47..604141a 100644
--- a/libavformat/spdif.c
+++ b/libavformat/spdif.c
@@ -2,20 +2,20 @@
  * IEC 61937 common code
  * Copyright (c) 2009 Bartlomiej Wolowiec
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/spdif.h b/libavformat/spdif.h
index b2a6b63..4b11de2 100644
--- a/libavformat/spdif.h
+++ b/libavformat/spdif.h
@@ -2,20 +2,20 @@
  * IEC 61937 common header
  * Copyright (c) 2009 Bartlomiej Wolowiec
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/spdifdec.c b/libavformat/spdifdec.c
index cecf101..dce3346 100644
--- a/libavformat/spdifdec.c
+++ b/libavformat/spdifdec.c
@@ -2,20 +2,20 @@
  * IEC 61937 demuxer
  * Copyright (c) 2010 Anssi Hannula <anssi.hannula at iki.fi>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -171,7 +171,7 @@
 
     while (state != (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))) {
         state = (state << 8) | avio_r8(pb);
-        if (pb->eof_reached)
+        if (url_feof(pb))
             return AVERROR_EOF;
     }
 
diff --git a/libavformat/spdifenc.c b/libavformat/spdifenc.c
index 77af92e..bb0c363 100644
--- a/libavformat/spdifenc.c
+++ b/libavformat/spdifenc.c
@@ -4,20 +4,20 @@
  * Copyright (c) 2010 Anssi Hannula
  * Copyright (c) 2010 Carl Eugen Hoyos
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -520,13 +520,13 @@
     }
 
     if (ctx->extra_bswap ^ (ctx->spdif_flags & SPDIF_FLAG_BIGENDIAN)) {
-    avio_write(s->pb, ctx->out_buf, ctx->out_bytes & ~1);
+        avio_write(s->pb, ctx->out_buf, ctx->out_bytes & ~1);
     } else {
-    av_fast_malloc(&ctx->buffer, &ctx->buffer_size, ctx->out_bytes + FF_INPUT_BUFFER_PADDING_SIZE);
-    if (!ctx->buffer)
-        return AVERROR(ENOMEM);
-    ff_spdif_bswap_buf16((uint16_t *)ctx->buffer, (uint16_t *)ctx->out_buf, ctx->out_bytes >> 1);
-    avio_write(s->pb, ctx->buffer, ctx->out_bytes & ~1);
+        av_fast_malloc(&ctx->buffer, &ctx->buffer_size, ctx->out_bytes + FF_INPUT_BUFFER_PADDING_SIZE);
+        if (!ctx->buffer)
+            return AVERROR(ENOMEM);
+        ff_spdif_bswap_buf16((uint16_t *)ctx->buffer, (uint16_t *)ctx->out_buf, ctx->out_bytes >> 1);
+        avio_write(s->pb, ctx->buffer, ctx->out_bytes & ~1);
     }
 
     /* a final lone byte has to be MSB aligned */
diff --git a/libavformat/srtdec.c b/libavformat/srtdec.c
index 9db5133..a66ced3 100644
--- a/libavformat/srtdec.c
+++ b/libavformat/srtdec.c
@@ -2,20 +2,20 @@
  * SubRip subtitle demuxer
  * Copyright (c) 2010  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -44,23 +44,30 @@
 {
     AVStream *st = avformat_new_stream(s, NULL);
     if (!st)
-        return -1;
+        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_SRT;
     return 0;
 }
 
-static int64_t get_pts(const char *buf)
+static int64_t get_pts(const char *buf, int *duration)
 {
-    int i, v, hour, min, sec, hsec;
+    int i, hour, min, sec, hsec;
+    int he, me, se, mse;
 
     for (i=0; i<2; i++) {
-        if (sscanf(buf, "%d:%2d:%2d%*1[,.]%3d --> %*d:%*2d:%*2d%*1[,.]%3d",
-                   &hour, &min, &sec, &hsec, &v) == 5) {
+        int64_t start, end;
+        if (sscanf(buf, "%d:%2d:%2d%*1[,.]%3d --> %d:%2d:%2d%*1[,.]%3d",
+                   &hour, &min, &sec, &hsec, &he, &me, &se, &mse) == 8) {
             min += 60*hour;
             sec += 60*min;
-            return sec*1000+hsec;
+            start = sec*1000+hsec;
+            me += 60*he;
+            se += 60*me;
+            end = se*1000+mse;
+            *duration = end - start;
+            return start;
         }
         buf += strcspn(buf, "\n") + 1;
     }
@@ -81,13 +88,13 @@
     do {
         ptr2 = ptr;
         ptr += ff_get_line(s->pb, ptr, sizeof(buffer)+buffer-ptr);
-    } while (!is_eol(*ptr2) && !s->pb->eof_reached && ptr-buffer<sizeof(buffer)-1);
+    } while (!is_eol(*ptr2) && !url_feof(s->pb) && ptr-buffer<sizeof(buffer)-1);
 
     if (buffer[0] && !(res = av_new_packet(pkt, ptr-buffer))) {
         memcpy(pkt->data, buffer, pkt->size);
         pkt->flags |= AV_PKT_FLAG_KEY;
         pkt->pos = pos;
-        pkt->pts = pkt->dts = get_pts(pkt->data);
+        pkt->pts = pkt->dts = get_pts(pkt->data, &(pkt->duration));
     }
     return res;
 }
diff --git a/libavformat/srtenc.c b/libavformat/srtenc.c
new file mode 100644
index 0000000..0b094b0
--- /dev/null
+++ b/libavformat/srtenc.c
@@ -0,0 +1,101 @@
+/*
+ * SubRip subtitle muxer
+ * Copyright (c) 2012  Nicolas George <nicolas.george@normalesup.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 "avformat.h"
+#include "internal.h"
+#include "libavutil/log.h"
+
+/* TODO: add options for:
+   - character encoding;
+   - LF / CRLF;
+   - byte order mark.
+ */
+
+typedef struct SRTContext{
+    unsigned index;
+} SRTContext;
+
+static int srt_write_header(AVFormatContext *avf)
+{
+    if (avf->nb_streams != 1 ||
+        avf->streams[0]->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) {
+        av_log(avf, AV_LOG_ERROR,
+               "SRT supports only a single subtitles stream.\n");
+        return AVERROR(EINVAL);
+    }
+    if (avf->streams[0]->codec->codec_id != AV_CODEC_ID_TEXT &&
+        avf->streams[0]->codec->codec_id != AV_CODEC_ID_SUBRIP &&
+        avf->streams[0]->codec->codec_id != AV_CODEC_ID_SRT) {
+        av_log(avf, AV_LOG_ERROR,
+               "Unsupported subtitles codec: %s\n",
+               avcodec_get_name(avf->streams[0]->codec->codec_id));
+        return AVERROR(EINVAL);
+    }
+    avpriv_set_pts_info(avf->streams[0], 64, 1, 1000);
+    return 0;
+}
+
+static int srt_write_packet(AVFormatContext *avf, AVPacket *pkt)
+{
+    SRTContext *srt = avf->priv_data;
+    int write_ts = avf->streams[0]->codec->codec_id != AV_CODEC_ID_SRT;
+
+    srt->index++;
+    if (write_ts) {
+        char buf[64];
+        int64_t s = pkt->pts, e, d = pkt->duration;
+        int len;
+
+        if (d <= 0)
+            /* For backward compatibility, fallback to convergence_duration. */
+            d = pkt->convergence_duration;
+        if (s == AV_NOPTS_VALUE || d <= 0) {
+            av_log(avf, AV_LOG_ERROR, "Insufficient timestamps.\n");
+            return AVERROR(EINVAL);
+        }
+        e = s + d;
+        len = snprintf(buf, sizeof(buf),
+                       "%d\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n",
+                       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));
+        avio_write(avf->pb, buf, len);
+    }
+    avio_write(avf->pb, pkt->data, pkt->size);
+    if (write_ts)
+        avio_write(avf->pb, "\n\n", 2);
+    avio_flush(avf->pb);
+    return 0;
+}
+
+AVOutputFormat ff_srt_muxer = {
+    .name           = "srt",
+    .long_name      = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
+    .mime_type      = "application/x-subrip",
+    .extensions     = "srt",
+    .priv_data_size = sizeof(SRTContext),
+    .write_header   = srt_write_header,
+    .write_packet   = srt_write_packet,
+    .flags          = AVFMT_VARIABLE_FPS,
+    .subtitle_codec = AV_CODEC_ID_TEXT,
+};
diff --git a/libavformat/subtitles.c b/libavformat/subtitles.c
new file mode 100644
index 0000000..1204526
--- /dev/null
+++ b/libavformat/subtitles.c
@@ -0,0 +1,145 @@
+/*
+ * 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
+ */
+
+#include "avformat.h"
+#include "subtitles.h"
+#include "libavutil/avstring.h"
+
+AVPacket *ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q,
+                                    const uint8_t *event, int len, int merge)
+{
+    AVPacket *subs, *sub;
+
+    if (merge && q->nb_subs > 0) {
+        /* merge with previous event */
+
+        int old_len;
+        sub = &q->subs[q->nb_subs - 1];
+        old_len = sub->size;
+        if (av_grow_packet(sub, len) < 0)
+            return NULL;
+        memcpy(sub->data + old_len, event, len);
+    } else {
+        /* new event */
+
+        if (q->nb_subs >= INT_MAX/sizeof(*q->subs) - 1)
+            return NULL;
+        subs = av_fast_realloc(q->subs, &q->allocated_size,
+                               (q->nb_subs + 1) * sizeof(*q->subs));
+        if (!subs)
+            return NULL;
+        q->subs = subs;
+        sub = &subs[q->nb_subs++];
+        if (av_new_packet(sub, len) < 0)
+            return NULL;
+        sub->destruct = NULL;
+        sub->flags |= AV_PKT_FLAG_KEY;
+        sub->pts = sub->dts = 0;
+        memcpy(sub->data, event, len);
+    }
+    return sub;
+}
+
+static int cmp_pkt_sub(const void *a, const void *b)
+{
+    const AVPacket *s1 = a;
+    const AVPacket *s2 = b;
+    if (s1->pts == s2->pts) {
+        if (s1->pos == s2->pos)
+            return 0;
+        return s1->pos > s2->pos ? 1 : -1;
+    }
+    return s1->pts > s2->pts ? 1 : -1;
+}
+
+void ff_subtitles_queue_finalize(FFDemuxSubtitlesQueue *q)
+{
+    int i;
+
+    qsort(q->subs, q->nb_subs, sizeof(*q->subs), cmp_pkt_sub);
+    for (i = 0; i < q->nb_subs; i++)
+        if (q->subs[i].duration == -1 && i < q->nb_subs - 1)
+            q->subs[i].duration = q->subs[i + 1].pts - q->subs[i].pts;
+}
+
+int ff_subtitles_queue_read_packet(FFDemuxSubtitlesQueue *q, AVPacket *pkt)
+{
+    AVPacket *sub = q->subs + q->current_sub_idx;
+
+    if (q->current_sub_idx == q->nb_subs)
+        return AVERROR_EOF;
+    *pkt = *sub;
+    pkt->dts = pkt->pts;
+    q->current_sub_idx++;
+    return 0;
+}
+
+void ff_subtitles_queue_clean(FFDemuxSubtitlesQueue *q)
+{
+    int i;
+
+    for (i = 0; i < q->nb_subs; i++)
+        av_destruct_packet(&q->subs[i]);
+    av_freep(&q->subs);
+    q->nb_subs = q->allocated_size = q->current_sub_idx = 0;
+}
+
+int ff_smil_extract_next_chunk(AVIOContext *pb, AVBPrint *buf, char *c)
+{
+    int i = 0;
+    char end_chr;
+
+    if (!*c) // cached char?
+        *c = avio_r8(pb);
+    if (!*c)
+        return 0;
+
+    end_chr = *c == '<' ? '>' : '<';
+    do {
+        av_bprint_chars(buf, *c, 1);
+        *c = avio_r8(pb);
+        i++;
+    } while (*c != end_chr && *c);
+    if (end_chr == '>') {
+        av_bprint_chars(buf, '>', 1);
+        *c = 0;
+    }
+    return i;
+}
+
+const char *ff_smil_get_attr_ptr(const char *s, const char *attr)
+{
+    int in_quotes = 0;
+    const int len = strlen(attr);
+
+    while (*s) {
+        while (*s) {
+            if (!in_quotes && isspace(*s))
+                break;
+            in_quotes ^= *s == '"'; // XXX: support escaping?
+            s++;
+        }
+        while (isspace(*s))
+            s++;
+        if (!av_strncasecmp(s, attr, len) && s[len] == '=')
+            return s + len + 1 + (s[len + 1] == '"');
+    }
+    return NULL;
+}
diff --git a/libavformat/subtitles.h b/libavformat/subtitles.h
new file mode 100644
index 0000000..b089bb2
--- /dev/null
+++ b/libavformat/subtitles.h
@@ -0,0 +1,77 @@
+/*
+ * 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
+ */
+
+#ifndef AVFORMAT_SUBTITLES_H
+#define AVFORMAT_SUBTITLES_H
+
+#include <stdint.h>
+#include "avformat.h"
+#include "libavutil/bprint.h"
+
+typedef struct {
+    AVPacket *subs;         ///< array of subtitles packets
+    int nb_subs;            ///< number of subtitles packets
+    int allocated_size;     ///< allocated size for subs
+    int current_sub_idx;    ///< current position for the read packet callback
+} FFDemuxSubtitlesQueue;
+
+/**
+ * Insert a new subtitle event.
+ *
+ * @param event the subtitle line, may not be zero terminated
+ * @param len   the length of the event (in strlen() sense, so without '\0')
+ * @param merge set to 1 if the current event should be concatenated with the
+ *              previous one instead of adding a new entry, 0 otherwise
+ */
+AVPacket *ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q,
+                                    const uint8_t *event, int len, int merge);
+
+/**
+ * Set missing durations and sort subtitles by PTS, and then byte position.
+ */
+void ff_subtitles_queue_finalize(FFDemuxSubtitlesQueue *q);
+
+/**
+ * Generic read_packet() callback for subtitles demuxers using this queue
+ * system.
+ */
+int ff_subtitles_queue_read_packet(FFDemuxSubtitlesQueue *q, AVPacket *pkt);
+
+/**
+ * Remove and destroy all the subtitles packets.
+ */
+void ff_subtitles_queue_clean(FFDemuxSubtitlesQueue *q);
+
+/**
+ * SMIL helper to load next chunk ("<...>" or untagged content) in buf.
+ *
+ * @param c cached character, to avoid a backward seek
+ */
+int ff_smil_extract_next_chunk(AVIOContext *pb, AVBPrint *buf, char *c);
+
+/**
+ * SMIL helper to point on the value of an attribute in the given tag.
+ *
+ * @param s    SMIL tag ("<...>")
+ * @param attr the attribute to look for
+ */
+const char *ff_smil_get_attr_ptr(const char *s, const char *attr);
+
+#endif /* AVFORMAT_SUBTITLES_H */
diff --git a/libavformat/subviewerdec.c b/libavformat/subviewerdec.c
new file mode 100644
index 0000000..e708a28
--- /dev/null
+++ b/libavformat/subviewerdec.c
@@ -0,0 +1,177 @@
+/*
+ * 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 subtitle demuxer
+ * @see https://en.wikipedia.org/wiki/SubViewer
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+#include "libavutil/intreadwrite.h"
+
+typedef struct {
+    FFDemuxSubtitlesQueue q;
+} SubViewerContext;
+
+static int subviewer_probe(AVProbeData *p)
+{
+    char c;
+    const unsigned char *ptr = p->buf;
+
+    if (AV_RB24(ptr) == 0xEFBBBF)
+        ptr += 3;  /* skip UTF-8 BOM */
+    if (sscanf(ptr, "%*u:%*u:%*u.%*u,%*u:%*u:%*u.%*u%c", &c) == 1)
+        return AVPROBE_SCORE_MAX/2;
+    if (!strncmp(ptr, "[INFORMATION]", 13))
+        return AVPROBE_SCORE_MAX/3;
+    return 0;
+}
+
+static int read_ts(const char *s, int64_t *start, int *duration)
+{
+    int64_t end;
+    int hh1, mm1, ss1, ms1;
+    int hh2, mm2, ss2, ms2;
+
+    if (sscanf(s, "%u:%u:%u.%u,%u:%u:%u.%u",
+               &hh1, &mm1, &ss1, &ms1, &hh2, &mm2, &ss2, &ms2) == 8) {
+        end    = (hh2*3600 + mm2*60 + ss2) * 100 + ms2;
+        *start = (hh1*3600 + mm1*60 + ss1) * 100 + ms1;
+        *duration = end - *start;
+        return 0;
+    }
+    return -1;
+}
+
+static int subviewer_read_header(AVFormatContext *s)
+{
+    SubViewerContext *subviewer = s->priv_data;
+    AVStream *st = avformat_new_stream(s, NULL);
+    AVBPrint header;
+    int res = 0;
+
+    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_SUBVIEWER;
+
+    av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED);
+
+    while (!url_feof(s->pb)) {
+        char line[2048];
+        const int64_t pos = avio_tell(s->pb);
+        int len = ff_get_line(s->pb, line, sizeof(line));
+
+        if (!len)
+            break;
+
+        if (line[0] == '[' && strncmp(line, "[br]", 4)) {
+
+            /* ignore event style, XXX: add to side_data? */
+            if (strstr(line, "[COLF]") || strstr(line, "[SIZE]") ||
+                strstr(line, "[FONT]") || strstr(line, "[STYLE]"))
+                continue;
+
+            if (!st->codec->extradata) { // header not finalized yet
+                av_bprintf(&header, "%s", 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);
+                        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;
+                    char key[32], value[128];
+
+                    for (i = 1; i < sizeof(key) - 1 && line[i] && line[i] != ']'; i++)
+                        key[i - 1] = av_tolower(line[i]);
+                    key[i - 1] = 0;
+
+                    if (line[i] == ']')
+                        i++;
+                    while (line[i] == ' ')
+                        i++;
+                    while (j < sizeof(value) - 1 && line[i] && !strchr("]\r\n", 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);
+            if (!sub) {
+                res = AVERROR(ENOMEM);
+                goto end;
+            }
+            if (timed_line) {
+                sub->pos = pos;
+                sub->pts = pts_start;
+                sub->duration = duration;
+            }
+        }
+    }
+
+    ff_subtitles_queue_finalize(&subviewer->q);
+
+end:
+    av_bprint_finalize(&header, NULL);
+    return res;
+}
+
+static int subviewer_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    SubViewerContext *subviewer = s->priv_data;
+    return ff_subtitles_queue_read_packet(&subviewer->q, pkt);
+}
+
+static int subviewer_read_close(AVFormatContext *s)
+{
+    SubViewerContext *subviewer = s->priv_data;
+    ff_subtitles_queue_clean(&subviewer->q);
+    return 0;
+}
+
+AVInputFormat ff_subviewer_demuxer = {
+    .name           = "subviewer",
+    .long_name      = NULL_IF_CONFIG_SMALL("SubViewer subtitle format"),
+    .priv_data_size = sizeof(SubViewerContext),
+    .read_probe     = subviewer_probe,
+    .read_header    = subviewer_read_header,
+    .read_packet    = subviewer_read_packet,
+    .read_close     = subviewer_read_close,
+    .flags          = AVFMT_GENERIC_INDEX,
+    .extensions     = "sub",
+};
diff --git a/libavformat/swf.c b/libavformat/swf.c
index e6adf69..1aa434a 100644
--- a/libavformat/swf.c
+++ b/libavformat/swf.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000 Fabrice Bellard
  * Copyright (c) 2003 Tinic Uro
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/swf.h b/libavformat/swf.h
index 97e7b2d..6ecd0da 100644
--- a/libavformat/swf.h
+++ b/libavformat/swf.h
@@ -3,26 +3,32 @@
  * Copyright (c) 2000 Fabrice Bellard
  * Copyright (c) 2003 Tinic Uro
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #ifndef AVFORMAT_SWF_H
 #define AVFORMAT_SWF_H
 
+#include "config.h"
+
+#if CONFIG_ZLIB
+#include <zlib.h>
+#endif
+
 #include "libavutil/fifo.h"
 #include "avformat.h"
 #include "avio.h"
@@ -32,20 +38,73 @@
 #define DUMMY_FILE_SIZE   (100 * 1024 * 1024)
 #define DUMMY_DURATION    600 /* in seconds */
 
-#define TAG_END           0
-#define TAG_SHOWFRAME     1
-#define TAG_DEFINESHAPE   2
-#define TAG_FREECHARACTER 3
-#define TAG_PLACEOBJECT   4
-#define TAG_REMOVEOBJECT  5
-#define TAG_STREAMHEAD    18
-#define TAG_STREAMBLOCK   19
-#define TAG_JPEG2         21
-#define TAG_PLACEOBJECT2  26
-#define TAG_STREAMHEAD2   45
-#define TAG_VIDEOSTREAM   60
-#define TAG_VIDEOFRAME    61
-#define TAG_FILEATTRIBUTES 69
+enum {
+    TAG_END                          =  0,
+    TAG_SHOWFRAME                    =  1,
+    TAG_DEFINESHAPE                  =  2,
+    TAG_FREECHARACTER                =  3,
+    TAG_PLACEOBJECT                  =  4,
+    TAG_REMOVEOBJECT                 =  5,
+    TAG_DEFINEBITS                   =  6,
+    TAG_DEFINEBUTTON                 =  7,
+    TAG_JPEGTABLES                   =  8,
+    TAG_SETBACKGROUNDCOLOR           =  9,
+    TAG_DEFINEFONT                   = 10,
+    TAG_DEFINETEXT                   = 11,
+    TAG_DOACTION                     = 12,
+    TAG_DEFINEFONTINFO               = 13,
+    TAG_DEFINESOUND                  = 14,
+    TAG_STARTSOUND                   = 15,
+    TAG_DEFINEBUTTONSOUND            = 17,
+    TAG_STREAMHEAD                   = 18,
+    TAG_STREAMBLOCK                  = 19,
+    TAG_DEFINEBITSLOSSLESS           = 20,
+    TAG_JPEG2                        = 21,
+    TAG_DEFINESHAPE2                 = 22,
+    TAG_DEFINEBUTTONCXFORM           = 23,
+    TAG_PROTECT                      = 24,
+    TAG_PLACEOBJECT2                 = 26,
+    TAG_REMOVEOBJECT2                = 28,
+    TAG_DEFINESHAPE3                 = 32,
+    TAG_DEFINETEXT2                  = 33,
+    TAG_DEFINEBUTTON2                = 34,
+    TAG_DEFINEBITSJPEG3              = 35,
+    TAG_DEFINEBITSLOSSLESS2          = 36,
+    TAG_DEFINEEDITTEXT               = 37,
+    TAG_DEFINESPRITE                 = 39,
+    TAG_FRAMELABEL                   = 43,
+    TAG_STREAMHEAD2                  = 45,
+    TAG_DEFINEMORPHSHAPE             = 46,
+    TAG_DEFINEFONT2                  = 48,
+    TAG_EXPORTASSETS                 = 56,
+    TAG_IMPORTASSETS                 = 57,
+    TAG_ENABLEDEBUGGER               = 58,
+    TAG_DOINITACTION                 = 59,
+    TAG_VIDEOSTREAM                  = 60,
+    TAG_VIDEOFRAME                   = 61,
+    TAG_DEFINEFONTINFO2              = 62,
+    TAG_ENABLEDEBUGGER2              = 64,
+    TAG_SCRIPTLIMITS                 = 65,
+    TAG_SETTABINDEX                  = 66,
+    TAG_FILEATTRIBUTES               = 69,
+    TAG_PLACEOBJECT3                 = 70,
+    TAG_IMPORTASSETS2                = 71,
+    TAG_DEFINEFONTALIGNZONES         = 73,
+    TAG_CSMTEXTSETTINGS              = 74,
+    TAG_DEFINEFONT3                  = 75,
+    TAG_SYMBOLCLASS                  = 76,
+    TAG_METADATA                     = 77,
+    TAG_DEFINESCALINGGRID            = 78,
+    TAG_DOABC                        = 82,
+    TAG_DEFINESHAPE4                 = 83,
+    TAG_DEFINEMORPHSHAPE2            = 84,
+    TAG_DEFINESCENEANDFRAMELABELDATA = 86,
+    TAG_DEFINEBINARYDATA             = 87,
+    TAG_DEFINEFONTNAME               = 88,
+    TAG_STARTSOUND2                  = 89,
+    TAG_DEFINEBITSJPEG4              = 90,
+    TAG_DEFINEFONT4                  = 91,
+};
 
 #define TAG_LONG         0x100
 
@@ -76,6 +135,13 @@
     int tag;
     AVFifoBuffer *audio_fifo;
     AVCodecContext *audio_enc, *video_enc;
+#if CONFIG_ZLIB
+    AVIOContext *zpb;
+#define ZBUF_SIZE 4096
+    uint8_t *zbuf_in;
+    uint8_t *zbuf_out;
+    z_stream zstream;
+#endif
 } SWFContext;
 
 extern const AVCodecTag ff_swf_codec_tags[];
diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c
index ff44452..e8ab718 100644
--- a/libavformat/swfdec.c
+++ b/libavformat/swfdec.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000 Fabrice Bellard
  * Copyright (c) 2003 Tinic Uro
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,8 +36,8 @@
 {
     int tag, len;
 
-    if (pb->eof_reached)
-        return -1;
+    if (url_feof(pb))
+        return AVERROR_EOF;
 
     tag = avio_rl16(pb);
     len = tag & 0x3f;
@@ -60,6 +60,39 @@
         return 0;
 }
 
+#if CONFIG_ZLIB
+static int zlib_refill(void *opaque, uint8_t *buf, int buf_size)
+{
+    AVFormatContext *s = opaque;
+    SWFContext *swf = s->priv_data;
+    z_stream *z = &swf->zstream;
+    int ret;
+
+retry:
+    if (!z->avail_in) {
+        int n = avio_read(s->pb, swf->zbuf_in, ZBUF_SIZE);
+        if (n < 0)
+            return n;
+        z->next_in  = swf->zbuf_in;
+        z->avail_in = n;
+    }
+
+    z->next_out  = buf;
+    z->avail_out = buf_size;
+
+    ret = inflate(z, Z_NO_FLUSH);
+    if (ret < 0)
+        return AVERROR(EINVAL);
+    if (ret == Z_STREAM_END)
+        return AVERROR_EOF;
+
+    if (buf_size - z->avail_out == 0)
+        goto retry;
+
+    return buf_size - z->avail_out;
+}
+#endif
+
 static int swf_read_header(AVFormatContext *s)
 {
     SWFContext *swf = s->priv_data;
@@ -67,14 +100,29 @@
     int nbits, len, tag;
 
     tag = avio_rb32(pb) & 0xffffff00;
+    avio_rl32(pb);
 
     if (tag == MKBETAG('C', 'W', 'S', 0)) {
-        av_log(s, AV_LOG_ERROR, "Compressed SWF format not supported\n");
+        av_log(s, AV_LOG_INFO, "SWF compressed file detected\n");
+#if CONFIG_ZLIB
+        swf->zbuf_in  = av_malloc(ZBUF_SIZE);
+        swf->zbuf_out = av_malloc(ZBUF_SIZE);
+        swf->zpb = avio_alloc_context(swf->zbuf_out, ZBUF_SIZE, 0, s,
+                                      zlib_refill, NULL, NULL);
+        if (!swf->zbuf_in || !swf->zbuf_out || !swf->zpb)
+            return AVERROR(ENOMEM);
+        swf->zpb->seekable = 0;
+        if (inflateInit(&swf->zstream) != Z_OK) {
+            av_log(s, AV_LOG_ERROR, "Unable to init zlib context\n");
+            return AVERROR(EINVAL);
+        }
+        pb = swf->zpb;
+#else
+        av_log(s, AV_LOG_ERROR, "zlib support is required to read SWF compressed files\n");
         return AVERROR(EIO);
-    }
-    if (tag != MKBETAG('F', 'W', 'S', 0))
+#endif
+    } else if (tag != MKBETAG('F', 'W', 'S', 0))
         return AVERROR(EIO);
-    avio_rl32(pb);
     /* skip rectangle size */
     nbits = avio_r8(pb) >> 3;
     len = (4 * nbits - 3 + 7) / 8;
@@ -94,11 +142,16 @@
     AVStream *vst = NULL, *ast = NULL, *st = 0;
     int tag, len, i, frame, v, res;
 
+#if CONFIG_ZLIB
+    if (swf->zpb)
+        pb = swf->zpb;
+#endif
+
     for(;;) {
         uint64_t pos = avio_tell(pb);
         tag = get_swf_tag(pb, &len);
         if (tag < 0)
-            return AVERROR(EIO);
+            return tag;
         if (tag == TAG_VIDEOSTREAM) {
             int ch_id = avio_rl16(pb);
             len -= 2;
@@ -116,7 +169,7 @@
             /* Check for FLV1 */
             vst = avformat_new_stream(s, NULL);
             if (!vst)
-                return -1;
+                return AVERROR(ENOMEM);
             vst->id = ch_id;
             vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
             vst->codec->codec_id = ff_codec_get_id(ff_swf_codec_tags, avio_r8(pb));
@@ -137,7 +190,7 @@
             swf->samples_per_frame = avio_rl16(pb);
             ast = avformat_new_stream(s, NULL);
             if (!ast)
-                return -1;
+                return AVERROR(ENOMEM);
             ast->id = -1; /* -1 to avoid clash with video stream ch_id */
             ast->codec->channels = 1 + (v&1);
             ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
@@ -147,6 +200,44 @@
             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++) {
+                st = s->streams[i];
+                if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->id == ch_id)
+                    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);
+            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);
+                len -= 2;
+            }
+            len -= 7;
+            if ((res = av_get_packet(pb, pkt, len)) < 0)
+                return res;
+            pkt->pos = pos;
+            pkt->stream_index = ast->index;
+            return pkt->size;
         } else if (tag == TAG_VIDEOFRAME) {
             int ch_id = avio_rl16(pb);
             len -= 2;
@@ -188,7 +279,7 @@
             if (i == s->nb_streams) {
                 vst = avformat_new_stream(s, NULL);
                 if (!vst)
-                    return -1;
+                    return AVERROR(ENOMEM);
                 vst->id = -2; /* -2 to avoid clash with video stream and audio stream */
                 vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
                 vst->codec->codec_id = AV_CODEC_ID_MJPEG;
@@ -217,6 +308,18 @@
     }
 }
 
+#if CONFIG_ZLIB
+static av_cold int swf_read_close(AVFormatContext *avctx)
+{
+    SWFContext *s = avctx->priv_data;
+    inflateEnd(&s->zstream);
+    av_freep(&s->zbuf_in);
+    av_freep(&s->zbuf_out);
+    av_freep(&s->zpb);
+    return 0;
+}
+#endif
+
 AVInputFormat ff_swf_demuxer = {
     .name           = "swf",
     .long_name      = NULL_IF_CONFIG_SMALL("SWF (ShockWave Flash)"),
@@ -224,4 +327,7 @@
     .read_probe     = swf_probe,
     .read_header    = swf_read_header,
     .read_packet    = swf_read_packet,
+#if CONFIG_ZLIB
+    .read_close     = swf_read_close,
+#endif
 };
diff --git a/libavformat/swfenc.c b/libavformat/swfenc.c
index 31f405d..b55f1a9 100644
--- a/libavformat/swfenc.c
+++ b/libavformat/swfenc.c
@@ -3,24 +3,25 @@
  * Copyright (c) 2000 Fabrice Bellard
  * Copyright (c) 2003 Tinic Uro
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "libavcodec/put_bits.h"
+#include "libavutil/avassert.h"
 #include "avformat.h"
 #include "swf.h"
 
@@ -56,7 +57,7 @@
         avio_wl16(pb, (tag << 6) | 0x3f);
         avio_wl32(pb, tag_len - 4);
     } else {
-        assert(tag_len < 0x3f);
+        av_assert0(tag_len < 0x3f);
         avio_wl16(pb, (tag << 6) | tag_len);
     }
     avio_seek(pb, pos, SEEK_SET);
@@ -425,7 +426,7 @@
         put_swf_tag(s, TAG_STREAMBLOCK | TAG_LONG);
         avio_wl16(pb, swf->sound_samples);
         avio_wl16(pb, 0); // seek samples
-        av_fifo_generic_read(swf->audio_fifo, pb, frame_size, &avio_write);
+        av_fifo_generic_read(swf->audio_fifo, pb, frame_size, (void*)avio_write);
         put_swf_end_tag(s);
 
         /* update FIFO */
@@ -500,8 +501,10 @@
         avio_wl32(pb, file_size);
         avio_seek(pb, swf->duration_pos, SEEK_SET);
         avio_wl16(pb, swf->video_frame_number);
+        if (swf->vframes_pos) {
         avio_seek(pb, swf->vframes_pos, SEEK_SET);
         avio_wl16(pb, swf->video_frame_number);
+        }
         avio_seek(pb, file_size, SEEK_SET);
     }
     return 0;
diff --git a/libavformat/takdec.c b/libavformat/takdec.c
new file mode 100644
index 0000000..a529017
--- /dev/null
+++ b/libavformat/takdec.c
@@ -0,0 +1,186 @@
+/*
+ * Raw TAK 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 "libavcodec/tak.h"
+#include "avformat.h"
+#include "internal.h"
+#include "rawdec.h"
+#include "apetag.h"
+
+typedef struct TAKDemuxContext {
+    int      mlast_frame;
+    int64_t  data_end;
+} TAKDemuxContext;
+
+static int tak_probe(AVProbeData *p)
+{
+    if (!memcmp(p->buf, "tBaK", 4))
+        return AVPROBE_SCORE_MAX / 2;
+    return 0;
+}
+
+static int tak_read_header(AVFormatContext *s)
+{
+    TAKDemuxContext *tc = s->priv_data;
+    AVIOContext *pb = s->pb;
+    GetBitContext gb;
+    AVStream *st;
+    uint8_t *buffer = NULL;
+    int ret;
+
+    st = avformat_new_stream(s, 0);
+    if (!st)
+        return AVERROR(ENOMEM);
+
+    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+    st->codec->codec_id   = AV_CODEC_ID_TAK;
+    st->need_parsing      = AVSTREAM_PARSE_FULL_RAW;
+
+    tc->mlast_frame = 0;
+    if (avio_rl32(pb) != MKTAG('t', 'B', 'a', 'K')) {
+        avio_seek(pb, -4, SEEK_CUR);
+        return 0;
+    }
+
+    while (!url_feof(pb)) {
+        enum TAKMetaDataType type;
+        int size;
+
+        type = avio_r8(pb) & 0x7f;
+        size = avio_rl24(pb);
+
+        switch (type) {
+        case TAK_METADATA_STREAMINFO:
+        case TAK_METADATA_LAST_FRAME:
+        case TAK_METADATA_ENCODER:
+            buffer = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
+            if (!buffer)
+                return AVERROR(ENOMEM);
+
+            if (avio_read(pb, buffer, size) != size) {
+                av_freep(&buffer);
+                return AVERROR(EIO);
+            }
+
+            init_get_bits(&gb, buffer, size * 8);
+            break;
+        case TAK_METADATA_MD5: {
+            uint8_t md5[16];
+            int i;
+
+            if (size != 19)
+                return AVERROR_INVALIDDATA;
+            avio_read(pb, md5, 16);
+            avio_skip(pb, 3);
+            av_log(s, AV_LOG_VERBOSE, "MD5=");
+            for (i = 0; i < 16; i++)
+                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);
+
+            if (pb->seekable) {
+                ff_ape_parse_tag(s);
+                avio_seek(pb, curpos, SEEK_SET);
+            }
+
+            tc->data_end += curpos;
+            return 0;
+            break;
+            }
+        default:
+            ret = avio_skip(pb, size);
+            if (ret < 0)
+                return ret;
+        }
+
+        if (type == TAK_METADATA_STREAMINFO) {
+            TAKStreamInfo ti;
+
+            avpriv_tak_parse_streaminfo(&gb, &ti);
+            if (ti.samples > 0)
+                st->duration = ti.samples;
+            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;
+            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+            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);
+            av_freep(&buffer);
+        } else if (type == TAK_METADATA_ENCODER) {
+            av_log(s, AV_LOG_VERBOSE, "encoder version: %0X\n",
+                   get_bits_long(&gb, TAK_ENCODER_VERSION_BITS));
+            av_freep(&buffer);
+        }
+    }
+
+    return AVERROR_EOF;
+}
+
+static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    TAKDemuxContext *tc = s->priv_data;
+    int ret;
+
+    if (tc->mlast_frame) {
+        AVIOContext *pb = s->pb;
+        int64_t size, left;
+
+        left = tc->data_end - avio_tell(s->pb);
+        size = FFMIN(left, 1024);
+        if (size <= 0)
+            return AVERROR_EOF;
+
+        ret = av_get_packet(pb, pkt, size);
+        if (ret < 0)
+            return ret;
+
+        pkt->stream_index = 0;
+    } else {
+        ret = ff_raw_read_partial_packet(s, pkt);
+    }
+
+    return ret;
+}
+
+AVInputFormat ff_tak_demuxer = {
+    .name           = "tak",
+    .long_name      = NULL_IF_CONFIG_SMALL("raw TAK"),
+    .priv_data_size = sizeof(TAKDemuxContext),
+    .read_probe     = tak_probe,
+    .read_header    = tak_read_header,
+    .read_packet    = raw_read_packet,
+    .flags          = AVFMT_GENERIC_INDEX,
+    .extensions     = "tak",
+    .raw_codec_id   = AV_CODEC_ID_TAK,
+};
diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index bdaab7f..8b35fb1 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -2,24 +2,25 @@
  * TCP protocol
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
 #include "libavutil/parseutils.h"
+#include "libavutil/opt.h"
 #include "internal.h"
 #include "network.h"
 #include "os_support.h"
@@ -29,23 +30,43 @@
 #endif
 
 typedef struct TCPContext {
+    const AVClass *class;
     int fd;
+    int listen;
+    int rw_timeout;
+    int listen_timeout;
 } TCPContext;
 
+#define OFFSET(x) offsetof(TCPContext, x)
+#define D AV_OPT_FLAG_DECODING_PARAM
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+{"listen", "listen on port instead of connecting", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D|E },
+{"timeout", "timeout of socket i/o operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D|E },
+{"listen_timeout", "connection awaiting timeout", OFFSET(listen_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E },
+{NULL}
+};
+
+static const AVClass tcp_context_class = {
+    .class_name = "tcp",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 /* return non zero if error */
 static int tcp_open(URLContext *h, const char *uri, int flags)
 {
     struct addrinfo hints = { 0 }, *ai, *cur_ai;
     int port, fd = -1;
     TCPContext *s = h->priv_data;
-    int listen_socket = 0;
     const char *p;
     char buf[256];
     int ret;
     socklen_t optlen;
-    int timeout = 100, listen_timeout = -1;
     char hostname[1024],proto[1024],path[1024];
     char portstr[10];
+    h->rw_timeout = 5000000;
 
     av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
         &port, path, sizeof(path), uri);
@@ -58,18 +79,19 @@
     p = strchr(uri, '?');
     if (p) {
         if (av_find_info_tag(buf, sizeof(buf), "listen", p))
-            listen_socket = 1;
+            s->listen = 1;
         if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {
-            timeout = strtol(buf, NULL, 10);
+            s->rw_timeout = strtol(buf, NULL, 10);
         }
         if (av_find_info_tag(buf, sizeof(buf), "listen_timeout", p)) {
-            listen_timeout = strtol(buf, NULL, 10);
+            s->listen_timeout = strtol(buf, NULL, 10);
         }
     }
+    h->rw_timeout = s->rw_timeout;
     hints.ai_family = AF_UNSPEC;
     hints.ai_socktype = SOCK_STREAM;
     snprintf(portstr, sizeof(portstr), "%d", port);
-    if (listen_socket)
+    if (s->listen)
         hints.ai_flags |= AI_PASSIVE;
     if (!hostname[0])
         ret = getaddrinfo(NULL, portstr, &hints, &ai);
@@ -90,7 +112,7 @@
     if (fd < 0)
         goto fail;
 
-    if (listen_socket) {
+    if (s->listen) {
         int fd1;
         int reuse = 1;
         struct pollfd lp = { fd, POLLIN, 0 };
@@ -105,7 +127,7 @@
             ret = ff_neterrno();
             goto fail1;
         }
-        ret = poll(&lp, 1, listen_timeout >= 0 ? listen_timeout : -1);
+        ret = poll(&lp, 1, s->listen_timeout >= 0 ? s->listen_timeout : -1);
         if (ret <= 0) {
             ret = AVERROR(ETIMEDOUT);
             goto fail1;
@@ -126,6 +148,7 @@
 
     if (ret < 0) {
         struct pollfd p = {fd, POLLOUT, 0};
+        int64_t wait_started;
         ret = ff_neterrno();
         if (ret == AVERROR(EINTR)) {
             if (ff_check_interrupt(&h->interrupt_callback)) {
@@ -139,7 +162,8 @@
             goto fail;
 
         /* wait until we are connected or until abort */
-        while(timeout--) {
+        wait_started = av_gettime();
+        do {
             if (ff_check_interrupt(&h->interrupt_callback)) {
                 ret = AVERROR_EXIT;
                 goto fail1;
@@ -147,7 +171,7 @@
             ret = poll(&p, 1, 100);
             if (ret > 0)
                 break;
-        }
+        } while (!h->rw_timeout || (av_gettime() - wait_started < h->rw_timeout));
         if (ret <= 0) {
             ret = AVERROR(ETIMEDOUT);
             goto fail;
@@ -192,8 +216,8 @@
     int ret;
 
     if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
-        ret = ff_network_wait_fd(s->fd, 0);
-        if (ret < 0)
+        ret = ff_network_wait_fd_timeout(s->fd, 0, h->rw_timeout, &h->interrupt_callback);
+        if (ret)
             return ret;
     }
     ret = recv(s->fd, buf, size, 0);
@@ -206,8 +230,8 @@
     int ret;
 
     if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
-        ret = ff_network_wait_fd(s->fd, 1);
-        if (ret < 0)
+        ret = ff_network_wait_fd_timeout(s->fd, 1, h->rw_timeout, &h->interrupt_callback);
+        if (ret)
             return ret;
     }
     ret = send(s->fd, buf, size, 0);
@@ -252,5 +276,6 @@
     .url_get_file_handle = tcp_get_file_handle,
     .url_shutdown        = tcp_shutdown,
     .priv_data_size      = sizeof(TCPContext),
+    .priv_data_class     = &tcp_context_class,
     .flags               = URL_PROTOCOL_FLAG_NETWORK,
 };
diff --git a/libavformat/thp.c b/libavformat/thp.c
index e8ca04f..0e96b53 100644
--- a/libavformat/thp.c
+++ b/libavformat/thp.c
@@ -2,20 +2,20 @@
  * THP Demuxer
  * Copyright (c) 2007 Marco Gerards
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -41,7 +41,7 @@
     unsigned char    components[16];
     AVStream*        vst;
     int              has_audio;
-    int              audiosize;
+    unsigned         audiosize;
 } ThpDemuxContext;
 
 
@@ -59,6 +59,7 @@
     ThpDemuxContext *thp = s->priv_data;
     AVStream *st;
     AVIOContext *pb = s->pb;
+    int64_t fsize= avio_size(pb);
     int i;
 
     /* Read the file header.  */
@@ -71,7 +72,9 @@
     thp->fps             = av_d2q(av_int2float(avio_rb32(pb)), INT_MAX);
     thp->framecnt        = avio_rb32(pb);
     thp->first_framesz   = avio_rb32(pb);
-                           avio_rb32(pb); /* Data size.  */
+    pb->maxsize          = avio_rb32(pb);
+    if(fsize>0 && (!pb->maxsize || fsize < pb->maxsize))
+        pb->maxsize= fsize;
 
     thp->compoff         = avio_rb32(pb);
                            avio_rb32(pb); /* offsetDataOffset.  */
@@ -142,7 +145,7 @@
 {
     ThpDemuxContext *thp = s->priv_data;
     AVIOContext *pb = s->pb;
-    int size;
+    unsigned int size;
     int ret;
 
     if (thp->audiosize == 0) {
diff --git a/libavformat/tiertexseq.c b/libavformat/tiertexseq.c
index 5582890..88941b7 100644
--- a/libavformat/tiertexseq.c
+++ b/libavformat/tiertexseq.c
@@ -2,20 +2,20 @@
  * Tiertex Limited SEQ File Demuxer
  * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/tls.c b/libavformat/tls.c
index 866e55f..38dd70c 100644
--- a/libavformat/tls.c
+++ b/libavformat/tls.c
@@ -22,6 +22,7 @@
 #include "avformat.h"
 #include "url.h"
 #include "libavutil/avstring.h"
+#include "libavutil/parseutils.h"
 #if CONFIG_GNUTLS
 #include <gnutls/gnutls.h>
 #define TLS_read(c, buf, size)  gnutls_record_recv(c->session, buf, size)
@@ -103,16 +104,71 @@
     return 0;
 }
 
+static void set_options(URLContext *h, const char *uri)
+{
+    TLSContext *c = h->priv_data;
+    char buf[1024], key[1024];
+    int has_cert, has_key, verify = 0;
+#if CONFIG_GNUTLS
+    int ret;
+#endif
+    const char *p = strchr(uri, '?');
+    if (!p)
+        return;
+
+    if (av_find_info_tag(buf, sizeof(buf), "cafile", p)) {
+#if CONFIG_GNUTLS
+        ret = gnutls_certificate_set_x509_trust_file(c->cred, buf, GNUTLS_X509_FMT_PEM);
+        if (ret < 0)
+            av_log(h, AV_LOG_ERROR, "%s\n", gnutls_strerror(ret));
+#elif CONFIG_OPENSSL
+        if (!SSL_CTX_load_verify_locations(c->ctx, buf, NULL))
+            av_log(h, AV_LOG_ERROR, "SSL_CTX_load_verify_locations %s\n", ERR_error_string(ERR_get_error(), NULL));
+#endif
+    }
+
+    if (av_find_info_tag(buf, sizeof(buf), "verify", p)) {
+        char *endptr = NULL;
+        verify = strtol(buf, &endptr, 10);
+        if (buf == endptr)
+            verify = 1;
+    }
+
+    has_cert = av_find_info_tag(buf, sizeof(buf), "cert", p);
+    has_key  = av_find_info_tag(key, sizeof(key), "key", p);
+#if CONFIG_GNUTLS
+    if (has_cert && has_key) {
+        ret = gnutls_certificate_set_x509_key_file(c->cred, buf, key, GNUTLS_X509_FMT_PEM);
+        if (ret < 0)
+            av_log(h, AV_LOG_ERROR, "%s\n", gnutls_strerror(ret));
+    } else if (has_cert ^ has_key) {
+        av_log(h, AV_LOG_ERROR, "cert and key required\n");
+    }
+    gnutls_certificate_set_verify_flags(c->cred, verify);
+#elif CONFIG_OPENSSL
+    if (has_cert && !SSL_CTX_use_certificate_chain_file(c->ctx, buf))
+        av_log(h, AV_LOG_ERROR, "SSL_CTX_use_certificate_chain_file %s\n", ERR_error_string(ERR_get_error(), NULL));
+    if (has_key && !SSL_CTX_use_PrivateKey_file(c->ctx, key, SSL_FILETYPE_PEM))
+        av_log(h, AV_LOG_ERROR, "SSL_CTX_use_PrivateKey_file %s\n", ERR_error_string(ERR_get_error(), NULL));
+    if (verify)
+        SSL_CTX_set_verify(c->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);
+#endif
+}
+
 static int tls_open(URLContext *h, const char *uri, int flags)
 {
     TLSContext *c = h->priv_data;
     int ret;
     int port;
-    char buf[200], host[200];
+    char buf[200], host[200], path[1024];
     int numerichost = 0;
     struct addrinfo hints = { 0 }, *ai = NULL;
     const char *proxy_path;
     int use_proxy;
+    int server = 0;
+    const char *p = strchr(uri, '?');
+    if (p && av_find_info_tag(buf, sizeof(buf), "listen", p))
+        server = 1;
 
     ff_tls_init();
 
@@ -120,8 +176,8 @@
     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, NULL, 0, uri);
-    ff_url_join(buf, sizeof(buf), "tcp", NULL, host, port, 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);
 
     hints.ai_flags = AI_NUMERICHOST;
     if (!getaddrinfo(host, NULL, &hints, &ai)) {
@@ -147,11 +203,11 @@
     c->fd = ffurl_get_file_handle(c->tcp);
 
 #if CONFIG_GNUTLS
-    gnutls_init(&c->session, GNUTLS_CLIENT);
+    gnutls_init(&c->session, server ? GNUTLS_SERVER : GNUTLS_CLIENT);
     if (!numerichost)
         gnutls_server_name_set(c->session, GNUTLS_NAME_DNS, host, strlen(host));
     gnutls_certificate_allocate_credentials(&c->cred);
-    gnutls_certificate_set_verify_flags(c->cred, 0);
+    set_options(h, uri);
     gnutls_credentials_set(c->session, GNUTLS_CRD_CERTIFICATE, c->cred);
     gnutls_transport_set_ptr(c->session, (gnutls_transport_ptr_t)
                                          (intptr_t) c->fd);
@@ -164,12 +220,13 @@
             goto fail;
     }
 #elif CONFIG_OPENSSL
-    c->ctx = SSL_CTX_new(TLSv1_client_method());
+    c->ctx = SSL_CTX_new(server ? TLSv1_server_method() : TLSv1_client_method());
     if (!c->ctx) {
         av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
         ret = AVERROR(EIO);
         goto fail;
     }
+    set_options(h, uri);
     c->ssl = SSL_new(c->ctx);
     if (!c->ssl) {
         av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
@@ -177,10 +234,10 @@
         goto fail;
     }
     SSL_set_fd(c->ssl, c->fd);
-    if (!numerichost)
+    if (!server && !numerichost)
         SSL_set_tlsext_host_name(c->ssl, host);
     while (1) {
-        ret = SSL_connect(c->ssl);
+        ret = server ? SSL_accept(c->ssl) : SSL_connect(c->ssl);
         if (ret > 0)
             break;
         if (ret == 0) {
diff --git a/libavformat/tmv.c b/libavformat/tmv.c
index 100e12f..acc3460 100644
--- a/libavformat/tmv.c
+++ b/libavformat/tmv.c
@@ -2,20 +2,20 @@
  * 8088flex TMV file demuxer
  * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -147,7 +147,7 @@
     int ret, pkt_size = tmv->stream_index ?
                         tmv->audio_chunk_size : tmv->video_chunk_size;
 
-    if (pb->eof_reached)
+    if (url_feof(pb))
         return AVERROR_EOF;
 
     ret = av_get_packet(pb, pkt, pkt_size);
diff --git a/libavformat/tta.c b/libavformat/tta.c
index 9d3d295..1440c80 100644
--- a/libavformat/tta.c
+++ b/libavformat/tta.c
@@ -2,20 +2,20 @@
  * TTA demuxer
  * Copyright (c) 2006 Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -78,8 +78,8 @@
     c->totalframes = datalen / c->frame_size + (c->last_frame_size < c->frame_size);
     c->currentframe = 0;
 
-    if(c->totalframes >= UINT_MAX/sizeof(uint32_t)){
-        av_log(s, AV_LOG_ERROR, "totalframes too large\n");
+    if(c->totalframes >= UINT_MAX/sizeof(uint32_t) || c->totalframes <= 0){
+        av_log(s, AV_LOG_ERROR, "totalframes %d invalid\n", c->totalframes);
         return -1;
     }
 
diff --git a/libavformat/tty.c b/libavformat/tty.c
index f85f230..4c62b5b 100644
--- a/libavformat/tty.c
+++ b/libavformat/tty.c
@@ -2,20 +2,20 @@
  * Tele-typewriter demuxer
  * Copyright (c) 2010 Peter Ross <pross@xvid.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -121,20 +121,22 @@
     TtyDemuxContext *s = avctx->priv_data;
     int n;
 
-    if (avctx->pb->eof_reached)
+    if (url_feof(avctx->pb))
         return AVERROR_EOF;
 
     n = s->chars_per_frame;
     if (s->fsize) {
         // ignore metadata buffer
         uint64_t p = avio_tell(avctx->pb);
+        if (p == s->fsize)
+            return AVERROR_EOF;
         if (p + s->chars_per_frame > s->fsize)
             n = s->fsize - p;
     }
 
     pkt->size = av_get_packet(avctx->pb, pkt, n);
-    if (pkt->size <= 0)
-        return AVERROR(EIO);
+    if (pkt->size < 0)
+        return pkt->size;
     pkt->flags |= AV_PKT_FLAG_KEY;
     return 0;
 }
diff --git a/libavformat/txd.c b/libavformat/txd.c
index 5897881..9e02d87 100644
--- a/libavformat/txd.c
+++ b/libavformat/txd.c
@@ -2,20 +2,20 @@
  * Renderware TeXture Dictionary (.txd) demuxer
  * Copyright (c) 2007 Ivo van Poorten
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -48,6 +48,7 @@
     st->codec->time_base.den = 5;
     st->codec->time_base.num = 1;
     /* the parameters will be extracted from the compressed bitstream */
+
     return 0;
 }
 
@@ -61,7 +62,7 @@
     chunk_size = avio_rl32(pb);
     marker     = avio_rl32(pb);
 
-    if (s->pb->eof_reached)
+    if (url_feof(s->pb))
         return AVERROR_EOF;
     if (marker != TXD_MARKER && marker != TXD_MARKER2) {
         av_log(s, AV_LOG_ERROR, "marker does not match\n");
diff --git a/libavformat/udp.c b/libavformat/udp.c
index e848ecd..433f961 100644
--- a/libavformat/udp.c
+++ b/libavformat/udp.c
@@ -2,20 +2,20 @@
  * UDP prototype streaming system
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,31 +29,86 @@
 #include "avformat.h"
 #include "avio_internal.h"
 #include "libavutil/parseutils.h"
+#include "libavutil/fifo.h"
+#include "libavutil/intreadwrite.h"
 #include "libavutil/avstring.h"
+#include "libavutil/opt.h"
+#include "libavutil/log.h"
 #include "internal.h"
 #include "network.h"
 #include "os_support.h"
 #include "url.h"
 
+#if HAVE_PTHREAD_CANCEL
+#include <pthread.h>
+#endif
+
+#ifndef HAVE_PTHREAD_CANCEL
+#define HAVE_PTHREAD_CANCEL 0
+#endif
+
 #ifndef IPV6_ADD_MEMBERSHIP
 #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
 #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
 #endif
 
+#define UDP_TX_BUF_SIZE 32768
+#define UDP_MAX_PKT_SIZE 65536
+
 typedef struct {
+    const AVClass *class;
     int udp_fd;
     int ttl;
     int buffer_size;
     int is_multicast;
     int local_port;
     int reuse_socket;
+    int overrun_nonfatal;
     struct sockaddr_storage dest_addr;
     int dest_addr_len;
     int is_connected;
+
+    /* Circular Buffer variables for use in UDP receive code */
+    int circular_buffer_size;
+    AVFifoBuffer *fifo;
+    int circular_buffer_error;
+#if HAVE_PTHREAD_CANCEL
+    pthread_t circular_buffer_thread;
+    pthread_mutex_t mutex;
+    pthread_cond_t cond;
+    int thread_started;
+#endif
+    uint8_t tmp[UDP_MAX_PKT_SIZE+4];
+    int remaining_in_dg;
+    char *local_addr;
+    int packet_size;
+    int timeout;
 } UDPContext;
 
-#define UDP_TX_BUF_SIZE 32768
-#define UDP_MAX_PKT_SIZE 65536
+#define OFFSET(x) offsetof(UDPContext, x)
+#define D AV_OPT_FLAG_DECODING_PARAM
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+{"buffer_size", "Socket buffer size in bytes", OFFSET(buffer_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D|E },
+{"localport", "Set local port to bind to", OFFSET(local_port), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D|E },
+{"localaddr", "Choose local IP address", OFFSET(local_addr), AV_OPT_TYPE_STRING, {.str = ""}, 0, 0, D|E },
+{"pkt_size", "Set size of UDP packets", OFFSET(packet_size), AV_OPT_TYPE_INT, {.i64 = 1472}, 0, INT_MAX, D|E },
+{"reuse", "Explicitly allow or disallow reusing UDP sockets", OFFSET(reuse_socket), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D|E },
+{"ttl", "Set the time to live value (for multicast only)", OFFSET(ttl), AV_OPT_TYPE_INT, {.i64 = 16}, 0, INT_MAX, E },
+{"connect", "Should connect() be called on socket", OFFSET(is_connected), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D|E },
+/* TODO 'sources', 'block' option */
+{"fifo_size", "Set the UDP receiving circular buffer size, expressed as a number of packets with size of 188 bytes", OFFSET(circular_buffer_size), AV_OPT_TYPE_INT, {.i64 = 7*4096}, 0, INT_MAX, D },
+{"overrun_nonfatal", "Survive in case of UDP receiving circular buffer overrun", OFFSET(overrun_nonfatal), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D },
+{"timeout", "In read mode: if no data arrived in more than this time interval, raise error", OFFSET(timeout), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D },
+{NULL}
+};
+
+static const AVClass udp_context_class = {
+    .class_name     = "udp",
+    .item_name      = av_default_item_name,
+    .option         = options,
+    .version        = LIBAVUTIL_VERSION_INT,
+};
 
 static void log_net_error(void *ctx, int level, const char* prefix)
 {
@@ -317,6 +372,7 @@
  *         'localport=n' : set the local port
  *         'pkt_size=n'  : set max packet size
  *         'reuse=1'     : enable reusing the socket
+ *         'overrun_nonfatal=1': survive in case of circular buffer overrun
  *
  * @param h media file context
  * @param uri of the remote server
@@ -378,6 +434,61 @@
     return s->udp_fd;
 }
 
+#if HAVE_PTHREAD_CANCEL
+static void *circular_buffer_task( void *_URLContext)
+{
+    URLContext *h = _URLContext;
+    UDPContext *s = h->priv_data;
+    int old_cancelstate;
+
+    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate);
+    ff_socket_nonblock(s->udp_fd, 0);
+    pthread_mutex_lock(&s->mutex);
+    while(1) {
+        int len;
+
+        pthread_mutex_unlock(&s->mutex);
+        /* Blocking operations are always cancellation points;
+           see "General Information" / "Thread Cancelation Overview"
+           in Single Unix. */
+        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancelstate);
+        len = recv(s->udp_fd, s->tmp+4, sizeof(s->tmp)-4, 0);
+        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate);
+        pthread_mutex_lock(&s->mutex);
+        if (len < 0) {
+            if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) {
+                s->circular_buffer_error = ff_neterrno();
+                goto end;
+            }
+            continue;
+        }
+        AV_WL32(s->tmp, len);
+
+        if(av_fifo_space(s->fifo) < len + 4) {
+            /* No Space left */
+            if (s->overrun_nonfatal) {
+                av_log(h, AV_LOG_WARNING, "Circular buffer overrun. "
+                        "Surviving due to overrun_nonfatal option\n");
+                continue;
+            } else {
+                av_log(h, AV_LOG_ERROR, "Circular buffer overrun. "
+                        "To avoid, increase fifo_size URL option. "
+                        "To survive in such case, use overrun_nonfatal option\n");
+                s->circular_buffer_error = AVERROR(EIO);
+                goto end;
+            }
+        }
+        av_fifo_generic_write(s->fifo, s->tmp, len+4, NULL);
+        pthread_cond_signal(&s->cond);
+    }
+
+end:
+    pthread_cond_signal(&s->cond);
+    pthread_mutex_unlock(&s->mutex);
+    return NULL;
+}
+#endif
+
 /* put it in UDP context */
 /* return non zero if error */
 static int udp_open(URLContext *h, const char *uri, int flags)
@@ -395,12 +506,10 @@
     char *sources[32];
 
     h->is_streamed = 1;
-    h->max_packet_size = 1472;
 
     is_output = !(flags & AVIO_FLAG_READ);
-
-    s->ttl = 16;
-    s->buffer_size = is_output ? UDP_TX_BUF_SIZE : UDP_MAX_PKT_SIZE;
+    if (!s->buffer_size) /* if not set explicitly */
+        s->buffer_size = is_output ? UDP_TX_BUF_SIZE : UDP_MAX_PKT_SIZE;
 
     p = strchr(uri, '?');
     if (p) {
@@ -412,6 +521,17 @@
                 s->reuse_socket = 1;
             reuse_specified = 1;
         }
+        if (av_find_info_tag(buf, sizeof(buf), "overrun_nonfatal", p)) {
+            char *endptr = NULL;
+            s->overrun_nonfatal = strtol(buf, &endptr, 10);
+            /* assume if no digits were found it is a request to enable it */
+            if (buf == endptr)
+                s->overrun_nonfatal = 1;
+            if (!HAVE_PTHREAD_CANCEL)
+                av_log(h, AV_LOG_WARNING,
+                       "'overrun_nonfatal' option was set but it is not supported "
+                       "on this build (pthread support is required)\n");
+        }
         if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {
             s->ttl = strtol(buf, NULL, 10);
         }
@@ -419,7 +539,7 @@
             s->local_port = strtol(buf, NULL, 10);
         }
         if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
-            h->max_packet_size = strtol(buf, NULL, 10);
+            s->packet_size = strtol(buf, NULL, 10);
         }
         if (av_find_info_tag(buf, sizeof(buf), "buffer_size", p)) {
             s->buffer_size = strtol(buf, NULL, 10);
@@ -427,6 +547,13 @@
         if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
             s->is_connected = strtol(buf, NULL, 10);
         }
+        if (av_find_info_tag(buf, sizeof(buf), "fifo_size", p)) {
+            s->circular_buffer_size = strtol(buf, NULL, 10);
+            if (!HAVE_PTHREAD_CANCEL)
+                av_log(h, AV_LOG_WARNING,
+                       "'circular_buffer_size' option was set but it is not supported "
+                       "on this build (pthread support is required)\n");
+        }
         if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) {
             av_strlcpy(localaddr, buf, sizeof(localaddr));
         }
@@ -449,7 +576,13 @@
                     break;
             }
         }
+        if (!is_output && av_find_info_tag(buf, sizeof(buf), "timeout", p))
+            s->timeout = strtol(buf, NULL, 10);
     }
+    /* handling needed to support options picking from both AVOption and URL */
+    s->circular_buffer_size *= 188;
+    h->max_packet_size = s->packet_size;
+    h->rw_timeout = s->timeout;
 
     /* fill the dest addr */
     av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);
@@ -466,7 +599,7 @@
 
     if ((s->is_multicast || !s->local_port) && (h->flags & AVIO_FLAG_READ))
         s->local_port = port;
-    udp_fd = udp_socket_create(s, &my_addr, &len, localaddr);
+    udp_fd = udp_socket_create(s, &my_addr, &len, localaddr[0] ? localaddr : s->local_addr);
     if (udp_fd < 0)
         goto fail;
 
@@ -549,15 +682,48 @@
     }
 
     for (i = 0; i < num_sources; i++)
-        av_free(sources[i]);
+        av_freep(&sources[i]);
 
     s->udp_fd = udp_fd;
+
+#if HAVE_PTHREAD_CANCEL
+    if (!is_output && s->circular_buffer_size) {
+        int ret;
+
+        /* start the task going */
+        s->fifo = av_fifo_alloc(s->circular_buffer_size);
+        ret = pthread_mutex_init(&s->mutex, NULL);
+        if (ret != 0) {
+            av_log(h, AV_LOG_ERROR, "pthread_mutex_init failed : %s\n", strerror(ret));
+            goto fail;
+        }
+        ret = pthread_cond_init(&s->cond, NULL);
+        if (ret != 0) {
+            av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", strerror(ret));
+            goto cond_fail;
+        }
+        ret = pthread_create(&s->circular_buffer_thread, NULL, circular_buffer_task, h);
+        if (ret != 0) {
+            av_log(h, AV_LOG_ERROR, "pthread_create failed : %s\n", strerror(ret));
+            goto thread_fail;
+        }
+        s->thread_started = 1;
+    }
+#endif
+
     return 0;
+#if HAVE_PTHREAD_CANCEL
+ thread_fail:
+    pthread_cond_destroy(&s->cond);
+ cond_fail:
+    pthread_mutex_destroy(&s->mutex);
+#endif
  fail:
     if (udp_fd >= 0)
         closesocket(udp_fd);
+    av_fifo_free(s->fifo);
     for (i = 0; i < num_sources; i++)
-        av_free(sources[i]);
+        av_freep(&sources[i]);
     return AVERROR(EIO);
 }
 
@@ -565,6 +731,48 @@
 {
     UDPContext *s = h->priv_data;
     int ret;
+    int avail, nonblock = h->flags & AVIO_FLAG_NONBLOCK;
+
+#if HAVE_PTHREAD_CANCEL
+    if (s->fifo) {
+        pthread_mutex_lock(&s->mutex);
+        do {
+            avail = av_fifo_size(s->fifo);
+            if (avail) { // >=size) {
+                uint8_t tmp[4];
+
+                av_fifo_generic_read(s->fifo, tmp, 4, NULL);
+                avail= AV_RL32(tmp);
+                if(avail > size){
+                    av_log(h, AV_LOG_WARNING, "Part of datagram lost due to insufficient buffer size\n");
+                    avail= size;
+                }
+
+                av_fifo_generic_read(s->fifo, buf, avail, NULL);
+                av_fifo_drain(s->fifo, AV_RL32(tmp) - avail);
+                pthread_mutex_unlock(&s->mutex);
+                return avail;
+            } else if(s->circular_buffer_error){
+                int err = s->circular_buffer_error;
+                pthread_mutex_unlock(&s->mutex);
+                return err;
+            } else if(nonblock) {
+                pthread_mutex_unlock(&s->mutex);
+                return AVERROR(EAGAIN);
+            }
+            else {
+                /* FIXME: using the monotonic clock would be better,
+                   but it does not exist on all supported platforms. */
+                int64_t t = av_gettime() + 100000;
+                struct timespec tv = { .tv_sec  =  t / 1000000,
+                                       .tv_nsec = (t % 1000000) * 1000 };
+                if (pthread_cond_timedwait(&s->cond, &s->mutex, &tv) < 0)
+                    return AVERROR(errno == ETIMEDOUT ? EAGAIN : errno);
+                nonblock = 1;
+            }
+        } while( 1);
+    }
+#endif
 
     if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
         ret = ff_network_wait_fd(s->udp_fd, 0);
@@ -572,6 +780,7 @@
             return ret;
     }
     ret = recv(s->udp_fd, buf, size, 0);
+
     return ret < 0 ? ff_neterrno() : ret;
 }
 
@@ -599,10 +808,22 @@
 static int udp_close(URLContext *h)
 {
     UDPContext *s = h->priv_data;
+    int ret;
 
     if (s->is_multicast && (h->flags & AVIO_FLAG_READ))
         udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr);
     closesocket(s->udp_fd);
+#if HAVE_PTHREAD_CANCEL
+    if (s->thread_started) {
+        pthread_cancel(s->circular_buffer_thread);
+        ret = pthread_join(s->circular_buffer_thread, NULL);
+        if (ret != 0)
+            av_log(h, AV_LOG_ERROR, "pthread_join(): %s\n", strerror(ret));
+        pthread_mutex_destroy(&s->mutex);
+        pthread_cond_destroy(&s->cond);
+    }
+#endif
+    av_fifo_free(s->fifo);
     return 0;
 }
 
@@ -614,5 +835,6 @@
     .url_close           = udp_close,
     .url_get_file_handle = udp_get_file_handle,
     .priv_data_size      = sizeof(UDPContext),
+    .priv_data_class     = &udp_context_class,
     .flags               = URL_PROTOCOL_FLAG_NETWORK,
 };
diff --git a/libavformat/url-test.c b/libavformat/url-test.c
index 58258e5..ceaffe8 100644
--- a/libavformat/url-test.c
+++ b/libavformat/url-test.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2012 Martin Storsjo
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/url.h b/libavformat/url.h
index 195a8ff..5f75dc9 100644
--- a/libavformat/url.h
+++ b/libavformat/url.h
@@ -1,19 +1,19 @@
 /*
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -48,6 +48,7 @@
     int is_streamed;            /**< true if streamed (no seek possible), default = false */
     int is_connected;
     AVIOInterruptCB interrupt_callback;
+    int64_t rw_timeout;         /**< maximum time to wait for (network) read/write operation completion, in mcs */
 } URLContext;
 
 typedef struct URLProtocol {
@@ -181,11 +182,12 @@
 
 /**
  * Close the resource accessed by the URLContext h, and free the
- * memory used by it.
+ * memory used by it. Also set the URLContext pointer to NULL.
  *
  * @return a negative value if an error condition occurred, 0
  * otherwise
  */
+int ffurl_closep(URLContext **h);
 int ffurl_close(URLContext *h);
 
 /**
diff --git a/libavformat/urldecode.c b/libavformat/urldecode.c
index 32460da..b100903 100644
--- a/libavformat/urldecode.c
+++ b/libavformat/urldecode.c
@@ -9,20 +9,20 @@
  * based on http://www.icosaedro.it/apache/urldecode.c
  *          from Umberto Salsi (salsi@icosaedro.it)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/urldecode.h b/libavformat/urldecode.h
index b43f319..cb81ebc 100644
--- a/libavformat/urldecode.h
+++ b/libavformat/urldecode.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/utils.c b/libavformat/utils.c
index ca52469..745dcaa 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1,21 +1,21 @@
 /*
- * various utility functions for use within Libav
+ * various utility functions for use within FFmpeg
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,7 +25,9 @@
 #include "avio_internal.h"
 #include "internal.h"
 #include "libavcodec/internal.h"
+#include "libavcodec/raw.h"
 #include "libavcodec/bytestream.h"
+#include "libavutil/avassert.h"
 #include "libavutil/opt.h"
 #include "libavutil/dict.h"
 #include "libavutil/pixdesc.h"
@@ -36,6 +38,7 @@
 #include "libavutil/mathematics.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/time.h"
+#include "libavutil/timestamp.h"
 #include "riff.h"
 #include "audiointerleave.h"
 #include "url.h"
@@ -49,23 +52,30 @@
 
 /**
  * @file
- * various utility functions for use within Libav
+ * various utility functions for use within FFmpeg
  */
 
 unsigned avformat_version(void)
 {
+    av_assert0(LIBAVFORMAT_VERSION_MICRO >= 100);
     return LIBAVFORMAT_VERSION_INT;
 }
 
 const char *avformat_configuration(void)
 {
-    return LIBAV_CONFIGURATION;
+    return FFMPEG_CONFIGURATION;
 }
 
 const char *avformat_license(void)
 {
 #define LICENSE_PREFIX "libavformat license: "
-    return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+    return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+}
+
+#define RELATIVE_TS_BASE (INT64_MAX - (1LL<<48))
+
+static int is_relative(int64_t ts) {
+    return ts > (RELATIVE_TS_BASE - (1LL<<48));
 }
 
 /** head of registered input format linked list */
@@ -167,7 +177,7 @@
     score_max = 0;
     while ((fmt = av_oformat_next(fmt))) {
         score = 0;
-        if (fmt->name && short_name && !av_strcasecmp(fmt->name, short_name))
+        if (fmt->name && short_name && match_format(short_name, fmt->name))
             score += 100;
         if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type))
             score += 10;
@@ -214,10 +224,33 @@
     return NULL;
 }
 
+int ffio_limit(AVIOContext *s, int size)
+{
+    if(s->maxsize>=0){
+        int64_t remaining= s->maxsize - avio_tell(s);
+        if(remaining < size){
+            int64_t newsize= avio_size(s);
+            if(!s->maxsize || s->maxsize<newsize)
+                s->maxsize= newsize - !newsize;
+            remaining= s->maxsize - avio_tell(s);
+            remaining= FFMAX(remaining, 0);
+        }
+
+        if(s->maxsize>=0 && remaining+1 < size){
+            av_log(0, remaining ? AV_LOG_ERROR : AV_LOG_DEBUG, "Truncating packet of size %d to %"PRId64"\n", size, remaining+1);
+            size= remaining+1;
+        }
+    }
+    return size;
+}
 
 int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
 {
-    int ret= av_new_packet(pkt, size);
+    int ret;
+    int orig_size = size;
+    size= ffio_limit(s, size);
+
+    ret= av_new_packet(pkt, size);
 
     if(ret<0)
         return ret;
@@ -229,6 +262,8 @@
         av_free_packet(pkt);
     else
         av_shrink_packet(pkt, ret);
+    if (pkt->size < orig_size)
+        pkt->flags |= AV_PKT_FLAG_CORRUPT;
 
     return ret;
 }
@@ -255,19 +290,19 @@
     return filename && (av_get_frame_filename(buf, sizeof(buf), filename, 1)>=0);
 }
 
-AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max)
+AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score_ret)
 {
     AVProbeData lpd = *pd;
     AVInputFormat *fmt1 = NULL, *fmt;
-    int score, id3 = 0;
+    int score, nodat = 0, score_max=0;
 
     if (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) {
         int id3len = ff_id3v2_tag_len(lpd.buf);
         if (lpd.buf_size > id3len + 16) {
             lpd.buf += id3len;
             lpd.buf_size -= id3len;
-        }
-        id3 = 1;
+        }else
+            nodat = 1;
     }
 
     fmt = NULL;
@@ -277,44 +312,41 @@
         score = 0;
         if (fmt1->read_probe) {
             score = fmt1->read_probe(&lpd);
+            if(fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions))
+                score = FFMAX(score, nodat ? AVPROBE_SCORE_MAX/4-1 : 1);
         } else if (fmt1->extensions) {
             if (av_match_ext(lpd.filename, fmt1->extensions)) {
                 score = 50;
             }
         }
-        if (score > *score_max) {
-            *score_max = score;
+        if (score > score_max) {
+            score_max = score;
             fmt = fmt1;
-        }else if (score == *score_max)
+        }else if (score == score_max)
             fmt = NULL;
     }
-
-    /* a hack for files with huge id3v2 tags -- try to guess by file extension. */
-    if (!fmt && is_opened && *score_max < AVPROBE_SCORE_MAX/4) {
-        while ((fmt = av_iformat_next(fmt)))
-            if (fmt->extensions && av_match_ext(lpd.filename, fmt->extensions)) {
-                *score_max = AVPROBE_SCORE_MAX/4;
-                break;
-            }
-    }
-
-    if (!fmt && id3 && *score_max < AVPROBE_SCORE_MAX/4-1) {
-        while ((fmt = av_iformat_next(fmt)))
-            if (fmt->extensions && av_match_ext("mp3", fmt->extensions)) {
-                *score_max = AVPROBE_SCORE_MAX/4-1;
-                break;
-            }
-    }
+    *score_ret= score_max;
 
     return fmt;
 }
 
+AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max)
+{
+    int score_ret;
+    AVInputFormat *fmt= av_probe_input_format3(pd, is_opened, &score_ret);
+    if(score_ret > *score_max){
+        *score_max= score_ret;
+        return fmt;
+    }else
+        return NULL;
+}
+
 AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened){
     int score=0;
     return av_probe_input_format2(pd, is_opened, &score);
 }
 
-static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeData *pd, int score)
+static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeData *pd)
 {
     static const struct {
         const char *name; enum AVCodecID id; enum AVMediaType type;
@@ -324,14 +356,16 @@
         { "dts"      , AV_CODEC_ID_DTS       , AVMEDIA_TYPE_AUDIO },
         { "eac3"     , AV_CODEC_ID_EAC3      , AVMEDIA_TYPE_AUDIO },
         { "h264"     , AV_CODEC_ID_H264      , AVMEDIA_TYPE_VIDEO },
+        { "loas"     , AV_CODEC_ID_AAC_LATM  , AVMEDIA_TYPE_AUDIO },
         { "m4v"      , AV_CODEC_ID_MPEG4     , AVMEDIA_TYPE_VIDEO },
         { "mp3"      , AV_CODEC_ID_MP3       , AVMEDIA_TYPE_AUDIO },
         { "mpegvideo", AV_CODEC_ID_MPEG2VIDEO, AVMEDIA_TYPE_VIDEO },
         { 0 }
     };
-    AVInputFormat *fmt = av_probe_input_format2(pd, 1, &score);
+    int score;
+    AVInputFormat *fmt = av_probe_input_format3(pd, 1, &score);
 
-    if (fmt) {
+    if (fmt && st->request_probe <= score) {
         int i;
         av_log(s, AV_LOG_DEBUG, "Probe with size=%d, packets=%d detected %s with score=%d\n",
                pd->buf_size, MAX_PROBE_PACKETS - st->probe_packets, fmt->name, score);
@@ -343,12 +377,28 @@
             }
         }
     }
-    return !!fmt;
+    return score;
 }
 
 /************************************************************/
 /* input media file */
 
+int av_demuxer_open(AVFormatContext *ic){
+    int err;
+
+    if (ic->iformat->read_header) {
+        err = ic->iformat->read_header(ic);
+        if (err < 0)
+            return err;
+    }
+
+    if (ic->pb && !ic->data_offset)
+        ic->data_offset = avio_tell(ic->pb);
+
+    return 0;
+}
+
+
 /** size of probe buffer, for guessing file type from file contents */
 #define PROBE_BUF_MIN 2048
 #define PROBE_BUF_MAX (1<<20)
@@ -375,15 +425,21 @@
 
     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_MAX/4 : 0;
+        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) {
             continue;
         }
 
         /* read probe data */
-        buf = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE);
+        buftmp = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE);
+        if(!buftmp){
+            av_free(buf);
+            return AVERROR(ENOMEM);
+        }
+        buf=buftmp;
         if ((ret = avio_read(pb, buf + buf_offset, probe_size - buf_offset)) < 0) {
             /* fail if error was not end of file, otherwise, lower score */
             if (ret != AVERROR_EOF) {
@@ -401,10 +457,10 @@
         /* guess file format */
         *fmt = av_probe_input_format2(&pd, 1, &score);
         if(*fmt){
-            if(score <= AVPROBE_SCORE_MAX/4){ //this can only be true in the last iteration
-                av_log(logctx, AV_LOG_WARNING, "Format detected only with low score of %d, misdetection possible!\n", score);
+            if(score <= AVPROBE_SCORE_RETRY){ //this can only be true in the last iteration
+                av_log(logctx, AV_LOG_WARNING, "Format %s detected only with low score of %d, misdetection possible!\n", (*fmt)->name, score);
             }else
-                av_log(logctx, AV_LOG_DEBUG, "Probed with size=%d and score=%d\n", probe_size, score);
+                av_log(logctx, AV_LOG_DEBUG, "Format %s probed with size=%d and score=%d\n", (*fmt)->name, probe_size, score);
         }
     }
 
@@ -414,8 +470,7 @@
     }
 
     /* rewind. reuse probe buffer to avoid seeking */
-    if ((ret = ffio_rewind_with_probe_data(pb, buf, pd.buf_size)) < 0)
-        av_free(buf);
+    ret = ffio_rewind_with_probe_data(pb, &buf, pd.buf_size);
 
     return ret;
 }
@@ -425,21 +480,23 @@
 {
     int ret;
     AVProbeData pd = {filename, NULL, 0};
+    int score = AVPROBE_SCORE_RETRY;
 
     if (s->pb) {
         s->flags |= AVFMT_FLAG_CUSTOM_IO;
         if (!s->iformat)
             return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, s->probesize);
         else if (s->iformat->flags & AVFMT_NOFILE)
-            return AVERROR(EINVAL);
+            av_log(s, AV_LOG_WARNING, "Custom AVIOContext makes no sense and "
+                                      "will be ignored with AVFMT_NOFILE format.\n");
         return 0;
     }
 
     if ( (s->iformat && s->iformat->flags & AVFMT_NOFILE) ||
-        (!s->iformat && (s->iformat = av_probe_input_format(&pd, 0))))
+        (!s->iformat && (s->iformat = av_probe_input_format2(&pd, 0, &score))))
         return 0;
 
-    if ((ret = avio_open2(&s->pb, filename, AVIO_FLAG_READ,
+    if ((ret = avio_open2(&s->pb, filename, AVIO_FLAG_READ | s->avio_flags,
                           &s->interrupt_callback, options)) < 0)
         return ret;
     if (s->iformat)
@@ -464,7 +521,7 @@
     return &pktl->pkt;
 }
 
-static void queue_attached_pictures(AVFormatContext *s)
+void avformat_queue_attached_pictures(AVFormatContext *s)
 {
     int i;
     for (i = 0; i < s->nb_streams; i++)
@@ -485,6 +542,10 @@
 
     if (!s && !(s = avformat_alloc_context()))
         return AVERROR(ENOMEM);
+    if (!s->av_class){
+        av_log(0, AV_LOG_ERROR, "Input context has not been properly allocated by avformat_alloc_context() and is not NULL either\n");
+        return AVERROR(EINVAL);
+    }
     if (fmt)
         s->iformat = fmt;
 
@@ -526,18 +587,22 @@
     if (s->pb)
         ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
 
-    if (s->iformat->read_header)
+    if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header)
         if ((ret = s->iformat->read_header(s)) < 0)
             goto fail;
 
-    if (id3v2_extra_meta &&
-        (ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0)
-        goto fail;
+    if (id3v2_extra_meta) {
+        if (!strcmp(s->iformat->name, "mp3")) {
+            if((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0)
+                goto fail;
+        } else
+            av_log(s, AV_LOG_DEBUG, "demuxer does not support additional id3 data, skipping\n");
+    }
     ff_id3v2_free_extra_meta(&id3v2_extra_meta);
 
-    queue_attached_pictures(s);
+    avformat_queue_attached_pictures(s);
 
-    if (s->pb && !s->data_offset)
+    if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->pb && !s->data_offset)
         s->data_offset = avio_tell(s->pb);
 
     s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
@@ -563,37 +628,63 @@
 
 static void probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
 {
-    if(st->codec->codec_id == AV_CODEC_ID_PROBE){
+    if(st->request_probe>0){
         AVProbeData *pd = &st->probe_data;
-        av_log(s, AV_LOG_DEBUG, "probing stream %d\n", st->index);
+        int end;
+        av_log(s, AV_LOG_DEBUG, "probing stream %d pp:%d\n", st->index, st->probe_packets);
         --st->probe_packets;
 
         if (pkt) {
-            pd->buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
+            uint8_t *new_buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
+            if(!new_buf)
+                goto no_packet;
+            pd->buf = new_buf;
             memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size);
             pd->buf_size += pkt->size;
             memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE);
         } else {
+no_packet:
             st->probe_packets = 0;
             if (!pd->buf_size) {
-                av_log(s, AV_LOG_ERROR, "nothing to probe for stream %d\n",
+                av_log(s, AV_LOG_WARNING, "nothing to probe for stream %d\n",
                        st->index);
-                return;
             }
         }
 
-        if (!st->probe_packets ||
-            av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)) {
-            set_codec_from_probe_data(s, st, pd, st->probe_packets > 0 ? AVPROBE_SCORE_MAX/4 : 0);
-            if(st->codec->codec_id != AV_CODEC_ID_PROBE){
+        end=    s->raw_packet_buffer_remaining_size <= 0
+                || st->probe_packets<=0;
+
+        if(end || av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){
+            int score= set_codec_from_probe_data(s, st, pd);
+            if(    (st->codec->codec_id != AV_CODEC_ID_NONE && score > AVPROBE_SCORE_RETRY)
+                || end){
                 pd->buf_size=0;
                 av_freep(&pd->buf);
-                av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index);
+                st->request_probe= -1;
+                if(st->codec->codec_id != AV_CODEC_ID_NONE){
+                    av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index);
+                }else
+                    av_log(s, AV_LOG_WARNING, "probed stream %d failed\n", st->index);
             }
         }
     }
 }
 
+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;
@@ -605,15 +696,7 @@
         if (pktl) {
             *pkt = pktl->pkt;
             st = s->streams[pkt->stream_index];
-            if (st->codec->codec_id != AV_CODEC_ID_PROBE || !st->probe_packets ||
-                s->raw_packet_buffer_remaining_size < pkt->size) {
-                AVProbeData *pd;
-                if (st->probe_packets) {
-                    probe_codec(s, st, NULL);
-                }
-                pd = &st->probe_data;
-                av_freep(&pd->buf);
-                pd->buf_size = 0;
+            if(st->request_probe <= 0){
                 s->raw_packet_buffer = pktl->next;
                 s->raw_packet_buffer_remaining_size += pkt->size;
                 av_free(pktl);
@@ -633,6 +716,7 @@
                 if (st->probe_packets) {
                     probe_codec(s, st, NULL);
                 }
+                av_assert0(st->request_probe <= 0);
             }
             continue;
         }
@@ -646,22 +730,23 @@
             continue;
         }
 
-        st= s->streams[pkt->stream_index];
+        if(!(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA))
+            av_packet_merge_side_data(pkt);
 
-        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;
+        if(pkt->stream_index >= (unsigned)s->nb_streams){
+            av_log(s, AV_LOG_ERROR, "Invalid stream index %d\n", pkt->stream_index);
+            continue;
         }
 
-        if(!pktl && (st->codec->codec_id != AV_CODEC_ID_PROBE ||
-                     !st->probe_packets))
+        st= s->streams[pkt->stream_index];
+
+        force_codec_ids(s, st);
+
+        /* TODO: audio: time filter; video: frame reordering (pts != dts) */
+        if (s->use_wallclock_as_timestamps)
+            pkt->dts = pkt->pts = av_rescale_q(av_gettime(), AV_TIME_BASE_Q, st->time_base);
+
+        if(!pktl && st->request_probe <= 0)
             return ret;
 
         add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end);
@@ -681,6 +766,17 @@
 
 /**********************************************************/
 
+static int determinable_frame_size(AVCodecContext *avctx)
+{
+    if (/*avctx->codec_id == AV_CODEC_ID_AAC ||*/
+        avctx->codec_id == AV_CODEC_ID_MP1 ||
+        avctx->codec_id == AV_CODEC_ID_MP2 ||
+        avctx->codec_id == AV_CODEC_ID_MP3/* ||
+        avctx->codec_id == AV_CODEC_ID_CELT*/)
+        return 1;
+    return 0;
+}
+
 /**
  * Get the number of samples of an audio frame. Return -1 on error.
  */
@@ -715,9 +811,9 @@
     *pden = 0;
     switch(st->codec->codec_type) {
     case AVMEDIA_TYPE_VIDEO:
-        if (st->avg_frame_rate.num) {
-            *pnum = st->avg_frame_rate.den;
-            *pden = st->avg_frame_rate.num;
+        if (st->r_frame_rate.num && !pc) {
+            *pnum = st->r_frame_rate.den;
+            *pden = st->r_frame_rate.num;
         } else if(st->time_base.num*1000LL > st->time_base.den) {
             *pnum = st->time_base.num;
             *pden = st->time_base.den;
@@ -746,40 +842,91 @@
     }
 }
 
-static int is_intra_only(enum AVCodecID id)
+static int is_intra_only(AVCodecContext *enc){
+    const AVCodecDescriptor *desc;
+
+    if(enc->codec_type != AVMEDIA_TYPE_VIDEO)
+        return 1;
+
+    desc = av_codec_get_codec_descriptor(enc);
+    if (!desc) {
+        desc = avcodec_descriptor_get(enc->codec_id);
+        av_codec_set_codec_descriptor(enc, desc);
+    }
+    if (desc)
+        return !!(desc->props & AV_CODEC_PROP_INTRA_ONLY);
+    return 0;
+}
+
+static int has_decode_delay_been_guessed(AVStream *st)
 {
-    const AVCodecDescriptor *d = avcodec_descriptor_get(id);
-    if (!d)
-        return 0;
-    if (d->type == AVMEDIA_TYPE_VIDEO && !(d->props & AV_CODEC_PROP_INTRA_ONLY))
-        return 0;
-    return 1;
+    if(st->codec->codec_id != AV_CODEC_ID_H264) return 1;
+    if(!st->info) // if we have left find_stream_info then nb_decoded_frames wont increase anymore for stream copy
+        return 1;
+#if CONFIG_H264_DECODER
+    if(st->codec->has_b_frames &&
+       avpriv_h264_has_num_reorder_frames(st->codec) == st->codec->has_b_frames)
+        return 1;
+#endif
+    if(st->codec->has_b_frames<3)
+        return st->nb_decoded_frames >= 7;
+    else if(st->codec->has_b_frames<4)
+        return st->nb_decoded_frames >= 18;
+    else
+        return st->nb_decoded_frames >= 20;
+}
+
+static AVPacketList *get_next_pkt(AVFormatContext *s, AVStream *st, AVPacketList *pktl)
+{
+    if (pktl->next)
+        return pktl->next;
+    if (pktl == s->parse_queue_end)
+        return s->packet_buffer;
+    return NULL;
 }
 
 static void update_initial_timestamps(AVFormatContext *s, int stream_index,
                                       int64_t dts, int64_t pts)
 {
     AVStream *st= s->streams[stream_index];
-    AVPacketList *pktl= s->packet_buffer;
+    AVPacketList *pktl= s->parse_queue ? s->parse_queue : s->packet_buffer;
+    int64_t pts_buffer[MAX_REORDER_DELAY+1];
+    int64_t shift;
+    int i, delay;
 
-    if(st->first_dts != AV_NOPTS_VALUE || dts == AV_NOPTS_VALUE || st->cur_dts == AV_NOPTS_VALUE)
+    if(st->first_dts != AV_NOPTS_VALUE || dts == AV_NOPTS_VALUE || st->cur_dts == AV_NOPTS_VALUE || is_relative(dts))
         return;
 
-    st->first_dts= dts - st->cur_dts;
+    delay = st->codec->has_b_frames;
+    st->first_dts= dts - (st->cur_dts - RELATIVE_TS_BASE);
     st->cur_dts= dts;
+    shift = st->first_dts - RELATIVE_TS_BASE;
 
-    for(; pktl; pktl= pktl->next){
+    for (i=0; i<MAX_REORDER_DELAY+1; i++)
+        pts_buffer[i] = AV_NOPTS_VALUE;
+
+    if (is_relative(pts))
+        pts += shift;
+
+    for(; pktl; pktl= get_next_pkt(s, st, pktl)){
         if(pktl->pkt.stream_index != stream_index)
             continue;
-        //FIXME think more about this check
-        if(pktl->pkt.pts != AV_NOPTS_VALUE && pktl->pkt.pts == pktl->pkt.dts)
-            pktl->pkt.pts += st->first_dts;
+        if(is_relative(pktl->pkt.pts))
+            pktl->pkt.pts += shift;
 
-        if(pktl->pkt.dts != AV_NOPTS_VALUE)
-            pktl->pkt.dts += st->first_dts;
+        if(is_relative(pktl->pkt.dts))
+            pktl->pkt.dts += shift;
 
         if(st->start_time == AV_NOPTS_VALUE && pktl->pkt.pts != AV_NOPTS_VALUE)
             st->start_time= pktl->pkt.pts;
+
+        if(pktl->pkt.pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY && has_decode_delay_been_guessed(st)){
+            pts_buffer[0]= pktl->pkt.pts;
+            for(i=0; i<delay && pts_buffer[i] > pts_buffer[i+1]; i++)
+                FFSWAP(int64_t, pts_buffer[i], pts_buffer[i+1]);
+            if(pktl->pkt.dts == AV_NOPTS_VALUE)
+                pktl->pkt.dts= pts_buffer[0];
+        }
     }
     if (st->start_time == AV_NOPTS_VALUE)
         st->start_time = pts;
@@ -788,38 +935,46 @@
 static void update_initial_durations(AVFormatContext *s, AVStream *st,
                                      int stream_index, int duration)
 {
-    AVPacketList *pktl= s->packet_buffer;
-    int64_t cur_dts= 0;
+    AVPacketList *pktl= s->parse_queue ? s->parse_queue : s->packet_buffer;
+    int64_t cur_dts= RELATIVE_TS_BASE;
 
     if(st->first_dts != AV_NOPTS_VALUE){
         cur_dts= st->first_dts;
-        for(; pktl; pktl= pktl->next){
+        for(; pktl; pktl= get_next_pkt(s, st, pktl)){
             if(pktl->pkt.stream_index == stream_index){
                 if(pktl->pkt.pts != pktl->pkt.dts || pktl->pkt.dts != AV_NOPTS_VALUE || pktl->pkt.duration)
                     break;
                 cur_dts -= duration;
             }
         }
-        pktl= s->packet_buffer;
+        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));
+            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));
+            return;
+        }
+        pktl= s->parse_queue ? s->parse_queue : s->packet_buffer;
         st->first_dts = cur_dts;
-    }else if(st->cur_dts)
+    }else if(st->cur_dts != RELATIVE_TS_BASE)
         return;
 
-    for(; pktl; pktl= pktl->next){
+    for(; pktl; pktl= get_next_pkt(s, st, pktl)){
         if(pktl->pkt.stream_index != stream_index)
             continue;
-        if(pktl->pkt.pts == pktl->pkt.dts && pktl->pkt.dts == AV_NOPTS_VALUE
+        if(pktl->pkt.pts == pktl->pkt.dts && (pktl->pkt.dts == AV_NOPTS_VALUE || pktl->pkt.dts == st->first_dts)
            && !pktl->pkt.duration){
             pktl->pkt.dts= cur_dts;
             if(!st->codec->has_b_frames)
                 pktl->pkt.pts= cur_dts;
-            cur_dts += duration;
-            if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO)
+//            if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO)
                 pktl->pkt.duration = duration;
         }else
             break;
+        cur_dts = pktl->pkt.dts + pktl->pkt.duration;
     }
-    if(st->first_dts == AV_NOPTS_VALUE)
+    if(!pktl)
         st->cur_dts= cur_dts;
 }
 
@@ -835,6 +990,10 @@
     if((s->flags & AVFMT_FLAG_IGNDTS) && pkt->pts != AV_NOPTS_VALUE)
         pkt->dts= AV_NOPTS_VALUE;
 
+    if (st->codec->codec_id != AV_CODEC_ID_H264 && pc && pc->pict_type == AV_PICTURE_TYPE_B)
+        //FIXME Set low_delay = 0 when has_b_frames = 1
+        st->codec->has_b_frames = 1;
+
     /* do we have a video B-frame ? */
     delay= st->codec->has_b_frames;
     presentation_delayed = 0;
@@ -845,28 +1004,30 @@
         pc && pc->pict_type != AV_PICTURE_TYPE_B)
         presentation_delayed = 1;
 
-    if(pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && pkt->dts > pkt->pts && st->pts_wrap_bits<63
-       /*&& pkt->dts-(1LL<<st->pts_wrap_bits) < pkt->pts*/){
-        pkt->dts -= 1LL<<st->pts_wrap_bits;
+    if(pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && st->pts_wrap_bits<63 && pkt->dts - (1LL<<(st->pts_wrap_bits-1)) > pkt->pts){
+        if(is_relative(st->cur_dts) || pkt->dts - (1LL<<(st->pts_wrap_bits-1)) > st->cur_dts) {
+            pkt->dts -= 1LL<<st->pts_wrap_bits;
+        } else
+            pkt->pts += 1LL<<st->pts_wrap_bits;
     }
 
     // some mpeg2 in mpeg-ps lack dts (issue171 / input_file.mpg)
     // we take the conservative approach and discard both
     // Note, if this is misbehaving for a H.264 file then possibly presentation_delayed is not set correctly.
     if(delay==1 && pkt->dts == pkt->pts && pkt->dts != AV_NOPTS_VALUE && presentation_delayed){
-        av_log(s, AV_LOG_DEBUG, "invalid dts/pts combination\n");
-        pkt->dts= pkt->pts= AV_NOPTS_VALUE;
+        av_log(s, AV_LOG_DEBUG, "invalid dts/pts combination %"PRIi64"\n", pkt->dts);
+        if(strcmp(s->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2")) // otherwise we discard correct timestamps for vc1-wmapro.ism
+            pkt->dts= AV_NOPTS_VALUE;
     }
 
-    if (pkt->duration == 0 && st->codec->codec_type != AVMEDIA_TYPE_AUDIO) {
+    if (pkt->duration == 0) {
         ff_compute_frame_duration(&num, &den, st, pc, pkt);
         if (den && num) {
             pkt->duration = av_rescale_rnd(1, num * (int64_t)st->time_base.den, den * (int64_t)st->time_base.num, AV_ROUND_DOWN);
-
-            if(pkt->duration != 0 && s->packet_buffer)
-                update_initial_durations(s, st, pkt->stream_index, pkt->duration);
         }
     }
+    if(pkt->duration != 0 && (s->packet_buffer || s->parse_queue))
+        update_initial_durations(s, st, pkt->stream_index, pkt->duration);
 
     /* correct timestamps with byte offset if demuxers only have timestamps
        on packet boundaries */
@@ -902,10 +1063,8 @@
     if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts > pkt->dts)
         presentation_delayed = 1;
 
-    av_dlog(NULL,
-            "IN delayed:%d pts:%"PRId64", dts:%"PRId64" cur_dts:%"PRId64" st:%d pc:%p\n",
-            presentation_delayed, pkt->pts, pkt->dts, st->cur_dts,
-            pkt->stream_index, pc);
+    av_dlog(NULL, "IN delayed:%d pts:%s, dts:%s cur_dts:%s st:%d pc:%p duration:%d\n",
+           presentation_delayed, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts), pkt->stream_index, pc, pkt->duration);
     /* interpolate PTS and DTS if they are not present */
     //We skip H264 currently because delay and has_b_frames are not reliably set
     if((delay==0 || (delay==1 && pc)) && st->codec->codec_id != AV_CODEC_ID_H264){
@@ -930,57 +1089,54 @@
             by knowing the future */
         } else if (pkt->pts != AV_NOPTS_VALUE ||
                    pkt->dts != AV_NOPTS_VALUE ||
-                   pkt->duration              ||
-                   st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+                   pkt->duration                ) {
             int duration = pkt->duration;
-            if (!duration && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
-                ff_compute_frame_duration(&num, &den, st, pc, pkt);
-                if (den && num) {
-                    duration = av_rescale_rnd(1, num * (int64_t)st->time_base.den,
-                                                 den * (int64_t)st->time_base.num,
-                                                 AV_ROUND_DOWN);
-                    if (duration != 0 && s->packet_buffer) {
-                        update_initial_durations(s, st, pkt->stream_index,
-                                                 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);
                 }
             }
 
-            if (pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE ||
-                duration) {
-                /* 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);
-                if (pkt->pts == AV_NOPTS_VALUE)
-                    pkt->pts = st->cur_dts;
-                pkt->dts = pkt->pts;
-                if (pkt->pts != AV_NOPTS_VALUE)
-                    st->cur_dts = pkt->pts + duration;
-            }
+            /* 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);
+            if (pkt->pts == AV_NOPTS_VALUE)
+                pkt->pts = st->cur_dts;
+            pkt->dts = pkt->pts;
+            if (pkt->pts != AV_NOPTS_VALUE)
+                st->cur_dts = pkt->pts + duration;
         }
     }
 
-    if(pkt->pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY){
+    if(pkt->pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY && has_decode_delay_been_guessed(st)){
         st->pts_buffer[0]= pkt->pts;
         for(i=0; i<delay && st->pts_buffer[i] > st->pts_buffer[i+1]; i++)
             FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i+1]);
         if(pkt->dts == AV_NOPTS_VALUE)
             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
-        }
-        if(pkt->dts > st->cur_dts)
-            st->cur_dts = pkt->dts;
     }
+    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
+    }
+    if(pkt->dts > st->cur_dts)
+        st->cur_dts = pkt->dts;
 
-    av_dlog(NULL,
-            "OUTdelayed:%d/%d pts:%"PRId64", dts:%"PRId64" cur_dts:%"PRId64"\n",
-            presentation_delayed, delay, pkt->pts, pkt->dts, st->cur_dts);
+    av_dlog(NULL, "OUTdelayed:%d/%d pts:%s, dts:%s cur_dts:%s\n",
+            presentation_delayed, delay, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts));
 
     /* update flags */
-    if (is_intra_only(st->codec->codec_id))
+    if (is_intra_only(st->codec))
         pkt->flags |= AV_PKT_FLAG_KEY;
     if (pc)
         pkt->convergence_duration = pc->convergence_duration;
@@ -1014,6 +1170,9 @@
         av_init_packet(&flush_pkt);
         pkt = &flush_pkt;
         got_output = 1;
+    } else if (!size && st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) {
+        // preserve 0-size sync packets
+        compute_pkt_fields(s, st, st->parser, pkt);
     }
 
     while (size > 0 || (pkt == &flush_pkt && got_output)) {
@@ -1025,6 +1184,7 @@
                                pkt->pts, pkt->dts, pkt->pos);
 
         pkt->pts = pkt->dts = AV_NOPTS_VALUE;
+        pkt->pos = -1;
         /* increment read pointer */
         data += len;
         size -= len;
@@ -1056,19 +1216,18 @@
         out_pkt.dts = st->parser->dts;
         out_pkt.pos = st->parser->pos;
 
+        if(st->need_parsing == AVSTREAM_PARSE_FULL_RAW)
+            out_pkt.pos = st->parser->frame_offset;
+
         if (st->parser->key_frame == 1 ||
             (st->parser->key_frame == -1 &&
              st->parser->pict_type == AV_PICTURE_TYPE_I))
             out_pkt.flags |= AV_PKT_FLAG_KEY;
 
-        compute_pkt_fields(s, st, st->parser, &out_pkt);
+        if(st->parser->key_frame == -1 && st->parser->pict_type==AV_PICTURE_TYPE_NONE && (pkt->flags&AV_PKT_FLAG_KEY))
+            out_pkt.flags |= AV_PKT_FLAG_KEY;
 
-        if ((s->iformat->flags & AVFMT_GENERIC_INDEX) &&
-            out_pkt.flags & AV_PKT_FLAG_KEY) {
-            ff_reduce_index(s, st->index);
-            av_add_index_entry(st, st->parser->frame_offset, out_pkt.dts,
-                               0, 0, AVINDEX_KEYFRAME);
-        }
+        compute_pkt_fields(s, st, st->parser, &out_pkt);
 
         if (out_pkt.data == pkt->data && out_pkt.size == pkt->size) {
             out_pkt.destruct = pkt->destruct;
@@ -1142,17 +1301,17 @@
         if (cur_pkt.pts != AV_NOPTS_VALUE &&
             cur_pkt.dts != AV_NOPTS_VALUE &&
             cur_pkt.pts < cur_pkt.dts) {
-            av_log(s, AV_LOG_WARNING, "Invalid timestamps stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d\n",
+            av_log(s, AV_LOG_WARNING, "Invalid timestamps stream=%d, pts=%s, dts=%s, size=%d\n",
                    cur_pkt.stream_index,
-                   cur_pkt.pts,
-                   cur_pkt.dts,
+                   av_ts2str(cur_pkt.pts),
+                   av_ts2str(cur_pkt.dts),
                    cur_pkt.size);
         }
         if (s->debug & FF_FDEBUG_TS)
-            av_log(s, AV_LOG_DEBUG, "ff_read_packet stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, duration=%d, flags=%d\n",
+            av_log(s, AV_LOG_DEBUG, "ff_read_packet stream=%d, pts=%s, dts=%s, size=%d, duration=%d, flags=%d\n",
                    cur_pkt.stream_index,
-                   cur_pkt.pts,
-                   cur_pkt.dts,
+                   av_ts2str(cur_pkt.pts),
+                   av_ts2str(cur_pkt.dts),
                    cur_pkt.size,
                    cur_pkt.duration,
                    cur_pkt.flags);
@@ -1160,12 +1319,17 @@
         if (st->need_parsing && !st->parser && !(s->flags & AVFMT_FLAG_NOPARSE)) {
             st->parser = av_parser_init(st->codec->codec_id);
             if (!st->parser) {
+                av_log(s, AV_LOG_VERBOSE, "parser not found for codec "
+                       "%s, packets or times may be invalid.\n",
+                       avcodec_get_name(st->codec->codec_id));
                 /* no parser available: just output the raw packets */
                 st->need_parsing = AVSTREAM_PARSE_NONE;
             } else if(st->need_parsing == AVSTREAM_PARSE_HEADERS) {
                 st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
             } else if(st->need_parsing == AVSTREAM_PARSE_FULL_ONCE) {
                 st->parser->flags |= PARSER_FLAG_ONCE;
+            } else if(st->need_parsing == AVSTREAM_PARSE_FULL_RAW) {
+                st->parser->flags |= PARSER_FLAG_USE_CODEC_TS;
             }
         }
 
@@ -1186,16 +1350,22 @@
             /* free packet */
             av_free_packet(&cur_pkt);
         }
+        if (pkt->flags & AV_PKT_FLAG_KEY)
+            st->skip_to_keyframe = 0;
+        if (st->skip_to_keyframe) {
+            av_free_packet(&cur_pkt);
+            got_packet = 0;
+        }
     }
 
     if (!got_packet && s->parse_queue)
         ret = read_from_packet_buffer(&s->parse_queue, &s->parse_queue_end, pkt);
 
     if(s->debug & FF_FDEBUG_TS)
-        av_log(s, AV_LOG_DEBUG, "read_frame_internal stream=%d, pts=%"PRId64", dts=%"PRId64", size=%d, duration=%d, flags=%d\n",
+        av_log(s, AV_LOG_DEBUG, "read_frame_internal stream=%d, pts=%s, dts=%s, size=%d, duration=%d, flags=%d\n",
             pkt->stream_index,
-            pkt->pts,
-            pkt->dts,
+            av_ts2str(pkt->pts),
+            av_ts2str(pkt->dts),
             pkt->size,
             pkt->duration,
             pkt->flags);
@@ -1207,15 +1377,19 @@
 {
     const int genpts = s->flags & AVFMT_FLAG_GENPTS;
     int          eof = 0;
+    int ret;
+    AVStream *st;
 
-    if (!genpts)
-        return s->packet_buffer ? read_from_packet_buffer(&s->packet_buffer,
-                                                          &s->packet_buffer_end,
-                                                          pkt) :
-                                  read_frame_internal(s, pkt);
+    if (!genpts) {
+        ret = s->packet_buffer ?
+            read_from_packet_buffer(&s->packet_buffer, &s->packet_buffer_end, pkt) :
+            read_frame_internal(s, pkt);
+        if (ret < 0)
+            return ret;
+        goto return_packet;
+    }
 
     for (;;) {
-        int ret;
         AVPacketList *pktl = s->packet_buffer;
 
         if (pktl) {
@@ -1223,22 +1397,40 @@
 
             if (next_pkt->dts != AV_NOPTS_VALUE) {
                 int wrap_bits = s->streams[next_pkt->stream_index]->pts_wrap_bits;
+                // last dts seen for this stream. if any of packets following
+                // current one had no dts, we will set this to AV_NOPTS_VALUE.
+                int64_t last_dts = next_pkt->dts;
                 while (pktl && next_pkt->pts == AV_NOPTS_VALUE) {
                     if (pktl->pkt.stream_index == next_pkt->stream_index &&
-                        (av_compare_mod(next_pkt->dts, pktl->pkt.dts, 2LL << (wrap_bits - 1)) < 0) &&
-                         av_compare_mod(pktl->pkt.pts, pktl->pkt.dts, 2LL << (wrap_bits - 1))) { //not b frame
-                        next_pkt->pts = pktl->pkt.dts;
+                        (av_compare_mod(next_pkt->dts, pktl->pkt.dts, 2LL << (wrap_bits - 1)) < 0)) {
+                        if (av_compare_mod(pktl->pkt.pts, pktl->pkt.dts, 2LL << (wrap_bits - 1))) { //not b frame
+                            next_pkt->pts = pktl->pkt.dts;
+                        }
+                        if (last_dts != AV_NOPTS_VALUE) {
+                            // Once last dts was set to AV_NOPTS_VALUE, we don't change it.
+                            last_dts = pktl->pkt.dts;
+                        }
                     }
                     pktl = pktl->next;
                 }
+                if (eof && next_pkt->pts == AV_NOPTS_VALUE && last_dts != AV_NOPTS_VALUE) {
+                    // Fixing the last reference frame had none pts issue (For MXF etc).
+                    // We only do this when
+                    // 1. eof.
+                    // 2. we are not able to resolve a pts value for current packet.
+                    // 3. the packets for this stream at the end of the files had valid dts.
+                    next_pkt->pts = last_dts + next_pkt->duration;
+                }
                 pktl = s->packet_buffer;
             }
 
             /* read packet from packet buffer, if there is data */
             if (!(next_pkt->pts == AV_NOPTS_VALUE &&
-                  next_pkt->dts != AV_NOPTS_VALUE && !eof))
-                return read_from_packet_buffer(&s->packet_buffer,
+                  next_pkt->dts != AV_NOPTS_VALUE && !eof)) {
+                ret = read_from_packet_buffer(&s->packet_buffer,
                                                &s->packet_buffer_end, pkt);
+                goto return_packet;
+            }
         }
 
         ret = read_frame_internal(s, pkt);
@@ -1254,6 +1446,28 @@
                           &s->packet_buffer_end)) < 0)
             return AVERROR(ENOMEM);
     }
+
+return_packet:
+
+    st = s->streams[pkt->stream_index];
+    if (st->skip_samples) {
+        uint8_t *p = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10);
+        AV_WL32(p, st->skip_samples);
+        av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d\n", st->skip_samples);
+        st->skip_samples = 0;
+    }
+
+    if ((s->iformat->flags & AVFMT_GENERIC_INDEX) && pkt->flags & AV_PKT_FLAG_KEY) {
+        ff_reduce_index(s, st->index);
+        av_add_index_entry(st, pkt->pos, pkt->dts, 0, 0, AVINDEX_KEYFRAME);
+    }
+
+    if (is_relative(pkt->dts))
+        pkt->dts -= RELATIVE_TS_BASE;
+    if (is_relative(pkt->pts))
+        pkt->pts -= RELATIVE_TS_BASE;
+
+    return ret;
 }
 
 /* XXX: suppress the packet queue */
@@ -1308,7 +1522,8 @@
             st->parser = NULL;
         }
         st->last_IP_pts = AV_NOPTS_VALUE;
-        st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */
+        if(st->first_dts == AV_NOPTS_VALUE) st->cur_dts = RELATIVE_TS_BASE;
+        else                                st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */
         st->reference_dts = AV_NOPTS_VALUE;
 
         st->probe_packets = MAX_PROBE_PACKETS;
@@ -1355,6 +1570,12 @@
     if((unsigned)*nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
         return -1;
 
+    if(timestamp == AV_NOPTS_VALUE)
+        return AVERROR(EINVAL);
+
+    if (is_relative(timestamp)) //FIXME this maintains previous behavior but we should shift by the correct offset once known
+        timestamp -= RELATIVE_TS_BASE;
+
     entries = av_fast_realloc(*index_entries,
                               index_entries_allocated_size,
                               (*nb_index_entries + 1) *
@@ -1451,7 +1672,7 @@
     if (stream_index < 0)
         return -1;
 
-    av_dlog(s, "read_seek: %d %"PRId64"\n", stream_index, target_ts);
+    av_dlog(s, "read_seek: %d %s\n", stream_index, av_ts2str(target_ts));
 
     ts_max=
     ts_min= AV_NOPTS_VALUE;
@@ -1468,8 +1689,8 @@
         if(e->timestamp <= target_ts || e->pos == e->min_distance){
             pos_min= e->pos;
             ts_min= e->timestamp;
-            av_dlog(s, "using cached pos_min=0x%"PRIx64" dts_min=%"PRId64"\n",
-                    pos_min,ts_min);
+            av_dlog(s, "using cached pos_min=0x%"PRIx64" dts_min=%s\n",
+                    pos_min, av_ts2str(ts_min));
         }else{
             assert(index==0);
         }
@@ -1482,8 +1703,8 @@
             pos_max= e->pos;
             ts_max= e->timestamp;
             pos_limit= pos_max - e->min_distance;
-            av_dlog(s, "using cached pos_max=0x%"PRIx64" pos_limit=0x%"PRIx64" dts_max=%"PRId64"\n",
-                    pos_max,pos_limit, ts_max);
+            av_dlog(s, "using cached pos_max=0x%"PRIx64" pos_limit=0x%"PRIx64" dts_max=%s\n",
+                    pos_max, pos_limit, av_ts2str(ts_max));
         }
     }
 
@@ -1495,6 +1716,7 @@
     if ((ret = avio_seek(s->pb, pos, SEEK_SET)) < 0)
         return ret;
 
+    ff_read_frame_flush(s);
     ff_update_cur_dts(s, st, ts);
 
     return 0;
@@ -1509,7 +1731,7 @@
     int64_t start_pos, filesize;
     int no_change;
 
-    av_dlog(s, "gen_seek: %d %"PRId64"\n", stream_index, target_ts);
+    av_dlog(s, "gen_seek: %d %s\n", stream_index, av_ts2str(target_ts));
 
     if(ts_min == AV_NOPTS_VALUE){
         pos_min = s->data_offset;
@@ -1518,6 +1740,11 @@
             return -1;
     }
 
+    if(ts_min >= target_ts){
+        *ts_ret= ts_min;
+        return pos_min;
+    }
+
     if(ts_max == AV_NOPTS_VALUE){
         int step= 1024;
         filesize = avio_size(s->pb);
@@ -1543,6 +1770,11 @@
         pos_limit= pos_max;
     }
 
+    if(ts_max <= target_ts){
+        *ts_ret= ts_max;
+        return pos_max;
+    }
+
     if(ts_min > ts_max){
         return -1;
     }else if(ts_min == ts_max){
@@ -1551,8 +1783,8 @@
 
     no_change=0;
     while (pos_min < pos_limit) {
-        av_dlog(s, "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%"PRId64" dts_max=%"PRId64"\n",
-                pos_min, pos_max, ts_min, ts_max);
+        av_dlog(s, "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%s dts_max=%s\n",
+                pos_min, pos_max, av_ts2str(ts_min), av_ts2str(ts_max));
         assert(pos_limit <= pos_max);
 
         if(no_change==0){
@@ -1579,8 +1811,9 @@
             no_change++;
         else
             no_change=0;
-        av_dlog(s, "%"PRId64" %"PRId64" %"PRId64" / %"PRId64" %"PRId64" %"PRId64" target:%"PRId64" limit:%"PRId64" start:%"PRId64" noc:%d\n",
-                pos_min, pos, pos_max, ts_min, ts, ts_max, target_ts,
+        av_dlog(s, "%"PRId64" %"PRId64" %"PRId64" / %s %s %s target:%s limit:%"PRId64" start:%"PRId64" noc:%d\n",
+                pos_min, pos, pos_max,
+                av_ts2str(ts_min), av_ts2str(ts), av_ts2str(ts_max), av_ts2str(target_ts),
                 pos_limit, start_pos, no_change);
         if(ts == AV_NOPTS_VALUE){
             av_log(s, AV_LOG_ERROR, "read_timestamp() failed in the middle\n");
@@ -1600,12 +1833,14 @@
 
     pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max;
     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);
     pos_min++;
     ts_max = read_timestamp(s, stream_index, &pos_min, INT64_MAX);
-    av_dlog(s, "pos=0x%"PRIx64" %"PRId64"<=%"PRId64"<=%"PRId64"\n",
-            pos, ts_min, target_ts, ts_max);
+    av_dlog(s, "pos=0x%"PRIx64" %s<=%s<=%s\n",
+            pos, av_ts2str(ts_min), av_ts2str(target_ts), av_ts2str(ts_max));
+#endif
     *ts_ret= ts;
     return pos;
 }
@@ -1641,6 +1876,7 @@
 
     if(index < 0 || index==st->nb_index_entries-1){
         AVPacket pkt;
+        int nonkey=0;
 
         if(st->nb_index_entries){
             assert(st->index_entries);
@@ -1660,9 +1896,13 @@
             if (read_status < 0)
                 break;
             av_free_packet(&pkt);
-            if(stream_index == pkt.stream_index){
-                if((pkt.flags & AV_PKT_FLAG_KEY) && pkt.dts > timestamp)
+            if(stream_index == pkt.stream_index && pkt.dts > timestamp){
+                if(pkt.flags & AV_PKT_FLAG_KEY)
                     break;
+                if(nonkey++ > 1000 && st->codec->codec_id != AV_CODEC_ID_CDGRAPHICS){
+                    av_log(s, AV_LOG_ERROR,"seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, %d non keyframes found\n", nonkey);
+                    break;
+                }
             }
         }
         index = av_index_search_timestamp(st, timestamp, flags);
@@ -1732,7 +1972,7 @@
     int ret = seek_frame_internal(s, stream_index, timestamp, flags);
 
     if (ret >= 0)
-        queue_attached_pictures(s);
+        avformat_queue_attached_pictures(s);
 
     return ret;
 }
@@ -1748,7 +1988,7 @@
         ret = s->iformat->read_seek2(s, stream_index, min_ts, ts, max_ts, flags);
 
         if (ret >= 0)
-            queue_attached_pictures(s);
+            avformat_queue_attached_pictures(s);
         return ret;
     }
 
@@ -1757,9 +1997,17 @@
     }
 
     //Fallback to old API if new is not implemented but old is
-    //Note the old has somewat different sematics
-    if(s->iformat->read_seek || 1)
-        return av_seek_frame(s, stream_index, ts, flags | (ts - min_ts > (uint64_t)(max_ts - ts) ? AVSEEK_FLAG_BACKWARD : 0));
+    //Note the old has somewhat different semantics
+    if (s->iformat->read_seek || 1) {
+        int dir = (ts - (uint64_t)min_ts > (uint64_t)max_ts - ts ? AVSEEK_FLAG_BACKWARD : 0);
+        int ret = av_seek_frame(s, stream_index, ts, flags | dir);
+        if (ret<0 && ts != min_ts && max_ts != ts) {
+            ret = av_seek_frame(s, stream_index, dir ? max_ts : min_ts, flags | dir);
+            if (ret >= 0)
+                ret = av_seek_frame(s, stream_index, ts, flags | (dir^AVSEEK_FLAG_BACKWARD));
+        }
+        return ret;
+    }
 
     // try some generic seek like seek_frame_generic() but with new ts semantics
 }
@@ -1793,19 +2041,24 @@
  */
 static void update_stream_timings(AVFormatContext *ic)
 {
-    int64_t start_time, start_time1, end_time, end_time1;
+    int64_t start_time, start_time1, start_time_text, end_time, end_time1;
     int64_t duration, duration1, filesize;
     int i;
     AVStream *st;
 
     start_time = INT64_MAX;
+    start_time_text = INT64_MAX;
     end_time = INT64_MIN;
     duration = INT64_MIN;
     for(i = 0;i < ic->nb_streams; i++) {
         st = ic->streams[i];
         if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) {
             start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q);
-            start_time = FFMIN(start_time, start_time1);
+            if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE || st->codec->codec_type == AVMEDIA_TYPE_DATA) {
+                if (start_time1 < start_time_text)
+                    start_time_text = start_time1;
+            } else
+                start_time = FFMIN(start_time, start_time1);
             if (st->duration != AV_NOPTS_VALUE) {
                 end_time1 = start_time1
                           + av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);
@@ -1817,19 +2070,24 @@
             duration = FFMAX(duration, duration1);
         }
     }
+    if (start_time == INT64_MAX || (start_time > start_time_text && start_time - start_time_text < AV_TIME_BASE))
+        start_time = start_time_text;
+    else if(start_time > start_time_text)
+        av_log(ic, AV_LOG_VERBOSE, "Ignoring outlier non primary stream starttime %f\n", start_time_text / (float)AV_TIME_BASE);
+
     if (start_time != INT64_MAX) {
         ic->start_time = start_time;
         if (end_time != INT64_MIN)
             duration = FFMAX(duration, end_time - start_time);
     }
-    if (duration != INT64_MIN) {
+    if (duration != INT64_MIN && duration > 0 && ic->duration == AV_NOPTS_VALUE) {
         ic->duration = duration;
-        if (ic->pb && (filesize = avio_size(ic->pb)) > 0) {
+    }
+        if (ic->pb && (filesize = avio_size(ic->pb)) > 0 && ic->duration != AV_NOPTS_VALUE) {
             /* compute the bitrate */
             ic->bit_rate = (double)filesize * 8.0 * AV_TIME_BASE /
                 (double)ic->duration;
         }
-    }
 }
 
 static void fill_all_stream_timings(AVFormatContext *ic)
@@ -1979,14 +2237,17 @@
         file_size && ic->pb->seekable) {
         /* get accurate estimate from the PTSes */
         estimate_timings_from_pts(ic, old_offset);
+        ic->duration_estimation_method = AVFMT_DURATION_FROM_PTS;
     } else if (has_duration(ic)) {
         /* at least one component has timings - we use them for all
            the components */
         fill_all_stream_timings(ic);
+        ic->duration_estimation_method = AVFMT_DURATION_FROM_STREAM;
     } else {
         av_log(ic, AV_LOG_WARNING, "Estimating duration from bitrate, this may be inaccurate\n");
         /* less precise: use bitrate info */
         estimate_timings_from_bit_rate(ic);
+        ic->duration_estimation_method = AVFMT_DURATION_FROM_BITRATE;
     }
     update_stream_timings(ic);
 
@@ -2006,32 +2267,46 @@
     }
 }
 
-static int has_codec_parameters(AVStream *st)
+static int has_codec_parameters(AVStream *st, const char **errmsg_ptr)
 {
     AVCodecContext *avctx = st->codec;
-    int val;
+
+#define FAIL(errmsg) do {                                         \
+        if (errmsg_ptr)                                           \
+            *errmsg_ptr = errmsg;                                 \
+        return 0;                                                 \
+    } while (0)
+
     switch (avctx->codec_type) {
     case AVMEDIA_TYPE_AUDIO:
-        val = avctx->sample_rate && avctx->channels;
+        if (!avctx->frame_size && determinable_frame_size(avctx))
+            FAIL("unspecified frame size");
         if (st->info->found_decoder >= 0 && avctx->sample_fmt == AV_SAMPLE_FMT_NONE)
-            return 0;
+            FAIL("unspecified sample format");
+        if (!avctx->sample_rate)
+            FAIL("unspecified sample rate");
+        if (!avctx->channels)
+            FAIL("unspecified number of channels");
+        if (st->info->found_decoder >= 0 && !st->nb_decoded_frames && avctx->codec_id == AV_CODEC_ID_DTS)
+            FAIL("no decodable DTS frames");
         break;
     case AVMEDIA_TYPE_VIDEO:
-        val = avctx->width;
+        if (!avctx->width)
+            FAIL("unspecified size");
         if (st->info->found_decoder >= 0 && avctx->pix_fmt == AV_PIX_FMT_NONE)
-            return 0;
+            FAIL("unspecified pixel format");
         break;
-    default:
-        val = 1;
+    case AVMEDIA_TYPE_SUBTITLE:
+        if (avctx->codec_id == AV_CODEC_ID_HDMV_PGS_SUBTITLE && !avctx->width)
+            FAIL("unspecified size");
         break;
+    case AVMEDIA_TYPE_DATA:
+        if(avctx->codec_id == AV_CODEC_ID_NONE) return 1;
     }
-    return avctx->codec_id != AV_CODEC_ID_NONE && val != 0;
-}
 
-static int has_decode_delay_been_guessed(AVStream *st)
-{
-    return st->codec->codec_id != AV_CODEC_ID_H264 ||
-        st->info->nb_decoded_frames >= 6;
+    if (avctx->codec_id == AV_CODEC_ID_NONE)
+        FAIL("unknown codec");
+    return 1;
 }
 
 /* returns 1 or 0 if or if not decoded data was returned, or a negative error */
@@ -2040,6 +2315,7 @@
     const AVCodec *codec;
     int got_picture = 1, ret = 0;
     AVFrame *frame = avcodec_alloc_frame();
+    AVSubtitle subtitle;
     AVPacket pkt = *avpkt;
 
     if (!frame)
@@ -2078,7 +2354,7 @@
 
     while ((pkt.size > 0 || (!pkt.data && got_picture)) &&
            ret >= 0 &&
-           (!has_codec_parameters(st)         ||
+           (!has_codec_parameters(st, NULL)   ||
            !has_decode_delay_been_guessed(st) ||
            (!st->codec_info_nb_frames && st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF))) {
         got_picture = 0;
@@ -2091,18 +2367,26 @@
         case AVMEDIA_TYPE_AUDIO:
             ret = avcodec_decode_audio4(st->codec, frame, &got_picture, &pkt);
             break;
+        case AVMEDIA_TYPE_SUBTITLE:
+            ret = avcodec_decode_subtitle2(st->codec, &subtitle,
+                                           &got_picture, &pkt);
+            ret = pkt.size;
+            break;
         default:
             break;
         }
         if (ret >= 0) {
             if (got_picture)
-                st->info->nb_decoded_frames++;
+                st->nb_decoded_frames++;
             pkt.data += ret;
             pkt.size -= ret;
             ret       = got_picture;
         }
     }
 
+    if(!pkt.data && !got_picture)
+        ret = -1;
+
 fail:
     avcodec_free_frame(&frame);
     return ret;
@@ -2174,8 +2458,8 @@
 }
 
 static int get_std_framerate(int i){
-    if(i<60*12) return i*1001;
-    else        return ((const int[]){24,30,60,12,15})[i-60*12]*1000*12;
+    if(i<60*12) return (i+1)*1001;
+    else        return ((const int[]){24,30,60,12,15,48})[i-60*12]*1000*12;
 }
 
 /*
@@ -2198,6 +2482,13 @@
     return 0;
 }
 
+#if FF_API_FORMAT_PARAMETERS
+int av_find_stream_info(AVFormatContext *ic)
+{
+    return avformat_find_stream_info(ic, NULL);
+}
+#endif
+
 int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
 {
     int i, count, ret, read_size, j;
@@ -2205,17 +2496,36 @@
     AVPacket pkt1, *pkt;
     int64_t old_offset = avio_tell(ic->pb);
     int orig_nb_streams = ic->nb_streams;        // new streams might appear, no options for those
+    int flush_codecs = ic->probesize > 0;
+
+    if(ic->pb)
+        av_log(ic, AV_LOG_DEBUG, "File position before avformat_find_stream_info() is %"PRId64"\n", avio_tell(ic->pb));
 
     for(i=0;i<ic->nb_streams;i++) {
         const AVCodec *codec;
         AVDictionary *thread_opt = NULL;
         st = ic->streams[i];
 
+        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
+            st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+/*            if(!st->time_base.num)
+                st->time_base= */
+            if(!st->codec->time_base.num)
+                st->codec->time_base= st->time_base;
+        }
         //only for the split stuff
         if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE)) {
             st->parser = av_parser_init(st->codec->codec_id);
-            if(st->need_parsing == AVSTREAM_PARSE_HEADERS && st->parser){
-                st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
+            if(st->parser){
+                if(st->need_parsing == AVSTREAM_PARSE_HEADERS){
+                    st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
+                } else if(st->need_parsing == AVSTREAM_PARSE_FULL_RAW) {
+                    st->parser->flags |= PARSER_FLAG_USE_CODEC_TS;
+                }
+            } else if (st->need_parsing) {
+                av_log(ic, AV_LOG_VERBOSE, "parser not found for codec "
+                       "%s, packets or times may be invalid.\n",
+                       avcodec_get_name(st->codec->codec_id));
             }
         }
         codec = st->codec->codec ? st->codec->codec :
@@ -2232,7 +2542,7 @@
                               : &thread_opt);
 
         //try to just open decoders, in case this is enough to get parameters
-        if (!has_codec_parameters(st)) {
+        if (!has_codec_parameters(st, NULL) && st->request_probe <= 0) {
             if (codec && !st->codec->codec)
                 avcodec_open2(st->codec, codec, options ? &options[i]
                               : &thread_opt);
@@ -2263,7 +2573,7 @@
             int fps_analyze_framecount = 20;
 
             st = ic->streams[i];
-            if (!has_codec_parameters(st))
+            if (!has_codec_parameters(st, NULL))
                 break;
             /* if the timebase is coarse (like the usual millisecond precision
                of mkv), we need to analyze more frames to reliably arrive at
@@ -2273,8 +2583,8 @@
             if (ic->fps_probe_size >= 0)
                 fps_analyze_framecount = ic->fps_probe_size;
             /* variable fps and no guess at the real fps */
-            if(   tb_unreliable(st->codec) && !st->avg_frame_rate.num
-               && st->codec_info_nb_frames < fps_analyze_framecount
+            if(   tb_unreliable(st->codec) && !(st->r_frame_rate.num && st->avg_frame_rate.num)
+               && st->info->duration_count < fps_analyze_framecount
                && st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
                 break;
             if(st->parser && st->parser->parser->split && !st->codec->extradata)
@@ -2292,6 +2602,7 @@
                 /* if we found the info for all the codecs, we can stop */
                 ret = count;
                 av_log(ic, AV_LOG_DEBUG, "All info found\n");
+                flush_codecs = 0;
                 break;
             }
         }
@@ -2299,6 +2610,12 @@
         if (read_size >= ic->probesize) {
             ret = count;
             av_log(ic, AV_LOG_DEBUG, "Probe buffer size limit %d 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)
+                    av_log(ic, AV_LOG_WARNING,
+                           "Stream #%d: not enough frames to estimate rate; "
+                           "consider increasing probesize\n", i);
             break;
         }
 
@@ -2310,35 +2627,6 @@
 
         if (ret < 0) {
             /* EOF or error*/
-            AVPacket empty_pkt = { 0 };
-            int err = 0;
-            av_init_packet(&empty_pkt);
-
-            ret = -1; /* we could not have all the codec parameters before EOF */
-            for(i=0;i<ic->nb_streams;i++) {
-                st = ic->streams[i];
-
-                /* flush the decoders */
-                if (st->info->found_decoder == 1) {
-                    do {
-                        err = try_decode_frame(st, &empty_pkt,
-                                               (options && i < orig_nb_streams) ?
-                                               &options[i] : NULL);
-                    } while (err > 0 && !has_codec_parameters(st));
-                }
-
-                if (err < 0) {
-                    av_log(ic, AV_LOG_WARNING,
-                           "decoding for stream %d failed\n", st->index);
-                } else if (!has_codec_parameters(st)) {
-                    char buf[256];
-                    avcodec_string(buf, sizeof(buf), st->codec, 0);
-                    av_log(ic, AV_LOG_WARNING,
-                           "Could not find codec parameters (%s)\n", buf);
-                } else {
-                    ret = 0;
-                }
-            }
             break;
         }
 
@@ -2358,7 +2646,7 @@
             /* check for non-increasing dts */
             if (st->info->fps_last_dts != AV_NOPTS_VALUE &&
                 st->info->fps_last_dts >= pkt->dts) {
-                av_log(ic, AV_LOG_WARNING, "Non-increasing DTS in stream %d: "
+                av_log(ic, AV_LOG_DEBUG, "Non-increasing DTS in stream %d: "
                        "packet %d with DTS %"PRId64", packet %d with DTS "
                        "%"PRId64"\n", st->index, st->info->fps_last_dts_idx,
                        st->info->fps_last_dts, st->codec_info_nb_frames, pkt->dts);
@@ -2385,36 +2673,46 @@
             }
             st->info->fps_last_dts = pkt->dts;
             st->info->fps_last_dts_idx = st->codec_info_nb_frames;
+        }
+        if (st->codec_info_nb_frames>1) {
+            int64_t t=0;
+            if (st->time_base.den > 0)
+                t = av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q);
+            if (st->avg_frame_rate.num > 0)
+                t = FFMAX(t, av_rescale_q(st->codec_info_nb_frames, av_inv_q(st->avg_frame_rate), AV_TIME_BASE_Q));
 
-            /* check max_analyze_duration */
-            if (av_rescale_q(pkt->dts - st->info->fps_first_dts, st->time_base,
-                             AV_TIME_BASE_Q) >= ic->max_analyze_duration) {
-                av_log(ic, AV_LOG_WARNING, "max_analyze_duration reached\n");
+            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);
                 break;
             }
+            st->info->codec_info_duration += pkt->duration;
         }
 #if FF_API_R_FRAME_RATE
         {
             int64_t last = st->info->last_dts;
 
             if(pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && pkt->dts > last){
+                double dts= (is_relative(pkt->dts) ?  pkt->dts - RELATIVE_TS_BASE : pkt->dts) * av_q2d(st->time_base);
                 int64_t duration= pkt->dts - last;
-                double dur= duration * av_q2d(st->time_base);
 
-                if (st->info->duration_count < 2)
-                    memset(st->info->duration_error, 0, sizeof(st->info->duration_error));
-                for (i=1; i<FF_ARRAY_ELEMS(st->info->duration_error); i++) {
+//                 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++) {
                     int framerate= get_std_framerate(i);
-                    int ticks= lrintf(dur*framerate/(1001*12));
-                    double error = dur - (double)ticks*1001*12 / framerate;
-                    st->info->duration_error[i] += error*error;
+                    double sdts= dts*framerate/(1001*12);
+                    for(j=0; j<2; j++){
+                        int ticks= lrintf(sdts+j*0.5);
+                        double error= sdts - ticks + j*0.5;
+                        st->info->duration_error[j][0][i] += error;
+                        st->info->duration_error[j][1][i] += error*error;
+                    }
                 }
                 st->info->duration_count++;
                 // ignore the first 4 values, they might have some random jitter
                 if (st->info->duration_count > 3)
                     st->info->duration_gcd = av_gcd(st->info->duration_gcd, duration);
             }
-            if (last == AV_NOPTS_VALUE || st->info->duration_count <= 1)
+            if (pkt->dts != AV_NOPTS_VALUE)
                 st->info->last_dts = pkt->dts;
         }
 #endif
@@ -2445,6 +2743,44 @@
         count++;
     }
 
+    if (flush_codecs) {
+        AVPacket empty_pkt = { 0 };
+        int err = 0;
+        av_init_packet(&empty_pkt);
+
+        ret = -1; /* we could not have all the codec parameters before EOF */
+        for(i=0;i<ic->nb_streams;i++) {
+            const char *errmsg;
+
+            st = ic->streams[i];
+
+            /* flush the decoders */
+            if (st->info->found_decoder == 1) {
+                do {
+                    err = try_decode_frame(st, &empty_pkt,
+                                            (options && i < orig_nb_streams) ?
+                                            &options[i] : NULL);
+                } while (err > 0 && !has_codec_parameters(st, NULL));
+
+                if (err < 0) {
+                    av_log(ic, AV_LOG_INFO,
+                        "decoding for stream %d failed\n", st->index);
+                }
+            }
+
+            if (!has_codec_parameters(st, &errmsg)) {
+                char buf[256];
+                avcodec_string(buf, sizeof(buf), st->codec, 0);
+                av_log(ic, AV_LOG_WARNING,
+                       "Could not find codec parameters for stream %d (%s): %s\n"
+                       "Consider increasing the value for the 'analyzeduration' and 'probesize' options\n",
+                       i, buf, errmsg);
+            } else {
+                ret = 0;
+            }
+        }
+    }
+
     // close codecs which were opened in try_decode_frame()
     for(i=0;i<ic->nb_streams;i++) {
         st = ic->streams[i];
@@ -2453,16 +2789,20 @@
     for(i=0;i<ic->nb_streams;i++) {
         st = ic->streams[i];
         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)
+                    st->codec->codec_tag= tag;
+            }
+
             /* estimate average framerate if not set by demuxer */
-            if (!st->avg_frame_rate.num && st->info->fps_last_dts != st->info->fps_first_dts) {
-                int64_t delta_dts = st->info->fps_last_dts - st->info->fps_first_dts;
-                int delta_packets = st->info->fps_last_dts_idx - st->info->fps_first_dts_idx;
+            if (st->codec_info_nb_frames>2 && !st->avg_frame_rate.num && st->info->codec_info_duration) {
                 int      best_fps = 0;
                 double best_error = 0.01;
 
                 av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
-                          delta_packets*(int64_t)st->time_base.den,
-                          delta_dts*(int64_t)st->time_base.num, 60000);
+                          (st->codec_info_nb_frames-2)*(int64_t)st->time_base.den,
+                          st->info->codec_info_duration*(int64_t)st->time_base.num, 60000);
 
                 /* round guessed framerate to a "standard" framerate if it's
                  * within 1% of the original estimate*/
@@ -2480,30 +2820,51 @@
                               best_fps, 12*1001, INT_MAX);
                 }
             }
-#if FF_API_R_FRAME_RATE
             // the check for tb_unreliable() is not completely correct, since this is not about handling
             // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
             // ipmovie.c produces.
-            if (tb_unreliable(st->codec) && st->info->duration_count > 15 && st->info->duration_gcd > 1 && !st->r_frame_rate.num)
+            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
                 && tb_unreliable(st->codec)) {
                 int num = 0;
-                double best_error= 2*av_q2d(st->time_base);
-                best_error = best_error*best_error*st->info->duration_count*1000*12*30;
+                double best_error= 0.01;
 
-                for (j=1; j<FF_ARRAY_ELEMS(st->info->duration_error); j++) {
-                    double error = st->info->duration_error[j] * get_std_framerate(j);
-                    if(error < best_error){
-                        best_error= error;
-                        num = get_std_framerate(j);
+                for (j=0; j<FF_ARRAY_ELEMS(st->info->duration_error[0][0]); 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))
+                        continue;
+                    if(!st->info->codec_info_duration && 1.0 < (1001*12.0)/get_std_framerate(j))
+                        continue;
+                    for(k=0; k<2; k++){
+                        int n= st->info->duration_count;
+                        double a= st->info->duration_error[k][0][j] / n;
+                        double error= st->info->duration_error[k][1][j]/n - a*a;
+
+                        if(error < best_error && best_error> 0.000000001){
+                            best_error= error;
+                            num = get_std_framerate(j);
+                        }
+                        if(error < 0.02)
+                            av_log(NULL, AV_LOG_DEBUG, "rfps: %f %f\n", get_std_framerate(j) / 12.0/1001, error);
                     }
                 }
                 // do not increase frame rate by more than 1 % in order to match a standard rate.
                 if (num && (!st->r_frame_rate.num || (double)num/(12*1001) < 1.01 * av_q2d(st->r_frame_rate)))
                     av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, num, 12*1001, INT_MAX);
             }
-#endif
+
+            if (!st->r_frame_rate.num){
+                if(    st->codec->time_base.den * (int64_t)st->time_base.num
+                    <= st->codec->time_base.num * st->codec->ticks_per_frame * (int64_t)st->time_base.den){
+                    st->r_frame_rate.num = st->codec->time_base.den;
+                    st->r_frame_rate.den = st->codec->time_base.num * st->codec->ticks_per_frame;
+                }else{
+                    st->r_frame_rate.num = st->time_base.den;
+                    st->r_frame_rate.den = st->time_base.num;
+                }
+            }
         }else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
             if(!st->codec->bits_per_coded_sample)
                 st->codec->bits_per_coded_sample= av_get_bits_per_sample(st->codec->codec_id);
@@ -2523,6 +2884,7 @@
         }
     }
 
+    if(ic->probesize)
     estimate_timings(ic, old_offset);
 
     compute_chapters_end(ic);
@@ -2533,17 +2895,25 @@
             ic->streams[i]->codec->thread_count = 0;
         av_freep(&ic->streams[i]->info);
     }
+    if(ic->pb)
+        av_log(ic, AV_LOG_DEBUG, "File position after avformat_find_stream_info() is %"PRId64"\n", avio_tell(ic->pb));
     return ret;
 }
 
-static AVProgram *find_program_from_stream(AVFormatContext *ic, int s)
+AVProgram *av_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int s)
 {
     int i, j;
 
-    for (i = 0; i < ic->nb_programs; i++)
-        for (j = 0; j < ic->programs[i]->nb_stream_indexes; j++)
-            if (ic->programs[i]->stream_index[j] == s)
-                return ic->programs[i];
+    for (i = 0; i < ic->nb_programs; i++) {
+        if (ic->programs[i] == last) {
+            last = NULL;
+        } else {
+            if (!last)
+                for (j = 0; j < ic->programs[i]->nb_stream_indexes; j++)
+                    if (ic->programs[i]->stream_index[j] == s)
+                        return ic->programs[i];
+        }
+    }
     return NULL;
 }
 
@@ -2560,7 +2930,7 @@
     AVCodec *decoder = NULL, *best_decoder = NULL;
 
     if (related_stream >= 0 && wanted_stream_nb < 0) {
-        AVProgram *p = find_program_from_stream(ic, related_stream);
+        AVProgram *p = av_find_program_from_stream(ic, NULL, related_stream);
         if (p) {
             program = p->stream_index;
             nb_streams = p->nb_stream_indexes;
@@ -2620,31 +2990,36 @@
     return AVERROR(ENOSYS);
 }
 
+void ff_free_stream(AVFormatContext *s, AVStream *st){
+    av_assert0(s->nb_streams>0);
+    av_assert0(s->streams[ s->nb_streams-1 ] == st);
+
+    if (st->parser) {
+        av_parser_close(st->parser);
+    }
+    if (st->attached_pic.data)
+        av_free_packet(&st->attached_pic);
+    av_dict_free(&st->metadata);
+    av_freep(&st->index_entries);
+    av_freep(&st->codec->extradata);
+    av_freep(&st->codec->subtitle_header);
+    av_freep(&st->codec);
+    av_freep(&st->priv_data);
+    av_freep(&st->info);
+    av_freep(&st->probe_data.buf);
+    av_freep(&s->streams[ --s->nb_streams ]);
+}
+
 void avformat_free_context(AVFormatContext *s)
 {
     int i;
-    AVStream *st;
 
     av_opt_free(s);
     if (s->iformat && s->iformat->priv_class && s->priv_data)
         av_opt_free(s->priv_data);
 
-    for(i=0;i<s->nb_streams;i++) {
-        /* free all data in a stream component */
-        st = s->streams[i];
-        if (st->parser) {
-            av_parser_close(st->parser);
-        }
-        if (st->attached_pic.data)
-            av_free_packet(&st->attached_pic);
-        av_dict_free(&st->metadata);
-        av_free(st->index_entries);
-        av_free(st->codec->extradata);
-        av_free(st->codec->subtitle_header);
-        av_free(st->codec);
-        av_free(st->priv_data);
-        av_free(st->info);
-        av_free(st);
+    for(i=s->nb_streams-1; i>=0; i--) {
+        ff_free_stream(s, s->streams[i]);
     }
     for(i=s->nb_programs-1; i>=0; i--) {
         av_dict_free(&s->programs[i]->metadata);
@@ -2655,7 +3030,7 @@
     av_freep(&s->priv_data);
     while(s->nb_chapters--) {
         av_dict_free(&s->chapters[s->nb_chapters]->metadata);
-        av_free(s->chapters[s->nb_chapters]);
+        av_freep(&s->chapters[s->nb_chapters]);
     }
     av_freep(&s->chapters);
     av_dict_free(&s->metadata);
@@ -2693,6 +3068,16 @@
     avio_close(pb);
 }
 
+#if FF_API_NEW_STREAM
+AVStream *av_new_stream(AVFormatContext *s, int id)
+{
+    AVStream *st = avformat_new_stream(s, NULL);
+    if (st)
+        st->id = id;
+    return st;
+}
+#endif
+
 AVStream *avformat_new_stream(AVFormatContext *s, AVCodec *c)
 {
     AVStream *st;
@@ -2713,6 +3098,7 @@
         av_free(st);
         return NULL;
     }
+    st->info->last_dts = AV_NOPTS_VALUE;
 
     st->codec = avcodec_alloc_context3(c);
     if (s->iformat) {
@@ -2726,7 +3112,7 @@
            but durations get some timestamps, formats with some unknown
            timestamps have their first few packets buffered and the
            timestamps corrected before they are returned to the user */
-    st->cur_dts = 0;
+    st->cur_dts = s->iformat ? RELATIVE_TS_BASE : 0;
     st->first_dts = AV_NOPTS_VALUE;
     st->probe_packets = MAX_PROBE_PACKETS;
 
@@ -2838,8 +3224,21 @@
 
         av_log(ctx, AV_LOG_INFO, "%sMetadata:\n", indent);
         while((tag=av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX))) {
-            if(strcmp("language", tag->key))
-                av_log(ctx, AV_LOG_INFO, "%s  %-16s: %s\n", indent, tag->key, tag->value);
+            if(strcmp("language", tag->key)){
+                const char *p = tag->value;
+                av_log(ctx, AV_LOG_INFO, "%s  %-16s: ", indent, tag->key);
+                while(*p) {
+                    char tmp[256];
+                    size_t len = strcspn(p, "\x8\xa\xb\xc\xd");
+                    av_strlcpy(tmp, p, FFMIN(sizeof(tmp), len+1));
+                    av_log(ctx, AV_LOG_INFO, "%s", tmp);
+                    p += len;
+                    if (*p == 0xd) av_log(ctx, AV_LOG_INFO, " ");
+                    if (*p == 0xa) av_log(ctx, AV_LOG_INFO, "\n%s  %-16s: ", indent, "");
+                    if (*p) p++;
+                }
+                av_log(ctx, AV_LOG_INFO, "\n");
+            }
         }
     }
 }
@@ -2853,7 +3252,7 @@
     int g = av_gcd(st->time_base.num, st->time_base.den);
     AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
     avcodec_string(buf, sizeof(buf), st->codec, is_output);
-    av_log(NULL, AV_LOG_INFO, "    Stream #%d.%d", index, i);
+    av_log(NULL, AV_LOG_INFO, "    Stream #%d:%d", index, i);
     /* the pid is an important information, so we display it */
     /* XXX: add a generic system */
     if (flags & AVFMT_SHOW_IDS)
@@ -2869,7 +3268,7 @@
                   st->codec->width*st->sample_aspect_ratio.num,
                   st->codec->height*st->sample_aspect_ratio.den,
                   1024*1024);
-        av_log(NULL, AV_LOG_INFO, ", PAR %d:%d DAR %d:%d",
+        av_log(NULL, AV_LOG_INFO, ", SAR %d:%d DAR %d:%d",
                  st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
                  display_aspect_ratio.num, display_aspect_ratio.den);
     }
@@ -3121,11 +3520,27 @@
         av_hex_dump(f, pkt->data, pkt->size);
 }
 
+#if FF_API_PKT_DUMP
+void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload)
+{
+    AVRational tb = { 1, AV_TIME_BASE };
+    pkt_dump_internal(NULL, f, 0, pkt, dump_payload, tb);
+}
+#endif
+
 void av_pkt_dump2(FILE *f, AVPacket *pkt, int dump_payload, AVStream *st)
 {
     pkt_dump_internal(NULL, f, 0, pkt, dump_payload, st->time_base);
 }
 
+#if FF_API_PKT_DUMP
+void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload)
+{
+    AVRational tb = { 1, AV_TIME_BASE };
+    pkt_dump_internal(avcl, NULL, level, pkt, dump_payload, tb);
+}
+#endif
+
 void av_pkt_dump_log2(void *avcl, int level, AVPacket *pkt, int dump_payload,
                       AVStream *st)
 {
@@ -3139,7 +3554,7 @@
                   char *path, int path_size,
                   const char *url)
 {
-    const char *p, *ls, *at, *col, *brk;
+    const char *p, *ls, *ls2, *at, *col, *brk;
 
     if (port_ptr)               *port_ptr = -1;
     if (proto_size > 0)         proto[0] = 0;
@@ -3161,8 +3576,11 @@
 
     /* separate path from hostname */
     ls = strchr(p, '/');
+    ls2 = strchr(p, '?');
     if(!ls)
-        ls = strchr(p, '?');
+        ls = ls2;
+    else if (ls && ls2)
+        ls = FFMIN(ls, ls2);
     if(ls)
         av_strlcpy(path, ls, path_size);
     else
@@ -3242,6 +3660,14 @@
     return len;
 }
 
+#if FF_API_SET_PTS_INFO
+void av_set_pts_info(AVStream *s, int pts_wrap_bits,
+                     unsigned int pts_num, unsigned int pts_den)
+{
+    avpriv_set_pts_info(s, pts_wrap_bits, pts_num, pts_den);
+}
+#endif
+
 void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits,
                          unsigned int pts_num, unsigned int pts_den)
 {
@@ -3253,10 +3679,11 @@
         av_log(NULL, AV_LOG_WARNING, "st:%d has too large timebase, reducing\n", s->index);
 
     if(new_tb.num <= 0 || new_tb.den <= 0) {
-        av_log(NULL, AV_LOG_ERROR, "Ignoring attempt to set invalid timebase for st:%d\n", s->index);
+        av_log(NULL, AV_LOG_ERROR, "Ignoring attempt to set invalid timebase %d/%d for st:%d\n", new_tb.num, new_tb.den, s->index);
         return;
     }
     s->time_base = new_tb;
+    av_codec_set_pkt_timebase(s->codec, new_tb);
     s->pts_wrap_bits = pts_wrap_bits;
 }
 
@@ -3457,20 +3884,14 @@
 
 int64_t ff_iso8601_to_unix_time(const char *datestr)
 {
-#if HAVE_STRPTIME
     struct tm time1 = {0}, time2 = {0};
     char *ret1, *ret2;
-    ret1 = strptime(datestr, "%Y - %m - %d %T", &time1);
-    ret2 = strptime(datestr, "%Y - %m - %dT%T", &time2);
+    ret1 = av_small_strptime(datestr, "%Y - %m - %d %H:%M:%S", &time1);
+    ret2 = av_small_strptime(datestr, "%Y - %m - %dT%H:%M:%S", &time2);
     if (ret2 && !ret1)
         return av_timegm(&time2);
     else
         return av_timegm(&time1);
-#else
-    av_log(NULL, AV_LOG_WARNING, "strptime() unavailable on this system, cannot convert "
-                                 "the date string.\n");
-    return 0;
-#endif
 }
 
 int avformat_query_codec(AVOutputFormat *ofmt, enum AVCodecID codec_id, int std_compliance)
@@ -3558,3 +3979,87 @@
 {
     return ff_codec_wav_tags;
 }
+
+AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame)
+{
+    AVRational undef = {0, 1};
+    AVRational stream_sample_aspect_ratio = stream ? stream->sample_aspect_ratio : undef;
+    AVRational codec_sample_aspect_ratio  = stream && stream->codec ? stream->codec->sample_aspect_ratio : undef;
+    AVRational frame_sample_aspect_ratio  = frame  ? frame->sample_aspect_ratio  : codec_sample_aspect_ratio;
+
+    av_reduce(&stream_sample_aspect_ratio.num, &stream_sample_aspect_ratio.den,
+               stream_sample_aspect_ratio.num,  stream_sample_aspect_ratio.den, INT_MAX);
+    if (stream_sample_aspect_ratio.num <= 0 || stream_sample_aspect_ratio.den <= 0)
+        stream_sample_aspect_ratio = undef;
+
+    av_reduce(&frame_sample_aspect_ratio.num, &frame_sample_aspect_ratio.den,
+               frame_sample_aspect_ratio.num,  frame_sample_aspect_ratio.den, INT_MAX);
+    if (frame_sample_aspect_ratio.num <= 0 || frame_sample_aspect_ratio.den <= 0)
+        frame_sample_aspect_ratio = undef;
+
+    if (stream_sample_aspect_ratio.num)
+        return stream_sample_aspect_ratio;
+    else
+        return frame_sample_aspect_ratio;
+}
+
+int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
+                                    const char *spec)
+{
+    if (*spec <= '9' && *spec >= '0') /* opt:index */
+        return strtol(spec, NULL, 0) == st->index;
+    else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
+             *spec == 't') { /* opt:[vasdt] */
+        enum AVMediaType type;
+
+        switch (*spec++) {
+        case 'v': type = AVMEDIA_TYPE_VIDEO;      break;
+        case 'a': type = AVMEDIA_TYPE_AUDIO;      break;
+        case 's': type = AVMEDIA_TYPE_SUBTITLE;   break;
+        case 'd': type = AVMEDIA_TYPE_DATA;       break;
+        case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
+        default:  av_assert0(0);
+        }
+        if (type != st->codec->codec_type)
+            return 0;
+        if (*spec++ == ':') { /* possibly followed by :index */
+            int i, index = strtol(spec, NULL, 0);
+            for (i = 0; i < s->nb_streams; i++)
+                if (s->streams[i]->codec->codec_type == type && index-- == 0)
+                   return i == st->index;
+            return 0;
+        }
+        return 1;
+    } else if (*spec == 'p' && *(spec + 1) == ':') {
+        int prog_id, i, j;
+        char *endptr;
+        spec += 2;
+        prog_id = strtol(spec, &endptr, 0);
+        for (i = 0; i < s->nb_programs; i++) {
+            if (s->programs[i]->id != prog_id)
+                continue;
+
+            if (*endptr++ == ':') {
+                int stream_idx = strtol(endptr, NULL, 0);
+                return stream_idx >= 0 &&
+                    stream_idx < s->programs[i]->nb_stream_indexes &&
+                    st->index == s->programs[i]->stream_index[stream_idx];
+            }
+
+            for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
+                if (st->index == s->programs[i]->stream_index[j])
+                    return 1;
+        }
+        return 0;
+    } else if (*spec == '#') {
+        int sid;
+        char *endptr;
+        sid = strtol(spec + 1, &endptr, 0);
+        if (!*endptr)
+            return st->id == sid;
+    } else if (!*spec) /* empty specifier, matches everything */
+        return 1;
+
+    av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
+    return AVERROR(EINVAL);
+}
diff --git a/libavformat/vc1test.c b/libavformat/vc1test.c
index 1895fc4..e411a25 100644
--- a/libavformat/vc1test.c
+++ b/libavformat/vc1test.c
@@ -2,20 +2,20 @@
  * VC1 Test Bitstreams Format Demuxer
  * Copyright (c) 2006, 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -92,7 +92,7 @@
     int keyframe = 0;
     uint32_t pts;
 
-    if(pb->eof_reached)
+    if(url_feof(pb))
         return AVERROR(EIO);
 
     frame_size = avio_rl24(pb);
diff --git a/libavformat/vc1testenc.c b/libavformat/vc1testenc.c
index abe8c6b..e084516 100644
--- a/libavformat/vc1testenc.c
+++ b/libavformat/vc1testenc.c
@@ -2,20 +2,20 @@
  * VC-1 test bitstreams format muxer.
  * Copyright (c) 2008 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
@@ -85,7 +85,6 @@
 AVOutputFormat ff_vc1t_muxer = {
     .name              = "rcv",
     .long_name         = NULL_IF_CONFIG_SMALL("VC-1 test bitstream"),
-    .mime_type         = "",
     .extensions        = "rcv",
     .priv_data_size    = sizeof(RCVContext),
     .audio_codec       = AV_CODEC_ID_NONE,
diff --git a/libavformat/version.h b/libavformat/version.h
index 79dc7d1..1bac92b 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -1,20 +1,20 @@
 /*
  * Version macros.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,8 +30,8 @@
 #include "libavutil/avutil.h"
 
 #define LIBAVFORMAT_VERSION_MAJOR 54
-#define LIBAVFORMAT_VERSION_MINOR 18
-#define LIBAVFORMAT_VERSION_MICRO  0
+#define LIBAVFORMAT_VERSION_MINOR 32
+#define LIBAVFORMAT_VERSION_MICRO 100
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \
@@ -49,6 +49,24 @@
  * the public API and may change, break or disappear at any time.
  */
 
+#ifndef FF_API_OLD_AVIO
+#define FF_API_OLD_AVIO                (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_PKT_DUMP
+#define FF_API_PKT_DUMP                (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
+#ifndef FF_API_ALLOC_OUTPUT_CONTEXT
+#define FF_API_ALLOC_OUTPUT_CONTEXT    (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_FORMAT_PARAMETERS
+#define FF_API_FORMAT_PARAMETERS       (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_NEW_STREAM
+#define FF_API_NEW_STREAM              (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
+#ifndef FF_API_SET_PTS_INFO
+#define FF_API_SET_PTS_INFO            (LIBAVFORMAT_VERSION_MAJOR < 55)
+#endif
 #ifndef FF_API_CLOSE_INPUT_FILE
 #define FF_API_CLOSE_INPUT_FILE        (LIBAVFORMAT_VERSION_MAJOR < 55)
 #endif
diff --git a/libavformat/voc.c b/libavformat/voc.c
index 1b7d499..2a97234 100644
--- a/libavformat/voc.c
+++ b/libavformat/voc.c
@@ -2,20 +2,20 @@
  * Creative Voice File common data.
  * Copyright (c) 2006  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/voc.h b/libavformat/voc.h
index 1668618..90178b3 100644
--- a/libavformat/voc.h
+++ b/libavformat/voc.h
@@ -2,20 +2,20 @@
  * Creative Voice File demuxer.
  * Copyright (c) 2006  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/vocdec.c b/libavformat/vocdec.c
index 4e06513..62215fc 100644
--- a/libavformat/vocdec.c
+++ b/libavformat/vocdec.c
@@ -2,20 +2,20 @@
  * Creative Voice File demuxer.
  * Copyright (c) 2006  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -150,7 +150,7 @@
         }
     }
 
-    dec->bit_rate = dec->sample_rate * dec->bits_per_coded_sample;
+    dec->bit_rate = dec->sample_rate * dec->channels * dec->bits_per_coded_sample;
 
     if (max_size <= 0)
         max_size = 2048;
diff --git a/libavformat/vocenc.c b/libavformat/vocenc.c
index d18eac2..d97cdc4 100644
--- a/libavformat/vocenc.c
+++ b/libavformat/vocenc.c
@@ -2,20 +2,20 @@
  * Creative Voice File muxer.
  * Copyright (c) 2006  Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -52,7 +52,7 @@
     AVIOContext *pb = s->pb;
 
     if (!voc->param_written) {
-        if (enc->codec_tag > 0xFF) {
+        if (enc->codec_tag > 3) {
             avio_w8(pb, VOC_TYPE_NEW_VOICE_DATA);
             avio_wl24(pb, pkt->size + 12);
             avio_wl32(pb, enc->sample_rate);
@@ -64,13 +64,13 @@
             if (s->streams[0]->codec->channels > 1) {
                 avio_w8(pb, VOC_TYPE_EXTENDED);
                 avio_wl24(pb, 4);
-                avio_wl16(pb, 65536-256000000/(enc->sample_rate*enc->channels));
+                avio_wl16(pb, 65536-(256000000 + enc->sample_rate*enc->channels/2)/(enc->sample_rate*enc->channels));
                 avio_w8(pb, enc->codec_tag);
                 avio_w8(pb, enc->channels - 1);
             }
             avio_w8(pb, VOC_TYPE_VOICE_DATA);
             avio_wl24(pb, pkt->size + 2);
-            avio_w8(pb, 256 - 1000000 / enc->sample_rate);
+            avio_w8(pb, 256 - (1000000 + enc->sample_rate/2) / enc->sample_rate);
             avio_w8(pb, enc->codec_tag);
         }
         voc->param_written = 1;
@@ -95,7 +95,7 @@
     .mime_type         = "audio/x-voc",
     .extensions        = "voc",
     .priv_data_size    = sizeof(VocEncContext),
-    .audio_codec       = AV_CODEC_ID_PCM_U8,
+    .audio_codec       = AV_CODEC_ID_PCM_S16LE,
     .video_codec       = AV_CODEC_ID_NONE,
     .write_header      = voc_write_header,
     .write_packet      = voc_write_packet,
diff --git a/libavformat/vorbiscomment.c b/libavformat/vorbiscomment.c
index 56936d7..9b38e6a 100644
--- a/libavformat/vorbiscomment.c
+++ b/libavformat/vorbiscomment.c
@@ -2,20 +2,20 @@
  * VorbisComment writer
  * Copyright (c) 2009 James Darnley
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/vorbiscomment.h b/libavformat/vorbiscomment.h
index 95e1a56..4e631e3 100644
--- a/libavformat/vorbiscomment.h
+++ b/libavformat/vorbiscomment.h
@@ -2,20 +2,20 @@
  * VorbisComment writer
  * Copyright (c) 2009 James Darnley
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/vqf.c b/libavformat/vqf.c
index 66ced37..5fff84e 100644
--- a/libavformat/vqf.c
+++ b/libavformat/vqf.c
@@ -2,20 +2,20 @@
  * VQF demuxer
  * Copyright (c) 2009 Vitor Sessak
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/wav.c b/libavformat/wav.c
index 47dcc73..f58bcb3 100644
--- a/libavformat/wav.c
+++ b/libavformat/wav.c
@@ -6,20 +6,20 @@
  * RF64 demuxer
  * Copyright (c) 2009 Daniel Verkamp
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -45,6 +45,14 @@
     int last_duration;
     int w64;
     int write_bext;
+    int64_t smv_data_ofs;
+    int smv_block_size;
+    int smv_frames_per_jpeg;
+    int smv_block;
+    int smv_last_stream;
+    int smv_eof;
+    int audio_eof;
+    int ignore_length;
 } WAVContext;
 
 #if CONFIG_WAV_MUXER
@@ -238,7 +246,7 @@
     int64_t size;
 
     for (;;) {
-        if (pb->eof_reached)
+        if (url_feof(pb))
             return -1;
         size = next_tag(pb, &tag);
         if (tag == tag1)
@@ -268,6 +276,14 @@
     return 0;
 }
 
+static void handle_stream_probing(AVStream *st)
+{
+    if (st->codec->codec_id == AV_CODEC_ID_PCM_S16LE) {
+        st->request_probe = AVPROBE_SCORE_MAX/2;
+        st->probe_packets = FFMIN(st->probe_packets, 4);
+    }
+}
+
 static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st)
 {
     AVIOContext *pb = s->pb;
@@ -281,7 +297,9 @@
     ret = ff_get_wav_header(pb, (*st)->codec, size);
     if (ret < 0)
         return ret;
-    (*st)->need_parsing = AVSTREAM_PARSE_FULL;
+    handle_stream_probing(*st);
+
+    (*st)->need_parsing = AVSTREAM_PARSE_FULL_RAW;
 
     avpriv_set_pts_info(*st, 64, 1, (*st)->codec->sample_rate);
 
@@ -339,7 +357,7 @@
             } else {
                 /* extended UMID */
                 snprintf(temp, sizeof(temp), "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64
-                                             "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
+                                               "%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
                          umid_parts[0], umid_parts[1], umid_parts[2], umid_parts[3],
                          umid_parts[4], umid_parts[5], umid_parts[6], umid_parts[7]);
             }
@@ -392,6 +410,8 @@
     int ret, got_fmt = 0;
     int64_t next_tag_ofs, data_ofs = -1;
 
+    wav->smv_data_ofs = -1;
+
     /* check RIFF header */
     tag = avio_rl32(pb);
 
@@ -407,7 +427,7 @@
         if (avio_rl32(pb) != MKTAG('d', 's', '6', '4'))
             return -1;
         size = avio_rl32(pb);
-        if (size < 16)
+        if (size < 24)
             return -1;
         avio_rl64(pb); /* RIFF size */
         data_size = avio_rl64(pb);
@@ -418,20 +438,22 @@
                    data_size, sample_count);
             return AVERROR_INVALIDDATA;
         }
-        avio_skip(pb, size - 16); /* skip rest of ds64 chunk */
+        avio_skip(pb, size - 24); /* skip rest of ds64 chunk */
+
     }
 
     for (;;) {
+        AVStream *vst;
         size = next_tag(pb, &tag);
         next_tag_ofs = avio_tell(pb) + size;
 
-        if (pb->eof_reached)
+        if (url_feof(pb))
             break;
 
         switch (tag) {
         case MKTAG('f', 'm', 't', ' '):
             /* only parse the first 'fmt ' tag found */
-            if (!got_fmt && (ret = wav_parse_fmt_tag(s, size, &st) < 0)) {
+            if (!got_fmt && (ret = wav_parse_fmt_tag(s, size, &st)) < 0) {
                 return ret;
             } else if (got_fmt)
                 av_log(s, AV_LOG_WARNING, "found more than one 'fmt ' tag\n");
@@ -467,10 +489,40 @@
             if ((ret = wav_parse_bext_tag(s, size)) < 0)
                 return ret;
             break;
+        case MKTAG('S','M','V','0'):
+            if (!got_fmt) {
+                av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'SMV0' tag\n");
+                return AVERROR_INVALIDDATA;
+            }
+            // SMV file, a wav file with video appended.
+            if (size != MKTAG('0','2','0','0')) {
+                av_log(s, AV_LOG_ERROR, "Unknown SMV version found\n");
+                goto break_loop;
+            }
+            av_log(s, AV_LOG_DEBUG, "Found SMV data\n");
+            vst = avformat_new_stream(s, NULL);
+            if (!vst)
+                return AVERROR(ENOMEM);
+            avio_r8(pb);
+            vst->id = 1;
+            vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+            vst->codec->codec_id = AV_CODEC_ID_MJPEG;
+            vst->codec->width  = avio_rl24(pb);
+            vst->codec->height = avio_rl24(pb);
+            size = avio_rl24(pb);
+            wav->smv_data_ofs = avio_tell(pb) + (size - 5) * 3;
+            avio_rl24(pb);
+            wav->smv_block_size = avio_rl24(pb);
+            avpriv_set_pts_info(vst, 32, 1, avio_rl24(pb));
+            vst->duration = avio_rl24(pb);
+            avio_rl24(pb);
+            avio_rl24(pb);
+            wav->smv_frames_per_jpeg = avio_rl24(pb);
+            goto break_loop;
         case MKTAG('L', 'I', 'S', 'T'):
             list_type = avio_rl32(pb);
-            if (size <= 4) {
-                av_log(s, AV_LOG_ERROR, "too short LIST");
+            if (size < 4) {
+                av_log(s, AV_LOG_ERROR, "too short LIST tag\n");
                 return AVERROR_INVALIDDATA;
             }
             switch (list_type) {
@@ -514,7 +566,7 @@
     uint8_t guid[16];
     int64_t size;
 
-    while (!pb->eof_reached) {
+    while (!url_feof(pb)) {
         avio_read(pb, guid, 16);
         size = avio_rl64(pb);
         if (size <= 24)
@@ -539,16 +591,61 @@
     AVStream *st;
     WAVContext *wav = s->priv_data;
 
+    if (wav->smv_data_ofs > 0) {
+        int64_t audio_dts, video_dts;
+smv_retry:
+        audio_dts = s->streams[0]->cur_dts;
+        video_dts = s->streams[1]->cur_dts;
+        if (audio_dts != AV_NOPTS_VALUE && video_dts != AV_NOPTS_VALUE) {
+            audio_dts = av_rescale_q(audio_dts, s->streams[0]->time_base, AV_TIME_BASE_Q);
+            video_dts = av_rescale_q(video_dts, s->streams[1]->time_base, AV_TIME_BASE_Q);
+            wav->smv_last_stream = video_dts >= audio_dts;
+        }
+        wav->smv_last_stream = !wav->smv_last_stream;
+        wav->smv_last_stream |= wav->audio_eof;
+        wav->smv_last_stream &= !wav->smv_eof;
+        if (wav->smv_last_stream) {
+            uint64_t old_pos = avio_tell(s->pb);
+            uint64_t new_pos = wav->smv_data_ofs +
+                wav->smv_block * wav->smv_block_size;
+            if (avio_seek(s->pb, new_pos, SEEK_SET) < 0) {
+                ret = AVERROR_EOF;
+                goto smv_out;
+            }
+            size = avio_rl24(s->pb);
+            ret  = av_get_packet(s->pb, pkt, size);
+            if (ret < 0)
+                goto smv_out;
+            pkt->pos -= 3;
+            pkt->pts = wav->smv_block * wav->smv_frames_per_jpeg;
+            wav->smv_block++;
+            pkt->stream_index = 1;
+smv_out:
+            avio_seek(s->pb, old_pos, SEEK_SET);
+            if (ret == AVERROR_EOF) {
+                wav->smv_eof = 1;
+                goto smv_retry;
+            }
+            return ret;
+        }
+    }
+
     st = s->streams[0];
 
     left = wav->data_end - avio_tell(s->pb);
+    if (wav->ignore_length)
+        left= INT_MAX;
     if (left <= 0){
         if (CONFIG_W64_DEMUXER && wav->w64)
             left = find_guid(s->pb, guid_data) - 24;
         else
             left = find_tag(s->pb, MKTAG('d', 'a', 't', 'a'));
-        if (left < 0)
+        if (left < 0) {
+            wav->audio_eof = 1;
+            if (wav->smv_data_ofs > 0 && !wav->smv_eof)
+                goto smv_retry;
             return AVERROR_EOF;
+        }
         wav->data_end= avio_tell(s->pb) + left;
     }
 
@@ -570,7 +667,18 @@
 static int wav_read_seek(AVFormatContext *s,
                          int stream_index, int64_t timestamp, int flags)
 {
+    WAVContext *wav = s->priv_data;
     AVStream *st;
+    wav->smv_eof = 0;
+    wav->audio_eof = 0;
+    if (wav->smv_data_ofs > 0) {
+        int64_t smv_timestamp = timestamp;
+        if (stream_index == 0)
+            smv_timestamp = av_rescale_q(timestamp, s->streams[0]->time_base, s->streams[1]->time_base);
+        else
+            timestamp = av_rescale_q(smv_timestamp, s->streams[1]->time_base, s->streams[0]->time_base);
+        wav->smv_block = smv_timestamp / wav->smv_frames_per_jpeg;
+    }
 
     st = s->streams[0];
     switch (st->codec->codec_id) {
@@ -586,6 +694,19 @@
     return ff_pcm_read_seek(s, stream_index, timestamp, flags);
 }
 
+#define OFFSET(x) offsetof(WAVContext, x)
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+static const AVOption demux_options[] = {
+    { "ignore_length", "Ignore length", OFFSET(ignore_length), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, DEC },
+    { NULL },
+};
+
+static const AVClass wav_demuxer_class = {
+    .class_name = "WAV demuxer",
+    .item_name  = av_default_item_name,
+    .option     = demux_options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
 AVInputFormat ff_wav_demuxer = {
     .name           = "wav",
     .long_name      = NULL_IF_CONFIG_SMALL("WAV / WAVE (Waveform Audio)"),
@@ -596,6 +717,7 @@
     .read_seek      = wav_read_seek,
     .flags          = AVFMT_GENERIC_INDEX,
     .codec_tag      = (const AVCodecTag* const []){ ff_codec_wav_tags, 0 },
+    .priv_class     = &wav_demuxer_class,
 };
 #endif /* CONFIG_WAV_DEMUXER */
 
@@ -659,7 +781,8 @@
         return ret;
     avio_skip(pb, FFALIGN(size, INT64_C(8)) - size);
 
-    st->need_parsing = AVSTREAM_PARSE_FULL;
+    handle_stream_probing(st);
+    st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
 
     avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
 
diff --git a/libavformat/wc3movie.c b/libavformat/wc3movie.c
index 117e4ea..836f567 100644
--- a/libavformat/wc3movie.c
+++ b/libavformat/wc3movie.c
@@ -2,20 +2,20 @@
  * Wing Commander III Movie (.mve) File Demuxer
  * Copyright (c) 2003 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -157,7 +157,7 @@
         fourcc_tag = avio_rl32(pb);
         /* chunk sizes are 16-bit aligned */
         size = (avio_rb32(pb) + 1) & (~1);
-        if (pb->eof_reached)
+        if (url_feof(pb))
             return AVERROR(EIO);
 
     } while (fourcc_tag != BRCH_TAG);
@@ -208,7 +208,7 @@
         fourcc_tag = avio_rl32(pb);
         /* chunk sizes are 16-bit aligned */
         size = (avio_rb32(pb) + 1) & (~1);
-        if (pb->eof_reached)
+        if (url_feof(pb))
             return AVERROR(EIO);
 
         switch (fourcc_tag) {
diff --git a/libavformat/webvttdec.c b/libavformat/webvttdec.c
new file mode 100644
index 0000000..b1cd293
--- /dev/null
+++ b/libavformat/webvttdec.c
@@ -0,0 +1,188 @@
+/*
+ * 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
+ * WebVTT subtitle demuxer
+ * @see http://dev.w3.org/html5/webvtt/
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "subtitles.h"
+#include "libavutil/bprint.h"
+#include "libavutil/intreadwrite.h"
+
+typedef struct {
+    FFDemuxSubtitlesQueue q;
+} WebVTTContext;
+
+static int webvtt_probe(AVProbeData *p)
+{
+    const uint8_t *ptr = p->buf;
+
+    if (AV_RB24(ptr) == 0xEFBBBF)
+        ptr += 3;  /* skip UTF-8 BOM */
+    if (!strncmp(ptr, "WEBVTT", 6) &&
+        (!ptr[6] || strchr("\n\r\t ", ptr[6])))
+        return AVPROBE_SCORE_MAX;
+    return 0;
+}
+
+static int64_t read_ts(const char *s)
+{
+    int hh, mm, ss, ms;
+    if (sscanf(s, "%u:%u:%u.%u", &hh, &mm, &ss, &ms) == 4) return (hh*3600 + mm*60 + ss) * 1000 + ms;
+    if (sscanf(s,    "%u:%u.%u",      &mm, &ss, &ms) == 3) return (          mm*60 + ss) * 1000 + ms;
+    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;
+    AVBPrint header, cue;
+    int res = 0;
+    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_WEBVTT;
+
+    av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED);
+    av_bprint_init(&cue,    0, AV_BPRINT_SIZE_UNLIMITED);
+
+    for (;;) {
+        int i, len;
+        int64_t pos = extract_cue(&cue, s->pb);
+        AVPacket *sub;
+        const char *p = cue.str;
+        const char *identifier = p;
+        //const char *settings = NULL;
+        int64_t ts_start, ts_end;
+
+        if (!*p) // EOF
+            break;
+
+        /* ignore header chunk */
+        if (!strncmp(p, "\xEF\xBB\xBFWEBVTT", 9) ||
+            !strncmp(p, "WEBVTT", 6))
+            continue;
+
+        /* optional cue identifier (can be a number like in SRT or some kind of
+         * chaptering id), silently skip it */
+        for (i = 0; p[i] && p[i] != '\n'; i++) {
+            if (!strncmp(p + i, "-->", 3)) {
+                identifier = NULL;
+                break;
+            }
+        }
+        if (identifier)
+            p += strcspn(p, "\n");
+
+        /* cue timestamps */
+        if ((ts_start = read_ts(p)) == AV_NOPTS_VALUE)
+            break;
+        if (!(p = strstr(p, "-->")))
+            break;
+        p += 3;
+        do p++; while (*p == ' ' || *p == '\t');
+        if ((ts_end = read_ts(p)) == AV_NOPTS_VALUE)
+            break;
+
+        /* optional cue settings, TODO: store in side_data */
+        p += strcspn(p, "\n\t ");
+        while (*p == '\t' || *p == ' ')
+            p++;
+        if (*p != '\n') {
+            //settings = p;
+            p += strcspn(p, "\n");
+        }
+        if (*p == '\n')
+            p++;
+
+        /* create packet */
+        len = cue.str + cue.len - p - 1;
+        sub = ff_subtitles_queue_insert(&webvtt->q, p, len, 0);
+        if (!sub) {
+            res = AVERROR(ENOMEM);
+            goto end;
+        }
+        sub->pos = pos;
+        sub->pts = ts_start;
+        sub->duration = ts_end - ts_start;
+    }
+
+    ff_subtitles_queue_finalize(&webvtt->q);
+
+end:
+    av_bprint_finalize(&cue,    NULL);
+    av_bprint_finalize(&header, NULL);
+    return res;
+}
+
+static int webvtt_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    WebVTTContext *webvtt = s->priv_data;
+    return ff_subtitles_queue_read_packet(&webvtt->q, pkt);
+}
+
+static int webvtt_read_close(AVFormatContext *s)
+{
+    WebVTTContext *webvtt = s->priv_data;
+    ff_subtitles_queue_clean(&webvtt->q);
+    return 0;
+}
+
+AVInputFormat ff_webvtt_demuxer = {
+    .name           = "webvtt",
+    .long_name      = NULL_IF_CONFIG_SMALL("WebVTT subtitle"),
+    .priv_data_size = sizeof(WebVTTContext),
+    .read_probe     = webvtt_probe,
+    .read_header    = webvtt_read_header,
+    .read_packet    = webvtt_read_packet,
+    .read_close     = webvtt_read_close,
+    .flags          = AVFMT_GENERIC_INDEX,
+    .extensions     = "vtt",
+};
diff --git a/libavformat/westwood_aud.c b/libavformat/westwood_aud.c
index 806aea6..2762cba 100644
--- a/libavformat/westwood_aud.c
+++ b/libavformat/westwood_aud.c
@@ -2,20 +2,20 @@
  * Westwood Studios AUD Format Demuxer
  * Copyright (c) 2003 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/westwood_vqa.c b/libavformat/westwood_vqa.c
index 7c9cb0d..708f3e5 100644
--- a/libavformat/westwood_vqa.c
+++ b/libavformat/westwood_vqa.c
@@ -2,20 +2,20 @@
  * Westwood Studios VQA Format Demuxer
  * Copyright (c) 2003 The ffmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -131,10 +131,8 @@
     /* there are 0 or more chunks before the FINF chunk; iterate until
      * FINF has been skipped and the file will be ready to be demuxed */
     do {
-        if (avio_read(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) {
-            av_free(st->codec->extradata);
+        if (avio_read(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE)
             return AVERROR(EIO);
-        }
         chunk_tag = AV_RB32(&scratch[0]);
         chunk_size = AV_RB32(&scratch[4]);
 
@@ -177,18 +175,15 @@
     while (avio_read(pb, preamble, VQA_PREAMBLE_SIZE) == VQA_PREAMBLE_SIZE) {
         chunk_type = AV_RB32(&preamble[0]);
         chunk_size = AV_RB32(&preamble[4]);
+
         skip_byte = chunk_size & 0x01;
 
         if ((chunk_type == SND0_TAG) || (chunk_type == SND1_TAG) ||
             (chunk_type == SND2_TAG) || (chunk_type == VQFR_TAG)) {
 
-            if (av_new_packet(pkt, chunk_size))
+            ret= av_get_packet(pb, pkt, chunk_size);
+            if (ret<0)
                 return AVERROR(EIO);
-            ret = avio_read(pb, pkt->data, chunk_size);
-            if (ret != chunk_size) {
-                av_free_packet(pkt);
-                return AVERROR(EIO);
-            }
 
             switch (chunk_type) {
             case SND0_TAG:
diff --git a/libavformat/wtv.c b/libavformat/wtv.c
index 57d239e..d85c3cf 100644
--- a/libavformat/wtv.c
+++ b/libavformat/wtv.c
@@ -1,1125 +1,76 @@
 /*
- * Windows Television (WTV) demuxer
+ * Windows Television (WTV)
  * Copyright (c) 2010-2011 Peter Ross <pross@xvid.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-/**
- * @file
- * Windows Television (WTV) demuxer
- * @author Peter Ross <pross@xvid.org>
- */
+#include "wtv.h"
 
-#include "libavutil/intreadwrite.h"
-#include "libavutil/intfloat.h"
-#include "libavutil/dict.h"
-#include "avformat.h"
-#include "internal.h"
-#include "riff.h"
-#include "asf.h"
-#include "mpegts.h"
-
-/* Macros for formating GUIDs */
-#define PRI_GUID \
-    "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
-#define ARG_GUID(g) \
-    g[0],g[1],g[2],g[3],g[4],g[5],g[6],g[7],g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]
-
-#define PRI_PRETTY_GUID \
-    "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x"
-#define ARG_PRETTY_GUID(g) \
-    AV_RL32(g),AV_RL16(g+4),AV_RL16(g+6),g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]
-#define LEN_PRETTY_GUID 34
-
-/*
- *
- * File system routines
- *
- */
-
-#define WTV_SECTOR_BITS    12
-#define WTV_SECTOR_SIZE    (1 << WTV_SECTOR_BITS)
-#define WTV_BIGSECTOR_BITS 18
-
-typedef struct {
-    AVIOContext *pb_filesystem;  /** file system (AVFormatContext->pb) */
-
-    int sector_bits;     /** sector shift bits; used to convert sector number into pb_filesystem offset */
-    uint32_t *sectors;   /** file allocation table */
-    int nb_sectors;      /** number of sectors */
-
-    int error;
-    int64_t position;
-    int64_t length;
-} WtvFile;
-
-/**
- * @return bytes read, 0 on end of file, or <0 on error
- */
-static int wtvfile_read_packet(void *opaque, uint8_t *buf, int buf_size)
-{
-    WtvFile *wf = opaque;
-    AVIOContext *pb = wf->pb_filesystem;
-    int nread = 0;
-
-    if (wf->error || pb->error)
-        return -1;
-    if (wf->position >= wf->length || pb->eof_reached)
-        return 0;
-
-    buf_size = FFMIN(buf_size, wf->length - wf->position);
-    while(nread < buf_size) {
-        int n;
-        int remaining_in_sector = (1 << wf->sector_bits) - (wf->position & ((1 << wf->sector_bits) - 1));
-        int read_request        = FFMIN(buf_size - nread, remaining_in_sector);
-
-        n = avio_read(pb, buf, read_request);
-        if (n <= 0)
-            break;
-        nread += n;
-        buf += n;
-        wf->position += n;
-        if (n == remaining_in_sector) {
-            int i = wf->position >> wf->sector_bits;
-            if (i >= wf->nb_sectors ||
-                (wf->sectors[i] != wf->sectors[i - 1] + (1 << (wf->sector_bits - WTV_SECTOR_BITS)) &&
-                avio_seek(pb, (int64_t)wf->sectors[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)) {
-                wf->error = 1;
-                break;
-            }
-        }
-    }
-    return nread;
-}
-
-/**
- * @return position (or file length)
- */
-static int64_t wtvfile_seek(void *opaque, int64_t offset, int whence)
-{
-    WtvFile *wf = opaque;
-    AVIOContext *pb = wf->pb_filesystem;
-
-    if (whence == AVSEEK_SIZE)
-        return wf->length;
-    else if (whence == SEEK_CUR)
-        offset = wf->position + offset;
-    else if (whence == SEEK_END)
-        offset = wf->length;
-
-    wf->error = offset < 0 || offset >= wf->length ||
-                avio_seek(pb, ((int64_t)wf->sectors[offset >> wf->sector_bits] << WTV_SECTOR_BITS)
-                              + (offset & ((1 << wf->sector_bits) - 1)), SEEK_SET) < 0;
-    wf->position = offset;
-    return offset;
-}
-
-/**
- * read non-zero integers (le32) from input stream
- * @param pb
- * @param[out] data destination
- * @param     count maximum number of integers to read
- * @return    total number of integers read
- */
-static int read_ints(AVIOContext *pb, uint32_t *data, int count)
-{
-    int i, total = 0;
-    for (i = 0; i < count; i++) {
-        if ((data[total] = avio_rl32(pb)))
-           total++;
-    }
-    return total;
-}
-
-/**
- * Open file
- * @param first_sector  First sector
- * @param length        Length of file (bytes)
- * @param depth         File allocation table depth
- * @return NULL on error
- */
-static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int depth, AVFormatContext *s)
-{
-    AVIOContext *pb;
-    WtvFile *wf;
-    uint8_t *buffer;
-
-    if (avio_seek(s->pb, first_sector << WTV_SECTOR_BITS, SEEK_SET) < 0)
-        return NULL;
-
-    wf = av_mallocz(sizeof(WtvFile));
-    if (!wf)
-        return NULL;
-
-    if (depth == 0) {
-        wf->sectors = av_malloc(sizeof(uint32_t));
-        if (!wf->sectors) {
-            av_free(wf);
-            return NULL;
-        }
-        wf->sectors[0]  = first_sector;
-        wf->nb_sectors  = 1;
-        wf->sector_bits = WTV_SECTOR_BITS;
-    } else if (depth == 1) {
-        wf->sectors = av_malloc(WTV_SECTOR_SIZE);
-        if (!wf->sectors) {
-            av_free(wf);
-            return NULL;
-        }
-        wf->nb_sectors  = read_ints(s->pb, wf->sectors, WTV_SECTOR_SIZE / 4);
-        wf->sector_bits = length & (1ULL<<63) ? WTV_SECTOR_BITS : WTV_BIGSECTOR_BITS;
-    } else if (depth == 2) {
-        uint32_t sectors1[WTV_SECTOR_SIZE / 4];
-        int nb_sectors1 = read_ints(s->pb, sectors1, WTV_SECTOR_SIZE / 4);
-        int i;
-
-        wf->sectors = av_malloc(nb_sectors1 << WTV_SECTOR_BITS);
-        if (!wf->sectors) {
-            av_free(wf);
-            return NULL;
-        }
-        wf->nb_sectors = 0;
-        for (i = 0; i < nb_sectors1; i++) {
-            if (avio_seek(s->pb, (int64_t)sectors1[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)
-                break;
-            wf->nb_sectors += read_ints(s->pb, wf->sectors + i * WTV_SECTOR_SIZE / 4, WTV_SECTOR_SIZE / 4);
-        }
-        wf->sector_bits = length & (1ULL<<63) ? WTV_SECTOR_BITS : WTV_BIGSECTOR_BITS;
-    } else {
-        av_log(s, AV_LOG_ERROR, "unsupported file allocation table depth (0x%x)\n", depth);
-        av_free(wf);
-        return NULL;
-    }
-
-    if (!wf->nb_sectors) {
-        av_free(wf->sectors);
-        av_free(wf);
-        return NULL;
-    }
-
-    /* check length */
-    length &= 0xFFFFFFFFFFFF;
-    if (length > ((int64_t)wf->nb_sectors << wf->sector_bits)) {
-        av_log(s, AV_LOG_WARNING, "reported file length (0x%"PRIx64") exceeds number of available sectors (0x%"PRIx64")\n", length, (int64_t)wf->nb_sectors << wf->sector_bits);
-        length = (int64_t)wf->nb_sectors <<  wf->sector_bits;
-    }
-    wf->length = length;
-
-    /* seek to intial sector */
-    wf->position = 0;
-    if (avio_seek(s->pb, (int64_t)wf->sectors[0] << WTV_SECTOR_BITS, SEEK_SET) < 0) {
-        av_free(wf->sectors);
-        av_free(wf);
-        return NULL;
-    }
-
-    wf->pb_filesystem = s->pb;
-    buffer = av_malloc(1 << wf->sector_bits);
-    if (!buffer) {
-        av_free(wf->sectors);
-        av_free(wf);
-        return NULL;
-    }
-
-    pb = avio_alloc_context(buffer, 1 << wf->sector_bits, 0, wf,
-                           wtvfile_read_packet, NULL, wtvfile_seek);
-    if (!pb) {
-        av_free(buffer);
-        av_free(wf->sectors);
-        av_free(wf);
-    }
-    return pb;
-}
-
-static const ff_asf_guid dir_entry_guid =
+/* WTV GUIDs*/
+const ff_asf_guid ff_dir_entry_guid =
     {0x92,0xB7,0x74,0x91,0x59,0x70,0x70,0x44,0x88,0xDF,0x06,0x3B,0x82,0xCC,0x21,0x3D};
-
-/**
- * Open file using filename
- * @param[in]  buf       directory buffer
- * @param      buf_size  directory buffer size
- * @param[in]  filename
- * @param      filename_size size of filename
- * @return NULL on error
- */
-static AVIOContext * wtvfile_open2(AVFormatContext *s, const uint8_t *buf, int buf_size, const uint8_t *filename, int filename_size)
-{
-    const uint8_t *buf_end = buf + buf_size;
-
-    while(buf + 48 <= buf_end) {
-        int dir_length, name_size, first_sector, depth;
-        uint64_t file_length;
-        const uint8_t *name;
-        if (ff_guidcmp(buf, dir_entry_guid)) {
-            av_log(s, AV_LOG_ERROR, "unknown guid "PRI_GUID", expected dir_entry_guid; "
-                   "remaining directory entries ignored\n", ARG_GUID(buf));
-            break;
-        }
-        dir_length  = AV_RL16(buf + 16);
-        file_length = AV_RL64(buf + 24);
-        name_size   = 2 * AV_RL32(buf + 32);
-        if (buf + 48 + name_size > buf_end) {
-            av_log(s, AV_LOG_ERROR, "filename exceeds buffer size; remaining directory entries ignored\n");
-            break;
-        }
-        first_sector = AV_RL32(buf + 40 + name_size);
-        depth        = AV_RL32(buf + 44 + name_size);
-
-        /* compare file name; test optional null terminator */
-        name = buf + 40;
-        if (name_size >= filename_size &&
-            !memcmp(name, filename, filename_size) &&
-            (name_size < filename_size + 2 || !AV_RN16(name + filename_size)))
-            return wtvfile_open_sector(first_sector, file_length, depth, s);
-
-        buf += dir_length;
-    }
-    return 0;
-}
-
-#define wtvfile_open(s, buf, buf_size, filename) \
-    wtvfile_open2(s, buf, buf_size, filename, sizeof(filename))
-
-/**
- * Close file opened with wtvfile_open_sector(), or wtv_open()
- */
-static void wtvfile_close(AVIOContext *pb)
-{
-    WtvFile *wf = pb->opaque;
-    av_free(wf->sectors);
-    av_free(wf);
-    av_free(pb->buffer);
-    av_free(pb);
-}
-
-/*
- *
- * Main demuxer
- *
- */
-
-typedef struct {
-    int seen_data;
-} WtvStream;
-
-typedef struct {
-    AVIOContext *pb;       /** timeline file */
-    int64_t epoch;
-    int64_t pts;             /** pts for next data chunk */
-    int64_t last_valid_pts;  /** latest valid pts, used for interative seeking */
-
-    /* maintain private seek index, as the AVIndexEntry->pos is relative to the
-       start of the 'timeline' file, not the file system (AVFormatContext->pb) */
-    AVIndexEntry *index_entries;
-    int nb_index_entries;
-    unsigned int index_entries_allocated_size;
-} WtvContext;
-
-typedef struct {
-    enum AVCodecID id;
-    ff_asf_guid guid;
-} AVCodecGuid;
-
-static enum AVCodecID ff_codec_guid_get_id(const AVCodecGuid *guids, ff_asf_guid guid)
-{
-    int i;
-    for (i = 0; guids[i].id != AV_CODEC_ID_NONE; i++) {
-        if (!ff_guidcmp(guids[i].guid, guid))
-            return guids[i].id;
-    }
-    return AV_CODEC_ID_NONE;
-}
-
-/* WTV GUIDs */
-static const ff_asf_guid wtv_guid =
+const ff_asf_guid ff_wtv_guid =
     {0xB7,0xD8,0x00,0x20,0x37,0x49,0xDA,0x11,0xA6,0x4E,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
-static const ff_asf_guid metadata_guid =
-    {0x5A,0xFE,0xD7,0x6D,0xC8,0x1D,0x8F,0x4A,0x99,0x22,0xFA,0xB1,0x1C,0x38,0x14,0x53};
-static const ff_asf_guid timestamp_guid =
+const ff_asf_guid ff_timestamp_guid =
     {0x5B,0x05,0xE6,0x1B,0x97,0xA9,0x49,0x43,0x88,0x17,0x1A,0x65,0x5A,0x29,0x8A,0x97};
-static const ff_asf_guid data_guid =
+const ff_asf_guid ff_data_guid =
     {0x95,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
-static const ff_asf_guid stream_guid =
+const ff_asf_guid ff_stream_guid =
     {0xED,0xA4,0x13,0x23,0x2D,0xBF,0x4F,0x45,0xAD,0x8A,0xD9,0x5B,0xA7,0xF9,0x1F,0xEE};
-static const ff_asf_guid stream2_guid =
-    {0xA2,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
-static const ff_asf_guid EVENTID_SubtitleSpanningEvent =
-    {0x48,0xC0,0xCE,0x5D,0xB9,0xD0,0x63,0x41,0x87,0x2C,0x4F,0x32,0x22,0x3B,0xE8,0x8A};
-static const ff_asf_guid EVENTID_LanguageSpanningEvent =
-    {0x6D,0x66,0x92,0xE2,0x02,0x9C,0x8D,0x44,0xAA,0x8D,0x78,0x1A,0x93,0xFD,0xC3,0x95};
-static const ff_asf_guid EVENTID_AudioDescriptorSpanningEvent =
-    {0x1C,0xD4,0x7B,0x10,0xDA,0xA6,0x91,0x46,0x83,0x69,0x11,0xB2,0xCD,0xAA,0x28,0x8E};
-static const ff_asf_guid EVENTID_CtxADescriptorSpanningEvent =
-    {0xE6,0xA2,0xB4,0x3A,0x47,0x42,0x34,0x4B,0x89,0x6C,0x30,0xAF,0xA5,0xD2,0x1C,0x24};
-static const ff_asf_guid EVENTID_CSDescriptorSpanningEvent =
-    {0xD9,0x79,0xE7,0xEf,0xF0,0x97,0x86,0x47,0x80,0x0D,0x95,0xCF,0x50,0x5D,0xDC,0x66};
-static const ff_asf_guid EVENTID_DVBScramblingControlSpanningEvent =
-    {0xC4,0xE1,0xD4,0x4B,0xA1,0x90,0x09,0x41,0x82,0x36,0x27,0xF0,0x0E,0x7D,0xCC,0x5B};
-static const ff_asf_guid EVENTID_StreamIDSpanningEvent =
-    {0x68,0xAB,0xF1,0xCA,0x53,0xE1,0x41,0x4D,0xA6,0xB3,0xA7,0xC9,0x98,0xDB,0x75,0xEE};
-static const ff_asf_guid EVENTID_TeletextSpanningEvent =
-    {0x50,0xD9,0x99,0x95,0x33,0x5F,0x17,0x46,0xAF,0x7C,0x1E,0x54,0xB5,0x10,0xDA,0xA3};
-static const ff_asf_guid EVENTID_AudioTypeSpanningEvent =
-    {0xBE,0xBF,0x1C,0x50,0x49,0xB8,0xCE,0x42,0x9B,0xE9,0x3D,0xB8,0x69,0xFB,0x82,0xB3};
-
-/* Windows media GUIDs */
-
-#define MEDIASUBTYPE_BASE_GUID \
-    0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71
-
-/* Media types */
-static const ff_asf_guid mediatype_audio =
-    {'a','u','d','s',MEDIASUBTYPE_BASE_GUID};
-static const ff_asf_guid mediatype_video =
-    {'v','i','d','s',MEDIASUBTYPE_BASE_GUID};
-static const ff_asf_guid mediasubtype_mpeg1payload =
-    {0x81,0xEB,0x36,0xE4,0x4F,0x52,0xCE,0x11,0x9F,0x53,0x00,0x20,0xAF,0x0B,0xA7,0x70};
-static const ff_asf_guid mediatype_mpeg2_sections =
-    {0x6C,0x17,0x5F,0x45,0x06,0x4B,0xCE,0x47,0x9A,0xEF,0x8C,0xAE,0xF7,0x3D,0xF7,0xB5};
-static const ff_asf_guid mediatype_mpeg2_pes =
-    {0x20,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA};
-static const ff_asf_guid mediatype_mstvcaption =
-    {0x89,0x8A,0x8B,0xB8,0x49,0xB0,0x80,0x4C,0xAD,0xCF,0x58,0x98,0x98,0x5E,0x22,0xC1};
-
-/* Media subtypes */
-static const ff_asf_guid mediasubtype_cpfilters_processed =
-    {0x28,0xBD,0xAD,0x46,0xD0,0x6F,0x96,0x47,0x93,0xB2,0x15,0x5C,0x51,0xDC,0x04,0x8D};
-static const ff_asf_guid mediasubtype_dvb_subtitle =
-    {0xC3,0xCB,0xFF,0x34,0xB3,0xD5,0x71,0x41,0x90,0x02,0xD4,0xC6,0x03,0x01,0x69,0x7F};
-static const ff_asf_guid mediasubtype_teletext =
-    {0xE3,0x76,0x2A,0xF7,0x0A,0xEB,0xD0,0x11,0xAC,0xE4,0x00,0x00,0xC0,0xCC,0x16,0xBA};
-static const ff_asf_guid mediasubtype_dtvccdata =
-    {0xAA,0xDD,0x2A,0xF5,0xF0,0x36,0xF5,0x43,0x95,0xEA,0x6D,0x86,0x64,0x84,0x26,0x2A};
-static const ff_asf_guid mediasubtype_mpeg2_sections =
-    {0x79,0x85,0x9F,0x4A,0xF8,0x6B,0x92,0x43,0x8A,0x6D,0xD2,0xDD,0x09,0xFA,0x78,0x61};
-
-/* Formats */
-static const ff_asf_guid format_cpfilters_processed =
-    {0x6F,0xB3,0x39,0x67,0x5F,0x1D,0xC2,0x4A,0x81,0x92,0x28,0xBB,0x0E,0x73,0xD1,0x6A};
-static const ff_asf_guid format_waveformatex =
-    {0x81,0x9F,0x58,0x05,0x56,0xC3,0xCE,0x11,0xBF,0x01,0x00,0xAA,0x00,0x55,0x59,0x5A};
-static const ff_asf_guid format_videoinfo2 =
-    {0xA0,0x76,0x2A,0xF7,0x0A,0xEB,0xD0,0x11,0xAC,0xE4,0x00,0x00,0xC0,0xCC,0x16,0xBA};
-static const ff_asf_guid format_mpeg2_video =
-    {0xE3,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA};
-static const ff_asf_guid format_none =
+const ff_asf_guid ff_mediatype_audio =
+    {'a','u','d','s',FF_MEDIASUBTYPE_BASE_GUID};
+const ff_asf_guid ff_mediatype_video =
+    {'v','i','d','s',FF_MEDIASUBTYPE_BASE_GUID};
+const ff_asf_guid ff_format_none =
     {0xD6,0x17,0x64,0x0F,0x18,0xC3,0xD0,0x11,0xA4,0x3F,0x00,0xA0,0xC9,0x22,0x31,0x96};
 
-static const AVCodecGuid video_guids[] = {
-    {AV_CODEC_ID_MPEG2VIDEO, {0x26,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA}},
-    {AV_CODEC_ID_NONE}
-};
-
-static const AVCodecGuid audio_guids[] = {
-    {AV_CODEC_ID_AC3,        {0x2C,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA}},
-    {AV_CODEC_ID_EAC3,       {0xAF,0x87,0xFB,0xA7,0x02,0x2D,0xFB,0x42,0xA4,0xD4,0x05,0xCD,0x93,0x84,0x3B,0xDD}},
-    {AV_CODEC_ID_MP2,        {0x2B,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA}},
-    {AV_CODEC_ID_NONE}
-};
-
-static int read_probe(AVProbeData *p)
-{
-    return ff_guidcmp(p->buf, wtv_guid) ? 0 : AVPROBE_SCORE_MAX;
-}
-
-/**
- * Convert win32 FILETIME to ISO-8601 string
- */
-static void filetime_to_iso8601(char *buf, int buf_size, int64_t value)
-{
-    time_t t = (value / 10000000LL) - 11644473600LL;
-    struct tm *tm = gmtime(&t);
-    if (tm)
-        strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
-    else
-        buf[0] = '\0';
-}
-
-/**
- * Convert crazy time (100ns since 1 Jan 0001) to ISO-8601 string
- */
-static void crazytime_to_iso8601(char *buf, int buf_size, int64_t value)
-{
-    time_t t = (value / 10000000LL) - 719162LL*86400LL;
-    struct tm *tm = gmtime(&t);
-    if (tm)
-        strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
-    else
-        buf[0] = '\0';
-}
-
-/**
- * Convert OLE DATE to ISO-8601 string
- */
-static void oledate_to_iso8601(char *buf, int buf_size, int64_t value)
-{
-    time_t t = 631112400LL + 86400*av_int2double(value);
-    struct tm *tm = gmtime(&t);
-    if (tm)
-        strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
-    else
-        buf[0] = '\0';
-}
-
-static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length)
-{
-    char mime[1024];
-    char description[1024];
-    unsigned int filesize;
-    AVStream *st;
-    int64_t pos = avio_tell(pb);
-
-    avio_get_str16le(pb, INT_MAX, mime, sizeof(mime));
-    if (strcmp(mime, "image/jpeg"))
-        goto done;
-
-    avio_r8(pb);
-    avio_get_str16le(pb, INT_MAX, description, sizeof(description));
-    filesize = avio_rl32(pb);
-    if (!filesize)
-        goto done;
-
-    st = avformat_new_stream(s, NULL);
-    if (!st)
-        goto done;
-    av_dict_set(&st->metadata, "title", description, 0);
-    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)
-        goto done;
-    st->codec->extradata_size = filesize;
-    avio_read(pb, st->codec->extradata, filesize);
-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);
-    if (!buf)
-        return;
-
-    if (type == 0 && length == 4) {
-        snprintf(buf, buf_size, "%"PRIi32, avio_rl32(pb));
-    } else if (type == 1) {
-        avio_get_str16le(pb, length, buf, buf_size);
-        if (!strlen(buf)) {
-           av_free(buf);
-           return;
-        }
-    } else if (type == 3 && length == 4) {
-        strcpy(buf, avio_rl32(pb) ? "true" : "false");
-    } else if (type == 4 && length == 8) {
-        int64_t num = avio_rl64(pb);
-        if (!strcmp(key, "WM/EncodingTime") ||
-            !strcmp(key, "WM/MediaOriginalBroadcastDateTime"))
-            filetime_to_iso8601(buf, buf_size, num);
-        else if (!strcmp(key, "WM/WMRVEncodeTime") ||
-                 !strcmp(key, "WM/WMRVEndTime"))
-            crazytime_to_iso8601(buf, buf_size, num);
-        else if (!strcmp(key, "WM/WMRVExpirationDate"))
-            oledate_to_iso8601(buf, buf_size, num);
-        else if (!strcmp(key, "WM/WMRVBitrate"))
-            snprintf(buf, buf_size, "%f", av_int2double(num));
-        else
-            snprintf(buf, buf_size, "%"PRIi64, num);
-    } else if (type == 5 && length == 2) {
-        snprintf(buf, buf_size, "%"PRIi16, avio_rl16(pb));
-    } else if (type == 6 && length == 16) {
-        ff_asf_guid guid;
-        avio_read(pb, guid, 16);
-        snprintf(buf, buf_size, PRI_PRETTY_GUID, ARG_PRETTY_GUID(guid));
-    } else if (type == 2 && !strcmp(key, "WM/Picture")) {
-        get_attachment(s, pb, length);
-        av_freep(&buf);
-        return;
-    } else {
-        av_freep(&buf);
-        av_log(s, AV_LOG_WARNING, "unsupported metadata entry; key:%s, type:%d, length:0x%x\n", key, type, length);
-        avio_skip(pb, length);
-        return;
-    }
-
-    av_dict_set(&s->metadata, key, buf, 0);
-    av_freep(&buf);
-}
-
-/**
- * Parse metadata entries
- */
-static void parse_legacy_attrib(AVFormatContext *s, AVIOContext *pb)
-{
-    ff_asf_guid guid;
-    int length, type;
-    while(!pb->eof_reached) {
-        char key[1024];
-        ff_get_guid(pb, &guid);
-        type   = avio_rl32(pb);
-        length = avio_rl32(pb);
-        if (!length)
-            break;
-        if (ff_guidcmp(&guid, metadata_guid)) {
-            av_log(s, AV_LOG_WARNING, "unknown guid "PRI_GUID", expected metadata_guid; "
-                   "remaining metadata entries ignored\n", ARG_GUID(guid));
-            break;
-        }
-        avio_get_str16le(pb, INT_MAX, key, sizeof(key));
-        get_tag(s, pb, key, type, length);
-    }
-
-    ff_metadata_conv(&s->metadata, NULL, ff_asf_metadata_conv);
-}
-
-/**
- * parse VIDEOINFOHEADER2 structure
- * @return bytes consumed
- */
-static int parse_videoinfoheader2(AVFormatContext *s, AVStream *st)
-{
-    WtvContext *wtv = s->priv_data;
-    AVIOContext *pb = wtv->pb;
-
-    avio_skip(pb, 72);  // picture aspect ratio is unreliable
-    ff_get_bmp_header(pb, st);
-
-    return 72 + 40;
-}
-
-/**
- * Parse MPEG1WAVEFORMATEX extradata structure
- */
-static void parse_mpeg1waveformatex(AVStream *st)
-{
-    /* fwHeadLayer */
-    switch (AV_RL16(st->codec->extradata)) {
-    case 0x0001 : st->codec->codec_id = AV_CODEC_ID_MP1; break;
-    case 0x0002 : st->codec->codec_id = AV_CODEC_ID_MP2; break;
-    case 0x0004 : st->codec->codec_id = AV_CODEC_ID_MP3; break;
-    }
-
-    st->codec->bit_rate = AV_RL32(st->codec->extradata + 2); /* dwHeadBitrate */
-
-    /* dwHeadMode */
-    switch (AV_RL16(st->codec->extradata + 6)) {
-    case 1 : case 2 : case 4 : st->codec->channels = 2; break;
-    case 8 :                   st->codec->channels = 1; break;
-    }
-}
-
-/**
- * Initialise stream
- * @param st Stream to initialise, or NULL to create and initialise new stream
- * @return NULL on error
- */
-static AVStream * new_stream(AVFormatContext *s, AVStream *st, int sid, int codec_type)
-{
-    if (st) {
-        if (st->codec->extradata) {
-            av_freep(&st->codec->extradata);
-            st->codec->extradata_size = 0;
-        }
-    } else {
-        WtvStream *wst = av_mallocz(sizeof(WtvStream));
-        if (!wst)
-            return NULL;
-        st = avformat_new_stream(s, NULL);
-        if (!st)
-            return NULL;
-        st->id = sid;
-        st->priv_data = wst;
-    }
-    st->codec->codec_type = codec_type;
-    st->need_parsing      = AVSTREAM_PARSE_FULL;
-    avpriv_set_pts_info(st, 64, 1, 10000000);
-    return st;
-}
-
-/**
- * parse Media Type structure and populate stream
- * @param st         Stream, or NULL to create new stream
- * @param mediatype  Mediatype GUID
- * @param subtype    Subtype GUID
- * @param formattype Format GUID
- * @param size       Size of format buffer
- * @return NULL on error
- */
-static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid,
-                                   ff_asf_guid mediatype, ff_asf_guid subtype,
-                                   ff_asf_guid formattype, int size)
-{
-    WtvContext *wtv = s->priv_data;
-    AVIOContext *pb = wtv->pb;
-    if (!ff_guidcmp(subtype, mediasubtype_cpfilters_processed) &&
-        !ff_guidcmp(formattype, format_cpfilters_processed)) {
-        ff_asf_guid actual_subtype;
-        ff_asf_guid actual_formattype;
-
-        if (size < 32) {
-            av_log(s, AV_LOG_WARNING, "format buffer size underflow\n");
-            avio_skip(pb, size);
-            return NULL;
-        }
-
-        avio_skip(pb, size - 32);
-        ff_get_guid(pb, &actual_subtype);
-        ff_get_guid(pb, &actual_formattype);
-        avio_seek(pb, -size, SEEK_CUR);
-
-        st = parse_media_type(s, st, sid, mediatype, actual_subtype, actual_formattype, size - 32);
-        avio_skip(pb, 32);
-        return st;
-    } else if (!ff_guidcmp(mediatype, mediatype_audio)) {
-        st = new_stream(s, st, sid, AVMEDIA_TYPE_AUDIO);
-        if (!st)
-            return NULL;
-        if (!ff_guidcmp(formattype, format_waveformatex)) {
-            int ret = ff_get_wav_header(pb, st->codec, size);
-            if (ret < 0)
-                return NULL;
-        } else {
-            if (ff_guidcmp(formattype, format_none))
-                av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype));
-            avio_skip(pb, size);
-        }
-
-        if (!memcmp(subtype + 4, (const uint8_t[]){MEDIASUBTYPE_BASE_GUID}, 12)) {
-            st->codec->codec_id = ff_wav_codec_get_id(AV_RL32(subtype), st->codec->bits_per_coded_sample);
-        } else if (!ff_guidcmp(subtype, mediasubtype_mpeg1payload)) {
-            if (st->codec->extradata && st->codec->extradata_size >= 22)
-                parse_mpeg1waveformatex(st);
-            else
-                av_log(s, AV_LOG_WARNING, "MPEG1WAVEFORMATEX underflow\n");
-        } else {
-            st->codec->codec_id = ff_codec_guid_get_id(audio_guids, subtype);
-            if (st->codec->codec_id == AV_CODEC_ID_NONE)
-                av_log(s, AV_LOG_WARNING, "unknown subtype:"PRI_GUID"\n", ARG_GUID(subtype));
-        }
-        return st;
-    } else if (!ff_guidcmp(mediatype, mediatype_video)) {
-        st = new_stream(s, st, sid, AVMEDIA_TYPE_VIDEO);
-        if (!st)
-            return NULL;
-        if (!ff_guidcmp(formattype, format_videoinfo2)) {
-            int consumed = parse_videoinfoheader2(s, st);
-            avio_skip(pb, FFMAX(size - consumed, 0));
-        } else if (!ff_guidcmp(formattype, format_mpeg2_video)) {
-            int consumed = parse_videoinfoheader2(s, st);
-            avio_skip(pb, FFMAX(size - consumed, 0));
-        } else {
-            if (ff_guidcmp(formattype, format_none))
-                av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype));
-            avio_skip(pb, size);
-        }
-
-        if (!memcmp(subtype + 4, (const uint8_t[]){MEDIASUBTYPE_BASE_GUID}, 12)) {
-            st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, AV_RL32(subtype));
-        } else {
-            st->codec->codec_id = ff_codec_guid_get_id(video_guids, subtype);
-        }
-        if (st->codec->codec_id == AV_CODEC_ID_NONE)
-            av_log(s, AV_LOG_WARNING, "unknown subtype:"PRI_GUID"\n", ARG_GUID(subtype));
-        return st;
-    } else if (!ff_guidcmp(mediatype, mediatype_mpeg2_pes) &&
-               !ff_guidcmp(subtype, mediasubtype_dvb_subtitle)) {
-        st = new_stream(s, st, sid, AVMEDIA_TYPE_SUBTITLE);
-        if (!st)
-            return NULL;
-        if (ff_guidcmp(formattype, format_none))
-            av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype));
-        avio_skip(pb, size);
-        st->codec->codec_id = AV_CODEC_ID_DVB_SUBTITLE;
-        return st;
-    } else if (!ff_guidcmp(mediatype, mediatype_mstvcaption) &&
-               (!ff_guidcmp(subtype, mediasubtype_teletext) || !ff_guidcmp(subtype, mediasubtype_dtvccdata))) {
-        st = new_stream(s, st, sid, AVMEDIA_TYPE_SUBTITLE);
-        if (!st)
-            return NULL;
-        if (ff_guidcmp(formattype, format_none))
-            av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype));
-        avio_skip(pb, size);
-        st->codec->codec_id   = AV_CODEC_ID_DVB_TELETEXT;
-        return st;
-    } else if (!ff_guidcmp(mediatype, mediatype_mpeg2_sections) &&
-               !ff_guidcmp(subtype, mediasubtype_mpeg2_sections)) {
-        if (ff_guidcmp(formattype, format_none))
-            av_log(s, AV_LOG_WARNING, "unknown formattype:"PRI_GUID"\n", ARG_GUID(formattype));
-        avio_skip(pb, size);
-        return NULL;
-    }
-
-    av_log(s, AV_LOG_WARNING, "unknown media type, mediatype:"PRI_GUID
-                              ", subtype:"PRI_GUID", formattype:"PRI_GUID"\n",
-                              ARG_GUID(mediatype), ARG_GUID(subtype), ARG_GUID(formattype));
-    avio_skip(pb, size);
-    return NULL;
-}
-
-enum {
-    SEEK_TO_DATA = 0,
-    SEEK_TO_PTS,
-};
-
-/**
- * Parse WTV chunks
- * @param mode SEEK_TO_DATA or SEEK_TO_PTS
- * @param seekts timestamp
- * @param[out] len_ptr Length of data chunk
- * @return stream index of data chunk, or <0 on error
- */
-static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_ptr)
-{
-    WtvContext *wtv = s->priv_data;
-    AVIOContext *pb = wtv->pb;
-    while (!pb->eof_reached) {
-        ff_asf_guid g;
-        int len, sid, consumed;
-
-        ff_get_guid(pb, &g);
-        len = avio_rl32(pb);
-        if (len < 32)
-            break;
-        sid = avio_rl32(pb) & 0x7FFF;
-        avio_skip(pb, 8);
-        consumed = 32;
-
-        if (!ff_guidcmp(g, stream_guid)) {
-            if (ff_find_stream_index(s, sid) < 0) {
-                ff_asf_guid mediatype, subtype, formattype;
-                int size;
-                avio_skip(pb, 28);
-                ff_get_guid(pb, &mediatype);
-                ff_get_guid(pb, &subtype);
-                avio_skip(pb, 12);
-                ff_get_guid(pb, &formattype);
-                size = avio_rl32(pb);
-                parse_media_type(s, 0, sid, mediatype, subtype, formattype, size);
-                consumed += 92 + size;
-            }
-        } else if (!ff_guidcmp(g, stream2_guid)) {
-            int stream_index = ff_find_stream_index(s, sid);
-            if (stream_index >= 0 && !((WtvStream*)s->streams[stream_index]->priv_data)->seen_data) {
-                ff_asf_guid mediatype, subtype, formattype;
-                int size;
-                avio_skip(pb, 12);
-                ff_get_guid(pb, &mediatype);
-                ff_get_guid(pb, &subtype);
-                avio_skip(pb, 12);
-                ff_get_guid(pb, &formattype);
-                size = avio_rl32(pb);
-                parse_media_type(s, s->streams[stream_index], sid, mediatype, subtype, formattype, size);
-                consumed += 76 + size;
-            }
-        } else if (!ff_guidcmp(g, EVENTID_AudioDescriptorSpanningEvent) ||
-                   !ff_guidcmp(g, EVENTID_CtxADescriptorSpanningEvent) ||
-                   !ff_guidcmp(g, EVENTID_CSDescriptorSpanningEvent) ||
-                   !ff_guidcmp(g, EVENTID_StreamIDSpanningEvent) ||
-                   !ff_guidcmp(g, EVENTID_SubtitleSpanningEvent) ||
-                   !ff_guidcmp(g, EVENTID_TeletextSpanningEvent)) {
-            int stream_index = ff_find_stream_index(s, sid);
-            if (stream_index >= 0) {
-                AVStream *st = s->streams[stream_index];
-                uint8_t buf[258];
-                const uint8_t *pbuf = buf;
-                int buf_size;
-
-                avio_skip(pb, 8);
-                consumed += 8;
-                if (!ff_guidcmp(g, EVENTID_CtxADescriptorSpanningEvent) ||
-                    !ff_guidcmp(g, EVENTID_CSDescriptorSpanningEvent)) {
-                    avio_skip(pb, 6);
-                    consumed += 6;
-                }
-
-                buf_size = FFMIN(len - consumed, sizeof(buf));
-                avio_read(pb, buf, buf_size);
-                consumed += buf_size;
-                ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, NULL, 0, 0, NULL);
-            }
-        } else if (!ff_guidcmp(g, EVENTID_AudioTypeSpanningEvent)) {
-            int stream_index = ff_find_stream_index(s, sid);
-            if (stream_index >= 0) {
-                AVStream *st = s->streams[stream_index];
-                int audio_type;
-                avio_skip(pb, 8);
-                audio_type = avio_r8(pb);
-                if (audio_type == 2)
-                    st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED;
-                else if (audio_type == 3)
-                    st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;
-                consumed += 9;
-            }
-        } else if (!ff_guidcmp(g, EVENTID_DVBScramblingControlSpanningEvent)) {
-            int stream_index = ff_find_stream_index(s, sid);
-            if (stream_index >= 0) {
-                avio_skip(pb, 12);
-                if (avio_rl32(pb))
-                    av_log(s, AV_LOG_WARNING, "DVB scrambled stream detected (st:%d), decoding will likely fail\n", stream_index);
-                consumed += 16;
-            }
-        } else if (!ff_guidcmp(g, EVENTID_LanguageSpanningEvent)) {
-            int stream_index = ff_find_stream_index(s, sid);
-            if (stream_index >= 0) {
-                AVStream *st = s->streams[stream_index];
-                uint8_t language[4];
-                avio_skip(pb, 12);
-                avio_read(pb, language, 3);
-                if (language[0]) {
-                    language[3] = 0;
-                    av_dict_set(&st->metadata, "language", language, 0);
-                    if (!strcmp(language, "nar") || !strcmp(language, "NAR"))
-                        st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;
-                }
-                consumed += 15;
-            }
-        } else if (!ff_guidcmp(g, timestamp_guid)) {
-            int stream_index = ff_find_stream_index(s, sid);
-            if (stream_index >= 0) {
-                avio_skip(pb, 8);
-                wtv->pts = avio_rl64(pb);
-                consumed += 16;
-                if (wtv->pts == -1)
-                    wtv->pts = AV_NOPTS_VALUE;
-                else {
-                    wtv->last_valid_pts = wtv->pts;
-                    if (wtv->epoch == AV_NOPTS_VALUE || wtv->pts < wtv->epoch)
-                        wtv->epoch = wtv->pts;
-                if (mode == SEEK_TO_PTS && wtv->pts >= seekts) {
-#define WTV_PAD8(x) (((x) + 7) & ~7)
-                    avio_skip(pb, WTV_PAD8(len) - consumed);
-                    return 0;
-                }
-                }
-            }
-        } else if (!ff_guidcmp(g, data_guid)) {
-            int stream_index = ff_find_stream_index(s, sid);
-            if (mode == SEEK_TO_DATA && stream_index >= 0 && len > 32) {
-                WtvStream *wst = s->streams[stream_index]->priv_data;
-                wst->seen_data = 1;
-                if (len_ptr) {
-                    *len_ptr = len;
-                }
-                return stream_index;
-            }
-        } else if (
-            !ff_guidcmp(g, /* DSATTRIB_CAPTURE_STREAMTIME */ (const ff_asf_guid){0x14,0x56,0x1A,0x0C,0xCD,0x30,0x40,0x4F,0xBC,0xBF,0xD0,0x3E,0x52,0x30,0x62,0x07}) ||
-            !ff_guidcmp(g, /* DSATTRIB_PicSampleSeq */ (const ff_asf_guid){0x02,0xAE,0x5B,0x2F,0x8F,0x7B,0x60,0x4F,0x82,0xD6,0xE4,0xEA,0x2F,0x1F,0x4C,0x99}) ||
-            !ff_guidcmp(g, /* DSATTRIB_TRANSPORT_PROPERTIES */ (const ff_asf_guid){0x12,0xF6,0x22,0xB6,0xAD,0x47,0x71,0x46,0xAD,0x6C,0x05,0xA9,0x8E,0x65,0xDE,0x3A}) ||
-            !ff_guidcmp(g, /* dvr_ms_vid_frame_rep_data */ (const ff_asf_guid){0xCC,0x32,0x64,0xDD,0x29,0xE2,0xDB,0x40,0x80,0xF6,0xD2,0x63,0x28,0xD2,0x76,0x1F}) ||
-            !ff_guidcmp(g, /* EVENTID_ChannelChangeSpanningEvent */ (const ff_asf_guid){0xE5,0xC5,0x67,0x90,0x5C,0x4C,0x05,0x42,0x86,0xC8,0x7A,0xFE,0x20,0xFE,0x1E,0xFA}) ||
-            !ff_guidcmp(g, /* EVENTID_ChannelInfoSpanningEvent */ (const ff_asf_guid){0x80,0x6D,0xF3,0x41,0x32,0x41,0xC2,0x4C,0xB1,0x21,0x01,0xA4,0x32,0x19,0xD8,0x1B}) ||
-            !ff_guidcmp(g, /* EVENTID_ChannelTypeSpanningEvent */ (const ff_asf_guid){0x51,0x1D,0xAB,0x72,0xD2,0x87,0x9B,0x48,0xBA,0x11,0x0E,0x08,0xDC,0x21,0x02,0x43}) ||
-            !ff_guidcmp(g, /* EVENTID_PIDListSpanningEvent */ (const ff_asf_guid){0x65,0x8F,0xFC,0x47,0xBB,0xE2,0x34,0x46,0x9C,0xEF,0xFD,0xBF,0xE6,0x26,0x1D,0x5C}) ||
-            !ff_guidcmp(g, /* EVENTID_SignalAndServiceStatusSpanningEvent */ (const ff_asf_guid){0xCB,0xC5,0x68,0x80,0x04,0x3C,0x2B,0x49,0xB4,0x7D,0x03,0x08,0x82,0x0D,0xCE,0x51}) ||
-            !ff_guidcmp(g, /* EVENTID_StreamTypeSpanningEvent */ (const ff_asf_guid){0xBC,0x2E,0xAF,0x82,0xA6,0x30,0x64,0x42,0xA8,0x0B,0xAD,0x2E,0x13,0x72,0xAC,0x60}) ||
-            !ff_guidcmp(g, (const ff_asf_guid){0x1E,0xBE,0xC3,0xC5,0x43,0x92,0xDC,0x11,0x85,0xE5,0x00,0x12,0x3F,0x6F,0x73,0xB9}) ||
-            !ff_guidcmp(g, (const ff_asf_guid){0x3B,0x86,0xA2,0xB1,0xEB,0x1E,0xC3,0x44,0x8C,0x88,0x1C,0xA3,0xFF,0xE3,0xE7,0x6A}) ||
-            !ff_guidcmp(g, (const ff_asf_guid){0x4E,0x7F,0x4C,0x5B,0xC4,0xD0,0x38,0x4B,0xA8,0x3E,0x21,0x7F,0x7B,0xBF,0x52,0xE7}) ||
-            !ff_guidcmp(g, (const ff_asf_guid){0x63,0x36,0xEB,0xFE,0xA1,0x7E,0xD9,0x11,0x83,0x08,0x00,0x07,0xE9,0x5E,0xAD,0x8D}) ||
-            !ff_guidcmp(g, (const ff_asf_guid){0x70,0xE9,0xF1,0xF8,0x89,0xA4,0x4C,0x4D,0x83,0x73,0xB8,0x12,0xE0,0xD5,0xF8,0x1E}) ||
-            !ff_guidcmp(g, (const ff_asf_guid){0x96,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D}) ||
-            !ff_guidcmp(g, (const ff_asf_guid){0x97,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D}) ||
-            !ff_guidcmp(g, (const ff_asf_guid){0xA1,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D})) {
-            //ignore known guids
-        } else
-            av_log(s, AV_LOG_WARNING, "unsupported chunk:"PRI_GUID"\n", ARG_GUID(g));
-
-        avio_skip(pb, WTV_PAD8(len) - consumed);
-    }
-    return AVERROR_EOF;
-}
-
 /* declare utf16le strings */
 #define _ , 0,
-static const uint8_t timeline_le16[] =
+const uint8_t ff_timeline_le16[] =
     {'t'_'i'_'m'_'e'_'l'_'i'_'n'_'e', 0};
-static const uint8_t table_0_entries_legacy_attrib_le16[] =
-    {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'e'_'n'_'t'_'r'_'i'_'e'_'s'_'.'_'l'_'e'_'g'_'a'_'c'_'y'_'_'_'a'_'t'_'t'_'r'_'i'_'b', 0};
-static const uint8_t table_0_entries_time_le16[] =
-    {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'e'_'n'_'t'_'r'_'i'_'e'_'s'_'.'_'t'_'i'_'m'_'e', 0};
-static const uint8_t timeline_table_0_entries_Events_le16[] =
+const uint8_t ff_timeline_table_0_entries_Events_le16[] =
     {'t'_'i'_'m'_'e'_'l'_'i'_'n'_'e'_'.'_'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'e'_'n'_'t'_'r'_'i'_'e'_'s'_'.'_'E'_'v'_'e'_'n'_'t'_'s', 0};
+const uint8_t ff_table_0_entries_legacy_attrib_le16[] =
+    {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'e'_'n'_'t'_'r'_'i'_'e'_'s'_'.'_'l'_'e'_'g'_'a'_'c'_'y'_'_'_'a'_'t'_'t'_'r'_'i'_'b', 0};
+const uint8_t ff_table_0_entries_time_le16[] =
+    {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'e'_'n'_'t'_'r'_'i'_'e'_'s'_'.'_'t'_'i'_'m'_'e', 0};
 #undef _
 
-static int read_header(AVFormatContext *s)
-{
-    WtvContext *wtv = s->priv_data;
-    int root_sector, root_size;
-    uint8_t root[WTV_SECTOR_SIZE];
-    AVIOContext *pb;
-    int64_t timeline_pos;
-    int ret;
+const ff_asf_guid ff_DSATTRIB_TRANSPORT_PROPERTIES =
+    {0x12,0xF6,0x22,0xB6,0xAD,0x47,0x71,0x46,0xAD,0x6C,0x05,0xA9,0x8E,0x65,0xDE,0x3A};
+const ff_asf_guid ff_metadata_guid =
+    {0x5A,0xFE,0xD7,0x6D,0xC8,0x1D,0x8F,0x4A,0x99,0x22,0xFA,0xB1,0x1C,0x38,0x14,0x53};
+const ff_asf_guid ff_stream2_guid =
+    {0xA2,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
 
-    wtv->epoch          =
-    wtv->pts            =
-    wtv->last_valid_pts = AV_NOPTS_VALUE;
+/* Media subtypes */
+const ff_asf_guid ff_mediasubtype_cpfilters_processed =
+    {0x28,0xBD,0xAD,0x46,0xD0,0x6F,0x96,0x47,0x93,0xB2,0x15,0x5C,0x51,0xDC,0x04,0x8D};
 
-    /* read root directory sector */
-    avio_skip(s->pb, 0x30);
-    root_size = avio_rl32(s->pb);
-    if (root_size > sizeof(root)) {
-        av_log(s, AV_LOG_ERROR, "root directory size exceeds sector size\n");
-        return AVERROR_INVALIDDATA;
-    }
-    avio_skip(s->pb, 4);
-    root_sector = avio_rl32(s->pb);
+/* Formats */
+const ff_asf_guid ff_format_cpfilters_processed =
+    {0x6F,0xB3,0x39,0x67,0x5F,0x1D,0xC2,0x4A,0x81,0x92,0x28,0xBB,0x0E,0x73,0xD1,0x6A};
+const ff_asf_guid ff_format_waveformatex =
+    {0x81,0x9F,0x58,0x05,0x56,0xC3,0xCE,0x11,0xBF,0x01,0x00,0xAA,0x00,0x55,0x59,0x5A};
+const ff_asf_guid ff_format_mpeg2_video =
+    {0xE3,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA};
 
-    avio_seek(s->pb, root_sector << WTV_SECTOR_BITS, SEEK_SET);
-    root_size = avio_read(s->pb, root, root_size);
-    if (root_size < 0)
-        return AVERROR_INVALIDDATA;
-
-    /* parse chunks up until first data chunk */
-    wtv->pb = wtvfile_open(s, root, root_size, timeline_le16);
-    if (!wtv->pb) {
-        av_log(s, AV_LOG_ERROR, "timeline data missing\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    ret = parse_chunks(s, SEEK_TO_DATA, 0, 0);
-    if (ret < 0)
-        return ret;
-    avio_seek(wtv->pb, -32, SEEK_CUR);
-
-    timeline_pos = avio_tell(s->pb); // save before opening another file
-
-    /* read metadata */
-    pb = wtvfile_open(s, root, root_size, table_0_entries_legacy_attrib_le16);
-    if (pb) {
-        parse_legacy_attrib(s, pb);
-        wtvfile_close(pb);
-    }
-
-    /* read seek index */
-    if (s->nb_streams) {
-        AVStream *st = s->streams[0];
-        pb = wtvfile_open(s, root, root_size, table_0_entries_time_le16);
-        if (pb) {
-            while(1) {
-                uint64_t timestamp = avio_rl64(pb);
-                uint64_t frame_nb  = avio_rl64(pb);
-                if (pb->eof_reached)
-                    break;
-                ff_add_index_entry(&wtv->index_entries, &wtv->nb_index_entries, &wtv->index_entries_allocated_size,
-                                   0, timestamp, frame_nb, 0, AVINDEX_KEYFRAME);
-            }
-            wtvfile_close(pb);
-
-            if (wtv->nb_index_entries) {
-                pb = wtvfile_open(s, root, root_size, timeline_table_0_entries_Events_le16);
-                if (pb) {
-                    int i;
-                    while (1) {
-                        uint64_t frame_nb = avio_rl64(pb);
-                        uint64_t position = avio_rl64(pb);
-                        if (pb->eof_reached)
-                            break;
-                        for (i = wtv->nb_index_entries - 1; i >= 0; i--) {
-                            AVIndexEntry *e = wtv->index_entries + i;
-                            if (frame_nb > e->size)
-                                break;
-                            if (position > e->pos)
-                                e->pos = position;
-                        }
-                    }
-                    wtvfile_close(pb);
-                    st->duration = wtv->index_entries[wtv->nb_index_entries - 1].timestamp;
-                }
-            }
-        }
-    }
-
-    avio_seek(s->pb, timeline_pos, SEEK_SET);
-    return 0;
-}
-
-static int read_packet(AVFormatContext *s, AVPacket *pkt)
-{
-    WtvContext *wtv = s->priv_data;
-    AVIOContext *pb = wtv->pb;
-    int stream_index, len, ret;
-
-    stream_index = parse_chunks(s, SEEK_TO_DATA, 0, &len);
-    if (stream_index < 0)
-        return stream_index;
-
-    ret = av_get_packet(pb, pkt, len - 32);
-    if (ret < 0)
-        return ret;
-    pkt->stream_index = stream_index;
-    pkt->pts          = wtv->pts;
-    avio_skip(pb, WTV_PAD8(len) - len);
-    return 0;
-}
-
-static int read_seek(AVFormatContext *s, int stream_index,
-                     int64_t ts, int flags)
-{
-    WtvContext *wtv = s->priv_data;
-    AVIOContext *pb = wtv->pb;
-    AVStream *st = s->streams[0];
-    int64_t ts_relative;
-    int i;
-
-    if ((flags & AVSEEK_FLAG_FRAME) || (flags & AVSEEK_FLAG_BYTE))
-        return AVERROR(ENOSYS);
-
-    /* timestamp adjustment is required because wtv->pts values are absolute,
-     * whereas AVIndexEntry->timestamp values are relative to epoch. */
-    ts_relative = ts;
-    if (wtv->epoch != AV_NOPTS_VALUE)
-        ts_relative -= wtv->epoch;
-
-    i = ff_index_search_timestamp(wtv->index_entries, wtv->nb_index_entries, ts_relative, flags);
-    if (i < 0) {
-        if (wtv->last_valid_pts == AV_NOPTS_VALUE || ts < wtv->last_valid_pts)
-            avio_seek(pb, 0, SEEK_SET);
-        else if (st->duration != AV_NOPTS_VALUE && ts_relative > st->duration && wtv->nb_index_entries)
-            avio_seek(pb, wtv->index_entries[wtv->nb_index_entries - 1].pos, SEEK_SET);
-        if (parse_chunks(s, SEEK_TO_PTS, ts, 0) < 0)
-            return AVERROR(ERANGE);
-        return 0;
-    }
-    wtv->pts = wtv->index_entries[i].timestamp;
-    if (wtv->epoch != AV_NOPTS_VALUE)
-        wtv->pts += wtv->epoch;
-    wtv->last_valid_pts = wtv->pts;
-    avio_seek(pb, wtv->index_entries[i].pos, SEEK_SET);
-    return 0;
-}
-
-static int read_close(AVFormatContext *s)
-{
-    WtvContext *wtv = s->priv_data;
-    av_free(wtv->index_entries);
-    wtvfile_close(wtv->pb);
-    return 0;
-}
-
-AVInputFormat ff_wtv_demuxer = {
-    .name           = "wtv",
-    .long_name      = NULL_IF_CONFIG_SMALL("Windows Television (WTV)"),
-    .priv_data_size = sizeof(WtvContext),
-    .read_probe     = read_probe,
-    .read_header    = read_header,
-    .read_packet    = read_packet,
-    .read_seek      = read_seek,
-    .read_close     = read_close,
-    .flags          = AVFMT_SHOW_IDS,
+const AVCodecGuid ff_video_guids[] = {
+    {AV_CODEC_ID_MPEG2VIDEO, {0x26,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA}},
+    {AV_CODEC_ID_NONE}
 };
diff --git a/libavformat/wtv.h b/libavformat/wtv.h
new file mode 100644
index 0000000..7e4f243
--- /dev/null
+++ b/libavformat/wtv.h
@@ -0,0 +1,55 @@
+/*
+ * Windows Television (WTV)
+ * Copyright (c) 2010-2011 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
+ */
+
+#ifndef AVFORMAT_WTV_H
+#define AVFORMAT_WTV_H
+
+#include "riff.h"
+#include "asf.h"
+
+#define WTV_SECTOR_BITS    12
+#define WTV_SECTOR_SIZE    (1 << WTV_SECTOR_BITS)
+#define WTV_BIGSECTOR_BITS 18
+#define WTV_PAD8(x) (((x) + 7) & ~7)
+
+extern const uint8_t ff_timeline_le16[16];
+extern const uint8_t ff_timeline_table_0_entries_Events_le16[62];
+extern const uint8_t ff_table_0_entries_legacy_attrib_le16[58];
+extern const uint8_t ff_table_0_entries_time_le16[40];
+
+extern const ff_asf_guid ff_dir_entry_guid;
+extern const ff_asf_guid ff_wtv_guid;
+extern const ff_asf_guid ff_timestamp_guid;
+extern const ff_asf_guid ff_data_guid;
+extern const ff_asf_guid ff_stream_guid;
+extern const ff_asf_guid ff_mediatype_audio;
+extern const ff_asf_guid ff_mediatype_video;
+extern const ff_asf_guid ff_format_none;
+extern const AVCodecGuid ff_video_guids[];
+
+extern const ff_asf_guid ff_DSATTRIB_TRANSPORT_PROPERTIES;
+extern const ff_asf_guid ff_metadata_guid;
+extern const ff_asf_guid ff_stream2_guid;
+extern const ff_asf_guid ff_mediasubtype_cpfilters_processed;
+extern const ff_asf_guid ff_format_cpfilters_processed;
+extern const ff_asf_guid ff_format_waveformatex;
+extern const ff_asf_guid ff_format_mpeg2_video;
+#endif /* AVFORMAT_WTV_H */
diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c
new file mode 100644
index 0000000..a8dc506
--- /dev/null
+++ b/libavformat/wtvdec.c
@@ -0,0 +1,1059 @@
+/*
+ * Windows Television (WTV) demuxer
+ * Copyright (c) 2010-2011 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
+ * Windows Television (WTV) demuxer
+ * @author Peter Ross <pross@xvid.org>
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "libavutil/intfloat.h"
+#include "avformat.h"
+#include "internal.h"
+#include "wtv.h"
+#include "mpegts.h"
+
+/* Macros for formating GUIDs */
+#define PRI_PRETTY_GUID \
+    "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x"
+#define ARG_PRETTY_GUID(g) \
+    AV_RL32(g),AV_RL16(g+4),AV_RL16(g+6),g[8],g[9],g[10],g[11],g[12],g[13],g[14],g[15]
+#define LEN_PRETTY_GUID 34
+
+/*
+ *
+ * File system routines
+ *
+ */
+
+typedef struct {
+    AVIOContext *pb_filesystem;  /** file system (AVFormatContext->pb) */
+
+    int sector_bits;     /** sector shift bits; used to convert sector number into pb_filesystem offset */
+    uint32_t *sectors;   /** file allocation table */
+    int nb_sectors;      /** number of sectors */
+
+    int error;
+    int64_t position;
+    int64_t length;
+} WtvFile;
+
+/**
+ * @return bytes read, 0 on end of file, or <0 on error
+ */
+static int wtvfile_read_packet(void *opaque, uint8_t *buf, int buf_size)
+{
+    WtvFile *wf = opaque;
+    AVIOContext *pb = wf->pb_filesystem;
+    int nread = 0;
+
+    if (wf->error || pb->error)
+        return -1;
+    if (wf->position >= wf->length || url_feof(pb))
+        return 0;
+
+    buf_size = FFMIN(buf_size, wf->length - wf->position);
+    while(nread < buf_size) {
+        int n;
+        int remaining_in_sector = (1 << wf->sector_bits) - (wf->position & ((1 << wf->sector_bits) - 1));
+        int read_request        = FFMIN(buf_size - nread, remaining_in_sector);
+
+        n = avio_read(pb, buf, read_request);
+        if (n <= 0)
+            break;
+        nread += n;
+        buf += n;
+        wf->position += n;
+        if (n == remaining_in_sector) {
+            int i = wf->position >> wf->sector_bits;
+            if (i >= wf->nb_sectors ||
+                (wf->sectors[i] != wf->sectors[i - 1] + (1 << (wf->sector_bits - WTV_SECTOR_BITS)) &&
+                avio_seek(pb, (int64_t)wf->sectors[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)) {
+                wf->error = 1;
+                break;
+            }
+        }
+    }
+    return nread;
+}
+
+/**
+ * @return position (or file length)
+ */
+static int64_t wtvfile_seek(void *opaque, int64_t offset, int whence)
+{
+    WtvFile *wf = opaque;
+    AVIOContext *pb = wf->pb_filesystem;
+
+    if (whence == AVSEEK_SIZE)
+        return wf->length;
+    else if (whence == SEEK_CUR)
+        offset = wf->position + offset;
+    else if (whence == SEEK_END)
+        offset = wf->length;
+
+    wf->error = offset < 0 || offset >= wf->length ||
+                avio_seek(pb, ((int64_t)wf->sectors[offset >> wf->sector_bits] << WTV_SECTOR_BITS)
+                              + (offset & ((1 << wf->sector_bits) - 1)), SEEK_SET) < 0;
+    wf->position = offset;
+    return offset;
+}
+
+/**
+ * read non-zero integers (le32) from input stream
+ * @param pb
+ * @param[out] data destination
+ * @param     count maximum number of integers to read
+ * @return    total number of integers read
+ */
+static int read_ints(AVIOContext *pb, uint32_t *data, int count)
+{
+    int i, total = 0;
+    for (i = 0; i < count; i++) {
+        if ((data[total] = avio_rl32(pb)))
+           total++;
+    }
+    return total;
+}
+
+/**
+ * Open file
+ * @param first_sector  First sector
+ * @param length        Length of file (bytes)
+ * @param depth         File allocation table depth
+ * @return NULL on error
+ */
+static AVIOContext * wtvfile_open_sector(int first_sector, uint64_t length, int depth, AVFormatContext *s)
+{
+    AVIOContext *pb;
+    WtvFile *wf;
+    uint8_t *buffer;
+
+    if (avio_seek(s->pb, first_sector << WTV_SECTOR_BITS, SEEK_SET) < 0)
+        return NULL;
+
+    wf = av_mallocz(sizeof(WtvFile));
+    if (!wf)
+        return NULL;
+
+    if (depth == 0) {
+        wf->sectors = av_malloc(sizeof(uint32_t));
+        if (!wf->sectors) {
+            av_free(wf);
+            return NULL;
+        }
+        wf->sectors[0]  = first_sector;
+        wf->nb_sectors  = 1;
+    } else if (depth == 1) {
+        wf->sectors = av_malloc(WTV_SECTOR_SIZE);
+        if (!wf->sectors) {
+            av_free(wf);
+            return NULL;
+        }
+        wf->nb_sectors  = read_ints(s->pb, wf->sectors, WTV_SECTOR_SIZE / 4);
+    } else if (depth == 2) {
+        uint32_t sectors1[WTV_SECTOR_SIZE / 4];
+        int nb_sectors1 = read_ints(s->pb, sectors1, WTV_SECTOR_SIZE / 4);
+        int i;
+
+        wf->sectors = av_malloc(nb_sectors1 << WTV_SECTOR_BITS);
+        if (!wf->sectors) {
+            av_free(wf);
+            return NULL;
+        }
+        wf->nb_sectors = 0;
+        for (i = 0; i < nb_sectors1; i++) {
+            if (avio_seek(s->pb, (int64_t)sectors1[i] << WTV_SECTOR_BITS, SEEK_SET) < 0)
+                break;
+            wf->nb_sectors += read_ints(s->pb, wf->sectors + i * WTV_SECTOR_SIZE / 4, WTV_SECTOR_SIZE / 4);
+        }
+    } else {
+        av_log(s, AV_LOG_ERROR, "unsupported file allocation table depth (0x%x)\n", depth);
+        av_free(wf);
+        return NULL;
+    }
+    wf->sector_bits = length & (1ULL<<63) ? WTV_SECTOR_BITS : WTV_BIGSECTOR_BITS;
+
+    if (!wf->nb_sectors) {
+        av_free(wf->sectors);
+        av_free(wf);
+        return NULL;
+    }
+
+    /* check length */
+    length &= 0xFFFFFFFFFFFF;
+    if (length > ((int64_t)wf->nb_sectors << wf->sector_bits)) {
+        av_log(s, AV_LOG_WARNING, "reported file length (0x%"PRIx64") exceeds number of available sectors (0x%"PRIx64")\n", length, (int64_t)wf->nb_sectors << wf->sector_bits);
+        length = (int64_t)wf->nb_sectors <<  wf->sector_bits;
+    }
+    wf->length = length;
+
+    /* seek to initial sector */
+    wf->position = 0;
+    if (avio_seek(s->pb, (int64_t)wf->sectors[0] << WTV_SECTOR_BITS, SEEK_SET) < 0) {
+        av_free(wf->sectors);
+        av_free(wf);
+        return NULL;
+    }
+
+    wf->pb_filesystem = s->pb;
+    buffer = av_malloc(1 << wf->sector_bits);
+    if (!buffer) {
+        av_free(wf->sectors);
+        av_free(wf);
+        return NULL;
+    }
+
+    pb = avio_alloc_context(buffer, 1 << wf->sector_bits, 0, wf,
+                           wtvfile_read_packet, NULL, wtvfile_seek);
+    if (!pb) {
+        av_free(buffer);
+        av_free(wf->sectors);
+        av_free(wf);
+    }
+    return pb;
+}
+
+/**
+ * Open file using filename
+ * @param[in]  buf       directory buffer
+ * @param      buf_size  directory buffer size
+ * @param[in]  filename
+ * @param      filename_size size of filename
+ * @return NULL on error
+ */
+static AVIOContext * wtvfile_open2(AVFormatContext *s, const uint8_t *buf, int buf_size, const uint8_t *filename, int filename_size)
+{
+    const uint8_t *buf_end = buf + buf_size;
+
+    while(buf + 48 <= buf_end) {
+        int dir_length, name_size, first_sector, depth;
+        uint64_t file_length;
+        const uint8_t *name;
+        if (ff_guidcmp(buf, ff_dir_entry_guid)) {
+            av_log(s, AV_LOG_ERROR, "unknown guid "FF_PRI_GUID", expected dir_entry_guid; "
+                   "remaining directory entries ignored\n", FF_ARG_GUID(buf));
+            break;
+        }
+        dir_length  = AV_RL16(buf + 16);
+        file_length = AV_RL64(buf + 24);
+        name_size   = 2 * AV_RL32(buf + 32);
+        if (buf + 48 + (int64_t)name_size > buf_end || name_size<0) {
+            av_log(s, AV_LOG_ERROR, "filename exceeds buffer size; remaining directory entries ignored\n");
+            break;
+        }
+        first_sector = AV_RL32(buf + 40 + name_size);
+        depth        = AV_RL32(buf + 44 + name_size);
+
+        /* compare file name; test optional null terminator */
+        name = buf + 40;
+        if (name_size >= filename_size &&
+            !memcmp(name, filename, filename_size) &&
+            (name_size < filename_size + 2 || !AV_RN16(name + filename_size)))
+            return wtvfile_open_sector(first_sector, file_length, depth, s);
+
+        buf += dir_length;
+    }
+    return 0;
+}
+
+#define wtvfile_open(s, buf, buf_size, filename) \
+    wtvfile_open2(s, buf, buf_size, filename, sizeof(filename))
+
+/**
+ * Close file opened with wtvfile_open_sector(), or wtv_open()
+ */
+static void wtvfile_close(AVIOContext *pb)
+{
+    WtvFile *wf = pb->opaque;
+    av_free(wf->sectors);
+    av_freep(&pb->opaque);
+    av_freep(&pb->buffer);
+    av_free(pb);
+}
+
+/*
+ *
+ * Main demuxer
+ *
+ */
+
+typedef struct {
+    int seen_data;
+} WtvStream;
+
+typedef struct {
+    AVIOContext *pb;       /** timeline file */
+    int64_t epoch;
+    int64_t pts;             /** pts for next data chunk */
+    int64_t last_valid_pts;  /** latest valid pts, used for interative seeking */
+
+    /* maintain private seek index, as the AVIndexEntry->pos is relative to the
+       start of the 'timeline' file, not the file system (AVFormatContext->pb) */
+    AVIndexEntry *index_entries;
+    int nb_index_entries;
+    unsigned int index_entries_allocated_size;
+} WtvContext;
+
+/* WTV GUIDs */
+static const ff_asf_guid EVENTID_SubtitleSpanningEvent =
+    {0x48,0xC0,0xCE,0x5D,0xB9,0xD0,0x63,0x41,0x87,0x2C,0x4F,0x32,0x22,0x3B,0xE8,0x8A};
+static const ff_asf_guid EVENTID_LanguageSpanningEvent =
+    {0x6D,0x66,0x92,0xE2,0x02,0x9C,0x8D,0x44,0xAA,0x8D,0x78,0x1A,0x93,0xFD,0xC3,0x95};
+static const ff_asf_guid EVENTID_AudioDescriptorSpanningEvent =
+    {0x1C,0xD4,0x7B,0x10,0xDA,0xA6,0x91,0x46,0x83,0x69,0x11,0xB2,0xCD,0xAA,0x28,0x8E};
+static const ff_asf_guid EVENTID_CtxADescriptorSpanningEvent =
+    {0xE6,0xA2,0xB4,0x3A,0x47,0x42,0x34,0x4B,0x89,0x6C,0x30,0xAF,0xA5,0xD2,0x1C,0x24};
+static const ff_asf_guid EVENTID_CSDescriptorSpanningEvent =
+    {0xD9,0x79,0xE7,0xEf,0xF0,0x97,0x86,0x47,0x80,0x0D,0x95,0xCF,0x50,0x5D,0xDC,0x66};
+static const ff_asf_guid EVENTID_DVBScramblingControlSpanningEvent =
+    {0xC4,0xE1,0xD4,0x4B,0xA1,0x90,0x09,0x41,0x82,0x36,0x27,0xF0,0x0E,0x7D,0xCC,0x5B};
+static const ff_asf_guid EVENTID_StreamIDSpanningEvent =
+    {0x68,0xAB,0xF1,0xCA,0x53,0xE1,0x41,0x4D,0xA6,0xB3,0xA7,0xC9,0x98,0xDB,0x75,0xEE};
+static const ff_asf_guid EVENTID_TeletextSpanningEvent =
+    {0x50,0xD9,0x99,0x95,0x33,0x5F,0x17,0x46,0xAF,0x7C,0x1E,0x54,0xB5,0x10,0xDA,0xA3};
+static const ff_asf_guid EVENTID_AudioTypeSpanningEvent =
+    {0xBE,0xBF,0x1C,0x50,0x49,0xB8,0xCE,0x42,0x9B,0xE9,0x3D,0xB8,0x69,0xFB,0x82,0xB3};
+
+/* Windows media GUIDs */
+
+/* Media types */
+static const ff_asf_guid mediasubtype_mpeg1payload =
+    {0x81,0xEB,0x36,0xE4,0x4F,0x52,0xCE,0x11,0x9F,0x53,0x00,0x20,0xAF,0x0B,0xA7,0x70};
+static const ff_asf_guid mediatype_mpeg2_sections =
+    {0x6C,0x17,0x5F,0x45,0x06,0x4B,0xCE,0x47,0x9A,0xEF,0x8C,0xAE,0xF7,0x3D,0xF7,0xB5};
+static const ff_asf_guid mediatype_mpeg2_pes =
+    {0x20,0x80,0x6D,0xE0,0x46,0xDB,0xCF,0x11,0xB4,0xD1,0x00,0x80,0x5F,0x6C,0xBB,0xEA};
+static const ff_asf_guid mediatype_mstvcaption =
+    {0x89,0x8A,0x8B,0xB8,0x49,0xB0,0x80,0x4C,0xAD,0xCF,0x58,0x98,0x98,0x5E,0x22,0xC1};
+
+/* Media subtypes */
+static const ff_asf_guid mediasubtype_dvb_subtitle =
+    {0xC3,0xCB,0xFF,0x34,0xB3,0xD5,0x71,0x41,0x90,0x02,0xD4,0xC6,0x03,0x01,0x69,0x7F};
+static const ff_asf_guid mediasubtype_teletext =
+    {0xE3,0x76,0x2A,0xF7,0x0A,0xEB,0xD0,0x11,0xAC,0xE4,0x00,0x00,0xC0,0xCC,0x16,0xBA};
+static const ff_asf_guid mediasubtype_dtvccdata =
+    {0xAA,0xDD,0x2A,0xF5,0xF0,0x36,0xF5,0x43,0x95,0xEA,0x6D,0x86,0x64,0x84,0x26,0x2A};
+static const ff_asf_guid mediasubtype_mpeg2_sections =
+    {0x79,0x85,0x9F,0x4A,0xF8,0x6B,0x92,0x43,0x8A,0x6D,0xD2,0xDD,0x09,0xFA,0x78,0x61};
+
+/* Formats */
+static const ff_asf_guid format_videoinfo2 =
+    {0xA0,0x76,0x2A,0xF7,0x0A,0xEB,0xD0,0x11,0xAC,0xE4,0x00,0x00,0xC0,0xCC,0x16,0xBA};
+
+static int read_probe(AVProbeData *p)
+{
+    return ff_guidcmp(p->buf, ff_wtv_guid) ? 0 : AVPROBE_SCORE_MAX;
+}
+
+/**
+ * Convert win32 FILETIME to ISO-8601 string
+ * @return <0 on error
+ */
+static int filetime_to_iso8601(char *buf, int buf_size, int64_t value)
+{
+    time_t t = (value / 10000000LL) - 11644473600LL;
+    struct tm *tm = gmtime(&t);
+    if (!tm)
+        return -1;
+    strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
+    return 0;
+}
+
+/**
+ * Convert crazy time (100ns since 1 Jan 0001) to ISO-8601 string
+ * @return <0 on error
+ */
+static int crazytime_to_iso8601(char *buf, int buf_size, int64_t value)
+{
+    time_t t = (value / 10000000LL) - 719162LL*86400LL;
+    struct tm *tm = gmtime(&t);
+    if (!tm)
+        return -1;
+    strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", gmtime(&t));
+    return 0;
+}
+
+/**
+ * Convert OLE DATE to ISO-8601 string
+ * @return <0 on error
+ */
+static int oledate_to_iso8601(char *buf, int buf_size, int64_t value)
+{
+    time_t t = (av_int2double(value) - 25569.0) * 86400;
+    struct tm *result= gmtime(&t);
+    if (!result)
+        return -1;
+    strftime(buf, buf_size, "%Y-%m-%d %H:%M:%S", result);
+    return 0;
+}
+
+static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length)
+{
+    char mime[1024];
+    char description[1024];
+    unsigned int filesize;
+    AVStream *st;
+    int64_t pos = avio_tell(pb);
+
+    avio_get_str16le(pb, INT_MAX, mime, sizeof(mime));
+    if (strcmp(mime, "image/jpeg"))
+        goto done;
+
+    avio_r8(pb);
+    avio_get_str16le(pb, INT_MAX, description, sizeof(description));
+    filesize = avio_rl32(pb);
+    if (!filesize)
+        goto done;
+
+    st = avformat_new_stream(s, NULL);
+    if (!st)
+        goto done;
+    av_dict_set(&st->metadata, "title", description, 0);
+    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)
+        goto done;
+    st->codec->extradata_size = filesize;
+    avio_read(pb, st->codec->extradata, filesize);
+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);
+    if (!buf)
+        return;
+
+    if (type == 0 && length == 4) {
+        snprintf(buf, buf_size, "%"PRIi32, avio_rl32(pb));
+    } else if (type == 1) {
+        avio_get_str16le(pb, length, buf, buf_size);
+        if (!strlen(buf)) {
+           av_free(buf);
+           return;
+        }
+    } else if (type == 3 && length == 4) {
+        strcpy(buf, avio_rl32(pb) ? "true" : "false");
+    } else if (type == 4 && length == 8) {
+        int64_t num = avio_rl64(pb);
+        if (!strcmp(key, "WM/EncodingTime") ||
+            !strcmp(key, "WM/MediaOriginalBroadcastDateTime")) {
+            if (filetime_to_iso8601(buf, buf_size, num) < 0) {
+                av_free(buf);
+                return;
+            }
+        } else if (!strcmp(key, "WM/WMRVEncodeTime") ||
+                   !strcmp(key, "WM/WMRVEndTime")) {
+            if (crazytime_to_iso8601(buf, buf_size, num) < 0) {
+                av_free(buf);
+                return;
+            }
+        } else if (!strcmp(key, "WM/WMRVExpirationDate")) {
+            if (oledate_to_iso8601(buf, buf_size, num) < 0 ) {
+                av_free(buf);
+                return;
+            }
+        } else if (!strcmp(key, "WM/WMRVBitrate"))
+            snprintf(buf, buf_size, "%f", av_int2double(num));
+        else
+            snprintf(buf, buf_size, "%"PRIi64, num);
+    } else if (type == 5 && length == 2) {
+        snprintf(buf, buf_size, "%"PRIi16, avio_rl16(pb));
+    } else if (type == 6 && length == 16) {
+        ff_asf_guid guid;
+        avio_read(pb, guid, 16);
+        snprintf(buf, buf_size, PRI_PRETTY_GUID, ARG_PRETTY_GUID(guid));
+    } else if (type == 2 && !strcmp(key, "WM/Picture")) {
+        get_attachment(s, pb, length);
+        av_freep(&buf);
+        return;
+    } else {
+        av_freep(&buf);
+        av_log(s, AV_LOG_WARNING, "unsupported metadata entry; key:%s, type:%d, length:0x%x\n", key, type, length);
+        avio_skip(pb, length);
+        return;
+    }
+
+    av_dict_set(&s->metadata, key, buf, 0);
+    av_freep(&buf);
+}
+
+/**
+ * Parse metadata entries
+ */
+static void parse_legacy_attrib(AVFormatContext *s, AVIOContext *pb)
+{
+    ff_asf_guid guid;
+    int length, type;
+    while(!url_feof(pb)) {
+        char key[1024];
+        ff_get_guid(pb, &guid);
+        type   = avio_rl32(pb);
+        length = avio_rl32(pb);
+        if (!length)
+            break;
+        if (ff_guidcmp(&guid, ff_metadata_guid)) {
+            av_log(s, AV_LOG_WARNING, "unknown guid "FF_PRI_GUID", expected metadata_guid; "
+                   "remaining metadata entries ignored\n", FF_ARG_GUID(guid));
+            break;
+        }
+        avio_get_str16le(pb, INT_MAX, key, sizeof(key));
+        get_tag(s, pb, key, type, length);
+    }
+
+    ff_metadata_conv(&s->metadata, NULL, ff_asf_metadata_conv);
+}
+
+/**
+ * parse VIDEOINFOHEADER2 structure
+ * @return bytes consumed
+ */
+static int parse_videoinfoheader2(AVFormatContext *s, AVStream *st)
+{
+    WtvContext *wtv = s->priv_data;
+    AVIOContext *pb = wtv->pb;
+
+    avio_skip(pb, 72);  // picture aspect ratio is unreliable
+    ff_get_bmp_header(pb, st, NULL);
+
+    return 72 + 40;
+}
+
+/**
+ * Parse MPEG1WAVEFORMATEX extradata structure
+ */
+static void parse_mpeg1waveformatex(AVStream *st)
+{
+    /* fwHeadLayer */
+    switch (AV_RL16(st->codec->extradata)) {
+    case 0x0001 : st->codec->codec_id = AV_CODEC_ID_MP1; break;
+    case 0x0002 : st->codec->codec_id = AV_CODEC_ID_MP2; break;
+    case 0x0004 : st->codec->codec_id = AV_CODEC_ID_MP3; break;
+    }
+
+    st->codec->bit_rate = AV_RL32(st->codec->extradata + 2); /* dwHeadBitrate */
+
+    /* dwHeadMode */
+    switch (AV_RL16(st->codec->extradata + 6)) {
+    case 1 : case 2 : case 4 : st->codec->channels = 2; break;
+    case 8 :                   st->codec->channels = 1; break;
+    }
+}
+
+/**
+ * Initialise stream
+ * @param st Stream to initialise, or NULL to create and initialise new stream
+ * @return NULL on error
+ */
+static AVStream * new_stream(AVFormatContext *s, AVStream *st, int sid, int codec_type)
+{
+    if (st) {
+        if (st->codec->extradata) {
+            av_freep(&st->codec->extradata);
+            st->codec->extradata_size = 0;
+        }
+    } else {
+        WtvStream *wst = av_mallocz(sizeof(WtvStream));
+        if (!wst)
+            return NULL;
+        st = avformat_new_stream(s, NULL);
+        if (!st) {
+            av_free(wst);
+            return NULL;
+        }
+        st->id = sid;
+        st->priv_data = wst;
+    }
+    st->codec->codec_type = codec_type;
+    st->need_parsing      = AVSTREAM_PARSE_FULL;
+    avpriv_set_pts_info(st, 64, 1, 10000000);
+    return st;
+}
+
+/**
+ * parse Media Type structure and populate stream
+ * @param st         Stream, or NULL to create new stream
+ * @param mediatype  Mediatype GUID
+ * @param subtype    Subtype GUID
+ * @param formattype Format GUID
+ * @param size       Size of format buffer
+ * @return NULL on error
+ */
+static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid,
+                                   ff_asf_guid mediatype, ff_asf_guid subtype,
+                                   ff_asf_guid formattype, int size)
+{
+    WtvContext *wtv = s->priv_data;
+    AVIOContext *pb = wtv->pb;
+    if (!ff_guidcmp(subtype, ff_mediasubtype_cpfilters_processed) &&
+        !ff_guidcmp(formattype, ff_format_cpfilters_processed)) {
+        ff_asf_guid actual_subtype;
+        ff_asf_guid actual_formattype;
+
+        if (size < 32) {
+            av_log(s, AV_LOG_WARNING, "format buffer size underflow\n");
+            avio_skip(pb, size);
+            return NULL;
+        }
+
+        avio_skip(pb, size - 32);
+        ff_get_guid(pb, &actual_subtype);
+        ff_get_guid(pb, &actual_formattype);
+        avio_seek(pb, -size, SEEK_CUR);
+
+        st = parse_media_type(s, st, sid, mediatype, actual_subtype, actual_formattype, size - 32);
+        avio_skip(pb, 32);
+        return st;
+    } else if (!ff_guidcmp(mediatype, ff_mediatype_audio)) {
+        st = new_stream(s, st, sid, AVMEDIA_TYPE_AUDIO);
+        if (!st)
+            return NULL;
+        if (!ff_guidcmp(formattype, ff_format_waveformatex)) {
+            int ret = ff_get_wav_header(pb, st->codec, size);
+            if (ret < 0)
+                return NULL;
+        } else {
+            if (ff_guidcmp(formattype, ff_format_none))
+                av_log(s, AV_LOG_WARNING, "unknown formattype:"FF_PRI_GUID"\n", FF_ARG_GUID(formattype));
+            avio_skip(pb, size);
+        }
+
+        if (!memcmp(subtype + 4, (const uint8_t[]){FF_MEDIASUBTYPE_BASE_GUID}, 12)) {
+            st->codec->codec_id = ff_wav_codec_get_id(AV_RL32(subtype), st->codec->bits_per_coded_sample);
+        } else if (!ff_guidcmp(subtype, mediasubtype_mpeg1payload)) {
+            if (st->codec->extradata && st->codec->extradata_size >= 22)
+                parse_mpeg1waveformatex(st);
+            else
+                av_log(s, AV_LOG_WARNING, "MPEG1WAVEFORMATEX underflow\n");
+        } else {
+            st->codec->codec_id = ff_codec_guid_get_id(ff_codec_wav_guids, subtype);
+            if (st->codec->codec_id == AV_CODEC_ID_NONE)
+                av_log(s, AV_LOG_WARNING, "unknown subtype:"FF_PRI_GUID"\n", FF_ARG_GUID(subtype));
+        }
+        return st;
+    } else if (!ff_guidcmp(mediatype, ff_mediatype_video)) {
+        st = new_stream(s, st, sid, AVMEDIA_TYPE_VIDEO);
+        if (!st)
+            return NULL;
+        if (!ff_guidcmp(formattype, format_videoinfo2)) {
+            int consumed = parse_videoinfoheader2(s, st);
+            avio_skip(pb, FFMAX(size - consumed, 0));
+        } else if (!ff_guidcmp(formattype, ff_format_mpeg2_video)) {
+            int consumed = parse_videoinfoheader2(s, st);
+            avio_skip(pb, FFMAX(size - consumed, 0));
+        } else {
+            if (ff_guidcmp(formattype, ff_format_none))
+                av_log(s, AV_LOG_WARNING, "unknown formattype:"FF_PRI_GUID"\n", FF_ARG_GUID(formattype));
+            avio_skip(pb, size);
+        }
+
+        if (!memcmp(subtype + 4, (const uint8_t[]){FF_MEDIASUBTYPE_BASE_GUID}, 12)) {
+            st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, AV_RL32(subtype));
+        } else {
+            st->codec->codec_id = ff_codec_guid_get_id(ff_video_guids, subtype);
+        }
+        if (st->codec->codec_id == AV_CODEC_ID_NONE)
+            av_log(s, AV_LOG_WARNING, "unknown subtype:"FF_PRI_GUID"\n", FF_ARG_GUID(subtype));
+        return st;
+    } else if (!ff_guidcmp(mediatype, mediatype_mpeg2_pes) &&
+               !ff_guidcmp(subtype, mediasubtype_dvb_subtitle)) {
+        st = new_stream(s, st, sid, AVMEDIA_TYPE_SUBTITLE);
+        if (!st)
+            return NULL;
+        if (ff_guidcmp(formattype, ff_format_none))
+            av_log(s, AV_LOG_WARNING, "unknown formattype:"FF_PRI_GUID"\n", FF_ARG_GUID(formattype));
+        avio_skip(pb, size);
+        st->codec->codec_id = AV_CODEC_ID_DVB_SUBTITLE;
+        return st;
+    } else if (!ff_guidcmp(mediatype, mediatype_mstvcaption) &&
+               (!ff_guidcmp(subtype, mediasubtype_teletext) || !ff_guidcmp(subtype, mediasubtype_dtvccdata))) {
+        st = new_stream(s, st, sid, AVMEDIA_TYPE_SUBTITLE);
+        if (!st)
+            return NULL;
+        if (ff_guidcmp(formattype, ff_format_none))
+            av_log(s, AV_LOG_WARNING, "unknown formattype:"FF_PRI_GUID"\n", FF_ARG_GUID(formattype));
+        avio_skip(pb, size);
+        st->codec->codec_id = !ff_guidcmp(subtype, mediasubtype_teletext) ? AV_CODEC_ID_DVB_TELETEXT : AV_CODEC_ID_EIA_608;
+        return st;
+    } else if (!ff_guidcmp(mediatype, mediatype_mpeg2_sections) &&
+               !ff_guidcmp(subtype, mediasubtype_mpeg2_sections)) {
+        if (ff_guidcmp(formattype, ff_format_none))
+            av_log(s, AV_LOG_WARNING, "unknown formattype:"FF_PRI_GUID"\n", FF_ARG_GUID(formattype));
+        avio_skip(pb, size);
+        return NULL;
+    }
+
+    av_log(s, AV_LOG_WARNING, "unknown media type, mediatype:"FF_PRI_GUID
+                              ", subtype:"FF_PRI_GUID", formattype:"FF_PRI_GUID"\n",
+                              FF_ARG_GUID(mediatype), FF_ARG_GUID(subtype), FF_ARG_GUID(formattype));
+    avio_skip(pb, size);
+    return NULL;
+}
+
+enum {
+    SEEK_TO_DATA = 0,
+    SEEK_TO_PTS,
+};
+
+/**
+ * Parse WTV chunks
+ * @param mode SEEK_TO_DATA or SEEK_TO_PTS
+ * @param seekts timestamp
+ * @param[out] len_ptr Length of data chunk
+ * @return stream index of data chunk, or <0 on error
+ */
+static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_ptr)
+{
+    WtvContext *wtv = s->priv_data;
+    AVIOContext *pb = wtv->pb;
+    while (!url_feof(pb)) {
+        ff_asf_guid g;
+        int len, sid, consumed;
+
+        ff_get_guid(pb, &g);
+        len = avio_rl32(pb);
+        if (len < 32)
+            break;
+        sid = avio_rl32(pb) & 0x7FFF;
+        avio_skip(pb, 8);
+        consumed = 32;
+
+        if (!ff_guidcmp(g, ff_stream_guid)) {
+            if (ff_find_stream_index(s, sid) < 0) {
+                ff_asf_guid mediatype, subtype, formattype;
+                int size;
+                avio_skip(pb, 28);
+                ff_get_guid(pb, &mediatype);
+                ff_get_guid(pb, &subtype);
+                avio_skip(pb, 12);
+                ff_get_guid(pb, &formattype);
+                size = avio_rl32(pb);
+                parse_media_type(s, 0, sid, mediatype, subtype, formattype, size);
+                consumed += 92 + size;
+            }
+        } else if (!ff_guidcmp(g, ff_stream2_guid)) {
+            int stream_index = ff_find_stream_index(s, sid);
+            if (stream_index >= 0 && !((WtvStream*)s->streams[stream_index]->priv_data)->seen_data) {
+                ff_asf_guid mediatype, subtype, formattype;
+                int size;
+                avio_skip(pb, 12);
+                ff_get_guid(pb, &mediatype);
+                ff_get_guid(pb, &subtype);
+                avio_skip(pb, 12);
+                ff_get_guid(pb, &formattype);
+                size = avio_rl32(pb);
+                parse_media_type(s, s->streams[stream_index], sid, mediatype, subtype, formattype, size);
+                consumed += 76 + size;
+            }
+        } else if (!ff_guidcmp(g, EVENTID_AudioDescriptorSpanningEvent) ||
+                   !ff_guidcmp(g, EVENTID_CtxADescriptorSpanningEvent) ||
+                   !ff_guidcmp(g, EVENTID_CSDescriptorSpanningEvent) ||
+                   !ff_guidcmp(g, EVENTID_StreamIDSpanningEvent) ||
+                   !ff_guidcmp(g, EVENTID_SubtitleSpanningEvent) ||
+                   !ff_guidcmp(g, EVENTID_TeletextSpanningEvent)) {
+            int stream_index = ff_find_stream_index(s, sid);
+            if (stream_index >= 0) {
+                AVStream *st = s->streams[stream_index];
+                uint8_t buf[258];
+                const uint8_t *pbuf = buf;
+                int buf_size;
+
+                avio_skip(pb, 8);
+                consumed += 8;
+                if (!ff_guidcmp(g, EVENTID_CtxADescriptorSpanningEvent) ||
+                    !ff_guidcmp(g, EVENTID_CSDescriptorSpanningEvent)) {
+                    avio_skip(pb, 6);
+                    consumed += 6;
+                }
+
+                buf_size = FFMIN(len - consumed, sizeof(buf));
+                avio_read(pb, buf, buf_size);
+                consumed += buf_size;
+                ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, NULL, 0, 0, NULL);
+            }
+        } else if (!ff_guidcmp(g, EVENTID_AudioTypeSpanningEvent)) {
+            int stream_index = ff_find_stream_index(s, sid);
+            if (stream_index >= 0) {
+                AVStream *st = s->streams[stream_index];
+                int audio_type;
+                avio_skip(pb, 8);
+                audio_type = avio_r8(pb);
+                if (audio_type == 2)
+                    st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED;
+                else if (audio_type == 3)
+                    st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;
+                consumed += 9;
+            }
+        } else if (!ff_guidcmp(g, EVENTID_DVBScramblingControlSpanningEvent)) {
+            int stream_index = ff_find_stream_index(s, sid);
+            if (stream_index >= 0) {
+                avio_skip(pb, 12);
+                if (avio_rl32(pb))
+                    av_log(s, AV_LOG_WARNING, "DVB scrambled stream detected (st:%d), decoding will likely fail\n", stream_index);
+                consumed += 16;
+            }
+        } else if (!ff_guidcmp(g, EVENTID_LanguageSpanningEvent)) {
+            int stream_index = ff_find_stream_index(s, sid);
+            if (stream_index >= 0) {
+                AVStream *st = s->streams[stream_index];
+                uint8_t language[4];
+                avio_skip(pb, 12);
+                avio_read(pb, language, 3);
+                if (language[0]) {
+                    language[3] = 0;
+                    av_dict_set(&st->metadata, "language", language, 0);
+                    if (!strcmp(language, "nar") || !strcmp(language, "NAR"))
+                        st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;
+                }
+                consumed += 15;
+            }
+        } else if (!ff_guidcmp(g, ff_timestamp_guid)) {
+            int stream_index = ff_find_stream_index(s, sid);
+            if (stream_index >= 0) {
+                avio_skip(pb, 8);
+                wtv->pts = avio_rl64(pb);
+                consumed += 16;
+                if (wtv->pts == -1)
+                    wtv->pts = AV_NOPTS_VALUE;
+                else {
+                    wtv->last_valid_pts = wtv->pts;
+                    if (wtv->epoch == AV_NOPTS_VALUE || wtv->pts < wtv->epoch)
+                        wtv->epoch = wtv->pts;
+                if (mode == SEEK_TO_PTS && wtv->pts >= seekts) {
+                    avio_skip(pb, WTV_PAD8(len) - consumed);
+                    return 0;
+                }
+                }
+            }
+        } else if (!ff_guidcmp(g, ff_data_guid)) {
+            int stream_index = ff_find_stream_index(s, sid);
+            if (mode == SEEK_TO_DATA && stream_index >= 0 && len > 32 && s->streams[stream_index]->priv_data) {
+                WtvStream *wst = s->streams[stream_index]->priv_data;
+                wst->seen_data = 1;
+                if (len_ptr) {
+                    *len_ptr = len;
+                }
+                return stream_index;
+            }
+        } else if (
+            !ff_guidcmp(g, /* DSATTRIB_CAPTURE_STREAMTIME */ (const ff_asf_guid){0x14,0x56,0x1A,0x0C,0xCD,0x30,0x40,0x4F,0xBC,0xBF,0xD0,0x3E,0x52,0x30,0x62,0x07}) ||
+            !ff_guidcmp(g, /* DSATTRIB_PicSampleSeq */ (const ff_asf_guid){0x02,0xAE,0x5B,0x2F,0x8F,0x7B,0x60,0x4F,0x82,0xD6,0xE4,0xEA,0x2F,0x1F,0x4C,0x99}) ||
+            !ff_guidcmp(g, /* DSATTRIB_TRANSPORT_PROPERTIES */ ff_DSATTRIB_TRANSPORT_PROPERTIES) ||
+            !ff_guidcmp(g, /* dvr_ms_vid_frame_rep_data */ (const ff_asf_guid){0xCC,0x32,0x64,0xDD,0x29,0xE2,0xDB,0x40,0x80,0xF6,0xD2,0x63,0x28,0xD2,0x76,0x1F}) ||
+            !ff_guidcmp(g, /* EVENTID_ChannelChangeSpanningEvent */ (const ff_asf_guid){0xE5,0xC5,0x67,0x90,0x5C,0x4C,0x05,0x42,0x86,0xC8,0x7A,0xFE,0x20,0xFE,0x1E,0xFA}) ||
+            !ff_guidcmp(g, /* EVENTID_ChannelInfoSpanningEvent */ (const ff_asf_guid){0x80,0x6D,0xF3,0x41,0x32,0x41,0xC2,0x4C,0xB1,0x21,0x01,0xA4,0x32,0x19,0xD8,0x1B}) ||
+            !ff_guidcmp(g, /* EVENTID_ChannelTypeSpanningEvent */ (const ff_asf_guid){0x51,0x1D,0xAB,0x72,0xD2,0x87,0x9B,0x48,0xBA,0x11,0x0E,0x08,0xDC,0x21,0x02,0x43}) ||
+            !ff_guidcmp(g, /* EVENTID_PIDListSpanningEvent */ (const ff_asf_guid){0x65,0x8F,0xFC,0x47,0xBB,0xE2,0x34,0x46,0x9C,0xEF,0xFD,0xBF,0xE6,0x26,0x1D,0x5C}) ||
+            !ff_guidcmp(g, /* EVENTID_SignalAndServiceStatusSpanningEvent */ (const ff_asf_guid){0xCB,0xC5,0x68,0x80,0x04,0x3C,0x2B,0x49,0xB4,0x7D,0x03,0x08,0x82,0x0D,0xCE,0x51}) ||
+            !ff_guidcmp(g, /* EVENTID_StreamTypeSpanningEvent */ (const ff_asf_guid){0xBC,0x2E,0xAF,0x82,0xA6,0x30,0x64,0x42,0xA8,0x0B,0xAD,0x2E,0x13,0x72,0xAC,0x60}) ||
+            !ff_guidcmp(g, (const ff_asf_guid){0x1E,0xBE,0xC3,0xC5,0x43,0x92,0xDC,0x11,0x85,0xE5,0x00,0x12,0x3F,0x6F,0x73,0xB9}) ||
+            !ff_guidcmp(g, (const ff_asf_guid){0x3B,0x86,0xA2,0xB1,0xEB,0x1E,0xC3,0x44,0x8C,0x88,0x1C,0xA3,0xFF,0xE3,0xE7,0x6A}) ||
+            !ff_guidcmp(g, (const ff_asf_guid){0x4E,0x7F,0x4C,0x5B,0xC4,0xD0,0x38,0x4B,0xA8,0x3E,0x21,0x7F,0x7B,0xBF,0x52,0xE7}) ||
+            !ff_guidcmp(g, (const ff_asf_guid){0x63,0x36,0xEB,0xFE,0xA1,0x7E,0xD9,0x11,0x83,0x08,0x00,0x07,0xE9,0x5E,0xAD,0x8D}) ||
+            !ff_guidcmp(g, (const ff_asf_guid){0x70,0xE9,0xF1,0xF8,0x89,0xA4,0x4C,0x4D,0x83,0x73,0xB8,0x12,0xE0,0xD5,0xF8,0x1E}) ||
+            !ff_guidcmp(g, (const ff_asf_guid){0x96,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D}) ||
+            !ff_guidcmp(g, (const ff_asf_guid){0x97,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D}) ||
+            !ff_guidcmp(g, (const ff_asf_guid){0xA1,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D}) ||
+            !ff_guidcmp(g, (const ff_asf_guid){0xF7,0x10,0x02,0xB9,0xEE,0x7C,0xED,0x4E,0xBD,0x7F,0x05,0x40,0x35,0x86,0x18,0xA1})) {
+            //ignore known guids
+        } else
+            av_log(s, AV_LOG_WARNING, "unsupported chunk:"FF_PRI_GUID"\n", FF_ARG_GUID(g));
+
+        avio_skip(pb, WTV_PAD8(len) - consumed);
+    }
+    return AVERROR_EOF;
+}
+
+static int read_header(AVFormatContext *s)
+{
+    WtvContext *wtv = s->priv_data;
+    int root_sector, root_size;
+    uint8_t root[WTV_SECTOR_SIZE];
+    AVIOContext *pb;
+    int64_t timeline_pos;
+    int ret;
+
+    wtv->epoch          =
+    wtv->pts            =
+    wtv->last_valid_pts = AV_NOPTS_VALUE;
+
+    /* read root directory sector */
+    avio_skip(s->pb, 0x30);
+    root_size = avio_rl32(s->pb);
+    if (root_size > sizeof(root)) {
+        av_log(s, AV_LOG_ERROR, "root directory size exceeds sector size\n");
+        return AVERROR_INVALIDDATA;
+    }
+    avio_skip(s->pb, 4);
+    root_sector = avio_rl32(s->pb);
+
+    avio_seek(s->pb, root_sector << WTV_SECTOR_BITS, SEEK_SET);
+    root_size = avio_read(s->pb, root, root_size);
+    if (root_size < 0)
+        return AVERROR_INVALIDDATA;
+
+    /* parse chunks up until first data chunk */
+    wtv->pb = wtvfile_open(s, root, root_size, ff_timeline_le16);
+    if (!wtv->pb) {
+        av_log(s, AV_LOG_ERROR, "timeline data missing\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    ret = parse_chunks(s, SEEK_TO_DATA, 0, 0);
+    if (ret < 0)
+        return ret;
+    avio_seek(wtv->pb, -32, SEEK_CUR);
+
+    timeline_pos = avio_tell(s->pb); // save before opening another file
+
+    /* read metadata */
+    pb = wtvfile_open(s, root, root_size, ff_table_0_entries_legacy_attrib_le16);
+    if (pb) {
+        parse_legacy_attrib(s, pb);
+        wtvfile_close(pb);
+    }
+
+    /* read seek index */
+    if (s->nb_streams) {
+        AVStream *st = s->streams[0];
+        pb = wtvfile_open(s, root, root_size, ff_table_0_entries_time_le16);
+        if (pb) {
+            while(1) {
+                uint64_t timestamp = avio_rl64(pb);
+                uint64_t frame_nb  = avio_rl64(pb);
+                if (url_feof(pb))
+                    break;
+                ff_add_index_entry(&wtv->index_entries, &wtv->nb_index_entries, &wtv->index_entries_allocated_size,
+                                   0, timestamp, frame_nb, 0, AVINDEX_KEYFRAME);
+            }
+            wtvfile_close(pb);
+
+            if (wtv->nb_index_entries) {
+                pb = wtvfile_open(s, root, root_size, ff_timeline_table_0_entries_Events_le16);
+                if (pb) {
+                    int i;
+                    while (1) {
+                        uint64_t frame_nb = avio_rl64(pb);
+                        uint64_t position = avio_rl64(pb);
+                        if (url_feof(pb))
+                            break;
+                        for (i = wtv->nb_index_entries - 1; i >= 0; i--) {
+                            AVIndexEntry *e = wtv->index_entries + i;
+                            if (frame_nb > e->size)
+                                break;
+                            if (position > e->pos)
+                                e->pos = position;
+                        }
+                    }
+                    wtvfile_close(pb);
+                    st->duration = wtv->index_entries[wtv->nb_index_entries - 1].timestamp;
+                }
+            }
+        }
+    }
+
+    avio_seek(s->pb, timeline_pos, SEEK_SET);
+    return 0;
+}
+
+static int read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    WtvContext *wtv = s->priv_data;
+    AVIOContext *pb = wtv->pb;
+    int stream_index, len, ret;
+
+    stream_index = parse_chunks(s, SEEK_TO_DATA, 0, &len);
+    if (stream_index < 0)
+        return stream_index;
+
+    ret = av_get_packet(pb, pkt, len - 32);
+    if (ret < 0)
+        return ret;
+    pkt->stream_index = stream_index;
+    pkt->pts          = wtv->pts;
+    avio_skip(pb, WTV_PAD8(len) - len);
+    return 0;
+}
+
+static int read_seek(AVFormatContext *s, int stream_index,
+                     int64_t ts, int flags)
+{
+    WtvContext *wtv = s->priv_data;
+    AVIOContext *pb = wtv->pb;
+    AVStream *st = s->streams[0];
+    int64_t ts_relative;
+    int i;
+
+    if ((flags & AVSEEK_FLAG_FRAME) || (flags & AVSEEK_FLAG_BYTE))
+        return AVERROR(ENOSYS);
+
+    /* timestamp adjustment is required because wtv->pts values are absolute,
+     * whereas AVIndexEntry->timestamp values are relative to epoch. */
+    ts_relative = ts;
+    if (wtv->epoch != AV_NOPTS_VALUE)
+        ts_relative -= wtv->epoch;
+
+    i = ff_index_search_timestamp(wtv->index_entries, wtv->nb_index_entries, ts_relative, flags);
+    if (i < 0) {
+        if (wtv->last_valid_pts == AV_NOPTS_VALUE || ts < wtv->last_valid_pts) {
+            if (avio_seek(pb, 0, SEEK_SET) < 0)
+                return -1;
+        } else if (st->duration != AV_NOPTS_VALUE && ts_relative > st->duration && wtv->nb_index_entries) {
+            if (avio_seek(pb, wtv->index_entries[wtv->nb_index_entries - 1].pos, SEEK_SET) < 0)
+                return -1;
+        }
+        if (parse_chunks(s, SEEK_TO_PTS, ts, 0) < 0)
+            return AVERROR(ERANGE);
+        return 0;
+    }
+    if (avio_seek(pb, wtv->index_entries[i].pos, SEEK_SET) < 0)
+        return -1;
+    wtv->pts = wtv->index_entries[i].timestamp;
+    if (wtv->epoch != AV_NOPTS_VALUE)
+        wtv->pts += wtv->epoch;
+    wtv->last_valid_pts = wtv->pts;
+    return 0;
+}
+
+static int read_close(AVFormatContext *s)
+{
+    WtvContext *wtv = s->priv_data;
+    av_freep(&wtv->index_entries);
+    wtvfile_close(wtv->pb);
+    return 0;
+}
+
+AVInputFormat ff_wtv_demuxer = {
+    .name           = "wtv",
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Television (WTV)"),
+    .priv_data_size = sizeof(WtvContext),
+    .read_probe     = read_probe,
+    .read_header    = read_header,
+    .read_packet    = read_packet,
+    .read_seek      = read_seek,
+    .read_close     = read_close,
+    .flags          = AVFMT_SHOW_IDS,
+};
diff --git a/libavformat/wtvenc.c b/libavformat/wtvenc.c
new file mode 100644
index 0000000..5bed51e
--- /dev/null
+++ b/libavformat/wtvenc.c
@@ -0,0 +1,723 @@
+/*
+ * Windows Television (WTV) muxer
+ * Copyright (c) 2011 Zhentan Feng <spyfeng at gmail dot com>
+ * Copyright (c) 2011 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
+ * Windows Television (WTV) demuxer
+ * @author Zhentan Feng <spyfeng at gmail dot com>
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "libavutil/avassert.h"
+#include "avformat.h"
+#include "internal.h"
+#include "wtv.h"
+#include "asf.h"
+
+#define WTV_BIGSECTOR_SIZE (1 << WTV_BIGSECTOR_BITS)
+#define INDEX_BASE 0x2
+#define MAX_NB_INDEX 10
+
+/* declare utf16le strings */
+#define _ , 0,
+static const uint8_t timeline_table_0_header_events[] =
+    {'t'_'i'_'m'_'e'_'l'_'i'_'n'_'e'_'.'_'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'h'_'e'_'a'_'d'_'e'_'r'_'.'_'E'_'v'_'e'_'n'_'t'_'s', 0};
+static const uint8_t table_0_header_legacy_attrib[] =
+    {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'h'_'e'_'a'_'d'_'e'_'r'_'.'_'l'_'e'_'g'_'a'_'c'_'y'_'_'_'a'_'t'_'t'_'r'_'i'_'b', 0};
+static const uint8_t table_0_redirector_legacy_attrib[] =
+    {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'r'_'e'_'d'_'i'_'r'_'e'_'c'_'t'_'o'_'r'_'.'_'l'_'e'_'g'_'a'_'c'_'y'_'_'_'a'_'t'_'t'_'r'_'i'_'b', 0};
+static const uint8_t table_0_header_time[] =
+    {'t'_'a'_'b'_'l'_'e'_'.'_'0'_'.'_'h'_'e'_'a'_'d'_'e'_'r'_'.'_'t'_'i'_'m'_'e', 0};
+static const uint8_t legacy_attrib[] =
+    {'l'_'e'_'g'_'a'_'c'_'y'_'_'_'a'_'t'_'t'_'r'_'i'_'b', 0};
+#undef _
+
+static const ff_asf_guid sub_wtv_guid =
+    {0x8C,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
+static const ff_asf_guid stream1_guid =
+    {0xA1,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
+static const ff_asf_guid sync_guid =
+    {0x97,0xC3,0xD2,0xC2,0x7E,0x9A,0xDA,0x11,0x8B,0xF7,0x00,0x07,0xE9,0x5E,0xAD,0x8D};
+static const ff_asf_guid index_guid =
+    {0x96,0xc3,0xd2,0xc2,0x7e,0x9a,0xda,0x11,0x8b,0xf7,0x00,0x07,0xe9,0x5e,0xad,0x8d};
+
+enum WtvFileIndex {
+    WTV_TIMELINE_TABLE_0_HEADER_EVENTS = 0,
+    WTV_TIMELINE_TABLE_0_ENTRIES_EVENTS,
+    WTV_TIMELINE,
+    WTV_TABLE_0_HEADER_LEGACY_ATTRIB,
+    WTV_TABLE_0_ENTRIES_LEGACY_ATTRIB,
+    WTV_TABLE_0_REDIRECTOR_LEGACY_ATTRIB,
+    WTV_TABLE_0_HEADER_TIME,
+    WTV_TABLE_0_ENTRIES_TIME,
+    WTV_FILES
+};
+
+typedef struct {
+    int64_t length;
+    const void *header;
+    int depth;
+    int first_sector;
+} WtvFile;
+
+typedef struct {
+    int64_t             pos;
+    int64_t             serial;
+    const ff_asf_guid * guid;
+    int                 stream_id;
+} WtvChunkEntry;
+
+typedef struct {
+    int64_t timeline_start_pos;
+    WtvFile file[WTV_FILES];
+    int64_t serial;         /** chunk serial number */
+    int64_t last_chunk_pos; /** last chunk position */
+    int64_t frame_nb;
+
+    WtvChunkEntry index[MAX_NB_INDEX];
+    int nb_index;
+    int first_video_flag;
+    int64_t sync_pos;
+} WtvContext;
+
+typedef int WTVHeaderWriteFunc(AVIOContext *pb);
+
+typedef struct {
+    const uint8_t *header;
+    int header_size;
+    WTVHeaderWriteFunc *write_header;
+} WTVRootEntryTable;
+
+static int write_pad(AVIOContext *pb, int size)
+{
+    for (; size > 0; size--)
+        avio_w8(pb, 0);
+    return 0;
+}
+
+static const ff_asf_guid *get_codec_guid(enum AVCodecID id, const AVCodecGuid *av_guid)
+{
+    int i;
+    for (i = 0; av_guid[i].id != AV_CODEC_ID_NONE; i++) {
+        if (id == av_guid[i].id)
+            return &(av_guid[i].guid);
+    }
+    return NULL;
+}
+
+/**
+ * Write chunk header. If header chunk (0x80000000 set) then add to list of header chunks
+ */
+static void write_chunk_header(AVFormatContext *s, const ff_asf_guid *guid, int length, int stream_id)
+{
+    WtvContext *wctx = s->priv_data;
+    AVIOContext *pb = s->pb;
+
+    wctx->last_chunk_pos = avio_tell(pb) - wctx->timeline_start_pos;
+    ff_put_guid(pb, guid);
+    avio_wl32(pb, 32 + length);
+    avio_wl32(pb, stream_id);
+    avio_wl64(pb, wctx->serial);
+
+    if ((stream_id & 0x80000000) && guid != &index_guid) {
+        WtvChunkEntry *t = wctx->index + wctx->nb_index;
+        av_assert0(wctx->nb_index < MAX_NB_INDEX);
+        t->pos       = wctx->last_chunk_pos;
+        t->serial    = wctx->serial;
+        t->guid      = guid;
+        t->stream_id = stream_id & 0x3FFFFFFF;
+        wctx->nb_index++;
+    }
+}
+
+static void write_chunk_header2(AVFormatContext *s, const ff_asf_guid *guid, int stream_id)
+{
+    WtvContext *wctx = s->priv_data;
+    AVIOContext *pb = s->pb;
+
+    int64_t last_chunk_pos = wctx->last_chunk_pos;
+    write_chunk_header(s, guid, 0, stream_id); // length updated later
+    avio_wl64(pb, last_chunk_pos);
+}
+
+static void finish_chunk_noindex(AVFormatContext *s)
+{
+    WtvContext *wctx = s->priv_data;
+    AVIOContext *pb = s->pb;
+
+    // update the chunk_len field and pad.
+    int64_t chunk_len = avio_tell(pb) - (wctx->last_chunk_pos + wctx->timeline_start_pos);
+    avio_seek(pb, -(chunk_len - 16), SEEK_CUR);
+    avio_wl32(pb, chunk_len);
+    avio_seek(pb, chunk_len - (16 + 4), SEEK_CUR);
+
+    write_pad(pb, WTV_PAD8(chunk_len) - chunk_len);
+    wctx->serial++;
+}
+
+static void write_index(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    WtvContext *wctx = s->priv_data;
+    int i;
+
+    write_chunk_header2(s, &index_guid, 0x80000000);
+    avio_wl32(pb, 0);
+    avio_wl32(pb, 0);
+
+    for (i = 0; i < wctx->nb_index; i++) {
+        WtvChunkEntry *t = wctx->index + i;
+        ff_put_guid(pb,  t->guid);
+        avio_wl64(pb, t->pos);
+        avio_wl32(pb, t->stream_id);
+        avio_wl32(pb, 0); // checksum?
+        avio_wl64(pb, t->serial);
+    }
+    wctx->nb_index = 0;   // reset index
+    finish_chunk_noindex(s);
+}
+
+static void finish_chunk(AVFormatContext *s)
+{
+    WtvContext *wctx = s->priv_data;
+    finish_chunk_noindex(s);
+    if (wctx->nb_index == MAX_NB_INDEX)
+        write_index(s);
+}
+
+static int write_stream_codec_info(AVFormatContext *s, AVStream *st)
+{
+    WtvContext *wctx = s->priv_data;
+    const ff_asf_guid *g, *media_type, *format_type;
+    AVIOContext *pb = s->pb;
+    int64_t  hdr_pos_start;
+    int hdr_size = 0;
+
+    if (st->codec->codec_type  == AVMEDIA_TYPE_VIDEO) {
+        g = get_codec_guid(st->codec->codec_id, ff_video_guids);
+        media_type = &ff_mediatype_video;
+        format_type = &ff_format_mpeg2_video;
+    } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+        g = get_codec_guid(st->codec->codec_id, ff_codec_wav_guids);
+        media_type = &ff_mediatype_audio;
+        format_type = &ff_format_waveformatex;
+    } else {
+        av_log(s, AV_LOG_ERROR, "unknown codec_type (0x%x)\n", st->codec->codec_type);
+        return -1;
+    }
+
+    if (g == NULL) {
+        av_log(s, AV_LOG_ERROR, "can't get video codec_id (0x%x) guid.\n", st->codec->codec_id);
+        return -1;
+    }
+
+    ff_put_guid(pb, media_type); // mediatype
+    ff_put_guid(pb, &ff_mediasubtype_cpfilters_processed); // subtype
+    write_pad(pb, 12);
+    ff_put_guid(pb,&ff_format_cpfilters_processed); // format type
+    avio_wl32(pb, 0); // size
+
+    hdr_pos_start = avio_tell(pb);
+    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+        if (wctx->first_video_flag) {
+            write_pad(pb, 216); //The size is sensitive.
+            wctx->first_video_flag = 0;
+        } else {
+            write_pad(pb, 72); // aspect ratio
+            ff_put_bmp_header(pb, st->codec, ff_codec_bmp_tags, 0);
+        }
+    } else {
+        ff_put_wav_header(pb, st->codec);
+    }
+    hdr_size = avio_tell(pb) - hdr_pos_start;
+
+    // seek back write hdr_size
+    avio_seek(pb, -(hdr_size + 4), SEEK_CUR);
+    avio_wl32(pb, hdr_size + 32);
+    avio_seek(pb, hdr_size, SEEK_CUR);
+    ff_put_guid(pb, g);           // actual_subtype
+    ff_put_guid(pb, format_type); // actual_formattype
+
+    return 0;
+}
+
+static int write_stream_codec(AVFormatContext *s, AVStream * st)
+{
+    AVIOContext *pb = s->pb;
+    int ret;
+    write_chunk_header2(s, &stream1_guid, 0x80000000 | 0x01);
+
+    avio_wl32(pb,  0x01);
+    write_pad(pb, 4);
+    write_pad(pb, 4);
+
+    ret = write_stream_codec_info(s, st);
+    if (ret < 0) {
+        av_log(s, AV_LOG_ERROR, "write stream codec info failed codec_type(0x%x)\n", st->codec->codec_type);
+        return -1;
+    }
+
+    finish_chunk(s);
+    return 0;
+}
+
+static void write_sync(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    WtvContext *wctx = s->priv_data;
+    int64_t last_chunk_pos = wctx->last_chunk_pos;
+    wctx->sync_pos = avio_tell(pb) - wctx->timeline_start_pos;
+
+    write_chunk_header(s, &sync_guid, 0x18, 0);
+    write_pad(pb, 24);
+
+    finish_chunk(s);
+
+    wctx->last_chunk_pos = last_chunk_pos;
+}
+
+static void write_DSATTRIB_TRANSPORT_PROPERTIES_init(AVFormatContext *s, int stream_index)
+{
+    AVIOContext *pb = s->pb;
+    write_chunk_header2(s, &ff_DSATTRIB_TRANSPORT_PROPERTIES, 0x80000000 | stream_index);
+    avio_wl64(pb, stream_index);
+    avio_wl64(pb, -1);
+    avio_wl64(pb, 0);
+    finish_chunk(s);
+}
+
+static int write_stream_data(AVFormatContext *s, AVStream *st, int flag)
+{
+    AVIOContext *pb = s->pb;
+    int ret;
+
+    if (!flag) {
+        write_chunk_header2(s, &ff_stream_guid, 0x80000000 | (st->index + INDEX_BASE));
+        avio_wl32(pb, 0x00000001);
+        avio_wl32(pb, st->index + INDEX_BASE); //stream_id
+        avio_wl32(pb, 0x00000001);
+        write_pad(pb, 8);
+    } else {
+        write_chunk_header2(s, &ff_stream2_guid, 0x80000000 | (st->index + INDEX_BASE));
+        write_pad(pb, 4);
+    }
+
+    ret = write_stream_codec_info(s, st);
+    if (ret < 0) {
+        av_log(s, AV_LOG_ERROR, "write stream codec info failed codec_type(0x%x)\n", st->codec->codec_type);
+        return -1;
+    }
+    finish_chunk(s);
+
+    avpriv_set_pts_info(st, 64, 1, 10000000);
+
+    return 0;
+}
+
+static int write_header(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    WtvContext *wctx = s->priv_data;
+    int i, pad, ret;
+    AVStream *st;
+
+    ff_put_guid(pb, &ff_wtv_guid);
+    ff_put_guid(pb, &sub_wtv_guid);
+
+    avio_wl32(pb, 0x01);
+    avio_wl32(pb, 0x02);
+    avio_wl32(pb, 1 << WTV_SECTOR_BITS);
+    avio_wl32(pb, 1 << WTV_BIGSECTOR_BITS);
+
+    //write initial root fields
+    avio_wl32(pb, 0); // root_size, update later
+    write_pad(pb, 4);
+    avio_wl32(pb, 0); // root_sector, update it later.
+
+    write_pad(pb, 32);
+    avio_wl32(pb, 0); // file ends pointer, update it later.
+
+    pad = (1 << WTV_SECTOR_BITS) - avio_tell(pb);
+    write_pad(pb, pad);
+    wctx->timeline_start_pos = avio_tell(pb);
+
+    wctx->serial = 1;
+    wctx->last_chunk_pos = -1;
+    wctx->first_video_flag = 1;
+
+    for (i = 0; i < s->nb_streams; i++) {
+        st = s->streams[i];
+        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);
+            return -1;
+        }
+        if (i + 1 < s->nb_streams) {
+            write_sync(s);
+        }
+    }
+
+    for (i = 0; i < s->nb_streams; i++) {
+        st = s->streams[i];
+        ret  = write_stream_data(s, st, 0);
+        if (ret < 0) {
+            av_log(s, AV_LOG_ERROR, "write stream data failed codec_type(0x%x)\n", st->codec->codec_type);
+            return -1;
+        }
+        ret = write_stream_data(s, st, 1);
+        if (ret < 0) {
+            av_log(s, AV_LOG_ERROR, "write stream2 data failed codec_type(0x%x)\n", st->codec->codec_type);
+            return -1;
+        }
+    }
+
+    for (i = 0; i < s->nb_streams; i++)
+        write_DSATTRIB_TRANSPORT_PROPERTIES_init(s, INDEX_BASE + i);
+
+    if (wctx->nb_index)
+        write_index(s);
+
+    return 0;
+}
+
+static void write_timestamp(AVFormatContext *s, AVPacket *pkt)
+{
+    AVIOContext *pb = s->pb;
+    WtvContext  *wctx = s->priv_data;
+    AVCodecContext *enc = s->streams[pkt->stream_index]->codec;
+    int flag = 0;
+    int64_t frame_number = 0;
+
+    if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
+        wctx->frame_nb++;
+        frame_number = wctx->frame_nb;
+        flag = pkt->flags & AV_PKT_FLAG_KEY ? 1 : 0;
+    }
+    write_chunk_header(s, &ff_timestamp_guid, 56, 0x40000000 | (INDEX_BASE + pkt->stream_index));
+    write_pad(pb, 8);
+    avio_wl64(pb, pkt->pts == AV_NOPTS_VALUE ? -1 : pkt->pts);
+    avio_wl64(pb, pkt->pts == AV_NOPTS_VALUE ? -1 : pkt->pts);
+
+    avio_wl64(pb, frame_number);
+    avio_wl64(pb, 0);
+    avio_wl64(pb, flag);
+    avio_wl64(pb, 0);
+}
+
+static int write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    AVIOContext *pb = s->pb;
+    WtvContext  *wctx = s->priv_data;
+
+    // write timestamp chunk
+    write_timestamp(s, pkt);
+
+    write_chunk_header(s, &ff_data_guid, pkt->size, INDEX_BASE + pkt->stream_index);
+    avio_write(pb, pkt->data, pkt->size);
+    write_pad(pb, WTV_PAD8(pkt->size) - pkt->size);
+
+    wctx->serial++;
+    avio_flush(pb);
+    return 0;
+}
+
+static int write_table0_header_envents(AVIOContext *pb)
+{
+    avio_wl32(pb, 0x10);
+    write_pad(pb, 84);
+    avio_wl64(pb, 0x32);
+    return 96;
+}
+
+static int write_table0_header_legacy_attrib(AVIOContext *pb)
+{
+    int pad = 0;
+    avio_wl32(pb, 0xFFFFFFFF);
+    write_pad(pb, 12);
+    avio_write(pb, legacy_attrib, sizeof(legacy_attrib));
+    pad = WTV_PAD8(sizeof(legacy_attrib)) - sizeof(legacy_attrib);
+    write_pad(pb, pad);
+    write_pad(pb, 32);
+    return 48 + WTV_PAD8(sizeof(legacy_attrib));
+}
+
+static int write_table0_header_time(AVIOContext *pb)
+{
+    avio_wl32(pb, 0x10);
+    write_pad(pb, 76);
+    avio_wl64(pb, 0x40);
+    return 88;
+}
+
+static const WTVRootEntryTable wtv_root_entry_table[] = {
+    { timeline_table_0_header_events,          sizeof(timeline_table_0_header_events),          write_table0_header_envents},
+    { ff_timeline_table_0_entries_Events_le16, sizeof(ff_timeline_table_0_entries_Events_le16), NULL},
+    { ff_timeline_le16,                        sizeof(ff_timeline_le16),                        NULL},
+    { table_0_header_legacy_attrib,            sizeof(table_0_header_legacy_attrib),            write_table0_header_legacy_attrib},
+    { ff_table_0_entries_legacy_attrib_le16,   sizeof(ff_table_0_entries_legacy_attrib_le16),   NULL},
+    { table_0_redirector_legacy_attrib,        sizeof(table_0_redirector_legacy_attrib),        NULL},
+    { table_0_header_time,                     sizeof(table_0_header_time),                     write_table0_header_time},
+    { ff_table_0_entries_time_le16,            sizeof(ff_table_0_entries_time_le16),            NULL},
+};
+
+static int write_root_table(AVFormatContext *s, int64_t sector_pos)
+{
+    AVIOContext *pb = s->pb;
+    WtvContext  *wctx = s->priv_data;
+    int size, pad;
+    int i;
+
+    const WTVRootEntryTable *h = wtv_root_entry_table;
+    for (i = 0; i < sizeof(wtv_root_entry_table)/sizeof(WTVRootEntryTable); i++, h++) {
+        WtvFile *w = &wctx->file[i];
+        int filename_padding = WTV_PAD8(h->header_size) - h->header_size;
+        WTVHeaderWriteFunc *write = h->write_header;
+        int len = 0;
+        int64_t len_pos;
+
+        ff_put_guid(pb, &ff_dir_entry_guid);
+        len_pos = avio_tell(pb);
+        avio_wl16(pb, 40 + h->header_size + filename_padding + 8); // maybe updated later
+        write_pad(pb, 6);
+        avio_wl64(pb, write ? 0 : w->length);// maybe update later
+        avio_wl32(pb, (h->header_size + filename_padding) >> 1);
+        write_pad(pb, 4);
+
+        avio_write(pb, h->header, h->header_size);
+        write_pad(pb, filename_padding);
+
+        if (write) {
+            len = write(pb);
+            // update length field
+            avio_seek(pb, len_pos, SEEK_SET);
+            avio_wl64(pb, 40 + h->header_size + filename_padding + len);
+            avio_wl64(pb, len |(1ULL<<62) | (1ULL<<60));
+            avio_seek(pb, 8 + h->header_size + filename_padding + len, SEEK_CUR);
+        } else {
+            avio_wl32(pb, w->first_sector);
+            avio_wl32(pb, w->depth);
+        }
+    }
+
+    // caculate root table size
+    size = avio_tell(pb) - sector_pos;
+    pad = WTV_SECTOR_SIZE- size;
+    write_pad(pb, pad);
+
+    return size;
+}
+
+static void write_fat(AVIOContext *pb, int start_sector, int nb_sectors, int shift)
+{
+    int i;
+    for (i = 0; i < nb_sectors; i++) {
+        avio_wl32(pb, start_sector + (i << shift));
+    }
+    // pad left sector pointer size
+    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)
+{
+    int64_t start_sector = start_pos >> WTV_SECTOR_BITS;
+    int shift = sector_bits - WTV_SECTOR_BITS;
+
+    int64_t fat = avio_tell(s->pb);
+    write_fat(s->pb, start_sector, nb_sectors, shift);
+
+    if (depth == 2) {
+        int64_t start_sector1 = fat >> WTV_SECTOR_BITS;
+        int nb_sectors1 = ((nb_sectors << 2) + WTV_SECTOR_SIZE - 1) / WTV_SECTOR_SIZE;
+        int64_t fat1 = avio_tell(s->pb);
+
+       write_fat(s->pb, start_sector1, nb_sectors1, 0);
+       return fat1;
+    }
+
+    return fat;
+}
+
+static void write_table_entries_events(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    WtvContext *wctx = s->priv_data;
+
+    //FIXME: output frame_nb, position pairs.
+    //We only set the first sync_chunk position here.
+    avio_wl64(pb, 0x2);   avio_wl64(pb, wctx->sync_pos);
+}
+
+static void write_tag(AVIOContext *pb, const char *key, const char *value)
+{
+    ff_put_guid(pb, &ff_metadata_guid);
+    avio_wl32(pb, 1);
+    avio_wl32(pb, strlen(value)*2 + 2);
+    avio_put_str16le(pb, key);
+    avio_put_str16le(pb, value);
+}
+
+static void write_table_entries_attrib(AVFormatContext *s)
+{
+    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);
+}
+
+static void write_table_redirector_legacy_attrib(AVFormatContext *s)
+{
+    AVIOContext *pb = s->pb;
+    AVDictionaryEntry *tag = 0;
+    int64_t pos = 0;
+
+    //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;
+    }
+}
+
+/**
+ * Pad the remainder of a file
+ * Write out fat table
+ * @return <0 on error
+ */
+static int finish_file(AVFormatContext *s, enum WtvFileIndex index, int64_t start_pos)
+{
+    WtvContext *wctx = s->priv_data;
+    AVIOContext *pb = s->pb;
+    WtvFile *w = &wctx->file[index];
+    int64_t end_pos = avio_tell(pb);
+    int sector_bits, nb_sectors, pad;
+
+    av_assert0(index < WTV_FILES);
+
+    w->length = (end_pos - start_pos);
+
+    // determine optimal fat table depth, sector_bits, nb_sectors
+    if (w->length <= WTV_SECTOR_SIZE) {
+        w->depth = 0;
+        sector_bits = WTV_SECTOR_BITS;
+    } else if (w->length <= (WTV_SECTOR_SIZE / 4) * WTV_SECTOR_SIZE) {
+        w->depth = 1;
+        sector_bits = WTV_SECTOR_BITS;
+    } else if (w->length <= (WTV_SECTOR_SIZE / 4) * WTV_BIGSECTOR_SIZE) {
+        w->depth = 1;
+        sector_bits = WTV_BIGSECTOR_BITS;
+    } else if (w->length <= (int64_t)(WTV_SECTOR_SIZE / 4) * (WTV_SECTOR_SIZE / 4) * WTV_SECTOR_SIZE) {
+        w->depth = 2;
+        sector_bits = WTV_SECTOR_BITS;
+    } else if (w->length <= (int64_t)(WTV_SECTOR_SIZE / 4) * (WTV_SECTOR_SIZE / 4) * WTV_BIGSECTOR_SIZE) {
+        w->depth = 2;
+        sector_bits = WTV_BIGSECTOR_BITS;
+    } else {
+        av_log(s, AV_LOG_ERROR, "unsupported file allocation table depth (%"PRIi64" bytes)\n", w->length);
+        return -1;
+    }
+
+    // determine the nb_sectors
+    nb_sectors = (int)(w->length >> sector_bits);
+
+    // pad sector of timeline
+    pad = (1 << sector_bits) - (w->length % (1 << sector_bits));
+    if (pad) {
+        nb_sectors++;
+        write_pad(pb, pad);
+    }
+
+    //write fat table
+    if (w->depth > 0) {
+        w->first_sector = write_fat_sector(s, start_pos, nb_sectors, sector_bits, w->depth);
+    } else {
+        w->first_sector = start_pos;
+    }
+    w->first_sector >>= WTV_SECTOR_BITS;
+
+    w->length |= 1ULL<<60;
+    if (sector_bits == WTV_SECTOR_BITS)
+        w->length |= 1ULL<<63;
+
+    return 0;
+}
+
+static int write_trailer(AVFormatContext *s)
+{
+    WtvContext *wctx = s->priv_data;
+    AVIOContext *pb = s->pb;
+    int root_size;
+    int64_t sector_pos;
+    int64_t start_pos, file_end_pos;
+
+    if (finish_file(s, WTV_TIMELINE, wctx->timeline_start_pos) < 0)
+        return -1;
+
+    start_pos = avio_tell(pb);
+    write_table_entries_events(s);
+    if (finish_file(s, WTV_TIMELINE_TABLE_0_ENTRIES_EVENTS, start_pos) < 0)
+        return -1;
+
+    start_pos = avio_tell(pb);
+    write_table_entries_attrib(s);
+    if (finish_file(s, WTV_TABLE_0_ENTRIES_LEGACY_ATTRIB, start_pos) < 0)
+        return -1;
+
+    start_pos = avio_tell(pb);
+    write_table_redirector_legacy_attrib(s);
+    if (finish_file(s, WTV_TABLE_0_REDIRECTOR_LEGACY_ATTRIB, start_pos) < 0)
+        return -1;
+
+    start_pos = avio_tell(pb);
+    //FIXME: output timestamp, frame_nb pairs here.
+    if (finish_file(s, WTV_TABLE_0_ENTRIES_TIME, start_pos) < 0)
+        return -1;
+
+    // write root table
+    sector_pos = avio_tell(pb);
+    root_size = write_root_table(s, sector_pos);
+
+    file_end_pos = avio_tell(pb);
+    // update root value
+    avio_seek(pb, 0x30, SEEK_SET);
+    avio_wl32(pb, root_size);
+    avio_seek(pb, 4, SEEK_CUR);
+    avio_wl32(pb, sector_pos >> WTV_SECTOR_BITS);
+    avio_seek(pb, 0x5c, SEEK_SET);
+    avio_wl32(pb, file_end_pos >> WTV_SECTOR_BITS);
+
+    avio_flush(pb);
+    return 0;
+}
+
+AVOutputFormat ff_wtv_muxer = {
+    .name           = "wtv",
+    .long_name      = NULL_IF_CONFIG_SMALL("Windows Television (WTV)"),
+    .extensions     = "wtv",
+    .priv_data_size = sizeof(WtvContext),
+    .audio_codec    = AV_CODEC_ID_AC3,
+    .video_codec    = AV_CODEC_ID_MPEG2VIDEO,
+    .write_header   = write_header,
+    .write_packet   = write_packet,
+    .write_trailer  = write_trailer,
+    .codec_tag      = (const AVCodecTag* const []){ ff_codec_bmp_tags,
+                                                    ff_codec_wav_tags, 0 },
+};
diff --git a/libavformat/wv.c b/libavformat/wv.c
index a2ae5a4..50e5e53 100644
--- a/libavformat/wv.c
+++ b/libavformat/wv.c
@@ -2,20 +2,20 @@
  * WavPack demuxer
  * Copyright (c) 2006,2011 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -276,7 +276,7 @@
     int64_t pos;
     uint32_t block_samples;
 
-    if (s->pb->eof_reached)
+    if (url_feof(s->pb))
         return AVERROR_EOF;
     if (wc->block_parsed) {
         if ((ret = wv_read_block_header(s, s->pb, 0)) < 0)
diff --git a/libavformat/wvenc.c b/libavformat/wvenc.c
new file mode 100644
index 0000000..d225ed4
--- /dev/null
+++ b/libavformat/wvenc.c
@@ -0,0 +1,100 @@
+/*
+ * WavPack 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 "avformat.h"
+#include "internal.h"
+#include "avio_internal.h"
+#include "apetag.h"
+
+typedef struct{
+    uint32_t duration;
+    int off;
+} WVMuxContext;
+
+static int write_header(AVFormatContext *s)
+{
+    WVMuxContext *wc = s->priv_data;
+    AVCodecContext *codec = s->streams[0]->codec;
+
+    if (s->nb_streams > 1) {
+        av_log(s, AV_LOG_ERROR, "only one stream is supported\n");
+        return AVERROR(EINVAL);
+    }
+    if (codec->codec_id != AV_CODEC_ID_WAVPACK) {
+        av_log(s, AV_LOG_ERROR, "unsupported codec\n");
+        return AVERROR(EINVAL);
+    }
+    if (codec->extradata_size > 0) {
+        av_log_missing_feature(s, "remuxing from matroska container", 0);
+        return AVERROR_PATCHWELCOME;
+    }
+    wc->off = codec->channels > 2 ? 4 : 0;
+    avpriv_set_pts_info(s->streams[0], 64, 1, codec->sample_rate);
+
+    return 0;
+}
+
+static int write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+    WVMuxContext *wc = s->priv_data;
+    AVIOContext *pb = s->pb;
+
+    wc->duration += pkt->duration;
+    ffio_wfourcc(pb, "wvpk");
+    avio_wl32(pb, pkt->size + 12 + wc->off);
+    avio_wl16(pb, 0x410);
+    avio_w8(pb, 0);
+    avio_w8(pb, 0);
+    avio_wl32(pb, -1);
+    avio_wl32(pb, pkt->pts);
+    avio_write(s->pb, pkt->data, pkt->size);
+    avio_flush(s->pb);
+
+    return 0;
+}
+
+static int write_trailer(AVFormatContext *s)
+{
+    WVMuxContext *wc = s->priv_data;
+    AVIOContext *pb = s->pb;
+
+    ff_ape_write(s);
+
+    if (pb->seekable) {
+        avio_seek(pb, 12, SEEK_SET);
+        avio_wl32(pb, wc->duration);
+        avio_flush(pb);
+    }
+
+    return 0;
+}
+
+AVOutputFormat ff_wv_muxer = {
+    .name              = "wv",
+    .long_name         = NULL_IF_CONFIG_SMALL("WavPack"),
+    .priv_data_size    = sizeof(WVMuxContext),
+    .extensions        = "wv",
+    .audio_codec       = AV_CODEC_ID_WAVPACK,
+    .video_codec       = AV_CODEC_ID_NONE,
+    .write_header      = write_header,
+    .write_packet      = write_packet,
+    .write_trailer     = write_trailer,
+};
diff --git a/libavformat/xa.c b/libavformat/xa.c
index 02d66c5..e3d36e6 100644
--- a/libavformat/xa.c
+++ b/libavformat/xa.c
@@ -2,20 +2,20 @@
  * Maxis XA (.xa) File Demuxer
  * Copyright (c) 2008 Robert Marston
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavformat/xmv.c b/libavformat/xmv.c
index 5041c57..f250aad 100644
--- a/libavformat/xmv.c
+++ b/libavformat/xmv.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2011 Sven Hesse <drmccoy@drmccoy.de>
  * Copyright (c) 2011 Matthew Hoops <clone2727@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -32,81 +32,79 @@
 #include "avformat.h"
 #include "internal.h"
 #include "riff.h"
+#include "libavutil/avassert.h"
 
+/** The min size of an XMV header. */
 #define XMV_MIN_HEADER_SIZE 36
 
+/** Audio flag: ADPCM'd 5.1 stream, front left / right channels */
 #define XMV_AUDIO_ADPCM51_FRONTLEFTRIGHT 1
+/** Audio flag: ADPCM'd 5.1 stream, front center / low frequency channels */
 #define XMV_AUDIO_ADPCM51_FRONTCENTERLOW 2
+/** Audio flag: ADPCM'd 5.1 stream, rear left / right channels */
 #define XMV_AUDIO_ADPCM51_REARLEFTRIGHT  4
 
+/** Audio flag: Any of the ADPCM'd 5.1 stream flags. */
 #define XMV_AUDIO_ADPCM51 (XMV_AUDIO_ADPCM51_FRONTLEFTRIGHT | \
                            XMV_AUDIO_ADPCM51_FRONTCENTERLOW | \
                            XMV_AUDIO_ADPCM51_REARLEFTRIGHT)
 
-typedef struct XMVAudioTrack {
-    uint16_t compression;
-    uint16_t channels;
-    uint32_t sample_rate;
-    uint16_t bits_per_sample;
-    uint32_t bit_rate;
-    uint16_t flags;
-    uint16_t block_align;
-    uint16_t block_samples;
-
-    enum AVCodecID codec_id;
-} XMVAudioTrack;
-
+/** A video packet with an XMV file. */
 typedef struct XMVVideoPacket {
-    /* The decoder stream index for this video packet. */
-    int stream_index;
+    int stream_index; ///< The decoder stream index for this video packet.
 
-    uint32_t data_size;
-    uint32_t data_offset;
+    uint32_t data_size;   ///< The size of the remaining video data.
+    uint64_t data_offset; ///< The offset of the video data within the file.
 
-    uint32_t current_frame;
-    uint32_t frame_count;
+    uint32_t current_frame; ///< The current frame within this video packet.
+    uint32_t frame_count;   ///< The amount of frames within this video packet.
 
-    /* Does the video packet contain extra data? */
-    int has_extradata;
+    int     has_extradata; ///< Does the video packet contain extra data?
+    uint8_t extradata[4];  ///< The extra data
 
-    /* Extra data */
-    uint8_t extradata[4];
-
-    int64_t last_pts;
-    int64_t pts;
+    int64_t last_pts; ///< PTS of the last video frame.
+    int64_t pts;      ///< PTS of the most current video frame.
 } XMVVideoPacket;
 
+/** An audio packet with an XMV file. */
 typedef struct XMVAudioPacket {
-    /* The decoder stream index for this audio packet. */
-    int stream_index;
+    int stream_index; ///< The decoder stream index for this audio packet.
 
-    /* The audio track this packet encodes. */
-    XMVAudioTrack *track;
+    /* Stream format properties. */
+    uint16_t compression;     ///< The type of compression.
+    uint16_t channels;        ///< Number of channels.
+    uint32_t sample_rate;     ///< Sampling rate.
+    uint16_t bits_per_sample; ///< Bits per compressed sample.
+    uint32_t bit_rate;        ///< Bits of compressed data per second.
+    uint16_t flags;           ///< Flags
+    uint16_t block_align;     ///< Bytes per compressed block.
+    uint16_t block_samples;   ///< Decompressed samples per compressed block.
 
-    uint32_t data_size;
-    uint32_t data_offset;
+    enum AVCodecID codec_id; ///< The codec ID of the compression scheme.
 
-    uint32_t frame_size;
+    uint32_t data_size;   ///< The size of the remaining audio data.
+    uint64_t data_offset; ///< The offset of the audio data within the file.
 
-    uint32_t block_count;
+    uint32_t frame_size; ///< Number of bytes to put into an audio frame.
+
+    uint64_t block_count; ///< Running counter of decompressed audio block.
 } XMVAudioPacket;
 
+/** Context for demuxing an XMV file. */
 typedef struct XMVDemuxContext {
-    uint16_t audio_track_count;
+    uint16_t audio_track_count; ///< Number of audio track in this file.
 
-    XMVAudioTrack *audio_tracks;
+    uint32_t this_packet_size; ///< Size of the current packet.
+    uint32_t next_packet_size; ///< Size of the next packet.
 
-    uint32_t this_packet_size;
-    uint32_t next_packet_size;
+    uint64_t this_packet_offset; ///< Offset of the current packet.
+    uint64_t next_packet_offset; ///< Offset of the next packet.
 
-    uint32_t this_packet_offset;
-    uint32_t next_packet_offset;
+    uint16_t current_stream; ///< The index of the stream currently handling.
+    uint16_t stream_count;   ///< The number of streams in this file.
 
-    uint16_t current_stream;
-    uint16_t stream_count;
-
-    XMVVideoPacket  video;
-    XMVAudioPacket *audio;
+    XMVVideoPacket  video; ///< The video packet contained in each packet.
+    XMVAudioPacket *audio; ///< The audio packets contained in each packet.
 } XMVDemuxContext;
 
 static int xmv_probe(AVProbeData *p)
@@ -172,34 +170,33 @@
 
     avio_skip(pb, 2); /* Unknown (padding?) */
 
-    xmv->audio_tracks = av_malloc(xmv->audio_track_count * sizeof(XMVAudioTrack));
-    if (!xmv->audio_tracks)
-        return AVERROR(ENOMEM);
-
     xmv->audio = av_malloc(xmv->audio_track_count * sizeof(XMVAudioPacket));
     if (!xmv->audio)
         return AVERROR(ENOMEM);
 
     for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) {
-        XMVAudioTrack  *track  = &xmv->audio_tracks[audio_track];
-        XMVAudioPacket *packet = &xmv->audio       [audio_track];
+        XMVAudioPacket *packet = &xmv->audio[audio_track];
         AVStream *ast = NULL;
 
-        track->compression     = avio_rl16(pb);
-        track->channels        = avio_rl16(pb);
-        track->sample_rate     = avio_rl32(pb);
-        track->bits_per_sample = avio_rl16(pb);
-        track->flags           = avio_rl16(pb);
+        packet->compression     = avio_rl16(pb);
+        packet->channels        = avio_rl16(pb);
+        packet->sample_rate     = avio_rl32(pb);
+        packet->bits_per_sample = avio_rl16(pb);
+        packet->flags           = avio_rl16(pb);
 
-        track->bit_rate      = track->bits_per_sample *
-                               track->sample_rate *
-                               track->channels;
-        track->block_align   = 36 * track->channels;
-        track->block_samples = 64;
-        track->codec_id      = ff_wav_codec_get_id(track->compression,
-                                                   track->bits_per_sample);
+        if (!packet->channels) {
+            av_log(s, AV_LOG_ERROR, "0 channels\n");
+            return AVERROR(EINVAL);
+        }
 
-        packet->track        = track;
+        packet->bit_rate      = packet->bits_per_sample *
+                                packet->sample_rate *
+                                packet->channels;
+        packet->block_align   = 36 * packet->channels;
+        packet->block_samples = 64;
+        packet->codec_id      = ff_wav_codec_get_id(packet->compression,
+                                                    packet->bits_per_sample);
+
         packet->stream_index = -1;
 
         packet->frame_size  = 0;
@@ -207,24 +204,24 @@
 
         /* TODO: ADPCM'd 5.1 sound is encoded in three separate streams.
          *       Those need to be interleaved to a proper 5.1 stream. */
-        if (track->flags & XMV_AUDIO_ADPCM51)
+        if (packet->flags & XMV_AUDIO_ADPCM51)
             av_log(s, AV_LOG_WARNING, "Unsupported 5.1 ADPCM audio stream "
-                                      "(0x%04X)\n", track->flags);
+                                      "(0x%04X)\n", packet->flags);
 
         ast = avformat_new_stream(s, NULL);
         if (!ast)
             return AVERROR(ENOMEM);
 
         ast->codec->codec_type            = AVMEDIA_TYPE_AUDIO;
-        ast->codec->codec_id              = track->codec_id;
-        ast->codec->codec_tag             = track->compression;
-        ast->codec->channels              = track->channels;
-        ast->codec->sample_rate           = track->sample_rate;
-        ast->codec->bits_per_coded_sample = track->bits_per_sample;
-        ast->codec->bit_rate              = track->bit_rate;
-        ast->codec->block_align           = 36 * track->channels;
+        ast->codec->codec_id              = packet->codec_id;
+        ast->codec->codec_tag             = packet->compression;
+        ast->codec->channels              = packet->channels;
+        ast->codec->sample_rate           = packet->sample_rate;
+        ast->codec->bits_per_coded_sample = packet->bits_per_sample;
+        ast->codec->bit_rate              = packet->bit_rate;
+        ast->codec->block_align           = 36 * packet->channels;
 
-        avpriv_set_pts_info(ast, 32, track->block_samples, track->sample_rate);
+        avpriv_set_pts_info(ast, 32, packet->block_samples, packet->sample_rate);
 
         packet->stream_index = ast->index;
 
@@ -232,7 +229,7 @@
     }
 
 
-    /** Initialize the packet context */
+    /* Initialize the packet context */
 
     xmv->next_packet_offset = avio_tell(pb);
     xmv->next_packet_size   = this_packet_size - xmv->next_packet_offset;
@@ -277,7 +274,7 @@
 
     uint8_t  data[8];
     uint16_t audio_track;
-    uint32_t data_offset;
+    uint64_t data_offset;
 
     /* Next packet size */
     xmv->next_packet_size = avio_rl32(pb);
@@ -298,7 +295,7 @@
      * short for every audio track. But as playing around with XMV files with
      * ADPCM audio showed, taking the extra 4 bytes from the audio data gives
      * you either completely distorted audio or click (when skipping the
-     * remaining 68 bytes of the ADPCM block). Substracting 4 bytes for every
+     * remaining 68 bytes of the ADPCM block). Subtracting 4 bytes for every
      * audio track from the video data works at least for the audio. Probably
      * some alignment thing?
      * The video data has (always?) lots of padding, so it should work out...
@@ -308,7 +305,7 @@
     xmv->current_stream = 0;
     if (!xmv->video.frame_count) {
         xmv->video.frame_count = 1;
-        xmv->current_stream    = 1;
+        xmv->current_stream    = xmv->stream_count > 1;
     }
 
     /* Packet audio header */
@@ -328,9 +325,9 @@
              */
             packet->data_size = xmv->audio[audio_track - 1].data_size;
 
-        /** Carve up the audio data in frame_count slices */
+        /* Carve up the audio data in frame_count slices */
         packet->frame_size  = packet->data_size  / xmv->video.frame_count;
-        packet->frame_size -= packet->frame_size % packet->track->block_align;
+        packet->frame_size -= packet->frame_size % packet->block_align;
     }
 
     /* Packet data offsets */
@@ -358,7 +355,7 @@
             if (xmv->video.stream_index >= 0) {
                 AVStream *vst = s->streams[xmv->video.stream_index];
 
-                assert(xmv->video.stream_index < s->nb_streams);
+                av_assert0(xmv->video.stream_index < s->nb_streams);
 
                 if (vst->codec->extradata_size < 4) {
                     av_free(vst->codec->extradata);
@@ -434,7 +431,7 @@
 
     /* Calculate the PTS */
 
-    block_count = data_size / audio->track->block_align;
+    block_count = data_size / audio->block_align;
 
     pkt->duration = block_count;
     pkt->pts      = audio->block_count;
@@ -459,7 +456,7 @@
     int result;
     uint32_t frame_header;
     uint32_t frame_size, frame_timestamp;
-    uint32_t i;
+    uint8_t *data, *end;
 
     /* Seek to it */
     if (avio_seek(pb, video->data_offset, SEEK_SET) != video->data_offset)
@@ -474,17 +471,17 @@
     if ((frame_size + 4) > video->data_size)
         return AVERROR(EIO);
 
-    /* Create the packet */
-    result = av_new_packet(pkt, frame_size);
-    if (result)
+    /* Get the packet data */
+    result = av_get_packet(pb, pkt, frame_size);
+    if (result != frame_size)
         return result;
 
     /* Contrary to normal WMV2 video, the bit stream in XMV's
      * WMV2 is little-endian.
      * TODO: This manual swap is of course suboptimal.
      */
-    for (i = 0; i < frame_size; i += 4)
-        AV_WB32(pkt->data + i, avio_rl32(pb));
+    for (data = pkt->data, end = pkt->data + frame_size; data < end; data += 4)
+        AV_WB32(data, AV_RL32(data));
 
     pkt->stream_index = video->stream_index;
 
@@ -550,8 +547,7 @@
 {
     XMVDemuxContext *xmv = s->priv_data;
 
-    av_free(xmv->audio);
-    av_free(xmv->audio_tracks);
+    av_freep(&xmv->audio);
 
     return 0;
 }
diff --git a/libavformat/xwma.c b/libavformat/xwma.c
index 46ca0b8..04c3629 100644
--- a/libavformat/xwma.c
+++ b/libavformat/xwma.c
@@ -2,20 +2,20 @@
  * xWMA demuxer
  * Copyright (c) 2011 Max Horn
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -42,7 +42,7 @@
 
 static int xwma_read_header(AVFormatContext *s)
 {
-    int64_t size, av_uninit(data_size);
+    int64_t size;
     int ret;
     uint32_t dpds_table_size = 0;
     uint32_t *dpds_table = 0;
diff --git a/libavformat/yop.c b/libavformat/yop.c
index 51d088b..2d89c6e 100644
--- a/libavformat/yop.c
+++ b/libavformat/yop.c
@@ -5,20 +5,20 @@
  * derived from the code by
  * Copyright (C) 2009 Thomas P. Higdon <thomas.p.higdon@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -38,10 +38,15 @@
 static int yop_probe(AVProbeData *probe_packet)
 {
     if (AV_RB16(probe_packet->buf) == AV_RB16("YO")  &&
+        probe_packet->buf[2]<10                      &&
+        probe_packet->buf[3]<10                      &&
         probe_packet->buf[6]                         &&
         probe_packet->buf[7]                         &&
         !(probe_packet->buf[8] & 1)                  &&
-        !(probe_packet->buf[10] & 1))
+        !(probe_packet->buf[10] & 1)                 &&
+        AV_RL16(probe_packet->buf + 12 + 6) >= 920    &&
+        AV_RL16(probe_packet->buf + 12 + 6) < probe_packet->buf[12] * 3 + 4 + probe_packet->buf[7] * 2048
+    )
         return AVPROBE_SCORE_MAX * 3 / 4;
 
     return 0;
@@ -59,6 +64,8 @@
 
     audio_stream = avformat_new_stream(s, NULL);
     video_stream = avformat_new_stream(s, NULL);
+    if (!audio_stream || !video_stream)
+        return AVERROR(ENOMEM);
 
     // Extra data that will be passed to the decoder
     video_stream->codec->extradata_size = 8;
diff --git a/libavformat/yuv4mpeg.c b/libavformat/yuv4mpeg.c
index bdae17b..cc13eaf 100644
--- a/libavformat/yuv4mpeg.c
+++ b/libavformat/yuv4mpeg.c
@@ -2,24 +2,25 @@
  * YUV4MPEG format
  * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
 #include "internal.h"
+#include "libavutil/pixdesc.h"
 
 #define Y4M_MAGIC "YUV4MPEG2"
 #define Y4M_FRAME_MAGIC "FRAME"
@@ -60,6 +61,9 @@
     case AV_PIX_FMT_GRAY8:
         colorspace = " Cmono";
         break;
+    case AV_PIX_FMT_GRAY16:
+        colorspace = " Cmono16";
+        break;
     case AV_PIX_FMT_YUV411P:
         colorspace = " C411 XYSCSS=411";
         break;
@@ -76,6 +80,33 @@
     case AV_PIX_FMT_YUV444P:
         colorspace = " C444 XYSCSS=444";
         break;
+    case AV_PIX_FMT_YUV420P9:
+        colorspace = " C420p9 XYSCSS=420P9";
+        break;
+    case AV_PIX_FMT_YUV422P9:
+        colorspace = " C422p9 XYSCSS=422P9";
+        break;
+    case AV_PIX_FMT_YUV444P9:
+        colorspace = " C444p9 XYSCSS=444P9";
+        break;
+    case AV_PIX_FMT_YUV420P10:
+        colorspace = " C420p10 XYSCSS=420P10";
+        break;
+    case AV_PIX_FMT_YUV422P10:
+        colorspace = " C422p10 XYSCSS=422P10";
+        break;
+    case AV_PIX_FMT_YUV444P10:
+        colorspace = " C444p10 XYSCSS=444P10";
+        break;
+    case AV_PIX_FMT_YUV420P16:
+        colorspace = " C420p16 XYSCSS=420P16";
+        break;
+    case AV_PIX_FMT_YUV422P16:
+        colorspace = " C422p16 XYSCSS=422P16";
+        break;
+    case AV_PIX_FMT_YUV444P16:
+        colorspace = " C444p16 XYSCSS=444P16";
+        break;
     }
 
     /* construct stream header, if this is the first frame */
@@ -90,7 +121,7 @@
 {
     AVStream *st = s->streams[pkt->stream_index];
     AVIOContext *pb = s->pb;
-    AVPicture *picture;
+    AVPicture *picture, picture_tmp;
     int* first_pkt = s->priv_data;
     int width, height, h_chroma_shift, v_chroma_shift;
     int i;
@@ -98,7 +129,8 @@
     char buf1[20];
     uint8_t *ptr, *ptr1, *ptr2;
 
-    picture = (AVPicture *)pkt->data;
+    memcpy(&picture_tmp, pkt->data, sizeof(AVPicture));
+    picture = &picture_tmp;
 
     /* for the first packet we have to output the header as well */
     if (*first_pkt) {
@@ -121,12 +153,39 @@
     height = st->codec->height;
 
     ptr = picture->data[0];
+
+    switch (st->codec->pix_fmt) {
+    case AV_PIX_FMT_GRAY8:
+    case AV_PIX_FMT_YUV411P:
+    case AV_PIX_FMT_YUV420P:
+    case AV_PIX_FMT_YUV422P:
+    case AV_PIX_FMT_YUV444P:
+        break;
+    case AV_PIX_FMT_GRAY16:
+    case AV_PIX_FMT_YUV420P9:
+    case AV_PIX_FMT_YUV422P9:
+    case AV_PIX_FMT_YUV444P9:
+    case AV_PIX_FMT_YUV420P10:
+    case AV_PIX_FMT_YUV422P10:
+    case AV_PIX_FMT_YUV444P10:
+    case AV_PIX_FMT_YUV420P16:
+    case AV_PIX_FMT_YUV422P16:
+    case AV_PIX_FMT_YUV444P16:
+        width *= 2;
+        break;
+    default:
+        av_log(s, AV_LOG_ERROR, "The pixel format '%s' is not supported.\n",
+               av_get_pix_fmt_name(st->codec->pix_fmt));
+        return AVERROR(EINVAL);
+    }
+
     for (i = 0; i < height; i++) {
         avio_write(pb, ptr, width);
         ptr += picture->linesize[0];
     }
 
-    if (st->codec->pix_fmt != AV_PIX_FMT_GRAY8) {
+    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);
@@ -144,6 +203,7 @@
             ptr2 += picture->linesize[2];
         }
     }
+
     avio_flush(pb);
     return 0;
 }
@@ -155,15 +215,48 @@
     if (s->nb_streams != 1)
         return AVERROR(EIO);
 
-    if (s->streams[0]->codec->pix_fmt == AV_PIX_FMT_YUV411P) {
-        av_log(s, AV_LOG_ERROR, "Warning: generating rarely used 4:1:1 YUV "
+    if (s->streams[0]->codec->codec_id != AV_CODEC_ID_RAWVIDEO) {
+        av_log(s, AV_LOG_ERROR,
+               "A non-rawvideo stream was selected, but yuv4mpeg only handles rawvideo streams\n");
+        return AVERROR(EINVAL);
+    }
+
+    switch (s->streams[0]->codec->pix_fmt) {
+    case AV_PIX_FMT_YUV411P:
+        av_log(s, AV_LOG_WARNING, "Warning: generating rarely used 4:1:1 YUV "
                "stream, some mjpegtools might not work.\n");
-    } else if ((s->streams[0]->codec->pix_fmt != AV_PIX_FMT_YUV420P) &&
-               (s->streams[0]->codec->pix_fmt != AV_PIX_FMT_YUV422P) &&
-               (s->streams[0]->codec->pix_fmt != AV_PIX_FMT_GRAY8)   &&
-               (s->streams[0]->codec->pix_fmt != AV_PIX_FMT_YUV444P)) {
-        av_log(s, AV_LOG_ERROR, "ERROR: yuv4mpeg only handles yuv444p, "
-               "yuv422p, yuv420p, yuv411p and gray pixel formats. "
+        break;
+    case AV_PIX_FMT_GRAY8:
+    case AV_PIX_FMT_GRAY16:
+    case AV_PIX_FMT_YUV420P:
+    case AV_PIX_FMT_YUV422P:
+    case AV_PIX_FMT_YUV444P:
+        break;
+    case AV_PIX_FMT_YUV420P9:
+    case AV_PIX_FMT_YUV422P9:
+    case AV_PIX_FMT_YUV444P9:
+    case AV_PIX_FMT_YUV420P10:
+    case AV_PIX_FMT_YUV422P10:
+    case AV_PIX_FMT_YUV444P10:
+    case AV_PIX_FMT_YUV420P16:
+    case AV_PIX_FMT_YUV422P16:
+    case AV_PIX_FMT_YUV444P16:
+        if (s->streams[0]->codec->strict_std_compliance >= FF_COMPLIANCE_NORMAL) {
+            av_log(s, AV_LOG_ERROR, "'%s' is not a official yuv4mpegpipe pixel format. "
+                   "Use '-strict -1' to encode to this pixel format.\n",
+                   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. "
+               "Mjpegtools will not work.\n");
+        break;
+    default:
+        av_log(s, AV_LOG_ERROR, "ERROR: yuv4mpeg can only handle "
+               "yuv444p, yuv422p, yuv420p, yuv411p and gray8 pixel formats. "
+               "And using 'strict -1' also yuv444p9, yuv422p9, yuv420p9, "
+               "yuv444p10, yuv422p10, yuv420p10, "
+               "yuv444p16, yuv422p16, yuv420p16 "
+               "and gray16 pixel formats. "
                "Use -pix_fmt to select one.\n");
         return AVERROR(EIO);
     }
@@ -175,7 +268,6 @@
 AVOutputFormat ff_yuv4mpegpipe_muxer = {
     .name              = "yuv4mpegpipe",
     .long_name         = NULL_IF_CONFIG_SMALL("YUV4MPEG pipe"),
-    .mime_type         = "",
     .extensions        = "y4m",
     .priv_data_size    = sizeof(int),
     .audio_codec       = AV_CODEC_ID_NONE,
@@ -244,20 +336,40 @@
             } else if (strncmp("420paldv", tokstart, 8) == 0) {
                 pix_fmt = AV_PIX_FMT_YUV420P;
                 chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
+            } else if (strncmp("420p16", tokstart, 6) == 0) {
+                pix_fmt = AV_PIX_FMT_YUV420P16;
+            } else if (strncmp("422p16", tokstart, 6) == 0) {
+                pix_fmt = AV_PIX_FMT_YUV422P16;
+            } else if (strncmp("444p16", tokstart, 6) == 0) {
+                pix_fmt = AV_PIX_FMT_YUV444P16;
+            } else if (strncmp("420p10", tokstart, 6) == 0) {
+                pix_fmt = AV_PIX_FMT_YUV420P10;
+            } else if (strncmp("422p10", tokstart, 6) == 0) {
+                pix_fmt = AV_PIX_FMT_YUV422P10;
+            } else if (strncmp("444p10", tokstart, 6) == 0) {
+                pix_fmt = AV_PIX_FMT_YUV444P10;
+            } else if (strncmp("420p9", tokstart, 5) == 0) {
+                pix_fmt = AV_PIX_FMT_YUV420P9;
+            } else if (strncmp("422p9", tokstart, 5) == 0) {
+                pix_fmt = AV_PIX_FMT_YUV422P9;
+            } else if (strncmp("444p9", tokstart, 5) == 0) {
+                pix_fmt = AV_PIX_FMT_YUV444P9;
             } else if (strncmp("420", tokstart, 3) == 0) {
                 pix_fmt = AV_PIX_FMT_YUV420P;
                 chroma_sample_location = AVCHROMA_LOC_CENTER;
-            } else if (strncmp("411", tokstart, 3) == 0)
+            } else if (strncmp("411", tokstart, 3) == 0) {
                 pix_fmt = AV_PIX_FMT_YUV411P;
-            else if (strncmp("422", tokstart, 3) == 0)
+            } else if (strncmp("422", tokstart, 3) == 0) {
                 pix_fmt = AV_PIX_FMT_YUV422P;
-            else if (strncmp("444alpha", tokstart, 8) == 0 ) {
+            } else if (strncmp("444alpha", tokstart, 8) == 0 ) {
                 av_log(s, AV_LOG_ERROR, "Cannot handle 4:4:4:4 "
                        "YUV4MPEG stream.\n");
                 return -1;
-            } else if (strncmp("444", tokstart, 3) == 0)
+            } else if (strncmp("444", tokstart, 3) == 0) {
                 pix_fmt = AV_PIX_FMT_YUV444P;
-            else if (strncmp("mono", tokstart, 4) == 0) {
+            } else if (strncmp("mono16", tokstart, 6) == 0) {
+                pix_fmt = AV_PIX_FMT_GRAY16;
+            } else if (strncmp("mono", tokstart, 4) == 0) {
                 pix_fmt = AV_PIX_FMT_GRAY8;
             } else {
                 av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains an unknown "
@@ -311,6 +423,24 @@
                     alt_pix_fmt = AV_PIX_FMT_YUV420P;
                 else if (strncmp("420PALDV", tokstart, 8) == 0)
                     alt_pix_fmt = AV_PIX_FMT_YUV420P;
+                else if (strncmp("420P9", tokstart, 5) == 0)
+                    alt_pix_fmt = AV_PIX_FMT_YUV420P9;
+                else if (strncmp("422P9", tokstart, 5) == 0)
+                    alt_pix_fmt = AV_PIX_FMT_YUV422P9;
+                else if (strncmp("444P9", tokstart, 5) == 0)
+                    alt_pix_fmt = AV_PIX_FMT_YUV444P9;
+                else if (strncmp("420P10", tokstart, 6) == 0)
+                    alt_pix_fmt = AV_PIX_FMT_YUV420P10;
+                else if (strncmp("422P10", tokstart, 6) == 0)
+                    alt_pix_fmt = AV_PIX_FMT_YUV422P10;
+                else if (strncmp("444P10", tokstart, 6) == 0)
+                    alt_pix_fmt = AV_PIX_FMT_YUV444P10;
+                else if (strncmp("420P16", tokstart, 6) == 0)
+                    alt_pix_fmt = AV_PIX_FMT_YUV420P16;
+                else if (strncmp("422P16", tokstart, 6) == 0)
+                    alt_pix_fmt = AV_PIX_FMT_YUV422P16;
+                else if (strncmp("444P16", tokstart, 6) == 0)
+                    alt_pix_fmt = AV_PIX_FMT_YUV444P16;
                 else if (strncmp("411", tokstart, 3) == 0)
                     alt_pix_fmt = AV_PIX_FMT_YUV411P;
                 else if (strncmp("422", tokstart, 3) == 0)
diff --git a/libavresample/arm/audio_convert_init.c b/libavresample/arm/audio_convert_init.c
index bbb7bae..3d19a0e 100644
--- a/libavresample/arm/audio_convert_init.c
+++ b/libavresample/arm/audio_convert_init.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavresample/arm/audio_convert_neon.S b/libavresample/arm/audio_convert_neon.S
index 092ce0c..98f77f0 100644
--- a/libavresample/arm/audio_convert_neon.S
+++ b/libavresample/arm/audio_convert_neon.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavresample/resample_template.c b/libavresample/resample_template.c
index 5b0fbec..06da90f 100644
--- a/libavresample/resample_template.c
+++ b/libavresample/resample_template.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavresample/utils.c b/libavresample/utils.c
index 378dd48..2a0aacd 100644
--- a/libavresample/utils.c
+++ b/libavresample/utils.c
@@ -20,7 +20,7 @@
 
 #include "libavutil/common.h"
 #include "libavutil/dict.h"
-#include "libavutil/error.h"
+// #include "libavutil/error.h"
 #include "libavutil/log.h"
 #include "libavutil/mem.h"
 #include "libavutil/opt.h"
@@ -425,10 +425,10 @@
 const char *avresample_license(void)
 {
 #define LICENSE_PREFIX "libavresample license: "
-    return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+    return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
 }
 
 const char *avresample_configuration(void)
 {
-    return LIBAV_CONFIGURATION;
+    return FFMPEG_CONFIGURATION;
 }
diff --git a/libavutil/Makefile b/libavutil/Makefile
index e2b84e0..841eec5 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -1,3 +1,5 @@
+include $(SUBDIR)../config.mak
+
 NAME = avutil
 
 HEADERS = adler32.h                                                     \
@@ -10,6 +12,7 @@
           avutil.h                                                      \
           base64.h                                                      \
           blowfish.h                                                    \
+          bprint.h                                                      \
           bswap.h                                                       \
           common.h                                                      \
           cpu.h                                                         \
@@ -39,6 +42,8 @@
           samplefmt.h                                                   \
           sha.h                                                         \
           time.h                                                        \
+          timecode.h                                                    \
+          timestamp.h                                                   \
           version.h                                                     \
           xtea.h                                                        \
 
@@ -56,6 +61,7 @@
        avstring.o                                                       \
        base64.o                                                         \
        blowfish.o                                                       \
+       bprint.o                                                         \
        cpu.o                                                            \
        crc.o                                                            \
        des.o                                                            \
@@ -84,12 +90,15 @@
        samplefmt.o                                                      \
        sha.o                                                            \
        time.o                                                           \
+       timecode.o                                                       \
        tree.o                                                           \
        utils.o                                                          \
+       xga_font_data.o                                                  \
        xtea.o                                                           \
 
-OBJS-$(HAVE_MSVCRT) += ../compat/msvcrt/snprintf.o                      \
-                       ../compat/strtod.o
+OBJS-$(HAVE_BROKEN_SNPRINTF) += ../compat/msvcrt/snprintf.o
+
+OBJS-$(HAVE_MSVCRT) += ../compat/strtod.o
 
 SKIPHEADERS          = old_pix_fmts.h
 
@@ -98,16 +107,28 @@
             avstring                                                    \
             base64                                                      \
             blowfish                                                    \
+            bprint                                                      \
             cpu                                                         \
             crc                                                         \
             des                                                         \
+            error                                                       \
             eval                                                        \
+            file                                                        \
             fifo                                                        \
             lfg                                                         \
             lls                                                         \
             md5                                                         \
             opt                                                         \
+            pca                                                         \
             parseutils                                                  \
+            random_seed                                                 \
+            rational                                                    \
             sha                                                         \
             tree                                                        \
             xtea                                                        \
+
+TESTPROGS-$(HAVE_LZO1X_999_COMPRESS) += lzo
+
+TOOLS = ffeval
+
+$(SUBDIR)lzo-test$(EXESUF): ELIBS = -llzo2
diff --git a/libavutil/adler32.c b/libavutil/adler32.c
index 7f5afdb..bc9b9a7 100644
--- a/libavutil/adler32.c
+++ b/libavutil/adler32.c
@@ -23,6 +23,8 @@
 
 #include "config.h"
 #include "adler32.h"
+#include "common.h"
+#include "intreadwrite.h"
 
 #define BASE 65521L /* largest prime smaller than 65536 */
 
@@ -37,16 +39,46 @@
     unsigned long s2 = adler >> 16;
 
     while (len > 0) {
-#if CONFIG_SMALL
+#if HAVE_FAST_64BIT && HAVE_FAST_UNALIGNED && !CONFIG_SMALL
+        unsigned len2 = FFMIN((len-1) & ~7, 23*8);
+        if (len2) {
+            uint64_t a1= 0;
+            uint64_t a2= 0;
+            uint64_t b1= 0;
+            uint64_t b2= 0;
+            len -= len2;
+            s2 += s1*len2;
+            while (len2 >= 8) {
+                uint64_t v = AV_RN64(buf);
+                a2 += a1;
+                b2 += b1;
+                a1 +=  v    &0x00FF00FF00FF00FF;
+                b1 += (v>>8)&0x00FF00FF00FF00FF;
+                len2 -= 8;
+                buf+=8;
+            }
+
+            //We combine the 8 interleaved adler32 checksums without overflows
+            //Decreasing the number of iterations would allow below code to be
+            //simplified but would likely be slower due to the fewer iterations
+            //of the inner loop
+            s1 += ((a1+b1)*0x1000100010001)>>48;
+            s2 += ((((a2&0xFFFF0000FFFF)+(b2&0xFFFF0000FFFF)+((a2>>16)&0xFFFF0000FFFF)+((b2>>16)&0xFFFF0000FFFF))*0x800000008)>>32)
+#if HAVE_BIGENDIAN
+                 + 2*((b1*0x1000200030004)>>48)
+                 +   ((a1*0x1000100010001)>>48)
+                 + 2*((a1*0x0000100020003)>>48);
+#else
+                 + 2*((a1*0x4000300020001)>>48)
+                 +   ((b1*0x1000100010001)>>48)
+                 + 2*((b1*0x3000200010000)>>48);
+#endif
+        }
+#else
         while (len > 4  && s2 < (1U << 31)) {
             DO4(buf);
             len -= 4;
         }
-#else
-        while (len > 16 && s2 < (1U << 31)) {
-            DO16(buf);
-            len -= 16;
-        }
 #endif
         DO1(buf); len--;
         s1 %= BASE;
@@ -56,6 +88,7 @@
 }
 
 #ifdef TEST
+// LCOV_EXCL_START
 #include <string.h>
 #include "log.h"
 #include "timer.h"
@@ -86,4 +119,5 @@
     av_log(NULL, AV_LOG_DEBUG, "%X (expected 50E6E508)\n", checksum);
     return checksum == 0x50e6e508 ? 0 : 1;
 }
+// LCOV_EXCL_STOP
 #endif
diff --git a/libavutil/adler32.h b/libavutil/adler32.h
index a8ff6f9..e926ef6 100644
--- a/libavutil/adler32.h
+++ b/libavutil/adler32.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Mans Rullgard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/aes.c b/libavutil/aes.c
index 4656a48..555cbb8 100644
--- a/libavutil/aes.c
+++ b/libavutil/aes.c
@@ -3,20 +3,20 @@
  *
  * some optimization ideas from aes128.c by Reimar Doeffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -266,6 +266,7 @@
 }
 
 #ifdef TEST
+// LCOV_EXCL_START
 #include <string.h>
 #include "lfg.h"
 #include "log.h"
@@ -338,4 +339,5 @@
     }
     return err;
 }
+// LCOV_EXCL_STOP
 #endif
diff --git a/libavutil/aes.h b/libavutil/aes.h
index edff275..9c1a54e 100644
--- a/libavutil/aes.h
+++ b/libavutil/aes.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2007 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/arm/asm.S b/libavutil/arm/asm.S
index 78942c8..bb7c383 100644
--- a/libavutil/arm/asm.S
+++ b/libavutil/arm/asm.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/arm/bswap.h b/libavutil/arm/bswap.h
index e49cdd4..c10c35f 100644
--- a/libavutil/arm/bswap.h
+++ b/libavutil/arm/bswap.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/arm/float_dsp_arm.h b/libavutil/arm/float_dsp_arm.h
index 81fad3e..f3fafe3 100644
--- a/libavutil/arm/float_dsp_arm.h
+++ b/libavutil/arm/float_dsp_arm.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/arm/float_dsp_init_arm.c b/libavutil/arm/float_dsp_init_arm.c
index b133d32..f721344 100644
--- a/libavutil/arm/float_dsp_init_arm.c
+++ b/libavutil/arm/float_dsp_init_arm.c
@@ -1,20 +1,20 @@
 /*
  * ARM optimized DSP utils
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/arm/float_dsp_init_vfp.c b/libavutil/arm/float_dsp_init_vfp.c
index ef808d8..7abc332 100644
--- a/libavutil/arm/float_dsp_init_vfp.c
+++ b/libavutil/arm/float_dsp_init_vfp.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/arm/float_dsp_vfp.S b/libavutil/arm/float_dsp_vfp.S
index 3931828..db63e5a6 100644
--- a/libavutil/arm/float_dsp_vfp.S
+++ b/libavutil/arm/float_dsp_vfp.S
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Siarhei Siamashka <ssvb@users.sourceforge.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/arm/intmath.h b/libavutil/arm/intmath.h
index 4d5a400..0980a6f 100644
--- a/libavutil/arm/intmath.h
+++ b/libavutil/arm/intmath.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/arm/intreadwrite.h b/libavutil/arm/intreadwrite.h
index 6eff733..2340a9a 100644
--- a/libavutil/arm/intreadwrite.h
+++ b/libavutil/arm/intreadwrite.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/arm/timer.h b/libavutil/arm/timer.h
index 4bca877..5e8bc8e 100644
--- a/libavutil/arm/timer.h
+++ b/libavutil/arm/timer.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/attributes.h b/libavutil/attributes.h
index 292a0a1..64b46f6 100644
--- a/libavutil/attributes.h
+++ b/libavutil/attributes.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -32,6 +32,7 @@
 #    define AV_GCC_VERSION_AT_LEAST(x,y) 0
 #endif
 
+#ifndef av_always_inline
 #if AV_GCC_VERSION_AT_LEAST(3,1)
 #    define av_always_inline __attribute__((always_inline)) inline
 #elif defined(_MSC_VER)
@@ -39,6 +40,15 @@
 #else
 #    define av_always_inline inline
 #endif
+#endif
+
+#ifndef av_extern_inline
+#if defined(__ICL) && __ICL >= 1210 || defined(__GNUC_STDC_INLINE__)
+#    define av_extern_inline extern inline
+#else
+#    define av_extern_inline inline
+#endif
+#endif
 
 #if AV_GCC_VERSION_AT_LEAST(3,1)
 #    define av_noinline __attribute__((noinline))
@@ -52,6 +62,10 @@
 #    define av_pure
 #endif
 
+#ifndef av_restrict
+#define av_restrict restrict
+#endif
+
 #if AV_GCC_VERSION_AT_LEAST(2,6)
 #    define av_const __attribute__((const))
 #else
@@ -76,6 +90,24 @@
 #    define attribute_deprecated
 #endif
 
+/**
+ * Disable warnings about deprecated features
+ * This is useful for sections of code kept for backward compatibility and
+ * scheduled for removal.
+ */
+#ifndef AV_NOWARN_DEPRECATED
+#if AV_GCC_VERSION_AT_LEAST(4,6)
+#    define AV_NOWARN_DEPRECATED(code) \
+        _Pragma("GCC diagnostic push") \
+        _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \
+        code \
+        _Pragma("GCC diagnostic pop")
+#else
+#    define AV_NOWARN_DEPRECATED(code) code
+#endif
+#endif
+
+
 #if defined(__GNUC__)
 #    define av_unused __attribute__((unused))
 #else
@@ -99,7 +131,7 @@
 #   define av_alias
 #endif
 
-#if defined(__GNUC__) && !defined(__ICC)
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
 #    define av_uninit(x) x=x
 #else
 #    define av_uninit(x) x
diff --git a/libavutil/audioconvert.c b/libavutil/audioconvert.c
index 113b9d7..caab5e6 100644
--- a/libavutil/audioconvert.c
+++ b/libavutil/audioconvert.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,41 +26,47 @@
 #include "avstring.h"
 #include "avutil.h"
 #include "audioconvert.h"
+#include "bprint.h"
 #include "common.h"
 
-static const char * const channel_names[] = {
-    [0]  = "FL",        /* front left */
-    [1]  = "FR",        /* front right */
-    [2]  = "FC",        /* front center */
-    [3]  = "LFE",       /* low frequency */
-    [4]  = "BL",        /* back left */
-    [5]  = "BR",        /* back right */
-    [6]  = "FLC",       /* front left-of-center  */
-    [7]  = "FRC",       /* front right-of-center */
-    [8]  = "BC",        /* back-center */
-    [9]  = "SL",        /* side left */
-    [10] = "SR",        /* side right */
-    [11] = "TC",        /* top center */
-    [12] = "TFL",       /* top front left */
-    [13] = "TFC",       /* top front center */
-    [14] = "TFR",       /* top front right */
-    [15] = "TBL",       /* top back left */
-    [16] = "TBC",       /* top back center */
-    [17] = "TBR",       /* top back right */
-    [29] = "DL",        /* downmix left */
-    [30] = "DR",        /* downmix right */
-    [31] = "WL",        /* wide left */
-    [32] = "WR",        /* wide right */
-    [33] = "SDL",       /* surround direct left */
-    [34] = "SDR",       /* surround direct right */
-    [35] = "LFE2",      /* low frequency 2 */
+struct channel_name {
+    const char *name;
+    const char *description;
+};
+
+static const struct channel_name channel_names[] = {
+     [0] = { "FL",        "front left"            },
+     [1] = { "FR",        "front right"           },
+     [2] = { "FC",        "front center"          },
+     [3] = { "LFE",       "low frequency"         },
+     [4] = { "BL",        "back left"             },
+     [5] = { "BR",        "back right"            },
+     [6] = { "FLC",       "front left-of-center"  },
+     [7] = { "FRC",       "front right-of-center" },
+     [8] = { "BC",        "back center"           },
+     [9] = { "SL",        "side left"             },
+    [10] = { "SR",        "side right"            },
+    [11] = { "TC",        "top center"            },
+    [12] = { "TFL",       "top front left"        },
+    [13] = { "TFC",       "top front center"      },
+    [14] = { "TFR",       "top front right"       },
+    [15] = { "TBL",       "top back left"         },
+    [16] = { "TBC",       "top back center"       },
+    [17] = { "TBR",       "top back right"        },
+    [29] = { "DL",        "downmix left"          },
+    [30] = { "DR",        "downmix right"         },
+    [31] = { "WL",        "wide left"             },
+    [32] = { "WR",        "wide right"            },
+    [33] = { "SDL",       "surround direct left"  },
+    [34] = { "SDR",       "surround direct right" },
+    [35] = { "LFE2",      "low frequency 2"       },
 };
 
 static const char *get_channel_name(int channel_id)
 {
     if (channel_id < 0 || channel_id >= FF_ARRAY_ELEMS(channel_names))
         return NULL;
-    return channel_names[channel_id];
+    return channel_names[channel_id].name;
 }
 
 static const struct {
@@ -70,19 +76,18 @@
 } channel_layout_map[] = {
     { "mono",        1,  AV_CH_LAYOUT_MONO },
     { "stereo",      2,  AV_CH_LAYOUT_STEREO },
-    { "stereo",      2,  AV_CH_LAYOUT_STEREO_DOWNMIX },
     { "2.1",         3,  AV_CH_LAYOUT_2POINT1 },
     { "3.0",         3,  AV_CH_LAYOUT_SURROUND },
     { "3.0(back)",   3,  AV_CH_LAYOUT_2_1 },
-    { "3.1",         4,  AV_CH_LAYOUT_3POINT1 },
     { "4.0",         4,  AV_CH_LAYOUT_4POINT0 },
     { "quad",        4,  AV_CH_LAYOUT_QUAD },
     { "quad(side)",  4,  AV_CH_LAYOUT_2_2 },
-    { "4.1",         5,  AV_CH_LAYOUT_4POINT1 },
-    { "5.0",         5,  AV_CH_LAYOUT_5POINT0 },
+    { "3.1",         4,  AV_CH_LAYOUT_3POINT1 },
     { "5.0",         5,  AV_CH_LAYOUT_5POINT0_BACK },
-    { "5.1",         6,  AV_CH_LAYOUT_5POINT1 },
+    { "5.0(side)",   5,  AV_CH_LAYOUT_5POINT0 },
+    { "4.1",         5,  AV_CH_LAYOUT_4POINT1 },
     { "5.1",         6,  AV_CH_LAYOUT_5POINT1_BACK },
+    { "5.1(side)",   6,  AV_CH_LAYOUT_5POINT1 },
     { "6.0",         6,  AV_CH_LAYOUT_6POINT0 },
     { "6.0(front)",  6,  AV_CH_LAYOUT_6POINT0_FRONT },
     { "hexagonal",   6,  AV_CH_LAYOUT_HEXAGONAL },
@@ -93,10 +98,8 @@
     { "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 },
     { "octagonal",   8,  AV_CH_LAYOUT_OCTAGONAL },
     { "downmix",     2,  AV_CH_LAYOUT_STEREO_DOWNMIX, },
-    { 0 }
 };
 
 static uint64_t get_channel_layout_single(const char *name, int name_len)
@@ -105,15 +108,15 @@
     char *end;
     int64_t layout;
 
-    for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map) - 1; i++) {
+    for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) {
         if (strlen(channel_layout_map[i].name) == name_len &&
             !memcmp(channel_layout_map[i].name, name, name_len))
             return channel_layout_map[i].layout;
     }
     for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++)
-        if (channel_names[i] &&
-            strlen(channel_names[i]) == name_len &&
-            !memcmp(channel_names[i], name, name_len))
+        if (channel_names[i].name &&
+            strlen(channel_names[i].name) == name_len &&
+            !memcmp(channel_names[i].name, name, name_len))
             return (int64_t)1 << i;
     i = strtol(name, &end, 10);
     if (end - name == name_len ||
@@ -141,58 +144,60 @@
     return layout;
 }
 
-void av_get_channel_layout_string(char *buf, int buf_size,
-                                  int nb_channels, uint64_t channel_layout)
+void av_bprint_channel_layout(struct AVBPrint *bp,
+                              int nb_channels, uint64_t channel_layout)
 {
     int i;
 
     if (nb_channels <= 0)
         nb_channels = av_get_channel_layout_nb_channels(channel_layout);
 
-    for (i = 0; channel_layout_map[i].name; i++)
+    for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
         if (nb_channels    == channel_layout_map[i].nb_channels &&
             channel_layout == channel_layout_map[i].layout) {
-            av_strlcpy(buf, channel_layout_map[i].name, buf_size);
+            av_bprintf(bp, "%s", channel_layout_map[i].name);
             return;
         }
 
-    snprintf(buf, buf_size, "%d channels", nb_channels);
+    av_bprintf(bp, "%d channels", nb_channels);
     if (channel_layout) {
         int i, ch;
-        av_strlcat(buf, " (", buf_size);
+        av_bprintf(bp, " (");
         for (i = 0, ch = 0; i < 64; i++) {
             if ((channel_layout & (UINT64_C(1) << i))) {
                 const char *name = get_channel_name(i);
                 if (name) {
                     if (ch > 0)
-                        av_strlcat(buf, "|", buf_size);
-                    av_strlcat(buf, name, buf_size);
+                        av_bprintf(bp, "+");
+                    av_bprintf(bp, "%s", name);
                 }
                 ch++;
             }
         }
-        av_strlcat(buf, ")", buf_size);
+        av_bprintf(bp, ")");
     }
 }
 
+void av_get_channel_layout_string(char *buf, int buf_size,
+                                  int nb_channels, uint64_t channel_layout)
+{
+    AVBPrint bp;
+
+    av_bprint_init_for_buffer(&bp, buf, buf_size);
+    av_bprint_channel_layout(&bp, nb_channels, channel_layout);
+}
+
 int av_get_channel_layout_nb_channels(uint64_t channel_layout)
 {
     return av_popcount64(channel_layout);
 }
 
-uint64_t av_get_default_channel_layout(int nb_channels)
-{
-    switch(nb_channels) {
-    case 1: return AV_CH_LAYOUT_MONO;
-    case 2: return AV_CH_LAYOUT_STEREO;
-    case 3: return AV_CH_LAYOUT_SURROUND;
-    case 4: return AV_CH_LAYOUT_QUAD;
-    case 5: return AV_CH_LAYOUT_5POINT0;
-    case 6: return AV_CH_LAYOUT_5POINT1;
-    case 7: return AV_CH_LAYOUT_6POINT1;
-    case 8: return AV_CH_LAYOUT_7POINT1;
-    default: return 0;
-    }
+int64_t av_get_default_channel_layout(int nb_channels) {
+    int i;
+    for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
+        if (nb_channels == channel_layout_map[i].nb_channels)
+            return channel_layout_map[i].layout;
+    return 0;
 }
 
 int av_get_channel_layout_channel_index(uint64_t channel_layout,
@@ -216,6 +221,17 @@
     return NULL;
 }
 
+const char *av_get_channel_description(uint64_t channel)
+{
+    int i;
+    if (av_get_channel_layout_nb_channels(channel) != 1)
+        return NULL;
+    for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++)
+        if ((1ULL<<i) & channel)
+            return channel_names[i].description;
+    return NULL;
+}
+
 uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
 {
     int i;
@@ -229,3 +245,13 @@
     }
     return 0;
 }
+
+int av_get_standard_channel_layout(unsigned index, uint64_t *layout,
+                                   const char **name)
+{
+    if (index >= FF_ARRAY_ELEMS(channel_layout_map))
+        return AVERROR_EOF;
+    if (layout) *layout = channel_layout_map[index].layout;
+    if (name)   *name   = channel_layout_map[index].name;
+    return 0;
+}
diff --git a/libavutil/audioconvert.h b/libavutil/audioconvert.h
index 73076cb..76eb278 100644
--- a/libavutil/audioconvert.h
+++ b/libavutil/audioconvert.h
@@ -2,20 +2,20 @@
  * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2008 Peter Ross
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -141,6 +141,12 @@
  */
 void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout);
 
+struct AVBPrint;
+/**
+ * Append a description of a channel layout to a bprint buffer.
+ */
+void av_bprint_channel_layout(struct AVBPrint *bp, int nb_channels, uint64_t channel_layout);
+
 /**
  * Return the number of channels in the channel layout.
  */
@@ -149,7 +155,7 @@
 /**
  * Return default channel layout for a given number of channels.
  */
-uint64_t av_get_default_channel_layout(int nb_channels);
+int64_t av_get_default_channel_layout(int nb_channels);
 
 /**
  * Get the index of a channel in channel_layout.
@@ -176,6 +182,26 @@
 const char *av_get_channel_name(uint64_t channel);
 
 /**
+ * Get the description of a given channel.
+ *
+ * @param channel  a channel layout with a single channel
+ * @return  channel description on success, NULL on error
+ */
+const char *av_get_channel_description(uint64_t channel);
+
+/**
+ * Get the value and name of a standard channel layout.
+ *
+ * @param[in]  index   index in an internal list, starting at 0
+ * @param[out] layout  channel layout mask
+ * @param[out] name    name of the layout
+ * @return  0  if the layout exists,
+ *          <0 if index is beyond the limits
+ */
+int av_get_standard_channel_layout(unsigned index, uint64_t *layout,
+                                   const char **name);
+
+/**
  * @}
  */
 
diff --git a/libavutil/avassert.h b/libavutil/avassert.h
index b223d26..e100d0b 100644
--- a/libavutil/avassert.h
+++ b/libavutil/avassert.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2010 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/avr32/bswap.h b/libavutil/avr32/bswap.h
index 857f024..e79d53f 100644
--- a/libavutil/avr32/bswap.h
+++ b/libavutil/avr32/bswap.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/avr32/intreadwrite.h b/libavutil/avr32/intreadwrite.h
index e0049fe..c6fd3aa 100644
--- a/libavutil/avr32/intreadwrite.h
+++ b/libavutil/avr32/intreadwrite.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/avstring.c b/libavutil/avstring.c
index 9b88c0b..8b258a4 100644
--- a/libavutil/avstring.c
+++ b/libavutil/avstring.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  * Copyright (c) 2007 Mans Rullgard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -52,11 +52,11 @@
 char *av_stristr(const char *s1, const char *s2)
 {
     if (!*s2)
-        return s1;
+        return (char*)(intptr_t)s1;
 
     do {
         if (av_stristart(s1, s2, NULL))
-            return s1;
+            return (char*)(intptr_t)s1;
     } while (*s1++);
 
     return NULL;
@@ -92,6 +92,32 @@
     return len;
 }
 
+char *av_asprintf(const char *fmt, ...)
+{
+    char *p = NULL;
+    va_list va;
+    int len;
+
+    va_start(va, fmt);
+    len = vsnprintf(NULL, 0, fmt, va);
+    va_end(va);
+    if (len < 0)
+        goto end;
+
+    p = av_malloc(len + 1);
+    if (!p)
+        goto end;
+
+    va_start(va, fmt);
+    len = vsnprintf(p, len + 1, fmt, va);
+    va_end(va);
+    if (len < 0)
+        av_freep(&p);
+
+end:
+    return p;
+}
+
 char *av_d2str(double d)
 {
     char *str= av_malloc(16);
@@ -135,6 +161,35 @@
     return ret;
 }
 
+char *av_strtok(char *s, const char *delim, char **saveptr)
+{
+    char *tok;
+
+    if (!s && !(s = *saveptr))
+        return NULL;
+
+    /* skip leading delimiters */
+    s += strspn(s, delim);
+
+    /* s now points to the first non delimiter char, or to the end of the string */
+    if (!*s) {
+        *saveptr = NULL;
+        return NULL;
+    }
+    tok = s++;
+
+    /* skip non delimiters */
+    s += strcspn(s, delim);
+    if (*s) {
+        *s = 0;
+        *saveptr = s+1;
+    } else {
+        *saveptr = NULL;
+    }
+
+    return tok;
+}
+
 int av_strcasecmp(const char *a, const char *b)
 {
     uint8_t c1, c2;
diff --git a/libavutil/avstring.h b/libavutil/avstring.h
index ed4e465..f73d6e7 100644
--- a/libavutil/avstring.h
+++ b/libavutil/avstring.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2007 Mans Rullgard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -116,6 +116,16 @@
 size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...) av_printf_format(3, 4);
 
 /**
+ * Print arguments following specified format into a large enough auto
+ * allocated buffer. It is similar to GNU asprintf().
+ * @param fmt printf-compatible format string, specifying how the
+ *            following parameters are used.
+ * @return the allocated string
+ * @note You have to free the string yourself with av_free().
+ */
+char *av_asprintf(const char *fmt, ...) av_printf_format(1, 2);
+
+/**
  * Convert a number to a av_malloced string.
  */
 char *av_d2str(double d);
@@ -137,6 +147,30 @@
 char *av_get_token(const char **buf, const char *term);
 
 /**
+ * Split the string into several tokens which can be accessed by
+ * successive calls to av_strtok().
+ *
+ * A token is defined as a sequence of characters not belonging to the
+ * set specified in delim.
+ *
+ * On the first call to av_strtok(), s should point to the string to
+ * parse, and the value of saveptr is ignored. In subsequent calls, s
+ * should be NULL, and saveptr should be unchanged since the previous
+ * call.
+ *
+ * This function is similar to strtok_r() defined in POSIX.1.
+ *
+ * @param s the string to parse, may be NULL
+ * @param delim 0-terminated list of token delimiters, must be non-NULL
+ * @param saveptr user-provided pointer which points to stored
+ * information necessary for av_strtok() to continue scanning the same
+ * string. saveptr is updated to point to the next character after the
+ * first delimiter found, or to NULL if the string was terminated
+ * @return the found token, or NULL when no token is found
+ */
+char *av_strtok(char *s, const char *delim, char **saveptr);
+
+/**
  * Locale-independent conversion of ASCII characters to uppercase.
  */
 static inline int av_toupper(int c)
@@ -156,7 +190,7 @@
     return c;
 }
 
-/*
+/**
  * Locale-independent case-insensitive compare.
  * @note This means only ASCII-range characters are case-insensitive
  */
diff --git a/libavutil/avutil.h b/libavutil/avutil.h
index a1433b4..cd02b35 100644
--- a/libavutil/avutil.h
+++ b/libavutil/avutil.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,19 +26,20 @@
  * external API header
  */
 
-/**
+/*
  * @mainpage
  *
- * @section libav_intro Introduction
+ * @section ffmpeg_intro Introduction
  *
  * This document describes the usage of the different libraries
- * provided by Libav.
+ * provided by FFmpeg.
  *
  * @li @ref libavc "libavcodec" encoding/decoding library
  * @li @subpage 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 @subpage libpostproc post processing library
  * @li @subpage libswscale  color conversion and scaling library
  */
 
@@ -46,7 +47,7 @@
  * @defgroup lavu Common utility functions
  *
  * @brief
- * libavutil contains the code shared across all the other Libav
+ * libavutil contains the code shared across all the other FFmpeg
  * libraries
  *
  * @note In order to use the functions provided by avutil you must include
@@ -184,6 +185,12 @@
 };
 
 /**
+ * Return a string describing the media_type enum, NULL if media_type
+ * is unknown.
+ */
+const char *av_get_media_type_string(enum AVMediaType media_type);
+
+/**
  * @defgroup lavu_const Constants
  * @{
  *
@@ -204,7 +211,7 @@
  * @}
  * @defgroup lavu_time Timestamp specific
  *
- * Libav internal timebase and timestamp definitions
+ * FFmpeg internal timebase and timestamp definitions
  *
  * @{
  */
@@ -216,7 +223,7 @@
  * either pts or dts.
  */
 
-#define AV_NOPTS_VALUE          INT64_C(0x8000000000000000)
+#define AV_NOPTS_VALUE          ((int64_t)UINT64_C(0x8000000000000000))
 
 /**
  * Internal time base represented as integer
@@ -241,7 +248,8 @@
  */
 
 enum AVPictureType {
-    AV_PICTURE_TYPE_I = 1, ///< Intra
+    AV_PICTURE_TYPE_NONE = 0, ///< Undefined
+    AV_PICTURE_TYPE_I,     ///< Intra
     AV_PICTURE_TYPE_P,     ///< Predicted
     AV_PICTURE_TYPE_B,     ///< Bi-dir predicted
     AV_PICTURE_TYPE_S,     ///< S(GMC)-VOP MPEG4
@@ -263,8 +271,22 @@
  * @}
  */
 
+#include "common.h"
 #include "error.h"
 #include "version.h"
+#include "mathematics.h"
+#include "rational.h"
+#include "intfloat_readwrite.h"
+#include "log.h"
+#include "pixfmt.h"
+
+/**
+ * Return x default pointer in case p is NULL.
+ */
+static inline void *av_x_if_null(const void *p, const void *x)
+{
+    return (void *)(intptr_t)(p ? p : x);
+}
 
 /**
  * @}
diff --git a/libavutil/base64.c b/libavutil/base64.c
index 73872b8..d907805 100644
--- a/libavutil/base64.c
+++ b/libavutil/base64.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,41 +26,106 @@
 
 #include "common.h"
 #include "base64.h"
+#include "intreadwrite.h"
 
 /* ---------------- private code */
-static const uint8_t map2[] =
+static const uint8_t map2[256] =
 {
+    0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff,
+
     0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36,
     0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff,
-    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01,
+    0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x01,
     0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
     0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
     0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b,
     0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
     0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
-    0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33
+    0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33,
+
+                      0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 };
 
-int av_base64_decode(uint8_t *out, const char *in, int out_size)
-{
-    int i, v;
-    uint8_t *dst = out;
+#define BASE64_DEC_STEP(i) do { \
+    bits = map2[in[i]]; \
+    if (bits & 0x80) \
+        goto out ## i; \
+    v = i ? (v << 6) + bits : bits; \
+} while(0)
 
-    v = 0;
-    for (i = 0; in[i] && in[i] != '='; i++) {
-        unsigned int index= in[i]-43;
-        if (index>=FF_ARRAY_ELEMS(map2) || map2[index] == 0xff)
-            return -1;
-        v = (v << 6) + map2[index];
-        if (i & 3) {
-            if (dst - out < out_size) {
-                *dst++ = v >> (6 - 2 * (i & 3));
-            }
-        }
+int av_base64_decode(uint8_t *out, const char *in_str, int out_size)
+{
+    uint8_t *dst = out;
+    uint8_t *end = out + out_size;
+    // no sign extension
+    const uint8_t *in = in_str;
+    unsigned bits = 0xff;
+    unsigned v;
+
+    while (end - dst > 3) {
+        BASE64_DEC_STEP(0);
+        BASE64_DEC_STEP(1);
+        BASE64_DEC_STEP(2);
+        BASE64_DEC_STEP(3);
+        // Using AV_WB32 directly confuses compiler
+        v = av_be2ne32(v << 8);
+        AV_WN32(dst, v);
+        dst += 3;
+        in += 4;
+    }
+    if (end - dst) {
+        BASE64_DEC_STEP(0);
+        BASE64_DEC_STEP(1);
+        BASE64_DEC_STEP(2);
+        BASE64_DEC_STEP(3);
+        *dst++ = v >> 16;
+        if (end - dst)
+            *dst++ = v >> 8;
+        if (end - dst)
+            *dst++ = v;
+        in += 4;
+    }
+    while (1) {
+        BASE64_DEC_STEP(0);
+        in++;
+        BASE64_DEC_STEP(0);
+        in++;
+        BASE64_DEC_STEP(0);
+        in++;
+        BASE64_DEC_STEP(0);
+        in++;
     }
 
-    return dst - out;
+out3:
+    *dst++ = v >> 10;
+    v <<= 2;
+out2:
+    *dst++ = v >> 4;
+out1:
+out0:
+    return bits & 1 ? -1 : dst - out;
 }
 
 /*****************************************************************************
@@ -82,15 +147,23 @@
         out_size < AV_BASE64_SIZE(in_size))
         return NULL;
     ret = dst = out;
+    while (bytes_remaining > 3) {
+        i_bits = AV_RB32(in);
+        in += 3; bytes_remaining -= 3;
+        *dst++ = b64[ i_bits>>26        ];
+        *dst++ = b64[(i_bits>>20) & 0x3F];
+        *dst++ = b64[(i_bits>>14) & 0x3F];
+        *dst++ = b64[(i_bits>>8 ) & 0x3F];
+    }
+    i_bits = 0;
     while (bytes_remaining) {
         i_bits = (i_bits << 8) + *in++;
         bytes_remaining--;
         i_shift += 8;
-
-        do {
-            *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f];
-            i_shift -= 6;
-        } while (i_shift > 6 || (bytes_remaining == 0 && i_shift > 0));
+    }
+    while (i_shift > 0) {
+        *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f];
+        i_shift -= 6;
     }
     while ((dst - ret) & 3)
         *dst++ = '=';
@@ -100,6 +173,7 @@
 }
 
 #ifdef TEST
+// LCOV_EXCL_START
 
 #undef printf
 
@@ -123,21 +197,40 @@
         return 1;
     }
 
-    if ((data2_size = av_base64_decode(data2, encoded, max_data2_size)) < 0) {
+    if ((data2_size = av_base64_decode(data2, encoded, max_data2_size)) != data_size) {
         printf("Failed: cannot decode the encoded string\n"
                "Encoded:\n%s\n", encoded);
         return 1;
     }
+    if ((data2_size = av_base64_decode(data2, encoded, data_size)) != data_size) {
+        printf("Failed: cannot decode with minimal buffer\n"
+               "Encoded:\n%s\n", encoded);
+        return 1;
+    }
     if (memcmp(data2, data, data_size)) {
         printf("Failed: encoded/decoded data differs from original data\n");
         return 1;
     }
+    if (av_base64_decode(NULL, encoded, 0) != 0) {
+        printf("Failed: decode to NULL buffer\n");
+        return 1;
+    }
+    if (strlen(encoded)) {
+        char *end = strchr(encoded, '=');
+        if (!end)
+            end = encoded + strlen(encoded) - 1;
+        *end = '%';
+        if (av_base64_decode(NULL, encoded, 0) >= 0) {
+            printf("Failed: error detection\n");
+            return 1;
+        }
+    }
 
     printf("Passed!\n");
     return 0;
 }
 
-int main(void)
+int main(int argc, char ** argv)
 {
     int i, error_count = 0;
     struct test {
@@ -153,12 +246,34 @@
         { "666666",  "NjY2NjY2"},
         { "abc:def", "YWJjOmRlZg=="},
     };
+    char in[1024], out[2048];
 
     printf("Encoding/decoding tests\n");
     for (i = 0; i < FF_ARRAY_ELEMS(tests); i++)
         error_count += test_encode_decode(tests[i].data, strlen(tests[i].data), tests[i].encoded_ref);
 
+    if (argc>1 && !strcmp(argv[1], "-t")) {
+        memset(in, 123, sizeof(in));
+        for(i=0; i<10000; i++){
+            START_TIMER
+            av_base64_encode(out, sizeof(out), in, sizeof(in));
+            STOP_TIMER("encode")
+        }
+        for(i=0; i<10000; i++){
+            START_TIMER
+            av_base64_decode(in, out, sizeof(in));
+            STOP_TIMER("decode")
+        }
+
+        for(i=0; i<10000; i++){
+            START_TIMER
+            av_base64_decode(NULL, out, 0);
+            STOP_TIMER("syntax check")
+        }
+    }
+
     return error_count;
 }
 
+// LCOV_EXCL_STOP
 #endif
diff --git a/libavutil/base64.h b/libavutil/base64.h
index 4750cf5..b095576 100644
--- a/libavutil/base64.h
+++ b/libavutil/base64.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/bfin/bswap.h b/libavutil/bfin/bswap.h
index 2837a2f..363ed40 100644
--- a/libavutil/bfin/bswap.h
+++ b/libavutil/bfin/bswap.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2007 Marc Hoffman
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/bfin/timer.h b/libavutil/bfin/timer.h
index 49d32a8..644573d 100644
--- a/libavutil/bfin/timer.h
+++ b/libavutil/bfin/timer.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2007 Marc Hoffman
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/blowfish.c b/libavutil/blowfish.c
index e6f07d6..cdc2952 100644
--- a/libavutil/blowfish.c
+++ b/libavutil/blowfish.c
@@ -4,20 +4,20 @@
  *
  * loosely based on Paul Kocher's implementation
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -294,24 +294,12 @@
       0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 }
 };
 
-static void F(AVBlowfish *ctx, uint32_t *xl, uint32_t *xr, int i)
-{
-    uint32_t Xl, Xr;
-    uint32_t y;
-
-    Xl = *xl;
-    Xr = *xr;
-
-    Xl ^= ctx->p[i];
-    y   = ctx->s[0][(Xl >> 24) & 0xFF];
-    y  += ctx->s[1][(Xl >> 16) & 0xFF];
-    y  ^= ctx->s[2][(Xl >>  8) & 0xFF];
-    y  += ctx->s[3][ Xl        & 0xFF];
-    Xr ^= y;
-
-    *xl = Xr;
-    *xr = Xl;
-}
+#define F(Xl, Xr, P) \
+    Xr ^=((( ctx->s[0][ Xl >> 24        ] \
+           + ctx->s[1][(Xl >> 16) & 0xFF])\
+           ^ ctx->s[2][(Xl >>  8) & 0xFF])\
+           + ctx->s[3][ Xl        & 0xFF])\
+           ^ P;
 
 av_cold void av_blowfish_init(AVBlowfish *ctx, const uint8_t *key, int key_len)
 {
@@ -358,17 +346,21 @@
     Xr = *xr;
 
     if (decrypt) {
-        for (i = AV_BF_ROUNDS + 1; i > 1; --i)
-            F(ctx, &Xl, &Xr, i);
+        Xl ^= ctx->p[AV_BF_ROUNDS + 1];
+        for (i = AV_BF_ROUNDS; i > 0; i-=2) {
+            F(Xl, Xr, ctx->p[i  ]);
+            F(Xr, Xl, ctx->p[i-1]);
+        }
 
-        Xl = Xl ^ ctx->p[1];
-        Xr = Xr ^ ctx->p[0];
+        Xr ^= ctx->p[0];
     } else {
-        for (i = 0; i < AV_BF_ROUNDS; ++i)
-            F(ctx, &Xl, &Xr, i);
+        Xl ^= ctx->p[0];
+        for (i = 1; i < AV_BF_ROUNDS+1; i+=2){
+            F(Xl, Xr, ctx->p[i  ]);
+            F(Xr, Xl, ctx->p[i+1]);
+        }
 
-        Xl = Xl ^ ctx->p[AV_BF_ROUNDS];
-        Xr = Xr ^ ctx->p[AV_BF_ROUNDS + 1];
+        Xr ^= ctx->p[AV_BF_ROUNDS + 1];
     }
 
     *xl = Xr;
diff --git a/libavutil/blowfish.h b/libavutil/blowfish.h
index 8c29536..0b00453 100644
--- a/libavutil/blowfish.h
+++ b/libavutil/blowfish.h
@@ -1,20 +1,21 @@
 /*
  * Blowfish algorithm
+ * Copyright (c) 2012 Samuel Pitoiset
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/bprint.c b/libavutil/bprint.c
new file mode 100644
index 0000000..373a492
--- /dev/null
+++ b/libavutil/bprint.c
@@ -0,0 +1,232 @@
+/*
+ * 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 <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include "avassert.h"
+#include "bprint.h"
+#include "common.h"
+#include "error.h"
+#include "mem.h"
+
+#define av_bprint_room(buf) ((buf)->size - FFMIN((buf)->len, (buf)->size))
+#define av_bprint_is_allocated(buf) ((buf)->str != (buf)->reserved_internal_buffer)
+
+static int av_bprint_alloc(AVBPrint *buf, unsigned room)
+{
+    char *old_str, *new_str;
+    unsigned min_size, new_size;
+
+    if (buf->size == buf->size_max)
+        return AVERROR(EIO);
+    if (!av_bprint_is_complete(buf))
+        return AVERROR_INVALIDDATA; /* it is already truncated anyway */
+    min_size = buf->len + 1 + FFMIN(UINT_MAX - buf->len - 1, room);
+    new_size = buf->size > buf->size_max / 2 ? buf->size_max : buf->size * 2;
+    if (new_size < min_size)
+        new_size = FFMIN(buf->size_max, min_size);
+    old_str = av_bprint_is_allocated(buf) ? buf->str : NULL;
+    new_str = av_realloc(old_str, new_size);
+    if (!new_str)
+        return AVERROR(ENOMEM);
+    if (!old_str)
+        memcpy(new_str, buf->str, buf->len + 1);
+    buf->str  = new_str;
+    buf->size = new_size;
+    return 0;
+}
+
+static void av_bprint_grow(AVBPrint *buf, unsigned extra_len)
+{
+    /* arbitrary margin to avoid small overflows */
+    extra_len = FFMIN(extra_len, UINT_MAX - 5 - buf->len);
+    buf->len += extra_len;
+    if (buf->size)
+        buf->str[FFMIN(buf->len, buf->size - 1)] = 0;
+}
+
+void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
+{
+    unsigned size_auto = (char *)buf + sizeof(*buf) -
+                         buf->reserved_internal_buffer;
+
+    if (size_max == 1)
+        size_max = size_auto;
+    buf->str      = buf->reserved_internal_buffer;
+    buf->len      = 0;
+    buf->size     = FFMIN(size_auto, size_max);
+    buf->size_max = size_max;
+    *buf->str = 0;
+    if (size_init > buf->size)
+        av_bprint_alloc(buf, size_init - 1);
+}
+
+void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size)
+{
+    buf->str      = buffer;
+    buf->len      = 0;
+    buf->size     = size;
+    buf->size_max = size;
+    *buf->str = 0;
+}
+
+void av_bprintf(AVBPrint *buf, const char *fmt, ...)
+{
+    unsigned room;
+    char *dst;
+    va_list vl;
+    int extra_len;
+
+    while (1) {
+        room = av_bprint_room(buf);
+        dst = room ? buf->str + buf->len : NULL;
+        va_start(vl, fmt);
+        extra_len = vsnprintf(dst, room, fmt, vl);
+        va_end(vl);
+        if (extra_len <= 0)
+            return;
+        if (extra_len < room)
+            break;
+        if (av_bprint_alloc(buf, extra_len))
+            break;
+    }
+    av_bprint_grow(buf, extra_len);
+}
+
+void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
+{
+    unsigned room, real_n;
+
+    while (1) {
+        room = av_bprint_room(buf);
+        if (n < room)
+            break;
+        if (av_bprint_alloc(buf, n))
+            break;
+    }
+    if (room) {
+        real_n = FFMIN(n, room - 1);
+        memset(buf->str + buf->len, c, real_n);
+    }
+    av_bprint_grow(buf, n);
+}
+
+void av_bprint_clear(AVBPrint *buf)
+{
+    if (buf->len) {
+        *buf->str = 0;
+        buf->len  = 0;
+    }
+}
+
+int av_bprint_finalize(AVBPrint *buf, char **ret_str)
+{
+    unsigned real_size = FFMIN(buf->len + 1, buf->size);
+    char *str;
+    int ret = 0;
+
+    if (ret_str) {
+        if (av_bprint_is_allocated(buf)) {
+            str = av_realloc(buf->str, real_size);
+            if (!str)
+                str = buf->str;
+            buf->str = NULL;
+        } else {
+            str = av_malloc(real_size);
+            if (str)
+                memcpy(str, buf->str, real_size);
+            else
+                ret = AVERROR(ENOMEM);
+        }
+        *ret_str = str;
+    } else {
+        if (av_bprint_is_allocated(buf))
+            av_freep(&buf->str);
+    }
+    buf->size = real_size;
+    return ret;
+}
+
+#ifdef TEST
+
+#undef printf
+
+static void bprint_pascal(AVBPrint *b, unsigned size)
+{
+    unsigned i, j;
+    unsigned p[42];
+
+    av_assert0(size < FF_ARRAY_ELEMS(p));
+
+    p[0] = 1;
+    av_bprintf(b, "%8d\n", 1);
+    for (i = 1; i <= size; i++) {
+        p[i] = 1;
+        for (j = i - 1; j > 0; j--)
+            p[j] = p[j] + p[j - 1];
+        for (j = 0; j <= i; j++)
+            av_bprintf(b, "%8d", p[j]);
+        av_bprintf(b, "\n");
+    }
+}
+
+int main(void)
+{
+    AVBPrint b;
+    char buf[256];
+
+    av_bprint_init(&b, 0, -1);
+    bprint_pascal(&b, 5);
+    printf("Short text in unlimited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
+    printf("%s\n", b.str);
+    av_bprint_finalize(&b, NULL);
+
+    av_bprint_init(&b, 0, -1);
+    bprint_pascal(&b, 25);
+    printf("Long text in unlimited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
+    av_bprint_finalize(&b, NULL);
+
+    av_bprint_init(&b, 0, 2048);
+    bprint_pascal(&b, 25);
+    printf("Long text in limited buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
+    av_bprint_finalize(&b, NULL);
+
+    av_bprint_init(&b, 0, 1);
+    bprint_pascal(&b, 5);
+    printf("Short text in automatic buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
+
+    av_bprint_init(&b, 0, 1);
+    bprint_pascal(&b, 25);
+    printf("Long text in automatic buffer: %u/%u\n", (unsigned)strlen(b.str)/8*8, b.len);
+    /* Note that the size of the automatic buffer is arch-dependant. */
+
+    av_bprint_init(&b, 0, 0);
+    bprint_pascal(&b, 25);
+    printf("Long text count only buffer: %u/%u\n", (unsigned)strlen(b.str), b.len);
+
+    av_bprint_init_for_buffer(&b, buf, sizeof(buf));
+    bprint_pascal(&b, 25);
+    printf("Long text count only buffer: %u/%u\n", (unsigned)strlen(buf), b.len);
+
+    return 0;
+}
+
+#endif
diff --git a/libavutil/bprint.h b/libavutil/bprint.h
new file mode 100644
index 0000000..2bef18d
--- /dev/null
+++ b/libavutil/bprint.h
@@ -0,0 +1,157 @@
+/*
+ * 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
+ */
+
+#ifndef AVUTIL_BPRINT_H
+#define AVUTIL_BPRINT_H
+
+#include "attributes.h"
+
+/**
+ * Define a structure with extra padding to a fixed size
+ * This helps ensuring binary compatibility with future versions.
+ */
+#define FF_PAD_STRUCTURE(size, ...) \
+    __VA_ARGS__ \
+    char reserved_padding[size - sizeof(struct { __VA_ARGS__ })];
+
+/**
+ * Buffer to print data progressively
+ *
+ * The string buffer grows as necessary and is always 0-terminated.
+ * The content of the string is never accessed, and thus is
+ * encoding-agnostic and can even hold binary data.
+ *
+ * Small buffers are kept in the structure itself, and thus require no
+ * memory allocation at all (unless the contents of the buffer is needed
+ * after the structure goes out of scope). This is almost as lightweight as
+ * declaring a local "char buf[512]".
+ *
+ * The length of the string can go beyond the allocated size: the buffer is
+ * then truncated, but the functions still keep account of the actual total
+ * length.
+ *
+ * In other words, buf->len can be greater than buf->size and records the
+ * total length of what would have been to the buffer if there had been
+ * enough memory.
+ *
+ * Append operations do not need to be tested for failure: if a memory
+ * allocation fails, data stop being appended to the buffer, but the length
+ * is still updated. This situation can be tested with
+ * av_bprint_is_complete().
+ *
+ * The size_max field determines several possible behaviours:
+ *
+ * size_max = -1 (= UINT_MAX) or any large value will let the buffer be
+ * reallocated as necessary, with an amortized linear cost.
+ *
+ * size_max = 0 prevents writing anything to the buffer: only the total
+ * length is computed. The write operations can then possibly be repeated in
+ * a buffer with exactly the necessary size
+ * (using size_init = size_max = len + 1).
+ *
+ * size_max = 1 is automatically replaced by the exact size available in the
+ * structure itself, thus ensuring no dynamic memory allocation. The
+ * internal buffer is large enough to hold a reasonable paragraph of text,
+ * such as the current paragraph.
+ */
+typedef struct AVBPrint {
+    FF_PAD_STRUCTURE(1024,
+    char *str;         /** string so far */
+    unsigned len;      /** length so far */
+    unsigned size;     /** allocated memory */
+    unsigned size_max; /** maximum allocated memory */
+    char reserved_internal_buffer[1];
+    )
+} AVBPrint;
+
+/**
+ * Convenience macros for special values for av_bprint_init() size_max
+ * parameter.
+ */
+#define AV_BPRINT_SIZE_UNLIMITED  ((unsigned)-1)
+#define AV_BPRINT_SIZE_AUTOMATIC  1
+#define AV_BPRINT_SIZE_COUNT_ONLY 0
+
+/**
+ * Init a print buffer.
+ *
+ * @param buf        buffer to init
+ * @param size_init  initial size (including the final 0)
+ * @param size_max   maximum size;
+ *                   0 means do not write anything, just count the length;
+ *                   1 is replaced by the maximum value for automatic storage;
+ *                   any large value means that the internal buffer will be
+ *                   reallocated as needed up to that limit; -1 is converted to
+ *                   UINT_MAX, the largest limit possible.
+ *                   Check also AV_BPRINT_SIZE_* macros.
+ */
+void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max);
+
+/**
+ * Init a print buffer using a pre-existing buffer.
+ *
+ * The buffer will not be reallocated.
+ *
+ * @param buf     buffer structure to init
+ * @param buffer  byte buffer to use for the string data
+ * @param size    size of buffer
+ */
+void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size);
+
+/**
+ * Append a formated string to a print buffer.
+ */
+void av_bprintf(AVBPrint *buf, const char *fmt, ...) av_printf_format(2, 3);
+
+/**
+ * Append char c n times to a print buffer.
+ */
+void av_bprint_chars(AVBPrint *buf, char c, unsigned n);
+
+/**
+ * Reset the string to "" but keep internal allocated data.
+ */
+void av_bprint_clear(AVBPrint *buf);
+
+/**
+ * Test if the print buffer is complete (not truncated).
+ *
+ * It may have been truncated due to a memory allocation failure
+ * or the size_max limit (compare size and size_max if necessary).
+ */
+static inline int av_bprint_is_complete(AVBPrint *buf)
+{
+    return buf->len < buf->size;
+}
+
+/**
+ * Finalize a print buffer.
+ *
+ * The print buffer can no longer be used afterwards,
+ * but the len and size fields are still valid.
+ *
+ * @arg[out] ret_str  if not NULL, used to return a permanent copy of the
+ *                    buffer contents, or NULL if memory allocation fails;
+ *                    if NULL, the buffer is discarded and freed
+ * @return  0 for success or error code (probably AVERROR(ENOMEM))
+ */
+int av_bprint_finalize(AVBPrint *buf, char **ret_str);
+
+#endif /* AVUTIL_BPRINT_H */
diff --git a/libavutil/bswap.h b/libavutil/bswap.h
index 8a350e1..06f6548 100644
--- a/libavutil/bswap.h
+++ b/libavutil/bswap.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/colorspace.h b/libavutil/colorspace.h
index 8757566..f438159 100644
--- a/libavutil/colorspace.h
+++ b/libavutil/colorspace.h
@@ -2,20 +2,20 @@
  * Colorspace conversion defines
  * Copyright (c) 2001, 2002, 2003 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/common.h b/libavutil/common.h
index c0e0fc5..9ed6f11 100644
--- a/libavutil/common.h
+++ b/libavutil/common.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -49,6 +49,8 @@
 #define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b))
 /* assume b>0 */
 #define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b))
+#define FFUDIV(a,b) (((a)>0 ?(a):(a)-(b)+1) / (b))
+#define FFUMOD(a,b) ((a)-(b)*FFUDIV(a,b))
 #define FFABS(a) ((a) >= 0 ? (a) : (-(a)))
 #define FFSIGN(a) ((a) > 0 ? 1 : -1)
 
@@ -64,6 +66,9 @@
 /* misc math functions */
 extern const uint8_t ff_log2_tab[256];
 
+/**
+ * Reverse the order of the bits of an 8-bits unsigned integer.
+ */
 #if FF_API_AV_REVERSE
 extern attribute_deprecated const uint8_t av_reverse[256];
 #endif
@@ -170,7 +175,7 @@
 static av_always_inline av_const int32_t av_clipl_int32_c(int64_t a)
 {
     if ((a+0x80000000u) & ~UINT64_C(0xFFFFFFFF)) return (a>>63) ^ 0x7FFFFFFF;
-    else                                         return a;
+    else                                         return (int32_t)a;
 }
 
 /**
@@ -253,7 +258,7 @@
  */
 static av_always_inline av_const int av_popcount64_c(uint64_t x)
 {
-    return av_popcount(x) + av_popcount(x >> 32);
+    return av_popcount((uint32_t)x) + av_popcount(x >> 32);
 }
 
 #define MKTAG(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((unsigned)(d) << 24))
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index 8db69be..f651cab 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -20,12 +20,15 @@
 #include "config.h"
 #include "opt.h"
 
-static int cpuflags_mask = -1, checked;
+static int flags, checked;
+
+void av_force_cpu_flags(int arg){
+    flags   = arg;
+    checked = arg != -1;
+}
 
 int av_get_cpu_flags(void)
 {
-    static int flags;
-
     if (checked)
         return flags;
 
@@ -33,16 +36,15 @@
     if (ARCH_PPC) flags = ff_get_cpu_flags_ppc();
     if (ARCH_X86) flags = ff_get_cpu_flags_x86();
 
-    flags  &= cpuflags_mask;
     checked = 1;
-
     return flags;
 }
 
 void av_set_cpu_flags_mask(int mask)
 {
-    cpuflags_mask = mask;
     checked       = 0;
+    flags         = av_get_cpu_flags() & mask;
+    checked       = 1;
 }
 
 int av_parse_cpu_flags(const char *s)
@@ -109,6 +111,50 @@
     return flags & INT_MAX;
 }
 
+int av_parse_cpu_caps(unsigned *flags, const char *s)
+{
+        static const AVOption cpuflags_opts[] = {
+        { "flags"   , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" },
+#if   ARCH_PPC
+        { "altivec" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ALTIVEC  },    .unit = "flags" },
+#elif ARCH_X86
+        { "mmx"     , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX      },    .unit = "flags" },
+        { "mmx2"    , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX2     },    .unit = "flags" },
+        { "mmxext"  , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_MMX2     },    .unit = "flags" },
+        { "sse"     , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE      },    .unit = "flags" },
+        { "sse2"    , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE2     },    .unit = "flags" },
+        { "sse2slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE2SLOW },    .unit = "flags" },
+        { "sse3"    , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE3     },    .unit = "flags" },
+        { "sse3slow", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE3SLOW },    .unit = "flags" },
+        { "ssse3"   , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSSE3    },    .unit = "flags" },
+        { "atom"    , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ATOM     },    .unit = "flags" },
+        { "sse4.1"  , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE4     },    .unit = "flags" },
+        { "sse4.2"  , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE42    },    .unit = "flags" },
+        { "avx"     , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AVX      },    .unit = "flags" },
+        { "xop"     , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_XOP      },    .unit = "flags" },
+        { "fma4"    , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_FMA4     },    .unit = "flags" },
+        { "3dnow"   , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_3DNOW    },    .unit = "flags" },
+        { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_3DNOWEXT },    .unit = "flags" },
+#elif ARCH_ARM
+        { "armv5te",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV5TE  },    .unit = "flags" },
+        { "armv6",    NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6    },    .unit = "flags" },
+        { "armv6t2",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6T2  },    .unit = "flags" },
+        { "vfp",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP      },    .unit = "flags" },
+        { "vfpv3",    NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFPV3    },    .unit = "flags" },
+        { "neon",     NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON     },    .unit = "flags" },
+#endif
+        { NULL },
+    };
+    static const AVClass class = {
+        .class_name = "cpuflags",
+        .item_name  = av_default_item_name,
+        .option     = cpuflags_opts,
+        .version    = LIBAVUTIL_VERSION_INT,
+    };
+    const AVClass *pclass = &class;
+
+    return av_opt_eval_flags(&pclass, &cpuflags_opts[0], s, flags);
+}
 #ifdef TEST
 
 #undef printf
diff --git a/libavutil/cpu.h b/libavutil/cpu.h
index 01f7201..c8f34e0 100644
--- a/libavutil/cpu.h
+++ b/libavutil/cpu.h
@@ -1,36 +1,34 @@
 /*
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #ifndef AVUTIL_CPU_H
 #define AVUTIL_CPU_H
 
-#include "version.h"
+#include "attributes.h"
 
 #define AV_CPU_FLAG_FORCE    0x80000000 /* force usage of selected flags (OR) */
 
     /* lower 16 bits - CPU features */
 #define AV_CPU_FLAG_MMX          0x0001 ///< standard MMX
 #define AV_CPU_FLAG_MMXEXT       0x0002 ///< SSE integer functions or AMD MMX ext
-#if LIBAVUTIL_VERSION_MAJOR < 52
 #define AV_CPU_FLAG_MMX2         0x0002 ///< SSE integer functions or AMD MMX ext
-#endif
 #define AV_CPU_FLAG_3DNOW        0x0004 ///< AMD 3DNOW
 #define AV_CPU_FLAG_SSE          0x0008 ///< SSE functions
 #define AV_CPU_FLAG_SSE2         0x0010 ///< PIV SSE2 functions
@@ -45,7 +43,11 @@
 #define AV_CPU_FLAG_AVX          0x4000 ///< AVX functions: requires OS support even if YMM registers aren't used
 #define AV_CPU_FLAG_XOP          0x0400 ///< Bulldozer XOP functions
 #define AV_CPU_FLAG_FMA4         0x0800 ///< Bulldozer FMA4 functions
-#define AV_CPU_FLAG_CMOV         0x1000 ///< i686 cmov
+// #if LIBAVUTIL_VERSION_MAJOR <52
+#define AV_CPU_FLAG_CMOV      0x1001000 ///< supports cmov instruction
+// #else
+// #define AV_CPU_FLAG_CMOV         0x1000 ///< supports cmov instruction
+// #endif
 
 #define AV_CPU_FLAG_ALTIVEC      0x0001 ///< standard
 
@@ -58,24 +60,46 @@
 
 /**
  * Return the flags which specify extensions supported by the CPU.
+ * The returned value is affected by av_force_cpu_flags() if that was used
+ * before. So av_get_cpu_flags() can easily be used in a application to
+ * detect the enabled cpu flags.
  */
 int av_get_cpu_flags(void);
 
 /**
+ * Disables cpu detection and forces the specified flags.
+ * -1 is a special case that disables forcing of specific flags.
+ */
+void av_force_cpu_flags(int flags);
+
+/**
  * Set a mask on flags returned by av_get_cpu_flags().
  * This function is mainly useful for testing.
+ * Please use av_force_cpu_flags() and av_get_cpu_flags() instead which are more flexible
  *
  * @warning this function is not thread safe.
  */
-void av_set_cpu_flags_mask(int mask);
+attribute_deprecated void av_set_cpu_flags_mask(int mask);
 
 /**
  * Parse CPU flags from a string.
  *
+ * The returned flags contain the specified flags as well as related unspecified flags.
+ *
+ * This function exists only for compatibility with libav.
+ * Please use av_parse_cpu_caps() when possible.
  * @return a combination of AV_CPU_* flags, negative on error.
  */
+attribute_deprecated
 int av_parse_cpu_flags(const char *s);
 
+/**
+ * Parse CPU caps from a string and update the given AV_CPU_* flags based on that.
+ *
+ * @return negative on error.
+ */
+int av_parse_cpu_caps(unsigned *flags, const char *s);
+
 /* The following CPU-specific functions shall not be called directly. */
 int ff_get_cpu_flags_arm(void);
 int ff_get_cpu_flags_ppc(void);
diff --git a/libavutil/crc.c b/libavutil/crc.c
index ee925d6..d640184 100644
--- a/libavutil/crc.c
+++ b/libavutil/crc.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/crc.h b/libavutil/crc.h
index 5c25607..1265054 100644
--- a/libavutil/crc.h
+++ b/libavutil/crc.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/crc_data.h b/libavutil/crc_data.h
index 8e4e6af..afa25e7 100644
--- a/libavutil/crc_data.h
+++ b/libavutil/crc_data.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2008 Aurelien Jacobs <aurel@gnuage.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/des.c b/libavutil/des.c
index c7c6f1d..32ac26f 100644
--- a/libavutil/des.c
+++ b/libavutil/des.c
@@ -2,20 +2,20 @@
  * DES encryption/decryption
  * Copyright (c) 2007 Reimar Doeffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include <inttypes.h>
@@ -286,7 +286,7 @@
     return in;
 }
 
-int av_des_init(AVDES *d, const uint8_t *key, int key_bits, int decrypt) {
+int av_des_init(AVDES *d, const uint8_t *key, int key_bits, av_unused int decrypt) {
     if (key_bits != 64 && key_bits != 192)
         return -1;
     d->triple_des = key_bits > 64;
@@ -337,6 +337,7 @@
 }
 
 #ifdef TEST
+// LCOV_EXCL_START
 #undef printf
 #undef rand
 #undef srand
@@ -414,10 +415,10 @@
     for (i = 0; i < 1000; i++) {
         key[0] = rand64(); key[1] = rand64(); key[2] = rand64();
         data = rand64();
-        av_des_init(&d, key, 192, 0);
-        av_des_crypt(&d, &ct, &data, 1, NULL, 0);
-        av_des_init(&d, key, 192, 1);
-        av_des_crypt(&d, &ct, &ct, 1, NULL, 1);
+        av_des_init(&d, (uint8_t*)key, 192, 0);
+        av_des_crypt(&d, (uint8_t*)&ct, (uint8_t*)&data, 1, NULL, 0);
+        av_des_init(&d, (uint8_t*)key, 192, 1);
+        av_des_crypt(&d, (uint8_t*)&ct, (uint8_t*)&ct, 1, NULL, 1);
         if (ct != data) {
             printf("Test 2 failed\n");
             return 1;
@@ -441,4 +442,5 @@
 #endif
     return 0;
 }
+// LCOV_EXCL_STOP
 #endif
diff --git a/libavutil/des.h b/libavutil/des.h
index cda9812..2feb046 100644
--- a/libavutil/des.h
+++ b/libavutil/des.h
@@ -2,20 +2,20 @@
  * DES encryption/decryption
  * Copyright (c) 2007 Reimar Doeffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/dict.c b/libavutil/dict.c
index 3c3194c..7e7d1cc 100644
--- a/libavutil/dict.c
+++ b/libavutil/dict.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2009 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -87,11 +87,11 @@
     }
     if (value) {
         if (flags & AV_DICT_DONT_STRDUP_KEY) {
-            m->elems[m->count].key  = key;
+            m->elems[m->count].key   = (char*)(intptr_t)key;
         } else
         m->elems[m->count].key  = av_strdup(key  );
         if (flags & AV_DICT_DONT_STRDUP_VAL) {
-            m->elems[m->count].value = value;
+            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)))
diff --git a/libavutil/dict.h b/libavutil/dict.h
index 492da9a..fde3650 100644
--- a/libavutil/dict.h
+++ b/libavutil/dict.h
@@ -1,25 +1,31 @@
 /*
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
  * @file
  * Public dictionary API.
+ * @deprecated
+ *  AVDictionary is provided for compatibility with libav. It is both in
+ *  implementation as well as API inefficient. It does not scale and is
+ *  extremely slow with large dictionaries.
+ *  It is recommended that new code uses our tree container from tree.c/h
+ *  where applicable, which uses AVL trees to achieve O(log n) performance.
  */
 
 #ifndef AVUTIL_DICT_H
diff --git a/libavutil/error.c b/libavutil/error.c
index c335cde..f49d214 100644
--- a/libavutil/error.c
+++ b/libavutil/error.c
@@ -1,53 +1,70 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#undef _GNU_SOURCE
 #include "avutil.h"
 #include "avstring.h"
 #include "common.h"
 
+struct error_entry {
+    int num;
+    const char *tag;
+    const char *str;
+};
+
+#define ERROR_TAG(tag) AVERROR_##tag, #tag
+static const struct error_entry error_entries[] = {
+    { ERROR_TAG(BSF_NOT_FOUND),      "Bitstream filter not found"                     },
+    { ERROR_TAG(BUG),                "Internal bug, should not have happened"         },
+    { ERROR_TAG(BUG2),               "Internal bug, should not have happened"         },
+    { ERROR_TAG(BUFFER_TOO_SMALL),   "Buffer too small"                               },
+    { ERROR_TAG(DECODER_NOT_FOUND),  "Decoder not found"                              },
+    { ERROR_TAG(DEMUXER_NOT_FOUND),  "Demuxer not found"                              },
+    { ERROR_TAG(ENCODER_NOT_FOUND),  "Encoder not found"                              },
+    { ERROR_TAG(EOF),                "End of file"                                    },
+    { ERROR_TAG(EXIT),               "Immediate exit requested"                       },
+    { ERROR_TAG(EXTERNAL),           "Generic error in an external library"           },
+    { ERROR_TAG(FILTER_NOT_FOUND),   "Filter not found"                               },
+    { ERROR_TAG(INVALIDDATA),        "Invalid data found when processing input"       },
+    { ERROR_TAG(MUXER_NOT_FOUND),    "Muxer not found"                                },
+    { ERROR_TAG(OPTION_NOT_FOUND),   "Option not found"                               },
+    { ERROR_TAG(PATCHWELCOME),       "Not yet implemented in FFmpeg, patches welcome" },
+    { ERROR_TAG(PROTOCOL_NOT_FOUND), "Protocol not found"                             },
+    { ERROR_TAG(STREAM_NOT_FOUND),   "Stream not found"                               },
+    { ERROR_TAG(UNKNOWN),            "Unknown error occurred"                         },
+};
+
 int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
 {
-    int ret = 0;
-    const char *errstr = NULL;
+    int ret = 0, i;
+    const struct error_entry *entry = NULL;
 
-    switch (errnum) {
-    case AVERROR_BSF_NOT_FOUND:     errstr = "Bitstream filter not found"                   ; break;
-    case AVERROR_DECODER_NOT_FOUND: errstr = "Decoder not found"                            ; break;
-    case AVERROR_DEMUXER_NOT_FOUND: errstr = "Demuxer not found"                            ; break;
-    case AVERROR_ENCODER_NOT_FOUND: errstr = "Encoder not found"                            ; break;
-    case AVERROR_EOF:               errstr = "End of file"                                  ; break;
-    case AVERROR_EXIT:              errstr = "Immediate exit requested"                     ; break;
-    case AVERROR_FILTER_NOT_FOUND:  errstr = "Filter not found"                             ; break;
-    case AVERROR_INVALIDDATA:       errstr = "Invalid data found when processing input"     ; break;
-    case AVERROR_MUXER_NOT_FOUND:   errstr = "Muxer not found"                              ; break;
-    case AVERROR_OPTION_NOT_FOUND:  errstr = "Option not found"                             ; break;
-    case AVERROR_PATCHWELCOME:      errstr = "Not yet implemented in Libav, patches welcome"; break;
-    case AVERROR_PROTOCOL_NOT_FOUND:errstr = "Protocol not found"                           ; break;
-    case AVERROR_STREAM_NOT_FOUND:  errstr = "Stream not found"                             ; break;
-    case AVERROR_BUG:               errstr = "Bug detected, please report the issue"        ; break;
-    case AVERROR_UNKNOWN:           errstr = "Unknown error occurred"                       ; break;
+    for (i = 0; i < FF_ARRAY_ELEMS(error_entries); i++) {
+        if (errnum == error_entries[i].num) {
+            entry = &error_entries[i];
+            break;
+        }
     }
-
-    if (errstr) {
-        av_strlcpy(errbuf, errstr, errbuf_size);
+    if (entry) {
+        av_strlcpy(errbuf, entry->str, errbuf_size);
     } else {
 #if HAVE_STRERROR_R
-        ret = strerror_r(AVUNERROR(errnum), errbuf, errbuf_size);
+        ret = AVERROR(strerror_r(AVUNERROR(errnum), errbuf, errbuf_size));
 #else
         ret = -1;
 #endif
@@ -57,3 +74,25 @@
 
     return ret;
 }
+
+#ifdef TEST
+
+#undef printf
+
+int main(void)
+{
+    int i;
+
+    for (i = 0; i < FF_ARRAY_ELEMS(error_entries); i++) {
+        const struct error_entry *entry = &error_entries[i];
+        printf("%d: %s [%s]\n", entry->num, av_err2str(entry->num), entry->tag);
+    }
+
+    for (i = 0; i < 256; i++) {
+        printf("%d: %s\n", -i, av_err2str(-i));
+    }
+
+    return 0;
+}
+
+#endif /* TEST */
diff --git a/libavutil/error.h b/libavutil/error.h
index 61d5fb9..1768167 100644
--- a/libavutil/error.h
+++ b/libavutil/error.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,7 +26,6 @@
 
 #include <errno.h>
 #include <stddef.h>
-#include "avutil.h"
 
 /**
  * @addtogroup lavu_error
@@ -45,21 +44,33 @@
 #define AVUNERROR(e) (e)
 #endif
 
-#define AVERROR_BSF_NOT_FOUND      (-0x39acbd08) ///< Bitstream filter not found
-#define AVERROR_DECODER_NOT_FOUND  (-0x3cbabb08) ///< Decoder not found
-#define AVERROR_DEMUXER_NOT_FOUND  (-0x32babb08) ///< Demuxer not found
-#define AVERROR_ENCODER_NOT_FOUND  (-0x3cb1ba08) ///< Encoder not found
-#define AVERROR_EOF                (-0x5fb9b0bb) ///< End of file
-#define AVERROR_EXIT               (-0x2bb6a7bb) ///< Immediate exit was requested; the called function should not be restarted
-#define AVERROR_FILTER_NOT_FOUND   (-0x33b6b908) ///< Filter not found
-#define AVERROR_INVALIDDATA        (-0x3ebbb1b7) ///< Invalid data found when processing input
-#define AVERROR_MUXER_NOT_FOUND    (-0x27aab208) ///< Muxer not found
-#define AVERROR_OPTION_NOT_FOUND   (-0x2bafb008) ///< Option not found
-#define AVERROR_PATCHWELCOME       (-0x3aa8beb0) ///< Not yet implemented in Libav, patches welcome
-#define AVERROR_PROTOCOL_NOT_FOUND (-0x30adaf08) ///< Protocol not found
-#define AVERROR_STREAM_NOT_FOUND   (-0x2dabac08) ///< Stream not found
-#define AVERROR_BUG                (-0x5fb8aabe) ///< Bug detected, please report the issue
-#define AVERROR_UNKNOWN            (-0x31b4b1ab) ///< Unknown error, typically from an external library
+#define FFERRTAG(a, b, c, d) (-(int)MKTAG(a, b, c, d))
+
+#define AVERROR_BSF_NOT_FOUND      FFERRTAG(0xF8,'B','S','F') ///< Bitstream filter not found
+#define AVERROR_BUG                FFERRTAG( 'B','U','G','!') ///< Internal bug, also see AVERROR_BUG2
+#define AVERROR_BUFFER_TOO_SMALL   FFERRTAG( 'B','U','F','S') ///< Buffer too small
+#define AVERROR_DECODER_NOT_FOUND  FFERRTAG(0xF8,'D','E','C') ///< Decoder not found
+#define AVERROR_DEMUXER_NOT_FOUND  FFERRTAG(0xF8,'D','E','M') ///< Demuxer not found
+#define AVERROR_ENCODER_NOT_FOUND  FFERRTAG(0xF8,'E','N','C') ///< Encoder not found
+#define AVERROR_EOF                FFERRTAG( 'E','O','F',' ') ///< End of file
+#define AVERROR_EXIT               FFERRTAG( 'E','X','I','T') ///< Immediate exit was requested; the called function should not be restarted
+#define AVERROR_EXTERNAL           FFERRTAG( 'E','X','T',' ') ///< Generic error in an external library
+#define AVERROR_FILTER_NOT_FOUND   FFERRTAG(0xF8,'F','I','L') ///< Filter not found
+#define AVERROR_INVALIDDATA        FFERRTAG( 'I','N','D','A') ///< Invalid data found when processing input
+#define AVERROR_MUXER_NOT_FOUND    FFERRTAG(0xF8,'M','U','X') ///< Muxer not found
+#define AVERROR_OPTION_NOT_FOUND   FFERRTAG(0xF8,'O','P','T') ///< Option not found
+#define AVERROR_PATCHWELCOME       FFERRTAG( 'P','A','W','E') ///< Not yet implemented in FFmpeg, patches welcome
+#define AVERROR_PROTOCOL_NOT_FOUND FFERRTAG(0xF8,'P','R','O') ///< Protocol not found
+#define AVERROR_STREAM_NOT_FOUND   FFERRTAG(0xF8,'S','T','R') ///< Stream not found
+
+/**
+ * This is semantically identical to AVERROR_BUG
+ * it has been introduced in Libav after our AVERROR_BUG and with a modified value.
+ */
+#define AVERROR_BUG2               FFERRTAG( 'B','U','G',' ')
+#define AVERROR_UNKNOWN            FFERRTAG( 'U','N','K','N') ///< Unknown error, typically from an external library
+
+#define AV_ERROR_MAX_STRING_SIZE 64
 
 /**
  * Put a description of the AVERROR code errnum in errbuf.
@@ -76,6 +87,29 @@
 int av_strerror(int errnum, char *errbuf, size_t errbuf_size);
 
 /**
+ * Fill the provided buffer with a string containing an error string
+ * corresponding to the AVERROR code errnum.
+ *
+ * @param errbuf         a buffer
+ * @param errbuf_size    size in bytes of errbuf
+ * @param errnum         error code to describe
+ * @return the buffer in input, filled with the error description
+ * @see av_strerror()
+ */
+static inline char *av_make_error_string(char *errbuf, size_t errbuf_size, int errnum)
+{
+    av_strerror(errnum, errbuf, errbuf_size);
+    return errbuf;
+}
+
+/**
+ * Convenience macro, the return value should be used only directly in
+ * function arguments but never stand-alone.
+ */
+#define av_err2str(errnum) \
+    av_make_error_string((char[AV_ERROR_MAX_STRING_SIZE]){0}, AV_ERROR_MAX_STRING_SIZE, errnum)
+
+/**
  * @}
  */
 
diff --git a/libavutil/eval.c b/libavutil/eval.c
index 9d17930..931ad6b 100644
--- a/libavutil/eval.c
+++ b/libavutil/eval.c
@@ -2,20 +2,20 @@
  * Copyright (c) 2002-2006 Michael Niedermayer <michaelni@gmx.at>
  * Copyright (c) 2006 Oded Shimon <ods15@ods15.dyndns.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,6 +26,7 @@
  * see http://joe.hotchkiss.com/programming/eval/eval.html
  */
 
+#include <float.h>
 #include "avutil.h"
 #include "common.h"
 #include "eval.h"
@@ -46,7 +47,7 @@
     int log_offset;
     void *log_ctx;
 #define VARS 10
-    double var[VARS];
+    double *var;
 } Parser;
 
 static const AVClass class = { "Eval", av_default_item_name, NULL, LIBAVUTIL_VERSION_INT, offsetof(Parser,log_offset), offsetof(Parser,log_ctx) };
@@ -74,11 +75,23 @@
     ['Y'-'E']=  24,
 };
 
+static const struct {
+    const char *name;
+    double value;
+} constants[] = {
+    { "E",   M_E   },
+    { "PI",  M_PI  },
+    { "PHI", M_PHI },
+};
+
 double av_strtod(const char *numstr, char **tail)
 {
     double d;
     char *next;
-    d = strtod(numstr, &next);
+    if(numstr[0]=='0' && (numstr[1]|0x20)=='x') {
+        d = strtoul(numstr, &next, 16);
+    } else
+        d = strtod(numstr, &next);
     /* if parsing succeeded, check for and interpret postfixes */
     if (next!=numstr) {
         if (*next >= 'E' && *next <= 'z') {
@@ -124,8 +137,9 @@
         e_squish, e_gauss, e_ld, e_isnan, e_isinf,
         e_mod, e_max, e_min, e_eq, e_gt, e_gte,
         e_pow, e_mul, e_div, e_add,
-        e_last, e_st, e_while, e_floor, e_ceil, e_trunc,
-        e_sqrt, e_not,
+        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,
     } type;
     double value; // is sign in other types
     union {
@@ -134,7 +148,8 @@
         double (*func1)(void *, double);
         double (*func2)(void *, double, double);
     } a;
-    struct AVExpr *param[2];
+    struct AVExpr *param[3];
+    double *var;
 };
 
 static double eval_expr(Parser *p, AVExpr *e)
@@ -154,18 +169,88 @@
         case e_ceil :  return e->value * ceil (eval_expr(p, e->param[0]));
         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_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_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];
+            r= r*1664525+1013904223;
+            p->var[idx]= r;
+            return e->value * (r * (1.0/UINT64_MAX));
+        }
         case e_while: {
             double d = NAN;
             while (eval_expr(p, e->param[0]))
                 d=eval_expr(p, e->param[1]);
             return d;
         }
+        case e_taylor: {
+            double t = 1, d = 0, v;
+            double x = eval_expr(p, e->param[1]);
+            int id = e->param[2] ? av_clip(eval_expr(p, e->param[2]), 0, VARS-1) : 0;
+            int i;
+            double var0 = p->var[id];
+            for(i=0; i<1000; i++) {
+                double ld = d;
+                p->var[id] = i;
+                v = eval_expr(p, e->param[0]);
+                d += t*v;
+                if(ld==d && v)
+                    break;
+                t *= x / (i+1);
+            }
+            p->var[id] = var0;
+            return d;
+        }
+        case e_root: {
+            int i, j;
+            double low = -1, high = -1, v, low_v = -DBL_MAX, high_v = DBL_MAX;
+            double var0 = p->var[0];
+            double x_max = eval_expr(p, e->param[1]);
+            for(i=-1; i<1024; i++) {
+                if(i<255) {
+                    p->var[0] = av_reverse[i&255]*x_max/255;
+                } else {
+                    p->var[0] = x_max*pow(0.9, i-255);
+                    if (i&1) p->var[0] *= -1;
+                    if (i&2) p->var[0] += low;
+                    else     p->var[0] += high;
+                }
+                v = eval_expr(p, e->param[0]);
+                if (v<=0 && v>low_v) {
+                    low    = p->var[0];
+                    low_v  = v;
+                }
+                if (v>=0 && v<high_v) {
+                    high   = p->var[0];
+                    high_v = v;
+                }
+                if (low>=0 && high>=0){
+                    for (j=0; j<1000; j++) {
+                        p->var[0] = (low+high)*0.5;
+                        if (low == p->var[0] || high == p->var[0])
+                            break;
+                        v = eval_expr(p, e->param[0]);
+                        if (v<=0) low = p->var[0];
+                        if (v>=0) high= p->var[0];
+                        if (isnan(v)) {
+                            low = high = v;
+                            break;
+                        }
+                    }
+                    break;
+                }
+            }
+            p->var[0] = var0;
+            return -low_v<high_v ? low : high;
+        }
         default: {
             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_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);
                 case e_eq:  return e->value * (d == d2 ? 1.0 : 0.0);
@@ -173,10 +258,11 @@
                 case e_gte: return e->value * (d >= d2 ? 1.0 : 0.0);
                 case e_pow: return e->value * pow(d, d2);
                 case e_mul: return e->value * (d * d2);
-                case e_div: return e->value * (d / d2);
+                case e_div: return e->value * ((!CONFIG_FTRAPV || d2 ) ? (d / d2) : d * INFINITY);
                 case e_add: return e->value * (d + d2);
                 case e_last:return e->value * d2;
                 case e_st : return e->value * (p->var[av_clip(d, 0, VARS-1)]= d2);
+                case e_hypot:return e->value * (sqrt(d*d + d2*d2));
             }
         }
     }
@@ -190,6 +276,8 @@
     if (!e) return;
     av_expr_free(e->param[0]);
     av_expr_free(e->param[1]);
+    av_expr_free(e->param[2]);
+    av_freep(&e->var);
     av_freep(&e);
 }
 
@@ -222,6 +310,15 @@
             return 0;
         }
     }
+    for (i = 0; i < FF_ARRAY_ELEMS(constants); i++) {
+        if (strmatch(p->s, constants[i].name)) {
+            p->s += strlen(constants[i].name);
+            d->type = e_value;
+            d->value = constants[i].value;
+            *e = d;
+            return 0;
+        }
+    }
 
     p->s= strchr(p->s, '(');
     if (p->s==NULL) {
@@ -252,6 +349,10 @@
         p->s++; // ","
         parse_expr(&d->param[1], p);
     }
+    if (p->s[0]== ',') {
+        p->s++; // ","
+        parse_expr(&d->param[2], p);
+    }
     if (p->s[0] != ')') {
         av_log(p, AV_LOG_ERROR, "Missing ')' or too many args in '%s'\n", s0);
         av_expr_free(d);
@@ -287,11 +388,19 @@
     else if (strmatch(next, "isinf" )) d->type = e_isinf;
     else if (strmatch(next, "st"    )) d->type = e_st;
     else if (strmatch(next, "while" )) d->type = e_while;
+    else if (strmatch(next, "taylor")) d->type = e_taylor;
+    else if (strmatch(next, "root"  )) d->type = e_root;
     else if (strmatch(next, "floor" )) d->type = e_floor;
     else if (strmatch(next, "ceil"  )) d->type = e_ceil;
     else if (strmatch(next, "trunc" )) d->type = e_trunc;
     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, "random")) d->type = e_random;
+    else if (strmatch(next, "hypot" )) d->type = e_hypot;
+    else if (strmatch(next, "gcd"   )) d->type = e_gcd;
+    else if (strmatch(next, "if"    )) d->type = e_if;
+    else if (strmatch(next, "ifnot" )) d->type = e_ifnot;
     else {
         for (i=0; p->func1_names && p->func1_names[i]; i++) {
             if (strmatch(next, p->func1_names[i])) {
@@ -462,8 +571,12 @@
         case e_trunc:
         case e_sqrt:
         case e_not:
-            return verify_expr(e->param[0]);
-        default: return verify_expr(e->param[0]) && verify_expr(e->param[1]);
+        case e_random:
+            return verify_expr(e->param[0]) && !e->param[1];
+        case e_taylor:
+            return verify_expr(e->param[0]) && verify_expr(e->param[1])
+                   && (!e->param[2] || verify_expr(e->param[2]));
+        default: return verify_expr(e->param[0]) && verify_expr(e->param[1]) && !e->param[2];
     }
 }
 
@@ -511,6 +624,7 @@
         ret = AVERROR(EINVAL);
         goto end;
     }
+    e->var= av_mallocz(sizeof(double) *VARS);
     *expr = e;
 end:
     av_free(w);
@@ -520,6 +634,7 @@
 double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
 {
     Parser p = { 0 };
+    p.var= e->var;
 
     p.const_values = const_values;
     p.opaque     = opaque;
@@ -544,7 +659,42 @@
     return isnan(*d) ? AVERROR(EINVAL) : 0;
 }
 
+#if FF_API_OLD_EVAL_NAMES
+// LCOV_EXCL_START
+int av_parse_expr(AVExpr **expr, const char *s,
+                  const char * const *const_names,
+                  const char * const *func1_names, double (* const *funcs1)(void *, double),
+                  const char * const *func2_names, double (* const *funcs2)(void *, double, double),
+                  int log_offset, void *log_ctx)
+{
+    return av_expr_parse(expr, s, const_names, func1_names, funcs1, func2_names, funcs2,
+                      log_offset, log_ctx);
+}
+
+double av_eval_expr(AVExpr *e, const double *const_values, void *opaque)
+{
+    return av_expr_eval(e, const_values, opaque);
+}
+
+int av_parse_and_eval_expr(double *res, const char *s,
+                           const char * const *const_names, const double *const_values,
+                           const char * const *func1_names, double (* const *funcs1)(void *, double),
+                           const char * const *func2_names, double (* const *funcs2)(void *, double, double),
+                           void *opaque, int log_offset, void *log_ctx)
+{
+    return av_expr_parse_and_eval(res, s, const_names, const_values, func1_names, funcs1, func2_names, funcs2,
+                                  opaque, log_offset, log_ctx);
+}
+
+void av_free_expr(AVExpr *e)
+{
+    av_expr_free(e);
+}
+// LCOV_EXCL_STOP
+#endif /* FF_API_OLD_EVAL_NAMES */
+
 #ifdef TEST
+// LCOV_EXCL_START
 #undef printf
 #include <string.h>
 
@@ -629,6 +779,17 @@
         "not(1)",
         "not(NAN)",
         "not(0)",
+        "pow(0,1.23)",
+        "pow(PI,1.23)",
+        "PI^1.23",
+        "pow(-1,1.23)",
+        "if(1, 2)",
+        "ifnot(0, 23)",
+        "ifnot(1, NaN) + if(0, 1)",
+        "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)",
+        "root(sin(ld(0))+6+sin(ld(0)/12)-log(ld(0)), 100)",
         NULL
     };
 
@@ -664,4 +825,5 @@
 
     return 0;
 }
+// LCOV_EXCL_STOP
 #endif
diff --git a/libavutil/eval.h b/libavutil/eval.h
index ccb29e7..22fa121 100644
--- a/libavutil/eval.h
+++ b/libavutil/eval.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -91,6 +91,39 @@
  */
 void av_expr_free(AVExpr *e);
 
+#if FF_API_OLD_EVAL_NAMES
+/**
+ * @deprecated Deprecated in favor of av_expr_parse_and_eval().
+ */
+attribute_deprecated
+int av_parse_and_eval_expr(double *res, const char *s,
+                           const char * const *const_names, const double *const_values,
+                           const char * const *func1_names, double (* const *funcs1)(void *, double),
+                           const char * const *func2_names, double (* const *funcs2)(void *, double, double),
+                           void *opaque, int log_offset, void *log_ctx);
+
+/**
+ * @deprecated Deprecated in favor of av_expr_parse().
+ */
+attribute_deprecated
+int av_parse_expr(AVExpr **expr, const char *s,
+                  const char * const *const_names,
+                  const char * const *func1_names, double (* const *funcs1)(void *, double),
+                  const char * const *func2_names, double (* const *funcs2)(void *, double, double),
+                  int log_offset, void *log_ctx);
+/**
+ * @deprecated Deprecated in favor of av_expr_eval().
+ */
+attribute_deprecated
+double av_eval_expr(AVExpr *e, const double *const_values, void *opaque);
+
+/**
+ * @deprecated Deprecated in favor of av_expr_free().
+ */
+attribute_deprecated
+void av_free_expr(AVExpr *e);
+#endif /* FF_API_OLD_EVAL_NAMES */
+
 /**
  * Parse the string in numstr and return its value as a double. If
  * the string is empty, contains only whitespaces, or does not contain
diff --git a/libavutil/fifo.c b/libavutil/fifo.c
index 5774d33..47328c4 100644
--- a/libavutil/fifo.c
+++ b/libavutil/fifo.c
@@ -3,20 +3,20 @@
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  * Copyright (c) 2006 Roman Shaposhnik
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "common.h"
@@ -25,7 +25,7 @@
 AVFifoBuffer *av_fifo_alloc(unsigned int size)
 {
     AVFifoBuffer *f= av_mallocz(sizeof(AVFifoBuffer));
-    if(!f)
+    if (!f)
         return NULL;
     f->buffer = av_malloc(size);
     f->end = f->buffer + size;
@@ -37,8 +37,8 @@
 
 void av_fifo_free(AVFifoBuffer *f)
 {
-    if(f){
-        av_free(f->buffer);
+    if (f) {
+        av_freep(&f->buffer);
         av_free(f);
     }
 }
@@ -59,45 +59,64 @@
     return f->end - f->buffer - av_fifo_size(f);
 }
 
-int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size) {
-    unsigned int old_size= f->end - f->buffer;
+int av_fifo_realloc2(AVFifoBuffer *f, unsigned int new_size)
+{
+    unsigned int old_size = f->end - f->buffer;
 
-    if(old_size < new_size){
-        int len= av_fifo_size(f);
-        AVFifoBuffer *f2= av_fifo_alloc(new_size);
+    if (old_size < new_size) {
+        int len = av_fifo_size(f);
+        AVFifoBuffer *f2 = av_fifo_alloc(new_size);
 
         if (!f2)
-            return -1;
+            return AVERROR(ENOMEM);
         av_fifo_generic_read(f, f2->buffer, len, NULL);
         f2->wptr += len;
         f2->wndx += len;
         av_free(f->buffer);
-        *f= *f2;
+        *f = *f2;
         av_free(f2);
     }
     return 0;
 }
 
+int av_fifo_grow(AVFifoBuffer *f, unsigned int size)
+{
+    unsigned int old_size = f->end - f->buffer;
+    if(size + (unsigned)av_fifo_size(f) < size)
+        return AVERROR(EINVAL);
+
+    size += av_fifo_size(f);
+
+    if (old_size < size)
+        return av_fifo_realloc2(f, FFMAX(size, 2*size));
+    return 0;
+}
+
 // src must NOT be const as it can be a context for func that may need updating (like a pointer or byte counter)
 int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int (*func)(void*, void*, int))
 {
     int total = size;
+    uint32_t wndx= f->wndx;
+    uint8_t *wptr= f->wptr;
+
     do {
-        int len = FFMIN(f->end - f->wptr, size);
-        if(func) {
-            if(func(src, f->wptr, len) <= 0)
+        int len = FFMIN(f->end - wptr, size);
+        if (func) {
+            if (func(src, wptr, len) <= 0)
                 break;
         } else {
-            memcpy(f->wptr, src, len);
+            memcpy(wptr, src, len);
             src = (uint8_t*)src + len;
         }
 // Write memory barrier needed for SMP here in theory
-        f->wptr += len;
-        if (f->wptr >= f->end)
-            f->wptr = f->buffer;
-        f->wndx += len;
+        wptr += len;
+        if (wptr >= f->end)
+            wptr = f->buffer;
+        wndx += len;
         size -= len;
     } while (size > 0);
+    f->wndx= wndx;
+    f->wptr= wptr;
     return total - size;
 }
 
diff --git a/libavutil/fifo.h b/libavutil/fifo.h
index e670175..ff66c95 100644
--- a/libavutil/fifo.h
+++ b/libavutil/fifo.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -95,6 +95,8 @@
 
 /**
  * Resize an AVFifoBuffer.
+ * In case of reallocation failure, the old FIFO is kept unchanged.
+ *
  * @param f AVFifoBuffer to resize
  * @param size new AVFifoBuffer size in bytes
  * @return <0 for failure, >=0 otherwise
@@ -102,6 +104,17 @@
 int av_fifo_realloc2(AVFifoBuffer *f, unsigned int size);
 
 /**
+ * Enlarge an AVFifoBuffer.
+ * In case of reallocation failure, the old FIFO is kept unchanged.
+ * The new fifo size may be larger than the requested size.
+ *
+ * @param f AVFifoBuffer to resize
+ * @param additional_space the amount of space in bytes to allocate in addition to av_fifo_size()
+ * @return <0 for failure, >=0 otherwise
+ */
+int av_fifo_grow(AVFifoBuffer *f, unsigned int additional_space);
+
+/**
  * Read and discard the specified amount of data from an AVFifoBuffer.
  * @param f AVFifoBuffer to read from
  * @param size amount of data to read in bytes
diff --git a/libavutil/file.c b/libavutil/file.c
index 41bd0dd..5aa4b9c 100644
--- a/libavutil/file.c
+++ b/libavutil/file.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -133,3 +133,69 @@
     av_free(bufptr);
 #endif
 }
+
+int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx) {
+    FileLogContext file_log_ctx = { &file_log_ctx_class, log_offset, log_ctx };
+    int fd=-1;
+#if !HAVE_MKSTEMP
+    void *ptr= tempnam(NULL, prefix);
+    if(!ptr)
+        ptr= tempnam(".", prefix);
+    *filename = av_strdup(ptr);
+#undef free
+    free(ptr);
+#else
+    size_t len = strlen(prefix) + 12; /* room for "/tmp/" and "XXXXXX\0" */
+    *filename = av_malloc(len);
+#endif
+    /* -----common section-----*/
+    if (*filename == NULL) {
+        av_log(&file_log_ctx, AV_LOG_ERROR, "ff_tempfile: Cannot allocate file name\n");
+        return AVERROR(ENOMEM);
+    }
+#if !HAVE_MKSTEMP
+#   ifndef O_BINARY
+#       define O_BINARY 0
+#   endif
+#   ifndef O_EXCL
+#       define O_EXCL 0
+#   endif
+    fd = open(*filename, O_RDWR | O_BINARY | O_CREAT | O_EXCL, 0600);
+#else
+    snprintf(*filename, len, "/tmp/%sXXXXXX", prefix);
+    fd = mkstemp(*filename);
+#ifdef _WIN32
+    if (fd < 0) {
+        snprintf(*filename, len, "./%sXXXXXX", prefix);
+        fd = mkstemp(*filename);
+    }
+#endif
+#endif
+    /* -----common section-----*/
+    if (fd < 0) {
+        int err = AVERROR(errno);
+        av_log(&file_log_ctx, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename);
+        av_freep(filename);
+        return err;
+    }
+    return fd; /* success */
+}
+
+#ifdef TEST
+
+#undef printf
+
+int main(void)
+{
+    uint8_t *buf;
+    size_t size;
+    if (av_file_map("file.c", &buf, &size, 0, NULL) < 0)
+        return 1;
+
+    buf[0] = 's';
+    printf("%s", buf);
+    av_file_unmap(buf, size);
+    return 0;
+}
+#endif
+
diff --git a/libavutil/file.h b/libavutil/file.h
index e3f02a8..f637005 100644
--- a/libavutil/file.h
+++ b/libavutil/file.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -51,4 +51,13 @@
  */
 void av_file_unmap(uint8_t *bufptr, size_t size);
 
+/**
+ * Wrapper to work around the lack of mkstemp() on mingw.
+ * Also, tries to create file in /tmp first, if possible.
+ * *prefix can be a character constant; *filename will be allocated internally.
+ * @return file descriptor of opened file (or -1 on error)
+ * and opened file name in **filename.
+ */
+int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_ctx);
+
 #endif /* AVUTIL_FILE_H */
diff --git a/libavutil/float_dsp.c b/libavutil/float_dsp.c
index 2e90939..f5a8360 100644
--- a/libavutil/float_dsp.c
+++ b/libavutil/float_dsp.c
@@ -1,18 +1,21 @@
 /*
- * This file is part of Libav.
+ * Copyright 2005 Balatoni Denes
+ * Copyright 2006 Loren Merritt
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/float_dsp.h b/libavutil/float_dsp.h
index 95cef62..735eb34 100644
--- a/libavutil/float_dsp.h
+++ b/libavutil/float_dsp.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c
index e661e1b..57ee07d 100644
--- a/libavutil/imgutils.c
+++ b/libavutil/imgutils.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,6 +24,7 @@
 #include "common.h"
 #include "imgutils.h"
 #include "internal.h"
+#include "intreadwrite.h"
 #include "log.h"
 #include "pixdesc.h"
 
@@ -45,27 +46,45 @@
     }
 }
 
+static inline
+int image_get_linesize(int width, int plane,
+                       int max_step, int max_step_comp,
+                       const AVPixFmtDescriptor *desc)
+{
+    int s, shifted_w, linesize;
+
+    if (!desc)
+        return AVERROR(EINVAL);
+
+    if (width < 0)
+        return AVERROR(EINVAL);
+    s = (max_step_comp == 1 || max_step_comp == 2) ? desc->log2_chroma_w : 0;
+    shifted_w = ((width + (1 << s) - 1)) >> s;
+    if (shifted_w && max_step > INT_MAX / shifted_w)
+        return AVERROR(EINVAL);
+    linesize = max_step * shifted_w;
+
+    if (desc->flags & PIX_FMT_BITSTREAM)
+        linesize = (linesize + 7) >> 3;
+    return linesize;
+}
+
 int av_image_get_linesize(enum AVPixelFormat pix_fmt, int width, int plane)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     int max_step     [4];       /* max pixel step for each plane */
     int max_step_comp[4];       /* the component for each plane which has the max pixel step */
-    int s;
 
-    if (!desc)
+    if ((unsigned)pix_fmt >= AV_PIX_FMT_NB || desc->flags & PIX_FMT_HWACCEL)
         return AVERROR(EINVAL);
 
-    if (desc->flags & PIX_FMT_BITSTREAM)
-        return (width * (desc->comp[0].step_minus1+1) + 7) >> 3;
-
     av_image_fill_max_pixsteps(max_step, max_step_comp, desc);
-    s = (max_step_comp[plane] == 1 || max_step_comp[plane] == 2) ? desc->log2_chroma_w : 0;
-    return max_step[plane] * (((width + (1 << s) - 1)) >> s);
+    return image_get_linesize(width, plane, max_step[plane], max_step_comp[plane], desc);
 }
 
 int av_image_fill_linesizes(int linesizes[4], enum AVPixelFormat pix_fmt, int width)
 {
-    int i;
+    int i, ret;
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     int max_step     [4];       /* max pixel step for each plane */
     int max_step_comp[4];       /* the component for each plane which has the max pixel step */
@@ -75,20 +94,11 @@
     if (!desc || desc->flags & PIX_FMT_HWACCEL)
         return AVERROR(EINVAL);
 
-    if (desc->flags & PIX_FMT_BITSTREAM) {
-        if (width > (INT_MAX -7) / (desc->comp[0].step_minus1+1))
-            return AVERROR(EINVAL);
-        linesizes[0] = (width * (desc->comp[0].step_minus1+1) + 7) >> 3;
-        return 0;
-    }
-
     av_image_fill_max_pixsteps(max_step, max_step_comp, desc);
     for (i = 0; i < 4; i++) {
-        int s = (max_step_comp[i] == 1 || max_step_comp[i] == 2) ? desc->log2_chroma_w : 0;
-        int shifted_w = ((width + (1 << s) - 1)) >> s;
-        if (max_step[i] > INT_MAX / shifted_w)
-            return AVERROR(EINVAL);
-        linesizes[i] = max_step[i] * shifted_w;
+        if ((ret = image_get_linesize(width, i, max_step[i], max_step_comp[i], desc)) < 0)
+            return ret;
+        linesizes[i] = ret;
     }
 
     return 0;
@@ -170,7 +180,7 @@
         default:
             return AVERROR(EINVAL);
         }
-        pal[i] = b + (g<<8) + (r<<16);
+        pal[i] = b + (g<<8) + (r<<16) + (0xFF<<24);
     }
 
     return 0;
@@ -188,7 +198,7 @@
 
     if ((ret = av_image_check_size(w, h, 0, NULL)) < 0)
         return ret;
-    if ((ret = av_image_fill_linesizes(linesizes, pix_fmt, w)) < 0)
+    if ((ret = av_image_fill_linesizes(linesizes, pix_fmt, align>7 ? FFALIGN(w, 8) : w)) < 0)
         return ret;
 
     for (i = 0; i < 4; i++)
@@ -275,3 +285,77 @@
         }
     }
 }
+
+int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],
+                         const uint8_t *src,
+                         enum AVPixelFormat pix_fmt, int width, int height, int align)
+{
+    int ret, i;
+
+    if ((ret = av_image_check_size(width, height, 0, NULL)) < 0)
+        return ret;
+
+    if ((ret = av_image_fill_linesizes(dst_linesize, pix_fmt, width)) < 0)
+        return ret;
+
+    for (i = 0; i < 4; i++)
+        dst_linesize[i] = FFALIGN(dst_linesize[i], align);
+
+    if ((ret = av_image_fill_pointers(dst_data, pix_fmt, width, NULL, dst_linesize)) < 0)
+        return ret;
+
+    return av_image_fill_pointers(dst_data, pix_fmt, height, (uint8_t *)src, dst_linesize);
+}
+
+int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align)
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+    uint8_t *data[4];
+    int linesize[4];
+
+    if (!desc)
+        return AVERROR(EINVAL);
+    if (av_image_check_size(width, height, 0, NULL) < 0)
+        return AVERROR(EINVAL);
+    if (desc->flags & PIX_FMT_PSEUDOPAL)
+        // do not include palette for these pseudo-paletted formats
+        return width * height;
+    return av_image_fill_arrays(data, linesize, NULL, pix_fmt, width, height, align);
+}
+
+int av_image_copy_to_buffer(uint8_t *dst, int dst_size,
+                            const uint8_t * const src_data[4], const int src_linesize[4],
+                            enum AVPixelFormat pix_fmt, int width, int height, int align)
+{
+    int i, j, nb_planes = 0, linesize[4];
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+    int size = av_image_get_buffer_size(pix_fmt, width, height, align);
+
+    if (size > dst_size || size < 0)
+        return AVERROR(EINVAL);
+
+    for (i = 0; i < desc->nb_components; i++)
+        nb_planes = FFMAX(desc->comp[i].plane, nb_planes);
+    nb_planes++;
+
+    av_image_fill_linesizes(linesize, pix_fmt, width);
+    for (i = 0; i < nb_planes; i++) {
+        int h, shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
+        const uint8_t *src = src_data[i];
+        h = (height + (1 << shift) - 1) >> shift;
+
+        for (j = 0; j < h; j++) {
+            memcpy(dst, src, linesize[i]);
+            dst += FFALIGN(linesize[i], align);
+            src += src_linesize[i];
+        }
+    }
+
+    if (desc->flags & PIX_FMT_PAL) {
+        uint32_t *d32 = (uint32_t *)(((size_t)dst + 3) & ~3);
+        for (i = 0; i<256; i++)
+            AV_WL32(d32 + i, AV_RN32(src_data[1] + 4*i));
+    }
+
+    return size;
+}
diff --git a/libavutil/imgutils.h b/libavutil/imgutils.h
index 4f355bd..f10000c 100644
--- a/libavutil/imgutils.h
+++ b/libavutil/imgutils.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -117,6 +117,65 @@
                    enum AVPixelFormat pix_fmt, int width, int height);
 
 /**
+ * Setup the data pointers and linesizes based on the specified image
+ * parameters and the provided array.
+ *
+ * The fields of the given image are filled in by using the src
+ * address which points to the image data buffer. Depending on the
+ * specified pixel format, one or multiple image data pointers and
+ * line sizes will be set.  If a planar format is specified, several
+ * pointers will be set pointing to the different picture planes and
+ * the line sizes of the different planes will be stored in the
+ * lines_sizes array. Call with src == NULL to get the required
+ * size for the src buffer.
+ *
+ * To allocate the buffer and fill in the dst_data and dst_linesize in
+ * one call, use av_image_alloc().
+ *
+ * @param dst_data      data pointers to be filled in
+ * @param dst_linesizes linesizes for the image in dst_data to be filled in
+ * @param src           buffer which will contain or contains the actual image data, can be NULL
+ * @param pix_fmt       the pixel format of the image
+ * @param width         the width of the image in pixels
+ * @param height        the height of the image in pixels
+ * @param align         the value used in src for linesize alignment
+ * @return the size in bytes required for src, a negative error code
+ * in case of failure
+ */
+int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],
+                         const uint8_t *src,
+                         enum AVPixelFormat pix_fmt, int width, int height, int align);
+
+/**
+ * Return the size in bytes of the amount of data required to store an
+ * image with the given parameters.
+ *
+ * @param[in] align the assumed linesize alignment
+ */
+int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align);
+
+/**
+ * Copy image data from an image into a buffer.
+ *
+ * av_image_get_buffer_size() can be used to compute the required size
+ * for the buffer to fill.
+ *
+ * @param dst           a buffer into which picture data will be copied
+ * @param dst_size      the size in bytes of dst
+ * @param src_data      pointers containing the source image data
+ * @param src_linesizes linesizes for the image in src_data
+ * @param pix_fmt       the pixel format of the source image
+ * @param width         the width of the source image in pixels
+ * @param height        the height of the source image in pixels
+ * @param align         the assumed linesize alignment for dst
+ * @return the number of bytes written to dst, or a negative value
+ * (error code) on error
+ */
+int av_image_copy_to_buffer(uint8_t *dst, int dst_size,
+                            const uint8_t * const src_data[4], const int src_linesize[4],
+                            enum AVPixelFormat pix_fmt, int width, int height, int align);
+
+/**
  * Check if the given dimension of an image is valid, meaning that all
  * bytes of the image can be addressed with a signed int.
  *
diff --git a/libavutil/integer.c b/libavutil/integer.c
new file mode 100644
index 0000000..5bcde0d
--- /dev/null
+++ b/libavutil/integer.c
@@ -0,0 +1,196 @@
+/*
+ * arbitrary precision integers
+ * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * arbitrary precision integers
+ * @author Michael Niedermayer <michaelni@gmx.at>
+ */
+
+#include "common.h"
+#include "integer.h"
+#include "avassert.h"
+
+AVInteger av_add_i(AVInteger a, AVInteger b){
+    int i, carry=0;
+
+    for(i=0; i<AV_INTEGER_SIZE; i++){
+        carry= (carry>>16) + a.v[i] + b.v[i];
+        a.v[i]= carry;
+    }
+    return a;
+}
+
+AVInteger av_sub_i(AVInteger a, AVInteger b){
+    int i, carry=0;
+
+    for(i=0; i<AV_INTEGER_SIZE; i++){
+        carry= (carry>>16) + a.v[i] - b.v[i];
+        a.v[i]= carry;
+    }
+    return a;
+}
+
+int av_log2_i(AVInteger a){
+    int i;
+
+    for(i=AV_INTEGER_SIZE-1; i>=0; i--){
+        if(a.v[i])
+            return av_log2_16bit(a.v[i]) + 16*i;
+    }
+    return -1;
+}
+
+AVInteger av_mul_i(AVInteger a, AVInteger b){
+    AVInteger out;
+    int i, j;
+    int na= (av_log2_i(a)+16) >> 4;
+    int nb= (av_log2_i(b)+16) >> 4;
+
+    memset(&out, 0, sizeof(out));
+
+    for(i=0; i<na; i++){
+        unsigned int carry=0;
+
+        if(a.v[i])
+            for(j=i; j<AV_INTEGER_SIZE && j-i<=nb; j++){
+                carry= (carry>>16) + out.v[j] + a.v[i]*b.v[j-i];
+                out.v[j]= carry;
+            }
+    }
+
+    return out;
+}
+
+int av_cmp_i(AVInteger a, AVInteger b){
+    int i;
+    int v= (int16_t)a.v[AV_INTEGER_SIZE-1] - (int16_t)b.v[AV_INTEGER_SIZE-1];
+    if(v) return (v>>16)|1;
+
+    for(i=AV_INTEGER_SIZE-2; i>=0; i--){
+        int v= a.v[i] - b.v[i];
+        if(v) return (v>>16)|1;
+    }
+    return 0;
+}
+
+AVInteger av_shr_i(AVInteger a, int s){
+    AVInteger out;
+    int i;
+
+    for(i=0; i<AV_INTEGER_SIZE; i++){
+        unsigned int index= i + (s>>4);
+        unsigned int v=0;
+        if(index+1<AV_INTEGER_SIZE) v = a.v[index+1]<<16;
+        if(index  <AV_INTEGER_SIZE) v+= a.v[index  ];
+        out.v[i]= v >> (s&15);
+    }
+    return out;
+}
+
+AVInteger av_mod_i(AVInteger *quot, AVInteger a, AVInteger b){
+    int i= av_log2_i(a) - av_log2_i(b);
+    AVInteger quot_temp;
+    if(!quot) quot = &quot_temp;
+
+    av_assert2((int16_t)a.v[AV_INTEGER_SIZE-1] >= 0 && (int16_t)b.v[AV_INTEGER_SIZE-1] >= 0);
+    av_assert2(av_log2_i(b)>=0);
+
+    if(i > 0)
+        b= av_shr_i(b, -i);
+
+    memset(quot, 0, sizeof(AVInteger));
+
+    while(i-- >= 0){
+        *quot= av_shr_i(*quot, -1);
+        if(av_cmp_i(a, b) >= 0){
+            a= av_sub_i(a, b);
+            quot->v[0] += 1;
+        }
+        b= av_shr_i(b, 1);
+    }
+    return a;
+}
+
+AVInteger av_div_i(AVInteger a, AVInteger b){
+    AVInteger quot;
+    av_mod_i(&quot, a, b);
+    return quot;
+}
+
+AVInteger av_int2i(int64_t a){
+    AVInteger out;
+    int i;
+
+    for(i=0; i<AV_INTEGER_SIZE; i++){
+        out.v[i]= a;
+        a>>=16;
+    }
+    return out;
+}
+
+int64_t av_i2int(AVInteger a){
+    int i;
+    int64_t out=(int8_t)a.v[AV_INTEGER_SIZE-1];
+
+    for(i= AV_INTEGER_SIZE-2; i>=0; i--){
+        out = (out<<16) + a.v[i];
+    }
+    return out;
+}
+
+#ifdef TEST
+
+const uint8_t ff_log2_tab[256]={
+        0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+        5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+        6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+        6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
+};
+
+int main(void){
+    int64_t a,b;
+
+    for(a=7; a<256*256*256; a+=13215){
+        for(b=3; b<256*256*256; b+=27118){
+            AVInteger ai= av_int2i(a);
+            AVInteger bi= av_int2i(b);
+
+            av_assert0(av_i2int(ai) == a);
+            av_assert0(av_i2int(bi) == b);
+            av_assert0(av_i2int(av_add_i(ai,bi)) == a+b);
+            av_assert0(av_i2int(av_sub_i(ai,bi)) == a-b);
+            av_assert0(av_i2int(av_mul_i(ai,bi)) == a*b);
+            av_assert0(av_i2int(av_shr_i(ai, 9)) == a>>9);
+            av_assert0(av_i2int(av_shr_i(ai,-9)) == a<<9);
+            av_assert0(av_i2int(av_shr_i(ai, 17)) == a>>17);
+            av_assert0(av_i2int(av_shr_i(ai,-17)) == a<<17);
+            av_assert0(av_log2_i(ai) == av_log2(a));
+            av_assert0(av_i2int(av_div_i(ai,bi)) == a/b);
+        }
+    }
+    return 0;
+}
+#endif
diff --git a/libavutil/integer.h b/libavutil/integer.h
new file mode 100644
index 0000000..45f733c
--- /dev/null
+++ b/libavutil/integer.h
@@ -0,0 +1,86 @@
+/*
+ * arbitrary precision integers
+ * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * arbitrary precision integers
+ * @author Michael Niedermayer <michaelni@gmx.at>
+ */
+
+#ifndef AVUTIL_INTEGER_H
+#define AVUTIL_INTEGER_H
+
+#include <stdint.h>
+#include "common.h"
+
+#define AV_INTEGER_SIZE 8
+
+typedef struct AVInteger{
+    uint16_t v[AV_INTEGER_SIZE];
+} AVInteger;
+
+AVInteger av_add_i(AVInteger a, AVInteger b) av_const;
+AVInteger av_sub_i(AVInteger a, AVInteger b) av_const;
+
+/**
+ * Return the rounded-down value of the base 2 logarithm of the given
+ * AVInteger. This is simply the index of the most significant bit
+ * which is 1, or 0 if all bits are 0.
+ */
+int av_log2_i(AVInteger a) av_const;
+AVInteger av_mul_i(AVInteger a, AVInteger b) av_const;
+
+/**
+ * Return 0 if a==b, 1 if a>b and -1 if a<b.
+ */
+int av_cmp_i(AVInteger a, AVInteger b) av_const;
+
+/**
+ * bitwise shift
+ * @param s the number of bits by which the value should be shifted right,
+            may be negative for shifting left
+ */
+AVInteger av_shr_i(AVInteger a, int s) av_const;
+
+/**
+ * Return a % b.
+ * @param quot a/b will be stored here.
+ */
+AVInteger av_mod_i(AVInteger *quot, AVInteger a, AVInteger b);
+
+/**
+ * Return a/b.
+ */
+AVInteger av_div_i(AVInteger a, AVInteger b) av_const;
+
+/**
+ * Convert the given int64_t to an AVInteger.
+ */
+AVInteger av_int2i(int64_t a) av_const;
+
+/**
+ * Convert the given AVInteger to an int64_t.
+ * If the AVInteger is too large to fit into an int64_t,
+ * then only the least significant 64 bits will be used.
+ */
+int64_t av_i2int(AVInteger a) av_const;
+
+#endif /* AVUTIL_INTEGER_H */
diff --git a/libavutil/internal.h b/libavutil/internal.h
index e61a629..f18e37a 100644
--- a/libavutil/internal.h
+++ b/libavutil/internal.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -37,6 +37,7 @@
 #include "config.h"
 #include "attributes.h"
 #include "timer.h"
+#include "cpu.h"
 #include "dict.h"
 
 #ifndef attribute_align_arg
@@ -116,12 +117,11 @@
 #   define NULL_IF_CONFIG_SMALL(x) x
 #endif
 
-
 /**
  * Define a function with only the non-default version specified.
  *
  * On systems with ELF shared libraries, all symbols exported from
- * Libav libraries are tagged with the name and major version of the
+ * FFmpeg libraries are tagged with the name and major version of the
  * library to which they belong.  If a function is moved from one
  * library to another, a wrapper must be retained in the original
  * location to preserve binary compatibility.
@@ -164,7 +164,8 @@
  */
 static av_always_inline void emms_c(void)
 {
-    __asm__ volatile ("emms" ::: "memory");
+    if(av_get_cpu_flags() & AV_CPU_FLAG_MMX)
+        __asm__ volatile ("emms" ::: "memory");
 }
 #elif HAVE_MMX && HAVE_MM_EMPTY
 #   include <mmintrin.h>
diff --git a/libavutil/intfloat_readwrite.c b/libavutil/intfloat_readwrite.c
index 6838563..2998229 100644
--- a/libavutil/intfloat_readwrite.c
+++ b/libavutil/intfloat_readwrite.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/intfloat_readwrite.h b/libavutil/intfloat_readwrite.h
index f093b92..9709f4d 100644
--- a/libavutil/intfloat_readwrite.h
+++ b/libavutil/intfloat_readwrite.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/intmath.h b/libavutil/intmath.h
index 0ad3012..da333bc 100644
--- a/libavutil/intmath.h
+++ b/libavutil/intmath.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,6 +29,10 @@
  * @{
  */
 
+#if   ARCH_ARM
+#   include "arm/intmath.h"
+#endif
+
 #if HAVE_FAST_CLZ && AV_GCC_VERSION_AT_LEAST(3,4)
 
 #ifndef av_log2
diff --git a/libavutil/intreadwrite.h b/libavutil/intreadwrite.h
index 01eb278..7c68ead 100644
--- a/libavutil/intreadwrite.h
+++ b/libavutil/intreadwrite.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -210,7 +210,8 @@
       ((const uint8_t*)(x))[1])
 #endif
 #ifndef AV_WB16
-#   define AV_WB16(p, d) do {                   \
+#   define AV_WB16(p, darg) do {                \
+        unsigned d = (darg);                    \
         ((uint8_t*)(p))[1] = (d);               \
         ((uint8_t*)(p))[0] = (d)>>8;            \
     } while(0)
@@ -222,7 +223,8 @@
       ((const uint8_t*)(x))[0])
 #endif
 #ifndef AV_WL16
-#   define AV_WL16(p, d) do {                   \
+#   define AV_WL16(p, darg) do {                \
+        unsigned d = (darg);                    \
         ((uint8_t*)(p))[0] = (d);               \
         ((uint8_t*)(p))[1] = (d)>>8;            \
     } while(0)
@@ -236,7 +238,8 @@
                 ((const uint8_t*)(x))[3])
 #endif
 #ifndef AV_WB32
-#   define AV_WB32(p, d) do {                   \
+#   define AV_WB32(p, darg) do {                \
+        unsigned d = (darg);                    \
         ((uint8_t*)(p))[3] = (d);               \
         ((uint8_t*)(p))[2] = (d)>>8;            \
         ((uint8_t*)(p))[1] = (d)>>16;           \
@@ -252,7 +255,8 @@
                 ((const uint8_t*)(x))[0])
 #endif
 #ifndef AV_WL32
-#   define AV_WL32(p, d) do {                   \
+#   define AV_WL32(p, darg) do {                \
+        unsigned d = (darg);                    \
         ((uint8_t*)(p))[0] = (d);               \
         ((uint8_t*)(p))[1] = (d)>>8;            \
         ((uint8_t*)(p))[2] = (d)>>16;           \
@@ -272,7 +276,8 @@
       (uint64_t)((const uint8_t*)(x))[7])
 #endif
 #ifndef AV_WB64
-#   define AV_WB64(p, d) do {                   \
+#   define AV_WB64(p, darg) do {                \
+        uint64_t d = (darg);                    \
         ((uint8_t*)(p))[7] = (d);               \
         ((uint8_t*)(p))[6] = (d)>>8;            \
         ((uint8_t*)(p))[5] = (d)>>16;           \
@@ -296,7 +301,8 @@
       (uint64_t)((const uint8_t*)(x))[0])
 #endif
 #ifndef AV_WL64
-#   define AV_WL64(p, d) do {                   \
+#   define AV_WL64(p, darg) do {                \
+        uint64_t d = (darg);                    \
         ((uint8_t*)(p))[0] = (d);               \
         ((uint8_t*)(p))[1] = (d)>>8;            \
         ((uint8_t*)(p))[2] = (d)>>16;           \
diff --git a/libavutil/lfg.c b/libavutil/lfg.c
index 4221e62..ffa2f1f 100644
--- a/libavutil/lfg.c
+++ b/libavutil/lfg.c
@@ -2,20 +2,20 @@
  * Lagged Fibonacci PRNG
  * Copyright (c) 2008 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -72,8 +72,10 @@
     av_lfg_init(&state, 0xdeadbeef);
     for (j = 0; j < 10000; j++) {
         START_TIMER
-        for (i = 0; i < 624; i++)
+        for (i = 0; i < 624; i++) {
+            //av_log(NULL, AV_LOG_ERROR, "%X\n", av_lfg_get(&state));
             x += av_lfg_get(&state);
+        }
         STOP_TIMER("624 calls of av_lfg_get");
     }
     av_log(NULL, AV_LOG_ERROR, "final value:%X\n", x);
diff --git a/libavutil/lfg.h b/libavutil/lfg.h
index 5e526c1..ec90562 100644
--- a/libavutil/lfg.h
+++ b/libavutil/lfg.h
@@ -2,20 +2,20 @@
  * Lagged Fibonacci PRNG
  * Copyright (c) 2008 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/libm.h b/libavutil/libm.h
index 8305b7c..d36420b 100644
--- a/libavutil/libm.h
+++ b/libavutil/libm.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,6 +29,10 @@
 #include "attributes.h"
 #include "intfloat.h"
 
+#if HAVE_MIPSFPU && HAVE_INLINE_ASM
+#include "libavutil/mips/libm_mips.h"
+#endif /* HAVE_MIPSFPU && HAVE_INLINE_ASM*/
+
 #if !HAVE_CBRTF
 static av_always_inline float cbrtf(float x)
 {
diff --git a/libavutil/lls.c b/libavutil/lls.c
index b29fc96..dcefc2c 100644
--- a/libavutil/lls.c
+++ b/libavutil/lls.c
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/lls.h b/libavutil/lls.h
index 3db391b..d168e59 100644
--- a/libavutil/lls.h
+++ b/libavutil/lls.h
@@ -3,20 +3,20 @@
  *
  * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/log.c b/libavutil/log.c
index d2cf88f..1bae1b2 100644
--- a/libavutil/log.c
+++ b/libavutil/log.c
@@ -2,20 +2,20 @@
  * log functions
  * Copyright (c) 2003 Michel Bardiaux
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,25 +30,69 @@
 #include <unistd.h>
 #endif
 #include <stdlib.h>
-#include "avstring.h"
 #include "avutil.h"
 #include "common.h"
 #include "log.h"
 
+#define LINE_SZ 1024
+
 static int av_log_level = AV_LOG_INFO;
 static int flags;
 
 #if defined(_WIN32) && !defined(__MINGW32CE__)
 #include <windows.h>
 #include <io.h>
-static const uint8_t color[] = { 12, 12, 12, 14, 7, 10, 11 };
+static const uint8_t color[16 + AV_CLASS_CATEGORY_NB] = {
+    [AV_LOG_PANIC  /8] = 12,
+    [AV_LOG_FATAL  /8] = 12,
+    [AV_LOG_ERROR  /8] = 12,
+    [AV_LOG_WARNING/8] = 14,
+    [AV_LOG_INFO   /8] =  7,
+    [AV_LOG_VERBOSE/8] = 10,
+    [AV_LOG_DEBUG  /8] = 10,
+    [16+AV_CLASS_CATEGORY_NA              ] =  7,
+    [16+AV_CLASS_CATEGORY_INPUT           ] = 13,
+    [16+AV_CLASS_CATEGORY_OUTPUT          ] =  5,
+    [16+AV_CLASS_CATEGORY_MUXER           ] = 13,
+    [16+AV_CLASS_CATEGORY_DEMUXER         ] =  5,
+    [16+AV_CLASS_CATEGORY_ENCODER         ] = 11,
+    [16+AV_CLASS_CATEGORY_DECODER         ] =  3,
+    [16+AV_CLASS_CATEGORY_FILTER          ] = 10,
+    [16+AV_CLASS_CATEGORY_BITSTREAM_FILTER] =  9,
+    [16+AV_CLASS_CATEGORY_SWSCALER        ] =  7,
+    [16+AV_CLASS_CATEGORY_SWRESAMPLER     ] =  7,
+};
+
 static int16_t background, attr_orig;
 static HANDLE con;
 #define set_color(x)  SetConsoleTextAttribute(con, background | color[x])
+#define set_256color set_color
 #define reset_color() SetConsoleTextAttribute(con, attr_orig)
 #else
-static const uint8_t color[] = { 0x41, 0x41, 0x11, 0x03, 9, 0x02, 0x06 };
-#define set_color(x)  fprintf(stderr, "\033[%d;3%dm", color[x] >> 4, color[x]&15)
+
+static const uint32_t color[16 + AV_CLASS_CATEGORY_NB] = {
+    [AV_LOG_PANIC  /8] =  52 << 16 | 196 << 8 | 0x41,
+    [AV_LOG_FATAL  /8] = 208 <<  8 | 0x41,
+    [AV_LOG_ERROR  /8] = 196 <<  8 | 0x11,
+    [AV_LOG_WARNING/8] = 226 <<  8 | 0x03,
+    [AV_LOG_INFO   /8] = 253 <<  8 | 0x09,
+    [AV_LOG_VERBOSE/8] =  40 <<  8 | 0x02,
+    [AV_LOG_DEBUG  /8] =  34 <<  8 | 0x02,
+    [16+AV_CLASS_CATEGORY_NA              ] = 250 << 8 | 0x09,
+    [16+AV_CLASS_CATEGORY_INPUT           ] = 219 << 8 | 0x15,
+    [16+AV_CLASS_CATEGORY_OUTPUT          ] = 201 << 8 | 0x05,
+    [16+AV_CLASS_CATEGORY_MUXER           ] = 213 << 8 | 0x15,
+    [16+AV_CLASS_CATEGORY_DEMUXER         ] = 207 << 8 | 0x05,
+    [16+AV_CLASS_CATEGORY_ENCODER         ] =  51 << 8 | 0x16,
+    [16+AV_CLASS_CATEGORY_DECODER         ] =  39 << 8 | 0x06,
+    [16+AV_CLASS_CATEGORY_FILTER          ] = 155 << 8 | 0x12,
+    [16+AV_CLASS_CATEGORY_BITSTREAM_FILTER] = 192 << 8 | 0x14,
+    [16+AV_CLASS_CATEGORY_SWSCALER        ] = 153 << 8 | 0x14,
+    [16+AV_CLASS_CATEGORY_SWRESAMPLER     ] = 147 << 8 | 0x14,
+};
+
+#define set_color(x)  fprintf(stderr, "\033[%d;3%dm", (color[x] >> 4) & 15, color[x] & 15)
+#define set_256color(x) fprintf(stderr, "\033[48;5;%dm\033[38;5;%dm", (color[x] >> 16) & 0xff, (color[x] >> 8) & 0xff)
 #define reset_color() fprintf(stderr, "\033[0m")
 #endif
 static int use_color = -1;
@@ -71,15 +115,18 @@
         use_color = !getenv("NO_COLOR") && !getenv("AV_LOG_FORCE_NOCOLOR") &&
                     (getenv("TERM") && isatty(2) ||
                      getenv("AV_LOG_FORCE_COLOR"));
+        if (getenv("AV_LOG_FORCE_256COLOR"))
+            use_color *= 256;
 #else
         use_color = getenv("AV_LOG_FORCE_COLOR") && !getenv("NO_COLOR") &&
                    !getenv("AV_LOG_FORCE_NOCOLOR");
 #endif
     }
 
-    if (use_color) {
+    if (use_color == 1) {
         set_color(level);
-    }
+    } else if (use_color == 256)
+        set_256color(level);
     fputs(str, stderr);
     if (use_color) {
         reset_color();
@@ -91,42 +138,88 @@
     return (*(AVClass **) ptr)->class_name;
 }
 
-void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl)
+AVClassCategory av_default_get_category(void *ptr)
 {
-    static int print_prefix = 1;
-    static int count;
-    static char prev[1024];
-    char line[1024];
-    static int is_atty;
+    return (*(AVClass **) ptr)->category;
+}
+
+static void sanitize(uint8_t *line){
+    while(*line){
+        if(*line < 0x08 || (*line > 0x0D && *line < 0x20))
+            *line='?';
+        line++;
+    }
+}
+
+static int get_category(void *ptr){
+    AVClass *avc = *(AVClass **) ptr;
+    if(    !avc
+        || (avc->version&0xFF)<100
+        ||  avc->version < (51 << 16 | 59 << 8)
+        ||  avc->category >= AV_CLASS_CATEGORY_NB) return AV_CLASS_CATEGORY_NA + 16;
+
+    if(avc->get_category)
+        return avc->get_category(ptr) + 16;
+
+    return avc->category + 16;
+}
+
+static void format_line(void *ptr, int level, const char *fmt, va_list vl,
+                        char part[3][LINE_SZ], int part_size, int *print_prefix, int type[2])
+{
     AVClass* avc = ptr ? *(AVClass **) ptr : NULL;
-    if (level > av_log_level)
-        return;
-    line[0] = 0;
-#undef fprintf
-    if (print_prefix && avc) {
+    part[0][0] = part[1][0] = part[2][0] = 0;
+    if(type) type[0] = type[1] = AV_CLASS_CATEGORY_NA + 16;
+    if (*print_prefix && avc) {
         if (avc->parent_log_context_offset) {
             AVClass** parent = *(AVClass ***) (((uint8_t *) ptr) +
                                    avc->parent_log_context_offset);
             if (parent && *parent) {
-                snprintf(line, sizeof(line), "[%s @ %p] ",
+                snprintf(part[0], part_size, "[%s @ %p] ",
                          (*parent)->item_name(parent), parent);
+                if(type) type[0] = get_category(((uint8_t *) ptr) + avc->parent_log_context_offset);
             }
         }
-        snprintf(line + strlen(line), sizeof(line) - strlen(line), "[%s @ %p] ",
+        snprintf(part[1], part_size, "[%s @ %p] ",
                  avc->item_name(ptr), ptr);
+        if(type) type[1] = get_category(ptr);
     }
 
-    vsnprintf(line + strlen(line), sizeof(line) - strlen(line), fmt, vl);
+    vsnprintf(part[2], part_size, fmt, vl);
 
-    print_prefix = strlen(line) && line[strlen(line) - 1] == '\n';
+    *print_prefix = strlen(part[2]) && part[2][strlen(part[2]) - 1] == '\n';
+}
+
+void av_log_format_line(void *ptr, int level, const char *fmt, va_list vl,
+                        char *line, int line_size, int *print_prefix)
+{
+    char part[3][LINE_SZ];
+    format_line(ptr, level, fmt, vl, part, sizeof(part[0]), print_prefix, NULL);
+    snprintf(line, line_size, "%s%s%s", part[0], part[1], part[2]);
+}
+
+void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl)
+{
+    static int print_prefix = 1;
+    static int count;
+    static char prev[LINE_SZ];
+    char part[3][LINE_SZ];
+    char line[LINE_SZ];
+    static int is_atty;
+    int type[2];
+
+    if (level > av_log_level)
+        return;
+    format_line(ptr, level, fmt, vl, part, sizeof(part[0]), &print_prefix, type);
+    snprintf(line, sizeof(line), "%s%s%s", part[0], part[1], part[2]);
 
 #if HAVE_ISATTY
     if (!is_atty)
         is_atty = isatty(2) ? 1 : -1;
 #endif
 
-    if (print_prefix && (flags & AV_LOG_SKIP_REPEATED) &&
-        !strncmp(line, prev, sizeof line)) {
+#undef fprintf
+    if (print_prefix && (flags & AV_LOG_SKIP_REPEATED) && !strcmp(line, prev)){
         count++;
         if (is_atty == 1)
             fprintf(stderr, "    Last message repeated %d times\r", count);
@@ -136,8 +229,13 @@
         fprintf(stderr, "    Last message repeated %d times\n", count);
         count = 0;
     }
-    colored_fputs(av_clip(level >> 3, 0, 6), line);
-    av_strlcpy(prev, line, sizeof line);
+    strcpy(prev, line);
+    sanitize(part[0]);
+    colored_fputs(type[0], part[0]);
+    sanitize(part[1]);
+    colored_fputs(type[1], part[1]);
+    sanitize(part[2]);
+    colored_fputs(av_clip(level >> 3, 0, 6), part[2]);
 }
 
 static void (*av_log_callback)(void*, int, const char*, va_list) =
@@ -157,7 +255,8 @@
 
 void av_vlog(void* avcl, int level, const char *fmt, va_list vl)
 {
-    av_log_callback(avcl, level, fmt, vl);
+    if(av_log_callback)
+        av_log_callback(avcl, level, fmt, vl);
 }
 
 int av_log_get_level(void)
diff --git a/libavutil/log.h b/libavutil/log.h
index 0678e1a..ba7315f 100644
--- a/libavutil/log.h
+++ b/libavutil/log.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -25,6 +25,21 @@
 #include "avutil.h"
 #include "attributes.h"
 
+typedef enum {
+    AV_CLASS_CATEGORY_NA = 0,
+    AV_CLASS_CATEGORY_INPUT,
+    AV_CLASS_CATEGORY_OUTPUT,
+    AV_CLASS_CATEGORY_MUXER,
+    AV_CLASS_CATEGORY_DEMUXER,
+    AV_CLASS_CATEGORY_ENCODER,
+    AV_CLASS_CATEGORY_DECODER,
+    AV_CLASS_CATEGORY_FILTER,
+    AV_CLASS_CATEGORY_BITSTREAM_FILTER,
+    AV_CLASS_CATEGORY_SWSCALER,
+    AV_CLASS_CATEGORY_SWRESAMPLER,
+    AV_CLASS_CATEGORY_NB, ///< not part of ABI/API
+}AVClassCategory;
+
 /**
  * Describe the class of an AVClass context structure. That is an
  * arbitrary struct of which the first field is a pointer to an
@@ -86,6 +101,19 @@
      * child_class_next iterates over _all possible_ children.
      */
     const struct AVClass* (*child_class_next)(const struct AVClass *prev);
+
+    /**
+     * Category used for visualization (like color)
+     * This is only set if the category is equal for all objects using this class.
+     * available since version (51 << 16 | 56 << 8 | 100)
+     */
+    AVClassCategory category;
+
+    /**
+     * Callback to return the category.
+     * available since version (51 << 16 | 59 << 8 | 100)
+     */
+    AVClassCategory (*get_category)(void* ctx);
 } AVClass;
 
 /* av_log API */
@@ -124,6 +152,8 @@
  */
 #define AV_LOG_DEBUG    48
 
+#define AV_LOG_MAX_OFFSET (AV_LOG_DEBUG - AV_LOG_QUIET)
+
 /**
  * Send the specified message to the log if the level is less than or equal
  * to the current av_log_level. By default, all logging messages are sent to
@@ -146,6 +176,17 @@
 void av_log_set_callback(void (*)(void*, int, const char*, va_list));
 void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl);
 const char* av_default_item_name(void* ctx);
+AVClassCategory av_default_get_category(void *ptr);
+
+/**
+ * Format a line of log the same way as the default callback.
+ * @param line          buffer to receive the formated line
+ * @param line_size     size of the buffer
+ * @param print_prefix  used to store whether the prefix must be printed;
+ *                      must point to a persistent integer initially set to 1
+ */
+void av_log_format_line(void *ptr, int level, const char *fmt, va_list vl,
+                        char *line, int line_size, int *print_prefix);
 
 /**
  * av_dlog macros
@@ -155,7 +196,7 @@
 #ifdef DEBUG
 #    define av_dlog(pctx, ...) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__)
 #else
-#    define av_dlog(pctx, ...)
+#    define av_dlog(pctx, ...) do { if (0) av_log(pctx, AV_LOG_DEBUG, __VA_ARGS__); } while (0)
 #endif
 
 /**
@@ -164,7 +205,7 @@
  * "Last message repeated x times" messages below (f)printf messages with some
  * bad luck.
  * Also to receive the last, "last repeated" line if any, the user app must
- * call av_log(NULL, AV_LOG_QUIET, ""); at the end
+ * call av_log(NULL, AV_LOG_QUIET, "%s", ""); at the end
  */
 #define AV_LOG_SKIP_REPEATED 1
 void av_log_set_flags(int arg);
diff --git a/libavutil/log2_tab.c b/libavutil/log2_tab.c
index f6cbe79..0dbf07d 100644
--- a/libavutil/log2_tab.c
+++ b/libavutil/log2_tab.c
@@ -1,18 +1,20 @@
 /*
- * This file is part of Libav.
+ * Copyright (c) 2003-2012 Michael Niedermayer <michaelni@gmx.at>
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/lzo.c b/libavutil/lzo.c
index fec3edb..3642308 100644
--- a/libavutil/lzo.c
+++ b/libavutil/lzo.c
@@ -2,20 +2,20 @@
  * LZO 1x decompression
  * Copyright (c) 2006 Reimar Doeffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -112,7 +112,7 @@
 
 /**
  * @brief Copies previously decoded bytes to current position.
- * @param back how many bytes back we start
+ * @param back how many bytes back we start, must be > 0
  * @param cnt number of bytes to copy, must be >= 0
  *
  * cnt > back is valid, this will copy the bytes we just copied,
@@ -135,7 +135,7 @@
 
 static inline void memcpy_backptr(uint8_t *dst, int back, int cnt) {
     const uint8_t *src = &dst[-back];
-    if (back == 1) {
+    if (back <= 1) {
         memset(dst, *src, cnt);
     } else {
 #ifdef OUTBUF_PADDED
@@ -175,11 +175,11 @@
     int state= 0;
     int x;
     LZOContext c;
-    if (!*outlen || !*inlen) {
+    if (*outlen <= 0 || *inlen <= 0) {
         int res = 0;
-        if (!*outlen)
+        if (*outlen <= 0)
             res |= AV_LZO_OUTPUT_FULL;
-        if (!*inlen)
+        if (*inlen <= 0)
             res |= AV_LZO_INPUT_DEPLETED;
         return res;
     }
@@ -241,3 +241,47 @@
     *outlen = c.out_end - c.out;
     return c.error;
 }
+
+#ifdef TEST
+#include <stdio.h>
+#include <lzo/lzo1x.h>
+#include "log.h"
+#define MAXSZ (10*1024*1024)
+
+/* Define one of these to 1 if you wish to benchmark liblzo
+ * instead of our native implementation. */
+#define BENCHMARK_LIBLZO_SAFE   0
+#define BENCHMARK_LIBLZO_UNSAFE 0
+
+int main(int argc, char *argv[]) {
+    FILE *in = fopen(argv[1], "rb");
+    uint8_t *orig = av_malloc(MAXSZ + 16);
+    uint8_t *comp = av_malloc(2*MAXSZ + 16);
+    uint8_t *decomp = av_malloc(MAXSZ + 16);
+    size_t s = fread(orig, 1, MAXSZ, in);
+    lzo_uint clen = 0;
+    long tmp[LZO1X_MEM_COMPRESS];
+    int inlen, outlen;
+    int i;
+    av_log_set_level(AV_LOG_DEBUG);
+    lzo1x_999_compress(orig, s, comp, &clen, tmp);
+    for (i = 0; i < 300; i++) {
+START_TIMER
+        inlen = clen; outlen = MAXSZ;
+#if BENCHMARK_LIBLZO_SAFE
+        if (lzo1x_decompress_safe(comp, inlen, decomp, &outlen, NULL))
+#elif BENCHMARK_LIBLZO_UNSAFE
+        if (lzo1x_decompress(comp, inlen, decomp, &outlen, NULL))
+#else
+        if (av_lzo1x_decode(decomp, &outlen, comp, &inlen))
+#endif
+            av_log(NULL, AV_LOG_ERROR, "decompression error\n");
+STOP_TIMER("lzod")
+    }
+    if (memcmp(orig, decomp, s))
+        av_log(NULL, AV_LOG_ERROR, "decompression incorrect\n");
+    else
+        av_log(NULL, AV_LOG_ERROR, "decompression OK\n");
+    return 0;
+}
+#endif
diff --git a/libavutil/lzo.h b/libavutil/lzo.h
index 1b774a5..060b5c9 100644
--- a/libavutil/lzo.h
+++ b/libavutil/lzo.h
@@ -2,20 +2,20 @@
  * LZO 1x decompression
  * copyright (c) 2006 Reimar Doeffinger
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -62,7 +62,7 @@
 /**
  * @brief deliberately overlapping memcpy implementation
  * @param dst destination buffer; must be padded with 12 additional bytes
- * @param back how many bytes back we start (the initial size of the overlapping window)
+ * @param back how many bytes back we start (the initial size of the overlapping window), must be > 0
  * @param cnt number of bytes to copy, must be >= 0
  *
  * cnt > back is valid, this will copy the bytes we just copied,
diff --git a/libavutil/mathematics.c b/libavutil/mathematics.c
index 137683e..bf93437 100644
--- a/libavutil/mathematics.c
+++ b/libavutil/mathematics.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -23,11 +23,12 @@
  * miscellaneous math routines and tables
  */
 
-#include <assert.h>
 #include <stdint.h>
 #include <limits.h>
 
 #include "mathematics.h"
+#include "libavutil/common.h"
+#include "avassert.h"
 #include "version.h"
 
 #if FF_API_AV_REVERSE
@@ -58,9 +59,9 @@
 
 int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd){
     int64_t r=0;
-    assert(c > 0);
-    assert(b >=0);
-    assert((unsigned)rnd<=5 && rnd!=4);
+    av_assert2(c > 0);
+    av_assert2(b >=0);
+    av_assert2((unsigned)rnd<=5 && rnd!=4);
 
     if(a<0 && a != INT64_MIN) return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd>>1)&1));
 
@@ -128,6 +129,8 @@
 int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b){
     int64_t a= tb_a.num * (int64_t)tb_b.den;
     int64_t b= tb_b.num * (int64_t)tb_a.den;
+    if((FFABS(ts_a)|a|FFABS(ts_b)|b)<=INT_MAX)
+        return (ts_a*a > ts_b*b) - (ts_a*a < ts_b*b);
     if (av_rescale_rnd(ts_a, a, b, AV_ROUND_DOWN) < ts_b) return -1;
     if (av_rescale_rnd(ts_b, b, a, AV_ROUND_DOWN) < ts_a) return  1;
     return 0;
diff --git a/libavutil/mathematics.h b/libavutil/mathematics.h
index 043dd0f..5458d2f 100644
--- a/libavutil/mathematics.h
+++ b/libavutil/mathematics.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -27,12 +27,30 @@
 #include "rational.h"
 #include "intfloat.h"
 
+#ifndef M_E
+#define M_E            2.7182818284590452354   /* e */
+#endif
+#ifndef M_LN2
+#define M_LN2          0.69314718055994530942  /* log_e 2 */
+#endif
+#ifndef M_LN10
+#define M_LN10         2.30258509299404568402  /* log_e 10 */
+#endif
 #ifndef M_LOG2_10
 #define M_LOG2_10      3.32192809488736234787  /* log_2 10 */
 #endif
 #ifndef M_PHI
 #define M_PHI          1.61803398874989484820   /* phi / golden ratio */
 #endif
+#ifndef M_PI
+#define M_PI           3.14159265358979323846  /* pi */
+#endif
+#ifndef M_SQRT1_2
+#define M_SQRT1_2      0.70710678118654752440  /* 1/sqrt(2) */
+#endif
+#ifndef M_SQRT2
+#define M_SQRT2        1.41421356237309504880  /* sqrt(2) */
+#endif
 #ifndef NAN
 #define NAN            av_int2float(0x7fc00000)
 #endif
diff --git a/libavutil/md5.c b/libavutil/md5.c
index 93a91d7..ce8400f 100644
--- a/libavutil/md5.c
+++ b/libavutil/md5.c
@@ -13,20 +13,20 @@
  * If you use gcc, then version 4.1 or later and -fomit-frame-pointer is
  * strongly recommended.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -96,12 +96,12 @@
 
 static void body(uint32_t ABCD[4], uint32_t X[16])
 {
-    int t;
     int i av_unused;
-    unsigned int a = ABCD[3];
-    unsigned int b = ABCD[2];
-    unsigned int c = ABCD[1];
-    unsigned int d = ABCD[0];
+    uint32_t t;
+    uint32_t a = ABCD[3];
+    uint32_t b = ABCD[2];
+    uint32_t c = ABCD[1];
+    uint32_t d = ABCD[0];
 
 #if HAVE_BIGENDIAN
     for (i = 0; i < 16; i++)
diff --git a/libavutil/md5.h b/libavutil/md5.h
index 29e4e7c..69199cc 100644
--- a/libavutil/md5.h
+++ b/libavutil/md5.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/mem.c b/libavutil/mem.c
index 3769da7..8ec226b 100644
--- a/libavutil/mem.c
+++ b/libavutil/mem.c
@@ -2,20 +2,20 @@
  * default memory allocator for libavutil
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,6 +24,8 @@
  * default memory allocator for libavutil
  */
 
+#define _XOPEN_SOURCE 600
+
 #include "config.h"
 
 #include <limits.h>
@@ -57,9 +59,18 @@
 
 #endif /* MALLOC_PREFIX */
 
-/* You can redefine av_malloc and av_free in your project to use your
-   memory allocator. You do not need to suppress this file because the
-   linker will do it automatically. */
+#define ALIGN (HAVE_AVX ? 32 : 16)
+
+/* NOTE: if you want to override these functions with your own
+ * implementations (not recommended) you have to link libav* as
+ * dynamic libraries and remove -Wl,-Bsymbolic from the linker flags.
+ * Note that this will cost performance. */
+
+static size_t max_alloc_size= INT_MAX;
+
+void av_max_alloc(size_t max){
+    max_alloc_size = max;
+}
 
 void *av_malloc(size_t size)
 {
@@ -69,23 +80,24 @@
 #endif
 
     /* let's disallow possible ambiguous cases */
-    if (size > (INT_MAX-32) || !size)
+    if (size > (max_alloc_size-32))
         return NULL;
 
 #if CONFIG_MEMALIGN_HACK
-    ptr = malloc(size+32);
+    ptr = malloc(size+ALIGN);
     if(!ptr)
         return ptr;
-    diff= ((-(long)ptr - 1)&31) + 1;
+    diff= ((-(long)ptr - 1)&(ALIGN-1)) + 1;
     ptr = (char*)ptr + diff;
     ((char*)ptr)[-1]= diff;
 #elif HAVE_POSIX_MEMALIGN
-    if (posix_memalign(&ptr,32,size))
+    if (size) //OS X on SDK 10.6 has a broken posix_memalign implementation
+    if (posix_memalign(&ptr,ALIGN,size))
         ptr = NULL;
 #elif HAVE_ALIGNED_MALLOC
-    ptr = _aligned_malloc(size, 32);
+    ptr = _aligned_malloc(size, ALIGN);
 #elif HAVE_MEMALIGN
-    ptr = memalign(32,size);
+    ptr = memalign(ALIGN,size);
     /* Why 64?
        Indeed, we should align it:
          on 4 for 386
@@ -113,6 +125,14 @@
 #else
     ptr = malloc(size);
 #endif
+    if(!ptr && !size) {
+        size = 1;
+        ptr= av_malloc(1);
+    }
+#if CONFIG_MEMORY_POISONING
+    if (ptr)
+        memset(ptr, 0x2a, size);
+#endif
     return ptr;
 }
 
@@ -123,21 +143,38 @@
 #endif
 
     /* let's disallow possible ambiguous cases */
-    if(size > (INT_MAX-16) )
+    if (size > (max_alloc_size-32))
         return NULL;
 
 #if CONFIG_MEMALIGN_HACK
     //FIXME this isn't aligned correctly, though it probably isn't needed
     if(!ptr) return av_malloc(size);
     diff= ((char*)ptr)[-1];
-    return (char*)realloc((char*)ptr - diff, size + diff) + diff;
+    ptr= realloc((char*)ptr - diff, size + diff);
+    if(ptr) ptr = (char*)ptr + diff;
+    return ptr;
 #elif HAVE_ALIGNED_MALLOC
-    return _aligned_realloc(ptr, size, 32);
+    return _aligned_realloc(ptr, size + !size, ALIGN);
 #else
-    return realloc(ptr, size);
+    return realloc(ptr, size + !size);
 #endif
 }
 
+void *av_realloc_f(void *ptr, size_t nelem, size_t elsize)
+{
+    size_t size;
+    void *r;
+
+    if (av_size_mult(elsize, nelem, &size)) {
+        av_free(ptr);
+        return NULL;
+    }
+    r = av_realloc(ptr, size);
+    if (!r && size)
+        av_free(ptr);
+    return r;
+}
+
 void av_free(void *ptr)
 {
 #if CONFIG_MEMALIGN_HACK
@@ -165,6 +202,13 @@
     return ptr;
 }
 
+void *av_calloc(size_t nmemb, size_t size)
+{
+    if (size <= 0 || nmemb >= INT_MAX / size)
+        return NULL;
+    return av_mallocz(nmemb * size);
+}
+
 char *av_strdup(const char *s)
 {
     char *ptr= NULL;
@@ -176,3 +220,25 @@
     }
     return ptr;
 }
+
+/* add one element to a dynamic array */
+void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem)
+{
+    /* see similar ffmpeg.c:grow_array() */
+    int nb, nb_alloc;
+    intptr_t *tab;
+
+    nb = *nb_ptr;
+    tab = *(intptr_t**)tab_ptr;
+    if ((nb & (nb - 1)) == 0) {
+        if (nb == 0)
+            nb_alloc = 1;
+        else
+            nb_alloc = nb * 2;
+        tab = av_realloc(tab, nb_alloc * sizeof(intptr_t));
+        *(intptr_t**)tab_ptr = tab;
+    }
+    tab[nb++] = (intptr_t)elem;
+    *nb_ptr = nb;
+}
+
diff --git a/libavutil/mem.h b/libavutil/mem.h
index fb22206..212dbf1 100644
--- a/libavutil/mem.h
+++ b/libavutil/mem.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,6 +29,7 @@
 #include <limits.h>
 
 #include "attributes.h"
+#include "error.h"
 #include "avutil.h"
 
 /**
@@ -37,7 +38,7 @@
  */
 
 
-#if defined(__ICC) && __ICC < 1200 || defined(__SUNPRO_C)
+#if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1110 || defined(__SUNPRO_C)
     #define DECLARE_ALIGNED(n,t,v)      t __attribute__ ((aligned (n))) v
     #define DECLARE_ASM_CONST(n,t,v)    const t __attribute__ ((aligned (n))) v
 #elif defined(__TI_COMPILER_VERSION__)
@@ -111,6 +112,16 @@
 void *av_realloc(void *ptr, size_t size) av_alloc_size(2);
 
 /**
+ * Allocate or reallocate a block of memory.
+ * This function does the same thing as av_realloc, except:
+ * - It takes two arguments and checks the result of the multiplication for
+ *   integer overflow.
+ * - It frees the input block in case of failure, thus avoiding the memory
+ *   leak with the classic "buf = realloc(buf); if (!buf) return -1;".
+ */
+void *av_realloc_f(void *ptr, size_t nelem, size_t elsize);
+
+/**
  * Free a memory block which has been allocated with av_malloc(z)() or
  * av_realloc().
  * @param ptr Pointer to the memory block which should be freed.
@@ -131,6 +142,18 @@
 void *av_mallocz(size_t size) av_malloc_attrib av_alloc_size(1);
 
 /**
+ * Allocate a block of nmemb * size bytes with alignment suitable for all
+ * memory accesses (including vectors if available on the CPU) and
+ * zero all the bytes of the block.
+ * The allocation will fail if nmemb * size is greater than or equal
+ * to INT_MAX.
+ * @param nmemb
+ * @param size
+ * @return Pointer to the allocated block, NULL if it cannot be allocated.
+ */
+void *av_calloc(size_t nmemb, size_t size) av_malloc_attrib;
+
+/**
  * Helper function to allocate a block of size * nmemb bytes with
  * using av_mallocz()
  * @param nmemb Number of elements
@@ -165,6 +188,35 @@
 void av_freep(void *ptr);
 
 /**
+ * Add an element to a dynamic array.
+ *
+ * @param tab_ptr Pointer to the array.
+ * @param nb_ptr  Pointer to the number of elements in the array.
+ * @param elem    Element to be added.
+ */
+void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem);
+
+/**
+ * Multiply two size_t values checking for overflow.
+ * @return  0 if success, AVERROR(EINVAL) if overflow.
+ */
+static inline int av_size_mult(size_t a, size_t b, size_t *r)
+{
+    size_t t = a * b;
+    /* Hack inspired from glibc: only try the division if nelem and elsize
+     * are both greater than sqrt(SIZE_MAX). */
+    if ((a | b) >= ((size_t)1 << (sizeof(size_t) * 4)) && a && t / a != b)
+        return AVERROR(EINVAL);
+    *r = t;
+    return 0;
+}
+
+/**
+ * Set the maximum size that may me allocated in one block.
+ */
+void av_max_alloc(size_t max);
+
+/**
  * @}
  */
 
diff --git a/libavutil/mips/intreadwrite.h b/libavutil/mips/intreadwrite.h
index 4dabbe6..9ba0491 100644
--- a/libavutil/mips/intreadwrite.h
+++ b/libavutil/mips/intreadwrite.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/mips/libm_mips.h b/libavutil/mips/libm_mips.h
new file mode 100644
index 0000000..8853bbc
--- /dev/null
+++ b/libavutil/mips/libm_mips.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012
+ *      MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author:  Nedeljko Babic (nbabic@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
+ * MIPS optimization for some libm functions
+ */
+
+#ifndef AVUTIL_LIBM_MIPS_H
+#define AVUTIL_LIBM_MIPS_H
+
+static av_always_inline av_const long int lrintf_mips(float x)
+{
+    register int ret_int;
+
+    __asm__ volatile (
+        "cvt.w.s    %[x],       %[x]    \n\t"
+        "mfc1       %[ret_int], %[x]    \n\t"
+
+        :[x]"+f"(x), [ret_int]"=r"(ret_int)
+    );
+    return ret_int;
+}
+
+#undef lrintf
+#define lrintf(x)   lrintf_mips(x)
+
+#define HAVE_LRINTF 1
+#endif /* AVUTIL_LIBM_MIPS_H */
diff --git a/libavutil/old_pix_fmts.h b/libavutil/old_pix_fmts.h
index 31765ae..57b6992 100644
--- a/libavutil/old_pix_fmts.h
+++ b/libavutil/old_pix_fmts.h
@@ -1,18 +1,20 @@
 /*
- * This file is part of Libav.
+ * copyright (c) 2006-2012 Michael Niedermayer <michaelni@gmx.at>
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -100,9 +102,13 @@
     PIX_FMT_RGB444BE,  ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), big-endian, most significant bits to 0
     PIX_FMT_BGR444LE,  ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), little-endian, most significant bits to 1
     PIX_FMT_BGR444BE,  ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), big-endian, most significant bits to 1
-    PIX_FMT_Y400A,     ///< 8bit gray, 8bit alpha
+    PIX_FMT_GRAY8A,    ///< 8bit gray, 8bit alpha
     PIX_FMT_BGR48BE,   ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big-endian
     PIX_FMT_BGR48LE,   ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as little-endian
+
+    //the following 10 formats have the disadvantage of needing 1 format for each bit depth, thus
+    //If you want to support multiple bit depths, then using PIX_FMT_YUV420P16* with the bpp stored separately
+    //is better
     PIX_FMT_YUV420P9BE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
     PIX_FMT_YUV420P9LE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
     PIX_FMT_YUV420P10BE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
@@ -116,6 +122,13 @@
     PIX_FMT_YUV422P9BE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
     PIX_FMT_YUV422P9LE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
     PIX_FMT_VDA_VLD,    ///< hardware decoding through VDA
+
+#ifdef AV_PIX_FMT_ABI_GIT_MASTER
+    PIX_FMT_RGBA64BE,  ///< 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
+    PIX_FMT_RGBA64LE,  ///< 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 little-endian
+    PIX_FMT_BGRA64BE,  ///< 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 big-endian
+    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
     PIX_FMT_GBRP,      ///< planar GBR 4:4:4 24bpp
     PIX_FMT_GBRP9BE,   ///< planar GBR 4:4:4 27bpp, big endian
     PIX_FMT_GBRP9LE,   ///< planar GBR 4:4:4 27bpp, little endian
@@ -123,6 +136,36 @@
     PIX_FMT_GBRP10LE,  ///< planar GBR 4:4:4 30bpp, little endian
     PIX_FMT_GBRP16BE,  ///< planar GBR 4:4:4 48bpp, big endian
     PIX_FMT_GBRP16LE,  ///< planar GBR 4:4:4 48bpp, little endian
-    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
 
+#ifndef AV_PIX_FMT_ABI_GIT_MASTER
+    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
+    PIX_FMT_RGBA64LE,  ///< 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 little-endian
+    PIX_FMT_BGRA64BE,  ///< 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 big-endian
+    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
+    PIX_FMT_0RGB=0x123+4,      ///< packed RGB 8:8:8, 32bpp, 0RGB0RGB...
+    PIX_FMT_RGB0,      ///< packed RGB 8:8:8, 32bpp, RGB0RGB0...
+    PIX_FMT_0BGR,      ///< packed BGR 8:8:8, 32bpp, 0BGR0BGR...
+    PIX_FMT_BGR0,      ///< packed BGR 8:8:8, 32bpp, BGR0BGR0...
+    PIX_FMT_YUVA444P,  ///< planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
+    PIX_FMT_YUVA422P,  ///< planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
+
+    PIX_FMT_YUV420P12BE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    PIX_FMT_YUV420P12LE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    PIX_FMT_YUV420P14BE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    PIX_FMT_YUV420P14LE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    PIX_FMT_YUV422P12BE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    PIX_FMT_YUV422P12LE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    PIX_FMT_YUV422P14BE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    PIX_FMT_YUV422P14LE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    PIX_FMT_YUV444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    PIX_FMT_YUV444P12LE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+    PIX_FMT_YUV444P14BE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    PIX_FMT_YUV444P14LE, ///< planar YUV 4:4:4,42bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
+    PIX_FMT_GBRP12BE,    ///< planar GBR 4:4:4 36bpp, big endian
+    PIX_FMT_GBRP12LE,    ///< planar GBR 4:4:4 36bpp, little endian
+    PIX_FMT_GBRP14BE,    ///< planar GBR 4:4:4 42bpp, big endian
+    PIX_FMT_GBRP14LE,    ///< planar GBR 4:4:4 42bpp, little endian
+
+    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
 #endif /* AVUTIL_OLD_PIX_FMTS_H */
diff --git a/libavutil/opt.c b/libavutil/opt.c
index b1ccf9b..ed475ec 100644
--- a/libavutil/opt.c
+++ b/libavutil/opt.c
@@ -2,20 +2,20 @@
  * AVOptions
  * Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -32,16 +32,17 @@
 #include "eval.h"
 #include "dict.h"
 #include "log.h"
+#include "parseutils.h"
+#include "pixdesc.h"
 #include "mathematics.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)
 {
-    AVClass *c= *(AVClass**)v; //FIXME silly way of storing AVClass
-    const AVOption *o= c->option;
+    const AVOption *o = NULL;
 
-    for (; o && o->name; o++) {
+    while ((o = av_next_option(v, o))) {
         if (!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) && (o->flags & mask) == flags)
             return o;
     }
@@ -59,7 +60,8 @@
 const AVOption *av_opt_next(void *obj, const AVOption *last)
 {
     AVClass *class = *(AVClass**)obj;
-    if (!last && class->option[0].name) return class->option;
+    if (!last && class->option && class->option[0].name)
+        return class->option;
     if (last && last[1].name)           return ++last;
     return NULL;
 }
@@ -75,6 +77,7 @@
     case AV_OPT_TYPE_RATIONAL:  *intnum = ((AVRational*)dst)->num;
                                 *den    = ((AVRational*)dst)->den;
                                                         return 0;
+    case AV_OPT_TYPE_CONST:     *num    = o->default_val.dbl; return 0;
     }
     return AVERROR(EINVAL);
 }
@@ -82,7 +85,7 @@
 static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum)
 {
     if (o->max*den < num*intnum || o->min*den > num*intnum) {
-        av_log(obj, AV_LOG_ERROR, "Value %lf for parameter '%s' out of range\n",
+        av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range\n",
                num*intnum/den, o->name);
         return AVERROR(ERANGE);
     }
@@ -233,11 +236,12 @@
 
 int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
 {
+    int ret;
     void *dst, *target_obj;
     const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj);
     if (!o || !target_obj)
         return AVERROR_OPTION_NOT_FOUND;
-    if (!val)
+    if (!val && (o->type != AV_OPT_TYPE_STRING && o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_IMAGE_SIZE))
         return AVERROR(EINVAL);
 
     dst = ((uint8_t*)target_obj) + o->offset;
@@ -250,6 +254,31 @@
     case AV_OPT_TYPE_FLOAT:
     case AV_OPT_TYPE_DOUBLE:
     case AV_OPT_TYPE_RATIONAL: return set_string_number(obj, o, val, dst);
+    case AV_OPT_TYPE_IMAGE_SIZE:
+        if (!val || !strcmp(val, "none")) {
+            *(int *)dst = *((int *)dst + 1) = 0;
+            return 0;
+        }
+        ret = av_parse_video_size(dst, ((int *)dst) + 1, val);
+        if (ret < 0)
+            av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val);
+        return ret;
+    case AV_OPT_TYPE_PIXEL_FMT:
+        if (!val || !strcmp(val, "none"))
+            ret = AV_PIX_FMT_NONE;
+        else {
+            ret = av_get_pix_fmt(val);
+            if (ret == AV_PIX_FMT_NONE) {
+                char *tail;
+                ret = strtol(val, &tail, 0);
+                if (*tail || (unsigned)ret >= AV_PIX_FMT_NB) {
+                    av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as pixel format\n", val);
+                    return AVERROR(EINVAL);
+                }
+            }
+        }
+        *(enum AVPixelFormat *)dst = ret;
+        return 0;
     }
 
     av_log(obj, AV_LOG_ERROR, "Invalid option type.\n");
@@ -362,7 +391,7 @@
  */
 const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len)
 {
-    const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);
+    const AVOption *o = av_opt_find(obj, name, NULL, 0, AV_OPT_SEARCH_CHILDREN);
     void *dst;
     uint8_t *bin;
     int len, i;
@@ -381,6 +410,7 @@
     case AV_OPT_TYPE_FLOAT:     snprintf(buf, buf_len, "%f" , *(float  *)dst);break;
     case AV_OPT_TYPE_DOUBLE:    snprintf(buf, buf_len, "%f" , *(double *)dst);break;
     case AV_OPT_TYPE_RATIONAL:  snprintf(buf, buf_len, "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
+    case AV_OPT_TYPE_CONST:     snprintf(buf, buf_len, "%f" , o->default_val.dbl);break;
     case AV_OPT_TYPE_STRING:    return *(void**)dst;
     case AV_OPT_TYPE_BINARY:
         len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *));
@@ -401,7 +431,7 @@
     uint8_t *bin, buf[128];
     int len, i, ret;
 
-    if (!o || !target_obj)
+    if (!o || !target_obj || (o->offset<=0 && o->type != AV_OPT_TYPE_CONST))
         return AVERROR_OPTION_NOT_FOUND;
 
     dst = (uint8_t*)target_obj + o->offset;
@@ -414,6 +444,7 @@
     case AV_OPT_TYPE_FLOAT:     ret = snprintf(buf, sizeof(buf), "%f" ,     *(float  *)dst);break;
     case AV_OPT_TYPE_DOUBLE:    ret = snprintf(buf, sizeof(buf), "%f" ,     *(double *)dst);break;
     case AV_OPT_TYPE_RATIONAL:  ret = snprintf(buf, sizeof(buf), "%d/%d",   ((AVRational*)dst)->num, ((AVRational*)dst)->den);break;
+    case AV_OPT_TYPE_CONST:     ret = snprintf(buf, sizeof(buf), "%f" ,     o->default_val.dbl);break;
     case AV_OPT_TYPE_STRING:
         if (*(uint8_t**)dst)
             *out_val = av_strdup(*(uint8_t**)dst);
@@ -430,6 +461,12 @@
         for (i = 0; i < len; i++)
             snprintf(*out_val + i*2, 3, "%02X", bin[i]);
         return 0;
+    case AV_OPT_TYPE_IMAGE_SIZE:
+        ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
+        break;
+    case AV_OPT_TYPE_PIXEL_FMT:
+        ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none"));
+        break;
     default:
         return AVERROR(EINVAL);
     }
@@ -599,6 +636,12 @@
             case AV_OPT_TYPE_BINARY:
                 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<binary>");
                 break;
+            case AV_OPT_TYPE_IMAGE_SIZE:
+                av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<image_size>");
+                break;
+            case AV_OPT_TYPE_PIXEL_FMT:
+                av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "<pix_fmt>");
+                break;
             case AV_OPT_TYPE_CONST:
             default:
                 av_log(av_log_obj, AV_LOG_INFO, "%-7s ", "");
@@ -606,6 +649,7 @@
         }
         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_ENCODING_PARAM) ? 'E' : '.');
         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_DECODING_PARAM) ? 'D' : '.');
+        av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_FILTERING_PARAM)? 'F' : '.');
         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM   ) ? 'V' : '.');
         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM   ) ? 'A' : '.');
         av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.');
@@ -669,6 +713,8 @@
             }
             break;
             case AV_OPT_TYPE_STRING:
+            case AV_OPT_TYPE_IMAGE_SIZE:
+            case AV_OPT_TYPE_PIXEL_FMT:
                 av_opt_set(s, opt->name, opt->default_val.str, 0);
                 break;
             case AV_OPT_TYPE_BINARY:
@@ -713,7 +759,7 @@
         return AVERROR(EINVAL);
     }
 
-    av_log(ctx, AV_LOG_DEBUG, "Setting value '%s' for key '%s'\n", val, key);
+    av_log(ctx, AV_LOG_DEBUG, "Setting entry with key '%s' to value '%s'\n", key, val);
 
     ret = av_opt_set(ctx, key, val, 0);
     if (ret == AVERROR_OPTION_NOT_FOUND)
@@ -744,6 +790,95 @@
     return count;
 }
 
+#define WHITESPACES " \n\t"
+
+static int is_key_char(char c)
+{
+    return (unsigned)((c | 32) - 'a') < 26 ||
+           (unsigned)(c - '0') < 10 ||
+           c == '-' || c == '_' || c == '/' || c == '.';
+}
+
+/**
+ * Read a key from a string.
+ *
+ * The key consists of is_key_char characters and must be terminated by a
+ * character from the delim string; spaces are ignored. The key buffer must
+ * be 4 bytes larger than the longest acceptable key. If the key is too
+ * long, an ellipsis will be written at the end.
+ *
+ * @return  0 for success (even with ellipsis), <0 for failure
+ */
+static int get_key(const char **ropts, const char *delim, char *key, unsigned key_size)
+{
+    unsigned key_pos = 0;
+    const char *opts = *ropts;
+
+    opts += strspn(opts, WHITESPACES);
+    while (is_key_char(*opts)) {
+        key[key_pos++] = *opts;
+        if (key_pos == key_size)
+            key_pos--;
+        (opts)++;
+    }
+    opts += strspn(opts, WHITESPACES);
+    if (!*opts || !strchr(delim, *opts))
+        return AVERROR(EINVAL);
+    opts++;
+    key[key_pos++] = 0;
+    if (key_pos == key_size)
+        key[key_pos - 4] = key[key_pos - 3] = key[key_pos - 2] = '.';
+    *ropts = opts;
+    return 0;
+}
+
+int av_opt_set_from_string(void *ctx, const char *opts,
+                           const char *const *shorthand,
+                           const char *key_val_sep, const char *pairs_sep)
+{
+    int ret, count = 0;
+    const char *dummy_shorthand = NULL;
+    char key_buf[68], *value;
+    const char *key;
+
+    if (!opts)
+        return 0;
+    if (!shorthand)
+        shorthand = &dummy_shorthand;
+
+    while (*opts) {
+        if ((ret = get_key(&opts, key_val_sep, key_buf, sizeof(key_buf))) < 0) {
+            if (*shorthand) {
+                key = *(shorthand++);
+            } else {
+                av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts);
+                return AVERROR(EINVAL);
+            }
+        } else {
+            key = key_buf;
+            while (*shorthand) /* discard all remaining shorthand */
+                shorthand++;
+        }
+
+        if (!(value = av_get_token(&opts, pairs_sep)))
+            return AVERROR(ENOMEM);
+        if (*opts && strchr(pairs_sep, *opts))
+            opts++;
+
+        av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
+        if ((ret = av_opt_set(ctx, key, value, 0)) < 0) {
+            if (ret == AVERROR_OPTION_NOT_FOUND)
+                av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
+            av_free(value);
+            return ret;
+        }
+
+        av_free(value);
+        count++;
+    }
+    return count;
+}
+
 void av_opt_free(void *obj)
 {
     const AVOption *o = NULL;
@@ -782,9 +917,14 @@
 const AVOption *av_opt_find2(void *obj, const char *name, const char *unit,
                              int opt_flags, int search_flags, void **target_obj)
 {
-    const AVClass  *c = *(AVClass**)obj;
+    const AVClass  *c;
     const AVOption *o = NULL;
 
+    if(!obj)
+        return NULL;
+
+    c= *(AVClass**)obj;
+
     if (search_flags & AV_OPT_SEARCH_CHILDREN) {
         if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) {
             const AVClass *child = NULL;
@@ -802,7 +942,7 @@
     while (o = av_opt_next(obj, o)) {
         if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags &&
             ((!unit && o->type != AV_OPT_TYPE_CONST) ||
-             (unit  && o->unit && !strcmp(o->unit, unit)))) {
+             (unit  && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) {
             if (target_obj) {
                 if (!(search_flags & AV_OPT_SEARCH_FAKE_OBJ))
                     *target_obj = obj;
@@ -830,6 +970,14 @@
     return NULL;
 }
 
+void *av_opt_ptr(const AVClass *class, void *obj, const char *name)
+{
+    const AVOption *opt= av_opt_find2(&class, name, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ, NULL);
+    if(!opt)
+        return NULL;
+    return (uint8_t*)obj + opt->offset;
+}
+
 #ifdef TEST
 
 #undef printf
@@ -842,6 +990,8 @@
     char *string;
     int flags;
     AVRational rational;
+    int w, h;
+    enum AVPixelFormat pix_fmt;
 } TestContext;
 
 #define OFFSET(x) offsetof(TestContext, x)
@@ -859,6 +1009,8 @@
 {"cool",     "set cool flag ", 0,                AV_OPT_TYPE_CONST,    {.i64 = TEST_FLAG_COOL}, INT_MIN,  INT_MAX, 0, "flags" },
 {"lame",     "set lame flag ", 0,                AV_OPT_TYPE_CONST,    {.i64 = TEST_FLAG_LAME}, INT_MIN,  INT_MAX, 0, "flags" },
 {"mu",       "set mu flag ",   0,                AV_OPT_TYPE_CONST,    {.i64 = TEST_FLAG_MU},   INT_MIN,  INT_MAX, 0, "flags" },
+{"size",     "set size",       OFFSET(w),        AV_OPT_TYPE_IMAGE_SIZE,{0},             0,        0                   },
+{"pix_fmt",  "set pixfmt",     OFFSET(pix_fmt),  AV_OPT_TYPE_PIXEL_FMT,{0},              0,        0                   },
 {NULL},
 };
 
@@ -879,7 +1031,7 @@
 
     printf("\nTesting av_set_options_string()\n");
     {
-        TestContext test_ctx;
+        TestContext test_ctx = { 0 };
         const char *options[] = {
             "",
             ":",
@@ -900,6 +1052,12 @@
             "num=42 : string=blahblah",
             "rational=0 : rational=1/2 : rational=1/-1",
             "rational=-1/0",
+            "size=1024x768",
+            "size=pal",
+            "size=bogus",
+            "pix_fmt=yuv420p",
+            "pix_fmt=2",
+            "pix_fmt=bogus",
         };
 
         test_ctx.class = &test_class;
@@ -914,6 +1072,38 @@
                 av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
             printf("\n");
         }
+        av_freep(&test_ctx.string);
+    }
+
+    printf("\nTesting av_opt_set_from_string()\n");
+    {
+        TestContext test_ctx = { 0 };
+        const char *options[] = {
+            "",
+            "5",
+            "5:hello",
+            "5:hello:size=pal",
+            "5:size=pal:hello",
+            ":",
+            "=",
+            " 5 : hello : size = pal ",
+            "a_very_long_option_name_that_will_need_to_be_ellipsized_around_here=42"
+        };
+        const char *shorthand[] = { "num", "string", NULL };
+
+        test_ctx.class = &test_class;
+        av_opt_set_defaults(&test_ctx);
+        test_ctx.string = av_strdup("default");
+
+        av_log_set_level(AV_LOG_DEBUG);
+
+        for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
+            av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
+            if (av_opt_set_from_string(&test_ctx, options[i], shorthand, "=", ":") < 0)
+                av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
+            printf("\n");
+        }
+        av_freep(&test_ctx.string);
     }
 
     return 0;
diff --git a/libavutil/opt.h b/libavutil/opt.h
index 24fd74f..81fefd9 100644
--- a/libavutil/opt.h
+++ b/libavutil/opt.h
@@ -2,20 +2,20 @@
  * AVOptions
  * copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -44,7 +44,7 @@
  * This section describes how to add AVOptions capabilities to a struct.
  *
  * All AVOptions-related information is stored in an AVClass. Therefore
- * the first member of the struct must be a pointer to an AVClass describing it.
+ * the first member of the struct should be a pointer to an AVClass describing it.
  * The option field of the AVClass must be set to a NULL-terminated static array
  * of AVOptions. Each AVOption must have a non-empty name, a type, a default
  * value and for number-type AVOptions also a range of allowed values. It must
@@ -81,7 +81,7 @@
  * @endcode
  *
  * Next, when allocating your struct, you must ensure that the AVClass pointer
- * is set to the correct value. Then, av_opt_set_defaults() must be called to
+ * is set to the correct value. Then, av_opt_set_defaults() can be called to
  * initialize defaults. After that the struct is ready to be used with the
  * AVOptions API.
  *
@@ -176,7 +176,7 @@
  *
  * @section avoptions_use Using AVOptions
  * This section deals with accessing options in an AVOptions-enabled struct.
- * Such structs in Libav are e.g. AVCodecContext in libavcodec or
+ * Such structs in FFmpeg are e.g. AVCodecContext in libavcodec or
  * AVFormatContext in libavformat.
  *
  * @subsection avoptions_use_examine Examining AVOptions
@@ -225,6 +225,8 @@
     AV_OPT_TYPE_RATIONAL,
     AV_OPT_TYPE_BINARY,  ///< offset must point to a pointer immediately followed by an int for the length
     AV_OPT_TYPE_CONST = 128,
+    AV_OPT_TYPE_IMAGE_SIZE = MKBETAG('S','I','Z','E'), ///< offset must point to two consecutive integers
+    AV_OPT_TYPE_PIXEL_FMT  = MKBETAG('P','F','M','T'),
 #if FF_API_OLD_AVOPTIONS
     FF_OPT_TYPE_FLAGS = 0,
     FF_OPT_TYPE_INT,
@@ -277,6 +279,7 @@
 #define AV_OPT_FLAG_AUDIO_PARAM     8
 #define AV_OPT_FLAG_VIDEO_PARAM     16
 #define AV_OPT_FLAG_SUBTITLE_PARAM  32
+#define AV_OPT_FLAG_FILTERING_PARAM (1<<16) ///< a generic parameter which can be set by the user for filtering
 //FIXME think about enc-audio, ... style flags
 
     /**
@@ -340,9 +343,9 @@
 attribute_deprecated const AVOption *av_set_q(void *obj, const char *name, AVRational n);
 attribute_deprecated const AVOption *av_set_int(void *obj, const char *name, int64_t n);
 
-attribute_deprecated double av_get_double(void *obj, const char *name, const AVOption **o_out);
-attribute_deprecated AVRational av_get_q(void *obj, const char *name, const AVOption **o_out);
-attribute_deprecated int64_t av_get_int(void *obj, const char *name, const AVOption **o_out);
+double av_get_double(void *obj, const char *name, const AVOption **o_out);
+AVRational av_get_q(void *obj, const char *name, const AVOption **o_out);
+int64_t av_get_int(void *obj, const char *name, const AVOption **o_out);
 attribute_deprecated const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len);
 attribute_deprecated const AVOption *av_next_option(void *obj, const AVOption *last);
 #endif
@@ -376,6 +379,7 @@
  * key. ctx must be an AVClass context, storing is done using
  * AVOptions.
  *
+ * @param opts options string to parse, may be NULL
  * @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
@@ -390,6 +394,36 @@
                           const char *key_val_sep, const char *pairs_sep);
 
 /**
+ * Parse the key-value pairs list in opts. For each key=value pair found,
+ * set the value of the corresponding option in ctx.
+ *
+ * @param ctx          the AVClass object to set options on
+ * @param opts         the options string, key-value pairs separated by a
+ *                     delimiter
+ * @param shorthand    a NULL-terminated array of options names for shorthand
+ *                     notation: if the first field in opts has no key part,
+ *                     the key is taken from the first element of shorthand;
+ *                     then again for the second, etc., until either opts is
+ *                     finished, shorthand is finished or a named option is
+ *                     found; after that, all options must be named
+ * @param key_val_sep  a 0-terminated list of characters used to separate
+ *                     key from value, for example '='
+ * @param pairs_sep    a 0-terminated list of characters used to separate
+ *                     two pairs from each other, for example ':' or ','
+ * @return  the number of successfully set key=value pairs, or a negative
+ *          value corresponding to an AVERROR code in case of error:
+ *          AVERROR(EINVAL) if opts cannot be parsed,
+ *          the error code issued by av_set_string3() if a key/value pair
+ *          cannot be set
+ *
+ * Options names must use only the following characters: a-z A-Z 0-9 - . / _
+ * Separators must use characters distinct from option names and from each
+ * other.
+ */
+int av_opt_set_from_string(void *ctx, const char *opts,
+                           const char *const *shorthand,
+                           const char *key_val_sep, const char *pairs_sep);
+/**
  * Free all string and binary options in obj.
  */
 void av_opt_free(void *obj);
@@ -586,6 +620,17 @@
 int av_opt_get_q     (void *obj, const char *name, int search_flags, AVRational *out_val);
 /**
  * @}
+ */
+/**
+ * Gets a pointer to the requested field in a struct.
+ * This function allows accessing a struct even when its fields are moved or
+ * renamed since the application making the access has been compiled,
+ *
+ * @returns a pointer to the field, it can be cast to the correct type and read
+ *          or written to.
+ */
+void *av_opt_ptr(const AVClass *avclass, void *obj, const char *name);
+/**
  * @}
  */
 
diff --git a/libavutil/parseutils.c b/libavutil/parseutils.c
index 28aa9c9..84bb9f7 100644
--- a/libavutil/parseutils.c
+++ b/libavutil/parseutils.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -31,6 +31,43 @@
 #include "random_seed.h"
 #include "parseutils.h"
 
+#undef time
+
+#ifdef TEST
+
+#define av_get_random_seed av_get_random_seed_deterministic
+static uint32_t av_get_random_seed_deterministic(void);
+
+#define time(t) 1331972053
+
+#endif
+
+int av_parse_ratio(AVRational *q, const char *str, int max,
+                   int log_offset, void *log_ctx)
+{
+    char c;
+    int ret;
+    int64_t gcd;
+
+    if (sscanf(str, "%d:%d%c", &q->num, &q->den, &c) != 2) {
+        double d;
+        ret = av_expr_parse_and_eval(&d, str, NULL, NULL,
+                                     NULL, NULL, NULL, NULL,
+                                     NULL, log_offset, log_ctx);
+        if (ret < 0)
+            return ret;
+        *q = av_d2q(d, max);
+    }
+
+    gcd = av_gcd(FFABS(q->num), FFABS(q->den));
+    if (gcd) {
+        q->num /= gcd;
+        q->den /= gcd;
+    }
+
+    return 0;
+}
+
 typedef struct {
     const char *abbr;
     int width, height;
@@ -96,7 +133,7 @@
 {
     int i;
     int n = FF_ARRAY_ELEMS(video_size_abbrs);
-    char *p;
+    const char *p;
     int width = 0, height = 0;
 
     for (i = 0; i < n; i++) {
@@ -107,10 +144,10 @@
         }
     }
     if (i == n) {
-        width = strtol(str, &p, 10);
+        width = strtol(str, (void*)&p, 10);
         if (*p)
             p++;
-        height = strtol(p, &p, 10);
+        height = strtol(p, (void*)&p, 10);
     }
     if (width <= 0 || height <= 0)
         return AVERROR(EINVAL);
@@ -123,7 +160,6 @@
 {
     int i, ret;
     int n = FF_ARRAY_ELEMS(video_rate_abbrs);
-    double res;
 
     /* First, we check our abbreviation table */
     for (i = 0; i < n; ++i)
@@ -133,10 +169,8 @@
         }
 
     /* Then, we try to parse it as fraction */
-    if ((ret = av_expr_parse_and_eval(&res, arg, NULL, NULL, NULL, NULL, NULL, NULL,
-                                      NULL, 0, NULL)) < 0)
+    if ((ret = av_parse_ratio_quiet(rate, arg, 1001000)) < 0)
         return ret;
-    *rate = av_d2q(res, 1001000);
     if (rate->num <= 0 || rate->den <= 0)
         return AVERROR(EINVAL);
     return 0;
@@ -147,7 +181,7 @@
     uint8_t     rgb_color[3];    ///< RGB values for the color
 } ColorEntry;
 
-static ColorEntry color_table[] = {
+static const ColorEntry color_table[] = {
     { "AliceBlue",            { 0xF0, 0xF8, 0xFF } },
     { "AntiqueWhite",         { 0xFA, 0xEB, 0xD7 } },
     { "Aqua",                 { 0x00, 0xFF, 0xFF } },
@@ -215,8 +249,8 @@
     { "LightCoral",           { 0xF0, 0x80, 0x80 } },
     { "LightCyan",            { 0xE0, 0xFF, 0xFF } },
     { "LightGoldenRodYellow", { 0xFA, 0xFA, 0xD2 } },
-    { "LightGrey",            { 0xD3, 0xD3, 0xD3 } },
     { "LightGreen",           { 0x90, 0xEE, 0x90 } },
+    { "LightGrey",            { 0xD3, 0xD3, 0xD3 } },
     { "LightPink",            { 0xFF, 0xB6, 0xC1 } },
     { "LightSalmon",          { 0xFF, 0xA0, 0x7A } },
     { "LightSeaGreen",        { 0x20, 0xB2, 0xAA } },
@@ -359,7 +393,11 @@
         if (!strncmp(alpha_string, "0x", 2)) {
             alpha = strtoul(alpha_string, &tail, 16);
         } else {
-            alpha = 255 * strtod(alpha_string, &tail);
+            double norm_alpha = strtod(alpha_string, &tail);
+            if (norm_alpha < 0.0 || norm_alpha > 1.0)
+                alpha = 256;
+            else
+                alpha = 255 * norm_alpha;
         }
 
         if (tail == alpha_string || *tail || alpha > 255 || alpha < 0) {
@@ -399,14 +437,20 @@
     return val;
 }
 
-static const char *small_strptime(const char *p, const char *fmt, struct tm *dt)
+char *av_small_strptime(const char *p, const char *fmt, struct tm *dt)
 {
     int c, val;
 
     for(;;) {
+        /* consume time string until a non whitespace char is found */
+        while (isspace(*fmt)) {
+            while (isspace(*p))
+                p++;
+            fmt++;
+        }
         c = *fmt++;
         if (c == '\0') {
-            return p;
+            return (char *)p;
         } else if (c == '%') {
             c = *fmt++;
             switch(c) {
@@ -481,9 +525,11 @@
 
 int av_parse_time(int64_t *timeval, const char *timestr, int duration)
 {
-    const char *p;
+    const char *p, *q;
     int64_t t;
+    time_t now;
     struct tm dt = { 0 };
+    int today = 0, negative = 0, microseconds = 0;
     int i;
     static const char * const date_fmt[] = {
         "%Y-%m-%d",
@@ -493,59 +539,41 @@
         "%H:%M:%S",
         "%H%M%S",
     };
-    const char *q;
-    int is_utc, len;
-    char lastch;
-    int negative = 0;
-
-#undef time
-    time_t now = time(0);
-
-    len = strlen(timestr);
-    if (len > 0)
-        lastch = timestr[len - 1];
-    else
-        lastch = '\0';
-    is_utc = (lastch == 'z' || lastch == 'Z');
 
     p = timestr;
     q = NULL;
+    *timeval = INT64_MIN;
     if (!duration) {
-        if (!av_strncasecmp(timestr, "now", len)) {
+        now = time(0);
+
+        if (!av_strcasecmp(timestr, "now")) {
             *timeval = (int64_t) now * 1000000;
             return 0;
         }
 
         /* parse the year-month-day part */
         for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) {
-            q = small_strptime(p, date_fmt[i], &dt);
-            if (q) {
+            q = av_small_strptime(p, date_fmt[i], &dt);
+            if (q)
                 break;
-            }
         }
 
         /* if the year-month-day part is missing, then take the
          * current year-month-day time */
         if (!q) {
-            if (is_utc) {
-                dt = *gmtime(&now);
-            } else {
-                dt = *localtime(&now);
-            }
-            dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
-        } else {
-            p = q;
+            today = 1;
+            q = p;
         }
+        p = q;
 
         if (*p == 'T' || *p == 't' || *p == ' ')
             p++;
 
         /* parse the hour-minute-second part */
         for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
-            q = small_strptime(p, time_fmt[i], &dt);
-            if (q) {
+            q = av_small_strptime(p, time_fmt[i], &dt);
+            if (q)
                 break;
-            }
         }
     } else {
         /* parse timestr as a duration */
@@ -554,50 +582,55 @@
             ++p;
         }
         /* parse timestr as HH:MM:SS */
-        q = small_strptime(p, time_fmt[0], &dt);
+        q = av_small_strptime(p, time_fmt[0], &dt);
         if (!q) {
             /* parse timestr as S+ */
-            dt.tm_sec = strtol(p, (char **)&q, 10);
-            if (q == p) {
-                /* the parsing didn't succeed */
-                *timeval = INT64_MIN;
+            dt.tm_sec = strtol(p, (void *)&q, 10);
+            if (q == p) /* the parsing didn't succeed */
                 return AVERROR(EINVAL);
-            }
             dt.tm_min = 0;
             dt.tm_hour = 0;
         }
     }
 
     /* Now we have all the fields that we can get */
-    if (!q) {
-        *timeval = INT64_MIN;
+    if (!q)
         return AVERROR(EINVAL);
+
+    /* parse the .m... part */
+    if (*q == '.') {
+        int n;
+        q++;
+        for (n = 100000; n >= 1; n /= 10, q++) {
+            if (!isdigit(*q))
+                break;
+            microseconds += n * (*q - '0');
+        }
+        while (isdigit(*q))
+            q++;
     }
 
     if (duration) {
         t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
     } else {
-        dt.tm_isdst = -1;       /* unknown */
-        if (is_utc) {
-            t = av_timegm(&dt);
-        } else {
-            t = mktime(&dt);
+        int is_utc = *q == 'Z' || *q == 'z';
+        q += is_utc;
+        if (today) { /* fill in today's date */
+            struct tm dt2 = is_utc ? *gmtime(&now) : *localtime(&now);
+            dt2.tm_hour = dt.tm_hour;
+            dt2.tm_min  = dt.tm_min;
+            dt2.tm_sec  = dt.tm_sec;
+            dt = dt2;
         }
+        t = is_utc ? av_timegm(&dt) : mktime(&dt);
     }
 
+    /* Check that we are at the end of the string */
+    if (*q)
+        return AVERROR(EINVAL);
+
     t *= 1000000;
-
-    /* parse the .m... part */
-    if (*q == '.') {
-        int val, n;
-        q++;
-        for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
-            if (!isdigit(*q))
-                break;
-            val += n * (*q - '0');
-        }
-        t += val;
-    }
+    t += microseconds;
     *timeval = negative ? -t : t;
     return 0;
 }
@@ -643,6 +676,13 @@
 
 #ifdef TEST
 
+static uint32_t random = MKTAG('L','A','V','U');
+
+static uint32_t av_get_random_seed_deterministic(void)
+{
+    return random = random * 1664525 + 1013904223;
+}
+
 #undef printf
 
 int main(void)
@@ -692,6 +732,8 @@
         int i;
         uint8_t rgba[4];
         static const char *const color_names[] = {
+            "bikeshed",
+            "RaNdOm",
             "foo",
             "red",
             "Red ",
@@ -734,6 +776,84 @@
             if (av_parse_color(rgba, color_names[i], -1, NULL) >= 0)
                 printf("%s -> R(%d) G(%d) B(%d) A(%d)\n",
                        color_names[i], rgba[0], rgba[1], rgba[2], rgba[3]);
+            else
+                printf("%s -> error\n", color_names[i]);
+        }
+    }
+
+    printf("\nTesting av_small_strptime()\n");
+    {
+        int i;
+        struct tm tm = { 0 };
+        struct fmt_timespec_entry {
+            const char *fmt, *timespec;
+        } fmt_timespec_entries[] = {
+            { "%Y-%m-%d",                    "2012-12-21" },
+            { "%Y - %m - %d",                "2012-12-21" },
+            { "%Y-%m-%d %H:%M:%S",           "2012-12-21 20:12:21" },
+            { "  %Y - %m - %d %H : %M : %S", "   2012 - 12 -  21   20 : 12 : 21" },
+        };
+
+        av_log_set_level(AV_LOG_DEBUG);
+        for (i = 0;  i < FF_ARRAY_ELEMS(fmt_timespec_entries); i++) {
+            char *p;
+            struct fmt_timespec_entry *e = &fmt_timespec_entries[i];
+            printf("fmt:'%s' spec:'%s' -> ", e->fmt, e->timespec);
+            p = av_small_strptime(e->timespec, e->fmt, &tm);
+            if (p) {
+                printf("%04d-%02d-%2d %02d:%02d:%02d\n",
+                       1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday,
+                       tm.tm_hour, tm.tm_min, tm.tm_sec);
+            } else {
+                printf("error\n");
+            }
+        }
+    }
+
+    printf("\nTesting av_parse_time()\n");
+    {
+        int i;
+        int64_t tv;
+        time_t tvi;
+        struct tm *tm;
+        static char tzstr[] = "TZ=CET-1";
+        const char *time_string[] = {
+            "now",
+            "12:35:46",
+            "2000-12-20 0:02:47.5z",
+            "2000-12-20T010247.6",
+        };
+        const char *duration_string[] = {
+            "2:34:56.79",
+            "-1:23:45.67",
+            "42.1729",
+            "-1729.42",
+            "12:34",
+        };
+
+        av_log_set_level(AV_LOG_DEBUG);
+        putenv(tzstr);
+        printf("(now is 2012-03-17 09:14:13 +0100, local time is UTC+1)\n");
+        for (i = 0;  i < FF_ARRAY_ELEMS(time_string); i++) {
+            printf("%-24s -> ", time_string[i]);
+            if (av_parse_time(&tv, time_string[i], 0)) {
+                printf("error\n");
+            } else {
+                tvi = tv / 1000000;
+                tm = gmtime(&tvi);
+                printf("%14"PRIi64".%06d = %04d-%02d-%02dT%02d:%02d:%02dZ\n",
+                       tv / 1000000, (int)(tv % 1000000),
+                       tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
+                       tm->tm_hour, tm->tm_min, tm->tm_sec);
+            }
+        }
+        for (i = 0;  i < FF_ARRAY_ELEMS(duration_string); i++) {
+            printf("%-24s -> ", duration_string[i]);
+            if (av_parse_time(&tv, duration_string[i], 1)) {
+                printf("error\n");
+            } else {
+                printf("%+21"PRIi64"\n", tv);
+            }
         }
     }
 
diff --git a/libavutil/parseutils.h b/libavutil/parseutils.h
index 0844abb..da7d345 100644
--- a/libavutil/parseutils.h
+++ b/libavutil/parseutils.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -29,6 +29,30 @@
  */
 
 /**
+ * Parse str and store the parsed ratio in q.
+ *
+ * Note that a ratio with infinite (1/0) or negative value is
+ * considered valid, so you should check on the returned value if you
+ * want to exclude those values.
+ *
+ * The undefined value can be expressed using the "0:0" string.
+ *
+ * @param[in,out] q pointer to the AVRational which will contain the ratio
+ * @param[in] str the string to parse: it has to be a string in the format
+ * num:den, a float number or an expression
+ * @param[in] max the maximum allowed numerator and denominator
+ * @param[in] log_offset log level offset which is applied to the log
+ * level of log_ctx
+ * @param[in] log_ctx parent logging context
+ * @return >= 0 on success, a negative error code otherwise
+ */
+int av_parse_ratio(AVRational *q, const char *str, int max,
+                   int log_offset, void *log_ctx);
+
+#define av_parse_ratio_quiet(rate, str, max) \
+    av_parse_ratio(rate, str, max, AV_LOG_MAX_OFFSET, NULL)
+
+/**
  * Parse str and put in width_ptr and height_ptr the detected values.
  *
  * @param[in,out] width_ptr pointer to the variable which will contain the detected
@@ -88,7 +112,7 @@
  * @param timestr a string representing a date or a duration.
  * - If a date the syntax is:
  * @code
- * [{YYYY-MM-DD|YYYYMMDD}[T|t| ]]{{HH[:MM[:SS[.m...]]]}|{HH[MM[SS[.m...]]]}}[Z]
+ * [{YYYY-MM-DD|YYYYMMDD}[T|t| ]]{{HH:MM:SS[.m...]]]}|{HHMMSS[.m...]]]}}[Z]
  * now
  * @endcode
  * If the value is "now" it takes the current time.
@@ -98,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
@@ -109,6 +133,31 @@
 int av_parse_time(int64_t *timeval, const char *timestr, int duration);
 
 /**
+ * Parse the input string p according to the format string fmt and
+ * store its results in the structure dt.
+ * This implementation supports only a subset of the formats supported
+ * by the standard strptime().
+ *
+ * In particular it actually supports the parameters:
+ * - %H: the hour as a decimal number, using a 24-hour clock, in the
+ * range '00' through '23'
+ * - %M: the minute as a decimal number, using a 24-hour clock, in the
+ * range '00' through '59'
+ * - %S: the second as a decimal number, using a 24-hour clock, in the
+ * range '00' through '59'
+ * - %Y: the year as a decimal number, using the Gregorian calendar
+ * - %m: the month as a decimal number, in the range '1' through '12'
+ * - %d: the day of the month as a decimal number, in the range '1'
+ * through '31'
+ * - %%: a literal '%'
+ *
+ * @return a pointer to the first character not processed in this
+ * function call, or NULL in case the function fails to match all of
+ * the fmt string and therefore an error occurred
+ */
+char *av_small_strptime(const char *p, const char *fmt, struct tm *dt);
+
+/**
  * Attempt to find a specific tag in a URL.
  *
  * syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done.
diff --git a/libavutil/pca.c b/libavutil/pca.c
new file mode 100644
index 0000000..54927a2
--- /dev/null
+++ b/libavutil/pca.c
@@ -0,0 +1,248 @@
+/*
+ * principal component analysis (PCA)
+ * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * principal component analysis (PCA)
+ */
+
+#include "common.h"
+#include "pca.h"
+
+typedef struct PCA{
+    int count;
+    int n;
+    double *covariance;
+    double *mean;
+    double *z;
+}PCA;
+
+PCA *ff_pca_init(int n){
+    PCA *pca;
+    if(n<=0)
+        return NULL;
+
+    pca= av_mallocz(sizeof(PCA));
+    pca->n= n;
+    pca->z = av_malloc(sizeof(*pca->z) * n);
+    pca->count=0;
+    pca->covariance= av_mallocz(sizeof(double)*n*n);
+    pca->mean= av_mallocz(sizeof(double)*n);
+
+    return pca;
+}
+
+void ff_pca_free(PCA *pca){
+    av_freep(&pca->covariance);
+    av_freep(&pca->mean);
+    av_freep(&pca->z);
+    av_free(pca);
+}
+
+void ff_pca_add(PCA *pca, double *v){
+    int i, j;
+    const int n= pca->n;
+
+    for(i=0; i<n; i++){
+        pca->mean[i] += v[i];
+        for(j=i; j<n; j++)
+            pca->covariance[j + i*n] += v[i]*v[j];
+    }
+    pca->count++;
+}
+
+int ff_pca(PCA *pca, double *eigenvector, double *eigenvalue){
+    int i, j, pass;
+    int k=0;
+    const int n= pca->n;
+    double *z = pca->z;
+
+    memset(eigenvector, 0, sizeof(double)*n*n);
+
+    for(j=0; j<n; j++){
+        pca->mean[j] /= pca->count;
+        eigenvector[j + j*n] = 1.0;
+        for(i=0; i<=j; i++){
+            pca->covariance[j + i*n] /= pca->count;
+            pca->covariance[j + i*n] -= pca->mean[i] * pca->mean[j];
+            pca->covariance[i + j*n] = pca->covariance[j + i*n];
+        }
+        eigenvalue[j]= pca->covariance[j + j*n];
+        z[j]= 0;
+    }
+
+    for(pass=0; pass < 50; pass++){
+        double sum=0;
+
+        for(i=0; i<n; i++)
+            for(j=i+1; j<n; j++)
+                sum += fabs(pca->covariance[j + i*n]);
+
+        if(sum == 0){
+            for(i=0; i<n; i++){
+                double maxvalue= -1;
+                for(j=i; j<n; j++){
+                    if(eigenvalue[j] > maxvalue){
+                        maxvalue= eigenvalue[j];
+                        k= j;
+                    }
+                }
+                eigenvalue[k]= eigenvalue[i];
+                eigenvalue[i]= maxvalue;
+                for(j=0; j<n; j++){
+                    double tmp= eigenvector[k + j*n];
+                    eigenvector[k + j*n]= eigenvector[i + j*n];
+                    eigenvector[i + j*n]= tmp;
+                }
+            }
+            return pass;
+        }
+
+        for(i=0; i<n; i++){
+            for(j=i+1; j<n; j++){
+                double covar= pca->covariance[j + i*n];
+                double t,c,s,tau,theta, h;
+
+                if(pass < 3 && fabs(covar) < sum / (5*n*n)) //FIXME why pass < 3
+                    continue;
+                if(fabs(covar) == 0.0) //FIXME should not be needed
+                    continue;
+                if(pass >=3 && fabs((eigenvalue[j]+z[j])/covar) > (1LL<<32) && fabs((eigenvalue[i]+z[i])/covar) > (1LL<<32)){
+                    pca->covariance[j + i*n]=0.0;
+                    continue;
+                }
+
+                h= (eigenvalue[j]+z[j]) - (eigenvalue[i]+z[i]);
+                theta=0.5*h/covar;
+                t=1.0/(fabs(theta)+sqrt(1.0+theta*theta));
+                if(theta < 0.0) t = -t;
+
+                c=1.0/sqrt(1+t*t);
+                s=t*c;
+                tau=s/(1.0+c);
+                z[i] -= t*covar;
+                z[j] += t*covar;
+
+#define ROTATE(a,i,j,k,l) {\
+    double g=a[j + i*n];\
+    double h=a[l + k*n];\
+    a[j + i*n]=g-s*(h+g*tau);\
+    a[l + k*n]=h+s*(g-h*tau); }
+                for(k=0; k<n; k++) {
+                    if(k!=i && k!=j){
+                        ROTATE(pca->covariance,FFMIN(k,i),FFMAX(k,i),FFMIN(k,j),FFMAX(k,j))
+                    }
+                    ROTATE(eigenvector,k,i,k,j)
+                }
+                pca->covariance[j + i*n]=0.0;
+            }
+        }
+        for (i=0; i<n; i++) {
+            eigenvalue[i] += z[i];
+            z[i]=0.0;
+        }
+    }
+
+    return -1;
+}
+
+#ifdef TEST
+
+#undef printf
+#include <stdio.h>
+#include <stdlib.h>
+#include "lfg.h"
+
+int main(void){
+    PCA *pca;
+    int i, j, k;
+#define LEN 8
+    double eigenvector[LEN*LEN];
+    double eigenvalue[LEN];
+    AVLFG prng;
+
+    av_lfg_init(&prng, 1);
+
+    pca= ff_pca_init(LEN);
+
+    for(i=0; i<9000000; i++){
+        double v[2*LEN+100];
+        double sum=0;
+        int pos = av_lfg_get(&prng) % LEN;
+        int v2  = av_lfg_get(&prng) % 101 - 50;
+        v[0]    = av_lfg_get(&prng) % 101 - 50;
+        for(j=1; j<8; j++){
+            if(j<=pos) v[j]= v[0];
+            else       v[j]= v2;
+            sum += v[j];
+        }
+/*        for(j=0; j<LEN; j++){
+            v[j] -= v[pos];
+        }*/
+//        sum += av_lfg_get(&prng) % 10;
+/*        for(j=0; j<LEN; j++){
+            v[j] -= sum/LEN;
+        }*/
+//        lbt1(v+100,v+100,LEN);
+        ff_pca_add(pca, v);
+    }
+
+
+    ff_pca(pca, eigenvector, eigenvalue);
+    for(i=0; i<LEN; i++){
+        pca->count= 1;
+        pca->mean[i]= 0;
+
+//        (0.5^|x|)^2 = 0.5^2|x| = 0.25^|x|
+
+
+//        pca.covariance[i + i*LEN]= pow(0.5, fabs
+        for(j=i; j<LEN; j++){
+            printf("%f ", pca->covariance[i + j*LEN]);
+        }
+        printf("\n");
+    }
+
+    for(i=0; i<LEN; i++){
+        double v[LEN];
+        double error=0;
+        memset(v, 0, sizeof(v));
+        for(j=0; j<LEN; j++){
+            for(k=0; k<LEN; k++){
+                v[j] += pca->covariance[FFMIN(k,j) + FFMAX(k,j)*LEN] * eigenvector[i + k*LEN];
+            }
+            v[j] /= eigenvalue[i];
+            error += fabs(v[j] - eigenvector[i + j*LEN]);
+        }
+        printf("%f ", error);
+    }
+    printf("\n");
+
+    for(i=0; i<LEN; i++){
+        for(j=0; j<LEN; j++){
+            printf("%9.6f ", eigenvector[i + j*LEN]);
+        }
+        printf("  %9.1f %f\n", eigenvalue[i], eigenvalue[i]/eigenvalue[0]);
+    }
+
+    return 0;
+}
+#endif
diff --git a/libavutil/pca.h b/libavutil/pca.h
new file mode 100644
index 0000000..00ddd60
--- /dev/null
+++ b/libavutil/pca.h
@@ -0,0 +1,35 @@
+/*
+ * principal component analysis (PCA)
+ * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * principal component analysis (PCA)
+ */
+
+#ifndef AVUTIL_PCA_H
+#define AVUTIL_PCA_H
+
+struct PCA *ff_pca_init(int n);
+void ff_pca_free(struct PCA *pca);
+void ff_pca_add(struct PCA *pca, double *v);
+int ff_pca(struct PCA *pca, double *eigenvector, double *eigenvalue);
+
+#endif /* AVUTIL_PCA_H */
diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index b8cfabd..3b5f264 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -2,20 +2,20 @@
  * pixel format descriptor
  * Copyright (c) 2009 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -169,9 +169,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 2, 1, 0, 7 },        /* B */
-            { 0, 2, 2, 0, 7 },        /* G */
             { 0, 2, 3, 0, 7 },        /* R */
+            { 0, 2, 2, 0, 7 },        /* G */
+            { 0, 2, 1, 0, 7 },        /* B */
         },
         .flags = PIX_FMT_RGB,
     },
@@ -231,6 +231,7 @@
         .comp = {
             { 0, 0, 1, 0, 7 },        /* Y */
         },
+        .flags = PIX_FMT_PSEUDOPAL,
     },
     [AV_PIX_FMT_MONOWHITE] = {
         .name = "monow",
@@ -292,9 +293,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            {0, 0, 1, 0, 7},        /* Y */
-            {1, 0, 1, 0, 7},        /* U */
-            {2, 0, 1, 0, 7},        /* V */
+            { 0, 0, 1, 0, 7 },        /* Y */
+            { 1, 0, 1, 0, 7 },        /* U */
+            { 2, 0, 1, 0, 7 },        /* V */
         },
         .flags = PIX_FMT_PLANAR,
     },
@@ -334,9 +335,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 0, 1, 6, 1 },        /* B */
-            { 0, 0, 1, 3, 2 },        /* G */
             { 0, 0, 1, 0, 2 },        /* R */
+            { 0, 0, 1, 3, 2 },        /* G */
+            { 0, 0, 1, 6, 1 },        /* B */
         },
         .flags = PIX_FMT_RGB | PIX_FMT_PSEUDOPAL,
     },
@@ -346,9 +347,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 3, 1, 0, 0 },        /* B */
-            { 0, 3, 2, 0, 1 },        /* G */
             { 0, 3, 4, 0, 0 },        /* R */
+            { 0, 3, 2, 0, 1 },        /* G */
+            { 0, 3, 1, 0, 0 },        /* B */
         },
         .flags = PIX_FMT_BITSTREAM | PIX_FMT_RGB,
     },
@@ -358,9 +359,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 0, 1, 3, 0 },        /* B */
-            { 0, 0, 1, 1, 1 },        /* G */
             { 0, 0, 1, 0, 0 },        /* R */
+            { 0, 0, 1, 1, 1 },        /* G */
+            { 0, 0, 1, 3, 0 },        /* B */
         },
         .flags = PIX_FMT_RGB | PIX_FMT_PSEUDOPAL,
     },
@@ -419,8 +420,8 @@
         .log2_chroma_h = 1,
         .comp = {
             { 0, 0, 1, 0, 7 },        /* Y */
-            { 1, 1, 1, 0, 7 },        /* V */
             { 1, 1, 2, 0, 7 },        /* U */
+            { 1, 1, 1, 0, 7 },        /* V */
         },
         .flags = PIX_FMT_PLANAR,
     },
@@ -430,10 +431,10 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 3, 1, 0, 7 },        /* A */
             { 0, 3, 2, 0, 7 },        /* R */
             { 0, 3, 3, 0, 7 },        /* G */
             { 0, 3, 4, 0, 7 },        /* B */
+            { 0, 3, 1, 0, 7 },        /* A */
         },
         .flags = PIX_FMT_RGB,
     },
@@ -456,10 +457,10 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 3, 1, 0, 7 },        /* A */
-            { 0, 3, 2, 0, 7 },        /* B */
-            { 0, 3, 3, 0, 7 },        /* G */
             { 0, 3, 4, 0, 7 },        /* R */
+            { 0, 3, 3, 0, 7 },        /* G */
+            { 0, 3, 2, 0, 7 },        /* B */
+            { 0, 3, 1, 0, 7 },        /* A */
         },
         .flags = PIX_FMT_RGB,
     },
@@ -469,9 +470,59 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 3, 1, 0, 7 },        /* B */
-            { 0, 3, 2, 0, 7 },        /* G */
             { 0, 3, 3, 0, 7 },        /* R */
+            { 0, 3, 2, 0, 7 },        /* G */
+            { 0, 3, 1, 0, 7 },        /* B */
+            { 0, 3, 4, 0, 7 },        /* A */
+        },
+        .flags = PIX_FMT_RGB,
+    },
+    [AV_PIX_FMT_0RGB] = {
+        .name = "0rgb",
+        .nb_components= 3,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            { 0, 3, 2, 0, 7 },        /* R */
+            { 0, 3, 3, 0, 7 },        /* G */
+            { 0, 3, 4, 0, 7 },        /* B */
+        },
+        .flags = PIX_FMT_RGB,
+    },
+    [AV_PIX_FMT_RGB0] = {
+        .name = "rgb0",
+        .nb_components= 3,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            { 0, 3, 1, 0, 7 },        /* R */
+            { 0, 3, 2, 0, 7 },        /* G */
+            { 0, 3, 3, 0, 7 },        /* B */
+            { 0, 3, 4, 0, 7 },        /* A */
+        },
+        .flags = PIX_FMT_RGB,
+    },
+    [AV_PIX_FMT_0BGR] = {
+        .name = "0bgr",
+        .nb_components= 3,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            { 0, 3, 4, 0, 7 },        /* R */
+            { 0, 3, 3, 0, 7 },        /* G */
+            { 0, 3, 2, 0, 7 },        /* B */
+        },
+        .flags = PIX_FMT_RGB,
+    },
+    [AV_PIX_FMT_BGR0] = {
+        .name = "bgr0",
+        .nb_components= 3,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            { 0, 3, 3, 0, 7 },        /* R */
+            { 0, 3, 2, 0, 7 },        /* G */
+            { 0, 3, 1, 0, 7 },        /* B */
             { 0, 3, 4, 0, 7 },        /* A */
         },
         .flags = PIX_FMT_RGB,
@@ -532,7 +583,7 @@
         },
         .flags = PIX_FMT_PLANAR,
     },
-        [AV_PIX_FMT_YUVA422P] = {
+    [AV_PIX_FMT_YUVA422P] = {
         .name = "yuva422p",
         .nb_components = 4,
         .log2_chroma_w = 1,
@@ -618,6 +669,32 @@
         },
         .flags = PIX_FMT_RGB,
     },
+    [AV_PIX_FMT_RGBA64BE] = {
+        .name = "rgba64be",
+        .nb_components= 4,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            { 0, 7, 1, 0, 15 },       /* R */
+            { 0, 7, 3, 0, 15 },       /* G */
+            { 0, 7, 5, 0, 15 },       /* B */
+            { 0, 7, 7, 0, 15 },       /* A */
+        },
+        .flags = PIX_FMT_RGB | PIX_FMT_BE,
+    },
+    [AV_PIX_FMT_RGBA64LE] = {
+        .name = "rgba64le",
+        .nb_components= 4,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            { 0, 7, 1, 0, 15 },       /* R */
+            { 0, 7, 3, 0, 15 },       /* G */
+            { 0, 7, 5, 0, 15 },       /* B */
+            { 0, 7, 7, 0, 15 },       /* A */
+        },
+        .flags = PIX_FMT_RGB,
+    },
     [AV_PIX_FMT_RGB565BE] = {
         .name = "rgb565be",
         .nb_components = 3,
@@ -696,9 +773,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 5, 1, 0, 15 },       /* B */
-            { 0, 5, 3, 0, 15 },       /* G */
             { 0, 5, 5, 0, 15 },       /* R */
+            { 0, 5, 3, 0, 15 },       /* G */
+            { 0, 5, 1, 0, 15 },       /* B */
         },
         .flags = PIX_FMT_BE | PIX_FMT_RGB,
     },
@@ -708,9 +785,35 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 5, 1, 0, 15 },       /* B */
-            { 0, 5, 3, 0, 15 },       /* G */
             { 0, 5, 5, 0, 15 },       /* R */
+            { 0, 5, 3, 0, 15 },       /* G */
+            { 0, 5, 1, 0, 15 },       /* B */
+        },
+        .flags = PIX_FMT_RGB,
+    },
+    [AV_PIX_FMT_BGRA64BE] = {
+        .name = "bgra64be",
+        .nb_components= 4,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            { 0, 7, 5, 0, 15 },       /* R */
+            { 0, 7, 3, 0, 15 },       /* G */
+            { 0, 7, 1, 0, 15 },       /* B */
+            { 0, 7, 7, 0, 15 },       /* A */
+        },
+        .flags = PIX_FMT_BE | PIX_FMT_RGB,
+    },
+    [AV_PIX_FMT_BGRA64LE] = {
+        .name = "bgra64le",
+        .nb_components= 4,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            { 0, 7, 5, 0, 15 },       /* R */
+            { 0, 7, 3, 0, 15 },       /* G */
+            { 0, 7, 1, 0, 15 },       /* B */
+            { 0, 7, 7, 0, 15 },       /* A */
         },
         .flags = PIX_FMT_RGB,
     },
@@ -720,9 +823,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 1, 0, 3, 4 },        /* B */
-            { 0, 1, 1, 5, 5 },        /* G */
             { 0, 1, 1, 0, 4 },        /* R */
+            { 0, 1, 1, 5, 5 },        /* G */
+            { 0, 1, 0, 3, 4 },        /* B */
         },
         .flags = PIX_FMT_BE | PIX_FMT_RGB,
     },
@@ -732,9 +835,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 1, 2, 3, 4 },        /* B */
-            { 0, 1, 1, 5, 5 },        /* G */
             { 0, 1, 1, 0, 4 },        /* R */
+            { 0, 1, 1, 5, 5 },        /* G */
+            { 0, 1, 2, 3, 4 },        /* B */
         },
         .flags = PIX_FMT_RGB,
     },
@@ -744,9 +847,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 1, 0, 2, 4 },       /* B */
-            { 0, 1, 1, 5, 4 },       /* G */
             { 0, 1, 1, 0, 4 },       /* R */
+            { 0, 1, 1, 5, 4 },       /* G */
+            { 0, 1, 0, 2, 4 },       /* B */
         },
         .flags = PIX_FMT_BE | PIX_FMT_RGB,
      },
@@ -756,9 +859,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 1, 2, 2, 4 },        /* B */
-            { 0, 1, 1, 5, 4 },        /* G */
             { 0, 1, 1, 0, 4 },        /* R */
+            { 0, 1, 1, 5, 4 },        /* G */
+            { 0, 1, 2, 2, 4 },        /* B */
         },
         .flags = PIX_FMT_RGB,
     },
@@ -768,9 +871,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 1, 0, 0, 3 },       /* B */
-            { 0, 1, 1, 4, 3 },       /* G */
             { 0, 1, 1, 0, 3 },       /* R */
+            { 0, 1, 1, 4, 3 },       /* G */
+            { 0, 1, 0, 0, 3 },       /* B */
         },
         .flags = PIX_FMT_BE | PIX_FMT_RGB,
      },
@@ -780,9 +883,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
-            { 0, 1, 2, 0, 3 },        /* B */
-            { 0, 1, 1, 4, 3 },        /* G */
             { 0, 1, 1, 0, 3 },        /* R */
+            { 0, 1, 1, 4, 3 },        /* G */
+            { 0, 1, 2, 0, 3 },        /* B */
         },
         .flags = PIX_FMT_RGB,
     },
@@ -804,12 +907,6 @@
         .log2_chroma_h = 1,
         .flags = PIX_FMT_HWACCEL,
     },
-    [AV_PIX_FMT_VDA_VLD] = {
-        .name = "vda_vld",
-        .log2_chroma_w = 1,
-        .log2_chroma_h = 1,
-        .flags = PIX_FMT_HWACCEL,
-    },
     [AV_PIX_FMT_YUV420P9LE] = {
         .name = "yuv420p9le",
         .nb_components = 3,
@@ -858,6 +955,54 @@
         },
         .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
     },
+    [AV_PIX_FMT_YUV420P12LE] = {
+        .name = "yuv420p12le",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 1,
+        .comp = {
+            { 0, 1, 1, 0, 11 },        /* Y */
+            { 1, 1, 1, 0, 11 },        /* U */
+            { 2, 1, 1, 0, 11 },        /* V */
+        },
+        .flags = PIX_FMT_PLANAR,
+    },
+    [AV_PIX_FMT_YUV420P12BE] = {
+        .name = "yuv420p12be",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 1,
+        .comp = {
+            { 0, 1, 1, 0, 11 },        /* Y */
+            { 1, 1, 1, 0, 11 },        /* U */
+            { 2, 1, 1, 0, 11 },        /* V */
+        },
+        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+    },
+    [AV_PIX_FMT_YUV420P14LE] = {
+        .name = "yuv420p14le",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 1,
+        .comp = {
+            { 0, 1, 1, 0, 13 },        /* Y */
+            { 1, 1, 1, 0, 13 },        /* U */
+            { 2, 1, 1, 0, 13 },        /* V */
+        },
+        .flags = PIX_FMT_PLANAR,
+    },
+    [AV_PIX_FMT_YUV420P14BE] = {
+        .name = "yuv420p14be",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 1,
+        .comp = {
+            { 0, 1, 1, 0, 13 },        /* Y */
+            { 1, 1, 1, 0, 13 },        /* U */
+            { 2, 1, 1, 0, 13 },        /* V */
+        },
+        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+    },
     [AV_PIX_FMT_YUV420P16LE] = {
         .name = "yuv420p16le",
         .nb_components = 3,
@@ -930,6 +1075,54 @@
         },
         .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
     },
+    [AV_PIX_FMT_YUV422P12LE] = {
+        .name = "yuv422p12le",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 1, 1, 0, 11 },        /* Y */
+            { 1, 1, 1, 0, 11 },        /* U */
+            { 2, 1, 1, 0, 11 },        /* V */
+        },
+        .flags = PIX_FMT_PLANAR,
+    },
+    [AV_PIX_FMT_YUV422P12BE] = {
+        .name = "yuv422p12be",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 1, 1, 0, 11 },        /* Y */
+            { 1, 1, 1, 0, 11 },        /* U */
+            { 2, 1, 1, 0, 11 },        /* V */
+        },
+        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+    },
+    [AV_PIX_FMT_YUV422P14LE] = {
+        .name = "yuv422p14le",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 1, 1, 0, 13 },        /* Y */
+            { 1, 1, 1, 0, 13 },        /* U */
+            { 2, 1, 1, 0, 13 },        /* V */
+        },
+        .flags = PIX_FMT_PLANAR,
+    },
+    [AV_PIX_FMT_YUV422P14BE] = {
+        .name = "yuv422p14be",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 1, 1, 0, 13 },        /* Y */
+            { 1, 1, 1, 0, 13 },        /* U */
+            { 2, 1, 1, 0, 13 },        /* V */
+        },
+        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+    },
     [AV_PIX_FMT_YUV422P16LE] = {
         .name = "yuv422p16le",
         .nb_components = 3,
@@ -1026,14 +1219,68 @@
         },
         .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
     },
+    [AV_PIX_FMT_YUV444P12LE] = {
+        .name = "yuv444p12le",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 1, 1, 0, 11 },        /* Y */
+            { 1, 1, 1, 0, 11 },        /* U */
+            { 2, 1, 1, 0, 11 },        /* V */
+        },
+        .flags = PIX_FMT_PLANAR,
+    },
+    [AV_PIX_FMT_YUV444P12BE] = {
+        .name = "yuv444p12be",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 1, 1, 0, 11 },        /* Y */
+            { 1, 1, 1, 0, 11 },        /* U */
+            { 2, 1, 1, 0, 11 },        /* V */
+        },
+        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+    },
+    [AV_PIX_FMT_YUV444P14LE] = {
+        .name = "yuv444p14le",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 1, 1, 0, 13 },        /* Y */
+            { 1, 1, 1, 0, 13 },        /* U */
+            { 2, 1, 1, 0, 13 },        /* V */
+        },
+        .flags = PIX_FMT_PLANAR,
+    },
+    [AV_PIX_FMT_YUV444P14BE] = {
+        .name = "yuv444p14be",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 1, 1, 0, 13 },        /* Y */
+            { 1, 1, 1, 0, 13 },        /* U */
+            { 2, 1, 1, 0, 13 },        /* V */
+        },
+        .flags = PIX_FMT_BE | PIX_FMT_PLANAR,
+    },
     [AV_PIX_FMT_DXVA2_VLD] = {
         .name = "dxva2_vld",
         .log2_chroma_w = 1,
         .log2_chroma_h = 1,
         .flags = PIX_FMT_HWACCEL,
     },
-    [AV_PIX_FMT_Y400A] = {
-        .name = "y400a",
+    [AV_PIX_FMT_VDA_VLD] = {
+        .name = "vda_vld",
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 1,
+        .flags = PIX_FMT_HWACCEL,
+    },
+    [AV_PIX_FMT_GRAY8A] = {
+        .name = "gray8a",
         .nb_components = 2,
         .comp = {
             { 0, 1, 1, 0, 7 },        /* Y */
@@ -1046,9 +1293,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
+            { 2, 0, 1, 0, 7 },        /* R */
             { 0, 0, 1, 0, 7 },        /* G */
             { 1, 0, 1, 0, 7 },        /* B */
-            { 2, 0, 1, 0, 7 },        /* R */
         },
         .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
     },
@@ -1058,9 +1305,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
+            { 2, 1, 1, 0, 8 },        /* R */
             { 0, 1, 1, 0, 8 },        /* G */
             { 1, 1, 1, 0, 8 },        /* B */
-            { 2, 1, 1, 0, 8 },        /* R */
         },
         .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
     },
@@ -1070,9 +1317,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
+            { 2, 1, 1, 0, 8 },        /* R */
             { 0, 1, 1, 0, 8 },        /* G */
             { 1, 1, 1, 0, 8 },        /* B */
-            { 2, 1, 1, 0, 8 },        /* R */
         },
         .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
     },
@@ -1082,9 +1329,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
+            { 2, 1, 1, 0, 9 },        /* R */
             { 0, 1, 1, 0, 9 },        /* G */
             { 1, 1, 1, 0, 9 },        /* B */
-            { 2, 1, 1, 0, 9 },        /* R */
         },
         .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
     },
@@ -1094,9 +1341,57 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
+            { 2, 1, 1, 0, 9 },        /* R */
             { 0, 1, 1, 0, 9 },        /* G */
             { 1, 1, 1, 0, 9 },        /* B */
-            { 2, 1, 1, 0, 9 },        /* R */
+        },
+        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
+    },
+    [AV_PIX_FMT_GBRP12LE] = {
+        .name = "gbrp12le",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 2, 1, 1, 0, 11 },        /* R */
+            { 0, 1, 1, 0, 11 },        /* G */
+            { 1, 1, 1, 0, 11 },        /* B */
+        },
+        .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+    },
+    [AV_PIX_FMT_GBRP12BE] = {
+        .name = "gbrp12be",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 2, 1, 1, 0, 11 },        /* R */
+            { 0, 1, 1, 0, 11 },        /* G */
+            { 1, 1, 1, 0, 11 },        /* B */
+        },
+        .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
+    },
+    [AV_PIX_FMT_GBRP14LE] = {
+        .name = "gbrp14le",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 2, 1, 1, 0, 13 },        /* R */
+            { 0, 1, 1, 0, 13 },        /* G */
+            { 1, 1, 1, 0, 13 },        /* B */
+        },
+        .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
+    },
+    [AV_PIX_FMT_GBRP14BE] = {
+        .name = "gbrp14be",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 2, 1, 1, 0, 13 },        /* R */
+            { 0, 1, 1, 0, 13 },        /* G */
+            { 1, 1, 1, 0, 13 },        /* B */
         },
         .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
     },
@@ -1106,9 +1401,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
+            { 2, 1, 1, 0, 15 },       /* R */
             { 0, 1, 1, 0, 15 },       /* G */
             { 1, 1, 1, 0, 15 },       /* B */
-            { 2, 1, 1, 0, 15 },       /* R */
         },
         .flags = PIX_FMT_PLANAR | PIX_FMT_RGB,
     },
@@ -1118,9 +1413,9 @@
         .log2_chroma_w = 0,
         .log2_chroma_h = 0,
         .comp = {
+            { 2, 1, 1, 0, 15 },       /* R */
             { 0, 1, 1, 0, 15 },       /* G */
             { 1, 1, 1, 0, 15 },       /* B */
-            { 2, 1, 1, 0, 15 },       /* R */
         },
         .flags = PIX_FMT_BE | PIX_FMT_PLANAR | PIX_FMT_RGB,
     },
diff --git a/libavutil/pixdesc.h b/libavutil/pixdesc.h
index 7da17bc..ccbee9b 100644
--- a/libavutil/pixdesc.h
+++ b/libavutil/pixdesc.h
@@ -2,20 +2,20 @@
  * pixel format descriptor
  * Copyright (c) 2009 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -76,9 +76,12 @@
     uint8_t flags;
 
     /**
-     * Parameters that describe how pixels are packed. If the format
-     * has chroma components, they must be stored in comp[1] and
-     * comp[2].
+     * Parameters that describe how pixels are packed.
+     * If the format has 2 or 4 components, then alpha is last.
+     * If the format has 1 or 2 components, then luma is 0.
+     * If the format has 3 or 4 components,
+     * if the RGB flag is set then 0 is red, 1 is green and 2 is blue;
+     * otherwise 0 is luma, 1 is chroma-U and 2 is chroma-V.
      */
     AVComponentDescriptor comp[4];
 }AVPixFmtDescriptor;
@@ -90,7 +93,7 @@
 #define PIX_FMT_PLANAR   16 ///< At least one pixel component is not in the first data plane
 #define PIX_FMT_RGB      32 ///< The pixel format contains RGB-like data (as opposed to YUV/grayscale)
 /**
- * The pixel format is "pseudo-paletted". This means that Libav treats it as
+ * The pixel format is "pseudo-paletted". This means that FFmpeg treats it as
  * paletted internally, but the palette is generated by the decoder and is not
  * stored in the file.
  */
@@ -148,7 +151,7 @@
  * For example in a little-endian system, first looks for "gray16",
  * then for "gray16le".
  *
- * Finally if no pixel format has been found, returns PIX_FMT_NONE.
+ * Finally if no pixel format has been found, returns AV_PIX_FMT_NONE.
  */
 enum AVPixelFormat av_get_pix_fmt(const char *name);
 
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index b11a034..ef7a16a 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,6 +30,9 @@
 #include "libavutil/avconfig.h"
 #include "libavutil/version.h"
 
+#define AVPALETTE_SIZE 1024
+#define AVPALETTE_COUNT 256
+
 /**
  * Pixel format.
  *
@@ -135,9 +138,13 @@
     AV_PIX_FMT_RGB444BE,  ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), big-endian, most significant bits to 0
     AV_PIX_FMT_BGR444LE,  ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), little-endian, most significant bits to 1
     AV_PIX_FMT_BGR444BE,  ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), big-endian, most significant bits to 1
-    AV_PIX_FMT_Y400A,     ///< 8bit gray, 8bit alpha
+    AV_PIX_FMT_GRAY8A,    ///< 8bit gray, 8bit alpha
     AV_PIX_FMT_BGR48BE,   ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as big-endian
     AV_PIX_FMT_BGR48LE,   ///< packed RGB 16:16:16, 48bpp, 16B, 16G, 16R, the 2-byte value for each R/G/B component is stored as little-endian
+
+    //the following 10 formats have the disadvantage of needing 1 format for each bit depth, thus
+    //If you want to support multiple bit depths, then using AV_PIX_FMT_YUV420P16* with the bpp stored separately
+    //is better
     AV_PIX_FMT_YUV420P9BE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
     AV_PIX_FMT_YUV420P9LE, ///< planar YUV 4:2:0, 13.5bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
     AV_PIX_FMT_YUV420P10BE,///< planar YUV 4:2:0, 15bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
@@ -151,6 +158,13 @@
     AV_PIX_FMT_YUV422P9BE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
     AV_PIX_FMT_YUV422P9LE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
     AV_PIX_FMT_VDA_VLD,    ///< hardware decoding through VDA
+
+#ifdef AV_PIX_FMT_ABI_GIT_MASTER
+    AV_PIX_FMT_RGBA64BE,  ///< 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
+    AV_PIX_FMT_RGBA64LE,  ///< 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 little-endian
+    AV_PIX_FMT_BGRA64BE,  ///< 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 big-endian
+    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
@@ -158,8 +172,45 @@
     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_YUVA422P,  ///< planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
+
+    /**
+     * duplicated pixel formats for compatibility with libav.
+     * FFmpeg supports these formats since May 8 2012 and Jan 28 2012 (commits f9ca1ac7 and 143a5c55)
+     * Libav added them Oct 12 2012 with incompatible values (commit 6d5600e85)
+     */
+    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)
+
+#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
+    AV_PIX_FMT_RGBA64LE,  ///< 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 little-endian
+    AV_PIX_FMT_BGRA64BE,  ///< 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 big-endian
+    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_0RGB=0x123+4,      ///< packed RGB 8:8:8, 32bpp, 0RGB0RGB...
+    AV_PIX_FMT_RGB0,      ///< packed RGB 8:8:8, 32bpp, RGB0RGB0...
+    AV_PIX_FMT_0BGR,      ///< packed BGR 8:8:8, 32bpp, 0BGR0BGR...
+    AV_PIX_FMT_BGR0,      ///< packed BGR 8:8:8, 32bpp, BGR0BGR0...
     AV_PIX_FMT_YUVA444P,  ///< planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
+    AV_PIX_FMT_YUVA422P,  ///< planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
+
+    AV_PIX_FMT_YUV420P12BE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    AV_PIX_FMT_YUV420P12LE, ///< planar YUV 4:2:0,18bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    AV_PIX_FMT_YUV420P14BE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian
+    AV_PIX_FMT_YUV420P14LE, ///< planar YUV 4:2:0,21bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian
+    AV_PIX_FMT_YUV422P12BE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    AV_PIX_FMT_YUV422P12LE, ///< planar YUV 4:2:2,24bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    AV_PIX_FMT_YUV422P14BE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
+    AV_PIX_FMT_YUV422P14LE, ///< planar YUV 4:2:2,28bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
+    AV_PIX_FMT_YUV444P12BE, ///< planar YUV 4:4:4,36bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian
+    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_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
@@ -167,6 +218,15 @@
 #endif
 };
 
+#if AV_HAVE_INCOMPATIBLE_FORK_ABI
+#define AV_PIX_FMT_YUVA422P AV_PIX_FMT_YUVA422P_LIBAV
+#define AV_PIX_FMT_YUVA444P AV_PIX_FMT_YUVA444P_LIBAV
+#endif
+
+
+#define AV_PIX_FMT_Y400A AV_PIX_FMT_GRAY8A
+#define AV_PIX_FMT_GBR24P AV_PIX_FMT_GBRP
+
 #if AV_HAVE_BIGENDIAN
 #   define AV_PIX_FMT_NE(be, le) AV_PIX_FMT_##be
 #else
@@ -177,6 +237,8 @@
 #define AV_PIX_FMT_RGB32_1 AV_PIX_FMT_NE(RGBA, ABGR)
 #define AV_PIX_FMT_BGR32   AV_PIX_FMT_NE(ABGR, RGBA)
 #define AV_PIX_FMT_BGR32_1 AV_PIX_FMT_NE(BGRA, ARGB)
+#define AV_PIX_FMT_0RGB32  AV_PIX_FMT_NE(0RGB, BGR0)
+#define AV_PIX_FMT_0BGR32  AV_PIX_FMT_NE(0BGR, RGB0)
 
 #define AV_PIX_FMT_GRAY16 AV_PIX_FMT_NE(GRAY16BE, GRAY16LE)
 #define AV_PIX_FMT_RGB48  AV_PIX_FMT_NE(RGB48BE,  RGB48LE)
@@ -194,23 +256,38 @@
 #define AV_PIX_FMT_YUV420P10 AV_PIX_FMT_NE(YUV420P10BE, YUV420P10LE)
 #define AV_PIX_FMT_YUV422P10 AV_PIX_FMT_NE(YUV422P10BE, YUV422P10LE)
 #define AV_PIX_FMT_YUV444P10 AV_PIX_FMT_NE(YUV444P10BE, YUV444P10LE)
+#define AV_PIX_FMT_YUV420P12 AV_PIX_FMT_NE(YUV420P12BE, YUV420P12LE)
+#define AV_PIX_FMT_YUV422P12 AV_PIX_FMT_NE(YUV422P12BE, YUV422P12LE)
+#define AV_PIX_FMT_YUV444P12 AV_PIX_FMT_NE(YUV444P12BE, YUV444P12LE)
+#define AV_PIX_FMT_YUV420P14 AV_PIX_FMT_NE(YUV420P14BE, YUV420P14LE)
+#define AV_PIX_FMT_YUV422P14 AV_PIX_FMT_NE(YUV422P14BE, YUV422P14LE)
+#define AV_PIX_FMT_YUV444P14 AV_PIX_FMT_NE(YUV444P14BE, YUV444P14LE)
 #define AV_PIX_FMT_YUV420P16 AV_PIX_FMT_NE(YUV420P16BE, YUV420P16LE)
 #define AV_PIX_FMT_YUV422P16 AV_PIX_FMT_NE(YUV422P16BE, YUV422P16LE)
 #define AV_PIX_FMT_YUV444P16 AV_PIX_FMT_NE(YUV444P16BE, YUV444P16LE)
 
+#define AV_PIX_FMT_RGBA64 AV_PIX_FMT_NE(RGBA64BE, RGBA64LE)
+#define AV_PIX_FMT_BGRA64 AV_PIX_FMT_NE(BGRA64BE, BGRA64LE)
 #define AV_PIX_FMT_GBRP9     AV_PIX_FMT_NE(GBRP9BE ,    GBRP9LE)
 #define AV_PIX_FMT_GBRP10    AV_PIX_FMT_NE(GBRP10BE,    GBRP10LE)
+#define AV_PIX_FMT_GBRP12    AV_PIX_FMT_NE(GBRP12BE,    GBRP12LE)
+#define AV_PIX_FMT_GBRP14    AV_PIX_FMT_NE(GBRP14BE,    GBRP14LE)
 #define AV_PIX_FMT_GBRP16    AV_PIX_FMT_NE(GBRP16BE,    GBRP16LE)
 
 #if FF_API_PIX_FMT
 #define PixelFormat AVPixelFormat
 
+#define PIX_FMT_Y400A AV_PIX_FMT_Y400A
+#define PIX_FMT_GBR24P AV_PIX_FMT_GBR24P
+
 #define PIX_FMT_NE(be, le) AV_PIX_FMT_NE(be, le)
 
 #define PIX_FMT_RGB32   AV_PIX_FMT_RGB32
 #define PIX_FMT_RGB32_1 AV_PIX_FMT_RGB32_1
 #define PIX_FMT_BGR32   AV_PIX_FMT_BGR32
 #define PIX_FMT_BGR32_1 AV_PIX_FMT_BGR32_1
+#define PIX_FMT_0RGB32  AV_PIX_FMT_0RGB32
+#define PIX_FMT_0BGR32  AV_PIX_FMT_0BGR32
 
 #define PIX_FMT_GRAY16 AV_PIX_FMT_GRAY16
 #define PIX_FMT_RGB48  AV_PIX_FMT_RGB48
@@ -228,12 +305,22 @@
 #define PIX_FMT_YUV420P10 AV_PIX_FMT_YUV420P10
 #define PIX_FMT_YUV422P10 AV_PIX_FMT_YUV422P10
 #define PIX_FMT_YUV444P10 AV_PIX_FMT_YUV444P10
+#define PIX_FMT_YUV420P12 AV_PIX_FMT_YUV420P12
+#define PIX_FMT_YUV422P12 AV_PIX_FMT_YUV422P12
+#define PIX_FMT_YUV444P12 AV_PIX_FMT_YUV444P12
+#define PIX_FMT_YUV420P14 AV_PIX_FMT_YUV420P14
+#define PIX_FMT_YUV422P14 AV_PIX_FMT_YUV422P14
+#define PIX_FMT_YUV444P14 AV_PIX_FMT_YUV444P14
 #define PIX_FMT_YUV420P16 AV_PIX_FMT_YUV420P16
 #define PIX_FMT_YUV422P16 AV_PIX_FMT_YUV422P16
 #define PIX_FMT_YUV444P16 AV_PIX_FMT_YUV444P16
 
+#define PIX_FMT_RGBA64 AV_PIX_FMT_RGBA64
+#define PIX_FMT_BGRA64 AV_PIX_FMT_BGRA64
 #define PIX_FMT_GBRP9  AV_PIX_FMT_GBRP9
 #define PIX_FMT_GBRP10 AV_PIX_FMT_GBRP10
+#define PIX_FMT_GBRP12 AV_PIX_FMT_GBRP12
+#define PIX_FMT_GBRP14 AV_PIX_FMT_GBRP14
 #define PIX_FMT_GBRP16 AV_PIX_FMT_GBRP16
 #endif
 
diff --git a/libavutil/ppc/cpu.c b/libavutil/ppc/cpu.c
index 0025711..20837da 100644
--- a/libavutil/ppc/cpu.c
+++ b/libavutil/ppc/cpu.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -61,7 +61,7 @@
     if (err == 0)
         return has_vu ? AV_CPU_FLAG_ALTIVEC : 0;
     return 0;
-#elif CONFIG_RUNTIME_CPUDETECT
+#elif CONFIG_RUNTIME_CPUDETECT && defined(__linux__) && !ARCH_PPC64
     int proc_ver;
     // Support of mfspr PVR emulation added in Linux 2.6.17.
     __asm__ volatile("mfspr %0, 287" : "=r" (proc_ver));
diff --git a/libavutil/ppc/float_dsp_altivec.c b/libavutil/ppc/float_dsp_altivec.c
index 55e3fbe..6340e6c 100644
--- a/libavutil/ppc/float_dsp_altivec.c
+++ b/libavutil/ppc/float_dsp_altivec.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2006 Luca Barbato <lu_zero@gentoo.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/ppc/float_dsp_altivec.h b/libavutil/ppc/float_dsp_altivec.h
index 0b9425b..20c89c2 100644
--- a/libavutil/ppc/float_dsp_altivec.h
+++ b/libavutil/ppc/float_dsp_altivec.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2006 Luca Barbato <lu_zero@gentoo.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/ppc/float_dsp_init.c b/libavutil/ppc/float_dsp_init.c
index 2052764..d0ae788 100644
--- a/libavutil/ppc/float_dsp_init.c
+++ b/libavutil/ppc/float_dsp_init.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2006 Luca Barbato <lu_zero@gentoo.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/ppc/intreadwrite.h b/libavutil/ppc/intreadwrite.h
index fec54e6..3667703 100644
--- a/libavutil/ppc/intreadwrite.h
+++ b/libavutil/ppc/intreadwrite.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/ppc/timer.h b/libavutil/ppc/timer.h
index 0981d0c..155fc01 100644
--- a/libavutil/ppc/timer.h
+++ b/libavutil/ppc/timer.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2005 Luca Barbato <lu_zero@gentoo.org>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/ppc/types_altivec.h b/libavutil/ppc/types_altivec.h
index 0a4eaf8..69d8957 100644
--- a/libavutil/ppc/types_altivec.h
+++ b/libavutil/ppc/types_altivec.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2006 Guillaume Poirier <gpoirier@mplayerhq.hu>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/ppc/util_altivec.h b/libavutil/ppc/util_altivec.h
index bdbf862..7fe3150 100644
--- a/libavutil/ppc/util_altivec.h
+++ b/libavutil/ppc/util_altivec.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/qsort.h b/libavutil/qsort.h
new file mode 100644
index 0000000..30edcc8
--- /dev/null
+++ b/libavutil/qsort.h
@@ -0,0 +1,117 @@
+/*
+ * copyright (c) 2012 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 "common.h"
+
+
+/**
+ * Quicksort
+ * This sort is fast, and fully inplace but not stable and it is possible
+ * to construct input that requires O(n^2) time but this is very unlikely to
+ * happen with non constructed input.
+ */
+#define AV_QSORT(p, num, type, cmp) {\
+    void *stack[64][2];\
+    int sp= 1;\
+    stack[0][0] = p;\
+    stack[0][1] = (p)+(num)-1;\
+    while(sp){\
+        type *start= stack[--sp][0];\
+        type *end  = stack[  sp][1];\
+        while(start < end){\
+            if(start < end-1) {\
+                int checksort=0;\
+                type *right = end-2;\
+                type *left  = start+1;\
+                type *mid = start + ((end-start)>>1);\
+                if(cmp(start, end) > 0) {\
+                    if(cmp(  end, mid) > 0) FFSWAP(type, *start, *mid);\
+                    else                    FFSWAP(type, *start, *end);\
+                }else{\
+                    if(cmp(start, mid) > 0) FFSWAP(type, *start, *mid);\
+                    else checksort= 1;\
+                }\
+                if(cmp(mid, end) > 0){ \
+                    FFSWAP(type, *mid, *end);\
+                    checksort=0;\
+                }\
+                if(start == end-2) break;\
+                FFSWAP(type, end[-1], *mid);\
+                while(left <= right){\
+                    while(left<=right && cmp(left, end-1) < 0)\
+                        left++;\
+                    while(left<=right && cmp(right, end-1) > 0)\
+                        right--;\
+                    if(left <= right){\
+                        FFSWAP(type, *left, *right);\
+                        left++;\
+                        right--;\
+                    }\
+                }\
+                FFSWAP(type, end[-1], *left);\
+                if(checksort && (mid == left-1 || mid == left)){\
+                    mid= start;\
+                    while(mid<end && cmp(mid, mid+1) <= 0)\
+                        mid++;\
+                    if(mid==end)\
+                        break;\
+                }\
+                if(end-left < left-start){\
+                    stack[sp  ][0]= start;\
+                    stack[sp++][1]= right;\
+                    start = left+1;\
+                }else{\
+                    stack[sp  ][0]= left+1;\
+                    stack[sp++][1]= end;\
+                    end = right;\
+                }\
+            }else{\
+                if(cmp(start, end) > 0)\
+                    FFSWAP(type, *start, *end);\
+                break;\
+            }\
+        }\
+    }\
+}
+
+/**
+ * Merge sort, this sort requires a temporary buffer and is stable, its worst
+ * case time is O(n log n)
+ * @param p     must be a lvalue pointer, this function may exchange it with tmp
+ * @param tmp   must be a lvalue pointer, this function may exchange it with p
+ */
+#define AV_MSORT(p, tmp, num, type, cmp) {\
+    unsigned i, j, step;\
+    for(step=1; step<(num); step+=step){\
+        for(i=0; i<(num); i+=2*step){\
+            unsigned a[2] = {i, i+step};\
+            unsigned end = FFMIN(i+2*step, (num));\
+            for(j=i; a[0]<i+step && a[1]<end; j++){\
+                int idx= cmp(p+a[0], p+a[1]) > 0;\
+                tmp[j] = p[ a[idx]++ ];\
+            }\
+            if(a[0]>=i+step) a[0] = a[1];\
+            for(; j<end; j++){\
+                tmp[j] = p[ a[0]++ ];\
+            }\
+        }\
+        FFSWAP(type*, p, tmp);\
+    }\
+}
diff --git a/libavutil/random_seed.c b/libavutil/random_seed.c
index ec9caa7..c674704 100644
--- a/libavutil/random_seed.c
+++ b/libavutil/random_seed.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Baptiste Coudurier <baptiste.coudurier@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,8 +30,16 @@
 #include <fcntl.h>
 #include <math.h>
 #include <time.h>
+#include <string.h>
+#include "avassert.h"
 #include "timer.h"
 #include "random_seed.h"
+#include "sha.h"
+#include "intreadwrite.h"
+
+#ifndef TEST
+#define TEST 0
+#endif
 
 static int read_random(uint32_t *dst, const char *file)
 {
@@ -52,34 +60,46 @@
 
 static uint32_t get_generic_seed(void)
 {
+    uint8_t tmp[120];
+    struct AVSHA *sha = (void*)tmp;
     clock_t last_t  = 0;
-    int bits        = 0;
-    uint64_t random = 0;
-    unsigned i;
-    float s = 0.000000000001;
+    static uint64_t i = 0;
+    static uint32_t buffer[512] = {0};
+    unsigned char digest[20];
+    uint64_t last_i = i;
 
-    for (i = 0; bits < 64; i++) {
+    av_assert0(sizeof(tmp) >= av_sha_size);
+
+    if(TEST){
+        memset(buffer, 0, sizeof(buffer));
+        last_i = i = 0;
+    }else{
+#ifdef AV_READ_TIME
+        buffer[13] ^= AV_READ_TIME();
+        buffer[41] ^= AV_READ_TIME()>>32;
+#endif
+    }
+
+    for (;;) {
         clock_t t = clock();
-        if (last_t && fabs(t - last_t) > s || t == (clock_t) -1) {
-            if (i < 10000 && s < (1 << 24)) {
-                s += s;
-                i = t = 0;
-            } else {
-                random = 2 * random + (i & 1);
-                bits++;
-            }
+
+        if(last_t == t){
+            buffer[i&511]++;
+        }else{
+            buffer[++i&511]+= (t-last_t) % 3294638521U;
+            if(last_i && i-last_i > 4 || i-last_i > 64 || TEST && i-last_i > 8)
+                break;
         }
         last_t = t;
     }
-#ifdef AV_READ_TIME
-    random ^= AV_READ_TIME();
-#else
-    random ^= clock();
-#endif
 
-    random += random >> 32;
+    if(TEST)
+        buffer[0] = buffer[1] = 0;
 
-    return random;
+    av_sha_init(sha, 160);
+    av_sha_update(sha, (uint8_t*)buffer, sizeof(buffer));
+    av_sha_final(sha, digest);
+    return AV_RB32(digest) + AV_RB32(digest+16);
 }
 
 uint32_t av_get_random_seed(void)
@@ -103,3 +123,29 @@
         return seed;
     return get_generic_seed();
 }
+
+#if TEST
+#undef printf
+#define N 256
+#include <stdio.h>
+
+int main(void)
+{
+    int i, j, retry;
+    uint32_t seeds[N];
+
+    for (retry=0; retry<3; retry++){
+        for (i=0; i<N; i++){
+            seeds[i] = av_get_random_seed();
+            for (j=0; j<i; j++)
+                if (seeds[j] == seeds[i])
+                    goto retry;
+        }
+        printf("seeds OK\n");
+        return 0;
+        retry:;
+    }
+    printf("FAIL at %d with %X\n", j, seeds[j]);
+    return 1;
+}
+#endif
diff --git a/libavutil/random_seed.h b/libavutil/random_seed.h
index b1fad13..0462a04 100644
--- a/libavutil/random_seed.h
+++ b/libavutil/random_seed.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2009 Baptiste Coudurier <baptiste.coudurier@gmail.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -28,12 +28,11 @@
  */
 
 /**
- * Get random data.
- *
- * This function can be called repeatedly to generate more random bits
- * as needed. It is generally quite slow, and usually used to seed a
- * PRNG.  As it uses /dev/urandom and /dev/random, the quality of the
- * returned random data depends on the platform.
+ * Get a seed to use in conjunction with random functions.
+ * This function tries to provide a good seed at a best effort bases.
+ * Its possible to call this function multiple times if more bits are needed.
+ * It can be quite slow, which is why it should only be used as seed for a faster
+ * PRNG. The quality of the seed depends on the platform.
  */
 uint32_t av_get_random_seed(void);
 
diff --git a/libavutil/rational.c b/libavutil/rational.c
index 4770c54..1a833eb 100644
--- a/libavutil/rational.c
+++ b/libavutil/rational.c
@@ -2,20 +2,20 @@
  * rational numbers
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -144,3 +144,28 @@
 
     return nearest_q_idx;
 }
+
+#ifdef TEST
+int main(void)
+{
+    AVRational a,b;
+    for (a.num = -2; a.num <= 2; a.num++) {
+        for (a.den = -2; a.den <= 2; a.den++) {
+            for (b.num = -2; b.num <= 2; b.num++) {
+                for (b.den = -2; b.den <= 2; b.den++) {
+                    int c = av_cmp_q(a,b);
+                    double d = av_q2d(a) == av_q2d(b) ?
+                               0 : (av_q2d(a) - av_q2d(b));
+                    if (d > 0)       d = 1;
+                    else if (d < 0)  d = -1;
+                    else if (d != d) d = INT_MIN;
+                    if (c != d)
+                        av_log(0, AV_LOG_ERROR, "%d/%d %d/%d, %d %f\n", a.num,
+                               a.den, b.num, b.den, c,d);
+                }
+            }
+        }
+    }
+    return 0;
+}
+#endif
diff --git a/libavutil/rational.h b/libavutil/rational.h
index 5d7dab7..417e29e 100644
--- a/libavutil/rational.h
+++ b/libavutil/rational.h
@@ -2,20 +2,20 @@
  * rational numbers
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/rc4.c b/libavutil/rc4.c
index 3bf710f..4e52ba5 100644
--- a/libavutil/rc4.c
+++ b/libavutil/rc4.c
@@ -4,20 +4,20 @@
  *
  * loosely based on LibTomCrypt by Tom St Denis
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avutil.h"
diff --git a/libavutil/rc4.h b/libavutil/rc4.h
index ec3b47c..9362fd8 100644
--- a/libavutil/rc4.h
+++ b/libavutil/rc4.h
@@ -1,20 +1,20 @@
 /*
  * RC4 encryption/decryption/pseudo-random number generator
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/samplefmt.c b/libavutil/samplefmt.c
index 4f6dfd7..96cc5fb 100644
--- a/libavutil/samplefmt.c
+++ b/libavutil/samplefmt.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,7 +24,7 @@
 #include <string.h>
 
 typedef struct SampleFmtInfo {
-    const char *name;
+    char name[8];
     int bits;
     int planar;
     enum AVSampleFormat altform; ///< planar<->packed alternative form
@@ -61,6 +61,15 @@
     return AV_SAMPLE_FMT_NONE;
 }
 
+enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar)
+{
+    if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
+        return AV_SAMPLE_FMT_NONE;
+    if (sample_fmt_info[sample_fmt].planar == planar)
+        return sample_fmt;
+    return sample_fmt_info[sample_fmt].altform;
+}
+
 enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
 {
     if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB)
@@ -155,7 +164,7 @@
     if (buf_size < 0)
         return buf_size;
 
-    audio_data[0] = buf;
+    audio_data[0] = (uint8_t *)buf;
     for (ch = 1; planar && ch < nb_channels; ch++)
         audio_data[ch] = audio_data[ch-1] + line_size;
 
@@ -203,8 +212,13 @@
     dst_offset *= block_align;
     src_offset *= block_align;
 
-    for (i = 0; i < planes; i++)
-        memcpy(dst[i] + dst_offset, src[i] + src_offset, data_size);
+    if((dst[0] < src[0] ? src[0] - dst[0] : dst[0] - src[0]) >= data_size) {
+        for (i = 0; i < planes; i++)
+            memcpy(dst[i] + dst_offset, src[i] + src_offset, data_size);
+    } else {
+        for (i = 0; i < planes; i++)
+            memmove(dst[i] + dst_offset, src[i] + src_offset, data_size);
+    }
 
     return 0;
 }
diff --git a/libavutil/samplefmt.h b/libavutil/samplefmt.h
index 0641c56..17300d1 100644
--- a/libavutil/samplefmt.h
+++ b/libavutil/samplefmt.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -76,6 +76,14 @@
 enum AVSampleFormat av_get_sample_fmt(const char *name);
 
 /**
+ * Return the planar<->packed alternative form of the given sample format, or
+ * AV_SAMPLE_FMT_NONE on error. If the passed sample_fmt is already in the
+ * requested planar/packed format, the format returned is the same as the
+ * input.
+ */
+enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar);
+
+/**
  * Get the packed alternative form of the given sample format.
  *
  * If the passed sample_fmt is already in packed format, the format returned is
@@ -150,16 +158,20 @@
                                enum AVSampleFormat sample_fmt, int align);
 
 /**
- * Fill channel data pointers and linesize for samples with sample
+ * Fill plane data pointers and linesize for samples with sample
  * format sample_fmt.
  *
- * The pointers array is filled with the pointers to the samples data:
+ * The audio_data array is filled with the pointers to the samples data planes:
  * for planar, set the start point of each channel's data within the buffer,
  * for packed, set the start point of the entire buffer only.
  *
- * The linesize array is filled with the aligned size of each channel's data
- * buffer for planar layout, or the aligned size of the buffer for all channels
- * for packed layout.
+ * The value pointed to by linesize is set to the aligned size of each
+ * channel's data buffer for planar layout, or to the aligned size of the
+ * buffer for all channels for packed layout.
+ *
+ * The buffer in buf must be big enough to contain all the samples
+ * (use av_samples_get_buffer_size() to compute its minimum size),
+ * otherwise the audio_data pointers will point to invalid data.
  *
  * @see enum AVSampleFormat
  * The documentation for AVSampleFormat describes the data layout.
diff --git a/libavutil/sh4/bswap.h b/libavutil/sh4/bswap.h
index 1ff1bfd..48dd27f 100644
--- a/libavutil/sh4/bswap.h
+++ b/libavutil/sh4/bswap.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/sha.c b/libavutil/sha.c
index d583191..e3a956a 100644
--- a/libavutil/sha.c
+++ b/libavutil/sha.c
@@ -4,20 +4,20 @@
  * based on public domain SHA-1 code by Steve Reid <steve@edmweb.com>
  * and on BSD-licensed SHA-2 code by Aaron D. Gifford
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -218,7 +218,7 @@
         a = T1 + T2;
     }
 #else
-    for (i = 0; i < 16;) {
+    for (i = 0; i < 16 - 7;) {
         ROUND256_0_TO_15(a, b, c, d, e, f, g, h);
         ROUND256_0_TO_15(h, a, b, c, d, e, f, g);
         ROUND256_0_TO_15(g, h, a, b, c, d, e, f);
@@ -229,7 +229,7 @@
         ROUND256_0_TO_15(b, c, d, e, f, g, h, a);
     }
 
-    for (; i < 64;) {
+    for (; i < 64 - 7;) {
         ROUND256_16_TO_63(a, b, c, d, e, f, g, h);
         ROUND256_16_TO_63(h, a, b, c, d, e, f, g);
         ROUND256_16_TO_63(g, h, a, b, c, d, e, f);
diff --git a/libavutil/sha.h b/libavutil/sha.h
index 4c9a0c9..744c66f 100644
--- a/libavutil/sha.h
+++ b/libavutil/sha.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2007 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/softfloat.c b/libavutil/softfloat.c
new file mode 100644
index 0000000..efa0420
--- /dev/null
+++ b/libavutil/softfloat.c
@@ -0,0 +1,72 @@
+/*
+ * 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 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 <inttypes.h>
+#include <stdio.h>
+#include <assert.h>
+#include "softfloat.h"
+#include "common.h"
+#include "log.h"
+
+#undef printf
+
+int main(void){
+    SoftFloat one= av_int2sf(1, 0);
+    SoftFloat sf1, sf2;
+    double d1, d2;
+    int i, j;
+    av_log_set_level(AV_LOG_DEBUG);
+
+    d1= 1;
+    for(i= 0; i<10; i++){
+        d1= 1/(d1+1);
+    }
+    printf("test1 double=%d\n", (int)(d1 * (1<<24)));
+
+    sf1= one;
+    for(i= 0; i<10; i++){
+        sf1= av_div_sf(one, av_normalize_sf(av_add_sf(one, sf1)));
+    }
+    printf("test1 sf    =%d\n", av_sf2int(sf1, 24));
+
+
+    for(i= 0; i<100; i++){
+        START_TIMER
+        d1= i;
+        d2= i/100.0;
+        for(j= 0; j<1000; j++){
+            d1= (d1+1)*d2;
+        }
+        STOP_TIMER("float add mul")
+    }
+    printf("test2 double=%d\n", (int)(d1 * (1<<24)));
+
+    for(i= 0; i<100; i++){
+        START_TIMER
+        sf1= av_int2sf(i, 0);
+        sf2= av_div_sf(av_int2sf(i, 2), av_int2sf(200, 3));
+        for(j= 0; j<1000; j++){
+            sf1= av_mul_sf(av_add_sf(sf1, one),sf2);
+        }
+        STOP_TIMER("softfloat add mul")
+    }
+    printf("test2 sf    =%d (%d %d)\n", av_sf2int(sf1, 24), sf1.exp, sf1.mant);
+    return 0;
+}
diff --git a/libavutil/softfloat.h b/libavutil/softfloat.h
new file mode 100644
index 0000000..97e09ea
--- /dev/null
+++ b/libavutil/softfloat.h
@@ -0,0 +1,126 @@
+/*
+ * 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 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_SOFTFLOAT_H
+#define AVUTIL_SOFTFLOAT_H
+
+#include <stdint.h>
+#include "common.h"
+
+#define MIN_EXP -126
+#define MAX_EXP  126
+#define ONE_BITS 29
+
+typedef struct SoftFloat{
+    int32_t  exp;
+    int32_t mant;
+}SoftFloat;
+
+static av_const SoftFloat av_normalize_sf(SoftFloat a){
+    if(a.mant){
+#if 1
+        while((a.mant + 0x20000000U)<0x40000000U){
+            a.mant += a.mant;
+            a.exp  -= 1;
+        }
+#else
+        int s=ONE_BITS + 1 - av_log2(a.mant ^ (a.mant<<1));
+        a.exp   -= s;
+        a.mant <<= s;
+#endif
+        if(a.exp < MIN_EXP){
+            a.exp = MIN_EXP;
+            a.mant= 0;
+        }
+    }else{
+        a.exp= MIN_EXP;
+    }
+    return a;
+}
+
+static inline av_const SoftFloat av_normalize1_sf(SoftFloat a){
+#if 1
+    if(a.mant + 0x40000000 < 0){
+        a.exp++;
+        a.mant>>=1;
+    }
+    return a;
+#elif 1
+    int t= a.mant + 0x40000000 < 0;
+    return (SoftFloat){a.exp+t, a.mant>>t};
+#else
+    int t= (a.mant + 0x40000000U)>>31;
+    return (SoftFloat){a.exp+t, a.mant>>t};
+#endif
+}
+
+/**
+ * @return Will not be more denormalized than a+b. So if either input is
+ *         normalized, then the output will not be worse then the other input.
+ *         If both are normalized, then the output will be normalized.
+ */
+static inline av_const SoftFloat av_mul_sf(SoftFloat a, SoftFloat b){
+    a.exp += b.exp;
+    a.mant = (a.mant * (int64_t)b.mant) >> ONE_BITS;
+    return av_normalize1_sf(a);
+}
+
+/**
+ * b has to be normalized and not zero.
+ * @return Will not be more denormalized than a.
+ */
+static av_const SoftFloat av_div_sf(SoftFloat a, SoftFloat b){
+    a.exp -= b.exp+1;
+    a.mant = ((int64_t)a.mant<<(ONE_BITS+1)) / b.mant;
+    return av_normalize1_sf(a);
+}
+
+static inline av_const int av_cmp_sf(SoftFloat a, SoftFloat b){
+    int t= a.exp - b.exp;
+    if(t<0) return (a.mant >> (-t)) -  b.mant      ;
+    else    return  a.mant          - (b.mant >> t);
+}
+
+static inline av_const SoftFloat av_add_sf(SoftFloat a, SoftFloat b){
+    int t= a.exp - b.exp;
+    if(t<0) return av_normalize1_sf((SoftFloat){b.exp, b.mant + (a.mant >> (-t))});
+    else    return av_normalize1_sf((SoftFloat){a.exp, a.mant + (b.mant >>   t )});
+}
+
+static inline av_const SoftFloat av_sub_sf(SoftFloat a, SoftFloat b){
+    return av_add_sf(a, (SoftFloat){b.exp, -b.mant});
+}
+
+//FIXME sqrt, log, exp, pow, sin, cos
+
+static inline av_const SoftFloat av_int2sf(int v, int frac_bits){
+    return av_normalize_sf((SoftFloat){ONE_BITS-frac_bits, v});
+}
+
+/**
+ * Rounding is to -inf.
+ */
+static inline av_const int av_sf2int(SoftFloat v, int frac_bits){
+    v.exp += frac_bits - ONE_BITS;
+    if(v.exp >= 0) return v.mant <<  v.exp ;
+    else           return v.mant >>(-v.exp);
+}
+
+#endif /* AVUTIL_SOFTFLOAT_H */
diff --git a/libavutil/time.c b/libavutil/time.c
index 51779c5..27feb0b 100644
--- a/libavutil/time.c
+++ b/libavutil/time.c
@@ -1,18 +1,20 @@
 /*
- * This file is part of Libav.
+ * Copyright (c) 2000-2003 Fabrice Bellard
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/time.h b/libavutil/time.h
index b01a97d..90eb436 100644
--- a/libavutil/time.h
+++ b/libavutil/time.h
@@ -1,18 +1,20 @@
 /*
- * This file is part of Libav.
+ * Copyright (c) 2000-2003 Fabrice Bellard
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/timecode.c b/libavutil/timecode.c
new file mode 100644
index 0000000..fcbd00d
--- /dev/null
+++ b/libavutil/timecode.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2006 Smartjog S.A.S, Baptiste Coudurier <baptiste.coudurier@gmail.com>
+ * Copyright (c) 2011-2012 Smartjog S.A.S, Clément Bœsch <clement.boesch@smartjog.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
+ * Timecode helpers
+ * @see https://en.wikipedia.org/wiki/SMPTE_time_code
+ * @see http://www.dropframetimecode.org
+ */
+
+#include <stdio.h>
+#include "timecode.h"
+#include "log.h"
+#include "error.h"
+
+#ifdef FF_API_OLD_TC_ADJUST_FRAMENUM
+int av_timecode_adjust_ntsc_framenum(int framenum)
+{
+    /* only works for NTSC 29.97 */
+    int d = framenum / 17982;
+    int m = framenum % 17982;
+    //if (m < 2) m += 2; /* not needed since -2,-1 / 1798 in C returns 0 */
+    return framenum + 18 * d + 2 * ((m - 2) / 1798);
+}
+#endif
+
+int av_timecode_adjust_ntsc_framenum2(int framenum, int fps)
+{
+    /* only works for NTSC 29.97 and 59.94 */
+    int drop_frames = 0;
+    int d = framenum / 17982;
+    int m = framenum % 17982;
+
+    if (fps == 30)
+        drop_frames = 2;
+    else if (fps == 60)
+        drop_frames = 4;
+    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);
+}
+
+uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum)
+{
+    unsigned fps = tc->fps;
+    int drop = !!(tc->flags & AV_TIMECODE_FLAG_DROPFRAME);
+    int hh, mm, ss, ff;
+
+    framenum += tc->start;
+    if (drop)
+        framenum = av_timecode_adjust_ntsc_framenum2(framenum, tc->fps);
+    ff = framenum % fps;
+    ss = framenum / fps      % 60;
+    mm = framenum / (fps*60) % 60;
+    hh = framenum / (fps*3600) % 24;
+    return 0         << 31 | // color frame flag (0: unsync mode, 1: sync mode)
+           drop      << 30 | // drop  frame flag (0: non drop,    1: drop)
+           (ff / 10) << 28 | // tens  of frames
+           (ff % 10) << 24 | // units of frames
+           0         << 23 | // PC (NTSC) or BGF0 (PAL)
+           (ss / 10) << 20 | // tens  of seconds
+           (ss % 10) << 16 | // units of seconds
+           0         << 15 | // BGF0 (NTSC) or BGF2 (PAL)
+           (mm / 10) << 12 | // tens  of minutes
+           (mm % 10) <<  8 | // units of minutes
+           0         <<  7 | // BGF2 (NTSC) or PC (PAL)
+           0         <<  6 | // BGF1
+           (hh / 10) <<  4 | // tens  of hours
+           (hh % 10);        // units of hours
+}
+
+char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum)
+{
+    int fps = tc->fps;
+    int drop = tc->flags & AV_TIMECODE_FLAG_DROPFRAME;
+    int hh, mm, ss, ff, neg = 0;
+
+    framenum += tc->start;
+    if (drop)
+        framenum = av_timecode_adjust_ntsc_framenum2(framenum, fps);
+    if (framenum < 0) {
+        framenum = -framenum;
+        neg = tc->flags & AV_TIMECODE_FLAG_ALLOWNEGATIVE;
+    }
+    ff = framenum % fps;
+    ss = framenum / fps        % 60;
+    mm = framenum / (fps*60)   % 60;
+    hh = framenum / (fps*3600);
+    if (tc->flags & AV_TIMECODE_FLAG_24HOURSMAX)
+        hh = hh % 24;
+    snprintf(buf, AV_TIMECODE_STR_SIZE, "%s%02d:%02d:%02d%c%02d",
+             neg ? "-" : "",
+             hh, mm, ss, drop ? ';' : ':', ff);
+    return buf;
+}
+
+static unsigned bcd2uint(uint8_t bcd)
+{
+   unsigned low  = bcd & 0xf;
+   unsigned high = bcd >> 4;
+   if (low > 9 || high > 9)
+       return 0;
+   return low + 10*high;
+}
+
+char *av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_df)
+{
+    unsigned hh   = bcd2uint(tcsmpte     & 0x3f);    // 6-bit hours
+    unsigned mm   = bcd2uint(tcsmpte>>8  & 0x7f);    // 7-bit minutes
+    unsigned ss   = bcd2uint(tcsmpte>>16 & 0x7f);    // 7-bit seconds
+    unsigned ff   = bcd2uint(tcsmpte>>24 & 0x3f);    // 6-bit frames
+    unsigned drop = tcsmpte & 1<<30 && !prevent_df;  // 1-bit drop if not arbitrary bit
+    snprintf(buf, AV_TIMECODE_STR_SIZE, "%02u:%02u:%02u%c%02u",
+             hh, mm, ss, drop ? ';' : ':', ff);
+    return buf;
+}
+
+char *av_timecode_make_mpeg_tc_string(char *buf, uint32_t tc25bit)
+{
+    snprintf(buf, AV_TIMECODE_STR_SIZE, "%02u:%02u:%02u%c%02u",
+             tc25bit>>19 & 0x1f,              // 5-bit hours
+             tc25bit>>13 & 0x3f,              // 6-bit minutes
+             tc25bit>>6  & 0x3f,              // 6-bit seconds
+             tc25bit     & 1<<24 ? ';' : ':', // 1-bit drop flag
+             tc25bit     & 0x3f);             // 6-bit frames
+    return buf;
+}
+
+static int check_fps(int fps)
+{
+    int i;
+    static const int supported_fps[] = {24, 25, 30, 50, 60};
+
+    for (i = 0; i < FF_ARRAY_ELEMS(supported_fps); i++)
+        if (fps == supported_fps[i])
+            return 0;
+    return -1;
+}
+
+static int check_timecode(void *log_ctx, AVTimecode *tc)
+{
+    if (tc->fps <= 0) {
+        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");
+        return AVERROR(EINVAL);
+    }
+    if (check_fps(tc->fps) < 0) {
+        av_log(log_ctx, AV_LOG_ERROR, "Timecode frame rate %d/%d not supported\n",
+               tc->rate.num, tc->rate.den);
+        return AVERROR_PATCHWELCOME;
+    }
+    return 0;
+}
+
+static int fps_from_frame_rate(AVRational rate)
+{
+    if (!rate.den || !rate.num)
+        return -1;
+    return (rate.num + rate.den/2) / rate.den;
+}
+
+int av_timecode_check_frame_rate(AVRational rate)
+{
+    return check_fps(fps_from_frame_rate(rate));
+}
+
+int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx)
+{
+    memset(tc, 0, sizeof(*tc));
+    tc->start = frame_start;
+    tc->flags = flags;
+    tc->rate  = rate;
+    tc->fps   = fps_from_frame_rate(rate);
+    return check_timecode(log_ctx, tc);
+}
+
+int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx)
+{
+    char c;
+    int hh, mm, ss, ff, ret;
+
+    if (sscanf(str, "%d:%d:%d%c%d", &hh, &mm, &ss, &c, &ff) != 5) {
+        av_log(log_ctx, AV_LOG_ERROR, "Unable to parse timecode, "
+                                      "syntax: hh:mm:ss[:;.]ff\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    memset(tc, 0, sizeof(*tc));
+    tc->flags = c != ':' ? AV_TIMECODE_FLAG_DROPFRAME : 0; // drop if ';', '.', ...
+    tc->rate  = rate;
+    tc->fps   = fps_from_frame_rate(rate);
+
+    ret = check_timecode(log_ctx, tc);
+    if (ret < 0)
+        return ret;
+
+    tc->start = (hh*3600 + mm*60 + ss) * tc->fps + ff;
+    if (tc->flags & AV_TIMECODE_FLAG_DROPFRAME) { /* adjust frame number */
+        int tmins = 60*hh + mm;
+        tc->start -= 2 * (tmins - tmins/10);
+    }
+    return 0;
+}
diff --git a/libavutil/timecode.h b/libavutil/timecode.h
new file mode 100644
index 0000000..17d6b95
--- /dev/null
+++ b/libavutil/timecode.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2006 Smartjog S.A.S, Baptiste Coudurier <baptiste.coudurier@gmail.com>
+ * Copyright (c) 2011-2012 Smartjog S.A.S, Clément Bœsch <clement.boesch@smartjog.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
+ * Timecode helpers header
+ */
+
+#ifndef AVUTIL_TIMECODE_H
+#define AVUTIL_TIMECODE_H
+
+#include <stdint.h>
+#include "rational.h"
+
+#define AV_TIMECODE_STR_SIZE 16
+
+enum AVTimecodeFlag {
+    AV_TIMECODE_FLAG_DROPFRAME      = 1<<0, ///< timecode is drop frame
+    AV_TIMECODE_FLAG_24HOURSMAX     = 1<<1, ///< timecode wraps after 24 hours
+    AV_TIMECODE_FLAG_ALLOWNEGATIVE  = 1<<2, ///< negative time values are allowed
+};
+
+typedef struct {
+    int start;          ///< timecode frame start (first base frame number)
+    uint32_t flags;     ///< flags such as drop frame, +24 hours support, ...
+    AVRational rate;    ///< frame rate in rational form
+    unsigned fps;       ///< frame per second; must be consistent with the rate field
+} AVTimecode;
+
+/**
+ * Adjust frame number for NTSC drop frame time code.
+ *
+ * @param framenum frame number to adjust
+ * @return         adjusted frame number
+ * @warning        adjustment is only valid in NTSC 29.97
+ * @deprecated     use av_timecode_adjust_ntsc_framenum2 instead
+ */
+attribute_deprecated int av_timecode_adjust_ntsc_framenum(int framenum);
+
+/**
+ * Adjust frame number for NTSC drop frame time code.
+ *
+ * @param framenum frame number to adjust
+ * @param fps      frame per second, 30 or 60
+ * @return         adjusted frame number
+ * @warning        adjustment is only valid in NTSC 29.97 and 59.94
+ */
+int av_timecode_adjust_ntsc_framenum2(int framenum, int fps);
+
+/**
+ * Convert frame number to SMPTE 12M binary representation.
+ *
+ * @param tc       timecode data correctly initialized
+ * @param framenum frame number
+ * @return         the SMPTE binary representation
+ *
+ * @note Frame number adjustment is automatically done in case of drop timecode,
+ *       you do NOT have to call av_timecode_adjust_ntsc_framenum().
+ * @note The frame number is relative to tc->start.
+ * @note Color frame (CF), binary group flags (BGF) and biphase mark polarity
+ *       correction (PC) bits are set to zero.
+ */
+uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum);
+
+/**
+ * Load timecode string in buf.
+ *
+ * @param buf      destination buffer, must be at least AV_TIMECODE_STR_SIZE long
+ * @param tc       timecode data correctly initialized
+ * @param framenum frame number
+ * @return         the buf parameter
+ *
+ * @note Timecode representation can be a negative timecode and have more than
+ *       24 hours, but will only be honored if the flags are correctly set.
+ * @note The frame number is relative to tc->start.
+ */
+char *av_timecode_make_string(const AVTimecode *tc, char *buf, int framenum);
+
+/**
+ * Get the timecode string from the SMPTE timecode format.
+ *
+ * @param buf        destination buffer, must be at least AV_TIMECODE_STR_SIZE long
+ * @param tcsmpte    the 32-bit SMPTE timecode
+ * @param prevent_df prevent the use of a drop flag when it is known the DF bit
+ *                   is arbitrary
+ * @return           the buf parameter
+ */
+char *av_timecode_make_smpte_tc_string(char *buf, uint32_t tcsmpte, int prevent_df);
+
+/**
+ * Get the timecode string from the 25-bit timecode format (MPEG GOP format).
+ *
+ * @param buf     destination buffer, must be at least AV_TIMECODE_STR_SIZE long
+ * @param tc25bit the 25-bits timecode
+ * @return        the buf parameter
+ */
+char *av_timecode_make_mpeg_tc_string(char *buf, uint32_t tc25bit);
+
+/**
+ * Init a timecode struct with the passed parameters.
+ *
+ * @param log_ctx     a pointer to an arbitrary struct of which the first field
+ *                    is a pointer to an AVClass struct (used for av_log)
+ * @param tc          pointer to an allocated AVTimecode
+ * @param rate        frame rate in rational form
+ * @param flags       miscellaneous flags such as drop frame, +24 hours, ...
+ *                    (see AVTimecodeFlag)
+ * @param frame_start the first frame number
+ * @return            0 on success, AVERROR otherwise
+ */
+int av_timecode_init(AVTimecode *tc, AVRational rate, int flags, int frame_start, void *log_ctx);
+
+/**
+ * Parse timecode representation (hh:mm:ss[:;.]ff).
+ *
+ * @param log_ctx a pointer to an arbitrary struct of which the first field is a
+ *                pointer to an AVClass struct (used for av_log).
+ * @param tc      pointer to an allocated AVTimecode
+ * @param rate    frame rate in rational form
+ * @param str     timecode string which will determine the frame start
+ * @return        0 on success, AVERROR otherwise
+ */
+int av_timecode_init_from_string(AVTimecode *tc, AVRational rate, const char *str, void *log_ctx);
+
+/**
+ * Check if the timecode feature is available for the given frame rate
+ *
+ * @return 0 if supported, <0 otherwise
+ */
+int av_timecode_check_frame_rate(AVRational rate);
+
+#endif /* AVUTIL_TIMECODE_H */
diff --git a/libavutil/timer.h b/libavutil/timer.h
index ea5c891..3e242f3 100644
--- a/libavutil/timer.h
+++ b/libavutil/timer.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/timestamp.h b/libavutil/timestamp.h
new file mode 100644
index 0000000..c7348d8
--- /dev/null
+++ b/libavutil/timestamp.h
@@ -0,0 +1,74 @@
+/*
+ * 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
+ * timestamp utils, mostly useful for debugging/logging purposes
+ */
+
+#ifndef AVUTIL_TIMESTAMP_H
+#define AVUTIL_TIMESTAMP_H
+
+#include "common.h"
+
+#define AV_TS_MAX_STRING_SIZE 32
+
+/**
+ * Fill the provided buffer with a string containing a timestamp
+ * representation.
+ *
+ * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE
+ * @param ts the timestamp to represent
+ * @return the buffer in input
+ */
+static inline char *av_ts_make_string(char *buf, int64_t ts)
+{
+    if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS");
+    else                      snprintf(buf, AV_TS_MAX_STRING_SIZE, "%"PRId64"", ts);
+    return buf;
+}
+
+/**
+ * Convenience macro, the return value should be used only directly in
+ * function arguments but never stand-alone.
+ */
+#define av_ts2str(ts) av_ts_make_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts)
+
+/**
+ * Fill the provided buffer with a string containing a timestamp time
+ * representation.
+ *
+ * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE
+ * @param ts the timestamp to represent
+ * @param tb the timebase of the timestamp
+ * @return the buffer in input
+ */
+static inline char *av_ts_make_time_string(char *buf, int64_t ts, AVRational *tb)
+{
+    if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS");
+    else                      snprintf(buf, AV_TS_MAX_STRING_SIZE, "%.6g", av_q2d(*tb) * ts);
+    return buf;
+}
+
+/**
+ * Convenience macro, the return value should be used only directly in
+ * function arguments but never stand-alone.
+ */
+#define av_ts2timestr(ts, tb) av_ts_make_time_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts, tb)
+
+#endif /* AVUTIL_TIMESTAMP_H */
diff --git a/libavutil/tomi/intreadwrite.h b/libavutil/tomi/intreadwrite.h
index 9295004..778b804 100644
--- a/libavutil/tomi/intreadwrite.h
+++ b/libavutil/tomi/intreadwrite.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Mans Rullgard <mans@mansr.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/tree.c b/libavutil/tree.c
index fd51a74..cba6fe8 100644
--- a/libavutil/tree.c
+++ b/libavutil/tree.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/tree.h b/libavutil/tree.h
index 623280f..7187496 100644
--- a/libavutil/tree.h
+++ b/libavutil/tree.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -65,18 +65,21 @@
 
 /**
  * Insert or remove an element.
+ *
  * If *next is NULL, then the supplied element will be removed if it exists.
- * If *next is not NULL, then the supplied element will be inserted, unless
+ * If *next is non-NULL, then the supplied element will be inserted, unless
  * it already exists in the tree.
+ *
  * @param rootp A pointer to a pointer to the root node of the tree; note that
  *              the root node can change during insertions, this is required
  *              to keep the tree balanced.
+ * @param key  pointer to the element key to insert in the tree
  * @param next Used to allocate and free AVTreeNodes. For insertion the user
  *             must set it to an allocated and zeroed object of at least
  *             av_tree_node_size bytes size. av_tree_insert() will set it to
  *             NULL if it has been consumed.
  *             For deleting elements *next is set to NULL by the user and
- *             av_tree_node_size() will set it to the AVTreeNode which was
+ *             av_tree_insert() will set it to the AVTreeNode which was
  *             used for the removed element.
  *             This allows the use of flat arrays, which have
  *             lower overhead compared to many malloced elements.
@@ -91,6 +94,7 @@
  *                 return av_tree_insert(rootp, key, cmp, next);
  *             }
  *             @endcode
+ * @param cmp compare function used to compare elements in the tree
  * @return If no insertion happened, the found element; if an insertion or
  *         removal happened, then either key or NULL will be returned.
  *         Which one it is depends on the tree state and the implementation. You
diff --git a/libavutil/utils.c b/libavutil/utils.c
index 9b18c97..01c940c 100644
--- a/libavutil/utils.c
+++ b/libavutil/utils.c
@@ -1,23 +1,25 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "config.h"
 #include "avutil.h"
+#include "avassert.h"
+#include "samplefmt.h"
 
 /**
  * @file
@@ -26,18 +28,37 @@
 
 unsigned avutil_version(void)
 {
+    av_assert0(AV_PIX_FMT_VDA_VLD == 81); //check if the pix fmt enum has not had anything inserted or removed by mistake
+    av_assert0(AV_SAMPLE_FMT_DBLP == 9);
+    av_assert0(AVMEDIA_TYPE_ATTACHMENT == 4);
+    av_assert0(AV_PICTURE_TYPE_BI == 7);
+    av_assert0(LIBAVUTIL_VERSION_MICRO >= 100);
+    av_assert0(HAVE_MMX2 == HAVE_MMXEXT);
+
     return LIBAVUTIL_VERSION_INT;
 }
 
 const char *avutil_configuration(void)
 {
-    return LIBAV_CONFIGURATION;
+    return FFMPEG_CONFIGURATION;
 }
 
 const char *avutil_license(void)
 {
 #define LICENSE_PREFIX "libavutil license: "
-    return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+    return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+}
+
+const char *av_get_media_type_string(enum AVMediaType media_type)
+{
+    switch (media_type) {
+    case AVMEDIA_TYPE_VIDEO:      return "video";
+    case AVMEDIA_TYPE_AUDIO:      return "audio";
+    case AVMEDIA_TYPE_DATA:       return "data";
+    case AVMEDIA_TYPE_SUBTITLE:   return "subtitle";
+    case AVMEDIA_TYPE_ATTACHMENT: return "attachment";
+    default:                      return NULL;
+    }
 }
 
 char av_get_picture_type_char(enum AVPictureType pict_type)
diff --git a/libavutil/version.h b/libavutil/version.h
index 4cc2f7c..4751af3 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -1,18 +1,20 @@
 /*
- * This file is part of Libav.
+ * copyright (c) 2003 Fabrice Bellard
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -37,8 +39,8 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR 51
-#define LIBAVUTIL_VERSION_MINOR 44
-#define LIBAVUTIL_VERSION_MICRO  0
+#define LIBAVUTIL_VERSION_MINOR 76
+#define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
                                                LIBAVUTIL_VERSION_MINOR, \
@@ -61,6 +63,9 @@
  * @{
  */
 
+#ifndef FF_API_OLD_EVAL_NAMES
+#define FF_API_OLD_EVAL_NAMES           (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
 #ifndef FF_API_GET_BITS_PER_SAMPLE_FMT
 #define FF_API_GET_BITS_PER_SAMPLE_FMT (LIBAVUTIL_VERSION_MAJOR < 52)
 #endif
@@ -73,6 +78,9 @@
 #ifndef FF_API_OLD_AVOPTIONS
 #define FF_API_OLD_AVOPTIONS            (LIBAVUTIL_VERSION_MAJOR < 52)
 #endif
+#ifndef FF_API_OLD_TC_ADJUST_FRAMENUM
+#define FF_API_OLD_TC_ADJUST_FRAMENUM   (LIBAVUTIL_VERSION_MAJOR < 52)
+#endif
 #ifndef FF_API_PIX_FMT
 #define FF_API_PIX_FMT                  (LIBAVUTIL_VERSION_MAJOR < 52)
 #endif
@@ -91,3 +99,4 @@
  */
 
 #endif /* AVUTIL_VERSION_H */
+
diff --git a/libavutil/x86/asm.h b/libavutil/x86/asm.h
index a43ab3c..d2e76db 100644
--- a/libavutil/x86/asm.h
+++ b/libavutil/x86/asm.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/x86/bswap.h b/libavutil/x86/bswap.h
index c73be9a..08e2a62 100644
--- a/libavutil/x86/bswap.h
+++ b/libavutil/x86/bswap.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/x86/cpu.c b/libavutil/x86/cpu.c
index dab2cac..3fee152 100644
--- a/libavutil/x86/cpu.c
+++ b/libavutil/x86/cpu.c
@@ -3,20 +3,20 @@
  * (c)1997-99 by H. Dietz and R. Fisher
  * Converted to C and improved by Fabrice Bellard.
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/x86/cpu.h b/libavutil/x86/cpu.h
index e4f6f0b..601476e 100644
--- a/libavutil/x86/cpu.h
+++ b/libavutil/x86/cpu.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/x86/cpuid.asm b/libavutil/x86/cpuid.asm
index d2ac1f0..4a9bf72 100644
--- a/libavutil/x86/cpuid.asm
+++ b/libavutil/x86/cpuid.asm
@@ -4,20 +4,20 @@
 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
 ;*          Jason Garrett-Glaser <darkshikari@gmail.com>
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
diff --git a/libavutil/x86/float_dsp.asm b/libavutil/x86/float_dsp.asm
index 5b9b444..3af928f 100644
--- a/libavutil/x86/float_dsp.asm
+++ b/libavutil/x86/float_dsp.asm
@@ -1,20 +1,22 @@
 ;*****************************************************************************
 ;* x86-optimized Float DSP functions
 ;*
-;* This file is part of Libav.
+;* Copyright 2006 Loren Merritt
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* 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.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
diff --git a/libavutil/x86/float_dsp_init.c b/libavutil/x86/float_dsp_init.c
index d1b0b8c..1382373 100644
--- a/libavutil/x86/float_dsp_init.c
+++ b/libavutil/x86/float_dsp_init.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/x86/intreadwrite.h b/libavutil/x86/intreadwrite.h
index 635096e..4061d19 100644
--- a/libavutil/x86/intreadwrite.h
+++ b/libavutil/x86/intreadwrite.h
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2010 Alexander Strange <astrange@ithinksw.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/x86/timer.h b/libavutil/x86/timer.h
index 35e614d..5969876 100644
--- a/libavutil/x86/timer.h
+++ b/libavutil/x86/timer.h
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libavutil/x86/x86inc.asm b/libavutil/x86/x86inc.asm
index d734c6e..c1827fb 100644
--- a/libavutil/x86/x86inc.asm
+++ b/libavutil/x86/x86inc.asm
@@ -55,19 +55,38 @@
 %endif
 
 ; Name of the .rodata section.
-; Kludge: Something on OS X fails to align .rodata even given an align attribute,
-; so use a different read-only section.
 %macro SECTION_RODATA 0-1 16
-    %ifidn __OUTPUT_FORMAT__,macho64
-        SECTION .text align=%1
-    %elifidn __OUTPUT_FORMAT__,macho
-        SECTION .text align=%1
-        fakegot:
-    %elifidn __OUTPUT_FORMAT__,aout
+    ; Kludge: Something on OS X fails to align .rodata even given an align
+    ; attribute, so use a different read-only section. This has been fixed in
+    ; yasm 0.8.0 and nasm 2.6.
+    %ifdef __YASM_VERSION_ID__
+        %if __YASM_VERSION_ID__ < 00080000h
+            %define NEED_MACHO_RODATA_KLUDGE
+        %endif
+    %elifdef __NASM_VERSION_ID__
+        %if __NASM_VERSION_ID__ < 02060000h
+            %define NEED_MACHO_RODATA_KLUDGE
+        %endif
+    %endif
+
+    %ifidn __OUTPUT_FORMAT__,aout
         section .text
     %else
-        SECTION .rodata align=%1
+        %ifndef NEED_MACHO_RODATA_KLUDGE
+            SECTION .rodata align=%1
+        %else
+            %ifidn __OUTPUT_FORMAT__,macho64
+                SECTION .text align=%1
+            %elifidn __OUTPUT_FORMAT__,macho
+                SECTION .text align=%1
+                fakegot:
+            %else
+                SECTION .rodata align=%1
+            %endif
+        %endif
     %endif
+
+    %undef NEED_MACHO_RODATA_KLUDGE
 %endmacro
 
 ; aout does not support align=
diff --git a/libavutil/x86/x86util.asm b/libavutil/x86/x86util.asm
index a5d89a1..cf5ea36 100644
--- a/libavutil/x86/x86util.asm
+++ b/libavutil/x86/x86util.asm
@@ -6,20 +6,20 @@
 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
 ;*          Holger Lubitz <holger@lubitz.org>
 ;*
-;* This file is part of Libav.
+;* This file is part of FFmpeg.
 ;*
-;* Libav is free software; you can redistribute it and/or
+;* FFmpeg is free software; you can redistribute it and/or
 ;* modify it under the terms of the GNU Lesser General Public
 ;* License as published by the Free Software Foundation; either
 ;* version 2.1 of the License, or (at your option) any later version.
 ;*
-;* Libav is distributed in the hope that it will be useful,
+;* FFmpeg is distributed in the hope that it will be useful,
 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 ;* Lesser General Public License for more details.
 ;*
 ;* You should have received a copy of the GNU Lesser General Public
-;* License along with Libav; if not, write to the Free Software
+;* License along with FFmpeg; if not, write to the Free Software
 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 ;******************************************************************************
 
diff --git a/libavutil/x86_cpu.h b/libavutil/x86_cpu.h
new file mode 100644
index 0000000..bec1c77
--- /dev/null
+++ b/libavutil/x86_cpu.h
@@ -0,0 +1 @@
+#include "libavutil/x86/asm.h"
diff --git a/libavutil/xga_font_data.c b/libavutil/xga_font_data.c
new file mode 100644
index 0000000..3aed314
--- /dev/null
+++ b/libavutil/xga_font_data.c
@@ -0,0 +1,417 @@
+/*
+ * CGA/EGA/VGA ROM font 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
+ */
+
+/**
+ * @file
+ * CGA/EGA/VGA ROM font data
+ */
+
+#include <stdint.h>
+#include "xga_font_data.h"
+
+const uint8_t avpriv_cga_font[2048] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e,
+ 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00,
+ 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c,
+ 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00,
+ 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
+ 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78,
+ 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0,
+ 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0, 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99,
+ 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00,
+ 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00,
+ 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00, 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78,
+ 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff,
+ 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
+ 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00,
+ 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00,
+ 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00,
+ 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00, 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00,
+ 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00,
+ 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00,
+ 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00,
+ 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00, 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00,
+ 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00, 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00,
+ 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00, 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00,
+ 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00,
+ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60,
+ 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
+ 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00,
+ 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00, 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00,
+ 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00,
+ 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00,
+ 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00, 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00,
+ 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00,
+ 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00,
+ 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00,
+ 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00,
+ 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00,
+ 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00,
+ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00,
+ 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00,
+ 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00,
+ 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00,
+ 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00,
+ 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00,
+ 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
+ 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
+ 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00, 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00,
+ 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00,
+ 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00,
+ 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e,
+ 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00,
+ 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00,
+ 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00,
+ 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8,
+ 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00, 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00,
+ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00,
+ 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00,
+ 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
+ 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00,
+ 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00,
+ 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38,
+ 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00,
+ 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00, 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00, 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00,
+ 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00,
+ 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00, 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
+ 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00,
+ 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
+ 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8, 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00,
+ 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18,
+ 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00, 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30,
+ 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7, 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70,
+ 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00, 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00,
+ 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00,
+ 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00, 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00,
+ 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00,
+ 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f,
+ 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00,
+ 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00,
+ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+ 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00, 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0,
+ 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00,
+ 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00,
+ 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00,
+ 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00,
+ 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00, 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00,
+ 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0,
+ 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00,
+ 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00,
+ 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00,
+ 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70,
+ 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00,
+ 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c,
+ 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+const uint8_t avpriv_vga16_font[4096] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00,
+ 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
+ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,
+ 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b, 0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
+ 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x18, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00,
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06, 0x0c, 0x1f, 0x00, 0x00,
+ 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00,
+ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
+ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+ 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
diff --git a/libavutil/xga_font_data.h b/libavutil/xga_font_data.h
new file mode 100644
index 0000000..ca5ee79
--- /dev/null
+++ b/libavutil/xga_font_data.h
@@ -0,0 +1,34 @@
+/*
+ * CGA/EGA/VGA ROM font 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
+ */
+
+/**
+ * @file
+ * CGA/EGA/VGA ROM font data
+ */
+
+#ifndef AVUTIL_XGA_FONT_DATA_H
+#define AVUTIL_XGA_FONT_DATA_H
+
+#include <stdint.h>
+
+extern const uint8_t avpriv_cga_font[2048];
+extern const uint8_t avpriv_vga16_font[4096];
+
+#endif /* AVUTIL_XGA_FONT_DATA_H */
diff --git a/libavutil/xtea.c b/libavutil/xtea.c
index f3357ce..28780fb 100644
--- a/libavutil/xtea.c
+++ b/libavutil/xtea.c
@@ -4,20 +4,20 @@
  *
  * loosely based on the implementation of David Wheeler and Roger Needham
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -39,32 +39,114 @@
                            int decrypt, uint8_t *iv)
 {
     uint32_t v0, v1;
-    int i;
+    uint32_t k0 = ctx->key[0];
+    uint32_t k1 = ctx->key[1];
+    uint32_t k2 = ctx->key[2];
+    uint32_t k3 = ctx->key[3];
 
     v0 = AV_RB32(src);
     v1 = AV_RB32(src + 4);
 
     if (decrypt) {
-        uint32_t delta = 0x9E3779B9, sum = delta * 32;
+#if CONFIG_SMALL
+        int i;
+        uint32_t delta = 0x9E3779B9U, sum = delta * 32;
 
         for (i = 0; i < 32; i++) {
             v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]);
             sum -= delta;
             v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]);
         }
+#else
+#define DSTEP(SUM, K0, K1) \
+            v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (SUM + K0); \
+            v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (SUM - 0x9E3779B9U + K1)
+
+        DSTEP(0xC6EF3720U, k2, k3);
+        DSTEP(0x28B7BD67U, k3, k2);
+        DSTEP(0x8A8043AEU, k0, k1);
+        DSTEP(0xEC48C9F5U, k1, k0);
+        DSTEP(0x4E11503CU, k2, k3);
+        DSTEP(0xAFD9D683U, k2, k2);
+        DSTEP(0x11A25CCAU, k3, k1);
+        DSTEP(0x736AE311U, k0, k0);
+        DSTEP(0xD5336958U, k1, k3);
+        DSTEP(0x36FBEF9FU, k1, k2);
+        DSTEP(0x98C475E6U, k2, k1);
+        DSTEP(0xFA8CFC2DU, k3, k0);
+        DSTEP(0x5C558274U, k0, k3);
+        DSTEP(0xBE1E08BBU, k1, k2);
+        DSTEP(0x1FE68F02U, k1, k1);
+        DSTEP(0x81AF1549U, k2, k0);
+        DSTEP(0xE3779B90U, k3, k3);
+        DSTEP(0x454021D7U, k0, k2);
+        DSTEP(0xA708A81EU, k1, k1);
+        DSTEP(0x08D12E65U, k1, k0);
+        DSTEP(0x6A99B4ACU, k2, k3);
+        DSTEP(0xCC623AF3U, k3, k2);
+        DSTEP(0x2E2AC13AU, k0, k1);
+        DSTEP(0x8FF34781U, k0, k0);
+        DSTEP(0xF1BBCDC8U, k1, k3);
+        DSTEP(0x5384540FU, k2, k2);
+        DSTEP(0xB54CDA56U, k3, k1);
+        DSTEP(0x1715609DU, k0, k0);
+        DSTEP(0x78DDE6E4U, k0, k3);
+        DSTEP(0xDAA66D2BU, k1, k2);
+        DSTEP(0x3C6EF372U, k2, k1);
+        DSTEP(0x9E3779B9U, k3, k0);
+#endif
         if (iv) {
             v0 ^= AV_RB32(iv);
             v1 ^= AV_RB32(iv + 4);
             memcpy(iv, src, 8);
         }
     } else {
-        uint32_t sum = 0, delta = 0x9E3779B9;
+#if CONFIG_SMALL
+        int i;
+        uint32_t sum = 0, delta = 0x9E3779B9U;
 
         for (i = 0; i < 32; i++) {
             v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + ctx->key[sum & 3]);
             sum += delta;
             v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + ctx->key[(sum >> 11) & 3]);
         }
+#else
+#define ESTEP(SUM, K0, K1) \
+            v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (SUM + K0);\
+            v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (SUM + 0x9E3779B9U + K1)
+        ESTEP(0x00000000U, k0, k3);
+        ESTEP(0x9E3779B9U, k1, k2);
+        ESTEP(0x3C6EF372U, k2, k1);
+        ESTEP(0xDAA66D2BU, k3, k0);
+        ESTEP(0x78DDE6E4U, k0, k0);
+        ESTEP(0x1715609DU, k1, k3);
+        ESTEP(0xB54CDA56U, k2, k2);
+        ESTEP(0x5384540FU, k3, k1);
+        ESTEP(0xF1BBCDC8U, k0, k0);
+        ESTEP(0x8FF34781U, k1, k0);
+        ESTEP(0x2E2AC13AU, k2, k3);
+        ESTEP(0xCC623AF3U, k3, k2);
+        ESTEP(0x6A99B4ACU, k0, k1);
+        ESTEP(0x08D12E65U, k1, k1);
+        ESTEP(0xA708A81EU, k2, k0);
+        ESTEP(0x454021D7U, k3, k3);
+        ESTEP(0xE3779B90U, k0, k2);
+        ESTEP(0x81AF1549U, k1, k1);
+        ESTEP(0x1FE68F02U, k2, k1);
+        ESTEP(0xBE1E08BBU, k3, k0);
+        ESTEP(0x5C558274U, k0, k3);
+        ESTEP(0xFA8CFC2DU, k1, k2);
+        ESTEP(0x98C475E6U, k2, k1);
+        ESTEP(0x36FBEF9FU, k3, k1);
+        ESTEP(0xD5336958U, k0, k0);
+        ESTEP(0x736AE311U, k1, k3);
+        ESTEP(0x11A25CCAU, k2, k2);
+        ESTEP(0xAFD9D683U, k3, k2);
+        ESTEP(0x4E11503CU, k0, k1);
+        ESTEP(0xEC48C9F5U, k1, k0);
+        ESTEP(0x8A8043AEU, k2, k3);
+        ESTEP(0x28B7BD67U, k3, k2);
+#endif
     }
 
     AV_WB32(dst, v0);
@@ -183,6 +265,7 @@
         memcpy(iv, "HALLO123", 8);
         test_xtea(&ctx, ct, ct, src, 4, iv, 1, "CBC inplace decryption");
     }
+
     printf("Test encryption/decryption success.\n");
 
     return 0;
diff --git a/libavutil/xtea.h b/libavutil/xtea.h
index 7d2b07b..0899c92 100644
--- a/libavutil/xtea.h
+++ b/libavutil/xtea.h
@@ -1,20 +1,21 @@
 /*
  * A 32-bit implementation of the XTEA algorithm
+ * Copyright (c) 2012 Samuel Pitoiset
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libpostproc/Makefile b/libpostproc/Makefile
new file mode 100644
index 0000000..3fb5a70
--- /dev/null
+++ b/libpostproc/Makefile
@@ -0,0 +1,9 @@
+include $(SUBDIR)../config.mak
+
+NAME = postproc
+FFLIBS = avutil
+
+HEADERS = postprocess.h        \
+          version.h            \
+
+OBJS = postprocess.o
diff --git a/libpostproc/libpostproc.v b/libpostproc/libpostproc.v
new file mode 100644
index 0000000..e65d76f4
--- /dev/null
+++ b/libpostproc/libpostproc.v
@@ -0,0 +1,4 @@
+LIBPOSTPROC_$MAJOR {
+        global: postproc_*; pp_*;
+        local: *;
+};
diff --git a/libpostproc/postprocess.c b/libpostproc/postprocess.c
new file mode 100644
index 0000000..f0d97d3
--- /dev/null
+++ b/libpostproc/postprocess.c
@@ -0,0 +1,1095 @@
+/*
+ * Copyright (C) 2001-2003 Michael Niedermayer (michaelni@gmx.at)
+ *
+ * AltiVec optimizations (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 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
+ * postprocessing.
+ */
+
+/*
+                        C       MMX     MMX2    3DNow   AltiVec
+isVertDC                Ec      Ec                      Ec
+isVertMinMaxOk          Ec      Ec                      Ec
+doVertLowPass           E               e       e       Ec
+doVertDefFilter         Ec      Ec      e       e       Ec
+isHorizDC               Ec      Ec                      Ec
+isHorizMinMaxOk         a       E                       Ec
+doHorizLowPass          E               e       e       Ec
+doHorizDefFilter        Ec      Ec      e       e       Ec
+do_a_deblock            Ec      E       Ec      E
+deRing                  E               e       e*      Ecp
+Vertical RKAlgo1        E               a       a
+Horizontal RKAlgo1                      a       a
+Vertical X1#            a               E       E
+Horizontal X1#          a               E       E
+LinIpolDeinterlace      e               E       E*
+CubicIpolDeinterlace    a               e       e*
+LinBlendDeinterlace     e               E       E*
+MedianDeinterlace#      E       Ec      Ec
+TempDeNoiser#           E               e       e       Ec
+
+* I do not have a 3DNow! CPU -> it is untested, but no one said it does not work so it seems to work
+# more or less selfinvented filters so the exactness is not too meaningful
+E = Exact implementation
+e = almost exact implementation (slightly different rounding,...)
+a = alternative / approximate impl
+c = checked against the other implementations (-vo md5)
+p = partially optimized, still some work to do
+*/
+
+/*
+TODO:
+reduce the time wasted on the mem transfer
+unroll stuff if instructions depend too much on the prior one
+move YScale thing to the end instead of fixing QP
+write a faster and higher quality deblocking filter :)
+make the mainloop more flexible (variable number of blocks at once
+        (the if/else stuff per block is slowing things down)
+compare the quality & speed of all filters
+split this huge file
+optimize c versions
+try to unroll inner for(x=0 ... loop to avoid these damn if(x ... checks
+...
+*/
+
+//Changelog: use git log
+
+#include "config.h"
+#include "libavutil/avutil.h"
+#include "libavutil/avassert.h"
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+//#undef HAVE_MMXEXT_INLINE
+//#define HAVE_AMD3DNOW_INLINE
+//#undef HAVE_MMX_INLINE
+//#undef ARCH_X86
+//#define DEBUG_BRIGHTNESS
+#include "postprocess.h"
+#include "postprocess_internal.h"
+#include "libavutil/avstring.h"
+
+unsigned postproc_version(void)
+{
+    av_assert0(LIBPOSTPROC_VERSION_MICRO >= 100);
+    return LIBPOSTPROC_VERSION_INT;
+}
+
+const char *postproc_configuration(void)
+{
+    return FFMPEG_CONFIGURATION;
+}
+
+const char *postproc_license(void)
+{
+#define LICENSE_PREFIX "libpostproc license: "
+    return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+}
+
+#if HAVE_ALTIVEC_H
+#include <altivec.h>
+#endif
+
+#define GET_MODE_BUFFER_SIZE 500
+#define OPTIONS_ARRAY_SIZE 10
+#define BLOCK_SIZE 8
+#define TEMP_STRIDE 8
+//#define NUM_BLOCKS_AT_ONCE 16 //not used yet
+
+#if ARCH_X86 && HAVE_INLINE_ASM
+DECLARE_ASM_CONST(8, uint64_t, w05)= 0x0005000500050005LL;
+DECLARE_ASM_CONST(8, uint64_t, w04)= 0x0004000400040004LL;
+DECLARE_ASM_CONST(8, uint64_t, w20)= 0x0020002000200020LL;
+DECLARE_ASM_CONST(8, uint64_t, b00)= 0x0000000000000000LL;
+DECLARE_ASM_CONST(8, uint64_t, b01)= 0x0101010101010101LL;
+DECLARE_ASM_CONST(8, uint64_t, b02)= 0x0202020202020202LL;
+DECLARE_ASM_CONST(8, uint64_t, b08)= 0x0808080808080808LL;
+DECLARE_ASM_CONST(8, uint64_t, b80)= 0x8080808080808080LL;
+#endif
+
+DECLARE_ASM_CONST(8, int, deringThreshold)= 20;
+
+
+static struct PPFilter filters[]=
+{
+    {"hb", "hdeblock",              1, 1, 3, H_DEBLOCK},
+    {"vb", "vdeblock",              1, 2, 4, V_DEBLOCK},
+/*  {"hr", "rkhdeblock",            1, 1, 3, H_RK1_FILTER},
+    {"vr", "rkvdeblock",            1, 2, 4, V_RK1_FILTER},*/
+    {"h1", "x1hdeblock",            1, 1, 3, H_X1_FILTER},
+    {"v1", "x1vdeblock",            1, 2, 4, V_X1_FILTER},
+    {"ha", "ahdeblock",             1, 1, 3, H_A_DEBLOCK},
+    {"va", "avdeblock",             1, 2, 4, V_A_DEBLOCK},
+    {"dr", "dering",                1, 5, 6, DERING},
+    {"al", "autolevels",            0, 1, 2, LEVEL_FIX},
+    {"lb", "linblenddeint",         1, 1, 4, LINEAR_BLEND_DEINT_FILTER},
+    {"li", "linipoldeint",          1, 1, 4, LINEAR_IPOL_DEINT_FILTER},
+    {"ci", "cubicipoldeint",        1, 1, 4, CUBIC_IPOL_DEINT_FILTER},
+    {"md", "mediandeint",           1, 1, 4, MEDIAN_DEINT_FILTER},
+    {"fd", "ffmpegdeint",           1, 1, 4, FFMPEG_DEINT_FILTER},
+    {"l5", "lowpass5",              1, 1, 4, LOWPASS5_DEINT_FILTER},
+    {"tn", "tmpnoise",              1, 7, 8, TEMP_NOISE_FILTER},
+    {"fq", "forcequant",            1, 0, 0, FORCE_QUANT},
+    {"be", "bitexact",              1, 0, 0, BITEXACT},
+    {NULL, NULL,0,0,0,0} //End Marker
+};
+
+static const char *replaceTable[]=
+{
+    "default",      "hb:a,vb:a,dr:a",
+    "de",           "hb:a,vb:a,dr:a",
+    "fast",         "h1:a,v1:a,dr:a",
+    "fa",           "h1:a,v1:a,dr:a",
+    "ac",           "ha:a:128:7,va:a,dr:a",
+    NULL //End Marker
+};
+
+
+#if ARCH_X86 && HAVE_INLINE_ASM
+static inline void prefetchnta(void *p)
+{
+    __asm__ volatile(   "prefetchnta (%0)\n\t"
+        : : "r" (p)
+    );
+}
+
+static inline void prefetcht0(void *p)
+{
+    __asm__ volatile(   "prefetcht0 (%0)\n\t"
+        : : "r" (p)
+    );
+}
+
+static inline void prefetcht1(void *p)
+{
+    __asm__ volatile(   "prefetcht1 (%0)\n\t"
+        : : "r" (p)
+    );
+}
+
+static inline void prefetcht2(void *p)
+{
+    __asm__ volatile(   "prefetcht2 (%0)\n\t"
+        : : "r" (p)
+    );
+}
+#endif
+
+/* The horizontal functions exist only in C because the MMX
+ * code is faster with vertical filters and transposing. */
+
+/**
+ * Check if the given 8x8 Block is mostly "flat"
+ */
+static inline int isHorizDC_C(uint8_t src[], int stride, PPContext *c)
+{
+    int numEq= 0;
+    int y;
+    const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1;
+    const int dcThreshold= dcOffset*2 + 1;
+
+    for(y=0; y<BLOCK_SIZE; y++){
+        if(((unsigned)(src[0] - src[1] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[1] - src[2] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[2] - src[3] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[3] - src[4] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[4] - src[5] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[5] - src[6] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[6] - src[7] + dcOffset)) < dcThreshold) numEq++;
+        src+= stride;
+    }
+    return numEq > c->ppMode.flatnessThreshold;
+}
+
+/**
+ * Check if the middle 8x8 Block in the given 8x16 block is flat
+ */
+static inline int isVertDC_C(uint8_t src[], int stride, PPContext *c)
+{
+    int numEq= 0;
+    int y;
+    const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1;
+    const int dcThreshold= dcOffset*2 + 1;
+
+    src+= stride*4; // src points to begin of the 8x8 Block
+    for(y=0; y<BLOCK_SIZE-1; y++){
+        if(((unsigned)(src[0] - src[0+stride] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[1] - src[1+stride] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[2] - src[2+stride] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[3] - src[3+stride] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[4] - src[4+stride] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[5] - src[5+stride] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[6] - src[6+stride] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[7] - src[7+stride] + dcOffset)) < dcThreshold) numEq++;
+        src+= stride;
+    }
+    return numEq > c->ppMode.flatnessThreshold;
+}
+
+static inline int isHorizMinMaxOk_C(uint8_t src[], int stride, int QP)
+{
+    int i;
+    for(i=0; i<2; i++){
+        if((unsigned)(src[0] - src[5] + 2*QP) > 4*QP) return 0;
+        src += stride;
+        if((unsigned)(src[2] - src[7] + 2*QP) > 4*QP) return 0;
+        src += stride;
+        if((unsigned)(src[4] - src[1] + 2*QP) > 4*QP) return 0;
+        src += stride;
+        if((unsigned)(src[6] - src[3] + 2*QP) > 4*QP) return 0;
+        src += stride;
+    }
+    return 1;
+}
+
+static inline int isVertMinMaxOk_C(uint8_t src[], int stride, int QP)
+{
+    int x;
+    src+= stride*4;
+    for(x=0; x<BLOCK_SIZE; x+=4){
+        if((unsigned)(src[  x + 0*stride] - src[  x + 5*stride] + 2*QP) > 4*QP) return 0;
+        if((unsigned)(src[1+x + 2*stride] - src[1+x + 7*stride] + 2*QP) > 4*QP) return 0;
+        if((unsigned)(src[2+x + 4*stride] - src[2+x + 1*stride] + 2*QP) > 4*QP) return 0;
+        if((unsigned)(src[3+x + 6*stride] - src[3+x + 3*stride] + 2*QP) > 4*QP) return 0;
+    }
+    return 1;
+}
+
+static inline int horizClassify_C(uint8_t src[], int stride, PPContext *c)
+{
+    if( isHorizDC_C(src, stride, c) ){
+        if( isHorizMinMaxOk_C(src, stride, c->QP) )
+            return 1;
+        else
+            return 0;
+    }else{
+        return 2;
+    }
+}
+
+static inline int vertClassify_C(uint8_t src[], int stride, PPContext *c)
+{
+    if( isVertDC_C(src, stride, c) ){
+        if( isVertMinMaxOk_C(src, stride, c->QP) )
+            return 1;
+        else
+            return 0;
+    }else{
+        return 2;
+    }
+}
+
+static inline void doHorizDefFilter_C(uint8_t dst[], int stride, PPContext *c)
+{
+    int y;
+    for(y=0; y<BLOCK_SIZE; y++){
+        const int middleEnergy= 5*(dst[4] - dst[3]) + 2*(dst[2] - dst[5]);
+
+        if(FFABS(middleEnergy) < 8*c->QP){
+            const int q=(dst[3] - dst[4])/2;
+            const int leftEnergy=  5*(dst[2] - dst[1]) + 2*(dst[0] - dst[3]);
+            const int rightEnergy= 5*(dst[6] - dst[5]) + 2*(dst[4] - dst[7]);
+
+            int d= FFABS(middleEnergy) - FFMIN( FFABS(leftEnergy), FFABS(rightEnergy) );
+            d= FFMAX(d, 0);
+
+            d= (5*d + 32) >> 6;
+            d*= FFSIGN(-middleEnergy);
+
+            if(q>0)
+            {
+                d= d<0 ? 0 : d;
+                d= d>q ? q : d;
+            }
+            else
+            {
+                d= d>0 ? 0 : d;
+                d= d<q ? q : d;
+            }
+
+            dst[3]-= d;
+            dst[4]+= d;
+        }
+        dst+= stride;
+    }
+}
+
+/**
+ * Do a horizontal low pass filter on the 10x8 block (dst points to middle 8x8 Block)
+ * using the 9-Tap Filter (1,1,2,2,4,2,2,1,1)/16 (C version)
+ */
+static inline void doHorizLowPass_C(uint8_t dst[], int stride, PPContext *c)
+{
+    int y;
+    for(y=0; y<BLOCK_SIZE; y++){
+        const int first= FFABS(dst[-1] - dst[0]) < c->QP ? dst[-1] : dst[0];
+        const int last= FFABS(dst[8] - dst[7]) < c->QP ? dst[8] : dst[7];
+
+        int sums[10];
+        sums[0] = 4*first + dst[0] + dst[1] + dst[2] + 4;
+        sums[1] = sums[0] - first  + dst[3];
+        sums[2] = sums[1] - first  + dst[4];
+        sums[3] = sums[2] - first  + dst[5];
+        sums[4] = sums[3] - first  + dst[6];
+        sums[5] = sums[4] - dst[0] + dst[7];
+        sums[6] = sums[5] - dst[1] + last;
+        sums[7] = sums[6] - dst[2] + last;
+        sums[8] = sums[7] - dst[3] + last;
+        sums[9] = sums[8] - dst[4] + last;
+
+        dst[0]= (sums[0] + sums[2] + 2*dst[0])>>4;
+        dst[1]= (sums[1] + sums[3] + 2*dst[1])>>4;
+        dst[2]= (sums[2] + sums[4] + 2*dst[2])>>4;
+        dst[3]= (sums[3] + sums[5] + 2*dst[3])>>4;
+        dst[4]= (sums[4] + sums[6] + 2*dst[4])>>4;
+        dst[5]= (sums[5] + sums[7] + 2*dst[5])>>4;
+        dst[6]= (sums[6] + sums[8] + 2*dst[6])>>4;
+        dst[7]= (sums[7] + sums[9] + 2*dst[7])>>4;
+
+        dst+= stride;
+    }
+}
+
+/**
+ * Experimental Filter 1 (Horizontal)
+ * will not damage linear gradients
+ * Flat blocks should look like they were passed through the (1,1,2,2,4,2,2,1,1) 9-Tap filter
+ * can only smooth blocks at the expected locations (it cannot smooth them if they did move)
+ * MMX2 version does correct clipping C version does not
+ * not identical with the vertical one
+ */
+static inline void horizX1Filter(uint8_t *src, int stride, int QP)
+{
+    int y;
+    static uint64_t *lut= NULL;
+    if(lut==NULL)
+    {
+        int i;
+        lut = av_malloc(256*8);
+        for(i=0; i<256; i++)
+        {
+            int v= i < 128 ? 2*i : 2*(i-256);
+/*
+//Simulate 112242211 9-Tap filter
+            uint64_t a= (v/16)  & 0xFF;
+            uint64_t b= (v/8)   & 0xFF;
+            uint64_t c= (v/4)   & 0xFF;
+            uint64_t d= (3*v/8) & 0xFF;
+*/
+//Simulate piecewise linear interpolation
+            uint64_t a= (v/16)   & 0xFF;
+            uint64_t b= (v*3/16) & 0xFF;
+            uint64_t c= (v*5/16) & 0xFF;
+            uint64_t d= (7*v/16) & 0xFF;
+            uint64_t A= (0x100 - a)&0xFF;
+            uint64_t B= (0x100 - b)&0xFF;
+            uint64_t C= (0x100 - c)&0xFF;
+            uint64_t D= (0x100 - c)&0xFF;
+
+            lut[i]   = (a<<56) | (b<<48) | (c<<40) | (d<<32) |
+                       (D<<24) | (C<<16) | (B<<8)  | (A);
+            //lut[i] = (v<<32) | (v<<24);
+        }
+    }
+
+    for(y=0; y<BLOCK_SIZE; y++){
+        int a= src[1] - src[2];
+        int b= src[3] - src[4];
+        int c= src[5] - src[6];
+
+        int d= FFMAX(FFABS(b) - (FFABS(a) + FFABS(c))/2, 0);
+
+        if(d < QP){
+            int v = d * FFSIGN(-b);
+
+            src[1] +=v/8;
+            src[2] +=v/4;
+            src[3] +=3*v/8;
+            src[4] -=3*v/8;
+            src[5] -=v/4;
+            src[6] -=v/8;
+        }
+        src+=stride;
+    }
+}
+
+/**
+ * accurate deblock filter
+ */
+static av_always_inline void do_a_deblock_C(uint8_t *src, int step, int stride, PPContext *c){
+    int y;
+    const int QP= c->QP;
+    const int dcOffset= ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1;
+    const int dcThreshold= dcOffset*2 + 1;
+//START_TIMER
+    src+= step*4; // src points to begin of the 8x8 Block
+    for(y=0; y<8; y++){
+        int numEq= 0;
+
+        if(((unsigned)(src[-1*step] - src[0*step] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[ 0*step] - src[1*step] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[ 1*step] - src[2*step] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[ 2*step] - src[3*step] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[ 3*step] - src[4*step] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[ 4*step] - src[5*step] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[ 5*step] - src[6*step] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[ 6*step] - src[7*step] + dcOffset)) < dcThreshold) numEq++;
+        if(((unsigned)(src[ 7*step] - src[8*step] + dcOffset)) < dcThreshold) numEq++;
+        if(numEq > c->ppMode.flatnessThreshold){
+            int min, max, x;
+
+            if(src[0] > src[step]){
+                max= src[0];
+                min= src[step];
+            }else{
+                max= src[step];
+                min= src[0];
+            }
+            for(x=2; x<8; x+=2){
+                if(src[x*step] > src[(x+1)*step]){
+                        if(src[x    *step] > max) max= src[ x   *step];
+                        if(src[(x+1)*step] < min) min= src[(x+1)*step];
+                }else{
+                        if(src[(x+1)*step] > max) max= src[(x+1)*step];
+                        if(src[ x   *step] < min) min= src[ x   *step];
+                }
+            }
+            if(max-min < 2*QP){
+                const int first= FFABS(src[-1*step] - src[0]) < QP ? src[-1*step] : src[0];
+                const int last= FFABS(src[8*step] - src[7*step]) < QP ? src[8*step] : src[7*step];
+
+                int sums[10];
+                sums[0] = 4*first + src[0*step] + src[1*step] + src[2*step] + 4;
+                sums[1] = sums[0] - first       + src[3*step];
+                sums[2] = sums[1] - first       + src[4*step];
+                sums[3] = sums[2] - first       + src[5*step];
+                sums[4] = sums[3] - first       + src[6*step];
+                sums[5] = sums[4] - src[0*step] + src[7*step];
+                sums[6] = sums[5] - src[1*step] + last;
+                sums[7] = sums[6] - src[2*step] + last;
+                sums[8] = sums[7] - src[3*step] + last;
+                sums[9] = sums[8] - src[4*step] + last;
+
+                src[0*step]= (sums[0] + sums[2] + 2*src[0*step])>>4;
+                src[1*step]= (sums[1] + sums[3] + 2*src[1*step])>>4;
+                src[2*step]= (sums[2] + sums[4] + 2*src[2*step])>>4;
+                src[3*step]= (sums[3] + sums[5] + 2*src[3*step])>>4;
+                src[4*step]= (sums[4] + sums[6] + 2*src[4*step])>>4;
+                src[5*step]= (sums[5] + sums[7] + 2*src[5*step])>>4;
+                src[6*step]= (sums[6] + sums[8] + 2*src[6*step])>>4;
+                src[7*step]= (sums[7] + sums[9] + 2*src[7*step])>>4;
+            }
+        }else{
+            const int middleEnergy= 5*(src[4*step] - src[3*step]) + 2*(src[2*step] - src[5*step]);
+
+            if(FFABS(middleEnergy) < 8*QP){
+                const int q=(src[3*step] - src[4*step])/2;
+                const int leftEnergy=  5*(src[2*step] - src[1*step]) + 2*(src[0*step] - src[3*step]);
+                const int rightEnergy= 5*(src[6*step] - src[5*step]) + 2*(src[4*step] - src[7*step]);
+
+                int d= FFABS(middleEnergy) - FFMIN( FFABS(leftEnergy), FFABS(rightEnergy) );
+                d= FFMAX(d, 0);
+
+                d= (5*d + 32) >> 6;
+                d*= FFSIGN(-middleEnergy);
+
+                if(q>0){
+                    d= d<0 ? 0 : d;
+                    d= d>q ? q : d;
+                }else{
+                    d= d>0 ? 0 : d;
+                    d= d<q ? q : d;
+                }
+
+                src[3*step]-= d;
+                src[4*step]+= d;
+            }
+        }
+
+        src += stride;
+    }
+/*if(step==16){
+    STOP_TIMER("step16")
+}else{
+    STOP_TIMER("stepX")
+}*/
+}
+
+//Note: we have C, MMX, MMX2, 3DNOW version there is no 3DNOW+MMX2 one
+//Plain C versions
+//we always compile C for testing which needs bitexactness
+#define COMPILE_C
+
+#if HAVE_ALTIVEC
+#define COMPILE_ALTIVEC
+#endif //HAVE_ALTIVEC
+
+#if ARCH_X86 && HAVE_INLINE_ASM
+
+#if (HAVE_MMX_INLINE && !HAVE_AMD3DNOW_INLINE && !HAVE_MMXEXT_INLINE) || CONFIG_RUNTIME_CPUDETECT
+#define COMPILE_MMX
+#endif
+
+#if HAVE_MMXEXT_INLINE || CONFIG_RUNTIME_CPUDETECT
+#define COMPILE_MMX2
+#endif
+
+#if (HAVE_AMD3DNOW_INLINE && !HAVE_MMXEXT_INLINE) || CONFIG_RUNTIME_CPUDETECT
+#define COMPILE_3DNOW
+#endif
+#endif /* ARCH_X86 */
+
+#undef HAVE_MMX_INLINE
+#define HAVE_MMX_INLINE 0
+#undef HAVE_MMXEXT_INLINE
+#define HAVE_MMXEXT_INLINE 0
+#undef HAVE_AMD3DNOW_INLINE
+#define HAVE_AMD3DNOW_INLINE 0
+#undef HAVE_ALTIVEC
+#define HAVE_ALTIVEC 0
+
+#ifdef COMPILE_C
+#define RENAME(a) a ## _C
+#include "postprocess_template.c"
+#endif
+
+#ifdef COMPILE_ALTIVEC
+#undef RENAME
+#undef HAVE_ALTIVEC
+#define HAVE_ALTIVEC 1
+#define RENAME(a) a ## _altivec
+#include "postprocess_altivec_template.c"
+#include "postprocess_template.c"
+#endif
+
+//MMX versions
+#ifdef COMPILE_MMX
+#undef RENAME
+#undef HAVE_MMX_INLINE
+#define HAVE_MMX_INLINE 1
+#define RENAME(a) a ## _MMX
+#include "postprocess_template.c"
+#endif
+
+//MMX2 versions
+#ifdef COMPILE_MMX2
+#undef RENAME
+#undef HAVE_MMX_INLINE
+#undef HAVE_MMXEXT_INLINE
+#define HAVE_MMX_INLINE 1
+#define HAVE_MMXEXT_INLINE 1
+#define RENAME(a) a ## _MMX2
+#include "postprocess_template.c"
+#endif
+
+//3DNOW versions
+#ifdef COMPILE_3DNOW
+#undef RENAME
+#undef HAVE_MMX_INLINE
+#undef HAVE_MMXEXT_INLINE
+#undef HAVE_AMD3DNOW_INLINE
+#define HAVE_MMX_INLINE 1
+#define HAVE_MMXEXT_INLINE 0
+#define HAVE_AMD3DNOW_INLINE 1
+#define RENAME(a) a ## _3DNow
+#include "postprocess_template.c"
+#endif
+
+// minor note: the HAVE_xyz is messed up after that line so do not use it.
+
+static inline void postProcess(const uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height,
+        const QP_STORE_T QPs[], int QPStride, int isColor, pp_mode *vm, pp_context *vc)
+{
+    PPContext *c= (PPContext *)vc;
+    PPMode *ppMode= (PPMode *)vm;
+    c->ppMode= *ppMode; //FIXME
+
+    if(ppMode->lumMode & BITEXACT) {
+        postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
+        return;
+    }
+
+    // Using ifs here as they are faster than function pointers although the
+    // difference would not be measurable here but it is much better because
+    // someone might exchange the CPU whithout restarting MPlayer ;)
+#if CONFIG_RUNTIME_CPUDETECT
+#if ARCH_X86 && HAVE_INLINE_ASM
+    // ordered per speed fastest first
+    if(c->cpuCaps & PP_CPU_CAPS_MMX2)
+        postProcess_MMX2(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
+    else if(c->cpuCaps & PP_CPU_CAPS_3DNOW)
+        postProcess_3DNow(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
+    else if(c->cpuCaps & PP_CPU_CAPS_MMX)
+        postProcess_MMX(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
+    else
+        postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
+#else
+#if HAVE_ALTIVEC
+    if(c->cpuCaps & PP_CPU_CAPS_ALTIVEC)
+            postProcess_altivec(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
+    else
+#endif
+            postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
+#endif
+#else /* CONFIG_RUNTIME_CPUDETECT */
+#if   HAVE_MMXEXT_INLINE
+            postProcess_MMX2(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
+#elif HAVE_AMD3DNOW_INLINE
+            postProcess_3DNow(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
+#elif HAVE_MMX_INLINE
+            postProcess_MMX(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
+#elif HAVE_ALTIVEC
+            postProcess_altivec(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
+#else
+            postProcess_C(src, srcStride, dst, dstStride, width, height, QPs, QPStride, isColor, c);
+#endif
+#endif /* !CONFIG_RUNTIME_CPUDETECT */
+}
+
+//static void postProcess(uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height,
+//        QP_STORE_T QPs[], int QPStride, int isColor, struct PPMode *ppMode);
+
+/* -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"
+"*      *               a       autoq           CPU power dependent enabler\n"
+"                       c       chrom           chrominance filtering enabled\n"
+"                       y       nochrom         chrominance filtering disabled\n"
+"                       n       noluma          luma filtering disabled\n"
+"hb     hdeblock        (2 threshold)           horizontal deblocking filter\n"
+"       1. difference factor: default=32, higher -> more deblocking\n"
+"       2. flatness threshold: default=39, lower -> more deblocking\n"
+"                       the h & v deblocking filters share these\n"
+"                       so you can't set different thresholds for h / v\n"
+"vb     vdeblock        (2 threshold)           vertical deblocking filter\n"
+"ha     hadeblock       (2 threshold)           horizontal deblocking filter\n"
+"va     vadeblock       (2 threshold)           vertical deblocking filter\n"
+"h1     x1hdeblock                              experimental h deblock filter 1\n"
+"v1     x1vdeblock                              experimental v deblock filter 1\n"
+"dr     dering                                  deringing filter\n"
+"al     autolevels                              automatic brightness / contrast\n"
+"                       f        fullyrange     stretch luminance to (0..255)\n"
+"lb     linblenddeint                           linear blend deinterlacer\n"
+"li     linipoldeint                            linear interpolating deinterlace\n"
+"ci     cubicipoldeint                          cubic interpolating deinterlacer\n"
+"md     mediandeint                             median deinterlacer\n"
+"fd     ffmpegdeint                             ffmpeg deinterlacer\n"
+"l5     lowpass5                                FIR lowpass deinterlacer\n"
+"de     default                                 hb:a,vb:a,dr:a\n"
+"fa     fast                                    h1:a,v1:a,dr:a\n"
+"ac                                             ha:a:128:7,va:a,dr:a\n"
+"tn     tmpnoise        (3 threshold)           temporal noise reducer\n"
+"                     1. <= 2. <= 3.            larger -> stronger filtering\n"
+"fq     forceQuant      <quantizer>             force quantizer\n"
+"Usage:\n"
+"<filterName>[:<option>[:<option>...]][[,|/][-]<filterName>[:<option>...]]...\n"
+"long form example:\n"
+"vdeblock:autoq/hdeblock:autoq/linblenddeint    default,-vdeblock\n"
+"short form example:\n"
+"vb:a/hb:a/lb                                   de,-vb\n"
+"more examples:\n"
+"tn:64:128:256\n"
+"\n"
+;
+
+pp_mode *pp_get_mode_by_name_and_quality(const char *name, int quality)
+{
+    char temp[GET_MODE_BUFFER_SIZE];
+    char *p= temp;
+    static const char filterDelimiters[] = ",/";
+    static const char optionDelimiters[] = ":";
+    struct PPMode *ppMode;
+    char *filterToken;
+
+    if (!name)  {
+        av_log(NULL, AV_LOG_ERROR, "pp: Missing argument\n");
+        return NULL;
+    }
+
+    if (!strcmp(name, "help")) {
+        const char *p;
+        for (p = pp_help; strchr(p, '\n'); p = strchr(p, '\n') + 1) {
+            av_strlcpy(temp, p, FFMIN(sizeof(temp), strchr(p, '\n') - p + 2));
+            av_log(NULL, AV_LOG_INFO, "%s", temp);
+        }
+        return NULL;
+    }
+
+    ppMode= av_malloc(sizeof(PPMode));
+
+    ppMode->lumMode= 0;
+    ppMode->chromMode= 0;
+    ppMode->maxTmpNoise[0]= 700;
+    ppMode->maxTmpNoise[1]= 1500;
+    ppMode->maxTmpNoise[2]= 3000;
+    ppMode->maxAllowedY= 234;
+    ppMode->minAllowedY= 16;
+    ppMode->baseDcDiff= 256/8;
+    ppMode->flatnessThreshold= 56-16-1;
+    ppMode->maxClippedThreshold= 0.01;
+    ppMode->error=0;
+
+    memset(temp, 0, GET_MODE_BUFFER_SIZE);
+    av_strlcpy(temp, name, GET_MODE_BUFFER_SIZE - 1);
+
+    av_log(NULL, AV_LOG_DEBUG, "pp: %s\n", name);
+
+    for(;;){
+        char *filterName;
+        int q= 1000000; //PP_QUALITY_MAX;
+        int chrom=-1;
+        int luma=-1;
+        char *option;
+        char *options[OPTIONS_ARRAY_SIZE];
+        int i;
+        int filterNameOk=0;
+        int numOfUnknownOptions=0;
+        int enable=1; //does the user want us to enabled or disabled the filter
+
+        filterToken= strtok(p, filterDelimiters);
+        if(filterToken == NULL) break;
+        p+= strlen(filterToken) + 1; // p points to next filterToken
+        filterName= strtok(filterToken, optionDelimiters);
+        av_log(NULL, AV_LOG_DEBUG, "pp: %s::%s\n", filterToken, filterName);
+
+        if(*filterName == '-'){
+            enable=0;
+            filterName++;
+        }
+
+        for(;;){ //for all options
+            option= strtok(NULL, optionDelimiters);
+            if(option == NULL) break;
+
+            av_log(NULL, AV_LOG_DEBUG, "pp: option: %s\n", option);
+            if(!strcmp("autoq", option) || !strcmp("a", option)) q= quality;
+            else if(!strcmp("nochrom", option) || !strcmp("y", option)) chrom=0;
+            else if(!strcmp("chrom", option) || !strcmp("c", option)) chrom=1;
+            else if(!strcmp("noluma", option) || !strcmp("n", option)) luma=0;
+            else{
+                options[numOfUnknownOptions] = option;
+                numOfUnknownOptions++;
+            }
+            if(numOfUnknownOptions >= OPTIONS_ARRAY_SIZE-1) break;
+        }
+        options[numOfUnknownOptions] = NULL;
+
+        /* replace stuff from the replace Table */
+        for(i=0; replaceTable[2*i]!=NULL; i++){
+            if(!strcmp(replaceTable[2*i], filterName)){
+                int newlen= strlen(replaceTable[2*i + 1]);
+                int plen;
+                int spaceLeft;
+
+                p--, *p=',';
+
+                plen= strlen(p);
+                spaceLeft= p - temp + plen;
+                if(spaceLeft + newlen  >= GET_MODE_BUFFER_SIZE - 1){
+                    ppMode->error++;
+                    break;
+                }
+                memmove(p + newlen, p, plen+1);
+                memcpy(p, replaceTable[2*i + 1], newlen);
+                filterNameOk=1;
+            }
+        }
+
+        for(i=0; filters[i].shortName!=NULL; i++){
+            if(   !strcmp(filters[i].longName, filterName)
+               || !strcmp(filters[i].shortName, filterName)){
+                ppMode->lumMode &= ~filters[i].mask;
+                ppMode->chromMode &= ~filters[i].mask;
+
+                filterNameOk=1;
+                if(!enable) break; // user wants to disable it
+
+                if(q >= filters[i].minLumQuality && luma)
+                    ppMode->lumMode|= filters[i].mask;
+                if(chrom==1 || (chrom==-1 && filters[i].chromDefault))
+                    if(q >= filters[i].minChromQuality)
+                            ppMode->chromMode|= filters[i].mask;
+
+                if(filters[i].mask == LEVEL_FIX){
+                    int o;
+                    ppMode->minAllowedY= 16;
+                    ppMode->maxAllowedY= 234;
+                    for(o=0; options[o]!=NULL; o++){
+                        if(  !strcmp(options[o],"fullyrange")
+                           ||!strcmp(options[o],"f")){
+                            ppMode->minAllowedY= 0;
+                            ppMode->maxAllowedY= 255;
+                            numOfUnknownOptions--;
+                        }
+                    }
+                }
+                else if(filters[i].mask == TEMP_NOISE_FILTER)
+                {
+                    int o;
+                    int numOfNoises=0;
+
+                    for(o=0; options[o]!=NULL; o++){
+                        char *tail;
+                        ppMode->maxTmpNoise[numOfNoises]=
+                            strtol(options[o], &tail, 0);
+                        if(tail!=options[o]){
+                            numOfNoises++;
+                            numOfUnknownOptions--;
+                            if(numOfNoises >= 3) break;
+                        }
+                    }
+                }
+                else if(filters[i].mask == V_DEBLOCK   || filters[i].mask == H_DEBLOCK
+                     || filters[i].mask == V_A_DEBLOCK || filters[i].mask == H_A_DEBLOCK){
+                    int o;
+
+                    for(o=0; options[o]!=NULL && o<2; o++){
+                        char *tail;
+                        int val= strtol(options[o], &tail, 0);
+                        if(tail==options[o]) break;
+
+                        numOfUnknownOptions--;
+                        if(o==0) ppMode->baseDcDiff= val;
+                        else ppMode->flatnessThreshold= val;
+                    }
+                }
+                else if(filters[i].mask == FORCE_QUANT){
+                    int o;
+                    ppMode->forcedQuant= 15;
+
+                    for(o=0; options[o]!=NULL && o<1; o++){
+                        char *tail;
+                        int val= strtol(options[o], &tail, 0);
+                        if(tail==options[o]) break;
+
+                        numOfUnknownOptions--;
+                        ppMode->forcedQuant= val;
+                    }
+                }
+            }
+        }
+        if(!filterNameOk) ppMode->error++;
+        ppMode->error += numOfUnknownOptions;
+    }
+
+    av_log(NULL, AV_LOG_DEBUG, "pp: lumMode=%X, chromMode=%X\n", ppMode->lumMode, ppMode->chromMode);
+    if(ppMode->error){
+        av_log(NULL, AV_LOG_ERROR, "%d errors in postprocess string \"%s\"\n", ppMode->error, name);
+        av_free(ppMode);
+        return NULL;
+    }
+    return ppMode;
+}
+
+void pp_free_mode(pp_mode *mode){
+    av_free(mode);
+}
+
+static void reallocAlign(void **p, int alignment, int size){
+    av_free(*p);
+    *p= av_mallocz(size);
+}
+
+static void reallocBuffers(PPContext *c, int width, int height, int stride, int qpStride){
+    int mbWidth = (width+15)>>4;
+    int mbHeight= (height+15)>>4;
+    int i;
+
+    c->stride= stride;
+    c->qpStride= qpStride;
+
+    reallocAlign((void **)&c->tempDst, 8, stride*24);
+    reallocAlign((void **)&c->tempSrc, 8, stride*24);
+    reallocAlign((void **)&c->tempBlocks, 8, 2*16*8);
+    reallocAlign((void **)&c->yHistogram, 8, 256*sizeof(uint64_t));
+    for(i=0; i<256; i++)
+            c->yHistogram[i]= width*height/64*15/256;
+
+    for(i=0; i<3; i++){
+        //Note: The +17*1024 is just there so I do not have to worry about r/w over the end.
+        reallocAlign((void **)&c->tempBlurred[i], 8, stride*mbHeight*16 + 17*1024);
+        reallocAlign((void **)&c->tempBlurredPast[i], 8, 256*((height+7)&(~7))/2 + 17*1024);//FIXME size
+    }
+
+    reallocAlign((void **)&c->deintTemp, 8, 2*width+32);
+    reallocAlign((void **)&c->nonBQPTable, 8, qpStride*mbHeight*sizeof(QP_STORE_T));
+    reallocAlign((void **)&c->stdQPTable, 8, qpStride*mbHeight*sizeof(QP_STORE_T));
+    reallocAlign((void **)&c->forcedQPTable, 8, mbWidth*sizeof(QP_STORE_T));
+}
+
+static const char * context_to_name(void * ptr) {
+    return "postproc";
+}
+
+static const AVClass av_codec_context_class = { "Postproc", context_to_name, NULL };
+
+pp_context *pp_get_context(int width, int height, int cpuCaps){
+    PPContext *c= av_malloc(sizeof(PPContext));
+    int stride= FFALIGN(width, 16);  //assumed / will realloc if needed
+    int qpStride= (width+15)/16 + 2; //assumed / will realloc if needed
+
+    memset(c, 0, sizeof(PPContext));
+    c->av_class = &av_codec_context_class;
+    c->cpuCaps= cpuCaps;
+    if(cpuCaps&PP_FORMAT){
+        c->hChromaSubSample= cpuCaps&0x3;
+        c->vChromaSubSample= (cpuCaps>>4)&0x3;
+    }else{
+        c->hChromaSubSample= 1;
+        c->vChromaSubSample= 1;
+    }
+
+    reallocBuffers(c, width, height, stride, qpStride);
+
+    c->frameNum=-1;
+
+    return c;
+}
+
+void pp_free_context(void *vc){
+    PPContext *c = (PPContext*)vc;
+    int i;
+
+    for(i=0; i<3; i++) av_free(c->tempBlurred[i]);
+    for(i=0; i<3; i++) av_free(c->tempBlurredPast[i]);
+
+    av_free(c->tempBlocks);
+    av_free(c->yHistogram);
+    av_free(c->tempDst);
+    av_free(c->tempSrc);
+    av_free(c->deintTemp);
+    av_free(c->stdQPTable);
+    av_free(c->nonBQPTable);
+    av_free(c->forcedQPTable);
+
+    memset(c, 0, sizeof(PPContext));
+
+    av_free(c);
+}
+
+void  pp_postprocess(const uint8_t * src[3], const int srcStride[3],
+                     uint8_t * dst[3], const int dstStride[3],
+                     int width, int height,
+                     const QP_STORE_T *QP_store,  int QPStride,
+                     pp_mode *vm,  void *vc, int pict_type)
+{
+    int mbWidth = (width+15)>>4;
+    int mbHeight= (height+15)>>4;
+    PPMode *mode = (PPMode*)vm;
+    PPContext *c = (PPContext*)vc;
+    int minStride= FFMAX(FFABS(srcStride[0]), FFABS(dstStride[0]));
+    int absQPStride = FFABS(QPStride);
+
+    // c->stride and c->QPStride are always positive
+    if(c->stride < minStride || c->qpStride < absQPStride)
+        reallocBuffers(c, width, height,
+                       FFMAX(minStride, c->stride),
+                       FFMAX(c->qpStride, absQPStride));
+
+    if(QP_store==NULL || (mode->lumMode & FORCE_QUANT)){
+        int i;
+        QP_store= c->forcedQPTable;
+        absQPStride = QPStride = 0;
+        if(mode->lumMode & FORCE_QUANT)
+            for(i=0; i<mbWidth; i++) c->forcedQPTable[i]= mode->forcedQuant;
+        else
+            for(i=0; i<mbWidth; i++) c->forcedQPTable[i]= 1;
+    }
+
+    if(pict_type & PP_PICT_TYPE_QP2){
+        int i;
+        const int count= mbHeight * absQPStride;
+        for(i=0; i<(count>>2); i++){
+            ((uint32_t*)c->stdQPTable)[i] = (((const uint32_t*)QP_store)[i]>>1) & 0x7F7F7F7F;
+        }
+        for(i<<=2; i<count; i++){
+            c->stdQPTable[i] = QP_store[i]>>1;
+        }
+        QP_store= c->stdQPTable;
+        QPStride= absQPStride;
+    }
+
+    if(0){
+        int x,y;
+        for(y=0; y<mbHeight; y++){
+            for(x=0; x<mbWidth; x++){
+                av_log(c, AV_LOG_INFO, "%2d ", QP_store[x + y*QPStride]);
+            }
+            av_log(c, AV_LOG_INFO, "\n");
+        }
+        av_log(c, AV_LOG_INFO, "\n");
+    }
+
+    if((pict_type&7)!=3){
+        if (QPStride >= 0){
+            int i;
+            const int count= mbHeight * QPStride;
+            for(i=0; i<(count>>2); i++){
+                ((uint32_t*)c->nonBQPTable)[i] = ((const uint32_t*)QP_store)[i] & 0x3F3F3F3F;
+            }
+            for(i<<=2; i<count; i++){
+                c->nonBQPTable[i] = QP_store[i] & 0x3F;
+            }
+        } else {
+            int i,j;
+            for(i=0; i<mbHeight; i++) {
+                for(j=0; j<absQPStride; j++) {
+                    c->nonBQPTable[i*absQPStride+j] = QP_store[i*QPStride+j] & 0x3F;
+                }
+            }
+        }
+    }
+
+    av_log(c, AV_LOG_DEBUG, "using npp filters 0x%X/0x%X\n",
+           mode->lumMode, mode->chromMode);
+
+    postProcess(src[0], srcStride[0], dst[0], dstStride[0],
+                width, height, QP_store, QPStride, 0, mode, c);
+
+    width  = (width )>>c->hChromaSubSample;
+    height = (height)>>c->vChromaSubSample;
+
+    if(mode->chromMode){
+        postProcess(src[1], srcStride[1], dst[1], dstStride[1],
+                    width, height, QP_store, QPStride, 1, mode, c);
+        postProcess(src[2], srcStride[2], dst[2], dstStride[2],
+                    width, height, QP_store, QPStride, 2, mode, c);
+    }
+    else if(srcStride[1] == dstStride[1] && srcStride[2] == dstStride[2]){
+        linecpy(dst[1], src[1], height, srcStride[1]);
+        linecpy(dst[2], src[2], height, srcStride[2]);
+    }else{
+        int y;
+        for(y=0; y<height; y++){
+            memcpy(&(dst[1][y*dstStride[1]]), &(src[1][y*srcStride[1]]), width);
+            memcpy(&(dst[2][y*dstStride[2]]), &(src[2][y*srcStride[2]]), width);
+        }
+    }
+}
diff --git a/libpostproc/postprocess.h b/libpostproc/postprocess.h
new file mode 100644
index 0000000..623b3b5
--- /dev/null
+++ b/libpostproc/postprocess.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2001-2003 Michael Niedermayer (michaelni@gmx.at)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef POSTPROC_POSTPROCESS_H
+#define POSTPROC_POSTPROCESS_H
+
+/**
+ * @file
+ * @brief
+ *     external postprocessing API
+ */
+
+#include "libpostproc/version.h"
+
+/**
+ * Return the LIBPOSTPROC_VERSION_INT constant.
+ */
+unsigned postproc_version(void);
+
+/**
+ * Return the libpostproc build-time configuration.
+ */
+const char *postproc_configuration(void);
+
+/**
+ * Return the libpostproc license.
+ */
+const char *postproc_license(void);
+
+#define PP_QUALITY_MAX 6
+
+#define QP_STORE_T int8_t
+
+#include <inttypes.h>
+
+typedef void pp_context;
+typedef void pp_mode;
+
+#if LIBPOSTPROC_VERSION_INT < (52<<16)
+typedef pp_context pp_context_t;
+typedef pp_mode pp_mode_t;
+extern const char *const pp_help; ///< a simple help text
+#else
+extern const char pp_help[]; ///< a simple help text
+#endif
+
+void  pp_postprocess(const uint8_t * src[3], const int srcStride[3],
+                     uint8_t * dst[3], const int dstStride[3],
+                     int horizontalSize, int verticalSize,
+                     const QP_STORE_T *QP_store,  int QP_stride,
+                     pp_mode *mode, pp_context *ppContext, int pict_type);
+
+
+/**
+ * Return a pp_mode or NULL if an error occurred.
+ *
+ * @param name    the string after "-pp" on the command line
+ * @param quality a number from 0 to PP_QUALITY_MAX
+ */
+pp_mode *pp_get_mode_by_name_and_quality(const char *name, int quality);
+void pp_free_mode(pp_mode *mode);
+
+pp_context *pp_get_context(int width, int height, int flags);
+void pp_free_context(pp_context *ppContext);
+
+#define PP_CPU_CAPS_MMX   0x80000000
+#define PP_CPU_CAPS_MMX2  0x20000000
+#define PP_CPU_CAPS_3DNOW 0x40000000
+#define PP_CPU_CAPS_ALTIVEC 0x10000000
+
+#define PP_FORMAT         0x00000008
+#define PP_FORMAT_420    (0x00000011|PP_FORMAT)
+#define PP_FORMAT_422    (0x00000001|PP_FORMAT)
+#define PP_FORMAT_411    (0x00000002|PP_FORMAT)
+#define PP_FORMAT_444    (0x00000000|PP_FORMAT)
+
+#define PP_PICT_TYPE_QP2  0x00000010 ///< MPEG2 style QScale
+
+#endif /* POSTPROC_POSTPROCESS_H */
diff --git a/libpostproc/postprocess_altivec_template.c b/libpostproc/postprocess_altivec_template.c
new file mode 100644
index 0000000..3a37562
--- /dev/null
+++ b/libpostproc/postprocess_altivec_template.c
@@ -0,0 +1,1210 @@
+/*
+ * AltiVec optimizations (C) 2004 Romain Dolbeau <romain@dolbeau.org>
+ *
+ * based on code by Copyright (C) 2001-2003 Michael Niedermayer (michaelni@gmx.at)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/avutil.h"
+
+#define ALTIVEC_TRANSPOSE_8x8_SHORT(src_a,src_b,src_c,src_d,src_e,src_f,src_g,src_h) \
+    do {                                                          \
+        __typeof__(src_a) tempA1, tempB1, tempC1, tempD1;         \
+        __typeof__(src_a) tempE1, tempF1, tempG1, tempH1;         \
+        __typeof__(src_a) tempA2, tempB2, tempC2, tempD2;         \
+        __typeof__(src_a) tempE2, tempF2, tempG2, tempH2;         \
+        tempA1 = vec_mergeh (src_a, src_e);                       \
+        tempB1 = vec_mergel (src_a, src_e);                       \
+        tempC1 = vec_mergeh (src_b, src_f);                       \
+        tempD1 = vec_mergel (src_b, src_f);                       \
+        tempE1 = vec_mergeh (src_c, src_g);                       \
+        tempF1 = vec_mergel (src_c, src_g);                       \
+        tempG1 = vec_mergeh (src_d, src_h);                       \
+        tempH1 = vec_mergel (src_d, src_h);                       \
+        tempA2 = vec_mergeh (tempA1, tempE1);                     \
+        tempB2 = vec_mergel (tempA1, tempE1);                     \
+        tempC2 = vec_mergeh (tempB1, tempF1);                     \
+        tempD2 = vec_mergel (tempB1, tempF1);                     \
+        tempE2 = vec_mergeh (tempC1, tempG1);                     \
+        tempF2 = vec_mergel (tempC1, tempG1);                     \
+        tempG2 = vec_mergeh (tempD1, tempH1);                     \
+        tempH2 = vec_mergel (tempD1, tempH1);                     \
+        src_a = vec_mergeh (tempA2, tempE2);                      \
+        src_b = vec_mergel (tempA2, tempE2);                      \
+        src_c = vec_mergeh (tempB2, tempF2);                      \
+        src_d = vec_mergel (tempB2, tempF2);                      \
+        src_e = vec_mergeh (tempC2, tempG2);                      \
+        src_f = vec_mergel (tempC2, tempG2);                      \
+        src_g = vec_mergeh (tempD2, tempH2);                      \
+        src_h = vec_mergel (tempD2, tempH2);                      \
+    } while (0)
+
+
+static inline int vertClassify_altivec(uint8_t src[], int stride, PPContext *c) {
+    /*
+    this code makes no assumption on src or stride.
+    One could remove the recomputation of the perm
+    vector by assuming (stride % 16) == 0, unfortunately
+    this is not always true.
+    */
+    short data_0 = ((c->nonBQP*c->ppMode.baseDcDiff)>>8) + 1;
+    DECLARE_ALIGNED(16, short, data)[8] =
+                    {
+                        data_0,
+                        data_0 * 2 + 1,
+                        c->QP * 2,
+                        c->QP * 4
+                    };
+    int numEq;
+    uint8_t *src2 = src;
+    vector signed short v_dcOffset;
+    vector signed short v2QP;
+    vector unsigned short v4QP;
+    vector unsigned short v_dcThreshold;
+    const int properStride = (stride % 16);
+    const int srcAlign = ((unsigned long)src2 % 16);
+    const int two_vectors = ((srcAlign > 8) || properStride) ? 1 : 0;
+    const vector signed int zero = vec_splat_s32(0);
+    const vector signed short mask = vec_splat_s16(1);
+    vector signed int v_numEq = vec_splat_s32(0);
+    vector signed short v_data = vec_ld(0, data);
+    vector signed short v_srcAss0, v_srcAss1, v_srcAss2, v_srcAss3,
+                        v_srcAss4, v_srcAss5, v_srcAss6, v_srcAss7;
+//FIXME avoid this mess if possible
+    register int j0 = 0,
+                 j1 = stride,
+                 j2 = 2 * stride,
+                 j3 = 3 * stride,
+                 j4 = 4 * stride,
+                 j5 = 5 * stride,
+                 j6 = 6 * stride,
+                 j7 = 7 * stride;
+    vector unsigned char v_srcA0, v_srcA1, v_srcA2, v_srcA3,
+                         v_srcA4, v_srcA5, v_srcA6, v_srcA7;
+
+    v_dcOffset = vec_splat(v_data, 0);
+    v_dcThreshold = (vector unsigned short)vec_splat(v_data, 1);
+    v2QP = vec_splat(v_data, 2);
+    v4QP = (vector unsigned short)vec_splat(v_data, 3);
+
+    src2 += stride * 4;
+
+#define LOAD_LINE(i)                                                    \
+    {                                                                   \
+    vector unsigned char perm##i = vec_lvsl(j##i, src2);                \
+    vector unsigned char v_srcA2##i;                                    \
+    vector unsigned char v_srcA1##i = vec_ld(j##i, src2);               \
+    if (two_vectors)                                                    \
+        v_srcA2##i = vec_ld(j##i + 16, src2);                           \
+    v_srcA##i =                                                         \
+        vec_perm(v_srcA1##i, v_srcA2##i, perm##i);                      \
+    v_srcAss##i =                                                       \
+        (vector signed short)vec_mergeh((vector signed char)zero,       \
+                                        (vector signed char)v_srcA##i); }
+
+#define LOAD_LINE_ALIGNED(i)                                            \
+    v_srcA##i = vec_ld(j##i, src2);                                     \
+    v_srcAss##i =                                                       \
+        (vector signed short)vec_mergeh((vector signed char)zero,       \
+                                        (vector signed char)v_srcA##i)
+
+    /* Special-casing the aligned case is worthwhile, as all calls from
+     * the (transposed) horizontable deblocks will be aligned, in addition
+     * to the naturally aligned vertical deblocks. */
+    if (properStride && srcAlign) {
+        LOAD_LINE_ALIGNED(0);
+        LOAD_LINE_ALIGNED(1);
+        LOAD_LINE_ALIGNED(2);
+        LOAD_LINE_ALIGNED(3);
+        LOAD_LINE_ALIGNED(4);
+        LOAD_LINE_ALIGNED(5);
+        LOAD_LINE_ALIGNED(6);
+        LOAD_LINE_ALIGNED(7);
+    } else {
+        LOAD_LINE(0);
+        LOAD_LINE(1);
+        LOAD_LINE(2);
+        LOAD_LINE(3);
+        LOAD_LINE(4);
+        LOAD_LINE(5);
+        LOAD_LINE(6);
+        LOAD_LINE(7);
+    }
+#undef LOAD_LINE
+#undef LOAD_LINE_ALIGNED
+
+#define ITER(i, j)                                                      \
+    const vector signed short v_diff##i =                               \
+        vec_sub(v_srcAss##i, v_srcAss##j);                              \
+    const vector signed short v_sum##i =                                \
+        vec_add(v_diff##i, v_dcOffset);                                 \
+    const vector signed short v_comp##i =                               \
+        (vector signed short)vec_cmplt((vector unsigned short)v_sum##i, \
+                                       v_dcThreshold);                  \
+    const vector signed short v_part##i = vec_and(mask, v_comp##i);
+
+    {
+        ITER(0, 1)
+        ITER(1, 2)
+        ITER(2, 3)
+        ITER(3, 4)
+        ITER(4, 5)
+        ITER(5, 6)
+        ITER(6, 7)
+
+        v_numEq = vec_sum4s(v_part0, v_numEq);
+        v_numEq = vec_sum4s(v_part1, v_numEq);
+        v_numEq = vec_sum4s(v_part2, v_numEq);
+        v_numEq = vec_sum4s(v_part3, v_numEq);
+        v_numEq = vec_sum4s(v_part4, v_numEq);
+        v_numEq = vec_sum4s(v_part5, v_numEq);
+        v_numEq = vec_sum4s(v_part6, v_numEq);
+    }
+
+#undef ITER
+
+    v_numEq = vec_sums(v_numEq, zero);
+
+    v_numEq = vec_splat(v_numEq, 3);
+    vec_ste(v_numEq, 0, &numEq);
+
+    if (numEq > c->ppMode.flatnessThreshold){
+        const vector unsigned char mmoP1 = (const vector unsigned char)
+            {0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
+             0x00, 0x01, 0x12, 0x13, 0x08, 0x09, 0x1A, 0x1B};
+        const vector unsigned char mmoP2 = (const vector unsigned char)
+            {0x04, 0x05, 0x16, 0x17, 0x0C, 0x0D, 0x1E, 0x1F,
+             0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f};
+        const vector unsigned char mmoP = (const vector unsigned char)
+            vec_lvsl(8, (unsigned char*)0);
+
+        vector signed short mmoL1 = vec_perm(v_srcAss0, v_srcAss2, mmoP1);
+        vector signed short mmoL2 = vec_perm(v_srcAss4, v_srcAss6, mmoP2);
+        vector signed short mmoL = vec_perm(mmoL1, mmoL2, mmoP);
+        vector signed short mmoR1 = vec_perm(v_srcAss5, v_srcAss7, mmoP1);
+        vector signed short mmoR2 = vec_perm(v_srcAss1, v_srcAss3, mmoP2);
+        vector signed short mmoR = vec_perm(mmoR1, mmoR2, mmoP);
+        vector signed short mmoDiff = vec_sub(mmoL, mmoR);
+        vector unsigned short mmoSum = (vector unsigned short)vec_add(mmoDiff, v2QP);
+
+        if (vec_any_gt(mmoSum, v4QP))
+            return 0;
+        else
+            return 1;
+    }
+    else return 2;
+}
+
+static inline void doVertLowPass_altivec(uint8_t *src, int stride, PPContext *c) {
+    /*
+    this code makes no assumption on src or stride.
+    One could remove the recomputation of the perm
+    vector by assuming (stride % 16) == 0, unfortunately
+    this is not always true. Quite a lot of load/stores
+    can be removed by assuming proper alignment of
+    src & stride :-(
+    */
+    uint8_t *src2 = src;
+    const vector signed int zero = vec_splat_s32(0);
+    const int properStride = (stride % 16);
+    const int srcAlign = ((unsigned long)src2 % 16);
+    DECLARE_ALIGNED(16, short, qp)[8] = {c->QP};
+    vector signed short vqp = vec_ld(0, qp);
+    vector signed short vb0, vb1, vb2, vb3, vb4, vb5, vb6, vb7, vb8, vb9;
+    vector unsigned char vbA0, av_uninit(vbA1), av_uninit(vbA2), av_uninit(vbA3), av_uninit(vbA4), av_uninit(vbA5), av_uninit(vbA6), av_uninit(vbA7), av_uninit(vbA8), vbA9;
+    vector unsigned char vbB0, av_uninit(vbB1), av_uninit(vbB2), av_uninit(vbB3), av_uninit(vbB4), av_uninit(vbB5), av_uninit(vbB6), av_uninit(vbB7), av_uninit(vbB8), vbB9;
+    vector unsigned char vbT0, vbT1, vbT2, vbT3, vbT4, vbT5, vbT6, vbT7, vbT8, vbT9;
+    vector unsigned char perml0, perml1, perml2, perml3, perml4,
+                         perml5, perml6, perml7, perml8, perml9;
+    register int j0 = 0,
+                 j1 = stride,
+                 j2 = 2 * stride,
+                 j3 = 3 * stride,
+                 j4 = 4 * stride,
+                 j5 = 5 * stride,
+                 j6 = 6 * stride,
+                 j7 = 7 * stride,
+                 j8 = 8 * stride,
+                 j9 = 9 * stride;
+
+    vqp = vec_splat(vqp, 0);
+
+    src2 += stride*3;
+
+#define LOAD_LINE(i)                                                    \
+    perml##i = vec_lvsl(i * stride, src2);                              \
+    vbA##i = vec_ld(i * stride, src2);                                  \
+    vbB##i = vec_ld(i * stride + 16, src2);                             \
+    vbT##i = vec_perm(vbA##i, vbB##i, perml##i);                        \
+    vb##i =                                                             \
+        (vector signed short)vec_mergeh((vector unsigned char)zero,     \
+                                        (vector unsigned char)vbT##i)
+
+#define LOAD_LINE_ALIGNED(i)                                            \
+    vbT##i = vec_ld(j##i, src2);                                        \
+    vb##i =                                                             \
+        (vector signed short)vec_mergeh((vector signed char)zero,       \
+                                        (vector signed char)vbT##i)
+
+      /* Special-casing the aligned case is worthwhile, as all calls from
+       * the (transposed) horizontable deblocks will be aligned, in addition
+       * to the naturally aligned vertical deblocks. */
+    if (properStride && srcAlign) {
+          LOAD_LINE_ALIGNED(0);
+          LOAD_LINE_ALIGNED(1);
+          LOAD_LINE_ALIGNED(2);
+          LOAD_LINE_ALIGNED(3);
+          LOAD_LINE_ALIGNED(4);
+          LOAD_LINE_ALIGNED(5);
+          LOAD_LINE_ALIGNED(6);
+          LOAD_LINE_ALIGNED(7);
+          LOAD_LINE_ALIGNED(8);
+          LOAD_LINE_ALIGNED(9);
+    } else {
+          LOAD_LINE(0);
+          LOAD_LINE(1);
+          LOAD_LINE(2);
+          LOAD_LINE(3);
+          LOAD_LINE(4);
+          LOAD_LINE(5);
+          LOAD_LINE(6);
+          LOAD_LINE(7);
+          LOAD_LINE(8);
+          LOAD_LINE(9);
+    }
+#undef LOAD_LINE
+#undef LOAD_LINE_ALIGNED
+    {
+        const vector unsigned short v_2 = vec_splat_u16(2);
+        const vector unsigned short v_4 = vec_splat_u16(4);
+
+        const vector signed short v_diff01 = vec_sub(vb0, vb1);
+        const vector unsigned short v_cmp01 =
+            (const vector unsigned short) vec_cmplt(vec_abs(v_diff01), vqp);
+        const vector signed short v_first = vec_sel(vb1, vb0, v_cmp01);
+        const vector signed short v_diff89 = vec_sub(vb8, vb9);
+        const vector unsigned short v_cmp89 =
+            (const vector unsigned short) vec_cmplt(vec_abs(v_diff89), vqp);
+        const vector signed short v_last = vec_sel(vb8, vb9, v_cmp89);
+
+        const vector signed short temp01 = vec_mladd(v_first, (vector signed short)v_4, vb1);
+        const vector signed short temp02 = vec_add(vb2, vb3);
+        const vector signed short temp03 = vec_add(temp01, (vector signed short)v_4);
+        const vector signed short v_sumsB0 = vec_add(temp02, temp03);
+
+        const vector signed short temp11 = vec_sub(v_sumsB0, v_first);
+        const vector signed short v_sumsB1 = vec_add(temp11, vb4);
+
+        const vector signed short temp21 = vec_sub(v_sumsB1, v_first);
+        const vector signed short v_sumsB2 = vec_add(temp21, vb5);
+
+        const vector signed short temp31 = vec_sub(v_sumsB2, v_first);
+        const vector signed short v_sumsB3 = vec_add(temp31, vb6);
+
+        const vector signed short temp41 = vec_sub(v_sumsB3, v_first);
+        const vector signed short v_sumsB4 = vec_add(temp41, vb7);
+
+        const vector signed short temp51 = vec_sub(v_sumsB4, vb1);
+        const vector signed short v_sumsB5 = vec_add(temp51, vb8);
+
+        const vector signed short temp61 = vec_sub(v_sumsB5, vb2);
+        const vector signed short v_sumsB6 = vec_add(temp61, v_last);
+
+        const vector signed short temp71 = vec_sub(v_sumsB6, vb3);
+        const vector signed short v_sumsB7 = vec_add(temp71, v_last);
+
+        const vector signed short temp81 = vec_sub(v_sumsB7, vb4);
+        const vector signed short v_sumsB8 = vec_add(temp81, v_last);
+
+        const vector signed short temp91 = vec_sub(v_sumsB8, vb5);
+        const vector signed short v_sumsB9 = vec_add(temp91, v_last);
+
+    #define COMPUTE_VR(i, j, k)                                             \
+        const vector signed short temps1##i =                               \
+            vec_add(v_sumsB##i, v_sumsB##k);                                \
+        const vector signed short temps2##i =                               \
+            vec_mladd(vb##j, (vector signed short)v_2, temps1##i);          \
+        const vector signed short  vr##j = vec_sra(temps2##i, v_4)
+
+        COMPUTE_VR(0, 1, 2);
+        COMPUTE_VR(1, 2, 3);
+        COMPUTE_VR(2, 3, 4);
+        COMPUTE_VR(3, 4, 5);
+        COMPUTE_VR(4, 5, 6);
+        COMPUTE_VR(5, 6, 7);
+        COMPUTE_VR(6, 7, 8);
+        COMPUTE_VR(7, 8, 9);
+
+        const vector signed char neg1 = vec_splat_s8(-1);
+        const vector unsigned char permHH = (const vector unsigned char){0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+                                                                         0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
+
+#define PACK_AND_STORE(i)                                       \
+{   const vector unsigned char perms##i =                       \
+        vec_lvsr(i * stride, src2);                             \
+    const vector unsigned char vf##i =                          \
+        vec_packsu(vr##i, (vector signed short)zero);           \
+    const vector unsigned char vg##i =                          \
+        vec_perm(vf##i, vbT##i, permHH);                        \
+    const vector unsigned char mask##i =                        \
+        vec_perm((vector unsigned char)zero, (vector unsigned char)neg1, perms##i); \
+    const vector unsigned char vg2##i =                         \
+        vec_perm(vg##i, vg##i, perms##i);                       \
+    const vector unsigned char svA##i =                         \
+        vec_sel(vbA##i, vg2##i, mask##i);                       \
+    const vector unsigned char svB##i =                         \
+        vec_sel(vg2##i, vbB##i, mask##i);                       \
+    vec_st(svA##i, i * stride, src2);                           \
+    vec_st(svB##i, i * stride + 16, src2);}
+
+#define PACK_AND_STORE_ALIGNED(i)                               \
+{   const vector unsigned char vf##i =                          \
+        vec_packsu(vr##i, (vector signed short)zero);           \
+    const vector unsigned char vg##i =                          \
+        vec_perm(vf##i, vbT##i, permHH);                        \
+    vec_st(vg##i, i * stride, src2);}
+
+        /* Special-casing the aligned case is worthwhile, as all calls from
+         * the (transposed) horizontable deblocks will be aligned, in addition
+         * to the naturally aligned vertical deblocks. */
+        if (properStride && srcAlign) {
+            PACK_AND_STORE_ALIGNED(1)
+            PACK_AND_STORE_ALIGNED(2)
+            PACK_AND_STORE_ALIGNED(3)
+            PACK_AND_STORE_ALIGNED(4)
+            PACK_AND_STORE_ALIGNED(5)
+            PACK_AND_STORE_ALIGNED(6)
+            PACK_AND_STORE_ALIGNED(7)
+            PACK_AND_STORE_ALIGNED(8)
+        } else {
+            PACK_AND_STORE(1)
+            PACK_AND_STORE(2)
+            PACK_AND_STORE(3)
+            PACK_AND_STORE(4)
+            PACK_AND_STORE(5)
+            PACK_AND_STORE(6)
+            PACK_AND_STORE(7)
+            PACK_AND_STORE(8)
+        }
+    #undef PACK_AND_STORE
+    #undef PACK_AND_STORE_ALIGNED
+    }
+}
+
+
+
+static inline void doVertDefFilter_altivec(uint8_t src[], int stride, PPContext *c) {
+    /*
+    this code makes no assumption on src or stride.
+    One could remove the recomputation of the perm
+    vector by assuming (stride % 16) == 0, unfortunately
+    this is not always true. Quite a lot of load/stores
+    can be removed by assuming proper alignment of
+    src & stride :-(
+    */
+    uint8_t *src2 = src + stride*3;
+    const vector signed int zero = vec_splat_s32(0);
+    DECLARE_ALIGNED(16, short, qp)[8] = {8*c->QP};
+    vector signed short vqp = vec_splat(
+                                (vector signed short)vec_ld(0, qp), 0);
+
+#define LOAD_LINE(i)                                                    \
+    const vector unsigned char perm##i =                                \
+        vec_lvsl(i * stride, src2);                                     \
+    const vector unsigned char vbA##i =                                 \
+        vec_ld(i * stride, src2);                                       \
+    const vector unsigned char vbB##i =                                 \
+        vec_ld(i * stride + 16, src2);                                  \
+    const vector unsigned char vbT##i =                                 \
+        vec_perm(vbA##i, vbB##i, perm##i);                              \
+    const vector signed short vb##i =                                   \
+        (vector signed short)vec_mergeh((vector unsigned char)zero,     \
+                                        (vector unsigned char)vbT##i)
+
+     LOAD_LINE(1);
+     LOAD_LINE(2);
+     LOAD_LINE(3);
+     LOAD_LINE(4);
+     LOAD_LINE(5);
+     LOAD_LINE(6);
+     LOAD_LINE(7);
+     LOAD_LINE(8);
+#undef LOAD_LINE
+
+     const vector signed short v_1 = vec_splat_s16(1);
+     const vector signed short v_2 = vec_splat_s16(2);
+     const vector signed short v_5 = vec_splat_s16(5);
+     const vector signed short v_32 = vec_sl(v_1,
+                                             (vector unsigned short)v_5);
+     /* middle energy */
+     const vector signed short l3minusl6 = vec_sub(vb3, vb6);
+     const vector signed short l5minusl4 = vec_sub(vb5, vb4);
+     const vector signed short twotimes_l3minusl6 = vec_mladd(v_2, l3minusl6, (vector signed short)zero);
+     const vector signed short mE = vec_mladd(v_5, l5minusl4, twotimes_l3minusl6);
+     const vector signed short absmE = vec_abs(mE);
+     /* left & right energy */
+     const vector signed short l1minusl4 = vec_sub(vb1, vb4);
+     const vector signed short l3minusl2 = vec_sub(vb3, vb2);
+     const vector signed short l5minusl8 = vec_sub(vb5, vb8);
+     const vector signed short l7minusl6 = vec_sub(vb7, vb6);
+     const vector signed short twotimes_l1minusl4 = vec_mladd(v_2, l1minusl4, (vector signed short)zero);
+     const vector signed short twotimes_l5minusl8 = vec_mladd(v_2, l5minusl8, (vector signed short)zero);
+     const vector signed short lE = vec_mladd(v_5, l3minusl2, twotimes_l1minusl4);
+     const vector signed short rE = vec_mladd(v_5, l7minusl6, twotimes_l5minusl8);
+     /* d */
+     const vector signed short ddiff = vec_sub(absmE,
+                                               vec_min(vec_abs(lE),
+                                                       vec_abs(rE)));
+     const vector signed short ddiffclamp = vec_max(ddiff, (vector signed short)zero);
+     const vector signed short dtimes64 = vec_mladd(v_5, ddiffclamp, v_32);
+     const vector signed short d = vec_sra(dtimes64, vec_splat_u16(6));
+     const vector signed short minusd = vec_sub((vector signed short)zero, d);
+     const vector signed short finald = vec_sel(minusd,
+                                                d,
+                                                vec_cmpgt(vec_sub((vector signed short)zero, mE),
+                                                          (vector signed short)zero));
+     /* q */
+     const vector signed short qtimes2 = vec_sub(vb4, vb5);
+     /* for a shift right to behave like /2, we need to add one
+        to all negative integer */
+     const vector signed short rounddown = vec_sel((vector signed short)zero,
+                                                   v_1,
+                                                   vec_cmplt(qtimes2, (vector signed short)zero));
+     const vector signed short q = vec_sra(vec_add(qtimes2, rounddown), vec_splat_u16(1));
+     /* clamp */
+     const vector signed short dclamp_P1 = vec_max((vector signed short)zero, finald);
+     const vector signed short dclamp_P = vec_min(dclamp_P1, q);
+     const vector signed short dclamp_N1 = vec_min((vector signed short)zero, finald);
+     const vector signed short dclamp_N = vec_max(dclamp_N1, q);
+
+     const vector signed short dclampedfinal = vec_sel(dclamp_N,
+                                                       dclamp_P,
+                                                       vec_cmpgt(q, (vector signed short)zero));
+     const vector signed short dornotd = vec_sel((vector signed short)zero,
+                                                 dclampedfinal,
+                                                 vec_cmplt(absmE, vqp));
+     /* add/subtract to l4 and l5 */
+     const vector signed short vb4minusd = vec_sub(vb4, dornotd);
+     const vector signed short vb5plusd  = vec_add(vb5, dornotd);
+     /* finally, stores */
+     const vector unsigned char st4 = vec_packsu(vb4minusd, (vector signed short)zero);
+     const vector unsigned char st5 = vec_packsu(vb5plusd,  (vector signed short)zero);
+
+     const vector signed char neg1 = vec_splat_s8(-1);
+     const vector unsigned char permHH = (const vector unsigned char){0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+                                                                      0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
+
+#define STORE(i)                                                \
+{    const vector unsigned char perms##i =                      \
+         vec_lvsr(i * stride, src2);                            \
+     const vector unsigned char vg##i =                         \
+         vec_perm(st##i, vbT##i, permHH);                       \
+     const vector unsigned char mask##i =                       \
+         vec_perm((vector unsigned char)zero, (vector unsigned char)neg1, perms##i); \
+     const vector unsigned char vg2##i =                        \
+         vec_perm(vg##i, vg##i, perms##i);                      \
+     const vector unsigned char svA##i =                        \
+         vec_sel(vbA##i, vg2##i, mask##i);                      \
+     const vector unsigned char svB##i =                        \
+         vec_sel(vg2##i, vbB##i, mask##i);                      \
+     vec_st(svA##i, i * stride, src2);                          \
+     vec_st(svB##i, i * stride + 16, src2);}
+
+     STORE(4)
+     STORE(5)
+}
+
+static inline void dering_altivec(uint8_t src[], int stride, PPContext *c) {
+    const vector signed int vsint32_8 = vec_splat_s32(8);
+    const vector unsigned int vuint32_4 = vec_splat_u32(4);
+    const vector signed char neg1 = vec_splat_s8(-1);
+
+    const vector unsigned char permA1 = (vector unsigned char)
+        {0x00, 0x01, 0x02, 0x10, 0x11, 0x12, 0x1F, 0x1F,
+         0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
+    const vector unsigned char permA2 = (vector unsigned char)
+        {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x10, 0x11,
+         0x12, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F};
+    const vector unsigned char permA1inc = (vector unsigned char)
+        {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
+         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    const vector unsigned char permA2inc = (vector unsigned char)
+        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    const vector unsigned char magic = (vector unsigned char)
+        {0x01, 0x02, 0x01, 0x02, 0x04, 0x02, 0x01, 0x02,
+         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    const vector unsigned char extractPerm = (vector unsigned char)
+        {0x10, 0x10, 0x10, 0x01, 0x10, 0x10, 0x10, 0x01,
+         0x10, 0x10, 0x10, 0x01, 0x10, 0x10, 0x10, 0x01};
+    const vector unsigned char extractPermInc = (vector unsigned char)
+        {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
+         0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01};
+    const vector unsigned char identity = vec_lvsl(0,(unsigned char *)0);
+    const vector unsigned char tenRight = (vector unsigned char)
+        {0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+    const vector unsigned char eightLeft = (vector unsigned char)
+        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08};
+
+    /*
+    this code makes no assumption on src or stride.
+    One could remove the recomputation of the perm
+    vector by assuming (stride % 16) == 0, unfortunately
+    this is not always true. Quite a lot of load/stores
+    can be removed by assuming proper alignment of
+    src & stride :-(
+    */
+    uint8_t *srcCopy = src;
+    DECLARE_ALIGNED(16, uint8_t, dt)[16] = { deringThreshold };
+    const vector signed int zero = vec_splat_s32(0);
+    vector unsigned char v_dt = vec_splat(vec_ld(0, dt), 0);
+
+#define LOAD_LINE(i)                                                  \
+    const vector unsigned char perm##i =                              \
+        vec_lvsl(i * stride, srcCopy);                                \
+    vector unsigned char sA##i = vec_ld(i * stride, srcCopy);         \
+    vector unsigned char sB##i = vec_ld(i * stride + 16, srcCopy);    \
+    vector unsigned char src##i = vec_perm(sA##i, sB##i, perm##i)
+
+    LOAD_LINE(0);
+    LOAD_LINE(1);
+    LOAD_LINE(2);
+    LOAD_LINE(3);
+    LOAD_LINE(4);
+    LOAD_LINE(5);
+    LOAD_LINE(6);
+    LOAD_LINE(7);
+    LOAD_LINE(8);
+    LOAD_LINE(9);
+#undef LOAD_LINE
+
+    vector unsigned char v_avg;
+    DECLARE_ALIGNED(16, signed int, S)[8];
+    DECLARE_ALIGNED(16, int, tQP2)[4] = { c->QP/2 + 1 };
+    vector signed int vQP2 = vec_ld(0, tQP2);
+    vQP2 = vec_splat(vQP2, 0);
+
+    {
+    const vector unsigned char trunc_perm = (vector unsigned char)
+        {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+         0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
+    const vector unsigned char trunc_src12 = vec_perm(src1, src2, trunc_perm);
+    const vector unsigned char trunc_src34 = vec_perm(src3, src4, trunc_perm);
+    const vector unsigned char trunc_src56 = vec_perm(src5, src6, trunc_perm);
+    const vector unsigned char trunc_src78 = vec_perm(src7, src8, trunc_perm);
+
+#define EXTRACT(op) do {                                                \
+    const vector unsigned char s_1   = vec_##op(trunc_src12, trunc_src34); \
+    const vector unsigned char s_2   = vec_##op(trunc_src56, trunc_src78); \
+    const vector unsigned char s_6   = vec_##op(s_1, s_2);     \
+    const vector unsigned char s_8h  = vec_mergeh(s_6, s_6);   \
+    const vector unsigned char s_8l  = vec_mergel(s_6, s_6);   \
+    const vector unsigned char s_9   = vec_##op(s_8h, s_8l);   \
+    const vector unsigned char s_9h  = vec_mergeh(s_9, s_9);   \
+    const vector unsigned char s_9l  = vec_mergel(s_9, s_9);   \
+    const vector unsigned char s_10  = vec_##op(s_9h, s_9l);   \
+    const vector unsigned char s_10h = vec_mergeh(s_10, s_10); \
+    const vector unsigned char s_10l = vec_mergel(s_10, s_10); \
+    const vector unsigned char s_11  = vec_##op(s_10h, s_10l); \
+    const vector unsigned char s_11h = vec_mergeh(s_11, s_11); \
+    const vector unsigned char s_11l = vec_mergel(s_11, s_11); \
+    v_##op = vec_##op(s_11h, s_11l);                           \
+} while (0)
+
+    vector unsigned char v_min;
+    vector unsigned char v_max;
+    EXTRACT(min);
+    EXTRACT(max);
+#undef EXTRACT
+
+    if (vec_all_lt(vec_sub(v_max, v_min), v_dt))
+        return;
+
+    v_avg = vec_avg(v_min, v_max);
+    }
+
+    {
+    const vector unsigned short mask1 = (vector unsigned short)
+                                        {0x0001, 0x0002, 0x0004, 0x0008,
+                                         0x0010, 0x0020, 0x0040, 0x0080};
+    const vector unsigned short mask2 = (vector unsigned short)
+                                        {0x0100, 0x0200, 0x0000, 0x0000,
+                                         0x0000, 0x0000, 0x0000, 0x0000};
+
+    const vector unsigned int vuint32_16 = vec_sl(vec_splat_u32(1), vec_splat_u32(4));
+    const vector unsigned int vuint32_1 = vec_splat_u32(1);
+
+    vector signed int sumA2;
+    vector signed int sumB2;
+    vector signed int sum0, sum1, sum2, sum3, sum4;
+    vector signed int sum5, sum6, sum7, sum8, sum9;
+
+#define COMPARE(i)                                                      \
+    do {                                                                \
+        const vector unsigned char cmp =                                \
+            (vector unsigned char)vec_cmpgt(src##i, v_avg);             \
+        const vector unsigned short cmpHi =                             \
+            (vector unsigned short)vec_mergeh(cmp, cmp);                \
+        const vector unsigned short cmpLi =                             \
+            (vector unsigned short)vec_mergel(cmp, cmp);                \
+        const vector signed short cmpHf =                               \
+            (vector signed short)vec_and(cmpHi, mask1);                 \
+        const vector signed short cmpLf =                               \
+            (vector signed short)vec_and(cmpLi, mask2);                 \
+        const vector signed int sump = vec_sum4s(cmpHf, zero);          \
+        const vector signed int sumq = vec_sum4s(cmpLf, sump);          \
+        sum##i  = vec_sums(sumq, zero);                                 \
+    } while (0)
+
+    COMPARE(0);
+    COMPARE(1);
+    COMPARE(2);
+    COMPARE(3);
+    COMPARE(4);
+    COMPARE(5);
+    COMPARE(6);
+    COMPARE(7);
+    COMPARE(8);
+    COMPARE(9);
+#undef COMPARE
+
+    {
+    const vector signed int sump02 = vec_mergel(sum0, sum2);
+    const vector signed int sump13 = vec_mergel(sum1, sum3);
+    const vector signed int sumA = vec_mergel(sump02, sump13);
+
+    const vector signed int sump46 = vec_mergel(sum4, sum6);
+    const vector signed int sump57 = vec_mergel(sum5, sum7);
+    const vector signed int sumB = vec_mergel(sump46, sump57);
+
+    const vector signed int sump8A = vec_mergel(sum8, zero);
+    const vector signed int sump9B = vec_mergel(sum9, zero);
+    const vector signed int sumC = vec_mergel(sump8A, sump9B);
+
+    const vector signed int tA = vec_sl(vec_nor(zero, sumA), vuint32_16);
+    const vector signed int tB = vec_sl(vec_nor(zero, sumB), vuint32_16);
+    const vector signed int tC = vec_sl(vec_nor(zero, sumC), vuint32_16);
+    const vector signed int t2A = vec_or(sumA, tA);
+    const vector signed int t2B = vec_or(sumB, tB);
+    const vector signed int t2C = vec_or(sumC, tC);
+    const vector signed int t3A = vec_and(vec_sra(t2A, vuint32_1),
+                                          vec_sl(t2A, vuint32_1));
+    const vector signed int t3B = vec_and(vec_sra(t2B, vuint32_1),
+                                          vec_sl(t2B, vuint32_1));
+    const vector signed int t3C = vec_and(vec_sra(t2C, vuint32_1),
+                                          vec_sl(t2C, vuint32_1));
+    const vector signed int yA = vec_and(t2A, t3A);
+    const vector signed int yB = vec_and(t2B, t3B);
+    const vector signed int yC = vec_and(t2C, t3C);
+
+    const vector unsigned char strangeperm1 = vec_lvsl(4, (unsigned char*)0);
+    const vector unsigned char strangeperm2 = vec_lvsl(8, (unsigned char*)0);
+    const vector signed int sumAd4 = vec_perm(yA, yB, strangeperm1);
+    const vector signed int sumAd8 = vec_perm(yA, yB, strangeperm2);
+    const vector signed int sumBd4 = vec_perm(yB, yC, strangeperm1);
+    const vector signed int sumBd8 = vec_perm(yB, yC, strangeperm2);
+    const vector signed int sumAp = vec_and(yA,
+                                            vec_and(sumAd4,sumAd8));
+    const vector signed int sumBp = vec_and(yB,
+                                            vec_and(sumBd4,sumBd8));
+    sumA2 = vec_or(sumAp,
+                   vec_sra(sumAp,
+                           vuint32_16));
+    sumB2  = vec_or(sumBp,
+                    vec_sra(sumBp,
+                            vuint32_16));
+    }
+    vec_st(sumA2, 0, S);
+    vec_st(sumB2, 16, S);
+    }
+
+    /* I'm not sure the following is actually faster
+       than straight, unvectorized C code :-( */
+
+#define F_INIT()                                       \
+    vector unsigned char tenRightM = tenRight;         \
+    vector unsigned char permA1M = permA1;             \
+    vector unsigned char permA2M = permA2;             \
+    vector unsigned char extractPermM = extractPerm
+
+#define F2(i, j, k, l)                                                  \
+    if (S[i] & (1 << (l+1))) {                                          \
+        const vector unsigned char a_A = vec_perm(src##i, src##j, permA1M); \
+        const vector unsigned char a_B = vec_perm(a_A, src##k, permA2M); \
+        const vector signed int a_sump =                                \
+            (vector signed int)vec_msum(a_B, magic, (vector unsigned int)zero);\
+        vector signed int F = vec_sr(vec_sums(a_sump, vsint32_8), vuint32_4); \
+        const vector signed int p =                                     \
+            (vector signed int)vec_perm(src##j, (vector unsigned char)zero, \
+                                        extractPermM);                  \
+        const vector signed int sum  = vec_add(p, vQP2);                \
+        const vector signed int diff = vec_sub(p, vQP2);                \
+        vector signed int newpm;                                        \
+        vector unsigned char newpm2, mask;                              \
+        F = vec_splat(F, 3);                                            \
+        if (vec_all_lt(sum, F))                                         \
+            newpm = sum;                                                \
+        else if (vec_all_gt(diff, F))                                   \
+            newpm = diff;                                               \
+        else newpm = F;                                                 \
+        newpm2 = vec_splat((vector unsigned char)newpm, 15);            \
+        mask = vec_add(identity, tenRightM);                            \
+        src##j = vec_perm(src##j, newpm2, mask);                        \
+    }                                                                   \
+    permA1M = vec_add(permA1M, permA1inc);                              \
+    permA2M = vec_add(permA2M, permA2inc);                              \
+    tenRightM = vec_sro(tenRightM, eightLeft);                          \
+    extractPermM = vec_add(extractPermM, extractPermInc)
+
+#define ITER(i, j, k) do {                      \
+    F_INIT();                                   \
+    F2(i, j, k, 0);                             \
+    F2(i, j, k, 1);                             \
+    F2(i, j, k, 2);                             \
+    F2(i, j, k, 3);                             \
+    F2(i, j, k, 4);                             \
+    F2(i, j, k, 5);                             \
+    F2(i, j, k, 6);                             \
+    F2(i, j, k, 7);                             \
+} while (0)
+
+    ITER(0, 1, 2);
+    ITER(1, 2, 3);
+    ITER(2, 3, 4);
+    ITER(3, 4, 5);
+    ITER(4, 5, 6);
+    ITER(5, 6, 7);
+    ITER(6, 7, 8);
+    ITER(7, 8, 9);
+
+#define STORE_LINE(i) do {                              \
+    const vector unsigned char permST =                 \
+        vec_lvsr(i * stride, srcCopy);                  \
+    const vector unsigned char maskST =                 \
+        vec_perm((vector unsigned char)zero,            \
+                 (vector unsigned char)neg1, permST);   \
+    src##i = vec_perm(src##i ,src##i, permST);          \
+    sA##i= vec_sel(sA##i, src##i, maskST);              \
+    sB##i= vec_sel(src##i, sB##i, maskST);              \
+    vec_st(sA##i, i * stride, srcCopy);                 \
+    vec_st(sB##i, i * stride + 16, srcCopy);            \
+} while (0)
+
+    STORE_LINE(1);
+    STORE_LINE(2);
+    STORE_LINE(3);
+    STORE_LINE(4);
+    STORE_LINE(5);
+    STORE_LINE(6);
+    STORE_LINE(7);
+    STORE_LINE(8);
+
+#undef STORE_LINE
+#undef ITER
+#undef F2
+}
+
+#define doHorizLowPass_altivec(a...) doHorizLowPass_C(a)
+#define doHorizDefFilter_altivec(a...) doHorizDefFilter_C(a)
+#define do_a_deblock_altivec(a...) do_a_deblock_C(a)
+
+static inline void RENAME(tempNoiseReducer)(uint8_t *src, int stride,
+                                            uint8_t *tempBlurred, uint32_t *tempBlurredPast, int *maxNoise)
+{
+    const vector signed char neg1 = vec_splat_s8(-1);
+    const vector unsigned char permHH = (const vector unsigned char){0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+                                                                     0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
+
+    const vector signed int zero = vec_splat_s32(0);
+    const vector signed short vsint16_1 = vec_splat_s16(1);
+    vector signed int v_dp = zero;
+    vector signed int v_sysdp = zero;
+    int d, sysd, i;
+
+#define LOAD_LINE(src, i)                                               \
+    register int j##src##i = i * stride;                                \
+    vector unsigned char perm##src##i = vec_lvsl(j##src##i, src);       \
+    const vector unsigned char v_##src##A1##i = vec_ld(j##src##i, src); \
+    const vector unsigned char v_##src##A2##i = vec_ld(j##src##i + 16, src); \
+    const vector unsigned char v_##src##A##i =                          \
+        vec_perm(v_##src##A1##i, v_##src##A2##i, perm##src##i);         \
+    vector signed short v_##src##Ass##i =                               \
+        (vector signed short)vec_mergeh((vector signed char)zero,       \
+                                        (vector signed char)v_##src##A##i)
+
+    LOAD_LINE(src, 0);
+    LOAD_LINE(src, 1);
+    LOAD_LINE(src, 2);
+    LOAD_LINE(src, 3);
+    LOAD_LINE(src, 4);
+    LOAD_LINE(src, 5);
+    LOAD_LINE(src, 6);
+    LOAD_LINE(src, 7);
+
+    LOAD_LINE(tempBlurred, 0);
+    LOAD_LINE(tempBlurred, 1);
+    LOAD_LINE(tempBlurred, 2);
+    LOAD_LINE(tempBlurred, 3);
+    LOAD_LINE(tempBlurred, 4);
+    LOAD_LINE(tempBlurred, 5);
+    LOAD_LINE(tempBlurred, 6);
+    LOAD_LINE(tempBlurred, 7);
+#undef LOAD_LINE
+
+#define ACCUMULATE_DIFFS(i) do {                                \
+        vector signed short v_d = vec_sub(v_tempBlurredAss##i,  \
+                                          v_srcAss##i);         \
+        v_dp = vec_msums(v_d, v_d, v_dp);                       \
+        v_sysdp = vec_msums(v_d, vsint16_1, v_sysdp);           \
+    } while (0)
+
+    ACCUMULATE_DIFFS(0);
+    ACCUMULATE_DIFFS(1);
+    ACCUMULATE_DIFFS(2);
+    ACCUMULATE_DIFFS(3);
+    ACCUMULATE_DIFFS(4);
+    ACCUMULATE_DIFFS(5);
+    ACCUMULATE_DIFFS(6);
+    ACCUMULATE_DIFFS(7);
+#undef ACCUMULATE_DIFFS
+
+    tempBlurredPast[127]= maxNoise[0];
+    tempBlurredPast[128]= maxNoise[1];
+    tempBlurredPast[129]= maxNoise[2];
+
+    v_dp = vec_sums(v_dp, zero);
+    v_sysdp = vec_sums(v_sysdp, zero);
+
+    v_dp = vec_splat(v_dp, 3);
+    v_sysdp = vec_splat(v_sysdp, 3);
+
+    vec_ste(v_dp, 0, &d);
+    vec_ste(v_sysdp, 0, &sysd);
+
+    i = d;
+    d = (4*d
+         +(*(tempBlurredPast-256))
+         +(*(tempBlurredPast-1))+ (*(tempBlurredPast+1))
+         +(*(tempBlurredPast+256))
+         +4)>>3;
+
+    *tempBlurredPast=i;
+
+    if (d > maxNoise[1]) {
+        if (d < maxNoise[2]) {
+#define OP(i) v_tempBlurredAss##i = vec_avg(v_tempBlurredAss##i, v_srcAss##i);
+
+            OP(0);
+            OP(1);
+            OP(2);
+            OP(3);
+            OP(4);
+            OP(5);
+            OP(6);
+            OP(7);
+#undef OP
+        } else {
+#define OP(i) v_tempBlurredAss##i = v_srcAss##i;
+
+            OP(0);
+            OP(1);
+            OP(2);
+            OP(3);
+            OP(4);
+            OP(5);
+            OP(6);
+            OP(7);
+#undef OP
+        }
+    } else {
+        if (d < maxNoise[0]) {
+            const vector signed short vsint16_7 = vec_splat_s16(7);
+            const vector signed short vsint16_4 = vec_splat_s16(4);
+            const vector unsigned short vuint16_3 = vec_splat_u16(3);
+
+#define OP(i) do {                                                      \
+            const vector signed short v_temp =                          \
+                vec_mladd(v_tempBlurredAss##i, vsint16_7, v_srcAss##i); \
+            const vector signed short v_temp2 = vec_add(v_temp, vsint16_4); \
+            v_tempBlurredAss##i = vec_sr(v_temp2, vuint16_3);           \
+        } while (0)
+
+            OP(0);
+            OP(1);
+            OP(2);
+            OP(3);
+            OP(4);
+            OP(5);
+            OP(6);
+            OP(7);
+#undef OP
+        } else {
+            const vector signed short vsint16_3 = vec_splat_s16(3);
+            const vector signed short vsint16_2 = vec_splat_s16(2);
+
+#define OP(i) do {                                              \
+            const vector signed short v_temp =                  \
+                vec_mladd(v_tempBlurredAss##i, vsint16_3, v_srcAss##i); \
+            const vector signed short v_temp2 = vec_add(v_temp, vsint16_2); \
+            v_tempBlurredAss##i =                                       \
+                vec_sr(v_temp2, (vector unsigned short)vsint16_2);      \
+        } while (0)
+
+            OP(0);
+            OP(1);
+            OP(2);
+            OP(3);
+            OP(4);
+            OP(5);
+            OP(6);
+            OP(7);
+#undef OP
+        }
+    }
+
+#define PACK_AND_STORE(src, i) do {                                      \
+    const vector unsigned char perms = vec_lvsr(i * stride, src);        \
+    const vector unsigned char vf =                                      \
+        vec_packsu(v_tempBlurredAss##1, (vector signed short)zero);     \
+    const vector unsigned char vg = vec_perm(vf, v_##src##A##i, permHH); \
+    const vector unsigned char mask =                                    \
+        vec_perm((vector unsigned char)zero, (vector unsigned char)neg1, perms); \
+    const vector unsigned char vg2 = vec_perm(vg, vg, perms);            \
+    const vector unsigned char svA = vec_sel(v_##src##A1##i, vg2, mask); \
+    const vector unsigned char svB = vec_sel(vg2, v_##src##A2##i, mask); \
+    vec_st(svA, i * stride, src);                                        \
+    vec_st(svB, i * stride + 16, src);                                   \
+} while (0)
+
+    PACK_AND_STORE(src, 0);
+    PACK_AND_STORE(src, 1);
+    PACK_AND_STORE(src, 2);
+    PACK_AND_STORE(src, 3);
+    PACK_AND_STORE(src, 4);
+    PACK_AND_STORE(src, 5);
+    PACK_AND_STORE(src, 6);
+    PACK_AND_STORE(src, 7);
+    PACK_AND_STORE(tempBlurred, 0);
+    PACK_AND_STORE(tempBlurred, 1);
+    PACK_AND_STORE(tempBlurred, 2);
+    PACK_AND_STORE(tempBlurred, 3);
+    PACK_AND_STORE(tempBlurred, 4);
+    PACK_AND_STORE(tempBlurred, 5);
+    PACK_AND_STORE(tempBlurred, 6);
+    PACK_AND_STORE(tempBlurred, 7);
+#undef PACK_AND_STORE
+}
+
+static inline void transpose_16x8_char_toPackedAlign_altivec(unsigned char* dst, unsigned char* src, int stride) {
+    const vector unsigned char zero = vec_splat_u8(0);
+
+#define LOAD_DOUBLE_LINE(i, j)                                          \
+    vector unsigned char perm1##i = vec_lvsl(i * stride, src);          \
+    vector unsigned char perm2##i = vec_lvsl(j * stride, src);          \
+    vector unsigned char srcA##i = vec_ld(i * stride, src);             \
+    vector unsigned char srcB##i = vec_ld(i * stride + 16, src);        \
+    vector unsigned char srcC##i = vec_ld(j * stride, src);             \
+    vector unsigned char srcD##i = vec_ld(j * stride+ 16, src);         \
+    vector unsigned char src##i = vec_perm(srcA##i, srcB##i, perm1##i); \
+    vector unsigned char src##j = vec_perm(srcC##i, srcD##i, perm2##i)
+
+    LOAD_DOUBLE_LINE(0, 1);
+    LOAD_DOUBLE_LINE(2, 3);
+    LOAD_DOUBLE_LINE(4, 5);
+    LOAD_DOUBLE_LINE(6, 7);
+#undef LOAD_DOUBLE_LINE
+
+    vector unsigned char tempA = vec_mergeh(src0, zero);
+    vector unsigned char tempB = vec_mergel(src0, zero);
+    vector unsigned char tempC = vec_mergeh(src1, zero);
+    vector unsigned char tempD = vec_mergel(src1, zero);
+    vector unsigned char tempE = vec_mergeh(src2, zero);
+    vector unsigned char tempF = vec_mergel(src2, zero);
+    vector unsigned char tempG = vec_mergeh(src3, zero);
+    vector unsigned char tempH = vec_mergel(src3, zero);
+    vector unsigned char tempI = vec_mergeh(src4, zero);
+    vector unsigned char tempJ = vec_mergel(src4, zero);
+    vector unsigned char tempK = vec_mergeh(src5, zero);
+    vector unsigned char tempL = vec_mergel(src5, zero);
+    vector unsigned char tempM = vec_mergeh(src6, zero);
+    vector unsigned char tempN = vec_mergel(src6, zero);
+    vector unsigned char tempO = vec_mergeh(src7, zero);
+    vector unsigned char tempP = vec_mergel(src7, zero);
+
+    vector unsigned char temp0  = vec_mergeh(tempA, tempI);
+    vector unsigned char temp1  = vec_mergel(tempA, tempI);
+    vector unsigned char temp2  = vec_mergeh(tempB, tempJ);
+    vector unsigned char temp3  = vec_mergel(tempB, tempJ);
+    vector unsigned char temp4  = vec_mergeh(tempC, tempK);
+    vector unsigned char temp5  = vec_mergel(tempC, tempK);
+    vector unsigned char temp6  = vec_mergeh(tempD, tempL);
+    vector unsigned char temp7  = vec_mergel(tempD, tempL);
+    vector unsigned char temp8  = vec_mergeh(tempE, tempM);
+    vector unsigned char temp9  = vec_mergel(tempE, tempM);
+    vector unsigned char temp10 = vec_mergeh(tempF, tempN);
+    vector unsigned char temp11 = vec_mergel(tempF, tempN);
+    vector unsigned char temp12 = vec_mergeh(tempG, tempO);
+    vector unsigned char temp13 = vec_mergel(tempG, tempO);
+    vector unsigned char temp14 = vec_mergeh(tempH, tempP);
+    vector unsigned char temp15 = vec_mergel(tempH, tempP);
+
+    tempA = vec_mergeh(temp0, temp8);
+    tempB = vec_mergel(temp0, temp8);
+    tempC = vec_mergeh(temp1, temp9);
+    tempD = vec_mergel(temp1, temp9);
+    tempE = vec_mergeh(temp2, temp10);
+    tempF = vec_mergel(temp2, temp10);
+    tempG = vec_mergeh(temp3, temp11);
+    tempH = vec_mergel(temp3, temp11);
+    tempI = vec_mergeh(temp4, temp12);
+    tempJ = vec_mergel(temp4, temp12);
+    tempK = vec_mergeh(temp5, temp13);
+    tempL = vec_mergel(temp5, temp13);
+    tempM = vec_mergeh(temp6, temp14);
+    tempN = vec_mergel(temp6, temp14);
+    tempO = vec_mergeh(temp7, temp15);
+    tempP = vec_mergel(temp7, temp15);
+
+    temp0  = vec_mergeh(tempA, tempI);
+    temp1  = vec_mergel(tempA, tempI);
+    temp2  = vec_mergeh(tempB, tempJ);
+    temp3  = vec_mergel(tempB, tempJ);
+    temp4  = vec_mergeh(tempC, tempK);
+    temp5  = vec_mergel(tempC, tempK);
+    temp6  = vec_mergeh(tempD, tempL);
+    temp7  = vec_mergel(tempD, tempL);
+    temp8  = vec_mergeh(tempE, tempM);
+    temp9  = vec_mergel(tempE, tempM);
+    temp10 = vec_mergeh(tempF, tempN);
+    temp11 = vec_mergel(tempF, tempN);
+    temp12 = vec_mergeh(tempG, tempO);
+    temp13 = vec_mergel(tempG, tempO);
+    temp14 = vec_mergeh(tempH, tempP);
+    temp15 = vec_mergel(tempH, tempP);
+
+    vec_st(temp0,    0, dst);
+    vec_st(temp1,   16, dst);
+    vec_st(temp2,   32, dst);
+    vec_st(temp3,   48, dst);
+    vec_st(temp4,   64, dst);
+    vec_st(temp5,   80, dst);
+    vec_st(temp6,   96, dst);
+    vec_st(temp7,  112, dst);
+    vec_st(temp8,  128, dst);
+    vec_st(temp9,  144, dst);
+    vec_st(temp10, 160, dst);
+    vec_st(temp11, 176, dst);
+    vec_st(temp12, 192, dst);
+    vec_st(temp13, 208, dst);
+    vec_st(temp14, 224, dst);
+    vec_st(temp15, 240, dst);
+}
+
+static inline void transpose_8x16_char_fromPackedAlign_altivec(unsigned char* dst, unsigned char* src, int stride) {
+    const vector unsigned char zero = vec_splat_u8(0);
+    const vector signed   char neg1 = vec_splat_s8(-1);
+
+#define LOAD_DOUBLE_LINE(i, j)                                  \
+    vector unsigned char src##i = vec_ld(i * 16, src);            \
+    vector unsigned char src##j = vec_ld(j * 16, src)
+
+    LOAD_DOUBLE_LINE(0, 1);
+    LOAD_DOUBLE_LINE(2, 3);
+    LOAD_DOUBLE_LINE(4, 5);
+    LOAD_DOUBLE_LINE(6, 7);
+    LOAD_DOUBLE_LINE(8, 9);
+    LOAD_DOUBLE_LINE(10, 11);
+    LOAD_DOUBLE_LINE(12, 13);
+    LOAD_DOUBLE_LINE(14, 15);
+#undef LOAD_DOUBLE_LINE
+
+    vector unsigned char tempA = vec_mergeh(src0, src8);
+    vector unsigned char tempB;
+    vector unsigned char tempC = vec_mergeh(src1, src9);
+    vector unsigned char tempD;
+    vector unsigned char tempE = vec_mergeh(src2, src10);
+    vector unsigned char tempG = vec_mergeh(src3, src11);
+    vector unsigned char tempI = vec_mergeh(src4, src12);
+    vector unsigned char tempJ;
+    vector unsigned char tempK = vec_mergeh(src5, src13);
+    vector unsigned char tempL;
+    vector unsigned char tempM = vec_mergeh(src6, src14);
+    vector unsigned char tempO = vec_mergeh(src7, src15);
+
+    vector unsigned char temp0 = vec_mergeh(tempA, tempI);
+    vector unsigned char temp1 = vec_mergel(tempA, tempI);
+    vector unsigned char temp2;
+    vector unsigned char temp3;
+    vector unsigned char temp4 = vec_mergeh(tempC, tempK);
+    vector unsigned char temp5 = vec_mergel(tempC, tempK);
+    vector unsigned char temp6;
+    vector unsigned char temp7;
+    vector unsigned char temp8 = vec_mergeh(tempE, tempM);
+    vector unsigned char temp9 = vec_mergel(tempE, tempM);
+    vector unsigned char temp12 = vec_mergeh(tempG, tempO);
+    vector unsigned char temp13 = vec_mergel(tempG, tempO);
+
+    tempA = vec_mergeh(temp0, temp8);
+    tempB = vec_mergel(temp0, temp8);
+    tempC = vec_mergeh(temp1, temp9);
+    tempD = vec_mergel(temp1, temp9);
+    tempI = vec_mergeh(temp4, temp12);
+    tempJ = vec_mergel(temp4, temp12);
+    tempK = vec_mergeh(temp5, temp13);
+    tempL = vec_mergel(temp5, temp13);
+
+    temp0 = vec_mergeh(tempA, tempI);
+    temp1 = vec_mergel(tempA, tempI);
+    temp2 = vec_mergeh(tempB, tempJ);
+    temp3 = vec_mergel(tempB, tempJ);
+    temp4 = vec_mergeh(tempC, tempK);
+    temp5 = vec_mergel(tempC, tempK);
+    temp6 = vec_mergeh(tempD, tempL);
+    temp7 = vec_mergel(tempD, tempL);
+
+
+#define STORE_DOUBLE_LINE(i, j) do {                                    \
+    vector unsigned char dstAi = vec_ld(i * stride, dst);               \
+    vector unsigned char dstBi = vec_ld(i * stride + 16, dst);          \
+    vector unsigned char dstAj = vec_ld(j * stride, dst);               \
+    vector unsigned char dstBj = vec_ld(j * stride+ 16, dst);           \
+    vector unsigned char aligni = vec_lvsr(i * stride, dst);            \
+    vector unsigned char alignj = vec_lvsr(j * stride, dst);            \
+    vector unsigned char maski =                                        \
+        vec_perm(zero, (vector unsigned char)neg1, aligni);             \
+    vector unsigned char maskj =                                        \
+        vec_perm(zero, (vector unsigned char)neg1, alignj);             \
+    vector unsigned char dstRi = vec_perm(temp##i, temp##i, aligni);    \
+    vector unsigned char dstRj = vec_perm(temp##j, temp##j, alignj);    \
+    vector unsigned char dstAFi = vec_sel(dstAi, dstRi, maski);         \
+    vector unsigned char dstBFi = vec_sel(dstRi, dstBi, maski);         \
+    vector unsigned char dstAFj = vec_sel(dstAj, dstRj, maskj);         \
+    vector unsigned char dstBFj = vec_sel(dstRj, dstBj, maskj);         \
+    vec_st(dstAFi, i * stride, dst);                                    \
+    vec_st(dstBFi, i * stride + 16, dst);                               \
+    vec_st(dstAFj, j * stride, dst);                                    \
+    vec_st(dstBFj, j * stride + 16, dst);                               \
+} while (0)
+
+    STORE_DOUBLE_LINE(0,1);
+    STORE_DOUBLE_LINE(2,3);
+    STORE_DOUBLE_LINE(4,5);
+    STORE_DOUBLE_LINE(6,7);
+}
diff --git a/libpostproc/postprocess_internal.h b/libpostproc/postprocess_internal.h
new file mode 100644
index 0000000..33c5f69
--- /dev/null
+++ b/libpostproc/postprocess_internal.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2001-2002 Michael Niedermayer (michaelni@gmx.at)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * internal api header.
+ */
+
+#ifndef POSTPROC_POSTPROCESS_INTERNAL_H
+#define POSTPROC_POSTPROCESS_INTERNAL_H
+
+#include <string.h>
+#include "libavutil/avutil.h"
+#include "libavutil/log.h"
+#include "postprocess.h"
+
+#define V_DEBLOCK       0x01
+#define H_DEBLOCK       0x02
+#define DERING          0x04
+#define LEVEL_FIX       0x08 ///< Brightness & Contrast
+
+#define LUM_V_DEBLOCK   V_DEBLOCK               //   1
+#define LUM_H_DEBLOCK   H_DEBLOCK               //   2
+#define CHROM_V_DEBLOCK (V_DEBLOCK<<4)          //  16
+#define CHROM_H_DEBLOCK (H_DEBLOCK<<4)          //  32
+#define LUM_DERING      DERING                  //   4
+#define CHROM_DERING    (DERING<<4)             //  64
+#define LUM_LEVEL_FIX   LEVEL_FIX               //   8
+#define CHROM_LEVEL_FIX (LEVEL_FIX<<4)          // 128 (not implemented yet)
+
+// Experimental vertical filters
+#define V_X1_FILTER     0x0200                  // 512
+#define V_A_DEBLOCK     0x0400
+
+// Experimental horizontal filters
+#define H_X1_FILTER     0x2000                  // 8192
+#define H_A_DEBLOCK     0x4000
+
+/// select between full y range (255-0) or standart one (234-16)
+#define FULL_Y_RANGE    0x8000                  // 32768
+
+//Deinterlacing Filters
+#define LINEAR_IPOL_DEINT_FILTER        0x10000 // 65536
+#define LINEAR_BLEND_DEINT_FILTER       0x20000 // 131072
+#define CUBIC_BLEND_DEINT_FILTER        0x8000  // (not implemented yet)
+#define CUBIC_IPOL_DEINT_FILTER         0x40000 // 262144
+#define MEDIAN_DEINT_FILTER             0x80000 // 524288
+#define FFMPEG_DEINT_FILTER             0x400000
+#define LOWPASS5_DEINT_FILTER           0x800000
+
+#define TEMP_NOISE_FILTER               0x100000
+#define FORCE_QUANT                     0x200000
+#define BITEXACT                        0x1000000
+
+//use if you want a faster postprocessing code
+//cannot differentiate between chroma & luma filters (both on or both off)
+//obviously the -pp option on the command line has no effect except turning the here selected
+//filters on
+//#define COMPILE_TIME_MODE 0x77
+
+static inline int CLIP(int a){
+    if(a&256) return ((a)>>31)^(-1);
+    else      return a;
+}
+/**
+ * Postprocessng filter.
+ */
+struct PPFilter{
+    const char *shortName;
+    const char *longName;
+    int chromDefault;       ///< is chrominance filtering on by default if this filter is manually activated
+    int minLumQuality;      ///< minimum quality to turn luminance filtering on
+    int minChromQuality;    ///< minimum quality to turn chrominance filtering on
+    int mask;               ///< Bitmask to turn this filter on
+};
+
+/**
+ * Postprocessng mode.
+ */
+typedef struct PPMode{
+    int lumMode;                    ///< acivates filters for luminance
+    int chromMode;                  ///< acivates filters for chrominance
+    int error;                      ///< non zero on error
+
+    int minAllowedY;                ///< for brigtness correction
+    int maxAllowedY;                ///< for brihtness correction
+    float maxClippedThreshold;      ///< amount of "black" you are willing to lose to get a brightness-corrected picture
+
+    int maxTmpNoise[3];             ///< for Temporal Noise Reducing filter (Maximal sum of abs differences)
+
+    int baseDcDiff;
+    int flatnessThreshold;
+
+    int forcedQuant;                ///< quantizer if FORCE_QUANT is used
+} PPMode;
+
+/**
+ * postprocess context.
+ */
+typedef struct PPContext{
+    /**
+     * info on struct for av_log
+     */
+    const AVClass *av_class;
+
+    uint8_t *tempBlocks; ///<used for the horizontal code
+
+    /**
+     * luma histogram.
+     * we need 64bit here otherwise we'll going to have a problem
+     * after watching a black picture for 5 hours
+     */
+    uint64_t *yHistogram;
+
+    DECLARE_ALIGNED(8, uint64_t, packedYOffset);
+    DECLARE_ALIGNED(8, uint64_t, packedYScale);
+
+    /** Temporal noise reducing buffers */
+    uint8_t *tempBlurred[3];
+    int32_t *tempBlurredPast[3];
+
+    /** Temporary buffers for handling the last row(s) */
+    uint8_t *tempDst;
+    uint8_t *tempSrc;
+
+    uint8_t *deintTemp;
+
+    DECLARE_ALIGNED(8, uint64_t, pQPb);
+    DECLARE_ALIGNED(8, uint64_t, pQPb2);
+
+    DECLARE_ALIGNED(8, uint64_t, mmxDcOffset)[64];
+    DECLARE_ALIGNED(8, uint64_t, mmxDcThreshold)[64];
+
+    QP_STORE_T *stdQPTable;       ///< used to fix MPEG2 style qscale
+    QP_STORE_T *nonBQPTable;
+    QP_STORE_T *forcedQPTable;
+
+    int QP;
+    int nonBQP;
+
+    int frameNum;
+
+    int cpuCaps;
+
+    int qpStride; ///<size of qp buffers (needed to realloc them if needed)
+    int stride;   ///<size of some buffers (needed to realloc them if needed)
+
+    int hChromaSubSample;
+    int vChromaSubSample;
+
+    PPMode ppMode;
+} PPContext;
+
+
+static inline void linecpy(void *dest, const void *src, int lines, int stride) {
+    if (stride > 0) {
+        memcpy(dest, src, lines*stride);
+    } else {
+        memcpy((uint8_t*)dest+(lines-1)*stride, (const uint8_t*)src+(lines-1)*stride, -lines*stride);
+    }
+}
+
+#endif /* POSTPROC_POSTPROCESS_INTERNAL_H */
diff --git a/libpostproc/postprocess_template.c b/libpostproc/postprocess_template.c
new file mode 100644
index 0000000..e1a3977
--- /dev/null
+++ b/libpostproc/postprocess_template.c
@@ -0,0 +1,3631 @@
+/*
+ * Copyright (C) 2001-2002 Michael Niedermayer (michaelni@gmx.at)
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * mmx/mmx2/3dnow postprocess code.
+ */
+
+#include "libavutil/x86/asm.h"
+
+#undef REAL_PAVGB
+#undef PAVGB
+#undef PMINUB
+#undef PMAXUB
+
+#if   HAVE_MMXEXT_INLINE
+#define REAL_PAVGB(a,b) "pavgb " #a ", " #b " \n\t"
+#elif HAVE_AMD3DNOW_INLINE
+#define REAL_PAVGB(a,b) "pavgusb " #a ", " #b " \n\t"
+#endif
+#define PAVGB(a,b)  REAL_PAVGB(a,b)
+
+#if   HAVE_MMXEXT_INLINE
+#define PMINUB(a,b,t) "pminub " #a ", " #b " \n\t"
+#elif HAVE_MMX_INLINE
+#define PMINUB(b,a,t) \
+    "movq " #a ", " #t " \n\t"\
+    "psubusb " #b ", " #t " \n\t"\
+    "psubb " #t ", " #a " \n\t"
+#endif
+
+#if   HAVE_MMXEXT_INLINE
+#define PMAXUB(a,b) "pmaxub " #a ", " #b " \n\t"
+#elif HAVE_MMX_INLINE
+#define PMAXUB(a,b) \
+    "psubusb " #a ", " #b " \n\t"\
+    "paddb " #a ", " #b " \n\t"
+#endif
+
+//FIXME? |255-0| = 1 (should not be a problem ...)
+#if HAVE_MMX_INLINE
+/**
+ * Check if the middle 8x8 Block in the given 8x16 block is flat
+ */
+static inline int RENAME(vertClassify)(uint8_t src[], int stride, PPContext *c){
+    int numEq= 0, dcOk;
+    src+= stride*4; // src points to begin of the 8x8 Block
+    __asm__ volatile(
+        "movq %0, %%mm7                         \n\t"
+        "movq %1, %%mm6                         \n\t"
+        : : "m" (c->mmxDcOffset[c->nonBQP]),  "m" (c->mmxDcThreshold[c->nonBQP])
+        );
+
+    __asm__ volatile(
+        "lea (%2, %3), %%"REG_a"                \n\t"
+//      0       1       2       3       4       5       6       7       8       9
+//      %1      eax     eax+%2  eax+2%2 %1+4%2  ecx     ecx+%2  ecx+2%2 %1+8%2  ecx+4%2
+
+        "movq (%2), %%mm0                       \n\t"
+        "movq (%%"REG_a"), %%mm1                \n\t"
+        "movq %%mm0, %%mm3                      \n\t"
+        "movq %%mm0, %%mm4                      \n\t"
+        PMAXUB(%%mm1, %%mm4)
+        PMINUB(%%mm1, %%mm3, %%mm5)
+        "psubb %%mm1, %%mm0                     \n\t" // mm0 = differnece
+        "paddb %%mm7, %%mm0                     \n\t"
+        "pcmpgtb %%mm6, %%mm0                   \n\t"
+
+        "movq (%%"REG_a",%3), %%mm2             \n\t"
+        PMAXUB(%%mm2, %%mm4)
+        PMINUB(%%mm2, %%mm3, %%mm5)
+        "psubb %%mm2, %%mm1                     \n\t"
+        "paddb %%mm7, %%mm1                     \n\t"
+        "pcmpgtb %%mm6, %%mm1                   \n\t"
+        "paddb %%mm1, %%mm0                     \n\t"
+
+        "movq (%%"REG_a", %3, 2), %%mm1         \n\t"
+        PMAXUB(%%mm1, %%mm4)
+        PMINUB(%%mm1, %%mm3, %%mm5)
+        "psubb %%mm1, %%mm2                     \n\t"
+        "paddb %%mm7, %%mm2                     \n\t"
+        "pcmpgtb %%mm6, %%mm2                   \n\t"
+        "paddb %%mm2, %%mm0                     \n\t"
+
+        "lea (%%"REG_a", %3, 4), %%"REG_a"      \n\t"
+
+        "movq (%2, %3, 4), %%mm2                \n\t"
+        PMAXUB(%%mm2, %%mm4)
+        PMINUB(%%mm2, %%mm3, %%mm5)
+        "psubb %%mm2, %%mm1                     \n\t"
+        "paddb %%mm7, %%mm1                     \n\t"
+        "pcmpgtb %%mm6, %%mm1                   \n\t"
+        "paddb %%mm1, %%mm0                     \n\t"
+
+        "movq (%%"REG_a"), %%mm1                \n\t"
+        PMAXUB(%%mm1, %%mm4)
+        PMINUB(%%mm1, %%mm3, %%mm5)
+        "psubb %%mm1, %%mm2                     \n\t"
+        "paddb %%mm7, %%mm2                     \n\t"
+        "pcmpgtb %%mm6, %%mm2                   \n\t"
+        "paddb %%mm2, %%mm0                     \n\t"
+
+        "movq (%%"REG_a", %3), %%mm2            \n\t"
+        PMAXUB(%%mm2, %%mm4)
+        PMINUB(%%mm2, %%mm3, %%mm5)
+        "psubb %%mm2, %%mm1                     \n\t"
+        "paddb %%mm7, %%mm1                     \n\t"
+        "pcmpgtb %%mm6, %%mm1                   \n\t"
+        "paddb %%mm1, %%mm0                     \n\t"
+
+        "movq (%%"REG_a", %3, 2), %%mm1         \n\t"
+        PMAXUB(%%mm1, %%mm4)
+        PMINUB(%%mm1, %%mm3, %%mm5)
+        "psubb %%mm1, %%mm2                     \n\t"
+        "paddb %%mm7, %%mm2                     \n\t"
+        "pcmpgtb %%mm6, %%mm2                   \n\t"
+        "paddb %%mm2, %%mm0                     \n\t"
+        "psubusb %%mm3, %%mm4                   \n\t"
+
+        "                                       \n\t"
+#if HAVE_MMXEXT_INLINE
+        "pxor %%mm7, %%mm7                      \n\t"
+        "psadbw %%mm7, %%mm0                    \n\t"
+#else
+        "movq %%mm0, %%mm1                      \n\t"
+        "psrlw $8, %%mm0                        \n\t"
+        "paddb %%mm1, %%mm0                     \n\t"
+        "movq %%mm0, %%mm1                      \n\t"
+        "psrlq $16, %%mm0                       \n\t"
+        "paddb %%mm1, %%mm0                     \n\t"
+        "movq %%mm0, %%mm1                      \n\t"
+        "psrlq $32, %%mm0                       \n\t"
+        "paddb %%mm1, %%mm0                     \n\t"
+#endif
+        "movq %4, %%mm7                         \n\t" // QP,..., QP
+        "paddusb %%mm7, %%mm7                   \n\t" // 2QP ... 2QP
+        "psubusb %%mm7, %%mm4                   \n\t" // Diff <= 2QP -> 0
+        "packssdw %%mm4, %%mm4                  \n\t"
+        "movd %%mm0, %0                         \n\t"
+        "movd %%mm4, %1                         \n\t"
+
+        : "=r" (numEq), "=r" (dcOk)
+        : "r" (src), "r" ((x86_reg)stride), "m" (c->pQPb)
+        : "%"REG_a
+        );
+
+    numEq= (-numEq) &0xFF;
+    if(numEq > c->ppMode.flatnessThreshold){
+        if(dcOk) return 0;
+        else     return 1;
+    }else{
+        return 2;
+    }
+}
+#endif //HAVE_MMX_INLINE
+
+/**
+ * Do a vertical low pass filter on the 8x16 block (only write to the 8x8 block in the middle)
+ * using the 9-Tap Filter (1,1,2,2,4,2,2,1,1)/16
+ */
+#if !HAVE_ALTIVEC
+static inline void RENAME(doVertLowPass)(uint8_t *src, int stride, PPContext *c)
+{
+#if HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    src+= stride*3;
+    __asm__ volatile(        //"movv %0 %1 %2\n\t"
+        "movq %2, %%mm0                         \n\t"  // QP,..., QP
+        "pxor %%mm4, %%mm4                      \n\t"
+
+        "movq (%0), %%mm6                       \n\t"
+        "movq (%0, %1), %%mm5                   \n\t"
+        "movq %%mm5, %%mm1                      \n\t"
+        "movq %%mm6, %%mm2                      \n\t"
+        "psubusb %%mm6, %%mm5                   \n\t"
+        "psubusb %%mm1, %%mm2                   \n\t"
+        "por %%mm5, %%mm2                       \n\t" // ABS Diff of lines
+        "psubusb %%mm0, %%mm2                   \n\t" // diff <= QP -> 0
+        "pcmpeqb %%mm4, %%mm2                   \n\t" // diff <= QP -> FF
+
+        "pand %%mm2, %%mm6                      \n\t"
+        "pandn %%mm1, %%mm2                     \n\t"
+        "por %%mm2, %%mm6                       \n\t"// First Line to Filter
+
+        "movq (%0, %1, 8), %%mm5                \n\t"
+        "lea (%0, %1, 4), %%"REG_a"             \n\t"
+        "lea (%0, %1, 8), %%"REG_c"             \n\t"
+        "sub %1, %%"REG_c"                      \n\t"
+        "add %1, %0                             \n\t" // %0 points to line 1 not 0
+        "movq (%0, %1, 8), %%mm7                \n\t"
+        "movq %%mm5, %%mm1                      \n\t"
+        "movq %%mm7, %%mm2                      \n\t"
+        "psubusb %%mm7, %%mm5                   \n\t"
+        "psubusb %%mm1, %%mm2                   \n\t"
+        "por %%mm5, %%mm2                       \n\t" // ABS Diff of lines
+        "psubusb %%mm0, %%mm2                   \n\t" // diff <= QP -> 0
+        "pcmpeqb %%mm4, %%mm2                   \n\t" // diff <= QP -> FF
+
+        "pand %%mm2, %%mm7                      \n\t"
+        "pandn %%mm1, %%mm2                     \n\t"
+        "por %%mm2, %%mm7                       \n\t" // First Line to Filter
+
+
+        //      1       2       3       4       5       6       7       8
+        //      %0      %0+%1   %0+2%1  eax     %0+4%1  eax+2%1 ecx     eax+4%1
+        // 6 4 2 2 1 1
+        // 6 4 4 2
+        // 6 8 2
+
+        "movq (%0, %1), %%mm0                   \n\t" //  1
+        "movq %%mm0, %%mm1                      \n\t" //  1
+        PAVGB(%%mm6, %%mm0)                           //1 1        /2
+        PAVGB(%%mm6, %%mm0)                           //3 1        /4
+
+        "movq (%0, %1, 4), %%mm2                \n\t" //     1
+        "movq %%mm2, %%mm5                      \n\t" //     1
+        PAVGB((%%REGa), %%mm2)                        //    11        /2
+        PAVGB((%0, %1, 2), %%mm2)                     //   211        /4
+        "movq %%mm2, %%mm3                      \n\t" //   211        /4
+        "movq (%0), %%mm4                       \n\t" // 1
+        PAVGB(%%mm4, %%mm3)                           // 4 211        /8
+        PAVGB(%%mm0, %%mm3)                           //642211        /16
+        "movq %%mm3, (%0)                       \n\t" // X
+        // mm1=2 mm2=3(211) mm4=1 mm5=5 mm6=0 mm7=9
+        "movq %%mm1, %%mm0                      \n\t" //  1
+        PAVGB(%%mm6, %%mm0)                           //1 1        /2
+        "movq %%mm4, %%mm3                      \n\t" // 1
+        PAVGB((%0,%1,2), %%mm3)                       // 1 1        /2
+        PAVGB((%%REGa,%1,2), %%mm5)                   //     11        /2
+        PAVGB((%%REGa), %%mm5)                        //    211 /4
+        PAVGB(%%mm5, %%mm3)                           // 2 2211 /8
+        PAVGB(%%mm0, %%mm3)                           //4242211 /16
+        "movq %%mm3, (%0,%1)                    \n\t" //  X
+        // mm1=2 mm2=3(211) mm4=1 mm5=4(211) mm6=0 mm7=9
+        PAVGB(%%mm4, %%mm6)                                   //11        /2
+        "movq (%%"REG_c"), %%mm0                \n\t" //       1
+        PAVGB((%%REGa, %1, 2), %%mm0)                 //      11/2
+        "movq %%mm0, %%mm3                      \n\t" //      11/2
+        PAVGB(%%mm1, %%mm0)                           //  2   11/4
+        PAVGB(%%mm6, %%mm0)                           //222   11/8
+        PAVGB(%%mm2, %%mm0)                           //22242211/16
+        "movq (%0, %1, 2), %%mm2                \n\t" //   1
+        "movq %%mm0, (%0, %1, 2)                \n\t" //   X
+        // mm1=2 mm2=3 mm3=6(11) mm4=1 mm5=4(211) mm6=0(11) mm7=9
+        "movq (%%"REG_a", %1, 4), %%mm0         \n\t" //        1
+        PAVGB((%%REGc), %%mm0)                        //       11        /2
+        PAVGB(%%mm0, %%mm6)                           //11     11        /4
+        PAVGB(%%mm1, %%mm4)                           // 11                /2
+        PAVGB(%%mm2, %%mm1)                           //  11                /2
+        PAVGB(%%mm1, %%mm6)                           //1122   11        /8
+        PAVGB(%%mm5, %%mm6)                           //112242211        /16
+        "movq (%%"REG_a"), %%mm5                \n\t" //    1
+        "movq %%mm6, (%%"REG_a")                \n\t" //    X
+        // mm0=7(11) mm1=2(11) mm2=3 mm3=6(11) mm4=1(11) mm5=4 mm7=9
+        "movq (%%"REG_a", %1, 4), %%mm6         \n\t" //        1
+        PAVGB(%%mm7, %%mm6)                           //        11        /2
+        PAVGB(%%mm4, %%mm6)                           // 11     11        /4
+        PAVGB(%%mm3, %%mm6)                           // 11   2211        /8
+        PAVGB(%%mm5, %%mm2)                           //   11                /2
+        "movq (%0, %1, 4), %%mm4                \n\t" //     1
+        PAVGB(%%mm4, %%mm2)                           //   112                /4
+        PAVGB(%%mm2, %%mm6)                           // 112242211        /16
+        "movq %%mm6, (%0, %1, 4)                \n\t" //     X
+        // mm0=7(11) mm1=2(11) mm2=3(112) mm3=6(11) mm4=5 mm5=4 mm7=9
+        PAVGB(%%mm7, %%mm1)                           //  11     2        /4
+        PAVGB(%%mm4, %%mm5)                           //    11                /2
+        PAVGB(%%mm5, %%mm0)                           //    11 11        /4
+        "movq (%%"REG_a", %1, 2), %%mm6         \n\t" //      1
+        PAVGB(%%mm6, %%mm1)                           //  11  4  2        /8
+        PAVGB(%%mm0, %%mm1)                           //  11224222        /16
+        "movq %%mm1, (%%"REG_a", %1, 2)         \n\t" //      X
+        // mm2=3(112) mm3=6(11) mm4=5 mm5=4(11) mm6=6 mm7=9
+        PAVGB((%%REGc), %%mm2)                        //   112 4        /8
+        "movq (%%"REG_a", %1, 4), %%mm0         \n\t" //        1
+        PAVGB(%%mm0, %%mm6)                           //      1 1        /2
+        PAVGB(%%mm7, %%mm6)                           //      1 12        /4
+        PAVGB(%%mm2, %%mm6)                           //   1122424        /4
+        "movq %%mm6, (%%"REG_c")                \n\t" //       X
+        // mm0=8 mm3=6(11) mm4=5 mm5=4(11) mm7=9
+        PAVGB(%%mm7, %%mm5)                           //    11   2        /4
+        PAVGB(%%mm7, %%mm5)                           //    11   6        /8
+
+        PAVGB(%%mm3, %%mm0)                           //      112        /4
+        PAVGB(%%mm0, %%mm5)                           //    112246        /16
+        "movq %%mm5, (%%"REG_a", %1, 4)         \n\t" //        X
+        "sub %1, %0                             \n\t"
+
+        :
+        : "r" (src), "r" ((x86_reg)stride), "m" (c->pQPb)
+        : "%"REG_a, "%"REG_c
+    );
+#else //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    const int l1= stride;
+    const int l2= stride + l1;
+    const int l3= stride + l2;
+    const int l4= stride + l3;
+    const int l5= stride + l4;
+    const int l6= stride + l5;
+    const int l7= stride + l6;
+    const int l8= stride + l7;
+    const int l9= stride + l8;
+    int x;
+    src+= stride*3;
+    for(x=0; x<BLOCK_SIZE; x++){
+        const int first= FFABS(src[0] - src[l1]) < c->QP ? src[0] : src[l1];
+        const int last= FFABS(src[l8] - src[l9]) < c->QP ? src[l9] : src[l8];
+
+        int sums[10];
+        sums[0] = 4*first + src[l1] + src[l2] + src[l3] + 4;
+        sums[1] = sums[0] - first  + src[l4];
+        sums[2] = sums[1] - first  + src[l5];
+        sums[3] = sums[2] - first  + src[l6];
+        sums[4] = sums[3] - first  + src[l7];
+        sums[5] = sums[4] - src[l1] + src[l8];
+        sums[6] = sums[5] - src[l2] + last;
+        sums[7] = sums[6] - src[l3] + last;
+        sums[8] = sums[7] - src[l4] + last;
+        sums[9] = sums[8] - src[l5] + last;
+
+        src[l1]= (sums[0] + sums[2] + 2*src[l1])>>4;
+        src[l2]= (sums[1] + sums[3] + 2*src[l2])>>4;
+        src[l3]= (sums[2] + sums[4] + 2*src[l3])>>4;
+        src[l4]= (sums[3] + sums[5] + 2*src[l4])>>4;
+        src[l5]= (sums[4] + sums[6] + 2*src[l5])>>4;
+        src[l6]= (sums[5] + sums[7] + 2*src[l6])>>4;
+        src[l7]= (sums[6] + sums[8] + 2*src[l7])>>4;
+        src[l8]= (sums[7] + sums[9] + 2*src[l8])>>4;
+
+        src++;
+    }
+#endif //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+}
+#endif //HAVE_ALTIVEC
+
+/**
+ * Experimental Filter 1
+ * will not damage linear gradients
+ * Flat blocks should look like they were passed through the (1,1,2,2,4,2,2,1,1) 9-Tap filter
+ * can only smooth blocks at the expected locations (it cannot smooth them if they did move)
+ * MMX2 version does correct clipping C version does not
+ */
+static inline void RENAME(vertX1Filter)(uint8_t *src, int stride, PPContext *co)
+{
+#if HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    src+= stride*3;
+
+    __asm__ volatile(
+        "pxor %%mm7, %%mm7                      \n\t" // 0
+        "lea (%0, %1), %%"REG_a"                \n\t"
+        "lea (%%"REG_a", %1, 4), %%"REG_c"      \n\t"
+//      0       1       2       3       4       5       6       7       8       9
+//      %0      eax     eax+%1  eax+2%1 %0+4%1  ecx     ecx+%1  ecx+2%1 %0+8%1  ecx+4%1
+        "movq (%%"REG_a", %1, 2), %%mm0         \n\t" // line 3
+        "movq (%0, %1, 4), %%mm1                \n\t" // line 4
+        "movq %%mm1, %%mm2                      \n\t" // line 4
+        "psubusb %%mm0, %%mm1                   \n\t"
+        "psubusb %%mm2, %%mm0                   \n\t"
+        "por %%mm1, %%mm0                       \n\t" // |l2 - l3|
+        "movq (%%"REG_c"), %%mm3                \n\t" // line 5
+        "movq (%%"REG_c", %1), %%mm4            \n\t" // line 6
+        "movq %%mm3, %%mm5                      \n\t" // line 5
+        "psubusb %%mm4, %%mm3                   \n\t"
+        "psubusb %%mm5, %%mm4                   \n\t"
+        "por %%mm4, %%mm3                       \n\t" // |l5 - l6|
+        PAVGB(%%mm3, %%mm0)                           // (|l2 - l3| + |l5 - l6|)/2
+        "movq %%mm2, %%mm1                      \n\t" // line 4
+        "psubusb %%mm5, %%mm2                   \n\t"
+        "movq %%mm2, %%mm4                      \n\t"
+        "pcmpeqb %%mm7, %%mm2                   \n\t" // (l4 - l5) <= 0 ? -1 : 0
+        "psubusb %%mm1, %%mm5                   \n\t"
+        "por %%mm5, %%mm4                       \n\t" // |l4 - l5|
+        "psubusb %%mm0, %%mm4                   \n\t" //d = MAX(0, |l4-l5| - (|l2-l3| + |l5-l6|)/2)
+        "movq %%mm4, %%mm3                      \n\t" // d
+        "movq %2, %%mm0                         \n\t"
+        "paddusb %%mm0, %%mm0                   \n\t"
+        "psubusb %%mm0, %%mm4                   \n\t"
+        "pcmpeqb %%mm7, %%mm4                   \n\t" // d <= QP ? -1 : 0
+        "psubusb "MANGLE(b01)", %%mm3           \n\t"
+        "pand %%mm4, %%mm3                      \n\t" // d <= QP ? d : 0
+
+        PAVGB(%%mm7, %%mm3)                           // d/2
+        "movq %%mm3, %%mm1                      \n\t" // d/2
+        PAVGB(%%mm7, %%mm3)                           // d/4
+        PAVGB(%%mm1, %%mm3)                           // 3*d/8
+
+        "movq (%0, %1, 4), %%mm0                \n\t" // line 4
+        "pxor %%mm2, %%mm0                      \n\t" //(l4 - l5) <= 0 ? -l4-1 : l4
+        "psubusb %%mm3, %%mm0                   \n\t"
+        "pxor %%mm2, %%mm0                      \n\t"
+        "movq %%mm0, (%0, %1, 4)                \n\t" // line 4
+
+        "movq (%%"REG_c"), %%mm0                \n\t" // line 5
+        "pxor %%mm2, %%mm0                      \n\t" //(l4 - l5) <= 0 ? -l5-1 : l5
+        "paddusb %%mm3, %%mm0                   \n\t"
+        "pxor %%mm2, %%mm0                      \n\t"
+        "movq %%mm0, (%%"REG_c")                \n\t" // line 5
+
+        PAVGB(%%mm7, %%mm1)                           // d/4
+
+        "movq (%%"REG_a", %1, 2), %%mm0         \n\t" // line 3
+        "pxor %%mm2, %%mm0                      \n\t" //(l4 - l5) <= 0 ? -l4-1 : l4
+        "psubusb %%mm1, %%mm0                   \n\t"
+        "pxor %%mm2, %%mm0                      \n\t"
+        "movq %%mm0, (%%"REG_a", %1, 2)         \n\t" // line 3
+
+        "movq (%%"REG_c", %1), %%mm0            \n\t" // line 6
+        "pxor %%mm2, %%mm0                      \n\t" //(l4 - l5) <= 0 ? -l5-1 : l5
+        "paddusb %%mm1, %%mm0                   \n\t"
+        "pxor %%mm2, %%mm0                      \n\t"
+        "movq %%mm0, (%%"REG_c", %1)            \n\t" // line 6
+
+        PAVGB(%%mm7, %%mm1)                           // d/8
+
+        "movq (%%"REG_a", %1), %%mm0            \n\t" // line 2
+        "pxor %%mm2, %%mm0                      \n\t" //(l4 - l5) <= 0 ? -l2-1 : l2
+        "psubusb %%mm1, %%mm0                   \n\t"
+        "pxor %%mm2, %%mm0                      \n\t"
+        "movq %%mm0, (%%"REG_a", %1)            \n\t" // line 2
+
+        "movq (%%"REG_c", %1, 2), %%mm0         \n\t" // line 7
+        "pxor %%mm2, %%mm0                      \n\t" //(l4 - l5) <= 0 ? -l7-1 : l7
+        "paddusb %%mm1, %%mm0                   \n\t"
+        "pxor %%mm2, %%mm0                      \n\t"
+        "movq %%mm0, (%%"REG_c", %1, 2)         \n\t" // line 7
+
+        :
+        : "r" (src), "r" ((x86_reg)stride), "m" (co->pQPb)
+        : "%"REG_a, "%"REG_c
+    );
+#else //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+
+    const int l1= stride;
+    const int l2= stride + l1;
+    const int l3= stride + l2;
+    const int l4= stride + l3;
+    const int l5= stride + l4;
+    const int l6= stride + l5;
+    const int l7= stride + l6;
+//    const int l8= stride + l7;
+//    const int l9= stride + l8;
+    int x;
+
+    src+= stride*3;
+    for(x=0; x<BLOCK_SIZE; x++){
+        int a= src[l3] - src[l4];
+        int b= src[l4] - src[l5];
+        int c= src[l5] - src[l6];
+
+        int d= FFABS(b) - ((FFABS(a) + FFABS(c))>>1);
+        d= FFMAX(d, 0);
+
+        if(d < co->QP*2){
+            int v = d * FFSIGN(-b);
+
+            src[l2] +=v>>3;
+            src[l3] +=v>>2;
+            src[l4] +=(3*v)>>3;
+            src[l5] -=(3*v)>>3;
+            src[l6] -=v>>2;
+            src[l7] -=v>>3;
+        }
+        src++;
+    }
+#endif //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+}
+
+#if !HAVE_ALTIVEC
+static inline void RENAME(doVertDefFilter)(uint8_t src[], int stride, PPContext *c)
+{
+#if HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+/*
+    uint8_t tmp[16];
+    const int l1= stride;
+    const int l2= stride + l1;
+    const int l3= stride + l2;
+    const int l4= (int)tmp - (int)src - stride*3;
+    const int l5= (int)tmp - (int)src - stride*3 + 8;
+    const int l6= stride*3 + l3;
+    const int l7= stride + l6;
+    const int l8= stride + l7;
+
+    memcpy(tmp, src+stride*7, 8);
+    memcpy(tmp+8, src+stride*8, 8);
+*/
+    src+= stride*4;
+    __asm__ volatile(
+
+#if 0 //slightly more accurate and slightly slower
+        "pxor %%mm7, %%mm7                      \n\t" // 0
+        "lea (%0, %1), %%"REG_a"                \n\t"
+        "lea (%%"REG_a", %1, 4), %%"REG_c"      \n\t"
+//      0       1       2       3       4       5       6       7
+//      %0      %0+%1   %0+2%1  eax+2%1 %0+4%1  eax+4%1 ecx+%1  ecx+2%1
+//      %0      eax     eax+%1  eax+2%1 %0+4%1  ecx     ecx+%1  ecx+2%1
+
+
+        "movq (%0, %1, 2), %%mm0                \n\t" // l2
+        "movq (%0), %%mm1                       \n\t" // l0
+        "movq %%mm0, %%mm2                      \n\t" // l2
+        PAVGB(%%mm7, %%mm0)                           // ~l2/2
+        PAVGB(%%mm1, %%mm0)                           // ~(l2 + 2l0)/4
+        PAVGB(%%mm2, %%mm0)                           // ~(5l2 + 2l0)/8
+
+        "movq (%%"REG_a"), %%mm1                \n\t" // l1
+        "movq (%%"REG_a", %1, 2), %%mm3         \n\t" // l3
+        "movq %%mm1, %%mm4                      \n\t" // l1
+        PAVGB(%%mm7, %%mm1)                           // ~l1/2
+        PAVGB(%%mm3, %%mm1)                           // ~(l1 + 2l3)/4
+        PAVGB(%%mm4, %%mm1)                           // ~(5l1 + 2l3)/8
+
+        "movq %%mm0, %%mm4                      \n\t" // ~(5l2 + 2l0)/8
+        "psubusb %%mm1, %%mm0                   \n\t"
+        "psubusb %%mm4, %%mm1                   \n\t"
+        "por %%mm0, %%mm1                       \n\t" // ~|2l0 - 5l1 + 5l2 - 2l3|/8
+// mm1= |lenergy|, mm2= l2, mm3= l3, mm7=0
+
+        "movq (%0, %1, 4), %%mm0                \n\t" // l4
+        "movq %%mm0, %%mm4                      \n\t" // l4
+        PAVGB(%%mm7, %%mm0)                           // ~l4/2
+        PAVGB(%%mm2, %%mm0)                           // ~(l4 + 2l2)/4
+        PAVGB(%%mm4, %%mm0)                           // ~(5l4 + 2l2)/8
+
+        "movq (%%"REG_c"), %%mm2                \n\t" // l5
+        "movq %%mm3, %%mm5                      \n\t" // l3
+        PAVGB(%%mm7, %%mm3)                           // ~l3/2
+        PAVGB(%%mm2, %%mm3)                           // ~(l3 + 2l5)/4
+        PAVGB(%%mm5, %%mm3)                           // ~(5l3 + 2l5)/8
+
+        "movq %%mm0, %%mm6                      \n\t" // ~(5l4 + 2l2)/8
+        "psubusb %%mm3, %%mm0                   \n\t"
+        "psubusb %%mm6, %%mm3                   \n\t"
+        "por %%mm0, %%mm3                       \n\t" // ~|2l2 - 5l3 + 5l4 - 2l5|/8
+        "pcmpeqb %%mm7, %%mm0                   \n\t" // SIGN(2l2 - 5l3 + 5l4 - 2l5)
+// mm0= SIGN(menergy), mm1= |lenergy|, mm2= l5, mm3= |menergy|, mm4=l4, mm5= l3, mm7=0
+
+        "movq (%%"REG_c", %1), %%mm6            \n\t" // l6
+        "movq %%mm6, %%mm5                      \n\t" // l6
+        PAVGB(%%mm7, %%mm6)                           // ~l6/2
+        PAVGB(%%mm4, %%mm6)                           // ~(l6 + 2l4)/4
+        PAVGB(%%mm5, %%mm6)                           // ~(5l6 + 2l4)/8
+
+        "movq (%%"REG_c", %1, 2), %%mm5         \n\t" // l7
+        "movq %%mm2, %%mm4                      \n\t" // l5
+        PAVGB(%%mm7, %%mm2)                           // ~l5/2
+        PAVGB(%%mm5, %%mm2)                           // ~(l5 + 2l7)/4
+        PAVGB(%%mm4, %%mm2)                           // ~(5l5 + 2l7)/8
+
+        "movq %%mm6, %%mm4                      \n\t" // ~(5l6 + 2l4)/8
+        "psubusb %%mm2, %%mm6                   \n\t"
+        "psubusb %%mm4, %%mm2                   \n\t"
+        "por %%mm6, %%mm2                       \n\t" // ~|2l4 - 5l5 + 5l6 - 2l7|/8
+// mm0= SIGN(menergy), mm1= |lenergy|/8, mm2= |renergy|/8, mm3= |menergy|/8, mm7=0
+
+
+        PMINUB(%%mm2, %%mm1, %%mm4)                   // MIN(|lenergy|,|renergy|)/8
+        "movq %2, %%mm4                         \n\t" // QP //FIXME QP+1 ?
+        "paddusb "MANGLE(b01)", %%mm4           \n\t"
+        "pcmpgtb %%mm3, %%mm4                   \n\t" // |menergy|/8 < QP
+        "psubusb %%mm1, %%mm3                   \n\t" // d=|menergy|/8-MIN(|lenergy|,|renergy|)/8
+        "pand %%mm4, %%mm3                      \n\t"
+
+        "movq %%mm3, %%mm1                      \n\t"
+//        "psubusb "MANGLE(b01)", %%mm3           \n\t"
+        PAVGB(%%mm7, %%mm3)
+        PAVGB(%%mm7, %%mm3)
+        "paddusb %%mm1, %%mm3                   \n\t"
+//        "paddusb "MANGLE(b01)", %%mm3           \n\t"
+
+        "movq (%%"REG_a", %1, 2), %%mm6         \n\t" //l3
+        "movq (%0, %1, 4), %%mm5                \n\t" //l4
+        "movq (%0, %1, 4), %%mm4                \n\t" //l4
+        "psubusb %%mm6, %%mm5                   \n\t"
+        "psubusb %%mm4, %%mm6                   \n\t"
+        "por %%mm6, %%mm5                       \n\t" // |l3-l4|
+        "pcmpeqb %%mm7, %%mm6                   \n\t" // SIGN(l3-l4)
+        "pxor %%mm6, %%mm0                      \n\t"
+        "pand %%mm0, %%mm3                      \n\t"
+        PMINUB(%%mm5, %%mm3, %%mm0)
+
+        "psubusb "MANGLE(b01)", %%mm3           \n\t"
+        PAVGB(%%mm7, %%mm3)
+
+        "movq (%%"REG_a", %1, 2), %%mm0         \n\t"
+        "movq (%0, %1, 4), %%mm2                \n\t"
+        "pxor %%mm6, %%mm0                      \n\t"
+        "pxor %%mm6, %%mm2                      \n\t"
+        "psubb %%mm3, %%mm0                     \n\t"
+        "paddb %%mm3, %%mm2                     \n\t"
+        "pxor %%mm6, %%mm0                      \n\t"
+        "pxor %%mm6, %%mm2                      \n\t"
+        "movq %%mm0, (%%"REG_a", %1, 2)         \n\t"
+        "movq %%mm2, (%0, %1, 4)                \n\t"
+#endif //0
+
+        "lea (%0, %1), %%"REG_a"                \n\t"
+        "pcmpeqb %%mm6, %%mm6                   \n\t" // -1
+//      0       1       2       3       4       5       6       7
+//      %0      %0+%1   %0+2%1  eax+2%1 %0+4%1  eax+4%1 ecx+%1  ecx+2%1
+//      %0      eax     eax+%1  eax+2%1 %0+4%1  ecx     ecx+%1  ecx+2%1
+
+
+        "movq (%%"REG_a", %1, 2), %%mm1         \n\t" // l3
+        "movq (%0, %1, 4), %%mm0                \n\t" // l4
+        "pxor %%mm6, %%mm1                      \n\t" // -l3-1
+        PAVGB(%%mm1, %%mm0)                           // -q+128 = (l4-l3+256)/2
+// mm1=-l3-1, mm0=128-q
+
+        "movq (%%"REG_a", %1, 4), %%mm2         \n\t" // l5
+        "movq (%%"REG_a", %1), %%mm3            \n\t" // l2
+        "pxor %%mm6, %%mm2                      \n\t" // -l5-1
+        "movq %%mm2, %%mm5                      \n\t" // -l5-1
+        "movq "MANGLE(b80)", %%mm4              \n\t" // 128
+        "lea (%%"REG_a", %1, 4), %%"REG_c"      \n\t"
+        PAVGB(%%mm3, %%mm2)                           // (l2-l5+256)/2
+        PAVGB(%%mm0, %%mm4)                           // ~(l4-l3)/4 + 128
+        PAVGB(%%mm2, %%mm4)                           // ~(l2-l5)/4 +(l4-l3)/8 + 128
+        PAVGB(%%mm0, %%mm4)                           // ~(l2-l5)/8 +5(l4-l3)/16 + 128
+// mm1=-l3-1, mm0=128-q, mm3=l2, mm4=menergy/16 + 128, mm5= -l5-1
+
+        "movq (%%"REG_a"), %%mm2                \n\t" // l1
+        "pxor %%mm6, %%mm2                      \n\t" // -l1-1
+        PAVGB(%%mm3, %%mm2)                           // (l2-l1+256)/2
+        PAVGB((%0), %%mm1)                            // (l0-l3+256)/2
+        "movq "MANGLE(b80)", %%mm3              \n\t" // 128
+        PAVGB(%%mm2, %%mm3)                           // ~(l2-l1)/4 + 128
+        PAVGB(%%mm1, %%mm3)                           // ~(l0-l3)/4 +(l2-l1)/8 + 128
+        PAVGB(%%mm2, %%mm3)                           // ~(l0-l3)/8 +5(l2-l1)/16 + 128
+// mm0=128-q, mm3=lenergy/16 + 128, mm4= menergy/16 + 128, mm5= -l5-1
+
+        PAVGB((%%REGc, %1), %%mm5)                    // (l6-l5+256)/2
+        "movq (%%"REG_c", %1, 2), %%mm1         \n\t" // l7
+        "pxor %%mm6, %%mm1                      \n\t" // -l7-1
+        PAVGB((%0, %1, 4), %%mm1)                     // (l4-l7+256)/2
+        "movq "MANGLE(b80)", %%mm2              \n\t" // 128
+        PAVGB(%%mm5, %%mm2)                           // ~(l6-l5)/4 + 128
+        PAVGB(%%mm1, %%mm2)                           // ~(l4-l7)/4 +(l6-l5)/8 + 128
+        PAVGB(%%mm5, %%mm2)                           // ~(l4-l7)/8 +5(l6-l5)/16 + 128
+// mm0=128-q, mm2=renergy/16 + 128, mm3=lenergy/16 + 128, mm4= menergy/16 + 128
+
+        "movq "MANGLE(b00)", %%mm1              \n\t" // 0
+        "movq "MANGLE(b00)", %%mm5              \n\t" // 0
+        "psubb %%mm2, %%mm1                     \n\t" // 128 - renergy/16
+        "psubb %%mm3, %%mm5                     \n\t" // 128 - lenergy/16
+        PMAXUB(%%mm1, %%mm2)                          // 128 + |renergy/16|
+        PMAXUB(%%mm5, %%mm3)                          // 128 + |lenergy/16|
+        PMINUB(%%mm2, %%mm3, %%mm1)                   // 128 + MIN(|lenergy|,|renergy|)/16
+
+// mm0=128-q, mm3=128 + MIN(|lenergy|,|renergy|)/16, mm4= menergy/16 + 128
+
+        "movq "MANGLE(b00)", %%mm7              \n\t" // 0
+        "movq %2, %%mm2                         \n\t" // QP
+        PAVGB(%%mm6, %%mm2)                           // 128 + QP/2
+        "psubb %%mm6, %%mm2                     \n\t"
+
+        "movq %%mm4, %%mm1                      \n\t"
+        "pcmpgtb %%mm7, %%mm1                   \n\t" // SIGN(menergy)
+        "pxor %%mm1, %%mm4                      \n\t"
+        "psubb %%mm1, %%mm4                     \n\t" // 128 + |menergy|/16
+        "pcmpgtb %%mm4, %%mm2                   \n\t" // |menergy|/16 < QP/2
+        "psubusb %%mm3, %%mm4                   \n\t" //d=|menergy|/16 - MIN(|lenergy|,|renergy|)/16
+// mm0=128-q, mm1= SIGN(menergy), mm2= |menergy|/16 < QP/2, mm4= d/16
+
+        "movq %%mm4, %%mm3                      \n\t" // d
+        "psubusb "MANGLE(b01)", %%mm4           \n\t"
+        PAVGB(%%mm7, %%mm4)                           // d/32
+        PAVGB(%%mm7, %%mm4)                           // (d + 32)/64
+        "paddb %%mm3, %%mm4                     \n\t" // 5d/64
+        "pand %%mm2, %%mm4                      \n\t"
+
+        "movq "MANGLE(b80)", %%mm5              \n\t" // 128
+        "psubb %%mm0, %%mm5                     \n\t" // q
+        "paddsb %%mm6, %%mm5                    \n\t" // fix bad rounding
+        "pcmpgtb %%mm5, %%mm7                   \n\t" // SIGN(q)
+        "pxor %%mm7, %%mm5                      \n\t"
+
+        PMINUB(%%mm5, %%mm4, %%mm3)                   // MIN(|q|, 5d/64)
+        "pxor %%mm1, %%mm7                      \n\t" // SIGN(d*q)
+
+        "pand %%mm7, %%mm4                      \n\t"
+        "movq (%%"REG_a", %1, 2), %%mm0         \n\t"
+        "movq (%0, %1, 4), %%mm2                \n\t"
+        "pxor %%mm1, %%mm0                      \n\t"
+        "pxor %%mm1, %%mm2                      \n\t"
+        "paddb %%mm4, %%mm0                     \n\t"
+        "psubb %%mm4, %%mm2                     \n\t"
+        "pxor %%mm1, %%mm0                      \n\t"
+        "pxor %%mm1, %%mm2                      \n\t"
+        "movq %%mm0, (%%"REG_a", %1, 2)         \n\t"
+        "movq %%mm2, (%0, %1, 4)                \n\t"
+
+        :
+        : "r" (src), "r" ((x86_reg)stride), "m" (c->pQPb)
+        : "%"REG_a, "%"REG_c
+    );
+
+/*
+    {
+    int x;
+    src-= stride;
+    for(x=0; x<BLOCK_SIZE; x++){
+        const int middleEnergy= 5*(src[l5] - src[l4]) + 2*(src[l3] - src[l6]);
+        if(FFABS(middleEnergy)< 8*QP){
+            const int q=(src[l4] - src[l5])/2;
+            const int leftEnergy=  5*(src[l3] - src[l2]) + 2*(src[l1] - src[l4]);
+            const int rightEnergy= 5*(src[l7] - src[l6]) + 2*(src[l5] - src[l8]);
+
+            int d= FFABS(middleEnergy) - FFMIN( FFABS(leftEnergy), FFABS(rightEnergy) );
+            d= FFMAX(d, 0);
+
+            d= (5*d + 32) >> 6;
+            d*= FFSIGN(-middleEnergy);
+
+            if(q>0){
+                d= d<0 ? 0 : d;
+                d= d>q ? q : d;
+            }else{
+                d= d>0 ? 0 : d;
+                d= d<q ? q : d;
+            }
+
+            src[l4]-= d;
+            src[l5]+= d;
+        }
+        src++;
+    }
+    src-=8;
+    for(x=0; x<8; x++){
+        int y;
+        for(y=4; y<6; y++){
+            int d= src[x+y*stride] - tmp[x+(y-4)*8];
+            int ad= FFABS(d);
+            static int max=0;
+            static int sum=0;
+            static int num=0;
+            static int bias=0;
+
+            if(max<ad) max=ad;
+            sum+= ad>3 ? 1 : 0;
+            if(ad>3){
+                src[0] = src[7] = src[stride*7] = src[(stride+1)*7]=255;
+            }
+            if(y==4) bias+=d;
+            num++;
+            if(num%1000000 == 0){
+                av_log(c, AV_LOG_INFO, " %d %d %d %d\n", num, sum, max, bias);
+            }
+        }
+    }
+}
+*/
+#elif HAVE_MMX_INLINE
+    DECLARE_ALIGNED(8, uint64_t, tmp)[4]; // make space for 4 8-byte vars
+    src+= stride*4;
+    __asm__ volatile(
+        "pxor %%mm7, %%mm7                      \n\t"
+//      0       1       2       3       4       5       6       7
+//      %0      %0+%1   %0+2%1  eax+2%1 %0+4%1  eax+4%1 edx+%1  edx+2%1
+//      %0      eax     eax+%1  eax+2%1 %0+4%1  edx     edx+%1  edx+2%1
+
+        "movq (%0), %%mm0                       \n\t"
+        "movq %%mm0, %%mm1                      \n\t"
+        "punpcklbw %%mm7, %%mm0                 \n\t" // low part of line 0
+        "punpckhbw %%mm7, %%mm1                 \n\t" // high part of line 0
+
+        "movq (%0, %1), %%mm2                   \n\t"
+        "lea (%0, %1, 2), %%"REG_a"             \n\t"
+        "movq %%mm2, %%mm3                      \n\t"
+        "punpcklbw %%mm7, %%mm2                 \n\t" // low part of line 1
+        "punpckhbw %%mm7, %%mm3                 \n\t" // high part of line 1
+
+        "movq (%%"REG_a"), %%mm4                \n\t"
+        "movq %%mm4, %%mm5                      \n\t"
+        "punpcklbw %%mm7, %%mm4                 \n\t" // low part of line 2
+        "punpckhbw %%mm7, %%mm5                 \n\t" // high part of line 2
+
+        "paddw %%mm0, %%mm0                     \n\t" // 2L0
+        "paddw %%mm1, %%mm1                     \n\t" // 2H0
+        "psubw %%mm4, %%mm2                     \n\t" // L1 - L2
+        "psubw %%mm5, %%mm3                     \n\t" // H1 - H2
+        "psubw %%mm2, %%mm0                     \n\t" // 2L0 - L1 + L2
+        "psubw %%mm3, %%mm1                     \n\t" // 2H0 - H1 + H2
+
+        "psllw $2, %%mm2                        \n\t" // 4L1 - 4L2
+        "psllw $2, %%mm3                        \n\t" // 4H1 - 4H2
+        "psubw %%mm2, %%mm0                     \n\t" // 2L0 - 5L1 + 5L2
+        "psubw %%mm3, %%mm1                     \n\t" // 2H0 - 5H1 + 5H2
+
+        "movq (%%"REG_a", %1), %%mm2            \n\t"
+        "movq %%mm2, %%mm3                      \n\t"
+        "punpcklbw %%mm7, %%mm2                 \n\t" // L3
+        "punpckhbw %%mm7, %%mm3                 \n\t" // H3
+
+        "psubw %%mm2, %%mm0                     \n\t" // 2L0 - 5L1 + 5L2 - L3
+        "psubw %%mm3, %%mm1                     \n\t" // 2H0 - 5H1 + 5H2 - H3
+        "psubw %%mm2, %%mm0                     \n\t" // 2L0 - 5L1 + 5L2 - 2L3
+        "psubw %%mm3, %%mm1                     \n\t" // 2H0 - 5H1 + 5H2 - 2H3
+        "movq %%mm0, (%3)                       \n\t" // 2L0 - 5L1 + 5L2 - 2L3
+        "movq %%mm1, 8(%3)                      \n\t" // 2H0 - 5H1 + 5H2 - 2H3
+
+        "movq (%%"REG_a", %1, 2), %%mm0         \n\t"
+        "movq %%mm0, %%mm1                      \n\t"
+        "punpcklbw %%mm7, %%mm0                 \n\t" // L4
+        "punpckhbw %%mm7, %%mm1                 \n\t" // H4
+
+        "psubw %%mm0, %%mm2                     \n\t" // L3 - L4
+        "psubw %%mm1, %%mm3                     \n\t" // H3 - H4
+        "movq %%mm2, 16(%3)                     \n\t" // L3 - L4
+        "movq %%mm3, 24(%3)                     \n\t" // H3 - H4
+        "paddw %%mm4, %%mm4                     \n\t" // 2L2
+        "paddw %%mm5, %%mm5                     \n\t" // 2H2
+        "psubw %%mm2, %%mm4                     \n\t" // 2L2 - L3 + L4
+        "psubw %%mm3, %%mm5                     \n\t" // 2H2 - H3 + H4
+
+        "lea (%%"REG_a", %1), %0                \n\t"
+        "psllw $2, %%mm2                        \n\t" // 4L3 - 4L4
+        "psllw $2, %%mm3                        \n\t" // 4H3 - 4H4
+        "psubw %%mm2, %%mm4                     \n\t" // 2L2 - 5L3 + 5L4
+        "psubw %%mm3, %%mm5                     \n\t" // 2H2 - 5H3 + 5H4
+//50 opcodes so far
+        "movq (%0, %1, 2), %%mm2                \n\t"
+        "movq %%mm2, %%mm3                      \n\t"
+        "punpcklbw %%mm7, %%mm2                 \n\t" // L5
+        "punpckhbw %%mm7, %%mm3                 \n\t" // H5
+        "psubw %%mm2, %%mm4                     \n\t" // 2L2 - 5L3 + 5L4 - L5
+        "psubw %%mm3, %%mm5                     \n\t" // 2H2 - 5H3 + 5H4 - H5
+        "psubw %%mm2, %%mm4                     \n\t" // 2L2 - 5L3 + 5L4 - 2L5
+        "psubw %%mm3, %%mm5                     \n\t" // 2H2 - 5H3 + 5H4 - 2H5
+
+        "movq (%%"REG_a", %1, 4), %%mm6         \n\t"
+        "punpcklbw %%mm7, %%mm6                 \n\t" // L6
+        "psubw %%mm6, %%mm2                     \n\t" // L5 - L6
+        "movq (%%"REG_a", %1, 4), %%mm6         \n\t"
+        "punpckhbw %%mm7, %%mm6                 \n\t" // H6
+        "psubw %%mm6, %%mm3                     \n\t" // H5 - H6
+
+        "paddw %%mm0, %%mm0                     \n\t" // 2L4
+        "paddw %%mm1, %%mm1                     \n\t" // 2H4
+        "psubw %%mm2, %%mm0                     \n\t" // 2L4 - L5 + L6
+        "psubw %%mm3, %%mm1                     \n\t" // 2H4 - H5 + H6
+
+        "psllw $2, %%mm2                        \n\t" // 4L5 - 4L6
+        "psllw $2, %%mm3                        \n\t" // 4H5 - 4H6
+        "psubw %%mm2, %%mm0                     \n\t" // 2L4 - 5L5 + 5L6
+        "psubw %%mm3, %%mm1                     \n\t" // 2H4 - 5H5 + 5H6
+
+        "movq (%0, %1, 4), %%mm2                \n\t"
+        "movq %%mm2, %%mm3                      \n\t"
+        "punpcklbw %%mm7, %%mm2                 \n\t" // L7
+        "punpckhbw %%mm7, %%mm3                 \n\t" // H7
+
+        "paddw %%mm2, %%mm2                     \n\t" // 2L7
+        "paddw %%mm3, %%mm3                     \n\t" // 2H7
+        "psubw %%mm2, %%mm0                     \n\t" // 2L4 - 5L5 + 5L6 - 2L7
+        "psubw %%mm3, %%mm1                     \n\t" // 2H4 - 5H5 + 5H6 - 2H7
+
+        "movq (%3), %%mm2                       \n\t" // 2L0 - 5L1 + 5L2 - 2L3
+        "movq 8(%3), %%mm3                      \n\t" // 2H0 - 5H1 + 5H2 - 2H3
+
+#if HAVE_MMXEXT_INLINE
+        "movq %%mm7, %%mm6                      \n\t" // 0
+        "psubw %%mm0, %%mm6                     \n\t"
+        "pmaxsw %%mm6, %%mm0                    \n\t" // |2L4 - 5L5 + 5L6 - 2L7|
+        "movq %%mm7, %%mm6                      \n\t" // 0
+        "psubw %%mm1, %%mm6                     \n\t"
+        "pmaxsw %%mm6, %%mm1                    \n\t" // |2H4 - 5H5 + 5H6 - 2H7|
+        "movq %%mm7, %%mm6                      \n\t" // 0
+        "psubw %%mm2, %%mm6                     \n\t"
+        "pmaxsw %%mm6, %%mm2                    \n\t" // |2L0 - 5L1 + 5L2 - 2L3|
+        "movq %%mm7, %%mm6                      \n\t" // 0
+        "psubw %%mm3, %%mm6                     \n\t"
+        "pmaxsw %%mm6, %%mm3                    \n\t" // |2H0 - 5H1 + 5H2 - 2H3|
+#else
+        "movq %%mm7, %%mm6                      \n\t" // 0
+        "pcmpgtw %%mm0, %%mm6                   \n\t"
+        "pxor %%mm6, %%mm0                      \n\t"
+        "psubw %%mm6, %%mm0                     \n\t" // |2L4 - 5L5 + 5L6 - 2L7|
+        "movq %%mm7, %%mm6                      \n\t" // 0
+        "pcmpgtw %%mm1, %%mm6                   \n\t"
+        "pxor %%mm6, %%mm1                      \n\t"
+        "psubw %%mm6, %%mm1                     \n\t" // |2H4 - 5H5 + 5H6 - 2H7|
+        "movq %%mm7, %%mm6                      \n\t" // 0
+        "pcmpgtw %%mm2, %%mm6                   \n\t"
+        "pxor %%mm6, %%mm2                      \n\t"
+        "psubw %%mm6, %%mm2                     \n\t" // |2L0 - 5L1 + 5L2 - 2L3|
+        "movq %%mm7, %%mm6                      \n\t" // 0
+        "pcmpgtw %%mm3, %%mm6                   \n\t"
+        "pxor %%mm6, %%mm3                      \n\t"
+        "psubw %%mm6, %%mm3                     \n\t" // |2H0 - 5H1 + 5H2 - 2H3|
+#endif
+
+#if HAVE_MMXEXT_INLINE
+        "pminsw %%mm2, %%mm0                    \n\t"
+        "pminsw %%mm3, %%mm1                    \n\t"
+#else
+        "movq %%mm0, %%mm6                      \n\t"
+        "psubusw %%mm2, %%mm6                   \n\t"
+        "psubw %%mm6, %%mm0                     \n\t"
+        "movq %%mm1, %%mm6                      \n\t"
+        "psubusw %%mm3, %%mm6                   \n\t"
+        "psubw %%mm6, %%mm1                     \n\t"
+#endif
+
+        "movd %2, %%mm2                         \n\t" // QP
+        "punpcklbw %%mm7, %%mm2                 \n\t"
+
+        "movq %%mm7, %%mm6                      \n\t" // 0
+        "pcmpgtw %%mm4, %%mm6                   \n\t" // sign(2L2 - 5L3 + 5L4 - 2L5)
+        "pxor %%mm6, %%mm4                      \n\t"
+        "psubw %%mm6, %%mm4                     \n\t" // |2L2 - 5L3 + 5L4 - 2L5|
+        "pcmpgtw %%mm5, %%mm7                   \n\t" // sign(2H2 - 5H3 + 5H4 - 2H5)
+        "pxor %%mm7, %%mm5                      \n\t"
+        "psubw %%mm7, %%mm5                     \n\t" // |2H2 - 5H3 + 5H4 - 2H5|
+// 100 opcodes
+        "psllw $3, %%mm2                        \n\t" // 8QP
+        "movq %%mm2, %%mm3                      \n\t" // 8QP
+        "pcmpgtw %%mm4, %%mm2                   \n\t"
+        "pcmpgtw %%mm5, %%mm3                   \n\t"
+        "pand %%mm2, %%mm4                      \n\t"
+        "pand %%mm3, %%mm5                      \n\t"
+
+
+        "psubusw %%mm0, %%mm4                   \n\t" // hd
+        "psubusw %%mm1, %%mm5                   \n\t" // ld
+
+
+        "movq "MANGLE(w05)", %%mm2              \n\t" // 5
+        "pmullw %%mm2, %%mm4                    \n\t"
+        "pmullw %%mm2, %%mm5                    \n\t"
+        "movq "MANGLE(w20)", %%mm2              \n\t" // 32
+        "paddw %%mm2, %%mm4                     \n\t"
+        "paddw %%mm2, %%mm5                     \n\t"
+        "psrlw $6, %%mm4                        \n\t"
+        "psrlw $6, %%mm5                        \n\t"
+
+        "movq 16(%3), %%mm0                     \n\t" // L3 - L4
+        "movq 24(%3), %%mm1                     \n\t" // H3 - H4
+
+        "pxor %%mm2, %%mm2                      \n\t"
+        "pxor %%mm3, %%mm3                      \n\t"
+
+        "pcmpgtw %%mm0, %%mm2                   \n\t" // sign (L3-L4)
+        "pcmpgtw %%mm1, %%mm3                   \n\t" // sign (H3-H4)
+        "pxor %%mm2, %%mm0                      \n\t"
+        "pxor %%mm3, %%mm1                      \n\t"
+        "psubw %%mm2, %%mm0                     \n\t" // |L3-L4|
+        "psubw %%mm3, %%mm1                     \n\t" // |H3-H4|
+        "psrlw $1, %%mm0                        \n\t" // |L3 - L4|/2
+        "psrlw $1, %%mm1                        \n\t" // |H3 - H4|/2
+
+        "pxor %%mm6, %%mm2                      \n\t"
+        "pxor %%mm7, %%mm3                      \n\t"
+        "pand %%mm2, %%mm4                      \n\t"
+        "pand %%mm3, %%mm5                      \n\t"
+
+#if HAVE_MMXEXT_INLINE
+        "pminsw %%mm0, %%mm4                    \n\t"
+        "pminsw %%mm1, %%mm5                    \n\t"
+#else
+        "movq %%mm4, %%mm2                      \n\t"
+        "psubusw %%mm0, %%mm2                   \n\t"
+        "psubw %%mm2, %%mm4                     \n\t"
+        "movq %%mm5, %%mm2                      \n\t"
+        "psubusw %%mm1, %%mm2                   \n\t"
+        "psubw %%mm2, %%mm5                     \n\t"
+#endif
+        "pxor %%mm6, %%mm4                      \n\t"
+        "pxor %%mm7, %%mm5                      \n\t"
+        "psubw %%mm6, %%mm4                     \n\t"
+        "psubw %%mm7, %%mm5                     \n\t"
+        "packsswb %%mm5, %%mm4                  \n\t"
+        "movq (%0), %%mm0                       \n\t"
+        "paddb   %%mm4, %%mm0                   \n\t"
+        "movq %%mm0, (%0)                       \n\t"
+        "movq (%0, %1), %%mm0                   \n\t"
+        "psubb %%mm4, %%mm0                     \n\t"
+        "movq %%mm0, (%0, %1)                   \n\t"
+
+        : "+r" (src)
+        : "r" ((x86_reg)stride), "m" (c->pQPb), "r"(tmp)
+        : "%"REG_a
+    );
+#else //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    const int l1= stride;
+    const int l2= stride + l1;
+    const int l3= stride + l2;
+    const int l4= stride + l3;
+    const int l5= stride + l4;
+    const int l6= stride + l5;
+    const int l7= stride + l6;
+    const int l8= stride + l7;
+//    const int l9= stride + l8;
+    int x;
+    src+= stride*3;
+    for(x=0; x<BLOCK_SIZE; x++){
+        const int middleEnergy= 5*(src[l5] - src[l4]) + 2*(src[l3] - src[l6]);
+        if(FFABS(middleEnergy) < 8*c->QP){
+            const int q=(src[l4] - src[l5])/2;
+            const int leftEnergy=  5*(src[l3] - src[l2]) + 2*(src[l1] - src[l4]);
+            const int rightEnergy= 5*(src[l7] - src[l6]) + 2*(src[l5] - src[l8]);
+
+            int d= FFABS(middleEnergy) - FFMIN( FFABS(leftEnergy), FFABS(rightEnergy) );
+            d= FFMAX(d, 0);
+
+            d= (5*d + 32) >> 6;
+            d*= FFSIGN(-middleEnergy);
+
+            if(q>0){
+                d= d<0 ? 0 : d;
+                d= d>q ? q : d;
+            }else{
+                d= d>0 ? 0 : d;
+                d= d<q ? q : d;
+            }
+
+            src[l4]-= d;
+            src[l5]+= d;
+        }
+        src++;
+    }
+#endif //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+}
+#endif //HAVE_ALTIVEC
+
+#if !HAVE_ALTIVEC
+static inline void RENAME(dering)(uint8_t src[], int stride, PPContext *c)
+{
+#if HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    DECLARE_ALIGNED(8, uint64_t, tmp)[3];
+    __asm__ volatile(
+        "pxor %%mm6, %%mm6                      \n\t"
+        "pcmpeqb %%mm7, %%mm7                   \n\t"
+        "movq %2, %%mm0                         \n\t"
+        "punpcklbw %%mm6, %%mm0                 \n\t"
+        "psrlw $1, %%mm0                        \n\t"
+        "psubw %%mm7, %%mm0                     \n\t"
+        "packuswb %%mm0, %%mm0                  \n\t"
+        "movq %%mm0, %3                         \n\t"
+
+        "lea (%0, %1), %%"REG_a"                \n\t"
+        "lea (%%"REG_a", %1, 4), %%"REG_d"      \n\t"
+
+//        0        1        2        3        4        5        6        7        8        9
+//        %0        eax        eax+%1        eax+2%1        %0+4%1        edx        edx+%1        edx+2%1        %0+8%1        edx+4%1
+
+#undef REAL_FIND_MIN_MAX
+#undef FIND_MIN_MAX
+#if HAVE_MMXEXT_INLINE
+#define REAL_FIND_MIN_MAX(addr)\
+        "movq " #addr ", %%mm0                  \n\t"\
+        "pminub %%mm0, %%mm7                    \n\t"\
+        "pmaxub %%mm0, %%mm6                    \n\t"
+#else
+#define REAL_FIND_MIN_MAX(addr)\
+        "movq " #addr ", %%mm0                  \n\t"\
+        "movq %%mm7, %%mm1                      \n\t"\
+        "psubusb %%mm0, %%mm6                   \n\t"\
+        "paddb %%mm0, %%mm6                     \n\t"\
+        "psubusb %%mm0, %%mm1                   \n\t"\
+        "psubb %%mm1, %%mm7                     \n\t"
+#endif
+#define FIND_MIN_MAX(addr)  REAL_FIND_MIN_MAX(addr)
+
+FIND_MIN_MAX((%%REGa))
+FIND_MIN_MAX((%%REGa, %1))
+FIND_MIN_MAX((%%REGa, %1, 2))
+FIND_MIN_MAX((%0, %1, 4))
+FIND_MIN_MAX((%%REGd))
+FIND_MIN_MAX((%%REGd, %1))
+FIND_MIN_MAX((%%REGd, %1, 2))
+FIND_MIN_MAX((%0, %1, 8))
+
+        "movq %%mm7, %%mm4                      \n\t"
+        "psrlq $8, %%mm7                        \n\t"
+#if HAVE_MMXEXT_INLINE
+        "pminub %%mm4, %%mm7                    \n\t" // min of pixels
+        "pshufw $0xF9, %%mm7, %%mm4             \n\t"
+        "pminub %%mm4, %%mm7                    \n\t" // min of pixels
+        "pshufw $0xFE, %%mm7, %%mm4             \n\t"
+        "pminub %%mm4, %%mm7                    \n\t"
+#else
+        "movq %%mm7, %%mm1                      \n\t"
+        "psubusb %%mm4, %%mm1                   \n\t"
+        "psubb %%mm1, %%mm7                     \n\t"
+        "movq %%mm7, %%mm4                      \n\t"
+        "psrlq $16, %%mm7                       \n\t"
+        "movq %%mm7, %%mm1                      \n\t"
+        "psubusb %%mm4, %%mm1                   \n\t"
+        "psubb %%mm1, %%mm7                     \n\t"
+        "movq %%mm7, %%mm4                      \n\t"
+        "psrlq $32, %%mm7                       \n\t"
+        "movq %%mm7, %%mm1                      \n\t"
+        "psubusb %%mm4, %%mm1                   \n\t"
+        "psubb %%mm1, %%mm7                     \n\t"
+#endif
+
+
+        "movq %%mm6, %%mm4                      \n\t"
+        "psrlq $8, %%mm6                        \n\t"
+#if HAVE_MMXEXT_INLINE
+        "pmaxub %%mm4, %%mm6                    \n\t" // max of pixels
+        "pshufw $0xF9, %%mm6, %%mm4             \n\t"
+        "pmaxub %%mm4, %%mm6                    \n\t"
+        "pshufw $0xFE, %%mm6, %%mm4             \n\t"
+        "pmaxub %%mm4, %%mm6                    \n\t"
+#else
+        "psubusb %%mm4, %%mm6                   \n\t"
+        "paddb %%mm4, %%mm6                     \n\t"
+        "movq %%mm6, %%mm4                      \n\t"
+        "psrlq $16, %%mm6                       \n\t"
+        "psubusb %%mm4, %%mm6                   \n\t"
+        "paddb %%mm4, %%mm6                     \n\t"
+        "movq %%mm6, %%mm4                      \n\t"
+        "psrlq $32, %%mm6                       \n\t"
+        "psubusb %%mm4, %%mm6                   \n\t"
+        "paddb %%mm4, %%mm6                     \n\t"
+#endif
+        "movq %%mm6, %%mm0                      \n\t" // max
+        "psubb %%mm7, %%mm6                     \n\t" // max - min
+        "push %4                              \n\t"
+        "movd %%mm6, %k4                        \n\t"
+        "cmpb "MANGLE(deringThreshold)", %b4    \n\t"
+        "pop %4                               \n\t"
+        " jb 1f                                 \n\t"
+        PAVGB(%%mm0, %%mm7)                           // a=(max + min)/2
+        "punpcklbw %%mm7, %%mm7                 \n\t"
+        "punpcklbw %%mm7, %%mm7                 \n\t"
+        "punpcklbw %%mm7, %%mm7                 \n\t"
+        "movq %%mm7, (%4)                       \n\t"
+
+        "movq (%0), %%mm0                       \n\t" // L10
+        "movq %%mm0, %%mm1                      \n\t" // L10
+        "movq %%mm0, %%mm2                      \n\t" // L10
+        "psllq $8, %%mm1                        \n\t"
+        "psrlq $8, %%mm2                        \n\t"
+        "movd -4(%0), %%mm3                     \n\t"
+        "movd 8(%0), %%mm4                      \n\t"
+        "psrlq $24, %%mm3                       \n\t"
+        "psllq $56, %%mm4                       \n\t"
+        "por %%mm3, %%mm1                       \n\t" // L00
+        "por %%mm4, %%mm2                       \n\t" // L20
+        "movq %%mm1, %%mm3                      \n\t" // L00
+        PAVGB(%%mm2, %%mm1)                           // (L20 + L00)/2
+        PAVGB(%%mm0, %%mm1)                           // (L20 + L00 + 2L10)/4
+        "psubusb %%mm7, %%mm0                   \n\t"
+        "psubusb %%mm7, %%mm2                   \n\t"
+        "psubusb %%mm7, %%mm3                   \n\t"
+        "pcmpeqb "MANGLE(b00)", %%mm0           \n\t" // L10 > a ? 0 : -1
+        "pcmpeqb "MANGLE(b00)", %%mm2           \n\t" // L20 > a ? 0 : -1
+        "pcmpeqb "MANGLE(b00)", %%mm3           \n\t" // L00 > a ? 0 : -1
+        "paddb %%mm2, %%mm0                     \n\t"
+        "paddb %%mm3, %%mm0                     \n\t"
+
+        "movq (%%"REG_a"), %%mm2                \n\t" // L11
+        "movq %%mm2, %%mm3                      \n\t" // L11
+        "movq %%mm2, %%mm4                      \n\t" // L11
+        "psllq $8, %%mm3                        \n\t"
+        "psrlq $8, %%mm4                        \n\t"
+        "movd -4(%%"REG_a"), %%mm5              \n\t"
+        "movd 8(%%"REG_a"), %%mm6               \n\t"
+        "psrlq $24, %%mm5                       \n\t"
+        "psllq $56, %%mm6                       \n\t"
+        "por %%mm5, %%mm3                       \n\t" // L01
+        "por %%mm6, %%mm4                       \n\t" // L21
+        "movq %%mm3, %%mm5                      \n\t" // L01
+        PAVGB(%%mm4, %%mm3)                           // (L21 + L01)/2
+        PAVGB(%%mm2, %%mm3)                           // (L21 + L01 + 2L11)/4
+        "psubusb %%mm7, %%mm2                   \n\t"
+        "psubusb %%mm7, %%mm4                   \n\t"
+        "psubusb %%mm7, %%mm5                   \n\t"
+        "pcmpeqb "MANGLE(b00)", %%mm2           \n\t" // L11 > a ? 0 : -1
+        "pcmpeqb "MANGLE(b00)", %%mm4           \n\t" // L21 > a ? 0 : -1
+        "pcmpeqb "MANGLE(b00)", %%mm5           \n\t" // L01 > a ? 0 : -1
+        "paddb %%mm4, %%mm2                     \n\t"
+        "paddb %%mm5, %%mm2                     \n\t"
+// 0, 2, 3, 1
+#define REAL_DERING_CORE(dst,src,ppsx,psx,sx,pplx,plx,lx,t0,t1) \
+        "movq " #src ", " #sx "                 \n\t" /* src[0] */\
+        "movq " #sx ", " #lx "                  \n\t" /* src[0] */\
+        "movq " #sx ", " #t0 "                  \n\t" /* src[0] */\
+        "psllq $8, " #lx "                      \n\t"\
+        "psrlq $8, " #t0 "                      \n\t"\
+        "movd -4" #src ", " #t1 "               \n\t"\
+        "psrlq $24, " #t1 "                     \n\t"\
+        "por " #t1 ", " #lx "                   \n\t" /* src[-1] */\
+        "movd 8" #src ", " #t1 "                \n\t"\
+        "psllq $56, " #t1 "                     \n\t"\
+        "por " #t1 ", " #t0 "                   \n\t" /* src[+1] */\
+        "movq " #lx ", " #t1 "                  \n\t" /* src[-1] */\
+        PAVGB(t0, lx)                                 /* (src[-1] + src[+1])/2 */\
+        PAVGB(sx, lx)                                 /* (src[-1] + 2src[0] + src[+1])/4 */\
+        PAVGB(lx, pplx)                                     \
+        "movq " #lx ", 8(%4)                    \n\t"\
+        "movq (%4), " #lx "                     \n\t"\
+        "psubusb " #lx ", " #t1 "               \n\t"\
+        "psubusb " #lx ", " #t0 "               \n\t"\
+        "psubusb " #lx ", " #sx "               \n\t"\
+        "movq "MANGLE(b00)", " #lx "            \n\t"\
+        "pcmpeqb " #lx ", " #t1 "               \n\t" /* src[-1] > a ? 0 : -1*/\
+        "pcmpeqb " #lx ", " #t0 "               \n\t" /* src[+1] > a ? 0 : -1*/\
+        "pcmpeqb " #lx ", " #sx "               \n\t" /* src[0]  > a ? 0 : -1*/\
+        "paddb " #t1 ", " #t0 "                 \n\t"\
+        "paddb " #t0 ", " #sx "                 \n\t"\
+\
+        PAVGB(plx, pplx)                              /* filtered */\
+        "movq " #dst ", " #t0 "                 \n\t" /* dst */\
+        "movq " #t0 ", " #t1 "                  \n\t" /* dst */\
+        "psubusb %3, " #t0 "                    \n\t"\
+        "paddusb %3, " #t1 "                    \n\t"\
+        PMAXUB(t0, pplx)\
+        PMINUB(t1, pplx, t0)\
+        "paddb " #sx ", " #ppsx "               \n\t"\
+        "paddb " #psx ", " #ppsx "              \n\t"\
+        "#paddb "MANGLE(b02)", " #ppsx "        \n\t"\
+        "pand "MANGLE(b08)", " #ppsx "          \n\t"\
+        "pcmpeqb " #lx ", " #ppsx "             \n\t"\
+        "pand " #ppsx ", " #pplx "              \n\t"\
+        "pandn " #dst ", " #ppsx "              \n\t"\
+        "por " #pplx ", " #ppsx "               \n\t"\
+        "movq " #ppsx ", " #dst "               \n\t"\
+        "movq 8(%4), " #lx "                    \n\t"
+
+#define DERING_CORE(dst,src,ppsx,psx,sx,pplx,plx,lx,t0,t1) \
+   REAL_DERING_CORE(dst,src,ppsx,psx,sx,pplx,plx,lx,t0,t1)
+/*
+0000000
+1111111
+
+1111110
+1111101
+1111100
+1111011
+1111010
+1111001
+
+1111000
+1110111
+
+*/
+//DERING_CORE(dst          ,src            ,ppsx ,psx  ,sx   ,pplx ,plx  ,lx   ,t0   ,t1)
+DERING_CORE((%%REGa)       ,(%%REGa, %1)   ,%%mm0,%%mm2,%%mm4,%%mm1,%%mm3,%%mm5,%%mm6,%%mm7)
+DERING_CORE((%%REGa, %1)   ,(%%REGa, %1, 2),%%mm2,%%mm4,%%mm0,%%mm3,%%mm5,%%mm1,%%mm6,%%mm7)
+DERING_CORE((%%REGa, %1, 2),(%0, %1, 4)    ,%%mm4,%%mm0,%%mm2,%%mm5,%%mm1,%%mm3,%%mm6,%%mm7)
+DERING_CORE((%0, %1, 4)    ,(%%REGd)       ,%%mm0,%%mm2,%%mm4,%%mm1,%%mm3,%%mm5,%%mm6,%%mm7)
+DERING_CORE((%%REGd)       ,(%%REGd, %1)   ,%%mm2,%%mm4,%%mm0,%%mm3,%%mm5,%%mm1,%%mm6,%%mm7)
+DERING_CORE((%%REGd, %1)   ,(%%REGd, %1, 2),%%mm4,%%mm0,%%mm2,%%mm5,%%mm1,%%mm3,%%mm6,%%mm7)
+DERING_CORE((%%REGd, %1, 2),(%0, %1, 8)    ,%%mm0,%%mm2,%%mm4,%%mm1,%%mm3,%%mm5,%%mm6,%%mm7)
+DERING_CORE((%0, %1, 8)    ,(%%REGd, %1, 4),%%mm2,%%mm4,%%mm0,%%mm3,%%mm5,%%mm1,%%mm6,%%mm7)
+
+        "1:                        \n\t"
+        : : "r" (src), "r" ((x86_reg)stride), "m" (c->pQPb), "m"(c->pQPb2), "q"(tmp)
+        : "%"REG_a, "%"REG_d
+    );
+#else //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    int y;
+    int min=255;
+    int max=0;
+    int avg;
+    uint8_t *p;
+    int s[10];
+    const int QP2= c->QP/2 + 1;
+
+    for(y=1; y<9; y++){
+        int x;
+        p= src + stride*y;
+        for(x=1; x<9; x++){
+            p++;
+            if(*p > max) max= *p;
+            if(*p < min) min= *p;
+        }
+    }
+    avg= (min + max + 1)>>1;
+
+    if(max - min <deringThreshold) return;
+
+    for(y=0; y<10; y++){
+        int t = 0;
+
+        if(src[stride*y + 0] > avg) t+= 1;
+        if(src[stride*y + 1] > avg) t+= 2;
+        if(src[stride*y + 2] > avg) t+= 4;
+        if(src[stride*y + 3] > avg) t+= 8;
+        if(src[stride*y + 4] > avg) t+= 16;
+        if(src[stride*y + 5] > avg) t+= 32;
+        if(src[stride*y + 6] > avg) t+= 64;
+        if(src[stride*y + 7] > avg) t+= 128;
+        if(src[stride*y + 8] > avg) t+= 256;
+        if(src[stride*y + 9] > avg) t+= 512;
+
+        t |= (~t)<<16;
+        t &= (t<<1) & (t>>1);
+        s[y] = t;
+    }
+
+    for(y=1; y<9; y++){
+        int t = s[y-1] & s[y] & s[y+1];
+        t|= t>>16;
+        s[y-1]= t;
+    }
+
+    for(y=1; y<9; y++){
+        int x;
+        int t = s[y-1];
+
+        p= src + stride*y;
+        for(x=1; x<9; x++){
+            p++;
+            if(t & (1<<x)){
+                int f= (*(p-stride-1)) + 2*(*(p-stride)) + (*(p-stride+1))
+                      +2*(*(p     -1)) + 4*(*p         ) + 2*(*(p     +1))
+                      +(*(p+stride-1)) + 2*(*(p+stride)) + (*(p+stride+1));
+                f= (f + 8)>>4;
+
+#ifdef DEBUG_DERING_THRESHOLD
+                    __asm__ volatile("emms\n\t":);
+                    {
+                    static long long numPixels=0;
+                    if(x!=1 && x!=8 && y!=1 && y!=8) numPixels++;
+//                    if((max-min)<20 || (max-min)*QP<200)
+//                    if((max-min)*QP < 500)
+//                    if(max-min<QP/2)
+                    if(max-min < 20){
+                        static int numSkipped=0;
+                        static int errorSum=0;
+                        static int worstQP=0;
+                        static int worstRange=0;
+                        static int worstDiff=0;
+                        int diff= (f - *p);
+                        int absDiff= FFABS(diff);
+                        int error= diff*diff;
+
+                        if(x==1 || x==8 || y==1 || y==8) continue;
+
+                        numSkipped++;
+                        if(absDiff > worstDiff){
+                            worstDiff= absDiff;
+                            worstQP= QP;
+                            worstRange= max-min;
+                        }
+                        errorSum+= error;
+
+                        if(1024LL*1024LL*1024LL % numSkipped == 0){
+                            av_log(c, AV_LOG_INFO, "sum:%1.3f, skip:%d, wQP:%d, "
+                                   "wRange:%d, wDiff:%d, relSkip:%1.3f\n",
+                                   (float)errorSum/numSkipped, numSkipped, worstQP, worstRange,
+                                   worstDiff, (float)numSkipped/numPixels);
+                        }
+                    }
+                    }
+#endif
+                    if     (*p + QP2 < f) *p= *p + QP2;
+                    else if(*p - QP2 > f) *p= *p - QP2;
+                    else *p=f;
+            }
+        }
+    }
+#ifdef DEBUG_DERING_THRESHOLD
+    if(max-min < 20){
+        for(y=1; y<9; y++){
+            int x;
+            int t = 0;
+            p= src + stride*y;
+            for(x=1; x<9; x++){
+                p++;
+                *p = FFMIN(*p + 20, 255);
+            }
+        }
+//        src[0] = src[7]=src[stride*7]=src[stride*7 + 7]=255;
+    }
+#endif
+#endif //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+}
+#endif //HAVE_ALTIVEC
+
+/**
+ * Deinterlace the given block by linearly interpolating every second line.
+ * will be called for every 8x8 block and can read & write from line 4-15
+ * lines 0-3 have been passed through the deblock / dering filters already, but can be read, too.
+ * lines 4-12 will be read into the deblocking filter and should be deinterlaced
+ */
+static inline void RENAME(deInterlaceInterpolateLinear)(uint8_t src[], int stride)
+{
+#if HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    src+= 4*stride;
+    __asm__ volatile(
+        "lea (%0, %1), %%"REG_a"                \n\t"
+        "lea (%%"REG_a", %1, 4), %%"REG_c"      \n\t"
+//      0       1       2       3       4       5       6       7       8       9
+//      %0      eax     eax+%1  eax+2%1 %0+4%1  ecx     ecx+%1  ecx+2%1 %0+8%1  ecx+4%1
+
+        "movq (%0), %%mm0                       \n\t"
+        "movq (%%"REG_a", %1), %%mm1            \n\t"
+        PAVGB(%%mm1, %%mm0)
+        "movq %%mm0, (%%"REG_a")                \n\t"
+        "movq (%0, %1, 4), %%mm0                \n\t"
+        PAVGB(%%mm0, %%mm1)
+        "movq %%mm1, (%%"REG_a", %1, 2)         \n\t"
+        "movq (%%"REG_c", %1), %%mm1            \n\t"
+        PAVGB(%%mm1, %%mm0)
+        "movq %%mm0, (%%"REG_c")                \n\t"
+        "movq (%0, %1, 8), %%mm0                \n\t"
+        PAVGB(%%mm0, %%mm1)
+        "movq %%mm1, (%%"REG_c", %1, 2)         \n\t"
+
+        : : "r" (src), "r" ((x86_reg)stride)
+        : "%"REG_a, "%"REG_c
+    );
+#else
+    int a, b, x;
+    src+= 4*stride;
+
+    for(x=0; x<2; x++){
+        a= *(uint32_t*)&src[stride*0];
+        b= *(uint32_t*)&src[stride*2];
+        *(uint32_t*)&src[stride*1]= (a|b) - (((a^b)&0xFEFEFEFEUL)>>1);
+        a= *(uint32_t*)&src[stride*4];
+        *(uint32_t*)&src[stride*3]= (a|b) - (((a^b)&0xFEFEFEFEUL)>>1);
+        b= *(uint32_t*)&src[stride*6];
+        *(uint32_t*)&src[stride*5]= (a|b) - (((a^b)&0xFEFEFEFEUL)>>1);
+        a= *(uint32_t*)&src[stride*8];
+        *(uint32_t*)&src[stride*7]= (a|b) - (((a^b)&0xFEFEFEFEUL)>>1);
+        src += 4;
+    }
+#endif
+}
+
+/**
+ * Deinterlace the given block by cubic interpolating every second line.
+ * will be called for every 8x8 block and can read & write from line 4-15
+ * lines 0-3 have been passed through the deblock / dering filters already, but can be read, too.
+ * lines 4-12 will be read into the deblocking filter and should be deinterlaced
+ * this filter will read lines 3-15 and write 7-13
+ */
+static inline void RENAME(deInterlaceInterpolateCubic)(uint8_t src[], int stride)
+{
+#if HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    src+= stride*3;
+    __asm__ volatile(
+        "lea (%0, %1), %%"REG_a"                \n\t"
+        "lea (%%"REG_a", %1, 4), %%"REG_d"      \n\t"
+        "lea (%%"REG_d", %1, 4), %%"REG_c"      \n\t"
+        "add %1, %%"REG_c"                      \n\t"
+        "pxor %%mm7, %%mm7                      \n\t"
+//      0       1       2       3       4       5       6       7       8       9       10
+//      %0      eax     eax+%1  eax+2%1 %0+4%1  edx     edx+%1  edx+2%1 %0+8%1  edx+4%1 ecx
+
+#define REAL_DEINT_CUBIC(a,b,c,d,e)\
+        "movq " #a ", %%mm0                     \n\t"\
+        "movq " #b ", %%mm1                     \n\t"\
+        "movq " #d ", %%mm2                     \n\t"\
+        "movq " #e ", %%mm3                     \n\t"\
+        PAVGB(%%mm2, %%mm1)                             /* (b+d) /2 */\
+        PAVGB(%%mm3, %%mm0)                             /* a(a+e) /2 */\
+        "movq %%mm0, %%mm2                      \n\t"\
+        "punpcklbw %%mm7, %%mm0                 \n\t"\
+        "punpckhbw %%mm7, %%mm2                 \n\t"\
+        "movq %%mm1, %%mm3                      \n\t"\
+        "punpcklbw %%mm7, %%mm1                 \n\t"\
+        "punpckhbw %%mm7, %%mm3                 \n\t"\
+        "psubw %%mm1, %%mm0                     \n\t"   /* L(a+e - (b+d))/2 */\
+        "psubw %%mm3, %%mm2                     \n\t"   /* H(a+e - (b+d))/2 */\
+        "psraw $3, %%mm0                        \n\t"   /* L(a+e - (b+d))/16 */\
+        "psraw $3, %%mm2                        \n\t"   /* H(a+e - (b+d))/16 */\
+        "psubw %%mm0, %%mm1                     \n\t"   /* L(9b + 9d - a - e)/16 */\
+        "psubw %%mm2, %%mm3                     \n\t"   /* H(9b + 9d - a - e)/16 */\
+        "packuswb %%mm3, %%mm1                  \n\t"\
+        "movq %%mm1, " #c "                     \n\t"
+#define DEINT_CUBIC(a,b,c,d,e)  REAL_DEINT_CUBIC(a,b,c,d,e)
+
+DEINT_CUBIC((%0)        , (%%REGa, %1), (%%REGa, %1, 2), (%0, %1, 4) , (%%REGd, %1))
+DEINT_CUBIC((%%REGa, %1), (%0, %1, 4) , (%%REGd)       , (%%REGd, %1), (%0, %1, 8))
+DEINT_CUBIC((%0, %1, 4) , (%%REGd, %1), (%%REGd, %1, 2), (%0, %1, 8) , (%%REGc))
+DEINT_CUBIC((%%REGd, %1), (%0, %1, 8) , (%%REGd, %1, 4), (%%REGc)    , (%%REGc, %1, 2))
+
+        : : "r" (src), "r" ((x86_reg)stride)
+        : "%"REG_a, "%"REG_d, "%"REG_c
+    );
+#else //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    int x;
+    src+= stride*3;
+    for(x=0; x<8; x++){
+        src[stride*3] = CLIP((-src[0]        + 9*src[stride*2] + 9*src[stride*4] - src[stride*6])>>4);
+        src[stride*5] = CLIP((-src[stride*2] + 9*src[stride*4] + 9*src[stride*6] - src[stride*8])>>4);
+        src[stride*7] = CLIP((-src[stride*4] + 9*src[stride*6] + 9*src[stride*8] - src[stride*10])>>4);
+        src[stride*9] = CLIP((-src[stride*6] + 9*src[stride*8] + 9*src[stride*10] - src[stride*12])>>4);
+        src++;
+    }
+#endif //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+}
+
+/**
+ * Deinterlace the given block by filtering every second line with a (-1 4 2 4 -1) filter.
+ * will be called for every 8x8 block and can read & write from line 4-15
+ * lines 0-3 have been passed through the deblock / dering filters already, but can be read, too.
+ * lines 4-12 will be read into the deblocking filter and should be deinterlaced
+ * this filter will read lines 4-13 and write 5-11
+ */
+static inline void RENAME(deInterlaceFF)(uint8_t src[], int stride, uint8_t *tmp)
+{
+#if HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    src+= stride*4;
+    __asm__ volatile(
+        "lea (%0, %1), %%"REG_a"                \n\t"
+        "lea (%%"REG_a", %1, 4), %%"REG_d"      \n\t"
+        "pxor %%mm7, %%mm7                      \n\t"
+        "movq (%2), %%mm0                       \n\t"
+//      0       1       2       3       4       5       6       7       8       9       10
+//      %0      eax     eax+%1  eax+2%1 %0+4%1  edx     edx+%1  edx+2%1 %0+8%1  edx+4%1 ecx
+
+#define REAL_DEINT_FF(a,b,c,d)\
+        "movq " #a ", %%mm1                     \n\t"\
+        "movq " #b ", %%mm2                     \n\t"\
+        "movq " #c ", %%mm3                     \n\t"\
+        "movq " #d ", %%mm4                     \n\t"\
+        PAVGB(%%mm3, %%mm1)                          \
+        PAVGB(%%mm4, %%mm0)                          \
+        "movq %%mm0, %%mm3                      \n\t"\
+        "punpcklbw %%mm7, %%mm0                 \n\t"\
+        "punpckhbw %%mm7, %%mm3                 \n\t"\
+        "movq %%mm1, %%mm4                      \n\t"\
+        "punpcklbw %%mm7, %%mm1                 \n\t"\
+        "punpckhbw %%mm7, %%mm4                 \n\t"\
+        "psllw $2, %%mm1                        \n\t"\
+        "psllw $2, %%mm4                        \n\t"\
+        "psubw %%mm0, %%mm1                     \n\t"\
+        "psubw %%mm3, %%mm4                     \n\t"\
+        "movq %%mm2, %%mm5                      \n\t"\
+        "movq %%mm2, %%mm0                      \n\t"\
+        "punpcklbw %%mm7, %%mm2                 \n\t"\
+        "punpckhbw %%mm7, %%mm5                 \n\t"\
+        "paddw %%mm2, %%mm1                     \n\t"\
+        "paddw %%mm5, %%mm4                     \n\t"\
+        "psraw $2, %%mm1                        \n\t"\
+        "psraw $2, %%mm4                        \n\t"\
+        "packuswb %%mm4, %%mm1                  \n\t"\
+        "movq %%mm1, " #b "                     \n\t"\
+
+#define DEINT_FF(a,b,c,d)  REAL_DEINT_FF(a,b,c,d)
+
+DEINT_FF((%0)        , (%%REGa)       , (%%REGa, %1), (%%REGa, %1, 2))
+DEINT_FF((%%REGa, %1), (%%REGa, %1, 2), (%0, %1, 4) , (%%REGd)       )
+DEINT_FF((%0, %1, 4) , (%%REGd)       , (%%REGd, %1), (%%REGd, %1, 2))
+DEINT_FF((%%REGd, %1), (%%REGd, %1, 2), (%0, %1, 8) , (%%REGd, %1, 4))
+
+        "movq %%mm0, (%2)                       \n\t"
+        : : "r" (src), "r" ((x86_reg)stride), "r"(tmp)
+        : "%"REG_a, "%"REG_d
+    );
+#else //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    int x;
+    src+= stride*4;
+    for(x=0; x<8; x++){
+        int t1= tmp[x];
+        int t2= src[stride*1];
+
+        src[stride*1]= CLIP((-t1 + 4*src[stride*0] + 2*t2 + 4*src[stride*2] - src[stride*3] + 4)>>3);
+        t1= src[stride*4];
+        src[stride*3]= CLIP((-t2 + 4*src[stride*2] + 2*t1 + 4*src[stride*4] - src[stride*5] + 4)>>3);
+        t2= src[stride*6];
+        src[stride*5]= CLIP((-t1 + 4*src[stride*4] + 2*t2 + 4*src[stride*6] - src[stride*7] + 4)>>3);
+        t1= src[stride*8];
+        src[stride*7]= CLIP((-t2 + 4*src[stride*6] + 2*t1 + 4*src[stride*8] - src[stride*9] + 4)>>3);
+        tmp[x]= t1;
+
+        src++;
+    }
+#endif //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+}
+
+/**
+ * Deinterlace the given block by filtering every line with a (-1 2 6 2 -1) filter.
+ * will be called for every 8x8 block and can read & write from line 4-15
+ * lines 0-3 have been passed through the deblock / dering filters already, but can be read, too.
+ * lines 4-12 will be read into the deblocking filter and should be deinterlaced
+ * this filter will read lines 4-13 and write 4-11
+ */
+static inline void RENAME(deInterlaceL5)(uint8_t src[], int stride, uint8_t *tmp, uint8_t *tmp2)
+{
+#if HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    src+= stride*4;
+    __asm__ volatile(
+        "lea (%0, %1), %%"REG_a"                \n\t"
+        "lea (%%"REG_a", %1, 4), %%"REG_d"      \n\t"
+        "pxor %%mm7, %%mm7                      \n\t"
+        "movq (%2), %%mm0                       \n\t"
+        "movq (%3), %%mm1                       \n\t"
+//      0       1       2       3       4       5       6       7       8       9       10
+//      %0      eax     eax+%1  eax+2%1 %0+4%1  edx     edx+%1  edx+2%1 %0+8%1  edx+4%1 ecx
+
+#define REAL_DEINT_L5(t1,t2,a,b,c)\
+        "movq " #a ", %%mm2                     \n\t"\
+        "movq " #b ", %%mm3                     \n\t"\
+        "movq " #c ", %%mm4                     \n\t"\
+        PAVGB(t2, %%mm3)                             \
+        PAVGB(t1, %%mm4)                             \
+        "movq %%mm2, %%mm5                      \n\t"\
+        "movq %%mm2, " #t1 "                    \n\t"\
+        "punpcklbw %%mm7, %%mm2                 \n\t"\
+        "punpckhbw %%mm7, %%mm5                 \n\t"\
+        "movq %%mm2, %%mm6                      \n\t"\
+        "paddw %%mm2, %%mm2                     \n\t"\
+        "paddw %%mm6, %%mm2                     \n\t"\
+        "movq %%mm5, %%mm6                      \n\t"\
+        "paddw %%mm5, %%mm5                     \n\t"\
+        "paddw %%mm6, %%mm5                     \n\t"\
+        "movq %%mm3, %%mm6                      \n\t"\
+        "punpcklbw %%mm7, %%mm3                 \n\t"\
+        "punpckhbw %%mm7, %%mm6                 \n\t"\
+        "paddw %%mm3, %%mm3                     \n\t"\
+        "paddw %%mm6, %%mm6                     \n\t"\
+        "paddw %%mm3, %%mm2                     \n\t"\
+        "paddw %%mm6, %%mm5                     \n\t"\
+        "movq %%mm4, %%mm6                      \n\t"\
+        "punpcklbw %%mm7, %%mm4                 \n\t"\
+        "punpckhbw %%mm7, %%mm6                 \n\t"\
+        "psubw %%mm4, %%mm2                     \n\t"\
+        "psubw %%mm6, %%mm5                     \n\t"\
+        "psraw $2, %%mm2                        \n\t"\
+        "psraw $2, %%mm5                        \n\t"\
+        "packuswb %%mm5, %%mm2                  \n\t"\
+        "movq %%mm2, " #a "                     \n\t"\
+
+#define DEINT_L5(t1,t2,a,b,c)  REAL_DEINT_L5(t1,t2,a,b,c)
+
+DEINT_L5(%%mm0, %%mm1, (%0)           , (%%REGa)       , (%%REGa, %1)   )
+DEINT_L5(%%mm1, %%mm0, (%%REGa)       , (%%REGa, %1)   , (%%REGa, %1, 2))
+DEINT_L5(%%mm0, %%mm1, (%%REGa, %1)   , (%%REGa, %1, 2), (%0, %1, 4)   )
+DEINT_L5(%%mm1, %%mm0, (%%REGa, %1, 2), (%0, %1, 4)    , (%%REGd)       )
+DEINT_L5(%%mm0, %%mm1, (%0, %1, 4)    , (%%REGd)       , (%%REGd, %1)   )
+DEINT_L5(%%mm1, %%mm0, (%%REGd)       , (%%REGd, %1)   , (%%REGd, %1, 2))
+DEINT_L5(%%mm0, %%mm1, (%%REGd, %1)   , (%%REGd, %1, 2), (%0, %1, 8)   )
+DEINT_L5(%%mm1, %%mm0, (%%REGd, %1, 2), (%0, %1, 8)    , (%%REGd, %1, 4))
+
+        "movq %%mm0, (%2)                       \n\t"
+        "movq %%mm1, (%3)                       \n\t"
+        : : "r" (src), "r" ((x86_reg)stride), "r"(tmp), "r"(tmp2)
+        : "%"REG_a, "%"REG_d
+    );
+#else //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    int x;
+    src+= stride*4;
+    for(x=0; x<8; x++){
+        int t1= tmp[x];
+        int t2= tmp2[x];
+        int t3= src[0];
+
+        src[stride*0]= CLIP((-(t1 + src[stride*2]) + 2*(t2 + src[stride*1]) + 6*t3 + 4)>>3);
+        t1= src[stride*1];
+        src[stride*1]= CLIP((-(t2 + src[stride*3]) + 2*(t3 + src[stride*2]) + 6*t1 + 4)>>3);
+        t2= src[stride*2];
+        src[stride*2]= CLIP((-(t3 + src[stride*4]) + 2*(t1 + src[stride*3]) + 6*t2 + 4)>>3);
+        t3= src[stride*3];
+        src[stride*3]= CLIP((-(t1 + src[stride*5]) + 2*(t2 + src[stride*4]) + 6*t3 + 4)>>3);
+        t1= src[stride*4];
+        src[stride*4]= CLIP((-(t2 + src[stride*6]) + 2*(t3 + src[stride*5]) + 6*t1 + 4)>>3);
+        t2= src[stride*5];
+        src[stride*5]= CLIP((-(t3 + src[stride*7]) + 2*(t1 + src[stride*6]) + 6*t2 + 4)>>3);
+        t3= src[stride*6];
+        src[stride*6]= CLIP((-(t1 + src[stride*8]) + 2*(t2 + src[stride*7]) + 6*t3 + 4)>>3);
+        t1= src[stride*7];
+        src[stride*7]= CLIP((-(t2 + src[stride*9]) + 2*(t3 + src[stride*8]) + 6*t1 + 4)>>3);
+
+        tmp[x]= t3;
+        tmp2[x]= t1;
+
+        src++;
+    }
+#endif //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+}
+
+/**
+ * Deinterlace the given block by filtering all lines with a (1 2 1) filter.
+ * will be called for every 8x8 block and can read & write from line 4-15
+ * lines 0-3 have been passed through the deblock / dering filters already, but can be read, too.
+ * lines 4-12 will be read into the deblocking filter and should be deinterlaced
+ * this filter will read lines 4-13 and write 4-11
+ */
+static inline void RENAME(deInterlaceBlendLinear)(uint8_t src[], int stride, uint8_t *tmp)
+{
+#if HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    src+= 4*stride;
+    __asm__ volatile(
+        "lea (%0, %1), %%"REG_a"                \n\t"
+        "lea (%%"REG_a", %1, 4), %%"REG_d"      \n\t"
+//      0       1       2       3       4       5       6       7       8       9
+//      %0      eax     eax+%1  eax+2%1 %0+4%1  edx     edx+%1  edx+2%1 %0+8%1  edx+4%1
+
+        "movq (%2), %%mm0                       \n\t" // L0
+        "movq (%%"REG_a"), %%mm1                \n\t" // L2
+        PAVGB(%%mm1, %%mm0)                           // L0+L2
+        "movq (%0), %%mm2                       \n\t" // L1
+        PAVGB(%%mm2, %%mm0)
+        "movq %%mm0, (%0)                       \n\t"
+        "movq (%%"REG_a", %1), %%mm0            \n\t" // L3
+        PAVGB(%%mm0, %%mm2)                           // L1+L3
+        PAVGB(%%mm1, %%mm2)                           // 2L2 + L1 + L3
+        "movq %%mm2, (%%"REG_a")                \n\t"
+        "movq (%%"REG_a", %1, 2), %%mm2         \n\t" // L4
+        PAVGB(%%mm2, %%mm1)                           // L2+L4
+        PAVGB(%%mm0, %%mm1)                           // 2L3 + L2 + L4
+        "movq %%mm1, (%%"REG_a", %1)            \n\t"
+        "movq (%0, %1, 4), %%mm1                \n\t" // L5
+        PAVGB(%%mm1, %%mm0)                           // L3+L5
+        PAVGB(%%mm2, %%mm0)                           // 2L4 + L3 + L5
+        "movq %%mm0, (%%"REG_a", %1, 2)         \n\t"
+        "movq (%%"REG_d"), %%mm0                \n\t" // L6
+        PAVGB(%%mm0, %%mm2)                           // L4+L6
+        PAVGB(%%mm1, %%mm2)                           // 2L5 + L4 + L6
+        "movq %%mm2, (%0, %1, 4)                \n\t"
+        "movq (%%"REG_d", %1), %%mm2            \n\t" // L7
+        PAVGB(%%mm2, %%mm1)                           // L5+L7
+        PAVGB(%%mm0, %%mm1)                           // 2L6 + L5 + L7
+        "movq %%mm1, (%%"REG_d")                \n\t"
+        "movq (%%"REG_d", %1, 2), %%mm1         \n\t" // L8
+        PAVGB(%%mm1, %%mm0)                           // L6+L8
+        PAVGB(%%mm2, %%mm0)                           // 2L7 + L6 + L8
+        "movq %%mm0, (%%"REG_d", %1)            \n\t"
+        "movq (%0, %1, 8), %%mm0                \n\t" // L9
+        PAVGB(%%mm0, %%mm2)                           // L7+L9
+        PAVGB(%%mm1, %%mm2)                           // 2L8 + L7 + L9
+        "movq %%mm2, (%%"REG_d", %1, 2)         \n\t"
+        "movq %%mm1, (%2)                       \n\t"
+
+        : : "r" (src), "r" ((x86_reg)stride), "r" (tmp)
+        : "%"REG_a, "%"REG_d
+    );
+#else //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    int a, b, c, x;
+    src+= 4*stride;
+
+    for(x=0; x<2; x++){
+        a= *(uint32_t*)&tmp[stride*0];
+        b= *(uint32_t*)&src[stride*0];
+        c= *(uint32_t*)&src[stride*1];
+        a= (a&c) + (((a^c)&0xFEFEFEFEUL)>>1);
+        *(uint32_t*)&src[stride*0]= (a|b) - (((a^b)&0xFEFEFEFEUL)>>1);
+
+        a= *(uint32_t*)&src[stride*2];
+        b= (a&b) + (((a^b)&0xFEFEFEFEUL)>>1);
+        *(uint32_t*)&src[stride*1]= (c|b) - (((c^b)&0xFEFEFEFEUL)>>1);
+
+        b= *(uint32_t*)&src[stride*3];
+        c= (b&c) + (((b^c)&0xFEFEFEFEUL)>>1);
+        *(uint32_t*)&src[stride*2]= (c|a) - (((c^a)&0xFEFEFEFEUL)>>1);
+
+        c= *(uint32_t*)&src[stride*4];
+        a= (a&c) + (((a^c)&0xFEFEFEFEUL)>>1);
+        *(uint32_t*)&src[stride*3]= (a|b) - (((a^b)&0xFEFEFEFEUL)>>1);
+
+        a= *(uint32_t*)&src[stride*5];
+        b= (a&b) + (((a^b)&0xFEFEFEFEUL)>>1);
+        *(uint32_t*)&src[stride*4]= (c|b) - (((c^b)&0xFEFEFEFEUL)>>1);
+
+        b= *(uint32_t*)&src[stride*6];
+        c= (b&c) + (((b^c)&0xFEFEFEFEUL)>>1);
+        *(uint32_t*)&src[stride*5]= (c|a) - (((c^a)&0xFEFEFEFEUL)>>1);
+
+        c= *(uint32_t*)&src[stride*7];
+        a= (a&c) + (((a^c)&0xFEFEFEFEUL)>>1);
+        *(uint32_t*)&src[stride*6]= (a|b) - (((a^b)&0xFEFEFEFEUL)>>1);
+
+        a= *(uint32_t*)&src[stride*8];
+        b= (a&b) + (((a^b)&0xFEFEFEFEUL)>>1);
+        *(uint32_t*)&src[stride*7]= (c|b) - (((c^b)&0xFEFEFEFEUL)>>1);
+
+        *(uint32_t*)&tmp[stride*0]= c;
+        src += 4;
+        tmp += 4;
+    }
+#endif //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+}
+
+/**
+ * Deinterlace the given block by applying a median filter to every second line.
+ * will be called for every 8x8 block and can read & write from line 4-15,
+ * lines 0-3 have been passed through the deblock / dering filters already, but can be read, too.
+ * lines 4-12 will be read into the deblocking filter and should be deinterlaced
+ */
+static inline void RENAME(deInterlaceMedian)(uint8_t src[], int stride)
+{
+#if HAVE_MMX_INLINE
+    src+= 4*stride;
+#if HAVE_MMXEXT_INLINE
+    __asm__ volatile(
+        "lea (%0, %1), %%"REG_a"                \n\t"
+        "lea (%%"REG_a", %1, 4), %%"REG_d"      \n\t"
+//      0       1       2       3       4       5       6       7       8       9
+//      %0      eax     eax+%1  eax+2%1 %0+4%1  edx     edx+%1  edx+2%1 %0+8%1  edx+4%1
+
+        "movq (%0), %%mm0                       \n\t" //
+        "movq (%%"REG_a", %1), %%mm2            \n\t" //
+        "movq (%%"REG_a"), %%mm1                \n\t" //
+        "movq %%mm0, %%mm3                      \n\t"
+        "pmaxub %%mm1, %%mm0                    \n\t" //
+        "pminub %%mm3, %%mm1                    \n\t" //
+        "pmaxub %%mm2, %%mm1                    \n\t" //
+        "pminub %%mm1, %%mm0                    \n\t"
+        "movq %%mm0, (%%"REG_a")                \n\t"
+
+        "movq (%0, %1, 4), %%mm0                \n\t" //
+        "movq (%%"REG_a", %1, 2), %%mm1         \n\t" //
+        "movq %%mm2, %%mm3                      \n\t"
+        "pmaxub %%mm1, %%mm2                    \n\t" //
+        "pminub %%mm3, %%mm1                    \n\t" //
+        "pmaxub %%mm0, %%mm1                    \n\t" //
+        "pminub %%mm1, %%mm2                    \n\t"
+        "movq %%mm2, (%%"REG_a", %1, 2)         \n\t"
+
+        "movq (%%"REG_d"), %%mm2                \n\t" //
+        "movq (%%"REG_d", %1), %%mm1            \n\t" //
+        "movq %%mm2, %%mm3                      \n\t"
+        "pmaxub %%mm0, %%mm2                    \n\t" //
+        "pminub %%mm3, %%mm0                    \n\t" //
+        "pmaxub %%mm1, %%mm0                    \n\t" //
+        "pminub %%mm0, %%mm2                    \n\t"
+        "movq %%mm2, (%%"REG_d")                \n\t"
+
+        "movq (%%"REG_d", %1, 2), %%mm2         \n\t" //
+        "movq (%0, %1, 8), %%mm0                \n\t" //
+        "movq %%mm2, %%mm3                      \n\t"
+        "pmaxub %%mm0, %%mm2                    \n\t" //
+        "pminub %%mm3, %%mm0                    \n\t" //
+        "pmaxub %%mm1, %%mm0                    \n\t" //
+        "pminub %%mm0, %%mm2                    \n\t"
+        "movq %%mm2, (%%"REG_d", %1, 2)         \n\t"
+
+
+        : : "r" (src), "r" ((x86_reg)stride)
+        : "%"REG_a, "%"REG_d
+    );
+
+#else // MMX without MMX2
+    __asm__ volatile(
+        "lea (%0, %1), %%"REG_a"                \n\t"
+        "lea (%%"REG_a", %1, 4), %%"REG_d"      \n\t"
+//      0       1       2       3       4       5       6       7       8       9
+//      %0      eax     eax+%1  eax+2%1 %0+4%1  edx     edx+%1  edx+2%1 %0+8%1  edx+4%1
+        "pxor %%mm7, %%mm7                      \n\t"
+
+#define REAL_MEDIAN(a,b,c)\
+        "movq " #a ", %%mm0                     \n\t"\
+        "movq " #b ", %%mm2                     \n\t"\
+        "movq " #c ", %%mm1                     \n\t"\
+        "movq %%mm0, %%mm3                      \n\t"\
+        "movq %%mm1, %%mm4                      \n\t"\
+        "movq %%mm2, %%mm5                      \n\t"\
+        "psubusb %%mm1, %%mm3                   \n\t"\
+        "psubusb %%mm2, %%mm4                   \n\t"\
+        "psubusb %%mm0, %%mm5                   \n\t"\
+        "pcmpeqb %%mm7, %%mm3                   \n\t"\
+        "pcmpeqb %%mm7, %%mm4                   \n\t"\
+        "pcmpeqb %%mm7, %%mm5                   \n\t"\
+        "movq %%mm3, %%mm6                      \n\t"\
+        "pxor %%mm4, %%mm3                      \n\t"\
+        "pxor %%mm5, %%mm4                      \n\t"\
+        "pxor %%mm6, %%mm5                      \n\t"\
+        "por %%mm3, %%mm1                       \n\t"\
+        "por %%mm4, %%mm2                       \n\t"\
+        "por %%mm5, %%mm0                       \n\t"\
+        "pand %%mm2, %%mm0                      \n\t"\
+        "pand %%mm1, %%mm0                      \n\t"\
+        "movq %%mm0, " #b "                     \n\t"
+#define MEDIAN(a,b,c)  REAL_MEDIAN(a,b,c)
+
+MEDIAN((%0)        , (%%REGa)       , (%%REGa, %1))
+MEDIAN((%%REGa, %1), (%%REGa, %1, 2), (%0, %1, 4))
+MEDIAN((%0, %1, 4) , (%%REGd)       , (%%REGd, %1))
+MEDIAN((%%REGd, %1), (%%REGd, %1, 2), (%0, %1, 8))
+
+        : : "r" (src), "r" ((x86_reg)stride)
+        : "%"REG_a, "%"REG_d
+    );
+#endif //HAVE_MMXEXT_INLINE
+#else //HAVE_MMX_INLINE
+    int x, y;
+    src+= 4*stride;
+    // FIXME - there should be a way to do a few columns in parallel like w/mmx
+    for(x=0; x<8; x++){
+        uint8_t *colsrc = src;
+        for (y=0; y<4; y++){
+            int a, b, c, d, e, f;
+            a = colsrc[0       ];
+            b = colsrc[stride  ];
+            c = colsrc[stride*2];
+            d = (a-b)>>31;
+            e = (b-c)>>31;
+            f = (c-a)>>31;
+            colsrc[stride  ] = (a|(d^f)) & (b|(d^e)) & (c|(e^f));
+            colsrc += stride*2;
+        }
+        src++;
+    }
+#endif //HAVE_MMX_INLINE
+}
+
+#if HAVE_MMX_INLINE
+/**
+ * Transpose and shift the given 8x8 Block into dst1 and dst2.
+ */
+static inline void RENAME(transpose1)(uint8_t *dst1, uint8_t *dst2, uint8_t *src, int srcStride)
+{
+    __asm__(
+        "lea (%0, %1), %%"REG_a"                \n\t"
+//      0       1       2       3       4       5       6       7       8       9
+//      %0      eax     eax+%1  eax+2%1 %0+4%1  edx     edx+%1  edx+2%1 %0+8%1  edx+4%1
+        "movq (%0), %%mm0                       \n\t" // 12345678
+        "movq (%%"REG_a"), %%mm1                \n\t" // abcdefgh
+        "movq %%mm0, %%mm2                      \n\t" // 12345678
+        "punpcklbw %%mm1, %%mm0                 \n\t" // 1a2b3c4d
+        "punpckhbw %%mm1, %%mm2                 \n\t" // 5e6f7g8h
+
+        "movq (%%"REG_a", %1), %%mm1            \n\t"
+        "movq (%%"REG_a", %1, 2), %%mm3         \n\t"
+        "movq %%mm1, %%mm4                      \n\t"
+        "punpcklbw %%mm3, %%mm1                 \n\t"
+        "punpckhbw %%mm3, %%mm4                 \n\t"
+
+        "movq %%mm0, %%mm3                      \n\t"
+        "punpcklwd %%mm1, %%mm0                 \n\t"
+        "punpckhwd %%mm1, %%mm3                 \n\t"
+        "movq %%mm2, %%mm1                      \n\t"
+        "punpcklwd %%mm4, %%mm2                 \n\t"
+        "punpckhwd %%mm4, %%mm1                 \n\t"
+
+        "movd %%mm0, 128(%2)                    \n\t"
+        "psrlq $32, %%mm0                       \n\t"
+        "movd %%mm0, 144(%2)                    \n\t"
+        "movd %%mm3, 160(%2)                    \n\t"
+        "psrlq $32, %%mm3                       \n\t"
+        "movd %%mm3, 176(%2)                    \n\t"
+        "movd %%mm3, 48(%3)                     \n\t"
+        "movd %%mm2, 192(%2)                    \n\t"
+        "movd %%mm2, 64(%3)                     \n\t"
+        "psrlq $32, %%mm2                       \n\t"
+        "movd %%mm2, 80(%3)                     \n\t"
+        "movd %%mm1, 96(%3)                     \n\t"
+        "psrlq $32, %%mm1                       \n\t"
+        "movd %%mm1, 112(%3)                    \n\t"
+
+        "lea (%%"REG_a", %1, 4), %%"REG_a"      \n\t"
+
+        "movq (%0, %1, 4), %%mm0                \n\t" // 12345678
+        "movq (%%"REG_a"), %%mm1                \n\t" // abcdefgh
+        "movq %%mm0, %%mm2                      \n\t" // 12345678
+        "punpcklbw %%mm1, %%mm0                 \n\t" // 1a2b3c4d
+        "punpckhbw %%mm1, %%mm2                 \n\t" // 5e6f7g8h
+
+        "movq (%%"REG_a", %1), %%mm1            \n\t"
+        "movq (%%"REG_a", %1, 2), %%mm3         \n\t"
+        "movq %%mm1, %%mm4                      \n\t"
+        "punpcklbw %%mm3, %%mm1                 \n\t"
+        "punpckhbw %%mm3, %%mm4                 \n\t"
+
+        "movq %%mm0, %%mm3                      \n\t"
+        "punpcklwd %%mm1, %%mm0                 \n\t"
+        "punpckhwd %%mm1, %%mm3                 \n\t"
+        "movq %%mm2, %%mm1                      \n\t"
+        "punpcklwd %%mm4, %%mm2                 \n\t"
+        "punpckhwd %%mm4, %%mm1                 \n\t"
+
+        "movd %%mm0, 132(%2)                    \n\t"
+        "psrlq $32, %%mm0                       \n\t"
+        "movd %%mm0, 148(%2)                    \n\t"
+        "movd %%mm3, 164(%2)                    \n\t"
+        "psrlq $32, %%mm3                       \n\t"
+        "movd %%mm3, 180(%2)                    \n\t"
+        "movd %%mm3, 52(%3)                     \n\t"
+        "movd %%mm2, 196(%2)                    \n\t"
+        "movd %%mm2, 68(%3)                     \n\t"
+        "psrlq $32, %%mm2                       \n\t"
+        "movd %%mm2, 84(%3)                     \n\t"
+        "movd %%mm1, 100(%3)                    \n\t"
+        "psrlq $32, %%mm1                       \n\t"
+        "movd %%mm1, 116(%3)                    \n\t"
+
+
+        :: "r" (src), "r" ((x86_reg)srcStride), "r" (dst1), "r" (dst2)
+        : "%"REG_a
+    );
+}
+
+/**
+ * Transpose the given 8x8 block.
+ */
+static inline void RENAME(transpose2)(uint8_t *dst, int dstStride, uint8_t *src)
+{
+    __asm__(
+        "lea (%0, %1), %%"REG_a"                \n\t"
+        "lea (%%"REG_a",%1,4), %%"REG_d"        \n\t"
+//      0       1       2       3       4       5       6       7       8       9
+//      %0      eax     eax+%1  eax+2%1 %0+4%1  edx     edx+%1  edx+2%1 %0+8%1  edx+4%1
+        "movq (%2), %%mm0                       \n\t" // 12345678
+        "movq 16(%2), %%mm1                     \n\t" // abcdefgh
+        "movq %%mm0, %%mm2                      \n\t" // 12345678
+        "punpcklbw %%mm1, %%mm0                 \n\t" // 1a2b3c4d
+        "punpckhbw %%mm1, %%mm2                 \n\t" // 5e6f7g8h
+
+        "movq 32(%2), %%mm1                     \n\t"
+        "movq 48(%2), %%mm3                     \n\t"
+        "movq %%mm1, %%mm4                      \n\t"
+        "punpcklbw %%mm3, %%mm1                 \n\t"
+        "punpckhbw %%mm3, %%mm4                 \n\t"
+
+        "movq %%mm0, %%mm3                      \n\t"
+        "punpcklwd %%mm1, %%mm0                 \n\t"
+        "punpckhwd %%mm1, %%mm3                 \n\t"
+        "movq %%mm2, %%mm1                      \n\t"
+        "punpcklwd %%mm4, %%mm2                 \n\t"
+        "punpckhwd %%mm4, %%mm1                 \n\t"
+
+        "movd %%mm0, (%0)                       \n\t"
+        "psrlq $32, %%mm0                       \n\t"
+        "movd %%mm0, (%%"REG_a")                \n\t"
+        "movd %%mm3, (%%"REG_a", %1)            \n\t"
+        "psrlq $32, %%mm3                       \n\t"
+        "movd %%mm3, (%%"REG_a", %1, 2)         \n\t"
+        "movd %%mm2, (%0, %1, 4)                \n\t"
+        "psrlq $32, %%mm2                       \n\t"
+        "movd %%mm2, (%%"REG_d")                \n\t"
+        "movd %%mm1, (%%"REG_d", %1)            \n\t"
+        "psrlq $32, %%mm1                       \n\t"
+        "movd %%mm1, (%%"REG_d", %1, 2)         \n\t"
+
+
+        "movq 64(%2), %%mm0                     \n\t" // 12345678
+        "movq 80(%2), %%mm1                     \n\t" // abcdefgh
+        "movq %%mm0, %%mm2                      \n\t" // 12345678
+        "punpcklbw %%mm1, %%mm0                 \n\t" // 1a2b3c4d
+        "punpckhbw %%mm1, %%mm2                 \n\t" // 5e6f7g8h
+
+        "movq 96(%2), %%mm1                     \n\t"
+        "movq 112(%2), %%mm3                    \n\t"
+        "movq %%mm1, %%mm4                      \n\t"
+        "punpcklbw %%mm3, %%mm1                 \n\t"
+        "punpckhbw %%mm3, %%mm4                 \n\t"
+
+        "movq %%mm0, %%mm3                      \n\t"
+        "punpcklwd %%mm1, %%mm0                 \n\t"
+        "punpckhwd %%mm1, %%mm3                 \n\t"
+        "movq %%mm2, %%mm1                      \n\t"
+        "punpcklwd %%mm4, %%mm2                 \n\t"
+        "punpckhwd %%mm4, %%mm1                 \n\t"
+
+        "movd %%mm0, 4(%0)                      \n\t"
+        "psrlq $32, %%mm0                       \n\t"
+        "movd %%mm0, 4(%%"REG_a")               \n\t"
+        "movd %%mm3, 4(%%"REG_a", %1)           \n\t"
+        "psrlq $32, %%mm3                       \n\t"
+        "movd %%mm3, 4(%%"REG_a", %1, 2)        \n\t"
+        "movd %%mm2, 4(%0, %1, 4)               \n\t"
+        "psrlq $32, %%mm2                       \n\t"
+        "movd %%mm2, 4(%%"REG_d")               \n\t"
+        "movd %%mm1, 4(%%"REG_d", %1)           \n\t"
+        "psrlq $32, %%mm1                       \n\t"
+        "movd %%mm1, 4(%%"REG_d", %1, 2)        \n\t"
+
+        :: "r" (dst), "r" ((x86_reg)dstStride), "r" (src)
+        : "%"REG_a, "%"REG_d
+    );
+}
+#endif //HAVE_MMX_INLINE
+//static long test=0;
+
+#if !HAVE_ALTIVEC
+static inline void RENAME(tempNoiseReducer)(uint8_t *src, int stride,
+                                    uint8_t *tempBlurred, uint32_t *tempBlurredPast, int *maxNoise)
+{
+    // to save a register (FIXME do this outside of the loops)
+    tempBlurredPast[127]= maxNoise[0];
+    tempBlurredPast[128]= maxNoise[1];
+    tempBlurredPast[129]= maxNoise[2];
+
+#define FAST_L2_DIFF
+//#define L1_DIFF //u should change the thresholds too if u try that one
+#if HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+    __asm__ volatile(
+        "lea (%2, %2, 2), %%"REG_a"             \n\t" // 3*stride
+        "lea (%2, %2, 4), %%"REG_d"             \n\t" // 5*stride
+        "lea (%%"REG_d", %2, 2), %%"REG_c"      \n\t" // 7*stride
+//      0       1       2       3       4       5       6       7       8       9
+//      %x      %x+%2   %x+2%2  %x+eax  %x+4%2  %x+edx  %x+2eax %x+ecx  %x+8%2
+//FIXME reorder?
+#ifdef L1_DIFF //needs mmx2
+        "movq (%0), %%mm0                       \n\t" // L0
+        "psadbw (%1), %%mm0                     \n\t" // |L0-R0|
+        "movq (%0, %2), %%mm1                   \n\t" // L1
+        "psadbw (%1, %2), %%mm1                 \n\t" // |L1-R1|
+        "movq (%0, %2, 2), %%mm2                \n\t" // L2
+        "psadbw (%1, %2, 2), %%mm2              \n\t" // |L2-R2|
+        "movq (%0, %%"REG_a"), %%mm3            \n\t" // L3
+        "psadbw (%1, %%"REG_a"), %%mm3          \n\t" // |L3-R3|
+
+        "movq (%0, %2, 4), %%mm4                \n\t" // L4
+        "paddw %%mm1, %%mm0                     \n\t"
+        "psadbw (%1, %2, 4), %%mm4              \n\t" // |L4-R4|
+        "movq (%0, %%"REG_d"), %%mm5            \n\t" // L5
+        "paddw %%mm2, %%mm0                     \n\t"
+        "psadbw (%1, %%"REG_d"), %%mm5          \n\t" // |L5-R5|
+        "movq (%0, %%"REG_a", 2), %%mm6         \n\t" // L6
+        "paddw %%mm3, %%mm0                     \n\t"
+        "psadbw (%1, %%"REG_a", 2), %%mm6       \n\t" // |L6-R6|
+        "movq (%0, %%"REG_c"), %%mm7            \n\t" // L7
+        "paddw %%mm4, %%mm0                     \n\t"
+        "psadbw (%1, %%"REG_c"), %%mm7          \n\t" // |L7-R7|
+        "paddw %%mm5, %%mm6                     \n\t"
+        "paddw %%mm7, %%mm6                     \n\t"
+        "paddw %%mm6, %%mm0                     \n\t"
+#else //L1_DIFF
+#if defined (FAST_L2_DIFF)
+        "pcmpeqb %%mm7, %%mm7                   \n\t"
+        "movq "MANGLE(b80)", %%mm6              \n\t"
+        "pxor %%mm0, %%mm0                      \n\t"
+#define REAL_L2_DIFF_CORE(a, b)\
+        "movq " #a ", %%mm5                     \n\t"\
+        "movq " #b ", %%mm2                     \n\t"\
+        "pxor %%mm7, %%mm2                      \n\t"\
+        PAVGB(%%mm2, %%mm5)\
+        "paddb %%mm6, %%mm5                     \n\t"\
+        "movq %%mm5, %%mm2                      \n\t"\
+        "psllw $8, %%mm5                        \n\t"\
+        "pmaddwd %%mm5, %%mm5                   \n\t"\
+        "pmaddwd %%mm2, %%mm2                   \n\t"\
+        "paddd %%mm2, %%mm5                     \n\t"\
+        "psrld $14, %%mm5                       \n\t"\
+        "paddd %%mm5, %%mm0                     \n\t"
+
+#else //defined (FAST_L2_DIFF)
+        "pxor %%mm7, %%mm7                      \n\t"
+        "pxor %%mm0, %%mm0                      \n\t"
+#define REAL_L2_DIFF_CORE(a, b)\
+        "movq " #a ", %%mm5                     \n\t"\
+        "movq " #b ", %%mm2                     \n\t"\
+        "movq %%mm5, %%mm1                      \n\t"\
+        "movq %%mm2, %%mm3                      \n\t"\
+        "punpcklbw %%mm7, %%mm5                 \n\t"\
+        "punpckhbw %%mm7, %%mm1                 \n\t"\
+        "punpcklbw %%mm7, %%mm2                 \n\t"\
+        "punpckhbw %%mm7, %%mm3                 \n\t"\
+        "psubw %%mm2, %%mm5                     \n\t"\
+        "psubw %%mm3, %%mm1                     \n\t"\
+        "pmaddwd %%mm5, %%mm5                   \n\t"\
+        "pmaddwd %%mm1, %%mm1                   \n\t"\
+        "paddd %%mm1, %%mm5                     \n\t"\
+        "paddd %%mm5, %%mm0                     \n\t"
+
+#endif //defined (FAST_L2_DIFF)
+
+#define L2_DIFF_CORE(a, b)  REAL_L2_DIFF_CORE(a, b)
+
+L2_DIFF_CORE((%0)          , (%1))
+L2_DIFF_CORE((%0, %2)      , (%1, %2))
+L2_DIFF_CORE((%0, %2, 2)   , (%1, %2, 2))
+L2_DIFF_CORE((%0, %%REGa)  , (%1, %%REGa))
+L2_DIFF_CORE((%0, %2, 4)   , (%1, %2, 4))
+L2_DIFF_CORE((%0, %%REGd)  , (%1, %%REGd))
+L2_DIFF_CORE((%0, %%REGa,2), (%1, %%REGa,2))
+L2_DIFF_CORE((%0, %%REGc)  , (%1, %%REGc))
+
+#endif //L1_DIFF
+
+        "movq %%mm0, %%mm4                      \n\t"
+        "psrlq $32, %%mm0                       \n\t"
+        "paddd %%mm0, %%mm4                     \n\t"
+        "movd %%mm4, %%ecx                      \n\t"
+        "shll $2, %%ecx                         \n\t"
+        "mov %3, %%"REG_d"                      \n\t"
+        "addl -4(%%"REG_d"), %%ecx              \n\t"
+        "addl 4(%%"REG_d"), %%ecx               \n\t"
+        "addl -1024(%%"REG_d"), %%ecx           \n\t"
+        "addl $4, %%ecx                         \n\t"
+        "addl 1024(%%"REG_d"), %%ecx            \n\t"
+        "shrl $3, %%ecx                         \n\t"
+        "movl %%ecx, (%%"REG_d")                \n\t"
+
+//        "mov %3, %%"REG_c"                      \n\t"
+//        "mov %%"REG_c", test                    \n\t"
+//        "jmp 4f                                 \n\t"
+        "cmpl 512(%%"REG_d"), %%ecx             \n\t"
+        " jb 2f                                 \n\t"
+        "cmpl 516(%%"REG_d"), %%ecx             \n\t"
+        " jb 1f                                 \n\t"
+
+        "lea (%%"REG_a", %2, 2), %%"REG_d"      \n\t" // 5*stride
+        "lea (%%"REG_d", %2, 2), %%"REG_c"      \n\t" // 7*stride
+        "movq (%0), %%mm0                       \n\t" // L0
+        "movq (%0, %2), %%mm1                   \n\t" // L1
+        "movq (%0, %2, 2), %%mm2                \n\t" // L2
+        "movq (%0, %%"REG_a"), %%mm3            \n\t" // L3
+        "movq (%0, %2, 4), %%mm4                \n\t" // L4
+        "movq (%0, %%"REG_d"), %%mm5            \n\t" // L5
+        "movq (%0, %%"REG_a", 2), %%mm6         \n\t" // L6
+        "movq (%0, %%"REG_c"), %%mm7            \n\t" // L7
+        "movq %%mm0, (%1)                       \n\t" // L0
+        "movq %%mm1, (%1, %2)                   \n\t" // L1
+        "movq %%mm2, (%1, %2, 2)                \n\t" // L2
+        "movq %%mm3, (%1, %%"REG_a")            \n\t" // L3
+        "movq %%mm4, (%1, %2, 4)                \n\t" // L4
+        "movq %%mm5, (%1, %%"REG_d")            \n\t" // L5
+        "movq %%mm6, (%1, %%"REG_a", 2)         \n\t" // L6
+        "movq %%mm7, (%1, %%"REG_c")            \n\t" // L7
+        "jmp 4f                                 \n\t"
+
+        "1:                                     \n\t"
+        "lea (%%"REG_a", %2, 2), %%"REG_d"      \n\t" // 5*stride
+        "lea (%%"REG_d", %2, 2), %%"REG_c"      \n\t" // 7*stride
+        "movq (%0), %%mm0                       \n\t" // L0
+        PAVGB((%1), %%mm0)                            // L0
+        "movq (%0, %2), %%mm1                   \n\t" // L1
+        PAVGB((%1, %2), %%mm1)                        // L1
+        "movq (%0, %2, 2), %%mm2                \n\t" // L2
+        PAVGB((%1, %2, 2), %%mm2)                     // L2
+        "movq (%0, %%"REG_a"), %%mm3            \n\t" // L3
+        PAVGB((%1, %%REGa), %%mm3)                    // L3
+        "movq (%0, %2, 4), %%mm4                \n\t" // L4
+        PAVGB((%1, %2, 4), %%mm4)                     // L4
+        "movq (%0, %%"REG_d"), %%mm5            \n\t" // L5
+        PAVGB((%1, %%REGd), %%mm5)                    // L5
+        "movq (%0, %%"REG_a", 2), %%mm6         \n\t" // L6
+        PAVGB((%1, %%REGa, 2), %%mm6)                 // L6
+        "movq (%0, %%"REG_c"), %%mm7            \n\t" // L7
+        PAVGB((%1, %%REGc), %%mm7)                    // L7
+        "movq %%mm0, (%1)                       \n\t" // R0
+        "movq %%mm1, (%1, %2)                   \n\t" // R1
+        "movq %%mm2, (%1, %2, 2)                \n\t" // R2
+        "movq %%mm3, (%1, %%"REG_a")            \n\t" // R3
+        "movq %%mm4, (%1, %2, 4)                \n\t" // R4
+        "movq %%mm5, (%1, %%"REG_d")            \n\t" // R5
+        "movq %%mm6, (%1, %%"REG_a", 2)         \n\t" // R6
+        "movq %%mm7, (%1, %%"REG_c")            \n\t" // R7
+        "movq %%mm0, (%0)                       \n\t" // L0
+        "movq %%mm1, (%0, %2)                   \n\t" // L1
+        "movq %%mm2, (%0, %2, 2)                \n\t" // L2
+        "movq %%mm3, (%0, %%"REG_a")            \n\t" // L3
+        "movq %%mm4, (%0, %2, 4)                \n\t" // L4
+        "movq %%mm5, (%0, %%"REG_d")            \n\t" // L5
+        "movq %%mm6, (%0, %%"REG_a", 2)         \n\t" // L6
+        "movq %%mm7, (%0, %%"REG_c")            \n\t" // L7
+        "jmp 4f                                 \n\t"
+
+        "2:                                     \n\t"
+        "cmpl 508(%%"REG_d"), %%ecx             \n\t"
+        " jb 3f                                 \n\t"
+
+        "lea (%%"REG_a", %2, 2), %%"REG_d"      \n\t" // 5*stride
+        "lea (%%"REG_d", %2, 2), %%"REG_c"      \n\t" // 7*stride
+        "movq (%0), %%mm0                       \n\t" // L0
+        "movq (%0, %2), %%mm1                   \n\t" // L1
+        "movq (%0, %2, 2), %%mm2                \n\t" // L2
+        "movq (%0, %%"REG_a"), %%mm3            \n\t" // L3
+        "movq (%1), %%mm4                       \n\t" // R0
+        "movq (%1, %2), %%mm5                   \n\t" // R1
+        "movq (%1, %2, 2), %%mm6                \n\t" // R2
+        "movq (%1, %%"REG_a"), %%mm7            \n\t" // R3
+        PAVGB(%%mm4, %%mm0)
+        PAVGB(%%mm5, %%mm1)
+        PAVGB(%%mm6, %%mm2)
+        PAVGB(%%mm7, %%mm3)
+        PAVGB(%%mm4, %%mm0)
+        PAVGB(%%mm5, %%mm1)
+        PAVGB(%%mm6, %%mm2)
+        PAVGB(%%mm7, %%mm3)
+        "movq %%mm0, (%1)                       \n\t" // R0
+        "movq %%mm1, (%1, %2)                   \n\t" // R1
+        "movq %%mm2, (%1, %2, 2)                \n\t" // R2
+        "movq %%mm3, (%1, %%"REG_a")            \n\t" // R3
+        "movq %%mm0, (%0)                       \n\t" // L0
+        "movq %%mm1, (%0, %2)                   \n\t" // L1
+        "movq %%mm2, (%0, %2, 2)                \n\t" // L2
+        "movq %%mm3, (%0, %%"REG_a")            \n\t" // L3
+
+        "movq (%0, %2, 4), %%mm0                \n\t" // L4
+        "movq (%0, %%"REG_d"), %%mm1            \n\t" // L5
+        "movq (%0, %%"REG_a", 2), %%mm2         \n\t" // L6
+        "movq (%0, %%"REG_c"), %%mm3            \n\t" // L7
+        "movq (%1, %2, 4), %%mm4                \n\t" // R4
+        "movq (%1, %%"REG_d"), %%mm5            \n\t" // R5
+        "movq (%1, %%"REG_a", 2), %%mm6         \n\t" // R6
+        "movq (%1, %%"REG_c"), %%mm7            \n\t" // R7
+        PAVGB(%%mm4, %%mm0)
+        PAVGB(%%mm5, %%mm1)
+        PAVGB(%%mm6, %%mm2)
+        PAVGB(%%mm7, %%mm3)
+        PAVGB(%%mm4, %%mm0)
+        PAVGB(%%mm5, %%mm1)
+        PAVGB(%%mm6, %%mm2)
+        PAVGB(%%mm7, %%mm3)
+        "movq %%mm0, (%1, %2, 4)                \n\t" // R4
+        "movq %%mm1, (%1, %%"REG_d")            \n\t" // R5
+        "movq %%mm2, (%1, %%"REG_a", 2)         \n\t" // R6
+        "movq %%mm3, (%1, %%"REG_c")            \n\t" // R7
+        "movq %%mm0, (%0, %2, 4)                \n\t" // L4
+        "movq %%mm1, (%0, %%"REG_d")            \n\t" // L5
+        "movq %%mm2, (%0, %%"REG_a", 2)         \n\t" // L6
+        "movq %%mm3, (%0, %%"REG_c")            \n\t" // L7
+        "jmp 4f                                 \n\t"
+
+        "3:                                     \n\t"
+        "lea (%%"REG_a", %2, 2), %%"REG_d"      \n\t" // 5*stride
+        "lea (%%"REG_d", %2, 2), %%"REG_c"      \n\t" // 7*stride
+        "movq (%0), %%mm0                       \n\t" // L0
+        "movq (%0, %2), %%mm1                   \n\t" // L1
+        "movq (%0, %2, 2), %%mm2                \n\t" // L2
+        "movq (%0, %%"REG_a"), %%mm3            \n\t" // L3
+        "movq (%1), %%mm4                       \n\t" // R0
+        "movq (%1, %2), %%mm5                   \n\t" // R1
+        "movq (%1, %2, 2), %%mm6                \n\t" // R2
+        "movq (%1, %%"REG_a"), %%mm7            \n\t" // R3
+        PAVGB(%%mm4, %%mm0)
+        PAVGB(%%mm5, %%mm1)
+        PAVGB(%%mm6, %%mm2)
+        PAVGB(%%mm7, %%mm3)
+        PAVGB(%%mm4, %%mm0)
+        PAVGB(%%mm5, %%mm1)
+        PAVGB(%%mm6, %%mm2)
+        PAVGB(%%mm7, %%mm3)
+        PAVGB(%%mm4, %%mm0)
+        PAVGB(%%mm5, %%mm1)
+        PAVGB(%%mm6, %%mm2)
+        PAVGB(%%mm7, %%mm3)
+        "movq %%mm0, (%1)                       \n\t" // R0
+        "movq %%mm1, (%1, %2)                   \n\t" // R1
+        "movq %%mm2, (%1, %2, 2)                \n\t" // R2
+        "movq %%mm3, (%1, %%"REG_a")            \n\t" // R3
+        "movq %%mm0, (%0)                       \n\t" // L0
+        "movq %%mm1, (%0, %2)                   \n\t" // L1
+        "movq %%mm2, (%0, %2, 2)                \n\t" // L2
+        "movq %%mm3, (%0, %%"REG_a")            \n\t" // L3
+
+        "movq (%0, %2, 4), %%mm0                \n\t" // L4
+        "movq (%0, %%"REG_d"), %%mm1            \n\t" // L5
+        "movq (%0, %%"REG_a", 2), %%mm2         \n\t" // L6
+        "movq (%0, %%"REG_c"), %%mm3            \n\t" // L7
+        "movq (%1, %2, 4), %%mm4                \n\t" // R4
+        "movq (%1, %%"REG_d"), %%mm5            \n\t" // R5
+        "movq (%1, %%"REG_a", 2), %%mm6         \n\t" // R6
+        "movq (%1, %%"REG_c"), %%mm7            \n\t" // R7
+        PAVGB(%%mm4, %%mm0)
+        PAVGB(%%mm5, %%mm1)
+        PAVGB(%%mm6, %%mm2)
+        PAVGB(%%mm7, %%mm3)
+        PAVGB(%%mm4, %%mm0)
+        PAVGB(%%mm5, %%mm1)
+        PAVGB(%%mm6, %%mm2)
+        PAVGB(%%mm7, %%mm3)
+        PAVGB(%%mm4, %%mm0)
+        PAVGB(%%mm5, %%mm1)
+        PAVGB(%%mm6, %%mm2)
+        PAVGB(%%mm7, %%mm3)
+        "movq %%mm0, (%1, %2, 4)                \n\t" // R4
+        "movq %%mm1, (%1, %%"REG_d")            \n\t" // R5
+        "movq %%mm2, (%1, %%"REG_a", 2)         \n\t" // R6
+        "movq %%mm3, (%1, %%"REG_c")            \n\t" // R7
+        "movq %%mm0, (%0, %2, 4)                \n\t" // L4
+        "movq %%mm1, (%0, %%"REG_d")            \n\t" // L5
+        "movq %%mm2, (%0, %%"REG_a", 2)         \n\t" // L6
+        "movq %%mm3, (%0, %%"REG_c")            \n\t" // L7
+
+        "4:                                     \n\t"
+
+        :: "r" (src), "r" (tempBlurred), "r"((x86_reg)stride), "m" (tempBlurredPast)
+        : "%"REG_a, "%"REG_d, "%"REG_c, "memory"
+    );
+#else //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+{
+    int y;
+    int d=0;
+//    int sysd=0;
+    int i;
+
+    for(y=0; y<8; y++){
+        int x;
+        for(x=0; x<8; x++){
+            int ref= tempBlurred[ x + y*stride ];
+            int cur= src[ x + y*stride ];
+            int d1=ref - cur;
+//            if(x==0 || x==7) d1+= d1>>1;
+//            if(y==0 || y==7) d1+= d1>>1;
+//            d+= FFABS(d1);
+            d+= d1*d1;
+//            sysd+= d1;
+        }
+    }
+    i=d;
+    d=  (
+        4*d
+        +(*(tempBlurredPast-256))
+        +(*(tempBlurredPast-1))+ (*(tempBlurredPast+1))
+        +(*(tempBlurredPast+256))
+        +4)>>3;
+    *tempBlurredPast=i;
+//    ((*tempBlurredPast)*3 + d + 2)>>2;
+
+/*
+Switch between
+ 1  0  0  0  0  0  0  (0)
+64 32 16  8  4  2  1  (1)
+64 48 36 27 20 15 11 (33) (approx)
+64 56 49 43 37 33 29 (200) (approx)
+*/
+    if(d > maxNoise[1]){
+        if(d < maxNoise[2]){
+            for(y=0; y<8; y++){
+                int x;
+                for(x=0; x<8; x++){
+                    int ref= tempBlurred[ x + y*stride ];
+                    int cur= src[ x + y*stride ];
+                    tempBlurred[ x + y*stride ]=
+                    src[ x + y*stride ]=
+                        (ref + cur + 1)>>1;
+                }
+            }
+        }else{
+            for(y=0; y<8; y++){
+                int x;
+                for(x=0; x<8; x++){
+                    tempBlurred[ x + y*stride ]= src[ x + y*stride ];
+                }
+            }
+        }
+    }else{
+        if(d < maxNoise[0]){
+            for(y=0; y<8; y++){
+                int x;
+                for(x=0; x<8; x++){
+                    int ref= tempBlurred[ x + y*stride ];
+                    int cur= src[ x + y*stride ];
+                    tempBlurred[ x + y*stride ]=
+                    src[ x + y*stride ]=
+                        (ref*7 + cur + 4)>>3;
+                }
+            }
+        }else{
+            for(y=0; y<8; y++){
+                int x;
+                for(x=0; x<8; x++){
+                    int ref= tempBlurred[ x + y*stride ];
+                    int cur= src[ x + y*stride ];
+                    tempBlurred[ x + y*stride ]=
+                    src[ x + y*stride ]=
+                        (ref*3 + cur + 2)>>2;
+                }
+            }
+        }
+    }
+}
+#endif //HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE
+}
+#endif //HAVE_ALTIVEC
+
+#if HAVE_MMX_INLINE
+/**
+ * accurate deblock filter
+ */
+static av_always_inline void RENAME(do_a_deblock)(uint8_t *src, int step, int stride, PPContext *c){
+    int64_t dc_mask, eq_mask, both_masks;
+    int64_t sums[10*8*2];
+    src+= step*3; // src points to begin of the 8x8 Block
+    //{ START_TIMER
+    __asm__ volatile(
+        "movq %0, %%mm7                         \n\t"
+        "movq %1, %%mm6                         \n\t"
+        : : "m" (c->mmxDcOffset[c->nonBQP]),  "m" (c->mmxDcThreshold[c->nonBQP])
+        );
+
+    __asm__ volatile(
+        "lea (%2, %3), %%"REG_a"                \n\t"
+//      0       1       2       3       4       5       6       7       8       9
+//      %1      eax     eax+%2  eax+2%2 %1+4%2  ecx     ecx+%2  ecx+2%2 %1+8%2  ecx+4%2
+
+        "movq (%2), %%mm0                       \n\t"
+        "movq (%%"REG_a"), %%mm1                \n\t"
+        "movq %%mm1, %%mm3                      \n\t"
+        "movq %%mm1, %%mm4                      \n\t"
+        "psubb %%mm1, %%mm0                     \n\t" // mm0 = differnece
+        "paddb %%mm7, %%mm0                     \n\t"
+        "pcmpgtb %%mm6, %%mm0                   \n\t"
+
+        "movq (%%"REG_a",%3), %%mm2             \n\t"
+        PMAXUB(%%mm2, %%mm4)
+        PMINUB(%%mm2, %%mm3, %%mm5)
+        "psubb %%mm2, %%mm1                     \n\t"
+        "paddb %%mm7, %%mm1                     \n\t"
+        "pcmpgtb %%mm6, %%mm1                   \n\t"
+        "paddb %%mm1, %%mm0                     \n\t"
+
+        "movq (%%"REG_a", %3, 2), %%mm1         \n\t"
+        PMAXUB(%%mm1, %%mm4)
+        PMINUB(%%mm1, %%mm3, %%mm5)
+        "psubb %%mm1, %%mm2                     \n\t"
+        "paddb %%mm7, %%mm2                     \n\t"
+        "pcmpgtb %%mm6, %%mm2                   \n\t"
+        "paddb %%mm2, %%mm0                     \n\t"
+
+        "lea (%%"REG_a", %3, 4), %%"REG_a"      \n\t"
+
+        "movq (%2, %3, 4), %%mm2                \n\t"
+        PMAXUB(%%mm2, %%mm4)
+        PMINUB(%%mm2, %%mm3, %%mm5)
+        "psubb %%mm2, %%mm1                     \n\t"
+        "paddb %%mm7, %%mm1                     \n\t"
+        "pcmpgtb %%mm6, %%mm1                   \n\t"
+        "paddb %%mm1, %%mm0                     \n\t"
+
+        "movq (%%"REG_a"), %%mm1                \n\t"
+        PMAXUB(%%mm1, %%mm4)
+        PMINUB(%%mm1, %%mm3, %%mm5)
+        "psubb %%mm1, %%mm2                     \n\t"
+        "paddb %%mm7, %%mm2                     \n\t"
+        "pcmpgtb %%mm6, %%mm2                   \n\t"
+        "paddb %%mm2, %%mm0                     \n\t"
+
+        "movq (%%"REG_a", %3), %%mm2            \n\t"
+        PMAXUB(%%mm2, %%mm4)
+        PMINUB(%%mm2, %%mm3, %%mm5)
+        "psubb %%mm2, %%mm1                     \n\t"
+        "paddb %%mm7, %%mm1                     \n\t"
+        "pcmpgtb %%mm6, %%mm1                   \n\t"
+        "paddb %%mm1, %%mm0                     \n\t"
+
+        "movq (%%"REG_a", %3, 2), %%mm1         \n\t"
+        PMAXUB(%%mm1, %%mm4)
+        PMINUB(%%mm1, %%mm3, %%mm5)
+        "psubb %%mm1, %%mm2                     \n\t"
+        "paddb %%mm7, %%mm2                     \n\t"
+        "pcmpgtb %%mm6, %%mm2                   \n\t"
+        "paddb %%mm2, %%mm0                     \n\t"
+
+        "movq (%2, %3, 8), %%mm2                \n\t"
+        PMAXUB(%%mm2, %%mm4)
+        PMINUB(%%mm2, %%mm3, %%mm5)
+        "psubb %%mm2, %%mm1                     \n\t"
+        "paddb %%mm7, %%mm1                     \n\t"
+        "pcmpgtb %%mm6, %%mm1                   \n\t"
+        "paddb %%mm1, %%mm0                     \n\t"
+
+        "movq (%%"REG_a", %3, 4), %%mm1         \n\t"
+        "psubb %%mm1, %%mm2                     \n\t"
+        "paddb %%mm7, %%mm2                     \n\t"
+        "pcmpgtb %%mm6, %%mm2                   \n\t"
+        "paddb %%mm2, %%mm0                     \n\t"
+        "psubusb %%mm3, %%mm4                   \n\t"
+
+        "pxor %%mm6, %%mm6                      \n\t"
+        "movq %4, %%mm7                         \n\t" // QP,..., QP
+        "paddusb %%mm7, %%mm7                   \n\t" // 2QP ... 2QP
+        "psubusb %%mm4, %%mm7                   \n\t" // Diff >=2QP -> 0
+        "pcmpeqb %%mm6, %%mm7                   \n\t" // Diff < 2QP -> 0
+        "pcmpeqb %%mm6, %%mm7                   \n\t" // Diff < 2QP -> 0
+        "movq %%mm7, %1                         \n\t"
+
+        "movq %5, %%mm7                         \n\t"
+        "punpcklbw %%mm7, %%mm7                 \n\t"
+        "punpcklbw %%mm7, %%mm7                 \n\t"
+        "punpcklbw %%mm7, %%mm7                 \n\t"
+        "psubb %%mm0, %%mm6                     \n\t"
+        "pcmpgtb %%mm7, %%mm6                   \n\t"
+        "movq %%mm6, %0                         \n\t"
+
+        : "=m" (eq_mask), "=m" (dc_mask)
+        : "r" (src), "r" ((x86_reg)step), "m" (c->pQPb), "m"(c->ppMode.flatnessThreshold)
+        : "%"REG_a
+    );
+
+    both_masks = dc_mask & eq_mask;
+
+    if(both_masks){
+        x86_reg offset= -8*step;
+        int64_t *temp_sums= sums;
+
+        __asm__ volatile(
+            "movq %2, %%mm0                         \n\t"  // QP,..., QP
+            "pxor %%mm4, %%mm4                      \n\t"
+
+            "movq (%0), %%mm6                       \n\t"
+            "movq (%0, %1), %%mm5                   \n\t"
+            "movq %%mm5, %%mm1                      \n\t"
+            "movq %%mm6, %%mm2                      \n\t"
+            "psubusb %%mm6, %%mm5                   \n\t"
+            "psubusb %%mm1, %%mm2                   \n\t"
+            "por %%mm5, %%mm2                       \n\t" // ABS Diff of lines
+            "psubusb %%mm2, %%mm0                   \n\t" // diff >= QP -> 0
+            "pcmpeqb %%mm4, %%mm0                   \n\t" // diff >= QP -> FF
+
+            "pxor %%mm6, %%mm1                      \n\t"
+            "pand %%mm0, %%mm1                      \n\t"
+            "pxor %%mm1, %%mm6                      \n\t"
+            // 0:QP  6:First
+
+            "movq (%0, %1, 8), %%mm5                \n\t"
+            "add %1, %0                             \n\t" // %0 points to line 1 not 0
+            "movq (%0, %1, 8), %%mm7                \n\t"
+            "movq %%mm5, %%mm1                      \n\t"
+            "movq %%mm7, %%mm2                      \n\t"
+            "psubusb %%mm7, %%mm5                   \n\t"
+            "psubusb %%mm1, %%mm2                   \n\t"
+            "por %%mm5, %%mm2                       \n\t" // ABS Diff of lines
+            "movq %2, %%mm0                         \n\t"  // QP,..., QP
+            "psubusb %%mm2, %%mm0                   \n\t" // diff >= QP -> 0
+            "pcmpeqb %%mm4, %%mm0                   \n\t" // diff >= QP -> FF
+
+            "pxor %%mm7, %%mm1                      \n\t"
+            "pand %%mm0, %%mm1                      \n\t"
+            "pxor %%mm1, %%mm7                      \n\t"
+
+            "movq %%mm6, %%mm5                      \n\t"
+            "punpckhbw %%mm4, %%mm6                 \n\t"
+            "punpcklbw %%mm4, %%mm5                 \n\t"
+            // 4:0 5/6:First 7:Last
+
+            "movq %%mm5, %%mm0                      \n\t"
+            "movq %%mm6, %%mm1                      \n\t"
+            "psllw $2, %%mm0                        \n\t"
+            "psllw $2, %%mm1                        \n\t"
+            "paddw "MANGLE(w04)", %%mm0             \n\t"
+            "paddw "MANGLE(w04)", %%mm1             \n\t"
+
+#define NEXT\
+            "movq (%0), %%mm2                       \n\t"\
+            "movq (%0), %%mm3                       \n\t"\
+            "add %1, %0                             \n\t"\
+            "punpcklbw %%mm4, %%mm2                 \n\t"\
+            "punpckhbw %%mm4, %%mm3                 \n\t"\
+            "paddw %%mm2, %%mm0                     \n\t"\
+            "paddw %%mm3, %%mm1                     \n\t"
+
+#define PREV\
+            "movq (%0), %%mm2                       \n\t"\
+            "movq (%0), %%mm3                       \n\t"\
+            "add %1, %0                             \n\t"\
+            "punpcklbw %%mm4, %%mm2                 \n\t"\
+            "punpckhbw %%mm4, %%mm3                 \n\t"\
+            "psubw %%mm2, %%mm0                     \n\t"\
+            "psubw %%mm3, %%mm1                     \n\t"
+
+
+            NEXT //0
+            NEXT //1
+            NEXT //2
+            "movq %%mm0, (%3)                       \n\t"
+            "movq %%mm1, 8(%3)                      \n\t"
+
+            NEXT //3
+            "psubw %%mm5, %%mm0                     \n\t"
+            "psubw %%mm6, %%mm1                     \n\t"
+            "movq %%mm0, 16(%3)                     \n\t"
+            "movq %%mm1, 24(%3)                     \n\t"
+
+            NEXT //4
+            "psubw %%mm5, %%mm0                     \n\t"
+            "psubw %%mm6, %%mm1                     \n\t"
+            "movq %%mm0, 32(%3)                     \n\t"
+            "movq %%mm1, 40(%3)                     \n\t"
+
+            NEXT //5
+            "psubw %%mm5, %%mm0                     \n\t"
+            "psubw %%mm6, %%mm1                     \n\t"
+            "movq %%mm0, 48(%3)                     \n\t"
+            "movq %%mm1, 56(%3)                     \n\t"
+
+            NEXT //6
+            "psubw %%mm5, %%mm0                     \n\t"
+            "psubw %%mm6, %%mm1                     \n\t"
+            "movq %%mm0, 64(%3)                     \n\t"
+            "movq %%mm1, 72(%3)                     \n\t"
+
+            "movq %%mm7, %%mm6                      \n\t"
+            "punpckhbw %%mm4, %%mm7                 \n\t"
+            "punpcklbw %%mm4, %%mm6                 \n\t"
+
+            NEXT //7
+            "mov %4, %0                             \n\t"
+            "add %1, %0                             \n\t"
+            PREV //0
+            "movq %%mm0, 80(%3)                     \n\t"
+            "movq %%mm1, 88(%3)                     \n\t"
+
+            PREV //1
+            "paddw %%mm6, %%mm0                     \n\t"
+            "paddw %%mm7, %%mm1                     \n\t"
+            "movq %%mm0, 96(%3)                     \n\t"
+            "movq %%mm1, 104(%3)                    \n\t"
+
+            PREV //2
+            "paddw %%mm6, %%mm0                     \n\t"
+            "paddw %%mm7, %%mm1                     \n\t"
+            "movq %%mm0, 112(%3)                    \n\t"
+            "movq %%mm1, 120(%3)                    \n\t"
+
+            PREV //3
+            "paddw %%mm6, %%mm0                     \n\t"
+            "paddw %%mm7, %%mm1                     \n\t"
+            "movq %%mm0, 128(%3)                    \n\t"
+            "movq %%mm1, 136(%3)                    \n\t"
+
+            PREV //4
+            "paddw %%mm6, %%mm0                     \n\t"
+            "paddw %%mm7, %%mm1                     \n\t"
+            "movq %%mm0, 144(%3)                    \n\t"
+            "movq %%mm1, 152(%3)                    \n\t"
+
+            "mov %4, %0                             \n\t" //FIXME
+
+            : "+&r"(src)
+            : "r" ((x86_reg)step), "m" (c->pQPb), "r"(sums), "g"(src)
+        );
+
+        src+= step; // src points to begin of the 8x8 Block
+
+        __asm__ volatile(
+            "movq %4, %%mm6                         \n\t"
+            "pcmpeqb %%mm5, %%mm5                   \n\t"
+            "pxor %%mm6, %%mm5                      \n\t"
+            "pxor %%mm7, %%mm7                      \n\t"
+
+            "1:                                     \n\t"
+            "movq (%1), %%mm0                       \n\t"
+            "movq 8(%1), %%mm1                      \n\t"
+            "paddw 32(%1), %%mm0                    \n\t"
+            "paddw 40(%1), %%mm1                    \n\t"
+            "movq (%0, %3), %%mm2                   \n\t"
+            "movq %%mm2, %%mm3                      \n\t"
+            "movq %%mm2, %%mm4                      \n\t"
+            "punpcklbw %%mm7, %%mm2                 \n\t"
+            "punpckhbw %%mm7, %%mm3                 \n\t"
+            "paddw %%mm2, %%mm0                     \n\t"
+            "paddw %%mm3, %%mm1                     \n\t"
+            "paddw %%mm2, %%mm0                     \n\t"
+            "paddw %%mm3, %%mm1                     \n\t"
+            "psrlw $4, %%mm0                        \n\t"
+            "psrlw $4, %%mm1                        \n\t"
+            "packuswb %%mm1, %%mm0                  \n\t"
+            "pand %%mm6, %%mm0                      \n\t"
+            "pand %%mm5, %%mm4                      \n\t"
+            "por %%mm4, %%mm0                       \n\t"
+            "movq %%mm0, (%0, %3)                   \n\t"
+            "add $16, %1                            \n\t"
+            "add %2, %0                             \n\t"
+            " js 1b                                 \n\t"
+
+            : "+r"(offset), "+r"(temp_sums)
+            : "r" ((x86_reg)step), "r"(src - offset), "m"(both_masks)
+        );
+    }else
+        src+= step; // src points to begin of the 8x8 Block
+
+    if(eq_mask != -1LL){
+        uint8_t *temp_src= src;
+        DECLARE_ALIGNED(8, uint64_t, tmp)[4]; // make space for 4 8-byte vars
+        __asm__ volatile(
+            "pxor %%mm7, %%mm7                      \n\t"
+//      0       1       2       3       4       5       6       7       8       9
+//      %0      eax     eax+%1  eax+2%1 %0+4%1  ecx     ecx+%1  ecx+2%1 %1+8%1  ecx+4%1
+
+            "movq (%0), %%mm0                       \n\t"
+            "movq %%mm0, %%mm1                      \n\t"
+            "punpcklbw %%mm7, %%mm0                 \n\t" // low part of line 0
+            "punpckhbw %%mm7, %%mm1                 \n\t" // high part of line 0
+
+            "movq (%0, %1), %%mm2                   \n\t"
+            "lea (%0, %1, 2), %%"REG_a"             \n\t"
+            "movq %%mm2, %%mm3                      \n\t"
+            "punpcklbw %%mm7, %%mm2                 \n\t" // low part of line 1
+            "punpckhbw %%mm7, %%mm3                 \n\t" // high part of line 1
+
+            "movq (%%"REG_a"), %%mm4                \n\t"
+            "movq %%mm4, %%mm5                      \n\t"
+            "punpcklbw %%mm7, %%mm4                 \n\t" // low part of line 2
+            "punpckhbw %%mm7, %%mm5                 \n\t" // high part of line 2
+
+            "paddw %%mm0, %%mm0                     \n\t" // 2L0
+            "paddw %%mm1, %%mm1                     \n\t" // 2H0
+            "psubw %%mm4, %%mm2                     \n\t" // L1 - L2
+            "psubw %%mm5, %%mm3                     \n\t" // H1 - H2
+            "psubw %%mm2, %%mm0                     \n\t" // 2L0 - L1 + L2
+            "psubw %%mm3, %%mm1                     \n\t" // 2H0 - H1 + H2
+
+            "psllw $2, %%mm2                        \n\t" // 4L1 - 4L2
+            "psllw $2, %%mm3                        \n\t" // 4H1 - 4H2
+            "psubw %%mm2, %%mm0                     \n\t" // 2L0 - 5L1 + 5L2
+            "psubw %%mm3, %%mm1                     \n\t" // 2H0 - 5H1 + 5H2
+
+            "movq (%%"REG_a", %1), %%mm2            \n\t"
+            "movq %%mm2, %%mm3                      \n\t"
+            "punpcklbw %%mm7, %%mm2                 \n\t" // L3
+            "punpckhbw %%mm7, %%mm3                 \n\t" // H3
+
+            "psubw %%mm2, %%mm0                     \n\t" // 2L0 - 5L1 + 5L2 - L3
+            "psubw %%mm3, %%mm1                     \n\t" // 2H0 - 5H1 + 5H2 - H3
+            "psubw %%mm2, %%mm0                     \n\t" // 2L0 - 5L1 + 5L2 - 2L3
+            "psubw %%mm3, %%mm1                     \n\t" // 2H0 - 5H1 + 5H2 - 2H3
+            "movq %%mm0, (%4)                       \n\t" // 2L0 - 5L1 + 5L2 - 2L3
+            "movq %%mm1, 8(%4)                      \n\t" // 2H0 - 5H1 + 5H2 - 2H3
+
+            "movq (%%"REG_a", %1, 2), %%mm0         \n\t"
+            "movq %%mm0, %%mm1                      \n\t"
+            "punpcklbw %%mm7, %%mm0                 \n\t" // L4
+            "punpckhbw %%mm7, %%mm1                 \n\t" // H4
+
+            "psubw %%mm0, %%mm2                     \n\t" // L3 - L4
+            "psubw %%mm1, %%mm3                     \n\t" // H3 - H4
+            "movq %%mm2, 16(%4)                     \n\t" // L3 - L4
+            "movq %%mm3, 24(%4)                     \n\t" // H3 - H4
+            "paddw %%mm4, %%mm4                     \n\t" // 2L2
+            "paddw %%mm5, %%mm5                     \n\t" // 2H2
+            "psubw %%mm2, %%mm4                     \n\t" // 2L2 - L3 + L4
+            "psubw %%mm3, %%mm5                     \n\t" // 2H2 - H3 + H4
+
+            "lea (%%"REG_a", %1), %0                \n\t"
+            "psllw $2, %%mm2                        \n\t" // 4L3 - 4L4
+            "psllw $2, %%mm3                        \n\t" // 4H3 - 4H4
+            "psubw %%mm2, %%mm4                     \n\t" // 2L2 - 5L3 + 5L4
+            "psubw %%mm3, %%mm5                     \n\t" // 2H2 - 5H3 + 5H4
+//50 opcodes so far
+            "movq (%0, %1, 2), %%mm2                \n\t"
+            "movq %%mm2, %%mm3                      \n\t"
+            "punpcklbw %%mm7, %%mm2                 \n\t" // L5
+            "punpckhbw %%mm7, %%mm3                 \n\t" // H5
+            "psubw %%mm2, %%mm4                     \n\t" // 2L2 - 5L3 + 5L4 - L5
+            "psubw %%mm3, %%mm5                     \n\t" // 2H2 - 5H3 + 5H4 - H5
+            "psubw %%mm2, %%mm4                     \n\t" // 2L2 - 5L3 + 5L4 - 2L5
+            "psubw %%mm3, %%mm5                     \n\t" // 2H2 - 5H3 + 5H4 - 2H5
+
+            "movq (%%"REG_a", %1, 4), %%mm6         \n\t"
+            "punpcklbw %%mm7, %%mm6                 \n\t" // L6
+            "psubw %%mm6, %%mm2                     \n\t" // L5 - L6
+            "movq (%%"REG_a", %1, 4), %%mm6         \n\t"
+            "punpckhbw %%mm7, %%mm6                 \n\t" // H6
+            "psubw %%mm6, %%mm3                     \n\t" // H5 - H6
+
+            "paddw %%mm0, %%mm0                     \n\t" // 2L4
+            "paddw %%mm1, %%mm1                     \n\t" // 2H4
+            "psubw %%mm2, %%mm0                     \n\t" // 2L4 - L5 + L6
+            "psubw %%mm3, %%mm1                     \n\t" // 2H4 - H5 + H6
+
+            "psllw $2, %%mm2                        \n\t" // 4L5 - 4L6
+            "psllw $2, %%mm3                        \n\t" // 4H5 - 4H6
+            "psubw %%mm2, %%mm0                     \n\t" // 2L4 - 5L5 + 5L6
+            "psubw %%mm3, %%mm1                     \n\t" // 2H4 - 5H5 + 5H6
+
+            "movq (%0, %1, 4), %%mm2                \n\t"
+            "movq %%mm2, %%mm3                      \n\t"
+            "punpcklbw %%mm7, %%mm2                 \n\t" // L7
+            "punpckhbw %%mm7, %%mm3                 \n\t" // H7
+
+            "paddw %%mm2, %%mm2                     \n\t" // 2L7
+            "paddw %%mm3, %%mm3                     \n\t" // 2H7
+            "psubw %%mm2, %%mm0                     \n\t" // 2L4 - 5L5 + 5L6 - 2L7
+            "psubw %%mm3, %%mm1                     \n\t" // 2H4 - 5H5 + 5H6 - 2H7
+
+            "movq (%4), %%mm2                       \n\t" // 2L0 - 5L1 + 5L2 - 2L3
+            "movq 8(%4), %%mm3                      \n\t" // 2H0 - 5H1 + 5H2 - 2H3
+
+#if HAVE_MMXEXT_INLINE
+            "movq %%mm7, %%mm6                      \n\t" // 0
+            "psubw %%mm0, %%mm6                     \n\t"
+            "pmaxsw %%mm6, %%mm0                    \n\t" // |2L4 - 5L5 + 5L6 - 2L7|
+            "movq %%mm7, %%mm6                      \n\t" // 0
+            "psubw %%mm1, %%mm6                     \n\t"
+            "pmaxsw %%mm6, %%mm1                    \n\t" // |2H4 - 5H5 + 5H6 - 2H7|
+            "movq %%mm7, %%mm6                      \n\t" // 0
+            "psubw %%mm2, %%mm6                     \n\t"
+            "pmaxsw %%mm6, %%mm2                    \n\t" // |2L0 - 5L1 + 5L2 - 2L3|
+            "movq %%mm7, %%mm6                      \n\t" // 0
+            "psubw %%mm3, %%mm6                     \n\t"
+            "pmaxsw %%mm6, %%mm3                    \n\t" // |2H0 - 5H1 + 5H2 - 2H3|
+#else
+            "movq %%mm7, %%mm6                      \n\t" // 0
+            "pcmpgtw %%mm0, %%mm6                   \n\t"
+            "pxor %%mm6, %%mm0                      \n\t"
+            "psubw %%mm6, %%mm0                     \n\t" // |2L4 - 5L5 + 5L6 - 2L7|
+            "movq %%mm7, %%mm6                      \n\t" // 0
+            "pcmpgtw %%mm1, %%mm6                   \n\t"
+            "pxor %%mm6, %%mm1                      \n\t"
+            "psubw %%mm6, %%mm1                     \n\t" // |2H4 - 5H5 + 5H6 - 2H7|
+            "movq %%mm7, %%mm6                      \n\t" // 0
+            "pcmpgtw %%mm2, %%mm6                   \n\t"
+            "pxor %%mm6, %%mm2                      \n\t"
+            "psubw %%mm6, %%mm2                     \n\t" // |2L0 - 5L1 + 5L2 - 2L3|
+            "movq %%mm7, %%mm6                      \n\t" // 0
+            "pcmpgtw %%mm3, %%mm6                   \n\t"
+            "pxor %%mm6, %%mm3                      \n\t"
+            "psubw %%mm6, %%mm3                     \n\t" // |2H0 - 5H1 + 5H2 - 2H3|
+#endif
+
+#if HAVE_MMXEXT_INLINE
+            "pminsw %%mm2, %%mm0                    \n\t"
+            "pminsw %%mm3, %%mm1                    \n\t"
+#else
+            "movq %%mm0, %%mm6                      \n\t"
+            "psubusw %%mm2, %%mm6                   \n\t"
+            "psubw %%mm6, %%mm0                     \n\t"
+            "movq %%mm1, %%mm6                      \n\t"
+            "psubusw %%mm3, %%mm6                   \n\t"
+            "psubw %%mm6, %%mm1                     \n\t"
+#endif
+
+            "movd %2, %%mm2                         \n\t" // QP
+            "punpcklbw %%mm7, %%mm2                 \n\t"
+
+            "movq %%mm7, %%mm6                      \n\t" // 0
+            "pcmpgtw %%mm4, %%mm6                   \n\t" // sign(2L2 - 5L3 + 5L4 - 2L5)
+            "pxor %%mm6, %%mm4                      \n\t"
+            "psubw %%mm6, %%mm4                     \n\t" // |2L2 - 5L3 + 5L4 - 2L5|
+            "pcmpgtw %%mm5, %%mm7                   \n\t" // sign(2H2 - 5H3 + 5H4 - 2H5)
+            "pxor %%mm7, %%mm5                      \n\t"
+            "psubw %%mm7, %%mm5                     \n\t" // |2H2 - 5H3 + 5H4 - 2H5|
+// 100 opcodes
+            "psllw $3, %%mm2                        \n\t" // 8QP
+            "movq %%mm2, %%mm3                      \n\t" // 8QP
+            "pcmpgtw %%mm4, %%mm2                   \n\t"
+            "pcmpgtw %%mm5, %%mm3                   \n\t"
+            "pand %%mm2, %%mm4                      \n\t"
+            "pand %%mm3, %%mm5                      \n\t"
+
+
+            "psubusw %%mm0, %%mm4                   \n\t" // hd
+            "psubusw %%mm1, %%mm5                   \n\t" // ld
+
+
+            "movq "MANGLE(w05)", %%mm2              \n\t" // 5
+            "pmullw %%mm2, %%mm4                    \n\t"
+            "pmullw %%mm2, %%mm5                    \n\t"
+            "movq "MANGLE(w20)", %%mm2              \n\t" // 32
+            "paddw %%mm2, %%mm4                     \n\t"
+            "paddw %%mm2, %%mm5                     \n\t"
+            "psrlw $6, %%mm4                        \n\t"
+            "psrlw $6, %%mm5                        \n\t"
+
+            "movq 16(%4), %%mm0                     \n\t" // L3 - L4
+            "movq 24(%4), %%mm1                     \n\t" // H3 - H4
+
+            "pxor %%mm2, %%mm2                      \n\t"
+            "pxor %%mm3, %%mm3                      \n\t"
+
+            "pcmpgtw %%mm0, %%mm2                   \n\t" // sign (L3-L4)
+            "pcmpgtw %%mm1, %%mm3                   \n\t" // sign (H3-H4)
+            "pxor %%mm2, %%mm0                      \n\t"
+            "pxor %%mm3, %%mm1                      \n\t"
+            "psubw %%mm2, %%mm0                     \n\t" // |L3-L4|
+            "psubw %%mm3, %%mm1                     \n\t" // |H3-H4|
+            "psrlw $1, %%mm0                        \n\t" // |L3 - L4|/2
+            "psrlw $1, %%mm1                        \n\t" // |H3 - H4|/2
+
+            "pxor %%mm6, %%mm2                      \n\t"
+            "pxor %%mm7, %%mm3                      \n\t"
+            "pand %%mm2, %%mm4                      \n\t"
+            "pand %%mm3, %%mm5                      \n\t"
+
+#if HAVE_MMXEXT_INLINE
+            "pminsw %%mm0, %%mm4                    \n\t"
+            "pminsw %%mm1, %%mm5                    \n\t"
+#else
+            "movq %%mm4, %%mm2                      \n\t"
+            "psubusw %%mm0, %%mm2                   \n\t"
+            "psubw %%mm2, %%mm4                     \n\t"
+            "movq %%mm5, %%mm2                      \n\t"
+            "psubusw %%mm1, %%mm2                   \n\t"
+            "psubw %%mm2, %%mm5                     \n\t"
+#endif
+            "pxor %%mm6, %%mm4                      \n\t"
+            "pxor %%mm7, %%mm5                      \n\t"
+            "psubw %%mm6, %%mm4                     \n\t"
+            "psubw %%mm7, %%mm5                     \n\t"
+            "packsswb %%mm5, %%mm4                  \n\t"
+            "movq %3, %%mm1                         \n\t"
+            "pandn %%mm4, %%mm1                     \n\t"
+            "movq (%0), %%mm0                       \n\t"
+            "paddb   %%mm1, %%mm0                   \n\t"
+            "movq %%mm0, (%0)                       \n\t"
+            "movq (%0, %1), %%mm0                   \n\t"
+            "psubb %%mm1, %%mm0                     \n\t"
+            "movq %%mm0, (%0, %1)                   \n\t"
+
+            : "+r" (temp_src)
+            : "r" ((x86_reg)step), "m" (c->pQPb), "m"(eq_mask), "r"(tmp)
+            : "%"REG_a
+        );
+    }
+/*if(step==16){
+    STOP_TIMER("step16")
+}else{
+    STOP_TIMER("stepX")
+}
+    } */
+}
+#endif //HAVE_MMX_INLINE
+
+static void RENAME(postProcess)(const uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height,
+                                const QP_STORE_T QPs[], int QPStride, int isColor, PPContext *c);
+
+/**
+ * Copy a block from src to dst and fixes the blacklevel.
+ * levelFix == 0 -> do not touch the brighness & contrast
+ */
+#undef REAL_SCALED_CPY
+#undef SCALED_CPY
+
+static inline void RENAME(blockCopy)(uint8_t dst[], int dstStride, const uint8_t src[], int srcStride,
+                                     int levelFix, int64_t *packedOffsetAndScale)
+{
+#if !HAVE_MMX_INLINE
+    int i;
+#endif
+    if(levelFix){
+#if HAVE_MMX_INLINE
+    __asm__ volatile(
+        "movq (%%"REG_a"), %%mm2        \n\t" // packedYOffset
+        "movq 8(%%"REG_a"), %%mm3       \n\t" // packedYScale
+        "lea (%2,%4), %%"REG_a"         \n\t"
+        "lea (%3,%5), %%"REG_d"         \n\t"
+        "pxor %%mm4, %%mm4              \n\t"
+#if HAVE_MMXEXT_INLINE
+#define REAL_SCALED_CPY(src1, src2, dst1, dst2)                                                \
+        "movq " #src1 ", %%mm0          \n\t"\
+        "movq " #src1 ", %%mm5          \n\t"\
+        "movq " #src2 ", %%mm1          \n\t"\
+        "movq " #src2 ", %%mm6          \n\t"\
+        "punpcklbw %%mm0, %%mm0         \n\t"\
+        "punpckhbw %%mm5, %%mm5         \n\t"\
+        "punpcklbw %%mm1, %%mm1         \n\t"\
+        "punpckhbw %%mm6, %%mm6         \n\t"\
+        "pmulhuw %%mm3, %%mm0           \n\t"\
+        "pmulhuw %%mm3, %%mm5           \n\t"\
+        "pmulhuw %%mm3, %%mm1           \n\t"\
+        "pmulhuw %%mm3, %%mm6           \n\t"\
+        "psubw %%mm2, %%mm0             \n\t"\
+        "psubw %%mm2, %%mm5             \n\t"\
+        "psubw %%mm2, %%mm1             \n\t"\
+        "psubw %%mm2, %%mm6             \n\t"\
+        "packuswb %%mm5, %%mm0          \n\t"\
+        "packuswb %%mm6, %%mm1          \n\t"\
+        "movq %%mm0, " #dst1 "          \n\t"\
+        "movq %%mm1, " #dst2 "          \n\t"\
+
+#else //HAVE_MMXEXT_INLINE
+#define REAL_SCALED_CPY(src1, src2, dst1, dst2)                                        \
+        "movq " #src1 ", %%mm0          \n\t"\
+        "movq " #src1 ", %%mm5          \n\t"\
+        "punpcklbw %%mm4, %%mm0         \n\t"\
+        "punpckhbw %%mm4, %%mm5         \n\t"\
+        "psubw %%mm2, %%mm0             \n\t"\
+        "psubw %%mm2, %%mm5             \n\t"\
+        "movq " #src2 ", %%mm1          \n\t"\
+        "psllw $6, %%mm0                \n\t"\
+        "psllw $6, %%mm5                \n\t"\
+        "pmulhw %%mm3, %%mm0            \n\t"\
+        "movq " #src2 ", %%mm6          \n\t"\
+        "pmulhw %%mm3, %%mm5            \n\t"\
+        "punpcklbw %%mm4, %%mm1         \n\t"\
+        "punpckhbw %%mm4, %%mm6         \n\t"\
+        "psubw %%mm2, %%mm1             \n\t"\
+        "psubw %%mm2, %%mm6             \n\t"\
+        "psllw $6, %%mm1                \n\t"\
+        "psllw $6, %%mm6                \n\t"\
+        "pmulhw %%mm3, %%mm1            \n\t"\
+        "pmulhw %%mm3, %%mm6            \n\t"\
+        "packuswb %%mm5, %%mm0          \n\t"\
+        "packuswb %%mm6, %%mm1          \n\t"\
+        "movq %%mm0, " #dst1 "          \n\t"\
+        "movq %%mm1, " #dst2 "          \n\t"\
+
+#endif //HAVE_MMXEXT_INLINE
+#define SCALED_CPY(src1, src2, dst1, dst2)\
+   REAL_SCALED_CPY(src1, src2, dst1, dst2)
+
+SCALED_CPY((%2)       , (%2, %4)      , (%3)       , (%3, %5))
+SCALED_CPY((%2, %4, 2), (%%REGa, %4, 2), (%3, %5, 2), (%%REGd, %5, 2))
+SCALED_CPY((%2, %4, 4), (%%REGa, %4, 4), (%3, %5, 4), (%%REGd, %5, 4))
+        "lea (%%"REG_a",%4,4), %%"REG_a"        \n\t"
+        "lea (%%"REG_d",%5,4), %%"REG_d"        \n\t"
+SCALED_CPY((%%REGa, %4), (%%REGa, %4, 2), (%%REGd, %5), (%%REGd, %5, 2))
+
+
+        : "=&a" (packedOffsetAndScale)
+        : "0" (packedOffsetAndScale),
+        "r"(src),
+        "r"(dst),
+        "r" ((x86_reg)srcStride),
+        "r" ((x86_reg)dstStride)
+        : "%"REG_d
+    );
+#else //HAVE_MMX_INLINE
+    for(i=0; i<8; i++)
+        memcpy( &(dst[dstStride*i]),
+                &(src[srcStride*i]), BLOCK_SIZE);
+#endif //HAVE_MMX_INLINE
+    }else{
+#if HAVE_MMX_INLINE
+    __asm__ volatile(
+        "lea (%0,%2), %%"REG_a"                 \n\t"
+        "lea (%1,%3), %%"REG_d"                 \n\t"
+
+#define REAL_SIMPLE_CPY(src1, src2, dst1, dst2)                              \
+        "movq " #src1 ", %%mm0          \n\t"\
+        "movq " #src2 ", %%mm1          \n\t"\
+        "movq %%mm0, " #dst1 "          \n\t"\
+        "movq %%mm1, " #dst2 "          \n\t"\
+
+#define SIMPLE_CPY(src1, src2, dst1, dst2)\
+   REAL_SIMPLE_CPY(src1, src2, dst1, dst2)
+
+SIMPLE_CPY((%0)       , (%0, %2)       , (%1)       , (%1, %3))
+SIMPLE_CPY((%0, %2, 2), (%%REGa, %2, 2), (%1, %3, 2), (%%REGd, %3, 2))
+SIMPLE_CPY((%0, %2, 4), (%%REGa, %2, 4), (%1, %3, 4), (%%REGd, %3, 4))
+        "lea (%%"REG_a",%2,4), %%"REG_a"        \n\t"
+        "lea (%%"REG_d",%3,4), %%"REG_d"        \n\t"
+SIMPLE_CPY((%%REGa, %2), (%%REGa, %2, 2), (%%REGd, %3), (%%REGd, %3, 2))
+
+        : : "r" (src),
+        "r" (dst),
+        "r" ((x86_reg)srcStride),
+        "r" ((x86_reg)dstStride)
+        : "%"REG_a, "%"REG_d
+    );
+#else //HAVE_MMX_INLINE
+    for(i=0; i<8; i++)
+        memcpy( &(dst[dstStride*i]),
+                &(src[srcStride*i]), BLOCK_SIZE);
+#endif //HAVE_MMX_INLINE
+    }
+}
+
+/**
+ * Duplicate the given 8 src pixels ? times upward
+ */
+static inline void RENAME(duplicate)(uint8_t src[], int stride)
+{
+#if HAVE_MMX_INLINE
+    __asm__ volatile(
+        "movq (%0), %%mm0               \n\t"
+        "add %1, %0                     \n\t"
+        "movq %%mm0, (%0)               \n\t"
+        "movq %%mm0, (%0, %1)           \n\t"
+        "movq %%mm0, (%0, %1, 2)        \n\t"
+        : "+r" (src)
+        : "r" ((x86_reg)-stride)
+    );
+#else
+    int i;
+    uint8_t *p=src;
+    for(i=0; i<3; i++){
+        p-= stride;
+        memcpy(p, src, 8);
+    }
+#endif
+}
+
+/**
+ * Filter array of bytes (Y or U or V values)
+ */
+static void RENAME(postProcess)(const uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height,
+                                const QP_STORE_T QPs[], int QPStride, int isColor, PPContext *c2)
+{
+    DECLARE_ALIGNED(8, PPContext, c)= *c2; //copy to stack for faster access
+    int x,y;
+#ifdef COMPILE_TIME_MODE
+    const int mode= COMPILE_TIME_MODE;
+#else
+    const int mode= isColor ? c.ppMode.chromMode : c.ppMode.lumMode;
+#endif
+    int black=0, white=255; // blackest black and whitest white in the picture
+    int QPCorrecture= 256*256;
+
+    int copyAhead;
+#if HAVE_MMX_INLINE
+    int i;
+#endif
+
+    const int qpHShift= isColor ? 4-c.hChromaSubSample : 4;
+    const int qpVShift= isColor ? 4-c.vChromaSubSample : 4;
+
+    //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;
+    //const int mbWidth= isColor ? (width+7)>>3 : (width+15)>>4;
+
+#if HAVE_MMX_INLINE
+    for(i=0; i<57; i++){
+        int offset= ((i*c.ppMode.baseDcDiff)>>8) + 1;
+        int threshold= offset*2 + 1;
+        c.mmxDcOffset[i]= 0x7F - offset;
+        c.mmxDcThreshold[i]= 0x7F - threshold;
+        c.mmxDcOffset[i]*= 0x0101010101010101LL;
+        c.mmxDcThreshold[i]*= 0x0101010101010101LL;
+    }
+#endif
+
+    if(mode & CUBIC_IPOL_DEINT_FILTER) copyAhead=16;
+    else if(   (mode & LINEAR_BLEND_DEINT_FILTER)
+            || (mode & FFMPEG_DEINT_FILTER)
+            || (mode & LOWPASS5_DEINT_FILTER)) copyAhead=14;
+    else if(   (mode & V_DEBLOCK)
+            || (mode & LINEAR_IPOL_DEINT_FILTER)
+            || (mode & MEDIAN_DEINT_FILTER)
+            || (mode & V_A_DEBLOCK)) copyAhead=13;
+    else if(mode & V_X1_FILTER) copyAhead=11;
+//    else if(mode & V_RK1_FILTER) copyAhead=10;
+    else if(mode & DERING) copyAhead=9;
+    else copyAhead=8;
+
+    copyAhead-= 8;
+
+    if(!isColor){
+        uint64_t sum= 0;
+        int i;
+        uint64_t maxClipped;
+        uint64_t clipped;
+        double scale;
+
+        c.frameNum++;
+        // first frame is fscked so we ignore it
+        if(c.frameNum == 1) yHistogram[0]= width*height/64*15/256;
+
+        for(i=0; i<256; i++){
+            sum+= yHistogram[i];
+        }
+
+        /* We always get a completely black picture first. */
+        maxClipped= (uint64_t)(sum * c.ppMode.maxClippedThreshold);
+
+        clipped= sum;
+        for(black=255; black>0; black--){
+            if(clipped < maxClipped) break;
+            clipped-= yHistogram[black];
+        }
+
+        clipped= sum;
+        for(white=0; white<256; white++){
+            if(clipped < maxClipped) break;
+            clipped-= yHistogram[white];
+        }
+
+        scale= (double)(c.ppMode.maxAllowedY - c.ppMode.minAllowedY) / (double)(white-black);
+
+#if HAVE_MMXEXT_INLINE
+        c.packedYScale= (uint16_t)(scale*256.0 + 0.5);
+        c.packedYOffset= (((black*c.packedYScale)>>8) - c.ppMode.minAllowedY) & 0xFFFF;
+#else
+        c.packedYScale= (uint16_t)(scale*1024.0 + 0.5);
+        c.packedYOffset= (black - c.ppMode.minAllowedY) & 0xFFFF;
+#endif
+
+        c.packedYOffset|= c.packedYOffset<<32;
+        c.packedYOffset|= c.packedYOffset<<16;
+
+        c.packedYScale|= c.packedYScale<<32;
+        c.packedYScale|= c.packedYScale<<16;
+
+        if(mode & LEVEL_FIX)        QPCorrecture= (int)(scale*256*256 + 0.5);
+        else                        QPCorrecture= 256*256;
+    }else{
+        c.packedYScale= 0x0100010001000100LL;
+        c.packedYOffset= 0;
+        QPCorrecture= 256*256;
+    }
+
+    /* copy & deinterlace first row of blocks */
+    y=-BLOCK_SIZE;
+    {
+        const uint8_t *srcBlock= &(src[y*srcStride]);
+        uint8_t *dstBlock= tempDst + dstStride;
+
+        // 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
+        for(x=0; x<width; x+=BLOCK_SIZE){
+
+#if HAVE_MMXEXT_INLINE
+/*
+            prefetchnta(srcBlock + (((x>>2)&6) + 5)*srcStride + 32);
+            prefetchnta(srcBlock + (((x>>2)&6) + 6)*srcStride + 32);
+            prefetcht0(dstBlock + (((x>>2)&6) + 5)*dstStride + 32);
+            prefetcht0(dstBlock + (((x>>2)&6) + 6)*dstStride + 32);
+*/
+
+            __asm__(
+                "mov %4, %%"REG_a"              \n\t"
+                "shr $2, %%"REG_a"              \n\t"
+                "and $6, %%"REG_a"              \n\t"
+                "add %5, %%"REG_a"              \n\t"
+                "mov %%"REG_a", %%"REG_d"       \n\t"
+                "imul %1, %%"REG_a"             \n\t"
+                "imul %3, %%"REG_d"             \n\t"
+                "prefetchnta 32(%%"REG_a", %0)  \n\t"
+                "prefetcht0 32(%%"REG_d", %2)   \n\t"
+                "add %1, %%"REG_a"              \n\t"
+                "add %3, %%"REG_d"              \n\t"
+                "prefetchnta 32(%%"REG_a", %0)  \n\t"
+                "prefetcht0 32(%%"REG_d", %2)   \n\t"
+                :: "r" (srcBlock), "r" ((x86_reg)srcStride), "r" (dstBlock), "r" ((x86_reg)dstStride),
+                "g" ((x86_reg)x), "g" ((x86_reg)copyAhead)
+                : "%"REG_a, "%"REG_d
+            );
+
+#elif HAVE_AMD3DNOW_INLINE
+//FIXME check if this is faster on an 3dnow chip or if it is faster without the prefetch or ...
+/*          prefetch(srcBlock + (((x>>3)&3) + 5)*srcStride + 32);
+            prefetch(srcBlock + (((x>>3)&3) + 9)*srcStride + 32);
+            prefetchw(dstBlock + (((x>>3)&3) + 5)*dstStride + 32);
+            prefetchw(dstBlock + (((x>>3)&3) + 9)*dstStride + 32);
+*/
+#endif
+
+            RENAME(blockCopy)(dstBlock + dstStride*8, dstStride,
+                              srcBlock + srcStride*8, srcStride, mode & LEVEL_FIX, &c.packedYOffset);
+
+            RENAME(duplicate)(dstBlock + dstStride*8, dstStride);
+
+            if(mode & LINEAR_IPOL_DEINT_FILTER)
+                RENAME(deInterlaceInterpolateLinear)(dstBlock, dstStride);
+            else if(mode & LINEAR_BLEND_DEINT_FILTER)
+                RENAME(deInterlaceBlendLinear)(dstBlock, dstStride, c.deintTemp + x);
+            else if(mode & MEDIAN_DEINT_FILTER)
+                RENAME(deInterlaceMedian)(dstBlock, dstStride);
+            else if(mode & CUBIC_IPOL_DEINT_FILTER)
+                RENAME(deInterlaceInterpolateCubic)(dstBlock, dstStride);
+            else if(mode & FFMPEG_DEINT_FILTER)
+                RENAME(deInterlaceFF)(dstBlock, dstStride, c.deintTemp + x);
+            else if(mode & LOWPASS5_DEINT_FILTER)
+                RENAME(deInterlaceL5)(dstBlock, dstStride, c.deintTemp + x, c.deintTemp + width + x);
+/*          else if(mode & CUBIC_BLEND_DEINT_FILTER)
+                RENAME(deInterlaceBlendCubic)(dstBlock, dstStride);
+*/
+            dstBlock+=8;
+            srcBlock+=8;
+        }
+        if(width==FFABS(dstStride))
+            linecpy(dst, tempDst + 9*dstStride, copyAhead, dstStride);
+        else{
+            int i;
+            for(i=0; i<copyAhead; i++){
+                memcpy(dst + i*dstStride, tempDst + (9+i)*dstStride, width);
+            }
+        }
+    }
+
+    for(y=0; y<height; y+=BLOCK_SIZE){
+        //1% speedup if these are here instead of the inner loop
+        const uint8_t *srcBlock= &(src[y*srcStride]);
+        uint8_t *dstBlock= &(dst[y*dstStride]);
+#if HAVE_MMX_INLINE
+        uint8_t *tempBlock1= c.tempBlocks;
+        uint8_t *tempBlock2= c.tempBlocks + 8;
+#endif
+        const int8_t *QPptr= &QPs[(y>>qpVShift)*QPStride];
+        int8_t *nonBQPptr= &c.nonBQPTable[(y>>qpVShift)*FFABS(QPStride)];
+        int QP=0;
+        /* can we mess with a 8x16 block from srcBlock/dstBlock downwards and 1 line upwards
+           if not than use a temporary buffer */
+        if(y+15 >= height){
+            int i;
+            /* copy from line (copyAhead) to (copyAhead+7) of src, these will be copied with
+               blockcopy to dst later */
+            linecpy(tempSrc + srcStride*copyAhead, srcBlock + srcStride*copyAhead,
+                    FFMAX(height-y-copyAhead, 0), srcStride);
+
+            /* duplicate last line of src to fill the void up to line (copyAhead+7) */
+            for(i=FFMAX(height-y, 8); i<copyAhead+8; i++)
+                    memcpy(tempSrc + srcStride*i, src + srcStride*(height-1), FFABS(srcStride));
+
+            /* copy up to (copyAhead+1) lines of dst (line -1 to (copyAhead-1))*/
+            linecpy(tempDst, dstBlock - dstStride, FFMIN(height-y+1, copyAhead+1), dstStride);
+
+            /* duplicate last line of dst to fill the void up to line (copyAhead) */
+            for(i=height-y+1; i<=copyAhead; i++)
+                    memcpy(tempDst + dstStride*i, dst + dstStride*(height-1), FFABS(dstStride));
+
+            dstBlock= tempDst + dstStride;
+            srcBlock= tempSrc;
+        }
+
+        // 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
+        for(x=0; x<width; x+=BLOCK_SIZE){
+            const int stride= dstStride;
+#if HAVE_MMX_INLINE
+            uint8_t *tmpXchg;
+#endif
+            if(isColor){
+                QP= QPptr[x>>qpHShift];
+                c.nonBQP= nonBQPptr[x>>qpHShift];
+            }else{
+                QP= QPptr[x>>4];
+                QP= (QP* QPCorrecture + 256*128)>>16;
+                c.nonBQP= nonBQPptr[x>>4];
+                c.nonBQP= (c.nonBQP* QPCorrecture + 256*128)>>16;
+                yHistogram[ srcBlock[srcStride*12 + 4] ]++;
+            }
+            c.QP= QP;
+#if HAVE_MMX_INLINE
+            __asm__ volatile(
+                "movd %1, %%mm7         \n\t"
+                "packuswb %%mm7, %%mm7  \n\t" // 0, 0, 0, QP, 0, 0, 0, QP
+                "packuswb %%mm7, %%mm7  \n\t" // 0,QP, 0, QP, 0,QP, 0, QP
+                "packuswb %%mm7, %%mm7  \n\t" // QP,..., QP
+                "movq %%mm7, %0         \n\t"
+                : "=m" (c.pQPb)
+                : "r" (QP)
+            );
+#endif
+
+
+#if HAVE_MMXEXT_INLINE
+/*
+            prefetchnta(srcBlock + (((x>>2)&6) + 5)*srcStride + 32);
+            prefetchnta(srcBlock + (((x>>2)&6) + 6)*srcStride + 32);
+            prefetcht0(dstBlock + (((x>>2)&6) + 5)*dstStride + 32);
+            prefetcht0(dstBlock + (((x>>2)&6) + 6)*dstStride + 32);
+*/
+
+            __asm__(
+                "mov %4, %%"REG_a"              \n\t"
+                "shr $2, %%"REG_a"              \n\t"
+                "and $6, %%"REG_a"              \n\t"
+                "add %5, %%"REG_a"              \n\t"
+                "mov %%"REG_a", %%"REG_d"       \n\t"
+                "imul %1, %%"REG_a"             \n\t"
+                "imul %3, %%"REG_d"             \n\t"
+                "prefetchnta 32(%%"REG_a", %0)  \n\t"
+                "prefetcht0 32(%%"REG_d", %2)   \n\t"
+                "add %1, %%"REG_a"              \n\t"
+                "add %3, %%"REG_d"              \n\t"
+                "prefetchnta 32(%%"REG_a", %0)  \n\t"
+                "prefetcht0 32(%%"REG_d", %2)   \n\t"
+                :: "r" (srcBlock), "r" ((x86_reg)srcStride), "r" (dstBlock), "r" ((x86_reg)dstStride),
+                "g" ((x86_reg)x), "g" ((x86_reg)copyAhead)
+                : "%"REG_a, "%"REG_d
+            );
+
+#elif HAVE_AMD3DNOW_INLINE
+//FIXME check if this is faster on an 3dnow chip or if it is faster without the prefetch or ...
+/*          prefetch(srcBlock + (((x>>3)&3) + 5)*srcStride + 32);
+            prefetch(srcBlock + (((x>>3)&3) + 9)*srcStride + 32);
+            prefetchw(dstBlock + (((x>>3)&3) + 5)*dstStride + 32);
+            prefetchw(dstBlock + (((x>>3)&3) + 9)*dstStride + 32);
+*/
+#endif
+
+            RENAME(blockCopy)(dstBlock + dstStride*copyAhead, dstStride,
+                              srcBlock + srcStride*copyAhead, srcStride, mode & LEVEL_FIX, &c.packedYOffset);
+
+            if(mode & LINEAR_IPOL_DEINT_FILTER)
+                RENAME(deInterlaceInterpolateLinear)(dstBlock, dstStride);
+            else if(mode & LINEAR_BLEND_DEINT_FILTER)
+                RENAME(deInterlaceBlendLinear)(dstBlock, dstStride, c.deintTemp + x);
+            else if(mode & MEDIAN_DEINT_FILTER)
+                RENAME(deInterlaceMedian)(dstBlock, dstStride);
+            else if(mode & CUBIC_IPOL_DEINT_FILTER)
+                RENAME(deInterlaceInterpolateCubic)(dstBlock, dstStride);
+            else if(mode & FFMPEG_DEINT_FILTER)
+                RENAME(deInterlaceFF)(dstBlock, dstStride, c.deintTemp + x);
+            else if(mode & LOWPASS5_DEINT_FILTER)
+                RENAME(deInterlaceL5)(dstBlock, dstStride, c.deintTemp + x, c.deintTemp + width + x);
+/*          else if(mode & CUBIC_BLEND_DEINT_FILTER)
+                RENAME(deInterlaceBlendCubic)(dstBlock, dstStride);
+*/
+
+            /* only deblock if we have 2 blocks */
+            if(y + 8 < height){
+                if(mode & V_X1_FILTER)
+                    RENAME(vertX1Filter)(dstBlock, stride, &c);
+                else if(mode & V_DEBLOCK){
+                    const int t= RENAME(vertClassify)(dstBlock, stride, &c);
+
+                    if(t==1)
+                        RENAME(doVertLowPass)(dstBlock, stride, &c);
+                    else if(t==2)
+                        RENAME(doVertDefFilter)(dstBlock, stride, &c);
+                }else if(mode & V_A_DEBLOCK){
+                    RENAME(do_a_deblock)(dstBlock, stride, 1, &c);
+                }
+            }
+
+#if HAVE_MMX_INLINE
+            RENAME(transpose1)(tempBlock1, tempBlock2, dstBlock, dstStride);
+#endif
+            /* check if we have a previous block to deblock it with dstBlock */
+            if(x - 8 >= 0){
+#if HAVE_MMX_INLINE
+                if(mode & H_X1_FILTER)
+                        RENAME(vertX1Filter)(tempBlock1, 16, &c);
+                else if(mode & H_DEBLOCK){
+//START_TIMER
+                    const int t= RENAME(vertClassify)(tempBlock1, 16, &c);
+//STOP_TIMER("dc & minmax")
+                    if(t==1)
+                        RENAME(doVertLowPass)(tempBlock1, 16, &c);
+                    else if(t==2)
+                        RENAME(doVertDefFilter)(tempBlock1, 16, &c);
+                }else if(mode & H_A_DEBLOCK){
+                        RENAME(do_a_deblock)(tempBlock1, 16, 1, &c);
+                }
+
+                RENAME(transpose2)(dstBlock-4, dstStride, tempBlock1 + 4*16);
+
+#else
+                if(mode & H_X1_FILTER)
+                    horizX1Filter(dstBlock-4, stride, QP);
+                else if(mode & H_DEBLOCK){
+#if HAVE_ALTIVEC
+                    DECLARE_ALIGNED(16, unsigned char, tempBlock)[272];
+                    int t;
+                    transpose_16x8_char_toPackedAlign_altivec(tempBlock, dstBlock - (4 + 1), stride);
+
+                    t = vertClassify_altivec(tempBlock-48, 16, &c);
+                    if(t==1) {
+                        doVertLowPass_altivec(tempBlock-48, 16, &c);
+                        transpose_8x16_char_fromPackedAlign_altivec(dstBlock - (4 + 1), tempBlock, stride);
+                    }
+                    else if(t==2) {
+                        doVertDefFilter_altivec(tempBlock-48, 16, &c);
+                        transpose_8x16_char_fromPackedAlign_altivec(dstBlock - (4 + 1), tempBlock, stride);
+                    }
+#else
+                    const int t= RENAME(horizClassify)(dstBlock-4, stride, &c);
+
+                    if(t==1)
+                        RENAME(doHorizLowPass)(dstBlock-4, stride, &c);
+                    else if(t==2)
+                        RENAME(doHorizDefFilter)(dstBlock-4, stride, &c);
+#endif
+                }else if(mode & H_A_DEBLOCK){
+                    RENAME(do_a_deblock)(dstBlock-8, 1, stride, &c);
+                }
+#endif //HAVE_MMX_INLINE
+                if(mode & DERING){
+                //FIXME filter first line
+                    if(y>0) RENAME(dering)(dstBlock - stride - 8, stride, &c);
+                }
+
+                if(mode & TEMP_NOISE_FILTER)
+                {
+                    RENAME(tempNoiseReducer)(dstBlock-8, stride,
+                            c.tempBlurred[isColor] + y*dstStride + x,
+                            c.tempBlurredPast[isColor] + (y>>3)*256 + (x>>3) + 256,
+                            c.ppMode.maxTmpNoise);
+                }
+            }
+
+            dstBlock+=8;
+            srcBlock+=8;
+
+#if HAVE_MMX_INLINE
+            tmpXchg= tempBlock1;
+            tempBlock1= tempBlock2;
+            tempBlock2 = tmpXchg;
+#endif
+        }
+
+        if(mode & DERING){
+            if(y > 0) RENAME(dering)(dstBlock - dstStride - 8, dstStride, &c);
+        }
+
+        if((mode & TEMP_NOISE_FILTER)){
+            RENAME(tempNoiseReducer)(dstBlock-8, dstStride,
+                    c.tempBlurred[isColor] + y*dstStride + x,
+                    c.tempBlurredPast[isColor] + (y>>3)*256 + (x>>3) + 256,
+                    c.ppMode.maxTmpNoise);
+        }
+
+        /* did we use a tmp buffer for the last lines*/
+        if(y+15 >= height){
+            uint8_t *dstBlock= &(dst[y*dstStride]);
+            if(width==FFABS(dstStride))
+                linecpy(dstBlock, tempDst + dstStride, height-y, dstStride);
+            else{
+                int i;
+                for(i=0; i<height-y; i++){
+                    memcpy(dstBlock + i*dstStride, tempDst + (i+1)*dstStride, width);
+                }
+            }
+        }
+/*
+        for(x=0; x<width; x+=32){
+            volatile int i;
+            i+=   dstBlock[x + 7*dstStride] + dstBlock[x + 8*dstStride]
+                + dstBlock[x + 9*dstStride] + dstBlock[x +10*dstStride]
+                + dstBlock[x +11*dstStride] + dstBlock[x +12*dstStride];
+                + dstBlock[x +13*dstStride]
+                + dstBlock[x +14*dstStride] + dstBlock[x +15*dstStride];
+        }*/
+    }
+#if   HAVE_AMD3DNOW_INLINE
+    __asm__ volatile("femms");
+#elif HAVE_MMX_INLINE
+    __asm__ volatile("emms");
+#endif
+
+#ifdef DEBUG_BRIGHTNESS
+    if(!isColor){
+        int max=1;
+        int i;
+        for(i=0; i<256; i++)
+            if(yHistogram[i] > max) max=yHistogram[i];
+
+        for(i=1; i<256; i++){
+            int x;
+            int start=yHistogram[i-1]/(max/256+1);
+            int end=yHistogram[i]/(max/256+1);
+            int inc= end > start ? 1 : -1;
+            for(x=start; x!=end+inc; x+=inc)
+                dst[ i*dstStride + x]+=128;
+        }
+
+        for(i=0; i<100; i+=2){
+            dst[ (white)*dstStride + i]+=128;
+            dst[ (black)*dstStride + i]+=128;
+        }
+    }
+#endif
+
+    *c2= c; //copy local context back
+
+}
diff --git a/libpostproc/version.h b/libpostproc/version.h
new file mode 100644
index 0000000..f634630
--- /dev/null
+++ b/libpostproc/version.h
@@ -0,0 +1,47 @@
+/*
+ * Version macros.
+ *
+ * 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 POSTPROC_POSTPROCESS_VERSION_H
+#define POSTPROC_POSTPROCESS_VERSION_H
+
+/**
+ * @file
+ * Libpostproc version macros
+ */
+
+#include "libavutil/avutil.h"
+
+#ifndef LIBPOSTPROC_VERSION_MAJOR
+#define LIBPOSTPROC_VERSION_MAJOR 52
+#define LIBPOSTPROC_VERSION_MINOR  1
+#define LIBPOSTPROC_VERSION_MICRO 100
+#endif
+
+#define LIBPOSTPROC_VERSION_INT AV_VERSION_INT(LIBPOSTPROC_VERSION_MAJOR, \
+                                               LIBPOSTPROC_VERSION_MINOR, \
+                                               LIBPOSTPROC_VERSION_MICRO)
+#define LIBPOSTPROC_VERSION     AV_VERSION(LIBPOSTPROC_VERSION_MAJOR, \
+                                           LIBPOSTPROC_VERSION_MINOR, \
+                                           LIBPOSTPROC_VERSION_MICRO)
+#define LIBPOSTPROC_BUILD       LIBPOSTPROC_VERSION_INT
+
+#define LIBPOSTPROC_IDENT       "postproc" AV_STRINGIFY(LIBPOSTPROC_VERSION)
+
+#endif /* POSTPROC_POSTPROCESS_VERSION_H */
diff --git a/library.mak b/library.mak
index b365935..2728340 100644
--- a/library.mak
+++ b/library.mak
@@ -19,7 +19,7 @@
 	$(DEPYASM) $(YASMFLAGS) -I $(<D)/ -M -o $@ $< > $(@:.o=.d)
 	$(YASM) $(YASMFLAGS) -I $(<D)/ -o $@ $<
 
-$(OBJS) $(SUBDIR)%.h.o $(TESTOBJS): CPPFLAGS += -DHAVE_AV_CONFIG_H
+$(OBJS) $(OBJS:.o=.s) $(SUBDIR)%.h.o $(TESTOBJS): CPPFLAGS += -DHAVE_AV_CONFIG_H
 $(TESTOBJS): CPPFLAGS += -DTEST
 
 $(SUBDIR)$(LIBNAME): $(OBJS)
@@ -42,11 +42,15 @@
 $(SUBDIR)$(SLIBNAME): $(SUBDIR)$(SLIBNAME_WITH_MAJOR)
 	$(Q)cd ./$(SUBDIR) && $(LN_S) $(SLIBNAME_WITH_MAJOR) $(SLIBNAME)
 
-$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SUBDIR)lib$(NAME).ver $(DEP_LIBS)
+$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(OBJS) $(SUBDIR)lib$(NAME).ver
 	$(SLIB_CREATE_DEF_CMD)
 	$$(LD) $(SHFLAGS) $(LDFLAGS) $$(LD_O) $$(filter %.o,$$^) $(FFEXTRALIBS)
 	$(SLIB_EXTRA_CMD)
 
+ifdef SUBDIR
+$(SUBDIR)$(SLIBNAME_WITH_MAJOR): $(DEP_LIBS)
+endif
+
 clean::
 	$(RM) $(addprefix $(SUBDIR),*-example$(EXESUF) *-test$(EXESUF) $(CLEANFILES) $(CLEANSUFFIXES) $(LIBSUFFIXES)) \
 	    $(CLEANSUFFIXES:%=$(SUBDIR)$(ARCH)/%) $(HOSTOBJS) $(HOSTPROGS)
@@ -57,6 +61,7 @@
 install-lib$(NAME)-shared: $(SUBDIR)$(SLIBNAME)
 	$(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);)
 	$(if $(SLIB_INSTALL_EXTRA_SHLIB),$$(INSTALL) -m 644 $(SLIB_INSTALL_EXTRA_SHLIB:%=$(SUBDIR)%) "$(SHLIBDIR)")
 	$(if $(SLIB_INSTALL_EXTRA_LIB),$(Q)mkdir -p "$(LIBDIR)")
@@ -79,8 +84,8 @@
 	-$(RM) "$(SHLIBDIR)/$(SLIBNAME_WITH_MAJOR)" \
 	       "$(SHLIBDIR)/$(SLIBNAME)"            \
 	       "$(SHLIBDIR)/$(SLIBNAME_WITH_VERSION)"
-	-$(RM) $(SLIB_INSTALL_EXTRA_SHLIB:%="$(SHLIBDIR)"%)
-	-$(RM) $(SLIB_INSTALL_EXTRA_LIB:%="$(LIBDIR)"%)
+	-$(RM)  $(SLIB_INSTALL_EXTRA_SHLIB:%="$(SHLIBDIR)/%")
+	-$(RM)  $(SLIB_INSTALL_EXTRA_LIB:%="$(LIBDIR)/%")
 	-$(RM) "$(LIBDIR)/$(LIBNAME)"
 
 uninstall-headers::
diff --git a/libswresample/Makefile b/libswresample/Makefile
new file mode 100644
index 0000000..d85ed8b
--- /dev/null
+++ b/libswresample/Makefile
@@ -0,0 +1,15 @@
+include $(SUBDIR)../config.mak
+
+NAME = swresample
+FFLIBS = avutil
+
+HEADERS = swresample.h                       \
+          version.h                          \
+
+OBJS = audioconvert.o                        \
+       dither.o                              \
+       rematrix.o                            \
+       resample.o                            \
+       swresample.o                          \
+
+TESTPROGS = swresample
diff --git a/libswresample/arm/Makefile b/libswresample/arm/Makefile
new file mode 100644
index 0000000..55683cb
--- /dev/null
+++ b/libswresample/arm/Makefile
@@ -0,0 +1,2 @@
+OBJS      += arm/audio_convert_init.o
+NEON-OBJS += arm/audio_convert_neon.o
diff --git a/libswresample/arm/audio_convert_init.c b/libswresample/arm/audio_convert_init.c
new file mode 100644
index 0000000..9fdb174
--- /dev/null
+++ b/libswresample/arm/audio_convert_init.c
@@ -0,0 +1,65 @@
+/*
+ * This file is part of libswresample.
+ *
+ * libswresample 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.
+ *
+ * libswresample is distributed in the hope that 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 libswresample; 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/cpu.h"
+#include "libavutil/arm/cpu.h"
+#include "libavutil/samplefmt.h"
+#include "libswresample/swresample_internal.h"
+#include "libswresample/audioconvert.h"
+
+void swri_oldapi_conv_flt_to_s16_neon(int16_t *dst, const float *src, int len);
+void swri_oldapi_conv_fltp_to_s16_2ch_neon(int16_t *dst, float *const *src, int len, int channels);
+void swri_oldapi_conv_fltp_to_s16_nch_neon(int16_t *dst, float *const *src, int len, int channels);
+
+static void conv_flt_to_s16_neon(uint8_t **dst, const uint8_t **src, int len){
+    swri_oldapi_conv_flt_to_s16_neon((int16_t*)*dst, (const float*)*src, len);
+}
+
+static void conv_fltp_to_s16_2ch_neon(uint8_t **dst, const uint8_t **src, int len){
+    swri_oldapi_conv_fltp_to_s16_2ch_neon((int16_t*)*dst, (float *const*)src, len, 2);
+}
+
+static void conv_fltp_to_s16_nch_neon(uint8_t **dst, const uint8_t **src, int len){
+    int channels;
+    for(channels=3; channels<SWR_CH_MAX && src[channels]; channels++)
+        ;
+    swri_oldapi_conv_fltp_to_s16_nch_neon((int16_t*)*dst, (float *const*)src, len, channels);
+}
+
+av_cold void swri_audio_convert_init_arm(struct AudioConvert *ac,
+                                       enum AVSampleFormat out_fmt,
+                                       enum AVSampleFormat in_fmt,
+                                       int channels)
+{
+    int cpu_flags = av_get_cpu_flags();
+
+    ac->simd_f= NULL;
+
+    if (have_neon(cpu_flags)) {
+        if(out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_FLTP)
+            ac->simd_f = conv_flt_to_s16_neon;
+        if(out_fmt == AV_SAMPLE_FMT_S16 && in_fmt == AV_SAMPLE_FMT_FLTP && channels == 2)
+            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;
+    }
+}
diff --git a/libswresample/arm/audio_convert_neon.S b/libswresample/arm/audio_convert_neon.S
new file mode 100644
index 0000000..471a2d8
--- /dev/null
+++ b/libswresample/arm/audio_convert_neon.S
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
+ *
+ * This file is part of libswresample.
+ *
+ * libswresample 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.
+ *
+ * libswresample is distributed in the hope that 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 libswresample; 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 swri_oldapi_conv_flt_to_s16_neon, export=1
+        subs            r2,  r2,  #8
+        vld1.32         {q0},     [r1,:128]!
+        vcvt.s32.f32    q8,  q0,  #31
+        vld1.32         {q1},     [r1,:128]!
+        vcvt.s32.f32    q9,  q1,  #31
+        beq             3f
+        bics            r12, r2,  #15
+        beq             2f
+1:      subs            r12, r12, #16
+        vqrshrn.s32     d4,  q8,  #16
+        vld1.32         {q0},     [r1,:128]!
+        vcvt.s32.f32    q0,  q0,  #31
+        vqrshrn.s32     d5,  q9,  #16
+        vld1.32         {q1},     [r1,:128]!
+        vcvt.s32.f32    q1,  q1,  #31
+        vqrshrn.s32     d6,  q0,  #16
+        vst1.16         {q2},     [r0,:128]!
+        vqrshrn.s32     d7,  q1,  #16
+        vld1.32         {q8},     [r1,:128]!
+        vcvt.s32.f32    q8,  q8,  #31
+        vld1.32         {q9},     [r1,:128]!
+        vcvt.s32.f32    q9,  q9,  #31
+        vst1.16         {q3},     [r0,:128]!
+        bne             1b
+        ands            r2,  r2,  #15
+        beq             3f
+2:      vld1.32         {q0},     [r1,:128]!
+        vqrshrn.s32     d4,  q8,  #16
+        vcvt.s32.f32    q0,  q0,  #31
+        vld1.32         {q1},     [r1,:128]!
+        vqrshrn.s32     d5,  q9,  #16
+        vcvt.s32.f32    q1,  q1,  #31
+        vqrshrn.s32     d6,  q0,  #16
+        vst1.16         {q2},     [r0,:128]!
+        vqrshrn.s32     d7,  q1,  #16
+        vst1.16         {q3},     [r0,:128]!
+        bx              lr
+3:      vqrshrn.s32     d4,  q8,  #16
+        vqrshrn.s32     d5,  q9,  #16
+        vst1.16         {q2},     [r0,:128]!
+        bx              lr
+endfunc
+
+function swri_oldapi_conv_fltp_to_s16_2ch_neon, export=1
+        ldm             r1,  {r1, r3}
+        subs            r2,  r2,  #8
+        vld1.32         {q0},     [r1,:128]!
+        vcvt.s32.f32    q8,  q0,  #31
+        vld1.32         {q1},     [r1,:128]!
+        vcvt.s32.f32    q9,  q1,  #31
+        vld1.32         {q10},    [r3,:128]!
+        vcvt.s32.f32    q10, q10, #31
+        vld1.32         {q11},    [r3,:128]!
+        vcvt.s32.f32    q11, q11, #31
+        beq             3f
+        bics            r12, r2,  #15
+        beq             2f
+1:      subs            r12, r12, #16
+        vld1.32         {q0},     [r1,:128]!
+        vcvt.s32.f32    q0,  q0,  #31
+        vsri.32         q10, q8,  #16
+        vld1.32         {q1},     [r1,:128]!
+        vcvt.s32.f32    q1,  q1,  #31
+        vld1.32         {q12},    [r3,:128]!
+        vcvt.s32.f32    q12, q12, #31
+        vld1.32         {q13},    [r3,:128]!
+        vsri.32         q11, q9,  #16
+        vst1.16         {q10},    [r0,:128]!
+        vcvt.s32.f32    q13, q13, #31
+        vst1.16         {q11},    [r0,:128]!
+        vsri.32         q12, q0,  #16
+        vld1.32         {q8},     [r1,:128]!
+        vsri.32         q13, q1,  #16
+        vst1.16         {q12},    [r0,:128]!
+        vcvt.s32.f32    q8,  q8,  #31
+        vld1.32         {q9},     [r1,:128]!
+        vcvt.s32.f32    q9,  q9,  #31
+        vld1.32         {q10},    [r3,:128]!
+        vcvt.s32.f32    q10, q10, #31
+        vld1.32         {q11},    [r3,:128]!
+        vcvt.s32.f32    q11, q11, #31
+        vst1.16         {q13},    [r0,:128]!
+        bne             1b
+        ands            r2,  r2,  #15
+        beq             3f
+2:      vsri.32         q10, q8,  #16
+        vld1.32         {q0},     [r1,:128]!
+        vcvt.s32.f32    q0,  q0,  #31
+        vld1.32         {q1},     [r1,:128]!
+        vcvt.s32.f32    q1,  q1,  #31
+        vld1.32         {q12},    [r3,:128]!
+        vcvt.s32.f32    q12, q12, #31
+        vsri.32         q11, q9,  #16
+        vld1.32         {q13},    [r3,:128]!
+        vcvt.s32.f32    q13, q13, #31
+        vst1.16         {q10},    [r0,:128]!
+        vsri.32         q12, q0,  #16
+        vst1.16         {q11},    [r0,:128]!
+        vsri.32         q13, q1,  #16
+        vst1.16         {q12-q13},[r0,:128]!
+        bx              lr
+3:      vsri.32         q10, q8,  #16
+        vsri.32         q11, q9,  #16
+        vst1.16         {q10-q11},[r0,:128]!
+        bx              lr
+endfunc
+
+function swri_oldapi_conv_fltp_to_s16_nch_neon, export=1
+        cmp             r3,  #2
+        itt             lt
+        ldrlt           r1,  [r1]
+        blt             swri_oldapi_conv_flt_to_s16_neon
+        beq             swri_oldapi_conv_fltp_to_s16_2ch_neon
+
+        push            {r4-r8, lr}
+        cmp             r3,  #4
+        lsl             r12, r3,  #1
+        blt             4f
+
+        @ 4 channels
+5:      ldm             r1!, {r4-r7}
+        mov             lr,  r2
+        mov             r8,  r0
+        vld1.32         {q8},     [r4,:128]!
+        vcvt.s32.f32    q8,  q8,  #31
+        vld1.32         {q9},     [r5,:128]!
+        vcvt.s32.f32    q9,  q9,  #31
+        vld1.32         {q10},    [r6,:128]!
+        vcvt.s32.f32    q10, q10, #31
+        vld1.32         {q11},    [r7,:128]!
+        vcvt.s32.f32    q11, q11, #31
+6:      subs            lr,  lr,  #8
+        vld1.32         {q0},     [r4,:128]!
+        vcvt.s32.f32    q0,  q0,  #31
+        vsri.32         q9,  q8,  #16
+        vld1.32         {q1},     [r5,:128]!
+        vcvt.s32.f32    q1,  q1,  #31
+        vsri.32         q11, q10, #16
+        vld1.32         {q2},     [r6,:128]!
+        vcvt.s32.f32    q2,  q2,  #31
+        vzip.32         d18, d22
+        vld1.32         {q3},     [r7,:128]!
+        vcvt.s32.f32    q3,  q3,  #31
+        vzip.32         d19, d23
+        vst1.16         {d18},    [r8], r12
+        vsri.32         q1,  q0,  #16
+        vst1.16         {d22},    [r8], r12
+        vsri.32         q3,  q2,  #16
+        vst1.16         {d19},    [r8], r12
+        vzip.32         d2,  d6
+        vst1.16         {d23},    [r8], r12
+        vzip.32         d3,  d7
+        beq             7f
+        vld1.32         {q8},     [r4,:128]!
+        vcvt.s32.f32    q8,  q8,  #31
+        vst1.16         {d2},     [r8], r12
+        vld1.32         {q9},     [r5,:128]!
+        vcvt.s32.f32    q9,  q9,  #31
+        vst1.16         {d6},     [r8], r12
+        vld1.32         {q10},    [r6,:128]!
+        vcvt.s32.f32    q10, q10, #31
+        vst1.16         {d3},     [r8], r12
+        vld1.32         {q11},    [r7,:128]!
+        vcvt.s32.f32    q11, q11, #31
+        vst1.16         {d7},     [r8], r12
+        b               6b
+7:      vst1.16         {d2},     [r8], r12
+        vst1.16         {d6},     [r8], r12
+        vst1.16         {d3},     [r8], r12
+        vst1.16         {d7},     [r8], r12
+        subs            r3,  r3,  #4
+        it              eq
+        popeq           {r4-r8, pc}
+        cmp             r3,  #4
+        add             r0,  r0,  #8
+        bge             5b
+
+        @ 2 channels
+4:      cmp             r3,  #2
+        blt             4f
+        ldm             r1!, {r4-r5}
+        mov             lr,  r2
+        mov             r8,  r0
+        tst             lr,  #8
+        vld1.32         {q8},     [r4,:128]!
+        vcvt.s32.f32    q8,  q8,  #31
+        vld1.32         {q9},     [r5,:128]!
+        vcvt.s32.f32    q9,  q9,  #31
+        vld1.32         {q10},    [r4,:128]!
+        vcvt.s32.f32    q10, q10, #31
+        vld1.32         {q11},    [r5,:128]!
+        vcvt.s32.f32    q11, q11, #31
+        beq             6f
+        subs            lr,  lr,  #8
+        beq             7f
+        vsri.32         d18, d16, #16
+        vsri.32         d19, d17, #16
+        vld1.32         {q8},     [r4,:128]!
+        vcvt.s32.f32    q8,  q8,  #31
+        vst1.32         {d18[0]}, [r8], r12
+        vsri.32         d22, d20, #16
+        vst1.32         {d18[1]}, [r8], r12
+        vsri.32         d23, d21, #16
+        vst1.32         {d19[0]}, [r8], r12
+        vst1.32         {d19[1]}, [r8], r12
+        vld1.32         {q9},     [r5,:128]!
+        vcvt.s32.f32    q9,  q9,  #31
+        vst1.32         {d22[0]}, [r8], r12
+        vst1.32         {d22[1]}, [r8], r12
+        vld1.32         {q10},    [r4,:128]!
+        vcvt.s32.f32    q10, q10, #31
+        vst1.32         {d23[0]}, [r8], r12
+        vst1.32         {d23[1]}, [r8], r12
+        vld1.32         {q11},    [r5,:128]!
+        vcvt.s32.f32    q11, q11, #31
+6:      subs            lr,  lr,  #16
+        vld1.32         {q0},     [r4,:128]!
+        vcvt.s32.f32    q0,  q0,  #31
+        vsri.32         d18, d16, #16
+        vld1.32         {q1},     [r5,:128]!
+        vcvt.s32.f32    q1,  q1,  #31
+        vsri.32         d19, d17, #16
+        vld1.32         {q2},     [r4,:128]!
+        vcvt.s32.f32    q2,  q2,  #31
+        vld1.32         {q3},     [r5,:128]!
+        vcvt.s32.f32    q3,  q3,  #31
+        vst1.32         {d18[0]}, [r8], r12
+        vsri.32         d22, d20, #16
+        vst1.32         {d18[1]}, [r8], r12
+        vsri.32         d23, d21, #16
+        vst1.32         {d19[0]}, [r8], r12
+        vsri.32         d2,  d0,  #16
+        vst1.32         {d19[1]}, [r8], r12
+        vsri.32         d3,  d1,  #16
+        vst1.32         {d22[0]}, [r8], r12
+        vsri.32         d6,  d4,  #16
+        vst1.32         {d22[1]}, [r8], r12
+        vsri.32         d7,  d5,  #16
+        vst1.32         {d23[0]}, [r8], r12
+        vst1.32         {d23[1]}, [r8], r12
+        beq             6f
+        vld1.32         {q8},     [r4,:128]!
+        vcvt.s32.f32    q8,  q8,  #31
+        vst1.32         {d2[0]},  [r8], r12
+        vst1.32         {d2[1]},  [r8], r12
+        vld1.32         {q9},     [r5,:128]!
+        vcvt.s32.f32    q9,  q9,  #31
+        vst1.32         {d3[0]},  [r8], r12
+        vst1.32         {d3[1]},  [r8], r12
+        vld1.32         {q10},    [r4,:128]!
+        vcvt.s32.f32    q10, q10, #31
+        vst1.32         {d6[0]},  [r8], r12
+        vst1.32         {d6[1]},  [r8], r12
+        vld1.32         {q11},    [r5,:128]!
+        vcvt.s32.f32    q11, q11, #31
+        vst1.32         {d7[0]},  [r8], r12
+        vst1.32         {d7[1]},  [r8], r12
+        bgt             6b
+6:      vst1.32         {d2[0]},  [r8], r12
+        vst1.32         {d2[1]},  [r8], r12
+        vst1.32         {d3[0]},  [r8], r12
+        vst1.32         {d3[1]},  [r8], r12
+        vst1.32         {d6[0]},  [r8], r12
+        vst1.32         {d6[1]},  [r8], r12
+        vst1.32         {d7[0]},  [r8], r12
+        vst1.32         {d7[1]},  [r8], r12
+        b               8f
+7:      vsri.32         d18, d16, #16
+        vsri.32         d19, d17, #16
+        vst1.32         {d18[0]}, [r8], r12
+        vsri.32         d22, d20, #16
+        vst1.32         {d18[1]}, [r8], r12
+        vsri.32         d23, d21, #16
+        vst1.32         {d19[0]}, [r8], r12
+        vst1.32         {d19[1]}, [r8], r12
+        vst1.32         {d22[0]}, [r8], r12
+        vst1.32         {d22[1]}, [r8], r12
+        vst1.32         {d23[0]}, [r8], r12
+        vst1.32         {d23[1]}, [r8], r12
+8:      subs            r3,  r3,  #2
+        add             r0,  r0,  #4
+        it              eq
+        popeq           {r4-r8, pc}
+
+        @ 1 channel
+4:      ldr             r4,  [r1]
+        tst             r2,  #8
+        mov             lr,  r2
+        mov             r5,  r0
+        vld1.32         {q0},     [r4,:128]!
+        vcvt.s32.f32    q0,  q0,  #31
+        vld1.32         {q1},     [r4,:128]!
+        vcvt.s32.f32    q1,  q1,  #31
+        bne             8f
+6:      subs            lr,  lr,  #16
+        vld1.32         {q2},     [r4,:128]!
+        vcvt.s32.f32    q2,  q2,  #31
+        vld1.32         {q3},     [r4,:128]!
+        vcvt.s32.f32    q3,  q3,  #31
+        vst1.16         {d0[1]},  [r5,:16], r12
+        vst1.16         {d0[3]},  [r5,:16], r12
+        vst1.16         {d1[1]},  [r5,:16], r12
+        vst1.16         {d1[3]},  [r5,:16], r12
+        vst1.16         {d2[1]},  [r5,:16], r12
+        vst1.16         {d2[3]},  [r5,:16], r12
+        vst1.16         {d3[1]},  [r5,:16], r12
+        vst1.16         {d3[3]},  [r5,:16], r12
+        beq             7f
+        vld1.32         {q0},     [r4,:128]!
+        vcvt.s32.f32    q0,  q0,  #31
+        vld1.32         {q1},     [r4,:128]!
+        vcvt.s32.f32    q1,  q1,  #31
+7:      vst1.16         {d4[1]},  [r5,:16], r12
+        vst1.16         {d4[3]},  [r5,:16], r12
+        vst1.16         {d5[1]},  [r5,:16], r12
+        vst1.16         {d5[3]},  [r5,:16], r12
+        vst1.16         {d6[1]},  [r5,:16], r12
+        vst1.16         {d6[3]},  [r5,:16], r12
+        vst1.16         {d7[1]},  [r5,:16], r12
+        vst1.16         {d7[3]},  [r5,:16], r12
+        bgt             6b
+        pop             {r4-r8, pc}
+8:      subs            lr,  lr,  #8
+        vst1.16         {d0[1]},  [r5,:16], r12
+        vst1.16         {d0[3]},  [r5,:16], r12
+        vst1.16         {d1[1]},  [r5,:16], r12
+        vst1.16         {d1[3]},  [r5,:16], r12
+        vst1.16         {d2[1]},  [r5,:16], r12
+        vst1.16         {d2[3]},  [r5,:16], r12
+        vst1.16         {d3[1]},  [r5,:16], r12
+        vst1.16         {d3[3]},  [r5,:16], r12
+        it              eq
+        popeq           {r4-r8, pc}
+        vld1.32         {q0},     [r4,:128]!
+        vcvt.s32.f32    q0,  q0,  #31
+        vld1.32         {q1},     [r4,:128]!
+        vcvt.s32.f32    q1,  q1,  #31
+        b               6b
+endfunc
diff --git a/libswresample/audioconvert.c b/libswresample/audioconvert.c
new file mode 100644
index 0000000..d2e3722
--- /dev/null
+++ b/libswresample/audioconvert.c
@@ -0,0 +1,208 @@
+/*
+ * audio conversion
+ * 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 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 conversion
+ * @author Michael Niedermayer <michaelni@gmx.at>
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/avassert.h"
+#include "libavutil/libm.h"
+#include "libavutil/samplefmt.h"
+#include "audioconvert.h"
+
+
+#define CONV_FUNC_NAME(dst_fmt, src_fmt) conv_ ## src_fmt ## _to_ ## dst_fmt
+
+//FIXME rounding ?
+#define CONV_FUNC(ofmt, otype, ifmt, expr)\
+static void CONV_FUNC_NAME(ofmt, ifmt)(uint8_t *po, const uint8_t *pi, int is, int os, uint8_t *end)\
+{\
+    uint8_t *end2 = end - 3*os;\
+    while(po < end2){\
+        *(otype*)po = expr; pi += is; po += os;\
+        *(otype*)po = expr; pi += is; po += os;\
+        *(otype*)po = expr; pi += is; po += os;\
+        *(otype*)po = expr; pi += is; po += os;\
+    }\
+    while(po < end){\
+        *(otype*)po = expr; pi += is; po += os;\
+    }\
+}
+
+//FIXME put things below under ifdefs so we do not waste space for cases no codec will need
+CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_U8 ,  *(const uint8_t*)pi)
+CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<8)
+CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<24)
+CONV_FUNC(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0f/ (1<<7)))
+CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
+CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80)
+CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16,  *(const int16_t*)pi)
+CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16,  *(const int16_t*)pi<<16)
+CONV_FUNC(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_S16,  *(const int16_t*)pi*(1.0f/ (1<<15)))
+CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S16,  *(const int16_t*)pi*(1.0 / (1<<15)))
+CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80)
+CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32,  *(const int32_t*)pi>>16)
+CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32,  *(const int32_t*)pi)
+CONV_FUNC(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_S32,  *(const int32_t*)pi*(1.0f/ (1U<<31)))
+CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S32,  *(const int32_t*)pi*(1.0 / (1U<<31)))
+CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(  lrintf(*(const float*)pi * (1<<7)) + 0x80))
+CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(  lrintf(*(const float*)pi * (1<<15))))
+CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31))))
+CONV_FUNC(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_FLT, *(const float*)pi)
+CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_FLT, *(const float*)pi)
+CONV_FUNC(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(  lrint(*(const double*)pi * (1<<7)) + 0x80))
+CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(  lrint(*(const double*)pi * (1<<15))))
+CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31))))
+CONV_FUNC(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_DBL, *(const double*)pi)
+CONV_FUNC(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_DBL, *(const double*)pi)
+
+#define FMT_PAIR_FUNC(out, in) [out + AV_SAMPLE_FMT_NB*in] = CONV_FUNC_NAME(out, in)
+
+static conv_func_type * const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB*AV_SAMPLE_FMT_NB] = {
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_U8 ),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8 ),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8 ),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8 ),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8 ),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_S16),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_S32),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_FLT),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8 , AV_SAMPLE_FMT_DBL),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL),
+    FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL),
+};
+
+static void cpy1(uint8_t **dst, const uint8_t **src, int len){
+    memcpy(*dst, *src, len);
+}
+static void cpy2(uint8_t **dst, const uint8_t **src, int len){
+    memcpy(*dst, *src, 2*len);
+}
+static void cpy4(uint8_t **dst, const uint8_t **src, int len){
+    memcpy(*dst, *src, 4*len);
+}
+static void cpy8(uint8_t **dst, const uint8_t **src, int len){
+    memcpy(*dst, *src, 8*len);
+}
+
+AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt,
+                                       enum AVSampleFormat in_fmt,
+                                       int channels, const int *ch_map,
+                                       int flags)
+{
+    AudioConvert *ctx;
+    conv_func_type *f = fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt) + AV_SAMPLE_FMT_NB*av_get_packed_sample_fmt(in_fmt)];
+
+    if (!f)
+        return NULL;
+    ctx = av_mallocz(sizeof(*ctx));
+    if (!ctx)
+        return NULL;
+
+    if(channels == 1){
+         in_fmt = av_get_planar_sample_fmt( in_fmt);
+        out_fmt = av_get_planar_sample_fmt(out_fmt);
+    }
+
+    ctx->channels = channels;
+    ctx->conv_f   = f;
+    ctx->ch_map   = ch_map;
+    if (in_fmt == AV_SAMPLE_FMT_U8 || in_fmt == AV_SAMPLE_FMT_U8P)
+        memset(ctx->silence, 0x80, sizeof(ctx->silence));
+
+    if(out_fmt == in_fmt && !ch_map) {
+        switch(av_get_bytes_per_sample(in_fmt)){
+            case 1:ctx->simd_f = cpy1; break;
+            case 2:ctx->simd_f = cpy2; break;
+            case 4:ctx->simd_f = cpy4; break;
+            case 8:ctx->simd_f = cpy8; break;
+        }
+    }
+
+    if(HAVE_YASM && HAVE_MMX) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);
+    if(ARCH_ARM)              swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);
+
+    return ctx;
+}
+
+void swri_audio_convert_free(AudioConvert **ctx)
+{
+    av_freep(ctx);
+}
+
+int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len)
+{
+    int ch;
+    int off=0;
+    const int os= (out->planar ? 1 :out->ch_count) *out->bps;
+
+    av_assert0(ctx->channels == out->ch_count);
+
+    //FIXME optimize common cases
+
+    if(ctx->simd_f && !ctx->ch_map){
+        off = len&~15;
+        av_assert1(off>=0);
+        av_assert1(off<=len);
+        av_assert2(ctx->channels == SWR_CH_MAX || !in->ch[ctx->channels]);
+        if(off>0){
+            if(out->planar == in->planar){
+                int planes = out->planar ? out->ch_count : 1;
+                for(ch=0; ch<planes; ch++){
+                    ctx->simd_f(out->ch+ch, (const uint8_t **)in->ch+ch, off * (out->planar ? 1 :out->ch_count));
+                }
+            }else{
+                ctx->simd_f(out->ch, (const uint8_t **)in->ch, off);
+            }
+        }
+        if(off == len)
+            return 0;
+    }
+
+    for(ch=0; ch<ctx->channels; ch++){
+        const int ich= ctx->ch_map ? ctx->ch_map[ch] : ch;
+        const int is= ich < 0 ? 0 : (in->planar ? 1 : in->ch_count) * in->bps;
+        const uint8_t *pi= ich < 0 ? ctx->silence : in->ch[ich];
+        uint8_t       *po= out->ch[ch];
+        uint8_t *end= po + os*len;
+        if(!po)
+            continue;
+        ctx->conv_f(po+off*os, pi+off*is, is, os, end);
+    }
+    return 0;
+}
diff --git a/libswresample/audioconvert.h b/libswresample/audioconvert.h
new file mode 100644
index 0000000..9a234d4
--- /dev/null
+++ b/libswresample/audioconvert.h
@@ -0,0 +1,77 @@
+/*
+ * audio conversion
+ * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (c) 2008 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
+ */
+
+#ifndef SWR_AUDIOCONVERT_H
+#define SWR_AUDIOCONVERT_H
+
+/**
+ * @file
+ * Audio format conversion routines
+ */
+
+
+#include "swresample_internal.h"
+#include "libavutil/cpu.h"
+#include "libavutil/audioconvert.h"
+
+
+typedef void (conv_func_type)(uint8_t *po, const uint8_t *pi, int is, int os, uint8_t *end);
+typedef void (simd_func_type)(uint8_t **dst, const uint8_t **src, int len);
+
+typedef struct AudioConvert {
+    int channels;
+    conv_func_type *conv_f;
+    simd_func_type *simd_f;
+    const int *ch_map;
+    uint8_t silence[8]; ///< silence input sample
+}AudioConvert;
+
+/**
+ * Create an audio sample format converter context
+ * @param out_fmt Output sample format
+ * @param in_fmt Input sample format
+ * @param channels Number of channels
+ * @param flags See AV_CPU_FLAG_xx
+ * @param ch_map list of the channels id to pick from the source stream, NULL
+ *               if all channels must be selected
+ * @return NULL on error
+ */
+AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt,
+                                       enum AVSampleFormat in_fmt,
+                                       int channels, const int *ch_map,
+                                       int flags);
+
+/**
+ * Free audio sample format converter context.
+ * and set the pointer to NULL
+ */
+void swri_audio_convert_free(AudioConvert **ctx);
+
+/**
+ * Convert between audio sample formats
+ * @param[in] out array of output buffers for each channel. set to NULL to ignore processing of the given channel.
+ * @param[in] in array of input buffers for each channel
+ * @param len length of audio frame size (measured in samples)
+ */
+int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len);
+
+#endif /* AUDIOCONVERT_H */
diff --git a/libswresample/dither.c b/libswresample/dither.c
new file mode 100644
index 0000000..79113f4
--- /dev/null
+++ b/libswresample/dither.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2012 Michael Niedermayer (michaelni@gmx.at)
+ *
+ * This file is part of libswresample
+ *
+ * libswresample 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.
+ *
+ * libswresample is distributed in the hope that 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 libswresample; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#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;
+#define TMP_EXTRA 2
+    double *tmp = av_malloc((len + TMP_EXTRA) * sizeof(double));
+    int i;
+
+    out_fmt = av_get_packed_sample_fmt(out_fmt);
+    in_fmt  = av_get_packed_sample_fmt( in_fmt);
+
+    if(in_fmt == AV_SAMPLE_FMT_FLT || in_fmt == AV_SAMPLE_FMT_DBL){
+        if(out_fmt == AV_SAMPLE_FMT_S32) scale = 1.0/(1L<<31);
+        if(out_fmt == AV_SAMPLE_FMT_S16) scale = 1.0/(1L<<15);
+        if(out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1.0/(1L<< 7);
+    }
+    if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_S16) scale = 1L<<16;
+    if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<24;
+    if(in_fmt == AV_SAMPLE_FMT_S16 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<8;
+
+    scale *= s->dither_scale;
+
+    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;
+            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);
+        }
+    }
+
+    av_free(tmp);
+}
diff --git a/libswresample/libswresample.v b/libswresample/libswresample.v
new file mode 100644
index 0000000..9b797bd
--- /dev/null
+++ b/libswresample/libswresample.v
@@ -0,0 +1,4 @@
+LIBSWRESAMPLE_$MAJOR {
+        global: swr_*; ff_*; swresample_*;
+        local: *;
+};
diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c
new file mode 100644
index 0000000..72da438
--- /dev/null
+++ b/libswresample/rematrix.c
@@ -0,0 +1,497 @@
+/*
+ * Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
+ *
+ * This file is part of libswresample
+ *
+ * libswresample 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.
+ *
+ * libswresample is distributed in the hope that 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 libswresample; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "swresample_internal.h"
+#include "libavutil/audioconvert.h"
+#include "libavutil/avassert.h"
+
+#define ONE (1.0)
+#define R(x) x
+#define SAMPLE float
+#define COEFF float
+#define INTER float
+#define RENAME(x) x ## _float
+#include "rematrix_template.c"
+#undef SAMPLE
+#undef RENAME
+#undef R
+#undef ONE
+#undef COEFF
+#undef INTER
+
+#define ONE (1.0)
+#define R(x) x
+#define SAMPLE double
+#define COEFF double
+#define INTER double
+#define RENAME(x) x ## _double
+#include "rematrix_template.c"
+#undef SAMPLE
+#undef RENAME
+#undef R
+#undef ONE
+#undef COEFF
+#undef INTER
+
+#define ONE (-32768)
+#define R(x) (((x) + 16384)>>15)
+#define SAMPLE int16_t
+#define COEFF int
+#define INTER int
+#define RENAME(x) x ## _s16
+#include "rematrix_template.c"
+
+
+#define FRONT_LEFT             0
+#define FRONT_RIGHT            1
+#define FRONT_CENTER           2
+#define LOW_FREQUENCY          3
+#define BACK_LEFT              4
+#define BACK_RIGHT             5
+#define FRONT_LEFT_OF_CENTER   6
+#define FRONT_RIGHT_OF_CENTER  7
+#define BACK_CENTER            8
+#define SIDE_LEFT              9
+#define SIDE_RIGHT             10
+#define TOP_CENTER             11
+#define TOP_FRONT_LEFT         12
+#define TOP_FRONT_CENTER       13
+#define TOP_FRONT_RIGHT        14
+#define TOP_BACK_LEFT          15
+#define TOP_BACK_CENTER        16
+#define TOP_BACK_RIGHT         17
+
+int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
+{
+    int nb_in, nb_out, in, out;
+
+    if (!s || s->in_convert) // s needs to be allocated but not initialized
+        return AVERROR(EINVAL);
+    memset(s->matrix, 0, sizeof(s->matrix));
+    nb_in  = av_get_channel_layout_nb_channels(s->in_ch_layout);
+    nb_out = av_get_channel_layout_nb_channels(s->out_ch_layout);
+    for (out = 0; out < nb_out; out++) {
+        for (in = 0; in < nb_in; in++)
+            s->matrix[out][in] = matrix[in];
+        matrix += stride;
+    }
+    s->rematrix_custom = 1;
+    return 0;
+}
+
+static int even(int64_t layout){
+    if(!layout) return 1;
+    if(layout&(layout-1)) return 1;
+    return 0;
+}
+
+static int clean_layout(SwrContext *s, int64_t layout){
+    if((layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == AV_CH_LAYOUT_STEREO_DOWNMIX)
+        return AV_CH_LAYOUT_STEREO;
+
+    if(layout && layout != AV_CH_FRONT_CENTER && !(layout&(layout-1))) {
+        char buf[128];
+        av_get_channel_layout_string(buf, sizeof(buf), -1, layout);
+        av_log(s, AV_LOG_VERBOSE, "Treating %s as mono\n", buf);
+        return AV_CH_FRONT_CENTER;
+    }
+
+    return layout;
+}
+
+static int sane_layout(int64_t layout){
+    if(!(layout & AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker
+        return 0;
+    if(!even(layout & (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT))) // no asymetric front
+        return 0;
+    if(!even(layout & (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)))   // no asymetric side
+        return 0;
+    if(!even(layout & (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT)))
+        return 0;
+    if(!even(layout & (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)))
+        return 0;
+    if(av_get_channel_layout_nb_channels(layout) >= SWR_CH_MAX)
+        return 0;
+
+    return 1;
+}
+
+av_cold static int auto_matrix(SwrContext *s)
+{
+    int i, j, out_i;
+    double matrix[64][64]={{0}};
+    int64_t unaccounted, in_ch_layout, out_ch_layout;
+    double maxcoef=0;
+    char buf[128];
+    const int matrix_encoding = s->matrix_encoding;
+
+    in_ch_layout = clean_layout(s, s->in_ch_layout);
+    if(!sane_layout(in_ch_layout)){
+        av_get_channel_layout_string(buf, sizeof(buf), -1, s->in_ch_layout);
+        av_log(s, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf);
+        return AVERROR(EINVAL);
+    }
+
+    out_ch_layout = clean_layout(s, s->out_ch_layout);
+    if(!sane_layout(out_ch_layout)){
+        av_get_channel_layout_string(buf, sizeof(buf), -1, s->out_ch_layout);
+        av_log(s, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf);
+        return AVERROR(EINVAL);
+    }
+
+    memset(s->matrix, 0, sizeof(s->matrix));
+    for(i=0; i<64; i++){
+        if(in_ch_layout & out_ch_layout & (1LL<<i))
+            matrix[i][i]= 1.0;
+    }
+
+    unaccounted= in_ch_layout & ~out_ch_layout;
+
+//FIXME implement dolby surround
+//FIXME implement full ac3
+
+
+    if(unaccounted & AV_CH_FRONT_CENTER){
+        if((out_ch_layout & AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO){
+            if(in_ch_layout & AV_CH_LAYOUT_STEREO) {
+                matrix[ FRONT_LEFT][FRONT_CENTER]+= s->clev;
+                matrix[FRONT_RIGHT][FRONT_CENTER]+= s->clev;
+            } else {
+                matrix[ FRONT_LEFT][FRONT_CENTER]+= M_SQRT1_2;
+                matrix[FRONT_RIGHT][FRONT_CENTER]+= M_SQRT1_2;
+            }
+        }else
+            av_assert0(0);
+    }
+    if(unaccounted & AV_CH_LAYOUT_STEREO){
+        if(out_ch_layout & AV_CH_FRONT_CENTER){
+            matrix[FRONT_CENTER][ FRONT_LEFT]+= M_SQRT1_2;
+            matrix[FRONT_CENTER][FRONT_RIGHT]+= M_SQRT1_2;
+            if(in_ch_layout & AV_CH_FRONT_CENTER)
+                matrix[FRONT_CENTER][ FRONT_CENTER] = s->clev*sqrt(2);
+        }else
+            av_assert0(0);
+    }
+
+    if(unaccounted & AV_CH_BACK_CENTER){
+        if(out_ch_layout & AV_CH_BACK_LEFT){
+            matrix[ BACK_LEFT][BACK_CENTER]+= M_SQRT1_2;
+            matrix[BACK_RIGHT][BACK_CENTER]+= M_SQRT1_2;
+        }else if(out_ch_layout & AV_CH_SIDE_LEFT){
+            matrix[ SIDE_LEFT][BACK_CENTER]+= M_SQRT1_2;
+            matrix[SIDE_RIGHT][BACK_CENTER]+= M_SQRT1_2;
+        }else if(out_ch_layout & AV_CH_FRONT_LEFT){
+            if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY ||
+                matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
+                if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) {
+                    matrix[FRONT_LEFT ][BACK_CENTER] -= s->slev * M_SQRT1_2;
+                    matrix[FRONT_RIGHT][BACK_CENTER] += s->slev * M_SQRT1_2;
+                } else {
+                    matrix[FRONT_LEFT ][BACK_CENTER] -= s->slev;
+                    matrix[FRONT_RIGHT][BACK_CENTER] += s->slev;
+                }
+            } else {
+                matrix[ FRONT_LEFT][BACK_CENTER]+= s->slev*M_SQRT1_2;
+                matrix[FRONT_RIGHT][BACK_CENTER]+= s->slev*M_SQRT1_2;
+            }
+        }else if(out_ch_layout & AV_CH_FRONT_CENTER){
+            matrix[ FRONT_CENTER][BACK_CENTER]+= s->slev*M_SQRT1_2;
+        }else
+            av_assert0(0);
+    }
+    if(unaccounted & AV_CH_BACK_LEFT){
+        if(out_ch_layout & AV_CH_BACK_CENTER){
+            matrix[BACK_CENTER][ BACK_LEFT]+= M_SQRT1_2;
+            matrix[BACK_CENTER][BACK_RIGHT]+= M_SQRT1_2;
+        }else if(out_ch_layout & AV_CH_SIDE_LEFT){
+            if(in_ch_layout & AV_CH_SIDE_LEFT){
+                matrix[ SIDE_LEFT][ BACK_LEFT]+= M_SQRT1_2;
+                matrix[SIDE_RIGHT][BACK_RIGHT]+= M_SQRT1_2;
+            }else{
+            matrix[ SIDE_LEFT][ BACK_LEFT]+= 1.0;
+            matrix[SIDE_RIGHT][BACK_RIGHT]+= 1.0;
+            }
+        }else if(out_ch_layout & AV_CH_FRONT_LEFT){
+            if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
+                matrix[FRONT_LEFT ][BACK_LEFT ] -= s->slev * M_SQRT1_2;
+                matrix[FRONT_LEFT ][BACK_RIGHT] -= s->slev * M_SQRT1_2;
+                matrix[FRONT_RIGHT][BACK_LEFT ] += s->slev * M_SQRT1_2;
+                matrix[FRONT_RIGHT][BACK_RIGHT] += s->slev * M_SQRT1_2;
+            } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
+                matrix[FRONT_LEFT ][BACK_LEFT ] -= s->slev * SQRT3_2;
+                matrix[FRONT_LEFT ][BACK_RIGHT] -= s->slev * M_SQRT1_2;
+                matrix[FRONT_RIGHT][BACK_LEFT ] += s->slev * M_SQRT1_2;
+                matrix[FRONT_RIGHT][BACK_RIGHT] += s->slev * SQRT3_2;
+            } else {
+                matrix[ FRONT_LEFT][ BACK_LEFT] += s->slev;
+                matrix[FRONT_RIGHT][BACK_RIGHT] += s->slev;
+            }
+        }else if(out_ch_layout & AV_CH_FRONT_CENTER){
+            matrix[ FRONT_CENTER][BACK_LEFT ]+= s->slev*M_SQRT1_2;
+            matrix[ FRONT_CENTER][BACK_RIGHT]+= s->slev*M_SQRT1_2;
+        }else
+            av_assert0(0);
+    }
+
+    if(unaccounted & AV_CH_SIDE_LEFT){
+        if(out_ch_layout & AV_CH_BACK_LEFT){
+            /* if back channels do not exist in the input, just copy side
+               channels to back channels, otherwise mix side into back */
+            if (in_ch_layout & AV_CH_BACK_LEFT) {
+                matrix[BACK_LEFT ][SIDE_LEFT ] += M_SQRT1_2;
+                matrix[BACK_RIGHT][SIDE_RIGHT] += M_SQRT1_2;
+            } else {
+                matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0;
+                matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0;
+            }
+        }else if(out_ch_layout & AV_CH_BACK_CENTER){
+            matrix[BACK_CENTER][ SIDE_LEFT]+= M_SQRT1_2;
+            matrix[BACK_CENTER][SIDE_RIGHT]+= M_SQRT1_2;
+        }else if(out_ch_layout & AV_CH_FRONT_LEFT){
+            if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
+                matrix[FRONT_LEFT ][SIDE_LEFT ] -= s->slev * M_SQRT1_2;
+                matrix[FRONT_LEFT ][SIDE_RIGHT] -= s->slev * M_SQRT1_2;
+                matrix[FRONT_RIGHT][SIDE_LEFT ] += s->slev * M_SQRT1_2;
+                matrix[FRONT_RIGHT][SIDE_RIGHT] += s->slev * M_SQRT1_2;
+            } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
+                matrix[FRONT_LEFT ][SIDE_LEFT ] -= s->slev * SQRT3_2;
+                matrix[FRONT_LEFT ][SIDE_RIGHT] -= s->slev * M_SQRT1_2;
+                matrix[FRONT_RIGHT][SIDE_LEFT ] += s->slev * M_SQRT1_2;
+                matrix[FRONT_RIGHT][SIDE_RIGHT] += s->slev * SQRT3_2;
+            } else {
+                matrix[ FRONT_LEFT][ SIDE_LEFT] += s->slev;
+                matrix[FRONT_RIGHT][SIDE_RIGHT] += s->slev;
+            }
+        }else if(out_ch_layout & AV_CH_FRONT_CENTER){
+            matrix[ FRONT_CENTER][SIDE_LEFT ]+= s->slev*M_SQRT1_2;
+            matrix[ FRONT_CENTER][SIDE_RIGHT]+= s->slev*M_SQRT1_2;
+        }else
+            av_assert0(0);
+    }
+
+    if(unaccounted & AV_CH_FRONT_LEFT_OF_CENTER){
+        if(out_ch_layout & AV_CH_FRONT_LEFT){
+            matrix[ FRONT_LEFT][ FRONT_LEFT_OF_CENTER]+= 1.0;
+            matrix[FRONT_RIGHT][FRONT_RIGHT_OF_CENTER]+= 1.0;
+        }else if(out_ch_layout & AV_CH_FRONT_CENTER){
+            matrix[ FRONT_CENTER][ FRONT_LEFT_OF_CENTER]+= M_SQRT1_2;
+            matrix[ FRONT_CENTER][FRONT_RIGHT_OF_CENTER]+= M_SQRT1_2;
+        }else
+            av_assert0(0);
+    }
+    /* mix LFE into front left/right or center */
+    if (unaccounted & AV_CH_LOW_FREQUENCY) {
+        if (out_ch_layout & AV_CH_FRONT_CENTER) {
+            matrix[FRONT_CENTER][LOW_FREQUENCY] += s->lfe_mix_level;
+        } else if (out_ch_layout & AV_CH_FRONT_LEFT) {
+            matrix[FRONT_LEFT ][LOW_FREQUENCY] += s->lfe_mix_level * M_SQRT1_2;
+            matrix[FRONT_RIGHT][LOW_FREQUENCY] += s->lfe_mix_level * M_SQRT1_2;
+        } else
+            av_assert0(0);
+    }
+
+    for(out_i=i=0; i<64; i++){
+        double sum=0;
+        int in_i=0;
+        for(j=0; j<64; j++){
+            s->matrix[out_i][in_i]= matrix[i][j];
+            if(matrix[i][j]){
+                sum += fabs(matrix[i][j]);
+            }
+            if(in_ch_layout & (1ULL<<j))
+                in_i++;
+        }
+        maxcoef= FFMAX(maxcoef, sum);
+        if(out_ch_layout & (1ULL<<i))
+            out_i++;
+    }
+    if(s->rematrix_volume  < 0)
+        maxcoef = -s->rematrix_volume;
+
+    if((   av_get_packed_sample_fmt(s->out_sample_fmt) < AV_SAMPLE_FMT_FLT
+        || av_get_packed_sample_fmt(s->int_sample_fmt) < AV_SAMPLE_FMT_FLT) && maxcoef > 1.0){
+        for(i=0; i<SWR_CH_MAX; i++)
+            for(j=0; j<SWR_CH_MAX; j++){
+                s->matrix[i][j] /= maxcoef;
+            }
+    }
+
+    if(s->rematrix_volume > 0){
+        for(i=0; i<SWR_CH_MAX; i++)
+            for(j=0; j<SWR_CH_MAX; j++){
+                s->matrix[i][j] *= s->rematrix_volume;
+            }
+    }
+
+    for(i=0; i<av_get_channel_layout_nb_channels(out_ch_layout); i++){
+        for(j=0; j<av_get_channel_layout_nb_channels(in_ch_layout); j++){
+            av_log(NULL, AV_LOG_DEBUG, "%f ", s->matrix[i][j]);
+        }
+        av_log(NULL, AV_LOG_DEBUG, "\n");
+    }
+    return 0;
+}
+
+av_cold int swri_rematrix_init(SwrContext *s){
+    int i, j;
+    int nb_in  = av_get_channel_layout_nb_channels(s->in_ch_layout);
+    int nb_out = av_get_channel_layout_nb_channels(s->out_ch_layout);
+
+    s->mix_any_f = NULL;
+
+    if (!s->rematrix_custom) {
+        int r = auto_matrix(s);
+        if (r)
+            return r;
+    }
+    if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){
+        s->native_matrix = av_mallocz(nb_in * nb_out * sizeof(int));
+        s->native_one    = av_mallocz(sizeof(int));
+        for (i = 0; i < nb_out; i++)
+            for (j = 0; j < nb_in; j++)
+                ((int*)s->native_matrix)[i * nb_in + j] = lrintf(s->matrix[i][j] * 32768);
+        *((int*)s->native_one) = 32768;
+        s->mix_1_1_f = (mix_1_1_func_type*)copy_s16;
+        s->mix_2_1_f = (mix_2_1_func_type*)sum2_s16;
+        s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s16(s);
+    }else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){
+        s->native_matrix = av_mallocz(nb_in * nb_out * sizeof(float));
+        s->native_one    = av_mallocz(sizeof(float));
+        for (i = 0; i < nb_out; i++)
+            for (j = 0; j < nb_in; j++)
+                ((float*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
+        *((float*)s->native_one) = 1.0;
+        s->mix_1_1_f = (mix_1_1_func_type*)copy_float;
+        s->mix_2_1_f = (mix_2_1_func_type*)sum2_float;
+        s->mix_any_f = (mix_any_func_type*)get_mix_any_func_float(s);
+    }else if(s->midbuf.fmt == AV_SAMPLE_FMT_DBLP){
+        s->native_matrix = av_mallocz(nb_in * nb_out * sizeof(double));
+        s->native_one    = av_mallocz(sizeof(double));
+        for (i = 0; i < nb_out; i++)
+            for (j = 0; j < nb_in; j++)
+                ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
+        *((double*)s->native_one) = 1.0;
+        s->mix_1_1_f = (mix_1_1_func_type*)copy_double;
+        s->mix_2_1_f = (mix_2_1_func_type*)sum2_double;
+        s->mix_any_f = (mix_any_func_type*)get_mix_any_func_double(s);
+    }else
+        av_assert0(0);
+    //FIXME quantize for integeres
+    for (i = 0; i < SWR_CH_MAX; i++) {
+        int ch_in=0;
+        for (j = 0; j < SWR_CH_MAX; j++) {
+            s->matrix32[i][j]= lrintf(s->matrix[i][j] * 32768);
+            if(s->matrix[i][j])
+                s->matrix_ch[i][++ch_in]= j;
+        }
+        s->matrix_ch[i][0]= ch_in;
+    }
+
+    if(HAVE_YASM && HAVE_MMX) swri_rematrix_init_x86(s);
+
+    return 0;
+}
+
+av_cold void swri_rematrix_free(SwrContext *s){
+    av_freep(&s->native_matrix);
+    av_freep(&s->native_one);
+    av_freep(&s->native_simd_matrix);
+}
+
+int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy){
+    int out_i, in_i, i, j;
+    int len1 = 0;
+    int off = 0;
+
+    if(s->mix_any_f) {
+        s->mix_any_f(out->ch, (const uint8_t **)in->ch, s->native_matrix, len);
+        return 0;
+    }
+
+    if(s->mix_2_1_simd || s->mix_1_1_simd){
+        len1= len&~15;
+        off = len1 * out->bps;
+    }
+
+    av_assert0(out->ch_count == av_get_channel_layout_nb_channels(s->out_ch_layout));
+    av_assert0(in ->ch_count == av_get_channel_layout_nb_channels(s-> in_ch_layout));
+
+    for(out_i=0; out_i<out->ch_count; out_i++){
+        switch(s->matrix_ch[out_i][0]){
+        case 0:
+            if(mustcopy)
+                memset(out->ch[out_i], 0, len * av_get_bytes_per_sample(s->int_sample_fmt));
+            break;
+        case 1:
+            in_i= s->matrix_ch[out_i][1];
+            if(s->matrix[out_i][in_i]!=1.0){
+                if(s->mix_1_1_simd && len1)
+                    s->mix_1_1_simd(out->ch[out_i]    , in->ch[in_i]    , s->native_simd_matrix, in->ch_count*out_i + in_i, len1);
+                if(len != len1)
+                    s->mix_1_1_f   (out->ch[out_i]+off, in->ch[in_i]+off, s->native_matrix, in->ch_count*out_i + in_i, len-len1);
+            }else if(mustcopy){
+                memcpy(out->ch[out_i], in->ch[in_i], len*out->bps);
+            }else{
+                out->ch[out_i]= in->ch[in_i];
+            }
+            break;
+        case 2: {
+            int in_i1 = s->matrix_ch[out_i][1];
+            int in_i2 = s->matrix_ch[out_i][2];
+            if(s->mix_2_1_simd && len1)
+                s->mix_2_1_simd(out->ch[out_i]    , in->ch[in_i1]    , in->ch[in_i2]    , s->native_simd_matrix, in->ch_count*out_i + in_i1, in->ch_count*out_i + in_i2, len1);
+            else
+                s->mix_2_1_f   (out->ch[out_i]    , in->ch[in_i1]    , in->ch[in_i2]    , s->native_matrix, in->ch_count*out_i + in_i1, in->ch_count*out_i + in_i2, len1);
+            if(len != len1)
+                s->mix_2_1_f   (out->ch[out_i]+off, in->ch[in_i1]+off, in->ch[in_i2]+off, s->native_matrix, in->ch_count*out_i + in_i1, in->ch_count*out_i + in_i2, len-len1);
+            break;}
+        default:
+            if(s->int_sample_fmt == AV_SAMPLE_FMT_FLTP){
+                for(i=0; i<len; i++){
+                    float v=0;
+                    for(j=0; j<s->matrix_ch[out_i][0]; j++){
+                        in_i= s->matrix_ch[out_i][1+j];
+                        v+= ((float*)in->ch[in_i])[i] * s->matrix[out_i][in_i];
+                    }
+                    ((float*)out->ch[out_i])[i]= v;
+                }
+            }else if(s->int_sample_fmt == AV_SAMPLE_FMT_DBLP){
+                for(i=0; i<len; i++){
+                    double v=0;
+                    for(j=0; j<s->matrix_ch[out_i][0]; j++){
+                        in_i= s->matrix_ch[out_i][1+j];
+                        v+= ((double*)in->ch[in_i])[i] * s->matrix[out_i][in_i];
+                    }
+                    ((double*)out->ch[out_i])[i]= v;
+                }
+            }else{
+                for(i=0; i<len; i++){
+                    int v=0;
+                    for(j=0; j<s->matrix_ch[out_i][0]; j++){
+                        in_i= s->matrix_ch[out_i][1+j];
+                        v+= ((int16_t*)in->ch[in_i])[i] * s->matrix32[out_i][in_i];
+                    }
+                    ((int16_t*)out->ch[out_i])[i]= (v + 16384)>>15;
+                }
+            }
+        }
+    }
+    return 0;
+}
diff --git a/libswresample/rematrix_template.c b/libswresample/rematrix_template.c
new file mode 100644
index 0000000..627bf1f
--- /dev/null
+++ b/libswresample/rematrix_template.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
+ *
+ * This file is part of libswresample
+ *
+ * libswresample 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.
+ *
+ * libswresample is distributed in the hope that 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 libswresample; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+typedef void (RENAME(mix_any_func_type))(SAMPLE **out, const SAMPLE **in1, COEFF *coeffp, int len);
+
+static void RENAME(sum2)(SAMPLE *out, const SAMPLE *in1, const SAMPLE *in2, COEFF *coeffp, int index1, int index2, int len){
+    int i;
+    COEFF coeff1 = coeffp[index1];
+    COEFF coeff2 = coeffp[index2];
+
+    for(i=0; i<len; i++)
+        out[i] = R(coeff1*in1[i] + coeff2*in2[i]);
+}
+
+static void RENAME(copy)(SAMPLE *out, const SAMPLE *in, COEFF *coeffp, int index, int len){
+    int i;
+    COEFF coeff = coeffp[index];
+    for(i=0; i<len; i++)
+        out[i] = R(coeff*in[i]);
+}
+
+static void RENAME(mix6to2)(SAMPLE **out, const SAMPLE **in, COEFF *coeffp, int len){
+    int i;
+
+    for(i=0; i<len; i++) {
+        INTER t = in[2][i]*coeffp[0*6+2] + in[3][i]*coeffp[0*6+3];
+        out[0][i] = R(t + in[0][i]*coeffp[0*6+0] + in[4][i]*coeffp[0*6+4]);
+        out[1][i] = R(t + in[1][i]*coeffp[1*6+1] + in[5][i]*coeffp[1*6+5]);
+    }
+}
+
+static void RENAME(mix8to2)(SAMPLE **out, const SAMPLE **in, COEFF *coeffp, int len){
+    int i;
+
+    for(i=0; i<len; i++) {
+        INTER t = in[2][i]*coeffp[0*8+2] + in[3][i]*coeffp[0*8+3];
+        out[0][i] = R(t + in[0][i]*coeffp[0*8+0] + in[4][i]*coeffp[0*8+4] + in[6][i]*coeffp[0*8+6]);
+        out[1][i] = R(t + in[1][i]*coeffp[1*8+1] + in[5][i]*coeffp[1*8+5] + in[7][i]*coeffp[1*8+7]);
+    }
+}
+
+static RENAME(mix_any_func_type) *RENAME(get_mix_any_func)(SwrContext *s){
+    if(   s->out_ch_layout == AV_CH_LAYOUT_STEREO && (s->in_ch_layout == AV_CH_LAYOUT_5POINT1 || s->in_ch_layout == AV_CH_LAYOUT_5POINT1_BACK)
+       && s->matrix[0][2] == s->matrix[1][2] && s->matrix[0][3] == s->matrix[1][3]
+       && !s->matrix[0][1] && !s->matrix[0][5] && !s->matrix[1][0] && !s->matrix[1][4]
+    )
+        return RENAME(mix6to2);
+
+    if(   s->out_ch_layout == AV_CH_LAYOUT_STEREO && s->in_ch_layout == AV_CH_LAYOUT_7POINT1
+       && s->matrix[0][2] == s->matrix[1][2] && s->matrix[0][3] == s->matrix[1][3]
+       && !s->matrix[0][1] && !s->matrix[0][5] && !s->matrix[1][0] && !s->matrix[1][4]
+       && !s->matrix[0][7] && !s->matrix[1][6]
+    )
+        return RENAME(mix8to2);
+
+    return NULL;
+}
diff --git a/libswresample/resample.c b/libswresample/resample.c
new file mode 100644
index 0000000..bf412dd
--- /dev/null
+++ b/libswresample/resample.c
@@ -0,0 +1,459 @@
+/*
+ * audio resampling
+ * Copyright (c) 2004-2012 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
+ * audio resampling
+ * @author Michael Niedermayer <michaelni@gmx.at>
+ */
+
+#include "libavutil/log.h"
+#include "libavutil/avassert.h"
+#include "swresample_internal.h"
+
+
+typedef struct ResampleContext {
+    const AVClass *av_class;
+    uint8_t *filter_bank;
+    int filter_length;
+    int filter_alloc;
+    int ideal_dst_incr;
+    int dst_incr;
+    int index;
+    int frac;
+    int src_incr;
+    int compensation_distance;
+    int phase_shift;
+    int phase_mask;
+    int linear;
+    enum SwrFilterType filter_type;
+    int kaiser_beta;
+    double factor;
+    enum AVSampleFormat format;
+    int felem_size;
+    int filter_shift;
+} ResampleContext;
+
+/**
+ * 0th order modified bessel function of the first kind.
+ */
+static double bessel(double x){
+    double v=1;
+    double lastv=0;
+    double t=1;
+    int i;
+    static const double inv[100]={
+ 1.0/( 1* 1), 1.0/( 2* 2), 1.0/( 3* 3), 1.0/( 4* 4), 1.0/( 5* 5), 1.0/( 6* 6), 1.0/( 7* 7), 1.0/( 8* 8), 1.0/( 9* 9), 1.0/(10*10),
+ 1.0/(11*11), 1.0/(12*12), 1.0/(13*13), 1.0/(14*14), 1.0/(15*15), 1.0/(16*16), 1.0/(17*17), 1.0/(18*18), 1.0/(19*19), 1.0/(20*20),
+ 1.0/(21*21), 1.0/(22*22), 1.0/(23*23), 1.0/(24*24), 1.0/(25*25), 1.0/(26*26), 1.0/(27*27), 1.0/(28*28), 1.0/(29*29), 1.0/(30*30),
+ 1.0/(31*31), 1.0/(32*32), 1.0/(33*33), 1.0/(34*34), 1.0/(35*35), 1.0/(36*36), 1.0/(37*37), 1.0/(38*38), 1.0/(39*39), 1.0/(40*40),
+ 1.0/(41*41), 1.0/(42*42), 1.0/(43*43), 1.0/(44*44), 1.0/(45*45), 1.0/(46*46), 1.0/(47*47), 1.0/(48*48), 1.0/(49*49), 1.0/(50*50),
+ 1.0/(51*51), 1.0/(52*52), 1.0/(53*53), 1.0/(54*54), 1.0/(55*55), 1.0/(56*56), 1.0/(57*57), 1.0/(58*58), 1.0/(59*59), 1.0/(60*60),
+ 1.0/(61*61), 1.0/(62*62), 1.0/(63*63), 1.0/(64*64), 1.0/(65*65), 1.0/(66*66), 1.0/(67*67), 1.0/(68*68), 1.0/(69*69), 1.0/(70*70),
+ 1.0/(71*71), 1.0/(72*72), 1.0/(73*73), 1.0/(74*74), 1.0/(75*75), 1.0/(76*76), 1.0/(77*77), 1.0/(78*78), 1.0/(79*79), 1.0/(80*80),
+ 1.0/(81*81), 1.0/(82*82), 1.0/(83*83), 1.0/(84*84), 1.0/(85*85), 1.0/(86*86), 1.0/(87*87), 1.0/(88*88), 1.0/(89*89), 1.0/(90*90),
+ 1.0/(91*91), 1.0/(92*92), 1.0/(93*93), 1.0/(94*94), 1.0/(95*95), 1.0/(96*96), 1.0/(97*97), 1.0/(98*98), 1.0/(99*99), 1.0/(10000)
+    };
+
+    x= x*x/4;
+    for(i=0; v != lastv; i++){
+        lastv=v;
+        t *= x*inv[i];
+        v += t;
+        av_assert2(i<99);
+    }
+    return v;
+}
+
+/**
+ * builds a polyphase filterbank.
+ * @param factor resampling factor
+ * @param scale wanted sum of coefficients for each filter
+ * @param filter_type  filter type
+ * @param kaiser_beta  kaiser window beta
+ * @return 0 on success, negative on error
+ */
+static int build_filter(ResampleContext *c, void *filter, double factor, int tap_count, int alloc, int phase_count, int scale,
+                        int filter_type, int kaiser_beta){
+    int ph, i;
+    double x, y, w;
+    double *tab = av_malloc(tap_count * sizeof(*tab));
+    const int center= (tap_count-1)/2;
+
+    if (!tab)
+        return AVERROR(ENOMEM);
+
+    /* if upsampling, only need to interpolate, no filter */
+    if (factor > 1.0)
+        factor = 1.0;
+
+    for(ph=0;ph<phase_count;ph++) {
+        double norm = 0;
+        for(i=0;i<tap_count;i++) {
+            x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
+            if (x == 0) y = 1.0;
+            else        y = sin(x) / x;
+            switch(filter_type){
+            case SWR_FILTER_TYPE_CUBIC:{
+                const float d= -0.5; //first order derivative = -0.5
+                x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
+                if(x<1.0) y= 1 - 3*x*x + 2*x*x*x + d*(            -x*x + x*x*x);
+                else      y=                       d*(-4 + 8*x - 5*x*x + x*x*x);
+                break;}
+            case SWR_FILTER_TYPE_BLACKMAN_NUTTALL:
+                w = 2.0*x / (factor*tap_count) + M_PI;
+                y *= 0.3635819 - 0.4891775 * cos(w) + 0.1365995 * cos(2*w) - 0.0106411 * cos(3*w);
+                break;
+            case SWR_FILTER_TYPE_KAISER:
+                w = 2.0*x / (factor*tap_count*M_PI);
+                y *= bessel(kaiser_beta*sqrt(FFMAX(1-w*w, 0)));
+                break;
+            default:
+                av_assert0(0);
+            }
+
+            tab[i] = y;
+            norm += y;
+        }
+
+        /* normalize so that an uniform color remains the same */
+        switch(c->format){
+        case AV_SAMPLE_FMT_S16P:
+            for(i=0;i<tap_count;i++)
+                ((int16_t*)filter)[ph * alloc + i] = av_clip(lrintf(tab[i] * scale / norm), INT16_MIN, INT16_MAX);
+            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);
+            break;
+        case AV_SAMPLE_FMT_FLTP:
+            for(i=0;i<tap_count;i++)
+                ((float*)filter)[ph * alloc + i] = tab[i] * scale / norm;
+            break;
+        case AV_SAMPLE_FMT_DBLP:
+            for(i=0;i<tap_count;i++)
+                ((double*)filter)[ph * alloc + i] = tab[i] * scale / norm;
+            break;
+        }
+    }
+#if 0
+    {
+#define LEN 1024
+        int j,k;
+        double sine[LEN + tap_count];
+        double filtered[LEN];
+        double maxff=-2, minff=2, maxsf=-2, minsf=2;
+        for(i=0; i<LEN; i++){
+            double ss=0, sf=0, ff=0;
+            for(j=0; j<LEN+tap_count; j++)
+                sine[j]= cos(i*j*M_PI/LEN);
+            for(j=0; j<LEN; j++){
+                double sum=0;
+                ph=0;
+                for(k=0; k<tap_count; k++)
+                    sum += filter[ph * tap_count + k] * sine[k+j];
+                filtered[j]= sum / (1<<FILTER_SHIFT);
+                ss+= sine[j + center] * sine[j + center];
+                ff+= filtered[j] * filtered[j];
+                sf+= sine[j + center] * filtered[j];
+            }
+            ss= sqrt(2*ss/LEN);
+            ff= sqrt(2*ff/LEN);
+            sf= 2*sf/LEN;
+            maxff= FFMAX(maxff, ff);
+            minff= FFMIN(minff, ff);
+            maxsf= FFMAX(maxsf, sf);
+            minsf= FFMIN(minsf, sf);
+            if(i%11==0){
+                av_log(NULL, AV_LOG_ERROR, "i:%4d ss:%f ff:%13.6e-%13.6e sf:%13.6e-%13.6e\n", i, ss, maxff, minff, maxsf, minsf);
+                minff=minsf= 2;
+                maxff=maxsf= -2;
+            }
+        }
+    }
+#endif
+
+    av_free(tab);
+    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){
+    double factor= FFMIN(out_rate * cutoff / in_rate, 1.0);
+    int phase_count= 1<<phase_shift;
+
+    if (!c || c->phase_shift != phase_shift || c->linear!=linear || c->factor != factor
+           || c->filter_length != FFMAX((int)ceil(filter_size/factor), 1) || c->format != format
+           || c->filter_type != filter_type || c->kaiser_beta != kaiser_beta) {
+        c = av_mallocz(sizeof(*c));
+        if (!c)
+            return NULL;
+
+        c->format= format;
+
+        c->felem_size= av_get_bytes_per_sample(c->format);
+
+        switch(c->format){
+        case AV_SAMPLE_FMT_S16P:
+            c->filter_shift = 15;
+            break;
+        case AV_SAMPLE_FMT_S32P:
+            c->filter_shift = 30;
+            break;
+        case AV_SAMPLE_FMT_FLTP:
+        case AV_SAMPLE_FMT_DBLP:
+            c->filter_shift = 0;
+            break;
+        default:
+            av_log(NULL, AV_LOG_ERROR, "Unsupported sample format\n");
+            av_assert0(0);
+        }
+
+        c->phase_shift   = phase_shift;
+        c->phase_mask    = phase_count - 1;
+        c->linear        = linear;
+        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_type   = filter_type;
+        c->kaiser_beta   = kaiser_beta;
+        if (!c->filter_bank)
+            goto error;
+        if (build_filter(c, (void*)c->filter_bank, factor, c->filter_length, c->filter_alloc, phase_count, 1<<c->filter_shift, filter_type, kaiser_beta))
+            goto error;
+        memcpy(c->filter_bank + (c->filter_alloc*phase_count+1)*c->felem_size, c->filter_bank, (c->filter_alloc-1)*c->felem_size);
+        memcpy(c->filter_bank + (c->filter_alloc*phase_count  )*c->felem_size, c->filter_bank + (c->filter_alloc - 1)*c->felem_size, c->felem_size);
+    }
+
+    c->compensation_distance= 0;
+    if(!av_reduce(&c->src_incr, &c->dst_incr, out_rate, in_rate * (int64_t)phase_count, INT32_MAX/2))
+        goto error;
+    c->ideal_dst_incr= c->dst_incr;
+
+    c->index= -phase_count*((c->filter_length-1)/2);
+    c->frac= 0;
+
+    return c;
+error:
+    av_free(c->filter_bank);
+    av_free(c);
+    return NULL;
+}
+
+void swri_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;
+    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;
+    else
+        c->dst_incr = c->ideal_dst_incr;
+    return 0;
+}
+
+#define RENAME(N) N ## _int16
+#define FILTER_SHIFT 15
+#define DELEM  int16_t
+#define FELEM  int16_t
+#define FELEM2 int32_t
+#define FELEML int64_t
+#define FELEM_MAX INT16_MAX
+#define FELEM_MIN INT16_MIN
+#define OUT(d, v) v = (v + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;\
+                  d = (unsigned)(v + 32768) > 65535 ? (v>>31) ^ 32767 : v
+#include "resample_template.c"
+
+#undef RENAME
+#undef FELEM
+#undef FELEM2
+#undef DELEM
+#undef FELEML
+#undef OUT
+#undef FELEM_MIN
+#undef FELEM_MAX
+#undef FILTER_SHIFT
+
+
+#define RENAME(N) N ## _int32
+#define FILTER_SHIFT 30
+#define DELEM  int32_t
+#define FELEM  int32_t
+#define FELEM2 int64_t
+#define FELEML int64_t
+#define FELEM_MAX INT32_MAX
+#define FELEM_MIN INT32_MIN
+#define OUT(d, v) v = (v + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;\
+                  d = (uint64_t)(v + 0x80000000) > 0xFFFFFFFF ? (v>>63) ^ 0x7FFFFFFF : v
+#include "resample_template.c"
+
+#undef RENAME
+#undef FELEM
+#undef FELEM2
+#undef DELEM
+#undef FELEML
+#undef OUT
+#undef FELEM_MIN
+#undef FELEM_MAX
+#undef FILTER_SHIFT
+
+
+#define RENAME(N) N ## _float
+#define FILTER_SHIFT 0
+#define DELEM  float
+#define FELEM  float
+#define FELEM2 float
+#define FELEML float
+#define OUT(d, v) d = v
+#include "resample_template.c"
+
+#undef RENAME
+#undef FELEM
+#undef FELEM2
+#undef DELEM
+#undef FELEML
+#undef OUT
+#undef FELEM_MIN
+#undef FELEM_MAX
+#undef FILTER_SHIFT
+
+
+#define RENAME(N) N ## _double
+#define FILTER_SHIFT 0
+#define DELEM  double
+#define FELEM  double
+#define FELEM2 double
+#define FELEML double
+#define OUT(d, v) d = v
+#include "resample_template.c"
+
+#undef RENAME
+#undef FELEM
+#undef FELEM2
+#undef DELEM
+#undef FELEML
+#undef OUT
+#undef FELEM_MIN
+#undef FELEM_MAX
+#undef FILTER_SHIFT
+
+// XXX FIXME the whole C loop should be written in asm so this x86 specific code here isnt needed
+#if HAVE_MMXEXT_INLINE
+#include "x86/resample_mmx.h"
+#define COMMON_CORE COMMON_CORE_INT16_MMX2
+#define RENAME(N) N ## _int16_mmx2
+#define FILTER_SHIFT 15
+#define DELEM  int16_t
+#define FELEM  int16_t
+#define FELEM2 int32_t
+#define FELEML int64_t
+#define FELEM_MAX INT16_MAX
+#define FELEM_MIN INT16_MIN
+#define OUT(d, v) v = (v + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;\
+                  d = (unsigned)(v + 32768) > 65535 ? (v>>31) ^ 32767 : v
+#include "resample_template.c"
+
+#undef COMMON_CORE
+#undef RENAME
+#undef FELEM
+#undef FELEM2
+#undef DELEM
+#undef FELEML
+#undef OUT
+#undef FELEM_MIN
+#undef FELEM_MAX
+#undef FILTER_SHIFT
+
+#if HAVE_SSSE3_INLINE
+#define COMMON_CORE COMMON_CORE_INT16_SSSE3
+#define RENAME(N) N ## _int16_ssse3
+#define FILTER_SHIFT 15
+#define DELEM  int16_t
+#define FELEM  int16_t
+#define FELEM2 int32_t
+#define FELEML int64_t
+#define FELEM_MAX INT16_MAX
+#define FELEM_MIN INT16_MIN
+#define OUT(d, v) v = (v + (1<<(FILTER_SHIFT-1)))>>FILTER_SHIFT;\
+                  d = (unsigned)(v + 32768) > 65535 ? (v>>31) ^ 32767 : v
+#include "resample_template.c"
+#endif
+#endif // HAVE_MMXEXT_INLINE
+
+int swri_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;
+
+    for(i=0; i<dst->ch_count; i++){
+#if HAVE_MMXEXT_INLINE
+#if HAVE_SSSE3_INLINE
+             if(c->format == AV_SAMPLE_FMT_S16P && (mm_flags&AV_CPU_FLAG_SSSE3)) ret= swri_resample_int16_ssse3(c, (int16_t*)dst->ch[i], (const int16_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
+        else
+#endif
+             if(c->format == AV_SAMPLE_FMT_S16P && (mm_flags&AV_CPU_FLAG_MMX2 )){
+                 ret= swri_resample_int16_mmx2 (c, (int16_t*)dst->ch[i], (const int16_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
+                 need_emms= 1;
+             } else
+#endif
+             if(c->format == AV_SAMPLE_FMT_S16P) ret= swri_resample_int16(c, (int16_t*)dst->ch[i], (const int16_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
+        else if(c->format == AV_SAMPLE_FMT_S32P) ret= swri_resample_int32(c, (int32_t*)dst->ch[i], (const int32_t*)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
+        else if(c->format == AV_SAMPLE_FMT_FLTP) ret= swri_resample_float(c, (float  *)dst->ch[i], (const float  *)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
+        else if(c->format == AV_SAMPLE_FMT_DBLP) ret= swri_resample_double(c,(double *)dst->ch[i], (const double *)src->ch[i], consumed, src_size, dst_size, i+1==dst->ch_count);
+    }
+    if(need_emms)
+        emms_c();
+    return ret;
+}
+
+int64_t swr_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;
+    }
+}
diff --git a/libswresample/resample_template.c b/libswresample/resample_template.c
new file mode 100644
index 0000000..ad84070
--- /dev/null
+++ b/libswresample/resample_template.c
@@ -0,0 +1,139 @@
+/*
+ * audio resampling
+ * Copyright (c) 2004-2012 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
+ * audio resampling
+ * @author Michael Niedermayer <michaelni@gmx.at>
+ */
+
+int RENAME(swri_resample)(ResampleContext *c, DELEM *dst, const DELEM *src, int *consumed, int src_size, int dst_size, int update_ctx){
+    int dst_index, i;
+    int index= c->index;
+    int frac= c->frac;
+    int dst_incr_frac= c->dst_incr % c->src_incr;
+    int dst_incr=      c->dst_incr / c->src_incr;
+    int compensation_distance= c->compensation_distance;
+
+    av_assert1(c->filter_shift == FILTER_SHIFT);
+    av_assert1(c->felem_size == sizeof(FELEM));
+
+    if(compensation_distance == 0 && c->filter_length == 1 && c->phase_shift==0){
+        int64_t index2= ((int64_t)index)<<32;
+        int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr;
+        dst_size= FFMIN(dst_size, (src_size-1-index) * (int64_t)c->src_incr / c->dst_incr);
+
+        for(dst_index=0; dst_index < dst_size; dst_index++){
+            dst[dst_index] = src[index2>>32];
+            index2 += incr;
+        }
+        index += dst_index * dst_incr;
+        index += (frac + dst_index * (int64_t)dst_incr_frac) / c->src_incr;
+        frac   = (frac + dst_index * (int64_t)dst_incr_frac) % c->src_incr;
+    }else if(compensation_distance == 0 && !c->linear && index >= 0){
+        for(dst_index=0; dst_index < dst_size; dst_index++){
+            FELEM *filter= ((FELEM*)c->filter_bank) + c->filter_alloc*(index & c->phase_mask);
+            int sample_index= index >> c->phase_shift;
+
+            if(sample_index + c->filter_length > src_size){
+                break;
+            }else{
+#ifdef COMMON_CORE
+                COMMON_CORE
+#else
+                FELEM2 val=0;
+                for(i=0; i<c->filter_length; i++){
+                    val += src[sample_index + i] * (FELEM2)filter[i];
+                }
+                OUT(dst[dst_index], val);
+#endif
+            }
+
+            frac += dst_incr_frac;
+            index += dst_incr;
+            if(frac >= c->src_incr){
+                frac -= c->src_incr;
+                index++;
+            }
+        }
+    }else{
+        for(dst_index=0; dst_index < dst_size; dst_index++){
+            FELEM *filter= ((FELEM*)c->filter_bank) + c->filter_alloc*(index & c->phase_mask);
+            int sample_index= index >> c->phase_shift;
+            FELEM2 val=0;
+
+            if(sample_index + c->filter_length > src_size || -sample_index >= src_size){
+                break;
+            }else if(sample_index < 0){
+                for(i=0; i<c->filter_length; i++)
+                    val += src[FFABS(sample_index + i)] * filter[i];
+            }else if(c->linear){
+                FELEM2 v2=0;
+                for(i=0; i<c->filter_length; i++){
+                    val += src[sample_index + i] * (FELEM2)filter[i];
+                    v2  += src[sample_index + i] * (FELEM2)filter[i + c->filter_alloc];
+                }
+                val+=(v2-val)*(FELEML)frac / c->src_incr;
+            }else{
+                for(i=0; i<c->filter_length; i++){
+                    val += src[sample_index + i] * (FELEM2)filter[i];
+                }
+            }
+
+            OUT(dst[dst_index], val);
+
+            frac += dst_incr_frac;
+            index += dst_incr;
+            if(frac >= c->src_incr){
+                frac -= c->src_incr;
+                index++;
+            }
+
+            if(dst_index + 1 == compensation_distance){
+                compensation_distance= 0;
+                dst_incr_frac= c->ideal_dst_incr % c->src_incr;
+                dst_incr=      c->ideal_dst_incr / c->src_incr;
+            }
+        }
+    }
+    *consumed= FFMAX(index, 0) >> c->phase_shift;
+    if(index>=0) index &= c->phase_mask;
+
+    if(compensation_distance){
+        compensation_distance -= dst_index;
+        av_assert1(compensation_distance > 0);
+    }
+    if(update_ctx){
+        c->frac= frac;
+        c->index= index;
+        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/swresample-test.c b/libswresample/swresample-test.c
new file mode 100644
index 0000000..4a0728c
--- /dev/null
+++ b/libswresample/swresample-test.c
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
+ * Copyright (c) 2002 Fabrice Bellard
+ *
+ * This file is part of libswresample
+ *
+ * libswresample 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.
+ *
+ * libswresample is distributed in the hope that 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 libswresample; 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 "libavutil/audioconvert.h"
+#include "libavutil/opt.h"
+#include "swresample.h"
+
+#undef time
+#include "time.h"
+#undef fprintf
+
+#define SAMPLES 1000
+
+#define ASSERT_LEVEL 2
+
+static double get(uint8_t *a[], int ch, int index, int ch_count, enum AVSampleFormat f){
+    const uint8_t *p;
+    if(av_sample_fmt_is_planar(f)){
+        f= av_get_alt_sample_fmt(f, 0);
+        p= a[ch];
+    }else{
+        p= a[0];
+        index= ch + index*ch_count;
+    }
+
+    switch(f){
+    case AV_SAMPLE_FMT_U8 : return ((const uint8_t*)p)[index]/127.0-1.0;
+    case AV_SAMPLE_FMT_S16: return ((const int16_t*)p)[index]/32767.0;
+    case AV_SAMPLE_FMT_S32: return ((const int32_t*)p)[index]/2147483647.0;
+    case AV_SAMPLE_FMT_FLT: return ((const float  *)p)[index];
+    case AV_SAMPLE_FMT_DBL: return ((const double *)p)[index];
+    default: av_assert0(0);
+    }
+}
+
+static void  set(uint8_t *a[], int ch, int index, int ch_count, enum AVSampleFormat f, double v){
+    uint8_t *p;
+    if(av_sample_fmt_is_planar(f)){
+        f= av_get_alt_sample_fmt(f, 0);
+        p= a[ch];
+    }else{
+        p= a[0];
+        index= ch + index*ch_count;
+    }
+    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_FLT: ((float  *)p)[index]= v;                                      break;
+    case AV_SAMPLE_FMT_DBL: ((double *)p)[index]= v;                                      break;
+    default: av_assert2(0);
+    }
+}
+
+static void shift(uint8_t *a[], int index, int ch_count, enum AVSampleFormat f){
+    int ch;
+
+    if(av_sample_fmt_is_planar(f)){
+        f= av_get_alt_sample_fmt(f, 0);
+        for(ch= 0; ch<ch_count; ch++)
+            a[ch] += index*av_get_bytes_per_sample(f);
+    }else{
+        a[0] += index*ch_count*av_get_bytes_per_sample(f);
+    }
+}
+
+static const enum AVSampleFormat formats[] = {
+    AV_SAMPLE_FMT_S16,
+    AV_SAMPLE_FMT_FLTP,
+    AV_SAMPLE_FMT_S16P,
+    AV_SAMPLE_FMT_FLT,
+    AV_SAMPLE_FMT_S32P,
+    AV_SAMPLE_FMT_S32,
+    AV_SAMPLE_FMT_U8P,
+    AV_SAMPLE_FMT_U8,
+    AV_SAMPLE_FMT_DBLP,
+    AV_SAMPLE_FMT_DBL,
+};
+
+static const int rates[] = {
+    8000,
+    11025,
+    16000,
+    22050,
+    32000,
+    48000,
+};
+
+uint64_t layouts[]={
+    AV_CH_LAYOUT_MONO                    ,
+    AV_CH_LAYOUT_STEREO                  ,
+    AV_CH_LAYOUT_2_1                     ,
+    AV_CH_LAYOUT_SURROUND                ,
+    AV_CH_LAYOUT_4POINT0                 ,
+    AV_CH_LAYOUT_2_2                     ,
+    AV_CH_LAYOUT_QUAD                    ,
+    AV_CH_LAYOUT_5POINT0                 ,
+    AV_CH_LAYOUT_5POINT1                 ,
+    AV_CH_LAYOUT_5POINT0_BACK            ,
+    AV_CH_LAYOUT_5POINT1_BACK            ,
+    AV_CH_LAYOUT_7POINT0                 ,
+    AV_CH_LAYOUT_7POINT1                 ,
+    AV_CH_LAYOUT_7POINT1_WIDE            ,
+};
+
+static void setup_array(uint8_t *out[SWR_CH_MAX], uint8_t *in, enum AVSampleFormat format, int samples){
+    if(av_sample_fmt_is_planar(format)){
+        int i;
+        int plane_size= av_get_bytes_per_sample(format&0xFF)*samples;
+        format&=0xFF;
+        for(i=0; i<SWR_CH_MAX; i++){
+            out[i]= in + i*plane_size;
+        }
+    }else{
+        out[0]= in;
+    }
+}
+
+static int cmp(const int *a, const int *b){
+    return *a - *b;
+}
+
+static void audiogen(void *data, enum AVSampleFormat sample_fmt,
+                     int channels, int sample_rate, int nb_samples)
+{
+    int i, ch, k;
+    double v, f, a, ampa;
+    double tabf1[SWR_CH_MAX];
+    double tabf2[SWR_CH_MAX];
+    double taba[SWR_CH_MAX];
+    unsigned static rnd;
+
+#define PUT_SAMPLE set(data, ch, k, channels, sample_fmt, v);
+#define uint_rand(x) (x = x * 1664525 + 1013904223)
+#define dbl_rand(x) (uint_rand(x)*2.0 / (double)UINT_MAX - 1)
+    k = 0;
+
+    /* 1 second of single freq sinus at 1000 Hz */
+    a = 0;
+    for (i = 0; i < 1 * sample_rate && k < nb_samples; i++, k++) {
+        v = sin(a) * 0.30;
+        for (ch = 0; ch < channels; ch++)
+            PUT_SAMPLE
+        a += M_PI * 1000.0 * 2.0 / sample_rate;
+    }
+
+    /* 1 second of varing 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;
+        for (ch = 0; ch < channels; ch++)
+            PUT_SAMPLE
+        f  = 100.0 + (((10000.0 - 100.0) * i) / sample_rate);
+        a += M_PI * f * 2.0 / sample_rate;
+    }
+
+    /* 0.5 second of low amplitude white noise */
+    for (i = 0; i < sample_rate / 2 && k < nb_samples; i++, k++) {
+        v = dbl_rand(rnd) * 0.30;
+        for (ch = 0; ch < channels; ch++)
+            PUT_SAMPLE
+    }
+
+    /* 0.5 second of high amplitude white noise */
+    for (i = 0; i < sample_rate / 2 && k < nb_samples; i++, k++) {
+        v = dbl_rand(rnd);
+        for (ch = 0; ch < channels; ch++)
+            PUT_SAMPLE
+    }
+
+    /* 1 second of unrelated ramps for each channel */
+    for (ch = 0; ch < channels; ch++) {
+        taba[ch]  = 0;
+        tabf1[ch] = 100 + uint_rand(rnd) % 5000;
+        tabf2[ch] = 100 + uint_rand(rnd) % 5000;
+    }
+    for (i = 0; i < 1 * sample_rate && k < nb_samples; i++, k++) {
+        for (ch = 0; ch < channels; ch++) {
+            v = sin(taba[ch]) * 0.30;
+            PUT_SAMPLE
+            f = tabf1[ch] + (((tabf2[ch] - tabf1[ch]) * i) / sample_rate);
+            taba[ch] += M_PI * f * 2.0 / sample_rate;
+        }
+    }
+
+    /* 2 seconds of 500 Hz with varying volume */
+    a    = 0;
+    ampa = 0;
+    for (i = 0; i < 2 * sample_rate && k < nb_samples; i++, k++) {
+        for (ch = 0; ch < channels; ch++) {
+            double amp = (1.0 + sin(ampa)) * 0.15;
+            if (ch & 1)
+                amp = 0.30 - amp;
+            v = sin(a) * amp;
+            PUT_SAMPLE
+            a    += M_PI * 500.0 * 2.0 / sample_rate;
+            ampa += M_PI *  2.0 / sample_rate;
+        }
+    }
+}
+
+int main(int argc, char **argv){
+    int in_sample_rate, out_sample_rate, ch ,i, flush_count;
+    uint64_t in_ch_layout, out_ch_layout;
+    enum AVSampleFormat in_sample_fmt, out_sample_fmt;
+    uint8_t array_in[SAMPLES*8*8];
+    uint8_t array_mid[SAMPLES*8*8*3];
+    uint8_t array_out[SAMPLES*8*8+100];
+    uint8_t *ain[SWR_CH_MAX];
+    uint8_t *aout[SWR_CH_MAX];
+    uint8_t *amid[SWR_CH_MAX];
+    int flush_i=0;
+    int mode;
+    int num_tests = 10000;
+    uint32_t seed = 0;
+    uint32_t rand_seed = 0;
+    int remaining_tests[FF_ARRAY_ELEMS(rates) * FF_ARRAY_ELEMS(layouts) * FF_ARRAY_ELEMS(formats) * FF_ARRAY_ELEMS(layouts) * FF_ARRAY_ELEMS(formats)];
+    int max_tests = FF_ARRAY_ELEMS(remaining_tests);
+    int test;
+    int specific_test= -1;
+
+    struct SwrContext * forw_ctx= NULL;
+    struct SwrContext *backw_ctx= NULL;
+
+    if (argc > 1) {
+        if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
+            av_log(NULL, AV_LOG_INFO, "Usage: swresample-test [<num_tests>[ <test>]]  \n"
+                   "num_tests           Default is %d\n", num_tests);
+            return 0;
+        }
+        num_tests = strtol(argv[1], NULL, 0);
+        if(num_tests < 0) {
+            num_tests = -num_tests;
+            rand_seed = time(0);
+        }
+        if(num_tests<= 0 || num_tests>max_tests)
+            num_tests = max_tests;
+        if(argc > 2) {
+            specific_test = strtol(argv[1], NULL, 0);
+        }
+    }
+
+    for(i=0; i<max_tests; i++)
+        remaining_tests[i] = i;
+
+    for(test=0; test<num_tests; test++){
+        unsigned r;
+        uint_rand(seed);
+        r = (seed * (uint64_t)(max_tests - test)) >>32;
+        FFSWAP(int, remaining_tests[r], remaining_tests[max_tests - test - 1]);
+    }
+    qsort(remaining_tests + max_tests - num_tests, num_tests, sizeof(remaining_tests[0]), (void*)cmp);
+    in_sample_rate=16000;
+    for(test=0; test<num_tests; test++){
+        char  in_layout_string[256];
+        char out_layout_string[256];
+        unsigned vector= remaining_tests[max_tests - test - 1];
+        int in_ch_count;
+        int out_count, mid_count, out_ch_count;
+
+        in_ch_layout    = layouts[vector % FF_ARRAY_ELEMS(layouts)]; vector /= FF_ARRAY_ELEMS(layouts);
+        out_ch_layout   = layouts[vector % FF_ARRAY_ELEMS(layouts)]; vector /= FF_ARRAY_ELEMS(layouts);
+        in_sample_fmt   = formats[vector % FF_ARRAY_ELEMS(formats)]; vector /= FF_ARRAY_ELEMS(formats);
+        out_sample_fmt  = formats[vector % FF_ARRAY_ELEMS(formats)]; vector /= FF_ARRAY_ELEMS(formats);
+        out_sample_rate = rates  [vector % FF_ARRAY_ELEMS(rates  )]; vector /= FF_ARRAY_ELEMS(rates);
+        av_assert0(!vector);
+
+        if(specific_test == 0){
+            if(out_sample_rate != in_sample_rate || in_ch_layout != out_ch_layout)
+                continue;
+        }
+
+        in_ch_count= av_get_channel_layout_nb_channels(in_ch_layout);
+        out_ch_count= av_get_channel_layout_nb_channels(out_ch_layout);
+        av_get_channel_layout_string( in_layout_string, sizeof( in_layout_string),  in_ch_count,  in_ch_layout);
+        av_get_channel_layout_string(out_layout_string, sizeof(out_layout_string), out_ch_count, out_ch_layout);
+        fprintf(stderr, "TEST: %s->%s, rate:%5d->%5d, fmt:%s->%s\n",
+                in_layout_string, out_layout_string,
+                in_sample_rate, out_sample_rate,
+                av_get_sample_fmt_name(in_sample_fmt), av_get_sample_fmt_name(out_sample_fmt));
+        forw_ctx  = swr_alloc_set_opts(forw_ctx, out_ch_layout, out_sample_fmt,  out_sample_rate,
+                                                    in_ch_layout,  in_sample_fmt,  in_sample_rate,
+                                        0, 0);
+        backw_ctx = swr_alloc_set_opts(backw_ctx, in_ch_layout,  in_sample_fmt,             in_sample_rate,
+                                                    out_ch_layout, out_sample_fmt, out_sample_rate,
+                                        0, 0);
+        if(swr_init( forw_ctx) < 0)
+            fprintf(stderr, "swr_init(->) failed\n");
+        if(swr_init(backw_ctx) < 0)
+            fprintf(stderr, "swr_init(<-) failed\n");
+        if(!forw_ctx)
+            fprintf(stderr, "Failed to init forw_cts\n");
+        if(!backw_ctx)
+            fprintf(stderr, "Failed to init backw_ctx\n");
+                //FIXME test planar
+        setup_array(ain , array_in ,  in_sample_fmt,   SAMPLES);
+        setup_array(amid, array_mid, out_sample_fmt, 3*SAMPLES);
+        setup_array(aout, array_out,  in_sample_fmt           ,   SAMPLES);
+#if 0
+        for(ch=0; ch<in_ch_count; ch++){
+            for(i=0; i<SAMPLES; i++)
+                set(ain, ch, i, in_ch_count, in_sample_fmt, sin(i*i*3/SAMPLES));
+        }
+#else
+        audiogen(ain, in_sample_fmt, in_ch_count, SAMPLES/6+1, SAMPLES);
+#endif
+        mode = uint_rand(rand_seed) % 3;
+        if(mode==0 /*|| out_sample_rate == in_sample_rate*/) {
+            mid_count= swr_convert(forw_ctx, amid, 3*SAMPLES, (const uint8_t **)ain, SAMPLES);
+        } else if(mode==1){
+            mid_count= swr_convert(forw_ctx, amid,         0, (const uint8_t **)ain, SAMPLES);
+            mid_count+=swr_convert(forw_ctx, amid, 3*SAMPLES, (const uint8_t **)ain,       0);
+        } else {
+            int tmp_count;
+            mid_count= swr_convert(forw_ctx, amid,         0, (const uint8_t **)ain,       1);
+            av_assert0(mid_count==0);
+            shift(ain,  1, in_ch_count, in_sample_fmt);
+            mid_count+=swr_convert(forw_ctx, amid, 3*SAMPLES, (const uint8_t **)ain,       0);
+            shift(amid,  mid_count, out_ch_count, out_sample_fmt); tmp_count = mid_count;
+            mid_count+=swr_convert(forw_ctx, amid,         2, (const uint8_t **)ain,       2);
+            shift(amid,  mid_count-tmp_count, out_ch_count, out_sample_fmt); tmp_count = mid_count;
+            shift(ain,  2, in_ch_count, in_sample_fmt);
+            mid_count+=swr_convert(forw_ctx, amid,         1, (const uint8_t **)ain, SAMPLES-3);
+            shift(amid,  mid_count-tmp_count, out_ch_count, out_sample_fmt); tmp_count = mid_count;
+            shift(ain, -3, in_ch_count, in_sample_fmt);
+            mid_count+=swr_convert(forw_ctx, amid, 3*SAMPLES, (const uint8_t **)ain,       0);
+            shift(amid,  -tmp_count, out_ch_count, out_sample_fmt);
+        }
+        out_count= swr_convert(backw_ctx,aout, SAMPLES, (const uint8_t **)amid, mid_count);
+
+        for(ch=0; ch<in_ch_count; ch++){
+            double sse, maxdiff=0;
+            double sum_a= 0;
+            double sum_b= 0;
+            double sum_aa= 0;
+            double sum_bb= 0;
+            double sum_ab= 0;
+            for(i=0; i<out_count; i++){
+                double a= get(ain , ch, i, in_ch_count, in_sample_fmt);
+                double b= get(aout, ch, i, in_ch_count, in_sample_fmt);
+                sum_a += a;
+                sum_b += b;
+                sum_aa+= a*a;
+                sum_bb+= b*b;
+                sum_ab+= a*b;
+                maxdiff= FFMAX(maxdiff, FFABS(a-b));
+            }
+            sse= sum_aa + sum_bb - 2*sum_ab;
+            if(sse < 0 && sse > -0.00001) sse=0; //fix rounding error
+
+            fprintf(stderr, "[e:%f c:%f max:%f] len:%5d\n", sqrt(sse/out_count), sum_ab/(sqrt(sum_aa*sum_bb)), maxdiff, out_count);
+        }
+
+        flush_i++;
+        flush_i%=21;
+        flush_count = swr_convert(backw_ctx,aout, flush_i, 0, 0);
+        shift(aout,  flush_i, in_ch_count, in_sample_fmt);
+        flush_count+= swr_convert(backw_ctx,aout, SAMPLES-flush_i, 0, 0);
+        shift(aout, -flush_i, in_ch_count, in_sample_fmt);
+        if(flush_count){
+            for(ch=0; ch<in_ch_count; ch++){
+                double sse, maxdiff=0;
+                double sum_a= 0;
+                double sum_b= 0;
+                double sum_aa= 0;
+                double sum_bb= 0;
+                double sum_ab= 0;
+                for(i=0; i<flush_count; i++){
+                    double a= get(ain , ch, i+out_count, in_ch_count, in_sample_fmt);
+                    double b= get(aout, ch, i, in_ch_count, in_sample_fmt);
+                    sum_a += a;
+                    sum_b += b;
+                    sum_aa+= a*a;
+                    sum_bb+= b*b;
+                    sum_ab+= a*b;
+                    maxdiff= FFMAX(maxdiff, FFABS(a-b));
+                }
+                sse= sum_aa + sum_bb - 2*sum_ab;
+                if(sse < 0 && sse > -0.00001) sse=0; //fix rounding error
+
+                fprintf(stderr, "[e:%f c:%f max:%f] len:%5d F:%3d\n", sqrt(sse/flush_count), sum_ab/(sqrt(sum_aa*sum_bb)), maxdiff, flush_count, flush_i);
+            }
+        }
+
+
+        fprintf(stderr, "\n");
+    }
+
+    return 0;
+}
diff --git a/libswresample/swresample.c b/libswresample/swresample.c
new file mode 100644
index 0000000..5d02aaf
--- /dev/null
+++ b/libswresample/swresample.c
@@ -0,0 +1,795 @@
+/*
+ * Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
+ *
+ * This file is part of libswresample
+ *
+ * libswresample 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.
+ *
+ * libswresample is distributed in the hope that 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 libswresample; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/opt.h"
+#include "swresample_internal.h"
+#include "audioconvert.h"
+#include "libavutil/avassert.h"
+#include "libavutil/audioconvert.h"
+
+#include <float.h>
+
+#define  C30DB  M_SQRT2
+#define  C15DB  1.189207115
+#define C__0DB  1.0
+#define C_15DB  0.840896415
+#define C_30DB  M_SQRT1_2
+#define C_45DB  0.594603558
+#define C_60DB  0.5
+
+#define ALIGN 32
+
+//TODO split options array out?
+#define OFFSET(x) offsetof(SwrContext,x)
+#define PARAM AV_OPT_FLAG_AUDIO_PARAM
+
+static const AVOption options[]={
+{"ich"                  ,  "Input Channel Count"        , OFFSET( in.ch_count   ), AV_OPT_TYPE_INT  , {.i64=2                     }, 0      , SWR_CH_MAX, PARAM},
+{"in_channel_count"     ,  "Input Channel Count"        , OFFSET( in.ch_count   ), AV_OPT_TYPE_INT  , {.i64=2                     }, 0      , SWR_CH_MAX, PARAM},
+{"och"                  , "Output Channel Count"        , OFFSET(out.ch_count   ), AV_OPT_TYPE_INT  , {.i64=2                     }, 0      , SWR_CH_MAX, PARAM},
+{"out_channel_count"    , "Output Channel Count"        , OFFSET(out.ch_count   ), AV_OPT_TYPE_INT  , {.i64=2                     }, 0      , SWR_CH_MAX, PARAM},
+{"uch"                  ,   "Used Channel Count"        , OFFSET(used_ch_count  ), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , SWR_CH_MAX, PARAM},
+{"used_channel_count"   ,   "Used Channel Count"        , OFFSET(used_ch_count  ), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , SWR_CH_MAX, PARAM},
+{"isr"                  ,  "Input Sample Rate"          , OFFSET( in_sample_rate), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , INT_MAX   , PARAM},
+{"in_sample_rate"       ,  "Input Sample Rate"          , OFFSET( in_sample_rate), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , INT_MAX   , PARAM},
+{"osr"                  , "Output Sample Rate"          , OFFSET(out_sample_rate), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , INT_MAX   , PARAM},
+{"out_sample_rate"      , "Output Sample Rate"          , OFFSET(out_sample_rate), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , INT_MAX   , PARAM},
+{"isf"                  ,    "Input Sample Format"      , OFFSET( in_sample_fmt ), AV_OPT_TYPE_INT  , {.i64=AV_SAMPLE_FMT_NONE    }, -1     , AV_SAMPLE_FMT_NB-1+256, PARAM},
+{"in_sample_fmt"        ,    "Input Sample Format"      , OFFSET( in_sample_fmt ), AV_OPT_TYPE_INT  , {.i64=AV_SAMPLE_FMT_NONE    }, -1     , AV_SAMPLE_FMT_NB-1+256, PARAM},
+{"osf"                  ,   "Output Sample Format"      , OFFSET(out_sample_fmt ), AV_OPT_TYPE_INT  , {.i64=AV_SAMPLE_FMT_NONE    }, -1     , AV_SAMPLE_FMT_NB-1+256, PARAM},
+{"out_sample_fmt"       ,   "Output Sample Format"      , OFFSET(out_sample_fmt ), AV_OPT_TYPE_INT  , {.i64=AV_SAMPLE_FMT_NONE    }, -1     , AV_SAMPLE_FMT_NB-1+256, PARAM},
+{"tsf"                  , "Internal Sample Format"      , OFFSET(int_sample_fmt ), AV_OPT_TYPE_INT  , {.i64=AV_SAMPLE_FMT_NONE    }, -1     , AV_SAMPLE_FMT_FLTP, PARAM},
+{"internal_sample_fmt"  , "Internal Sample Format"      , OFFSET(int_sample_fmt ), AV_OPT_TYPE_INT  , {.i64=AV_SAMPLE_FMT_NONE    }, -1     , AV_SAMPLE_FMT_FLTP, PARAM},
+{"icl"                  ,   "Input Channel Layout"      , OFFSET( in_ch_layout  ), AV_OPT_TYPE_INT64, {.i64=0                     }, 0      , INT64_MAX , PARAM, "channel_layout"},
+{"in_channel_layout"    ,   "Input Channel Layout"      , OFFSET( in_ch_layout  ), AV_OPT_TYPE_INT64, {.i64=0                     }, 0      , INT64_MAX , PARAM, "channel_layout"},
+{"ocl"                  ,  "Output Channel Layout"      , OFFSET(out_ch_layout  ), AV_OPT_TYPE_INT64, {.i64=0                     }, 0      , INT64_MAX , PARAM, "channel_layout"},
+{"out_channel_layout"   ,  "Output Channel Layout"      , OFFSET(out_ch_layout  ), AV_OPT_TYPE_INT64, {.i64=0                     }, 0      , INT64_MAX , PARAM, "channel_layout"},
+{"clev"                 ,    "Center Mix Level"         , OFFSET(clev           ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB                }, -32    , 32        , PARAM},
+{"center_mix_level"     ,    "Center Mix Level"         , OFFSET(clev           ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB                }, -32    , 32        , PARAM},
+{"slev"                 , "Sourround Mix Level"         , OFFSET(slev           ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB                }, -32    , 32        , PARAM},
+{"surround_mix_level"   , "Sourround Mix Level"         , OFFSET(slev           ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB                }, -32    , 32        , PARAM},
+{"lfe_mix_level"        , "LFE Mix Level"               , OFFSET(lfe_mix_level  ), AV_OPT_TYPE_FLOAT, {.dbl=0                     }, -32    , 32        , PARAM},
+{"rmvol"                , "Rematrix Volume"             , OFFSET(rematrix_volume), AV_OPT_TYPE_FLOAT, {.dbl=1.0                   }, -1000  , 1000      , PARAM},
+{"rematrix_volume"      , "Rematrix Volume"             , OFFSET(rematrix_volume), AV_OPT_TYPE_FLOAT, {.dbl=1.0                   }, -1000  , 1000      , PARAM},
+{"flags"                , NULL                          , OFFSET(flags          ), AV_OPT_TYPE_FLAGS, {.i64=0                     }, 0      , UINT_MAX  , PARAM, "flags"},
+{"swr_flags"            , NULL                          , 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"         , "Dither Scale"                , OFFSET(dither_scale   ), AV_OPT_TYPE_FLOAT, {.dbl=1                     }, 0      , INT_MAX   , PARAM},
+{"dither_method"        , "Dither Method"               , OFFSET(dither_method  ), AV_OPT_TYPE_INT  , {.i64=0                     }, 0      , SWR_DITHER_NB-1, PARAM, "dither_method"},
+{"rectangular"          , "Rectangular Dither"          , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_RECTANGULAR}, INT_MIN, INT_MAX   , PARAM, "dither_method"},
+{"triangular"           ,  "Triangular Dither"          , 0                      , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_TRIANGULAR }, INT_MIN, INT_MAX   , PARAM, "dither_method"},
+{"triangular_hp"        , "Triangular Dither With High Pass" , 0                 , AV_OPT_TYPE_CONST, {.i64=SWR_DITHER_TRIANGULAR_HIGHPASS }, INT_MIN, INT_MAX, PARAM, "dither_method"},
+{"filter_size"          , "Resampling Filter Size"      , OFFSET(filter_size)    , AV_OPT_TYPE_INT  , {.i64=16                    }, 0      , INT_MAX   , PARAM },
+{"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      , 1         , PARAM },
+{"min_comp"             , "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"        , "Minimum difference between timestamps and audio data (in seconds) to trigger padding/trimming the data."
+                                                   , OFFSET(min_hard_compensation),AV_OPT_TYPE_FLOAT ,{.dbl=0.1                   }, 0      , INT_MAX   , PARAM },
+{"comp_duration"        , "Duration (in seconds) over which data is stretched/squeezed to make it match the timestamps."
+                                              , OFFSET(soft_compensation_duration),AV_OPT_TYPE_FLOAT ,{.dbl=1                     }, 0      , INT_MAX   , PARAM },
+{"max_soft_comp"        , "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 },
+{ "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" },
+    { "dplii", "Dolby Pro Logic II", 0, AV_OPT_TYPE_CONST, { .i64 = AV_MATRIX_ENCODING_DPLII }, INT_MIN, INT_MAX, PARAM, "matrix_encoding" },
+{ "filter_type"         , "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"           , "Cubic"                       , 0                      , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_CUBIC            }, INT_MIN, INT_MAX, PARAM, "filter_type" },
+    { "blackman_nuttall", "Blackman Nuttall Windowed Sinc", 0                    , AV_OPT_TYPE_CONST, { .i64 = SWR_FILTER_TYPE_BLACKMAN_NUTTALL }, INT_MIN, INT_MAX, PARAM, "filter_type" },
+    { "kaiser"          , "Kaiser Windowed Sinc"        , 0                      , AV_OPT_TYPE_CONST, { .i64 = SWR_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 },
+
+{0}
+};
+
+static const char* context_to_name(void* ptr) {
+    return "SWR";
+}
+
+static const AVClass av_class = {
+    .class_name                = "SWResampler",
+    .item_name                 = context_to_name,
+    .option                    = options,
+    .version                   = LIBAVUTIL_VERSION_INT,
+    .log_level_offset_offset   = OFFSET(log_level_offset),
+    .parent_log_context_offset = OFFSET(log_ctx),
+    .category                  = AV_CLASS_CATEGORY_SWRESAMPLER,
+};
+
+unsigned swresample_version(void)
+{
+    av_assert0(LIBSWRESAMPLE_VERSION_MICRO >= 100);
+    return LIBSWRESAMPLE_VERSION_INT;
+}
+
+const char *swresample_configuration(void)
+{
+    return FFMPEG_CONFIGURATION;
+}
+
+const char *swresample_license(void)
+{
+#define LICENSE_PREFIX "libswresample license: "
+    return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+}
+
+int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map){
+    if(!s || s->in_convert) // s needs to be allocated but not initialized
+        return AVERROR(EINVAL);
+    s->channel_map = channel_map;
+    return 0;
+}
+
+const AVClass *swr_get_class(void)
+{
+    return &av_class;
+}
+
+av_cold struct SwrContext *swr_alloc(void){
+    SwrContext *s= av_mallocz(sizeof(SwrContext));
+    if(s){
+        s->av_class= &av_class;
+        av_opt_set_defaults(s);
+    }
+    return s;
+}
+
+struct SwrContext *swr_alloc_set_opts(struct SwrContext *s,
+                                      int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
+                                      int64_t  in_ch_layout, enum AVSampleFormat  in_sample_fmt, int  in_sample_rate,
+                                      int log_offset, void *log_ctx){
+    if(!s) s= swr_alloc();
+    if(!s) return NULL;
+
+    s->log_level_offset= log_offset;
+    s->log_ctx= log_ctx;
+
+    av_opt_set_int(s, "ocl", out_ch_layout,   0);
+    av_opt_set_int(s, "osf", out_sample_fmt,  0);
+    av_opt_set_int(s, "osr", out_sample_rate, 0);
+    av_opt_set_int(s, "icl", in_ch_layout,    0);
+    av_opt_set_int(s, "isf", in_sample_fmt,   0);
+    av_opt_set_int(s, "isr", in_sample_rate,  0);
+    av_opt_set_int(s, "tsf", AV_SAMPLE_FMT_NONE,   0);
+    av_opt_set_int(s, "ich", av_get_channel_layout_nb_channels(s-> in_ch_layout), 0);
+    av_opt_set_int(s, "och", av_get_channel_layout_nb_channels(s->out_ch_layout), 0);
+    av_opt_set_int(s, "uch", 0, 0);
+    return s;
+}
+
+static void set_audiodata_fmt(AudioData *a, enum AVSampleFormat fmt){
+    a->fmt   = fmt;
+    a->bps   = av_get_bytes_per_sample(fmt);
+    a->planar= av_sample_fmt_is_planar(fmt);
+}
+
+static void free_temp(AudioData *a){
+    av_free(a->data);
+    memset(a, 0, sizeof(*a));
+}
+
+av_cold void swr_free(SwrContext **ss){
+    SwrContext *s= *ss;
+    if(s){
+        free_temp(&s->postin);
+        free_temp(&s->midbuf);
+        free_temp(&s->preout);
+        free_temp(&s->in_buffer);
+        free_temp(&s->dither);
+        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);
+        swri_rematrix_free(s);
+    }
+
+    av_freep(ss);
+}
+
+av_cold int swr_init(struct SwrContext *s){
+    s->in_buffer_index= 0;
+    s->in_buffer_count= 0;
+    s->resample_in_constraint= 0;
+    free_temp(&s->postin);
+    free_temp(&s->midbuf);
+    free_temp(&s->preout);
+    free_temp(&s->in_buffer);
+    free_temp(&s->dither);
+    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);
+    swri_audio_convert_free(&s->out_convert);
+    swri_audio_convert_free(&s->full_convert);
+    swri_rematrix_free(s);
+
+    s->flushed = 0;
+
+    if(s-> in_sample_fmt >= AV_SAMPLE_FMT_NB){
+        av_log(s, AV_LOG_ERROR, "Requested input sample format %d is invalid\n", s->in_sample_fmt);
+        return AVERROR(EINVAL);
+    }
+    if(s->out_sample_fmt >= AV_SAMPLE_FMT_NB){
+        av_log(s, AV_LOG_ERROR, "Requested output sample format %d is invalid\n", s->out_sample_fmt);
+        return AVERROR(EINVAL);
+    }
+
+    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_FLTP){
+            s->int_sample_fmt= AV_SAMPLE_FMT_FLTP;
+        }else{
+            av_log(s, AV_LOG_DEBUG, "Using double precision mode\n");
+            s->int_sample_fmt= AV_SAMPLE_FMT_DBLP;
+        }
+    }
+
+    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
+        &&s->int_sample_fmt != AV_SAMPLE_FMT_DBLP){
+        av_log(s, AV_LOG_ERROR, "Requested sample format %s is not supported internally, S16/S32/FLT/DBL is supported\n", av_get_sample_fmt_name(s->int_sample_fmt));
+        return AVERROR(EINVAL);
+    }
+
+    set_audiodata_fmt(&s-> in, s-> in_sample_fmt);
+    set_audiodata_fmt(&s->out, s->out_sample_fmt);
+
+    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);
+    }else
+        swri_resample_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
+        && s->int_sample_fmt != AV_SAMPLE_FMT_DBLP
+        && s->resample){
+        av_log(s, AV_LOG_ERROR, "Resampling only supported with internal s16/s32/flt/dbl\n");
+        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);
+    if(!s->used_ch_count)
+        s->used_ch_count= s->in.ch_count;
+    if(!s->out.ch_count)
+        s->out.ch_count= av_get_channel_layout_nb_channels(s->out_ch_layout);
+
+    if(!s-> in.ch_count){
+        av_assert0(!s->in_ch_layout);
+        av_log(s, AV_LOG_ERROR, "Input channel count and layout are unset\n");
+        return -1;
+    }
+
+    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");
+        return -1;
+    }
+
+av_assert0(s->used_ch_count);
+av_assert0(s->out.ch_count);
+    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;
+
+    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;
+    }
+
+    s->in_convert = swri_audio_convert_alloc(s->int_sample_fmt,
+                                             s-> in_sample_fmt, s->used_ch_count, s->channel_map, 0);
+    s->out_convert= swri_audio_convert_alloc(s->out_sample_fmt,
+                                             s->int_sample_fmt, s->out.ch_count, NULL, 0);
+
+
+    s->postin= s->in;
+    s->preout= s->out;
+    s->midbuf= s->in;
+
+    if(s->channel_map){
+        s->postin.ch_count=
+        s->midbuf.ch_count= s->used_ch_count;
+        if(s->resample)
+            s->in_buffer.ch_count= s->used_ch_count;
+    }
+    if(!s->resample_first){
+        s->midbuf.ch_count= s->out.ch_count;
+        if(s->resample)
+            s->in_buffer.ch_count = s->out.ch_count;
+    }
+
+    set_audiodata_fmt(&s->postin, s->int_sample_fmt);
+    set_audiodata_fmt(&s->midbuf, s->int_sample_fmt);
+    set_audiodata_fmt(&s->preout, s->int_sample_fmt);
+
+    if(s->resample){
+        set_audiodata_fmt(&s->in_buffer, s->int_sample_fmt);
+    }
+
+    s->dither = s->preout;
+
+    if(s->rematrix || s->dither_method)
+        return swri_rematrix_init(s);
+
+    return 0;
+}
+
+static int realloc_audio(AudioData *a, int count){
+    int i, countb;
+    AudioData old;
+
+    if(count < 0 || count > INT_MAX/2/a->bps/a->ch_count)
+        return AVERROR(EINVAL);
+
+    if(a->count >= count)
+        return 0;
+
+    count*=2;
+
+    countb= FFALIGN(count*a->bps, ALIGN);
+    old= *a;
+
+    av_assert0(a->bps);
+    av_assert0(a->ch_count);
+
+    a->data= av_mallocz(countb*a->ch_count);
+    if(!a->data)
+        return AVERROR(ENOMEM);
+    for(i=0; i<a->ch_count; i++){
+        a->ch[i]= a->data + i*(a->planar ? countb : a->bps);
+        if(a->planar) memcpy(a->ch[i], old.ch[i], a->count*a->bps);
+    }
+    if(!a->planar) memcpy(a->ch[0], old.ch[0], a->count*a->ch_count*a->bps);
+    av_free(old.data);
+    a->count= count;
+
+    return 1;
+}
+
+static void copy(AudioData *out, AudioData *in,
+                 int count){
+    av_assert0(out->planar == in->planar);
+    av_assert0(out->bps == in->bps);
+    av_assert0(out->ch_count == in->ch_count);
+    if(out->planar){
+        int ch;
+        for(ch=0; ch<out->ch_count; ch++)
+            memcpy(out->ch[ch], in->ch[ch], count*out->bps);
+    }else
+        memcpy(out->ch[0], in->ch[0], count*out->ch_count*out->bps);
+}
+
+static void fill_audiodata(AudioData *out, uint8_t *in_arg [SWR_CH_MAX]){
+    int i;
+    if(!in_arg){
+        memset(out->ch, 0, sizeof(out->ch));
+    }else if(out->planar){
+        for(i=0; i<out->ch_count; i++)
+            out->ch[i]= in_arg[i];
+    }else{
+        for(i=0; i<out->ch_count; i++)
+            out->ch[i]= in_arg[0] + i*out->bps;
+    }
+}
+
+static void reversefill_audiodata(AudioData *out, uint8_t *in_arg [SWR_CH_MAX]){
+    int i;
+    if(out->planar){
+        for(i=0; i<out->ch_count; i++)
+            in_arg[i]= out->ch[i];
+    }else{
+        in_arg[0]= out->ch[0];
+    }
+}
+
+/**
+ *
+ * out may be equal in.
+ */
+static void buf_set(AudioData *out, AudioData *in, int count){
+    int ch;
+    if(in->planar){
+        for(ch=0; ch<out->ch_count; ch++)
+            out->ch[ch]= in->ch[ch] + count*out->bps;
+    }else{
+        for(ch=out->ch_count-1; ch>=0; ch--)
+            out->ch[ch]= in->ch[0] + (ch + count*out->ch_count) * out->bps;
+    }
+}
+
+/**
+ *
+ * @return number of samples output per channel
+ */
+static int resample(SwrContext *s, AudioData *out_param, int out_count,
+                             const AudioData * in_param, int in_count){
+    AudioData in, out, tmp;
+    int ret_sum=0;
+    int border=0;
+
+    av_assert1(s->in_buffer.ch_count == in_param->ch_count);
+    av_assert1(s->in_buffer.planar   == in_param->planar);
+    av_assert1(s->in_buffer.fmt      == in_param->fmt);
+
+    tmp=out=*out_param;
+    in =  *in_param;
+
+    do{
+        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);
+            out_count -= ret;
+            ret_sum += ret;
+            buf_set(&out, &out, ret);
+            s->in_buffer_count -= consumed;
+            s->in_buffer_index += consumed;
+
+            if(!in_count)
+                break;
+            if(s->in_buffer_count <= border){
+                buf_set(&in, &in, -s->in_buffer_count);
+                in_count += s->in_buffer_count;
+                s->in_buffer_count=0;
+                s->in_buffer_index=0;
+                border = 0;
+            }
+        }
+
+        if(in_count && !s->in_buffer_count){
+            s->in_buffer_index=0;
+            ret= swri_multiple_resample(s->resample, &out, out_count, &in, in_count, &consumed);
+            out_count -= ret;
+            ret_sum += ret;
+            buf_set(&out, &out, ret);
+            in_count -= consumed;
+            buf_set(&in, &in, consumed);
+        }
+
+        //TODO is this check sane considering the advanced copy avoidance below
+        size= s->in_buffer_index + s->in_buffer_count + in_count;
+        if(   size > s->in_buffer.count
+           && s->in_buffer_count + in_count <= s->in_buffer_index){
+            buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
+            copy(&s->in_buffer, &tmp, s->in_buffer_count);
+            s->in_buffer_index=0;
+        }else
+            if((ret=realloc_audio(&s->in_buffer, size)) < 0)
+                return ret;
+
+        if(in_count){
+            int count= in_count;
+            if(s->in_buffer_count && s->in_buffer_count+2 < count && out_count) count= s->in_buffer_count+2;
+
+            buf_set(&tmp, &s->in_buffer, s->in_buffer_index + s->in_buffer_count);
+            copy(&tmp, &in, /*in_*/count);
+            s->in_buffer_count += count;
+            in_count -= count;
+            border += count;
+            buf_set(&in, &in, count);
+            s->resample_in_constraint= 0;
+            if(s->in_buffer_count != count || in_count)
+                continue;
+        }
+        break;
+    }while(1);
+
+    s->resample_in_constraint= !!out_count;
+
+    return ret_sum;
+}
+
+static int swr_convert_internal(struct SwrContext *s, AudioData *out, int out_count,
+                                                      AudioData *in , int  in_count){
+    AudioData *postin, *midbuf, *preout;
+    int ret/*, in_max*/;
+    AudioData preout_tmp, midbuf_tmp;
+
+    if(s->full_convert){
+        av_assert0(!s->resample);
+        swri_audio_convert(s->full_convert, out, in, in_count);
+        return out_count;
+    }
+
+//     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)
+        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)
+            return ret;
+    }else{
+        av_assert0(s->midbuf.ch_count ==  s->out.ch_count);
+        if((ret=realloc_audio(&s->midbuf,  in_count))<0)
+            return ret;
+    }
+    if((ret=realloc_audio(&s->preout, out_count))<0)
+        return ret;
+
+    postin= &s->postin;
+
+    midbuf_tmp= s->midbuf;
+    midbuf= &midbuf_tmp;
+    preout_tmp= s->preout;
+    preout= &preout_tmp;
+
+    if(s->int_sample_fmt == s-> in_sample_fmt && s->in.planar && !s->channel_map)
+        postin= in;
+
+    if(s->resample_first ? !s->resample : !s->rematrix)
+        midbuf= postin;
+
+    if(s->resample_first ? !s->rematrix : !s->resample)
+        preout= midbuf;
+
+    if(s->int_sample_fmt == s->out_sample_fmt && s->out.planar){
+        if(preout==in){
+            out_count= FFMIN(out_count, in_count); //TODO check at the end if this is needed or redundant
+            av_assert0(s->in.planar); //we only support planar internally so it has to be, we support copying non planar though
+            copy(out, in, out_count);
+            return out_count;
+        }
+        else if(preout==postin) preout= midbuf= postin= out;
+        else if(preout==midbuf) preout= midbuf= out;
+        else                    preout= out;
+    }
+
+    if(in != postin){
+        swri_audio_convert(s->in_convert, postin, in, in_count);
+    }
+
+    if(s->resample_first){
+        if(postin != midbuf)
+            out_count= resample(s, midbuf, out_count, postin, in_count);
+        if(midbuf != preout)
+            swri_rematrix(s, preout, midbuf, out_count, preout==out);
+    }else{
+        if(postin != midbuf)
+            swri_rematrix(s, midbuf, postin, in_count, midbuf==out);
+        if(midbuf != preout)
+            out_count= resample(s, preout, out_count, midbuf, in_count);
+    }
+
+    if(preout != out && out_count){
+        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)
+                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);
+
+            if(s->dither_pos + out_count > s->dither.count)
+                s->dither_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);
+
+            s->dither_pos += out_count;
+        }
+//FIXME packed doesnt need more than 1 chan here!
+        swri_audio_convert(s->out_convert, out, preout, out_count);
+    }
+    return out_count;
+}
+
+int swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_count,
+                                const uint8_t *in_arg [SWR_CH_MAX], int  in_count){
+    AudioData * in= &s->in;
+    AudioData *out= &s->out;
+
+    if(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)
+            return ret;
+
+        reversefill_audiodata(&tmp, 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
+        s->drop_output *= -1;
+        if(ret>0)
+            s->drop_output -= ret;
+
+        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{
+            return 0;
+        }
+    }else
+        fill_audiodata(in ,  (void*)in_arg);
+
+    fill_audiodata(out, out_arg);
+
+    if(s->resample){
+        int ret = swr_convert_internal(s, out, out_count, in, in_count);
+        if(ret>0 && !s->drop_output)
+            s->outpts += ret * (int64_t)s->in_sample_rate;
+        return ret;
+    }else{
+        AudioData tmp= *in;
+        int ret2=0;
+        int ret, size;
+        size = FFMIN(out_count, s->in_buffer_count);
+        if(size){
+            buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
+            ret= swr_convert_internal(s, out, size, &tmp, size);
+            if(ret<0)
+                return ret;
+            ret2= ret;
+            s->in_buffer_count -= ret;
+            s->in_buffer_index += ret;
+            buf_set(out, out, ret);
+            out_count -= ret;
+            if(!s->in_buffer_count)
+                s->in_buffer_index = 0;
+        }
+
+        if(in_count){
+            size= s->in_buffer_index + s->in_buffer_count + in_count - out_count;
+
+            if(in_count > out_count) { //FIXME move after swr_convert_internal
+                if(   size > s->in_buffer.count
+                && s->in_buffer_count + in_count - out_count <= s->in_buffer_index){
+                    buf_set(&tmp, &s->in_buffer, s->in_buffer_index);
+                    copy(&s->in_buffer, &tmp, s->in_buffer_count);
+                    s->in_buffer_index=0;
+                }else
+                    if((ret=realloc_audio(&s->in_buffer, size)) < 0)
+                        return ret;
+            }
+
+            if(out_count){
+                size = FFMIN(in_count, out_count);
+                ret= swr_convert_internal(s, out, size, in, size);
+                if(ret<0)
+                    return ret;
+                buf_set(in, in, ret);
+                in_count -= ret;
+                ret2 += ret;
+            }
+            if(in_count){
+                buf_set(&tmp, &s->in_buffer, s->in_buffer_index + s->in_buffer_count);
+                copy(&tmp, in, in_count);
+                s->in_buffer_count += in_count;
+            }
+        }
+        if(ret2>0 && !s->drop_output)
+            s->outpts += ret2 * (int64_t)s->in_sample_rate;
+        return ret2;
+    }
+}
+
+int swr_drop_output(struct SwrContext *s, int count){
+    s->drop_output += count;
+
+    if(s->drop_output <= 0)
+        return 0;
+
+    av_log(s, AV_LOG_VERBOSE, "discarding %d audio samples\n", count);
+    return swr_convert(s, NULL, s->drop_output, NULL, 0);
+}
+
+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)
+        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);
+    } else
+        memset(silence.ch[0], silence.bps==1 ? 0x80 : 0, count*silence.bps*silence.ch_count);
+
+    reversefill_audiodata(&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_next_pts(struct SwrContext *s, int64_t pts){
+    if(pts == INT64_MIN)
+        return s->outpts;
+    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;
+        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){
+                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);
+                if(ret<0){
+                    av_log(s, AV_LOG_ERROR, "Failed to compensate for timestamp delta of %f\n", fdelta);
+                }
+            } else if(s->soft_compensation_duration && s->max_soft_compensation) {
+                int duration = s->out_sample_rate * s->soft_compensation_duration;
+                double max_soft_compensation = s->max_soft_compensation / (s->max_soft_compensation < 0 ? -s->in_sample_rate : 1);
+                int comp = av_clipf(fdelta, -max_soft_compensation, max_soft_compensation) * duration ;
+                av_log(s, AV_LOG_VERBOSE, "compensating audio timestamp drift:%f compensation:%d in:%d\n", fdelta, comp, duration);
+                swr_set_compensation(s, comp, duration);
+            }
+        }
+
+        return s->outpts;
+    }
+}
diff --git a/libswresample/swresample.h b/libswresample/swresample.h
new file mode 100644
index 0000000..ac43cd2
--- /dev/null
+++ b/libswresample/swresample.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
+ *
+ * This file is part of libswresample
+ *
+ * libswresample 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.
+ *
+ * libswresample is distributed in the hope that 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 libswresample; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * libswresample public header
+ */
+
+#ifndef SWR_H
+#define SWR_H
+
+#include <inttypes.h>
+#include "libavutil/samplefmt.h"
+
+#include "libswresample/version.h"
+
+#if LIBSWRESAMPLE_VERSION_MAJOR < 1
+#define SWR_CH_MAX 32   ///< Maximum number of channels
+#endif
+
+#define SWR_FLAG_RESAMPLE 1 ///< Force resampling even if equal sample rate
+//TODO use int resample ?
+//long term TODO can we enable this dynamically?
+
+enum SwrDitherType {
+    SWR_DITHER_NONE = 0,
+    SWR_DITHER_RECTANGULAR,
+    SWR_DITHER_TRIANGULAR,
+    SWR_DITHER_TRIANGULAR_HIGHPASS,
+    SWR_DITHER_NB,              ///< not part of API/ABI
+};
+
+/** Resampling Filter Types */
+enum SwrFilterType {
+    SWR_FILTER_TYPE_CUBIC,              /**< Cubic */
+    SWR_FILTER_TYPE_BLACKMAN_NUTTALL,   /**< Blackman Nuttall Windowed Sinc */
+    SWR_FILTER_TYPE_KAISER,             /**< Kaiser Windowed Sinc */
+};
+
+typedef struct SwrContext SwrContext;
+
+/**
+ * Get the AVClass for swrContext. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
+ *
+ * @see av_opt_find().
+ */
+const AVClass *swr_get_class(void);
+
+/**
+ * Allocate SwrContext.
+ *
+ * If you use this function you will need to set the parameters (manually or
+ * with swr_alloc_set_opts()) before calling swr_init().
+ *
+ * @see swr_alloc_set_opts(), swr_init(), swr_free()
+ * @return NULL on error, allocated context otherwise
+ */
+struct SwrContext *swr_alloc(void);
+
+/**
+ * Initialize context after user parameters have been set.
+ *
+ * @return AVERROR error code in case of failure.
+ */
+int swr_init(struct SwrContext *s);
+
+/**
+ * Allocate SwrContext if needed and set/reset common parameters.
+ *
+ * This function does not require s to be allocated with swr_alloc(). On the
+ * other hand, swr_alloc() can use swr_alloc_set_opts() to set the parameters
+ * on the allocated context.
+ *
+ * @param s               Swr context, can be NULL
+ * @param out_ch_layout   output channel layout (AV_CH_LAYOUT_*)
+ * @param out_sample_fmt  output sample format (AV_SAMPLE_FMT_*).
+ * @param out_sample_rate output sample rate (frequency in Hz)
+ * @param in_ch_layout    input channel layout (AV_CH_LAYOUT_*)
+ * @param in_sample_fmt   input sample format (AV_SAMPLE_FMT_*).
+ * @param in_sample_rate  input sample rate (frequency in Hz)
+ * @param log_offset      logging level offset
+ * @param log_ctx         parent logging context, can be NULL
+ *
+ * @see swr_init(), swr_free()
+ * @return NULL on error, allocated context otherwise
+ */
+struct SwrContext *swr_alloc_set_opts(struct SwrContext *s,
+                                      int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
+                                      int64_t  in_ch_layout, enum AVSampleFormat  in_sample_fmt, int  in_sample_rate,
+                                      int log_offset, void *log_ctx);
+
+/**
+ * Free the given SwrContext and set the pointer to NULL.
+ */
+void swr_free(struct SwrContext **s);
+
+/**
+ * Convert audio.
+ *
+ * in and in_count can be set to 0 to flush the last few samples out at the
+ * end.
+ *
+ * If more input is provided than output space then the input will be buffered.
+ * You can avoid this buffering by providing more output space than input.
+ * Convertion will run directly without copying whenever possible.
+ *
+ * @param s         allocated Swr context, with parameters set
+ * @param out       output buffers, only the first one need be set in case of packed audio
+ * @param out_count amount of space available for output in samples per channel
+ * @param in        input buffers, only the first one need to be set in case of packed audio
+ * @param in_count  number of input samples available in one channel
+ *
+ * @return number of samples output per channel, negative value on error
+ */
+int swr_convert(struct SwrContext *s, uint8_t **out, int out_count,
+                                const uint8_t **in , int in_count);
+
+/**
+ * Convert the next timestamp from input to output
+ * timestampe are in 1/(in_sample_rate * out_sample_rate) units.
+ *
+ * @note There are 2 slightly differently behaving modes.
+ *       First is when automatic timestamp compensation is not used, (min_compensation >= FLT_MAX)
+ *              in this case timestamps will be passed through with delays compensated
+ *       Second is when automatic timestamp compensation is used, (min_compensation < FLT_MAX)
+ *              in this case the output timestamps will match output sample numbers
+ *
+ * @param pts   timstamp for the next input sample, INT64_MIN if unknown
+ * @returns the output timestamp for the next output sample
+ */
+int64_t swr_next_pts(struct SwrContext *s, int64_t pts);
+
+/**
+ * Activate resampling compensation.
+ */
+int swr_set_compensation(struct SwrContext *s, int sample_delta, int compensation_distance);
+
+/**
+ * Set a customized input channel mapping.
+ *
+ * @param s           allocated Swr context, not yet initialized
+ * @param channel_map customized input channel mapping (array of channel
+ *                    indexes, -1 for a muted channel)
+ * @return AVERROR error code in case of failure.
+ */
+int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map);
+
+/**
+ * Set a customized remix matrix.
+ *
+ * @param s       allocated Swr context, not yet initialized
+ * @param matrix  remix coefficients; matrix[i + stride * o] is
+ *                the weight of input channel i in output channel o
+ * @param stride  offset between lines of the matrix
+ * @return  AVERROR error code in case of failure.
+ */
+int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride);
+
+/**
+ * Drops the specified number of output samples.
+ */
+int swr_drop_output(struct SwrContext *s, int count);
+
+/**
+ * Injects the specified number of silence samples.
+ */
+int swr_inject_silence(struct SwrContext *s, int count);
+
+/**
+ * Gets the delay the next input sample will experience relative to the next output sample.
+ *
+ * Swresample can buffer data if more input has been provided than available
+ * output space, also converting between sample rates needs a delay.
+ * This function returns the sum of all such delays.
+ *
+ * @param s     swr context
+ * @param base  timebase in which the returned delay will be
+ *              if its set to 1 the returned delay is in seconds
+ *              if its set to 1000 the returned delay is in milli seconds
+ *              if its set to the input sample rate then the returned delay is in input samples
+ *              if its set to the output sample rate then the returned delay is in output samples
+ *              an exact rounding free delay can be found by using LCM(in_sample_rate, out_sample_rate)
+ * @returns     the delay in 1/base units.
+ */
+int64_t swr_get_delay(struct SwrContext *s, int64_t base);
+
+/**
+ * Return the LIBSWRESAMPLE_VERSION_INT constant.
+ */
+unsigned swresample_version(void);
+
+/**
+ * Return the swr build-time configuration.
+ */
+const char *swresample_configuration(void);
+
+/**
+ * Return the swr license.
+ */
+const char *swresample_license(void);
+
+#endif
diff --git a/libswresample/swresample_internal.h b/libswresample/swresample_internal.h
new file mode 100644
index 0000000..ab17602
--- /dev/null
+++ b/libswresample/swresample_internal.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
+ *
+ * This file is part of libswresample
+ *
+ * libswresample 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.
+ *
+ * libswresample is distributed in the hope that 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 libswresample; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef SWR_INTERNAL_H
+#define SWR_INTERNAL_H
+
+#include "swresample.h"
+#include "libavutil/audioconvert.h"
+
+#define SQRT3_2      1.22474487139158904909  /* sqrt(3/2) */
+
+typedef void (mix_1_1_func_type)(void *out, const void *in, void *coeffp, int index, int len);
+typedef void (mix_2_1_func_type)(void *out, const void *in1, const void *in2, void *coeffp, int index1, int index2, int len);
+
+typedef void (mix_any_func_type)(uint8_t **out, const uint8_t **in1, void *coeffp, int len);
+
+typedef struct AudioData{
+    uint8_t *ch[SWR_CH_MAX];    ///< samples buffer per channel
+    uint8_t *data;              ///< samples buffer
+    int ch_count;               ///< number of channels
+    int bps;                    ///< bytes per sample
+    int count;                  ///< number of samples
+    int planar;                 ///< 1 if planar audio, 0 otherwise
+    enum AVSampleFormat fmt;    ///< sample format
+} AudioData;
+
+struct SwrContext {
+    const AVClass *av_class;                        ///< AVClass used for AVOption and av_log()
+    int log_level_offset;                           ///< logging level offset
+    void *log_ctx;                                  ///< parent logging context
+    enum AVSampleFormat  in_sample_fmt;             ///< input sample format
+    enum AVSampleFormat int_sample_fmt;             ///< internal sample format (AV_SAMPLE_FMT_FLTP or AV_SAMPLE_FMT_S16P)
+    enum AVSampleFormat out_sample_fmt;             ///< output sample format
+    int64_t  in_ch_layout;                          ///< input channel layout
+    int64_t out_ch_layout;                          ///< output channel layout
+    int      in_sample_rate;                        ///< input sample rate
+    int     out_sample_rate;                        ///< output sample rate
+    int flags;                                      ///< miscellaneous flags such as SWR_FLAG_RESAMPLE
+    float slev;                                     ///< surround mixing level
+    float clev;                                     ///< center mixing level
+    float lfe_mix_level;                            ///< LFE mixing level
+    float rematrix_volume;                          ///< rematrixing volume coefficient
+    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;
+    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) */
+
+    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
+
+    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)
+    int rematrix_custom;                            ///< flag to indicate that a custom matrix has been defined
+
+    AudioData in;                                   ///< input audio data
+    AudioData postin;                               ///< post-input audio data: used for rematrix/resample
+    AudioData midbuf;                               ///< intermediate audio data (postin/preout)
+    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
+    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
+    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
+
+    float matrix[SWR_CH_MAX][SWR_CH_MAX];           ///< floating point rematrixing coefficients
+    uint8_t *native_matrix;
+    uint8_t *native_one;
+    uint8_t *native_simd_matrix;
+    int32_t matrix32[SWR_CH_MAX][SWR_CH_MAX];       ///< 17.15 fixed point rematrixing coefficients
+    uint8_t matrix_ch[SWR_CH_MAX][SWR_CH_MAX+1];    ///< Lists of input channels per output channel that have non zero rematrixing coefficients
+    mix_1_1_func_type *mix_1_1_f;
+    mix_1_1_func_type *mix_1_1_simd;
+
+    mix_2_1_func_type *mix_2_1_f;
+    mix_2_1_func_type *mix_2_1_simd;
+
+    mix_any_func_type *mix_any_f;
+
+    /* 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);
+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);
+
+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_audio_convert_init_arm(struct AudioConvert *ac,
+                                 enum AVSampleFormat out_fmt,
+                                 enum AVSampleFormat in_fmt,
+                                 int channels);
+void swri_audio_convert_init_x86(struct AudioConvert *ac,
+                                 enum AVSampleFormat out_fmt,
+                                 enum AVSampleFormat in_fmt,
+                                 int channels);
+#endif
diff --git a/libswresample/version.h b/libswresample/version.h
new file mode 100644
index 0000000..2c7b932
--- /dev/null
+++ b/libswresample/version.h
@@ -0,0 +1,45 @@
+/*
+ * Version macros.
+ *
+ * This file is part of libswresample
+ *
+ * libswresample 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.
+ *
+ * libswresample is distributed in the hope that 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 libswresample; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef SWR_VERSION_H
+#define SWR_VERSION_H
+
+/**
+ * @file
+ * Libswresample version macros
+ */
+
+#include "libavutil/avutil.h"
+
+#define LIBSWRESAMPLE_VERSION_MAJOR 0
+#define LIBSWRESAMPLE_VERSION_MINOR 16
+#define LIBSWRESAMPLE_VERSION_MICRO 100
+
+#define LIBSWRESAMPLE_VERSION_INT  AV_VERSION_INT(LIBSWRESAMPLE_VERSION_MAJOR, \
+                                                  LIBSWRESAMPLE_VERSION_MINOR, \
+                                                  LIBSWRESAMPLE_VERSION_MICRO)
+#define LIBSWRESAMPLE_VERSION      AV_VERSION(LIBSWRESAMPLE_VERSION_MAJOR, \
+                                              LIBSWRESAMPLE_VERSION_MINOR, \
+                                              LIBSWRESAMPLE_VERSION_MICRO)
+#define LIBSWRESAMPLE_BUILD        LIBSWRESAMPLE_VERSION_INT
+
+#define LIBSWRESAMPLE_IDENT        "SwR" AV_STRINGIFY(LIBSWRESAMPLE_VERSION)
+
+#endif /* SWR_VERSION_H */
diff --git a/libswresample/x86/Makefile b/libswresample/x86/Makefile
new file mode 100644
index 0000000..e8feede
--- /dev/null
+++ b/libswresample/x86/Makefile
@@ -0,0 +1,3 @@
+YASM-OBJS                       += x86/swresample_x86.o\
+                                   x86/audio_convert.o\
+                                   x86/rematrix.o\
diff --git a/libswresample/x86/audio_convert.asm b/libswresample/x86/audio_convert.asm
new file mode 100644
index 0000000..29701a5
--- /dev/null
+++ b/libswresample/x86/audio_convert.asm
@@ -0,0 +1,462 @@
+;******************************************************************************
+;* 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
+;******************************************************************************
+
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
+
+SECTION_RODATA
+align 32
+flt2pm31: times 8 dd 4.6566129e-10
+flt2p31 : times 8 dd 2147483648.0
+flt2p15 : times 8 dd 32768.0
+
+word_unpack_shuf : db  0, 1, 4, 5, 8, 9,12,13, 2, 3, 6, 7,10,11,14,15
+
+SECTION .text
+
+
+;to, from, a/u, log2_outsize, log_intsize, const
+%macro PACK_2CH 5-7
+cglobal pack_2ch_%2_to_%1_%3, 3, 4, 6, dst, src, len, src2
+    mov src2q   , [srcq+gprsize]
+    mov srcq    , [srcq]
+    mov dstq    , [dstq]
+%ifidn %3, a
+    test dstq, mmsize-1
+        jne pack_2ch_%2_to_%1_u_int %+ SUFFIX
+    test srcq, mmsize-1
+        jne pack_2ch_%2_to_%1_u_int %+ SUFFIX
+    test src2q, mmsize-1
+        jne pack_2ch_%2_to_%1_u_int %+ SUFFIX
+%else
+pack_2ch_%2_to_%1_u_int %+ SUFFIX
+%endif
+    lea     srcq , [srcq  + (1<<%5)*lenq]
+    lea     src2q, [src2q + (1<<%5)*lenq]
+    lea     dstq , [dstq  + (2<<%4)*lenq]
+    neg     lenq
+    %7 m0,m1,m2,m3,m4,m5
+.next:
+%if %4 >= %5
+    mov%3     m0, [         srcq +(1<<%5)*lenq]
+    mova      m1, m0
+    mov%3     m2, [         src2q+(1<<%5)*lenq]
+%if %5 == 1
+    punpcklwd m0, m2
+    punpckhwd m1, m2
+%else
+    punpckldq m0, m2
+    punpckhdq m1, m2
+%endif
+    %6 m0,m1,m2,m3,m4,m5
+%else
+    mov%3     m0, [         srcq +(1<<%5)*lenq]
+    mov%3     m1, [mmsize + srcq +(1<<%5)*lenq]
+    mov%3     m2, [         src2q+(1<<%5)*lenq]
+    mov%3     m3, [mmsize + src2q+(1<<%5)*lenq]
+    %6 m0,m1,m2,m3,m4,m5
+    mova      m2, m0
+    punpcklwd m0, m1
+    punpckhwd m2, m1
+    SWAP 1,2
+%endif
+    mov%3 [           dstq+(2<<%4)*lenq], m0
+    mov%3 [  mmsize + dstq+(2<<%4)*lenq], m1
+%if %4 > %5
+    mov%3 [2*mmsize + dstq+(2<<%4)*lenq], m2
+    mov%3 [3*mmsize + dstq+(2<<%4)*lenq], m3
+    add lenq, 4*mmsize/(2<<%4)
+%else
+    add lenq, 2*mmsize/(2<<%4)
+%endif
+        jl .next
+    REP_RET
+%endmacro
+
+%macro UNPACK_2CH 5-7
+cglobal unpack_2ch_%2_to_%1_%3, 3, 4, 7, dst, src, len, dst2
+    mov dst2q   , [dstq+gprsize]
+    mov srcq    , [srcq]
+    mov dstq    , [dstq]
+%ifidn %3, a
+    test dstq, mmsize-1
+        jne unpack_2ch_%2_to_%1_u_int %+ SUFFIX
+    test srcq, mmsize-1
+        jne unpack_2ch_%2_to_%1_u_int %+ SUFFIX
+    test dst2q, mmsize-1
+        jne unpack_2ch_%2_to_%1_u_int %+ SUFFIX
+%else
+unpack_2ch_%2_to_%1_u_int %+ SUFFIX
+%endif
+    lea     srcq , [srcq  + (2<<%5)*lenq]
+    lea     dstq , [dstq  + (1<<%4)*lenq]
+    lea     dst2q, [dst2q + (1<<%4)*lenq]
+    neg     lenq
+    %7 m0,m1,m2,m3,m4,m5
+    mova      m6, [word_unpack_shuf]
+.next:
+    mov%3     m0, [           srcq +(2<<%5)*lenq]
+    mov%3     m2, [  mmsize + srcq +(2<<%5)*lenq]
+%if %5 == 1
+%ifidn SUFFIX, _ssse3
+    pshufb    m0, m6
+    mova      m1, m0
+    pshufb    m2, m6
+    punpcklqdq m0,m2
+    punpckhqdq m1,m2
+%else
+    mova      m1, m0
+    punpcklwd m0,m2
+    punpckhwd m1,m2
+
+    mova      m2, m0
+    punpcklwd m0,m1
+    punpckhwd m2,m1
+
+    mova      m1, m0
+    punpcklwd m0,m2
+    punpckhwd m1,m2
+%endif
+%else
+    mova      m1, m0
+    shufps    m0, m2, 10001000b
+    shufps    m1, m2, 11011101b
+%endif
+%if %4 < %5
+    mov%3     m2, [2*mmsize + srcq +(2<<%5)*lenq]
+    mova      m3, m2
+    mov%3     m4, [3*mmsize + srcq +(2<<%5)*lenq]
+    shufps    m2, m4, 10001000b
+    shufps    m3, m4, 11011101b
+    SWAP 1,2
+%endif
+    %6 m0,m1,m2,m3,m4,m5
+    mov%3 [           dstq+(1<<%4)*lenq], m0
+%if %4 > %5
+    mov%3 [          dst2q+(1<<%4)*lenq], m2
+    mov%3 [ mmsize +  dstq+(1<<%4)*lenq], m1
+    mov%3 [ mmsize + dst2q+(1<<%4)*lenq], m3
+    add lenq, 2*mmsize/(1<<%4)
+%else
+    mov%3 [          dst2q+(1<<%4)*lenq], m1
+    add lenq, mmsize/(1<<%4)
+%endif
+        jl .next
+    REP_RET
+%endmacro
+
+%macro CONV 5-7
+cglobal %2_to_%1_%3, 3, 3, 6, dst, src, len
+    mov srcq    , [srcq]
+    mov dstq    , [dstq]
+%ifidn %3, a
+    test dstq, mmsize-1
+        jne %2_to_%1_u_int %+ SUFFIX
+    test srcq, mmsize-1
+        jne %2_to_%1_u_int %+ SUFFIX
+%else
+%2_to_%1_u_int %+ SUFFIX
+%endif
+    lea     srcq , [srcq  + (1<<%5)*lenq]
+    lea     dstq , [dstq  + (1<<%4)*lenq]
+    neg     lenq
+    %7 m0,m1,m2,m3,m4,m5
+.next:
+    mov%3     m0, [           srcq +(1<<%5)*lenq]
+    mov%3     m1, [  mmsize + srcq +(1<<%5)*lenq]
+%if %4 < %5
+    mov%3     m2, [2*mmsize + srcq +(1<<%5)*lenq]
+    mov%3     m3, [3*mmsize + srcq +(1<<%5)*lenq]
+%endif
+    %6 m0,m1,m2,m3,m4,m5
+    mov%3 [           dstq+(1<<%4)*lenq], m0
+    mov%3 [  mmsize + dstq+(1<<%4)*lenq], m1
+%if %4 > %5
+    mov%3 [2*mmsize + dstq+(1<<%4)*lenq], m2
+    mov%3 [3*mmsize + dstq+(1<<%4)*lenq], m3
+    add lenq, 4*mmsize/(1<<%4)
+%else
+    add lenq, 2*mmsize/(1<<%4)
+%endif
+        jl .next
+    REP_RET
+%endmacro
+
+%macro PACK_6CH 5-7
+cglobal pack_6ch_%2_to_%1_%3, 2,8,7, dst, src, src1, src2, src3, src4, src5, len
+%if ARCH_X86_64
+    mov     lend, r2d
+%else
+    %define lend dword r2m
+%endif
+    mov    src1q, [srcq+1*gprsize]
+    mov    src2q, [srcq+2*gprsize]
+    mov    src3q, [srcq+3*gprsize]
+    mov    src4q, [srcq+4*gprsize]
+    mov    src5q, [srcq+5*gprsize]
+    mov     srcq, [srcq]
+    mov     dstq, [dstq]
+%ifidn %3, a
+    test dstq, mmsize-1
+        jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
+    test srcq, mmsize-1
+        jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
+    test src2q, mmsize-1
+        jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
+    test src3q, mmsize-1
+        jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
+    test src4q, mmsize-1
+        jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
+    test src5q, mmsize-1
+        jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
+%else
+pack_6ch_%2_to_%1_u_int %+ SUFFIX
+%endif
+    sub    src1q, srcq
+    sub    src2q, srcq
+    sub    src3q, srcq
+    sub    src4q, srcq
+    sub    src5q, srcq
+.loop:
+    mov%3     m0, [srcq      ]
+    mov%3     m1, [srcq+src1q]
+    mov%3     m2, [srcq+src2q]
+    mov%3     m3, [srcq+src3q]
+    mov%3     m4, [srcq+src4q]
+    mov%3     m5, [srcq+src5q]
+    %7 x,x,x,x,m7,x
+%if cpuflag(sse4)
+    SBUTTERFLYPS 0, 1, 6
+    SBUTTERFLYPS 2, 3, 6
+    SBUTTERFLYPS 4, 5, 6
+
+    blendps   m6, m4, m0, 1100b
+    movlhps   m0, m2
+    movhlps   m4, m2
+    blendps   m2, m5, m1, 1100b
+    movlhps   m1, m3
+    movhlps   m5, m3
+
+    %6 m0,m6,x,x,m7,m3
+    %6 m4,m1,x,x,m7,m3
+    %6 m2,m5,x,x,m7,m3
+
+    mov %+ %3 %+ ps [dstq   ], m0
+    mov %+ %3 %+ ps [dstq+16], m6
+    mov %+ %3 %+ ps [dstq+32], m4
+    mov %+ %3 %+ ps [dstq+48], m1
+    mov %+ %3 %+ ps [dstq+64], m2
+    mov %+ %3 %+ ps [dstq+80], m5
+%else ; mmx
+    SBUTTERFLY dq, 0, 1, 6
+    SBUTTERFLY dq, 2, 3, 6
+    SBUTTERFLY dq, 4, 5, 6
+
+    movq   [dstq   ], m0
+    movq   [dstq+ 8], m2
+    movq   [dstq+16], m4
+    movq   [dstq+24], m1
+    movq   [dstq+32], m3
+    movq   [dstq+40], m5
+%endif
+    add      srcq, mmsize
+    add      dstq, mmsize*6
+    sub      lend, mmsize/4
+    jg .loop
+%if mmsize == 8
+    emms
+    RET
+%else
+    REP_RET
+%endif
+%endmacro
+
+%macro INT16_TO_INT32_N 6
+    pxor      m2, m2
+    pxor      m3, m3
+    punpcklwd m2, m1
+    punpckhwd m3, m1
+    SWAP 4,0
+    pxor      m0, m0
+    pxor      m1, m1
+    punpcklwd m0, m4
+    punpckhwd m1, m4
+%endmacro
+
+%macro INT32_TO_INT16_N 6
+    psrad     m0, 16
+    psrad     m1, 16
+    psrad     m2, 16
+    psrad     m3, 16
+    packssdw  m0, m1
+    packssdw  m2, m3
+    SWAP 1,2
+%endmacro
+
+%macro INT32_TO_FLOAT_INIT 6
+    mova      %5, [flt2pm31]
+%endmacro
+%macro INT32_TO_FLOAT_N 6
+    cvtdq2ps  %1, %1
+    cvtdq2ps  %2, %2
+    mulps %1, %1, %5
+    mulps %2, %2, %5
+%endmacro
+
+%macro FLOAT_TO_INT32_INIT 6
+    mova      %5, [flt2p31]
+%endmacro
+%macro FLOAT_TO_INT32_N 6
+    mulps %1, %5
+    mulps %2, %5
+    cvtps2dq  %6, %1
+    cmpnltps %1, %5
+    paddd %1, %6
+    cvtps2dq  %6, %2
+    cmpnltps %2, %5
+    paddd %2, %6
+%endmacro
+
+%macro INT16_TO_FLOAT_INIT 6
+    mova      m5, [flt2pm31]
+%endmacro
+%macro INT16_TO_FLOAT_N 6
+    INT16_TO_INT32_N %1,%2,%3,%4,%5,%6
+    cvtdq2ps  m0, m0
+    cvtdq2ps  m1, m1
+    cvtdq2ps  m2, m2
+    cvtdq2ps  m3, m3
+    mulps m0, m0, m5
+    mulps m1, m1, m5
+    mulps m2, m2, m5
+    mulps m3, m3, m5
+%endmacro
+
+%macro FLOAT_TO_INT16_INIT 6
+    mova      m5, [flt2p15]
+%endmacro
+%macro FLOAT_TO_INT16_N 6
+    mulps m0, m5
+    mulps m1, m5
+    mulps m2, m5
+    mulps m3, m5
+    cvtps2dq  m0, m0
+    cvtps2dq  m1, m1
+    packssdw  m0, m1
+    cvtps2dq  m1, m2
+    cvtps2dq  m3, m3
+    packssdw  m1, m3
+%endmacro
+
+%macro NOP_N 0-6
+%endmacro
+
+INIT_MMX mmx
+CONV int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
+CONV int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
+CONV int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
+CONV int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
+
+PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
+PACK_6CH float, float, a, 2, 2, NOP_N, NOP_N
+
+INIT_XMM sse2
+CONV int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
+CONV int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
+CONV int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
+CONV int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
+
+PACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N
+PACK_2CH int16, int16, a, 1, 1, NOP_N, NOP_N
+PACK_2CH int32, int32, u, 2, 2, NOP_N, NOP_N
+PACK_2CH int32, int32, a, 2, 2, NOP_N, NOP_N
+PACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
+PACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
+PACK_2CH int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
+PACK_2CH int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
+
+UNPACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N
+UNPACK_2CH int16, int16, a, 1, 1, NOP_N, NOP_N
+UNPACK_2CH int32, int32, u, 2, 2, NOP_N, NOP_N
+UNPACK_2CH int32, int32, a, 2, 2, NOP_N, NOP_N
+UNPACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
+UNPACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
+UNPACK_2CH int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
+UNPACK_2CH int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
+
+CONV float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
+CONV float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
+CONV int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
+CONV int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
+CONV float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
+CONV float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
+CONV int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
+CONV int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
+
+PACK_2CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
+PACK_2CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
+PACK_2CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
+PACK_2CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
+PACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
+PACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
+PACK_2CH int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
+PACK_2CH int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
+
+UNPACK_2CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
+UNPACK_2CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
+UNPACK_2CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
+UNPACK_2CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
+UNPACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
+UNPACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
+UNPACK_2CH int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
+UNPACK_2CH int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
+
+
+INIT_XMM ssse3
+UNPACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N
+UNPACK_2CH int16, int16, a, 1, 1, NOP_N, NOP_N
+UNPACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
+UNPACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
+UNPACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
+UNPACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
+
+INIT_XMM sse4
+PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
+PACK_6CH float, float, a, 2, 2, NOP_N, NOP_N
+
+PACK_6CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
+PACK_6CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
+PACK_6CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
+PACK_6CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
+
+%if HAVE_AVX_EXTERNAL
+INIT_XMM avx
+PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
+PACK_6CH float, float, a, 2, 2, NOP_N, NOP_N
+
+PACK_6CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
+PACK_6CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
+PACK_6CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
+PACK_6CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
+
+INIT_YMM avx
+CONV float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
+CONV float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
+%endif
diff --git a/libswresample/x86/rematrix.asm b/libswresample/x86/rematrix.asm
new file mode 100644
index 0000000..d63545f
--- /dev/null
+++ b/libswresample/x86/rematrix.asm
@@ -0,0 +1,252 @@
+;******************************************************************************
+;* 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
+;******************************************************************************
+
+%include "libavutil/x86/x86inc.asm"
+%include "libavutil/x86/x86util.asm"
+
+
+SECTION_RODATA
+align 32
+dw1: times 8  dd 1
+w1 : times 16 dw 1
+
+SECTION .text
+
+%macro MIX2_FLT 1
+cglobal mix_2_1_%1_float, 7, 7, 6, out, in1, in2, coeffp, index1, index2, len
+%ifidn %1, a
+    test in1q, mmsize-1
+        jne mix_2_1_float_u_int %+ SUFFIX
+    test in2q, mmsize-1
+        jne mix_2_1_float_u_int %+ SUFFIX
+    test outq, mmsize-1
+        jne mix_2_1_float_u_int %+ SUFFIX
+%else
+mix_2_1_float_u_int %+ SUFFIX
+%endif
+    VBROADCASTSS m4, [coeffpq + 4*index1q]
+    VBROADCASTSS m5, [coeffpq + 4*index2q]
+    shl lend    , 2
+    add in1q    , lenq
+    add in2q    , lenq
+    add outq    , lenq
+    neg lenq
+.next:
+%ifidn %1, a
+    mulps        m0, m4, [in1q + lenq         ]
+    mulps        m1, m5, [in2q + lenq         ]
+    mulps        m2, m4, [in1q + lenq + mmsize]
+    mulps        m3, m5, [in2q + lenq + mmsize]
+%else
+    movu         m0, [in1q + lenq         ]
+    movu         m1, [in2q + lenq         ]
+    movu         m2, [in1q + lenq + mmsize]
+    movu         m3, [in2q + lenq + mmsize]
+    mulps        m0, m0, m4
+    mulps        m1, m1, m5
+    mulps        m2, m2, m4
+    mulps        m3, m3, m5
+%endif
+    addps        m0, m0, m1
+    addps        m2, m2, m3
+    mov%1  [outq + lenq         ], m0
+    mov%1  [outq + lenq + mmsize], m2
+    add        lenq, mmsize*2
+        jl .next
+    REP_RET
+%endmacro
+
+%macro MIX1_FLT 1
+cglobal mix_1_1_%1_float, 5, 5, 3, out, in, coeffp, index, len
+%ifidn %1, a
+    test inq, mmsize-1
+        jne mix_1_1_float_u_int %+ SUFFIX
+    test outq, mmsize-1
+        jne mix_1_1_float_u_int %+ SUFFIX
+%else
+mix_1_1_float_u_int %+ SUFFIX
+%endif
+    VBROADCASTSS m2, [coeffpq + 4*indexq]
+    shl lenq    , 2
+    add inq     , lenq
+    add outq    , lenq
+    neg lenq
+.next:
+%ifidn %1, a
+    mulps        m0, m2, [inq + lenq         ]
+    mulps        m1, m2, [inq + lenq + mmsize]
+%else
+    movu         m0, [inq + lenq         ]
+    movu         m1, [inq + lenq + mmsize]
+    mulps        m0, m0, m2
+    mulps        m1, m1, m2
+%endif
+    mov%1  [outq + lenq         ], m0
+    mov%1  [outq + lenq + mmsize], m1
+    add        lenq, mmsize*2
+        jl .next
+    REP_RET
+%endmacro
+
+%macro MIX1_INT16 1
+cglobal mix_1_1_%1_int16, 5, 5, 6, out, in, coeffp, index, len
+%ifidn %1, a
+    test inq, mmsize-1
+        jne mix_1_1_int16_u_int %+ SUFFIX
+    test outq, mmsize-1
+        jne mix_1_1_int16_u_int %+ SUFFIX
+%else
+mix_1_1_int16_u_int %+ SUFFIX
+%endif
+    movd   m4, [coeffpq + 4*indexq]
+    SPLATW m5, m4
+    psllq  m4, 32
+    psrlq  m4, 48
+    mova   m0, [w1]
+    psllw  m0, m4
+    psrlw  m0, 1
+    punpcklwd m5, m0
+    add lenq    , lenq
+    add inq     , lenq
+    add outq    , lenq
+    neg lenq
+.next:
+    mov%1        m0, [inq + lenq         ]
+    mov%1        m2, [inq + lenq + mmsize]
+    mova         m1, m0
+    mova         m3, m2
+    punpcklwd    m0, [w1]
+    punpckhwd    m1, [w1]
+    punpcklwd    m2, [w1]
+    punpckhwd    m3, [w1]
+    pmaddwd      m0, m5
+    pmaddwd      m1, m5
+    pmaddwd      m2, m5
+    pmaddwd      m3, m5
+    psrad        m0, m4
+    psrad        m1, m4
+    psrad        m2, m4
+    psrad        m3, m4
+    packssdw     m0, m1
+    packssdw     m2, m3
+    mov%1  [outq + lenq         ], m0
+    mov%1  [outq + lenq + mmsize], m2
+    add        lenq, mmsize*2
+        jl .next
+%if mmsize == 8
+    emms
+    RET
+%else
+    REP_RET
+%endif
+%endmacro
+
+%macro MIX2_INT16 1
+cglobal mix_2_1_%1_int16, 7, 7, 8, out, in1, in2, coeffp, index1, index2, len
+%ifidn %1, a
+    test in1q, mmsize-1
+        jne mix_2_1_int16_u_int %+ SUFFIX
+    test in2q, mmsize-1
+        jne mix_2_1_int16_u_int %+ SUFFIX
+    test outq, mmsize-1
+        jne mix_2_1_int16_u_int %+ SUFFIX
+%else
+mix_2_1_int16_u_int %+ SUFFIX
+%endif
+    movd   m4, [coeffpq + 4*index1q]
+    movd   m6, [coeffpq + 4*index2q]
+    SPLATW m5, m4
+    SPLATW m6, m6
+    psllq  m4, 32
+    psrlq  m4, 48
+    mova   m7, [dw1]
+    pslld  m7, m4
+    psrld  m7, 1
+    punpcklwd m5, m6
+    add lend    , lend
+    add in1q    , lenq
+    add in2q    , lenq
+    add outq    , lenq
+    neg lenq
+.next:
+    mov%1        m0, [in1q + lenq         ]
+    mov%1        m2, [in2q + lenq         ]
+    mova         m1, m0
+    punpcklwd    m0, m2
+    punpckhwd    m1, m2
+
+    mov%1        m2, [in1q + lenq + mmsize]
+    mov%1        m6, [in2q + lenq + mmsize]
+    mova         m3, m2
+    punpcklwd    m2, m6
+    punpckhwd    m3, m6
+
+    pmaddwd      m0, m5
+    pmaddwd      m1, m5
+    pmaddwd      m2, m5
+    pmaddwd      m3, m5
+    paddd        m0, m7
+    paddd        m1, m7
+    paddd        m2, m7
+    paddd        m3, m7
+    psrad        m0, m4
+    psrad        m1, m4
+    psrad        m2, m4
+    psrad        m3, m4
+    packssdw     m0, m1
+    packssdw     m2, m3
+    mov%1  [outq + lenq         ], m0
+    mov%1  [outq + lenq + mmsize], m2
+    add        lenq, mmsize*2
+        jl .next
+%if mmsize == 8
+    emms
+    RET
+%else
+    REP_RET
+%endif
+%endmacro
+
+
+INIT_MMX mmx
+MIX1_INT16 u
+MIX1_INT16 a
+MIX2_INT16 u
+MIX2_INT16 a
+
+INIT_XMM sse
+MIX2_FLT u
+MIX2_FLT a
+MIX1_FLT u
+MIX1_FLT a
+
+INIT_XMM sse2
+MIX1_INT16 u
+MIX1_INT16 a
+MIX2_INT16 u
+MIX2_INT16 a
+
+%if HAVE_AVX_EXTERNAL
+INIT_YMM avx
+MIX2_FLT u
+MIX2_FLT a
+MIX1_FLT u
+MIX1_FLT a
+%endif
diff --git a/libswresample/x86/resample_mmx.h b/libswresample/x86/resample_mmx.h
new file mode 100644
index 0000000..d96fd5a
--- /dev/null
+++ b/libswresample/x86/resample_mmx.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012 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/x86/asm.h"
+#include "libavutil/cpu.h"
+#include "libswresample/swresample_internal.h"
+
+int swri_resample_int16_mmx2 (struct ResampleContext *c, int16_t *dst, const int16_t *src, int *consumed, int src_size, int dst_size, int update_ctx);
+int swri_resample_int16_ssse3(struct ResampleContext *c, int16_t *dst, const int16_t *src, int *consumed, int src_size, int dst_size, int update_ctx);
+
+DECLARE_ALIGNED(16, const uint64_t, ff_resample_int16_rounder)[2]    = { 0x0000000000004000ULL, 0x0000000000000000ULL};
+
+#define COMMON_CORE_INT16_MMX2 \
+    x86_reg len= -2*c->filter_length;\
+__asm__ volatile(\
+    "movq "MANGLE(ff_resample_int16_rounder)", %%mm0 \n\t"\
+    "1:                         \n\t"\
+    "movq    (%1, %0), %%mm1    \n\t"\
+    "pmaddwd (%2, %0), %%mm1    \n\t"\
+    "paddd  %%mm1, %%mm0        \n\t"\
+    "add       $8, %0           \n\t"\
+    " js 1b                     \n\t"\
+    "pshufw $0x0E, %%mm0, %%mm1 \n\t"\
+    "paddd %%mm1, %%mm0         \n\t"\
+    "psrad    $15, %%mm0        \n\t"\
+    "packssdw %%mm0, %%mm0      \n\t"\
+    "movd %%mm0, (%3)           \n\t"\
+    : "+r" (len)\
+    : "r" (((uint8_t*)(src+sample_index))-len),\
+      "r" (((uint8_t*)filter)-len),\
+      "r" (dst+dst_index)\
+);
+
+#define COMMON_CORE_INT16_SSSE3 \
+    x86_reg len= -2*c->filter_length;\
+__asm__ volatile(\
+    "movdqa "MANGLE(ff_resample_int16_rounder)", %%xmm0 \n\t"\
+    "1:                           \n\t"\
+    "movdqu  (%1, %0), %%xmm1     \n\t"\
+    "pmaddwd (%2, %0), %%xmm1     \n\t"\
+    "paddd  %%xmm1, %%xmm0        \n\t"\
+    "add       $16, %0            \n\t"\
+    " js 1b                       \n\t"\
+    "phaddd %%xmm0, %%xmm0        \n\t"\
+    "phaddd %%xmm0, %%xmm0        \n\t"\
+    "psrad    $15, %%xmm0         \n\t"\
+    "packssdw %%xmm0, %%xmm0      \n\t"\
+    "movd %%xmm0, (%3)            \n\t"\
+    : "+r" (len)\
+    : "r" (((uint8_t*)(src+sample_index))-len),\
+      "r" (((uint8_t*)filter)-len),\
+      "r" (dst+dst_index)\
+);
diff --git a/libswresample/x86/swresample_x86.c b/libswresample/x86/swresample_x86.c
new file mode 100644
index 0000000..e18f0c5
--- /dev/null
+++ b/libswresample/x86/swresample_x86.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2012 Michael Niedermayer (michaelni@gmx.at)
+ *
+ * This file is part of libswresample
+ *
+ * libswresample 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.
+ *
+ * libswresample is distributed in the hope that 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 libswresample; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libswresample/swresample_internal.h"
+#include "libswresample/audioconvert.h"
+
+#define PROTO(pre, in, out, cap) void ff ## pre ## _ ##in## _to_ ##out## _a_ ##cap(uint8_t **dst, const uint8_t **src, int len);
+#define PROTO2(pre, out, cap) PROTO(pre, int16, out, cap) PROTO(pre, int32, out, cap) PROTO(pre, float, out, cap)
+#define PROTO3(pre, cap) PROTO2(pre, int16, cap) PROTO2(pre, int32, cap) PROTO2(pre, float, cap)
+#define PROTO4(pre) PROTO3(pre, mmx) PROTO3(pre, sse) PROTO3(pre, sse2) PROTO3(pre, ssse3) PROTO3(pre, sse4) PROTO3(pre, avx)
+PROTO4()
+PROTO4(_pack_2ch)
+PROTO4(_pack_6ch)
+PROTO4(_unpack_2ch)
+
+av_cold void swri_audio_convert_init_x86(struct AudioConvert *ac,
+                                 enum AVSampleFormat out_fmt,
+                                 enum AVSampleFormat in_fmt,
+                                 int channels){
+    int mm_flags = av_get_cpu_flags();
+
+    ac->simd_f= NULL;
+
+//FIXME add memcpy case
+
+#define MULTI_CAPS_FUNC(flag, cap) \
+    if (mm_flags & flag) {\
+        if(   out_fmt == AV_SAMPLE_FMT_S32  && in_fmt == AV_SAMPLE_FMT_S16 || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S16P)\
+            ac->simd_f =  ff_int16_to_int32_a_ ## cap;\
+        if(   out_fmt == AV_SAMPLE_FMT_S16  && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_S32P)\
+            ac->simd_f =  ff_int32_to_int16_a_ ## cap;\
+    }
+
+MULTI_CAPS_FUNC(AV_CPU_FLAG_MMX, mmx)
+MULTI_CAPS_FUNC(AV_CPU_FLAG_SSE2, sse2)
+
+    if(mm_flags & AV_CPU_FLAG_MMX) {
+        if(channels == 6) {
+            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)
+                ac->simd_f =  ff_pack_6ch_float_to_float_a_mmx;
+        }
+    }
+
+    if(mm_flags & AV_CPU_FLAG_SSE2) {
+        if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32P)
+            ac->simd_f =  ff_int32_to_float_a_sse2;
+        if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_S16 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S16P)
+            ac->simd_f =  ff_int16_to_float_a_sse2;
+        if(   out_fmt == AV_SAMPLE_FMT_S32  && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_FLTP)
+            ac->simd_f =  ff_float_to_int32_a_sse2;
+        if(   out_fmt == AV_SAMPLE_FMT_S16  && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S16P && in_fmt == AV_SAMPLE_FMT_FLTP)
+            ac->simd_f =  ff_float_to_int16_a_sse2;
+
+        if(channels == 2) {
+            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)
+                ac->simd_f =  ff_pack_2ch_int32_to_int32_a_sse2;
+            if(   out_fmt == AV_SAMPLE_FMT_S16  && in_fmt == AV_SAMPLE_FMT_S16P)
+                ac->simd_f =  ff_pack_2ch_int16_to_int16_a_sse2;
+            if(   out_fmt == AV_SAMPLE_FMT_S32  && in_fmt == AV_SAMPLE_FMT_S16P)
+                ac->simd_f =  ff_pack_2ch_int16_to_int32_a_sse2;
+            if(   out_fmt == AV_SAMPLE_FMT_S16  && in_fmt == AV_SAMPLE_FMT_S32P)
+                ac->simd_f =  ff_pack_2ch_int32_to_int16_a_sse2;
+
+            if(   out_fmt == AV_SAMPLE_FMT_FLTP  && in_fmt == AV_SAMPLE_FMT_FLT || out_fmt == AV_SAMPLE_FMT_S32P && in_fmt == AV_SAMPLE_FMT_S32)
+                ac->simd_f =  ff_unpack_2ch_int32_to_int32_a_sse2;
+            if(   out_fmt == AV_SAMPLE_FMT_S16P  && in_fmt == AV_SAMPLE_FMT_S16)
+                ac->simd_f =  ff_unpack_2ch_int16_to_int16_a_sse2;
+            if(   out_fmt == AV_SAMPLE_FMT_S32P  && in_fmt == AV_SAMPLE_FMT_S16)
+                ac->simd_f =  ff_unpack_2ch_int16_to_int32_a_sse2;
+            if(   out_fmt == AV_SAMPLE_FMT_S16P  && in_fmt == AV_SAMPLE_FMT_S32)
+                ac->simd_f =  ff_unpack_2ch_int32_to_int16_a_sse2;
+
+            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_S32P)
+                ac->simd_f =  ff_pack_2ch_int32_to_float_a_sse2;
+            if(   out_fmt == AV_SAMPLE_FMT_S32  && in_fmt == AV_SAMPLE_FMT_FLTP)
+                ac->simd_f =  ff_pack_2ch_float_to_int32_a_sse2;
+            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_S16P)
+                ac->simd_f =  ff_pack_2ch_int16_to_float_a_sse2;
+            if(   out_fmt == AV_SAMPLE_FMT_S16  && in_fmt == AV_SAMPLE_FMT_FLTP)
+                ac->simd_f =  ff_pack_2ch_float_to_int16_a_sse2;
+            if(   out_fmt == AV_SAMPLE_FMT_FLTP  && in_fmt == AV_SAMPLE_FMT_S32)
+                ac->simd_f =  ff_unpack_2ch_int32_to_float_a_sse2;
+            if(   out_fmt == AV_SAMPLE_FMT_S32P  && in_fmt == AV_SAMPLE_FMT_FLT)
+                ac->simd_f =  ff_unpack_2ch_float_to_int32_a_sse2;
+            if(   out_fmt == AV_SAMPLE_FMT_FLTP  && in_fmt == AV_SAMPLE_FMT_S16)
+                ac->simd_f =  ff_unpack_2ch_int16_to_float_a_sse2;
+            if(   out_fmt == AV_SAMPLE_FMT_S16P  && in_fmt == AV_SAMPLE_FMT_FLT)
+                ac->simd_f =  ff_unpack_2ch_float_to_int16_a_sse2;
+        }
+    }
+    if(mm_flags & AV_CPU_FLAG_SSSE3) {
+        if(channels == 2) {
+            if(   out_fmt == AV_SAMPLE_FMT_S16P  && in_fmt == AV_SAMPLE_FMT_S16)
+                ac->simd_f =  ff_unpack_2ch_int16_to_int16_a_ssse3;
+            if(   out_fmt == AV_SAMPLE_FMT_S32P  && in_fmt == AV_SAMPLE_FMT_S16)
+                ac->simd_f =  ff_unpack_2ch_int16_to_int32_a_ssse3;
+            if(   out_fmt == AV_SAMPLE_FMT_FLTP  && in_fmt == AV_SAMPLE_FMT_S16)
+                ac->simd_f =  ff_unpack_2ch_int16_to_float_a_ssse3;
+        }
+    }
+    if(mm_flags & AV_CPU_FLAG_SSE4) {
+        if(channels == 6) {
+            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)
+                ac->simd_f =  ff_pack_6ch_float_to_float_a_sse4;
+            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_S32P)
+                ac->simd_f =  ff_pack_6ch_int32_to_float_a_sse4;
+            if(   out_fmt == AV_SAMPLE_FMT_S32  && in_fmt == AV_SAMPLE_FMT_FLTP)
+                ac->simd_f =  ff_pack_6ch_float_to_int32_a_sse4;
+        }
+    }
+    if(HAVE_AVX_EXTERNAL && mm_flags & AV_CPU_FLAG_AVX) {
+        if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32P)
+            ac->simd_f =  ff_int32_to_float_a_avx;
+        if(channels == 6) {
+            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)
+                ac->simd_f =  ff_pack_6ch_float_to_float_a_avx;
+            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_S32P)
+                ac->simd_f =  ff_pack_6ch_int32_to_float_a_avx;
+            if(   out_fmt == AV_SAMPLE_FMT_S32  && in_fmt == AV_SAMPLE_FMT_FLTP)
+                ac->simd_f =  ff_pack_6ch_float_to_int32_a_avx;
+        }
+    }
+}
+
+#define D(type, simd) \
+mix_1_1_func_type ff_mix_1_1_a_## type ## _ ## simd;\
+mix_2_1_func_type ff_mix_2_1_a_## type ## _ ## simd;
+
+D(float, sse)
+D(float, avx)
+D(int16, mmx)
+D(int16, sse2)
+
+
+av_cold void swri_rematrix_init_x86(struct SwrContext *s){
+    int mm_flags = av_get_cpu_flags();
+    int nb_in  = av_get_channel_layout_nb_channels(s->in_ch_layout);
+    int nb_out = av_get_channel_layout_nb_channels(s->out_ch_layout);
+    int num    = nb_in * nb_out;
+    int i,j;
+
+    s->mix_1_1_simd = NULL;
+    s->mix_2_1_simd = NULL;
+
+    if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){
+        if(mm_flags & AV_CPU_FLAG_MMX) {
+            s->mix_1_1_simd = ff_mix_1_1_a_int16_mmx;
+            s->mix_2_1_simd = ff_mix_2_1_a_int16_mmx;
+        }
+        if(mm_flags & AV_CPU_FLAG_SSE2) {
+            s->mix_1_1_simd = ff_mix_1_1_a_int16_sse2;
+            s->mix_2_1_simd = ff_mix_2_1_a_int16_sse2;
+        }
+        s->native_simd_matrix = av_mallocz(2 * num * sizeof(int16_t));
+        for(i=0; i<nb_out; i++){
+            int sh = 0;
+            for(j=0; j<nb_in; j++)
+                sh = FFMAX(sh, FFABS(((int*)s->native_matrix)[i * nb_in + j]));
+            sh = FFMAX(av_log2(sh) - 14, 0);
+            for(j=0; j<nb_in; j++) {
+                ((int16_t*)s->native_simd_matrix)[2*(i * nb_in + j)+1] = 15 - sh;
+                ((int16_t*)s->native_simd_matrix)[2*(i * nb_in + j)] =
+                    ((((int*)s->native_matrix)[i * nb_in + j]) + (1<<sh>>1)) >> sh;
+            }
+        }
+    } else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){
+        if(mm_flags & AV_CPU_FLAG_SSE) {
+            s->mix_1_1_simd = ff_mix_1_1_a_float_sse;
+            s->mix_2_1_simd = ff_mix_2_1_a_float_sse;
+        }
+        if(HAVE_AVX_EXTERNAL && mm_flags & AV_CPU_FLAG_AVX) {
+            s->mix_1_1_simd = ff_mix_1_1_a_float_avx;
+            s->mix_2_1_simd = ff_mix_2_1_a_float_avx;
+        }
+        s->native_simd_matrix = av_mallocz(num * sizeof(float));
+        memcpy(s->native_simd_matrix, s->native_matrix, num * sizeof(float));
+    }
+}
diff --git a/libswscale/Makefile b/libswscale/Makefile
index 0799b45..dd00f7d 100644
--- a/libswscale/Makefile
+++ b/libswscale/Makefile
@@ -1,3 +1,5 @@
+include $(SUBDIR)../config.mak
+
 NAME = swscale
 FFLIBS = avutil
 
diff --git a/libswscale/bfin/internal_bfin.S b/libswscale/bfin/internal_bfin.S
index b007f07..eab30aa 100644
--- a/libswscale/bfin/internal_bfin.S
+++ b/libswscale/bfin/internal_bfin.S
@@ -5,20 +5,20 @@
  * Blackfin video color space converter operations
  * convert I420 YV12 to RGB in various formats
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libswscale/bfin/swscale_bfin.c b/libswscale/bfin/swscale_bfin.c
index 9d0bbe3..2b93858 100644
--- a/libswscale/bfin/swscale_bfin.c
+++ b/libswscale/bfin/swscale_bfin.c
@@ -3,20 +3,20 @@
  *
  * Blackfin software video scaler operations
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libswscale/bfin/yuv2rgb_bfin.c b/libswscale/bfin/yuv2rgb_bfin.c
index 5b74c7a..e1b7afa 100644
--- a/libswscale/bfin/yuv2rgb_bfin.c
+++ b/libswscale/bfin/yuv2rgb_bfin.c
@@ -4,23 +4,24 @@
  * Blackfin video color space converter operations
  * convert I420 YV12 to RGB in various formats
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/pixdesc.h"
 #include <stdint.h>
 
 #include "config.h"
@@ -195,7 +196,7 @@
     }
 
     av_log(c, AV_LOG_INFO, "BlackFin accelerated color space converter %s\n",
-           sws_format_name(c->dstFormat));
+           av_get_pix_fmt_name(c->dstFormat));
 
     return f;
 }
diff --git a/libswscale/colorspace-test.c b/libswscale/colorspace-test.c
index fbf595d..42a915b 100644
--- a/libswscale/colorspace-test.c
+++ b/libswscale/colorspace-test.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -33,7 +33,7 @@
 
 #define FUNC(s, d, n) { s, d, #n, n }
 
-int main(void)
+int main(int argc, char **argv)
 {
     int i, funcNum;
     uint8_t *srcBuffer = av_malloc(SIZE);
@@ -54,6 +54,7 @@
             const char *name;
             void (*func)(const uint8_t *src, uint8_t *dst, int src_size);
         } func_info[] = {
+            FUNC(2, 2, rgb12to15),
             FUNC(2, 2, rgb15to16),
             FUNC(2, 3, rgb15to24),
             FUNC(2, 4, rgb15to32),
@@ -66,6 +67,7 @@
             FUNC(4, 2, rgb32to16),
             FUNC(4, 3, rgb32to24),
             FUNC(2, 2, rgb16to15),
+            FUNC(2, 2, rgb12tobgr12),
             FUNC(2, 2, rgb15tobgr15),
             FUNC(2, 2, rgb15tobgr16),
             FUNC(2, 3, rgb15tobgr24),
@@ -82,6 +84,12 @@
             FUNC(4, 2, rgb32tobgr16),
             FUNC(4, 3, rgb32tobgr24),
             FUNC(4, 4, shuffle_bytes_2103), /* rgb32tobgr32 */
+            FUNC(6, 6, rgb48tobgr48_nobswap),
+            FUNC(6, 6, rgb48tobgr48_bswap),
+            FUNC(8, 6, rgb64to48_nobswap),
+            FUNC(8, 6, rgb64to48_bswap),
+            FUNC(8, 6, rgb64tobgr48_nobswap),
+            FUNC(8, 6, rgb64tobgr48_bswap),
             FUNC(0, 0, NULL)
         };
         int width;
diff --git a/libswscale/input.c b/libswscale/input.c
index 142cc29..6d76068 100644
--- a/libswscale/input.c
+++ b/libswscale/input.c
@@ -1,20 +1,20 @@
 /*
- * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2001-2012 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -30,6 +30,7 @@
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/avassert.h"
 #include "config.h"
 #include "rgb2rgb.h"
 #include "swscale.h"
@@ -51,6 +52,86 @@
 #define r ((origin == AV_PIX_FMT_BGR48BE || origin == AV_PIX_FMT_BGR48LE) ? b_r : r_b)
 #define b ((origin == AV_PIX_FMT_BGR48BE || origin == AV_PIX_FMT_BGR48LE) ? r_b : b_r)
 
+static av_always_inline void
+rgb64ToY_c_template(uint16_t *dst, const uint16_t *src, int width,
+                    enum AVPixelFormat origin)
+{
+    int i;
+    for (i = 0; i < width; i++) {
+        unsigned int r_b = input_pixel(&src[i*4+0]);
+        unsigned int   g = input_pixel(&src[i*4+1]);
+        unsigned int b_r = input_pixel(&src[i*4+2]);
+
+        dst[i] = (RY*r + GY*g + BY*b + (0x2001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
+    }
+}
+
+static av_always_inline void
+rgb64ToUV_c_template(uint16_t *dstU, uint16_t *dstV,
+                    const uint16_t *src1, const uint16_t *src2,
+                    int width, enum AVPixelFormat origin)
+{
+    int i;
+    av_assert1(src1==src2);
+    for (i = 0; i < width; i++) {
+        int r_b = input_pixel(&src1[i*4+0]);
+        int   g = input_pixel(&src1[i*4+1]);
+        int b_r = input_pixel(&src1[i*4+2]);
+
+        dstU[i] = (RU*r + GU*g + BU*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
+        dstV[i] = (RV*r + GV*g + BV*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
+    }
+}
+
+static av_always_inline void
+rgb64ToUV_half_c_template(uint16_t *dstU, uint16_t *dstV,
+                          const uint16_t *src1, const uint16_t *src2,
+                          int width, enum AVPixelFormat origin)
+{
+    int i;
+    av_assert1(src1==src2);
+    for (i = 0; i < width; i++) {
+        int r_b = (input_pixel(&src1[8 * i + 0]) + input_pixel(&src1[8 * i + 4]) + 1) >> 1;
+        int   g = (input_pixel(&src1[8 * i + 1]) + input_pixel(&src1[8 * i + 5]) + 1) >> 1;
+        int b_r = (input_pixel(&src1[8 * i + 2]) + input_pixel(&src1[8 * i + 6]) + 1) >> 1;
+
+        dstU[i]= (RU*r + GU*g + BU*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
+        dstV[i]= (RV*r + GV*g + BV*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
+    }
+}
+
+#define rgb64funcs(pattern, BE_LE, origin) \
+static void pattern ## 64 ## BE_LE ## ToY_c(uint8_t *_dst, const uint8_t *_src, const uint8_t *unused0, const uint8_t *unused1,\
+                                    int width, uint32_t *unused) \
+{ \
+    const uint16_t *src = (const uint16_t *) _src; \
+    uint16_t *dst = (uint16_t *) _dst; \
+    rgb64ToY_c_template(dst, src, width, origin); \
+} \
+ \
+static void pattern ## 64 ## BE_LE ## ToUV_c(uint8_t *_dstU, uint8_t *_dstV, \
+                                    const uint8_t *unused0, const uint8_t *_src1, const uint8_t *_src2, \
+                                    int width, uint32_t *unused) \
+{ \
+    const uint16_t *src1 = (const uint16_t *) _src1, \
+                   *src2 = (const uint16_t *) _src2; \
+    uint16_t *dstU = (uint16_t *) _dstU, *dstV = (uint16_t *) _dstV; \
+    rgb64ToUV_c_template(dstU, dstV, src1, src2, width, origin); \
+} \
+ \
+static void pattern ## 64 ## BE_LE ## ToUV_half_c(uint8_t *_dstU, uint8_t *_dstV, \
+                                    const uint8_t *unused0, const uint8_t *_src1, const uint8_t *_src2, \
+                                    int width, uint32_t *unused) \
+{ \
+    const uint16_t *src1 = (const uint16_t *) _src1, \
+                   *src2 = (const uint16_t *) _src2; \
+    uint16_t *dstU = (uint16_t *) _dstU, *dstV = (uint16_t *) _dstV; \
+    rgb64ToUV_half_c_template(dstU, dstV, src1, src2, width, origin); \
+}
+
+rgb64funcs(rgb, LE, AV_PIX_FMT_RGBA64LE)
+rgb64funcs(rgb, BE, AV_PIX_FMT_RGBA64BE)
+
 static av_always_inline void rgb48ToY_c_template(uint16_t *dst,
                                                  const uint16_t *src, int width,
                                                  enum AVPixelFormat origin)
@@ -73,7 +154,7 @@
                                                   enum AVPixelFormat origin)
 {
     int i;
-    assert(src1 == src2);
+    av_assert1(src1 == src2);
     for (i = 0; i < width; i++) {
         int r_b = input_pixel(&src1[i * 3 + 0]);
         int g   = input_pixel(&src1[i * 3 + 1]);
@@ -92,7 +173,7 @@
                                                        enum AVPixelFormat origin)
 {
     int i;
-    assert(src1 == src2);
+    av_assert1(src1 == src2);
     for (i = 0; i < width; i++) {
         int r_b = (input_pixel(&src1[6 * i + 0]) +
                    input_pixel(&src1[6 * i + 3]) + 1) >> 1;
@@ -113,6 +194,7 @@
 #define rgb48funcs(pattern, BE_LE, origin)                              \
 static void pattern ## 48 ## BE_LE ## ToY_c(uint8_t *_dst,              \
                                             const uint8_t *_src,        \
+                                            const uint8_t *unused0, const uint8_t *unused1,\
                                             int width,                  \
                                             uint32_t *unused)           \
 {                                                                       \
@@ -123,6 +205,7 @@
                                                                         \
 static void pattern ## 48 ## BE_LE ## ToUV_c(uint8_t *_dstU,            \
                                              uint8_t *_dstV,            \
+                                             const uint8_t *unused0,    \
                                              const uint8_t *_src1,      \
                                              const uint8_t *_src2,      \
                                              int width,                 \
@@ -137,6 +220,7 @@
                                                                         \
 static void pattern ## 48 ## BE_LE ## ToUV_half_c(uint8_t *_dstU,       \
                                                   uint8_t *_dstV,       \
+                                                  const uint8_t *unused0,    \
                                                   const uint8_t *_src1, \
                                                   const uint8_t *_src2, \
                                                   int width,            \
@@ -162,7 +246,7 @@
                         : (isBE(origin) ? AV_RB16(&src[(i) * 2])        \
                                         : AV_RL16(&src[(i) * 2])))
 
-static av_always_inline void rgb16_32ToY_c_template(uint8_t *dst,
+static av_always_inline void rgb16_32ToY_c_template(int16_t *dst,
                                                     const uint8_t *src,
                                                     int width,
                                                     enum AVPixelFormat origin,
@@ -173,7 +257,7 @@
                                                     int gsh, int bsh, int S)
 {
     const int ry       = RY << rsh, gy = GY << gsh, by = BY << bsh;
-    const unsigned rnd = 33u << (S - 1);
+    const unsigned rnd = (32<<((S)-1)) + (1<<(S-7));
     int i;
 
     for (i = 0; i < width; i++) {
@@ -182,12 +266,12 @@
         int g  = (px & maskg) >> shg;
         int r  = (px & maskr) >> shr;
 
-        dst[i] = (ry * r + gy * g + by * b + rnd) >> S;
+        dst[i] = (ry * r + gy * g + by * b + rnd) >> ((S)-6);
     }
 }
 
-static av_always_inline void rgb16_32ToUV_c_template(uint8_t *dstU,
-                                                     uint8_t *dstV,
+static av_always_inline void rgb16_32ToUV_c_template(int16_t *dstU,
+                                                     int16_t *dstV,
                                                      const uint8_t *src,
                                                      int width,
                                                      enum AVPixelFormat origin,
@@ -199,7 +283,7 @@
 {
     const int ru       = RU << rsh, gu = GU << gsh, bu = BU << bsh,
               rv       = RV << rsh, gv = GV << gsh, bv = BV << bsh;
-    const unsigned rnd = 257u << (S - 1);
+    const unsigned rnd = (256u<<((S)-1)) + (1<<(S-7));
     int i;
 
     for (i = 0; i < width; i++) {
@@ -208,13 +292,13 @@
         int g  = (px & maskg)   >> shg;
         int r  = (px & maskr)   >> shr;
 
-        dstU[i] = (ru * r + gu * g + bu * b + rnd) >> S;
-        dstV[i] = (rv * r + gv * g + bv * b + rnd) >> S;
+        dstU[i] = (ru * r + gu * g + bu * b + rnd) >> ((S)-6);
+        dstV[i] = (rv * r + gv * g + bv * b + rnd) >> ((S)-6);
     }
 }
 
-static av_always_inline void rgb16_32ToUV_half_c_template(uint8_t *dstU,
-                                                          uint8_t *dstV,
+static av_always_inline void rgb16_32ToUV_half_c_template(int16_t *dstU,
+                                                          int16_t *dstV,
                                                           const uint8_t *src,
                                                           int width,
                                                           enum AVPixelFormat origin,
@@ -227,7 +311,7 @@
     const int ru       = RU << rsh, gu = GU << gsh, bu = BU << bsh,
               rv       = RV << rsh, gv = GV << gsh, bv = BV << bsh,
               maskgx   = ~(maskr | maskb);
-    const unsigned rnd = 257u << S;
+    const unsigned rnd = (256U<<(S)) + (1<<(S-6));
     int i;
 
     maskr |= maskr << 1;
@@ -249,8 +333,8 @@
         }
         r = (rb & maskr) >> shr;
 
-        dstU[i] = (ru * r + gu * g + bu * b + rnd) >> (S + 1);
-        dstV[i] = (rv * r + gv * g + bv * b + rnd) >> (S + 1);
+        dstU[i] = (ru * r + gu * g + bu * b + (unsigned)rnd) >> ((S)-6+1);
+        dstV[i] = (rv * r + gv * g + bv * b + (unsigned)rnd) >> ((S)-6+1);
     }
 }
 
@@ -258,28 +342,28 @@
 
 #define rgb16_32_wrapper(fmt, name, shr, shg, shb, shp, maskr,          \
                          maskg, maskb, rsh, gsh, bsh, S)                \
-static void name ## ToY_c(uint8_t *dst, const uint8_t *src,             \
+static void name ## ToY_c(uint8_t *dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2,            \
                           int width, uint32_t *unused)                  \
 {                                                                       \
-    rgb16_32ToY_c_template(dst, src, width, fmt, shr, shg, shb, shp,    \
+    rgb16_32ToY_c_template((int16_t*)dst, src, width, fmt, shr, shg, shb, shp,    \
                            maskr, maskg, maskb, rsh, gsh, bsh, S);      \
 }                                                                       \
                                                                         \
 static void name ## ToUV_c(uint8_t *dstU, uint8_t *dstV,                \
-                           const uint8_t *src, const uint8_t *dummy,    \
+                           const uint8_t *unused0, const uint8_t *src, const uint8_t *dummy,    \
                            int width, uint32_t *unused)                 \
 {                                                                       \
-    rgb16_32ToUV_c_template(dstU, dstV, src, width, fmt,                \
+    rgb16_32ToUV_c_template((int16_t*)dstU, (int16_t*)dstV, src, width, fmt,                \
                             shr, shg, shb, shp,                         \
                             maskr, maskg, maskb, rsh, gsh, bsh, S);     \
 }                                                                       \
                                                                         \
 static void name ## ToUV_half_c(uint8_t *dstU, uint8_t *dstV,           \
-                                const uint8_t *src,                     \
+                                const uint8_t *unused0, const uint8_t *src,                     \
                                 const uint8_t *dummy,                   \
                                 int width, uint32_t *unused)            \
 {                                                                       \
-    rgb16_32ToUV_half_c_template(dstU, dstV, src, width, fmt,           \
+    rgb16_32ToUV_half_c_template((int16_t*)dstU, (int16_t*)dstV, src, width, fmt,           \
                                  shr, shg, shb, shp,                    \
                                  maskr, maskg, maskb,                   \
                                  rsh, gsh, bsh, S);                     \
@@ -302,71 +386,124 @@
 rgb16_32_wrapper(AV_PIX_FMT_RGB555BE, rgb15be, 0, 0,  0, 0,   0x7C00, 0x03E0,   0x001F,  0, 5, 10, RGB2YUV_SHIFT + 7)
 rgb16_32_wrapper(AV_PIX_FMT_RGB444BE, rgb12be, 0, 0,  0, 0,   0x0F00, 0x00F0,   0x000F,  0, 4,  8, RGB2YUV_SHIFT + 4)
 
-static void abgrToA_c(uint8_t *dst, const uint8_t *src, int width,
-                      uint32_t *unused)
+static void gbr24pToUV_half_c(uint8_t *_dstU, uint8_t *_dstV,
+                         const uint8_t *gsrc, const uint8_t *bsrc, const uint8_t *rsrc,
+                         int width, uint32_t *unused)
 {
+    uint16_t *dstU = (uint16_t *)_dstU;
+    uint16_t *dstV = (uint16_t *)_dstV;
     int i;
-    for (i = 0; i < width; i++)
-        dst[i] = src[4 * i];
+    for (i = 0; i < width; i++) {
+        unsigned int g   = gsrc[2*i] + gsrc[2*i+1];
+        unsigned int b   = bsrc[2*i] + bsrc[2*i+1];
+        unsigned int r   = rsrc[2*i] + rsrc[2*i+1];
+
+        dstU[i] = (RU*r + GU*g + BU*b + (0x4001<<(RGB2YUV_SHIFT-6))) >> (RGB2YUV_SHIFT-6+1);
+        dstV[i] = (RV*r + GV*g + BV*b + (0x4001<<(RGB2YUV_SHIFT-6))) >> (RGB2YUV_SHIFT-6+1);
+    }
 }
 
-static void rgbaToA_c(uint8_t *dst, const uint8_t *src, int width,
-                      uint32_t *unused)
+static void rgba64ToA_c(uint8_t *_dst, const uint8_t *_src, const uint8_t *unused1,
+                        const uint8_t *unused2, int width, uint32_t *unused)
 {
+    int16_t *dst = (int16_t *)_dst;
+    const uint16_t *src = (const uint16_t *)_src;
     int i;
     for (i = 0; i < width; i++)
         dst[i] = src[4 * i + 3];
 }
 
-static void palToY_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *pal)
+static void abgrToA_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2, int width, uint32_t *unused)
 {
+    int16_t *dst = (int16_t *)_dst;
+    int i;
+    for (i=0; i<width; i++) {
+        dst[i]= src[4*i]<<6;
+    }
+}
+
+static void rgbaToA_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2, int width, uint32_t *unused)
+{
+    int16_t *dst = (int16_t *)_dst;
+    int i;
+    for (i=0; i<width; i++) {
+        dst[i]= src[4*i+3]<<6;
+    }
+}
+
+static void palToA_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2, int width, uint32_t *pal)
+{
+    int16_t *dst = (int16_t *)_dst;
+    int i;
+    for (i=0; i<width; i++) {
+        int d= src[i];
+
+        dst[i]= (pal[d] >> 24)<<6;
+    }
+}
+
+static void palToY_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2, int width, uint32_t *pal)
+{
+    int16_t *dst = (int16_t *)_dst;
     int i;
     for (i = 0; i < width; i++) {
         int d = src[i];
 
-        dst[i] = pal[d] & 0xFF;
+        dst[i] = (pal[d] & 0xFF)<<6;
     }
 }
 
-static void palToUV_c(uint8_t *dstU, uint8_t *dstV,
-                      const uint8_t *src1, const uint8_t *src2,
+static void palToUV_c(uint8_t *_dstU, uint8_t *_dstV,
+                           const uint8_t *unused0, const uint8_t *src1, const uint8_t *src2,
                       int width, uint32_t *pal)
 {
+    uint16_t *dstU = (uint16_t *)_dstU;
+    int16_t *dstV = (int16_t *)_dstV;
     int i;
-    assert(src1 == src2);
+    av_assert1(src1 == src2);
     for (i = 0; i < width; i++) {
         int p = pal[src1[i]];
 
-        dstU[i] = p >> 8;
-        dstV[i] = p >> 16;
+        dstU[i] = (uint8_t)(p>> 8)<<6;
+        dstV[i] = (uint8_t)(p>>16)<<6;
     }
 }
 
-static void monowhite2Y_c(uint8_t *dst, const uint8_t *src,
-                          int width, uint32_t *unused)
+static void monowhite2Y_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2,  int width, uint32_t *unused)
 {
+    int16_t *dst = (int16_t *)_dst;
     int i, j;
     width = (width + 7) >> 3;
     for (i = 0; i < width; i++) {
         int d = ~src[i];
         for (j = 0; j < 8; j++)
-            dst[8 * i + j] = ((d >> (7 - j)) & 1) * 255;
+            dst[8*i+j]= ((d>>(7-j))&1) * 16383;
+    }
+    if(width&7){
+        int d= ~src[i];
+        for (j = 0; j < (width&7); j++)
+            dst[8*i+j]= ((d>>(7-j))&1) * 16383;
     }
 }
 
-static void monoblack2Y_c(uint8_t *dst, const uint8_t *src,
-                          int width, uint32_t *unused)
+static void monoblack2Y_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2,  int width, uint32_t *unused)
 {
+    int16_t *dst = (int16_t *)_dst;
     int i, j;
     width = (width + 7) >> 3;
     for (i = 0; i < width; i++) {
         int d = src[i];
         for (j = 0; j < 8; j++)
-            dst[8 * i + j] = ((d >> (7 - j)) & 1) * 255;
+            dst[8*i+j]= ((d>>(7-j))&1) * 16383;
+    }
+    if(width&7){
+        int d = src[i];
+        for (j = 0; j < (width&7); j++)
+            dst[8*i+j] = ((d>>(7-j))&1) * 16383;
     }
 }
 
-static void yuy2ToY_c(uint8_t *dst, const uint8_t *src, int width,
+static void yuy2ToY_c(uint8_t *dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2,  int width,
                       uint32_t *unused)
 {
     int i;
@@ -374,7 +511,7 @@
         dst[i] = src[2 * i];
 }
 
-static void yuy2ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
+static void yuy2ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *unused0, const uint8_t *src1,
                        const uint8_t *src2, int width, uint32_t *unused)
 {
     int i;
@@ -382,10 +519,10 @@
         dstU[i] = src1[4 * i + 1];
         dstV[i] = src1[4 * i + 3];
     }
-    assert(src1 == src2);
+    av_assert1(src1 == src2);
 }
 
-static void bswap16Y_c(uint8_t *_dst, const uint8_t *_src, int width,
+static void bswap16Y_c(uint8_t *_dst, const uint8_t *_src, const uint8_t *unused1, const uint8_t *unused2,  int width,
                        uint32_t *unused)
 {
     int i;
@@ -395,7 +532,7 @@
         dst[i] = av_bswap16(src[i]);
 }
 
-static void bswap16UV_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *_src1,
+static void bswap16UV_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *unused0, const uint8_t *_src1,
                         const uint8_t *_src2, int width, uint32_t *unused)
 {
     int i;
@@ -410,7 +547,7 @@
 
 /* This is almost identical to the previous, end exists only because
  * yuy2ToY/UV)(dst, src + 1, ...) would have 100% unaligned accesses. */
-static void uyvyToY_c(uint8_t *dst, const uint8_t *src, int width,
+static void uyvyToY_c(uint8_t *dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2,  int width,
                       uint32_t *unused)
 {
     int i;
@@ -418,7 +555,7 @@
         dst[i] = src[2 * i + 1];
 }
 
-static void uyvyToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
+static void uyvyToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *unused0, const uint8_t *src1,
                        const uint8_t *src2, int width, uint32_t *unused)
 {
     int i;
@@ -426,7 +563,7 @@
         dstU[i] = src1[4 * i + 0];
         dstV[i] = src1[4 * i + 2];
     }
-    assert(src1 == src2);
+    av_assert1(src1 == src2);
 }
 
 static av_always_inline void nvXXtoUV_c(uint8_t *dst1, uint8_t *dst2,
@@ -440,14 +577,14 @@
 }
 
 static void nv12ToUV_c(uint8_t *dstU, uint8_t *dstV,
-                       const uint8_t *src1, const uint8_t *src2,
+                       const uint8_t *unused0, const uint8_t *src1, const uint8_t *src2,
                        int width, uint32_t *unused)
 {
     nvXXtoUV_c(dstU, dstV, src1, width);
 }
 
 static void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV,
-                       const uint8_t *src1, const uint8_t *src2,
+                       const uint8_t *unused0, const uint8_t *src1, const uint8_t *src2,
                        int width, uint32_t *unused)
 {
     nvXXtoUV_c(dstV, dstU, src1, width);
@@ -455,114 +592,127 @@
 
 #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
 
-static void bgr24ToY_c(uint8_t *dst, const uint8_t *src,
+static void bgr24ToY_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2,
                        int width, uint32_t *unused)
 {
+    int16_t *dst = (int16_t *)_dst;
     int i;
     for (i = 0; i < width; i++) {
         int b = src[i * 3 + 0];
         int g = src[i * 3 + 1];
         int r = src[i * 3 + 2];
 
-        dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
+        dst[i] = ((RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6));
     }
 }
 
-static void bgr24ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
+static void bgr24ToUV_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *unused0, const uint8_t *src1,
                         const uint8_t *src2, int width, uint32_t *unused)
 {
+    int16_t *dstU = (int16_t *)_dstU;
+    int16_t *dstV = (int16_t *)_dstV;
     int i;
     for (i = 0; i < width; i++) {
         int b = src1[3 * i + 0];
         int g = src1[3 * i + 1];
         int r = src1[3 * i + 2];
 
-        dstU[i] = (RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
-        dstV[i] = (RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
+        dstU[i] = (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
+        dstV[i] = (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
     }
-    assert(src1 == src2);
+    av_assert1(src1 == src2);
 }
 
-static void bgr24ToUV_half_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
+static void bgr24ToUV_half_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *unused0, const uint8_t *src1,
                              const uint8_t *src2, int width, uint32_t *unused)
 {
+    int16_t *dstU = (int16_t *)_dstU;
+    int16_t *dstV = (int16_t *)_dstV;
     int i;
     for (i = 0; i < width; i++) {
         int b = src1[6 * i + 0] + src1[6 * i + 3];
         int g = src1[6 * i + 1] + src1[6 * i + 4];
         int r = src1[6 * i + 2] + src1[6 * i + 5];
 
-        dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
-        dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
+        dstU[i] = (RU*r + GU*g + BU*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
+        dstV[i] = (RV*r + GV*g + BV*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
     }
-    assert(src1 == src2);
+    av_assert1(src1 == src2);
 }
 
-static void rgb24ToY_c(uint8_t *dst, const uint8_t *src, int width,
+static void rgb24ToY_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2, int width,
                        uint32_t *unused)
 {
+    int16_t *dst = (int16_t *)_dst;
     int i;
     for (i = 0; i < width; i++) {
         int r = src[i * 3 + 0];
         int g = src[i * 3 + 1];
         int b = src[i * 3 + 2];
 
-        dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
+        dst[i] = ((RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6));
     }
 }
 
-static void rgb24ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
+static void rgb24ToUV_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *unused0, const uint8_t *src1,
                         const uint8_t *src2, int width, uint32_t *unused)
 {
+    int16_t *dstU = (int16_t *)_dstU;
+    int16_t *dstV = (int16_t *)_dstV;
     int i;
-    assert(src1 == src2);
+    av_assert1(src1 == src2);
     for (i = 0; i < width; i++) {
         int r = src1[3 * i + 0];
         int g = src1[3 * i + 1];
         int b = src1[3 * i + 2];
 
-        dstU[i] = (RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
-        dstV[i] = (RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
+        dstU[i] = (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
+        dstV[i] = (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1)) + (1<<(RGB2YUV_SHIFT-7)))>>(RGB2YUV_SHIFT-6);
     }
 }
 
-static void rgb24ToUV_half_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1,
+static void rgb24ToUV_half_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *unused0, const uint8_t *src1,
                              const uint8_t *src2, int width, uint32_t *unused)
 {
+    int16_t *dstU = (int16_t *)_dstU;
+    int16_t *dstV = (int16_t *)_dstV;
     int i;
-    assert(src1 == src2);
+    av_assert1(src1 == src2);
     for (i = 0; i < width; i++) {
         int r = src1[6 * i + 0] + src1[6 * i + 3];
         int g = src1[6 * i + 1] + src1[6 * i + 4];
         int b = src1[6 * i + 2] + src1[6 * i + 5];
 
-        dstU[i] = (RU * r + GU * g + BU * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
-        dstV[i] = (RV * r + GV * g + BV * b + (257 << RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT + 1);
+        dstU[i] = (RU*r + GU*g + BU*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
+        dstV[i] = (RV*r + GV*g + BV*b + (256<<RGB2YUV_SHIFT) + (1<<(RGB2YUV_SHIFT-6)))>>(RGB2YUV_SHIFT-5);
     }
 }
 
-static void planar_rgb_to_y(uint8_t *dst, const uint8_t *src[4], int width)
+static void planar_rgb_to_y(uint8_t *_dst, const uint8_t *src[4], int width)
 {
+    uint16_t *dst = (uint16_t *)_dst;
     int i;
     for (i = 0; i < width; i++) {
         int g = src[0][i];
         int b = src[1][i];
         int r = src[2][i];
 
-        dst[i] = ((RY * r + GY * g + BY * b + (33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
+        dst[i] = (RY*r + GY*g + BY*b + (0x801<<(RGB2YUV_SHIFT-7))) >> (RGB2YUV_SHIFT-6);
     }
 }
 
-static void planar_rgb_to_uv(uint8_t *dstU, uint8_t *dstV, const uint8_t *src[4], int width)
+static void planar_rgb_to_uv(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *src[4], int width)
 {
+    uint16_t *dstU = (uint16_t *)_dstU;
+    uint16_t *dstV = (uint16_t *)_dstV;
     int i;
     for (i = 0; i < width; i++) {
         int g = src[0][i];
         int b = src[1][i];
         int r = src[2][i];
 
-        dstU[i] = (RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
-        dstV[i] = (RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT;
+        dstU[i] = (RU*r + GU*g + BU*b + (0x4001<<(RGB2YUV_SHIFT-7))) >> (RGB2YUV_SHIFT-6);
+        dstV[i] = (RV*r + GV*g + BV*b + (0x4001<<(RGB2YUV_SHIFT-7))) >> (RGB2YUV_SHIFT-6);
     }
 }
 
@@ -603,6 +753,26 @@
     planar_rgb16_to_y(dst, src, w, 10, 1);
 }
 
+static void planar_rgb12le_to_y(uint8_t *dst, const uint8_t *src[4], int w)
+{
+    planar_rgb16_to_y(dst, src, w, 12, 0);
+}
+
+static void planar_rgb12be_to_y(uint8_t *dst, const uint8_t *src[4], int w)
+{
+    planar_rgb16_to_y(dst, src, w, 12, 1);
+}
+
+static void planar_rgb14le_to_y(uint8_t *dst, const uint8_t *src[4], int w)
+{
+    planar_rgb16_to_y(dst, src, w, 14, 0);
+}
+
+static void planar_rgb14be_to_y(uint8_t *dst, const uint8_t *src[4], int w)
+{
+    planar_rgb16_to_y(dst, src, w, 14, 1);
+}
+
 static void planar_rgb16le_to_y(uint8_t *dst, const uint8_t *src[4], int w)
 {
     planar_rgb16_to_y(dst, src, w, 16, 0);
@@ -656,6 +826,30 @@
     planar_rgb16_to_uv(dstU, dstV, src, w, 10, 1);
 }
 
+static void planar_rgb12le_to_uv(uint8_t *dstU, uint8_t *dstV,
+                                 const uint8_t *src[4], int w)
+{
+    planar_rgb16_to_uv(dstU, dstV, src, w, 12, 0);
+}
+
+static void planar_rgb12be_to_uv(uint8_t *dstU, uint8_t *dstV,
+                                 const uint8_t *src[4], int w)
+{
+    planar_rgb16_to_uv(dstU, dstV, src, w, 12, 1);
+}
+
+static void planar_rgb14le_to_uv(uint8_t *dstU, uint8_t *dstV,
+                                 const uint8_t *src[4], int w)
+{
+    planar_rgb16_to_uv(dstU, dstV, src, w, 14, 0);
+}
+
+static void planar_rgb14be_to_uv(uint8_t *dstU, uint8_t *dstV,
+                                 const uint8_t *src[4], int w)
+{
+    planar_rgb16_to_uv(dstU, dstV, src, w, 14, 1);
+}
+
 static void planar_rgb16le_to_uv(uint8_t *dstU, uint8_t *dstV,
                                  const uint8_t *src[4], int w)
 {
@@ -699,6 +893,12 @@
     case AV_PIX_FMT_GBRP10LE:
         c->readChrPlanar = planar_rgb10le_to_uv;
         break;
+    case AV_PIX_FMT_GBRP12LE:
+        c->readChrPlanar = planar_rgb12le_to_uv;
+        break;
+    case AV_PIX_FMT_GBRP14LE:
+        c->readChrPlanar = planar_rgb14le_to_uv;
+        break;
     case AV_PIX_FMT_GBRP16LE:
         c->readChrPlanar = planar_rgb16le_to_uv;
         break;
@@ -708,6 +908,12 @@
     case AV_PIX_FMT_GBRP10BE:
         c->readChrPlanar = planar_rgb10be_to_uv;
         break;
+    case AV_PIX_FMT_GBRP12BE:
+        c->readChrPlanar = planar_rgb12be_to_uv;
+        break;
+    case AV_PIX_FMT_GBRP14BE:
+        c->readChrPlanar = planar_rgb14be_to_uv;
+        break;
     case AV_PIX_FMT_GBRP16BE:
         c->readChrPlanar = planar_rgb16be_to_uv;
         break;
@@ -721,6 +927,12 @@
     case AV_PIX_FMT_YUV422P10LE:
     case AV_PIX_FMT_YUV444P10LE:
     case AV_PIX_FMT_YUV420P10LE:
+    case AV_PIX_FMT_YUV422P12LE:
+    case AV_PIX_FMT_YUV444P12LE:
+    case AV_PIX_FMT_YUV420P12LE:
+    case AV_PIX_FMT_YUV422P14LE:
+    case AV_PIX_FMT_YUV444P14LE:
+    case AV_PIX_FMT_YUV420P14LE:
     case AV_PIX_FMT_YUV420P16LE:
     case AV_PIX_FMT_YUV422P16LE:
     case AV_PIX_FMT_YUV444P16LE:
@@ -733,6 +945,12 @@
     case AV_PIX_FMT_YUV444P10BE:
     case AV_PIX_FMT_YUV422P10BE:
     case AV_PIX_FMT_YUV420P10BE:
+    case AV_PIX_FMT_YUV444P12BE:
+    case AV_PIX_FMT_YUV422P12BE:
+    case AV_PIX_FMT_YUV420P12BE:
+    case AV_PIX_FMT_YUV444P14BE:
+    case AV_PIX_FMT_YUV422P14BE:
+    case AV_PIX_FMT_YUV420P14BE:
     case AV_PIX_FMT_YUV420P16BE:
     case AV_PIX_FMT_YUV422P16BE:
     case AV_PIX_FMT_YUV444P16BE:
@@ -742,6 +960,12 @@
     }
     if (c->chrSrcHSubSample) {
         switch (srcFormat) {
+        case AV_PIX_FMT_RGBA64BE:
+            c->chrToYV12 = rgb64BEToUV_half_c;
+            break;
+        case AV_PIX_FMT_RGBA64LE:
+            c->chrToYV12 = rgb64LEToUV_half_c;
+            break;
         case AV_PIX_FMT_RGB48BE:
             c->chrToYV12 = rgb48BEToUV_half_c;
             break;
@@ -775,6 +999,9 @@
         case AV_PIX_FMT_BGR555BE:
             c->chrToYV12 = bgr15beToUV_half_c;
             break;
+        case AV_PIX_FMT_GBR24P  :
+            c->chrToYV12 = gbr24pToUV_half_c;
+            break;
         case AV_PIX_FMT_BGR444LE:
             c->chrToYV12 = bgr12leToUV_half_c;
             break;
@@ -811,6 +1038,12 @@
         }
     } else {
         switch (srcFormat) {
+        case AV_PIX_FMT_RGBA64BE:
+            c->chrToYV12 = rgb64BEToUV_c;
+            break;
+        case AV_PIX_FMT_RGBA64LE:
+            c->chrToYV12 = rgb64LEToUV_c;
+            break;
         case AV_PIX_FMT_RGB48BE:
             c->chrToYV12 = rgb48BEToUV_c;
             break;
@@ -889,6 +1122,12 @@
     case AV_PIX_FMT_GBRP10LE:
         c->readLumPlanar = planar_rgb10le_to_y;
         break;
+    case AV_PIX_FMT_GBRP12LE:
+        c->readLumPlanar = planar_rgb12le_to_y;
+        break;
+    case AV_PIX_FMT_GBRP14LE:
+        c->readLumPlanar = planar_rgb14le_to_y;
+        break;
     case AV_PIX_FMT_GBRP16LE:
         c->readLumPlanar = planar_rgb16le_to_y;
         break;
@@ -898,6 +1137,12 @@
     case AV_PIX_FMT_GBRP10BE:
         c->readLumPlanar = planar_rgb10be_to_y;
         break;
+    case AV_PIX_FMT_GBRP12BE:
+        c->readLumPlanar = planar_rgb12be_to_y;
+        break;
+    case AV_PIX_FMT_GBRP14BE:
+        c->readLumPlanar = planar_rgb14be_to_y;
+        break;
     case AV_PIX_FMT_GBRP16BE:
         c->readLumPlanar = planar_rgb16be_to_y;
         break;
@@ -911,6 +1156,12 @@
     case AV_PIX_FMT_YUV444P10LE:
     case AV_PIX_FMT_YUV422P10LE:
     case AV_PIX_FMT_YUV420P10LE:
+    case AV_PIX_FMT_YUV444P12LE:
+    case AV_PIX_FMT_YUV422P12LE:
+    case AV_PIX_FMT_YUV420P12LE:
+    case AV_PIX_FMT_YUV444P14LE:
+    case AV_PIX_FMT_YUV422P14LE:
+    case AV_PIX_FMT_YUV420P14LE:
     case AV_PIX_FMT_YUV420P16LE:
     case AV_PIX_FMT_YUV422P16LE:
     case AV_PIX_FMT_YUV444P16LE:
@@ -924,6 +1175,12 @@
     case AV_PIX_FMT_YUV444P10BE:
     case AV_PIX_FMT_YUV422P10BE:
     case AV_PIX_FMT_YUV420P10BE:
+    case AV_PIX_FMT_YUV444P12BE:
+    case AV_PIX_FMT_YUV422P12BE:
+    case AV_PIX_FMT_YUV420P12BE:
+    case AV_PIX_FMT_YUV444P14BE:
+    case AV_PIX_FMT_YUV422P14BE:
+    case AV_PIX_FMT_YUV420P14BE:
     case AV_PIX_FMT_YUV420P16BE:
     case AV_PIX_FMT_YUV422P16BE:
     case AV_PIX_FMT_YUV444P16BE:
@@ -1017,9 +1274,17 @@
     case AV_PIX_FMT_BGR48LE:
         c->lumToYV12 = bgr48LEToY_c;
         break;
+    case AV_PIX_FMT_RGBA64BE:
+        c->lumToYV12 = rgb64BEToY_c;
+        break;
+    case AV_PIX_FMT_RGBA64LE:
+        c->lumToYV12 = rgb64LEToY_c;
+        break;
     }
     if (c->alpPixBuf) {
         switch (srcFormat) {
+        case AV_PIX_FMT_RGBA64LE:
+        case AV_PIX_FMT_RGBA64BE:  c->alpToYV12 = rgba64ToA_c; break;
         case AV_PIX_FMT_BGRA:
         case AV_PIX_FMT_RGBA:
             c->alpToYV12 = rgbaToA_c;
@@ -1031,6 +1296,9 @@
         case AV_PIX_FMT_Y400A:
             c->alpToYV12 = uyvyToY_c;
             break;
+        case AV_PIX_FMT_PAL8 :
+            c->alpToYV12 = palToA_c;
+            break;
         }
     }
 }
diff --git a/libswscale/options.c b/libswscale/options.c
index daf013c..9cd4fc0 100644
--- a/libswscale/options.c
+++ b/libswscale/options.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -66,7 +66,12 @@
     { NULL }
 };
 
-const AVClass sws_context_class = { "SWScaler", sws_context_to_name, options };
+const AVClass sws_context_class = {
+    .class_name = "SWScaler",
+    .item_name  = sws_context_to_name,
+    .option     = options,
+    .category   = AV_CLASS_CATEGORY_SWSCALER,
+};
 
 const AVClass *sws_get_class(void)
 {
diff --git a/libswscale/output.c b/libswscale/output.c
index 4953290..8306298 100644
--- a/libswscale/output.c
+++ b/libswscale/output.c
@@ -1,20 +1,20 @@
 /*
- * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2001-2012 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -26,6 +26,7 @@
 
 #include "libavutil/attributes.h"
 #include "libavutil/avutil.h"
+#include "libavutil/avassert.h"
 #include "libavutil/bswap.h"
 #include "libavutil/cpu.h"
 #include "libavutil/intreadwrite.h"
@@ -36,24 +37,27 @@
 #include "swscale.h"
 #include "swscale_internal.h"
 
-DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_4)[2][8]={
+DECLARE_ALIGNED(8, const uint8_t, dither_2x2_4)[][8]={
 {  1,   3,   1,   3,   1,   3,   1,   3, },
 {  2,   0,   2,   0,   2,   0,   2,   0, },
+{  1,   3,   1,   3,   1,   3,   1,   3, },
 };
 
-DECLARE_ALIGNED(8, static const uint8_t, dither_2x2_8)[2][8]={
+DECLARE_ALIGNED(8, const uint8_t, dither_2x2_8)[][8]={
 {  6,   2,   6,   2,   6,   2,   6,   2, },
 {  0,   4,   0,   4,   0,   4,   0,   4, },
+{  6,   2,   6,   2,   6,   2,   6,   2, },
 };
 
-DECLARE_ALIGNED(8, const uint8_t, dither_4x4_16)[4][8]={
+DECLARE_ALIGNED(8, const uint8_t, dither_4x4_16)[][8]={
 {  8,   4,  11,   7,   8,   4,  11,   7, },
 {  2,  14,   1,  13,   2,  14,   1,  13, },
 { 10,   6,   9,   5,  10,   6,   9,   5, },
 {  0,  12,   3,  15,   0,  12,   3,  15, },
+{  8,   4,  11,   7,   8,   4,  11,   7, },
 };
 
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32)[8][8]={
+DECLARE_ALIGNED(8, const uint8_t, dither_8x8_32)[][8]={
 { 17,   9,  23,  15,  16,   8,  22,  14, },
 {  5,  29,   3,  27,   4,  28,   2,  26, },
 { 21,  13,  19,  11,  20,  12,  18,  10, },
@@ -62,9 +66,10 @@
 {  4,  28,   2,  26,   5,  29,   3,  27, },
 { 20,  12,  18,  10,  21,  13,  19,  11, },
 {  1,  25,   7,  31,   0,  24,   6,  30, },
+{ 17,   9,  23,  15,  16,   8,  22,  14, },
 };
 
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_73)[8][8]={
+DECLARE_ALIGNED(8, const uint8_t, dither_8x8_73)[][8]={
 {  0,  55,  14,  68,   3,  58,  17,  72, },
 { 37,  18,  50,  32,  40,  22,  54,  35, },
 {  9,  64,   5,  59,  13,  67,   8,  63, },
@@ -73,10 +78,11 @@
 { 39,  21,  52,  34,  38,  19,  51,  33, },
 { 11,  66,   7,  62,  10,  65,   6,  60, },
 { 48,  30,  43,  25,  47,  29,  42,  24, },
+{  0,  55,  14,  68,   3,  58,  17,  72, },
 };
 
 #if 1
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
+DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[][8]={
 {117,  62, 158, 103, 113,  58, 155, 100, },
 { 34, 199,  21, 186,  31, 196,  17, 182, },
 {144,  89, 131,  76, 141,  86, 127,  72, },
@@ -85,10 +91,11 @@
 { 28, 193,  14, 179,  38, 203,  24, 189, },
 {138,  83, 124,  69, 148,  93, 134,  79, },
 {  7, 172,  48, 213,   3, 168,  45, 210, },
+{117,  62, 158, 103, 113,  58, 155, 100, },
 };
 #elif 1
 // tries to correct a gamma of 1.5
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
+DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[][8]={
 {  0, 143,  18, 200,   2, 156,  25, 215, },
 { 78,  28, 125,  64,  89,  36, 138,  74, },
 { 10, 180,   3, 161,  16, 195,   8, 175, },
@@ -97,10 +104,11 @@
 { 85,  33, 134,  71,  81,  30, 130,  67, },
 { 14, 190,   6, 171,  12, 185,   5, 166, },
 {117,  57, 101,  44, 113,  54,  97,  41, },
+{  0, 143,  18, 200,   2, 156,  25, 215, },
 };
 #elif 1
 // tries to correct a gamma of 2.0
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
+DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[][8]={
 {  0, 124,   8, 193,   0, 140,  12, 213, },
 { 55,  14, 104,  42,  66,  19, 119,  52, },
 {  3, 168,   1, 145,   6, 187,   3, 162, },
@@ -109,10 +117,11 @@
 { 62,  17, 114,  48,  58,  16, 109,  45, },
 {  5, 181,   2, 157,   4, 175,   1, 151, },
 { 95,  36,  78,  26,  90,  34,  74,  24, },
+{  0, 124,   8, 193,   0, 140,  12, 213, },
 };
 #else
 // tries to correct a gamma of 2.5
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[8][8]={
+DECLARE_ALIGNED(8, const uint8_t, dither_8x8_220)[][8]={
 {  0, 107,   3, 187,   0, 125,   6, 212, },
 { 39,   7,  86,  28,  49,  11, 102,  36, },
 {  1, 158,   0, 131,   3, 180,   1, 151, },
@@ -121,6 +130,7 @@
 { 45,   9,  96,  33,  42,   8,  91,  30, },
 {  2, 172,   1, 144,   2, 165,   0, 137, },
 { 77,  23,  60,  15,  72,  21,  56,  14, },
+{  0, 107,   3, 187,   0, 125,   6, 212, },
 };
 #endif
 
@@ -136,7 +146,8 @@
                          int big_endian, int output_bits)
 {
     int i;
-    int shift = 19 - output_bits;
+    int shift = 3;
+    av_assert0(output_bits == 16);
 
     for (i = 0; i < dstW; i++) {
         int val = src[i] + (1 << (shift - 1));
@@ -150,10 +161,11 @@
                          int big_endian, int output_bits)
 {
     int i;
-    int shift = 15 + 16 - output_bits;
+    int shift = 15;
+    av_assert0(output_bits == 16);
 
     for (i = 0; i < dstW; i++) {
-        int val = 1 << (30-output_bits);
+        int val = 1 << (shift - 1);
         int j;
 
         /* range of val is [0,0x7FFFFFFF], so 31 bits, but with lanczos/spline
@@ -163,7 +175,7 @@
          * reasonable filterSize), and re-add that at the end. */
         val -= 0x40000000;
         for (j = 0; j < filterSize; j++)
-            val += src[j][i] * filter[j];
+            val += src[j][i] * (unsigned)filter[j];
 
         output_pixel(&dest[i], val, 0x8000, int);
     }
@@ -200,7 +212,7 @@
     int shift = 11 + 16 - output_bits;
 
     for (i = 0; i < dstW; i++) {
-        int val = 1 << (26-output_bits);
+        int val = 1 << (shift - 1);
         int j;
 
         for (j = 0; j < filterSize; j++)
@@ -393,14 +405,14 @@
     for (i = 0; i < dstW; i += 8) {
         int acc = 0;
 
-        accumulate_bit(acc, (buf0[i + 0] >> 7) + d128[0]);
-        accumulate_bit(acc, (buf0[i + 1] >> 7) + d128[1]);
-        accumulate_bit(acc, (buf0[i + 2] >> 7) + d128[2]);
-        accumulate_bit(acc, (buf0[i + 3] >> 7) + d128[3]);
-        accumulate_bit(acc, (buf0[i + 4] >> 7) + d128[4]);
-        accumulate_bit(acc, (buf0[i + 5] >> 7) + d128[5]);
-        accumulate_bit(acc, (buf0[i + 6] >> 7) + d128[6]);
-        accumulate_bit(acc, (buf0[i + 7] >> 7) + d128[7]);
+        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]);
+        accumulate_bit(acc, ((buf0[i + 3] + 64) >> 7) + d128[3]);
+        accumulate_bit(acc, ((buf0[i + 4] + 64) >> 7) + d128[4]);
+        accumulate_bit(acc, ((buf0[i + 5] + 64) >> 7) + d128[5]);
+        accumulate_bit(acc, ((buf0[i + 6] + 64) >> 7) + d128[6]);
+        accumulate_bit(acc, ((buf0[i + 7] + 64) >> 7) + d128[7]);
 
         output_pixel(*dest++, acc);
     }
@@ -516,10 +528,12 @@
         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha) >> 19;
         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha) >> 19;
 
-        Y1 = av_clip_uint8(Y1);
-        Y2 = av_clip_uint8(Y2);
-        U  = av_clip_uint8(U);
-        V  = av_clip_uint8(V);
+        if ((Y1 | Y2 | U | V) & 0x100) {
+            Y1 = av_clip_uint8(Y1);
+            Y2 = av_clip_uint8(Y2);
+            U  = av_clip_uint8(U);
+            V  = av_clip_uint8(V);
+        }
 
         output_pixels(i * 4, Y1, U, Y2, V);
     }
@@ -536,10 +550,17 @@
 
     if (uvalpha < 2048) {
         for (i = 0; i < ((dstW + 1) >> 1); i++) {
-            int Y1 = buf0[i * 2]     >> 7;
-            int Y2 = buf0[i * 2 + 1] >> 7;
-            int U  = ubuf0[i]        >> 7;
-            int V  = vbuf0[i]        >> 7;
+            int Y1 = (buf0[i * 2    ]+64) >> 7;
+            int Y2 = (buf0[i * 2 + 1]+64) >> 7;
+            int U  = (ubuf0[i]       +64) >> 7;
+            int V  = (vbuf0[i]       +64) >> 7;
+
+            if ((Y1 | Y2 | U | V) & 0x100) {
+                Y1 = av_clip_uint8(Y1);
+                Y2 = av_clip_uint8(Y2);
+                U  = av_clip_uint8(U);
+                V  = av_clip_uint8(V);
+            }
 
             Y1 = av_clip_uint8(Y1);
             Y2 = av_clip_uint8(Y2);
@@ -551,10 +572,17 @@
     } else {
         const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
         for (i = 0; i < ((dstW + 1) >> 1); i++) {
-            int Y1 =  buf0[i * 2]          >> 7;
-            int Y2 =  buf0[i * 2 + 1]      >> 7;
-            int U  = (ubuf0[i] + ubuf1[i]) >> 8;
-            int V  = (vbuf0[i] + vbuf1[i]) >> 8;
+            int Y1 = (buf0[i * 2    ]    + 64) >> 7;
+            int Y2 = (buf0[i * 2 + 1]    + 64) >> 7;
+            int U  = (ubuf0[i] + ubuf1[i]+128) >> 8;
+            int V  = (vbuf0[i] + vbuf1[i]+128) >> 8;
+
+            if ((Y1 | Y2 | U | V) & 0x100) {
+                Y1 = av_clip_uint8(Y1);
+                Y2 = av_clip_uint8(Y2);
+                U  = av_clip_uint8(U);
+                V  = av_clip_uint8(V);
+            }
 
             Y1 = av_clip_uint8(Y1);
             Y2 = av_clip_uint8(Y2);
@@ -599,12 +627,12 @@
         int R, G, B;
 
         for (j = 0; j < lumFilterSize; j++) {
-            Y1 += lumSrc[j][i * 2]     * lumFilter[j];
-            Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
+            Y1 += lumSrc[j][i * 2]     * (unsigned)lumFilter[j];
+            Y2 += lumSrc[j][i * 2 + 1] * (unsigned)lumFilter[j];
         }
-        for (j = 0; j < chrFilterSize; j++) {
-            U += chrUSrc[j][i] * chrFilter[j];
-            V += chrVSrc[j][i] * chrFilter[j];
+        for (j = 0; j < chrFilterSize; j++) {;
+            U += chrUSrc[j][i] * (unsigned)chrFilter[j];
+            V += chrVSrc[j][i] * (unsigned)chrFilter[j];
         }
 
         // 8bit: 12+15=27; 16-bit: 12+19=31
@@ -812,7 +840,7 @@
  * correct RGB values into the destination buffer.
  */
 static av_always_inline void
-yuv2rgb_write(uint8_t *_dest, int i, unsigned Y1, unsigned Y2,
+yuv2rgb_write(uint8_t *_dest, int i, int Y1, int Y2,
               unsigned A1, unsigned A2,
               const void *_r, const void *_g, const void *_b, int y,
               enum AVPixelFormat target, int hasAlpha)
@@ -848,6 +876,7 @@
 
 #define r_b ((target == AV_PIX_FMT_RGB24) ? r : b)
 #define b_r ((target == AV_PIX_FMT_RGB24) ? b : r)
+
         dest[i * 6 + 0] = r_b[Y1];
         dest[i * 6 + 1] =   g[Y1];
         dest[i * 6 + 2] = b_r[Y1];
@@ -953,12 +982,6 @@
         Y2 >>= 19;
         U  >>= 19;
         V  >>= 19;
-        if ((Y1 | Y2 | U | V) & 0x100) {
-            Y1 = av_clip_uint8(Y1);
-            Y2 = av_clip_uint8(Y2);
-            U  = av_clip_uint8(U);
-            V  = av_clip_uint8(V);
-        }
         if (hasAlpha) {
             A1 = 1 << 18;
             A2 = 1 << 18;
@@ -974,10 +997,9 @@
             }
         }
 
-        /* FIXME fix tables so that clipping is not needed and then use _NOCLIP*/
-        r =  c->table_rV[V];
-        g = (c->table_gU[U] + c->table_gV[V]);
-        b =  c->table_bU[U];
+        r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM];
+        g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]);
+        b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
 
         yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
                       r, g, b, y, target, hasAlpha);
@@ -1006,16 +1028,9 @@
         int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha) >> 19;
         int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha) >> 19;
         int A1, A2;
-        const void *r, *g, *b;
-
-        Y1 = av_clip_uint8(Y1);
-        Y2 = av_clip_uint8(Y2);
-        U  = av_clip_uint8(U);
-        V  = av_clip_uint8(V);
-
-        r =  c->table_rV[V];
-        g = (c->table_gU[U] + c->table_gV[V]);
-        b =  c->table_bU[U];
+        const void *r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM],
+                   *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]),
+                   *b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
 
         if (hasAlpha) {
             A1 = (abuf0[i * 2    ] * yalpha1 + abuf1[i * 2    ] * yalpha) >> 19;
@@ -1041,25 +1056,18 @@
 
     if (uvalpha < 2048) {
         for (i = 0; i < ((dstW + 1) >> 1); i++) {
-            int Y1 = buf0[i * 2]     >> 7;
-            int Y2 = buf0[i * 2 + 1] >> 7;
-            int U  = ubuf0[i]        >> 7;
-            int V  = vbuf0[i]        >> 7;
+            int Y1 = (buf0[i * 2    ] + 64) >> 7;
+            int Y2 = (buf0[i * 2 + 1] + 64) >> 7;
+            int U  = (ubuf0[i]        + 64) >> 7;
+            int V  = (vbuf0[i]        + 64) >> 7;
             int A1, A2;
-            const void *r, *g, *b;
-
-            Y1 = av_clip_uint8(Y1);
-            Y2 = av_clip_uint8(Y2);
-            U  = av_clip_uint8(U);
-            V  = av_clip_uint8(V);
-
-            r =  c->table_rV[V];
-            g = (c->table_gU[U] + c->table_gV[V]);
-            b =  c->table_bU[U];
+            const void *r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM],
+                       *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]),
+                       *b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
 
             if (hasAlpha) {
-                A1 = abuf0[i * 2    ] >> 7;
-                A2 = abuf0[i * 2 + 1] >> 7;
+                A1 = abuf0[i * 2    ] * 255 + 16384 >> 15;
+                A2 = abuf0[i * 2 + 1] * 255 + 16384 >> 15;
                 A1 = av_clip_uint8(A1);
                 A2 = av_clip_uint8(A2);
             }
@@ -1070,25 +1078,18 @@
     } else {
         const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];
         for (i = 0; i < ((dstW + 1) >> 1); i++) {
-            int Y1 =  buf0[i * 2]          >> 7;
-            int Y2 =  buf0[i * 2 + 1]      >> 7;
-            int U  = (ubuf0[i] + ubuf1[i]) >> 8;
-            int V  = (vbuf0[i] + vbuf1[i]) >> 8;
+            int Y1 = (buf0[i * 2    ]     +  64) >> 7;
+            int Y2 = (buf0[i * 2 + 1]     +  64) >> 7;
+            int U  = (ubuf0[i] + ubuf1[i] + 128) >> 8;
+            int V  = (vbuf0[i] + vbuf1[i] + 128) >> 8;
             int A1, A2;
-            const void *r, *g, *b;
-
-            Y1 = av_clip_uint8(Y1);
-            Y2 = av_clip_uint8(Y2);
-            U  = av_clip_uint8(U);
-            V  = av_clip_uint8(V);
-
-            r =  c->table_rV[V];
-            g = (c->table_gU[U] + c->table_gV[V]);
-            b =  c->table_bU[U];
+            const void *r =  c->table_rV[V + YUVRGB_TABLE_HEADROOM],
+                       *g = (c->table_gU[U + YUVRGB_TABLE_HEADROOM] + c->table_gV[V + YUVRGB_TABLE_HEADROOM]),
+                       *b =  c->table_bU[U + YUVRGB_TABLE_HEADROOM];
 
             if (hasAlpha) {
-                A1 = abuf0[i * 2    ] >> 7;
-                A2 = abuf0[i * 2 + 1] >> 7;
+                A1 = (abuf0[i * 2    ] + 64) >> 7;
+                A2 = (abuf0[i * 2 + 1] + 64) >> 7;
                 A1 = av_clip_uint8(A1);
                 A2 = av_clip_uint8(A2);
             }
@@ -1164,9 +1165,9 @@
 
     for (i = 0; i < dstW; i++) {
         int j;
-        int Y = 0;
-        int U = -128 << 19;
-        int V = -128 << 19;
+        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++) {
@@ -1180,7 +1181,7 @@
         U >>= 10;
         V >>= 10;
         if (hasAlpha) {
-            A = 1 << 21;
+            A = 1 << 18;
             for (j = 0; j < lumFilterSize; j++) {
                 A += alpSrc[j][i] * lumFilter[j];
             }
@@ -1223,7 +1224,6 @@
             dest[1] = B >> 22;
             dest[2] = G >> 22;
             dest[3] = R >> 22;
-            dest += 4;
             break;
         case AV_PIX_FMT_BGR24:
             dest[0] = B >> 22;
@@ -1355,7 +1355,10 @@
             *yuv2packedX = yuv2bgr24_full_X_c;
             break;
         }
+        if(!*yuv2packedX)
+            goto YUV_PACKED;
     } else {
+        YUV_PACKED:
         switch (dstFormat) {
         case AV_PIX_FMT_RGB48LE:
             *yuv2packed1 = yuv2rgb48le_1_c;
diff --git a/libswscale/ppc/swscale_altivec.c b/libswscale/ppc/swscale_altivec.c
index b0e25d0..9ca2868 100644
--- a/libswscale/ppc/swscale_altivec.c
+++ b/libswscale/ppc/swscale_altivec.c
@@ -4,20 +4,20 @@
  * Copyright (C) 2004 Romain Dolbeau <romain@dolbeau.org>
  * based on the equivalent C code in swscale.c
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -292,7 +292,7 @@
     if (!(av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC))
         return;
 
-    if (c->srcBpc == 8 && c->dstBpc <= 10) {
+    if (c->srcBpc == 8 && c->dstBpc <= 14) {
         c->hyScale = c->hcScale = hScale_altivec_real;
     }
     if (!is16BPS(dstFormat) && !is9_OR_10BPS(dstFormat) &&
diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c
index 94e87fe..a8501d9 100644
--- a/libswscale/ppc/yuv2rgb_altivec.c
+++ b/libswscale/ppc/yuv2rgb_altivec.c
@@ -3,20 +3,20 @@
  *
  * copyright (C) 2004 Marc Hoffman <marc.hoffman@analog.com>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -97,6 +97,7 @@
 #include "libswscale/swscale_internal.h"
 #include "libavutil/attributes.h"
 #include "libavutil/cpu.h"
+#include "libavutil/pixdesc.h"
 #include "yuv2rgb_altivec.h"
 
 #undef PROFILE_THE_BEAST
@@ -317,12 +318,7 @@
     const ubyte *ui  = in[1];                                                 \
     const ubyte *vi  = in[2];                                                 \
                                                                               \
-    vector unsigned char *oute =                                              \
-        (vector unsigned char *)                                              \
-            (oplanes[0] + srcSliceY * outstrides[0]);                         \
-    vector unsigned char *outo =                                              \
-        (vector unsigned char *)                                              \
-            (oplanes[0] + srcSliceY * outstrides[0] + outstrides[0]);         \
+    vector unsigned char *oute, *outo;                                        \
                                                                               \
     /* loop moves y{1, 2}i by w */                                            \
     instrides_scl[0] = instrides[0] * 2 - w;                                  \
@@ -332,6 +328,9 @@
     instrides_scl[2] = instrides[2] - w / 2;                                  \
                                                                               \
     for (i = 0; i < h / 2; i++) {                                             \
+        oute = (vector unsigned char *)(oplanes[0] + outstrides[0] *          \
+                                        (srcSliceY + i * 2));                 \
+        outo = oute + (outstrides[0] >> 4);                                   \
         vec_dstst(outo, (0x02000002 | (((w * 3 + 32) / 32) << 16)), 0);       \
         vec_dstst(oute, (0x02000002 | (((w * 3 + 32) / 32) << 16)), 1);       \
                                                                               \
@@ -429,9 +428,6 @@
             vi  += 8;                                                         \
         }                                                                     \
                                                                               \
-        outo += (outstrides[0]) >> 4;                                         \
-        oute += (outstrides[0]) >> 4;                                         \
-                                                                              \
         ui  += instrides_scl[1];                                              \
         vi  += instrides_scl[2];                                              \
         y1i += instrides_scl[0];                                              \
@@ -736,7 +732,7 @@
             if (!printed_error_message) {
                 av_log(c, AV_LOG_ERROR,
                        "altivec_yuv2packedX doesn't support %s output\n",
-                       sws_format_name(c->dstFormat));
+                       av_get_pix_fmt_name(c->dstFormat));
                 printed_error_message = 1;
             }
             return;
@@ -824,7 +820,7 @@
             /* Unreachable, I think. */
             av_log(c, AV_LOG_ERROR,
                    "altivec_yuv2packedX doesn't support %s output\n",
-                   sws_format_name(c->dstFormat));
+                   av_get_pix_fmt_name(c->dstFormat));
             return;
         }
 
diff --git a/libswscale/ppc/yuv2rgb_altivec.h b/libswscale/ppc/yuv2rgb_altivec.h
index 2c5e7ed..aa52a47 100644
--- a/libswscale/ppc/yuv2rgb_altivec.h
+++ b/libswscale/ppc/yuv2rgb_altivec.h
@@ -4,20 +4,20 @@
  * Copyright (C) 2004 Romain Dolbeau <romain@dolbeau.org>
  * based on the equivalent C code in swscale.c
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libswscale/ppc/yuv2yuv_altivec.c b/libswscale/ppc/yuv2yuv_altivec.c
index e68cccf..60d50a7 100644
--- a/libswscale/ppc/yuv2yuv_altivec.c
+++ b/libswscale/ppc/yuv2yuv_altivec.c
@@ -4,20 +4,20 @@
  * Copyright (C) 2004 Romain Dolbeau <romain@dolbeau.org>
  * based on the equivalent C code in swscale.c
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libswscale/rgb2rgb.c b/libswscale/rgb2rgb.c
index 26ef648..321e5ff 100644
--- a/libswscale/rgb2rgb.c
+++ b/libswscale/rgb2rgb.c
@@ -6,20 +6,20 @@
  * Written by Nick Kurshev.
  * palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -181,13 +181,13 @@
         register uint16_t bgr = *s++;
 #if HAVE_BIGENDIAN
         *d++ = 255;
-        *d++ = (bgr & 0x1F)   << 3;
-        *d++ = (bgr & 0x7E0)  >> 3;
-        *d++ = (bgr & 0xF800) >> 8;
+        *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
+        *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
+        *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
 #else
-        *d++ = (bgr & 0xF800) >> 8;
-        *d++ = (bgr & 0x7E0)  >> 3;
-        *d++ = (bgr & 0x1F)   << 3;
+        *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
+        *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
+        *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
         *d++ = 255;
 #endif
     }
@@ -220,9 +220,9 @@
 
     while (s < end) {
         register uint16_t bgr = *s++;
-        *d++ = (bgr & 0xF800) >> 8;
-        *d++ = (bgr & 0x7E0)  >> 3;
-        *d++ = (bgr & 0x1F)   << 3;
+        *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
+        *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
+        *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
     }
 }
 
@@ -256,13 +256,13 @@
         register uint16_t bgr = *s++;
 #if HAVE_BIGENDIAN
         *d++ = 255;
-        *d++ = (bgr & 0x1F)   << 3;
-        *d++ = (bgr & 0x3E0)  >> 2;
-        *d++ = (bgr & 0x7C00) >> 7;
+        *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
+        *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
+        *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
 #else
-        *d++ = (bgr & 0x7C00) >> 7;
-        *d++ = (bgr & 0x3E0)  >> 2;
-        *d++ = (bgr & 0x1F)   << 3;
+        *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
+        *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
+        *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
         *d++ = 255;
 #endif
     }
@@ -276,9 +276,9 @@
 
     while (s < end) {
         register uint16_t bgr = *s++;
-        *d++ = (bgr & 0x7C00) >> 7;
-        *d++ = (bgr & 0x3E0)  >> 2;
-        *d++ = (bgr & 0x1F)   << 3;
+        *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
+        *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
+        *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
     }
 }
 
@@ -315,18 +315,6 @@
     }
 }
 
-void bgr8torgb8(const uint8_t *src, uint8_t *dst, int src_size)
-{
-    int i, num_pixels = src_size;
-
-    for (i = 0; i < num_pixels; i++) {
-        register uint8_t rgb = src[i];
-        unsigned r           = (rgb & 0x07);
-        unsigned g           = (rgb & 0x38) >> 3;
-        unsigned b           = (rgb & 0xC0) >> 6;
-        dst[i]               = ((b << 1) & 0x07) | ((g & 0x07) << 3) | ((r & 0x03) << 6);
-    }
-}
 
 #define DEFINE_SHUFFLE_BYTES(a, b, c, d)                                \
 void shuffle_bytes_ ## a ## b ## c ## d(const uint8_t *src,             \
@@ -346,3 +334,57 @@
 DEFINE_SHUFFLE_BYTES(1, 2, 3, 0)
 DEFINE_SHUFFLE_BYTES(3, 0, 1, 2)
 DEFINE_SHUFFLE_BYTES(3, 2, 1, 0)
+
+#define DEFINE_RGB48TOBGR48(need_bswap, swap)                           \
+void rgb48tobgr48_ ## need_bswap(const uint8_t *src,                    \
+                                 uint8_t *dst, int src_size)            \
+{                                                                       \
+    uint16_t *d = (uint16_t *)dst;                                      \
+    uint16_t *s = (uint16_t *)src;                                      \
+    int i, num_pixels = src_size >> 1;                                  \
+                                                                        \
+    for (i = 0; i < num_pixels; i += 3) {                               \
+        d[i    ] = swap ? av_bswap16(s[i + 2]) : s[i + 2];              \
+        d[i + 1] = swap ? av_bswap16(s[i + 1]) : s[i + 1];              \
+        d[i + 2] = swap ? av_bswap16(s[i    ]) : s[i    ];              \
+    }                                                                   \
+}
+
+DEFINE_RGB48TOBGR48(nobswap, 0)
+DEFINE_RGB48TOBGR48(bswap, 1)
+
+#define DEFINE_RGB64TOBGR48(need_bswap, swap)                           \
+void rgb64tobgr48_ ## need_bswap(const uint8_t *src,                    \
+                                 uint8_t *dst, int src_size)            \
+{                                                                       \
+    uint16_t *d = (uint16_t *)dst;                                      \
+    uint16_t *s = (uint16_t *)src;                                      \
+    int i, num_pixels = src_size >> 3;                                  \
+                                                                        \
+    for (i = 0; i < num_pixels; i++) {                                  \
+        d[3 * i    ] = swap ? av_bswap16(s[4 * i + 2]) : s[4 * i + 2];  \
+        d[3 * i + 1] = swap ? av_bswap16(s[4 * i + 1]) : s[4 * i + 1];  \
+        d[3 * i + 2] = swap ? av_bswap16(s[4 * i    ]) : s[4 * i    ];  \
+    }                                                                   \
+}
+
+DEFINE_RGB64TOBGR48(nobswap, 0)
+DEFINE_RGB64TOBGR48(bswap, 1)
+
+#define DEFINE_RGB64TO48(need_bswap, swap)                              \
+void rgb64to48_ ## need_bswap(const uint8_t *src,                       \
+                              uint8_t *dst, int src_size)               \
+{                                                                       \
+    uint16_t *d = (uint16_t *)dst;                                      \
+    uint16_t *s = (uint16_t *)src;                                      \
+    int i, num_pixels = src_size >> 3;                                  \
+                                                                        \
+    for (i = 0; i < num_pixels; i++) {                                  \
+        d[3 * i    ] = swap ? av_bswap16(s[4 * i    ]) : s[4 * i    ];  \
+        d[3 * i + 1] = swap ? av_bswap16(s[4 * i + 1]) : s[4 * i + 1];  \
+        d[3 * i + 2] = swap ? av_bswap16(s[4 * i + 2]) : s[4 * i + 2];  \
+    }                                                                   \
+}
+
+DEFINE_RGB64TO48(nobswap, 0)
+DEFINE_RGB64TO48(bswap, 1)
diff --git a/libswscale/rgb2rgb.h b/libswscale/rgb2rgb.h
index 42f468f..e37f0fb 100644
--- a/libswscale/rgb2rgb.h
+++ b/libswscale/rgb2rgb.h
@@ -6,20 +6,20 @@
  *  Written by Nick Kurshev.
  *  YUV & runtime CPU stuff by Michael (michaelni@gmx.at)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -52,6 +52,12 @@
 
 extern void (*shuffle_bytes_2103)(const uint8_t *src, uint8_t *dst, int src_size);
 
+void rgb64tobgr48_nobswap(const uint8_t *src, uint8_t *dst, int src_size);
+void   rgb64tobgr48_bswap(const uint8_t *src, uint8_t *dst, int src_size);
+void rgb48tobgr48_nobswap(const uint8_t *src, uint8_t *dst, int src_size);
+void   rgb48tobgr48_bswap(const uint8_t *src, uint8_t *dst, int src_size);
+void    rgb64to48_nobswap(const uint8_t *src, uint8_t *dst, int src_size);
+void      rgb64to48_bswap(const uint8_t *src, uint8_t *dst, int src_size);
 void    rgb24to32(const uint8_t *src, uint8_t *dst, int src_size);
 void    rgb32to24(const uint8_t *src, uint8_t *dst, int src_size);
 void rgb16tobgr32(const uint8_t *src, uint8_t *dst, int src_size);
@@ -64,7 +70,6 @@
 void rgb15tobgr15(const uint8_t *src, uint8_t *dst, int src_size);
 void rgb12tobgr12(const uint8_t *src, uint8_t *dst, int src_size);
 void    rgb12to15(const uint8_t *src, uint8_t *dst, int src_size);
-void   bgr8torgb8(const uint8_t *src, uint8_t *dst, int src_size);
 
 void shuffle_bytes_0321(const uint8_t *src, uint8_t *dst, int src_size);
 void shuffle_bytes_1230(const uint8_t *src, uint8_t *dst, int src_size);
diff --git a/libswscale/rgb2rgb_template.c b/libswscale/rgb2rgb_template.c
index d1a43e0..c05cdc8 100644
--- a/libswscale/rgb2rgb_template.c
+++ b/libswscale/rgb2rgb_template.c
@@ -7,20 +7,20 @@
  * palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at)
  * lot of big-endian byte order fixes by Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -238,27 +238,6 @@
     }
 }
 
-/*
- * I use less accurate approximation here by simply left-shifting the input
- * value and filling the low order bits with zeroes. This method improves PNG
- * compression but this scheme cannot reproduce white exactly, since it does
- * not generate an all-ones maximum value; the net effect is to darken the
- * image slightly.
- *
- * The better method should be "left bit replication":
- *
- *  4 3 2 1 0
- *  ---------
- *  1 1 0 1 1
- *
- *  7 6 5 4 3  2 1 0
- *  ----------------
- *  1 1 0 1 1  1 1 0
- *  |=======|  |===|
- *      |      leftmost bits repeated to fill open bits
- *      |
- *  original bits
- */
 static inline void rgb15tobgr24_c(const uint8_t *src, uint8_t *dst,
                                   int src_size)
 {
@@ -268,9 +247,9 @@
 
     while (s < end) {
         register uint16_t bgr = *s++;
-        *d++ = (bgr & 0x1F)   << 3;
-        *d++ = (bgr & 0x3E0)  >> 2;
-        *d++ = (bgr & 0x7C00) >> 7;
+        *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
+        *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
+        *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
     }
 }
 
@@ -283,9 +262,9 @@
 
     while (s < end) {
         register uint16_t bgr = *s++;
-        *d++ = (bgr & 0x1F)   << 3;
-        *d++ = (bgr & 0x7E0)  >> 3;
-        *d++ = (bgr & 0xF800) >> 8;
+        *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
+        *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
+        *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
     }
 }
 
@@ -299,13 +278,13 @@
         register uint16_t bgr = *s++;
 #if HAVE_BIGENDIAN
         *d++ = 255;
-        *d++ = (bgr & 0x7C00) >> 7;
-        *d++ = (bgr & 0x3E0)  >> 2;
-        *d++ = (bgr & 0x1F)   << 3;
+        *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
+        *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
+        *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
 #else
-        *d++ = (bgr & 0x1F)   << 3;
-        *d++ = (bgr & 0x3E0)  >> 2;
-        *d++ = (bgr & 0x7C00) >> 7;
+        *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
+        *d++ = ((bgr&0x03E0)>>2) | ((bgr&0x03E0)>> 7);
+        *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
         *d++ = 255;
 #endif
     }
@@ -321,13 +300,13 @@
         register uint16_t bgr = *s++;
 #if HAVE_BIGENDIAN
         *d++ = 255;
-        *d++ = (bgr & 0xF800) >> 8;
-        *d++ = (bgr & 0x7E0)  >> 3;
-        *d++ = (bgr & 0x1F)   << 3;
+        *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
+        *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
+        *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
 #else
-        *d++ = (bgr & 0x1F)   << 3;
-        *d++ = (bgr & 0x7E0)  >> 3;
-        *d++ = (bgr & 0xF800) >> 8;
+        *d++ = ((bgr&0x001F)<<3) | ((bgr&0x001F)>> 2);
+        *d++ = ((bgr&0x07E0)>>3) | ((bgr&0x07E0)>> 9);
+        *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
         *d++ = 255;
 #endif
     }
@@ -665,6 +644,9 @@
         ydst += lumStride;
         src  += srcStride;
 
+        if (y+1 == height)
+            break;
+
         for (i = 0; i < chromWidth; i++) {
             unsigned int b = src[6 * i + 0];
             unsigned int g = src[6 * i + 1];
diff --git a/libswscale/sparc/yuv2rgb_vis.c b/libswscale/sparc/yuv2rgb_vis.c
index cd8a8b0..ed00837 100644
--- a/libswscale/sparc/yuv2rgb_vis.c
+++ b/libswscale/sparc/yuv2rgb_vis.c
@@ -2,20 +2,20 @@
  * VIS optimized software YUV to RGB converter
  * Copyright (c) 2007 Denes Balatoni <dbalatoni@programozo.hu>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/libswscale/swscale-test.c b/libswscale/swscale-test.c
index 12fa9ed..085aecb 100644
--- a/libswscale/swscale-test.c
+++ b/libswscale/swscale-test.c
@@ -1,20 +1,20 @@
 /*
- * Copyright (C) 2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2003-2011 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -90,7 +90,7 @@
     static int srcStride[4];
     uint8_t *dst[4] = { 0 };
     uint8_t *out[4] = { 0 };
-    int dstStride[4];
+    int dstStride[4] = {0};
     int i;
     uint64_t ssdY, ssdU = 0, ssdV = 0, ssdA = 0;
     struct SwsContext *dstContext = NULL, *outContext = NULL;
@@ -106,6 +106,7 @@
 
         av_image_fill_linesizes(srcStride, srcFormat, srcW);
         for (p = 0; p < 4; p++) {
+            srcStride[p] = FFALIGN(srcStride[p], 16);
             if (srcStride[p])
                 src[p] = av_mallocz(srcStride[p] * srcH + 16);
             if (srcStride[p] && !src[p]) {
@@ -139,6 +140,7 @@
          * allocated with av_malloc). */
         /* An extra 16 bytes is being allocated because some scalers may write
          * out of bounds. */
+        dstStride[i] = FFALIGN(dstStride[i], 16);
         if (dstStride[i])
             dst[i] = av_mallocz(dstStride[i] * dstH + 16);
         if (dstStride[i] && !dst[i]) {
@@ -177,6 +179,7 @@
         ssdA = r->ssdA;
     } else {
         for (i = 0; i < 4; i++) {
+            refStride[i] = FFALIGN(refStride[i], 16);
             if (refStride[i])
                 out[i] = av_mallocz(refStride[i] * h);
             if (refStride[i] && !out[i]) {
diff --git a/libswscale/swscale.c b/libswscale/swscale.c
index 3f54e4d..f7dc728 100644
--- a/libswscale/swscale.c
+++ b/libswscale/swscale.c
@@ -1,20 +1,20 @@
 /*
- * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2001-2011 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -24,6 +24,7 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "libavutil/avassert.h"
 #include "libavutil/avutil.h"
 #include "libavutil/bswap.h"
 #include "libavutil/cpu.h"
@@ -72,6 +73,9 @@
     int bits            = desc->comp[0].depth_minus1;
     int sh              = bits - 4;
 
+    if((isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8) && desc->comp[0].depth_minus1<15)
+        sh= 9;
+
     for (i = 0; i < dstW; i++) {
         int j;
         int srcPos = filterPos[i];
@@ -94,6 +98,9 @@
     const uint16_t *src = (const uint16_t *) _src;
     int sh              = desc->comp[0].depth_minus1;
 
+    if(sh<15)
+        sh= isAnyRGB(c->srcFormat) || c->srcFormat==AV_PIX_FMT_PAL8 ? 13 : desc->comp[0].depth_minus1;
+
     for (i = 0; i < dstW; i++) {
         int j;
         int srcPos = filterPos[i];
@@ -210,7 +217,7 @@
     int i;
     int32_t *dst = (int32_t *) _dst;
     for (i = 0; i < width; i++)
-        dst[i] = (dst[i] * 14071 + (33561947 << 4)) >> 14;
+        dst[i] = (dst[i]*(14071/4) + (33561947<<4)/4)>>12;
 }
 
 static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth,
@@ -224,6 +231,8 @@
         dst[i] = (src[xx] << 7) + (src[xx + 1] - src[xx]) * xalpha;
         xpos  += xInc;
     }
+    for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--)
+        dst[i] = src[srcW-1]*128;
 }
 
 // *** horizontal scale Y line to temp buffer
@@ -236,13 +245,13 @@
                                      uint8_t *formatConvBuffer,
                                      uint32_t *pal, int isAlpha)
 {
-    void (*toYV12)(uint8_t *, const uint8_t *, int, uint32_t *) =
+    void (*toYV12)(uint8_t *, const uint8_t *, const uint8_t *, const uint8_t *, int, uint32_t *) =
         isAlpha ? c->alpToYV12 : c->lumToYV12;
     void (*convertRange)(int16_t *, int) = isAlpha ? NULL : c->lumConvertRange;
     const uint8_t *src = src_in[isAlpha ? 3 : 0];
 
     if (toYV12) {
-        toYV12(formatConvBuffer, src, srcW, pal);
+        toYV12(formatConvBuffer, src, src_in[1], src_in[2], srcW, pal);
         src = formatConvBuffer;
     } else if (c->readLumPlanar && !isAlpha) {
         c->readLumPlanar(formatConvBuffer, src_in, srcW);
@@ -273,6 +282,10 @@
         dst2[i] = (src2[xx] * (xalpha ^ 127) + src2[xx + 1] * xalpha);
         xpos   += xInc;
     }
+    for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) {
+        dst1[i] = src1[srcW-1]*128;
+        dst2[i] = src2[srcW-1]*128;
+    }
 }
 
 static av_always_inline void hcscale(SwsContext *c, int16_t *dst1,
@@ -287,13 +300,13 @@
     const uint8_t *src1 = src_in[1], *src2 = src_in[2];
     if (c->chrToYV12) {
         uint8_t *buf2 = formatConvBuffer +
-                        FFALIGN(srcW * FFALIGN(c->srcBpc, 8) >> 3, 16);
-        c->chrToYV12(formatConvBuffer, buf2, src1, src2, srcW, pal);
-        src1 = formatConvBuffer;
-        src2 = buf2;
+                        FFALIGN(srcW*2+78, 16);
+        c->chrToYV12(formatConvBuffer, buf2, src_in[0], src1, src2, srcW, pal);
+        src1= formatConvBuffer;
+        src2= buf2;
     } else if (c->readChrPlanar) {
         uint8_t *buf2 = formatConvBuffer +
-                        FFALIGN(srcW * FFALIGN(c->srcBpc, 8) >> 3, 16);
+                        FFALIGN(srcW*2+78, 16);
         c->readChrPlanar(formatConvBuffer, buf2, src_in, srcW);
         src1 = formatConvBuffer;
         src2 = buf2;
@@ -334,8 +347,6 @@
     int32_t *vChrFilterPos           = c->vChrFilterPos;
     int32_t *hLumFilterPos           = c->hLumFilterPos;
     int32_t *hChrFilterPos           = c->hChrFilterPos;
-    int16_t *vLumFilter              = c->vLumFilter;
-    int16_t *vChrFilter              = c->vChrFilter;
     int16_t *hLumFilter              = c->hLumFilter;
     int16_t *hChrFilter              = c->hChrFilter;
     int32_t *lumMmxFilter            = c->lumMmxFilter;
@@ -394,8 +405,8 @@
     DEBUG_BUFFERS("vLumFilterSize: %d vLumBufSize: %d vChrFilterSize: %d vChrBufSize: %d\n",
                   vLumFilterSize, vLumBufSize, vChrFilterSize, vChrBufSize);
 
-    if (dstStride[0] % 8 != 0 || dstStride[1] % 8 != 0 ||
-        dstStride[2] % 8 != 0 || dstStride[3] % 8 != 0) {
+    if (dstStride[0]%16 !=0 || dstStride[1]%16 !=0 ||
+        dstStride[2]%16 !=0 || dstStride[3]%16 != 0) {
         static int warnedAlready = 0; // FIXME maybe move this into the context
         if (flags & SWS_PRINT_INFO && !warnedAlready) {
             av_log(c, AV_LOG_WARNING,
@@ -405,6 +416,18 @@
         }
     }
 
+    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
+        || dstStride[0]%16 || dstStride[1]%16 || dstStride[2]%16 || dstStride[3]%16
+        || srcStride[0]%16 || srcStride[1]%16 || srcStride[2]%16 || srcStride[3]%16
+    ) {
+        static int warnedAlready=0;
+        int cpu_flags = av_get_cpu_flags();
+        if (HAVE_MMXEXT && (cpu_flags & AV_CPU_FLAG_SSE2) && !warnedAlready){
+            av_log(c, AV_LOG_WARNING, "Warning: data is not aligned! This can lead to a speedloss\n");
+            warnedAlready=1;
+        }
+    }
+
     /* Note the user might start scaling the picture in the middle so this
      * will not get executed. This is not really intended but works
      * currently, so people might do it. */
@@ -429,6 +452,7 @@
             dst[2] + dstStride[2] * chrDstY,
             (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? dst[3] + dstStride[3] * dstY : NULL,
         };
+        int use_mmx_vfilter= c->use_mmx_vfilter;
 
         // First line needed as input
         const int firstLumSrcY  = FFMAX(1 - vLumFilterSize, vLumFilterPos[dstY]);
@@ -447,8 +471,8 @@
             lastInLumBuf = firstLumSrcY - 1;
         if (firstChrSrcY > lastInChrBuf)
             lastInChrBuf = firstChrSrcY - 1;
-        assert(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1);
-        assert(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1);
+        av_assert0(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1);
+        av_assert0(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1);
 
         DEBUG_BUFFERS("dstY: %d\n", dstY);
         DEBUG_BUFFERS("\tfirstLumSrcY: %d lastLumSrcY: %d lastInLumBuf: %d\n",
@@ -476,9 +500,9 @@
                 src[3] + (lastInLumBuf + 1 - srcSliceY) * srcStride[3],
             };
             lumBufIndex++;
-            assert(lumBufIndex < 2 * vLumBufSize);
-            assert(lastInLumBuf + 1 - srcSliceY < srcSliceH);
-            assert(lastInLumBuf + 1 - srcSliceY >= 0);
+            av_assert0(lumBufIndex < 2 * vLumBufSize);
+            av_assert0(lastInLumBuf + 1 - srcSliceY < srcSliceH);
+            av_assert0(lastInLumBuf + 1 - srcSliceY >= 0);
             hyscale(c, lumPixBuf[lumBufIndex], dstW, src1, srcW, lumXInc,
                     hLumFilter, hLumFilterPos, hLumFilterSize,
                     formatConvBuffer, pal, 0);
@@ -498,9 +522,9 @@
                 src[3] + (lastInChrBuf + 1 - chrSrcSliceY) * srcStride[3],
             };
             chrBufIndex++;
-            assert(chrBufIndex < 2 * vChrBufSize);
-            assert(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
-            assert(lastInChrBuf + 1 - chrSrcSliceY >= 0);
+            av_assert0(chrBufIndex < 2 * vChrBufSize);
+            av_assert0(lastInChrBuf + 1 - chrSrcSliceY < (chrSrcSliceH));
+            av_assert0(lastInChrBuf + 1 - chrSrcSliceY >= 0);
             // FIXME replace parameters through context struct (some at least)
 
             if (c->needs_hcscale)
@@ -533,103 +557,81 @@
              * this array's tail */
             ff_sws_init_output_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX,
                                      &yuv2packed1, &yuv2packed2, &yuv2packedX);
+            use_mmx_vfilter= 0;
         }
 
         {
-            const int16_t **lumSrcPtr  = (const int16_t **)lumPixBuf  + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
-            const int16_t **chrUSrcPtr = (const int16_t **)chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
-            const int16_t **chrVSrcPtr = (const int16_t **)chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
+            const int16_t **lumSrcPtr  = (const int16_t **)(void*) lumPixBuf  + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
+            const int16_t **chrUSrcPtr = (const int16_t **)(void*) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
+            const int16_t **chrVSrcPtr = (const int16_t **)(void*) chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
             const int16_t **alpSrcPtr  = (CONFIG_SWSCALE_ALPHA && alpPixBuf) ?
-                                         (const int16_t **)alpPixBuf  + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
-
-            if (firstLumSrcY < 0 || firstLumSrcY + vLumFilterSize > c->srcH) {
-                const int16_t **tmpY = (const int16_t **)lumPixBuf +
-                                       2 * vLumBufSize;
-                int neg = -firstLumSrcY, i;
-                int end = FFMIN(c->srcH - firstLumSrcY, vLumFilterSize);
-                for (i = 0; i < neg; i++)
-                    tmpY[i] = lumSrcPtr[neg];
-                for (; i < end; i++)
-                    tmpY[i] = lumSrcPtr[i];
-                for (; i < vLumFilterSize; i++)
-                    tmpY[i] = tmpY[i - 1];
-                lumSrcPtr = tmpY;
-
-                if (alpSrcPtr) {
-                    const int16_t **tmpA = (const int16_t **)alpPixBuf +
-                                           2 * vLumBufSize;
-                    for (i = 0; i < neg; i++)
-                        tmpA[i] = alpSrcPtr[neg];
-                    for (; i < end; i++)
-                        tmpA[i] = alpSrcPtr[i];
-                    for (; i < vLumFilterSize; i++)
-                        tmpA[i] = tmpA[i - 1];
-                    alpSrcPtr = tmpA;
-                }
-            }
-            if (firstChrSrcY < 0 ||
-                firstChrSrcY + vChrFilterSize > c->chrSrcH) {
-                const int16_t **tmpU = (const int16_t **)chrUPixBuf + 2 * vChrBufSize,
-                **tmpV               = (const int16_t **)chrVPixBuf + 2 * vChrBufSize;
-                int neg = -firstChrSrcY, i;
-                int end = FFMIN(c->chrSrcH - firstChrSrcY, vChrFilterSize);
-                for (i = 0; i < neg; i++) {
-                    tmpU[i] = chrUSrcPtr[neg];
-                    tmpV[i] = chrVSrcPtr[neg];
-                }
-                for (; i < end; i++) {
-                    tmpU[i] = chrUSrcPtr[i];
-                    tmpV[i] = chrVSrcPtr[i];
-                }
-                for (; i < vChrFilterSize; i++) {
-                    tmpU[i] = tmpU[i - 1];
-                    tmpV[i] = tmpV[i - 1];
-                }
-                chrUSrcPtr = tmpU;
-                chrVSrcPtr = tmpV;
-            }
+                                         (const int16_t **)(void*) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
+            int16_t *vLumFilter = c->vLumFilter;
+            int16_t *vChrFilter = c->vChrFilter;
 
             if (isPlanarYUV(dstFormat) ||
                 (isGray(dstFormat) && !isALPHA(dstFormat))) { // YV12 like
                 const int chrSkipMask = (1 << c->chrDstVSubSample) - 1;
 
+                vLumFilter +=    dstY * vLumFilterSize;
+                vChrFilter += chrDstY * vChrFilterSize;
+
+//                 av_assert0(use_mmx_vfilter != (
+//                                yuv2planeX == yuv2planeX_10BE_c
+//                             || yuv2planeX == yuv2planeX_10LE_c
+//                             || yuv2planeX == yuv2planeX_9BE_c
+//                             || yuv2planeX == yuv2planeX_9LE_c
+//                             || yuv2planeX == yuv2planeX_16BE_c
+//                             || yuv2planeX == yuv2planeX_16LE_c
+//                             || yuv2planeX == yuv2planeX_8_c) || !ARCH_X86);
+
+                if(use_mmx_vfilter){
+                    vLumFilter= c->lumMmxFilter;
+                    vChrFilter= c->chrMmxFilter;
+                }
+
                 if (vLumFilterSize == 1) {
                     yuv2plane1(lumSrcPtr[0], dest[0], dstW, c->lumDither8, 0);
                 } else {
-                    yuv2planeX(vLumFilter + dstY * vLumFilterSize,
-                               vLumFilterSize, lumSrcPtr, dest[0],
+                    yuv2planeX(vLumFilter, vLumFilterSize,
+                               lumSrcPtr, dest[0],
                                dstW, c->lumDither8, 0);
                 }
 
                 if (!((dstY & chrSkipMask) || isGray(dstFormat))) {
                     if (yuv2nv12cX) {
-                        yuv2nv12cX(c, vChrFilter + chrDstY * vChrFilterSize,
+                        yuv2nv12cX(c, vChrFilter,
                                    vChrFilterSize, chrUSrcPtr, chrVSrcPtr,
                                    dest[1], chrDstW);
                     } else if (vChrFilterSize == 1) {
                         yuv2plane1(chrUSrcPtr[0], dest[1], chrDstW, c->chrDither8, 0);
                         yuv2plane1(chrVSrcPtr[0], dest[2], chrDstW, c->chrDither8, 3);
                     } else {
-                        yuv2planeX(vChrFilter + chrDstY * vChrFilterSize,
+                        yuv2planeX(vChrFilter,
                                    vChrFilterSize, chrUSrcPtr, dest[1],
                                    chrDstW, c->chrDither8, 0);
-                        yuv2planeX(vChrFilter + chrDstY * vChrFilterSize,
+                        yuv2planeX(vChrFilter,
                                    vChrFilterSize, chrVSrcPtr, dest[2],
-                                   chrDstW, c->chrDither8, 3);
+                                   chrDstW, c->chrDither8, use_mmx_vfilter ? (c->uv_offx2 >> 1) : 3);
                     }
                 }
 
                 if (CONFIG_SWSCALE_ALPHA && alpPixBuf) {
+                    if(use_mmx_vfilter){
+                        vLumFilter= c->alpMmxFilter;
+                    }
                     if (vLumFilterSize == 1) {
                         yuv2plane1(alpSrcPtr[0], dest[3], dstW,
                                    c->lumDither8, 0);
                     } else {
-                        yuv2planeX(vLumFilter + dstY * vLumFilterSize,
+                        yuv2planeX(vLumFilter,
                                    vLumFilterSize, alpSrcPtr, dest[3],
                                    dstW, c->lumDither8, 0);
                     }
                 }
             } else {
+                av_assert1(lumSrcPtr  + vLumFilterSize - 1 < lumPixBuf  + vLumBufSize * 2);
+                av_assert1(chrUSrcPtr + vChrFilterSize - 1 < chrUPixBuf + vChrBufSize * 2);
                 if (c->yuv2packed1 && vLumFilterSize == 1 &&
                     vChrFilterSize <= 2) { // unscaled RGB
                     int chrAlpha = vChrFilterSize == 1 ? 0 : vChrFilter[2 * dstY + 1];
@@ -687,8 +689,9 @@
 
     ff_sws_init_input_funcs(c);
 
+
     if (c->srcBpc == 8) {
-        if (c->dstBpc <= 10) {
+        if (c->dstBpc <= 14) {
             c->hyScale = c->hcScale = hScale8To15_c;
             if (c->flags & SWS_FAST_BILINEAR) {
                 c->hyscale_fast = hyscale_fast_c;
@@ -698,12 +701,12 @@
             c->hyScale = c->hcScale = hScale8To19_c;
         }
     } else {
-        c->hyScale = c->hcScale = c->dstBpc > 10 ? hScale16To19_c
+        c->hyScale = c->hcScale = c->dstBpc > 14 ? hScale16To19_c
                                                  : hScale16To15_c;
     }
 
     if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
-        if (c->dstBpc <= 10) {
+        if (c->dstBpc <= 14) {
             if (c->srcRange) {
                 c->lumConvertRange = lumRangeFromJpeg_c;
                 c->chrConvertRange = chrRangeFromJpeg_c;
@@ -738,3 +741,204 @@
 
     return swScale;
 }
+
+static void reset_ptr(const uint8_t *src[], int format)
+{
+    if (!isALPHA(format))
+        src[3] = NULL;
+    if (!isPlanar(format)) {
+        src[3] = src[2] = NULL;
+
+        if (!usePal(format))
+            src[1] = NULL;
+    }
+}
+
+static int check_image_pointers(const uint8_t * const data[4], enum AVPixelFormat pix_fmt,
+                                const int linesizes[4])
+{
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+    int i;
+
+    for (i = 0; i < 4; i++) {
+        int plane = desc->comp[i].plane;
+        if (!data[plane] || !linesizes[plane])
+            return 0;
+    }
+
+    return 1;
+}
+
+/**
+ * swscale wrapper, so we don't need to export the SwsContext.
+ * Assumes planar YUV to be in YUV order instead of YVU.
+ */
+int attribute_align_arg sws_scale(struct SwsContext *c,
+                                  const uint8_t * const srcSlice[],
+                                  const int srcStride[], int srcSliceY,
+                                  int srcSliceH, uint8_t *const dst[],
+                                  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] };
+    uint8_t *rgb0_tmp = NULL;
+
+    // do not mess up sliceDir if we have a "trailing" 0-size slice
+    if (srcSliceH == 0)
+        return 0;
+
+    if (!check_image_pointers(srcSlice, c->srcFormat, srcStride)) {
+        av_log(c, AV_LOG_ERROR, "bad src image pointers\n");
+        return 0;
+    }
+    if (!check_image_pointers((const uint8_t* const*)dst, c->dstFormat, dstStride)) {
+        av_log(c, AV_LOG_ERROR, "bad dst image pointers\n");
+        return 0;
+    }
+
+    if (c->sliceDir == 0 && srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
+        av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n");
+        return 0;
+    }
+    if (c->sliceDir == 0) {
+        if (srcSliceY == 0) c->sliceDir = 1; else c->sliceDir = -1;
+    }
+
+    if (usePal(c->srcFormat)) {
+        for (i = 0; i < 256; i++) {
+            int p, r, g, b, y, u, v, a = 0xff;
+            if (c->srcFormat == AV_PIX_FMT_PAL8) {
+                p = ((const uint32_t *)(srcSlice[1]))[i];
+                a = (p >> 24) & 0xFF;
+                r = (p >> 16) & 0xFF;
+                g = (p >>  8) & 0xFF;
+                b =  p        & 0xFF;
+            } else if (c->srcFormat == AV_PIX_FMT_RGB8) {
+                r = ( i >> 5     ) * 36;
+                g = ((i >> 2) & 7) * 36;
+                b = ( i       & 3) * 85;
+            } else if (c->srcFormat == AV_PIX_FMT_BGR8) {
+                b = ( i >> 6     ) * 85;
+                g = ((i >> 3) & 7) * 36;
+                r = ( i       & 7) * 36;
+            } else if (c->srcFormat == AV_PIX_FMT_RGB4_BYTE) {
+                r = ( i >> 3     ) * 255;
+                g = ((i >> 1) & 3) * 85;
+                b = ( i       & 1) * 255;
+            } else if (c->srcFormat == AV_PIX_FMT_GRAY8 || c->srcFormat == AV_PIX_FMT_GRAY8A) {
+                r = g = b = i;
+            } else {
+                av_assert1(c->srcFormat == AV_PIX_FMT_BGR4_BYTE);
+                b = ( i >> 3     ) * 255;
+                g = ((i >> 1) & 3) * 85;
+                r = ( i       & 1) * 255;
+            }
+#define RGB2YUV_SHIFT 15
+#define BY ( (int) (0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define BV (-(int) (0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define BU ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define GY ( (int) (0.587 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define GV (-(int) (0.419 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define GU (-(int) (0.331 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define RY ( (int) (0.299 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define RV ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+#define RU (-(int) (0.169 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
+
+            y = av_clip_uint8((RY * r + GY * g + BY * b + ( 33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
+            u = av_clip_uint8((RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
+            v = av_clip_uint8((RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
+            c->pal_yuv[i]= y + (u<<8) + (v<<16) + (a<<24);
+
+            switch (c->dstFormat) {
+            case AV_PIX_FMT_BGR32:
+#if !HAVE_BIGENDIAN
+            case AV_PIX_FMT_RGB24:
+#endif
+                c->pal_rgb[i]=  r + (g<<8) + (b<<16) + (a<<24);
+                break;
+            case AV_PIX_FMT_BGR32_1:
+#if HAVE_BIGENDIAN
+            case AV_PIX_FMT_BGR24:
+#endif
+                c->pal_rgb[i]= a + (r<<8) + (g<<16) + (b<<24);
+                break;
+            case AV_PIX_FMT_RGB32_1:
+#if HAVE_BIGENDIAN
+            case AV_PIX_FMT_RGB24:
+#endif
+                c->pal_rgb[i]= a + (b<<8) + (g<<16) + (r<<24);
+                break;
+            case AV_PIX_FMT_RGB32:
+#if !HAVE_BIGENDIAN
+            case AV_PIX_FMT_BGR24:
+#endif
+            default:
+                c->pal_rgb[i]=  b + (g<<8) + (r<<16) + (a<<24);
+            }
+        }
+    }
+
+    if (c->src0Alpha && !c->dst0Alpha && isALPHA(c->dstFormat)) {
+        uint8_t *base;
+        int x,y;
+        rgb0_tmp = av_malloc(FFABS(srcStride[0]) * srcSliceH + 32);
+        base = srcStride[0] < 0 ? rgb0_tmp - srcStride[0] * (srcSliceH-1) : rgb0_tmp;
+        for (y=0; y<srcSliceH; y++){
+            memcpy(base + srcStride[0]*y, src2[0] + srcStride[0]*y, 4*c->srcW);
+            for (x=c->src0Alpha-1; x<4*c->srcW; x+=4) {
+                base[ srcStride[0]*y + x] = 0xFF;
+            }
+        }
+        src2[0] = base;
+    }
+
+    // copy strides, so they can safely be modified
+    if (c->sliceDir == 1) {
+        // slices go from top to bottom
+        int srcStride2[4] = { srcStride[0], srcStride[1], srcStride[2],
+                              srcStride[3] };
+        int dstStride2[4] = { dstStride[0], dstStride[1], dstStride[2],
+                              dstStride[3] };
+
+        reset_ptr(src2, c->srcFormat);
+        reset_ptr((void*)dst2, c->dstFormat);
+
+        /* reset slice direction at end of frame */
+        if (srcSliceY + srcSliceH == c->srcH)
+            c->sliceDir = 0;
+
+        ret = c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2,
+                          dstStride2);
+    } else {
+        // slices go from bottom to top => we flip the image internally
+        int srcStride2[4] = { -srcStride[0], -srcStride[1], -srcStride[2],
+                              -srcStride[3] };
+        int dstStride2[4] = { -dstStride[0], -dstStride[1], -dstStride[2],
+                              -dstStride[3] };
+
+        src2[0] += (srcSliceH - 1) * srcStride[0];
+        if (!usePal(c->srcFormat))
+            src2[1] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[1];
+        src2[2] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[2];
+        src2[3] += (srcSliceH - 1) * srcStride[3];
+        dst2[0] += ( c->dstH                         - 1) * dstStride[0];
+        dst2[1] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[1];
+        dst2[2] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[2];
+        dst2[3] += ( c->dstH                         - 1) * dstStride[3];
+
+        reset_ptr(src2, c->srcFormat);
+        reset_ptr((void*)dst2, c->dstFormat);
+
+        /* reset slice direction at end of frame */
+        if (!srcSliceY)
+            c->sliceDir = 0;
+
+        ret = c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH,
+                          srcSliceH, dst2, dstStride2);
+    }
+
+    av_free(rgb0_tmp);
+    return ret;
+}
+
diff --git a/libswscale/swscale.h b/libswscale/swscale.h
index 598946d..ea2116c 100644
--- a/libswscale/swscale.h
+++ b/libswscale/swscale.h
@@ -1,20 +1,20 @@
 /*
- * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2001-2011 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -217,7 +217,13 @@
               uint8_t *const dst[], const int dstStride[]);
 
 /**
- * @param inv_table the yuv2rgb coefficients, normally ff_yuv2rgb_coeffs[x]
+ * @param dstRange flag indicating the while-black range of the output (1=jpeg / 0=mpeg)
+ * @param srcRange flag indicating the while-black range of the input (1=jpeg / 0=mpeg)
+ * @param table the yuv2rgb coefficients describing the output yuv space, normally ff_yuv2rgb_coeffs[x]
+ * @param inv_table the yuv2rgb coefficients describing the input yuv space, normally ff_yuv2rgb_coeffs[x]
+ * @param brightness 16.16 fixed point brightness correction
+ * @param contrast 16.16 fixed point contrast correction
+ * @param saturation 16.16 fixed point saturation correction
  * @return -1 if not supported
  */
 int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4],
diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
index 011626a..9a7baab 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -1,20 +1,20 @@
 /*
- * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2001-2011 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -36,10 +36,14 @@
 
 #define STR(s) AV_TOSTRING(s) // AV_STRINGIFY is too long
 
+#define YUVRGB_TABLE_HEADROOM 128
+
 #define FAST_BGR2YV12 // use 7-bit instead of 15-bit coefficients
 
 #define MAX_FILTER_SIZE 256
 
+#define DITHER1XBPP
+
 #if HAVE_BIGENDIAN
 #define ALT32_CORR (-1)
 #else
@@ -317,10 +321,10 @@
     int dstY;                     ///< Last destination vertical line output from last slice.
     int flags;                    ///< Flags passed by the user to select scaler algorithm, optimizations, subsampling, etc...
     void *yuvTable;             // pointer to the yuv->rgb table start so it can be freed()
-    uint8_t *table_rV[256];
-    uint8_t *table_gU[256];
-    int table_gV[256];
-    uint8_t *table_bU[256];
+    uint8_t *table_rV[256 + 2*YUVRGB_TABLE_HEADROOM];
+    uint8_t *table_gU[256 + 2*YUVRGB_TABLE_HEADROOM];
+    int table_gV[256 + 2*YUVRGB_TABLE_HEADROOM];
+    uint8_t *table_bU[256 + 2*YUVRGB_TABLE_HEADROOM];
 
     //Colorspace stuff
     int contrast, brightness, saturation;    // for sws_getColorspaceDetails
@@ -328,6 +332,8 @@
     int dstColorspaceTable[4];
     int srcRange;                 ///< 0 = MPG YUV range, 1 = JPG YUV range (source      image).
     int dstRange;                 ///< 0 = MPG YUV range, 1 = JPG YUV range (destination image).
+    int src0Alpha;
+    int dst0Alpha;
     int yuv2rgb_y_offset;
     int yuv2rgb_y_coeff;
     int yuv2rgb_v2r_coeff;
@@ -384,8 +390,8 @@
     // alignment of these values is not necessary, but merely here
     // to maintain the same offset across x8632 and x86-64. Once we
     // use proper offset macros in the asm, they can be removed.
-    DECLARE_ALIGNED(8, ptrdiff_t, uv_off_px);   ///< offset (in pixels) between u and v planes
-    DECLARE_ALIGNED(8, ptrdiff_t, uv_off_byte); ///< offset (in bytes) between u and v planes
+    DECLARE_ALIGNED(8, ptrdiff_t, uv_off); ///< offset (in pixels) between u and v planes
+    DECLARE_ALIGNED(8, ptrdiff_t, uv_offx2); ///< offset (in bytes) between u and v planes
     DECLARE_ALIGNED(8, uint16_t, dither16)[8];
     DECLARE_ALIGNED(8, uint32_t, dither32)[8];
 
@@ -419,6 +425,7 @@
 #if HAVE_VIS
     DECLARE_ALIGNED(8, uint64_t, sparc_coeffs)[10];
 #endif
+    int use_mmx_vfilter;
 
     /* function pointers for swScale() */
     yuv2planar1_fn yuv2plane1;
@@ -429,14 +436,14 @@
     yuv2packedX_fn yuv2packedX;
 
     /// Unscaled conversion of luma plane to YV12 for horizontal scaler.
-    void (*lumToYV12)(uint8_t *dst, const uint8_t *src,
+    void (*lumToYV12)(uint8_t *dst, const uint8_t *src, const uint8_t *src2, const uint8_t *src3,
                       int width, uint32_t *pal);
     /// Unscaled conversion of alpha plane to YV12 for horizontal scaler.
-    void (*alpToYV12)(uint8_t *dst, const uint8_t *src,
+    void (*alpToYV12)(uint8_t *dst, const uint8_t *src, const uint8_t *src2, const uint8_t *src3,
                       int width, uint32_t *pal);
     /// Unscaled conversion of chroma planes to YV12 for horizontal scaler.
     void (*chrToYV12)(uint8_t *dstU, uint8_t *dstV,
-                      const uint8_t *src1, const uint8_t *src2,
+                      const uint8_t *src1, const uint8_t *src2, const uint8_t *src3,
                       int width, uint32_t *pal);
 
     /**
@@ -541,7 +548,13 @@
 SwsFunc ff_yuv2rgb_get_func_ptr_bfin(SwsContext *c);
 void ff_bfin_get_unscaled_swscale(SwsContext *c);
 
+#if FF_API_SWS_FORMAT_NAME
+/**
+ * @deprecated Use av_get_pix_fmt_name() instead.
+ */
+attribute_deprecated
 const char *sws_format_name(enum AVPixelFormat format);
+#endif
 
 static av_always_inline int is16BPS(enum AVPixelFormat pix_fmt)
 {
@@ -554,9 +567,11 @@
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return desc->comp[0].depth_minus1 == 8 || desc->comp[0].depth_minus1 == 9;
+    return desc->comp[0].depth_minus1 >= 8 && desc->comp[0].depth_minus1 <= 13;
 }
 
+#define isNBPS(x) is9_OR_10BPS(x)
+
 static av_always_inline int isBE(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
@@ -597,9 +612,12 @@
      (x) == AV_PIX_FMT_GRAY16LE)
 #endif
 
-#define isRGBinInt(x)                  \
-    ((x) == AV_PIX_FMT_RGB48BE     ||  \
+#define isRGBinInt(x) \
+    (           \
+     (x) == AV_PIX_FMT_RGB48BE     ||  \
      (x) == AV_PIX_FMT_RGB48LE     ||  \
+     (x) == AV_PIX_FMT_RGBA64BE    ||  \
+     (x) == AV_PIX_FMT_RGBA64LE    ||  \
      (x) == AV_PIX_FMT_RGB32       ||  \
      (x) == AV_PIX_FMT_RGB32_1     ||  \
      (x) == AV_PIX_FMT_RGB24       ||  \
@@ -613,11 +631,14 @@
      (x) == AV_PIX_FMT_RGB4        ||  \
      (x) == AV_PIX_FMT_RGB4_BYTE   ||  \
      (x) == AV_PIX_FMT_MONOBLACK   ||  \
-     (x) == AV_PIX_FMT_MONOWHITE)
-
-#define isBGRinInt(x)                  \
-    ((x) == AV_PIX_FMT_BGR48BE     ||  \
+     (x) == AV_PIX_FMT_MONOWHITE   \
+    )
+#define isBGRinInt(x) \
+    (           \
+     (x) == AV_PIX_FMT_BGR48BE     ||  \
      (x) == AV_PIX_FMT_BGR48LE     ||  \
+     (x) == AV_PIX_FMT_BGRA64BE    ||  \
+     (x) == AV_PIX_FMT_BGRA64LE    ||  \
      (x) == AV_PIX_FMT_BGR32       ||  \
      (x) == AV_PIX_FMT_BGR32_1     ||  \
      (x) == AV_PIX_FMT_BGR24       ||  \
@@ -631,11 +652,34 @@
      (x) == AV_PIX_FMT_BGR4        ||  \
      (x) == AV_PIX_FMT_BGR4_BYTE   ||  \
      (x) == AV_PIX_FMT_MONOBLACK   ||  \
-     (x) == AV_PIX_FMT_MONOWHITE)
+     (x) == AV_PIX_FMT_MONOWHITE   \
+    )
 
-#define isAnyRGB(x)                    \
-    (isRGBinInt(x)              ||     \
-     isBGRinInt(x))
+#define isRGBinBytes(x) (           \
+           (x) == AV_PIX_FMT_RGB48BE     \
+        || (x) == AV_PIX_FMT_RGB48LE     \
+        || (x) == AV_PIX_FMT_RGBA64BE    \
+        || (x) == AV_PIX_FMT_RGBA64LE    \
+        || (x) == AV_PIX_FMT_RGBA        \
+        || (x) == AV_PIX_FMT_ARGB        \
+        || (x) == AV_PIX_FMT_RGB24       \
+    )
+#define isBGRinBytes(x) (           \
+           (x) == AV_PIX_FMT_BGR48BE     \
+        || (x) == AV_PIX_FMT_BGR48LE     \
+        || (x) == AV_PIX_FMT_BGRA64BE    \
+        || (x) == AV_PIX_FMT_BGRA64LE    \
+        || (x) == AV_PIX_FMT_BGRA        \
+        || (x) == AV_PIX_FMT_ABGR        \
+        || (x) == AV_PIX_FMT_BGR24       \
+    )
+
+#define isAnyRGB(x) \
+    (           \
+          isRGBinInt(x)       ||    \
+          isBGRinInt(x)       ||    \
+          (x)==AV_PIX_FMT_GBR24P     \
+    )
 
 static av_always_inline int isALPHA(enum AVPixelFormat pix_fmt)
 {
@@ -644,6 +688,16 @@
     return desc->nb_components == 2 || desc->nb_components == 4;
 }
 
+#if 1
+#define isPacked(x)         (       \
+           (x)==AV_PIX_FMT_PAL8        \
+        || (x)==AV_PIX_FMT_YUYV422     \
+        || (x)==AV_PIX_FMT_UYVY422     \
+        || (x)==AV_PIX_FMT_Y400A       \
+        ||  isRGBinInt(x)           \
+        ||  isBGRinInt(x)           \
+    )
+#else
 static av_always_inline int isPacked(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
@@ -652,6 +706,7 @@
             pix_fmt == AV_PIX_FMT_PAL8);
 }
 
+#endif
 static av_always_inline int isPlanar(enum AVPixelFormat pix_fmt)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
@@ -678,12 +733,14 @@
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
     av_assert0(desc);
-    return ((desc->flags & PIX_FMT_PAL) || (desc->flags & PIX_FMT_PSEUDOPAL) ||
-            pix_fmt == AV_PIX_FMT_Y400A);
+    return (desc->flags & PIX_FMT_PAL) || (desc->flags & PIX_FMT_PSEUDOPAL);
 }
 
 extern const uint64_t ff_dither4[2];
 extern const uint64_t ff_dither8[2];
+extern const uint8_t dithers[8][8][8];
+extern const uint16_t dither_scale[15][16];
+
 
 extern const AVClass sws_context_class;
 
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index 70eff72..76c9142 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -1,20 +1,20 @@
 /*
- * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2001-2011 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -23,7 +23,6 @@
 #include <math.h>
 #include <stdio.h>
 #include "config.h"
-#include <assert.h>
 #include "swscale.h"
 #include "swscale_internal.h"
 #include "rgb2rgb.h"
@@ -33,59 +32,101 @@
 #include "libavutil/mathematics.h"
 #include "libavutil/bswap.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/avassert.h"
 
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_1)[8][8] = {
-    {   0,  1,  0,  1,  0,  1,  0,  1,},
-    {   1,  0,  1,  0,  1,  0,  1,  0,},
-    {   0,  1,  0,  1,  0,  1,  0,  1,},
-    {   1,  0,  1,  0,  1,  0,  1,  0,},
-    {   0,  1,  0,  1,  0,  1,  0,  1,},
-    {   1,  0,  1,  0,  1,  0,  1,  0,},
-    {   0,  1,  0,  1,  0,  1,  0,  1,},
-    {   1,  0,  1,  0,  1,  0,  1,  0,},
-};
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_3)[8][8] = {
-    {   1,  2,  1,  2,  1,  2,  1,  2,},
-    {   3,  0,  3,  0,  3,  0,  3,  0,},
-    {   1,  2,  1,  2,  1,  2,  1,  2,},
-    {   3,  0,  3,  0,  3,  0,  3,  0,},
-    {   1,  2,  1,  2,  1,  2,  1,  2,},
-    {   3,  0,  3,  0,  3,  0,  3,  0,},
-    {   1,  2,  1,  2,  1,  2,  1,  2,},
-    {   3,  0,  3,  0,  3,  0,  3,  0,},
-};
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_64)[8][8] = {
-    {  18, 34, 30, 46, 17, 33, 29, 45,},
-    {  50,  2, 62, 14, 49,  1, 61, 13,},
-    {  26, 42, 22, 38, 25, 41, 21, 37,},
-    {  58, 10, 54,  6, 57,  9, 53,  5,},
-    {  16, 32, 28, 44, 19, 35, 31, 47,},
-    {  48,  0, 60, 12, 51,  3, 63, 15,},
-    {  24, 40, 20, 36, 27, 43, 23, 39,},
-    {  56,  8, 52,  4, 59, 11, 55,  7,},
-};
-extern const uint8_t dither_8x8_128[8][8];
-DECLARE_ALIGNED(8, const uint8_t, dither_8x8_256)[8][8] = {
-    {  72, 136, 120, 184,  68, 132, 116, 180,},
-    { 200,   8, 248,  56, 196,   4, 244,  52,},
-    { 104, 168,  88, 152, 100, 164,  84, 148,},
-    { 232,  40, 216,  24, 228,  36, 212,  20,},
-    {  64, 128, 102, 176,  76, 140, 124, 188,},
-    { 192,   0, 240,  48, 204,  12, 252,  60,},
-    {  96, 160,  80, 144, 108, 172,  92, 156,},
-    { 224,  32, 208,  16, 236,  44, 220,  28,},
+DECLARE_ALIGNED(8, const uint8_t, dithers)[8][8][8]={
+{
+  {   0,  1,  0,  1,  0,  1,  0,  1,},
+  {   1,  0,  1,  0,  1,  0,  1,  0,},
+  {   0,  1,  0,  1,  0,  1,  0,  1,},
+  {   1,  0,  1,  0,  1,  0,  1,  0,},
+  {   0,  1,  0,  1,  0,  1,  0,  1,},
+  {   1,  0,  1,  0,  1,  0,  1,  0,},
+  {   0,  1,  0,  1,  0,  1,  0,  1,},
+  {   1,  0,  1,  0,  1,  0,  1,  0,},
+},{
+  {   1,  2,  1,  2,  1,  2,  1,  2,},
+  {   3,  0,  3,  0,  3,  0,  3,  0,},
+  {   1,  2,  1,  2,  1,  2,  1,  2,},
+  {   3,  0,  3,  0,  3,  0,  3,  0,},
+  {   1,  2,  1,  2,  1,  2,  1,  2,},
+  {   3,  0,  3,  0,  3,  0,  3,  0,},
+  {   1,  2,  1,  2,  1,  2,  1,  2,},
+  {   3,  0,  3,  0,  3,  0,  3,  0,},
+},{
+  {   2,  4,  3,  5,  2,  4,  3,  5,},
+  {   6,  0,  7,  1,  6,  0,  7,  1,},
+  {   3,  5,  2,  4,  3,  5,  2,  4,},
+  {   7,  1,  6,  0,  7,  1,  6,  0,},
+  {   2,  4,  3,  5,  2,  4,  3,  5,},
+  {   6,  0,  7,  1,  6,  0,  7,  1,},
+  {   3,  5,  2,  4,  3,  5,  2,  4,},
+  {   7,  1,  6,  0,  7,  1,  6,  0,},
+},{
+  {   4,  8,  7, 11,  4,  8,  7, 11,},
+  {  12,  0, 15,  3, 12,  0, 15,  3,},
+  {   6, 10,  5,  9,  6, 10,  5,  9,},
+  {  14,  2, 13,  1, 14,  2, 13,  1,},
+  {   4,  8,  7, 11,  4,  8,  7, 11,},
+  {  12,  0, 15,  3, 12,  0, 15,  3,},
+  {   6, 10,  5,  9,  6, 10,  5,  9,},
+  {  14,  2, 13,  1, 14,  2, 13,  1,},
+},{
+  {   9, 17, 15, 23,  8, 16, 14, 22,},
+  {  25,  1, 31,  7, 24,  0, 30,  6,},
+  {  13, 21, 11, 19, 12, 20, 10, 18,},
+  {  29,  5, 27,  3, 28,  4, 26,  2,},
+  {   8, 16, 14, 22,  9, 17, 15, 23,},
+  {  24,  0, 30,  6, 25,  1, 31,  7,},
+  {  12, 20, 10, 18, 13, 21, 11, 19,},
+  {  28,  4, 26,  2, 29,  5, 27,  3,},
+},{
+  {  18, 34, 30, 46, 17, 33, 29, 45,},
+  {  50,  2, 62, 14, 49,  1, 61, 13,},
+  {  26, 42, 22, 38, 25, 41, 21, 37,},
+  {  58, 10, 54,  6, 57,  9, 53,  5,},
+  {  16, 32, 28, 44, 19, 35, 31, 47,},
+  {  48,  0, 60, 12, 51,  3, 63, 15,},
+  {  24, 40, 20, 36, 27, 43, 23, 39,},
+  {  56,  8, 52,  4, 59, 11, 55,  7,},
+},{
+  {  18, 34, 30, 46, 17, 33, 29, 45,},
+  {  50,  2, 62, 14, 49,  1, 61, 13,},
+  {  26, 42, 22, 38, 25, 41, 21, 37,},
+  {  58, 10, 54,  6, 57,  9, 53,  5,},
+  {  16, 32, 28, 44, 19, 35, 31, 47,},
+  {  48,  0, 60, 12, 51,  3, 63, 15,},
+  {  24, 40, 20, 36, 27, 43, 23, 39,},
+  {  56,  8, 52,  4, 59, 11, 55,  7,},
+},{
+  {  36, 68, 60, 92, 34, 66, 58, 90,},
+  { 100,  4,124, 28, 98,  2,122, 26,},
+  {  52, 84, 44, 76, 50, 82, 42, 74,},
+  { 116, 20,108, 12,114, 18,106, 10,},
+  {  32, 64, 56, 88, 38, 70, 62, 94,},
+  {  96,  0,120, 24,102,  6,126, 30,},
+  {  48, 80, 40, 72, 54, 86, 46, 78,},
+  { 112, 16,104,  8,118, 22,110, 14,},
+}};
+
+const uint16_t dither_scale[15][16]={
+{    2,    3,    3,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,    5,},
+{    2,    3,    7,    7,   13,   13,   25,   25,   25,   25,   25,   25,   25,   25,   25,   25,},
+{    3,    3,    4,   15,   15,   29,   57,   57,   57,  113,  113,  113,  113,  113,  113,  113,},
+{    3,    4,    4,    5,   31,   31,   61,  121,  241,  241,  241,  241,  481,  481,  481,  481,},
+{    3,    4,    5,    5,    6,   63,   63,  125,  249,  497,  993,  993,  993,  993,  993, 1985,},
+{    3,    5,    6,    6,    6,    7,  127,  127,  253,  505, 1009, 2017, 4033, 4033, 4033, 4033,},
+{    3,    5,    6,    7,    7,    7,    8,  255,  255,  509, 1017, 2033, 4065, 8129,16257,16257,},
+{    3,    5,    6,    8,    8,    8,    8,    9,  511,  511, 1021, 2041, 4081, 8161,16321,32641,},
+{    3,    5,    7,    8,    9,    9,    9,    9,   10, 1023, 1023, 2045, 4089, 8177,16353,32705,},
+{    3,    5,    7,    8,   10,   10,   10,   10,   10,   11, 2047, 2047, 4093, 8185,16369,32737,},
+{    3,    5,    7,    8,   10,   11,   11,   11,   11,   11,   12, 4095, 4095, 8189,16377,32753,},
+{    3,    5,    7,    9,   10,   12,   12,   12,   12,   12,   12,   13, 8191, 8191,16381,32761,},
+{    3,    5,    7,    9,   10,   12,   13,   13,   13,   13,   13,   13,   14,16383,16383,32765,},
+{    3,    5,    7,    9,   10,   12,   14,   14,   14,   14,   14,   14,   14,   15,32767,32767,},
+{    3,    5,    7,    9,   11,   12,   14,   15,   15,   15,   15,   15,   15,   15,   16,65535,},
 };
 
-#define RGB2YUV_SHIFT 15
-#define BY ( (int) (0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
-#define BV (-(int) (0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
-#define BU ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
-#define GY ( (int) (0.587 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
-#define GV (-(int) (0.419 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
-#define GU (-(int) (0.331 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
-#define RY ( (int) (0.299 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
-#define RV ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
-#define RU (-(int) (0.169 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))
 
 static void fillPlane(uint8_t *plane, int stride, int width, int height, int y,
                       uint8_t val)
@@ -98,6 +139,20 @@
     }
 }
 
+static void fillPlane16(uint8_t *plane, int stride, int width, int height, int y,
+                      int alpha, int bits)
+{
+    int i, j;
+    uint8_t *ptr = plane + stride * y;
+    int v = alpha ? -1 : (1<<bits);
+    for (i = 0; i < height; i++) {
+        for (j = 0; j < width; j++) {
+            AV_WN16(ptr+2*j, v);
+        }
+        ptr += stride;
+    }
+}
+
 static void copyPlane(const uint8_t *src, int srcStride,
                       int srcSliceY, int srcSliceH, int width,
                       uint8_t *dst, int dstStride)
@@ -310,7 +365,7 @@
     uint8_t *dstPtr = dst[0] + dstStride[0] * srcSliceY;
     const uint8_t *srcPtr = src[0];
 
-    if (srcFormat == AV_PIX_FMT_Y400A) {
+    if (srcFormat == AV_PIX_FMT_GRAY8A) {
         switch (dstFormat) {
         case AV_PIX_FMT_RGB32  : conv = gray8aToPacked32; break;
         case AV_PIX_FMT_BGR32  : conv = gray8aToPacked32; break;
@@ -332,7 +387,7 @@
 
     if (!conv)
         av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
-               sws_format_name(srcFormat), sws_format_name(dstFormat));
+               av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
     else {
         for (i = 0; i < srcSliceH; i++) {
             conv(srcPtr, dstPtr, c->srcW, (uint8_t *) c->pal_rgb);
@@ -453,6 +508,20 @@
         || (x) == AV_PIX_FMT_ABGR   \
         )
 
+#define isRGBA64(x) (                \
+           (x) == AV_PIX_FMT_RGBA64LE   \
+        || (x) == AV_PIX_FMT_RGBA64BE   \
+        || (x) == AV_PIX_FMT_BGRA64LE   \
+        || (x) == AV_PIX_FMT_BGRA64BE   \
+        )
+
+#define isRGB48(x) (                \
+           (x) == AV_PIX_FMT_RGB48LE   \
+        || (x) == AV_PIX_FMT_RGB48BE   \
+        || (x) == AV_PIX_FMT_BGR48LE   \
+        || (x) == AV_PIX_FMT_BGR48BE   \
+        )
+
 /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
 typedef void (* rgbConvFn) (const uint8_t *, uint8_t *, int);
 static rgbConvFn findRgbConvFn(SwsContext *c)
@@ -469,10 +538,6 @@
     (((bpp + 7) >> 3) == 2 && \
      (!(desc->flags & PIX_FMT_BE) != !HAVE_BIGENDIAN))
 
-    /* if this is non-native rgb444/555/565, don't handle it here. */
-    if (IS_NOT_NE(srcId, desc_src) || IS_NOT_NE(dstId, desc_dst))
-        return NULL;
-
 #define CONV_IS(src, dst) (srcFormat == AV_PIX_FMT_##src && dstFormat == AV_PIX_FMT_##dst)
 
     if (isRGBA32(srcFormat) && isRGBA32(dstFormat)) {
@@ -488,6 +553,32 @@
               || CONV_IS(RGBA, BGRA)) conv = shuffle_bytes_2103;
         else if (CONV_IS(BGRA, ABGR)
               || CONV_IS(RGBA, ARGB)) conv = shuffle_bytes_3012;
+    } else if (isRGB48(srcFormat) && isRGB48(dstFormat)) {
+        if      (CONV_IS(RGB48LE, BGR48LE)
+              || CONV_IS(BGR48LE, RGB48LE)
+              || CONV_IS(RGB48BE, BGR48BE)
+              || CONV_IS(BGR48BE, RGB48BE)) conv = rgb48tobgr48_nobswap;
+        else if (CONV_IS(RGB48LE, BGR48BE)
+              || CONV_IS(BGR48LE, RGB48BE)
+              || CONV_IS(RGB48BE, BGR48LE)
+              || CONV_IS(BGR48BE, RGB48LE)) conv = rgb48tobgr48_bswap;
+    } else if (isRGBA64(srcFormat) && isRGB48(dstFormat)) {
+        if      (CONV_IS(RGBA64LE, BGR48LE)
+              || CONV_IS(BGRA64LE, RGB48LE)
+              || CONV_IS(RGBA64BE, BGR48BE)
+              || CONV_IS(BGRA64BE, RGB48BE)) conv = rgb64tobgr48_nobswap;
+        else if (CONV_IS(RGBA64LE, BGR48BE)
+              || CONV_IS(BGRA64LE, RGB48BE)
+              || CONV_IS(RGBA64BE, BGR48LE)
+              || CONV_IS(BGRA64BE, RGB48LE)) conv = rgb64tobgr48_bswap;
+        else if (CONV_IS(RGBA64LE, RGB48LE)
+              || CONV_IS(BGRA64LE, BGR48LE)
+              || CONV_IS(RGBA64BE, RGB48BE)
+              || CONV_IS(BGRA64BE, BGR48BE)) conv = rgb64to48_nobswap;
+        else if (CONV_IS(RGBA64LE, RGB48BE)
+              || CONV_IS(BGRA64LE, BGR48BE)
+              || CONV_IS(RGBA64BE, RGB48LE)
+              || CONV_IS(BGRA64BE, BGR48LE)) conv = rgb64to48_bswap;
     } else
     /* BGR -> BGR */
     if ((isBGRinInt(srcFormat) && isBGRinInt(dstFormat)) ||
@@ -540,16 +631,21 @@
 {
     const enum AVPixelFormat srcFormat = c->srcFormat;
     const enum AVPixelFormat dstFormat = c->dstFormat;
+    const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(c->dstFormat);
     const int srcBpp = (c->srcFormatBpp + 7) >> 3;
     const int dstBpp = (c->dstFormatBpp + 7) >> 3;
     rgbConvFn conv = findRgbConvFn(c);
 
     if (!conv) {
         av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
-               sws_format_name(srcFormat), sws_format_name(dstFormat));
+               av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
     } else {
         const uint8_t *srcPtr = src[0];
               uint8_t *dstPtr = dst[0];
+        int src_bswap = IS_NOT_NE(c->srcFormatBpp, desc_src);
+        int dst_bswap = IS_NOT_NE(c->dstFormatBpp, desc_dst);
+
         if ((srcFormat == AV_PIX_FMT_RGB32_1 || srcFormat == AV_PIX_FMT_BGR32_1) &&
             !isRGBA32(dstFormat))
             srcPtr += ALT32_CORR;
@@ -559,15 +655,23 @@
             dstPtr += ALT32_CORR;
 
         if (dstStride[0] * srcBpp == srcStride[0] * dstBpp && srcStride[0] > 0 &&
-            !(srcStride[0] % srcBpp))
+            !(srcStride[0] % srcBpp) && !dst_bswap && !src_bswap)
             conv(srcPtr, dstPtr + dstStride[0] * srcSliceY,
                  srcSliceH * srcStride[0]);
         else {
-            int i;
+            int i, j;
             dstPtr += dstStride[0] * srcSliceY;
 
             for (i = 0; i < srcSliceH; i++) {
-                conv(srcPtr, dstPtr, c->srcW * srcBpp);
+                if(src_bswap) {
+                    for(j=0; j<c->srcW; j++)
+                        ((uint16_t*)c->formatConvBuffer)[j] = av_bswap16(((uint16_t*)srcPtr)[j]);
+                    conv(c->formatConvBuffer, dstPtr, c->srcW * srcBpp);
+                }else
+                    conv(srcPtr, dstPtr, c->srcW * srcBpp);
+                if(dst_bswap)
+                    for(j=0; j<c->srcW; j++)
+                        ((uint16_t*)dstPtr)[j] = av_bswap16(((uint16_t*)dstPtr)[j]);
                 srcPtr += srcStride[0];
                 dstPtr += dstStride[0];
             }
@@ -625,7 +729,7 @@
         while (length + c->srcW <= FFABS(dstStride[0]) &&
                length + c->srcW <= FFABS(srcStride[0]))
             length += c->srcW;
-        assert(length != 0);
+        av_assert1(length != 0);
 
         for (i = 0; i < srcSliceH; i++) {
             memcpy(dstPtr, srcPtr, length);
@@ -636,25 +740,25 @@
     return srcSliceH;
 }
 
-#define clip9(x)  av_clip_uintp2(x,  9)
-#define clip10(x) av_clip_uintp2(x, 10)
-#define DITHER_COPY(dst, dstStride, wfunc, src, srcStride, rfunc, dithers, shift, clip) \
-    for (i = 0; i < height; i++) { \
-        const uint8_t *dither = dithers[i & 7]; \
-        for (j = 0; j < length - 7; j += 8) { \
-            wfunc(&dst[j + 0], clip((rfunc(&src[j + 0]) + dither[0]) >> shift)); \
-            wfunc(&dst[j + 1], clip((rfunc(&src[j + 1]) + dither[1]) >> shift)); \
-            wfunc(&dst[j + 2], clip((rfunc(&src[j + 2]) + dither[2]) >> shift)); \
-            wfunc(&dst[j + 3], clip((rfunc(&src[j + 3]) + dither[3]) >> shift)); \
-            wfunc(&dst[j + 4], clip((rfunc(&src[j + 4]) + dither[4]) >> shift)); \
-            wfunc(&dst[j + 5], clip((rfunc(&src[j + 5]) + dither[5]) >> shift)); \
-            wfunc(&dst[j + 6], clip((rfunc(&src[j + 6]) + dither[6]) >> shift)); \
-            wfunc(&dst[j + 7], clip((rfunc(&src[j + 7]) + dither[7]) >> shift)); \
-        } \
-        for (; j < length; j++) \
-            wfunc(&dst[j],     (rfunc(&src[j]) + dither[j & 7]) >> shift); \
-        dst += dstStride; \
-        src += srcStride; \
+#define DITHER_COPY(dst, dstStride, src, srcStride, bswap, dbswap)\
+    uint16_t scale= dither_scale[dst_depth-1][src_depth-1];\
+    int shift= src_depth-dst_depth + dither_scale[src_depth-2][dst_depth-1];\
+    for (i = 0; i < height; i++) {\
+        const uint8_t *dither= dithers[src_depth-9][i&7];\
+        for (j = 0; j < length-7; j+=8){\
+            dst[j+0] = dbswap((bswap(src[j+0]) + dither[0])*scale>>shift);\
+            dst[j+1] = dbswap((bswap(src[j+1]) + dither[1])*scale>>shift);\
+            dst[j+2] = dbswap((bswap(src[j+2]) + dither[2])*scale>>shift);\
+            dst[j+3] = dbswap((bswap(src[j+3]) + dither[3])*scale>>shift);\
+            dst[j+4] = dbswap((bswap(src[j+4]) + dither[4])*scale>>shift);\
+            dst[j+5] = dbswap((bswap(src[j+5]) + dither[5])*scale>>shift);\
+            dst[j+6] = dbswap((bswap(src[j+6]) + dither[6])*scale>>shift);\
+            dst[j+7] = dbswap((bswap(src[j+7]) + dither[7])*scale>>shift);\
+        }\
+        for (; j < length; j++)\
+            dst[j] = dbswap((bswap(src[j]) + dither[j&7])*scale>>shift);\
+        dst += dstStride;\
+        src += srcStride;\
     }
 
 static int planarCopyWrapper(SwsContext *c, const uint8_t *src[],
@@ -670,162 +774,126 @@
         int height = (plane == 0 || plane == 3) ? srcSliceH: -((-srcSliceH) >> c->chrDstVSubSample);
         const uint8_t *srcPtr = src[plane];
         uint8_t *dstPtr = dst[plane] + dstStride[plane] * y;
+        int shiftonly= plane==1 || plane==2 || (!c->srcRange && plane==0);
 
         if (!dst[plane])
             continue;
         // ignore palette for GRAY8
         if (plane == 1 && !dst[2]) continue;
         if (!src[plane] || (plane == 1 && !src[2])) {
-            if (is16BPS(c->dstFormat))
-                length *= 2;
-            fillPlane(dst[plane], dstStride[plane], length, height, y,
-                      (plane == 3) ? 255 : 128);
+            if (is16BPS(c->dstFormat) || isNBPS(c->dstFormat)) {
+                fillPlane16(dst[plane], dstStride[plane], length, height, y,
+                        plane == 3, desc_dst->comp[plane].depth_minus1);
+            } else {
+                fillPlane(dst[plane], dstStride[plane], length, height, y,
+                        (plane == 3) ? 255 : 128);
+            }
         } else {
-            if (is9_OR_10BPS(c->srcFormat)) {
+            if(isNBPS(c->srcFormat) || isNBPS(c->dstFormat)
+               || (is16BPS(c->srcFormat) != is16BPS(c->dstFormat))
+            ) {
                 const int src_depth = desc_src->comp[plane].depth_minus1 + 1;
                 const int dst_depth = desc_dst->comp[plane].depth_minus1 + 1;
                 const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;
+                uint16_t *dstPtr2 = (uint16_t*)dstPtr;
 
-                if (is16BPS(c->dstFormat)) {
-                    uint16_t *dstPtr2 = (uint16_t *) dstPtr;
-#define COPY9_OR_10TO16(rfunc, wfunc) \
-                    for (i = 0; i < height; i++) { \
-                        for (j = 0; j < length; j++) { \
-                            int srcpx = rfunc(&srcPtr2[j]); \
-                            wfunc(&dstPtr2[j], (srcpx << (16 - src_depth)) | (srcpx >> (2 * src_depth - 16))); \
-                        } \
-                        dstPtr2 += dstStride[plane] / 2; \
-                        srcPtr2 += srcStride[plane] / 2; \
-                    }
-                    if (isBE(c->dstFormat)) {
-                        if (isBE(c->srcFormat)) {
-                            COPY9_OR_10TO16(AV_RB16, AV_WB16);
-                        } else {
-                            COPY9_OR_10TO16(AV_RL16, AV_WB16);
-                        }
+                if (dst_depth == 8) {
+                    if(isBE(c->srcFormat) == HAVE_BIGENDIAN){
+                        DITHER_COPY(dstPtr, dstStride[plane], srcPtr2, srcStride[plane]/2, , )
                     } else {
-                        if (isBE(c->srcFormat)) {
-                            COPY9_OR_10TO16(AV_RB16, AV_WL16);
-                        } else {
-                            COPY9_OR_10TO16(AV_RL16, AV_WL16);
-                        }
+                        DITHER_COPY(dstPtr, dstStride[plane], srcPtr2, srcStride[plane]/2, av_bswap16, )
                     }
-                } else if (is9_OR_10BPS(c->dstFormat)) {
-                    uint16_t *dstPtr2 = (uint16_t *) dstPtr;
-#define COPY9_OR_10TO9_OR_10(loop) \
-                    for (i = 0; i < height; i++) { \
-                        for (j = 0; j < length; j++) { \
-                            loop; \
-                        } \
-                        dstPtr2 += dstStride[plane] / 2; \
-                        srcPtr2 += srcStride[plane] / 2; \
-                    }
-#define COPY9_OR_10TO9_OR_10_2(rfunc, wfunc) \
-                    if (dst_depth > src_depth) { \
-                        COPY9_OR_10TO9_OR_10(int srcpx = rfunc(&srcPtr2[j]); \
-                            wfunc(&dstPtr2[j], (srcpx << 1) | (srcpx >> 9))); \
-                    } else if (dst_depth < src_depth) { \
-                        DITHER_COPY(dstPtr2, dstStride[plane] / 2, wfunc, \
-                                    srcPtr2, srcStride[plane] / 2, rfunc, \
-                                    dither_8x8_1, 1, clip9); \
-                    } else { \
-                        COPY9_OR_10TO9_OR_10(wfunc(&dstPtr2[j], rfunc(&srcPtr2[j]))); \
-                    }
-                    if (isBE(c->dstFormat)) {
-                        if (isBE(c->srcFormat)) {
-                            COPY9_OR_10TO9_OR_10_2(AV_RB16, AV_WB16);
-                        } else {
-                            COPY9_OR_10TO9_OR_10_2(AV_RL16, AV_WB16);
+                } else if (src_depth == 8) {
+                    for (i = 0; i < height; i++) {
+                        #define COPY816(w)\
+                        if(shiftonly){\
+                            for (j = 0; j < length; j++)\
+                                w(&dstPtr2[j], srcPtr[j]<<(dst_depth-8));\
+                        }else{\
+                            for (j = 0; j < length; j++)\
+                                w(&dstPtr2[j], (srcPtr[j]<<(dst_depth-8)) |\
+                                               (srcPtr[j]>>(2*8-dst_depth)));\
                         }
-                    } else {
-                        if (isBE(c->srcFormat)) {
-                            COPY9_OR_10TO9_OR_10_2(AV_RB16, AV_WL16);
+                        if(isBE(c->dstFormat)){
+                            COPY816(AV_WB16)
                         } else {
-                            COPY9_OR_10TO9_OR_10_2(AV_RL16, AV_WL16);
+                            COPY816(AV_WL16)
                         }
+                        dstPtr2 += dstStride[plane]/2;
+                        srcPtr  += srcStride[plane];
+                    }
+                } else if (src_depth <= dst_depth) {
+                    int orig_length = length;
+                    for (i = 0; i < height; i++) {
+                        if(isBE(c->srcFormat) == HAVE_BIGENDIAN &&
+                           isBE(c->dstFormat) == HAVE_BIGENDIAN &&
+                           shiftonly) {
+                             unsigned shift = dst_depth - src_depth;
+                             length = orig_length;
+#if HAVE_FAST_64BIT
+#define FAST_COPY_UP(shift) \
+    for (j = 0; j < length - 3; j += 4) { \
+        uint64_t v = AV_RN64A(srcPtr2 + j); \
+        AV_WN64A(dstPtr2 + j, v << shift); \
+    } \
+    length &= 3;
+#else
+#define FAST_COPY_UP(shift) \
+    for (j = 0; j < length - 1; j += 2) { \
+        uint32_t v = AV_RN32A(srcPtr2 + j); \
+        AV_WN32A(dstPtr2 + j, v << shift); \
+    } \
+    length &= 1;
+#endif
+                             switch (shift)
+                             {
+                             case 6: FAST_COPY_UP(6); break;
+                             case 7: FAST_COPY_UP(7); break;
+                             }
+                        }
+#define COPY_UP(r,w) \
+    if(shiftonly){\
+        for (j = 0; j < length; j++){ \
+            unsigned int v= r(&srcPtr2[j]);\
+            w(&dstPtr2[j], v<<(dst_depth-src_depth));\
+        }\
+    }else{\
+        for (j = 0; j < length; j++){ \
+            unsigned int v= r(&srcPtr2[j]);\
+            w(&dstPtr2[j], (v<<(dst_depth-src_depth)) | \
+                        (v>>(2*src_depth-dst_depth)));\
+        }\
+    }
+                        if(isBE(c->srcFormat)){
+                            if(isBE(c->dstFormat)){
+                                COPY_UP(AV_RB16, AV_WB16)
+                            } else {
+                                COPY_UP(AV_RB16, AV_WL16)
+                            }
+                        } else {
+                            if(isBE(c->dstFormat)){
+                                COPY_UP(AV_RL16, AV_WB16)
+                            } else {
+                                COPY_UP(AV_RL16, AV_WL16)
+                            }
+                        }
+                        dstPtr2 += dstStride[plane]/2;
+                        srcPtr2 += srcStride[plane]/2;
                     }
                 } else {
-#define W8(a, b) { *(a) = (b); }
-#define COPY9_OR_10TO8(rfunc) \
-                    if (src_depth == 9) { \
-                        DITHER_COPY(dstPtr,  dstStride[plane],   W8, \
-                                    srcPtr2, srcStride[plane] / 2, rfunc, \
-                                    dither_8x8_1, 1, av_clip_uint8); \
-                    } else { \
-                        DITHER_COPY(dstPtr,  dstStride[plane],   W8, \
-                                    srcPtr2, srcStride[plane] / 2, rfunc, \
-                                    dither_8x8_3, 2, av_clip_uint8); \
-                    }
-                    if (isBE(c->srcFormat)) {
-                        COPY9_OR_10TO8(AV_RB16);
-                    } else {
-                        COPY9_OR_10TO8(AV_RL16);
-                    }
-                }
-            } else if (is9_OR_10BPS(c->dstFormat)) {
-                const int dst_depth = desc_dst->comp[plane].depth_minus1 + 1;
-                uint16_t *dstPtr2 = (uint16_t *) dstPtr;
-
-                if (is16BPS(c->srcFormat)) {
-                    const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;
-#define COPY16TO9_OR_10(rfunc, wfunc) \
-                    if (dst_depth == 9) { \
-                        DITHER_COPY(dstPtr2, dstStride[plane] / 2, wfunc, \
-                                    srcPtr2, srcStride[plane] / 2, rfunc, \
-                                    dither_8x8_128, 7, clip9); \
-                    } else { \
-                        DITHER_COPY(dstPtr2, dstStride[plane] / 2, wfunc, \
-                                    srcPtr2, srcStride[plane] / 2, rfunc, \
-                                    dither_8x8_64, 6, clip10); \
-                    }
-                    if (isBE(c->dstFormat)) {
-                        if (isBE(c->srcFormat)) {
-                            COPY16TO9_OR_10(AV_RB16, AV_WB16);
+                    if(isBE(c->srcFormat) == HAVE_BIGENDIAN){
+                        if(isBE(c->dstFormat) == HAVE_BIGENDIAN){
+                            DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, , )
                         } else {
-                            COPY16TO9_OR_10(AV_RL16, AV_WB16);
+                            DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, , av_bswap16)
                         }
-                    } else {
-                        if (isBE(c->srcFormat)) {
-                            COPY16TO9_OR_10(AV_RB16, AV_WL16);
+                    }else{
+                        if(isBE(c->dstFormat) == HAVE_BIGENDIAN){
+                            DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, av_bswap16, )
                         } else {
-                            COPY16TO9_OR_10(AV_RL16, AV_WL16);
+                            DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, av_bswap16, av_bswap16)
                         }
                     }
-                } else /* 8bit */ {
-#define COPY8TO9_OR_10(wfunc) \
-                    for (i = 0; i < height; i++) { \
-                        for (j = 0; j < length; j++) { \
-                            const int srcpx = srcPtr[j]; \
-                            wfunc(&dstPtr2[j], (srcpx << (dst_depth - 8)) | (srcpx >> (16 - dst_depth))); \
-                        } \
-                        dstPtr2 += dstStride[plane] / 2; \
-                        srcPtr  += srcStride[plane]; \
-                    }
-                    if (isBE(c->dstFormat)) {
-                        COPY8TO9_OR_10(AV_WB16);
-                    } else {
-                        COPY8TO9_OR_10(AV_WL16);
-                    }
-                }
-            } else if (is16BPS(c->srcFormat) && !is16BPS(c->dstFormat)) {
-                const uint16_t *srcPtr2 = (const uint16_t *) srcPtr;
-#define COPY16TO8(rfunc) \
-                    DITHER_COPY(dstPtr,  dstStride[plane],   W8, \
-                                srcPtr2, srcStride[plane] / 2, rfunc, \
-                                dither_8x8_256, 8, av_clip_uint8);
-                if (isBE(c->srcFormat)) {
-                    COPY16TO8(AV_RB16);
-                } else {
-                    COPY16TO8(AV_RL16);
-                }
-            } else if (!is16BPS(c->srcFormat) && is16BPS(c->dstFormat)) {
-                for (i = 0; i < height; i++) {
-                    for (j = 0; j < length; j++) {
-                        dstPtr[ j << 1     ] = srcPtr[j];
-                        dstPtr[(j << 1) + 1] = srcPtr[j];
-                    }
-                    srcPtr += srcStride[plane];
-                    dstPtr += dstStride[plane];
                 }
             } else if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat) &&
                       isBE(c->srcFormat) != isBE(c->dstFormat)) {
@@ -903,28 +971,32 @@
         && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
         c->swScale= rgbToRgbWrapper;
 
-    if (isPlanarRGB(srcFormat) && isPackedRGB(dstFormat))
+#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))
         c->swScale = planarRgbToRgbWrapper;
 
     /* 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)  ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGRA64) ||
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR555) ||
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_BGR565) ||
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_GRAY16) ||
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB444) ||
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB48)  ||
+        IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGBA64) ||
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB555) ||
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, AV_PIX_FMT_RGB565))
         c->swScale = packed_16bpc_bswap;
 
-    if ((usePal(srcFormat) && (
-        dstFormat == AV_PIX_FMT_RGB32   ||
-        dstFormat == AV_PIX_FMT_RGB32_1 ||
-        dstFormat == AV_PIX_FMT_RGB24   ||
-        dstFormat == AV_PIX_FMT_BGR32   ||
-        dstFormat == AV_PIX_FMT_BGR32_1 ||
-        dstFormat == AV_PIX_FMT_BGR24)))
+    if (usePal(srcFormat) && isByteRGB(dstFormat))
         c->swScale = palToRgbWrapper;
 
     if (srcFormat == AV_PIX_FMT_YUV422P) {
@@ -955,13 +1027,14 @@
     if (srcFormat == AV_PIX_FMT_UYVY422 && dstFormat == AV_PIX_FMT_YUV422P)
         c->swScale = uyvyToYuv422Wrapper;
 
+#define isPlanarGray(x) (isGray(x) && (x) != AV_PIX_FMT_GRAY8A)
     /* simple copy */
     if ( srcFormat == dstFormat ||
         (srcFormat == AV_PIX_FMT_YUVA420P && dstFormat == AV_PIX_FMT_YUV420P) ||
         (srcFormat == AV_PIX_FMT_YUV420P && dstFormat == AV_PIX_FMT_YUVA420P) ||
-        (isPlanarYUV(srcFormat) && isGray(dstFormat)) ||
-        (isPlanarYUV(dstFormat) && isGray(srcFormat)) ||
-        (isGray(dstFormat) && isGray(srcFormat)) ||
+        (isPlanarYUV(srcFormat) && isPlanarGray(dstFormat)) ||
+        (isPlanarYUV(dstFormat) && isPlanarGray(srcFormat)) ||
+        (isPlanarGray(dstFormat) && isPlanarGray(srcFormat)) ||
         (isPlanarYUV(srcFormat) && isPlanarYUV(dstFormat) &&
          c->chrDstHSubSample == c->chrSrcHSubSample &&
          c->chrDstVSubSample == c->chrSrcVSubSample &&
@@ -980,177 +1053,6 @@
         ff_swscale_get_unscaled_altivec(c);
 }
 
-static void reset_ptr(const uint8_t *src[], int format)
-{
-    if (!isALPHA(format))
-        src[3] = NULL;
-    if (!isPlanar(format)) {
-        src[3] = src[2] = NULL;
-
-        if (!usePal(format))
-            src[1] = NULL;
-    }
-}
-
-static int check_image_pointers(uint8_t *data[4], enum AVPixelFormat pix_fmt,
-                                const int linesizes[4])
-{
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
-    int i;
-
-    for (i = 0; i < 4; i++) {
-        int plane = desc->comp[i].plane;
-        if (!data[plane] || !linesizes[plane])
-            return 0;
-    }
-
-    return 1;
-}
-
-/**
- * swscale wrapper, so we don't need to export the SwsContext.
- * Assumes planar YUV to be in YUV order instead of YVU.
- */
-int attribute_align_arg sws_scale(struct SwsContext *c,
-                                  const uint8_t * const srcSlice[],
-                                  const int srcStride[], int srcSliceY,
-                                  int srcSliceH, uint8_t *const dst[],
-                                  const int dstStride[])
-{
-    int i;
-    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] };
-
-    // do not mess up sliceDir if we have a "trailing" 0-size slice
-    if (srcSliceH == 0)
-        return 0;
-
-    if (!check_image_pointers(srcSlice, c->srcFormat, srcStride)) {
-        av_log(c, AV_LOG_ERROR, "bad src image pointers\n");
-        return 0;
-    }
-    if (!check_image_pointers(dst, c->dstFormat, dstStride)) {
-        av_log(c, AV_LOG_ERROR, "bad dst image pointers\n");
-        return 0;
-    }
-
-    if (c->sliceDir == 0 && srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {
-        av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n");
-        return 0;
-    }
-    if (c->sliceDir == 0) {
-        if (srcSliceY == 0) c->sliceDir = 1; else c->sliceDir = -1;
-    }
-
-    if (usePal(c->srcFormat)) {
-        for (i = 0; i < 256; i++) {
-            int p, r, g, b, y, u, v;
-            if (c->srcFormat == AV_PIX_FMT_PAL8) {
-                p = ((const uint32_t *)(srcSlice[1]))[i];
-                r = (p >> 16) & 0xFF;
-                g = (p >>  8) & 0xFF;
-                b =  p        & 0xFF;
-            } else if (c->srcFormat == AV_PIX_FMT_RGB8) {
-                r = ( i >> 5     ) * 36;
-                g = ((i >> 2) & 7) * 36;
-                b = ( i       & 3) * 85;
-            } else if (c->srcFormat == AV_PIX_FMT_BGR8) {
-                b = ( i >> 6     ) * 85;
-                g = ((i >> 3) & 7) * 36;
-                r = ( i       & 7) * 36;
-            } else if (c->srcFormat == AV_PIX_FMT_RGB4_BYTE) {
-                r = ( i >> 3     ) * 255;
-                g = ((i >> 1) & 3) * 85;
-                b = ( i       & 1) * 255;
-            } else if (c->srcFormat == AV_PIX_FMT_GRAY8 ||
-                      c->srcFormat == AV_PIX_FMT_Y400A) {
-                r = g = b = i;
-            } else {
-                assert(c->srcFormat == AV_PIX_FMT_BGR4_BYTE);
-                b = ( i >> 3     ) * 255;
-                g = ((i >> 1) & 3) * 85;
-                r = ( i       & 1) * 255;
-            }
-            y = av_clip_uint8((RY * r + GY * g + BY * b + ( 33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
-            u = av_clip_uint8((RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
-            v = av_clip_uint8((RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);
-            c->pal_yuv[i] = y + (u << 8) + (v << 16);
-
-            switch (c->dstFormat) {
-            case AV_PIX_FMT_BGR32:
-#if !HAVE_BIGENDIAN
-            case AV_PIX_FMT_RGB24:
-#endif
-                c->pal_rgb[i] =  r + (g << 8) + (b << 16);
-                break;
-            case AV_PIX_FMT_BGR32_1:
-#if HAVE_BIGENDIAN
-            case AV_PIX_FMT_BGR24:
-#endif
-                c->pal_rgb[i] = (r + (g << 8) + (b << 16)) << 8;
-                break;
-            case AV_PIX_FMT_RGB32_1:
-#if HAVE_BIGENDIAN
-            case AV_PIX_FMT_RGB24:
-#endif
-                c->pal_rgb[i] = (b + (g << 8) + (r << 16)) << 8;
-                break;
-            case AV_PIX_FMT_RGB32:
-#if !HAVE_BIGENDIAN
-            case AV_PIX_FMT_BGR24:
-#endif
-            default:
-                c->pal_rgb[i] =  b + (g << 8) + (r << 16);
-            }
-        }
-    }
-
-    // copy strides, so they can safely be modified
-    if (c->sliceDir == 1) {
-        // slices go from top to bottom
-        int srcStride2[4] = { srcStride[0], srcStride[1], srcStride[2],
-                              srcStride[3] };
-        int dstStride2[4] = { dstStride[0], dstStride[1], dstStride[2],
-                              dstStride[3] };
-
-        reset_ptr(src2, c->srcFormat);
-        reset_ptr((const uint8_t **) dst2, c->dstFormat);
-
-        /* reset slice direction at end of frame */
-        if (srcSliceY + srcSliceH == c->srcH)
-            c->sliceDir = 0;
-
-        return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2,
-                          dstStride2);
-    } else {
-        // slices go from bottom to top => we flip the image internally
-        int srcStride2[4] = { -srcStride[0], -srcStride[1], -srcStride[2],
-                              -srcStride[3] };
-        int dstStride2[4] = { -dstStride[0], -dstStride[1], -dstStride[2],
-                              -dstStride[3] };
-
-        src2[0] += (srcSliceH - 1) * srcStride[0];
-        if (!usePal(c->srcFormat))
-            src2[1] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[1];
-        src2[2] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[2];
-        src2[3] += (srcSliceH - 1) * srcStride[3];
-        dst2[0] += ( c->dstH                         - 1) * dstStride[0];
-        dst2[1] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[1];
-        dst2[2] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[2];
-        dst2[3] += ( c->dstH                         - 1) * dstStride[3];
-
-        reset_ptr(src2, c->srcFormat);
-        reset_ptr((const uint8_t **) dst2, c->dstFormat);
-
-        /* reset slice direction at end of frame */
-        if (!srcSliceY)
-            c->sliceDir = 0;
-
-        return c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH,
-                          srcSliceH, dst2, dstStride2);
-    }
-}
-
 /* Convert the palette to the same packed 32-bit format as the palette */
 void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst,
                                    int num_pixels, const uint8_t *palette)
diff --git a/libswscale/utils.c b/libswscale/utils.c
index 4001606..3310d78 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -1,27 +1,27 @@
 /*
  * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include "config.h"
 
 #define _SVID_SOURCE // needed for MAP_ANONYMOUS
-#include <assert.h>
+#define _DARWIN_C_SOURCE // needed for MAP_ANON
 #include <inttypes.h>
 #include <math.h>
 #include <stdio.h>
@@ -38,6 +38,7 @@
 #endif
 
 #include "libavutil/attributes.h"
+#include "libavutil/avassert.h"
 #include "libavutil/avutil.h"
 #include "libavutil/bswap.h"
 #include "libavutil/cpu.h"
@@ -53,18 +54,19 @@
 
 unsigned swscale_version(void)
 {
+    av_assert0(LIBSWSCALE_VERSION_MICRO >= 100);
     return LIBSWSCALE_VERSION_INT;
 }
 
 const char *swscale_configuration(void)
 {
-    return LIBAV_CONFIGURATION;
+    return FFMPEG_CONFIGURATION;
 }
 
 const char *swscale_license(void)
 {
 #define LICENSE_PREFIX "libswscale license: "
-    return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+    return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
 }
 
 #define RET 0xC3 // near return opcode for x86
@@ -103,6 +105,10 @@
     [AV_PIX_FMT_RGBA]        = { 1, 1 },
     [AV_PIX_FMT_ABGR]        = { 1, 1 },
     [AV_PIX_FMT_BGRA]        = { 1, 1 },
+    [AV_PIX_FMT_0RGB]        = { 1, 1 },
+    [AV_PIX_FMT_RGB0]        = { 1, 1 },
+    [AV_PIX_FMT_0BGR]        = { 1, 1 },
+    [AV_PIX_FMT_BGR0]        = { 1, 1 },
     [AV_PIX_FMT_GRAY16BE]    = { 1, 1 },
     [AV_PIX_FMT_GRAY16LE]    = { 1, 1 },
     [AV_PIX_FMT_YUV440P]     = { 1, 1 },
@@ -112,6 +118,8 @@
     [AV_PIX_FMT_YUVA444P]    = { 1, 1 },
     [AV_PIX_FMT_RGB48BE]     = { 1, 1 },
     [AV_PIX_FMT_RGB48LE]     = { 1, 1 },
+    [AV_PIX_FMT_RGBA64BE]    = { 1, 0 },
+    [AV_PIX_FMT_RGBA64LE]    = { 1, 0 },
     [AV_PIX_FMT_RGB565BE]    = { 1, 1 },
     [AV_PIX_FMT_RGB565LE]    = { 1, 1 },
     [AV_PIX_FMT_RGB555BE]    = { 1, 1 },
@@ -133,23 +141,41 @@
     [AV_PIX_FMT_Y400A]       = { 1, 0 },
     [AV_PIX_FMT_BGR48BE]     = { 1, 1 },
     [AV_PIX_FMT_BGR48LE]     = { 1, 1 },
+    [AV_PIX_FMT_BGRA64BE]    = { 0, 0 },
+    [AV_PIX_FMT_BGRA64LE]    = { 0, 0 },
     [AV_PIX_FMT_YUV420P9BE]  = { 1, 1 },
     [AV_PIX_FMT_YUV420P9LE]  = { 1, 1 },
     [AV_PIX_FMT_YUV420P10BE] = { 1, 1 },
     [AV_PIX_FMT_YUV420P10LE] = { 1, 1 },
+    [AV_PIX_FMT_YUV420P12BE] = { 1, 1 },
+    [AV_PIX_FMT_YUV420P12LE] = { 1, 1 },
+    [AV_PIX_FMT_YUV420P14BE] = { 1, 1 },
+    [AV_PIX_FMT_YUV420P14LE] = { 1, 1 },
     [AV_PIX_FMT_YUV422P9BE]  = { 1, 1 },
     [AV_PIX_FMT_YUV422P9LE]  = { 1, 1 },
     [AV_PIX_FMT_YUV422P10BE] = { 1, 1 },
     [AV_PIX_FMT_YUV422P10LE] = { 1, 1 },
+    [AV_PIX_FMT_YUV422P12BE] = { 1, 1 },
+    [AV_PIX_FMT_YUV422P12LE] = { 1, 1 },
+    [AV_PIX_FMT_YUV422P14BE] = { 1, 1 },
+    [AV_PIX_FMT_YUV422P14LE] = { 1, 1 },
     [AV_PIX_FMT_YUV444P9BE]  = { 1, 1 },
     [AV_PIX_FMT_YUV444P9LE]  = { 1, 1 },
     [AV_PIX_FMT_YUV444P10BE] = { 1, 1 },
     [AV_PIX_FMT_YUV444P10LE] = { 1, 1 },
+    [AV_PIX_FMT_YUV444P12BE] = { 1, 1 },
+    [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_GBRP16LE]    = { 1, 0 },
     [AV_PIX_FMT_GBRP16BE]    = { 1, 0 },
 };
@@ -168,6 +194,7 @@
 
 extern const int32_t ff_yuv2rgb_coeffs[8][4];
 
+#if FF_API_SWS_FORMAT_NAME
 const char *sws_format_name(enum AVPixelFormat format)
 {
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format);
@@ -176,6 +203,7 @@
     else
         return "Unknown format";
 }
+#endif
 
 static double getSplineCoeff(double a, double b, double c, double d,
                              double dist)
@@ -194,7 +222,7 @@
                       int *outFilterSize, int xInc, int srcW, int dstW,
                       int filterAlign, int one, int flags, int cpu_flags,
                       SwsVector *srcFilter, SwsVector *dstFilter,
-                      double param[2], int is_horizontal)
+                      double param[2])
 {
     int i;
     int filterSize;
@@ -222,7 +250,7 @@
         }
     } else if (flags & SWS_POINT) { // lame looking point sampling mode
         int i;
-        int xDstInSrc;
+        int64_t xDstInSrc;
         filterSize = 1;
         FF_ALLOC_OR_GOTO(NULL, filter,
                          dstW * sizeof(*filter) * filterSize, fail);
@@ -238,7 +266,7 @@
     } else if ((xInc <= (1 << 16) && (flags & SWS_AREA)) ||
                (flags & SWS_FAST_BILINEAR)) { // bilinear upscale
         int i;
-        int xDstInSrc;
+        int64_t xDstInSrc;
         filterSize = 2;
         FF_ALLOC_OR_GOTO(NULL, filter,
                          dstW * sizeof(*filter) * filterSize, fail);
@@ -251,8 +279,7 @@
             (*filterPos)[i] = xx;
             // bilinear upscale / linear interpolate / area averaging
             for (j = 0; j < filterSize; j++) {
-                int64_t coeff = fone - FFABS((xx << 16) - xDstInSrc) *
-                                (fone >> 16);
+                int64_t coeff= fone - FFABS(((int64_t)xx<<16) - xDstInSrc)*(fone>>16);
                 if (coeff < 0)
                     coeff = 0;
                 filter[i * filterSize + j] = coeff;
@@ -281,8 +308,7 @@
         else if (flags & SWS_BILINEAR)
             sizeFactor = 2;
         else {
-            sizeFactor = 0;     // GCC warning killer
-            assert(0);
+            av_assert0(0);
         }
 
         if (xInc <= 1 << 16)
@@ -381,8 +407,7 @@
                     double p = -2.196152422706632;
                     coeff = getSplineCoeff(1.0, 0.0, p, -p - 1.0, floatd) * fone;
                 } else {
-                    coeff = 0.0; // GCC warning killer
-                    assert(0);
+                    av_assert0(0);
                 }
 
                 filter[i * filterSize + j] = coeff;
@@ -395,13 +420,13 @@
     /* apply src & dst Filter to filter -> filter2
      * av_free(filter);
      */
-    assert(filterSize > 0);
+    av_assert0(filterSize > 0);
     filter2Size = filterSize;
     if (srcFilter)
         filter2Size += srcFilter->length - 1;
     if (dstFilter)
         filter2Size += dstFilter->length - 1;
-    assert(filter2Size > 0);
+    av_assert0(filter2Size > 0);
     FF_ALLOCZ_OR_GOTO(NULL, filter2, filter2Size * dstW * sizeof(*filter2), fail);
 
     for (i = 0; i < dstW; i++) {
@@ -483,9 +508,9 @@
             filterAlign = 1;
     }
 
-    assert(minFilterSize > 0);
+    av_assert0(minFilterSize > 0);
     filterSize = (minFilterSize + (filterAlign - 1)) & (~(filterAlign - 1));
-    assert(filterSize > 0);
+    av_assert0(filterSize > 0);
     filter = av_malloc(filterSize * dstW * sizeof(*filter));
     if (filterSize >= MAX_FILTER_SIZE * 16 /
                       ((flags & SWS_ACCURATE_RND) ? APCK_SIZE : 16) || !filter)
@@ -513,29 +538,27 @@
     // FIXME try to align filterPos if possible
 
     // fix borders
-    if (is_horizontal) {
-        for (i = 0; i < dstW; i++) {
-            int j;
-            if ((*filterPos)[i] < 0) {
-                // move filter coefficients left to compensate for filterPos
-                for (j = 1; j < filterSize; j++) {
-                    int left = FFMAX(j + (*filterPos)[i], 0);
-                    filter[i * filterSize + left] += filter[i * filterSize + j];
-                    filter[i * filterSize + j]     = 0;
-                }
-                (*filterPos)[i] = 0;
+    for (i = 0; i < dstW; i++) {
+        int j;
+        if ((*filterPos)[i] < 0) {
+            // move filter coefficients left to compensate for filterPos
+            for (j = 1; j < filterSize; j++) {
+                int left = FFMAX(j + (*filterPos)[i], 0);
+                filter[i * filterSize + left] += filter[i * filterSize + j];
+                filter[i * filterSize + j]     = 0;
             }
+            (*filterPos)[i]= 0;
+        }
 
-            if ((*filterPos)[i] + filterSize > srcW) {
-                int shift = (*filterPos)[i] + filterSize - srcW;
-                // move filter coefficients right to compensate for filterPos
-                for (j = filterSize - 2; j >= 0; j--) {
-                    int right = FFMIN(j + shift, filterSize - 1);
-                    filter[i * filterSize + right] += filter[i * filterSize + j];
-                    filter[i * filterSize + j]      = 0;
-                }
-                (*filterPos)[i] = srcW - filterSize;
+        if ((*filterPos)[i] + filterSize > srcW) {
+            int shift = (*filterPos)[i] + filterSize - srcW;
+            // move filter coefficients right to compensate for filterPos
+            for (j = filterSize - 2; j >= 0; j--) {
+                int right = FFMIN(j + shift, filterSize - 1);
+                filter[i * filterSize + right] += filter[i * filterSize + j];
+                filter[i * filterSize + j]      = 0;
             }
+            (*filterPos)[i]= srcW - filterSize;
         }
     }
 
@@ -787,7 +810,7 @@
                              int *srcRange, int **table, int *dstRange,
                              int *brightness, int *contrast, int *saturation)
 {
-    if (isYUV(c->dstFormat) || isGray(c->dstFormat))
+    if (!c || isYUV(c->dstFormat) || isGray(c->dstFormat))
         return -1;
 
     *inv_table  = c->srcColorspaceTable;
@@ -821,6 +844,17 @@
     }
 }
 
+static int handle_0alpha(enum AVPixelFormat *format)
+{
+    switch (*format) {
+    case AV_PIX_FMT_0BGR    : *format = AV_PIX_FMT_ABGR   ; return 1;
+    case AV_PIX_FMT_BGR0    : *format = AV_PIX_FMT_BGRA   ; return 4;
+    case AV_PIX_FMT_0RGB    : *format = AV_PIX_FMT_ARGB   ; return 1;
+    case AV_PIX_FMT_RGB0    : *format = AV_PIX_FMT_RGBA   ; return 4;
+    default:                                          return 0;
+    }
+}
+
 SwsContext *sws_alloc_context(void)
 {
     SwsContext *c = av_mallocz(sizeof(SwsContext));
@@ -834,7 +868,7 @@
 av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
                              SwsFilter *dstFilter)
 {
-    int i;
+    int i, j;
     int usesVFilter, usesHFilter;
     int unscaled;
     SwsFilter dummyFilter = { NULL, NULL, NULL, NULL };
@@ -842,8 +876,7 @@
     int srcH              = c->srcH;
     int dstW              = c->dstW;
     int dstH              = c->dstH;
-    int dst_stride        = FFALIGN(dstW * sizeof(int16_t) + 16, 16);
-    int dst_stride_px     = dst_stride >> 1;
+    int dst_stride        = FFALIGN(dstW * sizeof(int16_t) + 66, 16);
     int flags, cpu_flags;
     enum AVPixelFormat srcFormat = c->srcFormat;
     enum AVPixelFormat dstFormat = c->dstFormat;
@@ -858,14 +891,25 @@
 
     unscaled = (srcW == dstW && srcH == dstH);
 
+    handle_jpeg(&srcFormat);
+    handle_jpeg(&dstFormat);
+    handle_0alpha(&srcFormat);
+    handle_0alpha(&dstFormat);
+
+    if(srcFormat!=c->srcFormat || dstFormat!=c->dstFormat){
+        av_log(c, AV_LOG_WARNING, "deprecated pixel format used, make sure you did set range correctly\n");
+        c->srcFormat= srcFormat;
+        c->dstFormat= dstFormat;
+    }
+
     if (!sws_isSupportedInput(srcFormat)) {
         av_log(c, AV_LOG_ERROR, "%s is not supported as input pixel format\n",
-               sws_format_name(srcFormat));
+               av_get_pix_fmt_name(srcFormat));
         return AVERROR(EINVAL);
     }
     if (!sws_isSupportedOutput(dstFormat)) {
         av_log(c, AV_LOG_ERROR, "%s is not supported as output pixel format\n",
-               sws_format_name(dstFormat));
+               av_get_pix_fmt_name(dstFormat));
         return AVERROR(EINVAL);
     }
 
@@ -881,8 +925,7 @@
                  SWS_SPLINE        |
                  SWS_BICUBLIN);
     if (!i || (i & (i - 1))) {
-        av_log(c, AV_LOG_ERROR,
-               "Exactly one scaler algorithm must be chosen\n");
+        av_log(c, AV_LOG_ERROR, "Exactly one scaler algorithm must be chosen, got %X\n", i);
         return AVERROR(EINVAL);
     }
     /* sanity check */
@@ -917,6 +960,14 @@
     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");
+            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 &&
@@ -927,9 +978,9 @@
         dstFormat != AV_PIX_FMT_ABGR  &&
         dstFormat != AV_PIX_FMT_RGB24 &&
         dstFormat != AV_PIX_FMT_BGR24) {
-        av_log(c, AV_LOG_ERROR,
+        av_log(c, AV_LOG_WARNING,
                "full chroma interpolation for destination format '%s' not yet implemented\n",
-               sws_format_name(dstFormat));
+               av_get_pix_fmt_name(dstFormat));
         flags   &= ~SWS_FULL_CHR_H_INT;
         c->flags = flags;
     }
@@ -957,6 +1008,8 @@
     c->chrDstW = -((-dstW) >> c->chrDstHSubSample);
     c->chrDstH = -((-dstH) >> c->chrDstVSubSample);
 
+    FF_ALLOC_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW*2+78, 16) * 2, fail);
+
     /* unscaled special cases */
     if (unscaled && !usesHFilter && !usesVFilter &&
         (c->srcRange == c->dstRange || isAnyRGB(dstFormat))) {
@@ -966,7 +1019,7 @@
             if (flags & SWS_PRINT_INFO)
                 av_log(c, AV_LOG_INFO,
                        "using unscaled %s -> %s special converter\n",
-                       sws_format_name(srcFormat), sws_format_name(dstFormat));
+                       av_get_pix_fmt_name(srcFormat), av_get_pix_fmt_name(dstFormat));
             return 0;
         }
     }
@@ -977,12 +1030,11 @@
     c->dstBpc = 1 + desc_dst->comp[0].depth_minus1;
     if (c->dstBpc < 8)
         c->dstBpc = 8;
+    if (isAnyRGB(srcFormat) || srcFormat == AV_PIX_FMT_PAL8)
+        c->srcBpc = 16;
     if (c->dstBpc == 16)
         dst_stride <<= 1;
-    FF_ALLOC_OR_GOTO(c, c->formatConvBuffer,
-                     (FFALIGN(srcW, 16) * 2 * FFALIGN(c->srcBpc, 8) >> 3) + 16,
-                     fail);
-    if (INLINE_MMXEXT(cpu_flags) && c->srcBpc == 8 && c->dstBpc <= 10) {
+    if (INLINE_MMXEXT(cpu_flags) && c->srcBpc == 8 && c->dstBpc <= 14) {
         c->canMMX2BeUsed = (dstW >= srcW && (dstW & 31) == 0 &&
                             (srcW & 15) == 0) ? 1 : 0;
         if (!c->canMMX2BeUsed && dstW >= srcW && (srcW & 15) == 0
@@ -991,8 +1043,8 @@
                 av_log(c, AV_LOG_INFO,
                        "output width is not a multiple of 32 -> no MMX2 scaler\n");
         }
-        if (usesHFilter)
-            c->canMMX2BeUsed = 0;
+        if (usesHFilter || isNBPS(c->srcFormat) || is16BPS(c->srcFormat) || isAnyRGB(c->srcFormat))
+            c->canMMX2BeUsed=0;
     } else
         c->canMMX2BeUsed = 0;
 
@@ -1012,7 +1064,7 @@
             c->chrXInc += 20;
         }
         // we don't use the x86 asm scaler if MMX is available
-        else if (INLINE_MMX(cpu_flags)) {
+        else if (INLINE_MMX(cpu_flags) && c->dstBpc <= 14) {
             c->lumXInc = ((int64_t)(srcW       - 2) << 16) / (dstW       - 2) - 20;
             c->chrXInc = ((int64_t)(c->chrSrcW - 2) << 16) / (c->chrDstW - 2) - 20;
         }
@@ -1039,17 +1091,25 @@
             c->chrMmx2FilterCode = av_malloc(c->chrMmx2FilterCodeSize);
 #endif
 
+#ifdef MAP_ANONYMOUS
+            if (c->lumMmx2FilterCode == MAP_FAILED || c->chrMmx2FilterCode == MAP_FAILED)
+#else
             if (!c->lumMmx2FilterCode || !c->chrMmx2FilterCode)
+#endif
+            {
+                av_log(c, AV_LOG_ERROR, "Failed to allocate MMX2FilterCode\n");
                 return AVERROR(ENOMEM);
+            }
+
             FF_ALLOCZ_OR_GOTO(c, c->hLumFilter,    (dstW           / 8 + 8) * sizeof(int16_t), fail);
             FF_ALLOCZ_OR_GOTO(c, c->hChrFilter,    (c->chrDstW     / 4 + 8) * sizeof(int16_t), fail);
             FF_ALLOCZ_OR_GOTO(c, c->hLumFilterPos, (dstW       / 2 / 8 + 8) * sizeof(int32_t), fail);
             FF_ALLOCZ_OR_GOTO(c, c->hChrFilterPos, (c->chrDstW / 2 / 4 + 8) * sizeof(int32_t), fail);
 
-            initMMX2HScaler(dstW, c->lumXInc, c->lumMmx2FilterCode,
-                            c->hLumFilter, c->hLumFilterPos, 8);
+            initMMX2HScaler(      dstW, c->lumXInc, c->lumMmx2FilterCode,
+                            c->hLumFilter, (uint32_t*)c->hLumFilterPos, 8);
             initMMX2HScaler(c->chrDstW, c->chrXInc, c->chrMmx2FilterCode,
-                            c->hChrFilter, c->hChrFilterPos, 4);
+                            c->hChrFilter, (uint32_t*)c->hChrFilterPos, 4);
 
 #ifdef MAP_ANONYMOUS
             mprotect(c->lumMmx2FilterCode, c->lumMmx2FilterCodeSize, PROT_EXEC | PROT_READ);
@@ -1068,14 +1128,14 @@
                            srcW, dstW, filterAlign, 1 << 14,
                            (flags & SWS_BICUBLIN) ? (flags | SWS_BICUBIC) : flags,
                            cpu_flags, srcFilter->lumH, dstFilter->lumH,
-                           c->param, 1) < 0)
+                           c->param) < 0)
                 goto fail;
             if (initFilter(&c->hChrFilter, &c->hChrFilterPos,
                            &c->hChrFilterSize, c->chrXInc,
                            c->chrSrcW, c->chrDstW, filterAlign, 1 << 14,
                            (flags & SWS_BICUBLIN) ? (flags | SWS_BILINEAR) : flags,
                            cpu_flags, srcFilter->chrH, dstFilter->chrH,
-                           c->param, 1) < 0)
+                           c->param) < 0)
                 goto fail;
         }
     } // initialize horizontal stuff
@@ -1091,14 +1151,14 @@
                        c->lumYInc, srcH, dstH, filterAlign, (1 << 12),
                        (flags & SWS_BICUBLIN) ? (flags | SWS_BICUBIC) : flags,
                        cpu_flags, srcFilter->lumV, dstFilter->lumV,
-                       c->param, 0) < 0)
+                       c->param) < 0)
             goto fail;
         if (initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize,
                        c->chrYInc, c->chrSrcH, c->chrDstH,
                        filterAlign, (1 << 12),
                        (flags & SWS_BICUBLIN) ? (flags | SWS_BILINEAR) : flags,
                        cpu_flags, srcFilter->chrV, dstFilter->chrV,
-                       c->param, 0) < 0)
+                       c->param) < 0)
             goto fail;
 
 #if HAVE_ALTIVEC
@@ -1155,9 +1215,9 @@
                           dst_stride + 16, fail);
         c->lumPixBuf[i] = c->lumPixBuf[i + c->vLumBufSize];
     }
-    // 64 / (c->dstBpc & ~7) is the same as 16 / sizeof(scaling_intermediate)
-    c->uv_off_px   = dst_stride_px + 64 / (c->dstBpc & ~7);
-    c->uv_off_byte = dst_stride + 16;
+    // 64 / c->scalingBpp is the same as 16 / sizeof(scaling_intermediate)
+    c->uv_off   = (dst_stride>>1) + 64 / (c->dstBpc &~ 7);
+    c->uv_offx2 = dst_stride + 16;
     for (i = 0; i < c->vChrBufSize; i++) {
         FF_ALLOC_OR_GOTO(c, c->chrUPixBuf[i + c->vChrBufSize],
                          dst_stride * 2 + 32, fail);
@@ -1174,9 +1234,15 @@
 
     // try to avoid drawing green stuff between the right end and the stride end
     for (i = 0; i < c->vChrBufSize; i++)
-        memset(c->chrUPixBuf[i], 64, dst_stride * 2 + 1);
+        if(desc_dst->comp[0].depth_minus1 == 15){
+            av_assert0(c->dstBpc > 14);
+            for(j=0; j<dst_stride/2+1; j++)
+                ((int32_t*)(c->chrUPixBuf[i]))[j] = 1<<18;
+        } else
+            for(j=0; j<dst_stride+1; j++)
+                ((int16_t*)(c->chrUPixBuf[i]))[j] = 1<<14;
 
-    assert(c->chrDstH <= dstH);
+    av_assert0(c->chrDstH <= dstH);
 
     if (flags & SWS_PRINT_INFO) {
         if (flags & SWS_FAST_BILINEAR)
@@ -1205,7 +1271,7 @@
             av_log(c, AV_LOG_INFO, "ehh flags invalid?! ");
 
         av_log(c, AV_LOG_INFO, "from %s to %s%s ",
-               sws_format_name(srcFormat),
+               av_get_pix_fmt_name(srcFormat),
 #ifdef DITHER1XBPP
                dstFormat == AV_PIX_FMT_BGR555   || dstFormat == AV_PIX_FMT_BGR565   ||
                dstFormat == AV_PIX_FMT_RGB444BE || dstFormat == AV_PIX_FMT_RGB444LE ||
@@ -1214,7 +1280,7 @@
 #else
                "",
 #endif
-               sws_format_name(dstFormat));
+               av_get_pix_fmt_name(dstFormat));
 
         if (INLINE_MMXEXT(cpu_flags))
             av_log(c, AV_LOG_INFO, "using MMX2\n");
@@ -1261,6 +1327,8 @@
     c->dstH      = dstH;
     c->srcRange  = handle_jpeg(&srcFormat);
     c->dstRange  = handle_jpeg(&dstFormat);
+    c->src0Alpha = handle_0alpha(&srcFormat);
+    c->dst0Alpha = handle_0alpha(&dstFormat);
     c->srcFormat = srcFormat;
     c->dstFormat = dstFormat;
 
@@ -1649,7 +1717,7 @@
 #endif /* HAVE_MMX_INLINE */
 
     av_freep(&c->yuvTable);
-    av_free(c->formatConvBuffer);
+    av_freep(&c->formatConvBuffer);
 
     av_free(c);
 }
@@ -1688,10 +1756,12 @@
         context->srcW      = srcW;
         context->srcH      = srcH;
         context->srcRange  = handle_jpeg(&srcFormat);
+        context->src0Alpha = handle_0alpha(&srcFormat);
         context->srcFormat = srcFormat;
         context->dstW      = dstW;
         context->dstH      = dstH;
         context->dstRange  = handle_jpeg(&dstFormat);
+        context->dst0Alpha = handle_0alpha(&dstFormat);
         context->dstFormat = dstFormat;
         context->flags     = flags;
         context->param[0]  = param[0];
diff --git a/libswscale/version.h b/libswscale/version.h
index acbdf6b..37dcc96 100644
--- a/libswscale/version.h
+++ b/libswscale/version.h
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -28,7 +28,7 @@
 
 #define LIBSWSCALE_VERSION_MAJOR 2
 #define LIBSWSCALE_VERSION_MINOR 1
-#define LIBSWSCALE_VERSION_MICRO 1
+#define LIBSWSCALE_VERSION_MICRO 101
 
 #define LIBSWSCALE_VERSION_INT  AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
                                                LIBSWSCALE_VERSION_MINOR, \
@@ -52,5 +52,8 @@
 #ifndef FF_API_SWS_CPU_CAPS
 #define FF_API_SWS_CPU_CAPS    (LIBSWSCALE_VERSION_MAJOR < 3)
 #endif
+#ifndef FF_API_SWS_FORMAT_NAME
+#define FF_API_SWS_FORMAT_NAME  (LIBSWSCALE_VERSION_MAJOR < 3)
+#endif
 
 #endif /* SWSCALE_VERSION_H */
diff --git a/libswscale/x86/Makefile b/libswscale/x86/Makefile
index 5416d48..7d219b4 100644
--- a/libswscale/x86/Makefile
+++ b/libswscale/x86/Makefile
@@ -1,3 +1,5 @@
+$(SUBDIR)x86/swscale_mmx.o: CFLAGS += $(NOREDZONE_FLAGS)
+
 OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o
 
 MMX-OBJS                        += x86/rgb2rgb.o                        \
diff --git a/libswscale/x86/input.asm b/libswscale/x86/input.asm
index 66d8845..0124c66 100644
--- a/libswscale/x86/input.asm
+++ b/libswscale/x86/input.asm
@@ -36,8 +36,8 @@
 %define GV 0xD0E3
 %define BV 0xF6E4
 
-rgb_Yrnd:        times 4 dd 0x84000        ;  16.5 << 15
-rgb_UVrnd:       times 4 dd 0x404000       ; 128.5 << 15
+rgb_Yrnd:        times 4 dd 0x80100        ;  16.5 << 15
+rgb_UVrnd:       times 4 dd 0x400100       ; 128.5 << 15
 bgr_Ycoeff_12x4: times 2 dw BY, GY, 0, BY
 bgr_Ycoeff_3x56: times 2 dw RY, 0, GY, RY
 rgb_Ycoeff_12x4: times 2 dw RY, GY, 0, RY
@@ -83,7 +83,7 @@
 ; %1 = nr. of XMM registers
 ; %2 = rgb or bgr
 %macro RGB24_TO_Y_FN 2-3
-cglobal %2 %+ 24ToY, 3, 3, %1, dst, src, w
+cglobal %2 %+ 24ToY, 6, 6, %1, dst, src, u1, u2, w, u3
 %if mmsize == 8
     mova           m5, [%2_Ycoeff_12x4]
     mova           m6, [%2_Ycoeff_3x56]
@@ -115,6 +115,7 @@
 %if ARCH_X86_64
     movsxd         wq, wd
 %endif
+    add            wq, wq
     add          dstq, wq
     neg            wq
 %if notcpuflag(ssse3)
@@ -158,12 +159,11 @@
     paddd          m2, m3                 ; (dword) { Bx*BY + Gx*GY + Rx*RY }[4-7]
     paddd          m0, m4                 ; += rgb_Yrnd, i.e. (dword) { Y[0-3] }
     paddd          m2, m4                 ; += rgb_Yrnd, i.e. (dword) { Y[4-7] }
-    psrad          m0, 15
-    psrad          m2, 15
+    psrad          m0, 9
+    psrad          m2, 9
     packssdw       m0, m2                 ; (word) { Y[0-7] }
-    packuswb       m0, m0                 ; (byte) { Y[0-7] }
-    movh    [dstq+wq], m0
-    add            wq, mmsize / 2
+    mova    [dstq+wq], m0
+    add            wq, mmsize
     jl .loop
     REP_RET
 %endif ; (ARCH_X86_64 && %0 == 3) || mmsize == 8
@@ -172,7 +172,7 @@
 ; %1 = nr. of XMM registers
 ; %2 = rgb or bgr
 %macro RGB24_TO_UV_FN 2-3
-cglobal %2 %+ 24ToUV, 3, 4, %1, dstU, dstV, src, w
+cglobal %2 %+ 24ToUV, 7, 7, %1, dstU, dstV, u1, src, u2, w, u3
 %if ARCH_X86_64
     mova           m8, [%2_Ucoeff_12x4]
     mova           m9, [%2_Ucoeff_3x56]
@@ -203,10 +203,11 @@
 %endif ; x86-32/64
 %endif ; cpuflag(ssse3)
 %if ARCH_X86_64
-    movsxd         wq, dword r4m
+    movsxd         wq, dword r5m
 %else ; x86-32
-    mov            wq, r4m
+    mov            wq, r5m
 %endif
+    add            wq, wq
     add         dstUq, wq
     add         dstVq, wq
     neg            wq
@@ -264,23 +265,20 @@
     paddd          m2, m6                 ; += rgb_UVrnd, i.e. (dword) { V[0-3] }
     paddd          m1, m6                 ; += rgb_UVrnd, i.e. (dword) { U[4-7] }
     paddd          m4, m6                 ; += rgb_UVrnd, i.e. (dword) { V[4-7] }
-    psrad          m0, 15
-    psrad          m2, 15
-    psrad          m1, 15
-    psrad          m4, 15
+    psrad          m0, 9
+    psrad          m2, 9
+    psrad          m1, 9
+    psrad          m4, 9
     packssdw       m0, m1                 ; (word) { U[0-7] }
     packssdw       m2, m4                 ; (word) { V[0-7] }
 %if mmsize == 8
-    packuswb       m0, m0                 ; (byte) { U[0-3] }
-    packuswb       m2, m2                 ; (byte) { V[0-3] }
-    movh   [dstUq+wq], m0
-    movh   [dstVq+wq], m2
+    mova   [dstUq+wq], m0
+    mova   [dstVq+wq], m2
 %else ; mmsize == 16
-    packuswb       m0, m2                 ; (byte) { U[0-7], V[0-7] }
-    movh   [dstUq+wq], m0
-    movhps [dstVq+wq], m0
+    mova   [dstUq+wq], m0
+    mova   [dstVq+wq], m2
 %endif ; mmsize == 8/16
-    add            wq, mmsize / 2
+    add            wq, mmsize
     jl .loop
     REP_RET
 %endif ; ARCH_X86_64 && %0 == 3
@@ -306,13 +304,15 @@
 INIT_XMM ssse3
 RGB24_FUNCS 11, 13
 
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 RGB24_FUNCS 11, 13
+%endif
 
 ; %1 = nr. of XMM registers
 ; %2-5 = rgba, bgra, argb or abgr (in individual characters)
 %macro RGB32_TO_Y_FN 5-6
-cglobal %2%3%4%5 %+ ToY, 3, 3, %1, dst, src, w
+cglobal %2%3%4%5 %+ ToY, 6, 6, %1, dst, src, u1, u2, w, u3
     mova           m5, [rgba_Ycoeff_%2%4]
     mova           m6, [rgba_Ycoeff_%3%5]
 %if %0 == 6
@@ -323,6 +323,7 @@
     movsxd         wq, wd
 %endif
     lea          srcq, [srcq+wq*4]
+    add            wq, wq
     add          dstq, wq
     neg            wq
     mova           m4, [rgb_Yrnd]
@@ -330,8 +331,8 @@
     psrlw          m7, 8                  ; (word) { 0x00ff } x4
 .loop:
     ; FIXME check alignment and use mova
-    movu           m0, [srcq+wq*4+0]      ; (byte) { Bx, Gx, Rx, xx }[0-3]
-    movu           m2, [srcq+wq*4+mmsize] ; (byte) { Bx, Gx, Rx, xx }[4-7]
+    movu           m0, [srcq+wq*2+0]      ; (byte) { Bx, Gx, Rx, xx }[0-3]
+    movu           m2, [srcq+wq*2+mmsize] ; (byte) { Bx, Gx, Rx, xx }[4-7]
     DEINTB          1,  0,  3,  2,  7     ; (word) { Gx, xx (m0/m2) or Bx, Rx (m1/m3) }[0-3]/[4-7]
     pmaddwd        m1, m5                 ; (dword) { Bx*BY + Rx*RY }[0-3]
     pmaddwd        m0, m6                 ; (dword) { Gx*GY }[0-3]
@@ -341,12 +342,11 @@
     paddd          m2, m4                 ; += rgb_Yrnd
     paddd          m0, m1                 ; (dword) { Y[0-3] }
     paddd          m2, m3                 ; (dword) { Y[4-7] }
-    psrad          m0, 15
-    psrad          m2, 15
+    psrad          m0, 9
+    psrad          m2, 9
     packssdw       m0, m2                 ; (word) { Y[0-7] }
-    packuswb       m0, m0                 ; (byte) { Y[0-7] }
-    movh    [dstq+wq], m0
-    add            wq, mmsize / 2
+    mova    [dstq+wq], m0
+    add            wq, mmsize
     jl .loop
     REP_RET
 %endif ; %0 == 3
@@ -355,7 +355,7 @@
 ; %1 = nr. of XMM registers
 ; %2-5 = rgba, bgra, argb or abgr (in individual characters)
 %macro RGB32_TO_UV_FN 5-6
-cglobal %2%3%4%5 %+ ToUV, 3, 4, %1, dstU, dstV, src, w
+cglobal %2%3%4%5 %+ ToUV, 7, 7, %1, dstU, dstV, u1, src, u2, w, u3
 %if ARCH_X86_64
     mova           m8, [rgba_Ucoeff_%2%4]
     mova           m9, [rgba_Ucoeff_%3%5]
@@ -376,21 +376,22 @@
 %else ; ARCH_X86_64 && %0 == 6
 .body:
 %if ARCH_X86_64
-    movsxd         wq, dword r4m
+    movsxd         wq, dword r5m
 %else ; x86-32
-    mov            wq, r4m
+    mov            wq, r5m
 %endif
+    add            wq, wq
     add         dstUq, wq
     add         dstVq, wq
-    lea          srcq, [srcq+wq*4]
+    lea          srcq, [srcq+wq*2]
     neg            wq
     pcmpeqb        m7, m7
     psrlw          m7, 8                  ; (word) { 0x00ff } x4
     mova           m6, [rgb_UVrnd]
 .loop:
     ; FIXME check alignment and use mova
-    movu           m0, [srcq+wq*4+0]      ; (byte) { Bx, Gx, Rx, xx }[0-3]
-    movu           m4, [srcq+wq*4+mmsize] ; (byte) { Bx, Gx, Rx, xx }[4-7]
+    movu           m0, [srcq+wq*2+0]      ; (byte) { Bx, Gx, Rx, xx }[0-3]
+    movu           m4, [srcq+wq*2+mmsize] ; (byte) { Bx, Gx, Rx, xx }[4-7]
     DEINTB          1,  0,  5,  4,  7     ; (word) { Gx, xx (m0/m4) or Bx, Rx (m1/m5) }[0-3]/[4-7]
     pmaddwd        m3, m1, coeffV1        ; (dword) { Bx*BV + Rx*RV }[0-3]
     pmaddwd        m2, m0, coeffV2        ; (dword) { Gx*GV }[0-3]
@@ -406,25 +407,22 @@
     pmaddwd        m4, coeffU2            ; (dword) { Gx*GU }[4-7]
     paddd          m3, m6                 ; += rgb_UVrnd
     paddd          m5, m6                 ; += rgb_UVrnd
-    psrad          m0, 15
+    psrad          m0, 9
     paddd          m1, m3                 ; (dword) { V[4-7] }
     paddd          m4, m5                 ; (dword) { U[4-7] }
-    psrad          m2, 15
-    psrad          m4, 15
-    psrad          m1, 15
+    psrad          m2, 9
+    psrad          m4, 9
+    psrad          m1, 9
     packssdw       m0, m4                 ; (word) { U[0-7] }
     packssdw       m2, m1                 ; (word) { V[0-7] }
 %if mmsize == 8
-    packuswb       m0, m0                 ; (byte) { U[0-7] }
-    packuswb       m2, m2                 ; (byte) { V[0-7] }
-    movh   [dstUq+wq], m0
-    movh   [dstVq+wq], m2
+    mova   [dstUq+wq], m0
+    mova   [dstVq+wq], m2
 %else ; mmsize == 16
-    packuswb       m0, m2                 ; (byte) { U[0-7], V[0-7] }
-    movh   [dstUq+wq], m0
-    movhps [dstVq+wq], m0
+    mova   [dstUq+wq], m0
+    mova   [dstVq+wq], m2
 %endif ; mmsize == 8/16
-    add            wq, mmsize / 2
+    add            wq, mmsize
     jl .loop
     REP_RET
 %endif ; ARCH_X86_64 && %0 == 3
@@ -452,8 +450,10 @@
 INIT_XMM sse2
 RGB32_FUNCS 8, 12
 
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 RGB32_FUNCS 8, 12
+%endif
 
 ;-----------------------------------------------------------------------------
 ; YUYV/UYVY/NV12/NV21 packed pixel shuffling.
@@ -490,7 +490,7 @@
 ;      will be the same (i.e. YUYV+AVX), and thus we don't need to
 ;      split the loop in an aligned and unaligned case
 %macro YUYV_TO_Y_FN 2-3
-cglobal %2ToY, 3, 3, %1, dst, src, w
+cglobal %2ToY, 5, 5, %1, dst, unused0, unused1, src, w
 %if ARCH_X86_64
     movsxd         wq, wd
 %endif
@@ -560,11 +560,11 @@
 ;      will be the same (i.e. UYVY+AVX), and thus we don't need to
 ;      split the loop in an aligned and unaligned case
 %macro YUYV_TO_UV_FN 2-3
-cglobal %2ToUV, 3, 4, %1, dstU, dstV, src, w
+cglobal %2ToUV, 4, 5, %1, dstU, dstV, unused, src, w
 %if ARCH_X86_64
-    movsxd         wq, dword r4m
+    movsxd         wq, dword r5m
 %else ; x86-32
-    mov            wq, r4m
+    mov            wq, r5m
 %endif
     add         dstUq, wq
     add         dstVq, wq
@@ -594,8 +594,8 @@
 .loop_%1:
     mov%1          m0, [srcq+wq*2]        ; (byte) { U0, V0, U1, V1, ... }
     mov%1          m1, [srcq+wq*2+mmsize] ; (byte) { U8, V8, U9, V9, ... }
-    pand           m2, m0, m4             ; (word) { U0, U1, ..., U7 }
-    pand           m3, m1, m4             ; (word) { U8, U9, ..., U15 }
+    pand           m2, m0, m5             ; (word) { U0, U1, ..., U7 }
+    pand           m3, m1, m5             ; (word) { U8, U9, ..., U15 }
     psrlw          m0, 8                  ; (word) { V0, V1, ..., V7 }
     psrlw          m1, 8                  ; (word) { V8, V9, ..., V15 }
     packuswb       m2, m3                 ; (byte) { U0, ..., U15 }
@@ -615,11 +615,11 @@
 ; %1 = nr. of XMM registers
 ; %2 = nv12 or nv21
 %macro NVXX_TO_UV_FN 2
-cglobal %2ToUV, 3, 4, %1, dstU, dstV, src, w
+cglobal %2ToUV, 4, 5, %1, dstU, dstV, unused, src, w
 %if ARCH_X86_64
-    movsxd         wq, dword r4m
+    movsxd         wq, dword r5m
 %else ; x86-32
-    mov            wq, r4m
+    mov            wq, r5m
 %endif
     add         dstUq, wq
     add         dstVq, wq
@@ -627,8 +627,8 @@
     test         srcq, 15
 %endif
     lea          srcq, [srcq+wq*2]
-    pcmpeqb        m4, m4                 ; (byte) { 0xff } x 16
-    psrlw          m4, 8                  ; (word) { 0x00ff } x 8
+    pcmpeqb        m5, m5                 ; (byte) { 0xff } x 16
+    psrlw          m5, 8                  ; (word) { 0x00ff } x 8
 %if mmsize == 16
     jnz .loop_u_start
     neg            wq
@@ -660,6 +660,7 @@
 NVXX_TO_UV_FN 5, nv12
 NVXX_TO_UV_FN 5, nv21
 
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 ; in theory, we could write a yuy2-to-y using vpand (i.e. AVX), but
 ; that's not faster in practice
@@ -667,3 +668,4 @@
 YUYV_TO_UV_FN 3, uyvy, 1
 NVXX_TO_UV_FN 5, nv12
 NVXX_TO_UV_FN 5, nv21
+%endif
diff --git a/libswscale/x86/output.asm b/libswscale/x86/output.asm
index 9b0b012..851165a 100644
--- a/libswscale/x86/output.asm
+++ b/libswscale/x86/output.asm
@@ -267,10 +267,12 @@
 yuv2planeX_fn 10,  7, 5
 yuv2planeX_fn 16,  8, 5
 
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 yuv2planeX_fn  8, 10, 7
 yuv2planeX_fn  9,  7, 5
 yuv2planeX_fn 10,  7, 5
+%endif
 
 ; %1=outout-bpc, %2=alignment (u/a)
 %macro yuv2plane1_mainloop 2
@@ -405,8 +407,10 @@
 INIT_XMM sse4
 yuv2plane1_fn 16, 5, 3
 
+%if HAVE_AVX_EXTERNAL
 INIT_XMM avx
 yuv2plane1_fn  8, 5, 5
 yuv2plane1_fn  9, 5, 3
 yuv2plane1_fn 10, 5, 3
 yuv2plane1_fn 16, 5, 3
+%endif
diff --git a/libswscale/x86/rgb2rgb.c b/libswscale/x86/rgb2rgb.c
index 5962680..83734a2 100644
--- a/libswscale/x86/rgb2rgb.c
+++ b/libswscale/x86/rgb2rgb.c
@@ -6,20 +6,20 @@
  * Written by Nick Kurshev.
  * palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -72,6 +72,9 @@
 DECLARE_ASM_CONST(8, uint64_t, red_15mask)   = 0x00007c0000007c00ULL;
 DECLARE_ASM_CONST(8, uint64_t, green_15mask) = 0x000003e0000003e0ULL;
 DECLARE_ASM_CONST(8, uint64_t, blue_15mask)  = 0x0000001f0000001fULL;
+DECLARE_ASM_CONST(8, uint64_t, mul15_mid)    = 0x4200420042004200ULL;
+DECLARE_ASM_CONST(8, uint64_t, mul15_hi)     = 0x0210021002100210ULL;
+DECLARE_ASM_CONST(8, uint64_t, mul16_mid)    = 0x2080208020802080ULL;
 
 #define RGB2YUV_SHIFT 8
 #define BY ((int)( 0.098*(1<<RGB2YUV_SHIFT)+0.5))
diff --git a/libswscale/x86/rgb2rgb_template.c b/libswscale/x86/rgb2rgb_template.c
index f312053..6584249 100644
--- a/libswscale/x86/rgb2rgb_template.c
+++ b/libswscale/x86/rgb2rgb_template.c
@@ -7,20 +7,20 @@
  * palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at)
  * lot of big-endian byte order fixes by Alex Beregszaszi
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -127,14 +127,11 @@
             "movq       %%mm4, %%mm3    \n\t" \
             "psllq        $48, %%mm2    \n\t" \
             "psllq        $32, %%mm3    \n\t" \
-            "pand "MANGLE(mask24hh)", %%mm2\n\t" \
-            "pand "MANGLE(mask24hhh)", %%mm3\n\t" \
             "por        %%mm2, %%mm0    \n\t" \
             "psrlq        $16, %%mm1    \n\t" \
             "psrlq        $32, %%mm4    \n\t" \
             "psllq        $16, %%mm5    \n\t" \
             "por        %%mm3, %%mm1    \n\t" \
-            "pand  "MANGLE(mask24hhhh)", %%mm5\n\t" \
             "por        %%mm5, %%mm4    \n\t" \
  \
             MOVNTQ"     %%mm0,   (%0)    \n\t" \
@@ -713,27 +710,6 @@
     }
 }
 
-/*
-  I use less accurate approximation here by simply left-shifting the input
-  value and filling the low order bits with zeroes. This method improves PNG
-  compression but this scheme cannot reproduce white exactly, since it does
-  not generate an all-ones maximum value; the net effect is to darken the
-  image slightly.
-
-  The better method should be "left bit replication":
-
-   4 3 2 1 0
-   ---------
-   1 1 0 1 1
-
-   7 6 5 4 3  2 1 0
-   ----------------
-   1 1 0 1 1  1 1 0
-   |=======|  |===|
-       |      leftmost bits repeated to fill open bits
-       |
-   original bits
-*/
 static inline void RENAME(rgb15tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)
 {
     const uint16_t *end;
@@ -752,9 +728,10 @@
             "pand          %2, %%mm0    \n\t"
             "pand          %3, %%mm1    \n\t"
             "pand          %4, %%mm2    \n\t"
-            "psllq         $3, %%mm0    \n\t"
-            "psrlq         $2, %%mm1    \n\t"
-            "psrlq         $7, %%mm2    \n\t"
+            "psllq         $5, %%mm0    \n\t"
+            "pmulhw        "MANGLE(mul15_mid)", %%mm0    \n\t"
+            "pmulhw        "MANGLE(mul15_mid)", %%mm1    \n\t"
+            "pmulhw        "MANGLE(mul15_hi)", %%mm2    \n\t"
             "movq       %%mm0, %%mm3    \n\t"
             "movq       %%mm1, %%mm4    \n\t"
             "movq       %%mm2, %%mm5    \n\t"
@@ -782,9 +759,10 @@
             "pand          %2, %%mm0    \n\t"
             "pand          %3, %%mm1    \n\t"
             "pand          %4, %%mm2    \n\t"
-            "psllq         $3, %%mm0    \n\t"
-            "psrlq         $2, %%mm1    \n\t"
-            "psrlq         $7, %%mm2    \n\t"
+            "psllq         $5, %%mm0    \n\t"
+            "pmulhw        "MANGLE(mul15_mid)", %%mm0    \n\t"
+            "pmulhw        "MANGLE(mul15_mid)", %%mm1    \n\t"
+            "pmulhw        "MANGLE(mul15_hi)", %%mm2    \n\t"
             "movq       %%mm0, %%mm3    \n\t"
             "movq       %%mm1, %%mm4    \n\t"
             "movq       %%mm2, %%mm5    \n\t"
@@ -830,9 +808,9 @@
     while (s < end) {
         register uint16_t bgr;
         bgr = *s++;
-        *d++ = (bgr&0x1F)<<3;
-        *d++ = (bgr&0x3E0)>>2;
-        *d++ = (bgr&0x7C00)>>7;
+        *d++ = ((bgr&0x1F)<<3) | ((bgr&0x1F)>>2);
+        *d++ = ((bgr&0x3E0)>>2) | ((bgr&0x3E0)>>7);
+        *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
     }
 }
 
@@ -854,9 +832,11 @@
             "pand          %2, %%mm0    \n\t"
             "pand          %3, %%mm1    \n\t"
             "pand          %4, %%mm2    \n\t"
-            "psllq         $3, %%mm0    \n\t"
-            "psrlq         $3, %%mm1    \n\t"
-            "psrlq         $8, %%mm2    \n\t"
+            "psllq         $5, %%mm0    \n\t"
+            "psrlq         $1, %%mm2    \n\t"
+            "pmulhw        "MANGLE(mul15_mid)", %%mm0    \n\t"
+            "pmulhw        "MANGLE(mul16_mid)", %%mm1    \n\t"
+            "pmulhw        "MANGLE(mul15_hi)", %%mm2    \n\t"
             "movq       %%mm0, %%mm3    \n\t"
             "movq       %%mm1, %%mm4    \n\t"
             "movq       %%mm2, %%mm5    \n\t"
@@ -884,9 +864,11 @@
             "pand          %2, %%mm0    \n\t"
             "pand          %3, %%mm1    \n\t"
             "pand          %4, %%mm2    \n\t"
-            "psllq         $3, %%mm0    \n\t"
-            "psrlq         $3, %%mm1    \n\t"
-            "psrlq         $8, %%mm2    \n\t"
+            "psllq         $5, %%mm0    \n\t"
+            "psrlq         $1, %%mm2    \n\t"
+            "pmulhw        "MANGLE(mul15_mid)", %%mm0    \n\t"
+            "pmulhw        "MANGLE(mul16_mid)", %%mm1    \n\t"
+            "pmulhw        "MANGLE(mul15_hi)", %%mm2    \n\t"
             "movq       %%mm0, %%mm3    \n\t"
             "movq       %%mm1, %%mm4    \n\t"
             "movq       %%mm2, %%mm5    \n\t"
@@ -931,9 +913,9 @@
     while (s < end) {
         register uint16_t bgr;
         bgr = *s++;
-        *d++ = (bgr&0x1F)<<3;
-        *d++ = (bgr&0x7E0)>>3;
-        *d++ = (bgr&0xF800)>>8;
+        *d++ = ((bgr&0x1F)<<3) | ((bgr&0x1F)>>2);
+        *d++ = ((bgr&0x7E0)>>3) | ((bgr&0x7E0)>>9);
+        *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
     }
 }
 
@@ -976,11 +958,12 @@
             "pand          %2, %%mm0    \n\t"
             "pand          %3, %%mm1    \n\t"
             "pand          %4, %%mm2    \n\t"
-            "psllq         $3, %%mm0    \n\t"
-            "psrlq         $2, %%mm1    \n\t"
-            "psrlq         $7, %%mm2    \n\t"
+            "psllq         $5, %%mm0    \n\t"
+            "pmulhw        %5, %%mm0    \n\t"
+            "pmulhw        %5, %%mm1    \n\t"
+            "pmulhw        "MANGLE(mul15_hi)", %%mm2    \n\t"
             PACK_RGB32
-            ::"r"(d),"r"(s),"m"(mask15b),"m"(mask15g),"m"(mask15r)
+            ::"r"(d),"r"(s),"m"(mask15b),"m"(mask15g),"m"(mask15r) ,"m"(mul15_mid)
             :"memory");
         d += 16;
         s += 4;
@@ -990,9 +973,9 @@
     while (s < end) {
         register uint16_t bgr;
         bgr = *s++;
-        *d++ = (bgr&0x1F)<<3;
-        *d++ = (bgr&0x3E0)>>2;
-        *d++ = (bgr&0x7C00)>>7;
+        *d++ = ((bgr&0x1F)<<3) | ((bgr&0x1F)>>2);
+        *d++ = ((bgr&0x3E0)>>2) | ((bgr&0x3E0)>>7);
+        *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
         *d++ = 255;
     }
 }
@@ -1017,11 +1000,13 @@
             "pand          %2, %%mm0    \n\t"
             "pand          %3, %%mm1    \n\t"
             "pand          %4, %%mm2    \n\t"
-            "psllq         $3, %%mm0    \n\t"
-            "psrlq         $3, %%mm1    \n\t"
-            "psrlq         $8, %%mm2    \n\t"
+            "psllq         $5, %%mm0    \n\t"
+            "psrlq         $1, %%mm2    \n\t"
+            "pmulhw        %5, %%mm0    \n\t"
+            "pmulhw        "MANGLE(mul16_mid)", %%mm1    \n\t"
+            "pmulhw        "MANGLE(mul15_hi)", %%mm2    \n\t"
             PACK_RGB32
-            ::"r"(d),"r"(s),"m"(mask16b),"m"(mask16g),"m"(mask16r)
+            ::"r"(d),"r"(s),"m"(mask16b),"m"(mask16g),"m"(mask16r),"m"(mul15_mid)
             :"memory");
         d += 16;
         s += 4;
@@ -1031,9 +1016,9 @@
     while (s < end) {
         register uint16_t bgr;
         bgr = *s++;
-        *d++ = (bgr&0x1F)<<3;
-        *d++ = (bgr&0x7E0)>>3;
-        *d++ = (bgr&0xF800)>>8;
+        *d++ = ((bgr&0x1F)<<3) | ((bgr&0x1F)>>2);
+        *d++ = ((bgr&0x7E0)>>3) | ((bgr&0x7E0)>>9);
+        *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
         *d++ = 255;
     }
 }
diff --git a/libswscale/x86/scale.asm b/libswscale/x86/scale.asm
index d56e253..6282ab2 100644
--- a/libswscale/x86/scale.asm
+++ b/libswscale/x86/scale.asm
@@ -408,11 +408,15 @@
 SCALE_FUNCS  8, 15, %1
 SCALE_FUNCS  9, 15, %2
 SCALE_FUNCS 10, 15, %2
+SCALE_FUNCS 12, 15, %2
+SCALE_FUNCS 14, 15, %2
 SCALE_FUNCS 16, 15, %3
 %endif ; !sse4
 SCALE_FUNCS  8, 19, %1
 SCALE_FUNCS  9, 19, %2
 SCALE_FUNCS 10, 19, %2
+SCALE_FUNCS 12, 19, %2
+SCALE_FUNCS 14, 19, %2
 SCALE_FUNCS 16, 19, %3
 %endmacro
 
diff --git a/libswscale/x86/swscale.c b/libswscale/x86/swscale.c
index ba7990e..e6a0123 100644
--- a/libswscale/x86/swscale.c
+++ b/libswscale/x86/swscale.c
@@ -1,20 +1,20 @@
 /*
- * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2001-2011 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -23,6 +23,7 @@
 #include "libswscale/swscale.h"
 #include "libswscale/swscale_internal.h"
 #include "libavutil/attributes.h"
+#include "libavutil/avassert.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/x86/asm.h"
 #include "libavutil/x86/cpu.h"
@@ -70,6 +71,7 @@
 DECLARE_ALIGNED(8, const uint64_t, ff_bgr2UVOffset) = 0x8080808080808080ULL;
 DECLARE_ALIGNED(8, const uint64_t, ff_w1111)        = 0x0001000100010001ULL;
 
+
 //MMX versions
 #if HAVE_MMX_INLINE
 #undef RENAME
@@ -117,9 +119,9 @@
         c->greenDither= ff_dither4[dstY&1];
     c->redDither= ff_dither8[(dstY+1)&1];
     if (dstY < dstH - 2) {
-        const int16_t **lumSrcPtr= (const int16_t **) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
-        const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
-        const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
+        const int16_t **lumSrcPtr= (const int16_t **)(void*) lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;
+        const int16_t **chrUSrcPtr= (const int16_t **)(void*) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;
+        const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **)(void*) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL;
         int i;
 
         if (firstLumSrcY < 0 || firstLumSrcY + vLumFilterSize > c->srcH) {
@@ -186,7 +188,7 @@
                 *(const void**)&lumMmxFilter[4*i+0]= lumSrcPtr[i];
                 lumMmxFilter[4*i+2]=
                 lumMmxFilter[4*i+3]=
-                ((uint16_t)vLumFilter[dstY*vLumFilterSize + i])*0x10001;
+                ((uint16_t)vLumFilter[dstY*vLumFilterSize + i])*0x10001U;
                 if (CONFIG_SWSCALE_ALPHA && alpPixBuf) {
                     *(const void**)&alpMmxFilter[4*i+0]= alpSrcPtr[i];
                     alpMmxFilter[4*i+2]=
@@ -197,12 +199,73 @@
                 *(const void**)&chrMmxFilter[4*i+0]= chrUSrcPtr[i];
                 chrMmxFilter[4*i+2]=
                 chrMmxFilter[4*i+3]=
-                ((uint16_t)vChrFilter[chrDstY*vChrFilterSize + i])*0x10001;
+                ((uint16_t)vChrFilter[chrDstY*vChrFilterSize + i])*0x10001U;
             }
         }
     }
 }
 
+#if HAVE_MMXEXT
+static void yuv2yuvX_sse3(const int16_t *filter, int filterSize,
+                           const int16_t **src, uint8_t *dest, int dstW,
+                           const uint8_t *dither, int offset)
+{
+    if(((int)dest) & 15){
+        return yuv2yuvX_MMX2(filter, filterSize, src, dest, dstW, dither, offset);
+    }
+    if (offset) {
+        __asm__ volatile("movq       (%0), %%xmm3\n\t"
+                         "movdqa    %%xmm3, %%xmm4\n\t"
+                         "psrlq       $24, %%xmm3\n\t"
+                         "psllq       $40, %%xmm4\n\t"
+                         "por       %%xmm4, %%xmm3\n\t"
+                         :: "r"(dither)
+                         );
+    } else {
+        __asm__ volatile("movq       (%0), %%xmm3\n\t"
+                         :: "r"(dither)
+                         );
+    }
+    __asm__ volatile(
+        "pxor      %%xmm0, %%xmm0\n\t"
+        "punpcklbw %%xmm0, %%xmm3\n\t"
+        "psraw        $4, %%xmm3\n\t"
+        "movdqa    %%xmm3, %%xmm4\n\t"
+        "movdqa    %%xmm3, %%xmm7\n\t"
+        "movl %3, %%ecx\n\t"
+        "mov                                 %0, %%"REG_d"  \n\t"\
+        "mov                        (%%"REG_d"), %%"REG_S"  \n\t"\
+        ".p2align                             4             \n\t" /* FIXME Unroll? */\
+        "1:                                                 \n\t"\
+        "movddup                  8(%%"REG_d"), %%xmm0      \n\t" /* filterCoeff */\
+        "movdqa              (%%"REG_S", %%"REG_c", 2), %%xmm2      \n\t" /* srcData */\
+        "movdqa            16(%%"REG_S", %%"REG_c", 2), %%xmm5      \n\t" /* srcData */\
+        "add                                $16, %%"REG_d"  \n\t"\
+        "mov                        (%%"REG_d"), %%"REG_S"  \n\t"\
+        "test                         %%"REG_S", %%"REG_S"  \n\t"\
+        "pmulhw                           %%xmm0, %%xmm2      \n\t"\
+        "pmulhw                           %%xmm0, %%xmm5      \n\t"\
+        "paddw                            %%xmm2, %%xmm3      \n\t"\
+        "paddw                            %%xmm5, %%xmm4      \n\t"\
+        " jnz                                1b             \n\t"\
+        "psraw                               $3, %%xmm3      \n\t"\
+        "psraw                               $3, %%xmm4      \n\t"\
+        "packuswb                         %%xmm4, %%xmm3      \n\t"
+        "movntdq                          %%xmm3, (%1, %%"REG_c")\n\t"
+        "add                         $16, %%"REG_c"         \n\t"\
+        "cmp                          %2, %%"REG_c"         \n\t"\
+        "movdqa    %%xmm7, %%xmm3\n\t"
+        "movdqa    %%xmm7, %%xmm4\n\t"
+        "mov                                 %0, %%"REG_d"  \n\t"\
+        "mov                        (%%"REG_d"), %%"REG_S"  \n\t"\
+        "jb                                  1b             \n\t"\
+        :: "g" (filter),
+           "r" (dest-offset), "g" ((x86_reg)(dstW+offset)), "m" (offset)
+        : "%"REG_d, "%"REG_S, "%"REG_c
+    );
+}
+#endif
+
 #endif /* HAVE_INLINE_ASM */
 
 #define SCALE_FUNC(filter_n, from_bpc, to_bpc, opt) \
@@ -216,10 +279,14 @@
     SCALE_FUNC(filter_n,  8, 15, opt); \
     SCALE_FUNC(filter_n,  9, 15, opt); \
     SCALE_FUNC(filter_n, 10, 15, opt); \
+    SCALE_FUNC(filter_n, 12, 15, opt); \
+    SCALE_FUNC(filter_n, 14, 15, opt); \
     SCALE_FUNC(filter_n, 16, 15, opt); \
     SCALE_FUNC(filter_n,  8, 19, opt); \
     SCALE_FUNC(filter_n,  9, 19, opt); \
     SCALE_FUNC(filter_n, 10, 19, opt); \
+    SCALE_FUNC(filter_n, 12, 19, opt); \
+    SCALE_FUNC(filter_n, 14, 19, opt); \
     SCALE_FUNC(filter_n, 16, 19, opt)
 
 #define SCALE_FUNCS_MMX(opt) \
@@ -275,11 +342,14 @@
 
 #define INPUT_Y_FUNC(fmt, opt) \
 extern void ff_ ## fmt ## ToY_  ## opt(uint8_t *dst, const uint8_t *src, \
+                                       const uint8_t *unused1, const uint8_t *unused2, \
                                        int w, uint32_t *unused)
 #define INPUT_UV_FUNC(fmt, opt) \
 extern void ff_ ## fmt ## ToUV_ ## opt(uint8_t *dstU, uint8_t *dstV, \
-                                       const uint8_t *src, const uint8_t *unused1, \
-                                       int w, uint32_t *unused2)
+                                       const uint8_t *unused0, \
+                                       const uint8_t *src1, \
+                                       const uint8_t *src2, \
+                                       int w, uint32_t *unused)
 #define INPUT_FUNC(fmt, opt) \
     INPUT_Y_FUNC(fmt, opt); \
     INPUT_UV_FUNC(fmt, opt)
@@ -312,21 +382,32 @@
 #if HAVE_MMXEXT_INLINE
     if (cpu_flags & AV_CPU_FLAG_MMXEXT)
         sws_init_swScale_MMX2(c);
+    if (cpu_flags & AV_CPU_FLAG_SSE3){
+        if(c->use_mmx_vfilter && !(c->flags & SWS_ACCURATE_RND))
+            c->yuv2planeX = yuv2yuvX_sse3;
+    }
 #endif
 #endif /* HAVE_INLINE_ASM */
 
 #define ASSIGN_SCALE_FUNC2(hscalefn, filtersize, opt1, opt2) do { \
     if (c->srcBpc == 8) { \
-        hscalefn = c->dstBpc <= 10 ? ff_hscale8to15_ ## filtersize ## _ ## opt2 : \
+        hscalefn = c->dstBpc <= 14 ? ff_hscale8to15_ ## filtersize ## _ ## opt2 : \
                                      ff_hscale8to19_ ## filtersize ## _ ## opt1; \
     } else if (c->srcBpc == 9) { \
-        hscalefn = c->dstBpc <= 10 ? ff_hscale9to15_ ## filtersize ## _ ## opt2 : \
+        hscalefn = c->dstBpc <= 14 ? ff_hscale9to15_ ## filtersize ## _ ## opt2 : \
                                      ff_hscale9to19_ ## filtersize ## _ ## opt1; \
     } else if (c->srcBpc == 10) { \
-        hscalefn = c->dstBpc <= 10 ? ff_hscale10to15_ ## filtersize ## _ ## opt2 : \
+        hscalefn = c->dstBpc <= 14 ? ff_hscale10to15_ ## filtersize ## _ ## opt2 : \
                                      ff_hscale10to19_ ## filtersize ## _ ## opt1; \
-    } else /* c->srcBpc == 16 */ { \
-        hscalefn = c->dstBpc <= 10 ? ff_hscale16to15_ ## filtersize ## _ ## opt2 : \
+    } else if (c->srcBpc == 12) { \
+        hscalefn = c->dstBpc <= 14 ? ff_hscale12to15_ ## filtersize ## _ ## opt2 : \
+                                     ff_hscale12to19_ ## filtersize ## _ ## opt1; \
+    } else if (c->srcBpc == 14 || ((c->srcFormat==AV_PIX_FMT_PAL8||isAnyRGB(c->srcFormat)) && av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1<15)) { \
+        hscalefn = c->dstBpc <= 14 ? ff_hscale14to15_ ## filtersize ## _ ## opt2 : \
+                                     ff_hscale14to19_ ## filtersize ## _ ## opt1; \
+    } else { /* c->srcBpc == 16 */ \
+        av_assert0(c->srcBpc == 16);\
+        hscalefn = c->dstBpc <= 14 ? ff_hscale16to15_ ## filtersize ## _ ## opt2 : \
                                      ff_hscale16to19_ ## filtersize ## _ ## opt1; \
     } \
 } while (0)
@@ -341,14 +422,15 @@
     case 16:                          do_16_case;                          break; \
     case 10: if (!isBE(c->dstFormat)) vscalefn = ff_yuv2planeX_10_ ## opt; break; \
     case 9:  if (!isBE(c->dstFormat)) vscalefn = ff_yuv2planeX_9_  ## opt; break; \
-    default: if (condition_8bit)      vscalefn = ff_yuv2planeX_8_  ## opt; break; \
+    default: if (condition_8bit)    /*vscalefn = ff_yuv2planeX_8_  ## opt;*/ break; \
     }
 #define ASSIGN_VSCALE_FUNC(vscalefn, opt1, opt2, opt2chk) \
     switch(c->dstBpc){ \
     case 16: if (!isBE(c->dstFormat))            vscalefn = ff_yuv2plane1_16_ ## opt1; break; \
     case 10: if (!isBE(c->dstFormat) && opt2chk) vscalefn = ff_yuv2plane1_10_ ## opt2; break; \
     case 9:  if (!isBE(c->dstFormat) && opt2chk) vscalefn = ff_yuv2plane1_9_  ## opt2;  break; \
-    default:                                     vscalefn = ff_yuv2plane1_8_  ## opt1;  break; \
+    case 8:                                      vscalefn = ff_yuv2plane1_8_  ## opt1;  break; \
+    default: av_assert0(c->dstBpc>8); \
     }
 #define case_rgb(x, X, opt) \
         case AV_PIX_FMT_ ## X: \
diff --git a/libswscale/x86/swscale_template.c b/libswscale/x86/swscale_template.c
index 0d5ba7e..a09de18 100644
--- a/libswscale/x86/swscale_template.c
+++ b/libswscale/x86/swscale_template.c
@@ -1,25 +1,26 @@
 /*
- * Copyright (C) 2001-2003 Michael Niedermayer <michaelni@gmx.at>
+ * Copyright (C) 2001-2011 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #undef REAL_MOVNTQ
 #undef MOVNTQ
+#undef MOVNTQ2
 #undef PREFETCH
 
 #if COMPILE_TEMPLATE_MMXEXT
@@ -30,11 +31,84 @@
 
 #if COMPILE_TEMPLATE_MMXEXT
 #define REAL_MOVNTQ(a,b) "movntq " #a ", " #b " \n\t"
+#define MOVNTQ2 "movntq "
 #else
 #define REAL_MOVNTQ(a,b) "movq " #a ", " #b " \n\t"
+#define MOVNTQ2 "movq "
 #endif
 #define MOVNTQ(a,b)  REAL_MOVNTQ(a,b)
 
+#if !COMPILE_TEMPLATE_MMXEXT
+static av_always_inline void
+dither_8to16(const uint8_t *srcDither, int rot)
+{
+    if (rot) {
+        __asm__ volatile("pxor      %%mm0, %%mm0\n\t"
+                         "movq       (%0), %%mm3\n\t"
+                         "movq      %%mm3, %%mm4\n\t"
+                         "psrlq       $24, %%mm3\n\t"
+                         "psllq       $40, %%mm4\n\t"
+                         "por       %%mm4, %%mm3\n\t"
+                         "movq      %%mm3, %%mm4\n\t"
+                         "punpcklbw %%mm0, %%mm3\n\t"
+                         "punpckhbw %%mm0, %%mm4\n\t"
+                         :: "r"(srcDither)
+                         );
+    } else {
+        __asm__ volatile("pxor      %%mm0, %%mm0\n\t"
+                         "movq       (%0), %%mm3\n\t"
+                         "movq      %%mm3, %%mm4\n\t"
+                         "punpcklbw %%mm0, %%mm3\n\t"
+                         "punpckhbw %%mm0, %%mm4\n\t"
+                         :: "r"(srcDither)
+                         );
+    }
+}
+#endif
+
+static void RENAME(yuv2yuvX)(const int16_t *filter, int filterSize,
+                           const int16_t **src, uint8_t *dest, int dstW,
+                           const uint8_t *dither, int offset)
+{
+    dither_8to16(dither, offset);
+    __asm__ volatile(\
+        "psraw        $4, %%mm3\n\t"
+        "psraw        $4, %%mm4\n\t"
+        "movq    %%mm3, %%mm6\n\t"
+        "movq    %%mm4, %%mm7\n\t"
+        "movl %3, %%ecx\n\t"
+        "mov                                 %0, %%"REG_d"  \n\t"\
+        "mov                        (%%"REG_d"), %%"REG_S"  \n\t"\
+        ".p2align                             4             \n\t" /* FIXME Unroll? */\
+        "1:                                                 \n\t"\
+        "movq                      8(%%"REG_d"), %%mm0      \n\t" /* filterCoeff */\
+        "movq                (%%"REG_S", %%"REG_c", 2), %%mm2      \n\t" /* srcData */\
+        "movq               8(%%"REG_S", %%"REG_c", 2), %%mm5      \n\t" /* srcData */\
+        "add                                $16, %%"REG_d"  \n\t"\
+        "mov                        (%%"REG_d"), %%"REG_S"  \n\t"\
+        "test                         %%"REG_S", %%"REG_S"  \n\t"\
+        "pmulhw                           %%mm0, %%mm2      \n\t"\
+        "pmulhw                           %%mm0, %%mm5      \n\t"\
+        "paddw                            %%mm2, %%mm3      \n\t"\
+        "paddw                            %%mm5, %%mm4      \n\t"\
+        " jnz                                1b             \n\t"\
+        "psraw                               $3, %%mm3      \n\t"\
+        "psraw                               $3, %%mm4      \n\t"\
+        "packuswb                         %%mm4, %%mm3      \n\t"
+        MOVNTQ2 "                         %%mm3, (%1, %%"REG_c")\n\t"
+        "add                          $8, %%"REG_c"         \n\t"\
+        "cmp                          %2, %%"REG_c"         \n\t"\
+        "movq    %%mm6, %%mm3\n\t"
+        "movq    %%mm7, %%mm4\n\t"
+        "mov                                 %0, %%"REG_d"  \n\t"\
+        "mov                        (%%"REG_d"), %%"REG_S"  \n\t"\
+        "jb                                  1b             \n\t"\
+        :: "g" (filter),
+           "r" (dest-offset), "g" ((x86_reg)(dstW+offset)), "m" (offset)
+        : "%"REG_d, "%"REG_S, "%"REG_c
+    );
+}
+
 #define YSCALEYUV2PACKEDX_UV \
     __asm__ volatile(\
         "xor                   %%"REG_a", %%"REG_a"     \n\t"\
@@ -260,7 +334,7 @@
 {
     x86_reg dummy=0;
     x86_reg dstW_reg = dstW;
-    x86_reg uv_off = c->uv_off_byte;
+    x86_reg uv_off = c->uv_offx2;
 
     if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
         YSCALEYUV2PACKEDX_ACCURATE
@@ -293,7 +367,7 @@
 {
     x86_reg dummy=0;
     x86_reg dstW_reg = dstW;
-    x86_reg uv_off = c->uv_off_byte;
+    x86_reg uv_off = c->uv_offx2;
 
     if (CONFIG_SWSCALE_ALPHA && c->alpPixBuf) {
         YSCALEYUV2PACKEDX
@@ -350,7 +424,7 @@
 {
     x86_reg dummy=0;
     x86_reg dstW_reg = dstW;
-    x86_reg uv_off = c->uv_off_byte;
+    x86_reg uv_off = c->uv_offx2;
 
     YSCALEYUV2PACKEDX_ACCURATE
     YSCALEYUV2RGBX
@@ -374,7 +448,7 @@
 {
     x86_reg dummy=0;
     x86_reg dstW_reg = dstW;
-    x86_reg uv_off = c->uv_off_byte;
+    x86_reg uv_off = c->uv_offx2;
 
     YSCALEYUV2PACKEDX
     YSCALEYUV2RGBX
@@ -427,7 +501,7 @@
 {
     x86_reg dummy=0;
     x86_reg dstW_reg = dstW;
-    x86_reg uv_off = c->uv_off_byte;
+    x86_reg uv_off = c->uv_offx2;
 
     YSCALEYUV2PACKEDX_ACCURATE
     YSCALEYUV2RGBX
@@ -451,7 +525,7 @@
 {
     x86_reg dummy=0;
     x86_reg dstW_reg = dstW;
-    x86_reg uv_off = c->uv_off_byte;
+    x86_reg uv_off = c->uv_offx2;
 
     YSCALEYUV2PACKEDX
     YSCALEYUV2RGBX
@@ -584,7 +658,7 @@
 {
     x86_reg dummy=0;
     x86_reg dstW_reg = dstW;
-    x86_reg uv_off = c->uv_off_byte;
+    x86_reg uv_off = c->uv_offx2;
 
     YSCALEYUV2PACKEDX_ACCURATE
     YSCALEYUV2RGBX
@@ -608,7 +682,7 @@
 {
     x86_reg dummy=0;
     x86_reg dstW_reg = dstW;
-    x86_reg uv_off = c->uv_off_byte;
+    x86_reg uv_off = c->uv_offx2;
 
     YSCALEYUV2PACKEDX
     YSCALEYUV2RGBX
@@ -649,7 +723,7 @@
 {
     x86_reg dummy=0;
     x86_reg dstW_reg = dstW;
-    x86_reg uv_off = c->uv_off_byte;
+    x86_reg uv_off = c->uv_offx2;
 
     YSCALEYUV2PACKEDX_ACCURATE
     /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
@@ -670,7 +744,7 @@
 {
     x86_reg dummy=0;
     x86_reg dstW_reg = dstW;
-    x86_reg uv_off = c->uv_off_byte;
+    x86_reg uv_off = c->uv_offx2;
 
     YSCALEYUV2PACKEDX
     /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */
@@ -786,8 +860,8 @@
             : "%r8"
         );
 #else
-        *(const uint16_t **)(&c->u_temp)=abuf0;
-        *(const uint16_t **)(&c->v_temp)=abuf1;
+        c->u_temp=(intptr_t)abuf0;
+        c->v_temp=(intptr_t)abuf1;
         __asm__ volatile(
             "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"
             "mov        %4, %%"REG_b"               \n\t"
@@ -1559,9 +1633,9 @@
 {
     enum AVPixelFormat dstFormat = c->dstFormat;
 
-    if (!is16BPS(dstFormat) && !is9_OR_10BPS(dstFormat) &&
-        dstFormat != AV_PIX_FMT_NV12 && dstFormat != AV_PIX_FMT_NV21) {
-        if (!(c->flags & SWS_BITEXACT)) {
+    c->use_mmx_vfilter= 0;
+    if (!is16BPS(dstFormat) && !is9_OR_10BPS(dstFormat) && dstFormat != AV_PIX_FMT_NV12
+        && dstFormat != AV_PIX_FMT_NV21 && !(c->flags & SWS_BITEXACT)) {
             if (c->flags & SWS_ACCURATE_RND) {
                 if (!(c->flags & SWS_FULL_CHR_H_INT)) {
                     switch (c->dstFormat) {
@@ -1574,6 +1648,8 @@
                     }
                 }
             } else {
+                c->use_mmx_vfilter= 1;
+                c->yuv2planeX = RENAME(yuv2yuvX    );
                 if (!(c->flags & SWS_FULL_CHR_H_INT)) {
                     switch (c->dstFormat) {
                     case AV_PIX_FMT_RGB32:   c->yuv2packedX = RENAME(yuv2rgb32_X);   break;
@@ -1585,7 +1661,6 @@
                     }
                 }
             }
-        }
         if (!(c->flags & SWS_FULL_CHR_H_INT)) {
             switch (c->dstFormat) {
             case AV_PIX_FMT_RGB32:
@@ -1614,7 +1689,7 @@
         }
     }
 
-    if (c->srcBpc == 8 && c->dstBpc <= 10) {
+    if (c->srcBpc == 8 && c->dstBpc <= 14) {
     // Use the new MMX scaler if the MMX2 one can't be used (it is faster than the x86 ASM one).
 #if COMPILE_TEMPLATE_MMXEXT
     if (c->flags & SWS_FAST_BILINEAR && c->canMMX2BeUsed)
diff --git a/libswscale/x86/yuv2rgb.c b/libswscale/x86/yuv2rgb.c
index b7d8f42..4d8e79d 100644
--- a/libswscale/x86/yuv2rgb.c
+++ b/libswscale/x86/yuv2rgb.c
@@ -7,20 +7,20 @@
  * 1,4,8bpp support and context / deglobalize stuff
  * by Michael Niedermayer (michaelni@gmx.at)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -74,10 +74,6 @@
 #if HAVE_INLINE_ASM
     int cpu_flags = av_get_cpu_flags();
 
-    if (c->srcFormat != AV_PIX_FMT_YUV420P &&
-        c->srcFormat != AV_PIX_FMT_YUVA420P)
-        return NULL;
-
 #if HAVE_MMXEXT_INLINE
     if (cpu_flags & AV_CPU_FLAG_MMXEXT) {
         switch (c->dstFormat) {
diff --git a/libswscale/x86/yuv2rgb_template.c b/libswscale/x86/yuv2rgb_template.c
index b028e93..c879102 100644
--- a/libswscale/x86/yuv2rgb_template.c
+++ b/libswscale/x86/yuv2rgb_template.c
@@ -4,20 +4,20 @@
  * Copyright (C) 2001-2007 Michael Niedermayer
  *           (c) 2010 Konstantin Shishkov
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -43,17 +43,14 @@
     if (h_size * depth > FFABS(dstStride[0]))                        \
         h_size -= 8;                                                 \
                                                                      \
-    if (c->srcFormat == AV_PIX_FMT_YUV422P) {                           \
-        srcStride[1] *= 2;                                           \
-        srcStride[2] *= 2;                                           \
-    }                                                                \
+    vshift = c->srcFormat != AV_PIX_FMT_YUV422P;                        \
                                                                      \
     __asm__ volatile ("pxor %mm4, %mm4\n\t");                        \
     for (y = 0; y < srcSliceH; y++) {                                \
         uint8_t *image    = dst[0] + (y + srcSliceY) * dstStride[0]; \
         const uint8_t *py = src[0] +               y * srcStride[0]; \
-        const uint8_t *pu = src[1] +        (y >> 1) * srcStride[1]; \
-        const uint8_t *pv = src[2] +        (y >> 1) * srcStride[2]; \
+        const uint8_t *pu = src[1] +   (y >> vshift) * srcStride[1]; \
+        const uint8_t *pv = src[2] +   (y >> vshift) * srcStride[2]; \
         x86_reg index = -h_size / 2;                                 \
 
 #define YUV2RGB_INITIAL_LOAD          \
@@ -141,6 +138,7 @@
         : "+r" (index), "+r" (image)                              \
         : "r" (pu - index), "r" (pv - index), "r"(&c->redDither), \
           "r" (py - 2*index)                                      \
+        : "memory"                                                \
         );                                                        \
     }                                                             \
 
@@ -148,6 +146,7 @@
         : "+r" (index), "+r" (image)                              \
         : "r" (pu - index), "r" (pv - index), "r"(&c->redDither), \
           "r" (py - 2*index), "r" (pa - 2*index)                  \
+        : "memory"                                                \
         );                                                        \
     }                                                             \
 
@@ -188,7 +187,7 @@
                                        int srcSliceY, int srcSliceH,
                                        uint8_t *dst[], int dstStride[])
 {
-    int y, h_size;
+    int y, h_size, vshift;
 
     YUV2RGB_LOOP(2)
 
@@ -216,7 +215,7 @@
                                        int srcSliceY, int srcSliceH,
                                        uint8_t *dst[], int dstStride[])
 {
-    int y, h_size;
+    int y, h_size, vshift;
 
     YUV2RGB_LOOP(2)
 
@@ -306,7 +305,7 @@
                                        int srcSliceY, int srcSliceH,
                                        uint8_t *dst[], int dstStride[])
 {
-    int y, h_size;
+    int y, h_size, vshift;
 
     YUV2RGB_LOOP(3)
 
@@ -324,7 +323,7 @@
                                        int srcSliceY, int srcSliceH,
                                        uint8_t *dst[], int dstStride[])
 {
-    int y, h_size;
+    int y, h_size, vshift;
 
     YUV2RGB_LOOP(3)
 
@@ -368,7 +367,7 @@
                                        int srcSliceY, int srcSliceH,
                                        uint8_t *dst[], int dstStride[])
 {
-    int y, h_size;
+    int y, h_size, vshift;
 
     YUV2RGB_LOOP(4)
 
@@ -389,7 +388,7 @@
                                         int srcSliceY, int srcSliceH,
                                         uint8_t *dst[], int dstStride[])
 {
-    int y, h_size;
+    int y, h_size, vshift;
 
     YUV2RGB_LOOP(4)
 
@@ -411,7 +410,7 @@
                                        int srcSliceY, int srcSliceH,
                                        uint8_t *dst[], int dstStride[])
 {
-    int y, h_size;
+    int y, h_size, vshift;
 
     YUV2RGB_LOOP(4)
 
@@ -432,7 +431,7 @@
                                         int srcSliceY, int srcSliceH,
                                         uint8_t *dst[], int dstStride[])
 {
-    int y, h_size;
+    int y, h_size, vshift;
 
     YUV2RGB_LOOP(4)
 
diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c
index 1dbd0d8..18afc5b 100644
--- a/libswscale/yuv2rgb.c
+++ b/libswscale/yuv2rgb.c
@@ -6,27 +6,26 @@
  * 1,4,8bpp support and context / deglobalize stuff
  * by Michael Niedermayer (michaelni@gmx.at)
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
-#include <assert.h>
 
 #include "libavutil/cpu.h"
 #include "libavutil/bswap.h"
@@ -34,11 +33,14 @@
 #include "rgb2rgb.h"
 #include "swscale.h"
 #include "swscale_internal.h"
+#include "libavutil/pixdesc.h"
 
-extern const uint8_t dither_4x4_16[4][8];
-extern const uint8_t dither_8x8_32[8][8];
-extern const uint8_t dither_8x8_73[8][8];
-extern const uint8_t dither_8x8_220[8][8];
+extern const uint8_t dither_2x2_4[3][8];
+extern const uint8_t dither_2x2_8[3][8];
+extern const uint8_t dither_4x4_16[5][8];
+extern const uint8_t dither_8x8_32[9][8];
+extern const uint8_t dither_8x8_73[9][8];
+extern const uint8_t dither_8x8_220[9][8];
 
 const int32_t ff_yuv2rgb_coeffs[8][4] = {
     { 117504, 138453, 13954, 34903 }, /* no sequence_display_extension */
@@ -61,9 +63,9 @@
 #define LOADCHROMA(i)                               \
     U = pu[i];                                      \
     V = pv[i];                                      \
-    r = (void *)c->table_rV[V];                     \
-    g = (void *)(c->table_gU[U] + c->table_gV[V]);  \
-    b = (void *)c->table_bU[U];
+    r = (void *)c->table_rV[V+YUVRGB_TABLE_HEADROOM];                     \
+    g = (void *)(c->table_gU[U+YUVRGB_TABLE_HEADROOM] + c->table_gV[V+YUVRGB_TABLE_HEADROOM]);  \
+    b = (void *)c->table_bU[U+YUVRGB_TABLE_HEADROOM];
 
 #define PUTRGB(dst, src, i)                         \
     Y              = src[2 * i];                    \
@@ -387,24 +389,65 @@
     PUTBGR24(dst_2, py_2, 0);
 ENDYUV2RGBFUNC()
 
-// This is exactly the same code as yuv2rgb_c_32 except for the types of
-// r, g, b, dst_1, dst_2
-YUV2RGBFUNC(yuv2rgb_c_16, uint16_t, 0)
+YUV2RGBFUNC(yuv2rgb_c_16_ordered_dither, uint16_t, 0)
+    const uint8_t *d16 = dither_2x2_8[y & 1];
+    const uint8_t *e16 = dither_2x2_4[y & 1];
+    const uint8_t *f16 = dither_2x2_8[(y & 1)^1];
+
+#define PUTRGB16(dst, src, i, o)                    \
+    Y              = src[2 * i];                    \
+    dst[2 * i]     = r[Y + d16[0 + o]] +            \
+                     g[Y + e16[0 + o]] +            \
+                     b[Y + f16[0 + o]];             \
+    Y              = src[2 * i + 1];                \
+    dst[2 * i + 1] = r[Y + d16[1 + o]] +            \
+                     g[Y + e16[1 + o]] +            \
+                     b[Y + f16[1 + o]];
     LOADCHROMA(0);
-    PUTRGB(dst_1, py_1, 0);
-    PUTRGB(dst_2, py_2, 0);
+    PUTRGB16(dst_1, py_1, 0, 0);
+    PUTRGB16(dst_2, py_2, 0, 0 + 8);
 
     LOADCHROMA(1);
-    PUTRGB(dst_2, py_2, 1);
-    PUTRGB(dst_1, py_1, 1);
+    PUTRGB16(dst_2, py_2, 1, 2 + 8);
+    PUTRGB16(dst_1, py_1, 1, 2);
 
     LOADCHROMA(2);
-    PUTRGB(dst_1, py_1, 2);
-    PUTRGB(dst_2, py_2, 2);
+    PUTRGB16(dst_1, py_1, 2, 4);
+    PUTRGB16(dst_2, py_2, 2, 4 + 8);
 
     LOADCHROMA(3);
-    PUTRGB(dst_2, py_2, 3);
-    PUTRGB(dst_1, py_1, 3);
+    PUTRGB16(dst_2, py_2, 3, 6 + 8);
+    PUTRGB16(dst_1, py_1, 3, 6);
+CLOSEYUV2RGBFUNC(8)
+
+YUV2RGBFUNC(yuv2rgb_c_15_ordered_dither, uint16_t, 0)
+    const uint8_t *d16 = dither_2x2_8[y & 1];
+    const uint8_t *e16 = dither_2x2_8[(y & 1)^1];
+
+#define PUTRGB15(dst, src, i, o)                    \
+    Y              = src[2 * i];                    \
+    dst[2 * i]     = r[Y + d16[0 + o]] +            \
+                     g[Y + d16[1 + o]] +            \
+                     b[Y + e16[0 + o]];             \
+    Y              = src[2 * i + 1];                \
+    dst[2 * i + 1] = r[Y + d16[1 + o]] +            \
+                     g[Y + d16[0 + o]] +            \
+                     b[Y + e16[1 + o]];
+    LOADCHROMA(0);
+    PUTRGB15(dst_1, py_1, 0, 0);
+    PUTRGB15(dst_2, py_2, 0, 0 + 8);
+
+    LOADCHROMA(1);
+    PUTRGB15(dst_2, py_2, 1, 2 + 8);
+    PUTRGB15(dst_1, py_1, 1, 2);
+
+    LOADCHROMA(2);
+    PUTRGB15(dst_1, py_1, 2, 4);
+    PUTRGB15(dst_2, py_2, 2, 4 + 8);
+
+    LOADCHROMA(3);
+    PUTRGB15(dst_2, py_2, 3, 6 + 8);
+    PUTRGB15(dst_1, py_1, 3, 6);
 CLOSEYUV2RGBFUNC(8)
 
 // r, g, b, dst_1, dst_2
@@ -537,7 +580,7 @@
 YUV2RGBFUNC(yuv2rgb_c_1_ordered_dither, uint8_t, 0)
     const uint8_t *d128 = dither_8x8_220[y & 7];
     char out_1 = 0, out_2 = 0;
-    g = c->table_gU[128] + c->table_gV[128];
+    g = c->table_gU[128 + YUVRGB_TABLE_HEADROOM] + c->table_gV[128 + YUVRGB_TABLE_HEADROOM];
 
 #define PUTRGB1(out, src, i, o)                     \
     Y    = src[2 * i];                              \
@@ -579,7 +622,7 @@
 
     av_log(c, AV_LOG_WARNING,
            "No accelerated colorspace conversion found from %s to %s.\n",
-           sws_format_name(c->srcFormat), sws_format_name(c->dstFormat));
+           av_get_pix_fmt_name(c->srcFormat), av_get_pix_fmt_name(c->dstFormat));
 
     switch (c->dstFormat) {
     case AV_PIX_FMT_BGR48BE:
@@ -590,23 +633,21 @@
         return yuv2rgb_c_48;
     case AV_PIX_FMT_ARGB:
     case AV_PIX_FMT_ABGR:
-        if (CONFIG_SWSCALE_ALPHA && c->srcFormat == AV_PIX_FMT_YUVA420P)
+        if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat))
             return yuva2argb_c;
     case AV_PIX_FMT_RGBA:
     case AV_PIX_FMT_BGRA:
-        if (CONFIG_SWSCALE_ALPHA && c->srcFormat == AV_PIX_FMT_YUVA420P)
-            return yuva2rgba_c;
-        else
-            return yuv2rgb_c_32;
+        return (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat)) ? yuva2rgba_c : yuv2rgb_c_32;
     case AV_PIX_FMT_RGB24:
         return yuv2rgb_c_24_rgb;
     case AV_PIX_FMT_BGR24:
         return yuv2rgb_c_24_bgr;
     case AV_PIX_FMT_RGB565:
     case AV_PIX_FMT_BGR565:
+        return yuv2rgb_c_16_ordered_dither;
     case AV_PIX_FMT_RGB555:
     case AV_PIX_FMT_BGR555:
-        return yuv2rgb_c_16;
+        return yuv2rgb_c_15_ordered_dither;
     case AV_PIX_FMT_RGB444:
     case AV_PIX_FMT_BGR444:
         return yuv2rgb_c_12_ordered_dither;
@@ -621,36 +662,32 @@
         return yuv2rgb_c_4b_ordered_dither;
     case AV_PIX_FMT_MONOBLACK:
         return yuv2rgb_c_1_ordered_dither;
-    default:
-        assert(0);
     }
     return NULL;
 }
 
-static void fill_table(uint8_t *table[256], const int elemsize,
+static void fill_table(uint8_t* table[256 + 2*YUVRGB_TABLE_HEADROOM], const int elemsize,
                        const int inc, void *y_tab)
 {
     int i;
-    int64_t cb       = 0;
     uint8_t *y_table = y_tab;
 
     y_table -= elemsize * (inc >> 9);
 
-    for (i = 0; i < 256; i++) {
+    for (i = 0; i < 256 + 2*YUVRGB_TABLE_HEADROOM; i++) {
+        int64_t cb = av_clip(i-YUVRGB_TABLE_HEADROOM, 0, 255)*inc;
         table[i] = y_table + elemsize * (cb >> 16);
-        cb      += inc;
     }
 }
 
-static void fill_gv_table(int table[256], const int elemsize, const int inc)
+static void fill_gv_table(int table[256 + 2*YUVRGB_TABLE_HEADROOM], const int elemsize, const int inc)
 {
     int i;
-    int64_t cb = 0;
     int off    = -(inc >> 9);
 
-    for (i = 0; i < 256; i++) {
+    for (i = 0; i < 256 + 2*YUVRGB_TABLE_HEADROOM; i++) {
+        int64_t cb = av_clip(i-YUVRGB_TABLE_HEADROOM, 0, 255)*inc;
         table[i] = elemsize * (off + (cb >> 16));
-        cb      += inc;
     }
 }
 
@@ -693,7 +730,7 @@
     uint8_t *y_table;
     uint16_t *y_table16;
     uint32_t *y_table32;
-    int i, base, rbase, gbase, bbase, abase, needAlpha;
+    int i, base, rbase, gbase, bbase, av_uninit(abase), needAlpha;
     const int yoffs = fullRange ? 384 : 326;
 
     int64_t crv =  inv_table[0];
diff --git a/presets/libvpx-1080p.avpreset b/presets/libvpx-1080p.avpreset
deleted file mode 100644
index 5c7da6f..0000000
--- a/presets/libvpx-1080p.avpreset
+++ /dev/null
@@ -1,17 +0,0 @@
-g=120
-lag-in-frames=16
-deadline=good
-cpu-used=0
-profile=1
-qmax=51
-qmin=11
-slices=4
-b=2M
-
-#ignored unless using -pass 2
-maxrate=24M
-minrate=100k
-auto-alt-ref=1
-arnr-maxframes=7
-arnr-strength=5
-arnr-type=centered
diff --git a/presets/libvpx-1080p.ffpreset b/presets/libvpx-1080p.ffpreset
new file mode 100644
index 0000000..cf25932
--- /dev/null
+++ b/presets/libvpx-1080p.ffpreset
@@ -0,0 +1,19 @@
+vcodec=libvpx
+
+g=120
+lag-in-frames=16
+deadline=good
+cpu-used=0
+vprofile=1
+qmax=51
+qmin=11
+slices=4
+b=2M
+
+#ignored unless using -pass 2
+maxrate=24M
+minrate=100k
+auto-alt-ref=1
+arnr-maxframes=7
+arnr-strength=5
+arnr-type=centered
diff --git a/presets/libvpx-1080p50_60.avpreset b/presets/libvpx-1080p50_60.avpreset
deleted file mode 100644
index f85d3d6..0000000
--- a/presets/libvpx-1080p50_60.avpreset
+++ /dev/null
@@ -1,17 +0,0 @@
-g=120
-lag-in-frames=25
-deadline=good
-cpu-used=0
-profile=1
-qmax=51
-qmin=11
-slices=4
-b=2M
-
-#ignored unless using -pass 2
-maxrate=24M
-minrate=100k
-auto-alt-ref=1
-arnr-maxframes=7
-arnr-strength=5
-arnr-type=centered
diff --git a/presets/libvpx-1080p50_60.ffpreset b/presets/libvpx-1080p50_60.ffpreset
new file mode 100644
index 0000000..4a88040
--- /dev/null
+++ b/presets/libvpx-1080p50_60.ffpreset
@@ -0,0 +1,19 @@
+vcodec=libvpx
+
+g=120
+lag-in-frames=25
+deadline=good
+cpu-used=0
+vprofile=1
+qmax=51
+qmin=11
+slices=4
+b=2M
+
+#ignored unless using -pass 2
+maxrate=24M
+minrate=100k
+auto-alt-ref=1
+arnr-maxframes=7
+arnr-strength=5
+arnr-type=centered
diff --git a/presets/libvpx-360p.avpreset b/presets/libvpx-360p.avpreset
deleted file mode 100644
index 2cb9e38..0000000
--- a/presets/libvpx-360p.avpreset
+++ /dev/null
@@ -1,16 +0,0 @@
-g=120
-lag-in-frames=16
-deadline=good
-cpu-used=0
-profile=0
-qmax=63
-qmin=0
-b=768k
-
-#ignored unless using -pass 2
-maxrate=1.5M
-minrate=40k
-auto-alt-ref=1
-arnr-maxframes=7
-arnr-strength=5
-arnr-type=centered
diff --git a/presets/libvpx-360p.ffpreset b/presets/libvpx-360p.ffpreset
new file mode 100644
index 0000000..f9729ba
--- /dev/null
+++ b/presets/libvpx-360p.ffpreset
@@ -0,0 +1,18 @@
+vcodec=libvpx
+
+g=120
+lag-in-frames=16
+deadline=good
+cpu-used=0
+vprofile=0
+qmax=63
+qmin=0
+b=768k
+
+#ignored unless using -pass 2
+maxrate=1.5M
+minrate=40k
+auto-alt-ref=1
+arnr-maxframes=7
+arnr-strength=5
+arnr-type=centered
diff --git a/presets/libvpx-720p.avpreset b/presets/libvpx-720p.avpreset
deleted file mode 100644
index 3c7e396..0000000
--- a/presets/libvpx-720p.avpreset
+++ /dev/null
@@ -1,17 +0,0 @@
-g=120
-lag-in-frames=16
-deadline=good
-cpu-used=0
-profile=0
-qmax=51
-qmin=11
-slices=4
-b=2M
-
-#ignored unless using -pass 2
-maxrate=24M
-minrate=100k
-auto-alt-ref=1
-arnr-maxframes=7
-arnr-strength=5
-arnr-type=centered
diff --git a/presets/libvpx-720p.ffpreset b/presets/libvpx-720p.ffpreset
new file mode 100644
index 0000000..e84cc15
--- /dev/null
+++ b/presets/libvpx-720p.ffpreset
@@ -0,0 +1,19 @@
+vcodec=libvpx
+
+g=120
+lag-in-frames=16
+deadline=good
+cpu-used=0
+vprofile=0
+qmax=51
+qmin=11
+slices=4
+b=2M
+
+#ignored unless using -pass 2
+maxrate=24M
+minrate=100k
+auto-alt-ref=1
+arnr-maxframes=7
+arnr-strength=5
+arnr-type=centered
diff --git a/presets/libvpx-720p50_60.avpreset b/presets/libvpx-720p50_60.avpreset
deleted file mode 100644
index 6139300..0000000
--- a/presets/libvpx-720p50_60.avpreset
+++ /dev/null
@@ -1,17 +0,0 @@
-g=120
-lag-in-frames=25
-deadline=good
-cpu-used=0
-profile=0
-qmax=51
-qmin=11
-slices=4
-b=2M
-
-#ignored unless using -pass 2
-maxrate=24M
-minrate=100k
-auto-alt-ref=1
-arnr-maxframes=7
-arnr-strength=5
-arnr-type=centered
diff --git a/presets/libvpx-720p50_60.ffpreset b/presets/libvpx-720p50_60.ffpreset
new file mode 100644
index 0000000..8fce2bf
--- /dev/null
+++ b/presets/libvpx-720p50_60.ffpreset
@@ -0,0 +1,19 @@
+vcodec=libvpx
+
+g=120
+lag-in-frames=25
+deadline=good
+cpu-used=0
+vprofile=0
+qmax=51
+qmin=11
+slices=4
+b=2M
+
+#ignored unless using -pass 2
+maxrate=24M
+minrate=100k
+auto-alt-ref=1
+arnr-maxframes=7
+arnr-strength=5
+arnr-type=centered
diff --git a/presets/libx264-baseline.avpreset b/presets/libx264-baseline.avpreset
deleted file mode 100644
index 0626e28..0000000
--- a/presets/libx264-baseline.avpreset
+++ /dev/null
@@ -1 +0,0 @@
-profile=baseline
diff --git a/presets/libx264-fast.avpreset b/presets/libx264-fast.avpreset
deleted file mode 100644
index a8c526e..0000000
--- a/presets/libx264-fast.avpreset
+++ /dev/null
@@ -1 +0,0 @@
-preset=fast
diff --git a/presets/libx264-fast_firstpass.avpreset b/presets/libx264-fast_firstpass.avpreset
deleted file mode 100644
index d9cf5af..0000000
--- a/presets/libx264-fast_firstpass.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=fast
-fastfirstpass=1
diff --git a/presets/libx264-faster.avpreset b/presets/libx264-faster.avpreset
deleted file mode 100644
index e311989..0000000
--- a/presets/libx264-faster.avpreset
+++ /dev/null
@@ -1 +0,0 @@
-preset=faster
diff --git a/presets/libx264-faster_firstpass.avpreset b/presets/libx264-faster_firstpass.avpreset
deleted file mode 100644
index 48a2d44..0000000
--- a/presets/libx264-faster_firstpass.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=faster
-fastfirstpass=1
diff --git a/presets/libx264-ipod320.avpreset b/presets/libx264-ipod320.avpreset
deleted file mode 100644
index 6323191..0000000
--- a/presets/libx264-ipod320.avpreset
+++ /dev/null
@@ -1,4 +0,0 @@
-profile=baseline
-level=13
-maxrate=768000
-bufsize=3000000
diff --git a/presets/libx264-ipod320.ffpreset b/presets/libx264-ipod320.ffpreset
new file mode 100644
index 0000000..76722bd
--- /dev/null
+++ b/presets/libx264-ipod320.ffpreset
@@ -0,0 +1,6 @@
+vcodec=libx264
+
+vprofile=baseline
+level=13
+maxrate=768000
+bufsize=3000000
diff --git a/presets/libx264-ipod640.avpreset b/presets/libx264-ipod640.avpreset
deleted file mode 100644
index c2c3e1a..0000000
--- a/presets/libx264-ipod640.avpreset
+++ /dev/null
@@ -1,4 +0,0 @@
-profile=baseline
-level=30
-maxrate=10000000
-bufsize=10000000
diff --git a/presets/libx264-ipod640.ffpreset b/presets/libx264-ipod640.ffpreset
new file mode 100644
index 0000000..51f7564
--- /dev/null
+++ b/presets/libx264-ipod640.ffpreset
@@ -0,0 +1,6 @@
+vcodec=libx264
+
+vprofile=baseline
+level=30
+maxrate=10000000
+bufsize=10000000
diff --git a/presets/libx264-lossless_fast.avpreset b/presets/libx264-lossless_fast.avpreset
deleted file mode 100644
index 1658d56..0000000
--- a/presets/libx264-lossless_fast.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=fast
-qp=0
diff --git a/presets/libx264-lossless_max.avpreset b/presets/libx264-lossless_max.avpreset
deleted file mode 100644
index c25ff32..0000000
--- a/presets/libx264-lossless_max.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=placebo
-qp=0
diff --git a/presets/libx264-lossless_medium.avpreset b/presets/libx264-lossless_medium.avpreset
deleted file mode 100644
index f7b1d81..0000000
--- a/presets/libx264-lossless_medium.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=medium
-qp=0
diff --git a/presets/libx264-lossless_slow.avpreset b/presets/libx264-lossless_slow.avpreset
deleted file mode 100644
index a15ff4c..0000000
--- a/presets/libx264-lossless_slow.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=slow
-qp=0
diff --git a/presets/libx264-lossless_slower.avpreset b/presets/libx264-lossless_slower.avpreset
deleted file mode 100644
index bd71f03..0000000
--- a/presets/libx264-lossless_slower.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=slower
-qp=0
diff --git a/presets/libx264-lossless_ultrafast.avpreset b/presets/libx264-lossless_ultrafast.avpreset
deleted file mode 100644
index 4d71eb7..0000000
--- a/presets/libx264-lossless_ultrafast.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=ultrafast
-qp=0
diff --git a/presets/libx264-main.avpreset b/presets/libx264-main.avpreset
deleted file mode 100644
index 336c69b..0000000
--- a/presets/libx264-main.avpreset
+++ /dev/null
@@ -1 +0,0 @@
-profile=main
diff --git a/presets/libx264-medium.avpreset b/presets/libx264-medium.avpreset
deleted file mode 100644
index 261d584..0000000
--- a/presets/libx264-medium.avpreset
+++ /dev/null
@@ -1 +0,0 @@
-preset=medium
diff --git a/presets/libx264-medium_firstpass.avpreset b/presets/libx264-medium_firstpass.avpreset
deleted file mode 100644
index 06c8f9f..0000000
--- a/presets/libx264-medium_firstpass.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=medium
-fastfirstpass=1
diff --git a/presets/libx264-placebo.avpreset b/presets/libx264-placebo.avpreset
deleted file mode 100644
index 93d721d..0000000
--- a/presets/libx264-placebo.avpreset
+++ /dev/null
@@ -1 +0,0 @@
-preset=placebo
diff --git a/presets/libx264-placebo_firstpass.avpreset b/presets/libx264-placebo_firstpass.avpreset
deleted file mode 100644
index c8099e5..0000000
--- a/presets/libx264-placebo_firstpass.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=placebo
-fastfirstpass=1
diff --git a/presets/libx264-slow.avpreset b/presets/libx264-slow.avpreset
deleted file mode 100644
index 85778ec..0000000
--- a/presets/libx264-slow.avpreset
+++ /dev/null
@@ -1 +0,0 @@
-preset=slow
diff --git a/presets/libx264-slow_firstpass.avpreset b/presets/libx264-slow_firstpass.avpreset
deleted file mode 100644
index 9998bc9..0000000
--- a/presets/libx264-slow_firstpass.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=slow
-fastfirstpass=1
diff --git a/presets/libx264-slower.avpreset b/presets/libx264-slower.avpreset
deleted file mode 100644
index 87d6989..0000000
--- a/presets/libx264-slower.avpreset
+++ /dev/null
@@ -1 +0,0 @@
-preset=slower
diff --git a/presets/libx264-slower_firstpass.avpreset b/presets/libx264-slower_firstpass.avpreset
deleted file mode 100644
index c798b82..0000000
--- a/presets/libx264-slower_firstpass.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=slower
-fastfirstpass=1
diff --git a/presets/libx264-superfast.avpreset b/presets/libx264-superfast.avpreset
deleted file mode 100644
index 1c117ec..0000000
--- a/presets/libx264-superfast.avpreset
+++ /dev/null
@@ -1 +0,0 @@
-preset=superfast
diff --git a/presets/libx264-superfast_firstpass.avpreset b/presets/libx264-superfast_firstpass.avpreset
deleted file mode 100644
index fc70e09..0000000
--- a/presets/libx264-superfast_firstpass.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=superfast
-fastfirstpass=1
diff --git a/presets/libx264-ultrafast.avpreset b/presets/libx264-ultrafast.avpreset
deleted file mode 100644
index 9103301..0000000
--- a/presets/libx264-ultrafast.avpreset
+++ /dev/null
@@ -1 +0,0 @@
-preset=ultrafast
diff --git a/presets/libx264-ultrafast_firstpass.avpreset b/presets/libx264-ultrafast_firstpass.avpreset
deleted file mode 100644
index e3aaa17..0000000
--- a/presets/libx264-ultrafast_firstpass.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=ultrafast
-fastfirstpass=1
diff --git a/presets/libx264-veryfast.avpreset b/presets/libx264-veryfast.avpreset
deleted file mode 100644
index fa49629..0000000
--- a/presets/libx264-veryfast.avpreset
+++ /dev/null
@@ -1 +0,0 @@
-preset=veryfast
diff --git a/presets/libx264-veryfast_firstpass.avpreset b/presets/libx264-veryfast_firstpass.avpreset
deleted file mode 100644
index 4909030..0000000
--- a/presets/libx264-veryfast_firstpass.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=veryfast
-fastfirstpass=1
diff --git a/presets/libx264-veryslow.avpreset b/presets/libx264-veryslow.avpreset
deleted file mode 100644
index 7e01c8f..0000000
--- a/presets/libx264-veryslow.avpreset
+++ /dev/null
@@ -1 +0,0 @@
-preset=veryslow
diff --git a/presets/libx264-veryslow_firstpass.avpreset b/presets/libx264-veryslow_firstpass.avpreset
deleted file mode 100644
index daf5a8f..0000000
--- a/presets/libx264-veryslow_firstpass.avpreset
+++ /dev/null
@@ -1,2 +0,0 @@
-preset=veryslow
-fastfirstpass=1
diff --git a/tests/Makefile b/tests/Makefile
index cb9954a..ac74b44 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,6 +1,18 @@
+FFSERVER_REFFILE = $(SRC_PATH)/tests/ffserver.regression.ref
+
 VREF = tests/vsynth1/00.pgm
 AREF = tests/data/asynth1.sw
 
+
+$(AREF): CMP=
+
+ffservertest: ffserver$(EXESUF) tests/vsynth1/00.pgm tests/data/asynth1.sw
+	@echo
+	@echo "Unfortunately ffserver is broken and therefore its regression"
+	@echo "test fails randomly. Treat the results accordingly."
+	@echo
+	$(SRC_PATH)/tests/ffserver-regression.sh $(FFSERVER_REFFILE) $(SRC_PATH)/tests/ffserver.conf
+
 OBJDIRS += tests/data tests/vsynth1
 
 tests/vsynth1/00.pgm: tests/videogen$(HOSTEXESUF) | tests/vsynth1
@@ -18,7 +30,16 @@
 tests/data/vsynth2.yuv: tests/rotozoom$(HOSTEXESUF) | tests/data
 	$(M)$< $(SRC_PATH)/tests/lena.pnm $@
 
-tests/data/asynth% tests/data/vsynth%.yuv tests/vsynth%/00.pgm: TAG = GEN
+tests/data/ffprobe-test.nut: ffmpeg$(EXESUF) | tests/data
+	$(M)$(TARGET_EXEC) ./$< \
+        -f lavfi -i "aevalsrc=sin(400*PI*2*t)::d=0.125[out0]; testsrc=d=0.125[out1]; testsrc=s=100x100:d=0.125[out2]" \
+        -f ffmetadata -i $(SRC_PATH)/tests/test.ffmeta \
+        -flags +bitexact -map 0:0 -map 0:1 -map 0:2 -map_metadata 1 \
+        -map_metadata:s:0 1:s:0 -map_metadata:s:1 1:s:1 \
+        -vcodec rawvideo -acodec pcm_s16le \
+        -y $@ 2>/dev/null
+
+tests/data/%.sw tests/data/asynth% tests/data/vsynth%.yuv tests/vsynth%/00.pgm tests/data/%.nut: TAG = GEN
 
 include $(SRC_PATH)/tests/fate/acodec.mak
 include $(SRC_PATH)/tests/fate/vcodec.mak
@@ -40,6 +61,7 @@
 include $(SRC_PATH)/tests/fate/dfa.mak
 include $(SRC_PATH)/tests/fate/dpcm.mak
 include $(SRC_PATH)/tests/fate/ea.mak
+include $(SRC_PATH)/tests/fate/ffprobe.mak
 include $(SRC_PATH)/tests/fate/filter.mak
 include $(SRC_PATH)/tests/fate/flac.mak
 include $(SRC_PATH)/tests/fate/fft.mak
@@ -49,11 +71,13 @@
 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
@@ -61,6 +85,7 @@
 include $(SRC_PATH)/tests/fate/qtrle.mak
 include $(SRC_PATH)/tests/fate/real.mak
 include $(SRC_PATH)/tests/fate/screen.mak
+include $(SRC_PATH)/tests/fate/subtitles.mak
 include $(SRC_PATH)/tests/fate/utvideo.mak
 include $(SRC_PATH)/tests/fate/video.mak
 include $(SRC_PATH)/tests/fate/voice.mak
@@ -70,6 +95,7 @@
 include $(SRC_PATH)/tests/fate/wavpack.mak
 include $(SRC_PATH)/tests/fate/wma.mak
 
+FATE_LAVF_FATE = $(LAVF_FATE_TESTS:%=fate-lavf-fate-%)
 FATE_LAVF    = $(LAVF_TESTS:%=fate-lavf-%)
 FATE_LAVFI   = $(LAVFI_TESTS:%=fate-lavfi-%)
 FATE_SEEK    = $(SEEK_TESTS:seek_%=fate-seek-%)
@@ -78,48 +104,59 @@
                $(FATE_LAVFI)                                            \
                $(FATE_SEEK)                                             \
 
-FATE_AVCONV += $(FATE_AVCONV-yes)
-FATE-$(CONFIG_AVCONV) += $(FATE_AVCONV)
+FATE_FFMPEG += $(FATE_FFMPEG-yes) $(FATE_AVCONV) $(FATE_AVCONV-yes)
+FATE-$(CONFIG_FFMPEG) += $(FATE_FFMPEG)
+FATE-$(CONFIG_FFPROBE) += $(FATE_FFPROBE)
 
 FATE-$(CONFIG_AVCODEC)  += $(FATE_LIBAVCODEC)
 FATE-$(CONFIG_AVFORMAT) += $(FATE_LIBAVFORMAT)
 
-FATE_SAMPLES-$(CONFIG_AVCONV) += $(FATE_SAMPLES_AVCONV)
-FATE_SAMPLES += $(FATE_SAMPLES-yes)
+FATE_EXTERN-$(CONFIG_FFMPEG) += $(FATE_SAMPLES_AVCONV) $(FATE_SAMPLES_FFMPEG)
+FATE_EXTERN += $(FATE_EXTERN-yes)
 
 FATE += $(FATE-yes)
 FATE += $(FATE_LIBAVUTIL)
 
-$(FATE_AVCONV) $(FATE_SAMPLES_AVCONV): avconv$(EXESUF)
+$(FATE_FFMPEG) $(FATE_LAVF_FATE) $(FATE_SAMPLES_AVCONV) $(FATE_SAMPLES_FFMPEG): ffmpeg$(EXESUF)
+
+$(FATE_FFPROBE): ffprobe$(EXESUF)
 
 $(FATE_LAVF):  $(AREF) $(VREF)
 $(FATE_LAVFI): $(VREF) libavfilter/filtfmts-test$(EXESUF)
 $(FATE_SEEK):  fate-acodec fate-vsynth2 fate-lavf libavformat/seek-test$(EXESUF)
 
+$(FATE_LAVF_FATE): CMD = lavffatetest
 $(FATE_LAVF):    CMD = lavftest
 $(FATE_LAVFI):   CMD = lavfitest
 $(FATE_SEEK):    CMD = seektest
 
+fate-lavf-fate: $(FATE_LAVF_FATE)
 fate-lavf:   $(FATE_LAVF)
 fate-lavfi:  $(FATE_LAVFI)
 fate-seek:   $(FATE_SEEK)
 
 ifdef SAMPLES
-FATE += $(FATE_SAMPLES)
+FATE += $(FATE_LAVF_FATE)
+FATE += $(FATE_FULL) $(FATE_FULL-yes)
+FATE += $(FATE_EXTERN)
 fate-rsync:
-	rsync -vaLW rsync://fate-suite.libav.org/fate-suite/ $(SAMPLES)
+	rsync -vaLW --timeout=60 --contimeout=60 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"
 fate-rsync:
 	@echo "use 'make fate-rsync SAMPLES=/path/to/samples' to sync the fate suite"
-$(FATE_SAMPLES):
+$(FATE_EXTERN):
 	@echo "$@ requires external samples and SAMPLES not specified"; false
 endif
 
 FATE_UTILS = base64 tiny_psnr
 
-fate: $(FATE)
+TOOL = ffmpeg
 
-$(FATE): $(FATE_UTILS:%=tests/%$(HOSTEXESUF))
+fate:: $(FATE)
+
+$(FATE) $(FATE_TESTS-no): $(FATE_UTILS:%=tests/%$(HOSTEXESUF))
 	@echo "TEST    $(@:fate-%=%)"
 	$(Q)$(SRC_PATH)/tests/fate-run.sh $@ "$(SAMPLES)" "$(TARGET_EXEC)" "$(TARGET_PATH)" '$(CMD)' '$(CMP)' '$(REF)' '$(FUZZ)' '$(THREADS)' '$(THREAD_TYPE)' '$(CPUFLAGS)' '$(CMP_SHIFT)' '$(CMP_TARGET)' '$(SIZE_TOLERANCE)' '$(CMP_UNIT)'
 
@@ -129,7 +166,7 @@
 clean:: testclean
 
 testclean:
-	$(RM) -r tests/vsynth1 tests/data
+	$(RM) -r tests/vsynth1 tests/data tools/lavfi-showfiltfmts$(EXESUF)
 	$(RM) $(CLEANSUFFIXES:%=tests/%)
 	$(RM) $(TESTTOOLS:%=tests/%$(HOSTEXESUF))
 
diff --git a/tests/asynth1.sw b/tests/asynth1.sw
new file mode 100644
index 0000000..adda4d5
--- /dev/null
+++ b/tests/asynth1.sw
Binary files differ
diff --git a/tests/audiogen.c b/tests/audiogen.c
index acb380d..07f0be3 100644
--- a/tests/audiogen.c
+++ b/tests/audiogen.c
@@ -4,20 +4,20 @@
  *
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/tests/base64.c b/tests/base64.c
index 6462d9a..5035ad9 100644
--- a/tests/base64.c
+++ b/tests/base64.c
@@ -1,18 +1,18 @@
 /*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/tests/copycooker.sh b/tests/copycooker.sh
new file mode 100755
index 0000000..4b5811d
--- /dev/null
+++ b/tests/copycooker.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+LC_ALL=C
+export LC_ALL
+
+datadir="tests/data"
+
+logfile="$datadir/copy.regression"
+reffile="$1"
+
+list=$(grep -oh ' ./tests/data/.*' tests/ref/{acodec,lavf,vsynth1}/*| sort)
+rm -f $logfile
+for i in $list ; do
+    echo ---------------- >> $logfile
+    echo $i >> $logfile
+    ./ffmpeg_g -flags +bitexact -i $i -acodec copy -vcodec copy -y first.nut
+    ./ffmpeg_g -flags +bitexact -i first.nut -acodec copy -vcodec copy -y second.nut
+    cmp first.nut second.nut >> $logfile
+    md5sum first.nut >> $logfile
+done
+
+if diff -u -w "$reffile" "$logfile" ; then
+    echo
+    echo copy regression test: success
+    exit 0
+else
+    echo
+    echo copy regression test: error
+    exit 1
+fi
diff --git a/tests/fate-run.sh b/tests/fate-run.sh
index 09776d6..ccd04a3 100755
--- a/tests/fate-run.sh
+++ b/tests/fate-run.sh
@@ -71,37 +71,37 @@
 }
 
 probefmt(){
-    run avprobe -show_format_entry format_name -v 0 "$@"
+    run ffprobe -show_format_entry format_name -print_format default=nw=1:nk=1 -v 0 "$@"
 }
 
-avconv(){
+ffmpeg(){
     dec_opts="-threads $threads -thread_type $thread_type"
-    avconv_args="-nostats -cpuflags $cpuflags"
+    ffmpeg_args="-nostats -cpuflags $cpuflags"
     for arg in $@; do
-        [ ${arg} = -i ] && avconv_args="${avconv_args} ${dec_opts}"
-        avconv_args="${avconv_args} ${arg}"
+        [ ${arg} = -i ] && ffmpeg_args="${ffmpeg_args} ${dec_opts}"
+        ffmpeg_args="${ffmpeg_args} ${arg}"
     done
-    run avconv ${avconv_args}
+    run ffmpeg ${ffmpeg_args}
 }
 
 framecrc(){
-    avconv "$@" -f framecrc -
+    ffmpeg "$@" -f framecrc -
 }
 
 framemd5(){
-    avconv "$@" -f framemd5 -
+    ffmpeg "$@" -f framemd5 -
 }
 
 crc(){
-    avconv "$@" -f crc -
+    ffmpeg "$@" -f crc -
 }
 
 md5(){
-    avconv "$@" md5:
+    ffmpeg "$@" md5:
 }
 
 pcm(){
-    avconv "$@" -vn -f s16le -
+    ffmpeg "$@" -vn -f s16le -
 }
 
 enc_dec_pcm(){
@@ -113,8 +113,8 @@
     encfile="${outdir}/${test}.${out_fmt}"
     cleanfiles=$encfile
     encfile=$(target_path ${encfile})
-    avconv -i $src_file "$@" -f $out_fmt -y ${encfile} || return
-    avconv -f $out_fmt -i ${encfile} -c:a pcm_${pcm_fmt} -f ${dec_fmt} -
+    ffmpeg -i $src_file "$@" -f $out_fmt -y ${encfile} || return
+    ffmpeg -flags +bitexact -i ${encfile} -c:a pcm_${pcm_fmt} -f ${dec_fmt} -
 }
 
 FLAGS="-flags +bitexact -sws_flags +accurate_rnd+bitexact"
@@ -135,11 +135,11 @@
     tsrcfile=$(target_path $srcfile)
     tencfile=$(target_path $encfile)
     tdecfile=$(target_path $decfile)
-    avconv -f $src_fmt $DEC_OPTS -i $tsrcfile $ENC_OPTS $enc_opt $FLAGS \
+    ffmpeg -f $src_fmt $DEC_OPTS -i $tsrcfile $ENC_OPTS $enc_opt $FLAGS \
         -f $enc_fmt -y $tencfile || return
     do_md5sum $encfile
     echo $(wc -c $encfile)
-    avconv $DEC_OPTS -i $tencfile $ENC_OPTS $dec_opt $FLAGS \
+    ffmpeg $8 $DEC_OPTS -i $tencfile $ENC_OPTS $dec_opt $FLAGS \
         -f $dec_fmt -y $tdecfile || return
     do_md5sum $decfile
     tests/tiny_psnr $srcfile $decfile $cmp_unit $cmp_shift
@@ -148,7 +148,11 @@
 regtest(){
     t="${test#$2-}"
     ref=${base}/ref/$2/$t
-    ${base}/${1}-regression.sh $t $2 $3 "$target_exec" "$target_path" "$threads" "$thread_type" "$cpuflags"
+    ${base}/${1}-regression.sh $t $2 $3 "$target_exec" "$target_path" "$threads" "$thread_type" "$cpuflags" "$samples"
+}
+
+lavffatetest(){
+    regtest lavf lavf-fate tests/vsynth1
 }
 
 lavftest(){
@@ -204,5 +208,9 @@
 
 echo "${test}:${sig:-$err}:$($base64 <$cmpfile):$($base64 <$errfile)" >$repfile
 
-test $err = 0 && rm -f $outfile $errfile $cmpfile $cleanfiles
+if test $err = 0; then
+    rm -f $outfile $errfile $cmpfile $cleanfiles
+else
+    echo "Test $test failed. Look at $errfile for details."
+fi
 exit $err
diff --git a/tests/fate-update.sh b/tests/fate-update.sh
new file mode 100755
index 0000000..6b4668f
--- /dev/null
+++ b/tests/fate-update.sh
@@ -0,0 +1,55 @@
+#! /bin/sh
+
+set -e
+
+base=$(dirname $0)
+ref="${base}/ref/fate"
+
+FATE_DB_URL="http://fate.multimedia.cx/fate-tests.sqlite.bz2"
+FATE_DB=$(mktemp fate-db.XXXXXX)
+SQL_TESTS='SELECT id,short_name,command FROM test_spec WHERE active=1 ORDER BY short_name'
+
+do_sql(){
+    sqlite3 -noheader -separator ' ' "$FATE_DB" "$@"
+}
+
+wget -q -O - "$FATE_DB_URL" | bunzip2 > "$FATE_DB"
+mkdir -p "$ref"
+exec 3>"$base/fate.mak"
+
+do_sql "$SQL_TESTS" | while read id name command; do
+    case "$name" in
+        00-full-regression|ffmpeg-help|binsize-*) continue ;;
+    esac
+    case "$command" in
+        {MD5}*)
+            command="${command#*ffmpeg}"; command="${command% -}"
+            command="md5 $command"
+            ;;
+        {*}*)   continue ;;
+        *-f\ framecrc\ -)
+            command="${command#*ffmpeg}"; command="${command% -f *}"
+            command="framecrc $command"
+            ;;
+        *-f\ framemd5\ -)
+            command="${command#*ffmpeg}"; command="${command% -f *}"
+            command="framemd5 $command"
+            ;;
+        *-f\ crc\ -)
+            command="${command#*ffmpeg}"; command="${command% -f *}"
+            command="crc $command"
+            ;;
+        *)
+            echo "Unhandled command '$command'"
+            exit 1
+            ;;
+    esac
+    command=$(echo "$command" | sed 's/\$SAMPLES_PATH/$(SAMPLES)/g')
+    command=$(echo "$command" | sed 's/ *$//')
+    do_sql "SELECT expected_stdout FROM test_spec WHERE id=$id" | awk '/./{print}' > "$ref/$name"
+    printf "FATE_TESTS += fate-${name}\n" >&3
+    printf "fate-${name}: CMD = %s\n" "$command" >&3
+done
+
+exec 3<&-
+rm -f "$FATE_DB"
diff --git a/tests/fate-valgrind.supp b/tests/fate-valgrind.supp
new file mode 100644
index 0000000..db72c54
--- /dev/null
+++ b/tests/fate-valgrind.supp
@@ -0,0 +1,31 @@
+# seems fixed in newer versions
+# http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=577135
+{
+   zlib-inflate
+   Memcheck:Cond
+   fun:inflateReset2
+   fun:inflateInit2_
+}
+# libc overreads on purpose
+# http://sourceware.org/bugzilla/show_bug.cgi?id=12424
+{
+   eval-strtod
+   Memcheck:Addr8
+   fun:__GI___strncasecmp_l
+   fun:____strtod_l_internal
+   fun:av_strtod
+}
+{
+   eval-strtod
+   Memcheck:Value8
+   fun:__GI___strncasecmp_l
+   fun:____strtod_l_internal
+   fun:av_strtod
+}
+{
+   eval-strtod
+   Memcheck:Cond
+   fun:__GI___strncasecmp_l
+   fun:____strtod_l_internal
+   fun:av_strtod
+}
diff --git a/tests/fate.sh b/tests/fate.sh
index 86e4178..1f70e79 100755
--- a/tests/fate.sh
+++ b/tests/fate.sh
@@ -41,10 +41,11 @@
 
 configure()(
     cd ${build} || return
-    ${src}/configure                                                    \
+    ${shell} ${src}/configure                                           \
         --prefix="${inst}"                                              \
         --samples="${samples}"                                          \
         --enable-gpl                                                    \
+        --enable-memory-poisoning                                       \
         ${arch:+--arch=$arch}                                           \
         ${cpu:+--cpu="$cpu"}                                            \
         ${cross_prefix:+--cross-prefix="$cross_prefix"}                 \
diff --git a/tests/fate/aac.mak b/tests/fate/aac.mak
index 9d52dae..1ac17f1 100644
--- a/tests/fate/aac.mak
+++ b/tests/fate/aac.mak
@@ -71,7 +71,25 @@
 
 FATE_AAC += $(FATE_AAC_CT:%=fate-aac-ct-%)
 
-FATE_SAMPLES_AVCONV += $(FATE_AAC)
-fate-aac: $(FATE_AAC)
+FATE_AAC_ENCODE += fate-aac-aref-encode
+fate-aac-aref-encode: ./tests/data/asynth-44100-2.wav
+fate-aac-aref-encode: CMD = enc_dec_pcm adts wav s16le $(REF) -strict -2 -c:a aac -b:a 512k
+fate-aac-aref-encode: CMP = stddev
+fate-aac-aref-encode: REF = ./tests/data/asynth-44100-2.wav
+fate-aac-aref-encode: CMP_SHIFT = -4096
+fate-aac-aref-encode: CMP_TARGET = 1862
+fate-aac-aref-encode: SIZE_TOLERANCE = 2464
+
+FATE_AAC_ENCODE += fate-aac-ln-encode
+fate-aac-ln-encode: CMD = enc_dec_pcm adts wav s16le $(REF) -strict -2 -c:a aac -b:a 512k
+fate-aac-ln-encode: CMP = stddev
+fate-aac-ln-encode: REF = $(SAMPLES)/audio-reference/luckynight_2ch_44kHz_s16.wav
+fate-aac-ln-encode: CMP_SHIFT = -4096
+fate-aac-ln-encode: CMP_TARGET = 65
+fate-aac-ln-encode: SIZE_TOLERANCE = 3560
+
+FATE_SAMPLES_FFMPEG += $(FATE_AAC) $(FATE_AAC_ENCODE)
+fate-aac: $(FATE_AAC) $(FATE_AAC_ENCODE)
+
 $(FATE_AAC): CMP = oneoff
 $(FATE_AAC): FUZZ = 2
diff --git a/tests/fate/ac3.mak b/tests/fate/ac3.mak
index b2bfb8e..b19b945 100644
--- a/tests/fate/ac3.mak
+++ b/tests/fate/ac3.mak
@@ -49,7 +49,7 @@
 fate-ac3-encode: CMP_SHIFT = -1024
 fate-ac3-encode: CMP_TARGET = 399.62
 fate-ac3-encode: SIZE_TOLERANCE = 488
-fate-ac3-encode: FUZZ = 3
+fate-ac3-encode: FUZZ = 4
 
 FATE_AC3_ENCODE += fate-eac3-encode
 fate-eac3-encode: CMD = enc_dec_pcm eac3 wav s16le $(REF) -c:a eac3 -b:a 128k
@@ -64,7 +64,7 @@
 FATE_AC3_ENCODE += fate-ac3-fixed-encode
 fate-ac3-fixed-encode: tests/data/asynth-44100-2.wav
 fate-ac3-fixed-encode: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav
-fate-ac3-fixed-encode: CMD = md5 -i $(SRC) -c ac3_fixed -b 128k -f ac3 -flags bitexact
+fate-ac3-fixed-encode: CMD = md5 -i $(SRC) -c ac3_fixed -ab 128k -f ac3 -flags +bitexact
 fate-ac3-fixed-encode: CMP = oneline
 fate-ac3-fixed-encode: REF = a1d1fc116463b771abf5aef7ed37d7b1
 
diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak
index b4d0cea..31f3441 100644
--- a/tests/fate/acodec.mak
+++ b/tests/fate/acodec.mak
@@ -1,6 +1,6 @@
 fate-acodec-%: CODEC = $(@:fate-acodec-%=%)
 fate-acodec-%: SRC = tests/data/asynth-44100-2.wav
-fate-acodec-%: CMD = enc_dec wav $(SRC) $(FMT) "-b 128k -c $(CODEC)" wav "-c pcm_s16le" -keep
+fate-acodec-%: CMD = enc_dec wav $(SRC) $(FMT) "-b 128k -c $(CODEC) $(ENCOPTS)" wav "-c pcm_s16le $(DECOPTS)" -keep
 fate-acodec-%: CMP_UNIT = 2
 
 FATE_ACODEC_PCM = alaw mulaw                                            \
@@ -40,10 +40,48 @@
 fate-acodec-alac: FMT = mov
 fate-acodec-alac: CODEC = alac -compression_level 1
 
+FATE_ACODEC += fate-acodec-dca
+fate-acodec-dca: tests/data/asynth-44100-2.wav
+fate-acodec-dca: SRC = tests/data/asynth-44100-2.wav
+fate-acodec-dca: CMD = md5 -i $(TARGET_PATH)/$(SRC) -c:a dca -strict -2 -f dts -flags +bitexact
+fate-acodec-dca: CMP = oneline
+fate-acodec-dca: REF = 66bd0e602be7fb97dc19151554c0ee29
+
+FATE_ACODEC += fate-acodec-dca2
+fate-acodec-dca2: CMD = enc_dec_pcm dts wav s16le $(SRC) -c:a dca -strict -2 -flags +bitexact
+fate-acodec-dca2: REF = $(SRC)
+fate-acodec-dca2: CMP = stddev
+fate-acodec-dca2: CMP_SHIFT = -1920
+fate-acodec-dca2: CMP_TARGET = 2424
+fate-acodec-dca2: SIZE_TOLERANCE = 544
+
 FATE_ACODEC += fate-acodec-flac
 fate-acodec-flac: FMT = flac
 fate-acodec-flac: CODEC = flac -compression_level 2
 
+FATE_ACODEC += fate-acodec-g723_1
+fate-acodec-g723_1: tests/data/asynth-8000-1.wav
+fate-acodec-g723_1: SRC = tests/data/asynth-8000-1.wav
+fate-acodec-g723_1: FMT = g723_1
+fate-acodec-g723_1: CODEC = g723_1
+fate-acodec-g723_1: ENCOPTS = -b:a 6.3k
+fate-acodec-g723_1: CMP_SHIFT = 8
+
+FATE_ACODEC += fate-acodec-ra144
+fate-acodec-ra144: tests/data/asynth-8000-1.wav
+fate-acodec-ra144: SRC = tests/data/asynth-8000-1.wav
+fate-acodec-ra144: CMD = enc_dec_pcm rm wav s16le $(SRC) -c:a real_144
+fate-acodec-ra144: REF = $(SRC)
+fate-acodec-ra144: CMP = stddev
+fate-acodec-ra144: CMP_TARGET = 4777
+fate-acodec-ra144: CMP_SHIFT = -320
+
+FATE_ACODEC += fate-acodec-roqaudio
+fate-acodec-roqaudio: FMT = roq
+fate-acodec-roqaudio: CODEC = roq_dpcm
+fate-acodec-roqaudio: ENCOPTS = -ar 22050
+fate-acodec-roqaudio: DECOPTS = -ar 44100
+
 $(FATE_ACODEC): tests/data/asynth-44100-2.wav
 
 FATE_AVCONV += $(FATE_ACODEC)
diff --git a/tests/fate/audio.mak b/tests/fate/audio.mak
index 86f78dd..44b0c24 100644
--- a/tests/fate/audio.mak
+++ b/tests/fate/audio.mak
@@ -10,35 +10,53 @@
 
 $(FATE_BINKAUDIO): CMP = oneoff
 
-FATE_SAMPLES_AVCONV += $(FATE_BINKAUDIO)
+FATE_SAMPLES_AUDIO += $(FATE_BINKAUDIO)
 fate-binkaudio: $(FATE_BINKAUDIO)
 
-FATE_SAMPLES_AVCONV += fate-bmv-audio
+FATE_SAMPLES_AUDIO += fate-bmv-audio
 fate-bmv-audio: CMD = framecrc -i $(SAMPLES)/bmv/SURFING-partial.BMV -vn
 
-FATE_SAMPLES_AVCONV += fate-delphine-cin-audio
+FATE_SAMPLES_AUDIO += fate-delphine-cin-audio
 fate-delphine-cin-audio: CMD = framecrc -i $(SAMPLES)/delphine-cin/LOGO-partial.CIN -vn
 
-FATE_SAMPLES_AVCONV += fate-dts
+FATE_SAMPLES_AUDIO += fate-dts
 fate-dts: CMD = pcm -i $(SAMPLES)/dts/dts.ts
 fate-dts: CMP = oneoff
 fate-dts: REF = $(SAMPLES)/dts/dts.pcm
 
-FATE_SAMPLES_AVCONV += fate-imc
+FATE_SAMPLES_AUDIO += fate-imc
 fate-imc: CMD = pcm -i $(SAMPLES)/imc/imc.avi
 fate-imc: CMP = oneoff
 fate-imc: REF = $(SAMPLES)/imc/imc.pcm
 
-FATE_SAMPLES_AVCONV += fate-nellymoser
+FATE_SAMPLES_AUDIO += fate-nellymoser
 fate-nellymoser: CMD = pcm -i $(SAMPLES)/nellymoser/nellymoser.flv
 fate-nellymoser: CMP = oneoff
 fate-nellymoser: REF = $(SAMPLES)/nellymoser/nellymoser.pcm
 
-FATE_SAMPLES_AVCONV += fate-sierra-vmd-audio
+FATE_SAMPLES_AUDIO += fate-nellymoser-aref-encode
+fate-nellymoser-aref-encode: $(AREF) ./tests/data/asynth-16000-1.wav
+fate-nellymoser-aref-encode: CMD = enc_dec_pcm flv wav s16le $(REF) -c:a nellymoser
+fate-nellymoser-aref-encode: CMP = stddev
+fate-nellymoser-aref-encode: REF = ./tests/data/asynth-16000-1.wav
+fate-nellymoser-aref-encode: CMP_SHIFT = -244
+fate-nellymoser-aref-encode: CMP_TARGET = 9612
+fate-nellymoser-aref-encode: SIZE_TOLERANCE = 268
+
+FATE_SAMPLES_AUDIO += fate-paf-audio
+fate-paf-audio: CMD = framecrc -i $(SAMPLES)/paf/hod1-partial.paf -vn
+
+FATE_SAMPLES_AUDIO += fate-sierra-vmd-audio
 fate-sierra-vmd-audio: CMD = framecrc -i $(SAMPLES)/vmd/12.vmd -vn
 
-FATE_SAMPLES_AVCONV += fate-smacker-audio
+FATE_SAMPLES_AUDIO += fate-smacker-audio
 fate-smacker-audio: CMD = framecrc -i $(SAMPLES)/smacker/wetlogo.smk -vn
 
-FATE_SAMPLES_AVCONV += fate-ws_snd
+FATE_SAMPLES_AUDIO += fate-vima
+fate-vima: CMD = framecrc -i $(SAMPLES)/smush/ronin_part.znm -vn
+
+FATE_SAMPLES_AUDIO += fate-ws_snd
 fate-ws_snd: CMD = md5 -i $(SAMPLES)/vqa/ws_snd.vqa -f s16le
+
+FATE_SAMPLES_FFMPEG += $(FATE_SAMPLES_AUDIO)
+fate-audio: $(FATE_SAMPLES_AUDIO)
diff --git a/tests/fate/demux.mak b/tests/fate/demux.mak
index d9fe629..f6031b8 100644
--- a/tests/fate/demux.mak
+++ b/tests/fate/demux.mak
@@ -1,71 +1,83 @@
-FATE_SAMPLES_AVCONV += fate-adts-demux
+FATE_SAMPLES_DEMUX += fate-avio-direct
+fate-avio-direct: CMD = framecrc -avioflags direct -i $(SAMPLES)/fraps/fraps-v5-bouncing-balls-partial.avi -avioflags direct
+
+FATE_SAMPLES_DEMUX += fate-adts-demux
 fate-adts-demux: CMD = crc -i $(SAMPLES)/aac/ct_faac-adts.aac -acodec copy
 
-FATE_SAMPLES_AVCONV += fate-aea-demux
+FATE_SAMPLES_DEMUX += fate-aea-demux
 fate-aea-demux: CMD = crc -i $(SAMPLES)/aea/chirp.aea -acodec copy
 
-FATE_SAMPLES_AVCONV += fate-bink-demux
+FATE_SAMPLES_DEMUX += fate-bink-demux
 fate-bink-demux: CMD = crc -i $(SAMPLES)/bink/Snd0a7d9b58.dee -vn -acodec copy
 
-FATE_SAMPLES_AVCONV += fate-caf
+FATE_SAMPLES_DEMUX += fate-caf
 fate-caf: CMD = crc -i $(SAMPLES)/caf/caf-pcm16.caf -c copy
 
-FATE_SAMPLES_AVCONV += fate-cdxl-demux
+FATE_SAMPLES_DEMUX += fate-cdxl-demux
 fate-cdxl-demux: CMD = framecrc -i $(SAMPLES)/cdxl/mirage.cdxl -vcodec copy -acodec copy
 
-FATE_SAMPLES_AVCONV += fate-d-cinema-demux
+FATE_SAMPLES_DEMUX += fate-d-cinema-demux
 fate-d-cinema-demux: CMD = framecrc -i $(SAMPLES)/d-cinema/THX_Science_FLT_1920-partial.302 -acodec copy
 
-FATE_SAMPLES_AVCONV += fate-iv8-demux
+FATE_SAMPLES_DEMUX += fate-iv8-demux
 fate-iv8-demux: CMD = framecrc -i $(SAMPLES)/iv8/zzz-partial.mpg -vcodec copy
 
-FATE_SAMPLES_AVCONV += fate-lmlm4-demux
+FATE_SAMPLES_DEMUX += fate-jv-demux
+fate-jv-demux: CMD = framecrc -i $(SAMPLES)/jv/intro.jv -vcodec copy -acodec copy
+
+FATE_SAMPLES_DEMUX += fate-lmlm4-demux
 fate-lmlm4-demux: CMD = framecrc -i $(SAMPLES)/lmlm4/LMLM4_CIFat30fps.divx -t 3 -acodec copy -vcodec copy
 
-FATE_SAMPLES_AVCONV += fate-maxis-xa
+FATE_SAMPLES_DEMUX += fate-maxis-xa
 fate-maxis-xa: CMD = framecrc -i $(SAMPLES)/maxis-xa/SC2KBUG.XA -frames:a 30 -c:a copy
 
-FATE_SAMPLES_AVCONV += fate-mtv
+FATE_SAMPLES_DEMUX += fate-mtv
 fate-mtv: CMD = framecrc -i $(SAMPLES)/mtv/comedian_auto-partial.mtv -c copy
 
-FATE_SAMPLES_AVCONV += fate-mxf-demux
+FATE_SAMPLES_DEMUX += fate-mxf-demux
 fate-mxf-demux: CMD = framecrc -i $(SAMPLES)/mxf/C0023S01.mxf -acodec copy -vcodec copy
 
-FATE_SAMPLES_AVCONV += fate-nc-demux
+FATE_SAMPLES_DEMUX += fate-nc-demux
 fate-nc-demux: CMD = framecrc -i $(SAMPLES)/nc-camera/nc-sample-partial -vcodec copy
 
-FATE_SAMPLES_AVCONV += fate-nsv-demux
+FATE_SAMPLES_DEMUX += fate-nsv-demux
 fate-nsv-demux: CMD = framecrc -i $(SAMPLES)/nsv/witchblade-51kbps.nsv -t 6 -vcodec copy -acodec copy
 
-FATE_SAMPLES_AVCONV += fate-oma-demux
+FATE_SAMPLES_DEMUX += fate-oma-demux
 fate-oma-demux: CMD = crc -i $(SAMPLES)/oma/01-Untitled-partial.oma -acodec copy
 
-FATE_SAMPLES_AVCONV += fate-psx-str-demux
+FATE_SAMPLES_DEMUX += fate-paf-demux
+fate-paf-demux: CMD = framecrc -i $(SAMPLES)/paf/hod1-partial.paf -vcodec copy -acodec copy
+
+FATE_SAMPLES_DEMUX += fate-psx-str-demux
 fate-psx-str-demux: CMD = framecrc -i $(SAMPLES)/psx-str/descent-partial.str -c copy
 
-FATE_SAMPLES_AVCONV += fate-pva-demux
-fate-pva-demux: CMD = framecrc -idct simple -i $(SAMPLES)/pva/PVA_test-partial.pva -t 0.6 -acodec copy -vn
+FATE_SAMPLES_DEMUX += fate-pva-demux
+fate-pva-demux: CMD = framecrc -idct simple -i $(SAMPLES)/pva/PVA_test-partial.pva -t 0.6 -acodec copy
 
-FATE_SAMPLES_AVCONV += fate-qcp-demux
+FATE_SAMPLES_DEMUX += fate-qcp-demux
 fate-qcp-demux: CMD = crc -i $(SAMPLES)/qcp/0036580847.QCP -acodec copy
 
-FATE_SAMPLES_AVCONV += fate-redcode-demux
+FATE_SAMPLES_DEMUX += fate-redcode-demux
 fate-redcode-demux: CMD = framecrc -i $(SAMPLES)/r3d/4MB-sample.r3d -vcodec copy -acodec copy
 
-FATE_SAMPLES_AVCONV += fate-siff
+FATE_SAMPLES_DEMUX += fate-siff
 fate-siff: CMD = framecrc -i $(SAMPLES)/SIFF/INTRO_B.VB -t 3 -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-smjpeg-demux
+FATE_SAMPLES_DEMUX += fate-smjpeg-demux
 fate-smjpeg-demux: CMD = framecrc -i $(SAMPLES)/smjpeg/scenwin.mjpg -c copy
 
-FATE_SAMPLES_AVCONV += fate-westwood-aud
+FATE_SAMPLES_DEMUX += fate-westwood-aud
 fate-westwood-aud: CMD = framecrc -i $(SAMPLES)/westwood-aud/excellent.aud -c copy
 
-FATE_SAMPLES_AVCONV += fate-wtv-demux
+FATE_SAMPLES_DEMUX += fate-wtv-demux
 fate-wtv-demux: CMD = framecrc -i $(SAMPLES)/wtv/law-and-order-partial.wtv -vcodec copy -acodec copy
 
-FATE_SAMPLES_AVCONV += fate-xmv-demux
+FATE_SAMPLES_DEMUX += fate-xmv-demux
 fate-xmv-demux: CMD = framecrc -i $(SAMPLES)/xmv/logos1p.fmv -vcodec copy -acodec copy
 
-FATE_SAMPLES_AVCONV += fate-xwma-demux
+FATE_SAMPLES_DEMUX += fate-xwma-demux
 fate-xwma-demux: CMD = crc -i $(SAMPLES)/xwma/ergon.xwma -acodec copy
+
+FATE_SAMPLES_FFMPEG += $(FATE_SAMPLES_DEMUX)
+fate-demux: $(FATE_SAMPLES_DEMUX)
diff --git a/tests/fate/ea.mak b/tests/fate/ea.mak
index 59745fa..2f7f2ad 100644
--- a/tests/fate/ea.mak
+++ b/tests/fate/ea.mak
@@ -1,20 +1,23 @@
-FATE_SAMPLES_AVCONV += fate-ea-cdata
+FATE_SAMPLES_EA += fate-ea-cdata
 fate-ea-cdata: CMD = md5 -i $(SAMPLES)/ea-cdata/166b084d.46410f77.0009b440.24be960c.cdata -f s16le
 
-FATE_SAMPLES_AVCONV += fate-ea-cmv
+FATE_SAMPLES_EA += fate-ea-cmv
 fate-ea-cmv: CMD = framecrc -i $(SAMPLES)/ea-cmv/TITLE.CMV -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-ea-tgq
+FATE_SAMPLES_EA += fate-ea-tgq
 fate-ea-tgq: CMD = framecrc -i $(SAMPLES)/ea-tgq/v27.tgq -an
 
-FATE_SAMPLES_AVCONV += fate-ea-tqi
+FATE_SAMPLES_EA += fate-ea-tqi
 fate-ea-tqi: CMD = framecrc -i $(SAMPLES)/ea-wve/networkBackbone-partial.wve -frames:v 26 -an
 
-FATE_SAMPLES_AVCONV += fate-ea-mad
+FATE_SAMPLES_EA += fate-ea-mad
 fate-ea-mad: CMD = framecrc -i $(SAMPLES)/ea-mad/NFS6LogoE.mad -an
 
-FATE_SAMPLES_AVCONV += fate-ea-tgv-1
+FATE_SAMPLES_EA += fate-ea-tgv-1
 fate-ea-tgv-1: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTRO8K-partial.TGV -pix_fmt rgb24 -an
 
-FATE_SAMPLES_AVCONV += fate-ea-tgv-2
+FATE_SAMPLES_EA += fate-ea-tgv-2
 fate-ea-tgv-2: CMD = framecrc -i $(SAMPLES)/ea-tgv/INTEL_S.TGV -pix_fmt rgb24 -an
+
+FATE_SAMPLES_FFMPEG += $(FATE_SAMPLES_EA)
+fate-ea: $(FATE_SAMPLES_EA)
diff --git a/tests/fate/ffprobe.mak b/tests/fate/ffprobe.mak
new file mode 100644
index 0000000..cf20185
--- /dev/null
+++ b/tests/fate/ffprobe.mak
@@ -0,0 +1,33 @@
+FFPROBE_TEST_FILE=tests/data/ffprobe-test.nut
+FFPROBE_COMMAND=ffprobe$(EXESUF) -show_streams -show_packets -show_format -show_frames -bitexact $(FFPROBE_TEST_FILE)
+
+FATE_FFPROBE += fate-ffprobe_compact
+fate-ffprobe_compact: $(FFPROBE_TEST_FILE)
+fate-ffprobe_compact: CMD = run $(FFPROBE_COMMAND) -of compact
+
+FATE_FFPROBE += fate-ffprobe_csv
+fate-ffprobe_csv: $(FFPROBE_TEST_FILE)
+fate-ffprobe_csv: CMD = run $(FFPROBE_COMMAND) -of csv
+
+FATE_FFPROBE += fate-ffprobe_default
+fate-ffprobe_default: $(FFPROBE_TEST_FILE)
+fate-ffprobe_default: CMD = run $(FFPROBE_COMMAND) -of default
+
+FATE_FFPROBE += fate-ffprobe_flat
+fate-ffprobe_flat: $(FFPROBE_TEST_FILE)
+fate-ffprobe_flat: CMD = run $(FFPROBE_COMMAND) -of flat
+
+FATE_FFPROBE += fate-ffprobe_ini
+fate-ffprobe_ini: $(FFPROBE_TEST_FILE)
+fate-ffprobe_ini: CMD = run $(FFPROBE_COMMAND) -of ini
+
+FATE_FFPROBE += fate-ffprobe_json
+fate-ffprobe_json: $(FFPROBE_TEST_FILE)
+fate-ffprobe_json: CMD = run $(FFPROBE_COMMAND) -of json
+
+FATE_FFPROBE += fate-ffprobe_xml
+fate-ffprobe_xml: $(FFPROBE_TEST_FILE)
+fate-ffprobe_xml: CMD = run $(FFPROBE_COMMAND) -of xml
+
+fate-ffprobe: $(FATE_FFPROBE)
+
diff --git a/tests/fate/filter.mak b/tests/fate/filter.mak
index f16aee1..3d563c8 100644
--- a/tests/fate/filter.mak
+++ b/tests/fate/filter.mak
@@ -1,15 +1,15 @@
 FATE_AMIX += fate-filter-amix-simple
-fate-filter-amix-simple: CMD = avconv -filter_complex amix -i $(SRC) -ss 3 -i $(SRC1) -f f32le -
+fate-filter-amix-simple: CMD = ffmpeg -filter_complex amix -i $(SRC) -ss 3 -i $(SRC1) -f f32le -
 fate-filter-amix-simple: REF = $(SAMPLES)/filter/amix_simple.pcm
 
 FATE_AMIX += fate-filter-amix-first
-fate-filter-amix-first: CMD = avconv -filter_complex amix=duration=first -ss 4 -i $(SRC) -i $(SRC1) -f f32le -
+fate-filter-amix-first: CMD = ffmpeg -filter_complex amix=duration=first -ss 4 -i $(SRC) -i $(SRC1) -f f32le -
 fate-filter-amix-first: REF = $(SAMPLES)/filter/amix_first.pcm
 
 FATE_AMIX += fate-filter-amix-transition
 fate-filter-amix-transition: tests/data/asynth-44100-2-3.wav
 fate-filter-amix-transition: SRC2 = $(TARGET_PATH)/tests/data/asynth-44100-2-3.wav
-fate-filter-amix-transition: CMD = avconv -filter_complex amix=inputs=3:dropout_transition=0.5 -i $(SRC) -ss 2 -i $(SRC1) -ss 4 -i $(SRC2) -f f32le -
+fate-filter-amix-transition: CMD = ffmpeg -filter_complex amix=inputs=3:dropout_transition=0.5 -i $(SRC) -ss 2 -i $(SRC1) -ss 4 -i $(SRC2) -f f32le -
 fate-filter-amix-transition: REF = $(SAMPLES)/filter/amix_transition.pcm
 
 $(FATE_AMIX): tests/data/asynth-44100-2.wav tests/data/asynth-44100-2-2.wav
@@ -24,7 +24,13 @@
 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.pcm
+fate-filter-asyncts: REF = $(SAMPLES)/nellymoser/nellymoser-discont-async.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: CMP = oneoff
+fate-filter-aresample: REF = $(SAMPLES)/nellymoser/nellymoser-discont.pcm
 
 fate-filter-delogo: CMD = framecrc -i $(SAMPLES)/real/rv30.rm -vf delogo=show=0:x=290:y=25:w=26:h=16 -an
 
diff --git a/tests/fate/h264.mak b/tests/fate/h264.mak
index 8f27995..113f9ca 100644
--- a/tests/fate/h264.mak
+++ b/tests/fate/h264.mak
@@ -113,6 +113,10 @@
             frext-hcafr3_hhi_a                                          \
             frext-hcafr4_hhi_a                                          \
             frext-hcamff1_hhi_b                                         \
+            frext-hi422fr10_sony_b                                      \
+            frext-hi422fr13_sony_b                                      \
+            frext-hi422fr1_sony_a                                       \
+            frext-hi422fr6_sony_a                                       \
             frext-hpca_brcm_c                                           \
             frext-hpcadq_brcm_b                                         \
             frext-hpcafl_bcrm_c                                         \
@@ -134,6 +138,13 @@
             frext-pph10i5_panasonic_a                                   \
             frext-pph10i6_panasonic_a                                   \
             frext-pph10i7_panasonic_a                                   \
+            frext-pph422i1_panasonic_a                                  \
+            frext-pph422i2_panasonic_a                                  \
+            frext-pph422i3_panasonic_a                                  \
+            frext-pph422i4_panasonic_a                                  \
+            frext-pph422i5_panasonic_a                                  \
+            frext-pph422i6_panasonic_a                                  \
+            frext-pph422i7_panasonic_a                                  \
             hcbp2_hhi_a                                                 \
             hcmp1_hhi_a                                                 \
             ls_sva_d                                                    \
@@ -180,178 +191,189 @@
 FATE_SAMPLES_AVCONV += $(FATE_H264)
 fate-h264: $(FATE_H264)
 
-fate-h264-conformance-aud_mw_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/AUD_MW_E.264
-fate-h264-conformance-ba1_ft_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/BA1_FT_C.264
-fate-h264-conformance-ba1_sony_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/BA1_Sony_D.jsv
-fate-h264-conformance-ba2_sony_f: CMD = framecrc -i $(SAMPLES)/h264-conformance/BA2_Sony_F.jsv
-fate-h264-conformance-ba3_sva_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/BA3_SVA_C.264
-fate-h264-conformance-ba_mw_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/BA_MW_D.264
-fate-h264-conformance-bamq1_jvc_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/BAMQ1_JVC_C.264
-fate-h264-conformance-bamq2_jvc_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/BAMQ2_JVC_C.264
-fate-h264-conformance-banm_mw_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/BANM_MW_D.264
-fate-h264-conformance-basqp1_sony_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/BASQP1_Sony_C.jsv
-fate-h264-conformance-caba1_sony_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/CABA1_Sony_D.jsv
-fate-h264-conformance-caba1_sva_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CABA1_SVA_B.264
-fate-h264-conformance-caba2_sony_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CABA2_Sony_E.jsv
-fate-h264-conformance-caba2_sva_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CABA2_SVA_B.264
-fate-h264-conformance-caba3_sony_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/CABA3_Sony_C.jsv
-fate-h264-conformance-caba3_sva_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CABA3_SVA_B.264
-fate-h264-conformance-caba3_toshiba_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CABA3_TOSHIBA_E.264
-fate-h264-conformance-cabac_mot_fld0_full: CMD = framecrc -i $(SAMPLES)/h264-conformance/camp_mot_fld0_full.26l
-fate-h264-conformance-cabac_mot_frm0_full: CMD = framecrc -i $(SAMPLES)/h264-conformance/camp_mot_frm0_full.26l
-fate-h264-conformance-cabac_mot_mbaff0_full: CMD = framecrc -i $(SAMPLES)/h264-conformance/camp_mot_mbaff0_full.26l
-fate-h264-conformance-cabac_mot_picaff0_full: CMD = framecrc -i $(SAMPLES)/h264-conformance/camp_mot_picaff0_full.26l
-fate-h264-conformance-cabaci3_sony_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CABACI3_Sony_B.jsv
-fate-h264-conformance-cabast3_sony_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CABAST3_Sony_E.jsv
-fate-h264-conformance-cabastbr3_sony_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CABASTBR3_Sony_B.jsv
-fate-h264-conformance-cabref3_sand_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/CABREF3_Sand_D.264
-fate-h264-conformance-cacqp3_sony_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/CACQP3_Sony_D.jsv
-fate-h264-conformance-cafi1_sva_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAFI1_SVA_C.264
-fate-h264-conformance-cama1_sony_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAMA1_Sony_C.jsv
-fate-h264-conformance-cama1_toshiba_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAMA1_TOSHIBA_B.264
-fate-h264-conformance-cama1_vtc_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/cama1_vtc_c.avc
-fate-h264-conformance-cama2_vtc_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/cama2_vtc_b.avc
-fate-h264-conformance-cama3_sand_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAMA3_Sand_E.264
-fate-h264-conformance-cama3_vtc_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/cama3_vtc_b.avc
-fate-h264-conformance-camaci3_sony_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAMACI3_Sony_C.jsv
-fate-h264-conformance-camanl1_toshiba_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAMANL1_TOSHIBA_B.264
-fate-h264-conformance-camanl2_toshiba_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAMANL2_TOSHIBA_B.264
-fate-h264-conformance-camanl3_sand_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAMANL3_Sand_E.264
-fate-h264-conformance-camasl3_sony_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAMASL3_Sony_B.jsv
-fate-h264-conformance-camp_mot_mbaff_l30: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L30.26l
-fate-h264-conformance-camp_mot_mbaff_l31: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L31.26l
-fate-h264-conformance-canl1_sony_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CANL1_Sony_E.jsv
-fate-h264-conformance-canl1_sva_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CANL1_SVA_B.264
-fate-h264-conformance-canl1_toshiba_g: CMD = framecrc -i $(SAMPLES)/h264-conformance/CANL1_TOSHIBA_G.264
-fate-h264-conformance-canl2_sony_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CANL2_Sony_E.jsv
-fate-h264-conformance-canl2_sva_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CANL2_SVA_B.264
-fate-h264-conformance-canl3_sony_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/CANL3_Sony_C.jsv
-fate-h264-conformance-canl3_sva_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CANL3_SVA_B.264
-fate-h264-conformance-canl4_sva_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CANL4_SVA_B.264
-fate-h264-conformance-canlma2_sony_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/CANLMA2_Sony_C.jsv
-fate-h264-conformance-canlma3_sony_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/CANLMA3_Sony_C.jsv
-fate-h264-conformance-capa1_toshiba_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAPA1_TOSHIBA_B.264
-fate-h264-conformance-capama3_sand_f: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAPAMA3_Sand_F.264
-fate-h264-conformance-capcm1_sand_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAPCM1_Sand_E.264
-fate-h264-conformance-capcmnl1_sand_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAPCMNL1_Sand_E.264
-fate-h264-conformance-capm3_sony_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAPM3_Sony_D.jsv
-fate-h264-conformance-caqp1_sony_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAQP1_Sony_B.jsv
-fate-h264-conformance-cavlc_mot_fld0_full_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/cvmp_mot_fld0_full_B.26l
-fate-h264-conformance-cavlc_mot_frm0_full_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/cvmp_mot_frm0_full_B.26l
-fate-h264-conformance-cavlc_mot_mbaff0_full_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/cvmp_mot_mbaff0_full_B.26l
-fate-h264-conformance-cavlc_mot_picaff0_full_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/cvmp_mot_picaff0_full_B.26l
-fate-h264-conformance-cawp1_toshiba_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAWP1_TOSHIBA_E.264
-fate-h264-conformance-cawp5_toshiba_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CAWP5_TOSHIBA_E.264
-fate-h264-conformance-ci1_ft_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CI1_FT_B.264
-fate-h264-conformance-ci_mw_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/CI_MW_D.264
-fate-h264-conformance-cvbs3_sony_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVBS3_Sony_C.jsv
-fate-h264-conformance-cvcanlma2_sony_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVCANLMA2_Sony_C.jsv
-fate-h264-conformance-cvfi1_sony_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVFI1_Sony_D.jsv
-fate-h264-conformance-cvfi1_sva_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVFI1_SVA_C.264
-fate-h264-conformance-cvfi2_sony_h: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVFI2_Sony_H.jsv
-fate-h264-conformance-cvfi2_sva_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVFI2_SVA_C.264
-fate-h264-conformance-cvma1_sony_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVMA1_Sony_D.jsv
-fate-h264-conformance-cvma1_toshiba_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVMA1_TOSHIBA_B.264
-fate-h264-conformance-cvmanl1_toshiba_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVMANL1_TOSHIBA_B.264
-fate-h264-conformance-cvmanl2_toshiba_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVMANL2_TOSHIBA_B.264
-fate-h264-conformance-cvmapaqp3_sony_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVMAPAQP3_Sony_E.jsv
-fate-h264-conformance-cvmaqp2_sony_g: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVMAQP2_Sony_G.jsv
-fate-h264-conformance-cvmaqp3_sony_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVMAQP3_Sony_D.jsv
-fate-h264-conformance-cvmp_mot_fld_l30_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVMP_MOT_FLD_L30_B.26l
-fate-h264-conformance-cvmp_mot_frm_l31_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVMP_MOT_FRM_L31_B.26l
-fate-h264-conformance-cvnlfi1_sony_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVNLFI1_Sony_C.jsv
-fate-h264-conformance-cvnlfi2_sony_h: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVNLFI2_Sony_H.jsv
-fate-h264-conformance-cvpa1_toshiba_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVPA1_TOSHIBA_B.264
-fate-h264-conformance-cvpcmnl1_sva_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVPCMNL1_SVA_C.264
-fate-h264-conformance-cvpcmnl2_sva_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVPCMNL2_SVA_C.264
-fate-h264-conformance-cvwp1_toshiba_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVWP1_TOSHIBA_E.264
-fate-h264-conformance-cvwp2_toshiba_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVWP2_TOSHIBA_E.264
-fate-h264-conformance-cvwp3_toshiba_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVWP3_TOSHIBA_E.264
-fate-h264-conformance-cvwp5_toshiba_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/CVWP5_TOSHIBA_E.264
-fate-h264-conformance-fi1_sony_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/FI1_Sony_E.jsv
-fate-h264-conformance-frext-alphaconformanceg: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/test8b43.264
-fate-h264-conformance-frext-bcrm_freh10: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/freh10.264 -vsync 0
-fate-h264-conformance-frext-brcm_freh11: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/freh11.264 -vsync 0
-fate-h264-conformance-frext-brcm_freh3: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/freh3.264
-fate-h264-conformance-frext-brcm_freh4: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/freh4.264 -vsync 0
-fate-h264-conformance-frext-brcm_freh5: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/freh5.264
-fate-h264-conformance-frext-brcm_freh8: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/freh8.264
-fate-h264-conformance-frext-brcm_freh9: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/freh9.264
-fate-h264-conformance-frext-freh12_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/Freh12_B.264
-fate-h264-conformance-frext-freh1_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/Freh1_B.264
-fate-h264-conformance-frext-freh2_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/Freh2_B.264
-fate-h264-conformance-frext-freh6: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/freh6.264 -vsync 0
-fate-h264-conformance-frext-freh7_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/Freh7_B.264 -vsync 0
-fate-h264-conformance-frext-frext01_jvc_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/FREXT01_JVC_D.264
-fate-h264-conformance-frext-frext02_jvc_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/FREXT02_JVC_C.264
-fate-h264-conformance-frext-frext1_panasonic_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/FRExt1_Panasonic.avc
-fate-h264-conformance-frext-frext2_panasonic_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/FRExt2_Panasonic.avc -vsync 0
-fate-h264-conformance-frext-frext3_panasonic_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/FRExt3_Panasonic.avc
-fate-h264-conformance-frext-frext4_panasonic_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/FRExt4_Panasonic.avc
-fate-h264-conformance-frext-frext_mmco4_sony_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/FRExt_MMCO4_Sony_B.264
-fate-h264-conformance-frext-hcaff1_hhi_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HCAFF1_HHI.264
-fate-h264-conformance-frext-hcafr1_hhi_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HCAFR1_HHI.264
-fate-h264-conformance-frext-hcafr2_hhi_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HCAFR2_HHI.264
-fate-h264-conformance-frext-hcafr3_hhi_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HCAFR3_HHI.264
-fate-h264-conformance-frext-hcafr4_hhi_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HCAFR4_HHI.264
-fate-h264-conformance-frext-hcamff1_hhi_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HCAMFF1_HHI.264
-fate-h264-conformance-frext-hpca_brcm_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HPCA_BRCM_C.264
-fate-h264-conformance-frext-hpcadq_brcm_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HPCADQ_BRCM_B.264
-fate-h264-conformance-frext-hpcafl_bcrm_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HPCAFL_BRCM_C.264 -vsync 0
-fate-h264-conformance-frext-hpcaflnl_bcrm_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HPCAFLNL_BRCM_C.264 -vsync 0
-fate-h264-conformance-frext-hpcalq_brcm_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HPCALQ_BRCM_B.264
-fate-h264-conformance-frext-hpcamapalq_bcrm_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HPCAMAPALQ_BRCM_B.264 -vsync 0
-fate-h264-conformance-frext-hpcamolq_brcm_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HPCAMOLQ_BRCM_B.264
-fate-h264-conformance-frext-hpcanl_brcm_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HPCANL_BRCM_C.264
-fate-h264-conformance-frext-hpcaq2lq_brcm_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HPCAQ2LQ_BRCM_B.264
-fate-h264-conformance-frext-hpcv_brcm_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HPCV_BRCM_A.264
-fate-h264-conformance-frext-hpcvfl_bcrm_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HPCVFL_BRCM_A.264 -vsync 0
-fate-h264-conformance-frext-hpcvflnl_bcrm_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HPCVFLNL_BRCM_A.264 -vsync 0
-fate-h264-conformance-frext-hpcvmolq_brcm_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HPCVMOLQ_BRCM_B.264
-fate-h264-conformance-frext-hpcvnl_brcm_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/HPCVNL_BRCM_A.264
-fate-h264-conformance-frext-pph10i1_panasonic_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/PPH10I1_Panasonic_A.264 -pix_fmt yuv420p10le
-fate-h264-conformance-frext-pph10i2_panasonic_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/PPH10I2_Panasonic_A.264 -pix_fmt yuv420p10le
-fate-h264-conformance-frext-pph10i3_panasonic_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/PPH10I3_Panasonic_A.264 -pix_fmt yuv420p10le
-fate-h264-conformance-frext-pph10i4_panasonic_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/PPH10I4_Panasonic_A.264 -pix_fmt yuv420p10le
-fate-h264-conformance-frext-pph10i5_panasonic_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/PPH10I5_Panasonic_A.264 -pix_fmt yuv420p10le
-fate-h264-conformance-frext-pph10i6_panasonic_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/PPH10I6_Panasonic_A.264 -pix_fmt yuv420p10le
-fate-h264-conformance-frext-pph10i7_panasonic_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/FRext/PPH10I7_Panasonic_A.264 -pix_fmt yuv420p10le
-fate-h264-conformance-hcbp2_hhi_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/HCBP2_HHI_A.264
-fate-h264-conformance-hcmp1_hhi_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/HCMP1_HHI_A.264
-fate-h264-conformance-ls_sva_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/LS_SVA_D.264
-fate-h264-conformance-midr_mw_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/MIDR_MW_D.264
-fate-h264-conformance-mps_mw_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/MPS_MW_A.264
-fate-h264-conformance-mr1_bt_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/MR1_BT_A.h264
-fate-h264-conformance-mr1_mw_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/MR1_MW_A.264
-fate-h264-conformance-mr2_mw_a: CMD = framecrc -i $(SAMPLES)/h264-conformance/MR2_MW_A.264
-fate-h264-conformance-mr2_tandberg_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/MR2_TANDBERG_E.264
-fate-h264-conformance-mr3_tandberg_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/MR3_TANDBERG_B.264
-fate-h264-conformance-mr4_tandberg_c: CMD = framecrc -strict 1 -i $(SAMPLES)/h264-conformance/MR4_TANDBERG_C.264
-fate-h264-conformance-mr5_tandberg_c: CMD = framecrc -strict 1 -i $(SAMPLES)/h264-conformance/MR5_TANDBERG_C.264
-fate-h264-conformance-mr6_bt_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/MR6_BT_B.h264
-fate-h264-conformance-mr7_bt_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/MR7_BT_B.h264
-fate-h264-conformance-mr8_bt_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/MR8_BT_B.h264
-fate-h264-conformance-mr9_bt_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/MR9_BT_B.h264
-fate-h264-conformance-mv1_brcm_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/src19td.IBP.264
-fate-h264-conformance-nl1_sony_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/NL1_Sony_D.jsv
-fate-h264-conformance-nl2_sony_h: CMD = framecrc -i $(SAMPLES)/h264-conformance/NL2_Sony_H.jsv
-fate-h264-conformance-nl3_sva_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/NL3_SVA_E.264
-fate-h264-conformance-nlmq1_jvc_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/NLMQ1_JVC_C.264
-fate-h264-conformance-nlmq2_jvc_c: CMD = framecrc -i $(SAMPLES)/h264-conformance/NLMQ2_JVC_C.264
-fate-h264-conformance-nrf_mw_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/NRF_MW_E.264
-fate-h264-conformance-sharp_mp_field_1_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/Sharp_MP_Field_1_B.jvt
-fate-h264-conformance-sharp_mp_field_2_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/Sharp_MP_Field_2_B.jvt
-fate-h264-conformance-sharp_mp_field_3_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/Sharp_MP_Field_3_B.jvt
-fate-h264-conformance-sharp_mp_paff_1r2: CMD = framecrc -i $(SAMPLES)/h264-conformance/Sharp_MP_PAFF_1r2.jvt
-fate-h264-conformance-sharp_mp_paff_2r: CMD = framecrc -i $(SAMPLES)/h264-conformance/Sharp_MP_PAFF_2.jvt
-fate-h264-conformance-sl1_sva_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/SL1_SVA_B.264
-fate-h264-conformance-sva_ba1_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/SVA_BA1_B.264
-fate-h264-conformance-sva_ba2_d: CMD = framecrc -i $(SAMPLES)/h264-conformance/SVA_BA2_D.264
-fate-h264-conformance-sva_base_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/SVA_Base_B.264
-fate-h264-conformance-sva_cl1_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/SVA_CL1_E.264
-fate-h264-conformance-sva_fm1_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/SVA_FM1_E.264
-fate-h264-conformance-sva_nl1_b: CMD = framecrc -i $(SAMPLES)/h264-conformance/SVA_NL1_B.264
-fate-h264-conformance-sva_nl2_e: CMD = framecrc -i $(SAMPLES)/h264-conformance/SVA_NL2_E.264
+fate-h264-conformance-aud_mw_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/AUD_MW_E.264
+fate-h264-conformance-ba1_ft_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BA1_FT_C.264
+fate-h264-conformance-ba1_sony_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BA1_Sony_D.jsv
+fate-h264-conformance-ba2_sony_f: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BA2_Sony_F.jsv
+fate-h264-conformance-ba3_sva_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BA3_SVA_C.264
+fate-h264-conformance-ba_mw_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BA_MW_D.264
+fate-h264-conformance-bamq1_jvc_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BAMQ1_JVC_C.264
+fate-h264-conformance-bamq2_jvc_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BAMQ2_JVC_C.264
+fate-h264-conformance-banm_mw_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BANM_MW_D.264
+fate-h264-conformance-basqp1_sony_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/BASQP1_Sony_C.jsv
+fate-h264-conformance-caba1_sony_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABA1_Sony_D.jsv
+fate-h264-conformance-caba1_sva_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABA1_SVA_B.264
+fate-h264-conformance-caba2_sony_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABA2_Sony_E.jsv
+fate-h264-conformance-caba2_sva_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABA2_SVA_B.264
+fate-h264-conformance-caba3_sony_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABA3_Sony_C.jsv
+fate-h264-conformance-caba3_sva_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABA3_SVA_B.264
+fate-h264-conformance-caba3_toshiba_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABA3_TOSHIBA_E.264
+fate-h264-conformance-cabac_mot_fld0_full: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/camp_mot_fld0_full.26l
+fate-h264-conformance-cabac_mot_frm0_full: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/camp_mot_frm0_full.26l
+fate-h264-conformance-cabac_mot_mbaff0_full: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/camp_mot_mbaff0_full.26l
+fate-h264-conformance-cabac_mot_picaff0_full: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/camp_mot_picaff0_full.26l
+fate-h264-conformance-cabaci3_sony_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABACI3_Sony_B.jsv
+fate-h264-conformance-cabast3_sony_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABAST3_Sony_E.jsv
+fate-h264-conformance-cabastbr3_sony_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABASTBR3_Sony_B.jsv
+fate-h264-conformance-cabref3_sand_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CABREF3_Sand_D.264
+fate-h264-conformance-cacqp3_sony_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CACQP3_Sony_D.jsv
+fate-h264-conformance-cafi1_sva_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAFI1_SVA_C.264
+fate-h264-conformance-cama1_sony_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMA1_Sony_C.jsv
+fate-h264-conformance-cama1_toshiba_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMA1_TOSHIBA_B.264
+fate-h264-conformance-cama1_vtc_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/cama1_vtc_c.avc
+fate-h264-conformance-cama2_vtc_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/cama2_vtc_b.avc
+fate-h264-conformance-cama3_sand_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMA3_Sand_E.264
+fate-h264-conformance-cama3_vtc_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/cama3_vtc_b.avc
+fate-h264-conformance-camaci3_sony_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMACI3_Sony_C.jsv
+fate-h264-conformance-camanl1_toshiba_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMANL1_TOSHIBA_B.264
+fate-h264-conformance-camanl2_toshiba_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMANL2_TOSHIBA_B.264
+fate-h264-conformance-camanl3_sand_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMANL3_Sand_E.264
+fate-h264-conformance-camasl3_sony_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMASL3_Sony_B.jsv
+fate-h264-conformance-camp_mot_mbaff_l30: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L30.26l
+fate-h264-conformance-camp_mot_mbaff_l31: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAMP_MOT_MBAFF_L31.26l
+fate-h264-conformance-canl1_sony_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL1_Sony_E.jsv
+fate-h264-conformance-canl1_sva_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL1_SVA_B.264
+fate-h264-conformance-canl1_toshiba_g: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL1_TOSHIBA_G.264
+fate-h264-conformance-canl2_sony_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL2_Sony_E.jsv
+fate-h264-conformance-canl2_sva_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL2_SVA_B.264
+fate-h264-conformance-canl3_sony_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL3_Sony_C.jsv
+fate-h264-conformance-canl3_sva_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL3_SVA_B.264
+fate-h264-conformance-canl4_sva_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANL4_SVA_B.264
+fate-h264-conformance-canlma2_sony_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANLMA2_Sony_C.jsv
+fate-h264-conformance-canlma3_sony_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CANLMA3_Sony_C.jsv
+fate-h264-conformance-capa1_toshiba_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAPA1_TOSHIBA_B.264
+fate-h264-conformance-capama3_sand_f: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAPAMA3_Sand_F.264
+fate-h264-conformance-capcm1_sand_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAPCM1_Sand_E.264
+fate-h264-conformance-capcmnl1_sand_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAPCMNL1_Sand_E.264
+fate-h264-conformance-capm3_sony_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAPM3_Sony_D.jsv
+fate-h264-conformance-caqp1_sony_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAQP1_Sony_B.jsv
+fate-h264-conformance-cavlc_mot_fld0_full_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/cvmp_mot_fld0_full_B.26l
+fate-h264-conformance-cavlc_mot_frm0_full_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/cvmp_mot_frm0_full_B.26l
+fate-h264-conformance-cavlc_mot_mbaff0_full_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/cvmp_mot_mbaff0_full_B.26l
+fate-h264-conformance-cavlc_mot_picaff0_full_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/cvmp_mot_picaff0_full_B.26l
+fate-h264-conformance-cawp1_toshiba_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAWP1_TOSHIBA_E.264
+fate-h264-conformance-cawp5_toshiba_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CAWP5_TOSHIBA_E.264
+fate-h264-conformance-ci1_ft_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CI1_FT_B.264
+fate-h264-conformance-ci_mw_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CI_MW_D.264
+fate-h264-conformance-cvbs3_sony_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVBS3_Sony_C.jsv
+fate-h264-conformance-cvcanlma2_sony_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVCANLMA2_Sony_C.jsv
+fate-h264-conformance-cvfi1_sony_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVFI1_Sony_D.jsv
+fate-h264-conformance-cvfi1_sva_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVFI1_SVA_C.264
+fate-h264-conformance-cvfi2_sony_h: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVFI2_Sony_H.jsv
+fate-h264-conformance-cvfi2_sva_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVFI2_SVA_C.264
+fate-h264-conformance-cvma1_sony_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMA1_Sony_D.jsv
+fate-h264-conformance-cvma1_toshiba_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMA1_TOSHIBA_B.264
+fate-h264-conformance-cvmanl1_toshiba_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMANL1_TOSHIBA_B.264
+fate-h264-conformance-cvmanl2_toshiba_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMANL2_TOSHIBA_B.264
+fate-h264-conformance-cvmapaqp3_sony_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMAPAQP3_Sony_E.jsv
+fate-h264-conformance-cvmaqp2_sony_g: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMAQP2_Sony_G.jsv
+fate-h264-conformance-cvmaqp3_sony_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMAQP3_Sony_D.jsv
+fate-h264-conformance-cvmp_mot_fld_l30_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMP_MOT_FLD_L30_B.26l
+fate-h264-conformance-cvmp_mot_frm_l31_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVMP_MOT_FRM_L31_B.26l
+fate-h264-conformance-cvnlfi1_sony_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVNLFI1_Sony_C.jsv
+fate-h264-conformance-cvnlfi2_sony_h: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVNLFI2_Sony_H.jsv
+fate-h264-conformance-cvpa1_toshiba_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVPA1_TOSHIBA_B.264
+fate-h264-conformance-cvpcmnl1_sva_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVPCMNL1_SVA_C.264
+fate-h264-conformance-cvpcmnl2_sva_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVPCMNL2_SVA_C.264
+fate-h264-conformance-cvwp1_toshiba_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVWP1_TOSHIBA_E.264
+fate-h264-conformance-cvwp2_toshiba_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVWP2_TOSHIBA_E.264
+fate-h264-conformance-cvwp3_toshiba_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVWP3_TOSHIBA_E.264
+fate-h264-conformance-cvwp5_toshiba_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/CVWP5_TOSHIBA_E.264
+fate-h264-conformance-fi1_sony_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FI1_Sony_E.jsv
+fate-h264-conformance-frext-alphaconformanceg: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/test8b43.264
+fate-h264-conformance-frext-bcrm_freh10: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh10.264 -vsync drop
+fate-h264-conformance-frext-brcm_freh11: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh11.264 -vsync drop
+fate-h264-conformance-frext-brcm_freh3: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh3.264
+fate-h264-conformance-frext-brcm_freh4: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh4.264 -vsync drop
+fate-h264-conformance-frext-brcm_freh5: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh5.264
+fate-h264-conformance-frext-brcm_freh8: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh8.264
+fate-h264-conformance-frext-brcm_freh9: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh9.264
+fate-h264-conformance-frext-freh12_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Freh12_B.264
+fate-h264-conformance-frext-freh1_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Freh1_B.264
+fate-h264-conformance-frext-freh2_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Freh2_B.264
+fate-h264-conformance-frext-freh6: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/freh6.264 -vsync drop
+fate-h264-conformance-frext-freh7_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Freh7_B.264 -vsync drop
+fate-h264-conformance-frext-frext01_jvc_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/FREXT01_JVC_D.264
+fate-h264-conformance-frext-frext02_jvc_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/FREXT02_JVC_C.264
+fate-h264-conformance-frext-frext1_panasonic_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/FRExt1_Panasonic.avc
+fate-h264-conformance-frext-frext2_panasonic_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/FRExt2_Panasonic.avc -vsync 0
+fate-h264-conformance-frext-frext3_panasonic_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/FRExt3_Panasonic.avc
+fate-h264-conformance-frext-frext4_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/FRExt4_Panasonic.avc
+fate-h264-conformance-frext-frext_mmco4_sony_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/FRExt_MMCO4_Sony_B.264
+fate-h264-conformance-frext-hcaff1_hhi_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HCAFF1_HHI.264
+fate-h264-conformance-frext-hcafr1_hhi_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HCAFR1_HHI.264
+fate-h264-conformance-frext-hcafr2_hhi_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HCAFR2_HHI.264
+fate-h264-conformance-frext-hcafr3_hhi_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HCAFR3_HHI.264
+fate-h264-conformance-frext-hcafr4_hhi_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HCAFR4_HHI.264
+fate-h264-conformance-frext-hcamff1_hhi_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HCAMFF1_HHI.264
+fate-h264-conformance-frext-hi422fr10_sony_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Hi422FR10_SONY_B.264
+fate-h264-conformance-frext-hi422fr13_sony_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Hi422FR13_SONY_B.264 -pix_fmt yuv422p10le
+fate-h264-conformance-frext-hi422fr1_sony_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Hi422FR1_SONY_A.jsv
+fate-h264-conformance-frext-hi422fr6_sony_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/Hi422FR6_SONY_A.jsv -pix_fmt yuv422p10le
+fate-h264-conformance-frext-hpca_brcm_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCA_BRCM_C.264
+fate-h264-conformance-frext-hpcadq_brcm_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCADQ_BRCM_B.264
+fate-h264-conformance-frext-hpcafl_bcrm_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCAFL_BRCM_C.264 -vsync drop
+fate-h264-conformance-frext-hpcaflnl_bcrm_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCAFLNL_BRCM_C.264 -vsync drop
+fate-h264-conformance-frext-hpcalq_brcm_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCALQ_BRCM_B.264
+fate-h264-conformance-frext-hpcamapalq_bcrm_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCAMAPALQ_BRCM_B.264 -vsync 0
+fate-h264-conformance-frext-hpcamolq_brcm_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCAMOLQ_BRCM_B.264
+fate-h264-conformance-frext-hpcanl_brcm_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCANL_BRCM_C.264
+fate-h264-conformance-frext-hpcaq2lq_brcm_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCAQ2LQ_BRCM_B.264
+fate-h264-conformance-frext-hpcv_brcm_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCV_BRCM_A.264
+fate-h264-conformance-frext-hpcvfl_bcrm_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCVFL_BRCM_A.264 -vsync drop
+fate-h264-conformance-frext-hpcvflnl_bcrm_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCVFLNL_BRCM_A.264 -vsync drop
+fate-h264-conformance-frext-hpcvmolq_brcm_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCVMOLQ_BRCM_B.264
+fate-h264-conformance-frext-hpcvnl_brcm_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/HPCVNL_BRCM_A.264
+fate-h264-conformance-frext-pph10i1_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH10I1_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i2_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH10I2_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i3_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH10I3_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i4_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH10I4_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i5_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH10I5_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i6_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH10I6_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph10i7_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH10I7_Panasonic_A.264 -pix_fmt yuv420p10le
+fate-h264-conformance-frext-pph422i1_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH422I1_Panasonic_A.264 -pix_fmt yuv422p10le
+fate-h264-conformance-frext-pph422i2_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH422I2_Panasonic_A.264 -pix_fmt yuv422p10le
+fate-h264-conformance-frext-pph422i3_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH422I3_Panasonic_A.264 -pix_fmt yuv422p10le
+fate-h264-conformance-frext-pph422i4_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH422I4_Panasonic_A.264 -pix_fmt yuv422p10le
+fate-h264-conformance-frext-pph422i5_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH422I5_Panasonic_A.264 -pix_fmt yuv422p10le
+fate-h264-conformance-frext-pph422i6_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH422I6_Panasonic_A.264 -pix_fmt yuv422p10le
+fate-h264-conformance-frext-pph422i7_panasonic_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/FRext/PPH422I7_Panasonic_A.264 -pix_fmt yuv422p10le
+fate-h264-conformance-hcbp2_hhi_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/HCBP2_HHI_A.264
+fate-h264-conformance-hcmp1_hhi_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/HCMP1_HHI_A.264
+fate-h264-conformance-ls_sva_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/LS_SVA_D.264
+fate-h264-conformance-midr_mw_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MIDR_MW_D.264
+fate-h264-conformance-mps_mw_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MPS_MW_A.264
+fate-h264-conformance-mr1_bt_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR1_BT_A.h264
+fate-h264-conformance-mr1_mw_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR1_MW_A.264
+fate-h264-conformance-mr2_mw_a: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR2_MW_A.264
+fate-h264-conformance-mr2_tandberg_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR2_TANDBERG_E.264
+fate-h264-conformance-mr3_tandberg_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR3_TANDBERG_B.264
+fate-h264-conformance-mr4_tandberg_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR4_TANDBERG_C.264
+fate-h264-conformance-mr5_tandberg_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR5_TANDBERG_C.264
+fate-h264-conformance-mr6_bt_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR6_BT_B.h264
+fate-h264-conformance-mr7_bt_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR7_BT_B.h264
+fate-h264-conformance-mr8_bt_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR8_BT_B.h264
+fate-h264-conformance-mr9_bt_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/MR9_BT_B.h264
+fate-h264-conformance-mv1_brcm_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/src19td.IBP.264
+fate-h264-conformance-nl1_sony_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/NL1_Sony_D.jsv
+fate-h264-conformance-nl2_sony_h: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/NL2_Sony_H.jsv
+fate-h264-conformance-nl3_sva_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/NL3_SVA_E.264
+fate-h264-conformance-nlmq1_jvc_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/NLMQ1_JVC_C.264
+fate-h264-conformance-nlmq2_jvc_c: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/NLMQ2_JVC_C.264
+fate-h264-conformance-nrf_mw_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/NRF_MW_E.264
+fate-h264-conformance-sharp_mp_field_1_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/Sharp_MP_Field_1_B.jvt
+fate-h264-conformance-sharp_mp_field_2_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/Sharp_MP_Field_2_B.jvt
+fate-h264-conformance-sharp_mp_field_3_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/Sharp_MP_Field_3_B.jvt
+fate-h264-conformance-sharp_mp_paff_1r2: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/Sharp_MP_PAFF_1r2.jvt
+fate-h264-conformance-sharp_mp_paff_2r: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/Sharp_MP_PAFF_2.jvt
+fate-h264-conformance-sl1_sva_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SL1_SVA_B.264
+fate-h264-conformance-sva_ba1_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SVA_BA1_B.264
+fate-h264-conformance-sva_ba2_d: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SVA_BA2_D.264
+fate-h264-conformance-sva_base_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SVA_Base_B.264
+fate-h264-conformance-sva_cl1_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SVA_CL1_E.264
+fate-h264-conformance-sva_fm1_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SVA_FM1_E.264
+fate-h264-conformance-sva_nl1_b: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SVA_NL1_B.264
+fate-h264-conformance-sva_nl2_e: CMD = framecrc -vsync drop -i $(SAMPLES)/h264-conformance/SVA_NL2_E.264
 
 fate-h264-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 a6768a0..5b89960 100644
--- a/tests/fate/image.mak
+++ b/tests/fate/image.mak
@@ -1,10 +1,10 @@
-FATE_SAMPLES_AVCONV += fate-dpx
+FATE_IMAGE += fate-dpx
 fate-dpx: CMD = framecrc -i $(SAMPLES)/dpx/lighthouse_rgb48.dpx
 
-FATE_SAMPLES_AVCONV += fate-pictor
+FATE_IMAGE += fate-pictor
 fate-pictor: CMD = framecrc -i $(SAMPLES)/pictor/MFISH.PIC -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-ptx
+FATE_IMAGE += fate-ptx
 fate-ptx: CMD = framecrc -i $(SAMPLES)/ptx/_113kw_pic.ptx -pix_fmt rgb24
 
 FATE_SUNRASTER += fate-sunraster-1bit-raw
@@ -28,7 +28,7 @@
 FATE_SUNRASTER += fate-sunraster-24bit-rle
 fate-sunraster-24bit-rle: CMD = framecrc -i $(SAMPLES)/sunraster/lena-24bit-rle.sun
 
-FATE_SAMPLES_AVCONV += $(FATE_SUNRASTER)
+FATE_IMAGE += $(FATE_SUNRASTER)
 fate-sunraster: $(FATE_SUNRASTER)
 
 FATE_TARGA = CBW8       \
@@ -45,7 +45,7 @@
 FATE_TARGA := $(FATE_TARGA:%=fate-targa-conformance-%)  \
               fate-targa-top-to-bottom
 
-FATE_SAMPLES_AVCONV += $(FATE_TARGA)
+FATE_IMAGE += $(FATE_TARGA)
 fate-targa: $(FATE_TARGA)
 
 fate-targa-conformance-CBW8:  CMD = framecrc -i $(SAMPLES)/targa-conformance/CBW8.TGA
@@ -67,5 +67,9 @@
 FATE_TIFF += fate-tiff-fax-g3s
 fate-tiff-fax-g3s: CMD = framecrc -i $(SAMPLES)/CCITT_fax/G31DS.TIF
 
-FATE_SAMPLES_AVCONV += $(FATE_TIFF)
+FATE_IMAGE += $(FATE_TIFF)
 fate-tiff: $(FATE_TIFF)
+
+FATE_SAMPLES_FFMPEG += $(FATE_IMAGE)
+fate-image: $(FATE_IMAGE)
+
diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak
index afb0a2c..488ec6b 100644
--- a/tests/fate/libavutil.mak
+++ b/tests/fate/libavutil.mak
@@ -16,6 +16,10 @@
 fate-blowfish: libavutil/blowfish-test$(EXESUF)
 fate-blowfish: CMD = run libavutil/blowfish-test
 
+FATE_LIBAVUTIL += fate-bprint
+fate-bprint: libavutil/bprint-test$(EXESUF)
+fate-bprint: CMD = run libavutil/bprint-test
+
 FATE_LIBAVUTIL += fate-crc
 fate-crc: libavutil/crc-test$(EXESUF)
 fate-crc: CMD = run libavutil/crc-test
@@ -41,6 +45,10 @@
 fate-parseutils: libavutil/parseutils-test$(EXESUF)
 fate-parseutils: CMD = run libavutil/parseutils-test
 
+FATE_LIBAVUTIL += fate-random_seed
+fate-random_seed: libavutil/random_seed-test$(EXESUF)
+fate-random_seed: CMD = run libavutil/random_seed-test
+
 FATE_LIBAVUTIL += fate-sha
 fate-sha: libavutil/sha-test$(EXESUF)
 fate-sha: CMD = run libavutil/sha-test
diff --git a/tests/fate/lossless-audio.mak b/tests/fate/lossless-audio.mak
index f0ff496..e052a98 100644
--- a/tests/fate/lossless-audio.mak
+++ b/tests/fate/lossless-audio.mak
@@ -1,17 +1,24 @@
-FATE_SAMPLES_AVCONV += fate-lossless-alac
+FATE_SAMPLES_LOSSLESS_AUDIO += fate-lossless-alac
 fate-lossless-alac: CMD = md5 -i $(SAMPLES)/lossless-audio/inside.m4a -f s16le
 
-FATE_SAMPLES_AVCONV += fate-lossless-meridianaudio
+FATE_SAMPLES_LOSSLESS_AUDIO += fate-lossless-meridianaudio
 fate-lossless-meridianaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.mlp -f s16le
 
-FATE_SAMPLES_AVCONV += fate-lossless-monkeysaudio
+FATE_SAMPLES_LOSSLESS_AUDIO += fate-lossless-monkeysaudio
 fate-lossless-monkeysaudio: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.ape -f s16le
 
-FATE_SAMPLES_AVCONV += fate-lossless-shorten
+FATE_SAMPLES_LOSSLESS_AUDIO += fate-lossless-shorten
 fate-lossless-shorten: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.shn -f s16le
 
-FATE_SAMPLES_AVCONV += fate-lossless-tta
+FATE_SAMPLES_LOSSLESS_AUDIO += fate-lossless-tak
+fate-lossless-tak: CMD = crc -i $(SAMPLES)/lossless-audio/luckynight-partial.tak
+
+FATE_SAMPLES_LOSSLESS_AUDIO += fate-lossless-tta
 fate-lossless-tta: CMD = crc -i $(SAMPLES)/lossless-audio/inside.tta
 
-FATE_SAMPLES_AVCONV += fate-lossless-wma
+FATE_SAMPLES_LOSSLESS_AUDIO += fate-lossless-wma
 fate-lossless-wma: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.wma -f s16le
+
+FATE_SAMPLES_FFMPEG += $(FATE_SAMPLES_LOSSLESS_AUDIO)
+fate-lossless-audio: $(FATE_SAMPLES_LOSSLESS_AUDIO)
+
diff --git a/tests/fate/lossless-video.mak b/tests/fate/lossless-video.mak
index 5055730..cbf7f52 100644
--- a/tests/fate/lossless-video.mak
+++ b/tests/fate/lossless-video.mak
@@ -4,7 +4,7 @@
 FATE_CLLC += fate-cllc-argb
 fate-cllc-argb: CMD = framecrc -i $(SAMPLES)/cllc/sample-cllc-argb.avi
 
-FATE_SAMPLES_AVCONV += $(FATE_CLLC)
+FATE_LOSSLESS_VIDEO += $(FATE_CLLC)
 fate-cllc: $(FATE_CLLC)
 
 FATE_LAGARITH += fate-lagarith-rgb24
@@ -28,20 +28,25 @@
 FATE_LOCO += fate-loco-yuy2
 fate-loco-yuy2: CMD = framecrc -i $(SAMPLES)/loco/pig-loco-0.avi
 
-FATE_SAMPLES_AVCONV += $(FATE_LOCO)
+FATE_LOSSLESS_VIDEO += $(FATE_LOCO)
 fate-loco: $(FATE_LOCO)
 
-FATE_SAMPLES_AVCONV += fate-msrle-8bit
+FATE_LOSSLESS_VIDEO += fate-msrle-8bit
 fate-msrle-8bit: CMD = framecrc -i $(SAMPLES)/msrle/Search-RLE.avi -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-mszh
+FATE_LOSSLESS_VIDEO += fate-mszh
 fate-mszh: CMD = framecrc -i $(SAMPLES)/lcl/mszh-1frame.avi
 
-FATE_SAMPLES_AVCONV += fate-vble
+FATE_LOSSLESS_VIDEO += fate-vble
 fate-vble: CMD = framecrc -i $(SAMPLES)/vble/flowers-partial-2MB.avi
 
-FATE_SAMPLES_AVCONV += fate-zlib
+FATE_LOSSLESS_VIDEO-$(CONFIG_ZLIB) += fate-zlib
 fate-zlib: CMD = framecrc -i $(SAMPLES)/lcl/zlib-1frame.avi
 
-FATE_SAMPLES_AVCONV += fate-zerocodec
+FATE_LOSSLESS_VIDEO-$(CONFIG_ZLIB) += fate-zerocodec
 fate-zerocodec: CMD = framecrc -i $(SAMPLES)/zerocodec/sample-zeco.avi
+
+FATE_LOSSLESS_VIDEO += $(FATE_LOSSLESS_VIDEO-yes)
+
+FATE_SAMPLES_FFMPEG += $(FATE_LOSSLESS_VIDEO)
+fate-lossless-video: $(FATE_LOSSLESS_VIDEO)
diff --git a/tests/fate/mapchan.mak b/tests/fate/mapchan.mak
new file mode 100644
index 0000000..119f566
--- /dev/null
+++ b/tests/fate/mapchan.mak
@@ -0,0 +1,14 @@
+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 -f wav md5: -map_channel 0.0.1 -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 -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 -f wav
+
+FATE_FFMPEG += $(FATE_MAPCHAN)
+fate-mapchan: $(FATE_MAPCHAN)
diff --git a/tests/fate/microsoft.mak b/tests/fate/microsoft.mak
index 48bdb95..e9cd9b1 100644
--- a/tests/fate/microsoft.mak
+++ b/tests/fate/microsoft.mak
@@ -1,4 +1,4 @@
-FATE_SAMPLES_AVCONV += fate-msmpeg4v1
+FATE_MICROSOFT += fate-msmpeg4v1
 fate-msmpeg4v1: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/msmpeg4v1/mpg4.avi -an
 
 FATE_MSVIDEO1 += fate-msvideo1-16bit
@@ -7,7 +7,7 @@
 FATE_MSVIDEO1 += fate-msvideo1-8bit
 fate-msvideo1-8bit: CMD = framecrc -i $(SAMPLES)/cram/skating.avi -t 1 -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += $(FATE_MSVIDEO1)
+FATE_MICROSOFT += $(FATE_MSVIDEO1)
 fate-msvideo1: $(FATE_MSVIDEO1)
 
 FATE_WMV8_DRM += fate-wmv8-drm
@@ -17,7 +17,11 @@
 FATE_WMV8_DRM += fate-wmv8-drm-nodec
 fate-wmv8-drm-nodec: CMD = framecrc -cryptokey 137381538c84c068111902a59c5cf6c340247c39 -i $(SAMPLES)/wmv8/wmv_drm.wmv -acodec copy -vcodec copy
 
-FATE_SAMPLES_AVCONV += $(FATE_WMV8_DRM)
+#FATE_MICROSOFT += fate-wmv8-x8intra
+FATE_TESTS-no += fate-wmv8-x8intra
+fate-wmv8-x8intra: CMD = framecrc -flags +bitexact -idct 19 -i $(SAMPLES)/wmv8/wmv8_x8intra.wmv -an
+
+FATE_MICROSOFT += $(FATE_WMV8_DRM)
 fate-wmv8_drm: $(FATE_WMV8_DRM)
 
 FATE_VC1 += fate-vc1_sa00040
@@ -38,5 +42,8 @@
 FATE_VC1 += fate-vc1-ism
 fate-vc1-ism: CMD = framecrc -i $(SAMPLES)/isom/vc1-wmapro.ism -an
 
-FATE_SAMPLES_AVCONV += $(FATE_VC1)
+FATE_MICROSOFT += $(FATE_VC1)
 fate-vc1: $(FATE_VC1)
+
+FATE_SAMPLES_FFMPEG += $(FATE_MICROSOFT)
+fate-microsoft: $(FATE_MICROSOFT)
diff --git a/tests/fate/mpc.mak b/tests/fate/mpc.mak
index f30ba60..5505a9a 100644
--- a/tests/fate/mpc.mak
+++ b/tests/fate/mpc.mak
@@ -9,5 +9,5 @@
 fate-musepack7: CMP = oneoff
 fate-musepack7: REF = $(SAMPLES)/musepack/inside-mp7.pcm
 
-FATE_SAMPLES_AVCONV += $(FATE_MPC)
+FATE_SAMPLES_FFMPEG += $(FATE_MPC)
 fate-mpc: $(FATE_MPC)
diff --git a/tests/fate/options.mak b/tests/fate/options.mak
new file mode 100644
index 0000000..940d454
--- /dev/null
+++ b/tests/fate/options.mak
@@ -0,0 +1,9 @@
+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/pcm.mak b/tests/fate/pcm.mak
index c84de9e..e978719 100644
--- a/tests/fate/pcm.mak
+++ b/tests/fate/pcm.mak
@@ -27,6 +27,6 @@
 fate-dcinema-encode: SRC = tests/data/asynth-96000-6.wav
 fate-dcinema-encode: CMD = enc_dec_pcm daud md5 s16le $(SRC) -c:a pcm_s24daud
 
-FATE_AVCONV += $(FATE_PCM)
+FATE_FFMPEG += $(FATE_PCM)
 FATE_SAMPLES_AVCONV += $(FATE_SAMPLES_PCM)
 fate-pcm: $(FATE_PCM) $(FATE_SAMPLES_PCM)
diff --git a/tests/fate/probe.mak b/tests/fate/probe.mak
index 73bc5cb..033b484 100644
--- a/tests/fate/probe.mak
+++ b/tests/fate/probe.mak
@@ -10,9 +10,9 @@
 FATE_PROBE_FORMAT += fate-probe-format-roundup2015
 fate-probe-format-roundup2015: REF = dv
 
-FATE_SAMPLES-$(CONFIG_AVPROBE) += $(FATE_PROBE_FORMAT)
+FATE_EXTERN-$(CONFIG_FFPROBE) += $(FATE_PROBE_FORMAT)
 fate-probe-format: $(FATE_PROBE_FORMAT)
 
-$(FATE_PROBE_FORMAT): avprobe$(EXESUF)
+$(FATE_PROBE_FORMAT): ffprobe$(EXESUF)
 $(FATE_PROBE_FORMAT): CMP = oneline
 fate-probe-format-%: CMD = probefmt $(SAMPLES)/probe-format/$(@:fate-probe-format-%=%)
diff --git a/tests/fate/prores.mak b/tests/fate/prores.mak
index 1d76fff..9f4d1b3 100644
--- a/tests/fate/prores.mak
+++ b/tests/fate/prores.mak
@@ -7,8 +7,8 @@
 FATE_SAMPLES_AVCONV += $(FATE_PRORES)
 fate-prores: $(FATE_PRORES)
 
-fate-prores-422:       CMD = framecrc -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422.mov -pix_fmt yuv422p10le
-fate-prores-422_hq:    CMD = framecrc -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_HQ.mov -pix_fmt yuv422p10le
-fate-prores-422_lt:    CMD = framecrc -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_LT.mov -pix_fmt yuv422p10le
-fate-prores-422_proxy: CMD = framecrc -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_Proxy.mov -pix_fmt yuv422p10le
-fate-prores-alpha:     CMD = framecrc -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_with_Alpha.mov -pix_fmt yuv444p10le
+fate-prores-422:       CMD = framecrc -flags +bitexact -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422.mov -pix_fmt yuv422p10le
+fate-prores-422_hq:    CMD = framecrc -flags +bitexact -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_HQ.mov -pix_fmt yuv422p10le
+fate-prores-422_lt:    CMD = framecrc -flags +bitexact -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_LT.mov -pix_fmt yuv422p10le
+fate-prores-422_proxy: CMD = framecrc -flags +bitexact -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_Proxy.mov -pix_fmt yuv422p10le
+fate-prores-alpha:     CMD = framecrc -flags +bitexact -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_with_Alpha.mov -pix_fmt yuv444p10le
diff --git a/tests/fate/qt.mak b/tests/fate/qt.mak
index b2b9500..3068ac6 100644
--- a/tests/fate/qt.mak
+++ b/tests/fate/qt.mak
@@ -1,50 +1,55 @@
-FATE_SAMPLES_AVCONV += fate-8bps
+FATE_QT += fate-8bps
 fate-8bps: CMD = framecrc -i $(SAMPLES)/8bps/full9iron-partial.mov -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-qdm2
+FATE_QT += fate-qdm2
 fate-qdm2: CMD = pcm -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-QDM2.mov
 fate-qdm2: CMP = oneoff
 fate-qdm2: REF = $(SAMPLES)/qt-surge-suite/surge-2-16-B-QDM2.pcm
 fate-qdm2: FUZZ = 2
 
-FATE_SAMPLES_AVCONV += fate-qt-alaw-mono
+FATE_QT += fate-qt-alaw-mono
 fate-qt-alaw-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-16-B-alaw.mov -f s16le
 
-FATE_SAMPLES_AVCONV += fate-qt-alaw-stereo
+FATE_QT += fate-qt-alaw-stereo
 fate-qt-alaw-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-alaw.mov -f s16le
 
-FATE_SAMPLES_AVCONV += fate-qt-ima4-mono
+FATE_QT += fate-qt-ima4-mono
 fate-qt-ima4-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-16-B-ima4.mov -f s16le
 
-FATE_SAMPLES_AVCONV += fate-qt-ima4-stereo
+FATE_QT += fate-qt-ima4-stereo
 fate-qt-ima4-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-ima4.mov -f s16le
 
-FATE_SAMPLES_AVCONV += fate-qt-mac3-mono
+FATE_QT += fate-qt-mac3-mono
 fate-qt-mac3-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-8-MAC3.mov -f s16le
 
-FATE_SAMPLES_AVCONV += fate-qt-mac3-stereo
+FATE_QT += fate-qt-mac3-stereo
 fate-qt-mac3-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-8-MAC3.mov -f s16le
 
-FATE_SAMPLES_AVCONV += fate-qt-mac6-mono
+FATE_QT += fate-qt-mac6-mono
 fate-qt-mac6-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-8-MAC6.mov -f s16le
 
-FATE_SAMPLES_AVCONV += fate-qt-mac6-stereo
+FATE_QT += fate-qt-mac6-stereo
 fate-qt-mac6-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-8-MAC6.mov -f s16le
 
-FATE_SAMPLES_AVCONV += fate-qt-ulaw-mono
+FATE_QT += fate-qt-ulaw-mono
 fate-qt-ulaw-mono: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-1-16-B-ulaw.mov -f s16le
 
-FATE_SAMPLES_AVCONV += fate-qt-ulaw-stereo
+FATE_QT += fate-qt-ulaw-stereo
 fate-qt-ulaw-stereo: CMD = md5 -i $(SAMPLES)/qt-surge-suite/surge-2-16-B-ulaw.mov -f s16le
 
-FATE_SAMPLES_AVCONV += fate-quickdraw
+FATE_QT += fate-quickdraw
 fate-quickdraw: CMD = framecrc -i $(SAMPLES)/quickdraw/Airplane.mov -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-rpza
+FATE_QT += fate-rpza
 fate-rpza: CMD = framecrc -i $(SAMPLES)/rpza/rpza2.mov -t 2 -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-svq1
+FATE_QT += fate-svq1
 fate-svq1: CMD = framecrc -i $(SAMPLES)/svq1/marymary-shackles.mov -an -t 10
 
-FATE_SAMPLES_AVCONV += fate-svq3
+FATE_QT-$(CONFIG_ZLIB) += fate-svq3
 fate-svq3: CMD = framecrc -i $(SAMPLES)/svq3/Vertical400kbit.sorenson3.mov -t 6 -an
+
+FATE_QT += $(FATE_QT-yes)
+
+FATE_SAMPLES_FFMPEG += $(FATE_QT)
+fate-qt: $(FATE_QT)
diff --git a/tests/fate/real.mak b/tests/fate/real.mak
index 97160dd..3ebbd9e 100644
--- a/tests/fate/real.mak
+++ b/tests/fate/real.mak
@@ -1,25 +1,25 @@
-FATE_SAMPLES_AVCONV += fate-ra-144
+FATE_REAL += fate-ra-144
 fate-ra-144: CMD = md5 -i $(SAMPLES)/real/ra3_in_rm_file.rm -f s16le
 
-FATE_SAMPLES_AVCONV += fate-ra-288
+FATE_REAL += fate-ra-288
 fate-ra-288: CMD = pcm -i $(SAMPLES)/real/ra_288.rm
 fate-ra-288: CMP = oneoff
 fate-ra-288: REF = $(SAMPLES)/real/ra_288.pcm
 fate-ra-288: FUZZ = 2
 
-FATE_SAMPLES_AVCONV += fate-ra-cook
+FATE_REAL += fate-ra-cook
 fate-ra-cook: CMD = pcm -i $(SAMPLES)/real/ra_cook.rm
 fate-ra-cook: CMP = oneoff
 fate-ra-cook: REF = $(SAMPLES)/real/ra_cook.pcm
 
-FATE_SAMPLES_AVCONV += fate-ralf
+FATE_REAL += fate-ralf
 fate-ralf: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.rmvb -vn -f s16le
 
-FATE_SAMPLES_AVCONV += fate-rv30
+FATE_REAL += fate-rv30
 fate-rv30: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/real/rv30.rm -an
 
-FATE_SAMPLES_AVCONV += fate-rv40
-fate-rv40: CMD = framecrc -i $(SAMPLES)/real/spygames-2MB.rmvb -t 10 -an -vsync 0
+FATE_REAL += fate-rv40
+fate-rv40: CMD = framecrc -i $(SAMPLES)/real/spygames-2MB.rmvb -t 10 -an
 
 FATE_SIPR += fate-sipr-5k0
 fate-sipr-5k0: CMD = pcm -i $(SAMPLES)/sipr/sipr_5k0.rm
@@ -39,5 +39,8 @@
 
 $(FATE_SIPR): CMP = oneoff
 
-FATE_SAMPLES_AVCONV += $(FATE_SIPR)
+FATE_REAL += $(FATE_SIPR)
 fate-sipr: $(FATE_SIPR)
+
+FATE_SAMPLES_FFMPEG += $(FATE_REAL)
+fate-real: $(FATE_REAL)
diff --git a/tests/fate/screen.mak b/tests/fate/screen.mak
index 8ae7e90..14264a6 100644
--- a/tests/fate/screen.mak
+++ b/tests/fate/screen.mak
@@ -1,8 +1,8 @@
 # FIXME dropped frames in this test because of coarse timebase
-FATE_SAMPLES_AVCONV += fate-cscd
+FATE_SCREEN += fate-cscd
 fate-cscd: CMD = framecrc -i $(SAMPLES)/CSCD/sample_video.avi -an -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-dxtory
+FATE_SCREEN += fate-dxtory
 fate-dxtory: CMD = framecrc -i $(SAMPLES)/dxtory/dxtory_mic.avi
 
 FATE_FRAPS += fate-fraps-v0
@@ -23,7 +23,7 @@
 FATE_FRAPS += fate-fraps-v5
 fate-fraps-v5: CMD = framecrc -i $(SAMPLES)/fraps/fraps-v5-bouncing-balls-partial.avi
 
-FATE_SAMPLES_AVCONV += $(FATE_FRAPS)
+FATE_SCREEN += $(FATE_FRAPS)
 fate-fraps: $(FATE_FRAPS)
 
 FATE_TSCC += fate-tscc-15bit
@@ -32,7 +32,7 @@
 FATE_TSCC += fate-tscc-32bit
 fate-tscc-32bit: CMD = framecrc -i $(SAMPLES)/tscc/2004-12-17-uebung9-partial.avi -pix_fmt rgb24 -an
 
-FATE_SAMPLES_AVCONV += $(FATE_TSCC)
+FATE_SCREEN-$(CONFIG_ZLIB) += $(FATE_TSCC)
 fate-tscc: $(FATE_TSCC)
 
 FATE_VMNC += fate-vmnc-16bit
@@ -41,7 +41,7 @@
 FATE_VMNC += fate-vmnc-32bit
 fate-vmnc-32bit: CMD = framecrc -i $(SAMPLES)/VMnc/VS2k5DebugDemo-01-partial.avi -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += $(FATE_VMNC)
+FATE_SCREEN += $(FATE_VMNC)
 fate-vmnc: $(FATE_VMNC)
 
 FATE_ZMBV += fate-zmbv-8bit
@@ -56,5 +56,10 @@
 FATE_ZMBV += fate-zmbv-32bit
 fate-zmbv-32bit: CMD = framecrc -i $(SAMPLES)/zmbv/zmbv_32bit.avi -pix_fmt rgb24 -t 25
 
-FATE_SAMPLES_AVCONV += $(FATE_ZMBV)
+FATE_SCREEN-$(CONFIG_ZLIB) += $(FATE_ZMBV)
 fate-zmbv: $(FATE_ZMBV)
+
+FATE_SCREEN += $(FATE_SCREEN-yes)
+
+FATE_SAMPLES_FFMPEG += $(FATE_SCREEN)
+fate-screen: $(FATE_SCREEN)
diff --git a/tests/fate/subtitles.mak b/tests/fate/subtitles.mak
new file mode 100644
index 0000000..d73352c
--- /dev/null
+++ b/tests/fate/subtitles.mak
@@ -0,0 +1,32 @@
+FATE_SUBTITLES += fate-sub-jacosub
+fate-sub-jacosub: CMD = md5 -i $(SAMPLES)/sub/JACOsub_capability_tester.jss -f ass
+
+FATE_SUBTITLES += fate-sub-microdvd
+fate-sub-microdvd: CMD = md5 -i $(SAMPLES)/sub/MicroDVD_capability_tester.sub -f ass
+
+FATE_SUBTITLES += fate-sub-movtext
+fate-sub-movtext: CMD = md5 -i $(SAMPLES)/sub/MovText_capability_tester.mp4 -f ass
+
+FATE_SUBTITLES += 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-sub-realtext: CMD = md5 -i $(SAMPLES)/sub/RealText_capability_tester.rt -f ass
+
+FATE_SUBTITLES += fate-sub-sami
+fate-sub-sami: CMD = md5 -i $(SAMPLES)/sub/SAMI_capability_tester.smi -f ass
+
+FATE_SUBTITLES += fate-sub-srt
+fate-sub-srt: CMD = md5 -i $(SAMPLES)/sub/SubRip_capability_tester.srt -f ass
+
+FATE_SUBTITLES += 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-sub-subviewer: CMD = md5 -i $(SAMPLES)/sub/SubViewer_capability_tester.sub -f ass
+
+FATE_SUBTITLES += fate-sub-webvtt
+fate-sub-webvtt: CMD = md5 -i $(SAMPLES)/sub/WebVTT_capability_tester.vtt -f ass
+
+FATE_SAMPLES_FFMPEG += $(FATE_SUBTITLES)
+fate-subtitles: $(FATE_SUBTITLES)
diff --git a/tests/fate/utvideo.mak b/tests/fate/utvideo.mak
index 7042163..184a3be 100644
--- a/tests/fate/utvideo.mak
+++ b/tests/fate/utvideo.mak
@@ -28,7 +28,7 @@
 FATE_SAMPLES_AVCONV += $(FATE_UTVIDEO)
 fate-utvideo: $(FATE_UTVIDEO)
 
-fate-utvideoenc%: CMD = framemd5 -f image2 -vcodec pgmyuv -i $(TARGET_PATH)/tests/vsynth1/%02d.pgm -vcodec utvideo -f avi -sws_flags +accurate_rnd+bitexact ${OPTS}
+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
diff --git a/tests/fate/vcodec.mak b/tests/fate/vcodec.mak
index 23dbc98..e895499 100644
--- a/tests/fate/vcodec.mak
+++ b/tests/fate/vcodec.mak
@@ -2,9 +2,11 @@
 fate-vsynth2-%: SRC = tests/data/vsynth2.yuv
 fate-vsynth%: CODEC = $(word 3, $(subst -, ,$(@)))
 fate-vsynth%: FMT = avi
-fate-vsynth%: CMD = enc_dec "rawvideo -s 352x288 -pix_fmt yuv420p" $(SRC) $(FMT) "-c $(CODEC) $(ENCOPTS)" rawvideo "-s 352x288 -pix_fmt yuv420p $(DECOPTS)" -keep
+fate-vsynth%: CMD = enc_dec "rawvideo -s 352x288 -pix_fmt yuv420p $(RAWDECOPTS)" $(SRC) $(FMT) "-c $(CODEC) $(ENCOPTS)" rawvideo "-s 352x288 -pix_fmt yuv420p -vsync 0 $(DECOPTS)" -keep "$(DECINOPTS)"
 fate-vsynth%: CMP_UNIT = 1
 
+FATE_VCODEC += amv
+
 FATE_VCODEC += asv1
 fate-vsynth%-asv1:               ENCOPTS = -qscale 10
 
@@ -15,22 +17,22 @@
 
 FATE_VCODEC += dnxhd-720p
 fate-vsynth%-dnxhd-720p:         ENCOPTS = -s hd720 -b 90M              \
-                                           -pix_fmt yuv422p -frames 5
+                                           -pix_fmt yuv422p -frames 5 -qmax 8
 fate-vsynth%-dnxhd-720p:         FMT     = dnxhd
 
 FATE_VCODEC += dnxhd-720p-rd
 fate-vsynth%-dnxhd-720p-rd:      ENCOPTS = -s hd720 -b 90M -threads 4 -mbd rd \
-                                           -pix_fmt yuv422p -frames 5
+                                           -pix_fmt yuv422p -frames 5 -qmax 8
 fate-vsynth%-dnxhd-720p-rd:      FMT     = dnxhd
 
 FATE_VCODEC += dnxhd-720p-10bit
 fate-vsynth%-dnxhd-720p-10bit:   ENCOPTS = -s hd720 -b 90M              \
-                                           -pix_fmt yuv422p10 -frames 5
+                                           -pix_fmt yuv422p10 -frames 5 -qmax 8
 fate-vsynth%-dnxhd-720p-10bit:   FMT     = dnxhd
 
 FATE_VCODEC += dnxhd-1080i
 fate-vsynth%-dnxhd-1080i:        ENCOPTS = -s hd1080 -b 120M -flags +ildct \
-                                           -pix_fmt yuv422p -frames 5
+                                           -pix_fmt yuv422p -frames 5 -qmax 8
 fate-vsynth%-dnxhd-1080i:        FMT     = mov
 
 FATE_VCODEC += dv
@@ -57,11 +59,16 @@
 
 FATE_VCODEC += ffvhuff
 
-FATE_VCODEC += flashsv
+FATE_VCODEC-$(CONFIG_ZLIB) += flashsv
 fate-vsynth%-flashsv:            ENCOPTS = -sws_flags neighbor+full_chroma_int
 fate-vsynth%-flashsv:            DECOPTS = -sws_flags area
 fate-vsynth%-flashsv:            FMT     = flv
 
+FATE_VCODEC-$(CONFIG_ZLIB) += flashsv2
+fate-vsynth%-flashsv2:           ENCOPTS = -sws_flags neighbor+full_chroma_int -strict experimental -compression_level 0
+fate-vsynth%-flashsv2:           DECOPTS = -sws_flags area
+fate-vsynth%-flashsv2:           FMT     = flv
+
 FATE_VCODEC += flv
 fate-vsynth%-flv:                ENCOPTS = -qscale 10
 fate-vsynth%-flv:                FMT     = flv
@@ -86,6 +93,10 @@
 fate-vsynth%-jpegls:             ENCOPTS = -sws_flags neighbor+full_chroma_int
 fate-vsynth%-jpegls:             DECOPTS = -sws_flags area
 
+FATE_VCODEC += j2k
+fate-vsynth%-j2k:                ENCOPTS = -qscale 7 -strict experimental -pix_fmt rgb24
+fate-vsynth%-j2k:                DECINOPTS = -vcodec j2k -strict experimental
+
 FATE_VCODEC += ljpeg
 fate-vsynth%-ljpeg:              ENCOPTS = -strict -1
 
@@ -185,13 +196,26 @@
 FATE_VCODEC += msmpeg4v2
 fate-vsynth%-msmpeg4v2:          ENCOPTS = -qscale 10
 
+FATE_VCODEC-$(CONFIG_ZLIB) += mpng
+fate-vsynth%-mpng:               CODEC   = png
+
+FATE_VCODEC += msvideo1
+
 FATE_VCODEC += prores
-fate-vsynth%-prores:             ENCOPTS = -profile hq
 fate-vsynth%-prores:             FMT     = mov
 
+FATE_VCODEC += prores_kostya
+fate-vsynth%-prores_kostya:             ENCOPTS = -profile hq
+fate-vsynth%-prores_kostya:             FMT     = mov
+
 FATE_VCODEC += qtrle
 fate-vsynth%-qtrle:              FMT     = mov
 
+FATE_VCODEC += qtrlegray
+fate-vsynth%-qtrlegray:          CODEC   = qtrle
+fate-vsynth%-qtrlegray:          ENCOPTS = -pix_fmt gray
+fate-vsynth%-qtrlegray:          FMT     = mov
+
 FATE_VCODEC += rgb
 fate-vsynth%-rgb:                CODEC   = rawvideo
 fate-vsynth%-rgb:                ENCOPTS = -pix_fmt bgr24
@@ -199,6 +223,7 @@
 FATE_VCODEC += roqvideo
 fate-vsynth%-roqvideo:           CODEC   = roqvideo
 fate-vsynth%-roqvideo:           ENCOPTS = -frames 5
+fate-vsynth%-roqvideo:           RAWDECOPTS = -r 30
 fate-vsynth%-roqvideo:           FMT     = roq
 
 FATE_VCODEC += rv10
@@ -227,8 +252,21 @@
 fate-vsynth%-svq1:               ENCOPTS = -qscale 3 -pix_fmt yuv410p
 fate-vsynth%-svq1:               FMT     = mov
 
+FATE_VCODEC += r210
+
 FATE_VCODEC += v210
 
+FATE_VCODEC += v308
+
+FATE_VCODEC += v408
+fate-vsynth%-v408:               ENCOPTS = -sws_flags neighbor+bitexact
+fate-vsynth%-v408:               DECOPTS = -sws_flags neighbor+bitexact
+
+FATE_VCODEC += avui
+fate-vsynth%-avui:               ENCOPTS = -s pal -strict experimental -sws_flags neighbor+bitexact
+fate-vsynth%-avui:               DECOPTS = -sws_flags neighbor+bitexact
+fate-vsynth%-avui:               FMT     = mov
+
 FATE_VCODEC += wmv1
 fate-vsynth%-wmv1:               ENCOPTS = -qscale 10
 
@@ -238,6 +276,14 @@
 FATE_VCODEC += yuv
 fate-vsynth%-yuv:                CODEC = rawvideo
 
+FATE_VCODEC += yuv4
+
+FATE_VCODEC += y41p
+
+FATE_VCODEC-$(CONFIG_ZLIB) += zlib
+
+FATE_VCODEC += $(FATE_VCODEC-yes)
+
 FATE_VSYNTH1 = $(FATE_VCODEC:%=fate-vsynth1-%)
 FATE_VSYNTH2 = $(FATE_VCODEC:%=fate-vsynth2-%)
 
diff --git a/tests/fate/video.mak b/tests/fate/video.mak
index b36554f..65b98a4 100644
--- a/tests/fate/video.mak
+++ b/tests/fate/video.mak
@@ -4,52 +4,55 @@
 FATE_4XM += fate-4xm-2
 fate-4xm-2: CMD = framecrc -i $(SAMPLES)/4xm/version2.4xm -pix_fmt rgb24 -an
 
-FATE_SAMPLES_AVCONV += $(FATE_4XM)
+FATE_VIDEO += $(FATE_4XM)
 fate-4xm: $(FATE_4XM)
 
-FATE_SAMPLES_AVCONV += fate-aasc
+FATE_VIDEO += fate-aasc
 fate-aasc: CMD = framecrc -i $(SAMPLES)/aasc/AASC-1.5MB.AVI -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-alg-mm
+FATE_VIDEO += fate-alg-mm
 fate-alg-mm: CMD = framecrc -i $(SAMPLES)/alg-mm/ibmlogo.mm -an -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-amv
+FATE_VIDEO += fate-amv
 fate-amv: CMD = framecrc -idct simple -i $(SAMPLES)/amv/MTV_high_res_320x240_sample_Penguin_Joke_MTV_from_WMV.amv -t 10 -an
 
-FATE_SAMPLES_AVCONV += fate-ansi
+FATE_VIDEO += fate-ansi
 fate-ansi: CMD = framecrc -chars_per_frame 44100 -i $(SAMPLES)/ansi/TRE-IOM5.ANS -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-armovie-escape124
+FATE_VIDEO += fate-ansi256
+fate-ansi256: CMD = framecrc -chars_per_frame 44100 -i $(SAMPLES)/ansi/ansi256.ans -pix_fmt rgb24
+
+FATE_VIDEO += fate-armovie-escape124
 fate-armovie-escape124: CMD = framecrc -i $(SAMPLES)/rpl/ESCAPE.RPL -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-auravision-v1
+FATE_VIDEO += fate-auravision-v1
 fate-auravision-v1: CMD = framecrc -i $(SAMPLES)/auravision/SOUVIDEO.AVI -an
 
-FATE_SAMPLES_AVCONV += fate-auravision-v2
+FATE_VIDEO += fate-auravision-v2
 fate-auravision-v2: CMD = framecrc -i $(SAMPLES)/auravision/salma-hayek-in-ugly-betty-partial-avi -an
 
-FATE_SAMPLES_AVCONV += fate-bethsoft-vid
+FATE_VIDEO += fate-bethsoft-vid
 fate-bethsoft-vid: CMD = framecrc -i $(SAMPLES)/bethsoft-vid/ANIM0001.VID -t 5 -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-bfi
+FATE_VIDEO += fate-bfi
 fate-bfi: CMD = framecrc -i $(SAMPLES)/bfi/2287.bfi -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-bink-video
+FATE_VIDEO += fate-bink-video
 fate-bink-video: CMD = framecrc -i $(SAMPLES)/bink/hol2br.bik
 
-FATE_SAMPLES_AVCONV += fate-bmv-video
+FATE_VIDEO += fate-bmv-video
 fate-bmv-video: CMD = framecrc -i $(SAMPLES)/bmv/SURFING-partial.BMV -pix_fmt rgb24 -an
 
-FATE_SAMPLES_AVCONV += fate-cdgraphics
+FATE_VIDEO += fate-cdgraphics
 fate-cdgraphics: CMD = framecrc -i $(SAMPLES)/cdgraphics/BrotherJohn.cdg -pix_fmt rgb24 -t 1
 
-FATE_SAMPLES_AVCONV += fate-cljr
+FATE_VIDEO += fate-cljr
 fate-cljr: CMD = framecrc -i $(SAMPLES)/cljr/testcljr-partial.avi
 
-FATE_SAMPLES_AVCONV += fate-corepng
+FATE_VIDEO-$(CONFIG_ZLIB) += fate-corepng
 fate-corepng: CMD = framecrc -i $(SAMPLES)/png1/corepng-partial.avi
 
-FATE_SAMPLES_AVCONV += fate-creatureshock-avs
+FATE_VIDEO += fate-creatureshock-avs
 fate-creatureshock-avs: CMD = framecrc -i $(SAMPLES)/creatureshock-avs/OUTATIME.AVS -pix_fmt rgb24
 
 FATE_CVID += fate-cvid-partial
@@ -61,19 +64,19 @@
 FATE_CVID += fate-cvid-grayscale
 fate-cvid-grayscale: CMD = framecrc -i $(SAMPLES)/cvid/pcitva15.avi -an
 
-FATE_SAMPLES_AVCONV += $(FATE_CVID)
+FATE_VIDEO += $(FATE_CVID)
 fate-cvid: $(FATE_CVID)
 
-FATE_SAMPLES_AVCONV += fate-cyberia-c93
+FATE_VIDEO += fate-cyberia-c93
 fate-cyberia-c93: CMD = framecrc -i $(SAMPLES)/cyberia-c93/intro1.c93 -t 3 -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-cyuv
+FATE_VIDEO += fate-cyuv
 fate-cyuv: CMD = framecrc -i $(SAMPLES)/cyuv/cyuv.avi
 
-FATE_SAMPLES_AVCONV += fate-delphine-cin-video
+FATE_VIDEO += fate-delphine-cin-video
 fate-delphine-cin-video: CMD = framecrc -i $(SAMPLES)/delphine-cin/LOGO-partial.CIN -pix_fmt rgb24 -an
 
-FATE_SAMPLES_AVCONV += fate-deluxepaint-anm
+FATE_VIDEO += fate-deluxepaint-anm
 fate-deluxepaint-anm: CMD = framecrc -i $(SAMPLES)/deluxepaint-anm/INTRO1.ANM -pix_fmt rgb24
 
 FATE_TRUEMOTION1 += fate-truemotion1-15
@@ -82,10 +85,10 @@
 FATE_TRUEMOTION1 += fate-truemotion1-24
 fate-truemotion1-24: CMD = framecrc -i $(SAMPLES)/duck/sonic3dblast_intro-partial.avi -pix_fmt rgb24 -an
 
-FATE_SAMPLES_AVCONV += $(FATE_TRUEMOTION1)
+FATE_VIDEO += $(FATE_TRUEMOTION1)
 fate-truemotion1: $(FATE_TRUEMOTION1)
 
-FATE_SAMPLES_AVCONV += fate-truemotion2
+FATE_VIDEO += fate-truemotion2
 fate-truemotion2: CMD = framecrc -i $(SAMPLES)/duck/tm20.avi
 
 FATE_DXA += fate-dxa-feeble
@@ -94,10 +97,10 @@
 FATE_DXA += fate-dxa-scummvm
 fate-dxa-scummvm: CMD = framecrc -i $(SAMPLES)/dxa/scummvm.dxa -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += $(FATE_DXA)
+FATE_VIDEO-$(CONFIG_ZLIB) += $(FATE_DXA)
 fate-dxa: $(FATE_DXA)
 
-FATE_SAMPLES_AVCONV += fate-film-cvid
+FATE_SAMPLES_PCM += fate-film-cvid
 fate-film-cvid: CMD = framecrc -i $(SAMPLES)/film/logo-capcom.cpk -an
 
 FATE_FLIC += fate-flic-af11-palette-change
@@ -109,16 +112,16 @@
 FATE_FLIC += fate-flic-magiccarpet
 fate-flic-magiccarpet: CMD = framecrc -i $(SAMPLES)/fli/intel.dat -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += $(FATE_FLIC)
+FATE_VIDEO += $(FATE_FLIC)
 fate-flic: $(FATE_FLIC)
 
-FATE_SAMPLES_AVCONV += fate-frwu
+FATE_VIDEO += fate-frwu
 fate-frwu: CMD = framecrc -i $(SAMPLES)/frwu/frwu.avi
 
-FATE_SAMPLES_AVCONV += fate-id-cin-video
+FATE_VIDEO += fate-id-cin-video
 fate-id-cin-video: CMD = framecrc -i $(SAMPLES)/idcin/idlog-2MB.cin -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-idroq-video-encode
+FATE_VIDEO-$(CONFIG_AVFILTER) += fate-idroq-video-encode
 fate-idroq-video-encode: CMD = md5 -f image2 -vcodec pgmyuv -i $(SAMPLES)/ffmpeg-synthetic/vsynth1/%02d.pgm -sws_flags +bitexact -vf pad=512:512:80:112 -f roq -t 0.2
 
 FATE_IFF += fate-iff-byterun1
@@ -130,37 +133,40 @@
 FATE_IFF += fate-iff-ilbm
 fate-iff-ilbm: CMD = framecrc -i $(SAMPLES)/iff/lms-matriks.ilbm -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += $(FATE_IFF)
+FATE_VIDEO += $(FATE_IFF)
 fate-iff: $(FATE_IFF)
 
-FATE_SAMPLES_AVCONV += fate-interplay-mve-8bit
+FATE_VIDEO += fate-interplay-mve-8bit
 fate-interplay-mve-8bit: CMD = framecrc -i $(SAMPLES)/interplay-mve/interplay-logo-2MB.mve -pix_fmt rgb24 -an
 
-FATE_SAMPLES_AVCONV += fate-interplay-mve-16bit
+FATE_VIDEO += fate-interplay-mve-16bit
 fate-interplay-mve-16bit: CMD = framecrc -i $(SAMPLES)/interplay-mve/descent3-level5-16bit-partial.mve -pix_fmt rgb24 -an
 
-FATE_SAMPLES_AVCONV += fate-kgv1
+FATE_VIDEO += fate-jv
+fate-jv: CMD = framecrc -i $(SAMPLES)/jv/intro.jv -pix_fmt rgb24 -an
+
+FATE_VIDEO += fate-kgv1
 fate-kgv1: CMD = framecrc -i $(SAMPLES)/kega/kgv1.avi -pix_fmt rgb555le -an
 
-FATE_SAMPLES_AVCONV += fate-kmvc
+FATE_VIDEO += fate-kmvc
 fate-kmvc: CMD = framecrc -i $(SAMPLES)/KMVC/LOGO1.AVI -an -t 3 -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-mdec
+FATE_VIDEO += fate-mdec
 fate-mdec: CMD = framecrc -idct simple -i $(SAMPLES)/ea-dct/NFS2Esprit-partial.dct -an
 
-FATE_SAMPLES_AVCONV += fate-mdec-v3
+FATE_VIDEO += fate-mdec-v3
 fate-mdec-v3: CMD = framecrc -idct simple -i $(SAMPLES)/psx-str/abc000_cut.str -an
 
-FATE_SAMPLES_AVCONV += fate-mimic
+FATE_VIDEO += fate-mimic
 fate-mimic: CMD = framecrc -idct simple -i $(SAMPLES)/mimic/mimic2-womanloveffmpeg.cam
 
-FATE_SAMPLES_AVCONV += fate-mjpegb
+FATE_VIDEO += fate-mjpegb
 fate-mjpegb: CMD = framecrc -idct simple -flags +bitexact -i $(SAMPLES)/mjpegb/mjpegb_part.mov -an
 
-FATE_SAMPLES_AVCONV += fate-motionpixels
+FATE_VIDEO += fate-motionpixels
 fate-motionpixels: CMD = framecrc -i $(SAMPLES)/motion-pixels/INTRO-partial.MVI -an -pix_fmt rgb24 -vframes 111
 
-FATE_SAMPLES_AVCONV += fate-mpeg2-field-enc
+FATE_VIDEO += fate-mpeg2-field-enc
 fate-mpeg2-field-enc: CMD = framecrc -flags +bitexact -dct fastint -idct simple -i $(SAMPLES)/mpeg2/mpeg2_field_encoding.ts -an
 
 # FIXME dropped frames in this test because of coarse timebase
@@ -170,43 +176,46 @@
 FATE_NUV += fate-nuv-rtjpeg-fh
 fate-nuv-rtjpeg-fh: CMD = framecrc -idct simple -i $(SAMPLES)/nuv/rtjpeg_frameheader.nuv -an
 
-FATE_SAMPLES_AVCONV += $(FATE_NUV)
+FATE_VIDEO += $(FATE_NUV)
 fate-nuv: $(FATE_NUV)
 
-FATE_SAMPLES_AVCONV += fate-qpeg
+FATE_VIDEO += fate-paf-video
+fate-paf-video: CMD = framecrc -i $(SAMPLES)/paf/hod1-partial.paf -pix_fmt rgb24 -an
+
+FATE_VIDEO += fate-qpeg
 fate-qpeg: CMD = framecrc -i $(SAMPLES)/qpeg/Clock.avi -an -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-r210
+FATE_VIDEO += fate-r210
 fate-r210: CMD = framecrc -i $(SAMPLES)/r210/r210.avi -pix_fmt rgb48le
 
-FATE_SAMPLES_AVCONV += fate-rl2
+FATE_VIDEO += fate-rl2
 fate-rl2: CMD = framecrc -i $(SAMPLES)/rl2/Z4915300.RL2 -pix_fmt rgb24 -an
 
-FATE_SAMPLES_AVCONV += fate-roqvideo
+FATE_VIDEO += fate-roqvideo
 fate-roqvideo: CMD = framecrc -i $(SAMPLES)/idroq/idlogo.roq -an
 
-FATE_SAMPLES_AVCONV += fate-sierra-vmd-video
+FATE_VIDEO += fate-sanm
+fate-sanm: CMD = framecrc -i $(SAMPLES)/smush/ronin_part.znm -an -pix_fmt rgb24
+
+FATA_VIDEO += fate-sierra-vmd-video
 fate-sierra-vmd-video: CMD = framecrc -i $(SAMPLES)/vmd/12.vmd -pix_fmt rgb24 -an
 
-FATE_SAMPLES_AVCONV += fate-smacker-video
+FATA_VIDEO += fate-smacker-video
 fate-smacker-video: CMD = framecrc -i $(SAMPLES)/smacker/wetlogo.smk -pix_fmt rgb24 -an
 
-FATE_SAMPLES_AVCONV += fate-smc
+FATE_VIDEO += fate-smc
 fate-smc: CMD = framecrc -i $(SAMPLES)/smc/cass_schi.qt -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-sp5x
+FATE_VIDEO += fate-sp5x
 fate-sp5x: CMD = framecrc -idct simple -i $(SAMPLES)/sp5x/sp5x_problem.avi
 
-FATE_SAMPLES_AVCONV += fate-sub-srt
-fate-sub-srt: CMD = md5 -i $(SAMPLES)/sub/SubRip_capability_tester.srt -f ass
-
-FATE_SAMPLES_AVCONV += fate-thp
+FATE_VIDEO += fate-thp
 fate-thp: CMD = framecrc -idct simple -i $(SAMPLES)/thp/pikmin2-opening1-partial.thp -an
 
-FATE_SAMPLES_AVCONV += fate-tiertex-seq
+FATE_VIDEO += fate-tiertex-seq
 fate-tiertex-seq: CMD = framecrc -i $(SAMPLES)/tiertex-seq/Gameover.seq -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-tmv
+FATE_VIDEO += fate-tmv
 fate-tmv: CMD = framecrc -i $(SAMPLES)/tmv/pop-partial.tmv -pix_fmt rgb24
 
 FATE_TXD += fate-txd-16bpp
@@ -215,39 +224,44 @@
 FATE_TXD += fate-txd-pal8
 fate-txd-pal8: CMD = framecrc -i $(SAMPLES)/txd/outro.txd -pix_fmt rgb24 -an
 
-FATE_SAMPLES_AVCONV += $(FATE_TXD)
+FATE_VIDEO += $(FATE_TXD)
 fate-txd: $(FATE_TXD)
 
-FATE_SAMPLES_AVCONV += fate-ulti
+FATE_VIDEO += fate-ulti
 fate-ulti: CMD = framecrc -i $(SAMPLES)/ulti/hit12w.avi -an
 
-FATE_SAMPLES_AVCONV += fate-v210
+FATE_VIDEO += fate-v210
 fate-v210: CMD = framecrc -i $(SAMPLES)/v210/v210_720p-partial.avi -pix_fmt yuv422p16be -an
 
-FATE_SAMPLES_AVCONV += fate-v410dec
+FATE_VIDEO += fate-v410dec
 fate-v410dec: CMD = framecrc -i $(SAMPLES)/v410/lenav410.mov -pix_fmt yuv444p10le
 
-FATE_SAMPLES_AVCONV += fate-v410enc
+FATE_VIDEO += fate-v410enc
 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_SAMPLES_AVCONV += fate-vcr1
+FATE_VIDEO += fate-vcr1
 fate-vcr1: CMD = framecrc -i $(SAMPLES)/vcr1/VCR1test.avi -an
 
-FATE_SAMPLES_AVCONV += fate-videoxl
+FATE_VIDEO += fate-videoxl
 fate-videoxl: CMD = framecrc -i $(SAMPLES)/vixl/pig-vixl.avi
 
-FATE_SAMPLES_AVCONV += fate-vqa-cc
+FATE_VIDEO += fate-vqa-cc
 fate-vqa-cc: CMD = framecrc -i $(SAMPLES)/vqa/cc-demo1-partial.vqa -pix_fmt rgb24 -an
 
-FATE_SAMPLES_AVCONV += fate-wc3movie-xan
+FATE_VIDEO += fate-wc3movie-xan
 fate-wc3movie-xan: CMD = framecrc -i $(SAMPLES)/wc3movie/SC_32-part.MVE -pix_fmt rgb24
 
-FATE_SAMPLES_AVCONV += fate-wnv1
+FATE_VIDEO += fate-wnv1
 fate-wnv1: CMD = framecrc -i $(SAMPLES)/wnv1/wnv1-codec.avi -an
 
-FATE_SAMPLES_AVCONV += fate-yop
+FATE_VIDEO += fate-yop
 fate-yop: CMD = framecrc -i $(SAMPLES)/yop/test1.yop -pix_fmt rgb24 -an
 
-FATE_SAMPLES_AVCONV += fate-xxan-wc4
+FATE_VIDEO += fate-xxan-wc4
 fate-xxan-wc4: CMD = framecrc -i $(SAMPLES)/wc4-xan/wc4trailer-partial.avi -an
+
+FATE_VIDEO += $(FATE_VIDEO-yes)
+
+FATE_SAMPLES_FFMPEG += $(FATE_VIDEO)
+fate-video: $(FATE_VIDEO)
diff --git a/tests/fate/voice.mak b/tests/fate/voice.mak
index 8fe445a..3535d55 100644
--- a/tests/fate/voice.mak
+++ b/tests/fate/voice.mak
@@ -6,7 +6,7 @@
 fate-g722-encode: SRC = tests/data/asynth-16000-1.wav
 fate-g722-encode: CMD = enc_dec_pcm wav md5 s16le $(SRC) -c:a g722
 
-FATE_SAMPLES_AVCONV += $(FATE_G722)
+FATE_VOICE += $(FATE_G722)
 fate-g722: $(FATE_G722)
 
 FATE_G723_1 += fate-g723_1-dec-1
@@ -51,7 +51,7 @@
 $(FATE_G726): tests/data/asynth-8000-1.wav
 $(FATE_G726): SRC = tests/data/asynth-8000-1.wav
 
-FATE_SAMPLES_AVCONV += $(FATE_G726)
+FATE_VOICE += $(FATE_G726)
 fate-g726: $(FATE_G726)
 
 FATE_GSM += fate-gsm-ms
@@ -60,15 +60,18 @@
 FATE_GSM += fate-gsm-toast
 fate-gsm-toast: CMD = framecrc -i $(SAMPLES)/gsm/sample-gsm-8000.mov -t 10
 
-FATE_SAMPLES_AVCONV += $(FATE_GSM)
+FATE_VOICE += $(FATE_GSM)
 fate-gsm: $(FATE_GSM)
 
-FATE_SAMPLES_AVCONV += fate-qcelp
+FATE_VOICE += fate-qcelp
 fate-qcelp: CMD = pcm -i $(SAMPLES)/qcp/0036580847.QCP
 fate-qcelp: CMP = oneoff
 fate-qcelp: REF = $(SAMPLES)/qcp/0036580847.pcm
 
-FATE_SAMPLES_AVCONV += fate-truespeech
+FATE_VOICE += fate-truespeech
 fate-truespeech: CMD = pcm -i $(SAMPLES)/truespeech/a6.wav
 fate-truespeech: CMP = oneoff
 fate-truespeech: REF = $(SAMPLES)/truespeech/a6.pcm
+
+FATE_SAMPLES_FFMPEG += $(FATE_VOICE)
+fate-voice: $(FATE_VOICE)
diff --git a/tests/fate/vpx.mak b/tests/fate/vpx.mak
index 4c1ed0d..d3f9cc7 100644
--- a/tests/fate/vpx.mak
+++ b/tests/fate/vpx.mak
@@ -37,13 +37,13 @@
 $(foreach N,$(VP8_SUITE),$(eval $(call FATE_VP8_SUITE,$(N),$(1),$(2))))
 
 # FIXME this file contains two frames with identical timestamps,
-# so avconv drops one of them
+# so ffmpeg drops one of them
 FATE_VP8 += fate-vp8-sign-bias$(1)
 fate-vp8-sign-bias$(1): CMD = framemd5 $(2) -i $(SAMPLES)/vp8/sintel-signbias.ivf
 fate-vp8-sign-bias$(1): REF = $(SRC_PATH)/tests/ref/fate/vp8-sign-bias
 
 FATE_VP8 += fate-vp8-size-change$(1)
-fate-vp8-size-change$(1): CMD = framemd5 $(2) -i $(SAMPLES)/vp8/frame_size_change.webm -frames:v 30
+fate-vp8-size-change$(1): CMD = framemd5 $(2) -flags +bitexact -i $(SAMPLES)/vp8/frame_size_change.webm -frames:v 30 -sws_flags bitexact+bilinear
 fate-vp8-size-change$(1): REF = $(SRC_PATH)/tests/ref/fate/vp8-size-change
 endef
 
diff --git a/tests/fate/vqf.mak b/tests/fate/vqf.mak
index 1867635..b8a91c1 100644
--- a/tests/fate/vqf.mak
+++ b/tests/fate/vqf.mak
@@ -1,7 +1,10 @@
-FATE_SAMPLES_AVCONV += fate-twinvq
+FATE_VQF += fate-twinvq
 fate-twinvq: CMD = pcm -i $(SAMPLES)/vqf/achterba.vqf
 fate-twinvq: CMP = oneoff
 fate-twinvq: REF = $(SAMPLES)/vqf/achterba.pcm
 
-FATE_SAMPLES_AVCONV += fate-vqf-demux
+FATE_VQF += fate-vqf-demux
 fate-vqf-demux: CMD = md5 -i $(SAMPLES)/vqf/achterba.vqf -acodec copy -f framecrc
+
+FATE_SAMPLES_FFMPEG += $(FATE_VQF)
+fate-vqf: $(FATE_VQF)
diff --git a/tests/ffserver-regression.sh b/tests/ffserver-regression.sh
new file mode 100755
index 0000000..11e4a54
--- /dev/null
+++ b/tests/ffserver-regression.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+#perl -e 'chomp($wd = `pwd`); print map { s!tests/data/!!; "<Stream $_>\nFile $wd/tests/data/$_\n</Stream>\n\n" } @ARGV' tests/data/a* >> tests/data/ffserver.conf
+#perl -e 'chomp($wd = `pwd`); print map { s!tests/data/!!; "<Stream $_.asf>\nFile $wd/tests/data/$_\n</Stream>\n\n" } @ARGV' tests/data/a* >> tests/data/ffserver.conf
+
+. $(dirname $0)/md5.sh
+
+FILES=$(sed -n 's/^[^#]*<Stream \(.*\)>.*/\1/p' $2 | grep -v html)
+
+rm -f tests/feed1.ffm
+./ffserver -d -f "$2" 2> /dev/null &
+FFSERVER_PID=$!
+echo "Waiting for feeds to startup..."
+sleep 2
+(
+    cd tests/data || exit $?
+    rm -f ff-* ffserver.regression
+    WGET_OPTIONS="--user-agent=NSPlayer -q --proxy=off -e verbose=off -e server_response=off"
+    for file in $FILES; do
+        if [ $(expr $file : "a-*") != 0 ]; then
+            wget $WGET_OPTIONS -O - http://localhost:9999/$file > ff-$file
+        else
+            wget $WGET_OPTIONS -O - http://localhost:9999/$file?date=19700101T000000Z | dd bs=1 count=20000 > ff-$file 2>/dev/null
+        fi
+        do_md5sum ff-$file >>ffserver.regression
+    done
+)
+kill $FFSERVER_PID
+wait > /dev/null 2>&1
+rm -f tests/feed1.ffm
+if diff -u "$1" tests/data/ffserver.regression; then
+    echo
+    echo Server regression test succeeded.
+    exit 0
+else
+    echo
+    echo Server regression test: Error.
+    exit 1
+fi
diff --git a/tests/ffserver.conf b/tests/ffserver.conf
new file mode 100644
index 0000000..1e6994a
--- /dev/null
+++ b/tests/ffserver.conf
@@ -0,0 +1,307 @@
+#
+# This is a test configuration file. You can invoke it with
+# ../ffserver -f ffserver.conf
+# when in the tests directory and once the vsynth1 subdirectory
+# has been populated. Then point your browser at http://whatever:9999/teststat.html
+# and you can look at the streams
+#
+
+#
+# Port on which the server is listening. You must select a different
+# port from your standard http web server if it is running on the same
+# computer.
+
+Port 9999
+RTSPPort 9990
+
+# Address on which the server is bound. Only useful if you have
+# several network interfaces.
+
+BindAddress 0.0.0.0
+
+# Number of simultaneous requests that can be handled. Since FFServer
+# is very fast, this limit is determined mainly by your Internet
+# connection speed.
+
+MaxClients 1000
+
+MaxBandwidth 100000
+
+# Access Log file (uses standard Apache log file format)
+# '-' is the standard output
+
+CustomLog -
+
+##################################################################
+# Definition of the live feeds. Each live feed contains one video
+# and/or audio sequence coming from an ffmpeg encoder or another
+# ffserver. This sequence may be encoded simultaneously with several
+# codecs at several resolutions.
+
+<Feed feed1.ffm>
+
+# You must use 'ffmpeg' to send a live feed to ffserver. In this
+# example, you can type:
+#
+# ffmpeg http://localhost:8090/feed1.ffm
+
+# ffserver can also do time shifting. It means that it can stream any
+# previously recorded live stream. The request should contain:
+# "http://xxxx?date=[YYYY-MM-DDT][[HH:]MM:]SS[.m...]".You must specify
+# a path where the feed is stored on disk. You also specify the
+# maximum size of the feed (100M bytes here). Default:
+# File=/tmp/feed_name.ffm FileMaxSize=5M
+
+File tests/feed1.ffm
+FileMaxSize 100M
+
+# Fire up ffmpeg pointing at this stream
+
+Launch ./ffmpeg -v 0 -y -f pgmyuv -i tests/vsynth1/%02d.pgm
+
+ACL allow localhost
+</Feed>
+
+##################################################################
+# Now you can define each stream which will be generated from the
+# original audio and video stream. Each format has a filename (here
+# 'test128.mpg'). FFServer will send this stream when answering a
+# request containing this filename.
+
+<Stream test_h.avi>
+Feed feed1.ffm
+Format avi
+#
+BitExact
+DctFastint
+IdctSimple
+VideoFrameRate 10
+VideoSize 352x288
+VideoBitRate 100
+VideoGopSize 30
+NoAudio
+
+PreRoll 10
+StartSendOnKey
+MaxTime 100
+
+</Stream>
+
+<Stream test_l.avi>
+Feed feed1.ffm
+Format avi
+#
+BitExact
+DctFastint
+IdctSimple
+VideoFrameRate 2
+VideoSize 320x240
+VideoBitRate 40
+VideoGopSize 20
+NoAudio
+
+PreRoll 20
+StartSendOnKey
+MaxTime 100
+
+</Stream>
+
+#<Stream test_h.mpg>
+#Feed feed1.ffm
+#
+#VideoFrameRate 10
+#VideoSize 352x288
+#VideoBitRate 100
+#VideoGopSize 30
+#NoAudio
+
+#PreRoll 10
+#StartSendOnKey
+#MaxTime 100
+#
+#</Stream>
+#
+#<Stream test_l.mpg>
+#Feed feed1.ffm
+##
+#VideoFrameRate 2
+#VideoSize 320x240
+#VideoBitRate 40
+#VideoGopSize 20
+#NoAudio
+#
+#PreRoll 20
+#StartSendOnKey
+#MaxTime 100
+#
+#</Stream>
+#
+<Stream test.swf>
+Feed feed1.ffm
+#
+BitExact
+DctFastint
+IdctSimple
+Qscale 10
+VideoFrameRate 10
+VideoSize 352x288
+VideoBitRate 100
+VideoGopSize 30
+NoAudio
+
+PreRoll 10
+StartSendOnKey
+MaxTime 100
+
+</Stream>
+
+<Stream test_h.asf>
+Feed feed1.ffm
+Format asf
+#
+BitExact
+DctFastint
+IdctSimple
+Qscale 10
+VideoFrameRate 10
+VideoSize 320x240
+VideoBitRate 100
+VideoGopSize 30
+NoAudio
+
+PreRoll 10
+StartSendOnKey
+MaxTime 100
+
+Title "Test data stream"
+
+</Stream>
+
+<Stream test_l.asf>
+Feed feed1.ffm
+Format asf
+#
+BitExact
+DctFastint
+IdctSimple
+Qscale 10
+VideoFrameRate 2
+VideoSize 320x240
+VideoBitRate 40
+VideoGopSize 20
+NoAudio
+
+PreRoll 20
+StartSendOnKey
+MaxTime 100
+
+Title "Test data stream"
+
+</Stream>
+
+<Stream test_h.rm>
+
+Feed feed1.ffm
+Format rm
+
+BitExact
+DctFastint
+IdctSimple
+Qscale 10
+VideoBitRate 100
+VideoFrameRate 10
+VideoGopSize 30
+VideoSize    320x240
+NoAudio
+
+PreRoll 10
+StartSendOnKey
+MaxTime 100
+
+</Stream>
+
+<Stream test_l.rm>
+
+Feed feed1.ffm
+Format rm
+
+BitExact
+DctFastint
+IdctSimple
+Qscale 10
+VideoBitRate 40
+VideoFrameRate 2
+VideoGopSize 20
+VideoSize    320x240
+NoAudio
+
+PreRoll 20
+StartSendOnKey
+MaxTime 100
+
+</Stream>
+
+
+<Stream test.jpg>
+
+Feed feed1.ffm
+Format jpeg
+Strict -1
+
+BitExact
+DctFastint
+IdctSimple
+VideoFrameRate 1
+VideoSize 352x288
+NoAudio
+
+PreRoll 2
+
+</Stream>
+
+<Stream test_small.jpg>
+
+Feed feed1.ffm
+Format jpeg
+Strict -1
+
+BitExact
+DctFastint
+IdctSimple
+VideoFrameRate 1
+VideoSize 160x128
+NoAudio
+
+PreRoll 2
+
+</Stream>
+
+<Stream test.mjpg>
+
+Feed feed1.ffm
+Format mpjpeg
+Strict -1
+
+BitExact
+DctFastint
+IdctSimple
+VideoFrameRate 1
+VideoSize    320x240
+NoAudio
+StartSendOnKey
+
+PreRoll 1
+MaxTime 100
+
+</Stream>
+
+
+##################################################################
+# Special stream : server status
+
+<Stream teststat.html>
+
+Format status
+
+</Stream>
+
diff --git a/tests/ffserver.regression.ref b/tests/ffserver.regression.ref
new file mode 100644
index 0000000..9fc7497
--- /dev/null
+++ b/tests/ffserver.regression.ref
@@ -0,0 +1,10 @@
+18c4ba0e8e7adb781216e38de61c2e39  ff-test_h.avi
+f84767c7af61f360f4b443c2c73f322f  ff-test_l.avi
+d976848a9e4d5d8fc2659e4841cdece5  ff-test.swf
+28fd87d5075b9b011aad57292f271a04  ff-test_h.asf
+a31ccd3aba2551e60b9fb1c156fca2f8  ff-test_l.asf
+3279d3ed0ef2d1347b5eda84db2cf3e6  ff-test_h.rm
+440231fe3cf0849887390b4d67d6894a  ff-test_l.rm
+e0dc91430660c619e97b5c82e0f398fc  ff-test.jpg
+0d6c98fc8a4f00560fe34e94e26880a9  ff-test_small.jpg
+e2a315d7ac0576279f8b4d917999615a  ff-test.mjpg
diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh
index a198306..4a348f5 100755
--- a/tests/lavf-regression.sh
+++ b/tests/lavf-regression.sh
@@ -11,6 +11,16 @@
 
 eval do_$test=y
 
+ENC_OPTS="$ENC_OPTS -metadata title=lavftest"
+
+do_lavf_fate()
+{
+    file=${outfile}lavf.$1
+    input="${samples}/$2"
+    do_avconv $file $DEC_OPTS -i "$input" $ENC_OPTS -vcodec copy -acodec copy
+    do_avconv_crc $file $DEC_OPTS -i $target_path/$file $3
+}
+
 do_lavf()
 {
     file=${outfile}lavf.$1
@@ -18,6 +28,16 @@
     do_avconv_crc $file $DEC_OPTS -i $target_path/$file $4
 }
 
+do_lavf_timecode_nodrop() { do_lavf $1 "" "$2 -timecode 02:56:14:13"; }
+do_lavf_timecode_drop()   { do_lavf $1 "" "$2 -timecode 02:56:14.13 -r 30000/1001"; }
+
+do_lavf_timecode()
+{
+    do_lavf_timecode_nodrop "$@"
+    do_lavf_timecode_drop "$@"
+    do_lavf $1 "" "$2"
+}
+
 do_streamed_images()
 {
     file=${outfile}${1}pipe.$1
@@ -30,9 +50,9 @@
     outfile="$datadir/images/$1/"
     mkdir -p "$outfile"
     file=${outfile}%02d.$1
-    run_avconv $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $2 $ENC_OPTS $3 -t 0.5 -y -qscale 10 $target_path/$file
+    run_avconv $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $2 $ENC_OPTS -t 0.5 -y -qscale 10 $target_path/$file
     do_md5sum ${outfile}02.$1
-    do_avconv_crc $file $DEC_OPTS $3 -i $target_path/$file
+    do_avconv_crc $file $DEC_OPTS -i $target_path/$file $3
     echo $(wc -c ${outfile}02.$1)
 }
 
@@ -44,26 +64,26 @@
 }
 
 if [ -n "$do_avi" ] ; then
-do_lavf avi "" "-acodec mp2"
+do_lavf avi "" "-acodec mp2 -ab 64k"
 fi
 
 if [ -n "$do_asf" ] ; then
-do_lavf asf "" "-acodec mp2" "-r 25"
+do_lavf asf "" "-acodec mp2 -ab 64k" "-r 25"
 fi
 
 if [ -n "$do_rm" ] ; then
 file=${outfile}lavf.rm
-do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le -i $pcm_src $ENC_OPTS -t 1 -qscale 10 -acodec ac3_fixed -b:a 64k
+do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $DEC_OPTS -ar 44100 -f s16le -i $pcm_src $ENC_OPTS -t 1 -qscale 10 -acodec ac3_fixed -ab 64k
 # broken
 #do_avconv_crc $file -i $target_path/$file
 fi
 
 if [ -n "$do_mpg" ] ; then
-do_lavf mpg
+do_lavf_timecode mpg "-ab 64k"
 fi
 
 if [ -n "$do_mxf" ] ; then
-do_lavf mxf "-ar 48000" "-bf 2 -timecode_frame_start 264363"
+do_lavf_timecode mxf "-ar 48000 -bf 2"
 fi
 
 if [ -n "$do_mxf_d10" ]; then
@@ -71,7 +91,7 @@
 fi
 
 if [ -n "$do_ts" ] ; then
-do_lavf ts "" "-mpegts_transport_stream_id 42"
+do_lavf ts "" "-ab 64k -mpegts_transport_stream_id 42"
 fi
 
 if [ -n "$do_swf" ] ; then
@@ -79,7 +99,7 @@
 fi
 
 if [ -n "$do_ffm" ] ; then
-do_lavf ffm
+do_lavf ffm "-ab 64k"
 fi
 
 if [ -n "$do_flv_fmt" ] ; then
@@ -87,23 +107,51 @@
 fi
 
 if [ -n "$do_mov" ] ; then
-do_lavf mov "" "-acodec pcm_alaw -c:v mpeg4"
+mov_common_opt="-acodec pcm_alaw -vcodec mpeg4"
+do_lavf mov "" "-movflags +rtphint $mov_common_opt"
+do_lavf_timecode mov "-movflags +faststart $mov_common_opt"
+fi
+
+if [ -n "$do_ismv" ] ; then
+do_lavf_timecode ismv "-an -vcodec mpeg4"
 fi
 
 if [ -n "$do_dv_fmt" ] ; then
+do_lavf_timecode_nodrop dv "-ar 48000 -r 25 -s pal -ac 2"
+do_lavf_timecode_drop   dv "-ar 48000 -pix_fmt yuv411p -s ntsc -ac 2"
 do_lavf dv "-ar 48000 -channel_layout stereo" "-r 25 -s pal"
 fi
 
 if [ -n "$do_gxf" ] ; then
+do_lavf_timecode_nodrop gxf "-ar 48000 -r 25 -s pal -ac 1"
+do_lavf_timecode_drop   gxf "-ar 48000 -s ntsc -ac 1"
 do_lavf gxf "-ar 48000" "-r 25 -s pal -ac 1"
 fi
 
 if [ -n "$do_nut" ] ; then
-do_lavf nut "" "-acodec mp2"
+do_lavf nut "" "-acodec mp2 -ab 64k"
 fi
 
 if [ -n "$do_mkv" ] ; then
-do_lavf mkv "" "-c:a mp2 -c:v mpeg4"
+do_lavf mkv "" "-acodec mp2 -ab 64k -vcodec mpeg4"
+fi
+
+if [ -n "$do_mp3" ] ; then
+do_lavf_fate mp3 "mp3-conformance/he_32khz.bit" "-acodec copy"
+fi
+
+if [ -n "$do_latm" ] ; then
+do_lavf_fate latm "aac/al04_44.mp4" "-acodec copy"
+fi
+
+if [ -n "$do_ogg_vp3" ] ; then
+# -idct simple causes different results on different systems
+DEC_OPTS="$DEC_OPTS -idct auto"
+do_lavf_fate ogg "vp3/coeff_level64.mkv"
+fi
+
+if [ -n "$do_wtv" ] ; then
+do_lavf wtv "" "-acodec mp2"
 fi
 
 
@@ -126,9 +174,18 @@
 fi
 
 if [ -n "$do_gif" ] ; then
+# this tests the gif muxer
 file=${outfile}lavf.gif
 do_avconv $file $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src $ENC_OPTS -t 1 -qscale 10 -pix_fmt rgb24
 do_avconv_crc $file $DEC_OPTS -i $target_path/$file -pix_fmt rgb24
+# and this the gif encoder
+do_image_formats gif "" "-pix_fmt rgb24"
+do_image_formats gif "-pix_fmt rgb4_byte" "-pix_fmt rgb24"
+do_image_formats gif "-pix_fmt bgr4_byte" "-pix_fmt rgb24"
+do_image_formats gif "-pix_fmt rgb8" "-pix_fmt rgb24"
+do_image_formats gif "-pix_fmt bgr8" "-pix_fmt rgb24"
+do_image_formats gif "-pix_fmt gray" "-pix_fmt rgb24"
+do_image_formats gif "-pix_fmt pal8" "-pix_fmt rgb24"
 fi
 
 if [ -n "$do_yuv4mpeg" ] ; then
@@ -149,6 +206,12 @@
 
 if [ -n "$do_png" ] ; then
 do_image_formats png
+do_image_formats png "-pix_fmt gray16be"
+do_image_formats png "-pix_fmt rgb48be"
+fi
+
+if [ -n "$do_xbm" ] ; then
+do_image_formats xbm
 fi
 
 if [ -n "$do_bmp" ] ; then
@@ -168,7 +231,7 @@
 fi
 
 if [ -n "$do_jpg" ] ; then
-do_image_formats jpg "-pix_fmt yuvj420p" "-f image2"
+do_image_formats jpg "-pix_fmt yuvj420p"
 fi
 
 if [ -n "$do_pam" ] ; then
@@ -179,12 +242,14 @@
 do_image_formats pcx
 fi
 
-if [ -n "$do_xwd" ] ; then
-do_image_formats xwd
-fi
-
 if [ -n "$do_dpx" ] ; then
 do_image_formats dpx
+do_image_formats dpx "-pix_fmt rgb48le"
+do_image_formats dpx "-pix_fmt rgb48le -bits_per_raw_sample 10" "-pix_fmt rgb48le"
+fi
+
+if [ -n "$do_xwd" ] ; then
+do_image_formats xwd
 fi
 
 if [ -n "$do_sunrast" ] ; then
@@ -218,7 +283,7 @@
 fi
 
 if [ -n "$do_voc" ] ; then
-do_audio_only voc
+do_audio_only voc "" "-acodec pcm_u8"
 fi
 
 if [ -n "$do_voc_s16" ] ; then
@@ -237,6 +302,10 @@
 do_audio_only sox
 fi
 
+if [ -n "$do_caf" ] ; then
+do_audio_only caf
+fi
+
 # pix_fmt conversions
 
 if [ -n "$do_pixfmt" ] ; then
diff --git a/tests/lavfi-regression.sh b/tests/lavfi-regression.sh
index a315e72..a25b54b 100755
--- a/tests/lavfi-regression.sh
+++ b/tests/lavfi-regression.sh
@@ -13,51 +13,98 @@
 
 do_video_filter() {
     label=$1
-    filters=$2
+    filters="$2"
     shift 2
     printf '%-20s' $label
     run_avconv $DEC_OPTS -f image2 -vcodec pgmyuv -i $raw_src    \
         $ENC_OPTS -vf "$filters" -vcodec rawvideo $* -f nut md5:
 }
 
-do_lavfi() {
-    vfilters="slicify=random,$2"
+do_lavfi_plain() {
+    vfilters="$2"
 
     if [ $test = $1 ] ; then
         do_video_filter $test "$vfilters"
     fi
 }
 
+do_lavfi() {
+    do_lavfi_plain $1 "slicify=random,$2"
+}
+
+do_lavfi_colormatrix() {
+    do_lavfi "${1}1" "$1=$4:$5,$1=$5:$3,$1=$3:$4,$1=$4:$3,$1=$3:$5,$1=$5:$2"
+    do_lavfi "${1}2" "$1=$2:$3,$1=$3:$2,$1=$2:$4,$1=$4:$2,$1=$2:$5,$1=$5:$4"
+}
+
 do_lavfi "crop"               "crop=iw-100:ih-100:100:100"
 do_lavfi "crop_scale"         "crop=iw-100:ih-100:100:100,scale=400:-1"
 do_lavfi "crop_scale_vflip"   "null,null,crop=iw-200:ih-200:200:200,crop=iw-20:ih-20:20:20,scale=200:200,scale=250:250,vflip,vflip,null,scale=200:200,crop=iw-100:ih-100:100:100,vflip,scale=200:200,null,vflip,crop=iw-100:ih-100:100:100,null"
 do_lavfi "crop_vflip"         "crop=iw-100:ih-100:100:100,vflip"
+do_lavfi "drawbox"            "drawbox=224:24:88:72:#FF8010@0.5"
+do_lavfi "edgedetect"         "edgedetect"
+do_lavfi "fade"               "fade=in:5:15,fade=out:30:15"
+do_lavfi "idet"               "idet"
 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 "scale200"           "scale=200:200"
 do_lavfi "scale500"           "scale=500:500"
+do_lavfi "select"             "select=not(eq(mod(n\,2)\,0)+eq(mod(n\,3)\,0))"
+do_lavfi "setdar"             "setdar=16/9"
+do_lavfi "setsar"             "setsar=16/11"
+do_lavfi "thumbnail"          "thumbnail=10"
+do_lavfi "tile"               "tile=3x3"
+do_lavfi "transpose"          "transpose"
+do_lavfi "unsharp"            "unsharp=10:10:-1.5:10:10:-1.5"
 do_lavfi "vflip"              "vflip"
 do_lavfi "vflip_crop"         "vflip,crop=iw-100:ih-100:100:100"
 do_lavfi "vflip_vflip"        "vflip,vflip"
 
+do_lavfi_plain "alphamerge_rgb"     "[in]slicify=random,format=bgra,split,alphamerge[out]"
+do_lavfi_plain "alphamerge_yuv"     "[in]slicify=random,format=yuv420p,split,alphamerge[out]"
+do_lavfi_plain "alphaextract_rgb"   "[in]slicify=random,format=bgra,split,alphamerge,slicify=random,split[o3][o4];[o4]alphaextract[alpha];[o3][alpha]alphamerge[out]"
+do_lavfi_plain "alphaextract_yuv"   "[in]slicify=random,format=yuv420p,split,alphamerge,slicify=random,split[o3][o4];[o4]alphaextract[alpha];[o3][alpha]alphamerge[out]"
+
+do_lavfi_colormatrix "colormatrix" bt709 fcc bt601 smpte240m
+
 do_lavfi_pixfmts(){
-    test ${test%_[bl]e} = pixfmts_$1 || return 0
+    # if there are three parameters, the first param is the test name
+    if [ -n "$3" ]; then
+        testname=$1;
+        shift;
+    else
+        testname=pixfmts_$1;
+    fi
+    test ${test%_[bl]e} = $testname || return 0
     filter=$1
     filter_args=$2
 
     showfiltfmts="$target_exec $target_path/libavfilter/filtfmts-test"
-    exclude_fmts=${outfile}${1}_exclude_fmts
-    out_fmts=${outfile}${1}_out_fmts
+    scale_exclude_fmts=${outfile}${testname}_scale_exclude_fmts
+    scale_in_fmts=${outfile}${testname}_scale_in_fmts
+    scale_out_fmts=${outfile}${testname}_scale_out_fmts
+    in_fmts=${outfile}${testname}_in_fmts
 
     # exclude pixel formats which are not supported as input
-    $avconv -pix_fmts list 2>/dev/null | sed -ne '9,$p' | grep '^\..\.' | cut -d' ' -f2 | sort >$exclude_fmts
-    $showfiltfmts scale | awk -F '[ \r]' '/^OUTPUT/{ print $3 }' | sort | comm -23 - $exclude_fmts >$out_fmts
+    $showfiltfmts scale | awk -F '[ \r]' '/^INPUT/{ fmt=substr($3, 5); print fmt }' | sort >$scale_in_fmts
+    $showfiltfmts scale | awk -F '[ \r]' '/^OUTPUT/{ fmt=substr($3, 5); print fmt }' | sort >$scale_out_fmts
+    comm -12 $scale_in_fmts $scale_out_fmts >$scale_exclude_fmts
 
-    pix_fmts=$($showfiltfmts $filter | awk -F '[ \r]' '/^INPUT/{ print $3 }' | sort | comm -12 - $out_fmts)
+    $showfiltfmts $filter | awk -F '[ \r]' '/^INPUT/{ fmt=substr($3, 5); print fmt }' | sort >$in_fmts
+    pix_fmts=$(comm -12 $scale_exclude_fmts $in_fmts)
+
     for pix_fmt in $pix_fmts; do
         do_video_filter $pix_fmt "slicify=random,format=$pix_fmt,$filter=$filter_args" -pix_fmt $pix_fmt
     done
 
-    rm $exclude_fmts $out_fmts
+    rm $in_fmts $scale_in_fmts $scale_out_fmts $scale_exclude_fmts
 }
 
 # all these filters have exactly one input and exactly one output
@@ -66,15 +113,25 @@
 do_lavfi_pixfmts "hflip"   ""
 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"   ""
 
-if [ -n "$do_pixdesc" ]; then
-    pix_fmts="$($avconv -pix_fmts list 2>/dev/null | sed -ne '9,$p' | grep '^IO' | cut -d' ' -f2 | sort)"
-    for pix_fmt in $pix_fmts; do
-        do_video_filter $pix_fmt "slicify=random,format=$pix_fmt,pixdesctest" -pix_fmt $pix_fmt
-    done
-fi
+do_lavfi_lavd() {
+    label=$1
+    graph=$2
+    shift 2
+    [ $test = $label ] || return 0
+    printf '%-20s' $label
+    run_avconv $DEC_OPTS -f lavfi -i $graph \
+        $ENC_OPTS -vcodec rawvideo $* -f nut md5:
+}
+
+do_lavfi_lavd "life"                 "life=s=40x40:r=5:seed=42:mold=64" -t 2
+do_lavfi_lavd "testsrc"              "testsrc=r=7:n=2:d=10"
 
 # TODO: add tests for
 # direct rendering,
diff --git a/tests/md5.sh b/tests/md5.sh
index 4b95127..e21e5c3 100644
--- a/tests/md5.sh
+++ b/tests/md5.sh
@@ -5,7 +5,7 @@
 elif [ X"$(echo | command md5 2> /dev/null)" != X ]; then
     do_md5sum() { command md5 $1 | sed 's#MD5 (\(.*\)) = \(.*\)#\2 *\1#'; }
 elif [ -x /sbin/md5 ]; then
-    do_md5sum() { /sbin/md5 -r $1 | sed 's# \**\./# *./#'; }
+    do_md5sum() { /sbin/md5 -r $1 | sed 's/\([0-9a-f]\) [ *]*/\1 */'; }
 elif openssl version >/dev/null 2>&1; then
     do_md5sum() { openssl md5 $1 | sed 's/MD5(\(.*\))= \(.*\)/\2 *\1/'; }
 else
diff --git a/tests/ref/fate/4xm-1 b/tests/ref/fate/4xm-1
index d38a47a..37371aa 100644
--- a/tests/ref/fate/4xm-1
+++ b/tests/ref/fate/4xm-1
@@ -1,16 +1,16 @@
 #tb 0: 1/15
-0,          0,          0,        1,   921600, 0xd08f97c7
-0,          1,          1,        1,   921600, 0xc433a85b
-0,          2,          2,        1,   921600, 0x7ffeee42
-0,          3,          3,        1,   921600, 0xc0ad9f52
-0,          4,          4,        1,   921600, 0xb0235112
-0,          5,          5,        1,   921600, 0xcbdd9805
-0,          6,          6,        1,   921600, 0x5468bdb9
-0,          7,          7,        1,   921600, 0x2f0c63fd
-0,          8,          8,        1,   921600, 0xf1de04f0
-0,          9,          9,        1,   921600, 0x95709ce2
-0,         10,         10,        1,   921600, 0x69037c4a
-0,         11,         11,        1,   921600, 0x513f8a98
-0,         12,         12,        1,   921600, 0x55b82fa1
-0,         13,         13,        1,   921600, 0x5c8ace28
-0,         14,         14,        1,   921600, 0xb019770a
+0,          0,          0,        1,   921600, 0xd82e4d57
+0,          1,          1,        1,   921600, 0x83f2349c
+0,          2,          2,        1,   921600, 0x70d87db0
+0,          3,          3,        1,   921600, 0x66d27b93
+0,          4,          4,        1,   921600, 0xb730941c
+0,          5,          5,        1,   921600, 0x15da4934
+0,          6,          6,        1,   921600, 0x1953968a
+0,          7,          7,        1,   921600, 0xf0d730a0
+0,          8,          8,        1,   921600, 0x35a7d30c
+0,          9,          9,        1,   921600, 0x33667f62
+0,         10,         10,        1,   921600, 0xf4707f6b
+0,         11,         11,        1,   921600, 0xaac6c392
+0,         12,         12,        1,   921600, 0x68397d16
+0,         13,         13,        1,   921600, 0xb2aa0450
+0,         14,         14,        1,   921600, 0xba25c62e
diff --git a/tests/ref/fate/4xm-2 b/tests/ref/fate/4xm-2
index 35b0797..cf71357 100644
--- a/tests/ref/fate/4xm-2
+++ b/tests/ref/fate/4xm-2
@@ -6,153 +6,153 @@
 0,          4,          4,        1,    80640, 0x3a942680
 0,          5,          5,        1,    80640, 0x3a942680
 0,          6,          6,        1,    80640, 0x3a942680
-0,          7,          7,        1,    80640, 0x1956ebfc
-0,          8,          8,        1,    80640, 0x61686290
-0,          9,          9,        1,    80640, 0x7e2c2753
-0,         10,         10,        1,    80640, 0x63e5e14f
-0,         11,         11,        1,    80640, 0xa775947a
-0,         12,         12,        1,    80640, 0x4b91b93d
-0,         13,         13,        1,    80640, 0x83345f32
-0,         14,         14,        1,    80640, 0x5d3a3374
-0,         15,         15,        1,    80640, 0x164808c5
-0,         16,         16,        1,    80640, 0xfd0189af
-0,         17,         17,        1,    80640, 0x062f9389
-0,         18,         18,        1,    80640, 0xe4dcaff8
-0,         19,         19,        1,    80640, 0xb2d9ec51
-0,         20,         20,        1,    80640, 0x3b4d5331
-0,         21,         21,        1,    80640, 0xfcbd8da1
-0,         22,         22,        1,    80640, 0xa0732142
-0,         23,         23,        1,    80640, 0x6438df5f
-0,         24,         24,        1,    80640, 0x614302fa
-0,         25,         25,        1,    80640, 0x53edf986
-0,         26,         26,        1,    80640, 0x6dfe13f0
-0,         27,         27,        1,    80640, 0x0b2194c3
-0,         28,         28,        1,    80640, 0xe0436945
-0,         29,         29,        1,    80640, 0x8d8ba77f
-0,         30,         30,        1,    80640, 0x9c723388
-0,         31,         31,        1,    80640, 0x336bd2a2
-0,         32,         32,        1,    80640, 0x5905fd0b
-0,         33,         33,        1,    80640, 0x2ca368bb
-0,         34,         34,        1,    80640, 0x38c1e5ec
-0,         35,         35,        1,    80640, 0xe439a194
-0,         36,         36,        1,    80640, 0xe7a19a64
-0,         37,         37,        1,    80640, 0xbe7f9094
-0,         38,         38,        1,    80640, 0x0b2cbec9
-0,         39,         39,        1,    80640, 0x8050bf7d
-0,         40,         40,        1,    80640, 0x4e9d4e78
-0,         41,         41,        1,    80640, 0xaa7bb85d
-0,         42,         42,        1,    80640, 0x6e42b1a6
-0,         43,         43,        1,    80640, 0x27043fe0
-0,         44,         44,        1,    80640, 0xe04bd5e6
-0,         45,         45,        1,    80640, 0xd60762d6
-0,         46,         46,        1,    80640, 0x2729df8f
-0,         47,         47,        1,    80640, 0x1b62c4f7
-0,         48,         48,        1,    80640, 0xe6b5d2f7
-0,         49,         49,        1,    80640, 0xf5885096
-0,         50,         50,        1,    80640, 0xe7625cf6
-0,         51,         51,        1,    80640, 0xed804de6
-0,         52,         52,        1,    80640, 0x3f92728e
-0,         53,         53,        1,    80640, 0x353e4b0d
-0,         54,         54,        1,    80640, 0x70b0228c
-0,         55,         55,        1,    80640, 0x851bd554
-0,         56,         56,        1,    80640, 0x594f22eb
-0,         57,         57,        1,    80640, 0xa2267c0b
-0,         58,         58,        1,    80640, 0xdc0fbafb
-0,         59,         59,        1,    80640, 0xd596b763
-0,         60,         60,        1,    80640, 0x3b9c4b1b
-0,         61,         61,        1,    80640, 0x218ac4b4
-0,         62,         62,        1,    80640, 0x4af393a4
-0,         63,         63,        1,    80640, 0x66c098c5
-0,         64,         64,        1,    80640, 0x7cc91e86
-0,         65,         65,        1,    80640, 0xba282a2e
-0,         66,         66,        1,    80640, 0x50932be6
-0,         67,         67,        1,    80640, 0x6531386e
-0,         68,         68,        1,    80640, 0x2616235f
-0,         69,         69,        1,    80640, 0x27aad18a
-0,         70,         70,        1,    80640, 0x67491df3
-0,         71,         71,        1,    80640, 0x167028f1
-0,         72,         72,        1,    80640, 0xa4229420
-0,         73,         73,        1,    80640, 0x77eaed07
-0,         74,         74,        1,    80640, 0xbdf7d8e8
-0,         75,         75,        1,    80640, 0xc2ac8545
-0,         76,         76,        1,    80640, 0xf3fe64ec
-0,         77,         77,        1,    80640, 0x66451d43
-0,         78,         78,        1,    80640, 0x1af2f05e
-0,         79,         79,        1,    80640, 0x2a63c2c4
-0,         80,         80,        1,    80640, 0xe4e07a0f
-0,         81,         81,        1,    80640, 0x598e8b11
-0,         82,         82,        1,    80640, 0xb2ebb868
-0,         83,         83,        1,    80640, 0xa4b6bb8a
-0,         84,         84,        1,    80640, 0x5037e910
-0,         85,         85,        1,    80640, 0x0c55f6c0
-0,         86,         86,        1,    80640, 0x3f4704f7
-0,         87,         87,        1,    80640, 0xa6a8e810
-0,         88,         88,        1,    80640, 0xedbfcfb0
-0,         89,         89,        1,    80640, 0xe568caa0
-0,         90,         90,        1,    80640, 0xdf21cc20
-0,         91,         91,        1,    80640, 0xb66cd4a8
-0,         92,         92,        1,    80640, 0xcd26c9c8
-0,         93,         93,        1,    80640, 0x5fe8d598
-0,         94,         94,        1,    80640, 0xed0dc9c8
-0,         95,         95,        1,    80640, 0x8313d288
-0,         96,         96,        1,    80640, 0x9ccdd4a0
-0,         97,         97,        1,    80640, 0x66ffe970
-0,         98,         98,        1,    80640, 0xf68ad1c8
-0,         99,         99,        1,    80640, 0xd570f658
-0,        100,        100,        1,    80640, 0x8c39d998
-0,        101,        101,        1,    80640, 0xe18fe5e0
-0,        102,        102,        1,    80640, 0xbbe7e340
-0,        103,        103,        1,    80640, 0x9a90d470
-0,        104,        104,        1,    80640, 0xd2bbced0
-0,        105,        105,        1,    80640, 0xbbf9dce0
-0,        106,        106,        1,    80640, 0x4ff7c888
-0,        107,        107,        1,    80640, 0xc2e7e1f0
-0,        108,        108,        1,    80640, 0x2104e3b0
-0,        109,        109,        1,    80640, 0xaef5e8f0
-0,        110,        110,        1,    80640, 0xc477e890
-0,        111,        111,        1,    80640, 0xb12df778
-0,        112,        112,        1,    80640, 0xd2115720
-0,        113,        113,        1,    80640, 0x620b6538
-0,        114,        114,        1,    80640, 0x894a8db8
-0,        115,        115,        1,    80640, 0x8da3bcb0
-0,        116,        116,        1,    80640, 0x96be8930
-0,        117,        117,        1,    80640, 0xe69dc1f0
-0,        118,        118,        1,    80640, 0x42b8d4e0
-0,        119,        119,        1,    80640, 0x0a8da4f0
-0,        120,        120,        1,    80640, 0x245fd3d8
-0,        121,        121,        1,    80640, 0x3fd1e858
-0,        122,        122,        1,    80640, 0xe2c299f0
-0,        123,        123,        1,    80640, 0xda1cddd0
-0,        124,        124,        1,    80640, 0xf126e498
-0,        125,        125,        1,    80640, 0xc85ab920
-0,        126,        126,        1,    80640, 0x52f39de8
-0,        127,        127,        1,    80640, 0xd0daac60
-0,        128,        128,        1,    80640, 0xef323347
-0,        129,        129,        1,    80640, 0xcc063317
-0,        130,        130,        1,    80640, 0xb6f53057
-0,        131,        131,        1,    80640, 0x5fe53b07
-0,        132,        132,        1,    80640, 0x63183d7f
-0,        133,        133,        1,    80640, 0x91a44bbf
-0,        134,        134,        1,    80640, 0xa433480f
-0,        135,        135,        1,    80640, 0xe90652ef
-0,        136,        136,        1,    80640, 0xe96e35bf
-0,        137,        137,        1,    80640, 0x84ff2ccf
-0,        138,        138,        1,    80640, 0x930f2b07
-0,        139,        139,        1,    80640, 0x5a1228d7
-0,        140,        140,        1,    80640, 0x29f226ef
-0,        141,        141,        1,    80640, 0xd35136df
-0,        142,        142,        1,    80640, 0x0e2d407f
-0,        143,        143,        1,    80640, 0x34a93267
-0,        144,        144,        1,    80640, 0x7ae82af7
-0,        145,        145,        1,    80640, 0xb20c2477
-0,        146,        146,        1,    80640, 0xa104218f
-0,        147,        147,        1,    80640, 0xcb1121e7
-0,        148,        148,        1,    80640, 0xaca04751
-0,        149,        149,        1,    80640, 0x3a51c704
-0,        150,        150,        1,    80640, 0xfa632e3d
-0,        151,        151,        1,    80640, 0x61c9407c
-0,        152,        152,        1,    80640, 0xe9a08dd9
-0,        153,        153,        1,    80640, 0xebf3c623
+0,          7,          7,        1,    80640, 0xa731901a
+0,          8,          8,        1,    80640, 0x0a1e5b3d
+0,          9,          9,        1,    80640, 0x2c66418f
+0,         10,         10,        1,    80640, 0xaaf8575a
+0,         11,         11,        1,    80640, 0x2d1a60b1
+0,         12,         12,        1,    80640, 0x646d6e66
+0,         13,         13,        1,    80640, 0x090de107
+0,         14,         14,        1,    80640, 0x90991f6c
+0,         15,         15,        1,    80640, 0xda862969
+0,         16,         16,        1,    80640, 0x5434e1ec
+0,         17,         17,        1,    80640, 0x4e981ce7
+0,         18,         18,        1,    80640, 0x97eb4000
+0,         19,         19,        1,    80640, 0xbfb375b0
+0,         20,         20,        1,    80640, 0x1529d95d
+0,         21,         21,        1,    80640, 0x2c0015af
+0,         22,         22,        1,    80640, 0x63779ce1
+0,         23,         23,        1,    80640, 0x3f2b3949
+0,         24,         24,        1,    80640, 0xe3cf3be4
+0,         25,         25,        1,    80640, 0x54451a22
+0,         26,         26,        1,    80640, 0xc2901d91
+0,         27,         27,        1,    80640, 0x312f8b7e
+0,         28,         28,        1,    80640, 0x99734f4e
+0,         29,         29,        1,    80640, 0xe50b8391
+0,         30,         30,        1,    80640, 0x7c6b04e4
+0,         31,         31,        1,    80640, 0x04989996
+0,         32,         32,        1,    80640, 0x30c3c00f
+0,         33,         33,        1,    80640, 0x77172ba4
+0,         34,         34,        1,    80640, 0x1257a596
+0,         35,         35,        1,    80640, 0x657e5fa8
+0,         36,         36,        1,    80640, 0xe66958ef
+0,         37,         37,        1,    80640, 0xbf7f4f0a
+0,         38,         38,        1,    80640, 0x588ac70e
+0,         39,         39,        1,    80640, 0xb1a91c4b
+0,         40,         40,        1,    80640, 0x5b73de24
+0,         41,         41,        1,    80640, 0xa3c15e73
+0,         42,         42,        1,    80640, 0x7326196b
+0,         43,         43,        1,    80640, 0x1aa52b88
+0,         44,         44,        1,    80640, 0x0029f511
+0,         45,         45,        1,    80640, 0x2398433a
+0,         46,         46,        1,    80640, 0xef9ab870
+0,         47,         47,        1,    80640, 0xb1ac9b79
+0,         48,         48,        1,    80640, 0x1cc2ab3b
+0,         49,         49,        1,    80640, 0x41362b53
+0,         50,         50,        1,    80640, 0x81e33811
+0,         51,         51,        1,    80640, 0x621d285a
+0,         52,         52,        1,    80640, 0x84e84c24
+0,         53,         53,        1,    80640, 0xbb8c2939
+0,         54,         54,        1,    80640, 0x6c6905a8
+0,         55,         55,        1,    80640, 0xc60bbaf0
+0,         56,         56,        1,    80640, 0xc80d08c8
+0,         57,         57,        1,    80640, 0xc5646343
+0,         58,         58,        1,    80640, 0x3df7a287
+0,         59,         59,        1,    80640, 0x628e9f78
+0,         60,         60,        1,    80640, 0x58f93044
+0,         61,         61,        1,    80640, 0x8ee3a59f
+0,         62,         62,        1,    80640, 0xaa297416
+0,         63,         63,        1,    80640, 0x7bbd7307
+0,         64,         64,        1,    80640, 0x12dbee42
+0,         65,         65,        1,    80640, 0xaea5fb22
+0,         66,         66,        1,    80640, 0x9405fd0b
+0,         67,         67,        1,    80640, 0x59400b6f
+0,         68,         68,        1,    80640, 0x70beeba0
+0,         69,         69,        1,    80640, 0xdc0681ae
+0,         70,         70,        1,    80640, 0xe4a3c803
+0,         71,         71,        1,    80640, 0x3424c568
+0,         72,         72,        1,    80640, 0xeb72838d
+0,         73,         73,        1,    80640, 0x671fbff3
+0,         74,         74,        1,    80640, 0xa4b849bd
+0,         75,         75,        1,    80640, 0xf4c2be6f
+0,         76,         76,        1,    80640, 0xb91988fd
+0,         77,         77,        1,    80640, 0xd0e5bf3a
+0,         78,         78,        1,    80640, 0x78c2b0bc
+0,         79,         79,        1,    80640, 0xcf2deb74
+0,         80,         80,        1,    80640, 0x84a9081b
+0,         81,         81,        1,    80640, 0x9931e9b1
+0,         82,         82,        1,    80640, 0x1ce6b59d
+0,         83,         83,        1,    80640, 0x24a31152
+0,         84,         84,        1,    80640, 0x206f4677
+0,         85,         85,        1,    80640, 0x507755ab
+0,         86,         86,        1,    80640, 0xc4b5643a
+0,         87,         87,        1,    80640, 0x197445f7
+0,         88,         88,        1,    80640, 0x53232d2a
+0,         89,         89,        1,    80640, 0x33ae27d4
+0,         90,         90,        1,    80640, 0x77bb2925
+0,         91,         91,        1,    80640, 0xb0d53220
+0,         92,         92,        1,    80640, 0xacdb26fc
+0,         93,         93,        1,    80640, 0xa83d32e1
+0,         94,         94,        1,    80640, 0xe2002717
+0,         95,         95,        1,    80640, 0xb1722fed
+0,         96,         96,        1,    80640, 0xa7de3206
+0,         97,         97,        1,    80640, 0x68f94780
+0,         98,         98,        1,    80640, 0x2bcc2f28
+0,         99,         99,        1,    80640, 0xaf9354e5
+0,        100,        100,        1,    80640, 0x45b4375c
+0,        101,        101,        1,    80640, 0x60e043ee
+0,        102,        102,        1,    80640, 0x9ed5411e
+0,        103,        103,        1,    80640, 0xbae131ce
+0,        104,        104,        1,    80640, 0x33be2be6
+0,        105,        105,        1,    80640, 0xdadb3a4c
+0,        106,        106,        1,    80640, 0xe9e72559
+0,        107,        107,        1,    80640, 0x9fe93f8c
+0,        108,        108,        1,    80640, 0xc20b413a
+0,        109,        109,        1,    80640, 0x02c74699
+0,        110,        110,        1,    80640, 0x1b284634
+0,        111,        111,        1,    80640, 0xb7ea559e
+0,        112,        112,        1,    80640, 0x62e3b0e1
+0,        113,        113,        1,    80640, 0x8b6bbf68
+0,        114,        114,        1,    80640, 0x04d2e8d8
+0,        115,        115,        1,    80640, 0xc6961955
+0,        116,        116,        1,    80640, 0xf318e461
+0,        117,        117,        1,    80640, 0x55231e8f
+0,        118,        118,        1,    80640, 0x772f325e
+0,        119,        119,        1,    80640, 0x31480120
+0,        120,        120,        1,    80640, 0x5eda30fe
+0,        121,        121,        1,    80640, 0x5c534632
+0,        122,        122,        1,    80640, 0xaca0f5c9
+0,        123,        123,        1,    80640, 0x9ec83b5a
+0,        124,        124,        1,    80640, 0x65944233
+0,        125,        125,        1,    80640, 0xbf7e15f0
+0,        126,        126,        1,    80640, 0xf985f9b7
+0,        127,        127,        1,    80640, 0x0e7a0887
+0,        128,        128,        1,    80640, 0xee33931b
+0,        129,        129,        1,    80640, 0xea6b92f8
+0,        130,        130,        1,    80640, 0xde559025
+0,        131,        131,        1,    80640, 0x970c9af6
+0,        132,        132,        1,    80640, 0x6a579d8a
+0,        133,        133,        1,    80640, 0x7053ac0c
+0,        134,        134,        1,    80640, 0x6d6ca81b
+0,        135,        135,        1,    80640, 0x6ffdb338
+0,        136,        136,        1,    80640, 0x402f953f
+0,        137,        137,        1,    80640, 0x24358c04
+0,        138,        138,        1,    80640, 0x26298a25
+0,        139,        139,        1,    80640, 0xbc0487e7
+0,        140,        140,        1,    80640, 0xf8c885fd
+0,        141,        141,        1,    80640, 0x98a79695
+0,        142,        142,        1,    80640, 0x846aa04b
+0,        143,        143,        1,    80640, 0x22ba919b
+0,        144,        144,        1,    80640, 0xcba08a11
+0,        145,        145,        1,    80640, 0xfba0836c
+0,        146,        146,        1,    80640, 0xb7ff8059
+0,        147,        147,        1,    80640, 0xb15080bb
+0,        148,        148,        1,    80640, 0x42627aed
+0,        149,        149,        1,    80640, 0xd045d485
+0,        150,        150,        1,    80640, 0xf22e7545
+0,        151,        151,        1,    80640, 0xe24a41fc
+0,        152,        152,        1,    80640, 0x854696ac
+0,        153,        153,        1,    80640, 0x6722f8f2
 0,        154,        154,        1,    80640, 0x00000000
 0,        155,        155,        1,    80640, 0x0f412500
 0,        156,        156,        1,    80640, 0x0f412500
@@ -160,16 +160,16 @@
 0,        158,        158,        1,    80640, 0xb6634270
 0,        159,        159,        1,    80640, 0x9e43a4a0
 0,        160,        160,        1,    80640, 0x136ab60b
-0,        161,        161,        1,    80640, 0x6ce3254e
-0,        162,        162,        1,    80640, 0xf4340d15
-0,        163,        163,        1,    80640, 0x73861114
-0,        164,        164,        1,    80640, 0x36b300d3
-0,        165,        165,        1,    80640, 0x2ddde523
-0,        166,        166,        1,    80640, 0xfdd79c02
-0,        167,        167,        1,    80640, 0xe6cc4fe9
-0,        168,        168,        1,    80640, 0x5b13e2b9
-0,        169,        169,        1,    80640, 0x0d588e70
-0,        170,        170,        1,    80640, 0xc6e4023f
-0,        171,        171,        1,    80640, 0xf54c496f
-0,        172,        172,        1,    80640, 0xa315a5cf
-0,        173,        173,        1,    80640, 0x2d2ac9c7
+0,        161,        161,        1,    80640, 0xe43625dc
+0,        162,        162,        1,    80640, 0xc2eb0f8c
+0,        163,        163,        1,    80640, 0x99af167d
+0,        164,        164,        1,    80640, 0xd9cb0a37
+0,        165,        165,        1,    80640, 0x1f2cf2ce
+0,        166,        166,        1,    80640, 0x00eeae7f
+0,        167,        167,        1,    80640, 0xcc1d666c
+0,        168,        168,        1,    80640, 0x77d6fcc9
+0,        169,        169,        1,    80640, 0x58c8acc6
+0,        170,        170,        1,    80640, 0xd026238d
+0,        171,        171,        1,    80640, 0xfefb6c9b
+0,        172,        172,        1,    80640, 0xa9a5cb36
+0,        173,        173,        1,    80640, 0xc845f000
diff --git a/tests/ref/fate/8bps b/tests/ref/fate/8bps
index 869d38c..9db9430 100644
--- a/tests/ref/fate/8bps
+++ b/tests/ref/fate/8bps
@@ -1,36 +1,36 @@
-#tb 0: 1/125
+#tb 0: 2/25
 #tb 1: 1/22050
 0,          0,          0,        1,   259200, 0x7e91df07
 1,          0,          0,     1024,     2048, 0x3d042426
 1,       1024,       1024,     1024,     2048, 0x5bcae456
-0,         10,         10,        1,   259200, 0x7e91df07
+0,          1,          1,        1,   259200, 0x7e91df07
 1,       2048,       2048,     1024,     2048, 0xb6043655
 1,       3072,       3072,     1024,     2048, 0x6fdaffad
-0,         20,         20,        1,   259200, 0xc468c119
+0,          2,          2,        1,   259200, 0xc468c119
 1,       4096,       4096,     1024,     2048, 0xf86700cb
 1,       5120,       5120,     1024,     2048, 0x045e46c1
-0,         30,         30,        1,   259200, 0x0e058930
+0,          3,          3,        1,   259200, 0x0e058930
 1,       6144,       6144,     1024,     2048, 0x000df0e5
-0,         40,         40,        1,   259200, 0xa0261310
+0,          4,          4,        1,   259200, 0xa0261310
 1,       7168,       7168,     1024,     2048, 0x8f5f12fb
 1,       8192,       8192,     1024,     2048, 0xd516f6b0
-0,         50,         50,        1,   259200, 0x78ca9aba
+0,          5,          5,        1,   259200, 0x78ca9aba
 1,       9216,       9216,     1024,     2048, 0xa1fe2bd3
 1,      10240,      10240,     1024,     2048, 0x3647087a
-0,         60,         60,        1,   259200, 0x4971f7b3
+0,          6,          6,        1,   259200, 0x4971f7b3
 1,      11264,      11264,     1024,     2048, 0xd2ee584e
 1,      12288,      12288,     1024,     2048, 0xf132088c
-0,         70,         70,        1,   259200, 0x7dc2cff7
+0,          7,          7,        1,   259200, 0x7dc2cff7
 1,      13312,      13312,     1024,     2048, 0x1efc0eb1
-0,         80,         80,        1,   259200, 0x8cbc53d5
+0,          8,          8,        1,   259200, 0x8cbc53d5
 1,      14336,      14336,     1024,     2048, 0xeb73f402
 1,      15360,      15360,     1024,     2048, 0x75cb3d20
-0,         90,         90,        1,   259200, 0xcccd77e3
+0,          9,          9,        1,   259200, 0xcccd77e3
 1,      16384,      16384,     1024,     2048, 0x85a501b6
 1,      17408,      17408,     1024,     2048, 0xa4eb312d
-0,        100,        100,        1,   259200, 0x6b3e0fb3
+0,         10,         10,        1,   259200, 0x6b3e0fb3
 1,      18432,      18432,     1024,     2048, 0xf0aaf8c7
-0,        110,        110,        1,   259200, 0x281dd175
+0,         11,         11,        1,   259200, 0x281dd175
 1,      19456,      19456,     1024,     2048, 0x65371cda
 1,      20480,      20480,     1024,     2048, 0x25512cd6
 1,      21504,      21504,     1024,     2048, 0xc81410e3
diff --git a/tests/ref/fate/aasc b/tests/ref/fate/aasc
index b991635..83f83b9 100644
--- a/tests/ref/fate/aasc
+++ b/tests/ref/fate/aasc
@@ -1,24 +1,25 @@
 #tb 0: 1/25
-0,          0,          0,        1,   168000, 0x45addf8f
-0,          1,          1,        1,   168000, 0x45addf8f
-0,          2,          2,        1,   168000, 0x45addf8f
-0,          3,          3,        1,   168000, 0x45addf8f
-0,          4,          4,        1,   168000, 0x45addf8f
-0,          5,          5,        1,   168000, 0x45addf8f
-0,          6,          6,        1,   168000, 0x45addf8f
-0,          7,          7,        1,   168000, 0x45addf8f
-0,          8,          8,        1,   168000, 0x45addf8f
-0,          9,          9,        1,   168000, 0x45addf8f
-0,         10,         10,        1,   168000, 0x45addf8f
-0,         11,         11,        1,   168000, 0x45addf8f
-0,         12,         12,        1,   168000, 0x8730699b
-0,         13,         13,        1,   168000, 0x08b095df
-0,         14,         14,        1,   168000, 0x203526e3
-0,         15,         15,        1,   168000, 0x0ebc5142
-0,         16,         16,        1,   168000, 0xd168e7c2
-0,         17,         17,        1,   168000, 0xcc7da0e6
-0,         18,         18,        1,   168000, 0x72ac60b8
-0,         19,         19,        1,   168000, 0xb691e27c
-0,         20,         20,        1,   168000, 0x646fa087
-0,         21,         21,        1,   168000, 0x404450a2
-0,         22,         22,        1,   168000, 0x5214c456
+0,          0,          0,        1,   168000, 0x00000000
+0,          1,          1,        1,   168000, 0x00000000
+0,          2,          2,        1,   168000, 0x00000000
+0,          3,          3,        1,   168000, 0x00000000
+0,          4,          4,        1,   168000, 0x00000000
+0,          5,          5,        1,   168000, 0x00000000
+0,          6,          6,        1,   168000, 0x00000000
+0,          7,          7,        1,   168000, 0x00000000
+0,          8,          8,        1,   168000, 0x00000000
+0,          9,          9,        1,   168000, 0x00000000
+0,         10,         10,        1,   168000, 0x00000000
+0,         11,         11,        1,   168000, 0x00000000
+0,         12,         12,        1,   168000, 0xa6298d46
+0,         13,         13,        1,   168000, 0x5d89d96c
+0,         14,         14,        1,   168000, 0x16d994da
+0,         15,         15,        1,   168000, 0xa8c6079b
+0,         16,         16,        1,   168000, 0xdd1decac
+0,         17,         17,        1,   168000, 0x6a96003c
+0,         18,         18,        1,   168000, 0xef7f1ff4
+0,         19,         19,        1,   168000, 0x90dc0126
+0,         20,         20,        1,   168000, 0x7a2b1006
+0,         21,         21,        1,   168000, 0xc7ca1345
+0,         22,         22,        1,   168000, 0x8841c413
+0,         23,         23,        1,   168000, 0xbaed0290
diff --git a/tests/ref/fate/acodec-adpcm_ima_qt b/tests/ref/fate/acodec-adpcm_ima_qt
new file mode 100644
index 0000000..a50c30a
--- /dev/null
+++ b/tests/ref/fate/acodec-adpcm_ima_qt
@@ -0,0 +1,4 @@
+23cbae1182e150ebf28e0abfb9cba127 *./tests/data/acodec/adpcm_qt.aiff
+281252 ./tests/data/acodec/adpcm_qt.aiff
+b0fafd002c38fb70acaddfda1a31ed61 *./tests/data/adpcm_ima_qt.acodec.out.wav
+stddev:  904.76 PSNR: 37.20 MAXDIFF:34029 bytes:  1058560/  1058400
diff --git a/tests/ref/fate/acodec-alac b/tests/ref/fate/acodec-alac
index bb7a202..d923719 100644
--- a/tests/ref/fate/acodec-alac
+++ b/tests/ref/fate/acodec-alac
@@ -1,4 +1,4 @@
-8ad790d3a0bbda81cd23c15ab8ba760d *tests/data/fate/acodec-alac.mov
-389258 tests/data/fate/acodec-alac.mov
+f01f453dd13c4e88266409cddf2a7177 *tests/data/fate/acodec-alac.mov
+389018 tests/data/fate/acodec-alac.mov
 64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-alac.out.wav
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
diff --git a/tests/ref/fate/acodec-aref b/tests/ref/fate/acodec-aref
new file mode 100644
index 0000000..d70876d
--- /dev/null
+++ b/tests/ref/fate/acodec-aref
@@ -0,0 +1,4 @@
+64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/acodec.ref.wav
+1058446 ./tests/data/acodec.ref.wav
+ce524631c2ad0a40aaab46e3a80a1176 *./tests/data/acodec-16000-1.ref.wav
+192046 ./tests/data/acodec-16000-1.ref.wav
diff --git a/tests/ref/fate/acodec-flac b/tests/ref/fate/acodec-flac
index 3ef32c2..1cc3770 100644
--- a/tests/ref/fate/acodec-flac
+++ b/tests/ref/fate/acodec-flac
@@ -1,4 +1,4 @@
-f582b59cc68adfcb3342dcfd7e020b71 *tests/data/fate/acodec-flac.flac
-361581 tests/data/fate/acodec-flac.flac
+151eef9097f944726968bec48649f00a *tests/data/fate/acodec-flac.flac
+361582 tests/data/fate/acodec-flac.flac
 64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-flac.out.wav
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
diff --git a/tests/ref/fate/acodec-g723_1 b/tests/ref/fate/acodec-g723_1
new file mode 100644
index 0000000..9f88a76
--- /dev/null
+++ b/tests/ref/fate/acodec-g723_1
@@ -0,0 +1,4 @@
+dec0deb2425e908d232d2471acff04a3 *tests/data/fate/acodec-g723_1.g723_1
+4800 tests/data/fate/acodec-g723_1.g723_1
+d70776846d77c652bceed281fcca9cc8 *tests/data/fate/acodec-g723_1.out.wav
+stddev: 8423.47 PSNR: 17.82 MAXDIFF:53292 bytes:    95992/    96000
diff --git a/tests/ref/fate/acodec-pcm-s16be b/tests/ref/fate/acodec-pcm-s16be
index 39c3838..6f7222a 100644
--- a/tests/ref/fate/acodec-pcm-s16be
+++ b/tests/ref/fate/acodec-pcm-s16be
@@ -1,4 +1,4 @@
-009a446579dd4cba793723b5e2b93c39 *tests/data/fate/acodec-pcm-s16be.mov
-1060097 tests/data/fate/acodec-pcm-s16be.mov
+d00ca427a66be2e33ca8d63bcde41316 *tests/data/fate/acodec-pcm-s16be.mov
+1059069 tests/data/fate/acodec-pcm-s16be.mov
 64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s16be.out.wav
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
diff --git a/tests/ref/fate/acodec-pcm-s24be b/tests/ref/fate/acodec-pcm-s24be
index 20bc4e0..3ebe02a 100644
--- a/tests/ref/fate/acodec-pcm-s24be
+++ b/tests/ref/fate/acodec-pcm-s24be
@@ -1,4 +1,4 @@
-de27dae0dff0359d8f39449b17d5607f *tests/data/fate/acodec-pcm-s24be.mov
-1589297 tests/data/fate/acodec-pcm-s24be.mov
+f65a7ae3b70ca53ffa354b1e7ff3a33d *tests/data/fate/acodec-pcm-s24be.mov
+1588323 tests/data/fate/acodec-pcm-s24be.mov
 64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s24be.out.wav
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
diff --git a/tests/ref/fate/acodec-pcm-s32be b/tests/ref/fate/acodec-pcm-s32be
index 302bc1a..9075083 100644
--- a/tests/ref/fate/acodec-pcm-s32be
+++ b/tests/ref/fate/acodec-pcm-s32be
@@ -1,4 +1,4 @@
-2db1e7fe92d4006103691a4b59064dc6 *tests/data/fate/acodec-pcm-s32be.mov
-2118497 tests/data/fate/acodec-pcm-s32be.mov
+f9e16fafeefb2285e943f53133e9cfd5 *tests/data/fate/acodec-pcm-s32be.mov
+2117527 tests/data/fate/acodec-pcm-s32be.mov
 64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s32be.out.wav
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
diff --git a/tests/ref/fate/acodec-pcm-s8 b/tests/ref/fate/acodec-pcm-s8
index f830d2f..247c46c 100644
--- a/tests/ref/fate/acodec-pcm-s8
+++ b/tests/ref/fate/acodec-pcm-s8
@@ -1,4 +1,4 @@
-9ee95a7fff38831a1cad3b49c33e6ed9 *tests/data/fate/acodec-pcm-s8.mov
-530897 tests/data/fate/acodec-pcm-s8.mov
+d931dc4fffa2d3398e0f31f97e7d6c3a *tests/data/fate/acodec-pcm-s8.mov
+529853 tests/data/fate/acodec-pcm-s8.mov
 651d4eb8d98dfcdda96ae6c43d8f156b *tests/data/fate/acodec-pcm-s8.out.wav
 stddev:  147.89 PSNR: 52.93 MAXDIFF:  255 bytes:  1058400/  1058400
diff --git a/tests/ref/fate/acodec-roqaudio b/tests/ref/fate/acodec-roqaudio
new file mode 100644
index 0000000..ec28668
--- /dev/null
+++ b/tests/ref/fate/acodec-roqaudio
@@ -0,0 +1,4 @@
+c8ff13cf7ebece23af76502f5785202e *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
diff --git a/tests/ref/fate/ansi b/tests/ref/fate/ansi
index 56c0226..78e853f 100644
--- a/tests/ref/fate/ansi
+++ b/tests/ref/fate/ansi
@@ -1,7 +1,7 @@
 #tb 0: 1/25
-0,          0,          0,        1,   768000, 0x3032d0de
-0,          1,          1,        1,   768000, 0xc3be5922
-0,          2,          2,        1,   768000, 0xf530c476
+0,          0,          0,        1,   768000, 0x772dd3d0
+0,          1,          1,        1,   768000, 0xd7dab1d1
+0,          2,          2,        1,   768000, 0x0e56f2d3
 0,          3,          3,        1,   768000, 0x11c1fb8e
 0,          4,          4,        1,   768000, 0x72d12da9
 0,          5,          5,        1,   768000, 0x39c7a70d
diff --git a/tests/ref/fate/ansi256 b/tests/ref/fate/ansi256
new file mode 100644
index 0000000..94acd45
--- /dev/null
+++ b/tests/ref/fate/ansi256
@@ -0,0 +1,9 @@
+#tb 0: 1/25
+0,          0,          0,        1,   768000, 0x4dfbb6d0
+0,          1,          1,        1,   768000, 0x22652a22
+0,          2,          2,        1,   768000, 0x6c613e8c
+0,          3,          3,        1,   768000, 0x82471f25
+0,          4,          4,        1,   768000, 0xd8dc5ac6
+0,          5,          5,        1,   768000, 0x1afdc026
+0,          6,          6,        1,   768000, 0x518f3ba1
+0,          7,          7,        1,   768000, 0xa82a8e4b
diff --git a/tests/ref/fate/armovie-escape124 b/tests/ref/fate/armovie-escape124
index c686327..83614c2 100644
--- a/tests/ref/fate/armovie-escape124
+++ b/tests/ref/fate/armovie-escape124
@@ -1,106 +1,106 @@
 #tb 0: 1/25
 #tb 1: 1/44100
-0,          0,          0,        1,   230400, 0x5288d70f
+0,          0,          0,        1,   230400, 0xd133e177
 1,          0,          0,    44100,   176400, 0xdd61578c
-0,          1,          1,        1,   230400, 0x2d3c1066
-0,          2,          2,        1,   230400, 0x89eb5b4a
-0,          3,          3,        1,   230400, 0x24c2d2e7
-0,          4,          4,        1,   230400, 0x9271cb38
-0,          5,          5,        1,   230400, 0xc74a5009
-0,          6,          6,        1,   230400, 0x61d70705
-0,          7,          7,        1,   230400, 0x6bb2c252
-0,          8,          8,        1,   230400, 0x6b3ac910
-0,          9,          9,        1,   230400, 0x44071f28
-0,         10,         10,        1,   230400, 0x8abd00fe
-0,         11,         11,        1,   230400, 0xcbe3395d
-0,         12,         12,        1,   230400, 0x603e7b7a
-0,         13,         13,        1,   230400, 0x2ca8865b
-0,         14,         14,        1,   230400, 0x11b4c665
-0,         15,         15,        1,   230400, 0x3f19787c
-0,         16,         16,        1,   230400, 0x651d24b6
-0,         17,         17,        1,   230400, 0x325d05af
-0,         18,         18,        1,   230400, 0x4f89d8a8
-0,         19,         19,        1,   230400, 0xb07647f0
-0,         20,         20,        1,   230400, 0x71141237
-0,         21,         21,        1,   230400, 0xa848a2d2
-0,         22,         22,        1,   230400, 0x3fbe4b58
-0,         23,         23,        1,   230400, 0xa1e235a0
-0,         24,         24,        1,   230400, 0x9bcf607a
-0,         25,         25,        1,   230400, 0x3302e9eb
+0,          1,          1,        1,   230400, 0xe3501bb2
+0,          2,          2,        1,   230400, 0x44da84f0
+0,          3,          3,        1,   230400, 0xe0fd17ed
+0,          4,          4,        1,   230400, 0xef4e08c7
+0,          5,          5,        1,   230400, 0xf52f82b5
+0,          6,          6,        1,   230400, 0x05eb186c
+0,          7,          7,        1,   230400, 0x0653f05d
+0,          8,          8,        1,   230400, 0xde1a0735
+0,          9,          9,        1,   230400, 0x6045576e
+0,         10,         10,        1,   230400, 0xac9444c4
+0,         11,         11,        1,   230400, 0x5f7f82fb
+0,         12,         12,        1,   230400, 0xaf4718ce
+0,         13,         13,        1,   230400, 0x117d5787
+0,         14,         14,        1,   230400, 0x319ac1f5
+0,         15,         15,        1,   230400, 0xd05cb30a
+0,         16,         16,        1,   230400, 0x96107c72
+0,         17,         17,        1,   230400, 0x73ff0a30
+0,         18,         18,        1,   230400, 0x865d0f3e
+0,         19,         19,        1,   230400, 0x3384ad55
+0,         20,         20,        1,   230400, 0x6694b2ea
+0,         21,         21,        1,   230400, 0x324f5cb8
+0,         22,         22,        1,   230400, 0x2de7c12f
+0,         23,         23,        1,   230400, 0x57fedb1a
+0,         24,         24,        1,   230400, 0xf46f2abf
+0,         25,         25,        1,   230400, 0xe5fead9b
 1,      44100,      44100,    44100,   176400, 0x0b9e6d67
-0,         26,         26,        1,   230400, 0xd731ba90
-0,         27,         27,        1,   230400, 0x821eedcf
-0,         28,         28,        1,   230400, 0xd068a93d
-0,         29,         29,        1,   230400, 0x2811d46e
-0,         30,         30,        1,   230400, 0xd9740446
-0,         31,         31,        1,   230400, 0x1bce0df6
-0,         32,         32,        1,   230400, 0x44bc60ad
-0,         33,         33,        1,   230400, 0xf56f6200
-0,         34,         34,        1,   230400, 0x874a2264
-0,         35,         35,        1,   230400, 0xaa155c0e
-0,         36,         36,        1,   230400, 0x595392d4
-0,         37,         37,        1,   230400, 0x58dc57de
-0,         38,         38,        1,   230400, 0x1c06733e
-0,         39,         39,        1,   230400, 0x6807b1db
-0,         40,         40,        1,   230400, 0x3fedff87
-0,         41,         41,        1,   230400, 0x3e38cc13
-0,         42,         42,        1,   230400, 0x6685ec35
-0,         43,         43,        1,   230400, 0x6c0742fd
-0,         44,         44,        1,   230400, 0x8108f83c
-0,         45,         45,        1,   230400, 0xc0e217c8
-0,         46,         46,        1,   230400, 0xb22ca65d
-0,         47,         47,        1,   230400, 0xd54cec93
-0,         48,         48,        1,   230400, 0xd9d61de3
-0,         49,         49,        1,   230400, 0x7e0f9675
-0,         50,         50,        1,   230400, 0x9869f5b7
+0,         26,         26,        1,   230400, 0x65764edb
+0,         27,         27,        1,   230400, 0xeabdcf53
+0,         28,         28,        1,   230400, 0xaeb659fc
+0,         29,         29,        1,   230400, 0x5ec97eb1
+0,         30,         30,        1,   230400, 0x2482abae
+0,         31,         31,        1,   230400, 0x297fb0c8
+0,         32,         32,        1,   230400, 0x57a52a3d
+0,         33,         33,        1,   230400, 0x44040e98
+0,         34,         34,        1,   230400, 0xa150e542
+0,         35,         35,        1,   230400, 0x0a1e1296
+0,         36,         36,        1,   230400, 0xf1085864
+0,         37,         37,        1,   230400, 0xe7a13b40
+0,         38,         38,        1,   230400, 0x759d384d
+0,         39,         39,        1,   230400, 0x72e08991
+0,         40,         40,        1,   230400, 0x10a4bbc9
+0,         41,         41,        1,   230400, 0xb258ac16
+0,         42,         42,        1,   230400, 0xde06facb
+0,         43,         43,        1,   230400, 0x94284e11
+0,         44,         44,        1,   230400, 0xedf23092
+0,         45,         45,        1,   230400, 0xc2be6319
+0,         46,         46,        1,   230400, 0x103a0b7b
+0,         47,         47,        1,   230400, 0x3415888b
+0,         48,         48,        1,   230400, 0x5ecaac75
+0,         49,         49,        1,   230400, 0xb9ba503e
+0,         50,         50,        1,   230400, 0xb20ccf57
 1,      88200,      88200,    44100,   176400, 0x2793fad7
-0,         51,         51,        1,   230400, 0x22f33400
-0,         52,         52,        1,   230400, 0x31b999bd
-0,         53,         53,        1,   230400, 0x36c23878
-0,         54,         54,        1,   230400, 0x06093a30
-0,         55,         55,        1,   230400, 0x213f1718
-0,         56,         56,        1,   230400, 0x83683006
-0,         57,         57,        1,   230400, 0x0bfcec36
-0,         58,         58,        1,   230400, 0x01b77825
-0,         59,         59,        1,   230400, 0x650a5ea2
-0,         60,         60,        1,   230400, 0xd8b2c559
-0,         61,         61,        1,   230400, 0xb012eb10
-0,         62,         62,        1,   230400, 0x135d53a4
-0,         63,         63,        1,   230400, 0x98dd0712
-0,         64,         64,        1,   230400, 0x75240ac0
-0,         65,         65,        1,   230400, 0xa16769d5
-0,         66,         66,        1,   230400, 0x3e08cda3
-0,         67,         67,        1,   230400, 0xcd20d561
-0,         68,         68,        1,   230400, 0x3531577d
-0,         69,         69,        1,   230400, 0x65ff4c82
-0,         70,         70,        1,   230400, 0x8fd4a580
-0,         71,         71,        1,   230400, 0x3cf7af4c
-0,         72,         72,        1,   230400, 0xda7a9202
-0,         73,         73,        1,   230400, 0x4bebc138
-0,         74,         74,        1,   230400, 0x5517e685
-0,         75,         75,        1,   230400, 0x95f6c7a3
+0,         51,         51,        1,   230400, 0x0dba31ed
+0,         52,         52,        1,   230400, 0x91c5e7d4
+0,         53,         53,        1,   230400, 0x09ac954b
+0,         54,         54,        1,   230400, 0xe9c3d563
+0,         55,         55,        1,   230400, 0xf46eef67
+0,         56,         56,        1,   230400, 0x117f4b80
+0,         57,         57,        1,   230400, 0x61714860
+0,         58,         58,        1,   230400, 0x5c7112d0
+0,         59,         59,        1,   230400, 0xd42c51e7
+0,         60,         60,        1,   230400, 0x425f0c99
+0,         61,         61,        1,   230400, 0x4c398834
+0,         62,         62,        1,   230400, 0x237f89c2
+0,         63,         63,        1,   230400, 0xd2e29b05
+0,         64,         64,        1,   230400, 0x204a054b
+0,         65,         65,        1,   230400, 0x25a9faf7
+0,         66,         66,        1,   230400, 0x83f6c1a8
+0,         67,         67,        1,   230400, 0xe48321b9
+0,         68,         68,        1,   230400, 0x714c1005
+0,         69,         69,        1,   230400, 0x36cc58e9
+0,         70,         70,        1,   230400, 0x5e9ffdd9
+0,         71,         71,        1,   230400, 0x582b55dc
+0,         72,         72,        1,   230400, 0x139a7f39
+0,         73,         73,        1,   230400, 0xefb5f998
+0,         74,         74,        1,   230400, 0xeb736da8
+0,         75,         75,        1,   230400, 0x488f9847
 1,     132300,     132300,    44100,   176400, 0xe2649a4a
-0,         76,         76,        1,   230400, 0x9849ebf9
-0,         77,         77,        1,   230400, 0xd77e1c7d
-0,         78,         78,        1,   230400, 0x4dc6c923
-0,         79,         79,        1,   230400, 0x7ce817c8
-0,         80,         80,        1,   230400, 0xafb4acde
-0,         81,         81,        1,   230400, 0xd0030b2c
-0,         82,         82,        1,   230400, 0xb3acb77c
-0,         83,         83,        1,   230400, 0x4d32b61c
-0,         84,         84,        1,   230400, 0x2436a915
-0,         85,         85,        1,   230400, 0xa6fd831f
-0,         86,         86,        1,   230400, 0x6c6edfca
-0,         87,         87,        1,   230400, 0x4b30d72e
-0,         88,         88,        1,   230400, 0x59f46a8a
-0,         89,         89,        1,   230400, 0xa2d0435f
-0,         90,         90,        1,   230400, 0x463872c4
-0,         91,         91,        1,   230400, 0x1d7e870a
-0,         92,         92,        1,   230400, 0x74f4e530
-0,         93,         93,        1,   230400, 0xbc61053d
-0,         94,         94,        1,   230400, 0x5fb238dc
-0,         95,         95,        1,   230400, 0x14a29d83
-0,         96,         96,        1,   230400, 0x3fd1d09b
-0,         97,         97,        1,   230400, 0x098afc13
-0,         98,         98,        1,   230400, 0x9bd12a62
-0,         99,         99,        1,   230400, 0x7bf71419
+0,         76,         76,        1,   230400, 0x6ab20741
+0,         77,         77,        1,   230400, 0xa73686f0
+0,         78,         78,        1,   230400, 0x67878643
+0,         79,         79,        1,   230400, 0x83bb241b
+0,         80,         80,        1,   230400, 0xe6b70660
+0,         81,         81,        1,   230400, 0x87f5aca3
+0,         82,         82,        1,   230400, 0x29c79bc3
+0,         83,         83,        1,   230400, 0xcadbd70b
+0,         84,         84,        1,   230400, 0x8cdcfdee
+0,         85,         85,        1,   230400, 0x90aa0442
+0,         86,         86,        1,   230400, 0xa68e87b7
+0,         87,         87,        1,   230400, 0xa2c49e58
+0,         88,         88,        1,   230400, 0x9a9a4c55
+0,         89,         89,        1,   230400, 0x06b53aed
+0,         90,         90,        1,   230400, 0x79e1808a
+0,         91,         91,        1,   230400, 0x3e53a411
+0,         92,         92,        1,   230400, 0xfebc13ca
+0,         93,         93,        1,   230400, 0x1f1f443b
+0,         94,         94,        1,   230400, 0xd0db806a
+0,         95,         95,        1,   230400, 0x6f2aee94
+0,         96,         96,        1,   230400, 0xe8cc23ba
+0,         97,         97,        1,   230400, 0x2edf510b
+0,         98,         98,        1,   230400, 0x87118129
+0,         99,         99,        1,   230400, 0x1dd1709a
diff --git a/tests/ref/fate/avio-direct b/tests/ref/fate/avio-direct
new file mode 100644
index 0000000..599683a
--- /dev/null
+++ b/tests/ref/fate/avio-direct
@@ -0,0 +1,59 @@
+#tb 0: 1/30
+0,          0,          0,        1,   145152, 0x8458d4cb
+0,          1,          1,        1,   145152, 0xa694d7c7
+0,          2,          2,        1,   145152, 0x2bd4bfc9
+0,          3,          3,        1,   145152, 0xe53b1616
+0,          4,          4,        1,   145152, 0x6a0a806a
+0,          5,          5,        1,   145152, 0x45f7b8e6
+0,          6,          6,        1,   145152, 0x4e14150e
+0,          7,          7,        1,   145152, 0xe1cd9b6f
+0,          8,          8,        1,   145152, 0x5b5802d7
+0,          9,          9,        1,   145152, 0xb03da5e7
+0,         10,         10,        1,   145152, 0x3436b06e
+0,         11,         11,        1,   145152, 0x4535e638
+0,         12,         12,        1,   145152, 0x72934af1
+0,         13,         13,        1,   145152, 0xb672d459
+0,         14,         14,        1,   145152, 0xab57491b
+0,         15,         15,        1,   145152, 0xdbac3480
+0,         16,         16,        1,   145152, 0x54215962
+0,         17,         17,        1,   145152, 0x451f456e
+0,         18,         18,        1,   145152, 0xa17655d1
+0,         19,         19,        1,   145152, 0xce95422c
+0,         20,         20,        1,   145152, 0xe0ee8e77
+0,         21,         21,        1,   145152, 0xdaabe277
+0,         22,         22,        1,   145152, 0xc21bb665
+0,         23,         23,        1,   145152, 0x1e74270e
+0,         24,         24,        1,   145152, 0xae7bac5f
+0,         25,         25,        1,   145152, 0xf62442ed
+0,         26,         26,        1,   145152, 0x5c8d8984
+0,         27,         27,        1,   145152, 0x97a69fe7
+0,         28,         28,        1,   145152, 0x1f244d19
+0,         29,         29,        1,   145152, 0x2758bc25
+0,         30,         30,        1,   145152, 0xf43ddb89
+0,         31,         31,        1,   145152, 0x086a524e
+0,         32,         32,        1,   145152, 0x8b464d4d
+0,         33,         33,        1,   145152, 0xb77b63d2
+0,         34,         34,        1,   145152, 0xfd842fa8
+0,         35,         35,        1,   145152, 0xa98b6dbe
+0,         36,         36,        1,   145152, 0xdedbab2c
+0,         37,         37,        1,   145152, 0x24e19172
+0,         38,         38,        1,   145152, 0x1ef456f6
+0,         39,         39,        1,   145152, 0xaceabdf0
+0,         40,         40,        1,   145152, 0xb54de3d9
+0,         41,         41,        1,   145152, 0x3af0df9b
+0,         42,         42,        1,   145152, 0xf89fbd9a
+0,         43,         43,        1,   145152, 0xc6a9673c
+0,         44,         44,        1,   145152, 0x6d5a929e
+0,         45,         45,        1,   145152, 0x879e7d9b
+0,         46,         46,        1,   145152, 0x233c14eb
+0,         47,         47,        1,   145152, 0x8246f081
+0,         48,         48,        1,   145152, 0x3366c4bf
+0,         49,         49,        1,   145152, 0x6b0203da
+0,         50,         50,        1,   145152, 0x48a00163
+0,         51,         51,        1,   145152, 0xe956ac2c
+0,         52,         52,        1,   145152, 0xa2511283
+0,         53,         53,        1,   145152, 0x7e03222d
+0,         54,         54,        1,   145152, 0xc31a7a40
+0,         55,         55,        1,   145152, 0x80448031
+0,         56,         56,        1,   145152, 0xe3b1fbf7
+0,         57,         57,        1,   145152, 0xa00395a4
diff --git a/tests/ref/fate/bethsoft-vid b/tests/ref/fate/bethsoft-vid
index a4c049e..f59823c 100644
--- a/tests/ref/fate/bethsoft-vid
+++ b/tests/ref/fate/bethsoft-vid
@@ -1,144 +1,143 @@
-#tb 0: 185/11111
+#tb 0: 1/14
 #tb 1: 1/11111
 0,          0,          0,        1,   192000, 0x00000000
 1,          0,          0,      740,     1480, 0x00000000
-0,          4,          4,        1,   192000, 0x01a6cf45
 1,        740,        740,      740,     1480, 0x20a92bd4
-0,          8,          8,        1,   192000, 0xd07d57e9
+0,          1,          1,        1,   192000, 0x5a5acf57
 1,       1480,       1480,      925,     1850, 0xa9e48a74
-0,         13,         13,        1,   192000, 0x3cb1dff5
+0,          2,          2,        1,   192000, 0xbd055cf1
+0,          3,          3,        1,   192000, 0x28b1eefc
 1,       2405,       2405,      740,     1480, 0x23ecd018
-0,         17,         17,        1,   192000, 0xd1aaa8fb
 1,       3145,       3145,      740,     1480, 0x206bb915
-0,         21,         21,        1,   192000, 0x75f526cd
+0,          4,          4,        1,   192000, 0x0636bacd
 1,       3885,       3885,      925,     1850, 0xb0e10e75
-0,         26,         26,        1,   192000, 0x0f673577
+0,          5,          5,        1,   192000, 0xbfd33cbd
+0,          6,          6,        1,   192000, 0x0bd150ef
 1,       4810,       4810,      740,     1480, 0x8d9baedd
-0,         30,         30,        1,   192000, 0x897b6781
 1,       5550,       5550,      740,     1480, 0xb802aae1
-0,         34,         34,        1,   192000, 0x81e6b7f7
+0,          7,          7,        1,   192000, 0x780d891e
 1,       6290,       6290,      740,     1480, 0xecd7b5cc
-0,         38,         38,        1,   192000, 0x1f45ce61
+0,          8,          8,        1,   192000, 0xacf5e205
 1,       7030,       7030,      925,     1850, 0x16861355
-0,         43,         43,        1,   192000, 0x5a0772a6
+0,          9,          9,        1,   192000, 0x37c900dc
+0,         10,         10,        1,   192000, 0x4ee6add7
 1,       7955,       7955,      740,     1480, 0xa51690bd
-0,         47,         47,        1,   192000, 0xf78732b3
 1,       8695,       8695,      740,     1480, 0xdd0b90d1
-0,         51,         51,        1,   192000, 0x8427f9e5
+0,         11,         11,        1,   192000, 0x1844783a
 1,       9435,       9435,      925,     1850, 0x3ce6e333
-0,         56,         56,        1,   192000, 0x40473f11
+0,         12,         12,        1,   192000, 0x7bf84848
+0,         13,         13,        1,   192000, 0x1ec296bc
 1,      10360,      10360,      740,     1480, 0xf8ce8ea3
-0,         60,         60,        1,   192000, 0x173ceebe
 1,      11100,      11100,      740,     1480, 0xda4597af
-0,         64,         64,        1,   192000, 0x136b9516
+0,         14,         14,        1,   192000, 0xbaeb5292
 1,      11840,      11840,      740,     1480, 0x918f7cb3
-0,         68,         68,        1,   192000, 0x138d11ae
+0,         15,         15,        1,   192000, 0xcb18038d
 1,      12580,      12580,      925,     1850, 0xca6edb15
-0,         73,         73,        1,   192000, 0x063dbff3
+0,         16,         16,        1,   192000, 0xb3cc8b65
+0,         17,         17,        1,   192000, 0x6f164685
 1,      13505,      13505,      740,     1480, 0xba279597
-0,         77,         77,        1,   192000, 0x5280852f
 1,      14245,      14245,      740,     1480, 0xc5a38a9e
-0,         81,         81,        1,   192000, 0x99943a8f
+0,         18,         18,        1,   192000, 0x304917c9
 1,      14985,      14985,      925,     1850, 0x8147eef5
-0,         86,         86,        1,   192000, 0x0330a728
+0,         19,         19,        1,   192000, 0x8269daa1
+0,         20,         20,        1,   192000, 0x04d3500d
 1,      15910,      15910,      740,     1480, 0xce2c7cb5
-0,         90,         90,        1,   192000, 0x5d35467d
 1,      16650,      16650,      740,     1480, 0x4282819f
-0,         94,         94,        1,   192000, 0xfd436343
+0,         21,         21,        1,   192000, 0x9788f7a5
 1,      17390,      17390,      740,     1480, 0xbdbb8da6
-0,         98,         98,        1,   192000, 0xc323fcfe
+0,         22,         22,        1,   192000, 0x05351c98
 1,      18130,      18130,      925,     1850, 0xdbbeea10
-0,        103,        103,        1,   192000, 0x2a1530a0
+0,         23,         23,        1,   192000, 0xcc8bba97
+0,         24,         24,        1,   192000, 0x76caf27b
 1,      19055,      19055,      740,     1480, 0xbe6a77c2
-0,        107,        107,        1,   192000, 0xbd43bb60
 1,      19795,      19795,      740,     1480, 0xa85c75b2
-0,        111,        111,        1,   192000, 0xa47f5eab
+0,         25,         25,        1,   192000, 0x28648040
 1,      20535,      20535,      925,     1850, 0xa45bde21
-0,        116,        116,        1,   192000, 0xff17f5f7
+0,         26,         26,        1,   192000, 0x99ea251f
+0,         27,         27,        1,   192000, 0x20e7bf4d
 1,      21460,      21460,      740,     1480, 0x84aa7895
-0,        120,        120,        1,   192000, 0xb4140b55
 1,      22200,      22200,      740,     1480, 0x147f7d9f
-0,        124,        124,        1,   192000, 0xb8782cc4
+0,         28,         28,        1,   192000, 0x046ed625
 1,      22940,      22940,      740,     1480, 0xc8e77b85
-0,        128,        128,        1,   192000, 0x92975b8b
+0,         29,         29,        1,   192000, 0x1613fb12
 1,      23680,      23680,      925,     1850, 0x10d4d81b
-0,        133,        133,        1,   192000, 0xf42a64d6
+0,         30,         30,        1,   192000, 0xd8b52d16
+0,         31,         31,        1,   192000, 0x31443aa9
 1,      24605,      24605,      740,     1480, 0xb4ae8bb1
-0,        137,        137,        1,   192000, 0x2cc7077d
 1,      25345,      25345,      740,     1480, 0x3ef782a5
-0,        141,        141,        1,   192000, 0x00080cc8
+0,         32,         32,        1,   192000, 0xd426de3d
 1,      26085,      26085,      925,     1850, 0xdeebda14
-0,        146,        146,        1,   192000, 0x584b48f3
+0,         33,         33,        1,   192000, 0xb2bce77b
+0,         34,         34,        1,   192000, 0x25a52805
 1,      27010,      27010,      740,     1480, 0x4c7e7bbb
-0,        150,        150,        1,   192000, 0xd68f57da
 1,      27750,      27750,      740,     1480, 0x0e0e9198
-0,        154,        154,        1,   192000, 0x60158422
+0,         35,         35,        1,   192000, 0x04f03a87
 1,      28490,      28490,      740,     1480, 0x5c1f819f
-0,        158,        158,        1,   192000, 0xd7fb89e6
+0,         36,         36,        1,   192000, 0x41d56889
 1,      29230,      29230,      925,     1850, 0x0e4cf6ff
-0,        163,        163,        1,   192000, 0x97f1c76a
+0,         37,         37,        1,   192000, 0x3d4d6de9
 1,      30155,      30155,      740,     1480, 0x374388a7
-0,        167,        167,        1,   192000, 0x46c4bb9e
+0,         38,         38,        1,   192000, 0xa7a2abfe
 1,      30895,      30895,      740,     1480, 0xed729389
-0,        171,        171,        1,   192000, 0xd32f9b66
+0,         39,         39,        1,   192000, 0x663e9fca
 1,      31635,      31635,      925,     1850, 0xe0f1e43f
-0,        176,        176,        1,   192000, 0x74f43886
+0,         40,         40,        1,   192000, 0x29a67f86
+0,         41,         41,        1,   192000, 0x51531bb0
 1,      32560,      32560,      740,     1480, 0x3b27839a
-0,        180,        180,        1,   192000, 0x3c4e47df
 1,      33300,      33300,      740,     1480, 0xe6287e94
-0,        184,        184,        1,   192000, 0xb5ac0a58
+0,         42,         42,        1,   192000, 0xd993277e
 1,      34040,      34040,      740,     1480, 0x7e0d84b5
-0,        188,        188,        1,   192000, 0xcc572b31
+0,         43,         43,        1,   192000, 0x4873e583
 1,      34780,      34780,      925,     1850, 0xf08bebf7
-0,        193,        193,        1,   192000, 0xb1739d26
+0,         44,         44,        1,   192000, 0x06df053b
 1,      35705,      35705,      740,     1480, 0x94cf73a0
-0,        197,        197,        1,   192000, 0x73da5473
+0,         45,         45,        1,   192000, 0x044f7698
 1,      36445,      36445,      740,     1480, 0xfef384ae
-0,        201,        201,        1,   192000, 0x5f79f5bc
+0,         46,         46,        1,   192000, 0xc2302a45
 1,      37185,      37185,      925,     1850, 0x3b93e0f7
-0,        206,        206,        1,   192000, 0x0affc0a0
+0,         47,         47,        1,   192000, 0xbdfec8ee
+0,         48,         48,        1,   192000, 0x3b739286
 1,      38110,      38110,      740,     1480, 0x28d27bae
-0,        210,        210,        1,   192000, 0x2b4d5c1c
 1,      38850,      38850,      740,     1480, 0x94d57da5
-0,        214,        214,        1,   192000, 0x309b41bc
+0,         49,         49,        1,   192000, 0x3ca82cd6
 1,      39590,      39590,      740,     1480, 0xc9327db5
-0,        218,        218,        1,   192000, 0xd42b6424
+0,         50,         50,        1,   192000, 0x25af10f2
 1,      40330,      40330,      925,     1850, 0xe781f604
-0,        223,        223,        1,   192000, 0x4795c948
+0,         51,         51,        1,   192000, 0x09ce32bf
 1,      41255,      41255,      740,     1480, 0x752f8c5b
-0,        227,        227,        1,   192000, 0xbc1a3a8b
+0,         52,         52,        1,   192000, 0xdab399c2
 1,      41995,      41995,      740,     1480, 0x30068032
-0,        231,        231,        1,   192000, 0x16529c5b
+0,         53,         53,        1,   192000, 0x77400d93
 1,      42735,      42735,      925,     1850, 0x7895023e
-0,        236,        236,        1,   192000, 0x6b1b31ba
+0,         54,         54,        1,   192000, 0x5e8e6fe7
+0,         55,         55,        1,   192000, 0x277506c9
 1,      43660,      43660,      740,     1480, 0xa1e0a6e1
-0,        240,        240,        1,   192000, 0x569182ce
 1,      44400,      44400,      740,     1480, 0x6af4b500
-0,        244,        244,        1,   192000, 0xe6ea9866
+0,         56,         56,        1,   192000, 0xe91b59ac
 1,      45140,      45140,      740,     1480, 0xc26ea4c7
-0,        248,        248,        1,   192000, 0x102c6076
+0,         57,         57,        1,   192000, 0xc2aa6e19
 1,      45880,      45880,      925,     1850, 0x16a72419
-0,        253,        253,        1,   192000, 0xb29f527a
+0,         58,         58,        1,   192000, 0x12c63645
 1,      46805,      46805,      740,     1480, 0x1794aacc
-0,        257,        257,        1,   192000, 0x040b4eee
+0,         59,         59,        1,   192000, 0xa39f27d6
 1,      47545,      47545,      740,     1480, 0x2ecad8d0
-0,        261,        261,        1,   192000, 0x92574f4a
+0,         60,         60,        1,   192000, 0x20c32512
 1,      48285,      48285,      925,     1850, 0x2e645e07
-0,        266,        266,        1,   192000, 0x1e8acdce
+0,         61,         61,        1,   192000, 0x385a26a0
+0,         62,         62,        1,   192000, 0x2566a70c
 1,      49210,      49210,      740,     1480, 0x1c54dfe7
-0,        270,        270,        1,   192000, 0x1becf516
 1,      49950,      49950,      740,     1480, 0xbd35feec
-0,        274,        274,        1,   192000, 0xb62e9776
+0,         63,         63,        1,   192000, 0x7105cfb9
 1,      50690,      50690,      740,     1480, 0x419403d6
-0,        278,        278,        1,   192000, 0xed37a08e
+0,         64,         64,        1,   192000, 0x725671a2
 1,      51430,      51430,      925,     1850, 0x78699d2a
-0,        283,        283,        1,   192000, 0xc0719912
+0,         65,         65,        1,   192000, 0x3ff2782a
 1,      52355,      52355,      740,     1480, 0x74ec68e0
-0,        287,        287,        1,   192000, 0x24cf7a7e
+0,         66,         66,        1,   192000, 0xdc0571c3
 1,      53095,      53095,      740,     1480, 0x76af64d9
-0,        291,        291,        1,   192000, 0x0307f62f
+0,         67,         67,        1,   192000, 0x4a6a5405
 1,      53835,      53835,      925,     1850, 0x5a303d1a
-0,        296,        296,        1,   192000, 0x79b7417b
+0,         68,         68,        1,   192000, 0x3ec3cce1
 1,      54760,      54760,      537,     1074, 0x142ce7ba
+0,         69,         69,        1,   192000, 0x159313a8
 1,      55297,      55297,      925,     1850, 0x7ff682f7
-0,        300,        300,        1,   192000, 0x468d8db4
diff --git a/tests/ref/fate/bprint b/tests/ref/fate/bprint
new file mode 100644
index 0000000..e027fa1
--- /dev/null
+++ b/tests/ref/fate/bprint
@@ -0,0 +1,14 @@
+Short text in unlimited buffer: 174/174
+       1
+       1       1
+       1       2       1
+       1       3       3       1
+       1       4       6       4       1
+       1       5      10      10       5       1
+
+Long text in unlimited buffer: 2834/2834
+Long text in limited buffer: 2047/2834
+Short text in automatic buffer: 174/174
+Long text in automatic buffer: 1000/2834
+Long text count only buffer: 0/2834
+Long text count only buffer: 255/2834
diff --git a/tests/ref/fate/cdgraphics b/tests/ref/fate/cdgraphics
index 78a8f28..1e5cc6f 100644
--- a/tests/ref/fate/cdgraphics
+++ b/tests/ref/fate/cdgraphics
@@ -35,267 +35,179 @@
 0,         33,         33,        1,   194400, 0x9ff8cbb1
 0,         34,         34,        1,   194400, 0xd015dba1
 0,         35,         35,        1,   194400, 0x6a39f18b
-0,         36,         36,        1,   194400, 0x7b8cf983
-0,         37,         37,        1,   194400, 0x07a20f7c
-0,         38,         38,        1,   194400, 0xa63e2962
-0,         39,         39,        1,   194400, 0x2dd54447
-0,         40,         40,        1,   194400, 0x90735e2d
-0,         41,         41,        1,   194400, 0x90d98506
-0,         42,         42,        1,   194400, 0xe5b08ffb
-0,         43,         43,        1,   194400, 0x7a0d95f5
-0,         44,         44,        1,   194400, 0xff6bacde
-0,         45,         45,        1,   194400, 0xd998c2c8
-0,         46,         46,        1,   194400, 0x3d1ddfab
-0,         47,         47,        1,   194400, 0x817de4a6
-0,         48,         48,        1,   194400, 0xfa3ef694
-0,         49,         49,        1,   194400, 0x0b5bfb8f
-0,         50,         50,        1,   194400, 0x00f62376
-0,         51,         51,        1,   194400, 0x2f6b2d6c
-0,         52,         52,        1,   194400, 0x40cb4752
-0,         53,         53,        1,   194400, 0xd8456435
-0,         54,         54,        1,   194400, 0x459f6a2f
-0,         55,         55,        1,   194400, 0x9b678910
-0,         56,         56,        1,   194400, 0x8791a1f7
-0,         57,         57,        1,   194400, 0xdb4ac5d3
-0,         58,         58,        1,   194400, 0xb223c8d0
-0,         59,         59,        1,   194400, 0x4a9ce7b1
-0,         60,         60,        1,   194400, 0x187eeaae
-0,         61,         61,        1,   194400, 0xc712f8a0
-0,         62,         62,        1,   194400, 0x549c00a7
-0,         63,         63,        1,   194400, 0x4d991295
-0,         64,         64,        1,   194400, 0xc41b2681
-0,         65,         65,        1,   194400, 0xed5a3077
-0,         66,         66,        1,   194400, 0x85ad4463
-0,         67,         67,        1,   194400, 0xb98f4760
-0,         68,         68,        1,   194400, 0x87ef5e49
-0,         69,         69,        1,   194400, 0x830a6146
-0,         70,         70,        1,   194400, 0xe33a792e
-0,         71,         71,        1,   194400, 0x83517a2d
-0,         72,         72,        1,   194400, 0xa97e9314
-0,         73,         73,        1,   194400, 0x39059611
-0,         74,         74,        1,   194400, 0xbf4eb9ed
-0,         75,         75,        1,   194400, 0xe5afc4e2
-0,         76,         76,        1,   194400, 0x35d4cdd9
-0,         77,         77,        1,   194400, 0xb376e1c5
-0,         78,         78,        1,   194400, 0x6128e3c3
-0,         79,         79,        1,   194400, 0x30b7f7af
-0,         80,         80,        1,   194400, 0xf1effaac
-0,         81,         81,        1,   194400, 0x483914a1
-0,         82,         82,        1,   194400, 0xbd48199c
-0,         83,         83,        1,   194400, 0x382f2d88
-0,         84,         84,        1,   194400, 0x5a573085
-0,         85,         85,        1,   194400, 0x89733580
-0,         86,         86,        1,   194400, 0xd1325a5b
-0,         87,         87,        1,   194400, 0x655b6253
-0,         88,         88,        1,   194400, 0x55146352
-0,         89,         89,        1,   194400, 0xda527c39
-0,         90,         90,        1,   194400, 0xb0cd7e37
-0,         91,         91,        1,   194400, 0x25e7991c
-0,         92,         92,        1,   194400, 0x5c22a411
-0,         93,         93,        1,   194400, 0x1e2abdf7
-0,         94,         94,        1,   194400, 0x8308bff5
-0,         95,         95,        1,   194400, 0xfdbfd6de
-0,         96,         96,        1,   194400, 0xd4d4d9db
-0,         97,         97,        1,   194400, 0xa449fbb9
-0,         98,         98,        1,   194400, 0x3dcafdb7
-0,         99,         99,        1,   194400, 0x6f1f01c2
-0,        100,        100,        1,   194400, 0xf54a1da6
-0,        101,        101,        1,   194400, 0x88d11fa4
-0,        102,        102,        1,   194400, 0x59642d96
-0,        103,        103,        1,   194400, 0x8ba44182
-0,        104,        104,        1,   194400, 0x88f56360
-0,        105,        105,        1,   194400, 0xfb246d56
-0,        106,        106,        1,   194400, 0xad128043
-0,        107,        107,        1,   194400, 0x3a4f8a39
-0,        108,        108,        1,   194400, 0x563d9d26
-0,        109,        109,        1,   194400, 0x6ff8a320
-0,        110,        110,        1,   194400, 0xcdb9b70c
-0,        111,        111,        1,   194400, 0x99c2bd06
-0,        112,        112,        1,   194400, 0x4b47cef4
-0,        113,        113,        1,   194400, 0x10b9dce6
-0,        114,        114,        1,   194400, 0xdd39f1d1
-0,        115,        115,        1,   194400, 0xbcf104cd
-0,        116,        116,        1,   194400, 0x85ec17ba
-0,        117,        117,        1,   194400, 0x069219b8
-0,        118,        118,        1,   194400, 0x84dd3899
-0,        119,        119,        1,   194400, 0xacca4190
-0,        120,        120,        1,   194400, 0xcf5b5d74
-0,        121,        121,        1,   194400, 0x4b8c626f
-0,        122,        122,        1,   194400, 0xf0817958
-0,        123,        123,        1,   194400, 0xc0887e53
-0,        124,        124,        1,   194400, 0x42e6854c
-0,        125,        125,        1,   194400, 0x036c9140
-0,        126,        126,        1,   194400, 0x0f21a62b
-0,        127,        127,        1,   194400, 0xcdaeaa27
-0,        128,        128,        1,   194400, 0xe425bc15
-0,        129,        129,        1,   194400, 0x8e18c20f
-0,        130,        130,        1,   194400, 0x767cd5fb
-0,        131,        131,        1,   194400, 0x554ae6ea
-0,        132,        132,        1,   194400, 0xeac1f9d7
-0,        133,        133,        1,   194400, 0x0b32fed2
-0,        134,        134,        1,   194400, 0xe30c19c6
-0,        135,        135,        1,   194400, 0x6a8a23bc
-0,        136,        136,        1,   194400, 0x26bf36a9
-0,        137,        137,        1,   194400, 0x1e4f3fa0
-0,        138,        138,        1,   194400, 0x231f5986
-0,        139,        139,        1,   194400, 0xf557756a
-0,        140,        140,        1,   194400, 0x6bce805f
-0,        141,        141,        1,   194400, 0xcd80924d
-0,        142,        142,        1,   194400, 0x65dc9f40
-0,        143,        143,        1,   194400, 0x2ab7af30
-0,        144,        144,        1,   194400, 0xd43cb728
-0,        145,        145,        1,   194400, 0x05d9c916
-0,        146,        146,        1,   194400, 0x43cad10e
-0,        147,        147,        1,   194400, 0x06b5e0fe
-0,        148,        148,        1,   194400, 0xa142f0ee
-0,        149,        149,        1,   194400, 0xed7f03ea
-0,        150,        150,        1,   194400, 0xf26019d4
-0,        151,        151,        1,   194400, 0x3b7f29c4
-0,        152,        152,        1,   194400, 0x30282ebf
-0,        153,        153,        1,   194400, 0xaeff4aa3
-0,        154,        154,        1,   194400, 0x1d355697
-0,        155,        155,        1,   194400, 0x2ead6f7e
-0,        156,        156,        1,   194400, 0xf1b67776
-0,        157,        157,        1,   194400, 0x93b38b62
-0,        158,        158,        1,   194400, 0x9469905d
-0,        159,        159,        1,   194400, 0x27bf9756
-0,        160,        160,        1,   194400, 0xd016a548
-0,        161,        161,        1,   194400, 0x6889b835
-0,        162,        162,        1,   194400, 0x6a05be2f
-0,        163,        163,        1,   194400, 0xe0a1ce1f
-0,        164,        164,        1,   194400, 0x8fdbd617
-0,        165,        165,        1,   194400, 0xd68fe805
-0,        166,        166,        1,   194400, 0x0d1dfbf1
-0,        167,        167,        1,   194400, 0x0fe70bf0
-0,        168,        168,        1,   194400, 0x0a8f13e8
-0,        169,        169,        1,   194400, 0x0ca42bd0
-0,        170,        170,        1,   194400, 0x6f3838c3
-0,        171,        171,        1,   194400, 0x045448b3
-0,        172,        172,        1,   194400, 0x764349b2
-0,        173,        173,        1,   194400, 0xed1651aa
-0,        174,        174,        1,   194400, 0xbb376398
-0,        175,        175,        1,   194400, 0xd0d5718a
-0,        176,        176,        1,   194400, 0xcd977e7d
-0,        177,        177,        1,   194400, 0x8cb39665
-0,        178,        178,        1,   194400, 0xb935b04b
-0,        179,        179,        1,   194400, 0x0292be3d
-0,        180,        180,        1,   194400, 0x4f21c833
-0,        181,        181,        1,   194400, 0xa5c7d823
-0,        182,        182,        1,   194400, 0xfb8ee01b
-0,        183,        183,        1,   194400, 0xea53ee0d
-0,        184,        184,        1,   194400, 0x803efcfe
-0,        185,        185,        1,   194400, 0x2c0e0aff
-0,        186,        186,        1,   194400, 0x3df318f1
-0,        187,        187,        1,   194400, 0xc4cb26e3
-0,        188,        188,        1,   194400, 0x92a033d6
-0,        189,        189,        1,   194400, 0x1b2048c1
-0,        190,        190,        1,   194400, 0x236858b1
-0,        191,        191,        1,   194400, 0x482f6d9c
-0,        192,        192,        1,   194400, 0x9ee97891
-0,        193,        193,        1,   194400, 0xe0dc8683
-0,        194,        194,        1,   194400, 0x461b9079
-0,        195,        195,        1,   194400, 0xd346a960
-0,        196,        196,        1,   194400, 0xa384b554
-0,        197,        197,        1,   194400, 0x3246cf3a
-0,        198,        198,        1,   194400, 0xa53fe722
-0,        199,        199,        1,   194400, 0xe620fd0c
-0,        200,        200,        1,   194400, 0xd6370414
-0,        201,        201,        1,   194400, 0xf57f1404
-0,        202,        202,        1,   194400, 0x8c6420f7
-0,        203,        203,        1,   194400, 0xd4be3add
-0,        204,        204,        1,   194400, 0xa8dc4ec9
-0,        205,        205,        1,   194400, 0xda1563b4
-0,        206,        206,        1,   194400, 0xd51873a4
-0,        207,        207,        1,   194400, 0x68588196
-0,        208,        208,        1,   194400, 0x40d18e89
-0,        209,        209,        1,   194400, 0x1b75a275
-0,        210,        210,        1,   194400, 0xedd1a572
-0,        211,        211,        1,   194400, 0x55daad6a
-0,        212,        212,        1,   194400, 0xcb93b067
-0,        213,        213,        1,   194400, 0x5888ba5d
-0,        214,        214,        1,   194400, 0x2c11c84f
-0,        215,        215,        1,   194400, 0x0fbae334
-0,        216,        216,        1,   194400, 0x773fed2a
-0,        217,        217,        1,   194400, 0x2f87fc1b
-0,        218,        218,        1,   194400, 0xe8120521
-0,        219,        219,        1,   194400, 0x64ac0f17
-0,        220,        220,        1,   194400, 0xba531c0a
-0,        221,        221,        1,   194400, 0xf49433f2
-0,        222,        222,        1,   194400, 0x79e234f1
-0,        223,        223,        1,   194400, 0x043937ee
-0,        224,        224,        1,   194400, 0x9e6141e4
-0,        225,        225,        1,   194400, 0x34204fd6
-0,        226,        226,        1,   194400, 0xa1dd60c5
-0,        227,        227,        1,   194400, 0x12b36eb7
-0,        228,        228,        1,   194400, 0x68987aab
-0,        229,        229,        1,   194400, 0x3207889d
-0,        230,        230,        1,   194400, 0x3bb59194
-0,        231,        231,        1,   194400, 0x0a119f86
-0,        232,        232,        1,   194400, 0x472bab7a
-0,        233,        233,        1,   194400, 0x7364c85d
-0,        234,        234,        1,   194400, 0xa812d84d
-0,        235,        235,        1,   194400, 0xf384f530
-0,        236,        236,        1,   194400, 0x1546052f
-0,        237,        237,        1,   194400, 0xeb611a1a
-0,        238,        238,        1,   194400, 0xc39d250f
-0,        239,        239,        1,   194400, 0x7bd73301
-0,        240,        240,        1,   194400, 0x10f73cf7
-0,        241,        241,        1,   194400, 0x95dc55de
-0,        242,        242,        1,   194400, 0x392e61d2
-0,        243,        243,        1,   194400, 0x113c7bb8
-0,        244,        244,        1,   194400, 0x17128fa4
-0,        245,        245,        1,   194400, 0xf95e9b98
-0,        246,        246,        1,   194400, 0xdc47aa89
-0,        247,        247,        1,   194400, 0xea5dc073
-0,        248,        248,        1,   194400, 0x8dfadc57
-0,        249,        249,        1,   194400, 0xe5c3e84b
-0,        250,        250,        1,   194400, 0x8952f43f
-0,        251,        251,        1,   194400, 0xec9e0240
-0,        252,        252,        1,   194400, 0x8f460c36
-0,        253,        253,        1,   194400, 0xd43e182a
-0,        254,        254,        1,   194400, 0xb00b2919
-0,        255,        255,        1,   194400, 0xc9f6350d
-0,        256,        256,        1,   194400, 0x87ca44fd
-0,        257,        257,        1,   194400, 0xa6a250f1
-0,        258,        258,        1,   194400, 0x34fa60e1
-0,        259,        259,        1,   194400, 0xe1a372cf
-0,        260,        260,        1,   194400, 0xc80785bc
-0,        261,        261,        1,   194400, 0x43e297aa
-0,        262,        262,        1,   194400, 0x7e8ea49d
-0,        263,        263,        1,   194400, 0xd009b091
-0,        264,        264,        1,   194400, 0x9126bc85
-0,        265,        265,        1,   194400, 0x175ad36e
-0,        266,        266,        1,   194400, 0xf9dae160
-0,        267,        267,        1,   194400, 0x1b98f948
-0,        268,        268,        1,   194400, 0xa6c5133d
-0,        269,        269,        1,   194400, 0xf5d42729
-0,        270,        270,        1,   194400, 0x8cfe311f
-0,        271,        271,        1,   194400, 0x18733e12
-0,        272,        272,        1,   194400, 0x24ac50ff
-0,        273,        273,        1,   194400, 0x0d1c64eb
-0,        274,        274,        1,   194400, 0xde947cd3
-0,        275,        275,        1,   194400, 0x08268dc2
-0,        276,        276,        1,   194400, 0xfec69fb0
-0,        277,        277,        1,   194400, 0xba83aba4
-0,        278,        278,        1,   194400, 0xfbe2bc93
-0,        279,        279,        1,   194400, 0xe22fcc83
-0,        280,        280,        1,   194400, 0x050fcf80
-0,        281,        281,        1,   194400, 0xee1ed778
-0,        282,        282,        1,   194400, 0xb44cda75
-0,        283,        283,        1,   194400, 0xa29fe46b
-0,        284,        284,        1,   194400, 0xa99bf55a
-0,        285,        285,        1,   194400, 0x4f840d51
-0,        286,        286,        1,   194400, 0x58941945
-0,        287,        287,        1,   194400, 0x62cb2638
-0,        288,        288,        1,   194400, 0x22ee312d
-0,        289,        289,        1,   194400, 0xea8f3925
-0,        290,        290,        1,   194400, 0xed294c12
-0,        291,        291,        1,   194400, 0xafa75e00
-0,        292,        292,        1,   194400, 0x19d45ffe
-0,        293,        293,        1,   194400, 0x7fcf61fc
-0,        294,        294,        1,   194400, 0x2c126df0
-0,        295,        295,        1,   194400, 0x331379e4
-0,        296,        296,        1,   194400, 0x99fe8cd1
-0,        297,        297,        1,   194400, 0xa5ec98c5
-0,        298,        298,        1,   194400, 0xac68a6b7
-0,        299,        299,        1,   194400, 0x28e6b2ab
+0,         37,         37,        1,   194400, 0x7b8cf983
+0,         38,         38,        1,   194400, 0x07a20f7c
+0,         40,         40,        1,   194400, 0xa63e2962
+0,         41,         41,        1,   194400, 0x2dd54447
+0,         43,         43,        1,   194400, 0x90735e2d
+0,         44,         44,        1,   194400, 0x90d98506
+0,         46,         46,        1,   194400, 0xe5b08ffb
+0,         47,         47,        1,   194400, 0x7a0d95f5
+0,         49,         49,        1,   194400, 0xff6bacde
+0,         50,         50,        1,   194400, 0xd998c2c8
+0,         52,         52,        1,   194400, 0x3d1ddfab
+0,         53,         53,        1,   194400, 0x817de4a6
+0,         55,         55,        1,   194400, 0xfa3ef694
+0,         56,         56,        1,   194400, 0x0b5bfb8f
+0,         58,         58,        1,   194400, 0x00f62376
+0,         59,         59,        1,   194400, 0x2f6b2d6c
+0,         61,         61,        1,   194400, 0x40cb4752
+0,         62,         62,        1,   194400, 0xd8456435
+0,         64,         64,        1,   194400, 0x459f6a2f
+0,         65,         65,        1,   194400, 0x9b678910
+0,         67,         67,        1,   194400, 0x8791a1f7
+0,         68,         68,        1,   194400, 0xdb4ac5d3
+0,         70,         70,        1,   194400, 0xb223c8d0
+0,         71,         71,        1,   194400, 0x4a9ce7b1
+0,         73,         73,        1,   194400, 0x187eeaae
+0,         74,         74,        1,   194400, 0xc712f8a0
+0,         76,         76,        1,   194400, 0x549c00a7
+0,         77,         77,        1,   194400, 0x4d991295
+0,         79,         79,        1,   194400, 0xc41b2681
+0,         80,         80,        1,   194400, 0xed5a3077
+0,         82,         82,        1,   194400, 0x85ad4463
+0,         83,         83,        1,   194400, 0xb98f4760
+0,         85,         85,        1,   194400, 0x87ef5e49
+0,         86,         86,        1,   194400, 0x830a6146
+0,         88,         88,        1,   194400, 0xe33a792e
+0,         89,         89,        1,   194400, 0x83517a2d
+0,         91,         91,        1,   194400, 0xa97e9314
+0,         92,         92,        1,   194400, 0x39059611
+0,         94,         94,        1,   194400, 0xbf4eb9ed
+0,         95,         95,        1,   194400, 0xe5afc4e2
+0,         97,         97,        1,   194400, 0x35d4cdd9
+0,         98,         98,        1,   194400, 0xb376e1c5
+0,        100,        100,        1,   194400, 0x6128e3c3
+0,        101,        101,        1,   194400, 0x30b7f7af
+0,        103,        103,        1,   194400, 0xf1effaac
+0,        104,        104,        1,   194400, 0x483914a1
+0,        106,        106,        1,   194400, 0xbd48199c
+0,        107,        107,        1,   194400, 0x382f2d88
+0,        109,        109,        1,   194400, 0x5a573085
+0,        110,        110,        1,   194400, 0x89733580
+0,        112,        112,        1,   194400, 0xd1325a5b
+0,        113,        113,        1,   194400, 0x655b6253
+0,        115,        115,        1,   194400, 0x55146352
+0,        116,        116,        1,   194400, 0xda527c39
+0,        118,        118,        1,   194400, 0xb0cd7e37
+0,        119,        119,        1,   194400, 0x25e7991c
+0,        121,        121,        1,   194400, 0x5c22a411
+0,        122,        122,        1,   194400, 0x1e2abdf7
+0,        124,        124,        1,   194400, 0x8308bff5
+0,        125,        125,        1,   194400, 0xfdbfd6de
+0,        127,        127,        1,   194400, 0xd4d4d9db
+0,        128,        128,        1,   194400, 0xa449fbb9
+0,        130,        130,        1,   194400, 0x3dcafdb7
+0,        131,        131,        1,   194400, 0x6f1f01c2
+0,        133,        133,        1,   194400, 0xf54a1da6
+0,        134,        134,        1,   194400, 0x88d11fa4
+0,        136,        136,        1,   194400, 0x59642d96
+0,        137,        137,        1,   194400, 0x8ba44182
+0,        139,        139,        1,   194400, 0x88f56360
+0,        140,        140,        1,   194400, 0xfb246d56
+0,        142,        142,        1,   194400, 0xad128043
+0,        143,        143,        1,   194400, 0x3a4f8a39
+0,        145,        145,        1,   194400, 0x563d9d26
+0,        146,        146,        1,   194400, 0x6ff8a320
+0,        148,        148,        1,   194400, 0xcdb9b70c
+0,        149,        149,        1,   194400, 0x99c2bd06
+0,        151,        151,        1,   194400, 0x4b47cef4
+0,        152,        152,        1,   194400, 0x10b9dce6
+0,        154,        154,        1,   194400, 0xdd39f1d1
+0,        155,        155,        1,   194400, 0xbcf104cd
+0,        157,        157,        1,   194400, 0x85ec17ba
+0,        158,        158,        1,   194400, 0x069219b8
+0,        160,        160,        1,   194400, 0x84dd3899
+0,        161,        161,        1,   194400, 0xacca4190
+0,        163,        163,        1,   194400, 0xcf5b5d74
+0,        164,        164,        1,   194400, 0x4b8c626f
+0,        166,        166,        1,   194400, 0xf0817958
+0,        167,        167,        1,   194400, 0xc0887e53
+0,        169,        169,        1,   194400, 0x42e6854c
+0,        170,        170,        1,   194400, 0x036c9140
+0,        172,        172,        1,   194400, 0x0f21a62b
+0,        173,        173,        1,   194400, 0xcdaeaa27
+0,        175,        175,        1,   194400, 0xe425bc15
+0,        176,        176,        1,   194400, 0x8e18c20f
+0,        178,        178,        1,   194400, 0x767cd5fb
+0,        179,        179,        1,   194400, 0x554ae6ea
+0,        181,        181,        1,   194400, 0xeac1f9d7
+0,        182,        182,        1,   194400, 0x0b32fed2
+0,        184,        184,        1,   194400, 0xe30c19c6
+0,        185,        185,        1,   194400, 0x6a8a23bc
+0,        187,        187,        1,   194400, 0x26bf36a9
+0,        188,        188,        1,   194400, 0x1e4f3fa0
+0,        190,        190,        1,   194400, 0x231f5986
+0,        191,        191,        1,   194400, 0xf557756a
+0,        193,        193,        1,   194400, 0x6bce805f
+0,        194,        194,        1,   194400, 0xcd80924d
+0,        196,        196,        1,   194400, 0x65dc9f40
+0,        197,        197,        1,   194400, 0x2ab7af30
+0,        199,        199,        1,   194400, 0xd43cb728
+0,        200,        200,        1,   194400, 0x05d9c916
+0,        202,        202,        1,   194400, 0x43cad10e
+0,        203,        203,        1,   194400, 0x06b5e0fe
+0,        205,        205,        1,   194400, 0xa142f0ee
+0,        206,        206,        1,   194400, 0xed7f03ea
+0,        208,        208,        1,   194400, 0xf26019d4
+0,        209,        209,        1,   194400, 0x3b7f29c4
+0,        211,        211,        1,   194400, 0x30282ebf
+0,        212,        212,        1,   194400, 0xaeff4aa3
+0,        214,        214,        1,   194400, 0x1d355697
+0,        215,        215,        1,   194400, 0x2ead6f7e
+0,        217,        217,        1,   194400, 0xf1b67776
+0,        218,        218,        1,   194400, 0x93b38b62
+0,        220,        220,        1,   194400, 0x9469905d
+0,        221,        221,        1,   194400, 0x27bf9756
+0,        223,        223,        1,   194400, 0xd016a548
+0,        224,        224,        1,   194400, 0x6889b835
+0,        226,        226,        1,   194400, 0x6a05be2f
+0,        227,        227,        1,   194400, 0xe0a1ce1f
+0,        229,        229,        1,   194400, 0x8fdbd617
+0,        230,        230,        1,   194400, 0xd68fe805
+0,        232,        232,        1,   194400, 0x0d1dfbf1
+0,        233,        233,        1,   194400, 0x0fe70bf0
+0,        235,        235,        1,   194400, 0x0a8f13e8
+0,        236,        236,        1,   194400, 0x0ca42bd0
+0,        238,        238,        1,   194400, 0x6f3838c3
+0,        239,        239,        1,   194400, 0x045448b3
+0,        241,        241,        1,   194400, 0x764349b2
+0,        242,        242,        1,   194400, 0xed1651aa
+0,        244,        244,        1,   194400, 0xbb376398
+0,        245,        245,        1,   194400, 0xd0d5718a
+0,        247,        247,        1,   194400, 0xcd977e7d
+0,        248,        248,        1,   194400, 0x8cb39665
+0,        250,        250,        1,   194400, 0xb935b04b
+0,        251,        251,        1,   194400, 0x0292be3d
+0,        253,        253,        1,   194400, 0x4f21c833
+0,        254,        254,        1,   194400, 0xa5c7d823
+0,        256,        256,        1,   194400, 0xfb8ee01b
+0,        257,        257,        1,   194400, 0xea53ee0d
+0,        259,        259,        1,   194400, 0x803efcfe
+0,        260,        260,        1,   194400, 0x2c0e0aff
+0,        262,        262,        1,   194400, 0x3df318f1
+0,        263,        263,        1,   194400, 0xc4cb26e3
+0,        265,        265,        1,   194400, 0x92a033d6
+0,        266,        266,        1,   194400, 0x1b2048c1
+0,        268,        268,        1,   194400, 0x236858b1
+0,        269,        269,        1,   194400, 0x482f6d9c
+0,        271,        271,        1,   194400, 0x9ee97891
+0,        272,        272,        1,   194400, 0xe0dc8683
+0,        274,        274,        1,   194400, 0x461b9079
+0,        275,        275,        1,   194400, 0xd346a960
+0,        277,        277,        1,   194400, 0xa384b554
+0,        278,        278,        1,   194400, 0x3246cf3a
+0,        280,        280,        1,   194400, 0xa53fe722
+0,        281,        281,        1,   194400, 0xe620fd0c
+0,        283,        283,        1,   194400, 0xd6370414
+0,        284,        284,        1,   194400, 0xf57f1404
+0,        286,        286,        1,   194400, 0x8c6420f7
+0,        287,        287,        1,   194400, 0xd4be3add
+0,        289,        289,        1,   194400, 0xa8dc4ec9
+0,        290,        290,        1,   194400, 0xda1563b4
+0,        292,        292,        1,   194400, 0xd51873a4
+0,        293,        293,        1,   194400, 0x68588196
+0,        295,        295,        1,   194400, 0x40d18e89
+0,        296,        296,        1,   194400, 0x1b75a275
+0,        298,        298,        1,   194400, 0xedd1a572
+0,        299,        299,        1,   194400, 0x55daad6a
diff --git a/tests/ref/fate/cdxl-bitline-ham6 b/tests/ref/fate/cdxl-bitline-ham6
index e4071a9..8060f06 100644
--- a/tests/ref/fate/cdxl-bitline-ham6
+++ b/tests/ref/fate/cdxl-bitline-ham6
@@ -1,11 +1,11 @@
-#tb 0: 1/11025
-0,          0,          0,        0,    63180, 0xcda82c16
-0,        220,        220,        0,    63180, 0xa6097bf9
-0,        440,        440,        0,    63180, 0x4c2fb091
-0,        660,        660,        0,    63180, 0xc597db00
-0,        880,        880,        0,    63180, 0xfa581ccd
-0,       1100,       1100,        0,    63180, 0x3e51498f
-0,       1320,       1320,        0,    63180, 0xe3495396
-0,       1540,       1540,        0,    63180, 0x425f5f02
-0,       1760,       1760,        0,    63180, 0x6077465f
-0,       1980,       1980,        0,    63180, 0x923ba29c
+#tb 0: 12/601
+0,          0,          0,        1,    63180, 0xcda82c16
+0,          1,          1,        1,    63180, 0xa6097bf9
+0,          2,          2,        1,    63180, 0x4c2fb091
+0,          3,          3,        1,    63180, 0xc597db00
+0,          4,          4,        1,    63180, 0xfa581ccd
+0,          5,          5,        1,    63180, 0x3e51498f
+0,          6,          6,        1,    63180, 0xe3495396
+0,          7,          7,        1,    63180, 0x425f5f02
+0,          8,          8,        1,    63180, 0x6077465f
+0,          9,          9,        1,    63180, 0x923ba29c
diff --git a/tests/ref/fate/cdxl-ham6 b/tests/ref/fate/cdxl-ham6
index 25886b2..6426d45 100644
--- a/tests/ref/fate/cdxl-ham6
+++ b/tests/ref/fate/cdxl-ham6
@@ -1,17 +1,17 @@
-#tb 0: 1/11025
-0,          0,          0,        0,    57600, 0x87887a7b
-0,       1092,       1092,        0,    57600, 0x10c301d2
-0,       2184,       2184,        0,    57600, 0xd1a6f910
-0,       3276,       3276,        0,    57600, 0x20242bb9
-0,       4368,       4368,        0,    57600, 0xae33cb7f
-0,       5460,       5460,        0,    57600, 0x501b82c8
-0,       6552,       6552,        0,    57600, 0x84199043
-0,       7644,       7644,        0,    57600, 0x946a6dbb
-0,       8736,       8736,        0,    57600, 0xeacea671
-0,       9828,       9828,        0,    57600, 0x77b8723f
-0,      10920,      10920,        0,    57600, 0x371cdb09
-0,      12012,      12012,        0,    57600, 0xa16ef5ee
-0,      13104,      13104,        0,    57600, 0xcb6abd9e
-0,      14196,      14196,        0,    57600, 0xb73e800f
-0,      15288,      15288,        0,    57600, 0x368bd93e
-0,      16380,      16380,        0,    57600, 0xcde72dc5
+#tb 0: 52/525
+0,          0,          0,        1,    57600, 0x87887a7b
+0,          1,          1,        1,    57600, 0x10c301d2
+0,          2,          2,        1,    57600, 0xd1a6f910
+0,          3,          3,        1,    57600, 0x20242bb9
+0,          4,          4,        1,    57600, 0xae33cb7f
+0,          5,          5,        1,    57600, 0x501b82c8
+0,          6,          6,        1,    57600, 0x84199043
+0,          7,          7,        1,    57600, 0x946a6dbb
+0,          8,          8,        1,    57600, 0xeacea671
+0,          9,          9,        1,    57600, 0x77b8723f
+0,         10,         10,        1,    57600, 0x371cdb09
+0,         11,         11,        1,    57600, 0xa16ef5ee
+0,         12,         12,        1,    57600, 0xcb6abd9e
+0,         13,         13,        1,    57600, 0xb73e800f
+0,         14,         14,        1,    57600, 0x368bd93e
+0,         15,         15,        1,    57600, 0xcde72dc5
diff --git a/tests/ref/fate/cdxl-ham8 b/tests/ref/fate/cdxl-ham8
index 356ad1b..269f1f3 100644
--- a/tests/ref/fate/cdxl-ham8
+++ b/tests/ref/fate/cdxl-ham8
@@ -1,2 +1,2 @@
-#tb 0: 1/11025
-0,          0,          0,        0,    67584, 0xce0cade5
+#tb 0: 3/158
+0,          0,          0,        1,    67584, 0xce0cade5
diff --git a/tests/ref/fate/cdxl-pal8 b/tests/ref/fate/cdxl-pal8
index f5c319a..82d4d63 100644
--- a/tests/ref/fate/cdxl-pal8
+++ b/tests/ref/fate/cdxl-pal8
@@ -1,12 +1,12 @@
-#tb 0: 1/11025
-0,          0,          0,        0,    67584, 0x5eae629b
-0,        220,        220,        0,    67584, 0x32591227
-0,        440,        440,        0,    67584, 0x4e4424c7
-0,        660,        660,        0,    67584, 0x70db0134
-0,        880,        880,        0,    67584, 0x3550ed0b
-0,       1100,       1100,        0,    67584, 0x86fe3eef
-0,       1320,       1320,        0,    67584, 0x3414bb33
-0,       1540,       1540,        0,    67584, 0x667bfb91
-0,       1760,       1760,        0,    67584, 0x6e1a4ccb
-0,       1980,       1980,        0,    67584, 0xf723f9ae
-0,       2200,       2200,        0,    67584, 0x88481d5d
+#tb 0: 12/601
+0,          0,          0,        1,    67584, 0x5eae629b
+0,          1,          1,        1,    67584, 0x32591227
+0,          2,          2,        1,    67584, 0x4e4424c7
+0,          3,          3,        1,    67584, 0x70db0134
+0,          4,          4,        1,    67584, 0x3550ed0b
+0,          5,          5,        1,    67584, 0x86fe3eef
+0,          6,          6,        1,    67584, 0x3414bb33
+0,          7,          7,        1,    67584, 0x667bfb91
+0,          8,          8,        1,    67584, 0x6e1a4ccb
+0,          9,          9,        1,    67584, 0xf723f9ae
+0,         10,         10,        1,    67584, 0x88481d5d
diff --git a/tests/ref/fate/cdxl-pal8-small b/tests/ref/fate/cdxl-pal8-small
index d285e9a..f7a1a46 100644
--- a/tests/ref/fate/cdxl-pal8-small
+++ b/tests/ref/fate/cdxl-pal8-small
@@ -1,47 +1,47 @@
-#tb 0: 1/11025
-0,          0,          0,        0,    30720, 0x0d552cfd
-0,        368,        368,        0,    30720, 0x3cf93291
-0,        736,        736,        0,    30720, 0xe45b2868
-0,       1104,       1104,        0,    30720, 0xb5df289b
-0,       1472,       1472,        0,    30720, 0x2562259e
-0,       1840,       1840,        0,    30720, 0xbf171878
-0,       2208,       2208,        0,    30720, 0x695b1d73
-0,       2576,       2576,        0,    30720, 0x89ef1614
-0,       2944,       2944,        0,    30720, 0xe12a1dd9
-0,       3312,       3312,        0,    30720, 0x49622ffa
-0,       3680,       3680,        0,    30720, 0xd6832703
-0,       4048,       4048,        0,    30720, 0xec1d0cb7
-0,       4416,       4416,        0,    30720, 0x8bee0525
-0,       4784,       4784,        0,    30720, 0x1e0cf0c4
-0,       5152,       5152,        0,    30720, 0xf83fd9db
-0,       5520,       5520,        0,    30720, 0xffb0d6ab
-0,       5888,       5888,        0,    30720, 0xe37fe239
-0,       6256,       6256,        0,    30720, 0x74b0f856
-0,       6624,       6624,        0,    30720, 0x9c88d3e1
-0,       6992,       6992,        0,    30720, 0x714db368
-0,       7360,       7360,        0,    30720, 0x6c8e8860
-0,       7728,       7728,        0,    30720, 0x804968e6
-0,       8096,       8096,        0,    30720, 0x7ac56ae4
-0,       8464,       8464,        0,    30720, 0xffd85cbf
-0,       8832,       8832,        0,    30720, 0x1f8455f9
-0,       9200,       9200,        0,    30720, 0x3ae65296
-0,       9568,       9568,        0,    30720, 0x9e544ecd
-0,       9936,       9936,        0,    30720, 0x35678e5a
-0,      10304,      10304,        0,    30720, 0x04bae866
-0,      10672,      10672,        0,    30720, 0xb126ed94
-0,      11040,      11040,        0,    30720, 0x1720efc5
-0,      11408,      11408,        0,    30720, 0x4c1b01c2
-0,      11776,      11776,        0,    30720, 0xd0a1e866
-0,      12144,      12144,        0,    30720, 0x0d330789
-0,      12512,      12512,        0,    30720, 0xf5ac08bb
-0,      12880,      12880,        0,    30720, 0x9abe0d83
-0,      13248,      13248,        0,    30720, 0xa44c02f4
-0,      13616,      13616,        0,    30720, 0xdc4cc688
-0,      13984,      13984,        0,    30720, 0x22eef3c1
-0,      14352,      14352,        0,    30720, 0xcfbc0d1d
-0,      14720,      14720,        0,    30720, 0x7104ea31
-0,      15088,      15088,        0,    30720, 0x80daecfb
-0,      15456,      15456,        0,    30720, 0xe1bab995
-0,      15824,      15824,        0,    30720, 0x43f4b896
-0,      16192,      16192,        0,    30720, 0xa0d2bf5c
-0,      16560,      16560,        0,    30720, 0x3556a114
+#tb 0: 368/11025
+0,          0,          0,        1,    30720, 0x0d552cfd
+0,          1,          1,        1,    30720, 0x3cf93291
+0,          2,          2,        1,    30720, 0xe45b2868
+0,          3,          3,        1,    30720, 0xb5df289b
+0,          4,          4,        1,    30720, 0x2562259e
+0,          5,          5,        1,    30720, 0xbf171878
+0,          6,          6,        1,    30720, 0x695b1d73
+0,          7,          7,        1,    30720, 0x89ef1614
+0,          8,          8,        1,    30720, 0xe12a1dd9
+0,          9,          9,        1,    30720, 0x49622ffa
+0,         10,         10,        1,    30720, 0xd6832703
+0,         11,         11,        1,    30720, 0xec1d0cb7
+0,         12,         12,        1,    30720, 0x8bee0525
+0,         13,         13,        1,    30720, 0x1e0cf0c4
+0,         14,         14,        1,    30720, 0xf83fd9db
+0,         15,         15,        1,    30720, 0xffb0d6ab
+0,         16,         16,        1,    30720, 0xe37fe239
+0,         17,         17,        1,    30720, 0x74b0f856
+0,         18,         18,        1,    30720, 0x9c88d3e1
+0,         19,         19,        1,    30720, 0x714db368
+0,         20,         20,        1,    30720, 0x6c8e8860
+0,         21,         21,        1,    30720, 0x804968e6
+0,         22,         22,        1,    30720, 0x7ac56ae4
+0,         23,         23,        1,    30720, 0xffd85cbf
+0,         24,         24,        1,    30720, 0x1f8455f9
+0,         25,         25,        1,    30720, 0x3ae65296
+0,         26,         26,        1,    30720, 0x9e544ecd
+0,         27,         27,        1,    30720, 0x35678e5a
+0,         28,         28,        1,    30720, 0x04bae866
+0,         29,         29,        1,    30720, 0xb126ed94
+0,         30,         30,        1,    30720, 0x1720efc5
+0,         31,         31,        1,    30720, 0x4c1b01c2
+0,         32,         32,        1,    30720, 0xd0a1e866
+0,         33,         33,        1,    30720, 0x0d330789
+0,         34,         34,        1,    30720, 0xf5ac08bb
+0,         35,         35,        1,    30720, 0x9abe0d83
+0,         36,         36,        1,    30720, 0xa44c02f4
+0,         37,         37,        1,    30720, 0xdc4cc688
+0,         38,         38,        1,    30720, 0x22eef3c1
+0,         39,         39,        1,    30720, 0xcfbc0d1d
+0,         40,         40,        1,    30720, 0x7104ea31
+0,         41,         41,        1,    30720, 0x80daecfb
+0,         42,         42,        1,    30720, 0xe1bab995
+0,         43,         43,        1,    30720, 0x43f4b896
+0,         44,         44,        1,    30720, 0xa0d2bf5c
+0,         45,         45,        1,    30720, 0x3556a114
diff --git a/tests/ref/fate/cljr b/tests/ref/fate/cljr
index f73c8c0..5842541 100644
--- a/tests/ref/fate/cljr
+++ b/tests/ref/fate/cljr
@@ -1,37 +1,37 @@
 #tb 0: 3521/100000
-0,          0,          0,        1,    64800, 0x44a1c47c
-0,          1,          1,        1,    64800, 0x649cc3a4
-0,          2,          2,        1,    64800, 0xcab1b88c
-0,          3,          3,        1,    64800, 0xf56cb788
-0,          4,          4,        1,    64800, 0x5336b618
-0,          5,          5,        1,    64800, 0x2704b438
-0,          6,          6,        1,    64800, 0x04c7b8e4
-0,          7,          7,        1,    64800, 0x3185b288
-0,          8,          8,        1,    64800, 0xa537c410
-0,          9,          9,        1,    64800, 0x6495c0f8
-0,         10,         10,        1,    64800, 0x06a1ca14
-0,         11,         11,        1,    64800, 0x69cdd2a0
-0,         12,         12,        1,    64800, 0x4ad2d828
-0,         13,         13,        1,    64800, 0x9604dea4
-0,         14,         14,        1,    64800, 0x1c00e430
-0,         15,         15,        1,    64800, 0x9afeefe0
-0,         16,         16,        1,    64800, 0xc13fdd78
-0,         17,         17,        1,    64800, 0x8438da7c
-0,         18,         18,        1,    64800, 0xa0ead278
-0,         19,         19,        1,    64800, 0xbeced2d8
-0,         20,         20,        1,    64800, 0x85bbd7dc
-0,         21,         21,        1,    64800, 0xbe59ce34
-0,         22,         22,        1,    64800, 0xd76ecccc
-0,         23,         23,        1,    64800, 0xe182b474
-0,         24,         24,        1,    64800, 0x916cc394
-0,         25,         25,        1,    64800, 0x7efebd14
-0,         26,         26,        1,    64800, 0x8d28c9f0
-0,         27,         27,        1,    64800, 0x00a1c960
-0,         28,         28,        1,    64800, 0xc164c400
-0,         29,         29,        1,    64800, 0xfd4dc544
-0,         30,         30,        1,    64800, 0x01bfbe38
-0,         31,         31,        1,    64800, 0xff11b5d0
-0,         32,         32,        1,    64800, 0x4876bb20
-0,         33,         33,        1,    64800, 0x756ecb04
-0,         34,         34,        1,    64800, 0x3b8cd540
-0,         35,         35,        1,    64800, 0x063ed444
+0,          0,          0,        1,    64800, 0x63132a60
+0,          1,          1,        1,    64800, 0xb3c729a3
+0,          2,          2,        1,    64800, 0xa27b1e0e
+0,          3,          3,        1,    64800, 0xb9131d00
+0,          4,          4,        1,    64800, 0xaf9a1bae
+0,          5,          5,        1,    64800, 0x11e319c5
+0,          6,          6,        1,    64800, 0xee6e1e6b
+0,          7,          7,        1,    64800, 0x418417e9
+0,          8,          8,        1,    64800, 0x339d29f4
+0,          9,          9,        1,    64800, 0x198926c4
+0,         10,         10,        1,    64800, 0x439a3044
+0,         11,         11,        1,    64800, 0x0a4e38e1
+0,         12,         12,        1,    64800, 0x6e043e7e
+0,         13,         13,        1,    64800, 0xde434533
+0,         14,         14,        1,    64800, 0xb58a4ad1
+0,         15,         15,        1,    64800, 0xaa105710
+0,         16,         16,        1,    64800, 0x1723440c
+0,         17,         17,        1,    64800, 0x3b064116
+0,         18,         18,        1,    64800, 0x853f38e4
+0,         19,         19,        1,    64800, 0x52f53917
+0,         20,         20,        1,    64800, 0xea363e5a
+0,         21,         21,        1,    64800, 0x4d0a344e
+0,         22,         22,        1,    64800, 0xe49232fc
+0,         23,         23,        1,    64800, 0x747b1a02
+0,         24,         24,        1,    64800, 0xbaa82992
+0,         25,         25,        1,    64800, 0x8e9322db
+0,         26,         26,        1,    64800, 0x029a2fcf
+0,         27,         27,        1,    64800, 0xb9a62f6a
+0,         28,         28,        1,    64800, 0x553329fe
+0,         29,         29,        1,    64800, 0x9a052b5b
+0,         30,         30,        1,    64800, 0xe2ff2404
+0,         31,         31,        1,    64800, 0xaacd1b59
+0,         32,         32,        1,    64800, 0x17d820de
+0,         33,         33,        1,    64800, 0x1c9e312c
+0,         34,         34,        1,    64800, 0x84df3b99
+0,         35,         35,        1,    64800, 0xf7d13aa1
diff --git a/tests/ref/fate/cllc-argb b/tests/ref/fate/cllc-argb
index 0283863..4a5dce5 100644
--- a/tests/ref/fate/cllc-argb
+++ b/tests/ref/fate/cllc-argb
@@ -3,3 +3,4 @@
 0,          1,          1,        1,  3686400, 0x66a45032
 0,          2,          2,        1,  3686400, 0xdf0c861f
 0,          3,          3,        1,  3686400, 0xa4a68cdb
+0,          4,          4,        1,  3686400, 0xb5f9526e
diff --git a/tests/ref/fate/cllc-rgb b/tests/ref/fate/cllc-rgb
index 06d54da..b4ca055 100644
--- a/tests/ref/fate/cllc-rgb
+++ b/tests/ref/fate/cllc-rgb
@@ -13,3 +13,4 @@
 0,         11,         11,        1,   921600, 0x4d7488fa
 0,         12,         12,        1,   921600, 0x16b9c9c9
 0,         13,         13,        1,   921600, 0xa0a4f77f
+0,         14,         14,        1,   921600, 0xf61a5501
diff --git a/tests/ref/fate/creatureshock-avs b/tests/ref/fate/creatureshock-avs
index 979baf6..4c721d8 100644
--- a/tests/ref/fate/creatureshock-avs
+++ b/tests/ref/fate/creatureshock-avs
@@ -1,94 +1,94 @@
-#tb 0: 1/90000
+#tb 0: 1/15
 #tb 1: 1/22222
-0,          0,          0,        0,   188892, 0xcb5be3dd
+0,          0,          0,        1,   188892, 0x9f47a5ec
 1,          0,          0,     8186,    16372, 0xfaaab59d
-0,       6000,       6000,        0,   188892, 0x0f313ebc
-0,      12000,      12000,        0,   188892, 0xc0da25cc
-0,      18000,      18000,        0,   188892, 0xad6e1d44
-0,      24000,      24000,        0,   188892, 0xb1103b40
-0,      30000,      30000,        0,   188892, 0xae033450
+0,          1,          1,        1,   188892, 0xdece0269
+0,          2,          2,        1,   188892, 0xd097e86e
+0,          3,          3,        1,   188892, 0x1cf2de83
+0,          4,          4,        1,   188892, 0xb664fd10
+0,          5,          5,        1,   188892, 0xc654f4c1
 1,       8186,       8186,     2014,     4028, 0xc2daed72
-0,      36000,      36000,        0,   188892, 0xb31f03b4
+0,          6,          6,        1,   188892, 0x5adac3ff
 1,      10200,      10200,     2743,     5486, 0xf7fd794d
-0,      42000,      42000,        0,   188892, 0xacb2d3f9
-0,      48000,      48000,        0,   188892, 0x7d77ecbd
+0,          7,          7,        1,   188892, 0x5928954e
+0,          8,          8,        1,   188892, 0x5e4cad6c
 1,      12943,      12943,     2895,     5790, 0xfd5a369f
-0,      54000,      54000,        0,   188892, 0x7faa2f6c
-0,      60000,      60000,        0,   188892, 0x28f4fdf1
+0,          9,          9,        1,   188892, 0xbbb5f11b
+0,         10,         10,        1,   188892, 0xcb6bbdee
 1,      15838,      15838,      534,     1068, 0x0b602cd0
-0,      66000,      66000,        0,   188892, 0x4b53f3b9
+0,         11,         11,        1,   188892, 0xa5b3b316
 1,      16372,      16372,     2454,     4908, 0xfe870aad
-0,      72000,      72000,        0,   188892, 0x1f09bb29
+0,         12,         12,        1,   188892, 0x9bf87b5d
 1,      18826,      18826,     3031,     6062, 0x8a4d6e0f
-0,      78000,      78000,        0,   188892, 0x3afcc11d
-0,      84000,      84000,        0,   188892, 0x6b918e49
+0,         13,         13,        1,   188892, 0xcc3981be
+0,         14,         14,        1,   188892, 0x2eb44dfa
 1,      21857,      21857,     2701,     5402, 0x71fd352f
-0,      90000,      90000,        0,   188892, 0x9630a04d
-0,      96000,      96000,        0,   188892, 0x9381b4c1
+0,         15,         15,        1,   188892, 0x11c861b9
+0,         16,         16,        1,   188892, 0x7c1b767b
 1,      24558,      24558,      272,      544, 0xeb766d34
 1,      24830,      24830,     2953,     5906, 0x47ac7e08
-0,     102000,     102000,        0,   188892, 0xa7dea7e5
-0,     108000,     108000,        0,   188892, 0xd277c41d
+0,         17,         17,        1,   188892, 0x5078694c
+0,         18,         18,        1,   188892, 0xa24485c2
 1,      27783,      27783,     2958,     5916, 0x0d26eb56
-0,     114000,     114000,        0,   188892, 0xafa2a6c9
-0,     120000,     120000,        0,   188892, 0x13a38839
+0,         19,         19,        1,   188892, 0xc8016946
+0,         20,         20,        1,   188892, 0x71e3493b
 1,      30741,      30741,     2003,     4006, 0x9941c71a
-0,     126000,     126000,        0,   188892, 0xcd5e5a6d
-0,     132000,     132000,        0,   188892, 0xe7da71e9
+0,         21,         21,        1,   188892, 0xa9771a0d
+0,         22,         22,        1,   188892, 0x98be33fd
 1,      32744,      32744,     1050,     2100, 0xc9a2ee36
 1,      33794,      33794,     2947,     5894, 0xd2ba4eaa
-0,     138000,     138000,        0,   188892, 0x06928add
-0,     144000,     144000,        0,   188892, 0x4a108eb9
+0,         23,         23,        1,   188892, 0x193e4cda
+0,         24,         24,        1,   188892, 0x3b444fd1
 1,      36741,      36741,     3045,     6090, 0xf43e73d0
-0,     150000,     150000,        0,   188892, 0xea2598f5
-0,     156000,     156000,        0,   188892, 0x17ed6839
+0,         25,         25,        1,   188892, 0x8bfe594c
+0,         26,         26,        1,   188892, 0xaab8267b
 1,      39786,      39786,     1144,     2288, 0x5a8b7aa0
-0,     162000,     162000,        0,   188892, 0x9de6ab65
+0,         27,         27,        1,   188892, 0x03206c55
 1,      40930,      40930,     1925,     3850, 0x7f66eb2c
-0,     168000,     168000,        0,   188892, 0xb4ee326f
+0,         28,         28,        1,   188892, 0x8ed7ea7d
 1,      42855,      42855,     2898,     5796, 0xc5cf3ee8
-0,     174000,     174000,        0,   188892, 0x3f85095b
-0,     180000,     180000,        0,   188892, 0xaab7e331
+0,         29,         29,        1,   188892, 0x2a1bc3e1
+0,         30,         30,        1,   188892, 0xa6a12aa7
 1,      45753,      45753,     3021,     6042, 0xed80136d
-0,     186000,     186000,        0,   188892, 0xc2a079e1
-0,     192000,     192000,        0,   188892, 0x612080c2
+0,         31,         31,        1,   188892, 0xa96ca4fa
+0,         32,         32,        1,   188892, 0x3e3a6d70
 1,      48774,      48774,      342,      684, 0xc42bd137
-0,     198000,     198000,        0,   188892, 0xa7232d47
+0,         33,         33,        1,   188892, 0x47e173dd
 1,      49116,      49116,     2718,     5436, 0xb7f8a6fd
-0,     204000,     204000,        0,   188892, 0xc053297d
+0,         34,         34,        1,   188892, 0xfcf183ba
 1,      51834,      51834,     3049,     6098, 0xee6354a2
-0,     210000,     210000,        0,   188892, 0x1ecc3bfe
-0,     216000,     216000,        0,   188892, 0xcc4ac803
-0,     222000,     222000,        0,   188892, 0x4b90047b
+0,         35,         35,        1,   188892, 0xf051be46
+0,         36,         36,        1,   188892, 0x8aa6b100
+0,         37,         37,        1,   188892, 0x36c86b01
 1,      54883,      54883,     2419,     4838, 0x129e61d0
-0,     228000,     228000,        0,   188892, 0xd863b643
+0,         38,         38,        1,   188892, 0x15ae396e
 1,      57302,      57302,      537,     1074, 0x9da90634
-0,     234000,     234000,        0,   188892, 0x93a25fb1
+0,         39,         39,        1,   188892, 0xc876eabf
 1,      57839,      57839,     3042,     6084, 0x8ffed952
-0,     240000,     240000,        0,   188892, 0xf969e131
-0,     246000,     246000,        0,   188892, 0x73bd2469
+0,         40,         40,        1,   188892, 0xc5c65fae
+0,         41,         41,        1,   188892, 0x4feec932
 1,      60881,      60881,     3019,     6038, 0xa07b4276
-0,     252000,     252000,        0,   188892, 0x265a9ce2
-0,     258000,     258000,        0,   188892, 0xd59ccd39
+0,         42,         42,        1,   188892, 0x21374e88
+0,         43,         43,        1,   188892, 0x52e689f1
 1,      63900,      63900,     1588,     3176, 0xebef63c1
-0,     264000,     264000,        0,   188892, 0xe50fc068
+0,         44,         44,        1,   188892, 0x9e2492e8
 1,      65488,      65488,     1397,     2794, 0xbe1000db
-0,     270000,     270000,        0,   188892, 0x83113a86
+0,         45,         45,        1,   188892, 0xac841247
 1,      66885,      66885,     3010,     6020, 0xd8e34961
-0,     276000,     276000,        0,   188892, 0xa0203504
-0,     282000,     282000,        0,   188892, 0x9e2d518c
+0,         46,         46,        1,   188892, 0x8467aab2
+0,         47,         47,        1,   188892, 0x552b6029
 1,      69895,      69895,     3010,     6020, 0xc07cf461
-0,     288000,     288000,        0,   188892, 0x5f610e66
-0,     294000,     294000,        0,   188892, 0x9b77f900
+0,         48,         48,        1,   188892, 0x836eb46e
+0,         49,         49,        1,   188892, 0x93eb9f1b
 1,      72905,      72905,      769,     1538, 0xc975ae02
 1,      73674,      73674,     2115,     4230, 0x0827111b
-0,     300000,     300000,        0,   188892, 0xaaf279c2
-0,     306000,     306000,        0,   188892, 0x4ac97cc2
+0,         50,         50,        1,   188892, 0xa3661fdd
+0,         51,         51,        1,   188892, 0x433d22dd
 1,      75789,      75789,     3042,     6084, 0x2cf0a407
-0,     312000,     312000,        0,   188892, 0xddd91642
-0,     318000,     318000,        0,   188892, 0x4f32dcd1
+0,         52,         52,        1,   188892, 0xd64dbc4e
+0,         53,         53,        1,   188892, 0x4a2aa0e3
 1,      78831,      78831,     2914,     5828, 0x12750279
-0,     324000,     324000,        0,   188892, 0xdc126b42
-0,     330000,     330000,        0,   188892, 0x00000000
+0,         54,         54,        1,   188892, 0xd98e4d4b
+0,         55,         55,        1,   188892, 0x00000000
 1,      81745,      81745,      115,      230, 0xc9c03f3b
 1,      81860,      81860,      384,      768, 0x6137a04d
diff --git a/tests/ref/fate/cvid-palette b/tests/ref/fate/cvid-palette
index 5fcbc51..49de1c1 100644
--- a/tests/ref/fate/cvid-palette
+++ b/tests/ref/fate/cvid-palette
@@ -1,57 +1,57 @@
-#tb 0: 1/14985
-0,          0,          0,        0,    57600, 0x1f5c89b7
-0,       1000,       1000,        0,    57600, 0xd2055aaf
-0,       2000,       2000,        0,    57600, 0x22336052
-0,       3000,       3000,        0,    57600, 0xf7135e2a
-0,       4000,       4000,        0,    57600, 0xd9de126a
-0,       5000,       5000,        0,    57600, 0xe5a9e1de
-0,       6000,       6000,        0,    57600, 0x253f1702
-0,       7000,       7000,        0,    57600, 0xcb8679c9
-0,       8000,       8000,        0,    57600, 0x96cb5fa8
-0,       9000,       9000,        0,    57600, 0xbe03528a
-0,      10000,      10000,        0,    57600, 0x120a097d
-0,      11000,      11000,        0,    57600, 0xaf562041
-0,      12000,      12000,        0,    57600, 0x15b2d8c9
-0,      13000,      13000,        0,    57600, 0x95f60e58
-0,      14000,      14000,        0,    57600, 0x5ace5a6b
-0,      15000,      15000,        0,    57600, 0x2f80b8e3
-0,      16000,      16000,        0,    57600, 0x5c49c915
-0,      17000,      17000,        0,    57600, 0xb91efe60
-0,      18000,      18000,        0,    57600, 0xa80d29e8
-0,      19000,      19000,        0,    57600, 0x6e72d03a
-0,      20000,      20000,        0,    57600, 0x4f716a9e
-0,      21000,      21000,        0,    57600, 0x3a43b9c9
-0,      22000,      22000,        0,    57600, 0x65002db3
-0,      23000,      23000,        0,    57600, 0x70edc765
-0,      24000,      24000,        0,    57600, 0x9dc54abd
-0,      25000,      25000,        0,    57600, 0xd17bda86
-0,      26000,      26000,        0,    57600, 0xc5d2d458
-0,      27000,      27000,        0,    57600, 0x32313c79
-0,      28000,      28000,        0,    57600, 0x2e537e8d
-0,      29000,      29000,        0,    57600, 0xe77d5d9e
-0,      30000,      30000,        0,    57600, 0x9cc2599a
-0,      31000,      31000,        0,    57600, 0x8a9be76e
-0,      32000,      32000,        0,    57600, 0x47447eef
-0,      33000,      33000,        0,    57600, 0xbf5f84fa
-0,      34000,      34000,        0,    57600, 0xacd49c07
-0,      35000,      35000,        0,    57600, 0xdc628975
-0,      36000,      36000,        0,    57600, 0x97d7964e
-0,      37000,      37000,        0,    57600, 0xd0a19b6b
-0,      38000,      38000,        0,    57600, 0x5ea3d78c
-0,      39000,      39000,        0,    57600, 0x39b59be0
-0,      40000,      40000,        0,    57600, 0x6501a2d2
-0,      41000,      41000,        0,    57600, 0x0ee7e36d
-0,      42000,      42000,        0,    57600, 0x354ddd1d
-0,      43000,      43000,        0,    57600, 0x9b8f22d3
-0,      44000,      44000,        0,    57600, 0x0aadfb8c
-0,      45000,      45000,        0,    57600, 0x322e2785
-0,      46000,      46000,        0,    57600, 0x78a6467e
-0,      47000,      47000,        0,    57600, 0x1757f3b1
-0,      48000,      48000,        0,    57600, 0xe874ceb7
-0,      49000,      49000,        0,    57600, 0xc40f9e4d
-0,      50000,      50000,        0,    57600, 0x89f6a735
-0,      51000,      51000,        0,    57600, 0xe3635393
-0,      52000,      52000,        0,    57600, 0xdae585c7
-0,      53000,      53000,        0,    57600, 0xf99baa60
-0,      54000,      54000,        0,    57600, 0x28a8b1ee
-0,      55000,      55000,        0,    57600, 0xcd5587f8
+#tb 0: 200/2997
+0,          0,          0,        1,    57600, 0x1f5c89b7
+0,          1,          1,        1,    57600, 0xd2055aaf
+0,          2,          2,        1,    57600, 0x22336052
+0,          3,          3,        1,    57600, 0xf7135e2a
+0,          4,          4,        1,    57600, 0xd9de126a
+0,          5,          5,        1,    57600, 0xe5a9e1de
+0,          6,          6,        1,    57600, 0x253f1702
+0,          7,          7,        1,    57600, 0xcb8679c9
+0,          8,          8,        1,    57600, 0x96cb5fa8
+0,          9,          9,        1,    57600, 0xbe03528a
+0,         10,         10,        1,    57600, 0x120a097d
+0,         11,         11,        1,    57600, 0xaf562041
+0,         12,         12,        1,    57600, 0x15b2d8c9
+0,         13,         13,        1,    57600, 0x95f60e58
+0,         14,         14,        1,    57600, 0x5ace5a6b
+0,         15,         15,        1,    57600, 0x2f80b8e3
+0,         16,         16,        1,    57600, 0x5c49c915
+0,         17,         17,        1,    57600, 0xb91efe60
+0,         18,         18,        1,    57600, 0xa80d29e8
+0,         19,         19,        1,    57600, 0x6e72d03a
+0,         20,         20,        1,    57600, 0x4f716a9e
+0,         21,         21,        1,    57600, 0x3a43b9c9
+0,         22,         22,        1,    57600, 0x65002db3
+0,         23,         23,        1,    57600, 0x70edc765
+0,         24,         24,        1,    57600, 0x9dc54abd
+0,         25,         25,        1,    57600, 0xd17bda86
+0,         26,         26,        1,    57600, 0xc5d2d458
+0,         27,         27,        1,    57600, 0x32313c79
+0,         28,         28,        1,    57600, 0x2e537e8d
+0,         29,         29,        1,    57600, 0xe77d5d9e
+0,         30,         30,        1,    57600, 0x9cc2599a
+0,         31,         31,        1,    57600, 0x8a9be76e
+0,         32,         32,        1,    57600, 0x47447eef
+0,         33,         33,        1,    57600, 0xbf5f84fa
+0,         34,         34,        1,    57600, 0xacd49c07
+0,         35,         35,        1,    57600, 0xdc628975
+0,         36,         36,        1,    57600, 0x97d7964e
+0,         37,         37,        1,    57600, 0xd0a19b6b
+0,         38,         38,        1,    57600, 0x5ea3d78c
+0,         39,         39,        1,    57600, 0x39b59be0
+0,         40,         40,        1,    57600, 0x6501a2d2
+0,         41,         41,        1,    57600, 0x0ee7e36d
+0,         42,         42,        1,    57600, 0x354ddd1d
+0,         43,         43,        1,    57600, 0x9b8f22d3
+0,         44,         44,        1,    57600, 0x0aadfb8c
+0,         45,         45,        1,    57600, 0x322e2785
+0,         46,         46,        1,    57600, 0x78a6467e
+0,         47,         47,        1,    57600, 0x1757f3b1
+0,         48,         48,        1,    57600, 0xe874ceb7
+0,         49,         49,        1,    57600, 0xc40f9e4d
+0,         50,         50,        1,    57600, 0x89f6a735
+0,         51,         51,        1,    57600, 0xe3635393
+0,         52,         52,        1,    57600, 0xdae585c7
+0,         53,         53,        1,    57600, 0xf99baa60
+0,         54,         54,        1,    57600, 0x28a8b1ee
+0,         55,         55,        1,    57600, 0xcd5587f8
diff --git a/tests/ref/fate/cvid-partial b/tests/ref/fate/cvid-partial
index 71596b4..907ef4a 100644
--- a/tests/ref/fate/cvid-partial
+++ b/tests/ref/fate/cvid-partial
@@ -77,3 +77,4 @@
 0,         75,         75,        1,   112400, 0xe4394f1f
 0,         76,         76,        1,   112400, 0x8ca8649f
 0,         77,         77,        1,   112400, 0x804d44eb
+0,         78,         78,        1,   112400, 0x3864488b
diff --git a/tests/ref/fate/d-cinema-demux b/tests/ref/fate/d-cinema-demux
index f663040..2f28e46 100644
--- a/tests/ref/fate/d-cinema-demux
+++ b/tests/ref/fate/d-cinema-demux
@@ -2,4 +2,4 @@
 0,          0,          0,     1875,    36000, 0xd592781d
 0,       1875,       1875,     1875,    36000, 0xd592781d
 0,       3750,       3750,     1875,    36000, 0xd592781d
-0,       5625,       5625,     1200,    23056, 0xde81f0d6
+0,       5625,       5625,     1200,    23056, 0xde81f0d6, F=0x3
diff --git a/tests/ref/fate/dfa1 b/tests/ref/fate/dfa1
index 92a7cce..7bc5bf1 100644
--- a/tests/ref/fate/dfa1
+++ b/tests/ref/fate/dfa1
@@ -1,26 +1,26 @@
 #tb 0: 16/125
-0,          0,          0,        1,   921600, 0x2e2b3ca4
-0,          1,          1,        1,   921600, 0x0ff7a368
-0,          2,          2,        1,   921600, 0xf5f0dc50
-0,          3,          3,        1,   921600, 0x56cb0c9d
-0,          4,          4,        1,   921600, 0xb253228f
-0,          5,          5,        1,   921600, 0xefd3419e
-0,          6,          6,        1,   921600, 0x708c0ce7
-0,          7,          7,        1,   921600, 0x0b3a7f6d
-0,          8,          8,        1,   921600, 0x72db4eac
-0,          9,          9,        1,   921600, 0x94328111
-0,         10,         10,        1,   921600, 0x95f7b2f0
-0,         11,         11,        1,   921600, 0xdc3c9655
-0,         12,         12,        1,   921600, 0xfe03dec6
-0,         13,         13,        1,   921600, 0x2551dffb
-0,         14,         14,        1,   921600, 0xe8b37d9e
-0,         15,         15,        1,   921600, 0xad93508b
-0,         16,         16,        1,   921600, 0x5a1c4890
-0,         17,         17,        1,   921600, 0x6f972fb4
-0,         18,         18,        1,   921600, 0xa1d5ff95
-0,         19,         19,        1,   921600, 0x7bc5d07c
-0,         20,         20,        1,   921600, 0xc0311e4e
-0,         21,         21,        1,   921600, 0x5b02cc48
-0,         22,         22,        1,   921600, 0x8db4d5fa
-0,         23,         23,        1,   921600, 0x31aae769
-0,         24,         24,        1,   921600, 0xab62b9a7
+0,          0,          0,        1,   921600, 0xb69faa34
+0,          1,          1,        1,   921600, 0x38680829
+0,          2,          2,        1,   921600, 0xa7263c5a
+0,          3,          3,        1,   921600, 0xa784626a
+0,          4,          4,        1,   921600, 0xb4c47212
+0,          5,          5,        1,   921600, 0xd17285ea
+0,          6,          6,        1,   921600, 0xe9b33902
+0,          7,          7,        1,   921600, 0x215ea693
+0,          8,          8,        1,   921600, 0xe2ab6c7a
+0,          9,          9,        1,   921600, 0xf2867624
+0,         10,         10,        1,   921600, 0x607d78c1
+0,         11,         11,        1,   921600, 0x6e743bb7
+0,         12,         12,        1,   921600, 0x1fbf8f5a
+0,         13,         13,        1,   921600, 0xac6c912e
+0,         14,         14,        1,   921600, 0x556933bc
+0,         15,         15,        1,   921600, 0xda4c242b
+0,         16,         16,        1,   921600, 0xa6b32f83
+0,         17,         17,        1,   921600, 0x1ecc2996
+0,         18,         18,        1,   921600, 0xf1c3fc0f
+0,         19,         19,        1,   921600, 0x3f1db909
+0,         20,         20,        1,   921600, 0x7582fb93
+0,         21,         21,        1,   921600, 0x102ba261
+0,         22,         22,        1,   921600, 0xfbcf9de0
+0,         23,         23,        1,   921600, 0xe9ecb4d9
+0,         24,         24,        1,   921600, 0x7ee36a42
diff --git a/tests/ref/fate/dfa10 b/tests/ref/fate/dfa10
index a140e5c..a799f03 100644
--- a/tests/ref/fate/dfa10
+++ b/tests/ref/fate/dfa10
@@ -1,9 +1,9 @@
 #tb 0: 71/1000
-0,          0,          0,        1,   192000, 0xbabcbd55
-0,          1,          1,        1,   192000, 0xf00a5683
-0,          2,          2,        1,   192000, 0xcce90589
-0,          3,          3,        1,   192000, 0x8545631f
-0,          4,          4,        1,   192000, 0xd3ab654c
-0,          5,          5,        1,   192000, 0x5e0dda12
-0,          6,          6,        1,   192000, 0x7e94b053
-0,          7,          7,        1,   192000, 0x8027e68b
+0,          0,          0,        1,   192000, 0x7384f9b2
+0,          1,          1,        1,   192000, 0xd1f61c71
+0,          2,          2,        1,   192000, 0x0c6937d1
+0,          3,          3,        1,   192000, 0x56459a3a
+0,          4,          4,        1,   192000, 0x6d011790
+0,          5,          5,        1,   192000, 0xb5347ce8
+0,          6,          6,        1,   192000, 0xcd422568
+0,          7,          7,        1,   192000, 0xde4fef2d
diff --git a/tests/ref/fate/dfa11 b/tests/ref/fate/dfa11
index 3990d24..30b4b71 100644
--- a/tests/ref/fate/dfa11
+++ b/tests/ref/fate/dfa11
@@ -1,10 +1,10 @@
 #tb 0: 71/1000
-0,          0,          0,        1,   192000, 0x8b8bd8de
-0,          1,          1,        1,   192000, 0xdac26ec2
-0,          2,          2,        1,   192000, 0x0fc01c28
-0,          3,          3,        1,   192000, 0x1251eef7
-0,          4,          4,        1,   192000, 0x89eced0e
-0,          5,          5,        1,   192000, 0x4943d821
-0,          6,          6,        1,   192000, 0x49258ec9
-0,          7,          7,        1,   192000, 0x9afd5881
-0,          8,          8,        1,   192000, 0xb322b901
+0,          0,          0,        1,   192000, 0x4269d703
+0,          1,          1,        1,   192000, 0xdf8667e7
+0,          2,          2,        1,   192000, 0x450026ad
+0,          3,          3,        1,   192000, 0x2528ea52
+0,          4,          4,        1,   192000, 0x83bcd1ec
+0,          5,          5,        1,   192000, 0x88d5ba27
+0,          6,          6,        1,   192000, 0x44424577
+0,          7,          7,        1,   192000, 0xd93f12a3
+0,          8,          8,        1,   192000, 0xcd625f3e
diff --git a/tests/ref/fate/dfa2 b/tests/ref/fate/dfa2
index a050c97..cc4b454 100644
--- a/tests/ref/fate/dfa2
+++ b/tests/ref/fate/dfa2
@@ -1,18 +1,18 @@
 #tb 0: 71/1000
-0,          0,          0,        1,   921600, 0x713f2da1
-0,          1,          1,        1,   921600, 0x9e772ec9
-0,          2,          2,        1,   921600, 0x9420310f
-0,          3,          3,        1,   921600, 0xd68f294f
-0,          4,          4,        1,   921600, 0xe25a1bcf
-0,          5,          5,        1,   921600, 0x32f903ec
-0,          6,          6,        1,   921600, 0xdb290b1c
-0,          7,          7,        1,   921600, 0x0b0d1b0f
-0,          8,          8,        1,   921600, 0x58430921
-0,          9,          9,        1,   921600, 0xe65dd39e
-0,         10,         10,        1,   921600, 0x146b3068
-0,         11,         11,        1,   921600, 0x6e1e7f78
-0,         12,         12,        1,   921600, 0x0166e01c
-0,         13,         13,        1,   921600, 0x83b86b56
-0,         14,         14,        1,   921600, 0xd52a1697
-0,         15,         15,        1,   921600, 0x5b38adc8
-0,         16,         16,        1,   921600, 0x457f6cea
+0,          0,          0,        1,   921600, 0x8a5d15df
+0,          1,          1,        1,   921600, 0x92c01362
+0,          2,          2,        1,   921600, 0xe1a31643
+0,          3,          3,        1,   921600, 0x37a90fe2
+0,          4,          4,        1,   921600, 0x74410783
+0,          5,          5,        1,   921600, 0xecf4ef1a
+0,          6,          6,        1,   921600, 0x4d7ff3d4
+0,          7,          7,        1,   921600, 0xac820317
+0,          8,          8,        1,   921600, 0xbe5ff56e
+0,          9,          9,        1,   921600, 0x8e59c329
+0,         10,         10,        1,   921600, 0x73bf23f3
+0,         11,         11,        1,   921600, 0xb90c780f
+0,         12,         12,        1,   921600, 0xfbd9dc32
+0,         13,         13,        1,   921600, 0x30586821
+0,         14,         14,        1,   921600, 0x6695195b
+0,         15,         15,        1,   921600, 0xc449aa85
+0,         16,         16,        1,   921600, 0xca6a391c
diff --git a/tests/ref/fate/dfa3 b/tests/ref/fate/dfa3
index 8c91faa..9b170ec 100644
--- a/tests/ref/fate/dfa3
+++ b/tests/ref/fate/dfa3
@@ -1,11 +1,11 @@
 #tb 0: 1/10
-0,          0,          0,        1,   192000, 0x10380cf0
-0,          1,          1,        1,   192000, 0x1d74af4c
-0,          2,          2,        1,   192000, 0xd665492d
-0,          3,          3,        1,   192000, 0xbf544565
-0,          4,          4,        1,   192000, 0xf8a33b00
-0,          5,          5,        1,   192000, 0x7d08bbad
-0,          6,          6,        1,   192000, 0x10685a90
-0,          7,          7,        1,   192000, 0x0a1a9ef6
-0,          8,          8,        1,   192000, 0x3e967980
-0,          9,          9,        1,   192000, 0x9849f751
+0,          0,          0,        1,   192000, 0x236a1b54
+0,          1,          1,        1,   192000, 0xfb438b68
+0,          2,          2,        1,   192000, 0xde504563
+0,          3,          3,        1,   192000, 0xfaf88e05
+0,          4,          4,        1,   192000, 0xe15de5af
+0,          5,          5,        1,   192000, 0x641fcca4
+0,          6,          6,        1,   192000, 0x74899cb6
+0,          7,          7,        1,   192000, 0x93fdb1b4
+0,          8,          8,        1,   192000, 0x58d83456
+0,          9,          9,        1,   192000, 0x7d3012ac
diff --git a/tests/ref/fate/dfa4 b/tests/ref/fate/dfa4
index 67b5722..0e0dc02 100644
--- a/tests/ref/fate/dfa4
+++ b/tests/ref/fate/dfa4
@@ -1,14 +1,15 @@
 #tb 0: 71/500
-0,          1,          1,        1,   921600, 0xe6309638
-0,          2,          2,        1,   921600, 0xa99a7665
-0,          3,          3,        1,   921600, 0x172ccfbb
-0,          4,          4,        1,   921600, 0xcf676571
-0,          5,          5,        1,   921600, 0x6a5077f2
-0,          6,          6,        1,   921600, 0x6a5077f2
-0,          7,          7,        1,   921600, 0x6a5077f2
-0,          8,          8,        1,   921600, 0x6a5077f2
-0,          9,          9,        1,   921600, 0x6a5077f2
-0,         10,         10,        1,   921600, 0x6a5077f2
-0,         11,         11,        1,   921600, 0xb83db404
-0,         12,         12,        1,   921600, 0x997ceb90
-0,         13,         13,        1,   921600, 0xd707157c
+0,          0,          0,        1,   921600, 0x00000000
+0,          1,          1,        1,   921600, 0xd9e060e3
+0,          2,          2,        1,   921600, 0x15e28dc7
+0,          3,          3,        1,   921600, 0x78e8bfbc
+0,          4,          4,        1,   921600, 0xe9407075
+0,          5,          5,        1,   921600, 0xab818b8a
+0,          6,          6,        1,   921600, 0xab818b8a
+0,          7,          7,        1,   921600, 0xab818b8a
+0,          8,          8,        1,   921600, 0xab818b8a
+0,          9,          9,        1,   921600, 0xab818b8a
+0,         10,         10,        1,   921600, 0xab818b8a
+0,         11,         11,        1,   921600, 0xad5ad11c
+0,         12,         12,        1,   921600, 0xe6e50f8c
+0,         13,         13,        1,   921600, 0x9f127099
diff --git a/tests/ref/fate/dfa5 b/tests/ref/fate/dfa5
index b9f7727..3be3c52 100644
--- a/tests/ref/fate/dfa5
+++ b/tests/ref/fate/dfa5
@@ -1,16 +1,16 @@
 #tb 0: 1/10
-0,          0,          0,        1,   192000, 0xc0941c10
-0,          1,          1,        1,   192000, 0xe2fe3ae5
-0,          2,          2,        1,   192000, 0x4a352d98
-0,          3,          3,        1,   192000, 0x7b78e0bb
-0,          4,          4,        1,   192000, 0x855c6675
-0,          5,          5,        1,   192000, 0xf443dad6
-0,          6,          6,        1,   192000, 0xe7e2a2e1
-0,          7,          7,        1,   192000, 0xa9009c58
-0,          8,          8,        1,   192000, 0x551855ab
-0,          9,          9,        1,   192000, 0x253908c7
-0,         10,         10,        1,   192000, 0x616213c4
-0,         11,         11,        1,   192000, 0xa381c3b1
-0,         12,         12,        1,   192000, 0xa2d64152
-0,         13,         13,        1,   192000, 0x34ed0f72
-0,         14,         14,        1,   192000, 0x05be63b4
+0,          0,          0,        1,   192000, 0x9754890f
+0,          1,          1,        1,   192000, 0x01668965
+0,          2,          2,        1,   192000, 0xbd1b5e12
+0,          3,          3,        1,   192000, 0x2e97fb9f
+0,          4,          4,        1,   192000, 0xf8b452e2
+0,          5,          5,        1,   192000, 0xc6859449
+0,          6,          6,        1,   192000, 0x910844f7
+0,          7,          7,        1,   192000, 0x99443581
+0,          8,          8,        1,   192000, 0xec52d1e5
+0,          9,          9,        1,   192000, 0x2fc66c35
+0,         10,         10,        1,   192000, 0xd9af7379
+0,         11,         11,        1,   192000, 0x947a26ef
+0,         12,         12,        1,   192000, 0x7b77ab28
+0,         13,         13,        1,   192000, 0x2507637e
+0,         14,         14,        1,   192000, 0x6ce8c0ea
diff --git a/tests/ref/fate/dfa6 b/tests/ref/fate/dfa6
index 92ed259..535f98b 100644
--- a/tests/ref/fate/dfa6
+++ b/tests/ref/fate/dfa6
@@ -1,13 +1,13 @@
 #tb 0: 71/1000
-0,          0,          0,        1,   192000, 0x69f6a5f6
-0,          1,          1,        1,   192000, 0xc741d0a6
-0,          2,          2,        1,   192000, 0xba31e7a4
-0,          3,          3,        1,   192000, 0x7dc45080
-0,          4,          4,        1,   192000, 0x1c91dad5
-0,          5,          5,        1,   192000, 0x564b69b1
-0,          6,          6,        1,   192000, 0xdd9d9ae8
-0,          7,          7,        1,   192000, 0x605c05e1
-0,          8,          8,        1,   192000, 0xa5341ddb
-0,          9,          9,        1,   192000, 0x1ebff8ba
-0,         10,         10,        1,   192000, 0x240df237
-0,         11,         11,        1,   192000, 0xac641867
+0,          0,          0,        1,   192000, 0xb718dc63
+0,          1,          1,        1,   192000, 0x2efb7b89
+0,          2,          2,        1,   192000, 0x70827047
+0,          3,          3,        1,   192000, 0x61e1fd2f
+0,          4,          4,        1,   192000, 0x06f8bccd
+0,          5,          5,        1,   192000, 0xf0362404
+0,          6,          6,        1,   192000, 0xc00fc1b8
+0,          7,          7,        1,   192000, 0x94265476
+0,          8,          8,        1,   192000, 0x4b50ad23
+0,          9,          9,        1,   192000, 0x4d578b60
+0,         10,         10,        1,   192000, 0xfb14b875
+0,         11,         11,        1,   192000, 0x81682338
diff --git a/tests/ref/fate/dfa7 b/tests/ref/fate/dfa7
index 7dd40f2..28122c5 100644
--- a/tests/ref/fate/dfa7
+++ b/tests/ref/fate/dfa7
@@ -1,13 +1,13 @@
 #tb 0: 71/1000
-0,          0,          0,        1,     7866, 0xa0056fdb
-0,          1,          1,        1,     7866, 0xed906c7a
-0,          2,          2,        1,     7866, 0x1c6e6f7d
-0,          3,          3,        1,     7866, 0xa2c460f7
-0,          4,          4,        1,     7866, 0xcf2166d4
-0,          5,          5,        1,     7866, 0xea545432
-0,          6,          6,        1,     7866, 0x604a5a9e
-0,          7,          7,        1,     7866, 0xbbc95c89
-0,          8,          8,        1,     7866, 0x80b16b5b
-0,          9,          9,        1,     7866, 0x9a1660ae
-0,         10,         10,        1,     7866, 0x6f886b10
-0,         11,         11,        1,     7866, 0xad8b5c99
+0,          0,          0,        1,     7866, 0xab73dae7
+0,          1,          1,        1,     7866, 0x100adec8
+0,          2,          2,        1,     7866, 0x1a20ddfa
+0,          3,          3,        1,     7866, 0xc358cd16
+0,          4,          4,        1,     7866, 0xee0bd20e
+0,          5,          5,        1,     7866, 0xef26bef9
+0,          6,          6,        1,     7866, 0xa9d0c755
+0,          7,          7,        1,     7866, 0x6c11cc7c
+0,          8,          8,        1,     7866, 0x4d6ed988
+0,          9,          9,        1,     7866, 0x9965cf24
+0,         10,         10,        1,     7866, 0x9a12db24
+0,         11,         11,        1,     7866, 0x2e85cfeb
diff --git a/tests/ref/fate/dfa8 b/tests/ref/fate/dfa8
index 39dde05..866260a 100644
--- a/tests/ref/fate/dfa8
+++ b/tests/ref/fate/dfa8
@@ -1,37 +1,37 @@
 #tb 0: 71/1000
-0,          0,          0,        1,   134724, 0x2ab217de
-0,          1,          1,        1,   134724, 0xbf240f9a
-0,          2,          2,        1,   134724, 0x020a6010
-0,          3,          3,        1,   134724, 0x9a5f9374
-0,          4,          4,        1,   134724, 0x1e93a7e9
-0,          5,          5,        1,   134724, 0x9e4a4c55
-0,          6,          6,        1,   134724, 0x8f9d1bab
-0,          7,          7,        1,   134724, 0xb26ac45b
-0,          8,          8,        1,   134724, 0xc08706d2
-0,          9,          9,        1,   134724, 0x0806b031
-0,         10,         10,        1,   134724, 0x234dbb33
-0,         11,         11,        1,   134724, 0xe4cbfb2f
-0,         12,         12,        1,   134724, 0xf603f3fd
-0,         13,         13,        1,   134724, 0x205669d1
-0,         14,         14,        1,   134724, 0x7ddbb5e3
-0,         15,         15,        1,   134724, 0x8dfbb45a
-0,         16,         16,        1,   134724, 0x9632f681
-0,         17,         17,        1,   134724, 0x259e462c
-0,         18,         18,        1,   134724, 0x14f2bac1
-0,         19,         19,        1,   134724, 0xac3de7ed
-0,         20,         20,        1,   134724, 0x6b8af396
-0,         21,         21,        1,   134724, 0xd1e4bc1c
-0,         22,         22,        1,   134724, 0x716d1c73
-0,         23,         23,        1,   134724, 0x610956c8
-0,         24,         24,        1,   134724, 0x89ff8e86
-0,         25,         25,        1,   134724, 0xc3ea6b6f
-0,         26,         26,        1,   134724, 0x886688ef
-0,         27,         27,        1,   134724, 0xe60fc8c1
-0,         28,         28,        1,   134724, 0x22bd3131
-0,         29,         29,        1,   134724, 0xb1d74561
-0,         30,         30,        1,   134724, 0x61b069bc
-0,         31,         31,        1,   134724, 0x50b665c1
-0,         32,         32,        1,   134724, 0x027e5144
-0,         33,         33,        1,   134724, 0xfe0c31b4
-0,         34,         34,        1,   134724, 0x1e7a1f2d
-0,         35,         35,        1,   134724, 0x48bff03d
+0,          0,          0,        1,   134724, 0x53784ca9
+0,          1,          1,        1,   134724, 0x14c345b7
+0,          2,          2,        1,   134724, 0xe0d0dd51
+0,          3,          3,        1,   134724, 0xd53b5610
+0,          4,          4,        1,   134724, 0x7cbb8d47
+0,          5,          5,        1,   134724, 0x875d67c4
+0,          6,          6,        1,   134724, 0x9811c085
+0,          7,          7,        1,   134724, 0x25f6d228
+0,          8,          8,        1,   134724, 0x349495a0
+0,          9,          9,        1,   134724, 0xd0d75311
+0,         10,         10,        1,   134724, 0xb49cdfbb
+0,         11,         11,        1,   134724, 0x9fa69518
+0,         12,         12,        1,   134724, 0x28a1f58c
+0,         13,         13,        1,   134724, 0xb8dab657
+0,         14,         14,        1,   134724, 0x8c7e3b3b
+0,         15,         15,        1,   134724, 0x37268acf
+0,         16,         16,        1,   134724, 0xcce8ca02
+0,         17,         17,        1,   134724, 0xe0fd0c28
+0,         18,         18,        1,   134724, 0x5bdac906
+0,         19,         19,        1,   134724, 0xdd850bf0
+0,         20,         20,        1,   134724, 0x2002a228
+0,         21,         21,        1,   134724, 0x633617ea
+0,         22,         22,        1,   134724, 0x2a3ef337
+0,         23,         23,        1,   134724, 0x507886c3
+0,         24,         24,        1,   134724, 0x51c0f07b
+0,         25,         25,        1,   134724, 0x5e73dce1
+0,         26,         26,        1,   134724, 0x26acc6f0
+0,         27,         27,        1,   134724, 0x360c4349
+0,         28,         28,        1,   134724, 0xc7dbabd4
+0,         29,         29,        1,   134724, 0x671bbf66
+0,         30,         30,        1,   134724, 0x4d44df79
+0,         31,         31,        1,   134724, 0x69eade5b
+0,         32,         32,        1,   134724, 0x2b1bca82
+0,         33,         33,        1,   134724, 0x8b16af47
+0,         34,         34,        1,   134724, 0xb59fa1bd
+0,         35,         35,        1,   134724, 0x2ec17c24
diff --git a/tests/ref/fate/dfa9 b/tests/ref/fate/dfa9
index cf24e3e..99eb3f6 100644
--- a/tests/ref/fate/dfa9
+++ b/tests/ref/fate/dfa9
@@ -1,7 +1,7 @@
 #tb 0: 71/1000
-0,          0,          0,        1,   228150, 0x188c6d9b
-0,          1,          1,        1,   228150, 0x658dbf2f
-0,          2,          2,        1,   228150, 0xc09a4b2e
-0,          3,          3,        1,   228150, 0x8777bc7d
-0,          4,          4,        1,   228150, 0xa388f0ce
-0,          5,          5,        1,   228150, 0x4e06666e
+0,          0,          0,        1,   228150, 0xde68df49
+0,          1,          1,        1,   228150, 0x8e12bcaf
+0,          2,          2,        1,   228150, 0x851b04f7
+0,          3,          3,        1,   228150, 0x7e5e0950
+0,          4,          4,        1,   228150, 0x1d92219f
+0,          5,          5,        1,   228150, 0x93caa693
diff --git a/tests/ref/fate/ea-cmv b/tests/ref/fate/ea-cmv
index 18f2b3a..8f9049e 100644
--- a/tests/ref/fate/ea-cmv
+++ b/tests/ref/fate/ea-cmv
@@ -1,195 +1,195 @@
 #tb 0: 1/10
-0,          1,          1,        1,   120000, 0x34ac91d2
-0,          2,          2,        1,   120000, 0x17150729
-0,          3,          3,        1,   120000, 0xc3f510bb
-0,          4,          4,        1,   120000, 0xb3b14a3b
-0,          5,          5,        1,   120000, 0x26a7f3d1
-0,          6,          6,        1,   120000, 0xd161af6f
-0,          7,          7,        1,   120000, 0x459fc92d
-0,          8,          8,        1,   120000, 0x05c3fa94
-0,          9,          9,        1,   120000, 0x6630cd8c
-0,         10,         10,        1,   120000, 0x60cd39d4
-0,         11,         11,        1,   120000, 0xc8854d1c
-0,         12,         12,        1,   120000, 0xe55e8e6d
-0,         13,         13,        1,   120000, 0xbeab201f
-0,         14,         14,        1,   120000, 0x70744b0b
-0,         15,         15,        1,   120000, 0x80dea5d0
-0,         16,         16,        1,   120000, 0x769bfa1c
-0,         17,         17,        1,   120000, 0x04e25bbe
-0,         18,         18,        1,   120000, 0x48abc5a5
-0,         19,         19,        1,   120000, 0xda5c4e2a
-0,         20,         20,        1,   120000, 0x8de96d38
-0,         21,         21,        1,   120000, 0xe96418b0
-0,         22,         22,        1,   120000, 0x1c2f272b
-0,         23,         23,        1,   120000, 0x4b755804
-0,         24,         24,        1,   120000, 0xc92f96fd
-0,         25,         25,        1,   120000, 0x69e90ebb
-0,         26,         26,        1,   120000, 0x78d4bd1a
-0,         27,         27,        1,   120000, 0xaf2edf55
-0,         28,         28,        1,   120000, 0x94161c78
-0,         29,         29,        1,   120000, 0x1109094d
-0,         30,         30,        1,   120000, 0xc61b0392
-0,         31,         31,        1,   120000, 0xc157d003
-0,         32,         32,        1,   120000, 0xf2747e7b
-0,         33,         33,        1,   120000, 0xa36299c2
-0,         34,         34,        1,   120000, 0x49bc788c
-0,         35,         35,        1,   120000, 0x3bee336e
-0,         36,         36,        1,   120000, 0xa316b9d1
-0,         37,         37,        1,   120000, 0x5cc32e9c
-0,         38,         38,        1,   120000, 0x9f7eca16
-0,         39,         39,        1,   120000, 0x958e2988
-0,         40,         40,        1,   120000, 0xebcba2f1
-0,         41,         41,        1,   120000, 0x281f1e60
-0,         42,         42,        1,   120000, 0x82256c4d
-0,         43,         43,        1,   120000, 0xddc8be56
-0,         44,         44,        1,   120000, 0x64ff2ed0
-0,         45,         45,        1,   120000, 0x3e63ab02
-0,         46,         46,        1,   120000, 0x43f78b37
-0,         47,         47,        1,   120000, 0xb7cc62d4
-0,         48,         48,        1,   120000, 0x694f1764
-0,         49,         49,        1,   120000, 0x2264c483
-0,         51,         51,        1,   120000, 0xb6680b4a
-0,         52,         52,        1,   120000, 0x2a92626a
-0,         53,         53,        1,   120000, 0x8da02509
-0,         54,         54,        1,   120000, 0xa976c382
-0,         55,         55,        1,   120000, 0x749e822b
-0,         56,         56,        1,   120000, 0xe9e7fc8c
-0,         57,         57,        1,   120000, 0xfdc05a0c
-0,         58,         58,        1,   120000, 0x7d5a856d
-0,         59,         59,        1,   120000, 0xcc344937
-0,         60,         60,        1,   120000, 0x9d90bc67
-0,         61,         61,        1,   120000, 0x3f527712
-0,         62,         62,        1,   120000, 0xf0f57f97
-0,         63,         63,        1,   120000, 0xc29535cd
-0,         64,         64,        1,   120000, 0x9a64598b
-0,         65,         65,        1,   120000, 0x0d1ddf7c
-0,         66,         66,        1,   120000, 0xb580ec24
-0,         67,         67,        1,   120000, 0xf0db5bbc
-0,         68,         68,        1,   120000, 0x6b980b61
-0,         69,         69,        1,   120000, 0xc29f30b5
-0,         70,         70,        1,   120000, 0xaf2c4bcd
-0,         71,         71,        1,   120000, 0x1e725645
-0,         72,         72,        1,   120000, 0x295c4c96
-0,         73,         73,        1,   120000, 0x7ea121a2
-0,         74,         74,        1,   120000, 0xdb9e9cec
-0,         75,         75,        1,   120000, 0x1da47c80
-0,         76,         76,        1,   120000, 0x9d0c1345
-0,         77,         77,        1,   120000, 0x88058527
-0,         78,         78,        1,   120000, 0x46766aed
-0,         79,         79,        1,   120000, 0xba520bd3
-0,         80,         80,        1,   120000, 0x7fb6373c
-0,         81,         81,        1,   120000, 0x05a86f4d
-0,         82,         82,        1,   120000, 0x7fb47cbd
-0,         83,         83,        1,   120000, 0x6814d8ca
-0,         84,         84,        1,   120000, 0x9c13acb8
-0,         85,         85,        1,   120000, 0xad0edbfe
-0,         86,         86,        1,   120000, 0x352fde81
-0,         87,         87,        1,   120000, 0xa654b386
-0,         88,         88,        1,   120000, 0xd3b3dc72
-0,         89,         89,        1,   120000, 0x01572668
-0,         90,         90,        1,   120000, 0x30189e03
-0,         91,         91,        1,   120000, 0x26126d30
-0,         92,         92,        1,   120000, 0x4f376c7d
-0,         93,         93,        1,   120000, 0xd3667bcf
-0,         94,         94,        1,   120000, 0x0b46b3d5
-0,         95,         95,        1,   120000, 0x893415ef
-0,         96,         96,        1,   120000, 0x99a78749
-0,         97,         97,        1,   120000, 0x6da0d8e9
-0,         98,         98,        1,   120000, 0x22d8ceb6
-0,         99,         99,        1,   120000, 0x67ef9be8
-0,        100,        100,        1,   120000, 0xb696fb53
-0,        101,        101,        1,   120000, 0x70339dab
-0,        102,        102,        1,   120000, 0xc1876efa
-0,        103,        103,        1,   120000, 0x80e78c92
-0,        104,        104,        1,   120000, 0x18d2f2ac
-0,        105,        105,        1,   120000, 0x28be9ae4
-0,        106,        106,        1,   120000, 0xc3c2c190
-0,        107,        107,        1,   120000, 0xd6a859d8
-0,        108,        108,        1,   120000, 0x40b9046d
-0,        109,        109,        1,   120000, 0x7f8d5999
-0,        110,        110,        1,   120000, 0x89724027
-0,        111,        111,        1,   120000, 0x4c15c988
-0,        112,        112,        1,   120000, 0x812ebe08
-0,        113,        113,        1,   120000, 0x273ef8e2
-0,        114,        114,        1,   120000, 0xe029de06
-0,        115,        115,        1,   120000, 0x5846127c
-0,        116,        116,        1,   120000, 0x6c5df8e3
-0,        117,        117,        1,   120000, 0x7424919f
-0,        118,        118,        1,   120000, 0xa8313015
-0,        119,        119,        1,   120000, 0x28878ab4
-0,        120,        120,        1,   120000, 0x126d0746
-0,        121,        121,        1,   120000, 0xee3f7138
-0,        122,        122,        1,   120000, 0xd4b2e0a1
-0,        123,        123,        1,   120000, 0x8d60bfff
-0,        124,        124,        1,   120000, 0x701c23d0
-0,        125,        125,        1,   120000, 0x1cbb5654
-0,        126,        126,        1,   120000, 0x0f5853e9
-0,        127,        127,        1,   120000, 0x2a5c3339
-0,        128,        128,        1,   120000, 0x86b00350
-0,        129,        129,        1,   120000, 0xe8cc6931
-0,        130,        130,        1,   120000, 0xf1cad983
-0,        131,        131,        1,   120000, 0xabcd8704
-0,        132,        132,        1,   120000, 0x89592f94
-0,        133,        133,        1,   120000, 0x100486d9
-0,        134,        134,        1,   120000, 0x60ef9e2d
-0,        135,        135,        1,   120000, 0x2485176a
-0,        136,        136,        1,   120000, 0x6b8c360d
-0,        137,        137,        1,   120000, 0xe2e1bf4f
-0,        138,        138,        1,   120000, 0xe17b65c3
-0,        139,        139,        1,   120000, 0x2a42821a
-0,        140,        140,        1,   120000, 0xbe9ddba7
-0,        141,        141,        1,   120000, 0x19f937fe
-0,        142,        142,        1,   120000, 0xb7e0c600
-0,        143,        143,        1,   120000, 0xfbf8c5f6
-0,        144,        144,        1,   120000, 0x93b62f93
-0,        145,        145,        1,   120000, 0xb6ddec93
-0,        146,        146,        1,   120000, 0xa04d031b
-0,        147,        147,        1,   120000, 0x61c986c0
-0,        148,        148,        1,   120000, 0x3516e54a
-0,        149,        149,        1,   120000, 0x3489eb2c
-0,        150,        150,        1,   120000, 0xb75a4827
-0,        151,        151,        1,   120000, 0x76031a80
-0,        152,        152,        1,   120000, 0x867c3969
-0,        153,        153,        1,   120000, 0x9b63a093
-0,        154,        154,        1,   120000, 0xcb253d8a
-0,        155,        155,        1,   120000, 0x354ba3b2
-0,        156,        156,        1,   120000, 0x4d5ead8c
-0,        157,        157,        1,   120000, 0x7b7029ae
-0,        158,        158,        1,   120000, 0x4765ab9d
-0,        159,        159,        1,   120000, 0x747cdee9
-0,        160,        160,        1,   120000, 0x20989b08
-0,        161,        161,        1,   120000, 0x3a957085
-0,        162,        162,        1,   120000, 0xdd49e8ad
-0,        163,        163,        1,   120000, 0x00e89719
-0,        164,        164,        1,   120000, 0x2822aa76
-0,        165,        165,        1,   120000, 0x492388f3
-0,        166,        166,        1,   120000, 0x4dffa6ee
-0,        167,        167,        1,   120000, 0xc382bb83
-0,        168,        168,        1,   120000, 0xb59aaa74
-0,        169,        169,        1,   120000, 0x7c7885d3
-0,        170,        170,        1,   120000, 0xc05ee219
-0,        171,        171,        1,   120000, 0xc3df6b73
-0,        172,        172,        1,   120000, 0x8ae31170
-0,        173,        173,        1,   120000, 0xb979fdce
-0,        174,        174,        1,   120000, 0xb8f9e407
-0,        175,        175,        1,   120000, 0x56675b80
-0,        176,        176,        1,   120000, 0x1aad1ce2
-0,        177,        177,        1,   120000, 0xa050a52b
-0,        178,        178,        1,   120000, 0x49f8c32f
-0,        179,        179,        1,   120000, 0x8e7f4d2c
-0,        180,        180,        1,   120000, 0x5c07f751
-0,        181,        181,        1,   120000, 0x67fa5523
-0,        182,        182,        1,   120000, 0xf38b933a
-0,        183,        183,        1,   120000, 0xb113e202
-0,        184,        184,        1,   120000, 0xb8d99ff4
-0,        185,        185,        1,   120000, 0x15ab6cc6
-0,        186,        186,        1,   120000, 0xd64a51c9
-0,        187,        187,        1,   120000, 0x2088b53c
-0,        188,        188,        1,   120000, 0xdd78d40a
-0,        189,        189,        1,   120000, 0x2fb58848
-0,        190,        190,        1,   120000, 0xf775d36a
-0,        191,        191,        1,   120000, 0xa03987e9
-0,        192,        192,        1,   120000, 0x457322ad
-0,        193,        193,        1,   120000, 0x0f6c3d1c
-0,        194,        194,        1,   120000, 0xbdf2f1a5
-0,        195,        195,        1,   120000, 0x5828ee1d
+0,          0,          0,        1,   120000, 0x34ac91d2
+0,          1,          1,        1,   120000, 0x17150729
+0,          2,          2,        1,   120000, 0xc3f510bb
+0,          3,          3,        1,   120000, 0xb3b14a3b
+0,          4,          4,        1,   120000, 0x26a7f3d1
+0,          5,          5,        1,   120000, 0xd161af6f
+0,          6,          6,        1,   120000, 0x459fc92d
+0,          7,          7,        1,   120000, 0x05c3fa94
+0,          8,          8,        1,   120000, 0x6630cd8c
+0,          9,          9,        1,   120000, 0x60cd39d4
+0,         10,         10,        1,   120000, 0xc8854d1c
+0,         11,         11,        1,   120000, 0xe55e8e6d
+0,         12,         12,        1,   120000, 0xbeab201f
+0,         13,         13,        1,   120000, 0x70744b0b
+0,         14,         14,        1,   120000, 0x80dea5d0
+0,         15,         15,        1,   120000, 0x769bfa1c
+0,         16,         16,        1,   120000, 0x04e25bbe
+0,         17,         17,        1,   120000, 0x48abc5a5
+0,         18,         18,        1,   120000, 0xda5c4e2a
+0,         19,         19,        1,   120000, 0x8de96d38
+0,         20,         20,        1,   120000, 0xe96418b0
+0,         21,         21,        1,   120000, 0x1c2f272b
+0,         22,         22,        1,   120000, 0x4b755804
+0,         23,         23,        1,   120000, 0xc92f96fd
+0,         24,         24,        1,   120000, 0x69e90ebb
+0,         25,         25,        1,   120000, 0x78d4bd1a
+0,         26,         26,        1,   120000, 0xaf2edf55
+0,         27,         27,        1,   120000, 0x94161c78
+0,         28,         28,        1,   120000, 0x1109094d
+0,         29,         29,        1,   120000, 0xc61b0392
+0,         30,         30,        1,   120000, 0xc157d003
+0,         31,         31,        1,   120000, 0xf2747e7b
+0,         32,         32,        1,   120000, 0xa36299c2
+0,         33,         33,        1,   120000, 0x49bc788c
+0,         34,         34,        1,   120000, 0x3bee336e
+0,         35,         35,        1,   120000, 0xa316b9d1
+0,         36,         36,        1,   120000, 0x5cc32e9c
+0,         37,         37,        1,   120000, 0x9f7eca16
+0,         38,         38,        1,   120000, 0x958e2988
+0,         39,         39,        1,   120000, 0xebcba2f1
+0,         40,         40,        1,   120000, 0x281f1e60
+0,         41,         41,        1,   120000, 0x82256c4d
+0,         42,         42,        1,   120000, 0xddc8be56
+0,         43,         43,        1,   120000, 0x64ff2ed0
+0,         44,         44,        1,   120000, 0x3e63ab02
+0,         45,         45,        1,   120000, 0x43f78b37
+0,         46,         46,        1,   120000, 0xb7cc62d4
+0,         47,         47,        1,   120000, 0x694f1764
+0,         48,         48,        1,   120000, 0x2264c483
+0,         49,         49,        1,   120000, 0xb6680b4a
+0,         50,         50,        1,   120000, 0x2a92626a
+0,         51,         51,        1,   120000, 0x8da02509
+0,         52,         52,        1,   120000, 0xa976c382
+0,         53,         53,        1,   120000, 0x749e822b
+0,         54,         54,        1,   120000, 0xe9e7fc8c
+0,         55,         55,        1,   120000, 0xfdc05a0c
+0,         56,         56,        1,   120000, 0x7d5a856d
+0,         57,         57,        1,   120000, 0xcc344937
+0,         58,         58,        1,   120000, 0x9d90bc67
+0,         59,         59,        1,   120000, 0x3f527712
+0,         60,         60,        1,   120000, 0xf0f57f97
+0,         61,         61,        1,   120000, 0xc29535cd
+0,         62,         62,        1,   120000, 0x9a64598b
+0,         63,         63,        1,   120000, 0x0d1ddf7c
+0,         64,         64,        1,   120000, 0xb580ec24
+0,         65,         65,        1,   120000, 0xf0db5bbc
+0,         66,         66,        1,   120000, 0x6b980b61
+0,         67,         67,        1,   120000, 0xc29f30b5
+0,         68,         68,        1,   120000, 0xaf2c4bcd
+0,         69,         69,        1,   120000, 0x1e725645
+0,         70,         70,        1,   120000, 0x295c4c96
+0,         71,         71,        1,   120000, 0x7ea121a2
+0,         72,         72,        1,   120000, 0xdb9e9cec
+0,         73,         73,        1,   120000, 0x1da47c80
+0,         74,         74,        1,   120000, 0x9d0c1345
+0,         75,         75,        1,   120000, 0x88058527
+0,         76,         76,        1,   120000, 0x46766aed
+0,         77,         77,        1,   120000, 0xba520bd3
+0,         78,         78,        1,   120000, 0x7fb6373c
+0,         79,         79,        1,   120000, 0x05a86f4d
+0,         80,         80,        1,   120000, 0x7fb47cbd
+0,         81,         81,        1,   120000, 0x6814d8ca
+0,         82,         82,        1,   120000, 0x9c13acb8
+0,         83,         83,        1,   120000, 0xad0edbfe
+0,         84,         84,        1,   120000, 0x352fde81
+0,         85,         85,        1,   120000, 0xa654b386
+0,         86,         86,        1,   120000, 0xd3b3dc72
+0,         87,         87,        1,   120000, 0x01572668
+0,         88,         88,        1,   120000, 0x30189e03
+0,         89,         89,        1,   120000, 0x26126d30
+0,         90,         90,        1,   120000, 0x4f376c7d
+0,         91,         91,        1,   120000, 0xd3667bcf
+0,         92,         92,        1,   120000, 0x0b46b3d5
+0,         93,         93,        1,   120000, 0x893415ef
+0,         94,         94,        1,   120000, 0x99a78749
+0,         95,         95,        1,   120000, 0x6da0d8e9
+0,         96,         96,        1,   120000, 0x22d8ceb6
+0,         97,         97,        1,   120000, 0x67ef9be8
+0,         98,         98,        1,   120000, 0xb696fb53
+0,         99,         99,        1,   120000, 0x70339dab
+0,        100,        100,        1,   120000, 0xc1876efa
+0,        101,        101,        1,   120000, 0x80e78c92
+0,        102,        102,        1,   120000, 0x18d2f2ac
+0,        103,        103,        1,   120000, 0x28be9ae4
+0,        104,        104,        1,   120000, 0xc3c2c190
+0,        105,        105,        1,   120000, 0xd6a859d8
+0,        106,        106,        1,   120000, 0x40b9046d
+0,        107,        107,        1,   120000, 0x7f8d5999
+0,        108,        108,        1,   120000, 0x89724027
+0,        109,        109,        1,   120000, 0x4c15c988
+0,        110,        110,        1,   120000, 0x812ebe08
+0,        111,        111,        1,   120000, 0x273ef8e2
+0,        112,        112,        1,   120000, 0xe029de06
+0,        113,        113,        1,   120000, 0x5846127c
+0,        114,        114,        1,   120000, 0x6c5df8e3
+0,        115,        115,        1,   120000, 0x7424919f
+0,        116,        116,        1,   120000, 0xa8313015
+0,        117,        117,        1,   120000, 0x28878ab4
+0,        118,        118,        1,   120000, 0x126d0746
+0,        119,        119,        1,   120000, 0xee3f7138
+0,        120,        120,        1,   120000, 0xd4b2e0a1
+0,        121,        121,        1,   120000, 0x8d60bfff
+0,        122,        122,        1,   120000, 0x701c23d0
+0,        123,        123,        1,   120000, 0x1cbb5654
+0,        124,        124,        1,   120000, 0x0f5853e9
+0,        125,        125,        1,   120000, 0x2a5c3339
+0,        126,        126,        1,   120000, 0x86b00350
+0,        127,        127,        1,   120000, 0xe8cc6931
+0,        128,        128,        1,   120000, 0xf1cad983
+0,        129,        129,        1,   120000, 0xabcd8704
+0,        130,        130,        1,   120000, 0x89592f94
+0,        131,        131,        1,   120000, 0x100486d9
+0,        132,        132,        1,   120000, 0x60ef9e2d
+0,        133,        133,        1,   120000, 0x2485176a
+0,        134,        134,        1,   120000, 0x6b8c360d
+0,        135,        135,        1,   120000, 0xe2e1bf4f
+0,        136,        136,        1,   120000, 0xe17b65c3
+0,        137,        137,        1,   120000, 0x2a42821a
+0,        138,        138,        1,   120000, 0xbe9ddba7
+0,        139,        139,        1,   120000, 0x19f937fe
+0,        140,        140,        1,   120000, 0xb7e0c600
+0,        141,        141,        1,   120000, 0xfbf8c5f6
+0,        142,        142,        1,   120000, 0x93b62f93
+0,        143,        143,        1,   120000, 0xb6ddec93
+0,        144,        144,        1,   120000, 0xa04d031b
+0,        145,        145,        1,   120000, 0x61c986c0
+0,        146,        146,        1,   120000, 0x3516e54a
+0,        147,        147,        1,   120000, 0x3489eb2c
+0,        148,        148,        1,   120000, 0xb75a4827
+0,        149,        149,        1,   120000, 0x76031a80
+0,        150,        150,        1,   120000, 0x867c3969
+0,        151,        151,        1,   120000, 0x9b63a093
+0,        152,        152,        1,   120000, 0xcb253d8a
+0,        153,        153,        1,   120000, 0x354ba3b2
+0,        154,        154,        1,   120000, 0x4d5ead8c
+0,        155,        155,        1,   120000, 0x7b7029ae
+0,        156,        156,        1,   120000, 0x4765ab9d
+0,        157,        157,        1,   120000, 0x747cdee9
+0,        158,        158,        1,   120000, 0x20989b08
+0,        159,        159,        1,   120000, 0x3a957085
+0,        160,        160,        1,   120000, 0xdd49e8ad
+0,        161,        161,        1,   120000, 0x00e89719
+0,        162,        162,        1,   120000, 0x2822aa76
+0,        163,        163,        1,   120000, 0x492388f3
+0,        164,        164,        1,   120000, 0x4dffa6ee
+0,        165,        165,        1,   120000, 0xc382bb83
+0,        166,        166,        1,   120000, 0xb59aaa74
+0,        167,        167,        1,   120000, 0x7c7885d3
+0,        168,        168,        1,   120000, 0xc05ee219
+0,        169,        169,        1,   120000, 0xc3df6b73
+0,        170,        170,        1,   120000, 0x8ae31170
+0,        171,        171,        1,   120000, 0xb979fdce
+0,        172,        172,        1,   120000, 0xb8f9e407
+0,        173,        173,        1,   120000, 0x56675b80
+0,        174,        174,        1,   120000, 0x1aad1ce2
+0,        175,        175,        1,   120000, 0xa050a52b
+0,        176,        176,        1,   120000, 0x49f8c32f
+0,        177,        177,        1,   120000, 0x8e7f4d2c
+0,        178,        178,        1,   120000, 0x5c07f751
+0,        179,        179,        1,   120000, 0x67fa5523
+0,        180,        180,        1,   120000, 0xf38b933a
+0,        181,        181,        1,   120000, 0xb113e202
+0,        182,        182,        1,   120000, 0xb8d99ff4
+0,        183,        183,        1,   120000, 0x15ab6cc6
+0,        184,        184,        1,   120000, 0xd64a51c9
+0,        185,        185,        1,   120000, 0x2088b53c
+0,        186,        186,        1,   120000, 0xdd78d40a
+0,        187,        187,        1,   120000, 0x2fb58848
+0,        188,        188,        1,   120000, 0xf775d36a
+0,        189,        189,        1,   120000, 0xa03987e9
+0,        190,        190,        1,   120000, 0x457322ad
+0,        191,        191,        1,   120000, 0x0f6c3d1c
+0,        192,        192,        1,   120000, 0xbdf2f1a5
+0,        193,        193,        1,   120000, 0x5828ee1d
diff --git a/tests/ref/fate/ea-mad b/tests/ref/fate/ea-mad
index ce1df4a..1ea92fd 100644
--- a/tests/ref/fate/ea-mad
+++ b/tests/ref/fate/ea-mad
@@ -1,97 +1,97 @@
-#tb 0: 1/90000
-0,          0,          0,        0,   535680, 0x889c32cf
-0,       2970,       2970,        0,   535680, 0x0b1ef044
-0,       5940,       5940,        0,   535680, 0xa7d0818b
-0,       8910,       8910,        0,   535680, 0xf392e4e1
-0,      11880,      11880,        0,   535680, 0x08480c69
-0,      14850,      14850,        0,   535680, 0x2b8af1ed
-0,      17820,      17820,        0,   535680, 0x0d58e062
-0,      20790,      20790,        0,   535680, 0xd140ced0
-0,      23760,      23760,        0,   535680, 0xbd0e6652
-0,      26730,      26730,        0,   535680, 0xdc2f2a6b
-0,      29700,      29700,        0,   535680, 0x97c31a38
-0,      32670,      32670,        0,   535680, 0x1a2bdf38
-0,      35640,      35640,        0,   535680, 0xb3af3ac4
-0,      38610,      38610,        0,   535680, 0x07a52577
-0,      41580,      41580,        0,   535680, 0x78407368
-0,      44550,      44550,        0,   535680, 0xd2a9efc3
-0,      47520,      47520,        0,   535680, 0x36df2f29
-0,      50490,      50490,        0,   535680, 0x9821d8f7
-0,      53460,      53460,        0,   535680, 0xf64321aa
-0,      56430,      56430,        0,   535680, 0x53e4d9aa
-0,      59400,      59400,        0,   535680, 0xdbd6f853
-0,      62370,      62370,        0,   535680, 0x5d40cf8b
-0,      65340,      65340,        0,   535680, 0xe624af9d
-0,      68310,      68310,        0,   535680, 0xd9dbb4cd
-0,      71280,      71280,        0,   535680, 0xf14e72ec
-0,      74250,      74250,        0,   535680, 0xb35c18f6
-0,      77220,      77220,        0,   535680, 0xc96d7757
-0,      80190,      80190,        0,   535680, 0xdfb937df
-0,      83160,      83160,        0,   535680, 0x40cd71d7
-0,      86130,      86130,        0,   535680, 0x15e176d6
-0,      89100,      89100,        0,   535680, 0x7f891b24
-0,      92070,      92070,        0,   535680, 0xb87a8c32
-0,      95040,      95040,        0,   535680, 0x0c01541f
-0,      98010,      98010,        0,   535680, 0x9eee99b3
-0,     100980,     100980,        0,   535680, 0xd65eb689
-0,     103950,     103950,        0,   535680, 0x6e733cfa
-0,     106920,     106920,        0,   535680, 0xac536670
-0,     109890,     109890,        0,   535680, 0x002275b8
-0,     112860,     112860,        0,   535680, 0x6a5385cb
-0,     115830,     115830,        0,   535680, 0xd129ade3
-0,     118800,     118800,        0,   535680, 0x32cab5d7
-0,     121770,     121770,        0,   535680, 0x08be1c8f
-0,     124740,     124740,        0,   535680, 0x59e1fba0
-0,     127710,     127710,        0,   535680, 0x138aee3a
-0,     130680,     130680,        0,   535680, 0x4cfbcd5e
-0,     133650,     133650,        0,   535680, 0xf6cf0fb4
-0,     136620,     136620,        0,   535680, 0xb13a06de
-0,     139590,     139590,        0,   535680, 0x59176f00
-0,     142560,     142560,        0,   535680, 0xf84b4ca3
-0,     145530,     145530,        0,   535680, 0x7fd09f73
-0,     148500,     148500,        0,   535680, 0x3be383b8
-0,     151470,     151470,        0,   535680, 0xa7118e51
-0,     154440,     154440,        0,   535680, 0xbd83120c
-0,     157410,     157410,        0,   535680, 0x3bc9d256
-0,     160380,     160380,        0,   535680, 0xb6c87f87
-0,     163350,     163350,        0,   535680, 0xe80d110a
-0,     166320,     166320,        0,   535680, 0xb3a83362
-0,     169290,     169290,        0,   535680, 0xfb39eb52
-0,     172260,     172260,        0,   535680, 0xbf6e1220
-0,     175230,     175230,        0,   535680, 0x9ecdfbae
-0,     178200,     178200,        0,   535680, 0x069a65f5
-0,     181170,     181170,        0,   535680, 0x206e372c
-0,     184140,     184140,        0,   535680, 0x58c83dd4
-0,     187110,     187110,        0,   535680, 0xc3562b03
-0,     190080,     190080,        0,   535680, 0xd1ed85a0
-0,     193050,     193050,        0,   535680, 0xb6205f4b
-0,     196020,     196020,        0,   535680, 0xaedf8bfa
-0,     198990,     198990,        0,   535680, 0xa48d5dea
-0,     201960,     201960,        0,   535680, 0xff82e7c1
-0,     204930,     204930,        0,   535680, 0xc9560222
-0,     207900,     207900,        0,   535680, 0x0fafa549
-0,     210870,     210870,        0,   535680, 0x8d556ccb
-0,     213840,     213840,        0,   535680, 0x802aac1f
-0,     216810,     216810,        0,   535680, 0x7d0fa168
-0,     219780,     219780,        0,   535680, 0x1a9255c9
-0,     222750,     222750,        0,   535680, 0xb4ec7e35
-0,     225720,     225720,        0,   535680, 0x48fac072
-0,     228690,     228690,        0,   535680, 0x1e260135
-0,     231660,     231660,        0,   535680, 0xce4d5079
-0,     234630,     234630,        0,   535680, 0x13e5e4ed
-0,     237600,     237600,        0,   535680, 0x592305ec
-0,     240570,     240570,        0,   535680, 0x9e227508
-0,     243540,     243540,        0,   535680, 0x1d37e5ea
-0,     246510,     246510,        0,   535680, 0x7eae7692
-0,     249480,     249480,        0,   535680, 0xf452e4b9
-0,     252450,     252450,        0,   535680, 0x1460e7e9
-0,     255420,     255420,        0,   535680, 0xc6d8a638
-0,     258390,     258390,        0,   535680, 0x854f5fb0
-0,     261360,     261360,        0,   535680, 0x854f5fb0
-0,     264330,     264330,        0,   535680, 0x70a02d87
-0,     267300,     267300,        0,   535680, 0x9a4ad464
-0,     270270,     270270,        0,   535680, 0x9a4ad464
-0,     273240,     273240,        0,   535680, 0x9a4ad464
-0,     276210,     276210,        0,   535680, 0x9a4ad464
-0,     279180,     279180,        0,   535680, 0x9a4ad464
-0,     282150,     282150,        0,   535680, 0x9a4ad464
+#tb 0: 33/1000
+0,          0,          0,        1,   535680, 0x889c32cf
+0,          1,          1,        1,   535680, 0x0b1ef044
+0,          2,          2,        1,   535680, 0xa7d0818b
+0,          3,          3,        1,   535680, 0xf392e4e1
+0,          4,          4,        1,   535680, 0x08480c69
+0,          5,          5,        1,   535680, 0x2b8af1ed
+0,          6,          6,        1,   535680, 0x0d58e062
+0,          7,          7,        1,   535680, 0xd140ced0
+0,          8,          8,        1,   535680, 0xbd0e6652
+0,          9,          9,        1,   535680, 0xdc2f2a6b
+0,         10,         10,        1,   535680, 0x97c31a38
+0,         11,         11,        1,   535680, 0x1a2bdf38
+0,         12,         12,        1,   535680, 0xb3af3ac4
+0,         13,         13,        1,   535680, 0x07a52577
+0,         14,         14,        1,   535680, 0x78407368
+0,         15,         15,        1,   535680, 0xd2a9efc3
+0,         16,         16,        1,   535680, 0x36df2f29
+0,         17,         17,        1,   535680, 0x9821d8f7
+0,         18,         18,        1,   535680, 0xf64321aa
+0,         19,         19,        1,   535680, 0x53e4d9aa
+0,         20,         20,        1,   535680, 0xdbd6f853
+0,         21,         21,        1,   535680, 0x5d40cf8b
+0,         22,         22,        1,   535680, 0xe624af9d
+0,         23,         23,        1,   535680, 0xd9dbb4cd
+0,         24,         24,        1,   535680, 0xf14e72ec
+0,         25,         25,        1,   535680, 0xb35c18f6
+0,         26,         26,        1,   535680, 0xc96d7757
+0,         27,         27,        1,   535680, 0xdfb937df
+0,         28,         28,        1,   535680, 0x40cd71d7
+0,         29,         29,        1,   535680, 0x15e176d6
+0,         30,         30,        1,   535680, 0x7f891b24
+0,         31,         31,        1,   535680, 0xb87a8c32
+0,         32,         32,        1,   535680, 0x0c01541f
+0,         33,         33,        1,   535680, 0x9eee99b3
+0,         34,         34,        1,   535680, 0xd65eb689
+0,         35,         35,        1,   535680, 0x6e733cfa
+0,         36,         36,        1,   535680, 0xac536670
+0,         37,         37,        1,   535680, 0x002275b8
+0,         38,         38,        1,   535680, 0x6a5385cb
+0,         39,         39,        1,   535680, 0xd129ade3
+0,         40,         40,        1,   535680, 0x32cab5d7
+0,         41,         41,        1,   535680, 0x08be1c8f
+0,         42,         42,        1,   535680, 0x59e1fba0
+0,         43,         43,        1,   535680, 0x138aee3a
+0,         44,         44,        1,   535680, 0x4cfbcd5e
+0,         45,         45,        1,   535680, 0xf6cf0fb4
+0,         46,         46,        1,   535680, 0xb13a06de
+0,         47,         47,        1,   535680, 0x59176f00
+0,         48,         48,        1,   535680, 0xf84b4ca3
+0,         49,         49,        1,   535680, 0x7fd09f73
+0,         50,         50,        1,   535680, 0x3be383b8
+0,         51,         51,        1,   535680, 0xa7118e51
+0,         52,         52,        1,   535680, 0xbd83120c
+0,         53,         53,        1,   535680, 0x3bc9d256
+0,         54,         54,        1,   535680, 0xb6c87f87
+0,         55,         55,        1,   535680, 0xe80d110a
+0,         56,         56,        1,   535680, 0xb3a83362
+0,         57,         57,        1,   535680, 0xfb39eb52
+0,         58,         58,        1,   535680, 0xbf6e1220
+0,         59,         59,        1,   535680, 0x9ecdfbae
+0,         60,         60,        1,   535680, 0x069a65f5
+0,         61,         61,        1,   535680, 0x206e372c
+0,         62,         62,        1,   535680, 0x58c83dd4
+0,         63,         63,        1,   535680, 0xc3562b03
+0,         64,         64,        1,   535680, 0xd1ed85a0
+0,         65,         65,        1,   535680, 0xb6205f4b
+0,         66,         66,        1,   535680, 0xaedf8bfa
+0,         67,         67,        1,   535680, 0xa48d5dea
+0,         68,         68,        1,   535680, 0xff82e7c1
+0,         69,         69,        1,   535680, 0xc9560222
+0,         70,         70,        1,   535680, 0x0fafa549
+0,         71,         71,        1,   535680, 0x8d556ccb
+0,         72,         72,        1,   535680, 0x802aac1f
+0,         73,         73,        1,   535680, 0x7d0fa168
+0,         74,         74,        1,   535680, 0x1a9255c9
+0,         75,         75,        1,   535680, 0xb4ec7e35
+0,         76,         76,        1,   535680, 0x48fac072
+0,         77,         77,        1,   535680, 0x1e260135
+0,         78,         78,        1,   535680, 0xce4d5079
+0,         79,         79,        1,   535680, 0x13e5e4ed
+0,         80,         80,        1,   535680, 0x592305ec
+0,         81,         81,        1,   535680, 0x9e227508
+0,         82,         82,        1,   535680, 0x1d37e5ea
+0,         83,         83,        1,   535680, 0x7eae7692
+0,         84,         84,        1,   535680, 0xf452e4b9
+0,         85,         85,        1,   535680, 0x1460e7e9
+0,         86,         86,        1,   535680, 0xc6d8a638
+0,         87,         87,        1,   535680, 0x854f5fb0
+0,         88,         88,        1,   535680, 0x854f5fb0
+0,         89,         89,        1,   535680, 0x70a02d87
+0,         90,         90,        1,   535680, 0x9a4ad464
+0,         91,         91,        1,   535680, 0x9a4ad464
+0,         92,         92,        1,   535680, 0x9a4ad464
+0,         93,         93,        1,   535680, 0x9a4ad464
+0,         94,         94,        1,   535680, 0x9a4ad464
+0,         95,         95,        1,   535680, 0x9a4ad464
diff --git a/tests/ref/fate/ea-tgq b/tests/ref/fate/ea-tgq
index edb04fa..5c0648d 100644
--- a/tests/ref/fate/ea-tgq
+++ b/tests/ref/fate/ea-tgq
@@ -1,279 +1,279 @@
-#tb 0: 1/90000
-0,          0,          0,        0,    34944, 0xe33671a4
-0,       6000,       6000,        0,    34944, 0xe33671a4
-0,      12000,      12000,        0,    34944, 0xe33671a4
-0,      18000,      18000,        0,    34944, 0xe33671a4
-0,      24000,      24000,        0,    34944, 0xe33671a4
-0,      30000,      30000,        0,    34944, 0xe33671a4
-0,      36000,      36000,        0,    34944, 0xe33671a4
-0,      42000,      42000,        0,    34944, 0xe33671a4
-0,      48000,      48000,        0,    34944, 0xe33671a4
-0,      54000,      54000,        0,    34944, 0xe33671a4
-0,      60000,      60000,        0,    34944, 0xe33671a4
-0,      66000,      66000,        0,    34944, 0xe33671a4
-0,      72000,      72000,        0,    34944, 0xe33671a4
-0,      78000,      78000,        0,    34944, 0xe33671a4
-0,      84000,      84000,        0,    34944, 0xe33671a4
-0,      90000,      90000,        0,    34944, 0x63196b41
-0,      96000,      96000,        0,    34944, 0x308d6f10
-0,     102000,     102000,        0,    34944, 0x86026ced
-0,     108000,     108000,        0,    34944, 0xaa6a6bc9
-0,     114000,     114000,        0,    34944, 0x58276ee3
-0,     120000,     120000,        0,    34944, 0x402d70c2
-0,     126000,     126000,        0,    34944, 0x948d74bf
-0,     132000,     132000,        0,    34944, 0x3d31759c
-0,     138000,     138000,        0,    34944, 0x638c734e
-0,     144000,     144000,        0,    34944, 0xe218768a
-0,     150000,     150000,        0,    34944, 0xed6678ff
-0,     156000,     156000,        0,    34944, 0x381b7dda
-0,     162000,     162000,        0,    34944, 0x216680e7
-0,     168000,     168000,        0,    34944, 0xaca5810f
-0,     174000,     174000,        0,    34944, 0xf70b81eb
-0,     180000,     180000,        0,    34944, 0x3675858b
-0,     186000,     186000,        0,    34944, 0xa51188c3
-0,     192000,     192000,        0,    34944, 0x3a848bf1
-0,     198000,     198000,        0,    34944, 0x67608d4d
-0,     204000,     204000,        0,    34944, 0xafe49165
-0,     210000,     210000,        0,    34944, 0x7e8a94a7
-0,     216000,     216000,        0,    34944, 0x3b889432
-0,     222000,     222000,        0,    34944, 0x97e89623
-0,     228000,     228000,        0,    34944, 0x07819793
-0,     234000,     234000,        0,    34944, 0xdac39b87
-0,     240000,     240000,        0,    34944, 0x4d8c9d93
-0,     246000,     246000,        0,    34944, 0xcf009fa7
-0,     252000,     252000,        0,    34944, 0x2f109f6e
-0,     258000,     258000,        0,    34944, 0xcedda4eb
-0,     264000,     264000,        0,    34944, 0xfe89a6df
-0,     270000,     270000,        0,    34944, 0x195ea7a9
-0,     276000,     276000,        0,    34944, 0x9287ab92
-0,     282000,     282000,        0,    34944, 0x6d21af54
-0,     288000,     288000,        0,    34944, 0xd627b28b
-0,     294000,     294000,        0,    34944, 0x3ad5b6fd
-0,     300000,     300000,        0,    34944, 0x5101b64d
-0,     306000,     306000,        0,    34944, 0xb968b8ca
-0,     312000,     312000,        0,    34944, 0xa105b74a
-0,     318000,     318000,        0,    34944, 0xc056bdd6
-0,     324000,     324000,        0,    34944, 0xec7fc1d9
-0,     330000,     330000,        0,    34944, 0x92c3c3e0
-0,     336000,     336000,        0,    34944, 0x9bffc45c
-0,     342000,     342000,        0,    34944, 0x5aabca4b
-0,     348000,     348000,        0,    34944, 0xcbdacb26
-0,     354000,     354000,        0,    34944, 0xed6cce3f
-0,     360000,     360000,        0,    34944, 0xcc61cfb8
-0,     366000,     366000,        0,    34944, 0x7a97d427
-0,     372000,     372000,        0,    34944, 0x7cdbd5ec
-0,     378000,     378000,        0,    34944, 0x5851d9c4
-0,     384000,     384000,        0,    34944, 0x69d5dd1d
-0,     390000,     390000,        0,    34944, 0xdf30dcf4
-0,     396000,     396000,        0,    34944, 0x2359e084
-0,     402000,     402000,        0,    34944, 0xe0bae491
-0,     408000,     408000,        0,    34944, 0xa716e4fd
-0,     414000,     414000,        0,    34944, 0xe48aeaf4
-0,     420000,     420000,        0,    34944, 0x0a0deb21
-0,     426000,     426000,        0,    34944, 0xe8a56e12
-0,     432000,     432000,        0,    34944, 0x0d72c98e
-0,     438000,     438000,        0,    34944, 0x71a7bb9d
-0,     444000,     444000,        0,    34944, 0xc0c8c108
-0,     450000,     450000,        0,    34944, 0x1d1fc3ba
-0,     456000,     456000,        0,    34944, 0xebcfc67f
-0,     462000,     462000,        0,    34944, 0x2921cb5b
-0,     468000,     468000,        0,    34944, 0x793ed099
-0,     474000,     474000,        0,    34944, 0xefebd9e8
-0,     480000,     480000,        0,    34944, 0x163c2330
-0,     486000,     486000,        0,    34944, 0x35155672
-0,     492000,     492000,        0,    34944, 0x05474e2e
-0,     498000,     498000,        0,    34944, 0x9433542f
-0,     504000,     504000,        0,    34944, 0x777d5a13
-0,     510000,     510000,        0,    34944, 0x87526776
-0,     516000,     516000,        0,    34944, 0x4c3c72c1
-0,     522000,     522000,        0,    34944, 0x70407b87
-0,     528000,     528000,        0,    34944, 0x2358861d
-0,     534000,     534000,        0,    34944, 0xec61923f
-0,     540000,     540000,        0,    34944, 0x0bb2a0d4
-0,     546000,     546000,        0,    34944, 0x6b6d8624
-0,     552000,     552000,        0,    34944, 0x624761ec
-0,     558000,     558000,        0,    34944, 0xff23b926
-0,     564000,     564000,        0,    34944, 0x07fc7ca5
-0,     570000,     570000,        0,    34944, 0xa8d3ffda
-0,     576000,     576000,        0,    34944, 0xa2d31265
-0,     582000,     582000,        0,    34944, 0x5e58225e
-0,     588000,     588000,        0,    34944, 0x284b2fb0
-0,     594000,     594000,        0,    34944, 0x205b3cb1
-0,     600000,     600000,        0,    34944, 0x3fa64a09
-0,     606000,     606000,        0,    34944, 0xa5de5097
-0,     612000,     612000,        0,    34944, 0x00686cea
-0,     618000,     618000,        0,    34944, 0x465a8282
-0,     624000,     624000,        0,    34944, 0x4ceb8189
-0,     630000,     630000,        0,    34944, 0x14698509
-0,     636000,     636000,        0,    34944, 0x232c830d
-0,     642000,     642000,        0,    34944, 0x0739807c
-0,     648000,     648000,        0,    34944, 0x83b0861e
-0,     654000,     654000,        0,    34944, 0xbdc094b1
-0,     660000,     660000,        0,    34944, 0xc4c0a605
-0,     666000,     666000,        0,    34944, 0x8376b059
-0,     672000,     672000,        0,    34944, 0x2035b939
-0,     678000,     678000,        0,    34944, 0xb6bfc812
-0,     684000,     684000,        0,    34944, 0xc5d4d5c4
-0,     690000,     690000,        0,    34944, 0x492c954e
-0,     696000,     696000,        0,    34944, 0xd23f0dcc
-0,     702000,     702000,        0,    34944, 0x22d7ff6c
-0,     708000,     708000,        0,    34944, 0xd08b4168
-0,     714000,     714000,        0,    34944, 0xa82e4062
-0,     720000,     720000,        0,    34944, 0xcc4f2f31
-0,     726000,     726000,        0,    34944, 0x964b0307
-0,     732000,     732000,        0,    34944, 0xe8130606
-0,     738000,     738000,        0,    34944, 0x5fb744bf
-0,     744000,     744000,        0,    34944, 0x1546a88b
-0,     750000,     750000,        0,    34944, 0xe6e4d94d
-0,     756000,     756000,        0,    34944, 0x8d1ea97e
-0,     762000,     762000,        0,    34944, 0x3bb1fb55
-0,     768000,     768000,        0,    34944, 0x3c37e9cc
-0,     774000,     774000,        0,    34944, 0xe2d22521
-0,     780000,     780000,        0,    34944, 0x7c0ec8cc
-0,     786000,     786000,        0,    34944, 0x7c2dc956
-0,     792000,     792000,        0,    34944, 0x7fe3c263
-0,     798000,     798000,        0,    34944, 0x9a65b813
-0,     804000,     804000,        0,    34944, 0x7ea7cb14
-0,     810000,     810000,        0,    34944, 0x31ded64e
-0,     816000,     816000,        0,    34944, 0x50f30ad1
-0,     822000,     822000,        0,    34944, 0x12eac45c
-0,     828000,     828000,        0,    34944, 0x984b6335
-0,     834000,     834000,        0,    34944, 0x3b9b02f0
-0,     840000,     840000,        0,    34944, 0x4629d2a4
-0,     846000,     846000,        0,    34944, 0x38687e89
-0,     852000,     852000,        0,    34944, 0xb76620fe
-0,     858000,     858000,        0,    34944, 0x66347155
-0,     864000,     864000,        0,    34944, 0x6e6bc297
-0,     870000,     870000,        0,    34944, 0x452a653a
-0,     876000,     876000,        0,    34944, 0x8c8a0683
-0,     882000,     882000,        0,    34944, 0xaf5d7c2d
-0,     888000,     888000,        0,    34944, 0x3064a7e1
-0,     894000,     894000,        0,    34944, 0xc0657fc4
-0,     900000,     900000,        0,    34944, 0x1f129266
-0,     906000,     906000,        0,    34944, 0x35adedfb
-0,     912000,     912000,        0,    34944, 0x40a3db0d
-0,     918000,     918000,        0,    34944, 0x87bebb37
-0,     924000,     924000,        0,    34944, 0x04d7ffed
-0,     930000,     930000,        0,    34944, 0x9bde3180
-0,     936000,     936000,        0,    34944, 0xc35c25bd
-0,     942000,     942000,        0,    34944, 0x820bf4bb
-0,     948000,     948000,        0,    34944, 0x876163ef
-0,     954000,     954000,        0,    34944, 0x3ab6dac0
-0,     960000,     960000,        0,    34944, 0x69a9ef73
-0,     966000,     966000,        0,    34944, 0x0df3813c
-0,     972000,     972000,        0,    34944, 0x1bba0947
-0,     978000,     978000,        0,    34944, 0x0b7883d4
-0,     984000,     984000,        0,    34944, 0xa9972f7e
-0,     990000,     990000,        0,    34944, 0x603d08fe
-0,     996000,     996000,        0,    34944, 0x05f4f111
-0,    1002000,    1002000,        0,    34944, 0xb24fdb42
-0,    1008000,    1008000,        0,    34944, 0xfe2ad344
-0,    1014000,    1014000,        0,    34944, 0xda4bcb8f
-0,    1020000,    1020000,        0,    34944, 0xd28aca6b
-0,    1026000,    1026000,        0,    34944, 0x9486c260
-0,    1032000,    1032000,        0,    34944, 0xad9fc04d
-0,    1038000,    1038000,        0,    34944, 0x9333c0ca
-0,    1044000,    1044000,        0,    34944, 0x96e9c226
-0,    1050000,    1050000,        0,    34944, 0x3e89bd6f
-0,    1056000,    1056000,        0,    34944, 0x7a2dbd32
-0,    1062000,    1062000,        0,    34944, 0xe578ba53
-0,    1068000,    1068000,        0,    34944, 0xb77ebab1
-0,    1074000,    1074000,        0,    34944, 0xd8bfbcb1
-0,    1080000,    1080000,        0,    34944, 0x15d9bc97
-0,    1086000,    1086000,        0,    34944, 0x09c3b9f0
-0,    1092000,    1092000,        0,    34944, 0xd8c8b944
-0,    1098000,    1098000,        0,    34944, 0x2c2fb996
-0,    1104000,    1104000,        0,    34944, 0xd7a8b7e7
-0,    1110000,    1110000,        0,    34944, 0xce34b843
-0,    1116000,    1116000,        0,    34944, 0xba69e9fd
-0,    1122000,    1122000,        0,    34944, 0x1b3f1adc
-0,    1128000,    1128000,        0,    34944, 0x48f515aa
-0,    1134000,    1134000,        0,    34944, 0x864e12bb
-0,    1140000,    1140000,        0,    34944, 0xca571996
-0,    1146000,    1146000,        0,    34944, 0x1d5a1af0
-0,    1152000,    1152000,        0,    34944, 0x3d1e171f
-0,    1158000,    1158000,        0,    34944, 0xb57417ca
-0,    1164000,    1164000,        0,    34944, 0x6e6d1e9d
-0,    1170000,    1170000,        0,    34944, 0xc9971899
-0,    1176000,    1176000,        0,    34944, 0xe0b112c8
-0,    1182000,    1182000,        0,    34944, 0x121b0cd9
-0,    1188000,    1188000,        0,    34944, 0x418e0eff
-0,    1194000,    1194000,        0,    34944, 0x9e1b07d8
-0,    1200000,    1200000,        0,    34944, 0x5590064a
-0,    1206000,    1206000,        0,    34944, 0x7a170b14
-0,    1212000,    1212000,        0,    34944, 0xf25709f0
-0,    1218000,    1218000,        0,    34944, 0x94fa099a
-0,    1224000,    1224000,        0,    34944, 0x081e06ae
-0,    1230000,    1230000,        0,    34944, 0xcfc40417
-0,    1236000,    1236000,        0,    34944, 0xed33096f
-0,    1242000,    1242000,        0,    34944, 0xd73a07e2
-0,    1248000,    1248000,        0,    34944, 0xc512077d
-0,    1254000,    1254000,        0,    34944, 0x27d7021d
-0,    1260000,    1260000,        0,    34944, 0xab59fd20
-0,    1266000,    1266000,        0,    34944, 0xcc2400b7
-0,    1272000,    1272000,        0,    34944, 0xcb3bfb99
-0,    1278000,    1278000,        0,    34944, 0x0974fb1a
-0,    1284000,    1284000,        0,    34944, 0xef79f8ba
-0,    1290000,    1290000,        0,    34944, 0xf932f3a2
-0,    1296000,    1296000,        0,    34944, 0xa32df1bc
-0,    1302000,    1302000,        0,    34944, 0xdbe0f532
-0,    1308000,    1308000,        0,    34944, 0x234cf142
-0,    1314000,    1314000,        0,    34944, 0xe68befd0
-0,    1320000,    1320000,        0,    34944, 0xe4e7ee45
-0,    1326000,    1326000,        0,    34944, 0x0283eff1
-0,    1332000,    1332000,        0,    34944, 0xc8d3f6db
-0,    1338000,    1338000,        0,    34944, 0x0aa6ee88
-0,    1344000,    1344000,        0,    34944, 0xcc3de527
-0,    1350000,    1350000,        0,    34944, 0x9db0ebef
-0,    1356000,    1356000,        0,    34944, 0xa207e9db
-0,    1362000,    1362000,        0,    34944, 0x35b3e74a
-0,    1368000,    1368000,        0,    34944, 0x1988e848
-0,    1374000,    1374000,        0,    34944, 0x727de73c
-0,    1380000,    1380000,        0,    34944, 0x05d5e709
-0,    1386000,    1386000,        0,    34944, 0x3214e4b2
-0,    1392000,    1392000,        0,    34944, 0xed85e0a9
-0,    1398000,    1398000,        0,    34944, 0xf6c9e100
-0,    1404000,    1404000,        0,    34944, 0x57a8dbaf
-0,    1410000,    1410000,        0,    34944, 0xc75fdf41
-0,    1416000,    1416000,        0,    34944, 0x736fde24
-0,    1422000,    1422000,        0,    34944, 0x8d4bde80
-0,    1428000,    1428000,        0,    34944, 0x3220dc86
-0,    1434000,    1434000,        0,    34944, 0xe498da85
-0,    1440000,    1440000,        0,    34944, 0x0655daed
-0,    1446000,    1446000,        0,    34944, 0xb22ad874
-0,    1452000,    1452000,        0,    34944, 0x8198d411
-0,    1458000,    1458000,        0,    34944, 0xd0d2d557
-0,    1464000,    1464000,        0,    34944, 0xd740d1ff
-0,    1470000,    1470000,        0,    34944, 0x2783d00e
-0,    1476000,    1476000,        0,    34944, 0x7abdcd6b
-0,    1482000,    1482000,        0,    34944, 0x2e47d1eb
-0,    1488000,    1488000,        0,    34944, 0xfe1bcf60
-0,    1494000,    1494000,        0,    34944, 0xf0f0d5bb
-0,    1500000,    1500000,        0,    34944, 0x9af7d581
-0,    1506000,    1506000,        0,    34944, 0xb325ca3d
-0,    1512000,    1512000,        0,    34944, 0xd88abfbd
-0,    1518000,    1518000,        0,    34944, 0xf2bab746
-0,    1524000,    1524000,        0,    34944, 0xac44a7dd
-0,    1530000,    1530000,        0,    34944, 0x609e9ea3
-0,    1536000,    1536000,        0,    34944, 0xa39993b9
-0,    1542000,    1542000,        0,    34944, 0x9c948911
-0,    1548000,    1548000,        0,    34944, 0x72f8822d
-0,    1554000,    1554000,        0,    34944, 0x7f3f7a8c
-0,    1560000,    1560000,        0,    34944, 0x7ab475f9
-0,    1566000,    1566000,        0,    34944, 0x536f73aa
-0,    1572000,    1572000,        0,    34944, 0x86cb71e5
-0,    1578000,    1578000,        0,    34944, 0x17157186
-0,    1584000,    1584000,        0,    34944, 0xe33671a4
-0,    1590000,    1590000,        0,    34944, 0xe33671a4
-0,    1596000,    1596000,        0,    34944, 0xe33671a4
-0,    1602000,    1602000,        0,    34944, 0xe33671a4
-0,    1608000,    1608000,        0,    34944, 0xe33671a4
-0,    1614000,    1614000,        0,    34944, 0xe33671a4
-0,    1620000,    1620000,        0,    34944, 0xe33671a4
-0,    1626000,    1626000,        0,    34944, 0xe33671a4
-0,    1632000,    1632000,        0,    34944, 0xe33671a4
-0,    1638000,    1638000,        0,    34944, 0xe33671a4
-0,    1644000,    1644000,        0,    34944, 0xe33671a4
-0,    1650000,    1650000,        0,    34944, 0xe33671a4
-0,    1656000,    1656000,        0,    34944, 0xe33671a4
-0,    1662000,    1662000,        0,    34944, 0xe33671a4
+#tb 0: 1/15
+0,          0,          0,        1,    34944, 0xe33671a4
+0,          1,          1,        1,    34944, 0xe33671a4
+0,          2,          2,        1,    34944, 0xe33671a4
+0,          3,          3,        1,    34944, 0xe33671a4
+0,          4,          4,        1,    34944, 0xe33671a4
+0,          5,          5,        1,    34944, 0xe33671a4
+0,          6,          6,        1,    34944, 0xe33671a4
+0,          7,          7,        1,    34944, 0xe33671a4
+0,          8,          8,        1,    34944, 0xe33671a4
+0,          9,          9,        1,    34944, 0xe33671a4
+0,         10,         10,        1,    34944, 0xe33671a4
+0,         11,         11,        1,    34944, 0xe33671a4
+0,         12,         12,        1,    34944, 0xe33671a4
+0,         13,         13,        1,    34944, 0xe33671a4
+0,         14,         14,        1,    34944, 0xe33671a4
+0,         15,         15,        1,    34944, 0x63196b41
+0,         16,         16,        1,    34944, 0x308d6f10
+0,         17,         17,        1,    34944, 0x86026ced
+0,         18,         18,        1,    34944, 0xaa6a6bc9
+0,         19,         19,        1,    34944, 0x58276ee3
+0,         20,         20,        1,    34944, 0x402d70c2
+0,         21,         21,        1,    34944, 0x948d74bf
+0,         22,         22,        1,    34944, 0x3d31759c
+0,         23,         23,        1,    34944, 0x638c734e
+0,         24,         24,        1,    34944, 0xe218768a
+0,         25,         25,        1,    34944, 0xed6678ff
+0,         26,         26,        1,    34944, 0x381b7dda
+0,         27,         27,        1,    34944, 0x216680e7
+0,         28,         28,        1,    34944, 0xaca5810f
+0,         29,         29,        1,    34944, 0xf70b81eb
+0,         30,         30,        1,    34944, 0x3675858b
+0,         31,         31,        1,    34944, 0xa51188c3
+0,         32,         32,        1,    34944, 0x3a848bf1
+0,         33,         33,        1,    34944, 0x67608d4d
+0,         34,         34,        1,    34944, 0xafe49165
+0,         35,         35,        1,    34944, 0x7e8a94a7
+0,         36,         36,        1,    34944, 0x3b889432
+0,         37,         37,        1,    34944, 0x97e89623
+0,         38,         38,        1,    34944, 0x07819793
+0,         39,         39,        1,    34944, 0xdac39b87
+0,         40,         40,        1,    34944, 0x4d8c9d93
+0,         41,         41,        1,    34944, 0xcf009fa7
+0,         42,         42,        1,    34944, 0x2f109f6e
+0,         43,         43,        1,    34944, 0xcedda4eb
+0,         44,         44,        1,    34944, 0xfe89a6df
+0,         45,         45,        1,    34944, 0x195ea7a9
+0,         46,         46,        1,    34944, 0x9287ab92
+0,         47,         47,        1,    34944, 0x6d21af54
+0,         48,         48,        1,    34944, 0xd627b28b
+0,         49,         49,        1,    34944, 0x3ad5b6fd
+0,         50,         50,        1,    34944, 0x5101b64d
+0,         51,         51,        1,    34944, 0xb968b8ca
+0,         52,         52,        1,    34944, 0xa105b74a
+0,         53,         53,        1,    34944, 0xc056bdd6
+0,         54,         54,        1,    34944, 0xec7fc1d9
+0,         55,         55,        1,    34944, 0x92c3c3e0
+0,         56,         56,        1,    34944, 0x9bffc45c
+0,         57,         57,        1,    34944, 0x5aabca4b
+0,         58,         58,        1,    34944, 0xcbdacb26
+0,         59,         59,        1,    34944, 0xed6cce3f
+0,         60,         60,        1,    34944, 0xcc61cfb8
+0,         61,         61,        1,    34944, 0x7a97d427
+0,         62,         62,        1,    34944, 0x7cdbd5ec
+0,         63,         63,        1,    34944, 0x5851d9c4
+0,         64,         64,        1,    34944, 0x69d5dd1d
+0,         65,         65,        1,    34944, 0xdf30dcf4
+0,         66,         66,        1,    34944, 0x2359e084
+0,         67,         67,        1,    34944, 0xe0bae491
+0,         68,         68,        1,    34944, 0xa716e4fd
+0,         69,         69,        1,    34944, 0xe48aeaf4
+0,         70,         70,        1,    34944, 0x0a0deb21
+0,         71,         71,        1,    34944, 0xe8a56e12
+0,         72,         72,        1,    34944, 0x0d72c98e
+0,         73,         73,        1,    34944, 0x71a7bb9d
+0,         74,         74,        1,    34944, 0xc0c8c108
+0,         75,         75,        1,    34944, 0x1d1fc3ba
+0,         76,         76,        1,    34944, 0xebcfc67f
+0,         77,         77,        1,    34944, 0x2921cb5b
+0,         78,         78,        1,    34944, 0x793ed099
+0,         79,         79,        1,    34944, 0xefebd9e8
+0,         80,         80,        1,    34944, 0x163c2330
+0,         81,         81,        1,    34944, 0x35155672
+0,         82,         82,        1,    34944, 0x05474e2e
+0,         83,         83,        1,    34944, 0x9433542f
+0,         84,         84,        1,    34944, 0x777d5a13
+0,         85,         85,        1,    34944, 0x87526776
+0,         86,         86,        1,    34944, 0x4c3c72c1
+0,         87,         87,        1,    34944, 0x70407b87
+0,         88,         88,        1,    34944, 0x2358861d
+0,         89,         89,        1,    34944, 0xec61923f
+0,         90,         90,        1,    34944, 0x0bb2a0d4
+0,         91,         91,        1,    34944, 0x6b6d8624
+0,         92,         92,        1,    34944, 0x624761ec
+0,         93,         93,        1,    34944, 0xff23b926
+0,         94,         94,        1,    34944, 0x07fc7ca5
+0,         95,         95,        1,    34944, 0xa8d3ffda
+0,         96,         96,        1,    34944, 0xa2d31265
+0,         97,         97,        1,    34944, 0x5e58225e
+0,         98,         98,        1,    34944, 0x284b2fb0
+0,         99,         99,        1,    34944, 0x205b3cb1
+0,        100,        100,        1,    34944, 0x3fa64a09
+0,        101,        101,        1,    34944, 0xa5de5097
+0,        102,        102,        1,    34944, 0x00686cea
+0,        103,        103,        1,    34944, 0x465a8282
+0,        104,        104,        1,    34944, 0x4ceb8189
+0,        105,        105,        1,    34944, 0x14698509
+0,        106,        106,        1,    34944, 0x232c830d
+0,        107,        107,        1,    34944, 0x0739807c
+0,        108,        108,        1,    34944, 0x83b0861e
+0,        109,        109,        1,    34944, 0xbdc094b1
+0,        110,        110,        1,    34944, 0xc4c0a605
+0,        111,        111,        1,    34944, 0x8376b059
+0,        112,        112,        1,    34944, 0x2035b939
+0,        113,        113,        1,    34944, 0xb6bfc812
+0,        114,        114,        1,    34944, 0xc5d4d5c4
+0,        115,        115,        1,    34944, 0x492c954e
+0,        116,        116,        1,    34944, 0xd23f0dcc
+0,        117,        117,        1,    34944, 0x22d7ff6c
+0,        118,        118,        1,    34944, 0xd08b4168
+0,        119,        119,        1,    34944, 0xa82e4062
+0,        120,        120,        1,    34944, 0xcc4f2f31
+0,        121,        121,        1,    34944, 0x964b0307
+0,        122,        122,        1,    34944, 0xe8130606
+0,        123,        123,        1,    34944, 0x5fb744bf
+0,        124,        124,        1,    34944, 0x1546a88b
+0,        125,        125,        1,    34944, 0xe6e4d94d
+0,        126,        126,        1,    34944, 0x8d1ea97e
+0,        127,        127,        1,    34944, 0x3bb1fb55
+0,        128,        128,        1,    34944, 0x3c37e9cc
+0,        129,        129,        1,    34944, 0xe2d22521
+0,        130,        130,        1,    34944, 0x7c0ec8cc
+0,        131,        131,        1,    34944, 0x7c2dc956
+0,        132,        132,        1,    34944, 0x7fe3c263
+0,        133,        133,        1,    34944, 0x9a65b813
+0,        134,        134,        1,    34944, 0x7ea7cb14
+0,        135,        135,        1,    34944, 0x31ded64e
+0,        136,        136,        1,    34944, 0x50f30ad1
+0,        137,        137,        1,    34944, 0x12eac45c
+0,        138,        138,        1,    34944, 0x984b6335
+0,        139,        139,        1,    34944, 0x3b9b02f0
+0,        140,        140,        1,    34944, 0x4629d2a4
+0,        141,        141,        1,    34944, 0x38687e89
+0,        142,        142,        1,    34944, 0xb76620fe
+0,        143,        143,        1,    34944, 0x66347155
+0,        144,        144,        1,    34944, 0x6e6bc297
+0,        145,        145,        1,    34944, 0x452a653a
+0,        146,        146,        1,    34944, 0x8c8a0683
+0,        147,        147,        1,    34944, 0xaf5d7c2d
+0,        148,        148,        1,    34944, 0x3064a7e1
+0,        149,        149,        1,    34944, 0xc0657fc4
+0,        150,        150,        1,    34944, 0x1f129266
+0,        151,        151,        1,    34944, 0x35adedfb
+0,        152,        152,        1,    34944, 0x40a3db0d
+0,        153,        153,        1,    34944, 0x87bebb37
+0,        154,        154,        1,    34944, 0x04d7ffed
+0,        155,        155,        1,    34944, 0x9bde3180
+0,        156,        156,        1,    34944, 0xc35c25bd
+0,        157,        157,        1,    34944, 0x820bf4bb
+0,        158,        158,        1,    34944, 0x876163ef
+0,        159,        159,        1,    34944, 0x3ab6dac0
+0,        160,        160,        1,    34944, 0x69a9ef73
+0,        161,        161,        1,    34944, 0x0df3813c
+0,        162,        162,        1,    34944, 0x1bba0947
+0,        163,        163,        1,    34944, 0x0b7883d4
+0,        164,        164,        1,    34944, 0xa9972f7e
+0,        165,        165,        1,    34944, 0x603d08fe
+0,        166,        166,        1,    34944, 0x05f4f111
+0,        167,        167,        1,    34944, 0xb24fdb42
+0,        168,        168,        1,    34944, 0xfe2ad344
+0,        169,        169,        1,    34944, 0xda4bcb8f
+0,        170,        170,        1,    34944, 0xd28aca6b
+0,        171,        171,        1,    34944, 0x9486c260
+0,        172,        172,        1,    34944, 0xad9fc04d
+0,        173,        173,        1,    34944, 0x9333c0ca
+0,        174,        174,        1,    34944, 0x96e9c226
+0,        175,        175,        1,    34944, 0x3e89bd6f
+0,        176,        176,        1,    34944, 0x7a2dbd32
+0,        177,        177,        1,    34944, 0xe578ba53
+0,        178,        178,        1,    34944, 0xb77ebab1
+0,        179,        179,        1,    34944, 0xd8bfbcb1
+0,        180,        180,        1,    34944, 0x15d9bc97
+0,        181,        181,        1,    34944, 0x09c3b9f0
+0,        182,        182,        1,    34944, 0xd8c8b944
+0,        183,        183,        1,    34944, 0x2c2fb996
+0,        184,        184,        1,    34944, 0xd7a8b7e7
+0,        185,        185,        1,    34944, 0xce34b843
+0,        186,        186,        1,    34944, 0xba69e9fd
+0,        187,        187,        1,    34944, 0x1b3f1adc
+0,        188,        188,        1,    34944, 0x48f515aa
+0,        189,        189,        1,    34944, 0x864e12bb
+0,        190,        190,        1,    34944, 0xca571996
+0,        191,        191,        1,    34944, 0x1d5a1af0
+0,        192,        192,        1,    34944, 0x3d1e171f
+0,        193,        193,        1,    34944, 0xb57417ca
+0,        194,        194,        1,    34944, 0x6e6d1e9d
+0,        195,        195,        1,    34944, 0xc9971899
+0,        196,        196,        1,    34944, 0xe0b112c8
+0,        197,        197,        1,    34944, 0x121b0cd9
+0,        198,        198,        1,    34944, 0x418e0eff
+0,        199,        199,        1,    34944, 0x9e1b07d8
+0,        200,        200,        1,    34944, 0x5590064a
+0,        201,        201,        1,    34944, 0x7a170b14
+0,        202,        202,        1,    34944, 0xf25709f0
+0,        203,        203,        1,    34944, 0x94fa099a
+0,        204,        204,        1,    34944, 0x081e06ae
+0,        205,        205,        1,    34944, 0xcfc40417
+0,        206,        206,        1,    34944, 0xed33096f
+0,        207,        207,        1,    34944, 0xd73a07e2
+0,        208,        208,        1,    34944, 0xc512077d
+0,        209,        209,        1,    34944, 0x27d7021d
+0,        210,        210,        1,    34944, 0xab59fd20
+0,        211,        211,        1,    34944, 0xcc2400b7
+0,        212,        212,        1,    34944, 0xcb3bfb99
+0,        213,        213,        1,    34944, 0x0974fb1a
+0,        214,        214,        1,    34944, 0xef79f8ba
+0,        215,        215,        1,    34944, 0xf932f3a2
+0,        216,        216,        1,    34944, 0xa32df1bc
+0,        217,        217,        1,    34944, 0xdbe0f532
+0,        218,        218,        1,    34944, 0x234cf142
+0,        219,        219,        1,    34944, 0xe68befd0
+0,        220,        220,        1,    34944, 0xe4e7ee45
+0,        221,        221,        1,    34944, 0x0283eff1
+0,        222,        222,        1,    34944, 0xc8d3f6db
+0,        223,        223,        1,    34944, 0x0aa6ee88
+0,        224,        224,        1,    34944, 0xcc3de527
+0,        225,        225,        1,    34944, 0x9db0ebef
+0,        226,        226,        1,    34944, 0xa207e9db
+0,        227,        227,        1,    34944, 0x35b3e74a
+0,        228,        228,        1,    34944, 0x1988e848
+0,        229,        229,        1,    34944, 0x727de73c
+0,        230,        230,        1,    34944, 0x05d5e709
+0,        231,        231,        1,    34944, 0x3214e4b2
+0,        232,        232,        1,    34944, 0xed85e0a9
+0,        233,        233,        1,    34944, 0xf6c9e100
+0,        234,        234,        1,    34944, 0x57a8dbaf
+0,        235,        235,        1,    34944, 0xc75fdf41
+0,        236,        236,        1,    34944, 0x736fde24
+0,        237,        237,        1,    34944, 0x8d4bde80
+0,        238,        238,        1,    34944, 0x3220dc86
+0,        239,        239,        1,    34944, 0xe498da85
+0,        240,        240,        1,    34944, 0x0655daed
+0,        241,        241,        1,    34944, 0xb22ad874
+0,        242,        242,        1,    34944, 0x8198d411
+0,        243,        243,        1,    34944, 0xd0d2d557
+0,        244,        244,        1,    34944, 0xd740d1ff
+0,        245,        245,        1,    34944, 0x2783d00e
+0,        246,        246,        1,    34944, 0x7abdcd6b
+0,        247,        247,        1,    34944, 0x2e47d1eb
+0,        248,        248,        1,    34944, 0xfe1bcf60
+0,        249,        249,        1,    34944, 0xf0f0d5bb
+0,        250,        250,        1,    34944, 0x9af7d581
+0,        251,        251,        1,    34944, 0xb325ca3d
+0,        252,        252,        1,    34944, 0xd88abfbd
+0,        253,        253,        1,    34944, 0xf2bab746
+0,        254,        254,        1,    34944, 0xac44a7dd
+0,        255,        255,        1,    34944, 0x609e9ea3
+0,        256,        256,        1,    34944, 0xa39993b9
+0,        257,        257,        1,    34944, 0x9c948911
+0,        258,        258,        1,    34944, 0x72f8822d
+0,        259,        259,        1,    34944, 0x7f3f7a8c
+0,        260,        260,        1,    34944, 0x7ab475f9
+0,        261,        261,        1,    34944, 0x536f73aa
+0,        262,        262,        1,    34944, 0x86cb71e5
+0,        263,        263,        1,    34944, 0x17157186
+0,        264,        264,        1,    34944, 0xe33671a4
+0,        265,        265,        1,    34944, 0xe33671a4
+0,        266,        266,        1,    34944, 0xe33671a4
+0,        267,        267,        1,    34944, 0xe33671a4
+0,        268,        268,        1,    34944, 0xe33671a4
+0,        269,        269,        1,    34944, 0xe33671a4
+0,        270,        270,        1,    34944, 0xe33671a4
+0,        271,        271,        1,    34944, 0xe33671a4
+0,        272,        272,        1,    34944, 0xe33671a4
+0,        273,        273,        1,    34944, 0xe33671a4
+0,        274,        274,        1,    34944, 0xe33671a4
+0,        275,        275,        1,    34944, 0xe33671a4
+0,        276,        276,        1,    34944, 0xe33671a4
+0,        277,        277,        1,    34944, 0xe33671a4
diff --git a/tests/ref/fate/ea-tqi b/tests/ref/fate/ea-tqi
index ba0073b..72afb81 100644
--- a/tests/ref/fate/ea-tqi
+++ b/tests/ref/fate/ea-tqi
@@ -1,27 +1,27 @@
-#tb 0: 1/90000
-0,          0,          0,        0,   115200, 0x375ec573
-0,       6000,       6000,        0,   115200, 0x375ec573
-0,      12000,      12000,        0,   115200, 0x375ec573
-0,      18000,      18000,        0,   115200, 0x375ec573
-0,      24000,      24000,        0,   115200, 0x375ec573
-0,      30000,      30000,        0,   115200, 0x375ec573
-0,      36000,      36000,        0,   115200, 0x375ec573
-0,      42000,      42000,        0,   115200, 0x375ec573
-0,      48000,      48000,        0,   115200, 0x0b4d31bf
-0,      54000,      54000,        0,   115200, 0xdd724598
-0,      60000,      60000,        0,   115200, 0xc3077e75
-0,      66000,      66000,        0,   115200, 0xbf70778a
-0,      72000,      72000,        0,   115200, 0x117eb766
-0,      78000,      78000,        0,   115200, 0x4617fbad
-0,      84000,      84000,        0,   115200, 0x5f5b02d2
-0,      90000,      90000,        0,   115200, 0x2a9c5325
-0,      96000,      96000,        0,   115200, 0x14a89e2a
-0,     102000,     102000,        0,   115200, 0xe69aa994
-0,     108000,     108000,        0,   115200, 0xfbacf589
-0,     114000,     114000,        0,   115200, 0x1d714c6e
-0,     120000,     120000,        0,   115200, 0x6eff66cb
-0,     126000,     126000,        0,   115200, 0xee21c1cb
-0,     132000,     132000,        0,   115200, 0xce714ada
-0,     138000,     138000,        0,   115200, 0xf89d56c3
-0,     144000,     144000,        0,   115200, 0x65fd5e60
-0,     150000,     150000,        0,   115200, 0x0c256424
+#tb 0: 1/15
+0,          0,          0,        1,   115200, 0x375ec573
+0,          1,          1,        1,   115200, 0x375ec573
+0,          2,          2,        1,   115200, 0x375ec573
+0,          3,          3,        1,   115200, 0x375ec573
+0,          4,          4,        1,   115200, 0x375ec573
+0,          5,          5,        1,   115200, 0x375ec573
+0,          6,          6,        1,   115200, 0x375ec573
+0,          7,          7,        1,   115200, 0x375ec573
+0,          8,          8,        1,   115200, 0x0b4d31bf
+0,          9,          9,        1,   115200, 0xdd724598
+0,         10,         10,        1,   115200, 0xc3077e75
+0,         11,         11,        1,   115200, 0xbf70778a
+0,         12,         12,        1,   115200, 0x117eb766
+0,         13,         13,        1,   115200, 0x4617fbad
+0,         14,         14,        1,   115200, 0x5f5b02d2
+0,         15,         15,        1,   115200, 0x2a9c5325
+0,         16,         16,        1,   115200, 0x14a89e2a
+0,         17,         17,        1,   115200, 0xe69aa994
+0,         18,         18,        1,   115200, 0xfbacf589
+0,         19,         19,        1,   115200, 0x1d714c6e
+0,         20,         20,        1,   115200, 0x6eff66cb
+0,         21,         21,        1,   115200, 0xee21c1cb
+0,         22,         22,        1,   115200, 0xce714ada
+0,         23,         23,        1,   115200, 0xf89d56c3
+0,         24,         24,        1,   115200, 0x65fd5e60
+0,         25,         25,        1,   115200, 0x0c256424
diff --git a/tests/ref/fate/eval b/tests/ref/fate/eval
index dfc5ae4..d58cc80 100644
--- a/tests/ref/fate/eval
+++ b/tests/ref/fate/eval
@@ -184,5 +184,38 @@
 Evaluating 'not(0)'
 'not(0)' -> 1.000000
 
+Evaluating 'pow(0,1.23)'
+'pow(0,1.23)' -> 0.000000
+
+Evaluating 'pow(PI,1.23)'
+'pow(PI,1.23)' -> 4.087844
+
+Evaluating 'PI^1.23'
+'PI^1.23' -> 4.087844
+
+Evaluating 'pow(-1,1.23)'
+'pow(-1,1.23)' -> nan
+
+Evaluating 'if(1, 2)'
+'if(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 'taylor(1, 1)'
+'taylor(1, 1)' -> 2.718282
+
+Evaluating 'taylor(eq(mod(ld(1),4),1)-eq(mod(ld(1),4),3), PI/2, 1)'
+'taylor(eq(mod(ld(1),4),1)-eq(mod(ld(1),4),3), PI/2, 1)' -> 1.000000
+
+Evaluating 'root(sin(ld(0))-1, 2)'
+'root(sin(ld(0))-1, 2)' -> 1.570796
+
+Evaluating 'root(sin(ld(0))+6+sin(ld(0)/12)-log(ld(0)), 100)'
+'root(sin(ld(0))+6+sin(ld(0)/12)-log(ld(0)), 100)' -> 60.965601
+
 12.700000 == 12.7
 0.931323 == 0.931322575
diff --git a/tests/ref/fate/ffprobe_compact b/tests/ref/fate/ffprobe_compact
new file mode 100644
index 0000000..a276848
--- /dev/null
+++ b/tests/ref/fate/ffprobe_compact
@@ -0,0 +1,32 @@
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+stream|index=0|codec_name=pcm_s16le|profile=unknown|codec_type=audio|codec_time_base=1/44100|codec_tag_string=[1][0][0][0]|codec_tag=0x0001|sample_fmt=s16|sample_rate=44100|channels=1|bits_per_sample=16|id=N/A|r_frame_rate=0/0|avg_frame_rate=0/0|time_base=1/44100|start_pts=0|start_time=0.000000|duration_ts=527406|duration=11.959320|bit_rate=705600|nb_frames=N/A|nb_read_frames=6|nb_read_packets=6|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|tag:E=mc²
+stream|index=1|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/51200|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=320|height=240|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=4:3|pix_fmt=rgb24|level=-99|timecode=N/A|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=612317|duration=11.959316|bit_rate=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0|tag:title=foobar|tag:duration_ts=field-and-tags-conflict-attempt
+stream|index=2|codec_name=rawvideo|profile=unknown|codec_type=video|codec_time_base=1/51200|codec_tag_string=RGB[24]|codec_tag=0x18424752|width=100|height=100|has_b_frames=0|sample_aspect_ratio=1:1|display_aspect_ratio=1:1|pix_fmt=rgb24|level=-99|timecode=N/A|id=N/A|r_frame_rate=25/1|avg_frame_rate=25/1|time_base=1/51200|start_pts=0|start_time=0.000000|duration_ts=612317|duration=11.959316|bit_rate=N/A|nb_frames=N/A|nb_read_frames=4|nb_read_packets=4|disposition:default=0|disposition:dub=0|disposition:original=0|disposition:comment=0|disposition:lyrics=0|disposition:karaoke=0|disposition:forced=0|disposition:hearing_impaired=0|disposition:visual_impaired=0|disposition:clean_effects=0|disposition:attached_pic=0
+format|filename=tests/data/ffprobe-test.nut|nb_streams=3|format_name=nut|start_time=0.000000|duration=11.959320|size=1054812|bit_rate=705599|tag:title=ffprobe test file|tag:comment='A comment with CSV, XML & JSON special chars': <tag value="x">|tag:comment2=I ♥ Üñîçød€
diff --git a/tests/ref/fate/ffprobe_csv b/tests/ref/fate/ffprobe_csv
new file mode 100644
index 0000000..7a09d65
--- /dev/null
+++ b/tests/ref/fate/ffprobe_csv
@@ -0,0 +1,32 @@
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+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
+stream,0,pcm_s16le,unknown,audio,1/44100,[1][0][0][0],0x0001,s16,44100,1,16,N/A,0/0,0/0,1/44100,0,0.000000,527406,11.959320,705600,N/A,6,6,0,0,0,0,0,0,0,0,0,0,0,mc²
+stream,1,rawvideo,unknown,video,1/51200,RGB[24],0x18424752,320,240,0,1:1,4:3,rgb24,-99,N/A,N/A,25/1,25/1,1/51200,0,0.000000,612317,11.959316,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0,foobar,field-and-tags-conflict-attempt
+stream,2,rawvideo,unknown,video,1/51200,RGB[24],0x18424752,100,100,0,1:1,1:1,rgb24,-99,N/A,N/A,25/1,25/1,1/51200,0,0.000000,612317,11.959316,N/A,N/A,4,4,0,0,0,0,0,0,0,0,0,0,0
+format,tests/data/ffprobe-test.nut,3,nut,0.000000,11.959320,1054812,705599,ffprobe test file,"'A comment with CSV, XML & JSON special chars': <tag value=""x"">",I ♥ Üñîçød€
diff --git a/tests/ref/fate/ffprobe_default b/tests/ref/fate/ffprobe_default
new file mode 100644
index 0000000..585f340
--- /dev/null
+++ b/tests/ref/fate/ffprobe_default
@@ -0,0 +1,607 @@
+[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
+[/PACKET]
+[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]
+[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
+[/PACKET]
+[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]
+[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
+[/PACKET]
+[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]
+[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
+[/PACKET]
+[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]
+[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
+[/PACKET]
+[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]
+[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
+[/PACKET]
+[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]
+[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
+[/PACKET]
+[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]
+[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
+[/PACKET]
+[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]
+[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
+[/PACKET]
+[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]
+[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
+[/PACKET]
+[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]
+[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
+[/PACKET]
+[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]
+[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
+[/PACKET]
+[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]
+[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
+[/PACKET]
+[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]
+[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
+[/PACKET]
+[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]
+[STREAM]
+index=0
+codec_name=pcm_s16le
+profile=unknown
+codec_type=audio
+codec_time_base=1/44100
+codec_tag_string=[1][0][0][0]
+codec_tag=0x0001
+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]
+[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]
+[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
+[/STREAM]
+[FORMAT]
+filename=tests/data/ffprobe-test.nut
+nb_streams=3
+format_name=nut
+start_time=0.000000
+duration=11.959320
+size=1054812
+bit_rate=705599
+TAG:title=ffprobe test file
+TAG:comment='A comment with CSV, XML & JSON special chars': <tag value="x">
+TAG:comment2=I ♥ Üñîçød€
+[/FORMAT]
diff --git a/tests/ref/fate/ffprobe_flat b/tests/ref/fate/ffprobe_flat
new file mode 100644
index 0000000..010f669
--- /dev/null
+++ b/tests/ref/fate/ffprobe_flat
@@ -0,0 +1,543 @@
+packets_and_frames.packet.0.codec_type="audio"
+packets_and_frames.packet.0.stream_index=0
+packets_and_frames.packet.0.pts=0
+packets_and_frames.packet.0.pts_time="0.000000"
+packets_and_frames.packet.0.dts=0
+packets_and_frames.packet.0.dts_time="0.000000"
+packets_and_frames.packet.0.duration=1024
+packets_and_frames.packet.0.duration_time="0.023220"
+packets_and_frames.packet.0.convergence_duration="N/A"
+packets_and_frames.packet.0.convergence_duration_time="N/A"
+packets_and_frames.packet.0.size="2048"
+packets_and_frames.packet.0.pos="572"
+packets_and_frames.packet.0.flags="K"
+packets_and_frames.frame.0.media_type="audio"
+packets_and_frames.frame.0.key_frame=1
+packets_and_frames.frame.0.pkt_pts=0
+packets_and_frames.frame.0.pkt_pts_time="0.000000"
+packets_and_frames.frame.0.pkt_dts=0
+packets_and_frames.frame.0.pkt_dts_time="0.000000"
+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.sample_fmt="s16"
+packets_and_frames.frame.0.nb_samples=1024
+packets_and_frames.frame.0.channels=1
+packets_and_frames.frame.0.channel_layout="unknown"
+packets_and_frames.packet.1.codec_type="video"
+packets_and_frames.packet.1.stream_index=1
+packets_and_frames.packet.1.pts=0
+packets_and_frames.packet.1.pts_time="0.000000"
+packets_and_frames.packet.1.dts=0
+packets_and_frames.packet.1.dts_time="0.000000"
+packets_and_frames.packet.1.duration=2048
+packets_and_frames.packet.1.duration_time="0.040000"
+packets_and_frames.packet.1.convergence_duration="N/A"
+packets_and_frames.packet.1.convergence_duration_time="N/A"
+packets_and_frames.packet.1.size="230400"
+packets_and_frames.packet.1.pos="2647"
+packets_and_frames.packet.1.flags="K"
+packets_and_frames.frame.1.media_type="video"
+packets_and_frames.frame.1.key_frame=1
+packets_and_frames.frame.1.pkt_pts=0
+packets_and_frames.frame.1.pkt_pts_time="0.000000"
+packets_and_frames.frame.1.pkt_dts=0
+packets_and_frames.frame.1.pkt_dts_time="0.000000"
+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.width=320
+packets_and_frames.frame.1.height=240
+packets_and_frames.frame.1.pix_fmt="rgb24"
+packets_and_frames.frame.1.sample_aspect_ratio="1:1"
+packets_and_frames.frame.1.pict_type="I"
+packets_and_frames.frame.1.coded_picture_number=0
+packets_and_frames.frame.1.display_picture_number=0
+packets_and_frames.frame.1.interlaced_frame=0
+packets_and_frames.frame.1.top_field_first=0
+packets_and_frames.frame.1.repeat_pict=0
+packets_and_frames.frame.1.reference=0
+packets_and_frames.packet.2.codec_type="video"
+packets_and_frames.packet.2.stream_index=2
+packets_and_frames.packet.2.pts=0
+packets_and_frames.packet.2.pts_time="0.000000"
+packets_and_frames.packet.2.dts=0
+packets_and_frames.packet.2.dts_time="0.000000"
+packets_and_frames.packet.2.duration=2048
+packets_and_frames.packet.2.duration_time="0.040000"
+packets_and_frames.packet.2.convergence_duration="N/A"
+packets_and_frames.packet.2.convergence_duration_time="N/A"
+packets_and_frames.packet.2.size="30000"
+packets_and_frames.packet.2.pos="233068"
+packets_and_frames.packet.2.flags="K"
+packets_and_frames.frame.2.media_type="video"
+packets_and_frames.frame.2.key_frame=1
+packets_and_frames.frame.2.pkt_pts=0
+packets_and_frames.frame.2.pkt_pts_time="0.000000"
+packets_and_frames.frame.2.pkt_dts=0
+packets_and_frames.frame.2.pkt_dts_time="0.000000"
+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.width=100
+packets_and_frames.frame.2.height=100
+packets_and_frames.frame.2.pix_fmt="rgb24"
+packets_and_frames.frame.2.sample_aspect_ratio="1:1"
+packets_and_frames.frame.2.pict_type="I"
+packets_and_frames.frame.2.coded_picture_number=0
+packets_and_frames.frame.2.display_picture_number=0
+packets_and_frames.frame.2.interlaced_frame=0
+packets_and_frames.frame.2.top_field_first=0
+packets_and_frames.frame.2.repeat_pict=0
+packets_and_frames.frame.2.reference=0
+packets_and_frames.packet.3.codec_type="audio"
+packets_and_frames.packet.3.stream_index=0
+packets_and_frames.packet.3.pts=1024
+packets_and_frames.packet.3.pts_time="0.023220"
+packets_and_frames.packet.3.dts=1024
+packets_and_frames.packet.3.dts_time="0.023220"
+packets_and_frames.packet.3.duration=1024
+packets_and_frames.packet.3.duration_time="0.023220"
+packets_and_frames.packet.3.convergence_duration="N/A"
+packets_and_frames.packet.3.convergence_duration_time="N/A"
+packets_and_frames.packet.3.size="2048"
+packets_and_frames.packet.3.pos="263073"
+packets_and_frames.packet.3.flags="K"
+packets_and_frames.frame.3.media_type="audio"
+packets_and_frames.frame.3.key_frame=1
+packets_and_frames.frame.3.pkt_pts=1024
+packets_and_frames.frame.3.pkt_pts_time="0.023220"
+packets_and_frames.frame.3.pkt_dts=1024
+packets_and_frames.frame.3.pkt_dts_time="0.023220"
+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.sample_fmt="s16"
+packets_and_frames.frame.3.nb_samples=1024
+packets_and_frames.frame.3.channels=1
+packets_and_frames.frame.3.channel_layout="unknown"
+packets_and_frames.packet.4.codec_type="video"
+packets_and_frames.packet.4.stream_index=1
+packets_and_frames.packet.4.pts=2048
+packets_and_frames.packet.4.pts_time="0.040000"
+packets_and_frames.packet.4.dts=2048
+packets_and_frames.packet.4.dts_time="0.040000"
+packets_and_frames.packet.4.duration=2048
+packets_and_frames.packet.4.duration_time="0.040000"
+packets_and_frames.packet.4.convergence_duration="N/A"
+packets_and_frames.packet.4.convergence_duration_time="N/A"
+packets_and_frames.packet.4.size="230400"
+packets_and_frames.packet.4.pos="265151"
+packets_and_frames.packet.4.flags="K"
+packets_and_frames.frame.4.media_type="video"
+packets_and_frames.frame.4.key_frame=1
+packets_and_frames.frame.4.pkt_pts=2048
+packets_and_frames.frame.4.pkt_pts_time="0.040000"
+packets_and_frames.frame.4.pkt_dts=2048
+packets_and_frames.frame.4.pkt_dts_time="0.040000"
+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.width=320
+packets_and_frames.frame.4.height=240
+packets_and_frames.frame.4.pix_fmt="rgb24"
+packets_and_frames.frame.4.sample_aspect_ratio="1:1"
+packets_and_frames.frame.4.pict_type="I"
+packets_and_frames.frame.4.coded_picture_number=0
+packets_and_frames.frame.4.display_picture_number=0
+packets_and_frames.frame.4.interlaced_frame=0
+packets_and_frames.frame.4.top_field_first=0
+packets_and_frames.frame.4.repeat_pict=0
+packets_and_frames.frame.4.reference=0
+packets_and_frames.packet.5.codec_type="video"
+packets_and_frames.packet.5.stream_index=2
+packets_and_frames.packet.5.pts=2048
+packets_and_frames.packet.5.pts_time="0.040000"
+packets_and_frames.packet.5.dts=2048
+packets_and_frames.packet.5.dts_time="0.040000"
+packets_and_frames.packet.5.duration=2048
+packets_and_frames.packet.5.duration_time="0.040000"
+packets_and_frames.packet.5.convergence_duration="N/A"
+packets_and_frames.packet.5.convergence_duration_time="N/A"
+packets_and_frames.packet.5.size="30000"
+packets_and_frames.packet.5.pos="495575"
+packets_and_frames.packet.5.flags="K"
+packets_and_frames.frame.5.media_type="video"
+packets_and_frames.frame.5.key_frame=1
+packets_and_frames.frame.5.pkt_pts=2048
+packets_and_frames.frame.5.pkt_pts_time="0.040000"
+packets_and_frames.frame.5.pkt_dts=2048
+packets_and_frames.frame.5.pkt_dts_time="0.040000"
+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.width=100
+packets_and_frames.frame.5.height=100
+packets_and_frames.frame.5.pix_fmt="rgb24"
+packets_and_frames.frame.5.sample_aspect_ratio="1:1"
+packets_and_frames.frame.5.pict_type="I"
+packets_and_frames.frame.5.coded_picture_number=0
+packets_and_frames.frame.5.display_picture_number=0
+packets_and_frames.frame.5.interlaced_frame=0
+packets_and_frames.frame.5.top_field_first=0
+packets_and_frames.frame.5.repeat_pict=0
+packets_and_frames.frame.5.reference=0
+packets_and_frames.packet.6.codec_type="audio"
+packets_and_frames.packet.6.stream_index=0
+packets_and_frames.packet.6.pts=2048
+packets_and_frames.packet.6.pts_time="0.046440"
+packets_and_frames.packet.6.dts=2048
+packets_and_frames.packet.6.dts_time="0.046440"
+packets_and_frames.packet.6.duration=1024
+packets_and_frames.packet.6.duration_time="0.023220"
+packets_and_frames.packet.6.convergence_duration="N/A"
+packets_and_frames.packet.6.convergence_duration_time="N/A"
+packets_and_frames.packet.6.size="2048"
+packets_and_frames.packet.6.pos="525580"
+packets_and_frames.packet.6.flags="K"
+packets_and_frames.frame.6.media_type="audio"
+packets_and_frames.frame.6.key_frame=1
+packets_and_frames.frame.6.pkt_pts=2048
+packets_and_frames.frame.6.pkt_pts_time="0.046440"
+packets_and_frames.frame.6.pkt_dts=2048
+packets_and_frames.frame.6.pkt_dts_time="0.046440"
+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.sample_fmt="s16"
+packets_and_frames.frame.6.nb_samples=1024
+packets_and_frames.frame.6.channels=1
+packets_and_frames.frame.6.channel_layout="unknown"
+packets_and_frames.packet.7.codec_type="audio"
+packets_and_frames.packet.7.stream_index=0
+packets_and_frames.packet.7.pts=3072
+packets_and_frames.packet.7.pts_time="0.069660"
+packets_and_frames.packet.7.dts=3072
+packets_and_frames.packet.7.dts_time="0.069660"
+packets_and_frames.packet.7.duration=1024
+packets_and_frames.packet.7.duration_time="0.023220"
+packets_and_frames.packet.7.convergence_duration="N/A"
+packets_and_frames.packet.7.convergence_duration_time="N/A"
+packets_and_frames.packet.7.size="2048"
+packets_and_frames.packet.7.pos="527651"
+packets_and_frames.packet.7.flags="K"
+packets_and_frames.frame.7.media_type="audio"
+packets_and_frames.frame.7.key_frame=1
+packets_and_frames.frame.7.pkt_pts=3072
+packets_and_frames.frame.7.pkt_pts_time="0.069660"
+packets_and_frames.frame.7.pkt_dts=3072
+packets_and_frames.frame.7.pkt_dts_time="0.069660"
+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.sample_fmt="s16"
+packets_and_frames.frame.7.nb_samples=1024
+packets_and_frames.frame.7.channels=1
+packets_and_frames.frame.7.channel_layout="unknown"
+packets_and_frames.packet.8.codec_type="video"
+packets_and_frames.packet.8.stream_index=1
+packets_and_frames.packet.8.pts=4096
+packets_and_frames.packet.8.pts_time="0.080000"
+packets_and_frames.packet.8.dts=4096
+packets_and_frames.packet.8.dts_time="0.080000"
+packets_and_frames.packet.8.duration=2048
+packets_and_frames.packet.8.duration_time="0.040000"
+packets_and_frames.packet.8.convergence_duration="N/A"
+packets_and_frames.packet.8.convergence_duration_time="N/A"
+packets_and_frames.packet.8.size="230400"
+packets_and_frames.packet.8.pos="529729"
+packets_and_frames.packet.8.flags="K"
+packets_and_frames.frame.8.media_type="video"
+packets_and_frames.frame.8.key_frame=1
+packets_and_frames.frame.8.pkt_pts=4096
+packets_and_frames.frame.8.pkt_pts_time="0.080000"
+packets_and_frames.frame.8.pkt_dts=4096
+packets_and_frames.frame.8.pkt_dts_time="0.080000"
+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.width=320
+packets_and_frames.frame.8.height=240
+packets_and_frames.frame.8.pix_fmt="rgb24"
+packets_and_frames.frame.8.sample_aspect_ratio="1:1"
+packets_and_frames.frame.8.pict_type="I"
+packets_and_frames.frame.8.coded_picture_number=0
+packets_and_frames.frame.8.display_picture_number=0
+packets_and_frames.frame.8.interlaced_frame=0
+packets_and_frames.frame.8.top_field_first=0
+packets_and_frames.frame.8.repeat_pict=0
+packets_and_frames.frame.8.reference=0
+packets_and_frames.packet.9.codec_type="video"
+packets_and_frames.packet.9.stream_index=2
+packets_and_frames.packet.9.pts=4096
+packets_and_frames.packet.9.pts_time="0.080000"
+packets_and_frames.packet.9.dts=4096
+packets_and_frames.packet.9.dts_time="0.080000"
+packets_and_frames.packet.9.duration=2048
+packets_and_frames.packet.9.duration_time="0.040000"
+packets_and_frames.packet.9.convergence_duration="N/A"
+packets_and_frames.packet.9.convergence_duration_time="N/A"
+packets_and_frames.packet.9.size="30000"
+packets_and_frames.packet.9.pos="760153"
+packets_and_frames.packet.9.flags="K"
+packets_and_frames.frame.9.media_type="video"
+packets_and_frames.frame.9.key_frame=1
+packets_and_frames.frame.9.pkt_pts=4096
+packets_and_frames.frame.9.pkt_pts_time="0.080000"
+packets_and_frames.frame.9.pkt_dts=4096
+packets_and_frames.frame.9.pkt_dts_time="0.080000"
+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.width=100
+packets_and_frames.frame.9.height=100
+packets_and_frames.frame.9.pix_fmt="rgb24"
+packets_and_frames.frame.9.sample_aspect_ratio="1:1"
+packets_and_frames.frame.9.pict_type="I"
+packets_and_frames.frame.9.coded_picture_number=0
+packets_and_frames.frame.9.display_picture_number=0
+packets_and_frames.frame.9.interlaced_frame=0
+packets_and_frames.frame.9.top_field_first=0
+packets_and_frames.frame.9.repeat_pict=0
+packets_and_frames.frame.9.reference=0
+packets_and_frames.packet.10.codec_type="audio"
+packets_and_frames.packet.10.stream_index=0
+packets_and_frames.packet.10.pts=4096
+packets_and_frames.packet.10.pts_time="0.092880"
+packets_and_frames.packet.10.dts=4096
+packets_and_frames.packet.10.dts_time="0.092880"
+packets_and_frames.packet.10.duration=1024
+packets_and_frames.packet.10.duration_time="0.023220"
+packets_and_frames.packet.10.convergence_duration="N/A"
+packets_and_frames.packet.10.convergence_duration_time="N/A"
+packets_and_frames.packet.10.size="2048"
+packets_and_frames.packet.10.pos="790158"
+packets_and_frames.packet.10.flags="K"
+packets_and_frames.frame.10.media_type="audio"
+packets_and_frames.frame.10.key_frame=1
+packets_and_frames.frame.10.pkt_pts=4096
+packets_and_frames.frame.10.pkt_pts_time="0.092880"
+packets_and_frames.frame.10.pkt_dts=4096
+packets_and_frames.frame.10.pkt_dts_time="0.092880"
+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.sample_fmt="s16"
+packets_and_frames.frame.10.nb_samples=1024
+packets_and_frames.frame.10.channels=1
+packets_and_frames.frame.10.channel_layout="unknown"
+packets_and_frames.packet.11.codec_type="audio"
+packets_and_frames.packet.11.stream_index=0
+packets_and_frames.packet.11.pts=5120
+packets_and_frames.packet.11.pts_time="0.116100"
+packets_and_frames.packet.11.dts=5120
+packets_and_frames.packet.11.dts_time="0.116100"
+packets_and_frames.packet.11.duration=1024
+packets_and_frames.packet.11.duration_time="0.023220"
+packets_and_frames.packet.11.convergence_duration="N/A"
+packets_and_frames.packet.11.convergence_duration_time="N/A"
+packets_and_frames.packet.11.size="2048"
+packets_and_frames.packet.11.pos="792229"
+packets_and_frames.packet.11.flags="K"
+packets_and_frames.frame.11.media_type="audio"
+packets_and_frames.frame.11.key_frame=1
+packets_and_frames.frame.11.pkt_pts=5120
+packets_and_frames.frame.11.pkt_pts_time="0.116100"
+packets_and_frames.frame.11.pkt_dts=5120
+packets_and_frames.frame.11.pkt_dts_time="0.116100"
+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.sample_fmt="s16"
+packets_and_frames.frame.11.nb_samples=1024
+packets_and_frames.frame.11.channels=1
+packets_and_frames.frame.11.channel_layout="unknown"
+packets_and_frames.packet.12.codec_type="video"
+packets_and_frames.packet.12.stream_index=1
+packets_and_frames.packet.12.pts=6144
+packets_and_frames.packet.12.pts_time="0.120000"
+packets_and_frames.packet.12.dts=6144
+packets_and_frames.packet.12.dts_time="0.120000"
+packets_and_frames.packet.12.duration=2048
+packets_and_frames.packet.12.duration_time="0.040000"
+packets_and_frames.packet.12.convergence_duration="N/A"
+packets_and_frames.packet.12.convergence_duration_time="N/A"
+packets_and_frames.packet.12.size="230400"
+packets_and_frames.packet.12.pos="794307"
+packets_and_frames.packet.12.flags="K"
+packets_and_frames.frame.12.media_type="video"
+packets_and_frames.frame.12.key_frame=1
+packets_and_frames.frame.12.pkt_pts=6144
+packets_and_frames.frame.12.pkt_pts_time="0.120000"
+packets_and_frames.frame.12.pkt_dts=6144
+packets_and_frames.frame.12.pkt_dts_time="0.120000"
+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.width=320
+packets_and_frames.frame.12.height=240
+packets_and_frames.frame.12.pix_fmt="rgb24"
+packets_and_frames.frame.12.sample_aspect_ratio="1:1"
+packets_and_frames.frame.12.pict_type="I"
+packets_and_frames.frame.12.coded_picture_number=0
+packets_and_frames.frame.12.display_picture_number=0
+packets_and_frames.frame.12.interlaced_frame=0
+packets_and_frames.frame.12.top_field_first=0
+packets_and_frames.frame.12.repeat_pict=0
+packets_and_frames.frame.12.reference=0
+packets_and_frames.packet.13.codec_type="video"
+packets_and_frames.packet.13.stream_index=2
+packets_and_frames.packet.13.pts=6144
+packets_and_frames.packet.13.pts_time="0.120000"
+packets_and_frames.packet.13.dts=6144
+packets_and_frames.packet.13.dts_time="0.120000"
+packets_and_frames.packet.13.duration=2048
+packets_and_frames.packet.13.duration_time="0.040000"
+packets_and_frames.packet.13.convergence_duration="N/A"
+packets_and_frames.packet.13.convergence_duration_time="N/A"
+packets_and_frames.packet.13.size="30000"
+packets_and_frames.packet.13.pos="1024731"
+packets_and_frames.packet.13.flags="K"
+packets_and_frames.frame.13.media_type="video"
+packets_and_frames.frame.13.key_frame=1
+packets_and_frames.frame.13.pkt_pts=6144
+packets_and_frames.frame.13.pkt_pts_time="0.120000"
+packets_and_frames.frame.13.pkt_dts=6144
+packets_and_frames.frame.13.pkt_dts_time="0.120000"
+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.width=100
+packets_and_frames.frame.13.height=100
+packets_and_frames.frame.13.pix_fmt="rgb24"
+packets_and_frames.frame.13.sample_aspect_ratio="1:1"
+packets_and_frames.frame.13.pict_type="I"
+packets_and_frames.frame.13.coded_picture_number=0
+packets_and_frames.frame.13.display_picture_number=0
+packets_and_frames.frame.13.interlaced_frame=0
+packets_and_frames.frame.13.top_field_first=0
+packets_and_frames.frame.13.repeat_pict=0
+packets_and_frames.frame.13.reference=0
+streams.stream.0.index=0
+streams.stream.0.codec_name="pcm_s16le"
+streams.stream.0.profile="unknown"
+streams.stream.0.codec_type="audio"
+streams.stream.0.codec_time_base="1/44100"
+streams.stream.0.codec_tag_string="[1][0][0][0]"
+streams.stream.0.codec_tag="0x0001"
+streams.stream.0.sample_fmt="s16"
+streams.stream.0.sample_rate="44100"
+streams.stream.0.channels=1
+streams.stream.0.bits_per_sample=16
+streams.stream.0.id="N/A"
+streams.stream.0.r_frame_rate="0/0"
+streams.stream.0.avg_frame_rate="0/0"
+streams.stream.0.time_base="1/44100"
+streams.stream.0.start_pts=0
+streams.stream.0.start_time="0.000000"
+streams.stream.0.duration_ts=527406
+streams.stream.0.duration="11.959320"
+streams.stream.0.bit_rate="705600"
+streams.stream.0.nb_frames="N/A"
+streams.stream.0.nb_read_frames="6"
+streams.stream.0.nb_read_packets="6"
+streams.stream.0.disposition.default=0
+streams.stream.0.disposition.dub=0
+streams.stream.0.disposition.original=0
+streams.stream.0.disposition.comment=0
+streams.stream.0.disposition.lyrics=0
+streams.stream.0.disposition.karaoke=0
+streams.stream.0.disposition.forced=0
+streams.stream.0.disposition.hearing_impaired=0
+streams.stream.0.disposition.visual_impaired=0
+streams.stream.0.disposition.clean_effects=0
+streams.stream.0.disposition.attached_pic=0
+streams.stream.0.tags.E="mc²"
+streams.stream.1.index=1
+streams.stream.1.codec_name="rawvideo"
+streams.stream.1.profile="unknown"
+streams.stream.1.codec_type="video"
+streams.stream.1.codec_time_base="1/51200"
+streams.stream.1.codec_tag_string="RGB[24]"
+streams.stream.1.codec_tag="0x18424752"
+streams.stream.1.width=320
+streams.stream.1.height=240
+streams.stream.1.has_b_frames=0
+streams.stream.1.sample_aspect_ratio="1:1"
+streams.stream.1.display_aspect_ratio="4:3"
+streams.stream.1.pix_fmt="rgb24"
+streams.stream.1.level=-99
+streams.stream.1.timecode="N/A"
+streams.stream.1.id="N/A"
+streams.stream.1.r_frame_rate="25/1"
+streams.stream.1.avg_frame_rate="25/1"
+streams.stream.1.time_base="1/51200"
+streams.stream.1.start_pts=0
+streams.stream.1.start_time="0.000000"
+streams.stream.1.duration_ts=612317
+streams.stream.1.duration="11.959316"
+streams.stream.1.bit_rate="N/A"
+streams.stream.1.nb_frames="N/A"
+streams.stream.1.nb_read_frames="4"
+streams.stream.1.nb_read_packets="4"
+streams.stream.1.disposition.default=0
+streams.stream.1.disposition.dub=0
+streams.stream.1.disposition.original=0
+streams.stream.1.disposition.comment=0
+streams.stream.1.disposition.lyrics=0
+streams.stream.1.disposition.karaoke=0
+streams.stream.1.disposition.forced=0
+streams.stream.1.disposition.hearing_impaired=0
+streams.stream.1.disposition.visual_impaired=0
+streams.stream.1.disposition.clean_effects=0
+streams.stream.1.disposition.attached_pic=0
+streams.stream.1.tags.title="foobar"
+streams.stream.1.tags.duration_ts="field-and-tags-conflict-attempt"
+streams.stream.2.index=2
+streams.stream.2.codec_name="rawvideo"
+streams.stream.2.profile="unknown"
+streams.stream.2.codec_type="video"
+streams.stream.2.codec_time_base="1/51200"
+streams.stream.2.codec_tag_string="RGB[24]"
+streams.stream.2.codec_tag="0x18424752"
+streams.stream.2.width=100
+streams.stream.2.height=100
+streams.stream.2.has_b_frames=0
+streams.stream.2.sample_aspect_ratio="1:1"
+streams.stream.2.display_aspect_ratio="1:1"
+streams.stream.2.pix_fmt="rgb24"
+streams.stream.2.level=-99
+streams.stream.2.timecode="N/A"
+streams.stream.2.id="N/A"
+streams.stream.2.r_frame_rate="25/1"
+streams.stream.2.avg_frame_rate="25/1"
+streams.stream.2.time_base="1/51200"
+streams.stream.2.start_pts=0
+streams.stream.2.start_time="0.000000"
+streams.stream.2.duration_ts=612317
+streams.stream.2.duration="11.959316"
+streams.stream.2.bit_rate="N/A"
+streams.stream.2.nb_frames="N/A"
+streams.stream.2.nb_read_frames="4"
+streams.stream.2.nb_read_packets="4"
+streams.stream.2.disposition.default=0
+streams.stream.2.disposition.dub=0
+streams.stream.2.disposition.original=0
+streams.stream.2.disposition.comment=0
+streams.stream.2.disposition.lyrics=0
+streams.stream.2.disposition.karaoke=0
+streams.stream.2.disposition.forced=0
+streams.stream.2.disposition.hearing_impaired=0
+streams.stream.2.disposition.visual_impaired=0
+streams.stream.2.disposition.clean_effects=0
+streams.stream.2.disposition.attached_pic=0
+format.filename="tests/data/ffprobe-test.nut"
+format.nb_streams=3
+format.format_name="nut"
+format.start_time="0.000000"
+format.duration="11.959320"
+format.size="1054812"
+format.bit_rate="705599"
+format.tags.title="ffprobe test file"
+format.tags.comment="'A comment with CSV, XML & JSON special chars': <tag value=\"x\">"
+format.tags.comment2="I ♥ Üñîçød€"
diff --git a/tests/ref/fate/ffprobe_ini b/tests/ref/fate/ffprobe_ini
new file mode 100644
index 0000000..af38129
--- /dev/null
+++ b/tests/ref/fate/ffprobe_ini
@@ -0,0 +1,620 @@
+# ffprobe output
+
+[packets_and_frames.packet.0]
+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
+
+[packets_and_frames.frame.0]
+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
+
+[packets_and_frames.packet.1]
+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
+
+[packets_and_frames.frame.1]
+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
+
+[packets_and_frames.packet.2]
+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
+
+[packets_and_frames.frame.2]
+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
+
+[packets_and_frames.packet.3]
+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
+
+[packets_and_frames.frame.3]
+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
+
+[packets_and_frames.packet.4]
+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
+
+[packets_and_frames.frame.4]
+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
+
+[packets_and_frames.packet.5]
+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
+
+[packets_and_frames.frame.5]
+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
+
+[packets_and_frames.packet.6]
+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
+
+[packets_and_frames.frame.6]
+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
+
+[packets_and_frames.packet.7]
+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
+
+[packets_and_frames.frame.7]
+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
+
+[packets_and_frames.packet.8]
+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
+
+[packets_and_frames.frame.8]
+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
+
+[packets_and_frames.packet.9]
+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
+
+[packets_and_frames.frame.9]
+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
+
+[packets_and_frames.packet.10]
+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
+
+[packets_and_frames.frame.10]
+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
+
+[packets_and_frames.packet.11]
+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
+
+[packets_and_frames.frame.11]
+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
+
+[packets_and_frames.packet.12]
+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
+
+[packets_and_frames.frame.12]
+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
+
+[packets_and_frames.packet.13]
+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
+
+[packets_and_frames.frame.13]
+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
+
+[streams.stream.0]
+index=0
+codec_name=pcm_s16le
+profile=unknown
+codec_type=audio
+codec_time_base=1/44100
+codec_tag_string=[1][0][0][0]
+codec_tag=0x0001
+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
+
+[streams.stream.0.disposition]
+default=0
+dub=0
+original=0
+comment=0
+lyrics=0
+karaoke=0
+forced=0
+hearing_impaired=0
+visual_impaired=0
+clean_effects=0
+attached_pic=0
+
+[streams.stream.0.tags]
+E=mc²
+
+[streams.stream.1]
+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
+
+[streams.stream.1.disposition]
+default=0
+dub=0
+original=0
+comment=0
+lyrics=0
+karaoke=0
+forced=0
+hearing_impaired=0
+visual_impaired=0
+clean_effects=0
+attached_pic=0
+
+[streams.stream.1.tags]
+title=foobar
+duration_ts=field-and-tags-conflict-attempt
+
+[streams.stream.2]
+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
+
+[streams.stream.2.disposition]
+default=0
+dub=0
+original=0
+comment=0
+lyrics=0
+karaoke=0
+forced=0
+hearing_impaired=0
+visual_impaired=0
+clean_effects=0
+attached_pic=0
+
+[format]
+filename=tests/data/ffprobe-test.nut
+nb_streams=3
+format_name=nut
+start_time=0.000000
+duration=11.959320
+size=1054812
+bit_rate=705599
+
+[format.tags]
+title=ffprobe test file
+comment='A comment with CSV, XML & JSON special chars'\: <tag value\="x">
+comment2=I ♥ Üñîçød€
diff --git a/tests/ref/fate/ffprobe_json b/tests/ref/fate/ffprobe_json
new file mode 100644
index 0000000..37e2e51
--- /dev/null
+++ b/tests/ref/fate/ffprobe_json
@@ -0,0 +1,606 @@
+{
+    "packets_and_frames": [
+        {
+            "type": "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"
+        },
+        {
+            "type": "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
+        },
+        {
+            "type": "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"
+        },
+        {
+            "type": "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
+        },
+        {
+            "type": "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"
+        },
+        {
+            "type": "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
+        },
+        {
+            "type": "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"
+        },
+        {
+            "type": "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
+        },
+        {
+            "type": "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"
+        },
+        {
+            "type": "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
+        },
+        {
+            "type": "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"
+        },
+        {
+            "type": "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
+        },
+        {
+            "type": "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"
+        },
+        {
+            "type": "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
+        },
+        {
+            "type": "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"
+        },
+        {
+            "type": "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
+        },
+        {
+            "type": "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"
+        },
+        {
+            "type": "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
+        },
+        {
+            "type": "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"
+        },
+        {
+            "type": "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
+        },
+        {
+            "type": "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"
+        },
+        {
+            "type": "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
+        },
+        {
+            "type": "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"
+        },
+        {
+            "type": "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
+        },
+        {
+            "type": "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"
+        },
+        {
+            "type": "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
+        },
+        {
+            "type": "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"
+        },
+        {
+            "type": "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
+        }
+    ],
+    "streams": [
+        {
+            "index": 0,
+            "codec_name": "pcm_s16le",
+            "codec_type": "audio",
+            "codec_time_base": "1/44100",
+            "codec_tag_string": "[1][0][0][0]",
+            "codec_tag": "0x0001",
+            "sample_fmt": "s16",
+            "sample_rate": "44100",
+            "channels": 1,
+            "bits_per_sample": 16,
+            "r_frame_rate": "0/0",
+            "avg_frame_rate": "0/0",
+            "time_base": "1/44100",
+            "start_pts": 0,
+            "start_time": "0.000000",
+            "duration_ts": 527406,
+            "duration": "11.959320",
+            "bit_rate": "705600",
+            "nb_read_frames": "6",
+            "nb_read_packets": "6",
+            "disposition": {
+                "default": 0,
+                "dub": 0,
+                "original": 0,
+                "comment": 0,
+                "lyrics": 0,
+                "karaoke": 0,
+                "forced": 0,
+                "hearing_impaired": 0,
+                "visual_impaired": 0,
+                "clean_effects": 0,
+                "attached_pic": 0
+            },
+            "tags": {
+                "E": "mc²"
+            }
+        },
+        {
+            "index": 1,
+            "codec_name": "rawvideo",
+            "codec_type": "video",
+            "codec_time_base": "1/51200",
+            "codec_tag_string": "RGB[24]",
+            "codec_tag": "0x18424752",
+            "width": 320,
+            "height": 240,
+            "has_b_frames": 0,
+            "sample_aspect_ratio": "1:1",
+            "display_aspect_ratio": "4:3",
+            "pix_fmt": "rgb24",
+            "level": -99,
+            "r_frame_rate": "25/1",
+            "avg_frame_rate": "25/1",
+            "time_base": "1/51200",
+            "start_pts": 0,
+            "start_time": "0.000000",
+            "duration_ts": 612317,
+            "duration": "11.959316",
+            "nb_read_frames": "4",
+            "nb_read_packets": "4",
+            "disposition": {
+                "default": 0,
+                "dub": 0,
+                "original": 0,
+                "comment": 0,
+                "lyrics": 0,
+                "karaoke": 0,
+                "forced": 0,
+                "hearing_impaired": 0,
+                "visual_impaired": 0,
+                "clean_effects": 0,
+                "attached_pic": 0
+            },
+            "tags": {
+                "title": "foobar",
+                "duration_ts": "field-and-tags-conflict-attempt"
+            }
+        },
+        {
+            "index": 2,
+            "codec_name": "rawvideo",
+            "codec_type": "video",
+            "codec_time_base": "1/51200",
+            "codec_tag_string": "RGB[24]",
+            "codec_tag": "0x18424752",
+            "width": 100,
+            "height": 100,
+            "has_b_frames": 0,
+            "sample_aspect_ratio": "1:1",
+            "display_aspect_ratio": "1:1",
+            "pix_fmt": "rgb24",
+            "level": -99,
+            "r_frame_rate": "25/1",
+            "avg_frame_rate": "25/1",
+            "time_base": "1/51200",
+            "start_pts": 0,
+            "start_time": "0.000000",
+            "duration_ts": 612317,
+            "duration": "11.959316",
+            "nb_read_frames": "4",
+            "nb_read_packets": "4",
+            "disposition": {
+                "default": 0,
+                "dub": 0,
+                "original": 0,
+                "comment": 0,
+                "lyrics": 0,
+                "karaoke": 0,
+                "forced": 0,
+                "hearing_impaired": 0,
+                "visual_impaired": 0,
+                "clean_effects": 0,
+                "attached_pic": 0
+            }
+        }
+    ],
+    "format": {
+        "filename": "tests/data/ffprobe-test.nut",
+        "nb_streams": 3,
+        "format_name": "nut",
+        "start_time": "0.000000",
+        "duration": "11.959320",
+        "size": "1054812",
+        "bit_rate": "705599",
+        "tags": {
+            "title": "ffprobe test file",
+            "comment": "'A comment with CSV, XML & JSON special chars': <tag value=\"x\">",
+            "comment2": "I ♥ Üñîçød€"
+        }
+    }
+}
diff --git a/tests/ref/fate/ffprobe_xml b/tests/ref/fate/ffprobe_xml
new file mode 100644
index 0000000..f428f9d
--- /dev/null
+++ b/tests/ref/fate/ffprobe_xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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"/>
+        <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"/>
+        <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"/>
+        <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"/>
+        <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"/>
+        <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"/>
+        <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"/>
+        <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"/>
+    </packets_and_frames>
+
+    <streams>
+        <stream index="0" codec_name="pcm_s16le" codec_type="audio" codec_time_base="1/44100" codec_tag_string="[1][0][0][0]" codec_tag="0x0001" sample_fmt="s16" sample_rate="44100" channels="1" bits_per_sample="16" r_frame_rate="0/0" avg_frame_rate="0/0" time_base="1/44100" start_pts="0" start_time="0.000000" duration_ts="527406" duration="11.959320" bit_rate="705600" nb_read_frames="6" nb_read_packets="6">
+            <disposition default="0" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0"/>
+            <tag key="E" value="mc²"/>
+        </stream>
+        <stream index="1" codec_name="rawvideo" codec_type="video" codec_time_base="1/51200" codec_tag_string="RGB[24]" codec_tag="0x18424752" width="320" height="240" has_b_frames="0" sample_aspect_ratio="1:1" display_aspect_ratio="4:3" pix_fmt="rgb24" level="-99" r_frame_rate="25/1" avg_frame_rate="25/1" time_base="1/51200" start_pts="0" start_time="0.000000" duration_ts="612317" duration="11.959316" nb_read_frames="4" nb_read_packets="4">
+            <disposition default="0" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0"/>
+            <tag key="title" value="foobar"/>
+            <tag key="duration_ts" value="field-and-tags-conflict-attempt"/>
+        </stream>
+        <stream index="2" codec_name="rawvideo" codec_type="video" codec_time_base="1/51200" codec_tag_string="RGB[24]" codec_tag="0x18424752" width="100" height="100" has_b_frames="0" sample_aspect_ratio="1:1" display_aspect_ratio="1:1" pix_fmt="rgb24" level="-99" r_frame_rate="25/1" avg_frame_rate="25/1" time_base="1/51200" start_pts="0" start_time="0.000000" duration_ts="612317" duration="11.959316" nb_read_frames="4" nb_read_packets="4">
+            <disposition default="0" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0"/>
+        </stream>
+    </streams>
+
+    <format filename="tests/data/ffprobe-test.nut" nb_streams="3" format_name="nut" start_time="0.000000" duration="11.959320" size="1054812" bit_rate="705599">
+        <tag key="title" value="ffprobe test file"/>
+        <tag key="comment" value="&apos;A comment with CSV, XML &amp; JSON special chars&apos;: &lt;tag value=&quot;x&quot;&gt;"/>
+        <tag key="comment2" value="I ♥ Üñîçød€"/>
+    </format>
+</ffprobe>
diff --git a/tests/ref/fate/filter-delogo b/tests/ref/fate/filter-delogo
index 0022698..e0f24cd 100644
--- a/tests/ref/fate/filter-delogo
+++ b/tests/ref/fate/filter-delogo
@@ -1,110 +1,110 @@
-#tb 0: 1/1000
-0,          1,          1,        0,   126720, 0x689de87e
-0,         33,         33,        0,   126720, 0x3db9e91c
-0,         66,         66,        0,   126720, 0x3db9e91c
-0,        100,        100,        0,   126720, 0x3db9e91c
-0,        133,        133,        0,   126720, 0xfa6ae95e
-0,        166,        166,        0,   126720, 0x5bcbf0e6
-0,        200,        200,        0,   126720, 0x94a0f126
-0,        233,        233,        0,   126720, 0x0250f106
-0,        266,        266,        0,   126720, 0xcf6ab4bc
-0,        300,        300,        0,   126720, 0x44aeb57c
-0,        333,        333,        0,   126720, 0x33b0b5bc
-0,        367,        367,        0,   126720, 0xc4bab591
-0,        400,        400,        0,   126720, 0xa492b5ec
-0,        433,        433,        0,   126720, 0x1459b85c
-0,        467,        467,        0,   126720, 0x806fb8dc
-0,        500,        500,        0,   126720, 0xd241b871
-0,        533,        533,        0,   126720, 0x698eb5cc
-0,        567,        567,        0,   126720, 0x4719aa98
-0,        600,        600,        0,   126720, 0x9ca1962c
-0,        633,        633,        0,   126720, 0x18cda460
-0,        667,        667,        0,   126720, 0xc230b716
-0,        700,        700,        0,   126720, 0x8451a4e2
-0,        734,        734,        0,   126720, 0x59e9a7ea
-0,        767,        767,        0,   126720, 0xc77ca73d
-0,        800,        800,        0,   126720, 0x725fb976
-0,        834,        834,        0,   126720, 0xb30da3b3
-0,        867,        867,        0,   126720, 0x7af2ea86
-0,        900,        900,        0,   126720, 0x40d4b4eb
-0,        934,        934,        0,   126720, 0x49d00307
-0,        967,        967,        0,   126720, 0x44c8848e
-0,       1000,       1000,        0,   126720, 0xc6990101
-0,       1034,       1034,        0,   126720, 0x2e01b963
-0,       1067,       1067,        0,   126720, 0xd0e903f0
-0,       1101,       1101,        0,   126720, 0x3457d592
-0,       1134,       1134,        0,   126720, 0x4f1ddb3c
-0,       1167,       1167,        0,   126720, 0x3980ace5
-0,       1201,       1201,        0,   126720, 0xb1e37954
-0,       1234,       1234,        0,   126720, 0x619fc554
-0,       1267,       1267,        0,   126720, 0x945fb39e
-0,       1301,       1301,        0,   126720, 0xb1d5e0ce
-0,       1334,       1334,        0,   126720, 0xf26e1dcc
-0,       1368,       1368,        0,   126720, 0x04d5783e
-0,       1401,       1401,        0,   126720, 0xbaa0479e
-0,       1434,       1434,        0,   126720, 0x20d88b01
-0,       1468,       1468,        0,   126720, 0x59d99901
-0,       1501,       1501,        0,   126720, 0x1c6e09f6
-0,       1534,       1534,        0,   126720, 0xeec50fc5
-0,       1568,       1568,        0,   126720, 0xb3a92827
-0,       1601,       1601,        0,   126720, 0xf62dd2b6
-0,       1634,       1634,        0,   126720, 0x75b1e619
-0,       1668,       1668,        0,   126720, 0x6bbce2c0
-0,       1701,       1701,        0,   126720, 0xd93e023c
-0,       1735,       1735,        0,   126720, 0xbbe8e7c2
-0,       1768,       1768,        0,   126720, 0x2272ec17
-0,       1801,       1801,        0,   126720, 0xf5e4ee6e
-0,       1835,       1835,        0,   126720, 0x751d2607
-0,       1868,       1868,        0,   126720, 0x44c499c9
-0,       1901,       1901,        0,   126720, 0xddccd842
-0,       1935,       1935,        0,   126720, 0x508dd214
-0,       1968,       1968,        0,   126720, 0x8eb10272
-0,       2001,       2001,        0,   126720, 0x7224b1c6
-0,       2035,       2035,        0,   126720, 0x50ff456c
-0,       2068,       2068,        0,   126720, 0xa81e2731
-0,       2102,       2102,        0,   126720, 0x7e50456d
-0,       2135,       2135,        0,   126720, 0x44802978
-0,       2168,       2168,        0,   126720, 0x86e88743
-0,       2202,       2202,        0,   126720, 0x0b1087d6
-0,       2235,       2235,        0,   126720, 0xb0227d21
-0,       2268,       2268,        0,   126720, 0x29d10bd2
-0,       2302,       2302,        0,   126720, 0x04b43afa
-0,       2335,       2335,        0,   126720, 0xb48e9698
-0,       2369,       2369,        0,   126720, 0x75d760fb
-0,       2402,       2402,        0,   126720, 0xa2ab1fdb
-0,       2435,       2435,        0,   126720, 0xec30a5ee
-0,       2469,       2469,        0,   126720, 0xbdab7c8c
-0,       2502,       2502,        0,   126720, 0xac5c3f2c
-0,       2535,       2535,        0,   126720, 0xce6350be
-0,       2569,       2569,        0,   126720, 0xb109657a
-0,       2602,       2602,        0,   126720, 0x723865a4
-0,       2635,       2635,        0,   126720, 0xa9869124
-0,       2669,       2669,        0,   126720, 0xc41af558
-0,       2702,       2702,        0,   126720, 0xcbe6a402
-0,       2736,       2736,        0,   126720, 0xb6735ecb
-0,       2769,       2769,        0,   126720, 0xba3059f2
-0,       2802,       2802,        0,   126720, 0xe7d63b8d
-0,       2836,       2836,        0,   126720, 0x8f115906
-0,       2869,       2869,        0,   126720, 0xaf6a8dcb
-0,       2902,       2902,        0,   126720, 0xb73e846e
-0,       2936,       2936,        0,   126720, 0xedd6380f
-0,       2969,       2969,        0,   126720, 0xd9026acf
-0,       3002,       3002,        0,   126720, 0xa03a650b
-0,       3036,       3036,        0,   126720, 0x262765bc
-0,       3069,       3069,        0,   126720, 0xaaa9ded1
-0,       3103,       3103,        0,   126720, 0xe4f42665
-0,       3136,       3136,        0,   126720, 0x78daf760
-0,       3169,       3169,        0,   126720, 0x3b0c6ef8
-0,       3203,       3203,        0,   126720, 0xb745df80
-0,       3236,       3236,        0,   126720, 0x08e57b90
-0,       3269,       3269,        0,   126720, 0x6f883ab0
-0,       3303,       3303,        0,   126720, 0x934b4dd5
-0,       3336,       3336,        0,   126720, 0x762f108f
-0,       3370,       3370,        0,   126720, 0x91ee0f2b
-0,       3403,       3403,        0,   126720, 0x9af6e5e8
-0,       3436,       3436,        0,   126720, 0xdcd95e0a
-0,       3470,       3470,        0,   126720, 0x22c33a6e
-0,       3503,       3503,        0,   126720, 0x21c1b7f4
-0,       3536,       3536,        0,   126720, 0x0a66a1ed
-0,       3570,       3570,        0,   126720, 0x53fea81b
-0,       3603,       3603,        0,   126720, 0x597f5567
+#tb 0: 32768/982057
+0,          0,          0,        1,   126720, 0x689de87e
+0,          1,          1,        1,   126720, 0x3db9e91c
+0,          2,          2,        1,   126720, 0x3db9e91c
+0,          3,          3,        1,   126720, 0x3db9e91c
+0,          4,          4,        1,   126720, 0xfa6ae95e
+0,          5,          5,        1,   126720, 0x5bcbf0e6
+0,          6,          6,        1,   126720, 0x94a0f126
+0,          7,          7,        1,   126720, 0x0250f106
+0,          8,          8,        1,   126720, 0xcf6ab4bc
+0,          9,          9,        1,   126720, 0x44aeb57c
+0,         10,         10,        1,   126720, 0x33b0b5bc
+0,         11,         11,        1,   126720, 0xc4bab591
+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,         16,         16,        1,   126720, 0x698eb5cc
+0,         17,         17,        1,   126720, 0x4719aa98
+0,         18,         18,        1,   126720, 0x9ca1962c
+0,         19,         19,        1,   126720, 0x18cda460
+0,         20,         20,        1,   126720, 0xc230b716
+0,         21,         21,        1,   126720, 0x8451a4e2
+0,         22,         22,        1,   126720, 0x59e9a7ea
+0,         23,         23,        1,   126720, 0xc77ca73d
+0,         24,         24,        1,   126720, 0x725fb976
+0,         25,         25,        1,   126720, 0xb30da3b3
+0,         26,         26,        1,   126720, 0x7af2ea86
+0,         27,         27,        1,   126720, 0x40d4b4eb
+0,         28,         28,        1,   126720, 0x49d00307
+0,         29,         29,        1,   126720, 0x44c8848e
+0,         30,         30,        1,   126720, 0xc6990101
+0,         31,         31,        1,   126720, 0x2e01b963
+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,         36,         36,        1,   126720, 0xb1e37954
+0,         37,         37,        1,   126720, 0x619fc554
+0,         38,         38,        1,   126720, 0x945fb39e
+0,         39,         39,        1,   126720, 0xb1d5e0ce
+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,         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
diff --git a/tests/ref/fate/filter-yadif-mode0 b/tests/ref/fate/filter-yadif-mode0
index e260977..7014333 100644
--- a/tests/ref/fate/filter-yadif-mode0
+++ b/tests/ref/fate/filter-yadif-mode0
@@ -1,32 +1,32 @@
-#tb 0: 1/180000
-0,      64800,      64800,        0,   622080, 0x4440caef
-0,      72000,      72000,        0,   622080, 0xce67e69d
-0,      79200,      79200,        0,   622080, 0x1dbdc653
-0,      86400,      86400,        0,   622080, 0x82c591d1
-0,      93600,      93600,        0,   622080, 0x8193740b
-0,     100800,     100800,        0,   622080, 0xcb219711
-0,     108000,     108000,        0,   622080, 0x1870783b
-0,     115200,     115200,        0,   622080, 0x7080590b
-0,     122400,     122400,        0,   622080, 0x6df4175d
-0,     129600,     129600,        0,   622080, 0x6b530e95
-0,     136800,     136800,        0,   622080, 0x7f9d66f7
-0,     144000,     144000,        0,   622080, 0x338cda81
-0,     151200,     151200,        0,   622080, 0xb13797f8
-0,     158400,     158400,        0,   622080, 0xb51e7ca4
-0,     165600,     165600,        0,   622080, 0x353eed75
-0,     172800,     172800,        0,   622080, 0xf93e92b0
-0,     180000,     180000,        0,   622080, 0xd0811094
-0,     187200,     187200,        0,   622080, 0xb04a3141
-0,     194400,     194400,        0,   622080, 0x4ab84909
-0,     201600,     201600,        0,   622080, 0xa0fcb8fb
-0,     208800,     208800,        0,   622080, 0x9003aebb
-0,     216000,     216000,        0,   622080, 0x153faa3e
-0,     223200,     223200,        0,   622080, 0xae724063
-0,     230400,     230400,        0,   622080, 0xeb4de77a
-0,     237600,     237600,        0,   622080, 0x209ed8c7
-0,     244800,     244800,        0,   622080, 0xe2bbac96
-0,     252000,     252000,        0,   622080, 0xe945441e
-0,     259200,     259200,        0,   622080, 0x8f8cbd5f
-0,     266400,     266400,        0,   622080, 0xbc3cf717
-0,     273600,     273600,        0,   622080, 0x0109f125
-0,     280800,     280800,        0,   622080, 0x230c373f
+#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
diff --git a/tests/ref/fate/filter-yadif-mode1 b/tests/ref/fate/filter-yadif-mode1
index b498137..87c8d97 100644
--- a/tests/ref/fate/filter-yadif-mode1
+++ b/tests/ref/fate/filter-yadif-mode1
@@ -1,63 +1,63 @@
-#tb 0: 1/180000
-0,      64800,      64800,        0,   622080, 0x4440caef
-0,      68400,      68400,        0,   622080, 0xa5cea88b
-0,      72000,      72000,        0,   622080, 0xce67e69d
-0,      75600,      75600,        0,   622080, 0x9a57891f
-0,      79200,      79200,        0,   622080, 0x1dbdc653
-0,      82800,      82800,        0,   622080, 0xc171c0c5
-0,      86400,      86400,        0,   622080, 0x82c591d1
-0,      90000,      90000,        0,   622080, 0x20db9890
-0,      93600,      93600,        0,   622080, 0x8193740b
-0,      97200,      97200,        0,   622080, 0xdb181d52
-0,     100800,     100800,        0,   622080, 0xcb219711
-0,     104400,     104400,        0,   622080, 0xc2b913d1
-0,     108000,     108000,        0,   622080, 0x1870783b
-0,     111600,     111600,        0,   622080, 0xf1d9c5fb
-0,     115200,     115200,        0,   622080, 0x7080590b
-0,     118800,     118800,        0,   622080, 0x669c5775
-0,     122400,     122400,        0,   622080, 0x6df4175d
-0,     126000,     126000,        0,   622080, 0x01921a16
-0,     129600,     129600,        0,   622080, 0x6b530e95
-0,     133200,     133200,        0,   622080, 0xd5047bc9
-0,     136800,     136800,        0,   622080, 0x7f9d66f7
-0,     140400,     140400,        0,   622080, 0xa8b006eb
-0,     144000,     144000,        0,   622080, 0x338cda81
-0,     147600,     147600,        0,   622080, 0xf0e125a7
-0,     151200,     151200,        0,   622080, 0xb13797f8
-0,     154800,     154800,        0,   622080, 0x4afe2976
-0,     158400,     158400,        0,   622080, 0xb51e7ca4
-0,     162000,     162000,        0,   622080, 0x637fcbfe
-0,     165600,     165600,        0,   622080, 0x353eed75
-0,     169200,     169200,        0,   622080, 0xd9a8f5ac
-0,     172800,     172800,        0,   622080, 0xf93e92b0
-0,     176400,     176400,        0,   622080, 0x4540039f
-0,     180000,     180000,        0,   622080, 0xd0811094
-0,     183600,     183600,        0,   622080, 0x3039906f
-0,     187200,     187200,        0,   622080, 0xb04a3141
-0,     190800,     190800,        0,   622080, 0x52872cf9
-0,     194400,     194400,        0,   622080, 0x4ab84909
-0,     198000,     198000,        0,   622080, 0x82de12ee
-0,     201600,     201600,        0,   622080, 0xa0fcb8fb
-0,     205200,     205200,        0,   622080, 0x7e849cc9
-0,     208800,     208800,        0,   622080, 0x9003aebb
-0,     212400,     212400,        0,   622080, 0xffe6f770
-0,     216000,     216000,        0,   622080, 0x153faa3e
-0,     219600,     219600,        0,   622080, 0xb67f3233
-0,     223200,     223200,        0,   622080, 0xae724063
-0,     226800,     226800,        0,   622080, 0x15fe44b4
-0,     230400,     230400,        0,   622080, 0xeb4de77a
-0,     234000,     234000,        0,   622080, 0x380f8563
-0,     237600,     237600,        0,   622080, 0x209ed8c7
-0,     241200,     241200,        0,   622080, 0xb964d70f
-0,     244800,     244800,        0,   622080, 0xe2bbac96
-0,     248400,     248400,        0,   622080, 0x4f60f7f4
-0,     252000,     252000,        0,   622080, 0xe945441e
-0,     255600,     255600,        0,   622080, 0xd0afb742
-0,     259200,     259200,        0,   622080, 0x8f8cbd5f
-0,     262800,     262800,        0,   622080, 0xb9a15294
-0,     266400,     266400,        0,   622080, 0xbc3cf717
-0,     270000,     270000,        0,   622080, 0xb70b01a9
-0,     273600,     273600,        0,   622080, 0x0109f125
-0,     277200,     277200,        0,   622080, 0xcb3a371f
-0,     280800,     280800,        0,   622080, 0x230c373f
-0,     284400,     284400,        0,   622080, 0x82dfb1f2
+#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
diff --git a/tests/ref/fate/flic-af11-palette-change b/tests/ref/fate/flic-af11-palette-change
index 61e6c1d..cd702b6 100644
--- a/tests/ref/fate/flic-af11-palette-change
+++ b/tests/ref/fate/flic-af11-palette-change
@@ -1,117 +1,117 @@
 #tb 0: 1/35
-0,          0,          0,        1,   192000, 0x64da83e8
-0,          1,          1,        1,   192000, 0xf59ccccc
-0,          2,          2,        1,   192000, 0xaaa06c5c
-0,          3,          3,        1,   192000, 0xa98f82c0
-0,          4,          4,        1,   192000, 0x164fbbdc
-0,          5,          5,        1,   192000, 0x0b3abc0c
-0,          6,          6,        1,   192000, 0x47661943
-0,          7,          7,        1,   192000, 0x30711074
-0,          8,          8,        1,   192000, 0x67684a84
-0,          9,          9,        1,   192000, 0x1d9afa70
-0,         10,         10,        1,   192000, 0x4fd28e78
-0,         11,         11,        1,   192000, 0x9bc5c8cc
-0,         12,         12,        1,   192000, 0xcf268b6c
-0,         13,         13,        1,   192000, 0xdfe65fd4
-0,         14,         14,        1,   192000, 0x47e75404
-0,         15,         15,        1,   192000, 0xb3b5b448
-0,         16,         16,        1,   192000, 0x826c94b4
-0,         17,         17,        1,   192000, 0x158e95f8
-0,         18,         18,        1,   192000, 0x576f031f
-0,         19,         19,        1,   192000, 0xea3399e8
-0,         20,         20,        1,   192000, 0x76b1e224
-0,         21,         21,        1,   192000, 0x290073db
-0,         22,         22,        1,   192000, 0x83741abf
-0,         23,         23,        1,   192000, 0x50f9c4ec
-0,         24,         24,        1,   192000, 0x6d8fdac0
-0,         25,         25,        1,   192000, 0xe26e2600
-0,         26,         26,        1,   192000, 0xbeb0e11c
-0,         27,         27,        1,   192000, 0x38282fd4
-0,         28,         28,        1,   192000, 0x13d0b790
-0,         29,         29,        1,   192000, 0x0cf8fca9
-0,         30,         30,        1,   192000, 0x64da83e8
-0,         31,         31,        1,   192000, 0xf59ccccc
-0,         32,         32,        1,   192000, 0xaaa06c5c
-0,         33,         33,        1,   192000, 0xa98f82c0
-0,         34,         34,        1,   192000, 0x164fbbdc
-0,         35,         35,        1,   192000, 0x0b3abc0c
-0,         36,         36,        1,   192000, 0x47661943
-0,         37,         37,        1,   192000, 0x30711074
-0,         38,         38,        1,   192000, 0x67684a84
-0,         39,         39,        1,   192000, 0x1d9afa70
-0,         40,         40,        1,   192000, 0x4fd28e78
-0,         41,         41,        1,   192000, 0x9bc5c8cc
-0,         42,         42,        1,   192000, 0xcf268b6c
-0,         43,         43,        1,   192000, 0xdfe65fd4
-0,         44,         44,        1,   192000, 0x47e75404
-0,         45,         45,        1,   192000, 0xb3b5b448
-0,         46,         46,        1,   192000, 0x826c94b4
-0,         47,         47,        1,   192000, 0x158e95f8
-0,         48,         48,        1,   192000, 0x576f031f
-0,         49,         49,        1,   192000, 0xea3399e8
-0,         50,         50,        1,   192000, 0x76b1e224
-0,         51,         51,        1,   192000, 0x290073db
-0,         52,         52,        1,   192000, 0x83741abf
-0,         53,         53,        1,   192000, 0x50f9c4ec
-0,         54,         54,        1,   192000, 0x6d8fdac0
-0,         55,         55,        1,   192000, 0xe26e2600
-0,         56,         56,        1,   192000, 0xbeb0e11c
-0,         57,         57,        1,   192000, 0x38282fd4
-0,         58,         58,        1,   192000, 0x13d0b790
-0,         59,         59,        1,   192000, 0x0cf8fca9
-0,         60,         60,        1,   192000, 0x64da83e8
-0,         61,         61,        1,   192000, 0xf59ccccc
-0,         62,         62,        1,   192000, 0xaaa06c5c
-0,         63,         63,        1,   192000, 0xa98f82c0
-0,         64,         64,        1,   192000, 0x164fbbdc
-0,         65,         65,        1,   192000, 0x0b3abc0c
-0,         66,         66,        1,   192000, 0x47661943
-0,         67,         67,        1,   192000, 0x30711074
-0,         68,         68,        1,   192000, 0x67684a84
-0,         69,         69,        1,   192000, 0x1d9afa70
-0,         70,         70,        1,   192000, 0x4fd28e78
-0,         71,         71,        1,   192000, 0x9bc5c8cc
-0,         72,         72,        1,   192000, 0xcf268b6c
-0,         73,         73,        1,   192000, 0xdfe65fd4
-0,         74,         74,        1,   192000, 0x47e75404
-0,         75,         75,        1,   192000, 0xb3b5b448
-0,         76,         76,        1,   192000, 0x826c94b4
-0,         77,         77,        1,   192000, 0x158e95f8
-0,         78,         78,        1,   192000, 0x576f031f
-0,         79,         79,        1,   192000, 0xea3399e8
-0,         80,         80,        1,   192000, 0x76b1e224
-0,         81,         81,        1,   192000, 0x290073db
-0,         82,         82,        1,   192000, 0x83741abf
-0,         83,         83,        1,   192000, 0x50f9c4ec
-0,         84,         84,        1,   192000, 0x6d8fdac0
-0,         85,         85,        1,   192000, 0xe26e2600
-0,         86,         86,        1,   192000, 0xbeb0e11c
-0,         87,         87,        1,   192000, 0x38282fd4
-0,         88,         88,        1,   192000, 0x13d0b790
-0,         89,         89,        1,   192000, 0x0cf8fca9
-0,         90,         90,        1,   192000, 0xfcb10883
-0,         91,         91,        1,   192000, 0xfcb10883
-0,         92,         92,        1,   192000, 0xd0ba80c4
-0,         93,         93,        1,   192000, 0xd0ba80c4
-0,         94,         94,        1,   192000, 0x690520d9
-0,         95,         95,        1,   192000, 0x690520d9
-0,         96,         96,        1,   192000, 0x5b621c3f
-0,         97,         97,        1,   192000, 0x5b621c3f
-0,         98,         98,        1,   192000, 0x689e231f
-0,         99,         99,        1,   192000, 0x689e231f
-0,        100,        100,        1,   192000, 0x20653ff2
-0,        101,        101,        1,   192000, 0x20653ff2
-0,        102,        102,        1,   192000, 0xc18b3231
-0,        103,        103,        1,   192000, 0xc18b3231
-0,        104,        104,        1,   192000, 0x6d87ec3d
-0,        105,        105,        1,   192000, 0x6d87ec3d
-0,        106,        106,        1,   192000, 0x1c5b53d6
-0,        107,        107,        1,   192000, 0x1c5b53d6
-0,        108,        108,        1,   192000, 0x152fdf12
-0,        109,        109,        1,   192000, 0xde187291
-0,        110,        110,        1,   192000, 0x167617a5
-0,        111,        111,        1,   192000, 0x5067b8de
-0,        112,        112,        1,   192000, 0xd02ae54e
-0,        113,        113,        1,   192000, 0x0d6e9402
-0,        114,        114,        1,   192000, 0xa8e98616
-0,        115,        115,        1,   192000, 0x04762d1a
+0,          0,          0,        1,   192000, 0x508ff8ac
+0,          1,          1,        1,   192000, 0xef0d4274
+0,          2,          2,        1,   192000, 0x0d50e0dd
+0,          3,          3,        1,   192000, 0xf638f782
+0,          4,          4,        1,   192000, 0x40e4314b
+0,          5,          5,        1,   192000, 0x0ce5318f
+0,          6,          6,        1,   192000, 0x14848fa9
+0,          7,          7,        1,   192000, 0x676f83e1
+0,          8,          8,        1,   192000, 0x5b98bea9
+0,          9,          9,        1,   192000, 0xf5cc709d
+0,         10,         10,        1,   192000, 0x719a0373
+0,         11,         11,        1,   192000, 0xba5a3e74
+0,         12,         12,        1,   192000, 0x34e10051
+0,         13,         13,        1,   192000, 0xb66dd42d
+0,         14,         14,        1,   192000, 0xfb58c833
+0,         15,         15,        1,   192000, 0xa28029a4
+0,         16,         16,        1,   192000, 0x28fa09b3
+0,         17,         17,        1,   192000, 0x676f0b08
+0,         18,         18,        1,   192000, 0x7af97965
+0,         19,         19,        1,   192000, 0x436f0f03
+0,         20,         20,        1,   192000, 0xbaca5814
+0,         21,         21,        1,   192000, 0xca97eb51
+0,         22,         22,        1,   192000, 0x1fc89137
+0,         23,         23,        1,   192000, 0x8af63a74
+0,         24,         24,        1,   192000, 0xca015077
+0,         25,         25,        1,   192000, 0x761599ad
+0,         26,         26,        1,   192000, 0x1ca1570c
+0,         27,         27,        1,   192000, 0x1209a3ac
+0,         28,         28,        1,   192000, 0xf7d92d01
+0,         29,         29,        1,   192000, 0x970d6fea
+0,         30,         30,        1,   192000, 0x508ff8ac
+0,         31,         31,        1,   192000, 0xef0d4274
+0,         32,         32,        1,   192000, 0x0d50e0dd
+0,         33,         33,        1,   192000, 0xf638f782
+0,         34,         34,        1,   192000, 0x40e4314b
+0,         35,         35,        1,   192000, 0x0ce5318f
+0,         36,         36,        1,   192000, 0x14848fa9
+0,         37,         37,        1,   192000, 0x676f83e1
+0,         38,         38,        1,   192000, 0x5b98bea9
+0,         39,         39,        1,   192000, 0xf5cc709d
+0,         40,         40,        1,   192000, 0x719a0373
+0,         41,         41,        1,   192000, 0xba5a3e74
+0,         42,         42,        1,   192000, 0x34e10051
+0,         43,         43,        1,   192000, 0xb66dd42d
+0,         44,         44,        1,   192000, 0xfb58c833
+0,         45,         45,        1,   192000, 0xa28029a4
+0,         46,         46,        1,   192000, 0x28fa09b3
+0,         47,         47,        1,   192000, 0x676f0b08
+0,         48,         48,        1,   192000, 0x7af97965
+0,         49,         49,        1,   192000, 0x436f0f03
+0,         50,         50,        1,   192000, 0xbaca5814
+0,         51,         51,        1,   192000, 0xca97eb51
+0,         52,         52,        1,   192000, 0x1fc89137
+0,         53,         53,        1,   192000, 0x8af63a74
+0,         54,         54,        1,   192000, 0xca015077
+0,         55,         55,        1,   192000, 0x761599ad
+0,         56,         56,        1,   192000, 0x1ca1570c
+0,         57,         57,        1,   192000, 0x1209a3ac
+0,         58,         58,        1,   192000, 0xf7d92d01
+0,         59,         59,        1,   192000, 0x970d6fea
+0,         60,         60,        1,   192000, 0x508ff8ac
+0,         61,         61,        1,   192000, 0xef0d4274
+0,         62,         62,        1,   192000, 0x0d50e0dd
+0,         63,         63,        1,   192000, 0xf638f782
+0,         64,         64,        1,   192000, 0x40e4314b
+0,         65,         65,        1,   192000, 0x0ce5318f
+0,         66,         66,        1,   192000, 0x14848fa9
+0,         67,         67,        1,   192000, 0x676f83e1
+0,         68,         68,        1,   192000, 0x5b98bea9
+0,         69,         69,        1,   192000, 0xf5cc709d
+0,         70,         70,        1,   192000, 0x719a0373
+0,         71,         71,        1,   192000, 0xba5a3e74
+0,         72,         72,        1,   192000, 0x34e10051
+0,         73,         73,        1,   192000, 0xb66dd42d
+0,         74,         74,        1,   192000, 0xfb58c833
+0,         75,         75,        1,   192000, 0xa28029a4
+0,         76,         76,        1,   192000, 0x28fa09b3
+0,         77,         77,        1,   192000, 0x676f0b08
+0,         78,         78,        1,   192000, 0x7af97965
+0,         79,         79,        1,   192000, 0x436f0f03
+0,         80,         80,        1,   192000, 0xbaca5814
+0,         81,         81,        1,   192000, 0xca97eb51
+0,         82,         82,        1,   192000, 0x1fc89137
+0,         83,         83,        1,   192000, 0x8af63a74
+0,         84,         84,        1,   192000, 0xca015077
+0,         85,         85,        1,   192000, 0x761599ad
+0,         86,         86,        1,   192000, 0x1ca1570c
+0,         87,         87,        1,   192000, 0x1209a3ac
+0,         88,         88,        1,   192000, 0xf7d92d01
+0,         89,         89,        1,   192000, 0x970d6fea
+0,         90,         90,        1,   192000, 0x1ff28298
+0,         91,         91,        1,   192000, 0x1ff28298
+0,         92,         92,        1,   192000, 0x407d09ca
+0,         93,         93,        1,   192000, 0x407d09ca
+0,         94,         94,        1,   192000, 0xc743a475
+0,         95,         95,        1,   192000, 0xc743a475
+0,         96,         96,        1,   192000, 0x46bf9f7d
+0,         97,         97,        1,   192000, 0x46bf9f7d
+0,         98,         98,        1,   192000, 0x57ecb2c1
+0,         99,         99,        1,   192000, 0x57ecb2c1
+0,        100,        100,        1,   192000, 0x680fd3bf
+0,        101,        101,        1,   192000, 0x680fd3bf
+0,        102,        102,        1,   192000, 0x8772ca19
+0,        103,        103,        1,   192000, 0x8772ca19
+0,        104,        104,        1,   192000, 0x3cc29bbf
+0,        105,        105,        1,   192000, 0x3cc29bbf
+0,        106,        106,        1,   192000, 0xe745fb3c
+0,        107,        107,        1,   192000, 0xe745fb3c
+0,        108,        108,        1,   192000, 0xc5279397
+0,        109,        109,        1,   192000, 0xcc902b35
+0,        110,        110,        1,   192000, 0x50a7cf32
+0,        111,        111,        1,   192000, 0x23fd6f51
+0,        112,        112,        1,   192000, 0x14fe9c4d
+0,        113,        113,        1,   192000, 0x703249f9
+0,        114,        114,        1,   192000, 0x47b73bce
+0,        115,        115,        1,   192000, 0x13bce1c9
diff --git a/tests/ref/fate/flic-magiccarpet b/tests/ref/fate/flic-magiccarpet
index f0faf1d..23a9342 100644
--- a/tests/ref/fate/flic-magiccarpet
+++ b/tests/ref/fate/flic-magiccarpet
@@ -1,43 +1,43 @@
 #tb 0: 1/14
 0,          0,          0,        1,   192000, 0x00000000
-0,          1,          1,        1,   192000, 0x9c057d9c
-0,          2,          2,        1,   192000, 0xab1aacaf
-0,          3,          3,        1,   192000, 0x49a1dccd
-0,          4,          4,        1,   192000, 0xebb7e245
-0,          5,          5,        1,   192000, 0x6287759e
-0,          6,          6,        1,   192000, 0xbf007410
-0,          7,          7,        1,   192000, 0x6c72b247
-0,          8,          8,        1,   192000, 0x4c26a8c3
-0,          9,          9,        1,   192000, 0x99f06050
-0,         10,         10,        1,   192000, 0x663f2d23
-0,         11,         11,        1,   192000, 0x813c3a1f
-0,         12,         12,        1,   192000, 0x6d6cfbe7
-0,         13,         13,        1,   192000, 0x7b04163a
-0,         14,         14,        1,   192000, 0x6792e679
-0,         15,         15,        1,   192000, 0x939ac626
-0,         16,         16,        1,   192000, 0xc7a139c0
-0,         17,         17,        1,   192000, 0xcac7ef0c
-0,         18,         18,        1,   192000, 0xf4ec59e0
-0,         19,         19,        1,   192000, 0x56060f59
-0,         20,         20,        1,   192000, 0xf45ecb3b
-0,         21,         21,        1,   192000, 0xe7e634ff
-0,         22,         22,        1,   192000, 0x7ac04aa4
-0,         23,         23,        1,   192000, 0x4eaba5a1
-0,         24,         24,        1,   192000, 0x89b84e25
-0,         25,         25,        1,   192000, 0xc368ec1e
-0,         26,         26,        1,   192000, 0xeeafb59e
-0,         27,         27,        1,   192000, 0x0b630619
-0,         28,         28,        1,   192000, 0x59cb8954
-0,         29,         29,        1,   192000, 0x16b2875f
-0,         30,         30,        1,   192000, 0x524e32bd
-0,         31,         31,        1,   192000, 0x96000ba2
-0,         32,         32,        1,   192000, 0x18ec28af
-0,         33,         33,        1,   192000, 0x2609c56c
-0,         34,         34,        1,   192000, 0xff25bb5a
-0,         35,         35,        1,   192000, 0xb19a8819
-0,         36,         36,        1,   192000, 0xa5ff8727
-0,         37,         37,        1,   192000, 0xe83f6289
-0,         38,         38,        1,   192000, 0xc6cb4903
-0,         39,         39,        1,   192000, 0xa4d93eb5
-0,         40,         40,        1,   192000, 0xec84ef6c
+0,          1,          1,        1,   192000, 0x03567eeb
+0,          2,          2,        1,   192000, 0xe73db12c
+0,          3,          3,        1,   192000, 0x7cefe740
+0,          4,          4,        1,   192000, 0xb769f827
+0,          5,          5,        1,   192000, 0x71669dea
+0,          6,          6,        1,   192000, 0xc203b934
+0,          7,          7,        1,   192000, 0x30671ee2
+0,          8,          8,        1,   192000, 0xaea33a1b
+0,          9,          9,        1,   192000, 0x50f220c3
+0,         10,         10,        1,   192000, 0x1ddd090f
+0,         11,         11,        1,   192000, 0x17ac22a4
+0,         12,         12,        1,   192000, 0x19f9f412
+0,         13,         13,        1,   192000, 0xa2df0e55
+0,         14,         14,        1,   192000, 0x5abcd663
+0,         15,         15,        1,   192000, 0x5b09b38d
+0,         16,         16,        1,   192000, 0x894d1f43
+0,         17,         17,        1,   192000, 0xbc95caaf
+0,         18,         18,        1,   192000, 0xeaca27fc
+0,         19,         19,        1,   192000, 0x49c5ccb4
+0,         20,         20,        1,   192000, 0x8b3e78b0
+0,         21,         21,        1,   192000, 0x1645d3ae
+0,         22,         22,        1,   192000, 0x4407da0f
+0,         23,         23,        1,   192000, 0x7d0826ac
+0,         24,         24,        1,   192000, 0xc17ec1b8
+0,         25,         25,        1,   192000, 0x4a82520d
+0,         26,         26,        1,   192000, 0xa89f0e2f
+0,         27,         27,        1,   192000, 0xd58b537a
+0,         28,         28,        1,   192000, 0x7123dafe
+0,         29,         29,        1,   192000, 0x15d1d065
+0,         30,         30,        1,   192000, 0xa86873f6
+0,         31,         31,        1,   192000, 0x32704a91
+0,         32,         32,        1,   192000, 0xbf2b63d7
+0,         33,         33,        1,   192000, 0xb98e0126
+0,         34,         34,        1,   192000, 0x412a03ee
+0,         35,         35,        1,   192000, 0x601ad161
+0,         36,         36,        1,   192000, 0x01ead407
+0,         37,         37,        1,   192000, 0x75a7bbe5
+0,         38,         38,        1,   192000, 0x155ea759
+0,         39,         39,        1,   192000, 0xe3a0a6aa
+0,         40,         40,        1,   192000, 0x2b5a5770
 0,         41,         41,        1,   192000, 0x00000000
diff --git a/tests/ref/fate/fraps-v2 b/tests/ref/fate/fraps-v2
index 1ebfb7c..06e0024 100644
--- a/tests/ref/fate/fraps-v2
+++ b/tests/ref/fate/fraps-v2
@@ -1,11 +1,3 @@
 #tb 0: 1/30
 0,          0,          0,        1,  1179648, 0x99f80436
-0,          1,          1,        1,  1179648, 0x99f80436
-0,          2,          2,        1,  1179648, 0x99f80436
-0,          3,          3,        1,  1179648, 0x99f80436
-0,          4,          4,        1,  1179648, 0x99f80436
 0,          5,          5,        1,  1179648, 0xe8ae7a30
-0,          6,          6,        1,  1179648, 0xe8ae7a30
-0,          7,          7,        1,  1179648, 0xe8ae7a30
-0,          8,          8,        1,  1179648, 0xe8ae7a30
-0,          9,          9,        1,  1179648, 0xe8ae7a30
diff --git a/tests/ref/fate/fraps-v3 b/tests/ref/fate/fraps-v3
index ac8b701..139ee7e 100644
--- a/tests/ref/fate/fraps-v3
+++ b/tests/ref/fate/fraps-v3
@@ -3,8 +3,6 @@
 0,          1,          1,        1,   589824, 0xcd740f79
 0,          2,          2,        1,   589824, 0x16f8f90e
 0,          3,          3,        1,   589824, 0x1aaaceba
-0,          4,          4,        1,   589824, 0x1aaaceba
 0,          5,          5,        1,   589824, 0x902e8fe4
 0,          6,          6,        1,   589824, 0x019a4443
-0,          7,          7,        1,   589824, 0x019a4443
 0,          8,          8,        1,   589824, 0x04eff6c6
diff --git a/tests/ref/fate/g729-0 b/tests/ref/fate/g729-0
new file mode 100644
index 0000000..36c6634
--- /dev/null
+++ b/tests/ref/fate/g729-0
@@ -0,0 +1,1000 @@
+0, 0, 160, 0xbb6d5aa0
+0, 900, 160, 0x91563d8d
+0, 1800, 160, 0x10a7535b
+0, 2700, 160, 0xa4f35594
+0, 3600, 160, 0x7f8e54e0
+0, 4500, 160, 0x85275000
+0, 5400, 160, 0x00734c7b
+0, 6300, 160, 0x8a2d544d
+0, 7200, 160, 0x97dc533c
+0, 8100, 160, 0xa7064ec4
+0, 9000, 160, 0xb7984a3c
+0, 9900, 160, 0x28334db6
+0, 10800, 160, 0x5838521f
+0, 11700, 160, 0x2337502c
+0, 12600, 160, 0x4a1e4599
+0, 13500, 160, 0x0d3858a8
+0, 14400, 160, 0xa0974b46
+0, 15300, 160, 0xc3254b93
+0, 16200, 160, 0x42b75231
+0, 17100, 160, 0x93634662
+0, 18000, 160, 0x11674fa1
+0, 18900, 160, 0xf2da5414
+0, 19800, 160, 0x97754dbc
+0, 20700, 160, 0x40a24d94
+0, 21600, 160, 0x26b34ebf
+0, 22500, 160, 0x7730542f
+0, 23400, 160, 0xb45254aa
+0, 24300, 160, 0xd8d752c3
+0, 25200, 160, 0x655c4a81
+0, 26100, 160, 0xa5da4f35
+0, 27000, 160, 0xd43551a1
+0, 27900, 160, 0x72a74e7d
+0, 28800, 160, 0xdb2150b3
+0, 29700, 160, 0x972852a1
+0, 30600, 160, 0xbae14c07
+0, 31500, 160, 0x23b54d57
+0, 32400, 160, 0x2d9650a5
+0, 33300, 160, 0xaf755107
+0, 34200, 160, 0xdb054f0e
+0, 35100, 160, 0x9f084cc0
+0, 36000, 160, 0x64ca5760
+0, 36900, 160, 0x3ea24be2
+0, 37800, 160, 0x93ea503b
+0, 38700, 160, 0xb6694afa
+0, 39600, 160, 0xf94c52e7
+0, 40500, 160, 0x2b7156b8
+0, 41400, 160, 0xbbdf414c
+0, 42300, 160, 0x10cd4ac8
+0, 43200, 160, 0x39885453
+0, 44100, 160, 0xa1505568
+0, 45000, 160, 0x86124ec1
+0, 45900, 160, 0xe2ab5489
+0, 46800, 160, 0x406254bc
+0, 47700, 160, 0x09044629
+0, 48600, 160, 0xb2ed5702
+0, 49500, 160, 0xd9ee5188
+0, 50400, 160, 0x59f7592a
+0, 51300, 160, 0x8f144c08
+0, 52200, 160, 0x90394e61
+0, 53100, 160, 0x79524df7
+0, 54000, 160, 0x58044674
+0, 54900, 160, 0x73b24d90
+0, 55800, 160, 0x80e257a1
+0, 56700, 160, 0xe8ff4caf
+0, 57600, 160, 0x1db84e3e
+0, 58500, 160, 0xd7db59d9
+0, 59400, 160, 0x43244c15
+0, 60300, 160, 0x1f63558f
+0, 61200, 160, 0xf0d851c6
+0, 62100, 160, 0x76484f3a
+0, 63000, 160, 0x5746551e
+0, 63900, 160, 0x83b54cd7
+0, 64800, 160, 0x97f550a1
+0, 65700, 160, 0x77c45340
+0, 66600, 160, 0xfd7b520a
+0, 67500, 160, 0x989a4e13
+0, 68400, 160, 0x9a8551c0
+0, 69300, 160, 0xa0cb4f93
+0, 70200, 160, 0xc568536f
+0, 71100, 160, 0x6fa74a95
+0, 72000, 160, 0xd550568b
+0, 72900, 160, 0xf88f4de5
+0, 73800, 160, 0x91285517
+0, 74700, 160, 0xdb675270
+0, 75600, 160, 0x606c53f9
+0, 76500, 160, 0x43f64601
+0, 77400, 160, 0x28b94b45
+0, 78300, 160, 0x7f2347f5
+0, 79200, 160, 0x84ba55db
+0, 80100, 160, 0x3ca3477c
+0, 81000, 160, 0x57d158ba
+0, 81900, 160, 0x2c3c506d
+0, 82800, 160, 0x59b34e5f
+0, 83700, 160, 0x014f530a
+0, 84600, 160, 0x877f4f76
+0, 85500, 160, 0x97a65c5f
+0, 86400, 160, 0xf643516d
+0, 87300, 160, 0x6ccc5242
+0, 88200, 160, 0x895450bd
+0, 89100, 160, 0xe246570e
+0, 90000, 160, 0xbb9f4a0c
+0, 90900, 160, 0x60e646fe
+0, 91800, 160, 0x546f515b
+0, 92700, 160, 0xc59254f0
+0, 93600, 160, 0xcad6551f
+0, 94500, 160, 0x14e14fac
+0, 95400, 160, 0x3cf94c52
+0, 96300, 160, 0x99b14f45
+0, 97200, 160, 0xfdb14dc7
+0, 98100, 160, 0x48f359e7
+0, 99000, 160, 0x186153e3
+0, 99900, 160, 0x047d4a78
+0, 100800, 160, 0x992f462b
+0, 101700, 160, 0x4a0e504d
+0, 102600, 160, 0x1f245275
+0, 103500, 160, 0x026959a9
+0, 104400, 160, 0x648846e7
+0, 105300, 160, 0xcac94cb3
+0, 106200, 160, 0x55e551a4
+0, 107100, 160, 0x767a5315
+0, 108000, 160, 0xbfde4d2b
+0, 108900, 160, 0x29bf4613
+0, 109800, 160, 0x8a8d5394
+0, 110700, 160, 0x36f94dae
+0, 111600, 160, 0x4cbf50ba
+0, 112500, 160, 0x9af44d8b
+0, 113400, 160, 0x6e8a519e
+0, 114300, 160, 0x496348b7
+0, 115200, 160, 0x95324eb2
+0, 116100, 160, 0x5bfe5118
+0, 117000, 160, 0xa1ff4c88
+0, 117900, 160, 0x86c2500a
+0, 118800, 160, 0xc53353c5
+0, 119700, 160, 0x062f52ee
+0, 120600, 160, 0x11cf522d
+0, 121500, 160, 0x054f5855
+0, 122400, 160, 0x8c4e44e9
+0, 123300, 160, 0x4d514fda
+0, 124200, 160, 0x5726568e
+0, 125100, 160, 0x281859ad
+0, 126000, 160, 0x3f3344f8
+0, 126900, 160, 0x2cbb3ee5
+0, 127800, 160, 0xa075551c
+0, 128700, 160, 0xafb25528
+0, 129600, 160, 0x9221478a
+0, 130500, 160, 0x6cb15634
+0, 131400, 160, 0xb5cf4523
+0, 132300, 160, 0x8a7a4f2c
+0, 133200, 160, 0x278e553d
+0, 134100, 160, 0x49054ad3
+0, 135000, 160, 0x5d7449bb
+0, 135900, 160, 0x67c346a0
+0, 136800, 160, 0x5d915bf8
+0, 137700, 160, 0x671355b2
+0, 138600, 160, 0xdfa84ee6
+0, 139500, 160, 0x4c3552d0
+0, 140400, 160, 0x63a1483c
+0, 141300, 160, 0x14c151ba
+0, 142200, 160, 0xf7434d78
+0, 143100, 160, 0x1c3652c9
+0, 144000, 160, 0x035b51da
+0, 144900, 160, 0x2bf6496b
+0, 145800, 160, 0x50a14f14
+0, 146700, 160, 0x518948f8
+0, 147600, 160, 0x7e784331
+0, 148500, 160, 0x73384dce
+0, 149400, 160, 0x11015066
+0, 150300, 160, 0xacc5525c
+0, 151200, 160, 0xf75a5431
+0, 152100, 160, 0xa78e4b8a
+0, 153000, 160, 0xd07955b0
+0, 153900, 160, 0x63164a03
+0, 154800, 160, 0x952f519e
+0, 155700, 160, 0xe5764f77
+0, 156600, 160, 0xa9255738
+0, 157500, 160, 0x65d64ce5
+0, 158400, 160, 0x8ab7507c
+0, 159300, 160, 0xf5265251
+0, 160200, 160, 0xa6a84d74
+0, 161100, 160, 0xc2594fee
+0, 162000, 160, 0xdfae5056
+0, 162900, 160, 0xa5a74c11
+0, 163800, 160, 0x5fdf4a21
+0, 164700, 160, 0x11014f8d
+0, 165600, 160, 0x08d0553f
+0, 166500, 160, 0x3036520e
+0, 167400, 160, 0xee3a464e
+0, 168300, 160, 0xbfd94949
+0, 169200, 160, 0x21625176
+0, 170100, 160, 0x6c714e8d
+0, 171000, 160, 0x055a4c05
+0, 171900, 160, 0xc7f35347
+0, 172800, 160, 0x82344b60
+0, 173700, 160, 0x99854ce4
+0, 174600, 160, 0x95504ec3
+0, 175500, 160, 0xe245502a
+0, 176400, 160, 0xb0e14a4c
+0, 177300, 160, 0x09835b86
+0, 178200, 160, 0xe9495220
+0, 179100, 160, 0xce9b514f
+0, 180000, 160, 0xbaf85695
+0, 180900, 160, 0x69aa3f1d
+0, 181800, 160, 0xd6a551b8
+0, 182700, 160, 0x4eb956e6
+0, 183600, 160, 0xdd6d4e58
+0, 184500, 160, 0xba1f4814
+0, 185400, 160, 0x4a604f48
+0, 186300, 160, 0xa8995890
+0, 187200, 160, 0x3a80616b
+0, 188100, 160, 0xfb796013
+0, 189000, 160, 0x8eba5c12
+0, 189900, 160, 0xd37859b9
+0, 190800, 160, 0x19a857c8
+0, 191700, 160, 0xec0e5a16
+0, 192600, 160, 0xd5335159
+0, 193500, 160, 0x560f4de7
+0, 194400, 160, 0x06d354c8
+0, 195300, 160, 0xdade5860
+0, 196200, 160, 0x093a512c
+0, 197100, 160, 0xb37b5098
+0, 198000, 160, 0x3eea537c
+0, 198900, 160, 0xf5c94f06
+0, 199800, 160, 0x552c4bb2
+0, 200700, 160, 0xea9a5a79
+0, 201600, 160, 0xd2645494
+0, 202500, 160, 0x5ba958ea
+0, 203400, 160, 0x54b559cf
+0, 204300, 160, 0x86bf5bba
+0, 205200, 160, 0xb89b6149
+0, 206100, 160, 0x1e825314
+0, 207000, 160, 0xf0d250cc
+0, 207900, 160, 0xc7ad53ba
+0, 208800, 160, 0x320c552f
+0, 209700, 160, 0xc62756f7
+0, 210600, 160, 0xa41351f7
+0, 211500, 160, 0x27ed4e78
+0, 212400, 160, 0x8d6047bc
+0, 213300, 160, 0xa45c48d0
+0, 214200, 160, 0x14da5400
+0, 215100, 160, 0x48514dd2
+0, 216000, 160, 0xec395318
+0, 216900, 160, 0xf3c85e4a
+0, 217800, 160, 0x657a63ed
+0, 218700, 160, 0xcc975c4d
+0, 219600, 160, 0x86125dd4
+0, 220500, 160, 0x6a3f6019
+0, 221400, 160, 0x84c05aeb
+0, 222300, 160, 0xe68561f7
+0, 223200, 160, 0x7ec763ae
+0, 224100, 160, 0x91bd5792
+0, 225000, 160, 0xb9365c8e
+0, 225900, 160, 0x42d7587a
+0, 226800, 160, 0x80a45453
+0, 227700, 160, 0x9ecf50c2
+0, 228600, 160, 0xc8de5173
+0, 229500, 160, 0x776952f7
+0, 230400, 160, 0x45f856c0
+0, 231300, 160, 0x729c4d73
+0, 232200, 160, 0xfd364a18
+0, 233100, 160, 0x709e587d
+0, 234000, 160, 0x288240e5
+0, 234900, 160, 0x16a6493f
+0, 235800, 160, 0x76db596f
+0, 236700, 160, 0x16c24a51
+0, 237600, 160, 0xc55b5a8f
+0, 238500, 160, 0x19024a2e
+0, 239400, 160, 0x16514d1b
+0, 240300, 160, 0x48bb5b82
+0, 241200, 160, 0x5a6e4d80
+0, 242100, 160, 0x6d404b0f
+0, 243000, 160, 0x57bc4e4a
+0, 243900, 160, 0xc10c5381
+0, 244800, 160, 0x34bd51d9
+0, 245700, 160, 0x5dcf52b7
+0, 246600, 160, 0xf61f57a7
+0, 247500, 160, 0x4e204934
+0, 248400, 160, 0xe18b4a3f
+0, 249300, 160, 0xb81256e3
+0, 250200, 160, 0x294047b2
+0, 251100, 160, 0x3ad559df
+0, 252000, 160, 0xd28d4d86
+0, 252900, 160, 0x67b75895
+0, 253800, 160, 0x191357b0
+0, 254700, 160, 0x8016556f
+0, 255600, 160, 0x62475c86
+0, 256500, 160, 0x0c975bc9
+0, 257400, 160, 0x901c5909
+0, 258300, 160, 0x9909567d
+0, 259200, 160, 0xce715b99
+0, 260100, 160, 0xae5062b1
+0, 261000, 160, 0x5bd056d6
+0, 261900, 160, 0xe3d3555a
+0, 262800, 160, 0xc4b1555c
+0, 263700, 160, 0x39c95649
+0, 264600, 160, 0x50145d11
+0, 265500, 160, 0xc0ba5307
+0, 266400, 160, 0x182455a3
+0, 267300, 160, 0x36c24e98
+0, 268200, 160, 0x1b5b52d0
+0, 269100, 160, 0xd38352d1
+0, 270000, 160, 0x6a1d5d2a
+0, 270900, 160, 0x50f05c44
+0, 271800, 160, 0xb2365dc1
+0, 272700, 160, 0x10825934
+0, 273600, 160, 0xcb4c61c2
+0, 274500, 160, 0x578252ab
+0, 275400, 160, 0xed99596c
+0, 276300, 160, 0xdfec6305
+0, 277200, 160, 0x97e2550a
+0, 278100, 160, 0xd60a56e1
+0, 279000, 160, 0xb6c4535e
+0, 279900, 160, 0x4d2e536c
+0, 280800, 160, 0xdef85cc7
+0, 281700, 160, 0xee985a98
+0, 282600, 160, 0x006a4cdb
+0, 283500, 160, 0xd06652ad
+0, 284400, 160, 0xeeee4ed6
+0, 285300, 160, 0xcb8b586d
+0, 286200, 160, 0x2ee4556e
+0, 287100, 160, 0x6d924c01
+0, 288000, 160, 0x7ff257cc
+0, 288900, 160, 0x67df5710
+0, 289800, 160, 0x0f704f29
+0, 290700, 160, 0x19dc53a7
+0, 291600, 160, 0xfbf44bc0
+0, 292500, 160, 0x640b5718
+0, 293400, 160, 0x2bfd4b91
+0, 294300, 160, 0xaae049bf
+0, 295200, 160, 0xca3154f6
+0, 296100, 160, 0x36064f2c
+0, 297000, 160, 0x28404919
+0, 297900, 160, 0x9c944fe3
+0, 298800, 160, 0xb4214c82
+0, 299700, 160, 0x442c514d
+0, 300600, 160, 0x44434ea5
+0, 301500, 160, 0x82a05aae
+0, 302400, 160, 0x4b86510d
+0, 303300, 160, 0x46844eab
+0, 304200, 160, 0xe5455deb
+0, 305100, 160, 0x60826550
+0, 306000, 160, 0x3c5a5448
+0, 306900, 160, 0x2db860c9
+0, 307800, 160, 0x4d845b78
+0, 308700, 160, 0x81dc5e23
+0, 309600, 160, 0x78c95932
+0, 310500, 160, 0xb5be57cd
+0, 311400, 160, 0x6fa45c65
+0, 312300, 160, 0x4e085e2a
+0, 313200, 160, 0x50ee530c
+0, 314100, 160, 0x2bb85587
+0, 315000, 160, 0x6d58614e
+0, 315900, 160, 0xcf4c5d69
+0, 316800, 160, 0x3cbf5ffb
+0, 317700, 160, 0x452157d3
+0, 318600, 160, 0x3cb55cd8
+0, 319500, 160, 0x2bba5735
+0, 320400, 160, 0x36a45670
+0, 321300, 160, 0x23b85b8a
+0, 322200, 160, 0x9a255457
+0, 323100, 160, 0x4e6956f3
+0, 324000, 160, 0xa0714edc
+0, 324900, 160, 0x7dee4a3d
+0, 325800, 160, 0x86404bc9
+0, 326700, 160, 0x358c50cd
+0, 327600, 160, 0x9eda47e8
+0, 328500, 160, 0x3cfe522e
+0, 329400, 160, 0xddb95758
+0, 330300, 160, 0x1a434a83
+0, 331200, 160, 0xa8a450bb
+0, 332100, 160, 0x44e7530e
+0, 333000, 160, 0x59b5555a
+0, 333900, 160, 0x65404db1
+0, 334800, 160, 0xcac15945
+0, 335700, 160, 0x38864f17
+0, 336600, 160, 0x61114f30
+0, 337500, 160, 0x195542d8
+0, 338400, 160, 0xacbb4c69
+0, 339300, 160, 0xd0da4ab9
+0, 340200, 160, 0x563d4eb6
+0, 341100, 160, 0xd0ce503c
+0, 342000, 160, 0x8b684e15
+0, 342900, 160, 0x711541d3
+0, 343800, 160, 0xb28b5b9b
+0, 344700, 160, 0x48b145e4
+0, 345600, 160, 0x908f5606
+0, 346500, 160, 0x22c74f02
+0, 347400, 160, 0x87274716
+0, 348300, 160, 0xaa2351e6
+0, 349200, 160, 0x2df5505a
+0, 350100, 160, 0x7999525c
+0, 351000, 160, 0x728a4b73
+0, 351900, 160, 0xa67447ff
+0, 352800, 160, 0x28884a20
+0, 353700, 160, 0x3ffa5840
+0, 354600, 160, 0xd6265047
+0, 355500, 160, 0x2f1553a8
+0, 356400, 160, 0xac0653ec
+0, 357300, 160, 0x35844368
+0, 358200, 160, 0x6e1553ba
+0, 359100, 160, 0xb62a4c88
+0, 360000, 160, 0x88a04ffc
+0, 360900, 160, 0x947e525e
+0, 361800, 160, 0x3dd24f98
+0, 362700, 160, 0x942e542e
+0, 363600, 160, 0xdb985211
+0, 364500, 160, 0x615a5022
+0, 365400, 160, 0x71c04569
+0, 366300, 160, 0xbbbe4f41
+0, 367200, 160, 0x62074e0b
+0, 368100, 160, 0x2c5d56c7
+0, 369000, 160, 0x34344c18
+0, 369900, 160, 0xc57d4c22
+0, 370800, 160, 0xb273560d
+0, 371700, 160, 0x7e985229
+0, 372600, 160, 0x2dd3542d
+0, 373500, 160, 0x39645000
+0, 374400, 160, 0x1b3f4d9e
+0, 375300, 160, 0x0bbf5ed2
+0, 376200, 160, 0xc81f5608
+0, 377100, 160, 0xe82e569e
+0, 378000, 160, 0x34df537d
+0, 378900, 160, 0x53175837
+0, 379800, 160, 0xbb76517f
+0, 380700, 160, 0xd5a25737
+0, 381600, 160, 0x58eb4f3d
+0, 382500, 160, 0x8f6e51d3
+0, 383400, 160, 0x1fd85602
+0, 384300, 160, 0xef2a4ee7
+0, 385200, 160, 0x0e6e58f4
+0, 386100, 160, 0x80345497
+0, 387000, 160, 0x710150a1
+0, 387900, 160, 0x32fb51db
+0, 388800, 160, 0x7efd564c
+0, 389700, 160, 0xf6604f26
+0, 390600, 160, 0xc0954d7e
+0, 391500, 160, 0x27705072
+0, 392400, 160, 0xd26f5958
+0, 393300, 160, 0x2c2552cd
+0, 394200, 160, 0xd14056b1
+0, 395100, 160, 0x11f356d2
+0, 396000, 160, 0x93b35efd
+0, 396900, 160, 0xa6d65ae7
+0, 397800, 160, 0x95015177
+0, 398700, 160, 0x2e6157e8
+0, 399600, 160, 0xb90c5021
+0, 400500, 160, 0xf39155c9
+0, 401400, 160, 0xd6ad544b
+0, 402300, 160, 0x4b8a5b98
+0, 403200, 160, 0x90a94f2d
+0, 404100, 160, 0x46a04f3f
+0, 405000, 160, 0x542b5cd1
+0, 405900, 160, 0xebaa5710
+0, 406800, 160, 0x504854a0
+0, 407700, 160, 0xbd9d53b5
+0, 408600, 160, 0x91524fed
+0, 409500, 160, 0x9b7a582d
+0, 410400, 160, 0xa4f258cf
+0, 411300, 160, 0x46274dda
+0, 412200, 160, 0xc0335ba9
+0, 413100, 160, 0xe59c5c74
+0, 414000, 160, 0xc2ee5ab0
+0, 414900, 160, 0x3e035996
+0, 415800, 160, 0x63e25521
+0, 416700, 160, 0xc09851af
+0, 417600, 160, 0xb8225715
+0, 418500, 160, 0x74355bfb
+0, 419400, 160, 0xf4c75adf
+0, 420300, 160, 0x2f8b56cd
+0, 421200, 160, 0xb4705795
+0, 422100, 160, 0xb4b25506
+0, 423000, 160, 0xaadb54f8
+0, 423900, 160, 0xe6d158aa
+0, 424800, 160, 0xed64614f
+0, 425700, 160, 0x80195732
+0, 426600, 160, 0xa8995f0e
+0, 427500, 160, 0xdc4a520d
+0, 428400, 160, 0x071a5bae
+0, 429300, 160, 0xce1b5ae9
+0, 430200, 160, 0x85e25804
+0, 431100, 160, 0x435e555f
+0, 432000, 160, 0xe4154ef4
+0, 432900, 160, 0xeff857b4
+0, 433800, 160, 0xc9e25868
+0, 434700, 160, 0x6e6961eb
+0, 435600, 160, 0x361e45e6
+0, 436500, 160, 0xf8a94988
+0, 437400, 160, 0x9de758b3
+0, 438300, 160, 0x2e65533e
+0, 439200, 160, 0x3f89422d
+0, 440100, 160, 0x77fd56a5
+0, 441000, 160, 0x91104845
+0, 441900, 160, 0x2eeb5491
+0, 442800, 160, 0x6a5348c4
+0, 443700, 160, 0xe0954882
+0, 444600, 160, 0x7e915761
+0, 445500, 160, 0x2cb5531f
+0, 446400, 160, 0xe1dc4ecd
+0, 447300, 160, 0xbf6b4e61
+0, 448200, 160, 0x3d6b5746
+0, 449100, 160, 0xe8bd5077
+0, 450000, 160, 0xd38d5921
+0, 450900, 160, 0xfc534e38
+0, 451800, 160, 0xd361475b
+0, 452700, 160, 0x4d5152c7
+0, 453600, 160, 0xb6684d11
+0, 454500, 160, 0xd2e25864
+0, 455400, 160, 0x02ec536a
+0, 456300, 160, 0x27ac550e
+0, 457200, 160, 0xe8d44e2d
+0, 458100, 160, 0x520152c8
+0, 459000, 160, 0xace747ea
+0, 459900, 160, 0x773a4ee3
+0, 460800, 160, 0x7dd1559f
+0, 461700, 160, 0x124453a8
+0, 462600, 160, 0x04154991
+0, 463500, 160, 0x3c794d98
+0, 464400, 160, 0x309f4e47
+0, 465300, 160, 0x98c74a48
+0, 466200, 160, 0xd0c34bcc
+0, 467100, 160, 0xfa304e19
+0, 468000, 160, 0x69505201
+0, 468900, 160, 0x2e714ac7
+0, 469800, 160, 0x076654a3
+0, 470700, 160, 0xc6674e27
+0, 471600, 160, 0x1adf4dd9
+0, 472500, 160, 0x4408507e
+0, 473400, 160, 0xd2654d94
+0, 474300, 160, 0x97a65cc0
+0, 475200, 160, 0xb53251f9
+0, 476100, 160, 0xd498584b
+0, 477000, 160, 0x46a058c8
+0, 477900, 160, 0xa2f85cbd
+0, 478800, 160, 0x43b856fb
+0, 479700, 160, 0xdeb957ba
+0, 480600, 160, 0x3064580a
+0, 481500, 160, 0xe86357a5
+0, 482400, 160, 0x9b974d00
+0, 483300, 160, 0x66ee4ff3
+0, 484200, 160, 0x0b9958f7
+0, 485100, 160, 0xc3754d0a
+0, 486000, 160, 0x42314c33
+0, 486900, 160, 0x4550555f
+0, 487800, 160, 0x0f064e4c
+0, 488700, 160, 0xe569596d
+0, 489600, 160, 0x056c4751
+0, 490500, 160, 0xdc1049fc
+0, 491400, 160, 0x63c54a1e
+0, 492300, 160, 0xb402518e
+0, 493200, 160, 0xaf0d4b19
+0, 494100, 160, 0xa22b4c5b
+0, 495000, 160, 0x28084bbf
+0, 495900, 160, 0x10495224
+0, 496800, 160, 0x4cb94993
+0, 497700, 160, 0x17c15457
+0, 498600, 160, 0xbd834d6d
+0, 499500, 160, 0x6ca25235
+0, 500400, 160, 0x84b74f89
+0, 501300, 160, 0xdeef4e76
+0, 502200, 160, 0x6ab05188
+0, 503100, 160, 0xa91c4646
+0, 504000, 160, 0xad574e7d
+0, 504900, 160, 0xba264d69
+0, 505800, 160, 0xd8734dd0
+0, 506700, 160, 0x69f25581
+0, 507600, 160, 0x3b8e4ae9
+0, 508500, 160, 0xb1124607
+0, 509400, 160, 0xd78e4e4f
+0, 510300, 160, 0x05a1504f
+0, 511200, 160, 0x3e705270
+0, 512100, 160, 0x1e144b3b
+0, 513000, 160, 0xbb0b5416
+0, 513900, 160, 0xc26f5b45
+0, 514800, 160, 0x14224ab9
+0, 515700, 160, 0x2bbd4837
+0, 516600, 160, 0xd2bf4e60
+0, 517500, 160, 0xbeec506c
+0, 518400, 160, 0x2cd34d3a
+0, 519300, 160, 0x85134fc6
+0, 520200, 160, 0xdb9a4ac2
+0, 521100, 160, 0x92715256
+0, 522000, 160, 0xff395098
+0, 522900, 160, 0xa5ec560c
+0, 523800, 160, 0xce95534b
+0, 524700, 160, 0xe36f46f1
+0, 525600, 160, 0x45f74a58
+0, 526500, 160, 0x02d05440
+0, 527400, 160, 0xa005529f
+0, 528300, 160, 0xae0f3f22
+0, 529200, 160, 0x3f984eb0
+0, 530100, 160, 0xc5bd5015
+0, 531000, 160, 0xf4504c53
+0, 531900, 160, 0x7f4044c5
+0, 532800, 160, 0x82dd4bab
+0, 533700, 160, 0x7a0d5122
+0, 534600, 160, 0xd0da5271
+0, 535500, 160, 0x67d14e3e
+0, 536400, 160, 0x54564f42
+0, 537300, 160, 0x77df4e0a
+0, 538200, 160, 0x0c4a4f70
+0, 539100, 160, 0xb2944f40
+0, 540000, 160, 0xe57a52de
+0, 540900, 160, 0x7d994ed1
+0, 541800, 160, 0x9dc35763
+0, 542700, 160, 0x8d0a4da9
+0, 543600, 160, 0x0c6449a4
+0, 544500, 160, 0xc73c503a
+0, 545400, 160, 0x52904cbe
+0, 546300, 160, 0x49824c2e
+0, 547200, 160, 0xb7e14e0b
+0, 548100, 160, 0x9745548e
+0, 549000, 160, 0xdafb4c20
+0, 549900, 160, 0x1aa84d67
+0, 550800, 160, 0x64bc5033
+0, 551700, 160, 0x9e2e5a05
+0, 552600, 160, 0x69144bc5
+0, 553500, 160, 0xce1253fa
+0, 554400, 160, 0x359f4c15
+0, 555300, 160, 0xdba74ed0
+0, 556200, 160, 0xea1453b8
+0, 557100, 160, 0xccdf49d3
+0, 558000, 160, 0xeb324750
+0, 558900, 160, 0x62b14ad4
+0, 559800, 160, 0x446e50c0
+0, 560700, 160, 0x111e5151
+0, 561600, 160, 0x6be84f3a
+0, 562500, 160, 0xf5cf4e42
+0, 563400, 160, 0xcc995459
+0, 564300, 160, 0x0faf5172
+0, 565200, 160, 0x31334f66
+0, 566100, 160, 0x20ba52c0
+0, 567000, 160, 0xc7cc4975
+0, 567900, 160, 0x9e7a51ba
+0, 568800, 160, 0x52884ff1
+0, 569700, 160, 0xc7a84cfd
+0, 570600, 160, 0x5ae64c22
+0, 571500, 160, 0x68125a92
+0, 572400, 160, 0x39ed54f1
+0, 573300, 160, 0xfa0a4ad1
+0, 574200, 160, 0xe8c8590c
+0, 575100, 160, 0x5f555576
+0, 576000, 160, 0xaf7a57a1
+0, 576900, 160, 0x858257e9
+0, 577800, 160, 0x1223523e
+0, 578700, 160, 0x446954a1
+0, 579600, 160, 0xfbe952d9
+0, 580500, 160, 0xd56259ff
+0, 581400, 160, 0xc4fa4f44
+0, 582300, 160, 0x77cc57f6
+0, 583200, 160, 0x53d3573d
+0, 584100, 160, 0x085e4ff9
+0, 585000, 160, 0x7a4e5410
+0, 585900, 160, 0xb4ad5794
+0, 586800, 160, 0x71255738
+0, 587700, 160, 0x36724918
+0, 588600, 160, 0x370e5974
+0, 589500, 160, 0xb709596c
+0, 590400, 160, 0x89b05052
+0, 591300, 160, 0x74e550ce
+0, 592200, 160, 0x6e2c5a49
+0, 593100, 160, 0x4dfa5b50
+0, 594000, 160, 0x80764c70
+0, 594900, 160, 0xc1d14fc6
+0, 595800, 160, 0x53e746b3
+0, 596700, 160, 0x728350c0
+0, 597600, 160, 0x9aa6500e
+0, 598500, 160, 0x60985454
+0, 599400, 160, 0xa0c54b6f
+0, 600300, 160, 0xe3b157ea
+0, 601200, 160, 0xce86573b
+0, 602100, 160, 0x9dad5535
+0, 603000, 160, 0xb3094af9
+0, 603900, 160, 0x2d1456ed
+0, 604800, 160, 0x328248b9
+0, 605700, 160, 0x4ffb4f52
+0, 606600, 160, 0x71fe53de
+0, 607500, 160, 0x0d114e92
+0, 608400, 160, 0x37065510
+0, 609300, 160, 0x426c4c07
+0, 610200, 160, 0x58e3528b
+0, 611100, 160, 0x71674484
+0, 612000, 160, 0x45934ee1
+0, 612900, 160, 0x4e914b31
+0, 613800, 160, 0x525b4ec2
+0, 614700, 160, 0x4393563d
+0, 615600, 160, 0xb10154e9
+0, 616500, 160, 0x23b15a4d
+0, 617400, 160, 0x6d995220
+0, 618300, 160, 0xcd2949fd
+0, 619200, 160, 0x67234f75
+0, 620100, 160, 0x00cc4cdb
+0, 621000, 160, 0x97c35574
+0, 621900, 160, 0xc0855753
+0, 622800, 160, 0xf4e650a5
+0, 623700, 160, 0x95b14bc2
+0, 624600, 160, 0x04d948dc
+0, 625500, 160, 0x284d4d02
+0, 626400, 160, 0xfb0d4cd9
+0, 627300, 160, 0x0e515126
+0, 628200, 160, 0xb4055a86
+0, 629100, 160, 0x0bbe4f68
+0, 630000, 160, 0xf1b848af
+0, 630900, 160, 0x7d154853
+0, 631800, 160, 0x78225418
+0, 632700, 160, 0xfb2f523e
+0, 633600, 160, 0xa6d34ea6
+0, 634500, 160, 0xe4264e30
+0, 635400, 160, 0x113750aa
+0, 636300, 160, 0x4073529b
+0, 637200, 160, 0xd1754dda
+0, 638100, 160, 0x1b495413
+0, 639000, 160, 0x29f94cd8
+0, 639900, 160, 0x49004a53
+0, 640800, 160, 0x1fec4de4
+0, 641700, 160, 0x7d6b4670
+0, 642600, 160, 0x626c4c9f
+0, 643500, 160, 0x79265234
+0, 644400, 160, 0xab765b86
+0, 645300, 160, 0xe9ae4d26
+0, 646200, 160, 0xeee1481f
+0, 647100, 160, 0x289d5287
+0, 648000, 160, 0xb5524e8b
+0, 648900, 160, 0x7e715764
+0, 649800, 160, 0xb1b25091
+0, 650700, 160, 0xf1a946f6
+0, 651600, 160, 0x57dc51bd
+0, 652500, 160, 0x4c0b4f14
+0, 653400, 160, 0xdc1f4930
+0, 654300, 160, 0x79d75057
+0, 655200, 160, 0x22bd52df
+0, 656100, 160, 0x963a5562
+0, 657000, 160, 0x7e475303
+0, 657900, 160, 0x2c065494
+0, 658800, 160, 0xb0514720
+0, 659700, 160, 0xbc734849
+0, 660600, 160, 0xf4924e4d
+0, 661500, 160, 0xe50f44c9
+0, 662400, 160, 0x978c4ce8
+0, 663300, 160, 0x302e51c2
+0, 664200, 160, 0x262b4a60
+0, 665100, 160, 0xf95f4e99
+0, 666000, 160, 0x7465504a
+0, 666900, 160, 0xab0e5108
+0, 667800, 160, 0xbec15395
+0, 668700, 160, 0x4f2c5139
+0, 669600, 160, 0x26444deb
+0, 670500, 160, 0xee4c4b15
+0, 671400, 160, 0x8bc350e1
+0, 672300, 160, 0xd0744a5a
+0, 673200, 160, 0xfee64d9d
+0, 674100, 160, 0x234c50b6
+0, 675000, 160, 0x8592482c
+0, 675900, 160, 0x5e8b5308
+0, 676800, 160, 0x4f9848c7
+0, 677700, 160, 0x939d4faa
+0, 678600, 160, 0x797654f1
+0, 679500, 160, 0x15d24d9b
+0, 680400, 160, 0xa6e54bd2
+0, 681300, 160, 0x755e4c90
+0, 682200, 160, 0xcd334bce
+0, 683100, 160, 0xfc1746e9
+0, 684000, 160, 0x81f04dd5
+0, 684900, 160, 0x44b35080
+0, 685800, 160, 0x91e65217
+0, 686700, 160, 0x492150af
+0, 687600, 160, 0xf73e58ec
+0, 688500, 160, 0xf988538a
+0, 689400, 160, 0x0dee4c10
+0, 690300, 160, 0x2c9f4c23
+0, 691200, 160, 0x8c1e4e08
+0, 692100, 160, 0x25bb5286
+0, 693000, 160, 0xd0ed469b
+0, 693900, 160, 0x71eb50e8
+0, 694800, 160, 0x249f4d26
+0, 695700, 160, 0x9662498f
+0, 696600, 160, 0x49ee55e2
+0, 697500, 160, 0x54d9491b
+0, 698400, 160, 0x4c675649
+0, 699300, 160, 0x0e4b4b34
+0, 700200, 160, 0x776f4995
+0, 701100, 160, 0x722656b2
+0, 702000, 160, 0x081d4b6f
+0, 702900, 160, 0xf70746fe
+0, 703800, 160, 0x08b151da
+0, 704700, 160, 0x6b255328
+0, 705600, 160, 0xeb2b586a
+0, 706500, 160, 0x812b4444
+0, 707400, 160, 0x1e16533f
+0, 708300, 160, 0xc1244760
+0, 709200, 160, 0x67584d87
+0, 710100, 160, 0xde8b5726
+0, 711000, 160, 0xe96d4e3e
+0, 711900, 160, 0x41174c98
+0, 712800, 160, 0x4cdd4cd8
+0, 713700, 160, 0xfb724b64
+0, 714600, 160, 0x78f154df
+0, 715500, 160, 0x97e1476d
+0, 716400, 160, 0x6f034e7f
+0, 717300, 160, 0x93b240df
+0, 718200, 160, 0xc4d040e6
+0, 719100, 160, 0xe47744a4
+0, 720000, 160, 0x87a950ff
+0, 720900, 160, 0x7079491b
+0, 721800, 160, 0x89f0491a
+0, 722700, 160, 0x70b8467e
+0, 723600, 160, 0x20945294
+0, 724500, 160, 0x2d5c4919
+0, 725400, 160, 0x1ed44c78
+0, 726300, 160, 0x93d74a5f
+0, 727200, 160, 0x300e490e
+0, 728100, 160, 0x8249558d
+0, 729000, 160, 0x630a4f57
+0, 729900, 160, 0xdd6e475f
+0, 730800, 160, 0xf50941e5
+0, 731700, 160, 0x1fe44bea
+0, 732600, 160, 0x03be5469
+0, 733500, 160, 0x7ece4f4c
+0, 734400, 160, 0x31f953dd
+0, 735300, 160, 0x22a44b7d
+0, 736200, 160, 0x1f5e5562
+0, 737100, 160, 0x771b5688
+0, 738000, 160, 0x7d1c4d45
+0, 738900, 160, 0x6bc45cd0
+0, 739800, 160, 0x8f714c36
+0, 740700, 160, 0xfb1f4c87
+0, 741600, 160, 0x1f8a4b36
+0, 742500, 160, 0xee5c451a
+0, 743400, 160, 0xd56950ac
+0, 744300, 160, 0x529057f6
+0, 745200, 160, 0x336641fd
+0, 746100, 160, 0xa0dd5a66
+0, 747000, 160, 0x5f4b5248
+0, 747900, 160, 0xb6ef49a3
+0, 748800, 160, 0x07705f19
+0, 749700, 160, 0x3fce4bbb
+0, 750600, 160, 0xda395511
+0, 751500, 160, 0x1ecf5145
+0, 752400, 160, 0x88a547ab
+0, 753300, 160, 0x6c6849be
+0, 754200, 160, 0x979c4e97
+0, 755100, 160, 0x171854b3
+0, 756000, 160, 0x9a715283
+0, 756900, 160, 0x064e50ac
+0, 757800, 160, 0xc2fb4e94
+0, 758700, 160, 0x708146f5
+0, 759600, 160, 0x1ca45198
+0, 760500, 160, 0x332d4869
+0, 761400, 160, 0xc2ff4656
+0, 762300, 160, 0x0747552e
+0, 763200, 160, 0x0c3d4ba8
+0, 764100, 160, 0x72934dab
+0, 765000, 160, 0xbb1e5860
+0, 765900, 160, 0x526d4cea
+0, 766800, 160, 0xa4c445d6
+0, 767700, 160, 0x70cd49ba
+0, 768600, 160, 0x008c53a7
+0, 769500, 160, 0xf7174bca
+0, 770400, 160, 0x0bab4936
+0, 771300, 160, 0x59e5564d
+0, 772200, 160, 0x33045087
+0, 773100, 160, 0xde7454f0
+0, 774000, 160, 0x31184cc3
+0, 774900, 160, 0x37984bb3
+0, 775800, 160, 0xf5e052d4
+0, 776700, 160, 0x23ca4b42
+0, 777600, 160, 0xbe2a572b
+0, 778500, 160, 0x9a91538d
+0, 779400, 160, 0x8a994c40
+0, 780300, 160, 0x5dea51ee
+0, 781200, 160, 0x1b53524c
+0, 782100, 160, 0xd9e75227
+0, 783000, 160, 0x58384c3b
+0, 783900, 160, 0x4a1b53b2
+0, 784800, 160, 0xc2a3458a
+0, 785700, 160, 0x7f68502d
+0, 786600, 160, 0x85475559
+0, 787500, 160, 0xd0d25472
+0, 788400, 160, 0x4c0d4bbf
+0, 789300, 160, 0xcad352df
+0, 790200, 160, 0x17904c97
+0, 791100, 160, 0x4e774b8e
+0, 792000, 160, 0x21905952
+0, 792900, 160, 0xc2d950cd
+0, 793800, 160, 0xfdea55e6
+0, 794700, 160, 0x22ca4e37
+0, 795600, 160, 0x1143562a
+0, 796500, 160, 0xe83c583e
+0, 797400, 160, 0xba544b27
+0, 798300, 160, 0x1e8c50e4
+0, 799200, 160, 0xf7ca4d2a
+0, 800100, 160, 0x67764579
+0, 801000, 160, 0x40d74f42
+0, 801900, 160, 0x88e35360
+0, 802800, 160, 0xda3f4f5b
+0, 803700, 160, 0x19c1522f
+0, 804600, 160, 0x93ce4f78
+0, 805500, 160, 0xf65447ba
+0, 806400, 160, 0xc0bc4e5a
+0, 807300, 160, 0x4915572b
+0, 808200, 160, 0x1651460b
+0, 809100, 160, 0xffe552a5
+0, 810000, 160, 0x5bd351ab
+0, 810900, 160, 0xbbd85034
+0, 811800, 160, 0xb9ff505f
+0, 812700, 160, 0xfc104eaf
+0, 813600, 160, 0xdaa74d6c
+0, 814500, 160, 0x34b04d78
+0, 815400, 160, 0x1e924f70
+0, 816300, 160, 0x0d46512d
+0, 817200, 160, 0x0d115950
+0, 818100, 160, 0x62de55a4
+0, 819000, 160, 0x58d652ab
+0, 819900, 160, 0x1776584e
+0, 820800, 160, 0x60175a2b
+0, 821700, 160, 0x4d714c82
+0, 822600, 160, 0xe13c4ce0
+0, 823500, 160, 0x7cd15464
+0, 824400, 160, 0x6c87571a
+0, 825300, 160, 0x1abe4f07
+0, 826200, 160, 0x039d5661
+0, 827100, 160, 0x0eba5909
+0, 828000, 160, 0xa46e51ec
+0, 828900, 160, 0x9be44eb7
+0, 829800, 160, 0xe0634aad
+0, 830700, 160, 0xcd53530b
+0, 831600, 160, 0x12cd482c
+0, 832500, 160, 0x71884634
+0, 833400, 160, 0xd5845743
+0, 834300, 160, 0xacd1502c
+0, 835200, 160, 0x04795031
+0, 836100, 160, 0xf0df54b9
+0, 837000, 160, 0x43aa5155
+0, 837900, 160, 0x316a4988
+0, 838800, 160, 0xfbc64f8a
+0, 839700, 160, 0xda084e8e
+0, 840600, 160, 0x3cc34ce2
+0, 841500, 160, 0xbfc055d8
+0, 842400, 160, 0x20ef4876
+0, 843300, 160, 0x035a5660
+0, 844200, 160, 0xbc7255be
+0, 845100, 160, 0xba514f44
+0, 846000, 160, 0x868c4c9c
+0, 846900, 160, 0x83494f04
+0, 847800, 160, 0xa452521a
+0, 848700, 160, 0x2ed04f65
+0, 849600, 160, 0x2e3e592d
+0, 850500, 160, 0x82bc4763
+0, 851400, 160, 0x339950db
+0, 852300, 160, 0x5bb64eff
+0, 853200, 160, 0x347c4d85
+0, 854100, 160, 0x25e949a3
+0, 855000, 160, 0xbdf649a8
+0, 855900, 160, 0x498650f3
+0, 856800, 160, 0x2a6f4e60
+0, 857700, 160, 0x661e5697
+0, 858600, 160, 0x5d6150ca
+0, 859500, 160, 0xe7c74b8f
+0, 860400, 160, 0x1ae148da
+0, 861300, 160, 0xaeef485d
+0, 862200, 160, 0x105650c6
+0, 863100, 160, 0xc1c45376
+0, 864000, 160, 0x83c55011
+0, 864900, 160, 0x77025597
+0, 865800, 160, 0x324250b7
+0, 866700, 160, 0x5cdc570f
+0, 867600, 160, 0x292e52a1
+0, 868500, 160, 0x8d7a5090
+0, 869400, 160, 0x32fc54e4
+0, 870300, 160, 0x50984e8b
+0, 871200, 160, 0x07f442a0
+0, 872100, 160, 0xc91c4fc3
+0, 873000, 160, 0x06cf53d7
+0, 873900, 160, 0xa66c5923
+0, 874800, 160, 0xc2015120
+0, 875700, 160, 0xedfa50c4
+0, 876600, 160, 0xe4c85fb5
+0, 877500, 160, 0xcd7b4c65
+0, 878400, 160, 0xb22353c1
+0, 879300, 160, 0x298c5996
+0, 880200, 160, 0xefce51db
+0, 881100, 160, 0x6df74ee3
+0, 882000, 160, 0x7c46496b
+0, 882900, 160, 0x910a48a4
+0, 883800, 160, 0xbf504b1e
+0, 884700, 160, 0x096947e8
+0, 885600, 160, 0x4a07629d
+0, 886500, 160, 0x577b43c1
+0, 887400, 160, 0x939e4d6d
+0, 888300, 160, 0x486e48ac
+0, 889200, 160, 0x50064871
+0, 890100, 160, 0x4a255534
+0, 891000, 160, 0xc80d4618
+0, 891900, 160, 0xf18a4780
+0, 892800, 160, 0x1c274dd4
+0, 893700, 160, 0x2f3e4f7c
+0, 894600, 160, 0x44b24cc2
+0, 895500, 160, 0x89b451f4
+0, 896400, 160, 0x06515b65
+0, 897300, 160, 0xc5b857ce
+0, 898200, 160, 0xa47b47a7
+0, 899100, 160, 0xfb375448
diff --git a/tests/ref/fate/g729-1 b/tests/ref/fate/g729-1
new file mode 100644
index 0000000..6bf05c5
--- /dev/null
+++ b/tests/ref/fate/g729-1
@@ -0,0 +1,1000 @@
+0, 0, 160, 0xf7e550f0
+0, 900, 160, 0x42794ea8
+0, 1800, 160, 0xfe023e42
+0, 2700, 160, 0xc1ae40e3
+0, 3600, 160, 0xee6d4bf1
+0, 4500, 160, 0x107451d7
+0, 5400, 160, 0x40cb4ba4
+0, 6300, 160, 0x90504e5e
+0, 7200, 160, 0xf6f3531d
+0, 8100, 160, 0x48664ea0
+0, 9000, 160, 0xa30458e1
+0, 9900, 160, 0x00b74aa2
+0, 10800, 160, 0x95234e49
+0, 11700, 160, 0x9cf24a94
+0, 12600, 160, 0x4f2952f4
+0, 13500, 160, 0x658353db
+0, 14400, 160, 0x98ef4d79
+0, 15300, 160, 0x765d5472
+0, 16200, 160, 0xc6e25262
+0, 17100, 160, 0x33334993
+0, 18000, 160, 0xfa104dc5
+0, 18900, 160, 0x03ee5530
+0, 19800, 160, 0x52c54e0e
+0, 20700, 160, 0xbd744638
+0, 21600, 160, 0x7775519f
+0, 22500, 160, 0xd22f499e
+0, 23400, 160, 0x26af4eec
+0, 24300, 160, 0x37474ed9
+0, 25200, 160, 0x6b19548d
+0, 26100, 160, 0x4a3449b7
+0, 27000, 160, 0x2bed5231
+0, 27900, 160, 0x556d5349
+0, 28800, 160, 0xbb6c5227
+0, 29700, 160, 0xea354b4d
+0, 30600, 160, 0xf35f4b7d
+0, 31500, 160, 0x9dcb4e9d
+0, 32400, 160, 0xc81f5ac2
+0, 33300, 160, 0xfa054cfd
+0, 34200, 160, 0x0c554e62
+0, 35100, 160, 0x7ffa5250
+0, 36000, 160, 0x7e5148ec
+0, 36900, 160, 0x95bc4d69
+0, 37800, 160, 0xf34a5644
+0, 38700, 160, 0xcaa3493d
+0, 39600, 160, 0xa44745dc
+0, 40500, 160, 0x320355c0
+0, 41400, 160, 0xbd1e5670
+0, 42300, 160, 0xfe3250cd
+0, 43200, 160, 0xce7a574c
+0, 44100, 160, 0x09b04f6e
+0, 45000, 160, 0x035759c8
+0, 45900, 160, 0x713458c7
+0, 46800, 160, 0x9a75494b
+0, 47700, 160, 0x99114fef
+0, 48600, 160, 0x129251f0
+0, 49500, 160, 0x4eb845f2
+0, 50400, 160, 0x5d064da5
+0, 51300, 160, 0x5a8e4a34
+0, 52200, 160, 0x5b784608
+0, 53100, 160, 0x1ca7546a
+0, 54000, 160, 0x327e5cbf
+0, 54900, 160, 0xd7ae4bc3
+0, 55800, 160, 0xba3f55b4
+0, 56700, 160, 0x09fe4ca7
+0, 57600, 160, 0x347248ba
+0, 58500, 160, 0xf0bf52ff
+0, 59400, 160, 0x3500507e
+0, 60300, 160, 0x30e65135
+0, 61200, 160, 0x390a5201
+0, 62100, 160, 0xf0dc5bca
+0, 63000, 160, 0x69b94f64
+0, 63900, 160, 0x6ac04cf6
+0, 64800, 160, 0xbc014cf4
+0, 65700, 160, 0x4b564eca
+0, 66600, 160, 0x33e44e85
+0, 67500, 160, 0xe39e5343
+0, 68400, 160, 0xebf64c80
+0, 69300, 160, 0x5a92562b
+0, 70200, 160, 0xe0075c88
+0, 71100, 160, 0x59bd55e8
+0, 72000, 160, 0xe6ca4ef2
+0, 72900, 160, 0xea9a4df2
+0, 73800, 160, 0xf53c4bf6
+0, 74700, 160, 0x977a4f32
+0, 75600, 160, 0xe5894eb2
+0, 76500, 160, 0x956c4c28
+0, 77400, 160, 0xdff74c3d
+0, 78300, 160, 0xace74db7
+0, 79200, 160, 0x00e74ef5
+0, 80100, 160, 0x6633560a
+0, 81000, 160, 0xd63647c5
+0, 81900, 160, 0xff144eef
+0, 82800, 160, 0xc5fe4d51
+0, 83700, 160, 0x5c244c7c
+0, 84600, 160, 0x95be50f1
+0, 85500, 160, 0x74d84b77
+0, 86400, 160, 0x1e965711
+0, 87300, 160, 0x7ae45ad7
+0, 88200, 160, 0xf9cd5920
+0, 89100, 160, 0xf0064ea9
+0, 90000, 160, 0xec645244
+0, 90900, 160, 0x8330539a
+0, 91800, 160, 0x4a5d5023
+0, 92700, 160, 0x706153d7
+0, 93600, 160, 0xd6e0520f
+0, 94500, 160, 0x0bd9586f
+0, 95400, 160, 0xc1554dec
+0, 96300, 160, 0x89be4bde
+0, 97200, 160, 0x0c2a49c0
+0, 98100, 160, 0xc18d498a
+0, 99000, 160, 0xc36147e1
+0, 99900, 160, 0x99de4d4b
+0, 100800, 160, 0x2b9d542b
+0, 101700, 160, 0x062b52c9
+0, 102600, 160, 0x9dcf542e
+0, 103500, 160, 0x641f58b9
+0, 104400, 160, 0x114c51ff
+0, 105300, 160, 0x78e04b0e
+0, 106200, 160, 0xfec74535
+0, 107100, 160, 0x71d54cd3
+0, 108000, 160, 0xee9e5289
+0, 108900, 160, 0x142354d9
+0, 109800, 160, 0x051e4ddc
+0, 110700, 160, 0x358146b8
+0, 111600, 160, 0x4dec58eb
+0, 112500, 160, 0xd0944f04
+0, 113400, 160, 0xdc025a99
+0, 114300, 160, 0x6b355402
+0, 115200, 160, 0x1c0b5a6d
+0, 116100, 160, 0xa3b34bc8
+0, 117000, 160, 0x92604eb7
+0, 117900, 160, 0x6f2f5465
+0, 118800, 160, 0xcb565361
+0, 119700, 160, 0x8bfb50a3
+0, 120600, 160, 0xf9114e99
+0, 121500, 160, 0x11065580
+0, 122400, 160, 0x903550c8
+0, 123300, 160, 0xe7aa3da8
+0, 124200, 160, 0x13f34e01
+0, 125100, 160, 0x4c3b4c0a
+0, 126000, 160, 0x08e64c60
+0, 126900, 160, 0xffcd6176
+0, 127800, 160, 0x09684f13
+0, 128700, 160, 0xd8a646b5
+0, 129600, 160, 0xc07355f0
+0, 130500, 160, 0xe836515b
+0, 131400, 160, 0x935741a5
+0, 132300, 160, 0x68f85160
+0, 133200, 160, 0x669a4ed0
+0, 134100, 160, 0xce9f4883
+0, 135000, 160, 0xd94c42de
+0, 135900, 160, 0xf1874b54
+0, 136800, 160, 0x42da46ce
+0, 137700, 160, 0xe99a4da5
+0, 138600, 160, 0x94934f16
+0, 139500, 160, 0x8571437f
+0, 140400, 160, 0xe4774dc2
+0, 141300, 160, 0x743f4f89
+0, 142200, 160, 0x3b3e50ba
+0, 143100, 160, 0x439355e9
+0, 144000, 160, 0x3e4d5178
+0, 144900, 160, 0x64595524
+0, 145800, 160, 0x42d14702
+0, 146700, 160, 0x051e4b1d
+0, 147600, 160, 0x5db84cee
+0, 148500, 160, 0x4d875136
+0, 149400, 160, 0x33b75996
+0, 150300, 160, 0xd5094d76
+0, 151200, 160, 0x6a7052b7
+0, 152100, 160, 0x77264c8f
+0, 153000, 160, 0xcf7e4ccf
+0, 153900, 160, 0x5f7c568b
+0, 154800, 160, 0x8886578b
+0, 155700, 160, 0xd33a4e52
+0, 156600, 160, 0xeefe5c23
+0, 157500, 160, 0xa9c94e38
+0, 158400, 160, 0x67845aa0
+0, 159300, 160, 0xbe91498f
+0, 160200, 160, 0x843d46e3
+0, 161100, 160, 0xbd215999
+0, 162000, 160, 0x1a2e5f2c
+0, 162900, 160, 0x6a344a63
+0, 163800, 160, 0xd80d5743
+0, 164700, 160, 0x80964879
+0, 165600, 160, 0xaafb5e35
+0, 166500, 160, 0x3b855ff3
+0, 167400, 160, 0x770b51d0
+0, 168300, 160, 0x623a5312
+0, 169200, 160, 0x0c235b56
+0, 170100, 160, 0xc8c25724
+0, 171000, 160, 0xb44650e2
+0, 171900, 160, 0xab964d47
+0, 172800, 160, 0x7aa35107
+0, 173700, 160, 0xf12d4780
+0, 174600, 160, 0x77e64f92
+0, 175500, 160, 0x34ee4fa0
+0, 176400, 160, 0x6701466b
+0, 177300, 160, 0xa79d4b4c
+0, 178200, 160, 0xbb7f557b
+0, 179100, 160, 0xaeb253c4
+0, 180000, 160, 0xe7255029
+0, 180900, 160, 0xa5f1505c
+0, 181800, 160, 0x4ae54f09
+0, 182700, 160, 0x6a2b4bc9
+0, 183600, 160, 0xf8724ea5
+0, 184500, 160, 0x4ab35317
+0, 185400, 160, 0xc8d350fb
+0, 186300, 160, 0x73a74994
+0, 187200, 160, 0x9cd1596d
+0, 188100, 160, 0x5ba16005
+0, 189000, 160, 0xb17e4fcc
+0, 189900, 160, 0x8ac958cd
+0, 190800, 160, 0x7919557f
+0, 191700, 160, 0x0be35121
+0, 192600, 160, 0xf8f752f2
+0, 193500, 160, 0xae894d40
+0, 194400, 160, 0x03d94c10
+0, 195300, 160, 0xf12c4917
+0, 196200, 160, 0x3c94534e
+0, 197100, 160, 0x111d51c3
+0, 198000, 160, 0x0a285304
+0, 198900, 160, 0xc3ac4ab1
+0, 199800, 160, 0x5576579d
+0, 200700, 160, 0x9cd04f10
+0, 201600, 160, 0x38a04bf9
+0, 202500, 160, 0xbd0d4d6d
+0, 203400, 160, 0x4db24510
+0, 204300, 160, 0x968753de
+0, 205200, 160, 0x1fa35c67
+0, 206100, 160, 0xc9c048bc
+0, 207000, 160, 0x221d629e
+0, 207900, 160, 0xbb864b0e
+0, 208800, 160, 0xe2964bcd
+0, 209700, 160, 0x20ff4b23
+0, 210600, 160, 0x01dc53e7
+0, 211500, 160, 0x522b56aa
+0, 212400, 160, 0x1e6a495a
+0, 213300, 160, 0x0dcf5731
+0, 214200, 160, 0x241f448d
+0, 215100, 160, 0xdafa55b6
+0, 216000, 160, 0x40584e43
+0, 216900, 160, 0xb73850ab
+0, 217800, 160, 0x7cff593a
+0, 218700, 160, 0x2796515a
+0, 219600, 160, 0x872c5454
+0, 220500, 160, 0xa13058e7
+0, 221400, 160, 0xd8a65261
+0, 222300, 160, 0x48a75601
+0, 223200, 160, 0xb1e7584c
+0, 224100, 160, 0x29cd53fa
+0, 225000, 160, 0xba514d84
+0, 225900, 160, 0x747f4f99
+0, 226800, 160, 0x5819526e
+0, 227700, 160, 0x10185413
+0, 228600, 160, 0x4d084cdc
+0, 229500, 160, 0x8313530b
+0, 230400, 160, 0xd26c5583
+0, 231300, 160, 0x76d749f9
+0, 232200, 160, 0x7cf847a5
+0, 233100, 160, 0xa642590c
+0, 234000, 160, 0x7fef56f2
+0, 234900, 160, 0xf6ea49b9
+0, 235800, 160, 0x6c654e89
+0, 236700, 160, 0x164f56e9
+0, 237600, 160, 0x84cf6139
+0, 238500, 160, 0x20c753ef
+0, 239400, 160, 0x3f3a485f
+0, 240300, 160, 0xee0c5f4b
+0, 241200, 160, 0x706b5313
+0, 242100, 160, 0x47da5af3
+0, 243000, 160, 0x05504b25
+0, 243900, 160, 0x584e59d8
+0, 244800, 160, 0xe9cc4e37
+0, 245700, 160, 0xf33b518a
+0, 246600, 160, 0xb9ac58b7
+0, 247500, 160, 0xed5c57f0
+0, 248400, 160, 0x4cf1579d
+0, 249300, 160, 0x96f94792
+0, 250200, 160, 0x7c455836
+0, 251100, 160, 0xad6652ce
+0, 252000, 160, 0x1ba95cab
+0, 252900, 160, 0xd86755bb
+0, 253800, 160, 0x2f9e51b4
+0, 254700, 160, 0x084e5119
+0, 255600, 160, 0x54ad5449
+0, 256500, 160, 0xff7c5b86
+0, 257400, 160, 0x29a94fff
+0, 258300, 160, 0x679c55ff
+0, 259200, 160, 0x9a415b81
+0, 260100, 160, 0x3ea5528a
+0, 261000, 160, 0x54e15d3f
+0, 261900, 160, 0x122b5c28
+0, 262800, 160, 0xdc0f4e7f
+0, 263700, 160, 0xdc304acd
+0, 264600, 160, 0xe55e5407
+0, 265500, 160, 0x8d07485f
+0, 266400, 160, 0xdc0b5333
+0, 267300, 160, 0xfaed4a90
+0, 268200, 160, 0xb0625538
+0, 269100, 160, 0x1ef3526b
+0, 270000, 160, 0xb48c48e9
+0, 270900, 160, 0x8c945190
+0, 271800, 160, 0x7f9a58b3
+0, 272700, 160, 0x55735499
+0, 273600, 160, 0xeba34a71
+0, 274500, 160, 0xbaa94a6d
+0, 275400, 160, 0x15ab484f
+0, 276300, 160, 0xdc675509
+0, 277200, 160, 0xc2e94f0e
+0, 278100, 160, 0xd7f348ac
+0, 279000, 160, 0x14884e8f
+0, 279900, 160, 0x2d274a97
+0, 280800, 160, 0x578c5834
+0, 281700, 160, 0x12074dab
+0, 282600, 160, 0x74c55067
+0, 283500, 160, 0x7c904e0f
+0, 284400, 160, 0x81d45735
+0, 285300, 160, 0x766f4d71
+0, 286200, 160, 0x9c915273
+0, 287100, 160, 0xf37f4d04
+0, 288000, 160, 0x1ac74d66
+0, 288900, 160, 0xf9b253ab
+0, 289800, 160, 0x6e0c5bb2
+0, 290700, 160, 0x603d629e
+0, 291600, 160, 0xbb674faf
+0, 292500, 160, 0x5d8d51c6
+0, 293400, 160, 0xae7350b9
+0, 294300, 160, 0xfde859ec
+0, 295200, 160, 0x900d50a4
+0, 296100, 160, 0x003551b2
+0, 297000, 160, 0xf8ae4c9d
+0, 297900, 160, 0x66ea508f
+0, 298800, 160, 0xd45b4c51
+0, 299700, 160, 0xb64451a3
+0, 300600, 160, 0x6d2a5621
+0, 301500, 160, 0x71db4d36
+0, 302400, 160, 0x06704647
+0, 303300, 160, 0x1f124cf9
+0, 304200, 160, 0x10d14b46
+0, 305100, 160, 0x421b59d8
+0, 306000, 160, 0x84ba4cae
+0, 306900, 160, 0x4fba48e1
+0, 307800, 160, 0xec294a6b
+0, 308700, 160, 0x2f1752a7
+0, 309600, 160, 0x8d665570
+0, 310500, 160, 0x586e537d
+0, 311400, 160, 0x18d54a49
+0, 312300, 160, 0xa895566d
+0, 313200, 160, 0xb9b35255
+0, 314100, 160, 0x2e194e1f
+0, 315000, 160, 0x4810594b
+0, 315900, 160, 0xb82557ee
+0, 316800, 160, 0x35d84d67
+0, 317700, 160, 0x5ee95128
+0, 318600, 160, 0x24f05747
+0, 319500, 160, 0x434d53f6
+0, 320400, 160, 0x3c894f3e
+0, 321300, 160, 0x81c34896
+0, 322200, 160, 0x7540543c
+0, 323100, 160, 0x35bc5504
+0, 324000, 160, 0x546943dc
+0, 324900, 160, 0x084d46e9
+0, 325800, 160, 0x983852ba
+0, 326700, 160, 0xefac4e15
+0, 327600, 160, 0xc9294430
+0, 328500, 160, 0xe9e74de1
+0, 329400, 160, 0x4ca1516a
+0, 330300, 160, 0x44014ceb
+0, 331200, 160, 0x1dbc5ad1
+0, 332100, 160, 0x98be4efd
+0, 333000, 160, 0x2dc75c7a
+0, 333900, 160, 0x46275852
+0, 334800, 160, 0x61c15d30
+0, 335700, 160, 0x1f605adc
+0, 336600, 160, 0xf08659ac
+0, 337500, 160, 0xb7656021
+0, 338400, 160, 0x1f4a5a72
+0, 339300, 160, 0xf8175275
+0, 340200, 160, 0xbbf4564d
+0, 341100, 160, 0x6fdc5a7d
+0, 342000, 160, 0x082f5250
+0, 342900, 160, 0x84cb55b5
+0, 343800, 160, 0x0e1a51ba
+0, 344700, 160, 0xa84e52fc
+0, 345600, 160, 0xcb5a55c9
+0, 346500, 160, 0x9ce6570d
+0, 347400, 160, 0x82b253cc
+0, 348300, 160, 0x34c4594b
+0, 349200, 160, 0xff5c5854
+0, 350100, 160, 0xd5da4ea0
+0, 351000, 160, 0xc86e5553
+0, 351900, 160, 0x7ecb55c6
+0, 352800, 160, 0xb08b5338
+0, 353700, 160, 0xd601573c
+0, 354600, 160, 0x93305092
+0, 355500, 160, 0x352d4912
+0, 356400, 160, 0xddba4d29
+0, 357300, 160, 0xc79c50b7
+0, 358200, 160, 0xe67d4e8e
+0, 359100, 160, 0xdbfd4bbc
+0, 360000, 160, 0xb2f746fb
+0, 360900, 160, 0x835b5539
+0, 361800, 160, 0x612049e9
+0, 362700, 160, 0x91a6503c
+0, 363600, 160, 0x762e4f0e
+0, 364500, 160, 0x2b2153f9
+0, 365400, 160, 0xdcfe5804
+0, 366300, 160, 0x79144cae
+0, 367200, 160, 0xd6394d99
+0, 368100, 160, 0x22395292
+0, 369000, 160, 0x50b04fa0
+0, 369900, 160, 0x846b49a5
+0, 370800, 160, 0x1f554dff
+0, 371700, 160, 0x0aa458dd
+0, 372600, 160, 0x62154dde
+0, 373500, 160, 0xe69847ac
+0, 374400, 160, 0x75855425
+0, 375300, 160, 0x49125665
+0, 376200, 160, 0xa8605945
+0, 377100, 160, 0xc02a5083
+0, 378000, 160, 0x6198537c
+0, 378900, 160, 0x90f25711
+0, 379800, 160, 0x32da51f1
+0, 380700, 160, 0x96c3474d
+0, 381600, 160, 0x82ae4579
+0, 382500, 160, 0xbabf5919
+0, 383400, 160, 0x78095772
+0, 384300, 160, 0x46964abb
+0, 385200, 160, 0x5fcb5ba3
+0, 386100, 160, 0x4a775585
+0, 387000, 160, 0xc41f53af
+0, 387900, 160, 0x457251bc
+0, 388800, 160, 0x8f864fb3
+0, 389700, 160, 0x439d526c
+0, 390600, 160, 0x5cf6503f
+0, 391500, 160, 0x90b7534f
+0, 392400, 160, 0xecc45253
+0, 393300, 160, 0x533b4ee3
+0, 394200, 160, 0x4cc44f27
+0, 395100, 160, 0x6ff35096
+0, 396000, 160, 0x141e4a80
+0, 396900, 160, 0x9e075461
+0, 397800, 160, 0xc4b55791
+0, 398700, 160, 0x40955666
+0, 399600, 160, 0x6255462f
+0, 400500, 160, 0x2cec55d6
+0, 401400, 160, 0xd71652e9
+0, 402300, 160, 0xe65e530c
+0, 403200, 160, 0xeeb9556d
+0, 404100, 160, 0x558f523e
+0, 405000, 160, 0x76e14b00
+0, 405900, 160, 0x3f9f4e9b
+0, 406800, 160, 0x0d7b492a
+0, 407700, 160, 0xdd6e51bd
+0, 408600, 160, 0x5ab353b9
+0, 409500, 160, 0x5b934f33
+0, 410400, 160, 0x36bb57a0
+0, 411300, 160, 0x455d54d3
+0, 412200, 160, 0x7e6853d7
+0, 413100, 160, 0xdcb85ed4
+0, 414000, 160, 0x3a8d5860
+0, 414900, 160, 0x5c90558f
+0, 415800, 160, 0x25504d46
+0, 416700, 160, 0x0fc55413
+0, 417600, 160, 0x98545409
+0, 418500, 160, 0x963b550e
+0, 419400, 160, 0x544a569c
+0, 420300, 160, 0x7ab65f77
+0, 421200, 160, 0x14c257e2
+0, 422100, 160, 0x6cac6262
+0, 423000, 160, 0x2f7f5091
+0, 423900, 160, 0xc2655462
+0, 424800, 160, 0xbb4b4744
+0, 425700, 160, 0x4c5f54db
+0, 426600, 160, 0x9e694ab5
+0, 427500, 160, 0xc2c95173
+0, 428400, 160, 0xf4ae553f
+0, 429300, 160, 0xb4c04ed1
+0, 430200, 160, 0xf3095128
+0, 431100, 160, 0x73b04de1
+0, 432000, 160, 0xff4951c7
+0, 432900, 160, 0x28c156bd
+0, 433800, 160, 0x17b652aa
+0, 434700, 160, 0xb9ce528b
+0, 435600, 160, 0x3cc558be
+0, 436500, 160, 0xdf385905
+0, 437400, 160, 0xe2de4fe2
+0, 438300, 160, 0xc2a6582d
+0, 439200, 160, 0xe5715bc9
+0, 440100, 160, 0x741b6416
+0, 441000, 160, 0xf9b1544f
+0, 441900, 160, 0x012e5f01
+0, 442800, 160, 0x5ab65a49
+0, 443700, 160, 0xfe1e5b1a
+0, 444600, 160, 0x370056ef
+0, 445500, 160, 0xfde45ed4
+0, 446400, 160, 0xa34f6053
+0, 447300, 160, 0x31755604
+0, 448200, 160, 0xc3415bfe
+0, 449100, 160, 0xe5dd5b58
+0, 450000, 160, 0xb6cf5295
+0, 450900, 160, 0x3d81538b
+0, 451800, 160, 0xc00255d2
+0, 452700, 160, 0xb0714f71
+0, 453600, 160, 0x9c9756ac
+0, 454500, 160, 0x4de053a0
+0, 455400, 160, 0x6706500c
+0, 456300, 160, 0x34e4511d
+0, 457200, 160, 0xe4224e3e
+0, 458100, 160, 0xdf695529
+0, 459000, 160, 0xeb1f54e0
+0, 459900, 160, 0x2870550e
+0, 460800, 160, 0x08465464
+0, 461700, 160, 0xe34150e6
+0, 462600, 160, 0xb77556e0
+0, 463500, 160, 0xb23e46ab
+0, 464400, 160, 0x83884a7b
+0, 465300, 160, 0xa0284b16
+0, 466200, 160, 0x87b749e1
+0, 467100, 160, 0x4b276444
+0, 468000, 160, 0x92f95091
+0, 468900, 160, 0x2b1056c2
+0, 469800, 160, 0xd5d5590a
+0, 470700, 160, 0x5a454fac
+0, 471600, 160, 0x0ab05b13
+0, 472500, 160, 0xd98e56ca
+0, 473400, 160, 0x183d5892
+0, 474300, 160, 0x8ba951e4
+0, 475200, 160, 0x487054ff
+0, 476100, 160, 0xc0d05562
+0, 477000, 160, 0x166c590f
+0, 477900, 160, 0x3e254cc0
+0, 478800, 160, 0xd2784ab4
+0, 479700, 160, 0x9f7b4ef6
+0, 480600, 160, 0xdd7653b6
+0, 481500, 160, 0x7ae453b7
+0, 482400, 160, 0xff6c50ec
+0, 483300, 160, 0xfa0d51a9
+0, 484200, 160, 0x29ab583b
+0, 485100, 160, 0x671d5437
+0, 486000, 160, 0x6867569f
+0, 486900, 160, 0xdd775e05
+0, 487800, 160, 0xbafa65ed
+0, 488700, 160, 0xd33f5aea
+0, 489600, 160, 0x851455a8
+0, 490500, 160, 0x044c4d45
+0, 491400, 160, 0xcd7c5d84
+0, 492300, 160, 0xd6565e61
+0, 493200, 160, 0x2f345a92
+0, 494100, 160, 0x50e05530
+0, 495000, 160, 0x787f516a
+0, 495900, 160, 0x75cd5ade
+0, 496800, 160, 0x55b558ad
+0, 497700, 160, 0x55255b01
+0, 498600, 160, 0xfc5b5945
+0, 499500, 160, 0x33914e05
+0, 500400, 160, 0x1f4a5c31
+0, 501300, 160, 0x542f4bf2
+0, 502200, 160, 0xd8b2573f
+0, 503100, 160, 0x127758b0
+0, 504000, 160, 0x18dd5a30
+0, 504900, 160, 0xe8ce61c4
+0, 505800, 160, 0x9a225b47
+0, 506700, 160, 0xd4436314
+0, 507600, 160, 0x2bf06310
+0, 508500, 160, 0x0de35e82
+0, 509400, 160, 0x76cb56f2
+0, 510300, 160, 0x65bc569b
+0, 511200, 160, 0x00a45461
+0, 512100, 160, 0xb5c55019
+0, 513000, 160, 0x5eb04b4d
+0, 513900, 160, 0xf1224c39
+0, 514800, 160, 0x4d135288
+0, 515700, 160, 0x9bc34ba7
+0, 516600, 160, 0xbde3510e
+0, 517500, 160, 0xefaf4fa4
+0, 518400, 160, 0x584950e2
+0, 519300, 160, 0x1e844e27
+0, 520200, 160, 0x38634315
+0, 521100, 160, 0x6b9b4a0b
+0, 522000, 160, 0xd491512a
+0, 522900, 160, 0x8624478c
+0, 523800, 160, 0x67ab45c7
+0, 524700, 160, 0xf78e4c53
+0, 525600, 160, 0xb1654f0d
+0, 526500, 160, 0x17bb4e96
+0, 527400, 160, 0xf3165e7c
+0, 528300, 160, 0xf7914633
+0, 529200, 160, 0x3421530f
+0, 530100, 160, 0x492e572c
+0, 531000, 160, 0xa3185319
+0, 531900, 160, 0x92d054c0
+0, 532800, 160, 0x1cc24ce1
+0, 533700, 160, 0x2ebc519e
+0, 534600, 160, 0x946b53e7
+0, 535500, 160, 0xf85c4fe6
+0, 536400, 160, 0x2974534c
+0, 537300, 160, 0xef7e4a28
+0, 538200, 160, 0x01a74c6e
+0, 539100, 160, 0x2a865674
+0, 540000, 160, 0x70474faf
+0, 540900, 160, 0x2df75014
+0, 541800, 160, 0xf1f3574e
+0, 542700, 160, 0x741b5308
+0, 543600, 160, 0xcb34513e
+0, 544500, 160, 0x7b5e50c7
+0, 545400, 160, 0x0165553b
+0, 546300, 160, 0x04b85450
+0, 547200, 160, 0x795d5873
+0, 548100, 160, 0x508859fb
+0, 549000, 160, 0xca09587d
+0, 549900, 160, 0x86a65ac8
+0, 550800, 160, 0x447353fe
+0, 551700, 160, 0x48ca54a5
+0, 552600, 160, 0x1b3e5f3e
+0, 553500, 160, 0x270a5aa2
+0, 554400, 160, 0x48a45c29
+0, 555300, 160, 0xfbf75a0b
+0, 556200, 160, 0xe65161e5
+0, 557100, 160, 0xf47c6701
+0, 558000, 160, 0xc12058bc
+0, 558900, 160, 0xdb17520c
+0, 559800, 160, 0x860455bd
+0, 560700, 160, 0xa02d56de
+0, 561600, 160, 0xf5574c7d
+0, 562500, 160, 0x500e59b3
+0, 563400, 160, 0xf0b75894
+0, 564300, 160, 0x9d454a04
+0, 565200, 160, 0x0b0554a4
+0, 566100, 160, 0x3fc34d98
+0, 567000, 160, 0x538550b8
+0, 567900, 160, 0xd84e495e
+0, 568800, 160, 0x736c4e17
+0, 569700, 160, 0xa59e5607
+0, 570600, 160, 0xe7485609
+0, 571500, 160, 0x20185a67
+0, 572400, 160, 0x9aa5576f
+0, 573300, 160, 0xed8c5d11
+0, 574200, 160, 0xecef5494
+0, 575100, 160, 0x76f75a5c
+0, 576000, 160, 0xa8fa5322
+0, 576900, 160, 0xd1945734
+0, 577800, 160, 0x817f5c82
+0, 578700, 160, 0x40756063
+0, 579600, 160, 0x524454c7
+0, 580500, 160, 0x5a776106
+0, 581400, 160, 0xd16e5d9d
+0, 582300, 160, 0x8522524c
+0, 583200, 160, 0x4a115bb9
+0, 584100, 160, 0xbf5c5c27
+0, 585000, 160, 0x48905da4
+0, 585900, 160, 0x58735040
+0, 586800, 160, 0x48635631
+0, 587700, 160, 0xf1305eaf
+0, 588600, 160, 0xd34451bd
+0, 589500, 160, 0x1a244fcf
+0, 590400, 160, 0xdb995ca0
+0, 591300, 160, 0xe38e52bb
+0, 592200, 160, 0x00715069
+0, 593100, 160, 0x72a95190
+0, 594000, 160, 0xea7d50b7
+0, 594900, 160, 0xb4094a9c
+0, 595800, 160, 0xd5284d79
+0, 596700, 160, 0x3c4349e5
+0, 597600, 160, 0x65d34e92
+0, 598500, 160, 0x67805756
+0, 599400, 160, 0x1b96502f
+0, 600300, 160, 0x395250ae
+0, 601200, 160, 0x4dc74976
+0, 602100, 160, 0x2666486e
+0, 603000, 160, 0x41924d01
+0, 603900, 160, 0x94a845f5
+0, 604800, 160, 0x1b264cf9
+0, 605700, 160, 0x63ea4aab
+0, 606600, 160, 0x9c0d4a82
+0, 607500, 160, 0x02ba4cf6
+0, 608400, 160, 0x9cd54b87
+0, 609300, 160, 0x24624c5b
+0, 610200, 160, 0x14cf54b1
+0, 611100, 160, 0xce54544b
+0, 612000, 160, 0x459b4fc9
+0, 612900, 160, 0xcc2453f1
+0, 613800, 160, 0xa4ab53bc
+0, 614700, 160, 0x92235013
+0, 615600, 160, 0xbfa257b3
+0, 616500, 160, 0xd32d51f5
+0, 617400, 160, 0x7d5d47e6
+0, 618300, 160, 0xe23d43ed
+0, 619200, 160, 0x51d8514f
+0, 620100, 160, 0x0fa04240
+0, 621000, 160, 0x233c4dce
+0, 621900, 160, 0xcd30466f
+0, 622800, 160, 0x4435546a
+0, 623700, 160, 0x3eb6445b
+0, 624600, 160, 0xcaed4ef9
+0, 625500, 160, 0xf0174da8
+0, 626400, 160, 0x60e756a0
+0, 627300, 160, 0x72ba457d
+0, 628200, 160, 0x84ce4f0f
+0, 629100, 160, 0x660d45ae
+0, 630000, 160, 0xac8446e2
+0, 630900, 160, 0xeeb153b4
+0, 631800, 160, 0x6a634c23
+0, 632700, 160, 0x890f4af8
+0, 633600, 160, 0x1d3743a7
+0, 634500, 160, 0xa37e4ee8
+0, 635400, 160, 0xb9334d56
+0, 636300, 160, 0xc1384bef
+0, 637200, 160, 0x52964f6e
+0, 638100, 160, 0xe36e57e2
+0, 639000, 160, 0x62114a53
+0, 639900, 160, 0xb1f855bb
+0, 640800, 160, 0xf0934da0
+0, 641700, 160, 0xb454494a
+0, 642600, 160, 0xb6e04b15
+0, 643500, 160, 0x933e488e
+0, 644400, 160, 0x762d5ce8
+0, 645300, 160, 0x1c4a4f85
+0, 646200, 160, 0xaaa25313
+0, 647100, 160, 0xd3655979
+0, 648000, 160, 0x8ff149e5
+0, 648900, 160, 0x5d5e51fb
+0, 649800, 160, 0x0a354c51
+0, 650700, 160, 0x79ea52ee
+0, 651600, 160, 0x306e5365
+0, 652500, 160, 0x7e03546a
+0, 653400, 160, 0x71575ddf
+0, 654300, 160, 0x08da523d
+0, 655200, 160, 0x2a2152b2
+0, 656100, 160, 0x50e55447
+0, 657000, 160, 0xf3b55758
+0, 657900, 160, 0xc29d5f12
+0, 658800, 160, 0x0c0b5778
+0, 659700, 160, 0x1b07593a
+0, 660600, 160, 0x946f562d
+0, 661500, 160, 0xcdc85636
+0, 662400, 160, 0x2421589b
+0, 663300, 160, 0x8e3b5451
+0, 664200, 160, 0xd565536a
+0, 665100, 160, 0x8d225557
+0, 666000, 160, 0xa0084e44
+0, 666900, 160, 0x85bd5413
+0, 667800, 160, 0xa4be4c3b
+0, 668700, 160, 0x332957c8
+0, 669600, 160, 0x60505225
+0, 670500, 160, 0x3d154eb3
+0, 671400, 160, 0xd85359f4
+0, 672300, 160, 0xf95b4f6b
+0, 673200, 160, 0x8bea5846
+0, 674100, 160, 0x43835a02
+0, 675000, 160, 0x340b5732
+0, 675900, 160, 0x8b6d5005
+0, 676800, 160, 0xa4995aca
+0, 677700, 160, 0x88d34efc
+0, 678600, 160, 0x078e5003
+0, 679500, 160, 0x09964b19
+0, 680400, 160, 0x2eaf5120
+0, 681300, 160, 0x52514d52
+0, 682200, 160, 0x08f84d4c
+0, 683100, 160, 0x4a9b4cc7
+0, 684000, 160, 0x947f4ca6
+0, 684900, 160, 0x086a4f32
+0, 685800, 160, 0x0e0857a6
+0, 686700, 160, 0x38145bf7
+0, 687600, 160, 0xc6e156bf
+0, 688500, 160, 0xb07853b2
+0, 689400, 160, 0xaeda5172
+0, 690300, 160, 0xc4e54d07
+0, 691200, 160, 0x0b075a61
+0, 692100, 160, 0x09f05c1f
+0, 693000, 160, 0xf5415796
+0, 693900, 160, 0xe3be584e
+0, 694800, 160, 0x6e1656f9
+0, 695700, 160, 0xd6d85599
+0, 696600, 160, 0xd9b4502e
+0, 697500, 160, 0x1186598c
+0, 698400, 160, 0x879c543d
+0, 699300, 160, 0x5b2551a3
+0, 700200, 160, 0xcf50528d
+0, 701100, 160, 0x95d059b2
+0, 702000, 160, 0x34ba5515
+0, 702900, 160, 0x7a014ba8
+0, 703800, 160, 0x27725169
+0, 704700, 160, 0x2fd14ca4
+0, 705600, 160, 0xd5ad542a
+0, 706500, 160, 0xddc24d2e
+0, 707400, 160, 0x8a4b48b4
+0, 708300, 160, 0x915e4a29
+0, 709200, 160, 0xd56d4cae
+0, 710100, 160, 0x59594eea
+0, 711000, 160, 0x87085338
+0, 711900, 160, 0xa5ee538f
+0, 712800, 160, 0xf34e5030
+0, 713700, 160, 0x6bef4da7
+0, 714600, 160, 0x05a14c52
+0, 715500, 160, 0x67bc49ce
+0, 716400, 160, 0xb18f4cff
+0, 717300, 160, 0x5d744e6d
+0, 718200, 160, 0xcb7c5973
+0, 719100, 160, 0x6df056f0
+0, 720000, 160, 0xd62c4e00
+0, 720900, 160, 0xa54d4d1e
+0, 721800, 160, 0xdaa250b0
+0, 722700, 160, 0x350e475f
+0, 723600, 160, 0x0e454bb2
+0, 724500, 160, 0xe37949ca
+0, 725400, 160, 0x551453bf
+0, 726300, 160, 0x35d04c27
+0, 727200, 160, 0x6749469d
+0, 728100, 160, 0x544752e9
+0, 729000, 160, 0xf23b4888
+0, 729900, 160, 0x6f0a5519
+0, 730800, 160, 0x808a58df
+0, 731700, 160, 0x8e674c88
+0, 732600, 160, 0xd3ab51f7
+0, 733500, 160, 0x985d500f
+0, 734400, 160, 0x734e52d8
+0, 735300, 160, 0xb0da5227
+0, 736200, 160, 0xcc7d4a21
+0, 737100, 160, 0xb1354baf
+0, 738000, 160, 0xfc8d4f9a
+0, 738900, 160, 0x6f044d82
+0, 739800, 160, 0x41e7546b
+0, 740700, 160, 0x67014682
+0, 741600, 160, 0x5516575b
+0, 742500, 160, 0x26254693
+0, 743400, 160, 0x81ce4af5
+0, 744300, 160, 0x77f152a0
+0, 745200, 160, 0x995a5096
+0, 746100, 160, 0x6114532e
+0, 747000, 160, 0x4df457f3
+0, 747900, 160, 0xbcd94804
+0, 748800, 160, 0x1e544fd2
+0, 749700, 160, 0xa70b5954
+0, 750600, 160, 0x1c77484c
+0, 751500, 160, 0xb07f4c42
+0, 752400, 160, 0x62074f1f
+0, 753300, 160, 0xf3b656a1
+0, 754200, 160, 0x65734ac0
+0, 755100, 160, 0x2a9752cd
+0, 756000, 160, 0x15ff4ef0
+0, 756900, 160, 0xabd4532c
+0, 757800, 160, 0x8a44503a
+0, 758700, 160, 0xbf4250f3
+0, 759600, 160, 0x17594ac5
+0, 760500, 160, 0x7b5e4b24
+0, 761400, 160, 0x24684cb5
+0, 762300, 160, 0xc4d54b42
+0, 763200, 160, 0xd48f58af
+0, 764100, 160, 0x0374593a
+0, 765000, 160, 0x398a5b0d
+0, 765900, 160, 0xf60855e6
+0, 766800, 160, 0x6fbb5587
+0, 767700, 160, 0x44405c2b
+0, 768600, 160, 0xa6345d70
+0, 769500, 160, 0x464557d5
+0, 770400, 160, 0x0c3153ca
+0, 771300, 160, 0x15ec50c4
+0, 772200, 160, 0xd5e559da
+0, 773100, 160, 0x999757b9
+0, 774000, 160, 0x7a5d5754
+0, 774900, 160, 0xf85b5f18
+0, 775800, 160, 0xa66d5c72
+0, 776700, 160, 0xd8f55981
+0, 777600, 160, 0xe6364f64
+0, 778500, 160, 0x528a5785
+0, 779400, 160, 0xdefe5332
+0, 780300, 160, 0x4bc4532e
+0, 781200, 160, 0x505a4eb3
+0, 782100, 160, 0xa28d589d
+0, 783000, 160, 0x092d511f
+0, 783900, 160, 0x3079591e
+0, 784800, 160, 0x2b1d5339
+0, 785700, 160, 0xf8d849d1
+0, 786600, 160, 0xadb056a6
+0, 787500, 160, 0x2ee74c4f
+0, 788400, 160, 0x35c34c9f
+0, 789300, 160, 0xb6ae53d3
+0, 790200, 160, 0x7258534e
+0, 791100, 160, 0xb76d4b1b
+0, 792000, 160, 0x99a14a0f
+0, 792900, 160, 0x88365944
+0, 793800, 160, 0x97cf4aed
+0, 794700, 160, 0x444b56f6
+0, 795600, 160, 0x1d1f4b01
+0, 796500, 160, 0x3dcd417e
+0, 797400, 160, 0xa4985140
+0, 798300, 160, 0x86f94c4d
+0, 799200, 160, 0xc3635436
+0, 800100, 160, 0x198b432b
+0, 801000, 160, 0xae5253e4
+0, 801900, 160, 0x248c4f1a
+0, 802800, 160, 0x787a45df
+0, 803700, 160, 0x5fd44cad
+0, 804600, 160, 0x68be581c
+0, 805500, 160, 0x5ff5531b
+0, 806400, 160, 0x2bcd4aa1
+0, 807300, 160, 0x0d134a7c
+0, 808200, 160, 0x28af5885
+0, 809100, 160, 0xc09f4d65
+0, 810000, 160, 0x7468552d
+0, 810900, 160, 0x82df49ac
+0, 811800, 160, 0xe3725fdc
+0, 812700, 160, 0x0ec74d11
+0, 813600, 160, 0xfc2a5355
+0, 814500, 160, 0x41df4d4f
+0, 815400, 160, 0x4ebe473d
+0, 816300, 160, 0xd8734bf2
+0, 817200, 160, 0x4acd5056
+0, 818100, 160, 0x47805700
+0, 819000, 160, 0xe4f25135
+0, 819900, 160, 0x9f195649
+0, 820800, 160, 0x8b055f64
+0, 821700, 160, 0xc4b751c8
+0, 822600, 160, 0x95e55ba4
+0, 823500, 160, 0xf0955494
+0, 824400, 160, 0xca1a47b9
+0, 825300, 160, 0x9d025711
+0, 826200, 160, 0xf6cb4a0a
+0, 827100, 160, 0xd8385b4d
+0, 828000, 160, 0x7b2852b6
+0, 828900, 160, 0x90a35643
+0, 829800, 160, 0x63105d0a
+0, 830700, 160, 0x55414083
+0, 831600, 160, 0xc94554a9
+0, 832500, 160, 0xa88f4a36
+0, 833400, 160, 0xda5d52bc
+0, 834300, 160, 0x5b3943da
+0, 835200, 160, 0xd2314755
+0, 836100, 160, 0x743c4cdc
+0, 837000, 160, 0x7c3e4dc2
+0, 837900, 160, 0x12644715
+0, 838800, 160, 0x1050480b
+0, 839700, 160, 0x73645906
+0, 840600, 160, 0x28ef4a9e
+0, 841500, 160, 0xf72440bc
+0, 842400, 160, 0x41964bda
+0, 843300, 160, 0x2afb4d9b
+0, 844200, 160, 0xf74b4c5a
+0, 845100, 160, 0xcf165e2e
+0, 846000, 160, 0x3dbb4d06
+0, 846900, 160, 0xbd9755f9
+0, 847800, 160, 0x3248581d
+0, 848700, 160, 0xc00c559d
+0, 849600, 160, 0xff6c4b0a
+0, 850500, 160, 0x154157e3
+0, 851400, 160, 0xb996499c
+0, 852300, 160, 0xe1a059ba
+0, 853200, 160, 0x98015946
+0, 854100, 160, 0x168b4ceb
+0, 855000, 160, 0x567b4f83
+0, 855900, 160, 0x903e52f8
+0, 856800, 160, 0xc0a252dc
+0, 857700, 160, 0x08cb4b70
+0, 858600, 160, 0x3d9a5be6
+0, 859500, 160, 0x904b4907
+0, 860400, 160, 0x738847b1
+0, 861300, 160, 0x10405c19
+0, 862200, 160, 0x8c134f27
+0, 863100, 160, 0xdfe34d7f
+0, 864000, 160, 0x9d0948a8
+0, 864900, 160, 0x67755611
+0, 865800, 160, 0x46734258
+0, 866700, 160, 0x76f449fa
+0, 867600, 160, 0xfad64d30
+0, 868500, 160, 0x7f4357f4
+0, 869400, 160, 0xd20e5079
+0, 870300, 160, 0xdf7857ec
+0, 871200, 160, 0x46ff4891
+0, 872100, 160, 0x1b724ffc
+0, 873000, 160, 0xdf20545a
+0, 873900, 160, 0xeb5254e0
+0, 874800, 160, 0x794b4a96
+0, 875700, 160, 0x86a15147
+0, 876600, 160, 0x30f75504
+0, 877500, 160, 0x39575354
+0, 878400, 160, 0xb6a35351
+0, 879300, 160, 0x9da34c3a
+0, 880200, 160, 0xcf2d5386
+0, 881100, 160, 0xa7f353f6
+0, 882000, 160, 0xa6e34e95
+0, 882900, 160, 0x98174400
+0, 883800, 160, 0x13685641
+0, 884700, 160, 0x99215154
+0, 885600, 160, 0x5be75237
+0, 886500, 160, 0x4cb64942
+0, 887400, 160, 0x15de4e03
+0, 888300, 160, 0x613a4fd5
+0, 889200, 160, 0xc97c4821
+0, 890100, 160, 0xbf1558f2
+0, 891000, 160, 0x651d4cf4
+0, 891900, 160, 0xbee44a56
+0, 892800, 160, 0x6cbd4c20
+0, 893700, 160, 0xcf45493d
+0, 894600, 160, 0x73e74d2a
+0, 895500, 160, 0x6a3256e4
+0, 896400, 160, 0x89ac4a68
+0, 897300, 160, 0x0d2652aa
+0, 898200, 160, 0x56ce4b78
+0, 899100, 160, 0xb7b24bcb
diff --git a/tests/ref/fate/h264-conformance-frext-hi422fr10_sony_b b/tests/ref/fate/h264-conformance-frext-hi422fr10_sony_b
new file mode 100644
index 0000000..244e546
--- /dev/null
+++ b/tests/ref/fate/h264-conformance-frext-hi422fr10_sony_b
@@ -0,0 +1,6 @@
+#tb 0: 1/25
+0,          0,          0,        1,   202752, 0xffa1c502
+0,          1,          1,        1,   202752, 0x51752f3c
+0,          2,          2,        1,   202752, 0xe683991d
+0,          3,          3,        1,   202752, 0xf70200a4
+0,          4,          4,        1,   202752, 0x1a4d63ef
diff --git a/tests/ref/fate/h264-conformance-frext-hi422fr13_sony_b b/tests/ref/fate/h264-conformance-frext-hi422fr13_sony_b
new file mode 100644
index 0000000..016abbc
--- /dev/null
+++ b/tests/ref/fate/h264-conformance-frext-hi422fr13_sony_b
@@ -0,0 +1,6 @@
+#tb 0: 1/25
+0,          0,          0,        1,   405504, 0xe0f40e71
+0,          1,          1,        1,   405504, 0x9bdb5900
+0,          2,          2,        1,   405504, 0x527003ca
+0,          3,          3,        1,   405504, 0x1fbf8ba6
+0,          4,          4,        1,   405504, 0x455e2a4e
diff --git a/tests/ref/fate/h264-conformance-frext-hi422fr1_sony_a b/tests/ref/fate/h264-conformance-frext-hi422fr1_sony_a
new file mode 100644
index 0000000..93a3aa4
--- /dev/null
+++ b/tests/ref/fate/h264-conformance-frext-hi422fr1_sony_a
@@ -0,0 +1,6 @@
+#tb 0: 1/25
+0,          0,          0,        1,   202752, 0xd5a1e49f
+0,          1,          1,        1,   202752, 0x08352d61
+0,          2,          2,        1,   202752, 0x43f78f47
+0,          3,          3,        1,   202752, 0xfb5910f4
+0,          4,          4,        1,   202752, 0xd98e8739
diff --git a/tests/ref/fate/h264-conformance-frext-hi422fr6_sony_a b/tests/ref/fate/h264-conformance-frext-hi422fr6_sony_a
new file mode 100644
index 0000000..4141eee
--- /dev/null
+++ b/tests/ref/fate/h264-conformance-frext-hi422fr6_sony_a
@@ -0,0 +1,6 @@
+#tb 0: 1/25
+0,          0,          0,        1,   405504, 0x049ab58e
+0,          1,          1,        1,   405504, 0x4f6226cb
+0,          2,          2,        1,   405504, 0xaa5fcb44
+0,          3,          3,        1,   405504, 0xbfc09965
+0,          4,          4,        1,   405504, 0xa30acb90
diff --git a/tests/ref/fate/h264-conformance-frext-pph422i1_panasonic_a b/tests/ref/fate/h264-conformance-frext-pph422i1_panasonic_a
new file mode 100644
index 0000000..0957654
--- /dev/null
+++ b/tests/ref/fate/h264-conformance-frext-pph422i1_panasonic_a
@@ -0,0 +1,11 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3686400, 0x1f9b5bee
+0,          1,          1,        1,  3686400, 0x657c3609
+0,          2,          2,        1,  3686400, 0x75753934
+0,          3,          3,        1,  3686400, 0xf434d8e1
+0,          4,          4,        1,  3686400, 0x40679c77
+0,          5,          5,        1,  3686400, 0x5734d8db
+0,          6,          6,        1,  3686400, 0x4a3d8269
+0,          7,          7,        1,  3686400, 0xd20b6cf6
+0,          8,          8,        1,  3686400, 0x31956bca
+0,          9,          9,        1,  3686400, 0xd28d9758
diff --git a/tests/ref/fate/h264-conformance-frext-pph422i2_panasonic_a b/tests/ref/fate/h264-conformance-frext-pph422i2_panasonic_a
new file mode 100644
index 0000000..79e69eb
--- /dev/null
+++ b/tests/ref/fate/h264-conformance-frext-pph422i2_panasonic_a
@@ -0,0 +1,11 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3686400, 0x8b3ff360
+0,          1,          1,        1,  3686400, 0x422dead1
+0,          2,          2,        1,  3686400, 0xbdd0e431
+0,          3,          3,        1,  3686400, 0x1e3cc216
+0,          4,          4,        1,  3686400, 0x1a80b718
+0,          5,          5,        1,  3686400, 0xc7e3c0a2
+0,          6,          6,        1,  3686400, 0xffc99142
+0,          7,          7,        1,  3686400, 0x8b3bdf1e
+0,          8,          8,        1,  3686400, 0xff1bccfb
+0,          9,          9,        1,  3686400, 0x781fc45b
diff --git a/tests/ref/fate/h264-conformance-frext-pph422i3_panasonic_a b/tests/ref/fate/h264-conformance-frext-pph422i3_panasonic_a
new file mode 100644
index 0000000..fc4cc50
--- /dev/null
+++ b/tests/ref/fate/h264-conformance-frext-pph422i3_panasonic_a
@@ -0,0 +1,11 @@
+#tb 0: 1/25
+0,          0,          0,        1,  3686400, 0x97c36ae3
+0,          1,          1,        1,  3686400, 0x6a0aa629
+0,          2,          2,        1,  3686400, 0xc658d722
+0,          3,          3,        1,  3686400, 0x713bc774
+0,          4,          4,        1,  3686400, 0x8d0b3afe
+0,          5,          5,        1,  3686400, 0x62bf24cd
+0,          6,          6,        1,  3686400, 0x77e80436
+0,          7,          7,        1,  3686400, 0x4f258e07
+0,          8,          8,        1,  3686400, 0x8426bc53
+0,          9,          9,        1,  3686400, 0xd33b58c8
diff --git a/tests/ref/fate/h264-conformance-frext-pph422i4_panasonic_a b/tests/ref/fate/h264-conformance-frext-pph422i4_panasonic_a
new file mode 100644
index 0000000..0aae9fe
--- /dev/null
+++ b/tests/ref/fate/h264-conformance-frext-pph422i4_panasonic_a
@@ -0,0 +1,11 @@
+#tb 0: 1/25
+0,          0,          0,        1,  8294400, 0xf50992f3
+0,          1,          1,        1,  8294400, 0xd34cdf98
+0,          2,          2,        1,  8294400, 0x76bced00
+0,          3,          3,        1,  8294400, 0xf9ffd9b1
+0,          4,          4,        1,  8294400, 0x303231aa
+0,          5,          5,        1,  8294400, 0x0ca57c6a
+0,          6,          6,        1,  8294400, 0xaa056bd5
+0,          7,          7,        1,  8294400, 0x785c9a12
+0,          8,          8,        1,  8294400, 0xe535750e
+0,          9,          9,        1,  8294400, 0x78fd76bb
diff --git a/tests/ref/fate/h264-conformance-frext-pph422i5_panasonic_a b/tests/ref/fate/h264-conformance-frext-pph422i5_panasonic_a
new file mode 100644
index 0000000..c74483c
--- /dev/null
+++ b/tests/ref/fate/h264-conformance-frext-pph422i5_panasonic_a
@@ -0,0 +1,11 @@
+#tb 0: 1/25
+0,          0,          0,        1,  8294400, 0x96d051a1
+0,          1,          1,        1,  8294400, 0xf3c2974e
+0,          2,          2,        1,  8294400, 0xb18f3ed0
+0,          3,          3,        1,  8294400, 0xb5ba9998
+0,          4,          4,        1,  8294400, 0x96327a34
+0,          5,          5,        1,  8294400, 0xe24d7b61
+0,          6,          6,        1,  8294400, 0xc45d5a16
+0,          7,          7,        1,  8294400, 0x13b4a537
+0,          8,          8,        1,  8294400, 0xa81dae90
+0,          9,          9,        1,  8294400, 0x2820bbe9
diff --git a/tests/ref/fate/h264-conformance-frext-pph422i6_panasonic_a b/tests/ref/fate/h264-conformance-frext-pph422i6_panasonic_a
new file mode 100644
index 0000000..26d41d4
--- /dev/null
+++ b/tests/ref/fate/h264-conformance-frext-pph422i6_panasonic_a
@@ -0,0 +1,11 @@
+#tb 0: 1/25
+0,          0,          0,        1,  8294400, 0x1b2f1079
+0,          1,          1,        1,  8294400, 0x6646f91c
+0,          2,          2,        1,  8294400, 0x17dc9f51
+0,          3,          3,        1,  8294400, 0x4aad9b3a
+0,          4,          4,        1,  8294400, 0x8a422d34
+0,          5,          5,        1,  8294400, 0x8fd76d87
+0,          6,          6,        1,  8294400, 0xc7c75f18
+0,          7,          7,        1,  8294400, 0x4a1c2643
+0,          8,          8,        1,  8294400, 0xfe225709
+0,          9,          9,        1,  8294400, 0x032ad2e5
diff --git a/tests/ref/fate/h264-conformance-frext-pph422i7_panasonic_a b/tests/ref/fate/h264-conformance-frext-pph422i7_panasonic_a
new file mode 100644
index 0000000..3f9bfed
--- /dev/null
+++ b/tests/ref/fate/h264-conformance-frext-pph422i7_panasonic_a
@@ -0,0 +1,11 @@
+#tb 0: 1/25
+0,          0,          0,        1,  8294400, 0xaa37ceea
+0,          1,          1,        1,  8294400, 0xa7546d5c
+0,          2,          2,        1,  8294400, 0xf2abaace
+0,          3,          3,        1,  8294400, 0x36f4d47e
+0,          4,          4,        1,  8294400, 0x1cdf917d
+0,          5,          5,        1,  8294400, 0xa9377ba3
+0,          6,          6,        1,  8294400, 0x21c9db51
+0,          7,          7,        1,  8294400, 0x07d7936e
+0,          8,          8,        1,  8294400, 0x7878ab94
+0,          9,          9,        1,  8294400, 0x77e40921
diff --git a/tests/ref/fate/h264-lossless b/tests/ref/fate/h264-lossless
index 11cc4d0..44cb13b 100644
--- a/tests/ref/fate/h264-lossless
+++ b/tests/ref/fate/h264-lossless
@@ -1,11 +1,11 @@
-#tb 0: 1/25
+#tb 0: 83333/5000000
 0,          0,          0,        1,   460800, 0x7731dd2f
-0,          1,          1,        1,   460800, 0x944b8c64
-0,          2,          2,        1,   460800, 0xbe833041
-0,          3,          3,        1,   460800, 0xbe95d96a
-0,          4,          4,        1,   460800, 0xfe7ea5e6
-0,          5,          5,        1,   460800, 0x381743c7
-0,          6,          6,        1,   460800, 0x63fcc2e9
-0,          7,          7,        1,   460800, 0x79574960
-0,          8,          8,        1,   460800, 0xdab9e18a
-0,          9,          9,        1,   460800, 0xd88e8fe8
+0,          2,          2,        1,   460800, 0x944b8c64
+0,          3,          3,        1,   460800, 0xbe833041
+0,          4,          4,        1,   460800, 0xbe95d96a
+0,          5,          5,        1,   460800, 0xfe7ea5e6
+0,          6,          6,        1,   460800, 0x381743c7
+0,          7,          7,        1,   460800, 0x63fcc2e9
+0,          8,          8,        1,   460800, 0x79574960
+0,          9,          9,        1,   460800, 0xdab9e18a
+0,         10,         10,        1,   460800, 0xd88e8fe8
diff --git a/tests/ref/fate/idroq-video-encode b/tests/ref/fate/idroq-video-encode
index badb06d..24f3f0d 100644
--- a/tests/ref/fate/idroq-video-encode
+++ b/tests/ref/fate/idroq-video-encode
@@ -1 +1 @@
-2ac89fa0e5600152667bcbc661f06cfe
+2be5ade557acab688d58f1c5ec0773f4
diff --git a/tests/ref/fate/indeo3 b/tests/ref/fate/indeo3
index e294f70..0f55649 100644
--- a/tests/ref/fate/indeo3
+++ b/tests/ref/fate/indeo3
@@ -1,41 +1,41 @@
-#tb 0: 1/600
+#tb 0: 1/10
 0,          0,          0,        1,    21600, 0x845098fc
-0,         60,         60,        1,    21600, 0xc28e8bf0
-0,        120,        120,        1,    21600, 0x2f418fb4
-0,        180,        180,        1,    21600, 0x051d7a0e
-0,        240,        240,        1,    21600, 0x1b36aa7c
-0,        300,        300,        1,    21600, 0xb9e2ad38
-0,        360,        360,        1,    21600, 0x8dc99b60
-0,        420,        420,        1,    21600, 0xa3fa789a
-0,        480,        480,        1,    21600, 0x1fdbade2
-0,        540,        540,        1,    21600, 0x4f4ac164
-0,        600,        600,        1,    21600, 0x0ea5cb50
-0,        660,        660,        1,    21600, 0xfb659528
-0,        720,        720,        1,    21600, 0xac5790f8
-0,        780,        780,        1,    21600, 0x9762beb4
-0,        840,        840,        1,    21600, 0x29b0da0a
-0,        900,        900,        1,    21600, 0x6d88b0da
-0,        960,        960,        1,    21600, 0x687b8efa
-0,       1020,       1020,        1,    21600, 0xcd726220
-0,       1080,       1080,        1,    21600, 0xa1766598
-0,       1140,       1140,        1,    21600, 0xff4b8074
-0,       1200,       1200,        1,    21600, 0x845098fc
-0,       1260,       1260,        1,    21600, 0xdb259e08
-0,       1320,       1320,        1,    21600, 0xb6bda5a0
-0,       1380,       1380,        1,    21600, 0xbb998962
-0,       1440,       1440,        1,    21600, 0x28aa7b7c
-0,       1500,       1500,        1,    21600, 0x1ad1a15c
-0,       1560,       1560,        1,    21600, 0xb535a128
-0,       1620,       1620,        1,    21600, 0x4dbf968a
-0,       1680,       1680,        1,    21600, 0xfe90a8d6
-0,       1740,       1740,        1,    21600, 0xf63fabf0
-0,       1800,       1800,        1,    21600, 0xd6fabe58
-0,       1860,       1860,        1,    21600, 0x172eb09c
-0,       1920,       1920,        1,    21600, 0x44f8a8fe
-0,       1980,       1980,        1,    21600, 0x29429a06
-0,       2040,       2040,        1,    21600, 0xb12f8cc4
-0,       2100,       2100,        1,    21600, 0xd0c78cb4
-0,       2160,       2160,        1,    21600, 0x97e17e0c
-0,       2220,       2220,        1,    21600, 0xf8ac6700
-0,       2280,       2280,        1,    21600, 0xf9c17c94
-0,       2340,       2340,        1,    21600, 0xb10e8c54
+0,          1,          1,        1,    21600, 0xc28e8bf0
+0,          2,          2,        1,    21600, 0x2f418fb4
+0,          3,          3,        1,    21600, 0x051d7a0e
+0,          4,          4,        1,    21600, 0x1b36aa7c
+0,          5,          5,        1,    21600, 0xb9e2ad38
+0,          6,          6,        1,    21600, 0x8dc99b60
+0,          7,          7,        1,    21600, 0xa3fa789a
+0,          8,          8,        1,    21600, 0x1fdbade2
+0,          9,          9,        1,    21600, 0x4f4ac164
+0,         10,         10,        1,    21600, 0x0ea5cb50
+0,         11,         11,        1,    21600, 0xfb659528
+0,         12,         12,        1,    21600, 0xac5790f8
+0,         13,         13,        1,    21600, 0x9762beb4
+0,         14,         14,        1,    21600, 0x29b0da0a
+0,         15,         15,        1,    21600, 0x6d88b0da
+0,         16,         16,        1,    21600, 0x687b8efa
+0,         17,         17,        1,    21600, 0xcd726220
+0,         18,         18,        1,    21600, 0xa1766598
+0,         19,         19,        1,    21600, 0xff4b8074
+0,         20,         20,        1,    21600, 0x845098fc
+0,         21,         21,        1,    21600, 0xdb259e08
+0,         22,         22,        1,    21600, 0xb6bda5a0
+0,         23,         23,        1,    21600, 0xbb998962
+0,         24,         24,        1,    21600, 0x28aa7b7c
+0,         25,         25,        1,    21600, 0x1ad1a15c
+0,         26,         26,        1,    21600, 0xb535a128
+0,         27,         27,        1,    21600, 0x4dbf968a
+0,         28,         28,        1,    21600, 0xfe90a8d6
+0,         29,         29,        1,    21600, 0xf63fabf0
+0,         30,         30,        1,    21600, 0xd6fabe58
+0,         31,         31,        1,    21600, 0x172eb09c
+0,         32,         32,        1,    21600, 0x44f8a8fe
+0,         33,         33,        1,    21600, 0x29429a06
+0,         34,         34,        1,    21600, 0xb12f8cc4
+0,         35,         35,        1,    21600, 0xd0c78cb4
+0,         36,         36,        1,    21600, 0x97e17e0c
+0,         37,         37,        1,    21600, 0xf8ac6700
+0,         38,         38,        1,    21600, 0xf9c17c94
+0,         39,         39,        1,    21600, 0xb10e8c54
diff --git a/tests/ref/fate/indeo5 b/tests/ref/fate/indeo5
index 3f0adfb..7b91238 100644
--- a/tests/ref/fate/indeo5
+++ b/tests/ref/fate/indeo5
@@ -1,6 +1,5 @@
 #tb 0: 1/15
 0,          0,          0,        1,    48600, 0x72d4193b
-0,          1,          1,        1,    48600, 0x72d4193b
 0,          2,          2,        1,    48600, 0x36abd6f3
 0,          3,          3,        1,    48600, 0x99e582f7
 0,          4,          4,        1,    48600, 0xa4cb6fb7
diff --git a/tests/ref/fate/interplay-mve-16bit b/tests/ref/fate/interplay-mve-16bit
index 2469aaa..b20e998 100644
--- a/tests/ref/fate/interplay-mve-16bit
+++ b/tests/ref/fate/interplay-mve-16bit
@@ -1,51 +1,51 @@
-#tb 0: 1/1000000
-0,          0,          0,        0,   614400, 0x00000000
-0,      33360,      33360,        0,   614400, 0x00000000
-0,      66720,      66720,        0,   614400, 0xa17ea4ec
-0,     100080,     100080,        0,   614400, 0x4fd207fb
-0,     133440,     133440,        0,   614400, 0xd7a510fb
-0,     166800,     166800,        0,   614400, 0xe901e2f4
-0,     200160,     200160,        0,   614400, 0x4ac5d3c4
-0,     233520,     233520,        0,   614400, 0x32e3e99c
-0,     266880,     266880,        0,   614400, 0x7a2ff20c
-0,     300240,     300240,        0,   614400, 0x59941193
-0,     333600,     333600,        0,   614400, 0x92773a2b
-0,     366960,     366960,        0,   614400, 0x4cd14313
-0,     400320,     400320,        0,   614400, 0x2a093fa3
-0,     433680,     433680,        0,   614400, 0xf68b8463
-0,     467040,     467040,        0,   614400, 0xa9e1969b
-0,     500400,     500400,        0,   614400, 0x461996bb
-0,     533760,     533760,        0,   614400, 0xae58d053
-0,     567120,     567120,        0,   614400, 0x7693015a
-0,     600480,     600480,        0,   614400, 0x0b3507fa
-0,     633840,     633840,        0,   614400, 0xff5c2492
-0,     667200,     667200,        0,   614400, 0x636e3e32
-0,     700560,     700560,        0,   614400, 0x1acd6d0a
-0,     733920,     733920,        0,   614400, 0x67039232
-0,     767280,     767280,        0,   614400, 0x8ab9c75a
-0,     800640,     800640,        0,   614400, 0xe824bbe2
-0,     834000,     834000,        0,   614400, 0x5133e9ea
-0,     867360,     867360,        0,   614400, 0xcecf1249
-0,     900720,     900720,        0,   614400, 0xe6d928c1
-0,     934080,     934080,        0,   614400, 0x8da46ff1
-0,     967440,     967440,        0,   614400, 0x1c778319
-0,    1000800,    1000800,        0,   614400, 0x35a19451
-0,    1034160,    1034160,        0,   614400, 0x5145d1b9
-0,    1067520,    1067520,        0,   614400, 0x146ee231
-0,    1100880,    1100880,        0,   614400, 0xd9b33380
-0,    1134240,    1134240,        0,   614400, 0x8b112ef8
-0,    1167600,    1167600,        0,   614400, 0xb9e79ab0
-0,    1200960,    1200960,        0,   614400, 0x62d3a498
-0,    1234320,    1234320,        0,   614400, 0xaeaaaa58
-0,    1267680,    1267680,        0,   614400, 0x8922c440
-0,    1301040,    1301040,        0,   614400, 0xd62ef758
-0,    1334400,    1334400,        0,   614400, 0x2a53149f
-0,    1367760,    1367760,        0,   614400, 0x13da47df
-0,    1401120,    1401120,        0,   614400, 0x27c05c3f
-0,    1434480,    1434480,        0,   614400, 0x41ff7ca7
-0,    1467840,    1467840,        0,   614400, 0x6b0e8a07
-0,    1501200,    1501200,        0,   614400, 0xa200ad9f
-0,    1534560,    1534560,        0,   614400, 0x9da7cc77
-0,    1567920,    1567920,        0,   614400, 0x2f5703be
-0,    1601280,    1601280,        0,   614400, 0x91c720f6
-0,    1634640,    1634640,        0,   614400, 0x927a882e
+#tb 0: 417/12500
+0,          0,          0,        1,   614400, 0x00000000
+0,          1,          1,        1,   614400, 0x00000000
+0,          2,          2,        1,   614400, 0x3c4ce011
+0,          3,          3,        1,   614400, 0x16e83922
+0,          4,          4,        1,   614400, 0x657a3d4d
+0,          5,          5,        1,   614400, 0x933a08b0
+0,          6,          6,        1,   614400, 0xfcd5f76e
+0,          7,          7,        1,   614400, 0xd0990cf8
+0,          8,          8,        1,   614400, 0x02131686
+0,          9,          9,        1,   614400, 0x4cf53656
+0,         10,         10,        1,   614400, 0x7d1960c0
+0,         11,         11,        1,   614400, 0x5d9f696f
+0,         12,         12,        1,   614400, 0x54e06663
+0,         13,         13,        1,   614400, 0x4c1eade1
+0,         14,         14,        1,   614400, 0x4bd3bfff
+0,         15,         15,        1,   614400, 0xab86c041
+0,         16,         16,        1,   614400, 0xbb2bfbf4
+0,         17,         17,        1,   614400, 0x43822e15
+0,         18,         18,        1,   614400, 0x835e352c
+0,         19,         19,        1,   614400, 0x72cc538f
+0,         20,         20,        1,   614400, 0x20bb6e30
+0,         21,         21,        1,   614400, 0xfb079f52
+0,         22,         22,        1,   614400, 0x759bc4d6
+0,         23,         23,        1,   614400, 0xd116fc3b
+0,         24,         24,        1,   614400, 0x5c06efd2
+0,         25,         25,        1,   614400, 0x61641ecd
+0,         26,         26,        1,   614400, 0x6c8d48a0
+0,         27,         27,        1,   614400, 0x64725eed
+0,         28,         28,        1,   614400, 0x88f9a8ca
+0,         29,         29,        1,   614400, 0xcf1cbcd9
+0,         30,         30,        1,   614400, 0x75a3ce24
+0,         31,         31,        1,   614400, 0x3bf80ce7
+0,         32,         32,        1,   614400, 0xd4011d7c
+0,         33,         33,        1,   614400, 0xd569716b
+0,         34,         34,        1,   614400, 0xfd626b6b
+0,         35,         35,        1,   614400, 0xc856dbaf
+0,         36,         36,        1,   614400, 0x0e56e68e
+0,         37,         37,        1,   614400, 0x5b29ecc9
+0,         38,         38,        1,   614400, 0xe83c0804
+0,         39,         39,        1,   614400, 0xebdd3d61
+0,         40,         40,        1,   614400, 0x7f4c5b56
+0,         41,         41,        1,   614400, 0xb4019155
+0,         42,         42,        1,   614400, 0xffdda515
+0,         43,         43,        1,   614400, 0x5271c695
+0,         44,         44,        1,   614400, 0x8526d3c1
+0,         45,         45,        1,   614400, 0x5accf7a6
+0,         46,         46,        1,   614400, 0x959017aa
+0,         47,         47,        1,   614400, 0x22f450f6
+0,         48,         48,        1,   614400, 0x2e3d6f37
+0,         49,         49,        1,   614400, 0x0db9d89f
diff --git a/tests/ref/fate/interplay-mve-8bit b/tests/ref/fate/interplay-mve-8bit
index abd86eb..b37bd6e 100644
--- a/tests/ref/fate/interplay-mve-8bit
+++ b/tests/ref/fate/interplay-mve-8bit
@@ -1,111 +1,111 @@
-#tb 0: 1/1000000
-0,          0,          0,        0,   414720, 0xa5cd50ca
-0,      66728,      66728,        0,   414720, 0x3facd321
-0,     133456,     133456,        0,   414720, 0x849e6d4b
-0,     200184,     200184,        0,   414720, 0xe649363f
-0,     266912,     266912,        0,   414720, 0x5bbd7b14
-0,     333640,     333640,        0,   414720, 0xe246ab51
-0,     400368,     400368,        0,   414720, 0x5721b22e
-0,     467096,     467096,        0,   414720, 0xe391e107
-0,     533824,     533824,        0,   414720, 0x04d851ff
-0,     600552,     600552,        0,   414720, 0x8d80d580
-0,     667280,     667280,        0,   414720, 0x5a24b0bc
-0,     734008,     734008,        0,   414720, 0x06cd6960
-0,     800736,     800736,        0,   414720, 0xf5ca48b4
-0,     867464,     867464,        0,   414720, 0x24700f94
-0,     934192,     934192,        0,   414720, 0xb0bfe451
-0,    1000920,    1000920,        0,   414720, 0x00e9f3d1
-0,    1067648,    1067648,        0,   414720, 0x0efbffd1
-0,    1134376,    1134376,        0,   414720, 0x2ecdfc8d
-0,    1201104,    1201104,        0,   414720, 0x94b531fc
-0,    1267832,    1267832,        0,   414720, 0x2c2579f8
-0,    1334560,    1334560,        0,   414720, 0x6c7ecfb8
-0,    1401288,    1401288,        0,   414720, 0x08982527
-0,    1468016,    1468016,        0,   414720, 0x5c0161b3
-0,    1534744,    1534744,        0,   414720, 0x453ce413
-0,    1601472,    1601472,        0,   414720, 0x634e36b2
-0,    1668200,    1668200,        0,   414720, 0x401a683a
-0,    1734928,    1734928,        0,   414720, 0x3c5f442e
-0,    1801656,    1801656,        0,   414720, 0x075ef787
-0,    1868384,    1868384,        0,   414720, 0x8501a04f
-0,    1935112,    1935112,        0,   414720, 0x3620093b
-0,    2001840,    2001840,        0,   414720, 0xa42d9480
-0,    2068568,    2068568,        0,   414720, 0x09b150b4
-0,    2135296,    2135296,        0,   414720, 0xcad407f0
-0,    2202024,    2202024,        0,   414720, 0x69e5eecd
-0,    2268752,    2268752,        0,   414720, 0xb92ad2d9
-0,    2335480,    2335480,        0,   414720, 0xc78eaf29
-0,    2402208,    2402208,        0,   414720, 0x47c3fa91
-0,    2468936,    2468936,        0,   414720, 0x8847b7b8
-0,    2535664,    2535664,        0,   414720, 0x864cab2f
-0,    2602392,    2602392,        0,   414720, 0x78d653e2
-0,    2669120,    2669120,        0,   414720, 0xda15cbd2
-0,    2735848,    2735848,        0,   414720, 0xdf9ce28a
-0,    2802576,    2802576,        0,   414720, 0xe88c49ca
-0,    2869304,    2869304,        0,   414720, 0xd6bcbc07
-0,    2936032,    2936032,        0,   414720, 0xf0b4a7bf
-0,    3002760,    3002760,        0,   414720, 0x74f9bfbf
-0,    3069488,    3069488,        0,   414720, 0x904ce103
-0,    3136216,    3136216,        0,   414720, 0xca877e4a
-0,    3202944,    3202944,        0,   414720, 0x588effd6
-0,    3269672,    3269672,        0,   414720, 0x6dff8b71
-0,    3336400,    3336400,        0,   414720, 0xbeaae788
-0,    3403128,    3403128,        0,   414720, 0x1a4d1242
-0,    3469856,    3469856,        0,   414720, 0x4ae98ea0
-0,    3536584,    3536584,        0,   414720, 0x41ed6d22
-0,    3603312,    3603312,        0,   414720, 0x486e70aa
-0,    3670040,    3670040,        0,   414720, 0xfddc103e
-0,    3736768,    3736768,        0,   414720, 0x8620f03e
-0,    3803496,    3803496,        0,   414720, 0x0e4ec273
-0,    3870224,    3870224,        0,   414720, 0xb2298b3e
-0,    3936952,    3936952,        0,   414720, 0xb4f50176
-0,    4003680,    4003680,        0,   414720, 0xb9c7a495
-0,    4070408,    4070408,        0,   414720, 0xed270702
-0,    4137136,    4137136,        0,   414720, 0x98b72586
-0,    4203864,    4203864,        0,   414720, 0xd8977cb1
-0,    4270592,    4270592,        0,   414720, 0xff3d3851
-0,    4337320,    4337320,        0,   414720, 0x7e4f0424
-0,    4404048,    4404048,        0,   414720, 0xa9e75006
-0,    4470776,    4470776,        0,   414720, 0x8f98cba9
-0,    4537504,    4537504,        0,   414720, 0x25ecd620
-0,    4604232,    4604232,        0,   414720, 0x78cf5c58
-0,    4670960,    4670960,        0,   414720, 0x3fb4b81a
-0,    4737688,    4737688,        0,   414720, 0xd7b655fa
-0,    4804416,    4804416,        0,   414720, 0xd9158db3
-0,    4871144,    4871144,        0,   414720, 0x2e651852
-0,    4937872,    4937872,        0,   414720, 0x9f9adb64
-0,    5004600,    5004600,        0,   414720, 0xe9d16e81
-0,    5071328,    5071328,        0,   414720, 0xbe73daf5
-0,    5138056,    5138056,        0,   414720, 0x3d164329
-0,    5204784,    5204784,        0,   414720, 0x1d5a9bc8
-0,    5271512,    5271512,        0,   414720, 0x8e8debbe
-0,    5338240,    5338240,        0,   414720, 0x4e7a2bf0
-0,    5404968,    5404968,        0,   414720, 0x4a13804d
-0,    5471696,    5471696,        0,   414720, 0x5dd188d8
-0,    5538424,    5538424,        0,   414720, 0xbe7f4963
-0,    5605152,    5605152,        0,   414720, 0xcff3b767
-0,    5671880,    5671880,        0,   414720, 0xbbd3afa0
-0,    5738608,    5738608,        0,   414720, 0xaf9dec62
-0,    5805336,    5805336,        0,   414720, 0xc74816a1
-0,    5872064,    5872064,        0,   414720, 0x51488bfc
-0,    5938792,    5938792,        0,   414720, 0x68c10a2c
-0,    6005520,    6005520,        0,   414720, 0x10179c4e
-0,    6072248,    6072248,        0,   414720, 0x18d559b7
-0,    6138976,    6138976,        0,   414720, 0x8257aa55
-0,    6205704,    6205704,        0,   414720, 0x9ea24501
-0,    6272432,    6272432,        0,   414720, 0x238605cc
-0,    6339160,    6339160,        0,   414720, 0xb552deaa
-0,    6405888,    6405888,        0,   414720, 0x07c3348d
-0,    6472616,    6472616,        0,   414720, 0x82f4f9b0
-0,    6539344,    6539344,        0,   414720, 0xf5d76bc5
-0,    6606072,    6606072,        0,   414720, 0x34b3a1e6
-0,    6672800,    6672800,        0,   414720, 0xda25e11b
-0,    6739528,    6739528,        0,   414720, 0x2b19936b
-0,    6806256,    6806256,        0,   414720, 0xe91f9f73
-0,    6872984,    6872984,        0,   414720, 0x48d09aab
-0,    6939712,    6939712,        0,   414720, 0xac42bf83
-0,    7006440,    7006440,        0,   414720, 0x2d8ca14e
-0,    7073168,    7073168,        0,   414720, 0xe65462fd
-0,    7139896,    7139896,        0,   414720, 0xe5bfc929
-0,    7206624,    7206624,        0,   414720, 0x66784c58
-0,    7273352,    7273352,        0,   414720, 0x70dbeca8
+#tb 0: 8341/125000
+0,          0,          0,        1,   414720, 0x2580d574
+0,          1,          1,        1,   414720, 0x97f55cd3
+0,          2,          2,        1,   414720, 0x9408fb63
+0,          3,          3,        1,   414720, 0x7e53c155
+0,          4,          4,        1,   414720, 0xd8570262
+0,          5,          5,        1,   414720, 0x9dc72ed5
+0,          6,          6,        1,   414720, 0xf7d33211
+0,          7,          7,        1,   414720, 0x95935e3b
+0,          8,          8,        1,   414720, 0x62b1cdc5
+0,          9,          9,        1,   414720, 0x971f500a
+0,         10,         10,        1,   414720, 0x05f82b6c
+0,         11,         11,        1,   414720, 0x7713e3cb
+0,         12,         12,        1,   414720, 0x3170c2f0
+0,         13,         13,        1,   414720, 0x8d818956
+0,         14,         14,        1,   414720, 0x16775d71
+0,         15,         15,        1,   414720, 0x63016ce1
+0,         16,         16,        1,   414720, 0x2f94792c
+0,         17,         17,        1,   414720, 0x37f67725
+0,         18,         18,        1,   414720, 0xeb95adb1
+0,         19,         19,        1,   414720, 0xbf32f6df
+0,         20,         20,        1,   414720, 0x242f4d09
+0,         21,         21,        1,   414720, 0x28a2a3b9
+0,         22,         22,        1,   414720, 0x895de0a6
+0,         23,         23,        1,   414720, 0xd3b46447
+0,         24,         24,        1,   414720, 0x3bbfb7d1
+0,         25,         25,        1,   414720, 0x0a5ee9ad
+0,         26,         26,        1,   414720, 0xaabac502
+0,         27,         27,        1,   414720, 0x0951779d
+0,         28,         28,        1,   414720, 0x150e2073
+0,         29,         29,        1,   414720, 0xb86d87ae
+0,         30,         30,        1,   414720, 0x135411da
+0,         31,         31,        1,   414720, 0x9c8fcda5
+0,         32,         32,        1,   414720, 0xb7ba838e
+0,         33,         33,        1,   414720, 0x7ef869e1
+0,         34,         34,        1,   414720, 0xf9764d47
+0,         35,         35,        1,   414720, 0xe6c72872
+0,         36,         36,        1,   414720, 0xb95b73b8
+0,         37,         37,        1,   414720, 0xa19e3221
+0,         38,         38,        1,   414720, 0xc0be27cd
+0,         39,         39,        1,   414720, 0xe97cd1a9
+0,         40,         40,        1,   414720, 0xb6524a34
+0,         41,         41,        1,   414720, 0x61a1607b
+0,         42,         42,        1,   414720, 0x1dd9c606
+0,         43,         43,        1,   414720, 0xe2e736fa
+0,         44,         44,        1,   414720, 0x25b922d9
+0,         45,         45,        1,   414720, 0xbc023b36
+0,         46,         46,        1,   414720, 0x39bb5cdf
+0,         47,         47,        1,   414720, 0xf83bfc4f
+0,         48,         48,        1,   414720, 0x3eae7f36
+0,         49,         49,        1,   414720, 0x8cf80c32
+0,         50,         50,        1,   414720, 0xbc576c03
+0,         51,         51,        1,   414720, 0x28b79ab1
+0,         52,         52,        1,   414720, 0x15da1138
+0,         53,         53,        1,   414720, 0x345ff676
+0,         54,         54,        1,   414720, 0x0108f909
+0,         55,         55,        1,   414720, 0x57459616
+0,         56,         56,        1,   414720, 0x2f497782
+0,         57,         57,        1,   414720, 0xb72b4f79
+0,         58,         58,        1,   414720, 0x2bfd1967
+0,         59,         59,        1,   414720, 0x974a99cd
+0,         60,         60,        1,   414720, 0x5f5f4129
+0,         61,         61,        1,   414720, 0x51ad9df4
+0,         62,         62,        1,   414720, 0xd6e5c16c
+0,         63,         63,        1,   414720, 0xd8751bda
+0,         64,         64,        1,   414720, 0x216ed6f3
+0,         65,         65,        1,   414720, 0x63a0a67d
+0,         66,         66,        1,   414720, 0xe4f4eb0f
+0,         67,         67,        1,   414720, 0xa1665ef8
+0,         68,         68,        1,   414720, 0xc3116dfd
+0,         69,         69,        1,   414720, 0x3213fd70
+0,         70,         70,        1,   414720, 0x2af76048
+0,         71,         71,        1,   414720, 0x3570085d
+0,         72,         72,        1,   414720, 0x2a7c3c39
+0,         73,         73,        1,   414720, 0xd8a6ba7e
+0,         74,         74,        1,   414720, 0x48107b4d
+0,         75,         75,        1,   414720, 0x653a0936
+0,         76,         76,        1,   414720, 0xf68c77ab
+0,         77,         77,        1,   414720, 0xa5ecde84
+0,         78,         78,        1,   414720, 0xaec33ca1
+0,         79,         79,        1,   414720, 0x26e68740
+0,         80,         80,        1,   414720, 0xac09bfa5
+0,         81,         81,        1,   414720, 0xed5111b2
+0,         82,         82,        1,   414720, 0x38041c98
+0,         83,         83,        1,   414720, 0x76fbde1d
+0,         84,         84,        1,   414720, 0x3ae64b7d
+0,         85,         85,        1,   414720, 0xb05f4da2
+0,         86,         86,        1,   414720, 0x65769088
+0,         87,         87,        1,   414720, 0xbc45ba59
+0,         88,         88,        1,   414720, 0x8c893436
+0,         89,         89,        1,   414720, 0x1d5ebe7f
+0,         90,         90,        1,   414720, 0xa9cd5a53
+0,         91,         91,        1,   414720, 0xc69e1fb0
+0,         92,         92,        1,   414720, 0xb28a77ec
+0,         93,         93,        1,   414720, 0x834f1219
+0,         94,         94,        1,   414720, 0xba34c848
+0,         95,         95,        1,   414720, 0x80e590c1
+0,         96,         96,        1,   414720, 0x7146dc31
+0,         97,         97,        1,   414720, 0x05929a5f
+0,         98,         98,        1,   414720, 0x721708c5
+0,         99,         99,        1,   414720, 0x4aa83cbe
+0,        100,        100,        1,   414720, 0x221d799f
+0,        101,        101,        1,   414720, 0xe9e72bec
+0,        102,        102,        1,   414720, 0xb6a3385d
+0,        103,        103,        1,   414720, 0x795a3362
+0,        104,        104,        1,   414720, 0x770b58d9
+0,        105,        105,        1,   414720, 0xb5563ce4
+0,        106,        106,        1,   414720, 0x0c1a00cc
+0,        107,        107,        1,   414720, 0xcbd467fd
+0,        108,        108,        1,   414720, 0x3bccec29
+0,        109,        109,        1,   414720, 0x92d78db7
diff --git a/tests/ref/fate/iv8-demux b/tests/ref/fate/iv8-demux
index 56a54a1..f13e691 100644
--- a/tests/ref/fate/iv8-demux
+++ b/tests/ref/fate/iv8-demux
@@ -19,8 +19,8 @@
 0,      57600,      61200,        0,    20874, 0xed0b91ec
 0,      61200,      64799,        0,    20877, 0xe1623e01
 0,      64799,      68399,        0,    20933, 0x19906564
-0,      68399,      72000,     3600,    20891, 0x3d064fd3
-0,      72000,      75600,     3600,    20834, 0xcb774dbc
-0,      75600,      79200,     3600,    20870, 0xbc536589
-0,      79200,      82800,     3600,    21421, 0xc99a68e4
-0,      82800,      86400,     3600,    12869, 0x5684e304
+0,      68399,      72000,        0,    20891, 0x3d064fd3
+0,      72000,      75600,        0,    20834, 0xcb774dbc
+0,      75600,      79200,        0,    20870, 0xbc536589
+0,      79200,      82800,        0,    21421, 0xc99a68e4
+0,      82800,      86400,        0,    12869, 0x5684e304
diff --git a/tests/ref/fate/jv b/tests/ref/fate/jv
new file mode 100644
index 0000000..b0a6008
--- /dev/null
+++ b/tests/ref/fate/jv
@@ -0,0 +1,8 @@
+#tb 0: 2/25
+0,          0,          0,        1,   192000, 0x00000000
+0,          2,          2,        1,   192000, 0x331b1c12
+0,          3,          3,        1,   192000, 0xc2fa2d89
+0,          4,          4,        1,   192000, 0x9b3035ac
+0,          5,          5,        1,   192000, 0xb8e331eb
+0,          6,          6,        1,   192000, 0xd35b2053
+0,          7,          7,        1,   192000, 0x01062188
diff --git a/tests/ref/fate/jv-demux b/tests/ref/fate/jv-demux
new file mode 100644
index 0000000..c57fce0
--- /dev/null
+++ b/tests/ref/fate/jv-demux
@@ -0,0 +1,20 @@
+#tb 0: 2/25
+#tb 1: 1/22050
+0,          0,          0,        1,        6, 0x000a0003
+1,          0,          0,   131072,   131072, 0x14c664d6
+0,          1,          1,        1,      773, 0x11802a51
+0,          2,          2,        1,    12974, 0xc2e466b7
+0,          3,          3,        1,    12200, 0x3c0eeb31
+0,          4,          4,        1,    13339, 0x91d82488
+0,          5,          5,        1,    13940, 0x064c350a
+0,          6,          6,        1,    14418, 0x078d2dd2
+0,          7,          7,        1,    14539, 0x145167ed
+0,          8,          8,        1,     2552, 0xcf2b1db7
+1,     131072,     131072,     1764,     1764, 0x30be734d
+1,     132836,     132836,     1764,     1764, 0xa4c873a7
+1,     134600,     134600,     1764,     1764, 0xd5f17443
+1,     136364,     136364,     1764,     1764, 0xd31c7230
+1,     138128,     138128,     1764,     1764, 0x181d730f
+1,     139892,     139892,     1764,     1764, 0x76f47538
+1,     141656,     141656,     1764,     1764, 0x6c51715d
+1,     143420,     143420,     1764,     1764, 0x689374f5
diff --git a/tests/ref/fate/lmlm4-demux b/tests/ref/fate/lmlm4-demux
index 0546135..f8a6e21 100644
--- a/tests/ref/fate/lmlm4-demux
+++ b/tests/ref/fate/lmlm4-demux
@@ -3,215 +3,215 @@
 0,          0, -9223372036854775808,        1,     5951, 0xe9118e0d
 1,          0,          0,     2160,      768, 0xaebcbebb
 1,       2160,       2160,     2160,      768, 0xaebcbebb
-0,          1, -9223372036854775808,        1,     1672, 0x4b80d4ca
+0,          1, -9223372036854775808,        1,     1672, 0x4b80d4ca, F=0x0
 1,       4320,       4320,     2160,      768, 0xaebcbebb
-0,          2, -9223372036854775808,        1,     1604, 0x99e1b0a7
+0,          2, -9223372036854775808,        1,     1604, 0x99e1b0a7, F=0x0
 1,       6480,       6480,     2160,      768, 0x866fe37a
 1,       8640,       8640,     2160,      768, 0x05d76890
-0,          3, -9223372036854775808,        1,     1204, 0x9559038a
+0,          3, -9223372036854775808,        1,     1204, 0x9559038a, F=0x0
 1,      10800,      10800,     2160,      768, 0x858f5511
-0,          4, -9223372036854775808,        1,     1482, 0x60056564
+0,          4, -9223372036854775808,        1,     1482, 0x60056564, F=0x0
 1,      12960,      12960,     2160,      768, 0x97cb65ef
-0,          5, -9223372036854775808,        1,     1105, 0xf508cef4
+0,          5, -9223372036854775808,        1,     1105, 0xf508cef4, F=0x0
 1,      15120,      15120,     2160,      768, 0xe269742c
 1,      17280,      17280,     2160,      768, 0xa6015f8d
-0,          6, -9223372036854775808,        1,     1193, 0xc8e0fd36
+0,          6, -9223372036854775808,        1,     1193, 0xc8e0fd36, F=0x0
 1,      19440,      19440,     2160,      768, 0x759163e0
-0,          7, -9223372036854775808,        1,     1247, 0x8dd202e5
+0,          7, -9223372036854775808,        1,     1247, 0x8dd202e5, F=0x0
 1,      21600,      21600,     2160,      768, 0xb1e16082
 1,      23760,      23760,     2160,      768, 0x1b616429
-0,          8, -9223372036854775808,        1,     1367, 0xf59435e5
+0,          8, -9223372036854775808,        1,     1367, 0xf59435e5, F=0x0
 1,      25920,      25920,     2160,      768, 0x7e4364f7
-0,          9, -9223372036854775808,        1,     1406, 0x68ba4a7e
+0,          9, -9223372036854775808,        1,     1406, 0x68ba4a7e, F=0x0
 1,      28080,      28080,     2160,      768, 0x59bd64f7
-0,         10, -9223372036854775808,        1,     1262, 0x82c04123
+0,         10, -9223372036854775808,        1,     1262, 0x82c04123, F=0x0
 1,      30240,      30240,     2160,      768, 0xc3116fc6
 1,      32400,      32400,     2160,      768, 0x6a1c6b56
-0,         11, -9223372036854775808,        1,     1381, 0x02335cf9
+0,         11, -9223372036854775808,        1,     1381, 0x02335cf9, F=0x0
 1,      34560,      34560,     2160,      768, 0x285a64cf
-0,         12, -9223372036854775808,        1,     1450, 0x7be46fd1
+0,         12, -9223372036854775808,        1,     1450, 0x7be46fd1, F=0x0
 1,      36720,      36720,     2160,      768, 0x79b16d65
 1,      38880,      38880,     2160,      768, 0x09b47635
-0,         13, -9223372036854775808,        1,     1362, 0x75cc381a
+0,         13, -9223372036854775808,        1,     1362, 0x75cc381a, F=0x0
 1,      41040,      41040,     2160,      768, 0x81597446
-0,         14, -9223372036854775808,        1,     1409, 0x9ed74f3f
+0,         14, -9223372036854775808,        1,     1409, 0x9ed74f3f, F=0x0
 1,      43200,      43200,     2160,      768, 0xfeb66eee
-0,         15, -9223372036854775808,        1,     1253, 0x82400ae1
+0,         15, -9223372036854775808,        1,     1253, 0x82400ae1, F=0x0
 1,      45360,      45360,     2160,      768, 0x78557618
 1,      47520,      47520,     2160,      768, 0x3af170bf
 0,         16, -9223372036854775808,        1,     5499, 0xed286805
 1,      49680,      49680,     2160,      768, 0xefbd6399
-0,         17, -9223372036854775808,        1,     1403, 0x483c4cbc
+0,         17, -9223372036854775808,        1,     1403, 0x483c4cbc, F=0x0
 1,      51840,      51840,     2160,      768, 0xc98e7492
 1,      54000,      54000,     2160,      768, 0x010d7149
-0,         18, -9223372036854775808,        1,     1632, 0xa9ebcd6c
+0,         18, -9223372036854775808,        1,     1632, 0xa9ebcd6c, F=0x0
 1,      56160,      56160,     2160,      768, 0xce838b07
-0,         19, -9223372036854775808,        1,     1207, 0xc8580724
+0,         19, -9223372036854775808,        1,     1207, 0xc8580724, F=0x0
 1,      58320,      58320,     2160,      768, 0xed18726c
-0,         20, -9223372036854775808,        1,     1289, 0x61fb2fd2
+0,         20, -9223372036854775808,        1,     1289, 0x61fb2fd2, F=0x0
 1,      60480,      60480,     2160,      768, 0x017e6712
 1,      62640,      62640,     2160,      768, 0x7f9268e9
-0,         21, -9223372036854775808,        1,     1230, 0xf348f53c
+0,         21, -9223372036854775808,        1,     1230, 0xf348f53c, F=0x0
 1,      64800,      64800,     2160,      768, 0xf6f258fc
-0,         22, -9223372036854775808,        1,     1579, 0xa260b1ac
+0,         22, -9223372036854775808,        1,     1579, 0xa260b1ac, F=0x0
 1,      66960,      66960,     2160,      768, 0x9a1a6f31
-0,         23, -9223372036854775808,        1,      949, 0x91849002
+0,         23, -9223372036854775808,        1,      949, 0x91849002, F=0x0
 1,      69120,      69120,     2160,      768, 0x14b47b23
 1,      71280,      71280,     2160,      768, 0x9bdc6a50
-0,         24, -9223372036854775808,        1,      786, 0x3e33576f
+0,         24, -9223372036854775808,        1,      786, 0x3e33576f, F=0x0
 1,      73440,      73440,     2160,      768, 0x0fc46dab
-0,         25, -9223372036854775808,        1,      894, 0x9ac36a61
+0,         25, -9223372036854775808,        1,      894, 0x9ac36a61, F=0x0
 1,      75600,      75600,     2160,      768, 0x6c387372
 1,      77760,      77760,     2160,      768, 0x581e71cd
-0,         26, -9223372036854775808,        1,     1186, 0x6bfc116e
+0,         26, -9223372036854775808,        1,     1186, 0x6bfc116e, F=0x0
 1,      79920,      79920,     2160,      768, 0x00cb785f
-0,         27, -9223372036854775808,        1,     1187, 0xcfc512ae
+0,         27, -9223372036854775808,        1,     1187, 0xcfc512ae, F=0x0
 1,      82080,      82080,     2160,      768, 0x1dda7032
-0,         28, -9223372036854775808,        1,     1527, 0x5c2c965a
+0,         28, -9223372036854775808,        1,     1527, 0x5c2c965a, F=0x0
 1,      84240,      84240,     2160,      768, 0xf57c7103
 1,      86400,      86400,     2160,      768, 0x2d927183
-0,         29, -9223372036854775808,        1,     1536, 0x5ba7ac29
+0,         29, -9223372036854775808,        1,     1536, 0x5ba7ac29, F=0x0
 1,      88560,      88560,     2160,      768, 0xdae86cdf
-0,         30, -9223372036854775808,        1,     1095, 0xce06eb96
+0,         30, -9223372036854775808,        1,     1095, 0xce06eb96, F=0x0
 1,      90720,      90720,     2160,      768, 0x2a2f6c3c
 1,      92880,      92880,     2160,      768, 0x44696eba
-0,         31, -9223372036854775808,        1,     1402, 0x642f6b0d
+0,         31, -9223372036854775808,        1,     1402, 0x642f6b0d, F=0x0
 1,      95040,      95040,     2160,      768, 0xf67c71c4
 0,         32, -9223372036854775808,        1,     5551, 0xf01a9c08
 1,      97200,      97200,     2160,      768, 0xc1ce7237
-0,         33, -9223372036854775808,        1,     1211, 0x350206f7
+0,         33, -9223372036854775808,        1,     1211, 0x350206f7, F=0x0
 1,      99360,      99360,     2160,      768, 0xd9c36ef5
 1,     101520,     101520,     2160,      768, 0x63b06b03
-0,         34, -9223372036854775808,        1,      887, 0x08767619
+0,         34, -9223372036854775808,        1,      887, 0x08767619, F=0x0
 1,     103680,     103680,     2160,      768, 0x8de97ebe
-0,         35, -9223372036854775808,        1,     1042, 0xcc81a9ed
+0,         35, -9223372036854775808,        1,     1042, 0xcc81a9ed, F=0x0
 1,     105840,     105840,     2160,      768, 0xbf117c32
 1,     108000,     108000,     2160,      768, 0x82897497
-0,         36, -9223372036854775808,        1,     1247, 0x6f320614
+0,         36, -9223372036854775808,        1,     1247, 0x6f320614, F=0x0
 1,     110160,     110160,     2160,      768, 0x7a347abb
-0,         37, -9223372036854775808,        1,     1459, 0xd28975b5
+0,         37, -9223372036854775808,        1,     1459, 0xd28975b5, F=0x0
 1,     112320,     112320,     2160,      768, 0xc99b691e
-0,         38, -9223372036854775808,        1,     1116, 0x1ab1e9db
+0,         38, -9223372036854775808,        1,     1116, 0x1ab1e9db, F=0x0
 1,     114480,     114480,     2160,      768, 0xf4fc6e74
 1,     116640,     116640,     2160,      768, 0x511d6ec4
-0,         39, -9223372036854775808,        1,     1110, 0x6411f66a
+0,         39, -9223372036854775808,        1,     1110, 0x6411f66a, F=0x0
 1,     118800,     118800,     2160,      768, 0xb8c06b5f
-0,         40, -9223372036854775808,        1,     1282, 0xd468375d
+0,         40, -9223372036854775808,        1,     1282, 0xd468375d, F=0x0
 1,     120960,     120960,     2160,      768, 0xf1776aed
 1,     123120,     123120,     2160,      768, 0xe6fe7fb4
-0,         41, -9223372036854775808,        1,     1077, 0x1273c6e3
+0,         41, -9223372036854775808,        1,     1077, 0x1273c6e3, F=0x0
 1,     125280,     125280,     2160,      768, 0x36907aff
-0,         42, -9223372036854775808,        1,     1043, 0x12dbd3ae
+0,         42, -9223372036854775808,        1,     1043, 0x12dbd3ae, F=0x0
 1,     127440,     127440,     2160,      768, 0xddf666bb
-0,         43, -9223372036854775808,        1,     1087, 0x3e70d37a
+0,         43, -9223372036854775808,        1,     1087, 0x3e70d37a, F=0x0
 1,     129600,     129600,     2160,      768, 0x8e896ebc
 1,     131760,     131760,     2160,      768, 0x0aa47dfa
-0,         44, -9223372036854775808,        1,      992, 0x0651a71c
+0,         44, -9223372036854775808,        1,      992, 0x0651a71c, F=0x0
 1,     133920,     133920,     2160,      768, 0xc1736811
-0,         45, -9223372036854775808,        1,     1012, 0x6a069f8c
+0,         45, -9223372036854775808,        1,     1012, 0x6a069f8c, F=0x0
 1,     136080,     136080,     2160,      768, 0xb3e87009
-0,         46, -9223372036854775808,        1,     1320, 0x92803d69
+0,         46, -9223372036854775808,        1,     1320, 0x92803d69, F=0x0
 1,     138240,     138240,     2160,      768, 0xf23e6c00
 1,     140400,     140400,     2160,      768, 0x993a71d2
-0,         47, -9223372036854775808,        1,     1080, 0xe0ffbe95
+0,         47, -9223372036854775808,        1,     1080, 0xe0ffbe95, F=0x0
 1,     142560,     142560,     2160,      768, 0xa53466dd
 0,         48, -9223372036854775808,        1,     5639, 0x658ca26b
 1,     144720,     144720,     2160,      768, 0xb43a74b0
 1,     146880,     146880,     2160,      768, 0x348f615c
-0,         49, -9223372036854775808,        1,     1385, 0xbcb96241
+0,         49, -9223372036854775808,        1,     1385, 0xbcb96241, F=0x0
 1,     149040,     149040,     2160,      768, 0x298f6e1b
-0,         50, -9223372036854775808,        1,     1142, 0x8c6df318
+0,         50, -9223372036854775808,        1,     1142, 0x8c6df318, F=0x0
 1,     151200,     151200,     2160,      768, 0x5db469c8
-0,         51, -9223372036854775808,        1,     1175, 0xcac1faef
+0,         51, -9223372036854775808,        1,     1175, 0xcac1faef, F=0x0
 1,     153360,     153360,     2160,      768, 0x08f16c2c
 1,     155520,     155520,     2160,      768, 0x4a0474cb
-0,         52, -9223372036854775808,        1,     1091, 0xa937e32a
+0,         52, -9223372036854775808,        1,     1091, 0xa937e32a, F=0x0
 1,     157680,     157680,     2160,      768, 0x077c760b
-0,         53, -9223372036854775808,        1,     1174, 0xfa50040d
+0,         53, -9223372036854775808,        1,     1174, 0xfa50040d, F=0x0
 1,     159840,     159840,     2160,      768, 0xa5777c2e
 1,     162000,     162000,     2160,      768, 0x0d157ea6
-0,         54, -9223372036854775808,        1,     1293, 0x0c8d2740
+0,         54, -9223372036854775808,        1,     1293, 0x0c8d2740, F=0x0
 1,     164160,     164160,     2160,      768, 0x9bc26f86
-0,         55, -9223372036854775808,        1,     1262, 0x502c0c35
+0,         55, -9223372036854775808,        1,     1262, 0x502c0c35, F=0x0
 1,     166320,     166320,     2160,      768, 0x1a72742d
-0,         56, -9223372036854775808,        1,     1038, 0x5e98c0cd
+0,         56, -9223372036854775808,        1,     1038, 0x5e98c0cd, F=0x0
 1,     168480,     168480,     2160,      768, 0xa5bb6bbb
 1,     170640,     170640,     2160,      768, 0x48496c4c
-0,         57, -9223372036854775808,        1,     1362, 0x256e43cf
+0,         57, -9223372036854775808,        1,     1362, 0x256e43cf, F=0x0
 1,     172800,     172800,     2160,      768, 0x800d78f0
-0,         58, -9223372036854775808,        1,     1200, 0x29e6f055
+0,         58, -9223372036854775808,        1,     1200, 0x29e6f055, F=0x0
 1,     174960,     174960,     2160,      768, 0x40db840c
 1,     177120,     177120,     2160,      768, 0xadc96a6b
-0,         59, -9223372036854775808,        1,     1495, 0x88e9b973
+0,         59, -9223372036854775808,        1,     1495, 0x88e9b973, F=0x0
 1,     179280,     179280,     2160,      768, 0xff986b03
-0,         60, -9223372036854775808,        1,     1386, 0x849297d2
+0,         60, -9223372036854775808,        1,     1386, 0x849297d2, F=0x0
 1,     181440,     181440,     2160,      768, 0x152473d6
-0,         61, -9223372036854775808,        1,     1572, 0x63b7dc79
+0,         61, -9223372036854775808,        1,     1572, 0x63b7dc79, F=0x0
 1,     183600,     183600,     2160,      768, 0x01567323
 1,     185760,     185760,     2160,      768, 0xe5f26fe5
-0,         62, -9223372036854775808,        1,     1190, 0x32ccf4cb
+0,         62, -9223372036854775808,        1,     1190, 0x32ccf4cb, F=0x0
 1,     187920,     187920,     2160,      768, 0xa8fd72cd
-0,         63, -9223372036854775808,        1,     1395, 0xa6ec4ae9
+0,         63, -9223372036854775808,        1,     1395, 0xa6ec4ae9, F=0x0
 1,     190080,     190080,     2160,      768, 0x8857655b
 0,         64, -9223372036854775808,        1,     5692, 0x81aed6f3
 1,     192240,     192240,     2160,      768, 0x84017b13
 1,     194400,     194400,     2160,      768, 0xe6a968b3
-0,         65, -9223372036854775808,        1,     1335, 0xe98a5497
+0,         65, -9223372036854775808,        1,     1335, 0xe98a5497, F=0x0
 1,     196560,     196560,     2160,      768, 0xb03a7566
-0,         66, -9223372036854775808,        1,     1361, 0x8ae15ab5
+0,         66, -9223372036854775808,        1,     1361, 0x8ae15ab5, F=0x0
 1,     198720,     198720,     2160,      768, 0x8bea5f62
 1,     200880,     200880,     2160,      768, 0xac7570b0
-0,         67, -9223372036854775808,        1,     1525, 0xed2bc1e8
+0,         67, -9223372036854775808,        1,     1525, 0xed2bc1e8, F=0x0
 1,     203040,     203040,     2160,      768, 0x11306fac
-0,         68, -9223372036854775808,        1,     1570, 0xba70d74b
+0,         68, -9223372036854775808,        1,     1570, 0xba70d74b, F=0x0
 1,     205200,     205200,     2160,      768, 0xf2af5b28
-0,         69, -9223372036854775808,        1,     1349, 0xd97a687d
+0,         69, -9223372036854775808,        1,     1349, 0xd97a687d, F=0x0
 1,     207360,     207360,     2160,      768, 0x3069681f
 1,     209520,     209520,     2160,      768, 0x7ff07033
-0,         70, -9223372036854775808,        1,     1270, 0xca8c3ca8
+0,         70, -9223372036854775808,        1,     1270, 0xca8c3ca8, F=0x0
 1,     211680,     211680,     2160,      768, 0xd74973f2
-0,         71, -9223372036854775808,        1,     1016, 0x32d0c81a
+0,         71, -9223372036854775808,        1,     1016, 0x32d0c81a, F=0x0
 1,     213840,     213840,     2160,      768, 0xb3627304
 1,     216000,     216000,     2160,      768, 0x11ff7589
-0,         72, -9223372036854775808,        1,      983, 0x536faa97
+0,         72, -9223372036854775808,        1,      983, 0x536faa97, F=0x0
 1,     218160,     218160,     2160,      768, 0x4a156c63
-0,         73, -9223372036854775808,        1,     1111, 0x44ade015
+0,         73, -9223372036854775808,        1,     1111, 0x44ade015, F=0x0
 1,     220320,     220320,     2160,      768, 0xcb036127
-0,         74, -9223372036854775808,        1,     1314, 0xce7c477d
+0,         74, -9223372036854775808,        1,     1314, 0xce7c477d, F=0x0
 1,     222480,     222480,     2160,      768, 0x0b796bb9
 1,     224640,     224640,     2160,      768, 0x1d516c35
-0,         75, -9223372036854775808,        1,     1005, 0x0196b491
+0,         75, -9223372036854775808,        1,     1005, 0x0196b491, F=0x0
 1,     226800,     226800,     2160,      768, 0xa9146da1
-0,         76, -9223372036854775808,        1,     1162, 0xb8f6ebe6
+0,         76, -9223372036854775808,        1,     1162, 0xb8f6ebe6, F=0x0
 1,     228960,     228960,     2160,      768, 0x6d176392
 1,     231120,     231120,     2160,      768, 0x6f966269
-0,         77, -9223372036854775808,        1,     1440, 0xfca67c72
+0,         77, -9223372036854775808,        1,     1440, 0xfca67c72, F=0x0
 1,     233280,     233280,     2160,      768, 0x7ee17724
-0,         78, -9223372036854775808,        1,     1437, 0x491181b1
+0,         78, -9223372036854775808,        1,     1437, 0x491181b1, F=0x0
 1,     235440,     235440,     2160,      768, 0x3f07614a
-0,         79, -9223372036854775808,        1,     1261, 0xf0cd1898
+0,         79, -9223372036854775808,        1,     1261, 0xf0cd1898, F=0x0
 1,     237600,     237600,     2160,      768, 0x49d56945
 1,     239760,     239760,     2160,      768, 0x68eb660a
 0,         80, -9223372036854775808,        1,     5638, 0x3a25a9f2
 1,     241920,     241920,     2160,      768, 0xe7c96677
-0,         81, -9223372036854775808,        1,     1091, 0x67d9c693
+0,         81, -9223372036854775808,        1,     1091, 0x67d9c693, F=0x0
 1,     244080,     244080,     2160,      768, 0x7dc07a35
 1,     246240,     246240,     2160,      768, 0x1e9c6397
-0,         82, -9223372036854775808,        1,      875, 0x52147bb1
+0,         82, -9223372036854775808,        1,      875, 0x52147bb1, F=0x0
 1,     248400,     248400,     2160,      768, 0x93ef5de4
-0,         83, -9223372036854775808,        1,     1188, 0x8522000f
+0,         83, -9223372036854775808,        1,     1188, 0x8522000f, F=0x0
 1,     250560,     250560,     2160,      768, 0x34af6803
-0,         84, -9223372036854775808,        1,     1360, 0x89b82e7b
+0,         84, -9223372036854775808,        1,     1360, 0x89b82e7b, F=0x0
 1,     252720,     252720,     2160,      768, 0x77e068be
 1,     254880,     254880,     2160,      768, 0x65e274de
-0,         85, -9223372036854775808,        1,     1378, 0xe8644914
+0,         85, -9223372036854775808,        1,     1378, 0xe8644914, F=0x0
 1,     257040,     257040,     2160,      768, 0xb7ad6a8a
-0,         86, -9223372036854775808,        1,     1194, 0x89fef83d
+0,         86, -9223372036854775808,        1,     1194, 0x89fef83d, F=0x0
 1,     259200,     259200,     2160,      768, 0x84b3635f
-0,         87, -9223372036854775808,        1,     1422, 0x99daa18b
+0,         87, -9223372036854775808,        1,     1422, 0x99daa18b, F=0x0
 1,     261360,     261360,     2160,      768, 0x066b78f2
 1,     263520,     263520,     2160,      768, 0xda137428
-0,         88, -9223372036854775808,        1,     1049, 0x72a9cec1
+0,         88, -9223372036854775808,        1,     1049, 0x72a9cec1, F=0x0
 1,     265680,     265680,     2160,      768, 0xfd6c7597
-0,         89, -9223372036854775808,        1,     1327, 0x7d15307c
+0,         89, -9223372036854775808,        1,     1327, 0x7d15307c, F=0x0
 1,     267840,     267840,     2160,      768, 0x8d766d40
diff --git a/tests/ref/fate/lossless-tak b/tests/ref/fate/lossless-tak
new file mode 100644
index 0000000..9e9ba47
--- /dev/null
+++ b/tests/ref/fate/lossless-tak
@@ -0,0 +1 @@
+CRC=0x4ec0971f
diff --git a/tests/ref/fate/mapchan-6ch-extract-2 b/tests/ref/fate/mapchan-6ch-extract-2
new file mode 100644
index 0000000..98c8540
--- /dev/null
+++ b/tests/ref/fate/mapchan-6ch-extract-2
@@ -0,0 +1,2 @@
+6f091fe8c0be88c75921731dc9f74314
+5c2d162b9024329eb367295d37b8ca0a
diff --git a/tests/ref/fate/mapchan-6ch-extract-2-downmix-mono b/tests/ref/fate/mapchan-6ch-extract-2-downmix-mono
new file mode 100644
index 0000000..f42de0c
--- /dev/null
+++ b/tests/ref/fate/mapchan-6ch-extract-2-downmix-mono
@@ -0,0 +1 @@
+959645ed73e6d08d8f1e947eac5d0b92
diff --git a/tests/ref/fate/mapchan-silent-mono b/tests/ref/fate/mapchan-silent-mono
new file mode 100644
index 0000000..a867e3b
--- /dev/null
+++ b/tests/ref/fate/mapchan-silent-mono
@@ -0,0 +1 @@
+4f5148f08587a4b9794aa52aec7852ac
diff --git a/tests/ref/fate/mjpegb b/tests/ref/fate/mjpegb
index e4887f4..ef8a00b 100644
--- a/tests/ref/fate/mjpegb
+++ b/tests/ref/fate/mjpegb
@@ -1,11 +1,11 @@
-#tb 0: 1/1200
-0,          0,          0,        0,    38400, 0x45311080
-0,        100,        100,        0,    38400, 0x9474f731
-0,        200,        200,        0,    38400, 0x429ebb12
-0,        300,        300,        0,    38400, 0x472c199a
-0,        400,        400,        0,    38400, 0xefd49dae
-0,        500,        500,        0,    38400, 0x78627fa9
-0,        600,        600,        0,    38400, 0x2a8d9148
-0,        700,        700,        0,    38400, 0x21cc6738
-0,        800,        800,        0,    38400, 0x0bc4703f
-0,        900,        900,        0,    38400, 0x1ddcc035
+#tb 0: 1/12
+0,          0,          0,        1,    38400, 0x45311080
+0,          1,          1,        1,    38400, 0x9474f731
+0,          2,          2,        1,    38400, 0x429ebb12
+0,          3,          3,        1,    38400, 0x472c199a
+0,          4,          4,        1,    38400, 0xefd49dae
+0,          5,          5,        1,    38400, 0x78627fa9
+0,          6,          6,        1,    38400, 0x2a8d9148
+0,          7,          7,        1,    38400, 0x21cc6738
+0,          8,          8,        1,    38400, 0x0bc4703f
+0,          9,          9,        1,    38400, 0x1ddcc035
diff --git a/tests/ref/fate/motionpixels b/tests/ref/fate/motionpixels
index 97d8edf..c875275 100644
--- a/tests/ref/fate/motionpixels
+++ b/tests/ref/fate/motionpixels
@@ -1,112 +1,112 @@
 #tb 0: 66667/1000000
 0,          0,          0,        1,   230400, 0xee05b509
-0,          1,          1,        1,   230400, 0x71048964
-0,          2,          2,        1,   230400, 0x2ebe4ba1
-0,          3,          3,        1,   230400, 0xeedc45a6
-0,          4,          4,        1,   230400, 0x218e8656
-0,          5,          5,        1,   230400, 0x5792b17e
-0,          6,          6,        1,   230400, 0x51b0a062
-0,          7,          7,        1,   230400, 0x5dc4fd9c
-0,          8,          8,        1,   230400, 0x9b0261b1
-0,          9,          9,        1,   230400, 0x35086ffc
-0,         10,         10,        1,   230400, 0xcf9352ff
-0,         11,         11,        1,   230400, 0x0b5139a1
-0,         12,         12,        1,   230400, 0x22e8a31e
-0,         13,         13,        1,   230400, 0x82f61a81
-0,         14,         14,        1,   230400, 0xc5741ab5
-0,         15,         15,        1,   230400, 0xb5e7b2ff
-0,         16,         16,        1,   230400, 0x583289ca
-0,         17,         17,        1,   230400, 0xee52afbb
-0,         18,         18,        1,   230400, 0xfdb4dc1a
-0,         19,         19,        1,   230400, 0xf5ce99c0
-0,         20,         20,        1,   230400, 0xae222255
-0,         21,         21,        1,   230400, 0xc4f4439d
-0,         22,         22,        1,   230400, 0x1758f224
-0,         23,         23,        1,   230400, 0x5f517926
-0,         24,         24,        1,   230400, 0x73a8bed8
-0,         25,         25,        1,   230400, 0x7ef8410c
-0,         26,         26,        1,   230400, 0xfcb693c7
-0,         27,         27,        1,   230400, 0x5292832e
-0,         28,         28,        1,   230400, 0x591261d7
-0,         29,         29,        1,   230400, 0x28cca691
-0,         30,         30,        1,   230400, 0x22cf40ef
-0,         31,         31,        1,   230400, 0x517b10f9
-0,         32,         32,        1,   230400, 0x8197e939
-0,         33,         33,        1,   230400, 0x9654ffdb
-0,         34,         34,        1,   230400, 0x803f10dd
-0,         35,         35,        1,   230400, 0xff9f67af
-0,         36,         36,        1,   230400, 0x4847244c
-0,         37,         37,        1,   230400, 0xff31638f
-0,         38,         38,        1,   230400, 0x9692def5
-0,         39,         39,        1,   230400, 0x67f0a5fb
-0,         40,         40,        1,   230400, 0xce192074
-0,         41,         41,        1,   230400, 0x33d6c4a5
-0,         42,         42,        1,   230400, 0xaf7b5a03
-0,         43,         43,        1,   230400, 0xd956b0c0
-0,         44,         44,        1,   230400, 0x58ff1a65
-0,         45,         45,        1,   230400, 0x044758a1
-0,         46,         46,        1,   230400, 0xe8045b65
-0,         47,         47,        1,   230400, 0xf504c5fb
-0,         48,         48,        1,   230400, 0x17a9a2b0
-0,         49,         49,        1,   230400, 0xf68bab8c
-0,         50,         50,        1,   230400, 0xd06dd0cb
-0,         51,         51,        1,   230400, 0xc47d2673
-0,         52,         52,        1,   230400, 0x2112f291
-0,         53,         53,        1,   230400, 0x4c07c83c
-0,         54,         54,        1,   230400, 0x22ca0113
-0,         55,         55,        1,   230400, 0x25b0c8b1
-0,         56,         56,        1,   230400, 0xb6afc645
-0,         57,         57,        1,   230400, 0x663b1c09
-0,         58,         58,        1,   230400, 0x9006ef1f
-0,         59,         59,        1,   230400, 0x54f81b11
-0,         60,         60,        1,   230400, 0x456b79f2
-0,         61,         61,        1,   230400, 0xb08f24d0
-0,         62,         62,        1,   230400, 0x652ad875
-0,         63,         63,        1,   230400, 0xc6ecd67f
-0,         64,         64,        1,   230400, 0x78dad721
-0,         65,         65,        1,   230400, 0x1d2a4f71
-0,         66,         66,        1,   230400, 0xc71721d1
-0,         67,         67,        1,   230400, 0x64e3a7df
-0,         68,         68,        1,   230400, 0x3bb18e71
-0,         69,         69,        1,   230400, 0xb571d58c
-0,         70,         70,        1,   230400, 0xdae6ed5c
-0,         71,         71,        1,   230400, 0xdd91504b
-0,         72,         72,        1,   230400, 0xd5a807a5
-0,         73,         73,        1,   230400, 0x39a67b03
-0,         74,         74,        1,   230400, 0xe245c8ac
-0,         75,         75,        1,   230400, 0x5b0d7858
-0,         76,         76,        1,   230400, 0x501b8097
-0,         77,         77,        1,   230400, 0xf7b10d48
-0,         78,         78,        1,   230400, 0x769db0bd
-0,         79,         79,        1,   230400, 0x600f1086
-0,         80,         80,        1,   230400, 0x874f5565
-0,         81,         81,        1,   230400, 0x14322f73
-0,         82,         82,        1,   230400, 0x0eaa36a5
-0,         83,         83,        1,   230400, 0x97178d13
-0,         84,         84,        1,   230400, 0xd4c7a0d1
-0,         85,         85,        1,   230400, 0x1d424ec8
-0,         86,         86,        1,   230400, 0x695ad8d9
-0,         87,         87,        1,   230400, 0xe7cc3ecf
-0,         88,         88,        1,   230400, 0xfd25fd8c
-0,         89,         89,        1,   230400, 0xef4bc203
-0,         90,         90,        1,   230400, 0x2a113bec
-0,         91,         91,        1,   230400, 0x6e7ad403
-0,         92,         92,        1,   230400, 0xc6714d2b
-0,         93,         93,        1,   230400, 0x77df8ba6
-0,         94,         94,        1,   230400, 0xcd283106
-0,         95,         95,        1,   230400, 0xcb95676f
-0,         96,         96,        1,   230400, 0xb0b70393
-0,         97,         97,        1,   230400, 0x4c40bd63
-0,         98,         98,        1,   230400, 0x557e8ccf
-0,         99,         99,        1,   230400, 0x9d5934b2
-0,        100,        100,        1,   230400, 0x43c1793f
-0,        101,        101,        1,   230400, 0x0232361e
-0,        102,        102,        1,   230400, 0x92ed91e4
-0,        103,        103,        1,   230400, 0x99769789
-0,        104,        104,        1,   230400, 0xd49c2c5b
-0,        105,        105,        1,   230400, 0x66b03495
-0,        106,        106,        1,   230400, 0xb88a4658
-0,        107,        107,        1,   230400, 0x9c21e4c2
-0,        108,        108,        1,   230400, 0xb343f372
-0,        109,        109,        1,   230400, 0xf7f1e588
-0,        110,        110,        1,   230400, 0x9682bdb2
+0,          1,          1,        1,   230400, 0x23b28b24
+0,          2,          2,        1,   230400, 0x4a4d6007
+0,          3,          3,        1,   230400, 0xe5550693
+0,          4,          4,        1,   230400, 0xad4905a3
+0,          5,          5,        1,   230400, 0xc83b9030
+0,          6,          6,        1,   230400, 0xbc73a26a
+0,          7,          7,        1,   230400, 0x7065ff8a
+0,          8,          8,        1,   230400, 0x65bc7675
+0,          9,          9,        1,   230400, 0xc245737f
+0,         10,         10,        1,   230400, 0x77e6c1ed
+0,         11,         11,        1,   230400, 0x6761d73a
+0,         12,         12,        1,   230400, 0x6207b8f8
+0,         13,         13,        1,   230400, 0xa3691862
+0,         14,         14,        1,   230400, 0x83fbfc24
+0,         15,         15,        1,   230400, 0xe1c34ef0
+0,         16,         16,        1,   230400, 0xd7b50e8e
+0,         17,         17,        1,   230400, 0x5b5e2f29
+0,         18,         18,        1,   230400, 0xca7825e5
+0,         19,         19,        1,   230400, 0xb4c7b4a9
+0,         20,         20,        1,   230400, 0xc35513b5
+0,         21,         21,        1,   230400, 0x36117834
+0,         22,         22,        1,   230400, 0x8af035d7
+0,         23,         23,        1,   230400, 0x25c50a2e
+0,         24,         24,        1,   230400, 0x52f54107
+0,         25,         25,        1,   230400, 0xaddca5f9
+0,         26,         26,        1,   230400, 0x3b1fe64c
+0,         27,         27,        1,   230400, 0xcd52de15
+0,         28,         28,        1,   230400, 0xfaa4f7fa
+0,         29,         29,        1,   230400, 0xce5b3221
+0,         30,         30,        1,   230400, 0xb2c3d9ba
+0,         31,         31,        1,   230400, 0xf6ec95e9
+0,         32,         32,        1,   230400, 0xfa7ebd18
+0,         33,         33,        1,   230400, 0xb6e50465
+0,         34,         34,        1,   230400, 0xd48ceee9
+0,         35,         35,        1,   230400, 0x333605cf
+0,         36,         36,        1,   230400, 0xe7ccf362
+0,         37,         37,        1,   230400, 0x39f07b83
+0,         38,         38,        1,   230400, 0xd6450b2e
+0,         39,         39,        1,   230400, 0x2029ec12
+0,         40,         40,        1,   230400, 0x15d7762e
+0,         41,         41,        1,   230400, 0x0d69506d
+0,         42,         42,        1,   230400, 0xcf2ef066
+0,         43,         43,        1,   230400, 0x2c145df0
+0,         44,         44,        1,   230400, 0x153d7fe7
+0,         45,         45,        1,   230400, 0x98846aea
+0,         46,         46,        1,   230400, 0xc0347d4e
+0,         47,         47,        1,   230400, 0xda7a58a8
+0,         48,         48,        1,   230400, 0x5724c05e
+0,         49,         49,        1,   230400, 0x9805237b
+0,         50,         50,        1,   230400, 0x2f5f0d70
+0,         51,         51,        1,   230400, 0xb1271014
+0,         52,         52,        1,   230400, 0x6cb29d9c
+0,         53,         53,        1,   230400, 0x4f91fdb4
+0,         54,         54,        1,   230400, 0x274b3f30
+0,         55,         55,        1,   230400, 0xdfc508e8
+0,         56,         56,        1,   230400, 0x16e974ef
+0,         57,         57,        1,   230400, 0x98fae336
+0,         58,         58,        1,   230400, 0xbf265f84
+0,         59,         59,        1,   230400, 0x75cf323b
+0,         60,         60,        1,   230400, 0xdb3481f7
+0,         61,         61,        1,   230400, 0xb8453df5
+0,         62,         62,        1,   230400, 0xd4598deb
+0,         63,         63,        1,   230400, 0x4dc19cf6
+0,         64,         64,        1,   230400, 0xa8d1b340
+0,         65,         65,        1,   230400, 0x1f98aa27
+0,         66,         66,        1,   230400, 0x505c0687
+0,         67,         67,        1,   230400, 0x86179997
+0,         68,         68,        1,   230400, 0x7e28cc7d
+0,         69,         69,        1,   230400, 0x0a81c0bc
+0,         70,         70,        1,   230400, 0x71cc0c9a
+0,         71,         71,        1,   230400, 0x8c01340f
+0,         72,         72,        1,   230400, 0x4afea48a
+0,         73,         73,        1,   230400, 0x7dc88c26
+0,         74,         74,        1,   230400, 0x4155fbbb
+0,         75,         75,        1,   230400, 0xb1ec2d6b
+0,         76,         76,        1,   230400, 0x6986ee65
+0,         77,         77,        1,   230400, 0x8ff9a311
+0,         78,         78,        1,   230400, 0x36c21c52
+0,         79,         79,        1,   230400, 0xdb0fad2e
+0,         80,         80,        1,   230400, 0xc7a83c34
+0,         81,         81,        1,   230400, 0x8bd97389
+0,         82,         82,        1,   230400, 0x6dd8f0d6
+0,         83,         83,        1,   230400, 0x228e2076
+0,         84,         84,        1,   230400, 0x22544f03
+0,         85,         85,        1,   230400, 0x938084ef
+0,         86,         86,        1,   230400, 0xb002cd81
+0,         87,         87,        1,   230400, 0xe58d3339
+0,         88,         88,        1,   230400, 0x02470a69
+0,         89,         89,        1,   230400, 0xa5c51328
+0,         90,         90,        1,   230400, 0x1a6e37ec
+0,         91,         91,        1,   230400, 0x8f40563c
+0,         92,         92,        1,   230400, 0x30f9095f
+0,         93,         93,        1,   230400, 0x6227f0e8
+0,         94,         94,        1,   230400, 0xdca3596d
+0,         95,         95,        1,   230400, 0x30938988
+0,         96,         96,        1,   230400, 0x28bdc666
+0,         97,         97,        1,   230400, 0x6c534265
+0,         98,         98,        1,   230400, 0x6ea56d2d
+0,         99,         99,        1,   230400, 0x125f3808
+0,        100,        100,        1,   230400, 0x92a41d2f
+0,        101,        101,        1,   230400, 0xf1cf2410
+0,        102,        102,        1,   230400, 0x1bea1204
+0,        103,        103,        1,   230400, 0x817e60f9
+0,        104,        104,        1,   230400, 0x9f6c720e
+0,        105,        105,        1,   230400, 0xf1a43a2f
+0,        106,        106,        1,   230400, 0x5e5e0b7f
+0,        107,        107,        1,   230400, 0x7f526bcf
+0,        108,        108,        1,   230400, 0x63a846ed
+0,        109,        109,        1,   230400, 0x94400af9
+0,        110,        110,        1,   230400, 0x51f4241e
diff --git a/tests/ref/fate/mpeg2-field-enc b/tests/ref/fate/mpeg2-field-enc
index 079aae4..903adb5 100644
--- a/tests/ref/fate/mpeg2-field-enc
+++ b/tests/ref/fate/mpeg2-field-enc
@@ -1,32 +1,32 @@
-#tb 0: 1/90000
-0,      32400,      32400,        0,   622080, 0xb3b66c5c
-0,      36000,      36000,        0,   622080, 0x088ec02b
-0,      39600,      39600,        0,   622080, 0x7a36db21
-0,      43200,      43200,        0,   622080, 0x541b286f
-0,      46800,      46800,        0,   622080, 0xb6c3e590
-0,      50400,      50400,        0,   622080, 0x39dbed51
-0,      54000,      54000,        0,   622080, 0x973dc728
-0,      57600,      57600,        0,   622080, 0xd7a4f804
-0,      61200,      61200,        0,   622080, 0xa2484762
-0,      64800,      64800,        0,   622080, 0x0cd268d1
-0,      68400,      68400,        0,   622080, 0x72eb663d
-0,      72000,      72000,        0,   622080, 0x8fdbac59
-0,      75600,      75600,        0,   622080, 0xa6f4feb9
-0,      79200,      79200,        0,   622080, 0xadb828c6
-0,      82800,      82800,        0,   622080, 0xea630a63
-0,      86400,      86400,        0,   622080, 0xa901d925
-0,      90000,      90000,        0,   622080, 0xac5e7087
-0,      93600,      93600,        0,   622080, 0x10274a2b
-0,      97200,      97200,        0,   622080, 0x143d541c
-0,     100800,     100800,        0,   622080, 0xee94c93a
-0,     104400,     104400,        0,   622080, 0xca030208
-0,     108000,     108000,        0,   622080, 0x26f30ead
-0,     111600,     111600,        0,   622080, 0xfc22f32c
-0,     115200,     115200,        0,   622080, 0x940a5ff8
-0,     118800,     118800,        0,   622080, 0x2164f805
-0,     122400,     122400,        0,   622080, 0xa76f5aba
-0,     126000,     126000,        0,   622080, 0x8c311471
-0,     129600,     129600,        0,   622080, 0xa45e1d95
-0,     133200,     133200,        0,   622080, 0x6cc61d6c
-0,     136800,     136800,        0,   622080, 0x6983b417
-0,     140400,     140400,        0,   622080, 0x982363c0
+#tb 0: 1/25
+0,          9,          9,        1,   622080, 0xb3b66c5c
+0,         10,         10,        1,   622080, 0x088ec02b
+0,         11,         11,        1,   622080, 0x7a36db21
+0,         12,         12,        1,   622080, 0x541b286f
+0,         13,         13,        1,   622080, 0xb6c3e590
+0,         14,         14,        1,   622080, 0x39dbed51
+0,         15,         15,        1,   622080, 0x973dc728
+0,         16,         16,        1,   622080, 0xd7a4f804
+0,         17,         17,        1,   622080, 0xa2484762
+0,         18,         18,        1,   622080, 0x0cd268d1
+0,         19,         19,        1,   622080, 0x72eb663d
+0,         20,         20,        1,   622080, 0x8fdbac59
+0,         21,         21,        1,   622080, 0xa6f4feb9
+0,         22,         22,        1,   622080, 0xadb828c6
+0,         23,         23,        1,   622080, 0xea630a63
+0,         24,         24,        1,   622080, 0xa901d925
+0,         25,         25,        1,   622080, 0xac5e7087
+0,         26,         26,        1,   622080, 0x10274a2b
+0,         27,         27,        1,   622080, 0x143d541c
+0,         28,         28,        1,   622080, 0xee94c93a
+0,         29,         29,        1,   622080, 0xca030208
+0,         30,         30,        1,   622080, 0x26f30ead
+0,         31,         31,        1,   622080, 0xfc22f32c
+0,         32,         32,        1,   622080, 0x940a5ff8
+0,         33,         33,        1,   622080, 0x2164f805
+0,         34,         34,        1,   622080, 0xa76f5aba
+0,         35,         35,        1,   622080, 0x8c311471
+0,         36,         36,        1,   622080, 0xa45e1d95
+0,         37,         37,        1,   622080, 0x6cc61d6c
+0,         38,         38,        1,   622080, 0x6983b417
+0,         39,         39,        1,   622080, 0x982363c0
diff --git a/tests/ref/fate/msvideo1-16bit b/tests/ref/fate/msvideo1-16bit
index fffdea2..f5c0e647 100644
--- a/tests/ref/fate/msvideo1-16bit
+++ b/tests/ref/fate/msvideo1-16bit
@@ -1,31 +1,31 @@
 #tb 0: 33369/500000
-0,          0,          0,        1,    65712, 0x917e0076
-0,          1,          1,        1,    65712, 0xfe76fd1f
-0,          2,          2,        1,    65712, 0xd85820ee
-0,          3,          3,        1,    65712, 0x1b410f6e
-0,          4,          4,        1,    65712, 0x53c50436
-0,          5,          5,        1,    65712, 0xa191044d
-0,          6,          6,        1,    65712, 0xcf02ff1f
-0,          7,          7,        1,    65712, 0xc2abf85f
-0,          8,          8,        1,    65712, 0xe273087e
-0,          9,          9,        1,    65712, 0x087d0936
-0,         10,         10,        1,    65712, 0x4e4f2e96
-0,         11,         11,        1,    65712, 0x91b51896
-0,         12,         12,        1,    65712, 0x2798450e
-0,         13,         13,        1,    65712, 0x9fea1d06
-0,         14,         14,        1,    65712, 0xc64a2506
-0,         15,         15,        1,    65712, 0x0551fe07
-0,         16,         16,        1,    65712, 0xc64a042e
-0,         17,         17,        1,    65712, 0xf3680dc6
-0,         18,         18,        1,    65712, 0x2ea5356e
-0,         19,         19,        1,    65712, 0x0315ed3f
-0,         20,         20,        1,    65712, 0xc1d1f917
-0,         21,         21,        1,    65712, 0xc0f6e607
-0,         22,         22,        1,    65712, 0x5b0a092e
-0,         23,         23,        1,    65712, 0x1551f16f
-0,         24,         24,        1,    65712, 0x8440ee87
-0,         25,         25,        1,    65712, 0xf7581ae6
-0,         26,         26,        1,    65712, 0xee67037e
-0,         27,         27,        1,    65712, 0x4a212ca6
-0,         28,         28,        1,    65712, 0x693e0aa6
-0,         29,         29,        1,    65712, 0x13e31116
+0,          0,          0,        1,    65712, 0x03ff25b8
+0,          1,          1,        1,    65712, 0xfca02276
+0,          2,          2,        1,    65712, 0xd23646e4
+0,          3,          3,        1,    65712, 0x9ea43556
+0,          4,          4,        1,    65712, 0x47412948
+0,          5,          5,        1,    65712, 0x667230c9
+0,          6,          6,        1,    65712, 0x8224247a
+0,          7,          7,        1,    65712, 0x9c0f1d71
+0,          8,          8,        1,    65712, 0x4fbb2e11
+0,          9,          9,        1,    65712, 0x0e4a2e34
+0,         10,         10,        1,    65712, 0xd58954c8
+0,         11,         11,        1,    65712, 0x131d3e2c
+0,         12,         12,        1,    65712, 0x3b686bc7
+0,         13,         13,        1,    65712, 0xbea342a7
+0,         14,         14,        1,    65712, 0xbdff4ac7
+0,         15,         15,        1,    65712, 0x215e22ab
+0,         16,         16,        1,    65712, 0xa9f0295f
+0,         17,         17,        1,    65712, 0x46fb32f3
+0,         18,         18,        1,    65712, 0xd8be5bee
+0,         19,         19,        1,    65712, 0x526411b6
+0,         20,         20,        1,    65712, 0x53951e21
+0,         21,         21,        1,    65712, 0x54a70ab3
+0,         22,         22,        1,    65712, 0xcc872e7a
+0,         23,         23,        1,    65712, 0x06b2164c
+0,         24,         24,        1,    65712, 0x1ae5135f
+0,         25,         25,        1,    65712, 0x8d8a40b4
+0,         26,         26,        1,    65712, 0x3d732893
+0,         27,         27,        1,    65712, 0x239a52a8
+0,         28,         28,        1,    65712, 0xf6bd2fc9
+0,         29,         29,        1,    65712, 0x40b336c4
diff --git a/tests/ref/fate/mtv b/tests/ref/fate/mtv
index 4f8f616..a781c08 100644
--- a/tests/ref/fate/mtv
+++ b/tests/ref/fate/mtv
@@ -133,6 +133,6 @@
 1,     104832,     104832,     1152,      418, 0xa105cdcc
 1,     105984,     105984,     1152,      418, 0x1477ba58
 1,     107136,     107136,     1152,      418, 0x8d0dcdb2
-0,         39,         39,        1,     3584, 0x0354c435
+0,         39,         39,        1,     3584, 0x0354c435, F=0x3
 1,     108288,     108288,     1152,      418, 0x0d7cbef4
 1,     109440,     109440,     1152,      294, 0x5e2b87c4
diff --git a/tests/ref/fate/mxf-demux b/tests/ref/fate/mxf-demux
index e162775..c67c4ab 100644
--- a/tests/ref/fate/mxf-demux
+++ b/tests/ref/fate/mxf-demux
@@ -2,98 +2,98 @@
 #tb 1: 1/25
 0,          0, -9223372036854775808,        1,     8468, 0xc0855553
 1,          0,          0,       50,    32000, 0x479155e6
-0,          1, -9223372036854775808,        1,     3814, 0xa10783b4
-0,          2, -9223372036854775808,        1,     3747, 0xb7bf6973
-0,          3, -9223372036854775808,        1,     3705, 0x5462a600
-0,          4, -9223372036854775808,        1,     3704, 0x1e564943
-0,          5, -9223372036854775808,        1,     3760, 0x10464b9a
-0,          6, -9223372036854775808,        1,     3799, 0xd41d6dcf
-0,          7, -9223372036854775808,        1,     3832, 0x5cf6999e
-0,          8, -9223372036854775808,        1,     3778, 0xe5fc7b9e
-0,          9, -9223372036854775808,        1,    38193, 0xd34e5dd4
+0,          1, -9223372036854775808,        1,     3814, 0xa10783b4, F=0x0
+0,          2, -9223372036854775808,        1,     3747, 0xb7bf6973, F=0x0
+0,          3, -9223372036854775808,        1,     3705, 0x5462a600, F=0x0
+0,          4, -9223372036854775808,        1,     3704, 0x1e564943, F=0x0
+0,          5, -9223372036854775808,        1,     3760, 0x10464b9a, F=0x0
+0,          6, -9223372036854775808,        1,     3799, 0xd41d6dcf, F=0x0
+0,          7, -9223372036854775808,        1,     3832, 0x5cf6999e, F=0x0
+0,          8, -9223372036854775808,        1,     3778, 0xe5fc7b9e, F=0x0
+0,          9, -9223372036854775808,        1,    38193, 0xd34e5dd4, F=0x0
 0,         10, -9223372036854775808,        1,     8520, 0x2a203e68
-0,         11, -9223372036854775808,        1,     3832, 0xe4c4b2fe
-0,         12, -9223372036854775808,        1,     3787, 0x0cf95fee
-0,         13, -9223372036854775808,        1,     3766, 0x9e019d14
-0,         14, -9223372036854775808,        1,     3785, 0x0ea9ae75
-0,         15, -9223372036854775808,        1,     3703, 0x11d349ff
-0,         16, -9223372036854775808,        1,     3731, 0x5cf358ef
-0,         17, -9223372036854775808,        1,     3785, 0x01c8962f
-0,         18, -9223372036854775808,        1,     3741, 0xb2c47d53
-0,         19, -9223372036854775808,        1,    38150, 0x08fa1f55
+0,         11, -9223372036854775808,        1,     3832, 0xe4c4b2fe, F=0x0
+0,         12, -9223372036854775808,        1,     3787, 0x0cf95fee, F=0x0
+0,         13, -9223372036854775808,        1,     3766, 0x9e019d14, F=0x0
+0,         14, -9223372036854775808,        1,     3785, 0x0ea9ae75, F=0x0
+0,         15, -9223372036854775808,        1,     3703, 0x11d349ff, F=0x0
+0,         16, -9223372036854775808,        1,     3731, 0x5cf358ef, F=0x0
+0,         17, -9223372036854775808,        1,     3785, 0x01c8962f, F=0x0
+0,         18, -9223372036854775808,        1,     3741, 0xb2c47d53, F=0x0
+0,         19, -9223372036854775808,        1,    38150, 0x08fa1f55, F=0x0
 0,         20, -9223372036854775808,        1,     8487, 0x0c234b9a
-0,         21, -9223372036854775808,        1,     3791, 0x831192ef
-0,         22, -9223372036854775808,        1,     3612, 0x598944fb
-0,         23, -9223372036854775808,        1,     3710, 0xccbb711a
-0,         24, -9223372036854775808,        1,     3864, 0x4385966e
-0,         25, -9223372036854775808,        1,     3919, 0x24e2abc3
-0,         26, -9223372036854775808,        1,     3777, 0x210c6219
-0,         27, -9223372036854775808,        1,     3811, 0x23bf68c2
-0,         28, -9223372036854775808,        1,     3802, 0x52688862
-0,         29, -9223372036854775808,        1,    38027, 0x3d5aa8b9
+0,         21, -9223372036854775808,        1,     3791, 0x831192ef, F=0x0
+0,         22, -9223372036854775808,        1,     3612, 0x598944fb, F=0x0
+0,         23, -9223372036854775808,        1,     3710, 0xccbb711a, F=0x0
+0,         24, -9223372036854775808,        1,     3864, 0x4385966e, F=0x0
+0,         25, -9223372036854775808,        1,     3919, 0x24e2abc3, F=0x0
+0,         26, -9223372036854775808,        1,     3777, 0x210c6219, F=0x0
+0,         27, -9223372036854775808,        1,     3811, 0x23bf68c2, F=0x0
+0,         28, -9223372036854775808,        1,     3802, 0x52688862, F=0x0
+0,         29, -9223372036854775808,        1,    38027, 0x3d5aa8b9, F=0x0
 0,         30, -9223372036854775808,        1,     8333, 0x617de950
-0,         31, -9223372036854775808,        1,     3831, 0x13fad8fc
-0,         32, -9223372036854775808,        1,     3719, 0xbc317470
-0,         33, -9223372036854775808,        1,     3761, 0xeac460b6
-0,         34, -9223372036854775808,        1,     3637, 0x27d64b32
-0,         35, -9223372036854775808,        1,     3666, 0xf0f700a5
-0,         36, -9223372036854775808,        1,     3788, 0x1c4662a8
-0,         37, -9223372036854775808,        1,     3960, 0xef6b9e99
-0,         38, -9223372036854775808,        1,     3793, 0x3a6ca832
-0,         39, -9223372036854775808,        1,    38312, 0xce1317cc
+0,         31, -9223372036854775808,        1,     3831, 0x13fad8fc, F=0x0
+0,         32, -9223372036854775808,        1,     3719, 0xbc317470, F=0x0
+0,         33, -9223372036854775808,        1,     3761, 0xeac460b6, F=0x0
+0,         34, -9223372036854775808,        1,     3637, 0x27d64b32, F=0x0
+0,         35, -9223372036854775808,        1,     3666, 0xf0f700a5, F=0x0
+0,         36, -9223372036854775808,        1,     3788, 0x1c4662a8, F=0x0
+0,         37, -9223372036854775808,        1,     3960, 0xef6b9e99, F=0x0
+0,         38, -9223372036854775808,        1,     3793, 0x3a6ca832, F=0x0
+0,         39, -9223372036854775808,        1,    38312, 0xce1317cc, F=0x0
 0,         40, -9223372036854775808,        1,     8548, 0x4ca944d4
-0,         41, -9223372036854775808,        1,     3866, 0x4e85bf0f
-0,         42, -9223372036854775808,        1,     3644, 0x030338e5
-0,         43, -9223372036854775808,        1,     3634, 0xa95f4512
-0,         44, -9223372036854775808,        1,     3925, 0x7583ba86
-0,         45, -9223372036854775808,        1,     3675, 0x979f423f
-0,         46, -9223372036854775808,        1,     3703, 0x11375f7a
-0,         47, -9223372036854775808,        1,     3705, 0xb7de5d16
-0,         48, -9223372036854775808,        1,     3688, 0x1db45852
-0,         49, -9223372036854775808,        1,    38412, 0x2ee26a63
+0,         41, -9223372036854775808,        1,     3866, 0x4e85bf0f, F=0x0
+0,         42, -9223372036854775808,        1,     3644, 0x030338e5, F=0x0
+0,         43, -9223372036854775808,        1,     3634, 0xa95f4512, F=0x0
+0,         44, -9223372036854775808,        1,     3925, 0x7583ba86, F=0x0
+0,         45, -9223372036854775808,        1,     3675, 0x979f423f, F=0x0
+0,         46, -9223372036854775808,        1,     3703, 0x11375f7a, F=0x0
+0,         47, -9223372036854775808,        1,     3705, 0xb7de5d16, F=0x0
+0,         48, -9223372036854775808,        1,     3688, 0x1db45852, F=0x0
+0,         49, -9223372036854775808,        1,    38412, 0x2ee26a63, F=0x0
 0,         50, -9223372036854775808,        1,     8385, 0x0bc20a27
 1,         50,         50,       50,    32000, 0x8f7e5009
-0,         51, -9223372036854775808,        1,     3733, 0xa3e2a9a0
-0,         52, -9223372036854775808,        1,     3773, 0x27769caa
-0,         53, -9223372036854775808,        1,     3670, 0xc8335e98
-0,         54, -9223372036854775808,        1,     3596, 0xd6512fb0
-0,         55, -9223372036854775808,        1,     3579, 0xa621fbc2
-0,         56, -9223372036854775808,        1,     3641, 0x2f4f46ca
-0,         57, -9223372036854775808,        1,     3686, 0x0a92385a
-0,         58, -9223372036854775808,        1,     3672, 0xe65137b9
-0,         59, -9223372036854775808,        1,    39065, 0xc723bf8b
+0,         51, -9223372036854775808,        1,     3733, 0xa3e2a9a0, F=0x0
+0,         52, -9223372036854775808,        1,     3773, 0x27769caa, F=0x0
+0,         53, -9223372036854775808,        1,     3670, 0xc8335e98, F=0x0
+0,         54, -9223372036854775808,        1,     3596, 0xd6512fb0, F=0x0
+0,         55, -9223372036854775808,        1,     3579, 0xa621fbc2, F=0x0
+0,         56, -9223372036854775808,        1,     3641, 0x2f4f46ca, F=0x0
+0,         57, -9223372036854775808,        1,     3686, 0x0a92385a, F=0x0
+0,         58, -9223372036854775808,        1,     3672, 0xe65137b9, F=0x0
+0,         59, -9223372036854775808,        1,    39065, 0xc723bf8b, F=0x0
 0,         60, -9223372036854775808,        1,     8611, 0x5d177f40
-0,         61, -9223372036854775808,        1,     3758, 0x33d59966
-0,         62, -9223372036854775808,        1,     3674, 0x54f37902
-0,         63, -9223372036854775808,        1,     3615, 0xa0f045fa
-0,         64, -9223372036854775808,        1,     3719, 0x41cf93ff
-0,         65, -9223372036854775808,        1,     3757, 0x3a1b7e8f
-0,         66, -9223372036854775808,        1,     3762, 0xe7f9714d
-0,         67, -9223372036854775808,        1,     3738, 0x8121805b
-0,         68, -9223372036854775808,        1,     3733, 0x13e262db
-0,         69, -9223372036854775808,        1,    38433, 0x3d58c500
+0,         61, -9223372036854775808,        1,     3758, 0x33d59966, F=0x0
+0,         62, -9223372036854775808,        1,     3674, 0x54f37902, F=0x0
+0,         63, -9223372036854775808,        1,     3615, 0xa0f045fa, F=0x0
+0,         64, -9223372036854775808,        1,     3719, 0x41cf93ff, F=0x0
+0,         65, -9223372036854775808,        1,     3757, 0x3a1b7e8f, F=0x0
+0,         66, -9223372036854775808,        1,     3762, 0xe7f9714d, F=0x0
+0,         67, -9223372036854775808,        1,     3738, 0x8121805b, F=0x0
+0,         68, -9223372036854775808,        1,     3733, 0x13e262db, F=0x0
+0,         69, -9223372036854775808,        1,    38433, 0x3d58c500, F=0x0
 0,         70, -9223372036854775808,        1,     8410, 0xa4f7fd2e
-0,         71, -9223372036854775808,        1,     3711, 0x0e112d3c
-0,         72, -9223372036854775808,        1,     3692, 0xb46574b2
-0,         73, -9223372036854775808,        1,     3563, 0xad43343d
-0,         74, -9223372036854775808,        1,     3613, 0x5cd85c4f
-0,         75, -9223372036854775808,        1,     3653, 0xe15a2853
-0,         76, -9223372036854775808,        1,     3684, 0x9ddd58cb
-0,         77, -9223372036854775808,        1,     3256, 0xd7f89f2e
-0,         78, -9223372036854775808,        1,     3698, 0x2b82624a
-0,         79, -9223372036854775808,        1,    39520, 0xd3f2b7c5
+0,         71, -9223372036854775808,        1,     3711, 0x0e112d3c, F=0x0
+0,         72, -9223372036854775808,        1,     3692, 0xb46574b2, F=0x0
+0,         73, -9223372036854775808,        1,     3563, 0xad43343d, F=0x0
+0,         74, -9223372036854775808,        1,     3613, 0x5cd85c4f, F=0x0
+0,         75, -9223372036854775808,        1,     3653, 0xe15a2853, F=0x0
+0,         76, -9223372036854775808,        1,     3684, 0x9ddd58cb, F=0x0
+0,         77, -9223372036854775808,        1,     3256, 0xd7f89f2e, F=0x0
+0,         78, -9223372036854775808,        1,     3698, 0x2b82624a, F=0x0
+0,         79, -9223372036854775808,        1,    39520, 0xd3f2b7c5, F=0x0
 0,         80, -9223372036854775808,        1,     8493, 0x163559be
-0,         81, -9223372036854775808,        1,     3719, 0x6fa0916f
-0,         82, -9223372036854775808,        1,     3655, 0xa9233de1
-0,         83, -9223372036854775808,        1,     3684, 0xa6125737
-0,         84, -9223372036854775808,        1,     3688, 0xa9da6686
-0,         85, -9223372036854775808,        1,     3685, 0x674d634e
-0,         86, -9223372036854775808,        1,     3677, 0x7a85535d
-0,         87, -9223372036854775808,        1,     3666, 0xce3600a2
-0,         88, -9223372036854775808,        1,     3837, 0x3a7090e1
-0,         89, -9223372036854775808,        1,    38696, 0x12c59cd2
+0,         81, -9223372036854775808,        1,     3719, 0x6fa0916f, F=0x0
+0,         82, -9223372036854775808,        1,     3655, 0xa9233de1, F=0x0
+0,         83, -9223372036854775808,        1,     3684, 0xa6125737, F=0x0
+0,         84, -9223372036854775808,        1,     3688, 0xa9da6686, F=0x0
+0,         85, -9223372036854775808,        1,     3685, 0x674d634e, F=0x0
+0,         86, -9223372036854775808,        1,     3677, 0x7a85535d, F=0x0
+0,         87, -9223372036854775808,        1,     3666, 0xce3600a2, F=0x0
+0,         88, -9223372036854775808,        1,     3837, 0x3a7090e1, F=0x0
+0,         89, -9223372036854775808,        1,    38696, 0x12c59cd2, F=0x0
 0,         90, -9223372036854775808,        1,     8022, 0xd343433f
-0,         91, -9223372036854775808,        1,     5157, 0x440c14e5
-0,         92, -9223372036854775808,        1,     5003, 0xf8e1daff
-0,         93, -9223372036854775808,        1,     4954, 0x89866344
-0,         94, -9223372036854775808,        1,    53664, 0xeb0c4c42
+0,         91, -9223372036854775808,        1,     5157, 0x440c14e5, F=0x0
+0,         92, -9223372036854775808,        1,     5003, 0xf8e1daff, F=0x0
+0,         93, -9223372036854775808,        1,     4954, 0x89866344, F=0x0
+0,         94, -9223372036854775808,        1,    53664, 0xeb0c4c42, F=0x0
diff --git a/tests/ref/fate/nc-demux b/tests/ref/fate/nc-demux
index 1d00f8e..f03aded 100644
--- a/tests/ref/fate/nc-demux
+++ b/tests/ref/fate/nc-demux
@@ -1,92 +1,92 @@
 #tb 0: 1/100
 0,          0, -9223372036854775808,        1,    19787, 0x75e463f3
-0,          1, -9223372036854775808,        1,    11913, 0x0f429c34
-0,          2, -9223372036854775808,        1,    14225, 0xbd3c704c
-0,          3, -9223372036854775808,        1,    10357, 0xbf232393
-0,          4, -9223372036854775808,        1,     9595, 0xf565d39e
-0,          5, -9223372036854775808,        1,     9262, 0x2afd6ce0
-0,          6, -9223372036854775808,        1,    12214, 0x6ae81d9b
-0,          7, -9223372036854775808,        1,    13920, 0x31b5b307
-0,          8, -9223372036854775808,        1,    10164, 0x141eca4e
-0,          9, -9223372036854775808,        1,     9516, 0xd5f2c42b
-0,         10, -9223372036854775808,        1,    10006, 0x80850a76
-0,         11, -9223372036854775808,        1,    11791, 0x10bc2dcd
-0,         12, -9223372036854775808,        1,    13756, 0xda1fee08
-0,         13, -9223372036854775808,        1,    10452, 0xbb3d62b0
-0,         14, -9223372036854775808,        1,     9171, 0x64ae10f6
-0,         15, -9223372036854775808,        1,     8816, 0x31ad8fcb
-0,         16, -9223372036854775808,        1,    13168, 0xea1085ac
-0,         17, -9223372036854775808,        1,    12797, 0x25143d22
-0,         18, -9223372036854775808,        1,    11324, 0x3a54b38e
-0,         19, -9223372036854775808,        1,     9173, 0x8b2bf552
-0,         20, -9223372036854775808,        1,     9247, 0x2e87226b
-0,         21, -9223372036854775808,        1,    14140, 0x1063786c
-0,         22, -9223372036854775808,        1,    14437, 0xde123a17
-0,         23, -9223372036854775808,        1,    11938, 0x3f1168f4
-0,         24, -9223372036854775808,        1,    11966, 0xdd6786ec
-0,         25, -9223372036854775808,        1,    13213, 0x8ab27c58
-0,         26, -9223372036854775808,        1,    11843, 0x90415d8b
-0,         27, -9223372036854775808,        1,    13345, 0x3c0e1793
-0,         28, -9223372036854775808,        1,     9977, 0x74fc7f4b
-0,         29, -9223372036854775808,        1,     9158, 0x0b5426a5
-0,         30, -9223372036854775808,        1,    12715, 0x0035d569
+0,          1, -9223372036854775808,        1,    11913, 0x0f429c34, F=0x0
+0,          2, -9223372036854775808,        1,    14225, 0xbd3c704c, F=0x0
+0,          3, -9223372036854775808,        1,    10357, 0xbf232393, F=0x0
+0,          4, -9223372036854775808,        1,     9595, 0xf565d39e, F=0x0
+0,          5, -9223372036854775808,        1,     9262, 0x2afd6ce0, F=0x0
+0,          6, -9223372036854775808,        1,    12214, 0x6ae81d9b, F=0x0
+0,          7, -9223372036854775808,        1,    13920, 0x31b5b307, F=0x0
+0,          8, -9223372036854775808,        1,    10164, 0x141eca4e, F=0x0
+0,          9, -9223372036854775808,        1,     9516, 0xd5f2c42b, F=0x0
+0,         10, -9223372036854775808,        1,    10006, 0x80850a76, F=0x0
+0,         11, -9223372036854775808,        1,    11791, 0x10bc2dcd, F=0x0
+0,         12, -9223372036854775808,        1,    13756, 0xda1fee08, F=0x0
+0,         13, -9223372036854775808,        1,    10452, 0xbb3d62b0, F=0x0
+0,         14, -9223372036854775808,        1,     9171, 0x64ae10f6, F=0x0
+0,         15, -9223372036854775808,        1,     8816, 0x31ad8fcb, F=0x0
+0,         16, -9223372036854775808,        1,    13168, 0xea1085ac, F=0x0
+0,         17, -9223372036854775808,        1,    12797, 0x25143d22, F=0x0
+0,         18, -9223372036854775808,        1,    11324, 0x3a54b38e, F=0x0
+0,         19, -9223372036854775808,        1,     9173, 0x8b2bf552, F=0x0
+0,         20, -9223372036854775808,        1,     9247, 0x2e87226b, F=0x0
+0,         21, -9223372036854775808,        1,    14140, 0x1063786c, F=0x0
+0,         22, -9223372036854775808,        1,    14437, 0xde123a17, F=0x0
+0,         23, -9223372036854775808,        1,    11938, 0x3f1168f4, F=0x0
+0,         24, -9223372036854775808,        1,    11966, 0xdd6786ec, F=0x0
+0,         25, -9223372036854775808,        1,    13213, 0x8ab27c58, F=0x0
+0,         26, -9223372036854775808,        1,    11843, 0x90415d8b, F=0x0
+0,         27, -9223372036854775808,        1,    13345, 0x3c0e1793, F=0x0
+0,         28, -9223372036854775808,        1,     9977, 0x74fc7f4b, F=0x0
+0,         29, -9223372036854775808,        1,     9158, 0x0b5426a5, F=0x0
+0,         30, -9223372036854775808,        1,    12715, 0x0035d569, F=0x0
 0,         31, -9223372036854775808,        1,    19944, 0xe2887ba8
-0,         32, -9223372036854775808,        1,    12762, 0xb0f17939
-0,         33, -9223372036854775808,        1,    10260, 0x182b27aa
-0,         34, -9223372036854775808,        1,     7405, 0x227fe9bf
-0,         35, -9223372036854775808,        1,    13317, 0x1a678c62
-0,         36, -9223372036854775808,        1,    11304, 0x3277af6d
-0,         37, -9223372036854775808,        1,    13291, 0xe267616a
-0,         38, -9223372036854775808,        1,     8975, 0xe7eeacea
-0,         39, -9223372036854775808,        1,     8473, 0x8bb1cbff
-0,         40, -9223372036854775808,        1,    13878, 0xfd3d55bb
-0,         41, -9223372036854775808,        1,    11278, 0x61c7c55e
-0,         42, -9223372036854775808,        1,    13785, 0x2acbf88f
-0,         43, -9223372036854775808,        1,     9521, 0x99e2d065
-0,         44, -9223372036854775808,        1,     9340, 0xe5c96510
-0,         45, -9223372036854775808,        1,    12777, 0x4c3c7844
-0,         46, -9223372036854775808,        1,    10685, 0x39e0f42e
-0,         47, -9223372036854775808,        1,    14237, 0x9398d07f
-0,         48, -9223372036854775808,        1,     9021, 0x3343c7ec
-0,         49, -9223372036854775808,        1,     9327, 0xad489e86
-0,         50, -9223372036854775808,        1,    13507, 0xb1344f1c
-0,         51, -9223372036854775808,        1,    10199, 0x9a8868bf
-0,         52, -9223372036854775808,        1,    14535, 0xddb13f41
-0,         53, -9223372036854775808,        1,     8773, 0x3d8b6a79
-0,         54, -9223372036854775808,        1,    16084, 0x5d915de4
-0,         55, -9223372036854775808,        1,     9156, 0x5cb08a6a
-0,         56, -9223372036854775808,        1,    15027, 0xc23b1dc8
-0,         57, -9223372036854775808,        1,     8240, 0xd6d3526c
-0,         58, -9223372036854775808,        1,     8720, 0x439c43bf
-0,         59, -9223372036854775808,        1,    13684, 0x18fc82f0
-0,         60, -9223372036854775808,        1,     8829, 0xa3ebeb30
-0,         61, -9223372036854775808,        1,    14650, 0x99e8678c
+0,         32, -9223372036854775808,        1,    12762, 0xb0f17939, F=0x0
+0,         33, -9223372036854775808,        1,    10260, 0x182b27aa, F=0x0
+0,         34, -9223372036854775808,        1,     7405, 0x227fe9bf, F=0x0
+0,         35, -9223372036854775808,        1,    13317, 0x1a678c62, F=0x0
+0,         36, -9223372036854775808,        1,    11304, 0x3277af6d, F=0x0
+0,         37, -9223372036854775808,        1,    13291, 0xe267616a, F=0x0
+0,         38, -9223372036854775808,        1,     8975, 0xe7eeacea, F=0x0
+0,         39, -9223372036854775808,        1,     8473, 0x8bb1cbff, F=0x0
+0,         40, -9223372036854775808,        1,    13878, 0xfd3d55bb, F=0x0
+0,         41, -9223372036854775808,        1,    11278, 0x61c7c55e, F=0x0
+0,         42, -9223372036854775808,        1,    13785, 0x2acbf88f, F=0x0
+0,         43, -9223372036854775808,        1,     9521, 0x99e2d065, F=0x0
+0,         44, -9223372036854775808,        1,     9340, 0xe5c96510, F=0x0
+0,         45, -9223372036854775808,        1,    12777, 0x4c3c7844, F=0x0
+0,         46, -9223372036854775808,        1,    10685, 0x39e0f42e, F=0x0
+0,         47, -9223372036854775808,        1,    14237, 0x9398d07f, F=0x0
+0,         48, -9223372036854775808,        1,     9021, 0x3343c7ec, F=0x0
+0,         49, -9223372036854775808,        1,     9327, 0xad489e86, F=0x0
+0,         50, -9223372036854775808,        1,    13507, 0xb1344f1c, F=0x0
+0,         51, -9223372036854775808,        1,    10199, 0x9a8868bf, F=0x0
+0,         52, -9223372036854775808,        1,    14535, 0xddb13f41, F=0x0
+0,         53, -9223372036854775808,        1,     8773, 0x3d8b6a79, F=0x0
+0,         54, -9223372036854775808,        1,    16084, 0x5d915de4, F=0x0
+0,         55, -9223372036854775808,        1,     9156, 0x5cb08a6a, F=0x0
+0,         56, -9223372036854775808,        1,    15027, 0xc23b1dc8, F=0x0
+0,         57, -9223372036854775808,        1,     8240, 0xd6d3526c, F=0x0
+0,         58, -9223372036854775808,        1,     8720, 0x439c43bf, F=0x0
+0,         59, -9223372036854775808,        1,    13684, 0x18fc82f0, F=0x0
+0,         60, -9223372036854775808,        1,     8829, 0xa3ebeb30, F=0x0
+0,         61, -9223372036854775808,        1,    14650, 0x99e8678c, F=0x0
 0,         62, -9223372036854775808,        1,    19626, 0x80a7ee5c
-0,         63, -9223372036854775808,        1,     7762, 0x7c209a12
-0,         64, -9223372036854775808,        1,    13636, 0xc89c1aa3
-0,         65, -9223372036854775808,        1,     8337, 0x749bf76a
-0,         66, -9223372036854775808,        1,    15098, 0xc98bc6dc
-0,         67, -9223372036854775808,        1,     9070, 0xcd4cf7f1
-0,         68, -9223372036854775808,        1,     8269, 0x90e95d54
-0,         69, -9223372036854775808,        1,    12672, 0x034888d0
-0,         70, -9223372036854775808,        1,     7519, 0x6c089672
-0,         71, -9223372036854775808,        1,    14439, 0x5d2478b9
-0,         72, -9223372036854775808,        1,     6928, 0x98fbaa67
-0,         73, -9223372036854775808,        1,     8735, 0x07643f1e
-0,         74, -9223372036854775808,        1,    13522, 0x55034cdb
-0,         75, -9223372036854775808,        1,     7807, 0xf5983103
-0,         76, -9223372036854775808,        1,    14484, 0xfc9cf260
-0,         77, -9223372036854775808,        1,     7193, 0x170a0fa1
-0,         78, -9223372036854775808,        1,     9444, 0x6f9be36f
-0,         79, -9223372036854775808,        1,    12598, 0x69b7609d
-0,         80, -9223372036854775808,        1,     7650, 0x1abaec9e
-0,         81, -9223372036854775808,        1,    15162, 0x2a87f723
-0,         82, -9223372036854775808,        1,     7752, 0xcca248aa
-0,         83, -9223372036854775808,        1,     9085, 0x1ca7d7e5
-0,         84, -9223372036854775808,        1,    13187, 0xababcc64
-0,         85, -9223372036854775808,        1,     7968, 0x64a28f46
-0,         86, -9223372036854775808,        1,    15474, 0xf34c587c
-0,         87, -9223372036854775808,        1,     8615, 0x61301034
-0,         88, -9223372036854775808,        1,    14129, 0x42c88bea
-0,         89, -9223372036854775808,        1,     7223, 0x675d7500
-0,         90, -9223372036854775808,        1,     3072, 0x4cb6254c
+0,         63, -9223372036854775808,        1,     7762, 0x7c209a12, F=0x0
+0,         64, -9223372036854775808,        1,    13636, 0xc89c1aa3, F=0x0
+0,         65, -9223372036854775808,        1,     8337, 0x749bf76a, F=0x0
+0,         66, -9223372036854775808,        1,    15098, 0xc98bc6dc, F=0x0
+0,         67, -9223372036854775808,        1,     9070, 0xcd4cf7f1, F=0x0
+0,         68, -9223372036854775808,        1,     8269, 0x90e95d54, F=0x0
+0,         69, -9223372036854775808,        1,    12672, 0x034888d0, F=0x0
+0,         70, -9223372036854775808,        1,     7519, 0x6c089672, F=0x0
+0,         71, -9223372036854775808,        1,    14439, 0x5d2478b9, F=0x0
+0,         72, -9223372036854775808,        1,     6928, 0x98fbaa67, F=0x0
+0,         73, -9223372036854775808,        1,     8735, 0x07643f1e, F=0x0
+0,         74, -9223372036854775808,        1,    13522, 0x55034cdb, F=0x0
+0,         75, -9223372036854775808,        1,     7807, 0xf5983103, F=0x0
+0,         76, -9223372036854775808,        1,    14484, 0xfc9cf260, F=0x0
+0,         77, -9223372036854775808,        1,     7193, 0x170a0fa1, F=0x0
+0,         78, -9223372036854775808,        1,     9444, 0x6f9be36f, F=0x0
+0,         79, -9223372036854775808,        1,    12598, 0x69b7609d, F=0x0
+0,         80, -9223372036854775808,        1,     7650, 0x1abaec9e, F=0x0
+0,         81, -9223372036854775808,        1,    15162, 0x2a87f723, F=0x0
+0,         82, -9223372036854775808,        1,     7752, 0xcca248aa, F=0x0
+0,         83, -9223372036854775808,        1,     9085, 0x1ca7d7e5, F=0x0
+0,         84, -9223372036854775808,        1,    13187, 0xababcc64, F=0x0
+0,         85, -9223372036854775808,        1,     7968, 0x64a28f46, F=0x0
+0,         86, -9223372036854775808,        1,    15474, 0xf34c587c, F=0x0
+0,         87, -9223372036854775808,        1,     8615, 0x61301034, F=0x0
+0,         88, -9223372036854775808,        1,    14129, 0x42c88bea, F=0x0
+0,         89, -9223372036854775808,        1,     7223, 0x675d7500, F=0x0
+0,         90, -9223372036854775808,        1,     3072, 0x4cb6254c, F=0x0
diff --git a/tests/ref/fate/nsv-demux b/tests/ref/fate/nsv-demux
index 0f09446..0ad08b1 100644
--- a/tests/ref/fate/nsv-demux
+++ b/tests/ref/fate/nsv-demux
@@ -1,173 +1,173 @@
 #tb 0: 1001/15000
 #tb 1: 1/30000000
 0,          0,          0,        1,       12, 0x1396035f
-0,          1,          1,        1,       24, 0x8ab80ac7
-0,          2,          2,        1,      208, 0x1de1603e
+0,          1,          1,        1,       24, 0x8ab80ac7, F=0x0
+0,          2,          2,        1,      208, 0x1de1603e, F=0x0
 1,    4173848,    4173848,  1567346,      104, 0x8ae85dc9
 1,    5741194,    5741194,  1567346,      105, 0xb7033847
-0,          3,          3,        1,      364, 0xffb4b341
+0,          3,          3,        1,      364, 0xffb4b341, F=0x0
 1,    7308540,    7308540,  1567346,      104, 0x5f853482
-0,          4,          4,        1,      456, 0x7a4deaeb
+0,          4,          4,        1,      456, 0x7a4deaeb, F=0x0
 1,    8875886,    8875886,  1567346,      105, 0xfcb731fd
-0,          5,          5,        1,      432, 0xf4ddd813
+0,          5,          5,        1,      432, 0xf4ddd813, F=0x0
 1,   10443232,   10443232,  1567346,      104, 0x4f8232bb
 1,   12010578,   12010578,  1567346,      105, 0x2f543039
-0,          6,          6,        1,      572, 0xc84c21ff
+0,          6,          6,        1,      572, 0xc84c21ff, F=0x0
 1,   13577924,   13577924,  1567346,      104, 0xe4cc34a1
-0,          7,          7,        1,      500, 0x0e6bf9f4
+0,          7,          7,        1,      500, 0x0e6bf9f4, F=0x0
 1,   15145270,   15145270,  1567346,      105, 0xea663711
-0,          8,          8,        1,      508, 0x2d6efe2a
+0,          8,          8,        1,      508, 0x2d6efe2a, F=0x0
 1,   16712616,   16712616,  1567346,      104, 0x3c583098
-0,          9,          9,        1,      436, 0x7d07d3c5
+0,          9,          9,        1,      436, 0x7d07d3c5, F=0x0
 1,   18279962,   18279962,  1567346,      105, 0xbe6c33ff
 1,   19847308,   19847308,  1567346,      104, 0x56de2d7a
-0,         10,         10,        1,      620, 0xa9313342
+0,         10,         10,        1,      620, 0xa9313342, F=0x0
 1,   21414654,   21414654,  1567346,      105, 0x4e80385d
 0,         11,         11,        1,     1384, 0x9b97c579
 1,   22982000,   22982000,  1567346,      104, 0x34eb340d
-0,         12,         12,        1,      760, 0xd1aa8183
+0,         12,         12,        1,      760, 0xd1aa8183, F=0x0
 1,   24549346,   24549346,  1567346,      105, 0x87e82f74
-0,         13,         13,        1,      836, 0x261da980
+0,         13,         13,        1,      836, 0x261da980, F=0x0
 1,   26116692,   26116692,  1567346,      104, 0xa546377d
 1,   27684038,   27684038,  1567346,      105, 0x92bd349d
-0,         14,         14,        1,      860, 0x52f0afa0
+0,         14,         14,        1,      860, 0x52f0afa0, F=0x0
 1,   29251384,   29251384,  1567346,      104, 0xdba53f3d
-0,         15,         15,        1,      696, 0x63845855
+0,         15,         15,        1,      696, 0x63845855, F=0x0
 1,   30818730,   30818730,  1567346,      105, 0xd3c3384e
-0,         16,         16,        1,      460, 0x2916e7be
+0,         16,         16,        1,      460, 0x2916e7be, F=0x0
 1,   32386076,   32386076,  1567346,      104, 0xdf7d30ce
 1,   33953422,   33953422,  1567346,      105, 0xae20344e
-0,         17,         17,        1,      328, 0xab8caaca
+0,         17,         17,        1,      328, 0xab8caaca, F=0x0
 1,   35520768,   35520768,  1567346,      104, 0xe4cc33b7
-0,         18,         18,        1,      396, 0xc775bc8e
+0,         18,         18,        1,      396, 0xc775bc8e, F=0x0
 1,   37088114,   37088114,  1567346,      105, 0xda993806
-0,         19,         19,        1,      344, 0x114ea25a
+0,         19,         19,        1,      344, 0x114ea25a, F=0x0
 1,   38655460,   38655460,  1567346,      104, 0xd6d12edd
 1,   40222806,   40222806,  1567346,      105, 0x6b9c2ed5
 1,   41790152,   41790152,  1567346,      104, 0xce6c3b04
-0,         21,         21,        1,      532, 0xd5650f54
+0,         21,         21,        1,      532, 0xd5650f54, F=0x0
 1,   43357498,   43357498,  1567346,      105, 0x31db399e
 1,   44924844,   44924844,  1567346,      104, 0xd50b347a
-0,         23,         23,        1,      476, 0x77f1f3a7
+0,         23,         23,        1,      476, 0x77f1f3a7, F=0x0
 1,   46492190,   46492190,  1567346,      105, 0xe87734d6
 1,   48059536,   48059536,  1567346,      104, 0x21873412
 0,         25,         25,        1,      976, 0x2f7cf7ae
 1,   50140000,   50140000,  1567346,      105, 0x29c03514
 1,   51707346,   51707346,  1567346,      104, 0x91a5347a
 1,   53274692,   53274692,  1567346,      105, 0xdbbf3696
-0,         27,         27,        1,      104, 0x8fbf2f65
+0,         27,         27,        1,      104, 0x8fbf2f65, F=0x0
 1,   54842038,   54842038,  1567346,      104, 0x3b463afc
 1,   56409384,   56409384,  1567346,      105, 0xddf53845
 1,   57976730,   57976730,  1567346,      104, 0x94c23d1a
-0,         29,         29,        1,      652, 0xa9244ac0
+0,         29,         29,        1,      652, 0xa9244ac0, F=0x0
 1,   59544076,   59544076,  1567346,      105, 0xc0fd36c4
 1,   61111422,   61111422,  1567346,      104, 0x36d535e0
-0,         31,         31,        1,      152, 0x97804cc1
+0,         31,         31,        1,      152, 0x97804cc1, F=0x0
 1,   62678768,   62678768,  1567346,      105, 0xe81a35da
 1,   64246114,   64246114,  1567346,      104, 0x2b4e3699
 1,   65813460,   65813460,  1567346,      105, 0x3978392c
-0,         33,         33,        1,      156, 0xca434d31
+0,         33,         33,        1,      156, 0xca434d31, F=0x0
 1,   67380806,   67380806,  1567346,      104, 0xca903459
-0,         34,         34,        1,      196, 0x1ff16161
+0,         34,         34,        1,      196, 0x1ff16161, F=0x0
 1,   68948152,   68948152,  1567346,      105, 0xedc4374a
-0,         35,         35,        1,      176, 0x9b455230
+0,         35,         35,        1,      176, 0x9b455230, F=0x0
 1,   70515498,   70515498,  1567346,      104, 0x0b3938d2
-0,         36,         36,        1,      156, 0xbbbf4bf3
+0,         36,         36,        1,      156, 0xbbbf4bf3, F=0x0
 1,   72082844,   72082844,  1567346,      105, 0xb2653246
 1,   73650190,   73650190,  1567346,      104, 0x76333479
-0,         37,         37,        1,      220, 0x77a97152
+0,         37,         37,        1,      220, 0x77a97152, F=0x0
 1,   75217536,   75217536,  1567346,      105, 0x779138c4
-0,         38,         38,        1,      204, 0x667d5ecf
+0,         38,         38,        1,      204, 0x667d5ecf, F=0x0
 1,   76784882,   76784882,  1567346,      104, 0xfe142f55
-0,         39,         39,        1,      232, 0x3a266ccd
+0,         39,         39,        1,      232, 0x3a266ccd, F=0x0
 1,   78352228,   78352228,  1567346,      105, 0x39aa3410
 1,   79919574,   79919574,  1567346,      104, 0x520f330d
-0,         40,         40,        1,      308, 0x844a95b7
+0,         40,         40,        1,      308, 0x844a95b7, F=0x0
 1,   81486920,   81486920,  1567346,      104, 0x1aad37b0
-0,         41,         41,        1,      384, 0x71d2c695
+0,         41,         41,        1,      384, 0x71d2c695, F=0x0
 1,   83054266,   83054266,  1567346,      105, 0x164038eb
 1,   84621612,   84621612,  1567346,      104, 0x21d434bd
-0,         43,         43,        1,      520, 0x4f9d012a
+0,         43,         43,        1,      520, 0x4f9d012a, F=0x0
 1,   86188958,   86188958,  1567346,      105, 0x9c1236d4
 1,   87756304,   87756304,  1567346,      104, 0x6aa933c3
 1,   89323650,   89323650,  1567346,      105, 0xec5c371e
-0,         45,         45,        1,      648, 0xabd13b29
+0,         45,         45,        1,      648, 0xabd13b29, F=0x0
 1,   90890996,   90890996,  1567346,      104, 0xedb33251
 1,   92458342,   92458342,  1567346,      105, 0x4f953476
 1,   94025688,   94025688,  1567346,      104, 0x7da13400
-0,         47,         47,        1,      604, 0x006b328f
+0,         47,         47,        1,      604, 0x006b328f, F=0x0
 1,   95593034,   95593034,  1567346,      105, 0x57a83aaa
 1,   97160380,   97160380,  1567346,      104, 0x8b822f2f
-0,         49,         49,        1,      492, 0xa150fac1
+0,         49,         49,        1,      492, 0xa150fac1, F=0x0
 1,   98727726,   98727726,  1567346,      105, 0x3b31341a
 1,  100295072,  100295072,  1567346,      104, 0x74a4316d
 1,  101862418,  101862418,  1567346,      105, 0x05013469
-0,         51,         51,        1,      456, 0xd3e9e52c
+0,         51,         51,        1,      456, 0xd3e9e52c, F=0x0
 1,  103429764,  103429764,  1567346,      104, 0xcc8932cb
 1,  104997110,  104997110,  1567346,      105, 0xd9233422
-0,         53,         53,        1,      340, 0x7229a1b7
+0,         53,         53,        1,      340, 0x7229a1b7, F=0x0
 1,  106564456,  106564456,  1567346,      104, 0x5c603350
 1,  108131802,  108131802,  1567346,      105, 0x76e631bc
 1,  109699148,  109699148,  1567346,      104, 0x657e3b35
-0,         55,         55,        1,      280, 0x48948b60
+0,         55,         55,        1,      280, 0x48948b60, F=0x0
 1,  111266494,  111266494,  1567346,      105, 0x9d283226
 1,  112833840,  112833840,  1567346,      104, 0x574936ef
-0,         57,         57,        1,      304, 0x3ae68dcf
+0,         57,         57,        1,      304, 0x3ae68dcf, F=0x0
 1,  114401186,  114401186,  1567346,      105, 0x1b923555
 1,  115968532,  115968532,  1567346,      104, 0x2a9f3583
 1,  117535878,  117535878,  1567346,      105, 0xb8cd306f
-0,         59,         59,        1,      324, 0x005da2ab
+0,         59,         59,        1,      324, 0x005da2ab, F=0x0
 1,  119103224,  119103224,  1567346,      104, 0xa21d3475
 1,  120670570,  120670570,  1567346,      105, 0x651539ea
-0,         61,         61,        1,      348, 0x3230a873
+0,         61,         61,        1,      348, 0x3230a873, F=0x0
 1,  122237916,  122237916,  1567346,      104, 0x7b7235b8
 1,  123805262,  123805262,  1567346,      105, 0x2bbb337a
 1,  125372608,  125372608,  1567346,      104, 0x26c332eb
-0,         63,         63,        1,      336, 0x8655ad2d
+0,         63,         63,        1,      336, 0x8655ad2d, F=0x0
 1,  126939954,  126939954,  1567346,      105, 0x990838d8
 1,  128507300,  128507300,  1567346,      104, 0x4dc63ad4
 1,  130074646,  130074646,  1567346,      105, 0xfb8e3418
-0,         65,         65,        1,      380, 0x742ebc44
+0,         65,         65,        1,      380, 0x742ebc44, F=0x0
 1,  131641992,  131641992,  1567346,      104, 0x1882388e
 1,  133209338,  133209338,  1567346,      105, 0xe6b534cc
-0,         67,         67,        1,      340, 0xfc1aa74e
+0,         67,         67,        1,      340, 0xfc1aa74e, F=0x0
 1,  134776684,  134776684,  1567346,      104, 0x60fe35d0
 1,  136344030,  136344030,  1567346,      105, 0x5164354a
 1,  137911376,  137911376,  1567346,      104, 0x92ee3115
-0,         69,         69,        1,      332, 0x3cfba56c
+0,         69,         69,        1,      332, 0x3cfba56c, F=0x0
 1,  139478722,  139478722,  1567346,      105, 0x9b32327e
 1,  141046068,  141046068,  1567346,      104, 0x9b9e394a
-0,         71,         71,        1,      332, 0xc024ad4c
+0,         71,         71,        1,      332, 0xc024ad4c, F=0x0
 1,  142613414,  142613414,  1567346,      105, 0xce3c337f
 1,  144180760,  144180760,  1567346,      104, 0x7a4e33c5
 0,         73,         73,        1,     3432, 0xcdfcd1c9
 1,  146956000,  146956000,  1567346,      105, 0x0e3d34eb
 1,  148523346,  148523346,  1567346,      104, 0xd23e338e
 1,  150090692,  150090692,  1567346,      105, 0x4abf340c
-0,         75,         75,        1,      792, 0xe7df949f
+0,         75,         75,        1,      792, 0xe7df949f, F=0x0
 1,  151658038,  151658038,  1567346,      104, 0xe7522e15
 1,  153225384,  153225384,  1567346,      105, 0x995037ba
-0,         77,         77,        1,      912, 0xbc61d549
+0,         77,         77,        1,      912, 0xbc61d549, F=0x0
 1,  154792730,  154792730,  1567346,      104, 0x5ef12e9b
 1,  156360076,  156360076,  1567346,      105, 0x5c3b3166
 1,  157927422,  157927422,  1567346,      104, 0xfc38314b
-0,         79,         79,        1,      956, 0x809bdff0
+0,         79,         79,        1,      956, 0x809bdff0, F=0x0
 1,  159494768,  159494768,  1567346,      104, 0x5e3636e4
 1,  161062114,  161062114,  1567346,      105, 0xae7b3345
-0,         81,         81,        1,      652, 0x88d3484f
+0,         81,         81,        1,      652, 0x88d3484f, F=0x0
 1,  162629460,  162629460,  1567346,      104, 0x635c317a
 1,  164196806,  164196806,  1567346,      105, 0xa90c361a
 1,  165764152,  165764152,  1567346,      104, 0x8f563594
 0,         83,         83,        1,     1284, 0xecc37164
 1,  167156000,  167156000,  1567346,      105, 0x028e3985
 1,  168723346,  168723346,  1567346,      104, 0x4fd135f6
-0,         85,         85,        1,      428, 0x4794e174
+0,         85,         85,        1,      428, 0x4794e174, F=0x0
 1,  170290692,  170290692,  1567346,      105, 0xaaf539ac
 1,  171858038,  171858038,  1567346,      104, 0x668b3265
 1,  173425384,  173425384,  1567346,      105, 0x74ad3b4b
-0,         87,         87,        1,      460, 0x7253d94a
+0,         87,         87,        1,      460, 0x7253d94a, F=0x0
 1,  174992730,  174992730,  1567346,      104, 0xbde5332f
 1,  176560076,  176560076,  1567346,      105, 0xdc3631e7
 1,  178127422,  178127422,  1567346,      104, 0x3e363a1e
-0,         89,         89,        1,       24, 0x664206ba
+0,         89,         89,        1,       24, 0x664206ba, F=0x0
 1,  179694768,  179694768,  1567346,      105, 0x48b63926
diff --git a/tests/ref/fate/nuv-rtjpeg b/tests/ref/fate/nuv-rtjpeg
index e9286d6..8838fbb 100644
--- a/tests/ref/fate/nuv-rtjpeg
+++ b/tests/ref/fate/nuv-rtjpeg
@@ -1,10 +1,10 @@
-#tb 0: 1/1000
-0,        118,        118,        0,   460800, 0x54aedafe
-0,        152,        152,        0,   460800, 0xb7aa8b56
-0,        177,        177,        0,   460800, 0x283ea3b5
-0,        202,        202,        0,   460800, 0x283ea3b5
-0,        235,        235,        0,   460800, 0x10e577de
-0,        269,        269,        0,   460800, 0x4e091ee2
-0,        302,        302,        0,   460800, 0x2ea88828
-0,        335,        335,        0,   460800, 0x4b7f4df0
-0,        369,        369,        0,   460800, 0xb30eb322
+#tb 0: 100/2997
+0,          4,          4,        1,   460800, 0x54aedafe
+0,          5,          5,        1,   460800, 0xb7aa8b56
+0,          6,          6,        1,   460800, 0x283ea3b5
+0,          7,          7,        1,   460800, 0x283ea3b5
+0,          8,          8,        1,   460800, 0x10e577de
+0,          9,          9,        1,   460800, 0x4e091ee2
+0,         10,         10,        1,   460800, 0x2ea88828
+0,         11,         11,        1,   460800, 0x4b7f4df0
+0,         12,         12,        1,   460800, 0xa57f20d0
diff --git a/tests/ref/fate/nuv-rtjpeg-fh b/tests/ref/fate/nuv-rtjpeg-fh
index 92aa122..151ef88 100644
--- a/tests/ref/fate/nuv-rtjpeg-fh
+++ b/tests/ref/fate/nuv-rtjpeg-fh
@@ -1,51 +1,51 @@
-#tb 0: 1/1000
-0,          0,          0,        0,   221184, 0xf48c94f6
-0,         40,         40,        0,   221184, 0x89b625b2
-0,         60,         60,        0,   221184, 0x37e04714
-0,         80,         80,        0,   221184, 0x4f4c5224
-0,        100,        100,        0,   221184, 0x9193c9f1
-0,        120,        120,        0,   221184, 0x5d1a6197
-0,        140,        140,        0,   221184, 0x40cd51e7
-0,        160,        160,        0,   221184, 0xb2c1a729
-0,        200,        200,        0,   221184, 0x998d6144
-0,        220,        220,        0,   221184, 0xf5d52311
-0,        240,        240,        0,   221184, 0xea9dd6bf
-0,        260,        260,        0,   221184, 0x0e2ed854
-0,        280,        280,        0,   221184, 0xe295ba58
-0,        300,        300,        0,   221184, 0x8aedbb69
-0,        320,        320,        0,   221184, 0x253c9aaa
-0,        340,        340,        0,   221184, 0x5eaf9fb1
-0,        360,        360,        0,   221184, 0xcdb5a0cb
-0,        380,        380,        0,   221184, 0xcdb5a0cb
-0,        400,        400,        0,   221184, 0x23f89994
-0,        420,        420,        0,   221184, 0x23f89994
-0,        440,        440,        0,   221184, 0x10dc98d6
-0,        460,        460,        0,   221184, 0x799b9d98
-0,        480,        480,        0,   221184, 0xb226996c
-0,        500,        500,        0,   221184, 0x0ac59a42
-0,        520,        520,        0,   221184, 0x87c2a654
-0,        540,        540,        0,   221184, 0xf4c1a711
-0,        560,        560,        0,   221184, 0xf60fa72e
-0,        580,        580,        0,   221184, 0xc8f8b6fc
-0,        600,        600,        0,   221184, 0xd709b813
-0,        620,        620,        0,   221184, 0x5fdfb76b
-0,        640,        640,        0,   221184, 0x5798b0aa
-0,        660,        660,        0,   221184, 0xf572b1c3
-0,        680,        680,        0,   221184, 0x14b0afdf
-0,        700,        700,        0,   221184, 0x0a66b5b8
-0,        720,        720,        0,   221184, 0xe316c620
-0,        740,        740,        0,   221184, 0xbc76c5c2
-0,        760,        760,        0,   221184, 0x77c7c5e5
-0,        780,        780,        0,   221184, 0xfc7ac63e
-0,        800,        800,        0,   221184, 0x05a29ffe
-0,        820,        820,        0,   221184, 0x9bffbf6c
-0,        840,        840,        0,   221184, 0x3c55be40
-0,        860,        860,        0,   221184, 0x6f46c14e
-0,        880,        880,        0,   221184, 0x9cf4ae70
-0,        900,        900,        0,   221184, 0xf205b2f8
-0,        920,        920,        0,   221184, 0x7180aff8
-0,        940,        940,        0,   221184, 0x125eaffe
-0,        960,        960,        0,   221184, 0x6970a32d
-0,        980,        980,        0,   221184, 0xaea79f62
-0,       1000,       1000,        0,   221184, 0x48d2a093
-0,       1020,       1020,        0,   221184, 0x10a59eb5
+#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
diff --git a/tests/ref/fate/options-force_key_frames b/tests/ref/fate/options-force_key_frames
new file mode 100644
index 0000000..205296c
--- /dev/null
+++ b/tests/ref/fate/options-force_key_frames
@@ -0,0 +1,4 @@
+654970e7a09ff4869596c2a47e698007 *tests/data/fate/options-force_key_frames.avi
+113320 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/paf-audio b/tests/ref/fate/paf-audio
new file mode 100644
index 0000000..ba47d5d
--- /dev/null
+++ b/tests/ref/fate/paf-audio
@@ -0,0 +1,7 @@
+#tb 0: 1/22050
+0,          0,          0,    57330,   229320, 0x062508b4
+0,      57330,      57330,    57330,   229320, 0x0a966cbf
+0,     114660,     114660,    57330,   229320, 0xee9bad45
+0,     171990,     171990,    57330,   229320, 0xde88274e
+0,     229320,     229320,    57330,   229320, 0x2fdeeaf6
+0,     286650,     286650,    57330,   229320, 0xf793fe5b
diff --git a/tests/ref/fate/paf-demux b/tests/ref/fate/paf-demux
new file mode 100644
index 0000000..857fb54
--- /dev/null
+++ b/tests/ref/fate/paf-demux
@@ -0,0 +1,160 @@
+#tb 0: 1/10
+#tb 1: 1/22050
+0,          0,          0,        1,   262144, 0x7f9a3c6a
+1,          0,          0,    57330,   131072, 0x255a6ac2
+0,          1,          1,        1,   260600, 0x0329e6f4, F=0x0
+0,          2,          2,        1,   259724, 0x2db0ad5e, F=0x0
+0,          3,          3,        1,   258616, 0xe666009d, F=0x0
+0,          4,          4,        1,   257364, 0xba42458c, F=0x0
+0,          5,          5,        1,   255964, 0xf7e04c83, F=0x0
+0,          6,          6,        1,   254192, 0xa04b49ff, F=0x0
+0,          7,          7,        1,   252232, 0x65d4ab4c, F=0x0
+0,          8,          8,        1,   249960, 0x8f0b3854, F=0x0
+0,          9,          9,        1,   247396, 0x16d70776, F=0x0
+0,         10,         10,        1,   244452, 0x8b0648f3, F=0x0
+0,         11,         11,        1,   240972, 0x07e3ef41, F=0x0
+0,         12,         12,        1,   237288, 0x197a1964, F=0x0
+0,         13,         13,        1,   233344, 0xd6c51f01, F=0x0
+0,         14,         14,        1,   229196, 0x48581a65, F=0x0
+0,         15,         15,        1,   224688, 0x710e1fdb, F=0x0
+0,         16,         16,        1,   219248, 0xcd96719d, F=0x0
+0,         17,         17,        1,   212712, 0x4de31fd8, F=0x0
+0,         18,         18,        1,   205864, 0x21a0a106, F=0x0
+0,         19,         19,        1,   199148, 0xd1d77c92, F=0x0
+0,         20,         20,        1,   192072, 0x620627a6, F=0x0
+0,         21,         21,        1,   184928, 0x81548454, F=0x0
+0,         22,         22,        1,   178296, 0x7bb40918, F=0x0
+0,         23,         23,        1,   171944, 0xa7b714bb, F=0x0
+0,         24,         24,        1,   165584, 0xa6246dba, F=0x0
+0,         25,         25,        1,   159468, 0x7bc54abb, F=0x0
+0,         26,         26,        1,   153524, 0xd2774028, F=0x0
+1,      57330,      57330,    57330,   131072, 0xcc38a5e5
+0,         27,         27,        1,   147568, 0xd94b2368, F=0x0
+0,         28,         28,        1,   141536, 0xb512eae6, F=0x0
+0,         29,         29,        1,   135368, 0x9b6ea2b3, F=0x0
+0,         30,         30,        1,   128296, 0x7c26d136, F=0x0
+0,         31,         31,        1,   120932, 0xccb8b273, F=0x0
+0,         32,         32,        1,   113432, 0x9f2bb997, F=0x0
+0,         33,         33,        1,   105724, 0x735519f6, F=0x0
+0,         34,         34,        1,    98428, 0xa2933dbb, F=0x0
+0,         35,         35,        1,    91136, 0xbe852457, F=0x0
+0,         36,         36,        1,    83844, 0xc471106a, F=0x0
+0,         37,         37,        1,    76648, 0x3f6e1c92, F=0x0
+0,         38,         38,        1,    69624, 0x00f86b27, F=0x0
+0,         39,         39,        1,    62436, 0xf360ccf0, F=0x0
+0,         40,         40,        1,    55268, 0x0373c2a3, F=0x0
+0,         41,         41,        1,    48220, 0xd5a5e0c1, F=0x0
+0,         42,         42,        1,    48216, 0x1da7e0ad, F=0x0
+0,         43,         43,        1,    48212, 0xa984e098, F=0x0
+0,         44,         44,        1,    48208, 0x7962e082, F=0x0
+0,         45,         45,        1,    48204, 0xc245e06e, F=0x0
+0,         46,         46,        1,    48200, 0x4f2de059, F=0x0
+0,         47,         47,        1,    48196, 0x2013e043, F=0x0
+0,         48,         48,        1,    48192, 0x34ffe02c, F=0x0
+0,         49,         49,        1,    48188, 0x7f22e018, F=0x0
+0,         50,         50,        1,    48184, 0x0d5ae003, F=0x0
+0,         51,         51,        1,    48180, 0xdf91dfed, F=0x0
+0,         52,         52,        1,    48176, 0xf5eddfd6, F=0x0
+1,     114660,     114660,    57330,   131072, 0x4d9c2c7e
+0,         53,         53,        1,    48172, 0x415fdfc2, F=0x0
+0,         54,         54,        1,    48168, 0xd0d8dfad, F=0x0
+0,         55,         55,        1,    48164, 0xa47edf97, F=0x0
+0,         56,         56,        1,    48160, 0xbc4adf80, F=0x0
+0,         57,         57,        1,    48156, 0x08fcdf6c, F=0x0
+0,         58,         58,        1,    48152, 0x99c5df57, F=0x0
+0,         59,         59,        1,    41116, 0x8c22a4c1, F=0x0
+0,         60,         60,        1,    34124, 0x33c9e476, F=0x0
+0,         61,         61,        1,    27272, 0x8069fb08, F=0x0
+0,         62,         62,        1,    20636, 0xa413e37e, F=0x0
+0,         63,         63,        1,    14072, 0x428a2075, F=0x0
+0,         64,         64,        1,     7712, 0x7c6b914f, F=0x0
+0,         65,         65,        1,   262144, 0x687484cb, F=0x0
+0,         66,         66,        1,   256292, 0x0dec8b5a, F=0x0
+0,         67,         67,        1,   250612, 0xd127f411, F=0x0
+0,         68,         68,        1,   245404, 0x4e760ddf, F=0x0
+0,         69,         69,        1,   241956, 0x0412f83d, F=0x0
+0,         70,         70,        1,   241184, 0x0de227e2, F=0x0
+0,         71,         71,        1,   241180, 0xebe9eafb, F=0x0
+0,         72,         72,        1,   241176, 0xf0c8eae5, F=0x0
+0,         73,         73,        1,   241172, 0x47bbeace, F=0x0
+0,         74,         74,        1,   241168, 0xfb8aeab9, F=0x0
+0,         75,         75,        1,   241164, 0x0180eaa3, F=0x0
+0,         76,         76,        1,   241160, 0x5978ea8c, F=0x0
+0,         77,         77,        1,   241156, 0xbc86ea78, F=0x0
+0,         78,         78,        1,   241152, 0x71b4ea63, F=0x0
+1,     171990,     171990,    57330,   131072, 0x1b512fb8
+0,         79,         79,        1,   241148, 0x78fbea4d, F=0x0
+0,         80,         80,        1,   241144, 0xd263ea36
+0,         81,         81,        1,   237912, 0xcb5839a6, F=0x0
+0,         82,         82,        1,   229296, 0x350f07b6, F=0x0
+0,         83,         83,        1,   214256, 0x3c954096, F=0x0
+0,         84,         84,        1,   198068, 0x1470ae1f, F=0x0
+0,         85,         85,        1,   180664, 0xa80de8b6, F=0x0
+0,         86,         86,        1,   164672, 0x11ecf816, F=0x0
+0,         87,         87,        1,   148996, 0x6346aa49, F=0x0
+0,         88,         88,        1,   134804, 0x8fe4699a, F=0x0
+0,         89,         89,        1,   124488, 0x63b82fa0, F=0x0
+0,         90,         90,        1,   116892, 0xac785c29, F=0x0
+0,         91,         91,        1,   109528, 0xc24da959, F=0x0
+0,         92,         92,        1,   102688, 0xba25eb56, F=0x0
+0,         93,         93,        1,    95192, 0x999820b3, F=0x0
+0,         94,         94,        1,    89980, 0xa81aee1a, F=0x0
+0,         95,         95,        1,    84696, 0xb274dad5, F=0x0
+0,         96,         96,        1,    79152, 0xd7936f6e, F=0x0
+0,         97,         97,        1,    74232, 0x1abdf78a, F=0x0
+0,         98,         98,        1,    69112, 0x212918e8, F=0x0
+0,         99,         99,        1,    63484, 0x45e36b2f, F=0x0
+0,        100,        100,        1,    58616, 0xef171a5a, F=0x0
+0,        101,        101,        1,    53396, 0xd16be9a0, F=0x0
+0,        102,        102,        1,    47388, 0xc602914b, F=0x0
+0,        103,        103,        1,    42276, 0x6b86b9dd, F=0x0
+0,        104,        104,        1,    36932, 0xea0d85cb, F=0x0
+1,     229320,     229320,    57330,   131072, 0x4e478505
+0,        105,        105,        1,    30408, 0xc7df6cba, F=0x0
+0,        106,        106,        1,    24468, 0x80007205, F=0x0
+0,        107,        107,        1,    18572, 0xb4aa84d2, F=0x0
+0,        108,        108,        1,    12632, 0x12c2efb8, F=0x0
+0,        109,        109,        1,     6604, 0x75002817, F=0x0
+0,        110,        110,        1,   262144, 0xf9544f5b, F=0x0
+0,        111,        111,        1,   255448, 0x9242877e, F=0x0
+0,        112,        112,        1,   248532, 0xef495999, F=0x0
+0,        113,        113,        1,   238032, 0xac29500b, F=0x0
+0,        114,        114,        1,   225424, 0x73035f24, F=0x0
+0,        115,        115,        1,   215860, 0xed94de14, F=0x0
+0,        116,        116,        1,   205996, 0x4d417b16, F=0x0
+0,        117,        117,        1,   191904, 0xc195d49f, F=0x0
+0,        118,        118,        1,   182596, 0x32a14954, F=0x0
+0,        119,        119,        1,   174988, 0xdc83fa02, F=0x0
+0,        120,        120,        1,   168008, 0x5e1d7302, F=0x0
+0,        121,        121,        1,   161032, 0xf503efb4, F=0x0
+0,        122,        122,        1,   154044, 0x1df06a7c, F=0x0
+0,        123,        123,        1,   147056, 0x4c22ec13, F=0x0
+0,        124,        124,        1,   140060, 0xede97385, F=0x0
+0,        125,        125,        1,   133064, 0x50eefee6, F=0x0
+0,        126,        126,        1,   126060, 0xc6478fb8, F=0x0
+0,        127,        127,        1,   119056, 0xf45a2080, F=0x0
+0,        128,        128,        1,   112044, 0x1d49b4ae, F=0x0
+0,        129,        129,        1,   105028, 0xd35649dd, F=0x0
+0,        130,        130,        1,    98012, 0x03ede949, F=0x0
+1,     286650,     286650,    57330,   131072, 0xb29e283e
+0,        131,        131,        1,    91000, 0x57128fb0, F=0x0
+0,        132,        132,        1,    84000, 0xf7ff39c0, F=0x0
+0,        133,        133,        1,    77004, 0xda18e580, F=0x0
+0,        134,        134,        1,    70004, 0x8eff8af4, F=0x0
+0,        135,        135,        1,    62992, 0x665831fd, F=0x0
+0,        136,        136,        1,    55976, 0x130ada75, F=0x0
+0,        137,        137,        1,    48956, 0x4cf47b2f, F=0x0
+0,        138,        138,        1,    41936, 0x7a8e2006, F=0x0
+0,        139,        139,        1,    34920, 0x9527ca2b, F=0x0
+0,        140,        140,        1,    27912, 0x4c8078df, F=0x0
+0,        141,        141,        1,    20884, 0x1e152e1f, F=0x0
+0,        142,        142,        1,    13848, 0xd358d51b, F=0x0
+0,        143,        143,        1,   262144, 0x38f14810, F=0x0
+0,        144,        144,        1,   255104, 0x579bf26b, F=0x0
+0,        145,        145,        1,   255100, 0x6488a2d4, F=0x0
+0,        146,        146,        1,   248096, 0xbe966730, F=0x0
+0,        147,        147,        1,   241144, 0xd8e3abf6, F=0x0
+0,        148,        148,        1,   234268, 0xde2bb38e, F=0x0
+0,        149,        149,        1,   227440, 0xb78f1aed, F=0x0
+0,        150,        150,        1,   220692, 0x86026588, F=0x0
+0,        151,        151,        1,   214000, 0x0fdbc796, F=0x0
diff --git a/tests/ref/fate/paf-video b/tests/ref/fate/paf-video
new file mode 100644
index 0000000..ed37c28
--- /dev/null
+++ b/tests/ref/fate/paf-video
@@ -0,0 +1,153 @@
+#tb 0: 1/10
+0,          0,          0,        1,   147456, 0x00000000
+0,          1,          1,        1,   147456, 0x7be40798
+0,          2,          2,        1,   147456, 0x44bc2fc0
+0,          3,          3,        1,   147456, 0x82676740
+0,          4,          4,        1,   147456, 0xd8b8ad10
+0,          5,          5,        1,   147456, 0x816f1c51
+0,          6,          6,        1,   147456, 0x43cdb992
+0,          7,          7,        1,   147456, 0x795198be
+0,          8,          8,        1,   147456, 0x4738b47b
+0,          9,          9,        1,   147456, 0xd05f2cca
+0,         10,         10,        1,   147456, 0xe1b2d879
+0,         11,         11,        1,   147456, 0x538e0987
+0,         12,         12,        1,   147456, 0x2009cbce
+0,         13,         13,        1,   147456, 0xf4fedfdf
+0,         14,         14,        1,   147456, 0x288cfddb
+0,         15,         15,        1,   147456, 0x27be3801
+0,         16,         16,        1,   147456, 0xba20cf85
+0,         17,         17,        1,   147456, 0x16dda72f
+0,         18,         18,        1,   147456, 0x06742d33
+0,         19,         19,        1,   147456, 0x268b800a
+0,         20,         20,        1,   147456, 0x3094518e
+0,         21,         21,        1,   147456, 0xea944b0d
+0,         22,         22,        1,   147456, 0xf99990e0
+0,         23,         23,        1,   147456, 0x609a90de
+0,         24,         24,        1,   147456, 0xcde18594
+0,         25,         25,        1,   147456, 0x86b3d02d
+0,         26,         26,        1,   147456, 0x38d99cd7
+0,         27,         27,        1,   147456, 0x5cbfa3d2
+0,         28,         28,        1,   147456, 0xf292759f
+0,         29,         29,        1,   147456, 0xdae223dd
+0,         30,         30,        1,   147456, 0x55097657
+0,         31,         31,        1,   147456, 0x5ea6276c
+0,         32,         32,        1,   147456, 0x85532d21
+0,         33,         33,        1,   147456, 0x21c447d1
+0,         34,         34,        1,   147456, 0x6cbb700d
+0,         35,         35,        1,   147456, 0x889c443a
+0,         36,         36,        1,   147456, 0xad4171fd
+0,         37,         37,        1,   147456, 0xab26d665
+0,         38,         38,        1,   147456, 0xcf8a2e29
+0,         39,         39,        1,   147456, 0xc934a62a
+0,         40,         40,        1,   147456, 0xacca580c
+0,         41,         41,        1,   147456, 0xacca580c
+0,         42,         42,        1,   147456, 0xacca580c
+0,         43,         43,        1,   147456, 0xacca580c
+0,         44,         44,        1,   147456, 0xacca580c
+0,         45,         45,        1,   147456, 0xacca580c
+0,         46,         46,        1,   147456, 0xacca580c
+0,         47,         47,        1,   147456, 0xacca580c
+0,         48,         48,        1,   147456, 0xacca580c
+0,         49,         49,        1,   147456, 0xacca580c
+0,         50,         50,        1,   147456, 0xacca580c
+0,         51,         51,        1,   147456, 0xacca580c
+0,         52,         52,        1,   147456, 0xacca580c
+0,         53,         53,        1,   147456, 0xacca580c
+0,         54,         54,        1,   147456, 0xacca580c
+0,         55,         55,        1,   147456, 0xacca580c
+0,         56,         56,        1,   147456, 0xacca580c
+0,         57,         57,        1,   147456, 0xacca580c
+0,         58,         58,        1,   147456, 0xdd6a7104
+0,         59,         59,        1,   147456, 0x33e84c72
+0,         60,         60,        1,   147456, 0x86526e6a
+0,         61,         61,        1,   147456, 0x569863ad
+0,         62,         62,        1,   147456, 0x6269920f
+0,         63,         63,        1,   147456, 0x9ce49665
+0,         64,         64,        1,   147456, 0x782fcf56
+0,         65,         65,        1,   147456, 0x4401ef4a
+0,         66,         66,        1,   147456, 0xe06ffba8
+0,         67,         67,        1,   147456, 0xc87b2af3
+0,         68,         68,        1,   147456, 0x9fcaf0ef
+0,         69,         69,        1,   147456, 0x00000000
+0,         70,         70,        1,   147456, 0x00000000
+0,         71,         71,        1,   147456, 0x00000000
+0,         72,         72,        1,   147456, 0x00000000
+0,         73,         73,        1,   147456, 0x00000000
+0,         74,         74,        1,   147456, 0x00000000
+0,         75,         75,        1,   147456, 0x00000000
+0,         76,         76,        1,   147456, 0x00000000
+0,         77,         77,        1,   147456, 0x00000000
+0,         78,         78,        1,   147456, 0x00000000
+0,         79,         79,        1,   147456, 0x00000000
+0,         80,         80,        1,   147456, 0xc30c145f
+0,         81,         81,        1,   147456, 0x2d51e3c6
+0,         82,         82,        1,   147456, 0x5d41d6d2
+0,         83,         83,        1,   147456, 0x7abf857a
+0,         84,         84,        1,   147456, 0xd72e22f3
+0,         85,         85,        1,   147456, 0x89548b30
+0,         86,         86,        1,   147456, 0xd26fc965
+0,         87,         87,        1,   147456, 0xc664fe62
+0,         88,         88,        1,   147456, 0x51608d9e
+0,         89,         89,        1,   147456, 0xf188e257
+0,         90,         90,        1,   147456, 0x3d82f8bd
+0,         91,         91,        1,   147456, 0x08e38aa9
+0,         92,         92,        1,   147456, 0xb0c78fc3
+0,         93,         93,        1,   147456, 0xeec1ce57
+0,         94,         94,        1,   147456, 0xac75dd73
+0,         95,         95,        1,   147456, 0x94beecca
+0,         96,         96,        1,   147456, 0xfa417ee8
+0,         97,         97,        1,   147456, 0x68ee990a
+0,         98,         98,        1,   147456, 0x3df4bcd2
+0,         99,         99,        1,   147456, 0xff68d376
+0,        100,        100,        1,   147456, 0x4a211592
+0,        101,        101,        1,   147456, 0x6ce6b6f2
+0,        102,        102,        1,   147456, 0x8f17ca91
+0,        103,        103,        1,   147456, 0xcb94232c
+0,        104,        104,        1,   147456, 0x46b58bcd
+0,        105,        105,        1,   147456, 0x260e8b49
+0,        106,        106,        1,   147456, 0xd9f55cb1
+0,        107,        107,        1,   147456, 0x96e0b93c
+0,        108,        108,        1,   147456, 0xdbb4e51c
+0,        109,        109,        1,   147456, 0x3a4c7fcd
+0,        110,        110,        1,   147456, 0x25c58597
+0,        111,        111,        1,   147456, 0xfc0afd6a
+0,        112,        112,        1,   147456, 0x65aae479
+0,        113,        113,        1,   147456, 0x9c060d17
+0,        114,        114,        1,   147456, 0xac1f5d8c
+0,        115,        115,        1,   147456, 0x627bf813
+0,        116,        116,        1,   147456, 0x2b6d2bbc
+0,        117,        117,        1,   147456, 0x4d6b8274
+0,        118,        118,        1,   147456, 0x89ab152b
+0,        119,        119,        1,   147456, 0xdcb31afc
+0,        120,        120,        1,   147456, 0x9aac1a8b
+0,        121,        121,        1,   147456, 0xe8ad1a42
+0,        122,        122,        1,   147456, 0x05e019de
+0,        123,        123,        1,   147456, 0x541e1991
+0,        124,        124,        1,   147456, 0xeb5d182b
+0,        125,        125,        1,   147456, 0x00ef16e4
+0,        126,        126,        1,   147456, 0xe91a164b
+0,        127,        127,        1,   147456, 0xc37014bf
+0,        128,        128,        1,   147456, 0xb87b130a
+0,        129,        129,        1,   147456, 0x879f1202
+0,        130,        130,        1,   147456, 0x8de710f6
+0,        131,        131,        1,   147456, 0x499910b0
+0,        132,        132,        1,   147456, 0x494f0f49
+0,        133,        133,        1,   147456, 0x1d090f09
+0,        134,        134,        1,   147456, 0x31930e92
+0,        135,        135,        1,   147456, 0x42fe0d72
+0,        136,        136,        1,   147456, 0xc8980c5d
+0,        137,        137,        1,   147456, 0xd1fc0b7b
+0,        138,        138,        1,   147456, 0x2b620a27
+0,        139,        139,        1,   147456, 0xe9cf08f4
+0,        140,        140,        1,   147456, 0x4fb707ea
+0,        141,        141,        1,   147456, 0x8ec706fa
+0,        142,        142,        1,   147456, 0xde090640
+0,        143,        143,        1,   147456, 0xf7b1059d
+0,        144,        144,        1,   147456, 0xf7b1059d
+0,        145,        145,        1,   147456, 0x581902c4
+0,        146,        146,        1,   147456, 0x2b18d1e7
+0,        147,        147,        1,   147456, 0xe07b8612
+0,        148,        148,        1,   147456, 0xdf341f10
+0,        149,        149,        1,   147456, 0x5c43a9df
+0,        150,        150,        1,   147456, 0xaf121817
+0,        151,        151,        1,   147456, 0x53ba70bf
diff --git a/tests/ref/fate/parseutils b/tests/ref/fate/parseutils
index 01f6e08..36756a8 100644
--- a/tests/ref/fate/parseutils
+++ b/tests/ref/fate/parseutils
@@ -9,10 +9,10 @@
 ' 123  /  321' -> 41/107 OK
 'foo/foo' -> 0/0 ERROR
 'foo/1' -> 0/0 ERROR
-'1/foo' -> 0/0 ERROR
+'1/foo' -> 1/0 ERROR
 '0/0' -> 0/0 ERROR
 '/0' -> 0/0 ERROR
-'1/' -> 0/0 ERROR
+'1/' -> 1/0 ERROR
 '1' -> 1/1 OK
 '0' -> 0/1 ERROR
 '-123/123' -> -1/1 ERROR
@@ -26,20 +26,57 @@
 ' -21332.2324   ' -> -917286/43 ERROR
 
 Testing av_parse_color()
+bikeshed -> R(80) G(64) B(140) A(59)
+RaNdOm -> R(185) G(88) B(148) A(94)
+foo -> error
 red -> R(255) G(0) B(0) A(255)
+Red  -> error
 RED -> R(255) G(0) B(0) A(255)
 Violet -> R(238) G(130) B(238) A(255)
 Yellow -> R(255) G(255) B(0) A(255)
 Red -> R(255) G(0) B(0) A(255)
 0x000000 -> R(0) G(0) B(0) A(255)
+0x0000000 -> error
 0xff000000 -> R(255) G(0) B(0) A(0)
 0x3e34ff -> R(62) G(52) B(255) A(255)
 0x3e34ffaa -> R(62) G(52) B(255) A(170)
+0xffXXee -> error
+0xfoobar -> error
+0xffffeeeeeeee -> error
 #ff0000 -> R(255) G(0) B(0) A(255)
+#ffXX00 -> error
 ff0000 -> R(255) G(0) B(0) A(255)
+ffXX00 -> error
+red@foo -> error
+random@10 -> error
 0xff0000@1.0 -> R(255) G(0) B(0) A(255)
+red@ -> error
+red@0xfff -> error
 red@0xf -> R(255) G(0) B(0) A(15)
+red@2 -> error
 red@0.1 -> R(255) G(0) B(0) A(25)
+red@-1 -> error
 red@0.5 -> R(255) G(0) B(0) A(127)
 red@1.0 -> R(255) G(0) B(0) A(255)
+red@256 -> error
+red@10foo -> error
+red@-1.0 -> error
 red@-0.0 -> R(255) G(0) B(0) A(0)
+
+Testing av_small_strptime()
+fmt:'%Y-%m-%d' spec:'2012-12-21' -> 2012-12-21 00:00:00
+fmt:'%Y - %m - %d' spec:'2012-12-21' -> 2012-12-21 00:00:00
+fmt:'%Y-%m-%d %H:%M:%S' spec:'2012-12-21 20:12:21' -> 2012-12-21 20:12:21
+fmt:'  %Y - %m - %d %H : %M : %S' spec:'   2012 - 12 -  21   20 : 12 : 21' -> 2012-12-21 20:12:21
+
+Testing av_parse_time()
+(now is 2012-03-17 09:14:13 +0100, local time is UTC+1)
+now                      ->     1331972053.000000 = 2012-03-17T08:14:13Z
+12:35:46                 ->     1331984146.000000 = 2012-03-17T11:35:46Z
+2000-12-20 0:02:47.5z    ->      977270567.500000 = 2000-12-20T00:02:47Z
+2000-12-20T010247.6      ->      977270567.600000 = 2000-12-20T00:02:47Z
+2:34:56.79               ->           +9296790000
+-1:23:45.67              ->           -5025670000
+42.1729                  ->             +42172900
+-1729.42                 ->           -1729420000
+12:34                    -> error
diff --git a/tests/ref/fate/pictor b/tests/ref/fate/pictor
index 3dc4344..c89b608 100644
--- a/tests/ref/fate/pictor
+++ b/tests/ref/fate/pictor
@@ -1,2 +1,2 @@
 #tb 0: 1/25
-0,          0,          0,        1,   192816, 0xf97e2ba1
+0,          0,          0,        1,   192816, 0x29b9c158
diff --git a/tests/ref/fate/prores-422 b/tests/ref/fate/prores-422
index 379739f..acd09e3 100644
--- a/tests/ref/fate/prores-422
+++ b/tests/ref/fate/prores-422
@@ -1,3 +1,3 @@
-#tb 0: 1/2997
-0,          0,          0,        0,  8294400, 0xe8e9d448
-0,        100,        100,        0,  8294400, 0xe8e9d448
+#tb 0: 100/2997
+0,          0,          0,        1,  8294400, 0xe8e9d448
+0,          1,          1,        1,  8294400, 0xe8e9d448
diff --git a/tests/ref/fate/prores-422_hq b/tests/ref/fate/prores-422_hq
index dc93c33..a404ef4 100644
--- a/tests/ref/fate/prores-422_hq
+++ b/tests/ref/fate/prores-422_hq
@@ -1,3 +1,3 @@
-#tb 0: 1/2997
-0,          0,          0,        0,  8294400, 0x817063b0
-0,        100,        100,        0,  8294400, 0x817063b0
+#tb 0: 100/2997
+0,          0,          0,        1,  8294400, 0x817063b0
+0,          1,          1,        1,  8294400, 0x817063b0
diff --git a/tests/ref/fate/prores-422_lt b/tests/ref/fate/prores-422_lt
index 1c50840..09e2408 100644
--- a/tests/ref/fate/prores-422_lt
+++ b/tests/ref/fate/prores-422_lt
@@ -1,3 +1,3 @@
-#tb 0: 1/2997
-0,          0,          0,        0,  8294400, 0xcd4ccde1
-0,        100,        100,        0,  8294400, 0xcd4ccde1
+#tb 0: 100/2997
+0,          0,          0,        1,  8294400, 0xcd4ccde1
+0,          1,          1,        1,  8294400, 0xcd4ccde1
diff --git a/tests/ref/fate/prores-422_proxy b/tests/ref/fate/prores-422_proxy
index 3763b00..d716f87 100644
--- a/tests/ref/fate/prores-422_proxy
+++ b/tests/ref/fate/prores-422_proxy
@@ -1,3 +1,3 @@
-#tb 0: 1/2997
-0,          0,          0,        0,  8294400, 0x51d29320
-0,        100,        100,        0,  8294400, 0x51d29320
+#tb 0: 100/2997
+0,          0,          0,        1,  8294400, 0x51d29320
+0,          1,          1,        1,  8294400, 0x51d29320
diff --git a/tests/ref/fate/prores-alpha b/tests/ref/fate/prores-alpha
index 80442fe..bdb5c6e 100644
--- a/tests/ref/fate/prores-alpha
+++ b/tests/ref/fate/prores-alpha
@@ -1,3 +1,3 @@
-#tb 0: 1/2997
-0,          0,          0,        0, 12441600, 0x254d8f95
-0,        100,        100,        0, 12441600, 0x254d8f95
+#tb 0: 100/2997
+0,          0,          0,        1, 12441600, 0x254d8f95
+0,          1,          1,        1, 12441600, 0x254d8f95
diff --git a/tests/ref/fate/ptx b/tests/ref/fate/ptx
index fad2a50..7edbbdd 100644
--- a/tests/ref/fate/ptx
+++ b/tests/ref/fate/ptx
@@ -1,2 +1,2 @@
 #tb 0: 1/25
-0,          0,          0,        1,   393216, 0xda280efc
+0,          0,          0,        1,   393216, 0x30479950
diff --git a/tests/ref/fate/pva-demux b/tests/ref/fate/pva-demux
index 69b1d40..67d4844 100644
--- a/tests/ref/fate/pva-demux
+++ b/tests/ref/fate/pva-demux
@@ -1,26 +1,27 @@
-#tb 0: 1/90000
-0,          0,          0,     2160,      384, 0x071abcc8
-0,       2160,       2160,     2160,      384, 0x31c9aee0
-0,       4320,       4320,     2160,      384, 0xa50eaa94
-0,       6480,       6480,     2160,      384, 0x9e86ba0e
-0,       8640,       8640,     2160,      384, 0x2321b800
-0,      10800,      10800,     2160,      384, 0x2347afa8
-0,      12960,      12960,     2160,      384, 0x0831b8d3
-0,      15120,      15120,     2160,      384, 0xd5acafa1
-0,      17280,      17280,     2160,      384, 0xc975b9d2
-0,      19440,      19440,     2160,      384, 0x2e10b02a
-0,      21600,      21600,     2160,      384, 0x501eadd0
-0,      23760,      23760,     2160,      384, 0x153fc171
-0,      25920,      25920,     2160,      384, 0xc5f0b3c2
-0,      28080,      28080,     2160,      384, 0xf731b200
-0,      30240,      30240,     2160,      384, 0x2e16b713
-0,      32400,      32400,     2160,      384, 0x61f6bba9
-0,      34560,      34560,     2160,      384, 0x1b9eb0ff
-0,      36720,      36720,     2160,      384, 0x2ab4b7bd
-0,      38880,      38880,     2160,      384, 0xd66eb45c
-0,      41040,      41040,     2160,      384, 0x145ab426
-0,      43200,      43200,     2160,      384, 0x297cb370
-0,      45360,      45360,     2160,      384, 0x287bb6b7
-0,      47520,      47520,     2160,      384, 0xfddbb7df
-0,      49680,      49680,     2160,      384, 0xbbb2af0c
-0,      51840,      51840,     2160,      384, 0x8f03b5fc
+#tb 0: 1/25
+#tb 1: 1/90000
+1,          0,          0,     2160,      384, 0x071abcc8
+1,       2160,       2160,     2160,      384, 0x31c9aee0
+1,       4320,       4320,     2160,      384, 0xa50eaa94
+1,       6480,       6480,     2160,      384, 0x9e86ba0e
+1,       8640,       8640,     2160,      384, 0x2321b800
+1,      10800,      10800,     2160,      384, 0x2347afa8
+1,      12960,      12960,     2160,      384, 0x0831b8d3
+1,      15120,      15120,     2160,      384, 0xd5acafa1
+1,      17280,      17280,     2160,      384, 0xc975b9d2
+1,      19440,      19440,     2160,      384, 0x2e10b02a
+1,      21600,      21600,     2160,      384, 0x501eadd0
+1,      23760,      23760,     2160,      384, 0x153fc171
+1,      25920,      25920,     2160,      384, 0xc5f0b3c2
+1,      28080,      28080,     2160,      384, 0xf731b200
+1,      30240,      30240,     2160,      384, 0x2e16b713
+1,      32400,      32400,     2160,      384, 0x61f6bba9
+1,      34560,      34560,     2160,      384, 0x1b9eb0ff
+1,      36720,      36720,     2160,      384, 0x2ab4b7bd
+1,      38880,      38880,     2160,      384, 0xd66eb45c
+1,      41040,      41040,     2160,      384, 0x145ab426
+1,      43200,      43200,     2160,      384, 0x297cb370
+1,      45360,      45360,     2160,      384, 0x287bb6b7
+1,      47520,      47520,     2160,      384, 0xfddbb7df
+1,      49680,      49680,     2160,      384, 0xbbb2af0c
+1,      51840,      51840,     2160,      384, 0x8f03b5fc
diff --git a/tests/ref/fate/qtrle-16bit b/tests/ref/fate/qtrle-16bit
index d0d71b5..2021f2a 100644
--- a/tests/ref/fate/qtrle-16bit
+++ b/tests/ref/fate/qtrle-16bit
@@ -1,84 +1,84 @@
-#tb 0: 1/600
-0,          0,          0,        1,    57600, 0xe6b0a48c
-0,         40,         40,        1,    57600, 0xe064d51c
-0,         80,         80,        1,    57600, 0xbfce6b33
-0,        120,        120,        1,    57600, 0x371bab02
-0,        160,        160,        1,    57600, 0x0d2d7456
-0,        200,        200,        1,    57600, 0x9184eecb
-0,        240,        240,        1,    57600, 0xb482e8db
-0,        280,        280,        1,    57600, 0x0f4cd4be
-0,        320,        320,        1,    57600, 0xe276cccb
-0,        360,        360,        1,    57600, 0x04c21c62
-0,        400,        400,        1,    57600, 0x848960a2
-0,        440,        440,        1,    57600, 0xc4c8cf03
-0,        480,        480,        1,    57600, 0xb4094866
-0,        520,        520,        1,    57600, 0xf22da043
-0,        560,        560,        1,    57600, 0x6517b67b
-0,        600,        600,        1,    57600, 0x23e39ccb
-0,        640,        640,        1,    57600, 0x41525ca3
-0,        680,        680,        1,    57600, 0xc3edc5f3
-0,        720,        720,        1,    57600, 0x8ce81c7e
-0,        760,        760,        1,    57600, 0x56829443
-0,        800,        800,        1,    57600, 0x511ce287
-0,        840,        840,        1,    57600, 0x8f029a5b
-0,        880,        880,        1,    57600, 0x2b47cf43
-0,        920,        920,        1,    57600, 0x8e7ecf4b
-0,        960,        960,        1,    57600, 0xd620317e
-0,       1000,       1000,        1,    57600, 0x5987646e
-0,       1040,       1040,        1,    57600, 0xcfedb7df
-0,       1080,       1080,        1,    57600, 0x33746e7b
-0,       1120,       1120,        1,    57600, 0x1d318573
-0,       1160,       1160,        1,    57600, 0xc851848b
-0,       1200,       1200,        1,    57600, 0x939db1d7
-0,       1240,       1240,        1,    57600, 0x1719aed3
-0,       1280,       1280,        1,    57600, 0x1ba3e18c
-0,       1320,       1320,        1,    57600, 0x04f355fb
-0,       1360,       1360,        1,    57600, 0x6fafd5f4
-0,       1400,       1400,        1,    57600, 0x434f800b
-0,       1440,       1440,        1,    57600, 0xed42179b
-0,       1480,       1480,        1,    57600, 0x3b33118b
-0,       1520,       1520,        1,    57600, 0xf81880cb
-0,       1560,       1560,        1,    57600, 0xd2c58e1b
-0,       1600,       1600,        1,    57600, 0xd96f50eb
-0,       1640,       1640,        1,    57600, 0x64ef63fb
-0,       1680,       1680,        1,    57600, 0x7b14b6fc
-0,       1720,       1720,        1,    57600, 0xeb1c9054
-0,       1760,       1760,        1,    57600, 0x3b30c97c
-0,       1800,       1800,        1,    57600, 0xc93e9484
-0,       1840,       1840,        1,    57600, 0xe012c0cc
-0,       1880,       1880,        1,    57600, 0x48e2dda4
-0,       1920,       1920,        1,    57600, 0x13eb55fb
-0,       1960,       1960,        1,    57600, 0xa5edbedc
-0,       2000,       2000,        1,    57600, 0x0123a484
-0,       2040,       2040,        1,    57600, 0xc624a7ac
-0,       2080,       2080,        1,    57600, 0xd83cf45c
-0,       2120,       2120,        1,    57600, 0x8f9bf4b4
-0,       2160,       2160,        1,    57600, 0x2d494b8c
-0,       2200,       2200,        1,    57600, 0xb246f07c
-0,       2240,       2240,        1,    57600, 0x5750e67c
-0,       2280,       2280,        1,    57600, 0x6643e9ac
-0,       2320,       2320,        1,    57600, 0x8d3b86b3
-0,       2360,       2360,        1,    57600, 0x4bb0546b
-0,       2400,       2400,        1,    57600, 0xfe439333
-0,       2440,       2440,        1,    57600, 0x0cc76233
-0,       2480,       2480,        1,    57600, 0xb6fe40ae
-0,       2520,       2520,        1,    57600, 0xf79fe0d7
-0,       2560,       2560,        1,    57600, 0xdc90dcbb
-0,       2600,       2600,        1,    57600, 0x371e7c2b
-0,       2640,       2640,        1,    57600, 0x7c4590bb
-0,       2680,       2680,        1,    57600, 0x66f5454b
-0,       2720,       2720,        1,    57600, 0x1678ae5b
-0,       2760,       2760,        1,    57600, 0x1ee8fdec
-0,       2800,       2800,        1,    57600, 0x98d2a083
-0,       2840,       2840,        1,    57600, 0x86d29e5b
-0,       2880,       2880,        1,    57600, 0x23d2bc83
-0,       2920,       2920,        1,    57600, 0x3fc729f2
-0,       2960,       2960,        1,    57600, 0x821d61da
-0,       3000,       3000,        1,    57600, 0xdd549e0e
-0,       3040,       3040,        1,    57600, 0x641234e2
-0,       3080,       3080,        1,    57600, 0x9a282112
-0,       3120,       3120,        1,    57600, 0x6587e2fb
-0,       3160,       3160,        1,    57600, 0x043d0cb2
-0,       3200,       3200,        1,    57600, 0x90328707
-0,       3240,       3240,        1,    57600, 0x5744d313
-0,       3280,       3280,        1,    57600, 0x6e1b95cb
+#tb 0: 1/15
+0,          0,          0,        1,    57600, 0xcf2d39fc
+0,          1,          1,        1,    57600, 0xfc9f6bed
+0,          2,          2,        1,    57600, 0x3f5805bb
+0,          3,          3,        1,    57600, 0xcb34504e
+0,          4,          4,        1,    57600, 0x66b6f6e9
+0,          5,          5,        1,    57600, 0x18698e4d
+0,          6,          6,        1,    57600, 0x233288d7
+0,          7,          7,        1,    57600, 0x6b195ac5
+0,          8,          8,        1,    57600, 0x3b466b45
+0,          9,          9,        1,    57600, 0x9e3dbd75
+0,         10,         10,        1,    57600, 0x90ee04b7
+0,         11,         11,        1,    57600, 0x81096dda
+0,         12,         12,        1,    57600, 0xef24ca50
+0,         13,         13,        1,    57600, 0xea7a3da8
+0,         14,         14,        1,    57600, 0xc3f054c2
+0,         15,         15,        1,    57600, 0x34af39ec
+0,         16,         16,        1,    57600, 0xfc31f846
+0,         17,         17,        1,    57600, 0xa4606399
+0,         18,         18,        1,    57600, 0x4b8a9c88
+0,         19,         19,        1,    57600, 0x87db3195
+0,         20,         20,        1,    57600, 0x443b618d
+0,         21,         21,        1,    57600, 0x601e380e
+0,         22,         22,        1,    57600, 0x405c6e6f
+0,         23,         23,        1,    57600, 0xe6b66f29
+0,         24,         24,        1,    57600, 0xb8e4b2d1
+0,         25,         25,        1,    57600, 0x9fc8e7da
+0,         26,         26,        1,    57600, 0x3bdb363b
+0,         27,         27,        1,    57600, 0xacac0b6a
+0,         28,         28,        1,    57600, 0xff3022fb
+0,         29,         29,        1,    57600, 0x1e5721f3
+0,         30,         30,        1,    57600, 0x511a3071
+0,         31,         31,        1,    57600, 0xff6d4dc0
+0,         32,         32,        1,    57600, 0x5df97a35
+0,         33,         33,        1,    57600, 0x3877f1b1
+0,         34,         34,        1,    57600, 0xa9096dd2
+0,         35,         35,        1,    57600, 0xd36e1ccc
+0,         36,         36,        1,    57600, 0xdc94b124
+0,         37,         37,        1,    57600, 0x873fab49
+0,         38,         38,        1,    57600, 0x7f081dca
+0,         39,         39,        1,    57600, 0x7df52bc3
+0,         40,         40,        1,    57600, 0xf41feb99
+0,         41,         41,        1,    57600, 0xcf59ffeb
+0,         42,         42,        1,    57600, 0x0dd94dfe
+0,         43,         43,        1,    57600, 0xfbc52500
+0,         44,         44,        1,    57600, 0xc300606e
+0,         45,         45,        1,    57600, 0x01e529b4
+0,         46,         46,        1,    57600, 0x359a57b0
+0,         47,         47,        1,    57600, 0xcfee7511
+0,         48,         48,        1,    57600, 0x2189f139
+0,         49,         49,        1,    57600, 0xcc535558
+0,         50,         50,        1,    57600, 0xeed13a76
+0,         51,         51,        1,    57600, 0xfb5c3ddd
+0,         52,         52,        1,    57600, 0x36a98c53
+0,         53,         53,        1,    57600, 0xf4c38c4b
+0,         54,         54,        1,    57600, 0x53d5df15
+0,         55,         55,        1,    57600, 0x336d890c
+0,         56,         56,        1,    57600, 0x19967f1c
+0,         57,         57,        1,    57600, 0xa36b8224
+0,         58,         58,        1,    57600, 0xf6ec2490
+0,         59,         59,        1,    57600, 0x6ffff0d1
+0,         60,         60,        1,    57600, 0xfcb73114
+0,         61,         61,        1,    57600, 0x5f5fff35
+0,         62,         62,        1,    57600, 0xf113c4a0
+0,         63,         63,        1,    57600, 0x64ca6175
+0,         64,         64,        1,    57600, 0x3f6f7d15
+0,         65,         65,        1,    57600, 0x18b619df
+0,         66,         66,        1,    57600, 0xe6872ed7
+0,         67,         67,        1,    57600, 0x3641e174
+0,         68,         68,        1,    57600, 0x4c144d8c
+0,         69,         69,        1,    57600, 0x82529776
+0,         70,         70,        1,    57600, 0xd96f3ead
+0,         71,         71,        1,    57600, 0xce183c4e
+0,         72,         72,        1,    57600, 0xaa475b24
+0,         73,         73,        1,    57600, 0xf7c5cbf3
+0,         74,         74,        1,    57600, 0x798e0548
+0,         75,         75,        1,    57600, 0x1233241a
+0,         76,         76,        1,    57600, 0x1424d758
+0,         77,         77,        1,    57600, 0xa446c264
+0,         78,         78,        1,    57600, 0x66e082ae
+0,         79,         79,        1,    57600, 0xb58cacc8
+0,         80,         80,        1,    57600, 0x3d86431c
+0,         81,         81,        1,    57600, 0x601b724e
+0,         82,         82,        1,    57600, 0xbe9a32c8
diff --git a/tests/ref/fate/qtrle-1bit b/tests/ref/fate/qtrle-1bit
index 1cbaa9c..f191169 100644
--- a/tests/ref/fate/qtrle-1bit
+++ b/tests/ref/fate/qtrle-1bit
@@ -1,39 +1,39 @@
-#tb 0: 1/1200
-0,          0,          0,        0,     9600, 0xc1632102
-0,        100,        100,        0,     9600, 0x0f6c0521
-0,        200,        200,        0,     9600, 0x04b90b5a
-0,        300,        300,        0,     9600, 0x2ebd4500
-0,        400,        400,        0,     9600, 0x726f46f4
-0,        500,        500,        0,     9600, 0x37f6968e
-0,        600,        600,        0,     9600, 0x7305872e
-0,        700,        700,        0,     9600, 0x222eff5e
-0,        800,        800,        0,     9600, 0x9317e227
-0,        900,        900,        0,     9600, 0x421eee9d
-0,       1000,       1000,        0,     9600, 0xcbcfaaff
-0,       1100,       1100,        0,     9600, 0xe7d43be2
-0,       1200,       1200,        0,     9600, 0x0b71e28c
-0,       1300,       1300,        0,     9600, 0xd6a050ca
-0,       1400,       1400,        0,     9600, 0x0ac6dbf5
-0,       1500,       1500,        0,     9600, 0x5c036038
-0,       1600,       1600,        0,     9600, 0x6e417ed6
-0,       1700,       1700,        0,     9600, 0x8bd0dc22
-0,       1800,       1800,        0,     9600, 0xdf3b0877
-0,       1900,       1900,        0,     9600, 0xae6e7823
-0,       2000,       2000,        0,     9600, 0x8ff0ac32
-0,       2100,       2100,        0,     9600, 0xa2d9e2ce
-0,       2200,       2200,        0,     9600, 0x5fd92b65
-0,       2300,       2300,        0,     9600, 0x81c1c824
-0,       2400,       2400,        0,     9600, 0xb8a2ace4
-0,       2500,       2500,        0,     9600, 0x65b70404
-0,       2600,       2600,        0,     9600, 0xc5349eb2
-0,       2700,       2700,        0,     9600, 0xf60cc2b8
-0,       2800,       2800,        0,     9600, 0x31474595
-0,       2900,       2900,        0,     9600, 0xf602635b
-0,       3000,       3000,        0,     9600, 0x873cbd87
-0,       3100,       3100,        0,     9600, 0xb9793ffe
-0,       3200,       3200,        0,     9600, 0x42eb2831
-0,       3300,       3300,        0,     9600, 0x44cc1dab
-0,       3400,       3400,        0,     9600, 0xbdcbbb87
-0,       3500,       3500,        0,     9600, 0x29c22df7
-0,       3600,       3600,        0,     9600, 0xde502ef5
-0,       3700,       3700,        0,     9600, 0xaf311aeb
+#tb 0: 1/12
+0,          0,          0,        1,     9600, 0xc5921aa2
+0,          1,          1,        1,     9600, 0x9032fc52
+0,          2,          2,        1,     9600, 0x7db0038e
+0,          3,          3,        1,     9600, 0x95b73c41
+0,          4,          4,        1,     9600, 0x531e4189
+0,          5,          5,        1,     9600, 0xb73390ec
+0,          6,          6,        1,     9600, 0x958e8221
+0,          7,          7,        1,     9600, 0xd393f8a6
+0,          8,          8,        1,     9600, 0xa085da1c
+0,          9,          9,        1,     9600, 0x57ace74f
+0,         10,         10,        1,     9600, 0x5d11a308
+0,         11,         11,        1,     9600, 0x13e133b7
+0,         12,         12,        1,     9600, 0x494edb86
+0,         13,         13,        1,     9600, 0x43a448ea
+0,         14,         14,        1,     9600, 0x3562d35b
+0,         15,         15,        1,     9600, 0x0bc655d2
+0,         16,         16,        1,     9600, 0xbece73a1
+0,         17,         17,        1,     9600, 0x82e7cfa1
+0,         18,         18,        1,     9600, 0xda29fd8f
+0,         19,         19,        1,     9600, 0x70fb700b
+0,         20,         20,        1,     9600, 0xaf57a6b0
+0,         21,         21,        1,     9600, 0x0a5ed9b9
+0,         22,         22,        1,     9600, 0xf7c62c38
+0,         23,         23,        1,     9600, 0x0aa2ccfd
+0,         24,         24,        1,     9600, 0xc9adabae
+0,         25,         25,        1,     9600, 0x67ff0aba
+0,         26,         26,        1,     9600, 0xea79a465
+0,         27,         27,        1,     9600, 0x8928c626
+0,         28,         28,        1,     9600, 0x8dab4111
+0,         29,         29,        1,     9600, 0x81ef63f9
+0,         30,         30,        1,     9600, 0xf977bc5e
+0,         31,         31,        1,     9600, 0x9e6a3f4a
+0,         32,         32,        1,     9600, 0x77c92865
+0,         33,         33,        1,     9600, 0x3915170d
+0,         34,         34,        1,     9600, 0xbe19b995
+0,         35,         35,        1,     9600, 0x3e8a3077
+0,         36,         36,        1,     9600, 0x1331342e
+0,         37,         37,        1,     9600, 0x4d692175
diff --git a/tests/ref/fate/qtrle-24bit b/tests/ref/fate/qtrle-24bit
index 7a162b8..a21b099 100644
--- a/tests/ref/fate/qtrle-24bit
+++ b/tests/ref/fate/qtrle-24bit
@@ -1,35 +1,35 @@
-#tb 0: 1/600
+#tb 0: 1/10
 0,          0,          0,        1,    57600, 0x3718ad00
-0,         60,         60,        1,    57600, 0x54861558
-0,        120,        120,        1,    57600, 0xea1d6233
-0,        180,        180,        1,    57600, 0xf669a2fd
-0,        240,        240,        1,    57600, 0xc9f76f31
-0,        300,        300,        1,    57600, 0xe23c6d7b
-0,        360,        360,        1,    57600, 0xbc9d6167
-0,        420,        420,        1,    57600, 0x0ca63477
-0,        480,        480,        1,    57600, 0xc0850d22
-0,        540,        540,        1,    57600, 0x735d10b2
-0,        600,        600,        1,    57600, 0x561f3c4a
-0,        660,        660,        1,    57600, 0x84db9cf1
-0,        720,        720,        1,    57600, 0x9fb841f4
-0,        780,        780,        1,    57600, 0xeaf262ab
-0,        840,        840,        1,    57600, 0x264886b4
-0,        900,        900,        1,    57600, 0x5edc5518
-0,        960,        960,        1,    57600, 0xd3e60c72
-0,       1020,       1020,        1,    57600, 0x9cabaed7
-0,       1080,       1080,        1,    57600, 0x616716cf
-0,       1140,       1140,        1,    57600, 0xa43f61aa
-0,       1200,       1200,        1,    57600, 0xdba3a0bd
-0,       1260,       1260,        1,    57600, 0xa7dd6dfa
-0,       1320,       1320,        1,    57600, 0xc3fa6c84
-0,       1380,       1380,        1,    57600, 0xb1275fb8
-0,       1440,       1440,        1,    57600, 0x2e39331f
-0,       1500,       1500,        1,    57600, 0x5b9e0bca
-0,       1560,       1560,        1,    57600, 0x0e760f5a
-0,       1620,       1620,        1,    57600, 0xc56c3e69
-0,       1680,       1680,        1,    57600, 0x51da9fb8
-0,       1740,       1740,        1,    57600, 0xe3a1432b
-0,       1800,       1800,        1,    57600, 0xe1b360a3
-0,       1860,       1860,        1,    57600, 0x30b383cd
-0,       1920,       1920,        1,    57600, 0x950c5439
-0,       1980,       1980,        1,    57600, 0x8f9d0ca2
+0,          1,          1,        1,    57600, 0x54861558
+0,          2,          2,        1,    57600, 0xea1d6233
+0,          3,          3,        1,    57600, 0xf669a2fd
+0,          4,          4,        1,    57600, 0xc9f76f31
+0,          5,          5,        1,    57600, 0xe23c6d7b
+0,          6,          6,        1,    57600, 0xbc9d6167
+0,          7,          7,        1,    57600, 0x0ca63477
+0,          8,          8,        1,    57600, 0xc0850d22
+0,          9,          9,        1,    57600, 0x735d10b2
+0,         10,         10,        1,    57600, 0x561f3c4a
+0,         11,         11,        1,    57600, 0x84db9cf1
+0,         12,         12,        1,    57600, 0x9fb841f4
+0,         13,         13,        1,    57600, 0xeaf262ab
+0,         14,         14,        1,    57600, 0x264886b4
+0,         15,         15,        1,    57600, 0x5edc5518
+0,         16,         16,        1,    57600, 0xd3e60c72
+0,         17,         17,        1,    57600, 0x9cabaed7
+0,         18,         18,        1,    57600, 0x616716cf
+0,         19,         19,        1,    57600, 0xa43f61aa
+0,         20,         20,        1,    57600, 0xdba3a0bd
+0,         21,         21,        1,    57600, 0xa7dd6dfa
+0,         22,         22,        1,    57600, 0xc3fa6c84
+0,         23,         23,        1,    57600, 0xb1275fb8
+0,         24,         24,        1,    57600, 0x2e39331f
+0,         25,         25,        1,    57600, 0x5b9e0bca
+0,         26,         26,        1,    57600, 0x0e760f5a
+0,         27,         27,        1,    57600, 0xc56c3e69
+0,         28,         28,        1,    57600, 0x51da9fb8
+0,         29,         29,        1,    57600, 0xe3a1432b
+0,         30,         30,        1,    57600, 0xe1b360a3
+0,         31,         31,        1,    57600, 0x30b383cd
+0,         32,         32,        1,    57600, 0x950c5439
+0,         33,         33,        1,    57600, 0x8f9d0ca2
diff --git a/tests/ref/fate/qtrle-2bit b/tests/ref/fate/qtrle-2bit
index 5866db5..95c0f7c 100644
--- a/tests/ref/fate/qtrle-2bit
+++ b/tests/ref/fate/qtrle-2bit
@@ -1,39 +1,39 @@
-#tb 0: 1/1200
-0,          0,          0,        0,   230400, 0xb1ee55dc
-0,        100,        100,        0,   230400, 0x97c580bf
-0,        200,        200,        0,   230400, 0xd4bd57e8
-0,        300,        300,        0,   230400, 0x412b79aa
-0,        400,        400,        0,   230400, 0x928a44d1
-0,        500,        500,        0,   230400, 0x6bbdc0e4
-0,        600,        600,        0,   230400, 0x382e960f
-0,        700,        700,        0,   230400, 0x62c863ea
-0,        800,        800,        0,   230400, 0xbfccd3ce
-0,        900,        900,        0,   230400, 0x1987cdd4
-0,       1000,       1000,        0,   230400, 0x40279727
-0,       1100,       1100,        0,   230400, 0x9d4f6746
-0,       1200,       1200,        0,   230400, 0x7b8a77ec
-0,       1300,       1300,        0,   230400, 0x2ce7a781
-0,       1400,       1400,        0,   230400, 0xb749815e
-0,       1500,       1500,        0,   230400, 0x61c88610
-0,       1600,       1600,        0,   230400, 0x8449114d
-0,       1700,       1700,        0,   230400, 0x5f73e666
-0,       1800,       1800,        0,   230400, 0xbde53ce6
-0,       1900,       1900,        0,   230400, 0x8c7406fd
-0,       2000,       2000,        0,   230400, 0xf9e9a3ef
-0,       2100,       2100,        0,   230400, 0x7e0a3077
-0,       2200,       2200,        0,   230400, 0xd9245c5f
-0,       2300,       2300,        0,   230400, 0x6d077ea2
-0,       2400,       2400,        0,   230400, 0xf622bb2a
-0,       2500,       2500,        0,   230400, 0x35292dc8
-0,       2600,       2600,        0,   230400, 0xc0cea946
-0,       2700,       2700,        0,   230400, 0x98b27b60
-0,       2800,       2800,        0,   230400, 0x668ef6bd
-0,       2900,       2900,        0,   230400, 0x6c07a31c
-0,       3000,       3000,        0,   230400, 0x0b4a6ae1
-0,       3100,       3100,        0,   230400, 0x945b9878
-0,       3200,       3200,        0,   230400, 0xab28031c
-0,       3300,       3300,        0,   230400, 0x977252b0
-0,       3400,       3400,        0,   230400, 0x6c3d9706
-0,       3500,       3500,        0,   230400, 0xe053bc2a
-0,       3600,       3600,        0,   230400, 0x4cf2fc7c
-0,       3700,       3700,        0,   230400, 0x610beda7
+#tb 0: 1/12
+0,          0,          0,        1,   230400, 0xb1ee55dc
+0,          1,          1,        1,   230400, 0x97c580bf
+0,          2,          2,        1,   230400, 0xd4bd57e8
+0,          3,          3,        1,   230400, 0x412b79aa
+0,          4,          4,        1,   230400, 0x928a44d1
+0,          5,          5,        1,   230400, 0x6bbdc0e4
+0,          6,          6,        1,   230400, 0x382e960f
+0,          7,          7,        1,   230400, 0x62c863ea
+0,          8,          8,        1,   230400, 0xbfccd3ce
+0,          9,          9,        1,   230400, 0x1987cdd4
+0,         10,         10,        1,   230400, 0x40279727
+0,         11,         11,        1,   230400, 0x9d4f6746
+0,         12,         12,        1,   230400, 0x7b8a77ec
+0,         13,         13,        1,   230400, 0x2ce7a781
+0,         14,         14,        1,   230400, 0xb749815e
+0,         15,         15,        1,   230400, 0x61c88610
+0,         16,         16,        1,   230400, 0x8449114d
+0,         17,         17,        1,   230400, 0x5f73e666
+0,         18,         18,        1,   230400, 0xbde53ce6
+0,         19,         19,        1,   230400, 0x8c7406fd
+0,         20,         20,        1,   230400, 0xf9e9a3ef
+0,         21,         21,        1,   230400, 0x7e0a3077
+0,         22,         22,        1,   230400, 0xd9245c5f
+0,         23,         23,        1,   230400, 0x6d077ea2
+0,         24,         24,        1,   230400, 0xf622bb2a
+0,         25,         25,        1,   230400, 0x35292dc8
+0,         26,         26,        1,   230400, 0xc0cea946
+0,         27,         27,        1,   230400, 0x98b27b60
+0,         28,         28,        1,   230400, 0x668ef6bd
+0,         29,         29,        1,   230400, 0x6c07a31c
+0,         30,         30,        1,   230400, 0x0b4a6ae1
+0,         31,         31,        1,   230400, 0x945b9878
+0,         32,         32,        1,   230400, 0xab28031c
+0,         33,         33,        1,   230400, 0x977252b0
+0,         34,         34,        1,   230400, 0x6c3d9706
+0,         35,         35,        1,   230400, 0xe053bc2a
+0,         36,         36,        1,   230400, 0x4cf2fc7c
+0,         37,         37,        1,   230400, 0x610beda7
diff --git a/tests/ref/fate/qtrle-32bit b/tests/ref/fate/qtrle-32bit
index bbdd464..ed6dc03 100644
--- a/tests/ref/fate/qtrle-32bit
+++ b/tests/ref/fate/qtrle-32bit
@@ -1,27 +1,27 @@
-#tb 0: 1/2997
-0,          0,          0,        0,  1036800, 0x2a90d062
-0,        100,        100,        0,  1036800, 0x6565aded
-0,        200,        200,        0,  1036800, 0xf0b587d2
-0,        300,        300,        0,  1036800, 0xf0b4e53f
-0,        400,        400,        0,  1036800, 0x5ba4b96a
-0,        500,        500,        0,  1036800, 0x501df9c1
-0,        600,        600,        0,  1036800, 0xcf45b940
-0,        700,        700,        0,  1036800, 0xa454df07
-0,        800,        800,        0,  1036800, 0xc504d152
-0,        900,        900,        0,  1036800, 0xd90ecac7
-0,       1000,       1000,        0,  1036800, 0xe30368df
-0,       1100,       1100,        0,  1036800, 0x0ca35522
-0,       1200,       1200,        0,  1036800, 0xe76b8d43
-0,       1300,       1300,        0,  1036800, 0x7c85a447
-0,       1400,       1400,        0,  1036800, 0x3e2d1b5f
-0,       1500,       1500,        0,  1036800, 0x230fa5a6
-0,       1600,       1600,        0,  1036800, 0x4fad025e
-0,       1700,       1700,        0,  1036800, 0x7d3366ae
-0,       1800,       1800,        0,  1036800, 0xa83720f7
-0,       1900,       1900,        0,  1036800, 0x5dbd13b1
-0,       2000,       2000,        0,  1036800, 0xd0ebd56d
-0,       2100,       2100,        0,  1036800, 0x4d7c67f3
-0,       2200,       2200,        0,  1036800, 0x226baa3f
-0,       2300,       2300,        0,  1036800, 0xc0e93acf
-0,       2400,       2400,        0,  1036800, 0x5a466c17
-0,       2500,       2500,        0,  1036800, 0xfdb7d2ea
+#tb 0: 100/2997
+0,          0,          0,        1,  1036800, 0x2a90d062
+0,          1,          1,        1,  1036800, 0x6565aded
+0,          2,          2,        1,  1036800, 0xf0b587d2
+0,          3,          3,        1,  1036800, 0xf0b4e53f
+0,          4,          4,        1,  1036800, 0x5ba4b96a
+0,          5,          5,        1,  1036800, 0x501df9c1
+0,          6,          6,        1,  1036800, 0xcf45b940
+0,          7,          7,        1,  1036800, 0xa454df07
+0,          8,          8,        1,  1036800, 0xc504d152
+0,          9,          9,        1,  1036800, 0xd90ecac7
+0,         10,         10,        1,  1036800, 0xe30368df
+0,         11,         11,        1,  1036800, 0x0ca35522
+0,         12,         12,        1,  1036800, 0xe76b8d43
+0,         13,         13,        1,  1036800, 0x7c85a447
+0,         14,         14,        1,  1036800, 0x3e2d1b5f
+0,         15,         15,        1,  1036800, 0x230fa5a6
+0,         16,         16,        1,  1036800, 0x4fad025e
+0,         17,         17,        1,  1036800, 0x7d3366ae
+0,         18,         18,        1,  1036800, 0xa83720f7
+0,         19,         19,        1,  1036800, 0x5dbd13b1
+0,         20,         20,        1,  1036800, 0xd0ebd56d
+0,         21,         21,        1,  1036800, 0x4d7c67f3
+0,         22,         22,        1,  1036800, 0x226baa3f
+0,         23,         23,        1,  1036800, 0xc0e93acf
+0,         24,         24,        1,  1036800, 0x5a466c17
+0,         25,         25,        1,  1036800, 0xfdb7d2ea
diff --git a/tests/ref/fate/qtrle-4bit b/tests/ref/fate/qtrle-4bit
index cc09e78..74eb4ab 100644
--- a/tests/ref/fate/qtrle-4bit
+++ b/tests/ref/fate/qtrle-4bit
@@ -1,39 +1,39 @@
-#tb 0: 1/1200
-0,          0,          0,        0,   230400, 0x0655b3d9
-0,        100,        100,        0,   230400, 0x9c626fd3
-0,        200,        200,        0,   230400, 0x5bc95868
-0,        300,        300,        0,   230400, 0x55a38387
-0,        400,        400,        0,   230400, 0xd3495b60
-0,        500,        500,        0,   230400, 0xecdb2d15
-0,        600,        600,        0,   230400, 0x7f9b373e
-0,        700,        700,        0,   230400, 0x51caac22
-0,        800,        800,        0,   230400, 0x0f2ac153
-0,        900,        900,        0,   230400, 0xe5a6f9e7
-0,       1000,       1000,        0,   230400, 0xfc2b2250
-0,       1100,       1100,        0,   230400, 0x24e2da1b
-0,       1200,       1200,        0,   230400, 0x2723d7dd
-0,       1300,       1300,        0,   230400, 0x024a4989
-0,       1400,       1400,        0,   230400, 0xdbafb92d
-0,       1500,       1500,        0,   230400, 0x6b9b5056
-0,       1600,       1600,        0,   230400, 0x010cabb4
-0,       1700,       1700,        0,   230400, 0xf75bc1c0
-0,       1800,       1800,        0,   230400, 0x6c7fd744
-0,       1900,       1900,        0,   230400, 0xabe4371a
-0,       2000,       2000,        0,   230400, 0xe41fb781
-0,       2100,       2100,        0,   230400, 0x42c5649e
-0,       2200,       2200,        0,   230400, 0xf5511deb
-0,       2300,       2300,        0,   230400, 0xebf5ab32
-0,       2400,       2400,        0,   230400, 0x44398194
-0,       2500,       2500,        0,   230400, 0xfd63510c
-0,       2600,       2600,        0,   230400, 0xa013975e
-0,       2700,       2700,        0,   230400, 0xe0aa028d
-0,       2800,       2800,        0,   230400, 0x349f6f3b
-0,       2900,       2900,        0,   230400, 0x2446032c
-0,       3000,       3000,        0,   230400, 0x648f122c
-0,       3100,       3100,        0,   230400, 0xbda221fd
-0,       3200,       3200,        0,   230400, 0xf0f97642
-0,       3300,       3300,        0,   230400, 0x6a1737de
-0,       3400,       3400,        0,   230400, 0x808a8179
-0,       3500,       3500,        0,   230400, 0x121641cf
-0,       3600,       3600,        0,   230400, 0x275d11ea
-0,       3700,       3700,        0,   230400, 0x92adf2cf
+#tb 0: 1/12
+0,          0,          0,        1,   230400, 0x0655b3d9
+0,          1,          1,        1,   230400, 0x9c626fd3
+0,          2,          2,        1,   230400, 0x5bc95868
+0,          3,          3,        1,   230400, 0x55a38387
+0,          4,          4,        1,   230400, 0xd3495b60
+0,          5,          5,        1,   230400, 0xecdb2d15
+0,          6,          6,        1,   230400, 0x7f9b373e
+0,          7,          7,        1,   230400, 0x51caac22
+0,          8,          8,        1,   230400, 0x0f2ac153
+0,          9,          9,        1,   230400, 0xe5a6f9e7
+0,         10,         10,        1,   230400, 0xfc2b2250
+0,         11,         11,        1,   230400, 0x24e2da1b
+0,         12,         12,        1,   230400, 0x2723d7dd
+0,         13,         13,        1,   230400, 0x024a4989
+0,         14,         14,        1,   230400, 0xdbafb92d
+0,         15,         15,        1,   230400, 0x6b9b5056
+0,         16,         16,        1,   230400, 0x010cabb4
+0,         17,         17,        1,   230400, 0xf75bc1c0
+0,         18,         18,        1,   230400, 0x6c7fd744
+0,         19,         19,        1,   230400, 0xabe4371a
+0,         20,         20,        1,   230400, 0xe41fb781
+0,         21,         21,        1,   230400, 0x42c5649e
+0,         22,         22,        1,   230400, 0xf5511deb
+0,         23,         23,        1,   230400, 0xebf5ab32
+0,         24,         24,        1,   230400, 0x44398194
+0,         25,         25,        1,   230400, 0xfd63510c
+0,         26,         26,        1,   230400, 0xa013975e
+0,         27,         27,        1,   230400, 0xe0aa028d
+0,         28,         28,        1,   230400, 0x349f6f3b
+0,         29,         29,        1,   230400, 0x2446032c
+0,         30,         30,        1,   230400, 0x648f122c
+0,         31,         31,        1,   230400, 0xbda221fd
+0,         32,         32,        1,   230400, 0xf0f97642
+0,         33,         33,        1,   230400, 0x6a1737de
+0,         34,         34,        1,   230400, 0x808a8179
+0,         35,         35,        1,   230400, 0x121641cf
+0,         36,         36,        1,   230400, 0x275d11ea
+0,         37,         37,        1,   230400, 0x92adf2cf
diff --git a/tests/ref/fate/qtrle-8bit b/tests/ref/fate/qtrle-8bit
index bef2358..5b30fbb 100644
--- a/tests/ref/fate/qtrle-8bit
+++ b/tests/ref/fate/qtrle-8bit
@@ -1,168 +1,168 @@
-#tb 0: 1/600
+#tb 0: 1/15
 0,          0,          0,        1,   921600, 0x1492e3ed
-0,         40,         40,        1,   921600, 0x1492e3ed
-0,         80,         80,        1,   921600, 0x1492e3ed
-0,        120,        120,        1,   921600, 0x23ef4fc7
-0,        160,        160,        1,   921600, 0x23ef4fc7
-0,        200,        200,        1,   921600, 0xe406d4be
-0,        240,        240,        1,   921600, 0xe406d4be
-0,        280,        280,        1,   921600, 0xe406d4be
-0,        320,        320,        1,   921600, 0x62b8b5a1
-0,        360,        360,        1,   921600, 0x62b8b5a1
-0,        400,        400,        1,   921600, 0x7d8ba674
-0,        440,        440,        1,   921600, 0x7d8ba674
-0,        480,        480,        1,   921600, 0x7d8ba674
-0,        520,        520,        1,   921600, 0xfe666be7
-0,        560,        560,        1,   921600, 0xfe666be7
-0,        600,        600,        1,   921600, 0x721baec0
-0,        640,        640,        1,   921600, 0x721baec0
-0,        680,        680,        1,   921600, 0x721baec0
-0,        720,        720,        1,   921600, 0xc237180a
-0,        760,        760,        1,   921600, 0xc237180a
-0,        800,        800,        1,   921600, 0xf03a7482
-0,        840,        840,        1,   921600, 0xf03a7482
-0,        880,        880,        1,   921600, 0xf03a7482
-0,        920,        920,        1,   921600, 0x5612a391
-0,        960,        960,        1,   921600, 0x5612a391
-0,       1000,       1000,        1,   921600, 0x9dbcc46a
-0,       1040,       1040,        1,   921600, 0x9dbcc46a
-0,       1080,       1080,        1,   921600, 0x9dbcc46a
-0,       1120,       1120,        1,   921600, 0xa128a5d5
-0,       1160,       1160,        1,   921600, 0xa128a5d5
-0,       1200,       1200,        1,   921600, 0x63e0025c
-0,       1240,       1240,        1,   921600, 0x63e0025c
-0,       1280,       1280,        1,   921600, 0x63e0025c
-0,       1320,       1320,        1,   921600, 0x262359ed
-0,       1360,       1360,        1,   921600, 0x262359ed
-0,       1400,       1400,        1,   921600, 0x343688e8
-0,       1440,       1440,        1,   921600, 0x343688e8
-0,       1480,       1480,        1,   921600, 0x343688e8
-0,       1520,       1520,        1,   921600, 0x343688e8
-0,       1560,       1560,        1,   921600, 0x343688e8
-0,       1600,       1600,        1,   921600, 0x343688e8
-0,       1640,       1640,        1,   921600, 0x343688e8
-0,       1680,       1680,        1,   921600, 0x343688e8
-0,       1720,       1720,        1,   921600, 0x343688e8
-0,       1760,       1760,        1,   921600, 0x343688e8
-0,       1800,       1800,        1,   921600, 0xe4b29d57
-0,       1840,       1840,        1,   921600, 0xe4b29d57
-0,       1880,       1880,        1,   921600, 0xe4b29d57
-0,       1920,       1920,        1,   921600, 0x198e8a4a
-0,       1960,       1960,        1,   921600, 0x198e8a4a
-0,       2000,       2000,        1,   921600, 0x0cad8dc9
-0,       2040,       2040,        1,   921600, 0x0cad8dc9
-0,       2080,       2080,        1,   921600, 0x0cad8dc9
-0,       2120,       2120,        1,   921600, 0x1f74cf3d
-0,       2160,       2160,        1,   921600, 0x1f74cf3d
-0,       2200,       2200,        1,   921600, 0xec5b5449
-0,       2240,       2240,        1,   921600, 0xec5b5449
-0,       2280,       2280,        1,   921600, 0xec5b5449
-0,       2320,       2320,        1,   921600, 0x39829711
-0,       2360,       2360,        1,   921600, 0x39829711
-0,       2400,       2400,        1,   921600, 0x6de5b9c6
-0,       2440,       2440,        1,   921600, 0x6de5b9c6
-0,       2480,       2480,        1,   921600, 0x6de5b9c6
-0,       2520,       2520,        1,   921600, 0x47b0e9d4
-0,       2560,       2560,        1,   921600, 0x47b0e9d4
-0,       2600,       2600,        1,   921600, 0x756452b8
-0,       2640,       2640,        1,   921600, 0x756452b8
-0,       2680,       2680,        1,   921600, 0x756452b8
-0,       2720,       2720,        1,   921600, 0x6fce3478
-0,       2760,       2760,        1,   921600, 0x6fce3478
-0,       2800,       2800,        1,   921600, 0x372397cd
-0,       2840,       2840,        1,   921600, 0x372397cd
-0,       2880,       2880,        1,   921600, 0x372397cd
-0,       2920,       2920,        1,   921600, 0xe3999ba1
-0,       2960,       2960,        1,   921600, 0xe3999ba1
-0,       3000,       3000,        1,   921600, 0x6ba26b43
-0,       3040,       3040,        1,   921600, 0x6ba26b43
-0,       3080,       3080,        1,   921600, 0x6ba26b43
-0,       3120,       3120,        1,   921600, 0x4e9ee49e
-0,       3160,       3160,        1,   921600, 0x4e9ee49e
-0,       3200,       3200,        1,   921600, 0xdb5fd6e7
-0,       3240,       3240,        1,   921600, 0xdb5fd6e7
-0,       3280,       3280,        1,   921600, 0xdb5fd6e7
-0,       3320,       3320,        1,   921600, 0x8f2254a5
-0,       3360,       3360,        1,   921600, 0x8f2254a5
-0,       3400,       3400,        1,   921600, 0x8f2254a5
-0,       3440,       3440,        1,   921600, 0x8f2254a5
-0,       3480,       3480,        1,   921600, 0x8f2254a5
-0,       3520,       3520,        1,   921600, 0x8f2254a5
-0,       3560,       3560,        1,   921600, 0x8f2254a5
-0,       3600,       3600,        1,   921600, 0x8f2254a5
-0,       3640,       3640,        1,   921600, 0x8f2254a5
-0,       3680,       3680,        1,   921600, 0x8f2254a5
-0,       3720,       3720,        1,   921600, 0x57e95c32
-0,       3760,       3760,        1,   921600, 0x57e95c32
-0,       3800,       3800,        1,   921600, 0x41627a9b
-0,       3840,       3840,        1,   921600, 0x41627a9b
-0,       3880,       3880,        1,   921600, 0x41627a9b
-0,       3920,       3920,        1,   921600, 0x7412dcee
-0,       3960,       3960,        1,   921600, 0x7412dcee
-0,       4000,       4000,        1,   921600, 0xaebe10ed
-0,       4040,       4040,        1,   921600, 0xaebe10ed
-0,       4080,       4080,        1,   921600, 0xaebe10ed
-0,       4120,       4120,        1,   921600, 0x411a91f6
-0,       4160,       4160,        1,   921600, 0x411a91f6
-0,       4200,       4200,        1,   921600, 0xb059df3f
-0,       4240,       4240,        1,   921600, 0xb059df3f
-0,       4280,       4280,        1,   921600, 0xb059df3f
-0,       4320,       4320,        1,   921600, 0x4d6f5a77
-0,       4360,       4360,        1,   921600, 0x4d6f5a77
-0,       4400,       4400,        1,   921600, 0xbbf06df4
-0,       4440,       4440,        1,   921600, 0xbbf06df4
-0,       4480,       4480,        1,   921600, 0xbbf06df4
-0,       4520,       4520,        1,   921600, 0xe27f7bf6
-0,       4560,       4560,        1,   921600, 0xe27f7bf6
-0,       4600,       4600,        1,   921600, 0xd7e8360e
-0,       4640,       4640,        1,   921600, 0xd7e8360e
-0,       4680,       4680,        1,   921600, 0xd7e8360e
-0,       4720,       4720,        1,   921600, 0x1dd4c344
-0,       4760,       4760,        1,   921600, 0x1dd4c344
-0,       4800,       4800,        1,   921600, 0x7995a7ce
-0,       4840,       4840,        1,   921600, 0x7995a7ce
-0,       4880,       4880,        1,   921600, 0x7995a7ce
-0,       4920,       4920,        1,   921600, 0x2ef3c566
-0,       4960,       4960,        1,   921600, 0x2ef3c566
-0,       5000,       5000,        1,   921600, 0xf296736e
-0,       5040,       5040,        1,   921600, 0xf296736e
-0,       5080,       5080,        1,   921600, 0xf296736e
-0,       5120,       5120,        1,   921600, 0xf296736e
-0,       5160,       5160,        1,   921600, 0xf296736e
-0,       5200,       5200,        1,   921600, 0xf296736e
-0,       5240,       5240,        1,   921600, 0xf296736e
-0,       5280,       5280,        1,   921600, 0xf296736e
-0,       5320,       5320,        1,   921600, 0xf296736e
-0,       5360,       5360,        1,   921600, 0xf296736e
-0,       5400,       5400,        1,   921600, 0x1a488311
-0,       5440,       5440,        1,   921600, 0x1a488311
-0,       5480,       5480,        1,   921600, 0x1a488311
-0,       5520,       5520,        1,   921600, 0x9e28011b
-0,       5560,       5560,        1,   921600, 0x9e28011b
-0,       5600,       5600,        1,   921600, 0x84d1ea80
-0,       5640,       5640,        1,   921600, 0x84d1ea80
-0,       5680,       5680,        1,   921600, 0x84d1ea80
-0,       5720,       5720,        1,   921600, 0x9ed41052
-0,       5760,       5760,        1,   921600, 0x9ed41052
-0,       5800,       5800,        1,   921600, 0xd4db7206
-0,       5840,       5840,        1,   921600, 0xd4db7206
-0,       5880,       5880,        1,   921600, 0xd4db7206
-0,       5920,       5920,        1,   921600, 0x55f695a9
-0,       5960,       5960,        1,   921600, 0x55f695a9
-0,       6000,       6000,        1,   921600, 0x9d8c667f
-0,       6040,       6040,        1,   921600, 0x9d8c667f
-0,       6080,       6080,        1,   921600, 0x9d8c667f
-0,       6120,       6120,        1,   921600, 0x9b6037ec
-0,       6160,       6160,        1,   921600, 0x9b6037ec
-0,       6200,       6200,        1,   921600, 0x57c5e835
-0,       6240,       6240,        1,   921600, 0x57c5e835
-0,       6280,       6280,        1,   921600, 0x57c5e835
-0,       6320,       6320,        1,   921600, 0x476dad89
-0,       6360,       6360,        1,   921600, 0x476dad89
-0,       6400,       6400,        1,   921600, 0xcfd6ad2b
-0,       6440,       6440,        1,   921600, 0xcfd6ad2b
-0,       6480,       6480,        1,   921600, 0xcfd6ad2b
-0,       6520,       6520,        1,   921600, 0x3b372379
-0,       6560,       6560,        1,   921600, 0x3b372379
-0,       6600,       6600,        1,   921600, 0x36f245f5
-0,       6620,       6620,        1,   921600, 0x36f245f5
+0,          1,          1,        1,   921600, 0x1492e3ed
+0,          2,          2,        1,   921600, 0x1492e3ed
+0,          3,          3,        1,   921600, 0x23ef4fc7
+0,          4,          4,        1,   921600, 0x23ef4fc7
+0,          5,          5,        1,   921600, 0xe406d4be
+0,          6,          6,        1,   921600, 0xe406d4be
+0,          7,          7,        1,   921600, 0xe406d4be
+0,          8,          8,        1,   921600, 0x62b8b5a1
+0,          9,          9,        1,   921600, 0x62b8b5a1
+0,         10,         10,        1,   921600, 0x7d8ba674
+0,         11,         11,        1,   921600, 0x7d8ba674
+0,         12,         12,        1,   921600, 0x7d8ba674
+0,         13,         13,        1,   921600, 0xfe666be7
+0,         14,         14,        1,   921600, 0xfe666be7
+0,         15,         15,        1,   921600, 0x721baec0
+0,         16,         16,        1,   921600, 0x721baec0
+0,         17,         17,        1,   921600, 0x721baec0
+0,         18,         18,        1,   921600, 0xc237180a
+0,         19,         19,        1,   921600, 0xc237180a
+0,         20,         20,        1,   921600, 0xf03a7482
+0,         21,         21,        1,   921600, 0xf03a7482
+0,         22,         22,        1,   921600, 0xf03a7482
+0,         23,         23,        1,   921600, 0x5612a391
+0,         24,         24,        1,   921600, 0x5612a391
+0,         25,         25,        1,   921600, 0x9dbcc46a
+0,         26,         26,        1,   921600, 0x9dbcc46a
+0,         27,         27,        1,   921600, 0x9dbcc46a
+0,         28,         28,        1,   921600, 0xa128a5d5
+0,         29,         29,        1,   921600, 0xa128a5d5
+0,         30,         30,        1,   921600, 0x63e0025c
+0,         31,         31,        1,   921600, 0x63e0025c
+0,         32,         32,        1,   921600, 0x63e0025c
+0,         33,         33,        1,   921600, 0x262359ed
+0,         34,         34,        1,   921600, 0x262359ed
+0,         35,         35,        1,   921600, 0x343688e8
+0,         36,         36,        1,   921600, 0x343688e8
+0,         37,         37,        1,   921600, 0x343688e8
+0,         38,         38,        1,   921600, 0x343688e8
+0,         39,         39,        1,   921600, 0x343688e8
+0,         40,         40,        1,   921600, 0x343688e8
+0,         41,         41,        1,   921600, 0x343688e8
+0,         42,         42,        1,   921600, 0x343688e8
+0,         43,         43,        1,   921600, 0x343688e8
+0,         44,         44,        1,   921600, 0x343688e8
+0,         45,         45,        1,   921600, 0xe4b29d57
+0,         46,         46,        1,   921600, 0xe4b29d57
+0,         47,         47,        1,   921600, 0xe4b29d57
+0,         48,         48,        1,   921600, 0x198e8a4a
+0,         49,         49,        1,   921600, 0x198e8a4a
+0,         50,         50,        1,   921600, 0x0cad8dc9
+0,         51,         51,        1,   921600, 0x0cad8dc9
+0,         52,         52,        1,   921600, 0x0cad8dc9
+0,         53,         53,        1,   921600, 0x1f74cf3d
+0,         54,         54,        1,   921600, 0x1f74cf3d
+0,         55,         55,        1,   921600, 0xec5b5449
+0,         56,         56,        1,   921600, 0xec5b5449
+0,         57,         57,        1,   921600, 0xec5b5449
+0,         58,         58,        1,   921600, 0x39829711
+0,         59,         59,        1,   921600, 0x39829711
+0,         60,         60,        1,   921600, 0x6de5b9c6
+0,         61,         61,        1,   921600, 0x6de5b9c6
+0,         62,         62,        1,   921600, 0x6de5b9c6
+0,         63,         63,        1,   921600, 0x47b0e9d4
+0,         64,         64,        1,   921600, 0x47b0e9d4
+0,         65,         65,        1,   921600, 0x756452b8
+0,         66,         66,        1,   921600, 0x756452b8
+0,         67,         67,        1,   921600, 0x756452b8
+0,         68,         68,        1,   921600, 0x6fce3478
+0,         69,         69,        1,   921600, 0x6fce3478
+0,         70,         70,        1,   921600, 0x372397cd
+0,         71,         71,        1,   921600, 0x372397cd
+0,         72,         72,        1,   921600, 0x372397cd
+0,         73,         73,        1,   921600, 0xe3999ba1
+0,         74,         74,        1,   921600, 0xe3999ba1
+0,         75,         75,        1,   921600, 0x6ba26b43
+0,         76,         76,        1,   921600, 0x6ba26b43
+0,         77,         77,        1,   921600, 0x6ba26b43
+0,         78,         78,        1,   921600, 0x4e9ee49e
+0,         79,         79,        1,   921600, 0x4e9ee49e
+0,         80,         80,        1,   921600, 0xdb5fd6e7
+0,         81,         81,        1,   921600, 0xdb5fd6e7
+0,         82,         82,        1,   921600, 0xdb5fd6e7
+0,         83,         83,        1,   921600, 0x8f2254a5
+0,         84,         84,        1,   921600, 0x8f2254a5
+0,         85,         85,        1,   921600, 0x8f2254a5
+0,         86,         86,        1,   921600, 0x8f2254a5
+0,         87,         87,        1,   921600, 0x8f2254a5
+0,         88,         88,        1,   921600, 0x8f2254a5
+0,         89,         89,        1,   921600, 0x8f2254a5
+0,         90,         90,        1,   921600, 0x8f2254a5
+0,         91,         91,        1,   921600, 0x8f2254a5
+0,         92,         92,        1,   921600, 0x8f2254a5
+0,         93,         93,        1,   921600, 0x57e95c32
+0,         94,         94,        1,   921600, 0x57e95c32
+0,         95,         95,        1,   921600, 0x41627a9b
+0,         96,         96,        1,   921600, 0x41627a9b
+0,         97,         97,        1,   921600, 0x41627a9b
+0,         98,         98,        1,   921600, 0x7412dcee
+0,         99,         99,        1,   921600, 0x7412dcee
+0,        100,        100,        1,   921600, 0xaebe10ed
+0,        101,        101,        1,   921600, 0xaebe10ed
+0,        102,        102,        1,   921600, 0xaebe10ed
+0,        103,        103,        1,   921600, 0x411a91f6
+0,        104,        104,        1,   921600, 0x411a91f6
+0,        105,        105,        1,   921600, 0xb059df3f
+0,        106,        106,        1,   921600, 0xb059df3f
+0,        107,        107,        1,   921600, 0xb059df3f
+0,        108,        108,        1,   921600, 0x4d6f5a77
+0,        109,        109,        1,   921600, 0x4d6f5a77
+0,        110,        110,        1,   921600, 0xbbf06df4
+0,        111,        111,        1,   921600, 0xbbf06df4
+0,        112,        112,        1,   921600, 0xbbf06df4
+0,        113,        113,        1,   921600, 0xe27f7bf6
+0,        114,        114,        1,   921600, 0xe27f7bf6
+0,        115,        115,        1,   921600, 0xd7e8360e
+0,        116,        116,        1,   921600, 0xd7e8360e
+0,        117,        117,        1,   921600, 0xd7e8360e
+0,        118,        118,        1,   921600, 0x1dd4c344
+0,        119,        119,        1,   921600, 0x1dd4c344
+0,        120,        120,        1,   921600, 0x7995a7ce
+0,        121,        121,        1,   921600, 0x7995a7ce
+0,        122,        122,        1,   921600, 0x7995a7ce
+0,        123,        123,        1,   921600, 0x2ef3c566
+0,        124,        124,        1,   921600, 0x2ef3c566
+0,        125,        125,        1,   921600, 0xf296736e
+0,        126,        126,        1,   921600, 0xf296736e
+0,        127,        127,        1,   921600, 0xf296736e
+0,        128,        128,        1,   921600, 0xf296736e
+0,        129,        129,        1,   921600, 0xf296736e
+0,        130,        130,        1,   921600, 0xf296736e
+0,        131,        131,        1,   921600, 0xf296736e
+0,        132,        132,        1,   921600, 0xf296736e
+0,        133,        133,        1,   921600, 0xf296736e
+0,        134,        134,        1,   921600, 0xf296736e
+0,        135,        135,        1,   921600, 0x1a488311
+0,        136,        136,        1,   921600, 0x1a488311
+0,        137,        137,        1,   921600, 0x1a488311
+0,        138,        138,        1,   921600, 0x9e28011b
+0,        139,        139,        1,   921600, 0x9e28011b
+0,        140,        140,        1,   921600, 0x84d1ea80
+0,        141,        141,        1,   921600, 0x84d1ea80
+0,        142,        142,        1,   921600, 0x84d1ea80
+0,        143,        143,        1,   921600, 0x9ed41052
+0,        144,        144,        1,   921600, 0x9ed41052
+0,        145,        145,        1,   921600, 0xd4db7206
+0,        146,        146,        1,   921600, 0xd4db7206
+0,        147,        147,        1,   921600, 0xd4db7206
+0,        148,        148,        1,   921600, 0x55f695a9
+0,        149,        149,        1,   921600, 0x55f695a9
+0,        150,        150,        1,   921600, 0x9d8c667f
+0,        151,        151,        1,   921600, 0x9d8c667f
+0,        152,        152,        1,   921600, 0x9d8c667f
+0,        153,        153,        1,   921600, 0x9b6037ec
+0,        154,        154,        1,   921600, 0x9b6037ec
+0,        155,        155,        1,   921600, 0x57c5e835
+0,        156,        156,        1,   921600, 0x57c5e835
+0,        157,        157,        1,   921600, 0x57c5e835
+0,        158,        158,        1,   921600, 0x476dad89
+0,        159,        159,        1,   921600, 0x476dad89
+0,        160,        160,        1,   921600, 0xcfd6ad2b
+0,        161,        161,        1,   921600, 0xcfd6ad2b
+0,        162,        162,        1,   921600, 0xcfd6ad2b
+0,        163,        163,        1,   921600, 0x3b372379
+0,        164,        164,        1,   921600, 0x3b372379
+0,        165,        165,        1,   921600, 0x36f245f5
+0,        166,        166,        1,   921600, 0x36f245f5
diff --git a/tests/ref/fate/quickdraw b/tests/ref/fate/quickdraw
index 9a55ad5..eccb477 100644
--- a/tests/ref/fate/quickdraw
+++ b/tests/ref/fate/quickdraw
@@ -1,3 +1,3 @@
-#tb 0: 1/600
+#tb 0: 1/15
 0,          0,          0,        1,   921600, 0xc0e68764
-0,         80,         80,        1,   921600, 0x01a16629
+0,          2,          2,        1,   921600, 0x01a16629
diff --git a/tests/ref/fate/random_seed b/tests/ref/fate/random_seed
new file mode 100644
index 0000000..2b5b3af
--- /dev/null
+++ b/tests/ref/fate/random_seed
@@ -0,0 +1 @@
+seeds OK
diff --git a/tests/ref/fate/redcode-demux b/tests/ref/fate/redcode-demux
index 34a2924..a7e2838 100644
--- a/tests/ref/fate/redcode-demux
+++ b/tests/ref/fate/redcode-demux
@@ -4,4 +4,4 @@
 1,          0,          0,    18140,    14816, 0xd185e8c7
 0,      10010,      10010,    10010,  1626092, 0x070bd882
 1,      18140,      18140,    40920,    32736, 0x791b737a
-0,      20020,      20020,    10010,   893932, 0x8c7cd0a6
+0,      20020,      20020,    10010,   893932, 0x8c7cd0a6, F=0x3
diff --git a/tests/ref/fate/rpza b/tests/ref/fate/rpza
index a1c5333..a9ae3bb 100644
--- a/tests/ref/fate/rpza
+++ b/tests/ref/fate/rpza
@@ -1,31 +1,31 @@
-#tb 0: 1/600
-0,          0,          0,        1,   230400, 0x4aec80a3
-0,         40,         40,        1,   230400, 0xb6c41452
-0,         80,         80,        1,   230400, 0xa6c27f12
-0,        120,        120,        1,   230400, 0x309bd2d2
-0,        160,        160,        1,   230400, 0x597a7341
-0,        200,        200,        1,   230400, 0x597a7341
-0,        240,        240,        1,   230400, 0xd6d6c569
-0,        280,        280,        1,   230400, 0x31413d89
-0,        320,        320,        1,   230400, 0x464e42e9
-0,        360,        360,        1,   230400, 0x502d7c71
-0,        400,        400,        1,   230400, 0x502d7c71
-0,        440,        440,        1,   230400, 0xc96f23d1
-0,        480,        480,        1,   230400, 0xc96f23d1
-0,        520,        520,        1,   230400, 0x5bfd2bc7
-0,        560,        560,        1,   230400, 0x821640a7
-0,        600,        600,        1,   230400, 0x8f001967
-0,        640,        640,        1,   230400, 0x406ba109
-0,        680,        680,        1,   230400, 0x85d99b50
-0,        720,        720,        1,   230400, 0x2fdb4018
-0,        760,        760,        1,   230400, 0xfa127259
-0,        800,        800,        1,   230400, 0xe6427b9b
-0,        840,        840,        1,   230400, 0xe6427b9b
-0,        880,        880,        1,   230400, 0x3a279000
-0,        920,        920,        1,   230400, 0x710755ee
-0,        960,        960,        1,   230400, 0x76549d35
-0,       1000,       1000,        1,   230400, 0xf4d0132c
-0,       1040,       1040,        1,   230400, 0xf4d0132c
-0,       1080,       1080,        1,   230400, 0x19d7ec14
-0,       1120,       1120,        1,   230400, 0x19d7ec14
-0,       1160,       1160,        1,   230400, 0x5f24b7e1
+#tb 0: 1/15
+0,          0,          0,        1,   230400, 0x26a4728c
+0,          1,          1,        1,   230400, 0xa5ff0a21
+0,          2,          2,        1,   230400, 0x479d767d
+0,          3,          3,        1,   230400, 0xc619cd01
+0,          4,          4,        1,   230400, 0x1d377157
+0,          5,          5,        1,   230400, 0x1d377157
+0,          6,          6,        1,   230400, 0x0941c629
+0,          7,          7,        1,   230400, 0xe64b3a93
+0,          8,          8,        1,   230400, 0x28493fd7
+0,          9,          9,        1,   230400, 0x18c77af2
+0,         10,         10,        1,   230400, 0x18c77af2
+0,         11,         11,        1,   230400, 0x5a542008
+0,         12,         12,        1,   230400, 0x5a542008
+0,         13,         13,        1,   230400, 0x3b1a34fd
+0,         14,         14,        1,   230400, 0x77d34944
+0,         15,         15,        1,   230400, 0x50ac218c
+0,         16,         16,        1,   230400, 0xcb999f16
+0,         17,         17,        1,   230400, 0xe1ce9f19
+0,         18,         18,        1,   230400, 0xb10b4264
+0,         19,         19,        1,   230400, 0x61207031
+0,         20,         20,        1,   230400, 0x81626d5b
+0,         21,         21,        1,   230400, 0x81626d5b
+0,         22,         22,        1,   230400, 0x1cb59751
+0,         23,         23,        1,   230400, 0x316e6962
+0,         24,         24,        1,   230400, 0x4c01b829
+0,         25,         25,        1,   230400, 0x276e32bc
+0,         26,         26,        1,   230400, 0x276e32bc
+0,         27,         27,        1,   230400, 0xe251117a
+0,         28,         28,        1,   230400, 0xe251117a
+0,         29,         29,        1,   230400, 0x41b7f098
diff --git a/tests/ref/fate/rv30 b/tests/ref/fate/rv30
index 4883423..df002d9 100644
--- a/tests/ref/fate/rv30
+++ b/tests/ref/fate/rv30
@@ -1,110 +1,110 @@
-#tb 0: 1/1000
-0,          1,          1,        0,   126720, 0xcefaec47
-0,         33,         33,        0,   126720, 0xa416ece5
-0,         66,         66,        0,   126720, 0xa416ece5
-0,        100,        100,        0,   126720, 0xa416ece5
-0,        133,        133,        0,   126720, 0x60d6ed27
-0,        166,        166,        0,   126720, 0x259af497
-0,        200,        200,        0,   126720, 0x5e6ff4d7
-0,        233,        233,        0,   126720, 0xcc10f4b7
-0,        266,        266,        0,   126720, 0x763ab817
-0,        300,        300,        0,   126720, 0xeb6fb8d7
-0,        333,        333,        0,   126720, 0xda71b917
-0,        367,        367,        0,   126720, 0x0967b8f7
-0,        400,        400,        0,   126720, 0x4b62b947
-0,        433,        433,        0,   126720, 0xbb1abbb7
-0,        467,        467,        0,   126720, 0x273fbc37
-0,        500,        500,        0,   126720, 0x16eebbd7
-0,        533,        533,        0,   126720, 0x105eb927
-0,        567,        567,        0,   126720, 0x7fa3ae27
-0,        600,        600,        0,   126720, 0x722e99f7
-0,        633,        633,        0,   126720, 0x5ac9a827
-0,        667,        667,        0,   126720, 0x07beba77
-0,        700,        700,        0,   126720, 0x29d6a887
-0,        734,        734,        0,   126720, 0xa5caab87
-0,        767,        767,        0,   126720, 0x9ca7aac7
-0,        800,        800,        0,   126720, 0xb7debcd7
-0,        834,        834,        0,   126720, 0xd115a757
-0,        867,        867,        0,   126720, 0x6ddaef32
-0,        900,        900,        0,   126720, 0xde1bb900
-0,        934,        934,        0,   126720, 0xac6c071b
-0,        967,        967,        0,   126720, 0x04e7897c
-0,       1000,       1000,        0,   126720, 0x5eee050f
-0,       1034,       1034,        0,   126720, 0xe675be59
-0,       1067,       1067,        0,   126720, 0xdc3e0837
-0,       1101,       1101,        0,   126720, 0x68cfda2b
-0,       1134,       1134,        0,   126720, 0xe572dfc9
-0,       1167,       1167,        0,   126720, 0x582fb176
-0,       1201,       1201,        0,   126720, 0xa9477df0
-0,       1234,       1234,        0,   126720, 0xbc3cc34f
-0,       1267,       1267,        0,   126720, 0xcf8cb0e2
-0,       1301,       1301,        0,   126720, 0xcff1db35
-0,       1334,       1334,        0,   126720, 0xc6e10f9f
-0,       1368,       1368,        0,   126720, 0x75ae61b6
-0,       1401,       1401,        0,   126720, 0x12af3119
-0,       1434,       1434,        0,   126720, 0x85597543
-0,       1468,       1468,        0,   126720, 0x68c27aca
-0,       1501,       1501,        0,   126720, 0x554fe3e4
-0,       1534,       1534,        0,   126720, 0x72ecea95
-0,       1568,       1568,        0,   126720, 0xf4d003d1
-0,       1601,       1601,        0,   126720, 0x9bf6a605
-0,       1634,       1634,        0,   126720, 0x5d00b5fe
-0,       1668,       1668,        0,   126720, 0x93f7b040
-0,       1701,       1701,        0,   126720, 0x0d6ad154
-0,       1735,       1735,        0,   126720, 0x4be8b4ea
-0,       1768,       1768,        0,   126720, 0xe39bba0d
-0,       1801,       1801,        0,   126720, 0x9c21bad8
-0,       1835,       1835,        0,   126720, 0xa567f25b
-0,       1868,       1868,        0,   126720, 0x7a82663a
-0,       1901,       1901,        0,   126720, 0x72f2a47d
-0,       1935,       1935,        0,   126720, 0x4f639ebe
-0,       1968,       1968,        0,   126720, 0xab0fce83
-0,       2001,       2001,        0,   126720, 0x6cf87d39
-0,       2035,       2035,        0,   126720, 0x534a10cc
-0,       2068,       2068,        0,   126720, 0x6bbcf44c
-0,       2102,       2102,        0,   126720, 0xfdca11d3
-0,       2135,       2135,        0,   126720, 0x7e58f5a6
-0,       2168,       2168,        0,   126720, 0x5fd753d8
-0,       2202,       2202,        0,   126720, 0x0c735615
-0,       2235,       2235,        0,   126720, 0x2a034ebf
-0,       2268,       2268,        0,   126720, 0xeaf3dd0b
-0,       2302,       2302,        0,   126720, 0x0eaf0c1b
-0,       2335,       2335,        0,   126720, 0xce5e6794
-0,       2369,       2369,        0,   126720, 0xf27c31c3
-0,       2402,       2402,        0,   126720, 0xb64af168
-0,       2435,       2435,        0,   126720, 0x14cf7974
-0,       2469,       2469,        0,   126720, 0x1c2a513d
-0,       2502,       2502,        0,   126720, 0xa3f515ab
-0,       2535,       2535,        0,   126720, 0xcfd62765
-0,       2569,       2569,        0,   126720, 0xbc513f2a
-0,       2602,       2602,        0,   126720, 0xbc303fae
-0,       2635,       2635,        0,   126720, 0x2f8f69b9
-0,       2669,       2669,        0,   126720, 0x0a22cc69
-0,       2702,       2702,        0,   126720, 0xd9f67585
-0,       2736,       2736,        0,   126720, 0x20403001
-0,       2769,       2769,        0,   126720, 0xf92b2a25
-0,       2802,       2802,        0,   126720, 0x3c170aad
-0,       2836,       2836,        0,   126720, 0x3378251f
-0,       2869,       2869,        0,   126720, 0xb3ed5911
-0,       2902,       2902,        0,   126720, 0x35d24ef8
-0,       2936,       2936,        0,   126720, 0x8da30275
-0,       2969,       2969,        0,   126720, 0xc15a3577
-0,       3002,       3002,        0,   126720, 0xf2942f53
-0,       3036,       3036,        0,   126720, 0x44d8304a
-0,       3069,       3069,        0,   126720, 0xd688a932
-0,       3103,       3103,        0,   126720, 0x0a24f256
-0,       3136,       3136,        0,   126720, 0xfab9c45d
-0,       3169,       3169,        0,   126720, 0x10e939ce
-0,       3203,       3203,        0,   126720, 0x97fcaa3a
-0,       3236,       3236,        0,   126720, 0x45464610
-0,       3269,       3269,        0,   126720, 0xfe2e057d
-0,       3303,       3303,        0,   126720, 0x0b6718ae
-0,       3336,       3336,        0,   126720, 0x5284da7b
-0,       3370,       3370,        0,   126720, 0x23efdc35
-0,       3403,       3403,        0,   126720, 0xc387b2b3
-0,       3436,       3436,        0,   126720, 0xc9e92bf1
-0,       3470,       3470,        0,   126720, 0xfbf20a01
-0,       3503,       3503,        0,   126720, 0x4d888b2e
-0,       3536,       3536,        0,   126720, 0xdd0d74df
-0,       3570,       3570,        0,   126720, 0x49d07aa4
-0,       3603,       3603,        0,   126720, 0x08382b8e
+#tb 0: 32768/982057
+0,          0,          0,        1,   126720, 0xcefaec47
+0,          1,          1,        1,   126720, 0xa416ece5
+0,          2,          2,        1,   126720, 0xa416ece5
+0,          3,          3,        1,   126720, 0xa416ece5
+0,          4,          4,        1,   126720, 0x60d6ed27
+0,          5,          5,        1,   126720, 0x259af497
+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,         12,         12,        1,   126720, 0x4b62b947
+0,         13,         13,        1,   126720, 0xbb1abbb7
+0,         14,         14,        1,   126720, 0x273fbc37
+0,         15,         15,        1,   126720, 0x16eebbd7
+0,         16,         16,        1,   126720, 0x105eb927
+0,         17,         17,        1,   126720, 0x7fa3ae27
+0,         18,         18,        1,   126720, 0x722e99f7
+0,         19,         19,        1,   126720, 0x5ac9a827
+0,         20,         20,        1,   126720, 0x07beba77
+0,         21,         21,        1,   126720, 0x29d6a887
+0,         22,         22,        1,   126720, 0xa5caab87
+0,         23,         23,        1,   126720, 0x9ca7aac7
+0,         24,         24,        1,   126720, 0xb7debcd7
+0,         25,         25,        1,   126720, 0xd115a757
+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,         32,         32,        1,   126720, 0xdc3e0837
+0,         33,         33,        1,   126720, 0x68cfda2b
+0,         34,         34,        1,   126720, 0xe572dfc9
+0,         35,         35,        1,   126720, 0x582fb176
+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,         40,         40,        1,   126720, 0xc6e10f9f
+0,         41,         41,        1,   126720, 0x75ae61b6
+0,         42,         42,        1,   126720, 0x12af3119
+0,         43,         43,        1,   126720, 0x85597543
+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
diff --git a/tests/ref/fate/rv40 b/tests/ref/fate/rv40
index d5cb265..6159859 100644
--- a/tests/ref/fate/rv40
+++ b/tests/ref/fate/rv40
@@ -1,240 +1,241 @@
-#tb 0: 1/1000
-0,        -41,        -41,        0,   276480, 0x5f7a0d4f
-0,         42,         42,        0,   276480, 0x5f7a0d4f
-0,         83,         83,        0,   276480, 0x5f7a0d4f
-0,        125,        125,        0,   276480, 0x5f7a0d4f
-0,        167,        167,        0,   276480, 0x5f7a0d4f
-0,        209,        209,        0,   276480, 0x5f7a0d4f
-0,        250,        250,        0,   276480, 0x5f7a0d4f
-0,        292,        292,        0,   276480, 0x5f7a0d4f
-0,        334,        334,        0,   276480, 0x5f7a0d4f
-0,        375,        375,        0,   276480, 0x5f7a0d4f
-0,        417,        417,        0,   276480, 0x5f7a0d4f
-0,        459,        459,        0,   276480, 0x5f7a0d4f
-0,        501,        501,        0,   276480, 0x5f7a0d4f
-0,        542,        542,        0,   276480, 0x5f7a0d4f
-0,        584,        584,        0,   276480, 0x5f7a0d4f
-0,        626,        626,        0,   276480, 0x5f7a0d4f
-0,        667,        667,        0,   276480, 0x5f7a0d4f
-0,        709,        709,        0,   276480, 0x5f7a0d4f
-0,        751,        751,        0,   276480, 0x5f7a0d4f
-0,        792,        792,        0,   276480, 0x5f7a0d4f
-0,        834,        834,        0,   276480, 0x5f7a0d4f
-0,        876,        876,        0,   276480, 0x5f7a0d4f
-0,        918,        918,        0,   276480, 0x5f7a0d4f
-0,        959,        959,        0,   276480, 0x5f7a0d4f
-0,       1001,       1001,        0,   276480, 0x5f7a0d4f
-0,       1043,       1043,        0,   276480, 0x5f7a0d4f
-0,       1084,       1084,        0,   276480, 0x5f7a0d4f
-0,       1126,       1126,        0,   276480, 0x5f7a0d4f
-0,       1168,       1168,        0,   276480, 0x5f7a0d4f
-0,       1210,       1210,        0,   276480, 0x5f7a0d4f
-0,       1251,       1251,        0,   276480, 0x5f7a0d4f
-0,       1293,       1293,        0,   276480, 0x5f7a0d4f
-0,       1335,       1335,        0,   276480, 0x5f7a0d4f
-0,       1376,       1376,        0,   276480, 0x75641594
-0,       1418,       1418,        0,   276480, 0x32ee3526
-0,       1460,       1460,        0,   276480, 0xcb53479a
-0,       1502,       1502,        0,   276480, 0x7ca9658e
-0,       1543,       1543,        0,   276480, 0x5ce39368
-0,       1585,       1585,        0,   276480, 0x4ec1e418
-0,       1627,       1627,        0,   276480, 0xb3790499
-0,       1668,       1668,        0,   276480, 0xa9f1506f
-0,       1710,       1710,        0,   276480, 0x85cbc3b5
-0,       1752,       1752,        0,   276480, 0x377c7b46
-0,       1793,       1793,        0,   276480, 0x1a61d8db
-0,       1835,       1835,        0,   276480, 0xe1de7f0a
-0,       1877,       1877,        0,   276480, 0x756a4a2e
-0,       1919,       1919,        0,   276480, 0xcb379547
-0,       1960,       1960,        0,   276480, 0xbae14484
-0,       2002,       2002,        0,   276480, 0x8e12331c
-0,       2044,       2044,        0,   276480, 0x99c085be
-0,       2085,       2085,        0,   276480, 0xe479ffed
-0,       2127,       2127,        0,   276480, 0x99c82949
-0,       2169,       2169,        0,   276480, 0xac7672dd
-0,       2211,       2211,        0,   276480, 0x1e4fae19
-0,       2252,       2252,        0,   276480, 0x776412ef
-0,       2294,       2294,        0,   276480, 0x7d9b579f
-0,       2336,       2336,        0,   276480, 0x1cd1ab29
-0,       2377,       2377,        0,   276480, 0x58ce0f38
-0,       2419,       2419,        0,   276480, 0x5ab69b27
-0,       2461,       2461,        0,   276480, 0x0afad610
-0,       2503,       2503,        0,   276480, 0x9eca3f11
-0,       2544,       2544,        0,   276480, 0xc3db9706
-0,       2586,       2586,        0,   276480, 0xc9c57884
-0,       2628,       2628,        0,   276480, 0xd9fbb2cf
-0,       2669,       2669,        0,   276480, 0xdc07f3c9
-0,       2711,       2711,        0,   276480, 0x000b5269
-0,       2753,       2753,        0,   276480, 0x27ff7a5d
-0,       2794,       2794,        0,   276480, 0xd92e2017
-0,       2836,       2836,        0,   276480, 0x18d4b27d
-0,       2878,       2878,        0,   276480, 0x70647530
-0,       2920,       2920,        0,   276480, 0x97612c4b
-0,       2961,       2961,        0,   276480, 0xc9d4ac78
-0,       3003,       3003,        0,   276480, 0x4ec4d57f
-0,       3045,       3045,        0,   276480, 0xdf4e04d7
-0,       3086,       3086,        0,   276480, 0xbd98f57c
-0,       3128,       3128,        0,   276480, 0x7247ea3e
-0,       3170,       3170,        0,   276480, 0xa5d670ec
-0,       3212,       3212,        0,   276480, 0x5163b29b
-0,       3253,       3253,        0,   276480, 0x99170e64
-0,       3295,       3295,        0,   276480, 0x37f4c0b0
-0,       3337,       3337,        0,   276480, 0x7a4f2561
-0,       3378,       3378,        0,   276480, 0x8a4e991f
-0,       3420,       3420,        0,   276480, 0x6a45425f
-0,       3462,       3462,        0,   276480, 0x1f0e2bb6
-0,       3504,       3504,        0,   276480, 0xd75482c6
-0,       3545,       3545,        0,   276480, 0x7bf6b1ef
-0,       3587,       3587,        0,   276480, 0x6de1e34b
-0,       3629,       3629,        0,   276480, 0x4526c89b
-0,       3670,       3670,        0,   276480, 0xf964e18e
-0,       3712,       3712,        0,   276480, 0xdcaaa99a
-0,       3754,       3754,        0,   276480, 0xd1e98808
-0,       3795,       3795,        0,   276480, 0x556b2365
-0,       3837,       3837,        0,   276480, 0x0cf65540
-0,       3879,       3879,        0,   276480, 0x6e2d524e
-0,       3921,       3921,        0,   276480, 0x22c50a3d
-0,       3962,       3962,        0,   276480, 0x293f19af
-0,       4004,       4004,        0,   276480, 0xf4b1c461
-0,       4046,       4046,        0,   276480, 0x62b76407
-0,       4087,       4087,        0,   276480, 0x51e9b3eb
-0,       4129,       4129,        0,   276480, 0x7b910bc7
-0,       4171,       4171,        0,   276480, 0x6dd14ca6
-0,       4213,       4213,        0,   276480, 0x441f7afd
-0,       4254,       4254,        0,   276480, 0xfb01efc6
-0,       4296,       4296,        0,   276480, 0x4f73ccea
-0,       4338,       4338,        0,   276480, 0x5ac8e06f
-0,       4379,       4379,        0,   276480, 0x294bb441
-0,       4421,       4421,        0,   276480, 0xe04ac45e
-0,       4463,       4463,        0,   276480, 0xa7a38d41
-0,       4505,       4505,        0,   276480, 0xf688a3ed
-0,       4546,       4546,        0,   276480, 0x58f275ea
-0,       4588,       4588,        0,   276480, 0xf0b3b71b
-0,       4630,       4630,        0,   276480, 0x3ce773bf
-0,       4671,       4671,        0,   276480, 0x01840548
-0,       4713,       4713,        0,   276480, 0x674e34e4
-0,       4755,       4755,        0,   276480, 0x41dda2d9
-0,       4796,       4796,        0,   276480, 0xc5b60838
-0,       4838,       4838,        0,   276480, 0x9b209f41
-0,       4880,       4880,        0,   276480, 0xf46ba7fb
-0,       4922,       4922,        0,   276480, 0x28b54815
-0,       4963,       4963,        0,   276480, 0xb605a933
-0,       5005,       5005,        0,   276480, 0x34484aff
-0,       5047,       5047,        0,   276480, 0xaf2b5d89
-0,       5088,       5088,        0,   276480, 0x8facba58
-0,       5130,       5130,        0,   276480, 0xbbe3e99f
-0,       5172,       5172,        0,   276480, 0x02162c7c
-0,       5214,       5214,        0,   276480, 0x28a63236
-0,       5255,       5255,        0,   276480, 0x1ad43fd7
-0,       5297,       5297,        0,   276480, 0xe37883e5
-0,       5339,       5339,        0,   276480, 0x2b8a89c5
-0,       5380,       5380,        0,   276480, 0x71507bd2
-0,       5422,       5422,        0,   276480, 0x35626022
-0,       5464,       5464,        0,   276480, 0x461fc3e7
-0,       5506,       5506,        0,   276480, 0xce5af1ec
-0,       5547,       5547,        0,   276480, 0x7c1139b3
-0,       5589,       5589,        0,   276480, 0x7fd73a99
-0,       5631,       5631,        0,   276480, 0x4ae4c3a6
-0,       5672,       5672,        0,   276480, 0xcb60725a
-0,       5714,       5714,        0,   276480, 0xb52e1aa2
-0,       5756,       5756,        0,   276480, 0xd6f82cae
-0,       5797,       5797,        0,   276480, 0x6310e665
-0,       5839,       5839,        0,   276480, 0xfa88a483
-0,       5881,       5881,        0,   276480, 0xf88f75d4
-0,       5923,       5923,        0,   276480, 0x04a8e3ee
-0,       5964,       5964,        0,   276480, 0x54766a12
-0,       6006,       6006,        0,   276480, 0x0b41f0d7
-0,       6048,       6048,        0,   276480, 0xa29f5b01
-0,       6089,       6089,        0,   276480, 0x754ceaf5
-0,       6131,       6131,        0,   276480, 0x150c0423
-0,       6173,       6173,        0,   276480, 0xde084059
-0,       6215,       6215,        0,   276480, 0x5a38b4af
-0,       6256,       6256,        0,   276480, 0xfcebc261
-0,       6298,       6298,        0,   276480, 0x0eb9770d
-0,       6340,       6340,        0,   276480, 0x046394ae
-0,       6381,       6381,        0,   276480, 0x3d3ca985
-0,       6423,       6423,        0,   276480, 0x94a03c75
-0,       6465,       6465,        0,   276480, 0x800eea2d
-0,       6507,       6507,        0,   276480, 0x6a841f41
-0,       6548,       6548,        0,   276480, 0x2f98911c
-0,       6590,       6590,        0,   276480, 0x923b9937
-0,       6632,       6632,        0,   276480, 0xe82f8e0f
-0,       6673,       6673,        0,   276480, 0xee82d657
-0,       6715,       6715,        0,   276480, 0xefab7ffd
-0,       6757,       6757,        0,   276480, 0x6b9fbc80
-0,       6798,       6798,        0,   276480, 0x4a1ada47
-0,       6840,       6840,        0,   276480, 0x6d4b49d7
-0,       6882,       6882,        0,   276480, 0xe4bdbd1e
-0,       6924,       6924,        0,   276480, 0x225a56c0
-0,       6965,       6965,        0,   276480, 0xd4adadad
-0,       7007,       7007,        0,   276480, 0xff4e1a8c
-0,       7049,       7049,        0,   276480, 0xf58b1b7c
-0,       7090,       7090,        0,   276480, 0xbaffcdcc
-0,       7132,       7132,        0,   276480, 0x374f88f0
-0,       7174,       7174,        0,   276480, 0x3d861ae6
-0,       7216,       7216,        0,   276480, 0xeb6eb88f
-0,       7257,       7257,        0,   276480, 0xdb753d35
-0,       7299,       7299,        0,   276480, 0x9aa543af
-0,       7341,       7341,        0,   276480, 0xb24c8016
-0,       7382,       7382,        0,   276480, 0xea80a82e
-0,       7424,       7424,        0,   276480, 0x2aae902a
-0,       7466,       7466,        0,   276480, 0x5bba3cfb
-0,       7508,       7508,        0,   276480, 0x5c6e97a9
-0,       7549,       7549,        0,   276480, 0x9b9ee961
-0,       7591,       7591,        0,   276480, 0xaa12b6fd
-0,       7633,       7633,        0,   276480, 0xe9d2439f
-0,       7674,       7674,        0,   276480, 0xbf09053c
-0,       7716,       7716,        0,   276480, 0x50c31e73
-0,       7758,       7758,        0,   276480, 0xdd9fb89f
-0,       7799,       7799,        0,   276480, 0x3e4e5aec
-0,       7841,       7841,        0,   276480, 0x0b752d28
-0,       7883,       7883,        0,   276480, 0xaf82399a
-0,       7925,       7925,        0,   276480, 0x7ce5f23c
-0,       7966,       7966,        0,   276480, 0xad135d0f
-0,       8008,       8008,        0,   276480, 0x55dadd30
-0,       8050,       8050,        0,   276480, 0x5aaa7519
-0,       8091,       8091,        0,   276480, 0xe45a5599
-0,       8133,       8133,        0,   276480, 0xc8e89913
-0,       8175,       8175,        0,   276480, 0x2f447fd3
-0,       8217,       8217,        0,   276480, 0x704411fb
-0,       8258,       8258,        0,   276480, 0x9d7430a1
-0,       8300,       8300,        0,   276480, 0x24dd5fd3
-0,       8342,       8342,        0,   276480, 0x51cb657c
-0,       8383,       8383,        0,   276480, 0x2c230702
-0,       8425,       8425,        0,   276480, 0x4a4f76cd
-0,       8467,       8467,        0,   276480, 0xdcd71e88
-0,       8509,       8509,        0,   276480, 0x87160f99
-0,       8550,       8550,        0,   276480, 0x27f54854
-0,       8592,       8592,        0,   276480, 0x694d76e3
-0,       8634,       8634,        0,   276480, 0xcbe93c19
-0,       8675,       8675,        0,   276480, 0x50742e1b
-0,       8717,       8717,        0,   276480, 0x525463e2
-0,       8759,       8759,        0,   276480, 0x819898f9
-0,       8800,       8800,        0,   276480, 0x08fac755
-0,       8842,       8842,        0,   276480, 0x35c46927
-0,       8884,       8884,        0,   276480, 0xeeed00fc
-0,       8926,       8926,        0,   276480, 0xb6f99ee3
-0,       8967,       8967,        0,   276480, 0xd87f4c73
-0,       9009,       9009,        0,   276480, 0xde97d9fd
-0,       9051,       9051,        0,   276480, 0xefc83107
-0,       9092,       9092,        0,   276480, 0xbb22e024
-0,       9134,       9134,        0,   276480, 0x53a7cfcb
-0,       9176,       9176,        0,   276480, 0xbe1fbb19
-0,       9218,       9218,        0,   276480, 0x300f922a
-0,       9259,       9259,        0,   276480, 0x826fc3bd
-0,       9301,       9301,        0,   276480, 0x679aa57a
-0,       9343,       9343,        0,   276480, 0x5497097b
-0,       9384,       9384,        0,   276480, 0x679a53f8
-0,       9426,       9426,        0,   276480, 0x976c9e93
-0,       9468,       9468,        0,   276480, 0xe80f87f2
-0,       9510,       9510,        0,   276480, 0xdc2d7c6c
-0,       9551,       9551,        0,   276480, 0xb194656e
-0,       9593,       9593,        0,   276480, 0xf002c5ca
-0,       9635,       9635,        0,   276480, 0x43fc1c64
-0,       9676,       9676,        0,   276480, 0xf62d8581
-0,       9718,       9718,        0,   276480, 0xb243dda5
-0,       9760,       9760,        0,   276480, 0x1700efbb
-0,       9801,       9801,        0,   276480, 0x9ebe6ba2
-0,       9843,       9843,        0,   276480, 0x8f316c66
-0,       9885,       9885,        0,   276480, 0x6348ecf5
-0,       9927,       9927,        0,   276480, 0x34b5b78a
+#tb 0: 32768/785647
+0,          0,          0,        1,   276480, 0x5f7a0d4f
+0,          1,          1,        1,   276480, 0x5f7a0d4f
+0,          2,          2,        1,   276480, 0x5f7a0d4f
+0,          3,          3,        1,   276480, 0x5f7a0d4f
+0,          4,          4,        1,   276480, 0x5f7a0d4f
+0,          5,          5,        1,   276480, 0x5f7a0d4f
+0,          6,          6,        1,   276480, 0x5f7a0d4f
+0,          7,          7,        1,   276480, 0x5f7a0d4f
+0,          8,          8,        1,   276480, 0x5f7a0d4f
+0,          9,          9,        1,   276480, 0x5f7a0d4f
+0,         10,         10,        1,   276480, 0x5f7a0d4f
+0,         11,         11,        1,   276480, 0x5f7a0d4f
+0,         12,         12,        1,   276480, 0x5f7a0d4f
+0,         13,         13,        1,   276480, 0x5f7a0d4f
+0,         14,         14,        1,   276480, 0x5f7a0d4f
+0,         15,         15,        1,   276480, 0x5f7a0d4f
+0,         16,         16,        1,   276480, 0x5f7a0d4f
+0,         17,         17,        1,   276480, 0x5f7a0d4f
+0,         18,         18,        1,   276480, 0x5f7a0d4f
+0,         19,         19,        1,   276480, 0x5f7a0d4f
+0,         20,         20,        1,   276480, 0x5f7a0d4f
+0,         21,         21,        1,   276480, 0x5f7a0d4f
+0,         22,         22,        1,   276480, 0x5f7a0d4f
+0,         23,         23,        1,   276480, 0x5f7a0d4f
+0,         24,         24,        1,   276480, 0x5f7a0d4f
+0,         25,         25,        1,   276480, 0x5f7a0d4f
+0,         26,         26,        1,   276480, 0x5f7a0d4f
+0,         27,         27,        1,   276480, 0x5f7a0d4f
+0,         28,         28,        1,   276480, 0x5f7a0d4f
+0,         29,         29,        1,   276480, 0x5f7a0d4f
+0,         30,         30,        1,   276480, 0x5f7a0d4f
+0,         31,         31,        1,   276480, 0x5f7a0d4f
+0,         32,         32,        1,   276480, 0x5f7a0d4f
+0,         33,         33,        1,   276480, 0x75641594
+0,         34,         34,        1,   276480, 0x32ee3526
+0,         35,         35,        1,   276480, 0xcb53479a
+0,         36,         36,        1,   276480, 0x7ca9658e
+0,         37,         37,        1,   276480, 0x5ce39368
+0,         38,         38,        1,   276480, 0x4ec1e418
+0,         39,         39,        1,   276480, 0xb3790499
+0,         40,         40,        1,   276480, 0xa9f1506f
+0,         41,         41,        1,   276480, 0x85cbc3b5
+0,         42,         42,        1,   276480, 0x377c7b46
+0,         43,         43,        1,   276480, 0x1a61d8db
+0,         44,         44,        1,   276480, 0xe1de7f0a
+0,         45,         45,        1,   276480, 0x756a4a2e
+0,         46,         46,        1,   276480, 0xcb379547
+0,         47,         47,        1,   276480, 0xbae14484
+0,         48,         48,        1,   276480, 0x8e12331c
+0,         49,         49,        1,   276480, 0x99c085be
+0,         50,         50,        1,   276480, 0xe479ffed
+0,         51,         51,        1,   276480, 0x99c82949
+0,         52,         52,        1,   276480, 0xac7672dd
+0,         53,         53,        1,   276480, 0x1e4fae19
+0,         54,         54,        1,   276480, 0x776412ef
+0,         55,         55,        1,   276480, 0x7d9b579f
+0,         56,         56,        1,   276480, 0x1cd1ab29
+0,         57,         57,        1,   276480, 0x58ce0f38
+0,         58,         58,        1,   276480, 0x5ab69b27
+0,         59,         59,        1,   276480, 0x0afad610
+0,         60,         60,        1,   276480, 0x9eca3f11
+0,         61,         61,        1,   276480, 0xc3db9706
+0,         62,         62,        1,   276480, 0xc9c57884
+0,         63,         63,        1,   276480, 0xd9fbb2cf
+0,         64,         64,        1,   276480, 0xdc07f3c9
+0,         65,         65,        1,   276480, 0x000b5269
+0,         66,         66,        1,   276480, 0x27ff7a5d
+0,         67,         67,        1,   276480, 0xd92e2017
+0,         68,         68,        1,   276480, 0x18d4b27d
+0,         69,         69,        1,   276480, 0x70647530
+0,         70,         70,        1,   276480, 0x97612c4b
+0,         71,         71,        1,   276480, 0xc9d4ac78
+0,         72,         72,        1,   276480, 0x4ec4d57f
+0,         73,         73,        1,   276480, 0xdf4e04d7
+0,         74,         74,        1,   276480, 0xbd98f57c
+0,         75,         75,        1,   276480, 0x7247ea3e
+0,         76,         76,        1,   276480, 0xa5d670ec
+0,         77,         77,        1,   276480, 0x5163b29b
+0,         78,         78,        1,   276480, 0x99170e64
+0,         79,         79,        1,   276480, 0x37f4c0b0
+0,         80,         80,        1,   276480, 0x7a4f2561
+0,         81,         81,        1,   276480, 0x8a4e991f
+0,         82,         82,        1,   276480, 0x6a45425f
+0,         83,         83,        1,   276480, 0x1f0e2bb6
+0,         84,         84,        1,   276480, 0xd75482c6
+0,         85,         85,        1,   276480, 0x7bf6b1ef
+0,         86,         86,        1,   276480, 0x6de1e34b
+0,         87,         87,        1,   276480, 0x4526c89b
+0,         88,         88,        1,   276480, 0xf964e18e
+0,         89,         89,        1,   276480, 0xdcaaa99a
+0,         90,         90,        1,   276480, 0xd1e98808
+0,         91,         91,        1,   276480, 0x556b2365
+0,         92,         92,        1,   276480, 0x0cf65540
+0,         93,         93,        1,   276480, 0x6e2d524e
+0,         94,         94,        1,   276480, 0x22c50a3d
+0,         95,         95,        1,   276480, 0x293f19af
+0,         96,         96,        1,   276480, 0xf4b1c461
+0,         97,         97,        1,   276480, 0x62b76407
+0,         98,         98,        1,   276480, 0x51e9b3eb
+0,         99,         99,        1,   276480, 0x7b910bc7
+0,        100,        100,        1,   276480, 0x6dd14ca6
+0,        101,        101,        1,   276480, 0x441f7afd
+0,        102,        102,        1,   276480, 0xfb01efc6
+0,        103,        103,        1,   276480, 0x4f73ccea
+0,        104,        104,        1,   276480, 0x5ac8e06f
+0,        105,        105,        1,   276480, 0x294bb441
+0,        106,        106,        1,   276480, 0xe04ac45e
+0,        107,        107,        1,   276480, 0xa7a38d41
+0,        108,        108,        1,   276480, 0xf688a3ed
+0,        109,        109,        1,   276480, 0x58f275ea
+0,        110,        110,        1,   276480, 0xf0b3b71b
+0,        111,        111,        1,   276480, 0x3ce773bf
+0,        112,        112,        1,   276480, 0x01840548
+0,        113,        113,        1,   276480, 0x674e34e4
+0,        114,        114,        1,   276480, 0x41dda2d9
+0,        115,        115,        1,   276480, 0xc5b60838
+0,        116,        116,        1,   276480, 0x9b209f41
+0,        117,        117,        1,   276480, 0xf46ba7fb
+0,        118,        118,        1,   276480, 0x28b54815
+0,        119,        119,        1,   276480, 0xb605a933
+0,        120,        120,        1,   276480, 0x34484aff
+0,        121,        121,        1,   276480, 0xaf2b5d89
+0,        122,        122,        1,   276480, 0x8facba58
+0,        123,        123,        1,   276480, 0xbbe3e99f
+0,        124,        124,        1,   276480, 0x02162c7c
+0,        125,        125,        1,   276480, 0x28a63236
+0,        126,        126,        1,   276480, 0x1ad43fd7
+0,        127,        127,        1,   276480, 0xe37883e5
+0,        128,        128,        1,   276480, 0x2b8a89c5
+0,        129,        129,        1,   276480, 0x71507bd2
+0,        130,        130,        1,   276480, 0x35626022
+0,        131,        131,        1,   276480, 0x461fc3e7
+0,        132,        132,        1,   276480, 0xce5af1ec
+0,        133,        133,        1,   276480, 0x7c1139b3
+0,        134,        134,        1,   276480, 0x7fd73a99
+0,        135,        135,        1,   276480, 0x4ae4c3a6
+0,        136,        136,        1,   276480, 0xcb60725a
+0,        137,        137,        1,   276480, 0xb52e1aa2
+0,        138,        138,        1,   276480, 0xd6f82cae
+0,        139,        139,        1,   276480, 0x6310e665
+0,        140,        140,        1,   276480, 0xfa88a483
+0,        141,        141,        1,   276480, 0xf88f75d4
+0,        142,        142,        1,   276480, 0x04a8e3ee
+0,        143,        143,        1,   276480, 0x54766a12
+0,        144,        144,        1,   276480, 0x0b41f0d7
+0,        145,        145,        1,   276480, 0xa29f5b01
+0,        146,        146,        1,   276480, 0x754ceaf5
+0,        147,        147,        1,   276480, 0x150c0423
+0,        148,        148,        1,   276480, 0xde084059
+0,        149,        149,        1,   276480, 0x5a38b4af
+0,        150,        150,        1,   276480, 0xfcebc261
+0,        151,        151,        1,   276480, 0x0eb9770d
+0,        152,        152,        1,   276480, 0x046394ae
+0,        153,        153,        1,   276480, 0x3d3ca985
+0,        154,        154,        1,   276480, 0x94a03c75
+0,        155,        155,        1,   276480, 0x800eea2d
+0,        156,        156,        1,   276480, 0x6a841f41
+0,        157,        157,        1,   276480, 0x2f98911c
+0,        158,        158,        1,   276480, 0x923b9937
+0,        159,        159,        1,   276480, 0xe82f8e0f
+0,        160,        160,        1,   276480, 0xee82d657
+0,        161,        161,        1,   276480, 0xefab7ffd
+0,        162,        162,        1,   276480, 0x6b9fbc80
+0,        163,        163,        1,   276480, 0x4a1ada47
+0,        164,        164,        1,   276480, 0x6d4b49d7
+0,        165,        165,        1,   276480, 0xe4bdbd1e
+0,        166,        166,        1,   276480, 0x225a56c0
+0,        167,        167,        1,   276480, 0xd4adadad
+0,        168,        168,        1,   276480, 0xff4e1a8c
+0,        169,        169,        1,   276480, 0xf58b1b7c
+0,        170,        170,        1,   276480, 0xbaffcdcc
+0,        171,        171,        1,   276480, 0x374f88f0
+0,        172,        172,        1,   276480, 0x3d861ae6
+0,        173,        173,        1,   276480, 0xeb6eb88f
+0,        174,        174,        1,   276480, 0xdb753d35
+0,        175,        175,        1,   276480, 0x9aa543af
+0,        176,        176,        1,   276480, 0xb24c8016
+0,        177,        177,        1,   276480, 0xea80a82e
+0,        178,        178,        1,   276480, 0x2aae902a
+0,        179,        179,        1,   276480, 0x5bba3cfb
+0,        180,        180,        1,   276480, 0x5c6e97a9
+0,        181,        181,        1,   276480, 0x9b9ee961
+0,        182,        182,        1,   276480, 0xaa12b6fd
+0,        183,        183,        1,   276480, 0xe9d2439f
+0,        184,        184,        1,   276480, 0xbf09053c
+0,        185,        185,        1,   276480, 0x50c31e73
+0,        186,        186,        1,   276480, 0xdd9fb89f
+0,        187,        187,        1,   276480, 0x3e4e5aec
+0,        188,        188,        1,   276480, 0x0b752d28
+0,        189,        189,        1,   276480, 0xaf82399a
+0,        190,        190,        1,   276480, 0x7ce5f23c
+0,        191,        191,        1,   276480, 0xad135d0f
+0,        192,        192,        1,   276480, 0x55dadd30
+0,        193,        193,        1,   276480, 0x5aaa7519
+0,        194,        194,        1,   276480, 0xe45a5599
+0,        195,        195,        1,   276480, 0xc8e89913
+0,        196,        196,        1,   276480, 0x2f447fd3
+0,        197,        197,        1,   276480, 0x704411fb
+0,        198,        198,        1,   276480, 0x9d7430a1
+0,        199,        199,        1,   276480, 0x24dd5fd3
+0,        200,        200,        1,   276480, 0x51cb657c
+0,        201,        201,        1,   276480, 0x2c230702
+0,        202,        202,        1,   276480, 0x4a4f76cd
+0,        203,        203,        1,   276480, 0xdcd71e88
+0,        204,        204,        1,   276480, 0x87160f99
+0,        205,        205,        1,   276480, 0x27f54854
+0,        206,        206,        1,   276480, 0x694d76e3
+0,        207,        207,        1,   276480, 0xcbe93c19
+0,        208,        208,        1,   276480, 0x50742e1b
+0,        209,        209,        1,   276480, 0x525463e2
+0,        210,        210,        1,   276480, 0x819898f9
+0,        211,        211,        1,   276480, 0x08fac755
+0,        212,        212,        1,   276480, 0x35c46927
+0,        213,        213,        1,   276480, 0xeeed00fc
+0,        214,        214,        1,   276480, 0xb6f99ee3
+0,        215,        215,        1,   276480, 0xd87f4c73
+0,        216,        216,        1,   276480, 0xde97d9fd
+0,        217,        217,        1,   276480, 0xefc83107
+0,        218,        218,        1,   276480, 0xbb22e024
+0,        219,        219,        1,   276480, 0x53a7cfcb
+0,        220,        220,        1,   276480, 0xbe1fbb19
+0,        221,        221,        1,   276480, 0x300f922a
+0,        222,        222,        1,   276480, 0x826fc3bd
+0,        223,        223,        1,   276480, 0x679aa57a
+0,        224,        224,        1,   276480, 0x5497097b
+0,        225,        225,        1,   276480, 0x679a53f8
+0,        226,        226,        1,   276480, 0x976c9e93
+0,        227,        227,        1,   276480, 0xe80f87f2
+0,        228,        228,        1,   276480, 0xdc2d7c6c
+0,        229,        229,        1,   276480, 0xb194656e
+0,        230,        230,        1,   276480, 0xf002c5ca
+0,        231,        231,        1,   276480, 0x43fc1c64
+0,        232,        232,        1,   276480, 0xf62d8581
+0,        233,        233,        1,   276480, 0xb243dda5
+0,        234,        234,        1,   276480, 0x1700efbb
+0,        235,        235,        1,   276480, 0x9ebe6ba2
+0,        236,        236,        1,   276480, 0x8f316c66
+0,        237,        237,        1,   276480, 0x6348ecf5
+0,        238,        238,        1,   276480, 0x34b5b78a
+0,        239,        239,        1,   276480, 0xcbf66922
diff --git a/tests/ref/fate/sanm b/tests/ref/fate/sanm
new file mode 100644
index 0000000..8b6f903
--- /dev/null
+++ b/tests/ref/fate/sanm
@@ -0,0 +1,16 @@
+#tb 0: 66667/1000000
+0,          0,          0,        1,   921600, 0x00000000
+0,          1,          1,        1,   921600, 0x00000000
+0,          2,          2,        1,   921600, 0x00000000
+0,          3,          3,        1,   921600, 0x00000000
+0,          4,          4,        1,   921600, 0x00000000
+0,          5,          5,        1,   921600, 0x00000000
+0,          6,          6,        1,   921600, 0x00000000
+0,          7,          7,        1,   921600, 0x00000000
+0,          8,          8,        1,   921600, 0x00000000
+0,          9,          9,        1,   921600, 0x00000000
+0,         10,         10,        1,   921600, 0x0aa05443
+0,         11,         11,        1,   921600, 0x81d2a7fe
+0,         12,         12,        1,   921600, 0x769f303b
+0,         13,         13,        1,   921600, 0xcd68d0cd
+0,         14,         14,        1,   921600, 0x4cb4894a
diff --git a/tests/ref/fate/smc b/tests/ref/fate/smc
index cdfc3d5..1635b37 100644
--- a/tests/ref/fate/smc
+++ b/tests/ref/fate/smc
@@ -1,121 +1,121 @@
-#tb 0: 1/30
+#tb 0: 1/10
 0,          0,          0,        1,   230400, 0xf814fc90
-0,          3,          3,        1,   230400, 0xe1b13137
-0,          6,          6,        1,   230400, 0xa7f4d408
-0,          9,          9,        1,   230400, 0x4b86e1d5
-0,         12,         12,        1,   230400, 0xc663af5a
-0,         15,         15,        1,   230400, 0x943b5757
-0,         18,         18,        1,   230400, 0x0d7ee496
-0,         21,         21,        1,   230400, 0x78792de4
-0,         24,         24,        1,   230400, 0xd102fb8d
-0,         27,         27,        1,   230400, 0xf9006139
-0,         30,         30,        1,   230400, 0x216bd87d
-0,         33,         33,        1,   230400, 0x1e4c902c
-0,         36,         36,        1,   230400, 0x5aaa7742
-0,         39,         39,        1,   230400, 0x48699d93
-0,         42,         42,        1,   230400, 0xd1e22a5c
-0,         45,         45,        1,   230400, 0x18929315
-0,         48,         48,        1,   230400, 0x680dd4d3
-0,         51,         51,        1,   230400, 0x4cdbcbcb
-0,         54,         54,        1,   230400, 0x6f810d98
-0,         57,         57,        1,   230400, 0xb4f68204
-0,         60,         60,        1,   230400, 0xbd3bb19e
-0,         63,         63,        1,   230400, 0xab27b424
-0,         66,         66,        1,   230400, 0xe5dd675d
-0,         69,         69,        1,   230400, 0x811e45a1
-0,         72,         72,        1,   230400, 0x951011f7
-0,         75,         75,        1,   230400, 0x2f1e2b99
-0,         78,         78,        1,   230400, 0x6657c0d6
-0,         81,         81,        1,   230400, 0xfd29177d
-0,         84,         84,        1,   230400, 0x4b4c01d7
-0,         87,         87,        1,   230400, 0x9af286aa
-0,         90,         90,        1,   230400, 0xc4e9b193
-0,         93,         93,        1,   230400, 0x05dc28ec
-0,         96,         96,        1,   230400, 0x68352119
-0,         99,         99,        1,   230400, 0x0b87e79c
-0,        102,        102,        1,   230400, 0x8358b180
-0,        105,        105,        1,   230400, 0x8debbc9d
-0,        108,        108,        1,   230400, 0x961c58ce
-0,        111,        111,        1,   230400, 0xd8a809c8
-0,        114,        114,        1,   230400, 0x5351789d
-0,        117,        117,        1,   230400, 0xa7ca598c
-0,        120,        120,        1,   230400, 0xc5ce1812
-0,        123,        123,        1,   230400, 0x74496550
-0,        126,        126,        1,   230400, 0x326e366e
-0,        129,        129,        1,   230400, 0x27ae9a92
-0,        132,        132,        1,   230400, 0xadbc8794
-0,        135,        135,        1,   230400, 0x7f3587d8
-0,        138,        138,        1,   230400, 0xf0400ca6
-0,        141,        141,        1,   230400, 0x59a5138e
-0,        144,        144,        1,   230400, 0x456d62a5
-0,        147,        147,        1,   230400, 0xf1a5e5f1
-0,        150,        150,        1,   230400, 0x75c712e4
-0,        153,        153,        1,   230400, 0xd160780a
-0,        156,        156,        1,   230400, 0xc6c23cf0
-0,        159,        159,        1,   230400, 0x0339a2ac
-0,        162,        162,        1,   230400, 0x0e27a2e2
-0,        165,        165,        1,   230400, 0x84976300
-0,        168,        168,        1,   230400, 0xb368f3c4
-0,        171,        171,        1,   230400, 0xa5231fb8
-0,        174,        174,        1,   230400, 0x17c036d4
-0,        177,        177,        1,   230400, 0xfc81a2c0
-0,        180,        180,        1,   230400, 0x99faa403
-0,        183,        183,        1,   230400, 0xff59efd3
-0,        186,        186,        1,   230400, 0xcece1d23
-0,        189,        189,        1,   230400, 0x56c785d9
-0,        192,        192,        1,   230400, 0xe5a9f222
-0,        195,        195,        1,   230400, 0xb80946f8
-0,        198,        198,        1,   230400, 0xf6b642c6
-0,        201,        201,        1,   230400, 0x69573aed
-0,        204,        204,        1,   230400, 0xfb69a1fd
-0,        207,        207,        1,   230400, 0x100b47f4
-0,        210,        210,        1,   230400, 0x6edf9543
-0,        213,        213,        1,   230400, 0x11fdf43c
-0,        216,        216,        1,   230400, 0xd143bf2a
-0,        219,        219,        1,   230400, 0x7ca747c4
-0,        222,        222,        1,   230400, 0xd984bd73
-0,        225,        225,        1,   230400, 0xc5477e8d
-0,        228,        228,        1,   230400, 0xf7d58300
-0,        231,        231,        1,   230400, 0x7a1b9463
-0,        234,        234,        1,   230400, 0x47a29342
-0,        237,        237,        1,   230400, 0xdf437f9d
-0,        240,        240,        1,   230400, 0xf836ef5d
-0,        243,        243,        1,   230400, 0xc98937af
-0,        246,        246,        1,   230400, 0x9258695b
-0,        249,        249,        1,   230400, 0xd4fe179c
-0,        252,        252,        1,   230400, 0x35d524d3
-0,        255,        255,        1,   230400, 0xd9ce5484
-0,        258,        258,        1,   230400, 0xdef776ed
-0,        261,        261,        1,   230400, 0x154c4057
-0,        264,        264,        1,   230400, 0xf5c764f1
-0,        267,        267,        1,   230400, 0x41979b13
-0,        270,        270,        1,   230400, 0xae4e83db
-0,        273,        273,        1,   230400, 0x09fc0f83
-0,        276,        276,        1,   230400, 0x60267fdf
-0,        279,        279,        1,   230400, 0xeaafc525
-0,        282,        282,        1,   230400, 0x80cc35e5
-0,        285,        285,        1,   230400, 0xd82c6164
-0,        288,        288,        1,   230400, 0xd68b8111
-0,        291,        291,        1,   230400, 0x96f874a3
-0,        294,        294,        1,   230400, 0x7fc861c4
-0,        297,        297,        1,   230400, 0xb911f310
-0,        300,        300,        1,   230400, 0x35bbf5aa
-0,        303,        303,        1,   230400, 0xa922b683
-0,        306,        306,        1,   230400, 0xbf6ae353
-0,        309,        309,        1,   230400, 0x6bd3984c
-0,        312,        312,        1,   230400, 0xe51768c0
-0,        315,        315,        1,   230400, 0xee691624
-0,        318,        318,        1,   230400, 0xd546fed7
-0,        321,        321,        1,   230400, 0x98d375e6
-0,        324,        324,        1,   230400, 0x3b9ca990
-0,        327,        327,        1,   230400, 0x27128ad1
-0,        330,        330,        1,   230400, 0x2788e38c
-0,        333,        333,        1,   230400, 0xb0cf3381
-0,        336,        336,        1,   230400, 0x4fc86d39
-0,        339,        339,        1,   230400, 0xf5632fff
-0,        342,        342,        1,   230400, 0x7fa1e6c2
-0,        345,        345,        1,   230400, 0xffeef044
-0,        348,        348,        1,   230400, 0x932af385
-0,        351,        351,        1,   230400, 0x76738428
-0,        354,        354,        1,   230400, 0xf6771ba2
-0,        357,        357,        1,   230400, 0x17e2ff27
+0,          1,          1,        1,   230400, 0xe1b13137
+0,          2,          2,        1,   230400, 0xa7f4d408
+0,          3,          3,        1,   230400, 0x4b86e1d5
+0,          4,          4,        1,   230400, 0xc663af5a
+0,          5,          5,        1,   230400, 0x943b5757
+0,          6,          6,        1,   230400, 0x0d7ee496
+0,          7,          7,        1,   230400, 0x78792de4
+0,          8,          8,        1,   230400, 0xd102fb8d
+0,          9,          9,        1,   230400, 0xf9006139
+0,         10,         10,        1,   230400, 0x216bd87d
+0,         11,         11,        1,   230400, 0x1e4c902c
+0,         12,         12,        1,   230400, 0x5aaa7742
+0,         13,         13,        1,   230400, 0x48699d93
+0,         14,         14,        1,   230400, 0xd1e22a5c
+0,         15,         15,        1,   230400, 0x18929315
+0,         16,         16,        1,   230400, 0x680dd4d3
+0,         17,         17,        1,   230400, 0x4cdbcbcb
+0,         18,         18,        1,   230400, 0x6f810d98
+0,         19,         19,        1,   230400, 0xb4f68204
+0,         20,         20,        1,   230400, 0xbd3bb19e
+0,         21,         21,        1,   230400, 0xab27b424
+0,         22,         22,        1,   230400, 0xe5dd675d
+0,         23,         23,        1,   230400, 0x811e45a1
+0,         24,         24,        1,   230400, 0x951011f7
+0,         25,         25,        1,   230400, 0x2f1e2b99
+0,         26,         26,        1,   230400, 0x6657c0d6
+0,         27,         27,        1,   230400, 0xfd29177d
+0,         28,         28,        1,   230400, 0x4b4c01d7
+0,         29,         29,        1,   230400, 0x9af286aa
+0,         30,         30,        1,   230400, 0xc4e9b193
+0,         31,         31,        1,   230400, 0x05dc28ec
+0,         32,         32,        1,   230400, 0x68352119
+0,         33,         33,        1,   230400, 0x0b87e79c
+0,         34,         34,        1,   230400, 0x8358b180
+0,         35,         35,        1,   230400, 0x8debbc9d
+0,         36,         36,        1,   230400, 0x961c58ce
+0,         37,         37,        1,   230400, 0xd8a809c8
+0,         38,         38,        1,   230400, 0x5351789d
+0,         39,         39,        1,   230400, 0xa7ca598c
+0,         40,         40,        1,   230400, 0xc5ce1812
+0,         41,         41,        1,   230400, 0x74496550
+0,         42,         42,        1,   230400, 0x326e366e
+0,         43,         43,        1,   230400, 0x27ae9a92
+0,         44,         44,        1,   230400, 0xadbc8794
+0,         45,         45,        1,   230400, 0x7f3587d8
+0,         46,         46,        1,   230400, 0xf0400ca6
+0,         47,         47,        1,   230400, 0x59a5138e
+0,         48,         48,        1,   230400, 0x456d62a5
+0,         49,         49,        1,   230400, 0xf1a5e5f1
+0,         50,         50,        1,   230400, 0x75c712e4
+0,         51,         51,        1,   230400, 0xd160780a
+0,         52,         52,        1,   230400, 0xc6c23cf0
+0,         53,         53,        1,   230400, 0x0339a2ac
+0,         54,         54,        1,   230400, 0x0e27a2e2
+0,         55,         55,        1,   230400, 0x84976300
+0,         56,         56,        1,   230400, 0xb368f3c4
+0,         57,         57,        1,   230400, 0xa5231fb8
+0,         58,         58,        1,   230400, 0x17c036d4
+0,         59,         59,        1,   230400, 0xfc81a2c0
+0,         60,         60,        1,   230400, 0x99faa403
+0,         61,         61,        1,   230400, 0xff59efd3
+0,         62,         62,        1,   230400, 0xcece1d23
+0,         63,         63,        1,   230400, 0x56c785d9
+0,         64,         64,        1,   230400, 0xe5a9f222
+0,         65,         65,        1,   230400, 0xb80946f8
+0,         66,         66,        1,   230400, 0xf6b642c6
+0,         67,         67,        1,   230400, 0x69573aed
+0,         68,         68,        1,   230400, 0xfb69a1fd
+0,         69,         69,        1,   230400, 0x100b47f4
+0,         70,         70,        1,   230400, 0x6edf9543
+0,         71,         71,        1,   230400, 0x11fdf43c
+0,         72,         72,        1,   230400, 0xd143bf2a
+0,         73,         73,        1,   230400, 0x7ca747c4
+0,         74,         74,        1,   230400, 0xd984bd73
+0,         75,         75,        1,   230400, 0xc5477e8d
+0,         76,         76,        1,   230400, 0xf7d58300
+0,         77,         77,        1,   230400, 0x7a1b9463
+0,         78,         78,        1,   230400, 0x47a29342
+0,         79,         79,        1,   230400, 0xdf437f9d
+0,         80,         80,        1,   230400, 0xf836ef5d
+0,         81,         81,        1,   230400, 0xc98937af
+0,         82,         82,        1,   230400, 0x9258695b
+0,         83,         83,        1,   230400, 0xd4fe179c
+0,         84,         84,        1,   230400, 0x35d524d3
+0,         85,         85,        1,   230400, 0xd9ce5484
+0,         86,         86,        1,   230400, 0xdef776ed
+0,         87,         87,        1,   230400, 0x154c4057
+0,         88,         88,        1,   230400, 0xf5c764f1
+0,         89,         89,        1,   230400, 0x41979b13
+0,         90,         90,        1,   230400, 0xae4e83db
+0,         91,         91,        1,   230400, 0x09fc0f83
+0,         92,         92,        1,   230400, 0x60267fdf
+0,         93,         93,        1,   230400, 0xeaafc525
+0,         94,         94,        1,   230400, 0x80cc35e5
+0,         95,         95,        1,   230400, 0xd82c6164
+0,         96,         96,        1,   230400, 0xd68b8111
+0,         97,         97,        1,   230400, 0x96f874a3
+0,         98,         98,        1,   230400, 0x7fc861c4
+0,         99,         99,        1,   230400, 0xb911f310
+0,        100,        100,        1,   230400, 0x35bbf5aa
+0,        101,        101,        1,   230400, 0xa922b683
+0,        102,        102,        1,   230400, 0xbf6ae353
+0,        103,        103,        1,   230400, 0x6bd3984c
+0,        104,        104,        1,   230400, 0xe51768c0
+0,        105,        105,        1,   230400, 0xee691624
+0,        106,        106,        1,   230400, 0xd546fed7
+0,        107,        107,        1,   230400, 0x98d375e6
+0,        108,        108,        1,   230400, 0x3b9ca990
+0,        109,        109,        1,   230400, 0x27128ad1
+0,        110,        110,        1,   230400, 0x2788e38c
+0,        111,        111,        1,   230400, 0xb0cf3381
+0,        112,        112,        1,   230400, 0x4fc86d39
+0,        113,        113,        1,   230400, 0xf5632fff
+0,        114,        114,        1,   230400, 0x7fa1e6c2
+0,        115,        115,        1,   230400, 0xffeef044
+0,        116,        116,        1,   230400, 0x932af385
+0,        117,        117,        1,   230400, 0x76738428
+0,        118,        118,        1,   230400, 0xf6771ba2
+0,        119,        119,        1,   230400, 0x17e2ff27
diff --git a/tests/ref/fate/smjpeg b/tests/ref/fate/smjpeg
new file mode 100644
index 0000000..7aac52f
--- /dev/null
+++ b/tests/ref/fate/smjpeg
@@ -0,0 +1,425 @@
+#tb 0: 1/1000
+#tb 1: 1/22050
+0,          0,          0,        0,      734, 0x5a042c2c
+1,          0,          0,      512,     1024, 0x00000000
+1,        507,        507,      512,     1024, 0x00000000
+1,       1014,       1014,      512,     1024, 0xd89a448e
+1,       1521,       1521,      512,     1024, 0x695b369c
+1,       2029,       2029,      512,     1024, 0xc8ba5707
+0,        111,        111,        0,      763, 0xb5893f2f
+1,       2558,       2558,      512,     1024, 0xdf241fc6
+1,       3065,       3065,      512,     1024, 0x61cf4166
+1,       3572,       3572,      512,     1024, 0x97cbc386
+1,       4079,       4079,      512,     1024, 0x44899d04
+1,       4586,       4586,      512,     1024, 0xa7cbaa62
+0,        222,        222,        0,     3023, 0x0f3907d3
+1,       5116,       5116,      512,     1024, 0xa7aea60c
+1,       5623,       5623,      512,     1024, 0xd7b18a89
+1,       6130,       6130,      512,     1024, 0x268e81f6
+1,       6637,       6637,      512,     1024, 0x9cf83a2f
+1,       7166,       7166,      512,     1024, 0x5559b508
+0,        333,        333,        0,     4800, 0x22e6e18a
+1,       7673,       7673,      512,     1024, 0xe1b9e71c
+1,       8181,       8181,      512,     1024, 0xdcee733e
+1,       8688,       8688,      512,     1024, 0xe5918f60
+1,       9195,       9195,      512,     1024, 0x29dbd209
+1,       9724,       9724,      512,     1024, 0x9bcbcf16
+0,        444,        444,        0,     6417, 0x427adde5
+1,      10231,      10231,      512,     1024, 0x86f5f458
+1,      10738,      10738,      512,     1024, 0xabcbda86
+1,      11246,      11246,      512,     1024, 0xc51f77b9
+1,      11775,      11775,      512,     1024, 0xf6b3a504
+0,        555,        555,        0,     6776, 0x7a74c6ad
+1,      12282,      12282,      512,     1024, 0x1af3e40e
+1,      12789,      12789,      512,     1024, 0x3866b03b
+1,      13296,      13296,      512,     1024, 0xbc005403
+1,      13803,      13803,      512,     1024, 0xe9dfcc51
+1,      14333,      14333,      512,     1024, 0x83c837cb
+0,        666,        666,        0,     6808, 0x1f6eb7c3
+1,      14840,      14840,      512,     1024, 0xfa649580
+1,      15347,      15347,      512,     1024, 0x519452ea
+1,      15854,      15854,      512,     1024, 0xd4978774
+1,      16383,      16383,      512,     1024, 0xe2a3b1cd
+1,      16890,      16890,      512,     1024, 0x9a9472ad
+0,        777,        777,        0,     6726, 0x452087e6
+1,      17397,      17397,      512,     1024, 0xa12d4060
+1,      17905,      17905,      512,     1024, 0x31fb0646
+1,      18412,      18412,      512,     1024, 0xfc44343f
+1,      18941,      18941,      512,     1024, 0x0847751a
+1,      19448,      19448,      512,     1024, 0x227968a2
+0,        888,        888,        0,     6829, 0xee82b109
+1,      19955,      19955,      512,     1024, 0x7cce9f1c
+1,      20462,      20462,      512,     1024, 0xb8356713
+1,      20992,      20992,      512,     1024, 0xb29f6e6f
+1,      21499,      21499,      512,     1024, 0x9e1430ab
+1,      22006,      22006,      512,     1024, 0x26d85423
+0,        999,        999,        0,     7055, 0xf41f1108
+1,      22513,      22513,      512,     1024, 0x6496547d
+1,      23020,      23020,      512,     1024, 0x316b1a86
+1,      23549,      23549,      512,     1024, 0x3cd83afc
+1,      24057,      24057,      512,     1024, 0x993ff633
+0,       1111,       1111,        0,     6977, 0xf8fe1ede
+1,      24564,      24564,      512,     1024, 0x0708d1a2
+1,      25071,      25071,      512,     1024, 0xd7230db9
+1,      25578,      25578,      512,     1024, 0xbb0779ca
+1,      26107,      26107,      512,     1024, 0xc6094e1b
+1,      26614,      26614,      512,     1024, 0x15a8b039
+0,       1222,       1222,        0,     6942, 0x9ad105c6
+1,      27122,      27122,      512,     1024, 0xd6dbe88c
+1,      27629,      27629,      512,     1024, 0x7e8d1140
+1,      28158,      28158,      512,     1024, 0xef88e525
+1,      28665,      28665,      512,     1024, 0x44e21149
+1,      29172,      29172,      512,     1024, 0x65b0f5f4
+0,       1333,       1333,        0,     6926, 0xe239dad6
+1,      29679,      29679,      512,     1024, 0xb955f687
+1,      30186,      30186,      512,     1024, 0xc85fba9c
+1,      30716,      30716,      512,     1024, 0xf59655ad
+1,      31223,      31223,      512,     1024, 0x6de80bf1
+1,      31730,      31730,      512,     1024, 0x2dcf6e41
+0,       1444,       1444,        0,     6966, 0x81dcfab1
+1,      32237,      32237,      512,     1024, 0xd0ddcf8a
+1,      32766,      32766,      512,     1024, 0x00135c2d
+1,      33273,      33273,      512,     1024, 0x697f8efd
+1,      33781,      33781,      512,     1024, 0x7a9bada5
+0,       1555,       1555,        0,     6896, 0x31e6cc02
+1,      34288,      34288,      512,     1024, 0x0d22783c
+1,      34795,      34795,      512,     1024, 0x7726d07d
+1,      35324,      35324,      512,     1024, 0xa2f14f67
+1,      35831,      35831,      512,     1024, 0x7f51060d
+1,      36338,      36338,      512,     1024, 0xc4ec6aea
+0,       1666,       1666,        0,     6889, 0x1cc1006e
+1,      36846,      36846,      512,     1024, 0x9bb37ca4
+1,      37375,      37375,      512,     1024, 0x9b085577
+1,      37882,      37882,      512,     1024, 0x8812f8af
+1,      38389,      38389,      512,     1024, 0x788f5221
+1,      38896,      38896,      512,     1024, 0x3a2ce642
+0,       1777,       1777,        0,     6933, 0xc303f87f
+1,      39403,      39403,      512,     1024, 0x72415692
+1,      39933,      39933,      512,     1024, 0xe3dcc105
+1,      40440,      40440,      512,     1024, 0xb26c0599
+1,      40947,      40947,      512,     1024, 0x5c9e55eb
+1,      41454,      41454,      512,     1024, 0x8fe88707
+0,       1888,       1888,        0,     7034, 0xb4970a20
+1,      41983,      41983,      512,     1024, 0xc5d7beb6
+1,      42490,      42490,      512,     1024, 0xe1d3a3b4
+1,      42998,      42998,      512,     1024, 0x012da0c6
+1,      43505,      43505,      512,     1024, 0x8d010922
+1,      44012,      44012,      512,     1024, 0x3366eb0d
+0,       1999,       1999,        0,     6961, 0xf064095d
+1,      44541,      44541,      512,     1024, 0xc9381a27
+1,      45048,      45048,      512,     1024, 0x0774f685
+1,      45555,      45555,      512,     1024, 0xc5cae0a5
+1,      46062,      46062,      512,     1024, 0xa6f4737c
+0,       2111,       2111,        0,     7089, 0x5ba350f9
+1,      46592,      46592,      512,     1024, 0x8fb6d0d1
+1,      47099,      47099,      512,     1024, 0x05f579c2
+1,      47606,      47606,      512,     1024, 0x56905d99
+1,      48113,      48113,      512,     1024, 0x002ee18d
+1,      48620,      48620,      512,     1024, 0xeb37ef51
+0,       2222,       2222,        0,     7078, 0xa83f3e88
+1,      49149,      49149,      512,     1024, 0x38025635
+1,      49657,      49657,      512,     1024, 0x4fe643c8
+1,      50164,      50164,      512,     1024, 0x11d66ab1
+1,      50671,      50671,      512,     1024, 0xcc3051e9
+1,      51178,      51178,      512,     1024, 0xcd93e854
+0,       2333,       2333,        0,     7147, 0xcda66cfc
+1,      51707,      51707,      512,     1024, 0x38f1196d
+1,      52214,      52214,      512,     1024, 0x657a15fc
+1,      52722,      52722,      512,     1024, 0x669ce2a9
+1,      53229,      53229,      512,     1024, 0x95862dda
+1,      53758,      53758,      512,     1024, 0x1726a7b2
+0,       2444,       2444,        0,     7173, 0xb7455859
+1,      54265,      54265,      512,     1024, 0xd6ece2a1
+1,      54772,      54772,      512,     1024, 0x33ab9553
+1,      55279,      55279,      512,     1024, 0xd50c73a6
+1,      55787,      55787,      512,     1024, 0xfe25b63a
+1,      56316,      56316,      512,     1024, 0x7e2959e3
+0,       2555,       2555,        0,     7213, 0x97b89994
+1,      56823,      56823,      512,     1024, 0xa4c07b34
+1,      57330,      57330,      512,     1024, 0xd6d8f15c
+1,      57837,      57837,      512,     1024, 0x1eccddd7
+1,      58366,      58366,      512,     1024, 0x2b69f9cb
+0,       2666,       2666,        0,     7170, 0xca8b2948
+1,      58874,      58874,      512,     1024, 0x667b775f
+1,      59381,      59381,      512,     1024, 0xad3b84e9
+1,      59888,      59888,      512,     1024, 0x4f29fc67
+1,      60395,      60395,      512,     1024, 0x8d611ab7
+1,      60924,      60924,      512,     1024, 0x278966ea
+0,       2777,       2777,        0,     7174, 0xc7cc6bbb
+1,      61431,      61431,      512,     1024, 0xaf33812b
+1,      61938,      61938,      512,     1024, 0xa55f4265
+1,      62446,      62446,      512,     1024, 0x023cb51c
+1,      62975,      62975,      512,     1024, 0x1d1f1005
+1,      63482,      63482,      512,     1024, 0x874cccf7
+0,       2888,       2888,        0,     7235, 0xc2e68d2b
+1,      63989,      63989,      512,     1024, 0xda705428
+1,      64496,      64496,      512,     1024, 0x48d9b440
+1,      65003,      65003,      512,     1024, 0xa14e0712
+1,      65533,      65533,      512,     1024, 0x7efbad1f
+1,      66040,      66040,      512,     1024, 0xdb82c17f
+0,       3000,       3000,        0,     7261, 0x8204a423
+1,      66547,      66547,      512,     1024, 0xcbe87613
+1,      67054,      67054,      512,     1024, 0x3a63df1d
+1,      67583,      67583,      512,     1024, 0xd5636bba
+1,      68090,      68090,      512,     1024, 0x9397af23
+0,       3111,       3111,        0,     7353, 0xacc7e7c0
+1,      68598,      68598,      512,     1024, 0x32a07c98
+1,      69105,      69105,      512,     1024, 0x202ca667
+1,      69612,      69612,      512,     1024, 0xdf969011
+1,      70141,      70141,      512,     1024, 0xc434d238
+1,      70648,      70648,      512,     1024, 0xe9ad7562
+0,       3222,       3222,        0,     7065, 0x45035c5c
+1,      71155,      71155,      512,     1024, 0xb51b6b50
+1,      71663,      71663,      512,     1024, 0xe70aecd3
+1,      72192,      72192,      512,     1024, 0x03c816b2
+1,      72699,      72699,      512,     1024, 0x869fdf25
+1,      73206,      73206,      512,     1024, 0xd40a0a62
+0,       3333,       3333,        0,     7269, 0x72edbb76
+1,      73713,      73713,      512,     1024, 0x5af7dd35
+1,      74220,      74220,      512,     1024, 0x891ffc72
+1,      74750,      74750,      512,     1024, 0x1ff68a08
+1,      75257,      75257,      512,     1024, 0x5a7517a9
+1,      75764,      75764,      512,     1024, 0x0f959f74
+0,       3444,       3444,        0,     7220, 0xb926772f
+1,      76271,      76271,      512,     1024, 0xe92a12a2
+1,      76778,      76778,      512,     1024, 0x38000e55
+1,      77307,      77307,      512,     1024, 0x39fbdd70
+1,      77814,      77814,      512,     1024, 0xca3d9184
+1,      78322,      78322,      512,     1024, 0x66c8995b
+0,       3555,       3555,        0,     7326, 0x0a66c632
+1,      78829,      78829,      512,     1024, 0xac25acea
+1,      79358,      79358,      512,     1024, 0x3cd1046c
+1,      79865,      79865,      512,     1024, 0x6a1df31c
+1,      80372,      80372,      512,     1024, 0x21ca10a1
+0,       3666,       3666,        0,     7225, 0xe39076ab
+1,      80879,      80879,      512,     1024, 0x1aeccedc
+1,      81387,      81387,      512,     1024, 0xddea1335
+1,      81916,      81916,      512,     1024, 0x19f5ca9f
+1,      82423,      82423,      512,     1024, 0x88e95e43
+1,      82930,      82930,      512,     1024, 0x726284fe
+0,       3777,       3777,        0,     7265, 0xe0209036
+1,      83437,      83437,      512,     1024, 0x6b85b40e
+1,      83966,      83966,      512,     1024, 0x111fee2a
+1,      84474,      84474,      512,     1024, 0x3656b588
+1,      84981,      84981,      512,     1024, 0xa5a2b552
+1,      85488,      85488,      512,     1024, 0x38fb2467
+0,       3888,       3888,        0,     7337, 0x7a5dc093
+1,      85995,      85995,      512,     1024, 0xaa919ccc
+1,      86524,      86524,      512,     1024, 0x15993dbc
+1,      87031,      87031,      512,     1024, 0xbe01a7b9
+1,      87539,      87539,      512,     1024, 0xefe93c09
+1,      88046,      88046,      512,     1024, 0x1bb566e5
+0,       4000,       4000,        0,     7246, 0x519a7a3c
+1,      88575,      88575,      512,     1024, 0x15ce6237
+1,      89082,      89082,      512,     1024, 0xa8552e66
+1,      89589,      89589,      512,     1024, 0x9d80187e
+1,      90096,      90096,      512,     1024, 0x5df3fc30
+1,      90603,      90603,      512,     1024, 0x1a312aa5
+0,       4111,       4111,        0,     7266, 0x352c8078
+1,      91133,      91133,      512,     1024, 0x6bb8e302
+1,      91640,      91640,      512,     1024, 0xbd9684bb
+1,      92147,      92147,      512,     1024, 0x78b0b166
+1,      92654,      92654,      512,     1024, 0xd9af5eae
+0,       4222,       4222,        0,     7323, 0xcaf69d7c
+1,      93183,      93183,      512,     1024, 0xdb90fe82
+1,      93690,      93690,      512,     1024, 0x327614e9
+1,      94198,      94198,      512,     1024, 0x1f19b7fe
+1,      94705,      94705,      512,     1024, 0x46c53f96
+1,      95212,      95212,      512,     1024, 0x921b2189
+0,       4333,       4333,        0,     7309, 0x98c1e6f7
+1,      95741,      95741,      512,     1024, 0xa8fbc85a
+1,      96248,      96248,      512,     1024, 0xabfdaaae
+1,      96755,      96755,      512,     1024, 0x6acc7387
+1,      97263,      97263,      512,     1024, 0x0d9c27b5
+1,      97792,      97792,      512,     1024, 0xba4dd809
+0,       4444,       4444,        0,     7121, 0x913d5bd6
+1,      98299,      98299,      512,     1024, 0x2a2ad521
+1,      98806,      98806,      512,     1024, 0x892de38a
+1,      99313,      99313,      512,     1024, 0xdc97a2eb
+1,      99820,      99820,      512,     1024, 0x4f614ca4
+1,     100350,     100350,      512,     1024, 0x9c8a77ea
+0,       4555,       4555,      111,     7088, 0x56302362
+1,     100857,     100857,      512,     1024, 0x2d30e646
+1,     101364,     101364,      512,     1024, 0x74e800a7
+1,     101871,     101871,      512,     1024, 0x1e01fb02
+1,     102378,     102378,      512,     1024, 0x4ed2c1d8
+0,       4666,       4666,      111,     7104, 0xc0d14f78
+1,     102907,     102907,      512,     1024, 0xf2fdbe63
+1,     103415,     103415,      512,     1024, 0x8d6f63a1
+1,     103922,     103922,      512,     1024, 0xded468d9
+1,     104429,     104429,      512,     1024, 0xccad839e
+1,     104958,     104958,      512,     1024, 0xdde7c082
+0,       4777,       4777,      111,     7169, 0xd03c825b
+1,     105465,     105465,      512,     1024, 0x548613c5
+1,     105972,     105972,      512,     1024, 0x383909bd
+1,     106479,     106479,      512,     1024, 0xfd37627b
+1,     106987,     106987,      512,     1024, 0x6d95a481
+1,     107516,     107516,      512,     1024, 0x56aa87fa
+0,       4888,       4888,      111,     7038, 0x1ecc201d
+1,     108023,     108023,      512,     1024, 0x7b67258c
+1,     108530,     108530,      512,     1024, 0x7dd99a92
+1,     109037,     109037,      512,     1024, 0x4a66d102
+1,     109566,     109566,      512,     1024, 0x7b3fce51
+1,     110074,     110074,      512,     1024, 0xbbd968aa
+0,       5000,       5000,      111,     7015, 0x83c94454
+1,     110581,     110581,      512,     1024, 0x8283ec36
+1,     111088,     111088,      512,     1024, 0x3c96493d
+1,     111595,     111595,      512,     1024, 0xfa4f8cf8
+1,     112124,     112124,      512,     1024, 0xe2cf872d
+1,     112631,     112631,      512,     1024, 0x0a9e7aa6
+0,       5111,       5111,      111,     6983, 0x9e51f54d
+1,     113139,     113139,      512,     1024, 0x6e7a0550
+1,     113646,     113646,      512,     1024, 0x3acfea2f
+1,     114175,     114175,      512,     1024, 0x7111d0fa
+1,     114682,     114682,      512,     1024, 0xe9a1eca9
+0,       5222,       5222,      111,     7088, 0x70d33de1
+1,     115189,     115189,      512,     1024, 0x24da6c46
+1,     115696,     115696,      512,     1024, 0x117cff37
+1,     116204,     116204,      512,     1024, 0x0f27cab6
+1,     116733,     116733,      512,     1024, 0x69b6b4e6
+1,     117240,     117240,      512,     1024, 0x1e6cc841
+0,       5333,       5333,      111,     7096, 0x4d0f81b5
+1,     117747,     117747,      512,     1024, 0xb01e2365
+1,     118254,     118254,      512,     1024, 0x14e200d3
+1,     118783,     118783,      512,     1024, 0xd1184c98
+1,     119291,     119291,      512,     1024, 0xef9140e9
+1,     119798,     119798,      512,     1024, 0x4cbb645e
+0,       5444,       5444,      111,     7106, 0xd1a83ddc
+1,     120305,     120305,      512,     1024, 0xe7fe2f06
+1,     120812,     120812,      512,     1024, 0xf8c45028
+1,     121341,     121341,      512,     1024, 0x561358f4
+1,     121848,     121848,      512,     1024, 0xd0129b77
+1,     122355,     122355,      512,     1024, 0xcc636e88
+0,       5555,       5555,      111,     7219, 0x20f47fe4
+1,     122863,     122863,      512,     1024, 0xe9406321
+1,     123392,     123392,      512,     1024, 0x9f16a041
+1,     123899,     123899,      512,     1024, 0x468bf409
+1,     124406,     124406,      512,     1024, 0x3df70f7b
+1,     124913,     124913,      512,     1024, 0xa880b11b
+0,       5666,       5666,      111,     7184, 0x45dc6a0e
+1,     125420,     125420,      512,     1024, 0x3286c489
+1,     125950,     125950,      512,     1024, 0x39fe9ebc
+1,     126457,     126457,      512,     1024, 0xc533d83b
+1,     126964,     126964,      512,     1024, 0x153b195d
+0,       5777,       5777,      111,     7222, 0x488c6499
+1,     127471,     127471,      512,     1024, 0xd84786a1
+1,     127978,     127978,      512,     1024, 0xdc295aaa
+1,     128507,     128507,      512,     1024, 0xfb764d8c
+1,     129015,     129015,      512,     1024, 0xeebc9db9
+1,     129522,     129522,      512,     1024, 0x7ba9403e
+0,       5888,       5888,      111,     7254, 0xbd097ba7
+1,     130029,     130029,      512,     1024, 0x4e5571ec
+1,     130558,     130558,      512,     1024, 0xd965fad4
+1,     131065,     131065,      512,     1024, 0x87e259f2
+1,     131572,     131572,      512,     1024, 0xae7e533b
+1,     132080,     132080,      512,     1024, 0x313cf4d6
+0,       6000,       6000,      111,     7189, 0x46e06d43
+1,     132587,     132587,      512,     1024, 0xe1844c90
+1,     133116,     133116,      512,     1024, 0xbb057b44
+1,     133623,     133623,      512,     1024, 0xa5099687
+1,     134130,     134130,      512,     1024, 0xbff10707
+1,     134637,     134637,      512,     1024, 0x37c4ffc0
+0,       6111,       6111,      111,     7283, 0x19dd7319
+1,     135167,     135167,      512,     1024, 0xf9fb6caa
+1,     135674,     135674,      512,     1024, 0x3b6a3a1f
+1,     136181,     136181,      512,     1024, 0x83431edb
+1,     136688,     136688,      512,     1024, 0x1eb713cf
+1,     137195,     137195,      512,     1024, 0xd7b07a6d
+0,       6222,       6222,      111,     7161, 0x23171d02
+1,     137724,     137724,      512,     1024, 0x81ae3391
+1,     138231,     138231,      512,     1024, 0xf150130a
+1,     138739,     138739,      512,     1024, 0x09678eaa
+1,     139246,     139246,      512,     1024, 0xb94e06f1
+0,       6333,       6333,      111,     6976, 0xcc610c26
+1,     139775,     139775,      512,     1024, 0x67b1dbc9
+1,     140282,     140282,      512,     1024, 0xd6edc235
+1,     140789,     140789,      512,     1024, 0x34e4c499
+1,     141296,     141296,      512,     1024, 0xeefd89c0
+1,     141804,     141804,      512,     1024, 0x38afdaf1
+0,       6444,       6444,      111,     7056, 0x6cd917b0
+1,     142333,     142333,      512,     1024, 0x29a60d76
+1,     142840,     142840,      512,     1024, 0xe28a4372
+1,     143347,     143347,      512,     1024, 0x7089454d
+1,     143854,     143854,      512,     1024, 0x0c01bb7b
+1,     144383,     144383,      512,     1024, 0xbd776a72
+0,       6555,       6555,      111,     6736, 0x02b78951
+1,     144891,     144891,      512,     1024, 0x86776fd0
+1,     145398,     145398,      512,     1024, 0xb37c88f7
+1,     145905,     145905,      512,     1024, 0x5f90aaf8
+1,     146412,     146412,      512,     1024, 0x203d4222
+1,     146941,     146941,      512,     1024, 0x382692a6
+0,       6666,       6666,      111,     6540, 0x767e0854
+1,     147448,     147448,      512,     1024, 0xf37c95fd
+1,     147956,     147956,      512,     1024, 0x6c0b8877
+1,     148463,     148463,      512,     1024, 0x2e54a8b6
+1,     148992,     148992,      512,     1024, 0x7f266488
+0,       6777,       6777,      111,     6170, 0xc84962fb
+1,     149499,     149499,      512,     1024, 0xfbf20f9a
+1,     150006,     150006,      512,     1024, 0xf2985cc0
+1,     150513,     150513,      512,     1024, 0xc7075340
+1,     151020,     151020,      512,     1024, 0xe4585695
+1,     151550,     151550,      512,     1024, 0xbdffa380
+0,       6888,       6888,      111,     6169, 0x27e06c03
+1,     152057,     152057,      512,     1024, 0x2422a8a9
+1,     152564,     152564,      512,     1024, 0x59cbd75f
+1,     153071,     153071,      512,     1024, 0x04ad1a8c
+1,     153578,     153578,      512,     1024, 0x33c09191
+1,     154107,     154107,      512,     1024, 0x55efa6fd
+0,       7000,       7000,      111,     5864, 0xd14db83f
+1,     154615,     154615,      512,     1024, 0xf73d0e5d
+1,     155122,     155122,      512,     1024, 0x6141ebae
+1,     155629,     155629,      512,     1024, 0x7db17a68
+1,     156158,     156158,      512,     1024, 0xa6c690b6
+1,     156665,     156665,      512,     1024, 0xa6fd6725
+0,       7111,       7111,      111,     5375, 0x4a21055d
+1,     157172,     157172,      512,     1024, 0x50a90b9b
+1,     157680,     157680,      512,     1024, 0xef990dc8
+1,     158187,     158187,      512,     1024, 0x75adf6b5
+1,     158716,     158716,      512,     1024, 0x61eac43e
+1,     159223,     159223,      512,     1024, 0x67797a19
+0,       7222,       7222,      111,     5206, 0x95ead3cb
+1,     159730,     159730,      512,     1024, 0xf325277a
+1,     160237,     160237,      512,     1024, 0x18bf254a
+1,     160767,     160767,      512,     1024, 0x2ce6bee3
+1,     161274,     161274,      512,     1024, 0x8d320860
+0,       7333,       7333,      111,     5220, 0xcfdcc37e
+1,     161781,     161781,      512,     1024, 0xc979b6e8
+1,     162288,     162288,      512,     1024, 0xdb644b41
+1,     162795,     162795,      512,     1024, 0xe1b368ba
+1,     163324,     163324,      512,     1024, 0xacc53d15
+1,     163832,     163832,      512,     1024, 0x42ea8c18
+0,       7444,       7444,      111,     4946, 0x2d864a77
+1,     164339,     164339,      512,     1024, 0xe52c99a4
+1,     164846,     164846,      512,     1024, 0xd7db54a6
+1,     165375,     165375,      512,     1024, 0x7f27a7e3
+1,     165882,     165882,      512,     1024, 0xf7ffeaa9
+1,     166389,     166389,      512,     1024, 0x792b6088
+0,       7555,       7555,      111,     4390, 0x2ab9f462
+1,     166896,     166896,      512,     1024, 0x61d99724
+1,     167404,     167404,      512,     1024, 0x5213720e
+1,     167933,     167933,      512,     1024, 0xac09dd30
+1,     168440,     168440,      512,     1024, 0x960bf6bb
+1,     168947,     168947,      512,     1024, 0xc90168e1
+0,       7666,       7666,      111,     4051, 0x1d09592e
+1,     169454,     169454,      512,     1024, 0x43b45768
+1,     169983,     169983,      512,     1024, 0x935d60a1
+1,     170491,     170491,      512,     1024, 0x9a342ef2
+1,     170998,     170998,      512,     1024, 0xc894709f
+0,       7777,       7777,      111,     3680, 0x39bd6a12
+1,     171505,     171505,      512,     1024, 0x59b43b07
+1,     172012,     172012,      512,     1024, 0x36a1a98d
+1,     172541,     172541,      512,     1024, 0x9e1a121c
+1,     173048,     173048,      512,     1024, 0x02208b78
+1,     173556,     173556,      512,     1024, 0xd1d7b274
+0,       7888,       7888,      111,     2910, 0x6337ece9
+1,     174063,     174063,      512,     1024, 0xdacd5096
+1,     174592,     174592,      512,     1024, 0x51b71ead
+1,     175099,     175099,      512,     1024, 0xd009a7ca
+1,     175606,     175606,      512,     1024, 0xb6d5a938
+1,     176113,     176113,      512,     1024, 0xf3d45e47
+0,       8000,       8000,      111,     2153, 0xf4e3bc17
+1,     176621,     176621,      512,     1024, 0xea8e04fc
+1,     177150,     177150,      512,     1024, 0x0b928bd8
+1,     177657,     177657,      512,     1024, 0x0f02caec
+1,     178164,     178164,      512,     1024, 0xe2b137a8
+1,     178671,     178671,      512,     1024, 0xd5f94892
diff --git a/tests/ref/fate/smjpeg-demux b/tests/ref/fate/smjpeg-demux
index 4fcd614..637f28c 100644
--- a/tests/ref/fate/smjpeg-demux
+++ b/tests/ref/fate/smjpeg-demux
@@ -232,7 +232,7 @@
 1,       4388,       4388,       23,      260, 0x06ad6a93
 1,       4411,       4411,       23,      260, 0xdd1b6c91
 1,       4435,       4435,       23,      260, 0x05b94d27
-0,       4444,       4444,      111,     7121, 0x913d5bd6
+0,       4444,       4444,        0,     7121, 0x913d5bd6
 1,       4458,       4458,       23,      260, 0x12cc5062
 1,       4481,       4481,       23,      260, 0x44526d0f
 1,       4504,       4504,       23,      260, 0xf2ac6d95
diff --git a/tests/ref/fate/sub-jacosub b/tests/ref/fate/sub-jacosub
new file mode 100644
index 0000000..b65aee2
--- /dev/null
+++ b/tests/ref/fate/sub-jacosub
@@ -0,0 +1 @@
+4e8f2d1d4130251163432d2a448680be
diff --git a/tests/ref/fate/sub-microdvd b/tests/ref/fate/sub-microdvd
new file mode 100644
index 0000000..9fc10fb
--- /dev/null
+++ b/tests/ref/fate/sub-microdvd
@@ -0,0 +1 @@
+6356b8c53169aae6a20bce34d0f7be87
diff --git a/tests/ref/fate/sub-movtext b/tests/ref/fate/sub-movtext
new file mode 100644
index 0000000..d91c243
--- /dev/null
+++ b/tests/ref/fate/sub-movtext
@@ -0,0 +1 @@
+21453e8ddbbe35d1368a99fe563c969d
diff --git a/tests/ref/fate/sub-movtextenc b/tests/ref/fate/sub-movtextenc
new file mode 100644
index 0000000..8f97497
--- /dev/null
+++ b/tests/ref/fate/sub-movtextenc
@@ -0,0 +1 @@
+0435265a76ab2f6e66627089d76845f4
diff --git a/tests/ref/fate/sub-realtext b/tests/ref/fate/sub-realtext
new file mode 100644
index 0000000..42ac3bb
--- /dev/null
+++ b/tests/ref/fate/sub-realtext
@@ -0,0 +1 @@
+5366f62be001f6fd4a7f48893828bf51
diff --git a/tests/ref/fate/sub-sami b/tests/ref/fate/sub-sami
new file mode 100644
index 0000000..308e000
--- /dev/null
+++ b/tests/ref/fate/sub-sami
@@ -0,0 +1 @@
+00642e143339b4ca29dc6e990436387c
diff --git a/tests/ref/fate/sub-srt b/tests/ref/fate/sub-srt
index 5a14664..ba5e50a 100644
--- a/tests/ref/fate/sub-srt
+++ b/tests/ref/fate/sub-srt
@@ -1 +1 @@
-03b2a3f7e7e83624c8e4d1b5569df758
+a246a00ed72655cb8db3eaf64a522e0d
diff --git a/tests/ref/fate/sub-subripenc b/tests/ref/fate/sub-subripenc
new file mode 100644
index 0000000..7daa4f5
--- /dev/null
+++ b/tests/ref/fate/sub-subripenc
@@ -0,0 +1 @@
+bd520f85238abf9df292374aed54681a
diff --git a/tests/ref/fate/sub-subviewer b/tests/ref/fate/sub-subviewer
new file mode 100644
index 0000000..3b5327f
--- /dev/null
+++ b/tests/ref/fate/sub-subviewer
@@ -0,0 +1 @@
+303c25863d2283928c19db58a53c93e2
diff --git a/tests/ref/fate/sub-webvtt b/tests/ref/fate/sub-webvtt
new file mode 100644
index 0000000..2e32e55
--- /dev/null
+++ b/tests/ref/fate/sub-webvtt
@@ -0,0 +1 @@
+5384a70c89ddca4b007fb7ffba95cffb
diff --git a/tests/ref/fate/svq1 b/tests/ref/fate/svq1
index 3b26d1f..3bcf715 100644
--- a/tests/ref/fate/svq1
+++ b/tests/ref/fate/svq1
@@ -1,151 +1,151 @@
-#tb 0: 1/600
+#tb 0: 1/15
 0,          0,          0,        1,    21600, 0x7f9389e3
-0,         40,         40,        1,    21600, 0xcebb8896
-0,         80,         80,        1,    21600, 0xef51860a
-0,        120,        120,        1,    21600, 0x88d97e7d
-0,        160,        160,        1,    21600, 0xc7757c88
-0,        200,        200,        1,    21600, 0x2f537ade
-0,        240,        240,        1,    21600, 0xd50a7eff
-0,        280,        280,        1,    21600, 0xdcfb7fc6
-0,        320,        320,        1,    21600, 0x0d608299
-0,        360,        360,        1,    21600, 0x97ca81b4
-0,        400,        400,        1,    21600, 0x791f80e7
-0,        440,        440,        1,    21600, 0x96ae7d33
-0,        480,        480,        1,    21600, 0x4d7474a8
-0,        520,        520,        1,    21600, 0x2ae76f37
-0,        560,        560,        1,    21600, 0x7da76265
-0,        600,        600,        1,    21600, 0x93ae3eb6
-0,        640,        640,        1,    21600, 0xebfd3868
-0,        680,        680,        1,    21600, 0x54f82ffa
-0,        720,        720,        1,    21600, 0x8d5b2ad0
-0,        760,        760,        1,    21600, 0xe67128e6
-0,        800,        800,        1,    21600, 0xb7bf613e
-0,        840,        840,        1,    21600, 0xefd0f51b
-0,        880,        880,        1,    21600, 0x31b7da59
-0,        920,        920,        1,    21600, 0x7a84a8f7
-0,        960,        960,        1,    21600, 0x0351ad27
-0,       1000,       1000,        1,    21600, 0xed6f434d
-0,       1040,       1040,        1,    21600, 0x0e771127
-0,       1080,       1080,        1,    21600, 0x37bf0b95
-0,       1120,       1120,        1,    21600, 0x30e10a77
-0,       1160,       1160,        1,    21600, 0x1a48288a
-0,       1200,       1200,        1,    21600, 0xf43c6770
-0,       1240,       1240,        1,    21600, 0x3c43ae68
-0,       1280,       1280,        1,    21600, 0x04dc0949
-0,       1320,       1320,        1,    21600, 0x7920758d
-0,       1360,       1360,        1,    21600, 0x6c12bab5
-0,       1400,       1400,        1,    21600, 0x1ac23706
-0,       1440,       1440,        1,    21600, 0x7a95cb5f
-0,       1480,       1480,        1,    21600, 0xf1bfbb46
-0,       1520,       1520,        1,    21600, 0x773d1d0c
-0,       1560,       1560,        1,    21600, 0x2e7bea65
-0,       1600,       1600,        1,    21600, 0xdb1a086f
-0,       1640,       1640,        1,    21600, 0x5b36b78d
-0,       1680,       1680,        1,    21600, 0x7b533ca6
-0,       1720,       1720,        1,    21600, 0x65d75105
-0,       1760,       1760,        1,    21600, 0xfe6f6207
-0,       1800,       1800,        1,    21600, 0x44c4ce57
-0,       1840,       1840,        1,    21600, 0x220f3dae
-0,       1880,       1880,        1,    21600, 0xb4d20ffb
-0,       1920,       1920,        1,    21600, 0x8907ad72
-0,       1960,       1960,        1,    21600, 0xc6418998
-0,       2000,       2000,        1,    21600, 0x395b6670
-0,       2040,       2040,        1,    21600, 0x83495b88
-0,       2080,       2080,        1,    21600, 0x8920d683
-0,       2120,       2120,        1,    21600, 0xd7fc64ea
-0,       2160,       2160,        1,    21600, 0x21a3b222
-0,       2200,       2200,        1,    21600, 0xc11f2dbd
-0,       2240,       2240,        1,    21600, 0xd1d5495d
-0,       2280,       2280,        1,    21600, 0x70f2de20
-0,       2320,       2320,        1,    21600, 0x10adc9a9
-0,       2360,       2360,        1,    21600, 0xf713c0ec
-0,       2400,       2400,        1,    21600, 0xa346b3fe
-0,       2440,       2440,        1,    21600, 0x7945c29b
-0,       2480,       2480,        1,    21600, 0xb07ceb91
-0,       2520,       2520,        1,    21600, 0xe1eaf9ef
-0,       2560,       2560,        1,    21600, 0x6fa915c7
-0,       2600,       2600,        1,    21600, 0x61952055
-0,       2640,       2640,        1,    21600, 0x4bca2382
-0,       2680,       2680,        1,    21600, 0x36161fe2
-0,       2720,       2720,        1,    21600, 0xf93a28f7
-0,       2760,       2760,        1,    21600, 0xa02a3d47
-0,       2800,       2800,        1,    21600, 0x925b3609
-0,       2840,       2840,        1,    21600, 0x5b6941db
-0,       2880,       2880,        1,    21600, 0x33154a91
-0,       2920,       2920,        1,    21600, 0xb1d75c50
-0,       2960,       2960,        1,    21600, 0x1cb369bd
-0,       3000,       3000,        1,    21600, 0x3be4eff2
-0,       3040,       3040,        1,    21600, 0xbb89c301
-0,       3080,       3080,        1,    21600, 0xc7630d85
-0,       3120,       3120,        1,    21600, 0xf7441c67
-0,       3160,       3160,        1,    21600, 0xc23611ef
-0,       3200,       3200,        1,    21600, 0x840efb21
-0,       3240,       3240,        1,    21600, 0x7d470a0f
-0,       3280,       3280,        1,    21600, 0xfe093210
-0,       3320,       3320,        1,    21600, 0x0f3ea098
-0,       3360,       3360,        1,    21600, 0xcd72286f
-0,       3400,       3400,        1,    21600, 0x826f8030
-0,       3440,       3440,        1,    21600, 0xcda3ace8
-0,       3480,       3480,        1,    21600, 0x39cb4cd0
-0,       3520,       3520,        1,    21600, 0xa86a60ac
-0,       3560,       3560,        1,    21600, 0xcd32ed8e
-0,       3600,       3600,        1,    21600, 0x769b285d
-0,       3640,       3640,        1,    21600, 0x10234cd0
-0,       3680,       3680,        1,    21600, 0x951036b8
-0,       3720,       3720,        1,    21600, 0xaef248fa
-0,       3760,       3760,        1,    21600, 0x74e36e84
-0,       3800,       3800,        1,    21600, 0x3908531b
-0,       3840,       3840,        1,    21600, 0x342f2a9d
-0,       3880,       3880,        1,    21600, 0x291d58f3
-0,       3920,       3920,        1,    21600, 0xcf24b1e5
-0,       3960,       3960,        1,    21600, 0x3e7c7959
-0,       4000,       4000,        1,    21600, 0x6517e573
-0,       4040,       4040,        1,    21600, 0x304cc6db
-0,       4080,       4080,        1,    21600, 0x272895e4
-0,       4120,       4120,        1,    21600, 0x52325837
-0,       4160,       4160,        1,    21600, 0xd01344bd
-0,       4200,       4200,        1,    21600, 0xd25a370b
-0,       4240,       4240,        1,    21600, 0x274e0ae9
-0,       4280,       4280,        1,    21600, 0x6f66138f
-0,       4320,       4320,        1,    21600, 0xd35a0f60
-0,       4360,       4360,        1,    21600, 0xe0610863
-0,       4400,       4400,        1,    21600, 0x920b05fb
-0,       4440,       4440,        1,    21600, 0x5befe39d
-0,       4480,       4480,        1,    21600, 0xd167bd58
-0,       4520,       4520,        1,    21600, 0x653ac504
-0,       4560,       4560,        1,    21600, 0x8372c6d7
-0,       4600,       4600,        1,    21600, 0x0302c276
-0,       4640,       4640,        1,    21600, 0xa176b694
-0,       4680,       4680,        1,    21600, 0x4c2e935a
-0,       4720,       4720,        1,    21600, 0xf7ea844e
-0,       4760,       4760,        1,    21600, 0x76d6c07b
-0,       4800,       4800,        1,    21600, 0x0a14d610
-0,       4840,       4840,        1,    21600, 0x0ec9f3f3
-0,       4880,       4880,        1,    21600, 0xdc90f6ea
-0,       4920,       4920,        1,    21600, 0xc841f9ef
-0,       4960,       4960,        1,    21600, 0x7ab5f9b9
-0,       5000,       5000,        1,    21600, 0xda40f3c2
-0,       5040,       5040,        1,    21600, 0x0040fb72
-0,       5080,       5080,        1,    21600, 0x705b0786
-0,       5120,       5120,        1,    21600, 0x26d5198d
-0,       5160,       5160,        1,    21600, 0x6f5153ad
-0,       5200,       5200,        1,    21600, 0x9f26624b
-0,       5240,       5240,        1,    21600, 0x0d3ea7af
-0,       5280,       5280,        1,    21600, 0xb957ca79
-0,       5320,       5320,        1,    21600, 0x03a60612
-0,       5360,       5360,        1,    21600, 0x3ddc4ff1
-0,       5400,       5400,        1,    21600, 0x8fe5697f
-0,       5440,       5440,        1,    21600, 0x3d199b09
-0,       5480,       5480,        1,    21600, 0x97e2b504
-0,       5520,       5520,        1,    21600, 0x7563f784
-0,       5560,       5560,        1,    21600, 0x9a473879
-0,       5600,       5600,        1,    21600, 0x2e2054e5
-0,       5640,       5640,        1,    21600, 0x06b3658b
-0,       5680,       5680,        1,    21600, 0xa37ee249
-0,       5720,       5720,        1,    21600, 0xa527efa1
-0,       5760,       5760,        1,    21600, 0x12791532
-0,       5800,       5800,        1,    21600, 0xc5350145
-0,       5840,       5840,        1,    21600, 0xcd44f1ac
-0,       5880,       5880,        1,    21600, 0xe610edfb
-0,       5920,       5920,        1,    21600, 0x5642f672
-0,       5960,       5960,        1,    21600, 0xf2bc3e5b
+0,          1,          1,        1,    21600, 0xcebb8896
+0,          2,          2,        1,    21600, 0xef51860a
+0,          3,          3,        1,    21600, 0x88d97e7d
+0,          4,          4,        1,    21600, 0xc7757c88
+0,          5,          5,        1,    21600, 0x2f537ade
+0,          6,          6,        1,    21600, 0xd50a7eff
+0,          7,          7,        1,    21600, 0xdcfb7fc6
+0,          8,          8,        1,    21600, 0x0d608299
+0,          9,          9,        1,    21600, 0x97ca81b4
+0,         10,         10,        1,    21600, 0x791f80e7
+0,         11,         11,        1,    21600, 0x96ae7d33
+0,         12,         12,        1,    21600, 0x4d7474a8
+0,         13,         13,        1,    21600, 0x2ae76f37
+0,         14,         14,        1,    21600, 0x7da76265
+0,         15,         15,        1,    21600, 0x93ae3eb6
+0,         16,         16,        1,    21600, 0xebfd3868
+0,         17,         17,        1,    21600, 0x54f82ffa
+0,         18,         18,        1,    21600, 0x8d5b2ad0
+0,         19,         19,        1,    21600, 0xe67128e6
+0,         20,         20,        1,    21600, 0xb7bf613e
+0,         21,         21,        1,    21600, 0xefd0f51b
+0,         22,         22,        1,    21600, 0x31b7da59
+0,         23,         23,        1,    21600, 0x7a84a8f7
+0,         24,         24,        1,    21600, 0x0351ad27
+0,         25,         25,        1,    21600, 0xed6f434d
+0,         26,         26,        1,    21600, 0x0e771127
+0,         27,         27,        1,    21600, 0x37bf0b95
+0,         28,         28,        1,    21600, 0x30e10a77
+0,         29,         29,        1,    21600, 0x1a48288a
+0,         30,         30,        1,    21600, 0xf43c6770
+0,         31,         31,        1,    21600, 0x3c43ae68
+0,         32,         32,        1,    21600, 0x04dc0949
+0,         33,         33,        1,    21600, 0x7920758d
+0,         34,         34,        1,    21600, 0x6c12bab5
+0,         35,         35,        1,    21600, 0x1ac23706
+0,         36,         36,        1,    21600, 0x7a95cb5f
+0,         37,         37,        1,    21600, 0xf1bfbb46
+0,         38,         38,        1,    21600, 0x773d1d0c
+0,         39,         39,        1,    21600, 0x2e7bea65
+0,         40,         40,        1,    21600, 0xdb1a086f
+0,         41,         41,        1,    21600, 0x5b36b78d
+0,         42,         42,        1,    21600, 0x7b533ca6
+0,         43,         43,        1,    21600, 0x65d75105
+0,         44,         44,        1,    21600, 0xfe6f6207
+0,         45,         45,        1,    21600, 0x44c4ce57
+0,         46,         46,        1,    21600, 0x220f3dae
+0,         47,         47,        1,    21600, 0xb4d20ffb
+0,         48,         48,        1,    21600, 0x8907ad72
+0,         49,         49,        1,    21600, 0xc6418998
+0,         50,         50,        1,    21600, 0x395b6670
+0,         51,         51,        1,    21600, 0x83495b88
+0,         52,         52,        1,    21600, 0x8920d683
+0,         53,         53,        1,    21600, 0xd7fc64ea
+0,         54,         54,        1,    21600, 0x21a3b222
+0,         55,         55,        1,    21600, 0xc11f2dbd
+0,         56,         56,        1,    21600, 0xd1d5495d
+0,         57,         57,        1,    21600, 0x70f2de20
+0,         58,         58,        1,    21600, 0x10adc9a9
+0,         59,         59,        1,    21600, 0xf713c0ec
+0,         60,         60,        1,    21600, 0xa346b3fe
+0,         61,         61,        1,    21600, 0x7945c29b
+0,         62,         62,        1,    21600, 0xb07ceb91
+0,         63,         63,        1,    21600, 0xe1eaf9ef
+0,         64,         64,        1,    21600, 0x6fa915c7
+0,         65,         65,        1,    21600, 0x61952055
+0,         66,         66,        1,    21600, 0x4bca2382
+0,         67,         67,        1,    21600, 0x36161fe2
+0,         68,         68,        1,    21600, 0xf93a28f7
+0,         69,         69,        1,    21600, 0xa02a3d47
+0,         70,         70,        1,    21600, 0x925b3609
+0,         71,         71,        1,    21600, 0x5b6941db
+0,         72,         72,        1,    21600, 0x33154a91
+0,         73,         73,        1,    21600, 0xb1d75c50
+0,         74,         74,        1,    21600, 0x1cb369bd
+0,         75,         75,        1,    21600, 0x3be4eff2
+0,         76,         76,        1,    21600, 0xbb89c301
+0,         77,         77,        1,    21600, 0xc7630d85
+0,         78,         78,        1,    21600, 0xf7441c67
+0,         79,         79,        1,    21600, 0xc23611ef
+0,         80,         80,        1,    21600, 0x840efb21
+0,         81,         81,        1,    21600, 0x7d470a0f
+0,         82,         82,        1,    21600, 0xfe093210
+0,         83,         83,        1,    21600, 0x0f3ea098
+0,         84,         84,        1,    21600, 0xcd72286f
+0,         85,         85,        1,    21600, 0x826f8030
+0,         86,         86,        1,    21600, 0xcda3ace8
+0,         87,         87,        1,    21600, 0x39cb4cd0
+0,         88,         88,        1,    21600, 0xa86a60ac
+0,         89,         89,        1,    21600, 0xcd32ed8e
+0,         90,         90,        1,    21600, 0x769b285d
+0,         91,         91,        1,    21600, 0x10234cd0
+0,         92,         92,        1,    21600, 0x951036b8
+0,         93,         93,        1,    21600, 0xaef248fa
+0,         94,         94,        1,    21600, 0x74e36e84
+0,         95,         95,        1,    21600, 0x3908531b
+0,         96,         96,        1,    21600, 0x342f2a9d
+0,         97,         97,        1,    21600, 0x291d58f3
+0,         98,         98,        1,    21600, 0xcf24b1e5
+0,         99,         99,        1,    21600, 0x3e7c7959
+0,        100,        100,        1,    21600, 0x6517e573
+0,        101,        101,        1,    21600, 0x304cc6db
+0,        102,        102,        1,    21600, 0x272895e4
+0,        103,        103,        1,    21600, 0x52325837
+0,        104,        104,        1,    21600, 0xd01344bd
+0,        105,        105,        1,    21600, 0xd25a370b
+0,        106,        106,        1,    21600, 0x274e0ae9
+0,        107,        107,        1,    21600, 0x6f66138f
+0,        108,        108,        1,    21600, 0xd35a0f60
+0,        109,        109,        1,    21600, 0xe0610863
+0,        110,        110,        1,    21600, 0x920b05fb
+0,        111,        111,        1,    21600, 0x5befe39d
+0,        112,        112,        1,    21600, 0xd167bd58
+0,        113,        113,        1,    21600, 0x653ac504
+0,        114,        114,        1,    21600, 0x8372c6d7
+0,        115,        115,        1,    21600, 0x0302c276
+0,        116,        116,        1,    21600, 0xa176b694
+0,        117,        117,        1,    21600, 0x4c2e935a
+0,        118,        118,        1,    21600, 0xf7ea844e
+0,        119,        119,        1,    21600, 0x76d6c07b
+0,        120,        120,        1,    21600, 0x0a14d610
+0,        121,        121,        1,    21600, 0x0ec9f3f3
+0,        122,        122,        1,    21600, 0xdc90f6ea
+0,        123,        123,        1,    21600, 0xc841f9ef
+0,        124,        124,        1,    21600, 0x7ab5f9b9
+0,        125,        125,        1,    21600, 0xda40f3c2
+0,        126,        126,        1,    21600, 0x0040fb72
+0,        127,        127,        1,    21600, 0x705b0786
+0,        128,        128,        1,    21600, 0x26d5198d
+0,        129,        129,        1,    21600, 0x6f5153ad
+0,        130,        130,        1,    21600, 0x9f26624b
+0,        131,        131,        1,    21600, 0x0d3ea7af
+0,        132,        132,        1,    21600, 0xb957ca79
+0,        133,        133,        1,    21600, 0x03a60612
+0,        134,        134,        1,    21600, 0x3ddc4ff1
+0,        135,        135,        1,    21600, 0x8fe5697f
+0,        136,        136,        1,    21600, 0x3d199b09
+0,        137,        137,        1,    21600, 0x97e2b504
+0,        138,        138,        1,    21600, 0x7563f784
+0,        139,        139,        1,    21600, 0x9a473879
+0,        140,        140,        1,    21600, 0x2e2054e5
+0,        141,        141,        1,    21600, 0x06b3658b
+0,        142,        142,        1,    21600, 0xa37ee249
+0,        143,        143,        1,    21600, 0xa527efa1
+0,        144,        144,        1,    21600, 0x12791532
+0,        145,        145,        1,    21600, 0xc5350145
+0,        146,        146,        1,    21600, 0xcd44f1ac
+0,        147,        147,        1,    21600, 0xe610edfb
+0,        148,        148,        1,    21600, 0x5642f672
+0,        149,        149,        1,    21600, 0xf2bc3e5b
diff --git a/tests/ref/fate/svq3 b/tests/ref/fate/svq3
index 141300a..073d10b 100644
--- a/tests/ref/fate/svq3
+++ b/tests/ref/fate/svq3
@@ -1,181 +1,181 @@
-#tb 0: 1/600
+#tb 0: 1/30
 0,          0,          0,        1,   115200, 0x2c810465
-0,         20,         20,        1,   115200, 0x010b5765
-0,         40,         40,        1,   115200, 0x2be11a4e
-0,         60,         60,        1,   115200, 0x99445d06
-0,         80,         80,        1,   115200, 0x6b54d83c
-0,        100,        100,        1,   115200, 0x3832b76a
-0,        120,        120,        1,   115200, 0x3832b76a
-0,        140,        140,        1,   115200, 0xe18385db
-0,        160,        160,        1,   115200, 0x847d4bf0
-0,        180,        180,        1,   115200, 0x0d650f50
-0,        200,        200,        1,   115200, 0x4b85c44c
-0,        220,        220,        1,   115200, 0xce1927a6
-0,        240,        240,        1,   115200, 0x89353747
-0,        260,        260,        1,   115200, 0x58da43f2
-0,        280,        280,        1,   115200, 0xee9a4eef
-0,        300,        300,        1,   115200, 0xce9453d9
-0,        320,        320,        1,   115200, 0x804a5eb0
-0,        340,        340,        1,   115200, 0xb3d46605
-0,        360,        360,        1,   115200, 0x45b5668e
-0,        380,        380,        1,   115200, 0xdd0d4c5a
-0,        400,        400,        1,   115200, 0x99101301
-0,        420,        420,        1,   115200, 0xf0c3f272
-0,        440,        440,        1,   115200, 0xea21f8b1
-0,        460,        460,        1,   115200, 0xd8e7fbb1
-0,        480,        480,        1,   115200, 0x89d90aa1
-0,        500,        500,        1,   115200, 0x882e19da
-0,        520,        520,        1,   115200, 0xfc0f2709
-0,        540,        540,        1,   115200, 0x9b732f3f
-0,        560,        560,        1,   115200, 0xec453cda
-0,        580,        580,        1,   115200, 0xa77e4989
-0,        600,        600,        1,   115200, 0xad935834
-0,        620,        620,        1,   115200, 0x3a5a6177
-0,        640,        640,        1,   115200, 0xd3c07999
-0,        660,        660,        1,   115200, 0xfad388dd
-0,        680,        680,        1,   115200, 0xaf6e9520
-0,        700,        700,        1,   115200, 0xdb64a4b3
-0,        720,        720,        1,   115200, 0xc6f9b49e
-0,        740,        740,        1,   115200, 0x4446c315
-0,        760,        760,        1,   115200, 0x660bd01c
-0,        780,        780,        1,   115200, 0x963fdd7d
-0,        800,        800,        1,   115200, 0x8733e7b3
-0,        820,        820,        1,   115200, 0x41aaf1d5
-0,        840,        840,        1,   115200, 0xa803fd81
-0,        860,        860,        1,   115200, 0xe2b4077f
-0,        880,        880,        1,   115200, 0xfe6707cb
-0,        900,        900,        1,   115200, 0x027c122d
-0,        920,        920,        1,   115200, 0xbcb81ea8
-0,        940,        940,        1,   115200, 0xd2ac2405
-0,        960,        960,        1,   115200, 0x3d893006
-0,        980,        980,        1,   115200, 0xbdcc3ba8
-0,       1000,       1000,        1,   115200, 0x83ed4c6b
-0,       1020,       1020,        1,   115200, 0x69ee5e7c
-0,       1040,       1040,        1,   115200, 0xfe317411
-0,       1060,       1060,        1,   115200, 0x849e84e6
-0,       1080,       1080,        1,   115200, 0x040f945f
-0,       1100,       1100,        1,   115200, 0x6481ac89
-0,       1120,       1120,        1,   115200, 0x8a48be9e
-0,       1140,       1140,        1,   115200, 0xb162ce94
-0,       1160,       1160,        1,   115200, 0x178dd69a
-0,       1180,       1180,        1,   115200, 0x64fdecaa
-0,       1200,       1200,        1,   115200, 0x4b51297e
-0,       1220,       1220,        1,   115200, 0x3d39a1ae
-0,       1240,       1240,        1,   115200, 0x900fd939
-0,       1260,       1260,        1,   115200, 0x7704fb19
-0,       1280,       1280,        1,   115200, 0xa426137e
-0,       1300,       1300,        1,   115200, 0x9a112706
-0,       1320,       1320,        1,   115200, 0x294931f7
-0,       1340,       1340,        1,   115200, 0x0d0e4372
-0,       1360,       1360,        1,   115200, 0x33bd50e4
-0,       1380,       1380,        1,   115200, 0x9c86e3e2
-0,       1400,       1400,        1,   115200, 0x714af5d5
-0,       1420,       1420,        1,   115200, 0xc5f9fcd0
-0,       1440,       1440,        1,   115200, 0x184602bb
-0,       1460,       1460,        1,   115200, 0x6958e9e6
-0,       1480,       1480,        1,   115200, 0x5a214952
-0,       1500,       1500,        1,   115200, 0x706cca0e
-0,       1520,       1520,        1,   115200, 0x67689363
-0,       1540,       1540,        1,   115200, 0x459f410c
-0,       1560,       1560,        1,   115200, 0xa8f4c365
-0,       1580,       1580,        1,   115200, 0xf1fc50c5
-0,       1600,       1600,        1,   115200, 0xc22af545
-0,       1620,       1620,        1,   115200, 0xd39802a2
-0,       1640,       1640,        1,   115200, 0xb76c04b6
-0,       1660,       1660,        1,   115200, 0x7a548db4
-0,       1680,       1680,        1,   115200, 0x79e56765
-0,       1700,       1700,        1,   115200, 0x3f273a17
-0,       1720,       1720,        1,   115200, 0xe04366db
-0,       1740,       1740,        1,   115200, 0x8e10939b
-0,       1760,       1760,        1,   115200, 0x49220ea2
-0,       1780,       1780,        1,   115200, 0x35361889
-0,       1800,       1800,        1,   115200, 0x9b20bdfa
-0,       1820,       1820,        1,   115200, 0x5d472eaf
-0,       1840,       1840,        1,   115200, 0xeda43081
-0,       1860,       1860,        1,   115200, 0x59bae8b4
-0,       1880,       1880,        1,   115200, 0xf126d6a4
-0,       1900,       1900,        1,   115200, 0x18106464
-0,       1920,       1920,        1,   115200, 0x85530c73
-0,       1940,       1940,        1,   115200, 0xcef32c78
-0,       1960,       1960,        1,   115200, 0xfd6233a0
-0,       1980,       1980,        1,   115200, 0xae9d6fc3
-0,       2000,       2000,        1,   115200, 0x3d0cce10
-0,       2020,       2020,        1,   115200, 0xfce5f124
-0,       2040,       2040,        1,   115200, 0x90b10802
-0,       2060,       2060,        1,   115200, 0xeea44201
-0,       2080,       2080,        1,   115200, 0x1cefb56d
-0,       2100,       2100,        1,   115200, 0xd6daa0b1
-0,       2120,       2120,        1,   115200, 0xd700cef4
-0,       2140,       2140,        1,   115200, 0x36dbf58f
-0,       2160,       2160,        1,   115200, 0xdb20d060
-0,       2180,       2180,        1,   115200, 0x5ca61fd5
-0,       2200,       2200,        1,   115200, 0x4f271361
-0,       2220,       2220,        1,   115200, 0xcaf03743
-0,       2240,       2240,        1,   115200, 0x520f351a
-0,       2260,       2260,        1,   115200, 0x40bc7b89
-0,       2280,       2280,        1,   115200, 0xd0af0b08
-0,       2300,       2300,        1,   115200, 0x6a45290c
-0,       2320,       2320,        1,   115200, 0x57210c14
-0,       2340,       2340,        1,   115200, 0xc1e233f9
-0,       2360,       2360,        1,   115200, 0x96fdfc54
-0,       2380,       2380,        1,   115200, 0x43a8359c
-0,       2400,       2400,        1,   115200, 0xd493bfde
-0,       2420,       2420,        1,   115200, 0xd5339d13
-0,       2440,       2440,        1,   115200, 0x7542baa0
-0,       2460,       2460,        1,   115200, 0x268d2cb9
-0,       2480,       2480,        1,   115200, 0xaf3888bb
-0,       2500,       2500,        1,   115200, 0xb82f520a
-0,       2520,       2520,        1,   115200, 0x0feb2981
-0,       2540,       2540,        1,   115200, 0x45314b58
-0,       2560,       2560,        1,   115200, 0xb26a193a
-0,       2580,       2580,        1,   115200, 0xdfdffc38
-0,       2600,       2600,        1,   115200, 0xec6a55f5
-0,       2620,       2620,        1,   115200, 0xf6e35716
-0,       2640,       2640,        1,   115200, 0x5ce8544e
-0,       2660,       2660,        1,   115200, 0x3e38ddce
-0,       2680,       2680,        1,   115200, 0x964a2006
-0,       2700,       2700,        1,   115200, 0xaba138d6
-0,       2720,       2720,        1,   115200, 0x2f46949c
-0,       2740,       2740,        1,   115200, 0xbdbdb587
-0,       2760,       2760,        1,   115200, 0x1bf11e1d
-0,       2780,       2780,        1,   115200, 0x2632f558
-0,       2800,       2800,        1,   115200, 0x0e58078b
-0,       2820,       2820,        1,   115200, 0x2ab2f9be
-0,       2840,       2840,        1,   115200, 0x9205f1d8
-0,       2860,       2860,        1,   115200, 0x6a4bd949
-0,       2880,       2880,        1,   115200, 0xedc1552f
-0,       2900,       2900,        1,   115200, 0x0a60974d
-0,       2920,       2920,        1,   115200, 0xe1a1400e
-0,       2940,       2940,        1,   115200, 0x45f06952
-0,       2960,       2960,        1,   115200, 0xc5163125
-0,       2980,       2980,        1,   115200, 0x151da156
-0,       3000,       3000,        1,   115200, 0x3f34b048
-0,       3020,       3020,        1,   115200, 0xcf7c1e5d
-0,       3040,       3040,        1,   115200, 0xed9c4e1c
-0,       3060,       3060,        1,   115200, 0x47e06453
-0,       3080,       3080,        1,   115200, 0xc8ce6f19
-0,       3100,       3100,        1,   115200, 0xac619619
-0,       3120,       3120,        1,   115200, 0x64711e2d
-0,       3140,       3140,        1,   115200, 0x1f502b52
-0,       3160,       3160,        1,   115200, 0x39592c9d
-0,       3180,       3180,        1,   115200, 0x7dffb901
-0,       3200,       3200,        1,   115200, 0xc75fa3ce
-0,       3220,       3220,        1,   115200, 0x625bc977
-0,       3240,       3240,        1,   115200, 0x15c7fda3
-0,       3260,       3260,        1,   115200, 0x6e5d35b5
-0,       3280,       3280,        1,   115200, 0xf847cf88
-0,       3300,       3300,        1,   115200, 0xc10867fe
-0,       3320,       3320,        1,   115200, 0xae07fbfc
-0,       3340,       3340,        1,   115200, 0xc1571542
-0,       3360,       3360,        1,   115200, 0x4c7d5602
-0,       3380,       3380,        1,   115200, 0xbe7045aa
-0,       3400,       3400,        1,   115200, 0xc8b4835b
-0,       3420,       3420,        1,   115200, 0xf9b7d427
-0,       3440,       3440,        1,   115200, 0x7fa7c112
-0,       3460,       3460,        1,   115200, 0xe0105feb
-0,       3480,       3480,        1,   115200, 0x70784740
-0,       3500,       3500,        1,   115200, 0xa6801ef5
-0,       3520,       3520,        1,   115200, 0x9cf35921
-0,       3540,       3540,        1,   115200, 0x4d956630
-0,       3560,       3560,        1,   115200, 0x717a25c1
-0,       3580,       3580,        1,   115200, 0x8f5e39de
+0,          1,          1,        1,   115200, 0x010b5765
+0,          2,          2,        1,   115200, 0x2be11a4e
+0,          3,          3,        1,   115200, 0x99445d06
+0,          4,          4,        1,   115200, 0x6b54d83c
+0,          5,          5,        1,   115200, 0x3832b76a
+0,          6,          6,        1,   115200, 0x3832b76a
+0,          7,          7,        1,   115200, 0xe18385db
+0,          8,          8,        1,   115200, 0x847d4bf0
+0,          9,          9,        1,   115200, 0x0d650f50
+0,         10,         10,        1,   115200, 0x4b85c44c
+0,         11,         11,        1,   115200, 0xce1927a6
+0,         12,         12,        1,   115200, 0x89353747
+0,         13,         13,        1,   115200, 0x58da43f2
+0,         14,         14,        1,   115200, 0xee9a4eef
+0,         15,         15,        1,   115200, 0xce9453d9
+0,         16,         16,        1,   115200, 0x804a5eb0
+0,         17,         17,        1,   115200, 0xb3d46605
+0,         18,         18,        1,   115200, 0x45b5668e
+0,         19,         19,        1,   115200, 0xdd0d4c5a
+0,         20,         20,        1,   115200, 0x99101301
+0,         21,         21,        1,   115200, 0xf0c3f272
+0,         22,         22,        1,   115200, 0xea21f8b1
+0,         23,         23,        1,   115200, 0xd8e7fbb1
+0,         24,         24,        1,   115200, 0x89d90aa1
+0,         25,         25,        1,   115200, 0x882e19da
+0,         26,         26,        1,   115200, 0xfc0f2709
+0,         27,         27,        1,   115200, 0x9b732f3f
+0,         28,         28,        1,   115200, 0xec453cda
+0,         29,         29,        1,   115200, 0xa77e4989
+0,         30,         30,        1,   115200, 0xad935834
+0,         31,         31,        1,   115200, 0x3a5a6177
+0,         32,         32,        1,   115200, 0xd3c07999
+0,         33,         33,        1,   115200, 0xfad388dd
+0,         34,         34,        1,   115200, 0xaf6e9520
+0,         35,         35,        1,   115200, 0xdb64a4b3
+0,         36,         36,        1,   115200, 0xc6f9b49e
+0,         37,         37,        1,   115200, 0x4446c315
+0,         38,         38,        1,   115200, 0x660bd01c
+0,         39,         39,        1,   115200, 0x963fdd7d
+0,         40,         40,        1,   115200, 0x8733e7b3
+0,         41,         41,        1,   115200, 0x41aaf1d5
+0,         42,         42,        1,   115200, 0xa803fd81
+0,         43,         43,        1,   115200, 0xe2b4077f
+0,         44,         44,        1,   115200, 0xfe6707cb
+0,         45,         45,        1,   115200, 0x027c122d
+0,         46,         46,        1,   115200, 0xbcb81ea8
+0,         47,         47,        1,   115200, 0xd2ac2405
+0,         48,         48,        1,   115200, 0x3d893006
+0,         49,         49,        1,   115200, 0xbdcc3ba8
+0,         50,         50,        1,   115200, 0x83ed4c6b
+0,         51,         51,        1,   115200, 0x69ee5e7c
+0,         52,         52,        1,   115200, 0xfe317411
+0,         53,         53,        1,   115200, 0x849e84e6
+0,         54,         54,        1,   115200, 0x040f945f
+0,         55,         55,        1,   115200, 0x6481ac89
+0,         56,         56,        1,   115200, 0x8a48be9e
+0,         57,         57,        1,   115200, 0xb162ce94
+0,         58,         58,        1,   115200, 0x178dd69a
+0,         59,         59,        1,   115200, 0x64fdecaa
+0,         60,         60,        1,   115200, 0x4b51297e
+0,         61,         61,        1,   115200, 0x3d39a1ae
+0,         62,         62,        1,   115200, 0x900fd939
+0,         63,         63,        1,   115200, 0x7704fb19
+0,         64,         64,        1,   115200, 0xa426137e
+0,         65,         65,        1,   115200, 0x9a112706
+0,         66,         66,        1,   115200, 0x294931f7
+0,         67,         67,        1,   115200, 0x0d0e4372
+0,         68,         68,        1,   115200, 0x33bd50e4
+0,         69,         69,        1,   115200, 0x9c86e3e2
+0,         70,         70,        1,   115200, 0x714af5d5
+0,         71,         71,        1,   115200, 0xc5f9fcd0
+0,         72,         72,        1,   115200, 0x184602bb
+0,         73,         73,        1,   115200, 0x6958e9e6
+0,         74,         74,        1,   115200, 0x5a214952
+0,         75,         75,        1,   115200, 0x706cca0e
+0,         76,         76,        1,   115200, 0x67689363
+0,         77,         77,        1,   115200, 0x459f410c
+0,         78,         78,        1,   115200, 0xa8f4c365
+0,         79,         79,        1,   115200, 0xf1fc50c5
+0,         80,         80,        1,   115200, 0xc22af545
+0,         81,         81,        1,   115200, 0xd39802a2
+0,         82,         82,        1,   115200, 0xb76c04b6
+0,         83,         83,        1,   115200, 0x7a548db4
+0,         84,         84,        1,   115200, 0x79e56765
+0,         85,         85,        1,   115200, 0x3f273a17
+0,         86,         86,        1,   115200, 0xe04366db
+0,         87,         87,        1,   115200, 0x8e10939b
+0,         88,         88,        1,   115200, 0x49220ea2
+0,         89,         89,        1,   115200, 0x35361889
+0,         90,         90,        1,   115200, 0x9b20bdfa
+0,         91,         91,        1,   115200, 0x5d472eaf
+0,         92,         92,        1,   115200, 0xeda43081
+0,         93,         93,        1,   115200, 0x59bae8b4
+0,         94,         94,        1,   115200, 0xf126d6a4
+0,         95,         95,        1,   115200, 0x18106464
+0,         96,         96,        1,   115200, 0x85530c73
+0,         97,         97,        1,   115200, 0xcef32c78
+0,         98,         98,        1,   115200, 0xfd6233a0
+0,         99,         99,        1,   115200, 0xae9d6fc3
+0,        100,        100,        1,   115200, 0x3d0cce10
+0,        101,        101,        1,   115200, 0xfce5f124
+0,        102,        102,        1,   115200, 0x90b10802
+0,        103,        103,        1,   115200, 0xeea44201
+0,        104,        104,        1,   115200, 0x1cefb56d
+0,        105,        105,        1,   115200, 0xd6daa0b1
+0,        106,        106,        1,   115200, 0xd700cef4
+0,        107,        107,        1,   115200, 0x36dbf58f
+0,        108,        108,        1,   115200, 0xdb20d060
+0,        109,        109,        1,   115200, 0x5ca61fd5
+0,        110,        110,        1,   115200, 0x4f271361
+0,        111,        111,        1,   115200, 0xcaf03743
+0,        112,        112,        1,   115200, 0x520f351a
+0,        113,        113,        1,   115200, 0x40bc7b89
+0,        114,        114,        1,   115200, 0xd0af0b08
+0,        115,        115,        1,   115200, 0x6a45290c
+0,        116,        116,        1,   115200, 0x57210c14
+0,        117,        117,        1,   115200, 0xc1e233f9
+0,        118,        118,        1,   115200, 0x96fdfc54
+0,        119,        119,        1,   115200, 0x43a8359c
+0,        120,        120,        1,   115200, 0xd493bfde
+0,        121,        121,        1,   115200, 0xd5339d13
+0,        122,        122,        1,   115200, 0x7542baa0
+0,        123,        123,        1,   115200, 0x268d2cb9
+0,        124,        124,        1,   115200, 0xaf3888bb
+0,        125,        125,        1,   115200, 0xb82f520a
+0,        126,        126,        1,   115200, 0x0feb2981
+0,        127,        127,        1,   115200, 0x45314b58
+0,        128,        128,        1,   115200, 0xb26a193a
+0,        129,        129,        1,   115200, 0xdfdffc38
+0,        130,        130,        1,   115200, 0xec6a55f5
+0,        131,        131,        1,   115200, 0xf6e35716
+0,        132,        132,        1,   115200, 0x5ce8544e
+0,        133,        133,        1,   115200, 0x3e38ddce
+0,        134,        134,        1,   115200, 0x964a2006
+0,        135,        135,        1,   115200, 0xaba138d6
+0,        136,        136,        1,   115200, 0x2f46949c
+0,        137,        137,        1,   115200, 0xbdbdb587
+0,        138,        138,        1,   115200, 0x1bf11e1d
+0,        139,        139,        1,   115200, 0x2632f558
+0,        140,        140,        1,   115200, 0x0e58078b
+0,        141,        141,        1,   115200, 0x2ab2f9be
+0,        142,        142,        1,   115200, 0x9205f1d8
+0,        143,        143,        1,   115200, 0x6a4bd949
+0,        144,        144,        1,   115200, 0xedc1552f
+0,        145,        145,        1,   115200, 0x0a60974d
+0,        146,        146,        1,   115200, 0xe1a1400e
+0,        147,        147,        1,   115200, 0x45f06952
+0,        148,        148,        1,   115200, 0xc5163125
+0,        149,        149,        1,   115200, 0x151da156
+0,        150,        150,        1,   115200, 0x3f34b048
+0,        151,        151,        1,   115200, 0xcf7c1e5d
+0,        152,        152,        1,   115200, 0xed9c4e1c
+0,        153,        153,        1,   115200, 0x47e06453
+0,        154,        154,        1,   115200, 0xc8ce6f19
+0,        155,        155,        1,   115200, 0xac619619
+0,        156,        156,        1,   115200, 0x64711e2d
+0,        157,        157,        1,   115200, 0x1f502b52
+0,        158,        158,        1,   115200, 0x39592c9d
+0,        159,        159,        1,   115200, 0x7dffb901
+0,        160,        160,        1,   115200, 0xc75fa3ce
+0,        161,        161,        1,   115200, 0x625bc977
+0,        162,        162,        1,   115200, 0x15c7fda3
+0,        163,        163,        1,   115200, 0x6e5d35b5
+0,        164,        164,        1,   115200, 0xf847cf88
+0,        165,        165,        1,   115200, 0xc10867fe
+0,        166,        166,        1,   115200, 0xae07fbfc
+0,        167,        167,        1,   115200, 0xc1571542
+0,        168,        168,        1,   115200, 0x4c7d5602
+0,        169,        169,        1,   115200, 0xbe7045aa
+0,        170,        170,        1,   115200, 0xc8b4835b
+0,        171,        171,        1,   115200, 0xf9b7d427
+0,        172,        172,        1,   115200, 0x7fa7c112
+0,        173,        173,        1,   115200, 0xe0105feb
+0,        174,        174,        1,   115200, 0x70784740
+0,        175,        175,        1,   115200, 0xa6801ef5
+0,        176,        176,        1,   115200, 0x9cf35921
+0,        177,        177,        1,   115200, 0x4d956630
+0,        178,        178,        1,   115200, 0x717a25c1
+0,        179,        179,        1,   115200, 0x8f5e39de
diff --git a/tests/ref/fate/targa-conformance-CCM8 b/tests/ref/fate/targa-conformance-CCM8
index aad3bfc..45bb181 100644
--- a/tests/ref/fate/targa-conformance-CCM8
+++ b/tests/ref/fate/targa-conformance-CCM8
@@ -1,2 +1,2 @@
 #tb 0: 1/25
-0,          0,          0,        1,    65536, 0xcf98bc29
+0,          0,          0,        1,    65536, 0x47e97fe9
diff --git a/tests/ref/fate/targa-conformance-UCM8 b/tests/ref/fate/targa-conformance-UCM8
index aad3bfc..45bb181 100644
--- a/tests/ref/fate/targa-conformance-UCM8
+++ b/tests/ref/fate/targa-conformance-UCM8
@@ -1,2 +1,2 @@
 #tb 0: 1/25
-0,          0,          0,        1,    65536, 0xcf98bc29
+0,          0,          0,        1,    65536, 0x47e97fe9
diff --git a/tests/ref/fate/truemotion1-15 b/tests/ref/fate/truemotion1-15
index 6b5281d..af4a320 100644
--- a/tests/ref/fate/truemotion1-15
+++ b/tests/ref/fate/truemotion1-15
@@ -1,106 +1,106 @@
 #tb 0: 1/15
-0,          0,          0,        1,   161280, 0x7041748d
-0,          1,          1,        1,   161280, 0x3cc4dfb5
-0,          2,          2,        1,   161280, 0xca3af22d
-0,          3,          3,        1,   161280, 0x23ad1d85
-0,          4,          4,        1,   161280, 0x9c9cf364
-0,          5,          5,        1,   161280, 0x1551d6a8
-0,          6,          6,        1,   161280, 0xc39f6b95
-0,          7,          7,        1,   161280, 0x3b036dcc
-0,          8,          8,        1,   161280, 0xa6fac1db
-0,          9,          9,        1,   161280, 0x67656b62
-0,         10,         10,        1,   161280, 0xb41f47d1
-0,         11,         11,        1,   161280, 0xc207249e
-0,         12,         12,        1,   161280, 0xbee8f843
-0,         13,         13,        1,   161280, 0x092acf46
-0,         14,         14,        1,   161280, 0x8d9e2680
-0,         15,         15,        1,   161280, 0x8becc20c
-0,         16,         16,        1,   161280, 0x655e444e
-0,         17,         17,        1,   161280, 0x5c112da0
-0,         18,         18,        1,   161280, 0x232fa9eb
-0,         19,         19,        1,   161280, 0x9721745d
-0,         20,         20,        1,   161280, 0x92f1d880
-0,         21,         21,        1,   161280, 0x16233978
-0,         22,         22,        1,   161280, 0x19a27e69
-0,         23,         23,        1,   161280, 0x7b6ad73a
-0,         24,         24,        1,   161280, 0xa7a674aa
-0,         25,         25,        1,   161280, 0x4e434abb
-0,         26,         26,        1,   161280, 0xb96eea14
-0,         27,         27,        1,   161280, 0x1350188c
-0,         28,         28,        1,   161280, 0x79c6f305
-0,         29,         29,        1,   161280, 0xa9c7782d
-0,         30,         30,        1,   161280, 0x40a4f456
-0,         31,         31,        1,   161280, 0xaf291ed6
-0,         32,         32,        1,   161280, 0xab29b4e1
-0,         33,         33,        1,   161280, 0xbfcd2712
-0,         34,         34,        1,   161280, 0xff22a0d7
-0,         35,         35,        1,   161280, 0xb0ae88a9
-0,         36,         36,        1,   161280, 0x811d1259
-0,         37,         37,        1,   161280, 0x593c39a1
-0,         38,         38,        1,   161280, 0x5a5a97f8
-0,         39,         39,        1,   161280, 0xa5639ecf
-0,         40,         40,        1,   161280, 0x543920c6
-0,         41,         41,        1,   161280, 0xb41689ee
-0,         42,         42,        1,   161280, 0xc0ad83de
-0,         43,         43,        1,   161280, 0x9e9e7456
-0,         44,         44,        1,   161280, 0x777ccbfe
-0,         45,         45,        1,   161280, 0x9c2df916
-0,         46,         46,        1,   161280, 0xe0c13b35
-0,         47,         47,        1,   161280, 0x39bfa5a5
-0,         48,         48,        1,   161280, 0x35dfb264
-0,         49,         49,        1,   161280, 0x43018613
-0,         50,         50,        1,   161280, 0x43584b8a
-0,         51,         51,        1,   161280, 0xa5cd230a
-0,         52,         52,        1,   161280, 0x6fe2cfb3
-0,         53,         53,        1,   161280, 0x88a7c0db
-0,         54,         54,        1,   161280, 0x476f1cd2
-0,         55,         55,        1,   161280, 0x96401d49
-0,         56,         56,        1,   161280, 0x7d932919
-0,         57,         57,        1,   161280, 0x06465481
-0,         58,         58,        1,   161280, 0x39631520
-0,         59,         59,        1,   161280, 0xc3fff780
-0,         60,         60,        1,   161280, 0xa81faf28
-0,         61,         61,        1,   161280, 0x7a311f4f
-0,         62,         62,        1,   161280, 0x52f9b931
-0,         63,         63,        1,   161280, 0x938cf016
-0,         64,         64,        1,   161280, 0xf8f6e19c
-0,         65,         65,        1,   161280, 0xca90561b
-0,         66,         66,        1,   161280, 0x8594d06b
-0,         67,         67,        1,   161280, 0xea32bf3b
-0,         68,         68,        1,   161280, 0x4646111a
-0,         69,         69,        1,   161280, 0xee891162
-0,         70,         70,        1,   161280, 0xcfc32082
-0,         71,         71,        1,   161280, 0x863c281a
-0,         72,         72,        1,   161280, 0x01b591aa
-0,         73,         73,        1,   161280, 0x211fbc62
-0,         74,         74,        1,   161280, 0xae2bafe2
-0,         75,         75,        1,   161280, 0xcfe46dca
-0,         76,         76,        1,   161280, 0xcf8fe8a3
-0,         77,         77,        1,   161280, 0x3f8474eb
-0,         78,         78,        1,   161280, 0x06da345a
-0,         79,         79,        1,   161280, 0xbd4d3280
-0,         80,         80,        1,   161280, 0xb5e70fea
-0,         81,         81,        1,   161280, 0x0c99c804
-0,         82,         82,        1,   161280, 0x19841ed4
-0,         83,         83,        1,   161280, 0xf81dea50
-0,         84,         84,        1,   161280, 0x7777d81c
-0,         85,         85,        1,   161280, 0x0497cfd8
-0,         86,         86,        1,   161280, 0x50b6eb64
-0,         87,         87,        1,   161280, 0x5071fc07
-0,         88,         88,        1,   161280, 0xbb7527fb
-0,         89,         89,        1,   161280, 0x13054f1f
-0,         90,         90,        1,   161280, 0x4b78fb27
-0,         91,         91,        1,   161280, 0xf504968f
-0,         92,         92,        1,   161280, 0x555b10b7
-0,         93,         93,        1,   161280, 0xcc0dde40
-0,         94,         94,        1,   161280, 0xcc0dde40
-0,         95,         95,        1,   161280, 0x367f60c8
-0,         96,         96,        1,   161280, 0x367f60c8
-0,         97,         97,        1,   161280, 0x367f60c8
-0,         98,         98,        1,   161280, 0x367f60c8
-0,         99,         99,        1,   161280, 0x367f60c8
-0,        100,        100,        1,   161280, 0x367f60c8
-0,        101,        101,        1,   161280, 0x367f60c8
-0,        102,        102,        1,   161280, 0x367f60c8
-0,        103,        103,        1,   161280, 0x367f60c8
-0,        104,        104,        1,   161280, 0x367f60c8
+0,          0,          0,        1,   161280, 0x677c9fb3
+0,          1,          1,        1,   161280, 0xaa280e0a
+0,          2,          2,        1,   161280, 0x8a4d2225
+0,          3,          3,        1,   161280, 0xf10f46a8
+0,          4,          4,        1,   161280, 0x98d9eab6
+0,          5,          5,        1,   161280, 0xa543ae1e
+0,          6,          6,        1,   161280, 0x79d717ae
+0,          7,          7,        1,   161280, 0x1a87e2cb
+0,          8,          8,        1,   161280, 0xe5c000ac
+0,          9,          9,        1,   161280, 0xa5827077
+0,         10,         10,        1,   161280, 0xfd0615ee
+0,         11,         11,        1,   161280, 0xc6fdc861
+0,         12,         12,        1,   161280, 0xaa007c7e
+0,         13,         13,        1,   161280, 0xf15e3a96
+0,         14,         14,        1,   161280, 0xce827ae1
+0,         15,         15,        1,   161280, 0xf379fc13
+0,         16,         16,        1,   161280, 0x89686a0c
+0,         17,         17,        1,   161280, 0x7e8342bd
+0,         18,         18,        1,   161280, 0x640dab86
+0,         19,         19,        1,   161280, 0xc6a86456
+0,         20,         20,        1,   161280, 0xe360b538
+0,         21,         21,        1,   161280, 0xbcc21064
+0,         22,         22,        1,   161280, 0x95bc4e63
+0,         23,         23,        1,   161280, 0x390fa1bd
+0,         24,         24,        1,   161280, 0xa35b3bb9
+0,         25,         25,        1,   161280, 0x730b0779
+0,         26,         26,        1,   161280, 0xf3c3a3eb
+0,         27,         27,        1,   161280, 0x676ecbaa
+0,         28,         28,        1,   161280, 0x06c4a4e5
+0,         29,         29,        1,   161280, 0x177d26d9
+0,         30,         30,        1,   161280, 0xdaf69ebe
+0,         31,         31,        1,   161280, 0xabadc296
+0,         32,         32,        1,   161280, 0xec144665
+0,         33,         33,        1,   161280, 0x6785aa48
+0,         34,         34,        1,   161280, 0x2a0cfcaf
+0,         35,         35,        1,   161280, 0x9288d513
+0,         36,         36,        1,   161280, 0x1d295ad0
+0,         37,         37,        1,   161280, 0xb9fd8406
+0,         38,         38,        1,   161280, 0x98bced49
+0,         39,         39,        1,   161280, 0x42e6fbae
+0,         40,         40,        1,   161280, 0xfd218209
+0,         41,         41,        1,   161280, 0x21c2ef31
+0,         42,         42,        1,   161280, 0xce4be932
+0,         43,         43,        1,   161280, 0xd5c0d5fc
+0,         44,         44,        1,   161280, 0xf8d13076
+0,         45,         45,        1,   161280, 0xdbf86007
+0,         46,         46,        1,   161280, 0x9475a651
+0,         47,         47,        1,   161280, 0x41bf1542
+0,         48,         48,        1,   161280, 0x6945297f
+0,         49,         49,        1,   161280, 0x2282025e
+0,         50,         50,        1,   161280, 0x55aace0c
+0,         51,         51,        1,   161280, 0xc78aa51c
+0,         52,         52,        1,   161280, 0xb4b84e6c
+0,         53,         53,        1,   161280, 0x3bbb3e44
+0,         54,         54,        1,   161280, 0x4dd89d80
+0,         55,         55,        1,   161280, 0xa446a5c5
+0,         56,         56,        1,   161280, 0x8f56b1d6
+0,         57,         57,        1,   161280, 0xa170df87
+0,         58,         58,        1,   161280, 0x4740a4df
+0,         59,         59,        1,   161280, 0x86608ee7
+0,         60,         60,        1,   161280, 0x629b4543
+0,         61,         61,        1,   161280, 0x697fb952
+0,         62,         62,        1,   161280, 0x98e84a51
+0,         63,         63,        1,   161280, 0x97949a90
+0,         64,         64,        1,   161280, 0x6a8c9b96
+0,         65,         65,        1,   161280, 0xafa714ab
+0,         66,         66,        1,   161280, 0x0cf39314
+0,         67,         67,        1,   161280, 0x9ccc8171
+0,         68,         68,        1,   161280, 0x8232d5a8
+0,         69,         69,        1,   161280, 0x250dd5cb
+0,         70,         70,        1,   161280, 0xf764e43a
+0,         71,         71,        1,   161280, 0x2f4bec00
+0,         72,         72,        1,   161280, 0x76f1598b
+0,         73,         73,        1,   161280, 0xa91b84da
+0,         74,         74,        1,   161280, 0x011a77fb
+0,         75,         75,        1,   161280, 0xdbf5341c
+0,         76,         76,        1,   161280, 0x40d5abfa
+0,         77,         77,        1,   161280, 0x9fb8360c
+0,         78,         78,        1,   161280, 0xabc5fba8
+0,         79,         79,        1,   161280, 0x98090909
+0,         80,         80,        1,   161280, 0x9a3613bd
+0,         81,         81,        1,   161280, 0x9071024f
+0,         82,         82,        1,   161280, 0x4df39487
+0,         83,         83,        1,   161280, 0x17658524
+0,         84,         84,        1,   161280, 0xbcd794df
+0,         85,         85,        1,   161280, 0x2a14ae05
+0,         86,         86,        1,   161280, 0x664feab2
+0,         87,         87,        1,   161280, 0xf6b721f4
+0,         88,         88,        1,   161280, 0xfec565f3
+0,         89,         89,        1,   161280, 0xd39aabee
+0,         90,         90,        1,   161280, 0x1f3d5de7
+0,         91,         91,        1,   161280, 0xaf97f50c
+0,         92,         92,        1,   161280, 0xe34b6b6a
+0,         93,         93,        1,   161280, 0x4117371e
+0,         94,         94,        1,   161280, 0x4117371e
+0,         95,         95,        1,   161280, 0xe555b55e
+0,         96,         96,        1,   161280, 0xe555b55e
+0,         97,         97,        1,   161280, 0xe555b55e
+0,         98,         98,        1,   161280, 0xe555b55e
+0,         99,         99,        1,   161280, 0xe555b55e
+0,        100,        100,        1,   161280, 0xe555b55e
+0,        101,        101,        1,   161280, 0xe555b55e
+0,        102,        102,        1,   161280, 0xe555b55e
+0,        103,        103,        1,   161280, 0xe555b55e
+0,        104,        104,        1,   161280, 0xe555b55e
diff --git a/tests/ref/fate/truemotion1-24 b/tests/ref/fate/truemotion1-24
index f097ed0..73bb9e7 100644
--- a/tests/ref/fate/truemotion1-24
+++ b/tests/ref/fate/truemotion1-24
@@ -14,3 +14,4 @@
 0,         12,         12,        1,    69120, 0xf55d74c7
 0,         13,         13,        1,    69120, 0xb5082ca7
 0,         14,         14,        1,    69120, 0x5876d758
+0,         15,         15,        1,    69120, 0x45e7dd5c
diff --git a/tests/ref/fate/tscc-15bit b/tests/ref/fate/tscc-15bit
index 372b165..a2871ef 100644
--- a/tests/ref/fate/tscc-15bit
+++ b/tests/ref/fate/tscc-15bit
@@ -1,242 +1,242 @@
 #tb 0: 1/15
 #tb 1: 1/11025
-0,          0,          0,        1,   657600, 0xaf456809
+0,          0,          0,        1,   657600, 0x50b3a0c2
 1,          0,          0,    11025,    22050, 0x1740aaec
-0,          1,          1,        1,   657600, 0xaf456809
-0,          2,          2,        1,   657600, 0xaf456809
-0,          3,          3,        1,   657600, 0x2dbe6889
-0,          4,          4,        1,   657600, 0x2dbe6889
-0,          5,          5,        1,   657600, 0x2dbe6889
-0,          6,          6,        1,   657600, 0x2dbe6889
-0,          7,          7,        1,   657600, 0x2dbe6889
-0,          8,          8,        1,   657600, 0x2dbe6889
-0,          9,          9,        1,   657600, 0x2dbe6889
-0,         10,         10,        1,   657600, 0x2dbe6889
-0,         11,         11,        1,   657600, 0x2dbe6889
-0,         12,         12,        1,   657600, 0x2dbe6889
-0,         13,         13,        1,   657600, 0x2dbe6889
-0,         14,         14,        1,   657600, 0x2dbe6889
-0,         15,         15,        1,   657600, 0x2dbe6889
+0,          1,          1,        1,   657600, 0x50b3a0c2
+0,          2,          2,        1,   657600, 0x50b3a0c2
+0,          3,          3,        1,   657600, 0x661aa145
+0,          4,          4,        1,   657600, 0x661aa145
+0,          5,          5,        1,   657600, 0x661aa145
+0,          6,          6,        1,   657600, 0x661aa145
+0,          7,          7,        1,   657600, 0x661aa145
+0,          8,          8,        1,   657600, 0x661aa145
+0,          9,          9,        1,   657600, 0x661aa145
+0,         10,         10,        1,   657600, 0x661aa145
+0,         11,         11,        1,   657600, 0x661aa145
+0,         12,         12,        1,   657600, 0x661aa145
+0,         13,         13,        1,   657600, 0x661aa145
+0,         14,         14,        1,   657600, 0x661aa145
+0,         15,         15,        1,   657600, 0x661aa145
 1,      11025,      11025,    11025,    22050, 0x75ed6086
-0,         16,         16,        1,   657600, 0x2dbe6889
-0,         17,         17,        1,   657600, 0x2dbe6889
-0,         18,         18,        1,   657600, 0x2dbe6889
-0,         19,         19,        1,   657600, 0x2dbe6889
-0,         20,         20,        1,   657600, 0x2dbe6889
-0,         21,         21,        1,   657600, 0x92796e59
-0,         22,         22,        1,   657600, 0x92796e59
-0,         23,         23,        1,   657600, 0x92796e59
-0,         24,         24,        1,   657600, 0x64cb6889
-0,         25,         25,        1,   657600, 0x64cb6889
-0,         26,         26,        1,   657600, 0x64cb6889
-0,         27,         27,        1,   657600, 0x64cb6889
-0,         28,         28,        1,   657600, 0x64cb6889
-0,         29,         29,        1,   657600, 0x64cb6889
-0,         30,         30,        1,   657600, 0x42036b71
+0,         16,         16,        1,   657600, 0x661aa145
+0,         17,         17,        1,   657600, 0x661aa145
+0,         18,         18,        1,   657600, 0x661aa145
+0,         19,         19,        1,   657600, 0x661aa145
+0,         20,         20,        1,   657600, 0x661aa145
+0,         21,         21,        1,   657600, 0x3c29a73f
+0,         22,         22,        1,   657600, 0x3c29a73f
+0,         23,         23,        1,   657600, 0x3c29a73f
+0,         24,         24,        1,   657600, 0xee2ca145
+0,         25,         25,        1,   657600, 0xee2ca145
+0,         26,         26,        1,   657600, 0xee2ca145
+0,         27,         27,        1,   657600, 0xee2ca145
+0,         28,         28,        1,   657600, 0xee2ca145
+0,         29,         29,        1,   657600, 0xee2ca145
+0,         30,         30,        1,   657600, 0xeb6fa442
 1,      22050,      22050,    11025,    22050, 0xca52a4e9
-0,         31,         31,        1,   657600, 0x42036b71
-0,         32,         32,        1,   657600, 0x42036b71
-0,         33,         33,        1,   657600, 0xc40a6889
-0,         34,         34,        1,   657600, 0xc40a6889
-0,         35,         35,        1,   657600, 0xc40a6889
-0,         36,         36,        1,   657600, 0xaa6f7429
-0,         37,         37,        1,   657600, 0xaa6f7429
-0,         38,         38,        1,   657600, 0xaa6f7429
-0,         39,         39,        1,   657600, 0x854172d9
-0,         40,         40,        1,   657600, 0x854172d9
-0,         41,         41,        1,   657600, 0x854172d9
-0,         42,         42,        1,   657600, 0x22d10de0
-0,         43,         43,        1,   657600, 0xa75f0d60
-0,         44,         44,        1,   657600, 0x7a440be0
-0,         45,         45,        1,   657600, 0x40095d50
+0,         31,         31,        1,   657600, 0xeb6fa442
+0,         32,         32,        1,   657600, 0xeb6fa442
+0,         33,         33,        1,   657600, 0xb235a145
+0,         34,         34,        1,   657600, 0xb235a145
+0,         35,         35,        1,   657600, 0xb235a145
+0,         36,         36,        1,   657600, 0x39f7ad39
+0,         37,         37,        1,   657600, 0x39f7ad39
+0,         38,         38,        1,   657600, 0x39f7ad39
+0,         39,         39,        1,   657600, 0xb851abda
+0,         40,         40,        1,   657600, 0xb851abda
+0,         41,         41,        1,   657600, 0xb851abda
+0,         42,         42,        1,   657600, 0xf6574b22
+0,         43,         43,        1,   657600, 0x1a154a9f
+0,         44,         44,        1,   657600, 0x3de64916
+0,         45,         45,        1,   657600, 0xca3d9cd5
 1,      33075,      33075,    11025,    22050, 0xb306d419
-0,         46,         46,        1,   657600, 0x40095d50
-0,         47,         47,        1,   657600, 0x64766320
-0,         48,         48,        1,   657600, 0x64766320
-0,         49,         49,        1,   657600, 0x64766320
-0,         50,         50,        1,   657600, 0x64766320
-0,         51,         51,        1,   657600, 0x64766320
-0,         52,         52,        1,   657600, 0x64766320
-0,         53,         53,        1,   657600, 0x64766320
-0,         54,         54,        1,   657600, 0x64766320
-0,         55,         55,        1,   657600, 0x64766320
-0,         56,         56,        1,   657600, 0x64766320
-0,         57,         57,        1,   657600, 0xf51adc49
-0,         58,         58,        1,   657600, 0xf51adc49
-0,         59,         59,        1,   657600, 0xf51adc49
-0,         60,         60,        1,   657600, 0xdd47af59
+0,         46,         46,        1,   657600, 0xca3d9cd5
+0,         47,         47,        1,   657600, 0x4779a2cf
+0,         48,         48,        1,   657600, 0x4779a2cf
+0,         49,         49,        1,   657600, 0x4779a2cf
+0,         50,         50,        1,   657600, 0x4779a2cf
+0,         51,         51,        1,   657600, 0x4779a2cf
+0,         52,         52,        1,   657600, 0x4779a2cf
+0,         53,         53,        1,   657600, 0x4779a2cf
+0,         54,         54,        1,   657600, 0x4779a2cf
+0,         55,         55,        1,   657600, 0x4779a2cf
+0,         56,         56,        1,   657600, 0x4779a2cf
+0,         57,         57,        1,   657600, 0x29af1818
+0,         58,         58,        1,   657600, 0x29af1818
+0,         59,         59,        1,   657600, 0x29af1818
+0,         60,         60,        1,   657600, 0x77ace9c5
 1,      44100,      44100,    11025,    22050, 0x8cbb9625
-0,         61,         61,        1,   657600, 0xdd47af59
-0,         62,         62,        1,   657600, 0xffa8acf1
-0,         63,         63,        1,   657600, 0x5994b059
-0,         64,         64,        1,   657600, 0x5994b059
-0,         65,         65,        1,   657600, 0x5994b059
-0,         66,         66,        1,   657600, 0x03ffae71
-0,         67,         67,        1,   657600, 0x03ffae71
-0,         68,         68,        1,   657600, 0x03ffae71
-0,         69,         69,        1,   657600, 0xe33ab89e
-0,         70,         70,        1,   657600, 0xe33ab89e
-0,         71,         71,        1,   657600, 0xe33ab89e
-0,         72,         72,        1,   657600, 0xbe37b549
-0,         73,         73,        1,   657600, 0xbe37b549
-0,         74,         74,        1,   657600, 0x1d395bf9
-0,         75,         75,        1,   657600, 0x1d395bf9
+0,         61,         61,        1,   657600, 0x77ace9c5
+0,         62,         62,        1,   657600, 0x61b8e74b
+0,         63,         63,        1,   657600, 0x8c6deace
+0,         64,         64,        1,   657600, 0x8c6deace
+0,         65,         65,        1,   657600, 0x8c6deace
+0,         66,         66,        1,   657600, 0xbe1fe8d7
+0,         67,         67,        1,   657600, 0xbe1fe8d7
+0,         68,         68,        1,   657600, 0xbe1fe8d7
+0,         69,         69,        1,   657600, 0x633209db
+0,         70,         70,        1,   657600, 0x633209db
+0,         71,         71,        1,   657600, 0x633209db
+0,         72,         72,        1,   657600, 0x3148adb5
+0,         73,         73,        1,   657600, 0x3148adb5
+0,         74,         74,        1,   657600, 0x3b5f5216
+0,         75,         75,        1,   657600, 0x3b5f5216
 1,      55125,      55125,    11025,    22050, 0x34a11f66
-0,         76,         76,        1,   657600, 0x1d395bf9
-0,         77,         77,        1,   657600, 0x1d395bf9
-0,         78,         78,        1,   657600, 0x2ec36f37
-0,         79,         79,        1,   657600, 0x2ec36f37
-0,         80,         80,        1,   657600, 0xb04a6eb7
-0,         81,         81,        1,   657600, 0x66610458
-0,         82,         82,        1,   657600, 0x66610458
-0,         83,         83,        1,   657600, 0xaf8901f0
-0,         84,         84,        1,   657600, 0x3ae41c48
-0,         85,         85,        1,   657600, 0x5b870b70
-0,         86,         86,        1,   657600, 0x11490c60
-0,         87,         87,        1,   657600, 0x70064801
-0,         88,         88,        1,   657600, 0x80d54519
-0,         89,         89,        1,   657600, 0xe8c942b1
-0,         90,         90,        1,   657600, 0x830d8c24
+0,         76,         76,        1,   657600, 0x3b5f5216
+0,         77,         77,        1,   657600, 0x3b5f5216
+0,         78,         78,        1,   657600, 0x5e51fb89
+0,         79,         79,        1,   657600, 0x5e51fb89
+0,         80,         80,        1,   657600, 0x48eafb06
+0,         81,         81,        1,   657600, 0x9f7a8653
+0,         82,         82,        1,   657600, 0x9f7a8653
+0,         83,         83,        1,   657600, 0x29fc83d9
+0,         84,         84,        1,   657600, 0xe7689f10
+0,         85,         85,        1,   657600, 0x9f788dba
+0,         86,         86,        1,   657600, 0x0e808eb2
+0,         87,         87,        1,   657600, 0x3ec53d79
+0,         88,         88,        1,   657600, 0x67ca3a7c
+0,         89,         89,        1,   657600, 0xf7583802
+0,         90,         90,        1,   657600, 0x239e2fc6
 1,      66150,      66150,    11025,    22050, 0x1ae81230
-0,         91,         91,        1,   657600, 0x830d8c24
-0,         92,         92,        1,   657600, 0x830d8c24
-0,         93,         93,        1,   657600, 0xf3c4707c
-0,         94,         94,        1,   657600, 0x6ace707c
-0,         95,         95,        1,   657600, 0x6ace707c
-0,         96,         96,        1,   657600, 0x6ace707c
-0,         97,         97,        1,   657600, 0x6ace707c
-0,         98,         98,        1,   657600, 0x6ace707c
-0,         99,         99,        1,   657600, 0x5f461aae
-0,        100,        100,        1,   657600, 0x5f461aae
-0,        101,        101,        1,   657600, 0x221ceecf
-0,        102,        102,        1,   657600, 0x221ceecf
-0,        103,        103,        1,   657600, 0x221ceecf
-0,        104,        104,        1,   657600, 0x221ceecf
-0,        105,        105,        1,   657600, 0x221ceecf
+0,         91,         91,        1,   657600, 0x239e2fc6
+0,         92,         92,        1,   657600, 0x239e2fc6
+0,         93,         93,        1,   657600, 0x001c134c
+0,         94,         94,        1,   657600, 0x5c85134c
+0,         95,         95,        1,   657600, 0x5c85134c
+0,         96,         96,        1,   657600, 0x5c85134c
+0,         97,         97,        1,   657600, 0x5c85134c
+0,         98,         98,        1,   657600, 0x5c85134c
+0,         99,         99,        1,   657600, 0x5fef8bea
+0,        100,        100,        1,   657600, 0x5fef8bea
+0,        101,        101,        1,   657600, 0x23135efa
+0,        102,        102,        1,   657600, 0x23135efa
+0,        103,        103,        1,   657600, 0x23135efa
+0,        104,        104,        1,   657600, 0x23135efa
+0,        105,        105,        1,   657600, 0x23135efa
 1,      77175,      77175,    11025,    22050, 0x1217eeba
-0,        106,        106,        1,   657600, 0x221ceecf
-0,        107,        107,        1,   657600, 0x221ceecf
-0,        108,        108,        1,   657600, 0x3bf6f39f
-0,        109,        109,        1,   657600, 0x3bf6f39f
-0,        110,        110,        1,   657600, 0x3bf6f39f
-0,        111,        111,        1,   657600, 0xc2caeecf
-0,        112,        112,        1,   657600, 0xc2caeecf
-0,        113,        113,        1,   657600, 0xc2caeecf
-0,        114,        114,        1,   657600, 0xc316d63e
-0,        115,        115,        1,   657600, 0xc316d63e
-0,        116,        116,        1,   657600, 0xc316d63e
-0,        117,        117,        1,   657600, 0x41f6218d
-0,        118,        118,        1,   657600, 0x41f6218d
-0,        119,        119,        1,   657600, 0x41f6218d
-0,        120,        120,        1,   657600, 0xff43ec36
+0,        106,        106,        1,   657600, 0x23135efa
+0,        107,        107,        1,   657600, 0x23135efa
+0,        108,        108,        1,   657600, 0x50cf63ee
+0,        109,        109,        1,   657600, 0x50cf63ee
+0,        110,        110,        1,   657600, 0x50cf63ee
+0,        111,        111,        1,   657600, 0x2f5c5efa
+0,        112,        112,        1,   657600, 0x2f5c5efa
+0,        113,        113,        1,   657600, 0x2f5c5efa
+0,        114,        114,        1,   657600, 0x9980d3c1
+0,        115,        115,        1,   657600, 0x9980d3c1
+0,        116,        116,        1,   657600, 0x9980d3c1
+0,        117,        117,        1,   657600, 0x23f02141
+0,        118,        118,        1,   657600, 0x23f02141
+0,        119,        119,        1,   657600, 0x23f02141
+0,        120,        120,        1,   657600, 0x3d31ea57
 1,      88200,      88200,    11025,    22050, 0x50e70baa
-0,        121,        121,        1,   657600, 0x0b10eb16
-0,        122,        122,        1,   657600, 0x0b10eb16
-0,        123,        123,        1,   657600, 0xbdf41aa5
-0,        124,        124,        1,   657600, 0xbdf41aa5
-0,        125,        125,        1,   657600, 0xbdf41aa5
-0,        126,        126,        1,   657600, 0xd502ca06
-0,        127,        127,        1,   657600, 0xd502ca06
-0,        128,        128,        1,   657600, 0xd502ca06
-0,        129,        129,        1,   657600, 0x8446f89e
-0,        130,        130,        1,   657600, 0x8446f89e
-0,        131,        131,        1,   657600, 0x8446f89e
-0,        132,        132,        1,   657600, 0x3d4ccf06
-0,        133,        133,        1,   657600, 0x0897d1de
-0,        134,        134,        1,   657600, 0x0897d1de
-0,        135,        135,        1,   657600, 0x3e27e01e
+0,        121,        121,        1,   657600, 0x1e9be92f
+0,        122,        122,        1,   657600, 0x1e9be92f
+0,        123,        123,        1,   657600, 0x05091a2e
+0,        124,        124,        1,   657600, 0x05091a2e
+0,        125,        125,        1,   657600, 0x05091a2e
+0,        126,        126,        1,   657600, 0xd214c71a
+0,        127,        127,        1,   657600, 0xd214c71a
+0,        128,        128,        1,   657600, 0xd214c71a
+0,        129,        129,        1,   657600, 0x3b07f720
+0,        130,        130,        1,   657600, 0x3b07f720
+0,        131,        131,        1,   657600, 0x3b07f720
+0,        132,        132,        1,   657600, 0x02becc42
+0,        133,        133,        1,   657600, 0x3d8fcf2e
+0,        134,        134,        1,   657600, 0x3d8fcf2e
+0,        135,        135,        1,   657600, 0xec51ddd7
 1,      99225,      99225,    11025,    22050, 0xb19e89c0
-0,        136,        136,        1,   657600, 0x3e27e01e
-0,        137,        137,        1,   657600, 0x3e27e01e
-0,        138,        138,        1,   657600, 0x3e27e01e
-0,        139,        139,        1,   657600, 0x3e27e01e
-0,        140,        140,        1,   657600, 0x3e27e01e
-0,        141,        141,        1,   657600, 0xe51078a8
-0,        142,        142,        1,   657600, 0xe51078a8
-0,        143,        143,        1,   657600, 0xe9967a40
-0,        144,        144,        1,   657600, 0xe9967a40
-0,        145,        145,        1,   657600, 0xe9967a40
-0,        146,        146,        1,   657600, 0xe9967a40
-0,        147,        147,        1,   657600, 0xe9967a40
-0,        148,        148,        1,   657600, 0xe9967a40
-0,        149,        149,        1,   657600, 0xe9967a40
-0,        150,        150,        1,   657600, 0x726cb6b8
+0,        136,        136,        1,   657600, 0xec51ddd7
+0,        137,        137,        1,   657600, 0xec51ddd7
+0,        138,        138,        1,   657600, 0xec51ddd7
+0,        139,        139,        1,   657600, 0xec51ddd7
+0,        140,        140,        1,   657600, 0xec51ddd7
+0,        141,        141,        1,   657600, 0x40a3b905
+0,        142,        142,        1,   657600, 0x40a3b905
+0,        143,        143,        1,   657600, 0xbfc5baa9
+0,        144,        144,        1,   657600, 0xbfc5baa9
+0,        145,        145,        1,   657600, 0xbfc5baa9
+0,        146,        146,        1,   657600, 0xbfc5baa9
+0,        147,        147,        1,   657600, 0xbfc5baa9
+0,        148,        148,        1,   657600, 0xbfc5baa9
+0,        149,        149,        1,   657600, 0xbfc5baa9
+0,        150,        150,        1,   657600, 0x54a2f8dd
 1,     110250,     110250,    11025,    22050, 0x78526696
-0,        151,        151,        1,   657600, 0x2960b6e8
-0,        152,        152,        1,   657600, 0x2960b6e8
-0,        153,        153,        1,   657600, 0x1637d6c8
-0,        154,        154,        1,   657600, 0x6f2fd9b0
-0,        155,        155,        1,   657600, 0x27a7d6c8
-0,        156,        156,        1,   657600, 0xe855d6c8
-0,        157,        157,        1,   657600, 0xe855d6c8
-0,        158,        158,        1,   657600, 0xe855d6c8
-0,        159,        159,        1,   657600, 0x1a8ad6c8
-0,        160,        160,        1,   657600, 0x9c11d648
-0,        161,        161,        1,   657600, 0x6136d648
-0,        162,        162,        1,   657600, 0xdfa0d6c8
-0,        163,        163,        1,   657600, 0xdfa0d6c8
-0,        164,        164,        1,   657600, 0xdfa0d6c8
-0,        165,        165,        1,   657600, 0xdfa0d6c8
+0,        151,        151,        1,   657600, 0x0b96f90d
+0,        152,        152,        1,   657600, 0x0b96f90d
+0,        153,        153,        1,   657600, 0xa18119e9
+0,        154,        154,        1,   657600, 0x70a11ce6
+0,        155,        155,        1,   657600, 0xb36f19e9
+0,        156,        156,        1,   657600, 0xeb2219e9
+0,        157,        157,        1,   657600, 0xeb2219e9
+0,        158,        158,        1,   657600, 0xeb2219e9
+0,        159,        159,        1,   657600, 0xb98f19e9
+0,        160,        160,        1,   657600, 0xa4281966
+0,        161,        161,        1,   657600, 0xf0e61966
+0,        162,        162,        1,   657600, 0x065c19e9
+0,        163,        163,        1,   657600, 0x065c19e9
+0,        164,        164,        1,   657600, 0x065c19e9
+0,        165,        165,        1,   657600, 0x065c19e9
 1,     121275,     121275,    11025,    22050, 0x48e3bb21
-0,        166,        166,        1,   657600, 0xdfa0d6c8
-0,        167,        167,        1,   657600, 0xdfa0d6c8
-0,        168,        168,        1,   657600, 0xdfa0d6c8
-0,        169,        169,        1,   657600, 0xdfa0d6c8
-0,        170,        170,        1,   657600, 0xdfa0d6c8
-0,        171,        171,        1,   657600, 0x125cd9b0
-0,        172,        172,        1,   657600, 0x125cd9b0
-0,        173,        173,        1,   657600, 0x8a7ed6c8
-0,        174,        174,        1,   657600, 0x09a6d9b0
-0,        175,        175,        1,   657600, 0x09a6d9b0
-0,        176,        176,        1,   657600, 0x09a6d9b0
-0,        177,        177,        1,   657600, 0x85e87a68
-0,        178,        178,        1,   657600, 0x85e87a68
-0,        179,        179,        1,   657600, 0x85e87a68
-0,        180,        180,        1,   657600, 0xb0a141a8
+0,        166,        166,        1,   657600, 0x065c19e9
+0,        167,        167,        1,   657600, 0x065c19e9
+0,        168,        168,        1,   657600, 0x065c19e9
+0,        169,        169,        1,   657600, 0x065c19e9
+0,        170,        170,        1,   657600, 0x065c19e9
+0,        171,        171,        1,   657600, 0x2f1d1ce6
+0,        172,        172,        1,   657600, 0x2f1d1ce6
+0,        173,        173,        1,   657600, 0x181719e9
+0,        174,        174,        1,   657600, 0x938d1ce6
+0,        175,        175,        1,   657600, 0x938d1ce6
+0,        176,        176,        1,   657600, 0x938d1ce6
+0,        177,        177,        1,   657600, 0xf0acbabf
+0,        178,        178,        1,   657600, 0xf0acbabf
+0,        179,        179,        1,   657600, 0xf0acbabf
+0,        180,        180,        1,   657600, 0x0f47804f
 1,     132300,     132300,    11025,    22050, 0xbc32204a
-0,        181,        181,        1,   657600, 0xb0a141a8
-0,        182,        182,        1,   657600, 0xf3333bd8
-0,        183,        183,        1,   657600, 0xea090688
-0,        184,        184,        1,   657600, 0xa017fe41
-0,        185,        185,        1,   657600, 0xa017fe41
-0,        186,        186,        1,   657600, 0x32e93bd8
-0,        187,        187,        1,   657600, 0x7fe640c0
-0,        188,        188,        1,   657600, 0x7fe640c0
-0,        189,        189,        1,   657600, 0xcd8995b2
-0,        190,        190,        1,   657600, 0x84278a92
-0,        191,        191,        1,   657600, 0x84278a92
-0,        192,        192,        1,   657600, 0xf1d2874a
-0,        193,        193,        1,   657600, 0xf1d2874a
-0,        194,        194,        1,   657600, 0xf1d2874a
-0,        195,        195,        1,   657600, 0xa58d6742
+0,        181,        181,        1,   657600, 0x0f47804f
+0,        182,        182,        1,   657600, 0x5e0c7a55
+0,        183,        183,        1,   657600, 0x0c8f4374
+0,        184,        184,        1,   657600, 0x709a3b00
+0,        185,        185,        1,   657600, 0x709a3b00
+0,        186,        186,        1,   657600, 0xf57b7a0f
+0,        187,        187,        1,   657600, 0x99427f1b
+0,        188,        188,        1,   657600, 0x99427f1b
+0,        189,        189,        1,   657600, 0xcb3608e7
+0,        190,        190,        1,   657600, 0x0992fd64
+0,        191,        191,        1,   657600, 0x0992fd64
+0,        192,        192,        1,   657600, 0x7a95fa02
+0,        193,        193,        1,   657600, 0x7a95fa02
+0,        194,        194,        1,   657600, 0x7a95fa02
+0,        195,        195,        1,   657600, 0xb97dd910
 1,     143325,     143325,    11025,    22050, 0xdf6f1e46
-0,        196,        196,        1,   657600, 0xa58d6742
-0,        197,        197,        1,   657600, 0xa58d6742
-0,        198,        198,        1,   657600, 0xb0cd11bb
-0,        199,        199,        1,   657600, 0xb0cd11bb
-0,        200,        200,        1,   657600, 0xc55610bb
-0,        201,        201,        1,   657600, 0x4ee1168b
-0,        202,        202,        1,   657600, 0x61c513a3
-0,        203,        203,        1,   657600, 0xd26410bb
-0,        204,        204,        1,   657600, 0xe7c410bb
-0,        205,        205,        1,   657600, 0x444a0dd3
-0,        206,        206,        1,   657600, 0x444a0dd3
-0,        207,        207,        1,   657600, 0x97ac10bb
-0,        208,        208,        1,   657600, 0x97ac10bb
-0,        209,        209,        1,   657600, 0xe8b30dd3
-0,        210,        210,        1,   657600, 0x3d0c10bb
+0,        196,        196,        1,   657600, 0xb97dd910
+0,        197,        197,        1,   657600, 0xb97dd910
+0,        198,        198,        1,   657600, 0x3be07a66
+0,        199,        199,        1,   657600, 0x3be07a66
+0,        200,        200,        1,   657600, 0x1ae77960
+0,        201,        201,        1,   657600, 0x62177f5a
+0,        202,        202,        1,   657600, 0xf57c7c5d
+0,        203,        203,        1,   657600, 0x600e7960
+0,        204,        204,        1,   657600, 0xe15d7960
+0,        205,        205,        1,   657600, 0x79427663
+0,        206,        206,        1,   657600, 0x79427663
+0,        207,        207,        1,   657600, 0xa7c77960
+0,        208,        208,        1,   657600, 0xa7c77960
+0,        209,        209,        1,   657600, 0x75f67663
+0,        210,        210,        1,   657600, 0x3a157960
 1,     154350,     154350,    11025,    22050, 0x4c91da9d
-0,        211,        211,        1,   657600, 0x8d2b0dd3
-0,        212,        212,        1,   657600, 0x8d2b0dd3
-0,        213,        213,        1,   657600, 0xa5760dd3
-0,        214,        214,        1,   657600, 0xa5760dd3
-0,        215,        215,        1,   657600, 0xa5760dd3
-0,        216,        216,        1,   657600, 0x31a30dd3
-0,        217,        217,        1,   657600, 0x31a30dd3
-0,        218,        218,        1,   657600, 0x31a30dd3
-0,        219,        219,        1,   657600, 0x31a30dd3
-0,        220,        220,        1,   657600, 0x31a30dd3
-0,        221,        221,        1,   657600, 0x31a30dd3
-0,        222,        222,        1,   657600, 0x31a30dd3
-0,        223,        223,        1,   657600, 0x31a30dd3
-0,        224,        224,        1,   657600, 0x31a30dd3
+0,        211,        211,        1,   657600, 0x72aa7663
+0,        212,        212,        1,   657600, 0x72aa7663
+0,        213,        213,        1,   657600, 0x1b277663
+0,        214,        214,        1,   657600, 0x1b277663
+0,        215,        215,        1,   657600, 0x1b277663
+0,        216,        216,        1,   657600, 0x6f5e7663
+0,        217,        217,        1,   657600, 0x6f5e7663
+0,        218,        218,        1,   657600, 0x6f5e7663
+0,        219,        219,        1,   657600, 0x6f5e7663
+0,        220,        220,        1,   657600, 0x6f5e7663
+0,        221,        221,        1,   657600, 0x6f5e7663
+0,        222,        222,        1,   657600, 0x6f5e7663
+0,        223,        223,        1,   657600, 0x6f5e7663
+0,        224,        224,        1,   657600, 0x6f5e7663
diff --git a/tests/ref/fate/txd-16bpp b/tests/ref/fate/txd-16bpp
index 3a23c0b..9522873 100644
--- a/tests/ref/fate/txd-16bpp
+++ b/tests/ref/fate/txd-16bpp
@@ -1,12 +1,12 @@
-#tb 0: 1/90000
-0,          0,          0,        0,    16384, 0x213f9ea8
-0,      18000,      18000,        0,    16384, 0x8185fdb1
-0,      36000,      36000,        0,    16384, 0xf03581d1
-0,      54000,      54000,        0,    16384, 0x629cd573
-0,      72000,      72000,        0,    16384, 0xfe7a5b63
-0,      90000,      90000,        0,    16384, 0x4afc05b2
-0,     108000,     108000,        0,    16384, 0x074b8515
-0,     126000,     126000,        0,    16384, 0x17fde900
-0,     144000,     144000,        0,    16384, 0x831bac76
-0,     162000,     162000,        0,    16384, 0x2fb579f3
-0,     180000,     180000,        0,    16384, 0x68762bed
+#tb 0: 1/5
+0,          0,          0,        1,    16384, 0x213f9ea8
+0,          1,          1,        1,    16384, 0x8185fdb1
+0,          2,          2,        1,    16384, 0xf03581d1
+0,          3,          3,        1,    16384, 0x629cd573
+0,          4,          4,        1,    16384, 0xfe7a5b63
+0,          5,          5,        1,    16384, 0x4afc05b2
+0,          6,          6,        1,    16384, 0x074b8515
+0,          7,          7,        1,    16384, 0x17fde900
+0,          8,          8,        1,    16384, 0x831bac76
+0,          9,          9,        1,    16384, 0x2fb579f3
+0,         10,         10,        1,    16384, 0x68762bed
diff --git a/tests/ref/fate/txd-pal8 b/tests/ref/fate/txd-pal8
index 3f0aab2..61fee80 100644
--- a/tests/ref/fate/txd-pal8
+++ b/tests/ref/fate/txd-pal8
@@ -1,2 +1,2 @@
-#tb 0: 1/90000
-0,          0,          0,        0,   786432, 0x56654d61
+#tb 0: 1/5
+0,          0,          0,        1,   786432, 0x56654d61
diff --git a/tests/ref/fate/v210 b/tests/ref/fate/v210
index 2847564..7ad9dcf 100644
--- a/tests/ref/fate/v210
+++ b/tests/ref/fate/v210
@@ -1,2 +1,2 @@
 #tb 0: 1/50
-0,          0,          0,        1,  3686400, 0x75ee1dde
+0,          0,          0,        1,  3686400, 0x8d5c3847
diff --git a/tests/ref/fate/vc1-ism b/tests/ref/fate/vc1-ism
index 4daca95..7d3b0ab 100644
--- a/tests/ref/fate/vc1-ism
+++ b/tests/ref/fate/vc1-ism
@@ -1,121 +1,121 @@
-#tb 0: 1/10000000
-0,     423334,     423334,        0,    37440, 0xd1bc5235
-0,     840000,     840000,        0,    37440, 0x158e6167
-0,    1256666,    1256666,        0,    37440, 0x0faa4481
-0,    1670000,    1670000,        0,    37440, 0x427158c5
-0,    2086666,    2086666,        0,    37440, 0x4eb53ac6
-0,    2500000,    2500000,        0,    37440, 0x99304eea
-0,    2916666,    2916666,        0,    37440, 0xcc554a6f
-0,    3340000,    3340000,        0,    37440, 0xabeb6c35
-0,    3756666,    3756666,        0,    37440, 0xddfc7e18
-0,    4170000,    4170000,        0,    37440, 0xaa79b504
-0,    4586666,    4586666,        0,    37440, 0x5cb1c839
-0,    5000000,    5000000,        0,    37440, 0x7e36ecca
-0,    5416666,    5416666,        0,    37440, 0xf486f425
-0,    5840000,    5840000,        0,    37440, 0xf1b4138f
-0,    6256666,    6256666,        0,    37440, 0x966f1a49
-0,    6670000,    6670000,        0,    37440, 0x5eff21da
-0,    7086666,    7086666,        0,    37440, 0x333f39b1
-0,    7500000,    7500000,        0,    37440, 0x62e5963e
-0,    7916666,    7916666,        0,    37440, 0x26930671
-0,    8340000,    8340000,        0,    37440, 0x27b4bb6c
-0,    8756666,    8756666,        0,    37440, 0xdbd07766
-0,    9170000,    9170000,        0,    37440, 0x04260104
-0,    9586666,    9586666,        0,    37440, 0x9b1e078b
-0,   10000000,   10000000,        0,    37440, 0xdf4e2474
-0,   10416666,   10416666,        0,    37440, 0x57d44986
-0,   10840000,   10840000,        0,    37440, 0x8780e34c
-0,   11256666,   11256666,        0,    37440, 0xf80c8bc0
-0,   11670000,   11670000,        0,    37440, 0x630a7583
-0,   12086666,   12086666,        0,    37440, 0x235ae089
-0,   12500000,   12500000,        0,    37440, 0x984b8f0e
-0,   12916666,   12916666,        0,    37440, 0x865cf592
-0,   13340000,   13340000,        0,    37440, 0x70f376f2
-0,   13756666,   13756666,        0,    37440, 0x8b30c035
-0,   14170000,   14170000,        0,    37440, 0xde772d79
-0,   14586666,   14586666,        0,    37440, 0x8e076be5
-0,   15000000,   15000000,        0,    37440, 0x3dc2bd9f
-0,   15416666,   15416666,        0,    37440, 0xb782eb67
-0,   15840000,   15840000,        0,    37440, 0x02025d73
-0,   16256666,   16256666,        0,    37440, 0x86bbbce8
-0,   16670000,   16670000,        0,    37440, 0xd6554f62
-0,   17086666,   17086666,        0,    37440, 0xb831b917
-0,   17500000,   17500000,        0,    37440, 0x80643560
-0,   17916666,   17916666,        0,    37440, 0x4ecf9afd
-0,   18340000,   18340000,        0,    37440, 0x9ce51e0b
-0,   18756666,   18756666,        0,    37440, 0x179466cd
-0,   19170000,   19170000,        0,    37440, 0x145fc900
-0,   19586666,   19586666,        0,    37440, 0xb1b50402
-0,   20000000,   20000000,        0,    37440, 0x0a87552a
-0,   20416666,   20416666,        0,    37440, 0x8f53821d
-0,   20840000,   20840000,        0,    37440, 0x1c07c825
-0,   21256666,   21256666,        0,    37440, 0x49dde82f
-0,   21670000,   21670000,        0,    37440, 0xb1a32605
-0,   22086666,   22086666,        0,    37440, 0x410f3cd5
-0,   22500000,   22500000,        0,    37440, 0xff5e6696
-0,   22916666,   22916666,        0,    37440, 0x96f678c9
-0,   23340000,   23340000,        0,    37440, 0x6c9e9e68
-0,   23756666,   23756666,        0,    37440, 0x79a2a655
-0,   24170000,   24170000,        0,    37440, 0xf237bd6c
-0,   24586666,   24586666,        0,    37440, 0x4051b611
-0,   25000000,   25000000,        0,    37440, 0xc7ccc918
-0,   25416666,   25416666,        0,    37440, 0xbd02c122
-0,   25840000,   25840000,        0,    37440, 0xacb3c881
-0,   26256666,   26256666,        0,    37440, 0x2abdb940
-0,   26670000,   26670000,        0,    37440, 0x19d5be85
-0,   27086666,   27086666,        0,    37440, 0xfa5fb1ba
-0,   27503332,   27503332,        0,    37440, 0xdae7a7aa
-0,   27919998,   27919998,        0,    37440, 0x6b0f9f69
-0,   28340000,   28340000,        0,    37440, 0x353e8201
-0,   28756666,   28756666,        0,    37440, 0xa21443aa
-0,   29170000,   29170000,        0,    37440, 0x66c8d7e0
-0,   29586666,   29586666,        0,    37440, 0xc332068e
-0,   30000000,   30000000,        0,    37440, 0x71431b9b
-0,   30416666,   30416666,        0,    37440, 0x392f15cb
-0,   30840000,   30840000,        0,    37440, 0x95a146bb
-0,   31256666,   31256666,        0,    37440, 0x7c51740a
-0,   31670000,   31670000,        0,    37440, 0xa3bdd43c
-0,   32086666,   32086666,        0,    37440, 0xa079f965
-0,   32500000,   32500000,        0,    37440, 0xa95423ea
-0,   32916666,   32916666,        0,    37440, 0xd1bd2c67
-0,   33340000,   33340000,        0,    37440, 0x6cf82844
-0,   33756666,   33756666,        0,    37440, 0xd401e128
-0,   34170000,   34170000,        0,    37440, 0x1f7db118
-0,   34586666,   34586666,        0,    37440, 0x2e0a65a9
-0,   35000000,   35000000,        0,    37440, 0x321c1c40
-0,   35416666,   35416666,        0,    37440, 0x95b2a127
-0,   35840000,   35840000,        0,    37440, 0xa1471f4b
-0,   36256666,   36256666,        0,    37440, 0x29d148c0
-0,   36670000,   36670000,        0,    37440, 0x24c07107
-0,   37086666,   37086666,        0,    37440, 0x0ead678d
-0,   37500000,   37500000,        0,    37440, 0xd0ca6495
-0,   37916666,   37916666,        0,    37440, 0x08f935ef
-0,   38340000,   38340000,        0,    37440, 0xb5ec3c38
-0,   38756666,   38756666,        0,    37440, 0xce371628
-0,   39170000,   39170000,        0,    37440, 0x68170812
-0,   39586666,   39586666,        0,    37440, 0xe222699e
-0,   40000000,   40000000,        0,    37440, 0xd688706c
-0,   40416666,   40416666,        0,    37440, 0x81a033f9
-0,   40840000,   40840000,        0,    37440, 0x28bd0fbf
-0,   41256666,   41256666,        0,    37440, 0xe36db7b2
-0,   41670000,   41670000,        0,    37440, 0x30559121
-0,   42086666,   42086666,        0,    37440, 0xbf2b5fc8
-0,   42500000,   42500000,        0,    37440, 0x4b427672
-0,   42916666,   42916666,        0,    37440, 0x0544b0b4
-0,   43340000,   43340000,        0,    37440, 0x38a70b06
-0,   43756666,   43756666,        0,    37440, 0x4ed62607
-0,   44170000,   44170000,        0,    37440, 0x6efe8ea6
-0,   44586666,   44586666,        0,    37440, 0x81197e11
-0,   45000000,   45000000,        0,    37440, 0xf4060050
-0,   45416666,   45416666,        0,    37440, 0xaf205f13
-0,   45840000,   45840000,        0,    37440, 0x5fa21382
-0,   46256666,   46256666,        0,    37440, 0x8627ad05
-0,   46670000,   46670000,        0,    37440, 0xf7130133
-0,   47086666,   47086666,        0,    37440, 0x76dea7ba
-0,   47500000,   47500000,        0,    37440, 0x1dbae1be
-0,   47916666,   47916666,        0,    37440, 0x74a933f7
-0,   48340000,   48340000,        0,    37440, 0xbdcd41a3
-0,   48756666,   48756666,        0,    37440, 0xf0fe8c1c
-0,   49170000,   49170000,        0,    37440, 0xc0036222
-0,   49586666,   49586666,        0,    37440, 0x3058385c
-0,   49586667,   49586667,        0,    37440, 0x68141016
+#tb 0: 1/24
+0,          0,          0,        1,    37440, 0xd1bc5235
+0,          2,          2,        1,    37440, 0x158e6167
+0,          3,          3,        1,    37440, 0x0faa4481
+0,          4,          4,        1,    37440, 0x427158c5
+0,          5,          5,        1,    37440, 0x4eb53ac6
+0,          6,          6,        1,    37440, 0x99304eea
+0,          7,          7,        1,    37440, 0xcc554a6f
+0,          8,          8,        1,    37440, 0xabeb6c35
+0,          9,          9,        1,    37440, 0xddfc7e18
+0,         10,         10,        1,    37440, 0xaa79b504
+0,         11,         11,        1,    37440, 0x5cb1c839
+0,         12,         12,        1,    37440, 0x7e36ecca
+0,         13,         13,        1,    37440, 0xf486f425
+0,         14,         14,        1,    37440, 0xf1b4138f
+0,         15,         15,        1,    37440, 0x966f1a49
+0,         16,         16,        1,    37440, 0x5eff21da
+0,         17,         17,        1,    37440, 0x333f39b1
+0,         18,         18,        1,    37440, 0x62e5963e
+0,         19,         19,        1,    37440, 0x26930671
+0,         20,         20,        1,    37440, 0x27b4bb6c
+0,         21,         21,        1,    37440, 0xdbd07766
+0,         22,         22,        1,    37440, 0x04260104
+0,         23,         23,        1,    37440, 0x9b1e078b
+0,         24,         24,        1,    37440, 0xdf4e2474
+0,         25,         25,        1,    37440, 0x57d44986
+0,         26,         26,        1,    37440, 0x8780e34c
+0,         27,         27,        1,    37440, 0xf80c8bc0
+0,         28,         28,        1,    37440, 0x630a7583
+0,         29,         29,        1,    37440, 0x235ae089
+0,         30,         30,        1,    37440, 0x984b8f0e
+0,         31,         31,        1,    37440, 0x865cf592
+0,         32,         32,        1,    37440, 0x70f376f2
+0,         33,         33,        1,    37440, 0x8b30c035
+0,         34,         34,        1,    37440, 0xde772d79
+0,         35,         35,        1,    37440, 0x8e076be5
+0,         36,         36,        1,    37440, 0x3dc2bd9f
+0,         37,         37,        1,    37440, 0xb782eb67
+0,         38,         38,        1,    37440, 0x02025d73
+0,         39,         39,        1,    37440, 0x86bbbce8
+0,         40,         40,        1,    37440, 0xd6554f62
+0,         41,         41,        1,    37440, 0xb831b917
+0,         42,         42,        1,    37440, 0x80643560
+0,         43,         43,        1,    37440, 0x4ecf9afd
+0,         44,         44,        1,    37440, 0x9ce51e0b
+0,         45,         45,        1,    37440, 0x179466cd
+0,         46,         46,        1,    37440, 0x145fc900
+0,         47,         47,        1,    37440, 0xb1b50402
+0,         48,         48,        1,    37440, 0x0a87552a
+0,         49,         49,        1,    37440, 0x8f53821d
+0,         50,         50,        1,    37440, 0x1c07c825
+0,         51,         51,        1,    37440, 0x49dde82f
+0,         52,         52,        1,    37440, 0xb1a32605
+0,         53,         53,        1,    37440, 0x410f3cd5
+0,         54,         54,        1,    37440, 0xff5e6696
+0,         55,         55,        1,    37440, 0x96f678c9
+0,         56,         56,        1,    37440, 0x6c9e9e68
+0,         57,         57,        1,    37440, 0x79a2a655
+0,         58,         58,        1,    37440, 0xf237bd6c
+0,         59,         59,        1,    37440, 0x4051b611
+0,         60,         60,        1,    37440, 0xc7ccc918
+0,         61,         61,        1,    37440, 0xbd02c122
+0,         62,         62,        1,    37440, 0xacb3c881
+0,         63,         63,        1,    37440, 0x2abdb940
+0,         64,         64,        1,    37440, 0x19d5be85
+0,         65,         65,        1,    37440, 0xfa5fb1ba
+0,         66,         66,        1,    37440, 0xdae7a7aa
+0,         67,         67,        1,    37440, 0x6b0f9f69
+0,         68,         68,        1,    37440, 0x353e8201
+0,         69,         69,        1,    37440, 0xa21443aa
+0,         70,         70,        1,    37440, 0x66c8d7e0
+0,         71,         71,        1,    37440, 0xc332068e
+0,         72,         72,        1,    37440, 0x71431b9b
+0,         73,         73,        1,    37440, 0x392f15cb
+0,         74,         74,        1,    37440, 0x95a146bb
+0,         75,         75,        1,    37440, 0x7c51740a
+0,         76,         76,        1,    37440, 0xa3bdd43c
+0,         77,         77,        1,    37440, 0xa079f965
+0,         78,         78,        1,    37440, 0xa95423ea
+0,         79,         79,        1,    37440, 0xd1bd2c67
+0,         80,         80,        1,    37440, 0x6cf82844
+0,         81,         81,        1,    37440, 0xd401e128
+0,         82,         82,        1,    37440, 0x1f7db118
+0,         83,         83,        1,    37440, 0x2e0a65a9
+0,         84,         84,        1,    37440, 0x321c1c40
+0,         85,         85,        1,    37440, 0x95b2a127
+0,         86,         86,        1,    37440, 0xa1471f4b
+0,         87,         87,        1,    37440, 0x29d148c0
+0,         88,         88,        1,    37440, 0x24c07107
+0,         89,         89,        1,    37440, 0x0ead678d
+0,         90,         90,        1,    37440, 0xd0ca6495
+0,         91,         91,        1,    37440, 0x08f935ef
+0,         92,         92,        1,    37440, 0xb5ec3c38
+0,         93,         93,        1,    37440, 0xce371628
+0,         94,         94,        1,    37440, 0x68170812
+0,         95,         95,        1,    37440, 0xe222699e
+0,         96,         96,        1,    37440, 0xd688706c
+0,         97,         97,        1,    37440, 0x81a033f9
+0,         98,         98,        1,    37440, 0x28bd0fbf
+0,         99,         99,        1,    37440, 0xe36db7b2
+0,        100,        100,        1,    37440, 0x30559121
+0,        101,        101,        1,    37440, 0xbf2b5fc8
+0,        102,        102,        1,    37440, 0x4b427672
+0,        103,        103,        1,    37440, 0x0544b0b4
+0,        104,        104,        1,    37440, 0x38a70b06
+0,        105,        105,        1,    37440, 0x4ed62607
+0,        106,        106,        1,    37440, 0x6efe8ea6
+0,        107,        107,        1,    37440, 0x81197e11
+0,        108,        108,        1,    37440, 0xf4060050
+0,        109,        109,        1,    37440, 0xaf205f13
+0,        110,        110,        1,    37440, 0x5fa21382
+0,        111,        111,        1,    37440, 0x8627ad05
+0,        112,        112,        1,    37440, 0xf7130133
+0,        113,        113,        1,    37440, 0x76dea7ba
+0,        114,        114,        1,    37440, 0x1dbae1be
+0,        115,        115,        1,    37440, 0x74a933f7
+0,        116,        116,        1,    37440, 0xbdcd41a3
+0,        117,        117,        1,    37440, 0xf0fe8c1c
+0,        118,        118,        1,    37440, 0xc0036222
+0,        119,        119,        1,    37440, 0x3058385c
+0,        120,        120,        1,    37440, 0x68141016
diff --git a/tests/ref/fate/vc1_sa10143 b/tests/ref/fate/vc1_sa10143
index a008356..0d2e697 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, 0xeb8d84a1
-0,          3,          3,        1,   518400, 0x2121ff57
-0,          4,          4,        1,   518400, 0xd81adb3d
-0,          5,          5,        1,   518400, 0x01e36aa2
-0,          6,          6,        1,   518400, 0x6b802361
-0,          7,          7,        1,   518400, 0xc8403c77
-0,          8,          8,        1,   518400, 0xdd342b5d
-0,          9,          9,        1,   518400, 0x2100eea5
-0,         10,         10,        1,   518400, 0x92a22da6
-0,         11,         11,        1,   518400, 0x6bacdef7
-0,         12,         12,        1,   518400, 0x4a00715f
-0,         13,         13,        1,   518400, 0x59b98727
-0,         14,         14,        1,   518400, 0xbf912ee1
-0,         15,         15,        1,   518400, 0x8c966cd6
-0,         16,         16,        1,   518400, 0x2c9a2535
-0,         17,         17,        1,   518400, 0x29085c06
-0,         18,         18,        1,   518400, 0x46ae6b7d
-0,         19,         19,        1,   518400, 0x283100f4
-0,         20,         20,        1,   518400, 0x2731b5ff
-0,         21,         21,        1,   518400, 0x1132ea54
-0,         22,         22,        1,   518400, 0x37cbe539
-0,         23,         23,        1,   518400, 0x08ff75cf
-0,         24,         24,        1,   518400, 0xafb6bc45
-0,         25,         25,        1,   518400, 0x19d3873d
-0,         26,         26,        1,   518400, 0xd494a8be
-0,         27,         27,        1,   518400, 0x285f41ef
-0,         28,         28,        1,   518400, 0xd4b1ffa1
-0,         29,         29,        1,   518400, 0xc3876c3a
-0,         30,         30,        1,   518400, 0xb73dbb62
+0,          2,          2,        1,   518400, 0x1480849d
+0,          3,          3,        1,   518400, 0x0e69ff59
+0,          4,          4,        1,   518400, 0x00d6db06
+0,          5,          5,        1,   518400, 0x1a5b6a69
+0,          6,          6,        1,   518400, 0xc1a1232e
+0,          7,          7,        1,   518400, 0x9a4e3c54
+0,          8,          8,        1,   518400, 0x04122b44
+0,          9,          9,        1,   518400, 0x0fcfeebc
+0,         10,         10,        1,   518400, 0xc7882dc1
+0,         11,         11,        1,   518400, 0x9d79df09
+0,         12,         12,        1,   518400, 0xff6b716f
+0,         13,         13,        1,   518400, 0x638a8746
+0,         14,         14,        1,   518400, 0x07572efb
+0,         15,         15,        1,   518400, 0x306f6cef
+0,         16,         16,        1,   518400, 0xd7602518
+0,         17,         17,        1,   518400, 0x49ab5bf5
+0,         18,         18,        1,   518400, 0x3c736b6c
+0,         19,         19,        1,   518400, 0x95ae00c9
+0,         20,         20,        1,   518400, 0x7b9ab64e
+0,         21,         21,        1,   518400, 0x5205ea68
+0,         22,         22,        1,   518400, 0xb486e618
+0,         23,         23,        1,   518400, 0xa3217616
+0,         24,         24,        1,   518400, 0xc66bbc56
+0,         25,         25,        1,   518400, 0xf024872a
+0,         26,         26,        1,   518400, 0x97d2a8ba
+0,         27,         27,        1,   518400, 0xa3a2418e
+0,         28,         28,        1,   518400, 0x08460005
+0,         29,         29,        1,   518400, 0x50fb6c94
+0,         30,         30,        1,   518400, 0x5584bb40
diff --git a/tests/ref/fate/vima b/tests/ref/fate/vima
new file mode 100644
index 0000000..6984c5d
--- /dev/null
+++ b/tests/ref/fate/vima
@@ -0,0 +1,17 @@
+#tb 0: 1/22050
+0,          0,          0,    73500,   294000, 0x37d439ee
+0,      73500,      73500,     1470,     5880, 0xe524b177
+0,      74970,      74970,     1470,     5880, 0x9e784af1
+0,      76440,      76440,     1470,     5880, 0x821989b0
+0,      77910,      77910,     1470,     5880, 0x8f4993da
+0,      79380,      79380,     1470,     5880, 0x889a9035
+0,      80850,      80850,     1470,     5880, 0x7f0f5299
+0,      82320,      82320,     1470,     5880, 0xf12f5d2a
+0,      83790,      83790,     1470,     5880, 0xd6292fda
+0,      85260,      85260,     1470,     5880, 0xe1b8405f
+0,      86730,      86730,     1470,     5880, 0xe23d2d44
+0,      88200,      88200,     1470,     5880, 0xe20631a4
+0,      89670,      89670,     1470,     5880, 0x3f72210f
+0,      91140,      91140,     1470,     5880, 0xec0b3fe8
+0,      92610,      92610,     1470,     5880, 0x9615f198
+0,      94080,      94080,     1470,     5880, 0x500226ce
diff --git a/tests/ref/fate/vmnc-16bit b/tests/ref/fate/vmnc-16bit
index 2a1848e..064b7fa 100644
--- a/tests/ref/fate/vmnc-16bit
+++ b/tests/ref/fate/vmnc-16bit
@@ -1,193 +1,193 @@
 #tb 0: 1/5
-0,          0,          0,        1,   864000, 0x9b1cee65
-0,          1,          1,        1,   864000, 0x82950e3f
-0,          2,          2,        1,   864000, 0x335f9678
-0,          3,          3,        1,   864000, 0x6b86b7e7
-0,          4,          4,        1,   864000, 0x25618cf2
-0,          5,          5,        1,   864000, 0xed2196c9
-0,          6,          6,        1,   864000, 0xbeaa31ba
-0,          7,          7,        1,   864000, 0x14e6c8ab
-0,          8,          8,        1,   864000, 0x17e5c196
-0,          9,          9,        1,   864000, 0x4aa15110
-0,         10,         10,        1,   864000, 0x4aa15110
-0,         11,         11,        1,   864000, 0x4aa15110
-0,         12,         12,        1,   864000, 0x3c2d3809
-0,         13,         13,        1,   864000, 0xd075f4d0
-0,         14,         14,        1,   864000, 0x0c3f2833
-0,         15,         15,        1,   864000, 0xe7471872
-0,         16,         16,        1,   864000, 0x4300b71d
-0,         17,         17,        1,   864000, 0x6b5844ec
-0,         18,         18,        1,   864000, 0xb3ebc395
-0,         19,         19,        1,   864000, 0x39aa8a7d
-0,         20,         20,        1,   864000, 0x52a3d93d
-0,         21,         21,        1,   864000, 0x73adbdac
-0,         22,         22,        1,   864000, 0xa9fd6cdc
-0,         23,         23,        1,   864000, 0x4a085344
-0,         24,         24,        1,   864000, 0xc21b943c
-0,         25,         25,        1,   864000, 0xfaef6ed4
-0,         26,         26,        1,   864000, 0xa3e9163c
-0,         27,         27,        1,   864000, 0x917e2be4
-0,         28,         28,        1,   864000, 0x2d89d534
-0,         29,         29,        1,   864000, 0x6fe5a9e4
-0,         30,         30,        1,   864000, 0x71af29ec
-0,         31,         31,        1,   864000, 0x8f33f6ad
-0,         32,         32,        1,   864000, 0xe7d46a24
-0,         33,         33,        1,   864000, 0xb631e044
-0,         34,         34,        1,   864000, 0x77db01cb
-0,         35,         35,        1,   864000, 0x9861b6ec
-0,         36,         36,        1,   864000, 0x973bd263
-0,         37,         37,        1,   864000, 0xdd4c175b
-0,         38,         38,        1,   864000, 0xdc28469b
-0,         39,         39,        1,   864000, 0x67393ebb
-0,         40,         40,        1,   864000, 0x01a06813
-0,         41,         41,        1,   864000, 0x63e88f73
-0,         42,         42,        1,   864000, 0x3ffbdd73
-0,         43,         43,        1,   864000, 0xd25f790b
-0,         44,         44,        1,   864000, 0x14e3c5d3
-0,         45,         45,        1,   864000, 0x0d3d1202
-0,         46,         46,        1,   864000, 0x69decf03
-0,         47,         47,        1,   864000, 0x1b20ab93
-0,         48,         48,        1,   864000, 0xee2f8d4a
-0,         49,         49,        1,   864000, 0xaac44c52
-0,         50,         50,        1,   864000, 0x3f874a5a
-0,         51,         51,        1,   864000, 0x239b2d7a
-0,         52,         52,        1,   864000, 0xb85db552
-0,         53,         53,        1,   864000, 0xb12962a2
-0,         54,         54,        1,   864000, 0xb8270fd9
-0,         55,         55,        1,   864000, 0x14930601
-0,         56,         56,        1,   864000, 0x827a15c1
-0,         57,         57,        1,   864000, 0xe31011d1
-0,         58,         58,        1,   864000, 0xcd2154c1
-0,         59,         59,        1,   864000, 0xad02dbd9
-0,         60,         60,        1,   864000, 0x40c17d58
-0,         61,         61,        1,   864000, 0x8219e3b9
-0,         62,         62,        1,   864000, 0x2d348340
-0,         63,         63,        1,   864000, 0x6b61dfc9
-0,         64,         64,        1,   864000, 0xc8d95be1
-0,         65,         65,        1,   864000, 0x70ba0918
-0,         66,         66,        1,   864000, 0xdc728131
-0,         67,         67,        1,   864000, 0x9b054a10
-0,         68,         68,        1,   864000, 0x3983f751
-0,         69,         69,        1,   864000, 0x325fe1a9
-0,         70,         70,        1,   864000, 0x7a41eac0
-0,         71,         71,        1,   864000, 0x324372a8
-0,         72,         72,        1,   864000, 0xc014ea18
-0,         73,         73,        1,   864000, 0x1a506a1f
-0,         74,         74,        1,   864000, 0x47b59557
-0,         75,         75,        1,   864000, 0x5f2e194f
-0,         76,         76,        1,   864000, 0x9f6abb68
-0,         77,         77,        1,   864000, 0x831d2b97
-0,         78,         78,        1,   864000, 0x0635af7f
-0,         79,         79,        1,   864000, 0xe54a5626
-0,         80,         80,        1,   864000, 0x704dca4f
-0,         81,         81,        1,   864000, 0x47de6676
-0,         82,         82,        1,   864000, 0x609705fd
-0,         83,         83,        1,   864000, 0x8d92e086
-0,         84,         84,        1,   864000, 0xdb7dab5e
-0,         85,         85,        1,   864000, 0xe6ccb686
-0,         86,         86,        1,   864000, 0x0d137f66
-0,         87,         87,        1,   864000, 0xd200035d
-0,         88,         88,        1,   864000, 0x7dcb959d
-0,         89,         89,        1,   864000, 0xee849f75
-0,         90,         90,        1,   864000, 0x89d14acd
-0,         91,         91,        1,   864000, 0x3738029d
-0,         92,         92,        1,   864000, 0x6f4c4395
-0,         93,         93,        1,   864000, 0x06334395
-0,         94,         94,        1,   864000, 0x238b7c94
-0,         95,         95,        1,   864000, 0xfa5d1e14
-0,         96,         96,        1,   864000, 0x50b10e54
-0,         97,         97,        1,   864000, 0x9ed3b6e4
-0,         98,         98,        1,   864000, 0x68da9374
-0,         99,         99,        1,   864000, 0xb32a137c
-0,        100,        100,        1,   864000, 0x577d5084
-0,        101,        101,        1,   864000, 0xd262176b
-0,        102,        102,        1,   864000, 0xf58b44b3
-0,        103,        103,        1,   864000, 0xd0828edc
-0,        104,        104,        1,   864000, 0xc91a7544
-0,        105,        105,        1,   864000, 0x18ae7f1c
-0,        106,        106,        1,   864000, 0x82623643
-0,        107,        107,        1,   864000, 0x9cf82cfb
-0,        108,        108,        1,   864000, 0x93ad116b
-0,        109,        109,        1,   864000, 0xa669044b
-0,        110,        110,        1,   864000, 0x8adf88c3
-0,        111,        111,        1,   864000, 0xb83fb413
-0,        112,        112,        1,   864000, 0xb9e291f3
-0,        113,        113,        1,   864000, 0x5833dcc3
-0,        114,        114,        1,   864000, 0x4ab825aa
-0,        115,        115,        1,   864000, 0xb52c3b53
-0,        116,        116,        1,   864000, 0x0cb0dd53
-0,        117,        117,        1,   864000, 0x98b8dd52
-0,        118,        118,        1,   864000, 0x989230ba
-0,        119,        119,        1,   864000, 0xaed4c073
-0,        120,        120,        1,   864000, 0x76a7c83a
-0,        121,        121,        1,   864000, 0x02711eea
-0,        122,        122,        1,   864000, 0x8de65fe2
-0,        123,        123,        1,   864000, 0xc1163689
-0,        124,        124,        1,   864000, 0xc04f8b31
-0,        125,        125,        1,   864000, 0x69218d2a
-0,        126,        126,        1,   864000, 0x7e3abe62
-0,        127,        127,        1,   864000, 0x00ebe27a
-0,        128,        128,        1,   864000, 0x34803f11
-0,        129,        129,        1,   864000, 0x85591cd9
-0,        130,        130,        1,   864000, 0x8422fb51
-0,        131,        131,        1,   864000, 0x67c759e1
-0,        132,        132,        1,   864000, 0x4ac36af1
-0,        133,        133,        1,   864000, 0xdf00fca2
-0,        134,        134,        1,   864000, 0x74c633d1
-0,        135,        135,        1,   864000, 0x00251c31
-0,        136,        136,        1,   864000, 0x6d12a499
-0,        137,        137,        1,   864000, 0x1b6492e1
-0,        138,        138,        1,   864000, 0xdfc9a2a1
-0,        139,        139,        1,   864000, 0x33dcac79
-0,        140,        140,        1,   864000, 0x2305a499
-0,        141,        141,        1,   864000, 0xe1f3ae71
-0,        142,        142,        1,   864000, 0xc0cc92e1
-0,        143,        143,        1,   864000, 0x53d3b261
-0,        144,        144,        1,   864000, 0xf953aa81
-0,        145,        145,        1,   864000, 0x4108da69
-0,        146,        146,        1,   864000, 0xd6acf9e9
-0,        147,        147,        1,   864000, 0xb97ed900
-0,        148,        148,        1,   864000, 0x1d8b7a80
-0,        149,        149,        1,   864000, 0xd5406cb8
-0,        150,        150,        1,   864000, 0x5aa34948
-0,        151,        151,        1,   864000, 0x328eee01
-0,        152,        152,        1,   864000, 0xac92e621
-0,        153,        153,        1,   864000, 0x4fa1f5e1
-0,        154,        154,        1,   864000, 0xf7c4e8a8
-0,        155,        155,        1,   864000, 0xc358bd58
-0,        156,        156,        1,   864000, 0x29ec4b27
-0,        157,        157,        1,   864000, 0xf7219c88
-0,        158,        158,        1,   864000, 0xe77ff130
-0,        159,        159,        1,   864000, 0x73683417
-0,        160,        160,        1,   864000, 0x08b6be77
-0,        161,        161,        1,   864000, 0x3a7eea6f
-0,        162,        162,        1,   864000, 0xb319cce7
-0,        163,        163,        1,   864000, 0x9607b13e
-0,        164,        164,        1,   864000, 0x30543f0d
-0,        165,        165,        1,   864000, 0x56915a9e
-0,        166,        166,        1,   864000, 0x79f158a6
-0,        167,        167,        1,   864000, 0x498b8bd6
-0,        168,        168,        1,   864000, 0xe9ad7046
-0,        169,        169,        1,   864000, 0xe9ad7046
-0,        170,        170,        1,   864000, 0x10317e0e
-0,        171,        171,        1,   864000, 0x10317e0e
-0,        172,        172,        1,   864000, 0x10317e0e
-0,        173,        173,        1,   864000, 0x99ec7046
-0,        174,        174,        1,   864000, 0x924d46ee
-0,        175,        175,        1,   864000, 0x98bf333e
-0,        176,        176,        1,   864000, 0xb2625c96
-0,        177,        177,        1,   864000, 0xb46b3926
-0,        178,        178,        1,   864000, 0xeb4e5c96
-0,        179,        179,        1,   864000, 0x87154ece
-0,        180,        180,        1,   864000, 0x9e4c666e
-0,        181,        181,        1,   864000, 0x65b53d16
-0,        182,        182,        1,   864000, 0x99e85e8e
-0,        183,        183,        1,   864000, 0x650ba17e
-0,        184,        184,        1,   864000, 0x1ecb000e
-0,        185,        185,        1,   864000, 0xb942327d
-0,        186,        186,        1,   864000, 0x1bf20925
-0,        187,        187,        1,   864000, 0x61dba6a5
-0,        188,        188,        1,   864000, 0x5de16d8d
-0,        189,        189,        1,   864000, 0x4eb1f75d
-0,        190,        190,        1,   864000, 0x4eb1f75d
-0,        191,        191,        1,   864000, 0xd0750144
+0,          0,          0,        1,   864000, 0xd6929ea7
+0,          1,          1,        1,   864000, 0x9d5283fa
+0,          2,          2,        1,   864000, 0xcec52d42
+0,          3,          3,        1,   864000, 0x34d5943e
+0,          4,          4,        1,   864000, 0x5bd0b2a8
+0,          5,          5,        1,   864000, 0x41f1c468
+0,          6,          6,        1,   864000, 0x16aa54b9
+0,          7,          7,        1,   864000, 0xdb92e88a
+0,          8,          8,        1,   864000, 0x0ae5d695
+0,          9,          9,        1,   864000, 0x2c338d33
+0,         10,         10,        1,   864000, 0x2c338d33
+0,         11,         11,        1,   864000, 0x2c338d33
+0,         12,         12,        1,   864000, 0xd9c1152f
+0,         13,         13,        1,   864000, 0x9833bf29
+0,         14,         14,        1,   864000, 0xbedbe1bc
+0,         15,         15,        1,   864000, 0xd137d921
+0,         16,         16,        1,   864000, 0xcb0f967a
+0,         17,         17,        1,   864000, 0x931a2881
+0,         18,         18,        1,   864000, 0xeb8ca351
+0,         19,         19,        1,   864000, 0xe2f66886
+0,         20,         20,        1,   864000, 0xb81fb99e
+0,         21,         21,        1,   864000, 0x2048a4d9
+0,         22,         22,        1,   864000, 0x145b514f
+0,         23,         23,        1,   864000, 0xcb6236f4
+0,         24,         24,        1,   864000, 0x6d2d79db
+0,         25,         25,        1,   864000, 0xadca5356
+0,         26,         26,        1,   864000, 0x5d51f80c
+0,         27,         27,        1,   864000, 0x9e240e68
+0,         28,         28,        1,   864000, 0xcafcbcc2
+0,         29,         29,        1,   864000, 0x76f99028
+0,         30,         30,        1,   864000, 0xd7450c61
+0,         31,         31,        1,   864000, 0x1431d79c
+0,         32,         32,        1,   864000, 0x081a4e30
+0,         33,         33,        1,   864000, 0x0437c7d4
+0,         34,         34,        1,   864000, 0xb4bbea4b
+0,         35,         35,        1,   864000, 0x0a149d41
+0,         36,         36,        1,   864000, 0xf7dbc0d5
+0,         37,         37,        1,   864000, 0x6933003c
+0,         38,         38,        1,   864000, 0x18ce30e4
+0,         39,         39,        1,   864000, 0x8c8728c8
+0,         40,         40,        1,   864000, 0x37b6535b
+0,         41,         41,        1,   864000, 0xcdab7be7
+0,         42,         42,        1,   864000, 0xe1e1cbe7
+0,         43,         43,        1,   864000, 0x1d476482
+0,         44,         44,        1,   864000, 0x0ae0b393
+0,         45,         45,        1,   864000, 0x49140206
+0,         46,         46,        1,   864000, 0xe9f9bd09
+0,         47,         47,        1,   864000, 0x89a7988b
+0,         48,         48,        1,   864000, 0x24f780a7
+0,         49,         49,        1,   864000, 0x88a53dc0
+0,         50,         50,        1,   864000, 0x27ed3bb9
+0,         51,         51,        1,   864000, 0xc8151dfd
+0,         52,         52,        1,   864000, 0xfcb8a9e0
+0,         53,         53,        1,   864000, 0xd6d554ba
+0,         54,         54,        1,   864000, 0xbc6e06c6
+0,         55,         55,        1,   864000, 0x6334fc94
+0,         56,         56,        1,   864000, 0x7a7e0cdb
+0,         57,         57,        1,   864000, 0xf96008cd
+0,         58,         58,        1,   864000, 0xffbc4dbb
+0,         59,         59,        1,   864000, 0x1071d886
+0,         60,         60,        1,   864000, 0x6b967ed3
+0,         61,         61,        1,   864000, 0xd370e0a2
+0,         62,         62,        1,   864000, 0x4cca84e8
+0,         63,         63,        1,   864000, 0xd46bdc94
+0,         64,         64,        1,   864000, 0x102a54bf
+0,         65,         65,        1,   864000, 0xe39406cb
+0,         66,         66,        1,   864000, 0x9bb07ad9
+0,         67,         67,        1,   864000, 0xd3b749b2
+0,         68,         68,        1,   864000, 0x59faf47d
+0,         69,         69,        1,   864000, 0xba38de30
+0,         70,         70,        1,   864000, 0x7084eed8
+0,         71,         71,        1,   864000, 0xa966732d
+0,         72,         72,        1,   864000, 0xb9f1ee2b
+0,         73,         73,        1,   864000, 0x09267201
+0,         74,         74,        1,   864000, 0xc6b09e30
+0,         75,         75,        1,   864000, 0x080d1e77
+0,         76,         76,        1,   864000, 0xe28bbdc5
+0,         77,         77,        1,   864000, 0x230a30f8
+0,         78,         78,        1,   864000, 0x4d0bb8cd
+0,         79,         79,        1,   864000, 0x96096417
+0,         80,         80,        1,   864000, 0x7467d417
+0,         81,         81,        1,   864000, 0xbcc07491
+0,         82,         82,        1,   864000, 0x794718d7
+0,         83,         83,        1,   864000, 0xf23ff243
+0,         84,         84,        1,   864000, 0x9961bb86
+0,         85,         85,        1,   864000, 0x7be4c703
+0,         86,         86,        1,   864000, 0x727f8e3f
+0,         87,         87,        1,   864000, 0xda421623
+0,         88,         88,        1,   864000, 0xca69ac6b
+0,         89,         89,        1,   864000, 0x67aeb68e
+0,         90,         90,        1,   864000, 0x3b665f61
+0,         91,         91,        1,   864000, 0x3716150b
+0,         92,         92,        1,   864000, 0x2dcd57f2
+0,         93,         93,        1,   864000, 0x800257f2
+0,         94,         94,        1,   864000, 0x10de99ef
+0,         95,         95,        1,   864000, 0x3438389f
+0,         96,         96,        1,   864000, 0x42682867
+0,         97,         97,        1,   864000, 0x9d64d5a9
+0,         98,         98,        1,   864000, 0x9e2eb12b
+0,         99,         99,        1,   864000, 0xb9f42d64
+0,        100,        100,        1,   864000, 0xd6f36c3d
+0,        101,        101,        1,   864000, 0xfeaa390f
+0,        102,        102,        1,   864000, 0x3fe067b0
+0,        103,        103,        1,   864000, 0x45ebac70
+0,        104,        104,        1,   864000, 0xabfb9215
+0,        105,        105,        1,   864000, 0x20f79c38
+0,        106,        106,        1,   864000, 0x326858d2
+0,        107,        107,        1,   864000, 0x67154ef1
+0,        108,        108,        1,   864000, 0x2b3d328f
+0,        109,        109,        1,   864000, 0x8190250b
+0,        110,        110,        1,   864000, 0x31dead22
+0,        111,        111,        1,   864000, 0xa9b8d9bc
+0,        112,        112,        1,   864000, 0x330db698
+0,        113,        113,        1,   864000, 0x0ff803b1
+0,        114,        114,        1,   864000, 0xb7614eb4
+0,        115,        115,        1,   864000, 0x12c75d64
+0,        116,        116,        1,   864000, 0x622c03f3
+0,        117,        117,        1,   864000, 0x0ace0b90
+0,        118,        118,        1,   864000, 0x2c2b59c6
+0,        119,        119,        1,   864000, 0xadbbe628
+0,        120,        120,        1,   864000, 0x1371f576
+0,        121,        121,        1,   864000, 0x066a471c
+0,        122,        122,        1,   864000, 0x0e6f8a03
+0,        123,        123,        1,   864000, 0x4325670d
+0,        124,        124,        1,   864000, 0x2e8abe3a
+0,        125,        125,        1,   864000, 0x0ea8b8a4
+0,        126,        126,        1,   864000, 0x65e4eb53
+0,        127,        127,        1,   864000, 0xa03d108d
+0,        128,        128,        1,   864000, 0xd3d56fd6
+0,        129,        129,        1,   864000, 0x1b8e4c47
+0,        130,        130,        1,   864000, 0x5bd0316d
+0,        131,        131,        1,   864000, 0x49478b20
+0,        132,        132,        1,   864000, 0x3dae9cb2
+0,        133,        133,        1,   864000, 0x671e2b2a
+0,        134,        134,        1,   864000, 0x521763ee
+0,        135,        135,        1,   864000, 0x73dc4b9a
+0,        136,        136,        1,   864000, 0x3c95d7bf
+0,        137,        137,        1,   864000, 0x3abdc580
+0,        138,        138,        1,   864000, 0xae24d5b8
+0,        139,        139,        1,   864000, 0xe630dfdb
+0,        140,        140,        1,   864000, 0x229ad7bf
+0,        141,        141,        1,   864000, 0x3372e1e2
+0,        142,        142,        1,   864000, 0xa821c580
+0,        143,        143,        1,   864000, 0x7c78e5f0
+0,        144,        144,        1,   864000, 0x3324ddd4
+0,        145,        145,        1,   864000, 0x98580f38
+0,        146,        146,        1,   864000, 0x14072fa8
+0,        147,        147,        1,   864000, 0xdbb21510
+0,        148,        148,        1,   864000, 0x6a55b3b1
+0,        149,        149,        1,   864000, 0x7b5ba580
+0,        150,        150,        1,   864000, 0x2f5e8102
+0,        151,        151,        1,   864000, 0x691e2313
+0,        152,        152,        1,   864000, 0x423b1af7
+0,        153,        153,        1,   864000, 0x02842b2f
+0,        154,        154,        1,   864000, 0x8a4e24dd
+0,        155,        155,        1,   864000, 0xbbebf834
+0,        156,        156,        1,   864000, 0x0ba68a3b
+0,        157,        157,        1,   864000, 0x6390d66a
+0,        158,        158,        1,   864000, 0x6ee32da6
+0,        159,        159,        1,   864000, 0xace87229
+0,        160,        160,        1,   864000, 0xb2a10064
+0,        161,        161,        1,   864000, 0x9cc42dab
+0,        162,        162,        1,   864000, 0x32eb0f42
+0,        163,        163,        1,   864000, 0x6cb1fa03
+0,        164,        164,        1,   864000, 0xddd28c0a
+0,        165,        165,        1,   864000, 0xae5ca0cf
+0,        166,        166,        1,   864000, 0x4cb99ec8
+0,        167,        167,        1,   864000, 0xdad7d37e
+0,        168,        168,        1,   864000, 0x7090b71c
+0,        169,        169,        1,   864000, 0x7090b71c
+0,        170,        170,        1,   864000, 0x96a4c54d
+0,        171,        171,        1,   864000, 0x96a4c54d
+0,        172,        172,        1,   864000, 0x96a4c54d
+0,        173,        173,        1,   864000, 0xc47eb71c
+0,        174,        174,        1,   864000, 0xcd678c89
+0,        175,        175,        1,   864000, 0xb89e7843
+0,        176,        176,        1,   864000, 0x7f3aa2d6
+0,        177,        177,        1,   864000, 0xffc57e58
+0,        178,        178,        1,   864000, 0x091fa2d6
+0,        179,        179,        1,   864000, 0x3bc994a5
+0,        180,        180,        1,   864000, 0x73afacf9
+0,        181,        181,        1,   864000, 0x628b8266
+0,        182,        182,        1,   864000, 0xe2f2a4dd
+0,        183,        183,        1,   864000, 0x7118e9cb
+0,        184,        184,        1,   864000, 0x65b1438d
+0,        185,        185,        1,   864000, 0x51657ec8
+0,        186,        186,        1,   864000, 0x41a75435
+0,        187,        187,        1,   864000, 0xe387f665
+0,        188,        188,        1,   864000, 0x2baabb9a
+0,        189,        189,        1,   864000, 0xd2d74993
+0,        190,        190,        1,   864000, 0xd2d74993
+0,        191,        191,        1,   864000, 0xa7bf53b6
diff --git a/tests/ref/fate/vp3-coeff-level64 b/tests/ref/fate/vp3-coeff-level64
index d6abb62..4bfafaf 100644
--- a/tests/ref/fate/vp3-coeff-level64
+++ b/tests/ref/fate/vp3-coeff-level64
@@ -1,9 +1,9 @@
-#tb 0: 1/1000
-0,          0,          0,        0,  4617600, 0x4ba6df50
-0,         66,         66,        0,  4617600, 0x419fdeaf
-0,        132,        132,        0,  4617600, 0xeb2edced
-0,        198,        198,        0,  4617600, 0xa2bb3a1a
-0,        264,        264,        0,  4617600, 0x411cfb36
-0,        330,        330,        0,  4617600, 0xb2dc22ed
-0,        396,        396,        0,  4617600, 0x236d23b5
-0,        462,        462,        0,  4617600, 0x7fef275e
+#tb 0: 1/15
+0,          0,          0,        1,  4617600, 0x4ba6df50
+0,          1,          1,        1,  4617600, 0x419fdeaf
+0,          2,          2,        1,  4617600, 0xeb2edced
+0,          3,          3,        1,  4617600, 0xa2bb3a1a
+0,          4,          4,        1,  4617600, 0x411cfb36
+0,          5,          5,        1,  4617600, 0xb2dc22ed
+0,          6,          6,        1,  4617600, 0x236d23b5
+0,          7,          7,        1,  4617600, 0x7fef275e
diff --git a/tests/ref/fate/vp5 b/tests/ref/fate/vp5
index 791fe60..0e601ba 100644
--- a/tests/ref/fate/vp5
+++ b/tests/ref/fate/vp5
@@ -245,3 +245,4 @@
 0,        243,        243,        1,   233472, 0x6f530ac6
 0,        244,        244,        1,   233472, 0x94f7466c
 0,        245,        245,        1,   233472, 0xa8c1d365
+0,        246,        246,        1,   233472, 0xedcff050
diff --git a/tests/ref/fate/vp60 b/tests/ref/fate/vp60
index 5e4b62c..c1da72b 100644
--- a/tests/ref/fate/vp60
+++ b/tests/ref/fate/vp60
@@ -6,8 +6,8 @@
 0,          4,          4,        1,    55296, 0x17720594
 0,          5,          5,        1,    55296, 0x49440805
 0,          6,          6,        1,    55296, 0x5b2e0d32
-0,          7,          7,        1,    55296, 0x207891c1
-0,          8,          8,        1,    55296, 0x502da4cd
+0,          7,          7,        1,    55296, 0x5cf691c3
+0,          8,          8,        1,    55296, 0x61a5a4c8
 0,          9,          9,        1,    55296, 0x75a22a75
 0,         10,         10,        1,    55296, 0xd55099af
 0,         11,         11,        1,    55296, 0x48778bb6
@@ -16,85 +16,85 @@
 0,         14,         14,        1,    55296, 0xc83d9b90
 0,         15,         15,        1,    55296, 0x567877b8
 0,         16,         16,        1,    55296, 0x334c7f6e
-0,         17,         17,        1,    55296, 0x8717945c
-0,         18,         18,        1,    55296, 0xe432831e
-0,         19,         19,        1,    55296, 0x032e8d2d
+0,         17,         17,        1,    55296, 0x9317945c
+0,         18,         18,        1,    55296, 0xf032831e
+0,         19,         19,        1,    55296, 0x7b6c8d2c
 0,         20,         20,        1,    55296, 0x37109fd6
 0,         21,         21,        1,    55296, 0xe9b0b61b
 0,         22,         22,        1,    55296, 0x7385dae8
-0,         23,         23,        1,    55296, 0x74b8a9f5
-0,         24,         24,        1,    55296, 0xbce2e218
-0,         25,         25,        1,    55296, 0x0ab6c623
-0,         26,         26,        1,    55296, 0x2234d6d6
-0,         27,         27,        1,    55296, 0xd18be4d6
-0,         28,         28,        1,    55296, 0x5247ecc9
-0,         29,         29,        1,    55296, 0xc89f10ca
-0,         30,         30,        1,    55296, 0x16181f87
-0,         31,         31,        1,    55296, 0x893bfa85
-0,         32,         32,        1,    55296, 0x1fd9f1c0
-0,         33,         33,        1,    55296, 0xa2e8e6a9
-0,         34,         34,        1,    55296, 0x1b42dfd5
-0,         35,         35,        1,    55296, 0x0fa9f509
-0,         36,         36,        1,    55296, 0x4449c216
-0,         37,         37,        1,    55296, 0xb66baa36
-0,         38,         38,        1,    55296, 0x38c19f3b
-0,         39,         39,        1,    55296, 0xcdce83a0
+0,         23,         23,        1,    55296, 0x74a8a9f5
+0,         24,         24,        1,    55296, 0xbcd2e218
+0,         25,         25,        1,    55296, 0x0aa6c623
+0,         26,         26,        1,    55296, 0x2224d6d6
+0,         27,         27,        1,    55296, 0x8c8ee4d9
+0,         28,         28,        1,    55296, 0x0d4ceccc
+0,         29,         29,        1,    55296, 0x623f10c7
+0,         30,         30,        1,    55296, 0x13a61f8f
+0,         31,         31,        1,    55296, 0x5343fa8d
+0,         32,         32,        1,    55296, 0x21fef1b5
+0,         33,         33,        1,    55296, 0x380de6b4
+0,         34,         34,        1,    55296, 0x04bedfd3
+0,         35,         35,        1,    55296, 0x428cf510
+0,         36,         36,        1,    55296, 0xbca8c214
+0,         37,         37,        1,    55296, 0x947faa34
+0,         38,         38,        1,    55296, 0x70769f45
+0,         39,         39,        1,    55296, 0xcb9483ad
 0,         40,         40,        1,    55296, 0xac4ea82b
-0,         41,         41,        1,    55296, 0xb77a6979
-0,         42,         42,        1,    55296, 0xc8834ec2
-0,         43,         43,        1,    55296, 0x181d3f0f
-0,         44,         44,        1,    55296, 0x2ae04252
-0,         45,         45,        1,    55296, 0x07633c18
-0,         46,         46,        1,    55296, 0xdc6a3340
-0,         47,         47,        1,    55296, 0xa456ebb1
-0,         48,         48,        1,    55296, 0xbf7de5e2
-0,         49,         49,        1,    55296, 0x54a1c39b
-0,         50,         50,        1,    55296, 0x08fc9423
-0,         51,         51,        1,    55296, 0x926f968a
-0,         52,         52,        1,    55296, 0x5c908481
-0,         53,         53,        1,    55296, 0x6b257f16
-0,         54,         54,        1,    55296, 0xbaf8658a
-0,         55,         55,        1,    55296, 0x61c957b1
-0,         56,         56,        1,    55296, 0xa6d181ff
-0,         57,         57,        1,    55296, 0xef476e69
-0,         58,         58,        1,    55296, 0x74f72f9a
-0,         59,         59,        1,    55296, 0x3a9328e9
-0,         60,         60,        1,    55296, 0xbe962874
-0,         61,         61,        1,    55296, 0x5f8b58cc
-0,         62,         62,        1,    55296, 0x1e066d22
-0,         63,         63,        1,    55296, 0x9ef72b34
-0,         64,         64,        1,    55296, 0x525c2bb1
-0,         65,         65,        1,    55296, 0x8e5a20a3
-0,         66,         66,        1,    55296, 0x1c6723d0
-0,         67,         67,        1,    55296, 0x2b1023c8
-0,         68,         68,        1,    55296, 0x8f682691
-0,         69,         69,        1,    55296, 0x3a0624f5
+0,         41,         41,        1,    55296, 0xa3816977
+0,         42,         42,        1,    55296, 0xcfd54ec4
+0,         43,         43,        1,    55296, 0x97743f0e
+0,         44,         44,        1,    55296, 0x4cb4424d
+0,         45,         45,        1,    55296, 0x0b503c11
+0,         46,         46,        1,    55296, 0x879f333a
+0,         47,         47,        1,    55296, 0x6ff9eb8f
+0,         48,         48,        1,    55296, 0x7cd6e5af
+0,         49,         49,        1,    55296, 0x44e2c36f
+0,         50,         50,        1,    55296, 0x4e8993fb
+0,         51,         51,        1,    55296, 0xf0bb9664
+0,         52,         52,        1,    55296, 0xde608458
+0,         53,         53,        1,    55296, 0xb3017f01
+0,         54,         54,        1,    55296, 0x2e096579
+0,         55,         55,        1,    55296, 0xd7295790
+0,         56,         56,        1,    55296, 0xc40b81cb
+0,         57,         57,        1,    55296, 0x53a86e41
+0,         58,         58,        1,    55296, 0x74142f89
+0,         59,         59,        1,    55296, 0x2a1428ce
+0,         60,         60,        1,    55296, 0x5d0c2852
+0,         61,         61,        1,    55296, 0x162058a4
+0,         62,         62,        1,    55296, 0x4e8c6ce8
+0,         63,         63,        1,    55296, 0x1d382af2
+0,         64,         64,        1,    55296, 0x35dd2b75
+0,         65,         65,        1,    55296, 0x1e4c205f
+0,         66,         66,        1,    55296, 0x74a22383
+0,         67,         67,        1,    55296, 0x6ddb237d
+0,         68,         68,        1,    55296, 0xd290263b
+0,         69,         69,        1,    55296, 0xc778249f
 0,         70,         70,        1,    55296, 0xbc1046fb
-0,         71,         71,        1,    55296, 0x2859470e
-0,         72,         72,        1,    55296, 0x61d45a12
-0,         73,         73,        1,    55296, 0xa68853b6
-0,         74,         74,        1,    55296, 0x36543ce4
-0,         75,         75,        1,    55296, 0x95b953d4
-0,         76,         76,        1,    55296, 0x804b3c53
-0,         77,         77,        1,    55296, 0x743960f6
-0,         78,         78,        1,    55296, 0x23916b9c
-0,         79,         79,        1,    55296, 0x8f5a59e3
-0,         80,         80,        1,    55296, 0xf1285f83
-0,         81,         81,        1,    55296, 0xde75640f
-0,         82,         82,        1,    55296, 0xde146188
-0,         83,         83,        1,    55296, 0xb5315cc9
+0,         71,         71,        1,    55296, 0xf44d470f
+0,         72,         72,        1,    55296, 0x28d85a11
+0,         73,         73,        1,    55296, 0xa68953b6
+0,         74,         74,        1,    55296, 0x02593ce5
+0,         75,         75,        1,    55296, 0x61be53d5
+0,         76,         76,        1,    55296, 0x4c503c54
+0,         77,         77,        1,    55296, 0x3d3e60f7
+0,         78,         78,        1,    55296, 0xec876b9d
+0,         79,         79,        1,    55296, 0x5b5f59e4
+0,         80,         80,        1,    55296, 0xbd2d5f84
+0,         81,         81,        1,    55296, 0xaa7a6410
+0,         82,         82,        1,    55296, 0xaa196189
+0,         83,         83,        1,    55296, 0x81365cca
 0,         84,         84,        1,    55296, 0xa85f6861
-0,         85,         85,        1,    55296, 0x4fda562f
-0,         86,         86,        1,    55296, 0xa0185863
-0,         87,         87,        1,    55296, 0xe4dc5a5f
-0,         88,         88,        1,    55296, 0x8a2aabb6
-0,         89,         89,        1,    55296, 0x3ba89b4f
-0,         90,         90,        1,    55296, 0x82b07c21
-0,         91,         91,        1,    55296, 0xb7998478
-0,         92,         92,        1,    55296, 0xceca8046
-0,         93,         93,        1,    55296, 0xe652b325
-0,         94,         94,        1,    55296, 0xc26bb607
-0,         95,         95,        1,    55296, 0x40c99200
+0,         85,         85,        1,    55296, 0xcb46562e
+0,         86,         86,        1,    55296, 0x1b935862
+0,         87,         87,        1,    55296, 0x80a45a60
+0,         88,         88,        1,    55296, 0x8e8aabba
+0,         89,         89,        1,    55296, 0x38939b53
+0,         90,         90,        1,    55296, 0x4f397c22
+0,         91,         91,        1,    55296, 0x7d0d8476
+0,         92,         92,        1,    55296, 0x943e8044
+0,         93,         93,        1,    55296, 0xabc6b323
+0,         94,         94,        1,    55296, 0x87dfb605
+0,         95,         95,        1,    55296, 0x5ca89202
 0,         96,         96,        1,    55296, 0x61bc9b27
 0,         97,         97,        1,    55296, 0x1e4baa30
 0,         98,         98,        1,    55296, 0xd8a7adb0
@@ -110,25 +110,25 @@
 0,        108,        108,        1,    55296, 0xe208d626
 0,        109,        109,        1,    55296, 0x28cc0616
 0,        110,        110,        1,    55296, 0xc545179e
-0,        111,        111,        1,    55296, 0xdf9205af
-0,        112,        112,        1,    55296, 0x31d6ed99
-0,        113,        113,        1,    55296, 0x866bf86e
-0,        114,        114,        1,    55296, 0x0490fbd1
-0,        115,        115,        1,    55296, 0xe1102987
-0,        116,        116,        1,    55296, 0x7f860c29
-0,        117,        117,        1,    55296, 0xc3a91f7a
-0,        118,        118,        1,    55296, 0x69641a52
-0,        119,        119,        1,    55296, 0x05b12204
-0,        120,        120,        1,    55296, 0x715b6206
-0,        121,        121,        1,    55296, 0xdcf55139
-0,        122,        122,        1,    55296, 0x1369f746
+0,        111,        111,        1,    55296, 0xd38e05af
+0,        112,        112,        1,    55296, 0x25d6ed99
+0,        113,        113,        1,    55296, 0x7a6bf86e
+0,        114,        114,        1,    55296, 0xbb3bfbcd
+0,        115,        115,        1,    55296, 0x33de2984
+0,        116,        116,        1,    55296, 0xd5b10c27
+0,        117,        117,        1,    55296, 0x19e31f78
+0,        118,        118,        1,    55296, 0xf62f1a4f
+0,        119,        119,        1,    55296, 0x3f792203
+0,        120,        120,        1,    55296, 0xe4ed6202
+0,        121,        121,        1,    55296, 0xee265136
+0,        122,        122,        1,    55296, 0x408af73c
 0,        123,        123,        1,    55296, 0xc1533ef5
-0,        124,        124,        1,    55296, 0xc00ff85f
-0,        125,        125,        1,    55296, 0x4f5f70dc
-0,        126,        126,        1,    55296, 0x85720ccc
-0,        127,        127,        1,    55296, 0xfdff0780
-0,        128,        128,        1,    55296, 0x57ef04ff
-0,        129,        129,        1,    55296, 0xbf94041f
-0,        130,        130,        1,    55296, 0x4cee0392
-0,        131,        131,        1,    55296, 0x80160314
-0,        132,        132,        1,    55296, 0x396802af
+0,        124,        124,        1,    55296, 0xf671f85d
+0,        125,        125,        1,    55296, 0xae2670e0
+0,        126,        126,        1,    55296, 0xe4390cd0
+0,        127,        127,        1,    55296, 0x5cd50784
+0,        128,        128,        1,    55296, 0x05880500
+0,        129,        129,        1,    55296, 0x6d2d0420
+0,        130,        130,        1,    55296, 0xfa780393
+0,        131,        131,        1,    55296, 0x2daf0315
+0,        132,        132,        1,    55296, 0x982f02b3
diff --git a/tests/ref/fate/vp6a b/tests/ref/fate/vp6a
index 6ce8486..1f2ddd9 100644
--- a/tests/ref/fate/vp6a
+++ b/tests/ref/fate/vp6a
@@ -1,94 +1,94 @@
-#tb 0: 1/1000
-0,          0,          0,        0,   135000, 0x9dceed6d
-0,        249,        249,        0,   135000, 0xcb87787f
-0,        499,        499,        0,   135000, 0xdb4361ce
-0,        749,        749,        0,   135000, 0xb8fd81c2
-0,       1000,       1000,        0,   135000, 0xbf86a7af
-0,       1249,       1249,        0,   135000, 0x2e7787e3
-0,       1499,       1499,        0,   135000, 0x6cec6ebd
-0,       1749,       1749,        0,   135000, 0xa4d08c07
-0,       2000,       2000,        0,   135000, 0x1be48faf
-0,       2249,       2249,        0,   135000, 0xf3cd8ede
-0,       2499,       2499,        0,   135000, 0x33ec8a49
-0,       2749,       2749,        0,   135000, 0x11e887ec
-0,       3000,       3000,        0,   135000, 0x3e215c25
-0,       3249,       3249,        0,   135000, 0x1a2cb3f8
-0,       3499,       3499,        0,   135000, 0x7fb0e48a
-0,       3749,       3749,        0,   135000, 0x749f3738
-0,       4000,       4000,        0,   135000, 0x686e78e9
-0,       4249,       4249,        0,   135000, 0x29515bc7
-0,       4499,       4499,        0,   135000, 0x987126bd
-0,       4749,       4749,        0,   135000, 0xdf77bb13
-0,       5000,       5000,        0,   135000, 0x5fb1468a
-0,       5249,       5249,        0,   135000, 0x06ea50ea
-0,       5499,       5499,        0,   135000, 0x7bd9c715
-0,       5749,       5749,        0,   135000, 0xdd6e6831
-0,       6000,       6000,        0,   135000, 0x0ee3760f
-0,       6249,       6249,        0,   135000, 0xc7984dc8
-0,       6499,       6499,        0,   135000, 0x7e385bff
-0,       6749,       6749,        0,   135000, 0xae155ab9
-0,       7000,       7000,        0,   135000, 0xc05ee8f7
-0,       7249,       7249,        0,   135000, 0x93de3392
-0,       7499,       7499,        0,   135000, 0xfe45b38b
-0,       7749,       7749,        0,   135000, 0xeb5ed72c
-0,       8000,       8000,        0,   135000, 0x0794cb57
-0,       8249,       8249,        0,   135000, 0x2578c6e5
-0,       8499,       8499,        0,   135000, 0x78486707
-0,       8749,       8749,        0,   135000, 0x41e1f0e6
-0,       9000,       9000,        0,   135000, 0x4508eb76
-0,       9249,       9249,        0,   135000, 0xd8c087f3
-0,       9499,       9499,        0,   135000, 0x1a8db89a
-0,       9749,       9749,        0,   135000, 0x6dbd90c6
-0,      10000,      10000,        0,   135000, 0x0845e400
-0,      10249,      10249,        0,   135000, 0xe8b02fc2
-0,      10499,      10499,        0,   135000, 0x8007d813
-0,      10749,      10749,        0,   135000, 0xdfb04e69
-0,      11000,      11000,        0,   135000, 0x5746cf71
-0,      11249,      11249,        0,   135000, 0xe510299f
-0,      11499,      11499,        0,   135000, 0xeea0c829
-0,      11749,      11749,        0,   135000, 0x7c0578ab
-0,      12000,      12000,        0,   135000, 0xb1569ce9
-0,      12249,      12249,        0,   135000, 0x6c233986
-0,      12499,      12499,        0,   135000, 0x95b77f3d
-0,      12749,      12749,        0,   135000, 0xfc368d80
-0,      13000,      13000,        0,   135000, 0x5c73b064
-0,      13249,      13249,        0,   135000, 0x2206da8d
-0,      13499,      13499,        0,   135000, 0x62bb599e
-0,      13749,      13749,        0,   135000, 0x15a68991
-0,      14000,      14000,        0,   135000, 0x5f5eb810
-0,      14249,      14249,        0,   135000, 0x85a9634a
-0,      14499,      14499,        0,   135000, 0xf24b5c1a
-0,      14749,      14749,        0,   135000, 0x38034850
-0,      15000,      15000,        0,   135000, 0x48fd3599
-0,      15249,      15249,        0,   135000, 0xb9d62408
-0,      15499,      15499,        0,   135000, 0xaf202a21
-0,      15749,      15749,        0,   135000, 0x341aa582
-0,      16000,      16000,        0,   135000, 0x90cdc9bb
-0,      16249,      16249,        0,   135000, 0x0b52f319
-0,      16499,      16499,        0,   135000, 0xce61aa5e
-0,      16749,      16749,        0,   135000, 0x988acb45
-0,      17000,      17000,        0,   135000, 0xcd353664
-0,      17249,      17249,        0,   135000, 0xa80c8ce9
-0,      17499,      17499,        0,   135000, 0x15dce784
-0,      17749,      17749,        0,   135000, 0x16bd4519
-0,      18000,      18000,        0,   135000, 0x571712f3
-0,      18249,      18249,        0,   135000, 0x6b109f1e
-0,      18499,      18499,        0,   135000, 0x8e4c19aa
-0,      18749,      18749,        0,   135000, 0x4132bd4c
-0,      19000,      19000,        0,   135000, 0x5babafe2
-0,      19249,      19249,        0,   135000, 0xddef6313
-0,      19499,      19499,        0,   135000, 0x76d6b48b
-0,      19749,      19749,        0,   135000, 0x929e7702
-0,      20000,      20000,        0,   135000, 0x33f5e4a1
-0,      20249,      20249,        0,   135000, 0xdb7041bf
-0,      20499,      20499,        0,   135000, 0xbc761e04
-0,      20749,      20749,        0,   135000, 0x0b2a81e6
-0,      21000,      21000,        0,   135000, 0xf6fd20ea
-0,      21249,      21249,        0,   135000, 0x1894a26c
-0,      21499,      21499,        0,   135000, 0xb25e216f
-0,      21749,      21749,        0,   135000, 0x83bb02ee
-0,      22000,      22000,        0,   135000, 0x6952a3c3
-0,      22249,      22249,        0,   135000, 0x372184d6
-0,      22499,      22499,        0,   135000, 0x2ac47afe
-0,      22749,      22749,        0,   135000, 0x14c33a35
-0,      23000,      23000,        0,   135000, 0xdc08470e
+#tb 0: 1/4
+0,          0,          0,        1,   135000, 0x9dceed6d
+0,          1,          1,        1,   135000, 0x47e5778d
+0,          2,          2,        1,   135000, 0x5de36599
+0,          3,          3,        1,   135000, 0x540d8079
+0,          4,          4,        1,   135000, 0xba9ea534
+0,          5,          5,        1,   135000, 0xa75088f8
+0,          6,          6,        1,   135000, 0x7d867559
+0,          7,          7,        1,   135000, 0xcc678fee
+0,          8,          8,        1,   135000, 0x79c590b9
+0,          9,          9,        1,   135000, 0x87789918
+0,         10,         10,        1,   135000, 0xaa939213
+0,         11,         11,        1,   135000, 0x3912916d
+0,         12,         12,        1,   135000, 0x41305d0b
+0,         13,         13,        1,   135000, 0x2686b5dd
+0,         14,         14,        1,   135000, 0xa69ae422
+0,         15,         15,        1,   135000, 0x998a3478
+0,         16,         16,        1,   135000, 0x5842768d
+0,         17,         17,        1,   135000, 0xf6a85b16
+0,         18,         18,        1,   135000, 0x7a5b2708
+0,         19,         19,        1,   135000, 0x8b2abb63
+0,         20,         20,        1,   135000, 0x7dc8468b
+0,         21,         21,        1,   135000, 0x04d85001
+0,         22,         22,        1,   135000, 0x83e3c647
+0,         23,         23,        1,   135000, 0xcddd687e
+0,         24,         24,        1,   135000, 0x818e785e
+0,         25,         25,        1,   135000, 0x3a915080
+0,         26,         26,        1,   135000, 0x953d603d
+0,         27,         27,        1,   135000, 0x79005ebf
+0,         28,         28,        1,   135000, 0x80afec75
+0,         29,         29,        1,   135000, 0xfc8e376b
+0,         30,         30,        1,   135000, 0xf957b7ef
+0,         31,         31,        1,   135000, 0xe878da44
+0,         32,         32,        1,   135000, 0xe68ecca3
+0,         33,         33,        1,   135000, 0x1a2cc7d3
+0,         34,         34,        1,   135000, 0x4f346a69
+0,         35,         35,        1,   135000, 0x7a0cf4ac
+0,         36,         36,        1,   135000, 0x6d4eee7a
+0,         37,         37,        1,   135000, 0xf0688cbd
+0,         38,         38,        1,   135000, 0xca4abbbc
+0,         39,         39,        1,   135000, 0x87669519
+0,         40,         40,        1,   135000, 0xd090e9d7
+0,         41,         41,        1,   135000, 0xd7f536c1
+0,         42,         42,        1,   135000, 0x353ede54
+0,         43,         43,        1,   135000, 0xbc8f5358
+0,         44,         44,        1,   135000, 0xb52cd59a
+0,         45,         45,        1,   135000, 0x0b882eba
+0,         46,         46,        1,   135000, 0xc544cd54
+0,         47,         47,        1,   135000, 0x31ca7e73
+0,         48,         48,        1,   135000, 0xb1569ce9
+0,         49,         49,        1,   135000, 0x8bf4394f
+0,         50,         50,        1,   135000, 0xf413812a
+0,         51,         51,        1,   135000, 0xf2fa90ab
+0,         52,         52,        1,   135000, 0xdcd8b265
+0,         53,         53,        1,   135000, 0xa89cdba1
+0,         54,         54,        1,   135000, 0x212b59a5
+0,         55,         55,        1,   135000, 0x10c589c3
+0,         56,         56,        1,   135000, 0x432ab5b4
+0,         57,         57,        1,   135000, 0x85a9634a
+0,         58,         58,        1,   135000, 0x10db5b87
+0,         59,         59,        1,   135000, 0x583145d9
+0,         60,         60,        1,   135000, 0x7d3a33bd
+0,         61,         61,        1,   135000, 0xcf592423
+0,         62,         62,        1,   135000, 0xb59728e5
+0,         63,         63,        1,   135000, 0x1eeca660
+0,         64,         64,        1,   135000, 0xff7bcc34
+0,         65,         65,        1,   135000, 0x0ef8f271
+0,         66,         66,        1,   135000, 0x8c9ca8ee
+0,         67,         67,        1,   135000, 0x8a7ece34
+0,         68,         68,        1,   135000, 0x7d4c3b5d
+0,         69,         69,        1,   135000, 0x99118f21
+0,         70,         70,        1,   135000, 0xd97fe7e2
+0,         71,         71,        1,   135000, 0xf93842f1
+0,         72,         72,        1,   135000, 0x35c912e8
+0,         73,         73,        1,   135000, 0x14e59e97
+0,         74,         74,        1,   135000, 0x8e4c19aa
+0,         75,         75,        1,   135000, 0x4adfbc53
+0,         76,         76,        1,   135000, 0x0613adde
+0,         77,         77,        1,   135000, 0x8db264ab
+0,         78,         78,        1,   135000, 0x3948b619
+0,         79,         79,        1,   135000, 0x843d7c02
+0,         80,         80,        1,   135000, 0x534fea34
+0,         81,         81,        1,   135000, 0xdb7041bf
+0,         82,         82,        1,   135000, 0xd0ce1cce
+0,         83,         83,        1,   135000, 0x3c008335
+0,         84,         84,        1,   135000, 0xb699208f
+0,         85,         85,        1,   135000, 0xe07da3ca
+0,         86,         86,        1,   135000, 0x26331f41
+0,         87,         87,        1,   135000, 0x4e19fe83
+0,         88,         88,        1,   135000, 0xaa9a9e45
+0,         89,         89,        1,   135000, 0x336b7ed0
+0,         90,         90,        1,   135000, 0xc9bf7611
+0,         91,         91,        1,   135000, 0x14c33a35
+0,         92,         92,        1,   135000, 0xdc08470e
diff --git a/tests/ref/fate/vp6f b/tests/ref/fate/vp6f
index 8795042..edb555d 100644
--- a/tests/ref/fate/vp6f
+++ b/tests/ref/fate/vp6f
@@ -1,175 +1,175 @@
-#tb 0: 1/1000
-0,          0,          0,        0,    13440, 0x7cb0a22f
-0,        100,        100,        0,    13440, 0xdfcea6ba
-0,        200,        200,        0,    13440, 0x59b2a5da
-0,        300,        300,        0,    13440, 0x12f1b2d8
-0,        400,        400,        0,    13440, 0x280fb9f6
-0,        500,        500,        0,    13440, 0x7bace8b3
-0,        600,        600,        0,    13440, 0x4ec91480
-0,        700,        700,        0,    13440, 0xa8010450
-0,        800,        800,        0,    13440, 0x61d8fc46
-0,        900,        900,        0,    13440, 0x242bb24e
-0,       1000,       1000,        0,    13440, 0x88397a36
-0,       1100,       1100,        0,    13440, 0x10e15726
-0,       1200,       1200,        0,    13440, 0x3018438c
-0,       1300,       1300,        0,    13440, 0xbbb94c21
-0,       1400,       1400,        0,    13440, 0xfc3e5e2b
-0,       1500,       1500,        0,    13440, 0xeaa69354
-0,       1600,       1600,        0,    13440, 0x96f1cc01
-0,       1700,       1700,        0,    13440, 0x333fdaff
-0,       1800,       1800,        0,    13440, 0xb5230ed2
-0,       1900,       1900,        0,    13440, 0x59383446
-0,       2000,       2000,        0,    13440, 0x954939e6
-0,       2100,       2100,        0,    13440, 0x53813d2f
-0,       2200,       2200,        0,    13440, 0x3ca53600
-0,       2300,       2300,        0,    13440, 0x7b30227a
-0,       2400,       2400,        0,    13440, 0x5145bbfe
-0,       2500,       2500,        0,    13440, 0xa0979632
-0,       2600,       2600,        0,    13440, 0x08026e21
-0,       2700,       2700,        0,    13440, 0x3f456d1e
-0,       2800,       2800,        0,    13440, 0x7d036b62
-0,       2900,       2900,        0,    13440, 0x508085fb
-0,       3000,       3000,        0,    13440, 0x251dc193
-0,       3100,       3100,        0,    13440, 0xf3121c9b
-0,       3200,       3200,        0,    13440, 0xf5da772e
-0,       3300,       3300,        0,    13440, 0x8179ccf7
-0,       3400,       3400,        0,    13440, 0xd57ceeb3
-0,       3500,       3500,        0,    13440, 0xc8f2169c
-0,       3600,       3600,        0,    13440, 0xbf8296c3
-0,       3700,       3700,        0,    13440, 0xee1927d0
-0,       3800,       3800,        0,    13440, 0xdd84e8d1
-0,       3900,       3900,        0,    13440, 0x7be57be2
-0,       4000,       4000,        0,    13440, 0xae353f91
-0,       4100,       4100,        0,    13440, 0x3ae927f2
-0,       4200,       4200,        0,    13440, 0x417227c6
-0,       4300,       4300,        0,    13440, 0x32572bea
-0,       4400,       4400,        0,    13440, 0x8b9e4839
-0,       4500,       4500,        0,    13440, 0xad669441
-0,       4600,       4600,        0,    13440, 0xc9de99a6
-0,       4700,       4700,        0,    13440, 0xb3ffb88b
-0,       4800,       4800,        0,    13440, 0xb321b8a0
-0,       4900,       4900,        0,    13440, 0x2efdbf53
-0,       5000,       5000,        0,    13440, 0x9b7aa566
-0,       5100,       5100,        0,    13440, 0x563c8d60
-0,       5200,       5200,        0,    13440, 0xe3848ee8
-0,       5300,       5300,        0,    13440, 0xa84b8f1d
-0,       5400,       5400,        0,    13440, 0x52da9f9f
-0,       5500,       5500,        0,    13440, 0x2ed56d97
-0,       5600,       5600,        0,    13440, 0x4e8534c2
-0,       5700,       5700,        0,    13440, 0x318900a6
-0,       5800,       5800,        0,    13440, 0xda96de39
-0,       5900,       5900,        0,    13440, 0xaae7ac0b
-0,       6000,       6000,        0,    13440, 0x7533ad99
-0,       6100,       6100,        0,    13440, 0x4e70c2c9
-0,       6200,       6200,        0,    13440, 0x9ce5e3fa
-0,       6300,       6300,        0,    13440, 0xc788fbbc
-0,       6400,       6400,        0,    13440, 0xd36604a9
-0,       6500,       6500,        0,    13440, 0x246221a4
-0,       6600,       6600,        0,    13440, 0x290c5c2b
-0,       6700,       6700,        0,    13440, 0xde6c68ec
-0,       6800,       6800,        0,    13440, 0x56248dbf
-0,       6900,       6900,        0,    13440, 0x5b898cbd
-0,       7000,       7000,        0,    13440, 0x090574b9
-0,       7100,       7100,        0,    13440, 0x8df2814a
-0,       7200,       7200,        0,    13440, 0xd4a6b285
-0,       7300,       7300,        0,    13440, 0xa016e921
-0,       7400,       7400,        0,    13440, 0x7f93fdc1
-0,       7500,       7500,        0,    13440, 0xfd0dee6f
-0,       7600,       7600,        0,    13440, 0xef04ce0e
-0,       7700,       7700,        0,    13440, 0x7560bee3
-0,       7800,       7800,        0,    13440, 0x5a8cdc85
-0,       7900,       7900,        0,    13440, 0x4788f7bc
-0,       8000,       8000,        0,    13440, 0xc001e34d
-0,       8100,       8100,        0,    13440, 0xc687eb74
-0,       8200,       8200,        0,    13440, 0xbf20feba
-0,       8300,       8300,        0,    13440, 0xd32647a8
-0,       8400,       8400,        0,    13440, 0xe69a955a
-0,       8500,       8500,        0,    13440, 0x1b56951f
-0,       8600,       8600,        0,    13440, 0xd1977378
-0,       8700,       8700,        0,    13440, 0x1620357d
-0,       8800,       8800,        0,    13440, 0x2596116f
-0,       8900,       8900,        0,    13440, 0x7473feca
-0,       9000,       9000,        0,    13440, 0x7f92bb47
-0,       9100,       9100,        0,    13440, 0x6866a683
-0,       9200,       9200,        0,    13440, 0xe9b08d7e
-0,       9300,       9300,        0,    13440, 0xa3fd7546
-0,       9400,       9400,        0,    13440, 0xa4416522
-0,       9500,       9500,        0,    13440, 0xd8f5572e
-0,       9600,       9600,        0,    13440, 0xf5746dbd
-0,       9700,       9700,        0,    13440, 0x256a87c6
-0,       9800,       9800,        0,    13440, 0x722aa2c8
-0,       9900,       9900,        0,    13440, 0xb26de5f5
-0,      10000,      10000,        0,    13440, 0x117f0841
-0,      10100,      10100,        0,    13440, 0xda2d192c
-0,      10200,      10200,        0,    13440, 0xb022442d
-0,      10300,      10300,        0,    13440, 0xbc4044f2
-0,      10400,      10400,        0,    13440, 0x68b330da
-0,      10500,      10500,        0,    13440, 0xc07228cf
-0,      10600,      10600,        0,    13440, 0xaa3f3d44
-0,      10700,      10700,        0,    13440, 0x25867aad
-0,      10800,      10800,        0,    13440, 0xa3ecb432
-0,      10900,      10900,        0,    13440, 0x93ccdcbb
-0,      11000,      11000,        0,    13440, 0x8302fa4f
-0,      11100,      11100,        0,    13440, 0x2f960f33
-0,      11200,      11200,        0,    13440, 0x15d41d14
-0,      11300,      11300,        0,    13440, 0x636529d0
-0,      11400,      11400,        0,    13440, 0x11035be5
-0,      11500,      11500,        0,    13440, 0x9b6e9167
-0,      11600,      11600,        0,    13440, 0x7b01adc7
-0,      11700,      11700,        0,    13440, 0xa237e05d
-0,      11800,      11800,        0,    13440, 0xd2f4f134
-0,      11900,      11900,        0,    13440, 0x2052d368
-0,      12000,      12000,        0,    13440, 0x08f7ae0d
-0,      12100,      12100,        0,    13440, 0xa89185bc
-0,      12200,      12200,        0,    13440, 0xfa628236
-0,      12300,      12300,        0,    13440, 0xdf79848b
-0,      12400,      12400,        0,    13440, 0xd19a906f
-0,      12500,      12500,        0,    13440, 0x219f9324
-0,      12600,      12600,        0,    13440, 0x46509b6d
-0,      12700,      12700,        0,    13440, 0xc5d9a568
-0,      12800,      12800,        0,    13440, 0xb21aaaa8
-0,      12900,      12900,        0,    13440, 0x925a97ed
-0,      13000,      13000,        0,    13440, 0xc5e3557f
-0,      13100,      13100,        0,    13440, 0x7c57155a
-0,      13200,      13200,        0,    13440, 0x6b26d005
-0,      13300,      13300,        0,    13440, 0xfdc7b369
-0,      13400,      13400,        0,    13440, 0x99919fc2
-0,      13500,      13500,        0,    13440, 0xcfe889e4
-0,      13600,      13600,        0,    13440, 0xd1196856
-0,      13700,      13700,        0,    13440, 0xec8348c6
-0,      13800,      13800,        0,    13440, 0x5ede0d9a
-0,      13900,      13900,        0,    13440, 0x198ef66e
-0,      14000,      14000,        0,    13440, 0x62fcefdf
-0,      14100,      14100,        0,    13440, 0x7791f415
-0,      14200,      14200,        0,    13440, 0xfbdb0029
-0,      14300,      14300,        0,    13440, 0xdab12b01
-0,      14400,      14400,        0,    13440, 0x646b2d5f
-0,      14500,      14500,        0,    13440, 0x5410f52e
-0,      14600,      14600,        0,    13440, 0x7186eef8
-0,      14700,      14700,        0,    13440, 0xca251ef6
-0,      14800,      14800,        0,    13440, 0x757c3b43
-0,      14900,      14900,        0,    13440, 0x59ff4982
-0,      15000,      15000,        0,    13440, 0xbe8ff084
-0,      15100,      15100,        0,    13440, 0xc85a9e38
-0,      15200,      15200,        0,    13440, 0x541b9a19
-0,      15300,      15300,        0,    13440, 0x274893c9
-0,      15400,      15400,        0,    13440, 0x7634b5d2
-0,      15500,      15500,        0,    13440, 0x1bd8e10c
-0,      15600,      15600,        0,    13440, 0xa661dfb1
-0,      15700,      15700,        0,    13440, 0x9d01bf92
-0,      15800,      15800,        0,    13440, 0xcb1eb220
-0,      15900,      15900,        0,    13440, 0x0ce27d25
-0,      16000,      16000,        0,    13440, 0x523b594f
-0,      16100,      16100,        0,    13440, 0xf0a04c4f
-0,      16200,      16200,        0,    13440, 0x0f0ffc3d
-0,      16300,      16300,        0,    13440, 0xb0d8b778
-0,      16400,      16400,        0,    13440, 0x5137a642
-0,      16500,      16500,        0,    13440, 0xd213a552
-0,      16600,      16600,        0,    13440, 0xc2fbc9b1
-0,      16700,      16700,        0,    13440, 0xfc2ee379
-0,      16800,      16800,        0,    13440, 0xfb80f737
-0,      16900,      16900,        0,    13440, 0xd6cb2447
-0,      17000,      17000,        0,    13440, 0x124b606d
-0,      17100,      17100,        0,    13440, 0xf788a066
-0,      17200,      17200,        0,    13440, 0xa16eed6e
-0,      17300,      17300,        0,    13440, 0x73ff0f82
+#tb 0: 1/10
+0,          0,          0,        1,    13440, 0x7cb0a22f
+0,          1,          1,        1,    13440, 0xdfcea6ba
+0,          2,          2,        1,    13440, 0x59b2a5da
+0,          3,          3,        1,    13440, 0x12f1b2d8
+0,          4,          4,        1,    13440, 0x280fb9f6
+0,          5,          5,        1,    13440, 0x7bace8b3
+0,          6,          6,        1,    13440, 0x4ec91480
+0,          7,          7,        1,    13440, 0xa8010450
+0,          8,          8,        1,    13440, 0x61d8fc46
+0,          9,          9,        1,    13440, 0x242bb24e
+0,         10,         10,        1,    13440, 0x88397a36
+0,         11,         11,        1,    13440, 0x10e15726
+0,         12,         12,        1,    13440, 0x3018438c
+0,         13,         13,        1,    13440, 0xbbb94c21
+0,         14,         14,        1,    13440, 0xfc3e5e2b
+0,         15,         15,        1,    13440, 0xeaa69354
+0,         16,         16,        1,    13440, 0x96f1cc01
+0,         17,         17,        1,    13440, 0x333fdaff
+0,         18,         18,        1,    13440, 0xb5230ed2
+0,         19,         19,        1,    13440, 0x59383446
+0,         20,         20,        1,    13440, 0x954939e6
+0,         21,         21,        1,    13440, 0x53813d2f
+0,         22,         22,        1,    13440, 0x3ca53600
+0,         23,         23,        1,    13440, 0x7b30227a
+0,         24,         24,        1,    13440, 0x5145bbfe
+0,         25,         25,        1,    13440, 0xa0979632
+0,         26,         26,        1,    13440, 0x08026e21
+0,         27,         27,        1,    13440, 0x3f456d1e
+0,         28,         28,        1,    13440, 0x7d036b62
+0,         29,         29,        1,    13440, 0x508085fb
+0,         30,         30,        1,    13440, 0x251dc193
+0,         31,         31,        1,    13440, 0xf3121c9b
+0,         32,         32,        1,    13440, 0xf5da772e
+0,         33,         33,        1,    13440, 0x8179ccf7
+0,         34,         34,        1,    13440, 0xd57ceeb3
+0,         35,         35,        1,    13440, 0xc8f2169c
+0,         36,         36,        1,    13440, 0xbf8296c3
+0,         37,         37,        1,    13440, 0xee1927d0
+0,         38,         38,        1,    13440, 0xdd84e8d1
+0,         39,         39,        1,    13440, 0x7be57be2
+0,         40,         40,        1,    13440, 0xae353f91
+0,         41,         41,        1,    13440, 0x3ae927f2
+0,         42,         42,        1,    13440, 0x417227c6
+0,         43,         43,        1,    13440, 0x32572bea
+0,         44,         44,        1,    13440, 0x8b9e4839
+0,         45,         45,        1,    13440, 0xad669441
+0,         46,         46,        1,    13440, 0xc9de99a6
+0,         47,         47,        1,    13440, 0xb3ffb88b
+0,         48,         48,        1,    13440, 0xb321b8a0
+0,         49,         49,        1,    13440, 0x2efdbf53
+0,         50,         50,        1,    13440, 0x9b7aa566
+0,         51,         51,        1,    13440, 0x563c8d60
+0,         52,         52,        1,    13440, 0xe3848ee8
+0,         53,         53,        1,    13440, 0xa84b8f1d
+0,         54,         54,        1,    13440, 0x52da9f9f
+0,         55,         55,        1,    13440, 0x2ed56d97
+0,         56,         56,        1,    13440, 0x4e8534c2
+0,         57,         57,        1,    13440, 0x318900a6
+0,         58,         58,        1,    13440, 0xda96de39
+0,         59,         59,        1,    13440, 0xaae7ac0b
+0,         60,         60,        1,    13440, 0x7533ad99
+0,         61,         61,        1,    13440, 0x4e70c2c9
+0,         62,         62,        1,    13440, 0x9ce5e3fa
+0,         63,         63,        1,    13440, 0xc788fbbc
+0,         64,         64,        1,    13440, 0xd36604a9
+0,         65,         65,        1,    13440, 0x246221a4
+0,         66,         66,        1,    13440, 0x290c5c2b
+0,         67,         67,        1,    13440, 0xde6c68ec
+0,         68,         68,        1,    13440, 0x56248dbf
+0,         69,         69,        1,    13440, 0x5b898cbd
+0,         70,         70,        1,    13440, 0x090574b9
+0,         71,         71,        1,    13440, 0x8df2814a
+0,         72,         72,        1,    13440, 0xd4a6b285
+0,         73,         73,        1,    13440, 0xa016e921
+0,         74,         74,        1,    13440, 0x7f93fdc1
+0,         75,         75,        1,    13440, 0xfd0dee6f
+0,         76,         76,        1,    13440, 0xef04ce0e
+0,         77,         77,        1,    13440, 0x7560bee3
+0,         78,         78,        1,    13440, 0x5a8cdc85
+0,         79,         79,        1,    13440, 0x4788f7bc
+0,         80,         80,        1,    13440, 0xc001e34d
+0,         81,         81,        1,    13440, 0xc687eb74
+0,         82,         82,        1,    13440, 0xbf20feba
+0,         83,         83,        1,    13440, 0xd32647a8
+0,         84,         84,        1,    13440, 0xe69a955a
+0,         85,         85,        1,    13440, 0x1b56951f
+0,         86,         86,        1,    13440, 0xd1977378
+0,         87,         87,        1,    13440, 0x1620357d
+0,         88,         88,        1,    13440, 0x2596116f
+0,         89,         89,        1,    13440, 0x7473feca
+0,         90,         90,        1,    13440, 0x7f92bb47
+0,         91,         91,        1,    13440, 0x6866a683
+0,         92,         92,        1,    13440, 0xe9b08d7e
+0,         93,         93,        1,    13440, 0xa3fd7546
+0,         94,         94,        1,    13440, 0xa4416522
+0,         95,         95,        1,    13440, 0xd8f5572e
+0,         96,         96,        1,    13440, 0xf5746dbd
+0,         97,         97,        1,    13440, 0x256a87c6
+0,         98,         98,        1,    13440, 0x722aa2c8
+0,         99,         99,        1,    13440, 0xb26de5f5
+0,        100,        100,        1,    13440, 0x117f0841
+0,        101,        101,        1,    13440, 0xda2d192c
+0,        102,        102,        1,    13440, 0xb022442d
+0,        103,        103,        1,    13440, 0xbc4044f2
+0,        104,        104,        1,    13440, 0x68b330da
+0,        105,        105,        1,    13440, 0xc07228cf
+0,        106,        106,        1,    13440, 0xaa3f3d44
+0,        107,        107,        1,    13440, 0x25867aad
+0,        108,        108,        1,    13440, 0xa3ecb432
+0,        109,        109,        1,    13440, 0x93ccdcbb
+0,        110,        110,        1,    13440, 0x8302fa4f
+0,        111,        111,        1,    13440, 0x2f960f33
+0,        112,        112,        1,    13440, 0x15d41d14
+0,        113,        113,        1,    13440, 0x636529d0
+0,        114,        114,        1,    13440, 0x11035be5
+0,        115,        115,        1,    13440, 0x9b6e9167
+0,        116,        116,        1,    13440, 0x7b01adc7
+0,        117,        117,        1,    13440, 0xa237e05d
+0,        118,        118,        1,    13440, 0xd2f4f134
+0,        119,        119,        1,    13440, 0x2052d368
+0,        120,        120,        1,    13440, 0x08f7ae0d
+0,        121,        121,        1,    13440, 0xa89185bc
+0,        122,        122,        1,    13440, 0xfa628236
+0,        123,        123,        1,    13440, 0xdf79848b
+0,        124,        124,        1,    13440, 0xd19a906f
+0,        125,        125,        1,    13440, 0x219f9324
+0,        126,        126,        1,    13440, 0x46509b6d
+0,        127,        127,        1,    13440, 0xc5d9a568
+0,        128,        128,        1,    13440, 0xb21aaaa8
+0,        129,        129,        1,    13440, 0x925a97ed
+0,        130,        130,        1,    13440, 0xc5e3557f
+0,        131,        131,        1,    13440, 0x7c57155a
+0,        132,        132,        1,    13440, 0x6b26d005
+0,        133,        133,        1,    13440, 0xfdc7b369
+0,        134,        134,        1,    13440, 0x99919fc2
+0,        135,        135,        1,    13440, 0xcfe889e4
+0,        136,        136,        1,    13440, 0xd1196856
+0,        137,        137,        1,    13440, 0xec8348c6
+0,        138,        138,        1,    13440, 0x5ede0d9a
+0,        139,        139,        1,    13440, 0x198ef66e
+0,        140,        140,        1,    13440, 0x62fcefdf
+0,        141,        141,        1,    13440, 0x7791f415
+0,        142,        142,        1,    13440, 0xfbdb0029
+0,        143,        143,        1,    13440, 0xdab12b01
+0,        144,        144,        1,    13440, 0x646b2d5f
+0,        145,        145,        1,    13440, 0x5410f52e
+0,        146,        146,        1,    13440, 0x7186eef8
+0,        147,        147,        1,    13440, 0xca251ef6
+0,        148,        148,        1,    13440, 0x757c3b43
+0,        149,        149,        1,    13440, 0x59ff4982
+0,        150,        150,        1,    13440, 0xbe8ff084
+0,        151,        151,        1,    13440, 0xc85a9e38
+0,        152,        152,        1,    13440, 0x541b9a19
+0,        153,        153,        1,    13440, 0x274893c9
+0,        154,        154,        1,    13440, 0x7634b5d2
+0,        155,        155,        1,    13440, 0x1bd8e10c
+0,        156,        156,        1,    13440, 0xa661dfb1
+0,        157,        157,        1,    13440, 0x9d01bf92
+0,        158,        158,        1,    13440, 0xcb1eb220
+0,        159,        159,        1,    13440, 0x0ce27d25
+0,        160,        160,        1,    13440, 0x523b594f
+0,        161,        161,        1,    13440, 0xf0a04c4f
+0,        162,        162,        1,    13440, 0x0f0ffc3d
+0,        163,        163,        1,    13440, 0xb0d8b778
+0,        164,        164,        1,    13440, 0x5137a642
+0,        165,        165,        1,    13440, 0xd213a552
+0,        166,        166,        1,    13440, 0xc2fbc9b1
+0,        167,        167,        1,    13440, 0xfc2ee379
+0,        168,        168,        1,    13440, 0xfb80f737
+0,        169,        169,        1,    13440, 0xd6cb2447
+0,        170,        170,        1,    13440, 0x124b606d
+0,        171,        171,        1,    13440, 0xf788a066
+0,        172,        172,        1,    13440, 0xa16eed6e
+0,        173,        173,        1,    13440, 0x73ff0f82
diff --git a/tests/ref/fate/vp8-sign-bias b/tests/ref/fate/vp8-sign-bias
index 77b69ed..38843c0 100644
--- a/tests/ref/fate/vp8-sign-bias
+++ b/tests/ref/fate/vp8-sign-bias
@@ -6,4 +6,5 @@
 0,          5,          5,        1,   614880, 52f47f1e0348f3297d9f233fb5405e8b
 0,          6,          6,        1,   614880, cd51d2c200bfd66e8e1b0fd6b404570f
 0,          7,          7,        1,   614880, cf535cf0a53e903cd98a9a944b72da6d
-0,          8,          8,        1,   614880, ff373c0c8a4a319c84e72b1c3d76b399
+0,          8,          8,        1,   614880, 1b270fd2b56daa7892102c2885d23201
+0,          9,          9,        1,   614880, ff373c0c8a4a319c84e72b1c3d76b399
diff --git a/tests/ref/fate/vp8-size-change b/tests/ref/fate/vp8-size-change
index d87c563..1fba74e 100644
--- a/tests/ref/fate/vp8-size-change
+++ b/tests/ref/fate/vp8-size-change
@@ -1,31 +1,31 @@
-#tb 0: 1/1000
-0,          0,          0,        0,  3110400, 649f0f2e3e09e6938161bb07bede5282
-0,         33,         33,        0,  3110400, f24f632d50eafef73fa89391ca98c375
-0,         67,         67,        0,  3110400, 57b6d2ed51bfaf6588f39eb73e7922b8
-0,        100,        100,        0,  3110400, 463e0988ce28eb1c30669c06113deb4c
-0,        133,        133,        0,  3110400, 3c4ac119f998a0ccd7d3a6361f4d10a0
-0,        167,        167,        0,  3110400, 0f11c5cc9c1ac9055e21e417e1259c69
-0,        200,        200,        0,  3110400, 08c6e70f101c61013f2969b6a370d3f9
-0,        233,        233,        0,  3110400, ea8cb37017d8a9d20bf443b730fd8365
-0,        267,        267,        0,  3110400, 3f614203f054c89151680f4b1b0c6c4c
-0,        300,        300,        0,  3110400, 90488ee40d06c0f05eee8348dde57325
-0,        333,        333,        0,  3110400, f48117b74ac7455e69fd14e9b68ce95d
-0,        367,        367,        0,  3110400, 37ee06b6267b5ec25fd642525cf4469a
-0,        400,        400,        0,  3110400, cd5e0988e7c084f29bda4a18cb38c1e8
-0,        433,        433,        0,  3110400, 1fe943b01f00b8bc0cb5722010cef03c
-0,        467,        467,        0,  3110400, 40d8e8150326c7eb061d3f6cfd307d97
-0,        500,        500,        0,  3110400, 49812cbf928858cb56331c8c8aaaf556
-0,        533,        533,        0,  3110400, 3df607c752273ebcac21123e2c4c010c
-0,        567,        567,        0,  3110400, 020a0ae162c8326f83f8f4d8bf1627d2
-0,        600,        600,        0,  3110400, 459ac9f9488a6a2f4e378703a6b2a45a
-0,        633,        633,        0,  3110400, b1baf9a56f7667e4b8f4e3007b9ebe0f
-0,        667,        667,        0,  3110400, eea61a72a05c380450a96b575ba25f65
-0,        700,        700,        0,  3110400, e013a9f233824631d8c6e3f93106eebe
-0,        733,        733,        0,  3110400, 6c64147ebdee4b36728c6978b290ffb5
-0,        767,        767,        0,  3110400, c37956235667345d92fdfc7c62496e84
-0,        800,        800,        0,  3110400, 0ac58c28575b804d9e63395653c3aef2
-0,        833,        833,        0,  3110400, 641f2a78e338c733ef159bd36ec7966f
-0,        867,        867,        0,  3110400, 9402d455fa5bd556b85f479c42c3a4d2
-0,        900,        900,        0,  3110400, ca86e16b05db0c79b028d709c19e1f13
-0,        933,        933,        0,  3110400, 9167d622809df07eef9bcb3cb09de0f0
-0,        967,        967,        0,  3110400, e1d52ae2a2eb6aabb9bdc7e7ed05253e
+#tb 0: 1/30
+0,          0,          0,        1,  3110400, 7dde8cd136ab4b04a95d9856b941697e
+0,          1,          1,        1,  3110400, aa885f78cb6374b5bfcc66a4fc57026f
+0,          2,          2,        1,  3110400, b69b7b56f549a3f9b0a603940bac85ed
+0,          3,          3,        1,  3110400, 20e2e0f0c89c58828b6a3b10d9e175e5
+0,          4,          4,        1,  3110400, 483997936e7d6bb849e64d50426ec689
+0,          5,          5,        1,  3110400, c85ef97a853ff594e2bfdf0a0a581dcc
+0,          6,          6,        1,  3110400, c5e7b9ff4c25391793446da788cb83a9
+0,          7,          7,        1,  3110400, 63f93e89d24162e2f6328edbc6716b33
+0,          8,          8,        1,  3110400, 0e346ab4831ce8c69001153c72b7b827
+0,          9,          9,        1,  3110400, c526c21511d8bec2659d3d43d93734f2
+0,         10,         10,        1,  3110400, e95d01d5f9fb81a98bd34305c7ab30f8
+0,         11,         11,        1,  3110400, 177e75e7516e8746d31b43ea9d39e6b1
+0,         12,         12,        1,  3110400, 489d2bc0da93f118dc9a2697275697a7
+0,         13,         13,        1,  3110400, a2dc00d627350ff1ab302bcbad5ca5ac
+0,         14,         14,        1,  3110400, 20ce143831b0189f763ee5bee9c51188
+0,         15,         15,        1,  3110400, 7822fd908bd81b521c23fa4a639caf9e
+0,         16,         16,        1,  3110400, dabc4febbe09734126ac6f5a5180ba8c
+0,         17,         17,        1,  3110400, ef88f0d6667feefac1471b065208e1c8
+0,         18,         18,        1,  3110400, 7c7fc665a6fd9e19af9358bbdc162a51
+0,         19,         19,        1,  3110400, f2bcf32f734f99506bdd0a0376badf82
+0,         20,         20,        1,  3110400, 06809c2d277fd3b3918ebb4b65c27661
+0,         21,         21,        1,  3110400, e403e9e86fa5d519f65c565b3add84b5
+0,         22,         22,        1,  3110400, d2b876730e12245cacb578307794349a
+0,         23,         23,        1,  3110400, dfdfd8cb626a96138f6a2c1953dcf5ec
+0,         24,         24,        1,  3110400, 0ac58c28575b804d9e63395653c3aef2
+0,         25,         25,        1,  3110400, 641f2a78e338c733ef159bd36ec7966f
+0,         26,         26,        1,  3110400, 9402d455fa5bd556b85f479c42c3a4d2
+0,         27,         27,        1,  3110400, 0044d42b4048bc93112aa59789dbdc2d
+0,         28,         28,        1,  3110400, 5d9e5c5ba35f6f452e5f31ccff9e819c
+0,         29,         29,        1,  3110400, 307a55a94739b4cfdf41f7da7e5c0135
diff --git a/tests/ref/fate/vqa-cc b/tests/ref/fate/vqa-cc
index d3c5e6a..8950f94 100644
--- a/tests/ref/fate/vqa-cc
+++ b/tests/ref/fate/vqa-cc
@@ -3,37 +3,37 @@
 0,          1,          1,        1,   192000, 0x00000000
 0,          2,          2,        1,   192000, 0x00000000
 0,          3,          3,        1,   192000, 0x00000000
-0,          4,          4,        1,   192000, 0xcd900ccc
-0,          5,          5,        1,   192000, 0xfd496438
-0,          6,          6,        1,   192000, 0x965f0bf3
-0,          7,          7,        1,   192000, 0x378fca5f
-0,          8,          8,        1,   192000, 0x5ccd8966
-0,          9,          9,        1,   192000, 0x859676f9
-0,         10,         10,        1,   192000, 0x820bfb1c
-0,         11,         11,        1,   192000, 0x7570cc05
-0,         12,         12,        1,   192000, 0xf38bdb06
-0,         13,         13,        1,   192000, 0x9b0cbb44
-0,         14,         14,        1,   192000, 0x0ed70665
-0,         15,         15,        1,   192000, 0xd16de7fc
-0,         16,         16,        1,   192000, 0x97afb484
-0,         17,         17,        1,   192000, 0x012893f3
-0,         18,         18,        1,   192000, 0x742a4b43
-0,         19,         19,        1,   192000, 0x309dcd75
-0,         20,         20,        1,   192000, 0xed7814ac
-0,         21,         21,        1,   192000, 0xdb7de3d7
-0,         22,         22,        1,   192000, 0xe18679a3
-0,         23,         23,        1,   192000, 0xb1f213f4
-0,         24,         24,        1,   192000, 0x33c99b5c
-0,         25,         25,        1,   192000, 0xf66c0c91
-0,         26,         26,        1,   192000, 0x929cdc73
-0,         27,         27,        1,   192000, 0xa723fc3b
-0,         28,         28,        1,   192000, 0xe6395ccc
-0,         29,         29,        1,   192000, 0x147fbf74
-0,         30,         30,        1,   192000, 0x3ec62d28
-0,         31,         31,        1,   192000, 0x22104ffb
-0,         32,         32,        1,   192000, 0x91f25f58
-0,         33,         33,        1,   192000, 0xc91b0e4e
-0,         34,         34,        1,   192000, 0x4683df56
-0,         35,         35,        1,   192000, 0x8ef8932a
-0,         36,         36,        1,   192000, 0xce6c0ec0
-0,         37,         37,        1,   192000, 0xcc10e2a0
+0,          4,          4,        1,   192000, 0x9ee00ccf
+0,          5,          5,        1,   192000, 0x67256507
+0,          6,          6,        1,   192000, 0x74c70e87
+0,          7,          7,        1,   192000, 0x8ecdce9a
+0,          8,          8,        1,   192000, 0xc40f8efd
+0,          9,          9,        1,   192000, 0xb8107dfb
+0,         10,         10,        1,   192000, 0xb4e504eb
+0,         11,         11,        1,   192000, 0x0c7fdb95
+0,         12,         12,        1,   192000, 0x58c9f045
+0,         13,         13,        1,   192000, 0xcba9d0e9
+0,         14,         14,        1,   192000, 0x392a20f6
+0,         15,         15,        1,   192000, 0xc37905cc
+0,         16,         16,        1,   192000, 0xe278cf95
+0,         17,         17,        1,   192000, 0x3d03b01d
+0,         18,         18,        1,   192000, 0x16a26f28
+0,         19,         19,        1,   192000, 0xdd17f51c
+0,         20,         20,        1,   192000, 0x19703b85
+0,         21,         21,        1,   192000, 0xe51f0e70
+0,         22,         22,        1,   192000, 0x6f94ad2a
+0,         23,         23,        1,   192000, 0x71e449f1
+0,         24,         24,        1,   192000, 0x1dcacc52
+0,         25,         25,        1,   192000, 0x49c23f58
+0,         26,         26,        1,   192000, 0x4ce61551
+0,         27,         27,        1,   192000, 0xe54832d5
+0,         28,         28,        1,   192000, 0xbae28a59
+0,         29,         29,        1,   192000, 0xe8a4efbe
+0,         30,         30,        1,   192000, 0xe9e96883
+0,         31,         31,        1,   192000, 0xa5468c49
+0,         32,         32,        1,   192000, 0x7ec6936a
+0,         33,         33,        1,   192000, 0x46e53ee4
+0,         34,         34,        1,   192000, 0x937b168a
+0,         35,         35,        1,   192000, 0xed76cec4
+0,         36,         36,        1,   192000, 0x4b9f454d
+0,         37,         37,        1,   192000, 0xb58c1566
diff --git a/tests/ref/fate/vsynth1-amv b/tests/ref/fate/vsynth1-amv
new file mode 100644
index 0000000..9abfb05
--- /dev/null
+++ b/tests/ref/fate/vsynth1-amv
@@ -0,0 +1,4 @@
+00947dc33a092a3080d78d5bf69ed4e3 *tests/data/fate/vsynth1-amv.avi
+1365508 tests/data/fate/vsynth1-amv.avi
+e38681b9527b6d2531942f8a176a0265 *tests/data/fate/vsynth1-amv.out.rawvideo
+stddev:   10.07 PSNR: 28.06 MAXDIFF:   98 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-avui b/tests/ref/fate/vsynth1-avui
new file mode 100644
index 0000000..03f2b31
--- /dev/null
+++ b/tests/ref/fate/vsynth1-avui
@@ -0,0 +1,4 @@
+853dad3a1248614c6d61c2f9dc2a999c *tests/data/fate/vsynth1-avui.mov
+42624907 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/fate/vsynth1-cljr b/tests/ref/fate/vsynth1-cljr
index 41d40c9..77d73b2 100644
--- a/tests/ref/fate/vsynth1-cljr
+++ b/tests/ref/fate/vsynth1-cljr
@@ -1,4 +1,4 @@
-b4d3d31da0b4b6873ad8239d113c91d2 *tests/data/fate/vsynth1-cljr.avi
+041982e4fa83428c621a127647d47b3f *tests/data/fate/vsynth1-cljr.avi
 5075660 tests/data/fate/vsynth1-cljr.avi
-72e01607bae16527bc6389cf6db00b5f *tests/data/fate/vsynth1-cljr.out.rawvideo
-stddev:    6.95 PSNR: 31.28 MAXDIFF:   86 bytes:  7603200/  7603200
+7bd979b8b397f7bac22a0102c7889452 *tests/data/fate/vsynth1-cljr.out.rawvideo
+stddev:    6.74 PSNR: 31.55 MAXDIFF:   84 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-dnxhd-1080i b/tests/ref/fate/vsynth1-dnxhd-1080i
index 1eddbf8..899ef9e 100644
--- a/tests/ref/fate/vsynth1-dnxhd-1080i
+++ b/tests/ref/fate/vsynth1-dnxhd-1080i
@@ -1,4 +1,4 @@
-3cfbe36a7dd5b48859b8a569d626ef77 *tests/data/fate/vsynth1-dnxhd-1080i.mov
-3031875 tests/data/fate/vsynth1-dnxhd-1080i.mov
-0c651e840f860592f0d5b66030d9fa32 *tests/data/fate/vsynth1-dnxhd-1080i.out.rawvideo
+9a4781b0a052d9efaafbaf8893db9632 *tests/data/fate/vsynth1-dnxhd-1080i.mov
+3031911 tests/data/fate/vsynth1-dnxhd-1080i.mov
+e55bf857297ba4d911a9d17a984b125d *tests/data/fate/vsynth1-dnxhd-1080i.out.rawvideo
 stddev:    6.29 PSNR: 32.15 MAXDIFF:   64 bytes:  7603200/   760320
diff --git a/tests/ref/fate/vsynth1-dnxhd-720p b/tests/ref/fate/vsynth1-dnxhd-720p
index 94c28ed..fd77e86 100644
--- a/tests/ref/fate/vsynth1-dnxhd-720p
+++ b/tests/ref/fate/vsynth1-dnxhd-720p
@@ -1,4 +1,4 @@
-81f5be451dc18cf8a1d333c7885de60b *tests/data/fate/vsynth1-dnxhd-720p.dnxhd
+af03d57b8320568027162132643f7814 *tests/data/fate/vsynth1-dnxhd-720p.dnxhd
 2293760 tests/data/fate/vsynth1-dnxhd-720p.dnxhd
-94b21e5e68ccf9471eff74afd0ebe319 *tests/data/fate/vsynth1-dnxhd-720p.out.rawvideo
-stddev:    6.32 PSNR: 32.11 MAXDIFF:  183 bytes:  7603200/   760320
+f074f1b5ed394871b3c73184ad55b895 *tests/data/fate/vsynth1-dnxhd-720p.out.rawvideo
+stddev:    6.26 PSNR: 32.19 MAXDIFF:   65 bytes:  7603200/   760320
diff --git a/tests/ref/fate/vsynth1-dnxhd-720p-10bit b/tests/ref/fate/vsynth1-dnxhd-720p-10bit
index a667b9d..59423e7 100644
--- a/tests/ref/fate/vsynth1-dnxhd-720p-10bit
+++ b/tests/ref/fate/vsynth1-dnxhd-720p-10bit
@@ -1,4 +1,4 @@
-b5e24a055af02edec8674333260214fd *tests/data/fate/vsynth1-dnxhd-720p-10bit.dnxhd
+f8c4b7aa165a80df2485d526161290a3 *tests/data/fate/vsynth1-dnxhd-720p-10bit.dnxhd
 2293760 tests/data/fate/vsynth1-dnxhd-720p-10bit.dnxhd
-4466ff3d73d01bbe75ea25001d379b63 *tests/data/fate/vsynth1-dnxhd-720p-10bit.out.rawvideo
+790777baa4bb70c4e32cb13649cc26bf *tests/data/fate/vsynth1-dnxhd-720p-10bit.out.rawvideo
 stddev:    6.27 PSNR: 32.18 MAXDIFF:   64 bytes:  7603200/   760320
diff --git a/tests/ref/fate/vsynth1-dnxhd-720p-rd b/tests/ref/fate/vsynth1-dnxhd-720p-rd
index 1de576a..0422776 100644
--- a/tests/ref/fate/vsynth1-dnxhd-720p-rd
+++ b/tests/ref/fate/vsynth1-dnxhd-720p-rd
@@ -1,4 +1,4 @@
-1dc6e95925c4f3a230848ec17c02abed *tests/data/fate/vsynth1-dnxhd-720p-rd.dnxhd
+276e5175376051218b0e3eb36f9e9a63 *tests/data/fate/vsynth1-dnxhd-720p-rd.dnxhd
 2293760 tests/data/fate/vsynth1-dnxhd-720p-rd.dnxhd
-02972d2aec120ec1577ec9053d68ae0f *tests/data/fate/vsynth1-dnxhd-720p-rd.out.rawvideo
+28662df973b289798bf6069fbbee8071 *tests/data/fate/vsynth1-dnxhd-720p-rd.out.rawvideo
 stddev:    6.26 PSNR: 32.19 MAXDIFF:   65 bytes:  7603200/   760320
diff --git a/tests/ref/fate/vsynth1-dnxhd_1080i b/tests/ref/fate/vsynth1-dnxhd_1080i
new file mode 100644
index 0000000..f8f6df0
--- /dev/null
+++ b/tests/ref/fate/vsynth1-dnxhd_1080i
@@ -0,0 +1,4 @@
+027c985483caab9397592bf27477dce1 *./tests/data/vsynth1/dnxhd-1080i.mov
+3031911 ./tests/data/vsynth1/dnxhd-1080i.mov
+0c651e840f860592f0d5b66030d9fa32 *./tests/data/dnxhd_1080i.vsynth1.out.yuv
+stddev:    6.29 PSNR: 32.15 MAXDIFF:   64 bytes:   760320/  7603200
diff --git a/tests/ref/fate/vsynth1-dv b/tests/ref/fate/vsynth1-dv
index f5a37ad..d051e8d 100644
--- a/tests/ref/fate/vsynth1-dv
+++ b/tests/ref/fate/vsynth1-dv
@@ -1,4 +1,4 @@
-27ade3031b17214cf81c19cbf70f37d7 *tests/data/fate/vsynth1-dv.dv
+4d572f758b55a1756adf9f54132f3b9e *tests/data/fate/vsynth1-dv.dv
 7200000 tests/data/fate/vsynth1-dv.dv
 02ac7cdeab91d4d5621e7ce96dddc498 *tests/data/fate/vsynth1-dv.out.rawvideo
 stddev:    6.90 PSNR: 31.34 MAXDIFF:   76 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-dv-411 b/tests/ref/fate/vsynth1-dv-411
index a1f07da..bc4b802 100644
--- a/tests/ref/fate/vsynth1-dv-411
+++ b/tests/ref/fate/vsynth1-dv-411
@@ -1,4 +1,4 @@
-bd67f2431db160d4bb6dcd791cea6efd *tests/data/fate/vsynth1-dv-411.dv
+f179899efba432c6f01149c36c709092 *tests/data/fate/vsynth1-dv-411.dv
 7200000 tests/data/fate/vsynth1-dv-411.dv
 53946d51762b7826773e681fb02f377b *tests/data/fate/vsynth1-dv-411.out.rawvideo
 stddev:    9.45 PSNR: 28.62 MAXDIFF:   84 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-dv-50 b/tests/ref/fate/vsynth1-dv-50
index 18ee398..e747075 100644
--- a/tests/ref/fate/vsynth1-dv-50
+++ b/tests/ref/fate/vsynth1-dv-50
@@ -1,4 +1,4 @@
-26dba84f0ea895b914ef5b333d8394ac *tests/data/fate/vsynth1-dv-50.dv
+a193c5f92bf6e74c604e759d5f4f0f94 *tests/data/fate/vsynth1-dv-50.dv
 14400000 tests/data/fate/vsynth1-dv-50.dv
 a2ff093e93ffed10f730fa21df02fc50 *tests/data/fate/vsynth1-dv-50.out.rawvideo
 stddev:    1.72 PSNR: 43.38 MAXDIFF:   29 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-dv_411 b/tests/ref/fate/vsynth1-dv_411
new file mode 100644
index 0000000..c45b593
--- /dev/null
+++ b/tests/ref/fate/vsynth1-dv_411
@@ -0,0 +1,4 @@
+f179899efba432c6f01149c36c709092 *./tests/data/vsynth1/dv411.dv
+7200000 ./tests/data/vsynth1/dv411.dv
+b6640a3a572353f51284acb746eb00c4 *./tests/data/dv_411.vsynth1.out.yuv
+stddev:   30.76 PSNR: 18.37 MAXDIFF:  205 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-ffvhuff b/tests/ref/fate/vsynth1-ffvhuff
index 67f4b35..fc44dff 100644
--- a/tests/ref/fate/vsynth1-ffvhuff
+++ b/tests/ref/fate/vsynth1-ffvhuff
@@ -1,4 +1,4 @@
-da0c0bd12ac141c976ffa6a71832ab4b *tests/data/fate/vsynth1-ffvhuff.avi
+0632ffae6f1e06dd299bf41a845b9099 *tests/data/fate/vsynth1-ffvhuff.avi
 5987208 tests/data/fate/vsynth1-ffvhuff.avi
 c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-ffvhuff.out.rawvideo
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-flashsv b/tests/ref/fate/vsynth1-flashsv
index b934d8d..8b27830 100644
--- a/tests/ref/fate/vsynth1-flashsv
+++ b/tests/ref/fate/vsynth1-flashsv
@@ -1,4 +1,4 @@
 97894502b4cb57aca1105b6333f72dae *tests/data/fate/vsynth1-flashsv.flv
 14681925 tests/data/fate/vsynth1-flashsv.flv
-947cb24ec45a453348ae6fe3fa278071 *tests/data/fate/vsynth1-flashsv.out.rawvideo
-stddev:    2.85 PSNR: 39.03 MAXDIFF:   49 bytes:  7603200/  7603200
+791e1fb999deb2e4156e2286d48c4ed1 *tests/data/fate/vsynth1-flashsv.out.rawvideo
+stddev:    2.84 PSNR: 39.04 MAXDIFF:   49 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-flashsv2 b/tests/ref/fate/vsynth1-flashsv2
new file mode 100644
index 0000000..a01ccbe
--- /dev/null
+++ b/tests/ref/fate/vsynth1-flashsv2
@@ -0,0 +1,4 @@
+adbbdd25c1ed2f87ea589d2314307cdf *tests/data/fate/vsynth1-flashsv2.flv
+9368395 tests/data/fate/vsynth1-flashsv2.flv
+efa88d09115a2e947eff00ee435ba3f3 *tests/data/fate/vsynth1-flashsv2.out.rawvideo
+stddev:    3.47 PSNR: 37.31 MAXDIFF:   49 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-flv b/tests/ref/fate/vsynth1-flv
index 4b57bdf..3a21e6a 100644
--- a/tests/ref/fate/vsynth1-flv
+++ b/tests/ref/fate/vsynth1-flv
@@ -1,4 +1,4 @@
-d6a80659cedee7698aefe9c4a8285fa4 *tests/data/fate/vsynth1-flv.flv
-636269 tests/data/fate/vsynth1-flv.flv
-5ab46d8dd01dbb1d63df2a84858a4b05 *tests/data/fate/vsynth1-flv.out.rawvideo
+7f6ece1acc4163e33a982dd77dfad58a *tests/data/fate/vsynth1-flv.flv
+636264 tests/data/fate/vsynth1-flv.flv
+00ffbd9dac9233e53f4a4a19589a0efe *tests/data/fate/vsynth1-flv.out.rawvideo
 stddev:    8.02 PSNR: 30.04 MAXDIFF:  105 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-h261 b/tests/ref/fate/vsynth1-h261
index be7f80a..eb9575d 100644
--- a/tests/ref/fate/vsynth1-h261
+++ b/tests/ref/fate/vsynth1-h261
@@ -1,4 +1,4 @@
-d155470b713aeebacb85980b0d5f2ce3 *tests/data/fate/vsynth1-h261.avi
-707588 tests/data/fate/vsynth1-h261.avi
-716e83cb51afb1246bfaa80967df48ea *tests/data/fate/vsynth1-h261.out.rawvideo
+fe87fa742c7f04449c5b1dd55bfe70e6 *tests/data/fate/vsynth1-h261.avi
+707558 tests/data/fate/vsynth1-h261.avi
+85fde92037c2ccecc02e2d6c21a169b0 *tests/data/fate/vsynth1-h261.out.rawvideo
 stddev:    9.11 PSNR: 28.93 MAXDIFF:  113 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-h263 b/tests/ref/fate/vsynth1-h263
index 5d5d28a..9f31fc6 100644
--- a/tests/ref/fate/vsynth1-h263
+++ b/tests/ref/fate/vsynth1-h263
@@ -1,4 +1,4 @@
-fb4dc9b9eac2628c56cb82cf332e1f58 *tests/data/fate/vsynth1-h263.avi
+0037e453d71210d9d6a2d625c490705c *tests/data/fate/vsynth1-h263.avi
 659686 tests/data/fate/vsynth1-h263.avi
-1a1ba9a3a63ec1a1a9585fded0a7c954 *tests/data/fate/vsynth1-h263.out.rawvideo
+aef88517578fa7f53fe5159c4b6754ef *tests/data/fate/vsynth1-h263.out.rawvideo
 stddev:    8.03 PSNR: 30.03 MAXDIFF:  103 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-h263-obmc b/tests/ref/fate/vsynth1-h263-obmc
index b7e8f49..d82c425 100644
--- a/tests/ref/fate/vsynth1-h263-obmc
+++ b/tests/ref/fate/vsynth1-h263-obmc
@@ -1,4 +1,4 @@
-8a7be9f9f97673bf8b926b6dcf8a710d *tests/data/fate/vsynth1-h263-obmc.avi
-657366 tests/data/fate/vsynth1-h263-obmc.avi
-eba1d733a0c4b71322a78f718f312599 *tests/data/fate/vsynth1-h263-obmc.out.rawvideo
+bdd8f9cafa39df97f2e395110f4419e0 *tests/data/fate/vsynth1-h263-obmc.avi
+657328 tests/data/fate/vsynth1-h263-obmc.avi
+844f7ee27fa122e199fe20987b41a15c *tests/data/fate/vsynth1-h263-obmc.out.rawvideo
 stddev:    8.16 PSNR: 29.89 MAXDIFF:  113 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-h263p b/tests/ref/fate/vsynth1-h263p
index 9161a1d..a4cf7c8 100644
--- a/tests/ref/fate/vsynth1-h263p
+++ b/tests/ref/fate/vsynth1-h263p
@@ -1,4 +1,4 @@
-bbcadeceba295e1dad148aea1e57c370 *tests/data/fate/vsynth1-h263p.avi
-2328348 tests/data/fate/vsynth1-h263p.avi
-9554cda00c3487ab3ffda2c3ea22fa2f *tests/data/fate/vsynth1-h263p.out.rawvideo
+7474e28919ea4a6951e1534b951ddd28 *tests/data/fate/vsynth1-h263p.avi
+2328374 tests/data/fate/vsynth1-h263p.avi
+911330cb57c99c440234392be1588081 *tests/data/fate/vsynth1-h263p.out.rawvideo
 stddev:    2.06 PSNR: 41.83 MAXDIFF:   20 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-huffyuv b/tests/ref/fate/vsynth1-huffyuv
index e237af5..3d55c6b 100644
--- a/tests/ref/fate/vsynth1-huffyuv
+++ b/tests/ref/fate/vsynth1-huffyuv
@@ -1,4 +1,4 @@
-ace2536fa169d835d0fb332abde28d51 *tests/data/fate/vsynth1-huffyuv.avi
+f5f2e109af0612694ff3cd6464063e82 *tests/data/fate/vsynth1-huffyuv.avi
 7933800 tests/data/fate/vsynth1-huffyuv.avi
 c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-huffyuv.out.rawvideo
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-j2k b/tests/ref/fate/vsynth1-j2k
new file mode 100644
index 0000000..e434db8
--- /dev/null
+++ b/tests/ref/fate/vsynth1-j2k
@@ -0,0 +1,4 @@
+8da8ef50cccb9996f4bebbc585c4edb4 *tests/data/fate/vsynth1-j2k.avi
+2306914 tests/data/fate/vsynth1-j2k.avi
+ee9b245b3b07eed90bc6f2147bbd916c *tests/data/fate/vsynth1-j2k.out.rawvideo
+stddev:    5.47 PSNR: 33.37 MAXDIFF:   64 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-jpegls b/tests/ref/fate/vsynth1-jpegls
index 68ae0b2..de4f109 100644
--- a/tests/ref/fate/vsynth1-jpegls
+++ b/tests/ref/fate/vsynth1-jpegls
@@ -1,4 +1,4 @@
 870dceeb6d3931dd68b34f0c33be5d26 *tests/data/fate/vsynth1-jpegls.avi
 9089812 tests/data/fate/vsynth1-jpegls.avi
-947cb24ec45a453348ae6fe3fa278071 *tests/data/fate/vsynth1-jpegls.out.rawvideo
-stddev:    2.85 PSNR: 39.03 MAXDIFF:   49 bytes:  7603200/  7603200
+791e1fb999deb2e4156e2286d48c4ed1 *tests/data/fate/vsynth1-jpegls.out.rawvideo
+stddev:    2.84 PSNR: 39.04 MAXDIFF:   49 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mjpeg b/tests/ref/fate/vsynth1-mjpeg
index e32f452..6fd5c5b 100644
--- a/tests/ref/fate/vsynth1-mjpeg
+++ b/tests/ref/fate/vsynth1-mjpeg
@@ -1,4 +1,4 @@
-8bbf9513b1822945539f27a6eff3c7fa *tests/data/fate/vsynth1-mjpeg.avi
-1516140 tests/data/fate/vsynth1-mjpeg.avi
-c6ae81b5b896e4d05ff584311aebdb18 *tests/data/fate/vsynth1-mjpeg.out.rawvideo
+add304152c969eeb073157ccc9cc7799 *tests/data/fate/vsynth1-mjpeg.avi
+1515914 tests/data/fate/vsynth1-mjpeg.avi
+9a3b8169c251d19044f7087a95458c55 *tests/data/fate/vsynth1-mjpeg.out.rawvideo
 stddev:    7.87 PSNR: 30.21 MAXDIFF:   63 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg1 b/tests/ref/fate/vsynth1-mpeg1
index 5f3d703..b350cda 100644
--- a/tests/ref/fate/vsynth1-mpeg1
+++ b/tests/ref/fate/vsynth1-mpeg1
@@ -1,4 +1,4 @@
-1428744c6d5835f27506e69be4f837f4 *tests/data/fate/vsynth1-mpeg1.mpeg1video
-712006 tests/data/fate/vsynth1-mpeg1.mpeg1video
-58f0c332bf689117b57fa629a2bc0d2b *tests/data/fate/vsynth1-mpeg1.out.rawvideo
-stddev:    7.62 PSNR: 30.48 MAXDIFF:   84 bytes:  7603200/  7603200
+490e08209e30f162cf3f2a6f2e49c7ce *tests/data/fate/vsynth1-mpeg1.mpeg1video
+711835 tests/data/fate/vsynth1-mpeg1.mpeg1video
+c126c7dd12e7161df192d253e3100475 *tests/data/fate/vsynth1-mpeg1.out.rawvideo
+stddev:    7.63 PSNR: 30.48 MAXDIFF:   84 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg1b b/tests/ref/fate/vsynth1-mpeg1b
index ddd9bef..5c9e3c1 100644
--- a/tests/ref/fate/vsynth1-mpeg1b
+++ b/tests/ref/fate/vsynth1-mpeg1b
@@ -1,4 +1,4 @@
-777639666b449ab0a7ef260511e40532 *tests/data/fate/vsynth1-mpeg1b.mpeg1video
-1030337 tests/data/fate/vsynth1-mpeg1b.mpeg1video
-91a7fce732b34748e7bf753ebabe2483 *tests/data/fate/vsynth1-mpeg1b.out.rawvideo
+fc095c7816920052fd0b91329c60cf29 *tests/data/fate/vsynth1-mpeg1b.mpeg1video
+1031387 tests/data/fate/vsynth1-mpeg1b.mpeg1video
+22289cbbeb1e40c5fd68dcc73a07d8f5 *tests/data/fate/vsynth1-mpeg1b.out.rawvideo
 stddev:    6.30 PSNR: 32.13 MAXDIFF:   75 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg2 b/tests/ref/fate/vsynth1-mpeg2
index 1ee3674..8dbc88b 100644
--- a/tests/ref/fate/vsynth1-mpeg2
+++ b/tests/ref/fate/vsynth1-mpeg2
@@ -1,4 +1,4 @@
-fbddea2368cd2028fc8db4dfd4682e94 *tests/data/fate/vsynth1-mpeg2.mpeg2video
-728044 tests/data/fate/vsynth1-mpeg2.mpeg2video
-b41ca49c1a02e66ce64d262e2cdaec15 *tests/data/fate/vsynth1-mpeg2.out.rawvideo
+5434d2fbac67dc1a910883c9c04644fa *tests/data/fate/vsynth1-mpeg2.mpeg2video
+728400 tests/data/fate/vsynth1-mpeg2.mpeg2video
+66c2a14725ba0a6f1535b9a62768977b *tests/data/fate/vsynth1-mpeg2.out.rawvideo
 stddev:    7.65 PSNR: 30.45 MAXDIFF:   84 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg2-422 b/tests/ref/fate/vsynth1-mpeg2-422
index 5948446..bb0dce7 100644
--- a/tests/ref/fate/vsynth1-mpeg2-422
+++ b/tests/ref/fate/vsynth1-mpeg2-422
@@ -1,4 +1,4 @@
-af0cb75451aaa807beb5102707a98823 *tests/data/fate/vsynth1-mpeg2-422.mpeg2video
-728200 tests/data/fate/vsynth1-mpeg2-422.mpeg2video
-eb7fe83ce09af2d79ec16577c9d44e3c *tests/data/fate/vsynth1-mpeg2-422.out.rawvideo
-stddev:   10.29 PSNR: 27.88 MAXDIFF:  168 bytes:  7603200/  7603200
+0af0a148bf44bed5d260cafae6cc53e7 *tests/data/fate/vsynth1-mpeg2-422.mpeg2video
+730780 tests/data/fate/vsynth1-mpeg2-422.mpeg2video
+0273cd8463d1fc115378748239951560 *tests/data/fate/vsynth1-mpeg2-422.out.rawvideo
+stddev:   10.27 PSNR: 27.90 MAXDIFF:  162 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg2-ilace b/tests/ref/fate/vsynth1-mpeg2-ilace
index be08c31..b83b04c 100644
--- a/tests/ref/fate/vsynth1-mpeg2-ilace
+++ b/tests/ref/fate/vsynth1-mpeg2-ilace
@@ -1,4 +1,4 @@
-ec3f6713c88a2b41f6c369fd64341077 *tests/data/fate/vsynth1-mpeg2-ilace.mpeg2video
-737473 tests/data/fate/vsynth1-mpeg2-ilace.mpeg2video
-97615390fdd69abfcbc7e02df863a7d2 *tests/data/fate/vsynth1-mpeg2-ilace.out.rawvideo
+8492b04953b04dbef51cbe065f894e47 *tests/data/fate/vsynth1-mpeg2-ilace.mpeg2video
+738127 tests/data/fate/vsynth1-mpeg2-ilace.mpeg2video
+d0f2fab8d3a3fb8bc67aca068447d2db *tests/data/fate/vsynth1-mpeg2-ilace.out.rawvideo
 stddev:    7.67 PSNR: 30.43 MAXDIFF:   84 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg2-ivlc-qprd b/tests/ref/fate/vsynth1-mpeg2-ivlc-qprd
index 5ef30cd..4e00f0a 100644
--- a/tests/ref/fate/vsynth1-mpeg2-ivlc-qprd
+++ b/tests/ref/fate/vsynth1-mpeg2-ivlc-qprd
@@ -1,4 +1,4 @@
-8f6b20714918e6443e0c03716ed06f0d *tests/data/fate/vsynth1-mpeg2-ivlc-qprd.mpeg2video
-783552 tests/data/fate/vsynth1-mpeg2-ivlc-qprd.mpeg2video
-98eb9da15f880978e7f2ee1e7ce476ef *tests/data/fate/vsynth1-mpeg2-ivlc-qprd.out.rawvideo
-stddev:   10.07 PSNR: 28.06 MAXDIFF:  165 bytes:  7603200/  7603200
+f5e8917781d576d0721d44a3111d3efa *tests/data/fate/vsynth1-mpeg2-ivlc-qprd.mpeg2video
+783518 tests/data/fate/vsynth1-mpeg2-ivlc-qprd.mpeg2video
+0876d78f40971c5a8eb2367cbd27c5a6 *tests/data/fate/vsynth1-mpeg2-ivlc-qprd.out.rawvideo
+stddev:   10.07 PSNR: 28.07 MAXDIFF:  165 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg2-thread b/tests/ref/fate/vsynth1-mpeg2-thread
index 55a4fab..fd56bf0 100644
--- a/tests/ref/fate/vsynth1-mpeg2-thread
+++ b/tests/ref/fate/vsynth1-mpeg2-thread
@@ -1,4 +1,4 @@
-ecd183706688bd977c9994c3d1b23d61 *tests/data/fate/vsynth1-mpeg2-thread.mpeg2video
-801313 tests/data/fate/vsynth1-mpeg2-thread.mpeg2video
-d1658911ca83f5616c1d32abc40750de *tests/data/fate/vsynth1-mpeg2-thread.out.rawvideo
+c52f961dd53263cd9e7785a0d46949b7 *tests/data/fate/vsynth1-mpeg2-thread.mpeg2video
+801214 tests/data/fate/vsynth1-mpeg2-thread.mpeg2video
+d433c9b07b40b0d6c4fd5426699efb7f *tests/data/fate/vsynth1-mpeg2-thread.out.rawvideo
 stddev:    7.63 PSNR: 30.48 MAXDIFF:  110 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg2-thread-ivlc b/tests/ref/fate/vsynth1-mpeg2-thread-ivlc
index 7d04052..235dfe5 100644
--- a/tests/ref/fate/vsynth1-mpeg2-thread-ivlc
+++ b/tests/ref/fate/vsynth1-mpeg2-thread-ivlc
@@ -1,4 +1,4 @@
-23d600b026222253c2340e23300a4c02 *tests/data/fate/vsynth1-mpeg2-thread-ivlc.mpeg2video
-791773 tests/data/fate/vsynth1-mpeg2-thread-ivlc.mpeg2video
-d1658911ca83f5616c1d32abc40750de *tests/data/fate/vsynth1-mpeg2-thread-ivlc.out.rawvideo
+6c5ac0817a7fc501ed6d91e9b9899ed3 *tests/data/fate/vsynth1-mpeg2-thread-ivlc.mpeg2video
+791673 tests/data/fate/vsynth1-mpeg2-thread-ivlc.mpeg2video
+d433c9b07b40b0d6c4fd5426699efb7f *tests/data/fate/vsynth1-mpeg2-thread-ivlc.out.rawvideo
 stddev:    7.63 PSNR: 30.48 MAXDIFF:  110 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4 b/tests/ref/fate/vsynth1-mpeg4
index 9a917d0..b6da11c 100644
--- a/tests/ref/fate/vsynth1-mpeg4
+++ b/tests/ref/fate/vsynth1-mpeg4
@@ -1,4 +1,4 @@
-59a9e2eed314abface66aaf1b45eb8f2 *tests/data/fate/vsynth1-mpeg4.mp4
-540180 tests/data/fate/vsynth1-mpeg4.mp4
-8828a375448dc5c2215163ba70656f89 *tests/data/fate/vsynth1-mpeg4.out.rawvideo
+a2acdf772bf7b7641079d8a03ea03ccf *tests/data/fate/vsynth1-mpeg4.mp4
+540024 tests/data/fate/vsynth1-mpeg4.mp4
+f80ec173d37f2f91add031e95579a220 *tests/data/fate/vsynth1-mpeg4.out.rawvideo
 stddev:    7.97 PSNR: 30.10 MAXDIFF:  105 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-adap b/tests/ref/fate/vsynth1-mpeg4-adap
index 12cd15e..1764e25 100644
--- a/tests/ref/fate/vsynth1-mpeg4-adap
+++ b/tests/ref/fate/vsynth1-mpeg4-adap
@@ -1,4 +1,4 @@
-2d870c0da9ab2231ab5fc06981e70399 *tests/data/fate/vsynth1-mpeg4-adap.avi
-403456 tests/data/fate/vsynth1-mpeg4-adap.avi
-fa2049396479b5f170aa764fed5b2a31 *tests/data/fate/vsynth1-mpeg4-adap.out.rawvideo
+520ee9e41fc09c5ad0d4b9852a2ea1d2 *tests/data/fate/vsynth1-mpeg4-adap.avi
+403444 tests/data/fate/vsynth1-mpeg4-adap.avi
+fad0b9dc08fe4a95b297af1a7411c1e9 *tests/data/fate/vsynth1-mpeg4-adap.out.rawvideo
 stddev:   14.05 PSNR: 25.17 MAXDIFF:  184 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-adv b/tests/ref/fate/vsynth1-mpeg4-adv
index e223d5f..c328a42 100644
--- a/tests/ref/fate/vsynth1-mpeg4-adv
+++ b/tests/ref/fate/vsynth1-mpeg4-adv
@@ -1,4 +1,4 @@
-7d8eb01fd68d83d62a98585757704d47 *tests/data/fate/vsynth1-mpeg4-adv.avi
+5b2b17eac3210b85d847e7088469b53c *tests/data/fate/vsynth1-mpeg4-adv.avi
 589716 tests/data/fate/vsynth1-mpeg4-adv.avi
-f8b226876b1b2c0b98fd6928fd9adbd8 *tests/data/fate/vsynth1-mpeg4-adv.out.rawvideo
+b651bd94456005a1990fb64c28306262 *tests/data/fate/vsynth1-mpeg4-adv.out.rawvideo
 stddev:    6.98 PSNR: 31.25 MAXDIFF:   84 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-error b/tests/ref/fate/vsynth1-mpeg4-error
index 74d5aaa..ab3a266 100644
--- a/tests/ref/fate/vsynth1-mpeg4-error
+++ b/tests/ref/fate/vsynth1-mpeg4-error
@@ -1,4 +1,4 @@
-7416dfd319f04044d4575dc9d1b406e1 *tests/data/fate/vsynth1-mpeg4-error.avi
-756836 tests/data/fate/vsynth1-mpeg4-error.avi
-79e94ba32b37759397362cbcb479d4d3 *tests/data/fate/vsynth1-mpeg4-error.out.rawvideo
-stddev:   18.36 PSNR: 22.85 MAXDIFF:  243 bytes:  7603200/  7603200
+ed45da2282cbc0a3e4d4d45bbcab71d8 *tests/data/fate/vsynth1-mpeg4-error.avi
+752358 tests/data/fate/vsynth1-mpeg4-error.avi
+5853c8c789f260ae4dcbf37a17d04b66 *tests/data/fate/vsynth1-mpeg4-error.out.rawvideo
+stddev:   17.33 PSNR: 23.35 MAXDIFF:  229 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-nr b/tests/ref/fate/vsynth1-mpeg4-nr
index a83f4fd..4814b1a 100644
--- a/tests/ref/fate/vsynth1-mpeg4-nr
+++ b/tests/ref/fate/vsynth1-mpeg4-nr
@@ -1,4 +1,4 @@
-c02f54157ba08ca12ad979c6308212ad *tests/data/fate/vsynth1-mpeg4-nr.avi
-675638 tests/data/fate/vsynth1-mpeg4-nr.avi
-d2b89d5958fb7331f6c9e5b7ecaaa5b6 *tests/data/fate/vsynth1-mpeg4-nr.out.rawvideo
-stddev:    6.99 PSNR: 31.23 MAXDIFF:   86 bytes:  7603200/  7603200
+9f990e290b5978f0243ea5a2141feb6c *tests/data/fate/vsynth1-mpeg4-nr.avi
+675464 tests/data/fate/vsynth1-mpeg4-nr.avi
+5fee518cde41e5567f800fbe14210fb8 *tests/data/fate/vsynth1-mpeg4-nr.out.rawvideo
+stddev:    6.99 PSNR: 31.24 MAXDIFF:   86 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-qpel b/tests/ref/fate/vsynth1-mpeg4-qpel
index 254c3ee..00c0022 100644
--- a/tests/ref/fate/vsynth1-mpeg4-qpel
+++ b/tests/ref/fate/vsynth1-mpeg4-qpel
@@ -1,4 +1,4 @@
-3bf17c3d04f52988386ce106a2a58976 *tests/data/fate/vsynth1-mpeg4-qpel.avi
-860678 tests/data/fate/vsynth1-mpeg4-qpel.avi
-756928496245ecc701f79eebeec8e5e6 *tests/data/fate/vsynth1-mpeg4-qpel.out.rawvideo
-stddev:    5.63 PSNR: 33.12 MAXDIFF:   70 bytes:  7603200/  7603200
+8636a8011e315dafe7fa66e493a41174 *tests/data/fate/vsynth1-mpeg4-qpel.avi
+858692 tests/data/fate/vsynth1-mpeg4-qpel.avi
+5089090df7169eb482532df5471d7f5f *tests/data/fate/vsynth1-mpeg4-qpel.out.rawvideo
+stddev:    5.63 PSNR: 33.11 MAXDIFF:   70 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-qprd b/tests/ref/fate/vsynth1-mpeg4-qprd
index 1a61654..8a5f84c 100644
--- a/tests/ref/fate/vsynth1-mpeg4-qprd
+++ b/tests/ref/fate/vsynth1-mpeg4-qprd
@@ -1,4 +1,4 @@
-d6b7e724a6ad66ab5e4c5a499218b40d *tests/data/fate/vsynth1-mpeg4-qprd.avi
-710944 tests/data/fate/vsynth1-mpeg4-qprd.avi
-e65f4c7f343fe2bad1cac44b7da5f7c4 *tests/data/fate/vsynth1-mpeg4-qprd.out.rawvideo
+d4746d1d22f2d464b1cdd6cc2d63ddcf *tests/data/fate/vsynth1-mpeg4-qprd.avi
+710684 tests/data/fate/vsynth1-mpeg4-qprd.avi
+693231ac7e6fbf8758415f9f2509408d *tests/data/fate/vsynth1-mpeg4-qprd.out.rawvideo
 stddev:    9.79 PSNR: 28.31 MAXDIFF:  176 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-rc b/tests/ref/fate/vsynth1-mpeg4-rc
index 180df10..74bde1c 100644
--- a/tests/ref/fate/vsynth1-mpeg4-rc
+++ b/tests/ref/fate/vsynth1-mpeg4-rc
@@ -1,4 +1,4 @@
-1c6dadf75f60f4ba59a0fe0b6eaedf57 *tests/data/fate/vsynth1-mpeg4-rc.avi
-830160 tests/data/fate/vsynth1-mpeg4-rc.avi
-4d95e340db9bc57a559162c039f3784e *tests/data/fate/vsynth1-mpeg4-rc.out.rawvideo
+7d147478239dbc75f1ea3f7e27b07c95 *tests/data/fate/vsynth1-mpeg4-rc.avi
+830506 tests/data/fate/vsynth1-mpeg4-rc.avi
+9dcd9d022ae14fe1e4a53aa4865464c6 *tests/data/fate/vsynth1-mpeg4-rc.out.rawvideo
 stddev:   10.24 PSNR: 27.92 MAXDIFF:  196 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpeg4-thread b/tests/ref/fate/vsynth1-mpeg4-thread
index 66a5508..b60933d 100644
--- a/tests/ref/fate/vsynth1-mpeg4-thread
+++ b/tests/ref/fate/vsynth1-mpeg4-thread
@@ -1,4 +1,4 @@
-4f4ea04faad7212374919aa1ec7ff994 *tests/data/fate/vsynth1-mpeg4-thread.avi
-774760 tests/data/fate/vsynth1-mpeg4-thread.avi
-64b96cddf5301990e118978b3a3bcd0d *tests/data/fate/vsynth1-mpeg4-thread.out.rawvideo
+ae675a6a953ddeaecb7a9db14c4d0fa0 *tests/data/fate/vsynth1-mpeg4-thread.avi
+774762 tests/data/fate/vsynth1-mpeg4-thread.avi
+9aa327a244d5179acf7fe64dc1459bff *tests/data/fate/vsynth1-mpeg4-thread.out.rawvideo
 stddev:   10.13 PSNR: 28.02 MAXDIFF:  183 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-mpng b/tests/ref/fate/vsynth1-mpng
new file mode 100644
index 0000000..875d81b
--- /dev/null
+++ b/tests/ref/fate/vsynth1-mpng
@@ -0,0 +1,4 @@
+a8e7393fa534289eee9319ded7807f99 *tests/data/fate/vsynth1-mpng.avi
+12157242 tests/data/fate/vsynth1-mpng.avi
+93695a27c24a61105076ca7b1f010bbd *tests/data/fate/vsynth1-mpng.out.rawvideo
+stddev:    3.42 PSNR: 37.44 MAXDIFF:   48 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-msmpeg4 b/tests/ref/fate/vsynth1-msmpeg4
index 55fb06d..8d32ccc 100644
--- a/tests/ref/fate/vsynth1-msmpeg4
+++ b/tests/ref/fate/vsynth1-msmpeg4
@@ -1,4 +1,4 @@
-4b08952b0afceb17ee3db31b67f6b778 *tests/data/fate/vsynth1-msmpeg4.avi
-624718 tests/data/fate/vsynth1-msmpeg4.avi
-5ca72c39e3fc5df8e62f223c869589f5 *tests/data/fate/vsynth1-msmpeg4.out.rawvideo
+f63295e3dcf4afe48135667dbe9b60b8 *tests/data/fate/vsynth1-msmpeg4.avi
+624714 tests/data/fate/vsynth1-msmpeg4.avi
+4529fee96b8073e02974f5355e5f6c4e *tests/data/fate/vsynth1-msmpeg4.out.rawvideo
 stddev:    7.98 PSNR: 30.09 MAXDIFF:  104 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-msmpeg4v2 b/tests/ref/fate/vsynth1-msmpeg4v2
index 839078a..ff54534 100644
--- a/tests/ref/fate/vsynth1-msmpeg4v2
+++ b/tests/ref/fate/vsynth1-msmpeg4v2
@@ -1,4 +1,4 @@
-88957e35efcc718bce0307627ad3298d *tests/data/fate/vsynth1-msmpeg4v2.avi
-623788 tests/data/fate/vsynth1-msmpeg4v2.avi
-c6ff1041a0ef62c2a2e5ef519e5e94c4 *tests/data/fate/vsynth1-msmpeg4v2.out.rawvideo
+6fbce2ce8618cf8c4c19897188eb1ca0 *tests/data/fate/vsynth1-msmpeg4v2.avi
+623778 tests/data/fate/vsynth1-msmpeg4v2.avi
+0476d9aafc4358654f411fa9648f9560 *tests/data/fate/vsynth1-msmpeg4v2.out.rawvideo
 stddev:    7.97 PSNR: 30.10 MAXDIFF:  105 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-msvideo1 b/tests/ref/fate/vsynth1-msvideo1
new file mode 100644
index 0000000..9beb739
--- /dev/null
+++ b/tests/ref/fate/vsynth1-msvideo1
@@ -0,0 +1,4 @@
+37aa67b5928794534cb6a268d4adf48c *tests/data/fate/vsynth1-msvideo1.avi
+2162264 tests/data/fate/vsynth1-msvideo1.avi
+c0665fac1bd896b6fe7fe0eead805bd5 *tests/data/fate/vsynth1-msvideo1.out.rawvideo
+stddev:   11.80 PSNR: 26.69 MAXDIFF:  151 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-prores b/tests/ref/fate/vsynth1-prores
index ac30a6a..d13bd30 100644
--- a/tests/ref/fate/vsynth1-prores
+++ b/tests/ref/fate/vsynth1-prores
@@ -1,4 +1,4 @@
-2566517b15c62887bd94daaab1b1a85b *tests/data/fate/vsynth1-prores.mov
-3859037 tests/data/fate/vsynth1-prores.mov
-0a4153637d0cc0a88a8bcbf04cfaf8c6 *tests/data/fate/vsynth1-prores.out.rawvideo
-stddev:    3.17 PSNR: 38.09 MAXDIFF:   39 bytes:  7603200/  7603200
+17a598a8cc6b899c79e3c69b9679e08d *tests/data/fate/vsynth1-prores.mov
+5022811 tests/data/fate/vsynth1-prores.mov
+a2e2d1d45341a94ff994d1d92629f778 *tests/data/fate/vsynth1-prores.out.rawvideo
+stddev:    2.47 PSNR: 40.27 MAXDIFF:   31 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-prores_kostya b/tests/ref/fate/vsynth1-prores_kostya
new file mode 100644
index 0000000..aa28aa2
--- /dev/null
+++ b/tests/ref/fate/vsynth1-prores_kostya
@@ -0,0 +1,4 @@
+504b53c891d5bd917d5cf5190c312a20 *tests/data/fate/vsynth1-prores_kostya.mov
+3858901 tests/data/fate/vsynth1-prores_kostya.mov
+0a4153637d0cc0a88a8bcbf04cfaf8c6 *tests/data/fate/vsynth1-prores_kostya.out.rawvideo
+stddev:    3.17 PSNR: 38.09 MAXDIFF:   39 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-qtrle b/tests/ref/fate/vsynth1-qtrle
index c9c8ccf..081707d 100644
--- a/tests/ref/fate/vsynth1-qtrle
+++ b/tests/ref/fate/vsynth1-qtrle
@@ -1,4 +1,4 @@
-7d75328a17e04796a39fe9be3a322946 *tests/data/fate/vsynth1-qtrle.mov
-15263232 tests/data/fate/vsynth1-qtrle.mov
-243325fb2cae1a9245efd49aff936327 *tests/data/fate/vsynth1-qtrle.out.rawvideo
-stddev:    3.42 PSNR: 37.43 MAXDIFF:   48 bytes:  7603200/  7603200
+f66efb8a1fd455ef31de540df9a81909 *tests/data/fate/vsynth1-qtrle.mov
+15263148 tests/data/fate/vsynth1-qtrle.mov
+93695a27c24a61105076ca7b1f010bbd *tests/data/fate/vsynth1-qtrle.out.rawvideo
+stddev:    3.42 PSNR: 37.44 MAXDIFF:   48 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-qtrlegray b/tests/ref/fate/vsynth1-qtrlegray
new file mode 100644
index 0000000..99ec831
--- /dev/null
+++ b/tests/ref/fate/vsynth1-qtrlegray
@@ -0,0 +1,4 @@
+a9f365910ce1eb0ccbc05b68ca7cfafb *tests/data/fate/vsynth1-qtrlegray.mov
+5113284 tests/data/fate/vsynth1-qtrlegray.mov
+29def4aed035ed65d3a89f7d382fccbe *tests/data/fate/vsynth1-qtrlegray.out.rawvideo
+stddev:   25.95 PSNR: 19.85 MAXDIFF:  122 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-r210 b/tests/ref/fate/vsynth1-r210
new file mode 100644
index 0000000..68cdac8
--- /dev/null
+++ b/tests/ref/fate/vsynth1-r210
@@ -0,0 +1,4 @@
+604a34c9f9151891c2d63d2652b75329 *tests/data/fate/vsynth1-r210.avi
+22125260 tests/data/fate/vsynth1-r210.avi
+ecaafa9eec11b5e1453a63ed6d194eed *tests/data/fate/vsynth1-r210.out.rawvideo
+stddev:    3.23 PSNR: 37.94 MAXDIFF:   48 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-rgb b/tests/ref/fate/vsynth1-rgb
index e9a5b19..94e11e9 100644
--- a/tests/ref/fate/vsynth1-rgb
+++ b/tests/ref/fate/vsynth1-rgb
@@ -1,4 +1,4 @@
 05f0719cb52486d9a4beb9cfae3f2571 *tests/data/fate/vsynth1-rgb.avi
 15213260 tests/data/fate/vsynth1-rgb.avi
-243325fb2cae1a9245efd49aff936327 *tests/data/fate/vsynth1-rgb.out.rawvideo
-stddev:    3.42 PSNR: 37.43 MAXDIFF:   48 bytes:  7603200/  7603200
+93695a27c24a61105076ca7b1f010bbd *tests/data/fate/vsynth1-rgb.out.rawvideo
+stddev:    3.42 PSNR: 37.44 MAXDIFF:   48 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-rv10 b/tests/ref/fate/vsynth1-rv10
index 234015f..d414bd6 100644
--- a/tests/ref/fate/vsynth1-rv10
+++ b/tests/ref/fate/vsynth1-rv10
@@ -1,4 +1,4 @@
-4d7e82de72a83905cf84b8abc3e70b8f *tests/data/fate/vsynth1-rv10.rm
-653905 tests/data/fate/vsynth1-rv10.rm
-1a1ba9a3a63ec1a1a9585fded0a7c954 *tests/data/fate/vsynth1-rv10.out.rawvideo
+5ef46004d474669d19ad06133a1cf137 *tests/data/fate/vsynth1-rv10.rm
+653907 tests/data/fate/vsynth1-rv10.rm
+aef88517578fa7f53fe5159c4b6754ef *tests/data/fate/vsynth1-rv10.out.rawvideo
 stddev:    8.03 PSNR: 30.03 MAXDIFF:  103 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-rv20 b/tests/ref/fate/vsynth1-rv20
index abcc4a1..5b3310a 100644
--- a/tests/ref/fate/vsynth1-rv20
+++ b/tests/ref/fate/vsynth1-rv20
@@ -1,4 +1,4 @@
-81868601e602eee5b6d80f5ece4aaa98 *tests/data/fate/vsynth1-rv20.rm
-646016 tests/data/fate/vsynth1-rv20.rm
-b45fdb0201b06f7649f44050e262c54c *tests/data/fate/vsynth1-rv20.out.rawvideo
+0f04eec24aaa8ea06eafc58082c2e2ef *tests/data/fate/vsynth1-rv20.rm
+646019 tests/data/fate/vsynth1-rv20.rm
+3f55bcfb3c672d74f0fa64aa90aa0395 *tests/data/fate/vsynth1-rv20.out.rawvideo
 stddev:    8.26 PSNR: 29.79 MAXDIFF:  103 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-svq1 b/tests/ref/fate/vsynth1-svq1
index 0f8a6b2..7468b36 100644
--- a/tests/ref/fate/vsynth1-svq1
+++ b/tests/ref/fate/vsynth1-svq1
@@ -1,4 +1,4 @@
-5c9d8734693f3cab57f61e76b5b6da7d *tests/data/fate/vsynth1-svq1.mov
-1334367 tests/data/fate/vsynth1-svq1.mov
+f2930c19bd18eb03c1f984a72cdb67c8 *tests/data/fate/vsynth1-svq1.mov
+1334223 tests/data/fate/vsynth1-svq1.mov
 9cc35c54b2c77d36bd7e308b393c1f81 *tests/data/fate/vsynth1-svq1.out.rawvideo
 stddev:    9.58 PSNR: 28.50 MAXDIFF:  210 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-v308 b/tests/ref/fate/vsynth1-v308
new file mode 100644
index 0000000..137dcf9
--- /dev/null
+++ b/tests/ref/fate/vsynth1-v308
@@ -0,0 +1,4 @@
+8d5f2065ce6547acc51041a679b7d6c4 *tests/data/fate/vsynth1-v308.avi
+15213260 tests/data/fate/vsynth1-v308.avi
+10fb42f1abf40a289c3edafc0390482c *tests/data/fate/vsynth1-v308.out.rawvideo
+stddev:    2.67 PSNR: 39.60 MAXDIFF:   43 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-v408 b/tests/ref/fate/vsynth1-v408
new file mode 100644
index 0000000..c7f414c
--- /dev/null
+++ b/tests/ref/fate/vsynth1-v408
@@ -0,0 +1,4 @@
+98057c4d5ce12a1b1b3ca15839f47c95 *tests/data/fate/vsynth1-v408.avi
+20282060 tests/data/fate/vsynth1-v408.avi
+c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-v408.out.rawvideo
+stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-wmv1 b/tests/ref/fate/vsynth1-wmv1
index d487e4e..9afc020 100644
--- a/tests/ref/fate/vsynth1-wmv1
+++ b/tests/ref/fate/vsynth1-wmv1
@@ -1,4 +1,4 @@
-4f3461315776e5118866fa3819cff9b6 *tests/data/fate/vsynth1-wmv1.avi
-626908 tests/data/fate/vsynth1-wmv1.avi
-5182edba5b5e0354b39ce4f3604b62da *tests/data/fate/vsynth1-wmv1.out.rawvideo
+8c406d0253bd474d4764f5d75776fc03 *tests/data/fate/vsynth1-wmv1.avi
+626882 tests/data/fate/vsynth1-wmv1.avi
+3354066ebdd8cd8098394be2384744e7 *tests/data/fate/vsynth1-wmv1.out.rawvideo
 stddev:    7.97 PSNR: 30.09 MAXDIFF:  110 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-wmv2 b/tests/ref/fate/vsynth1-wmv2
index 14304dd..6ce5520 100644
--- a/tests/ref/fate/vsynth1-wmv2
+++ b/tests/ref/fate/vsynth1-wmv2
@@ -1,4 +1,4 @@
-13efda9d3811345aadc0632fc9a9332b *tests/data/fate/vsynth1-wmv2.avi
-659852 tests/data/fate/vsynth1-wmv2.avi
-5182edba5b5e0354b39ce4f3604b62da *tests/data/fate/vsynth1-wmv2.out.rawvideo
+916932bf4b81443b4b87128ba8b63580 *tests/data/fate/vsynth1-wmv2.avi
+659844 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
diff --git a/tests/ref/fate/vsynth1-y41p b/tests/ref/fate/vsynth1-y41p
new file mode 100644
index 0000000..d2147f6
--- /dev/null
+++ b/tests/ref/fate/vsynth1-y41p
@@ -0,0 +1,4 @@
+70bbcb52acac0a3cb3217719669a8242 *tests/data/fate/vsynth1-y41p.avi
+7610060 tests/data/fate/vsynth1-y41p.avi
+3aef1d83732a3f9835ee2523a11c95c1 *tests/data/fate/vsynth1-y41p.out.rawvideo
+stddev:    5.98 PSNR: 32.59 MAXDIFF:   87 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-yuv b/tests/ref/fate/vsynth1-yuv
index 927a64a..5dc29aa 100644
--- a/tests/ref/fate/vsynth1-yuv
+++ b/tests/ref/fate/vsynth1-yuv
@@ -1,4 +1,4 @@
-aa6b9e862aebcf8902a6d770e7729d59 *tests/data/fate/vsynth1-yuv.avi
+eaa66c3b27a2602e882befe154a8b119 *tests/data/fate/vsynth1-yuv.avi
 7610060 tests/data/fate/vsynth1-yuv.avi
 c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-yuv.out.rawvideo
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-yuv4 b/tests/ref/fate/vsynth1-yuv4
new file mode 100644
index 0000000..5b7b925
--- /dev/null
+++ b/tests/ref/fate/vsynth1-yuv4
@@ -0,0 +1,4 @@
+e0d593eb635432f421b93224e425ee03 *tests/data/fate/vsynth1-yuv4.avi
+7610060 tests/data/fate/vsynth1-yuv4.avi
+c5ccac874dbf808e9088bc3107860042 *tests/data/fate/vsynth1-yuv4.out.rawvideo
+stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-zlib b/tests/ref/fate/vsynth1-zlib
new file mode 100644
index 0000000..068f154
--- /dev/null
+++ b/tests/ref/fate/vsynth1-zlib
@@ -0,0 +1,4 @@
+fe4983e551b48dc555e1aeaf628f649f *tests/data/fate/vsynth1-zlib.avi
+12108644 tests/data/fate/vsynth1-zlib.avi
+93695a27c24a61105076ca7b1f010bbd *tests/data/fate/vsynth1-zlib.out.rawvideo
+stddev:    3.42 PSNR: 37.44 MAXDIFF:   48 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth1-zmbv b/tests/ref/fate/vsynth1-zmbv
new file mode 100644
index 0000000..c608c4b
--- /dev/null
+++ b/tests/ref/fate/vsynth1-zmbv
@@ -0,0 +1,4 @@
+09bae55394f86ddb9e5c3254b174f865 *tests/data/fate/vsynth1-zmbv.avi
+2285442 tests/data/fate/vsynth1-zmbv.avi
+4ad1ca9de7c65eab68a619c54fffaec8 *tests/data/fate/vsynth1-zmbv.out.rawvideo
+stddev:    8.61 PSNR: 29.43 MAXDIFF:   64 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-amv b/tests/ref/fate/vsynth2-amv
new file mode 100644
index 0000000..313edac
--- /dev/null
+++ b/tests/ref/fate/vsynth2-amv
@@ -0,0 +1,4 @@
+853ae9d6426cb3c4d4bad3592e1a2ec3 *tests/data/fate/vsynth2-amv.avi
+761988 tests/data/fate/vsynth2-amv.avi
+f256ad9feefb499c6569d06d868eb496 *tests/data/fate/vsynth2-amv.out.rawvideo
+stddev:    4.30 PSNR: 35.46 MAXDIFF:   65 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-avui b/tests/ref/fate/vsynth2-avui
new file mode 100644
index 0000000..59bac8d
--- /dev/null
+++ b/tests/ref/fate/vsynth2-avui
@@ -0,0 +1,4 @@
+d6ed112daf14e73ea50f1c32ecc6d4ce *tests/data/fate/vsynth2-avui.mov
+42624907 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/fate/vsynth2-cljr b/tests/ref/fate/vsynth2-cljr
index 91ce30c..ae13185 100644
--- a/tests/ref/fate/vsynth2-cljr
+++ b/tests/ref/fate/vsynth2-cljr
@@ -1,4 +1,4 @@
-416ddcf73d2d993456f3c49f3eed4f1a *tests/data/fate/vsynth2-cljr.avi
+fdc1926e0a599de94513f0a3472b598f *tests/data/fate/vsynth2-cljr.avi
 5075660 tests/data/fate/vsynth2-cljr.avi
-cfe7802bf34aafed7df5dcaa5126ef23 *tests/data/fate/vsynth2-cljr.out.rawvideo
-stddev:    3.69 PSNR: 36.78 MAXDIFF:   22 bytes:  7603200/  7603200
+965c4a134144b30b24d6d138b03ddb8c *tests/data/fate/vsynth2-cljr.out.rawvideo
+stddev:    3.29 PSNR: 37.76 MAXDIFF:   23 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-dnxhd-1080i b/tests/ref/fate/vsynth2-dnxhd-1080i
index 41a8d51..874e60b 100644
--- a/tests/ref/fate/vsynth2-dnxhd-1080i
+++ b/tests/ref/fate/vsynth2-dnxhd-1080i
@@ -1,4 +1,4 @@
-19a91b7da35cecf41e5e3cb322485627 *tests/data/fate/vsynth2-dnxhd-1080i.mov
-3031875 tests/data/fate/vsynth2-dnxhd-1080i.mov
-3c559af629ae0a8fb1a9a0e4b4da7733 *tests/data/fate/vsynth2-dnxhd-1080i.out.rawvideo
+93b878dcf8f2ecc9798d0e0885c9eec9 *tests/data/fate/vsynth2-dnxhd-1080i.mov
+3031911 tests/data/fate/vsynth2-dnxhd-1080i.mov
+27edc8dfe2ca19097c7f9119705b3a60 *tests/data/fate/vsynth2-dnxhd-1080i.out.rawvideo
 stddev:    1.31 PSNR: 45.77 MAXDIFF:   23 bytes:  7603200/   760320
diff --git a/tests/ref/fate/vsynth2-dnxhd-720p b/tests/ref/fate/vsynth2-dnxhd-720p
index afc6fde..0a8441b 100644
--- a/tests/ref/fate/vsynth2-dnxhd-720p
+++ b/tests/ref/fate/vsynth2-dnxhd-720p
@@ -1,4 +1,4 @@
-58e07cc6ae0a2d36787044d0e82708a6 *tests/data/fate/vsynth2-dnxhd-720p.dnxhd
+4ca9473a8d106bdfe36e9bf7c516b648 *tests/data/fate/vsynth2-dnxhd-720p.dnxhd
 2293760 tests/data/fate/vsynth2-dnxhd-720p.dnxhd
-ab601eaafef74d80d3d20b780dddd836 *tests/data/fate/vsynth2-dnxhd-720p.out.rawvideo
-stddev:    1.36 PSNR: 45.45 MAXDIFF:  127 bytes:  7603200/   760320
+d44c4b08cda8a8042ae345124fdfffcc *tests/data/fate/vsynth2-dnxhd-720p.out.rawvideo
+stddev:    1.32 PSNR: 45.68 MAXDIFF:   22 bytes:  7603200/   760320
diff --git a/tests/ref/fate/vsynth2-dnxhd-720p-10bit b/tests/ref/fate/vsynth2-dnxhd-720p-10bit
index f087c13..cf3ba7b 100644
--- a/tests/ref/fate/vsynth2-dnxhd-720p-10bit
+++ b/tests/ref/fate/vsynth2-dnxhd-720p-10bit
@@ -1,4 +1,4 @@
-4b57da2c0c1280469ff3579f7151c227 *tests/data/fate/vsynth2-dnxhd-720p-10bit.dnxhd
+e96fc4a7d994b9369c50da32fd325822 *tests/data/fate/vsynth2-dnxhd-720p-10bit.dnxhd
 2293760 tests/data/fate/vsynth2-dnxhd-720p-10bit.dnxhd
-31a6aa8b8702e85fa3b48e73f035c4e4 *tests/data/fate/vsynth2-dnxhd-720p-10bit.out.rawvideo
-stddev:    1.35 PSNR: 45.46 MAXDIFF:   23 bytes:  7603200/   760320
+a57ce32ab22ae60bf21655b0d1ba3b07 *tests/data/fate/vsynth2-dnxhd-720p-10bit.out.rawvideo
+stddev:    1.35 PSNR: 45.47 MAXDIFF:   22 bytes:  7603200/   760320
diff --git a/tests/ref/fate/vsynth2-dnxhd-720p-rd b/tests/ref/fate/vsynth2-dnxhd-720p-rd
index c1b8f96..5387ce5 100644
--- a/tests/ref/fate/vsynth2-dnxhd-720p-rd
+++ b/tests/ref/fate/vsynth2-dnxhd-720p-rd
@@ -1,4 +1,4 @@
-092ffb7b8cf3c11556bb05dbb8b476ac *tests/data/fate/vsynth2-dnxhd-720p-rd.dnxhd
+b305b03708e905717b42fc0b304367d4 *tests/data/fate/vsynth2-dnxhd-720p-rd.dnxhd
 2293760 tests/data/fate/vsynth2-dnxhd-720p-rd.dnxhd
-33547ca318acff9448cba719cb99296d *tests/data/fate/vsynth2-dnxhd-720p-rd.out.rawvideo
+13de1c5ed025abb5120450e134aa623d *tests/data/fate/vsynth2-dnxhd-720p-rd.out.rawvideo
 stddev:    1.32 PSNR: 45.66 MAXDIFF:   22 bytes:  7603200/   760320
diff --git a/tests/ref/fate/vsynth2-dnxhd_1080i b/tests/ref/fate/vsynth2-dnxhd_1080i
new file mode 100644
index 0000000..81ecc5e
--- /dev/null
+++ b/tests/ref/fate/vsynth2-dnxhd_1080i
@@ -0,0 +1,4 @@
+204e80f2e406ada90fca596ab2810b3e *./tests/data/vsynth2/dnxhd-1080i.mov
+3031911 ./tests/data/vsynth2/dnxhd-1080i.mov
+3c559af629ae0a8fb1a9a0e4b4da7733 *./tests/data/dnxhd_1080i.vsynth2.out.yuv
+stddev:    1.31 PSNR: 45.77 MAXDIFF:   23 bytes:   760320/  7603200
diff --git a/tests/ref/fate/vsynth2-dv b/tests/ref/fate/vsynth2-dv
index 2aac5ff..0d1465c 100644
--- a/tests/ref/fate/vsynth2-dv
+++ b/tests/ref/fate/vsynth2-dv
@@ -1,4 +1,4 @@
-bfa766f89bfeabc0ae1044f3954bed52 *tests/data/fate/vsynth2-dv.dv
+85b8d55b0b68bb3fc2e90babb580f9b7 *tests/data/fate/vsynth2-dv.dv
 7200000 tests/data/fate/vsynth2-dv.dv
 7ec62bd3350a6848364669e6e1e4b9cc *tests/data/fate/vsynth2-dv.out.rawvideo
 stddev:    1.71 PSNR: 43.47 MAXDIFF:   33 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-dv-411 b/tests/ref/fate/vsynth2-dv-411
index 00ecace..d0e6d29 100644
--- a/tests/ref/fate/vsynth2-dv-411
+++ b/tests/ref/fate/vsynth2-dv-411
@@ -1,4 +1,4 @@
-00a9d8683ac6826af41bcf7223fb0389 *tests/data/fate/vsynth2-dv-411.dv
+e428508f400327aeb96969c08fb9e1b5 *tests/data/fate/vsynth2-dv-411.dv
 7200000 tests/data/fate/vsynth2-dv-411.dv
 3cd4b85065d67bfb7fbab3bea4039711 *tests/data/fate/vsynth2-dv-411.out.rawvideo
 stddev:    2.89 PSNR: 38.91 MAXDIFF:   45 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-dv-50 b/tests/ref/fate/vsynth2-dv-50
index e7e5dc1..c5ac608 100644
--- a/tests/ref/fate/vsynth2-dv-50
+++ b/tests/ref/fate/vsynth2-dv-50
@@ -1,4 +1,4 @@
-61e31c79e8949b25c849753a0785b0d7 *tests/data/fate/vsynth2-dv-50.dv
+0032a07167199e6f49e07fa7ed4d5f62 *tests/data/fate/vsynth2-dv-50.dv
 14400000 tests/data/fate/vsynth2-dv-50.dv
 af3f2dd5ab62c1a1d98b07d4aeb6852f *tests/data/fate/vsynth2-dv-50.out.rawvideo
 stddev:    0.82 PSNR: 49.82 MAXDIFF:   12 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-dv_411 b/tests/ref/fate/vsynth2-dv_411
new file mode 100644
index 0000000..708ac88
--- /dev/null
+++ b/tests/ref/fate/vsynth2-dv_411
@@ -0,0 +1,4 @@
+e428508f400327aeb96969c08fb9e1b5 *./tests/data/vsynth2/dv411.dv
+7200000 ./tests/data/vsynth2/dv411.dv
+7f9fa421028aabb11eaf4c6513a5a843 *./tests/data/dv_411.vsynth2.out.yuv
+stddev:   10.09 PSNR: 28.05 MAXDIFF:   60 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-ffvhuff b/tests/ref/fate/vsynth2-ffvhuff
index 1b279aa..ac58147 100644
--- a/tests/ref/fate/vsynth2-ffvhuff
+++ b/tests/ref/fate/vsynth2-ffvhuff
@@ -1,4 +1,4 @@
-d31aab445b24f738df45fdd7479d6dd7 *tests/data/fate/vsynth2-ffvhuff.avi
+63926d8835dd5779dca0a4bc081ca8ae *tests/data/fate/vsynth2-ffvhuff.avi
 4988056 tests/data/fate/vsynth2-ffvhuff.avi
 dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-ffvhuff.out.rawvideo
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-flashsv b/tests/ref/fate/vsynth2-flashsv
index cbe79e6..e44fa8f 100644
--- a/tests/ref/fate/vsynth2-flashsv
+++ b/tests/ref/fate/vsynth2-flashsv
@@ -1,4 +1,4 @@
 0667077971e0cb63b5f49c580006e90e *tests/data/fate/vsynth2-flashsv.flv
 12368953 tests/data/fate/vsynth2-flashsv.flv
-592b3321994e26a990deb3a0a1415de9 *tests/data/fate/vsynth2-flashsv.out.rawvideo
-stddev:    0.65 PSNR: 51.84 MAXDIFF:   14 bytes:  7603200/  7603200
+3a984506f1ebfc9fb73b6814cab201cc *tests/data/fate/vsynth2-flashsv.out.rawvideo
+stddev:    0.66 PSNR: 51.73 MAXDIFF:   14 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-flashsv2 b/tests/ref/fate/vsynth2-flashsv2
new file mode 100644
index 0000000..d207a8b
--- /dev/null
+++ b/tests/ref/fate/vsynth2-flashsv2
@@ -0,0 +1,4 @@
+01e0aa4da9ccc8e12fd03df63625eea4 *tests/data/fate/vsynth2-flashsv2.flv
+9291162 tests/data/fate/vsynth2-flashsv2.flv
+8f63e24049ba1789a7f8353c695a3d99 *tests/data/fate/vsynth2-flashsv2.out.rawvideo
+stddev:    2.39 PSNR: 40.55 MAXDIFF:   21 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-flv b/tests/ref/fate/vsynth2-flv
index 6864a1b..ab31755 100644
--- a/tests/ref/fate/vsynth2-flv
+++ b/tests/ref/fate/vsynth2-flv
@@ -1,4 +1,4 @@
-2edc92093d36506bcc0a5c0e17e86113 *tests/data/fate/vsynth2-flv.flv
-131360 tests/data/fate/vsynth2-flv.flv
-8999c8264fb0941561f64c4a736e9d88 *tests/data/fate/vsynth2-flv.out.rawvideo
-stddev:    5.33 PSNR: 33.59 MAXDIFF:   80 bytes:  7603200/  7603200
+dee04bdab18c2eed81373faec89fd5a7 *tests/data/fate/vsynth2-flv.flv
+131380 tests/data/fate/vsynth2-flv.flv
+184034553ceb801bb1d1521d2d998a67 *tests/data/fate/vsynth2-flv.out.rawvideo
+stddev:    5.33 PSNR: 33.59 MAXDIFF:   79 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-h261 b/tests/ref/fate/vsynth2-h261
index 908e670..375c5c6 100644
--- a/tests/ref/fate/vsynth2-h261
+++ b/tests/ref/fate/vsynth2-h261
@@ -1,4 +1,4 @@
-dfd005d4c9030a0dc889c828a6408b9c *tests/data/fate/vsynth2-h261.avi
-191086 tests/data/fate/vsynth2-h261.avi
-db7ceff174823b98834faa2320ca89ac *tests/data/fate/vsynth2-h261.out.rawvideo
+3a11ad7fb9e953041f40d0e8fd0ff278 *tests/data/fate/vsynth2-h261.avi
+191072 tests/data/fate/vsynth2-h261.avi
+08f65e9aeeeaf189548c2bb417d5114f *tests/data/fate/vsynth2-h261.out.rawvideo
 stddev:    6.37 PSNR: 32.03 MAXDIFF:   77 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-h263 b/tests/ref/fate/vsynth2-h263
index 46169d7..47c86c5 100644
--- a/tests/ref/fate/vsynth2-h263
+++ b/tests/ref/fate/vsynth2-h263
@@ -1,4 +1,4 @@
-9a368687ab34c48079f11a202839a6bc *tests/data/fate/vsynth2-h263.avi
-160106 tests/data/fate/vsynth2-h263.avi
-61213b91b359697ebcefb9e0a53ac54a *tests/data/fate/vsynth2-h263.out.rawvideo
+dc956aec267ebed753c1284847f62e2e *tests/data/fate/vsynth2-h263.avi
+160114 tests/data/fate/vsynth2-h263.avi
+b7d733ebedbaa04f49bf7493a907e223 *tests/data/fate/vsynth2-h263.out.rawvideo
 stddev:    5.43 PSNR: 33.42 MAXDIFF:   77 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-h263-obmc b/tests/ref/fate/vsynth2-h263-obmc
index 32c2341..d8a65db 100644
--- a/tests/ref/fate/vsynth2-h263-obmc
+++ b/tests/ref/fate/vsynth2-h263-obmc
@@ -1,4 +1,4 @@
-0c84ee18c2261070ffc91b5d606094ae *tests/data/fate/vsynth2-h263-obmc.avi
-154728 tests/data/fate/vsynth2-h263-obmc.avi
-6f326547cf1cbd95a8c0a5ddce9eb71a *tests/data/fate/vsynth2-h263-obmc.out.rawvideo
+482d48074d94ed72b0c7057b9c129b45 *tests/data/fate/vsynth2-h263-obmc.avi
+154738 tests/data/fate/vsynth2-h263-obmc.avi
+588d992d9d8096da8bdc5027268da914 *tests/data/fate/vsynth2-h263-obmc.out.rawvideo
 stddev:    5.39 PSNR: 33.49 MAXDIFF:   82 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-h263p b/tests/ref/fate/vsynth2-h263p
index 6e45957..2920d7a 100644
--- a/tests/ref/fate/vsynth2-h263p
+++ b/tests/ref/fate/vsynth2-h263p
@@ -1,4 +1,4 @@
-c7644d40e9f40bbd98e5a978f9f94bb4 *tests/data/fate/vsynth2-h263p.avi
-868018 tests/data/fate/vsynth2-h263p.avi
-4b0ee791f280029dc03c528f76f195d4 *tests/data/fate/vsynth2-h263p.out.rawvideo
+628d3df9dad01c2da648f4cdc31ef62d *tests/data/fate/vsynth2-h263p.avi
+868010 tests/data/fate/vsynth2-h263p.avi
+dca18571c05c13dd691d7b0b232e43fc *tests/data/fate/vsynth2-h263p.out.rawvideo
 stddev:    1.91 PSNR: 42.50 MAXDIFF:   19 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-huffyuv b/tests/ref/fate/vsynth2-huffyuv
index a1c3c22..d94cbd6 100644
--- a/tests/ref/fate/vsynth2-huffyuv
+++ b/tests/ref/fate/vsynth2-huffyuv
@@ -1,4 +1,4 @@
-56cd44907a48990e06bd065e189ff461 *tests/data/fate/vsynth2-huffyuv.avi
+ed66182be0d515e8b6cb970ad63162da *tests/data/fate/vsynth2-huffyuv.avi
 6455232 tests/data/fate/vsynth2-huffyuv.avi
 dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-huffyuv.out.rawvideo
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-j2k b/tests/ref/fate/vsynth2-j2k
new file mode 100644
index 0000000..1ad4482
--- /dev/null
+++ b/tests/ref/fate/vsynth2-j2k
@@ -0,0 +1,4 @@
+b30dc1851c0fb37726d977ec1d5ad527 *tests/data/fate/vsynth2-j2k.avi
+1151156 tests/data/fate/vsynth2-j2k.avi
+ec5218eec33a021945c28c72093382a5 *tests/data/fate/vsynth2-j2k.out.rawvideo
+stddev:    4.54 PSNR: 34.99 MAXDIFF:   61 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-jpegls b/tests/ref/fate/vsynth2-jpegls
index 7f17391..728d54f 100644
--- a/tests/ref/fate/vsynth2-jpegls
+++ b/tests/ref/fate/vsynth2-jpegls
@@ -1,4 +1,4 @@
 8a94dc94b6df8bdde9a639246351d816 *tests/data/fate/vsynth2-jpegls.avi
 8334630 tests/data/fate/vsynth2-jpegls.avi
-592b3321994e26a990deb3a0a1415de9 *tests/data/fate/vsynth2-jpegls.out.rawvideo
-stddev:    0.65 PSNR: 51.84 MAXDIFF:   14 bytes:  7603200/  7603200
+3a984506f1ebfc9fb73b6814cab201cc *tests/data/fate/vsynth2-jpegls.out.rawvideo
+stddev:    0.66 PSNR: 51.73 MAXDIFF:   14 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mjpeg b/tests/ref/fate/vsynth2-mjpeg
index e7649ff..c823c42 100644
--- a/tests/ref/fate/vsynth2-mjpeg
+++ b/tests/ref/fate/vsynth2-mjpeg
@@ -1,4 +1,4 @@
-89df32b46c977fb4cb140ec6c489dd76 *tests/data/fate/vsynth2-mjpeg.avi
-673224 tests/data/fate/vsynth2-mjpeg.avi
-a96a4e15ffcb13e44360df642d049496 *tests/data/fate/vsynth2-mjpeg.out.rawvideo
+fb05e46b8c69ad1f00d3d15cf4be6cee *tests/data/fate/vsynth2-mjpeg.avi
+673186 tests/data/fate/vsynth2-mjpeg.avi
+9d4bd90e9abfa18192383b4adc23c8d4 *tests/data/fate/vsynth2-mjpeg.out.rawvideo
 stddev:    4.32 PSNR: 35.40 MAXDIFF:   49 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpeg1 b/tests/ref/fate/vsynth2-mpeg1
index a975973..bc94fbc 100644
--- a/tests/ref/fate/vsynth2-mpeg1
+++ b/tests/ref/fate/vsynth2-mpeg1
@@ -1,4 +1,4 @@
-73ca6f1deab02d1d67a0e8495c026a9e *tests/data/fate/vsynth2-mpeg1.mpeg1video
-192783 tests/data/fate/vsynth2-mpeg1.mpeg1video
-56147e94b12f08df7213e610e177823d *tests/data/fate/vsynth2-mpeg1.out.rawvideo
+c6f1a98dd7201b1e5d7f0f69d7e9577d *tests/data/fate/vsynth2-mpeg1.mpeg1video
+192794 tests/data/fate/vsynth2-mpeg1.mpeg1video
+b3584042c60385e0fb988b8ec5b36409 *tests/data/fate/vsynth2-mpeg1.out.rawvideo
 stddev:    4.95 PSNR: 34.22 MAXDIFF:   57 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpeg1b b/tests/ref/fate/vsynth2-mpeg1b
index 4b92ac5..f4864a5 100644
--- a/tests/ref/fate/vsynth2-mpeg1b
+++ b/tests/ref/fate/vsynth2-mpeg1b
@@ -1,4 +1,4 @@
-e026a2fef80c9679776d2b5c8be09338 *tests/data/fate/vsynth2-mpeg1b.mpeg1video
-225198 tests/data/fate/vsynth2-mpeg1b.mpeg1video
-1150495f4bd487486ee53326c42d0bb8 *tests/data/fate/vsynth2-mpeg1b.out.rawvideo
+8300bede250c3987f1c5bc9bbd1d78e1 *tests/data/fate/vsynth2-mpeg1b.mpeg1video
+225201 tests/data/fate/vsynth2-mpeg1b.mpeg1video
+f17fb3eef4ed3d03eeaaee45b217f7a5 *tests/data/fate/vsynth2-mpeg1b.out.rawvideo
 stddev:    4.10 PSNR: 35.86 MAXDIFF:   59 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpeg2 b/tests/ref/fate/vsynth2-mpeg2
index a2a2ca6..b5f5af9 100644
--- a/tests/ref/fate/vsynth2-mpeg2
+++ b/tests/ref/fate/vsynth2-mpeg2
@@ -1,4 +1,4 @@
-2d55ce623a7be4e8136f80266e487678 *tests/data/fate/vsynth2-mpeg2.mpeg2video
-198667 tests/data/fate/vsynth2-mpeg2.mpeg2video
-b7cae8a1f751b821cddcbe4d5dbc518c *tests/data/fate/vsynth2-mpeg2.out.rawvideo
+81fc934ad6901b6c37a59b94ccda8de7 *tests/data/fate/vsynth2-mpeg2.mpeg2video
+198673 tests/data/fate/vsynth2-mpeg2.mpeg2video
+9efe4846a75d9b7387d1e3bb1e5db29a *tests/data/fate/vsynth2-mpeg2.out.rawvideo
 stddev:    4.96 PSNR: 34.20 MAXDIFF:   59 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpeg2-422 b/tests/ref/fate/vsynth2-mpeg2-422
index 2405cf0..14d751b 100644
--- a/tests/ref/fate/vsynth2-mpeg2-422
+++ b/tests/ref/fate/vsynth2-mpeg2-422
@@ -1,4 +1,4 @@
-2c8e33c2d2efab86fc16a195f6877682 *tests/data/fate/vsynth2-mpeg2-422.mpeg2video
-356124 tests/data/fate/vsynth2-mpeg2-422.mpeg2video
-df6e54e2d8a4feb8382029286857ca6d *tests/data/fate/vsynth2-mpeg2-422.out.rawvideo
-stddev:    3.16 PSNR: 38.13 MAXDIFF:   49 bytes:  7603200/  7603200
+99ba26ba009e0172855a9dadaefef2d9 *tests/data/fate/vsynth2-mpeg2-422.mpeg2video
+356431 tests/data/fate/vsynth2-mpeg2-422.mpeg2video
+51ca353620f85db8b5b1c56f1a275add *tests/data/fate/vsynth2-mpeg2-422.out.rawvideo
+stddev:    3.15 PSNR: 38.14 MAXDIFF:   49 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpeg2-ilace b/tests/ref/fate/vsynth2-mpeg2-ilace
index e488bc5..2f9a306 100644
--- a/tests/ref/fate/vsynth2-mpeg2-ilace
+++ b/tests/ref/fate/vsynth2-mpeg2-ilace
@@ -1,4 +1,4 @@
-f90197a8b6e62ae25f82625337f27240 *tests/data/fate/vsynth2-mpeg2-ilace.mpeg2video
-204579 tests/data/fate/vsynth2-mpeg2-ilace.mpeg2video
-ea5057b60146c06d40449cdfc686bf13 *tests/data/fate/vsynth2-mpeg2-ilace.out.rawvideo
+a6f4c4dbd7f73b73e876fbd7a9650610 *tests/data/fate/vsynth2-mpeg2-ilace.mpeg2video
+204576 tests/data/fate/vsynth2-mpeg2-ilace.mpeg2video
+d69be0d4ba1cb9c1fef9fb0d94a912ba *tests/data/fate/vsynth2-mpeg2-ilace.out.rawvideo
 stddev:    4.98 PSNR: 34.18 MAXDIFF:   65 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpeg2-thread b/tests/ref/fate/vsynth2-mpeg2-thread
index f43cdbc..40552fe 100644
--- a/tests/ref/fate/vsynth2-mpeg2-thread
+++ b/tests/ref/fate/vsynth2-mpeg2-thread
@@ -1,4 +1,4 @@
-889c754a42d7689b228853e1ece6d345 *tests/data/fate/vsynth2-mpeg2-thread.mpeg2video
-179650 tests/data/fate/vsynth2-mpeg2-thread.mpeg2video
-8c6a7ed2eb73bd18fd2bb9829464100d *tests/data/fate/vsynth2-mpeg2-thread.out.rawvideo
+38af1e2261ae363abea5818db74ea241 *tests/data/fate/vsynth2-mpeg2-thread.mpeg2video
+179656 tests/data/fate/vsynth2-mpeg2-thread.mpeg2video
+f8f084b7f51fbe4f82d57b8aeec17edf *tests/data/fate/vsynth2-mpeg2-thread.out.rawvideo
 stddev:    4.72 PSNR: 34.65 MAXDIFF:   72 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpeg2-thread-ivlc b/tests/ref/fate/vsynth2-mpeg2-thread-ivlc
index 2c42a21..9bcac8b 100644
--- a/tests/ref/fate/vsynth2-mpeg2-thread-ivlc
+++ b/tests/ref/fate/vsynth2-mpeg2-thread-ivlc
@@ -1,4 +1,4 @@
-10b900e32809758857c596d56746e00e *tests/data/fate/vsynth2-mpeg2-thread-ivlc.mpeg2video
-178801 tests/data/fate/vsynth2-mpeg2-thread-ivlc.mpeg2video
-8c6a7ed2eb73bd18fd2bb9829464100d *tests/data/fate/vsynth2-mpeg2-thread-ivlc.out.rawvideo
+9cb6b65e05fa854da2ad08b34fe032aa *tests/data/fate/vsynth2-mpeg2-thread-ivlc.mpeg2video
+178807 tests/data/fate/vsynth2-mpeg2-thread-ivlc.mpeg2video
+f8f084b7f51fbe4f82d57b8aeec17edf *tests/data/fate/vsynth2-mpeg2-thread-ivlc.out.rawvideo
 stddev:    4.72 PSNR: 34.65 MAXDIFF:   72 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4 b/tests/ref/fate/vsynth2-mpeg4
index 4d96557..399ef58 100644
--- a/tests/ref/fate/vsynth2-mpeg4
+++ b/tests/ref/fate/vsynth2-mpeg4
@@ -1,4 +1,4 @@
-8c9afbf564008a8ce6719cc3546deae1 *tests/data/fate/vsynth2-mpeg4.mp4
-119833 tests/data/fate/vsynth2-mpeg4.mp4
-90a3577850239083a9042bef33c50e85 *tests/data/fate/vsynth2-mpeg4.out.rawvideo
+04f74c54f4db25e1d454ede9216632c1 *tests/data/fate/vsynth2-mpeg4.mp4
+119661 tests/data/fate/vsynth2-mpeg4.mp4
+9a1e085d9e488c5ead0c940c9612a37a *tests/data/fate/vsynth2-mpeg4.out.rawvideo
 stddev:    5.34 PSNR: 33.57 MAXDIFF:   83 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4-adap b/tests/ref/fate/vsynth2-mpeg4-adap
index d2f3bd1..0209cce 100644
--- a/tests/ref/fate/vsynth2-mpeg4-adap
+++ b/tests/ref/fate/vsynth2-mpeg4-adap
@@ -1,4 +1,4 @@
-547e1849dcf910935ff6383ca49e5706 *tests/data/fate/vsynth2-mpeg4-adap.avi
-198510 tests/data/fate/vsynth2-mpeg4-adap.avi
-4affb83f6adc94f31024b4f9e0168945 *tests/data/fate/vsynth2-mpeg4-adap.out.rawvideo
+d1683da1db86ec4365a9629ca764951f *tests/data/fate/vsynth2-mpeg4-adap.avi
+198508 tests/data/fate/vsynth2-mpeg4-adap.avi
+87b6dbe98d276137fceaae2fa672eced *tests/data/fate/vsynth2-mpeg4-adap.out.rawvideo
 stddev:    3.75 PSNR: 36.65 MAXDIFF:   71 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4-error b/tests/ref/fate/vsynth2-mpeg4-error
index a3f4453..eb9fc37 100644
--- a/tests/ref/fate/vsynth2-mpeg4-error
+++ b/tests/ref/fate/vsynth2-mpeg4-error
@@ -1,4 +1,4 @@
-90e65096aa9ebafa3fe3f44a5a47cdc4 *tests/data/fate/vsynth2-mpeg4-error.avi
-176588 tests/data/fate/vsynth2-mpeg4-error.avi
-96baa9e4c24c837a3ba5abd8dd2cdd30 *tests/data/fate/vsynth2-mpeg4-error.out.rawvideo
-stddev:    8.98 PSNR: 29.06 MAXDIFF:  184 bytes:  7603200/  7603200
+ee46af7cbbb9c7c03311e2143190fb20 *tests/data/fate/vsynth2-mpeg4-error.avi
+180376 tests/data/fate/vsynth2-mpeg4-error.avi
+4537ba5320f1ae0971cc6e329c366776 *tests/data/fate/vsynth2-mpeg4-error.out.rawvideo
+stddev:    7.65 PSNR: 30.45 MAXDIFF:  158 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4-nr b/tests/ref/fate/vsynth2-mpeg4-nr
index 752b504..0a1194a 100644
--- a/tests/ref/fate/vsynth2-mpeg4-nr
+++ b/tests/ref/fate/vsynth2-mpeg4-nr
@@ -1,4 +1,4 @@
-c41187c99588fb7229ad330b2f80d28b *tests/data/fate/vsynth2-mpeg4-nr.avi
-155044 tests/data/fate/vsynth2-mpeg4-nr.avi
-f7fc191308679f709405e62271f5c65f *tests/data/fate/vsynth2-mpeg4-nr.out.rawvideo
+a42042b1a2d3f4577d6293fc0dd077cb *tests/data/fate/vsynth2-mpeg4-nr.avi
+155006 tests/data/fate/vsynth2-mpeg4-nr.avi
+d89cd5d0b1707f48fa9c4747c66d2d56 *tests/data/fate/vsynth2-mpeg4-nr.out.rawvideo
 stddev:    4.73 PSNR: 34.63 MAXDIFF:   64 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4-qpel b/tests/ref/fate/vsynth2-mpeg4-qpel
index 3cba30d..0869eda 100644
--- a/tests/ref/fate/vsynth2-mpeg4-qpel
+++ b/tests/ref/fate/vsynth2-mpeg4-qpel
@@ -1,4 +1,4 @@
-7680d2e7d34399dfdfb8a49cf1e10239 *tests/data/fate/vsynth2-mpeg4-qpel.avi
-163688 tests/data/fate/vsynth2-mpeg4-qpel.avi
-26dc7c78955fa678fbf150e236eb5627 *tests/data/fate/vsynth2-mpeg4-qpel.out.rawvideo
+0e0aaf9c114eb8c60a4083b8a98ea7c7 *tests/data/fate/vsynth2-mpeg4-qpel.avi
+163674 tests/data/fate/vsynth2-mpeg4-qpel.avi
+e2ce994dbb66da51c2e1ad26617d7c2f *tests/data/fate/vsynth2-mpeg4-qpel.out.rawvideo
 stddev:    3.97 PSNR: 36.14 MAXDIFF:   54 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4-qprd b/tests/ref/fate/vsynth2-mpeg4-qprd
index 87f5e02..8e69b3e 100644
--- a/tests/ref/fate/vsynth2-mpeg4-qprd
+++ b/tests/ref/fate/vsynth2-mpeg4-qprd
@@ -1,4 +1,4 @@
-fd5ab0f55dbc959316e32923e86290df *tests/data/fate/vsynth2-mpeg4-qprd.avi
-231458 tests/data/fate/vsynth2-mpeg4-qprd.avi
-de8a883865e2dff7a51f66da6c48df48 *tests/data/fate/vsynth2-mpeg4-qprd.out.rawvideo
+5aca88f3b6036515a1cdd41647395dc2 *tests/data/fate/vsynth2-mpeg4-qprd.avi
+231462 tests/data/fate/vsynth2-mpeg4-qprd.avi
+3071250e0864546c2455c9f9c9b8604e *tests/data/fate/vsynth2-mpeg4-qprd.out.rawvideo
 stddev:    3.71 PSNR: 36.72 MAXDIFF:   61 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4-rc b/tests/ref/fate/vsynth2-mpeg4-rc
index bdd897b..4401f92 100644
--- a/tests/ref/fate/vsynth2-mpeg4-rc
+++ b/tests/ref/fate/vsynth2-mpeg4-rc
@@ -1,4 +1,4 @@
-c25ede9e268b834a09a63f5136cd1b95 *tests/data/fate/vsynth2-mpeg4-rc.avi
-226332 tests/data/fate/vsynth2-mpeg4-rc.avi
-2b34e606af895b62a250de98749a19b0 *tests/data/fate/vsynth2-mpeg4-rc.out.rawvideo
+8e4101a166eee52093ed687c62764d5e *tests/data/fate/vsynth2-mpeg4-rc.avi
+226322 tests/data/fate/vsynth2-mpeg4-rc.avi
+6e8b62e8c3bcbfdcc58afb69a0b1c4e3 *tests/data/fate/vsynth2-mpeg4-rc.out.rawvideo
 stddev:    4.23 PSNR: 35.60 MAXDIFF:   85 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpeg4-thread b/tests/ref/fate/vsynth2-mpeg4-thread
index e004009..664f89e 100644
--- a/tests/ref/fate/vsynth2-mpeg4-thread
+++ b/tests/ref/fate/vsynth2-mpeg4-thread
@@ -1,4 +1,4 @@
-ba30d10ff70d46e7c5b7fa859ea1faa4 *tests/data/fate/vsynth2-mpeg4-thread.avi
-250140 tests/data/fate/vsynth2-mpeg4-thread.avi
-5355deb8c7609a3f1ff2173aab1dee70 *tests/data/fate/vsynth2-mpeg4-thread.out.rawvideo
+9859aa7d322b639b07386980bc3f4797 *tests/data/fate/vsynth2-mpeg4-thread.avi
+250104 tests/data/fate/vsynth2-mpeg4-thread.avi
+045fe9f226bbcc3d41644bffaed03b31 *tests/data/fate/vsynth2-mpeg4-thread.out.rawvideo
 stddev:    3.69 PSNR: 36.78 MAXDIFF:   65 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-mpng b/tests/ref/fate/vsynth2-mpng
new file mode 100644
index 0000000..1a298f9
--- /dev/null
+++ b/tests/ref/fate/vsynth2-mpng
@@ -0,0 +1,4 @@
+198a3d67c56e1b5b12bdd3ffa67d8128 *tests/data/fate/vsynth2-mpng.avi
+12557288 tests/data/fate/vsynth2-mpng.avi
+98d0e2854731472c5bf13d8638502d0a *tests/data/fate/vsynth2-mpng.out.rawvideo
+stddev:    1.26 PSNR: 46.10 MAXDIFF:   13 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-msmpeg4 b/tests/ref/fate/vsynth2-msmpeg4
index c65a9af..0656101 100644
--- a/tests/ref/fate/vsynth2-msmpeg4
+++ b/tests/ref/fate/vsynth2-msmpeg4
@@ -1,4 +1,4 @@
-26dee25a62a66daba4f38ac6bd8f4677 *tests/data/fate/vsynth2-msmpeg4.avi
-127680 tests/data/fate/vsynth2-msmpeg4.avi
-0e1c6e25c71c6a8fa8e506e3d97ca4c9 *tests/data/fate/vsynth2-msmpeg4.out.rawvideo
-stddev:    5.33 PSNR: 33.59 MAXDIFF:   78 bytes:  7603200/  7603200
+cc347c58bf116cdb09b0ce1d549fa989 *tests/data/fate/vsynth2-msmpeg4.avi
+127672 tests/data/fate/vsynth2-msmpeg4.avi
+bb14902d5850d6b0ab70fdb017855775 *tests/data/fate/vsynth2-msmpeg4.out.rawvideo
+stddev:    5.33 PSNR: 33.58 MAXDIFF:   78 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-msmpeg4v2 b/tests/ref/fate/vsynth2-msmpeg4v2
index d2b63d8..fe9cc4c 100644
--- a/tests/ref/fate/vsynth2-msmpeg4v2
+++ b/tests/ref/fate/vsynth2-msmpeg4v2
@@ -1,4 +1,4 @@
-c09815e40a9d260628e1ebad8b2b3774 *tests/data/fate/vsynth2-msmpeg4v2.avi
-129918 tests/data/fate/vsynth2-msmpeg4v2.avi
-8920194f8bf8f9cdd6c65b3df9e1a292 *tests/data/fate/vsynth2-msmpeg4v2.out.rawvideo
-stddev:    5.33 PSNR: 33.59 MAXDIFF:   80 bytes:  7603200/  7603200
+dc94a157743f7439b15e69d6a0737b8a *tests/data/fate/vsynth2-msmpeg4v2.avi
+129930 tests/data/fate/vsynth2-msmpeg4v2.avi
+537c114e1d47c54a4bccd31f4073e9bd *tests/data/fate/vsynth2-msmpeg4v2.out.rawvideo
+stddev:    5.33 PSNR: 33.59 MAXDIFF:   79 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-msvideo1 b/tests/ref/fate/vsynth2-msvideo1
new file mode 100644
index 0000000..8338ac4
--- /dev/null
+++ b/tests/ref/fate/vsynth2-msvideo1
@@ -0,0 +1,4 @@
+e70658b8b97eb4c7e63b2081c3a602de *tests/data/fate/vsynth2-msvideo1.avi
+1259308 tests/data/fate/vsynth2-msvideo1.avi
+cd83ffcbc73573044e3aead3094229e5 *tests/data/fate/vsynth2-msvideo1.out.rawvideo
+stddev:    7.42 PSNR: 30.72 MAXDIFF:  123 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-prores b/tests/ref/fate/vsynth2-prores
index 9a834ed..089fc6c 100644
--- a/tests/ref/fate/vsynth2-prores
+++ b/tests/ref/fate/vsynth2-prores
@@ -1,4 +1,4 @@
-28755ce05e812adbb8b7c180318ffba8 *tests/data/fate/vsynth2-prores.mov
-3884722 tests/data/fate/vsynth2-prores.mov
-ca2f6c1162635dedfa468c90f1fdc0ef *tests/data/fate/vsynth2-prores.out.rawvideo
-stddev:    0.92 PSNR: 48.77 MAXDIFF:   10 bytes:  7603200/  7603200
+2fb771b09172b82d045772b60084c923 *tests/data/fate/vsynth2-prores.mov
+2844066 tests/data/fate/vsynth2-prores.mov
+b5844025c0f4c7c37db702c3213db232 *tests/data/fate/vsynth2-prores.out.rawvideo
+stddev:    1.31 PSNR: 45.77 MAXDIFF:   11 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-prores_kostya b/tests/ref/fate/vsynth2-prores_kostya
new file mode 100644
index 0000000..3566f1d
--- /dev/null
+++ b/tests/ref/fate/vsynth2-prores_kostya
@@ -0,0 +1,4 @@
+fcfd0e077ed36d46719d34248c0d6281 *tests/data/fate/vsynth2-prores_kostya.mov
+3884586 tests/data/fate/vsynth2-prores_kostya.mov
+ca2f6c1162635dedfa468c90f1fdc0ef *tests/data/fate/vsynth2-prores_kostya.out.rawvideo
+stddev:    0.92 PSNR: 48.77 MAXDIFF:   10 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-qtrle b/tests/ref/fate/vsynth2-qtrle
index ceee854..b29b7cc 100644
--- a/tests/ref/fate/vsynth2-qtrle
+++ b/tests/ref/fate/vsynth2-qtrle
@@ -1,4 +1,4 @@
-4805f35ca6e03b9279cc18f3f7356366 *tests/data/fate/vsynth2-qtrle.mov
-14798419 tests/data/fate/vsynth2-qtrle.mov
-b2418e0e3a9a8619b31219cbcf24dc82 *tests/data/fate/vsynth2-qtrle.out.rawvideo
-stddev:    1.26 PSNR: 46.06 MAXDIFF:   13 bytes:  7603200/  7603200
+7ff87d3858b742ef2d72a7dd12dea019 *tests/data/fate/vsynth2-qtrle.mov
+14798335 tests/data/fate/vsynth2-qtrle.mov
+98d0e2854731472c5bf13d8638502d0a *tests/data/fate/vsynth2-qtrle.out.rawvideo
+stddev:    1.26 PSNR: 46.10 MAXDIFF:   13 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-qtrlegray b/tests/ref/fate/vsynth2-qtrlegray
new file mode 100644
index 0000000..6fa35d1
--- /dev/null
+++ b/tests/ref/fate/vsynth2-qtrlegray
@@ -0,0 +1,4 @@
+4d4eac9e7258dde5fbafe931c4bdca59 *tests/data/fate/vsynth2-qtrlegray.mov
+5111273 tests/data/fate/vsynth2-qtrlegray.mov
+f63b5ebdfdba750e547c25131b0a3fd1 *tests/data/fate/vsynth2-qtrlegray.out.rawvideo
+stddev:   19.42 PSNR: 22.36 MAXDIFF:   72 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-r210 b/tests/ref/fate/vsynth2-r210
new file mode 100644
index 0000000..610ba2c
--- /dev/null
+++ b/tests/ref/fate/vsynth2-r210
@@ -0,0 +1,4 @@
+d7a6f298e6869a74c0988fc3b30d0351 *tests/data/fate/vsynth2-r210.avi
+22125260 tests/data/fate/vsynth2-r210.avi
+6ea4fcd93fc83defc8770e85b64b60bb *tests/data/fate/vsynth2-r210.out.rawvideo
+stddev:    0.70 PSNR: 51.12 MAXDIFF:   12 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-rgb b/tests/ref/fate/vsynth2-rgb
index 36ac105..c89f46f 100644
--- a/tests/ref/fate/vsynth2-rgb
+++ b/tests/ref/fate/vsynth2-rgb
@@ -1,4 +1,4 @@
 f2e9c419023c743bf99aa5b2e55ad233 *tests/data/fate/vsynth2-rgb.avi
 15213260 tests/data/fate/vsynth2-rgb.avi
-b2418e0e3a9a8619b31219cbcf24dc82 *tests/data/fate/vsynth2-rgb.out.rawvideo
-stddev:    1.26 PSNR: 46.06 MAXDIFF:   13 bytes:  7603200/  7603200
+98d0e2854731472c5bf13d8638502d0a *tests/data/fate/vsynth2-rgb.out.rawvideo
+stddev:    1.26 PSNR: 46.10 MAXDIFF:   13 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-rv10 b/tests/ref/fate/vsynth2-rv10
index 7afe4fc..3fc93d9 100644
--- a/tests/ref/fate/vsynth2-rv10
+++ b/tests/ref/fate/vsynth2-rv10
@@ -1,4 +1,4 @@
-b1467b0e8d8cad730e36d1e8ab49d573 *tests/data/fate/vsynth2-rv10.rm
-154310 tests/data/fate/vsynth2-rv10.rm
-61213b91b359697ebcefb9e0a53ac54a *tests/data/fate/vsynth2-rv10.out.rawvideo
+33a2aae3351b0b2121f823057c0e226f *tests/data/fate/vsynth2-rv10.rm
+154321 tests/data/fate/vsynth2-rv10.rm
+b7d733ebedbaa04f49bf7493a907e223 *tests/data/fate/vsynth2-rv10.out.rawvideo
 stddev:    5.43 PSNR: 33.42 MAXDIFF:   77 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-rv20 b/tests/ref/fate/vsynth2-rv20
index a3440fa..1251e49 100644
--- a/tests/ref/fate/vsynth2-rv20
+++ b/tests/ref/fate/vsynth2-rv20
@@ -1,4 +1,4 @@
-96acb098850b9bf309f89e48b08fe96f *tests/data/fate/vsynth2-rv20.rm
-153302 tests/data/fate/vsynth2-rv20.rm
-46f314e70d9bac2e7d82cfc230534977 *tests/data/fate/vsynth2-rv20.out.rawvideo
+4d23a72fe7e29f98f38888804eacd111 *tests/data/fate/vsynth2-rv20.rm
+153304 tests/data/fate/vsynth2-rv20.rm
+6fa5dc1c2f00f858fc4895ad640891a2 *tests/data/fate/vsynth2-rv20.out.rawvideo
 stddev:    5.48 PSNR: 33.35 MAXDIFF:   81 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-svq1 b/tests/ref/fate/vsynth2-svq1
index 251f72d..ec9cf88 100644
--- a/tests/ref/fate/vsynth2-svq1
+++ b/tests/ref/fate/vsynth2-svq1
@@ -1,4 +1,4 @@
-138ad38281570f1a3b68d63ed896435d *tests/data/fate/vsynth2-svq1.mov
-766851 tests/data/fate/vsynth2-svq1.mov
+c0a8f7e727a521ff3c1f6f9bd163e63d *tests/data/fate/vsynth2-svq1.mov
+766691 tests/data/fate/vsynth2-svq1.mov
 aa03471dac3f49455a33a2b19fda1098 *tests/data/fate/vsynth2-svq1.out.rawvideo
 stddev:    3.23 PSNR: 37.93 MAXDIFF:   61 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-v308 b/tests/ref/fate/vsynth2-v308
new file mode 100644
index 0000000..cd20214
--- /dev/null
+++ b/tests/ref/fate/vsynth2-v308
@@ -0,0 +1,4 @@
+214671673e6c82bad8190d0329f01fdc *tests/data/fate/vsynth2-v308.avi
+15213260 tests/data/fate/vsynth2-v308.avi
+d43cb310c130c69214332d74f6ee5f9a *tests/data/fate/vsynth2-v308.out.rawvideo
+stddev:    0.41 PSNR: 55.80 MAXDIFF:    7 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-v408 b/tests/ref/fate/vsynth2-v408
new file mode 100644
index 0000000..8d12fc7
--- /dev/null
+++ b/tests/ref/fate/vsynth2-v408
@@ -0,0 +1,4 @@
+033d112ec5a1a78882233d0b791e5ef7 *tests/data/fate/vsynth2-v408.avi
+20282060 tests/data/fate/vsynth2-v408.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-v408.out.rawvideo
+stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-wmv1 b/tests/ref/fate/vsynth2-wmv1
index 4545d42..7eb0fe6 100644
--- a/tests/ref/fate/vsynth2-wmv1
+++ b/tests/ref/fate/vsynth2-wmv1
@@ -1,4 +1,4 @@
-1011e26e7d351c96d7bbfe106d831b69 *tests/data/fate/vsynth2-wmv1.avi
-129530 tests/data/fate/vsynth2-wmv1.avi
-81eee429b665254d19a06607463c0b5e *tests/data/fate/vsynth2-wmv1.out.rawvideo
+0eef8e6c0bddcd7b60564e0dfcbcf461 *tests/data/fate/vsynth2-wmv1.avi
+129522 tests/data/fate/vsynth2-wmv1.avi
+dec44e3c04db4fef49a7728f164d9159 *tests/data/fate/vsynth2-wmv1.out.rawvideo
 stddev:    5.33 PSNR: 33.60 MAXDIFF:   77 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-wmv2 b/tests/ref/fate/vsynth2-wmv2
index a7384ad..8d55a47 100644
--- a/tests/ref/fate/vsynth2-wmv2
+++ b/tests/ref/fate/vsynth2-wmv2
@@ -1,4 +1,4 @@
-1f6598e9776ed00aebdc44cc8d48cb7c *tests/data/fate/vsynth2-wmv2.avi
-129860 tests/data/fate/vsynth2-wmv2.avi
-81eee429b665254d19a06607463c0b5e *tests/data/fate/vsynth2-wmv2.out.rawvideo
+c68ca99473538064d9de3bdcc8f2e759 *tests/data/fate/vsynth2-wmv2.avi
+129846 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
diff --git a/tests/ref/fate/vsynth2-y41p b/tests/ref/fate/vsynth2-y41p
new file mode 100644
index 0000000..b310e3b
--- /dev/null
+++ b/tests/ref/fate/vsynth2-y41p
@@ -0,0 +1,4 @@
+8e0139963e79180a0fc1c154e36cebe5 *tests/data/fate/vsynth2-y41p.avi
+7610060 tests/data/fate/vsynth2-y41p.avi
+d27a84ccdac09055724d122e03fea82a *tests/data/fate/vsynth2-y41p.out.rawvideo
+stddev:    1.07 PSNR: 47.54 MAXDIFF:   21 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-yuv b/tests/ref/fate/vsynth2-yuv
index a2332e0..e5409b0 100644
--- a/tests/ref/fate/vsynth2-yuv
+++ b/tests/ref/fate/vsynth2-yuv
@@ -1,4 +1,4 @@
-30a400773ab26f2c83e469198b156f1d *tests/data/fate/vsynth2-yuv.avi
+3d5ee6d2023bc15bba898819e4977e46 *tests/data/fate/vsynth2-yuv.avi
 7610060 tests/data/fate/vsynth2-yuv.avi
 dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-yuv.out.rawvideo
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-yuv4 b/tests/ref/fate/vsynth2-yuv4
new file mode 100644
index 0000000..a5e9ee5
--- /dev/null
+++ b/tests/ref/fate/vsynth2-yuv4
@@ -0,0 +1,4 @@
+3d24f1d320c4ead1efbf3c952a902379 *tests/data/fate/vsynth2-yuv4.avi
+7610060 tests/data/fate/vsynth2-yuv4.avi
+dde5895817ad9d219f79a52d0bdfb001 *tests/data/fate/vsynth2-yuv4.out.rawvideo
+stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-zlib b/tests/ref/fate/vsynth2-zlib
new file mode 100644
index 0000000..d3295e3
--- /dev/null
+++ b/tests/ref/fate/vsynth2-zlib
@@ -0,0 +1,4 @@
+f4bfa774c853abe8f06a29596c1f16cb *tests/data/fate/vsynth2-zlib.avi
+12517188 tests/data/fate/vsynth2-zlib.avi
+98d0e2854731472c5bf13d8638502d0a *tests/data/fate/vsynth2-zlib.out.rawvideo
+stddev:    1.26 PSNR: 46.10 MAXDIFF:   13 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/vsynth2-zmbv b/tests/ref/fate/vsynth2-zmbv
new file mode 100644
index 0000000..93e0b6a
--- /dev/null
+++ b/tests/ref/fate/vsynth2-zmbv
@@ -0,0 +1,4 @@
+e9cc761eb3fedc36ce5f97744196ed8b *tests/data/fate/vsynth2-zmbv.avi
+1808720 tests/data/fate/vsynth2-zmbv.avi
+ee68a5292fd0745834246b4ec0d85e9b *tests/data/fate/vsynth2-zmbv.out.rawvideo
+stddev:    8.12 PSNR: 29.94 MAXDIFF:   32 bytes:  7603200/  7603200
diff --git a/tests/ref/fate/wmv8-drm b/tests/ref/fate/wmv8-drm
index c2a6dd5..31291d3 100644
--- a/tests/ref/fate/wmv8-drm
+++ b/tests/ref/fate/wmv8-drm
@@ -1,131 +1,131 @@
-#tb 0: 1/1000
-0,          0,          0,        0,    84480, 0x7760a00b
-0,       1208,       1208,        0,    84480, 0xfe39a1db
-0,       1250,       1250,        0,    84480, 0xd71961b4
-0,       1291,       1291,        0,    84480, 0xc80dedba
-0,       1333,       1333,        0,    84480, 0x34d8b538
-0,       1375,       1375,        0,    84480, 0x1a86b8e5
-0,       1416,       1416,        0,    84480, 0xabf7c25d
-0,       1458,       1458,        0,    84480, 0x912600ee
-0,       1500,       1500,        0,    84480, 0x7ee7c70b
-0,       1541,       1541,        0,    84480, 0x09c5b0d1
-0,       1583,       1583,        0,    84480, 0x6dbe6c0c
-0,       1625,       1625,        0,    84480, 0x0fe0a120
-0,       1666,       1666,        0,    84480, 0x2352d3a2
-0,       1708,       1708,        0,    84480, 0xb22ce92e
-0,       1750,       1750,        0,    84480, 0x31db0099
-0,       1791,       1791,        0,    84480, 0xad2dd73a
-0,       1833,       1833,        0,    84480, 0xb9af8e20
-0,       1875,       1875,        0,    84480, 0x7b956549
-0,       1916,       1916,        0,    84480, 0x3f774b87
-0,       1958,       1958,        0,    84480, 0x824a23a3
-0,       2000,       2000,        0,    84480, 0x4469a8d8
-0,       2041,       2041,        0,    84480, 0xc80c7a0a
-0,       2083,       2083,        0,    84480, 0xcf958549
-0,       2125,       2125,        0,    84480, 0x449746e3
-0,       2166,       2166,        0,    84480, 0xbac66a82
-0,       2208,       2208,        0,    84480, 0x99e85855
-0,       2250,       2250,        0,    84480, 0xa4a17d17
-0,       2291,       2291,        0,    84480, 0xe29c7587
-0,       2333,       2333,        0,    84480, 0x551de592
-0,       2375,       2375,        0,    84480, 0xe0877bce
-0,       2416,       2416,        0,    84480, 0x9660eb35
-0,       2458,       2458,        0,    84480, 0x0a34b644
-0,       2500,       2500,        0,    84480, 0x352919f0
-0,       2541,       2541,        0,    84480, 0xef56ce27
-0,       2583,       2583,        0,    84480, 0x030fe862
-0,       2625,       2625,        0,    84480, 0x2eba33e2
-0,       2666,       2666,        0,    84480, 0x242de401
-0,       2708,       2708,        0,    84480, 0xbadd61ca
-0,       2750,       2750,        0,    84480, 0x2060465b
-0,       2791,       2791,        0,    84480, 0x256e6965
-0,       2833,       2833,        0,    84480, 0x243b7084
-0,       2875,       2875,        0,    84480, 0x8b3c0b47
-0,       2916,       2916,        0,    84480, 0xc174a9af
-0,       2958,       2958,        0,    84480, 0xb6d48686
-0,       3000,       3000,        0,    84480, 0xa3dd1871
-0,       3041,       3041,        0,    84480, 0x04cdcaf7
-0,       3083,       3083,        0,    84480, 0x55f89c94
-0,       3125,       3125,        0,    84480, 0xda657032
-0,       3166,       3166,        0,    84480, 0x38ba7698
-0,       3208,       3208,        0,    84480, 0x4d03a7f2
-0,       3250,       3250,        0,    84480, 0x115d9035
-0,       3291,       3291,        0,    84480, 0x24c6acc6
-0,       3333,       3333,        0,    84480, 0xdd2bbcae
-0,       3375,       3375,        0,    84480, 0xb4fee0b9
-0,       3416,       3416,        0,    84480, 0xc51c14e0
-0,       3458,       3458,        0,    84480, 0xfb7737de
-0,       3500,       3500,        0,    84480, 0x38675fb0
-0,       3541,       3541,        0,    84480, 0x4752c710
-0,       3583,       3583,        0,    84480, 0xfeb7491b
-0,       3625,       3625,        0,    84480, 0xaa248122
-0,       3666,       3666,        0,    84480, 0x9a4af87c
-0,       3708,       3708,        0,    84480, 0xedcf09df
-0,       3750,       3750,        0,    84480, 0x563a05df
-0,       3791,       3791,        0,    84480, 0x0dde1e03
-0,       3833,       3833,        0,    84480, 0xd8f0ff65
-0,       3875,       3875,        0,    84480, 0xbeb9ae1a
-0,       3916,       3916,        0,    84480, 0x416d1468
-0,       3958,       3958,        0,    84480, 0x66c87d4c
-0,       4000,       4000,        0,    84480, 0xa67c0774
-0,       4041,       4041,        0,    84480, 0xd8f8aec1
-0,       4083,       4083,        0,    84480, 0xadfa502b
-0,       4125,       4125,        0,    84480, 0x50bf20e4
-0,       4166,       4166,        0,    84480, 0xbcb3d8cc
-0,       4208,       4208,        0,    84480, 0xa54677d7
-0,       4250,       4250,        0,    84480, 0x3566042d
-0,       4291,       4291,        0,    84480, 0x4c9eed57
-0,       4333,       4333,        0,    84480, 0xc3b90e58
-0,       4375,       4375,        0,    84480, 0x3c042bfa
-0,       4416,       4416,        0,    84480, 0x19f8e890
-0,       4458,       4458,        0,    84480, 0xd3dacfb9
-0,       4500,       4500,        0,    84480, 0x2365fc6f
-0,       4541,       4541,        0,    84480, 0xa2c19d00
-0,       4583,       4583,        0,    84480, 0xce94336f
-0,       4625,       4625,        0,    84480, 0xfa9bcf14
-0,       4916,       4916,        0,    84480, 0x24d6a243
-0,       4958,       4958,        0,    84480, 0xae1c8854
-0,       5000,       5000,        0,    84480, 0xbb8968bf
-0,       5041,       5041,        0,    84480, 0x6f923623
-0,       5083,       5083,        0,    84480, 0x22e98029
-0,       5125,       5125,        0,    84480, 0x8ac33af3
-0,       5166,       5166,        0,    84480, 0x05947b6e
-0,       5208,       5208,        0,    84480, 0xfc35661a
-0,       5250,       5250,        0,    84480, 0x0e6b6e47
-0,       5291,       5291,        0,    84480, 0x82c764bb
-0,       5333,       5333,        0,    84480, 0x57a36833
-0,       5375,       5375,        0,    84480, 0xc8dd690a
-0,       5416,       5416,        0,    84480, 0x02c47232
-0,       5458,       5458,        0,    84480, 0x6645715d
-0,       5500,       5500,        0,    84480, 0xc64860f7
-0,       5541,       5541,        0,    84480, 0x4f5614b3
-0,       5583,       5583,        0,    84480, 0xa70842ca
-0,       5625,       5625,        0,    84480, 0x379d8458
-0,       5666,       5666,        0,    84480, 0xa14701cf
-0,       5708,       5708,        0,    84480, 0xad1aa2b2
-0,       5750,       5750,        0,    84480, 0xee28f320
-0,       5791,       5791,        0,    84480, 0x505801e9
-0,       5833,       5833,        0,    84480, 0x7947233b
-0,       5875,       5875,        0,    84480, 0x3ce72a9d
-0,       5916,       5916,        0,    84480, 0xa6834e64
-0,       5958,       5958,        0,    84480, 0xfebf4d70
-0,       6000,       6000,        0,    84480, 0x4a0775e2
-0,       6041,       6041,        0,    84480, 0x9d7e945b
-0,       6083,       6083,        0,    84480, 0xaa9eadd9
-0,       6125,       6125,        0,    84480, 0xaa85c9b1
-0,       6166,       6166,        0,    84480, 0xa005edaf
-0,       6208,       6208,        0,    84480, 0x7fc4e5cc
-0,       6250,       6250,        0,    84480, 0xb0f6e8d1
-0,       6291,       6291,        0,    84480, 0x9ef9f330
-0,       6333,       6333,        0,    84480, 0xbe14ff1f
-0,       6375,       6375,        0,    84480, 0xd494048c
-0,       6416,       6416,        0,    84480, 0x046166a7
-0,       6458,       6458,        0,    84480, 0x052a09b2
-0,       6500,       6500,        0,    84480, 0x71fff4ab
-0,       6541,       6541,        0,    84480, 0xb9684e41
-0,       6583,       6583,        0,    84480, 0x1ddce068
-0,       6625,       6625,        0,    84480, 0xb9de300e
-0,       6666,       6666,        0,    84480, 0x13962590
-0,       6708,       6708,        0,    84480, 0xde79482f
-0,       6750,       6750,        0,    84480, 0x7d1ca064
-0,       6791,       6791,        0,    84480, 0x2676a064
+#tb 0: 1/24
+0,          0,          0,        1,    84480, 0x7760a00b
+0,         29,         29,        1,    84480, 0xfe39a1db
+0,         30,         30,        1,    84480, 0xd71961b4
+0,         31,         31,        1,    84480, 0xc80dedba
+0,         32,         32,        1,    84480, 0x34d8b538
+0,         33,         33,        1,    84480, 0x1a86b8e5
+0,         34,         34,        1,    84480, 0xabf7c25d
+0,         35,         35,        1,    84480, 0x912600ee
+0,         36,         36,        1,    84480, 0x7ee7c70b
+0,         37,         37,        1,    84480, 0x09c5b0d1
+0,         38,         38,        1,    84480, 0x6dbe6c0c
+0,         39,         39,        1,    84480, 0x0fe0a120
+0,         40,         40,        1,    84480, 0x2352d3a2
+0,         41,         41,        1,    84480, 0xb22ce92e
+0,         42,         42,        1,    84480, 0x31db0099
+0,         43,         43,        1,    84480, 0xad2dd73a
+0,         44,         44,        1,    84480, 0xb9af8e20
+0,         45,         45,        1,    84480, 0x7b956549
+0,         46,         46,        1,    84480, 0x3f774b87
+0,         47,         47,        1,    84480, 0x824a23a3
+0,         48,         48,        1,    84480, 0x4469a8d8
+0,         49,         49,        1,    84480, 0xc80c7a0a
+0,         50,         50,        1,    84480, 0xcf958549
+0,         51,         51,        1,    84480, 0x449746e3
+0,         52,         52,        1,    84480, 0xbac66a82
+0,         53,         53,        1,    84480, 0x99e85855
+0,         54,         54,        1,    84480, 0xa4a17d17
+0,         55,         55,        1,    84480, 0xe29c7587
+0,         56,         56,        1,    84480, 0x551de592
+0,         57,         57,        1,    84480, 0xe0877bce
+0,         58,         58,        1,    84480, 0x9660eb35
+0,         59,         59,        1,    84480, 0x0a34b644
+0,         60,         60,        1,    84480, 0x352919f0
+0,         61,         61,        1,    84480, 0xef56ce27
+0,         62,         62,        1,    84480, 0x030fe862
+0,         63,         63,        1,    84480, 0x2eba33e2
+0,         64,         64,        1,    84480, 0x242de401
+0,         65,         65,        1,    84480, 0xbadd61ca
+0,         66,         66,        1,    84480, 0x2060465b
+0,         67,         67,        1,    84480, 0x256e6965
+0,         68,         68,        1,    84480, 0x243b7084
+0,         69,         69,        1,    84480, 0x8b3c0b47
+0,         70,         70,        1,    84480, 0xc174a9af
+0,         71,         71,        1,    84480, 0xb6d48686
+0,         72,         72,        1,    84480, 0xa3dd1871
+0,         73,         73,        1,    84480, 0x04cdcaf7
+0,         74,         74,        1,    84480, 0x55f89c94
+0,         75,         75,        1,    84480, 0xda657032
+0,         76,         76,        1,    84480, 0x38ba7698
+0,         77,         77,        1,    84480, 0x4d03a7f2
+0,         78,         78,        1,    84480, 0x115d9035
+0,         79,         79,        1,    84480, 0x24c6acc6
+0,         80,         80,        1,    84480, 0xdd2bbcae
+0,         81,         81,        1,    84480, 0xb4fee0b9
+0,         82,         82,        1,    84480, 0xc51c14e0
+0,         83,         83,        1,    84480, 0xfb7737de
+0,         84,         84,        1,    84480, 0x38675fb0
+0,         85,         85,        1,    84480, 0x4752c710
+0,         86,         86,        1,    84480, 0xfeb7491b
+0,         87,         87,        1,    84480, 0xaa248122
+0,         88,         88,        1,    84480, 0x9a4af87c
+0,         89,         89,        1,    84480, 0xedcf09df
+0,         90,         90,        1,    84480, 0x563a05df
+0,         91,         91,        1,    84480, 0x0dde1e03
+0,         92,         92,        1,    84480, 0xd8f0ff65
+0,         93,         93,        1,    84480, 0xbeb9ae1a
+0,         94,         94,        1,    84480, 0x416d1468
+0,         95,         95,        1,    84480, 0x66c87d4c
+0,         96,         96,        1,    84480, 0xa67c0774
+0,         97,         97,        1,    84480, 0xd8f8aec1
+0,         98,         98,        1,    84480, 0xadfa502b
+0,         99,         99,        1,    84480, 0x50bf20e4
+0,        100,        100,        1,    84480, 0xbcb3d8cc
+0,        101,        101,        1,    84480, 0xa54677d7
+0,        102,        102,        1,    84480, 0x3566042d
+0,        103,        103,        1,    84480, 0x4c9eed57
+0,        104,        104,        1,    84480, 0xc3b90e58
+0,        105,        105,        1,    84480, 0x3c042bfa
+0,        106,        106,        1,    84480, 0x19f8e890
+0,        107,        107,        1,    84480, 0xd3dacfb9
+0,        108,        108,        1,    84480, 0x2365fc6f
+0,        109,        109,        1,    84480, 0xa2c19d00
+0,        110,        110,        1,    84480, 0xce94336f
+0,        111,        111,        1,    84480, 0xfa9bcf14
+0,        118,        118,        1,    84480, 0x24d6a243
+0,        119,        119,        1,    84480, 0xae1c8854
+0,        120,        120,        1,    84480, 0xbb8968bf
+0,        121,        121,        1,    84480, 0x6f923623
+0,        122,        122,        1,    84480, 0x22e98029
+0,        123,        123,        1,    84480, 0x8ac33af3
+0,        124,        124,        1,    84480, 0x05947b6e
+0,        125,        125,        1,    84480, 0xfc35661a
+0,        126,        126,        1,    84480, 0x0e6b6e47
+0,        127,        127,        1,    84480, 0x82c764bb
+0,        128,        128,        1,    84480, 0x57a36833
+0,        129,        129,        1,    84480, 0xc8dd690a
+0,        130,        130,        1,    84480, 0x02c47232
+0,        131,        131,        1,    84480, 0x6645715d
+0,        132,        132,        1,    84480, 0xc64860f7
+0,        133,        133,        1,    84480, 0x4f5614b3
+0,        134,        134,        1,    84480, 0xa70842ca
+0,        135,        135,        1,    84480, 0x379d8458
+0,        136,        136,        1,    84480, 0xa14701cf
+0,        137,        137,        1,    84480, 0xad1aa2b2
+0,        138,        138,        1,    84480, 0xee28f320
+0,        139,        139,        1,    84480, 0x505801e9
+0,        140,        140,        1,    84480, 0x7947233b
+0,        141,        141,        1,    84480, 0x3ce72a9d
+0,        142,        142,        1,    84480, 0xa6834e64
+0,        143,        143,        1,    84480, 0xfebf4d70
+0,        144,        144,        1,    84480, 0x4a0775e2
+0,        145,        145,        1,    84480, 0x9d7e945b
+0,        146,        146,        1,    84480, 0xaa9eadd9
+0,        147,        147,        1,    84480, 0xaa85c9b1
+0,        148,        148,        1,    84480, 0xa005edaf
+0,        149,        149,        1,    84480, 0x7fc4e5cc
+0,        150,        150,        1,    84480, 0xb0f6e8d1
+0,        151,        151,        1,    84480, 0x9ef9f330
+0,        152,        152,        1,    84480, 0xbe14ff1f
+0,        153,        153,        1,    84480, 0xd494048c
+0,        154,        154,        1,    84480, 0x046166a7
+0,        155,        155,        1,    84480, 0x052a09b2
+0,        156,        156,        1,    84480, 0x71fff4ab
+0,        157,        157,        1,    84480, 0xb9684e41
+0,        158,        158,        1,    84480, 0x1ddce068
+0,        159,        159,        1,    84480, 0xb9de300e
+0,        160,        160,        1,    84480, 0x13962590
+0,        161,        161,        1,    84480, 0xde79482f
+0,        162,        162,        1,    84480, 0x7d1ca064
+0,        163,        163,        1,    84480, 0x0998a064
diff --git a/tests/ref/fate/wmv8-drm-nodec b/tests/ref/fate/wmv8-drm-nodec
index d6bf15e..76c4e75 100644
--- a/tests/ref/fate/wmv8-drm-nodec
+++ b/tests/ref/fate/wmv8-drm-nodec
@@ -5,148 +5,148 @@
 1,        435,        435,        0,     1088, 0x8dfa1368
 1,        740,        740,        0,     1088, 0xc0d211be
 1,       1023,       1023,        0,     1088, 0x8238113a
-0,       1208,       1208,        0,      137, 0x903c415e
-0,       1250,       1250,        0,      942, 0xd5b7d2aa
-0,       1291,       1291,        0,      841, 0xaffd8ce6
+0,       1208,       1208,        0,      137, 0x903c415e, F=0x0
+0,       1250,       1250,        0,      942, 0xd5b7d2aa, F=0x0
+0,       1291,       1291,        0,      841, 0xaffd8ce6, F=0x0
 1,       1306,       1306,        0,     1088, 0x9f8924b7
-0,       1333,       1333,        0,     1164, 0x4ed84836
-0,       1375,       1375,        0,     1492, 0x37f3e8aa
-0,       1416,       1416,        0,     1663, 0xc091392d
-0,       1458,       1458,        0,     1443, 0x6162c718
-0,       1500,       1500,        0,     1721, 0x7bdb3dd0
-0,       1541,       1541,        0,     1410, 0xde689881
-0,       1583,       1583,        0,     1258, 0xb5b86920
+0,       1333,       1333,        0,     1164, 0x4ed84836, F=0x0
+0,       1375,       1375,        0,     1492, 0x37f3e8aa, F=0x0
+0,       1416,       1416,        0,     1663, 0xc091392d, F=0x0
+0,       1458,       1458,        0,     1443, 0x6162c718, F=0x0
+0,       1500,       1500,        0,     1721, 0x7bdb3dd0, F=0x0
+0,       1541,       1541,        0,     1410, 0xde689881, F=0x0
+0,       1583,       1583,        0,     1258, 0xb5b86920, F=0x0
 1,       1589,       1589,        0,     1088, 0x767f317a
-0,       1625,       1625,        0,     2050, 0x99b6d7c7
-0,       1666,       1666,        0,     1242, 0x9ba35009
-0,       1708,       1708,        0,     1630, 0x17f10192
-0,       1750,       1750,        0,     1747, 0xbbee59d7
-0,       1791,       1791,        0,     1565, 0xb09b00d9
-0,       1833,       1833,        0,     1573, 0xd2e62201
+0,       1625,       1625,        0,     2050, 0x99b6d7c7, F=0x0
+0,       1666,       1666,        0,     1242, 0x9ba35009, F=0x0
+0,       1708,       1708,        0,     1630, 0x17f10192, F=0x0
+0,       1750,       1750,        0,     1747, 0xbbee59d7, F=0x0
+0,       1791,       1791,        0,     1565, 0xb09b00d9, F=0x0
+0,       1833,       1833,        0,     1573, 0xd2e62201, F=0x0
 1,       1872,       1872,        0,     1088, 0x57000d38
-0,       1875,       1875,        0,     1353, 0x2305a24d
-0,       1916,       1916,        0,     1425, 0xf41bbb46
-0,       1958,       1958,        0,     1355, 0xfc08a762
-0,       2000,       2000,        0,     1363, 0x98cda71d
-0,       2041,       2041,        0,     1547, 0x8742f11f
-0,       2083,       2083,        0,     1967, 0x43d61723
-0,       2125,       2125,        0,     1378, 0xde22c753
-0,       2166,       2166,        0,      961, 0x2418a4da
+0,       1875,       1875,        0,     1353, 0x2305a24d, F=0x0
+0,       1916,       1916,        0,     1425, 0xf41bbb46, F=0x0
+0,       1958,       1958,        0,     1355, 0xfc08a762, F=0x0
+0,       2000,       2000,        0,     1363, 0x98cda71d, F=0x0
+0,       2041,       2041,        0,     1547, 0x8742f11f, F=0x0
+0,       2083,       2083,        0,     1967, 0x43d61723, F=0x0
+0,       2125,       2125,        0,     1378, 0xde22c753, F=0x0
+0,       2166,       2166,        0,      961, 0x2418a4da, F=0x0
 1,       2198,       2198,        0,     1088, 0xad977261
-0,       2208,       2208,        0,      968, 0x0d04ba51
-0,       2250,       2250,        0,     1140, 0x737f3543
-0,       2291,       2291,        0,     1119, 0x3c050388
-0,       2333,       2333,        0,     1078, 0xeac8d981
-0,       2375,       2375,        0,     1113, 0xebfa0314
-0,       2416,       2416,        0,     1229, 0x95dc3cb5
-0,       2458,       2458,        0,     1311, 0x8a6f5bda
-0,       2500,       2500,        0,     1270, 0x2e66540a
-0,       2541,       2541,        0,     1408, 0x5f489779
-0,       2583,       2583,        0,     1359, 0x8bd085f5
-0,       2625,       2625,        0,     1428, 0xef9ba480
-0,       2666,       2666,        0,     1179, 0x5bb221a8
-0,       2708,       2708,        0,     1108, 0x9a6019a8
-0,       2750,       2750,        0,     1205, 0xccba4d22
-0,       2791,       2791,        0,     1306, 0xde708c19
-0,       2833,       2833,       41,     1724, 0xa70b521e
-0,       2875,       2875,       41,     1336, 0xdf3974b9
-0,       2916,       2916,       41,     1259, 0x1f6b4307
-0,       2958,       2958,       41,     1194, 0x635f5a43
-0,       3000,       3000,       41,     1183, 0x1dd47115
-0,       3041,       3041,       41,     1126, 0x5bac3cc8
-0,       3083,       3083,       41,     1360, 0x1fe2d981
-0,       3125,       3125,       41,     1261, 0x34288acb
-0,       3166,       3166,       41,     1250, 0x26bd72b3
-0,       3208,       3208,       41,     1147, 0x02e81ba0
-0,       3250,       3250,       41,     1368, 0xb8146962
-0,       3291,       3291,       41,     1377, 0xf7b6ce65
-0,       3333,       3333,       41,     1396, 0x88467dee
-0,       3375,       3375,       41,     1408, 0x5585c25c
-0,       3416,       3416,       41,     1551, 0x42002c8d
-0,       3458,       3458,       41,     1524, 0xbcb609e3
+0,       2208,       2208,        0,      968, 0x0d04ba51, F=0x0
+0,       2250,       2250,        0,     1140, 0x737f3543, F=0x0
+0,       2291,       2291,        0,     1119, 0x3c050388, F=0x0
+0,       2333,       2333,        0,     1078, 0xeac8d981, F=0x0
+0,       2375,       2375,        0,     1113, 0xebfa0314, F=0x0
+0,       2416,       2416,        0,     1229, 0x95dc3cb5, F=0x0
+0,       2458,       2458,        0,     1311, 0x8a6f5bda, F=0x0
+0,       2500,       2500,        0,     1270, 0x2e66540a, F=0x0
+0,       2541,       2541,        0,     1408, 0x5f489779, F=0x0
+0,       2583,       2583,        0,     1359, 0x8bd085f5, F=0x0
+0,       2625,       2625,        0,     1428, 0xef9ba480, F=0x0
+0,       2666,       2666,        0,     1179, 0x5bb221a8, F=0x0
+0,       2708,       2708,        0,     1108, 0x9a6019a8, F=0x0
+0,       2750,       2750,        0,     1205, 0xccba4d22, F=0x0
+0,       2791,       2791,        0,     1306, 0xde708c19, F=0x0
+0,       2833,       2833,        0,     1724, 0xa70b521e, F=0x0
+0,       2875,       2875,       41,     1336, 0xdf3974b9, F=0x0
+0,       2916,       2916,       41,     1259, 0x1f6b4307, F=0x0
+0,       2958,       2958,       41,     1194, 0x635f5a43, F=0x0
+0,       3000,       3000,       41,     1183, 0x1dd47115, F=0x0
+0,       3041,       3041,       41,     1126, 0x5bac3cc8, F=0x0
+0,       3083,       3083,       41,     1360, 0x1fe2d981, F=0x0
+0,       3125,       3125,       41,     1261, 0x34288acb, F=0x0
+0,       3166,       3166,       41,     1250, 0x26bd72b3, F=0x0
+0,       3208,       3208,       41,     1147, 0x02e81ba0, F=0x0
+0,       3250,       3250,       41,     1368, 0xb8146962, F=0x0
+0,       3291,       3291,       41,     1377, 0xf7b6ce65, F=0x0
+0,       3333,       3333,       41,     1396, 0x88467dee, F=0x0
+0,       3375,       3375,       41,     1408, 0x5585c25c, F=0x0
+0,       3416,       3416,       41,     1551, 0x42002c8d, F=0x0
+0,       3458,       3458,       41,     1524, 0xbcb609e3, F=0x0
 1,       3482,       3482,        0,     1088, 0xdce57471
-0,       3500,       3500,       41,     1554, 0x3d740564
-0,       3541,       3541,       41,     1467, 0xc349f2d7
-0,       3583,       3583,       41,     1066, 0xb7401462
-0,       3625,       3625,       41,     1502, 0x3ee602ed
-0,       3666,       3666,       41,     1148, 0xba463637
-0,       3708,       3708,       41,     1351, 0x5e85ae79
-0,       3750,       3750,       41,     1187, 0xed8d6055
-0,       3791,       3791,       41,     1200, 0x64185be6
-0,       3833,       3833,       41,     1175, 0x12ad3c1e
-0,       3875,       3875,       41,     1179, 0x7e034570
-0,       3916,       3916,       41,     1136, 0x5c633c51
+0,       3500,       3500,       41,     1554, 0x3d740564, F=0x0
+0,       3541,       3541,       41,     1467, 0xc349f2d7, F=0x0
+0,       3583,       3583,       41,     1066, 0xb7401462, F=0x0
+0,       3625,       3625,       41,     1502, 0x3ee602ed, F=0x0
+0,       3666,       3666,       41,     1148, 0xba463637, F=0x0
+0,       3708,       3708,       41,     1351, 0x5e85ae79, F=0x0
+0,       3750,       3750,       41,     1187, 0xed8d6055, F=0x0
+0,       3791,       3791,       41,     1200, 0x64185be6, F=0x0
+0,       3833,       3833,       41,     1175, 0x12ad3c1e, F=0x0
+0,       3875,       3875,       41,     1179, 0x7e034570, F=0x0
+0,       3916,       3916,       41,     1136, 0x5c633c51, F=0x0
 1,       3918,       3918,        0,     1088, 0xf3887977
-0,       3958,       3958,       41,     1064, 0x5eb51d89
-0,       4000,       4000,       41,      953, 0xe148bbdd
-0,       4041,       4041,       41,      989, 0x901ec306
-0,       4083,       4083,       41,     1030, 0x680de26f
-0,       4125,       4125,       41,     1078, 0x86e0ee43
-0,       4166,       4166,       41,     1232, 0x98546a86
-0,       4208,       4208,       41,     1164, 0x93305074
-0,       4250,       4250,       41,     1348, 0x27cfa91b
-0,       4291,       4291,       41,     1417, 0x2312d70e
-0,       4333,       4333,       41,     1285, 0x46ca4cca
+0,       3958,       3958,       41,     1064, 0x5eb51d89, F=0x0
+0,       4000,       4000,       41,      953, 0xe148bbdd, F=0x0
+0,       4041,       4041,       41,      989, 0x901ec306, F=0x0
+0,       4083,       4083,       41,     1030, 0x680de26f, F=0x0
+0,       4125,       4125,       41,     1078, 0x86e0ee43, F=0x0
+0,       4166,       4166,       41,     1232, 0x98546a86, F=0x0
+0,       4208,       4208,       41,     1164, 0x93305074, F=0x0
+0,       4250,       4250,       41,     1348, 0x27cfa91b, F=0x0
+0,       4291,       4291,       41,     1417, 0x2312d70e, F=0x0
+0,       4333,       4333,       41,     1285, 0x46ca4cca, F=0x0
 1,       4353,       4353,        0,     1088, 0x1d6c8ed2
-0,       4375,       4375,       41,     1037, 0xcf09dd3d
-0,       4416,       4416,       41,     1005, 0xe780cf1f
-0,       4458,       4458,       41,      890, 0x8b1d8c1b
-0,       4500,       4500,       41,     1023, 0xd1dbd506
-0,       4541,       4541,       41,      803, 0x935e775e
-0,       4583,       4583,       41,     1035, 0x6a220483
-0,       4625,       4625,       41,      466, 0xd88bb237
+0,       4375,       4375,       41,     1037, 0xcf09dd3d, F=0x0
+0,       4416,       4416,       41,     1005, 0xe780cf1f, F=0x0
+0,       4458,       4458,       41,      890, 0x8b1d8c1b, F=0x0
+0,       4500,       4500,       41,     1023, 0xd1dbd506, F=0x0
+0,       4541,       4541,       41,      803, 0x935e775e, F=0x0
+0,       4583,       4583,       41,     1035, 0x6a220483, F=0x0
+0,       4625,       4625,       41,      466, 0xd88bb237, F=0x0
 1,       4789,       4789,        0,     1088, 0x09115bae
-0,       4916,       4916,       41,      945, 0x8f2eb1ec
+0,       4916,       4916,       41,      945, 0x8f2eb1ec, F=0x0
 0,       4958,       4958,       41,     1190, 0x4c451c1b
-0,       5000,       5000,       41,     1811, 0x727c52cb
-0,       5041,       5041,       41,     1552, 0x73f82bff
-0,       5083,       5083,       41,     1544, 0xa7241ece
-0,       5125,       5125,       41,     1707, 0x3d1a6464
-0,       5166,       5166,       41,     1103, 0x06b22710
-0,       5208,       5208,       41,     1122, 0x656725b8
+0,       5000,       5000,       41,     1811, 0x727c52cb, F=0x0
+0,       5041,       5041,       41,     1552, 0x73f82bff, F=0x0
+0,       5083,       5083,       41,     1544, 0xa7241ece, F=0x0
+0,       5125,       5125,       41,     1707, 0x3d1a6464, F=0x0
+0,       5166,       5166,       41,     1103, 0x06b22710, F=0x0
+0,       5208,       5208,       41,     1122, 0x656725b8, F=0x0
 1,       5224,       5224,        0,     1088, 0x0c8b9372
-0,       5250,       5250,       41,     1150, 0xf9674678
-0,       5291,       5291,       41,     1438, 0x03fac426
-0,       5333,       5333,       41,     1623, 0x7adb1321
-0,       5375,       5375,       41,     1677, 0x0b9a3e62
-0,       5416,       5416,       41,     1124, 0x769c0ea2
-0,       5458,       5458,       41,     1221, 0xd942409f
-0,       5500,       5500,       41,     1698, 0xd7ca3fe3
-0,       5541,       5541,       41,     1262, 0xb994692f
-0,       5583,       5583,       41,     2097, 0xf4eb663f
-0,       5625,       5625,       41,     1251, 0xfd4f633a
+0,       5250,       5250,       41,     1150, 0xf9674678, F=0x0
+0,       5291,       5291,       41,     1438, 0x03fac426, F=0x0
+0,       5333,       5333,       41,     1623, 0x7adb1321, F=0x0
+0,       5375,       5375,       41,     1677, 0x0b9a3e62, F=0x0
+0,       5416,       5416,       41,     1124, 0x769c0ea2, F=0x0
+0,       5458,       5458,       41,     1221, 0xd942409f, F=0x0
+0,       5500,       5500,       41,     1698, 0xd7ca3fe3, F=0x0
+0,       5541,       5541,       41,     1262, 0xb994692f, F=0x0
+0,       5583,       5583,       41,     2097, 0xf4eb663f, F=0x0
+0,       5625,       5625,       41,     1251, 0xfd4f633a, F=0x0
 1,       5659,       5659,        0,     1088, 0x75a82540
-0,       5666,       5666,       41,     1633, 0xb7e1290e
-0,       5708,       5708,       41,     1739, 0xecd18c38
-0,       5750,       5750,       41,     1132, 0xc83e1828
-0,       5791,       5791,       41,      825, 0xdd02867c
-0,       5833,       5833,       41,      903, 0x349ba205
-0,       5875,       5875,       41,     1013, 0x1366ec2a
-0,       5916,       5916,       41,     1340, 0xeaa2a231
-0,       5958,       5958,       41,     1102, 0x82de2889
-0,       6000,       6000,       41,     1834, 0x59b99b92
+0,       5666,       5666,       41,     1633, 0xb7e1290e, F=0x0
+0,       5708,       5708,       41,     1739, 0xecd18c38, F=0x0
+0,       5750,       5750,       41,     1132, 0xc83e1828, F=0x0
+0,       5791,       5791,       41,      825, 0xdd02867c, F=0x0
+0,       5833,       5833,       41,      903, 0x349ba205, F=0x0
+0,       5875,       5875,       41,     1013, 0x1366ec2a, F=0x0
+0,       5916,       5916,       41,     1340, 0xeaa2a231, F=0x0
+0,       5958,       5958,       41,     1102, 0x82de2889, F=0x0
+0,       6000,       6000,       41,     1834, 0x59b99b92, F=0x0
 1,       6008,       6008,        0,     1088, 0x690312b0
-0,       6041,       6041,       41,     1332, 0x0610813a
-0,       6083,       6083,       41,     1275, 0x5b0d7be7
-0,       6125,       6125,       41,     1376, 0xd915b0fe
-0,       6166,       6166,       41,     1417, 0x8606b34a
-0,       6208,       6208,       41,     1360, 0x3bcd93d3
-0,       6250,       6250,       41,     1330, 0xd0439c93
-0,       6291,       6291,       41,     1562, 0xb2560a09
+0,       6041,       6041,       41,     1332, 0x0610813a, F=0x0
+0,       6083,       6083,       41,     1275, 0x5b0d7be7, F=0x0
+0,       6125,       6125,       41,     1376, 0xd915b0fe, F=0x0
+0,       6166,       6166,       41,     1417, 0x8606b34a, F=0x0
+0,       6208,       6208,       41,     1360, 0x3bcd93d3, F=0x0
+0,       6250,       6250,       41,     1330, 0xd0439c93, F=0x0
+0,       6291,       6291,       41,     1562, 0xb2560a09, F=0x0
 1,       6312,       6312,        0,     1088, 0x76d50ff3
-0,       6333,       6333,       41,     1376, 0x4f9eb447
-0,       6375,       6375,       41,     1405, 0x85d3b084
-0,       6416,       6416,       41,     1344, 0xcdbda2ae
-0,       6458,       6458,       41,     1313, 0xe3067b35
-0,       6500,       6500,       41,     1459, 0xf9d2c56f
-0,       6541,       6541,       41,     1275, 0xf5536d81
-0,       6583,       6583,       41,     1209, 0x3b5b4ea5
+0,       6333,       6333,       41,     1376, 0x4f9eb447, F=0x0
+0,       6375,       6375,       41,     1405, 0x85d3b084, F=0x0
+0,       6416,       6416,       41,     1344, 0xcdbda2ae, F=0x0
+0,       6458,       6458,       41,     1313, 0xe3067b35, F=0x0
+0,       6500,       6500,       41,     1459, 0xf9d2c56f, F=0x0
+0,       6541,       6541,       41,     1275, 0xf5536d81, F=0x0
+0,       6583,       6583,       41,     1209, 0x3b5b4ea5, F=0x0
 1,       6595,       6595,        0,     1088, 0x8766276f
-0,       6625,       6625,       41,     1352, 0x7b199d28
-0,       6666,       6666,       41,     1349, 0x02adaaf3
-0,       6708,       6708,       41,     1464, 0x20d7cfd2
-0,       6750,       6750,       41,     1377, 0x78e0b1f4
-0,       6791,       6791,       41,      289, 0x1f2e9246
+0,       6625,       6625,       41,     1352, 0x7b199d28, F=0x0
+0,       6666,       6666,       41,     1349, 0x02adaaf3, F=0x0
+0,       6708,       6708,       41,     1464, 0x20d7cfd2, F=0x0
+0,       6750,       6750,       41,     1377, 0x78e0b1f4, F=0x0
+0,       6791,       6791,       41,      289, 0x1f2e9246, F=0x0
 1,       6878,       6878,        0,     1088, 0x678f20fd
 1,       7161,       7161,        0,     1088, 0x718afa20
 1,       7444,       7444,        0,     1088, 0x758f0939
diff --git a/tests/ref/fate/wmv8-x8intra b/tests/ref/fate/wmv8-x8intra
new file mode 100644
index 0000000..1f75ce2
--- /dev/null
+++ b/tests/ref/fate/wmv8-x8intra
@@ -0,0 +1,474 @@
+#tb 0: 1/15
+0,          0,          0,        1,   115200, 0x03fbd838
+0,          3,          3,        1,   115200, 0x8911d86f
+0,          4,          4,        1,   115200, 0x7c5dd82e
+0,          5,          5,        1,   115200, 0x7c5ed82e
+0,         30,         30,        1,   115200, 0xd323d838
+0,         31,         31,        1,   115200, 0x6e7479ab
+0,         32,         32,        1,   115200, 0x14674bf6
+0,         33,         33,        1,   115200, 0x074c2e3d
+0,         34,         34,        1,   115200, 0x9b3025ef
+0,         35,         35,        1,   115200, 0x76882dae
+0,         36,         36,        1,   115200, 0xedf3421b
+0,         37,         37,        1,   115200, 0xb5378486
+0,         38,         38,        1,   115200, 0xc4a53420
+0,         39,         39,        1,   115200, 0x559cb60f
+0,         40,         40,        1,   115200, 0xcc034ddd
+0,         41,         41,        1,   115200, 0xb77b7779
+0,         42,         42,        1,   115200, 0x0ad9c3e6
+0,         43,         43,        1,   115200, 0x4e673027
+0,         44,         44,        1,   115200, 0x54717979
+0,         45,         45,        1,   115200, 0xf9e557c9
+0,         46,         46,        1,   115200, 0xefad6344
+0,         47,         47,        1,   115200, 0x07497ba3
+0,         48,         48,        1,   115200, 0xabef71d3
+0,         49,         49,        1,   115200, 0x5b8f5802
+0,         50,         50,        1,   115200, 0x8b920b76
+0,         51,         51,        1,   115200, 0xb93f0f04
+0,         52,         52,        1,   115200, 0xa31b18c0
+0,         53,         53,        1,   115200, 0x9116235b
+0,         54,         54,        1,   115200, 0xe54b1d0b
+0,         55,         55,        1,   115200, 0x35e7252a
+0,         56,         56,        1,   115200, 0x2cae31d5
+0,         57,         57,        1,   115200, 0x28493c57
+0,         58,         58,        1,   115200, 0xd8a445b5
+0,         59,         59,        1,   115200, 0xbf854c55
+0,         60,         60,        1,   115200, 0x3761555c
+0,         61,         61,        1,   115200, 0x07a35c8a
+0,         62,         62,        1,   115200, 0x848c6eb0
+0,         63,         63,        1,   115200, 0x8d7c77d1
+0,         64,         64,        1,   115200, 0x903980b7
+0,         65,         65,        1,   115200, 0xbd30898c
+0,         66,         66,        1,   115200, 0x31f78d25
+0,         67,         67,        1,   115200, 0x308aa19d
+0,         68,         68,        1,   115200, 0xf185948c
+0,         69,         69,        1,   115200, 0x8aeea0b9
+0,         70,         70,        1,   115200, 0x06669545
+0,         71,         71,        1,   115200, 0x4d3e84d7
+0,         72,         72,        1,   115200, 0x80007e9c
+0,         73,         73,        1,   115200, 0x7cad6ea5
+0,         74,         74,        1,   115200, 0xd5d747f6
+0,         75,         75,        1,   115200, 0xeddb43bf
+0,         76,         76,        1,   115200, 0x2d3c30b5
+0,         77,         77,        1,   115200, 0x7b465872
+0,         78,         78,        1,   115200, 0xd144b461
+0,         79,         79,        1,   115200, 0x36b0053e
+0,         80,         80,        1,   115200, 0xdf90ec64
+0,         81,         81,        1,   115200, 0xb59cecc6
+0,         82,         82,        1,   115200, 0x0469ed52
+0,         83,         83,        1,   115200, 0x2d7cf7cb
+0,         84,         84,        1,   115200, 0x8376bf2c
+0,         85,         85,        1,   115200, 0xd79dbd1e
+0,         86,         86,        1,   115200, 0xbc79996d
+0,         87,         87,        1,   115200, 0x524d0a62
+0,         88,         88,        1,   115200, 0x07798f44
+0,         89,         89,        1,   115200, 0xd8b85d49
+0,         90,         90,        1,   115200, 0x54126d07
+0,         91,         91,        1,   115200, 0x0346f350
+0,         92,         92,        1,   115200, 0x0feada4f
+0,         93,         93,        1,   115200, 0x74243c65
+0,         94,         94,        1,   115200, 0xbce280c8
+0,         95,         95,        1,   115200, 0xe9bc40c7
+0,         96,         96,        1,   115200, 0x72ecea21
+0,         97,         97,        1,   115200, 0xb4c32a43
+0,         98,         98,        1,   115200, 0x428a6276
+0,         99,         99,        1,   115200, 0xf67f9364
+0,        100,        100,        1,   115200, 0xf25e8858
+0,        101,        101,        1,   115200, 0x9739b909
+0,        102,        102,        1,   115200, 0x8a1b8f38
+0,        103,        103,        1,   115200, 0xe4a2cff1
+0,        104,        104,        1,   115200, 0xa800b83f
+0,        105,        105,        1,   115200, 0xa88e00d0
+0,        106,        106,        1,   115200, 0x5786082e
+0,        107,        107,        1,   115200, 0xc7205eeb
+0,        108,        108,        1,   115200, 0x9ad02d6b
+0,        109,        109,        1,   115200, 0x5314185d
+0,        110,        110,        1,   115200, 0x015b6351
+0,        111,        111,        1,   115200, 0x51a5c2e1
+0,        112,        112,        1,   115200, 0xc232ec26
+0,        113,        113,        1,   115200, 0x35b30ffc
+0,        114,        114,        1,   115200, 0x2b947acd
+0,        115,        115,        1,   115200, 0xcf1a7971
+0,        116,        116,        1,   115200, 0x70055748
+0,        117,        117,        1,   115200, 0x774b61e6
+0,        118,        118,        1,   115200, 0x74da78a7
+0,        119,        119,        1,   115200, 0x13b5523c
+0,        120,        120,        1,   115200, 0xe27050a0
+0,        121,        121,        1,   115200, 0x073156b0
+0,        122,        122,        1,   115200, 0x9a3662d4
+0,        123,        123,        1,   115200, 0x8c90139c
+0,        124,        124,        1,   115200, 0x45cdeb08
+0,        125,        125,        1,   115200, 0x046ff217
+0,        126,        126,        1,   115200, 0xa6b0a863
+0,        127,        127,        1,   115200, 0xa9c2427a
+0,        128,        128,        1,   115200, 0x7d478df1
+0,        129,        129,        1,   115200, 0x9f426504
+0,        130,        130,        1,   115200, 0x89723d89
+0,        131,        131,        1,   115200, 0x851dd023
+0,        132,        132,        1,   115200, 0xe6ed007d
+0,        133,        133,        1,   115200, 0xfe5cb08d
+0,        134,        134,        1,   115200, 0xc96e52bd
+0,        135,        135,        1,   115200, 0x15c5ffe8
+0,        136,        136,        1,   115200, 0x54540656
+0,        137,        137,        1,   115200, 0xa5e8dbec
+0,        138,        138,        1,   115200, 0x35edde29
+0,        139,        139,        1,   115200, 0xbbb6cb36
+0,        140,        140,        1,   115200, 0x59c5ed50
+0,        141,        141,        1,   115200, 0x7e8a497a
+0,        142,        142,        1,   115200, 0x16586d33
+0,        143,        143,        1,   115200, 0x19dfd6e6
+0,        144,        144,        1,   115200, 0x7ea8574a
+0,        145,        145,        1,   115200, 0x58567b44
+0,        146,        146,        1,   115200, 0x0d2d049e
+0,        147,        147,        1,   115200, 0x7c2d7b00
+0,        148,        148,        1,   115200, 0x92debda6
+0,        149,        149,        1,   115200, 0x1e4cfcc1
+0,        150,        150,        1,   115200, 0xf58b742e
+0,        151,        151,        1,   115200, 0xc2089e8b
+0,        152,        152,        1,   115200, 0x1b4f01e8
+0,        153,        153,        1,   115200, 0x113b1e76
+0,        154,        154,        1,   115200, 0x0f154b48
+0,        155,        155,        1,   115200, 0xf82f5795
+0,        156,        156,        1,   115200, 0xa9f68f5c
+0,        157,        157,        1,   115200, 0xd37992fa
+0,        158,        158,        1,   115200, 0x5e08b0ad
+0,        159,        159,        1,   115200, 0xacf77f50
+0,        160,        160,        1,   115200, 0x4a37945b
+0,        161,        161,        1,   115200, 0x9d2670b7
+0,        162,        162,        1,   115200, 0x7f7e5d76
+0,        163,        163,        1,   115200, 0x357d3ec3
+0,        164,        164,        1,   115200, 0xe4622287
+0,        165,        165,        1,   115200, 0x95260aa6
+0,        166,        166,        1,   115200, 0xff87049a
+0,        167,        167,        1,   115200, 0x5b91c76b
+0,        168,        168,        1,   115200, 0xe5fca44c
+0,        169,        169,        1,   115200, 0xccc46ee1
+0,        170,        170,        1,   115200, 0x0aec53e8
+0,        171,        171,        1,   115200, 0x7509537f
+0,        172,        172,        1,   115200, 0xd6516a81
+0,        173,        173,        1,   115200, 0xbc14562b
+0,        174,        174,        1,   115200, 0xe3f9619e
+0,        175,        175,        1,   115200, 0x2cbe35ef
+0,        176,        176,        1,   115200, 0xd78a40b9
+0,        177,        177,        1,   115200, 0x2cfa08cd
+0,        178,        178,        1,   115200, 0x3ece09fe
+0,        179,        179,        1,   115200, 0xc445d43a
+0,        180,        180,        1,   115200, 0xe1cbacdd
+0,        181,        181,        1,   115200, 0x7a03b421
+0,        182,        182,        1,   115200, 0x7c80ab27
+0,        183,        183,        1,   115200, 0xececae60
+0,        184,        184,        1,   115200, 0xef00c6b3
+0,        185,        185,        1,   115200, 0xcdc9e78d
+0,        186,        186,        1,   115200, 0xa5170dd1
+0,        187,        187,        1,   115200, 0xfe561e1f
+0,        188,        188,        1,   115200, 0xc5d056f9
+0,        189,        189,        1,   115200, 0xf0267284
+0,        190,        190,        1,   115200, 0xcdc4a09a
+0,        191,        191,        1,   115200, 0xa8c8af40
+0,        192,        192,        1,   115200, 0x0c0cc987
+0,        193,        193,        1,   115200, 0x13a0cc64
+0,        194,        194,        1,   115200, 0x0ff3e6fe
+0,        195,        195,        1,   115200, 0x7fbfe852
+0,        196,        196,        1,   115200, 0x62ea0273
+0,        197,        197,        1,   115200, 0x8d021330
+0,        198,        198,        1,   115200, 0x7ac6321a
+0,        199,        199,        1,   115200, 0xefc92de8
+0,        200,        200,        1,   115200, 0x4be95c24
+0,        201,        201,        1,   115200, 0xf62c79b0
+0,        202,        202,        1,   115200, 0x1d9f85c6
+0,        203,        203,        1,   115200, 0x13b6ad8f
+0,        204,        204,        1,   115200, 0x3d96e451
+0,        205,        205,        1,   115200, 0x0891f3c4
+0,        206,        206,        1,   115200, 0xc728f8cd
+0,        207,        207,        1,   115200, 0x9481ee74
+0,        208,        208,        1,   115200, 0xaf95fcf9
+0,        209,        209,        1,   115200, 0x856fe48d
+0,        210,        210,        1,   115200, 0x5b9c03da
+0,        211,        211,        1,   115200, 0x98f80228
+0,        212,        212,        1,   115200, 0xa4e52148
+0,        213,        213,        1,   115200, 0x65bc4b91
+0,        214,        214,        1,   115200, 0x0c166312
+0,        215,        215,        1,   115200, 0x4657a356
+0,        216,        216,        1,   115200, 0xf17e0003
+0,        217,        217,        1,   115200, 0x95a81738
+0,        218,        218,        1,   115200, 0xb02d6bd9
+0,        219,        219,        1,   115200, 0x2594e89d
+0,        220,        220,        1,   115200, 0x5c4a1349
+0,        221,        221,        1,   115200, 0xbc9d5875
+0,        222,        222,        1,   115200, 0xd935b307
+0,        223,        223,        1,   115200, 0x2114cb84
+0,        224,        224,        1,   115200, 0xbe58130c
+0,        225,        225,        1,   115200, 0x7a3d2b2b
+0,        226,        226,        1,   115200, 0xe5753e6b
+0,        227,        227,        1,   115200, 0xc84042cc
+0,        228,        228,        1,   115200, 0x98ef4c58
+0,        229,        229,        1,   115200, 0x2cb83bff
+0,        230,        230,        1,   115200, 0x4e58433a
+0,        231,        231,        1,   115200, 0x7ec26734
+0,        232,        232,        1,   115200, 0x49168d07
+0,        233,        233,        1,   115200, 0xfc9e82f2
+0,        234,        234,        1,   115200, 0x49976c26
+0,        235,        235,        1,   115200, 0xa12466ff
+0,        236,        236,        1,   115200, 0x98ae6499
+0,        237,        237,        1,   115200, 0xc8575e78
+0,        238,        238,        1,   115200, 0xc6596cd2
+0,        239,        239,        1,   115200, 0x83d9a068
+0,        240,        240,        1,   115200, 0xe819b560
+0,        241,        241,        1,   115200, 0xb07ac3c3
+0,        242,        242,        1,   115200, 0x3d79ef5b
+0,        243,        243,        1,   115200, 0xbc6800e0
+0,        244,        244,        1,   115200, 0xc78c15f8
+0,        245,        245,        1,   115200, 0xcb91360b
+0,        246,        246,        1,   115200, 0x6c657143
+0,        247,        247,        1,   115200, 0x636391d1
+0,        248,        248,        1,   115200, 0xb519e49d
+0,        249,        249,        1,   115200, 0xb65d00c5
+0,        250,        250,        1,   115200, 0x14672ba8
+0,        251,        251,        1,   115200, 0xb65d389f
+0,        252,        252,        1,   115200, 0xe88e991b
+0,        253,        253,        1,   115200, 0x6a7bad4e
+0,        254,        254,        1,   115200, 0xd305eca1
+0,        255,        255,        1,   115200, 0x8cdbe729
+0,        256,        256,        1,   115200, 0x0d1bfd9a
+0,        257,        257,        1,   115200, 0xef740a06
+0,        258,        258,        1,   115200, 0x1cd423df
+0,        259,        259,        1,   115200, 0xf78616ba
+0,        260,        260,        1,   115200, 0xcc0b2b81
+0,        261,        261,        1,   115200, 0x434e4ae9
+0,        262,        262,        1,   115200, 0xf2d461ec
+0,        263,        263,        1,   115200, 0xc75f6a15
+0,        264,        264,        1,   115200, 0x71038c87
+0,        265,        265,        1,   115200, 0x7a55ab55
+0,        266,        266,        1,   115200, 0xeef2e1de
+0,        267,        267,        1,   115200, 0xd2600c3d
+0,        268,        268,        1,   115200, 0xdd872452
+0,        269,        269,        1,   115200, 0xd1361fcd
+0,        270,        270,        1,   115200, 0xda4f0d12
+0,        271,        271,        1,   115200, 0xba061920
+0,        272,        272,        1,   115200, 0x4b2ef9ed
+0,        273,        273,        1,   115200, 0x11dfab08
+0,        274,        274,        1,   115200, 0x7a603fc2
+0,        275,        275,        1,   115200, 0x61690ad9
+0,        276,        276,        1,   115200, 0x481ac8b9
+0,        277,        277,        1,   115200, 0xea35570d
+0,        278,        278,        1,   115200, 0xdd306f19
+0,        279,        279,        1,   115200, 0x3f975f1b
+0,        280,        280,        1,   115200, 0x2386cd1f
+0,        281,        281,        1,   115200, 0x1b77f573
+0,        282,        282,        1,   115200, 0x8ce213de
+0,        283,        283,        1,   115200, 0x5f7407c6
+0,        284,        284,        1,   115200, 0x01b3ee00
+0,        285,        285,        1,   115200, 0x92759715
+0,        286,        286,        1,   115200, 0x4a208e1e
+0,        287,        287,        1,   115200, 0x6e1b80a5
+0,        288,        288,        1,   115200, 0x298c7621
+0,        289,        289,        1,   115200, 0x0e255da8
+0,        290,        290,        1,   115200, 0xabd661ca
+0,        291,        291,        1,   115200, 0x6f045226
+0,        292,        292,        1,   115200, 0x396a5e4c
+0,        293,        293,        1,   115200, 0x4bd53915
+0,        294,        294,        1,   115200, 0xaf9631b3
+0,        295,        295,        1,   115200, 0xb2602290
+0,        296,        296,        1,   115200, 0xb1272f1b
+0,        297,        297,        1,   115200, 0xe8d23699
+0,        298,        298,        1,   115200, 0xd6e2558d
+0,        299,        299,        1,   115200, 0xf1270106
+0,        300,        300,        1,   115200, 0x6ab1fc4f
+0,        301,        301,        1,   115200, 0x4a9b5c6f
+0,        302,        302,        1,   115200, 0x14177b61
+0,        303,        303,        1,   115200, 0x8f7f7971
+0,        304,        304,        1,   115200, 0x165973cd
+0,        305,        305,        1,   115200, 0x341c4ba5
+0,        306,        306,        1,   115200, 0x08df3902
+0,        307,        307,        1,   115200, 0x4c1e386a
+0,        308,        308,        1,   115200, 0x1b1c387c
+0,        309,        309,        1,   115200, 0xe42fdb83
+0,        310,        310,        1,   115200, 0x5bb2ad2e
+0,        311,        311,        1,   115200, 0x31924902
+0,        312,        312,        1,   115200, 0x5a290e9a
+0,        313,        313,        1,   115200, 0x15d6ea45
+0,        314,        314,        1,   115200, 0xb5adc34d
+0,        315,        315,        1,   115200, 0xb210a956
+0,        316,        316,        1,   115200, 0x79478dac
+0,        317,        317,        1,   115200, 0x626a3fa9
+0,        318,        318,        1,   115200, 0x6b0e370d
+0,        319,        319,        1,   115200, 0x1f1113ec
+0,        320,        320,        1,   115200, 0x362efa10
+0,        321,        321,        1,   115200, 0xca8de637
+0,        322,        322,        1,   115200, 0x432e1f19
+0,        323,        323,        1,   115200, 0xa2c93031
+0,        324,        324,        1,   115200, 0x63294fcc
+0,        325,        325,        1,   115200, 0x1c1d5928
+0,        326,        326,        1,   115200, 0xe5fb45ea
+0,        327,        327,        1,   115200, 0x0712cc77
+0,        328,        328,        1,   115200, 0xaef1c94b
+0,        329,        329,        1,   115200, 0x30c8a84e
+0,        330,        330,        1,   115200, 0xd6896b75
+0,        331,        331,        1,   115200, 0x7f8839cb
+0,        332,        332,        1,   115200, 0xcd69d7d4
+0,        333,        333,        1,   115200, 0xa6f3cdaa
+0,        334,        334,        1,   115200, 0xccbdc609
+0,        335,        335,        1,   115200, 0x2d3f77d7
+0,        336,        336,        1,   115200, 0x18f8582d
+0,        337,        337,        1,   115200, 0xe88717bb
+0,        338,        338,        1,   115200, 0xb42fd44b
+0,        339,        339,        1,   115200, 0x7edaa5b7
+0,        340,        340,        1,   115200, 0xef399a7b
+0,        341,        341,        1,   115200, 0x11d75f35
+0,        342,        342,        1,   115200, 0xc0717b78
+0,        343,        343,        1,   115200, 0x9aebc04d
+0,        344,        344,        1,   115200, 0x44c705fc
+0,        345,        345,        1,   115200, 0xd322add3
+0,        346,        346,        1,   115200, 0x0f5f0b79
+0,        347,        347,        1,   115200, 0x54a15070
+0,        348,        348,        1,   115200, 0xd11553df
+0,        349,        349,        1,   115200, 0x6f3ed910
+0,        350,        350,        1,   115200, 0x6d3a3c17
+0,        351,        351,        1,   115200, 0x434ebc13
+0,        352,        352,        1,   115200, 0xcf07ecb2
+0,        353,        353,        1,   115200, 0x1c94497e
+0,        354,        354,        1,   115200, 0x83c13cbc
+0,        355,        355,        1,   115200, 0x4a8ba4f5
+0,        356,        356,        1,   115200, 0x922a393f
+0,        357,        357,        1,   115200, 0x44024959
+0,        358,        358,        1,   115200, 0x23f18ebd
+0,        359,        359,        1,   115200, 0x2cdf1146
+0,        360,        360,        1,   115200, 0x8a7d402c
+0,        361,        361,        1,   115200, 0x42d67bb3
+0,        362,        362,        1,   115200, 0x7045ff2c
+0,        363,        363,        1,   115200, 0xb67a4f15
+0,        364,        364,        1,   115200, 0x7481f311
+0,        365,        365,        1,   115200, 0xe394ff8d
+0,        366,        366,        1,   115200, 0x2ca16f23
+0,        367,        367,        1,   115200, 0xd53238e1
+0,        368,        368,        1,   115200, 0xe28a80c9
+0,        369,        369,        1,   115200, 0x043ccd51
+0,        370,        370,        1,   115200, 0x2e950d80
+0,        371,        371,        1,   115200, 0xf7394c6e
+0,        372,        372,        1,   115200, 0xae46d2c8
+0,        373,        373,        1,   115200, 0x4b54df85
+0,        374,        374,        1,   115200, 0x636f4ca5
+0,        375,        375,        1,   115200, 0x2c687754
+0,        376,        376,        1,   115200, 0x0ddea0f9
+0,        377,        377,        1,   115200, 0x82b08dfd
+0,        378,        378,        1,   115200, 0x5db58c25
+0,        379,        379,        1,   115200, 0x9b975eaa
+0,        380,        380,        1,   115200, 0x2cbe4bf1
+0,        381,        381,        1,   115200, 0xc8873bd7
+0,        382,        382,        1,   115200, 0x9aa357f2
+0,        383,        383,        1,   115200, 0x526e5392
+0,        384,        384,        1,   115200, 0x30aa5d18
+0,        385,        385,        1,   115200, 0x1fe738b4
+0,        386,        386,        1,   115200, 0x9cec04ad
+0,        387,        387,        1,   115200, 0x3ddd922d
+0,        388,        388,        1,   115200, 0xc6578bbb
+0,        389,        389,        1,   115200, 0x413c35ae
+0,        390,        390,        1,   115200, 0x90095ab3
+0,        391,        391,        1,   115200, 0x8ae84371
+0,        392,        392,        1,   115200, 0x1c935404
+0,        393,        393,        1,   115200, 0x213f37e8
+0,        394,        394,        1,   115200, 0x19ab39e6
+0,        395,        395,        1,   115200, 0x795bf82f
+0,        396,        396,        1,   115200, 0xe238fccf
+0,        397,        397,        1,   115200, 0xe2c0d69e
+0,        398,        398,        1,   115200, 0xa1e9d34c
+0,        399,        399,        1,   115200, 0xedf3d303
+0,        400,        400,        1,   115200, 0x40fac156
+0,        401,        401,        1,   115200, 0x1bc59ddb
+0,        402,        402,        1,   115200, 0x4295a2ab
+0,        403,        403,        1,   115200, 0xc337809d
+0,        404,        404,        1,   115200, 0x4a329996
+0,        405,        405,        1,   115200, 0xb4fa76b4
+0,        406,        406,        1,   115200, 0xb49b7d18
+0,        407,        407,        1,   115200, 0xfab67262
+0,        408,        408,        1,   115200, 0x31919404
+0,        409,        409,        1,   115200, 0x983d896c
+0,        410,        410,        1,   115200, 0x8594939e
+0,        411,        411,        1,   115200, 0x9fb8932a
+0,        412,        412,        1,   115200, 0xb9f3af07
+0,        413,        413,        1,   115200, 0x5904c5b4
+0,        414,        414,        1,   115200, 0xf6e095d6
+0,        415,        415,        1,   115200, 0xd168bd86
+0,        416,        416,        1,   115200, 0x39151a63
+0,        417,        417,        1,   115200, 0x9e426f6d
+0,        418,        418,        1,   115200, 0x0c6d7d1d
+0,        419,        419,        1,   115200, 0x65f787ca
+0,        420,        420,        1,   115200, 0xf42288c6
+0,        421,        421,        1,   115200, 0x565b8d91
+0,        422,        422,        1,   115200, 0xd72e882f
+0,        423,        423,        1,   115200, 0x8def886c
+0,        424,        424,        1,   115200, 0x1d5e7800
+0,        425,        425,        1,   115200, 0x628276f7
+0,        426,        426,        1,   115200, 0x00e27d0f
+0,        427,        427,        1,   115200, 0x52df7737
+0,        428,        428,        1,   115200, 0xf98f6303
+0,        429,        429,        1,   115200, 0x9a2d2d65
+0,        430,        430,        1,   115200, 0xd8cb25f5
+0,        431,        431,        1,   115200, 0x68071ce1
+0,        432,        432,        1,   115200, 0x4c6218c9
+0,        433,        433,        1,   115200, 0xaf0a11a3
+0,        434,        434,        1,   115200, 0xfa0a0fb9
+0,        435,        435,        1,   115200, 0xc61414fb
+0,        436,        436,        1,   115200, 0x3a8b0e94
+0,        437,        437,        1,   115200, 0x1eab0e92
+0,        438,        438,        1,   115200, 0xc726028c
+0,        439,        439,        1,   115200, 0x2da2f5de
+0,        440,        440,        1,   115200, 0x7672e92f
+0,        441,        441,        1,   115200, 0x7edae686
+0,        442,        442,        1,   115200, 0x9a6ce3c6
+0,        443,        443,        1,   115200, 0x9f69e74c
+0,        444,        444,        1,   115200, 0x73fbf502
+0,        445,        445,        1,   115200, 0xff81f5b8
+0,        446,        446,        1,   115200, 0x2b8bf7de
+0,        447,        447,        1,   115200, 0xcd00f380
+0,        448,        448,        1,   115200, 0x4cedfe7c
+0,        449,        449,        1,   115200, 0xcd30fbb4
+0,        450,        450,        1,   115200, 0x4b7df228
+0,        451,        451,        1,   115200, 0xedc7e5df
+0,        452,        452,        1,   115200, 0x687ae0f5
+0,        453,        453,        1,   115200, 0x8127e2b9
+0,        454,        454,        1,   115200, 0xe31ae11c
+0,        455,        455,        1,   115200, 0xece5e5c5
+0,        456,        456,        1,   115200, 0x4f1bdfe4
+0,        457,        457,        1,   115200, 0x65c5dfe3
+0,        458,        458,        1,   115200, 0xfc89d51f
+0,        459,        459,        1,   115200, 0xedd1c6bc
+0,        460,        460,        1,   115200, 0x2913d073
+0,        461,        461,        1,   115200, 0xf196fbbe
+0,        462,        462,        1,   115200, 0xc0be13e1
+0,        463,        463,        1,   115200, 0x55b21f01
+0,        464,        464,        1,   115200, 0xb16b2364
+0,        465,        465,        1,   115200, 0x4a8632db
+0,        466,        466,        1,   115200, 0x44c94426
+0,        467,        467,        1,   115200, 0xe5470b01
+0,        468,        468,        1,   115200, 0xd895d5d0
+0,        469,        469,        1,   115200, 0xe98715c2
+0,        470,        470,        1,   115200, 0x2688599b
+0,        471,        471,        1,   115200, 0x8e4889aa
+0,        472,        472,        1,   115200, 0x658bcd8d
+0,        473,        473,        1,   115200, 0xf0090c06
+0,        474,        474,        1,   115200, 0xefd9bd28
+0,        475,        475,        1,   115200, 0x45009bb4
+0,        476,        476,        1,   115200, 0x7ebd1655
+0,        477,        477,        1,   115200, 0x64ff7898
+0,        478,        478,        1,   115200, 0x4a9384f1
+0,        479,        479,        1,   115200, 0xd80f0701
+0,        480,        480,        1,   115200, 0x2f855116
+0,        481,        481,        1,   115200, 0x0c1313cb
+0,        482,        482,        1,   115200, 0xf4df4d19
+0,        483,        483,        1,   115200, 0xde6218fb
+0,        484,        484,        1,   115200, 0xce26e6b4
+0,        485,        485,        1,   115200, 0x848af931
+0,        486,        486,        1,   115200, 0x86770a97
+0,        487,        487,        1,   115200, 0x8f35c3c0
+0,        488,        488,        1,   115200, 0xb26dc220
+0,        489,        489,        1,   115200, 0x3d5bbfce
+0,        490,        490,        1,   115200, 0xa1f9bee6
+0,        491,        491,        1,   115200, 0xa87dcd24
+0,        492,        492,        1,   115200, 0x9374cb71
+0,        493,        493,        1,   115200, 0x0c7ccbd0
+0,        494,        494,        1,   115200, 0x9a16cc49
+0,        495,        495,        1,   115200, 0x4df0c28b
+0,        496,        496,        1,   115200, 0xb5b8b866
+0,        497,        497,        1,   115200, 0xafcc1019
+0,        510,        510,        1,   115200, 0x623b0ff3
diff --git a/tests/ref/fate/wtv-demux b/tests/ref/fate/wtv-demux
index bdd6c20..362c55b 100644
--- a/tests/ref/fate/wtv-demux
+++ b/tests/ref/fate/wtv-demux
@@ -33,109 +33,109 @@
 1,    7199998,    7199998,   240000,      576, 0xeb4b0d93
 1,    7439998,    7439998,   240000,      576, 0xde1322f5
 1,    7679998,    7679998,   240000,      576, 0xc3131f35
-0,    7886331,    9486442,   400000,    41980, 0xd4920915
 1,    7919998,    7919998,   240000,      576, 0x708f1381
 1,    8159998,    8159998,   240000,      576, 0x1f00137e
+0,    8286442,    9486442,   400000,    41980, 0xd4920915
 1,    8399998,    8399998,   240000,      576, 0x05131eb0
 1,    8639998,    8639998,   240000,      576, 0x78151c22
-0,    8686442,    8686442,   400000,     7228, 0x1b141fa3
+0,    8686442,    8686442,   400000,     7228, 0x1b141fa3, F=0x0
 1,    8879998,    8879998,   240000,      576, 0x31771239
-0,    9086331,    9086331,   400000,     7492, 0x1a47f3e4
+0,    9086331,    9086331,   400000,     7492, 0x1a47f3e4, F=0x0
 1,    9119998,    9119998,   240000,      576, 0x3ce4097c
 1,    9359998,    9359998,   240000,      576, 0x180e15f4
-0,    9486442,   10686331,   400000,    25068, 0xcb70a744
+0,    9486442,   10686331,   400000,    25068, 0xcb70a744, F=0x0
 1,    9599998,    9599998,   240000,      576, 0x30db0604
 1,    9839998,    9839998,   240000,      576, 0x9b290284
-0,    9886442,    9886442,   400000,     7212, 0x0ab9f558
+0,    9886442,    9886442,   400000,     7212, 0x0ab9f558, F=0x0
 1,   10079998,   10079998,   240000,      576, 0xcf340753
-0,   10286442,   10286442,   400000,     7612, 0xa93054f0
+0,   10286442,   10286442,   400000,     7612, 0xa93054f0, F=0x0
 1,   10319998,   10319998,   240000,      576, 0xdaa41457
 1,   10559998,   10559998,   240000,      576, 0x34d310a2
-0,   10686331,   11886331,   400000,    22868, 0xa77db64a
+0,   10686331,   11886331,   400000,    22868, 0xa77db64a, F=0x0
 1,   10799998,   10799998,   240000,      576, 0x58b31010
 1,   11039998,   11039998,   240000,      576, 0x19610f54
-0,   11086442,   11086442,   400000,     6260, 0x6cf76411
+0,   11086442,   11086442,   400000,     6260, 0x6cf76411, F=0x0
 1,   11279998,   11279998,   240000,      576, 0x17762352
-0,   11486331,   11486331,   400000,     6156, 0xe168394b
+0,   11486331,   11486331,   400000,     6156, 0xe168394b, F=0x0
 1,   11519998,   11519998,   240000,      576, 0x1fea1448
 1,   11759998,   11759998,   240000,      576, 0x55840a01
-0,   11886331,   13086442,   449438,    23364, 0x53164f1e
+0,   11886331,   13086442,   400000,    23364, 0x53164f1e, F=0x0
 1,   11999998,   11999998,   240000,      576, 0x6c9c24ce
 1,   12239998,   12239998,   240000,      576, 0x955f1e97
-0,   12286442,   12286442,   449438,     6708, 0x89877269
+0,   12286442,   12286442,   400000,     6708, 0x89877269, F=0x0
 1,   12479998,   12479998,   240000,      576, 0x2827134f
-0,   12686442,   12686442,   449438,     6908, 0x8d62a249
+0,   12686442,   12686442,   400000,     6908, 0x8d62a249, F=0x0
 1,   12719998,   12719998,   240000,      576, 0x34a01c29
 1,   12959998,   12959998,   240000,      576, 0x7d351e52
-0,   13086442,   14286442,   449438,    38156, 0xec41f682
+0,   13086442,   14286442,   400000,    38156, 0xec41f682
 1,   13199998,   13199998,   240000,      576, 0x00c91d9e
 1,   13439998,   13439998,   240000,      576, 0x57ea1a97
-0,   13486331,   13486331,   449438,     5764, 0xcc04534b
+0,   13486331,   13486331,   400000,     5764, 0xcc04534b, F=0x0
 1,   13679998,   13679998,   240000,      576, 0xef3a1c74
-0,   13886331,   13886331,   449438,     5388, 0xb8a1c3c5
+0,   13886331,   13886331,   400000,     5388, 0xb8a1c3c5, F=0x0
 1,   13919998,   13919998,   240000,      576, 0x11fc217d
 1,   14159998,   14159998,   240000,      576, 0x59ce20e5
-0,   14286442,   15486331,   449438,    16764, 0x59460d96
+0,   14286442,   15486331,   400000,    16764, 0x59460d96, F=0x0
 1,   14399998,   14399998,   240000,      576, 0xaafc1dbf
 1,   14639998,   14639998,   240000,      576, 0xdd941609
-0,   14686331,   14686331,   449438,     5548, 0x5c91e93d
+0,   14686331,   14686331,   400000,     5548, 0x5c91e93d, F=0x0
 1,   14879998,   14879998,   240000,      576, 0x900420b0
-0,   15086331,   15086331,   449438,     5652, 0x5e321aed
+0,   15086331,   15086331,   400000,     5652, 0x5e321aed, F=0x0
 1,   15119998,   15119998,   240000,      576, 0x5f4f1aa1
 1,   15359998,   15359998,   240000,      576, 0x7d7e18de
-0,   15486331,   16686331,   449438,    15564, 0xefdf5080
+0,   15486331,   16686331,   400000,    15564, 0xefdf5080, F=0x0
 1,   15599998,   15599998,   240000,      576, 0x986c0d9d
 1,   15839998,   15839998,   240000,      576, 0xcb4c21c0
-0,   15886331,   15886331,   449438,     6492, 0xd1d5c5f8
+0,   15886331,   15886331,   400000,     6492, 0xd1d5c5f8, F=0x0
 1,   16079998,   16079998,   240000,      576, 0xbcfb1e8b
-0,   16286331,   16286331,   449438,     5604, 0xf9472b44
+0,   16286331,   16286331,   400000,     5604, 0xf9472b44, F=0x0
 1,   16319998,   16319998,   240000,      576, 0xcb541b4c
 1,   16559998,   16559998,   240000,      576, 0x980426e9
-0,   16686331,   17886331,   449438,    17924, 0x45815b7b
+0,   16686331,   17886331,   400000,    17924, 0x45815b7b, F=0x0
 1,   16799998,   16799998,   240000,      576, 0x09d00aa0
 1,   17039998,   17039998,   240000,      576, 0xad591374
-0,   17086442,   17086442,   449438,     5020, 0x3cc5e554
+0,   17086442,   17086442,   400000,     5020, 0x3cc5e554, F=0x0
 1,   17279998,   17279998,   240000,      576, 0x97bf1461
-0,   17486442,   17486442,   449438,     5276, 0xa0554c12
+0,   17486442,   17486442,   400000,     5276, 0xa0554c12, F=0x0
 1,   17519998,   17519998,   240000,      576, 0xdc871cc4
 1,   17759998,   17759998,   240000,      576, 0x56781896
-0,   17886331,   19086442,   449438,    31460, 0x5765eb5f
+0,   17886331,   19086442,   400000,    31460, 0x5765eb5f
 1,   17999998,   17999998,   240000,      576, 0xc77714e3
 1,   18239998,   18239998,   240000,      576, 0x280e18d4
-0,   18286331,   18286331,   449438,     4972, 0x91adbab7
+0,   18286331,   18286331,   400000,     4972, 0x91adbab7, F=0x0
 1,   18479998,   18479998,   240000,      576, 0xbc0d2302
-0,   18686442,   18686442,   449438,     5580, 0xfea707cb
+0,   18686442,   18686442,   400000,     5580, 0xfea707cb, F=0x0
 1,   18719998,   18719998,   240000,      576, 0x79191384
 1,   18959998,   18959998,   240000,      576, 0x65481c97
-0,   19086442,   20286331,   449438,    17412, 0x0afe4d27
+0,   19086442,   20286331,   400000,    17412, 0x0afe4d27, F=0x0
 1,   19199998,   19199998,   240000,      576, 0xc94d227d
 1,   19439998,   19439998,   240000,      576, 0xa68a1f14
-0,   19486442,   19486442,   449438,     5236, 0x03f55309
+0,   19486442,   19486442,   400000,     5236, 0x03f55309, F=0x0
 1,   19679998,   19679998,   240000,      576, 0x6af11a5c
-0,   19886331,   19886331,   449438,     4924, 0x558e753c
+0,   19886331,   19886331,   400000,     4924, 0x558e753c, F=0x0
 1,   19919998,   19919998,   240000,      576, 0x4d1019ef
 1,   20159998,   20159998,   240000,      576, 0x3b1b17b5
-0,   20286331,   21486331,   449438,    15396, 0xf145d121
+0,   20286331,   21486331,   400000,    15396, 0xf145d121, F=0x0
 1,   20399998,   20399998,   240000,      576, 0xcdd8159f
 1,   20639998,   20639998,   240000,      576, 0x97cd1d06
-0,   20686331,   20686331,   449438,     4708, 0x43066a92
+0,   20686331,   20686331,   400000,     4708, 0x43066a92, F=0x0
 1,   20879998,   20879998,   240000,      576, 0x5d1b1123
-0,   21086442,   21086442,   449438,     4332, 0x9e22bcba
+0,   21086442,   21086442,   400000,     4332, 0x9e22bcba, F=0x0
 1,   21119998,   21119998,   240000,      576, 0x888d0cb0
 1,   21359998,   21359998,   240000,      576, 0x556e1dad
-0,   21486331,   22686442,   449438,    12876, 0x46ff9ef4
+0,   21486331,   22686442,   400000,    12876, 0x46ff9ef4, F=0x0
 1,   21599998,   21599998,   240000,      576, 0xf7af0bce
 1,   21839998,   21839998,   240000,      576, 0xb5da160a
-0,   21886442,   21886442,   449438,     5940, 0x27cba62e
+0,   21886442,   21886442,   400000,     5940, 0x27cba62e, F=0x0
 1,   22079998,   22079998,   240000,      576, 0x4a8d0e98
-0,   22286442,   22286442,   449438,     6124, 0x6bab0a6d
+0,   22286442,   22286442,   400000,     6124, 0x6bab0a6d, F=0x0
 1,   22319998,   22319998,   240000,      576, 0x183b1c7e
 1,   22559998,   22559998,   240000,      576, 0xc47120e6
-0,   22686442,   23886442,   449438,    36428, 0x942f9648
+0,   22686442,   23886442,   400000,    36428, 0x942f9648
 1,   22799998,   22799998,   240000,      576, 0xb1f31346
-0,   23086331,   23086331,   449438,     6660, 0x545a0db7
-0,   23486331,   23486331,   449438,     6780, 0x2d1d4189
-0,   23886442,   25086331,   449438,    16460, 0x7c3b3ca4
-0,   24286442,   24286442,   449438,     6724, 0x8538cc6f
-0,   24686442,   24686442,   449438,     7068, 0x69574fd0
-0,   25086331,   26286331,   449438,    19552, 0xf230e854
+0,   23086331,   23086331,   400000,     6660, 0x545a0db7, F=0x0
+0,   23486331,   23486331,   400000,     6780, 0x2d1d4189, F=0x0
+0,   23886442,   25086331,   400000,    16460, 0x7c3b3ca4, F=0x0
+0,   24286442,   24286442,   400000,     6724, 0x8538cc6f, F=0x0
+0,   24686442,   24686442,   400000,     7068, 0x69574fd0, F=0x0
+0,   25086331,   26286331,   400000,    19552, 0xf230e854, F=0x0
diff --git a/tests/ref/fate/xmv-demux b/tests/ref/fate/xmv-demux
index 20c6ac1..49f22c9 100644
--- a/tests/ref/fate/xmv-demux
+++ b/tests/ref/fate/xmv-demux
@@ -7,32 +7,32 @@
 1,        249,        249,       83,     5976, 0x4ea056f4
 1,        332,        332,       83,     5976, 0xda772d8d
 1,        415,        415,       83,     5976, 0xafacf7c9
-0,        640,        640,        0,      108, 0x06713c96
-0,        680,        680,        0,      952, 0xd306df7e
-0,        720,        720,        0,     2312, 0xaf316585
+0,        640,        640,        0,      108, 0x06713c96, F=0x0
+0,        680,        680,        0,      952, 0xd306df7e, F=0x0
+0,        720,        720,        0,     2312, 0xaf316585, F=0x0
 1,        498,        498,       83,     5976, 0xdeb003f4
-0,        760,        760,        0,     3872, 0xfc1c527c
-0,        800,        800,        0,       20, 0xaffc0edd
-0,        840,        840,        0,     6600, 0xe1b66c7f
+0,        760,        760,        0,     3872, 0xfc1c527c, F=0x0
+0,        800,        800,        0,       20, 0xaffc0edd, F=0x0
+0,        840,        840,        0,     6600, 0xe1b66c7f, F=0x0
 1,        581,        581,       28,     2016, 0xa7380d36
-0,        880,        880,        0,     6868, 0xd5b3f631
+0,        880,        880,        0,     6868, 0xd5b3f631, F=0x0
 1,        609,        609,       28,     2016, 0xbc090bac
-0,        920,        920,        0,     8420, 0xf70ee33b
+0,        920,        920,        0,     8420, 0xf70ee33b, F=0x0
 1,        637,        637,       28,     2016, 0x6f8c164c
-0,        960,        960,        0,    13144, 0x9a54ef39
+0,        960,        960,        0,    13144, 0x9a54ef39, F=0x0
 1,        665,        665,       28,     2016, 0x13b80e28
-0,       1000,       1000,        0,     6340, 0xe55bf555
+0,       1000,       1000,        0,     6340, 0xe55bf555, F=0x0
 1,        693,        693,       28,     2016, 0xd40ff863
-0,       1040,       1040,        0,     3736, 0x0b23f89f
+0,       1040,       1040,        0,     3736, 0x0b23f89f, F=0x0
 1,        721,        721,       28,     2016, 0x4d530ed7
-0,       1080,       1080,        0,     2624, 0x79e2e451
+0,       1080,       1080,        0,     2624, 0x79e2e451, F=0x0
 1,        749,        749,       30,     2160, 0x0fbc37eb
-0,       1120,       1120,        0,     1860, 0x63886f11
+0,       1120,       1120,        0,     1860, 0x63886f11, F=0x0
 1,        779,        779,      192,    13824, 0x82fb2602
-0,       1160,       1160,        0,     1244, 0x74594601
-0,       1200,       1200,        0,      564, 0xf4561dfb
-0,       1240,       1240,        0,       80, 0xbf8e2e30
-0,       1280,       1280,        0,       20, 0xa0990c29
+0,       1160,       1160,        0,     1244, 0x74594601, F=0x0
+0,       1200,       1200,        0,      564, 0xf4561dfb, F=0x0
+0,       1240,       1240,        0,       80, 0xbf8e2e30, F=0x0
+0,       1280,       1280,        0,       20, 0xa0990c29, F=0x0
 1,        971,        971,      192,    13824, 0x08771caf
 1,       1163,       1163,      192,    13824, 0xdf7d4a65
 1,       1355,       1355,      193,    13896, 0x24bf3f47
@@ -40,35 +40,35 @@
 1,       1598,       1598,       50,     3600, 0x8c666fd6
 1,       1648,       1648,       50,     3600, 0x305c6ca1
 1,       1698,       1698,       50,     3600, 0x48b04e1e
-0,       2480,       2480,        0,      104, 0x12413980
-0,       2520,       2520,        0,      796, 0x2e698ed3
+0,       2480,       2480,        0,      104, 0x12413980, F=0x0
+0,       2520,       2520,        0,      796, 0x2e698ed3, F=0x0
 1,       1748,       1748,       50,     3600, 0x8c915935
-0,       2560,       2560,        0,     1808, 0x8b3e6e5e
-0,       2600,       2600,        0,     4712, 0xdbd51737
+0,       2560,       2560,        0,     1808, 0x8b3e6e5e, F=0x0
+0,       2600,       2600,        0,     4712, 0xdbd51737, F=0x0
 1,       1798,       1798,       50,     3600, 0xa8f45e01
-0,       2640,       2640,        0,     5548, 0xee9c831c
-0,       2680,       2680,        0,     6152, 0x9c18ccc1
+0,       2640,       2640,        0,     5548, 0xee9c831c, F=0x0
+0,       2680,       2680,        0,     6152, 0x9c18ccc1, F=0x0
 1,       1848,       1848,       53,     3816, 0xc64cc5ed
-0,       2720,       2720,        0,     6452, 0x7860462a
+0,       2720,       2720,        0,     6452, 0x7860462a, F=0x0
 1,       1901,       1901,       27,     1944, 0x0ac2e3f1
-0,       2760,       2760,        0,     6676, 0xe1b1c9e4
+0,       2760,       2760,        0,     6676, 0xe1b1c9e4, F=0x0
 1,       1928,       1928,       27,     1944, 0x2197dccd
-0,       2800,       2800,        0,    10904, 0x0bded7b7
+0,       2800,       2800,        0,    10904, 0x0bded7b7, F=0x0
 1,       1955,       1955,       27,     1944, 0x0c02e77f
-0,       2840,       2840,        0,    12844, 0xe6d16cff
+0,       2840,       2840,        0,    12844, 0xe6d16cff, F=0x0
 1,       1982,       1982,       27,     1944, 0x675ee06a
-0,       2880,       2880,        0,    10920, 0xe114c46b
+0,       2880,       2880,        0,    10920, 0xe114c46b, F=0x0
 1,       2009,       2009,       30,     2160, 0x0d803a8b
-0,       2920,       2920,        0,     5952, 0xb7464634
+0,       2920,       2920,        0,     5952, 0xb7464634, F=0x0
 1,       2039,       2039,       93,     6696, 0xa7a0dfea
-0,       2960,       2960,        0,     4732, 0x2fa2e36d
-0,       3000,       3000,        0,     2592, 0xf54ddd57
-0,       3040,       3040,        0,     1516, 0x4a1cd4d5
-0,       3080,       3080,        0,      864, 0x49889afc
+0,       2960,       2960,        0,     4732, 0x2fa2e36d, F=0x0
+0,       3000,       3000,        0,     2592, 0xf54ddd57, F=0x0
+0,       3040,       3040,        0,     1516, 0x4a1cd4d5, F=0x0
+0,       3080,       3080,        0,      864, 0x49889afc, F=0x0
 1,       2132,       2132,       93,     6696, 0x59aa3145
-0,       3120,       3120,        0,      468, 0x3932e6a4
-0,       3160,       3160,        0,      116, 0x2b8341e6
-0,       3200,       3200,        0,       16, 0x6a3109cf
+0,       3120,       3120,        0,      468, 0x3932e6a4, F=0x0
+0,       3160,       3160,        0,      116, 0x2b8341e6, F=0x0
+0,       3200,       3200,        0,       16, 0x6a3109cf, F=0x0
 1,       2225,       2225,       93,     6696, 0x69be4d78
 1,       2318,       2318,       93,     6696, 0x64064c67
 1,       2411,       2411,       93,     6696, 0xc8536f98
@@ -80,104 +80,104 @@
 1,       2937,       2937,      123,     8856, 0x19e18797
 1,       3060,       3060,      123,     8856, 0x0a0c7fbd
 1,       3183,       3183,      124,     8928, 0x4a9b2d42
-0,       4640,       4640,        0,      100, 0x45023894
-0,       4680,       4680,        0,      948, 0xa65ed345
-0,       4720,       4720,      108,     2808, 0xd7285746
-0,       4760,       4760,      108,     5372, 0x05794175
+0,       4640,       4640,        0,      100, 0x45023894, F=0x0
+0,       4680,       4680,        0,      948, 0xa65ed345, F=0x0
+0,       4720,       4720,        0,     2808, 0xd7285746, F=0x0
+0,       4760,       4760,       40,     5372, 0x05794175, F=0x0
 1,       3307,       3307,       21,     1512, 0xed8b3f4b
-0,       4800,       4800,      108,    11596, 0x8636eca7
+0,       4800,       4800,       40,    11596, 0x8636eca7, F=0x0
 1,       3328,       3328,       21,     1512, 0xa27d3891
-0,       4840,       4840,      108,    11524, 0xe1f39be3
+0,       4840,       4840,       40,    11524, 0xe1f39be3, F=0x0
 1,       3349,       3349,       21,     1512, 0xb0f13eb6
-0,       4880,       4880,      108,    23392, 0xab053f05
+0,       4880,       4880,       40,    23392, 0xab053f05, F=0x0
 1,       3370,       3370,       23,     1656, 0xe5a98324
-0,       4920,       4920,      108,     4560, 0x03197d07
+0,       4920,       4920,       40,     4560, 0x03197d07, F=0x0
 1,       3393,       3393,       31,     2232, 0x15445433
-0,       4960,       4960,      108,     4440, 0x1cc361a2
+0,       4960,       4960,       40,     4440, 0x1cc361a2, F=0x0
 1,       3424,       3424,       31,     2232, 0x5cb348a9
-0,       5000,       5000,      108,    23688, 0x16030634
+0,       5000,       5000,       40,    23688, 0x16030634, F=0x0
 1,       3455,       3455,       31,     2232, 0xf10347da
-0,       5040,       5040,      108,    16132, 0xf0eca799
+0,       5040,       5040,       40,    16132, 0xf0eca799, F=0x0
 1,       3486,       3486,       34,     2448, 0x3e16a175
-0,       5080,       5080,      108,    29896, 0x0c0988ea
+0,       5080,       5080,       40,    29896, 0x0c0988ea, F=0x0
 1,       3520,       3520,       35,     2520, 0x17e3ca2b
-0,       5120,       5120,      108,    19956, 0x0093aa0b
+0,       5120,       5120,       40,    19956, 0x0093aa0b, F=0x0
 1,       3555,       3555,       27,     1944, 0x35c2de84
-0,       5160,       5160,      108,    16392, 0x8829a9ca
+0,       5160,       5160,       40,    16392, 0x8829a9ca, F=0x0
 1,       3582,       3582,       27,     1944, 0x55b4db40
-0,       5200,       5200,      108,    16772, 0x9a4a546d
+0,       5200,       5200,       40,    16772, 0x9a4a546d, F=0x0
 1,       3609,       3609,       29,     2088, 0xdaae14b2
-0,       5240,       5240,      108,     8920, 0xcd8ca203
+0,       5240,       5240,       40,     8920, 0xcd8ca203, F=0x0
 1,       3638,       3638,       27,     1944, 0x92ccd37f
-0,       5280,       5280,      108,     9632, 0x53c1d37b
+0,       5280,       5280,       40,     9632, 0x53c1d37b, F=0x0
 1,       3665,       3665,       27,     1944, 0x70efede1
-0,       5320,       5320,      108,     8976, 0xfe4da2cc
+0,       5320,       5320,       40,     8976, 0xfe4da2cc, F=0x0
 1,       3692,       3692,       27,     1944, 0x7601d304
-0,       5360,       5360,      108,     6680, 0x35348fe0
+0,       5360,       5360,       40,     6680, 0x35348fe0, F=0x0
 1,       3719,       3719,       27,     1944, 0x3922ebc2
-0,       5400,       5400,      108,     9228, 0xcbf62b0c
+0,       5400,       5400,       40,     9228, 0xcbf62b0c, F=0x0
 1,       3746,       3746,       30,     2160, 0xde462f2e
-0,       5440,       5440,      108,     5108, 0xd1d88511
+0,       5440,       5440,       40,     5108, 0xd1d88511, F=0x0
 1,       3776,       3776,       26,     1872, 0x467ac1d2
-0,       5480,       5480,      108,    10016, 0xaff4b2b2
+0,       5480,       5480,       40,    10016, 0xaff4b2b2, F=0x0
 1,       3802,       3802,       26,     1872, 0xa1e4cd43
-0,       5520,       5520,      108,     7468, 0x23e81ab8
+0,       5520,       5520,       40,     7468, 0x23e81ab8, F=0x0
 1,       3828,       3828,       26,     1872, 0x1dceccc6
-0,       5560,       5560,      108,     4172, 0x253cd05b
+0,       5560,       5560,       40,     4172, 0x253cd05b, F=0x0
 1,       3854,       3854,       26,     1872, 0x2bbad2a5
-0,       5600,       5600,      108,     8188, 0x7ede743f
+0,       5600,       5600,       40,     8188, 0x7ede743f, F=0x0
 1,       3880,       3880,       26,     1872, 0xc603d44d
-0,       5640,       5640,      108,     2884, 0x2dec55a3
+0,       5640,       5640,       40,     2884, 0x2dec55a3, F=0x0
 1,       3906,       3906,       26,     1872, 0x1b4cc261
-0,       5680,       5680,      108,     3900, 0xd0666a18
+0,       5680,       5680,       40,     3900, 0xd0666a18, F=0x0
 1,       3932,       3932,       26,     1872, 0x10edd6cf
-0,       5720,       5720,      108,     2996, 0x9cc99b8c
+0,       5720,       5720,       40,     2996, 0x9cc99b8c, F=0x0
 1,       3958,       3958,       33,     2376, 0xecdb9d61
-0,       5760,       5760,      108,     2156, 0xae612776
+0,       5760,       5760,       40,     2156, 0xae612776, F=0x0
 1,       3991,       3991,       36,     2592, 0x5559eced
-0,       5800,       5800,      108,     3988, 0x0d2c9992
-0,       5840,       5840,      108,     1512, 0x6281fc00
+0,       5800,       5800,       40,     3988, 0x0d2c9992, F=0x0
+0,       5840,       5840,       40,     1512, 0x6281fc00, F=0x0
 1,       4027,       4027,       36,     2592, 0x8848dfc7
-0,       5880,       5880,      108,     6544, 0xb75c2562
+0,       5880,       5880,       40,     6544, 0xb75c2562, F=0x0
 1,       4063,       4063,       36,     2592, 0x4ca2d7da
-0,       5920,       5920,      108,     4108, 0xfb21efc9
+0,       5920,       5920,       40,     4108, 0xfb21efc9, F=0x0
 1,       4099,       4099,       36,     2592, 0x285fd7e6
-0,       5960,       5960,      108,     1096, 0x85922a37
-0,       6000,       6000,      108,     9740, 0xe57d7647
+0,       5960,       5960,       40,     1096, 0x85922a37, F=0x0
+0,       6000,       6000,       40,     9740, 0xe57d7647, F=0x0
 1,       4135,       4135,       36,     2592, 0x2717e404
-0,       6040,       6040,      108,      416, 0x61c2ea02
+0,       6040,       6040,       40,      416, 0x61c2ea02, F=0x0
 1,       4171,       4171,       36,     2592, 0xf106111a
-0,       6080,       6080,      108,      336, 0x1dc5ac1c
+0,       6080,       6080,       40,      336, 0x1dc5ac1c, F=0x0
 1,       4207,       4207,       36,     2592, 0xd7d01119
-0,       6120,       6120,      108,      204, 0x16f57017
+0,       6120,       6120,       40,      204, 0x16f57017, F=0x0
 1,       4243,       4243,       36,     2592, 0x550cfeda
-0,       6160,       6160,      108,      112, 0x78374234
-0,       6200,       6200,      108,       40, 0x6cb21985
+0,       6160,       6160,       40,      112, 0x78374234, F=0x0
+0,       6200,       6200,       40,       40, 0x6cb21985, F=0x0
 1,       4279,       4279,       36,     2592, 0x47ad00c4
 1,       4315,       4315,       36,     2592, 0x39bbf306
 1,       4351,       4351,       45,     3240, 0x69addfce
 1,       4396,       4396,      297,    21384, 0x254f63e0
 1,       4693,       4693,      298,    21456, 0x2f7a9859
-0,       6840,       6840,      108,    14420, 0x53324ca4
-0,       6880,       6880,      108,       40, 0x10971420
+0,       6840,       6840,       40,    14420, 0x53324ca4, F=0x0
+0,       6880,       6880,       40,       40, 0x10971420, F=0x0
 1,       4991,       4991,      521,    37512, 0x6e962928
 1,       5512,       5512,       38,     2736, 0x1dc91c69
-0,       8000,       8000,      108,    24904, 0x15574f7e
+0,       8000,       8000,       40,    24904, 0x15574f7e
 1,       5550,       5550,       38,     2736, 0x023434fd
 1,       5588,       5588,       38,     2736, 0x906f1541
-0,       8160,       8160,      108,     1908, 0xccb2dd3c
+0,       8160,       8160,       40,     1908, 0xccb2dd3c, F=0x0
 1,       5626,       5626,       38,     2736, 0x85a31102
-0,       8200,       8200,      108,     4676, 0xbfa42b7e
+0,       8200,       8200,       40,     4676, 0xbfa42b7e, F=0x0
 1,       5664,       5664,       42,     3024, 0x9296a5f3
-0,       8240,       8240,      108,     3600, 0x87c9dc58
-0,       8280,       8280,      108,     8184, 0x504a8e65
+0,       8240,       8240,       40,     3600, 0x87c9dc58, F=0x0
+0,       8280,       8280,       40,     8184, 0x504a8e65, F=0x0
 1,       5706,       5706,       27,     1944, 0x7bf4dedc
-0,       8320,       8320,      108,     9636, 0x2efb3006
+0,       8320,       8320,       40,     9636, 0x2efb3006, F=0x0
 1,       5733,       5733,       27,     1944, 0x4196c404
 1,       5760,       5760,       27,     1944, 0xcda97c7a
-0,       8360,       8360,      108,     9580, 0x0fb6f4e8
+0,       8360,       8360,       40,     9580, 0x0fb6f4e8, F=0x0
 1,       5787,       5787,       27,     1944, 0x5f4922b2
-0,       8400,       8400,      108,     7840, 0xe996f564
+0,       8400,       8400,       40,     7840, 0xe996f564, F=0x0
 1,       5814,       5814,       29,     2088, 0x37dfc157
-0,       8440,       8440,      108,     4208, 0xe9c2fba2
-0,       8480,       8480,      108,      556, 0x3f1e077c
+0,       8440,       8440,       40,     4208, 0xe9c2fba2, F=0x0
+0,       8480,       8480,       40,      556, 0x3f1e077c, F=0x0
diff --git a/tests/ref/fate/yop b/tests/ref/fate/yop
index 5629825..537447a 100644
--- a/tests/ref/fate/yop
+++ b/tests/ref/fate/yop
@@ -1,8 +1,8 @@
 #tb 0: 1/12
-0,          0,          0,        1,   302760, 0x78939253
-0,          1,          1,        1,   302760, 0x534f5253
-0,          2,          2,        1,   302760, 0xe991aa82
-0,          3,          3,        1,   302760, 0xc34b20bd
-0,          4,          4,        1,   302760, 0x461d29a1
-0,          5,          5,        1,   302760, 0x45abca02
-0,          6,          6,        1,   302760, 0xb05448b9
+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,          5,          5,        1,   302760, 0x26e93266
+0,          6,          6,        1,   302760, 0x4cddb216
diff --git a/tests/ref/fate/zmbv-8bit b/tests/ref/fate/zmbv-8bit
index 64dacae..f104c98 100644
--- a/tests/ref/fate/zmbv-8bit
+++ b/tests/ref/fate/zmbv-8bit
@@ -1,4 +1,4 @@
-#tb 0: 1000000/70086303
+#tb 0: 15967/1119068
 0,          0,          0,        1,   192000, 0x5234b617
 0,          1,          1,        1,   192000, 0x5234b617
 0,          2,          2,        1,   192000, 0x5234b617
@@ -274,3 +274,4 @@
 0,        272,        272,        1,   192000, 0xd08e49d1
 0,        273,        273,        1,   192000, 0xd08e49d1
 0,        274,        274,        1,   192000, 0xd08e49d1
+0,        275,        275,        1,   192000, 0x1f34135f
diff --git a/tests/ref/lavf-fate/latm b/tests/ref/lavf-fate/latm
new file mode 100644
index 0000000..8c4f541
--- /dev/null
+++ b/tests/ref/lavf-fate/latm
@@ -0,0 +1,3 @@
+eb13788e71c9b5bc7d62ceb748312bbb *./tests/data/lavf-fate/lavf.latm
+67876 ./tests/data/lavf-fate/lavf.latm
+./tests/data/lavf-fate/lavf.latm CRC=0xcf94c59d
diff --git a/tests/ref/lavf-fate/mp3 b/tests/ref/lavf-fate/mp3
new file mode 100644
index 0000000..91e2b48
--- /dev/null
+++ b/tests/ref/lavf-fate/mp3
@@ -0,0 +1,3 @@
+40a4e41ae74ec8dacdf02402831a6a58 *./tests/data/lavf-fate/lavf.mp3
+97230 ./tests/data/lavf-fate/lavf.mp3
+./tests/data/lavf-fate/lavf.mp3 CRC=0x6c9850fe
diff --git a/tests/ref/lavf-fate/ogg_vp3 b/tests/ref/lavf-fate/ogg_vp3
new file mode 100644
index 0000000..b77476d
--- /dev/null
+++ b/tests/ref/lavf-fate/ogg_vp3
@@ -0,0 +1,3 @@
+adbe6c30bdfe934dc5ae397f4db2960d *./tests/data/lavf-fate/lavf.ogg
+417644 ./tests/data/lavf-fate/lavf.ogg
+./tests/data/lavf-fate/lavf.ogg CRC=0x037e3e79
diff --git a/tests/ref/lavf/asf b/tests/ref/lavf/asf
index 0137925..cfa53dc 100644
--- a/tests/ref/lavf/asf
+++ b/tests/ref/lavf/asf
@@ -1,3 +1,3 @@
-528d3cbe33288ad983a8ff5b66738976 *./tests/data/lavf/lavf.asf
-333375 ./tests/data/lavf/lavf.asf
-./tests/data/lavf/lavf.asf CRC=0xba1f5213
+3937dfece4b48c0cdd8f44bcab3cdd2d *./tests/data/lavf/lavf.asf
+333581 ./tests/data/lavf/lavf.asf
+./tests/data/lavf/lavf.asf CRC=0x51485213
diff --git a/tests/ref/lavf/avi b/tests/ref/lavf/avi
index ae85efc..056d0c7 100644
--- a/tests/ref/lavf/avi
+++ b/tests/ref/lavf/avi
@@ -1,3 +1,3 @@
-e056e1164236b22fafc8325de8221a58 *./tests/data/lavf/lavf.avi
-330798 ./tests/data/lavf/lavf.avi
-./tests/data/lavf/lavf.avi CRC=0xa79b84dd
+feb26a85f820ede7e521a55be565f3b1 *./tests/data/lavf/lavf.avi
+330806 ./tests/data/lavf/lavf.avi
+./tests/data/lavf/lavf.avi CRC=0x4780846b
diff --git a/tests/ref/lavf/caf b/tests/ref/lavf/caf
new file mode 100644
index 0000000..972b27c
--- /dev/null
+++ b/tests/ref/lavf/caf
@@ -0,0 +1,3 @@
+71e1abdfc59613fe05fca2939f02e02d *./tests/data/lavf/lavf.caf
+90204 ./tests/data/lavf/lavf.caf
+./tests/data/lavf/lavf.caf CRC=0xf1ae5536
diff --git a/tests/ref/lavf/dpx b/tests/ref/lavf/dpx
index a852ae0..1196934 100644
--- a/tests/ref/lavf/dpx
+++ b/tests/ref/lavf/dpx
@@ -1,3 +1,9 @@
 808ea110635774252439722a48329d61 *./tests/data/images/dpx/02.dpx
 ./tests/data/images/dpx/%02d.dpx CRC=0x6da01946
 305792 ./tests/data/images/dpx/02.dpx
+5e1a777fa3f4094c9c4dd989cf9e8e8b *./tests/data/images/dpx/02.dpx
+./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
+407168 ./tests/data/images/dpx/02.dpx
diff --git a/tests/ref/lavf/dv_fmt b/tests/ref/lavf/dv_fmt
index c2b7335..e8720af 100644
--- a/tests/ref/lavf/dv_fmt
+++ b/tests/ref/lavf/dv_fmt
@@ -1,3 +1,9 @@
-eb51fbb48af28584ea5515f9f2400fcd *./tests/data/lavf/lavf.dv
+6f9cfff48f536fa727696f2f9fb3ac08 *./tests/data/lavf/lavf.dv
+3600000 ./tests/data/lavf/lavf.dv
+./tests/data/lavf/lavf.dv CRC=0x5ce4e5e4
+2e8989478f05f6d4eaf1921fdfac4799 *./tests/data/lavf/lavf.dv
+3600000 ./tests/data/lavf/lavf.dv
+./tests/data/lavf/lavf.dv CRC=0x747caf33
+87d3b20f656235671383a7eaa2f66330 *./tests/data/lavf/lavf.dv
 3600000 ./tests/data/lavf/lavf.dv
 ./tests/data/lavf/lavf.dv CRC=0x0e868a82
diff --git a/tests/ref/lavf/ffm b/tests/ref/lavf/ffm
index 8921544..0494c0e 100644
--- a/tests/ref/lavf/ffm
+++ b/tests/ref/lavf/ffm
@@ -1,3 +1,3 @@
-c5dcf5950031020864db57bbde0064df *./tests/data/lavf/lavf.ffm
+c76e8f9a9bcd04379dfa3239e272d049 *./tests/data/lavf/lavf.ffm
 376832 ./tests/data/lavf/lavf.ffm
-./tests/data/lavf/lavf.ffm CRC=0x38388ba1
+./tests/data/lavf/lavf.ffm CRC=0x5b136bb1
diff --git a/tests/ref/lavf/flv_fmt b/tests/ref/lavf/flv_fmt
index 1d38b6f..f014bec 100644
--- a/tests/ref/lavf/flv_fmt
+++ b/tests/ref/lavf/flv_fmt
@@ -1,3 +1,3 @@
-62c3177547fb5853a5116661802e1ae2 *./tests/data/lavf/lavf.flv
-329541 ./tests/data/lavf/lavf.flv
-./tests/data/lavf/lavf.flv CRC=0x881785d1
+0d229f87b3aad778074ace499359d137 *./tests/data/lavf/lavf.flv
+329554 ./tests/data/lavf/lavf.flv
+./tests/data/lavf/lavf.flv CRC=0x4eac88c5
diff --git a/tests/ref/lavf/gif b/tests/ref/lavf/gif
index 4a4ebfb..19106ca 100644
--- a/tests/ref/lavf/gif
+++ b/tests/ref/lavf/gif
@@ -1,3 +1,24 @@
 e6089fd4ef3b9df44090ab3650bdd810 *./tests/data/lavf/lavf.gif
 2906401 ./tests/data/lavf/lavf.gif
 ./tests/data/lavf/lavf.gif CRC=0xe5605ff6
+022dc66b5068404e88c618ce79d9eb5f *./tests/data/images/gif/02.gif
+./tests/data/images/gif/%02d.gif CRC=0x032e0034
+81538 ./tests/data/images/gif/02.gif
+759522b3025fcf8ed6aae582a18c5a14 *./tests/data/images/gif/02.gif
+./tests/data/images/gif/%02d.gif CRC=0x4c8f8a89
+38715 ./tests/data/images/gif/02.gif
+21e802ae7a2239bdbea6f915da1134b9 *./tests/data/images/gif/02.gif
+./tests/data/images/gif/%02d.gif CRC=0x4c8f8a89
+38715 ./tests/data/images/gif/02.gif
+fc4792ac40319344dc7027668a403fc3 *./tests/data/images/gif/02.gif
+./tests/data/images/gif/%02d.gif CRC=0x032e0034
+81538 ./tests/data/images/gif/02.gif
+022dc66b5068404e88c618ce79d9eb5f *./tests/data/images/gif/02.gif
+./tests/data/images/gif/%02d.gif CRC=0x032e0034
+81538 ./tests/data/images/gif/02.gif
+e3392f49c55aa794d3dc49189f52f257 *./tests/data/images/gif/02.gif
+./tests/data/images/gif/%02d.gif CRC=0x22d67c27
+63144 ./tests/data/images/gif/02.gif
+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 0d28ac5..b242875 100644
--- a/tests/ref/lavf/gxf
+++ b/tests/ref/lavf/gxf
@@ -1,3 +1,9 @@
-32e34e23f3740e27e5bcf1621a698aad *./tests/data/lavf/lavf.gxf
-796392 ./tests/data/lavf/lavf.gxf
-./tests/data/lavf/lavf.gxf CRC=0x4f52fc7f
+72e150dc3430a6a78656790658eb9a09 *./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
+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/ismv b/tests/ref/lavf/ismv
new file mode 100644
index 0000000..c6651b5
--- /dev/null
+++ b/tests/ref/lavf/ismv
@@ -0,0 +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
+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/jpg b/tests/ref/lavf/jpg
index 9e5be55..1309d74 100644
--- a/tests/ref/lavf/jpg
+++ b/tests/ref/lavf/jpg
@@ -1,3 +1,3 @@
 131878fee153a086d740543fbf2ab359 *./tests/data/images/jpg/02.jpg
-./tests/data/images/jpg/%02d.jpg CRC=0x8b019f23
+./tests/data/images/jpg/%02d.jpg CRC=0xe3509f33
 28406 ./tests/data/images/jpg/02.jpg
diff --git a/tests/ref/lavf/mkv b/tests/ref/lavf/mkv
index 5ea3638..8820300 100644
--- a/tests/ref/lavf/mkv
+++ b/tests/ref/lavf/mkv
@@ -1,3 +1,3 @@
-2c6fbc2c818c849e77702141294d775d *./tests/data/lavf/lavf.mkv
-320262 ./tests/data/lavf/lavf.mkv
-./tests/data/lavf/lavf.mkv CRC=0xd86284dd
+796a3bbf2410e55e186367037bda6bb5 *./tests/data/lavf/lavf.mkv
+320297 ./tests/data/lavf/lavf.mkv
+./tests/data/lavf/lavf.mkv CRC=0x7065846b
diff --git a/tests/ref/lavf/mmf b/tests/ref/lavf/mmf
index 756527c..8909784 100644
--- a/tests/ref/lavf/mmf
+++ b/tests/ref/lavf/mmf
@@ -1,3 +1,3 @@
-272b91d8fc31ed43b08246d182719751 *./tests/data/lavf/lavf.mmf
+1982e25aaa5307068c5e0f0fd54b193a *./tests/data/lavf/lavf.mmf
 22609 ./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 2db01d4..d7cfbf8 100644
--- a/tests/ref/lavf/mov
+++ b/tests/ref/lavf/mov
@@ -1,3 +1,12 @@
-a5c982910b1a1547db68ffa35cc2a05a *./tests/data/lavf/lavf.mov
-357741 ./tests/data/lavf/lavf.mov
-./tests/data/lavf/lavf.mov CRC=0x2f6a9b26
+fcbe7806047914d9751fd9053009df69 *./tests/data/lavf/lavf.mov
+367365 ./tests/data/lavf/lavf.mov
+./tests/data/lavf/lavf.mov CRC=0xb2f59ab4
+d023fdd2149f75ef231180b6b0b0a988 *./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
+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 e76f747..c880fe6 100644
--- a/tests/ref/lavf/mpg
+++ b/tests/ref/lavf/mpg
@@ -1,3 +1,9 @@
-af32acbc73ee486b05a37d53e516d5e7 *./tests/data/lavf/lavf.mpg
+bba1d30df5e8309c8eac70722014ad92 *./tests/data/lavf/lavf.mpg
 372736 ./tests/data/lavf/lavf.mpg
-./tests/data/lavf/lavf.mpg CRC=0x38388ba1
+./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
+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 c69e278..d8aeb4a 100644
--- a/tests/ref/lavf/mxf
+++ b/tests/ref/lavf/mxf
@@ -1,3 +1,9 @@
-21d359aecf0453a5910d2c1a9ec906b2 *./tests/data/lavf/lavf.mxf
-525881 ./tests/data/lavf/lavf.mxf
-./tests/data/lavf/lavf.mxf CRC=0x773f059a
+3fb5387504760db6ebbed106fcda5789 *./tests/data/lavf/lavf.mxf
+525369 ./tests/data/lavf/lavf.mxf
+./tests/data/lavf/lavf.mxf CRC=0x17ce1069
+830a8b9ee58781bf654c55905067cdae *./tests/data/lavf/lavf.mxf
+554553 ./tests/data/lavf/lavf.mxf
+./tests/data/lavf/lavf.mxf CRC=0xa3c0dbc4
+10c6ae1bd97c851728c9abad9dddfa2e *./tests/data/lavf/lavf.mxf
+525369 ./tests/data/lavf/lavf.mxf
+./tests/data/lavf/lavf.mxf CRC=0x17ce1069
diff --git a/tests/ref/lavf/mxf_d10 b/tests/ref/lavf/mxf_d10
index 98569c4..8e08bdd 100644
--- a/tests/ref/lavf/mxf_d10
+++ b/tests/ref/lavf/mxf_d10
@@ -1,3 +1,3 @@
-b66087558cd1ff8e64290ffd856c88bc *./tests/data/lavf/lavf.mxf_d10
+28cf73e6d35a8f7aba30c0ed2bd84924 *./tests/data/lavf/lavf.mxf_d10
 5330989 ./tests/data/lavf/lavf.mxf_d10
-./tests/data/lavf/lavf.mxf_d10 CRC=0x4474d480
+./tests/data/lavf/lavf.mxf_d10 CRC=0x6c74d488
diff --git a/tests/ref/lavf/nut b/tests/ref/lavf/nut
index e658434..72e59e8 100644
--- a/tests/ref/lavf/nut
+++ b/tests/ref/lavf/nut
@@ -1,3 +1,3 @@
-7e44a8ed5ff2fe5442f758d48fe1b496 *./tests/data/lavf/lavf.nut
-319680 ./tests/data/lavf/lavf.nut
-./tests/data/lavf/lavf.nut CRC=0xa79b84dd
+56c403dd91ae1dd4569348381b2b43a4 *./tests/data/lavf/lavf.nut
+319902 ./tests/data/lavf/lavf.nut
+./tests/data/lavf/lavf.nut CRC=0x4780846b
diff --git a/tests/ref/lavf/ogg b/tests/ref/lavf/ogg
index 7bc66a3..584e09b 100644
--- a/tests/ref/lavf/ogg
+++ b/tests/ref/lavf/ogg
@@ -1,3 +1,3 @@
-37147a98d9a484208389efa6a1f8796f *./tests/data/lavf/lavf.ogg
-13966 ./tests/data/lavf/lavf.ogg
+ce1734741fa50c6c85f9cc8f410a720c *./tests/data/lavf/lavf.ogg
+13985 ./tests/data/lavf/lavf.ogg
 ./tests/data/lavf/lavf.ogg CRC=0x37a143ea
diff --git a/tests/ref/lavf/pcx b/tests/ref/lavf/pcx
index bdb2204..6568b60 100644
--- a/tests/ref/lavf/pcx
+++ b/tests/ref/lavf/pcx
@@ -1,3 +1,3 @@
-2df1d747fba23d03b6ff9c91b8b465c9 *./tests/data/images/pcx/02.pcx
+c4faf65ecc812ec8412cc26140c13bd5 *./tests/data/images/pcx/02.pcx
 ./tests/data/images/pcx/%02d.pcx CRC=0x6da01946
 364147 ./tests/data/images/pcx/02.pcx
diff --git a/tests/ref/lavf/pixfmt b/tests/ref/lavf/pixfmt
index 186dde5..bf62d90 100644
--- a/tests/ref/lavf/pixfmt
+++ b/tests/ref/lavf/pixfmt
@@ -16,21 +16,21 @@
 304128 ./tests/data/pixfmt/yuvj422p.yuv
 c10442da177c9f1d12be3c53be6fa12c *./tests/data/pixfmt/yuvj444p.yuv
 304128 ./tests/data/pixfmt/yuvj444p.yuv
-c6e0f9b5817f484b175c1ec4ffb4e9c9 *./tests/data/pixfmt/rgb24.yuv
+6bb61113e7b70eb09dbcec356122a0e2 *./tests/data/pixfmt/rgb24.yuv
 304128 ./tests/data/pixfmt/rgb24.yuv
-c6e0f9b5817f484b175c1ec4ffb4e9c9 *./tests/data/pixfmt/bgr24.yuv
+6bb61113e7b70eb09dbcec356122a0e2 *./tests/data/pixfmt/bgr24.yuv
 304128 ./tests/data/pixfmt/bgr24.yuv
-c6e0f9b5817f484b175c1ec4ffb4e9c9 *./tests/data/pixfmt/rgb32.yuv
+6bb61113e7b70eb09dbcec356122a0e2 *./tests/data/pixfmt/rgb32.yuv
 304128 ./tests/data/pixfmt/rgb32.yuv
-66d39d464bd89ded2a124897f0a75ade *./tests/data/pixfmt/rgb565.yuv
+efa7c0337cc00c796c6df615223716f1 *./tests/data/pixfmt/rgb565.yuv
 304128 ./tests/data/pixfmt/rgb565.yuv
-c894c3bd8d2631ed1964500b90a0c350 *./tests/data/pixfmt/rgb555.yuv
+0df2a477af1415a1b8fbf2a3e552bc39 *./tests/data/pixfmt/rgb555.yuv
 304128 ./tests/data/pixfmt/rgb555.yuv
 6be306b0cce5f8e6c271ea17fef9745b *./tests/data/pixfmt/gray.yuv
 304128 ./tests/data/pixfmt/gray.yuv
-31398104d2349dd48328a6862bc6711f *./tests/data/pixfmt/monow.yuv
+6c719671e39f1bcf67b47eab98fa529b *./tests/data/pixfmt/monow.yuv
 304128 ./tests/data/pixfmt/monow.yuv
-31398104d2349dd48328a6862bc6711f *./tests/data/pixfmt/monob.yuv
+6c719671e39f1bcf67b47eab98fa529b *./tests/data/pixfmt/monob.yuv
 304128 ./tests/data/pixfmt/monob.yuv
 00b85790df5740bab95e2559d81603a7 *./tests/data/pixfmt/yuv440p.yuv
 304128 ./tests/data/pixfmt/yuv440p.yuv
diff --git a/tests/ref/lavf/png b/tests/ref/lavf/png
index 4343adb..4e64628 100644
--- a/tests/ref/lavf/png
+++ b/tests/ref/lavf/png
@@ -1,3 +1,9 @@
 c162094e51dc1a3203de43e496086dfd *./tests/data/images/png/02.png
 ./tests/data/images/png/%02d.png CRC=0x6da01946
 248612 ./tests/data/images/png/02.png
+63805114b3723490833789277246276f *./tests/data/images/png/02.png
+./tests/data/images/png/%02d.png CRC=0x831a2963
+41666 ./tests/data/images/png/02.png
+b4c1f0b706a296ba6e791d436757dc5f *./tests/data/images/png/02.png
+./tests/data/images/png/%02d.png CRC=0x5984c023
+511879 ./tests/data/images/png/02.png
diff --git a/tests/ref/lavf/rm b/tests/ref/lavf/rm
index 188d15d..2c05806 100644
--- a/tests/ref/lavf/rm
+++ b/tests/ref/lavf/rm
@@ -1,2 +1,2 @@
-c002d460bc77043ced69fd00f4ae7968 *./tests/data/lavf/lavf.rm
-346414 ./tests/data/lavf/lavf.rm
+85ef42a1fdeffaf083d14b633bbd697f *./tests/data/lavf/lavf.rm
+346424 ./tests/data/lavf/lavf.rm
diff --git a/tests/ref/lavf/swf b/tests/ref/lavf/swf
index 1e07793..7ce0fa4 100644
--- a/tests/ref/lavf/swf
+++ b/tests/ref/lavf/swf
@@ -1,3 +1,3 @@
-62c5aeb636fc82cf6ba6277d36e42cb5 *./tests/data/lavf/lavf.swf
-329479 ./tests/data/lavf/lavf.swf
-./tests/data/lavf/lavf.swf CRC=0x881785d1
+11e9e9bf99a0ae6a0ba5434b745eae21 *./tests/data/lavf/lavf.swf
+329474 ./tests/data/lavf/lavf.swf
+./tests/data/lavf/lavf.swf CRC=0x4eac88c5
diff --git a/tests/ref/lavf/ts b/tests/ref/lavf/ts
index 333149e..0cab3dd 100644
--- a/tests/ref/lavf/ts
+++ b/tests/ref/lavf/ts
@@ -1,3 +1,3 @@
-ec8df9c78de8f7f20a3eb1ce8f863c02 *./tests/data/lavf/lavf.ts
-406456 ./tests/data/lavf/lavf.ts
-./tests/data/lavf/lavf.ts CRC=0x0fdeb4df
+4531d0f4a80d5a2ee2b08a8d4ba3b442 *./tests/data/lavf/lavf.ts
+407020 ./tests/data/lavf/lavf.ts
+./tests/data/lavf/lavf.ts CRC=0xcc2dc628
diff --git a/tests/ref/lavf/voc b/tests/ref/lavf/voc
index ea903b6..062da63 100644
--- a/tests/ref/lavf/voc
+++ b/tests/ref/lavf/voc
@@ -1,3 +1,3 @@
-5c4ee01048e7a8a138a97e80cf7a1924 *./tests/data/lavf/lavf.voc
+e4cefbeb4c20f5735de1877fbcfd8d1d *./tests/data/lavf/lavf.voc
 45261 ./tests/data/lavf/lavf.voc
 ./tests/data/lavf/lavf.voc CRC=0x74b2b546
diff --git a/tests/ref/lavf/voc_s16 b/tests/ref/lavf/voc_s16
index d53c950..23e5aab 100644
--- a/tests/ref/lavf/voc_s16
+++ b/tests/ref/lavf/voc_s16
@@ -1,3 +1,3 @@
-8ed10b311e49b4d4b18679b126492159 *./tests/data/lavf/lavf.s16.voc
-180437 ./tests/data/lavf/lavf.s16.voc
+a8225786fdbf5a2a19d1eeaf15f28632 *./tests/data/lavf/lavf.s16.voc
+180439 ./tests/data/lavf/lavf.s16.voc
 ./tests/data/lavf/lavf.s16.voc CRC=0x7bd585ff
diff --git a/tests/ref/lavf/wtv b/tests/ref/lavf/wtv
new file mode 100644
index 0000000..24cf15d
--- /dev/null
+++ b/tests/ref/lavf/wtv
@@ -0,0 +1,3 @@
+05aff2517b5bd436ec26c736b4b8372c *./tests/data/lavf/lavf.wtv
+413696 ./tests/data/lavf/lavf.wtv
+./tests/data/lavf/lavf.wtv CRC=0xcc2dc628
diff --git a/tests/ref/lavf/xbm b/tests/ref/lavf/xbm
new file mode 100644
index 0000000..4cc4be6
--- /dev/null
+++ b/tests/ref/lavf/xbm
@@ -0,0 +1,3 @@
+99c20fff5d17b698b4a25282aebc3c51 *./tests/data/images/xbm/02.xbm
+./tests/data/images/xbm/%02d.xbm CRC=0x0f5aa5cb
+76411 ./tests/data/images/xbm/02.xbm
diff --git a/tests/ref/lavfi/alphaextract_rgb b/tests/ref/lavfi/alphaextract_rgb
new file mode 100644
index 0000000..d46b563
--- /dev/null
+++ b/tests/ref/lavfi/alphaextract_rgb
@@ -0,0 +1 @@
+alphaextract_rgb    4a46df014912056534fcab2f45a02279
diff --git a/tests/ref/lavfi/alphaextract_yuv b/tests/ref/lavfi/alphaextract_yuv
new file mode 100644
index 0000000..32b9ab9
--- /dev/null
+++ b/tests/ref/lavfi/alphaextract_yuv
@@ -0,0 +1 @@
+alphaextract_yuv    591e2d45f96ecfa8cc326eb741456a79
diff --git a/tests/ref/lavfi/alphamerge_rgb b/tests/ref/lavfi/alphamerge_rgb
new file mode 100644
index 0000000..d890fae
--- /dev/null
+++ b/tests/ref/lavfi/alphamerge_rgb
@@ -0,0 +1 @@
+alphamerge_rgb      4a46df014912056534fcab2f45a02279
diff --git a/tests/ref/lavfi/alphamerge_yuv b/tests/ref/lavfi/alphamerge_yuv
new file mode 100644
index 0000000..2e58301
--- /dev/null
+++ b/tests/ref/lavfi/alphamerge_yuv
@@ -0,0 +1 @@
+alphamerge_yuv      591e2d45f96ecfa8cc326eb741456a79
diff --git a/tests/ref/lavfi/colormatrix1 b/tests/ref/lavfi/colormatrix1
new file mode 100644
index 0000000..9ec093d
--- /dev/null
+++ b/tests/ref/lavfi/colormatrix1
@@ -0,0 +1 @@
+colormatrix1        600fef16b66cff4ee76540ff2a8f4480
diff --git a/tests/ref/lavfi/colormatrix2 b/tests/ref/lavfi/colormatrix2
new file mode 100644
index 0000000..9961bae
--- /dev/null
+++ b/tests/ref/lavfi/colormatrix2
@@ -0,0 +1 @@
+colormatrix2        e4ba95b7dd5e0862aa5f5e3ddc54bda4
diff --git a/tests/ref/lavfi/crop b/tests/ref/lavfi/crop
index 32041c2..dec7f29 100644
--- a/tests/ref/lavfi/crop
+++ b/tests/ref/lavfi/crop
@@ -1 +1 @@
-crop                3d163f156eaddf41d2be20736f973539
+crop                f7b5236ddf88224188051c7c43503a14
diff --git a/tests/ref/lavfi/crop_scale b/tests/ref/lavfi/crop_scale
index 82e5394..e692a8a 100644
--- a/tests/ref/lavfi/crop_scale
+++ b/tests/ref/lavfi/crop_scale
@@ -1 +1 @@
-crop_scale          0a3d45d58b805b8c47416b9239535f94
+crop_scale          c298d61e731a97d0a9600e7fde80b6b4
diff --git a/tests/ref/lavfi/crop_scale_vflip b/tests/ref/lavfi/crop_scale_vflip
index 07c729a..a1cc0e9 100644
--- a/tests/ref/lavfi/crop_scale_vflip
+++ b/tests/ref/lavfi/crop_scale_vflip
@@ -1 +1 @@
-crop_scale_vflip    e88a4dfb960d0bb28ee875567bedde5d
+crop_scale_vflip    b2760ee11238873d6321d0a11cd42d0e
diff --git a/tests/ref/lavfi/crop_vflip b/tests/ref/lavfi/crop_vflip
index a3f8200..d6d6bad 100644
--- a/tests/ref/lavfi/crop_vflip
+++ b/tests/ref/lavfi/crop_vflip
@@ -1 +1 @@
-crop_vflip          628542e17b6900ee79b1429183ae01b0
+crop_vflip          8368eb12fa29acc5826bade961257375
diff --git a/tests/ref/lavfi/drawbox b/tests/ref/lavfi/drawbox
new file mode 100644
index 0000000..6d2f632
--- /dev/null
+++ b/tests/ref/lavfi/drawbox
@@ -0,0 +1 @@
+drawbox             b6ff6ecda5611de46ed26db05b49dc72
diff --git a/tests/ref/lavfi/edgedetect b/tests/ref/lavfi/edgedetect
new file mode 100644
index 0000000..6db0e72
--- /dev/null
+++ b/tests/ref/lavfi/edgedetect
@@ -0,0 +1 @@
+edgedetect          9d396de52d56b63a77ea6933a323f61f
diff --git a/tests/ref/lavfi/fade b/tests/ref/lavfi/fade
new file mode 100644
index 0000000..852abb9
--- /dev/null
+++ b/tests/ref/lavfi/fade
@@ -0,0 +1 @@
+fade                129fb9b266524b0adf102689c366cac8
diff --git a/tests/ref/lavfi/idet b/tests/ref/lavfi/idet
new file mode 100644
index 0000000..2c6c2ae
--- /dev/null
+++ b/tests/ref/lavfi/idet
@@ -0,0 +1 @@
+idet                1077e3cb6fc4916b5441dd08cea4c9a8
diff --git a/tests/ref/lavfi/life b/tests/ref/lavfi/life
new file mode 100644
index 0000000..05713f3
--- /dev/null
+++ b/tests/ref/lavfi/life
@@ -0,0 +1 @@
+life                bc4822aa5d473a8b5efb31fef7aeac86
diff --git a/tests/ref/lavfi/null b/tests/ref/lavfi/null
index 3c3b7b7..0b9b9b8 100644
--- a/tests/ref/lavfi/null
+++ b/tests/ref/lavfi/null
@@ -1 +1 @@
-null                eba2f135a08829387e2f698ff72a2939
+null                61fffd2d8425759a33ae07e718d0242d
diff --git a/tests/ref/lavfi/overlay b/tests/ref/lavfi/overlay
new file mode 100644
index 0000000..ca70370
--- /dev/null
+++ b/tests/ref/lavfi/overlay
@@ -0,0 +1 @@
+overlay             4e85d551db9e56e8faddc1fc70fd6a00
diff --git a/tests/ref/lavfi/pad b/tests/ref/lavfi/pad
new file mode 100644
index 0000000..7a6f61e
--- /dev/null
+++ b/tests/ref/lavfi/pad
@@ -0,0 +1 @@
+pad                 8122d716097523d0875e2d55b0926105
diff --git a/tests/ref/lavfi/pixdesc b/tests/ref/lavfi/pixdesc
deleted file mode 100644
index dc1b857..0000000
--- a/tests/ref/lavfi/pixdesc
+++ /dev/null
@@ -1,66 +0,0 @@
-abgr                037bf9df6a765520ad6d490066bf4b89
-argb                c442a8261c2265a07212ef0f72e35f5a
-bgr24               0d0cb38ab3fa0b2ec0865c14f78b217b
-bgr444be            d9ea9307d21b162225b8b2c524cf9477
-bgr444le            88035350e9da3a8f67387890b956f0bc
-bgr48be             00624e6c7ec7ab19897ba2f0a3257fe8
-bgr48le             d02c235ebba7167881ca2d576497ff84
-bgr4_byte           50d23cc82d9dcef2fd12adb81fb9b806
-bgr555be            49f01b1f1f0c84fd9e776dd34cc3c280
-bgr555le            378d6ac4223651a1adcbf94a3d0d807b
-bgr565be            257cf78afa35dc31e9696f139c916715
-bgr565le            1dfdd03995c287e3c754b164bf26a355
-bgr8                24bd566170343d06fec6fccfff5abc54
-bgra                76a18a5151242fa137133f604cd624d2
-gray                db08f7f0751900347e6b8649e4164d21
-gray16be            7becf34ae825a3df3969bf4c6bfeb5e2
-gray16le            10bd87059b5c189f3caef2837f4f2b5c
-monob               668ebe8b8103b9046b251b2fa8a1d88f
-monow               9251497f3b0634f1165d12d5a289d943
-nv12                e0af357888584d36eec5aa0f673793ef
-nv21                9a3297f3b34baa038b1f37cb202b512f
-rgb24               b41eba9651e1b5fe386289b506188105
-rgb444be            9e89db334568c6b2e3d5d0540f4ba960
-rgb444le            0a68cb6de8bf530aa30c5c1205c25155
-rgb48be             cc139ec1dd9451f0e049c0cb3a0c8aa2
-rgb48le             86c5608904f75360d492dbc5c9589969
-rgb4_byte           c93ba89b74c504e7f5ae9d9ab1546c73
-rgb555be            912a62c5e53bfcbac2a0340e10973cf2
-rgb555le            a937a0fc764fb57dc1b3af87cba0273c
-rgb565be            9cadf742e05ddc23a3b5b270f89aad3c
-rgb565le            d39aa298bb525e9be8860351c6f62dab
-rgb8                4a9d8e4f2f154e83a7e1735be6300700
-rgba                93a5b3712e6eb8c5b9a09ffc7b9fbc12
-uyvy422             adcf64516a19fce44df77082bdb16291
-yuv410p             2d9225153c83ee1132397d619d94d1b3
-yuv411p             8b298af3e43348ca1b11eb8a3252ac6c
-yuv420p             eba2f135a08829387e2f698ff72a2939
-yuv420p10be         299fe1d785a3d3dd5e70778700d7fb06
-yuv420p10le         8aee004e765a5383be0954f5e916b72f
-yuv420p16be         16c009a235cd52b74791a895423152a3
-yuv420p16le         2d59c4f1d0314a5a957a7cfc4b6fabcc
-yuv420p9be          ce880fa07830e5297c22acf6e20555ce
-yuv420p9le          16543fda8f87d94a6cf857d2e8d4461a
-yuv422p             c9bba4529821d796a6ab09f6a5fd355a
-yuv422p10be         11af7dfafe8bc025c7e3bd82b830fe8a
-yuv422p10le         ec04efb76efa79bf0d02b21572371a56
-yuv422p16be         5499502e1c29534a158a1fe60e889f60
-yuv422p16le         e3d61fde6978591596bc36b914386623
-yuv422p9be          29b71579946940a8c00fa844c9dff507
-yuv422p9le          062b7f9cbb972bf36b5bdb1a7623701a
-yuv440p             5a064afe2b453bb52cdb3f176b1aa1cf
-yuv444p             0a98447b78fd476aa39686da6a74fa2e
-yuv444p10be         71be185a2fb7a353eb024df9bc63212d
-yuv444p10le         c1c6b30a12065c7901c0a267e4861a0f
-yuv444p16be         1c6ea2c2f5e539006112ceec3d4e7d90
-yuv444p16le         20f86bc2f68d2b3f1f2b48b97b2189f4
-yuv444p9be          6ab31f4c12b533ce318ecdff83cdd054
-yuv444p9le          f0606604a5c08becab6ba500124c4b7c
-yuva420p            a29884f3f3dfe1e00b961bc17bef3d47
-yuva422p            92b6815f465297284cdb843711682cee
-yuva444p            c523716e4900cfe515eaab1d7124fdd9
-yuvj420p            32eec78ba51857b16ce9b813a49b7189
-yuvj422p            0dfa0ed434f73be51428758c69e082cb
-yuvj440p            657501a28004e27a592757a7509f5189
-yuvj444p            98d3d054f2ec09a75eeed5d328dc75b7
-yuyv422             f2569f2b5069a0ee0cecae33de0455e3
diff --git a/tests/ref/lavfi/pixfmts_copy b/tests/ref/lavfi/pixfmts_copy
index dc1b857..042f2d5 100644
--- a/tests/ref/lavfi/pixfmts_copy
+++ b/tests/ref/lavfi/pixfmts_copy
@@ -1,66 +1,83 @@
-abgr                037bf9df6a765520ad6d490066bf4b89
-argb                c442a8261c2265a07212ef0f72e35f5a
-bgr24               0d0cb38ab3fa0b2ec0865c14f78b217b
-bgr444be            d9ea9307d21b162225b8b2c524cf9477
-bgr444le            88035350e9da3a8f67387890b956f0bc
-bgr48be             00624e6c7ec7ab19897ba2f0a3257fe8
-bgr48le             d02c235ebba7167881ca2d576497ff84
-bgr4_byte           50d23cc82d9dcef2fd12adb81fb9b806
-bgr555be            49f01b1f1f0c84fd9e776dd34cc3c280
-bgr555le            378d6ac4223651a1adcbf94a3d0d807b
-bgr565be            257cf78afa35dc31e9696f139c916715
-bgr565le            1dfdd03995c287e3c754b164bf26a355
-bgr8                24bd566170343d06fec6fccfff5abc54
-bgra                76a18a5151242fa137133f604cd624d2
-gray                db08f7f0751900347e6b8649e4164d21
-gray16be            7becf34ae825a3df3969bf4c6bfeb5e2
-gray16le            10bd87059b5c189f3caef2837f4f2b5c
-monob               668ebe8b8103b9046b251b2fa8a1d88f
-monow               9251497f3b0634f1165d12d5a289d943
-nv12                e0af357888584d36eec5aa0f673793ef
-nv21                9a3297f3b34baa038b1f37cb202b512f
-rgb24               b41eba9651e1b5fe386289b506188105
-rgb444be            9e89db334568c6b2e3d5d0540f4ba960
-rgb444le            0a68cb6de8bf530aa30c5c1205c25155
-rgb48be             cc139ec1dd9451f0e049c0cb3a0c8aa2
-rgb48le             86c5608904f75360d492dbc5c9589969
-rgb4_byte           c93ba89b74c504e7f5ae9d9ab1546c73
-rgb555be            912a62c5e53bfcbac2a0340e10973cf2
-rgb555le            a937a0fc764fb57dc1b3af87cba0273c
-rgb565be            9cadf742e05ddc23a3b5b270f89aad3c
-rgb565le            d39aa298bb525e9be8860351c6f62dab
-rgb8                4a9d8e4f2f154e83a7e1735be6300700
-rgba                93a5b3712e6eb8c5b9a09ffc7b9fbc12
-uyvy422             adcf64516a19fce44df77082bdb16291
-yuv410p             2d9225153c83ee1132397d619d94d1b3
-yuv411p             8b298af3e43348ca1b11eb8a3252ac6c
-yuv420p             eba2f135a08829387e2f698ff72a2939
-yuv420p10be         299fe1d785a3d3dd5e70778700d7fb06
-yuv420p10le         8aee004e765a5383be0954f5e916b72f
-yuv420p16be         16c009a235cd52b74791a895423152a3
-yuv420p16le         2d59c4f1d0314a5a957a7cfc4b6fabcc
-yuv420p9be          ce880fa07830e5297c22acf6e20555ce
-yuv420p9le          16543fda8f87d94a6cf857d2e8d4461a
-yuv422p             c9bba4529821d796a6ab09f6a5fd355a
-yuv422p10be         11af7dfafe8bc025c7e3bd82b830fe8a
-yuv422p10le         ec04efb76efa79bf0d02b21572371a56
-yuv422p16be         5499502e1c29534a158a1fe60e889f60
-yuv422p16le         e3d61fde6978591596bc36b914386623
-yuv422p9be          29b71579946940a8c00fa844c9dff507
-yuv422p9le          062b7f9cbb972bf36b5bdb1a7623701a
-yuv440p             5a064afe2b453bb52cdb3f176b1aa1cf
-yuv444p             0a98447b78fd476aa39686da6a74fa2e
-yuv444p10be         71be185a2fb7a353eb024df9bc63212d
-yuv444p10le         c1c6b30a12065c7901c0a267e4861a0f
-yuv444p16be         1c6ea2c2f5e539006112ceec3d4e7d90
-yuv444p16le         20f86bc2f68d2b3f1f2b48b97b2189f4
-yuv444p9be          6ab31f4c12b533ce318ecdff83cdd054
-yuv444p9le          f0606604a5c08becab6ba500124c4b7c
-yuva420p            a29884f3f3dfe1e00b961bc17bef3d47
-yuva422p            92b6815f465297284cdb843711682cee
-yuva444p            c523716e4900cfe515eaab1d7124fdd9
-yuvj420p            32eec78ba51857b16ce9b813a49b7189
-yuvj422p            0dfa0ed434f73be51428758c69e082cb
-yuvj440p            657501a28004e27a592757a7509f5189
-yuvj444p            98d3d054f2ec09a75eeed5d328dc75b7
-yuyv422             f2569f2b5069a0ee0cecae33de0455e3
+0bgr                a06d3a7652e4885c65895e0e168aab28
+0rgb                b6b5653d2228cdf2ba3c55a72f2e713f
+abgr                1a147fa04ed70b9a7e67a4c89052f630
+argb                997df0b5c268a0d8f9c611cae4e01e05
+bgr0                218df6dc3eb5094a0c16a8bd18bc3999
+bgr24               d6370f6dc34df2ea66e1718baf74137b
+bgr444be            aba6dfea008ae12c2120a95f54293904
+bgr444le            cfb5401e8f076cc8675e17ed1114a3df
+bgr48be             ab65229b64606f6408cd732b967c0b01
+bgr48le             f1b4e718cadee9bd2978289153ce43de
+bgr4_byte           de96505ef9ad7078f87b4dfdf6fe4b61
+bgr555be            8d5de9e9200d622f27dc73958a85045c
+bgr555le            74eb9837706143a40e26305a16a79369
+bgr565be            13a36d6502be88fc0c2aec05b8d2d501
+bgr565le            ed027571692aecd522aa65a90cc7e09b
+bgr8                71ef789609c746c2e7e4be9dec29062c
+bgra                0364b074268682ea46168742a8239f7d
+gray                1e5e2b8548843a6898eedd9c974c422c
+gray16be            389f4e5a8ab413b3af32767b59ed7f9e
+gray16le            a1f912941247e45b394b9cf4f0e81130
+monob               309b5785a36bd988d17e15d88f4ffad1
+monow               8809a02bc69b58d1114b09ca79ebffad
+nv12                75e90c54d858b993e99f4ee6d2a2a38f
+nv21                8831a3f411015d45fbc5dd191245ba9c
+pal8                13de2a1c3c80cb64d14e2bc4f6f461d0
+rgb0                992f5ad24802cc255edab45c3084db4a
+rgb24               c71ba90f69f15c8275232bb3f62d0ced
+rgb444be            26eaec65d7efd2b0c9c13b47dfd9b241
+rgb444le            5f29863553107110ea817f52151d77b7
+rgb48be             a3bc81c46c21818a989f23104a599ab0
+rgb48le             e87c661ac49aea1f1e93939802883d92
+rgb4_byte           293b1b84f01efd90bde40cb3faffc127
+rgb555be            5229183fa64d4e5c7e3703d8263ee6ae
+rgb555le            c3e9978cb2a4129a5575935e8cbc433a
+rgb565be            bc123b962629ead1a06af0c18cbb6e5f
+rgb565le            20757fafe4756e62d845b2ab4c0b8f93
+rgb8                e01614f5416dcc8ad365ad7a57afc9fb
+rgba                53796fa4c392a1b2659595b6a284f8c4
+uyvy422             3f411f947e3ac8f842c88e717d68bd9a
+yuv410p             7dcf3f4770c8b494290ceacd2c2ce6db
+yuv411p             9461b188dab6f8b90d9a27e353a89f58
+yuv420p             61fffd2d8425759a33ae07e718d0242d
+yuv420p10be         2abf90242cb021cb6fcf9f2c3c92f6a7
+yuv420p10le         180b7e4de684c7225d2fb37614f842cb
+yuv420p12be         256c9e6cfc878a8abf681b30777c0620
+yuv420p12le         8dc8b86c4790da3769d4a62e87608623
+yuv420p14be         8d22756c5d2b9e501924c082bfb22a6c
+yuv420p14le         c9da19d4818bcb119ad6481b75778f7e
+yuv420p16be         4ccdcca6dd6a960f9a3333f0aee095bd
+yuv420p16le         9c5847d9b0de258a10ee906dc47e24ea
+yuv420p9be          fa7ad4f73232aac0e35def62af1e2c39
+yuv420p9le          3720ba1786b56c8f4913e67dddebbb07
+yuv422p             eee223e92f1f2e5ad4186b411ebf5816
+yuv422p10be         80fa87750491dcc3e93d175b64835654
+yuv422p10le         e1640cd315bd96c6b59f7753825a7306
+yuv422p12be         8a17ae3a5f565479ec4aa230ef78a6fa
+yuv422p12le         04215506e2eca5b79f47e322a5949a58
+yuv422p14be         0fec4a6615ff610e3ea5e85acbd1b273
+yuv422p14le         a54c6121c1cb713a33961ea0faa35956
+yuv422p16be         1f3c216927d17966a009a42def124bba
+yuv422p16le         90adbdffaeea9b09398339c8a1322b02
+yuv422p9be          e46446534dd0821029d3b831c9c1d1b0
+yuv422p9le          520e418a2429f7efee511b7fcbf45ab6
+yuv440p             456d83524b299f2fa1bb988e421554d9
+yuv444p             068bc09d282d18c9fa35c2787943fc2a
+yuv444p10be         9f6e1490080a454243daee9229425e1e
+yuv444p10le         cc183e51041351d9ac06c4df6e8ad5f7
+yuv444p12be         df420773bb3cca2ffb585db3bbe01195
+yuv444p12le         25c0c73d98c3c1e281044d79097608f5
+yuv444p14be         516b18e8331e7d404c7541bafc5501e6
+yuv444p14le         7c88d9a233979d73762cffef2fe08306
+yuv444p16be         4000b12fa88ed0feef182da31c7e6b96
+yuv444p16le         96a857dba8dc6792c58daec872825b32
+yuv444p9be          07727e5c9040b7f0a17d591288ac330d
+yuv444p9le          4d12d20a68dc28618594c96c2ade4ff4
+yuva420p            3a8c5c142e051367c196f95696e0e2c3
+yuva422p            45ae66d6f69fd5b77e6831e98d228bf4
+yuva444p            86b05da54db8c7e8cf5b6638e19c6fc5
+yuvj420p            73661456012f20cda81207b14bb0c0a5
+yuvj422p            aa97862b57f47c5a6506156e9aaf129a
+yuvj440p            ff8b9884a49d546b035f5d2ac1e673df
+yuvj444p            b8142888d80b8065c54045839e79b331
+yuyv422             f06a4fbbdb32807d05de825daa2c3a1b
diff --git a/tests/ref/lavfi/pixfmts_crop b/tests/ref/lavfi/pixfmts_crop
index cbbcf90..797aedc 100644
--- a/tests/ref/lavfi/pixfmts_crop
+++ b/tests/ref/lavfi/pixfmts_crop
@@ -1,42 +1,43 @@
-abgr                cd761690872843d1b7ab0c695393c751
-argb                2ec6ef18769bcd651c2e8904d5a3ee67
-bgr24               3450fd00cf1493d1ded75544d82ba3ec
-bgr48be             18ca4002732f278cc9f525215c2fca41
-bgr48le             395a4c187c4e95217d089bd3df9f3654
-bgr4_byte           2f6ac3cdd4676ab4e2982bdf0664945b
-bgr555be            d3a7c273604723adeb7e5f5dd1c4272b
-bgr555le            d22442fc13b464f9ba455b08df4e981f
-bgr565be            fadceef4a64ad6873fcb43ddee0deb3c
-bgr565le            891664e5a54ae5968901347da92bc5e9
-bgr8                4b7159e05765bd4703180072d86423c8
-bgra                395c9f706fccda721471acaa5c96c16c
-gray                8c4850e66562a587a292dc728a65ea4a
-gray16be            daa5a6b98fb4a280c57c57bff1a2ab5a
-gray16le            84f5ea7259073edcb893113b42213c8e
-rgb24               3b90ed64b687d3dc186c6ef521dc71a8
-rgb48be             e6fd353c0eb9bea889423954414bea35
-rgb48le             68a1723da11ce08b502d42e204376503
-rgb4_byte           6958029f73c6cdfed4f71020d816f027
-rgb555be            41a7d1836837bc90f2cae19a9c9df3b3
-rgb555le            eeb78f8ce6186fba55c941469e60ba67
-rgb565be            b2d1cb525f3a0cfe27753c0d479b2fa9
-rgb565le            6a49700680be9a0d434411825a769556
-rgb8                88b0398c265d1ed7a837dc084fa0917c
-rgba                fd00b24c7597268c32759a84a1de2de4
-yuv410p             a9f2eaa747bf988b7bebe4f442b9c67a
-yuv411p             3334d3aef8dba238658090ac172375d1
-yuv420p             bfea0188ddd4889787c403caae119cc7
-yuv420p16be         8365eff38b8c329aeb95fc605fa229bb
-yuv420p16le         5e8dd38d973d5854abe1ad4efad20cc1
-yuv422p             f2f930a91fe00d4252c4720b5ecd8961
-yuv422p16be         167e4338811a7d272925a4c6417d60da
-yuv422p16le         3359395d5875d581fa1e975013d30114
-yuv440p             2472417d980e395ad6843cbb8b633b29
-yuv444p             1f151980486848c96bc5585ced99003e
-yuv444p16be         1ce8fcd4712d525af983e6179d6a4f9e
-yuv444p16le         5f1441e18345aadb3f881dac99c6c08a
-yuva420p            7536753dfbc7932560fb50c921369a0e
-yuvj420p            21f891093006d42d7683b0e1d773a657
-yuvj422p            9a43d474c407590ad8f213880586b45e
-yuvj440p            977351350450ebdbf7a9d20020c6b5a5
-yuvj444p            4a50ba26859dad91dcf7000de0d0efa1
+abgr                ef31d9057f6e65a7c3308a1b1daa98fa
+argb                5e5e261c4870e0de05d56ff640b9550a
+bgr24               44bec15f35513de7e957b3d59b53cb7b
+bgr48be             0b5ebce3c48eb8614d79e204b5268603
+bgr48le             c4ab61a8b9d502132730c6abb6ffd84c
+bgr4_byte           cab930dbe1fe77d58b41837ecdcb8460
+bgr555be            67162782fdb86813f446d8e1c21c73e9
+bgr555le            85913cfa8dab465f7dcfcfe7f9001a01
+bgr565be            ee9a1debb896d41c53a026f9e6ce006b
+bgr565le            ab7b6055bc3b6b7edc9a5e4de43ec90d
+bgr8                f85ff16e21d922ad6d32648ef3acfbfb
+bgra                9f2e37d73ad3b759fc9d6b12ee668c38
+gray                3266b99065a17cbd647f2339addc5303
+gray16be            02ac848ad4e28c06938599563ba81ff7
+gray16le            672aebfeb8a0f4067b3c6064340056e4
+pal8                e1fd50b8a8a67fb5abd8b44abc778bbb
+rgb24               d044123f1fe50f656f2101dd3f091ead
+rgb48be             ef5507f88948b54218911d12e1dbef36
+rgb48le             6d045d5990d6ada64a112e3b581a7b38
+rgb4_byte           0f0f9ee31c65dc60da49bf98a1b06dcf
+rgb555be            48fa619bfd04f6dee05416b02605c031
+rgb555le            292cff1f824e49076bad50a07ab1c749
+rgb565be            0dd6f6a5a8713bd1c3d9826bb7a88eab
+rgb565le            6afd85faa8c6f0f330969539178eb9a2
+rgb8                87cf541b110e35a6f9a983e9cde85e15
+rgba                7abe1af7b97f5b9a7aa5ad3e4bf32f76
+yuv410p             126e0da1da4fd89be28087b8367bbb36
+yuv411p             b94f0af107fc4796aca70c0a36d374c5
+yuv420p             74c6b331bd30f005e6c75a192423ad90
+yuv420p16be         2d3c84ebff77479e8c5b6e3e59ec4e45
+yuv420p16le         e2c906f2751609bf8cbcbeb2f629319a
+yuv422p             124bc8d668072de1bb3b894cc4bae859
+yuv422p16be         3ec47e2709107fcc388b5e0abebf7eaf
+yuv422p16le         a4183a62917bf8568fe11ff446dd18f9
+yuv440p             15c81c685fa5b9db95150caff14ff83f
+yuv444p             12b752f78af72666627cea2d0c274cdb
+yuv444p16be         f2bf0e22a1d184e37eaa199a76cf22ba
+yuv444p16le         c11b151dced5c8854d385373fa4dcc8f
+yuva420p            920c5d1b965eeb72e3a0e343696face3
+yuvj420p            f9183e49f42bae31d7d85b92161fa82f
+yuvj422p            aabeed60a6e1b2cf88665ac627bf531f
+yuvj440p            5ae4f404b42f3167f978473d9a3737fc
+yuvj444p            6728997f65b879fd5a3175cb449a8f0c
diff --git a/tests/ref/lavfi/pixfmts_hflip b/tests/ref/lavfi/pixfmts_hflip
index 3741713..e696997 100644
--- a/tests/ref/lavfi/pixfmts_hflip
+++ b/tests/ref/lavfi/pixfmts_hflip
@@ -1,42 +1,47 @@
-abgr                49468c6c9ceee5d52b08b1270a909323
-argb                50ba9f16c6475530602f2983278b82d0
-bgr24               cc53d2011d097972db0d22756c3699e3
-bgr48be             815192d3757c66de97b0d51818acbe0f
-bgr48le             8e4184ac6eae251b4bace51dba7d790c
-bgr4_byte           aac987e7d1a6a96477cfc0b48a4285de
-bgr555be            bc07265898440116772200390d70c092
-bgr555le            ccee08679bac84a1f960c6c9070c5538
-bgr565be            e088789ce46224b87c6e46610ef19add
-bgr565le            3703466e19e1b52e03a34fd244a8e8e4
-bgr8                50b505a889f0428242305acb642da107
-bgra                01ca21e7e6a8d1281b4553bde8e8a404
-gray                03efcb4ab52a24c0af0e03cfd26c9377
-gray16be            9bcbca979601ddc4869f846f08f3d1dd
-gray16le            c1b8965adcc7f847ee343149ff507073
-rgb24               754f1722fc738590cc407ac65749bfe8
-rgb48be             d690412ca5fada031b5da47b87096248
-rgb48le             c901feb564232f5d0bc0eabd66dae3e7
-rgb4_byte           c8a3f995fcf3e0919239ea2c413ddc29
-rgb555be            045ce8607d3910586f4d97481dda8632
-rgb555le            8778ee0cf58ce9ad1d99a1eca9f95e87
-rgb565be            c8022a1b2470e72f124e4389fad4c372
-rgb565le            2cb690eb3fcb72da3771ad6a48931158
-rgb8                9e462b811b9b6173397b9cfc1f6b2f17
-rgba                d3d0dc1ecef3ed72f26a2986d0efc204
-yuv410p             acb543ebbbf63eefe533e6faffc006da
-yuv411p             c626cf6d191139b4ca7efc0155f957f1
-yuv420p             2d5c80f9ba2ddd85b2aeda3564cc7d64
-yuv420p16be         758b0c1e2113b15e7afde48da4e4d024
-yuv420p16le         480ccd951dcb806bc875d307e02e50a0
-yuv422p             6e728f4eb9eae287c224f396d84be6ea
-yuv422p16be         a05d43cd62b790087bd37083174557de
-yuv422p16le         6954abebcbc62d81068d58d0c62bdd5b
-yuv440p             a99e2b57ed601f39852715c9d675d0d3
-yuv444p             947e47f7bb5fdccc659d19b7df2b6fc3
-yuv444p16be         58c012e5ab73b066ef3c2b6411a395f1
-yuv444p16le         32c12794e184042a59738ab2de608c8d
-yuva420p            d83ec0c01498189f179ec574918185f1
-yuvj420p            df3aaaec3bb157c3bde5f0365af30f4f
-yuvj422p            d113871528d510a192797af59df9c05c
-yuvj440p            07f5ff12ced85aba1b5cf51692fff4bb
-yuvj444p            8d95f6b4d4c9b4b0389d36df686bfa46
+abgr                8ab842e280c8b31f66450e8951dfedfa
+argb                cdb6aa47939d49c0ff72537bfc8c82e0
+bgr24               5b64fd60e2050946b50da1f4945127fb
+bgr444be            b52c1b9d9dc02cb46c04e80d97139e60
+bgr444le            48172797fa65a25c0ad30ddc7e8f5bcb
+bgr48be             58e292c33eb60708171c3393a5700615
+bgr48le             e1be8e6bfe26acdee258e76329d2f03d
+bgr4_byte           af34e1158edfbc8c6929365d651a9549
+bgr555be            c82d7877f7ef25ee1154d05b240cf54c
+bgr555le            b7a4e2c66807a82bd132dfcf8540bfb5
+bgr565be            3b464a00c619410eac7bdea9c96faf60
+bgr565le            4b4c708d4ad222f41734dce68e9d48b6
+bgr8                ad1db7a17cdfab2ede6f22c2415a3fbf
+bgra                85fa06ad9fd156c3179a647a2e741b60
+gray                35b50e78d5d27255f43e642a404dd708
+gray16be            d206a080739d89cb7dc0009ad4082ed4
+gray16le            7ebcfd9401ba85e584230de8fc02986d
+pal8                19c8735b23feeed18ec2d37913a5f3f8
+rgb24               c2752464ac2b549268e9638745dba857
+rgb444be            85586541cc7eb12e05ff7162b12304c2
+rgb444le            670da20b82403e00609bf2c1f5611223
+rgb48be             a9ee2c9946d8d54dba60cebbdbe43886
+rgb48le             28e2cf59b789249dbd0859f58f4ae55d
+rgb4_byte           31dca70b4f3537afa9840cea1b062acf
+rgb555be            c010cc746ce9483b47387ba846670179
+rgb555le            a768de014e0908dfa886108da376b2e5
+rgb565be            6727e71974c8e5dad157925c10ee1532
+rgb565le            b0a2b4817775289cfc415bb951f9ae0c
+rgb8                22fdbd14ce296c1afa9bb4a6ea09b3fe
+rgba                a37789c4df73c3bd8648ad1fe9d3f991
+yuv410p             a1280c2b9b562dba3c2d35a1e5fc4b23
+yuv411p             6bf10756ac5c7841db63a97106ff911b
+yuv420p             45f4a06481f2cd8e28fb29c7c151e110
+yuv420p16be         cde798cad650bcb087943442a399c8ea
+yuv420p16le         b7124c56605eeb12f3d13287ddc77f3a
+yuv422p             c3982fbb57e796881efedae11b8346de
+yuv422p16be         4b96fb571e686185d96b4a97e3413d5f
+yuv422p16le         503bc49bace58dae1767173746a16056
+yuv440p             44f78792c5766ab896fbe0d718976946
+yuv444p             a36b8ce12de27971b52e93267fe6583f
+yuv444p16be         9370058632b2582ab7a21725ec4f4e1d
+yuv444p16le         0674c63a0e8debbfc010a2730da66a13
+yuva420p            a62cf0a72905b54a7ef10fcaeff723bc
+yuvj420p            86370b945c5d19d809ee92386d476a53
+yuvj422p            d3bda08bd4b92a256a8ec8432c4767d1
+yuvj440p            dbae7083c82f20a38fc55e6f8bc374bc
+yuvj444p            55ce75c7bd172b28703e82f64186e6b6
diff --git a/tests/ref/lavfi/pixfmts_null b/tests/ref/lavfi/pixfmts_null
index dc1b857..042f2d5 100644
--- a/tests/ref/lavfi/pixfmts_null
+++ b/tests/ref/lavfi/pixfmts_null
@@ -1,66 +1,83 @@
-abgr                037bf9df6a765520ad6d490066bf4b89
-argb                c442a8261c2265a07212ef0f72e35f5a
-bgr24               0d0cb38ab3fa0b2ec0865c14f78b217b
-bgr444be            d9ea9307d21b162225b8b2c524cf9477
-bgr444le            88035350e9da3a8f67387890b956f0bc
-bgr48be             00624e6c7ec7ab19897ba2f0a3257fe8
-bgr48le             d02c235ebba7167881ca2d576497ff84
-bgr4_byte           50d23cc82d9dcef2fd12adb81fb9b806
-bgr555be            49f01b1f1f0c84fd9e776dd34cc3c280
-bgr555le            378d6ac4223651a1adcbf94a3d0d807b
-bgr565be            257cf78afa35dc31e9696f139c916715
-bgr565le            1dfdd03995c287e3c754b164bf26a355
-bgr8                24bd566170343d06fec6fccfff5abc54
-bgra                76a18a5151242fa137133f604cd624d2
-gray                db08f7f0751900347e6b8649e4164d21
-gray16be            7becf34ae825a3df3969bf4c6bfeb5e2
-gray16le            10bd87059b5c189f3caef2837f4f2b5c
-monob               668ebe8b8103b9046b251b2fa8a1d88f
-monow               9251497f3b0634f1165d12d5a289d943
-nv12                e0af357888584d36eec5aa0f673793ef
-nv21                9a3297f3b34baa038b1f37cb202b512f
-rgb24               b41eba9651e1b5fe386289b506188105
-rgb444be            9e89db334568c6b2e3d5d0540f4ba960
-rgb444le            0a68cb6de8bf530aa30c5c1205c25155
-rgb48be             cc139ec1dd9451f0e049c0cb3a0c8aa2
-rgb48le             86c5608904f75360d492dbc5c9589969
-rgb4_byte           c93ba89b74c504e7f5ae9d9ab1546c73
-rgb555be            912a62c5e53bfcbac2a0340e10973cf2
-rgb555le            a937a0fc764fb57dc1b3af87cba0273c
-rgb565be            9cadf742e05ddc23a3b5b270f89aad3c
-rgb565le            d39aa298bb525e9be8860351c6f62dab
-rgb8                4a9d8e4f2f154e83a7e1735be6300700
-rgba                93a5b3712e6eb8c5b9a09ffc7b9fbc12
-uyvy422             adcf64516a19fce44df77082bdb16291
-yuv410p             2d9225153c83ee1132397d619d94d1b3
-yuv411p             8b298af3e43348ca1b11eb8a3252ac6c
-yuv420p             eba2f135a08829387e2f698ff72a2939
-yuv420p10be         299fe1d785a3d3dd5e70778700d7fb06
-yuv420p10le         8aee004e765a5383be0954f5e916b72f
-yuv420p16be         16c009a235cd52b74791a895423152a3
-yuv420p16le         2d59c4f1d0314a5a957a7cfc4b6fabcc
-yuv420p9be          ce880fa07830e5297c22acf6e20555ce
-yuv420p9le          16543fda8f87d94a6cf857d2e8d4461a
-yuv422p             c9bba4529821d796a6ab09f6a5fd355a
-yuv422p10be         11af7dfafe8bc025c7e3bd82b830fe8a
-yuv422p10le         ec04efb76efa79bf0d02b21572371a56
-yuv422p16be         5499502e1c29534a158a1fe60e889f60
-yuv422p16le         e3d61fde6978591596bc36b914386623
-yuv422p9be          29b71579946940a8c00fa844c9dff507
-yuv422p9le          062b7f9cbb972bf36b5bdb1a7623701a
-yuv440p             5a064afe2b453bb52cdb3f176b1aa1cf
-yuv444p             0a98447b78fd476aa39686da6a74fa2e
-yuv444p10be         71be185a2fb7a353eb024df9bc63212d
-yuv444p10le         c1c6b30a12065c7901c0a267e4861a0f
-yuv444p16be         1c6ea2c2f5e539006112ceec3d4e7d90
-yuv444p16le         20f86bc2f68d2b3f1f2b48b97b2189f4
-yuv444p9be          6ab31f4c12b533ce318ecdff83cdd054
-yuv444p9le          f0606604a5c08becab6ba500124c4b7c
-yuva420p            a29884f3f3dfe1e00b961bc17bef3d47
-yuva422p            92b6815f465297284cdb843711682cee
-yuva444p            c523716e4900cfe515eaab1d7124fdd9
-yuvj420p            32eec78ba51857b16ce9b813a49b7189
-yuvj422p            0dfa0ed434f73be51428758c69e082cb
-yuvj440p            657501a28004e27a592757a7509f5189
-yuvj444p            98d3d054f2ec09a75eeed5d328dc75b7
-yuyv422             f2569f2b5069a0ee0cecae33de0455e3
+0bgr                a06d3a7652e4885c65895e0e168aab28
+0rgb                b6b5653d2228cdf2ba3c55a72f2e713f
+abgr                1a147fa04ed70b9a7e67a4c89052f630
+argb                997df0b5c268a0d8f9c611cae4e01e05
+bgr0                218df6dc3eb5094a0c16a8bd18bc3999
+bgr24               d6370f6dc34df2ea66e1718baf74137b
+bgr444be            aba6dfea008ae12c2120a95f54293904
+bgr444le            cfb5401e8f076cc8675e17ed1114a3df
+bgr48be             ab65229b64606f6408cd732b967c0b01
+bgr48le             f1b4e718cadee9bd2978289153ce43de
+bgr4_byte           de96505ef9ad7078f87b4dfdf6fe4b61
+bgr555be            8d5de9e9200d622f27dc73958a85045c
+bgr555le            74eb9837706143a40e26305a16a79369
+bgr565be            13a36d6502be88fc0c2aec05b8d2d501
+bgr565le            ed027571692aecd522aa65a90cc7e09b
+bgr8                71ef789609c746c2e7e4be9dec29062c
+bgra                0364b074268682ea46168742a8239f7d
+gray                1e5e2b8548843a6898eedd9c974c422c
+gray16be            389f4e5a8ab413b3af32767b59ed7f9e
+gray16le            a1f912941247e45b394b9cf4f0e81130
+monob               309b5785a36bd988d17e15d88f4ffad1
+monow               8809a02bc69b58d1114b09ca79ebffad
+nv12                75e90c54d858b993e99f4ee6d2a2a38f
+nv21                8831a3f411015d45fbc5dd191245ba9c
+pal8                13de2a1c3c80cb64d14e2bc4f6f461d0
+rgb0                992f5ad24802cc255edab45c3084db4a
+rgb24               c71ba90f69f15c8275232bb3f62d0ced
+rgb444be            26eaec65d7efd2b0c9c13b47dfd9b241
+rgb444le            5f29863553107110ea817f52151d77b7
+rgb48be             a3bc81c46c21818a989f23104a599ab0
+rgb48le             e87c661ac49aea1f1e93939802883d92
+rgb4_byte           293b1b84f01efd90bde40cb3faffc127
+rgb555be            5229183fa64d4e5c7e3703d8263ee6ae
+rgb555le            c3e9978cb2a4129a5575935e8cbc433a
+rgb565be            bc123b962629ead1a06af0c18cbb6e5f
+rgb565le            20757fafe4756e62d845b2ab4c0b8f93
+rgb8                e01614f5416dcc8ad365ad7a57afc9fb
+rgba                53796fa4c392a1b2659595b6a284f8c4
+uyvy422             3f411f947e3ac8f842c88e717d68bd9a
+yuv410p             7dcf3f4770c8b494290ceacd2c2ce6db
+yuv411p             9461b188dab6f8b90d9a27e353a89f58
+yuv420p             61fffd2d8425759a33ae07e718d0242d
+yuv420p10be         2abf90242cb021cb6fcf9f2c3c92f6a7
+yuv420p10le         180b7e4de684c7225d2fb37614f842cb
+yuv420p12be         256c9e6cfc878a8abf681b30777c0620
+yuv420p12le         8dc8b86c4790da3769d4a62e87608623
+yuv420p14be         8d22756c5d2b9e501924c082bfb22a6c
+yuv420p14le         c9da19d4818bcb119ad6481b75778f7e
+yuv420p16be         4ccdcca6dd6a960f9a3333f0aee095bd
+yuv420p16le         9c5847d9b0de258a10ee906dc47e24ea
+yuv420p9be          fa7ad4f73232aac0e35def62af1e2c39
+yuv420p9le          3720ba1786b56c8f4913e67dddebbb07
+yuv422p             eee223e92f1f2e5ad4186b411ebf5816
+yuv422p10be         80fa87750491dcc3e93d175b64835654
+yuv422p10le         e1640cd315bd96c6b59f7753825a7306
+yuv422p12be         8a17ae3a5f565479ec4aa230ef78a6fa
+yuv422p12le         04215506e2eca5b79f47e322a5949a58
+yuv422p14be         0fec4a6615ff610e3ea5e85acbd1b273
+yuv422p14le         a54c6121c1cb713a33961ea0faa35956
+yuv422p16be         1f3c216927d17966a009a42def124bba
+yuv422p16le         90adbdffaeea9b09398339c8a1322b02
+yuv422p9be          e46446534dd0821029d3b831c9c1d1b0
+yuv422p9le          520e418a2429f7efee511b7fcbf45ab6
+yuv440p             456d83524b299f2fa1bb988e421554d9
+yuv444p             068bc09d282d18c9fa35c2787943fc2a
+yuv444p10be         9f6e1490080a454243daee9229425e1e
+yuv444p10le         cc183e51041351d9ac06c4df6e8ad5f7
+yuv444p12be         df420773bb3cca2ffb585db3bbe01195
+yuv444p12le         25c0c73d98c3c1e281044d79097608f5
+yuv444p14be         516b18e8331e7d404c7541bafc5501e6
+yuv444p14le         7c88d9a233979d73762cffef2fe08306
+yuv444p16be         4000b12fa88ed0feef182da31c7e6b96
+yuv444p16le         96a857dba8dc6792c58daec872825b32
+yuv444p9be          07727e5c9040b7f0a17d591288ac330d
+yuv444p9le          4d12d20a68dc28618594c96c2ade4ff4
+yuva420p            3a8c5c142e051367c196f95696e0e2c3
+yuva422p            45ae66d6f69fd5b77e6831e98d228bf4
+yuva444p            86b05da54db8c7e8cf5b6638e19c6fc5
+yuvj420p            73661456012f20cda81207b14bb0c0a5
+yuvj422p            aa97862b57f47c5a6506156e9aaf129a
+yuvj440p            ff8b9884a49d546b035f5d2ac1e673df
+yuvj444p            b8142888d80b8065c54045839e79b331
+yuyv422             f06a4fbbdb32807d05de825daa2c3a1b
diff --git a/tests/ref/lavfi/pixfmts_pad b/tests/ref/lavfi/pixfmts_pad
index 03db5a7..9c31974 100644
--- a/tests/ref/lavfi/pixfmts_pad
+++ b/tests/ref/lavfi/pixfmts_pad
@@ -1,17 +1,24 @@
-abgr                e8e5e350c856c051d502cd435a2aa0bd
-argb                a98e0a1213824ee4566d4891468bb614
-bgr24               ac7417cea8d6e799a31a3c9a39b8f202
-bgra                6113a09a023cb2b08e9cad78eb1eb37a
-rgb24               65eed443acc66c4f02bab6df4ebed515
-rgba                74d4158ad0c626e9a7c6923b9ca73294
-yuv410p             a5210eb6a9b10c3269899b935df9a2d6
-yuv411p             a23380c9698e2d80c9fa8a8b6d4f6854
-yuv420p             f8733600369adaea28aa445dbdf2ed4c
-yuv422p             3e0d822c11c716e7636387b1bf27c5ff
-yuv440p             225dd7fbc8cceb24c26b765187d43a9e
-yuv444p             45484f0411d336ce94636da0395f4692
-yuva420p            919722724765dc3a716c38fa53b20580
-yuvj420p            4f20e2799966c21a9d9e0788b0956925
-yuvj422p            e4d84b0683f77a76f1c17d976eff127c
-yuvj440p            33511c43339aa32533ab832861c150c3
-yuvj444p            82f0badd9d0c062bbfa0d9d73d7240a3
+0bgr                36ba5b43e0ac64d8daad4f897efd8cdf
+0rgb                cc3ca0f63885af19b3daa4504cadcc19
+abgr                9ddb78f395d7d3f75b65b5309223c0c5
+argb                e5fbb7bb282a80897b8f730627f68876
+bgr0                c55368036cccbb0af471d6bd82abe02a
+bgr24               67f9fd70dc6d9896b7122976b33932b4
+bgra                c8dd017b5a3b55e8b9d0ac1cdcf327bd
+gray                b1abadae3718522aa57a7972da8cbe17
+rgb0                b1977b45634c4db58a183a07feb2acff
+rgb24               e73de9dc0fdd78f4853c168603cc7aba
+rgba                5a36df3c5ba623b589728a5a442e98e2
+yuv410p             ff246b8b41d3d4a3eb90414ae3031123
+yuv411p             a82c606c665fa747679aa8bfffa8a5db
+yuv420p             0fe4d9031999f83ca96292ec2025f272
+yuv422p             5e0bffdac30b39f1bae9ec54fd9a6a34
+yuv440p             5e338303cd89d1d76ab918e5bec1e90d
+yuv444p             248bdf9747d5c3718580dc2279e2e273
+yuva420p            b5bdefbb0c5b302b6d18ee4df7c1d7c7
+yuva422p            8b56b36d9eb3c382d2a5a695107e759d
+yuva444p            389cf95e98bf24684a42d5d67b913e16
+yuvj420p            d182ac937d312e4894c1bc548883bf1c
+yuvj422p            26ac91b5daf6f2f1f3c22be489e994a3
+yuvj440p            63e2b94f81e0a6f2868055a4c8258b63
+yuvj444p            64f103c7db8fc803d062db7ed2b8dc76
diff --git a/tests/ref/lavfi/pixfmts_pixdesctest b/tests/ref/lavfi/pixfmts_pixdesctest
new file mode 100644
index 0000000..918efbc
--- /dev/null
+++ b/tests/ref/lavfi/pixfmts_pixdesctest
@@ -0,0 +1,83 @@
+0bgr                2b46a6ce47a19ffc240e4e93f498f491
+0rgb                e90e5d377a3e5af69fdf7b60cbf88f51
+abgr                1a147fa04ed70b9a7e67a4c89052f630
+argb                997df0b5c268a0d8f9c611cae4e01e05
+bgr0                b61591a68252e66c576b9bb074a9eaed
+bgr24               d6370f6dc34df2ea66e1718baf74137b
+bgr444be            aba6dfea008ae12c2120a95f54293904
+bgr444le            cfb5401e8f076cc8675e17ed1114a3df
+bgr48be             ab65229b64606f6408cd732b967c0b01
+bgr48le             f1b4e718cadee9bd2978289153ce43de
+bgr4_byte           de96505ef9ad7078f87b4dfdf6fe4b61
+bgr555be            8d5de9e9200d622f27dc73958a85045c
+bgr555le            74eb9837706143a40e26305a16a79369
+bgr565be            13a36d6502be88fc0c2aec05b8d2d501
+bgr565le            ed027571692aecd522aa65a90cc7e09b
+bgr8                71ef789609c746c2e7e4be9dec29062c
+bgra                0364b074268682ea46168742a8239f7d
+gray                1e5e2b8548843a6898eedd9c974c422c
+gray16be            389f4e5a8ab413b3af32767b59ed7f9e
+gray16le            a1f912941247e45b394b9cf4f0e81130
+monob               309b5785a36bd988d17e15d88f4ffad1
+monow               8809a02bc69b58d1114b09ca79ebffad
+nv12                75e90c54d858b993e99f4ee6d2a2a38f
+nv21                8831a3f411015d45fbc5dd191245ba9c
+pal8                13de2a1c3c80cb64d14e2bc4f6f461d0
+rgb0                5774780b3c532896300fa326fcde01a8
+rgb24               c71ba90f69f15c8275232bb3f62d0ced
+rgb444be            26eaec65d7efd2b0c9c13b47dfd9b241
+rgb444le            5f29863553107110ea817f52151d77b7
+rgb48be             a3bc81c46c21818a989f23104a599ab0
+rgb48le             e87c661ac49aea1f1e93939802883d92
+rgb4_byte           293b1b84f01efd90bde40cb3faffc127
+rgb555be            5229183fa64d4e5c7e3703d8263ee6ae
+rgb555le            c3e9978cb2a4129a5575935e8cbc433a
+rgb565be            bc123b962629ead1a06af0c18cbb6e5f
+rgb565le            20757fafe4756e62d845b2ab4c0b8f93
+rgb8                e01614f5416dcc8ad365ad7a57afc9fb
+rgba                53796fa4c392a1b2659595b6a284f8c4
+uyvy422             3f411f947e3ac8f842c88e717d68bd9a
+yuv410p             7dcf3f4770c8b494290ceacd2c2ce6db
+yuv411p             9461b188dab6f8b90d9a27e353a89f58
+yuv420p             61fffd2d8425759a33ae07e718d0242d
+yuv420p10be         2abf90242cb021cb6fcf9f2c3c92f6a7
+yuv420p10le         180b7e4de684c7225d2fb37614f842cb
+yuv420p12be         256c9e6cfc878a8abf681b30777c0620
+yuv420p12le         8dc8b86c4790da3769d4a62e87608623
+yuv420p14be         8d22756c5d2b9e501924c082bfb22a6c
+yuv420p14le         c9da19d4818bcb119ad6481b75778f7e
+yuv420p16be         4ccdcca6dd6a960f9a3333f0aee095bd
+yuv420p16le         9c5847d9b0de258a10ee906dc47e24ea
+yuv420p9be          fa7ad4f73232aac0e35def62af1e2c39
+yuv420p9le          3720ba1786b56c8f4913e67dddebbb07
+yuv422p             eee223e92f1f2e5ad4186b411ebf5816
+yuv422p10be         80fa87750491dcc3e93d175b64835654
+yuv422p10le         e1640cd315bd96c6b59f7753825a7306
+yuv422p12be         8a17ae3a5f565479ec4aa230ef78a6fa
+yuv422p12le         04215506e2eca5b79f47e322a5949a58
+yuv422p14be         0fec4a6615ff610e3ea5e85acbd1b273
+yuv422p14le         a54c6121c1cb713a33961ea0faa35956
+yuv422p16be         1f3c216927d17966a009a42def124bba
+yuv422p16le         90adbdffaeea9b09398339c8a1322b02
+yuv422p9be          e46446534dd0821029d3b831c9c1d1b0
+yuv422p9le          520e418a2429f7efee511b7fcbf45ab6
+yuv440p             456d83524b299f2fa1bb988e421554d9
+yuv444p             068bc09d282d18c9fa35c2787943fc2a
+yuv444p10be         9f6e1490080a454243daee9229425e1e
+yuv444p10le         cc183e51041351d9ac06c4df6e8ad5f7
+yuv444p12be         df420773bb3cca2ffb585db3bbe01195
+yuv444p12le         25c0c73d98c3c1e281044d79097608f5
+yuv444p14be         516b18e8331e7d404c7541bafc5501e6
+yuv444p14le         7c88d9a233979d73762cffef2fe08306
+yuv444p16be         4000b12fa88ed0feef182da31c7e6b96
+yuv444p16le         96a857dba8dc6792c58daec872825b32
+yuv444p9be          07727e5c9040b7f0a17d591288ac330d
+yuv444p9le          4d12d20a68dc28618594c96c2ade4ff4
+yuva420p            3a8c5c142e051367c196f95696e0e2c3
+yuva422p            45ae66d6f69fd5b77e6831e98d228bf4
+yuva444p            86b05da54db8c7e8cf5b6638e19c6fc5
+yuvj420p            73661456012f20cda81207b14bb0c0a5
+yuvj422p            aa97862b57f47c5a6506156e9aaf129a
+yuvj440p            ff8b9884a49d546b035f5d2ac1e673df
+yuvj444p            b8142888d80b8065c54045839e79b331
+yuyv422             f06a4fbbdb32807d05de825daa2c3a1b
diff --git a/tests/ref/lavfi/pixfmts_scale b/tests/ref/lavfi/pixfmts_scale
index acd40e3..3713142 100644
--- a/tests/ref/lavfi/pixfmts_scale
+++ b/tests/ref/lavfi/pixfmts_scale
@@ -1,66 +1,83 @@
-abgr                d894cb97f6c80eb21bdbe8a4eea62d86
-argb                54346f2b2eef10919e0f247241df3b24
-bgr24               570f8d6b51a838aed022ef67535f6bdc
-bgr444be            25fe04f73a3bad4140d1c4f96ca5b670
-bgr444le            2fde227e6cea6dca5decdd0b7c0866f7
-bgr48be             390d3058a12a99c2b153ed7922508bea
-bgr48le             39fe06feb4ec1d9730dccc04a0cfac4c
-bgr4_byte           ee1d35a7baf8e9016891929a2f565c0b
-bgr555be            de8901c1358834fddea060fcb3a67beb
-bgr555le            36b745067197f9ca8c1731cac51329c9
-bgr565be            922a2503767036ae9536f4f7823c04ee
-bgr565le            3a514a298c6161a071ddf9963c06509d
-bgr8                7f007fa6c153a16e808a9c51605a4016
-bgra                a5e7040f9a80cccd65e5acf2ca09ace5
-gray                d7786a7d9d99ac74230cc045cab5632c
-gray16be            b554d6c1cc8da23967445be4dd3e4a86
-gray16le            715a33aa1c19cb26b14f5cc000e7a3d1
-monob               88c4c050758e64d120f50c7eff694381
-monow               d31772ebaa877fc2a78565937f7f9673
-nv12                4676d59db43d657dc12841f6bc3ab452
-nv21                69c699510ff1fb777b118ebee1002f14
-rgb24               514692e28e8ff6860e415ce4fcf6eb8c
-rgb444be            12254053ae93373869fca18b2afcba31
-rgb444le            badbd68b59c87df6ae73248309637634
-rgb48be             8fac63787a711886030f8e056872b488
-rgb48le             ab92f2763a2eb264c3870cc758f97149
-rgb4_byte           d81ffd3add95842a618eec81024f0b5c
-rgb555be            4607309f9f217d51cbb53d13b84b4537
-rgb555le            a350ef1dc2c9688ed49e7ba018843795
-rgb565be            678ce231c4ea13629c1353b1df4ffbef
-rgb565le            6f4bb711238baa762d73305213f8d035
-rgb8                091d0170b354ef0e97312b95feb5483f
-rgba                a3d362f222098a00e63867f612018659
-uyvy422             314bd486277111a95d9369b944fa0400
-yuv410p             7df8f6d69b56a8dcb6c7ee908e5018b5
-yuv411p             1143e7c5cc28fe0922b051b17733bc4c
-yuv420p             fdad2d8df8985e3d17e73c71f713cb14
-yuv420p10be         27f28a6e09b1c04d0f755035a5db1f43
-yuv420p10le         a5a1692e026590ba2eddb46b9b827529
-yuv420p16be         d7270efce54eb59c7b01c14157a1b890
-yuv420p16le         e85abf00bad940a922b623c91c9026d7
-yuv420p9be          bb87fddca65d1742412c8d2b1caf96c6
-yuv420p9le          828eec50014a41258a5423c1fe56ac97
-yuv422p             918e37701ee7377d16a8a6c119c56a40
-yuv422p10be         315654908d50718e175aae018c484732
-yuv422p10le         91bbc78a9a56f659b55abc17722dcc09
-yuv422p16be         e7e34fe9264784763ab6cb406524c0f3
-yuv422p16le         c435b76b08204dda6908640fb5fd4621
-yuv422p9be          82494823944912f73cebc58ad2979bbd
-yuv422p9le          fc69c8a21f473916a4b4225636b97e06
-yuv440p             461503fdb9b90451020aa3b25ddf041c
-yuv444p             81b2eba962d12e8d64f003ac56f6faf2
-yuv444p10be         fb304d77c6d2e18df5938662a22176f0
-yuv444p10le         b17136913eb066dca6be6af645b9f7e8
-yuv444p16be         0da9bed80f5542682ab286f3261cf24c
-yuv444p16le         a0c5d3c7bf3f181db503cf8e450d1335
-yuv444p9be          9ac2643ce7f7e5c4e17c8c9fd8494d4a
-yuv444p9le          896a1cc9cccca1ba410dd53942d33cc4
-yuva420p            8673a9131fb47de69788863f93a50eb7
-yuva422p            3c76ebeca0a7d3aa5f8e31ef80a86ffe
-yuva444p            3268c6abe5e3cdbd16552a1eddced816
-yuvj420p            30427bd6caf5bda93a173dbebe759e09
-yuvj422p            fc8288f64fd149573f73cf8da05d8e6d
-yuvj440p            508ac7a9ddeb6d1794a1100ba7a1664c
-yuvj444p            73aebe144085b22d1189caf6ca07e18c
-yuyv422             169e19ac91b257bd84ace0fdf56559ad
+0bgr                710350573339f608b23e5bf8ea3327d0
+0rgb                ba87d80ccd24ffb20ac711511132adb8
+abgr                e448ff50225b119979987e55399e49e2
+argb                ef03d804e0de6315fd59e3d2edaddb9d
+bgr0                93cd61cfcbef1789d2d5ccae4de75f79
+bgr24               793fc4c2b1c92ad4f7f4dca157e624d1
+bgr444be            9af6abe0bc74cdcc75b4ab2f441f5f67
+bgr444le            b8c0e693ae2cbd7c03abcc3aeb4bf7b4
+bgr48be             3aa33b667b9baefe3f17ef44360688cd
+bgr48le             eaf353ab363fbb279fd72d6c6e3b8855
+bgr4_byte           a6e269daf7085504a01113ce5e8bff57
+bgr555be            9d71206c1a5373b8978126e5f5779726
+bgr555le            025caaa21fed9d14c382cac26af778c8
+bgr565be            fca6f07daf23d9dd84381dd4c9afd959
+bgr565le            f524e9f16bdd68b247dbcb621e543fc0
+bgr8                68a3a395043dc57335ad1f8e891229c5
+bgra                3eaf5489b8aa13a3388aad3751b597bf
+gray                045c35e6cc7d41460f2b96b3e254deab
+gray16be            70064f9acdc5e3935ccda67e765bf2fb
+gray16le            578241fb43029e5ae841a3c94d940dce
+monob               91ec2a25b13f6ca34d42da778b217de0
+monow               a991455fda8f60f373aeb744456996b9
+nv12                0617f1e13ae4a43d4cb49282b9c02f71
+nv21                8a00d5d29766c1251eeda74c0ddee3f2
+pal8                7849884994cf99604f025b053332d08d
+rgb0                6a9d26ebf674f02b5a8830583ba7a171
+rgb24               1de2978e23ad10b9b4ca2777688b4546
+rgb444be            88f534c5d07ebf5a4374484aed540893
+rgb444le            c243685bfad7c243a78892a0dafe2b9f
+rgb48be             874c8e2305ce9d82165ffddf2854d1f2
+rgb48le             877075f2ff2d9a0aec6fec843385f126
+rgb4_byte           4a8b119cf1996efe273302da29cbfbfb
+rgb555be            8aeefa1fc4eba200abee3b1eb52186af
+rgb555le            0495a7c13f9b0d0253379d5ae90cf6c4
+rgb565be            5168b66e69c25351948085e5fc51bb3a
+rgb565le            301a4d41f0db3aaed341d812ed0d7927
+rgb8                8e5786e83099bc89d2e38a76e6dfcc52
+rgba                de6a65b8c01bdad84e575202ca8b66a0
+uyvy422             479105bc4c7fbb4a33ca8745aa8c2de8
+yuv410p             d0daa93f5cee83360e219e39563ab6da
+yuv411p             e5c8f3ca024a88dd07e0a92db3e2133d
+yuv420p             485d9af8608f926ffffbf42230b4150d
+yuv420p10be         e4f12002b46549779886f27fd3c6c645
+yuv420p10le         698b7a346ae6d1315280d3e28c86b973
+yuv420p12be         3d2f7485d277fb66503f6af88bc81b62
+yuv420p12le         a19c3fd126c7a11d9632922e713ce555
+yuv420p14be         a1fcbe583e2e687e89ced29260a51fe2
+yuv420p14le         c689144ea25dd2f760331a6d525bebc2
+yuv420p16be         6ebcf48a9317c6265430cd3ba5f569a2
+yuv420p16le         604a7215f384488a38aa0cffdbcbe17e
+yuv420p9be          7b293aec92897bf0a32ec3a02a20acf9
+yuv420p9le          f37fdff7d6c62ebe2ab0cf791cd049db
+yuv422p             b1724528079199908c667b3428a7c01c
+yuv422p10be         1c7281254fb980c123148dfd145c4a05
+yuv422p10le         959caa253354e897f01848db21b8006e
+yuv422p12be         15f63e4cc4a175db4599af1c2aad4047
+yuv422p12le         08d08b2d2ab7482c41ebdf50fcc3ee3c
+yuv422p14be         ca008297abbb10b931a9e142747291ec
+yuv422p14le         0fd39837ecd739f9da916dbf81f0b45c
+yuv422p16be         4ccc3e0bc94eaf3a3350e4d694c3a56c
+yuv422p16le         dde889032f13fa5f8d76b8484dd73116
+yuv422p9be          ba5eae7669d02a13f54a592344612098
+yuv422p9le          2deb39425d924a15c8946df79ceaa579
+yuv440p             19de0ba1fd354b42189e96cdf73ef7cc
+yuv444p             fba8a00cd0b182af82e9de3b2f4d2c8a
+yuv444p10be         db89397ac4d33e66b5eab3678661f73a
+yuv444p10le         28208677f07d4e4191ef228c096f3297
+yuv444p12be         e41f8e27049c52da647e3d6927b591b3
+yuv444p12le         9428605417583e26041cb2b8d166df62
+yuv444p14be         a71cad94426e92d77e2f548d4d21a7c0
+yuv444p14le         adfe8463839fe67394529299620c078d
+yuv444p16be         07e27200d2f4382090ca260874f02e92
+yuv444p16le         f8bac16bf1f2afbd3626e07bcc815a9f
+yuv444p9be          db739906e3ae3b8792cdc5a0c3387565
+yuv444p9le          693b8d30958ef1a37296b1690b4b36d2
+yuva420p            df46b738bdaf30d3a7f880b5ae45b092
+yuva422p            650755270debb03d2c03b2e93b64c576
+yuva444p            72083e0941cc45af9f97b89d3cd16112
+yuvj420p            31386dce60a2dcc493da5d0ed9d880df
+yuvj422p            492452e50a3fe66724840cad29be4098
+yuvj440p            7632893e81d3f4f3ace3755f97479897
+yuvj444p            389388dd5d623f660c30ab840807ce82
+yuyv422             518be9b5ac93c365c0962453770fbe73
diff --git a/tests/ref/lavfi/pixfmts_super2xsai b/tests/ref/lavfi/pixfmts_super2xsai
new file mode 100644
index 0000000..964d04a
--- /dev/null
+++ b/tests/ref/lavfi/pixfmts_super2xsai
@@ -0,0 +1,14 @@
+abgr                b04e3dfb0043f6eb04a573d2d13052eb
+argb                257e33717d23298430025c0665642cd5
+bgr24               3765d88f93d4ae8baa2cfbc64b0b32e1
+bgr555be            81832e6269c509be55bba49bdd0ebed5
+bgr555le            56772e91aefba4013890d156866730ce
+bgr565be            0b3c420fbddcec5a420c285b3c4b8792
+bgr565le            6cbded26d2bab8204afe2115384c09a8
+bgra                c81430c3d1465e37b6acaa19cc54e932
+rgb24               9899359a817e705dc5b9cc363d35a625
+rgb555be            9b60d9aa1f3c78edf9936894f37e3243
+rgb555le            917fa8565f35882404a45fee3a947bf7
+rgb565be            12edaab49440fbb3aa4c1835fd697745
+rgb565le            5bf91cb1767066f23f0c672dedb4d476
+rgba                71687289b6c3ab6fa727d468de459026
diff --git a/tests/ref/lavfi/pixfmts_vflip b/tests/ref/lavfi/pixfmts_vflip
index a4dffb9..50a459d 100644
--- a/tests/ref/lavfi/pixfmts_vflip
+++ b/tests/ref/lavfi/pixfmts_vflip
@@ -1,66 +1,83 @@
-abgr                25e72e9dbd01ab00727c976d577f7be5
-argb                19869bf1a5ac0b6af4d8bbe2c104533c
-bgr24               89108a4ba00201f79b75b9305c42352d
-bgr444be            9ef12c42fb791948ca4423c452dc6b9a
-bgr444le            3650ecfc163abd1596c0cd29d130c4b0
-bgr48be             2f23931844f57641f3737348182d118c
-bgr48le             4242a026012b6c135a6aa138a6d67031
-bgr4_byte           407fcf564ed764c38e1d748f700ab921
-bgr555be            f739d2519f7e9d494359bf67a3821537
-bgr555le            bd7b3ec4d684dfad075d89a606cb8b74
-bgr565be            f19e9a4786395e1ddcd51399c98c9f6c
-bgr565le            fdb617533e1e7ff512ea5b6b6233e738
-bgr8                c60f93fd152c6903391d1fe9decd3547
-bgra                7f9b799fb48544e49ce93e91d7f9fca8
-gray                30d9014a9d43b5f37e7aa64be3a3ecfc
-gray16be            6b84b85d3326182fa1217e138249edc5
-gray16le            66bb8faa09dc149734aca3c768a6d4e1
-monob               d0cf8732677a5360b6160133043590d8
-monow               ff9869d067ecb94eb9d90c9750c31fea
-nv12                046f00f598ce14d9854a3534a5c99114
-nv21                01ea369dd2d0d3ed7451dc5c8d61497f
-rgb24               eaefabc168d0b14576bab45bc1e56e1e
-rgb444be            06722e03f8404e7d2226665ed2444a32
-rgb444le            185c9a5d9c2877484310d4196ef4cd6f
-rgb48be             62dd185862ed142283bd300eb6dbd216
-rgb48le             dcb76353268bc5862194d131762220da
-rgb4_byte           8c6ff02df0b06dd2d574836c3741b2a2
-rgb555be            40dc33cfb5cf56aac1c5a290ac486c36
-rgb555le            4f8eaad29a17e0f8e9d8ab743e76b999
-rgb565be            b57623ad9df74648339311a0edcebc7b
-rgb565le            73f247a3315dceaea3022ac7c197c5ef
-rgb8                13a8d89ef78d8127297d899005456ff0
-rgba                1fc6e920a42ec812aaa3b2aa02f37987
-uyvy422             ffbd36720c77398d9a0d03ce2625928f
-yuv410p             7bfb39d7afb49d6a6173e6b23ae321eb
-yuv411p             4a90048cc3a65fac150e53289700efe1
-yuv420p             2e6d6062e8cad37fb3ab2c433b55f382
-yuv420p10be         fb0772f5e2b9da20ff826e64c3893137
-yuv420p10le         e95879e14c4a6805f39643964baf41f7
-yuv420p16be         539076782902664a8acf381bf4f713e8
-yuv420p16le         0f609e588e5a258644ef85170d70e030
-yuv420p9be          be40ec975fb2873891643cbbbddbc3b0
-yuv420p9le          7e606310d3f5ff12badf911e8f333471
-yuv422p             d7f5cb44d9b0210d66d6a8762640ab34
-yuv422p10be         0be8378c3773e1c0b394315ef4994351
-yuv422p10le         6518094fe8de6bee95af21af1e5dc1e1
-yuv422p16be         9bd8f8c961822b586fa4cf992be54acc
-yuv422p16le         9c4a1239605c7952b736ac3130163f14
-yuv422p9be          7c6f1e140b3999ee7d923854e507752a
-yuv422p9le          51f10d79c07989060dd06e767e6d7d60
-yuv440p             876385e96165acf51271b20e5d85a416
-yuv444p             9c3c667d1613b72d15bc6d851c5eb8f7
-yuv444p10be         ee069cc6db48975eb029d72f889a7fe6
-yuv444p10le         645b3335248113cafe3c29edb1d7f3be
-yuv444p16be         de2dedfc6f12073ffead113f86e07ecf
-yuv444p16le         8e83323cf102d6c823a03ae8a7b7e033
-yuv444p9be          6ac92b7dc9ab2fc59bee99204886899a
-yuv444p9le          85aef13a654953d3455d89770b0d74bd
-yuva420p            c705d1cf061d8c6580ac690b55f92276
-yuva422p            6aed0ea657ed51cc047a4fbdd981aec8
-yuva444p            da5d64f2b2bd2013c186456f595fad65
-yuvj420p            41fd02b204da0ab62452cd14b595e2e4
-yuvj422p            7f6ca9bc1812cde02036d7d29a7cce43
-yuvj440p            25711c3c0fd15ec19c59a10784fcfb96
-yuvj444p            e45dee2ac02276dfab92e8ebfbe52e00
-yuyv422             e944ff7316cd03c42c091717ce74f602
+0bgr                30d1f7d7081c012556da0373e6d389ee
+0rgb                66cd838e9c19f750c61efd73f66c42ac
+abgr                e6cc18ed21293e455d1dc63f9e1645e4
+argb                b5383d783698a0b3d753d01f2498e490
+bgr0                f99729e70a94d1c278c292a7acdddae5
+bgr24               c48ec71c68a9840572a548c2ad141028
+bgr444be            ab9253d2f836f58ff8f3f2b4ec76abdc
+bgr444le            b1bd8245a286b615e75e10d34fda4e62
+bgr48be             b5355b4fa578b9422288507cf7fba2b6
+bgr48le             11dc232500b6339f58a9981f46d1d7a9
+bgr4_byte           531fd9a2249a213c89b1afc9788d070e
+bgr555be            54ba55dc1dcc5a7f27f2727976be6583
+bgr555le            a45c637fe5ce84b238b1e6f66fc8c852
+bgr565be            7100c2ddfee42e7efafec1ccefecf7c6
+bgr565le            9fab295d966386d4ef99d5b43066da47
+bgr8                275ce12eeb05de67a6915f67cbb43ce5
+bgra                d29c35871248c476c366e678db580982
+gray                a53528cdf80ed31c9897042a2ea16618
+gray16be            9b23f3e79c54a6ccb62e0135a32e3045
+gray16le            93cfa8fbb2a86ead275ce1817444e6d5
+monob               c395a8efb9477b4ec53a77326e41ccd7
+monow               efaee1c763ccd5ce1a8519d2ed5aa5a9
+nv12                77373304a9c732b65dab0a33afba9295
+nv21                1e70b3ce8be75f91f465a6d62df550c3
+pal8                be51ffaaad8e8428f2ce1e10d5729d3d
+rgb0                84a83e576fc59ffd1ac5549fd7aa0023
+rgb24               a00171a51cbbdcc61ecbd0198b2e2513
+rgb444be            09a819863d3fe75518376cdac01c069f
+rgb444le            4ab35fc85b8550be2a9b96dec9bf7306
+rgb48be             97a30a902d26b4840235926dae9028dd
+rgb48le             82b33a864bab70d5463d57eaf693e78c
+rgb4_byte           afbfab537406988eab7460ec748a0389
+rgb555be            95e417e9429622245e2d2e0b1c3ab3e4
+rgb555le            e4b35d8e9c1710f6d051fb4bda8700cc
+rgb565be            c70d86afbd68a073f2d4fe0eee3a9832
+rgb565le            991576c5d3308a73068a826543b3e7af
+rgb8                42230235c5a2a66c0f9a2fcd20f9f5cd
+rgba                a6973a2940a378d2a8284194da26eec0
+uyvy422             21c48162379321bb83ec2399535f9253
+yuv410p             8699f50c04f8ac931aa5a8306827364b
+yuv411p             47af34559b92b68851df4c2b170f7736
+yuv420p             c59b35b82b5a195128736021913b35a4
+yuv420p10be         fc5eed1744cdd033728362772a450e32
+yuv420p10le         141e6b39adac979765c846f3a5a8293c
+yuv420p12be         0e0145d3592d56362c1bcc62cbd78a78
+yuv420p12le         8c3a2b27126df203786d4e05fd79e269
+yuv420p14be         6a11c75aa378f9628cd8fc3339474e68
+yuv420p14le         e8b683876508bc0371582e2b8c0eb191
+yuv420p16be         c467fae3a1936f3f91c19dd1c0c63e49
+yuv420p16le         87f09595ac106e694c538382179bfcc5
+yuv420p9be          31bc440f64fdd8d9e7cba897881345ec
+yuv420p9le          c6fed3016f03c49aa01bdcd63f846d3a
+yuv422p             5e48541d3e659046ac0e1eacb038485f
+yuv422p10be         9097b4d06f1fc598375b7c6480a2ba50
+yuv422p10le         da7bd36f65cac06bd54bc9857493d835
+yuv422p12be         1203cc6c2294234ddc5435f48b192d7c
+yuv422p12le         5cc76614210c026c3f1a5398f8654774
+yuv422p14be         d52e4b435329e806c03860421b94f9fd
+yuv422p14le         143937ee2e47fa35b71972a2aa74b772
+yuv422p16be         95ed65e718929dbeb5092bf0d852026d
+yuv422p16le         c62e554dde4a170177bec2efc3f4f1a2
+yuv422p9be          b249cd58eaab5ccac6bae3e184774362
+yuv422p9le          696fc2a55f155edaaa9fc289574b2bb8
+yuv440p             fca8395b7e43e2d0f38dd6ba822ef747
+yuv444p             1ef971a434c53e81c578e3c7cb9cbcad
+yuv444p10be         3114a7469c2b9c440a9a9ccbd6e167d6
+yuv444p10le         34cb8774a1eb627b5f32825ac7d0ae9a
+yuv444p12be         d770e81c67d6fe707c239b422021dd29
+yuv444p12le         9aa076fb7ac058b34ae4e8f09d7895e6
+yuv444p14be         40a9bef6e22c4c3dfd1d9dbeecd701e3
+yuv444p14le         123539bdc6946cfb61bd0d82cf8c6f17
+yuv444p16be         35340098dc6956c34afce17bc6ffcedd
+yuv444p16le         201e3acfa6f7628dfe2a1663de1128b1
+yuv444p9be          6143c321929ade9e0bc93ddea926e936
+yuv444p9le          e43ba2026848ec803fabf74d77c10125
+yuva420p            dc8fd115eaf203a3eac351b92a7d8f18
+yuva422p            6091f9c62a121c09eadb02e9173b2da2
+yuva444p            9a55e83047abcc7a709f20805070135e
+yuvj420p            200b0332de9944e76c94d2e0699a5a2d
+yuvj422p            a19a89ef145305cf224ef5aa247d075a
+yuvj440p            4240c9348d28af5f3edd0e642002bd2c
+yuvj444p            9e11298ba9c4faae0f5c81420d2123f2
+yuyv422             867fff568fa4170503779c48e5f25e6e
diff --git a/tests/ref/lavfi/pp b/tests/ref/lavfi/pp
new file mode 100644
index 0000000..bfa86ef
--- /dev/null
+++ b/tests/ref/lavfi/pp
@@ -0,0 +1 @@
+pp                  8e68fb247880aa083e91bcbddf9d76c7
diff --git a/tests/ref/lavfi/pp2 b/tests/ref/lavfi/pp2
new file mode 100644
index 0000000..819d4e4
--- /dev/null
+++ b/tests/ref/lavfi/pp2
@@ -0,0 +1 @@
+pp2                 28e91376aeb49c79dae9221b1a4997ae
diff --git a/tests/ref/lavfi/pp3 b/tests/ref/lavfi/pp3
new file mode 100644
index 0000000..2956375
--- /dev/null
+++ b/tests/ref/lavfi/pp3
@@ -0,0 +1 @@
+pp3                 d8d19c1f5e3f4032e9ed7bbb2026f030
diff --git a/tests/ref/lavfi/pp4 b/tests/ref/lavfi/pp4
new file mode 100644
index 0000000..0557ca6
--- /dev/null
+++ b/tests/ref/lavfi/pp4
@@ -0,0 +1 @@
+pp4                 d79a3727359f62747edb82cc92ed040b
diff --git a/tests/ref/lavfi/pp5 b/tests/ref/lavfi/pp5
new file mode 100644
index 0000000..4265566
--- /dev/null
+++ b/tests/ref/lavfi/pp5
@@ -0,0 +1 @@
+pp5                 5dc5a1f0c67d8a78e32cf50f47d1b27f
diff --git a/tests/ref/lavfi/pp6 b/tests/ref/lavfi/pp6
new file mode 100644
index 0000000..ca40024
--- /dev/null
+++ b/tests/ref/lavfi/pp6
@@ -0,0 +1 @@
+pp6                 40fb584b10082dff87fb947a1bccdbef
diff --git a/tests/ref/lavfi/scale200 b/tests/ref/lavfi/scale200
index 17103a2..f267522 100644
--- a/tests/ref/lavfi/scale200
+++ b/tests/ref/lavfi/scale200
@@ -1 +1 @@
-scale200            aebdc1c3e08da2a925ba7212b1fadee0
+scale200            e84ce966038a9f8f915704959f64278d
diff --git a/tests/ref/lavfi/scale500 b/tests/ref/lavfi/scale500
index 93ba4f2..ec4a699 100644
--- a/tests/ref/lavfi/scale500
+++ b/tests/ref/lavfi/scale500
@@ -1 +1 @@
-scale500            ef865c51156e55ce1ce38c8f90a709e6
+scale500            24e89b23ba4286162c2026181db8d2b7
diff --git a/tests/ref/lavfi/select b/tests/ref/lavfi/select
new file mode 100644
index 0000000..a9d2be0
--- /dev/null
+++ b/tests/ref/lavfi/select
@@ -0,0 +1 @@
+select              7975bb8d0e326af9369379927324f1a6
diff --git a/tests/ref/lavfi/setdar b/tests/ref/lavfi/setdar
new file mode 100644
index 0000000..5bc7d5d
--- /dev/null
+++ b/tests/ref/lavfi/setdar
@@ -0,0 +1 @@
+setdar              04b06d4622b116cdae756d4b475b9d5d
diff --git a/tests/ref/lavfi/setsar b/tests/ref/lavfi/setsar
new file mode 100644
index 0000000..86592e8
--- /dev/null
+++ b/tests/ref/lavfi/setsar
@@ -0,0 +1 @@
+setsar              04b06d4622b116cdae756d4b475b9d5d
diff --git a/tests/ref/lavfi/testsrc b/tests/ref/lavfi/testsrc
new file mode 100644
index 0000000..8e2363b
--- /dev/null
+++ b/tests/ref/lavfi/testsrc
@@ -0,0 +1 @@
+testsrc             cdac8817054b30e086d6ecabdcec5444
diff --git a/tests/ref/lavfi/thumbnail b/tests/ref/lavfi/thumbnail
new file mode 100644
index 0000000..5cfbf50
--- /dev/null
+++ b/tests/ref/lavfi/thumbnail
@@ -0,0 +1 @@
+thumbnail           33c479d5701943253df5e6adc6bc8746
diff --git a/tests/ref/lavfi/tile b/tests/ref/lavfi/tile
new file mode 100644
index 0000000..472d32c
--- /dev/null
+++ b/tests/ref/lavfi/tile
@@ -0,0 +1 @@
+tile                e36d067fb3e6e7b96522b7b0124f3850
diff --git a/tests/ref/lavfi/tinterlace_merge b/tests/ref/lavfi/tinterlace_merge
new file mode 100644
index 0000000..300713f
--- /dev/null
+++ b/tests/ref/lavfi/tinterlace_merge
@@ -0,0 +1,10 @@
+gray                c996e583bbc5a6f380463142eb77b7c6
+yuv410p             c9bad1317b496071d6d895238638e07d
+yuv420p             9794d11e59ec7bcdf9e30a433e4137b1
+yuv422p             e852e61e455db8ee3981ea942d510b0f
+yuv444p             a38a3f65d2f358cde5e9547c897cfcd5
+yuva420p            c1dc15d6ee78587d9f825acd795673d7
+yuvj420p            3ee7014727ee64b45292a4f15ba028d8
+yuvj422p            4f990d5473f15571276adb5770b3b773
+yuvj440p            9a005e8b8431aaa762fde8d942fd11a9
+yuvj444p            e29bf9f42e3a3632e09df529979e0040
diff --git a/tests/ref/lavfi/tinterlace_pad b/tests/ref/lavfi/tinterlace_pad
new file mode 100644
index 0000000..722ac85
--- /dev/null
+++ b/tests/ref/lavfi/tinterlace_pad
@@ -0,0 +1,10 @@
+gray                25a7d1ccf1a06c1a8a0520c1e6cb30ff
+yuv410p             17163d1b4f21d894598fc62e6aeb8141
+yuv420p             f8bbae33295741c1c17d33ff8ee16f7f
+yuv422p             4fa67d1580d3453942bb0950c5784f6e
+yuv444p             f0558305fb7ca65b5b86d3ee88c4201e
+yuva420p            7c76c0ca03a62275d25e8140c68da2b9
+yuvj420p            b5b7baf11946a2265fc56e48be5b0436
+yuvj422p            2e70ab700851d12a773f926bb1785235
+yuvj440p            93319f9c8a02ee793966fae40f7e42fd
+yuvj444p            81a124fffe0214bee5205c90ae0dd201
diff --git a/tests/ref/lavfi/transpose b/tests/ref/lavfi/transpose
new file mode 100644
index 0000000..1785e3a
--- /dev/null
+++ b/tests/ref/lavfi/transpose
@@ -0,0 +1 @@
+transpose           75d71957db820f657ccc46c14da6c8e9
diff --git a/tests/ref/lavfi/unsharp b/tests/ref/lavfi/unsharp
new file mode 100644
index 0000000..ad064ae
--- /dev/null
+++ b/tests/ref/lavfi/unsharp
@@ -0,0 +1 @@
+unsharp             7d72d2ab7b7f60159c822a097e01068b
diff --git a/tests/ref/lavfi/vflip b/tests/ref/lavfi/vflip
index 66b8732..ee49247 100644
--- a/tests/ref/lavfi/vflip
+++ b/tests/ref/lavfi/vflip
@@ -1 +1 @@
-vflip               2e6d6062e8cad37fb3ab2c433b55f382
+vflip               c59b35b82b5a195128736021913b35a4
diff --git a/tests/ref/lavfi/vflip_crop b/tests/ref/lavfi/vflip_crop
index 6bb832f..43c944a 100644
--- a/tests/ref/lavfi/vflip_crop
+++ b/tests/ref/lavfi/vflip_crop
@@ -1 +1 @@
-vflip_crop          72ee0d0dfc8af0cd94a466760313654d
+vflip_crop          cd56578bb7e89ca0853467dfecab244b
diff --git a/tests/ref/lavfi/vflip_vflip b/tests/ref/lavfi/vflip_vflip
index b719745..f401fc7 100644
--- a/tests/ref/lavfi/vflip_vflip
+++ b/tests/ref/lavfi/vflip_vflip
@@ -1 +1 @@
-vflip_vflip         eba2f135a08829387e2f698ff72a2939
+vflip_vflip         61fffd2d8425759a33ae07e718d0242d
diff --git a/tests/ref/seek/dnxhd_1080i_mov b/tests/ref/seek/dnxhd_1080i_mov
index 6c41d67..a5f0ce9 100644
--- a/tests/ref/seek/dnxhd_1080i_mov
+++ b/tests/ref/seek/dnxhd_1080i_mov
@@ -3,41 +3,41 @@
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size:606208
 ret: 0         st:-1 flags:1  ts: 1.894167
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:2424868 size:606208
-ret:-1         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1  ts:-0.320000
+ret:-1         st: 0 flags:0  ts: 0.788359
+ret: 0         st: 0 flags:1  ts:-0.317500
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size:606208
 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: 0.160000 pts: 0.160000 pos:2424868 size:606208
-ret:-1         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1  ts:-0.760000
+ret:-1         st: 0 flags:0  ts: 0.365000
+ret: 0         st: 0 flags:1  ts:-0.740859
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size:606208
 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.160000 pts: 0.160000 pos:2424868 size:606208
-ret: 0         st: 0 flags:0  ts:-0.040000
+ret: 0         st: 0 flags:0  ts:-0.058359
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size:606208
-ret: 0         st: 0 flags:1  ts: 2.840000
+ret: 0         st: 0 flags:1  ts: 2.835859
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:2424868 size:606208
 ret:-1         st:-1 flags:0  ts: 1.730004
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:2424868 size:606208
-ret: 0         st: 0 flags:0  ts:-0.480000
+ret: 0         st: 0 flags:0  ts:-0.481641
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size:606208
-ret: 0         st: 0 flags:1  ts: 2.400000
+ret: 0         st: 0 flags:1  ts: 2.412500
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:2424868 size:606208
 ret:-1         st:-1 flags:0  ts: 1.306672
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:2424868 size:606208
-ret: 0         st: 0 flags:0  ts:-0.920000
+ret: 0         st: 0 flags:0  ts:-0.905000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size:606208
-ret: 0         st: 0 flags:1  ts: 2.000000
+ret: 0         st: 0 flags:1  ts: 1.989141
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:2424868 size:606208
 ret:-1         st:-1 flags:0  ts: 0.883340
 ret: 0         st:-1 flags:1  ts:-0.222493
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size:606208
-ret:-1         st: 0 flags:0  ts: 2.680000
-ret: 0         st: 0 flags:1  ts: 1.560000
+ret:-1         st: 0 flags:0  ts: 2.671641
+ret: 0         st: 0 flags:1  ts: 1.565859
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:2424868 size:606208
 ret:-1         st:-1 flags:0  ts: 0.460008
 ret: 0         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/dnxhd_720p_dnxhd b/tests/ref/seek/dnxhd_720p_dnxhd
index b6398b6..b57f07d 100644
--- a/tests/ref/seek/dnxhd_720p_dnxhd
+++ b/tests/ref/seek/dnxhd_720p_dnxhd
@@ -3,38 +3,38 @@
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:458752
 ret: 0         st:-1 flags:1  ts: 1.894167
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:1835008 size:458752
-ret:-1         st: 0 flags:0  ts: 0.800000
-ret:-1         st: 0 flags:1  ts:-0.320000
+ret:-1         st: 0 flags:0  ts: 0.788334
+ret:-1         st: 0 flags:1  ts:-0.317499
 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: 0.160000 pts: 0.160000 pos:1835008 size:458752
-ret:-1         st: 0 flags:0  ts: 0.360000
-ret:-1         st: 0 flags:1  ts:-0.760000
+ret:-1         st: 0 flags:0  ts: 0.365002
+ret:-1         st: 0 flags:1  ts:-0.740831
 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.160000 pts: 0.160000 pos:1835008 size:458752
-ret: 0         st: 0 flags:0  ts:-0.040000
+ret: 0         st: 0 flags:0  ts:-0.058330
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:458752
-ret: 0         st: 0 flags:1  ts: 2.840000
+ret: 0         st: 0 flags:1  ts: 2.835837
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:1835008 size:458752
 ret:-1         st:-1 flags:0  ts: 1.730004
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:1835008 size:458752
-ret: 0         st: 0 flags:0  ts:-0.480000
+ret: 0         st: 0 flags:0  ts:-0.481662
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:458752
-ret: 0         st: 0 flags:1  ts: 2.400000
+ret: 0         st: 0 flags:1  ts: 2.412505
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:1835008 size:458752
 ret:-1         st:-1 flags:0  ts: 1.306672
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:1835008 size:458752
-ret: 0         st: 0 flags:0  ts:-0.920000
+ret: 0         st: 0 flags:0  ts:-0.904994
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:458752
-ret: 0         st: 0 flags:1  ts: 2.000000
+ret: 0         st: 0 flags:1  ts: 1.989173
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:1835008 size:458752
 ret:-1         st:-1 flags:0  ts: 0.883340
 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:-1         st: 0 flags:0  ts: 2.671674
+ret: 0         st: 0 flags:1  ts: 1.565841
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:1835008 size:458752
 ret:-1         st:-1 flags:0  ts: 0.460008
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/dnxhd_720p_rd_dnxhd b/tests/ref/seek/dnxhd_720p_rd_dnxhd
index b6398b6..b57f07d 100644
--- a/tests/ref/seek/dnxhd_720p_rd_dnxhd
+++ b/tests/ref/seek/dnxhd_720p_rd_dnxhd
@@ -3,38 +3,38 @@
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:458752
 ret: 0         st:-1 flags:1  ts: 1.894167
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:1835008 size:458752
-ret:-1         st: 0 flags:0  ts: 0.800000
-ret:-1         st: 0 flags:1  ts:-0.320000
+ret:-1         st: 0 flags:0  ts: 0.788334
+ret:-1         st: 0 flags:1  ts:-0.317499
 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: 0.160000 pts: 0.160000 pos:1835008 size:458752
-ret:-1         st: 0 flags:0  ts: 0.360000
-ret:-1         st: 0 flags:1  ts:-0.760000
+ret:-1         st: 0 flags:0  ts: 0.365002
+ret:-1         st: 0 flags:1  ts:-0.740831
 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.160000 pts: 0.160000 pos:1835008 size:458752
-ret: 0         st: 0 flags:0  ts:-0.040000
+ret: 0         st: 0 flags:0  ts:-0.058330
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:458752
-ret: 0         st: 0 flags:1  ts: 2.840000
+ret: 0         st: 0 flags:1  ts: 2.835837
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:1835008 size:458752
 ret:-1         st:-1 flags:0  ts: 1.730004
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:1835008 size:458752
-ret: 0         st: 0 flags:0  ts:-0.480000
+ret: 0         st: 0 flags:0  ts:-0.481662
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:458752
-ret: 0         st: 0 flags:1  ts: 2.400000
+ret: 0         st: 0 flags:1  ts: 2.412505
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:1835008 size:458752
 ret:-1         st:-1 flags:0  ts: 1.306672
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:1835008 size:458752
-ret: 0         st: 0 flags:0  ts:-0.920000
+ret: 0         st: 0 flags:0  ts:-0.904994
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:458752
-ret: 0         st: 0 flags:1  ts: 2.000000
+ret: 0         st: 0 flags:1  ts: 1.989173
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:1835008 size:458752
 ret:-1         st:-1 flags:0  ts: 0.883340
 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:-1         st: 0 flags:0  ts: 2.671674
+ret: 0         st: 0 flags:1  ts: 1.565841
 ret: 0         st: 0 flags:1 dts: 0.160000 pts: 0.160000 pos:1835008 size:458752
 ret:-1         st:-1 flags:0  ts: 0.460008
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/dv_411_dv b/tests/ref/seek/dv_411_dv
index baaeefb..d318794 100644
--- a/tests/ref/seek/dv_411_dv
+++ b/tests/ref/seek/dv_411_dv
@@ -1,53 +1,53 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.880000 pts: 1.880000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.880000 pts: 1.880000 pos:6768000 size:144000
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos:2880000 size:144000
 ret: 0         st: 0 flags:1  ts:-0.320000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st:-1 flags:0  ts: 2.576668
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:7056000 size:144000
 ret: 0         st:-1 flags:1  ts: 1.470835
-ret: 0         st: 0 flags:1 dts: 1.480000 pts: 1.480000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.480000 pts: 1.480000 pos:5328000 size:144000
 ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:1296000 size:144000
 ret: 0         st: 0 flags:1  ts:-0.760000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st:-1 flags:0  ts: 2.153336
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:7056000 size:144000
 ret: 0         st:-1 flags:1  ts: 1.047503
-ret: 0         st: 0 flags:1 dts: 1.040000 pts: 1.040000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.040000 pts: 1.040000 pos:3744000 size:144000
 ret: 0         st: 0 flags:0  ts:-0.040000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:7056000 size:144000
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.720000 pts: 1.720000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.720000 pts: 1.720000 pos:6192000 size:144000
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.640000 pts: 0.640000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.640000 pts: 0.640000 pos:2304000 size:144000
 ret: 0         st: 0 flags:0  ts:-0.480000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:7056000 size:144000
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.320000 pts: 1.320000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.320000 pts: 1.320000 pos:4752000 size:144000
 ret: 0         st:-1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos: 720000 size:144000
 ret: 0         st: 0 flags:0  ts:-0.920000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:7056000 size:144000
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos:3168000 size:144000
 ret: 0         st:-1 flags:1  ts:-0.222493
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st: 0 flags:0  ts: 2.680000
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:7056000 size:144000
 ret: 0         st: 0 flags:1  ts: 1.560000
-ret: 0         st: 0 flags:1 dts: 1.560000 pts: 1.560000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.560000 pts: 1.560000 pos:5616000 size:144000
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:1728000 size:144000
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
diff --git a/tests/ref/seek/dv_50_dv b/tests/ref/seek/dv_50_dv
index 1f07e5b7..fae6d1b 100644
--- a/tests/ref/seek/dv_50_dv
+++ b/tests/ref/seek/dv_50_dv
@@ -1,53 +1,53 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:288000
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:288000
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.880000 pts: 1.880000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 1.880000 pts: 1.880000 pos:13536000 size:288000
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos:5760000 size:288000
 ret: 0         st: 0 flags:1  ts:-0.320000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:288000
 ret: 0         st:-1 flags:0  ts: 2.576668
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:14112000 size:288000
 ret: 0         st:-1 flags:1  ts: 1.470835
-ret: 0         st: 0 flags:1 dts: 1.480000 pts: 1.480000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 1.480000 pts: 1.480000 pos:10656000 size:288000
 ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:2592000 size:288000
 ret: 0         st: 0 flags:1  ts:-0.760000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:288000
 ret: 0         st:-1 flags:0  ts: 2.153336
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:14112000 size:288000
 ret: 0         st:-1 flags:1  ts: 1.047503
-ret: 0         st: 0 flags:1 dts: 1.040000 pts: 1.040000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 1.040000 pts: 1.040000 pos:7488000 size:288000
 ret: 0         st: 0 flags:0  ts:-0.040000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:288000
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:14112000 size:288000
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.720000 pts: 1.720000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 1.720000 pts: 1.720000 pos:12384000 size:288000
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.640000 pts: 0.640000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 0.640000 pts: 0.640000 pos:4608000 size:288000
 ret: 0         st: 0 flags:0  ts:-0.480000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:288000
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:14112000 size:288000
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.320000 pts: 1.320000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 1.320000 pts: 1.320000 pos:9504000 size:288000
 ret: 0         st:-1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:1440000 size:288000
 ret: 0         st: 0 flags:0  ts:-0.920000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:288000
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:14112000 size:288000
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos:6336000 size:288000
 ret: 0         st:-1 flags:1  ts:-0.222493
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:288000
 ret: 0         st: 0 flags:0  ts: 2.680000
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:14112000 size:288000
 ret: 0         st: 0 flags:1  ts: 1.560000
-ret: 0         st: 0 flags:1 dts: 1.560000 pts: 1.560000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 1.560000 pts: 1.560000 pos:11232000 size:288000
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:3456000 size:288000
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:288000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:288000
diff --git a/tests/ref/seek/dv_dv b/tests/ref/seek/dv_dv
index baaeefb..d318794 100644
--- a/tests/ref/seek/dv_dv
+++ b/tests/ref/seek/dv_dv
@@ -1,53 +1,53 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.880000 pts: 1.880000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.880000 pts: 1.880000 pos:6768000 size:144000
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos:2880000 size:144000
 ret: 0         st: 0 flags:1  ts:-0.320000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st:-1 flags:0  ts: 2.576668
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:7056000 size:144000
 ret: 0         st:-1 flags:1  ts: 1.470835
-ret: 0         st: 0 flags:1 dts: 1.480000 pts: 1.480000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.480000 pts: 1.480000 pos:5328000 size:144000
 ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:1296000 size:144000
 ret: 0         st: 0 flags:1  ts:-0.760000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st:-1 flags:0  ts: 2.153336
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:7056000 size:144000
 ret: 0         st:-1 flags:1  ts: 1.047503
-ret: 0         st: 0 flags:1 dts: 1.040000 pts: 1.040000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.040000 pts: 1.040000 pos:3744000 size:144000
 ret: 0         st: 0 flags:0  ts:-0.040000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:7056000 size:144000
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.720000 pts: 1.720000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.720000 pts: 1.720000 pos:6192000 size:144000
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.640000 pts: 0.640000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.640000 pts: 0.640000 pos:2304000 size:144000
 ret: 0         st: 0 flags:0  ts:-0.480000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:7056000 size:144000
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.320000 pts: 1.320000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.320000 pts: 1.320000 pos:4752000 size:144000
 ret: 0         st:-1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos: 720000 size:144000
 ret: 0         st: 0 flags:0  ts:-0.920000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:7056000 size:144000
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos:3168000 size:144000
 ret: 0         st:-1 flags:1  ts:-0.222493
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st: 0 flags:0  ts: 2.680000
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos:7056000 size:144000
 ret: 0         st: 0 flags:1  ts: 1.560000
-ret: 0         st: 0 flags:1 dts: 1.560000 pts: 1.560000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 1.560000 pts: 1.560000 pos:5616000 size:144000
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:1728000 size:144000
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
diff --git a/tests/ref/seek/flac_flac b/tests/ref/seek/flac_flac
index 15ab0d2..ab31891 100644
--- a/tests/ref/seek/flac_flac
+++ b/tests/ref/seek/flac_flac
@@ -1,49 +1,49 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8255 size:   614
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8256 size:   614
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8255 size:   614
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8256 size:   614
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.880816 pts: 1.880816 pos:  86741 size:  2191
+ret: 0         st: 0 flags:1 dts: 1.880816 pts: 1.880816 pos:  86742 size:  2191
 ret: 0         st: 0 flags:0  ts: 0.788345
-ret: 0         st: 0 flags:1 dts: 0.809796 pts: 0.809796 pos:  27365 size:   615
+ret: 0         st: 0 flags:1 dts: 0.809796 pts: 0.809796 pos:  27366 size:   615
 ret:-1         st: 0 flags:1  ts:-0.317506
 ret: 0         st:-1 flags:0  ts: 2.576668
-ret: 0         st: 0 flags:1 dts: 2.586122 pts: 2.586122 pos: 145605 size:  2384
+ret: 0         st: 0 flags:1 dts: 2.586122 pts: 2.586122 pos: 145606 size:  2384
 ret: 0         st:-1 flags:1  ts: 1.470835
-ret: 0         st: 0 flags:1 dts: 1.462857 pts: 1.462857 pos:  53387 size:  1851
+ret: 0         st: 0 flags:1 dts: 1.462857 pts: 1.462857 pos:  53388 size:  1851
 ret: 0         st: 0 flags:0  ts: 0.365011
-ret: 0         st: 0 flags:1 dts: 0.365714 pts: 0.365714 pos:  16889 size:   614
+ret: 0         st: 0 flags:1 dts: 0.365714 pts: 0.365714 pos:  16890 size:   614
 ret:-1         st: 0 flags:1  ts:-0.740839
 ret: 0         st:-1 flags:0  ts: 2.153336
-ret: 0         st: 0 flags:1 dts: 2.168163 pts: 2.168163 pos: 110530 size:  2143
+ret: 0         st: 0 flags:1 dts: 2.168163 pts: 2.168163 pos: 110531 size:  2143
 ret: 0         st:-1 flags:1  ts: 1.047503
-ret: 0         st: 0 flags:1 dts: 1.044898 pts: 1.044898 pos:  32879 size:   579
+ret: 0         st: 0 flags:1 dts: 1.044898 pts: 1.044898 pos:  32880 size:   579
 ret: 0         st: 0 flags:0  ts:-0.058322
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8255 size:   614
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8256 size:   614
 ret: 0         st: 0 flags:1  ts: 2.835828
-ret: 0         st: 0 flags:1 dts: 2.821224 pts: 2.821224 pos: 167111 size:  2391
+ret: 0         st: 0 flags:1 dts: 2.821224 pts: 2.821224 pos: 167112 size:  2391
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.750204 pts: 1.750204 pos:  75787 size:  2191
+ret: 0         st: 0 flags:1 dts: 1.750204 pts: 1.750204 pos:  75788 size:  2191
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.600816 pts: 0.600816 pos:  22445 size:   616
+ret: 0         st: 0 flags:1 dts: 0.600816 pts: 0.600816 pos:  22446 size:   616
 ret: 0         st: 0 flags:0  ts:-0.481655
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8255 size:   614
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8256 size:   614
 ret: 0         st: 0 flags:1  ts: 2.412494
-ret: 0         st: 0 flags:1 dts: 2.403265 pts: 2.403265 pos: 129792 size:  2138
+ret: 0         st: 0 flags:1 dts: 2.403265 pts: 2.403265 pos: 129793 size:  2138
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.332245 pts: 1.332245 pos:  44811 size:  1609
+ret: 0         st: 0 flags:1 dts: 1.332245 pts: 1.332245 pos:  44812 size:  1609
 ret: 0         st:-1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:1 dts: 0.182857 pts: 0.182857 pos:  12571 size:   628
+ret: 0         st: 0 flags:1 dts: 0.182857 pts: 0.182857 pos:  12572 size:   628
 ret: 0         st: 0 flags:0  ts:-0.904989
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8255 size:   614
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   8256 size:   614
 ret: 0         st: 0 flags:1  ts: 1.989184
-ret: 0         st: 0 flags:1 dts: 1.985306 pts: 1.985306 pos:  95507 size:  2169
+ret: 0         st: 0 flags:1 dts: 1.985306 pts: 1.985306 pos:  95508 size:  2169
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.888163 pts: 0.888163 pos:  29210 size:   620
+ret: 0         st: 0 flags:1 dts: 0.888163 pts: 0.888163 pos:  29211 size:   620
 ret:-1         st:-1 flags:1  ts:-0.222493
 ret: 0         st: 0 flags:0  ts: 2.671678
-ret: 0         st: 0 flags:1 dts: 2.690612 pts: 2.690612 pos: 155153 size:  2394
+ret: 0         st: 0 flags:1 dts: 2.690612 pts: 2.690612 pos: 155154 size:  2394
 ret: 0         st: 0 flags:1  ts: 1.565850
-ret: 0         st: 0 flags:1 dts: 1.541224 pts: 1.541224 pos:  59081 size:  1974
+ret: 0         st: 0 flags:1 dts: 1.541224 pts: 1.541224 pos:  59082 size:  1974
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.470204 pts: 0.470204 pos:  19352 size:   608
+ret: 0         st: 0 flags:1 dts: 0.470204 pts: 0.470204 pos:  19353 size:   608
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/flv_flv b/tests/ref/seek/flv_flv
index 6952a4e..d4aecda 100644
--- a/tests/ref/seek/flv_flv
+++ b/tests/ref/seek/flv_flv
@@ -18,15 +18,15 @@
 ret: 0         st: 0 flags:0  ts:-0.058000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    199 size: 10380
 ret: 0         st: 0 flags:1  ts: 2.836000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 117158 size: 12730
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 117177 size: 12730
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 117158 size: 12730
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 117177 size: 12730
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  25960 size: 10089
 ret: 0         st: 0 flags:0  ts:-0.482000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    199 size: 10380
 ret: 0         st: 0 flags:1  ts: 2.413000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 117158 size: 12730
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 117177 size: 12730
 ret: 0         st:-1 flags:0  ts: 1.306672
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83240 size: 12295
 ret: 0         st:-1 flags:1  ts: 0.200839
@@ -34,7 +34,7 @@
 ret: 0         st: 0 flags:0  ts:-0.905000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    199 size: 10380
 ret: 0         st: 0 flags:1  ts: 1.989000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 117158 size: 12730
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 117177 size: 12730
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  52585 size: 11127
 ret:-1         st:-1 flags:1  ts:-0.222493
diff --git a/tests/ref/seek/h261_avi b/tests/ref/seek/h261_avi
index d31364f..55ccf97 100644
--- a/tests/ref/seek/h261_avi
+++ b/tests/ref/seek/h261_avi
@@ -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:   5660 size:  9645
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 126514 size: 11377
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 126506 size: 11377
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  82072 size: 10322
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  82064 size: 10322
 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: 126514 size: 11377
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 126506 size: 11377
 ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  44678 size:  9404
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  44676 size:  9404
 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:  82072 size: 10322
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  82064 size: 10322
 ret: 0         st: 0 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9645
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 175882 size: 11707
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 175868 size: 11707
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 175882 size: 11707
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 175868 size: 11707
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  44678 size:  9404
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  44676 size:  9404
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9645
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 175882 size: 11707
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 175868 size: 11707
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 126514 size: 11377
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 126506 size: 11377
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9645
 ret: 0         st: 0 flags:0  ts:-0.920000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9645
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 175882 size: 11707
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 175868 size: 11707
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  82072 size: 10322
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  82064 size: 10322
 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: 126514 size: 11377
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 126506 size: 11377
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  44678 size:  9404
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  44676 size:  9404
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/h263_avi b/tests/ref/seek/h263_avi
index 8b1795c..c9f7908 100644
--- a/tests/ref/seek/h263_avi
+++ b/tests/ref/seek/h263_avi
@@ -18,15 +18,15 @@
 ret: 0         st: 0 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size: 10381
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 144558 size: 12731
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 144564 size: 12731
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 144558 size: 12731
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 144564 size: 12731
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  36450 size: 10090
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size: 10381
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 144558 size: 12731
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 144564 size: 12731
 ret: 0         st:-1 flags:0  ts: 1.306672
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 103714 size: 12296
 ret: 0         st:-1 flags:1  ts: 0.200839
@@ -34,7 +34,7 @@
 ret: 0         st: 0 flags:0  ts:-0.920000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size: 10381
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 144558 size: 12731
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 144564 size: 12731
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  66804 size: 11128
 ret:-1         st:-1 flags:1  ts:-0.222493
diff --git a/tests/ref/seek/h263p_avi b/tests/ref/seek/h263p_avi
index 51e6952..2756439 100644
--- a/tests/ref/seek/h263p_avi
+++ b/tests/ref/seek/h263p_avi
@@ -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:   5660 size: 36208
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 569938 size: 45151
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 569930 size: 45151
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 355988 size: 40907
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 355980 size: 40907
 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: 569938 size: 45151
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 569930 size: 45151
 ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 171054 size: 36515
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 171054 size: 36514
 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: 355988 size: 40907
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 355980 size: 40907
 ret: 0         st: 0 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size: 36208
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 804378 size: 46411
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 804370 size: 46411
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 804378 size: 46411
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 804370 size: 46411
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 171054 size: 36515
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 171054 size: 36514
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size: 36208
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 804378 size: 46411
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 804370 size: 46411
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 569938 size: 45151
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 569930 size: 45151
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size: 36208
 ret: 0         st: 0 flags:0  ts:-0.920000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size: 36208
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 804378 size: 46411
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 804370 size: 46411
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 355988 size: 40907
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 355980 size: 40907
 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: 569938 size: 45151
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 569930 size: 45151
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 171054 size: 36515
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 171054 size: 36514
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/lavf_asf b/tests/ref/seek/lavf_asf
index e1d6d32..9a14895 100644
--- a/tests/ref/seek/lavf_asf
+++ b/tests/ref/seek/lavf_asf
@@ -1,53 +1,53 @@
-ret: 0         st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos:    575 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    689 size:   208
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 1 flags:1 dts: 0.459000 pts: 0.459000 pos: 147775 size:   209
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    689 size:   208
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 1 flags:1 dts: 0.930000 pts: 0.930000 pos: 301375 size:   209
+ret: 0         st: 1 flags:1 dts: 0.470000 pts: 0.470000 pos: 147889 size:   209
 ret: 0         st: 0 flags:0  ts: 0.788000
-ret: 0         st: 1 flags:1 dts: 0.930000 pts: 0.930000 pos: 301375 size:   209
+ret: 0         st: 1 flags:1 dts: 0.470000 pts: 0.470000 pos: 147889 size:   209
 ret: 0         st: 0 flags:1  ts:-0.317000
-ret: 0         st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos:    575 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    689 size:   208
 ret: 0         st: 1 flags:0  ts: 2.577000
-ret: 0         st: 1 flags:1 dts: 0.982000 pts: 0.982000 pos: 330175 size:   209
+ret: 0         st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 330289 size:   209
 ret: 0         st: 1 flags:1  ts: 1.471000
-ret: 0         st: 1 flags:1 dts: 0.982000 pts: 0.982000 pos: 330175 size:   209
+ret: 0         st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 330289 size:   209
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 1 flags:1 dts: 0.459000 pts: 0.459000 pos: 147775 size:   209
+ret: 0         st: 1 flags:1 dts: 0.470000 pts: 0.470000 pos: 147889 size:   209
 ret: 0         st:-1 flags:1  ts:-0.740831
-ret: 0         st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos:    575 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    689 size:   208
 ret: 0         st: 0 flags:0  ts: 2.153000
-ret: 0         st: 1 flags:1 dts: 0.930000 pts: 0.930000 pos: 301375 size:   209
+ret: 0         st: 1 flags:1 dts: 0.941000 pts: 0.941000 pos: 301489 size:   209
 ret: 0         st: 0 flags:1  ts: 1.048000
-ret: 0         st: 1 flags:1 dts: 0.930000 pts: 0.930000 pos: 301375 size:   209
+ret: 0         st: 1 flags:1 dts: 0.941000 pts: 0.941000 pos: 301489 size:   209
 ret: 0         st: 1 flags:0  ts:-0.058000
-ret: 0         st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos:    575 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    689 size:   208
 ret: 0         st: 1 flags:1  ts: 2.836000
-ret: 0         st: 1 flags:1 dts: 0.982000 pts: 0.982000 pos: 330175 size:   209
+ret: 0         st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 330289 size:   209
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 1 flags:1 dts: 0.930000 pts: 0.930000 pos: 301375 size:   209
+ret: 0         st: 1 flags:1 dts: 0.941000 pts: 0.941000 pos: 301489 size:   209
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 1 flags:1 dts: 0.459000 pts: 0.459000 pos: 147775 size:   209
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    689 size:   208
 ret: 0         st: 0 flags:0  ts:-0.482000
-ret: 0         st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos:    575 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    689 size:   208
 ret: 0         st: 0 flags:1  ts: 2.413000
-ret: 0         st: 1 flags:1 dts: 0.930000 pts: 0.930000 pos: 301375 size:   209
+ret: 0         st: 1 flags:1 dts: 0.941000 pts: 0.941000 pos: 301489 size:   209
 ret: 0         st: 1 flags:0  ts: 1.307000
-ret: 0         st: 1 flags:1 dts: 0.982000 pts: 0.982000 pos: 330175 size:   209
+ret: 0         st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 330289 size:   209
 ret: 0         st: 1 flags:1  ts: 0.201000
-ret: 0         st: 1 flags:1 dts: 0.198000 pts: 0.198000 pos:  74175 size:   209
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    689 size:   208
 ret: 0         st:-1 flags:0  ts:-0.904994
-ret: 0         st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos:    575 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    689 size:   208
 ret: 0         st:-1 flags:1  ts: 1.989173
-ret: 0         st: 1 flags:1 dts: 0.930000 pts: 0.930000 pos: 301375 size:   209
+ret: 0         st: 1 flags:1 dts: 0.941000 pts: 0.941000 pos: 301489 size:   209
 ret: 0         st: 0 flags:0  ts: 0.883000
-ret: 0         st: 1 flags:1 dts: 0.930000 pts: 0.930000 pos: 301375 size:   209
+ret: 0         st: 1 flags:1 dts: 0.470000 pts: 0.470000 pos: 147889 size:   209
 ret: 0         st: 0 flags:1  ts:-0.222000
-ret: 0         st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos:    575 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    689 size:   208
 ret: 0         st: 1 flags:0  ts: 2.672000
-ret: 0         st: 1 flags:1 dts: 0.982000 pts: 0.982000 pos: 330175 size:   209
+ret: 0         st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 330289 size:   209
 ret: 0         st: 1 flags:1  ts: 1.566000
-ret: 0         st: 1 flags:1 dts: 0.982000 pts: 0.982000 pos: 330175 size:   209
+ret: 0         st: 1 flags:1 dts: 0.993000 pts: 0.993000 pos: 330289 size:   209
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 1 flags:1 dts: 0.459000 pts: 0.459000 pos: 147775 size:   209
+ret: 0         st: 1 flags:1 dts: 0.470000 pts: 0.470000 pos: 147889 size:   209
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos:    575 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    689 size:   208
diff --git a/tests/ref/seek/lavf_avi b/tests/ref/seek/lavf_avi
index 2e09ad1..7725134 100644
--- a/tests/ref/seek/lavf_avi
+++ b/tests/ref/seek/lavf_avi
@@ -1,44 +1,44 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   9908 size: 27867
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   9926 size: 27867
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   9908 size: 27867
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   9926 size: 27867
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 301466 size: 27864
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 301474 size: 27864
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 301466 size: 27864
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 301474 size: 27864
 ret:-1         st: 0 flags:1  ts:-0.320000
 ret:-1         st: 1 flags:0  ts: 2.586122
 ret: 0         st: 1 flags:1  ts: 1.462857
-ret: 0         st: 1 flags:1 dts: 0.992653 pts: 0.992653 pos: 329556 size:   209
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 301474 size: 27864
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 156166 size: 27955
+ret: 0         st: 1 flags:1 dts: 0.470204 pts: 0.470204 pos: 155956 size:   209
 ret:-1         st:-1 flags:1  ts:-0.740831
 ret:-1         st: 0 flags:0  ts: 2.160000
 ret: 0         st: 0 flags:1  ts: 1.040000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 301466 size: 27864
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 301474 size: 27864
 ret: 0         st: 1 flags:0  ts:-0.052245
-ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:  37784 size:   208
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   9926 size: 27867
 ret: 0         st: 1 flags:1  ts: 2.847347
-ret: 0         st: 1 flags:1 dts: 0.992653 pts: 0.992653 pos: 329556 size:   209
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 301474 size: 27864
 ret:-1         st:-1 flags:0  ts: 1.730004
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 156166 size: 27955
+ret: 0         st: 1 flags:1 dts: 0.470204 pts: 0.470204 pos: 155956 size:   209
 ret: 0         st: 0 flags:0  ts:-0.480000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   9908 size: 27867
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   9926 size: 27867
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 301466 size: 27864
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 301474 size: 27864
 ret:-1         st: 1 flags:0  ts: 1.306122
 ret: 0         st: 1 flags:1  ts: 0.208980
-ret: 0         st: 1 flags:1 dts: 0.208980 pts: 0.208980 pos:  92800 size:   209
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   9926 size: 27867
 ret: 0         st:-1 flags:0  ts:-0.904994
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   9908 size: 27867
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   9926 size: 27867
 ret: 0         st:-1 flags:1  ts: 1.989173
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 301466 size: 27864
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 301474 size: 27864
 ret: 0         st: 0 flags:0  ts: 0.880000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 301466 size: 27864
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 301474 size: 27864
 ret:-1         st: 0 flags:1  ts:-0.240000
 ret:-1         st: 1 flags:0  ts: 2.664490
 ret: 0         st: 1 flags:1  ts: 1.567347
-ret: 0         st: 1 flags:1 dts: 0.992653 pts: 0.992653 pos: 329556 size:   209
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 301474 size: 27864
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 156166 size: 27955
+ret: 0         st: 1 flags:1 dts: 0.470204 pts: 0.470204 pos: 155956 size:   209
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/lavf_dv b/tests/ref/seek/lavf_dv
index 3c49749..0000ff5 100644
--- a/tests/ref/seek/lavf_dv
+++ b/tests/ref/seek/lavf_dv
@@ -1,53 +1,53 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos:2880000 size:144000
 ret: 0         st: 0 flags:1  ts:-0.320000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st: 1 flags:0  ts: 2.576667
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000
 ret: 0         st: 1 flags:1  ts: 1.470833
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:1296000 size:144000
 ret: 0         st:-1 flags:1  ts:-0.740831
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st: 0 flags:0  ts: 2.160000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000
 ret: 0         st: 0 flags:1  ts: 1.040000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000
 ret: 0         st: 1 flags:0  ts:-0.058333
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st: 1 flags:1  ts: 2.835833
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.640000 pts: 0.640000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.640000 pts: 0.640000 pos:2304000 size:144000
 ret: 0         st: 0 flags:0  ts:-0.480000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000
 ret: 0         st: 1 flags:0  ts: 1.306667
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000
 ret: 0         st: 1 flags:1  ts: 0.200833
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000
 ret: 0         st:-1 flags:0  ts:-0.904994
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st:-1 flags:1  ts: 1.989173
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000
 ret: 0         st: 0 flags:0  ts: 0.880000
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos:3168000 size:144000
 ret: 0         st: 0 flags:1  ts:-0.240000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
 ret: 0         st: 1 flags:0  ts: 2.671667
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000
 ret: 0         st: 1 flags:1  ts: 1.565833
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:3456000 size:144000
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:1728000 size:144000
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:144000
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:      0 size:144000
diff --git a/tests/ref/seek/lavf_ffm b/tests/ref/seek/lavf_ffm
index 2597220..eceed1a 100644
--- a/tests/ref/seek/lavf_ffm
+++ b/tests/ref/seek/lavf_ffm
@@ -1,26 +1,26 @@
-ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24664
+ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24663
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24664
+ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24663
 ret: 0         st:-1 flags:1  ts: 1.894167
 ret: 0         st: 1 flags:1 dts: 0.929501 pts: 0.929501 pos: 376832 size:   209
 ret: 0         st: 0 flags:0  ts: 0.788334
-ret: 0         st: 1 flags:1 dts: 0.772766 pts: 0.772766 pos: 315392 size:   209
+ret: 0         st: 1 flags:1 dts: 0.825011 pts: 0.825011 pos: 327680 size:   209
 ret: 0         st: 0 flags:1  ts:-0.317499
-ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24664
+ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24663
 ret: 0         st: 1 flags:0  ts: 2.576668
 ret: 0         st: 1 flags:1 dts: 0.929501 pts: 0.929501 pos: 376832 size:   209
 ret: 0         st: 1 flags:1  ts: 1.470835
 ret: 0         st: 1 flags:1 dts: 0.929501 pts: 0.929501 pos: 376832 size:   209
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 1 flags:1 dts: 0.328685 pts: 0.328685 pos: 155648 size:   209
+ret: 0         st: 1 flags:1 dts: 0.380930 pts: 0.380930 pos: 163840 size:   209
 ret: 0         st:-1 flags:1  ts:-0.740831
-ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24664
+ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24663
 ret: 0         st: 0 flags:0  ts: 2.153336
 ret: 0         st: 1 flags:1 dts: 0.929501 pts: 0.929501 pos: 376832 size:   209
 ret: 0         st: 0 flags:1  ts: 1.047503
 ret: 0         st: 1 flags:1 dts: 0.929501 pts: 0.929501 pos: 376832 size:   209
 ret: 0         st: 1 flags:0  ts:-0.058330
-ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24664
+ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24663
 ret: 0         st: 1 flags:1  ts: 2.835837
 ret: 0         st: 1 flags:1 dts: 0.929501 pts: 0.929501 pos: 376832 size:   209
 ret: 0         st:-1 flags:0  ts: 1.730004
@@ -28,7 +28,7 @@
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 1 flags:1 dts: 0.642154 pts: 0.642154 pos: 274432 size:   209
 ret: 0         st: 0 flags:0  ts:-0.481662
-ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24664
+ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24663
 ret: 0         st: 0 flags:1  ts: 2.412505
 ret: 0         st: 1 flags:1 dts: 0.929501 pts: 0.929501 pos: 376832 size:   209
 ret: 0         st: 1 flags:0  ts: 1.306672
@@ -36,18 +36,18 @@
 ret: 0         st: 1 flags:1  ts: 0.200839
 ret: 0         st: 1 flags:1 dts: 0.224195 pts: 0.224195 pos: 114688 size:   209
 ret: 0         st:-1 flags:0  ts:-0.904994
-ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24664
+ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24663
 ret: 0         st:-1 flags:1  ts: 1.989173
 ret: 0         st: 1 flags:1 dts: 0.929501 pts: 0.929501 pos: 376832 size:   209
 ret: 0         st: 0 flags:0  ts: 0.883340
-ret: 0         st: 1 flags:1 dts: 0.877256 pts: 0.877256 pos: 339968 size:   209
+ret: 0         st: 0 flags:0 dts: 0.880000 pts: 0.920000 pos: 339968 size: 12307
 ret: 0         st: 0 flags:1  ts:-0.222493
-ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24664
+ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24663
 ret: 0         st: 1 flags:0  ts: 2.671674
 ret: 0         st: 1 flags:1 dts: 0.929501 pts: 0.929501 pos: 376832 size:   209
 ret: 0         st: 1 flags:1  ts: 1.565841
 ret: 0         st: 1 flags:1 dts: 0.929501 pts: 0.929501 pos: 376832 size:   209
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 1 flags:1 dts: 0.459297 pts: 0.459297 pos: 204800 size:   209
+ret: 0         st: 1 flags:1 dts: 0.485420 pts: 0.485420 pos: 221184 size:   209
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24664
+ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   8192 size: 24663
diff --git a/tests/ref/seek/lavf_flv b/tests/ref/seek/lavf_flv
index 2e7a0bc..c12da84 100644
--- a/tests/ref/seek/lavf_flv
+++ b/tests/ref/seek/lavf_flv
@@ -1,44 +1,44 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    199 size: 31074
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    217 size: 31074
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    199 size: 31074
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    217 size: 31074
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298403 size: 31134
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298416 size: 31134
 ret: 0         st: 0 flags:0  ts: 0.788000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298403 size: 31134
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298416 size: 31134
 ret:-1         st: 0 flags:1  ts:-0.317000
 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: 0.960000 pts: 0.960000 pos: 298403 size: 31134
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298416 size: 31134
 ret: 0         st: 0 flags:0  ts: 0.365000
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 149441 size: 31125
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 149456 size: 31125
 ret:-1         st: 0 flags:1  ts:-0.741000
 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: 298403 size: 31134
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298416 size: 31134
 ret: 0         st: 0 flags:0  ts:-0.058000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    199 size: 31074
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    217 size: 31074
 ret: 0         st: 0 flags:1  ts: 2.836000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298403 size: 31134
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298416 size: 31134
 ret:-1         st:-1 flags:0  ts: 1.730004
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 149441 size: 31125
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 149456 size: 31125
 ret: 0         st: 0 flags:0  ts:-0.482000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    199 size: 31074
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    217 size: 31074
 ret: 0         st: 0 flags:1  ts: 2.413000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298403 size: 31134
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298416 size: 31134
 ret:-1         st:-1 flags:0  ts: 1.306672
 ret: 0         st:-1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    199 size: 31074
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    217 size: 31074
 ret: 0         st: 0 flags:0  ts:-0.905000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    199 size: 31074
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    217 size: 31074
 ret: 0         st: 0 flags:1  ts: 1.989000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298403 size: 31134
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298416 size: 31134
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298403 size: 31134
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298416 size: 31134
 ret:-1         st:-1 flags:1  ts:-0.222493
 ret:-1         st: 0 flags:0  ts: 2.672000
 ret: 0         st: 0 flags:1  ts: 1.566000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298403 size: 31134
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 298416 size: 31134
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 149441 size: 31125
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 149456 size: 31125
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/lavf_gxf b/tests/ref/seek/lavf_gxf
index bc7ff3b..7162462 100644
--- a/tests/ref/seek/lavf_gxf
+++ b/tests/ref/seek/lavf_gxf
@@ -2,52 +2,52 @@
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:   5024 size: 65536
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741640 size: 54736
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741124 size: 54736
 ret: 0         st: 0 flags:0  ts: 0.780000
-ret: 0         st: 0 flags:0 dts: 0.800000 pts: NOPTS    pos: 653328 size: 22148
+ret: 0         st: 0 flags:0 dts: 0.800000 pts: NOPTS    pos: 653420 size: 22124
 ret: 0         st: 0 flags:1  ts:-0.320000
 ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:   5024 size: 65536
 ret: 0         st: 1 flags:0  ts: 2.580000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741640 size: 54736
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741124 size: 54736
 ret: 0         st: 1 flags:1  ts: 1.480000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741640 size: 54736
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741124 size: 54736
 ret: 0         st: 2 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:0 dts: 0.360000 pts: NOPTS    pos: 302676 size: 25108
+ret: 0         st: 0 flags:0 dts: 0.360000 pts: NOPTS    pos: 302672 size: 25116
 ret: 0         st: 2 flags:1  ts:-0.740000
 ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:   5024 size: 65536
 ret: 0         st:-1 flags:0  ts: 2.153336
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741640 size: 54736
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741124 size: 54736
 ret: 0         st:-1 flags:1  ts: 1.047503
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741640 size: 54736
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741124 size: 54736
 ret: 0         st: 0 flags:0  ts:-0.060000
 ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:   5024 size: 65536
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741640 size: 54736
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741124 size: 54736
 ret: 0         st: 1 flags:0  ts: 1.740000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741640 size: 54736
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741124 size: 54736
 ret: 0         st: 1 flags:1  ts: 0.620000
-ret: 0         st: 0 flags:0 dts: 0.640000 pts: NOPTS    pos: 497156 size: 21596
+ret: 0         st: 0 flags:0 dts: 0.640000 pts: NOPTS    pos: 497196 size: 21612
 ret: 0         st: 2 flags:0  ts:-0.480000
 ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:   5024 size: 65536
 ret: 0         st: 2 flags:1  ts: 2.420000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741640 size: 54736
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741124 size: 54736
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741640 size: 54736
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741124 size: 54736
 ret: 0         st:-1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:0 dts: 0.200000 pts: NOPTS    pos: 209504 size: 22968
+ret: 0         st: 0 flags:0 dts: 0.200000 pts: NOPTS    pos: 209504 size: 22964
 ret: 0         st: 0 flags:0  ts:-0.900000
 ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:   5024 size: 65536
 ret: 0         st: 0 flags:1  ts: 1.980000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741640 size: 54736
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741124 size: 54736
 ret: 0         st: 1 flags:0  ts: 0.880000
-ret: 0         st: 0 flags:0 dts: 0.880000 pts: NOPTS    pos: 696044 size: 22484
+ret: 0         st: 0 flags:0 dts: 0.880000 pts: NOPTS    pos: 696160 size: 21820
 ret: 0         st: 1 flags:1  ts:-0.220000
 ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:   5024 size: 65536
 ret: 0         st: 2 flags:0  ts: 2.680000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741640 size: 54736
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741124 size: 54736
 ret: 0         st: 2 flags:1  ts: 1.560000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741640 size: 54736
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos: 741124 size: 54736
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: NOPTS    pos: 370660 size: 54628
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: NOPTS    pos: 370700 size: 54628
 ret: 0         st:-1 flags:1  ts:-0.645825
 ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:   5024 size: 65536
diff --git a/tests/ref/seek/lavf_mkv b/tests/ref/seek/lavf_mkv
index e51e9c9..ece15a1 100644
--- a/tests/ref/seek/lavf_mkv
+++ b/tests/ref/seek/lavf_mkv
@@ -1,53 +1,48 @@
-ret: 0         st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos:    512 size:   208
+ret: 0         st: 1 flags:1 dts:-0.011000 pts:-0.011000 pos:    555 size:   208
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    512 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    555 size:   208
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 292150 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 292185 size: 27834
 ret: 0         st: 0 flags:0  ts: 0.788000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 292150 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 292185 size: 27834
 ret: 0         st: 0 flags:1  ts:-0.317000
-ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    512 size:   208
-ret: 0         st: 1 flags:0  ts: 2.577000
-ret:-EOF
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    555 size:   208
+ret:-1         st: 1 flags:0  ts: 2.577000
 ret: 0         st: 1 flags:1  ts: 1.471000
-ret: 0         st: 1 flags:1 dts: 0.982000 pts: 0.982000 pos: 319991 size:   209
+ret: 0         st: 1 flags:1 dts: 0.982000 pts: 0.982000 pos: 320026 size:   209
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146703 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146738 size: 27925
 ret: 0         st:-1 flags:1  ts:-0.740831
-ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    512 size:   208
-ret: 0         st: 0 flags:0  ts: 2.153000
-ret:-EOF
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    555 size:   208
+ret:-1         st: 0 flags:0  ts: 2.153000
 ret: 0         st: 0 flags:1  ts: 1.048000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 292150 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 292185 size: 27834
 ret: 0         st: 1 flags:0  ts:-0.058000
-ret: 0         st: 1 flags:1 dts: 0.015000 pts: 0.015000 pos:    512 size:   208
+ret: 0         st: 1 flags:1 dts: 0.015000 pts: 0.015000 pos:    555 size:   208
 ret: 0         st: 1 flags:1  ts: 2.836000
-ret: 0         st: 1 flags:1 dts: 0.982000 pts: 0.982000 pos: 319991 size:   209
-ret: 0         st:-1 flags:0  ts: 1.730004
-ret:-EOF
+ret: 0         st: 1 flags:1 dts: 0.982000 pts: 0.982000 pos: 320026 size:   209
+ret:-1         st:-1 flags:0  ts: 1.730004
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146703 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146738 size: 27925
 ret: 0         st: 0 flags:0  ts:-0.482000
-ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    512 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    555 size:   208
 ret: 0         st: 0 flags:1  ts: 2.413000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 292150 size: 27834
-ret: 0         st: 1 flags:0  ts: 1.307000
-ret:-EOF
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 292185 size: 27834
+ret:-1         st: 1 flags:0  ts: 1.307000
 ret: 0         st: 1 flags:1  ts: 0.201000
-ret: 0         st: 1 flags:1 dts: 0.015000 pts: 0.015000 pos:    512 size:   208
+ret: 0         st: 1 flags:1 dts: 0.015000 pts: 0.015000 pos:    555 size:   208
 ret: 0         st:-1 flags:0  ts:-0.904994
-ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    512 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    555 size:   208
 ret: 0         st:-1 flags:1  ts: 1.989173
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 292150 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 292185 size: 27834
 ret: 0         st: 0 flags:0  ts: 0.883000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 292150 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 292185 size: 27834
 ret: 0         st: 0 flags:1  ts:-0.222000
-ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    512 size:   208
-ret: 0         st: 1 flags:0  ts: 2.672000
-ret:-EOF
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    555 size:   208
+ret:-1         st: 1 flags:0  ts: 2.672000
 ret: 0         st: 1 flags:1  ts: 1.566000
-ret: 0         st: 1 flags:1 dts: 0.982000 pts: 0.982000 pos: 319991 size:   209
+ret: 0         st: 1 flags:1 dts: 0.982000 pts: 0.982000 pos: 320026 size:   209
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146703 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146738 size: 27925
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    512 size:   208
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    555 size:   208
diff --git a/tests/ref/seek/lavf_mmf b/tests/ref/seek/lavf_mmf
index 196d263..b7fd5f5 100644
--- a/tests/ref/seek/lavf_mmf
+++ b/tests/ref/seek/lavf_mmf
@@ -1,4 +1,4 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     -1 size:  4096
+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
diff --git a/tests/ref/seek/lavf_mov b/tests/ref/seek/lavf_mov
index 0091915..9563a0d 100644
--- a/tests/ref/seek/lavf_mov
+++ b/tests/ref/seek/lavf_mov
@@ -1,48 +1,48 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 325248 size:  1024
-ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 326272 size: 27834
-ret: 0         st: 0 flags:1  ts:-0.320000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 27837
+ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 326931 size:  1024
+ret: 0         st: 0 flags:0  ts: 0.788359
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 327955 size: 27834
+ret: 0         st: 0 flags:1  ts:-0.317500
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
 ret:-1         st: 1 flags:0  ts: 2.576667
 ret: 0         st: 1 flags:1  ts: 1.470839
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 326272 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 327955 size: 27834
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 163526 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 165209 size: 27925
 ret: 0         st:-1 flags:1  ts:-0.740831
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 27837
-ret:-1         st: 0 flags:0  ts: 2.160000
-ret: 0         st: 0 flags:1  ts: 1.040000
-ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 325248 size:  1024
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
+ret:-1         st: 0 flags:0  ts: 2.153359
+ret: 0         st: 0 flags:1  ts: 1.047500
+ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 326931 size:  1024
 ret: 0         st: 1 flags:0  ts:-0.058322
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
 ret: 0         st: 1 flags:1  ts: 2.835828
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 326272 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 327955 size: 27834
 ret:-1         st:-1 flags:0  ts: 1.730004
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 1 flags:1 dts: 0.464399 pts: 0.464399 pos: 162502 size:  1024
-ret: 0         st: 0 flags:0  ts:-0.480000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 27837
-ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 325248 size:  1024
+ret: 0         st: 1 flags:1 dts: 0.464399 pts: 0.464399 pos: 164185 size:  1024
+ret: 0         st: 0 flags:0  ts:-0.481641
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
+ret: 0         st: 0 flags:1  ts: 2.412500
+ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 326931 size:  1024
 ret:-1         st: 1 flags:0  ts: 1.306667
 ret: 0         st: 1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
 ret: 0         st:-1 flags:0  ts:-0.904994
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
 ret: 0         st:-1 flags:1  ts: 1.989173
-ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 325248 size:  1024
-ret: 0         st: 0 flags:0  ts: 0.880000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 326272 size: 27834
-ret: 0         st: 0 flags:1  ts:-0.240000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 27837
+ret: 0         st: 1 flags:1 dts: 0.952018 pts: 0.952018 pos: 326931 size:  1024
+ret: 0         st: 0 flags:0  ts: 0.883359
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 327955 size: 27834
+ret: 0         st: 0 flags:1  ts:-0.222500
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
 ret:-1         st: 1 flags:0  ts: 2.671678
 ret: 0         st: 1 flags:1  ts: 1.565850
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 326272 size: 27834
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 327955 size: 27834
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 163526 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 165209 size: 27925
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   1727 size: 27837
diff --git a/tests/ref/seek/lavf_mpg b/tests/ref/seek/lavf_mpg
index 0f0d720..935eae1 100644
--- a/tests/ref/seek/lavf_mpg
+++ b/tests/ref/seek/lavf_mpg
@@ -2,7 +2,7 @@
 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  ts: 1.894167
-ret: 0         st: 0 flags:0 dts: 1.880000 pts: 1.920000 pos: 327680 size: 12894
+ret: 0         st: 0 flags:0 dts: 1.880000 pts: 1.920000 pos: 327680 size: 12629
 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:1  ts:-0.317500
@@ -16,7 +16,7 @@
 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: 0 flags:0  ts: 2.153333
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.960000 pos: 339968 size:   681
+ret: 0         st: 1 flags:1 dts: 1.511544 pts: 1.511544 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: 1 flags:0  ts:-0.058333
@@ -24,13 +24,13 @@
 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:0  ts: 1.730004
-ret: 0         st: 0 flags:0 dts: 1.760000 pts: 1.800000 pos: 292864 size: 13170
+ret: 0         st: 0 flags:0 dts: 1.760000 pts: 1.800000 pos: 292864 size: 12894
 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  ts:-0.481667
 ret: 0         st: 1 flags:1 dts: 0.989089 pts: 0.989089 pos:   2048 size:   208
 ret: 0         st: 0 flags:1  ts: 2.412500
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.960000 pos: 339968 size:   681
+ret: 0         st: 1 flags:1 dts: 1.511544 pts: 1.511544 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  ts: 0.200844
@@ -38,7 +38,7 @@
 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  ts: 1.989173
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.960000 pos: 339968 size:   681
+ret: 0         st: 1 flags:1 dts: 1.511544 pts: 1.511544 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:1  ts:-0.222489
diff --git a/tests/ref/seek/lavf_mxf b/tests/ref/seek/lavf_mxf
index cc634a8..f7d1f67 100644
--- a/tests/ref/seek/lavf_mxf
+++ b/tests/ref/seek/lavf_mxf
@@ -2,47 +2,47 @@
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   6144 size: 24801
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
+ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460288 size: 24711
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
+ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460288 size: 24711
 ret: 0         st: 0 flags:1  ts:-0.320000
 ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   6144 size: 24801
 ret:-1         st: 1 flags:0  ts: 2.560000
 ret: 0         st: 1 flags:1  ts: 1.480000
-ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
+ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460288 size: 24711
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.480000 pos: 211968 size: 24787
+ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.480000 pos: 211456 size: 24786
 ret: 0         st:-1 flags:1  ts:-0.740831
 ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   6144 size: 24801
 ret:-1         st: 0 flags:0  ts: 2.160000
 ret: 0         st: 0 flags:1  ts: 1.040000
-ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
+ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460288 size: 24711
 ret: 0         st: 1 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   6144 size: 24801
 ret: 0         st: 1 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
+ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460288 size: 24711
 ret:-1         st:-1 flags:0  ts: 1.730004
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.480000 pos: 211968 size: 24787
+ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.480000 pos: 211456 size: 24786
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   6144 size: 24801
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
+ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460288 size: 24711
 ret:-1         st: 1 flags:0  ts: 1.320000
 ret: 0         st: 1 flags:1  ts: 0.200000
 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
-ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
+ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460288 size: 24711
 ret: 0         st: 0 flags:0  ts: 0.880000
-ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
+ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460288 size: 24711
 ret: 0         st: 0 flags:1  ts:-0.240000
 ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   6144 size: 24801
 ret:-1         st: 1 flags:0  ts: 2.680000
 ret: 0         st: 1 flags:1  ts: 1.560000
-ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
+ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460288 size: 24711
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712
+ret: 0         st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460288 size: 24711
 ret: 0         st:-1 flags:1  ts:-0.645825
 ret: 0         st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos:   6144 size: 24801
diff --git a/tests/ref/seek/lavf_nut b/tests/ref/seek/lavf_nut
index fc3ef63..ef47ceb 100644
--- a/tests/ref/seek/lavf_nut
+++ b/tests/ref/seek/lavf_nut
@@ -1,53 +1,53 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    279 size: 27837
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    339 size:   208
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    279 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.010918 pts: 0.010918 pos:    567 size: 27837
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
-ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
-ret: 0         st: 0 flags:1  ts:-0.320000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    279 size: 27837
-ret: 0         st: 1 flags:0  ts: 2.586122
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
-ret: 0         st: 1 flags:1  ts: 1.462857
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.490918 pts: 0.490918 pos: 146434 size: 27925
+ret: 0         st: 0 flags:0  ts: 0.788340
+ret: 0         st: 0 flags:1 dts: 0.490918 pts: 0.490918 pos: 146434 size: 27925
+ret: 0         st: 0 flags:1  ts:-0.317500
+ret: 0         st: 0 flags:1 dts: 0.010918 pts: 0.010918 pos:    567 size: 27837
+ret: 0         st: 1 flags:0  ts: 2.576667
+ret: 0         st: 1 flags:1 dts: 0.862041 pts: 0.862041 pos: 271259 size:   209
+ret: 0         st: 1 flags:1  ts: 1.470839
+ret: 0         st: 1 flags:1 dts: 0.862041 pts: 0.862041 pos: 271259 size:   209
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    279 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.490918 pts: 0.490918 pos: 146434 size: 27925
 ret: 0         st:-1 flags:1  ts:-0.740831
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    279 size: 27837
-ret: 0         st: 0 flags:0  ts: 2.160000
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
-ret: 0         st: 0 flags:1  ts: 1.040000
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
-ret: 0         st: 1 flags:0  ts:-0.052245
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    279 size: 27837
-ret: 0         st: 1 flags:1  ts: 2.847347
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.010918 pts: 0.010918 pos:    567 size: 27837
+ret: 0         st: 0 flags:0  ts: 2.153340
+ret: 0         st: 0 flags:1 dts: 0.490918 pts: 0.490918 pos: 146434 size: 27925
+ret: 0         st: 0 flags:1  ts: 1.047500
+ret: 0         st: 0 flags:1 dts: 0.490918 pts: 0.490918 pos: 146434 size: 27925
+ret: 0         st: 1 flags:0  ts:-0.058322
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    339 size:   208
+ret: 0         st: 1 flags:1  ts: 2.835828
+ret: 0         st: 1 flags:1 dts: 0.862041 pts: 0.862041 pos: 271259 size:   209
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.490918 pts: 0.490918 pos: 146434 size: 27925
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
-ret: 0         st: 0 flags:0  ts:-0.480000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    279 size: 27837
-ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
-ret: 0         st: 1 flags:0  ts: 1.306122
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
-ret: 0         st: 1 flags:1  ts: 0.208980
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    279 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.490918 pts: 0.490918 pos: 146434 size: 27925
+ret: 0         st: 0 flags:0  ts:-0.481660
+ret: 0         st: 0 flags:1 dts: 0.010918 pts: 0.010918 pos:    567 size: 27837
+ret: 0         st: 0 flags:1  ts: 2.412500
+ret: 0         st: 0 flags:1 dts: 0.490918 pts: 0.490918 pos: 146434 size: 27925
+ret: 0         st: 1 flags:0  ts: 1.306667
+ret: 0         st: 1 flags:1 dts: 0.862041 pts: 0.862041 pos: 271259 size:   209
+ret: 0         st: 1 flags:1  ts: 0.200839
+ret: 0         st: 1 flags:1 dts: 0.182857 pts: 0.182857 pos:  71901 size:   209
 ret: 0         st:-1 flags:0  ts:-0.904994
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    279 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.010918 pts: 0.010918 pos:    567 size: 27837
 ret: 0         st:-1 flags:1  ts: 1.989173
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
-ret: 0         st: 0 flags:0  ts: 0.880000
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
-ret: 0         st: 0 flags:1  ts:-0.240000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    279 size: 27837
-ret: 0         st: 1 flags:0  ts: 2.664490
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
-ret: 0         st: 1 flags:1  ts: 1.567347
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.490918 pts: 0.490918 pos: 146434 size: 27925
+ret: 0         st: 0 flags:0  ts: 0.883340
+ret: 0         st: 0 flags:1 dts: 0.490918 pts: 0.490918 pos: 146434 size: 27925
+ret: 0         st: 0 flags:1  ts:-0.222500
+ret: 0         st: 0 flags:1 dts: 0.010918 pts: 0.010918 pos:    567 size: 27837
+ret: 0         st: 1 flags:0  ts: 2.671678
+ret: 0         st: 1 flags:1 dts: 0.862041 pts: 0.862041 pos: 271259 size:   209
+ret: 0         st: 1 flags:1  ts: 1.565850
+ret: 0         st: 1 flags:1 dts: 0.862041 pts: 0.862041 pos: 271259 size:   209
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146329 size: 27925
+ret: 0         st: 0 flags:1 dts: 0.490918 pts: 0.490918 pos: 146434 size: 27925
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    279 size: 27837
+ret: 0         st: 0 flags:1 dts: 0.010918 pts: 0.010918 pos:    567 size: 27837
diff --git a/tests/ref/seek/lavf_ogg b/tests/ref/seek/lavf_ogg
index ea8eb8b..2898d10 100644
--- a/tests/ref/seek/lavf_ogg
+++ b/tests/ref/seek/lavf_ogg
@@ -1,27 +1,35 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    124 size:  1364
-ret:-1         st:-1 flags:0  ts:-1.000000
+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:-1         st: 0 flags:1  ts:-0.317506
+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:-1         st: 0 flags:1  ts:-0.740839
+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:-1         st: 0 flags:0  ts:-0.058322
+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:-1         st: 0 flags:0  ts:-0.481655
+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:-1         st: 0 flags:0  ts:-0.904989
+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:-1         st:-1 flags:1  ts:-0.222493
+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:-1         st:-1 flags:1  ts:-0.645825
+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_rm b/tests/ref/seek/lavf_rm
index adce9e0..4b19173 100644
--- a/tests/ref/seek/lavf_rm
+++ b/tests/ref/seek/lavf_rm
@@ -1,53 +1,53 @@
-ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    387 size:   278
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    395 size:   278
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    688 size: 31082
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    696 size: 31082
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314982 size: 31143
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314992 size: 31143
 ret: 0         st: 0 flags:0  ts: 0.788000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314982 size: 31143
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314992 size: 31143
 ret: 0         st: 0 flags:1  ts:-0.317000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    688 size: 31082
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    696 size: 31082
 ret: 0         st: 1 flags:0  ts: 2.577000
-ret: 0         st: 1 flags:1 dts: 0.975000 pts: 0.975000 pos: 346128 size:   278
+ret: 0         st: 1 flags:1 dts: 0.975000 pts: 0.975000 pos: 346138 size:   278
 ret: 0         st: 1 flags:1  ts: 1.471000
-ret: 0         st: 1 flags:1 dts: 0.975000 pts: 0.975000 pos: 346128 size:   278
+ret: 0         st: 1 flags:1 dts: 0.975000 pts: 0.975000 pos: 346138 size:   278
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 158515 size: 31134
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 158523 size: 31134
 ret: 0         st:-1 flags:1  ts:-0.740831
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    688 size: 31082
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    696 size: 31082
 ret: 0         st: 0 flags:0  ts: 2.153000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314982 size: 31143
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314992 size: 31143
 ret: 0         st: 0 flags:1  ts: 1.048000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314982 size: 31143
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314992 size: 31143
 ret: 0         st: 1 flags:0  ts:-0.058000
-ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    387 size:   278
+ret: 0         st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos:    395 size:   278
 ret: 0         st: 1 flags:1  ts: 2.836000
-ret: 0         st: 1 flags:1 dts: 0.975000 pts: 0.975000 pos: 346128 size:   278
+ret: 0         st: 1 flags:1 dts: 0.975000 pts: 0.975000 pos: 346138 size:   278
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314982 size: 31143
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314992 size: 31143
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 158515 size: 31134
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 158523 size: 31134
 ret: 0         st: 0 flags:0  ts:-0.482000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    688 size: 31082
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    696 size: 31082
 ret: 0         st: 0 flags:1  ts: 2.413000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314982 size: 31143
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314992 size: 31143
 ret: 0         st: 1 flags:0  ts: 1.307000
-ret: 0         st: 1 flags:1 dts: 0.975000 pts: 0.975000 pos: 346128 size:   278
+ret: 0         st: 1 flags:1 dts: 0.975000 pts: 0.975000 pos: 346138 size:   278
 ret: 0         st: 1 flags:1  ts: 0.201000
-ret: 0         st: 1 flags:1 dts: 0.174000 pts: 0.174000 pos:  78969 size:   278
+ret: 0         st: 1 flags:1 dts: 0.174000 pts: 0.174000 pos:  78977 size:   278
 ret: 0         st:-1 flags:0  ts:-0.904994
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    688 size: 31082
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    696 size: 31082
 ret: 0         st:-1 flags:1  ts: 1.989173
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314982 size: 31143
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314992 size: 31143
 ret: 0         st: 0 flags:0  ts: 0.883000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314982 size: 31143
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 314992 size: 31143
 ret: 0         st: 0 flags:1  ts:-0.222000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    688 size: 31082
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    696 size: 31082
 ret: 0         st: 1 flags:0  ts: 2.672000
-ret: 0         st: 1 flags:1 dts: 0.975000 pts: 0.975000 pos: 346128 size:   278
+ret: 0         st: 1 flags:1 dts: 0.975000 pts: 0.975000 pos: 346138 size:   278
 ret: 0         st: 1 flags:1  ts: 1.566000
-ret: 0         st: 1 flags:1 dts: 0.975000 pts: 0.975000 pos: 346128 size:   278
+ret: 0         st: 1 flags:1 dts: 0.975000 pts: 0.975000 pos: 346138 size:   278
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 158515 size: 31134
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 158523 size: 31134
 ret: 0         st:-1 flags:1  ts:-0.645825
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    688 size: 31082
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    696 size: 31082
diff --git a/tests/ref/seek/lavf_ts b/tests/ref/seek/lavf_ts
index 81093b7..407ba59 100644
--- a/tests/ref/seek/lavf_ts
+++ b/tests/ref/seek/lavf_ts
@@ -1,53 +1,53 @@
 ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:0 dts: 1.440000 pts: 1.480000 pos:  44932 size: 14502
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 403636 size:   209
+ret: 0         st: 0 flags:0 dts: 1.880000 pts: 1.920000 pos: 216388 size: 17440
 ret: 0         st: 0 flags:0  ts: 0.788333
-ret: 0         st: 0 flags:0 dts: 1.520000 pts: 1.560000 pos:  74260 size: 13388
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
 ret: 0         st: 0 flags:1  ts:-0.317500
 ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
 ret: 0         st: 1 flags:0  ts: 2.576667
-ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 403636 size:   209
+ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 404576 size:   209
 ret: 0         st: 1 flags:1  ts: 1.470833
-ret: 0         st: 0 flags:0 dts: 2.160000 pts: 2.200000 pos: 325240 size: 12679
+ret: 0         st: 1 flags:1 dts: 1.389089 pts: 1.389089 pos: 159988 size:   208
 ret: 0         st:-1 flags:0  ts: 0.365002
-ret: 0         st: 0 flags:0 dts: 1.440000 pts: 1.480000 pos:  44932 size: 14502
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
 ret: 0         st:-1 flags:1  ts:-0.740831
 ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
 ret: 0         st: 0 flags:0  ts: 2.153333
-ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 403636 size:   209
+ret: 0         st: 0 flags:0 dts: 2.160000 pts: 2.200000 pos: 325992 size: 12692
 ret: 0         st: 0 flags:1  ts: 1.047500
-ret: 0         st: 0 flags:0 dts: 1.680000 pts: 1.720000 pos: 130096 size: 14133
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
 ret: 0         st: 1 flags:0  ts:-0.058333
-ret: 0         st: 0 flags:0 dts: 1.440000 pts: 1.480000 pos:  44932 size: 14502
+ret: 0         st: 1 flags:1 dts: 1.389089 pts: 1.389089 pos: 159988 size:   208
 ret: 0         st: 1 flags:1  ts: 2.835833
-ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 403636 size:   209
+ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 404576 size:   209
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 403636 size:   209
+ret: 0         st: 0 flags:0 dts: 1.760000 pts: 1.800000 pos: 162996 size: 12135
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
 ret: 0         st: 0 flags:0  ts:-0.481667
-ret: 0         st: 0 flags:0 dts: 1.440000 pts: 1.480000 pos:  44932 size: 14502
-ret: 0         st: 0 flags:1  ts: 2.412500
-ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 403636 size:   209
-ret: 0         st: 1 flags:0  ts: 1.306667
-ret: 0         st: 0 flags:0 dts: 2.080000 pts: 2.120000 pos: 294032 size: 13839
-ret: 0         st: 1 flags:1  ts: 0.200844
 ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
+ret: 0         st: 0 flags:1  ts: 2.412500
+ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 404576 size:   209
+ret: 0         st: 1 flags:0  ts: 1.306667
+ret: 0         st: 1 flags:1 dts: 1.389089 pts: 1.389089 pos: 159988 size:   208
+ret: 0         st: 1 flags:1  ts: 0.200844
+ret: 0         st: 1 flags:1 dts: 1.389089 pts: 1.389089 pos: 159988 size:   208
 ret: 0         st:-1 flags:0  ts:-0.904994
-ret: 0         st: 0 flags:0 dts: 1.440000 pts: 1.480000 pos:  44932 size: 14502
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
 ret: 0         st:-1 flags:1  ts: 1.989173
-ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 403636 size:   209
+ret: 0         st: 0 flags:0 dts: 1.960000 pts: 2.000000 pos: 251356 size: 13449
 ret: 0         st: 0 flags:0  ts: 0.883344
-ret: 0         st: 0 flags:0 dts: 1.600000 pts: 1.640000 pos: 102836 size: 12781
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
 ret: 0         st: 0 flags:1  ts:-0.222489
 ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
 ret: 0         st: 1 flags:0  ts: 2.671678
-ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 403636 size:   209
+ret: 0         st: 1 flags:1 dts: 2.120522 pts: 2.120522 pos: 404576 size:   209
 ret: 0         st: 1 flags:1  ts: 1.565844
-ret: 0         st: 0 flags:0 dts: 2.240000 pts: 2.280000 pos: 350996 size: 11307
+ret: 0         st: 1 flags:1 dts: 1.389089 pts: 1.389089 pos: 159988 size:   208
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:0 dts: 1.440000 pts: 1.480000 pos:  44932 size: 14502
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
 ret: 0         st:-1 flags:1  ts:-0.645825
 ret: 0         st: 0 flags:1 dts: 1.360000 pts: 1.400000 pos:    564 size: 24801
diff --git a/tests/ref/seek/lavf_voc b/tests/ref/seek/lavf_voc
index 387aef6..833d763 100644
--- a/tests/ref/seek/lavf_voc
+++ b/tests/ref/seek/lavf_voc
@@ -1,27 +1,27 @@
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     32 size:  1024
 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.788335
-ret:-1         st: 0 flags:1  ts:-0.317508
+ret:-1         st: 0 flags:0  ts: 0.788330
+ret:-1         st: 0 flags:1  ts:-0.317494
 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.365006
-ret:-1         st: 0 flags:1  ts:-0.740837
+ret:-1         st: 0 flags:0  ts: 0.365012
+ret:-1         st: 0 flags:1  ts:-0.740834
 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.058323
-ret:-1         st: 0 flags:1  ts: 2.835834
+ret:-1         st: 0 flags:0  ts:-0.058328
+ret:-1         st: 0 flags:1  ts: 2.835848
 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.481652
-ret:-1         st: 0 flags:1  ts: 2.412505
+ret:-1         st: 0 flags:0  ts:-0.481669
+ret:-1         st: 0 flags:1  ts: 2.412507
 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.905003
-ret:-1         st: 0 flags:1  ts: 1.989176
+ret:-1         st: 0 flags:0  ts:-0.904986
+ret:-1         st: 0 flags:1  ts: 1.989167
 ret:-1         st:-1 flags:0  ts: 0.883340
 ret:-1         st:-1 flags:1  ts:-0.222493
-ret:-1         st: 0 flags:0  ts: 2.671668
-ret:-1         st: 0 flags:1  ts: 1.565847
+ret:-1         st: 0 flags:0  ts: 2.671673
+ret:-1         st: 0 flags:1  ts: 1.565849
 ret:-1         st:-1 flags:0  ts: 0.460008
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/lavf_wtv b/tests/ref/seek/lavf_wtv
new file mode 100644
index 0000000..e2a1697
--- /dev/null
+++ b/tests/ref/seek/lavf_wtv
@@ -0,0 +1,41 @@
+ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  27072 size:   208
+ret: 0         st:-1 flags:0  ts:-1.000000
+ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  27072 size:   208
+ret:-1         st:-1 flags:1  ts: 1.894167
+ret: 0         st: 0 flags:0  ts: 0.788334
+ret: 0         st: 1 flags:1 dts: 0.772766 pts: 0.772766 pos: 321528 size:   209
+ret: 0         st: 0 flags:1  ts:-0.317499
+ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  27072 size:   208
+ret:-1         st: 1 flags:0  ts: 2.576668
+ret:-1         st: 1 flags:1  ts: 1.470835
+ret: 0         st:-1 flags:0  ts: 0.365002
+ret: 0         st: 1 flags:1 dts: 0.380930 pts: 0.380930 pos: 167728 size:   209
+ret: 0         st:-1 flags:1  ts:-0.740831
+ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  27072 size:   208
+ret:-1         st: 0 flags:0  ts: 2.153336
+ret:-1         st: 0 flags:1  ts: 1.047503
+ret: 0         st: 1 flags:0  ts:-0.058330
+ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  27072 size:   208
+ret:-1         st: 1 flags:1  ts: 2.835837
+ret:-1         st:-1 flags:0  ts: 1.730004
+ret: 0         st:-1 flags:1  ts: 0.624171
+ret: 0         st: 1 flags:1 dts: 0.616032 pts: 0.616032 pos: 266872 size:   209
+ret: 0         st: 0 flags:0  ts:-0.481662
+ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  27072 size:   208
+ret:-1         st: 0 flags:1  ts: 2.412505
+ret:-1         st: 1 flags:0  ts: 1.306672
+ret: 0         st: 1 flags:1  ts: 0.200839
+ret: 0         st: 1 flags:1 dts: 0.224195 pts: 0.224195 pos: 113632 size:   209
+ret: 0         st:-1 flags:0  ts:-0.904994
+ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  27072 size:   208
+ret:-1         st:-1 flags:1  ts: 1.989173
+ret: 0         st: 0 flags:0  ts: 0.883340
+ret: 0         st: 1 flags:1 dts: 0.903379 pts: 0.903379 pos: 358360 size:   209
+ret: 0         st: 0 flags:1  ts:-0.222493
+ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  27072 size:   208
+ret:-1         st: 1 flags:0  ts: 2.671674
+ret:-1         st: 1 flags:1  ts: 1.565841
+ret: 0         st:-1 flags:0  ts: 0.460008
+ret: 0         st: 1 flags:1 dts: 0.459297 pts: 0.459297 pos: 206056 size:   209
+ret: 0         st:-1 flags:1  ts:-0.645825
+ret: 0         st: 1 flags:1 dts:-0.010907 pts:-0.010907 pos:  27072 size:   208
diff --git a/tests/ref/seek/mjpeg_avi b/tests/ref/seek/mjpeg_avi
index b0f975b..e172b91 100644
--- a/tests/ref/seek/mjpeg_avi
+++ b/tests/ref/seek/mjpeg_avi
@@ -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:   5660 size: 12096
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.880000 pts: 1.880000 pos: 627866 size: 14811
+ret: 0         st: 0 flags:1 dts: 1.880000 pts: 1.880000 pos: 627826 size: 14806
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos: 247500 size: 12959
+ret: 0         st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos: 247510 size: 12959
 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.480000 pts: 1.480000 pos: 480770 size: 14528
+ret: 0         st: 0 flags:1 dts: 1.480000 pts: 1.480000 pos: 480748 size: 14519
 ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos: 111012 size: 11927
+ret: 0         st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos: 111008 size: 11924
 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: 1.040000 pts: 1.040000 pos: 326684 size: 13489
+ret: 0         st: 0 flags:1 dts: 1.040000 pts: 1.040000 pos: 326692 size: 13491
 ret: 0         st: 0 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size: 12096
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos: 657534 size: 14881
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos: 657480 size: 14897
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.720000 pts: 1.720000 pos: 568664 size: 14746
+ret: 0         st: 0 flags:1 dts: 1.720000 pts: 1.720000 pos: 568618 size: 14751
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.640000 pts: 0.640000 pos: 196428 size: 12719
+ret: 0         st: 0 flags:1 dts: 0.640000 pts: 0.640000 pos: 196432 size: 12720
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size: 12096
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos: 657534 size: 14881
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos: 657480 size: 14897
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.320000 pts: 1.320000 pos: 423494 size: 14119
+ret: 0         st: 0 flags:1 dts: 1.320000 pts: 1.320000 pos: 423482 size: 14114
 ret: 0         st:-1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:  63872 size: 11714
+ret: 0         st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:  63874 size: 11715
 ret: 0         st: 0 flags:0  ts:-0.920000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size: 12096
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos: 657534 size: 14881
+ret: 0         st: 0 flags:1 dts: 1.960000 pts: 1.960000 pos: 657480 size: 14897
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos: 273520 size: 13131
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos: 273524 size: 13122
 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.560000 pts: 1.560000 pos: 509938 size: 14597
+ret: 0         st: 0 flags:1 dts: 1.560000 pts: 1.560000 pos: 509904 size: 14594
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146970 size: 12168
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 146962 size: 12173
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/mpeg1_mpeg1video b/tests/ref/seek/mpeg1_mpeg1video
index a85055a..0ec751a 100644
--- a/tests/ref/seek/mpeg1_mpeg1video
+++ b/tests/ref/seek/mpeg1_mpeg1video
@@ -2,45 +2,45 @@
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9779
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: NOPTS    pos: 124245 size: 11796
-ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos:  76694 size: 10792
-ret:-1         st: 0 flags:1  ts:-0.320000
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: NOPTS    pos: 124255 size: 11796
+ret: 0         st: 0 flags:0  ts: 0.788334
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos:  76706 size: 10792
+ret:-1         st: 0 flags:1  ts:-0.317499
 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: NOPTS    pos: 124245 size: 11796
-ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: NOPTS    pos: 124255 size: 11796
+ret: 0         st: 0 flags:0  ts: 0.365002
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: NOPTS    pos:  37721 size:  9873
-ret:-1         st: 0 flags:1  ts:-0.760000
+ret:-1         st: 0 flags:1  ts:-0.740831
 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: NOPTS    pos:  76694 size: 10792
-ret: 0         st: 0 flags:0  ts:-0.040000
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos:  76706 size: 10792
+ret: 0         st: 0 flags:0  ts:-0.058330
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9779
-ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 177089 size: 12057
+ret: 0         st: 0 flags:1  ts: 2.835837
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 177099 size: 12057
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 177089 size: 12057
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 177099 size: 12057
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: NOPTS    pos:  37721 size:  9873
-ret: 0         st: 0 flags:0  ts:-0.480000
+ret: 0         st: 0 flags:0  ts:-0.481662
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9779
-ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 177089 size: 12057
+ret: 0         st: 0 flags:1  ts: 2.412505
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 177099 size: 12057
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: NOPTS    pos: 124245 size: 11796
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: NOPTS    pos: 124255 size: 11796
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9779
-ret: 0         st: 0 flags:0  ts:-0.920000
+ret: 0         st: 0 flags:0  ts:-0.904994
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9779
-ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 177089 size: 12057
+ret: 0         st: 0 flags:1  ts: 1.989173
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 177099 size: 12057
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos:  76694 size: 10792
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos:  76706 size: 10792
 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: NOPTS    pos: 124245 size: 11796
+ret:-1         st: 0 flags:0  ts: 2.671674
+ret: 0         st: 0 flags:1  ts: 1.565841
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: NOPTS    pos: 124255 size: 11796
 ret: 0         st:-1 flags:0  ts: 0.460008
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: NOPTS    pos:  37721 size:  9873
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/mpeg1b_mpeg1video b/tests/ref/seek/mpeg1b_mpeg1video
index 3b0b084..e079e34 100644
--- a/tests/ref/seek/mpeg1b_mpeg1video
+++ b/tests/ref/seek/mpeg1b_mpeg1video
@@ -2,44 +2,44 @@
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size: 11817
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.800000 pts: NOPTS    pos: 194420 size: 14837
-ret: 0         st: 0 flags:0  ts: 0.800000
+ret: 0         st: 0 flags:1 dts: 1.800000 pts: NOPTS    pos: 194424 size: 14837
+ret: 0         st: 0 flags:0  ts: 0.788334
 ret: 0         st: 0 flags:1 dts: 0.840000 pts: NOPTS    pos:  80757 size: 13267
-ret:-1         st: 0 flags:1  ts:-0.320000
+ret:-1         st: 0 flags:1  ts:-0.317499
 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.320000 pts: NOPTS    pos: 133899 size: 14470
-ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.360000 pts: NOPTS    pos:  34797 size: 12009
-ret:-1         st: 0 flags:1  ts:-0.760000
+ret: 0         st: 0 flags:0  ts: 0.365002
+ret: 0         st: 0 flags:1 dts: 0.840000 pts: NOPTS    pos:  80757 size: 13267
+ret:-1         st: 0 flags:1  ts:-0.740831
 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.840000 pts: NOPTS    pos:  80757 size: 13267
-ret: 0         st: 0 flags:0  ts:-0.040000
+ret: 0         st: 0 flags:0  ts:-0.058330
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size: 11817
-ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.800000 pts: NOPTS    pos: 194420 size: 14837
+ret: 0         st: 0 flags:1  ts: 2.835837
+ret: 0         st: 0 flags:1 dts: 1.800000 pts: NOPTS    pos: 194424 size: 14837
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.800000 pts: NOPTS    pos: 194420 size: 14837
+ret: 0         st: 0 flags:1 dts: 1.800000 pts: NOPTS    pos: 194424 size: 14837
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.360000 pts: NOPTS    pos:  34797 size: 12009
-ret: 0         st: 0 flags:0  ts:-0.480000
+ret: 0         st: 0 flags:0  ts:-0.481662
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size: 11817
-ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.800000 pts: NOPTS    pos: 194420 size: 14837
+ret: 0         st: 0 flags:1  ts: 2.412505
+ret: 0         st: 0 flags:1 dts: 1.800000 pts: NOPTS    pos: 194424 size: 14837
 ret: 0         st:-1 flags:0  ts: 1.306672
 ret: 0         st: 0 flags:1 dts: 1.320000 pts: NOPTS    pos: 133899 size: 14470
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size: 11817
-ret: 0         st: 0 flags:0  ts:-0.920000
+ret: 0         st: 0 flags:0  ts:-0.904994
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size: 11817
-ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.800000 pts: NOPTS    pos: 194420 size: 14837
+ret: 0         st: 0 flags:1  ts: 1.989173
+ret: 0         st: 0 flags:1 dts: 1.800000 pts: NOPTS    pos: 194424 size: 14837
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 1.320000 pts: NOPTS    pos: 133899 size: 14470
 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:-1         st: 0 flags:0  ts: 2.671674
+ret: 0         st: 0 flags:1  ts: 1.565841
 ret: 0         st: 0 flags:1 dts: 1.320000 pts: NOPTS    pos: 133899 size: 14470
 ret: 0         st:-1 flags:0  ts: 0.460008
 ret: 0         st: 0 flags:1 dts: 0.840000 pts: NOPTS    pos:  80757 size: 13267
diff --git a/tests/ref/seek/mpeg2_422_mpeg2video b/tests/ref/seek/mpeg2_422_mpeg2video
index d06b7cb..06d8f7a 100644
--- a/tests/ref/seek/mpeg2_422_mpeg2video
+++ b/tests/ref/seek/mpeg2_422_mpeg2video
@@ -2,45 +2,45 @@
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size: 17497
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 325162 size: 19936
-ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 200736 size: 22575
-ret:-1         st: 0 flags:1  ts:-0.320000
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 325397 size: 19967
+ret: 0         st: 0 flags:0  ts: 0.788334
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 200747 size: 22575
+ret:-1         st: 0 flags:1  ts:-0.317499
 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.360000 pts: NOPTS    pos: 265477 size: 21329
-ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 265466 size: 21329
+ret: 0         st: 0 flags:0  ts: 0.365002
 ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos: 104454 size: 28984
-ret:-1         st: 0 flags:1  ts:-0.760000
+ret:-1         st: 0 flags:1  ts:-0.740831
 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.880000 pts: NOPTS    pos: 200736 size: 22575
-ret: 0         st: 0 flags:0  ts:-0.040000
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 200747 size: 22575
+ret: 0         st: 0 flags:0  ts:-0.058330
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size: 17497
-ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 325162 size: 19936
+ret: 0         st: 0 flags:1  ts: 2.835837
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 325397 size: 19967
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 325162 size: 19936
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 325397 size: 19967
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos: 104454 size: 28984
-ret: 0         st: 0 flags:0  ts:-0.480000
+ret: 0         st: 0 flags:0  ts:-0.481662
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size: 17497
-ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 325162 size: 19936
+ret: 0         st: 0 flags:1  ts: 2.412505
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 325397 size: 19967
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 265477 size: 21329
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 265466 size: 21329
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size: 17497
-ret: 0         st: 0 flags:0  ts:-0.920000
+ret: 0         st: 0 flags:0  ts:-0.904994
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size: 17497
-ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 325162 size: 19936
+ret: 0         st: 0 flags:1  ts: 1.989173
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 325397 size: 19967
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 200736 size: 22575
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 265466 size: 21329
 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.360000 pts: NOPTS    pos: 265477 size: 21329
+ret:-1         st: 0 flags:0  ts: 2.671674
+ret: 0         st: 0 flags:1  ts: 1.565841
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 265466 size: 21329
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 200736 size: 22575
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 200747 size: 22575
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/mpeg2_idct_int_mpeg2video b/tests/ref/seek/mpeg2_idct_int_mpeg2video
index 698cedf..b096f6f 100644
--- a/tests/ref/seek/mpeg2_idct_int_mpeg2video
+++ b/tests/ref/seek/mpeg2_idct_int_mpeg2video
@@ -3,43 +3,43 @@
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9911
 ret: 0         st:-1 flags:1  ts: 1.894167
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: NOPTS    pos: 127925 size: 11918
-ret: 0         st: 0 flags:0  ts: 0.800000
+ret: 0         st: 0 flags:0  ts: 0.788334
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos:  79103 size: 10909
-ret:-1         st: 0 flags:1  ts:-0.320000
+ret:-1         st: 0 flags:1  ts:-0.317499
 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: NOPTS    pos: 127925 size: 11918
-ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:0  ts: 0.365002
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: NOPTS    pos:  38992 size:  9985
-ret:-1         st: 0 flags:1  ts:-0.760000
+ret:-1         st: 0 flags:1  ts:-0.740831
 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: NOPTS    pos:  79103 size: 10909
-ret: 0         st: 0 flags:0  ts:-0.040000
+ret: 0         st: 0 flags:0  ts:-0.058330
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9911
-ret: 0         st: 0 flags:1  ts: 2.840000
+ret: 0         st: 0 flags:1  ts: 2.835837
 ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 182138 size: 12183
 ret: 0         st:-1 flags:0  ts: 1.730004
 ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 182138 size: 12183
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: NOPTS    pos:  38992 size:  9985
-ret: 0         st: 0 flags:0  ts:-0.480000
+ret: 0         st: 0 flags:0  ts:-0.481662
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9911
-ret: 0         st: 0 flags:1  ts: 2.400000
+ret: 0         st: 0 flags:1  ts: 2.412505
 ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 182138 size: 12183
 ret: 0         st:-1 flags:0  ts: 1.306672
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: NOPTS    pos: 127925 size: 11918
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9911
-ret: 0         st: 0 flags:0  ts:-0.920000
+ret: 0         st: 0 flags:0  ts:-0.904994
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9911
-ret: 0         st: 0 flags:1  ts: 2.000000
+ret: 0         st: 0 flags:1  ts: 1.989173
 ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 182138 size: 12183
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos:  79103 size: 10909
 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:-1         st: 0 flags:0  ts: 2.671674
+ret: 0         st: 0 flags:1  ts: 1.565841
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: NOPTS    pos: 127925 size: 11918
 ret: 0         st:-1 flags:0  ts: 0.460008
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: NOPTS    pos:  38992 size:  9985
diff --git a/tests/ref/seek/mpeg2_ilace_mpeg2video b/tests/ref/seek/mpeg2_ilace_mpeg2video
index a2427f3..d2a7838 100644
--- a/tests/ref/seek/mpeg2_ilace_mpeg2video
+++ b/tests/ref/seek/mpeg2_ilace_mpeg2video
@@ -2,45 +2,45 @@
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9961
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: NOPTS    pos: 132607 size: 11970
-ret: 0         st: 0 flags:0  ts: 0.800000
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: NOPTS    pos: 132603 size: 11970
+ret: 0         st: 0 flags:0  ts: 0.788334
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos:  82152 size: 10965
-ret:-1         st: 0 flags:1  ts:-0.320000
+ret:-1         st: 0 flags:1  ts:-0.317499
 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: NOPTS    pos: 132607 size: 11970
-ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: NOPTS    pos: 132603 size: 11970
+ret: 0         st: 0 flags:0  ts: 0.365002
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: NOPTS    pos:  40546 size: 10045
-ret:-1         st: 0 flags:1  ts:-0.760000
+ret:-1         st: 0 flags:1  ts:-0.740831
 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: NOPTS    pos:  82152 size: 10965
-ret: 0         st: 0 flags:0  ts:-0.040000
+ret: 0         st: 0 flags:0  ts:-0.058330
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9961
-ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 188429 size: 12232
+ret: 0         st: 0 flags:1  ts: 2.835837
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 188425 size: 12232
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 188429 size: 12232
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 188425 size: 12232
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: NOPTS    pos:  40546 size: 10045
-ret: 0         st: 0 flags:0  ts:-0.480000
+ret: 0         st: 0 flags:0  ts:-0.481662
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9961
-ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 188429 size: 12232
+ret: 0         st: 0 flags:1  ts: 2.412505
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 188425 size: 12232
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: NOPTS    pos: 132607 size: 11970
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: NOPTS    pos: 132603 size: 11970
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9961
-ret: 0         st: 0 flags:0  ts:-0.920000
+ret: 0         st: 0 flags:0  ts:-0.904994
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9961
-ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 188429 size: 12232
+ret: 0         st: 0 flags:1  ts: 1.989173
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: NOPTS    pos: 188425 size: 12232
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: NOPTS    pos:  82152 size: 10965
 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: NOPTS    pos: 132607 size: 11970
+ret:-1         st: 0 flags:0  ts: 2.671674
+ret: 0         st: 0 flags:1  ts: 1.565841
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: NOPTS    pos: 132603 size: 11970
 ret: 0         st:-1 flags:0  ts: 0.460008
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: NOPTS    pos:  40546 size: 10045
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/mpeg2_ivlc_qprd_mpeg2video b/tests/ref/seek/mpeg2_ivlc_qprd_mpeg2video
index 9a623c2..330dc16 100644
--- a/tests/ref/seek/mpeg2_ivlc_qprd_mpeg2video
+++ b/tests/ref/seek/mpeg2_ivlc_qprd_mpeg2video
@@ -3,43 +3,43 @@
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size: 16239
 ret: 0         st:-1 flags:1  ts: 1.894167
 ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 227500 size: 12725
-ret: 0         st: 0 flags:0  ts: 0.800000
+ret: 0         st: 0 flags:0  ts: 0.788334
 ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 164167 size: 13921
-ret:-1         st: 0 flags:1  ts:-0.320000
+ret:-1         st: 0 flags:1  ts:-0.317499
 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.360000 pts: NOPTS    pos: 196681 size: 13159
-ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:0  ts: 0.365002
 ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  98748 size: 29165
-ret:-1         st: 0 flags:1  ts:-0.760000
+ret:-1         st: 0 flags:1  ts:-0.740831
 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.880000 pts: NOPTS    pos: 164167 size: 13921
-ret: 0         st: 0 flags:0  ts:-0.040000
+ret: 0         st: 0 flags:0  ts:-0.058330
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size: 16239
-ret: 0         st: 0 flags:1  ts: 2.840000
+ret: 0         st: 0 flags:1  ts: 2.835837
 ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 227500 size: 12725
 ret: 0         st:-1 flags:0  ts: 1.730004
 ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 227500 size: 12725
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  98748 size: 29165
-ret: 0         st: 0 flags:0  ts:-0.480000
+ret: 0         st: 0 flags:0  ts:-0.481662
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size: 16239
-ret: 0         st: 0 flags:1  ts: 2.400000
+ret: 0         st: 0 flags:1  ts: 2.412505
 ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 227500 size: 12725
 ret: 0         st:-1 flags:0  ts: 1.306672
 ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 196681 size: 13159
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size: 16239
-ret: 0         st: 0 flags:0  ts:-0.920000
+ret: 0         st: 0 flags:0  ts:-0.904994
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size: 16239
-ret: 0         st: 0 flags:1  ts: 2.000000
+ret: 0         st: 0 flags:1  ts: 1.989173
 ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 227500 size: 12725
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 164167 size: 13921
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 196681 size: 13159
 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:-1         st: 0 flags:0  ts: 2.671674
+ret: 0         st: 0 flags:1  ts: 1.565841
 ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 196681 size: 13159
 ret: 0         st:-1 flags:0  ts: 0.460008
 ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 164167 size: 13921
diff --git a/tests/ref/seek/mpeg2_thread_ivlc_mpeg2video b/tests/ref/seek/mpeg2_thread_ivlc_mpeg2video
index f1909b6..49ec819 100644
--- a/tests/ref/seek/mpeg2_thread_ivlc_mpeg2video
+++ b/tests/ref/seek/mpeg2_thread_ivlc_mpeg2video
@@ -2,45 +2,45 @@
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9954
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 157678 size: 11930
-ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  67723 size: 10791
-ret:-1         st: 0 flags:1  ts:-0.320000
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 157685 size: 11930
+ret: 0         st: 0 flags:0  ts: 0.788334
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  67716 size: 10791
+ret:-1         st: 0 flags:1  ts:-0.317499
 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.360000 pts: NOPTS    pos: 110080 size: 11697
-ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 110086 size: 11697
+ret: 0         st: 0 flags:0  ts: 0.365002
 ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  30744 size:  9980
-ret:-1         st: 0 flags:1  ts:-0.760000
+ret:-1         st: 0 flags:1  ts:-0.740831
 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.880000 pts: NOPTS    pos:  67723 size: 10791
-ret: 0         st: 0 flags:0  ts:-0.040000
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  67716 size: 10791
+ret: 0         st: 0 flags:0  ts:-0.058330
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9954
-ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 157678 size: 11930
+ret: 0         st: 0 flags:1  ts: 2.835837
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 157685 size: 11930
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 157678 size: 11930
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 157685 size: 11930
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  30744 size:  9980
-ret: 0         st: 0 flags:0  ts:-0.480000
+ret: 0         st: 0 flags:0  ts:-0.481662
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9954
-ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 157678 size: 11930
+ret: 0         st: 0 flags:1  ts: 2.412505
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 157685 size: 11930
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 110080 size: 11697
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 110086 size: 11697
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9954
-ret: 0         st: 0 flags:0  ts:-0.920000
+ret: 0         st: 0 flags:0  ts:-0.904994
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9954
-ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 157678 size: 11930
+ret: 0         st: 0 flags:1  ts: 1.989173
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 157685 size: 11930
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  67723 size: 10791
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 110086 size: 11697
 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.360000 pts: NOPTS    pos: 110080 size: 11697
+ret:-1         st: 0 flags:0  ts: 2.671674
+ret: 0         st: 0 flags:1  ts: 1.565841
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 110086 size: 11697
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  67723 size: 10791
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  67716 size: 10791
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/mpeg2_thread_mpeg2video b/tests/ref/seek/mpeg2_thread_mpeg2video
index d8c9e28..8e16f43 100644
--- a/tests/ref/seek/mpeg2_thread_mpeg2video
+++ b/tests/ref/seek/mpeg2_thread_mpeg2video
@@ -2,45 +2,45 @@
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9961
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 158225 size: 12232
-ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  67790 size: 10965
-ret:-1         st: 0 flags:1  ts:-0.320000
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 158232 size: 12232
+ret: 0         st: 0 flags:0  ts: 0.788334
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  67783 size: 10965
+ret:-1         st: 0 flags:1  ts:-0.317499
 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.360000 pts: NOPTS    pos: 110330 size: 11970
-ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 110336 size: 11970
+ret: 0         st: 0 flags:0  ts: 0.365002
 ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  30747 size: 10045
-ret:-1         st: 0 flags:1  ts:-0.760000
+ret:-1         st: 0 flags:1  ts:-0.740831
 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.880000 pts: NOPTS    pos:  67790 size: 10965
-ret: 0         st: 0 flags:0  ts:-0.040000
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  67783 size: 10965
+ret: 0         st: 0 flags:0  ts:-0.058330
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9961
-ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 158225 size: 12232
+ret: 0         st: 0 flags:1  ts: 2.835837
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 158232 size: 12232
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 158225 size: 12232
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 158232 size: 12232
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  30747 size: 10045
-ret: 0         st: 0 flags:0  ts:-0.480000
+ret: 0         st: 0 flags:0  ts:-0.481662
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9961
-ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 158225 size: 12232
+ret: 0         st: 0 flags:1  ts: 2.412505
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 158232 size: 12232
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 110330 size: 11970
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 110336 size: 11970
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9961
-ret: 0         st: 0 flags:0  ts:-0.920000
+ret: 0         st: 0 flags:0  ts:-0.904994
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:      0 size:  9961
-ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 158225 size: 12232
+ret: 0         st: 0 flags:1  ts: 1.989173
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 158232 size: 12232
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  67790 size: 10965
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 110336 size: 11970
 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.360000 pts: NOPTS    pos: 110330 size: 11970
+ret:-1         st: 0 flags:0  ts: 2.671674
+ret: 0         st: 0 flags:1  ts: 1.565841
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 110336 size: 11970
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  67790 size: 10965
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  67783 size: 10965
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/mpeg4_adap_avi b/tests/ref/seek/mpeg4_adap_avi
index 8397b41..c627014 100644
--- a/tests/ref/seek/mpeg4_adap_avi
+++ b/tests/ref/seek/mpeg4_adap_avi
@@ -2,13 +2,13 @@
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size:  6855
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 174456 size: 16883
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 174454 size: 16883
 ret: 0         st: 0 flags:0  ts: 0.800000
 ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  98228 size: 17063
 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.360000 pts: NOPTS    pos: 135598 size: 17525
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 135590 size: 17525
 ret: 0         st: 0 flags:0  ts: 0.360000
 ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  59454 size: 17261
 ret:-1         st: 0 flags:1  ts:-0.760000
@@ -18,29 +18,29 @@
 ret: 0         st: 0 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size:  6855
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 174456 size: 16883
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 174454 size: 16883
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 174456 size: 16883
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 174454 size: 16883
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  59454 size: 17261
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size:  6855
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 174456 size: 16883
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 174454 size: 16883
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 135598 size: 17525
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 135590 size: 17525
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size:  6855
 ret: 0         st: 0 flags:0  ts:-0.920000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size:  6855
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 174456 size: 16883
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 174454 size: 16883
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  98228 size: 17063
 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.360000 pts: NOPTS    pos: 135598 size: 17525
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 135590 size: 17525
 ret: 0         st:-1 flags:0  ts: 0.460008
 ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  98228 size: 17063
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/mpeg4_error_avi b/tests/ref/seek/mpeg4_error_avi
index 3c6fa21..ca77060 100644
--- a/tests/ref/seek/mpeg4_error_avi
+++ b/tests/ref/seek/mpeg4_error_avi
@@ -1,46 +1,46 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9564
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9729
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9564
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9729
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 113142 size: 12795
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 113194 size: 15063
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  71660 size: 11680
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  73154 size: 10235
 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: 113142 size: 12795
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 113194 size: 15063
 ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  36782 size: 10310
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  38240 size: 10303
 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:  71660 size: 11680
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  73154 size: 10235
 ret: 0         st: 0 flags:0  ts:-0.040000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9564
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9729
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 159370 size: 13895
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 163076 size: 13980
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 159370 size: 13895
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 163076 size: 13980
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  36782 size: 10310
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  38240 size: 10303
 ret: 0         st: 0 flags:0  ts:-0.480000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9564
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9729
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 159370 size: 13895
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 163076 size: 13980
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 113142 size: 12795
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 113194 size: 15063
 ret: 0         st:-1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9564
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9729
 ret: 0         st: 0 flags:0  ts:-0.920000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9564
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9729
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 159370 size: 13895
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 163076 size: 13980
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  71660 size: 11680
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  73154 size: 10235
 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: 113142 size: 12795
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 113194 size: 15063
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  36782 size: 10310
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  38240 size: 10303
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/mpeg4_mp4 b/tests/ref/seek/mpeg4_mp4
index 0600ed0..b1c8a19 100644
--- a/tests/ref/seek/mpeg4_mp4
+++ b/tests/ref/seek/mpeg4_mp4
@@ -3,46 +3,46 @@
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     44 size:  8719
 ret: 0         st:-1 flags:1  ts: 1.894167
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  75140 size: 10776
-ret: 0         st: 0 flags:0  ts: 0.800000
+ret: 0         st: 0 flags:0  ts: 0.788359
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  47228 size:  9634
-ret: 0         st: 0 flags:1  ts:-0.320000
+ret: 0         st: 0 flags:1  ts:-0.317500
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     44 size:  8719
 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:  75140 size: 10776
-ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:0  ts: 0.365000
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  23271 size:  8524
-ret: 0         st: 0 flags:1  ts:-0.760000
+ret: 0         st: 0 flags:1  ts:-0.740859
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     44 size:  8719
 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:  47228 size:  9634
-ret: 0         st: 0 flags:0  ts:-0.040000
+ret: 0         st: 0 flags:0  ts:-0.058359
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     44 size:  8719
-ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 106167 size: 11182
+ret: 0         st: 0 flags:1  ts: 2.835859
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 106181 size: 11182
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 106167 size: 11182
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 106181 size: 11182
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  23271 size:  8524
-ret: 0         st: 0 flags:0  ts:-0.480000
+ret: 0         st: 0 flags:0  ts:-0.481641
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     44 size:  8719
-ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 106167 size: 11182
+ret: 0         st: 0 flags:1  ts: 2.412500
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 106181 size: 11182
 ret: 0         st:-1 flags:0  ts: 1.306672
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  75140 size: 10776
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     44 size:  8719
-ret: 0         st: 0 flags:0  ts:-0.920000
+ret: 0         st: 0 flags:0  ts:-0.905000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     44 size:  8719
-ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 106167 size: 11182
+ret: 0         st: 0 flags:1  ts: 1.989141
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 106181 size: 11182
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  47228 size:  9634
 ret: 0         st:-1 flags:1  ts:-0.222493
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     44 size:  8719
-ret:-1         st: 0 flags:0  ts: 2.680000
-ret: 0         st: 0 flags:1  ts: 1.560000
+ret:-1         st: 0 flags:0  ts: 2.671641
+ret: 0         st: 0 flags:1  ts: 1.565859
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  75140 size: 10776
 ret: 0         st:-1 flags:0  ts: 0.460008
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  23271 size:  8524
diff --git a/tests/ref/seek/mpeg4_nr_avi b/tests/ref/seek/mpeg4_nr_avi
index c9af36f..f31619f 100644
--- a/tests/ref/seek/mpeg4_nr_avi
+++ b/tests/ref/seek/mpeg4_nr_avi
@@ -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:   5660 size: 10673
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 100640 size: 12464
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 100664 size: 12464
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  65480 size: 11181
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  65500 size: 11180
 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: 100640 size: 12464
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 100664 size: 12464
 ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  35312 size:  9987
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  35322 size:  9987
 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:  65480 size: 11181
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  65500 size: 11180
 ret: 0         st: 0 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size: 10673
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139424 size: 12911
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139384 size: 12911
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139424 size: 12911
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139384 size: 12911
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  35312 size:  9987
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  35322 size:  9987
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size: 10673
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139424 size: 12911
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139384 size: 12911
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 100640 size: 12464
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 100664 size: 12464
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size: 10673
 ret: 0         st: 0 flags:0  ts:-0.920000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size: 10673
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139424 size: 12911
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139384 size: 12911
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  65480 size: 11181
+ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  65500 size: 11180
 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: 100640 size: 12464
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 100664 size: 12464
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  35312 size:  9987
+ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  35322 size:  9987
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/mpeg4_qpel_avi b/tests/ref/seek/mpeg4_qpel_avi
index 1bb1504..63b474c 100644
--- a/tests/ref/seek/mpeg4_qpel_avi
+++ b/tests/ref/seek/mpeg4_qpel_avi
@@ -1,46 +1,46 @@
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 11942
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 11938
 ret: 0         st:-1 flags:0  ts:-1.000000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 11942
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 11938
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 141530 size: 15562
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 141538 size: 15554
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  64116 size: 13382
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  64122 size: 13377
 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.360000 pts: NOPTS    pos: 100368 size: 15057
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 100348 size: 15055
 ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  32818 size: 11813
+ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  32848 size: 11806
 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.880000 pts: NOPTS    pos:  64116 size: 13382
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  64122 size: 13377
 ret: 0         st: 0 flags:0  ts:-0.040000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 11942
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 11938
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 141530 size: 15562
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 141538 size: 15554
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 141530 size: 15562
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 141538 size: 15554
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  32818 size: 11813
+ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  32848 size: 11806
 ret: 0         st: 0 flags:0  ts:-0.480000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 11942
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 11938
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 141530 size: 15562
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 141538 size: 15554
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 100368 size: 15057
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 100348 size: 15055
 ret: 0         st:-1 flags:1  ts: 0.200839
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 11942
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 11938
 ret: 0         st: 0 flags:0  ts:-0.920000
-ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 11942
+ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 11938
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 141530 size: 15562
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 141538 size: 15554
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  64116 size: 13382
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  64122 size: 13377
 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.360000 pts: NOPTS    pos: 100368 size: 15057
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 100348 size: 15055
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  64116 size: 13382
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos:  64122 size: 13377
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/mpeg4_qprd_avi b/tests/ref/seek/mpeg4_qprd_avi
index 70374df..61605de 100644
--- a/tests/ref/seek/mpeg4_qprd_avi
+++ b/tests/ref/seek/mpeg4_qprd_avi
@@ -2,13 +2,13 @@
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 14873
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 211032 size: 14638
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 211042 size: 14638
 ret: 0         st: 0 flags:0  ts: 0.800000
 ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 150666 size: 14502
 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.360000 pts: NOPTS    pos: 180782 size: 14371
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 180790 size: 14371
 ret: 0         st: 0 flags:0  ts: 0.360000
 ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  93036 size: 29366
 ret:-1         st: 0 flags:1  ts:-0.760000
@@ -18,29 +18,29 @@
 ret: 0         st: 0 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 14873
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 211032 size: 14638
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 211042 size: 14638
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 211032 size: 14638
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 211042 size: 14638
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  93036 size: 29366
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 14873
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 211032 size: 14638
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 211042 size: 14638
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 180782 size: 14371
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 180790 size: 14371
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 14873
 ret: 0         st: 0 flags:0  ts:-0.920000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 14873
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 211032 size: 14638
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 211042 size: 14638
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 150666 size: 14502
 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.360000 pts: NOPTS    pos: 180782 size: 14371
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 180790 size: 14371
 ret: 0         st:-1 flags:0  ts: 0.460008
 ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 150666 size: 14502
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/mpeg4_rc_avi b/tests/ref/seek/mpeg4_rc_avi
index dc703d7..fbefdc0 100644
--- a/tests/ref/seek/mpeg4_rc_avi
+++ b/tests/ref/seek/mpeg4_rc_avi
@@ -2,45 +2,45 @@
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 15766
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 207968 size: 13826
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 207962 size: 13826
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 153812 size: 13382
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 153796 size: 13377
 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.360000 pts: NOPTS    pos: 180960 size: 13326
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 180958 size: 13326
 ret: 0         st: 0 flags:0  ts: 0.360000
-ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  94594 size: 32807
+ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  94586 size: 32807
 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.880000 pts: NOPTS    pos: 153812 size: 13382
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 153796 size: 13377
 ret: 0         st: 0 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 15766
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 207968 size: 13826
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 207962 size: 13826
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 207968 size: 13826
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 207962 size: 13826
 ret: 0         st:-1 flags:1  ts: 0.624171
-ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  94594 size: 32807
+ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  94586 size: 32807
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 15766
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 207968 size: 13826
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 207962 size: 13826
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 180960 size: 13326
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 180958 size: 13326
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 15766
 ret: 0         st: 0 flags:0  ts:-0.920000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 15766
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 207968 size: 13826
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 207962 size: 13826
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 153812 size: 13382
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 153796 size: 13377
 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.360000 pts: NOPTS    pos: 180960 size: 13326
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 180958 size: 13326
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 153812 size: 13382
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 153796 size: 13377
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/mpeg4_thread_avi b/tests/ref/seek/mpeg4_thread_avi
index 8c97827..6ddeeb2 100644
--- a/tests/ref/seek/mpeg4_thread_avi
+++ b/tests/ref/seek/mpeg4_thread_avi
@@ -2,45 +2,45 @@
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 14874
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 228222 size: 16324
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 228198 size: 16323
 ret: 0         st: 0 flags:0  ts: 0.800000
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 162162 size: 16475
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 162168 size: 16462
 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.360000 pts: NOPTS    pos: 195332 size: 16136
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 195342 size: 16153
 ret: 0         st: 0 flags:0  ts: 0.360000
 ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  97844 size: 33332
 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.880000 pts: NOPTS    pos: 162162 size: 16475
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 162168 size: 16462
 ret: 0         st: 0 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 14874
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 228222 size: 16324
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 228198 size: 16323
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 228222 size: 16324
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 228198 size: 16323
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.400000 pts: NOPTS    pos:  97844 size: 33332
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 14874
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 228222 size: 16324
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 228198 size: 16323
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 195332 size: 16136
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 195342 size: 16153
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 14874
 ret: 0         st: 0 flags:0  ts:-0.920000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: NOPTS    pos:   5660 size: 14874
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 228222 size: 16324
+ret: 0         st: 0 flags:1 dts: 1.840000 pts: NOPTS    pos: 228198 size: 16323
 ret: 0         st:-1 flags:0  ts: 0.883340
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 162162 size: 16475
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 162168 size: 16462
 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.360000 pts: NOPTS    pos: 195332 size: 16136
+ret: 0         st: 0 flags:1 dts: 1.360000 pts: NOPTS    pos: 195342 size: 16153
 ret: 0         st:-1 flags:0  ts: 0.460008
-ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 162162 size: 16475
+ret: 0         st: 0 flags:1 dts: 0.880000 pts: NOPTS    pos: 162168 size: 16462
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/seek/msmpeg4_avi b/tests/ref/seek/msmpeg4_avi
index fafd442..f95d615 100644
--- a/tests/ref/seek/msmpeg4_avi
+++ b/tests/ref/seek/msmpeg4_avi
@@ -18,15 +18,15 @@
 ret: 0         st: 0 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  8637
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 114276 size: 11180
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 114268 size: 11180
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 114276 size: 11180
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 114268 size: 11180
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29400 size:  8502
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  8637
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 114276 size: 11180
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 114268 size: 11180
 ret: 0         st:-1 flags:0  ts: 1.306672
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  82520 size: 10783
 ret: 0         st:-1 flags:1  ts: 0.200839
@@ -34,7 +34,7 @@
 ret: 0         st: 0 flags:0  ts:-0.920000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  8637
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 114276 size: 11180
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 114268 size: 11180
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  53858 size:  9624
 ret:-1         st:-1 flags:1  ts:-0.222493
diff --git a/tests/ref/seek/msmpeg4v2_avi b/tests/ref/seek/msmpeg4v2_avi
index 566ade0..21804fe 100644
--- a/tests/ref/seek/msmpeg4v2_avi
+++ b/tests/ref/seek/msmpeg4v2_avi
@@ -18,15 +18,15 @@
 ret: 0         st: 0 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9003
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116112 size: 11578
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116124 size: 11578
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116112 size: 11578
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116124 size: 11578
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29782 size:  8869
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9003
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116112 size: 11578
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116124 size: 11578
 ret: 0         st:-1 flags:0  ts: 1.306672
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83882 size: 11165
 ret: 0         st:-1 flags:1  ts: 0.200839
@@ -34,7 +34,7 @@
 ret: 0         st: 0 flags:0  ts:-0.920000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  9003
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116112 size: 11578
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116124 size: 11578
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54790 size: 10010
 ret:-1         st:-1 flags:1  ts:-0.222493
diff --git a/tests/ref/seek/rv10_rm b/tests/ref/seek/rv10_rm
index 123b03c..818040d 100644
--- a/tests/ref/seek/rv10_rm
+++ b/tests/ref/seek/rv10_rm
@@ -1,14 +1,13 @@
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    239 size: 10388
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    239 size: 10388
-ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  98608 size: 12303
+ret:-1         st:-1 flags:1  ts: 1.894167
 ret: 0         st: 0 flags:0  ts: 0.788000
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  61592 size: 11135
 ret: 0         st: 0 flags:1  ts:-0.317000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    239 size: 10388
 ret: 0         st:-1 flags:0  ts: 2.576668
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139556 size: 12738
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139566 size: 12738
 ret: 0         st:-1 flags:1  ts: 1.470835
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  98608 size: 12303
 ret: 0         st: 0 flags:0  ts: 0.365000
@@ -16,21 +15,21 @@
 ret: 0         st: 0 flags:1  ts:-0.741000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    239 size: 10388
 ret: 0         st:-1 flags:0  ts: 2.153336
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139556 size: 12738
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139566 size: 12738
 ret: 0         st:-1 flags:1  ts: 1.047503
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  61592 size: 11135
 ret: 0         st: 0 flags:0  ts:-0.058000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    239 size: 10388
 ret: 0         st: 0 flags:1  ts: 2.836000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139556 size: 12738
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139566 size: 12738
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139556 size: 12738
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139566 size: 12738
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  31132 size: 10097
 ret: 0         st: 0 flags:0  ts:-0.482000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    239 size: 10388
 ret: 0         st: 0 flags:1  ts: 2.413000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139556 size: 12738
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139566 size: 12738
 ret: 0         st:-1 flags:0  ts: 1.306672
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  98608 size: 12303
 ret: 0         st:-1 flags:1  ts: 0.200839
@@ -38,13 +37,13 @@
 ret: 0         st: 0 flags:0  ts:-0.905000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    239 size: 10388
 ret: 0         st: 0 flags:1  ts: 1.989000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139556 size: 12738
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139566 size: 12738
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  61592 size: 11135
 ret: 0         st:-1 flags:1  ts:-0.222493
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    239 size: 10388
 ret: 0         st: 0 flags:0  ts: 2.672000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139556 size: 12738
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139566 size: 12738
 ret: 0         st: 0 flags:1  ts: 1.566000
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  98608 size: 12303
 ret: 0         st:-1 flags:0  ts: 0.460008
diff --git a/tests/ref/seek/rv20_rm b/tests/ref/seek/rv20_rm
index f2b24e3..7f1ad39 100644
--- a/tests/ref/seek/rv20_rm
+++ b/tests/ref/seek/rv20_rm
@@ -8,7 +8,7 @@
 ret: 0         st: 0 flags:1  ts:-0.317000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    239 size:  9361
 ret: 0         st:-1 flags:0  ts: 2.576668
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139145 size: 11803
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139147 size: 11803
 ret: 0         st:-1 flags:1  ts: 1.470835
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  98158 size: 11344
 ret: 0         st: 0 flags:0  ts: 0.365000
@@ -16,21 +16,21 @@
 ret: 0         st: 0 flags:1  ts:-0.741000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    239 size:  9361
 ret: 0         st:-1 flags:0  ts: 2.153336
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139145 size: 11803
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139147 size: 11803
 ret: 0         st:-1 flags:1  ts: 1.047503
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  61133 size: 10166
 ret: 0         st: 0 flags:0  ts:-0.058000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    239 size:  9361
 ret: 0         st: 0 flags:1  ts: 2.836000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139145 size: 11803
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139147 size: 11803
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139145 size: 11803
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139147 size: 11803
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  30753 size:  9101
 ret: 0         st: 0 flags:0  ts:-0.482000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    239 size:  9361
 ret: 0         st: 0 flags:1  ts: 2.413000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139145 size: 11803
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139147 size: 11803
 ret: 0         st:-1 flags:0  ts: 1.306672
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  98158 size: 11344
 ret: 0         st:-1 flags:1  ts: 0.200839
@@ -38,13 +38,13 @@
 ret: 0         st: 0 flags:0  ts:-0.905000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    239 size:  9361
 ret: 0         st: 0 flags:1  ts: 1.989000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139145 size: 11803
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139147 size: 11803
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  61133 size: 10166
 ret: 0         st:-1 flags:1  ts:-0.222493
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:    239 size:  9361
 ret: 0         st: 0 flags:0  ts: 2.672000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139145 size: 11803
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 139147 size: 11803
 ret: 0         st: 0 flags:1  ts: 1.566000
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  98158 size: 11344
 ret: 0         st:-1 flags:0  ts: 0.460008
diff --git a/tests/ref/seek/svq1_mov b/tests/ref/seek/svq1_mov
index 17bb99e..33fe33e 100644
--- a/tests/ref/seek/svq1_mov
+++ b/tests/ref/seek/svq1_mov
@@ -3,46 +3,46 @@
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 22300
 ret: 0         st:-1 flags:1  ts: 1.894167
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 517568 size: 25636
-ret: 0         st: 0 flags:0  ts: 0.800000
+ret: 0         st: 0 flags:0  ts: 0.788359
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 326556 size: 23552
-ret: 0         st: 0 flags:1  ts:-0.320000
+ret: 0         st: 0 flags:1  ts:-0.317500
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 22300
 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: 517568 size: 25636
-ret: 0         st: 0 flags:0  ts: 0.360000
+ret: 0         st: 0 flags:0  ts: 0.365000
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 157040 size: 21896
-ret: 0         st: 0 flags:1  ts:-0.760000
+ret: 0         st: 0 flags:1  ts:-0.740859
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 22300
 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: 326556 size: 23552
-ret: 0         st: 0 flags:0  ts:-0.040000
+ret: 0         st: 0 flags:0  ts:-0.058359
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 22300
-ret: 0         st: 0 flags:1  ts: 2.840000
+ret: 0         st: 0 flags:1  ts: 2.835859
 ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 722804 size: 25888
 ret: 0         st:-1 flags:0  ts: 1.730004
 ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 722804 size: 25888
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 157040 size: 21896
-ret: 0         st: 0 flags:0  ts:-0.480000
+ret: 0         st: 0 flags:0  ts:-0.481641
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 22300
-ret: 0         st: 0 flags:1  ts: 2.400000
+ret: 0         st: 0 flags:1  ts: 2.412500
 ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 722804 size: 25888
 ret: 0         st:-1 flags:0  ts: 1.306672
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 517568 size: 25636
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 22300
-ret: 0         st: 0 flags:0  ts:-0.920000
+ret: 0         st: 0 flags:0  ts:-0.905000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 22300
-ret: 0         st: 0 flags:1  ts: 2.000000
+ret: 0         st: 0 flags:1  ts: 1.989141
 ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 722804 size: 25888
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 326556 size: 23552
 ret: 0         st:-1 flags:1  ts:-0.222493
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:     36 size: 22300
-ret:-1         st: 0 flags:0  ts: 2.680000
-ret: 0         st: 0 flags:1  ts: 1.560000
+ret:-1         st: 0 flags:0  ts: 2.671641
+ret: 0         st: 0 flags:1  ts: 1.565859
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 517568 size: 25636
 ret: 0         st:-1 flags:0  ts: 0.460008
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 157040 size: 21896
diff --git a/tests/ref/seek/wmv1_avi b/tests/ref/seek/wmv1_avi
index 8739c96..836f7b6 100644
--- a/tests/ref/seek/wmv1_avi
+++ b/tests/ref/seek/wmv1_avi
@@ -18,15 +18,15 @@
 ret: 0         st: 0 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  8990
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 115824 size: 11487
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 115818 size: 11486
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 115824 size: 11487
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 115818 size: 11486
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29806 size:  8796
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  8990
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 115824 size: 11487
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 115818 size: 11486
 ret: 0         st:-1 flags:0  ts: 1.306672
 ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83754 size: 11099
 ret: 0         st:-1 flags:1  ts: 0.200839
@@ -34,7 +34,7 @@
 ret: 0         st: 0 flags:0  ts:-0.920000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5660 size:  8990
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 115824 size: 11487
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 115818 size: 11486
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54770 size:  9931
 ret:-1         st:-1 flags:1  ts:-0.222493
diff --git a/tests/ref/seek/wmv2_avi b/tests/ref/seek/wmv2_avi
index ca01a39..af03bea 100644
--- a/tests/ref/seek/wmv2_avi
+++ b/tests/ref/seek/wmv2_avi
@@ -2,13 +2,13 @@
 ret: 0         st:-1 flags:0  ts:-1.000000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5664 size:  8917
 ret: 0         st:-1 flags:1  ts: 1.894167
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83802 size: 11170
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83802 size: 11169
 ret: 0         st: 0 flags:0  ts: 0.800000
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54584 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:  83802 size: 11170
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83802 size: 11169
 ret: 0         st: 0 flags:0  ts: 0.360000
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29644 size:  8839
 ret:-1         st: 0 flags:1  ts:-0.760000
@@ -18,29 +18,29 @@
 ret: 0         st: 0 flags:0  ts:-0.040000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5664 size:  8917
 ret: 0         st: 0 flags:1  ts: 2.840000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116070 size: 11554
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116056 size: 11554
 ret: 0         st:-1 flags:0  ts: 1.730004
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116070 size: 11554
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116056 size: 11554
 ret: 0         st:-1 flags:1  ts: 0.624171
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29644 size:  8839
 ret: 0         st: 0 flags:0  ts:-0.480000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5664 size:  8917
 ret: 0         st: 0 flags:1  ts: 2.400000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116070 size: 11554
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116056 size: 11554
 ret: 0         st:-1 flags:0  ts: 1.306672
-ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83802 size: 11170
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83802 size: 11169
 ret: 0         st:-1 flags:1  ts: 0.200839
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5664 size:  8917
 ret: 0         st: 0 flags:0  ts:-0.920000
 ret: 0         st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:   5664 size:  8917
 ret: 0         st: 0 flags:1  ts: 2.000000
-ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116070 size: 11554
+ret: 0         st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 116056 size: 11554
 ret: 0         st:-1 flags:0  ts: 0.883340
 ret: 0         st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:  54584 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:  83802 size: 11170
+ret: 0         st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos:  83802 size: 11169
 ret: 0         st:-1 flags:0  ts: 0.460008
 ret: 0         st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:  29644 size:  8839
 ret:-1         st:-1 flags:1  ts:-0.645825
diff --git a/tests/ref/vsynth1/cljr b/tests/ref/vsynth1/cljr
new file mode 100644
index 0000000..6002bbb
--- /dev/null
+++ b/tests/ref/vsynth1/cljr
@@ -0,0 +1,4 @@
+041982e4fa83428c621a127647d47b3f *./tests/data/vsynth1/cljr.avi
+5075660 ./tests/data/vsynth1/cljr.avi
+e1c4c96c74de3435d0f9f6118c5ed9b5 *./tests/data/cljr.vsynth1.out.yuv
+stddev:   30.53 PSNR: 18.43 MAXDIFF:  225 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth1/yuv b/tests/ref/vsynth1/yuv
new file mode 100644
index 0000000..6d8b143
--- /dev/null
+++ b/tests/ref/vsynth1/yuv
@@ -0,0 +1,4 @@
+eaa66c3b27a2602e882befe154a8b119 *./tests/data/vsynth1/yuv.avi
+7610060 ./tests/data/vsynth1/yuv.avi
+c5ccac874dbf808e9088bc3107860042 *./tests/data/yuv.vsynth1.out.yuv
+stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth2/cljr b/tests/ref/vsynth2/cljr
new file mode 100644
index 0000000..f4cf7d1
--- /dev/null
+++ b/tests/ref/vsynth2/cljr
@@ -0,0 +1,4 @@
+fdc1926e0a599de94513f0a3472b598f *./tests/data/vsynth2/cljr.avi
+5075660 ./tests/data/vsynth2/cljr.avi
+7df03229ee6361ea11a0d83d4926cb10 *./tests/data/cljr.vsynth2.out.yuv
+stddev:   10.30 PSNR: 27.87 MAXDIFF:   65 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth2/huffyuv b/tests/ref/vsynth2/huffyuv
new file mode 100644
index 0000000..e59b53c
--- /dev/null
+++ b/tests/ref/vsynth2/huffyuv
@@ -0,0 +1,4 @@
+ed66182be0d515e8b6cb970ad63162da *./tests/data/vsynth2/huffyuv.avi
+6455232 ./tests/data/vsynth2/huffyuv.avi
+dde5895817ad9d219f79a52d0bdfb001 *./tests/data/huffyuv.vsynth2.out.yuv
+stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth2/yuv b/tests/ref/vsynth2/yuv
new file mode 100644
index 0000000..699ebc9
--- /dev/null
+++ b/tests/ref/vsynth2/yuv
@@ -0,0 +1,4 @@
+3d5ee6d2023bc15bba898819e4977e46 *./tests/data/vsynth2/yuv.avi
+7610060 ./tests/data/vsynth2/yuv.avi
+dde5895817ad9d219f79a52d0bdfb001 *./tests/data/yuv.vsynth2.out.yuv
+stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  7603200/  7603200
diff --git a/tests/regression-funcs.sh b/tests/regression-funcs.sh
index ce5aee8..7538795 100755
--- a/tests/regression-funcs.sh
+++ b/tests/regression-funcs.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# common regression functions for avconv
+# common regression functions for ffmpeg
 #
 #
 
@@ -11,6 +11,7 @@
 target_path=$5
 threads=${6:-1}
 cpuflags=${8:-all}
+samples=$9
 
 datadir="./tests/data"
 target_datadir="${target_path}/${datadir}"
@@ -19,10 +20,12 @@
 outfile="$datadir/$test_ref/"
 
 # various files
-avconv="$target_exec ${target_path}/avconv"
+ffmpeg="$target_exec ${target_path}/ffmpeg"
 raw_src="${target_path}/$raw_src_dir/%02d.pgm"
 raw_dst="$datadir/$this.out.yuv"
 pcm_src="$target_datadir/asynth1.sw"
+pcm_src_1ch="$target_datadir/asynth-16000-1.wav"
+pcm_ref_1ch="$datadir/$test_ref-16000-1.ref.wav"
 crcfile="$datadir/$this.crc"
 target_crcfile="$target_datadir/$this.crc"
 
@@ -47,8 +50,8 @@
 
 run_avconv()
 {
-    $echov $avconv $AVCONV_OPTS $*
-    $avconv $AVCONV_OPTS $*
+    $echov $ffmpeg $AVCONV_OPTS $*
+    $ffmpeg $AVCONV_OPTS $*
 }
 
 do_avconv()
@@ -61,6 +64,21 @@
     echo $(wc -c $f)
 }
 
+do_avconv_nomd5()
+{
+    f="$1"
+    shift
+    set -- $* ${target_path}/$f
+    run_avconv $*
+    if [ $f = $raw_dst ] ; then
+        $tiny_psnr $f $raw_ref
+    elif [ $f = $pcm_dst ] ; then
+        $tiny_psnr $f $pcm_ref 2
+    else
+        echo $(wc -c $f)
+    fi
+}
+
 do_avconv_crc()
 {
     f="$1"
diff --git a/tests/rotozoom.c b/tests/rotozoom.c
index 69c88c2..cfa7f81 100644
--- a/tests/rotozoom.c
+++ b/tests/rotozoom.c
@@ -3,20 +3,20 @@
  *
  * copyright (c) Sebastien Bechet <s.bechet@av7.net>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/tests/test.ffmeta b/tests/test.ffmeta
new file mode 100644
index 0000000..ad37b02
--- /dev/null
+++ b/tests/test.ffmeta
@@ -0,0 +1,9 @@
+;FFMETADATA1
+title=ffprobe test file
+comment='A comment with CSV, XML & JSON special chars': <tag value=\"x\">
+comment2=I ♥ Üñîçød€
+[STREAM]
+E=mc²
+[STREAM]
+title=foobar
+duration_ts=field-and-tags-conflict-attempt
diff --git a/tests/tiny_psnr.c b/tests/tiny_psnr.c
index 5db2662..b912061 100644
--- a/tests/tiny_psnr.c
+++ b/tests/tiny_psnr.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -54,6 +54,21 @@
     582360139072LL,
 };
 
+#if 0
+// 16.16 fixpoint exp()
+static unsigned int exp16(unsigned int a){
+    int i;
+    int out= 1<<16;
+
+    for(i=19;i>=0;i--){
+        if(a&(1<<i))
+            out= (out*exp16_table[i] + (1<<15))>>16;
+    }
+
+    return out;
+}
+#endif
+
 // 16.16 fixpoint log()
 static int64_t log16(uint64_t a)
 {
@@ -107,78 +122,48 @@
     return v.f;
 }
 
-int main(int argc, char *argv[])
+static int run_psnr(FILE *f[2], int len, int shift, int skip_bytes)
 {
     int i, j;
     uint64_t sse = 0;
     uint64_t dev;
-    FILE *f[2];
     uint8_t buf[2][SIZE];
     uint64_t psnr;
-    int len = 1;
-    int64_t max;
-    int shift      = argc < 5 ? 0 : atoi(argv[4]);
-    int skip_bytes = argc < 6 ? 0 : atoi(argv[5]);
+    int64_t max    = (1LL << (8 * len)) - 1;
     int size0      = 0;
     int size1      = 0;
     int maxdist    = 0;
+    int noseek;
 
-    if (argc < 3) {
-        printf("tiny_psnr <file1> <file2> [<elem size> [<shift> [<skip bytes>]]]\n");
-        printf("WAV headers are skipped automatically.\n");
-        return 1;
-    }
+    noseek = fseek(f[0], 0, SEEK_SET) ||
+             fseek(f[1], 0, SEEK_SET);
 
-    if (argc > 3) {
-        if (!strcmp(argv[3], "u8")) {
-            len = 1;
-        } else if (!strcmp(argv[3], "s16")) {
-            len = 2;
-        } else if (!strcmp(argv[3], "f32")) {
-            len = 4;
-        } else {
-            char *end;
-            len = strtol(argv[3], &end, 0);
-            if (*end || len > 2) {
-                fprintf(stderr, "Unsupported sample format: %s\n", argv[3]);
+    if (!noseek) {
+        for (i = 0; i < 2; i++) {
+            uint8_t *p = buf[i];
+            if (fread(p, 1, 12, f[i]) != 12)
                 return 1;
-            }
-        }
-    }
-
-    max = (1 << (8 * len)) - 1;
-
-    f[0] = fopen(argv[1], "rb");
-    f[1] = fopen(argv[2], "rb");
-    if (!f[0] || !f[1]) {
-        fprintf(stderr, "Could not open input files.\n");
-        return 1;
-    }
-
-    for (i = 0; i < 2; i++) {
-        uint8_t *p = buf[i];
-        if (fread(p, 1, 12, f[i]) != 12)
-            return 1;
-        if (!memcmp(p, "RIFF", 4) &&
-            !memcmp(p + 8, "WAVE", 4)) {
-            if (fread(p, 1, 8, f[i]) != 8)
-                return 1;
-            while (memcmp(p, "data", 4)) {
-                int s = p[4] | p[5] << 8 | p[6] << 16 | p[7] << 24;
-                fseek(f[i], s, SEEK_CUR);
+            if (!memcmp(p, "RIFF", 4) &&
+                !memcmp(p + 8, "WAVE", 4)) {
                 if (fread(p, 1, 8, f[i]) != 8)
                     return 1;
+                while (memcmp(p, "data", 4)) {
+                    int s = p[4] | p[5] << 8 | p[6] << 16 | p[7] << 24;
+                    fseek(f[i], s, SEEK_CUR);
+                    if (fread(p, 1, 8, f[i]) != 8)
+                        return 1;
+                }
+            } else {
+                fseek(f[i], -12, SEEK_CUR);
             }
-        } else {
-            fseek(f[i], -12, SEEK_CUR);
         }
+
+        fseek(f[shift < 0], abs(shift), SEEK_CUR);
+
+        fseek(f[0], skip_bytes, SEEK_CUR);
+        fseek(f[1], skip_bytes, SEEK_CUR);
     }
 
-    fseek(f[shift < 0], abs(shift), SEEK_CUR);
-
-    fseek(f[0], skip_bytes, SEEK_CUR);
-    fseek(f[1], skip_bytes, SEEK_CUR);
-
     for (;;) {
         int s0 = fread(buf[0], 1, SIZE, f[0]);
         int s1 = fread(buf[1], 1, SIZE, f[1]);
@@ -222,5 +207,58 @@
            (int)(dev / F), (int)(dev % F),
            (int)(psnr / F), (int)(psnr % F),
            maxdist, size0, size1);
+    return psnr;
+}
+
+int main(int argc, char *argv[])
+{
+    FILE *f[2];
+    int len = 1;
+    int shift_first= argc < 5 ? 0 : atoi(argv[4]);
+    int skip_bytes = argc < 6 ? 0 : atoi(argv[5]);
+    int shift_last = shift_first + (argc < 7 ? 0 : atoi(argv[6]));
+    int shift;
+    int max_psnr   = -1;
+    int max_psnr_shift = 0;
+
+    if (argc > 3) {
+        if (!strcmp(argv[3], "u8")) {
+            len = 1;
+        } else if (!strcmp(argv[3], "s16")) {
+            len = 2;
+        } else if (!strcmp(argv[3], "f32")) {
+            len = 4;
+        } else {
+            char *end;
+            len = strtol(argv[3], &end, 0);
+            if (*end || len > 2) {
+                fprintf(stderr, "Unsupported sample format: %s\n", argv[3]);
+                return 1;
+            }
+        }
+    }
+
+    if (argc < 3) {
+        printf("tiny_psnr <file1> <file2> [<elem size> [<shift> [<skip bytes> [<shift search range>]]]]\n");
+        printf("WAV headers are skipped automatically.\n");
+        return 1;
+    }
+
+    f[0] = fopen(argv[1], "rb");
+    f[1] = fopen(argv[2], "rb");
+    if (!f[0] || !f[1]) {
+        fprintf(stderr, "Could not open input files.\n");
+        return 1;
+    }
+
+    for (shift = shift_first; shift <= shift_last; shift++) {
+        int psnr = run_psnr(f, len, shift, skip_bytes);
+        if (psnr > max_psnr || (shift < 0 && psnr == max_psnr)) {
+            max_psnr = psnr;
+            max_psnr_shift = shift;
+        }
+    }
+    if (shift_last > shift_first)
+        printf("Best PSNR is %3d.%02d for shift %i\n", (int)(max_psnr / F), (int)(max_psnr % F), max_psnr_shift);
     return 0;
 }
diff --git a/tests/utils.c b/tests/utils.c
index 2fdc491..e8ef06f 100644
--- a/tests/utils.c
+++ b/tests/utils.c
@@ -1,18 +1,20 @@
 /*
- * This file is part of Libav.
+ * copyright (c) Sebastien Bechet <s.bechet@av7.net>
  *
- * Libav is free software; you can redistribute it and/or
+ * 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.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/tests/videogen.c b/tests/videogen.c
index 0b7f67e..94e6e77 100644
--- a/tests/videogen.c
+++ b/tests/videogen.c
@@ -4,20 +4,20 @@
  *
  * Copyright (c) 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/tools/bisect-create b/tools/bisect-create
new file mode 100755
index 0000000..fc60e86
--- /dev/null
+++ b/tools/bisect-create
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+set -e
+
+if test "bisect-create" = "`basename $0`" ; then
+    echo tools/ffbisect created
+    git show master:tools/bisect-create > tools/ffbisect
+    chmod u+x tools/ffbisect
+    exit 1
+fi
+
+if ! git show master:tools/bisect-create | diff - tools/ffbisect > /dev/null ; then
+    echo updating tools/ffbisect script to HEAD.
+    git show master:tools/bisect-create > tools/ffbisect
+    chmod u+x tools/ffbisect
+    tools/ffbisect $*
+    exit 0
+fi
+
+case "$1" in
+    need)
+        case $2 in
+            ffmpeg|ffplay|ffprobe|ffserver)
+                echo $2.c >> tools/bisect.need
+            ;;
+        esac
+    ;;
+    start|reset)
+        echo . > tools/bisect.need
+        git bisect $*
+    ;;
+    skip)
+        git bisect $*
+    ;;
+    good|bad)
+        git bisect $*
+
+        until ls `cat tools/bisect.need` > /dev/null 2> /dev/null; do
+            git bisect skip || break
+        done
+    ;;
+    run)
+       shift # remove "run" from arguments
+       git bisect run sh -c "ls \`cat tools/bisect.need\` > /dev/null 2> /dev/null || exit 125; \"\$@\"" sh "$@"
+    ;;
+esac
diff --git a/tools/build_libstagefright b/tools/build_libstagefright
new file mode 100644
index 0000000..8b3a093
--- /dev/null
+++ b/tools/build_libstagefright
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+if [ "$NDK" = "" ]; then
+    echo NDK variable not set, assuming ${HOME}/android-ndk
+    export NDK=${HOME}/android-ndk
+fi
+
+echo "Fetching Android system headers"
+git clone --depth=1 --branch gingerbread-release git://github.com/CyanogenMod/android_frameworks_base.git ../android-source/frameworks/base
+git clone --depth=1 --branch gingerbread-release git://github.com/CyanogenMod/android_system_core.git ../android-source/system/core
+
+echo "Fetching Android libraries for linking"
+# Libraries from any froyo/gingerbread device/emulator should work
+# fine, since the symbols used should be available on most of them.
+if [ ! -d "../android-libs" ]; then
+    if [ ! -f "../update-cm-7.0.3-N1-signed.zip" ]; then
+        wget http://download.cyanogenmod.com/get/update-cm-7.0.3-N1-signed.zip -P../
+    fi
+    unzip ../update-cm-7.0.3-N1-signed.zip system/lib/* -d../
+    mv ../system/lib ../android-libs
+    rmdir ../system
+fi
+
+
+SYSROOT=$NDK/platforms/android-9/arch-arm
+# Expand the prebuilt/* path into the correct one
+TOOLCHAIN=`echo $NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/*-x86`
+export PATH=$TOOLCHAIN/bin:$PATH
+ANDROID_SOURCE=../android-source
+ANDROID_LIBS=../android-libs
+ABI="armeabi-v7a"
+
+rm -rf ../build/stagefright
+mkdir -p ../build/stagefright
+
+DEST=../build/stagefright
+FLAGS="--target-os=linux --cross-prefix=arm-linux-androideabi- --arch=arm --cpu=armv7-a"
+FLAGS="$FLAGS --sysroot=$SYSROOT"
+FLAGS="$FLAGS --disable-avdevice --disable-decoder=h264 --disable-decoder=h264_vdpau --enable-libstagefright-h264"
+
+EXTRA_CFLAGS="-I$ANDROID_SOURCE/frameworks/base/include -I$ANDROID_SOURCE/system/core/include"
+EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/frameworks/base/media/libstagefright"
+EXTRA_CFLAGS="$EXTRA_CFLAGS -I$ANDROID_SOURCE/frameworks/base/include/media/stagefright/openmax"
+EXTRA_CFLAGS="$EXTRA_CFLAGS -I$NDK/sources/cxx-stl/gnu-libstdc++/include -I$NDK/sources/cxx-stl/gnu-libstdc++/libs/$ABI/include"
+
+EXTRA_CFLAGS="$EXTRA_CFLAGS -march=armv7-a -mfloat-abi=softfp -mfpu=neon"
+EXTRA_LDFLAGS="-Wl,--fix-cortex-a8 -L$ANDROID_LIBS -Wl,-rpath-link,$ANDROID_LIBS -L$NDK/sources/cxx-stl/gnu-libstdc++/libs/$ABI"
+EXTRA_CXXFLAGS="-Wno-multichar -fno-exceptions -fno-rtti"
+DEST="$DEST/$ABI"
+FLAGS="$FLAGS --prefix=$DEST"
+
+mkdir -p $DEST
+
+echo $FLAGS --extra-cflags="$EXTRA_CFLAGS" --extra-ldflags="$EXTRA_LDFLAGS" --extra-cxxflags="$EXTRA_CXXFLAGS" > $DEST/info.txt
+./configure $FLAGS --extra-cflags="$EXTRA_CFLAGS" --extra-ldflags="$EXTRA_LDFLAGS" --extra-cxxflags="$EXTRA_CXXFLAGS" | tee $DEST/configuration.txt
+[ $PIPESTATUS == 0 ] || exit 1
+make clean
+make -j4 || exit 1
diff --git a/tools/clean-diff b/tools/clean-diff
new file mode 100755
index 0000000..4600702
--- /dev/null
+++ b/tools/clean-diff
@@ -0,0 +1,11 @@
+#!/bin/sh
+sed '/^+[^+]/!s/	/TaBBaT/g' |\
+ expand -t $(seq -s , 9 8 200) |\
+ sed 's/TaBBaT/	/g' |\
+ sed '/^+[^+]/s/ * $//' |\
+ tr -d '\015' |\
+ tr '\n' '°' |\
+ sed 's/\(@@[^@]*@@°[^@]*\)/\n\1/g' |\
+ egrep -v '@@[^@]*@@°(( [^°]*°)|([+-][[:space:]]*°)|(-[[:space:]]*([^°]*)°\+[[:space:]]*\5°))*$' |\
+ tr -d '\n' |\
+ tr '°' '\n'
diff --git a/tools/enum_options.c b/tools/enum_options.c
new file mode 100644
index 0000000..45ac727
--- /dev/null
+++ b/tools/enum_options.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2011 Anton Khirnov
+ *
+ * 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
+ */
+
+/*
+ * enumerate avoptions and format them in texinfo format
+ */
+
+#include <string.h>
+
+#include "libavformat/avformat.h"
+#include "libavcodec/avcodec.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+
+static void print_usage(void)
+{
+    fprintf(stderr, "Usage: enum_options type\n"
+            "type: format codec\n");
+    exit(1);
+}
+
+static void print_option(const AVClass *class, const AVOption *o)
+{
+    printf("@item -%s @var{", o->name);
+    switch (o->type) {
+    case FF_OPT_TYPE_BINARY:   printf("hexadecimal string"); break;
+    case FF_OPT_TYPE_STRING:   printf("string");             break;
+    case FF_OPT_TYPE_INT:
+    case FF_OPT_TYPE_INT64:    printf("integer");            break;
+    case FF_OPT_TYPE_FLOAT:
+    case FF_OPT_TYPE_DOUBLE:   printf("float");              break;
+    case FF_OPT_TYPE_RATIONAL: printf("rational number");    break;
+    case FF_OPT_TYPE_FLAGS:    printf("flags");              break;
+    default:                   printf("value");              break;
+    }
+    printf("} (@emph{");
+
+    if (o->flags & AV_OPT_FLAG_ENCODING_PARAM) {
+        printf("input");
+        if (o->flags & AV_OPT_FLAG_ENCODING_PARAM)
+            printf("/");
+    }
+    if (o->flags & AV_OPT_FLAG_ENCODING_PARAM)
+        printf("output");
+
+    printf("})\n");
+    if (o->help)
+        printf("%s\n", o->help);
+
+    if (o->unit) {
+        const AVOption *u = NULL;
+        printf("\nPossible values:\n@table @samp\n");
+
+        while ((u = av_next_option(&class, u)))
+            if (u->type == FF_OPT_TYPE_CONST && u->unit && !strcmp(u->unit, o->unit))
+                printf("@item %s\n%s\n", u->name, u->help ? u->help : "");
+        printf("@end table\n");
+    }
+}
+
+static void show_opts(const AVClass *class)
+{
+    const AVOption *o = NULL;
+
+    printf("@table @option\n");
+    while ((o = av_next_option(&class, o)))
+        if (o->type != FF_OPT_TYPE_CONST)
+            print_option(class, o);
+    printf("@end table\n");
+}
+
+static void show_format_opts(void)
+{
+    AVInputFormat *iformat = NULL;
+    AVOutputFormat *oformat = NULL;
+
+    printf("@section Generic format AVOptions\n");
+    show_opts(avformat_get_class());
+
+    printf("@section Format-specific AVOptions\n");
+    while ((iformat = av_iformat_next(iformat))) {
+        if (!iformat->priv_class)
+            continue;
+        printf("@subsection %s AVOptions\n", iformat->priv_class->class_name);
+        show_opts(iformat->priv_class);
+    }
+    while ((oformat = av_oformat_next(oformat))) {
+        if (!oformat->priv_class)
+            continue;
+        printf("@subsection %s AVOptions\n", oformat->priv_class->class_name);
+        show_opts(oformat->priv_class);
+    }
+}
+
+static void show_codec_opts(void)
+{
+    AVCodec *c = NULL;
+
+    printf("@section Generic codec AVOptions\n");
+    show_opts(avcodec_get_class());
+
+    printf("@section Codec-specific AVOptions\n");
+    while ((c = av_codec_next(c))) {
+        if (!c->priv_class)
+            continue;
+        printf("@subsection %s AVOptions\n", c->priv_class->class_name);
+        show_opts(c->priv_class);
+    }
+}
+
+int main(int argc, char **argv)
+{
+    if (argc < 2)
+        print_usage();
+
+    av_register_all();
+
+    if (!strcmp(argv[1], "format"))
+        show_format_opts();
+    else if (!strcmp(argv[1], "codec"))
+        show_codec_opts();
+    else
+        print_usage();
+
+    return 0;
+}
diff --git a/tools/ffeval.c b/tools/ffeval.c
new file mode 100644
index 0000000..027cd48
--- /dev/null
+++ b/tools/ffeval.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2012 Stefano Sabatini
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <unistd.h>             /* getopt */
+#include "libavutil/eval.h"
+
+/**
+ * @file
+ * simple arithmetic expression evaluator
+ */
+
+static void usage(void)
+{
+    printf("Simple expression evalutor, please *don't* turn me to a feature-complete language interpreter\n");
+    printf("usage: ffeval [OPTIONS]\n");
+    printf("\n"
+           "Options:\n"
+           "-e                echo each input line on output\n"
+           "-h                print this help\n"
+           "-i INFILE         set INFILE as input file, stdin if omitted\n"
+           "-o OUTFILE        set OUTFILE as output file, stdout if omitted\n"
+           "-p PROMPT         set output prompt\n");
+}
+
+#define MAX_BLOCK_SIZE SIZE_MAX
+
+int main(int argc, char **argv)
+{
+    size_t buf_size = 256;
+    char *buf = av_malloc(buf_size);
+    const char *outfilename = NULL, *infilename = NULL;
+    FILE *outfile = NULL, *infile = NULL;
+    const char *prompt = "=> ";
+    int count = 0, echo = 0;
+    char c;
+
+    av_max_alloc(MAX_BLOCK_SIZE);
+
+    while ((c = getopt(argc, argv, "ehi:o:p:")) != -1) {
+        switch (c) {
+        case 'e':
+            echo = 1;
+            break;
+        case 'h':
+            usage();
+            return 0;
+        case 'i':
+            infilename = optarg;
+            break;
+        case 'o':
+            outfilename = optarg;
+            break;
+        case 'p':
+            prompt = optarg;
+            break;
+        case '?':
+            return 1;
+        }
+    }
+
+    if (!infilename || !strcmp(infilename, "-"))
+        infilename = "/dev/stdin";
+    infile = fopen(infilename, "r");
+    if (!infile) {
+        fprintf(stderr, "Impossible to open input file '%s': %s\n", infilename, strerror(errno));
+        return 1;
+    }
+
+    if (!outfilename || !strcmp(outfilename, "-"))
+        outfilename = "/dev/stdout";
+    outfile = fopen(outfilename, "w");
+    if (!outfile) {
+        fprintf(stderr, "Impossible to open output file '%s': %s\n", outfilename, strerror(errno));
+        return 1;
+    }
+
+    while ((c = fgetc(infile)) != EOF) {
+        if (c == '\n') {
+            double d;
+
+            buf[count] = 0;
+            if (buf[0] != '#') {
+                av_expr_parse_and_eval(&d, buf,
+                                       NULL, NULL,
+                                       NULL, NULL, NULL, NULL, NULL, 0, NULL);
+                if (echo)
+                    fprintf(outfile, "%s ", buf);
+                fprintf(outfile, "%s%f\n", prompt, d);
+            }
+            count = 0;
+        } else {
+            if (count >= buf_size-1) {
+                if (buf_size == MAX_BLOCK_SIZE) {
+                    av_log(NULL, AV_LOG_ERROR, "Memory allocation problem, "
+                           "max block size '%zd' reached\n", MAX_BLOCK_SIZE);
+                    return 1;
+                }
+                buf_size = FFMIN(buf_size, MAX_BLOCK_SIZE / 2) * 2;
+                buf = av_realloc_f((void *)buf, buf_size, 1);
+                if (!buf) {
+                    av_log(NULL, AV_LOG_ERROR, "Memory allocation problem occurred\n");
+                    return 1;
+                }
+            }
+            buf[count++] = c;
+        }
+    }
+
+    av_free(buf);
+    return 0;
+}
diff --git a/tools/fourcc2pixfmt.c b/tools/fourcc2pixfmt.c
new file mode 100644
index 0000000..6ee085b
--- /dev/null
+++ b/tools/fourcc2pixfmt.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2012 Stefano Sabatini
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#if HAVE_UNISTD_H
+#include <unistd.h>             /* getopt */
+#endif
+
+#include "libavutil/pixdesc.h"
+#include "libavcodec/avcodec.h"
+#include "libavutil/common.h"
+#include "libavcodec/raw.h"
+
+#if !HAVE_GETOPT
+#include "compat/getopt.c"
+#endif
+
+static void usage(void)
+{
+    printf("Show the relationships between rawvideo pixel formats and FourCC tags.\n");
+    printf("usage: fourcc2pixfmt [OPTIONS]\n");
+    printf("\n"
+           "Options:\n"
+           "-l                list the pixel format for each fourcc\n"
+           "-L                list the fourccs for each pixel format\n"
+           "-p PIX_FMT        given a pixel format, print the list of associated fourccs (one per line)\n"
+           "-h                print this help\n");
+}
+
+static void print_pix_fmt_fourccs(enum AVPixelFormat pix_fmt, char sep)
+{
+    int i;
+
+    for (i = 0; ff_raw_pix_fmt_tags[i].pix_fmt != AV_PIX_FMT_NONE; i++) {
+        if (ff_raw_pix_fmt_tags[i].pix_fmt == pix_fmt) {
+            char buf[32];
+            av_get_codec_tag_string(buf, sizeof(buf), ff_raw_pix_fmt_tags[i].fourcc);
+            printf("%s%c", buf, sep);
+        }
+    }
+}
+
+int main(int argc, char **argv)
+{
+    int i, list_fourcc_pix_fmt = 0, list_pix_fmt_fourccs = 0;
+    const char *pix_fmt_name = NULL;
+    char c;
+
+    if (argc == 1) {
+        usage();
+        return 0;
+    }
+
+    while ((c = getopt(argc, argv, "hp:lL")) != -1) {
+        switch (c) {
+        case 'h':
+            usage();
+            return 0;
+        case 'l':
+            list_fourcc_pix_fmt = 1;
+            break;
+        case 'L':
+            list_pix_fmt_fourccs = 1;
+            break;
+        case 'p':
+            pix_fmt_name = optarg;
+            break;
+        case '?':
+            usage();
+            return 1;
+        }
+    }
+
+    if (list_fourcc_pix_fmt) {
+        for (i = 0; ff_raw_pix_fmt_tags[i].pix_fmt != AV_PIX_FMT_NONE; i++) {
+            char buf[32];
+            av_get_codec_tag_string(buf, sizeof(buf), ff_raw_pix_fmt_tags[i].fourcc);
+            printf("%s: %s\n", buf, av_get_pix_fmt_name(ff_raw_pix_fmt_tags[i].pix_fmt));
+        }
+    }
+
+    if (list_pix_fmt_fourccs) {
+        for (i = 0; i < AV_PIX_FMT_NB; i++) {
+            const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[i];
+            if (!pix_desc->name || pix_desc->flags & PIX_FMT_HWACCEL)
+                continue;
+            printf("%s: ", pix_desc->name);
+            print_pix_fmt_fourccs(i, ' ');
+            printf("\n");
+        }
+    }
+
+    if (pix_fmt_name) {
+        enum AVPixelFormat pix_fmt = av_get_pix_fmt(pix_fmt_name);
+        if (pix_fmt == AV_PIX_FMT_NONE) {
+            fprintf(stderr, "Invalid pixel format selected '%s'\n", pix_fmt_name);
+            return 1;
+        }
+        print_pix_fmt_fourccs(pix_fmt, '\n');
+    }
+
+    return 0;
+}
diff --git a/tools/graph2dot.c b/tools/graph2dot.c
index c0142cc..4a30beb 100644
--- a/tools/graph2dot.c
+++ b/tools/graph2dot.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2008-2010 Stefano Sabatini
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -62,7 +62,7 @@
         char filter_ctx_label[128];
         const AVFilterContext *filter_ctx = graph->filters[i];
 
-        snprintf(filter_ctx_label, sizeof(filter_ctx_label), "%s (%s)",
+        snprintf(filter_ctx_label, sizeof(filter_ctx_label), "%s\\n(%s)",
                  filter_ctx->name,
                  filter_ctx->filter->name);
 
@@ -73,28 +73,32 @@
                 const AVFilterContext *dst_filter_ctx = link->dst;
 
                 snprintf(dst_filter_ctx_label, sizeof(dst_filter_ctx_label),
-                         "%s (%s)",
+                         "%s\\n(%s)",
                          dst_filter_ctx->name,
                          dst_filter_ctx->filter->name);
 
-                fprintf(outfile, "\"%s\" -> \"%s\"",
-                        filter_ctx_label, dst_filter_ctx_label);
+                fprintf(outfile, "\"%s\" -> \"%s\" [ label= \"inpad:%s -> outpad:%s\\n",
+                        filter_ctx_label, dst_filter_ctx_label,
+                        link->srcpad->name, link->dstpad->name);
+
                 if (link->type == AVMEDIA_TYPE_VIDEO) {
                     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
                     fprintf(outfile,
-                            " [ label= \"fmt:%s w:%d h:%d tb:%d/%d\" ]",
-                            desc->name, link->w, link->h, link->time_base.num,
-                            link->time_base.den);
+                            "fmt:%s w:%d h:%d tb:%d/%d",
+                            desc->name,
+                            link->w, link->h,
+                            link->time_base.num, link->time_base.den);
                 } else if (link->type == AVMEDIA_TYPE_AUDIO) {
                     char buf[255];
                     av_get_channel_layout_string(buf, sizeof(buf), -1,
                                                  link->channel_layout);
                     fprintf(outfile,
-                            " [ label= \"fmt:%s sr:%d cl:%s\" ]",
+                            "fmt:%s sr:%d cl:%s tb:%d/%d",
                             av_get_sample_fmt_name(link->format),
-                            link->sample_rate, buf);
+                            link->sample_rate, buf,
+                            link->time_base.num, link->time_base.den);
                 }
-                fprintf(outfile, ";\n");
+                fprintf(outfile, "\" ];\n");
             }
         }
     }
diff --git a/tools/ismindex.c b/tools/ismindex.c
index bf8c69d..b801d43 100644
--- a/tools/ismindex.c
+++ b/tools/ismindex.c
@@ -20,7 +20,7 @@
 
 /*
  * To create a simple file for smooth streaming:
- * avconv <normal input/transcoding options> -movflags frag_keyframe foo.ismv
+ * ffmpeg <normal input/transcoding options> -movflags frag_keyframe foo.ismv
  * ismindex -n foo foo.ismv
  * This step creates foo.ism and foo.ismc that is required by IIS for
  * serving it.
diff --git a/tools/make_chlayout_test b/tools/make_chlayout_test
new file mode 100755
index 0000000..fcdbda3
--- /dev/null
+++ b/tools/make_chlayout_test
@@ -0,0 +1,114 @@
+#!/usr/bin/env perl
+
+# 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
+
+=head1 NAME
+
+make_chlayout_test - produce a multichannel test file with the channels
+clearly identified
+
+=head1 SYNOPSIS
+
+tools/make_chlayout_test I<channels> I<out_options>
+
+=head1 DESCRIPTION
+
+This script uses B<ffmpeg> and B<libflite> to produce a file with audio
+channels clearly identified by their name. The resulting file can be used to
+check that the layout and order of channels is correctly handled by a piece
+of software, either a part of B<FFmpeg> or not.
+
+I<channels> is a list of channels or channel layouts, separated by '+'.
+
+I<out_options> is a list of valid ffmpeg outout options, including the
+output file.
+
+Note that some output codecs or formats can not handle arbitrary channel
+layout.
+
+This script requires a B<ffmpeg> binary, either in the source tree or in the
+search path; it must have the flite audio source enabled.
+
+=head1 EXAMPLES
+
+Check that the speakers are correctly plugged:
+
+  tools/make_chlayout_test FL+FR -f alsa default
+
+Produce a 5.1 FLAC file:
+
+  tools/make_chlayout_test 5.1 surround.flac
+
+=cut
+
+use strict;
+use warnings;
+use Getopt::Long ":config" => "require_order";
+use Pod::Usage;
+
+GetOptions (
+  "help|usage|?|h" => sub { pod2usage({ -verbose => 1, -exitval => 0 }) },
+  "manpage|m"      => sub { pod2usage({ -verbose => 2, -exitval => 0 }) },
+) and @ARGV >= 2 or pod2usage({ -verbose => 1, -exitval => 1 });
+
+my $channels = shift @ARGV;
+my @out_options = @ARGV;
+
+my $ffmpeg = exists $ENV{FFMPEG} ? $ENV{FFMPEG} :
+             $0 =~ /(.*)\// && -e "$1/../ffmpeg" ? "$1/../ffmpeg" :
+             "ffmpeg";
+
+my %channel_label_to_descr;
+my %layout_to_channels;
+
+{
+  open my $stderr, ">&STDERR";
+  open STDERR, ">", "/dev/null";
+  open my $f, "-|", $ffmpeg, "-layouts" or die "$ffmpeg: $!\n";
+  open STDERR, ">&", $stderr;
+  while (<$f>) {
+    chomp;
+    next if /^NAME/ or /:$/ or /^$/; # skip headings
+    my ($name, $descr) = split " ", $_, 2;
+    next unless $descr;
+    if ($descr =~ /^[[:upper:]]+(?:\+[[:upper:]]+)*$/) {
+      $layout_to_channels{$name} = [ split /\+/, $descr ];
+    } else {
+      $channel_label_to_descr{$name} = $descr;
+    }
+  }
+}
+
+my @channels = map { @{$layout_to_channels{$_} // [$_]} } split /\+/, $channels;
+
+my $layout = join "+", @channels;
+my $graph = "";
+my $concat_in = "";
+for my $i (0 .. $#channels) {
+  my $label = $channels[$i];
+  my $descr = $channel_label_to_descr{$label}
+    or die "Channel $label not found\n";
+  $graph .= "flite=text='${descr}', aformat=channel_layouts=mono, " .
+            "pan=${layout}:${label}=c0 [ch$i] ;\n";
+  $concat_in .= "[ch$i] ";
+}
+$graph .= "${concat_in}concat=v=0:a=1:n=" . scalar(@channels);
+
+exec $ffmpeg, "-f", "lavfi", "-i", $graph, @out_options
+  or die "$ffmpeg: $!\n";
diff --git a/tools/missing_codec_desc b/tools/missing_codec_desc
new file mode 100755
index 0000000..093d02e
--- /dev/null
+++ b/tools/missing_codec_desc
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+srcdir=${0%/*}/..
+
+while read -r field equal value; do
+  case "$field $equal" in
+    ".id =")
+      eval "known_${value%,}=1"
+      ;;
+  esac
+done < $srcdir/libavcodec/codec_desc.c
+
+known_AV_CODEC_ID_NONE=1
+known_AV_CODEC_ID_FIRST_AUDIO=1
+known_AV_CODEC_ID_FIRST_SUBTITLE=1
+known_AV_CODEC_ID_FIRST_UNKNOWN=1
+known_AV_CODEC_ID_TTF=1
+known_AV_CODEC_ID_PROBE=1
+known_AV_CODEC_ID_MPEG2TS=1
+known_AV_CODEC_ID_MPEG4SYSTEMS=1
+known_AV_CODEC_ID_FFMETADATA=1
+
+in=0
+while read -r line; do
+  case "$in-$line" in
+    0-"enum AVCodecID"*) in=1;;
+    1-*"};"*)            in=0;;
+    1-*AV_CODEC_ID_*,*)
+      cid="${line%%[, =]*}"
+      eval "known=\$known_$cid"
+      case "$known" in
+        1) ;;
+        *) echo "$cid missing";;
+      esac
+      ;;
+  esac
+done < $srcdir/libavcodec/avcodec.h
diff --git a/tools/patcheck b/tools/patcheck
index 78ca824..f82787b 100755
--- a/tools/patcheck
+++ b/tools/patcheck
@@ -15,11 +15,11 @@
 #FILES=$($GREP '^+++' $* | sed 's/+++ //g')
 
 echo patCHeck 1e10.0
-echo This tool is intended to help a human check/review patches it is very far from
-echo being free of false positives and negatives, its output are just hints of what
+echo This tool is intended to help a human check/review patches. It is very far from
+echo being free of false positives and negatives, and its output are just hints of what
 echo may or may not be bad. When you use it and it misses something or detects
-echo something wrong, fix it and send a patch to the libav-devel mailing list.
-echo License:GPL Autor: Michael Niedermayer
+echo something wrong, fix it and send a patch to the ffmpeg-devel mailing list.
+echo License: GPL, Author: Michael Niedermayer
 
 ERE_PRITYP='(unsigned *|)(char|short|long|int|long *int|short *int|void|float|double|(u|)int(8|16|32|64)_t)'
 ERE_TYPES='(const|static|av_cold|inline| *)*('$ERE_PRITYP'|[a-zA-Z][a-zA-Z0-9_]*)[* ]{1,}[a-zA-Z][a-zA-Z0-9_]*'
@@ -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|heigth|informations|colums|loosy|loosing|seperate|preceed|upto|paket|posible|unkown|inpossible|dimention|acheive)\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)\b' 'common typos' $*
 
 hiegrep 'av_log\( *NULL' 'Missing context in av_log' $*
 hiegrep '[^sn]printf' 'Please use av_log' $*
diff --git a/tools/pktdumper.c b/tools/pktdumper.c
index 98b9327..920397b 100644
--- a/tools/pktdumper.c
+++ b/tools/pktdumper.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2005 Francois Revol
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/tools/probetest.c b/tools/probetest.c
index 678f4dd..f8a617d 100644
--- a/tools/probetest.c
+++ b/tools/probetest.c
@@ -1,20 +1,20 @@
 /*
  * copyright (c) 2009 Michael Niedermayer <michaelni@gmx.at>
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -49,12 +49,19 @@
     }
 }
 
-int main(void)
+int main(int argc, char **argv)
 {
     unsigned int p, i, type, size, retry;
     AVProbeData pd;
     AVLFG state;
     PutBitContext pb;
+    int retry_count= 4097;
+    int max_size = 65537;
+
+    if(argc >= 2)
+        retry_count = atoi(argv[1]);
+    if(argc >= 3)
+        max_size = atoi(argv[2]);
 
     avcodec_register_all();
     av_register_all();
@@ -62,14 +69,14 @@
     av_lfg_init(&state, 0xdeadbeef);
 
     pd.buf = NULL;
-    for (size = 1; size < 65537; size *= 2) {
+    for (size = 1; size < max_size; size *= 2) {
         pd.buf_size = size;
         pd.buf      = av_realloc(pd.buf, size + AVPROBE_PADDING_SIZE);
         pd.filename = "";
 
         fprintf(stderr, "testing size=%d\n", size);
 
-        for (retry = 0; retry < 4097; retry += FFMAX(size, 32)) {
+        for (retry = 0; retry < retry_count; retry += FFMAX(size, 32)) {
             for (type = 0; type < 4; type++) {
                 for (p = 0; p < 4096; p++) {
                     unsigned hist = 0;
diff --git a/tools/qt-faststart.c b/tools/qt-faststart.c
index f33d6fa..8af510f 100644
--- a/tools/qt-faststart.c
+++ b/tools/qt-faststart.c
@@ -8,7 +8,7 @@
  * is in front of the data, thus facilitating network streaming.
  *
  * To compile this program, start from the base directory from which you
- * are building Libav and type:
+ * are building FFmpeg and type:
  *  make tools/qt-faststart
  * The qt-faststart program will be built in the tools/ directory. If you
  * do not build the program in this manner, correct results are not
@@ -37,6 +37,8 @@
 #define ftello(x)       _ftelli64(x)
 #endif
 
+#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
+
 #define BE_16(x) ((((uint8_t*)(x))[0] <<  8) | ((uint8_t*)(x))[1])
 
 #define BE_32(x) ((((uint8_t*)(x))[0] << 24) |  \
@@ -77,7 +79,7 @@
 #define CO64_ATOM QT_ATOM('c', 'o', '6', '4')
 
 #define ATOM_PREAMBLE_SIZE    8
-#define COPY_BUFFER_SIZE   1024
+#define COPY_BUFFER_SIZE   33554432
 
 int main(int argc, char *argv[])
 {
@@ -96,7 +98,7 @@
     uint32_t offset_count;
     uint64_t current_offset;
     uint64_t start_offset = 0;
-    unsigned char copy_buffer[COPY_BUFFER_SIZE];
+    unsigned char *copy_buffer = NULL;
     int bytes_to_copy;
 
     if (argc != 3) {
@@ -293,12 +295,15 @@
     }
 
     /* copy the remainder of the infile, from offset 0 -> last_offset - 1 */
+    bytes_to_copy = FFMIN(COPY_BUFFER_SIZE, last_offset);
+    copy_buffer = malloc(bytes_to_copy);
+    if (!copy_buffer) {
+        printf("could not allocate %d bytes for copy_buffer\n", bytes_to_copy);
+        goto error_out;
+    }
     printf(" copying rest of file...\n");
     while (last_offset) {
-        if (last_offset > COPY_BUFFER_SIZE)
-            bytes_to_copy = COPY_BUFFER_SIZE;
-        else
-            bytes_to_copy = last_offset;
+        bytes_to_copy = FFMIN(bytes_to_copy, last_offset);
 
         if (fread(copy_buffer, bytes_to_copy, 1, infile) != 1) {
             perror(argv[1]);
@@ -315,6 +320,7 @@
     fclose(outfile);
     free(moov_atom);
     free(ftyp_atom);
+    free(copy_buffer);
 
     return 0;
 
@@ -325,5 +331,6 @@
         fclose(outfile);
     free(moov_atom);
     free(ftyp_atom);
+    free(copy_buffer);
     return 1;
 }
diff --git a/tools/trasher.c b/tools/trasher.c
index 35625e9..93bfc0c 100644
--- a/tools/trasher.c
+++ b/tools/trasher.c
@@ -1,20 +1,20 @@
 /*
  * Copyright (c) 2007 Michael Niedermayer
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
diff --git a/tools/unwrap-diff b/tools/unwrap-diff
new file mode 100755
index 0000000..ccea99b
--- /dev/null
+++ b/tools/unwrap-diff
@@ -0,0 +1,2 @@
+#!/bin/sh
+tr '\n' '\001' | sed 's/\x01\x01/\x01 \x01/g' | sed 's/\x01\([^-+ @]\)/ \1/g' | tr '\001' '\n'
diff --git a/tools/yuvcmp.c b/tools/yuvcmp.c
new file mode 100644
index 0000000..11585f9
--- /dev/null
+++ b/tools/yuvcmp.c
@@ -0,0 +1,182 @@
+/*
+ * originally by Andreas Öman (andoma)
+ * some changes by Alexander Strange
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+
+int
+main(int argc, char **argv)
+{
+    int fd[2];
+    int print_pixels = 0;
+    int dump_blocks = 0;
+
+    int width;
+    int height;
+    int to_skip = 0;
+
+    if (argc < 6) {
+        fprintf(stderr, "%s [YUV file 1] [YUV file 2] width height pixelcmp|blockdump (# to skip)\n", argv[0]);
+        return 1;
+    }
+
+    width  = atoi(argv[3]);
+    height = atoi(argv[4]);
+    if (argc > 6)
+        to_skip = atoi(argv[6]);
+
+    uint8_t *Y[2], *C[2][2];
+    int i, v, c, p;
+    int lsiz = width * height;
+    int csiz = width * height / 4;
+    int x, y;
+    int cwidth = width / 2;
+    int fr = to_skip;
+    int mb;
+    char *mberrors;
+    int mb_x, mb_y;
+    uint8_t *a;
+    uint8_t *b;
+    int die = 0;
+
+    print_pixels = strstr(argv[5], "pixelcmp") ? 1 : 0;
+    dump_blocks  = strstr(argv[5], "blockdump") ? 1 : 0;
+
+    for(i = 0; i < 2; i++) {
+        Y[i] = malloc(lsiz);
+        C[0][i] = malloc(csiz);
+        C[1][i] = malloc(csiz);
+
+        fd[i] = open(argv[1 + i], O_RDONLY);
+        if(fd[i] == -1) {
+            perror("open");
+            exit(1);
+        }
+        fcntl(fd[i], F_NOCACHE, 1);
+
+        if (to_skip)
+            lseek(fd[i], to_skip * (lsiz + 2*csiz), SEEK_SET);
+    }
+
+    mb_x = width / 16;
+    mb_y = height / 16;
+
+    mberrors = malloc(mb_x * mb_y);
+
+    while(!die) {
+        memset(mberrors, 0, mb_x * mb_y);
+
+        printf("Loading frame %d\n", ++fr);
+
+        for(i = 0; i < 2; i++) {
+            v = read(fd[i], Y[i], lsiz);
+            if(v != lsiz) {
+                fprintf(stderr, "Unable to read Y from file %d, exiting\n", i + 1);
+                return 1;
+            }
+        }
+
+
+        for(c = 0; c < lsiz; c++) {
+            if(Y[0][c] != Y[1][c]) {
+                x = c % width;
+                y = c / width;
+
+                mb = x / 16 + (y / 16) * mb_x;
+
+                if(print_pixels)
+                    printf("Luma diff 0x%02x != 0x%02x at pixel (%4d,%-4d) mb(%d,%d) #%d\n",
+                           Y[0][c],
+                           Y[1][c],
+                           x, y,
+                           x / 16,
+                           y / 16,
+                           mb);
+
+                mberrors[mb] |= 1;
+            }
+        }
+
+        /* Chroma planes */
+
+        for(p = 0; p < 2; p++) {
+
+            for(i = 0; i < 2; i++) {
+                v = read(fd[i], C[p][i], csiz);
+                if(v != csiz) {
+                    fprintf(stderr, "Unable to read %c from file %d, exiting\n",
+                            "UV"[p], i + 1);
+                    return 1;
+                }
+            }
+
+            for(c = 0; c < csiz; c++) {
+                if(C[p][0][c] != C[p][1][c]) {
+                    x = c % cwidth;
+                    y = c / cwidth;
+
+                    mb = x / 8 + (y / 8) * mb_x;
+
+                    mberrors[mb] |= 2 << p;
+
+                    if(print_pixels)
+
+                        printf("c%c diff 0x%02x != 0x%02x at pixel (%4d,%-4d) "
+                               "mb(%3d,%-3d) #%d\n",
+                               p ? 'r' : 'b',
+                               C[p][0][c],
+                               C[p][1][c],
+
+                               x, y,
+                               x / 8,
+                               y / 8,
+                               x / 8 + y / 8 * cwidth / 8);
+                }
+            }
+        }
+
+        for(i = 0; i < mb_x * mb_y; i++) {
+            x = i % mb_x;
+            y = i / mb_x;
+
+            if(mberrors[i]) {
+                die = 1;
+
+                printf("MB (%3d,%-3d) %4d %d %c%c%c damaged\n",
+                       x, y, i, mberrors[i],
+                       mberrors[i] & 1 ? 'Y' : ' ',
+                       mberrors[i] & 2 ? 'U' : ' ',
+                       mberrors[i] & 4 ? 'V' : ' ');
+
+                if(dump_blocks) {
+                    a = Y[0] + x * 16 + y * 16 * width;
+                    b = Y[1] + x * 16 + y * 16 * width;
+
+                    for(y = 0; y < 16; y++) {
+                        printf("%c ", "TB"[y&1]);
+                        for(x = 0; x < 16; x++)
+                            printf("%02x%c", a[x + y * width],
+                                   a[x + y * width] != b[x + y * width] ? '<' : ' ');
+
+                        printf("| ");
+                        for(x = 0; x < 16; x++)
+                            printf("%02x%c", b[x + y * width],
+                                   a[x + y * width] != b[x + y * width] ? '<' : ' ');
+
+                        printf("\n");
+                    }
+                }
+            }
+        }
+    }
+
+    return 0;
+}
diff --git a/version.sh b/version.sh
index 6f72b2c..8d084c2 100755
--- a/version.sh
+++ b/version.sh
@@ -1,11 +1,33 @@
 #!/bin/sh
 
 # check for git short hash
-revision=$(cd "$1" && git describe --always 2> /dev/null)
+if ! test "$revision"; then
+    revision=$(cd "$1" && git describe --tags --match N 2> /dev/null)
+fi
+
+# Shallow Git clones (--depth) do not have the N tag:
+# use 'git-YYYY-MM-DD-hhhhhhh'.
+test "$revision" || revision=$(cd "$1" &&
+  git log -1 --pretty=format:"git-%cd-%h" --date=short 2> /dev/null)
+
+# Snapshots from gitweb are in a directory called ffmpeg-hhhhhhh or
+# ffmpeg-HEAD-hhhhhhh.
+if [ -z "$revision" ]; then
+  srcdir=$(cd "$1" && pwd)
+  case "$srcdir" in
+    */ffmpeg-[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f])
+      git_hash="${srcdir##*-}";;
+    */ffmpeg-HEAD-[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f])
+      git_hash="${srcdir##*-}";;
+  esac
+fi
 
 # no revision number found
 test "$revision" || revision=$(cd "$1" && cat RELEASE 2> /dev/null)
 
+# Append the Git hash if we have one
+test "$revision" && test "$git_hash" && revision="$revision-$git_hash"
+
 # releases extract the version number from the VERSION file
 version=$(cd "$1" && cat VERSION 2> /dev/null)
 test "$version" || version=$revision
@@ -17,7 +39,7 @@
     exit
 fi
 
-NEW_REVISION="#define LIBAV_VERSION \"$version\""
+NEW_REVISION="#define FFMPEG_VERSION \"$version\""
 OLD_REVISION=$(cat version.h 2> /dev/null)
 
 # Update version.h only on revision changes to avoid spurious rebuilds